bind9-9.10.3.dfsg.P4/0002755000470500017500000000000012664730167013404 5ustar lamontlamontbind9-9.10.3.dfsg.P4/mkinstalldirs0000755000470500017500000000132712664710322016202 0ustar lamontlamont#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain # $Id: mkinstalldirs,v 1.1 2000/09/20 19:05:51 gson Exp $ errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" 1>&2 mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here bind9-9.10.3.dfsg.P4/acconfig.h0000644000470500017500000001027612664710322015321 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2008, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: acconfig.h,v 1.53 2008/12/01 23:47:44 tbox Exp $ */ /*! \file */ /*** *** This file is not to be included by any public header files, because *** it does not get installed. ***/ @TOP@ /** define on DEC OSF to enable 4.4BSD style sa_len support */ #undef _SOCKADDR_LEN /** define if your system needs pthread_init() before using pthreads */ #undef NEED_PTHREAD_INIT /** define if your system has sigwait() */ #undef HAVE_SIGWAIT /** define if sigwait() is the UnixWare flavor */ #undef HAVE_UNIXWARE_SIGWAIT /** define on Solaris to get sigwait() to work using pthreads semantics */ #undef _POSIX_PTHREAD_SEMANTICS /** define if LinuxThreads is in use */ #undef HAVE_LINUXTHREADS /** define if sysconf() is available */ #undef HAVE_SYSCONF /** define if sysctlbyname() is available */ #undef HAVE_SYSCTLBYNAME /** define if catgets() is available */ #undef HAVE_CATGETS /** define if getifaddrs() exists */ #undef HAVE_GETIFADDRS /** define if you have the NET_RT_IFLIST sysctl variable and sys/sysctl.h */ #undef HAVE_IFLIST_SYSCTL /** define if tzset() is available */ #undef HAVE_TZSET /** define if struct addrinfo exists */ #undef HAVE_ADDRINFO /** define if getaddrinfo() exists */ #undef HAVE_GETADDRINFO /** define if gai_strerror() exists */ #undef HAVE_GAISTRERROR /** define if arc4random() exists */ #undef HAVE_ARC4RANDOM /** define if arc4random_addrandom() exists */ #undef HAVE_ARC4RANDOM_ADDRANDOM /** * define if pthread_setconcurrency() should be called to tell the * OS how many threads we might want to run. */ #undef CALL_PTHREAD_SETCONCURRENCY /** define if IPv6 is not disabled */ #undef WANT_IPV6 /** define if flockfile() is available */ #undef HAVE_FLOCKFILE /** define if getc_unlocked() is available */ #undef HAVE_GETCUNLOCKED /** Shut up warnings about sputaux in stdio.h on BSD/OS pre-4.1 */ #undef SHUTUP_SPUTAUX #ifdef SHUTUP_SPUTAUX struct __sFILE; extern __inline int __sputaux(int _c, struct __sFILE *_p); #endif /** Shut up warnings about missing sigwait prototype on BSD/OS 4.0* */ #undef SHUTUP_SIGWAIT #ifdef SHUTUP_SIGWAIT int sigwait(const unsigned int *set, int *sig); #endif /** Shut up warnings from gcc -Wcast-qual on BSD/OS 4.1. */ #undef SHUTUP_STDARG_CAST #if defined(SHUTUP_STDARG_CAST) && defined(__GNUC__) #include /** Grr. Must be included *every time*. */ /** * The silly continuation line is to keep configure from * commenting out the #undef. */ #undef \ va_start #define va_start(ap, last) \ do { \ union { const void *konst; long *var; } _u; \ _u.konst = &(last); \ ap = (va_list)(_u.var + __va_words(__typeof(last))); \ } while (0) #endif /** SHUTUP_STDARG_CAST && __GNUC__ */ /** define if the system has a random number generating device */ #undef PATH_RANDOMDEV /** define if pthread_attr_getstacksize() is available */ #undef HAVE_PTHREAD_ATTR_GETSTACKSIZE /** define if pthread_attr_setstacksize() is available */ #undef HAVE_PTHREAD_ATTR_SETSTACKSIZE /** define if you have strerror in the C library. */ #undef HAVE_STRERROR /* Define if OpenSSL includes DSA support */ #undef HAVE_OPENSSL_DSA /* Define if you have getpassphrase in the C library. */ #undef HAVE_GETPASSPHRASE /* Define to the length type used by the socket API (socklen_t, size_t, int). */ #undef ISC_SOCKADDR_LEN_T /* Define if threads need PTHREAD_SCOPE_SYSTEM */ #undef NEED_PTHREAD_SCOPE_SYSTEM bind9-9.10.3.dfsg.P4/config.h.in0000644000470500017500000003714612664710322015427 0ustar lamontlamont/* config.h.in. Generated from configure.in by autoheader. */ /* * Copyright (C) 2004, 2005, 2007, 2008, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: acconfig.h,v 1.53 2008/12/01 23:47:44 tbox Exp $ */ /*! \file */ /*** *** This file is not to be included by any public header files, because *** it does not get installed. ***/ /** define on DEC OSF to enable 4.4BSD style sa_len support */ #undef _SOCKADDR_LEN /** define if your system needs pthread_init() before using pthreads */ #undef NEED_PTHREAD_INIT /** define if your system has sigwait() */ #undef HAVE_SIGWAIT /** define if sigwait() is the UnixWare flavor */ #undef HAVE_UNIXWARE_SIGWAIT /** define on Solaris to get sigwait() to work using pthreads semantics */ #undef _POSIX_PTHREAD_SEMANTICS /** define if LinuxThreads is in use */ #undef HAVE_LINUXTHREADS /** define if sysconf() is available */ #undef HAVE_SYSCONF /** define if sysctlbyname() is available */ #undef HAVE_SYSCTLBYNAME /** define if catgets() is available */ #undef HAVE_CATGETS /** define if getifaddrs() exists */ #undef HAVE_GETIFADDRS /** define if you have the NET_RT_IFLIST sysctl variable and sys/sysctl.h */ #undef HAVE_IFLIST_SYSCTL /** define if tzset() is available */ #undef HAVE_TZSET /** define if struct addrinfo exists */ #undef HAVE_ADDRINFO /** define if getaddrinfo() exists */ #undef HAVE_GETADDRINFO /** define if gai_strerror() exists */ #undef HAVE_GAISTRERROR /** define if arc4random() exists */ #undef HAVE_ARC4RANDOM /** define if arc4random_addrandom() exists */ #undef HAVE_ARC4RANDOM_ADDRANDOM /** * define if pthread_setconcurrency() should be called to tell the * OS how many threads we might want to run. */ #undef CALL_PTHREAD_SETCONCURRENCY /** define if IPv6 is not disabled */ #undef WANT_IPV6 /** define if flockfile() is available */ #undef HAVE_FLOCKFILE /** define if getc_unlocked() is available */ #undef HAVE_GETCUNLOCKED /** Shut up warnings about sputaux in stdio.h on BSD/OS pre-4.1 */ #undef SHUTUP_SPUTAUX #ifdef SHUTUP_SPUTAUX struct __sFILE; extern __inline int __sputaux(int _c, struct __sFILE *_p); #endif /** Shut up warnings about missing sigwait prototype on BSD/OS 4.0* */ #undef SHUTUP_SIGWAIT #ifdef SHUTUP_SIGWAIT int sigwait(const unsigned int *set, int *sig); #endif /** Shut up warnings from gcc -Wcast-qual on BSD/OS 4.1. */ #undef SHUTUP_STDARG_CAST #if defined(SHUTUP_STDARG_CAST) && defined(__GNUC__) #include /** Grr. Must be included *every time*. */ /** * The silly continuation line is to keep configure from * commenting out the #undef. */ #undef \ va_start #define va_start(ap, last) \ do { \ union { const void *konst; long *var; } _u; \ _u.konst = &(last); \ ap = (va_list)(_u.var + __va_words(__typeof(last))); \ } while (0) #endif /** SHUTUP_STDARG_CAST && __GNUC__ */ /** define if the system has a random number generating device */ #undef PATH_RANDOMDEV /** define if pthread_attr_getstacksize() is available */ #undef HAVE_PTHREAD_ATTR_GETSTACKSIZE /** define if pthread_attr_setstacksize() is available */ #undef HAVE_PTHREAD_ATTR_SETSTACKSIZE /** define if you have strerror in the C library. */ #undef HAVE_STRERROR /* Define if OpenSSL includes DSA support */ #undef HAVE_OPENSSL_DSA /* Define if you have getpassphrase in the C library. */ #undef HAVE_GETPASSPHRASE /* Define to the length type used by the socket API (socklen_t, size_t, int). */ #undef ISC_SOCKADDR_LEN_T /* Define if threads need PTHREAD_SCOPE_SYSTEM */ #undef NEED_PTHREAD_SCOPE_SYSTEM /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD /* Use AES for Source Identity Token generation */ #undef AES_SIT /* Define to enable the "filter-aaaa-on-v4" and "filter-aaaa-on-v6" options. */ #undef ALLOW_FILTER_AAAA /* define if ATF unit tests are to be built. */ #undef ATF_TEST /* Define if recvmsg() does not meet all of the BSD socket API specifications. */ #undef BROKEN_RECVMSG /* Define if you cannot bind() before connect() for TCP sockets. */ #undef BROKEN_TCP_BIND_BEFORE_CONNECT /* Define to enable "rrset-order fixed" syntax. */ #undef DNS_RDATASET_FIXED /* Define to enable the "fetches-per-server" and "fetches-per-zone" options. */ #undef ENABLE_FETCHLIMIT /* Define to enable rpz-nsdname rules. */ #undef ENABLE_RPZ_NSDNAME /* Define to enable rpz-nsip rules. */ #undef ENABLE_RPZ_NSIP /* Solaris hack to get select_large_fdset. */ #undef FD_SETSIZE /* Define to nothing if C supports flexible array members, and to 1 if it does not. That way, with a declaration like `struct s { int n; double d[FLEXIBLE_ARRAY_MEMBER]; };', the struct hack can be used with pre-C99 compilers. When computing the size of such an object, don't use 'sizeof (struct s)' as it overestimates the size. Use 'offsetof (struct s, d)' instead. Don't use 'offsetof (struct s, d[0])', as this doesn't work with MSVC and with C++ compilers. */ #undef FLEXIBLE_ARRAY_MEMBER /* Define to 1 if you have the `chroot' function. */ #undef HAVE_CHROOT /* Define if clock_gettime is available. */ #undef HAVE_CLOCK_GETTIME /* Define to 1 if you have the header file. */ #undef HAVE_DEVPOLL_H /* Define to 1 if you have the `dlclose' function. */ #undef HAVE_DLCLOSE /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the `dlopen' function. */ #undef HAVE_DLOPEN /* Define to 1 if you have the `dlsym' function. */ #undef HAVE_DLSYM /* Define to 1 if you have the `EVP_sha256' function. */ #undef HAVE_EVP_SHA256 /* Define to 1 if you have the `EVP_sha384' function. */ #undef HAVE_EVP_SHA384 /* Define to 1 if you have the `EVP_sha512' function. */ #undef HAVE_EVP_SHA512 /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if you have the `fseeko' function. */ #undef HAVE_FSEEKO /* Define to 1 if you have the `ftello' function. */ #undef HAVE_FTELLO /* Build with GeoIP support */ #undef HAVE_GEOIP /* Build with GeoIP City IPv6 support */ #undef HAVE_GEOIP_CITY_V6 /* Build with GeoIP Country IPv6 support */ #undef HAVE_GEOIP_V6 /* Define to use gperftools CPU profiler. */ #undef HAVE_GPERFTOOLS_PROFILER /* Define to 1 if you have the header file. */ #undef HAVE_GSSAPI_GSSAPI_H /* Define to 1 if you have the header file. */ #undef HAVE_GSSAPI_GSSAPI_KRB5_H /* Define to 1 if you have the header file. */ #undef HAVE_GSSAPI_H /* Define to 1 if you have the header file. */ #undef HAVE_GSSAPI_KRB5_H /* Define to 1 if you have the if_nametoindex function. */ #undef HAVE_IF_NAMETOINDEX /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define if libjson was found */ #undef HAVE_JSON /* Define if json-c was found */ #undef HAVE_JSON_C /* Define to 1 if you have the header file. */ #undef HAVE_KERBEROSV5_KRB5_H /* Define to 1 if you have the header file. */ #undef HAVE_KRB5_H /* Define to 1 if you have the header file. */ #undef HAVE_KRB5_KRB5_H /* Define to 1 if you have the `c' library (-lc). */ #undef HAVE_LIBC /* Define to 1 if you have the `cap' library (-lcap). */ #undef HAVE_LIBCAP /* if system have backtrace function */ #undef HAVE_LIBCTRACE /* Define to 1 if you have the `c_r' library (-lc_r). */ #undef HAVE_LIBC_R /* Define to 1 if you have the `nsl' library (-lnsl). */ #undef HAVE_LIBNSL /* Define to 1 if you have the `pthread' library (-lpthread). */ #undef HAVE_LIBPTHREAD /* Define to 1 if you have the `rt' library (-lrt). */ #undef HAVE_LIBRT /* Define to 1 if you have the `scf' library (-lscf). */ #undef HAVE_LIBSCF /* Define to use libseccomp system call filtering. */ #undef HAVE_LIBSECCOMP /* Define to 1 if you have the `socket' library (-lsocket). */ #undef HAVE_LIBSOCKET /* Define to 1 if you have the `thr' library (-lthr). */ #undef HAVE_LIBTHR /* Define if libxml2 was found */ #undef HAVE_LIBXML2 /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_CAPABILITY_H /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_NETLINK_H /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_RTNETLINK_H /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_LOCALE_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `mmap' function. */ #undef HAVE_MMAP /* Define to 1 if you have the `nanosleep' function. */ #undef HAVE_NANOSLEEP /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF6_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_ROUTE_H /* Define if your OpenSSL version supports AES */ #undef HAVE_OPENSSL_AES /* Define if your OpenSSL version supports ECDSA. */ #undef HAVE_OPENSSL_ECDSA /* Define if your OpenSSL version supports EVP AES */ #undef HAVE_OPENSSL_EVP_AES /* Define if your OpenSSL version supports GOST. */ #undef HAVE_OPENSSL_GOST /* Define if your PKCS11 provider supports ECDSA. */ #undef HAVE_PKCS11_ECDSA /* Define if your PKCS11 provider supports GOST. */ #undef HAVE_PKCS11_GOST /* Support for PTHREAD_MUTEX_ADAPTIVE_NP */ #undef HAVE_PTHREAD_MUTEX_ADAPTIVE_NP /* Define to 1 if you have the `pthread_yield' function. */ #undef HAVE_PTHREAD_YIELD /* Define to 1 if you have the `pthread_yield_np' function. */ #undef HAVE_PTHREAD_YIELD_NP /* Define to 1 if you have the `readline' function. */ #undef HAVE_READLINE /* Define to 1 if you have the header file. */ #undef HAVE_REGEX_H /* Define to 1 if you have the header file. */ #undef HAVE_SCHED_H /* Define to 1 if you have the `sched_yield' function. */ #undef HAVE_SCHED_YIELD /* Define to 1 if you have the `setegid' function. */ #undef HAVE_SETEGID /* Define to 1 if you have the `seteuid' function. */ #undef HAVE_SETEUID /* Define to 1 if you have the `setlocale' function. */ #undef HAVE_SETLOCALE /* Define to 1 if you have the `setresgid' function. */ #undef HAVE_SETRESGID /* Define to 1 if you have the `setresuid' function. */ #undef HAVE_SETRESUID /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_CAPABILITY_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_DEVPOLL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_DYNTUNE_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MMAN_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PARAM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PRCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKIO_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SYSCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_UN_H /* Define if running under Compaq TruCluster */ #undef HAVE_TRUCLUSTER /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `usleep' function. */ #undef HAVE_USLEEP /* HMAC_*() return ints */ #undef HMAC_RETURN_INT /* Use HMAC-SHA1 for Source Identity Token generation */ #undef HMAC_SHA1_SIT /* Use HMAC-SHA256 for Source Identity Token generation */ #undef HMAC_SHA256_SIT /* return type of gai_strerror */ #undef IRS_GAISTRERROR_RETURN_T /* Define to the buffer length type used by getnameinfo(3). */ #undef IRS_GETNAMEINFO_BUFLEN_T /* Define to the flags type used by getnameinfo(3). */ #undef IRS_GETNAMEINFO_FLAGS_T /* Define to the sockaddr length type used by getnameinfo(3). */ #undef IRS_GETNAMEINFO_SOCKLEN_T /* Define to allow building of objects for dlopen(). */ #undef ISC_DLZ_DLOPEN /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Defined if extern char *optarg is not declared. */ #undef NEED_OPTARG /* Define if connect does not honour the permission on the UNIX domain socket. */ #undef NEED_SECURE_DIRECTORY /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Sets which flag to pass to open/fcntl to make non-blocking (O_NDELAY/O_NONBLOCK). */ #undef PORT_NONBLOCK /* Define if GOST private keys are encoded in ASN.1. */ #undef PREFER_GOSTASN1 /* The size of `void *', as computed by sizeof. */ #undef SIZEOF_VOID_P /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Define to use large-system tuning. */ #undef TUNE_LARGE /* Defined if you need to use ioctl(FIONBIO) instead a fcntl call to make non-blocking. */ #undef USE_FIONBIO_IOCTL /* Define to enable very verbose query trace logging. */ #undef WANT_QUERYTRACE /* define if idnkit support is to be included. */ #undef WITH_IDN /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN # undef WORDS_BIGENDIAN # endif #endif /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to empty if your compiler does not support "static inline". */ #undef inline /* Define to `unsigned int' if does not define. */ #undef size_t /* Define to `int' if does not define. */ #undef ssize_t /* Define to `unsigned long' if does not define. */ #undef uintptr_t /* Define to empty if the keyword `volatile' does not work. Warning: valid code using `volatile' can become incorrect without. Disable with care. */ #undef volatile bind9-9.10.3.dfsg.P4/HISTORY0000644000470500017500000003076712664710322014472 0ustar lamontlamontSummary of functional enhancements from prior major releases of BIND 9: BIND 9.8.0 BIND 9.8.0 includes a number of changes from BIND 9.7 and earlier releases. New features include: - Built-in trust anchor for the root zone, which can be switched on via "dnssec-validation auto;" - Support for DNS64. - Support for response policy zones (RPZ). - Support for writable DLZ zones. - Improved ease of configuration of GSS/TSIG for interoperability with Active Directory - Support for GOST signing algorithm for DNSSEC. - Removed RTT Banding from server selection algorithm. - New "static-stub" zone type. - Allow configuration of resolver timeouts via "resolver-query-timeout" option. - The DLZ "dlopen" driver is now built by default. - Added a new include file with function typedefs for the DLZ "dlopen" driver. - Made "--with-gssapi" default. - More verbose error reporting from DLZ LDAP. BIND 9.7.0 BIND 9.7.0 includes a number of changes from BIND 9.6 and earlier releases. Most are intended to simplify DNSSEC configuration. New features include: - Fully automatic signing of zones by "named". - Simplified configuration of DNSSEC Lookaside Validation (DLV). - Simplified configuration of Dynamic DNS, using the "ddns-confgen" command line tool or the "local" update-policy option. (As a side effect, this also makes it easier to configure automatic zone re-signing.) - New named option "attach-cache" that allows multiple views to share a single cache. - DNS rebinding attack prevention. - New default values for dnssec-keygen parameters. - Support for RFC 5011 automated trust anchor maintenance - Smart signing: simplified tools for zone signing and key maintenance. - The "statistics-channels" option is now available on Windows. - A new DNSSEC-aware libdns API for use by non-BIND9 applications - On some platforms, named and other binaries can now print out a stack backtrace on assertion failure, to aid in debugging. - A "tools only" installation mode on Windows, which only installs dig, host, nslookup and nsupdate. - Improved PKCS#11 support, including Keyper support and explicit OpenSSL engine selection. BIND 9.6.0 Full NSEC3 support Automatic zone re-signing New update-policy methods tcp-self and 6to4-self The BIND 8 resolver library, libbind, has been removed from the BIND 9 distribution and is now available as a separate download. Change the default pid file location from /var/run to /var/run/{named,lwresd} for improved chroot/setuid support. BIND 9.5.0 GSS-TSIG support (RFC 3645). DHCID support. Experimental http server and statistics support for named via xml. More detailed statistics counters including those supported in BIND 8. Faster ACL processing. Use Doxygen to generate internal documentation. Efficient LRU cache-cleaning mechanism. NSID support. BIND 9.4.0 Implemented "additional section caching (or acache)", an internal cache framework for additional section content to improve response performance. Several configuration options were provided to control the behavior. New notify type 'master-only'. Enable notify for master zones only. Accept 'notify-source' style syntax for query-source. rndc now allows addresses to be set in the server clauses. New option "allow-query-cache". This lets "allow-query" be used to specify the default zone access level rather than having to have every zone override the global value. "allow-query-cache" can be set at both the options and view levels. If "allow-query-cache" is not set then "allow-recursion" is used if set, otherwise "allow-query" is used if set unless "recursion no;" is set in which case "none;" is used, otherwise the default (localhost; localnets;) is used. rndc: the source address can now be specified. ixfr-from-differences now takes master and slave in addition to yes and no at the options and view levels. Allow the journal's name to be changed via named.conf. 'rndc notify zone [class [view]]' resend the NOTIFY messages for the specified zone. 'dig +trace' now randomly selects the next servers to try. Report if there is a bad delegation. Improve check-names error messages. Make public the function to read a key file, dst_key_read_public(). dig now returns the byte count for axfr/ixfr. allow-update is now settable at the options / view level. named-checkconf now checks the logging configuration. host now can turn on memory debugging flags with '-m'. Don't send notify messages to self. Perform sanity checks on NS records which refer to 'in zone' names. New zone option "notify-delay". Specify a minimum delay between sets of NOTIFY messages. Extend adjusting TTL warning messages. Named and named-checkzone can now both check for non-terminal wildcard records. "rndc freeze/thaw" now freezes/thaws all zones. named-checkconf now check acls to verify that they only refer to existing acls. The server syntax has been extended to support a range of servers. Report differences between hints and real NS rrset and associated address records. Preserve the case of domain names in rdata during zone transfers. Restructured the data locking framework using architecture dependent atomic operations (when available), improving response performance on multi-processor machines significantly. x86, x86_64, alpha, powerpc, and mips are currently supported. UNIX domain controls are now supported. Add support for additional zone file formats for improving loading performance. The masterfile-format option in named.conf can be used to specify a non-default format. A separate command named-compilezone was provided to generate zone files in the new format. Additionally, the -I and -O options for dnssec-signzone specify the input and output formats. dnssec-signzone can now randomize signature end times (dnssec-signzone -j jitter). Add support for CH A record. Add additional zone data constancy checks. named-checkzone has extended checking of NS, MX and SRV record and the hosts they reference. named has extended post zone load checks. New zone options: check-mx and integrity-check. edns-udp-size can now be overridden on a per server basis. dig can now specify the EDNS version when making a query. Added framework for handling multiple EDNS versions. Additional memory debugging support to track size and mctx arguments. Detect duplicates of UDP queries we are recursing on and drop them. New stats category "duplicates". "USE INTERNAL MALLOC" is now runtime selectable. The lame cache is now done on a basis as some servers only appear to be lame for certain query types. Limit the number of recursive clients that can be waiting for a single query () to resolve. New options clients-per-query and max-clients-per-query. dig: report the number of extra bytes still left in the packet after processing all the records. Support for IPSECKEY rdata type. Raise the UDP recieve buffer size to 32k if it is less than 32k. x86 and x86_64 now have seperate atomic locking implementations. named-checkconf now validates update-policy entries. Attempt to make the amount of work performed in a iteration self tuning. The covers nodes clean from the cache per iteration, nodes written to disk when rewriting a master file and nodes destroyed per iteration when destroying a zone or a cache. ISC string copy API. Automatic empty zone creation for D.F.IP6.ARPA and friends. Note: RFC 1918 zones are not yet covered by this but are likely to be in a future release. New options: empty-server, empty-contact, empty-zones-enable and disable-empty-zone. dig now has a '-q queryname' and '+showsearch' options. host/nslookup now continue (default)/fail on SERVFAIL. dig now warns if 'RA' is not set in the answer when 'RD' was set in the query. host/nslookup skip servers that fail to set 'RA' when 'RD' is set unless a server is explicitly set. Integrate contibuted DLZ code into named. Integrate contibuted IDN code from JPNIC. libbind: corresponds to that from BIND 8.4.7. BIND 9.3.0 DNSSEC is now DS based (RFC 3658). See also RFC 3845, doc/draft/draft-ietf-dnsext-dnssec-*. DNSSEC lookaside validation. check-names is now implemented. rrset-order in more complete. IPv4/IPv6 transition support, dual-stack-servers. IXFR deltas can now be generated when loading master files, ixfr-from-differences. It is now possible to specify the size of a journal, max-journal-size. It is now possible to define a named set of master servers to be used in masters clause, masters. The advertised EDNS UDP size can now be set, edns-udp-size. allow-v6-synthesis has been obsoleted. NOTE: * Zones containing MD and MF will now be rejected. * dig, nslookup name. now report "Not Implemented" as NOTIMP rather than NOTIMPL. This will have impact on scripts that are looking for NOTIMPL. libbind: corresponds to that from BIND 8.4.5. BIND 9.2.0 The size of the cache can now be limited using the "max-cache-size" option. The server can now automatically convert RFC1886-style recursive lookup requests into RFC2874-style lookups, when enabled using the new option "allow-v6-synthesis". This allows stub resolvers that support AAAA records but not A6 record chains or binary labels to perform lookups in domains that make use of these IPv6 DNS features. Performance has been improved. The man pages now use the more portable "man" macros rather than the "mandoc" macros, and are installed by "make install". The named.conf parser has been completely rewritten. It now supports "include" directives in more places such as inside "view" statements, and it no longer has any reserved words. The "rndc status" command is now implemented. rndc can now be configured automatically. A BIND 8 compatible stub resolver library is now included in lib/bind. OpenSSL has been removed from the distribution. This means that to use DNSSEC, OpenSSL must be installed and the --with-openssl option must be supplied to configure. This does not apply to the use of TSIG, which does not require OpenSSL. The source distribution now builds on Windows. See win32utils/readme1.txt and win32utils/win32-build.txt for details. This distribution also includes a new lightweight stub resolver library and associated resolver daemon that fully support forward and reverse lookups of both IPv4 and IPv6 addresses. This library is considered experimental and is not a complete replacement for the BIND 8 resolver library. Applications that use the BIND 8 res_* functions to perform DNS lookups or dynamic updates still need to be linked against the BIND 8 libraries. For DNS lookups, they can also use the new "getrrsetbyname()" API. BIND 9.2 is capable of acting as an authoritative server for DNSSEC secured zones. This functionality is believed to be stable and complete except for lacking support for verifications involving wildcard records in secure zones. When acting as a caching server, BIND 9.2 can be configured to perform DNSSEC secure resolution on behalf of its clients. This part of the DNSSEC implementation is still considered experimental. For detailed information about the state of the DNSSEC implementation, see the file doc/misc/dnssec. There are a few known bugs: On some systems, IPv6 and IPv4 sockets interact in unexpected ways. For details, see doc/misc/ipv6. To reduce the impact of these problems, the server no longer listens for requests on IPv6 addresses by default. If you need to accept DNS queries over IPv6, you must specify "listen-on-v6 { any; };" in the named.conf options statement. FreeBSD prior to 4.2 (and 4.2 if running as non-root) and OpenBSD prior to 2.8 log messages like "fcntl(8, F_SETFL, 4): Inappropriate ioctl for device". This is due to a bug in "/dev/random" and impacts the server's DNSSEC support. OS X 10.1.4 (Darwin 5.4), OS X 10.1.5 (Darwin 5.5) and OS X 10.2 (Darwin 6.0) reports errors like "fcntl(3, F_SETFL, 4): Operation not supported by device". This is due to a bug in "/dev/random" and impacts the server's DNSSEC support. --with-libtool does not work on AIX. A bug in some versions of the Microsoft DNS server can cause zone transfers from a BIND 9 server to a W2K server to fail. For details, see the "Zone Transfers" section in doc/misc/migration. bind9-9.10.3.dfsg.P4/config.threads.in0000644000470500017500000000576012664710322016627 0ustar lamontlamont# # Begin pthreads checking. # # First, decide whether to use multithreading or not. # # Enable multithreading by default on systems where it is known # to work well, and where debugging of multithreaded programs # is supported. # AC_MSG_CHECKING(whether to build with thread support) case $host in *-dec-osf*) use_threads=true ;; [*-solaris2.[0-6]]) # Thread signals are broken on Solaris 2.6; they are sometimes # delivered to the wrong thread. use_threads=false ;; *-solaris*) use_threads=true ;; *-ibm-aix*) use_threads=true ;; *-hp-hpux10*) use_threads=false ;; *-hp-hpux11*) use_threads=true ;; *-sgi-irix*) use_threads=true ;; *-sco-sysv*uw*|*-*-sysv*UnixWare*) # UnixWare use_threads=false ;; *-*-sysv*OpenUNIX*) # UnixWare use_threads=true ;; [*-netbsd[1234].*]) # NetBSD earlier than NetBSD 5.0 has poor pthreads. # Don't use it by default. use_threads=false ;; *-netbsd*) use_threads=true ;; *-openbsd*) # OpenBSD users have reported that named dumps core on # startup when built with threads. use_threads=false ;; [*-freebsd[1234567].*]) # Threads are broken at least up to FreeBSD 4.11. # FreeBSD 5, 6 and 7 we have never officially supported threads # on. YMMV use_threads=false ;; *-freebsd*) use_threads=true ;; [*-bsdi[234]*]) # Thread signals do not work reliably on some versions of BSD/OS. use_threads=false ;; *-bsdi5*) use_threads=true ;; *-linux*) use_threads=true ;; *-darwin[[123456789]].*) use_threads=false ;; *-darwin*.*) use_threads=true ;; *) use_threads=true ;; esac AC_ARG_ENABLE(threads, [ --enable-threads enable multithreading]) case "$enable_threads" in yes) use_threads=true ;; no) use_threads=false ;; '') # Use system-dependent default ;; *) AC_MSG_ERROR([--enable-threads takes yes or no]) ;; esac if $use_threads then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi if $use_threads then # # Search for / configure pthreads in a system-dependent fashion. # case "$host" in *-freebsd*) # We don't want to set -lpthread as that break # the ability to choose threads library at final # link time and is not valid for all architectures. PTHREAD= if test "X$GCC" = "Xyes"; then saved_cc="$CC" CC="$CC -pthread" AC_MSG_CHECKING(for gcc -pthread support); AC_TRY_LINK([#include ], [printf("%x\n", pthread_create);], PTHREAD="yes" AC_MSG_RESULT(yes), AC_MSG_RESULT(no)) CC="$saved_cc" fi if test "X$PTHREAD" != "Xyes"; then AC_CHECK_LIB(pthread, pthread_create,, AC_CHECK_LIB(thr, thread_create,, AC_CHECK_LIB(c_r, pthread_create,, AC_CHECK_LIB(c, pthread_create,, AC_MSG_ERROR("could not find thread libraries"))))) fi ;; *) AC_CHECK_LIB(pthread, pthread_create,, AC_CHECK_LIB(pthread, __pthread_create,, AC_CHECK_LIB(pthread, __pthread_create_system,, AC_CHECK_LIB(c_r, pthread_create,, AC_CHECK_LIB(c, pthread_create,, AC_MSG_ERROR("could not find thread libraries")))))) ;; esac fi bind9-9.10.3.dfsg.P4/Makefile.in0000644000470500017500000000641012664710322015437 0ustar lamontlamont# Copyright (C) 2004-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2002 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.62 2011/09/06 04:06:37 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ SUBDIRS = make unit lib bin doc TARGETS = PREREQS = bind.keys.h MANPAGES = isc-config.sh.1 HTMLPAGES = isc-config.sh.html MANOBJS = ${MANPAGES} ${HTMLPAGES} @BIND9_MAKE_RULES@ bind.keys.h: ${top_srcdir}/bind.keys ${srcdir}/util/bindkeys.pl ${PERL} ${srcdir}/util/bindkeys.pl < ${top_srcdir}/bind.keys > $@ distclean:: rm -f config.cache config.h config.log config.status TAGS rm -f libtool isc-config.sh configure.lineno rm -f util/conf.sh docutil/docbook2man-wrapper.sh # XXX we should clean libtool stuff too. Only do this after we add rules # to make it. maintainer-clean:: rm -f configure rm -f bind.keys.h docclean manclean maintainer-clean:: rm -f ${MANOBJS} doc man:: ${MANOBJS} installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${bindir} \ ${DESTDIR}${localstatedir}/run ${DESTDIR}${sysconfdir} $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man1 install:: isc-config.sh installdirs ${INSTALL_SCRIPT} isc-config.sh ${DESTDIR}${bindir} rm -f ${DESTDIR}${bindir}/bind9-config @LN@ ${DESTDIR}${bindir}/isc-config.sh ${DESTDIR}${bindir}/bind9-config ${INSTALL_DATA} ${top_srcdir}/isc-config.sh.1 ${DESTDIR}${mandir}/man1 rm -f ${DESTDIR}${mandir}/man1/bind9-config.1 @LN@ ${DESTDIR}${mandir}/man1/isc-config.sh.1 ${DESTDIR}${mandir}/man1/bind9-config.1 ${INSTALL_DATA} ${top_srcdir}/bind.keys ${DESTDIR}${sysconfdir} tags: rm -f TAGS find lib bin -name "*.[ch]" -print | @ETAGS@ - test check: @if test -n "`${PERL} ${top_srcdir}/bin/tests/system/testsock.pl 2>&- || echo fail`"; then \ echo I: NOTE: The tests were not run because they require that; \ echo I: the IP addresses 10.53.0.1 through 10.53.0.8 are configured; \ echo I: as alias addresses on the loopback interface. Please run; \ echo I: \'bin/tests/system/ifconfig.sh up\' as root to configure; \ echo I: them, then rerun the tests. Run make force-test to run the; \ echo I: tests anyway.; \ exit 1; \ fi ${MAKE} test-force force-test: test-force test-force: status=0; \ (cd bin/tests && ${MAKE} ${MAKEDEFS} test) || status=1; \ (test -f unit/unittest.sh && $(SHELL) unit/unittest.sh) || status=1; \ exit $$status FAQ: FAQ.xml ${XSLTPROC} doc/xsl/isc-docbook-text.xsl FAQ.xml | \ LC_ALL=C ${W3M} -T text/html -dump -cols 72 >$@.tmp mv $@.tmp $@ unit:: sh ${top_srcdir}/unit/unittest.sh clean:: rm -f FAQ.tmp bind9-9.10.3.dfsg.P4/win32utils/0002755000470500017500000000000012664730167015427 5ustar lamontlamontbind9-9.10.3.dfsg.P4/win32utils/GeoIP.diff0000644000470500017500000003011612664710322017212 0ustar lamontlamontdiff -ruN dists/GeoIP-1.5.1/libGeoIP/GeoIP.c dev/GeoIP-1.5.1/libGeoIP/GeoIP.c --- dists/GeoIP-1.5.1/libGeoIP/GeoIP.c 2013-03-23 03:26:09.000000000 +0100 +++ dev/GeoIP-1.5.1/libGeoIP/GeoIP.c 2013-07-19 16:56:58.000000000 +0200 @@ -19,6 +19,7 @@ */ #include "GeoIP.h" +#include "GeoIP_internal.h" static geoipv6_t IPV6_NULL; @@ -44,6 +45,10 @@ #include /* For uint32_t */ #endif +#if defined(_WIN32) +#include "pread.h" +#endif + #ifdef _UNUSED #elif defined(__GNUC__) #define _UNUSED __attribute__ ((unused)) diff -ruN dists/GeoIP-1.5.1/libGeoIP/GeoIP.h dev/GeoIP-1.5.1/libGeoIP/GeoIP.h --- dists/GeoIP-1.5.1/libGeoIP/GeoIP.h 2013-03-23 03:26:09.000000000 +0100 +++ dev/GeoIP-1.5.1/libGeoIP/GeoIP.h 2013-07-19 16:53:33.000000000 +0200 @@ -154,31 +154,33 @@ GEOIP_CORPORATE_SPEED = 3, } GeoIPNetspeedValues; +#ifdef GEOIP_EXPORTS +#define GEOIP_API __declspec(dllexport) +#define GEOIP_DATA __declspec(dllexport) +#else +#define GEOIP_DATA __declspec(dllimport) +#define GEOIP_API +#endif /* GEOIP_EXPORTS */ + extern char **GeoIPDBFileName; -extern const char * GeoIPDBDescription[NUM_DB_TYPES]; -extern const char *GeoIPCountryDBFileName; -extern const char *GeoIPRegionDBFileName; -extern const char *GeoIPCityDBFileName; -extern const char *GeoIPOrgDBFileName; -extern const char *GeoIPISPDBFileName; -extern const char *GeoIPLocationADBFileName; -extern const char *GeoIPAccuracyRadiusFileName; -extern const char *GeoIPCityConfidenceFileName; +extern GEOIP_DATA const char * GeoIPDBDescription[NUM_DB_TYPES]; +extern GEOIP_DATA const char *GeoIPCountryDBFileName; +extern GEOIP_DATA const char *GeoIPRegionDBFileName; +extern GEOIP_DATA const char *GeoIPCityDBFileName; +extern GEOIP_DATA const char *GeoIPOrgDBFileName; +extern GEOIP_DATA const char *GeoIPISPDBFileName; +extern GEOIP_DATA const char *GeoIPLocationADBFileName; +extern GEOIP_DATA const char *GeoIPAccuracyRadiusFileName; +extern GEOIP_DATA const char *GeoIPCityConfidenceFileName; extern char * GeoIP_custom_directory; /* Warning: do not use those arrays as doing so may break your * program with newer GeoIP versions */ -extern const char GeoIP_country_code[255][3]; -extern const char GeoIP_country_code3[255][4]; -extern const char * GeoIP_country_name[255]; -extern const char * GeoIP_utf8_country_name[255]; -extern const char GeoIP_country_continent[255][3]; - -#ifdef DLL -#define GEOIP_API __declspec(dllexport) -#else -#define GEOIP_API -#endif /* DLL */ +extern GEOIP_DATA const char GeoIP_country_code[255][3]; +extern GEOIP_DATA const char GeoIP_country_code3[255][4]; +extern GEOIP_DATA const char * GeoIP_country_name[255]; +extern GEOIP_DATA const char * GeoIP_utf8_country_name[255]; +extern GEOIP_DATA const char GeoIP_country_continent[255][3]; GEOIP_API void GeoIP_setup_custom_directory(char *dir); GEOIP_API GeoIP* GeoIP_open_type (int type, int flags); diff -ruN dists/GeoIP-1.5.1/libGeoIP/GeoIPCity.c dev/GeoIP-1.5.1/libGeoIP/GeoIPCity.c --- dists/GeoIP-1.5.1/libGeoIP/GeoIPCity.c 2013-03-23 03:26:09.000000000 +0100 +++ dev/GeoIP-1.5.1/libGeoIP/GeoIPCity.c 2013-07-19 15:41:05.000000000 +0200 @@ -35,6 +35,10 @@ #include /* For uint32_t */ #endif +#if defined(_WIN32) +#include "pread.h" +#endif + #ifndef HAVE_PREAD #define pread(fd, buf, count, offset) \ ( \ diff -ruN dists/GeoIP-1.5.1/libGeoIP/GeoIPCity.h dev/GeoIP-1.5.1/libGeoIP/GeoIPCity.h --- dists/GeoIP-1.5.1/libGeoIP/GeoIPCity.h 2013-03-23 03:26:09.000000000 +0100 +++ dev/GeoIP-1.5.1/libGeoIP/GeoIPCity.h 2013-07-19 16:23:58.000000000 +0200 @@ -48,22 +48,22 @@ int netmask; } GeoIPRecord; -GeoIPRecord * GeoIP_record_by_ipnum (GeoIP* gi, unsigned long ipnum); -GeoIPRecord * GeoIP_record_by_addr (GeoIP* gi, const char *addr); -GeoIPRecord * GeoIP_record_by_name (GeoIP* gi, const char *host); - -GeoIPRecord * GeoIP_record_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); -GeoIPRecord * GeoIP_record_by_addr_v6 (GeoIP* gi, const char *addr); -GeoIPRecord * GeoIP_record_by_name_v6 (GeoIP* gi, const char *host); +GEOIP_API GeoIPRecord * GeoIP_record_by_ipnum (GeoIP* gi, unsigned long ipnum); +GEOIP_API GeoIPRecord * GeoIP_record_by_addr (GeoIP* gi, const char *addr); +GEOIP_API GeoIPRecord * GeoIP_record_by_name (GeoIP* gi, const char *host); + +GEOIP_API GeoIPRecord * GeoIP_record_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); +GEOIP_API GeoIPRecord * GeoIP_record_by_addr_v6 (GeoIP* gi, const char *addr); +GEOIP_API GeoIPRecord * GeoIP_record_by_name_v6 (GeoIP* gi, const char *host); -int GeoIP_record_id_by_addr (GeoIP* gi, const char *addr); -int GeoIP_record_id_by_addr_v6 (GeoIP* gi, const char *addr); +GEOIP_API int GeoIP_record_id_by_addr (GeoIP* gi, const char *addr); +GEOIP_API int GeoIP_record_id_by_addr_v6 (GeoIP* gi, const char *addr); -int GeoIP_init_record_iter (GeoIP* gi); +GEOIP_API int GeoIP_init_record_iter (GeoIP* gi); /* returns 0 on success, 1 on failure */ -int GeoIP_next_record (GeoIP* gi, GeoIPRecord **gir, int *record_iter); +GEOIP_API int GeoIP_next_record (GeoIP* gi, GeoIPRecord **gir, int *record_iter); -void GeoIPRecord_delete (GeoIPRecord *gir); +GEOIP_API void GeoIPRecord_delete (GeoIPRecord *gir); /* NULL on failure otherwise a malloced string in utf8 */ /* char * GeoIP_iso_8859_1__utf8(const char *); */ diff -ruN dists/GeoIP-1.5.1/libGeoIP/Makefile.vc dev/GeoIP-1.5.1/libGeoIP/Makefile.vc --- dists/GeoIP-1.5.1/libGeoIP/Makefile.vc 2013-03-23 03:26:09.000000000 +0100 +++ dev/GeoIP-1.5.1/libGeoIP/Makefile.vc 2013-07-19 16:47:45.000000000 +0200 @@ -1,29 +1,42 @@ #NMAKE makefile for Windows developers. -#Produces a static library (GeoIP.lib). +##Produces a static library (GeoIP.lib). +#Produces a DLL (GeoIP.dll) and library (GeoIP.lib). COMPILER=cl -CFLAGS=-DWIN32 -MD -nologo +CFLAGS=-DWIN32 -DGEOIP_EXPORTS -MD -nologo GEOIPINC = -I..\libGeoIP -CC1 = $(COMPILER) $(CFLAGS) $(GEOIPINC) -DGEOIPDATADIR=\"$(GEOIPDATADIR)\" +CC1 = $(COMPILER) $(CFLAGS) $(GEOIPINC) -DGEOIPDATADIR=\"$(GEOIPDATADIR)\" -DPACKAGE_VERSION=\"1.5.1\" -OBJS=GeoIP.obj GeoIPCity.obj regionName.obj md5.obj timeZone.obj +LINKER=link + +LDFLAGS=/DLL /nologo /subsystem:console + +LD1 = $(LINKER) $(LDFLAGS) + +OBJS=GeoIP.obj GeoIPCity.obj GeoIP_depreciated.obj regionName.obj md5.obj timeZone.obj pread.obj -EXTRA_LIBS= advapi32.lib wsock32.lib +EXTRA_LIBS= ws2_32.lib AR=lib -GeoIP.lib: GeoIP.obj GeoIPCity.obj regionName.obj md5.obj timeZone.obj - $(AR) -nologo $(OBJS) $(EXTRA_LIBS) /OUT:GeoIP.lib +#GeoIP.lib: GeoIP.obj GeoIPCity.obj regionName.obj md5.obj timeZone.obj pread.obj +# $(AR) -nologo $(OBJS) $(EXTRA_LIBS) /OUT:GeoIP.lib +GeoIP.dll GeoIP.lib: $(OBJS) + $(LD1) $(OBJS) $(EXTRA_LIBS) /out:GeoIP.dll /implib:GeoIP.lib + GeoIP.obj: GeoIP.c $(CC1) -c GeoIP.c $(GEOIPINC) GeoIPCity.obj: GeoIPCity.c $(CC1) -c GeoIPCity.c $(GEOIPINC) +GeoIP_depreciated.obj: GeoIP_depreciated.c + $(CC1) -c GeoIP_depreciated.c $(GEOIPINC) + regionName.obj: regionName.c $(CC1) -c regionName.c $(GEOIPINC) @@ -32,3 +45,6 @@ timeZone.obj: timeZone.c $(CC1) -c timeZone.c $(GEOIPINC) + +pread.obj: pread.c + $(CC1) -c pread.c $(GEOIPINC) diff -ruN dists/GeoIP-1.5.1/libGeoIP/pread.c dev/GeoIP-1.5.1/libGeoIP/pread.c --- dists/GeoIP-1.5.1/libGeoIP/pread.c 1970-01-01 01:00:00.000000000 +0100 +++ dev/GeoIP-1.5.1/libGeoIP/pread.c 2013-07-19 15:37:44.000000000 +0200 @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include "pread.h" + +CRITICAL_SECTION preadsc; + +#ifdef _WIN64 +int pread(int fd, void *buf, unsigned int nbyte, __int64 offset) +{ + int cc = -1; + __int64 prev = (__int64)-1L; + + EnterCriticalSection(&preadsc); + prev = _lseeki64(fd, 0L, SEEK_CUR); + if (prev == (__int64)-1L) + goto done; + if (_lseeki64(fd, offset, SEEK_SET) != offset) + goto done; + cc = _read(fd, buf, nbyte); + +done: + if (prev != (__int64)-1L) + (void)_lseeki64(fd, prev, SEEK_SET); + LeaveCriticalSection(&preadsc); + + return cc; +} +#else +int pread(int fd, void *buf, unsigned int nbyte, long offset) +{ + int cc = -1; + long prev = -1L; + + EnterCriticalSection(&preadsc); + prev = _lseek(fd, 0L, SEEK_CUR); + if (prev == -1L) + goto done; + if (_lseek(fd, offset, SEEK_SET) != offset) + goto done; + cc = _read(fd, buf, nbyte); + +done: + if (prev != -1L) + (void)_lseek(fd, prev, SEEK_SET); + LeaveCriticalSection(&preadsc); + + return cc; +} +#endif + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved ) +{ + if (fdwReason == DLL_PROCESS_ATTACH) + InitializeCriticalSection(&preadsc); + return TRUE; +} diff -ruN dists/GeoIP-1.5.1/libGeoIP/pread.h dev/GeoIP-1.5.1/libGeoIP/pread.h --- dists/GeoIP-1.5.1/libGeoIP/pread.h 1970-01-01 01:00:00.000000000 +0100 +++ dev/GeoIP-1.5.1/libGeoIP/pread.h 2013-07-19 15:39:01.000000000 +0200 @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef _WIN64 +typedef __int64 ssize_t; + +int pread(int fd, void *buf, unsigned int nbyte, __int64 offset); +#else +typedef int ssize_t; + +int pread(int fd, void *buf, unsigned int nbyte, long offset); +#endif + +#define HAVE_PREAD + +extern CRITICAL_SECTION preadsc; diff -ruN dists/GeoIP-1.5.1/libGeoIP/regionName.c dev/GeoIP-1.5.1/libGeoIP/regionName.c --- dists/GeoIP-1.5.1/libGeoIP/regionName.c 2013-03-23 03:26:09.000000000 +0100 +++ dev/GeoIP-1.5.1/libGeoIP/regionName.c 2013-07-19 16:37:56.000000000 +0200 @@ -1,3 +1,5 @@ +#include "GeoIP.h" + #include #include diff -ruN dists/GeoIP-1.5.1/libGeoIP/timeZone.c dev/GeoIP-1.5.1/libGeoIP/timeZone.c --- dists/GeoIP-1.5.1/libGeoIP/timeZone.c 2013-03-23 03:26:09.000000000 +0100 +++ dev/GeoIP-1.5.1/libGeoIP/timeZone.c 2013-07-19 17:22:44.000000000 +0200 @@ -1,4 +1,7 @@ +#include "GeoIP.h" + #include + const char* GeoIP_time_zone_by_country_and_region(const char * country,const char * region) { const char* timezone = NULL; if (country == NULL) { diff -ruN dists/GeoIP-1.5.1/test/Makefile.vc dev/GeoIP-1.5.1/test/Makefile.vc --- dists/GeoIP-1.5.1/test/Makefile.vc 2013-03-23 03:26:09.000000000 +0100 +++ dev/GeoIP-1.5.1/test/Makefile.vc 2013-07-19 16:48:55.000000000 +0200 @@ -9,7 +9,7 @@ GEOIPINC = -I..\libGeoIP -CC1 = $(COMPILER) $(CFLAGS) $(GEOIPINC) +CC1 = $(COMPILER) $(CFLAGS) $(GEOIPINC) -DSRCDIR=\"../\" GEOIPLIB = ..\libGeoIP\GeoIP.lib diff -ruN dists/GeoIP-1.5.1/test/benchmark.c dev/GeoIP-1.5.1/test/benchmark.c --- dists/GeoIP-1.5.1/test/benchmark.c 2013-03-23 03:26:09.000000000 +0100 +++ dev/GeoIP-1.5.1/test/benchmark.c 2013-07-19 16:26:23.000000000 +0200 @@ -81,7 +81,7 @@ void testgeoiporg(int flags, const char *msg, int numlookups) { GeoIP *i = NULL; - GeoIPRegion *i3 = NULL; + char *i3 = NULL; int i4 = 0; int i2 = 0; double t = 0; bind9-9.10.3.dfsg.P4/win32utils/readme1st.txt0000644000470500017500000001476212664710322020054 0ustar lamontlamontCopyright (C) 2004, 2005, 2007-2009, 2012-2014 Internet Systems Consortium, Inc. ("ISC") Copyright (C) 2001, 2003 Internet Software Consortium. See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. NOTES ON BIND 9.10 FOR WINDOWS: BIND 9.10 is known to run on Windows XP, Vista, Windows 7, and Windows Server 2003 and higher. KIT INSTALLATION: Unpack the kit into any convenient directory and run the BINDInstall program. This will install the named and associated programs into the correct directories and set up the required registry keys. BINDInstall requires that you install it under an account with restricted privileges. The installer will prompt you for an account name (the default is "named") and a password for that account. It will also check for the existence of that account. If it does not exist is will create it with only the privileges required to run BIND. If the account does exist it will check that it has only the one privilege required: "Log on as a service". If it has too many privileges it will prompt you if you want to continue. With BIND running under an account name, it is necessary for all files and directories that BIND uses to have permissions set up for the named account if the files are on an NTFS disk. BIND requires that the account have read and write access to the directory for the pid file, any files that are maintained either for slave zones or for master zones supporting dynamic updates. The account will also need read access to the named.conf and any other file that it needs to read. "NT AUTHORITY\LocalService" is also an acceptable account (and the only acceptable on some recent versions of Windows). This account is built into Windows and no password is required. Appropriate file permissions will also need to be set for "NT AUTHORITY\LocalService" similar to those that would have been required for the "named" account. It is important that on Windows the directory directive is used in the options section to tell BIND where to find the files used in named.conf (default "%ProgramFiles%\ISC BIND 9\etc\named.conf"). For example: options { directory "C:\Program Files (x86)\ISC BIND 9\etc"; }; for a 32 bit BIND on a 64 bit US Domestic Windows system. Messages are logged to the Application log in the EventViewer. CONTROLLING BIND: Windows uses the same rndc program as is used on Unix systems. The rndc.conf file must be configured for your system in order to work. You will need to generate a key for this. To do this use the rndc-confgen program. The program will be installed in the same directory as named: "%ProgramFiles%\ISC BIND 9\bin". From the DOS prompt, use the command this way: rndc-confgen -a which will create a rndc.key file in the "%ProgramFiles%\ISC BIND 9\etc" directory. This will allow you to run rndc without an explicit rndc.conf file or key and control entry in named.conf file. See section 3.4.1.2 of the ARM for details of this. An rndc.conf can also be generated by running: rndc-confgen > rndc.conf which will create the rndc.conf file in the current directory, but not copy it to the "%ProgramFiles%\ISC BIND 9\etc" directory where it needs to reside. If you create rndc.conf this way you will need to copy the same key statement into named.conf. The additions look like the following: key "rndc-key" { algorithm hmac-sha256; secret "xxxxxxxxx=="; }; controls { inet 127.0.0.1 port 953 allow { localhost; } keys { "rndc-key"; }; }; Note that the value of the secret must come from the key generated above for rndc and must be the same key value for both. Details of this may be found in section 3.4.1.2 of the ARM. If you have rndc on a Unix box you can use it to control BIND on the Windows box as well as using the Windows version of rndc to control a BIND 9 daemon on a Unix box. However you must have key statements valid for the servers you wish to control, specifically the IP address and key in both named.conf and rndc.conf. Again see section 3.4.1.2 of the ARM for details. In order to run rndc from a different system it is important to ensure that the clocks are synchronized. The clocks must be kept within 5 minutes of each other or the rndc commands will fail authentication. Use NTP or other time synchronization software to keep your clocks accurate. NTP can be found at http://www.ntp.org/. In addition BIND is installed as a win32 system service, can be started and stopped in the same way as any other service and automatically starts whenever the system is booted. Signals are not supported and are in fact ignored. Note: Unlike most Windows applications, named does not, change its working directory when started as a service. If you wish to use relative files in named.conf you will need to specify a working directory using the directory directive options. DOCUMENTATION: This kit includes Documentation in HTML format. The documentation is not copied during the installation process so you should move it to any convenient location for later reference. Of particular importance is the BIND 9 Administrator's Reference Manual (Bv9ARM*.html) which provides detailed information on BIND 9. In addition, there are HTML pages for each of the BIND 9 applications. INCLUDED TOOLS: The following tools have been built for Windows: dig, nslookup, host, nsupdate, ddns-confgen, rndc, rndc-confgen, named-checkconf, named-checkzone, named-compilezone, named-journalprint, named-rrchecker, dnssec-importkey, dnssec-keygen, dnssec-signzone, dnssec-dsfromkey, dnssec-keyfromlabel, dnssec-revoke, dnssec-settime and dnssec-verify. The latter tools are for use with DNSSEC. All tools are installed in the "%ProgramFiles%\ISC BIND 9\bin" directory. IMPORTANT NOTE ON USING THE TOOLS: It is no longer necessary to create a resolv.conf file on Windows as the tools will look in the registry for the required name server information. However, if you do create a resolv.conf file as follows, the tools will use it in preference to the registry name server entries. Place resolv.conf the "%ProgramFiles%\ISC BIND 9\etc" directory. It must contain a list of recursive server addresses. The format of this file is: nameserver 1.2.3.4 nameserver 5.6.7.8 Replace the above IP addresses with the real name server addresses. 127.0.0.1 is a valid address if you are running a recursive name server on the localhost. PROBLEMS: Please report bugs to bind9-bugs@isc.org. Other questions can go to the bind-users@isc.org mailing list. bind9-9.10.3.dfsg.P4/win32utils/legacy/0002755000470500017500000000000012672612753016672 5ustar lamontlamontbind9-9.10.3.dfsg.P4/win32utils/legacy/BuildAll.bat.in0000644000470500017500000002047312664710322021453 0ustar lamontlamontecho off rem rem Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") rem Copyright (C) 2001-2002 Internet Software Consortium. rem rem Permission to use, copy, modify, and distribute this software for any rem purpose with or without fee is hereby granted, provided that the above rem copyright notice and this permission notice appear in all copies. rem rem THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH rem REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY rem AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, rem INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM rem LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE rem OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR rem PERFORMANCE OF THIS SOFTWARE. rem BuildAll.bat rem This script sets up the files necessary ready to build BIND 9 rem and then builds all of the binaries that make up the installation kit. rem This requires perl to be installed on the system. rem IMPORTANT NOTE: rem OpenSSL is a prerequisite for building and running this release of rem BIND 9. You must fetch the OpenSSL sources yourself from rem http://www.OpenSSL.org/ and compile it yourself. The code must reside rem at the same level as the bind 9.2.0 source tree and it's top-level rem directory be named openssl-0.9.6k. This restriction will be lifted in rem a future release of BIND 9 for Windows NT/2000/XP. echo Setting up the BIND files required for the build rem Setup the files call BuildSetup.bat echo Build all of the Library files cd ..\..\lib cd isc\win32 nmake /nologo -f libisc.mak CFG="libisc - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd dns\win32 nmake /nologo -f libdns.mak CFG="libdns - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd isccfg\win32 nmake /nologo -f libisccfg.mak CFG="libisccfg - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd isccc\win32 nmake /nologo -f libisccc.mak CFG="libisccc - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd bind9\win32 nmake /nologo -f libbind9.mak CFG="libbind9 - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd lwres\win32 nmake /nologo -f liblwres.mak CFG="liblwres - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd irs\win32 nmake /nologo -f libirs.mak CFG="libirs - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. @IF TESTS cd tests\win32 nmake /nologo -f libtests.mak CFG="libtests - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. @END TESTS @IF SAMPLES cd samples\win32 nmake /nologo -f resolve.mak CFG="resolve - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f async.mak CFG="async - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f gai.mak CFG="gai - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f update.mak CFG="update - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f request.mak CFG="request - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f nsprobe.mak CFG="nsprobe - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. @END SAMPLES rem This is the DLL required for the event Viewer cd win32\bindevt nmake /nologo -f bindevt.mak CFG="bindevt - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd .. echo Now build the apps cd bin cd named\win32 nmake /nologo -f named.mak CFG="named - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd rndc\win32 nmake /nologo -f rndc.mak CFG="rndc - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd confgen\win32 nmake /nologo -f rndcconfgen.mak CFG="rndcconfgen - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f ddnsconfgen.mak CFG="ddnsconfgen - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd dig\win32 nmake /nologo -f dig.mak CFG="dig - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo /nologo -f host.mak CFG="host - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f nslookup.mak CFG="nslookup - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd delv\win32 nmake /nologo -f delv.mak CFG="delv - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd nsupdate\win32 nmake /nologo -f nsupdate.mak CFG="nsupdate - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd check\win32 nmake /nologo -f checkconf.mak CFG="checkconf - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f checkzone.mak CFG="checkzone - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd dnssec\win32 nmake /nologo -f keygen.mak CFG="keygen - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f signzone.mak CFG="signzone - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f dsfromkey.mak CFG="dsfromkey - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f keyfromlabel.mak CFG="keyfromlabel - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f revoke.mak CFG="revoke - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f settime.mak CFG="settime - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f verify.mak CFG="verify - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f importkey.mak CFG="importkey - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. @IF PKCS11 cd pkcs11\win32 nmake /nologo -f pk11keygen.mak CFG="pk11keygen - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f pk11list.mak CFG="pk11list - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f pk11destroy.mak CFG="pk11destroy - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f pk11tokens.mak CFG="pk11tokens - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. @END PKCS11 cd tools\win32 nmake /nologo -f arpaname.mak CFG="arpaname - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f genrandom.mak CFG="genrandom - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f nsec3hash.mak CFG="nsec3hash - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f journalprint.mak CFG="journalprint - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f ischmacfixup.mak CFG="ischmacfixup - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f rrchecker.mak CFG="rrchecker - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. @IF TESTS cd tests @IF ATOMIC cd atomic\win32 nmake /nologo -f t_atomic.mak CFG="t_atomic - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. @END ATOMIC cd db\win32 nmake /nologo -f t_db.mak CFG="t_db - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd dst\win32 nmake /nologo -f t_dst.mak CFG="t_dst - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd master\win32 nmake /nologo -f t_master.mak CFG="t_master - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd mem\win32 nmake /nologo -f t_mem.mak CFG="t_mem - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd hashes\win32 nmake /nologo -f t_hashes.mak CFG="t_hashes - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd names\win32 nmake /nologo -f t_names.mak CFG="t_names - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd rbt\win32 nmake /nologo -f t_rbt.mak CFG="t_rbt - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd resolver\win32 nmake /nologo -f t_resolver.mak CFG="t_resolver - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd sockaddr\win32 nmake /nologo -f t_sockaddr.mak CFG="t_sockaddr - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd tasks\win32 nmake /nologo -f t_tasks.mak CFG="t_tasks - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd timers\win32 nmake /nologo -f t_timers.mak CFG="t_timers - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd .. @END TESTS @IF XTESTS cd tests\win32 nmake /nologo -f backtrace_test.mak CFG="backtrace_test - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f inter_test.mak CFG="inter_test - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f rwlock_test.mak CFG="rwlock_test - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f shutdown_test.mak CFG="shutdown_test - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f sock_test.mak CFG="sock_test - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f task_test.mak CFG="task_test - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" nmake /nologo -f timer_test.mak CFG="timer_test - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. @END XTESTS rem This is the BIND 9 Installer cd win32\BINDInstall nmake /nologo -f BINDInstall.mak CFG="BINDInstall - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd ..\.. cd .. cd win32utils\legacy call BuildPost.bat echo Done. rem exit here. bind9-9.10.3.dfsg.P4/win32utils/legacy/makedefs.pl0000644000470500017500000001105112664710322020772 0ustar lamontlamont#!/usr/bin/perl # # Copyright (C) 2004, 2007, 2009, 2012-2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id$ # makedefs.pl # This script goes through all of the lib header files and creates a .def file # for each DLL for Win32. It recurses as necessary through the subdirectories # # This program should only be run if it is necessary to regenerate # the .def files. Normally these files should be updated by hand, adding # new functions to the end and removing obsolete ones. # If you do regenerate them you will also need to modify them by hand to # to pick up those routines not detected by this program (like openlog). # # Search String: ^(([_a-z0-9])*( ))*prefix_[_a-z0-9]+_[a-z0-9]+( )*\( # List of directories @prefixlist = ("isc", "isccfg", "dns", "isccc", "bind9", "lwres", "irs"); @iscdirlist = ("isc/include/isc","isc/win32/include/isc","isc/include/pk11", "isc/include/pkcs11","isc/win32/include/pkcs11"); @iscprefixlist = ("isc", "pk11", "pkcs"); @isccfgdirlist = ("isccfg/include/isccfg"); @isccfgprefixlist = ("cfg"); @iscccdirlist = ("isccc/include/isccc"); @iscccprefixlist = ("isccc"); @dnsdirlist = ("dns/include/dns","dns/include/dst"); @dnsprefixlist = ("dns", "dst"); @lwresdirlist = ("lwres/include/lwres","lwres/win32/include/lwres"); @lwresprefixlist = ("lwres"); @bind9dirlist = ("bind9/include/bind9"); @bind9prefixlist = ("bind9"); @irsdirlist = ("irs/include/irs","irs/win32/include/irs"); @irsprefixlist = ("irs"); # Run the changes for each directory in the directory list $ind = 0; createoutfile($iscprefixlist[0]); foreach $dir (@iscdirlist) { createdeffile($dir, $iscprefixlist[$ind]); $ind++; } close OUTDEFFILE; $ind = 0; createoutfile($isccfgprefixlist[0]); foreach $dir (@isccfgdirlist) { createdeffile($dir, $isccfgprefixlist[$ind]); $ind++; } close OUTDEFFILE; $ind = 0; createoutfile($dnsprefixlist[0]); foreach $dir (@dnsdirlist) { createdeffile($dir, $dnsprefixlist[$ind]); $ind++; } close OUTDEFFILE; $ind = 0; createoutfile($iscccprefixlist[0]); foreach $dir (@iscccdirlist) { createdeffile($dir, $iscccprefixlist[$ind]); $ind++; } close OUTDEFFILE; $ind = 0; createoutfile($lwresprefixlist[0]); foreach $dir (@lwresdirlist) { createdeffile($dir, $lwresprefixlist[$ind]); $ind++; } close OUTDEFFILE; $ind = 0; createoutfile($bind9prefixlist[0]); foreach $dir (@bind9dirlist) { createdeffile($dir, $bind9prefixlist[$ind]); $ind++; } close OUTDEFFILE; $ind = 0; createoutfile($irsprefixlist[0]); foreach $dir (@irsdirlist) { createdeffile($dir, $irsprefixlist[$ind]); $ind++; } close OUTDEFFILE; exit; # # Subroutines # sub createdeffile { $xdir = $_[0]; # # Get the List of files in the directory to be processed. # #^(([_a-z0-9])*( ))*prefix_[_a-z]+_[a-z]+( )*\( $prefix = $_[1]; $pattern = "\^\(\(\[\_a\-z0\-9\]\)\*\( \)\)\*\(\\*\( \)\+\)\*$prefix"; $pattern = "$pattern\_\[\_a\-z0\-9\]\+_\[a\-z0\-9\]\+\( \)\*\\\("; opendir(DIR,$xdir) || die "No Directory: $!"; @files = grep(/\.h$/i, readdir(DIR)); closedir(DIR); foreach $filename (sort @files) { # # Open the file and locate the pattern. # open (HFILE, "$xdir/$filename") || die "Can't open file $filename : $!"; while () { if(/$pattern/) { $func = $&; chop($func); $space = rindex($func, " ") + 1; if($space >= 0) { # strip out return values $func = substr($func, $space, 100); } print OUTDEFFILE "$func\n"; } } # Set up the Patterns close(HFILE); } } # This is the routine that applies the changes # output the result to the platform specific directory. sub createoutfile { $outfile = "lib$_[0].def"; open (OUTDEFFILE, ">$outfile") || die "Can't open output file $outfile: $!"; print OUTDEFFILE "LIBRARY lib$_[0]\n"; print OUTDEFFILE "\n"; print OUTDEFFILE "; Exported Functions\n"; print OUTDEFFILE "EXPORTS\n"; print OUTDEFFILE "\n"; } bind9-9.10.3.dfsg.P4/win32utils/legacy/win32-build.txt0000644000470500017500000001035512664710322021464 0ustar lamontlamontCopyright (C) 2004, 2005, 2008, 2009, 2012-2014 Internet Systems Consortium, Inc. ("ISC") Copyright (C) 2001, 2002 Internet Software Consortium. See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. *LEGACY* BIND 9.10 for Win32 Source Build Instructions. 04-Feb-2014 Building BIND 9.10 on Windows using legacy compilers (up to Visual Studio 2008) has the following prerequisites: 1) Perl, 2) Visual C++ redistributable object, 3) OpenSSL, and optionally 4) LibXML2, 5) LibGeoIP, and 6) Readline. See ..\build.txt for more details on these prerequisites. If you want to build using Visual C++ 6.0, you'll need some extra files that are to be found in the Platform SDK (which you will need to install), namely: iphlpapi.h iptypes.h ipexport.h iphlpapi.lib You'll also need an updated Iprtrmib.h - using the VC++6.0 one will get you some compilation errors. You can just overwrite the old one if you're not using it for any purposes, and maybe keep a backup of it. You can copy the header files under VC98\INCLUDE and the library file under VC98\LIB. I think you can also put them in a separate directory and add it to the include search list, but I don't know if that can be made persistent. For building on VC++ 7.0 or more recent, no extra files are required. The instructions assume a Visual C++ 6.0 compiler with Visual Studio and Visual Studio Service Pack 3 or later. It may build and work with earlier versions but it has not been tested. The binaries may be built and run on any of the following platforms: NT 4.0 Workstation (SP3 or later), NT 4.0 Server (SP3 or later), Windows 2000 Professional (SP1 or later), Windows 2000 Server or any kind (SP1 or later), Windows XP, Windows 2003 Server, Windows Vista, Windows 2008 Server, Windows 7, Windows 2008 R2 Server, Windows 8, Windows 2012 Server (untested), and further (untested as not yet available). It will NOT build or run on Windows 95, Windows 98, etc., or Windows RT platforms. BUILDING BIND From the command prompt cd to the win32utils\legacy directory under the BIND9 root: cd bind-9.10.0\win32utils\legacy If you wish to use nmake from VC++ 6.0 or more recent, run the BuildAll.bat file: BuildAll This will do the following: 1) Build the gen application in the lib/dns directory. 2) Run the gen application and build the required lib/dns header files. 3) Create the Build/Release subdirectory under the root of the BIND source tree which will hold the binaries being built. 4) Build the libraries, named, application tools like dig, rndc dnssec tools, installer, checkconf and checkzones programs, BIND 9 Installer. 5) Copies the release notes and the OpenSSL DLL to the BUILD/Release directory. 6) Copies the BIND 9 ARM HTML files and the application HTML files to the Build\Release area. If you wish to use the Visual Studio GUI for building, you can just run the BuildSetup.bat file: BuildSetup This will create or find and copy into place several files which are necessary for the build to proceed. It also locates and copies into place the DLLs for OpenSSL and libxml2. Use BINDBuild.dsw (also located in the win32utils\legacy directory) to open the workspace for all of the BIND9 libraries and applications. If needed Visual Studio will update the workspace (aka solution) and project files. Note it is known to give slightly incorrect files on VS 2010 or more recent, for instance BINDInstall is not compiled to use DLLs. Finally select "Build->Batch Build", click "Select All", then click "Build". After the build has completed, run the BuildPost.bat file: BuildPost ...which does post-build processing. Installation is accomplished by running the BINDInstall program. All DLL's are copied to the Program Files area and all applications (including BINDInstall which may be necessary for uninstalling BIND 9) to the bin directory. If BIND 8 has previously been installed on the system it must be uninstalled first by running it's own BINDInstall program. The BIND 9 installer does not yet do this. All bugs found, whether in the process of building the application or running BIND or the tools should be reported to the bind9 bugs email account at bind9-bugs@isc.org. bind9-9.10.3.dfsg.P4/win32utils/legacy/BuildPost.bat.in0000644000470500017500000000377612664710322021677 0ustar lamontlamontecho off rem rem Copyright (C) 2005,2013,2014 Internet Systems Consortium, Inc. ("ISC") rem rem Permission to use, copy, modify, and distribute this software for any rem purpose with or without fee is hereby granted, provided that the above rem copyright notice and this permission notice appear in all copies. rem rem THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH rem REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY rem AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, rem INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM rem LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE rem OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR rem PERFORMANCE OF THIS SOFTWARE. rem BuildPost.bat rem This script does the final stages if BINDBuild.dsw is used. echo Copying named-checkzone.exe to named-compilezone.exe copy /Y ..\..\Build\Release\named-checkzone.exe ..\..\Build\Release\named-compilezone.exe if exist ..\..\Build\Debug\named-checkzone.exe copy /Y ..\..\Build\Debug\named-checkzone.exe ..\..\Build\Debug\named-compilezone.exe if exist ..\..\Build\Debug\named-checkzone.ilk copy /Y ..\..\Build\Debug\named-checkzone.ilk ..\..\Build\Debug\named-compilezone.ilk copy /Y ..\..\Build\Release\ddns-confgen.exe ..\..\Build\Release\tsig-keygen.exe if exist ..\..\Build\Debug\ddns-confgen.exe copy /Y ..\..\Build\Debug\ddns-confgen.exe ..\..\Build\Debug\tsig-keygen.exe if exist ..\..\Build\Debug\ddns-confgen.ilk copy /Y ..\..\Build\Debug\ddns-confgen.ilk ..\..\Build\Debug\tsig-keygen.ilk @IF PYTHON echo Copying python scripts copy /Y ..\..\bin\python\dnssec-checkds.py ..\..\Build\Release\dnssec-checkds.py copy /Y ..\..\bin\python\dnssec-checkds.py ..\..\Build\Debug\dnssec-checkds.py copy /Y ..\..\bin\python\dnssec-coverage.py ..\..\Build\Release\dnssec-coverage.py copy /Y ..\..\bin\python\dnssec-coverage.py ..\..\Build\Debug\dnssec-coverage.py @END PYTHON echo Done. rem exit here. bind9-9.10.3.dfsg.P4/win32utils/legacy/BuildSetup.bat.in0000644000470500017500000001411112664710322022033 0ustar lamontlamontecho off rem rem Copyright (C) 2004,2005 Internet Systems Consortium, Inc. ("ISC") rem Copyright (C) 2001-2002 Internet Software Consortium. rem rem Permission to use, copy, modify, and distribute this software for any rem purpose with or without fee is hereby granted, provided that the above rem copyright notice and this permission notice appear in all copies. rem rem THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH rem REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY rem AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, rem INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM rem LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE rem OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR rem PERFORMANCE OF THIS SOFTWARE. rem BuildSetup.bat rem This script sets up the files necessary ready to build BIND 9. rem This requires perl to be installed on the system. echo Generate header files for lib/dns cd ..\..\lib\dns cd win32 nmake /nologo /f gen.mak CFG="gen - @PLATFORM@ Release" NO_EXTERNAL_DEPS="1" cd .. gen -s . -t > include/dns/enumtype.h gen -s . -c > include/dns/enumclass.h gen -s . -i -P ./rdata/rdatastructpre.h -S ./rdata/rdatastructsuf.h > include/dns/rdatastruct.h gen -s . > code.h cd ..\..\win32utils\legacy rem Make sure that the Build directories are there. if NOT Exist ..\..\Build mkdir ..\..\Build if NOT Exist ..\..\Build\Release mkdir ..\..\Build\Release if NOT Exist ..\..\Build\Debug mkdir ..\..\Build\Debug echo Copying the ARM and the Installation Notes. copy ..\..\COPYRIGHT ..\..\Build\Release copy ..\..\COPYRIGHT ..\..\Build\Debug copy ..\..\README ..\..\Build\Release copy ..\..\HISTORY ..\..\Build\Release copy ..\readme1st.txt ..\..\Build\Release copy ..\index.html ..\..\Build\Release copy ..\..\doc\arm\*.html ..\..\Build\Release copy ..\..\doc\arm\notes.pdf ..\..\Build\Release copy ..\..\doc\arm\Bv9ARM.pdf ..\..\Build\Release copy ..\..\CHANGES ..\..\Build\Release if Exist ..\CHANGES.SE copy ..\CHANGES.SE ..\Build\Release copy ..\..\FAQ ..\..\Build\Release echo Copying the standalone manual pages. copy ..\..\bin\named\named.html ..\..\Build\Release copy ..\..\bin\rndc\*.html ..\..\Build\Release copy ..\..\bin\confgen\*.html ..\..\Build\Release copy ..\..\bin\dig\*.html ..\..\Build\Release copy ..\..\bin\delv\*.html ..\..\Build\Release copy ..\..\bin\nsupdate\*.html ..\..\Build\Release copy ..\..\bin\check\*.html ..\..\Build\Release copy ..\..\bin\dnssec\dnssec-keygen.html ..\..\Build\Release copy ..\..\bin\dnssec\dnssec-signzone.html ..\..\Build\Release copy ..\..\bin\dnssec\dnssec-dsfromkey.html ..\..\Build\Release copy ..\..\bin\dnssec\dnssec-keyfromlabel.html ..\..\Build\Release copy ..\..\bin\dnssec\dnssec-settime.html ..\..\Build\Release copy ..\..\bin\dnssec\dnssec-revoke.html ..\..\Build\Release copy ..\..\bin\dnssec\dnssec-verify.html ..\..\Build\Release copy ..\..\bin\dnssec\dnssec-importkey.html ..\..\Build\Release @IF PYTHON copy ..\..\bin\python\dnssec-checkds.html ..\..\Build\Release copy ..\..\bin\python\dnssec-coverage.html ..\..\Build\Release @END PYTHON @IF PKCS11 copy ..\..\bin\pkcs11\pkcs11-keygen.html ..\..\Build\Release copy ..\..\bin\pkcs11\pkcs11-list.html ..\..\Build\Release copy ..\..\bin\pkcs11\pkcs11-destroy.html ..\..\Build\Release copy ..\..\bin\pkcs11\pkcs11-tokens.html ..\..\Build\Release @END PKCS11 copy ..\..\bin\tools\arpaname.html ..\..\Build\Release copy ..\..\bin\tools\genrandom.html ..\..\Build\Release copy ..\..\bin\tools\isc-hmac-fixup.html ..\..\Build\Release copy ..\..\bin\tools\named-journalprint.html ..\..\Build\Release copy ..\..\bin\tools\named-rrchecker.html ..\..\Build\Release copy ..\..\bin\tools\nsec3hash.html ..\..\Build\Release echo Copying the migration notes. copy ..\..\doc\misc\migration ..\..\Build\Release copy ..\..\doc\misc\migration-4to9 ..\..\Build\Release @IF OPENSSL echo Copying the OpenSSL DLL and LICENSE. copy @OPENSSL_DLL@ ..\..\Build\Release\ copy @OPENSSL_DLL@ ..\..\Build\Debug\ copy @OPENSSL_PATH@\LICENSE ..\..\Build\Release\OpenSSL-LICENSE copy @OPENSSL_PATH@\LICENSE ..\..\Build\Debug\OpenSSL-LICENSE @END OPENSSL @IF LIBXML2 echo Copying the libxml DLL. copy @LIBXML2_DLL@ ..\..\Build\Release\ copy @LIBXML2_DLL@ ..\..\Build\Debug\ @END LIBXML2 @IF GSSAPI echo Copying the GSSAPI and KRB5 DLLs. copy @GSSAPI_DLL@ ..\..\Build\Release\ copy @GSSAPI_DLL@ ..\..\Build\Debug\ copy @KRB5_DLL@ ..\..\Build\Release\ copy @KRB5_DLL@ ..\..\Build\Debug\ copy @COMERR_DLL@ ..\..\Build\Release\ copy @COMERR_DLL@ ..\..\Build\Debug\ copy @K5SPRT_DLL@ ..\..\Build\Release\ copy @K5SPRT_DLL@ ..\..\Build\Debug\ copy @WSHELP_DLL@ ..\..\Build\Release\ copy @WSHELP_DLL@ ..\..\Build\Debug\ @END GSSAPI @IF GEOIP echo Copying the GeoIP DLL. copy @GEOIP_DLL@ ..\..\Build\Release\ copy @GEOIP_DLL@ ..\..\Build\Debug\ @END GEOIP @IF IDNKIT echo Copying the IDN kit DLL. copy @IDN_DLL@ ..\Build\Release\ copy @IDN_DLL@ ..\Build\Debug\ copy @ICONV_DLL@ ..\Build\Release\ copy @ICONV_DLL@ ..\Build\Debug\ @END IDNKIT echo Copying the redistributable runtime object. rem rem Use /Y so we always have the current version of the installer. rem copy /Y @VCREDIST_PATH@ ..\..\Build\Release\ copy /Y @VCREDIST_PATH@ ..\..\Build\Debug\ @IF TESTS cd ..\..\bin\tests\dst copy "Kdh.+002+18602.key.in" "Kdh.+002+18602.key" copy "Kdh.+002+18602.private.in" "Kdh.+002+18602.private" copy "Kdh.+002+48957.key.in" "Kdh.+002+48957.key" copy "Kdh.+002+48957.private.in" "Kdh.+002+48957.private" copy "Ktest.+001+00002.key.in" "Ktest.+001+00002.key" copy "Ktest.+001+54622.key.in" "Ktest.+001+54622.key" copy "Ktest.+001+54622.private.in" "Ktest.+001+54622.private" copy "Ktest.+003+23616.key.in" "Ktest.+003+23616.key" copy "Ktest.+003+23616.private.in" "Ktest.+003+23616.private" copy "Ktest.+003+49667.key.in" "Ktest.+003+49667.key" copy dst_2_data.in dst_2_data copy t2_data_1.in t2_data_1 copy t2_data_2.in t2_data_2 copy t2_dsasig.in t2_dsasig copy t2_rsasig.in t2_rsasig cd ..\..\..\win32utils\legacy @END TESTS echo Running Message Compiler cd ..\..\lib\win32\bindevt mc bindevt.mc cd ..\..\..\win32utils\legacy rem Done bind9-9.10.3.dfsg.P4/win32utils/legacy/BINDBuild.dsw.in0000644000470500017500000007345512664710322021516 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "BINDInstall"="..\..\bin\win32\BINDInstall\BINDInstall.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "libisc"="..\..\lib\isc\win32\libisc.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "libdns"="..\..\lib\dns\win32\libdns.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency }}} ############################################################################### Project: "libisccc"="..\..\lib\isccc\win32\libisccc.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency }}} ############################################################################### Project: "libisccfg"="..\..\lib\isccfg\win32\libisccfg.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libisccc End Project Dependency }}} ############################################################################### Project: "libbind9"="..\..\lib\bind9\win32\libbind9.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libisccc End Project Dependency Begin Project Dependency Project_Dep_Name libisccfg End Project Dependency }}} ############################################################################### Project: "liblwres"="..\..\lib\lwres\win32\liblwres.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "libirs"="..\..\lib\irs\win32\libirs.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libisccfg End Project Dependency }}} ############################################################################### Project: "bindevt"="..\..\lib\win32\bindevt\bindevt.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### @IF TESTS Project: "libtests"="..\..\lib\tests\win32\libtests.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency }}} @END TESTS ############################################################################### @IF SAMPLES Project: "resolve"="..\..\lib\samples\win32\resolve.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libisccfg End Project Dependency Begin Project Dependency Project_Dep_Name libirs End Project Dependency }}} ############################################################################### Project: "async"="..\..\lib\samples\win32\async.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libisccfg End Project Dependency }}} ############################################################################### Project: "gai"="..\..\lib\samples\win32\gai.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libisccfg End Project Dependency Begin Project Dependency Project_Dep_Name libirs End Project Dependency }}} ############################################################################### Project: "update"="..\..\lib\samples\win32\update.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libisccfg End Project Dependency }}} ############################################################################### Project: "request"="..\..\lib\samples\win32\request.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libisccfg End Project Dependency }}} ############################################################################### Project: "nsprobe"="..\..\lib\samples\win32\nsprobe.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libisccfg End Project Dependency }}} @END SAMPLES ############################################################################### Project: "named"="..\..\bin\named\win32\named.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libisccc End Project Dependency Begin Project Dependency Project_Dep_Name libisccfg End Project Dependency Begin Project Dependency Project_Dep_Name libbind9 End Project Dependency Begin Project Dependency Project_Dep_Name liblwres End Project Dependency }}} ############################################################################### Project: "rndcutil"="..\..\bin\rndc\win32\rndcutil.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "rndc"="..\..\bin\rndc\win32\rndc.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libisccc End Project Dependency Begin Project Dependency Project_Dep_Name libisccfg End Project Dependency Begin Project Dependency Project_Dep_Name libbind9 End Project Dependency Begin Project Dependency Project_Dep_Name rndcutil End Project Dependency }}} ############################################################################### Project: "delv"="..\..\bin\delv\win32\delv.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libisccfg End Project Dependency Begin Project Dependency Project_Dep_Name libirs End Project Dependency }}} ############################################################################### Project: "dighost"="..\..\bin\dig\win32\dighost.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "dig"="..\..\bin\dig\win32\dig.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libisccc End Project Dependency Begin Project Dependency Project_Dep_Name libisccfg End Project Dependency Begin Project Dependency Project_Dep_Name libbind9 End Project Dependency Begin Project Dependency Project_Dep_Name liblwres End Project Dependency Begin Project Dependency Project_Dep_Name dighost End Project Dependency }}} ############################################################################### Project: "host"="..\..\bin\dig\win32\host.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libisccc End Project Dependency Begin Project Dependency Project_Dep_Name libisccfg End Project Dependency Begin Project Dependency Project_Dep_Name libbind9 End Project Dependency Begin Project Dependency Project_Dep_Name liblwres End Project Dependency Begin Project Dependency Project_Dep_Name dighost End Project Dependency }}} ############################################################################### Project: "nslookup"="..\..\bin\dig\win32\nslookup.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libisccc End Project Dependency Begin Project Dependency Project_Dep_Name libisccfg End Project Dependency Begin Project Dependency Project_Dep_Name libbind9 End Project Dependency Begin Project Dependency Project_Dep_Name liblwres End Project Dependency Begin Project Dependency Project_Dep_Name dighost End Project Dependency }}} ############################################################################### Project: "dnssectool"="..\..\bin\dnssec\win32\dnssectool.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "keygen"="..\..\bin\dnssec\win32\keygen.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name dnssectool End Project Dependency }}} ############################################################################### Project: "signzone"="..\..\bin\dnssec\win32\signzone.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name dnssectool End Project Dependency }}} ############################################################################### Project: "importkey"="..\..\bin\dnssec\win32\importkey.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name dnssectool End Project Dependency }}} ############################################################################### Project: "keyfromlabel"="..\..\bin\dnssec\win32\keyfromlabel.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name dnssectool End Project Dependency }}} ############################################################################### Project: "dsfromkey"="..\..\bin\dnssec\win32\dsfromkey.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name dnssectool End Project Dependency }}} ############################################################################### Project: "revoke"="..\..\bin\dnssec\win32\revoke.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name dnssectool End Project Dependency }}} ############################################################################### Project: "settime"="..\..\bin\dnssec\win32\settime.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name dnssectool End Project Dependency }}} ############################################################################### Project: "verify"="..\..\bin\dnssec\win32\verify.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name dnssectool End Project Dependency }}} ############################################################################### Project: "arpaname"="..\..\bin\tools\win32\arpaname.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency }}} ############################################################################### Project: "journalprint"="..\..\bin\tools\win32\journalprint.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency }}} ############################################################################### Project: "nsec3hash"="..\..\bin\tools\win32\nsec3hash.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency }}} ############################################################################### Project: "rrchecker"="..\..\bin\tools\win32\rrchecker.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency }}} ############################################################################### Project: "genrandom"="..\..\bin\tools\win32\genrandom.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency }}} ############################################################################### Project: "ischmacfixup"="..\..\bin\tools\win32\ischmacfixup.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency }}} ############################################################################### Project: "nsupdate"="..\..\bin\nsupdate\win32\nsupdate.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libisccc End Project Dependency Begin Project Dependency Project_Dep_Name libisccfg End Project Dependency Begin Project Dependency Project_Dep_Name libbind9 End Project Dependency Begin Project Dependency Project_Dep_Name liblwres End Project Dependency }}} ############################################################################### Project: "checktool"="..\..\bin\check\win32\checktool.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "checkconf"="..\..\bin\check\win32\checkconf.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libisccc End Project Dependency Begin Project Dependency Project_Dep_Name libisccfg End Project Dependency Begin Project Dependency Project_Dep_Name libbind9 End Project Dependency Begin Project Dependency Project_Dep_Name checktool End Project Dependency }}} ############################################################################### Project: "checkzone"="..\..\bin\check\win32\checkzone.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libisccc End Project Dependency Begin Project Dependency Project_Dep_Name libisccfg End Project Dependency Begin Project Dependency Project_Dep_Name checktool End Project Dependency }}} ############################################################################### Project: "confgentool"="..\..\bin\confgen\win32\confgentool.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "rndcconfgen"="..\..\bin\confgen\win32\rndcconfgen.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libisccc End Project Dependency Begin Project Dependency Project_Dep_Name libisccfg End Project Dependency Begin Project Dependency Project_Dep_Name libbind9 End Project Dependency Begin Project Dependency Project_Dep_Name confgentool End Project Dependency }}} ############################################################################### Project: "ddnsconfgen"="..\..\bin\confgen\win32\ddnsconfgen.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name confgentool End Project Dependency }}} ############################################################################### @IF PKCS11 Project: "pk11keygen"="..\..\bin\pkcs11\win32\pk11keygen.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency }}} ############################################################################### Project: "pk11list"="..\..\bin\pkcs11\win32\pk11list.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency }}} ############################################################################### Project: "pk11destroy"="..\..\bin\pkcs11\win32\pk11destroy.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency }}} ############################################################################### Project: "pk11tokens"="..\..\bin\pkcs11\win32\pk11tokens.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency }}} @END PKCS11 ############################################################################### @IF TESTS @IF ATOMIC Project: "t_atomic"="..\..\bin\tests\atomic\win32\t_atomic.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libtests End Project Dependency }}} @END ATOMIC ############################################################################### Project: "t_db"="..\..\bin\tests\db\win32\t_db.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libisccfg End Project Dependency Begin Project Dependency Project_Dep_Name libtests End Project Dependency }}} ############################################################################### Project: "t_dst"="..\..\bin\tests\dst\win32\t_dst.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libtests End Project Dependency }}} ############################################################################### Project: "t_master"="..\..\bin\tests\master\win32\t_master.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libtests End Project Dependency }}} ############################################################################### Project: "t_mem"="..\..\bin\tests\mem\win32\t_mem.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libtests End Project Dependency }}} ############################################################################### Project: "t_hashes"="..\..\bin\tests\hashes\win32\t_hashes.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libtests End Project Dependency }}} ############################################################################### Project: "t_names"="..\..\bin\tests\names\win32\t_names.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libtests End Project Dependency }}} ############################################################################### Project: "t_rbt"="..\..\bin\tests\rbt\win32\t_rbt.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libtests End Project Dependency }}} ############################################################################### Project: "t_resolver"="..\..\bin\tests\resolver\win32\t_resolver.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libdns End Project Dependency Begin Project Dependency Project_Dep_Name libtests End Project Dependency }}} ############################################################################### Project: "t_sockaddr"="..\..\bin\tests\sockaddr\win32\t_sockaddr.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libtests End Project Dependency }}} ############################################################################### Project: "t_tasks"="..\..\bin\tests\tasks\win32\t_tasks.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libtests End Project Dependency }}} ############################################################################### Project: "t_timers"="..\..\bin\tests\timers\win32\t_timers.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency Begin Project Dependency Project_Dep_Name libtests End Project Dependency }}} @END TESTS ############################################################################### @IF XTESTS Project: "backtrace_test"="..\..\bin\tests\win32\backtrace_test.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency }}} ############################################################################### Project: "inter_test"="..\..\bin\tests\win32\inter_test.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency }}} ############################################################################### Project: "rwlock_test"="..\..\bin\tests\win32\rwlock_test.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency }}} ############################################################################### Project: "shutdown_test"="..\..\bin\tests\win32\shutdown_test.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency }}} ############################################################################### Project: "sock_test"="..\..\bin\tests\win32\sock_test.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency }}} ############################################################################### Project: "task_test"="..\..\bin\tests\win32\task_test.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency }}} ############################################################################### Project: "timer_test"="..\..\bin\tests\win32\timer_test.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libisc End Project Dependency }}} @END XTESTS ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/win32utils/bind9.sln.in0000644000470500017500000020537712664710322017562 0ustar lamontlamont Microsoft Visual Studio Solution File, Format Version 11.00 # Visual C++ Express 2010 # BINDInstall must be the first project Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BINDInstall", "..\bin\win32\BINDInstall\BINDInstall.vcxproj", "{190CC424-E8CC-46F2-9013-3152D6905118}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {B556705F-1920-4400-878A-B259D3556047} = {B556705F-1920-4400-878A-B259D3556047} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} {E741C10B-B075-4206-9596-46765B665E03} = {E741C10B-B075-4206-9596-46765B665E03} {EBDB30A3-E8EB-4E1D-915E-06720600A84E} = {EBDB30A3-E8EB-4E1D-915E-06720600A84E} {A4F29CEB-7644-4A7F-BE9E-02B6A90E4919} = {A4F29CEB-7644-4A7F-BE9E-02B6A90E4919} {0D745CD9-FC3B-49DC-99BE-1E6DF85593F0} = {0D745CD9-FC3B-49DC-99BE-1E6DF85593F0} @IF TESTS {F6F08940-7597-4FEE-9CE0-E09A009C45A3} = {F6F08940-7597-4FEE-9CE0-E09A009C45A3} @END TESTS @IF SAMPLES {F66D8B7E-721D-4602-99AD-820D19AD1313} = {F66D8B7E-721D-4602-99AD-820D19AD1313} {9FC33CA3-CE4A-4EDF-BA99-EECA4B81AD06} = {9FC33CA3-CE4A-4EDF-BA99-EECA4B81AD06} {D42B8670-8DF6-4D90-90F7-DB5FB845AFAE} = {D42B8670-8DF6-4D90-90F7-DB5FB845AFAE} {05682E12-523F-4DAE-8E6D-ADFDBC308AFD} = {05682E12-523F-4DAE-8E6D-ADFDBC308AFD} {FF440E85-7450-439C-82EE-04C464512D0E} = {FF440E85-7450-439C-82EE-04C464512D0E} {CB2A29F6-E73B-40AB-8AC4-2C1AAE7280BD} = {CB2A29F6-E73B-40AB-8AC4-2C1AAE7280BD} @END SAMPLES {723C65DA-A96C-4BA3-A34E-44F11CA346F9} = {723C65DA-A96C-4BA3-A34E-44F11CA346F9} {7C8681A1-E3A8-470E-9EEF-16054D111A19} = {7C8681A1-E3A8-470E-9EEF-16054D111A19} {39721F26-8B80-4AA9-9826-2AEF7322C3D5} = {39721F26-8B80-4AA9-9826-2AEF7322C3D5} {140DE800-E552-43CC-B0C7-A33A92E368CA} = {140DE800-E552-43CC-B0C7-A33A92E368CA} {F938F9B8-D395-4A40-BEC7-0122D289C692} = {F938F9B8-D395-4A40-BEC7-0122D289C692} {BA1048A8-6961-4A20-BE12-08BE20611C9D} = {BA1048A8-6961-4A20-BE12-08BE20611C9D} {C15A6E1A-94CE-4686-99F9-6BC5FD623EB5} = {C15A6E1A-94CE-4686-99F9-6BC5FD623EB5} {BE172EFE-C1DC-4812-BFB9-8C5F8ADB7E9F} = {BE172EFE-C1DC-4812-BFB9-8C5F8ADB7E9F} {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70} = {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70} {0BF11E21-168C-4CAA-B784-429D126BBAE5} = {0BF11E21-168C-4CAA-B784-429D126BBAE5} {205ED8A9-2E4C-41CC-9385-F3613402AA90} = {205ED8A9-2E4C-41CC-9385-F3613402AA90} {17455DC6-5FBB-47C3-8F44-7DB574A188D3} = {17455DC6-5FBB-47C3-8F44-7DB574A188D3} {6E6297F4-69D7-4533-85E1-BD17C30017C8} = {6E6297F4-69D7-4533-85E1-BD17C30017C8} {D171F185-D3C2-4463-9CF3-ED1D0B1D6832} = {D171F185-D3C2-4463-9CF3-ED1D0B1D6832} {03FB7588-C5A7-4572-968F-14F1206BC69C} = {03FB7588-C5A7-4572-968F-14F1206BC69C} {FD653434-F1A8-44A9-85B2-A7468491DA6D} = {FD653434-F1A8-44A9-85B2-A7468491DA6D} {AB6690A0-055E-458f-BAC5-BF38BCC5834F} = {AB6690A0-055E-458f-BAC5-BF38BCC5834F} {91E60FDA-E48C-4DA0-92A2-97F963348E00} = {91E60FDA-E48C-4DA0-92A2-97F963348E00} {B19042CE-D3D9-469B-BCD2-C3140150939A} = {B19042CE-D3D9-469B-BCD2-C3140150939A} {4EE91023-94C3-48C0-B71C-5333B726C2EE} = {4EE91023-94C3-48C0-B71C-5333B726C2EE} {B4AC7F81-E3DC-43E9-B339-4FA5149FA8F7} = {B4AC7F81-E3DC-43E9-B339-4FA5149FA8F7} {70F2F0DF-665D-4444-A982-AEA31A861A22} = {70F2F0DF-665D-4444-A982-AEA31A861A22} {98743A7C-6AF8-467f-9911-FA69C451AF2B} = {98743A7C-6AF8-467f-9911-FA69C451AF2B} {C41266C7-E27E-4D60-9815-82D3B32BF82F} = {C41266C7-E27E-4D60-9815-82D3B32BF82F} {2C1F7096-C5B5-48D4-846F-A7ACA454335D} = {2C1F7096-C5B5-48D4-846F-A7ACA454335D} {03A96113-CB14-43AA-AEB2-48950E3915C5} = {03A96113-CB14-43AA-AEB2-48950E3915C5} {66028555-7DD5-4016-B601-9EF9A1EE8BFA} = {66028555-7DD5-4016-B601-9EF9A1EE8BFA} {64964B03-4815-41F0-9057-E766A94AF197} = {64964B03-4815-41F0-9057-E766A94AF197} {1E2C1635-3093-4D59-80E7-4743AC10F22F} = {1E2C1635-3093-4D59-80E7-4743AC10F22F} {1EA4FC64-F33B-4A50-970A-EA052BBE9CF1} = {1EA4FC64-F33B-4A50-970A-EA052BBE9CF1} @IF PKCS11 {5042D371-0402-4FA3-A52A-769708694422} = {5042D371-0402-4FA3-A52A-769708694422} {C663B088-F7BC-4C8C-8D06-A76636EED651} = {C663B088-F7BC-4C8C-8D06-A76636EED651} {5B3137E5-7E1F-49AA-8810-A09AA417D326} = {5B3137E5-7E1F-49AA-8810-A09AA417D326} {403FD4B1-A4F9-4159-9013-5860E3A4417D} = {403FD4B1-A4F9-4159-9013-5860E3A4417D} @END PKCS11 @IF TESTS @IF ATOMIC {EC6ECB35-58C0-48EC-BAC9-9A652D9406C9} = {EC6ECB35-58C0-48EC-BAC9-9A652D9406C9} @END ATOMIC {E6338E67-3224-4E66-9463-7AD719DA9346} = {E6338E67-3224-4E66-9463-7AD719DA9346} {EE9B94CF-7C33-4F3B-A674-FB756D422C54} = {EE9B94CF-7C33-4F3B-A674-FB756D422C54} {5DC2F8D3-9373-41BB-B3AB-78F2E12F1E5E} = {5DC2F8D3-9373-41BB-B3AB-78F2E12F1E5E} {627F32A9-267F-41CA-827C-1FD04DE20A56} = {627F32A9-267F-41CA-827C-1FD04DE20A56} {14071120-84F6-4A6F-BF23-90EC5D0372CE} = {14071120-84F6-4A6F-BF23-90EC5D0372CE} {124DC0D3-3096-41D2-B490-CE85E890FF33} = {124DC0D3-3096-41D2-B490-CE85E890FF33} {39F714D4-FEFB-4E23-91DB-1F6FC80A98B5} = {39F714D4-FEFB-4E23-91DB-1F6FC80A98B5} {66E58849-A764-44E4-8D32-7C1107246A26} = {66E58849-A764-44E4-8D32-7C1107246A26} {351D3872-707B-46AD-8BC0-5A668B8C745B} = {351D3872-707B-46AD-8BC0-5A668B8C745B} {2CB7B128-5954-4FAF-B5EA-501B23BB8054} = {2CB7B128-5954-4FAF-B5EA-501B23BB8054} {4E6F5A7C-89AA-4259-99DB-F89DAE418B3F} = {4E6F5A7C-89AA-4259-99DB-F89DAE418B3F} @END TESTS @IF XTESTS {14751171-C40E-40EE-A2F0-37FFC3CCD4A2} = {14751171-C40E-40EE-A2F0-37FFC3CCD4A2} {06AA5F16-7121-4C3A-91EF-AFC3BF3B8CE1} = {06AA5F16-7121-4C3A-91EF-AFC3BF3B8CE1} {7705EEF6-6980-48F9-A045-699DAFE860C9} = {7705EEF6-6980-48F9-A045-699DAFE860C9} {551561F6-4A2A-4824-8A34-A4AF0EB7C179} = {551561F6-4A2A-4824-8A34-A4AF0EB7C179} {6200ED9D-CAB1-4C00-8D79-478F64A19B8F} = {6200ED9D-CAB1-4C00-8D79-478F64A19B8F} {CC7340C1-CBAF-4145-969A-73AE960401D6} = {CC7340C1-CBAF-4145-969A-73AE960401D6} {E55653C8-5501-4871-A97C-C926631F40F9} = {E55653C8-5501-4871-A97C-C926631F40F9} @END XTESTS EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gen", "..\lib\dns\win32\gen.vcxproj", "{A3F71D12-F38A-4C77-8D87-8E8854CA74A1}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libisc", "..\lib\isc\win32\libisc.vcxproj", "{3840E563-D180-4761-AA9C-E6155F02EAFF}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libisccc", "..\lib\isccc\win32\libisccc.vcxproj", "{B556705F-1920-4400-878A-B259D3556047}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libdns", "..\lib\dns\win32\libdns.vcxproj", "{5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libisccfg", "..\lib\isccfg\win32\libisccfg.vcxproj", "{B2DFA58C-6347-478E-81E8-01E06999D4F1}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {B556705F-1920-4400-878A-B259D3556047} = {B556705F-1920-4400-878A-B259D3556047} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbind9", "..\lib\bind9\win32\libbind9.vcxproj", "{E741C10B-B075-4206-9596-46765B665E03}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {B556705F-1920-4400-878A-B259D3556047} = {B556705F-1920-4400-878A-B259D3556047} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblwres", "..\lib\lwres\win32\liblwres.vcxproj", "{EBDB30A3-E8EB-4E1D-915E-06720600A84E}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libirs", "..\lib\irs\win32\libirs.vcxproj", "{A4F29CEB-7644-4A7F-BE9E-02B6A90E4919}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bindevt", "..\lib\win32\bindevt\bindevt.vcxproj", "{0D745CD9-FC3B-49DC-99BE-1E6DF85593F0}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} EndProjectSection EndProject @IF TESTS Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtests", "..\lib\tests\win32\libtests.vcxproj", "{F6F08940-7597-4FEE-9CE0-E09A009C45A3}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} EndProjectSection EndProject @END TESTS @IF SAMPLES Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resolve", "..\lib\samples\win32\resolve.vcxproj", "{F66D8B7E-721D-4602-99AD-820D19AD1313}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} {A4F29CEB-7644-4A7F-BE9E-02B6A90E4919} = {A4F29CEB-7644-4A7F-BE9E-02B6A90E4919} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "async", "..\lib\samples\win32\async.vcxproj", "{9FC33CA3-CE4A-4EDF-BA99-EECA4B81AD06}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gai", "..\lib\samples\win32\gai.vcxproj", "{D42B8670-8DF6-4D90-90F7-DB5FB845AFAE}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} {A4F29CEB-7644-4A7F-BE9E-02B6A90E4919} = {A4F29CEB-7644-4A7F-BE9E-02B6A90E4919} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "update", "..\lib\samples\win32\update.vcxproj", "{05682E12-523F-4DAE-8E6D-ADFDBC308AFD}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "request", "..\lib\samples\win32\request.vcxproj", "{FF440E85-7450-439C-82EE-04C464512D0E}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nsprobe", "..\lib\samples\win32\nsprobe.vcxproj", "{CB2A29F6-E73B-40AB-8AC4-2C1AAE7280BD}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} EndProjectSection EndProject @END SAMPLES Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "named", "..\bin\named\win32\named.vcxproj", "{723C65DA-A96C-4BA3-A34E-44F11CA346F9}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {B556705F-1920-4400-878A-B259D3556047} = {B556705F-1920-4400-878A-B259D3556047} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} {E741C10B-B075-4206-9596-46765B665E03} = {E741C10B-B075-4206-9596-46765B665E03} {EBDB30A3-E8EB-4E1D-915E-06720600A84E} = {EBDB30A3-E8EB-4E1D-915E-06720600A84E} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rndcutil", "..\bin\rndc\win32\rndcutil.vcxproj", "{7C8681A1-E3A8-470E-9EEF-16054D111A19}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rndc", "..\bin\rndc\win32\rndc.vcxproj", "{39721F26-8B80-4AA9-9826-2AEF7322C3D5}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {B556705F-1920-4400-878A-B259D3556047} = {B556705F-1920-4400-878A-B259D3556047} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} {E741C10B-B075-4206-9596-46765B665E03} = {E741C10B-B075-4206-9596-46765B665E03} {7C8681A1-E3A8-470E-9EEF-16054D111A19} = {7C8681A1-E3A8-470E-9EEF-16054D111A19} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dighost", "..\bin\dig\win32\dighost.vcxproj", "{140DE800-E552-43CC-B0C7-A33A92E368CA}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} {E741C10B-B075-4206-9596-46765B665E03} = {E741C10B-B075-4206-9596-46765B665E03} {EBDB30A3-E8EB-4E1D-915E-06720600A84E} = {EBDB30A3-E8EB-4E1D-915E-06720600A84E} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dig", "..\bin\dig\win32\dig.vcxproj", "{F938F9B8-D395-4A40-BEC7-0122D289C692}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} {E741C10B-B075-4206-9596-46765B665E03} = {E741C10B-B075-4206-9596-46765B665E03} {EBDB30A3-E8EB-4E1D-915E-06720600A84E} = {EBDB30A3-E8EB-4E1D-915E-06720600A84E} {140DE800-E552-43CC-B0C7-A33A92E368CA} = {140DE800-E552-43CC-B0C7-A33A92E368CA} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "host", "..\bin\dig\win32\host.vcxproj", "{BA1048A8-6961-4A20-BE12-08BE20611C9D}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} {E741C10B-B075-4206-9596-46765B665E03} = {E741C10B-B075-4206-9596-46765B665E03} {EBDB30A3-E8EB-4E1D-915E-06720600A84E} = {EBDB30A3-E8EB-4E1D-915E-06720600A84E} {140DE800-E552-43CC-B0C7-A33A92E368CA} = {140DE800-E552-43CC-B0C7-A33A92E368CA} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nslookup", "..\bin\dig\win32\nslookup.vcxproj", "{C15A6E1A-94CE-4686-99F9-6BC5FD623EB5}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} {E741C10B-B075-4206-9596-46765B665E03} = {E741C10B-B075-4206-9596-46765B665E03} {EBDB30A3-E8EB-4E1D-915E-06720600A84E} = {EBDB30A3-E8EB-4E1D-915E-06720600A84E} {140DE800-E552-43CC-B0C7-A33A92E368CA} = {140DE800-E552-43CC-B0C7-A33A92E368CA} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "delv", "..\bin\delv\win32\delv.vcxproj", "{BE172EFE-C1DC-4812-BFB9-8C5F8ADB7E9F}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} {A4F29CEB-7644-4A7F-BE9E-02B6A90E4919} = {A4F29CEB-7644-4A7F-BE9E-02B6A90E4919} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dnssectool", "..\bin\dnssec\win32\dnssectool.vcxproj", "{2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "keygen", "..\bin\dnssec\win32\keygen.vcxproj", "{0BF11E21-168C-4CAA-B784-429D126BBAE5}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70} = {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "signzone", "..\bin\dnssec\win32\signzone.vcxproj", "{205ED8A9-2E4C-41CC-9385-F3613402AA90}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70} = {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "keyfromlabel", "..\bin\dnssec\win32\keyfromlabel.vcxproj", "{17455DC6-5FBB-47C3-8F44-7DB574A188D3}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70} = {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dsfromkey", "..\bin\dnssec\win32\dsfromkey.vcxproj", "{6E6297F4-69D7-4533-85E1-BD17C30017C8}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70} = {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "revoke", "..\bin\dnssec\win32\revoke.vcxproj", "{D171F185-D3C2-4463-9CF3-ED1D0B1D6832}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70} = {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "settime", "..\bin\dnssec\win32\settime.vcxproj", "{03FB7588-C5A7-4572-968F-14F1206BC69C}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70} = {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "verify", "..\bin\dnssec\win32\verify.vcxproj", "{FD653434-F1A8-44A9-85B2-A7468491DA6D}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70} = {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "importkey", "..\bin\dnssec\win32\importkey.vcxproj", "{AB6690A0-055E-458f-BAC5-BF38BCC5834F}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70} = {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "arpaname", "..\bin\tools\win32\arpaname.vcxproj", "{91E60FDA-E48C-4DA0-92A2-97F963348E00}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "journalprint", "..\bin\tools\win32\journalprint.vcxproj", "{B19042CE-D3D9-469B-BCD2-C3140150939A}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nsec3hash", "..\bin\tools\win32\nsec3hash.vcxproj", "{4EE91023-94C3-48C0-B71C-5333B726C2EE}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "genrandom", "..\bin\tools\win32\genrandom.vcxproj", "{B4AC7F81-E3DC-43E9-B339-4FA5149FA8F7}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ischmacfixup", "..\bin\tools\win32\ischmacfixup.vcxproj", "{70F2F0DF-665D-4444-A982-AEA31A861A22}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rrchecker", "..\bin\tools\win32\rrchecker.vcxproj", "{98743A7C-6AF8-467f-9911-FA69C451AF2B}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nsupdate", "..\bin\nsupdate\win32\nsupdate.vcxproj", "{C41266C7-E27E-4D60-9815-82D3B32BF82F}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} {E741C10B-B075-4206-9596-46765B665E03} = {E741C10B-B075-4206-9596-46765B665E03} {EBDB30A3-E8EB-4E1D-915E-06720600A84E} = {EBDB30A3-E8EB-4E1D-915E-06720600A84E} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "checktool", "..\bin\check\win32\checktool.vcxproj", "{2C1F7096-C5B5-48D4-846F-A7ACA454335D}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "checkconf", "..\bin\check\win32\checkconf.vcxproj", "{03A96113-CB14-43AA-AEB2-48950E3915C5}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} {E741C10B-B075-4206-9596-46765B665E03} = {E741C10B-B075-4206-9596-46765B665E03} {2C1F7096-C5B5-48D4-846F-A7ACA454335D} = {2C1F7096-C5B5-48D4-846F-A7ACA454335D} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "checkzone", "..\bin\check\win32\checkzone.vcxproj", "{66028555-7DD5-4016-B601-9EF9A1EE8BFA}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} {2C1F7096-C5B5-48D4-846F-A7ACA454335D} = {2C1F7096-C5B5-48D4-846F-A7ACA454335D} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "confgentool", "..\bin\confgen\win32\confgentool.vcxproj", "{64964B03-4815-41F0-9057-E766A94AF197}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {B556705F-1920-4400-878A-B259D3556047} = {B556705F-1920-4400-878A-B259D3556047} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rndcconfgen", "..\bin\confgen\win32\rndcconfgen.vcxproj", "{1E2C1635-3093-4D59-80E7-4743AC10F22F}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {B556705F-1920-4400-878A-B259D3556047} = {B556705F-1920-4400-878A-B259D3556047} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} {64964B03-4815-41F0-9057-E766A94AF197} = {64964B03-4815-41F0-9057-E766A94AF197} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ddnsconfgen", "..\bin\confgen\win32\ddnsconfgen.vcxproj", "{1EA4FC64-F33B-4A50-970A-EA052BBE9CF1}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {B556705F-1920-4400-878A-B259D3556047} = {B556705F-1920-4400-878A-B259D3556047} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} {64964B03-4815-41F0-9057-E766A94AF197} = {64964B03-4815-41F0-9057-E766A94AF197} EndProjectSection EndProject @IF PKCS11 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pk11keygen", "..\bin\pkcs11\win32\pk11keygen.vcxproj", "{5042D371-0402-4FA3-A52A-769708694422}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pk11list", "..\bin\pkcs11\win32\pk11list.vcxproj", "{C663B088-F7BC-4C8C-8D06-A76636EED651}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pk11destroy", "..\bin\pkcs11\win32\pk11destroy.vcxproj", "{5B3137E5-7E1F-49AA-8810-A09AA417D326}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pk11tokens", "..\bin\pkcs11\win32\pk11tokens.vcxproj", "{403FD4B1-A4F9-4159-9013-5860E3A4417D}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} EndProjectSection EndProject @END PKCS11 @IF TESTS @IF ATOMIC Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "t_atomic", "..\bin\tests\atomic\win32\t_atomic.vcxproj", "{EC6ECB35-58C0-48EC-BAC9-9A652D9406C9}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {F6F08940-7597-4FEE-9CE0-E09A009C45A3} = {F6F08940-7597-4FEE-9CE0-E09A009C45A3} EndProjectSection EndProject @END ATOMIC Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "t_db", "..\bin\tests\db\win32\t_db.vcxproj", "{E6338E67-3224-4E66-9463-7AD719DA9346}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {B2DFA58C-6347-478E-81E8-01E06999D4F1} = {B2DFA58C-6347-478E-81E8-01E06999D4F1} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "t_dst", "..\bin\tests\dst\win32\t_dst.vcxproj", "{EE9B94CF-7C33-4F3B-A674-FB756D422C54}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {F6F08940-7597-4FEE-9CE0-E09A009C45A3} = {F6F08940-7597-4FEE-9CE0-E09A009C45A3} {B4AC7F81-E3DC-43E9-B339-4FA5149FA8F7} = {B4AC7F81-E3DC-43E9-B339-4FA5149FA8F7} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "t_master", "..\bin\tests\master\win32\t_master.vcxproj", "{5DC2F8D3-9373-41BB-B3AB-78F2E12F1E5E}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {F6F08940-7597-4FEE-9CE0-E09A009C45A3} = {F6F08940-7597-4FEE-9CE0-E09A009C45A3} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "t_mem", "..\bin\tests\mem\win32\t_mem.vcxproj", "{627F32A9-267F-41CA-827C-1FD04DE20A56}" ProjectSection(ProjectDependencies) = postProject {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {F6F08940-7597-4FEE-9CE0-E09A009C45A3} = {F6F08940-7597-4FEE-9CE0-E09A009C45A3} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "t_hashes", "..\bin\tests\hashes\win32\t_hashes.vcxproj", "{14071120-84F6-4A6F-BF23-90EC5D0372CE}" ProjectSection(ProjectDependencies) = postProject {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {F6F08940-7597-4FEE-9CE0-E09A009C45A3} = {F6F08940-7597-4FEE-9CE0-E09A009C45A3} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "t_names", "..\bin\tests\names\win32\t_names.vcxproj", "{124DC0D3-3096-41D2-B490-CE85E890FF33}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {F6F08940-7597-4FEE-9CE0-E09A009C45A3} = {F6F08940-7597-4FEE-9CE0-E09A009C45A3} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "t_rbt", "..\bin\tests\rbt\win32\t_rbt.vcxproj", "{39F714D4-FEFB-4E23-91DB-1F6FC80A98B5}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {F6F08940-7597-4FEE-9CE0-E09A009C45A3} = {F6F08940-7597-4FEE-9CE0-E09A009C45A3} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "t_resolver", "..\bin\tests\resolver\win32\t_resolver.vcxproj", "{66E58849-A764-44E4-8D32-7C1107246A26}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} = {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} {F6F08940-7597-4FEE-9CE0-E09A009C45A3} = {F6F08940-7597-4FEE-9CE0-E09A009C45A3} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "t_sockaddr", "..\bin\tests\sockaddr\win32\t_sockaddr.vcxproj", "{351D3872-707B-46AD-8BC0-5A668B8C745B}" ProjectSection(ProjectDependencies) = postProject {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {F6F08940-7597-4FEE-9CE0-E09A009C45A3} = {F6F08940-7597-4FEE-9CE0-E09A009C45A3} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "t_tasks", "..\bin\tests\tasks\win32\t_tasks.vcxproj", "{2CB7B128-5954-4FAF-B5EA-501B23BB8054}" ProjectSection(ProjectDependencies) = postProject {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {F6F08940-7597-4FEE-9CE0-E09A009C45A3} = {F6F08940-7597-4FEE-9CE0-E09A009C45A3} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "t_timers", "..\bin\tests\timers\win32\t_timers.vcxproj", "{4E6F5A7C-89AA-4259-99DB-F89DAE418B3F}" ProjectSection(ProjectDependencies) = postProject {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} {F6F08940-7597-4FEE-9CE0-E09A009C45A3} = {F6F08940-7597-4FEE-9CE0-E09A009C45A3} EndProjectSection EndProject @END TESTS @IF XTESTS Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "backtrace_test", "..\bin\tests\win32\backtrace_test.vcxproj", "{14751171-C40E-40EE-A2F0-37FFC3CCD4A2}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "inter_test", "..\bin\tests\win32\inter_test.vcxproj", "{06AA5F16-7121-4C3A-91EF-AFC3BF3B8CE1}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rwlock_test", "..\bin\tests\win32\rwlock_test.vcxproj", "{7705EEF6-6980-48F9-A045-699DAFE860C9}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shutdown_test", "..\bin\tests\win32\shutdown_test.vcxproj", "{551561F6-4A2A-4824-8A34-A4AF0EB7C179}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sock_test", "..\bin\tests\win32\sock_test.vcxproj", "{6200ED9D-CAB1-4C00-8D79-478F64A19B8F}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "task_test", "..\bin\tests\win32\task_test.vcxproj", "{CC7340C1-CBAF-4145-969A-73AE960401D6}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "timer_test", "..\bin\tests\win32\timer_test.vcxproj", "{E55653C8-5501-4871-A97C-C926631F40F9}" ProjectSection(ProjectDependencies) = postProject {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} = {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} {3840E563-D180-4761-AA9C-E6155F02EAFF} = {3840E563-D180-4761-AA9C-E6155F02EAFF} EndProjectSection EndProject @END XTESTS Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|@PLATFORM@ = Debug|@PLATFORM@ Release|@PLATFORM@ = Release|@PLATFORM@ EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {190CC424-E8CC-46F2-9013-3152D6905118}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {190CC424-E8CC-46F2-9013-3152D6905118}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {190CC424-E8CC-46F2-9013-3152D6905118}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {190CC424-E8CC-46F2-9013-3152D6905118}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {A3F71D12-F38A-4C77-8D87-8E8854CA74A1}.Debug|@BUILD_PLATFORM@.ActiveCfg = Debug|@BUILD_PLATFORM@ {A3F71D12-F38A-4C77-8D87-8E8854CA74A1}.Debug|@BUILD_PLATFORM@.Build.0 = Debug|@BUILD_PLATFORM@ {A3F71D12-F38A-4C77-8D87-8E8854CA74A1}.Release|@BUILD_PLATFORM@.ActiveCfg = Release|@BUILD_PLATFORM@ {A3F71D12-F38A-4C77-8D87-8E8854CA74A1}.Release|@BUILD_PLATFORM@.Build.0 = Release|@BUILD_PLATFORM@ {3840E563-D180-4761-AA9C-E6155F02EAFF}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {3840E563-D180-4761-AA9C-E6155F02EAFF}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {3840E563-D180-4761-AA9C-E6155F02EAFF}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {3840E563-D180-4761-AA9C-E6155F02EAFF}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {B556705F-1920-4400-878A-B259D3556047}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {B556705F-1920-4400-878A-B259D3556047}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {B556705F-1920-4400-878A-B259D3556047}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {B556705F-1920-4400-878A-B259D3556047}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {B2DFA58C-6347-478E-81E8-01E06999D4F1}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {B2DFA58C-6347-478E-81E8-01E06999D4F1}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {B2DFA58C-6347-478E-81E8-01E06999D4F1}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {B2DFA58C-6347-478E-81E8-01E06999D4F1}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {E741C10B-B075-4206-9596-46765B665E03}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {E741C10B-B075-4206-9596-46765B665E03}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {E741C10B-B075-4206-9596-46765B665E03}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {E741C10B-B075-4206-9596-46765B665E03}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {EBDB30A3-E8EB-4E1D-915E-06720600A84E}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {EBDB30A3-E8EB-4E1D-915E-06720600A84E}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {EBDB30A3-E8EB-4E1D-915E-06720600A84E}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {EBDB30A3-E8EB-4E1D-915E-06720600A84E}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {A4F29CEB-7644-4A7F-BE9E-02B6A90E4919}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {A4F29CEB-7644-4A7F-BE9E-02B6A90E4919}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {A4F29CEB-7644-4A7F-BE9E-02B6A90E4919}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {A4F29CEB-7644-4A7F-BE9E-02B6A90E4919}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {0D745CD9-FC3B-49DC-99BE-1E6DF85593F0}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {0D745CD9-FC3B-49DC-99BE-1E6DF85593F0}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {0D745CD9-FC3B-49DC-99BE-1E6DF85593F0}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {0D745CD9-FC3B-49DC-99BE-1E6DF85593F0}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ @IF TESTS {F6F08940-7597-4FEE-9CE0-E09A009C45A3}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {F6F08940-7597-4FEE-9CE0-E09A009C45A3}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {F6F08940-7597-4FEE-9CE0-E09A009C45A3}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {F6F08940-7597-4FEE-9CE0-E09A009C45A3}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ @END TESTS @IF SAMPLES {F66D8B7E-721D-4602-99AD-820D19AD1313}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {F66D8B7E-721D-4602-99AD-820D19AD1313}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {F66D8B7E-721D-4602-99AD-820D19AD1313}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {F66D8B7E-721D-4602-99AD-820D19AD1313}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {9FC33CA3-CE4A-4EDF-BA99-EECA4B81AD06}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {9FC33CA3-CE4A-4EDF-BA99-EECA4B81AD06}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {9FC33CA3-CE4A-4EDF-BA99-EECA4B81AD06}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {9FC33CA3-CE4A-4EDF-BA99-EECA4B81AD06}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {D42B8670-8DF6-4D90-90F7-DB5FB845AFAE}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {D42B8670-8DF6-4D90-90F7-DB5FB845AFAE}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {D42B8670-8DF6-4D90-90F7-DB5FB845AFAE}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {D42B8670-8DF6-4D90-90F7-DB5FB845AFAE}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {05682E12-523F-4DAE-8E6D-ADFDBC308AFD}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {05682E12-523F-4DAE-8E6D-ADFDBC308AFD}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {05682E12-523F-4DAE-8E6D-ADFDBC308AFD}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {05682E12-523F-4DAE-8E6D-ADFDBC308AFD}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {FF440E85-7450-439C-82EE-04C464512D0E}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {FF440E85-7450-439C-82EE-04C464512D0E}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {FF440E85-7450-439C-82EE-04C464512D0E}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {FF440E85-7450-439C-82EE-04C464512D0E}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {CB2A29F6-E73B-40AB-8AC4-2C1AAE7280BD}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {CB2A29F6-E73B-40AB-8AC4-2C1AAE7280BD}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {CB2A29F6-E73B-40AB-8AC4-2C1AAE7280BD}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {CB2A29F6-E73B-40AB-8AC4-2C1AAE7280BD}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ @END SAMPLES {723C65DA-A96C-4BA3-A34E-44F11CA346F9}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {723C65DA-A96C-4BA3-A34E-44F11CA346F9}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {723C65DA-A96C-4BA3-A34E-44F11CA346F9}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {723C65DA-A96C-4BA3-A34E-44F11CA346F9}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {7C8681A1-E3A8-470E-9EEF-16054D111A19}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {7C8681A1-E3A8-470E-9EEF-16054D111A19}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {7C8681A1-E3A8-470E-9EEF-16054D111A19}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {7C8681A1-E3A8-470E-9EEF-16054D111A19}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {39721F26-8B80-4AA9-9826-2AEF7322C3D5}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {39721F26-8B80-4AA9-9826-2AEF7322C3D5}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {39721F26-8B80-4AA9-9826-2AEF7322C3D5}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {39721F26-8B80-4AA9-9826-2AEF7322C3D5}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {140DE800-E552-43CC-B0C7-A33A92E368CA}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {140DE800-E552-43CC-B0C7-A33A92E368CA}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {140DE800-E552-43CC-B0C7-A33A92E368CA}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {140DE800-E552-43CC-B0C7-A33A92E368CA}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {F938F9B8-D395-4A40-BEC7-0122D289C692}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {F938F9B8-D395-4A40-BEC7-0122D289C692}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {F938F9B8-D395-4A40-BEC7-0122D289C692}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {F938F9B8-D395-4A40-BEC7-0122D289C692}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {BA1048A8-6961-4A20-BE12-08BE20611C9D}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {BA1048A8-6961-4A20-BE12-08BE20611C9D}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {BA1048A8-6961-4A20-BE12-08BE20611C9D}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {BA1048A8-6961-4A20-BE12-08BE20611C9D}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {C15A6E1A-94CE-4686-99F9-6BC5FD623EB5}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {C15A6E1A-94CE-4686-99F9-6BC5FD623EB5}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {C15A6E1A-94CE-4686-99F9-6BC5FD623EB5}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {C15A6E1A-94CE-4686-99F9-6BC5FD623EB5}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {BE172EFE-C1DC-4812-BFB9-8C5F8ADB7E9F}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {BE172EFE-C1DC-4812-BFB9-8C5F8ADB7E9F}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {BE172EFE-C1DC-4812-BFB9-8C5F8ADB7E9F}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {BE172EFE-C1DC-4812-BFB9-8C5F8ADB7E9F}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {0BF11E21-168C-4CAA-B784-429D126BBAE5}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {0BF11E21-168C-4CAA-B784-429D126BBAE5}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {0BF11E21-168C-4CAA-B784-429D126BBAE5}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {0BF11E21-168C-4CAA-B784-429D126BBAE5}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {205ED8A9-2E4C-41CC-9385-F3613402AA90}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {205ED8A9-2E4C-41CC-9385-F3613402AA90}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {205ED8A9-2E4C-41CC-9385-F3613402AA90}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {205ED8A9-2E4C-41CC-9385-F3613402AA90}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {17455DC6-5FBB-47C3-8F44-7DB574A188D3}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {17455DC6-5FBB-47C3-8F44-7DB574A188D3}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {17455DC6-5FBB-47C3-8F44-7DB574A188D3}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {17455DC6-5FBB-47C3-8F44-7DB574A188D3}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {6E6297F4-69D7-4533-85E1-BD17C30017C8}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {6E6297F4-69D7-4533-85E1-BD17C30017C8}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {6E6297F4-69D7-4533-85E1-BD17C30017C8}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {6E6297F4-69D7-4533-85E1-BD17C30017C8}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {D171F185-D3C2-4463-9CF3-ED1D0B1D6832}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {D171F185-D3C2-4463-9CF3-ED1D0B1D6832}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {D171F185-D3C2-4463-9CF3-ED1D0B1D6832}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {D171F185-D3C2-4463-9CF3-ED1D0B1D6832}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {03FB7588-C5A7-4572-968F-14F1206BC69C}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {03FB7588-C5A7-4572-968F-14F1206BC69C}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {03FB7588-C5A7-4572-968F-14F1206BC69C}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {03FB7588-C5A7-4572-968F-14F1206BC69C}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {FD653434-F1A8-44A9-85B2-A7468491DA6D}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {FD653434-F1A8-44A9-85B2-A7468491DA6D}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {FD653434-F1A8-44A9-85B2-A7468491DA6D}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {FD653434-F1A8-44A9-85B2-A7468491DA6D}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {AB6690A0-055E-458f-BAC5-BF38BCC5834F}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {AB6690A0-055E-458f-BAC5-BF38BCC5834F}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {AB6690A0-055E-458f-BAC5-BF38BCC5834F}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {AB6690A0-055E-458f-BAC5-BF38BCC5834F}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {91E60FDA-E48C-4DA0-92A2-97F963348E00}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {91E60FDA-E48C-4DA0-92A2-97F963348E00}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {91E60FDA-E48C-4DA0-92A2-97F963348E00}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {91E60FDA-E48C-4DA0-92A2-97F963348E00}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {B19042CE-D3D9-469B-BCD2-C3140150939A}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {B19042CE-D3D9-469B-BCD2-C3140150939A}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {B19042CE-D3D9-469B-BCD2-C3140150939A}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {B19042CE-D3D9-469B-BCD2-C3140150939A}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {4EE91023-94C3-48C0-B71C-5333B726C2EE}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {4EE91023-94C3-48C0-B71C-5333B726C2EE}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {4EE91023-94C3-48C0-B71C-5333B726C2EE}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {4EE91023-94C3-48C0-B71C-5333B726C2EE}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {B4AC7F81-E3DC-43E9-B339-4FA5149FA8F7}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {B4AC7F81-E3DC-43E9-B339-4FA5149FA8F7}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {B4AC7F81-E3DC-43E9-B339-4FA5149FA8F7}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {B4AC7F81-E3DC-43E9-B339-4FA5149FA8F7}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {70F2F0DF-665D-4444-A982-AEA31A861A22}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {70F2F0DF-665D-4444-A982-AEA31A861A22}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {70F2F0DF-665D-4444-A982-AEA31A861A22}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {70F2F0DF-665D-4444-A982-AEA31A861A22}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {98743A7C-6AF8-467f-9911-FA69C451AF2B}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {98743A7C-6AF8-467f-9911-FA69C451AF2B}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {98743A7C-6AF8-467f-9911-FA69C451AF2B}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {98743A7C-6AF8-467f-9911-FA69C451AF2B}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {C41266C7-E27E-4D60-9815-82D3B32BF82F}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {C41266C7-E27E-4D60-9815-82D3B32BF82F}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {C41266C7-E27E-4D60-9815-82D3B32BF82F}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {C41266C7-E27E-4D60-9815-82D3B32BF82F}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {2C1F7096-C5B5-48D4-846F-A7ACA454335D}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {2C1F7096-C5B5-48D4-846F-A7ACA454335D}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {2C1F7096-C5B5-48D4-846F-A7ACA454335D}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {2C1F7096-C5B5-48D4-846F-A7ACA454335D}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {03A96113-CB14-43AA-AEB2-48950E3915C5}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {03A96113-CB14-43AA-AEB2-48950E3915C5}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {03A96113-CB14-43AA-AEB2-48950E3915C5}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {03A96113-CB14-43AA-AEB2-48950E3915C5}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {66028555-7DD5-4016-B601-9EF9A1EE8BFA}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {66028555-7DD5-4016-B601-9EF9A1EE8BFA}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {66028555-7DD5-4016-B601-9EF9A1EE8BFA}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {66028555-7DD5-4016-B601-9EF9A1EE8BFA}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {64964B03-4815-41F0-9057-E766A94AF197}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {64964B03-4815-41F0-9057-E766A94AF197}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {64964B03-4815-41F0-9057-E766A94AF197}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {64964B03-4815-41F0-9057-E766A94AF197}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {1E2C1635-3093-4D59-80E7-4743AC10F22F}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {1E2C1635-3093-4D59-80E7-4743AC10F22F}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {1E2C1635-3093-4D59-80E7-4743AC10F22F}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {1E2C1635-3093-4D59-80E7-4743AC10F22F}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {1EA4FC64-F33B-4A50-970A-EA052BBE9CF1}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {1EA4FC64-F33B-4A50-970A-EA052BBE9CF1}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {1EA4FC64-F33B-4A50-970A-EA052BBE9CF1}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {1EA4FC64-F33B-4A50-970A-EA052BBE9CF1}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ @IF PKCS11 {5042D371-0402-4FA3-A52A-769708694422}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {5042D371-0402-4FA3-A52A-769708694422}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {5042D371-0402-4FA3-A52A-769708694422}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {5042D371-0402-4FA3-A52A-769708694422}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {C663B088-F7BC-4C8C-8D06-A76636EED651}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {C663B088-F7BC-4C8C-8D06-A76636EED651}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {C663B088-F7BC-4C8C-8D06-A76636EED651}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {C663B088-F7BC-4C8C-8D06-A76636EED651}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {5B3137E5-7E1F-49AA-8810-A09AA417D326}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {5B3137E5-7E1F-49AA-8810-A09AA417D326}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {5B3137E5-7E1F-49AA-8810-A09AA417D326}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {5B3137E5-7E1F-49AA-8810-A09AA417D326}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {403FD4B1-A4F9-4159-9013-5860E3A4417D}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {403FD4B1-A4F9-4159-9013-5860E3A4417D}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {403FD4B1-A4F9-4159-9013-5860E3A4417D}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {403FD4B1-A4F9-4159-9013-5860E3A4417D}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ @END PKCS11 @IF TESTS @IF ATOMIC {EC6ECB35-58C0-48EC-BAC9-9A652D9406C9}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {EC6ECB35-58C0-48EC-BAC9-9A652D9406C9}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {EC6ECB35-58C0-48EC-BAC9-9A652D9406C9}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {EC6ECB35-58C0-48EC-BAC9-9A652D9406C9}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ @END ATOMIC {E6338E67-3224-4E66-9463-7AD719DA9346}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {E6338E67-3224-4E66-9463-7AD719DA9346}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {E6338E67-3224-4E66-9463-7AD719DA9346}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {E6338E67-3224-4E66-9463-7AD719DA9346}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {EE9B94CF-7C33-4F3B-A674-FB756D422C54}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {EE9B94CF-7C33-4F3B-A674-FB756D422C54}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {EE9B94CF-7C33-4F3B-A674-FB756D422C54}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {EE9B94CF-7C33-4F3B-A674-FB756D422C54}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {5DC2F8D3-9373-41BB-B3AB-78F2E12F1E5E}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {5DC2F8D3-9373-41BB-B3AB-78F2E12F1E5E}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {5DC2F8D3-9373-41BB-B3AB-78F2E12F1E5E}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {5DC2F8D3-9373-41BB-B3AB-78F2E12F1E5E}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {627F32A9-267F-41CA-827C-1FD04DE20A56}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {627F32A9-267F-41CA-827C-1FD04DE20A56}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {627F32A9-267F-41CA-827C-1FD04DE20A56}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {627F32A9-267F-41CA-827C-1FD04DE20A56}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {14071120-84F6-4A6F-BF23-90EC5D0372CE}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {14071120-84F6-4A6F-BF23-90EC5D0372CE}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {14071120-84F6-4A6F-BF23-90EC5D0372CE}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {14071120-84F6-4A6F-BF23-90EC5D0372CE}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {124DC0D3-3096-41D2-B490-CE85E890FF33}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {124DC0D3-3096-41D2-B490-CE85E890FF33}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {124DC0D3-3096-41D2-B490-CE85E890FF33}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {124DC0D3-3096-41D2-B490-CE85E890FF33}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {39F714D4-FEFB-4E23-91DB-1F6FC80A98B5}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {39F714D4-FEFB-4E23-91DB-1F6FC80A98B5}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {39F714D4-FEFB-4E23-91DB-1F6FC80A98B5}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {39F714D4-FEFB-4E23-91DB-1F6FC80A98B5}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {66E58849-A764-44E4-8D32-7C1107246A26}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {66E58849-A764-44E4-8D32-7C1107246A26}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {66E58849-A764-44E4-8D32-7C1107246A26}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {66E58849-A764-44E4-8D32-7C1107246A26}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {351D3872-707B-46AD-8BC0-5A668B8C745B}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {351D3872-707B-46AD-8BC0-5A668B8C745B}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {351D3872-707B-46AD-8BC0-5A668B8C745B}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {351D3872-707B-46AD-8BC0-5A668B8C745B}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {2CB7B128-5954-4FAF-B5EA-501B23BB8054}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {2CB7B128-5954-4FAF-B5EA-501B23BB8054}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {2CB7B128-5954-4FAF-B5EA-501B23BB8054}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {2CB7B128-5954-4FAF-B5EA-501B23BB8054}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {4E6F5A7C-89AA-4259-99DB-F89DAE418B3F}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {4E6F5A7C-89AA-4259-99DB-F89DAE418B3F}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {4E6F5A7C-89AA-4259-99DB-F89DAE418B3F}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {4E6F5A7C-89AA-4259-99DB-F89DAE418B3F}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ @END TESTS @IF XTESTS {14751171-C40E-40EE-A2F0-37FFC3CCD4A2}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {14751171-C40E-40EE-A2F0-37FFC3CCD4A2}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {14751171-C40E-40EE-A2F0-37FFC3CCD4A2}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {14751171-C40E-40EE-A2F0-37FFC3CCD4A2}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {06AA5F16-7121-4C3A-91EF-AFC3BF3B8CE1}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {06AA5F16-7121-4C3A-91EF-AFC3BF3B8CE1}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {06AA5F16-7121-4C3A-91EF-AFC3BF3B8CE1}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {06AA5F16-7121-4C3A-91EF-AFC3BF3B8CE1}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {7705EEF6-6980-48F9-A045-699DAFE860C9}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {7705EEF6-6980-48F9-A045-699DAFE860C9}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {7705EEF6-6980-48F9-A045-699DAFE860C9}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {7705EEF6-6980-48F9-A045-699DAFE860C9}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {551561F6-4A2A-4824-8A34-A4AF0EB7C179}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {551561F6-4A2A-4824-8A34-A4AF0EB7C179}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {551561F6-4A2A-4824-8A34-A4AF0EB7C179}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {551561F6-4A2A-4824-8A34-A4AF0EB7C179}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {6200ED9D-CAB1-4C00-8D79-478F64A19B8F}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {6200ED9D-CAB1-4C00-8D79-478F64A19B8F}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {6200ED9D-CAB1-4C00-8D79-478F64A19B8F}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {6200ED9D-CAB1-4C00-8D79-478F64A19B8F}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {CC7340C1-CBAF-4145-969A-73AE960401D6}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {CC7340C1-CBAF-4145-969A-73AE960401D6}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {CC7340C1-CBAF-4145-969A-73AE960401D6}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {CC7340C1-CBAF-4145-969A-73AE960401D6}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ {E55653C8-5501-4871-A97C-C926631F40F9}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@ {E55653C8-5501-4871-A97C-C926631F40F9}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@ {E55653C8-5501-4871-A97C-C926631F40F9}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@ {E55653C8-5501-4871-A97C-C926631F40F9}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@ @END XTESTS EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal bind9-9.10.3.dfsg.P4/win32utils/Configure0000644000470500017500000027171012664710322017270 0ustar lamontlamont#!/usr/bin/perl # # Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # Configure # # This script builds nmake and visual studio build files # require 5.000; use strict; use File::Spec; use Cwd; # files to configure my $configfilein = "..\\config.h.win32"; my $configfileout = ">..\\config.h"; my $platformfile = "..\\lib\\isc\\win32\\include\\isc\\platform.h"; my @filelist = ("..\\bin\\check\\win32\\checktool.dsp", "..\\bin\\check\\win32\\checkconf.dsp", "..\\bin\\check\\win32\\checkconf.mak", "..\\bin\\check\\win32\\checkzone.dsp", "..\\bin\\check\\win32\\checkzone.mak", "..\\bin\\confgen\\win32\\confgentool.dsp", "..\\bin\\confgen\\win32\\ddnsconfgen.dsp", "..\\bin\\confgen\\win32\\ddnsconfgen.mak", "..\\bin\\confgen\\win32\\rndcconfgen.dsp", "..\\bin\\confgen\\win32\\rndcconfgen.mak", "..\\bin\\delv\\win32\\delv.dsp", "..\\bin\\delv\\win32\\delv.mak", "..\\bin\\dig\\win32\\dig.dsp", "..\\bin\\dig\\win32\\dig.mak", "..\\bin\\dig\\win32\\dighost.dsp", "..\\bin\\dig\\win32\\host.dsp", "..\\bin\\dig\\win32\\host.mak", "..\\bin\\dig\\win32\\nslookup.dsp", "..\\bin\\dig\\win32\\nslookup.mak", "..\\bin\\dnssec\\win32\\dnssectool.dsp", "..\\bin\\dnssec\\win32\\dsfromkey.dsp", "..\\bin\\dnssec\\win32\\dsfromkey.mak", "..\\bin\\dnssec\\win32\\importkey.dsp", "..\\bin\\dnssec\\win32\\importkey.mak", "..\\bin\\dnssec\\win32\\keyfromlabel.dsp", "..\\bin\\dnssec\\win32\\keyfromlabel.mak", "..\\bin\\dnssec\\win32\\keygen.dsp", "..\\bin\\dnssec\\win32\\keygen.mak", "..\\bin\\dnssec\\win32\\revoke.dsp", "..\\bin\\dnssec\\win32\\revoke.mak", "..\\bin\\dnssec\\win32\\settime.dsp", "..\\bin\\dnssec\\win32\\settime.mak", "..\\bin\\dnssec\\win32\\signzone.dsp", "..\\bin\\dnssec\\win32\\signzone.mak", "..\\bin\\dnssec\\win32\\verify.dsp", "..\\bin\\dnssec\\win32\\verify.mak", "..\\bin\\named\\win32\\named.dsp", "..\\bin\\named\\win32\\named.mak", "..\\bin\\nsupdate\\win32\\nsupdate.dsp", "..\\bin\\nsupdate\\win32\\nsupdate.mak", "..\\bin\\pkcs11\\win32\\pk11destroy.dsp", "..\\bin\\pkcs11\\win32\\pk11destroy.mak", "..\\bin\\pkcs11\\win32\\pk11keygen.dsp", "..\\bin\\pkcs11\\win32\\pk11keygen.mak", "..\\bin\\pkcs11\\win32\\pk11list.dsp", "..\\bin\\pkcs11\\win32\\pk11list.mak", "..\\bin\\pkcs11\\win32\\pk11tokens.dsp", "..\\bin\\pkcs11\\win32\\pk11tokens.mak", "..\\bin\\python\\dnssec-checkds.py", "..\\bin\\python\\dnssec-coverage.py", "..\\bin\\rndc\\win32\\rndc.dsp", "..\\bin\\rndc\\win32\\rndc.mak", "..\\bin\\rndc\\win32\\rndcutil.dsp", "..\\bin\\tools\\win32\\arpaname.dsp", "..\\bin\\tools\\win32\\arpaname.mak", "..\\bin\\tools\\win32\\genrandom.dsp", "..\\bin\\tools\\win32\\genrandom.mak", "..\\bin\\tools\\win32\\ischmacfixup.dsp", "..\\bin\\tools\\win32\\ischmacfixup.mak", "..\\bin\\tools\\win32\\journalprint.dsp", "..\\bin\\tools\\win32\\journalprint.mak", "..\\bin\\tools\\win32\\nsec3hash.dsp", "..\\bin\\tools\\win32\\nsec3hash.mak", "..\\bin\\tools\\win32\\rrchecker.dsp", "..\\bin\\tools\\win32\\rrchecker.mak", "..\\bin\\tests\\atomic\\win32\\t_atomic.dsp", "..\\bin\\tests\\atomic\\win32\\t_atomic.mak", "..\\bin\\tests\\db\\win32\\t_db.dsp", "..\\bin\\tests\\db\\win32\\t_db.mak", "..\\bin\\tests\\dst\\win32\\t_dst.dsp", "..\\bin\\tests\\dst\\win32\\t_dst.mak", "..\\bin\\tests\\master\\win32\\t_master.dsp", "..\\bin\\tests\\master\\win32\\t_master.mak", "..\\bin\\tests\\mem\\win32\\t_mem.dsp", "..\\bin\\tests\\mem\\win32\\t_mem.mak", "..\\bin\\tests\\hashes\\win32\\t_hashes.dsp", "..\\bin\\tests\\hashes\\win32\\t_hashes.mak", "..\\bin\\tests\\names\\win32\\t_names.dsp", "..\\bin\\tests\\names\\win32\\t_names.mak", "..\\bin\\tests\\rbt\\win32\\t_rbt.dsp", "..\\bin\\tests\\rbt\\win32\\t_rbt.mak", "..\\bin\\tests\\resolver\\win32\\t_resolver.dsp", "..\\bin\\tests\\resolver\\win32\\t_resolver.mak", "..\\bin\\tests\\sockaddr\\win32\\t_sockaddr.dsp", "..\\bin\\tests\\sockaddr\\win32\\t_sockaddr.mak", "..\\bin\\tests\\tasks\\win32\\t_tasks.dsp", "..\\bin\\tests\\tasks\\win32\\t_tasks.mak", "..\\bin\\tests\\timers\\win32\\t_timers.dsp", "..\\bin\\tests\\timers\\win32\\t_timers.mak", "..\\bin\\tests\\win32\\backtrace_test.dsp", "..\\bin\\tests\\win32\\backtrace_test.mak", "..\\bin\\tests\\win32\\inter_test.dsp", "..\\bin\\tests\\win32\\inter_test.mak", "..\\bin\\tests\\win32\\rwlock_test.dsp", "..\\bin\\tests\\win32\\rwlock_test.mak", "..\\bin\\tests\\win32\\shutdown_test.dsp", "..\\bin\\tests\\win32\\shutdown_test.mak", "..\\bin\\tests\\win32\\sock_test.dsp", "..\\bin\\tests\\win32\\sock_test.mak", "..\\bin\\tests\\win32\\task_test.dsp", "..\\bin\\tests\\win32\\task_test.mak", "..\\bin\\tests\\win32\\timer_test.dsp", "..\\bin\\tests\\win32\\timer_test.mak", "..\\bin\\tests\\win32\\inter_test.dsp", "..\\bin\\tests\\win32\\inter_test.mak", "..\\bin\\tests\\win32\\rwlock_test.dsp", "..\\bin\\tests\\win32\\rwlock_test.mak", "..\\bin\\tests\\win32\\shutdown_test.dsp", "..\\bin\\tests\\win32\\shutdown_test.mak", "..\\bin\\tests\\win32\\sock_test.dsp", "..\\bin\\tests\\win32\\sock_test.mak", "..\\bin\\tests\\win32\\task_test.dsp", "..\\bin\\tests\\win32\\task_test.mak", "..\\bin\\tests\\win32\\timer_test.dsp", "..\\bin\\tests\\win32\\timer_test.mak", "..\\bin\\win32\\BINDInstall\\BINDInstall.dsp", "..\\bin\\win32\\BINDInstall\\BINDInstall.mak", "..\\lib\\bind9\\win32\\libbind9.dsp", "..\\lib\\bind9\\win32\\libbind9.mak", "..\\lib\\dns\\win32\\gen.dsp", "..\\lib\\dns\\win32\\gen.mak", "..\\lib\\dns\\win32\\libdns.def", "..\\lib\\dns\\win32\\libdns.dsp", "..\\lib\\dns\\win32\\libdns.mak", "..\\lib\\irs\\win32\\libirs.dsp", "..\\lib\\irs\\win32\\libirs.mak", "..\\lib\\isc\\win32\\libisc.def", "..\\lib\\isc\\win32\\libisc.dsp", "..\\lib\\isc\\win32\\libisc.mak", "..\\lib\\isccc\\win32\\libisccc.dsp", "..\\lib\\isccc\\win32\\libisccc.mak", "..\\lib\\isccfg\\win32\\libisccfg.dsp", "..\\lib\\isccfg\\win32\\libisccfg.mak", "..\\lib\\lwres\\win32\\liblwres.dsp", "..\\lib\\lwres\\win32\\liblwres.mak", "..\\lib\\samples\\win32\\async.dsp", "..\\lib\\samples\\win32\\async.mak", "..\\lib\\samples\\win32\\gai.dsp", "..\\lib\\samples\\win32\\gai.mak", "..\\lib\\samples\\win32\\nsprobe.dsp", "..\\lib\\samples\\win32\\nsprobe.mak", "..\\lib\\samples\\win32\\request.dsp", "..\\lib\\samples\\win32\\request.mak", "..\\lib\\samples\\win32\\resolve.dsp", "..\\lib\\samples\\win32\\resolve.mak", "..\\lib\\samples\\win32\\update.dsp", "..\\lib\\samples\\win32\\update.mak", "..\\lib\\tests\\win32\\libtests.dsp", "..\\lib\\tests\\win32\\libtests.mak", "..\\lib\\win32\\bindevt\\bindevt.dsp", "..\\lib\\win32\\bindevt\\bindevt.mak", "legacy\\BINDBuild.dsw", "legacy\\BuildAll.bat", "legacy\\BuildPost.bat", "legacy\\BuildSetup.bat"); my @projectlist = ("..\\bin\\check\\win32\\checkconf.vcxproj", "..\\bin\\check\\win32\\checkconf.vcxproj.filters", "..\\bin\\check\\win32\\checktool.vcxproj", "..\\bin\\check\\win32\\checktool.vcxproj.filters", "..\\bin\\check\\win32\\checkzone.vcxproj", "..\\bin\\check\\win32\\checkzone.vcxproj.filters", "..\\bin\\confgen\\win32\\confgentool.vcxproj", "..\\bin\\confgen\\win32\\confgentool.vcxproj.filters", "..\\bin\\confgen\\win32\\ddnsconfgen.vcxproj", "..\\bin\\confgen\\win32\\ddnsconfgen.vcxproj.filters", "..\\bin\\confgen\\win32\\rndcconfgen.vcxproj", "..\\bin\\confgen\\win32\\rndcconfgen.vcxproj.filters", "..\\bin\\delv\\win32\\delv.vcxproj", "..\\bin\\delv\\win32\\delv.vcxproj.filters", "..\\bin\\dig\\win32\\dig.vcxproj", "..\\bin\\dig\\win32\\dig.vcxproj.filters", "..\\bin\\dig\\win32\\dighost.vcxproj", "..\\bin\\dig\\win32\\dighost.vcxproj.filters", "..\\bin\\dig\\win32\\host.vcxproj", "..\\bin\\dig\\win32\\host.vcxproj.filters", "..\\bin\\dig\\win32\\nslookup.vcxproj", "..\\bin\\dig\\win32\\nslookup.vcxproj.filters", "..\\bin\\dnssec\\win32\\dnssectool.vcxproj", "..\\bin\\dnssec\\win32\\dnssectool.vcxproj.filters", "..\\bin\\dnssec\\win32\\dsfromkey.vcxproj", "..\\bin\\dnssec\\win32\\dsfromkey.vcxproj.filters", "..\\bin\\dnssec\\win32\\importkey.vcxproj", "..\\bin\\dnssec\\win32\\importkey.vcxproj.filters", "..\\bin\\dnssec\\win32\\keyfromlabel.vcxproj", "..\\bin\\dnssec\\win32\\keyfromlabel.vcxproj.filters", "..\\bin\\dnssec\\win32\\keygen.vcxproj", "..\\bin\\dnssec\\win32\\keygen.vcxproj.filters", "..\\bin\\dnssec\\win32\\revoke.vcxproj", "..\\bin\\dnssec\\win32\\revoke.vcxproj.filters", "..\\bin\\dnssec\\win32\\settime.vcxproj", "..\\bin\\dnssec\\win32\\settime.vcxproj.filters", "..\\bin\\dnssec\\win32\\signzone.vcxproj", "..\\bin\\dnssec\\win32\\signzone.vcxproj.filters", "..\\bin\\dnssec\\win32\\verify.vcxproj", "..\\bin\\dnssec\\win32\\verify.vcxproj.filters", "..\\bin\\named\\win32\\named.vcxproj", "..\\bin\\named\\win32\\named.vcxproj.filters", "..\\bin\\nsupdate\\win32\\nsupdate.vcxproj", "..\\bin\\nsupdate\\win32\\nsupdate.vcxproj.filters", "..\\bin\\pkcs11\\win32\\pk11destroy.vcxproj", "..\\bin\\pkcs11\\win32\\pk11destroy.vcxproj.filters", "..\\bin\\pkcs11\\win32\\pk11keygen.vcxproj", "..\\bin\\pkcs11\\win32\\pk11keygen.vcxproj.filters", "..\\bin\\pkcs11\\win32\\pk11list.vcxproj", "..\\bin\\pkcs11\\win32\\pk11list.vcxproj.filters", "..\\bin\\pkcs11\\win32\\pk11tokens.vcxproj", "..\\bin\\pkcs11\\win32\\pk11tokens.vcxproj.filters", "..\\bin\\rndc\\win32\\rndc.vcxproj", "..\\bin\\rndc\\win32\\rndc.vcxproj.filters", "..\\bin\\rndc\\win32\\rndcutil.vcxproj", "..\\bin\\rndc\\win32\\rndcutil.vcxproj.filters", "..\\bin\\tools\\win32\\arpaname.vcxproj", "..\\bin\\tools\\win32\\arpaname.vcxproj.filters", "..\\bin\\tools\\win32\\genrandom.vcxproj", "..\\bin\\tools\\win32\\genrandom.vcxproj.filters", "..\\bin\\tools\\win32\\ischmacfixup.vcxproj", "..\\bin\\tools\\win32\\ischmacfixup.vcxproj.filters", "..\\bin\\tools\\win32\\journalprint.vcxproj", "..\\bin\\tools\\win32\\journalprint.vcxproj.filters", "..\\bin\\tools\\win32\\nsec3hash.vcxproj", "..\\bin\\tools\\win32\\nsec3hash.vcxproj.filters", "..\\bin\\tools\\win32\\rrchecker.vcxproj", "..\\bin\\tools\\win32\\rrchecker.vcxproj.filters", "..\\bin\\tests\\atomic\\win32\\t_atomic.vcxproj", "..\\bin\\tests\\atomic\\win32\\t_atomic.vcxproj.filters", "..\\bin\\tests\\db\\win32\\t_db.vcxproj", "..\\bin\\tests\\db\\win32\\t_db.vcxproj.filters", "..\\bin\\tests\\dst\\win32\\t_dst.vcxproj", "..\\bin\\tests\\dst\\win32\\t_dst.vcxproj.filters", "..\\bin\\tests\\master\\win32\\t_master.vcxproj", "..\\bin\\tests\\master\\win32\\t_master.vcxproj.filters", "..\\bin\\tests\\mem\\win32\\t_mem.vcxproj", "..\\bin\\tests\\mem\\win32\\t_mem.vcxproj.filters", "..\\bin\\tests\\hashes\\win32\\t_hashes.vcxproj", "..\\bin\\tests\\hashes\\win32\\t_hashes.vcxproj.filters", "..\\bin\\tests\\names\\win32\\t_names.vcxproj", "..\\bin\\tests\\names\\win32\\t_names.vcxproj.filters", "..\\bin\\tests\\rbt\\win32\\t_rbt.vcxproj", "..\\bin\\tests\\rbt\\win32\\t_rbt.vcxproj.filters", "..\\bin\\tests\\resolver\\win32\\t_resolver.vcxproj", "..\\bin\\tests\\resolver\\win32\\t_resolver.vcxproj.filters", "..\\bin\\tests\\sockaddr\\win32\\t_sockaddr.vcxproj", "..\\bin\\tests\\sockaddr\\win32\\t_sockaddr.vcxproj.filters", "..\\bin\\tests\\tasks\\win32\\t_tasks.vcxproj", "..\\bin\\tests\\tasks\\win32\\t_tasks.vcxproj.filters", "..\\bin\\tests\\timers\\win32\\t_timers.vcxproj", "..\\bin\\tests\\timers\\win32\\t_timers.vcxproj.filters", "..\\bin\\tests\\win32\\backtrace_test.vcxproj", "..\\bin\\tests\\win32\\backtrace_test.vcxproj.filters", "..\\bin\\tests\\win32\\inter_test.vcxproj", "..\\bin\\tests\\win32\\inter_test.vcxproj.filters", "..\\bin\\tests\\win32\\rwlock_test.vcxproj", "..\\bin\\tests\\win32\\rwlock_test.vcxproj.filters", "..\\bin\\tests\\win32\\shutdown_test.vcxproj", "..\\bin\\tests\\win32\\shutdown_test.vcxproj.filters", "..\\bin\\tests\\win32\\sock_test.vcxproj", "..\\bin\\tests\\win32\\sock_test.vcxproj.filters", "..\\bin\\tests\\win32\\task_test.vcxproj", "..\\bin\\tests\\win32\\task_test.vcxproj.filters", "..\\bin\\tests\\win32\\timer_test.vcxproj", "..\\bin\\tests\\win32\\timer_test.vcxproj.filters", "..\\bin\\tests\\win32\\inter_test.vcxproj", "..\\bin\\tests\\win32\\inter_test.vcxproj.filters", "..\\bin\\tests\\win32\\rwlock_test.vcxproj", "..\\bin\\tests\\win32\\rwlock_test.vcxproj.filters", "..\\bin\\tests\\win32\\shutdown_test.vcxproj", "..\\bin\\tests\\win32\\shutdown_test.vcxproj.filters", "..\\bin\\tests\\win32\\sock_test.vcxproj", "..\\bin\\tests\\win32\\sock_test.vcxproj.filters", "..\\bin\\tests\\win32\\task_test.vcxproj", "..\\bin\\tests\\win32\\task_test.vcxproj.filters", "..\\bin\\tests\\win32\\timer_test.vcxproj", "..\\bin\\tests\\win32\\timer_test.vcxproj.filters", "..\\bin\\win32\\BINDInstall\\BINDInstall.vcxproj", "..\\bin\\win32\\BINDInstall\\BINDInstall.vcxproj.filters", "..\\lib\\bind9\\win32\\libbind9.vcxproj", "..\\lib\\bind9\\win32\\libbind9.vcxproj.filters", "..\\lib\\dns\\win32\\gen.vcxproj", "..\\lib\\dns\\win32\\gen.vcxproj.filters", "..\\lib\\dns\\win32\\libdns.vcxproj", "..\\lib\\dns\\win32\\libdns.vcxproj.filters", "..\\lib\\irs\\win32\\libirs.vcxproj", "..\\lib\\irs\\win32\\libirs.vcxproj.filters", "..\\lib\\isc\\win32\\libisc.vcxproj", "..\\lib\\isc\\win32\\libisc.vcxproj.filters", "..\\lib\\isccc\\win32\\libisccc.vcxproj", "..\\lib\\isccc\\win32\\libisccc.vcxproj.filters", "..\\lib\\isccfg\\win32\\libisccfg.vcxproj", "..\\lib\\isccfg\\win32\\libisccfg.vcxproj.filters", "..\\lib\\lwres\\win32\\liblwres.vcxproj", "..\\lib\\lwres\\win32\\liblwres.vcxproj.filters", "..\\lib\\samples\\win32\\resolve.vcxproj", "..\\lib\\samples\\win32\\resolve.vcxproj.filters", "..\\lib\\samples\\win32\\async.vcxproj", "..\\lib\\samples\\win32\\async.vcxproj.filters", "..\\lib\\samples\\win32\\gai.vcxproj", "..\\lib\\samples\\win32\\gai.vcxproj.filters", "..\\lib\\samples\\win32\\update.vcxproj", "..\\lib\\samples\\win32\\update.vcxproj.filters", "..\\lib\\samples\\win32\\request.vcxproj", "..\\lib\\samples\\win32\\request.vcxproj.filters", "..\\lib\\samples\\win32\\nsprobe.vcxproj", "..\\lib\\samples\\win32\\nsprobe.vcxproj.filters", "..\\lib\\tests\\win32\\libtests.vcxproj", "..\\lib\\tests\\win32\\libtests.vcxproj.filters", "..\\lib\\win32\\bindevt\\bindevt.vcxproj", "..\\lib\\win32\\bindevt\\bindevt.vcxproj.filters", "bind9.sln"); # for config.h my %configdefh; my @substdefh = ("AES_SIT", "ALLOW_FILTER_AAAA", "CONFIGARGS", "DNS_RDATASET_FIXED", "ENABLE_RPZ_NSDNAME", "ENABLE_RPZ_NSIP", "HAVE_EVP_SHA256", "HAVE_EVP_SHA384", "HAVE_EVP_SHA512", "HAVE_GEOIP", "HAVE_GEOIP_CITY_V6", "HAVE_GEOIP_V6", "HAVE_LIBXML2", "HAVE_OPENSSL_AES", "HAVE_OPENSSL_DSA", "HAVE_OPENSSL_ECDSA", "HAVE_OPENSSL_EVP_AES", "HAVE_OPENSSL_GOST", "HAVE_PKCS11_ECDSA", "HAVE_PKCS11_GOST", "HAVE_READLINE", "HMAC_RETURN_INT", "HMAC_SHA1_SIT", "HMAC_SHA256_SIT", "ISC_LIST_CHECKINIT", "PREFER_GOSTASN1", "TUNE_LARGE", "WANT_QUERYTRACE", "WITH_IDN"); # for platform.h my %configdefp; my @substdefp = ("ISC_PLATFORM_HAVEATOMICSTORE", "ISC_PLATFORM_HAVECMPXCHG", "ISC_PLATFORM_HAVEXADD", "ISC_PLATFORM_HAVEXADDQ", "ISC_PLATFORM_NEEDSTRCASESTR", "ISC_PLATFORM_USEBACKTRACE", "ISC_PLATFORM_USESIT", "ISC_PLATFORM_WANTAES"); # includes my %configinc; my @substinc = ("GSSAPI_INC", "GEOIP_INC", "IDN_INC", "LIBXML2_INC", "OPENSSL_INC", "READLINE_INC"); # libraries my %configlib; my @substlib = ("GSSAPI_LIB", "GEOIP_LIB", "IDN_LIB", "KRB5_LIB", "LIBXML2_LIB", "OPENSSL_LIB", "READLINE_LIB", "READLINE_LIBD"); # DLLs my %configdll; my @substdll = ("COMERR_DLL", "GSSAPI_DLL", "GEOIP_DLL", "ICONV_DLL", "IDN_DLL", "KRB5_DLL", "K5SPRT_DLL", "LIBXML2_DLL", "OPENSSL_DLL", "WSHELP_DLL"); # variables my %configvar; my @substvar = ("BUILD_MACHINE", "BUILD_PLATFORM", "COPTI", "COPTML", "COPTMLD", "COPTX", "COPTY", "INTRINSIC", "MACHINE", "OPENSSL_PATH", "PLATFORM", "PKCS11_TOOLS", "prefix", "PYTHON", "VCREDIST_PATH"), # defines my %configdefd; my @substdefd = ("CRYPTO", "PK11_LIB_LOCATION", "USE_GSSAPI", "USE_PKCS11", "USE_PYTHON", "USE_ISC_SPNEGO"); # conditions my %configcond; my @substcond = ("AES", "ATOMIC", "GSSAPI", "GEOIP", "IDNKIT", "LIBXML2", "OPENSSL", "PKCS11", "PYTHON", "SAMPLES", "TESTS", "XTESTS"); # arguments # enable-xxx/disable-xxx my @enablelist = ("developer", "fixed-rrset", "intrinsics", "isc-spnego", "native-pkcs11", "openssl-hash", "filter-aaaa", "querytrace", "rpz-nsdname", "rpz-nsip", "sit"); # with-xxx/without-xxx my @withlist = ("aes", "cross-compile", "ecdsa", "extra-tests", "gssapi", "geoip", "gost", "iconv", "idn", "openssl", "libxml2", "pkcs11", "python", "readline", "samples", "sit-alg", "tests", "tuning", "vcredist"); # general arguments my @optionlist = ("help", "verbose", "legacy", "win32", "x64", "clean"); # usage my @usage = ("Usage: perl Configure help\n", " perl Configure options* win32|x64\n", " perl Configure clean\n"); # help my @help = ( "'Configure' configures BIND9 build files.\n\n", @usage, "\nGeneral Options and Commands:\n", " verbose (options) print messages\n", " help (command) print this help\n", " legacy (options) process only files for legacy build\n", " win32 (command) configure for Win32 platform\n", " x64 (command) configure for x64 platform\n", " clean (command) clean up generated files\n", " (command) print a summary of the configuration\n", "\nOptional Features:\n", " enable-intrinsics enable instrinsic/atomic functions [default=yes]\n", " enable-native-pkcs11 use native PKCS#11 for all crypto [default=no]\n", " enable-openssl-hash use OpenSSL for hash functions [default=yes]\n", " enable-isc-spnego use SPNEGO from lib/dns [default=yes]\n", " enable-filter-aaaa enable filtering of AAAA records [default=no]\n", " enable-fixed-rrset enable fixed rrset ordering [default=no]\n", " enable-developer enable developer build settings [default=no]\n", " enable-querytrace enable very verbose query trace [default=no]\n", " enable-rpz-nsip enable rpz-nsip rules [default=yes]\n", " enable-rpz-nsdname enable rpz-nsdname rules [default=yes]\n", " enable-sit enable source identity token [default=yes]\n", "\nOptional Packages:\n", " with-tests build with test suite\n", " with-extra-tests build with extra test suite\n", " with-samples build with sample programs\n", " with-openssl[=PATH] build with OpenSSL yes|no|path\n", " with-pkcs11[=PATH] build with PKCS#11 support yes|no|provider-path\n", " with-ecdsa crypto ECDSA\n", " with-gost[=ENC] crypto GOST yes|no|raw|ans1\n", " with-aes crypto AES\n", " with-sit-alg choose the algorithm for SIT aes|sha1|sha256\n", " with-gssapi[=PATH] build with MIT KfW GSSAPI yes|no|path\n", " with-libxml2[=PATH] build with libxml2 library yes|no|path\n", " with-geoip[=PATH] build with GeoIP support yes|no|path\n", " with-python[=COMMAND] specify python interpreter python|command\n", " with-readline[=PATH] build with readline library support yes|no|path\n", " with-idn[=PATH] build with IDN kit support yes|no|path\n", " with-iconv[=PATH] path of the iconv DLL [default=same than idn]\n", " with-vcredist[=PATH] visual C++ redistributable package yes|path\n", " with-tuning=OPTION tune for plaform size (large|default)\n", " with-cross-compile 32 / 64 bit build / host plaforms\n"); # Parse arguments my $verbose = 0; my $legacy_only = 0; my $want_help = "no"; my $want_win32 = "no"; my $want_x64 = "no"; my $want_clean = "no"; my $want_unknown = "no"; my $unknown_value; my $enable_intrinsics = "yes"; my $enable_native_pkcs11 = "no"; my $enable_openssl_hash = "auto"; my $enable_filter_aaaa = "no"; my $enable_isc_spnego = "yes"; my $enable_fixed_rrset = "no"; my $enable_developer = "no"; my $enable_querytrace = "no"; my $enable_rpz_nsip = "yes"; my $enable_rpz_nsdname = "yes"; my $enable_sit = "yes"; my $use_tests = "no"; my $use_xtests = "no"; my $use_samples = "no"; my $use_openssl = "auto"; my $openssl_path = "..\\..\\"; my $use_pkcs11 = "no"; my $pkcs11_path = "unknown"; my $use_ecdsa = "auto"; my $use_gost = "auto"; my $gost_encoding = "raw"; my $use_aes = "auto"; my $sit_algorithm = "aes"; my $use_gssapi = "no"; my $gssapi_path = "C:\\Program\ Files\\MIT\\Kerberos\\"; my $use_geoip = "no"; my $geoip_path = ""; my $use_libxml2 = "auto"; my $libxml2_path = "..\\..\\"; my $use_python = "auto"; my $python_command = "python"; my $use_readline = "no"; my $readline_path = "..\\..\\"; my $use_idn = "no"; my $idn_path = "..\\..\\"; my $iconv_path = " --idn-- "; my $use_vcredist = "yes"; my $vcredist_path = " --infer-- "; my $cross_compile = "no"; my $tuning = "default"; # no arguments -> usage if ($#ARGV < 0) { foreach (@usage) { print $_; } exit 1; } # parse arguments foreach (@ARGV) { if (/^verbose$/i) { $verbose = 1; } elsif (/^help$/i) { $want_help = "yes"; } elsif (/^disable-(.*)$/i) { appargs($_); myenable($1, "no"); } elsif (/^enable-(.*)$/i) { appargs($_); myenable($1, "yes"); } elsif (/^without-(.*)$/i) { appargs($_); mywith($1, "no"); } elsif (/^with-(.*)=(.*)$/i) { appargs($_); mywith($1, $2); } elsif (/^with-(.*)$/i) { appargs($_); mywith($1, "yes"); } elsif (/^legacy$/i) { $legacy_only = 1; } elsif (/^win32$/i) { $want_win32 = "yes"; } elsif (/^x64$/i) { appargs($_); $want_x64 = "yes"; } elsif (/^clean$/i) { $want_clean = "yes"; } else { $want_unknown = "yes"; $unknown_value = $_; } } # legacy default to win32 if ($legacy_only && ($want_x64 ne "yes")) { $want_win32 = "yes"; } # configure the platform if (($want_win32 eq "yes") && ($want_x64 eq "yes")) { die "can't ask for both Win32 and x64 platforms\n"; } elsif ($want_win32 eq "yes") { $configvar{"PLATFORM"} = "Win32"; $configvar{"BUILD_PLATFORM"} = "Win32"; $configvar{"MACHINE"} = "/machine:X86"; $configvar{"BUILD_MACHINE"} = "/machine:X86"; } elsif ($want_x64 eq "yes") { $configvar{"PLATFORM"} = "x64"; $configvar{"BUILD_PLATFORM"} = "x64"; $configvar{"MACHINE"} = "/machine:X64"; $configvar{"BUILD_MACHINE"} = "/machine:X64"; } # append seen args to CONFIGARGS define sub appargs { my $arg = $_[0]; # escape backslashes, spaces and double quotes $arg =~ s/([\\ "])/\\$1/g; if (defined($configdefh{"CONFIGARGS"})) { $configdefh{"CONFIGARGS"} .= " " . $arg; } else { $configdefh{"CONFIGARGS"} = $arg; } } if (!$configdefh{"CONFIGARGS"}) { # CONFIGARGS default is "default" $configdefh{"CONFIGARGS"} = "\"default\""; } else { my $val = $configdefh{"CONFIGARGS"}; $configdefh{"CONFIGARGS"} = "\"'$val'\""; } # parse enable/disable sub myenable { my $key = $_[0]; my $val = $_[1]; if ($key =~ /^intrinsics$/i) { if ($val =~ /^no$/i) { $enable_intrinsics = "no"; } } elsif ($key =~ /^native-pkcs11$/i) { if ($val =~ /^yes$/i) { $enable_native_pkcs11 = "yes"; } } elsif ($key =~ /^openssl-hash$/i) { if ($val =~ /^yes$/i) { $enable_openssl_hash = "yes"; } elsif ($val =~ /^no$/i) { $enable_openssl_hash = "no"; } } elsif ($key =~ /^isc-spnego$/i) { if ($val =~ /^no$/i) { $enable_isc_spnego = "no"; } } elsif ($key =~ /^filter-aaaa$/i) { if ($val =~ /^yes$/i) { $enable_filter_aaaa = "yes"; } } elsif ($key =~ /^fixed-rrset$/i) { if ($val =~ /^yes$/i) { $enable_fixed_rrset = "yes"; } } elsif ($key =~ /^developer$/i) { if ($val =~ /^yes$/i) { $enable_developer = "yes"; } } elsif ($key =~ /^querytrace$/i) { if ($val =~ /^yes$/i) { $enable_querytrace = "yes"; } } elsif ($key =~ /^rpz-nsip$/i) { if ($val =~ /^no$/i) { $enable_rpz_nsip = "no"; } } elsif ($key =~ /^rpz-nsdname$/i) { if ($val =~ /^no$/i) { $enable_rpz_nsdname = "no"; } } elsif ($key =~ /^sit$/i) { if ($val =~ /^no$/i) { $enable_sit = "no"; } } else { $want_unknown = "yes"; if ($val eq "no") { $unknown_value = "disable-" . $key; } else { $unknown_value = "enable-". $key; } } } # enable-developer expansion now if ($enable_developer eq "yes") { $configdefh{"ISC_LIST_CHECKINIT"} = 1; $enable_filter_aaaa = "yes"; $enable_querytrace = "yes"; # no atf on WIN32 $enable_fixed_rrset = "yes"; # TODO: dlz filesystem $use_tests = "yes"; $use_samples = "yes"; $enable_sit = "yes"; } # parse with/without sub mywith { my $key = $_[0]; my $val = $_[1]; if ($key =~ /^tests$/i) { if ($val =~ /^yes$/i) { $use_tests = "yes"; } } elsif ($key =~ /^extra-tests$/i) { if ($val =~ /^yes$/i) { $use_tests = "yes"; $use_xtests = "yes"; } } elsif ($key =~ /^samples$/i) { if ($val =~ /^yes$/i) { $use_samples = "yes"; } } elsif ($key =~ /^openssl$/i) { if ($val =~ /^no$/i) { $use_openssl = "no"; } elsif ($val !~ /^yes$/i) { $use_openssl = "yes"; $openssl_path = $val; } } elsif ($key =~ /^pkcs11$/i) { if ($val =~ /^yes$/i) { $use_pkcs11 = "yes"; } elsif ($val !~ /^no$/i) { $use_pkcs11= "yes"; $pkcs11_path = $val; $pkcs11_path =~ s/\.dll$//i; } } elsif ($key =~ /^ecdsa$/i) { if ($val =~ /^no$/i) { $use_ecdsa = "no"; } elsif ($val =~ /^yes$/i) { $use_ecdsa = "yes"; } } elsif ($key =~ /^gost$/i) { if ($val =~ /^no$/i) { $use_gost = "no"; } elsif ($val =~ /^yes$/i) { $use_gost = "yes"; $gost_encoding = $val; } } elsif ($key =~ /^aes$/i) { if ($val =~ /^no$/i) { $use_aes = "no"; } elsif ($val =~ /^yes$/i) { $use_aes = "yes"; } } elsif ($key =~ /^sit-alg$/i) { $sit_algorithm = $val; } elsif ($key =~ /^gssapi$/i) { if ($val !~ /^no$/i) { $use_gssapi = "yes"; if ($val !~ /^yes$/i) { $gssapi_path = $val; } } } elsif ($key =~ /^libxml2$/i) { if ($val =~ /^no$/i) { $use_libxml2 = "no"; } elsif ($val !~ /^yes$/i) { $use_libxml2 = "yes"; $libxml2_path = $val; } } elsif ($key =~ /^geoip$/i) { if ($val !~ /^no$/i) { $use_geoip = "yes"; if ($val !~ /^yes$/i) { $geoip_path = $val; } } } elsif ($key =~ /^readline$/i) { if ($val !~ /^no$/i) { $use_readline = "yes"; if ($val !~ /^yes$/i) { $readline_path = $val; } } } elsif ($key =~ /^idn$/i) { if ($val !~ /^no$/i) { $use_idn = "yes"; if ($val !~ /^yes$/i) { $idn_path = $val; } } } elsif ($key =~ /^iconv$/i) { if ($val =~ /^no$/i) { $want_unknown = "yes"; $unknown_value = "without-iconv doesn't make sense)"; } elsif ($val !~ /^yes$/i) { $iconv_path = $val; } } elsif ($key =~ /^python$/i) { if ($val =~ /^no$/i) { $use_python = "no"; } else { $use_python = "yes"; if ($val !~ /^yes$/i) { $python_command = $val; } } } elsif ($key =~ /^vcredist$/i) { if ($val =~ /^no$/i) { $want_unknown = "yes"; $unknown_value = "without-vcredist (vcredist is required)"; } elsif ($val !~ /^yes$/i) { $vcredist_path = $val; } } elsif ($key =~ /^cross-compile$/i) { if ($val =~ /^yes$/i) { $cross_compile = "yes"; } } elsif ($key =~ /^tuning$/i) { if ($val =~ /^large$/i) { $tuning = "large"; } } else { $want_unknown = "yes"; if ($val eq "no") { $unknown_value = "without-" . $key; } else { $unknown_value = "with-" . $key; } } } # resolve enable-openssl-hash if ($enable_openssl_hash eq "auto") { if ($use_openssl ne "no") { if ($enable_native_pkcs11 eq "yes") { $enable_openssl_hash="no"; } else { $enable_openssl_hash="yes"; } } else { $enable_openssl_hash="no"; } } if ($want_help ne "no") { foreach (@help) { print $_; } exit 1; } # clean up and exit if requested if ($want_clean eq "yes") { my $file; foreach $file (@filelist) { unlink($file); } foreach $file (@projectlist) { unlink($file); } exit 0; } if ($want_unknown ne "no") { print STDERR "can't parse $unknown_value\n"; exit 1; } if ($verbose) { if ($want_win32 eq "yes") { print "configure for win32\n"; } if ($want_x64 eq "yes") { print "configure for x64\n"; } if ($cross_compile eq "yes") { print "cross compiling"; if ($want_x64 eq "yes") { print ": build on win32 for x64 host\n"; } elsif ($want_win32 eq "yes") { print ": build on x64 for win32 host\n"; } else { print "\n"; } } if ($enable_intrinsics eq "yes") { print "intrinsics: enabled\n"; } else { print "intrinsics: disabled\n"; } if ($enable_native_pkcs11 eq "yes") { print "native-pkcs11: enabled\n"; } else { print "native-pkcs11: disabled\n"; } if ($enable_openssl_hash eq "yes") { print "openssl-hash: enabled\n"; } else { print "openssl-hash: disabled\n"; } if ($enable_isc_spnego eq "yes") { print "isc-spnego: enabled\n"; } else { print "isc-spnego: disabled\n"; } if ($enable_filter_aaaa eq "yes") { print "filter-aaaa: enabled\n"; } else { print "filter-aaaa: disabled\n"; } if ($enable_fixed_rrset eq "yes") { print "fixed-rrset: enabled\n"; } else { print "fixed-rrset: disabled\n"; } if ($enable_developer eq "yes") { print "developer: enabled\n"; } else { print "developer: disabled\n"; } if ($enable_querytrace eq "yes") { print "querytrace: enabled\n"; } else { print "querytrace: disabled\n"; } if ($enable_rpz_nsip eq "yes") { print "rpz-nsip: enabled\n"; } else { print "rpz-nsip: disabled\n"; } if ($enable_rpz_nsdname eq "yes") { print "rpz-nsdname: enabled\n"; } else { print "rpz-nsdname: disabled\n"; } if ($enable_sit eq "yes") { print "sit: enabled\n"; print "sit algorithm: $sit_algorithm\n"; } else { print "sit: disabled\n"; } if ($use_openssl eq "no") { print "openssl: disabled\n"; } else { print "openssl-path: $openssl_path\n"; } if ($use_tests eq "yes") { print "tests: enabled\n"; } if ($use_xtests eq "yes") { print "extra tests: enabled\n"; } if ($use_samples eq "yes") { print "sample programs: enabled\n"; } if ($use_pkcs11 eq "no") { print "pkcs11: disabled\n"; } else { print "pkcs11-provider-path: $pkcs11_path\n"; } if ($use_ecdsa eq "no") { print "ecdsa: disabled\n"; } else { print "ecdsa: enabled\n"; } if ($use_gost eq "no") { print "gost: disabled\n"; } else { print "gost: enabled\n"; print "gost private key encoding: $gost_encoding\n"; } if ($use_aes eq "no") { print "aes: disabled\n"; } else { print "aes: enabled\n"; } if ($use_gssapi eq "no") { print "gssapi: disabled\n"; } else { print "gssapi-path: $gssapi_path\n"; } if ($use_libxml2 eq "no") { print "libxml2: disabled\n"; } else { print "libxml2-path: $libxml2_path\n"; } if ($use_geoip eq "no") { print "geoip: disabled\n"; } else { print "geoip-path: $geoip_path\n"; } if ($use_readline eq "no") { print "readline: disabled\n"; } else { print "readline-path: $readline_path\n"; } if ($use_idn eq "no") { print "idn: disabled\n"; } else { print "idn-path: $idn_path\n"; if ($iconv_path ne " --idn-- ") { print "iconv-path: $iconv_path\n"; } } if ($use_python eq "no") { print "python: disabled\n"; } else { print "python-command: $python_command\n"; } print "vcredist-path: $vcredist_path\n"; } # Check environment # infer vcredist when not given if ($vcredist_path eq " --infer-- ") { if ($verbose) { print "trying to infer vcredist path from build environment\n"; } my @vcpaths = {}; push(@vcpaths, $ENV{"VCRedistPath"}) if ($ENV{"VCRedistPath"} ne ""); push(@vcpaths, File::Spec->catfile( cwd(), "..", ".." )); if ($ENV{"FrameworkSDKDir"} ne "" && $want_win32 eq "yes") { push(@vcpaths, File::Spec->catfile($ENV{"FrameworkSDKDir"}, "BootStrapper", "Packages", "vcredist_x86")); } elsif ($ENV{"FrameworkSDKDir"} ne "" && $want_x64 eq "yes") { push(@vcpaths, File::Spec->catfile($ENV{"FrameworkSDKDir"}, "BootStrapper", "Packages", "vcredist_x64")); } if ($ENV{"WindowsSDKDir"} ne "" && $want_win32 eq "yes") { push(@vcpaths, File::Spec->catfile($ENV{"WindowsSDKDir"}, "BootStrapper", "Packages", "vcredist_x86")); } elsif ($ENV{"WindowsSDKDir"} ne "" && $want_x64 eq "yes") { push(@vcpaths, File::Spec->catfile($ENV{"WindowsSDKDir"}, "BootStrapper", "Packages", "vcredist_x64")); } if ($ENV{"WindowsSDKDir_old"} ne "" && $want_win32 eq "yes") { push(@vcpaths, File::Spec->catfile($ENV{"WindowsSDKDir_old"}, "BootStrapper", "Packages", "vcredist_x86")); } elsif ($ENV{"WindowsSDKDir_old"} ne "" && $want_x64 eq "yes") { push(@vcpaths, File::Spec->catfile($ENV{"WindowsSDKDir_old"}, "BootStrapper", "Packages", "vcredist_x64")); } if ($ENV{"VCINSTALLDIR"}) { push(@vcpaths, File::Spec->catfile($ENV{"VCINSTALLDIR"}, "redist", "1033")); } my $rfile; if ($want_win32 eq "yes") { $rfile = "vcredist_x86.exe"; } else { $rfile = "vcredist_x64.exe"; } foreach (@vcpaths) { my $vp = File::Spec->catfile($_, $rfile); if (-f $vp) { $vcredist_path = $vp; last; } } if ($vcredist_path eq " --infer-- ") { die "with-vcredist is REQUIRED\n"; } if ($verbose) { print "found vcredist at " . $vcredist_path . "\n"; } } my $msc_ver = 0; open F, ">mscver.c" || die $!; print F << 'EOF'; #include #include int main(void) { printf("%d\n", _MSC_VER); return(0); } EOF close F; my $compret = `cl /nologo /MD mscver.c`; if (grep { -f and -x } ".\\mscver.exe") { $msc_ver = `.\\mscver.exe`; } else { die "can't get _MSC_VER value: $compret\n"; } if ($verbose) { print "_MSV_VER == $msc_ver\n"; } if ($msc_ver < 1600) { print STDERR "warning: old version of C++ compiler/Visual Studio\n"; print STDERR "only the legacy (cf legacy\\win32-build.txt) will work\n"; } # gen single threaded for < VS 2005 if ($msc_ver < 1400) { $configvar{"COPTML"} = "/ML"; $configvar{"COPTMLD"} = "/MLD"; } # /GX deprecated in VS 2005 if ($msc_ver < 1400) { $configvar{"COPTX"} = "/GX"; } else { $configvar{"COPTX"} = "/EHsc"; } # /YX for < VS 2005 if ($msc_ver < 1400) { $configvar{"COPTY"} = "/YX"; } # backtrace for >= VS 2012 if ($msc_ver >= 1700) { $configdefp{"ISC_PLATFORM_USEBACKTRACE"} = 1; } # no version of MSVS supports strcasestr() yet $configdefp{"ISC_PLATFORM_NEEDSTRCASESTR"} = 1; # warn when cross compiling if ($cross_compile eq "yes") { if ($want_x64 eq "yes") { $configvar{"BUILD_PLATFORM"} = "Win32"; $configvar{"BUILD_MACHINE"} = "/machine:X86"; } if ($want_win32 eq "yes") { $configvar{"BUILD_PLATFORM"} = "x64"; $configvar{"BUILD_MACHINE"} = "/machine:X64"; } } elsif ($want_win32 eq "yes") { open F, ">cross.c" || die $!; print F << 'EOF'; #include #include int main(void) { #ifdef _WIN64 fprintf(stderr, "compiling for x64 when win32 was asked?!\n"); #endif return(0); } EOF close F; my $compret = `cl /nologo /MD cross.c`; if (grep { -f and -x } ".\\cross.exe") { my $cross = `.\\cross.exe`; if ($cross) { print STDERR $cross; } } else { print STDERR "can't check cross compile: $compret\n"; } } else { open F, ">cross.c" || die $!; print F << 'EOF'; #include #include int main(void) { #ifndef _WIN64 fprintf(stderr, "compiling in 32 bits when x64 was asked?!\n"); #endif return(0); } EOF close F; my $compret = `cl /nologo /MD cross.c`; if (grep { -f and -x } ".\\cross.exe") { my $cross = `.\\cross.exe`; if ($cross) { print STDERR $cross; } } else { print STDERR "can't check cross compile: $compret\n"; } } # Process arguments # enable-intrinsics if ($enable_intrinsics eq "yes") { $configcond{"ATOMIC"} = 1; $configvar{"INTRINSIC"} = "true"; $configvar{"COPTI"} = "/Oi"; $configdefp{"ISC_PLATFORM_HAVEXADD"} = 1; if ($want_x64 eq "yes") { $configdefp{"ISC_PLATFORM_HAVEXADDQ"} = 1; } $configdefp{"ISC_PLATFORM_HAVEATOMICSTORE"} = 1; $configdefp{"ISC_PLATFORM_HAVECMPXCHG"} = 1; } else { $configvar{"INTRINSIC"} = "false"; } # enable-native-pkcs11 if ($enable_native_pkcs11 eq "yes") { if ($use_openssl eq "auto") { $use_openssl = "no"; } if ($use_openssl ne "no") { die "can't have both OpenSSL and native PKCS#11\n"; } if ($use_pkcs11 ne "yes") { if ($verbose) { print "native PKCS#11 support: force with-pkcs11\n"; } $use_pkcs11 = "yes"; } if ($pkcs11_path eq "unknown") { if ($verbose) { print "native PKCS#11 support: no PKCS#11 provider defined?\n"; } } $configdefd{"CRYPTO"} = "PKCS11CRYPTO"; if ($use_ecdsa eq "no") { if ($verbose) { print "no ECDSA support in native PKCS#11\n"; } } else { if ($verbose) { print "enabled ECDSA support in native PKCS#11\n"; } $configdefh{"HAVE_PKCS11_ECDSA"} = 1; } if ($use_gost eq "no") { if ($verbose) { print "no GOST support in native PKCS#11\n"; } } else { if ($verbose) { print "enabled GOST support in native PKCS#11\n"; } $configdefh{"HAVE_PKCS11_GOST"} = 1; } if ($use_aes eq "no") { if ($verbose) { print "no AES support in native PKCS#11\n"; } } else { if ($verbose) { print "enabled AES support in native PKCS#11\n"; } $use_aes = "pkcs11"; } } # enable-filter-aaaa if ($enable_filter_aaaa eq "yes") { $configdefh{"ALLOW_FILTER_AAAA"} = 1; } # enable-fixed-rrset if ($enable_fixed_rrset eq "yes") { $configdefh{"DNS_RDATASET_FIXED"} = 1; } # enable-rpz-nsip if ($enable_rpz_nsip ne "no") { $configdefh{"ENABLE_RPZ_NSIP"} = 1; } # enable-querytrace if ($enable_querytrace eq "yes") { $configdefh{"WANT_QUERYTRACE"} = 1; } # enable-rpz-nsdname if ($enable_rpz_nsdname ne "no") { $configdefh{"ENABLE_RPZ_NSDNAME"} = 1; } # enable-sit if ($enable_sit ne "no") { $configdefp{"ISC_PLATFORM_USESIT"} = 1; } # with-tests if ($use_tests eq "yes") { $configcond{"TESTS"} = 1; } # with-extra-tests if ($use_xtests eq "yes") { $configcond{"XTESTS"} = 1; } # with-samples if ($use_samples eq "yes") { $configcond{"SAMPLES"} = 1; } # with-openssl if ($use_openssl eq "no") { if ($verbose) { print "OpenSSL library is disabled\n"; } } elsif ($use_openssl eq "auto") { if ($verbose) { print "checking for an OpenSSL built directory at sibling root\n"; } opendir DIR, $openssl_path || die "No Directory: $!\n"; my @dirlist = grep (/^openssl-[0-9]+\.[0-9]+\.[0-9]+[a-z]{0,1}$/i, readdir(DIR)); closedir(DIR); # Make sure we have something if (scalar(@dirlist) == 0) { die "can't find an OpenSSL at sibling root\n"; } # Now see if we have a directory or just a file. # Make sure we are case insensitive my $file; foreach $file (sort {uc($b) cmp uc($a)} @dirlist) { if (-f File::Spec->catfile($openssl_path, $file, "inc32\\openssl", "opensslv.h")) { $openssl_path = File::Spec->catdir($openssl_path, $file); $use_openssl = "yes"; last; } } # If we have one use it otherwise report the error if ($use_openssl eq "auto") { die "can't find an OpenSSL built directory at sibling root\n"; } } # falls into (so no else) if ($use_openssl eq "yes") { $openssl_path = File::Spec->rel2abs($openssl_path); if ($verbose) { print "checking for OpenSSL built directory at \"$openssl_path\"\n"; } if (!-f File::Spec->catfile($openssl_path, "inc32\\openssl", "opensslv.h")) { die "can't find OpenSSL opensslv.h include\n"; } if (!-f File::Spec->catfile($openssl_path, "out32dll", "libeay32.lib")) { die "can't find OpenSSL libeay32.lib library\n"; } if (!-f File::Spec->catfile($openssl_path, "out32dll", "libeay32.dll")) { die "can't find OpenSSL libeay32.dll DLL\n"; } my $openssl_inc = File::Spec->catdir($openssl_path, "inc32"); my $openssl_libdir = File::Spec->catdir($openssl_path, "out32dll"); my $openssl_lib = File::Spec->catfile($openssl_libdir, "libeay32.lib"); my $openssl_dll = File::Spec->catfile($openssl_libdir, "libeay32.dll"); $configcond{"OPENSSL"} = 1; $configdefd{"CRYPTO"} = "OPENSSL"; $configvar{"OPENSSL_PATH"} = "$openssl_path"; $configinc{"OPENSSL_INC"} = "$openssl_inc"; $configlib{"OPENSSL_LIB"} = "$openssl_lib"; $configdll{"OPENSSL_DLL"} = "$openssl_dll"; if (-f File::Spec->catfile($openssl_inc, "openssl", "dsa.h")) { $configdefh{"HAVE_OPENSSL_DSA"} = 1; } elsif ($verbose) { print "OpenSSL DSA support is disabled\n"; } } # check OpenSSL if ($use_openssl eq "yes") { if ($verbose) { print "checking whether linking with OpenSSL works\n"; } my $dll = $configdll{"OPENSSL_DLL"}; my $ret = `copy "$dll" .`; if ($? != 0) { die "Can't copy OpenSSL DLL to working directory: $ret\n"; } open F, ">testossl.c" || die $!; print F << 'EOF'; #include int main(void) { ERR_clear_error(); return(0); } EOF close F; my $include = $configinc{"OPENSSL_INC"}; my $library = $configlib{"OPENSSL_LIB"}; $compret = `cl /nologo /MD /I "$include" testossl.c "$library"`; if (grep { -f and -x } ".\\testossl.exe") { `.\\testossl.exe`; if ($? != 0) { die "OpenSSL test failed\n"; } } else { die "can't compile OpenSSL test: $compret\n"; } } # check OpenSSL version if ($use_openssl eq "yes") { if ($verbose) { printf "checking OpenSSL library version\n"; } open F, ">testosslv.c" || die $!; print F << 'EOF'; #include #include int main() { if ((OPENSSL_VERSION_NUMBER >= 0x009070cfL && OPENSSL_VERSION_NUMBER < 0x00908000L) || OPENSSL_VERSION_NUMBER >= 0x0090804fL) return (0); printf("\n\nFound OPENSSL_VERSION_NUMBER %#010x\n", OPENSSL_VERSION_NUMBER); printf("Require OPENSSL_VERSION_NUMBER 0x009070cf or greater (0.9.7l)\n" "Require OPENSSL_VERSION_NUMBER 0x0090804f or greater (0.9.8d)\n\n"); return (1); } EOF close F; my $include = $configinc{"OPENSSL_INC"}; my $library = $configlib{"OPENSSL_LIB"}; $compret = `cl /nologo /MD /I "$include" testosslv.c "$library"`; if (grep { -f and -x } ".\\testosslv.exe") { `.\\testosslv.exe`; if ($? != 0) { die "OpenSSL version test failed\n"; } } else { die "can't compile OpenSSL version test: $compret\n"; } } # check EVP_sha256 / EVP_sha384 / EVP_sha512 if ($use_openssl eq "yes") { if ($verbose) { printf "checking for EVP_sha256\n"; } open F, ">testsha256.c" || die $!; print F << 'EOF'; extern void *EVP_sha256(); int main() { return EVP_sha256() != 0; } EOF close F; my $library = $configlib{"OPENSSL_LIB"}; $compret = `cl /nologo /MD testsha256.c "$library"`; if (grep { -f and -x } ".\\testsha256.exe") { `.\\testsha256.exe`; if ($? == 0) { if ($verbose) { print "EVP_sha256 test failed: disabling EVP_sha256\n"; } $use_ecdsa = "no"; $enable_openssl_hash = "no"; } else { $configdefh{"HAVE_EVP_SHA256"} = 1; } } else { if ($verbose) { print "can't compile EVP_sha256 test: $compret\n"; print "disabling EVP_sha256\n"; } $use_ecdsa = "no"; $enable_openssl_hash = "no"; } if ($verbose) { printf "checking for EVP_sha384\n"; } open F, ">testsha384.c" || die $!; print F << 'EOF'; extern void *EVP_sha384(); int main() { return EVP_sha384() != 0; } EOF close F; $compret = `cl /nologo /MD testsha384.c "$library"`; if (grep { -f and -x } ".\\testsha384.exe") { `.\\testsha384.exe`; if ($? == 0) { if ($verbose) { print "EVP_sha384 test failed: disabling EVP_sha384\n"; } $use_ecdsa = "no"; $enable_openssl_hash = "no"; } else { $configdefh{"HAVE_EVP_SHA384"} = 1; } } else { if ($verbose) { print "can't compile EVP_sha384 test: $compret\n"; print "disabling EVP_sha384\n"; } $use_ecdsa = "no"; $enable_openssl_hash = "no"; } if ($verbose) { printf "checking for EVP_sha512\n"; } open F, ">testsha512.c" || die $!; print F << 'EOF'; extern void *EVP_sha512(); int main() { return EVP_sha512() != 0; } EOF close F; $compret = `cl /nologo /MD testsha512.c "$library"`; if (grep { -f and -x } ".\\testsha512.exe") { `.\\testsha512.exe`; if ($? == 0) { if ($verbose) { print "EVP_sha512 test failed: disabling EVP_sha512\n"; } } else { $configdefh{"HAVE_EVP_SHA512"} = 1; } } else { if ($verbose) { print "can't compile EVP_sha512 test: $compret\n"; print "disabling EVP_sha512\n"; } } } # with-ecdsa if ($use_openssl eq "no") { $use_ecdsa = "no"; } if ($use_ecdsa eq "auto") { if ($verbose) { print "checking for OpenSSL ECDSA support\n"; } open F, ">testecdsa.c" || die $!; print F << 'EOF'; #include #include int main(void) { EC_KEY *ec256, *ec384; ec256 = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); ec384 = EC_KEY_new_by_curve_name(NID_secp384r1); if (ec256 == NULL || ec384 == NULL) return (2); return (0); } EOF close F; my $include = $configinc{"OPENSSL_INC"}; my $library = $configlib{"OPENSSL_LIB"}; $compret = `cl /nologo /MD /I "$include" testecdsa.c "$library"`; if (grep { -f and -x } ".\\testecdsa.exe") { `.\\testecdsa.exe`; if ($? != 0) { if ($verbose) { print "ECDSA test failed: disabling ECDSA\n"; } $use_ecdsa = "no"; } } else { if ($verbose) { print "can't compile ECDSA test: $compret\n"; print "disabling ECDSA\n"; } $use_ecdsa = "no"; } } if ($use_ecdsa ne "no") { $use_ecdsa = "yes"; $configdefh{"HAVE_OPENSSL_ECDSA"} = 1; } # with-gost if ($use_openssl eq "no") { $use_gost = "no"; } if ($use_gost eq "auto") { if ($verbose) { print "checking for OpenSSL GOST support\n"; } open F, ">testgost.c" || die $!; print F << 'EOF'; #include #include int main(void) { #if (OPENSSL_VERSION_NUMBER >= 0x10000000L) ENGINE *e; EC_KEY *ek; ek = NULL; OPENSSL_config(NULL); e = ENGINE_by_id("gost"); if (e == NULL) return (1); if (ENGINE_init(e) <= 0) return (1); return (0); #else return (1); #endif } EOF close F; my $include = $configinc{"OPENSSL_INC"}; my $library = $configlib{"OPENSSL_LIB"}; $compret = `cl /nologo /MD /I "$include" testgost.c "$library"`; if (grep { -f and -x } ".\\testgost.exe") { `.\\testgost.exe`; if ($? != 0) { if ($verbose) { print "GOST test failed: disabling GOST\n"; } $use_gost = "no"; } } else { if ($verbose) { print "can't compile GOST test: $compret\n"; print "disabling GOST\n"; } $use_gost = "no"; } } if ($use_gost ne "no") { $use_gost = "yes"; $configdefh{"HAVE_OPENSSL_GOST"} = 1; } if ($gost_encoding eq "ans1") { $configdefh{"PREFER_GOSTASN1"} = 1; } elsif ($gost_encoding ne "raw") { die "Unrecognized GOST private key encoding: $gost_encoding\n"; } # with-aes if ($use_openssl eq "no") { if ($use_aes ne "pkcs11") { $use_aes = "no"; } } if ($use_aes eq "auto") { if ($verbose) { print "checking for OpenSSL EVP AES support\n"; } $use_aes = "evp"; open F, ">testevpaes.c" || die $!; print F << 'EOF'; #include int main(void) { EVP_CIPHER *aes128, *aes192, *aes256; aes128 = EVP_aes_128_ecb(); aes192 = EVP_aes_192_ecb(); aes256 = EVP_aes_256_ecb(); if (aes128 == NULL || aes192 == NULL || aes256 == NULL) return (1); return (0); } EOF close F; my $include = $configinc{"OPENSSL_INC"}; my $library = $configlib{"OPENSSL_LIB"}; $compret = `cl /nologo /MD /I "$include" testevpaes.c "$library"`; if (grep { -f and -x } ".\\testevpaes.exe") { `.\\testevpaes.exe`; if ($? != 0) { if ($verbose) { print "EVP AES test failed: disabling EVP AES\n"; } $use_aes = "auto"; } } else { if ($verbose) { print "can't compile EVP AES test: $compret\n"; print "disabling EVP AES\n"; } $use_aes = "auto"; } } if ($use_aes eq "auto") { if ($verbose) { print "checking for OpenSSL native AES support\n"; } $use_aes = "native"; open F, ">testaes.c" || die $!; print F << 'EOF'; #include AES_KEY k; const unsigned char bufin[16]; unsigned char bufout[16]; int main(void) { AES_encrypt(bufin, bufout, &k); return (0); } EOF close F; my $include = $configinc{"OPENSSL_INC"}; my $library = $configlib{"OPENSSL_LIB"}; $compret = `cl /nologo /MD /I "$include" testaes.c "$library"`; if (grep { -f and -x } ".\\testaes.exe") { `.\\testaes.exe`; if ($? != 0) { if ($verbose) { print "native AES test failed: disabling AES\n"; } $use_aes = "no"; } } else { if ($verbose) { print "can't compile native AES test: $compret\n"; print "disabling AES\n"; } $use_aes = "no"; } } if ($use_aes eq "yes") { $configdefh{"HAVE_OPENSSL_EVP_AES"} = 1; } elsif ($use_aes eq "evp") { $configdefh{"HAVE_OPENSSL_EVP_AES"} = 1; $use_aes = "yes"; } elsif ($use_aes eq "native") { $configdefh{"HAVE_OPENSSL_AES"} = 1; $use_aes = "yes"; } elsif ($use_aes eq "pkcs11") { $use_aes = "yes"; } if ($use_aes eq "yes") { $configdefp{"ISC_PLATFORM_WANTAES"} = 1; $configcond{"AES"} = 1; } # with-sit-alg if ($enable_sit ne "no") { if ($sit_algorithm eq "aes") { if ($use_aes ne "yes") { $sit_algorithm = "sha256"; } else { $configdefh{"AES_SIT"} = 1; } } if ($sit_algorithm eq "sha1") { $configdefh{"HMAC_SHA1_SIT"} = 1; } elsif ($sit_algorithm eq "sha256") { $configdefh{"HMAC_SHA256_SIT"} = 1; } elsif ($sit_algorithm ne "aes") { die "Unrecognized SIT algorithm: $sit_algorithm\n"; } } # enable-openssl-hash if ($enable_openssl_hash eq "yes") { if ($use_openssl eq "no") { die "No OpenSSL for hash functions\n"; } $configdefp{"ISC_PLATFORM_OPENSSLHASH"} = 1; if ($verbose) { print "checking HMAC_Init() return type\n"; } open F, ">testhmac.c" || die $!; print F << 'EOF'; #include int main(void) { HMAC_CTX ctx; int n = HMAC_Init(&ctx, NULL, 0, NULL); n += HMAC_Update(&ctx, NULL, 0); n += HMAC_Final(&ctx, NULL, NULL); return(n); } EOF close F; my $include = $configinc{"OPENSSL_INC"}; my $library = $configlib{"OPENSSL_LIB"}; $compret = `cl /nologo /MD /I "$include" testhmac.c "$library"`; if (grep { -f and -x } ".\\testhmac.exe") { $configdefh{"HMAC_RETURN_INT"} = 1; } } # with-pkcs11 if ($use_pkcs11 ne "no") { $configcond{"PKCS11"} = 1; $configdefd{"USE_PKCS11"} = "USE_PKCS11"; $configvar{"PKCS11_TOOLS"} = "pkcs11"; $configdefd{"PK11_LIB_LOCATION"} = "PK11_LIB_LOCATION=\"$pkcs11_path\""; } # with-gssapi if ($use_gssapi eq "no") { if ($verbose) { print "gssapi library is disabled\n"; } } else { $gssapi_path = File::Spec->rel2abs($gssapi_path); if ($verbose) { print "checking for gssapi directory at \"$gssapi_path\"\n"; } $configcond{"GSSAPI"} = 1; $configdefd{"USE_GSSAPI"} = "GSSAPI"; if (!-f File::Spec->catfile($gssapi_path, "include", "gssapi", "gssapi.h")) { die "can't find gssapi.h include\n"; } if (!-f File::Spec->catfile($gssapi_path, "include", "gssapi", "gssapi_krb5.h")) { die "can't find gssapi_krb5.h include\n"; } if (!-f File::Spec->catfile($gssapi_path, "include", "krb5", "krb5.h")) { die "can't find krb5.h include\n"; } $configinc{"GSSAPI_INC"} = File::Spec->catdir($gssapi_path, "include"); my $bits = "32"; my $gssapi_lib; my $krb5_lib; if ($want_win32 eq "yes") { $bits = "32"; if (!-f File::Spec->catfile($gssapi_path, "lib", "i386", "gssapi${bits}.lib")) { die "can't find gssapi${bits}.lib library\n"; } $gssapi_lib = File::Spec->catfile($gssapi_path, "lib", "i386", "gssapi${bits}.lib"); if (!-f File::Spec->catfile($gssapi_path, "lib", "i386", "krb5_${bits}.lib")) { die "can't find krb5_${bits}.lib library\n"; } $krb5_lib = File::Spec->catfile($gssapi_path, "lib", "i386", "krb5_${bits}.lib"); } elsif ($want_x64 eq "yes") { $bits = "64"; if (!-f File::Spec->catfile($gssapi_path, "lib", "amd64", "gssapi${bits}.lib")) { die "can't find gssapi${bits}.lib library\n"; } $gssapi_lib = File::Spec->catfile($gssapi_path, "lib", "amd64", "gssapi${bits}.lib"); if (!-f File::Spec->catfile($gssapi_path, "lib", "amd64", "krb5_${bits}.lib")) { die "can't find krb5_${bits}.lib library\n"; } $krb5_lib = File::Spec->catfile($gssapi_path, "lib", "amd64", "krb5_${bits}.lib"); } else { die "can't happen: no choice between Win32 and x64\n"; } if (!-f File::Spec->catfile($gssapi_path, "bin", "gssapi${bits}.dll")) { die "can't find gssapi${bits}.dll DLL\n"; } if (!-f File::Spec->catfile($gssapi_path, "bin", "krb5_${bits}.dll")) { die "can't find krb5_${bits}.dll DLL\n"; } if (!-f File::Spec->catfile($gssapi_path, "bin", "comerr${bits}.dll")) { die "can't find comerr${bits}.dll DLL\n"; } if (!-f File::Spec->catfile($gssapi_path, "bin", "k5sprt${bits}.dll")) { die "can't find k5sprt${bits}.dll DLL\n"; } if (!-f File::Spec->catfile($gssapi_path, "bin", "wshelp${bits}.dll")) { die "can't find wshelp${bits}.dll DLL\n"; } $configlib{"GSSAPI_LIB"} = "$gssapi_lib"; $configlib{"KRB5_LIB"} = "$krb5_lib"; my $gssapi_dll = File::Spec->catfile($gssapi_path, "bin", "gssapi${bits}.dll"); $configdll{"GSSAPI_DLL"} = "$gssapi_dll"; my $krb5_dll = File::Spec->catfile($gssapi_path, "bin", "krb5_${bits}.dll"); $configdll{"KRB5_DLL"} = "$krb5_dll"; my $comerr_dll = File::Spec->catfile($gssapi_path, "bin", "comerr${bits}.dll"); $configdll{"COMERR_DLL"} = "$comerr_dll"; my $k5sprt_dll = File::Spec->catfile($gssapi_path, "bin", "k5sprt${bits}.dll"); $configdll{"K5SPRT_DLL"} = "$k5sprt_dll"; my $wshelp_dll = File::Spec->catfile($gssapi_path, "bin", "wshelp${bits}.dll"); $configdll{"WSHELP_DLL"} = "$wshelp_dll"; } # enable-isc-spnego if ($use_gssapi ne "yes") { $enable_isc_spnego = "no"; } elsif ($enable_isc_spnego eq "yes") { if ($use_gssapi eq "no") { die "No GSSAPI for SPNEGO\n"; } $configdefd{"USE_ISC_SPNEGO"} = "USE_ISC_SPNEGO"; } # with-geoip if ($use_geoip eq "no") { if ($verbose) { print "geoip library is disabled\n"; } } else { $configcond{"GEOIP"} = 1; $geoip_path = File::Spec->rel2abs($geoip_path); if ($verbose) { print "checking for geoip directory at \"$geoip_path\"\n"; } if (!-f File::Spec->catfile($geoip_path, "GeoIP.h")) { die "can't find GeoIP.h include\n"; } if (!-f File::Spec->catfile($geoip_path, "GeoIP.lib")) { die "can't find Geoip.lib library\n"; } if (!-f File::Spec->catfile($geoip_path, "GeoIP.dll")) { die "can't find Geoip.dll DLL\n"; } $configinc{"GEOIP_INC"} = "$geoip_path"; my $geoip_lib = File::Spec->catfile($geoip_path, "GeoIP.lib"); $configlib{"GEOIP_LIB"} = "$geoip_lib"; my $geoip_dll = File::Spec->catfile($geoip_path, "GeoIP.dll"); $configdll{"GEOIP_DLL"} = "$geoip_dll"; if ($verbose) { print "checking for GeoIP support\n"; } my $ret = `copy "$geoip_dll" .`; if ($? != 0) { die "Can't copy GeoIP DLL to working directory: $ret\n"; } open F, ">testgeoip.c" || die $!; print F << 'EOF'; extern void *GeoIP_open(); int main() { return GeoIP_open != 0; } EOF close F; $compret = `cl /nologo /MD testgeoip.c "$geoip_lib"`; if (grep { -f and -x } ".\\testgeoip.exe") { `.\\testgeoip.exe`; if ($? == 0) { die "GeoIP test failed\n"; } } else { die "can't compile GeoIP test: $compret\n"; } $configdefh{"HAVE_GEOIP"} = 1; if ($verbose) { print "checking for GeoIP Country IPv6 support\n"; } my $geoip_inc = qq(/I "$geoip_path"); my $geoip_libs = qq("$geoip_lib" ws2_32.lib); open F, ">testgeoip1.c" || die $!; print F << 'EOF'; #include struct in6_addr in6; int flag = 1; int main() { if (flag) return 1; return GeoIP_country_name_by_ipnum_v6(NULL, in6) != NULL; } EOF close F; $compret = `cl /nologo $geoip_inc /MD testgeoip1.c $geoip_libs`; if (grep { -f and -x } ".\\testgeoip1.exe") { `.\\testgeoip1.exe`; if ($? == 0) { die "GeoIP Country IPv6 test failed\n"; } } else { die "can't compile GeoIP Country IPv6 test: $compret\n"; } $configdefh{"HAVE_GEOIP_V6"} = 1; if ($verbose) { print "checking for GeoIP City IPv6 support\n"; } open F, ">testgeoip2.c" || die $!; print F << 'EOF'; #include #include struct in6_addr in6; int i = GEOIP_CITY_EDITION_REV0_V6; int flag = 1; int main() { if (flag) return 1; return GeoIP_record_by_ipnum_v6(NULL, in6) != NULL; } EOF close F; $compret = `cl /nologo $geoip_inc /MD testgeoip2.c $geoip_libs`; if (grep { -f and -x } ".\\testgeoip2.exe") { `.\\testgeoip2.exe`; if ($? == 0) { die "GeoIP City IPv6 test failed\n"; } } else { die "can't compile GeoIP City IPv6 test: $compret\n"; } $configdefh{"HAVE_GEOIP_CITY_V6"} = 1; } # with-readline if ($use_readline eq "no") { if ($verbose) { print "readline library is disabled\n"; } } else { $readline_path = File::Spec->rel2abs($readline_path); if ($verbose) { print "checking for readline directory at \"$readline_path\"\n"; } if (!-f File::Spec->catfile($readline_path, "readline", "readline.h")) { die "can't find readline.h include\n"; } if (!-f File::Spec->catfile($readline_path, "readline", "readline.lib")) { die "can't find readline.lib library\n"; } $configdefh{"HAVE_READLINE"} = 1; $configinc{"READLINE_INC"} = "$readline_path"; my $readline_lib = File::Spec->catfile($readline_path, "readline", "readline.lib"); $configlib{"READLINE_LIB"} = "$readline_lib"; if (-f File::Spec->catfile($readline_path, "readline", "readlineD.lib")) { my $readline_libd = File::Spec->catfile($readline_path, "readline", "readlineD.lib"); $configlib{"READLINE_LIBD"} = "$readline_libd"; } else { $configlib{"READLINE_LIBD"} = "$readline_lib"; } } # with-idn (including with-iconv) if ($use_idn eq "no") { if ($verbose) { print "IDN kit is disabled\n"; } } else { $idn_path = File::Spec->rel2abs($idn_path); if ($verbose) { print "checking for IDN kit directory at \"$idn_path\"\n"; } if (!-f File::Spec->catfile($idn_path, "idn", "api.h")) { die "can't find idn\\api.h include\n"; } if (!-f File::Spec->catfile($idn_path, "idn", "idnkit.lib")) { die "can't find idnkit.lib library\n"; } if (!-f File::Spec->catfile($idn_path, "idn", "idnkit.dll")) { die "can't find idnkit.dll DLL\n"; } $configcond{"IDNKIT"} = 1; $configdefh{"WITH_IDN"} = 1; $configinc{"IDN_INC"} = "$idn_path"; my $idn_lib = File::Spec->catfile($idn_path, "idn", "idnkit.lib"); $configlib{"IDN_LIB"} = "$idn_lib"; my $idn_dll = File::Spec->catfile($idn_path, "idn", "idnkit.dll"); $configdll{"IDN_DLL"} = "$idn_dll"; if ($iconv_path eq " --idn-- ") { my $iconv_dll = File::Spec->catfile($idn_path, "idn", "iconv.dll"); $configdll{"ICONV_DLL"} = "$iconv_dll"; } else { my $iconv_dll =File::Spec->catfile($iconv_path, "iconv.dll"); $configdll{"ICONV_DLL"} = "$iconv_dll"; } } # with-libxml2 if ($use_libxml2 eq "no") { if ($verbose) { print "libxml2 library is disabled\n"; } } elsif ($use_libxml2 eq "auto") { if ($verbose) { print "checking for a libxml2 built directory at sibling root\n"; } opendir DIR, $libxml2_path || die "No Directory: $!\n"; my @dirlist = grep (/^libxml2-[0-9]+\.[0-9]+\.[0-9]+[a-z]*/i, readdir(DIR)); closedir(DIR); # Make sure we have something if (scalar(@dirlist) == 0) { die "can't find a libxml2 at sibling root\n"; } # Now see if we have a directory or just a file. # Make sure we are case insensitive my $file; foreach $file (sort {uc($b) cmp uc($a)} @dirlist) { if (-f File::Spec->catfile($libxml2_path, $file, "include\\libxml", "xmlversion.h")) { $libxml2_path = File::Spec->catdir($libxml2_path, $file); $use_libxml2 = "yes"; last; } } # If we have one use it otherwise report the error if ($use_libxml2 eq "auto") { die "can't find a libxml2 built directory at sibling root\n"; } } # falls into (so no else) if ($use_libxml2 eq "yes") { $libxml2_path = File::Spec->rel2abs($libxml2_path); if ($verbose) { print "checking for libxml2 built directory at \"$libxml2_path\"\n"; } if (!-f File::Spec->catfile($libxml2_path, "include\\libxml", "xmlversion.h")) { die "can't find libxml2 xmlversion.h include\n"; } if (!-f File::Spec->catfile($libxml2_path, "win32\\bin.msvc", "libxml2.lib")) { die "can't find Libxml2 libxml2.lib library\n"; } if (!-f File::Spec->catfile($libxml2_path, "win32\\bin.msvc", "libxml2.dll")) { die "can't find Libxml2 DLL\n"; } $configcond{"LIBXML2"} = 1; $configdefh{"HAVE_LIBXML2"} = 1; my $libxml2_inc = File::Spec->catdir($libxml2_path, "include"); $configinc{"LIBXML2_INC"} = "$libxml2_inc"; my $libxml2_libdir = File::Spec->catdir($libxml2_path, "win32\\bin.msvc"); my $libxml2_lib = File::Spec->catfile($libxml2_libdir, "libxml2.lib"); $configlib{"LIBXML2_LIB"} = "$libxml2_lib"; my $libxml2_dll = File::Spec->catfile($libxml2_libdir, "libxml2.dll"); $configdll{"LIBXML2_DLL"} = "$libxml2_dll"; } # with-python if ($use_python eq "no") { if ($verbose) { print "python is disabled\n"; } } elsif ($use_python eq "auto") { if ($verbose) { print "checking for python in path\n"; } my $pythonret = `python -c "quit()" 2>&1`; if ($? != 0) { die "can't launch the python interpreter: $pythonret\n"; } $use_python = "yes"; } if ($use_python ne "no") { if ($verbose) { my $pythonret = `"$python_command" -c "quit()" 2>&1`; if ($? != 0) { print STDERR "can't lanch the local python interpreter: $pythonret\n"; } } $configcond{"PYTHON"} = 1; $configdefd{"USE_PYTHON"} = "USE_PYTHON"; $configvar{"PYTHON"} = "$python_command"; # Only a default! $configvar{"prefix"} = "C:\\Program Files\ISC BIND 9"; } # with-vcredist $vcredist_path = File::Spec->rel2abs($vcredist_path); if (!grep { -f and -x } $vcredist_path) { die "$vcredist_path is not correct\n"; } else { $configvar{"VCREDIST_PATH"} = "$vcredist_path"; } # tuning if ($tuning eq "large") { $configdefh{"TUNE_LARGE"} = 1; } # setup config.h with %configdefh sub setupconfigh { my $line; my @Lines; open F, $configfilein || die $!; @Lines = ; close F; foreach $line (@Lines) { chomp $line; if ($line =~ /^@([^@]+)\@$/) { if (defined($configdefh{$1})) { $line = "#define $1 $configdefh{$1}"; } else { $line = "/* #undef $1 */"; } } } open F, $configfileout || die $!; if ($verbose) { print "Setting up config.h\n"; } foreach $line (@Lines) { print F $line . "\n"; } close F; } # setup platform.h with %configdefp sub setupplatformh { my $line; my @Lines; open F, $platformfile . ".in" || die $!; @Lines = ; close F; foreach $line (@Lines) { chomp $line; if ($line =~ /^@([^@]+)\@$/) { if (defined($configdefp{$1})) { $line = "#define $1 $configdefp{$1}"; } else { $line = "/* #undef $1 */"; } } } open F, ">" . $platformfile || die $!; if ($verbose) { print "Setting up platform.h\n"; } foreach $line (@Lines) { print F $line . "\n"; } close F; } # escape spaces sub kw { if ($_[0] =~ / /) { return "\"$_[0]\""; } else { return "$_[0]"; } } # setup a file with %configcond stack and %config{var,defd,inc,lib,dll} sub setupfile { my $line; my @Linesin; my @Linesout; my $filename = $_[0]; my $cond; my @conds; my $pass = 1; my @passes; my $val; open F, $filename . ".in" || die $!; @Linesin = ; close F; foreach $line (@Linesin) { chomp $line; if ($line =~ /^\@IF (.*)$/) { if (defined($cond)) { unshift(@conds, $cond); unshift(@passes, $pass); } $cond = $1; if (defined($configcond{$cond})) { # do nothing } else { $pass = 0; } next; } elsif ($line =~ /^\@ELSE (.*)$/) { if ($cond ne $1) { die "\@ELSE $1 mismatch in $filename\n"; } if (defined($configcond{$cond})) { $pass = 0; } else { if (scalar(@conds) > 0) { $pass = $passes[0]; } else { $pass = 1; } } next; } elsif ($line =~ /^\@END (.*)$/) { if ($cond ne $1) { die "\@END $1 mismatch in $filename\n"; } $cond = shift(@conds); if (scalar(@passes) > 0) { $pass = shift(@passes); } else { $pass = 1; } next; } if ($pass == 0) { next; } while ($line =~ /@([^@ ]*)@/) { if ($1 ~~ @substvar) { if (defined($configvar{$1})) { $val = kw($configvar{$1}); $line = "$`$val$'"; } else { $line = "$`$'"; } } elsif ($1 ~~ @substdefd) { if (defined($configdefd{$1})) { my $def = $configdefd{$1}; my $pre = "$`"; my $post = "$'"; $def =~ s/([\\ "])/\\$1/g; $line = qq($pre/D "$def"$post); } else { $line = "$`$'"; } } elsif ($1 ~~ @substinc) { if (defined($configinc{$1})) { $line = qq($`/I "$configinc{$1}"$'); } else { $line = "$`$'"; } } elsif ($1 ~~ @substlib) { if (defined($configlib{$1})) { $val = kw($configlib{$1}); $line = "$`$val$'"; } else { $line = "$`$'"; } } elsif ($1 ~~ @substdll) { if (defined($configdll{$1})) { $val = kw($configdll{$1}); $line = "$`$val$'"; } else { $line = "$`$'"; } } else { die "unknown control $& in $filename\n"; } } push @Linesout, $line; } open F, ">" . $filename || die $!; if ($verbose) { print "Setting up $filename\n"; } foreach $line (@Linesout) { print F $line . "\n"; } close F; } # setup a project with %configcond stack and %config{var,defd,inc,lib,dll} sub setupproject { my $line; my @Linesin; my @Linesout; my $projectname = $_[0]; my $cond; my @conds; my $pass = 1; my @passes; my $val; open F, $projectname . ".in" || die $!; @Linesin = ; close F; foreach $line (@Linesin) { chomp $line; if ($line =~ /^\@IF (.*)$/) { if (defined($cond)) { unshift(@conds, $cond); unshift(@passes, $pass); } $cond = $1; if (defined($configcond{$cond})) { # do nothing } else { $pass = 0; } next; } elsif ($line =~ /^\@ELSE (.*)$/) { if ($cond ne $1) { die "\@ELSE $1 mismatch in $projectname\n"; } if (defined($configcond{$cond})) { $pass = 0; } else { if (scalar(@conds) > 0) { $pass = $passes[0]; } else { $pass = 1; } } next; } elsif ($line =~ /^\@END (.*)$/) { if ($cond ne $1) { die "\@END $1 mismatch in $projectname\n"; } $cond = shift(@conds); if (scalar(@passes) > 0) { $pass = shift(@passes); } else { $pass = 1; } next; } if ($pass == 0) { next; } while ($line =~ /@([^@ ]*)@/) { if ($1 ~~ @substvar) { if (defined($configvar{$1})) { $val = kw($configvar{$1}); $line = "$`$val$'"; } else { $line = "$`$'"; } } elsif ($1 ~~ @substdefd) { if (defined($configdefd{$1})) { $val = kw($configdefd{$1}); $line = "$`$val;$'"; } else { $line = "$`$'"; } } elsif ($1 ~~ @substinc) { if (defined($configinc{$1})) { $val = kw($configinc{$1}); $line = "$`$val;$'"; } else { $line = "$`$'"; } } elsif ($1 ~~ @substlib) { if (defined($configlib{$1})) { $val = kw($configlib{$1}); $line = "$`$val;$'"; } else { $line = "$`$'"; } } elsif ($1 ~~ @substdll) { if (defined($configdll{$1})) { $val = kw($configdll{$1}); $line = "$`$val$'"; } else { $line = "$`$'"; } } else { die "unknown control $& in $projectname\n"; } } push @Linesout, $line; } open F, ">" . $projectname || die $!; if ($verbose) { print "Setting up $projectname\n"; } foreach $line (@Linesout) { print F $line . "\n"; } close F; } # make versions.h sub makeversion { # List of directories with version files my @dirlist = ("isc", "dns", "isccc", "isccfg", "lwres", "bind9", "irs"); my %LibMacros = ( "bind9" => "LIBBIND9_EXPORTS", "dns" => "LIBDNS_EXPORTS", "irs" => "LIBIRS_EXPORTS", "isc" => "LIBISC_EXPORTS", "isccc" => "LIBISCCC_EXPORTS", "isccfg" => "LIBISCCFG_EXPORTS", "lwres" => "LIBLWRES_EXPORTS"); my @VersionNames = ("LIBINTERFACE", "LIBREVISION", "LIBAGE"); my %Versions; my $Version; my %ApiVersions; my $Mapapi; my $versionfile = "versions.h"; my $versionpath = "..\\$versionfile"; my $data; my $name; my $value; # First get the version information open V, "..\\version" || die $!; while () { chomp; ($data) = split(/\#/); if ($data) { ($name, $value) = split(/=/, $data); ($name) = split(/\s+/, $name); if ($name eq 'PRODUCT' || $name eq 'DESCRIPTION') { ($value) =~ s/^["\s]+//; ($value) =~ s/["\s]+$//; } else { ($value) = split(/\s+/, $value); } $Versions{$name} = $value; } } close V; # And the mapapi one open M, "..\\lib\\dns\\mapapi" || die $!; while () { chomp; ($data) = split(/\#/); if ($data) { ($name, $value) = split(/=/, $data); ($name) = split(/\s+/, $name); if ($name eq 'MAPAPI') { ($value) =~ s/^["\s]+//; ($value) =~ s/["\s]+$//; } else { ($value) = split(/\s+/, $value); } $Mapapi = $value; } } close M; # Now set up the output version file my $ThisDate = scalar localtime(); open O, ">$versionpath" || die "Can't open output file $versionpath: $!\n"; # Standard Header print O '/* * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ '; print O "/*\n"; print O " * $versionfile."; print O " Generated automatically by Configure.pl.\n"; print O " * Date generated: $ThisDate\n"; print O " */\n\n"; print O ' #ifndef VERSIONS_H #define VERSIONS_H 1 '; $Version = "$Versions{'MAJORVER'}.$Versions{'MINORVER'}"; if ($Versions{'PATCHVER'} != "") { $Version = "$Version.$Versions{'PATCHVER'}"; } $Version = "$Version$Versions{'RELEASETYPE'}$Versions{'RELEASEVER'}"; $Version = "$Version$Versions{'EXTENSIONS'}"; if ($verbose) { print "BIND Version: $Version\n"; } print O "#define VERSION \"$Version\"\n"; print O "#define PRODUCT \"$Versions{'PRODUCT'}\"\n\n"; print O "#define DESCRIPTION \"$Versions{'DESCRIPTION'}\"\n\n"; print O "#define MAJOR \"$Versions{'MAJORVER'}.$Versions{'MINORVER'}\"\n\n"; print O "#define MAPAPI \"$Mapapi\"\n\n"; my $dir; my $apifile; foreach $dir (@dirlist) { $apifile = "..\\lib\\$dir\\api"; open A, $apifile || die $!; while () { chomp; ($data) = split(/\#/); if ($data) { ($name, $value) = split(/=/, $data); $name =~ s/\s+//; $value =~ s/\s+//; $ApiVersions{$name} = $value; } } close A; print O "\n#ifdef $LibMacros{$dir}\n"; foreach $name (@VersionNames) { print O "#define $name\t$ApiVersions{$name}\n"; } print O "#endif\n\n"; } print O "#endif /* VERSIONS_H */\n"; close O; } # make srcid.h sub makesrcid { my $data; my $name; my $value; my $srcid = "unset"; open SOUT, ">..\\srcid.h" || die "cannot open srcid.h: $!\n"; if (open (SIN, "..\\srcid")) { LOOP: while () { chomp; ($data) = split(/\#/); if ($data) { ($name, $value) = split(/=/, $data); ($name) = split(/\s+/, $name); ($value) = split(/\s+/, $value); next LOOP if ($name != "SRCID"); $srcid = $value; } } close SIN; } # Now set up the output version file my $ThisDate = scalar localtime(); # Standard Header print SOUT '/* * Copyright (C) 2012 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ '; print SOUT "/*\n"; print SOUT " * srcid.h"; print SOUT " * Generated automatically by Configure.pl.\n"; print SOUT " * Date generated: $ThisDate\n"; print SOUT " */\n\n"; print SOUT ' #ifndef SRCID_H #define SRCID_H 1 '; if ($verbose) { print "BIND SRCID: $srcid\n"; } print SOUT "#define SRCID\t\"$srcid\"\n"; print SOUT "#endif /* SRCID_H */\n"; close SOUT; } # Status if ($verbose) { my $name; print "Configuration Status\n"; print "\tconfig.h:\n"; foreach $name (@substdefh) { if (defined($configdefh{$name})) { print qq(\t\t$name defined to "$configdefh{$name}"\n); } else { printf qq(\t\t$name undefined\n); } } print "\tplatform.h:\n"; foreach $name (@substdefp) { if (defined($configdefp{$name})) { print qq(\t\t$name defined to "$configdefp{$name}"\n); } else { printf qq(\t\t$name undefined\n); } } print "\tconditions:\n"; foreach $name (@substcond) { if (defined($configcond{$name})) { print "\t\t$name is true\n"; } else { print "\t\t$name is false\n"; } } print "\tsubstitutions:\n"; foreach $name (@substvar) { if (defined($configvar{$name})) { print qq(\t\t$name -> "$configvar{$name}"\n); } } print "\tdefines:\n"; foreach $name (@substdefd) { if (defined($configdefd{$name})) { print qq(\t\t/D "$configdefd{$name}"\n); } } print "\tincludes:\n"; foreach $name (@substinc) { if (defined($configinc{$name})) { print qq(\t\t/I "$configinc{$name}"\n); } } print "\tlibraries:\n"; foreach $name (@substlib) { if (defined($configlib{$name})) { print "\t\t$configlib{$name}\n"; } } print "\tDLLs:\n"; foreach $name (@substdll) { if (defined($configdll{$name})) { print "\t\t$configdll{$name}\n"; } } print "\n"; } # Setup if (($want_win32 eq "yes") || ($want_x64 eq "yes")) { setupconfigh(); setupplatformh(); my $file; foreach $file (@filelist) { setupfile($file); } if (!$legacy_only) { foreach $file (@projectlist) { setupproject($file); } } makeversion(); makesrcid(); print "Configured.\n"; } else { print "add win32 or x64 to commit configuration to build files\n"; } exit 0; # Notes: Unix configure.in options # --enable-developer partially supported # --enable-newstats (9.9/9.9sub only) # --enable-native-pkcs11 supported # --enable-openssl-version-check included without a way to disable it # --enable-openssl-hash supported # --enable-threads included without a way to disable it # --enable-backtrace backtrace included without a way to disable it # --enable-symtable incompatible with DLLs (or libtool) # --enable-exportlib TODO (obsolete) # --enable-ipv6 included without a way to disable it # --enable-atomic supported (renamed to intrinsic) # --enable-spnego support (part of GSSAPI) # --enable-fixed-rrset supported # --enable-querytrace supported # --disable-rpz-nsip supported # --disable-rpz-nsdname supported # --enable-filter-aaaa supported # --enable-sit supported # --enable-full-report supported by verbose # --with-python supported # --with-openssl supported # --with-pkcs11 supported # --with-ecdsa supported # --with-gost supported # --with-aes supported # --with-sit-alg supported # --with-geoip supported # --with-gssapi supported with MIT (K)erberos (f)or (W)indows # --with-libxml2 supported # --with-libjson not supported on WIN32 (package not available on WIN32) # --with-purify ? (package available on WIN32 but for free?) # --with-gperftools-profiler (package not available on WIN32) # --with-libtool not supported on WIN32 (never) # --with-locktype not supported on WIN32 (not yet available on WIN32) # --with-readline supported # --with-idn support # --with-[lib]iconv (part of IDN) # --with-atf not supported on WIN32 (package not available on WIN32) # --with-tuning supported # --with-dlopen included without a way to disable it # --with-dlz-* ? # # Notes: MSVC versions # MSVC 14.0 _MSC_VER == 1900 (VS 2015) # MSVC 12.0 _MSC_VER == 1800 (VS 2013) # MSVC 11.0 _MSC_VER == 1700 (VS 2012) # MSVC 10.0 _MSC_VER == 1600 (VS 2010) # MSVC 9.0 _MSC_VER == 1500 (VS 2008) # MSVC 8.0 _MSC_VER == 1400 (VS 2005) # MSVC 7.1 _MSC_VER == 1310 (VS .NET 2003) # MSVC 7.0 _MSC_VER == 1300 (VS .NET (2002)) # MSVC 6.0 _MSC_VER == 1200 (VS 6.0 (1998)) # MSVC 5.0 _MSC_VER == 1100 (VS 97) bind9-9.10.3.dfsg.P4/win32utils/build.txt0000644000470500017500000001766112664710322017267 0ustar lamontlamontCopyright (C) 2013, 2014 Internet Systems Consortium, Inc. ("ISC") See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. BIND 9.10 for Win32 Source Build Instructions. 02-Feb-2014 Building BIND 9.10 on Windows has the following prerequisites: 1) You need to install Perl for Windows. ActivePerl (http://www.activestate.com/) and Strawberry Perl (http://www.strawberryperl.com) have both been tested and found to work. 2) OpenSSL (http://www.openssl.org) must be downloaded and built on the system on which you are building BIND. 3) If you wish to use the statistics channel, LibXML2 (ftp://xmlsoft.org/libxml2) must be downloaded and built on the system on which you are building BIND. 4) Optional external packages (not used by default) If you wish to use IP geolocation, GeoIP API and database must be downloaded, patched and built on the system on which you are building BIND. If you wish to use readline, the readline library must be downloaded and built on the system on which you are building BIND. 5) The BIND Installer (BINDInstall) includes a copy of the redistributable runtime object vcredist_x86.exe (or vcredist_x64.exe), which is included with Visual Studio and can be downloaded from Microsoft. This file must be in place prior to running Configure. 6) BIND is known to run on the following versions of Windows: Windows XP (with Service Pack 2 or higher), Vista, 7, 8, Server 2003, Server 2008, Server 2008R2, and Server 2012. Step 1: Download and build OpenSSL OpenSSL is required for DNSSEC. If you wish to build BIND 9 without DNSSEC support, skip to step 2. Download and untar the OpenSSL sources from http://www.openssl.org/. Extract them at in the same directory in which you extracted the BIND 9 source: If BIND 9 is in \build\bind-9.10.0, for instance, OpenSSL should be in \build\openssl-1.0.1g (subject to version number changes). Note: Building OpenSSL requires that you install Perl as it uses it during its build process. The following commands work as of openssl-1.0.1g, but you should check the OpenSSL distribution to see if the build instructions in the INSTALL.W32 (or INSTALL.W64) file have changed, in particular for the assembler options: 32-bit builds: (In an x86 Visual Studio Command Prompt window) cd openssl-1.0.1g perl Configure --prefix=c:\openssl enable-static-engine VC-WIN32 ms\do_ms nmake /f ms\ntdll.mak 64-bit builds: (In an x64 Visual Studio Command Prompt window) cd openssl-1.0.1g perl Configure --prefix=c:\openssl64 enable-static-engine VC-WIN64A ms\do_win64a nmake /f ms\ntdll.mak The "enable-static-engine" option is needed when an OpenSSL engine will be used -- for example, when using the GOST signing algorithm or OpenSSL-based PKCS#11 support. If you wish to use OpenSSL-based PKCS#11 to control a cryptographic hardware service module, please see "PKCS#11 (Cryptoki) support" in chapter 4 of the BIND 9 Administrator Reference Guide. You will need to apply the patch in bind9\bin\pkcs11\openssl-1.0.1g-patch (this can be done using the Cygwin 'patch' utility) and add --pk11-libname and --pk11-flavor to the Configure command above. Step 2: Download and build LibXML2 LibXML2 is required to use the statistics channel. If you wish to build BIND 9 without support for this feature, skip to step 3. Download and untar the libxml2 sources from ftp://xmlsoft.org/libxml2. Extract them in the same directory in which you extracted the BIND 9 source: If BIND 9 is in \build\bind-9.10.0, for instance, libxml2 should be in \build\libxml2-2.9.1 (subject to version number changes). Now build libxml2, and copy the resulting files into the include and lib directories: cd libxml2-2.9.1\win32 cscript configure.js compiler=msvc vcmanifest=yes static=yes \ debug=no iconv=no nmake /f Makefile.msvc libxml Step 3: Download and build GeoIP Geographic ("geoip") ACLs require libGeoIP. If you wish to build BIND 9 without support for this feature, skip to step 4. The libGeoIP source code is available from: https://github.com/maxmind/geoip-api-c/releases. As of this writing, the current version of libGeoIP is 1.6.0. There is a known bug in this and all prior versions which prevents it from building a suitable DLL with thread support on Windows. You can apply the patch file bind9/win32utils/GeoIP.diff to address the problem. This patch has been submitted upstream, and will be included in future versions of libGeoIP. Step 4: Download and build Readline The readline library adds command-line editing in nslookup and nsupdate. If you wish to build BIND 9 without support for this feature, skip to step 5. Because the original GNU source for the readline library has no WIN32 support, it will be necessary to download a version of the static readline library source that is ready to be built by Visual Studio. One such version is available at: http://gpsim.sourceforge.net/gpsimWin32/gpsimWin32.html#readline_lib Step 5: Make the redistributable runtime object available Check that the Microsoft redistributable object (vcredist_x86.exe or vcredist_x64.exe) is available to the build. The file may be placed in the directory in which the BIND 9 source was extracted (for instance, if BIND 9 is in \build\bind-9.10.0, the redistributable may be placed in \build\vcredist_x86.exe). Or, the path to the file can be specified via the VCREDIST_PATH environment variable, or via the "with-vcredist=PATH" option to the configuration script (see step 4). If none of these options is used, Configure will attempt to find the redistributable based on clues in the build environment. Step 6: Configuring the BIND build From the command prompt, cd to the win32utils directory under the BIND 9 root: cd bind-9.10.0\win32utils In this directory, you can prepare the Windows build by running: perl Configure win32 For 64 bit: perl Configure x64 This will set up all the files needed for building BIND 9 according to the given options. To see the available options, run: perl Configure help To remove all files generated by Configure, run: perl Configure clean Step 7: Building BIND To build using 'nmake' or older versions of Visual Studio (e.g. VS 2005 or VS 2008), go to the legacy subdirectory: cd legacy and follow the instructions in win32-build.txt. Note: Only 32-bit builds are supported in this mode. To build using the Visual Studio GUI in VS 2010 or VS 2012: open the bind9.sln solution file; this will load the project files for all of the BIND 9 libraries and applications. Select "Build->Batch Build", click "Select All", then click "Build". To build using MSBuild in VS 2010 or VS 2012: call MSBuild on the bind9.sln solution file: msbuild /t:Build /p:Configuration=Release bind9.sln msbuild /t:Build /p:Configuration=Debug bind9.sln Note: This mode does not support building for Windows XP. Step 8: Install Installation is accomplished by running the BINDInstall program. All DLL's are copied to the Program Files area and all applications (including BINDInstall which may be necessary for uninstalling BIND 9) to the bin directory. If BIND 8 has previously been installed on the system it must be uninstalled first by running it's own BINDInstall program. The BIND 9 installer does not yet do this. Note: BINDInstall.exe requires the MFC (Microsoft Foundation Class). This is only distributed with non-free (i.e., not "Express") versions of Visual Studio. The other BIND 9 libraries and applications do not have this dependency. Please report bugs, whether in the process of building the application or in BIND 9 itself, to bind9-bugs@isc.org. bind9-9.10.3.dfsg.P4/win32utils/index.html0000644000470500017500000000511212664710322017410 0ustar lamontlamont Bind9 docs index Bind 9.x documents BIND tools: bind9-9.10.3.dfsg.P4/version0000644000470500017500000000026712664710322015006 0ustar lamontlamont# This file must follow /bin/sh rules. It is imported directly via # configure. # PRODUCT=BIND DESCRIPTION= MAJORVER=9 MINORVER=10 PATCHVER=3 RELEASETYPE=-P RELEASEVER=4 EXTENSIONS= bind9-9.10.3.dfsg.P4/docutil/0002755000470500017500000000000012672612753015046 5ustar lamontlamontbind9-9.10.3.dfsg.P4/docutil/patch-db2latex-nested-param-bug0000644000470500017500000000140612664710322022713 0ustar lamontlamont;; $Id: patch-db2latex-nested-param-bug,v 1.1 2007/02/06 20:58:13 sra Exp $ ;; ;; Latest version of xsltproc doesn't like . --- xsl/lists.mod.xsl.~1~ Sat Jan 31 06:53:50 2004 +++ xsl/lists.mod.xsl Tue Feb 6 15:41:12 2007 @@ -269,10 +269,8 @@ - - - + bind9-9.10.3.dfsg.P4/docutil/patch-db2latex-duplicate-template-bug0000644000470500017500000000577012664710322024126 0ustar lamontlamont;; $Id: patch-db2latex-duplicate-template-bug,v 1.2 2007/01/12 22:24:20 sra Exp $ ;; ;; This is a patch to work around a known bug in db2latex. Apparently ;; xsltproc's error checking got a lot better since the authors of ;; db2latex last tested this, so a clear language violation that ;; xsltproc used to ignore now prevents xsltproc from working with ;; db2latex. ;; ;; On FreeBSD you can simply drop this patch into the directory ;; /usr/ports/textproc/db2latex/files/ and the ports system should ;; take it from there. I've sent this patch off to the port ;; maintainer but have not yet heard anything back. ;; ;; I don't really know whther this is the "right" fix, but it seems to ;; work, and I'm pretty sure that the code this patch deletes does not ;; work as it stands, so at worst the result after applying this patch ;; should be no worse than the result without this patch. ;; ;; YMMV. If this patch breaks, you get to keep both pieces. Index: xsl/qandaset.mod.xsl --- xsl/qandaset.mod.xsl.~1~ Sun Jan 4 08:22:27 2004 +++ xsl/qandaset.mod.xsl Fri Apr 1 22:30:20 2005 @@ -363,53 +363,4 @@ - - - - - - - - - - - - - - - - - - - - - question - answer - qandadiv - qandaset - - - - - - - - - - - - - - - - - - - - - - - - - bind9-9.10.3.dfsg.P4/docutil/patch-db2latex-xsltproc-title-bug0000644000470500017500000000266112664710322023334 0ustar lamontlamont;; $Id: patch-db2latex-xsltproc-title-bug,v 1.2 2007/01/12 22:24:20 sra Exp $ ;; ;; This patches around a problem that I don't completely understand, ;; and which may in fact be an xsltproc bug rather than a db2latex ;; bug. Symptom is that the generated \title{} contains not only the ;; book title but also the concatenation of all the chapter titles. ;; This makes no sense, it doesn't happen with saxon, it doesn't ;; happen with all versions of xsltproc, and attempts to trace this ;; with --verbose and leave me more wondering whether ;; it's me or xsltproc that doesn't understand the XSLT pattern ;; matching rules. ;; ;; All that said, the change below prevents the bad behavior and ;; should be completely harmless, so it will do as a workaround. Index: xsl/book-article.mod.xsl --- xsl/book-article.mod.xsl.~1~ Tue May 3 21:51:18 2005 +++ xsl/book-article.mod.xsl Sat May 7 09:00:26 2005 @@ -87,8 +87,8 @@ \title{ - - + + } \author{ bind9-9.10.3.dfsg.P4/docutil/HTML_COPYRIGHT0000644000470500017500000000152312664710322017154 0ustar lamontlamont bind9-9.10.3.dfsg.P4/docutil/MAN_COPYRIGHT0000644000470500017500000000153612664710322017027 0ustar lamontlamont.\" .\" Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" bind9-9.10.3.dfsg.P4/make/0002755000470500017500000000000012672612753014320 5ustar lamontlamontbind9-9.10.3.dfsg.P4/make/Makefile.in0000644000470500017500000000202112664710322016346 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.16 2007/06/19 23:47:24 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS= TARGETS= @BIND9_MAKE_RULES@ distclean:: rm -f rules mkdep includes bind9-9.10.3.dfsg.P4/make/rules.in0000644000470500017500000002576112664710322016003 0ustar lamontlamont# Copyright (C) 2004-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2003 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. ### ### Common Makefile rules for BIND 9. ### ### ### Paths ### ### Note: paths that vary by Makefile MUST NOT be listed ### here, or they won't get expanded correctly. prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ includedir = @includedir@ libdir = @libdir@ sysconfdir = @sysconfdir@ localstatedir = @localstatedir@ mandir = @mandir@ datarootdir = @datarootdir@ DESTDIR = @SET_MAKE@ top_builddir = @BIND9_TOP_BUILDDIR@ ### ### All ### ### Makefile may define: ### PREREQS ### TARGETS all: ${PREREQS} subdirs ${TARGETS} testdirs ### ### Subdirectories ### ### Makefile may define: ### SUBDIRS ALL_SUBDIRS = ${SUBDIRS} nulldir ALL_TESTDIRS = ${TESTDIRS} nulldir # # We use a single-colon rule so that additional dependencies of # subdirectories can be specified after the inclusion of this file. # The "depend" and "testdirs" targets are treated the same way. # subdirs: @for i in ${ALL_SUBDIRS}; do \ if [ "$$i" != "nulldir" -a -d $$i ]; then \ echo "making all in `pwd`/$$i"; \ (cd $$i; ${MAKE} ${MAKEDEFS} DESTDIR="${DESTDIR}" all) || exit 1; \ fi; \ done # # Tests are built after the targets instead of before # testdirs: @for i in ${ALL_TESTDIRS}; do \ if [ "$$i" != "nulldir" -a -d $$i ]; then \ echo "making all in `pwd`/$$i"; \ (cd $$i; ${MAKE} ${MAKEDEFS} DESTDIR="${DESTDIR}" all) || exit 1; \ fi; \ done install:: all install clean distclean maintainer-clean doc docclean man manclean:: @for i in ${ALL_SUBDIRS} ${ALL_TESTDIRS}; do \ if [ "$$i" != "nulldir" -a -d $$i ]; then \ echo "making $@ in `pwd`/$$i"; \ (cd $$i; ${MAKE} ${MAKEDEFS} DESTDIR="${DESTDIR}" $@) || exit 1; \ fi; \ done ### ### C Programs ### ### Makefile must define ### CC ### Makefile may define ### CFLAGS ### LDFLAGS ### CINCLUDES ### CDEFINES ### CWARNINGS ### User may define externally ### EXT_CFLAGS CC = @CC@ CFLAGS = @CFLAGS@ LDFLAGS = @LDFLAGS@ STD_CINCLUDES = @STD_CINCLUDES@ STD_CDEFINES = @STD_CDEFINES@ STD_CWARNINGS = @STD_CWARNINGS@ BUILD_CC = @BUILD_CC@ BUILD_CFLAGS = @BUILD_CFLAGS@ BUILD_CPPFLAGS = @BUILD_CPPFLAGS@ BUILD_LDFLAGS = @BUILD_LDFLAGS@ BUILD_LIBS = @BUILD_LIBS@ .SUFFIXES: .SUFFIXES: .c .@O@ ALWAYS_INCLUDES = -I${top_builddir} -I${top_srcdir} ALWAYS_DEFINES = @ALWAYS_DEFINES@ ALWAYS_WARNINGS = ALL_CPPFLAGS = \ ${ALWAYS_INCLUDES} ${CINCLUDES} ${STD_CINCLUDES} \ ${ALWAYS_DEFINES} ${CDEFINES} ${STD_CDEFINES} ALL_CFLAGS = ${EXT_CFLAGS} ${ALL_CPPFLAGS} ${CFLAGS} \ ${ALWAYS_WARNINGS} ${STD_CWARNINGS} ${CWARNINGS} @BIND9_CO_RULE@ ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -c $< SHELL = @SHELL@ LIBTOOL = @LIBTOOL@ LIBTOOL_MODE_COMPILE = ${LIBTOOL} @LIBTOOL_MODE_COMPILE@ LIBTOOL_MODE_INSTALL = ${LIBTOOL} @LIBTOOL_MODE_INSTALL@ LIBTOOL_MODE_LINK = ${LIBTOOL} @LIBTOOL_MODE_LINK@ PURIFY = @PURIFY@ MKDEP = ${SHELL} ${top_builddir}/make/mkdep ### ### This is a template compound command to build an executable binary with ### an internal symbol table. ### This process is tricky. We first link all objects including a tentative ### empty symbol table, then get a tentative list of symbols from the resulting ### binary ($@tmp0). Next, we re-link all objects, but this time with the ### symbol table just created ($tmp@1). The set of symbols should be the same, ### but the corresponding addresses would be changed due to the difference on ### the size of symbol tables. So we create the symbol table and re-create the ### objects once again. Finally, we check the symbol table embedded in the ### final binaryis consistent with the binary itself; otherwise the process is ### terminated. ### ### To minimize the overhead of creating symbol tables, the autoconf switch ### --enable-symtable takes an argument so that the symbol table can be created ### on a per application basis: unless the argument is set to "all", the symbol ### table is created only when a shell (environment) variable "MAKE_SYMTABLE" is ### set to a non-null value in the rule to build the executable binary. ### ### Each Makefile.in that uses this macro is expected to define "LIBS" and ### "NOSYMLIBS"; the former includes libisc with an empty symbol table, and ### the latter includes libisc without the definition of a symbol table. ### The rule to make the executable binary will look like this ### binary@EXEEXT@: ${OBJS} ### #export MAKE_SYMTABLE="yes"; \ <- enable if symtable is always needed ### export BASEOBJS="${OBJS}"; \ ### ${FINALBUILDCMD} ### ### Normally, ${LIBS} includes all necessary libraries to build the binary; ### there are some exceptions however, where the rule lists some of the ### necessary libraries explicitly in addition to (or instead of) ${LIBS}, ### like this: ### binary@EXEEXT@: ${OBJS} ### cc -o $@ ${OBJS} ${OTHERLIB1} ${OTHERLIB2} ${lIBS} ### in order to modify such a rule to use this compound command, a separate ### variable "LIBS0" should be deinfed for the explicitly listed libraries, ### while making sure ${LIBS} still includes libisc. So the above rule would ### be modified as follows: ### binary@EXEEXT@: ${OBJS} ### export BASEOBJS="${OBJS}"; \ ### export LIBS0="${OTHERLIB1} ${OTHERLIB2}"; \ ### ${FINALBUILDCMD} ### See bin/check/Makefile.in for a complete example of the use of LIBS0. ### FINALBUILDCMD = if [ X"${MKSYMTBL_PROGRAM}" = X -o X"$${MAKE_SYMTABLE:-${ALWAYS_MAKE_SYMTABLE}}" = X ] ; then \ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} \ -o $@ $${BASEOBJS} $${LIBS0} ${LIBS}; \ else \ rm -f $@tmp0; \ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} \ -o $@tmp0 $${BASEOBJS} $${LIBS0} ${LIBS} || exit 1; \ rm -f $@-symtbl.c $@-symtbl.@O@; \ ${MKSYMTBL_PROGRAM} ${top_srcdir}/util/mksymtbl.pl \ -o $@-symtbl.c $@tmp0 || exit 1; \ $(MAKE) $@-symtbl.@O@ || exit 1; \ rm -f $@tmp1; \ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} \ -o $@tmp1 $${BASEOBJS} $@-symtbl.@O@ $${LIBS0} ${NOSYMLIBS} || exit 1; \ rm -f $@-symtbl.c $@-symtbl.@O@; \ ${MKSYMTBL_PROGRAM} ${top_srcdir}/util/mksymtbl.pl \ -o $@-symtbl.c $@tmp1 || exit 1; \ $(MAKE) $@-symtbl.@O@ || exit 1; \ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} \ -o $@tmp2 $${BASEOBJS} $@-symtbl.@O@ $${LIBS0} ${NOSYMLIBS}; \ ${MKSYMTBL_PROGRAM} ${top_srcdir}/util/mksymtbl.pl \ -o $@-symtbl2.c $@tmp2; \ count=0; \ until diff $@-symtbl.c $@-symtbl2.c > /dev/null ; \ do \ count=`expr $$count + 1` ; \ test $$count = 42 && exit 1 ; \ rm -f $@-symtbl.c $@-symtbl.@O@; \ ${MKSYMTBL_PROGRAM} ${top_srcdir}/util/mksymtbl.pl \ -o $@-symtbl.c $@tmp2 || exit 1; \ $(MAKE) $@-symtbl.@O@ || exit 1; \ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} \ ${LDFLAGS} -o $@tmp2 $${BASEOBJS} $@-symtbl.@O@ \ $${LIBS0} ${NOSYMLIBS}; \ ${MKSYMTBL_PROGRAM} ${top_srcdir}/util/mksymtbl.pl \ -o $@-symtbl2.c $@tmp2; \ done ; \ mv $@tmp2 $@; \ rm -f $@tmp0 $@tmp1 $@tmp2 $@-symtbl2.c; \ fi cleandir: distclean superclean: maintainer-clean clean distclean maintainer-clean:: rm -f *.@O@ *.o *.lo *.la core *.core *-symtbl.c *tmp0 *tmp1 *tmp2 rm -rf .depend .libs distclean maintainer-clean:: rm -f Makefile depend: @for i in ${ALL_SUBDIRS}; do \ if [ "$$i" != "nulldir" -a -d $$i ]; then \ echo "making depend in `pwd`/$$i"; \ (cd $$i; ${MAKE} ${MAKEDEFS} DESTDIR="${DESTDIR}" $@) || exit 1; \ fi; \ done @if [ X"${srcdir}" != X. ] ; then \ if [ X"${SRCS}" != X -a X"${PSRCS}" != X ] ; then \ echo ${MKDEP} -vpath ${srcdir} ${ALL_CPPFLAGS} ${ALL_CFLAGS} ${SRCS}; \ ${MKDEP} -vpath ${srcdir} ${ALL_CPPFLAGS} ${ALL_CFLAGS} ${SRCS}; \ echo ${MKDEP} -vpath ${srcdir} -ap ${ALL_CPPFLAGS} ${ALL_CFLAGS} ${PSRCS}; \ ${MKDEP} -vpath ${srcdir} -ap ${ALL_CPPFLAGS} ${ALL_CFLAGS} ${PSRCS}; \ ${DEPENDEXTRA} \ elif [ X"${SRCS}" != X ] ; then \ echo ${MKDEP} -vpath ${srcdir} ${ALL_CPPFLAGS} ${ALL_CFLAGS} ${SRCS}; \ ${MKDEP} -vpath ${srcdir} ${ALL_CPPFLAGS} ${ALL_CFLAGS} ${SRCS}; \ ${DEPENDEXTRA} \ elif [ X"${PSRCS}" != X ] ; then \ echo ${MKDEP} -vpath ${srcdir} ${ALL_CPPFLAGS} ${ALL_CFLAGS} ${PSRCS}; \ ${MKDEP} -vpath ${srcdir} -p ${ALL_CPPFLAGS} ${ALL_CFLAGS} ${PSRCS}; \ ${DEPENDEXTRA} \ fi \ else \ if [ X"${SRCS}" != X -a X"${PSRCS}" != X ] ; then \ echo ${MKDEP} ${ALL_CPPFLAGS} ${ALL_CFLAGS} ${SRCS}; \ ${MKDEP} ${ALL_CPPFLAGS} ${ALL_CFLAGS} ${SRCS}; \ echo ${MKDEP} -ap ${ALL_CPPFLAGS} ${ALL_CFLAGS} ${PSRCS}; \ ${MKDEP} -ap ${ALL_CPPFLAGS} ${ALL_CFLAGS} ${PSRCS}; \ ${DEPENDEXTRA} \ elif [ X"${SRCS}" != X ] ; then \ echo ${MKDEP} ${ALL_CPPFLAGS} ${ALL_CFLAGS} ${SRCS}; \ ${MKDEP} ${ALL_CPPFLAGS} ${ALL_CFLAGS} ${SRCS}; \ ${DEPENDEXTRA} \ elif [ X"${PSRCS}" != X ] ; then \ echo ${MKDEP} ${ALL_CPPFLAGS} ${ALL_CFLAGS} ${PSRCS}; \ ${MKDEP} -p ${ALL_CPPFLAGS} ${ALL_CFLAGS} ${PSRCS}; \ ${DEPENDEXTRA} \ fi \ fi FORCE: ### ### Libraries ### AR = @AR@ ARFLAGS = @ARFLAGS@ RANLIB = @RANLIB@ ### ### Installation ### INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ LINK_PROGRAM = @LN_S@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_LIBRARY = @INSTALL_LIBRARY@ ### ### Programs used when generating documentation. It's ok for these ### not to exist when not generating documentation. ### XSLTPROC = @XSLTPROC@ --novalid --xinclude --nonet PERL = @PERL@ LATEX = @LATEX@ PDFLATEX = @PDFLATEX@ W3M = @W3M@ ### ### Script language program used to create internal symbol tables ### MKSYMTBL_PROGRAM = @MKSYMTBL_PROGRAM@ ### ### Switch to create internal symbol table selectively ### ALWAYS_MAKE_SYMTABLE = @ALWAYS_MAKE_SYMTABLE@ ### ### DocBook -> HTML ### DocBook -> man page ### .SUFFIXES: .docbook .html .1 .2 .3 .4 .5 .6 .7 .8 .docbook.html: ${XSLTPROC} -o $@ ${top_srcdir}/doc/xsl/isc-docbook-html.xsl $< .docbook.1: ${XSLTPROC} -o $@ ${top_srcdir}/doc/xsl/isc-manpage.xsl $< .docbook.2: ${XSLTPROC} -o $@ ${top_srcdir}/doc/xsl/isc-manpage.xsl $< .docbook.3: ${XSLTPROC} -o $@ ${top_srcdir}/doc/xsl/isc-manpage.xsl $< .docbook.4: ${XSLTPROC} -o $@ ${top_srcdir}/doc/xsl/isc-manpage.xsl $< .docbook.5: ${XSLTPROC} -o $@ ${top_srcdir}/doc/xsl/isc-manpage.xsl $< .docbook.6: ${XSLTPROC} -o $@ ${top_srcdir}/doc/xsl/isc-manpage.xsl $< .docbook.7: ${XSLTPROC} -o $@ ${top_srcdir}/doc/xsl/isc-manpage.xsl $< .docbook.8: ${XSLTPROC} -o $@ ${top_srcdir}/doc/xsl/isc-manpage.xsl $< bind9-9.10.3.dfsg.P4/make/includes.in0000644000470500017500000000373112664710322016450 0ustar lamontlamont# Copyright (C) 2004, 2005, 2007, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1999-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: includes.in,v 1.21 2007/06/19 23:47:24 tbox Exp $ # Search for machine-generated header files in the build tree, # and for normal headers in the source tree (${top_srcdir}). # We only need to look in OS-specific subdirectories for the # latter case, because there are no machine-generated OS-specific # headers. ISC_INCLUDES = @BIND9_ISC_BUILDINCLUDE@ \ -I${top_srcdir}/lib/isc \ -I${top_srcdir}/lib/isc/include \ -I${top_srcdir}/lib/isc/unix/include \ -I${top_srcdir}/lib/isc/@ISC_THREAD_DIR@/include \ -I${top_srcdir}/lib/isc/@ISC_ARCH_DIR@/include ISCCC_INCLUDES = @BIND9_ISCCC_BUILDINCLUDE@ \ -I${top_srcdir}/lib/isccc/include ISCCFG_INCLUDES = @BIND9_ISCCFG_BUILDINCLUDE@ \ -I${top_srcdir}/lib/isccfg/include DNS_INCLUDES = @BIND9_DNS_BUILDINCLUDE@ \ -I${top_srcdir}/lib/dns/include IRS_INCLUDES = @BIND9_IRS_BUILDINCLUDE@ \ -I${top_srcdir}/lib/irs/include LWRES_INCLUDES = @BIND9_LWRES_BUILDINCLUDE@ \ -I${top_srcdir}/lib/lwres/unix/include \ -I${top_srcdir}/lib/lwres/include BIND9_INCLUDES = @BIND9_BIND9_BUILDINCLUDE@ \ -I${top_srcdir}/lib/bind9/include TEST_INCLUDES = \ -I${top_srcdir}/lib/tests/include bind9-9.10.3.dfsg.P4/make/mkdep.in0000644000470500017500000001216712664710322015745 0ustar lamontlamont#!/bin/sh - ## ## Modified to handle -vpath option by Michael Graff, ISC. ## The purpose of this is to allow this script to run outside of the ## source directory, for instance when running configure with ## ../bind9-mainline/configure ## and still have "make depend" work. ## ## ++Copyright++ 1987 ## - ## Copyright (c) 1987 Regents of the University of California. ## 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. Neither the name of the University 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 REGENTS 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. ## - ## Portions Copyright (c) 1993 by Digital Equipment Corporation. ## ## Permission to use, copy, modify, and distribute this software for any ## purpose with or without fee is hereby granted, provided that the above ## copyright notice and this permission notice appear in all copies, and that ## the name of Digital Equipment Corporation not be used in advertising or ## publicity pertaining to distribution of the document or software without ## specific, written prior permission. ## ## THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL ## WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES ## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT ## CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL ## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR ## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ## SOFTWARE. ## - ## --Copyright-- # # @(#)mkdep.sh 5.12 (Berkeley) 6/30/88 # MAKE=Makefile # default makefile name is "Makefile" while : do case "$1" in # -vpath allows one to select a virtual path for .c files -vpath) VPATH=$2; shift; shift ;; # -f allows you to select a makefile name -f) MAKE=$2 shift; shift ;; # the -p flag produces "program: program.c" style dependencies # so .o's don't get produced -p) SED='s;\.o;;' shift ;; *) break ;; esac done if [ $# = 0 ] ; then echo 'usage: mkdep [-vpath path] [-p] [-f makefile] [flags] file ...' exit 1 fi if [ ! -w $MAKE ]; then echo "mkdep: no writeable file \"$MAKE\"" exit 1 fi TMP=mkdep$$ trap 'rm -f $TMP ; exit 1' 1 2 3 13 15 cp $MAKE ${MAKE}.bak sed -e '/DO NOT DELETE THIS LINE/,$d' < $MAKE > $TMP cat << _EOF_ >> $TMP # DO NOT DELETE THIS LINE -- mkdep uses it. # DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. _EOF_ # If your compiler doesn't have -M, add it. If you can't, the next two # lines will try and replace the "cc -M". The real problem is that this # hack can't deal with anything that requires a search path, and doesn't # even try for anything using bracket (<>) syntax. # # egrep '^#include[ ]*".*"' /dev/null $* | # sed -e 's/:[^"]*"\([^"]*\)".*/: \1/' -e 's/\.c/.o/' | if [ X"${VPATH}" != X ] ; then for arg in $* ; do case "$arg" in -*) newargs="$newargs $arg" ;; *) newargs="$newargs $VPATH/$arg" ;; esac done else newargs="$*"; fi MKDEPPROG="@MKDEPPROG@" if [ X"${MKDEPPROG}" != X ]; then @SHELL@ -c "${MKDEPPROG} ${newargs}" else @MKDEPCC@ @MKDEPCFLAGS@ ${newargs} | sed " s; \\./; ;g s; \\\\; ;g @LIBTOOL_MKDEP_SED@ $SED" | awk '$1 ~ /:$/ { if (rec != "") print rec; if (NF == 1) rec = $1; else rec = $1 " " $2; for (i = 3; i <= NF; i++) { if (length(rec $i) > 76) { print rec " \\"; rec = " " $i; } else { rec = rec " " $i; } } next; } { for (i = 1; i <= NF; i++) { if (length(rec $i) > 76) { print rec, "\\"; rec = " " $i; } else { rec = rec " " $i; } } } END { print rec }' >> $TMP fi cat << _EOF_ >> $TMP # IF YOU PUT ANYTHING HERE IT WILL GO AWAY _EOF_ # copy to preserve permissions cp $TMP $MAKE rm -f ${MAKE}.bak $TMP exit 0 bind9-9.10.3.dfsg.P4/lib/0002755000470500017500000000000012672612753014151 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/samples/0002755000470500017500000000000012672612753015615 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/samples/sample-gai.c0000644000470500017500000000426512664710322017775 0ustar lamontlamont/* * Copyright (C) 2009, 2012-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: sample-gai.c,v 1.4 2009/09/02 23:48:02 tbox Exp $ */ #include #include #include #include #include #include #include static void do_gai(int family, char *hostname) { struct addrinfo hints, *res, *res0; int error; char namebuf[1024], addrbuf[1024], servbuf[1024]; memset(&hints, 0, sizeof(hints)); hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_CANONNAME; error = getaddrinfo(hostname, "http", &hints, &res0); if (error) { fprintf(stderr, "getaddrinfo failed for %s,family=%d: %s\n", hostname, family, gai_strerror(error)); return; } for (res = res0; res; res = res->ai_next) { error = getnameinfo(res->ai_addr, (socklen_t)res->ai_addrlen, addrbuf, sizeof(addrbuf), NULL, 0, NI_NUMERICHOST); if (error == 0) error = getnameinfo(res->ai_addr, (socklen_t)res->ai_addrlen, namebuf, sizeof(namebuf), servbuf, sizeof(servbuf), 0); if (error != 0) { fprintf(stderr, "getnameinfo failed: %s\n", gai_strerror(error)); } else { printf("%s(%s/%s)=%s:%s\n", hostname, res->ai_canonname, addrbuf, namebuf, servbuf); } } freeaddrinfo(res0); } int main(int argc, char *argv[]) { if (argc < 2) exit(1); do_gai(AF_INET, argv[1]); do_gai(AF_INET6, argv[1]); do_gai(AF_UNSPEC, argv[1]); return (0); } bind9-9.10.3.dfsg.P4/lib/samples/sample-request.c0000644000470500017500000001541212664710322020721 0ustar lamontlamont/* * Copyright (C) 2009, 2012-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: sample-request.c,v 1.5 2009/09/29 15:06:07 fdupont Exp $ */ #include #ifndef WIN32 #include #include #include #include #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static isc_mem_t *mctx; static dns_fixedname_t fixedqname; ISC_PLATFORM_NORETURN_PRE static void usage(void) ISC_PLATFORM_NORETURN_POST; static void usage(void) { fprintf(stderr, "sample-request [-t RRtype] server_address hostname\n"); exit(1); } static isc_result_t make_querymessage(dns_message_t *message, const char *namestr, dns_rdatatype_t rdtype) { dns_name_t *qname = NULL, *qname0; dns_rdataset_t *qrdataset = NULL; isc_result_t result; isc_buffer_t b; unsigned int namelen; REQUIRE(message != NULL); REQUIRE(namestr != NULL); /* Construct qname */ namelen = strlen(namestr); isc_buffer_constinit(&b, namestr, namelen); isc_buffer_add(&b, namelen); dns_fixedname_init(&fixedqname); qname0 = dns_fixedname_name(&fixedqname); result = dns_name_fromtext(qname0, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to convert qname: %d\n", result); return (result); } /* Construct query message */ message->opcode = dns_opcode_query; message->rdclass = dns_rdataclass_in; result = dns_message_gettempname(message, &qname); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_message_gettemprdataset(message, &qrdataset); if (result != ISC_R_SUCCESS) goto cleanup; dns_name_init(qname, NULL); dns_name_clone(qname0, qname); dns_rdataset_makequestion(qrdataset, message->rdclass, rdtype); ISC_LIST_APPEND(qname->list, qrdataset, link); dns_message_addname(message, qname, DNS_SECTION_QUESTION); return (ISC_R_SUCCESS); cleanup: if (qname != NULL) dns_message_puttempname(message, &qname); if (qrdataset != NULL) dns_message_puttemprdataset(message, &qrdataset); dns_message_destroy(&message); return (result); } static void print_section(dns_message_t *message, int section, isc_buffer_t *buf) { isc_result_t result; isc_region_t r; result = dns_message_sectiontotext(message, section, &dns_master_style_full, 0, buf); if (result != ISC_R_SUCCESS) goto fail; isc_buffer_usedregion(buf, &r); printf("%.*s", (int)r.length, (char *)r.base); return; fail: fprintf(stderr, "failed to convert a section\n"); } int main(int argc, char *argv[]) { int ch, i, gai_error; struct addrinfo hints, *res; isc_textregion_t tr; dns_client_t *client = NULL; isc_result_t result; isc_sockaddr_t sa; dns_message_t *qmessage, *rmessage; dns_rdatatype_t type = dns_rdatatype_a; isc_buffer_t *outputbuf; while ((ch = isc_commandline_parse(argc, argv, "t:")) != -1) { switch (ch) { case 't': tr.base = isc_commandline_argument; tr.length = strlen(isc_commandline_argument); result = dns_rdatatype_fromtext(&type, &tr); if (result != ISC_R_SUCCESS) { fprintf(stderr, "invalid RRtype: %s\n", isc_commandline_argument); exit(1); } break; default: usage(); } } argc -= isc_commandline_index; argv += isc_commandline_index; if (argc < 2) usage(); isc_lib_register(); result = dns_lib_init(); if (result != ISC_R_SUCCESS) { fprintf(stderr, "dns_lib_init failed: %d\n", result); exit(1); } result = dns_client_create(&client, 0); if (result != ISC_R_SUCCESS) { fprintf(stderr, "dns_client_create failed: %d\n", result); exit(1); } /* Prepare message structures */ mctx = NULL; qmessage = NULL; rmessage = NULL; result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to create a memory context\n"); exit(1); } result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &qmessage); if (result == ISC_R_SUCCESS) { result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &rmessage); } if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to create messages\n"); exit(1); } /* Initialize the nameserver address */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; #ifdef AI_NUMERICHOST hints.ai_flags = AI_NUMERICHOST; #endif gai_error = getaddrinfo(argv[0], "53", &hints, &res); if (gai_error != 0) { fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(gai_error)); exit(1); } INSIST(res->ai_addrlen <= sizeof(sa.type)); memmove(&sa.type, res->ai_addr, res->ai_addrlen); freeaddrinfo(res); sa.length = (unsigned int)res->ai_addrlen; ISC_LINK_INIT(&sa, link); /* Construct qname */ result = make_querymessage(qmessage, argv[1], type); if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to create a query\n"); exit(1); } /* Send request and wait for a response */ result = dns_client_request(client, qmessage, rmessage, &sa, 0, 0, NULL, 60, 0, 3); if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to get a response: %s\n", dns_result_totext(result)); } /* Dump the response */ outputbuf = NULL; result = isc_buffer_allocate(mctx, &outputbuf, 65535); if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to allocate a result buffer\n"); exit(1); } for (i = 0; i < DNS_SECTION_MAX; i++) { print_section(rmessage, i, outputbuf); isc_buffer_clear(outputbuf); } isc_buffer_free(&outputbuf); /* Cleanup */ dns_message_destroy(&qmessage); dns_message_destroy(&rmessage); isc_mem_destroy(&mctx); dns_client_destroy(&client); dns_lib_shutdown(); return (0); } bind9-9.10.3.dfsg.P4/lib/samples/Makefile.in0000644000470500017500000000564312664710322017660 0ustar lamontlamont# Copyright (C) 2009, 2012-2014 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ @BIND9_MAKE_INCLUDES@ CINCLUDES = -I${srcdir}/include -I../dns/include \ ${DNS_INCLUDES} ${ISC_INCLUDES} \ -I${top_srcdir}/lib/irs/include \ -I../../lib/irs/include CDEFINES = -DVERSION=\"${VERSION}\" -DSYSCONFDIR=\"${sysconfdir}\" CWARNINGS = ISCLIBS = ../isc/libisc.@A@ DNSLIBS = ../dns/libdns.@A@ @DNS_CRYPTO_LIBS@ ISCCFGLIBS = ../isccfg/libisccfg.@A@ IRSLIBS = ../irs/libirs.@A@ ISCDEPLIBS = ../isc/libisc.@A@ DNSDEPLIBS = ../dns/libdns.@A@ ISCCFGDEPLIBS = ../isccfg/libisccfg.@A@ IRSDEPLIBS = ../irs/libirs.@A@ DEPLIBS = ${DNSDEPLIBS} ${ISCCFGDEPLIBS} ${ISCDEPLIBS} LIBS = ${DNSLIBS} ${ISCCFGLIBS} ${ISCLIBS} @LIBS@ SUBDIRS = TARGETS = resolve@EXEEXT@ \ sample-async@EXEEXT@ sample-gai@EXEEXT@ \ sample-update@EXEEXT@ sample-request@EXEEXT@ nsprobe@EXEEXT@ OBJS = resolve.@O@ \ sample-async.@O@ sample-gai.@O@ sample-update.@O@ \ sample-request.@O@ nsprobe.@O@ UOBJS = SRCS = resolve.c \ sample-async.c sample-gai.c sample-update.c \ sample-request.c nsprobe.c MANPAGES = HTMLPAGES = MANOBJS = ${MANPAGES} ${HTMLPAGES} @BIND9_MAKE_RULES@ resolve@EXEEXT@: resolve.@O@ ${IRSDEPLIBS} ${DEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ resolve.@O@ ${IRSLIBS} ${LIBS} sample-async@EXEEXT@: sample-async.@O@ ${DEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ sample-async.@O@ ${LIBS} sample-gai@EXEEXT@: sample-gai.@O@ ${IRSDEPLIBS} ${DEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ sample-gai.@O@ ${IRSLIBS} ${LIBS} sample-update@EXEEXT@: sample-update.@O@ ${DEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ sample-update.@O@ ${LIBS} sample-request@EXEEXT@: sample-request.@O@ ${DEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ sample-request.@O@ ${LIBS} nsprobe@EXEEXT@: nsprobe.@O@ ${DEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ nsprobe.@O@ ${LIBS} doc man:: ${MANOBJS} docclean manclean maintainer-clean:: rm -f ${MANOBJS} clean distclean maintainer-clean:: rm -f ${TARGETS} rm -f sample.key bind9-9.10.3.dfsg.P4/lib/samples/resolve.c0000644000470500017500000003105212664710322017427 0ustar lamontlamont/* * Copyright (C) 2009, 2012-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #ifndef WIN32 #include #include #include #include #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static char *algname; static isc_result_t printdata(dns_rdataset_t *rdataset, dns_name_t *owner) { isc_buffer_t target; isc_result_t result; isc_region_t r; char t[4096]; if (!dns_rdataset_isassociated(rdataset)) { printf("[WARN: empty]\n"); return (ISC_R_SUCCESS); } isc_buffer_init(&target, t, sizeof(t)); result = dns_rdataset_totext(rdataset, owner, ISC_FALSE, ISC_FALSE, &target); if (result != ISC_R_SUCCESS) return (result); isc_buffer_usedregion(&target, &r); printf("%.*s", (int)r.length, (char *)r.base); return (ISC_R_SUCCESS); } ISC_PLATFORM_NORETURN_PRE static void usage(void) ISC_PLATFORM_NORETURN_POST; static void usage(void) { fprintf(stderr, "resolve [-t RRtype] " "[[-a algorithm] [-e] -k keyname -K keystring] " "[-S domain:serveraddr_for_domain ] [-s server_address]" "[-b address[#port]] hostname\n"); exit(1); } static void set_key(dns_client_t *client, char *keynamestr, char *keystr, isc_boolean_t is_sep, isc_mem_t **mctxp) { isc_result_t result; dns_fixedname_t fkeyname; unsigned int namelen; dns_name_t *keyname; dns_rdata_dnskey_t keystruct; unsigned char keydata[4096]; isc_buffer_t keydatabuf; unsigned char rrdata[4096]; isc_buffer_t rrdatabuf; isc_buffer_t b; isc_textregion_t tr; isc_region_t r; dns_secalg_t alg; result = isc_mem_create(0, 0, mctxp); if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to create mctx\n"); exit(1); } if (algname != NULL) { tr.base = algname; tr.length = strlen(algname); result = dns_secalg_fromtext(&alg, &tr); if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to identify the algorithm\n"); exit(1); } } else alg = DNS_KEYALG_RSASHA1; keystruct.common.rdclass = dns_rdataclass_in; keystruct.common.rdtype = dns_rdatatype_dnskey; keystruct.flags = DNS_KEYOWNER_ZONE; /* fixed */ if (is_sep) keystruct.flags |= DNS_KEYFLAG_KSK; keystruct.protocol = DNS_KEYPROTO_DNSSEC; /* fixed */ keystruct.algorithm = alg; isc_buffer_init(&keydatabuf, keydata, sizeof(keydata)); isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata)); result = isc_base64_decodestring(keystr, &keydatabuf); if (result != ISC_R_SUCCESS) { fprintf(stderr, "base64 decode failed\n"); exit(1); } isc_buffer_usedregion(&keydatabuf, &r); keystruct.datalen = r.length; keystruct.data = r.base; result = dns_rdata_fromstruct(NULL, keystruct.common.rdclass, keystruct.common.rdtype, &keystruct, &rrdatabuf); if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to construct key rdata\n"); exit(1); } namelen = strlen(keynamestr); isc_buffer_init(&b, keynamestr, namelen); isc_buffer_add(&b, namelen); dns_fixedname_init(&fkeyname); keyname = dns_fixedname_name(&fkeyname); result = dns_name_fromtext(keyname, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to construct key name\n"); exit(1); } result = dns_client_addtrustedkey(client, dns_rdataclass_in, keyname, &rrdatabuf); if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to add key for %s\n", keynamestr); exit(1); } } static void addserver(dns_client_t *client, const char *addrstr, const char *port, const char *namespace) { struct addrinfo hints, *res; int gai_error; isc_sockaddr_t sa; isc_sockaddrlist_t servers; isc_result_t result; unsigned int namelen; isc_buffer_t b; dns_fixedname_t fname; dns_name_t *name = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; hints.ai_flags = AI_NUMERICHOST; gai_error = getaddrinfo(addrstr, port, &hints, &res); if (gai_error != 0) { fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(gai_error)); exit(1); } INSIST(res->ai_addrlen <= sizeof(sa.type)); memmove(&sa.type, res->ai_addr, res->ai_addrlen); sa.length = (unsigned int)res->ai_addrlen; freeaddrinfo(res); ISC_LINK_INIT(&sa, link); ISC_LIST_INIT(servers); ISC_LIST_APPEND(servers, &sa, link); if (namespace != NULL) { namelen = strlen(namespace); isc_buffer_constinit(&b, namespace, namelen); isc_buffer_add(&b, namelen); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to convert qname: %d\n", result); exit(1); } } result = dns_client_setservers(client, dns_rdataclass_in, name, &servers); if (result != ISC_R_SUCCESS) { fprintf(stderr, "set server failed: %d\n", result); exit(1); } } int main(int argc, char *argv[]) { int ch; isc_textregion_t tr; char *server = NULL; char *altserver = NULL; char *altserveraddr = NULL; char *altservername = NULL; dns_client_t *client = NULL; char *keynamestr = NULL; char *keystr = NULL; isc_result_t result; isc_buffer_t b; dns_fixedname_t qname0; unsigned int namelen; dns_name_t *qname, *name; dns_rdatatype_t type = dns_rdatatype_a; dns_rdataset_t *rdataset; dns_namelist_t namelist; isc_mem_t *keymctx = NULL; unsigned int clientopt, resopt; isc_boolean_t is_sep = ISC_FALSE; const char *port = "53"; isc_mem_t *mctx = NULL; isc_appctx_t *actx = NULL; isc_taskmgr_t *taskmgr = NULL; isc_socketmgr_t *socketmgr = NULL; isc_timermgr_t *timermgr = NULL; struct in_addr in4; struct in6_addr in6; isc_sockaddr_t a4, a6; isc_sockaddr_t *addr4 = NULL, *addr6 = NULL; while ((ch = isc_commandline_parse(argc, argv, "a:b:es:t:k:K:p:S:")) != -1) { switch (ch) { case 't': tr.base = isc_commandline_argument; tr.length = strlen(isc_commandline_argument); result = dns_rdatatype_fromtext(&type, &tr); if (result != ISC_R_SUCCESS) { fprintf(stderr, "invalid RRtype: %s\n", isc_commandline_argument); exit(1); } break; case 'a': algname = isc_commandline_argument; break; case 'b': if (inet_pton(AF_INET, isc_commandline_argument, &in4) == 1) { if (addr4 != NULL) { fprintf(stderr, "only one local " "address per family " "can be specified\n"); exit(1); } isc_sockaddr_fromin(&a4, &in4, 0); addr4 = &a4; } else if (inet_pton(AF_INET6, isc_commandline_argument, &in6) == 1) { if (addr6 != NULL) { fprintf(stderr, "only one local " "address per family " "can be specified\n"); exit(1); } isc_sockaddr_fromin6(&a6, &in6, 0); addr6 = &a6; } else { fprintf(stderr, "invalid address %s\n", isc_commandline_argument); exit(1); } break; case 'e': is_sep = ISC_TRUE; break; case 'S': if (altserver != NULL) { fprintf(stderr, "alternate server " "already defined: %s\n", altserver); exit(1); } altserver = isc_commandline_argument; break; case 's': if (server != NULL) { fprintf(stderr, "server " "already defined: %s\n", server); exit(1); } server = isc_commandline_argument; break; case 'k': keynamestr = isc_commandline_argument; break; case 'K': keystr = isc_commandline_argument; break; case 'p': port = isc_commandline_argument; break; default: usage(); } } argc -= isc_commandline_index; argv += isc_commandline_index; if (argc < 1) usage(); if (altserver != NULL) { char *cp; cp = strchr(altserver, ':'); if (cp == NULL) { fprintf(stderr, "invalid alternate server: %s\n", altserver); exit(1); } *cp = '\0'; altservername = altserver; altserveraddr = cp + 1; } isc_lib_register(); result = dns_lib_init(); if (result != ISC_R_SUCCESS) { fprintf(stderr, "dns_lib_init failed: %d\n", result); exit(1); } result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to crate mctx\n"); exit(1); } result = isc_appctx_create(mctx, &actx); if (result != ISC_R_SUCCESS) goto cleanup; result = isc_app_ctxstart(actx); if (result != ISC_R_SUCCESS) goto cleanup; result = isc_taskmgr_createinctx(mctx, actx, 1, 0, &taskmgr); if (result != ISC_R_SUCCESS) goto cleanup; result = isc_socketmgr_createinctx(mctx, actx, &socketmgr); if (result != ISC_R_SUCCESS) goto cleanup; result = isc_timermgr_createinctx(mctx, actx, &timermgr); if (result != ISC_R_SUCCESS) goto cleanup; clientopt = 0; result = dns_client_createx2(mctx, actx, taskmgr, socketmgr, timermgr, clientopt, &client, addr4, addr6); if (result != ISC_R_SUCCESS) { fprintf(stderr, "dns_client_create failed: %d, %s\n", result, isc_result_totext(result)); exit(1); } /* Set the nameserver */ if (server == NULL) { irs_resconf_t *resconf = NULL; isc_sockaddrlist_t *nameservers; result = irs_resconf_load(mctx, "/etc/resolv.conf", &resconf); if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) { fprintf(stderr, "irs_resconf_load failed: %d\n", result); exit(1); } nameservers = irs_resconf_getnameservers(resconf); result = dns_client_setservers(client, dns_rdataclass_in, NULL, nameservers); if (result != ISC_R_SUCCESS) { irs_resconf_destroy(&resconf); fprintf(stderr, "dns_client_setservers failed: %d\n", result); exit(1); } irs_resconf_destroy(&resconf); } else { addserver(client, server, port, NULL); } /* Set the alternate nameserver (when specified) */ if (altserver != NULL) addserver(client, altserveraddr, port, altservername); /* Install DNSSEC key (if given) */ if (keynamestr != NULL) { if (keystr == NULL) { fprintf(stderr, "key string is missing " "while key name is provided\n"); exit(1); } set_key(client, keynamestr, keystr, is_sep, &keymctx); } /* Construct qname */ namelen = strlen(argv[0]); isc_buffer_init(&b, argv[0], namelen); isc_buffer_add(&b, namelen); dns_fixedname_init(&qname0); qname = dns_fixedname_name(&qname0); result = dns_name_fromtext(qname, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) fprintf(stderr, "failed to convert qname: %d\n", result); /* Perform resolution */ resopt = DNS_CLIENTRESOPT_ALLOWRUN; if (keynamestr == NULL) resopt |= DNS_CLIENTRESOPT_NODNSSEC; ISC_LIST_INIT(namelist); result = dns_client_resolve(client, qname, dns_rdataclass_in, type, resopt, &namelist); if (result != ISC_R_SUCCESS) { fprintf(stderr, "resolution failed: %s\n", dns_result_totext(result)); } for (name = ISC_LIST_HEAD(namelist); name != NULL; name = ISC_LIST_NEXT(name, link)) { for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (printdata(rdataset, name) != ISC_R_SUCCESS) fprintf(stderr, "print data failed\n"); } } dns_client_freeresanswer(client, &namelist); /* Cleanup */ cleanup: dns_client_destroy(&client); if (taskmgr != NULL) isc_taskmgr_destroy(&taskmgr); if (timermgr != NULL) isc_timermgr_destroy(&timermgr); if (socketmgr != NULL) isc_socketmgr_destroy(&socketmgr); if (actx != NULL) isc_appctx_destroy(&actx); isc_mem_detach(&mctx); if (keynamestr != NULL) isc_mem_destroy(&keymctx); dns_lib_shutdown(); return (0); } bind9-9.10.3.dfsg.P4/lib/samples/rootkey.sh0000644000470500017500000000252712664710322017641 0ustar lamontlamont#!/bin/sh # # Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # Fetch a copy of a current root signing key; used for testing # DNSSEC validation in 'sample'. # # After running this script, "sample `cat sample.key` " will # perform a lookup as specified in and validate the result # using the root key. # # (This is NOT a secure method of obtaining the root key; it is # included here for testing purposes only.) dig +noall +answer dnskey . | perl -n -e ' local ($dn, $ttl, $class, $type, $flags, $proto, $alg, @rest) = split; next if ($flags != 257); local $key = join("", @rest); print "-a $alg -e -k $dn -K $key\n" ' > sample.key bind9-9.10.3.dfsg.P4/lib/samples/sample-async.c0000644000470500017500000002345112664710322020350 0ustar lamontlamont/* * Copyright (C) 2009, 2013-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: sample-async.c,v 1.5 2009/09/29 15:06:07 fdupont Exp $ */ #include #ifndef WIN32 #include #include #include #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_SERVERS 10 #define MAX_QUERIES 100 static dns_client_t *client = NULL; static isc_task_t *query_task = NULL; static isc_appctx_t *query_actx = NULL; static unsigned int outstanding_queries = 0; static const char *def_server = "127.0.0.1"; static FILE *fp; struct query_trans { int id; isc_boolean_t inuse; dns_rdatatype_t type; dns_fixedname_t fixedname; dns_name_t *qname; dns_namelist_t answerlist; dns_clientrestrans_t *xid; }; static struct query_trans query_array[MAX_QUERIES]; static isc_result_t dispatch_query(struct query_trans *trans); static void ctxs_destroy(isc_mem_t **mctxp, isc_appctx_t **actxp, isc_taskmgr_t **taskmgrp, isc_socketmgr_t **socketmgrp, isc_timermgr_t **timermgrp) { if (*taskmgrp != NULL) isc_taskmgr_destroy(taskmgrp); if (*timermgrp != NULL) isc_timermgr_destroy(timermgrp); if (*socketmgrp != NULL) isc_socketmgr_destroy(socketmgrp); if (*actxp != NULL) isc_appctx_destroy(actxp); if (*mctxp != NULL) isc_mem_destroy(mctxp); } static isc_result_t ctxs_init(isc_mem_t **mctxp, isc_appctx_t **actxp, isc_taskmgr_t **taskmgrp, isc_socketmgr_t **socketmgrp, isc_timermgr_t **timermgrp) { isc_result_t result; result = isc_mem_create(0, 0, mctxp); if (result != ISC_R_SUCCESS) goto fail; result = isc_appctx_create(*mctxp, actxp); if (result != ISC_R_SUCCESS) goto fail; result = isc_taskmgr_createinctx(*mctxp, *actxp, 1, 0, taskmgrp); if (result != ISC_R_SUCCESS) goto fail; result = isc_socketmgr_createinctx(*mctxp, *actxp, socketmgrp); if (result != ISC_R_SUCCESS) goto fail; result = isc_timermgr_createinctx(*mctxp, *actxp, timermgrp); if (result != ISC_R_SUCCESS) goto fail; return (ISC_R_SUCCESS); fail: ctxs_destroy(mctxp, actxp, taskmgrp, socketmgrp, timermgrp); return (result); } static isc_result_t printdata(dns_rdataset_t *rdataset, dns_name_t *owner) { isc_buffer_t target; isc_result_t result; isc_region_t r; char t[4096]; isc_buffer_init(&target, t, sizeof(t)); if (!dns_rdataset_isassociated(rdataset)) return (ISC_R_SUCCESS); result = dns_rdataset_totext(rdataset, owner, ISC_FALSE, ISC_FALSE, &target); if (result != ISC_R_SUCCESS) return (result); isc_buffer_usedregion(&target, &r); printf(" %.*s", (int)r.length, (char *)r.base); return (ISC_R_SUCCESS); } static void process_answer(isc_task_t *task, isc_event_t *event) { struct query_trans *trans = event->ev_arg; dns_clientresevent_t *rev = (dns_clientresevent_t *)event; dns_name_t *name; dns_rdataset_t *rdataset; isc_result_t result; REQUIRE(task == query_task); REQUIRE(trans->inuse == ISC_TRUE); REQUIRE(outstanding_queries > 0); printf("answer[%2d]\n", trans->id); if (rev->result != ISC_R_SUCCESS) printf(" failed: %d(%s)\n", rev->result, dns_result_totext(rev->result)); for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL; name = ISC_LIST_NEXT(name, link)) { for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { (void)printdata(rdataset, name); } } dns_client_freeresanswer(client, &rev->answerlist); dns_client_destroyrestrans(&trans->xid); isc_event_free(&event); trans->inuse = ISC_FALSE; dns_fixedname_invalidate(&trans->fixedname); trans->qname = NULL; outstanding_queries--; result = dispatch_query(trans); #if 0 /* for cancel test */ if (result == ISC_R_SUCCESS) { static int count = 0; if ((++count) % 10 == 0) dns_client_cancelresolve(trans->xid); } #endif if (result == ISC_R_NOMORE && outstanding_queries == 0) isc_app_ctxshutdown(query_actx); } static isc_result_t dispatch_query(struct query_trans *trans) { isc_result_t result; unsigned int namelen; isc_buffer_t b; char buf[4096]; /* XXX ad hoc constant, but should be enough */ char *cp; REQUIRE(trans != NULL); REQUIRE(trans->inuse == ISC_FALSE); REQUIRE(ISC_LIST_EMPTY(trans->answerlist)); REQUIRE(outstanding_queries < MAX_QUERIES); /* Construct qname */ cp = fgets(buf, sizeof(buf), fp); if (cp == NULL) return (ISC_R_NOMORE); /* zap NL if any */ if ((cp = strchr(buf, '\n')) != NULL) *cp = '\0'; namelen = strlen(buf); isc_buffer_init(&b, buf, namelen); isc_buffer_add(&b, namelen); dns_fixedname_init(&trans->fixedname); trans->qname = dns_fixedname_name(&trans->fixedname); result = dns_name_fromtext(trans->qname, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) goto cleanup; /* Start resolution */ result = dns_client_startresolve(client, trans->qname, dns_rdataclass_in, trans->type, 0, query_task, process_answer, trans, &trans->xid); if (result != ISC_R_SUCCESS) goto cleanup; trans->inuse = ISC_TRUE; outstanding_queries++; return (ISC_R_SUCCESS); cleanup: dns_fixedname_invalidate(&trans->fixedname); return (result); } ISC_PLATFORM_NORETURN_PRE static void usage(void) ISC_PLATFORM_NORETURN_POST; static void usage(void) { fprintf(stderr, "usage: sample-async [-s server_address] [-t RR type] " "input_file\n"); exit(1); } int main(int argc, char *argv[]) { int ch; isc_textregion_t tr; isc_mem_t *mctx = NULL; isc_taskmgr_t *taskmgr = NULL; isc_socketmgr_t *socketmgr = NULL; isc_timermgr_t *timermgr = NULL; int nservers = 0; const char *serveraddr[MAX_SERVERS]; isc_sockaddr_t sa[MAX_SERVERS]; isc_sockaddrlist_t servers; dns_rdatatype_t type = dns_rdatatype_a; struct in_addr inaddr; isc_result_t result; int i; while ((ch = isc_commandline_parse(argc, argv, "s:t:")) != -1) { switch (ch) { case 't': tr.base = isc_commandline_argument; tr.length = strlen(isc_commandline_argument); result = dns_rdatatype_fromtext(&type, &tr); if (result != ISC_R_SUCCESS) { fprintf(stderr, "invalid RRtype: %s\n", isc_commandline_argument); exit(1); } break; case 's': if (nservers == MAX_SERVERS) { fprintf(stderr, "too many servers (up to %d)\n", MAX_SERVERS); exit(1); } serveraddr[nservers++] = (const char *)isc_commandline_argument; break; default: usage(); } } argc -= isc_commandline_index; argv += isc_commandline_index; if (argc < 1) usage(); if (nservers == 0) { nservers = 1; serveraddr[0] = def_server; } for (i = 0; i < MAX_QUERIES; i++) { query_array[i].id = i; query_array[i].inuse = ISC_FALSE; query_array[i].type = type; dns_fixedname_init(&query_array[i].fixedname); query_array[i].qname = NULL; ISC_LIST_INIT(query_array[i].answerlist); query_array[i].xid = NULL; } isc_lib_register(); result = dns_lib_init(); if (result != ISC_R_SUCCESS) { fprintf(stderr, "dns_lib_init failed: %d\n", result); exit(1); } result = ctxs_init(&mctx, &query_actx, &taskmgr, &socketmgr, &timermgr); if (result != ISC_R_SUCCESS) { fprintf(stderr, "ctx create failed: %d\n", result); exit(1); } isc_app_ctxstart(query_actx); result = dns_client_createx(mctx, query_actx, taskmgr, socketmgr, timermgr, 0, &client); if (result != ISC_R_SUCCESS) { fprintf(stderr, "dns_client_createx failed: %d\n", result); exit(1); } /* Set nameservers */ ISC_LIST_INIT(servers); for (i = 0; i < nservers; i++) { if (inet_pton(AF_INET, serveraddr[i], &inaddr) != 1) { fprintf(stderr, "failed to parse IPv4 address %s\n", serveraddr[i]); exit(1); } isc_sockaddr_fromin(&sa[i], &inaddr, 53); ISC_LIST_APPEND(servers, &sa[i], link); } result = dns_client_setservers(client, dns_rdataclass_in, NULL, &servers); if (result != ISC_R_SUCCESS) { fprintf(stderr, "set server failed: %d\n", result); exit(1); } /* Create the main task */ query_task = NULL; result = isc_task_create(taskmgr, 0, &query_task); if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to create task: %d\n", result); exit(1); } /* Open input file */ fp = fopen(argv[0], "r"); if (fp == NULL) { fprintf(stderr, "failed to open input file: %s\n", argv[1]); exit(1); } /* Dispatch initial queries */ for (i = 0; i < MAX_QUERIES; i++) { result = dispatch_query(&query_array[i]); if (result == ISC_R_NOMORE) break; } /* Start event loop */ isc_app_ctxrun(query_actx); /* Sanity check */ for (i = 0; i < MAX_QUERIES; i++) INSIST(query_array[i].inuse == ISC_FALSE); /* Cleanup */ isc_task_detach(&query_task); dns_client_destroy(&client); dns_lib_shutdown(); isc_app_ctxfinish(query_actx); ctxs_destroy(&mctx, &query_actx, &taskmgr, &socketmgr, &timermgr); return (0); } bind9-9.10.3.dfsg.P4/lib/samples/Makefile-postinstall.in0000644000470500017500000000513612664710322022227 0ustar lamontlamont# Copyright (C) 2009, 2012-2014 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile-postinstall.in,v 1.3 2009/09/02 23:48:02 tbox Exp $ srcdir = @srcdir@ #prefix = @prefix@ #exec_prefix = @exec_prefix@ CDEFINES = CWARNINGS = DNSLIBS = -ldns @DNS_CRYPTO_LIBS@ ISCLIBS = -lisc ISCCFGLIBS = -lisccfg IRSLIBS = -lirs LIBS = ${DNSLIBS} ${ISCCFGLIBS} ${ISCLIBS} @LIBS@ SUBDIRS = TARGETS = sample@EXEEXT@ sample-async@EXEEXT@ sample-gai@EXEEXT@ \ sample-update@EXEEXT@ sample-request@EXEEXT@ nsprobe@EXEEXT@ \ dlvchecks@EXEEXT@ OBJS = sample.@O@ sample-async.@O@ sample-gai.@O@ sample-update.@O@ \ sample-request.@O@ nsprobe.@O@ dlvchecks.@O@ SRCS = sample.c sample-async.c sample-gai.c sample-update.c \ sample-request.c nsprobe.c dlvchecks..c @BIND9_MAKE_RULES@ # The following two may depend on BIND9_MAKE_RULES CINCLUDES = -I@export_includedir@ LDFLAGS = -L@export_libdir@ sample@EXEEXT@: sample.@O@ ${DEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ sample.@O@ ${LIBS} sample-async@EXEEXT@: sample-async.@O@ ${DEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ sample-async.@O@ ${LIBS} sample-gai@EXEEXT@: sample-gai.@O@ ${IRSDEPLIBS} ${DEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ sample-gai.@O@ ${IRSLIBS} ${LIBS} sample-update@EXEEXT@: sample-update.@O@ ${DEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ sample-update.@O@ ${LIBS} sample-request@EXEEXT@: sample-request.@O@ ${DEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ sample-request.@O@ ${LIBS} nsprobe@EXEEXT@: nsprobe.@O@ ${DEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ nsprobe.@O@ ${LIBS} dlvchecks@EXEEXT@: dlvchecks.@O@ ${DEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ dlvchecks.@O@ ${LIBS} clean distclean maintainer-clean:: rm -f ${TARGETS} bind9-9.10.3.dfsg.P4/lib/samples/win32/0002755000470500017500000000000012664730167016560 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/samples/win32/nsprobe.mak.in0000644000470500017500000001722312664710322021321 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on nsprobe.dsp !IF "$(CFG)" == "" CFG=nsprobe - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to nsprobe - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "nsprobe - @PLATFORM@ Release" && "$(CFG)" != "nsprobe - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "nsprobe.mak" CFG="nsprobe - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "nsprobe - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "nsprobe - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF !IF "$(CFG)" == "nsprobe - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "nsprobe - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release ALL : "..\..\..\Build\Release\nsprobe.exe" CLEAN : -@erase "$(INTDIR)\nsprobe.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "..\..\..\Build\Release\nsprobe.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\nsprobe.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\nsprobe.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Release/libisc.lib ../../dns/win32/Release/libdns.lib ../../isccfg/win32/Release/libisccfg.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\nsprobe.pdb" @MACHINE@ /out:"../../../Build/Release/nsprobe.exe" LINK32_OBJS= \ "$(INTDIR)\nsprobe.obj" "..\..\..\Build\Release\nsprobe.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "nsprobe - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros ALL : "..\..\..\Build\Debug\nsprobe.exe" "$(OUTDIR)\nsprobe.bsc" CLEAN : -@erase "$(INTDIR)\nsprobe.obj" -@erase "$(INTDIR)\nsprobe.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\nsprobe.pdb" -@erase "$(OUTDIR)\nsprobe.bsc" -@erase "..\..\..\Build\Debug\nsprobe.exe" -@erase "..\..\..\Build\Debug\nsprobe.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\nsprobe.bsc" BSC32_SBRS= \ "$(INTDIR)\nsprobe.sbr" "$(OUTDIR)\nsprobe.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Debug/libisc.lib ../../dns/win32/Debug/libdns.lib ../../isccfg/win32/Debug/libisccfg.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\nsprobe.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/nsprobe.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\nsprobe.obj" "..\..\..\Build\Debug\nsprobe.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("nsprobe.dep") !INCLUDE "nsprobe.dep" !ELSE !MESSAGE Warning: cannot find "nsprobe.dep" !ENDIF !ENDIF !IF "$(CFG)" == "nsprobe - @PLATFORM@ Release" || "$(CFG)" == "nsprobe - @PLATFORM@ Debug" SOURCE="..\nsprobe.c" !IF "$(CFG)" == "nsprobe - @PLATFORM@ Release" "$(INTDIR)\nsprobe.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "nsprobe - @PLATFORM@ Debug" "$(INTDIR)\nsprobe.obj" "$(INTDIR)\nsprobe.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/lib/samples/win32/request.dsw0000644000470500017500000000103312664710322020751 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "request"=".\request.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/lib/samples/win32/gai.dsp.in0000644000470500017500000001106012664710322020420 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="gai" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 CFG=gai - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "gai.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "gai.mak" CFG="gai - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "gai - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "gai - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "gai - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /I "../../irs/win32/include" /I "../../irs/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @MACHINE@ # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Release/libisc.lib ../../dns/win32/Release/libdns.lib ../../isccfg/win32/Release/libisccfg.lib ../../irs/win32/Release/libirs.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/sample-gai.exe" !ELSEIF "$(CFG)" == "gai - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /I "../../irs/win32/include" /I "../../irs/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c # SUBTRACT CPP /X @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Debug/libisc.lib ../../dns/win32/Debug/libdns.lib ../../isccfg/win32/Debug/libisccfg.lib ../../irs/win32/Debug/libirs.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/sample-gai.exe" /pdbtype:sept !ENDIF # Begin Target # Name "gai - @PLATFORM@ Release" # Name "gai - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE="..\sample-gai.c" # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/lib/samples/win32/request.vcxproj.filters.in0000644000470500017500000000170412664710322023730 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files bind9-9.10.3.dfsg.P4/lib/samples/win32/gai.vcxproj.in0000644000470500017500000001500512664710322021330 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {D42B8670-8DF6-4D90-90F7-DB5FB845AFAE} Win32Proj gai Application true MultiByte Application false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true ..\..\..\;@LIBXML2_INC@..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;..\..\dns\win32\include;..\..\dns\include;..\..\irs\win32\include;..\..\irs\include;%(AdditionalIncludeDirectories) Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) ..\..\isc\win32\$(Configuration);..\..\dns\win32\$(Configuration);..\..\isccfg\win32\$(Configuration);..\..\irs\win32\$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;libdns.lib;libisccfg.lib;libirs.lib;ws2_32.lib;%(AdditionalDependencies) Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb ..\..\..\;@LIBXML2_INC@..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;..\..\dns\win32\include;..\..\dns\include;..\..\irs\win32\include;..\..\irs\include;%(AdditionalIncludeDirectories) Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Default ..\..\isc\win32\$(Configuration);..\..\dns\win32\$(Configuration);..\..\isccfg\win32\$(Configuration);..\..\irs\win32\$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;libdns.lib;libisccfg.lib;libirs.lib;ws2_32.lib;%(AdditionalDependencies) bind9-9.10.3.dfsg.P4/lib/samples/win32/resolve.dsp.in0000644000470500017500000001112312664710322021337 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="resolve" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 CFG=resolve - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "resolve.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "resolve.mak" CFG="resolve - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "resolve - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "resolve - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "resolve - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /I "../../irs/win32/include" /I "../../irs/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @MACHINE@ # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Release/libisc.lib ../../dns/win32/Release/libdns.lib ../../isccfg/win32/Release/libisccfg.lib ../../irs/win32/Release/libirs.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/resolve.exe" !ELSEIF "$(CFG)" == "resolve - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /I "../../irs/win32/include" /I "../../irs/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c # SUBTRACT CPP /X @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Debug/libisc.lib ../../dns/win32/Debug/libdns.lib ../../isccfg/win32/Debug/libisccfg.lib ../../irs/win32/Debug/libirs.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/resolve.exe" /pdbtype:sept !ENDIF # Begin Target # Name "resolve - @PLATFORM@ Release" # Name "resolve - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE="..\resolve.c" # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/lib/samples/win32/resolve.vcxproj.filters.in0000644000470500017500000000167512664710322023726 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files bind9-9.10.3.dfsg.P4/lib/samples/win32/update.mak.in0000644000470500017500000001747512664710322021144 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on update.dsp !IF "$(CFG)" == "" CFG=update - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to update - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "update - @PLATFORM@ Release" && "$(CFG)" != "update - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "update.mak" CFG="update - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "update - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "update - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF !IF "$(CFG)" == "update - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "update - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release ALL : "..\..\..\Build\Release\sample-update.exe" CLEAN : -@erase "$(INTDIR)\sample-update.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "..\..\..\Build\Release\sample-update.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\sample-update.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\sample-update.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Release/libisc.lib ../../dns/win32/Release/libdns.lib ../../isccfg/win32/Release/libisccfg.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\sample-update.pdb" @MACHINE@ /out:"../../../Build/Release/sample-update.exe" LINK32_OBJS= \ "$(INTDIR)\sample-update.obj" "..\..\..\Build\Release\sample-update.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "update - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros ALL : "..\..\..\Build\Debug\sample-update.exe" "$(OUTDIR)\sample-update.bsc" CLEAN : -@erase "$(INTDIR)\sample-update.obj" -@erase "$(INTDIR)\sample-update.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\sample-update.pdb" -@erase "$(OUTDIR)\sample-update.bsc" -@erase "..\..\..\Build\Debug\sample-update.exe" -@erase "..\..\..\Build\Debug\sample-update.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\sample-update.bsc" BSC32_SBRS= \ "$(INTDIR)\sample-update.sbr" "$(OUTDIR)\sample-update.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Debug/libisc.lib ../../dns/win32/Debug/libdns.lib ../../isccfg/win32/Debug/libisccfg.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\sample-update.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/sample-update.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\sample-update.obj" "..\..\..\Build\Debug\sample-update.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("sample-update.dep") !INCLUDE "sample-update.dep" !ELSE !MESSAGE Warning: cannot find "sample-update.dep" !ENDIF !ENDIF !IF "$(CFG)" == "update - @PLATFORM@ Release" || "$(CFG)" == "update - @PLATFORM@ Debug" SOURCE="..\sample-update.c" !IF "$(CFG)" == "update - @PLATFORM@ Release" "$(INTDIR)\sample-update.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "update - @PLATFORM@ Debug" "$(INTDIR)\sample-update.obj" "$(INTDIR)\sample-update.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/lib/samples/win32/nsprobe.vcxproj.in0000644000470500017500000001453212664710322022244 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {CB2A29F6-E73B-40AB-8AC4-2C1AAE7280BD} Win32Proj nsprobe Application true MultiByte Application false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true ..\..\..\;@LIBXML2_INC@..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;..\..\dns\win32\include;..\..\dns\include;%(AdditionalIncludeDirectories) Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) ..\..\isc\win32\$(Configuration);..\..\dns\win32\$(Configuration);..\..\isccfg\win32\$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;libdns.lib;libisccfg.lib;ws2_32.lib;%(AdditionalDependencies) Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb ..\..\..\;@LIBXML2_INC@..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;..\..\dns\win32\include;..\..\dns\include;%(AdditionalIncludeDirectories) Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Default ..\..\isc\win32\$(Configuration);..\..\dns\win32\$(Configuration);..\..\isccfg\win32\$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;libdns.lib;libisccfg.lib;ws2_32.lib;%(AdditionalDependencies) bind9-9.10.3.dfsg.P4/lib/samples/win32/update.vcxproj.user0000644000470500017500000000021712664710322022421 0ustar lamontlamont bind9-9.10.3.dfsg.P4/lib/samples/win32/resolve.mak.in0000644000470500017500000001747712664710322021343 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on resolve.dsp !IF "$(CFG)" == "" CFG=resolve - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to resolve - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "resolve - @PLATFORM@ Release" && "$(CFG)" != "resolve - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "resolve.mak" CFG="resolve - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "resolve - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "resolve - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF !IF "$(CFG)" == "resolve - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "resolve - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release ALL : "..\..\..\Build\Release\resolve.exe" CLEAN : -@erase "$(INTDIR)\resolve.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "..\..\..\Build\Release\resolve.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /I "../../irs/win32/include" /I "../../irs/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\resolve.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\resolve.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Release/libisc.lib ../../dns/win32/Release/libdns.lib ../../isccfg/win32/Release/libisccfg.lib ../../irs/win32/Release/libirs.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\resolve.pdb" @MACHINE@ /out:"../../../Build/Release/resolve.exe" LINK32_OBJS= \ "$(INTDIR)\resolve.obj" "..\..\..\Build\Release\resolve.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "resolve - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros ALL : "..\..\..\Build\Debug\resolve.exe" "$(OUTDIR)\resolve.bsc" CLEAN : -@erase "$(INTDIR)\resolve.obj" -@erase "$(INTDIR)\resolve.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\resolve.pdb" -@erase "$(OUTDIR)\resolve.bsc" -@erase "..\..\..\Build\Debug\resolve.exe" -@erase "..\..\..\Build\Debug\resolve.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /I "../../irs/win32/include" /I "../../irs/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\resolve.bsc" BSC32_SBRS= \ "$(INTDIR)\resolve.sbr" "$(OUTDIR)\resolve.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Debug/libisc.lib ../../dns/win32/Debug/libdns.lib ../../isccfg/win32/Debug/libisccfg.lib ../../irs/win32/Debug/libirs.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\resolve.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/resolve.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\resolve.obj" "..\..\..\Build\Debug\resolve.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("resolve.dep") !INCLUDE "resolve.dep" !ELSE !MESSAGE Warning: cannot find "resolve.dep" !ENDIF !ENDIF !IF "$(CFG)" == "resolve - @PLATFORM@ Release" || "$(CFG)" == "resolve - @PLATFORM@ Debug" SOURCE="..\resolve.c" !IF "$(CFG)" == "resolve - @PLATFORM@ Release" "$(INTDIR)\resolve.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "resolve - @PLATFORM@ Debug" "$(INTDIR)\resolve.obj" "$(INTDIR)\resolve.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/lib/samples/win32/async.vcxproj.in0000644000470500017500000001453512664710322021714 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {9FC33CA3-CE4A-4EDF-BA99-EECA4B81AD06} Win32Proj async Application true MultiByte Application false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true ..\..\..\;@LIBXML2_INC@..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;..\..\dns\win32\include;..\..\dns\include;%(AdditionalIncludeDirectories) Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) ..\..\isc\win32\$(Configuration);..\..\dns\win32\$(Configuration);..\..\isccfg\win32\$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;libdns.lib;libisccfg.lib;ws2_32.lib;%(AdditionalDependencies) Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb ..\..\..\;@LIBXML2_INC@..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;..\..\dns\win32\include;..\..\dns\include;%(AdditionalIncludeDirectories) Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Default ..\..\isc\win32\$(Configuration);..\..\dns\win32\$(Configuration);..\..\isccfg\win32\$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;libdns.lib;libisccfg.lib;ws2_32.lib;%(AdditionalDependencies) bind9-9.10.3.dfsg.P4/lib/samples/win32/request.vcxproj.in0000644000470500017500000001454112664710322022264 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {FF440E85-7450-439C-82EE-04C464512D0E} Win32Proj request Application true MultiByte Application false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true ..\..\..\;@LIBXML2_INC@..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;..\..\dns\win32\include;..\..\dns\include;%(AdditionalIncludeDirectories) Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) ..\..\isc\win32\$(Configuration);..\..\dns\win32\$(Configuration);..\..\isccfg\win32\$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;libdns.lib;libisccfg.lib;ws2_32.lib;%(AdditionalDependencies) Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb ..\..\..\;@LIBXML2_INC@..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;..\..\dns\win32\include;..\..\dns\include;%(AdditionalIncludeDirectories) Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Default ..\..\isc\win32\$(Configuration);..\..\dns\win32\$(Configuration);..\..\isccfg\win32\$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;libdns.lib;libisccfg.lib;ws2_32.lib;%(AdditionalDependencies) bind9-9.10.3.dfsg.P4/lib/samples/win32/request.vcxproj.user0000644000470500017500000000021712664710322022627 0ustar lamontlamont bind9-9.10.3.dfsg.P4/lib/samples/win32/resolve.vcxproj.in0000644000470500017500000001500612664710322022250 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {F66D8B7E-721D-4602-99AD-820D19AD1313} Win32Proj resolve Application true MultiByte Application false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true ..\..\..\;@LIBXML2_INC@..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;..\..\dns\win32\include;..\..\dns\include;..\..\irs\win32\include;..\..\irs\include;%(AdditionalIncludeDirectories) Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) ..\..\isc\win32\$(Configuration);..\..\dns\win32\$(Configuration);..\..\isccfg\win32\$(Configuration);..\..\irs\win32\$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;libdns.lib;libisccfg.lib;libirs.lib;ws2_32.lib;%(AdditionalDependencies) Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb ..\..\..\;@LIBXML2_INC@..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;..\..\dns\win32\include;..\..\dns\include;..\..\irs\win32\include;..\..\irs\include;%(AdditionalIncludeDirectories) Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Default ..\..\isc\win32\$(Configuration);..\..\dns\win32\$(Configuration);..\..\isccfg\win32\$(Configuration);..\..\irs\win32\$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;libdns.lib;libisccfg.lib;libirs.lib;ws2_32.lib;%(AdditionalDependencies) bind9-9.10.3.dfsg.P4/lib/samples/win32/async.mak.in0000644000470500017500000001741612664710322020772 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on async.dsp !IF "$(CFG)" == "" CFG=async - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to async - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "async - @PLATFORM@ Release" && "$(CFG)" != "async - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "async.mak" CFG="async - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "async - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "async - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF !IF "$(CFG)" == "async - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "async - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release ALL : "..\..\..\Build\Release\sample-async.exe" CLEAN : -@erase "$(INTDIR)\sample-async.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "..\..\..\Build\Release\sample-async.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\sample-async.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\sample-async.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Release/libisc.lib ../../dns/win32/Release/libdns.lib ../../isccfg/win32/Release/libisccfg.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\sample-async.pdb" @MACHINE@ /out:"../../../Build/Release/sample-async.exe" LINK32_OBJS= \ "$(INTDIR)\sample-async.obj" "..\..\..\Build\Release\sample-async.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "async - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros ALL : "..\..\..\Build\Debug\sample-async.exe" "$(OUTDIR)\sample-async.bsc" CLEAN : -@erase "$(INTDIR)\sample-async.obj" -@erase "$(INTDIR)\sample-async.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\sample-async.pdb" -@erase "$(OUTDIR)\sample-async.bsc" -@erase "..\..\..\Build\Debug\sample-async.exe" -@erase "..\..\..\Build\Debug\sample-async.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\sample-async.bsc" BSC32_SBRS= \ "$(INTDIR)\sample-async.sbr" "$(OUTDIR)\sample-async.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Debug/libisc.lib ../../dns/win32/Debug/libdns.lib ../../isccfg/win32/Debug/libisccfg.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\sample-async.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/sample-async.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\sample-async.obj" "..\..\..\Build\Debug\sample-async.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("sample-async.dep") !INCLUDE "sample-async.dep" !ELSE !MESSAGE Warning: cannot find "sample-async.dep" !ENDIF !ENDIF !IF "$(CFG)" == "async - @PLATFORM@ Release" || "$(CFG)" == "async - @PLATFORM@ Debug" SOURCE="..\sample-async.c" !IF "$(CFG)" == "async - @PLATFORM@ Release" "$(INTDIR)\sample-async.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "async - @PLATFORM@ Debug" "$(INTDIR)\sample-async.obj" "$(INTDIR)\sample-async.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/lib/samples/win32/async.dsp.in0000644000470500017500000001064012664710322021000 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="async" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 CFG=async - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "async.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "async.mak" CFG="async - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "async - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "async - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "async - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @MACHINE@ # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Release/libisc.lib ../../dns/win32/Release/libdns.lib ../../isccfg/win32/Release/libisccfg.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/sample-async.exe" !ELSEIF "$(CFG)" == "async - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c # SUBTRACT CPP /X @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Debug/libisc.lib ../../dns/win32/Debug/libdns.lib ../../isccfg/win32/Debug/libisccfg.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/sample-async.exe" /pdbtype:sept !ENDIF # Begin Target # Name "async - @PLATFORM@ Release" # Name "async - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE="..\sample-async.c" # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/lib/samples/win32/gai.vcxproj.filters.in0000644000470500017500000000170012664710322022774 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files bind9-9.10.3.dfsg.P4/lib/samples/win32/resolve.dsw0000644000470500017500000000103312664710322020740 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "resolve"=".\resolve.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/lib/samples/win32/request.mak.in0000644000470500017500000001755412664710322021350 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on request.dsp !IF "$(CFG)" == "" CFG=request - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to request - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "request - @PLATFORM@ Release" && "$(CFG)" != "request - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "request.mak" CFG="request - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "request - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "request - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF !IF "$(CFG)" == "request - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "request - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release ALL : "..\..\..\Build\Release\sample-request.exe" CLEAN : -@erase "$(INTDIR)\sample-request.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "..\..\..\Build\Release\sample-request.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\sample-request.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\sample-request.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Release/libisc.lib ../../dns/win32/Release/libdns.lib ../../isccfg/win32/Release/libisccfg.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\sample-request.pdb" @MACHINE@ /out:"../../../Build/Release/sample-request.exe" LINK32_OBJS= \ "$(INTDIR)\sample-request.obj" "..\..\..\Build\Release\sample-request.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "request - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros ALL : "..\..\..\Build\Debug\sample-request.exe" "$(OUTDIR)\sample-request.bsc" CLEAN : -@erase "$(INTDIR)\sample-request.obj" -@erase "$(INTDIR)\sample-request.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\sample-request.pdb" -@erase "$(OUTDIR)\sample-request.bsc" -@erase "..\..\..\Build\Debug\sample-request.exe" -@erase "..\..\..\Build\Debug\sample-request.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\sample-request.bsc" BSC32_SBRS= \ "$(INTDIR)\sample-request.sbr" "$(OUTDIR)\sample-request.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Debug/libisc.lib ../../dns/win32/Debug/libdns.lib ../../isccfg/win32/Debug/libisccfg.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\sample-request.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/sample-request.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\sample-request.obj" "..\..\..\Build\Debug\sample-request.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("sample-request.dep") !INCLUDE "sample-request.dep" !ELSE !MESSAGE Warning: cannot find "sample-request.dep" !ENDIF !ENDIF !IF "$(CFG)" == "request - @PLATFORM@ Release" || "$(CFG)" == "request - @PLATFORM@ Debug" SOURCE="..\sample-request.c" !IF "$(CFG)" == "request - @PLATFORM@ Release" "$(INTDIR)\sample-request.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "request - @PLATFORM@ Debug" "$(INTDIR)\sample-request.obj" "$(INTDIR)\sample-request.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/lib/samples/win32/update.vcxproj.filters.in0000644000470500017500000000170312664710322023521 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files bind9-9.10.3.dfsg.P4/lib/samples/win32/update.dsw0000644000470500017500000000103112664710322020541 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "update"=".\update.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/lib/samples/win32/async.dsw0000644000470500017500000000102712664710322020401 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "async"=".\async.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/lib/samples/win32/async.vcxproj.filters.in0000644000470500017500000000170212664710322023353 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files bind9-9.10.3.dfsg.P4/lib/samples/win32/update.vcxproj.in0000644000470500017500000001453712664710322022063 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {05682E12-523F-4DAE-8E6D-ADFDBC308AFD} Win32Proj update Application true MultiByte Application false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true ..\..\..\;@LIBXML2_INC@..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;..\..\dns\win32\include;..\..\dns\include;%(AdditionalIncludeDirectories) Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) ..\..\isc\win32\$(Configuration);..\..\dns\win32\$(Configuration);..\..\isccfg\win32\$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;libdns.lib;libisccfg.lib;ws2_32.lib;%(AdditionalDependencies) Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb ..\..\..\;@LIBXML2_INC@..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;..\..\dns\win32\include;..\..\dns\include;%(AdditionalIncludeDirectories) Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Default ..\..\isc\win32\$(Configuration);..\..\dns\win32\$(Configuration);..\..\isccfg\win32\$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;libdns.lib;libisccfg.lib;ws2_32.lib;%(AdditionalDependencies) bind9-9.10.3.dfsg.P4/lib/samples/win32/gai.dsw0000644000470500017500000000102312664710322020020 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "gai"=".\gai.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/lib/samples/win32/async.vcxproj.user0000644000470500017500000000021712664710322022254 0ustar lamontlamont bind9-9.10.3.dfsg.P4/lib/samples/win32/gai.mak.in0000644000470500017500000001753412664710322020416 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on gai.dsp !IF "$(CFG)" == "" CFG=gai - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to gai - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "gai - @PLATFORM@ Release" && "$(CFG)" != "gai - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "gai.mak" CFG="gai - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "gai - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "gai - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF !IF "$(CFG)" == "gai - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "gai - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release ALL : "..\..\..\Build\Release\sample-gai.exe" CLEAN : -@erase "$(INTDIR)\sample-gai.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "..\..\..\Build\Release\sample-gai.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /I "../../irs/win32/include" /I "../../irs/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\sample-gai.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\sample-gai.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Release/libisc.lib ../../dns/win32/Release/libdns.lib ../../isccfg/win32/Release/libisccfg.lib ../../irs/win32/Release/libirs.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\sample-gai.pdb" @MACHINE@ /out:"../../../Build/Release/sample-gai.exe" LINK32_OBJS= \ "$(INTDIR)\sample-gai.obj" "..\..\..\Build\Release\sample-gai.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "gai - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros ALL : "..\..\..\Build\Debug\sample-gai.exe" "$(OUTDIR)\sample-gai.bsc" CLEAN : -@erase "$(INTDIR)\sample-gai.obj" -@erase "$(INTDIR)\sample-gai.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\sample-gai.pdb" -@erase "$(OUTDIR)\sample-gai.bsc" -@erase "..\..\..\Build\Debug\sample-gai.exe" -@erase "..\..\..\Build\Debug\sample-gai.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /I "../../irs/win32/include" /I "../../irs/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\sample-gai.bsc" BSC32_SBRS= \ "$(INTDIR)\sample-gai.sbr" "$(OUTDIR)\sample-gai.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Debug/libisc.lib ../../dns/win32/Debug/libdns.lib ../../isccfg/win32/Debug/libisccfg.lib ../../irs/win32/Debug/libirs.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\sample-gai.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/sample-gai.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\sample-gai.obj" "..\..\..\Build\Debug\sample-gai.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("sample-gai.dep") !INCLUDE "sample-gai.dep" !ELSE !MESSAGE Warning: cannot find "sample-gai.dep" !ENDIF !ENDIF !IF "$(CFG)" == "gai - @PLATFORM@ Release" || "$(CFG)" == "gai - @PLATFORM@ Debug" SOURCE="..\sample-gai.c" !IF "$(CFG)" == "gai - @PLATFORM@ Release" "$(INTDIR)\sample-gai.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "gai - @PLATFORM@ Debug" "$(INTDIR)\sample-gai.obj" "$(INTDIR)\sample-gai.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/lib/samples/win32/resolve.vcxproj.user0000644000470500017500000000021712664710322022616 0ustar lamontlamont bind9-9.10.3.dfsg.P4/lib/samples/win32/nsprobe.dsp.in0000644000470500017500000001064712664710322021342 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="nsprobe" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 CFG=nsprobe - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "nsprobe.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "nsprobe.mak" CFG="nsprobe - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "nsprobe - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "nsprobe - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "nsprobe - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @MACHINE@ # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Release/libisc.lib ../../dns/win32/Release/libdns.lib ../../isccfg/win32/Release/libisccfg.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/nsprobe.exe" !ELSEIF "$(CFG)" == "nsprobe - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c # SUBTRACT CPP /X @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Debug/libisc.lib ../../dns/win32/Debug/libdns.lib ../../isccfg/win32/Debug/libisccfg.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/nsprobe.exe" /pdbtype:sept !ENDIF # Begin Target # Name "nsprobe - @PLATFORM@ Release" # Name "nsprobe - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE="..\nsprobe.c" # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/lib/samples/win32/request.dsp.in0000644000470500017500000001067412664710322021362 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="request" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 CFG=request - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "request.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "request.mak" CFG="request - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "request - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "request - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "request - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @MACHINE@ # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Release/libisc.lib ../../dns/win32/Release/libdns.lib ../../isccfg/win32/Release/libisccfg.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/sample-request.exe" !ELSEIF "$(CFG)" == "request - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c # SUBTRACT CPP /X @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Debug/libisc.lib ../../dns/win32/Debug/libdns.lib ../../isccfg/win32/Debug/libisccfg.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/sample-request.exe" /pdbtype:sept !ENDIF # Begin Target # Name "request - @PLATFORM@ Release" # Name "request - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE="..\sample-request.c" # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/lib/samples/win32/nsprobe.vcxproj.user0000644000470500017500000000021712664710322022607 0ustar lamontlamont bind9-9.10.3.dfsg.P4/lib/samples/win32/gai.vcxproj.user0000644000470500017500000000021712664710322021677 0ustar lamontlamont bind9-9.10.3.dfsg.P4/lib/samples/win32/nsprobe.dsw0000644000470500017500000000103312664710322020731 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "nsprobe"=".\nsprobe.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/lib/samples/win32/update.dsp.in0000644000470500017500000001065612664710322021154 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="update" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 CFG=update - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "update.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "update.mak" CFG="update - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "update - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "update - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "update - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @MACHINE@ # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Release/libisc.lib ../../dns/win32/Release/libdns.lib ../../isccfg/win32/Release/libisccfg.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/sample-update.exe" !ELSEIF "$(CFG)" == "update - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "../../../" @LIBXML2_INC@ /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" /I "../../dns/win32/include" /I "../../dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c # SUBTRACT CPP /X @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Debug/libisc.lib ../../dns/win32/Debug/libdns.lib ../../isccfg/win32/Debug/libisccfg.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/sample-update.exe" /pdbtype:sept !ENDIF # Begin Target # Name "update - @PLATFORM@ Release" # Name "update - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE="..\sample-update.c" # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/lib/samples/win32/nsprobe.vcxproj.filters.in0000644000470500017500000000167512664710322023717 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files bind9-9.10.3.dfsg.P4/lib/samples/nsprobe.c0000644000470500017500000007622712664710322017435 0ustar lamontlamont/* * Copyright (C) 2009-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #include #ifndef WIN32 #include #include #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_PROBES 1000 static dns_client_t *client = NULL; static isc_task_t *probe_task = NULL; static isc_appctx_t *actx = NULL; static isc_mem_t *mctx = NULL; static unsigned int outstanding_probes = 0; const char *cacheserver = "127.0.0.1"; static FILE *input; typedef enum { none, exist, nxdomain, othererr, multiplesoa, multiplecname, brokenanswer, lame, timedout, notype, unexpected } query_result_t; struct server { ISC_LINK(struct server) link; isc_sockaddr_t address; query_result_t result_a; query_result_t result_aaaa; }; struct probe_ns { ISC_LINK(struct probe_ns) link; dns_fixedname_t fixedname; dns_name_t *name; struct server *current_server; ISC_LIST(struct server) servers; }; struct probe_trans { isc_boolean_t inuse; char *domain; dns_fixedname_t fixedname; dns_name_t *qname; const char **qlabel; isc_boolean_t qname_found; dns_clientrestrans_t *resid; dns_message_t *qmessage; dns_message_t *rmessage; dns_clientreqtrans_t *reqid; /* NS list */ struct probe_ns *current_ns; ISC_LIST(struct probe_ns) nslist; }; struct lcl_stat { unsigned long valid; unsigned long ignore; unsigned long nxdomain; unsigned long othererr; unsigned long multiplesoa; unsigned long multiplecname; unsigned long brokenanswer; unsigned long lame; unsigned long unknown; } server_stat, domain_stat; static unsigned long number_of_domains = 0; static unsigned long number_of_servers = 0; static unsigned long multiple_error_domains = 0; static isc_boolean_t debug_mode = ISC_FALSE; static int verbose_level = 0; static const char *qlabels[] = {"www.", "ftp.", NULL}; static struct probe_trans probes[MAX_PROBES]; static isc_result_t probe_domain(struct probe_trans *trans); static void reset_probe(struct probe_trans *trans); static isc_result_t fetch_nsaddress(struct probe_trans *trans); static isc_result_t probe_name(struct probe_trans *trans, dns_rdatatype_t type); /* Dump an rdataset for debug */ static isc_result_t print_rdataset(dns_rdataset_t *rdataset, dns_name_t *owner) { isc_buffer_t target; isc_result_t result; isc_region_t r; char t[4096]; if (!debug_mode) return (ISC_R_SUCCESS); isc_buffer_init(&target, t, sizeof(t)); if (!dns_rdataset_isassociated(rdataset)) return (ISC_R_SUCCESS); result = dns_rdataset_totext(rdataset, owner, ISC_FALSE, ISC_FALSE, &target); if (result != ISC_R_SUCCESS) return (result); isc_buffer_usedregion(&target, &r); printf("%.*s", (int)r.length, (char *)r.base); return (ISC_R_SUCCESS); } static isc_result_t print_name(dns_name_t *name) { isc_result_t result; isc_buffer_t target; isc_region_t r; char t[4096]; isc_buffer_init(&target, t, sizeof(t)); result = dns_name_totext(name, ISC_TRUE, &target); if (result == ISC_R_SUCCESS) { isc_buffer_usedregion(&target, &r); printf("%.*s", (int)r.length, (char *)r.base); } else printf("(invalid name)"); return (result); } static isc_result_t print_address(FILE *fp, isc_sockaddr_t *addr) { char buf[NI_MAXHOST]; if (getnameinfo(&addr->type.sa, addr->length, buf, sizeof(buf), NULL, 0, NI_NUMERICHOST) == 0) { fprintf(fp, "%s", buf); } else { fprintf(fp, "(invalid address)"); } return (ISC_R_SUCCESS); } static void ctxs_destroy(isc_mem_t **mctxp, isc_appctx_t **actxp, isc_taskmgr_t **taskmgrp, isc_socketmgr_t **socketmgrp, isc_timermgr_t **timermgrp) { if (*taskmgrp != NULL) isc_taskmgr_destroy(taskmgrp); if (*timermgrp != NULL) isc_timermgr_destroy(timermgrp); if (*socketmgrp != NULL) isc_socketmgr_destroy(socketmgrp); if (*actxp != NULL) isc_appctx_destroy(actxp); if (*mctxp != NULL) isc_mem_destroy(mctxp); } static isc_result_t ctxs_init(isc_mem_t **mctxp, isc_appctx_t **actxp, isc_taskmgr_t **taskmgrp, isc_socketmgr_t **socketmgrp, isc_timermgr_t **timermgrp) { isc_result_t result; result = isc_mem_create(0, 0, mctxp); if (result != ISC_R_SUCCESS) goto fail; result = isc_appctx_create(*mctxp, actxp); if (result != ISC_R_SUCCESS) goto fail; result = isc_taskmgr_createinctx(*mctxp, *actxp, 1, 0, taskmgrp); if (result != ISC_R_SUCCESS) goto fail; result = isc_socketmgr_createinctx(*mctxp, *actxp, socketmgrp); if (result != ISC_R_SUCCESS) goto fail; result = isc_timermgr_createinctx(*mctxp, *actxp, timermgrp); if (result != ISC_R_SUCCESS) goto fail; return (ISC_R_SUCCESS); fail: ctxs_destroy(mctxp, actxp, taskmgrp, socketmgrp, timermgrp); return (result); } /* * Common routine to make query data */ static isc_result_t make_querymessage(dns_message_t *message, dns_name_t *qname0, dns_rdatatype_t rdtype) { dns_name_t *qname = NULL; dns_rdataset_t *qrdataset = NULL; isc_result_t result; message->opcode = dns_opcode_query; message->rdclass = dns_rdataclass_in; result = dns_message_gettempname(message, &qname); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_message_gettemprdataset(message, &qrdataset); if (result != ISC_R_SUCCESS) goto cleanup; dns_name_init(qname, NULL); dns_name_clone(qname0, qname); dns_rdataset_makequestion(qrdataset, message->rdclass, rdtype); ISC_LIST_APPEND(qname->list, qrdataset, link); dns_message_addname(message, qname, DNS_SECTION_QUESTION); return (ISC_R_SUCCESS); cleanup: if (qname != NULL) dns_message_puttempname(message, &qname); if (qrdataset != NULL) dns_message_puttemprdataset(message, &qrdataset); return (result); } /* * Update statistics */ static inline void increment_entry(unsigned long *entryp) { (*entryp)++; INSIST(*entryp != 0U); /* check overflow */ } static void update_stat(struct probe_trans *trans) { struct probe_ns *pns; struct server *server; struct lcl_stat local_stat; unsigned int err_count = 0; const char *stattype; increment_entry(&number_of_domains); memset(&local_stat, 0, sizeof(local_stat)); /* Update per sever statistics */ for (pns = ISC_LIST_HEAD(trans->nslist); pns != NULL; pns = ISC_LIST_NEXT(pns, link)) { for (server = ISC_LIST_HEAD(pns->servers); server != NULL; server = ISC_LIST_NEXT(server, link)) { increment_entry(&number_of_servers); if (server->result_aaaa == exist || server->result_aaaa == notype) { /* * Don't care about the result of A query if * the answer to AAAA query was expected. */ stattype = "valid"; increment_entry(&server_stat.valid); increment_entry(&local_stat.valid); } else if (server->result_a == exist) { switch (server->result_aaaa) { case exist: case notype: stattype = "valid"; increment_entry(&server_stat.valid); increment_entry(&local_stat.valid); break; case timedout: stattype = "ignore"; increment_entry(&server_stat.ignore); increment_entry(&local_stat.ignore); break; case nxdomain: stattype = "nxdomain"; increment_entry(&server_stat.nxdomain); increment_entry(&local_stat.nxdomain); break; case othererr: stattype = "othererr"; increment_entry(&server_stat.othererr); increment_entry(&local_stat.othererr); break; case multiplesoa: stattype = "multiplesoa"; increment_entry(&server_stat.multiplesoa); increment_entry(&local_stat.multiplesoa); break; case multiplecname: stattype = "multiplecname"; increment_entry(&server_stat.multiplecname); increment_entry(&local_stat.multiplecname); break; case brokenanswer: stattype = "brokenanswer"; increment_entry(&server_stat.brokenanswer); increment_entry(&local_stat.brokenanswer); break; case lame: stattype = "lame"; increment_entry(&server_stat.lame); increment_entry(&local_stat.lame); break; default: stattype = "unknown"; increment_entry(&server_stat.unknown); increment_entry(&local_stat.unknown); break; } } else { stattype = "unknown"; increment_entry(&server_stat.unknown); increment_entry(&local_stat.unknown); } if (verbose_level > 1 || (verbose_level == 1 && strcmp(stattype, "valid") != 0 && strcmp(stattype, "unknown") != 0)) { print_name(pns->name); putchar('('); print_address(stdout, &server->address); printf(") for %s:%s\n", trans->domain, stattype); } } } /* Update per domain statistics */ if (local_stat.ignore > 0U) { if (verbose_level > 0) printf("%s:ignore\n", trans->domain); increment_entry(&domain_stat.ignore); err_count++; } if (local_stat.nxdomain > 0U) { if (verbose_level > 0) printf("%s:nxdomain\n", trans->domain); increment_entry(&domain_stat.nxdomain); err_count++; } if (local_stat.othererr > 0U) { if (verbose_level > 0) printf("%s:othererr\n", trans->domain); increment_entry(&domain_stat.othererr); err_count++; } if (local_stat.multiplesoa > 0U) { if (verbose_level > 0) printf("%s:multiplesoa\n", trans->domain); increment_entry(&domain_stat.multiplesoa); err_count++; } if (local_stat.multiplecname > 0U) { if (verbose_level > 0) printf("%s:multiplecname\n", trans->domain); increment_entry(&domain_stat.multiplecname); err_count++; } if (local_stat.brokenanswer > 0U) { if (verbose_level > 0) printf("%s:brokenanswer\n", trans->domain); increment_entry(&domain_stat.brokenanswer); err_count++; } if (local_stat.lame > 0U) { if (verbose_level > 0) printf("%s:lame\n", trans->domain); increment_entry(&domain_stat.lame); err_count++; } if (err_count > 1U) increment_entry(&multiple_error_domains); /* * We regard the domain as valid if and only if no authoritative server * has a problem and at least one server is known to be valid. */ if (local_stat.valid > 0U && err_count == 0U) { if (verbose_level > 1) printf("%s:valid\n", trans->domain); increment_entry(&domain_stat.valid); } /* * If the domain has no available server or all servers have the * 'unknown' result, the domain's result is also regarded as unknown. */ if (local_stat.valid == 0U && err_count == 0U) { if (verbose_level > 1) printf("%s:unknown\n", trans->domain); increment_entry(&domain_stat.unknown); } } /* * Search for an existent name with an A RR */ static isc_result_t set_nextqname(struct probe_trans *trans) { isc_result_t result; unsigned int domainlen; isc_buffer_t b; char buf[4096]; /* XXX ad-hoc constant, but should be enough */ if (*trans->qlabel == NULL) return (ISC_R_NOMORE); result = isc_string_copy(buf, sizeof(buf), *trans->qlabel); if (result != ISC_R_SUCCESS) return (result); result = isc_string_append(buf, sizeof(buf), trans->domain); if (result != ISC_R_SUCCESS) return (result); domainlen = strlen(buf); isc_buffer_init(&b, buf, domainlen); isc_buffer_add(&b, domainlen); dns_fixedname_init(&trans->fixedname); trans->qname = dns_fixedname_name(&trans->fixedname); result = dns_name_fromtext(trans->qname, &b, dns_rootname, 0, NULL); trans->qlabel++; return (result); } static void request_done(isc_task_t *task, isc_event_t *event) { struct probe_trans *trans = event->ev_arg; dns_clientreqevent_t *rev = (dns_clientreqevent_t *)event; dns_message_t *rmessage; struct probe_ns *pns; struct server *server; isc_result_t result; query_result_t *resultp; dns_name_t *name; dns_rdataset_t *rdataset; dns_rdatatype_t type; REQUIRE(task == probe_task); REQUIRE(trans != NULL && trans->inuse == ISC_TRUE); rmessage = rev->rmessage; REQUIRE(rmessage == trans->rmessage); INSIST(outstanding_probes > 0); server = trans->current_ns->current_server; INSIST(server != NULL); if (server->result_a == none) { type = dns_rdatatype_a; resultp = &server->result_a; } else { resultp = &server->result_aaaa; type = dns_rdatatype_aaaa; } if (rev->result == ISC_R_SUCCESS) { if ((rmessage->flags & DNS_MESSAGEFLAG_AA) == 0) *resultp = lame; else if (rmessage->rcode == dns_rcode_nxdomain) *resultp = nxdomain; else if (rmessage->rcode != dns_rcode_noerror) *resultp = othererr; else if (rmessage->counts[DNS_SECTION_ANSWER] == 0) { /* no error but empty answer */ *resultp = notype; } else { result = dns_message_firstname(rmessage, DNS_SECTION_ANSWER); while (result == ISC_R_SUCCESS) { name = NULL; dns_message_currentname(rmessage, DNS_SECTION_ANSWER, &name); for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { (void)print_rdataset(rdataset, name); if (rdataset->type == dns_rdatatype_cname || rdataset->type == dns_rdatatype_dname) { /* Should chase the chain? */ *resultp = exist; goto found; } else if (rdataset->type == type) { *resultp = exist; goto found; } } result = dns_message_nextname(rmessage, DNS_SECTION_ANSWER); } /* * Something unexpected happened: the response * contained a non-empty authoritative answer, but we * could not find an expected result. */ *resultp = unexpected; } } else if (rev->result == DNS_R_RECOVERABLE || rev->result == DNS_R_BADLABELTYPE) { /* Broken response. Try identifying known cases. */ *resultp = brokenanswer; if (rmessage->counts[DNS_SECTION_ANSWER] > 0) { result = dns_message_firstname(rmessage, DNS_SECTION_ANSWER); while (result == ISC_R_SUCCESS) { /* * Check to see if the response has multiple * CNAME RRs. Update the result code if so. */ name = NULL; dns_message_currentname(rmessage, DNS_SECTION_ANSWER, &name); for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (rdataset->type == dns_rdatatype_cname && dns_rdataset_count(rdataset) > 1) { *resultp = multiplecname; goto found; } } result = dns_message_nextname(rmessage, DNS_SECTION_ANSWER); } } if (rmessage->counts[DNS_SECTION_AUTHORITY] > 0) { result = dns_message_firstname(rmessage, DNS_SECTION_AUTHORITY); while (result == ISC_R_SUCCESS) { /* * Check to see if the response has multiple * SOA RRs. Update the result code if so. */ name = NULL; dns_message_currentname(rmessage, DNS_SECTION_AUTHORITY, &name); for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (rdataset->type == dns_rdatatype_soa && dns_rdataset_count(rdataset) > 1) { *resultp = multiplesoa; goto found; } } result = dns_message_nextname(rmessage, DNS_SECTION_AUTHORITY); } } } else if (rev->result == ISC_R_TIMEDOUT) *resultp = timedout; else { fprintf(stderr, "unexpected result: %d (domain=%s, server=", rev->result, trans->domain); print_address(stderr, &server->address); fputc('\n', stderr); *resultp = unexpected; } found: INSIST(*resultp != none); if (type == dns_rdatatype_a && *resultp == exist) trans->qname_found = ISC_TRUE; dns_client_destroyreqtrans(&trans->reqid); isc_event_free(&event); dns_message_reset(trans->rmessage, DNS_MESSAGE_INTENTPARSE); result = probe_name(trans, type); if (result == ISC_R_NOMORE) { /* We've tried all addresses of all servers. */ if (type == dns_rdatatype_a && trans->qname_found) { /* * If we've explored A RRs and found an existent * record, we can move to AAAA. */ trans->current_ns = ISC_LIST_HEAD(trans->nslist); probe_name(trans, dns_rdatatype_aaaa); result = ISC_R_SUCCESS; } else if (type == dns_rdatatype_a) { /* * No server provided an existent A RR of this name. * Try next label. */ dns_fixedname_invalidate(&trans->fixedname); trans->qname = NULL; result = set_nextqname(trans); if (result == ISC_R_SUCCESS) { trans->current_ns = ISC_LIST_HEAD(trans->nslist); for (pns = trans->current_ns; pns != NULL; pns = ISC_LIST_NEXT(pns, link)) { for (server = ISC_LIST_HEAD(pns->servers); server != NULL; server = ISC_LIST_NEXT(server, link)) { INSIST(server->result_aaaa == none); server->result_a = none; } } result = probe_name(trans, dns_rdatatype_a); } } if (result != ISC_R_SUCCESS) { /* * We've explored AAAA RRs or failed to find a valid * query label. Wrap up the result and move to the * next domain. */ reset_probe(trans); } } else if (result != ISC_R_SUCCESS) reset_probe(trans); /* XXX */ } static isc_result_t probe_name(struct probe_trans *trans, dns_rdatatype_t type) { isc_result_t result; struct probe_ns *pns; struct server *server; REQUIRE(trans->reqid == NULL); REQUIRE(type == dns_rdatatype_a || type == dns_rdatatype_aaaa); for (pns = trans->current_ns; pns != NULL; pns = ISC_LIST_NEXT(pns, link)) { for (server = ISC_LIST_HEAD(pns->servers); server != NULL; server = ISC_LIST_NEXT(server, link)) { if ((type == dns_rdatatype_a && server->result_a == none) || (type == dns_rdatatype_aaaa && server->result_aaaa == none)) { pns->current_server = server; goto found; } } } found: trans->current_ns = pns; if (pns == NULL) return (ISC_R_NOMORE); INSIST(pns->current_server != NULL); dns_message_reset(trans->qmessage, DNS_MESSAGE_INTENTRENDER); result = make_querymessage(trans->qmessage, trans->qname, type); if (result != ISC_R_SUCCESS) return (result); result = dns_client_startrequest(client, trans->qmessage, trans->rmessage, &pns->current_server->address, 0, DNS_MESSAGEPARSE_BESTEFFORT, NULL, 120, 0, 4, probe_task, request_done, trans, &trans->reqid); return (result); } /* * Get IP addresses of NSes */ static void resolve_nsaddress(isc_task_t *task, isc_event_t *event) { struct probe_trans *trans = event->ev_arg; dns_clientresevent_t *rev = (dns_clientresevent_t *)event; dns_name_t *name; dns_rdataset_t *rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; struct probe_ns *pns = trans->current_ns; isc_result_t result; REQUIRE(task == probe_task); REQUIRE(trans->inuse == ISC_TRUE); REQUIRE(pns != NULL); INSIST(outstanding_probes > 0); for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL; name = ISC_LIST_NEXT(name, link)) { for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { (void)print_rdataset(rdataset, name); if (rdataset->type != dns_rdatatype_a) continue; for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdata_in_a_t rdata_a; struct server *server; dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &rdata_a, NULL); if (result != ISC_R_SUCCESS) continue; server = isc_mem_get(mctx, sizeof(*server)); if (server == NULL) { fprintf(stderr, "resolve_nsaddress: " "mem_get failed"); result = ISC_R_NOMEMORY; POST(result); goto cleanup; } isc_sockaddr_fromin(&server->address, &rdata_a.in_addr, 53); ISC_LINK_INIT(server, link); server->result_a = none; server->result_aaaa = none; ISC_LIST_APPEND(pns->servers, server, link); } } } cleanup: dns_client_freeresanswer(client, &rev->answerlist); dns_client_destroyrestrans(&trans->resid); isc_event_free(&event); next_ns: trans->current_ns = ISC_LIST_NEXT(pns, link); if (trans->current_ns == NULL) { trans->current_ns = ISC_LIST_HEAD(trans->nslist); dns_fixedname_invalidate(&trans->fixedname); trans->qname = NULL; result = set_nextqname(trans); if (result == ISC_R_SUCCESS) result = probe_name(trans, dns_rdatatype_a); } else { result = fetch_nsaddress(trans); if (result != ISC_R_SUCCESS) goto next_ns; /* XXX: this is unlikely to succeed */ } if (result != ISC_R_SUCCESS) reset_probe(trans); } static isc_result_t fetch_nsaddress(struct probe_trans *trans) { struct probe_ns *pns; pns = trans->current_ns; REQUIRE(pns != NULL); return (dns_client_startresolve(client, pns->name, dns_rdataclass_in, dns_rdatatype_a, 0, probe_task, resolve_nsaddress, trans, &trans->resid)); } /* * Get NS RRset for a given domain */ static void reset_probe(struct probe_trans *trans) { struct probe_ns *pns; struct server *server; isc_result_t result; REQUIRE(trans->resid == NULL); REQUIRE(trans->reqid == NULL); update_stat(trans); dns_message_reset(trans->qmessage, DNS_MESSAGE_INTENTRENDER); dns_message_reset(trans->rmessage, DNS_MESSAGE_INTENTPARSE); trans->inuse = ISC_FALSE; if (trans->domain != NULL) isc_mem_free(mctx, trans->domain); trans->domain = NULL; if (trans->qname != NULL) dns_fixedname_invalidate(&trans->fixedname); trans->qname = NULL; trans->qlabel = qlabels; trans->qname_found = ISC_FALSE; trans->current_ns = NULL; while ((pns = ISC_LIST_HEAD(trans->nslist)) != NULL) { ISC_LIST_UNLINK(trans->nslist, pns, link); while ((server = ISC_LIST_HEAD(pns->servers)) != NULL) { ISC_LIST_UNLINK(pns->servers, server, link); isc_mem_put(mctx, server, sizeof(*server)); } isc_mem_put(mctx, pns, sizeof(*pns)); } outstanding_probes--; result = probe_domain(trans); if (result == ISC_R_NOMORE && outstanding_probes == 0) isc_app_ctxshutdown(actx); } static void resolve_ns(isc_task_t *task, isc_event_t *event) { struct probe_trans *trans = event->ev_arg; dns_clientresevent_t *rev = (dns_clientresevent_t *)event; dns_name_t *name; dns_rdataset_t *rdataset; isc_result_t result = ISC_R_SUCCESS; dns_rdata_t rdata = DNS_RDATA_INIT; struct probe_ns *pns; REQUIRE(task == probe_task); REQUIRE(trans->inuse == ISC_TRUE); INSIST(outstanding_probes > 0); for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL; name = ISC_LIST_NEXT(name, link)) { for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { (void)print_rdataset(rdataset, name); if (rdataset->type != dns_rdatatype_ns) continue; for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdata_ns_t ns; dns_rdataset_current(rdataset, &rdata); /* * Extract the name from the NS record. */ result = dns_rdata_tostruct(&rdata, &ns, NULL); if (result != ISC_R_SUCCESS) continue; pns = isc_mem_get(mctx, sizeof(*pns)); if (pns == NULL) { fprintf(stderr, "resolve_ns: mem_get failed"); result = ISC_R_NOMEMORY; POST(result); /* * XXX: should we continue with the * available servers anyway? */ goto cleanup; } dns_fixedname_init(&pns->fixedname); pns->name = dns_fixedname_name(&pns->fixedname); ISC_LINK_INIT(pns, link); ISC_LIST_APPEND(trans->nslist, pns, link); ISC_LIST_INIT(pns->servers); dns_name_copy(&ns.name, pns->name, NULL); dns_rdata_reset(&rdata); dns_rdata_freestruct(&ns); } } } cleanup: dns_client_freeresanswer(client, &rev->answerlist); dns_client_destroyrestrans(&trans->resid); isc_event_free(&event); if (!ISC_LIST_EMPTY(trans->nslist)) { /* Go get addresses of NSes */ trans->current_ns = ISC_LIST_HEAD(trans->nslist); result = fetch_nsaddress(trans); } else result = ISC_R_FAILURE; if (result == ISC_R_SUCCESS) return; reset_probe(trans); } static isc_result_t probe_domain(struct probe_trans *trans) { isc_result_t result; unsigned int domainlen; isc_buffer_t b; char buf[4096]; /* XXX ad hoc constant, but should be enough */ char *cp; REQUIRE(trans != NULL); REQUIRE(trans->inuse == ISC_FALSE); REQUIRE(outstanding_probes < MAX_PROBES); /* Construct domain */ cp = fgets(buf, sizeof(buf), input); if (cp == NULL) return (ISC_R_NOMORE); if ((cp = strchr(buf, '\n')) != NULL) /* zap NL if any */ *cp = '\0'; trans->domain = isc_mem_strdup(mctx, buf); if (trans->domain == NULL) { fprintf(stderr, "failed to allocate memory for domain: %s", cp); return (ISC_R_NOMEMORY); } /* Start getting NS for the domain */ domainlen = strlen(buf); isc_buffer_init(&b, buf, domainlen); isc_buffer_add(&b, domainlen); dns_fixedname_init(&trans->fixedname); trans->qname = dns_fixedname_name(&trans->fixedname); result = dns_name_fromtext(trans->qname, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_client_startresolve(client, trans->qname, dns_rdataclass_in, dns_rdatatype_ns, 0, probe_task, resolve_ns, trans, &trans->resid); if (result != ISC_R_SUCCESS) goto cleanup; trans->inuse = ISC_TRUE; outstanding_probes++; return (ISC_R_SUCCESS); cleanup: isc_mem_free(mctx, trans->domain); dns_fixedname_invalidate(&trans->fixedname); return (result); } ISC_PLATFORM_NORETURN_PRE static void usage(void) ISC_PLATFORM_NORETURN_POST; static void usage(void) { fprintf(stderr, "usage: nsprobe [-d] [-v [-v...]] [-c cache_address] " "[input_file]\n"); exit(1); } int main(int argc, char *argv[]) { int i, ch, error; struct addrinfo hints, *res; isc_result_t result; isc_sockaddr_t sa; isc_sockaddrlist_t servers; isc_taskmgr_t *taskmgr = NULL; isc_socketmgr_t *socketmgr = NULL; isc_timermgr_t *timermgr = NULL; while ((ch = isc_commandline_parse(argc, argv, "c:dhv")) != -1) { switch (ch) { case 'c': cacheserver = isc_commandline_argument; break; case 'd': debug_mode = ISC_TRUE; break; case 'h': usage(); break; case 'v': verbose_level++; break; default: usage(); break; } } argc -= isc_commandline_index; argv += isc_commandline_index; /* Common set up */ isc_lib_register(); result = dns_lib_init(); if (result != ISC_R_SUCCESS) { fprintf(stderr, "dns_lib_init failed: %d\n", result); exit(1); } result = ctxs_init(&mctx, &actx, &taskmgr, &socketmgr, &timermgr); if (result != ISC_R_SUCCESS) { fprintf(stderr, "ctx create failed: %d\n", result); exit(1); } isc_app_ctxstart(actx); result = dns_client_createx(mctx, actx, taskmgr, socketmgr, timermgr, 0, &client); if (result != ISC_R_SUCCESS) { fprintf(stderr, "dns_client_createx failed: %d\n", result); exit(1); } /* Set local cache server */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; error = getaddrinfo(cacheserver, "53", &hints, &res); if (error != 0) { fprintf(stderr, "failed to convert server name (%s): %s\n", cacheserver, gai_strerror(error)); exit(1); } if (res->ai_addrlen > sizeof(sa.type)) { fprintf(stderr, "assumption failure: addrlen is too long: %ld\n", (long)res->ai_addrlen); exit(1); } memmove(&sa.type.sa, res->ai_addr, res->ai_addrlen); sa.length = (unsigned int)res->ai_addrlen; freeaddrinfo(res); ISC_LINK_INIT(&sa, link); ISC_LIST_INIT(servers); ISC_LIST_APPEND(servers, &sa, link); result = dns_client_setservers(client, dns_rdataclass_in, NULL, &servers); if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to set server: %d\n", result); exit(1); } /* Create the main task */ probe_task = NULL; result = isc_task_create(taskmgr, 0, &probe_task); if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to create task: %d\n", result); exit(1); } /* Open input file */ if (argc == 0) input = stdin; else { input = fopen(argv[0], "r"); if (input == NULL) { fprintf(stderr, "failed to open input file: %s\n", argv[0]); exit(1); } } /* Set up and start probe */ for (i = 0; i < MAX_PROBES; i++) { probes[i].inuse = ISC_FALSE; probes[i].domain = NULL; dns_fixedname_init(&probes[i].fixedname); probes[i].qname = NULL; probes[i].qlabel = qlabels; probes[i].qname_found = ISC_FALSE; probes[i].resid = NULL; ISC_LIST_INIT(probes[i].nslist); probes[i].reqid = NULL; probes[i].qmessage = NULL; result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &probes[i].qmessage); if (result == ISC_R_SUCCESS) { result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &probes[i].rmessage); } if (result != ISC_R_SUCCESS) { fprintf(stderr, "initialization failure\n"); exit(1); } } for (i = 0; i < MAX_PROBES; i++) { result = probe_domain(&probes[i]); if (result == ISC_R_NOMORE) break; else if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to issue an initial probe\n"); exit(1); } } /* Start event loop */ isc_app_ctxrun(actx); /* Dump results */ printf("Per domain results (out of %lu domains):\n", number_of_domains); printf(" valid: %lu\n" " ignore: %lu\n" " nxdomain: %lu\n" " othererr: %lu\n" " multiplesoa: %lu\n" " multiplecname: %lu\n" " brokenanswer: %lu\n" " lame: %lu\n" " unknown: %lu\n" " multiple errors: %lu\n", domain_stat.valid, domain_stat.ignore, domain_stat.nxdomain, domain_stat.othererr, domain_stat.multiplesoa, domain_stat.multiplecname, domain_stat.brokenanswer, domain_stat.lame, domain_stat.unknown, multiple_error_domains); printf("Per server results (out of %lu servers):\n", number_of_servers); printf(" valid: %lu\n" " ignore: %lu\n" " nxdomain: %lu\n" " othererr: %lu\n" " multiplesoa: %lu\n" " multiplecname: %lu\n" " brokenanswer: %lu\n" " lame: %lu\n" " unknown: %lu\n", server_stat.valid, server_stat.ignore, server_stat.nxdomain, server_stat.othererr, server_stat.multiplesoa, server_stat.multiplecname, server_stat.brokenanswer, server_stat.lame, server_stat.unknown); /* Cleanup */ for (i = 0; i < MAX_PROBES; i++) { dns_message_destroy(&probes[i].qmessage); dns_message_destroy(&probes[i].rmessage); } isc_task_detach(&probe_task); dns_client_destroy(&client); dns_lib_shutdown(); isc_app_ctxfinish(actx); ctxs_destroy(&mctx, &actx, &taskmgr, &socketmgr, &timermgr); return (0); } bind9-9.10.3.dfsg.P4/lib/samples/sample-update.c0000644000470500017500000004724012664710322020517 0ustar lamontlamont/* * Copyright (C) 2009, 2010, 2012-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: sample-update.c,v 1.10 2010/12/09 00:54:34 marka Exp $ */ #include #ifndef WIN32 #include #include #include #include #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static dns_tsec_t *tsec = NULL; static const dns_rdataclass_t default_rdataclass = dns_rdataclass_in; static isc_bufferlist_t usedbuffers; static ISC_LIST(dns_rdatalist_t) usedrdatalists; static void setup_tsec(char *keyfile, isc_mem_t *mctx); static void update_addordelete(isc_mem_t *mctx, char *cmdline, isc_boolean_t isdelete, dns_name_t *name); static void evaluate_prereq(isc_mem_t *mctx, char *cmdline, dns_name_t *name); ISC_PLATFORM_NORETURN_PRE static void usage(void) ISC_PLATFORM_NORETURN_POST; static void usage(void) { fprintf(stderr, "sample-update " "[-a auth_server] " "[-k keyfile] " "[-p prerequisite] " "[-r recursive_server] " "[-z zonename] " "(add|delete) \"name TTL RRtype RDATA\"\n"); exit(1); } int main(int argc, char *argv[]) { int ch; struct addrinfo hints, *res; int gai_error; dns_client_t *client = NULL; char *zonenamestr = NULL; char *keyfilename = NULL; char *prereqstr = NULL; isc_sockaddrlist_t auth_servers; char *auth_server = NULL; char *recursive_server = NULL; isc_sockaddr_t sa_auth, sa_recursive; isc_sockaddrlist_t rec_servers; isc_result_t result; isc_boolean_t isdelete; isc_buffer_t b, *buf; dns_fixedname_t zname0, pname0, uname0; unsigned int namelen; dns_name_t *zname = NULL, *uname, *pname; dns_rdataset_t *rdataset; dns_rdatalist_t *rdatalist; dns_rdata_t *rdata; dns_namelist_t updatelist, prereqlist, *prereqlistp = NULL; isc_mem_t *umctx = NULL; while ((ch = isc_commandline_parse(argc, argv, "a:k:p:r:z:")) != EOF) { switch (ch) { case 'k': keyfilename = isc_commandline_argument; break; case 'a': auth_server = isc_commandline_argument; break; case 'p': prereqstr = isc_commandline_argument; break; case 'r': recursive_server = isc_commandline_argument; break; case 'z': zonenamestr = isc_commandline_argument; break; default: usage(); } } argc -= isc_commandline_index; argv += isc_commandline_index; if (argc < 2) usage(); /* command line argument validation */ if (strcmp(argv[0], "delete") == 0) isdelete = ISC_TRUE; else if (strcmp(argv[0], "add") == 0) isdelete = ISC_FALSE; else { fprintf(stderr, "invalid update command: %s\n", argv[0]); exit(1); } if (auth_server == NULL && recursive_server == NULL) { fprintf(stderr, "authoritative or recursive server " "must be specified\n"); usage(); } /* Initialization */ ISC_LIST_INIT(usedbuffers); ISC_LIST_INIT(usedrdatalists); ISC_LIST_INIT(prereqlist); ISC_LIST_INIT(auth_servers); isc_lib_register(); result = dns_lib_init(); if (result != ISC_R_SUCCESS) { fprintf(stderr, "dns_lib_init failed: %d\n", result); exit(1); } result = isc_mem_create(0, 0, &umctx); if (result != ISC_R_SUCCESS) { fprintf(stderr, "failed to crate mctx\n"); exit(1); } result = dns_client_create(&client, 0); if (result != ISC_R_SUCCESS) { fprintf(stderr, "dns_client_create failed: %d\n", result); exit(1); } /* Set the authoritative server */ if (auth_server != NULL) { memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; #ifdef AI_NUMERICHOST hints.ai_flags = AI_NUMERICHOST; #endif gai_error = getaddrinfo(auth_server, "53", &hints, &res); if (gai_error != 0) { fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(gai_error)); exit(1); } INSIST(res->ai_addrlen <= sizeof(sa_auth.type)); memmove(&sa_auth.type, res->ai_addr, res->ai_addrlen); freeaddrinfo(res); sa_auth.length = (unsigned int)res->ai_addrlen; ISC_LINK_INIT(&sa_auth, link); ISC_LIST_APPEND(auth_servers, &sa_auth, link); } /* Set the recursive server */ if (recursive_server != NULL) { memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; #ifdef AI_NUMERICHOST hints.ai_flags = AI_NUMERICHOST; #endif gai_error = getaddrinfo(recursive_server, "53", &hints, &res); if (gai_error != 0) { fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(gai_error)); exit(1); } INSIST(res->ai_addrlen <= sizeof(sa_recursive.type)); memmove(&sa_recursive.type, res->ai_addr, res->ai_addrlen); freeaddrinfo(res); sa_recursive.length = (unsigned int)res->ai_addrlen; ISC_LINK_INIT(&sa_recursive, link); ISC_LIST_INIT(rec_servers); ISC_LIST_APPEND(rec_servers, &sa_recursive, link); result = dns_client_setservers(client, dns_rdataclass_in, NULL, &rec_servers); if (result != ISC_R_SUCCESS) { fprintf(stderr, "set server failed: %d\n", result); exit(1); } } /* Construct zone name */ zname = NULL; if (zonenamestr != NULL) { namelen = strlen(zonenamestr); isc_buffer_init(&b, zonenamestr, namelen); isc_buffer_add(&b, namelen); dns_fixedname_init(&zname0); zname = dns_fixedname_name(&zname0); result = dns_name_fromtext(zname, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) fprintf(stderr, "failed to convert zone name: %d\n", result); } /* Construct prerequisite name (if given) */ if (prereqstr != NULL) { dns_fixedname_init(&pname0); pname = dns_fixedname_name(&pname0); evaluate_prereq(umctx, prereqstr, pname); ISC_LIST_APPEND(prereqlist, pname, link); prereqlistp = &prereqlist; } /* Construct update name */ ISC_LIST_INIT(updatelist); dns_fixedname_init(&uname0); uname = dns_fixedname_name(&uname0); update_addordelete(umctx, argv[1], isdelete, uname); ISC_LIST_APPEND(updatelist, uname, link); /* Set up TSIG/SIG(0) key (if given) */ if (keyfilename != NULL) setup_tsec(keyfilename, umctx); /* Perform update */ result = dns_client_update(client, default_rdataclass, /* XXX: fixed */ zname, prereqlistp, &updatelist, (auth_server == NULL) ? NULL : &auth_servers, tsec, 0); if (result != ISC_R_SUCCESS) { fprintf(stderr, "update failed: %s\n", dns_result_totext(result)); } else fprintf(stderr, "update succeeded\n"); /* Cleanup */ while ((pname = ISC_LIST_HEAD(prereqlist)) != NULL) { while ((rdataset = ISC_LIST_HEAD(pname->list)) != NULL) { ISC_LIST_UNLINK(pname->list, rdataset, link); dns_rdataset_disassociate(rdataset); isc_mem_put(umctx, rdataset, sizeof(*rdataset)); } ISC_LIST_UNLINK(prereqlist, pname, link); } while ((uname = ISC_LIST_HEAD(updatelist)) != NULL) { while ((rdataset = ISC_LIST_HEAD(uname->list)) != NULL) { ISC_LIST_UNLINK(uname->list, rdataset, link); dns_rdataset_disassociate(rdataset); isc_mem_put(umctx, rdataset, sizeof(*rdataset)); } ISC_LIST_UNLINK(updatelist, uname, link); } while ((rdatalist = ISC_LIST_HEAD(usedrdatalists)) != NULL) { while ((rdata = ISC_LIST_HEAD(rdatalist->rdata)) != NULL) { ISC_LIST_UNLINK(rdatalist->rdata, rdata, link); isc_mem_put(umctx, rdata, sizeof(*rdata)); } ISC_LIST_UNLINK(usedrdatalists, rdatalist, link); isc_mem_put(umctx, rdatalist, sizeof(*rdatalist)); } while ((buf = ISC_LIST_HEAD(usedbuffers)) != NULL) { ISC_LIST_UNLINK(usedbuffers, buf, link); isc_buffer_free(&buf); } if (tsec != NULL) dns_tsec_destroy(&tsec); isc_mem_destroy(&umctx); dns_client_destroy(&client); dns_lib_shutdown(); return (0); } /* * Subroutines borrowed from nsupdate.c */ #define MAXWIRE (64 * 1024) #define TTL_MAX 2147483647U /* Maximum signed 32 bit integer. */ static char * nsu_strsep(char **stringp, const char *delim) { char *string = *stringp; char *s; const char *d; char sc, dc; if (string == NULL) return (NULL); for (; *string != '\0'; string++) { sc = *string; for (d = delim; (dc = *d) != '\0'; d++) { if (sc == dc) break; } if (dc == 0) break; } for (s = string; *s != '\0'; s++) { sc = *s; for (d = delim; (dc = *d) != '\0'; d++) { if (sc == dc) { *s++ = '\0'; *stringp = s; return (string); } } } *stringp = NULL; return (string); } static void fatal(const char *format, ...) { va_list args; va_start(args, format); vfprintf(stderr, format, args); va_end(args); fprintf(stderr, "\n"); exit(1); } static inline void check_result(isc_result_t result, const char *msg) { if (result != ISC_R_SUCCESS) fatal("%s: %s", msg, isc_result_totext(result)); } static void parse_name(char **cmdlinep, dns_name_t *name) { isc_result_t result; char *word; isc_buffer_t source; word = nsu_strsep(cmdlinep, " \t\r\n"); if (word == NULL || *word == 0) { fprintf(stderr, "could not read owner name\n"); exit(1); } isc_buffer_init(&source, word, strlen(word)); isc_buffer_add(&source, strlen(word)); result = dns_name_fromtext(name, &source, dns_rootname, 0, NULL); check_result(result, "dns_name_fromtext"); isc_buffer_invalidate(&source); } static void parse_rdata(isc_mem_t *mctx, char **cmdlinep, dns_rdataclass_t rdataclass, dns_rdatatype_t rdatatype, dns_rdata_t *rdata) { char *cmdline = *cmdlinep; isc_buffer_t source, *buf = NULL, *newbuf = NULL; isc_region_t r; isc_lex_t *lex = NULL; dns_rdatacallbacks_t callbacks; isc_result_t result; while (cmdline != NULL && *cmdline != 0 && isspace((unsigned char)*cmdline)) cmdline++; if (cmdline != NULL && *cmdline != 0) { dns_rdatacallbacks_init(&callbacks); result = isc_lex_create(mctx, strlen(cmdline), &lex); check_result(result, "isc_lex_create"); isc_buffer_init(&source, cmdline, strlen(cmdline)); isc_buffer_add(&source, strlen(cmdline)); result = isc_lex_openbuffer(lex, &source); check_result(result, "isc_lex_openbuffer"); result = isc_buffer_allocate(mctx, &buf, MAXWIRE); check_result(result, "isc_buffer_allocate"); result = dns_rdata_fromtext(rdata, rdataclass, rdatatype, lex, dns_rootname, 0, mctx, buf, &callbacks); isc_lex_destroy(&lex); if (result == ISC_R_SUCCESS) { isc_buffer_usedregion(buf, &r); result = isc_buffer_allocate(mctx, &newbuf, r.length); check_result(result, "isc_buffer_allocate"); isc_buffer_putmem(newbuf, r.base, r.length); isc_buffer_usedregion(newbuf, &r); dns_rdata_reset(rdata); dns_rdata_fromregion(rdata, rdataclass, rdatatype, &r); isc_buffer_free(&buf); ISC_LIST_APPEND(usedbuffers, newbuf, link); } else { fprintf(stderr, "invalid rdata format: %s\n", isc_result_totext(result)); isc_buffer_free(&buf); exit(1); } } else { rdata->flags = DNS_RDATA_UPDATE; } *cmdlinep = cmdline; } static void update_addordelete(isc_mem_t *mctx, char *cmdline, isc_boolean_t isdelete, dns_name_t *name) { isc_result_t result; isc_uint32_t ttl; char *word; dns_rdataclass_t rdataclass; dns_rdatatype_t rdatatype; dns_rdata_t *rdata = NULL; dns_rdatalist_t *rdatalist = NULL; dns_rdataset_t *rdataset = NULL; isc_textregion_t region; /* * Read the owner name. */ parse_name(&cmdline, name); rdata = isc_mem_get(mctx, sizeof(*rdata)); if (rdata == NULL) { fprintf(stderr, "memory allocation for rdata failed\n"); exit(1); } dns_rdata_init(rdata); /* * If this is an add, read the TTL and verify that it's in range. * If it's a delete, ignore a TTL if present (for compatibility). */ word = nsu_strsep(&cmdline, " \t\r\n"); if (word == NULL || *word == 0) { if (!isdelete) { fprintf(stderr, "could not read owner ttl\n"); exit(1); } else { ttl = 0; rdataclass = dns_rdataclass_any; rdatatype = dns_rdatatype_any; rdata->flags = DNS_RDATA_UPDATE; goto doneparsing; } } result = isc_parse_uint32(&ttl, word, 10); if (result != ISC_R_SUCCESS) { if (isdelete) { ttl = 0; goto parseclass; } else { fprintf(stderr, "ttl '%s': %s\n", word, isc_result_totext(result)); exit(1); } } if (isdelete) ttl = 0; else if (ttl > TTL_MAX) { fprintf(stderr, "ttl '%s' is out of range (0 to %u)\n", word, TTL_MAX); exit(1); } /* * Read the class or type. */ word = nsu_strsep(&cmdline, " \t\r\n"); parseclass: if (word == NULL || *word == 0) { if (isdelete) { rdataclass = dns_rdataclass_any; rdatatype = dns_rdatatype_any; rdata->flags = DNS_RDATA_UPDATE; goto doneparsing; } else { fprintf(stderr, "could not read class or type\n"); exit(1); } } region.base = word; region.length = strlen(word); result = dns_rdataclass_fromtext(&rdataclass, ®ion); if (result == ISC_R_SUCCESS) { /* * Now read the type. */ word = nsu_strsep(&cmdline, " \t\r\n"); if (word == NULL || *word == 0) { if (isdelete) { rdataclass = dns_rdataclass_any; rdatatype = dns_rdatatype_any; rdata->flags = DNS_RDATA_UPDATE; goto doneparsing; } else { fprintf(stderr, "could not read type\n"); exit(1); } } region.base = word; region.length = strlen(word); result = dns_rdatatype_fromtext(&rdatatype, ®ion); if (result != ISC_R_SUCCESS) { fprintf(stderr, "'%s' is not a valid type: %s\n", word, isc_result_totext(result)); exit(1); } } else { rdataclass = default_rdataclass; result = dns_rdatatype_fromtext(&rdatatype, ®ion); if (result != ISC_R_SUCCESS) { fprintf(stderr, "'%s' is not a valid class or type: " "%s\n", word, isc_result_totext(result)); exit(1); } } parse_rdata(mctx, &cmdline, rdataclass, rdatatype, rdata); if (isdelete) { if ((rdata->flags & DNS_RDATA_UPDATE) != 0) rdataclass = dns_rdataclass_any; else rdataclass = dns_rdataclass_none; } else { if ((rdata->flags & DNS_RDATA_UPDATE) != 0) { fprintf(stderr, "could not read rdata\n"); exit(1); } } doneparsing: rdatalist = isc_mem_get(mctx, sizeof(*rdatalist)); if (rdatalist == NULL) { fprintf(stderr, "memory allocation for rdatalist failed\n"); exit(1); } dns_rdatalist_init(rdatalist); rdatalist->type = rdatatype; rdatalist->rdclass = rdataclass; rdatalist->covers = rdatatype; rdatalist->ttl = (dns_ttl_t)ttl; ISC_LIST_INIT(rdatalist->rdata); ISC_LIST_APPEND(rdatalist->rdata, rdata, link); ISC_LIST_APPEND(usedrdatalists, rdatalist, link); rdataset = isc_mem_get(mctx, sizeof(*rdataset)); if (rdataset == NULL) { fprintf(stderr, "memory allocation for rdataset failed\n"); exit(1); } dns_rdataset_init(rdataset); dns_rdatalist_tordataset(rdatalist, rdataset); ISC_LIST_INIT(name->list); ISC_LIST_APPEND(name->list, rdataset, link); } static void make_prereq(isc_mem_t *mctx, char *cmdline, isc_boolean_t ispositive, isc_boolean_t isrrset, dns_name_t *name) { isc_result_t result; char *word; isc_textregion_t region; dns_rdataset_t *rdataset = NULL; dns_rdatalist_t *rdatalist = NULL; dns_rdataclass_t rdataclass; dns_rdatatype_t rdatatype; dns_rdata_t *rdata = NULL; /* * Read the owner name */ parse_name(&cmdline, name); /* * If this is an rrset prereq, read the class or type. */ if (isrrset) { word = nsu_strsep(&cmdline, " \t\r\n"); if (word == NULL || *word == 0) { fprintf(stderr, "could not read class or type\n"); exit(1); } region.base = word; region.length = strlen(word); result = dns_rdataclass_fromtext(&rdataclass, ®ion); if (result == ISC_R_SUCCESS) { /* * Now read the type. */ word = nsu_strsep(&cmdline, " \t\r\n"); if (word == NULL || *word == 0) { fprintf(stderr, "could not read type\n"); exit(1); } region.base = word; region.length = strlen(word); result = dns_rdatatype_fromtext(&rdatatype, ®ion); if (result != ISC_R_SUCCESS) { fprintf(stderr, "invalid type: %s\n", word); exit(1); } } else { rdataclass = default_rdataclass; result = dns_rdatatype_fromtext(&rdatatype, ®ion); if (result != ISC_R_SUCCESS) { fprintf(stderr, "invalid type: %s\n", word); exit(1); } } } else rdatatype = dns_rdatatype_any; rdata = isc_mem_get(mctx, sizeof(*rdata)); if (rdata == NULL) { fprintf(stderr, "memory allocation for rdata failed\n"); exit(1); } dns_rdata_init(rdata); if (isrrset && ispositive) parse_rdata(mctx, &cmdline, rdataclass, rdatatype, rdata); else rdata->flags = DNS_RDATA_UPDATE; rdatalist = isc_mem_get(mctx, sizeof(*rdatalist)); if (rdatalist == NULL) { fprintf(stderr, "memory allocation for rdatalist failed\n"); exit(1); } dns_rdatalist_init(rdatalist); rdatalist->type = rdatatype; if (ispositive) { if (isrrset && rdata->data != NULL) rdatalist->rdclass = rdataclass; else rdatalist->rdclass = dns_rdataclass_any; } else rdatalist->rdclass = dns_rdataclass_none; rdata->rdclass = rdatalist->rdclass; rdata->type = rdatatype; ISC_LIST_APPEND(rdatalist->rdata, rdata, link); ISC_LIST_APPEND(usedrdatalists, rdatalist, link); rdataset = isc_mem_get(mctx, sizeof(*rdataset)); if (rdataset == NULL) { fprintf(stderr, "memory allocation for rdataset failed\n"); exit(1); } dns_rdataset_init(rdataset); dns_rdatalist_tordataset(rdatalist, rdataset); ISC_LIST_INIT(name->list); ISC_LIST_APPEND(name->list, rdataset, link); } static void evaluate_prereq(isc_mem_t *mctx, char *cmdline, dns_name_t *name) { char *word; isc_boolean_t ispositive, isrrset; word = nsu_strsep(&cmdline, " \t\r\n"); if (word == NULL || *word == 0) { fprintf(stderr, "could not read operation code\n"); exit(1); } if (strcasecmp(word, "nxdomain") == 0) { ispositive = ISC_FALSE; isrrset = ISC_FALSE; } else if (strcasecmp(word, "yxdomain") == 0) { ispositive = ISC_TRUE; isrrset = ISC_FALSE; } else if (strcasecmp(word, "nxrrset") == 0) { ispositive = ISC_FALSE; isrrset = ISC_TRUE; } else if (strcasecmp(word, "yxrrset") == 0) { ispositive = ISC_TRUE; isrrset = ISC_TRUE; } else { fprintf(stderr, "incorrect operation code: %s\n", word); exit(1); } make_prereq(mctx, cmdline, ispositive, isrrset, name); } static void setup_tsec(char *keyfile, isc_mem_t *mctx) { dst_key_t *dstkey = NULL; isc_result_t result; dns_tsectype_t tsectype; result = dst_key_fromnamedfile(keyfile, NULL, DST_TYPE_PRIVATE | DST_TYPE_KEY, mctx, &dstkey); if (result != ISC_R_SUCCESS) { fprintf(stderr, "could not read key from %s: %s\n", keyfile, isc_result_totext(result)); exit(1); } if (dst_key_alg(dstkey) == DST_ALG_HMACMD5) tsectype = dns_tsectype_tsig; else tsectype = dns_tsectype_sig0; result = dns_tsec_create(mctx, tsectype, dstkey, &tsec); dst_key_free(&dstkey); if (result != ISC_R_SUCCESS) { fprintf(stderr, "could not create tsec: %s\n", isc_result_totext(result)); exit(1); } } bind9-9.10.3.dfsg.P4/lib/Makefile.in0000644000470500017500000000223112664710322016202 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012-2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001, 2003 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.21 2007/06/19 23:47:13 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ # Note: the order of SUBDIRS is important. # Attempt to disable parallel processing. .NOTPARALLEL: .NO_PARALLEL: SUBDIRS = isc isccc dns isccfg bind9 lwres irs tests samples TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/bind9/0002755000470500017500000000000012672612753015156 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/bind9/version.c0000644000470500017500000000217112664710322016776 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: version.c,v 1.8 2007/06/19 23:47:16 tbox Exp $ */ /*! \file */ #include const char bind9_version[] = VERSION; const unsigned int bind9_libinterface = LIBINTERFACE; const unsigned int bind9_librevision = LIBREVISION; const unsigned int bind9_libage = LIBAGE; bind9-9.10.3.dfsg.P4/lib/bind9/check.c0000644000470500017500000026476212664710322016406 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef ISC_PLATFORM_USESIT #ifdef AES_SIT #include #endif #ifdef HMAC_SHA1_SIT #include #endif #ifdef HMAC_SHA256_SIT #include #endif #endif #include #include #include #include #include #include #include #include #include static isc_result_t fileexist(const cfg_obj_t *obj, isc_symtab_t *symtab, isc_boolean_t writeable, isc_log_t *logctxlogc); static void freekey(char *key, unsigned int type, isc_symvalue_t value, void *userarg) { UNUSED(type); UNUSED(value); isc_mem_free(userarg, key); } static isc_result_t check_orderent(const cfg_obj_t *ent, isc_log_t *logctx) { isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; isc_textregion_t r; dns_fixedname_t fixed; const cfg_obj_t *obj; dns_rdataclass_t rdclass; dns_rdatatype_t rdtype; isc_buffer_t b; const char *str; dns_fixedname_init(&fixed); obj = cfg_tuple_get(ent, "class"); if (cfg_obj_isstring(obj)) { DE_CONST(cfg_obj_asstring(obj), r.base); r.length = strlen(r.base); tresult = dns_rdataclass_fromtext(&rdclass, &r); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "rrset-order: invalid class '%s'", r.base); result = ISC_R_FAILURE; } } obj = cfg_tuple_get(ent, "type"); if (cfg_obj_isstring(obj)) { DE_CONST(cfg_obj_asstring(obj), r.base); r.length = strlen(r.base); tresult = dns_rdatatype_fromtext(&rdtype, &r); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "rrset-order: invalid type '%s'", r.base); result = ISC_R_FAILURE; } } obj = cfg_tuple_get(ent, "name"); if (cfg_obj_isstring(obj)) { str = cfg_obj_asstring(obj); isc_buffer_constinit(&b, str, strlen(str)); isc_buffer_add(&b, strlen(str)); tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b, dns_rootname, 0, NULL); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "rrset-order: invalid name '%s'", str); result = ISC_R_FAILURE; } } obj = cfg_tuple_get(ent, "order"); if (!cfg_obj_isstring(obj) || strcasecmp("order", cfg_obj_asstring(obj)) != 0) { cfg_obj_log(ent, logctx, ISC_LOG_ERROR, "rrset-order: keyword 'order' missing"); result = ISC_R_FAILURE; } obj = cfg_tuple_get(ent, "ordering"); if (!cfg_obj_isstring(obj)) { cfg_obj_log(ent, logctx, ISC_LOG_ERROR, "rrset-order: missing ordering"); result = ISC_R_FAILURE; } else if (strcasecmp(cfg_obj_asstring(obj), "fixed") == 0) { #if !DNS_RDATASET_FIXED cfg_obj_log(obj, logctx, ISC_LOG_WARNING, "rrset-order: order 'fixed' was disabled at " "compilation time"); #endif } else if (strcasecmp(cfg_obj_asstring(obj), "random") != 0 && strcasecmp(cfg_obj_asstring(obj), "cyclic") != 0) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "rrset-order: invalid order '%s'", cfg_obj_asstring(obj)); result = ISC_R_FAILURE; } return (result); } static isc_result_t check_order(const cfg_obj_t *options, isc_log_t *logctx) { isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; const cfg_listelt_t *element; const cfg_obj_t *obj = NULL; if (cfg_map_get(options, "rrset-order", &obj) != ISC_R_SUCCESS) return (result); for (element = cfg_list_first(obj); element != NULL; element = cfg_list_next(element)) { tresult = check_orderent(cfg_listelt_value(element), logctx); if (tresult != ISC_R_SUCCESS) result = tresult; } return (result); } static isc_result_t check_dual_stack(const cfg_obj_t *options, isc_log_t *logctx) { const cfg_listelt_t *element; const cfg_obj_t *alternates = NULL; const cfg_obj_t *value; const cfg_obj_t *obj; const char *str; dns_fixedname_t fixed; dns_name_t *name; isc_buffer_t buffer; isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; (void)cfg_map_get(options, "dual-stack-servers", &alternates); if (alternates == NULL) return (ISC_R_SUCCESS); obj = cfg_tuple_get(alternates, "port"); if (cfg_obj_isuint32(obj)) { isc_uint32_t val = cfg_obj_asuint32(obj); if (val > ISC_UINT16_MAX) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "port '%u' out of range", val); result = ISC_R_FAILURE; } } obj = cfg_tuple_get(alternates, "addresses"); for (element = cfg_list_first(obj); element != NULL; element = cfg_list_next(element)) { value = cfg_listelt_value(element); if (cfg_obj_issockaddr(value)) continue; obj = cfg_tuple_get(value, "name"); str = cfg_obj_asstring(obj); isc_buffer_constinit(&buffer, str, strlen(str)); isc_buffer_add(&buffer, strlen(str)); dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); tresult = dns_name_fromtext(name, &buffer, dns_rootname, 0, NULL); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "bad name '%s'", str); result = ISC_R_FAILURE; } obj = cfg_tuple_get(value, "port"); if (cfg_obj_isuint32(obj)) { isc_uint32_t val = cfg_obj_asuint32(obj); if (val > ISC_UINT16_MAX) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "port '%u' out of range", val); result = ISC_R_FAILURE; } } } return (result); } static isc_result_t check_forward(const cfg_obj_t *options, const cfg_obj_t *global, isc_log_t *logctx) { const cfg_obj_t *forward = NULL; const cfg_obj_t *forwarders = NULL; (void)cfg_map_get(options, "forward", &forward); (void)cfg_map_get(options, "forwarders", &forwarders); if (forwarders != NULL && global != NULL) { const char *file = cfg_obj_file(global); unsigned int line = cfg_obj_line(global); cfg_obj_log(forwarders, logctx, ISC_LOG_ERROR, "forwarders declared in root zone and " "in general configuration: %s:%u", file, line); return (ISC_R_FAILURE); } if (forward != NULL && forwarders == NULL) { cfg_obj_log(forward, logctx, ISC_LOG_ERROR, "no matching 'forwarders' statement"); return (ISC_R_FAILURE); } return (ISC_R_SUCCESS); } static isc_result_t disabled_algorithms(const cfg_obj_t *disabled, isc_log_t *logctx) { isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; const cfg_listelt_t *element; const char *str; isc_buffer_t b; dns_fixedname_t fixed; dns_name_t *name; const cfg_obj_t *obj; dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); obj = cfg_tuple_get(disabled, "name"); str = cfg_obj_asstring(obj); isc_buffer_constinit(&b, str, strlen(str)); isc_buffer_add(&b, strlen(str)); tresult = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "bad domain name '%s'", str); result = tresult; } obj = cfg_tuple_get(disabled, "algorithms"); for (element = cfg_list_first(obj); element != NULL; element = cfg_list_next(element)) { isc_textregion_t r; dns_secalg_t alg; DE_CONST(cfg_obj_asstring(cfg_listelt_value(element)), r.base); r.length = strlen(r.base); tresult = dns_secalg_fromtext(&alg, &r); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(cfg_listelt_value(element), logctx, ISC_LOG_ERROR, "invalid algorithm '%s'", r.base); result = tresult; } } return (result); } static isc_result_t disabled_ds_digests(const cfg_obj_t *disabled, isc_log_t *logctx) { isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; const cfg_listelt_t *element; const char *str; isc_buffer_t b; dns_fixedname_t fixed; dns_name_t *name; const cfg_obj_t *obj; dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); obj = cfg_tuple_get(disabled, "name"); str = cfg_obj_asstring(obj); isc_buffer_constinit(&b, str, strlen(str)); isc_buffer_add(&b, strlen(str)); tresult = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "bad domain name '%s'", str); result = tresult; } obj = cfg_tuple_get(disabled, "digests"); for (element = cfg_list_first(obj); element != NULL; element = cfg_list_next(element)) { isc_textregion_t r; dns_dsdigest_t digest; DE_CONST(cfg_obj_asstring(cfg_listelt_value(element)), r.base); r.length = strlen(r.base); /* works with a numeric argument too */ tresult = dns_dsdigest_fromtext(&digest, &r); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(cfg_listelt_value(element), logctx, ISC_LOG_ERROR, "invalid digest type '%s'", r.base); result = tresult; } } return (result); } static isc_result_t nameexist(const cfg_obj_t *obj, const char *name, int value, isc_symtab_t *symtab, const char *fmt, isc_log_t *logctx, isc_mem_t *mctx) { char *key; const char *file; unsigned int line; isc_result_t result; isc_symvalue_t symvalue; key = isc_mem_strdup(mctx, name); if (key == NULL) return (ISC_R_NOMEMORY); symvalue.as_cpointer = obj; result = isc_symtab_define(symtab, key, value, symvalue, isc_symexists_reject); if (result == ISC_R_EXISTS) { RUNTIME_CHECK(isc_symtab_lookup(symtab, key, value, &symvalue) == ISC_R_SUCCESS); file = cfg_obj_file(symvalue.as_cpointer); line = cfg_obj_line(symvalue.as_cpointer); if (file == NULL) file = ""; cfg_obj_log(obj, logctx, ISC_LOG_ERROR, fmt, key, file, line); isc_mem_free(mctx, key); result = ISC_R_EXISTS; } else if (result != ISC_R_SUCCESS) { isc_mem_free(mctx, key); } return (result); } static isc_result_t mustbesecure(const cfg_obj_t *secure, isc_symtab_t *symtab, isc_log_t *logctx, isc_mem_t *mctx) { const cfg_obj_t *obj; char namebuf[DNS_NAME_FORMATSIZE]; const char *str; dns_fixedname_t fixed; dns_name_t *name; isc_buffer_t b; isc_result_t result = ISC_R_SUCCESS; dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); obj = cfg_tuple_get(secure, "name"); str = cfg_obj_asstring(obj); isc_buffer_constinit(&b, str, strlen(str)); isc_buffer_add(&b, strlen(str)); result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "bad domain name '%s'", str); } else { dns_name_format(name, namebuf, sizeof(namebuf)); result = nameexist(secure, namebuf, 1, symtab, "dnssec-must-be-secure '%s': already " "exists previous definition: %s:%u", logctx, mctx); } return (result); } static isc_result_t checkacl(const char *aclname, cfg_aclconfctx_t *actx, const cfg_obj_t *zconfig, const cfg_obj_t *voptions, const cfg_obj_t *config, isc_log_t *logctx, isc_mem_t *mctx) { isc_result_t result; const cfg_obj_t *aclobj = NULL; const cfg_obj_t *options; dns_acl_t *acl = NULL; if (zconfig != NULL) { options = cfg_tuple_get(zconfig, "options"); cfg_map_get(options, aclname, &aclobj); } if (voptions != NULL && aclobj == NULL) cfg_map_get(voptions, aclname, &aclobj); if (config != NULL && aclobj == NULL) { options = NULL; cfg_map_get(config, "options", &options); if (options != NULL) cfg_map_get(options, aclname, &aclobj); } if (aclobj == NULL) return (ISC_R_SUCCESS); result = cfg_acl_fromconfig(aclobj, config, logctx, actx, mctx, 0, &acl); if (acl != NULL) dns_acl_detach(&acl); return (result); } static isc_result_t check_viewacls(cfg_aclconfctx_t *actx, const cfg_obj_t *voptions, const cfg_obj_t *config, isc_log_t *logctx, isc_mem_t *mctx) { isc_result_t result = ISC_R_SUCCESS, tresult; int i = 0; static const char *acls[] = { "allow-query", "allow-query-on", "allow-query-cache", "allow-query-cache-on", "blackhole", "match-clients", "match-destinations", "sortlist", "filter-aaaa", NULL }; while (acls[i] != NULL) { tresult = checkacl(acls[i++], actx, NULL, voptions, config, logctx, mctx); if (tresult != ISC_R_SUCCESS) result = tresult; } return (result); } static const unsigned char zeros[16]; static isc_result_t check_dns64(cfg_aclconfctx_t *actx, const cfg_obj_t *voptions, const cfg_obj_t *config, isc_log_t *logctx, isc_mem_t *mctx) { isc_result_t result = ISC_R_SUCCESS; const cfg_obj_t *dns64 = NULL; const cfg_obj_t *options; const cfg_listelt_t *element; const cfg_obj_t *map, *obj; isc_netaddr_t na, sa; unsigned int prefixlen; int nbytes; int i; static const char *acls[] = { "clients", "exclude", "mapped", NULL}; if (voptions != NULL) cfg_map_get(voptions, "dns64", &dns64); if (config != NULL && dns64 == NULL) { options = NULL; cfg_map_get(config, "options", &options); if (options != NULL) cfg_map_get(options, "dns64", &dns64); } if (dns64 == NULL) return (ISC_R_SUCCESS); for (element = cfg_list_first(dns64); element != NULL; element = cfg_list_next(element)) { map = cfg_listelt_value(element); obj = cfg_map_getname(map); cfg_obj_asnetprefix(obj, &na, &prefixlen); if (na.family != AF_INET6) { cfg_obj_log(map, logctx, ISC_LOG_ERROR, "dns64 requires a IPv6 prefix"); result = ISC_R_FAILURE; continue; } if (prefixlen != 32 && prefixlen != 40 && prefixlen != 48 && prefixlen != 56 && prefixlen != 64 && prefixlen != 96) { cfg_obj_log(map, logctx, ISC_LOG_ERROR, "bad prefix length %u [32/40/48/56/64/96]", prefixlen); result = ISC_R_FAILURE; continue; } for (i = 0; acls[i] != NULL; i++) { obj = NULL; (void)cfg_map_get(map, acls[i], &obj); if (obj != NULL) { dns_acl_t *acl = NULL; isc_result_t tresult; tresult = cfg_acl_fromconfig(obj, config, logctx, actx, mctx, 0, &acl); if (acl != NULL) dns_acl_detach(&acl); if (tresult != ISC_R_SUCCESS) result = tresult; } } obj = NULL; (void)cfg_map_get(map, "suffix", &obj); if (obj != NULL) { isc_netaddr_fromsockaddr(&sa, cfg_obj_assockaddr(obj)); if (sa.family != AF_INET6) { cfg_obj_log(map, logctx, ISC_LOG_ERROR, "dns64 requires a IPv6 suffix"); result = ISC_R_FAILURE; continue; } nbytes = prefixlen / 8 + 4; if (prefixlen >= 32 && prefixlen <= 64) nbytes++; if (memcmp(sa.type.in6.s6_addr, zeros, nbytes) != 0) { char netaddrbuf[ISC_NETADDR_FORMATSIZE]; isc_netaddr_format(&sa, netaddrbuf, sizeof(netaddrbuf)); cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "bad suffix '%s' leading " "%u octets not zeros", netaddrbuf, nbytes); result = ISC_R_FAILURE; } } } return (result); } /* * Check allow-recursion and allow-recursion-on acls, and also log a * warning if they're inconsistent with the "recursion" option. */ static isc_result_t check_recursionacls(cfg_aclconfctx_t *actx, const cfg_obj_t *voptions, const char *viewname, const cfg_obj_t *config, isc_log_t *logctx, isc_mem_t *mctx) { const cfg_obj_t *options, *aclobj, *obj = NULL; dns_acl_t *acl = NULL; isc_result_t result = ISC_R_SUCCESS, tresult; isc_boolean_t recursion; const char *forview = " for view "; int i = 0; static const char *acls[] = { "allow-recursion", "allow-recursion-on", NULL }; if (voptions != NULL) cfg_map_get(voptions, "recursion", &obj); if (obj == NULL && config != NULL) { options = NULL; cfg_map_get(config, "options", &options); if (options != NULL) cfg_map_get(options, "recursion", &obj); } if (obj == NULL) recursion = ISC_TRUE; else recursion = cfg_obj_asboolean(obj); if (viewname == NULL) { viewname = ""; forview = ""; } for (i = 0; acls[i] != NULL; i++) { aclobj = options = NULL; acl = NULL; if (voptions != NULL) cfg_map_get(voptions, acls[i], &aclobj); if (config != NULL && aclobj == NULL) { options = NULL; cfg_map_get(config, "options", &options); if (options != NULL) cfg_map_get(options, acls[i], &aclobj); } if (aclobj == NULL) continue; tresult = cfg_acl_fromconfig(aclobj, config, logctx, actx, mctx, 0, &acl); if (tresult != ISC_R_SUCCESS) result = tresult; if (acl == NULL) continue; if (recursion == ISC_FALSE && !dns_acl_isnone(acl)) { cfg_obj_log(aclobj, logctx, ISC_LOG_WARNING, "both \"recursion no;\" and " "\"%s\" active%s%s", acls[i], forview, viewname); } if (acl != NULL) dns_acl_detach(&acl); } return (result); } static isc_result_t check_filteraaaa(cfg_aclconfctx_t *actx, const cfg_obj_t *voptions, const char *viewname, const cfg_obj_t *config, isc_log_t *logctx, isc_mem_t *mctx) { const cfg_obj_t *options, *aclobj, *obj; dns_acl_t *acl = NULL; isc_result_t result = ISC_R_SUCCESS; dns_aaaa_t filter4, filter6; const char *forview = " for view "; if (viewname == NULL) { viewname = ""; forview = ""; } aclobj = options = NULL; acl = NULL; if (voptions != NULL) cfg_map_get(voptions, "filter-aaaa", &aclobj); if (config != NULL && aclobj == NULL) { options = NULL; cfg_map_get(config, "options", &options); if (options != NULL) cfg_map_get(options, "filter-aaaa", &aclobj); } if (aclobj == NULL) return (result); result = cfg_acl_fromconfig(aclobj, config, logctx, actx, mctx, 0, &acl); if (result != ISC_R_SUCCESS) goto failure; obj = NULL; if (voptions != NULL) cfg_map_get(voptions, "filter-aaaa-on-v4", &obj); if (obj == NULL && config != NULL) { options = NULL; cfg_map_get(config, "options", &options); if (options != NULL) cfg_map_get(options, "filter-aaaa-on-v4", &obj); } if (obj == NULL) filter4 = dns_aaaa_ok; /* default */ else if (cfg_obj_isboolean(obj)) filter4 = cfg_obj_asboolean(obj) ? dns_aaaa_filter : dns_aaaa_ok; else filter4 = dns_aaaa_break_dnssec; /* break-dnssec */ obj = NULL; if (voptions != NULL) cfg_map_get(voptions, "filter-aaaa-on-v6", &obj); if (obj == NULL && config != NULL) { options = NULL; cfg_map_get(config, "options", &options); if (options != NULL) cfg_map_get(options, "filter-aaaa-on-v6", &obj); } if (obj == NULL) filter6 = dns_aaaa_ok; /* default */ else if (cfg_obj_isboolean(obj)) filter6 = cfg_obj_asboolean(obj) ? dns_aaaa_filter : dns_aaaa_ok; else filter6 = dns_aaaa_break_dnssec; /* break-dnssec */ if ((filter4 != dns_aaaa_ok || filter6 != dns_aaaa_ok) && dns_acl_isnone(acl)) { cfg_obj_log(aclobj, logctx, ISC_LOG_WARNING, "\"filter-aaaa\" is 'none;' but " "either filter-aaaa-on-v4 or filter-aaaa-on-v6 " "is enabled%s%s", forview, viewname); result = ISC_R_FAILURE; } else if (filter4 == dns_aaaa_ok && filter6 == dns_aaaa_ok && !dns_acl_isnone(acl)) { cfg_obj_log(aclobj, logctx, ISC_LOG_WARNING, "\"filter-aaaa\" is set but " "neither filter-aaaa-on-v4 or filter-aaaa-on-v6 " "is enabled%s%s", forview, viewname); result = ISC_R_FAILURE; } failure: if (acl != NULL) dns_acl_detach(&acl); return (result); } typedef struct { const char *name; unsigned int scale; unsigned int max; } intervaltable; typedef enum { optlevel_config, optlevel_options, optlevel_view, optlevel_zone } optlevel_t; static isc_result_t check_dscp(const cfg_obj_t *options, isc_log_t *logctx) { isc_result_t result = ISC_R_SUCCESS; const cfg_obj_t *obj = NULL; /* * Check that DSCP setting is within range */ obj = NULL; (void)cfg_map_get(options, "dscp", &obj); if (obj != NULL) { isc_uint32_t dscp = cfg_obj_asuint32(obj); if (dscp >= 64) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "'dscp' out of range (0-63)"); result = ISC_R_FAILURE; } } return (result); } static isc_result_t check_name(const char *str) { dns_fixedname_t fixed; dns_fixedname_init(&fixed); return (dns_name_fromstring(dns_fixedname_name(&fixed), str, 0, NULL)); } static isc_result_t check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, optlevel_t optlevel) { isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; unsigned int i; const cfg_obj_t *obj = NULL; const cfg_obj_t *resignobj = NULL; const cfg_listelt_t *element; isc_symtab_t *symtab = NULL; dns_fixedname_t fixed; const char *str; dns_name_t *name; #ifdef ISC_PLATFORM_USESIT isc_buffer_t b; #endif static intervaltable intervals[] = { { "cleaning-interval", 60, 28 * 24 * 60 }, /* 28 days */ { "heartbeat-interval", 60, 28 * 24 * 60 }, /* 28 days */ { "interface-interval", 60, 28 * 24 * 60 }, /* 28 days */ { "max-transfer-idle-in", 60, 28 * 24 * 60 }, /* 28 days */ { "max-transfer-idle-out", 60, 28 * 24 * 60 }, /* 28 days */ { "max-transfer-time-in", 60, 28 * 24 * 60 }, /* 28 days */ { "max-transfer-time-out", 60, 28 * 24 * 60 }, /* 28 days */ { "statistics-interval", 60, 28 * 24 * 60 }, /* 28 days */ }; static const char *server_contact[] = { "empty-server", "empty-contact", "dns64-server", "dns64-contact", NULL }; /* * Check that fields specified in units of time other than seconds * have reasonable values. */ for (i = 0; i < sizeof(intervals) / sizeof(intervals[0]); i++) { isc_uint32_t val; obj = NULL; (void)cfg_map_get(options, intervals[i].name, &obj); if (obj == NULL) continue; val = cfg_obj_asuint32(obj); if (val > intervals[i].max) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "%s '%u' is out of range (0..%u)", intervals[i].name, val, intervals[i].max); result = ISC_R_RANGE; } else if (val > (ISC_UINT32_MAX / intervals[i].scale)) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "%s '%d' is out of range", intervals[i].name, val); result = ISC_R_RANGE; } } obj = NULL; cfg_map_get(options, "max-rsa-exponent-size", &obj); if (obj != NULL) { isc_uint32_t val; val = cfg_obj_asuint32(obj); if (val != 0 && (val < 35 || val > 4096)) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "max-rsa-exponent-size '%u' is out of " "range (35..4096)", val); result = ISC_R_RANGE; } } obj = NULL; cfg_map_get(options, "sig-validity-interval", &obj); if (obj != NULL) { isc_uint32_t validity, resign = 0; validity = cfg_obj_asuint32(cfg_tuple_get(obj, "validity")); resignobj = cfg_tuple_get(obj, "re-sign"); if (!cfg_obj_isvoid(resignobj)) resign = cfg_obj_asuint32(resignobj); if (validity > 3660 || validity == 0) { /* 10 years */ cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "%s '%u' is out of range (1..3660)", "sig-validity-interval", validity); result = ISC_R_RANGE; } if (!cfg_obj_isvoid(resignobj)) { if (resign > 3660 || resign == 0) { /* 10 years */ cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "%s '%u' is out of range (1..3660)", "sig-validity-interval (re-sign)", validity); result = ISC_R_RANGE; } else if ((validity > 7 && validity < resign) || (validity <= 7 && validity * 24 < resign)) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "validity interval (%u days) " "less than re-signing interval " "(%u %s)", validity, resign, (validity > 7) ? "days" : "hours"); result = ISC_R_RANGE; } } } obj = NULL; (void)cfg_map_get(options, "preferred-glue", &obj); if (obj != NULL) { str = cfg_obj_asstring(obj); if (strcasecmp(str, "a") != 0 && strcasecmp(str, "aaaa") != 0 && strcasecmp(str, "none") != 0) cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "preferred-glue unexpected value '%s'", str); } obj = NULL; (void)cfg_map_get(options, "root-delegation-only", &obj); if (obj != NULL) { if (!cfg_obj_isvoid(obj)) { for (element = cfg_list_first(obj); element != NULL; element = cfg_list_next(element)) { const cfg_obj_t *exclude; exclude = cfg_listelt_value(element); str = cfg_obj_asstring(exclude); tresult = check_name(str); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "bad domain name '%s'", str); result = tresult; } } } } /* * Set supported DNSSEC algorithms. */ obj = NULL; (void)cfg_map_get(options, "disable-algorithms", &obj); if (obj != NULL) { for (element = cfg_list_first(obj); element != NULL; element = cfg_list_next(element)) { obj = cfg_listelt_value(element); tresult = disabled_algorithms(obj, logctx); if (tresult != ISC_R_SUCCESS) result = tresult; } } /* * Set supported DS/DLV digest types. */ obj = NULL; (void)cfg_map_get(options, "disable-ds-digests", &obj); if (obj != NULL) { for (element = cfg_list_first(obj); element != NULL; element = cfg_list_next(element)) { obj = cfg_listelt_value(element); tresult = disabled_ds_digests(obj, logctx); if (tresult != ISC_R_SUCCESS) result = tresult; } } dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); /* * Check the DLV zone name. */ obj = NULL; (void)cfg_map_get(options, "dnssec-lookaside", &obj); if (obj != NULL) { tresult = isc_symtab_create(mctx, 100, freekey, mctx, ISC_FALSE, &symtab); if (tresult != ISC_R_SUCCESS) result = tresult; for (element = cfg_list_first(obj); element != NULL; element = cfg_list_next(element)) { const char *dlv; const cfg_obj_t *dlvobj, *anchor; obj = cfg_listelt_value(element); anchor = cfg_tuple_get(obj, "trust-anchor"); dlvobj = cfg_tuple_get(obj, "domain"); dlv = cfg_obj_asstring(dlvobj); /* * If domain is "auto" or "no" and trust anchor * is missing, skip remaining tests */ if (cfg_obj_isvoid(anchor)) { if (!strcasecmp(dlv, "no") || !strcasecmp(dlv, "auto")) continue; } tresult = dns_name_fromstring(name, dlv, 0, NULL); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "bad domain name '%s'", dlv); result = tresult; continue; } if (symtab != NULL) { tresult = nameexist(obj, dlv, 1, symtab, "dnssec-lookaside '%s': " "already exists previous " "definition: %s:%u", logctx, mctx); if (tresult != ISC_R_SUCCESS && result == ISC_R_SUCCESS) result = tresult; } /* * XXXMPA to be removed when multiple lookaside * namespaces are supported. */ if (!dns_name_equal(dns_rootname, name)) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "dnssec-lookaside '%s': " "non-root not yet supported", dlv); if (result == ISC_R_SUCCESS) result = ISC_R_FAILURE; } if (!cfg_obj_isvoid(anchor)) { dlv = cfg_obj_asstring(anchor); tresult = check_name(dlv); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "bad domain name '%s'", dlv); if (result == ISC_R_SUCCESS) result = tresult; } } else { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "dnssec-lookaside requires " "either 'auto' or 'no', or a " "domain and trust anchor"); if (result == ISC_R_SUCCESS) result = ISC_R_FAILURE; } } if (symtab != NULL) isc_symtab_destroy(&symtab); } /* * Check auto-dnssec at the view/options level */ obj = NULL; (void)cfg_map_get(options, "auto-dnssec", &obj); if (obj != NULL) { const char *arg = cfg_obj_asstring(obj); if (optlevel != optlevel_zone && strcasecmp(arg, "off") != 0) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "auto-dnssec may only be activated at the " "zone level"); result = ISC_R_FAILURE; } } /* * Check dnssec-must-be-secure. */ obj = NULL; (void)cfg_map_get(options, "dnssec-must-be-secure", &obj); if (obj != NULL) { tresult = isc_symtab_create(mctx, 100, freekey, mctx, ISC_FALSE, &symtab); if (tresult != ISC_R_SUCCESS) result = tresult; for (element = cfg_list_first(obj); element != NULL; element = cfg_list_next(element)) { obj = cfg_listelt_value(element); tresult = mustbesecure(obj, symtab, logctx, mctx); if (tresult != ISC_R_SUCCESS) result = tresult; } if (symtab != NULL) isc_symtab_destroy(&symtab); } /* * Check server/contacts for syntactic validity. */ for (i= 0; server_contact[i] != NULL; i++) { obj = NULL; (void)cfg_map_get(options, server_contact[i], &obj); if (obj != NULL) { str = cfg_obj_asstring(obj); if (check_name(str) != ISC_R_SUCCESS) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "%s: invalid name '%s'", server_contact[i], str); result = ISC_R_FAILURE; } } } /* * Check empty zone configuration. */ obj = NULL; (void)cfg_map_get(options, "disable-empty-zone", &obj); for (element = cfg_list_first(obj); element != NULL; element = cfg_list_next(element)) { obj = cfg_listelt_value(element); str = cfg_obj_asstring(obj); if (check_name(str) != ISC_R_SUCCESS) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "disable-empty-zone: invalid name '%s'", str); result = ISC_R_FAILURE; } } /* * Check that server-id is not too long. * 1024 bytes should be big enough. */ obj = NULL; (void)cfg_map_get(options, "server-id", &obj); if (obj != NULL && cfg_obj_isstring(obj) && strlen(cfg_obj_asstring(obj)) > 1024U) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "'server-id' too big (>1024 bytes)"); result = ISC_R_FAILURE; } tresult = check_dscp(options, logctx); if (tresult != ISC_R_SUCCESS) result = tresult; #ifdef ISC_PLATFORM_USESIT obj = NULL; (void) cfg_map_get(options, "sit-secret", &obj); if (obj != NULL) { unsigned char secret[32]; memset(secret, 0, sizeof(secret)); isc_buffer_init(&b, secret, sizeof(secret)); tresult = isc_hex_decodestring(cfg_obj_asstring(obj), &b); if (tresult == ISC_R_NOSPACE) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "sit-secret: too long"); } else if (tresult != ISC_R_SUCCESS) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "sit-secret: invalid hex string"); } if (tresult != ISC_R_SUCCESS) result = tresult; #ifdef AES_SIT if (tresult == ISC_R_SUCCESS && isc_buffer_usedlength(&b) != ISC_AES128_KEYLENGTH) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "AES sit-secret must be on 128 bits"); result = ISC_R_RANGE; } #endif #ifdef HMAC_SHA1_SIT if (tresult == ISC_R_SUCCESS && isc_buffer_usedlength(&b) != ISC_SHA1_DIGESTLENGTH) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "SHA1 sit-secret must be on 160 bits"); result = ISC_R_RANGE; } #endif #ifdef HMAC_SHA256_SIT if (tresult == ISC_R_SUCCESS && isc_buffer_usedlength(&b) != ISC_SHA256_DIGESTLENGTH) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "SHA256 sit-secret must be on 256 bits"); result = ISC_R_RANGE; } #endif } #endif return (result); } static isc_result_t get_masters_def(const cfg_obj_t *cctx, const char *name, const cfg_obj_t **ret) { isc_result_t result; const cfg_obj_t *masters = NULL; const cfg_listelt_t *elt; result = cfg_map_get(cctx, "masters", &masters); if (result != ISC_R_SUCCESS) return (result); for (elt = cfg_list_first(masters); elt != NULL; elt = cfg_list_next(elt)) { const cfg_obj_t *list; const char *listname; list = cfg_listelt_value(elt); listname = cfg_obj_asstring(cfg_tuple_get(list, "name")); if (strcasecmp(listname, name) == 0) { *ret = list; return (ISC_R_SUCCESS); } } return (ISC_R_NOTFOUND); } static isc_result_t validate_masters(const cfg_obj_t *obj, const cfg_obj_t *config, isc_uint32_t *countp, isc_log_t *logctx, isc_mem_t *mctx) { isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; isc_uint32_t count = 0; isc_symtab_t *symtab = NULL; isc_symvalue_t symvalue; const cfg_listelt_t *element; const cfg_listelt_t **stack = NULL; isc_uint32_t stackcount = 0, pushed = 0; const cfg_obj_t *list; REQUIRE(countp != NULL); result = isc_symtab_create(mctx, 100, NULL, NULL, ISC_FALSE, &symtab); if (result != ISC_R_SUCCESS) { *countp = count; return (result); } newlist: list = cfg_tuple_get(obj, "addresses"); element = cfg_list_first(list); resume: for ( ; element != NULL; element = cfg_list_next(element)) { const char *listname; const cfg_obj_t *addr; const cfg_obj_t *key; addr = cfg_tuple_get(cfg_listelt_value(element), "masterselement"); key = cfg_tuple_get(cfg_listelt_value(element), "key"); if (cfg_obj_issockaddr(addr)) { count++; continue; } if (!cfg_obj_isvoid(key)) { cfg_obj_log(key, logctx, ISC_LOG_ERROR, "unexpected token '%s'", cfg_obj_asstring(key)); if (result == ISC_R_SUCCESS) result = ISC_R_FAILURE; } listname = cfg_obj_asstring(addr); symvalue.as_cpointer = addr; tresult = isc_symtab_define(symtab, listname, 1, symvalue, isc_symexists_reject); if (tresult == ISC_R_EXISTS) continue; tresult = get_masters_def(config, listname, &obj); if (tresult != ISC_R_SUCCESS) { if (result == ISC_R_SUCCESS) result = tresult; cfg_obj_log(addr, logctx, ISC_LOG_ERROR, "unable to find masters list '%s'", listname); continue; } /* Grow stack? */ if (stackcount == pushed) { void * new; isc_uint32_t newlen = stackcount + 16; size_t newsize, oldsize; newsize = newlen * sizeof(*stack); oldsize = stackcount * sizeof(*stack); new = isc_mem_get(mctx, newsize); if (new == NULL) goto cleanup; if (stackcount != 0) { void *ptr; DE_CONST(stack, ptr); memmove(new, stack, oldsize); isc_mem_put(mctx, ptr, oldsize); } stack = new; stackcount = newlen; } stack[pushed++] = cfg_list_next(element); goto newlist; } if (pushed != 0) { element = stack[--pushed]; goto resume; } cleanup: if (stack != NULL) { void *ptr; DE_CONST(stack, ptr); isc_mem_put(mctx, ptr, stackcount * sizeof(*stack)); } isc_symtab_destroy(&symtab); *countp = count; return (result); } static isc_result_t check_update_policy(const cfg_obj_t *policy, isc_log_t *logctx) { isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; const cfg_listelt_t *element; const cfg_listelt_t *element2; dns_fixedname_t fixed; const char *str; isc_buffer_t b; /* Check for "update-policy local;" */ if (cfg_obj_isstring(policy) && strcmp("local", cfg_obj_asstring(policy)) == 0) return (ISC_R_SUCCESS); /* Now check the grant policy */ for (element = cfg_list_first(policy); element != NULL; element = cfg_list_next(element)) { const cfg_obj_t *stmt = cfg_listelt_value(element); const cfg_obj_t *identity = cfg_tuple_get(stmt, "identity"); const cfg_obj_t *matchtype = cfg_tuple_get(stmt, "matchtype"); const cfg_obj_t *dname = cfg_tuple_get(stmt, "name"); const cfg_obj_t *typelist = cfg_tuple_get(stmt, "types"); dns_fixedname_init(&fixed); str = cfg_obj_asstring(identity); isc_buffer_constinit(&b, str, strlen(str)); isc_buffer_add(&b, strlen(str)); tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b, dns_rootname, 0, NULL); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(identity, logctx, ISC_LOG_ERROR, "'%s' is not a valid name", str); result = tresult; } if (tresult == ISC_R_SUCCESS && strcasecmp(cfg_obj_asstring(matchtype), "zonesub") != 0) { dns_fixedname_init(&fixed); str = cfg_obj_asstring(dname); isc_buffer_constinit(&b, str, strlen(str)); isc_buffer_add(&b, strlen(str)); tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b, dns_rootname, 0, NULL); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(dname, logctx, ISC_LOG_ERROR, "'%s' is not a valid name", str); result = tresult; } } if (tresult == ISC_R_SUCCESS && strcasecmp(cfg_obj_asstring(matchtype), "wildcard") == 0 && !dns_name_iswildcard(dns_fixedname_name(&fixed))) { cfg_obj_log(identity, logctx, ISC_LOG_ERROR, "'%s' is not a wildcard", str); result = ISC_R_FAILURE; } for (element2 = cfg_list_first(typelist); element2 != NULL; element2 = cfg_list_next(element2)) { const cfg_obj_t *typeobj; isc_textregion_t r; dns_rdatatype_t type; typeobj = cfg_listelt_value(element2); DE_CONST(cfg_obj_asstring(typeobj), r.base); r.length = strlen(r.base); tresult = dns_rdatatype_fromtext(&type, &r); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(typeobj, logctx, ISC_LOG_ERROR, "'%s' is not a valid type", r.base); result = tresult; } } } return (result); } #define MASTERZONE 1 #define SLAVEZONE 2 #define STUBZONE 4 #define HINTZONE 8 #define FORWARDZONE 16 #define DELEGATIONZONE 32 #define STATICSTUBZONE 64 #define REDIRECTZONE 128 #define STREDIRECTZONE 0 /* Set to REDIRECTZONE to allow xfr-in. */ #define CHECKACL 512 typedef struct { const char *name; int allowed; } optionstable; static isc_result_t check_nonzero(const cfg_obj_t *options, isc_log_t *logctx) { isc_result_t result = ISC_R_SUCCESS; const cfg_obj_t *obj = NULL; unsigned int i; static const char *nonzero[] = { "max-retry-time", "min-retry-time", "max-refresh-time", "min-refresh-time" }; /* * Check if value is zero. */ for (i = 0; i < sizeof(nonzero) / sizeof(nonzero[0]); i++) { obj = NULL; if (cfg_map_get(options, nonzero[i], &obj) == ISC_R_SUCCESS && cfg_obj_asuint32(obj) == 0) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "'%s' must not be zero", nonzero[i]); result = ISC_R_FAILURE; } } return (result); } static isc_result_t check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, const cfg_obj_t *config, isc_symtab_t *symtab, isc_symtab_t *files, dns_rdataclass_t defclass, cfg_aclconfctx_t *actx, isc_log_t *logctx, isc_mem_t *mctx) { const char *znamestr; const char *typestr; unsigned int ztype; const cfg_obj_t *zoptions, *goptions = NULL; const cfg_obj_t *obj = NULL; isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; unsigned int i; dns_rdataclass_t zclass; dns_fixedname_t fixedname; dns_name_t *zname = NULL; isc_buffer_t b; isc_boolean_t root = ISC_FALSE; const cfg_listelt_t *element; isc_boolean_t dlz; dns_masterformat_t masterformat; isc_boolean_t ddns = ISC_FALSE; static optionstable options[] = { { "allow-notify", SLAVEZONE | CHECKACL }, { "allow-query", MASTERZONE | SLAVEZONE | STUBZONE | REDIRECTZONE | CHECKACL | STATICSTUBZONE }, { "allow-transfer", MASTERZONE | SLAVEZONE | CHECKACL }, { "allow-update", MASTERZONE | CHECKACL }, { "allow-update-forwarding", SLAVEZONE | CHECKACL }, { "also-notify", MASTERZONE | SLAVEZONE }, { "auto-dnssec", MASTERZONE | SLAVEZONE }, { "check-dup-records", MASTERZONE }, { "check-mx", MASTERZONE }, { "check-mx-cname", MASTERZONE }, { "check-srv-cname", MASTERZONE }, { "check-wildcard", MASTERZONE }, { "database", MASTERZONE | SLAVEZONE | STUBZONE | REDIRECTZONE }, { "delegation-only", HINTZONE | STUBZONE | FORWARDZONE | DELEGATIONZONE }, { "dialup", MASTERZONE | SLAVEZONE | STUBZONE | STREDIRECTZONE }, { "dnssec-dnskey-kskonly", MASTERZONE | SLAVEZONE }, { "dnssec-loadkeys-interval", MASTERZONE | SLAVEZONE }, { "dnssec-secure-to-insecure", MASTERZONE }, { "file", MASTERZONE | SLAVEZONE | STUBZONE | HINTZONE | REDIRECTZONE }, { "forward", MASTERZONE | SLAVEZONE | STUBZONE | STATICSTUBZONE | FORWARDZONE }, { "forwarders", MASTERZONE | SLAVEZONE | STUBZONE | STATICSTUBZONE | FORWARDZONE }, { "integrity-check", MASTERZONE }, { "ixfr-base", MASTERZONE | SLAVEZONE }, { "ixfr-tmp-file", MASTERZONE | SLAVEZONE }, { "journal", MASTERZONE | SLAVEZONE | STREDIRECTZONE }, { "key-directory", MASTERZONE | SLAVEZONE }, { "maintain-ixfr-base", MASTERZONE | SLAVEZONE | STREDIRECTZONE }, { "masterfile-format", MASTERZONE | SLAVEZONE | STUBZONE | REDIRECTZONE }, { "masters", SLAVEZONE | STUBZONE | REDIRECTZONE }, { "max-ixfr-log-size", MASTERZONE | SLAVEZONE | STREDIRECTZONE }, { "max-refresh-time", SLAVEZONE | STUBZONE | STREDIRECTZONE }, { "max-retry-time", SLAVEZONE | STUBZONE | STREDIRECTZONE }, { "max-transfer-idle-in", SLAVEZONE | STUBZONE | STREDIRECTZONE }, { "max-transfer-idle-out", MASTERZONE | SLAVEZONE }, { "max-transfer-time-in", SLAVEZONE | STUBZONE | STREDIRECTZONE }, { "max-transfer-time-out", MASTERZONE | SLAVEZONE }, { "max-zone-ttl", MASTERZONE | REDIRECTZONE }, { "min-refresh-time", SLAVEZONE | STUBZONE | STREDIRECTZONE }, { "min-retry-time", SLAVEZONE | STUBZONE | STREDIRECTZONE }, { "notify", MASTERZONE | SLAVEZONE }, { "notify-source", MASTERZONE | SLAVEZONE }, { "notify-source-v6", MASTERZONE | SLAVEZONE }, { "pubkey", MASTERZONE | SLAVEZONE | STUBZONE }, { "request-ixfr", SLAVEZONE | REDIRECTZONE }, { "server-addresses", STATICSTUBZONE }, { "server-names", STATICSTUBZONE }, { "sig-re-signing-interval", MASTERZONE | SLAVEZONE }, { "sig-signing-nodes", MASTERZONE | SLAVEZONE }, { "sig-signing-signatures", MASTERZONE | SLAVEZONE }, { "sig-signing-type", MASTERZONE | SLAVEZONE }, { "sig-validity-interval", MASTERZONE | SLAVEZONE }, { "signing", MASTERZONE | SLAVEZONE }, { "transfer-source", SLAVEZONE | STUBZONE | STREDIRECTZONE }, { "transfer-source-v6", SLAVEZONE | STUBZONE | STREDIRECTZONE }, { "try-tcp-refresh", SLAVEZONE | STREDIRECTZONE }, { "update-check-ksk", MASTERZONE | SLAVEZONE }, { "update-policy", MASTERZONE }, { "zone-statistics", MASTERZONE | SLAVEZONE | STUBZONE | STATICSTUBZONE | REDIRECTZONE }, }; static optionstable dialups[] = { { "notify", MASTERZONE | SLAVEZONE | STREDIRECTZONE }, { "notify-passive", SLAVEZONE | STREDIRECTZONE }, { "refresh", SLAVEZONE | STUBZONE | STREDIRECTZONE }, { "passive", SLAVEZONE | STUBZONE | STREDIRECTZONE }, }; znamestr = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); zoptions = cfg_tuple_get(zconfig, "options"); if (config != NULL) cfg_map_get(config, "options", &goptions); obj = NULL; (void)cfg_map_get(zoptions, "in-view", &obj); if (obj != NULL) { const cfg_obj_t *fwd = NULL; unsigned int maxopts = 1; (void)cfg_map_get(zoptions, "forward", &fwd); if (fwd != NULL) maxopts++; fwd = NULL; (void)cfg_map_get(zoptions, "forwarders", &fwd); if (fwd != NULL) maxopts++; if (cfg_map_count(zoptions) > maxopts) { cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR, "zone '%s': 'in-view' used " "with incompatible zone options", znamestr); return (ISC_R_FAILURE); } return (ISC_R_SUCCESS); } obj = NULL; (void)cfg_map_get(zoptions, "type", &obj); if (obj == NULL) { cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR, "zone '%s': type not present", znamestr); return (ISC_R_FAILURE); } typestr = cfg_obj_asstring(obj); if (strcasecmp(typestr, "master") == 0) ztype = MASTERZONE; else if (strcasecmp(typestr, "slave") == 0) ztype = SLAVEZONE; else if (strcasecmp(typestr, "stub") == 0) ztype = STUBZONE; else if (strcasecmp(typestr, "static-stub") == 0) ztype = STATICSTUBZONE; else if (strcasecmp(typestr, "forward") == 0) ztype = FORWARDZONE; else if (strcasecmp(typestr, "hint") == 0) ztype = HINTZONE; else if (strcasecmp(typestr, "delegation-only") == 0) ztype = DELEGATIONZONE; else if (strcasecmp(typestr, "redirect") == 0) ztype = REDIRECTZONE; else { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "zone '%s': invalid type %s", znamestr, typestr); return (ISC_R_FAILURE); } if (ztype == REDIRECTZONE && strcmp(znamestr, ".") != 0) { cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR, "redirect zones must be called \".\""); return (ISC_R_FAILURE); } obj = cfg_tuple_get(zconfig, "class"); if (cfg_obj_isstring(obj)) { isc_textregion_t r; DE_CONST(cfg_obj_asstring(obj), r.base); r.length = strlen(r.base); result = dns_rdataclass_fromtext(&zclass, &r); if (result != ISC_R_SUCCESS) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "zone '%s': invalid class %s", znamestr, r.base); return (ISC_R_FAILURE); } if (zclass != defclass) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "zone '%s': class '%s' does not " "match view/default class", znamestr, r.base); return (ISC_R_FAILURE); } } /* * Look for an already existing zone. * We need to make this canonical as isc_symtab_define() * deals with strings. */ dns_fixedname_init(&fixedname); isc_buffer_constinit(&b, znamestr, strlen(znamestr)); isc_buffer_add(&b, strlen(znamestr)); tresult = dns_name_fromtext(dns_fixedname_name(&fixedname), &b, dns_rootname, DNS_NAME_DOWNCASE, NULL); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR, "zone '%s': is not a valid name", znamestr); result = ISC_R_FAILURE; } else { char namebuf[DNS_NAME_FORMATSIZE]; zname = dns_fixedname_name(&fixedname); dns_name_format(zname, namebuf, sizeof(namebuf)); tresult = nameexist(zconfig, namebuf, ztype == HINTZONE ? 1 : ztype == REDIRECTZONE ? 2 : 3, symtab, "zone '%s': already exists " "previous definition: %s:%u", logctx, mctx); if (tresult != ISC_R_SUCCESS) result = tresult; if (dns_name_equal(zname, dns_rootname)) root = ISC_TRUE; } /* * Check if value is zero. */ if (check_nonzero(zoptions, logctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; /* * Look for inappropriate options for the given zone type. * Check that ACLs expand correctly. */ for (i = 0; i < sizeof(options) / sizeof(options[0]); i++) { obj = NULL; if ((options[i].allowed & ztype) == 0 && cfg_map_get(zoptions, options[i].name, &obj) == ISC_R_SUCCESS) { if (strcmp(options[i].name, "allow-update") != 0 || ztype != SLAVEZONE) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "option '%s' is not allowed " "in '%s' zone '%s'", options[i].name, typestr, znamestr); result = ISC_R_FAILURE; } else cfg_obj_log(obj, logctx, ISC_LOG_WARNING, "option '%s' is not allowed " "in '%s' zone '%s'", options[i].name, typestr, znamestr); } obj = NULL; if ((options[i].allowed & ztype) != 0 && (options[i].allowed & CHECKACL) != 0) { tresult = checkacl(options[i].name, actx, zconfig, voptions, config, logctx, mctx); if (tresult != ISC_R_SUCCESS) result = tresult; } } /* * Master & slave zones may have an "also-notify" field, but * shouldn't if notify is disabled. */ if (ztype == MASTERZONE || ztype == SLAVEZONE ) { isc_boolean_t donotify = ISC_TRUE; obj = NULL; tresult = cfg_map_get(zoptions, "notify", &obj); if (tresult != ISC_R_SUCCESS && voptions != NULL) tresult = cfg_map_get(voptions, "notify", &obj); if (tresult != ISC_R_SUCCESS && goptions != NULL) tresult = cfg_map_get(goptions, "notify", &obj); if (tresult == ISC_R_SUCCESS) { if (cfg_obj_isboolean(obj)) donotify = cfg_obj_asboolean(obj); else { const char *notifystr = cfg_obj_asstring(obj); if (ztype != MASTERZONE && strcasecmp(notifystr, "master-only") == 0) donotify = ISC_FALSE; } } obj = NULL; tresult = cfg_map_get(zoptions, "also-notify", &obj); if (tresult == ISC_R_SUCCESS && !donotify) { cfg_obj_log(zoptions, logctx, ISC_LOG_WARNING, "zone '%s': 'also-notify' set but " "'notify' is disabled", znamestr); } else if (tresult == ISC_R_SUCCESS) { isc_uint32_t count; tresult = validate_masters(obj, config, &count, logctx, mctx); if (tresult != ISC_R_SUCCESS && result == ISC_R_SUCCESS) result = tresult; } } /* * Slave & stub zones must have a "masters" field. */ if (ztype == SLAVEZONE || ztype == STUBZONE) { obj = NULL; if (cfg_map_get(zoptions, "masters", &obj) != ISC_R_SUCCESS) { cfg_obj_log(zoptions, logctx, ISC_LOG_ERROR, "zone '%s': missing 'masters' entry", znamestr); result = ISC_R_FAILURE; } else { isc_uint32_t count; tresult = validate_masters(obj, config, &count, logctx, mctx); if (tresult != ISC_R_SUCCESS && result == ISC_R_SUCCESS) result = tresult; if (tresult == ISC_R_SUCCESS && count == 0) { cfg_obj_log(zoptions, logctx, ISC_LOG_ERROR, "zone '%s': empty 'masters' entry", znamestr); result = ISC_R_FAILURE; } } } /* * Master zones can't have both "allow-update" and "update-policy". */ if (ztype == MASTERZONE || ztype == SLAVEZONE) { isc_boolean_t signing = ISC_FALSE; isc_result_t res1, res2, res3; const cfg_obj_t *au = NULL; const char *arg; obj = NULL; res1 = cfg_map_get(zoptions, "allow-update", &au); obj = NULL; res2 = cfg_map_get(zoptions, "update-policy", &obj); if (res1 == ISC_R_SUCCESS && res2 == ISC_R_SUCCESS) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "zone '%s': 'allow-update' is ignored " "when 'update-policy' is present", znamestr); result = ISC_R_FAILURE; } else if (res2 == ISC_R_SUCCESS) { res3 = check_update_policy(obj, logctx); if (res3 != ISC_R_SUCCESS) result = ISC_R_FAILURE; } /* * To determine whether auto-dnssec is allowed, * we should also check for allow-update at the * view and options levels. */ if (res1 != ISC_R_SUCCESS && voptions != NULL) res1 = cfg_map_get(voptions, "allow-update", &au); if (res1 != ISC_R_SUCCESS && goptions != NULL) res1 = cfg_map_get(goptions, "allow-update", &au); if (res2 == ISC_R_SUCCESS) ddns = ISC_TRUE; else if (res1 == ISC_R_SUCCESS) { dns_acl_t *acl = NULL; res1 = cfg_acl_fromconfig(au, config, logctx, actx, mctx, 0, &acl); if (res1 != ISC_R_SUCCESS) { cfg_obj_log(au, logctx, ISC_LOG_ERROR, "acl expansion failed: %s", isc_result_totext(result)); result = ISC_R_FAILURE; } else if (acl != NULL) { if (!dns_acl_isnone(acl)) ddns = ISC_TRUE; dns_acl_detach(&acl); } } obj = NULL; res1 = cfg_map_get(zoptions, "inline-signing", &obj); if (res1 == ISC_R_SUCCESS) signing = cfg_obj_asboolean(obj); obj = NULL; arg = "off"; res3 = cfg_map_get(zoptions, "auto-dnssec", &obj); if (res3 == ISC_R_SUCCESS) arg = cfg_obj_asstring(obj); if (strcasecmp(arg, "off") != 0 && !ddns && !signing) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "'auto-dnssec %s;' requires%s " "inline-signing to be configured for " "the zone", arg, (ztype == MASTERZONE) ? " dynamic DNS or" : ""); result = ISC_R_FAILURE; } obj = NULL; res1 = cfg_map_get(zoptions, "sig-signing-type", &obj); if (res1 == ISC_R_SUCCESS) { isc_uint32_t type = cfg_obj_asuint32(obj); if (type < 0xff00U || type > 0xffffU) cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "sig-signing-type: %u out of " "range [%u..%u]", type, 0xff00U, 0xffffU); result = ISC_R_FAILURE; } obj = NULL; res1 = cfg_map_get(zoptions, "dnssec-dnskey-kskonly", &obj); if (res1 == ISC_R_SUCCESS && ztype == SLAVEZONE && !signing) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "dnssec-dnskey-kskonly: requires " "inline-signing when used in slave zone"); result = ISC_R_FAILURE; } obj = NULL; res1 = cfg_map_get(zoptions, "dnssec-loadkeys-interval", &obj); if (res1 == ISC_R_SUCCESS && ztype == SLAVEZONE && !signing) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "dnssec-loadkeys-interval: requires " "inline-signing when used in slave zone"); result = ISC_R_FAILURE; } obj = NULL; res1 = cfg_map_get(zoptions, "update-check-ksk", &obj); if (res1 == ISC_R_SUCCESS && ztype == SLAVEZONE && !signing) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "update-check-ksk: requires " "inline-signing when used in slave zone"); result = ISC_R_FAILURE; } } /* * Check the excessively complicated "dialup" option. */ if (ztype == MASTERZONE || ztype == SLAVEZONE || ztype == STUBZONE) { const cfg_obj_t *dialup = NULL; (void)cfg_map_get(zoptions, "dialup", &dialup); if (dialup != NULL && cfg_obj_isstring(dialup)) { const char *str = cfg_obj_asstring(dialup); for (i = 0; i < sizeof(dialups) / sizeof(dialups[0]); i++) { if (strcasecmp(dialups[i].name, str) != 0) continue; if ((dialups[i].allowed & ztype) == 0) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "dialup type '%s' is not " "allowed in '%s' " "zone '%s'", str, typestr, znamestr); result = ISC_R_FAILURE; } break; } if (i == sizeof(dialups) / sizeof(dialups[0])) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "invalid dialup type '%s' in zone " "'%s'", str, znamestr); result = ISC_R_FAILURE; } } } /* * Check that forwarding is reasonable. */ obj = NULL; if (root) { if (voptions != NULL) (void)cfg_map_get(voptions, "forwarders", &obj); if (obj == NULL && goptions != NULL) (void)cfg_map_get(goptions, "forwarders", &obj); } if (check_forward(zoptions, obj, logctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; /* * Check validity of static stub server addresses. */ obj = NULL; (void)cfg_map_get(zoptions, "server-addresses", &obj); if (ztype == STATICSTUBZONE && obj != NULL) { for (element = cfg_list_first(obj); element != NULL; element = cfg_list_next(element)) { isc_sockaddr_t sa; isc_netaddr_t na; obj = cfg_listelt_value(element); sa = *cfg_obj_assockaddr(obj); if (isc_sockaddr_getport(&sa) != 0) { result = ISC_R_FAILURE; cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "port is not configurable for " "static stub server-addresses"); } isc_netaddr_fromsockaddr(&na, &sa); if (isc_netaddr_getzone(&na) != 0) { result = ISC_R_FAILURE; cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "scoped address is not allowed " "for static stub " "server-addresses"); } } } /* * Check validity of static stub server names. */ obj = NULL; (void)cfg_map_get(zoptions, "server-names", &obj); if (zname != NULL && ztype == STATICSTUBZONE && obj != NULL) { for (element = cfg_list_first(obj); element != NULL; element = cfg_list_next(element)) { const char *snamestr; dns_fixedname_t fixed_sname; isc_buffer_t b2; dns_name_t *sname; obj = cfg_listelt_value(element); snamestr = cfg_obj_asstring(obj); dns_fixedname_init(&fixed_sname); isc_buffer_constinit(&b2, snamestr, strlen(snamestr)); isc_buffer_add(&b2, strlen(snamestr)); sname = dns_fixedname_name(&fixed_sname); tresult = dns_name_fromtext(sname, &b2, dns_rootname, 0, NULL); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR, "server-name '%s' is not a valid " "name", snamestr); result = ISC_R_FAILURE; } else if (dns_name_issubdomain(sname, zname)) { cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR, "server-name '%s' must not be a " "subdomain of zone name '%s'", snamestr, znamestr); result = ISC_R_FAILURE; } } } /* * Check that max-zone-ttl isn't used with masterfile-format map */ masterformat = dns_masterformat_text; obj = NULL; (void)cfg_map_get(zoptions, "masterfile-format", &obj); if (obj != NULL) { const char *masterformatstr = cfg_obj_asstring(obj); if (strcasecmp(masterformatstr, "text") == 0) masterformat = dns_masterformat_text; else if (strcasecmp(masterformatstr, "raw") == 0) masterformat = dns_masterformat_raw; else if (strcasecmp(masterformatstr, "map") == 0) masterformat = dns_masterformat_map; else INSIST(0); } if (masterformat == dns_masterformat_map) { obj = NULL; (void)cfg_map_get(zoptions, "max-zone-ttl", &obj); if (obj == NULL && voptions != NULL) (void)cfg_map_get(voptions, "max-zone-ttl", &obj); if (obj == NULL && goptions !=NULL) (void)cfg_map_get(goptions, "max-zone-ttl", &obj); if (obj != NULL) { cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR, "zone '%s': 'max-zone-ttl' is not " "compatible with 'masterfile-format map'", znamestr); result = ISC_R_FAILURE; } } /* * Warn if key-directory doesn't exist */ obj = NULL; tresult = cfg_map_get(zoptions, "key-directory", &obj); if (tresult == ISC_R_SUCCESS) { const char *dir = cfg_obj_asstring(obj); tresult = isc_file_isdirectory(dir); switch (tresult) { case ISC_R_SUCCESS: break; case ISC_R_FILENOTFOUND: cfg_obj_log(obj, logctx, ISC_LOG_WARNING, "key-directory: '%s' does not exist", dir); break; case ISC_R_INVALIDFILE: cfg_obj_log(obj, logctx, ISC_LOG_WARNING, "key-directory: '%s' is not a directory", dir); break; default: cfg_obj_log(obj, logctx, ISC_LOG_WARNING, "key-directory: '%s' %s", dir, isc_result_totext(tresult)); result = tresult; } } /* * Check various options. */ tresult = check_options(zoptions, logctx, mctx, optlevel_zone); if (tresult != ISC_R_SUCCESS) result = tresult; /* * If the zone type is rbt/rbt64 then master/hint zones * require file clauses. * If inline signing is used, then slave zones require a * file clause as well */ obj = NULL; dlz = ISC_FALSE; tresult = cfg_map_get(zoptions, "dlz", &obj); if (tresult == ISC_R_SUCCESS) dlz = ISC_TRUE; obj = NULL; tresult = cfg_map_get(zoptions, "database", &obj); if (dlz && tresult == ISC_R_SUCCESS) { cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR, "zone '%s': cannot specify both 'dlz' " "and 'database'", znamestr); result = ISC_R_FAILURE; } else if (!dlz && (tresult == ISC_R_NOTFOUND || (tresult == ISC_R_SUCCESS && (strcmp("rbt", cfg_obj_asstring(obj)) == 0 || strcmp("rbt64", cfg_obj_asstring(obj)) == 0)))) { isc_result_t res1; const cfg_obj_t *fileobj = NULL; tresult = cfg_map_get(zoptions, "file", &fileobj); obj = NULL; res1 = cfg_map_get(zoptions, "inline-signing", &obj); if ((tresult != ISC_R_SUCCESS && (ztype == MASTERZONE || ztype == HINTZONE || (ztype == SLAVEZONE && res1 == ISC_R_SUCCESS && cfg_obj_asboolean(obj))))) { cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR, "zone '%s': missing 'file' entry", znamestr); result = tresult; } else if (tresult == ISC_R_SUCCESS && (ztype == SLAVEZONE || ddns)) { tresult = fileexist(fileobj, files, ISC_TRUE, logctx); if (tresult != ISC_R_SUCCESS) result = tresult; } else if (tresult == ISC_R_SUCCESS && (ztype == MASTERZONE || ztype == HINTZONE)) { tresult = fileexist(fileobj, files, ISC_FALSE, logctx); if (tresult != ISC_R_SUCCESS) result = tresult; } } return (result); } typedef struct keyalgorithms { const char *name; isc_uint16_t size; } algorithmtable; isc_result_t bind9_check_key(const cfg_obj_t *key, isc_log_t *logctx) { const cfg_obj_t *algobj = NULL; const cfg_obj_t *secretobj = NULL; const char *keyname = cfg_obj_asstring(cfg_map_getname(key)); const char *algorithm; int i; size_t len = 0; isc_result_t result; isc_buffer_t buf; unsigned char secretbuf[1024]; static const algorithmtable algorithms[] = { { "hmac-md5", 128 }, { "hmac-md5.sig-alg.reg.int", 0 }, { "hmac-md5.sig-alg.reg.int.", 0 }, { "hmac-sha1", 160 }, { "hmac-sha224", 224 }, { "hmac-sha256", 256 }, { "hmac-sha384", 384 }, { "hmac-sha512", 512 }, { NULL, 0 } }; (void)cfg_map_get(key, "algorithm", &algobj); (void)cfg_map_get(key, "secret", &secretobj); if (secretobj == NULL || algobj == NULL) { cfg_obj_log(key, logctx, ISC_LOG_ERROR, "key '%s' must have both 'secret' and " "'algorithm' defined", keyname); return (ISC_R_FAILURE); } isc_buffer_init(&buf, secretbuf, sizeof(secretbuf)); result = isc_base64_decodestring(cfg_obj_asstring(secretobj), &buf); if (result != ISC_R_SUCCESS) { cfg_obj_log(secretobj, logctx, ISC_LOG_ERROR, "bad secret '%s'", isc_result_totext(result)); return (result); } algorithm = cfg_obj_asstring(algobj); for (i = 0; algorithms[i].name != NULL; i++) { len = strlen(algorithms[i].name); if (strncasecmp(algorithms[i].name, algorithm, len) == 0 && (algorithm[len] == '\0' || (algorithms[i].size != 0 && algorithm[len] == '-'))) break; } if (algorithms[i].name == NULL) { cfg_obj_log(algobj, logctx, ISC_LOG_ERROR, "unknown algorithm '%s'", algorithm); return (ISC_R_NOTFOUND); } if (algorithm[len] == '-') { isc_uint16_t digestbits; result = isc_parse_uint16(&digestbits, algorithm + len + 1, 10); if (result == ISC_R_SUCCESS || result == ISC_R_RANGE) { if (result == ISC_R_RANGE || digestbits > algorithms[i].size) { cfg_obj_log(algobj, logctx, ISC_LOG_ERROR, "key '%s' digest-bits too large " "[%u..%u]", keyname, algorithms[i].size / 2, algorithms[i].size); return (ISC_R_RANGE); } if ((digestbits % 8) != 0) { cfg_obj_log(algobj, logctx, ISC_LOG_ERROR, "key '%s' digest-bits not multiple" " of 8", keyname); return (ISC_R_RANGE); } /* * Recommended minima for hmac algorithms. */ if ((digestbits < (algorithms[i].size / 2U) || (digestbits < 80U))) cfg_obj_log(algobj, logctx, ISC_LOG_WARNING, "key '%s' digest-bits too small " "[<%u]", keyname, algorithms[i].size/2); } else { cfg_obj_log(algobj, logctx, ISC_LOG_ERROR, "key '%s': unable to parse digest-bits", keyname); return (result); } } return (ISC_R_SUCCESS); } static isc_result_t fileexist(const cfg_obj_t *obj, isc_symtab_t *symtab, isc_boolean_t writeable, isc_log_t *logctx) { isc_result_t result; isc_symvalue_t symvalue; unsigned int line; const char *file; result = isc_symtab_lookup(symtab, cfg_obj_asstring(obj), 0, &symvalue); if (result == ISC_R_SUCCESS) { if (writeable) { file = cfg_obj_file(symvalue.as_cpointer); line = cfg_obj_line(symvalue.as_cpointer); cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "writeable file '%s': already in use: " "%s:%u", cfg_obj_asstring(obj), file, line); return (ISC_R_EXISTS); } result = isc_symtab_lookup(symtab, cfg_obj_asstring(obj), 2, &symvalue); if (result == ISC_R_SUCCESS) { file = cfg_obj_file(symvalue.as_cpointer); line = cfg_obj_line(symvalue.as_cpointer); cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "writeable file '%s': already in use: " "%s:%u", cfg_obj_asstring(obj), file, line); return (ISC_R_EXISTS); } return (ISC_R_SUCCESS); } symvalue.as_cpointer = obj; result = isc_symtab_define(symtab, cfg_obj_asstring(obj), writeable ? 2 : 1, symvalue, isc_symexists_reject); return (result); } /* * Check key list for duplicates key names and that the key names * are valid domain names as these keys are used for TSIG. * * Check the key contents for validity. */ static isc_result_t check_keylist(const cfg_obj_t *keys, isc_symtab_t *symtab, isc_mem_t *mctx, isc_log_t *logctx) { char namebuf[DNS_NAME_FORMATSIZE]; dns_fixedname_t fname; dns_name_t *name; isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; const cfg_listelt_t *element; dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); for (element = cfg_list_first(keys); element != NULL; element = cfg_list_next(element)) { const cfg_obj_t *key = cfg_listelt_value(element); const char *keyid = cfg_obj_asstring(cfg_map_getname(key)); isc_symvalue_t symvalue; isc_buffer_t b; char *keyname; isc_buffer_constinit(&b, keyid, strlen(keyid)); isc_buffer_add(&b, strlen(keyid)); tresult = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(key, logctx, ISC_LOG_ERROR, "key '%s': bad key name", keyid); result = tresult; continue; } tresult = bind9_check_key(key, logctx); if (tresult != ISC_R_SUCCESS) return (tresult); dns_name_format(name, namebuf, sizeof(namebuf)); keyname = isc_mem_strdup(mctx, namebuf); if (keyname == NULL) return (ISC_R_NOMEMORY); symvalue.as_cpointer = key; tresult = isc_symtab_define(symtab, keyname, 1, symvalue, isc_symexists_reject); if (tresult == ISC_R_EXISTS) { const char *file; unsigned int line; RUNTIME_CHECK(isc_symtab_lookup(symtab, keyname, 1, &symvalue) == ISC_R_SUCCESS); file = cfg_obj_file(symvalue.as_cpointer); line = cfg_obj_line(symvalue.as_cpointer); if (file == NULL) file = ""; cfg_obj_log(key, logctx, ISC_LOG_ERROR, "key '%s': already exists " "previous definition: %s:%u", keyid, file, line); isc_mem_free(mctx, keyname); result = tresult; } else if (tresult != ISC_R_SUCCESS) { isc_mem_free(mctx, keyname); return (tresult); } } return (result); } static struct { const char *v4; const char *v6; } sources[] = { { "transfer-source", "transfer-source-v6" }, { "notify-source", "notify-source-v6" }, { "query-source", "query-source-v6" }, { NULL, NULL } }; /* * RNDC keys are not normalised unlike TSIG keys. * * "foo." is different to "foo". */ static isc_boolean_t rndckey_exists(const cfg_obj_t *keylist, const char *keyname) { const cfg_listelt_t *element; const cfg_obj_t *obj; const char *str; if (keylist == NULL) return (ISC_FALSE); for (element = cfg_list_first(keylist); element != NULL; element = cfg_list_next(element)) { obj = cfg_listelt_value(element); str = cfg_obj_asstring(cfg_map_getname(obj)); if (!strcasecmp(str, keyname)) return (ISC_TRUE); } return (ISC_FALSE); } static isc_result_t check_servers(const cfg_obj_t *config, const cfg_obj_t *voptions, isc_symtab_t *symtab, isc_log_t *logctx) { dns_fixedname_t fname; isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; const cfg_listelt_t *e1, *e2; const cfg_obj_t *v1, *v2, *keys; const cfg_obj_t *servers; isc_netaddr_t n1, n2; unsigned int p1, p2; const cfg_obj_t *obj; char buf[ISC_NETADDR_FORMATSIZE]; char namebuf[DNS_NAME_FORMATSIZE]; const char *xfr; const char *keyval; isc_buffer_t b; int source; dns_name_t *keyname; servers = NULL; if (voptions != NULL) (void)cfg_map_get(voptions, "server", &servers); if (servers == NULL) (void)cfg_map_get(config, "server", &servers); if (servers == NULL) return (ISC_R_SUCCESS); for (e1 = cfg_list_first(servers); e1 != NULL; e1 = cfg_list_next(e1)) { v1 = cfg_listelt_value(e1); cfg_obj_asnetprefix(cfg_map_getname(v1), &n1, &p1); /* * Check that unused bits are zero. */ tresult = isc_netaddr_prefixok(&n1, p1); if (tresult != ISC_R_SUCCESS) { INSIST(tresult == ISC_R_FAILURE); isc_netaddr_format(&n1, buf, sizeof(buf)); cfg_obj_log(v1, logctx, ISC_LOG_ERROR, "server '%s/%u': invalid prefix " "(extra bits specified)", buf, p1); result = tresult; } source = 0; do { obj = NULL; if (n1.family == AF_INET) xfr = sources[source].v6; else xfr = sources[source].v4; (void)cfg_map_get(v1, xfr, &obj); if (obj != NULL) { isc_netaddr_format(&n1, buf, sizeof(buf)); cfg_obj_log(v1, logctx, ISC_LOG_ERROR, "server '%s/%u': %s not legal", buf, p1, xfr); result = ISC_R_FAILURE; } } while (sources[++source].v4 != NULL); e2 = e1; while ((e2 = cfg_list_next(e2)) != NULL) { v2 = cfg_listelt_value(e2); cfg_obj_asnetprefix(cfg_map_getname(v2), &n2, &p2); if (p1 == p2 && isc_netaddr_equal(&n1, &n2)) { const char *file = cfg_obj_file(v1); unsigned int line = cfg_obj_line(v1); if (file == NULL) file = ""; isc_netaddr_format(&n2, buf, sizeof(buf)); cfg_obj_log(v2, logctx, ISC_LOG_ERROR, "server '%s/%u': already exists " "previous definition: %s:%u", buf, p2, file, line); result = ISC_R_FAILURE; } } keys = NULL; cfg_map_get(v1, "keys", &keys); if (keys != NULL) { /* * Normalize key name. */ keyval = cfg_obj_asstring(keys); dns_fixedname_init(&fname); isc_buffer_constinit(&b, keyval, strlen(keyval)); isc_buffer_add(&b, strlen(keyval)); keyname = dns_fixedname_name(&fname); tresult = dns_name_fromtext(keyname, &b, dns_rootname, 0, NULL); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(keys, logctx, ISC_LOG_ERROR, "bad key name '%s'", keyval); result = ISC_R_FAILURE; continue; } dns_name_format(keyname, namebuf, sizeof(namebuf)); tresult = isc_symtab_lookup(symtab, namebuf, 1, NULL); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(keys, logctx, ISC_LOG_ERROR, "unknown key '%s'", keyval); result = ISC_R_FAILURE; } } } return (result); } static isc_result_t check_trusted_key(const cfg_obj_t *key, isc_boolean_t managed, isc_log_t *logctx) { const char *keystr, *keynamestr; dns_fixedname_t fkeyname; dns_name_t *keyname; isc_buffer_t b; isc_region_t r; isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; isc_uint32_t flags, proto, alg; unsigned char keydata[4096]; flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags")); proto = cfg_obj_asuint32(cfg_tuple_get(key, "protocol")); alg = cfg_obj_asuint32(cfg_tuple_get(key, "algorithm")); dns_fixedname_init(&fkeyname); keyname = dns_fixedname_name(&fkeyname); keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name")); isc_buffer_constinit(&b, keynamestr, strlen(keynamestr)); isc_buffer_add(&b, strlen(keynamestr)); result = dns_name_fromtext(keyname, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) { cfg_obj_log(key, logctx, ISC_LOG_WARNING, "bad key name: %s\n", isc_result_totext(result)); result = ISC_R_FAILURE; } if (flags > 0xffff) { cfg_obj_log(key, logctx, ISC_LOG_WARNING, "flags too big: %u\n", flags); result = ISC_R_FAILURE; } if (proto > 0xff) { cfg_obj_log(key, logctx, ISC_LOG_WARNING, "protocol too big: %u\n", proto); result = ISC_R_FAILURE; } if (alg > 0xff) { cfg_obj_log(key, logctx, ISC_LOG_WARNING, "algorithm too big: %u\n", alg); result = ISC_R_FAILURE; } if (managed) { const char *initmethod; initmethod = cfg_obj_asstring(cfg_tuple_get(key, "init")); if (strcasecmp(initmethod, "initial-key") != 0) { cfg_obj_log(key, logctx, ISC_LOG_ERROR, "managed key '%s': " "invalid initialization method '%s'", keynamestr, initmethod); result = ISC_R_FAILURE; } } isc_buffer_init(&b, keydata, sizeof(keydata)); keystr = cfg_obj_asstring(cfg_tuple_get(key, "key")); tresult = isc_base64_decodestring(keystr, &b); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(key, logctx, ISC_LOG_ERROR, "%s", isc_result_totext(tresult)); result = ISC_R_FAILURE; } else { isc_buffer_usedregion(&b, &r); if ((alg == DST_ALG_RSASHA1 || alg == DST_ALG_RSAMD5) && r.length > 1 && r.base[0] == 1 && r.base[1] == 3) cfg_obj_log(key, logctx, ISC_LOG_WARNING, "%s key '%s' has a weak exponent", managed ? "managed" : "trusted", keynamestr); } return (result); } static isc_result_t check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, const char *viewname, dns_rdataclass_t vclass, isc_symtab_t *files, isc_log_t *logctx, isc_mem_t *mctx) { const cfg_obj_t *zones = NULL; const cfg_obj_t *keys = NULL; const cfg_listelt_t *element, *element2; isc_symtab_t *symtab = NULL; isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult = ISC_R_SUCCESS; cfg_aclconfctx_t *actx = NULL; const cfg_obj_t *obj; const cfg_obj_t *options = NULL; isc_boolean_t enablednssec, enablevalidation; const char *valstr = "no"; /* * Get global options block */ (void)cfg_map_get(config, "options", &options); /* * Check that all zone statements are syntactically correct and * there are no duplicate zones. */ tresult = isc_symtab_create(mctx, 1000, freekey, mctx, ISC_FALSE, &symtab); if (tresult != ISC_R_SUCCESS) return (ISC_R_NOMEMORY); cfg_aclconfctx_create(mctx, &actx); if (voptions != NULL) (void)cfg_map_get(voptions, "zone", &zones); else (void)cfg_map_get(config, "zone", &zones); for (element = cfg_list_first(zones); element != NULL; element = cfg_list_next(element)) { const cfg_obj_t *zone = cfg_listelt_value(element); tresult = check_zoneconf(zone, voptions, config, symtab, files, vclass, actx, logctx, mctx); if (tresult != ISC_R_SUCCESS) result = ISC_R_FAILURE; } isc_symtab_destroy(&symtab); /* * Check that forwarding is reasonable. */ if (voptions == NULL) { if (options != NULL) if (check_forward(options, NULL, logctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; } else { if (check_forward(voptions, NULL, logctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; } /* * Check non-zero options at the global and view levels. */ if (options != NULL && check_nonzero(options, logctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; if (voptions != NULL &&check_nonzero(voptions, logctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; /* * Check that dual-stack-servers is reasonable. */ if (voptions == NULL) { if (options != NULL) if (check_dual_stack(options, logctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; } else { if (check_dual_stack(voptions, logctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; } /* * Check that rrset-order is reasonable. */ if (voptions != NULL) { if (check_order(voptions, logctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; } /* * Check that all key statements are syntactically correct and * there are no duplicate keys. */ tresult = isc_symtab_create(mctx, 1000, freekey, mctx, ISC_FALSE, &symtab); if (tresult != ISC_R_SUCCESS) goto cleanup; (void)cfg_map_get(config, "key", &keys); tresult = check_keylist(keys, symtab, mctx, logctx); if (tresult == ISC_R_EXISTS) result = ISC_R_FAILURE; else if (tresult != ISC_R_SUCCESS) { result = tresult; goto cleanup; } if (voptions != NULL) { keys = NULL; (void)cfg_map_get(voptions, "key", &keys); tresult = check_keylist(keys, symtab, mctx, logctx); if (tresult == ISC_R_EXISTS) result = ISC_R_FAILURE; else if (tresult != ISC_R_SUCCESS) { result = tresult; goto cleanup; } } /* * Global servers can refer to keys in views. */ if (check_servers(config, voptions, symtab, logctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; isc_symtab_destroy(&symtab); /* * Check that dnssec-enable/dnssec-validation are sensible. */ obj = NULL; if (voptions != NULL) (void)cfg_map_get(voptions, "dnssec-enable", &obj); if (obj == NULL && options != NULL) (void)cfg_map_get(options, "dnssec-enable", &obj); if (obj == NULL) enablednssec = ISC_TRUE; else enablednssec = cfg_obj_asboolean(obj); obj = NULL; if (voptions != NULL) (void)cfg_map_get(voptions, "dnssec-validation", &obj); if (obj == NULL && options != NULL) (void)cfg_map_get(options, "dnssec-validation", &obj); if (obj == NULL) { enablevalidation = enablednssec; valstr = "yes"; } else if (cfg_obj_isboolean(obj)) { enablevalidation = cfg_obj_asboolean(obj); valstr = enablevalidation ? "yes" : "no"; } else { enablevalidation = ISC_TRUE; valstr = "auto"; } if (enablevalidation && !enablednssec) cfg_obj_log(obj, logctx, ISC_LOG_WARNING, "'dnssec-validation %s;' and 'dnssec-enable no;'", valstr); /* * Check trusted-keys and managed-keys. */ keys = NULL; if (voptions != NULL) (void)cfg_map_get(voptions, "trusted-keys", &keys); if (keys == NULL) (void)cfg_map_get(config, "trusted-keys", &keys); for (element = cfg_list_first(keys); element != NULL; element = cfg_list_next(element)) { const cfg_obj_t *keylist = cfg_listelt_value(element); for (element2 = cfg_list_first(keylist); element2 != NULL; element2 = cfg_list_next(element2)) { obj = cfg_listelt_value(element2); tresult = check_trusted_key(obj, ISC_FALSE, logctx); if (tresult != ISC_R_SUCCESS) result = tresult; } } keys = NULL; if (voptions != NULL) (void)cfg_map_get(voptions, "managed-keys", &keys); if (keys == NULL) (void)cfg_map_get(config, "managed-keys", &keys); for (element = cfg_list_first(keys); element != NULL; element = cfg_list_next(element)) { const cfg_obj_t *keylist = cfg_listelt_value(element); for (element2 = cfg_list_first(keylist); element2 != NULL; element2 = cfg_list_next(element2)) { obj = cfg_listelt_value(element2); tresult = check_trusted_key(obj, ISC_TRUE, logctx); if (tresult != ISC_R_SUCCESS) result = tresult; } } /* * Check options. */ if (voptions != NULL) tresult = check_options(voptions, logctx, mctx, optlevel_view); else tresult = check_options(config, logctx, mctx, optlevel_config); if (tresult != ISC_R_SUCCESS) result = tresult; tresult = check_viewacls(actx, voptions, config, logctx, mctx); if (tresult != ISC_R_SUCCESS) result = tresult; tresult = check_recursionacls(actx, voptions, viewname, config, logctx, mctx); if (tresult != ISC_R_SUCCESS) result = tresult; tresult = check_filteraaaa(actx, voptions, viewname, config, logctx, mctx); if (tresult != ISC_R_SUCCESS) result = tresult; tresult = check_dns64(actx, voptions, config, logctx, mctx); if (tresult != ISC_R_SUCCESS) result = tresult; cleanup: if (symtab != NULL) isc_symtab_destroy(&symtab); if (actx != NULL) cfg_aclconfctx_detach(&actx); return (result); } static const char * default_channels[] = { "default_syslog", "default_stderr", "default_debug", "null", NULL }; static isc_result_t bind9_check_logging(const cfg_obj_t *config, isc_log_t *logctx, isc_mem_t *mctx) { const cfg_obj_t *categories = NULL; const cfg_obj_t *category; const cfg_obj_t *channels = NULL; const cfg_obj_t *channel; const cfg_listelt_t *element; const cfg_listelt_t *delement; const char *channelname; const char *catname; const cfg_obj_t *fileobj = NULL; const cfg_obj_t *syslogobj = NULL; const cfg_obj_t *nullobj = NULL; const cfg_obj_t *stderrobj = NULL; const cfg_obj_t *logobj = NULL; isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; isc_symtab_t *symtab = NULL; isc_symvalue_t symvalue; int i; (void)cfg_map_get(config, "logging", &logobj); if (logobj == NULL) return (ISC_R_SUCCESS); result = isc_symtab_create(mctx, 100, NULL, NULL, ISC_FALSE, &symtab); if (result != ISC_R_SUCCESS) return (result); symvalue.as_cpointer = NULL; for (i = 0; default_channels[i] != NULL; i++) { tresult = isc_symtab_define(symtab, default_channels[i], 1, symvalue, isc_symexists_replace); if (tresult != ISC_R_SUCCESS) result = tresult; } cfg_map_get(logobj, "channel", &channels); for (element = cfg_list_first(channels); element != NULL; element = cfg_list_next(element)) { channel = cfg_listelt_value(element); channelname = cfg_obj_asstring(cfg_map_getname(channel)); fileobj = syslogobj = nullobj = stderrobj = NULL; (void)cfg_map_get(channel, "file", &fileobj); (void)cfg_map_get(channel, "syslog", &syslogobj); (void)cfg_map_get(channel, "null", &nullobj); (void)cfg_map_get(channel, "stderr", &stderrobj); i = 0; if (fileobj != NULL) i++; if (syslogobj != NULL) i++; if (nullobj != NULL) i++; if (stderrobj != NULL) i++; if (i != 1) { cfg_obj_log(channel, logctx, ISC_LOG_ERROR, "channel '%s': exactly one of file, syslog, " "null, and stderr must be present", channelname); result = ISC_R_FAILURE; } tresult = isc_symtab_define(symtab, channelname, 1, symvalue, isc_symexists_replace); if (tresult != ISC_R_SUCCESS) result = tresult; } cfg_map_get(logobj, "category", &categories); for (element = cfg_list_first(categories); element != NULL; element = cfg_list_next(element)) { category = cfg_listelt_value(element); catname = cfg_obj_asstring(cfg_tuple_get(category, "name")); if (isc_log_categorybyname(logctx, catname) == NULL) { cfg_obj_log(category, logctx, ISC_LOG_ERROR, "undefined category: '%s'", catname); result = ISC_R_FAILURE; } channels = cfg_tuple_get(category, "destinations"); for (delement = cfg_list_first(channels); delement != NULL; delement = cfg_list_next(delement)) { channel = cfg_listelt_value(delement); channelname = cfg_obj_asstring(channel); tresult = isc_symtab_lookup(symtab, channelname, 1, &symvalue); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(channel, logctx, ISC_LOG_ERROR, "undefined channel: '%s'", channelname); result = tresult; } } } isc_symtab_destroy(&symtab); return (result); } static isc_result_t bind9_check_controlskeys(const cfg_obj_t *control, const cfg_obj_t *keylist, isc_log_t *logctx) { isc_result_t result = ISC_R_SUCCESS; const cfg_obj_t *control_keylist; const cfg_listelt_t *element; const cfg_obj_t *key; const char *keyval; control_keylist = cfg_tuple_get(control, "keys"); if (cfg_obj_isvoid(control_keylist)) return (ISC_R_SUCCESS); for (element = cfg_list_first(control_keylist); element != NULL; element = cfg_list_next(element)) { key = cfg_listelt_value(element); keyval = cfg_obj_asstring(key); if (!rndckey_exists(keylist, keyval)) { cfg_obj_log(key, logctx, ISC_LOG_ERROR, "unknown key '%s'", keyval); result = ISC_R_NOTFOUND; } } return (result); } static isc_result_t bind9_check_controls(const cfg_obj_t *config, isc_log_t *logctx, isc_mem_t *mctx) { isc_result_t result = ISC_R_SUCCESS, tresult; cfg_aclconfctx_t *actx = NULL; const cfg_listelt_t *element, *element2; const cfg_obj_t *allow; const cfg_obj_t *control; const cfg_obj_t *controls; const cfg_obj_t *controlslist = NULL; const cfg_obj_t *inetcontrols; const cfg_obj_t *unixcontrols; const cfg_obj_t *keylist = NULL; const char *path; isc_uint32_t perm, mask; dns_acl_t *acl = NULL; isc_sockaddr_t addr; int i; (void)cfg_map_get(config, "controls", &controlslist); if (controlslist == NULL) return (ISC_R_SUCCESS); (void)cfg_map_get(config, "key", &keylist); cfg_aclconfctx_create(mctx, &actx); /* * INET: Check allow clause. * UNIX: Check "perm" for sanity, check path length. */ for (element = cfg_list_first(controlslist); element != NULL; element = cfg_list_next(element)) { controls = cfg_listelt_value(element); unixcontrols = NULL; inetcontrols = NULL; (void)cfg_map_get(controls, "unix", &unixcontrols); (void)cfg_map_get(controls, "inet", &inetcontrols); for (element2 = cfg_list_first(inetcontrols); element2 != NULL; element2 = cfg_list_next(element2)) { control = cfg_listelt_value(element2); allow = cfg_tuple_get(control, "allow"); tresult = cfg_acl_fromconfig(allow, config, logctx, actx, mctx, 0, &acl); if (acl != NULL) dns_acl_detach(&acl); if (tresult != ISC_R_SUCCESS) result = tresult; tresult = bind9_check_controlskeys(control, keylist, logctx); if (tresult != ISC_R_SUCCESS) result = tresult; } for (element2 = cfg_list_first(unixcontrols); element2 != NULL; element2 = cfg_list_next(element2)) { control = cfg_listelt_value(element2); path = cfg_obj_asstring(cfg_tuple_get(control, "path")); tresult = isc_sockaddr_frompath(&addr, path); if (tresult == ISC_R_NOSPACE) { cfg_obj_log(control, logctx, ISC_LOG_ERROR, "unix control '%s': path too long", path); result = ISC_R_NOSPACE; } perm = cfg_obj_asuint32(cfg_tuple_get(control, "perm")); for (i = 0; i < 3; i++) { #ifdef NEED_SECURE_DIRECTORY mask = (0x1 << (i*3)); /* SEARCH */ #else mask = (0x6 << (i*3)); /* READ + WRITE */ #endif if ((perm & mask) == mask) break; } if (i == 0) { cfg_obj_log(control, logctx, ISC_LOG_WARNING, "unix control '%s' allows access " "to everyone", path); } else if (i == 3) { cfg_obj_log(control, logctx, ISC_LOG_WARNING, "unix control '%s' allows access " "to nobody", path); } tresult = bind9_check_controlskeys(control, keylist, logctx); if (tresult != ISC_R_SUCCESS) result = tresult; } } cfg_aclconfctx_detach(&actx); return (result); } isc_result_t bind9_check_namedconf(const cfg_obj_t *config, isc_log_t *logctx, isc_mem_t *mctx) { const cfg_obj_t *options = NULL; const cfg_obj_t *views = NULL; const cfg_obj_t *acls = NULL; const cfg_obj_t *kals = NULL; const cfg_obj_t *obj; const cfg_listelt_t *velement; isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; isc_symtab_t *symtab = NULL; isc_symtab_t *files = NULL; static const char *builtin[] = { "localhost", "localnets", "any", "none"}; (void)cfg_map_get(config, "options", &options); if (options != NULL && check_options(options, logctx, mctx, optlevel_options) != ISC_R_SUCCESS) result = ISC_R_FAILURE; if (bind9_check_logging(config, logctx, mctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; if (bind9_check_controls(config, logctx, mctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; if (options != NULL && check_order(options, logctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; (void)cfg_map_get(config, "view", &views); if (views != NULL && options != NULL) if (check_dual_stack(options, logctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; /* * Use case insensitve comparision as not all file systems are * case sensitive. This will prevent people using FOO.DB and foo.db * on case sensitive file systems but that shouldn't be a major issue. */ tresult = isc_symtab_create(mctx, 100, NULL, NULL, ISC_FALSE, &files); if (tresult != ISC_R_SUCCESS) result = tresult; if (views == NULL) { if (check_viewconf(config, NULL, NULL, dns_rdataclass_in, files, logctx, mctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; } else { const cfg_obj_t *zones = NULL; (void)cfg_map_get(config, "zone", &zones); if (zones != NULL) { cfg_obj_log(zones, logctx, ISC_LOG_ERROR, "when using 'view' statements, " "all zones must be in views"); result = ISC_R_FAILURE; } } tresult = isc_symtab_create(mctx, 100, NULL, NULL, ISC_TRUE, &symtab); if (tresult != ISC_R_SUCCESS) result = tresult; for (velement = cfg_list_first(views); velement != NULL; velement = cfg_list_next(velement)) { const cfg_obj_t *view = cfg_listelt_value(velement); const cfg_obj_t *vname = cfg_tuple_get(view, "name"); const cfg_obj_t *voptions = cfg_tuple_get(view, "options"); const cfg_obj_t *vclassobj = cfg_tuple_get(view, "class"); dns_rdataclass_t vclass = dns_rdataclass_in; const char *key = cfg_obj_asstring(vname); isc_symvalue_t symvalue; unsigned int symtype; tresult = ISC_R_SUCCESS; if (cfg_obj_isstring(vclassobj)) { isc_textregion_t r; DE_CONST(cfg_obj_asstring(vclassobj), r.base); r.length = strlen(r.base); tresult = dns_rdataclass_fromtext(&vclass, &r); if (tresult != ISC_R_SUCCESS) cfg_obj_log(vclassobj, logctx, ISC_LOG_ERROR, "view '%s': invalid class %s", cfg_obj_asstring(vname), r.base); } symtype = vclass + 1; if (tresult == ISC_R_SUCCESS && symtab != NULL) { symvalue.as_cpointer = view; tresult = isc_symtab_define(symtab, key, symtype, symvalue, isc_symexists_reject); if (tresult == ISC_R_EXISTS) { const char *file; unsigned int line; RUNTIME_CHECK(isc_symtab_lookup(symtab, key, symtype, &symvalue) == ISC_R_SUCCESS); file = cfg_obj_file(symvalue.as_cpointer); line = cfg_obj_line(symvalue.as_cpointer); cfg_obj_log(view, logctx, ISC_LOG_ERROR, "view '%s': already exists " "previous definition: %s:%u", key, file, line); result = tresult; } else if (tresult != ISC_R_SUCCESS) { result = tresult; } else if ((strcasecmp(key, "_bind") == 0 && vclass == dns_rdataclass_ch) || (strcasecmp(key, "_default") == 0 && vclass == dns_rdataclass_in)) { cfg_obj_log(view, logctx, ISC_LOG_ERROR, "attempt to redefine builtin view " "'%s'", key); result = ISC_R_EXISTS; } } if (tresult == ISC_R_SUCCESS) tresult = check_viewconf(config, voptions, key, vclass, files, logctx, mctx); if (tresult != ISC_R_SUCCESS) result = ISC_R_FAILURE; } if (symtab != NULL) isc_symtab_destroy(&symtab); if (files != NULL) isc_symtab_destroy(&files); if (views != NULL && options != NULL) { obj = NULL; tresult = cfg_map_get(options, "cache-file", &obj); if (tresult == ISC_R_SUCCESS) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "'cache-file' cannot be a global " "option if views are present"); result = ISC_R_FAILURE; } } cfg_map_get(config, "acl", &acls); if (acls != NULL) { const cfg_listelt_t *elt; const cfg_listelt_t *elt2; const char *aclname; for (elt = cfg_list_first(acls); elt != NULL; elt = cfg_list_next(elt)) { const cfg_obj_t *acl = cfg_listelt_value(elt); unsigned int line = cfg_obj_line(acl); unsigned int i; aclname = cfg_obj_asstring(cfg_tuple_get(acl, "name")); for (i = 0; i < sizeof(builtin) / sizeof(builtin[0]); i++) if (strcasecmp(aclname, builtin[i]) == 0) { cfg_obj_log(acl, logctx, ISC_LOG_ERROR, "attempt to redefine " "builtin acl '%s'", aclname); result = ISC_R_FAILURE; break; } for (elt2 = cfg_list_next(elt); elt2 != NULL; elt2 = cfg_list_next(elt2)) { const cfg_obj_t *acl2 = cfg_listelt_value(elt2); const char *name; name = cfg_obj_asstring(cfg_tuple_get(acl2, "name")); if (strcasecmp(aclname, name) == 0) { const char *file = cfg_obj_file(acl); if (file == NULL) file = ""; cfg_obj_log(acl2, logctx, ISC_LOG_ERROR, "attempt to redefine " "acl '%s' previous " "definition: %s:%u", name, file, line); result = ISC_R_FAILURE; } } } } tresult = cfg_map_get(config, "kal", &kals); if (tresult == ISC_R_SUCCESS) { const cfg_listelt_t *elt; const cfg_listelt_t *elt2; const char *aclname; for (elt = cfg_list_first(kals); elt != NULL; elt = cfg_list_next(elt)) { const cfg_obj_t *acl = cfg_listelt_value(elt); aclname = cfg_obj_asstring(cfg_tuple_get(acl, "name")); for (elt2 = cfg_list_next(elt); elt2 != NULL; elt2 = cfg_list_next(elt2)) { const cfg_obj_t *acl2 = cfg_listelt_value(elt2); const char *name; name = cfg_obj_asstring(cfg_tuple_get(acl2, "name")); if (strcasecmp(aclname, name) == 0) { const char *file = cfg_obj_file(acl); unsigned int line = cfg_obj_line(acl); if (file == NULL) file = ""; cfg_obj_log(acl2, logctx, ISC_LOG_ERROR, "attempt to redefine " "kal '%s' previous " "definition: %s:%u", name, file, line); result = ISC_R_FAILURE; } } } } return (result); } bind9-9.10.3.dfsg.P4/lib/bind9/getaddresses.c0000644000470500017500000001325112664710322017767 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001, 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: getaddresses.c,v 1.22 2007/06/19 23:47:16 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_ADDRINFO #ifdef HAVE_GETADDRINFO #ifdef HAVE_GAISTRERROR #define USE_GETADDRINFO #endif #endif #endif #ifndef USE_GETADDRINFO #ifndef ISC_PLATFORM_NONSTDHERRNO extern int h_errno; #endif #endif isc_result_t bind9_getaddresses(const char *hostname, in_port_t port, isc_sockaddr_t *addrs, int addrsize, int *addrcount) { struct in_addr in4; struct in6_addr in6; isc_boolean_t have_ipv4, have_ipv6; int i; #ifdef USE_GETADDRINFO struct addrinfo *ai = NULL, *tmpai, hints; int result; #else struct hostent *he; #endif REQUIRE(hostname != NULL); REQUIRE(addrs != NULL); REQUIRE(addrcount != NULL); REQUIRE(addrsize > 0); have_ipv4 = ISC_TF((isc_net_probeipv4() == ISC_R_SUCCESS)); have_ipv6 = ISC_TF((isc_net_probeipv6() == ISC_R_SUCCESS)); /* * Try IPv4, then IPv6. In order to handle the extended format * for IPv6 scoped addresses (address%scope_ID), we'll use a local * working buffer of 128 bytes. The length is an ad-hoc value, but * should be enough for this purpose; the buffer can contain a string * of at least 80 bytes for scope_ID in addition to any IPv6 numeric * addresses (up to 46 bytes), the delimiter character and the * terminating NULL character. */ if (inet_pton(AF_INET, hostname, &in4) == 1) { if (have_ipv4) isc_sockaddr_fromin(&addrs[0], &in4, port); else isc_sockaddr_v6fromin(&addrs[0], &in4, port); *addrcount = 1; return (ISC_R_SUCCESS); } else if (strlen(hostname) <= 127U) { char tmpbuf[128], *d; isc_uint32_t zone = 0; strcpy(tmpbuf, hostname); d = strchr(tmpbuf, '%'); if (d != NULL) *d = '\0'; if (inet_pton(AF_INET6, tmpbuf, &in6) == 1) { isc_netaddr_t na; if (!have_ipv6) return (ISC_R_FAMILYNOSUPPORT); if (d != NULL) { #ifdef ISC_PLATFORM_HAVESCOPEID isc_result_t iresult; iresult = isc_netscope_pton(AF_INET6, d + 1, &in6, &zone); if (iresult != ISC_R_SUCCESS) return (iresult); #else /* * The extended format is specified while the * system does not provide the ability to use * it. Throw an explicit error instead of * ignoring the specified value. */ return (ISC_R_BADADDRESSFORM); #endif } isc_netaddr_fromin6(&na, &in6); isc_netaddr_setzone(&na, zone); isc_sockaddr_fromnetaddr(&addrs[0], (const isc_netaddr_t *)&na, port); *addrcount = 1; return (ISC_R_SUCCESS); } } #ifdef USE_GETADDRINFO memset(&hints, 0, sizeof(hints)); if (!have_ipv6) hints.ai_family = PF_INET; else if (!have_ipv4) hints.ai_family = PF_INET6; else { hints.ai_family = PF_UNSPEC; #ifdef AI_ADDRCONFIG hints.ai_flags = AI_ADDRCONFIG; #endif } hints.ai_socktype = SOCK_STREAM; #ifdef AI_ADDRCONFIG again: #endif result = getaddrinfo(hostname, NULL, &hints, &ai); switch (result) { case 0: break; case EAI_NONAME: #if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) case EAI_NODATA: #endif return (ISC_R_NOTFOUND); #ifdef AI_ADDRCONFIG case EAI_BADFLAGS: if ((hints.ai_flags & AI_ADDRCONFIG) != 0) { hints.ai_flags &= ~AI_ADDRCONFIG; goto again; } #endif default: return (ISC_R_FAILURE); } for (tmpai = ai, i = 0; tmpai != NULL && i < addrsize; tmpai = tmpai->ai_next) { if (tmpai->ai_family != AF_INET && tmpai->ai_family != AF_INET6) continue; if (tmpai->ai_family == AF_INET) { struct sockaddr_in *sin; sin = (struct sockaddr_in *)tmpai->ai_addr; isc_sockaddr_fromin(&addrs[i], &sin->sin_addr, port); } else { struct sockaddr_in6 *sin6; sin6 = (struct sockaddr_in6 *)tmpai->ai_addr; isc_sockaddr_fromin6(&addrs[i], &sin6->sin6_addr, port); } i++; } freeaddrinfo(ai); *addrcount = i; #else he = gethostbyname(hostname); if (he == NULL) { switch (h_errno) { case HOST_NOT_FOUND: #ifdef NO_DATA case NO_DATA: #endif #if defined(NO_ADDRESS) && (!defined(NO_DATA) || (NO_DATA != NO_ADDRESS)) case NO_ADDRESS: #endif return (ISC_R_NOTFOUND); default: return (ISC_R_FAILURE); } } if (he->h_addrtype != AF_INET && he->h_addrtype != AF_INET6) return (ISC_R_NOTFOUND); for (i = 0; i < addrsize; i++) { if (he->h_addrtype == AF_INET) { struct in_addr *inp; inp = (struct in_addr *)(he->h_addr_list[i]); if (inp == NULL) break; isc_sockaddr_fromin(&addrs[i], inp, port); } else { struct in6_addr *in6p; in6p = (struct in6_addr *)(he->h_addr_list[i]); if (in6p == NULL) break; isc_sockaddr_fromin6(&addrs[i], in6p, port); } } *addrcount = i; #endif if (*addrcount == 0) return (ISC_R_NOTFOUND); else return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/bind9/Makefile.in0000644000470500017500000000460412664710322017215 0ustar lamontlamont# Copyright (C) 2004, 2007, 2009, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.14 2009/12/05 23:31:40 each Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ @LIBBIND9_API@ @BIND9_MAKE_INCLUDES@ CINCLUDES = -I. ${BIND9_INCLUDES} ${DNS_INCLUDES} ${ISC_INCLUDES} \ ${ISCCFG_INCLUDES} CDEFINES = CWARNINGS = ISCLIBS = ../../lib/isc/libisc.@A@ ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@ DNSLIBS = ../../lib/dns/libdns.@A@ ISCDEPLIBS = ../../lib/isc/libisc.@A@ ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@ DNSDEPLIBS = ../../lib/dns/libdns.@A@ LIBS = @LIBS@ SUBDIRS = include # Alphabetically OBJS = check.@O@ getaddresses.@O@ version.@O@ # Alphabetically SRCS = check.c getaddresses.c version.c TARGETS = timestamp @BIND9_MAKE_RULES@ version.@O@: version.c ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ -DVERSION=\"${VERSION}\" \ -DLIBINTERFACE=${LIBINTERFACE} \ -DLIBREVISION=${LIBREVISION} \ -DLIBAGE=${LIBAGE} \ -c ${srcdir}/version.c libbind9.@SA@: ${OBJS} ${AR} ${ARFLAGS} $@ ${OBJS} ${RANLIB} $@ libbind9.la: ${OBJS} ${ISCCFGDEPLIBS} ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} \ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libbind9.la -rpath ${libdir} \ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \ ${OBJS} ${DNSLIBS} ${ISCCFGLIBS} ${ISCLIBS} @DNS_CRYPTO_LIBS@ \ ${LIBS} timestamp: libbind9.@A@ touch timestamp installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${libdir} install:: timestamp installdirs ${LIBTOOL_MODE_INSTALL} ${INSTALL_LIBRARY} libbind9.@A@ ${DESTDIR}${libdir} clean distclean:: rm -f libbind9.@A@ timestamp bind9-9.10.3.dfsg.P4/lib/bind9/include/0002755000470500017500000000000012672612753016601 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/bind9/include/Makefile.in0000644000470500017500000000175212664710322020641 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.4 2007/06/19 23:47:16 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = bind9 TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/bind9/include/bind9/0002755000470500017500000000000012664710322017576 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/bind9/include/bind9/Makefile.in0000644000470500017500000000260012664710322021637 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.8 2007/06/19 23:47:16 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ # # Only list headers that are to be installed and are not # machine generated. The latter are handled specially in the # install target below. # HEADERS = check.h getaddresses.h version.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/bind9 install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/bind9 ; \ done bind9-9.10.3.dfsg.P4/lib/bind9/include/bind9/version.h0000644000470500017500000000231112664710322021427 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: version.h,v 1.9 2007/06/19 23:47:16 tbox Exp $ */ /*! \file bind9/version.h */ #include LIBBIND9_EXTERNAL_DATA extern const char bind9_version[]; LIBBIND9_EXTERNAL_DATA extern const unsigned int bind9_libinterface; LIBBIND9_EXTERNAL_DATA extern const unsigned int bind9_librevision; LIBBIND9_EXTERNAL_DATA extern const unsigned int bind9_libage; bind9-9.10.3.dfsg.P4/lib/bind9/include/bind9/check.h0000644000470500017500000000315212664710322021023 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: check.h,v 1.9 2007/06/19 23:47:16 tbox Exp $ */ #ifndef BIND9_CHECK_H #define BIND9_CHECK_H 1 /*! \file bind9/check.h */ #include #include #include ISC_LANG_BEGINDECLS isc_result_t bind9_check_namedconf(const cfg_obj_t *config, isc_log_t *logctx, isc_mem_t *mctx); /*%< * Check the syntactic validity of a configuration parse tree generated from * a named.conf file. * * Requires: *\li config is a valid parse tree * *\li logctx is a valid logging context. * * Returns: * \li #ISC_R_SUCCESS * \li #ISC_R_FAILURE */ isc_result_t bind9_check_key(const cfg_obj_t *config, isc_log_t *logctx); /*%< * Same as bind9_check_namedconf(), but for a single 'key' statement. */ ISC_LANG_ENDDECLS #endif /* BIND9_CHECK_H */ bind9-9.10.3.dfsg.P4/lib/bind9/include/bind9/getaddresses.h0000644000470500017500000000406112664710322022423 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: getaddresses.h,v 1.11 2009/01/17 23:47:42 tbox Exp $ */ #ifndef BIND9_GETADDRESSES_H #define BIND9_GETADDRESSES_H 1 /*! \file bind9/getaddresses.h */ #include #include #include ISC_LANG_BEGINDECLS isc_result_t bind9_getaddresses(const char *hostname, in_port_t port, isc_sockaddr_t *addrs, int addrsize, int *addrcount); /*%< * Use the system resolver to get the addresses associated with a hostname. * If successful, the number of addresses found is returned in 'addrcount'. * If a hostname lookup is performed and addresses of an unknown family is * seen, it is ignored. If more than 'addrsize' addresses are seen, the * first 'addrsize' are returned and the remainder silently truncated. * * This routine may block. If called by a program using the isc_app * framework, it should be surrounded by isc_app_block()/isc_app_unblock(). * * Requires: *\li 'hostname' is not NULL. *\li 'addrs' is not NULL. *\li 'addrsize' > 0 *\li 'addrcount' is not NULL. * * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOTFOUND *\li #ISC_R_NOFAMILYSUPPORT - 'hostname' is an IPv6 address, and IPv6 is * not supported. */ ISC_LANG_ENDDECLS #endif /* BIND9_GETADDRESSES_H */ bind9-9.10.3.dfsg.P4/lib/bind9/win32/0002755000470500017500000000000012664730167016121 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/bind9/win32/libbind9.vcxproj.in0000644000470500017500000001622412664710322021631 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {E741C10B-B075-4206-9596-46765B665E03} Win32Proj libbind9 DynamicLibrary true MultiByte DynamicLibrary false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ Level3 Disabled WIN32;USE_MD5;@CRYPTO@_DEBUG;_WINDOWS;_USRDLL;LIBBIND9_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions) ./;../../../;include;../include;../../isc/win32;../../isc/win32/include;../../isc/include;../../isccfg/include;../../dns/include;@LIBXML2_INC@@GEOIP_INC@%(AdditionalIncludeDirectories) false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true Console true ../../isc/win32/$(Configuration);../../dns/win32/$(Configuration);../../isccfg/win32/$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;libdns.lib;libisccfg.lib;ws2_32.lib;%(AdditionalDependencies) .\libbind9.def .\$(Configuration)\$(ProjectName).lib ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Level3 MaxSpeed true @INTRINSIC@ WIN32;USE_MD5;@CRYPTO@NDEBUG;_WINDOWS;_USRDLL;LIBBIND9_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions) ./;../../../;include;../include;../../isc/win32;../../isc/win32/include;../../isc/include;../../isccfg/include;../../dns/include;@LIBXML2_INC@@GEOIP_INC@%(AdditionalIncludeDirectories) OnlyExplicitInline false true .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb Console false true true ../../isc/win32/$(Configuration);../../dns/win32/$(Configuration);../../isccfg/win32/$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;libdns.lib;libisccfg.lib;ws2_32.lib;%(AdditionalDependencies) .\libbind9.def .\$(Configuration)\$(ProjectName).lib Default ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) bind9-9.10.3.dfsg.P4/lib/bind9/win32/version.c0000644000470500017500000000233512664710322017742 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: version.c,v 1.5 2007/06/19 23:47:16 tbox Exp $ */ #include #include LIBBIND9_EXTERNAL_DATA const char bind9_version[] = VERSION; LIBBIND9_EXTERNAL_DATA const unsigned int bind9_libinterface = LIBINTERFACE; LIBBIND9_EXTERNAL_DATA const unsigned int bind9_librevision = LIBREVISION; LIBBIND9_EXTERNAL_DATA const unsigned int bind9_libage = LIBAGE; bind9-9.10.3.dfsg.P4/lib/bind9/win32/libbind9.dsp.in0000644000470500017500000001213712664710322020723 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="libbind9" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Dynamic-Link Library" 0x0102 CFG=libbind9 - @PLATFORM@ Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "libbind9.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "libbind9.mak" CFG="libbind9 - @PLATFORM@ Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "libbind9 - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE "libbind9 - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "libbind9 - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "libbind9_EXPORTS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 @LIBXML2_INC@ @GEOIP_INC@ /I "../../../lib/dns/win32/include" /I "./" /I "../../../" /I "include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isccfg/include" /I "../../../lib/dns/include" /I "../../../lib/isc/include" /D "NDEBUG" /D "WIN32" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ /D "LIBBIND9_EXPORTS" @COPTY@ /FD /c # SUBTRACT CPP /X # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll @MACHINE@ # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Release/libisc.lib ../../dns/win32/Release/libdns.lib ../../isccfg/win32/Release/libisccfg.lib /nologo /dll @MACHINE@ /out:"../../../Build/Release/libbind9.dll" !ELSEIF "$(CFG)" == "libbind9 - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "libbind9_EXPORTS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od @LIBXML2_INC@ @GEOIP_INC@ /I "../../../lib/isccfg/include" /I "./" /I "../../../" /I "include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isc/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ /D "LIBBIND9_EXPORTS" /FR @COPTY@ /FD /GZ /c # SUBTRACT CPP /X # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../isc/win32/debug/libisc.lib ../../dns/win32/debug/libdns.lib ../../isccfg/win32/debug/libisccfg.lib /nologo /dll /debug @MACHINE@ /out:"../../../Build/Debug/libbind9.dll" /pdbtype:sept !ENDIF # Begin Target # Name "libbind9 - @PLATFORM@ Release" # Name "libbind9 - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\check.c # End Source File # Begin Source File SOURCE=.\DLLMain.c # End Source File # Begin Source File SOURCE=..\getaddresses.c # End Source File # Begin Source File SOURCE=.\version.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=..\include\bind9\check.h # End Source File # Begin Source File SOURCE=..\include\bind9\version.h # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # Begin Source File SOURCE=.\libbind9.def # End Source File # End Target # End Project bind9-9.10.3.dfsg.P4/lib/bind9/win32/libbind9.mak.in0000644000470500017500000003130012664710322020676 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on libbind9.dsp !IF "$(CFG)" == "" CFG=libbind9 - @PLATFORM@ Release !MESSAGE No configuration specified. Defaulting to libbind9 - @PLATFORM@ Release. !ENDIF !IF "$(CFG)" != "libbind9 - @PLATFORM@ Release" && "$(CFG)" != "libbind9 - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "libbind9.mak" CFG="libbind9 - @PLATFORM@ Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "libbind9 - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE "libbind9 - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "libbind9 - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "libbind9 - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release !IF "$(RECURSE)" == "0" ALL : "..\..\..\Build\Release\libbind9.dll" !ELSE ALL : "libisccfg - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" "libdns - @PLATFORM@ Release" "..\..\..\Build\Release\libbind9.dll" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libdns - @PLATFORM@ ReleaseCLEAN" "libisc - @PLATFORM@ ReleaseCLEAN" "libisccfg - @PLATFORM@ ReleaseCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\check.obj" -@erase "$(INTDIR)\DLLMain.obj" -@erase "$(INTDIR)\getaddresses.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\version.obj" -@erase "$(OUTDIR)\libbind9.exp" -@erase "$(OUTDIR)\libbind9.lib" -@erase "..\..\..\Build\Release\libbind9.dll" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 @LIBXML2_INC@ @GEOIP_INC@ /I "../../../lib/dns/win32/include" /I "./" /I "../../../" /I "include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isccfg/include" /I "../../../lib/dns/include" /I "../../../lib/isc/include" /D "NDEBUG" /D "WIN32" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ /D "LIBBIND9_EXPORTS" /Fp"$(INTDIR)\libbind9.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\libbind9.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Release/libisc.lib ../../dns/win32/Release/libdns.lib ../../isccfg/win32/Release/libisccfg.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\libbind9.pdb" @MACHINE@ /def:".\libbind9.def" /out:"../../../Build/Release/libbind9.dll" /implib:"$(OUTDIR)\libbind9.lib" DEF_FILE= \ ".\libbind9.def" LINK32_OBJS= \ "$(INTDIR)\check.obj" \ "$(INTDIR)\DLLMain.obj" \ "$(INTDIR)\getaddresses.obj" \ "$(INTDIR)\version.obj" \ "..\..\dns\win32\Release\libdns.lib" \ "..\..\isc\win32\Release\libisc.lib" \ "..\..\isccfg\win32\Release\libisccfg.lib" "..\..\..\Build\Release\libbind9.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_DLL) !ELSEIF "$(CFG)" == "libbind9 - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros !IF "$(RECURSE)" == "0" ALL : "..\..\..\Build\Debug\libbind9.dll" "$(OUTDIR)\libbind9.bsc" !ELSE ALL : "libisccfg - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" "libdns - @PLATFORM@ Debug" "..\..\..\Build\Debug\libbind9.dll" "$(OUTDIR)\libbind9.bsc" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libdns - @PLATFORM@ DebugCLEAN" "libisc - @PLATFORM@ DebugCLEAN" "libisccfg - @PLATFORM@ DebugCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\check.obj" -@erase "$(INTDIR)\check.sbr" -@erase "$(INTDIR)\DLLMain.obj" -@erase "$(INTDIR)\DLLMain.sbr" -@erase "$(INTDIR)\getaddresses.obj" -@erase "$(INTDIR)\getaddresses.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(INTDIR)\version.obj" -@erase "$(INTDIR)\version.sbr" -@erase "$(OUTDIR)\libbind9.bsc" -@erase "$(OUTDIR)\libbind9.exp" -@erase "$(OUTDIR)\libbind9.lib" -@erase "$(OUTDIR)\libbind9.pdb" -@erase "..\..\..\Build\Debug\libbind9.dll" -@erase "..\..\..\Build\Debug\libbind9.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od @LIBXML2_INC@ @GEOIP_INC@ /I "../../../lib/isccfg/include" /I "./" /I "../../../" /I "include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isc/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ /D "LIBBIND9_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\libbind9.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\libbind9.bsc" BSC32_SBRS= \ "$(INTDIR)\check.sbr" \ "$(INTDIR)\DLLMain.sbr" \ "$(INTDIR)\getaddresses.sbr" \ "$(INTDIR)\version.sbr" "$(OUTDIR)\libbind9.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../isc/win32/debug/libisc.lib ../../dns/win32/debug/libdns.lib ../../isccfg/win32/debug/libisccfg.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\libbind9.pdb" /debug @MACHINE@ /def:".\libbind9.def" /out:"../../../Build/Debug/libbind9.dll" /implib:"$(OUTDIR)\libbind9.lib" /pdbtype:sept DEF_FILE= \ ".\libbind9.def" LINK32_OBJS= \ "$(INTDIR)\check.obj" \ "$(INTDIR)\DLLMain.obj" \ "$(INTDIR)\getaddresses.obj" \ "$(INTDIR)\version.obj" \ "..\..\dns\win32\Debug\libdns.lib" \ "..\..\isc\win32\Debug\libisc.lib" \ "..\..\isccfg\win32\Debug\libisccfg.lib" "..\..\..\Build\Debug\libbind9.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_DLL) !ENDIF .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("libbind9.dep") !INCLUDE "libbind9.dep" !ELSE !MESSAGE Warning: cannot find "libbind9.dep" !ENDIF !ENDIF !IF "$(CFG)" == "libbind9 - @PLATFORM@ Release" || "$(CFG)" == "libbind9 - @PLATFORM@ Debug" SOURCE=..\check.c !IF "$(CFG)" == "libbind9 - @PLATFORM@ Release" "$(INTDIR)\check.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libbind9 - @PLATFORM@ Debug" "$(INTDIR)\check.obj" "$(INTDIR)\check.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=.\DLLMain.c !IF "$(CFG)" == "libbind9 - @PLATFORM@ Release" "$(INTDIR)\DLLMain.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libbind9 - @PLATFORM@ Debug" "$(INTDIR)\DLLMain.obj" "$(INTDIR)\DLLMain.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=..\getaddresses.c !IF "$(CFG)" == "libbind9 - @PLATFORM@ Release" "$(INTDIR)\getaddresses.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libbind9 - @PLATFORM@ Debug" "$(INTDIR)\getaddresses.obj" "$(INTDIR)\getaddresses.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=.\version.c !IF "$(CFG)" == "libbind9 - @PLATFORM@ Release" "$(INTDIR)\version.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libbind9 - @PLATFORM@ Debug" "$(INTDIR)\version.obj" "$(INTDIR)\version.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF !IF "$(CFG)" == "libbind9 - @PLATFORM@ Release" "libdns - @PLATFORM@ Release" : cd "..\..\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" cd "..\..\bind9\win32" "libdns - @PLATFORM@ ReleaseCLEAN" : cd "..\..\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\bind9\win32" !ELSEIF "$(CFG)" == "libbind9 - @PLATFORM@ Debug" "libdns - @PLATFORM@ Debug" : cd "..\..\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" cd "..\..\bind9\win32" "libdns - @PLATFORM@ DebugCLEAN" : cd "..\..\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\bind9\win32" !ENDIF !IF "$(CFG)" == "libbind9 - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" cd "..\..\bind9\win32" "libisc - @PLATFORM@ ReleaseCLEAN" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\bind9\win32" !ELSEIF "$(CFG)" == "libbind9 - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" cd "..\..\bind9\win32" "libisc - @PLATFORM@ DebugCLEAN" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\bind9\win32" !ENDIF !IF "$(CFG)" == "libbind9 - @PLATFORM@ Release" "libisccfg - @PLATFORM@ Release" : cd "..\..\isccfg\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Release" cd "..\..\bind9\win32" "libisccfg - @PLATFORM@ ReleaseCLEAN" : cd "..\..\isccfg\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\bind9\win32" !ELSEIF "$(CFG)" == "libbind9 - @PLATFORM@ Debug" "libisccfg - @PLATFORM@ Debug" : cd "..\..\isccfg\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Debug" cd "..\..\bind9\win32" "libisccfg - @PLATFORM@ DebugCLEAN" : cd "..\..\isccfg\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\bind9\win32" !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/lib/bind9/win32/DLLMain.c0000644000470500017500000000313212664710322017471 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: DLLMain.c,v 1.4 2007/06/18 23:47:39 tbox Exp $ */ #include #include /* * Called when we enter the DLL */ __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { /* * The DLL is loading due to process * initialization or a call to LoadLibrary. */ case DLL_PROCESS_ATTACH: break; /* The attached process creates a new thread. */ case DLL_THREAD_ATTACH: break; /* The thread of the attached process terminates. */ case DLL_THREAD_DETACH: break; /* * The DLL is unloading from a process due to * process termination or a call to FreeLibrary. */ case DLL_PROCESS_DETACH: break; default: break; } return (TRUE); } bind9-9.10.3.dfsg.P4/lib/bind9/win32/libbind9.def0000644000470500017500000000015112664710322020257 0ustar lamontlamontLIBRARY libbind9 ; Exported Functions EXPORTS bind9_check_namedconf bind9_check_key bind9_getaddresses bind9-9.10.3.dfsg.P4/lib/bind9/win32/libbind9.vcxproj.user0000644000470500017500000000021712664710322022174 0ustar lamontlamont bind9-9.10.3.dfsg.P4/lib/bind9/win32/libbind9.vcxproj.filters.in0000644000470500017500000000302712664710322023275 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files Source Files Source Files Source Files Header Files Header Files bind9-9.10.3.dfsg.P4/lib/bind9/win32/libbind9.dsw0000644000470500017500000000103312664710322020316 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "libbind9"=.\libbind9.dsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/lib/bind9/api0000644000470500017500000000025712664710322015644 0ustar lamontlamont# LIBINTERFACE ranges # 9.6: 50-59, 110-119 # 9.7: 60-79 # 9.8: 80-89, 120-129 # 9.9: 90-109 # 9.9-sub: 130-139 # 9.10: 140-149 LIBINTERFACE = 140 LIBREVISION = 10 LIBAGE = 0 bind9-9.10.3.dfsg.P4/lib/lwres/0002755000470500017500000000000012672612753015305 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/lwres/lwconfig.c0000644000470500017500000004411112664710322017250 0ustar lamontlamont/* * Copyright (C) 2004-2008, 2011, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ /** * Module for parsing resolv.conf files. * * lwres_conf_init() creates an empty lwres_conf_t structure for * lightweight resolver context ctx. * * lwres_conf_clear() frees up all the internal memory used by that * lwres_conf_t structure in resolver context ctx. * * lwres_conf_parse() opens the file filename and parses it to initialise * the resolver context ctx's lwres_conf_t structure. * * lwres_conf_print() prints the lwres_conf_t structure for resolver * context ctx to the FILE fp. * * \section lwconfig_return Return Values * * lwres_conf_parse() returns #LWRES_R_SUCCESS if it successfully read and * parsed filename. It returns #LWRES_R_FAILURE if filename could not be * opened or contained incorrect resolver statements. * * lwres_conf_print() returns #LWRES_R_SUCCESS unless an error occurred * when converting the network addresses to a numeric host address * string. If this happens, the function returns #LWRES_R_FAILURE. * * \section lwconfig_see See Also * * stdio(3), \link resolver resolver \endlink * * \section files Files * * /etc/resolv.conf */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "assert_p.h" #include "context_p.h" #include "print_p.h" #if ! defined(NS_INADDRSZ) #define NS_INADDRSZ 4 #endif #if ! defined(NS_IN6ADDRSZ) #define NS_IN6ADDRSZ 16 #endif static lwres_result_t lwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp); static lwres_result_t lwres_conf_parselwserver(lwres_context_t *ctx, FILE *fp); static lwres_result_t lwres_conf_parsedomain(lwres_context_t *ctx, FILE *fp); static lwres_result_t lwres_conf_parsesearch(lwres_context_t *ctx, FILE *fp); static lwres_result_t lwres_conf_parsesortlist(lwres_context_t *ctx, FILE *fp); static lwres_result_t lwres_conf_parseoption(lwres_context_t *ctx, FILE *fp); static void lwres_resetaddr(lwres_addr_t *addr); static lwres_result_t lwres_create_addr(const char *buff, lwres_addr_t *addr, int convert_zero); static int lwresaddr2af(int lwresaddrtype); static int lwresaddr2af(int lwresaddrtype) { int af = 0; switch (lwresaddrtype) { case LWRES_ADDRTYPE_V4: af = AF_INET; break; case LWRES_ADDRTYPE_V6: af = AF_INET6; break; } return (af); } /*! * Eat characters from FP until EOL or EOF. Returns EOF or '\n' */ static int eatline(FILE *fp) { int ch; ch = fgetc(fp); while (ch != '\n' && ch != EOF) ch = fgetc(fp); return (ch); } /*! * Eats white space up to next newline or non-whitespace character (of * EOF). Returns the last character read. Comments are considered white * space. */ static int eatwhite(FILE *fp) { int ch; ch = fgetc(fp); while (ch != '\n' && ch != EOF && isspace((unsigned char)ch)) ch = fgetc(fp); if (ch == ';' || ch == '#') ch = eatline(fp); return (ch); } /*! * Skip over any leading whitespace and then read in the next sequence of * non-whitespace characters. In this context newline is not considered * whitespace. Returns EOF on end-of-file, or the character * that caused the reading to stop. */ static int getword(FILE *fp, char *buffer, size_t size) { int ch; char *p = buffer; REQUIRE(buffer != NULL); REQUIRE(size > 0U); *p = '\0'; ch = eatwhite(fp); if (ch == EOF) return (EOF); do { *p = '\0'; if (ch == EOF || isspace((unsigned char)ch)) break; else if ((size_t) (p - buffer) == size - 1) return (EOF); /* Not enough space. */ *p++ = (char)ch; ch = fgetc(fp); } while (1); return (ch); } static void lwres_resetaddr(lwres_addr_t *addr) { REQUIRE(addr != NULL); memset(addr->address, 0, LWRES_ADDR_MAXLEN); addr->family = 0; addr->length = 0; addr->zone = 0; } static char * lwres_strdup(lwres_context_t *ctx, const char *str) { char *p; REQUIRE(str != NULL); REQUIRE(strlen(str) > 0U); p = CTXMALLOC(strlen(str) + 1); if (p != NULL) strcpy(p, str); return (p); } /*% intializes data structure for subsequent config parsing. */ void lwres_conf_init(lwres_context_t *ctx) { int i; lwres_conf_t *confdata; REQUIRE(ctx != NULL); confdata = &ctx->confdata; confdata->nsnext = 0; confdata->lwnext = 0; confdata->domainname = NULL; confdata->searchnxt = 0; confdata->sortlistnxt = 0; confdata->resdebug = 0; confdata->ndots = 1; confdata->no_tld_query = 0; for (i = 0; i < LWRES_CONFMAXNAMESERVERS; i++) lwres_resetaddr(&confdata->nameservers[i]); for (i = 0; i < LWRES_CONFMAXSEARCH; i++) confdata->search[i] = NULL; for (i = 0; i < LWRES_CONFMAXSORTLIST; i++) { lwres_resetaddr(&confdata->sortlist[i].addr); lwres_resetaddr(&confdata->sortlist[i].mask); } } /*% Frees up all the internal memory used by the config data structure, returning it to the lwres_context_t. */ void lwres_conf_clear(lwres_context_t *ctx) { int i; lwres_conf_t *confdata; REQUIRE(ctx != NULL); confdata = &ctx->confdata; for (i = 0; i < confdata->nsnext; i++) lwres_resetaddr(&confdata->nameservers[i]); if (confdata->domainname != NULL) { CTXFREE(confdata->domainname, strlen(confdata->domainname) + 1); confdata->domainname = NULL; } for (i = 0; i < confdata->searchnxt; i++) { if (confdata->search[i] != NULL) { CTXFREE(confdata->search[i], strlen(confdata->search[i]) + 1); confdata->search[i] = NULL; } } for (i = 0; i < LWRES_CONFMAXSORTLIST; i++) { lwres_resetaddr(&confdata->sortlist[i].addr); lwres_resetaddr(&confdata->sortlist[i].mask); } confdata->nsnext = 0; confdata->lwnext = 0; confdata->domainname = NULL; confdata->searchnxt = 0; confdata->sortlistnxt = 0; confdata->resdebug = 0; confdata->ndots = 1; confdata->no_tld_query = 0; } static lwres_result_t lwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp) { char word[LWRES_CONFMAXLINELEN]; int res; lwres_conf_t *confdata; lwres_addr_t address; confdata = &ctx->confdata; if (confdata->nsnext == LWRES_CONFMAXNAMESERVERS) return (LWRES_R_SUCCESS); res = getword(fp, word, sizeof(word)); if (strlen(word) == 0U) return (LWRES_R_FAILURE); /* Nothing on line. */ else if (res == ' ' || res == '\t') res = eatwhite(fp); if (res != EOF && res != '\n') return (LWRES_R_FAILURE); /* Extra junk on line. */ res = lwres_create_addr(word, &address, 1); if (res == LWRES_R_SUCCESS && ((address.family == LWRES_ADDRTYPE_V4 && ctx->use_ipv4 == 1) || (address.family == LWRES_ADDRTYPE_V6 && ctx->use_ipv6 == 1))) { confdata->nameservers[confdata->nsnext++] = address; } return (LWRES_R_SUCCESS); } static lwres_result_t lwres_conf_parselwserver(lwres_context_t *ctx, FILE *fp) { char word[LWRES_CONFMAXLINELEN]; int res; lwres_conf_t *confdata; confdata = &ctx->confdata; if (confdata->lwnext == LWRES_CONFMAXLWSERVERS) return (LWRES_R_SUCCESS); res = getword(fp, word, sizeof(word)); if (strlen(word) == 0U) return (LWRES_R_FAILURE); /* Nothing on line. */ else if (res == ' ' || res == '\t') res = eatwhite(fp); if (res != EOF && res != '\n') return (LWRES_R_FAILURE); /* Extra junk on line. */ res = lwres_create_addr(word, &confdata->lwservers[confdata->lwnext++], 1); if (res != LWRES_R_SUCCESS) return (res); return (LWRES_R_SUCCESS); } static lwres_result_t lwres_conf_parsedomain(lwres_context_t *ctx, FILE *fp) { char word[LWRES_CONFMAXLINELEN]; int res, i; lwres_conf_t *confdata; confdata = &ctx->confdata; res = getword(fp, word, sizeof(word)); if (strlen(word) == 0U) return (LWRES_R_FAILURE); /* Nothing else on line. */ else if (res == ' ' || res == '\t') res = eatwhite(fp); if (res != EOF && res != '\n') return (LWRES_R_FAILURE); /* Extra junk on line. */ if (confdata->domainname != NULL) CTXFREE(confdata->domainname, strlen(confdata->domainname) + 1); /* */ /* * Search and domain are mutually exclusive. */ for (i = 0; i < LWRES_CONFMAXSEARCH; i++) { if (confdata->search[i] != NULL) { CTXFREE(confdata->search[i], strlen(confdata->search[i])+1); confdata->search[i] = NULL; } } confdata->searchnxt = 0; confdata->domainname = lwres_strdup(ctx, word); if (confdata->domainname == NULL) return (LWRES_R_FAILURE); return (LWRES_R_SUCCESS); } static lwres_result_t lwres_conf_parsesearch(lwres_context_t *ctx, FILE *fp) { int idx, delim; char word[LWRES_CONFMAXLINELEN]; lwres_conf_t *confdata; confdata = &ctx->confdata; if (confdata->domainname != NULL) { /* * Search and domain are mutually exclusive. */ CTXFREE(confdata->domainname, strlen(confdata->domainname) + 1); confdata->domainname = NULL; } /* * Remove any previous search definitions. */ for (idx = 0; idx < LWRES_CONFMAXSEARCH; idx++) { if (confdata->search[idx] != NULL) { CTXFREE(confdata->search[idx], strlen(confdata->search[idx])+1); confdata->search[idx] = NULL; } } confdata->searchnxt = 0; delim = getword(fp, word, sizeof(word)); if (strlen(word) == 0U) return (LWRES_R_FAILURE); /* Nothing else on line. */ idx = 0; while (strlen(word) > 0U) { if (confdata->searchnxt == LWRES_CONFMAXSEARCH) goto ignore; /* Too many domains. */ confdata->search[idx] = lwres_strdup(ctx, word); if (confdata->search[idx] == NULL) return (LWRES_R_FAILURE); idx++; confdata->searchnxt++; ignore: if (delim == EOF || delim == '\n') break; else delim = getword(fp, word, sizeof(word)); } return (LWRES_R_SUCCESS); } static lwres_result_t lwres_create_addr(const char *buffer, lwres_addr_t *addr, int convert_zero) { struct in_addr v4; struct in6_addr v6; char buf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") + sizeof("%4294967295")]; char *percent; size_t n; n = strlcpy(buf, buffer, sizeof(buf)); if (n >= sizeof(buf)) return (LWRES_R_FAILURE); percent = strchr(buf, '%'); if (percent != NULL) *percent = 0; if (lwres_net_aton(buffer, &v4) == 1) { if (convert_zero) { unsigned char zeroaddress[] = {0, 0, 0, 0}; unsigned char loopaddress[] = {127, 0, 0, 1}; if (memcmp(&v4, zeroaddress, 4) == 0) memmove(&v4, loopaddress, 4); } addr->family = LWRES_ADDRTYPE_V4; addr->length = NS_INADDRSZ; addr->zone = 0; memmove((void *)addr->address, &v4, NS_INADDRSZ); } else if (lwres_net_pton(AF_INET6, buf, &v6) == 1) { addr->family = LWRES_ADDRTYPE_V6; addr->length = NS_IN6ADDRSZ; memmove((void *)addr->address, &v6, NS_IN6ADDRSZ); if (percent != NULL) { unsigned long zone; char *ep; percent++; #ifdef HAVE_IF_NAMETOINDEX zone = if_nametoindex(percent); if (zone != 0U) { addr->zone = zone; return (LWRES_R_SUCCESS); } #endif zone = strtoul(percent, &ep, 10); if (ep != percent && *ep == 0) addr->zone = zone; else return (LWRES_R_FAILURE); } else addr->zone = 0; } else return (LWRES_R_FAILURE); /* Unrecognised format. */ return (LWRES_R_SUCCESS); } static lwres_result_t lwres_conf_parsesortlist(lwres_context_t *ctx, FILE *fp) { int delim, res, idx; char word[LWRES_CONFMAXLINELEN]; char *p; lwres_conf_t *confdata; confdata = &ctx->confdata; delim = getword(fp, word, sizeof(word)); if (strlen(word) == 0U) return (LWRES_R_FAILURE); /* Empty line after keyword. */ while (strlen(word) > 0U) { if (confdata->sortlistnxt == LWRES_CONFMAXSORTLIST) return (LWRES_R_FAILURE); /* Too many values. */ p = strchr(word, '/'); if (p != NULL) *p++ = '\0'; idx = confdata->sortlistnxt; res = lwres_create_addr(word, &confdata->sortlist[idx].addr, 1); if (res != LWRES_R_SUCCESS) return (res); if (p != NULL) { res = lwres_create_addr(p, &confdata->sortlist[idx].mask, 0); if (res != LWRES_R_SUCCESS) return (res); } else { /* * Make up a mask. */ confdata->sortlist[idx].mask = confdata->sortlist[idx].addr; memset(&confdata->sortlist[idx].mask.address, 0xff, confdata->sortlist[idx].addr.length); } confdata->sortlistnxt++; if (delim == EOF || delim == '\n') break; else delim = getword(fp, word, sizeof(word)); } return (LWRES_R_SUCCESS); } static lwres_result_t lwres_conf_parseoption(lwres_context_t *ctx, FILE *fp) { int delim; long ndots; char *p; char word[LWRES_CONFMAXLINELEN]; lwres_conf_t *confdata; REQUIRE(ctx != NULL); confdata = &ctx->confdata; delim = getword(fp, word, sizeof(word)); if (strlen(word) == 0U) return (LWRES_R_FAILURE); /* Empty line after keyword. */ while (strlen(word) > 0U) { if (strcmp("debug", word) == 0) { confdata->resdebug = 1; } else if (strcmp("no_tld_query", word) == 0) { confdata->no_tld_query = 1; } else if (strncmp("ndots:", word, 6) == 0) { ndots = strtol(word + 6, &p, 10); if (*p != '\0') /* Bad string. */ return (LWRES_R_FAILURE); if (ndots < 0 || ndots > 0xff) /* Out of range. */ return (LWRES_R_FAILURE); confdata->ndots = (lwres_uint8_t)ndots; } if (delim == EOF || delim == '\n') break; else delim = getword(fp, word, sizeof(word)); } return (LWRES_R_SUCCESS); } /*% parses a file and fills in the data structure. */ lwres_result_t lwres_conf_parse(lwres_context_t *ctx, const char *filename) { FILE *fp = NULL; char word[256]; lwres_result_t rval, ret; lwres_conf_t *confdata; int stopchar; REQUIRE(ctx != NULL); confdata = &ctx->confdata; REQUIRE(filename != NULL); REQUIRE(strlen(filename) > 0U); REQUIRE(confdata != NULL); errno = 0; if ((fp = fopen(filename, "r")) == NULL) return (LWRES_R_NOTFOUND); ret = LWRES_R_SUCCESS; do { stopchar = getword(fp, word, sizeof(word)); if (stopchar == EOF) { rval = LWRES_R_SUCCESS; POST(rval); break; } if (strlen(word) == 0U) rval = LWRES_R_SUCCESS; else if (strcmp(word, "nameserver") == 0) rval = lwres_conf_parsenameserver(ctx, fp); else if (strcmp(word, "lwserver") == 0) rval = lwres_conf_parselwserver(ctx, fp); else if (strcmp(word, "domain") == 0) rval = lwres_conf_parsedomain(ctx, fp); else if (strcmp(word, "search") == 0) rval = lwres_conf_parsesearch(ctx, fp); else if (strcmp(word, "sortlist") == 0) rval = lwres_conf_parsesortlist(ctx, fp); else if (strcmp(word, "options") == 0) rval = lwres_conf_parseoption(ctx, fp); else { /* unrecognised word. Ignore entire line */ rval = LWRES_R_SUCCESS; stopchar = eatline(fp); if (stopchar == EOF) { break; } } if (ret == LWRES_R_SUCCESS && rval != LWRES_R_SUCCESS) ret = rval; } while (1); fclose(fp); return (ret); } /*% Prints the config data structure to the FILE. */ lwres_result_t lwres_conf_print(lwres_context_t *ctx, FILE *fp) { int i; int af; char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; char buf[sizeof("%4000000000")]; const char *p; lwres_conf_t *confdata; lwres_addr_t tmpaddr; REQUIRE(ctx != NULL); confdata = &ctx->confdata; REQUIRE(confdata->nsnext <= LWRES_CONFMAXNAMESERVERS); for (i = 0; i < confdata->nsnext; i++) { af = lwresaddr2af(confdata->nameservers[i].family); p = lwres_net_ntop(af, confdata->nameservers[i].address, tmp, sizeof(tmp)); if (p != tmp) return (LWRES_R_FAILURE); if (af == AF_INET6 && confdata->lwservers[i].zone != 0) { snprintf(buf, sizeof(buf), "%%%u", confdata->nameservers[i].zone); } else buf[0] = 0; fprintf(fp, "nameserver %s%s\n", tmp, buf); } for (i = 0; i < confdata->lwnext; i++) { af = lwresaddr2af(confdata->lwservers[i].family); p = lwres_net_ntop(af, confdata->lwservers[i].address, tmp, sizeof(tmp)); if (p != tmp) return (LWRES_R_FAILURE); if (af == AF_INET6 && confdata->lwservers[i].zone != 0) { snprintf(buf, sizeof(buf), "%%%u", confdata->nameservers[i].zone); } else buf[0] = 0; fprintf(fp, "lwserver %s%s\n", tmp, buf); } if (confdata->domainname != NULL) { fprintf(fp, "domain %s\n", confdata->domainname); } else if (confdata->searchnxt > 0) { REQUIRE(confdata->searchnxt <= LWRES_CONFMAXSEARCH); fprintf(fp, "search"); for (i = 0; i < confdata->searchnxt; i++) fprintf(fp, " %s", confdata->search[i]); fputc('\n', fp); } REQUIRE(confdata->sortlistnxt <= LWRES_CONFMAXSORTLIST); if (confdata->sortlistnxt > 0) { fputs("sortlist", fp); for (i = 0; i < confdata->sortlistnxt; i++) { af = lwresaddr2af(confdata->sortlist[i].addr.family); p = lwres_net_ntop(af, confdata->sortlist[i].addr.address, tmp, sizeof(tmp)); if (p != tmp) return (LWRES_R_FAILURE); fprintf(fp, " %s", tmp); tmpaddr = confdata->sortlist[i].mask; memset(&tmpaddr.address, 0xff, tmpaddr.length); if (memcmp(&tmpaddr.address, confdata->sortlist[i].mask.address, confdata->sortlist[i].mask.length) != 0) { af = lwresaddr2af( confdata->sortlist[i].mask.family); p = lwres_net_ntop (af, confdata->sortlist[i].mask.address, tmp, sizeof(tmp)); if (p != tmp) return (LWRES_R_FAILURE); fprintf(fp, "/%s", tmp); } } fputc('\n', fp); } if (confdata->resdebug) fprintf(fp, "options debug\n"); if (confdata->ndots > 0) fprintf(fp, "options ndots:%d\n", confdata->ndots); if (confdata->no_tld_query) fprintf(fp, "options no_tld_query\n"); return (LWRES_R_SUCCESS); } /*% Returns a pointer to the current config structure. */ lwres_conf_t * lwres_conf_get(lwres_context_t *ctx) { REQUIRE(ctx != NULL); return (&ctx->confdata); } bind9-9.10.3.dfsg.P4/lib/lwres/lwres_grbn.c0000644000470500017500000002445312664710322017613 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lwres_grbn.c,v 1.10 2007/06/19 23:47:22 tbox Exp $ */ /*! \file lwres_grbn.c */ #include #include #include #include #include #include #include #include #include "context_p.h" #include "assert_p.h" /*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */ lwres_result_t lwres_grbnrequest_render(lwres_context_t *ctx, lwres_grbnrequest_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b) { unsigned char *buf; size_t buflen; int ret; size_t payload_length; lwres_uint16_t datalen; REQUIRE(ctx != NULL); REQUIRE(req != NULL); REQUIRE(req->name != NULL); REQUIRE(pkt != NULL); REQUIRE(b != NULL); datalen = strlen(req->name); payload_length = 4 + 2 + 2 + 2 + req->namelen + 1; buflen = LWRES_LWPACKET_LENGTH + payload_length; buf = CTXMALLOC(buflen); if (buf == NULL) return (LWRES_R_NOMEMORY); lwres_buffer_init(b, buf, (unsigned int)buflen); pkt->length = (lwres_uint32_t)buflen; pkt->version = LWRES_LWPACKETVERSION_0; pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE; pkt->opcode = LWRES_OPCODE_GETRDATABYNAME; pkt->result = 0; pkt->authtype = 0; pkt->authlength = 0; ret = lwres_lwpacket_renderheader(b, pkt); if (ret != LWRES_R_SUCCESS) { lwres_buffer_invalidate(b); CTXFREE(buf, buflen); return (ret); } INSIST(SPACE_OK(b, payload_length)); /* * Flags. */ lwres_buffer_putuint32(b, req->flags); /* * Class. */ lwres_buffer_putuint16(b, req->rdclass); /* * Type. */ lwres_buffer_putuint16(b, req->rdtype); /* * Put the length and the data. We know this will fit because we * just checked for it. */ lwres_buffer_putuint16(b, datalen); lwres_buffer_putmem(b, (unsigned char *)req->name, datalen); lwres_buffer_putuint8(b, 0); /* trailing NUL */ INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0); return (LWRES_R_SUCCESS); } /*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */ lwres_result_t lwres_grbnresponse_render(lwres_context_t *ctx, lwres_grbnresponse_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b) { unsigned char *buf; size_t buflen; int ret; size_t payload_length; lwres_uint16_t datalen; int x; REQUIRE(ctx != NULL); REQUIRE(req != NULL); REQUIRE(pkt != NULL); REQUIRE(b != NULL); /* flags, class, type, ttl, nrdatas, nsigs */ payload_length = 4 + 2 + 2 + 4 + 2 + 2; /* real name encoding */ payload_length += 2 + req->realnamelen + 1; /* each rr */ for (x = 0; x < req->nrdatas; x++) payload_length += 2 + req->rdatalen[x]; for (x = 0; x < req->nsigs; x++) payload_length += 2 + req->siglen[x]; buflen = LWRES_LWPACKET_LENGTH + payload_length; buf = CTXMALLOC(buflen); if (buf == NULL) return (LWRES_R_NOMEMORY); lwres_buffer_init(b, buf, (unsigned int)buflen); pkt->length = (lwres_uint32_t)buflen; pkt->version = LWRES_LWPACKETVERSION_0; pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE; pkt->opcode = LWRES_OPCODE_GETRDATABYNAME; pkt->authtype = 0; pkt->authlength = 0; ret = lwres_lwpacket_renderheader(b, pkt); if (ret != LWRES_R_SUCCESS) { lwres_buffer_invalidate(b); CTXFREE(buf, buflen); return (ret); } /* * Check space needed here. */ INSIST(SPACE_OK(b, payload_length)); /* Flags. */ lwres_buffer_putuint32(b, req->flags); /* encode class, type, ttl, and nrdatas */ lwres_buffer_putuint16(b, req->rdclass); lwres_buffer_putuint16(b, req->rdtype); lwres_buffer_putuint32(b, req->ttl); lwres_buffer_putuint16(b, req->nrdatas); lwres_buffer_putuint16(b, req->nsigs); /* encode the real name */ datalen = req->realnamelen; lwres_buffer_putuint16(b, datalen); lwres_buffer_putmem(b, (unsigned char *)req->realname, datalen); lwres_buffer_putuint8(b, 0); /* encode the rdatas */ for (x = 0; x < req->nrdatas; x++) { datalen = req->rdatalen[x]; lwres_buffer_putuint16(b, datalen); lwres_buffer_putmem(b, req->rdatas[x], datalen); } /* encode the signatures */ for (x = 0; x < req->nsigs; x++) { datalen = req->siglen[x]; lwres_buffer_putuint16(b, datalen); lwres_buffer_putmem(b, req->sigs[x], datalen); } INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0); INSIST(LWRES_BUFFER_USEDCOUNT(b) == pkt->length); return (LWRES_R_SUCCESS); } /*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */ lwres_result_t lwres_grbnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_grbnrequest_t **structp) { int ret; char *name; lwres_grbnrequest_t *grbn; lwres_uint32_t flags; lwres_uint16_t rdclass, rdtype; lwres_uint16_t namelen; REQUIRE(ctx != NULL); REQUIRE(pkt != NULL); REQUIRE(b != NULL); REQUIRE(structp != NULL && *structp == NULL); if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0) return (LWRES_R_FAILURE); if (!SPACE_REMAINING(b, 4 + 2 + 2)) return (LWRES_R_UNEXPECTEDEND); /* * Pull off the flags, class, and type. */ flags = lwres_buffer_getuint32(b); rdclass = lwres_buffer_getuint16(b); rdtype = lwres_buffer_getuint16(b); /* * Pull off the name itself */ ret = lwres_string_parse(b, &name, &namelen); if (ret != LWRES_R_SUCCESS) return (ret); if (LWRES_BUFFER_REMAINING(b) != 0) return (LWRES_R_TRAILINGDATA); grbn = CTXMALLOC(sizeof(lwres_grbnrequest_t)); if (grbn == NULL) return (LWRES_R_NOMEMORY); grbn->flags = flags; grbn->rdclass = rdclass; grbn->rdtype = rdtype; grbn->name = name; grbn->namelen = namelen; *structp = grbn; return (LWRES_R_SUCCESS); } /*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */ lwres_result_t lwres_grbnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_grbnresponse_t **structp) { lwres_result_t ret; unsigned int x; lwres_uint32_t flags; lwres_uint16_t rdclass, rdtype; lwres_uint32_t ttl; lwres_uint16_t nrdatas, nsigs; lwres_grbnresponse_t *grbn; REQUIRE(ctx != NULL); REQUIRE(pkt != NULL); REQUIRE(b != NULL); REQUIRE(structp != NULL && *structp == NULL); grbn = NULL; if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0) return (LWRES_R_FAILURE); /* * Pull off the flags, class, type, ttl, nrdatas, and nsigs */ if (!SPACE_REMAINING(b, 4 + 2 + 2 + 4 + 2 + 2)) return (LWRES_R_UNEXPECTEDEND); flags = lwres_buffer_getuint32(b); rdclass = lwres_buffer_getuint16(b); rdtype = lwres_buffer_getuint16(b); ttl = lwres_buffer_getuint32(b); nrdatas = lwres_buffer_getuint16(b); nsigs = lwres_buffer_getuint16(b); /* * Pull off the name itself */ grbn = CTXMALLOC(sizeof(lwres_grbnresponse_t)); if (grbn == NULL) return (LWRES_R_NOMEMORY); grbn->rdatas = NULL; grbn->rdatalen = NULL; grbn->sigs = NULL; grbn->siglen = NULL; grbn->base = NULL; grbn->flags = flags; grbn->rdclass = rdclass; grbn->rdtype = rdtype; grbn->ttl = ttl; grbn->nrdatas = nrdatas; grbn->nsigs = nsigs; if (nrdatas > 0) { grbn->rdatas = CTXMALLOC(sizeof(char *) * nrdatas); if (grbn->rdatas == NULL) { ret = LWRES_R_NOMEMORY; goto out; } grbn->rdatalen = CTXMALLOC(sizeof(lwres_uint16_t) * nrdatas); if (grbn->rdatalen == NULL) { ret = LWRES_R_NOMEMORY; goto out; } } if (nsigs > 0) { grbn->sigs = CTXMALLOC(sizeof(char *) * nsigs); if (grbn->sigs == NULL) { ret = LWRES_R_NOMEMORY; goto out; } grbn->siglen = CTXMALLOC(sizeof(lwres_uint16_t) * nsigs); if (grbn->siglen == NULL) { ret = LWRES_R_NOMEMORY; goto out; } } /* * Now, pull off the real name. */ ret = lwres_string_parse(b, &grbn->realname, &grbn->realnamelen); if (ret != LWRES_R_SUCCESS) goto out; /* * Parse off the rdatas. */ for (x = 0; x < grbn->nrdatas; x++) { ret = lwres_data_parse(b, &grbn->rdatas[x], &grbn->rdatalen[x]); if (ret != LWRES_R_SUCCESS) goto out; } /* * Parse off the signatures. */ for (x = 0; x < grbn->nsigs; x++) { ret = lwres_data_parse(b, &grbn->sigs[x], &grbn->siglen[x]); if (ret != LWRES_R_SUCCESS) goto out; } if (LWRES_BUFFER_REMAINING(b) != 0) { ret = LWRES_R_TRAILINGDATA; goto out; } *structp = grbn; return (LWRES_R_SUCCESS); out: if (grbn != NULL) { if (grbn->rdatas != NULL) CTXFREE(grbn->rdatas, sizeof(char *) * nrdatas); if (grbn->rdatalen != NULL) CTXFREE(grbn->rdatalen, sizeof(lwres_uint16_t) * nrdatas); if (grbn->sigs != NULL) CTXFREE(grbn->sigs, sizeof(char *) * nsigs); if (grbn->siglen != NULL) CTXFREE(grbn->siglen, sizeof(lwres_uint16_t) * nsigs); CTXFREE(grbn, sizeof(lwres_grbnresponse_t)); } return (ret); } /*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */ void lwres_grbnrequest_free(lwres_context_t *ctx, lwres_grbnrequest_t **structp) { lwres_grbnrequest_t *grbn; REQUIRE(ctx != NULL); REQUIRE(structp != NULL && *structp != NULL); grbn = *structp; *structp = NULL; CTXFREE(grbn, sizeof(lwres_grbnrequest_t)); } /*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */ void lwres_grbnresponse_free(lwres_context_t *ctx, lwres_grbnresponse_t **structp) { lwres_grbnresponse_t *grbn; REQUIRE(ctx != NULL); REQUIRE(structp != NULL && *structp != NULL); grbn = *structp; *structp = NULL; if (grbn->nrdatas > 0) { CTXFREE(grbn->rdatas, sizeof(char *) * grbn->nrdatas); CTXFREE(grbn->rdatalen, sizeof(lwres_uint16_t) * grbn->nrdatas); } if (grbn->nsigs > 0) { CTXFREE(grbn->sigs, sizeof(char *) * grbn->nsigs); CTXFREE(grbn->siglen, sizeof(lwres_uint16_t) * grbn->nsigs); } if (grbn->base != NULL) CTXFREE(grbn->base, grbn->baselen); CTXFREE(grbn, sizeof(lwres_grbnresponse_t)); } bind9-9.10.3.dfsg.P4/lib/lwres/version.c0000644000470500017500000000220012664710322017116 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: version.c,v 1.12 2007/06/19 23:47:22 tbox Exp $ */ /*! \file */ #include const char lwres_version[] = VERSION; const unsigned int lwres_libinterface = LIBINTERFACE; const unsigned int lwres_librevision = LIBREVISION; const unsigned int lwres_libage = LIBAGE; bind9-9.10.3.dfsg.P4/lib/lwres/gethost.c0000644000470500017500000002574012664710322017124 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2013-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: gethost.c,v 1.34 2007/06/19 23:47:22 tbox Exp $ */ /*! \file */ /** * These functions provide hostname-to-address and address-to-hostname * lookups by means of the lightweight resolver. They are similar to the * standard gethostent(3) functions provided by most operating systems. * They use a struct hostent which is usually defined in . * * \code * struct hostent { * char *h_name; // official name of host * char **h_aliases; // alias list * int h_addrtype; // host address type * int h_length; // length of address * char **h_addr_list; // list of addresses from name server * }; * #define h_addr h_addr_list[0] // address, for backward compatibility * \endcode * * The members of this structure are: * * \li h_name: * The official (canonical) name of the host. * * \li h_aliases: * A NULL-terminated array of alternate names (nicknames) for the * host. * * \li h_addrtype: * The type of address being returned -- PF_INET or PF_INET6. * * \li h_length: * The length of the address in bytes. * * \li h_addr_list: * A NULL terminated array of network addresses for the host. Host * addresses are returned in network byte order. * * For backward compatibility with very old software, h_addr is the first * address in h_addr_list. * * lwres_gethostent(), lwres_sethostent(), lwres_endhostent(), * lwres_gethostent_r(), lwres_sethostent_r() and lwres_endhostent_r() * provide iteration over the known host entries on systems that provide * such functionality through facilities like /etc/hosts or NIS. The * lightweight resolver does not currently implement these functions; it * only provides them as stub functions that always return failure. * * lwres_gethostbyname() and lwres_gethostbyname2() look up the hostname * name. lwres_gethostbyname() always looks for an IPv4 address while * lwres_gethostbyname2() looks for an address of protocol family af: * either PF_INET or PF_INET6 -- IPv4 or IPV6 addresses respectively. * Successful calls of the functions return a struct hostent for the name * that was looked up. NULL is returned if the lookups by * lwres_gethostbyname() or lwres_gethostbyname2() fail. * * Reverse lookups of addresses are performed by lwres_gethostbyaddr(). * addr is an address of length len bytes and protocol family type -- * PF_INET or PF_INET6. lwres_gethostbyname_r() is a thread-safe function * for forward lookups. If an error occurs, an error code is returned in * *error. resbuf is a pointer to a struct hostent which is initialised * by a successful call to lwres_gethostbyname_r() . buf is a buffer of * length len bytes which is used to store the h_name, h_aliases, and * h_addr_list elements of the struct hostent returned in resbuf. * Successful calls to lwres_gethostbyname_r() return resbuf, which is a * pointer to the struct hostent it created. * * lwres_gethostbyaddr_r() is a thread-safe function that performs a * reverse lookup of address addr which is len bytes long and is of * protocol family type -- PF_INET or PF_INET6. If an error occurs, the * error code is returned in *error. The other function parameters are * identical to those in lwres_gethostbyname_r(). resbuf is a pointer to * a struct hostent which is initialised by a successful call to * lwres_gethostbyaddr_r(). buf is a buffer of length len bytes which is * used to store the h_name, h_aliases, and h_addr_list elements of the * struct hostent returned in resbuf. Successful calls to * lwres_gethostbyaddr_r() return resbuf, which is a pointer to the * struct hostent it created. * * \section gethost_return Return Values * * The functions lwres_gethostbyname(), lwres_gethostbyname2(), * lwres_gethostbyaddr(), and lwres_gethostent() return NULL to indicate * an error. In this case the global variable lwres_h_errno will contain * one of the following error codes defined in \link netdb.h :\endlink * * \li #HOST_NOT_FOUND: * The host or address was not found. * * \li #TRY_AGAIN: * A recoverable error occurred, e.g., a timeout. Retrying the * lookup may succeed. * * \li #NO_RECOVERY: * A non-recoverable error occurred. * * \li #NO_DATA: * The name exists, but has no address information associated with * it (or vice versa in the case of a reverse lookup). The code * NO_ADDRESS is accepted as a synonym for NO_DATA for backwards * compatibility. * * lwres_hstrerror() translates these error codes to suitable error * messages. * * lwres_gethostent() and lwres_gethostent_r() always return NULL. * * Successful calls to lwres_gethostbyname_r() and * lwres_gethostbyaddr_r() return resbuf, a pointer to the struct hostent * that was initialised by these functions. They return NULL if the * lookups fail or if buf was too small to hold the list of addresses and * names referenced by the h_name, h_aliases, and h_addr_list elements of * the struct hostent. If buf was too small, both lwres_gethostbyname_r() * and lwres_gethostbyaddr_r() set the global variable errno to ERANGE. * * \section gethost_see See Also * * gethostent(), \link getipnode.c getipnode\endlink, lwres_hstrerror() * * \section gethost_bugs Bugs * * lwres_gethostbyname(), lwres_gethostbyname2(), lwres_gethostbyaddr() * and lwres_endhostent() are not thread safe; they return pointers to * static data and provide error codes through a global variable. * Thread-safe versions for name and address lookup are provided by * lwres_gethostbyname_r(), and lwres_gethostbyaddr_r() respectively. * * The resolver daemon does not currently support any non-DNS name * services such as /etc/hosts or NIS, consequently the above functions * don't, either. */ #include #include #include #ifdef HAVE_INTTYPES_H #include /* uintptr_t */ #endif #include #include #include "assert_p.h" #define LWRES_ALIGNBYTES (sizeof(char *) - 1) #define LWRES_ALIGN(p) \ (((uintptr_t)(p) + LWRES_ALIGNBYTES) &~ LWRES_ALIGNBYTES) static struct hostent *he = NULL; static int copytobuf(struct hostent *, struct hostent *, char *, int); /*% Always looks for an IPv4 address. */ struct hostent * lwres_gethostbyname(const char *name) { if (he != NULL) lwres_freehostent(he); he = lwres_getipnodebyname(name, AF_INET, 0, &lwres_h_errno); return (he); } /*% Looks for either an IPv4 or IPv6 address. */ struct hostent * lwres_gethostbyname2(const char *name, int af) { if (he != NULL) lwres_freehostent(he); he = lwres_getipnodebyname(name, af, 0, &lwres_h_errno); return (he); } /*% Reverse lookup of addresses. */ struct hostent * lwres_gethostbyaddr(const char *addr, int len, int type) { if (he != NULL) lwres_freehostent(he); he = lwres_getipnodebyaddr(addr, len, type, &lwres_h_errno); return (he); } /*% Stub function. Always returns failure. */ struct hostent * lwres_gethostent(void) { if (he != NULL) lwres_freehostent(he); return (NULL); } /*% Stub function. Always returns failure. */ void lwres_sethostent(int stayopen) { /* * Empty. */ UNUSED(stayopen); } /*% Stub function. Always returns failure. */ void lwres_endhostent(void) { /* * Empty. */ } /*% Thread-safe function for forward lookups. */ struct hostent * lwres_gethostbyname_r(const char *name, struct hostent *resbuf, char *buf, int buflen, int *error) { struct hostent *myhe; int res; myhe = lwres_getipnodebyname(name, AF_INET, 0, error); if (myhe == NULL) return (NULL); res = copytobuf(myhe, resbuf, buf, buflen); lwres_freehostent(myhe); if (res != 0) { errno = ERANGE; return (NULL); } return (resbuf); } /*% Thread-safe reverse lookup. */ struct hostent * lwres_gethostbyaddr_r(const char *addr, int len, int type, struct hostent *resbuf, char *buf, int buflen, int *error) { struct hostent *myhe; int res; myhe = lwres_getipnodebyaddr(addr, len, type, error); if (myhe == NULL) return (NULL); res = copytobuf(myhe, resbuf, buf, buflen); lwres_freehostent(myhe); if (res != 0) { errno = ERANGE; return (NULL); } return (resbuf); } /*% Stub function. Always returns failure. */ struct hostent * lwres_gethostent_r(struct hostent *resbuf, char *buf, int buflen, int *error) { UNUSED(resbuf); UNUSED(buf); UNUSED(buflen); *error = 0; return (NULL); } /*% Stub function. Always returns failure. */ void lwres_sethostent_r(int stayopen) { /* * Empty. */ UNUSED(stayopen); } /*% Stub function. Always returns failure. */ void lwres_endhostent_r(void) { /* * Empty. */ } static int copytobuf(struct hostent *src, struct hostent *hptr, char *buf, int buflen) { char *cp; char **ptr; int i, n; int nptr, len; /* * Find out the amount of space required to store the answer. */ nptr = 2; /* NULL ptrs */ len = (int)((char *)LWRES_ALIGN(buf) - buf); for (i = 0; src->h_addr_list[i]; i++, nptr++) { len += src->h_length; } for (i = 0; src->h_aliases[i]; i++, nptr++) { len += strlen(src->h_aliases[i]) + 1; } len += strlen(src->h_name) + 1; len += nptr * sizeof(char*); if (len > buflen) { return (-1); } /* * Copy address size and type. */ hptr->h_addrtype = src->h_addrtype; n = hptr->h_length = src->h_length; ptr = (char **)LWRES_ALIGN(buf); cp = (char *)LWRES_ALIGN(buf) + nptr * sizeof(char *); /* * Copy address list. */ hptr->h_addr_list = ptr; for (i = 0; src->h_addr_list[i]; i++, ptr++) { memmove(cp, src->h_addr_list[i], n); hptr->h_addr_list[i] = cp; cp += n; } hptr->h_addr_list[i] = NULL; ptr++; /* * Copy official name. */ n = strlen(src->h_name) + 1; strcpy(cp, src->h_name); hptr->h_name = cp; cp += n; /* * Copy aliases. */ hptr->h_aliases = ptr; for (i = 0; src->h_aliases[i]; i++) { n = strlen(src->h_aliases[i]) + 1; strcpy(cp, src->h_aliases[i]); hptr->h_aliases[i] = cp; cp += n; } hptr->h_aliases[i] = NULL; return (0); } bind9-9.10.3.dfsg.P4/lib/lwres/getipnode.c0000644000470500017500000006577312664710322017437 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: getipnode.c,v 1.47 2009/09/01 23:47:45 tbox Exp $ */ /*! \file */ /** * These functions perform thread safe, protocol independent * nodename-to-address and address-to-nodename translation as defined in * RFC2553. This use a struct hostent which is defined in namedb.h: * * \code * struct hostent { * char *h_name; // official name of host * char **h_aliases; // alias list * int h_addrtype; // host address type * int h_length; // length of address * char **h_addr_list; // list of addresses from name server * }; * #define h_addr h_addr_list[0] // address, for backward compatibility * \endcode * * The members of this structure are: * * \li h_name: * The official (canonical) name of the host. * * \li h_aliases: * A NULL-terminated array of alternate names (nicknames) for the * host. * * \li h_addrtype: * The type of address being returned - usually PF_INET or * PF_INET6. * * \li h_length: * The length of the address in bytes. * * \li h_addr_list: * A NULL terminated array of network addresses for the host. Host * addresses are returned in network byte order. * * lwres_getipnodebyname() looks up addresses of protocol family af for * the hostname name. The flags parameter contains ORed flag bits to * specify the types of addresses that are searched for, and the types of * addresses that are returned. The flag bits are: * * \li #AI_V4MAPPED: * This is used with an af of #AF_INET6, and causes IPv4 addresses * to be returned as IPv4-mapped IPv6 addresses. * * \li #AI_ALL: * This is used with an af of #AF_INET6, and causes all known * addresses (IPv6 and IPv4) to be returned. If #AI_V4MAPPED is * also set, the IPv4 addresses are return as mapped IPv6 * addresses. * * \li #AI_ADDRCONFIG: * Only return an IPv6 or IPv4 address if here is an active * network interface of that type. This is not currently * implemented in the BIND 9 lightweight resolver, and the flag is * ignored. * * \li #AI_DEFAULT: * This default sets the #AI_V4MAPPED and #AI_ADDRCONFIG flag bits. * * lwres_getipnodebyaddr() performs a reverse lookup of address src which * is len bytes long. af denotes the protocol family, typically PF_INET * or PF_INET6. * * lwres_freehostent() releases all the memory associated with the struct * hostent pointer. Any memory allocated for the h_name, h_addr_list * and h_aliases is freed, as is the memory for the hostent structure * itself. * * \section getipnode_return Return Values * * If an error occurs, lwres_getipnodebyname() and * lwres_getipnodebyaddr() set *error_num to an appropriate error code * and the function returns a NULL pointer. The error codes and their * meanings are defined in \link netdb.h \endlink: * * \li #HOST_NOT_FOUND: * No such host is known. * * \li #NO_ADDRESS: * The server recognised the request and the name but no address * is available. Another type of request to the name server for * the domain might return an answer. * * \li #TRY_AGAIN: * A temporary and possibly transient error occurred, such as a * failure of a server to respond. The request may succeed if * retried. * * \li #NO_RECOVERY: * An unexpected failure occurred, and retrying the request is * pointless. * * lwres_hstrerror() translates these error codes to suitable error * messages. * * \section getipnode_see See Also * * getaddrinfo.c, gethost.c, getnameinfo.c, herror.c, RFC2553 */ #include #include #include #include #include #include #include #include /* XXX #include */ #include "assert_p.h" #ifndef INADDRSZ #define INADDRSZ 4 #endif #ifndef IN6ADDRSZ #define IN6ADDRSZ 16 #endif #ifdef LWRES_PLATFORM_NEEDIN6ADDRANY LIBLWRES_EXTERNAL_DATA const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; #endif #ifndef IN6_IS_ADDR_V4COMPAT static const unsigned char in6addr_compat[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; #define IN6_IS_ADDR_V4COMPAT(x) (!memcmp((x)->s6_addr, in6addr_compat, 12) && \ ((x)->s6_addr[12] != 0 || \ (x)->s6_addr[13] != 0 || \ (x)->s6_addr[14] != 0 || \ ((x)->s6_addr[15] != 0 && \ (x)->s6_addr[15] != 1))) #endif #ifndef IN6_IS_ADDR_V4MAPPED #define IN6_IS_ADDR_V4MAPPED(x) (!memcmp((x)->s6_addr, in6addr_mapped, 12)) #endif static const unsigned char in6addr_mapped[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; /*** *** Forward declarations. ***/ static int scan_interfaces(int *, int *); static struct hostent * copyandmerge(struct hostent *, struct hostent *, int, int *); static struct hostent * hostfromaddr(lwres_gnbaresponse_t *addr, int af, const void *src); static struct hostent * hostfromname(lwres_gabnresponse_t *name, int af); /*** *** Public functions. ***/ /*! * AI_V4MAPPED + AF_INET6 * If no IPv6 address then a query for IPv4 and map returned values. * * AI_ALL + AI_V4MAPPED + AF_INET6 * Return IPv6 and IPv4 mapped. * * AI_ADDRCONFIG * Only return IPv6 / IPv4 address if there is an interface of that * type active. */ struct hostent * lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) { int have_v4 = 1, have_v6 = 1; struct in_addr in4; struct in6_addr in6; struct hostent he, *he1 = NULL, *he2 = NULL, *he3 = NULL; int v4 = 0, v6 = 0; int tmp_err = 0; lwres_context_t *lwrctx = NULL; lwres_gabnresponse_t *by = NULL; int n; /* * If we care about active interfaces then check. */ if ((flags & AI_ADDRCONFIG) != 0) if (scan_interfaces(&have_v4, &have_v6) == -1) { *error_num = NO_RECOVERY; return (NULL); } /* Check for literal address. */ if ((v4 = lwres_net_pton(AF_INET, name, &in4)) != 1) v6 = lwres_net_pton(AF_INET6, name, &in6); /* * Impossible combination? */ if ((af == AF_INET6 && (flags & AI_V4MAPPED) == 0 && v4 == 1) || (af == AF_INET && v6 == 1) || (have_v4 == 0 && v4 == 1) || (have_v6 == 0 && v6 == 1) || (have_v4 == 0 && af == AF_INET) || (have_v6 == 0 && af == AF_INET6 && (((flags & AI_V4MAPPED) != 0 && have_v4) || (flags & AI_V4MAPPED) == 0))) { *error_num = HOST_NOT_FOUND; return (NULL); } /* * Literal address? */ if (v4 == 1 || v6 == 1) { char *addr_list[2]; char *aliases[1]; char mappedname[sizeof("::ffff:123.123.123.123")]; union { const char *const_name; char *deconst_name; } u; u.const_name = name; if (v4 == 1 && af == AF_INET6) { strcpy(mappedname, "::ffff:"); lwres_net_ntop(AF_INET, (char *)&in4, mappedname + sizeof("::ffff:") - 1, sizeof(mappedname) - sizeof("::ffff:") + 1); he.h_name = mappedname; } else he.h_name = u.deconst_name; he.h_addr_list = addr_list; he.h_addr_list[0] = (v4 == 1) ? (char *)&in4 : (char *)&in6; he.h_addr_list[1] = NULL; he.h_aliases = aliases; he.h_aliases[0] = NULL; he.h_length = (v4 == 1) ? INADDRSZ : IN6ADDRSZ; he.h_addrtype = (v4 == 1) ? AF_INET : AF_INET6; return (copyandmerge(&he, NULL, af, error_num)); } n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0); if (n != 0) { *error_num = NO_RECOVERY; goto cleanup; } (void) lwres_conf_parse(lwrctx, lwres_resolv_conf); tmp_err = NO_RECOVERY; if (have_v6 && af == AF_INET6) { n = lwres_getaddrsbyname(lwrctx, name, LWRES_ADDRTYPE_V6, &by); if (n == 0) { he1 = hostfromname(by, AF_INET6); lwres_gabnresponse_free(lwrctx, &by); if (he1 == NULL) { *error_num = NO_RECOVERY; goto cleanup; } } else { if (n == LWRES_R_NOTFOUND) tmp_err = HOST_NOT_FOUND; else { *error_num = NO_RECOVERY; goto cleanup; } } } if (have_v4 && ((af == AF_INET) || (af == AF_INET6 && (flags & AI_V4MAPPED) != 0 && (he1 == NULL || (flags & AI_ALL) != 0)))) { n = lwres_getaddrsbyname(lwrctx, name, LWRES_ADDRTYPE_V4, &by); if (n == 0) { he2 = hostfromname(by, AF_INET); lwres_gabnresponse_free(lwrctx, &by); if (he2 == NULL) { *error_num = NO_RECOVERY; goto cleanup; } } else if (he1 == NULL) { if (n == LWRES_R_NOTFOUND) *error_num = HOST_NOT_FOUND; else *error_num = NO_RECOVERY; goto cleanup; } } else *error_num = tmp_err; he3 = copyandmerge(he1, he2, af, error_num); cleanup: if (he1 != NULL) lwres_freehostent(he1); if (he2 != NULL) lwres_freehostent(he2); if (lwrctx != NULL) { lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); } return (he3); } /*% performs a reverse lookup of address src which is len bytes long. af denotes the protocol family, typically #PF_INET or PF_INET6. */ struct hostent * lwres_getipnodebyaddr(const void *src, size_t len, int af, int *error_num) { struct hostent *he1, *he2; lwres_context_t *lwrctx = NULL; lwres_gnbaresponse_t *by = NULL; lwres_result_t n; union { const void *konst; struct in6_addr *in6; } u; /* * Sanity checks. */ if (src == NULL) { *error_num = NO_RECOVERY; return (NULL); } switch (af) { case AF_INET: if (len != (unsigned int)INADDRSZ) { *error_num = NO_RECOVERY; return (NULL); } break; case AF_INET6: if (len != (unsigned int)IN6ADDRSZ) { *error_num = NO_RECOVERY; return (NULL); } break; default: *error_num = NO_RECOVERY; return (NULL); } /* * The de-"const"-ing game is done because at least one * vendor's system (RedHat 6.0) defines the IN6_IS_ADDR_* * macros in such a way that they discard the const with * internal casting, and gcc ends up complaining. Rather * than replacing their own (possibly optimized) definitions * with our own, cleanly discarding the const is the easiest * thing to do. */ u.konst = src; /* * Look up IPv4 and IPv4 mapped/compatible addresses. */ if ((af == AF_INET6 && IN6_IS_ADDR_V4COMPAT(u.in6)) || (af == AF_INET6 && IN6_IS_ADDR_V4MAPPED(u.in6)) || (af == AF_INET)) { const unsigned char *cp = src; if (af == AF_INET6) cp += 12; n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0); if (n == LWRES_R_SUCCESS) (void) lwres_conf_parse(lwrctx, lwres_resolv_conf); if (n == LWRES_R_SUCCESS) n = lwres_getnamebyaddr(lwrctx, LWRES_ADDRTYPE_V4, INADDRSZ, cp, &by); if (n != LWRES_R_SUCCESS) { lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); if (n == LWRES_R_NOTFOUND) *error_num = HOST_NOT_FOUND; else *error_num = NO_RECOVERY; return (NULL); } he1 = hostfromaddr(by, AF_INET, cp); lwres_gnbaresponse_free(lwrctx, &by); lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); if (af != AF_INET6) return (he1); /* * Convert from AF_INET to AF_INET6. */ he2 = copyandmerge(he1, NULL, af, error_num); lwres_freehostent(he1); if (he2 == NULL) return (NULL); /* * Restore original address. */ memmove(he2->h_addr, src, len); return (he2); } /* * Lookup IPv6 address. */ if (memcmp(src, &in6addr_any, IN6ADDRSZ) == 0) { *error_num = HOST_NOT_FOUND; return (NULL); } n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0); if (n == LWRES_R_SUCCESS) (void) lwres_conf_parse(lwrctx, lwres_resolv_conf); if (n == LWRES_R_SUCCESS) n = lwres_getnamebyaddr(lwrctx, LWRES_ADDRTYPE_V6, IN6ADDRSZ, src, &by); if (n != 0) { lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); if (n == LWRES_R_NOTFOUND) *error_num = HOST_NOT_FOUND; else *error_num = NO_RECOVERY; return (NULL); } he1 = hostfromaddr(by, AF_INET6, src); lwres_gnbaresponse_free(lwrctx, &by); if (he1 == NULL) *error_num = NO_RECOVERY; lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); return (he1); } /*% releases all the memory associated with the struct hostent pointer */ void lwres_freehostent(struct hostent *he) { char **cpp; int names = 1; int addresses = 1; if (he == NULL) return; free(he->h_name); cpp = he->h_addr_list; while (*cpp != NULL) { free(*cpp); *cpp = NULL; cpp++; addresses++; } cpp = he->h_aliases; while (*cpp != NULL) { free(*cpp); cpp++; names++; } free(he->h_aliases); free(he->h_addr_list); free(he); } /* * Private */ /* * Scan the interface table and set have_v4 and have_v6 depending * upon whether there are IPv4 and IPv6 interface addresses. * * Returns: * 0 on success * -1 on failure. */ #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \ !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF) #ifdef __hpux #define lifc_len iflc_len #define lifc_buf iflc_buf #define lifc_req iflc_req #define LIFCONF if_laddrconf #else #define ISC_HAVE_LIFC_FAMILY 1 #define ISC_HAVE_LIFC_FLAGS 1 #define LIFCONF lifconf #endif #ifdef __hpux #define lifr_addr iflr_addr #define lifr_name iflr_name #define lifr_dstaddr iflr_dstaddr #define lifr_flags iflr_flags #define ss_family sa_family #define LIFREQ if_laddrreq #else #define LIFREQ lifreq #endif static int scan_interfaces6(int *have_v4, int *have_v6) { struct LIFCONF lifc; struct LIFREQ lifreq; struct in_addr in4; struct in6_addr in6; char *buf = NULL, *cp, *cplim; static unsigned int bufsiz = 4095; int s, cpsize, n; /* * Set to zero. Used as loop terminators below. */ *have_v4 = *have_v6 = 0; /* * Get interface list from system. */ if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) == -1) goto err_ret; /* * Grow buffer until large enough to contain all interface * descriptions. */ for (;;) { buf = malloc(bufsiz); if (buf == NULL) goto err_ret; #ifdef ISC_HAVE_LIFC_FAMILY lifc.lifc_family = AF_UNSPEC; /* request all families */ #endif #ifdef ISC_HAVE_LIFC_FLAGS lifc.lifc_flags = 0; #endif lifc.lifc_len = bufsiz; lifc.lifc_buf = buf; if ((n = ioctl(s, SIOCGLIFCONF, (char *)&lifc)) != -1) { /* * Some OS's just return what will fit rather * than set EINVAL if the buffer is too small * to fit all the interfaces in. If * lifc.lifc_len is too near to the end of the * buffer we will grow it just in case and * retry. */ if (lifc.lifc_len + 2 * sizeof(lifreq) < bufsiz) break; } if ((n == -1) && errno != EINVAL) goto err_ret; if (bufsiz > 1000000) goto err_ret; free(buf); bufsiz += 4096; } /* * Parse system's interface list. */ cplim = buf + lifc.lifc_len; /* skip over if's with big ifr_addr's */ for (cp = buf; (*have_v4 == 0 || *have_v6 == 0) && cp < cplim; cp += cpsize) { memmove(&lifreq, cp, sizeof(lifreq)); #ifdef LWRES_PLATFORM_HAVESALEN #ifdef FIX_ZERO_SA_LEN if (lifreq.lifr_addr.sa_len == 0) lifreq.lifr_addr.sa_len = 16; #endif #ifdef HAVE_MINIMUM_IFREQ cpsize = sizeof(lifreq); if (lifreq.lifr_addr.sa_len > sizeof(struct sockaddr)) cpsize += (int)lifreq.lifr_addr.sa_len - (int)(sizeof(struct sockaddr)); #else cpsize = sizeof(lifreq.lifr_name) + lifreq.lifr_addr.sa_len; #endif /* HAVE_MINIMUM_IFREQ */ #elif defined SIOCGIFCONF_ADDR cpsize = sizeof(lifreq); #else cpsize = sizeof(lifreq.lifr_name); /* XXX maybe this should be a hard error? */ if (ioctl(s, SIOCGLIFADDR, (char *)&lifreq) < 0) continue; #endif switch (lifreq.lifr_addr.ss_family) { case AF_INET: if (*have_v4 == 0) { memmove(&in4, &((struct sockaddr_in *) &lifreq.lifr_addr)->sin_addr, sizeof(in4)); if (in4.s_addr == INADDR_ANY) break; n = ioctl(s, SIOCGLIFFLAGS, (char *)&lifreq); if (n < 0) break; if ((lifreq.lifr_flags & IFF_UP) == 0) break; *have_v4 = 1; } break; case AF_INET6: if (*have_v6 == 0) { memmove(&in6, &((struct sockaddr_in6 *) &lifreq.lifr_addr)->sin6_addr, sizeof(in6)); if (memcmp(&in6, &in6addr_any, sizeof(in6)) == 0) break; n = ioctl(s, SIOCGLIFFLAGS, (char *)&lifreq); if (n < 0) break; if ((lifreq.lifr_flags & IFF_UP) == 0) break; *have_v6 = 1; } break; } } if (buf != NULL) free(buf); close(s); return (0); err_ret: if (buf != NULL) free(buf); if (s != -1) close(s); return (-1); } #endif static int scan_interfaces(int *have_v4, int *have_v6) { #if !defined(SIOCGIFCONF) || !defined(SIOCGIFADDR) *have_v4 = *have_v6 = 1; return (0); #else struct ifconf ifc; union { char _pad[256]; /* leave space for IPv6 addresses */ struct ifreq ifreq; } u; struct in_addr in4; struct in6_addr in6; char *buf = NULL, *cp, *cplim; static unsigned int bufsiz = 4095; int s, n; size_t cpsize; #ifdef WIN32 InitSockets(); #endif #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \ !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF) /* * Try to scan the interfaces using IPv6 ioctls(). */ if (!scan_interfaces6(have_v4, have_v6)) { #ifdef WIN32 DestroySockets(); #endif return (0); } #endif /* * Set to zero. Used as loop terminators below. */ *have_v4 = *have_v6 = 0; /* * Get interface list from system. */ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) goto err_ret; /* * Grow buffer until large enough to contain all interface * descriptions. */ for (;;) { buf = malloc(bufsiz); if (buf == NULL) goto err_ret; ifc.ifc_len = bufsiz; ifc.ifc_buf = buf; #ifdef IRIX_EMUL_IOCTL_SIOCGIFCONF /* * This is a fix for IRIX OS in which the call to ioctl with * the flag SIOCGIFCONF may not return an entry for all the * interfaces like most flavors of Unix. */ if (emul_ioctl(&ifc) >= 0) break; #else if ((n = ioctl(s, SIOCGIFCONF, (char *)&ifc)) != -1) { /* * Some OS's just return what will fit rather * than set EINVAL if the buffer is too small * to fit all the interfaces in. If * ifc.ifc_len is too near to the end of the * buffer we will grow it just in case and * retry. */ if (ifc.ifc_len + 2 * sizeof(u.ifreq) < bufsiz) break; } #endif if ((n == -1) && errno != EINVAL) goto err_ret; if (bufsiz > 1000000) goto err_ret; free(buf); bufsiz += 4096; } /* * Parse system's interface list. */ cplim = buf + ifc.ifc_len; /* skip over if's with big ifr_addr's */ for (cp = buf; (*have_v4 == 0 || *have_v6 == 0) && cp < cplim; cp += cpsize) { memmove(&u.ifreq, cp, sizeof(u.ifreq)); #ifdef LWRES_PLATFORM_HAVESALEN #ifdef FIX_ZERO_SA_LEN if (u.ifreq.ifr_addr.sa_len == 0) u.ifreq.ifr_addr.sa_len = 16; #endif #ifdef HAVE_MINIMUM_IFREQ cpsize = sizeof(u.ifreq); if (u.ifreq.ifr_addr.sa_len > sizeof(struct sockaddr)) cpsize += (int)u.ifreq.ifr_addr.sa_len - (int)(sizeof(struct sockaddr)); #else cpsize = sizeof(u.ifreq.ifr_name) + u.ifreq.ifr_addr.sa_len; #endif /* HAVE_MINIMUM_IFREQ */ if (cpsize > sizeof(u.ifreq) && cpsize <= sizeof(u)) memmove(&u.ifreq, cp, cpsize); #elif defined SIOCGIFCONF_ADDR cpsize = sizeof(u.ifreq); #else cpsize = sizeof(u.ifreq.ifr_name); /* XXX maybe this should be a hard error? */ if (ioctl(s, SIOCGIFADDR, (char *)&u.ifreq) < 0) continue; #endif switch (u.ifreq.ifr_addr.sa_family) { case AF_INET: if (*have_v4 == 0) { memmove(&in4, &((struct sockaddr_in *) &u.ifreq.ifr_addr)->sin_addr, sizeof(in4)); if (in4.s_addr == INADDR_ANY) break; n = ioctl(s, SIOCGIFFLAGS, (char *)&u.ifreq); if (n < 0) break; if ((u.ifreq.ifr_flags & IFF_UP) == 0) break; *have_v4 = 1; } break; case AF_INET6: if (*have_v6 == 0) { memmove(&in6, &((struct sockaddr_in6 *) &u.ifreq.ifr_addr)->sin6_addr, sizeof(in6)); if (memcmp(&in6, &in6addr_any, sizeof(in6)) == 0) break; n = ioctl(s, SIOCGIFFLAGS, (char *)&u.ifreq); if (n < 0) break; if ((u.ifreq.ifr_flags & IFF_UP) == 0) break; *have_v6 = 1; } break; } } if (buf != NULL) free(buf); #ifdef WIN32 DestroySockets(); #endif close(s); return (0); err_ret: if (buf != NULL) free(buf); if (s != -1) close(s); #ifdef WIN32 DestroySockets(); #endif return (-1); #endif } static struct hostent * copyandmerge(struct hostent *he1, struct hostent *he2, int af, int *error_num) { struct hostent *he = NULL; int addresses = 1; /* NULL terminator */ int names = 1; /* NULL terminator */ int len = 0; char **cpp, **npp; /* * Work out array sizes. */ if (he1 != NULL) { cpp = he1->h_addr_list; while (*cpp != NULL) { addresses++; cpp++; } cpp = he1->h_aliases; while (*cpp != NULL) { names++; cpp++; } } if (he2 != NULL) { cpp = he2->h_addr_list; while (*cpp != NULL) { addresses++; cpp++; } if (he1 == NULL) { cpp = he2->h_aliases; while (*cpp != NULL) { names++; cpp++; } } } if (addresses == 1) { *error_num = NO_ADDRESS; return (NULL); } he = malloc(sizeof(*he)); if (he == NULL) goto no_recovery; he->h_addr_list = malloc(sizeof(char *) * (addresses)); if (he->h_addr_list == NULL) goto cleanup0; memset(he->h_addr_list, 0, sizeof(char *) * (addresses)); /* * Copy addresses. */ npp = he->h_addr_list; if (he1 != NULL) { cpp = he1->h_addr_list; while (*cpp != NULL) { *npp = malloc((af == AF_INET) ? INADDRSZ : IN6ADDRSZ); if (*npp == NULL) goto cleanup1; /* * Convert to mapped if required. */ if (af == AF_INET6 && he1->h_addrtype == AF_INET) { memmove(*npp, in6addr_mapped, sizeof(in6addr_mapped)); memmove(*npp + sizeof(in6addr_mapped), *cpp, INADDRSZ); } else { memmove(*npp, *cpp, (af == AF_INET) ? INADDRSZ : IN6ADDRSZ); } cpp++; npp++; } } if (he2 != NULL) { cpp = he2->h_addr_list; while (*cpp != NULL) { *npp = malloc((af == AF_INET) ? INADDRSZ : IN6ADDRSZ); if (*npp == NULL) goto cleanup1; /* * Convert to mapped if required. */ if (af == AF_INET6 && he2->h_addrtype == AF_INET) { memmove(*npp, in6addr_mapped, sizeof(in6addr_mapped)); memmove(*npp + sizeof(in6addr_mapped), *cpp, INADDRSZ); } else { memmove(*npp, *cpp, (af == AF_INET) ? INADDRSZ : IN6ADDRSZ); } cpp++; npp++; } } he->h_aliases = malloc(sizeof(char *) * (names)); if (he->h_aliases == NULL) goto cleanup1; memset(he->h_aliases, 0, sizeof(char *) * (names)); /* * Copy aliases. */ npp = he->h_aliases; cpp = (he1 != NULL) ? he1->h_aliases : ((he2 != NULL) ? he2->h_aliases : NULL); while (cpp != NULL && *cpp != NULL) { len = strlen (*cpp) + 1; *npp = malloc(len); if (*npp == NULL) goto cleanup2; strcpy(*npp, *cpp); npp++; cpp++; } /* * Copy hostname. */ he->h_name = malloc(strlen((he1 != NULL) ? he1->h_name : he2->h_name) + 1); if (he->h_name == NULL) goto cleanup2; strcpy(he->h_name, (he1 != NULL) ? he1->h_name : he2->h_name); /* * Set address type and length. */ he->h_addrtype = af; he->h_length = (af == AF_INET) ? INADDRSZ : IN6ADDRSZ; return (he); cleanup2: cpp = he->h_aliases; while (*cpp != NULL) { free(*cpp); cpp++; } free(he->h_aliases); cleanup1: cpp = he->h_addr_list; while (*cpp != NULL) { free(*cpp); *cpp = NULL; cpp++; } free(he->h_addr_list); cleanup0: free(he); no_recovery: *error_num = NO_RECOVERY; return (NULL); } static struct hostent * hostfromaddr(lwres_gnbaresponse_t *addr, int af, const void *src) { struct hostent *he; int i; he = malloc(sizeof(*he)); if (he == NULL) goto cleanup; memset(he, 0, sizeof(*he)); /* * Set family and length. */ he->h_addrtype = af; switch (af) { case AF_INET: he->h_length = INADDRSZ; break; case AF_INET6: he->h_length = IN6ADDRSZ; break; default: INSIST(0); } /* * Copy name. */ he->h_name = strdup(addr->realname); if (he->h_name == NULL) goto cleanup; /* * Copy aliases. */ he->h_aliases = malloc(sizeof(char *) * (addr->naliases + 1)); if (he->h_aliases == NULL) goto cleanup; for (i = 0; i < addr->naliases; i++) { he->h_aliases[i] = strdup(addr->aliases[i]); if (he->h_aliases[i] == NULL) goto cleanup; } he->h_aliases[i] = NULL; /* * Copy address. */ he->h_addr_list = malloc(sizeof(char *) * 2); if (he->h_addr_list == NULL) goto cleanup; he->h_addr_list[0] = malloc(he->h_length); if (he->h_addr_list[0] == NULL) goto cleanup; memmove(he->h_addr_list[0], src, he->h_length); he->h_addr_list[1] = NULL; return (he); cleanup: if (he != NULL && he->h_addr_list != NULL) { for (i = 0; he->h_addr_list[i] != NULL; i++) free(he->h_addr_list[i]); free(he->h_addr_list); } if (he != NULL && he->h_aliases != NULL) { for (i = 0; he->h_aliases[i] != NULL; i++) free(he->h_aliases[i]); free(he->h_aliases); } if (he != NULL && he->h_name != NULL) free(he->h_name); if (he != NULL) free(he); return (NULL); } static struct hostent * hostfromname(lwres_gabnresponse_t *name, int af) { struct hostent *he; int i; lwres_addr_t *addr; he = malloc(sizeof(*he)); if (he == NULL) goto cleanup; memset(he, 0, sizeof(*he)); /* * Set family and length. */ he->h_addrtype = af; switch (af) { case AF_INET: he->h_length = INADDRSZ; break; case AF_INET6: he->h_length = IN6ADDRSZ; break; default: INSIST(0); } /* * Copy name. */ he->h_name = strdup(name->realname); if (he->h_name == NULL) goto cleanup; /* * Copy aliases. */ he->h_aliases = malloc(sizeof(char *) * (name->naliases + 1)); if (he->h_aliases == NULL) goto cleanup; for (i = 0; i < name->naliases; i++) { he->h_aliases[i] = strdup(name->aliases[i]); if (he->h_aliases[i] == NULL) goto cleanup; } he->h_aliases[i] = NULL; /* * Copy addresses. */ he->h_addr_list = malloc(sizeof(char *) * (name->naddrs + 1)); if (he->h_addr_list == NULL) goto cleanup; addr = LWRES_LIST_HEAD(name->addrs); i = 0; while (addr != NULL) { he->h_addr_list[i] = malloc(he->h_length); if (he->h_addr_list[i] == NULL) goto cleanup; memmove(he->h_addr_list[i], addr->address, he->h_length); addr = LWRES_LIST_NEXT(addr, link); i++; } he->h_addr_list[i] = NULL; return (he); cleanup: if (he != NULL && he->h_addr_list != NULL) { for (i = 0; he->h_addr_list[i] != NULL; i++) free(he->h_addr_list[i]); free(he->h_addr_list); } if (he != NULL && he->h_aliases != NULL) { for (i = 0; he->h_aliases[i] != NULL; i++) free(he->h_aliases[i]); free(he->h_aliases); } if (he != NULL && he->h_name != NULL) free(he->h_name); if (he != NULL) free(he); return (NULL); } bind9-9.10.3.dfsg.P4/lib/lwres/getaddrinfo.c0000644000470500017500000005307412664710322017736 0ustar lamontlamont/* * Copyright (C) 2004-2008, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * This code is derived from software contributed to ISC by * Berkeley Software Design, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND BERKELEY SOFTWARE DESIGN, INC. * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: getaddrinfo.c,v 1.54 2008/11/25 23:47:23 tbox Exp $ */ /*! \file */ /** * lwres_getaddrinfo() is used to get a list of IP addresses and port * numbers for host hostname and service servname. The function is the * lightweight resolver's implementation of getaddrinfo() as defined in * RFC2133. hostname and servname are pointers to null-terminated strings * or NULL. hostname is either a host name or a numeric host address * string: a dotted decimal IPv4 address or an IPv6 address. servname is * either a decimal port number or a service name as listed in * /etc/services. * * If the operating system does not provide a struct addrinfo, the * following structure is used: * * \code * struct addrinfo { * int ai_flags; // AI_PASSIVE, AI_CANONNAME * int ai_family; // PF_xxx * int ai_socktype; // SOCK_xxx * int ai_protocol; // 0 or IPPROTO_xxx for IPv4 and IPv6 * size_t ai_addrlen; // length of ai_addr * char *ai_canonname; // canonical name for hostname * struct sockaddr *ai_addr; // binary address * struct addrinfo *ai_next; // next structure in linked list * }; * \endcode * * * hints is an optional pointer to a struct addrinfo. This structure can * be used to provide hints concerning the type of socket that the caller * supports or wishes to use. The caller can supply the following * structure elements in *hints: * *
    *
  • ai_family: * The protocol family that should be used. When ai_family is set * to PF_UNSPEC, it means the caller will accept any protocol * family supported by the operating system.
  • * *
  • ai_socktype: * denotes the type of socket -- SOCK_STREAM, SOCK_DGRAM or * SOCK_RAW -- that is wanted. When ai_socktype is zero the caller * will accept any socket type.
  • * *
  • ai_protocol: * indicates which transport protocol is wanted: IPPROTO_UDP or * IPPROTO_TCP. If ai_protocol is zero the caller will accept any * protocol.
  • * *
  • ai_flags: * Flag bits. If the AI_CANONNAME bit is set, a successful call to * lwres_getaddrinfo() will return a null-terminated string * containing the canonical name of the specified hostname in * ai_canonname of the first addrinfo structure returned. Setting * the AI_PASSIVE bit indicates that the returned socket address * structure is intended for used in a call to bind(2). In this * case, if the hostname argument is a NULL pointer, then the IP * address portion of the socket address structure will be set to * INADDR_ANY for an IPv4 address or IN6ADDR_ANY_INIT for an IPv6 * address.

    * * When ai_flags does not set the AI_PASSIVE bit, the returned * socket address structure will be ready for use in a call to * connect(2) for a connection-oriented protocol or connect(2), * sendto(2), or sendmsg(2) if a connectionless protocol was * chosen. The IP address portion of the socket address structure * will be set to the loopback address if hostname is a NULL * pointer and AI_PASSIVE is not set in ai_flags.

    * * If ai_flags is set to AI_NUMERICHOST it indicates that hostname * should be treated as a numeric string defining an IPv4 or IPv6 * address and no name resolution should be attempted. *
* * All other elements of the struct addrinfo passed via hints must be * zero. * * A hints of NULL is treated as if the caller provided a struct addrinfo * initialized to zero with ai_familyset to PF_UNSPEC. * * After a successful call to lwres_getaddrinfo(), *res is a pointer to a * linked list of one or more addrinfo structures. Each struct addrinfo * in this list cn be processed by following the ai_next pointer, until a * NULL pointer is encountered. The three members ai_family, ai_socktype, * and ai_protocol in each returned addrinfo structure contain the * corresponding arguments for a call to socket(2). For each addrinfo * structure in the list, the ai_addr member points to a filled-in socket * address structure of length ai_addrlen. * * All of the information returned by lwres_getaddrinfo() is dynamically * allocated: the addrinfo structures, and the socket address structures * and canonical host name strings pointed to by the addrinfostructures. * Memory allocated for the dynamically allocated structures created by a * successful call to lwres_getaddrinfo() is released by * lwres_freeaddrinfo(). ai is a pointer to a struct addrinfo created by * a call to lwres_getaddrinfo(). * * \section lwresreturn RETURN VALUES * * lwres_getaddrinfo() returns zero on success or one of the error codes * listed in gai_strerror() if an error occurs. If both hostname and * servname are NULL lwres_getaddrinfo() returns #EAI_NONAME. * * \section lwressee SEE ALSO * * lwres(3), lwres_getaddrinfo(), lwres_freeaddrinfo(), * lwres_gai_strerror(), RFC2133, getservbyname(3), connect(2), * sendto(2), sendmsg(2), socket(2). */ #include #include #include #include #include #include #include #include #define SA(addr) ((struct sockaddr *)(addr)) #define SIN(addr) ((struct sockaddr_in *)(addr)) #define SIN6(addr) ((struct sockaddr_in6 *)(addr)) #define SLOCAL(addr) ((struct sockaddr_un *)(addr)) /*! \struct addrinfo */ static struct addrinfo *ai_reverse(struct addrinfo *oai), *ai_clone(struct addrinfo *oai, int family), *ai_alloc(int family, int addrlen); #ifdef AF_LOCAL static int get_local(const char *name, int socktype, struct addrinfo **res); #endif static int add_ipv4(const char *hostname, int flags, struct addrinfo **aip, int socktype, int port); static int add_ipv6(const char *hostname, int flags, struct addrinfo **aip, int socktype, int port); static void set_order(int, int (**)(const char *, int, struct addrinfo **, int, int)); #define FOUND_IPV4 0x1 #define FOUND_IPV6 0x2 #define FOUND_MAX 2 #define ISC_AI_MASK (AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST) /*% Get a list of IP addresses and port numbers for host hostname and service servname. */ int lwres_getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res) { struct servent *sp; const char *proto; int family, socktype, flags, protocol; struct addrinfo *ai, *ai_list; int port, err, i; int (*net_order[FOUND_MAX+1])(const char *, int, struct addrinfo **, int, int); if (hostname == NULL && servname == NULL) return (EAI_NONAME); proto = NULL; if (hints != NULL) { if ((hints->ai_flags & ~(ISC_AI_MASK)) != 0) return (EAI_BADFLAGS); if (hints->ai_addrlen || hints->ai_canonname || hints->ai_addr || hints->ai_next) { errno = EINVAL; return (EAI_SYSTEM); } family = hints->ai_family; socktype = hints->ai_socktype; protocol = hints->ai_protocol; flags = hints->ai_flags; switch (family) { case AF_UNSPEC: switch (hints->ai_socktype) { case SOCK_STREAM: proto = "tcp"; break; case SOCK_DGRAM: proto = "udp"; break; } break; case AF_INET: case AF_INET6: switch (hints->ai_socktype) { case 0: break; case SOCK_STREAM: proto = "tcp"; break; case SOCK_DGRAM: proto = "udp"; break; case SOCK_RAW: break; default: return (EAI_SOCKTYPE); } break; #ifdef AF_LOCAL case AF_LOCAL: switch (hints->ai_socktype) { case 0: break; case SOCK_STREAM: break; case SOCK_DGRAM: break; default: return (EAI_SOCKTYPE); } break; #endif default: return (EAI_FAMILY); } } else { protocol = 0; family = 0; socktype = 0; flags = 0; } #ifdef AF_LOCAL /*! * First, deal with AF_LOCAL. If the family was not set, * then assume AF_LOCAL if the first character of the * hostname/servname is '/'. */ if (hostname != NULL && (family == AF_LOCAL || (family == 0 && *hostname == '/'))) return (get_local(hostname, socktype, res)); if (servname != NULL && (family == AF_LOCAL || (family == 0 && *servname == '/'))) return (get_local(servname, socktype, res)); #endif /* * Ok, only AF_INET and AF_INET6 left. */ ai_list = NULL; /* * First, look up the service name (port) if it was * requested. If the socket type wasn't specified, then * try and figure it out. */ if (servname != NULL) { char *e; port = strtol(servname, &e, 10); if (*e == '\0') { if (socktype == 0) return (EAI_SOCKTYPE); if (port < 0 || port > 65535) return (EAI_SERVICE); port = htons((unsigned short) port); } else { sp = getservbyname(servname, proto); if (sp == NULL) return (EAI_SERVICE); port = sp->s_port; if (socktype == 0) { if (strcmp(sp->s_proto, "tcp") == 0) socktype = SOCK_STREAM; else if (strcmp(sp->s_proto, "udp") == 0) socktype = SOCK_DGRAM; } } } else port = 0; /* * Next, deal with just a service name, and no hostname. * (we verified that one of them was non-null up above). */ if (hostname == NULL && (flags & AI_PASSIVE) != 0) { if (family == AF_INET || family == 0) { ai = ai_alloc(AF_INET, sizeof(struct sockaddr_in)); if (ai == NULL) return (EAI_MEMORY); ai->ai_socktype = socktype; ai->ai_protocol = protocol; SIN(ai->ai_addr)->sin_port = port; ai->ai_next = ai_list; ai_list = ai; } if (family == AF_INET6 || family == 0) { ai = ai_alloc(AF_INET6, sizeof(struct sockaddr_in6)); if (ai == NULL) { lwres_freeaddrinfo(ai_list); return (EAI_MEMORY); } ai->ai_socktype = socktype; ai->ai_protocol = protocol; SIN6(ai->ai_addr)->sin6_port = port; ai->ai_next = ai_list; ai_list = ai; } *res = ai_list; return (0); } /* * If the family isn't specified or AI_NUMERICHOST specified, * check first to see if it is a numeric address. * Though the gethostbyname2() routine * will recognize numeric addresses, it will only recognize * the format that it is being called for. Thus, a numeric * AF_INET address will be treated by the AF_INET6 call as * a domain name, and vice versa. Checking for both numerics * here avoids that. */ if (hostname != NULL && (family == 0 || (flags & AI_NUMERICHOST) != 0)) { char abuf[sizeof(struct in6_addr)]; char nbuf[NI_MAXHOST]; int addrsize, addroff; #ifdef LWRES_HAVE_SIN6_SCOPE_ID char *p, *ep; char ntmp[NI_MAXHOST]; lwres_uint32_t scopeid; #endif #ifdef LWRES_HAVE_SIN6_SCOPE_ID /* * Scope identifier portion. */ ntmp[0] = '\0'; if (strchr(hostname, '%') != NULL) { strncpy(ntmp, hostname, sizeof(ntmp) - 1); ntmp[sizeof(ntmp) - 1] = '\0'; p = strchr(ntmp, '%'); ep = NULL; /* * Vendors may want to support non-numeric * scopeid around here. */ if (p != NULL) scopeid = (lwres_uint32_t)strtoul(p + 1, &ep, 10); if (p != NULL && ep != NULL && ep[0] == '\0') *p = '\0'; else { ntmp[0] = '\0'; scopeid = 0; } } else scopeid = 0; #endif if (lwres_net_pton(AF_INET, hostname, (struct in_addr *)abuf) == 1) { if (family == AF_INET6) { /* * Convert to a V4 mapped address. */ struct in6_addr *a6 = (struct in6_addr *)abuf; memmove(&a6->s6_addr[12], &a6->s6_addr[0], 4); memset(&a6->s6_addr[10], 0xff, 2); memset(&a6->s6_addr[0], 0, 10); goto inet6_addr; } addrsize = sizeof(struct in_addr); addroff = offsetof(struct sockaddr_in, sin_addr); family = AF_INET; goto common; #ifdef LWRES_HAVE_SIN6_SCOPE_ID } else if (ntmp[0] != '\0' && lwres_net_pton(AF_INET6, ntmp, abuf) == 1) { if (family && family != AF_INET6) return (EAI_NONAME); addrsize = sizeof(struct in6_addr); addroff = offsetof(struct sockaddr_in6, sin6_addr); family = AF_INET6; goto common; #endif } else if (lwres_net_pton(AF_INET6, hostname, abuf) == 1) { if (family != 0 && family != AF_INET6) return (EAI_NONAME); inet6_addr: addrsize = sizeof(struct in6_addr); addroff = offsetof(struct sockaddr_in6, sin6_addr); family = AF_INET6; common: ai = ai_clone(ai_list, family); if (ai == NULL) return (EAI_MEMORY); ai_list = ai; ai->ai_socktype = socktype; SIN(ai->ai_addr)->sin_port = port; memmove((char *)ai->ai_addr + addroff, abuf, addrsize); if (flags & AI_CANONNAME) { #if defined(LWRES_HAVE_SIN6_SCOPE_ID) if (ai->ai_family == AF_INET6) SIN6(ai->ai_addr)->sin6_scope_id = scopeid; #endif if (lwres_getnameinfo(ai->ai_addr, ai->ai_addrlen, nbuf, sizeof(nbuf), NULL, 0, NI_NUMERICHOST) == 0) { ai->ai_canonname = strdup(nbuf); if (ai->ai_canonname == NULL) { lwres_freeaddrinfo(ai_list); return (EAI_MEMORY); } } else { /* XXX raise error? */ ai->ai_canonname = NULL; } } goto done; } else if ((flags & AI_NUMERICHOST) != 0) { return (EAI_NONAME); } } set_order(family, net_order); for (i = 0; i < FOUND_MAX; i++) { if (net_order[i] == NULL) break; err = (net_order[i])(hostname, flags, &ai_list, socktype, port); if (err != 0) return (err); } if (ai_list == NULL) return (EAI_NODATA); done: ai_list = ai_reverse(ai_list); *res = ai_list; return (0); } static char * lwres_strsep(char **stringp, const char *delim) { char *string = *stringp; char *s; const char *d; char sc, dc; if (string == NULL) return (NULL); for (s = string; *s != '\0'; s++) { sc = *s; for (d = delim; (dc = *d) != '\0'; d++) if (sc == dc) { *s++ = '\0'; *stringp = s; return (string); } } *stringp = NULL; return (string); } static void set_order(int family, int (**net_order)(const char *, int, struct addrinfo **, int, int)) { char *order, *tok; int found; if (family) { switch (family) { case AF_INET: *net_order++ = add_ipv4; break; case AF_INET6: *net_order++ = add_ipv6; break; } } else { order = getenv("NET_ORDER"); found = 0; while (order != NULL) { /* * We ignore any unknown names. */ tok = lwres_strsep(&order, ":"); if (strcasecmp(tok, "inet6") == 0) { if ((found & FOUND_IPV6) == 0) *net_order++ = add_ipv6; found |= FOUND_IPV6; } else if (strcasecmp(tok, "inet") == 0 || strcasecmp(tok, "inet4") == 0) { if ((found & FOUND_IPV4) == 0) *net_order++ = add_ipv4; found |= FOUND_IPV4; } } /* * Add in anything that we didn't find. */ if ((found & FOUND_IPV4) == 0) *net_order++ = add_ipv4; if ((found & FOUND_IPV6) == 0) *net_order++ = add_ipv6; } *net_order = NULL; return; } static char v4_loop[4] = { 127, 0, 0, 1 }; /* * The test against 0 is there to keep the Solaris compiler * from complaining about "end-of-loop code not reached". */ #define SETERROR(code) \ do { result = (code); \ if (result != 0) goto cleanup; \ } while (0) static int add_ipv4(const char *hostname, int flags, struct addrinfo **aip, int socktype, int port) { struct addrinfo *ai; lwres_context_t *lwrctx = NULL; lwres_gabnresponse_t *by = NULL; lwres_addr_t *addr; lwres_result_t lwres; int result = 0; lwres = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0); if (lwres != LWRES_R_SUCCESS) SETERROR(EAI_FAIL); (void) lwres_conf_parse(lwrctx, lwres_resolv_conf); if (hostname == NULL && (flags & AI_PASSIVE) == 0) { ai = ai_clone(*aip, AF_INET); if (ai == NULL) SETERROR(EAI_MEMORY); *aip = ai; ai->ai_socktype = socktype; SIN(ai->ai_addr)->sin_port = port; memmove(&SIN(ai->ai_addr)->sin_addr, v4_loop, 4); } else { lwres = lwres_getaddrsbyname(lwrctx, hostname, LWRES_ADDRTYPE_V4, &by); if (lwres != LWRES_R_SUCCESS) { if (lwres == LWRES_R_NOTFOUND) goto cleanup; else SETERROR(EAI_FAIL); } addr = LWRES_LIST_HEAD(by->addrs); while (addr != NULL) { ai = ai_clone(*aip, AF_INET); if (ai == NULL) SETERROR(EAI_MEMORY); *aip = ai; ai->ai_socktype = socktype; SIN(ai->ai_addr)->sin_port = port; memmove(&SIN(ai->ai_addr)->sin_addr, addr->address, 4); if (flags & AI_CANONNAME) { ai->ai_canonname = strdup(by->realname); if (ai->ai_canonname == NULL) SETERROR(EAI_MEMORY); } addr = LWRES_LIST_NEXT(addr, link); } } cleanup: if (by != NULL) lwres_gabnresponse_free(lwrctx, &by); if (lwrctx != NULL) { lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); } return (result); } static char v6_loop[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; static int add_ipv6(const char *hostname, int flags, struct addrinfo **aip, int socktype, int port) { struct addrinfo *ai; lwres_context_t *lwrctx = NULL; lwres_gabnresponse_t *by = NULL; lwres_addr_t *addr; lwres_result_t lwres; int result = 0; lwres = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0); if (lwres != LWRES_R_SUCCESS) SETERROR(EAI_FAIL); (void) lwres_conf_parse(lwrctx, lwres_resolv_conf); if (hostname == NULL && (flags & AI_PASSIVE) == 0) { ai = ai_clone(*aip, AF_INET6); if (ai == NULL) SETERROR(EAI_MEMORY); *aip = ai; ai->ai_socktype = socktype; SIN6(ai->ai_addr)->sin6_port = port; memmove(&SIN6(ai->ai_addr)->sin6_addr, v6_loop, 16); } else { lwres = lwres_getaddrsbyname(lwrctx, hostname, LWRES_ADDRTYPE_V6, &by); if (lwres != LWRES_R_SUCCESS) { if (lwres == LWRES_R_NOTFOUND) goto cleanup; else SETERROR(EAI_FAIL); } addr = LWRES_LIST_HEAD(by->addrs); while (addr != NULL) { ai = ai_clone(*aip, AF_INET6); if (ai == NULL) SETERROR(EAI_MEMORY); *aip = ai; ai->ai_socktype = socktype; SIN6(ai->ai_addr)->sin6_port = port; memmove(&SIN6(ai->ai_addr)->sin6_addr, addr->address, 16); if (flags & AI_CANONNAME) { ai->ai_canonname = strdup(by->realname); if (ai->ai_canonname == NULL) SETERROR(EAI_MEMORY); } addr = LWRES_LIST_NEXT(addr, link); } } cleanup: if (by != NULL) lwres_gabnresponse_free(lwrctx, &by); if (lwrctx != NULL) { lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); } return (result); } /*% Free address info. */ void lwres_freeaddrinfo(struct addrinfo *ai) { struct addrinfo *ai_next; while (ai != NULL) { ai_next = ai->ai_next; if (ai->ai_addr != NULL) free(ai->ai_addr); if (ai->ai_canonname) free(ai->ai_canonname); free(ai); ai = ai_next; } } #ifdef AF_LOCAL static int get_local(const char *name, int socktype, struct addrinfo **res) { struct addrinfo *ai; struct sockaddr_un *slocal; if (socktype == 0) return (EAI_SOCKTYPE); if (strlen(name) >= sizeof(slocal->sun_path)) return (EAI_OVERFLOW); ai = ai_alloc(AF_LOCAL, sizeof(*slocal)); if (ai == NULL) return (EAI_MEMORY); slocal = SLOCAL(ai->ai_addr); strncpy(slocal->sun_path, name, sizeof(slocal->sun_path)); slocal->sun_path[sizeof(slocal->sun_path) - 1] = '\0'; ai->ai_socktype = socktype; /* * ai->ai_flags, ai->ai_protocol, ai->ai_canonname, * and ai->ai_next were initialized to zero. */ *res = ai; return (0); } #endif /*! * Allocate an addrinfo structure, and a sockaddr structure * of the specificed length. We initialize: * ai_addrlen * ai_family * ai_addr * ai_addr->sa_family * ai_addr->sa_len (LWRES_PLATFORM_HAVESALEN) * and everything else is initialized to zero. */ static struct addrinfo * ai_alloc(int family, int addrlen) { struct addrinfo *ai; ai = (struct addrinfo *)calloc(1, sizeof(*ai)); if (ai == NULL) return (NULL); ai->ai_addr = SA(calloc(1, addrlen)); if (ai->ai_addr == NULL) { free(ai); return (NULL); } ai->ai_addrlen = addrlen; ai->ai_family = family; ai->ai_addr->sa_family = family; #ifdef LWRES_PLATFORM_HAVESALEN ai->ai_addr->sa_len = addrlen; #endif return (ai); } static struct addrinfo * ai_clone(struct addrinfo *oai, int family) { struct addrinfo *ai; ai = ai_alloc(family, ((family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))); if (ai == NULL) { lwres_freeaddrinfo(oai); return (NULL); } if (oai == NULL) return (ai); ai->ai_flags = oai->ai_flags; ai->ai_socktype = oai->ai_socktype; ai->ai_protocol = oai->ai_protocol; ai->ai_canonname = NULL; ai->ai_next = oai; return (ai); } static struct addrinfo * ai_reverse(struct addrinfo *oai) { struct addrinfo *nai, *tai; nai = NULL; while (oai != NULL) { /* * Grab one off the old list. */ tai = oai; oai = oai->ai_next; /* * Put it on the front of the new list. */ tai->ai_next = nai; nai = tai; } return (nai); } bind9-9.10.3.dfsg.P4/lib/lwres/lwres_gnba.c0000644000470500017500000002732112664710322017567 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lwres_gnba.c,v 1.28 2007/09/24 17:18:25 each Exp $ */ /*! \file lwres_gnba.c These are low-level routines for creating and parsing lightweight resolver address-to-name lookup request and response messages. There are four main functions for the getnamebyaddr opcode. One render function converts a getnamebyaddr request structure -- lwres_gnbarequest_t -- to the lightweight resolver's canonical format. It is complemented by a parse function that converts a packet in this canonical format to a getnamebyaddr request structure. Another render function converts the getnamebyaddr response structure -- lwres_gnbaresponse_t to the canonical format. This is complemented by a parse function which converts a packet in canonical format to a getnamebyaddr response structure. These structures are defined in \link lwres.h \endlink They are shown below. \code #define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U typedef struct { lwres_uint32_t flags; lwres_addr_t addr; } lwres_gnbarequest_t; typedef struct { lwres_uint32_t flags; lwres_uint16_t naliases; char *realname; char **aliases; lwres_uint16_t realnamelen; lwres_uint16_t *aliaslen; void *base; size_t baselen; } lwres_gnbaresponse_t; \endcode lwres_gnbarequest_render() uses resolver context ctx to convert getnamebyaddr request structure req to canonical format. The packet header structure pkt is initialised and transferred to buffer b. The contents of *req are then appended to the buffer in canonical format. lwres_gnbaresponse_render() performs the same task, except it converts a getnamebyaddr response structure lwres_gnbaresponse_t to the lightweight resolver's canonical format. lwres_gnbarequest_parse() uses context ctx to convert the contents of packet pkt to a lwres_gnbarequest_t structure. Buffer b provides space to be used for storing this structure. When the function succeeds, the resulting lwres_gnbarequest_t is made available through *structp. lwres_gnbaresponse_parse() offers the same semantics as lwres_gnbarequest_parse() except it yields a lwres_gnbaresponse_t structure. lwres_gnbaresponse_free() and lwres_gnbarequest_free() release the memory in resolver context ctx that was allocated to the lwres_gnbaresponse_t or lwres_gnbarequest_t structures referenced via structp. Any memory associated with ancillary buffers and strings for those structures is also discarded. \section lwres_gbna_return Return Values The getnamebyaddr opcode functions lwres_gnbarequest_render(), lwres_gnbaresponse_render() lwres_gnbarequest_parse() and lwres_gnbaresponse_parse() all return #LWRES_R_SUCCESS on success. They return #LWRES_R_NOMEMORY if memory allocation fails. #LWRES_R_UNEXPECTEDEND is returned if the available space in the buffer b is too small to accommodate the packet header or the lwres_gnbarequest_t and lwres_gnbaresponse_t structures. lwres_gnbarequest_parse() and lwres_gnbaresponse_parse() will return #LWRES_R_UNEXPECTEDEND if the buffer is not empty after decoding the received packet. These functions will return #LWRES_R_FAILURE if pktflags in the packet header structure #lwres_lwpacket_t indicate that the packet is not a response to an earlier query. \section lwres_gbna_see See Also \link lwpacket.c lwres_packet\endlink */ #include #include #include #include #include #include #include #include #include "context_p.h" #include "assert_p.h" /*% Uses resolver context ctx to convert getnamebyaddr request structure req to canonical format. */ lwres_result_t lwres_gnbarequest_render(lwres_context_t *ctx, lwres_gnbarequest_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b) { unsigned char *buf; size_t buflen; int ret; size_t payload_length; REQUIRE(ctx != NULL); REQUIRE(req != NULL); REQUIRE(req->addr.family != 0); REQUIRE(req->addr.length != 0); REQUIRE(pkt != NULL); REQUIRE(b != NULL); payload_length = 4 + 4 + 2 + + req->addr.length; buflen = LWRES_LWPACKET_LENGTH + payload_length; buf = CTXMALLOC(buflen); if (buf == NULL) return (LWRES_R_NOMEMORY); lwres_buffer_init(b, buf, (unsigned int)buflen); pkt->length = (lwres_uint32_t)buflen; pkt->version = LWRES_LWPACKETVERSION_0; pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE; pkt->opcode = LWRES_OPCODE_GETNAMEBYADDR; pkt->result = 0; pkt->authtype = 0; pkt->authlength = 0; ret = lwres_lwpacket_renderheader(b, pkt); if (ret != LWRES_R_SUCCESS) { lwres_buffer_invalidate(b); CTXFREE(buf, buflen); return (ret); } INSIST(SPACE_OK(b, payload_length)); /* * Put the length and the data. We know this will fit because we * just checked for it. */ lwres_buffer_putuint32(b, req->flags); lwres_buffer_putuint32(b, req->addr.family); lwres_buffer_putuint16(b, req->addr.length); lwres_buffer_putmem(b, (unsigned char *)req->addr.address, req->addr.length); INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0); return (LWRES_R_SUCCESS); } /*% Converts a getnamebyaddr response structure lwres_gnbaresponse_t to the lightweight resolver's canonical format. */ lwres_result_t lwres_gnbaresponse_render(lwres_context_t *ctx, lwres_gnbaresponse_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b) { unsigned char *buf; size_t buflen; int ret; size_t payload_length; lwres_uint16_t datalen; int x; REQUIRE(ctx != NULL); REQUIRE(req != NULL); REQUIRE(pkt != NULL); REQUIRE(b != NULL); /* * Calculate packet size. */ payload_length = 4; /* flags */ payload_length += 2; /* naliases */ payload_length += 2 + req->realnamelen + 1; /* real name encoding */ for (x = 0; x < req->naliases; x++) /* each alias */ payload_length += 2 + req->aliaslen[x] + 1; buflen = LWRES_LWPACKET_LENGTH + payload_length; buf = CTXMALLOC(buflen); if (buf == NULL) return (LWRES_R_NOMEMORY); lwres_buffer_init(b, buf, (unsigned int)buflen); pkt->length = (lwres_uint32_t)buflen; pkt->version = LWRES_LWPACKETVERSION_0; pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE; pkt->opcode = LWRES_OPCODE_GETNAMEBYADDR; pkt->authtype = 0; pkt->authlength = 0; ret = lwres_lwpacket_renderheader(b, pkt); if (ret != LWRES_R_SUCCESS) { lwres_buffer_invalidate(b); CTXFREE(buf, buflen); return (ret); } INSIST(SPACE_OK(b, payload_length)); lwres_buffer_putuint32(b, req->flags); /* encode naliases */ lwres_buffer_putuint16(b, req->naliases); /* encode the real name */ datalen = req->realnamelen; lwres_buffer_putuint16(b, datalen); lwres_buffer_putmem(b, (unsigned char *)req->realname, datalen); lwres_buffer_putuint8(b, 0); /* encode the aliases */ for (x = 0; x < req->naliases; x++) { datalen = req->aliaslen[x]; lwres_buffer_putuint16(b, datalen); lwres_buffer_putmem(b, (unsigned char *)req->aliases[x], datalen); lwres_buffer_putuint8(b, 0); } INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0); return (LWRES_R_SUCCESS); } /*% Uses context ctx to convert the contents of packet pkt to a lwres_gnbarequest_t structure. */ lwres_result_t lwres_gnbarequest_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gnbarequest_t **structp) { int ret; lwres_gnbarequest_t *gnba; REQUIRE(ctx != NULL); REQUIRE(pkt != NULL); REQUIRE(b != NULL); REQUIRE(structp != NULL && *structp == NULL); if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0) return (LWRES_R_FAILURE); if (!SPACE_REMAINING(b, 4)) return (LWRES_R_UNEXPECTEDEND); gnba = CTXMALLOC(sizeof(lwres_gnbarequest_t)); if (gnba == NULL) return (LWRES_R_NOMEMORY); gnba->flags = lwres_buffer_getuint32(b); ret = lwres_addr_parse(b, &gnba->addr); if (ret != LWRES_R_SUCCESS) goto out; if (LWRES_BUFFER_REMAINING(b) != 0) { ret = LWRES_R_TRAILINGDATA; goto out; } *structp = gnba; return (LWRES_R_SUCCESS); out: if (gnba != NULL) lwres_gnbarequest_free(ctx, &gnba); return (ret); } /*% Offers the same semantics as lwres_gnbarequest_parse() except it yields a lwres_gnbaresponse_t structure. */ lwres_result_t lwres_gnbaresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gnbaresponse_t **structp) { int ret; unsigned int x; lwres_uint32_t flags; lwres_uint16_t naliases; lwres_gnbaresponse_t *gnba; REQUIRE(ctx != NULL); REQUIRE(pkt != NULL); REQUIRE(b != NULL); REQUIRE(structp != NULL && *structp == NULL); gnba = NULL; if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0) return (LWRES_R_FAILURE); /* * Pull off flags & naliases */ if (!SPACE_REMAINING(b, 4 + 2)) return (LWRES_R_UNEXPECTEDEND); flags = lwres_buffer_getuint32(b); naliases = lwres_buffer_getuint16(b); gnba = CTXMALLOC(sizeof(lwres_gnbaresponse_t)); if (gnba == NULL) return (LWRES_R_NOMEMORY); gnba->base = NULL; gnba->aliases = NULL; gnba->aliaslen = NULL; gnba->flags = flags; gnba->naliases = naliases; if (naliases > 0) { gnba->aliases = CTXMALLOC(sizeof(char *) * naliases); if (gnba->aliases == NULL) { ret = LWRES_R_NOMEMORY; goto out; } gnba->aliaslen = CTXMALLOC(sizeof(lwres_uint16_t) * naliases); if (gnba->aliaslen == NULL) { ret = LWRES_R_NOMEMORY; goto out; } } /* * Now, pull off the real name. */ ret = lwres_string_parse(b, &gnba->realname, &gnba->realnamelen); if (ret != LWRES_R_SUCCESS) goto out; /* * Parse off the aliases. */ for (x = 0; x < gnba->naliases; x++) { ret = lwres_string_parse(b, &gnba->aliases[x], &gnba->aliaslen[x]); if (ret != LWRES_R_SUCCESS) goto out; } if (LWRES_BUFFER_REMAINING(b) != 0) { ret = LWRES_R_TRAILINGDATA; goto out; } *structp = gnba; return (LWRES_R_SUCCESS); out: if (gnba != NULL) { if (gnba->aliases != NULL) CTXFREE(gnba->aliases, sizeof(char *) * naliases); if (gnba->aliaslen != NULL) CTXFREE(gnba->aliaslen, sizeof(lwres_uint16_t) * naliases); CTXFREE(gnba, sizeof(lwres_gnbaresponse_t)); } return (ret); } /*% Release the memory in resolver context ctx that was allocated to the lwres_gnbarequest_t. */ void lwres_gnbarequest_free(lwres_context_t *ctx, lwres_gnbarequest_t **structp) { lwres_gnbarequest_t *gnba; REQUIRE(ctx != NULL); REQUIRE(structp != NULL && *structp != NULL); gnba = *structp; *structp = NULL; CTXFREE(gnba, sizeof(lwres_gnbarequest_t)); } /*% Release the memory in resolver context ctx that was allocated to the lwres_gnbaresponse_t. */ void lwres_gnbaresponse_free(lwres_context_t *ctx, lwres_gnbaresponse_t **structp) { lwres_gnbaresponse_t *gnba; REQUIRE(ctx != NULL); REQUIRE(structp != NULL && *structp != NULL); gnba = *structp; *structp = NULL; if (gnba->naliases > 0) { CTXFREE(gnba->aliases, sizeof(char *) * gnba->naliases); CTXFREE(gnba->aliaslen, sizeof(lwres_uint16_t) * gnba->naliases); } if (gnba->base != NULL) CTXFREE(gnba->base, gnba->baselen); CTXFREE(gnba, sizeof(lwres_gnbaresponse_t)); } bind9-9.10.3.dfsg.P4/lib/lwres/Makefile.in0000644000470500017500000000517612664710322017351 0ustar lamontlamont# Copyright (C) 2004, 2005, 2007, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000, 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.34 2007/06/19 23:47:22 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ @LIBLWRES_API@ @BIND9_MAKE_INCLUDES@ CINCLUDES = -I${srcdir}/unix/include \ -I. -I./include -I${srcdir}/include ${ISC_INCLUDES} CDEFINES = CWARNINGS = # Alphabetically OBJS = compat.@O@ context.@O@ \ gai_strerror.@O@ getaddrinfo.@O@ gethost.@O@ \ getipnode.@O@ getnameinfo.@O@ getrrset.@O@ herror.@O@ \ lwbuffer.@O@ lwconfig.@O@ lwpacket.@O@ lwresutil.@O@ \ lwres_gabn.@O@ lwres_gnba.@O@ lwres_grbn.@O@ lwres_noop.@O@ \ lwinetaton.@O@ lwinetpton.@O@ lwinetntop.@O@ print.@O@ # Alphabetically SRCS = compat.c context.c gai_strerror.c getaddrinfo.c gethost.c \ getipnode.c getnameinfo.c getrrset.c herror.c \ lwbuffer.c lwconfig.c lwpacket.c lwresutil.c \ lwres_gabn.c lwres_gnba.c lwres_grbn.c lwres_noop.c \ lwinetaton.c lwinetpton.c lwinetntop.c print.c LIBS = @LIBS@ SUBDIRS = include man unix TARGETS = timestamp TESTDIRS = @UNITTESTS@ @BIND9_MAKE_RULES@ version.@O@: version.c ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ -DVERSION=\"${VERSION}\" \ -DLIBINTERFACE=${LIBINTERFACE} \ -DLIBREVISION=${LIBREVISION} \ -DLIBAGE=${LIBAGE} \ -c ${srcdir}/version.c liblwres.@SA@: ${OBJS} version.@O@ ${AR} ${ARFLAGS} $@ ${OBJS} version.@O@ ${RANLIB} $@ liblwres.la: ${OBJS} version.@O@ ${LIBTOOL_MODE_LINK} \ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o liblwres.la -rpath ${libdir} \ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \ ${OBJS} version.@O@ ${LIBS} timestamp: liblwres.@A@ touch timestamp installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${libdir} install:: timestamp installdirs ${LIBTOOL_MODE_INSTALL} ${INSTALL_LIBRARY} liblwres.@A@ ${DESTDIR}${libdir} clean distclean:: rm -f liblwres.@A@ liblwres.la timestamp bind9-9.10.3.dfsg.P4/lib/lwres/gai_strerror.c0000644000470500017500000000575012664710322020150 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: gai_strerror.c,v 1.22 2007/06/19 23:47:22 tbox Exp $ */ /*! \file gai_strerror.c * lwres_gai_strerror() returns an error message corresponding to an * error code returned by getaddrinfo(). The following error codes and * their meaning are defined in \link netdb.h include/lwres/netdb.h.\endlink * * \li #EAI_ADDRFAMILY address family for hostname not supported * \li #EAI_AGAIN temporary failure in name resolution * \li #EAI_BADFLAGS invalid value for #ai_flags * \li #EAI_FAIL non-recoverable failure in name resolution * \li #EAI_FAMILY ai_family not supported * \li #EAI_MEMORY memory allocation failure * \li #EAI_NODATA no address associated with hostname * \li #EAI_NONAME hostname or servname not provided, or not known * \li #EAI_SERVICE servname not supported for ai_socktype * \li #EAI_SOCKTYPE ai_socktype not supported * \li #EAI_SYSTEM system error returned in errno * * The message invalid error code is returned if ecode is out of range. * * ai_flags, ai_family and ai_socktype are elements of the struct * addrinfo used by lwres_getaddrinfo(). * * \section gai_strerror_see See Also * * strerror, lwres_getaddrinfo(), getaddrinfo(), RFC2133. */ #include #include /*% Text of error messages. */ static const char *gai_messages[] = { "no error", "address family for hostname not supported", "temporary failure in name resolution", "invalid value for ai_flags", "non-recoverable failure in name resolution", "ai_family not supported", "memory allocation failure", "no address associated with hostname", "hostname nor servname provided, or not known", "servname not supported for ai_socktype", "ai_socktype not supported", "system error returned in errno", "bad hints", "bad protocol", "overflow" }; /*% Returns an error message corresponding to an error code returned by getaddrinfo() */ char * lwres_gai_strerror(int ecode) { union { const char *const_ptr; char *deconst_ptr; } ptr; if ((ecode < 0) || (ecode >= (int)(sizeof(gai_messages)/sizeof(*gai_messages)))) ptr.const_ptr = "invalid error code"; else ptr.const_ptr = gai_messages[ecode]; return (ptr.deconst_ptr); } bind9-9.10.3.dfsg.P4/lib/lwres/tests/0002755000470500017500000000000012672612753016447 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/lwres/tests/testdata/0002755000470500017500000000000012664710322020250 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/lwres/tests/testdata/link-local.conf0000644000470500017500000000002512664710322023137 0ustar lamontlamontnameserver fe80::1%1 bind9-9.10.3.dfsg.P4/lib/lwres/tests/Makefile.in0000644000470500017500000000273712664710322020513 0ustar lamontlamont# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id$ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ # Attempt to disable parallel processing. .NOTPARALLEL: .NO_PARALLEL: @BIND9_VERSION@ @BIND9_MAKE_INCLUDES@ CINCLUDES = -I. -Iinclude -I../include ${LWRES_INCLUDES} CDEFINES = -DTESTS="\"${top_builddir}/lib/lwres/tests/\"" LWRESLIBS = ../liblwres.@A@ LWRESDEPLIBS = ../liblwres.@A@ LIBS = @LIBS@ @ATFLIBS@ OBJS = SRCS = config_test.c SUBDIRS = TARGETS = config_test@EXEEXT@ @BIND9_MAKE_RULES@ config_test@EXEEXT@: config_test.@O@ ${LWRESDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ config_test.@O@ ${LWRESLIBS} ${LIBS} unit:: sh ${top_srcdir}/unit/unittest.sh clean distclean:: rm -f ${TARGETS} rm -f atf.out bind9-9.10.3.dfsg.P4/lib/lwres/tests/Atffile0000644000470500017500000000014012664710322017725 0ustar lamontlamontContent-Type: application/X-atf-atffile; version="1" prop: test-suite = bind9 tp-glob: *_test bind9-9.10.3.dfsg.P4/lib/lwres/tests/config_test.c0000644000470500017500000000413612664710322021111 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #include #include "../lwconfig.c" static void setup_test() { /* * atf-run changes us to a /tmp directory, so tests * that access test data files must first chdir to the proper * location. */ ATF_CHECK(chdir(TESTS) != -1); } ATF_TC(parse_linklocal); ATF_TC_HEAD(parse_linklocal, tc) { atf_tc_set_md_var(tc, "descr", "lwres_conf_parse link-local nameserver"); } ATF_TC_BODY(parse_linklocal, tc) { lwres_result_t result; lwres_context_t *ctx = NULL; unsigned char addr[16] = { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; UNUSED(tc); setup_test(); lwres_context_create(&ctx, NULL, NULL, NULL, LWRES_CONTEXT_USEIPV4 | LWRES_CONTEXT_USEIPV6); ATF_CHECK_EQ(ctx->confdata.nsnext, 0); ATF_CHECK_EQ(ctx->confdata.nameservers[0].zone, 0); result = lwres_conf_parse(ctx, "testdata/link-local.conf"); ATF_CHECK_EQ(result, LWRES_R_SUCCESS); ATF_CHECK_EQ(ctx->confdata.nsnext, 1); ATF_CHECK_EQ(ctx->confdata.nameservers[0].zone, 1); ATF_CHECK_EQ(memcmp(ctx->confdata.nameservers[0].address, addr, 16), 0); lwres_context_destroy(&ctx); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, parse_linklocal); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/lwres/lwpacket.c0000644000470500017500000001106112664710322017250 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lwpacket.c,v 1.18 2007/06/19 23:47:22 tbox Exp $ */ /*! \file */ /** * These functions rely on a struct lwres_lwpacket which is defined in * \link lwpacket.h lwres/lwpacket.h.\endlink * * The following opcodes are currently defined: * * \li #LWRES_OPCODE_NOOP * Success is always returned and the packet contents are * echoed. The \link lwres_noop.c lwres_noop_*()\endlink functions should be used for this * type. * * \li #LWRES_OPCODE_GETADDRSBYNAME * returns all known addresses for a given name. The * \link lwres_gabn.c lwres_gabn_*()\endlink functions should be used for this type. * * \li #LWRES_OPCODE_GETNAMEBYADDR * return the hostname for the given address. The * \link lwres_gnba.c lwres_gnba_*() \endlink functions should be used for this type. * * lwres_lwpacket_renderheader() transfers the contents of lightweight * resolver packet structure #lwres_lwpacket_t *pkt in network byte * order to the lightweight resolver buffer, *b. * * lwres_lwpacket_parseheader() performs the converse operation. It * transfers data in network byte order from buffer *b to resolver * packet *pkt. The contents of the buffer b should correspond to a * #lwres_lwpacket_t. * * \section lwpacket_return Return Values * * Successful calls to lwres_lwpacket_renderheader() and * lwres_lwpacket_parseheader() return #LWRES_R_SUCCESS. If there is * insufficient space to copy data between the buffer *b and * lightweight resolver packet *pkt both functions return * #LWRES_R_UNEXPECTEDEND. */ #include #include #include #include #include #include #include #include "assert_p.h" /*% Length of Packet */ #define LWPACKET_LENGTH \ (sizeof(lwres_uint16_t) * 4 + sizeof(lwres_uint32_t) * 5) /*% transfers the contents of lightweight resolver packet structure lwres_lwpacket_t *pkt in network byte order to the lightweight resolver buffer, *b. */ lwres_result_t lwres_lwpacket_renderheader(lwres_buffer_t *b, lwres_lwpacket_t *pkt) { REQUIRE(b != NULL); REQUIRE(pkt != NULL); if (!SPACE_OK(b, LWPACKET_LENGTH)) return (LWRES_R_UNEXPECTEDEND); lwres_buffer_putuint32(b, pkt->length); lwres_buffer_putuint16(b, pkt->version); lwres_buffer_putuint16(b, pkt->pktflags); lwres_buffer_putuint32(b, pkt->serial); lwres_buffer_putuint32(b, pkt->opcode); lwres_buffer_putuint32(b, pkt->result); lwres_buffer_putuint32(b, pkt->recvlength); lwres_buffer_putuint16(b, pkt->authtype); lwres_buffer_putuint16(b, pkt->authlength); return (LWRES_R_SUCCESS); } /*% transfers data in network byte order from buffer *b to resolver packet *pkt. The contents of the buffer b should correspond to a lwres_lwpacket_t. */ lwres_result_t lwres_lwpacket_parseheader(lwres_buffer_t *b, lwres_lwpacket_t *pkt) { lwres_uint32_t space; REQUIRE(b != NULL); REQUIRE(pkt != NULL); space = LWRES_BUFFER_REMAINING(b); if (space < LWPACKET_LENGTH) return (LWRES_R_UNEXPECTEDEND); pkt->length = lwres_buffer_getuint32(b); /* * XXXBEW/MLG Checking that the buffer is long enough probably * shouldn't be done here, since this function is supposed to just * parse the header. */ if (pkt->length > space) return (LWRES_R_UNEXPECTEDEND); pkt->version = lwres_buffer_getuint16(b); pkt->pktflags = lwres_buffer_getuint16(b); pkt->serial = lwres_buffer_getuint32(b); pkt->opcode = lwres_buffer_getuint32(b); pkt->result = lwres_buffer_getuint32(b); pkt->recvlength = lwres_buffer_getuint32(b); pkt->authtype = lwres_buffer_getuint16(b); pkt->authlength = lwres_buffer_getuint16(b); return (LWRES_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/lwres/lwinetntop.c0000644000470500017500000001217712664710322017652 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1996-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file lwinetntop.c */ #if defined(LIBC_SCCS) && !defined(lint) static char rcsid[] = "$Id: lwinetntop.c,v 1.18 2007/06/19 23:47:22 tbox Exp $"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include "print_p.h" #define NS_INT16SZ 2 #define NS_IN6ADDRSZ 16 /* * WARNING: Don't even consider trying to compile this on a system where * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ static const char *inet_ntop4(const unsigned char *src, char *dst, size_t size); #ifdef AF_INET6 static const char *inet_ntop6(const unsigned char *src, char *dst, size_t size); #endif /*! char * * lwres_net_ntop(af, src, dst, size) * convert a network format address to presentation format. * return: * pointer to presentation format address (`dst'), or NULL (see errno). * author: * Paul Vixie, 1996. */ const char * lwres_net_ntop(int af, const void *src, char *dst, size_t size) { switch (af) { case AF_INET: return (inet_ntop4(src, dst, size)); #ifdef AF_INET6 case AF_INET6: return (inet_ntop6(src, dst, size)); #endif default: errno = EAFNOSUPPORT; return (NULL); } /* NOTREACHED */ } /*! const char * * inet_ntop4(src, dst, size) * format an IPv4 address * return: * `dst' (as a const) * notes: * (1) uses no statics * (2) takes a unsigned char* not an in_addr as input * author: * Paul Vixie, 1996. */ static const char * inet_ntop4(const unsigned char *src, char *dst, size_t size) { static const char fmt[] = "%u.%u.%u.%u"; char tmp[sizeof("255.255.255.255")]; size_t len; len = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]); if (len >= size) { errno = ENOSPC; return (NULL); } strcpy(dst, tmp); return (dst); } /*! const char * * inet_ntop6(src, dst, size) * convert IPv6 binary address into presentation (printable) format * author: * Paul Vixie, 1996. */ #ifdef AF_INET6 static const char * inet_ntop6(const unsigned char *src, char *dst, size_t size) { /*! * Note that int32_t and int16_t need only be "at least" large enough * to contain a value of the specified size. On some systems, like * Crays, there is no such thing as an integer variable with 16 bits. * Keep this in mind if you think this function should have been coded * to use pointer overlays. All the world's not a VAX. */ char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")], *tp; struct { int base, len; } best, cur; unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ]; int i; /* * Preprocess: * Copy the input (bytewise) array into a wordwise array. * Find the longest run of 0x00's in src[] for :: shorthanding. */ memset(words, '\0', sizeof(words)); for (i = 0; i < NS_IN6ADDRSZ; i++) words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); best.base = -1; best.len = 0; cur.base = -1; cur.len = 0; for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { if (words[i] == 0) { if (cur.base == -1) cur.base = i, cur.len = 1; else cur.len++; } else { if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; cur.base = -1; } } } if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; } if (best.base != -1 && best.len < 2) best.base = -1; /* * Format the result. */ tp = tmp; for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { /* Are we inside the best run of 0x00's? */ if (best.base != -1 && i >= best.base && i < (best.base + best.len)) { if (i == best.base) *tp++ = ':'; continue; } /* Are we following an initial run of 0x00s or any real hex? */ if (i != 0) *tp++ = ':'; /* Is this address an encapsulated IPv4? */ if (i == 6 && best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { if (!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp))) return (NULL); tp += strlen(tp); break; } tp += sprintf(tp, "%x", words[i]); /* XXX */ } /* Was it a trailing run of 0x00's? */ if (best.base != -1 && (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ)) *tp++ = ':'; *tp++ = '\0'; /* * Check for overflow, copy, and we're done. */ if ((size_t)(tp - tmp) > size) { errno = ENOSPC; return (NULL); } strcpy(dst, tmp); return (dst); } #endif /* AF_INET6 */ bind9-9.10.3.dfsg.P4/lib/lwres/lwinetpton.c0000644000470500017500000001237312664710322017650 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2011-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1996-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file lwinetpton.c */ #if defined(LIBC_SCCS) && !defined(lint) static char rcsid[] = "$Id$"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #define NS_INT16SZ 2 #define NS_INADDRSZ 4 #define NS_IN6ADDRSZ 16 /* * WARNING: Don't even consider trying to compile this on a system where * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ static int inet_pton4(const char *src, unsigned char *dst); static int inet_pton6(const char *src, unsigned char *dst); /*! * int * lwres_net_pton(af, src, dst) * convert from presentation format (which usually means ASCII printable) * to network format (which is usually some kind of binary format). * return: * 1 if the address was valid for the specified address family * 0 if the address wasn't valid (`dst' is untouched in this case) * -1 if some other error occurred (`dst' is untouched in this case, too) * author: * Paul Vixie, 1996. */ int lwres_net_pton(int af, const char *src, void *dst) { switch (af) { case AF_INET: return (inet_pton4(src, dst)); case AF_INET6: return (inet_pton6(src, dst)); default: errno = EAFNOSUPPORT; return (-1); } /* NOTREACHED */ } /*! int * inet_pton4(src, dst) * like inet_aton() but without all the hexadecimal and shorthand. * return: * 1 if `src' is a valid dotted quad, else 0. * notice: * does not touch `dst' unless it's returning 1. * author: * Paul Vixie, 1996. */ static int inet_pton4(const char *src, unsigned char *dst) { static const char digits[] = "0123456789"; int saw_digit, octets, ch; unsigned char tmp[NS_INADDRSZ], *tp; saw_digit = 0; octets = 0; *(tp = tmp) = 0; while ((ch = *src++) != '\0') { const char *pch; if ((pch = strchr(digits, ch)) != NULL) { unsigned int new = *tp * 10; new += (unsigned int)(pch - digits); if (new > 255) return (0); *tp = new; if (! saw_digit) { if (++octets > 4) return (0); saw_digit = 1; } } else if (ch == '.' && saw_digit) { if (octets == 4) return (0); /* * "clang --analyse" generates warnings using: * *++tp = 0; */ tp++; *tp = 0; saw_digit = 0; } else return (0); } if (octets < 4) return (0); memmove(dst, tmp, NS_INADDRSZ); return (1); } /*! int * inet_pton6(src, dst) * convert presentation level address to network order binary form. * return: * 1 if `src' is a valid [RFC1884 2.2] address, else 0. * notice: * (1) does not touch `dst' unless it's returning 1. * (2) :: in a full address is silently ignored. * credit: * inspired by Mark Andrews. * author: * Paul Vixie, 1996. */ static int inet_pton6(const char *src, unsigned char *dst) { static const char xdigits_l[] = "0123456789abcdef", xdigits_u[] = "0123456789ABCDEF"; unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; const char *xdigits, *curtok; int ch, seen_xdigits; unsigned int val; memset((tp = tmp), '\0', NS_IN6ADDRSZ); endp = tp + NS_IN6ADDRSZ; colonp = NULL; /* Leading :: requires some special handling. */ if (*src == ':') if (*++src != ':') return (0); curtok = src; seen_xdigits = 0; val = 0; while ((ch = *src++) != '\0') { const char *pch; if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) pch = strchr((xdigits = xdigits_u), ch); if (pch != NULL) { val <<= 4; val |= (pch - xdigits); if (++seen_xdigits > 4) return (0); continue; } if (ch == ':') { curtok = src; if (!seen_xdigits) { if (colonp) return (0); colonp = tp; continue; } if (tp + NS_INT16SZ > endp) return (0); *tp++ = (unsigned char) (val >> 8) & 0xff; *tp++ = (unsigned char) val & 0xff; seen_xdigits = 0; val = 0; continue; } if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && inet_pton4(curtok, tp) > 0) { tp += NS_INADDRSZ; seen_xdigits = 0; break; /* '\0' was seen by inet_pton4(). */ } return (0); } if (seen_xdigits) { if (tp + NS_INT16SZ > endp) return (0); *tp++ = (unsigned char) (val >> 8) & 0xff; *tp++ = (unsigned char) val & 0xff; } if (colonp != NULL) { /* * Since some memmove()'s erroneously fail to handle * overlapping regions, we'll do the shift by hand. */ const int n = (int)(tp - colonp); int i; for (i = 1; i <= n; i++) { endp[- i] = colonp[n - i]; colonp[n - i] = 0; } tp = endp; } if (tp != endp) return (0); memmove(dst, tmp, NS_IN6ADDRSZ); return (1); } bind9-9.10.3.dfsg.P4/lib/lwres/herror.c0000644000470500017500000001032012664710322016734 0ustar lamontlamont/* * Portions Copyright (C) 2004, 2005, 2007, 2011, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (c) 1987, 1993 * The Regents of the University of California. 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. Neither the name of the University 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 REGENTS 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 herror.c lwres_herror() prints the string s on stderr followed by the string generated by lwres_hstrerror() for the error code stored in the global variable lwres_h_errno. lwres_hstrerror() returns an appropriate string for the error code gievn by err. The values of the error codes and messages are as follows: \li #NETDB_SUCCESS: Resolver Error 0 (no error) \li #HOST_NOT_FOUND: Unknown host \li #TRY_AGAIN: Host name lookup failure \li #NO_RECOVERY: Unknown server error \li #NO_DATA: No address associated with name */ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93"; static const char rcsid[] = "$Id$"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include LIBLWRES_EXTERNAL_DATA int lwres_h_errno; /*! * these have never been declared in any header file so make them static */ static const char *h_errlist[] = { "Resolver Error 0 (no error)", /*%< 0 no error */ "Unknown host", /*%< 1 HOST_NOT_FOUND */ "Host name lookup failure", /*%< 2 TRY_AGAIN */ "Unknown server error", /*%< 3 NO_RECOVERY */ "No address associated with name", /*%< 4 NO_ADDRESS */ }; static int h_nerr = sizeof(h_errlist) / sizeof(h_errlist[0]); /*! * herror -- * print the error indicated by the h_errno value. */ void lwres_herror(const char *s) { fprintf(stderr, "%s: %s\n", s, lwres_hstrerror(lwres_h_errno)); } /*! * hstrerror -- * return the string associated with a given "host" errno value. */ const char * lwres_hstrerror(int err) { if (err < 0) return ("Resolver internal error"); else if (err < h_nerr) return (h_errlist[err]); return ("Unknown resolver error"); } bind9-9.10.3.dfsg.P4/lib/lwres/lwbuffer.c0000644000470500017500000002353512664710322017263 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lwbuffer.c,v 1.15 2007/06/19 23:47:22 tbox Exp $ */ /*! \file */ /** * These functions provide bounds checked access to a region of memory * where data is being read or written. They are based on, and similar * to, the isc_buffer_ functions in the ISC library. * * A buffer is a region of memory, together with a set of related * subregions. The used region and the available region are disjoint, and * their union is the buffer's region. The used region extends from the * beginning of the buffer region to the last used byte. The available * region extends from one byte greater than the last used byte to the * end of the buffer's region. The size of the used region can be changed * using various buffer commands. Initially, the used region is empty. * * The used region is further subdivided into two disjoint regions: the * consumed region and the remaining region. The union of these two * regions is the used region. The consumed region extends from the * beginning of the used region to the byte before the current offset (if * any). The remaining region the current pointer to the end of the used * region. The size of the consumed region can be changed using various * buffer commands. Initially, the consumed region is empty. * * The active region is an (optional) subregion of the remaining region. * It extends from the current offset to an offset in the remaining * region. Initially, the active region is empty. If the current offset * advances beyond the chosen offset, the active region will also be * empty. * * * \verbatim * /------------entire length---------------\\ * /----- used region -----\\/-- available --\\ * +----------------------------------------+ * | consumed | remaining | | * +----------------------------------------+ * a b c d e * * a == base of buffer. * b == current pointer. Can be anywhere between a and d. * c == active pointer. Meaningful between b and d. * d == used pointer. * e == length of buffer. * * a-e == entire length of buffer. * a-d == used region. * a-b == consumed region. * b-d == remaining region. * b-c == optional active region. * \endverbatim * * lwres_buffer_init() initializes the lwres_buffer_t *b and assocates it * with the memory region of size length bytes starting at location base. * * lwres_buffer_invalidate() marks the buffer *b as invalid. Invalidating * a buffer after use is not required, but makes it possible to catch its * possible accidental use. * * The functions lwres_buffer_add() and lwres_buffer_subtract() * respectively increase and decrease the used space in buffer *b by n * bytes. lwres_buffer_add() checks for buffer overflow and * lwres_buffer_subtract() checks for underflow. These functions do not * allocate or deallocate memory. They just change the value of used. * * A buffer is re-initialised by lwres_buffer_clear(). The function sets * used , current and active to zero. * * lwres_buffer_first() makes the consumed region of buffer *p empty by * setting current to zero (the start of the buffer). * * lwres_buffer_forward() increases the consumed region of buffer *b by n * bytes, checking for overflow. Similarly, lwres_buffer_back() decreases * buffer b's consumed region by n bytes and checks for underflow. * * lwres_buffer_getuint8() reads an unsigned 8-bit integer from *b and * returns it. lwres_buffer_putuint8() writes the unsigned 8-bit integer * val to buffer *b. * * lwres_buffer_getuint16() and lwres_buffer_getuint32() are identical to * lwres_buffer_putuint8() except that they respectively read an unsigned * 16-bit or 32-bit integer in network byte order from b. Similarly, * lwres_buffer_putuint16() and lwres_buffer_putuint32() writes the * unsigned 16-bit or 32-bit integer val to buffer b, in network byte * order. * * Arbitrary amounts of data are read or written from a lightweight * resolver buffer with lwres_buffer_getmem() and lwres_buffer_putmem() * respectively. lwres_buffer_putmem() copies length bytes of memory at * base to b. Conversely, lwres_buffer_getmem() copies length bytes of * memory from b to base. */ #include #include #include #include "assert_p.h" void lwres_buffer_init(lwres_buffer_t *b, void *base, unsigned int length) { /* * Make 'b' refer to the 'length'-byte region starting at base. */ REQUIRE(b != NULL); b->magic = LWRES_BUFFER_MAGIC; b->base = base; b->length = length; b->used = 0; b->current = 0; b->active = 0; } /* Make 'b' an invalid buffer. */ void lwres_buffer_invalidate(lwres_buffer_t *b) { REQUIRE(LWRES_BUFFER_VALID(b)); b->magic = 0; b->base = NULL; b->length = 0; b->used = 0; b->current = 0; b->active = 0; } /* Increase the 'used' region of 'b' by 'n' bytes. */ void lwres_buffer_add(lwres_buffer_t *b, unsigned int n) { REQUIRE(LWRES_BUFFER_VALID(b)); REQUIRE(b->used + n <= b->length); b->used += n; } /* Decrease the 'used' region of 'b' by 'n' bytes. */ void lwres_buffer_subtract(lwres_buffer_t *b, unsigned int n) { REQUIRE(LWRES_BUFFER_VALID(b)); REQUIRE(b->used >= n); b->used -= n; if (b->current > b->used) b->current = b->used; if (b->active > b->used) b->active = b->used; } /* Make the used region empty. */ void lwres_buffer_clear(lwres_buffer_t *b) { REQUIRE(LWRES_BUFFER_VALID(b)); b->used = 0; b->current = 0; b->active = 0; } /* Make the consumed region empty. */ void lwres_buffer_first(lwres_buffer_t *b) { REQUIRE(LWRES_BUFFER_VALID(b)); b->current = 0; } /* Increase the 'consumed' region of 'b' by 'n' bytes. */ void lwres_buffer_forward(lwres_buffer_t *b, unsigned int n) { REQUIRE(LWRES_BUFFER_VALID(b)); REQUIRE(b->current + n <= b->used); b->current += n; } /* Decrease the 'consumed' region of 'b' by 'n' bytes. */ void lwres_buffer_back(lwres_buffer_t *b, unsigned int n) { REQUIRE(LWRES_BUFFER_VALID(b)); REQUIRE(n <= b->current); b->current -= n; } /* Read an unsigned 8-bit integer from 'b' and return it. */ lwres_uint8_t lwres_buffer_getuint8(lwres_buffer_t *b) { unsigned char *cp; lwres_uint8_t result; REQUIRE(LWRES_BUFFER_VALID(b)); REQUIRE(b->used - b->current >= 1); cp = b->base; cp += b->current; b->current += 1; result = ((unsigned int)(cp[0])); return (result); } /* Put an unsigned 8-bit integer */ void lwres_buffer_putuint8(lwres_buffer_t *b, lwres_uint8_t val) { unsigned char *cp; REQUIRE(LWRES_BUFFER_VALID(b)); REQUIRE(b->used + 1 <= b->length); cp = b->base; cp += b->used; b->used += 1; cp[0] = (val & 0x00ff); } /* Read an unsigned 16-bit integer in network byte order from 'b', convert it to host byte order, and return it. */ lwres_uint16_t lwres_buffer_getuint16(lwres_buffer_t *b) { unsigned char *cp; lwres_uint16_t result; REQUIRE(LWRES_BUFFER_VALID(b)); REQUIRE(b->used - b->current >= 2); cp = b->base; cp += b->current; b->current += 2; result = ((unsigned int)(cp[0])) << 8; result |= ((unsigned int)(cp[1])); return (result); } /* Put an unsigned 16-bit integer. */ void lwres_buffer_putuint16(lwres_buffer_t *b, lwres_uint16_t val) { unsigned char *cp; REQUIRE(LWRES_BUFFER_VALID(b)); REQUIRE(b->used + 2 <= b->length); cp = b->base; cp += b->used; b->used += 2; cp[0] = (val & 0xff00) >> 8; cp[1] = (val & 0x00ff); } /* Read an unsigned 32-bit integer in network byte order from 'b', convert it to host byte order, and return it. */ lwres_uint32_t lwres_buffer_getuint32(lwres_buffer_t *b) { unsigned char *cp; lwres_uint32_t result; REQUIRE(LWRES_BUFFER_VALID(b)); REQUIRE(b->used - b->current >= 4); cp = b->base; cp += b->current; b->current += 4; result = ((unsigned int)(cp[0])) << 24; result |= ((unsigned int)(cp[1])) << 16; result |= ((unsigned int)(cp[2])) << 8; result |= ((unsigned int)(cp[3])); return (result); } /* Put an unsigned 32-bit integer. */ void lwres_buffer_putuint32(lwres_buffer_t *b, lwres_uint32_t val) { unsigned char *cp; REQUIRE(LWRES_BUFFER_VALID(b)); REQUIRE(b->used + 4 <= b->length); cp = b->base; cp += b->used; b->used += 4; cp[0] = (unsigned char)((val & 0xff000000) >> 24); cp[1] = (unsigned char)((val & 0x00ff0000) >> 16); cp[2] = (unsigned char)((val & 0x0000ff00) >> 8); cp[3] = (unsigned char)(val & 0x000000ff); } /* copies length bytes of memory at base to b */ void lwres_buffer_putmem(lwres_buffer_t *b, const unsigned char *base, unsigned int length) { unsigned char *cp; REQUIRE(LWRES_BUFFER_VALID(b)); REQUIRE(b->used + length <= b->length); cp = (unsigned char *)b->base + b->used; memmove(cp, base, length); b->used += length; } /* copies length bytes of memory at b to base */ void lwres_buffer_getmem(lwres_buffer_t *b, unsigned char *base, unsigned int length) { unsigned char *cp; REQUIRE(LWRES_BUFFER_VALID(b)); REQUIRE(b->used - b->current >= length); cp = b->base; cp += b->current; b->current += length; memmove(base, cp, length); } bind9-9.10.3.dfsg.P4/lib/lwres/Atffile0000644000470500017500000000013212664710322016564 0ustar lamontlamontContent-Type: application/X-atf-atffile; version="1" prop: test-suite = bind9 tp: tests bind9-9.10.3.dfsg.P4/lib/lwres/include/0002755000470500017500000000000012672612753016730 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/lwres/include/Makefile.in0000644000470500017500000000176012664710322020767 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000, 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.8 2007/06/19 23:47:22 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = lwres TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/lwres/include/lwres/0002755000470500017500000000000012664710322020054 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/lwres/include/lwres/lang.h0000644000470500017500000000222712664710322021147 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lang.h,v 1.13 2007/06/19 23:47:23 tbox Exp $ */ #ifndef LWRES_LANG_H #define LWRES_LANG_H 1 /*! \file lwres/lang.h */ #ifdef __cplusplus #define LWRES_LANG_BEGINDECLS extern "C" { #define LWRES_LANG_ENDDECLS } #else #define LWRES_LANG_BEGINDECLS #define LWRES_LANG_ENDDECLS #endif #endif /* LWRES_LANG_H */ bind9-9.10.3.dfsg.P4/lib/lwres/include/lwres/int.h0000644000470500017500000000242112664710322021014 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: int.h,v 1.14 2007/06/19 23:47:23 tbox Exp $ */ #ifndef LWRES_INT_H #define LWRES_INT_H 1 /*! \file lwres/int.h */ typedef char lwres_int8_t; typedef unsigned char lwres_uint8_t; typedef short lwres_int16_t; typedef unsigned short lwres_uint16_t; typedef int lwres_int32_t; typedef unsigned int lwres_uint32_t; typedef long long lwres_int64_t; typedef unsigned long long lwres_uint64_t; #endif /* LWRES_INT_H */ bind9-9.10.3.dfsg.P4/lib/lwres/include/lwres/lwres.h0000644000470500017500000003720612664710322021367 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lwres.h,v 1.57 2007/06/19 23:47:23 tbox Exp $ */ #ifndef LWRES_LWRES_H #define LWRES_LWRES_H 1 #include #include #include #include #include #include /*! \file lwres/lwres.h */ /*! * Design notes: * * Each opcode has two structures and three functions which operate on each * structure. For example, using the "no operation/ping" opcode as an * example: * *
  • lwres_nooprequest_t: * * lwres_nooprequest_render() takes a lwres_nooprequest_t and * and renders it into wire format, storing the allocated * buffer information in a passed-in buffer. When this buffer * is no longer needed, it must be freed by * lwres_context_freemem(). All other memory used by the * caller must be freed manually, including the * lwres_nooprequest_t passed in.

    * * lwres_nooprequest_parse() takes a wire format message and * breaks it out into a lwres_nooprequest_t. The structure * must be freed via lwres_nooprequest_free() when it is no longer * needed.

    * * lwres_nooprequest_free() releases into the lwres_context_t * any space allocated during parsing.
  • * *
  • lwres_noopresponse_t: * * The functions used are similar to the three used for * requests, just with different names.
* * Typically, the client will use request_render, response_parse, and * response_free, while the daemon will use request_parse, response_render, * and request_free. * * The basic flow of a typical client is: * * \li fill in a request_t, and call the render function. * * \li Transmit the buffer returned to the daemon. * * \li Wait for a response. * * \li When a response is received, parse it into a response_t. * * \li free the request buffer using lwres_context_freemem(). * * \li free the response structure and its associated buffer using * response_free(). */ #define LWRES_UDP_PORT 921 /*%< UDP Port Number */ #define LWRES_RECVLENGTH 16384 /*%< Maximum Packet Length */ #define LWRES_ADDR_MAXLEN 16 /*%< changing this breaks ABI */ #define LWRES_RESOLV_CONF "/etc/resolv.conf" /*%< Location of resolv.conf */ /*% DNSSEC is not required (input). Only relevant to rrset queries. */ #define LWRES_FLAG_TRUSTNOTREQUIRED 0x00000001U /*% The data was crypto-verified with DNSSEC (output). */ #define LWRES_FLAG_SECUREDATA 0x00000002U /*% no-op */ #define LWRES_OPCODE_NOOP 0x00000000U /*% lwres_nooprequest_t */ typedef struct { /* public */ lwres_uint16_t datalength; unsigned char *data; } lwres_nooprequest_t; /*% lwres_noopresponse_t */ typedef struct { /* public */ lwres_uint16_t datalength; unsigned char *data; } lwres_noopresponse_t; /*% get addresses by name */ #define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U /*% lwres_addr_t */ typedef struct lwres_addr lwres_addr_t; /*% LWRES_LIST */ typedef LWRES_LIST(lwres_addr_t) lwres_addrlist_t; /*% lwres_addr */ struct lwres_addr { lwres_uint32_t family; lwres_uint16_t length; unsigned char address[LWRES_ADDR_MAXLEN]; lwres_uint32_t zone; LWRES_LINK(lwres_addr_t) link; }; /*% lwres_gabnrequest_t */ typedef struct { /* public */ lwres_uint32_t flags; lwres_uint32_t addrtypes; lwres_uint16_t namelen; char *name; } lwres_gabnrequest_t; /*% lwres_gabnresponse_t */ typedef struct { /* public */ lwres_uint32_t flags; lwres_uint16_t naliases; lwres_uint16_t naddrs; char *realname; char **aliases; lwres_uint16_t realnamelen; lwres_uint16_t *aliaslen; lwres_addrlist_t addrs; /*! if base != NULL, it will be freed when this structure is freed. */ void *base; size_t baselen; } lwres_gabnresponse_t; /*% get name by address */ #define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U /*% lwres_gnbarequest_t */ typedef struct { /* public */ lwres_uint32_t flags; lwres_addr_t addr; } lwres_gnbarequest_t; /*% lwres_gnbaresponse_t */ typedef struct { /* public */ lwres_uint32_t flags; lwres_uint16_t naliases; char *realname; char **aliases; lwres_uint16_t realnamelen; lwres_uint16_t *aliaslen; /*! if base != NULL, it will be freed when this structure is freed. */ void *base; size_t baselen; } lwres_gnbaresponse_t; /*% get rdata by name */ #define LWRES_OPCODE_GETRDATABYNAME 0x00010003U /*% lwres_grbnrequest_t */ typedef struct { /* public */ lwres_uint32_t flags; lwres_uint16_t rdclass; lwres_uint16_t rdtype; lwres_uint16_t namelen; char *name; } lwres_grbnrequest_t; /*% lwres_grbnresponse_t */ typedef struct { /* public */ lwres_uint32_t flags; lwres_uint16_t rdclass; lwres_uint16_t rdtype; lwres_uint32_t ttl; lwres_uint16_t nrdatas; lwres_uint16_t nsigs; char *realname; lwres_uint16_t realnamelen; unsigned char **rdatas; lwres_uint16_t *rdatalen; unsigned char **sigs; lwres_uint16_t *siglen; /*% if base != NULL, it will be freed when this structure is freed. */ void *base; size_t baselen; } lwres_grbnresponse_t; /*% Used by lwres_getrrsetbyname() */ #define LWRDATA_VALIDATED 0x00000001 /*! * resolv.conf data */ #define LWRES_CONFMAXNAMESERVERS 3 /*%< max 3 "nameserver" entries */ #define LWRES_CONFMAXLWSERVERS 1 /*%< max 1 "lwserver" entry */ #define LWRES_CONFMAXSEARCH 8 /*%< max 8 domains in "search" entry */ #define LWRES_CONFMAXLINELEN 256 /*%< max size of a line */ #define LWRES_CONFMAXSORTLIST 10 /*%< max 10 */ /*% lwres_conf_t */ typedef struct { lwres_context_t *lwctx; lwres_addr_t nameservers[LWRES_CONFMAXNAMESERVERS]; lwres_uint8_t nsnext; /*%< index for next free slot */ lwres_addr_t lwservers[LWRES_CONFMAXLWSERVERS]; lwres_uint8_t lwnext; /*%< index for next free slot */ char *domainname; char *search[LWRES_CONFMAXSEARCH]; lwres_uint8_t searchnxt; /*%< index for next free slot */ struct { lwres_addr_t addr; /*% mask has a non-zero 'family' and 'length' if set */ lwres_addr_t mask; } sortlist[LWRES_CONFMAXSORTLIST]; lwres_uint8_t sortlistnxt; lwres_uint8_t resdebug; /*%< non-zero if 'options debug' set */ lwres_uint8_t ndots; /*%< set to n in 'options ndots:n' */ lwres_uint8_t no_tld_query; /*%< non-zero if 'options no_tld_query' */ } lwres_conf_t; #define LWRES_ADDRTYPE_V4 0x00000001U /*%< ipv4 */ #define LWRES_ADDRTYPE_V6 0x00000002U /*%< ipv6 */ #define LWRES_MAX_ALIASES 16 /*%< max # of aliases */ #define LWRES_MAX_ADDRS 64 /*%< max # of addrs */ LWRES_LANG_BEGINDECLS /*% This is in host byte order. */ LIBLWRES_EXTERNAL_DATA extern lwres_uint16_t lwres_udp_port; LIBLWRES_EXTERNAL_DATA extern const char *lwres_resolv_conf; lwres_result_t lwres_gabnrequest_render(lwres_context_t *ctx, lwres_gabnrequest_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b); lwres_result_t lwres_gabnresponse_render(lwres_context_t *ctx, lwres_gabnresponse_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b); lwres_result_t lwres_gabnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gabnrequest_t **structp); lwres_result_t lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gabnresponse_t **structp); void lwres_gabnrequest_free(lwres_context_t *ctx, lwres_gabnrequest_t **structp); /**< * Frees any dynamically allocated memory for this structure. * * Requires: * * ctx != NULL, and be a context returned via lwres_context_create(). * * structp != NULL && *structp != NULL. * * Ensures: * * *structp == NULL. * * All memory allocated by this structure will be returned to the * system via the context's free function. */ void lwres_gabnresponse_free(lwres_context_t *ctx, lwres_gabnresponse_t **structp); /**< * Frees any dynamically allocated memory for this structure. * * Requires: * * ctx != NULL, and be a context returned via lwres_context_create(). * * structp != NULL && *structp != NULL. * * Ensures: * * *structp == NULL. * * All memory allocated by this structure will be returned to the * system via the context's free function. */ lwres_result_t lwres_gnbarequest_render(lwres_context_t *ctx, lwres_gnbarequest_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b); lwres_result_t lwres_gnbaresponse_render(lwres_context_t *ctx, lwres_gnbaresponse_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b); lwres_result_t lwres_gnbarequest_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gnbarequest_t **structp); lwres_result_t lwres_gnbaresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gnbaresponse_t **structp); void lwres_gnbarequest_free(lwres_context_t *ctx, lwres_gnbarequest_t **structp); /**< * Frees any dynamically allocated memory for this structure. * * Requires: * * ctx != NULL, and be a context returned via lwres_context_create(). * * structp != NULL && *structp != NULL. * * Ensures: * * *structp == NULL. * * All memory allocated by this structure will be returned to the * system via the context's free function. */ void lwres_gnbaresponse_free(lwres_context_t *ctx, lwres_gnbaresponse_t **structp); /**< * Frees any dynamically allocated memory for this structure. * * Requires: * * ctx != NULL, and be a context returned via lwres_context_create(). * * structp != NULL && *structp != NULL. * * Ensures: * * *structp == NULL. * * All memory allocated by this structure will be returned to the * system via the context's free function. */ lwres_result_t lwres_grbnrequest_render(lwres_context_t *ctx, lwres_grbnrequest_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b); lwres_result_t lwres_grbnresponse_render(lwres_context_t *ctx, lwres_grbnresponse_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b); lwres_result_t lwres_grbnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_grbnrequest_t **structp); lwres_result_t lwres_grbnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_grbnresponse_t **structp); void lwres_grbnrequest_free(lwres_context_t *ctx, lwres_grbnrequest_t **structp); /**< * Frees any dynamically allocated memory for this structure. * * Requires: * * ctx != NULL, and be a context returned via lwres_context_create(). * * structp != NULL && *structp != NULL. * * Ensures: * * *structp == NULL. * * All memory allocated by this structure will be returned to the * system via the context's free function. */ void lwres_grbnresponse_free(lwres_context_t *ctx, lwres_grbnresponse_t **structp); /**< * Frees any dynamically allocated memory for this structure. * * Requires: * * ctx != NULL, and be a context returned via lwres_context_create(). * * structp != NULL && *structp != NULL. * * Ensures: * * *structp == NULL. * * All memory allocated by this structure will be returned to the * system via the context's free function. */ lwres_result_t lwres_nooprequest_render(lwres_context_t *ctx, lwres_nooprequest_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b); /**< * Allocate space and render into wire format a noop request packet. * * Requires: * * ctx != NULL, and be a context returned via lwres_context_create(). * * b != NULL, and points to a lwres_buffer_t. The contents of the * buffer structure will be initialized to contain the wire-format * noop request packet. * * Caller needs to fill in parts of "pkt" before calling: * serial, maxrecv, result. * * Returns: * * Returns 0 on success, non-zero on failure. * * On successful return, *b will contain data about the wire-format * packet. It can be transmitted in any way, including lwres_sendblock(). */ lwres_result_t lwres_noopresponse_render(lwres_context_t *ctx, lwres_noopresponse_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b); lwres_result_t lwres_nooprequest_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_nooprequest_t **structp); /**< * Parse a noop request. Note that to get here, the lwpacket must have * already been parsed and removed by the caller, otherwise it would be * pretty hard for it to know this is the right function to call. * * The function verifies bits of the header, but does not modify it. */ lwres_result_t lwres_noopresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_noopresponse_t **structp); void lwres_nooprequest_free(lwres_context_t *ctx, lwres_nooprequest_t **structp); void lwres_noopresponse_free(lwres_context_t *ctx, lwres_noopresponse_t **structp); /**< * Frees any dynamically allocated memory for this structure. * * Requires: * * ctx != NULL, and be a context returned via lwres_context_create(). * * structp != NULL && *structp != NULL. * * Ensures: * * *structp == NULL. * * All memory allocated by this structure will be returned to the * system via the context's free function. */ lwres_result_t lwres_conf_parse(lwres_context_t *ctx, const char *filename); /**< * parses a resolv.conf-format file and stores the results in the structure * pointed to by *ctx. * * Requires: * ctx != NULL * filename != NULL && strlen(filename) > 0 * * Returns: * LWRES_R_SUCCESS on a successful parse. * Anything else on error, although the structure may be partially filled * in. */ lwres_result_t lwres_conf_print(lwres_context_t *ctx, FILE *fp); /**< * Prints a resolv.conf-format of confdata output to fp. * * Requires: * ctx != NULL */ void lwres_conf_init(lwres_context_t *ctx); /**< * sets all internal fields to a default state. Used to initialize a new * lwres_conf_t structure (not reset a used on). * * Requires: * ctx != NULL */ void lwres_conf_clear(lwres_context_t *ctx); /**< * frees all internally allocated memory in confdata. Uses the memory * routines supplied by ctx. * * Requires: * ctx != NULL */ lwres_conf_t * lwres_conf_get(lwres_context_t *ctx); /**< * Be extremely cautions in modifying the contents of this structure; it * needs an API to return the various bits of data, walk lists, etc. * * Requires: * ctx != NULL */ /* * Helper functions */ lwres_result_t lwres_data_parse(lwres_buffer_t *b, unsigned char **p, lwres_uint16_t *len); lwres_result_t lwres_string_parse(lwres_buffer_t *b, char **c, lwres_uint16_t *len); lwres_result_t lwres_addr_parse(lwres_buffer_t *b, lwres_addr_t *addr); lwres_result_t lwres_getaddrsbyname(lwres_context_t *ctx, const char *name, lwres_uint32_t addrtypes, lwres_gabnresponse_t **structp); lwres_result_t lwres_getnamebyaddr(lwres_context_t *ctx, lwres_uint32_t addrtype, lwres_uint16_t addrlen, const unsigned char *addr, lwres_gnbaresponse_t **structp); lwres_result_t lwres_getrdatabyname(lwres_context_t *ctx, const char *name, lwres_uint16_t rdclass, lwres_uint16_t rdtype, lwres_uint32_t flags, lwres_grbnresponse_t **structp); LWRES_LANG_ENDDECLS #endif /* LWRES_LWRES_H */ bind9-9.10.3.dfsg.P4/lib/lwres/include/lwres/platform.h.in0000644000470500017500000000572312664710322022463 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: platform.h.in,v 1.21 2007/06/19 23:47:23 tbox Exp $ */ /*! \file */ #ifndef LWRES_PLATFORM_H #define LWRES_PLATFORM_H 1 /***** ***** Platform-dependent defines. *****/ /*** *** Network. ***/ /* * Define if this system needs the header file for IPv6. */ @LWRES_PLATFORM_NEEDNETINETIN6H@ /* * Define if this system needs the header file for IPv6. */ @LWRES_PLATFORM_NEEDNETINET6IN6H@ /* * If sockaddrs on this system have an sa_len field, LWRES_PLATFORM_HAVESALEN * will be defined. */ @LWRES_PLATFORM_HAVESALEN@ /* * If this system has the IPv6 structure definitions, LWRES_PLATFORM_HAVEIPV6 * will be defined. */ @LWRES_PLATFORM_HAVEIPV6@ /* * If this system is missing in6addr_any, LWRES_PLATFORM_NEEDIN6ADDRANY will * be defined. */ @LWRES_PLATFORM_NEEDIN6ADDRANY@ /* * If this system is missing in6addr_loopback, * LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK will be defined. */ @LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK@ /* * If this system has in_addr6, rather than in6_addr, * LWRES_PLATFORM_HAVEINADDR6 will be defined. */ @LWRES_PLATFORM_HAVEINADDR6@ /* * Defined if unistd.h does not cause fd_set to be delared. */ @LWRES_PLATFORM_NEEDSYSSELECTH@ /* * Used to control how extern data is linked; needed for Win32 platforms. */ @LWRES_PLATFORM_USEDECLSPEC@ /* * Defined this system needs vsnprintf() and snprintf(). */ @LWRES_PLATFORM_NEEDVSNPRINTF@ /* * If this system need a modern sprintf() that returns (int) not (char*). */ @LWRES_PLATFORM_NEEDSPRINTF@ /* * The printf format string modifier to use with lwres_uint64_t values. */ @LWRES_PLATFORM_QUADFORMAT@ /*! \brief * Define if this system needs strtoul. */ @LWRES_PLATFORM_NEEDSTRTOUL@ /*! \brief * Define if this system needs strlcpy. */ @LWRES_PLATFORM_NEEDSTRLCPY@ #ifndef LWRES_PLATFORM_USEDECLSPEC #define LIBLWRES_EXTERNAL_DATA #else #ifdef LIBLWRES_EXPORTS #define LIBLWRES_EXTERNAL_DATA __declspec(dllexport) #else #define LIBLWRES_EXTERNAL_DATA __declspec(dllimport) #endif #endif /* * Tell Emacs to use C mode on this file. * Local Variables: * mode: c * End: */ #endif /* LWRES_PLATFORM_H */ bind9-9.10.3.dfsg.P4/lib/lwres/include/lwres/Makefile.in0000644000470500017500000000305112664710322022116 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000, 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ # # Only list headers that are to be installed and are not # machine generated. The latter are handled specially in the # install target below. # HEADERS = context.h int.h ipv6.h lang.h list.h \ lwbuffer.h lwpacket.h lwres.h result.h \ stdlib.h string.h version.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/lwres install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/lwres ; \ done ${INSTALL_DATA} netdb.h ${DESTDIR}${includedir}/lwres ${INSTALL_DATA} platform.h ${DESTDIR}${includedir}/lwres distclean:: rm -f netdb.h platform.h bind9-9.10.3.dfsg.P4/lib/lwres/include/lwres/ipv6.h0000644000470500017500000000640712664710322021116 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ipv6.h,v 1.16 2007/06/19 23:47:23 tbox Exp $ */ #ifndef LWRES_IPV6_H #define LWRES_IPV6_H 1 /***** ***** Module Info *****/ /*! \file lwres/ipv6.h * IPv6 definitions for systems which do not support IPv6. */ /*** *** Imports. ***/ #include #include /*** *** Types. ***/ /*% in6_addr structure */ struct in6_addr { union { lwres_uint8_t _S6_u8[16]; lwres_uint16_t _S6_u16[8]; lwres_uint32_t _S6_u32[4]; } _S6_un; }; /*@{*/ /*% IP v6 types */ #define s6_addr _S6_un._S6_u8 #define s6_addr8 _S6_un._S6_u8 #define s6_addr16 _S6_un._S6_u16 #define s6_addr32 _S6_un._S6_u32 /*@}*/ #define IN6ADDR_ANY_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}} #define IN6ADDR_LOOPBACK_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}} LIBLWRES_EXTERNAL_DATA extern const struct in6_addr in6addr_any; LIBLWRES_EXTERNAL_DATA extern const struct in6_addr in6addr_loopback; /*% used in getaddrinfo.c and getnameinfo.c */ struct sockaddr_in6 { #ifdef LWRES_PLATFORM_HAVESALEN lwres_uint8_t sin6_len; lwres_uint8_t sin6_family; #else lwres_uint16_t sin6_family; #endif lwres_uint16_t sin6_port; lwres_uint32_t sin6_flowinfo; struct in6_addr sin6_addr; lwres_uint32_t sin6_scope_id; }; #ifdef LWRES_PLATFORM_HAVESALEN #define SIN6_LEN 1 #endif /*% in6_pktinfo structure */ struct in6_pktinfo { struct in6_addr ipi6_addr; /*%< src/dst IPv6 address */ unsigned int ipi6_ifindex; /*%< send/recv interface index */ }; /*! * Unspecified IPv6 address */ #define IN6_IS_ADDR_UNSPECIFIED(a) \ (((a)->s6_addr32[0] == 0) && \ ((a)->s6_addr32[1] == 0) && \ ((a)->s6_addr32[2] == 0) && \ ((a)->s6_addr32[3] == 0)) /* * Loopback */ #define IN6_IS_ADDR_LOOPBACK(a) \ (((a)->s6_addr32[0] == 0) && \ ((a)->s6_addr32[1] == 0) && \ ((a)->s6_addr32[2] == 0) && \ ((a)->s6_addr32[3] == htonl(1))) /* * IPv4 compatible */ #define IN6_IS_ADDR_V4COMPAT(a) \ (((a)->s6_addr32[0] == 0) && \ ((a)->s6_addr32[1] == 0) && \ ((a)->s6_addr32[2] == 0) && \ ((a)->s6_addr32[3] != 0) && \ ((a)->s6_addr32[3] != htonl(1))) /* * Mapped */ #define IN6_IS_ADDR_V4MAPPED(a) \ (((a)->s6_addr32[0] == 0) && \ ((a)->s6_addr32[1] == 0) && \ ((a)->s6_addr32[2] == htonl(0x0000ffff))) #endif /* LWRES_IPV6_H */ bind9-9.10.3.dfsg.P4/lib/lwres/include/lwres/string.h0000644000470500017500000000215312664710322021532 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef LWRES_STRING_H #define LWRES_STRING_H 1 /*! \file lwres/string.h */ #include #include #include #ifdef LWRES_PLATFORM_NEEDSTRLCPY #define strlcpy lwres_strlcpy #endif LWRES_LANG_BEGINDECLS size_t lwres_strlcpy(char *dst, const char *src, size_t size); LWRES_LANG_ENDDECLS #endif bind9-9.10.3.dfsg.P4/lib/lwres/include/lwres/lwpacket.h0000644000470500017500000001300212664710322022031 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lwpacket.h,v 1.24 2007/06/19 23:47:23 tbox Exp $ */ #ifndef LWRES_LWPACKET_H #define LWRES_LWPACKET_H 1 #include #include #include /*% lwres_lwpacket_t */ typedef struct lwres_lwpacket lwres_lwpacket_t; /*% lwres_lwpacket structure */ struct lwres_lwpacket { /*! The overall packet length, including the * entire packet header. * This field is filled in by the * \link lwres_gabn.c lwres_gabn_*()\endlink * and \link lwres_gnba.c lwres_gnba_*()\endlink calls. */ lwres_uint32_t length; /*! Specifies the header format. Currently, * there is only one format, #LWRES_LWPACKETVERSION_0. * This field is filled in by the * \link lwres_gabn.c lwres_gabn_*()\endlink * and \link lwres_gnba.c lwres_gnba_*()\endlink calls. */ lwres_uint16_t version; /*! Specifies library-defined flags for this packet, such as * whether the packet is a request or a reply. None of * these are definable by the caller, but library-defined values * can be set by the caller. For example, one bit in this field * indicates if the packet is a request or a response. * This field is filled in by * the application wits the exception of the * #LWRES_LWPACKETFLAG_RESPONSE bit, which is set by the library * in the * \link lwres_gabn.c lwres_gabn_*()\endlink * and \link lwres_gnba.c lwres_gnba_*()\endlink calls. */ lwres_uint16_t pktflags; /*! Set by the requestor and is returned in all replies. * If two packets from the same source have the same serial * number and are from the same source, they are assumed to * be duplicates and the latter ones may be dropped. * (The library does not do this by default on replies, but * does so on requests.) */ lwres_uint32_t serial; /*! Opcodes between 0x04000000 and 0xffffffff * are application defined. Opcodes between * 0x00000000 and 0x03ffffff are * reserved for library use. * This field is filled in by the * \link lwres_gabn.c lwres_gabn_*()\endlink * and \link lwres_gnba.c lwres_gnba_*()\endlink calls. */ lwres_uint32_t opcode; /*! Only valid for results. * Results between 0x04000000 and 0xffffffff are application * defined. * Results between 0x00000000 and 0x03ffffff are reserved for * library use. * (This is the same reserved range defined in , * so it * would be trivial to map ISC_R_* result codes into packet result * codes when appropriate.) * This field is filled in by the * \link lwres_gabn.c lwres_gabn_*()\endlink * and \link lwres_gnba.c lwres_gnba_*()\endlink calls. */ lwres_uint32_t result; /*! Set to the maximum buffer size that the receiver can * handle on requests, and the size of the buffer needed to * satisfy a request * when the buffer is too large for replies. * This field is supplied by the application. */ lwres_uint32_t recvlength; /*! The packet level auth type used. * Authtypes between 0x1000 and 0xffff are application defined. * Authtypes * between 0x0000 and 0x0fff are reserved for library use. * This is currently * unused and MUST be set to zero. */ lwres_uint16_t authtype; /*! The length of the authentication data. * See the specific * authtypes for more information on what is contained * in this field. This is currently unused, and * MUST be set to zero. */ lwres_uint16_t authlength; }; #define LWRES_LWPACKET_LENGTH (4 * 5 + 2 * 4) /*%< Overall length. */ #define LWRES_LWPACKETFLAG_RESPONSE 0x0001U /*%< If set, pkt is a response. */ #define LWRES_LWPACKETVERSION_0 0 /*%< Header format. */ /*! \file lwres/lwpacket.h * * * The remainder of the packet consists of two regions, one described by * "authlen" and one of "length - authlen - sizeof(lwres_lwpacket_t)". * * That is: * * \code * pkt header * authlen bytes of auth information * data bytes * \endcode * * Currently defined opcodes: * *\li #LWRES_OPCODE_NOOP. Success is always returned, with the packet contents echoed. * *\li #LWRES_OPCODE_GETADDRSBYNAME. Return all known addresses for a given name. * This may return NIS or /etc/hosts info as well as DNS * information. Flags will be provided to indicate ip4/ip6 * addresses are desired. * *\li #LWRES_OPCODE_GETNAMEBYADDR. Return the hostname for the given address. Once * again, it will return data from multiple sources. */ LWRES_LANG_BEGINDECLS /* XXXMLG document */ lwres_result_t lwres_lwpacket_renderheader(lwres_buffer_t *b, lwres_lwpacket_t *pkt); lwres_result_t lwres_lwpacket_parseheader(lwres_buffer_t *b, lwres_lwpacket_t *pkt); LWRES_LANG_ENDDECLS #endif /* LWRES_LWPACKET_H */ bind9-9.10.3.dfsg.P4/lib/lwres/include/lwres/result.h0000644000470500017500000000277112664710322021550 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: result.h,v 1.21 2007/06/19 23:47:23 tbox Exp $ */ #ifndef LWRES_RESULT_H #define LWRES_RESULT_H 1 /*! \file lwres/result.h */ typedef unsigned int lwres_result_t; #define LWRES_R_SUCCESS 0 #define LWRES_R_NOMEMORY 1 #define LWRES_R_TIMEOUT 2 #define LWRES_R_NOTFOUND 3 #define LWRES_R_UNEXPECTEDEND 4 /* unexpected end of input */ #define LWRES_R_FAILURE 5 /* generic failure */ #define LWRES_R_IOERROR 6 #define LWRES_R_NOTIMPLEMENTED 7 #define LWRES_R_UNEXPECTED 8 #define LWRES_R_TRAILINGDATA 9 #define LWRES_R_INCOMPLETE 10 #define LWRES_R_RETRY 11 #define LWRES_R_TYPENOTFOUND 12 #define LWRES_R_TOOLARGE 13 #endif /* LWRES_RESULT_H */ bind9-9.10.3.dfsg.P4/lib/lwres/include/lwres/context.h0000644000470500017500000000731012664710322021710 0ustar lamontlamont/* * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: context.h,v 1.23 2008/12/17 23:47:58 tbox Exp $ */ #ifndef LWRES_CONTEXT_H #define LWRES_CONTEXT_H 1 /*! \file lwres/context.h */ #include #include #include #include /*! * Used to set various options such as timeout, authentication, etc */ typedef struct lwres_context lwres_context_t; LWRES_LANG_BEGINDECLS typedef void *(*lwres_malloc_t)(void *arg, size_t length); typedef void (*lwres_free_t)(void *arg, void *mem, size_t length); /* * XXXMLG * * Make the server reload /etc/resolv.conf periodically. * * Make the server do sortlist/searchlist. * * Client side can disable the search/sortlist processing. * * Use an array of addresses/masks and searchlist for client-side, and * if added to the client disable the processing on the server. * * Share /etc/resolv.conf data between contexts. */ /*! * _SERVERMODE * Don't allocate and connect a socket to the server, since the * caller _is_ a server. * * _USEIPV4, _USEIPV6 * Use IPv4 and IPv6 transactions with remote servers, respectively. * For backward compatibility, regard both flags as being set when both * are cleared. */ #define LWRES_CONTEXT_SERVERMODE 0x00000001U #define LWRES_CONTEXT_USEIPV4 0x00000002U #define LWRES_CONTEXT_USEIPV6 0x00000004U lwres_result_t lwres_context_create(lwres_context_t **contextp, void *arg, lwres_malloc_t malloc_function, lwres_free_t free_function, unsigned int flags); /**< * Allocate a lwres context. This is used in all lwres calls. * * Memory management can be replaced here by passing in two functions. * If one is non-NULL, they must both be non-NULL. "arg" is passed to * these functions. * * Contexts are not thread safe. Document at the top of the file. * XXXMLG * * If they are NULL, the standard malloc() and free() will be used. * *\pre contextp != NULL && contextp == NULL. * *\return Returns 0 on success, non-zero on failure. */ void lwres_context_destroy(lwres_context_t **contextp); /**< * Frees all memory associated with a lwres context. * *\pre contextp != NULL && contextp == NULL. */ lwres_uint32_t lwres_context_nextserial(lwres_context_t *ctx); /**< * XXXMLG Document */ void lwres_context_initserial(lwres_context_t *ctx, lwres_uint32_t serial); void lwres_context_freemem(lwres_context_t *ctx, void *mem, size_t len); void * lwres_context_allocmem(lwres_context_t *ctx, size_t len); int lwres_context_getsocket(lwres_context_t *ctx); lwres_result_t lwres_context_send(lwres_context_t *ctx, void *sendbase, int sendlen); lwres_result_t lwres_context_recv(lwres_context_t *ctx, void *recvbase, int recvlen, int *recvd_len); lwres_result_t lwres_context_sendrecv(lwres_context_t *ctx, void *sendbase, int sendlen, void *recvbase, int recvlen, int *recvd_len); LWRES_LANG_ENDDECLS #endif /* LWRES_CONTEXT_H */ bind9-9.10.3.dfsg.P4/lib/lwres/include/lwres/lwbuffer.h0000644000470500017500000002224712664710322022046 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lwbuffer.h,v 1.22 2007/06/19 23:47:23 tbox Exp $ */ /*! \file lwres/lwbuffer.h * * A buffer is a region of memory, together with a set of related subregions. * Buffers are used for parsing and I/O operations. * * The 'used region' and the 'available' region are disjoint, and their * union is the buffer's region. The used region extends from the beginning * of the buffer region to the last used byte. The available region * extends from one byte greater than the last used byte to the end of the * buffer's region. The size of the used region can be changed using various * buffer commands. Initially, the used region is empty. * * The used region is further subdivided into two disjoint regions: the * 'consumed region' and the 'remaining region'. The union of these two * regions is the used region. The consumed region extends from the beginning * of the used region to the byte before the 'current' offset (if any). The * 'remaining' region the current pointer to the end of the used * region. The size of the consumed region can be changed using various * buffer commands. Initially, the consumed region is empty. * * The 'active region' is an (optional) subregion of the remaining region. * It extends from the current offset to an offset in the remaining region * that is selected with lwres_buffer_setactive(). Initially, the active * region is empty. If the current offset advances beyond the chosen offset, * the active region will also be empty. * * \verbatim * /----- used region -----\/-- available --\ * +----------------------------------------+ * | consumed | remaining | | * +----------------------------------------+ * a b c d e * * a == base of buffer. * b == current pointer. Can be anywhere between a and d. * c == active pointer. Meaningful between b and d. * d == used pointer. * e == length of buffer. * * a-e == entire (length) of buffer. * a-d == used region. * a-b == consumed region. * b-d == remaining region. * b-c == optional active region. * \endverbatim * * The following invariants are maintained by all routines: * *\verbatim * length > 0 * * base is a valid pointer to length bytes of memory * * 0 <= used <= length * * 0 <= current <= used * * 0 <= active <= used * (although active < current implies empty active region) *\endverbatim * * \li MP: * Buffers have no synchronization. Clients must ensure exclusive * access. * * \li Reliability: * No anticipated impact. * * \li Resources: * Memory: 1 pointer + 6 unsigned integers per buffer. * * \li Security: * No anticipated impact. * * \li Standards: * None. */ #ifndef LWRES_LWBUFFER_H #define LWRES_LWBUFFER_H 1 /*** *** Imports ***/ #include #include LWRES_LANG_BEGINDECLS /*** *** Magic numbers ***/ #define LWRES_BUFFER_MAGIC 0x4275663fU /* Buf?. */ #define LWRES_BUFFER_VALID(b) ((b) != NULL && \ (b)->magic == LWRES_BUFFER_MAGIC) /*! * The following macros MUST be used only on valid buffers. It is the * caller's responsibility to ensure this by using the LWRES_BUFFER_VALID * check above, or by calling another lwres_buffer_*() function (rather than * another macro.) */ /*! * Get the length of the used region of buffer "b" */ #define LWRES_BUFFER_USEDCOUNT(b) ((b)->used) /*! * Get the length of the available region of buffer "b" */ #define LWRES_BUFFER_AVAILABLECOUNT(b) ((b)->length - (b)->used) #define LWRES_BUFFER_REMAINING(b) ((b)->used - (b)->current) /*! * Note that the buffer structure is public. This is principally so buffer * operations can be implemented using macros. Applications are strongly * discouraged from directly manipulating the structure. */ typedef struct lwres_buffer lwres_buffer_t; /*! * Buffer data structure */ struct lwres_buffer { unsigned int magic; unsigned char *base; /* The following integers are byte offsets from 'base'. */ unsigned int length; unsigned int used; unsigned int current; unsigned int active; }; /*** *** Functions ***/ void lwres_buffer_init(lwres_buffer_t *b, void *base, unsigned int length); /**< * Make 'b' refer to the 'length'-byte region starting at base. * * Requires: * * 'length' > 0 * * 'base' is a pointer to a sequence of 'length' bytes. * */ void lwres_buffer_invalidate(lwres_buffer_t *b); /**< * Make 'b' an invalid buffer. * * Requires: * 'b' is a valid buffer. * * Ensures: * If assertion checking is enabled, future attempts to use 'b' without * calling lwres_buffer_init() on it will cause an assertion failure. */ void lwres_buffer_add(lwres_buffer_t *b, unsigned int n); /**< * Increase the 'used' region of 'b' by 'n' bytes. * * Requires: * * 'b' is a valid buffer * * used + n <= length * */ void lwres_buffer_subtract(lwres_buffer_t *b, unsigned int n); /**< * Decrease the 'used' region of 'b' by 'n' bytes. * * Requires: * * 'b' is a valid buffer * * used >= n * */ void lwres_buffer_clear(lwres_buffer_t *b); /**< * Make the used region empty. * * Requires: * * 'b' is a valid buffer * * Ensures: * * used = 0 * */ void lwres_buffer_first(lwres_buffer_t *b); /**< * Make the consumed region empty. * * Requires: * * 'b' is a valid buffer * * Ensures: * * current == 0 * */ void lwres_buffer_forward(lwres_buffer_t *b, unsigned int n); /**< * Increase the 'consumed' region of 'b' by 'n' bytes. * * Requires: * * 'b' is a valid buffer * * current + n <= used * */ void lwres_buffer_back(lwres_buffer_t *b, unsigned int n); /**< * Decrease the 'consumed' region of 'b' by 'n' bytes. * * Requires: * * 'b' is a valid buffer * * n <= current * */ lwres_uint8_t lwres_buffer_getuint8(lwres_buffer_t *b); /**< * Read an unsigned 8-bit integer from 'b' and return it. * * Requires: * * 'b' is a valid buffer. * * The length of the available region of 'b' is at least 1. * * Ensures: * * The current pointer in 'b' is advanced by 1. * * Returns: * * A 8-bit unsigned integer. */ void lwres_buffer_putuint8(lwres_buffer_t *b, lwres_uint8_t val); /**< * Store an unsigned 8-bit integer from 'val' into 'b'. * * Requires: * 'b' is a valid buffer. * * The length of the unused region of 'b' is at least 1. * * Ensures: * The used pointer in 'b' is advanced by 1. */ lwres_uint16_t lwres_buffer_getuint16(lwres_buffer_t *b); /**< * Read an unsigned 16-bit integer in network byte order from 'b', convert * it to host byte order, and return it. * * Requires: * * 'b' is a valid buffer. * * The length of the available region of 'b' is at least 2. * * Ensures: * * The current pointer in 'b' is advanced by 2. * * Returns: * * A 16-bit unsigned integer. */ void lwres_buffer_putuint16(lwres_buffer_t *b, lwres_uint16_t val); /**< * Store an unsigned 16-bit integer in host byte order from 'val' * into 'b' in network byte order. * * Requires: * 'b' is a valid buffer. * * The length of the unused region of 'b' is at least 2. * * Ensures: * The used pointer in 'b' is advanced by 2. */ lwres_uint32_t lwres_buffer_getuint32(lwres_buffer_t *b); /**< * Read an unsigned 32-bit integer in network byte order from 'b', convert * it to host byte order, and return it. * * Requires: * * 'b' is a valid buffer. * * The length of the available region of 'b' is at least 2. * * Ensures: * * The current pointer in 'b' is advanced by 2. * * Returns: * * A 32-bit unsigned integer. */ void lwres_buffer_putuint32(lwres_buffer_t *b, lwres_uint32_t val); /**< * Store an unsigned 32-bit integer in host byte order from 'val' * into 'b' in network byte order. * * Requires: * 'b' is a valid buffer. * * The length of the unused region of 'b' is at least 4. * * Ensures: * The used pointer in 'b' is advanced by 4. */ void lwres_buffer_putmem(lwres_buffer_t *b, const unsigned char *base, unsigned int length); /**< * Copy 'length' bytes of memory at 'base' into 'b'. * * Requires: * 'b' is a valid buffer. * * 'base' points to 'length' bytes of valid memory. * */ void lwres_buffer_getmem(lwres_buffer_t *b, unsigned char *base, unsigned int length); /**< * Copy 'length' bytes of memory from 'b' into 'base'. * * Requires: * 'b' is a valid buffer. * * 'base' points to at least 'length' bytes of valid memory. * * 'b' have at least 'length' bytes remaining. */ LWRES_LANG_ENDDECLS #endif /* LWRES_LWBUFFER_H */ bind9-9.10.3.dfsg.P4/lib/lwres/include/lwres/version.h0000644000470500017500000000231312664710322021707 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: version.h,v 1.9 2007/06/19 23:47:23 tbox Exp $ */ /*! \file lwres/version.h */ #include LIBLWRES_EXTERNAL_DATA extern const char lwres_version[]; LIBLWRES_EXTERNAL_DATA extern const unsigned int lwres_libinterface; LIBLWRES_EXTERNAL_DATA extern const unsigned int lwres_librevision; LIBLWRES_EXTERNAL_DATA extern const unsigned int lwres_libage; bind9-9.10.3.dfsg.P4/lib/lwres/include/lwres/netdb.h.in0000644000470500017500000003127412664710322021733 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: netdb.h.in,v 1.41 2009/01/18 23:48:14 tbox Exp $ */ /*! \file */ #ifndef LWRES_NETDB_H #define LWRES_NETDB_H 1 #include /* Required on FreeBSD (and others?) for size_t. */ #include /* Contractual provision. */ #include /* * Define if does not declare struct addrinfo. */ @ISC_LWRES_NEEDADDRINFO@ #ifdef ISC_LWRES_NEEDADDRINFO struct addrinfo { int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ int ai_family; /* PF_xxx */ int ai_socktype; /* SOCK_xxx */ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ size_t ai_addrlen; /* Length of ai_addr */ char *ai_canonname; /* Canonical name for hostname */ struct sockaddr *ai_addr; /* Binary address */ struct addrinfo *ai_next; /* Next structure in linked list */ }; #endif /* * Undefine all #defines we are interested in as may or may not have * defined them. */ /* * Error return codes from gethostbyname() and gethostbyaddr() * (left in extern int h_errno). */ #undef NETDB_INTERNAL #undef NETDB_SUCCESS #undef HOST_NOT_FOUND #undef TRY_AGAIN #undef NO_RECOVERY #undef NO_DATA #undef NO_ADDRESS #define NETDB_INTERNAL -1 /* see errno */ #define NETDB_SUCCESS 0 /* no problem */ #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */ #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL */ #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ #define NO_DATA 4 /* Valid name, no data record of requested type */ #define NO_ADDRESS NO_DATA /* no address, look for MX record */ /* * Error return codes from getaddrinfo() */ #undef EAI_ADDRFAMILY #undef EAI_AGAIN #undef EAI_BADFLAGS #undef EAI_FAIL #undef EAI_FAMILY #undef EAI_MEMORY #undef EAI_NODATA #undef EAI_NONAME #undef EAI_SERVICE #undef EAI_SOCKTYPE #undef EAI_SYSTEM #undef EAI_BADHINTS #undef EAI_PROTOCOL #undef EAI_OVERFLOW #undef EAI_MAX #define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ #define EAI_AGAIN 2 /* temporary failure in name resolution */ #define EAI_BADFLAGS 3 /* invalid value for ai_flags */ #define EAI_FAIL 4 /* non-recoverable failure in name resolution */ #define EAI_FAMILY 5 /* ai_family not supported */ #define EAI_MEMORY 6 /* memory allocation failure */ #define EAI_NODATA 7 /* no address associated with hostname */ #define EAI_NONAME 8 /* hostname nor servname provided, or not known */ #define EAI_SERVICE 9 /* servname not supported for ai_socktype */ #define EAI_SOCKTYPE 10 /* ai_socktype not supported */ #define EAI_SYSTEM 11 /* system error returned in errno */ #define EAI_BADHINTS 12 #define EAI_PROTOCOL 13 #define EAI_OVERFLOW 14 #define EAI_MAX 15 /* * Flag values for getaddrinfo() */ #undef AI_PASSIVE #undef AI_CANONNAME #undef AI_NUMERICHOST #define AI_PASSIVE 0x00000001 #define AI_CANONNAME 0x00000002 #define AI_NUMERICHOST 0x00000004 /* * Flag values for getipnodebyname() */ #undef AI_V4MAPPED #undef AI_ALL #undef AI_ADDRCONFIG #undef AI_DEFAULT #define AI_V4MAPPED 0x00000008 #define AI_ALL 0x00000010 #define AI_ADDRCONFIG 0x00000020 #define AI_DEFAULT (AI_V4MAPPED|AI_ADDRCONFIG) /* * Constants for lwres_getnameinfo() */ #undef NI_MAXHOST #undef NI_MAXSERV #define NI_MAXHOST 1025 #define NI_MAXSERV 32 /* * Flag values for lwres_getnameinfo() */ #undef NI_NOFQDN #undef NI_NUMERICHOST #undef NI_NAMEREQD #undef NI_NUMERICSERV #undef NI_DGRAM #undef NI_NUMERICSCOPE #define NI_NOFQDN 0x00000001 #define NI_NUMERICHOST 0x00000002 #define NI_NAMEREQD 0x00000004 #define NI_NUMERICSERV 0x00000008 #define NI_DGRAM 0x00000010 #define NI_NUMERICSCOPE 0x00000020 /*2553bis-00*/ /* * Define if does not declare struct rrsetinfo. */ @ISC_LWRES_NEEDRRSETINFO@ #ifdef ISC_LWRES_NEEDRRSETINFO /* * Structures for getrrsetbyname() */ struct rdatainfo { unsigned int rdi_length; unsigned char *rdi_data; }; struct rrsetinfo { unsigned int rri_flags; int rri_rdclass; int rri_rdtype; unsigned int rri_ttl; unsigned int rri_nrdatas; unsigned int rri_nsigs; char *rri_name; struct rdatainfo *rri_rdatas; struct rdatainfo *rri_sigs; }; /* * Flags for getrrsetbyname() */ #define RRSET_VALIDATED 0x00000001 /* Set was dnssec validated */ /* * Return codes for getrrsetbyname() */ #define ERRSET_SUCCESS 0 #define ERRSET_NOMEMORY 1 #define ERRSET_FAIL 2 #define ERRSET_INVAL 3 #define ERRSET_NONAME 4 #define ERRSET_NODATA 5 #endif /* * Define to map into lwres_ namespace. */ #define LWRES_NAMESPACE #ifdef LWRES_NAMESPACE /* * Use our versions not the ones from the C library. */ #ifdef getnameinfo #undef getnameinfo #endif #define getnameinfo lwres_getnameinfo #ifdef getaddrinfo #undef getaddrinfo #endif #define getaddrinfo lwres_getaddrinfo #ifdef freeaddrinfo #undef freeaddrinfo #endif #define freeaddrinfo lwres_freeaddrinfo #ifdef gai_strerror #undef gai_strerror #endif #define gai_strerror lwres_gai_strerror #ifdef herror #undef herror #endif #define herror lwres_herror #ifdef hstrerror #undef hstrerror #endif #define hstrerror lwres_hstrerror #ifdef getipnodebyname #undef getipnodebyname #endif #define getipnodebyname lwres_getipnodebyname #ifdef getipnodebyaddr #undef getipnodebyaddr #endif #define getipnodebyaddr lwres_getipnodebyaddr #ifdef freehostent #undef freehostent #endif #define freehostent lwres_freehostent #ifdef gethostbyname #undef gethostbyname #endif #define gethostbyname lwres_gethostbyname #ifdef gethostbyname2 #undef gethostbyname2 #endif #define gethostbyname2 lwres_gethostbyname2 #ifdef gethostbyaddr #undef gethostbyaddr #endif #define gethostbyaddr lwres_gethostbyaddr #ifdef gethostent #undef gethostent #endif #define gethostent lwres_gethostent #ifdef sethostent #undef sethostent #endif #define sethostent lwres_sethostent #ifdef endhostent #undef endhostent #endif #define endhostent lwres_endhostent /* #define sethostfile lwres_sethostfile */ #ifdef gethostbyname_r #undef gethostbyname_r #endif #define gethostbyname_r lwres_gethostbyname_r #ifdef gethostbyaddr_r #undef gethostbyaddr_r #endif #define gethostbyaddr_r lwres_gethostbyaddr_r #ifdef gethostent_r #undef gethostent_r #endif #define gethostent_r lwres_gethostent_r #ifdef sethostent_r #undef sethostent_r #endif #define sethostent_r lwres_sethostent_r #ifdef endhostent_r #undef endhostent_r #endif #define endhostent_r lwres_endhostent_r #ifdef getrrsetbyname #undef getrrsetbyname #endif #define getrrsetbyname lwres_getrrsetbyname #ifdef freerrset #undef freerrset #endif #define freerrset lwres_freerrset #ifdef notyet #define getservbyname lwres_getservbyname #define getservbyport lwres_getservbyport #define getservent lwres_getservent #define setservent lwres_setservent #define endservent lwres_endservent #define getservbyname_r lwres_getservbyname_r #define getservbyport_r lwres_getservbyport_r #define getservent_r lwres_getservent_r #define setservent_r lwres_setservent_r #define endservent_r lwres_endservent_r #define getprotobyname lwres_getprotobyname #define getprotobynumber lwres_getprotobynumber #define getprotoent lwres_getprotoent #define setprotoent lwres_setprotoent #define endprotoent lwres_endprotoent #define getprotobyname_r lwres_getprotobyname_r #define getprotobynumber_r lwres_getprotobynumber_r #define getprotoent_r lwres_getprotoent_r #define setprotoent_r lwres_setprotoent_r #define endprotoent_r lwres_endprotoent_r #ifdef getnetbyname #undef getnetbyname #endif #define getnetbyname lwres_getnetbyname #ifdef getnetbyaddr #undef getnetbyaddr #endif #define getnetbyaddr lwres_getnetbyaddr #ifdef getnetent #undef getnetent #endif #define getnetent lwres_getnetent #ifdef setnetent #undef setnetent #endif #define setnetent lwres_setnetent #ifdef endnetent #undef endnetent #endif #define endnetent lwres_endnetent #ifdef getnetbyname_r #undef getnetbyname_r #endif #define getnetbyname_r lwres_getnetbyname_r #ifdef getnetbyaddr_r #undef getnetbyaddr_r #endif #define getnetbyaddr_r lwres_getnetbyaddr_r #ifdef getnetent_r #undef getnetent_r #endif #define getnetent_r lwres_getnetent_r #ifdef setnetent_r #undef setnetent_r #endif #define setnetent_r lwres_setnetent_r #ifdef endnetent_r #undef endnetent_r #endif #define endnetent_r lwres_endnetent_r #endif /* notyet */ #ifdef h_errno #undef h_errno #endif #define h_errno lwres_h_errno #endif /* LWRES_NAMESPACE */ LWRES_LANG_BEGINDECLS extern int lwres_h_errno; int lwres_getaddrinfo(const char *, const char *, const struct addrinfo *, struct addrinfo **); int lwres_getnameinfo(const struct sockaddr *, size_t, char *, size_t, char *, size_t, int); void lwres_freeaddrinfo(struct addrinfo *); char *lwres_gai_strerror(int); struct hostent *lwres_gethostbyaddr(const char *, int, int); struct hostent *lwres_gethostbyname(const char *); struct hostent *lwres_gethostbyname2(const char *, int); struct hostent *lwres_gethostent(void); struct hostent *lwres_getipnodebyname(const char *, int, int, int *); struct hostent *lwres_getipnodebyaddr(const void *, size_t, int, int *); void lwres_endhostent(void); void lwres_sethostent(int); /* void lwres_sethostfile(const char *); */ void lwres_freehostent(struct hostent *); int lwres_getrrsetbyname(const char *, unsigned int, unsigned int, unsigned int, struct rrsetinfo **); void lwres_freerrset(struct rrsetinfo *); #ifdef notyet struct netent *lwres_getnetbyaddr(unsigned long, int); struct netent *lwres_getnetbyname(const char *); struct netent *lwres_getnetent(void); void lwres_endnetent(void); void lwres_setnetent(int); struct protoent *lwres_getprotobyname(const char *); struct protoent *lwres_getprotobynumber(int); struct protoent *lwres_getprotoent(void); void lwres_endprotoent(void); void lwres_setprotoent(int); struct servent *lwres_getservbyname(const char *, const char *); struct servent *lwres_getservbyport(int, const char *); struct servent *lwres_getservent(void); void lwres_endservent(void); void lwres_setservent(int); #endif /* notyet */ void lwres_herror(const char *); const char *lwres_hstrerror(int); struct hostent *lwres_gethostbyaddr_r(const char *, int, int, struct hostent *, char *, int, int *); struct hostent *lwres_gethostbyname_r(const char *, struct hostent *, char *, int, int *); struct hostent *lwres_gethostent_r(struct hostent *, char *, int, int *); void lwres_sethostent_r(int); void lwres_endhostent_r(void); #ifdef notyet struct netent *lwres_getnetbyname_r(const char *, struct netent *, char *, int); struct netent *lwres_getnetbyaddr_r(long, int, struct netent *, char *, int); struct netent *lwres_getnetent_r(struct netent *, char *, int); void lwres_setnetent_r(int); void lwres_endnetent_r(void); struct protoent *lwres_getprotobyname_r(const char *, struct protoent *, char *, int); struct protoent *lwres_getprotobynumber_r(int, struct protoent *, char *, int); struct protoent *lwres_getprotoent_r(struct protoent *, char *, int); void lwres_setprotoent_r(int); void lwres_endprotoent_r(void); struct servent *lwres_getservbyname_r(const char *name, const char *, struct servent *, char *, int); struct servent *lwres_getservbyport_r(int port, const char *, struct servent *, char *, int); struct servent *lwres_getservent_r(struct servent *, char *, int); void lwres_setservent_r(int); void lwres_endservent_r(void); #endif /* notyet */ LWRES_LANG_ENDDECLS #ifdef notyet /* This is nec'y to make this include file properly replace the sun version. */ #ifdef sun #ifdef __GNU_LIBRARY__ #include /* Required. */ #else /* !__GNU_LIBRARY__ */ struct rpcent { char *r_name; /* name of server for this rpc program */ char **r_aliases; /* alias list */ int r_number; /* rpc program number */ }; struct rpcent *lwres_getrpcbyname(); struct rpcent *lwres_getrpcbynumber(), struct rpcent *lwres_getrpcent(); #endif /* __GNU_LIBRARY__ */ #endif /* sun */ #endif /* notyet */ /* * Tell Emacs to use C mode on this file. * Local variables: * mode: c * End: */ #endif /* LWRES_NETDB_H */ bind9-9.10.3.dfsg.P4/lib/lwres/include/lwres/list.h0000644000470500017500000000730412664710322021202 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1997-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: list.h,v 1.14 2007/06/19 23:47:23 tbox Exp $ */ #ifndef LWRES_LIST_H #define LWRES_LIST_H 1 /*! \file lwres/list.h */ #define LWRES_LIST(type) struct { type *head, *tail; } #define LWRES_LIST_INIT(list) \ do { (list).head = NULL; (list).tail = NULL; } while (0) #define LWRES_LINK(type) struct { type *prev, *next; } #define LWRES_LINK_INIT(elt, link) \ do { \ (elt)->link.prev = (void *)(-1); \ (elt)->link.next = (void *)(-1); \ } while (0) #define LWRES_LINK_LINKED(elt, link) \ ((void *)((elt)->link.prev) != (void *)(-1)) #define LWRES_LIST_HEAD(list) ((list).head) #define LWRES_LIST_TAIL(list) ((list).tail) #define LWRES_LIST_EMPTY(list) LWRES_TF((list).head == NULL) #define LWRES_LIST_PREPEND(list, elt, link) \ do { \ if ((list).head != NULL) \ (list).head->link.prev = (elt); \ else \ (list).tail = (elt); \ (elt)->link.prev = NULL; \ (elt)->link.next = (list).head; \ (list).head = (elt); \ } while (0) #define LWRES_LIST_APPEND(list, elt, link) \ do { \ if ((list).tail != NULL) \ (list).tail->link.next = (elt); \ else \ (list).head = (elt); \ (elt)->link.prev = (list).tail; \ (elt)->link.next = NULL; \ (list).tail = (elt); \ } while (0) #define LWRES_LIST_UNLINK(list, elt, link) \ do { \ if ((elt)->link.next != NULL) \ (elt)->link.next->link.prev = (elt)->link.prev; \ else \ (list).tail = (elt)->link.prev; \ if ((elt)->link.prev != NULL) \ (elt)->link.prev->link.next = (elt)->link.next; \ else \ (list).head = (elt)->link.next; \ (elt)->link.prev = (void *)(-1); \ (elt)->link.next = (void *)(-1); \ } while (0) #define LWRES_LIST_PREV(elt, link) ((elt)->link.prev) #define LWRES_LIST_NEXT(elt, link) ((elt)->link.next) #define LWRES_LIST_INSERTBEFORE(list, before, elt, link) \ do { \ if ((before)->link.prev == NULL) \ LWRES_LIST_PREPEND(list, elt, link); \ else { \ (elt)->link.prev = (before)->link.prev; \ (before)->link.prev = (elt); \ (elt)->link.prev->link.next = (elt); \ (elt)->link.next = (before); \ } \ } while (0) #define LWRES_LIST_INSERTAFTER(list, after, elt, link) \ do { \ if ((after)->link.next == NULL) \ LWRES_LIST_APPEND(list, elt, link); \ else { \ (elt)->link.next = (after)->link.next; \ (after)->link.next = (elt); \ (elt)->link.next->link.prev = (elt); \ (elt)->link.prev = (after); \ } \ } while (0) #define LWRES_LIST_APPENDLIST(list1, list2, link) \ do { \ if (LWRES_LIST_EMPTY(list1)) \ (list1) = (list2); \ else if (!LWRES_LIST_EMPTY(list2)) { \ (list1).tail->link.next = (list2).head; \ (list2).head->link.prev = (list1).tail; \ (list1).tail = (list2).tail; \ } \ (list2).head = NULL; \ (list2).tail = NULL; \ } while (0) #define LWRES_LIST_ENQUEUE(list, elt, link) LWRES_LIST_APPEND(list, elt, link) #define LWRES_LIST_DEQUEUE(list, elt, link) LWRES_LIST_UNLINK(list, elt, link) #endif /* LWRES_LIST_H */ bind9-9.10.3.dfsg.P4/lib/lwres/include/lwres/stdlib.h0000644000470500017500000000224512664710322021507 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef LWRES_STDLIB_H #define LWRES_STDLIB_H 1 /*! \file lwres/stdlib.h */ #include #include #include #ifdef LWRES_PLATFORM_NEEDSTRTOUL #define strtoul lwres_strtoul #endif LWRES_LANG_BEGINDECLS unsigned long lwres_strtoul(const char *, char **, int); LWRES_LANG_ENDDECLS #endif bind9-9.10.3.dfsg.P4/lib/lwres/getrrset.c0000644000470500017500000002150112664710322017275 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: getrrset.c,v 1.18 2007/06/19 23:47:22 tbox Exp $ */ /*! \file */ /** * DESCRIPTION * * lwres_getrrsetbyname() gets a set of resource records associated with * a hostname, class, and type. hostname is a pointer a to * null-terminated string. The flags field is currently unused and must * be zero. * * After a successful call to lwres_getrrsetbyname(), *res is a pointer * to an #rrsetinfo structure, containing a list of one or more #rdatainfo * structures containing resource records and potentially another list of * rdatainfo structures containing SIG resource records associated with * those records. The members #rri_rdclass and #rri_rdtype are copied from * the parameters. #rri_ttl and #rri_name are properties of the obtained * rrset. The resource records contained in #rri_rdatas and #rri_sigs are * in uncompressed DNS wire format. Properties of the rdataset are * represented in the #rri_flags bitfield. If the #RRSET_VALIDATED bit is * set, the data has been DNSSEC validated and the signatures verified. * * All of the information returned by lwres_getrrsetbyname() is * dynamically allocated: the rrsetinfo and rdatainfo structures, and the * canonical host name strings pointed to by the rrsetinfostructure. * Memory allocated for the dynamically allocated structures created by a * successful call to lwres_getrrsetbyname() is released by * lwres_freerrset(). rrset is a pointer to a struct rrset created by a * call to lwres_getrrsetbyname(). * * The following structures are used: * * \code * struct rdatainfo { * unsigned int rdi_length; // length of data * unsigned char *rdi_data; // record data * }; * * struct rrsetinfo { * unsigned int rri_flags; // RRSET_VALIDATED... * unsigned int rri_rdclass; // class number * unsigned int rri_rdtype; // RR type number * unsigned int rri_ttl; // time to live * unsigned int rri_nrdatas; // size of rdatas array * unsigned int rri_nsigs; // size of sigs array * char *rri_name; // canonical name * struct rdatainfo *rri_rdatas; // individual records * struct rdatainfo *rri_sigs; // individual signatures * }; * \endcode * * \section getrrset_return Return Values * * lwres_getrrsetbyname() returns zero on success, and one of the * following error codes if an error occurred: * * \li #ERRSET_NONAME: the name does not exist * * \li #ERRSET_NODATA: * the name exists, but does not have data of the desired type * * \li #ERRSET_NOMEMORY: * memory could not be allocated * * \li #ERRSET_INVAL: * a parameter is invalid * * \li #ERRSET_FAIL: * other failure */ #include #include #include #include #include #include #include /* XXX #include */ #include "assert_p.h" /*! * Structure to map results */ static unsigned int lwresult_to_result(lwres_result_t lwresult) { switch (lwresult) { case LWRES_R_SUCCESS: return (ERRSET_SUCCESS); case LWRES_R_NOMEMORY: return (ERRSET_NOMEMORY); case LWRES_R_NOTFOUND: return (ERRSET_NONAME); case LWRES_R_TYPENOTFOUND: return (ERRSET_NODATA); default: return (ERRSET_FAIL); } } /*@{*/ /*! * malloc / calloc functions that guarantee to only * return NULL if there is an error, like they used * to before the ANSI C committee broke them. */ static void * sane_malloc(size_t size) { if (size == 0U) size = 1; return (malloc(size)); } static void * sane_calloc(size_t number, size_t size) { size_t len = number * size; void *mem = sane_malloc(len); if (mem != NULL) memset(mem, 0, len); return (mem); } /*@}*/ /*% Returns a set of resource records associated with a hostname, class, and type. hostname is a pointer a to null-terminated string. */ int lwres_getrrsetbyname(const char *hostname, unsigned int rdclass, unsigned int rdtype, unsigned int flags, struct rrsetinfo **res) { lwres_context_t *lwrctx = NULL; lwres_result_t lwresult; lwres_grbnresponse_t *response = NULL; struct rrsetinfo *rrset = NULL; unsigned int i; unsigned int lwflags; unsigned int result; if (rdclass > 0xffff || rdtype > 0xffff) { result = ERRSET_INVAL; goto fail; } /* * Don't allow queries of class or type ANY */ if (rdclass == 0xff || rdtype == 0xff) { result = ERRSET_INVAL; goto fail; } lwresult = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0); if (lwresult != LWRES_R_SUCCESS) { result = lwresult_to_result(lwresult); goto fail; } (void) lwres_conf_parse(lwrctx, lwres_resolv_conf); /* * If any input flags were defined, lwflags would be set here * based on them */ UNUSED(flags); lwflags = 0; lwresult = lwres_getrdatabyname(lwrctx, hostname, (lwres_uint16_t)rdclass, (lwres_uint16_t)rdtype, lwflags, &response); if (lwresult != LWRES_R_SUCCESS) { result = lwresult_to_result(lwresult); goto fail; } rrset = sane_malloc(sizeof(struct rrsetinfo)); if (rrset == NULL) { result = ERRSET_NOMEMORY; goto fail; } rrset->rri_name = NULL; rrset->rri_rdclass = response->rdclass; rrset->rri_rdtype = response->rdtype; rrset->rri_ttl = response->ttl; rrset->rri_flags = 0; rrset->rri_nrdatas = 0; rrset->rri_rdatas = NULL; rrset->rri_nsigs = 0; rrset->rri_sigs = NULL; rrset->rri_name = sane_malloc(response->realnamelen + 1); if (rrset->rri_name == NULL) { result = ERRSET_NOMEMORY; goto fail; } strncpy(rrset->rri_name, response->realname, response->realnamelen); rrset->rri_name[response->realnamelen] = 0; if ((response->flags & LWRDATA_VALIDATED) != 0) rrset->rri_flags |= RRSET_VALIDATED; rrset->rri_nrdatas = response->nrdatas; rrset->rri_rdatas = sane_calloc(rrset->rri_nrdatas, sizeof(struct rdatainfo)); if (rrset->rri_rdatas == NULL) { result = ERRSET_NOMEMORY; goto fail; } for (i = 0; i < rrset->rri_nrdatas; i++) { rrset->rri_rdatas[i].rdi_length = response->rdatalen[i]; rrset->rri_rdatas[i].rdi_data = sane_malloc(rrset->rri_rdatas[i].rdi_length); if (rrset->rri_rdatas[i].rdi_data == NULL) { result = ERRSET_NOMEMORY; goto fail; } memmove(rrset->rri_rdatas[i].rdi_data, response->rdatas[i], rrset->rri_rdatas[i].rdi_length); } rrset->rri_nsigs = response->nsigs; rrset->rri_sigs = sane_calloc(rrset->rri_nsigs, sizeof(struct rdatainfo)); if (rrset->rri_sigs == NULL) { result = ERRSET_NOMEMORY; goto fail; } for (i = 0; i < rrset->rri_nsigs; i++) { rrset->rri_sigs[i].rdi_length = response->siglen[i]; rrset->rri_sigs[i].rdi_data = sane_malloc(rrset->rri_sigs[i].rdi_length); if (rrset->rri_sigs[i].rdi_data == NULL) { result = ERRSET_NOMEMORY; goto fail; } memmove(rrset->rri_sigs[i].rdi_data, response->sigs[i], rrset->rri_sigs[i].rdi_length); } lwres_grbnresponse_free(lwrctx, &response); lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); *res = rrset; return (ERRSET_SUCCESS); fail: if (rrset != NULL) lwres_freerrset(rrset); if (response != NULL) lwres_grbnresponse_free(lwrctx, &response); if (lwrctx != NULL) { lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); } return (result); } /*% Releases memory allocated for the dynamically allocated structures created by a successful call to lwres_getrrsetbyname(). */ void lwres_freerrset(struct rrsetinfo *rrset) { unsigned int i; if (rrset->rri_rdatas != NULL) { for (i = 0; i < rrset->rri_nrdatas; i++) { if (rrset->rri_rdatas[i].rdi_data == NULL) break; free(rrset->rri_rdatas[i].rdi_data); } free(rrset->rri_rdatas); } if (rrset->rri_sigs != NULL) { for (i = 0; i < rrset->rri_nsigs; i++) { if (rrset->rri_sigs[i].rdi_data == NULL) break; free(rrset->rri_sigs[i].rdi_data); } free(rrset->rri_sigs); } free(rrset->rri_name); free(rrset); } bind9-9.10.3.dfsg.P4/lib/lwres/unix/0002755000470500017500000000000012672612753016270 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/lwres/unix/Makefile.in0000644000470500017500000000175412664710322020332 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.4 2007/06/19 23:47:23 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = include TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/lwres/unix/include/0002755000470500017500000000000012664710322017703 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/lwres/unix/include/Makefile.in0000644000470500017500000000175212664710322021753 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.4 2007/06/19 23:47:23 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = lwres TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/lwres/unix/include/lwres/0002755000470500017500000000000012664710322021037 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/lwres/unix/include/lwres/Makefile.in0000644000470500017500000000230012664710322023075 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.4 2007/06/19 23:47:23 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ HEADERS = net.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/lwres install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/lwres ; \ done bind9-9.10.3.dfsg.P4/lib/lwres/unix/include/lwres/net.h0000644000470500017500000000703412664710322022000 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: net.h,v 1.9 2007/06/19 23:47:23 tbox Exp $ */ #ifndef LWRES_NET_H #define LWRES_NET_H 1 /***** ***** Module Info *****/ /*! \file net.h * This module is responsible for defining the following basic networking * types: * *\li struct in_addr *\li struct in6_addr *\li struct sockaddr *\li struct sockaddr_in *\li struct sockaddr_in6 * * It ensures that the AF_ and PF_ macros are defined. * * It declares ntoh[sl]() and hton[sl](). * * It declares lwres_net_aton(), lwres_net_ntop(), and lwres_net_pton(). * * It ensures that #INADDR_LOOPBACK, #INADDR_ANY and #IN6ADDR_ANY_INIT * are defined. */ /*** *** Imports. ***/ #include /* Required for LWRES_PLATFORM_*. */ #include #include #include /* Contractual promise. */ #include #include #include #include /* Contractual promise. */ #include /* Contractual promise. */ #ifdef LWRES_PLATFORM_NEEDNETINETIN6H #include /* Required on UnixWare. */ #endif #ifdef LWRES_PLATFORM_NEEDNETINET6IN6H #include /* Required on BSD/OS for in6_pktinfo. */ #endif #include #include #ifndef LWRES_PLATFORM_HAVEIPV6 #include /* Contractual promise. */ #endif #ifdef LWRES_PLATFORM_HAVEINADDR6 #define in6_addr in_addr6 /* Required for pre RFC2133 implementations. */ #endif /*! * Required for some pre RFC2133 implementations. * IN6ADDR_ANY_INIT and IN6ADDR_LOOPBACK_INIT were added in * draft-ietf-ipngwg-bsd-api-04.txt or draft-ietf-ipngwg-bsd-api-05.txt. * If 's6_addr' is defined then assume that there is a union and three * levels otherwise assume two levels required. */ #ifndef IN6ADDR_ANY_INIT #ifdef s6_addr #define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } } #else #define IN6ADDR_ANY_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } #endif #endif /*! * Initialize address loopback. See IN6ADDR_ANY_INIT */ #ifndef IN6ADDR_LOOPBACK_INIT #ifdef s6_addr #define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } } #else #define IN6ADDR_LOOPBACK_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } #endif #endif /*% Used by AI_ALL */ #ifndef AF_INET6 #define AF_INET6 99 #endif /*% Used to return IPV6 address types. */ #ifndef PF_INET6 #define PF_INET6 AF_INET6 #endif /*% inaddr Loopback */ #ifndef INADDR_LOOPBACK #define INADDR_LOOPBACK 0x7f000001UL #endif LWRES_LANG_BEGINDECLS const char * lwres_net_ntop(int af, const void *src, char *dst, size_t size); int lwres_net_pton(int af, const char *src, void *dst); int lwres_net_aton(const char *cp, struct in_addr *addr); LWRES_LANG_ENDDECLS #endif /* LWRES_NET_H */ bind9-9.10.3.dfsg.P4/lib/lwres/assert_p.h0000644000470500017500000000242112664710322017263 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef LWRES_ASSERT_P_H #define LWRES_ASSERT_P_H 1 /*! \file */ #include /* Required for assert() prototype. */ #define REQUIRE(x) assert(x) #define INSIST(x) assert(x) #define UNUSED(x) ((void)(x)) #define POST(x) ((void)(x)) #define SPACE_OK(b, s) (LWRES_BUFFER_AVAILABLECOUNT(b) >= (s)) #define SPACE_REMAINING(b, s) (LWRES_BUFFER_REMAINING(b) >= (s)) #endif /* LWRES_ASSERT_P_H */ bind9-9.10.3.dfsg.P4/lib/lwres/win32/0002755000470500017500000000000012664730167016250 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/lwres/win32/lwconfig.c0000644000470500017500000001116712664710322020217 0ustar lamontlamont/* * Copyright (C) 2004, 2006, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lwconfig.c,v 1.7 2007/12/14 01:40:42 marka Exp $ */ /* * We do this so that we may incorporate everything in the main routines * so that we can take advantage of the fixes and changes made there * without having to add them twice. We can then call the parse routine * if there is a resolv.conf file and fetch our own data from the * Windows environment otherwise. */ /* * Note that on Win32 there is normally no resolv.conf since all information * is stored in the registry. Therefore there is no ordering like the * contents of resolv.conf. Since the "search" or "domain" keyword, on * Win32 if a search list is found it is used, otherwise the domain name * is used since they are mutually exclusive. The search list can be entered * in the DNS tab of the "Advanced TCP/IP settings" window under the same place * that you add your nameserver list. */ #define lwres_conf_parse generic_lwres_conf_parse #include "../lwconfig.c" #undef lwres_conf_parse #include #define TCPIP_SUBKEY \ "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters" void get_win32_searchlist(lwres_context_t *ctx) { HKEY hKey; BOOL keyFound = TRUE; char searchlist[MAX_PATH]; DWORD searchlen = MAX_PATH; char *cp; lwres_conf_t *confdata; REQUIRE(ctx != NULL); confdata = &ctx->confdata; memset(searchlist, 0, MAX_PATH); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TCPIP_SUBKEY, 0, KEY_READ, &hKey) != ERROR_SUCCESS) keyFound = FALSE; if (keyFound == TRUE) { /* Get the named directory */ if (RegQueryValueEx(hKey, "SearchList", NULL, NULL, (LPBYTE)searchlist, &searchlen) != ERROR_SUCCESS) keyFound = FALSE; RegCloseKey(hKey); } confdata->searchnxt = 0; if (!keyFound) return; cp = strtok((char *)searchlist, ", \0"); while (cp != NULL) { if (confdata->searchnxt == LWRES_CONFMAXSEARCH) break; if (strlen(cp) <= MAX_PATH && strlen(cp) > 0) { confdata->search[confdata->searchnxt] = lwres_strdup(ctx, cp); if (confdata->search[confdata->searchnxt] != NULL) confdata->searchnxt++; } cp = strtok(NULL, ", \0"); } } lwres_result_t lwres_conf_parse(lwres_context_t *ctx, const char *filename) { lwres_result_t ret; lwres_conf_t *confdata; FIXED_INFO * FixedInfo; ULONG BufLen = sizeof(FIXED_INFO); DWORD dwRetVal; IP_ADDR_STRING *pIPAddr; REQUIRE(ctx != NULL); confdata = &ctx->confdata; REQUIRE(confdata != NULL); /* Use the resolver if there is one */ ret = generic_lwres_conf_parse(ctx, filename); if ((ret != LWRES_R_NOTFOUND && ret != LWRES_R_SUCCESS) || (ret == LWRES_R_SUCCESS && confdata->nsnext > 0)) return (ret); /* * We didn't get any nameservers so we need to do this ourselves */ FixedInfo = (FIXED_INFO *) GlobalAlloc(GPTR, BufLen); dwRetVal = GetNetworkParams(FixedInfo, &BufLen); if (dwRetVal == ERROR_BUFFER_OVERFLOW) { GlobalFree(FixedInfo); FixedInfo = GlobalAlloc(GPTR, BufLen); dwRetVal = GetNetworkParams(FixedInfo, &BufLen); } if (dwRetVal != ERROR_SUCCESS) { GlobalFree(FixedInfo); return (LWRES_R_FAILURE); } /* Get the search list from the registry */ get_win32_searchlist(ctx); /* Use only if there is no search list */ if (confdata->searchnxt == 0 && strlen(FixedInfo->DomainName) > 0) { confdata->domainname = lwres_strdup(ctx, FixedInfo->DomainName); if (confdata->domainname == NULL) { GlobalFree(FixedInfo); return (LWRES_R_FAILURE); } } else confdata->domainname = NULL; /* Get the list of nameservers */ pIPAddr = &FixedInfo->DnsServerList; while (pIPAddr) { if (confdata->nsnext >= LWRES_CONFMAXNAMESERVERS) break; ret = lwres_create_addr(pIPAddr->IpAddress.String, &confdata->nameservers[confdata->nsnext++], 1); if (ret != LWRES_R_SUCCESS) { GlobalFree(FixedInfo); return (ret); } pIPAddr = pIPAddr ->Next; } GlobalFree(FixedInfo); return (LWRES_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/lwres/win32/version.c0000644000470500017500000000233512664710322020071 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: version.c,v 1.6 2007/06/19 23:47:23 tbox Exp $ */ #include #include LIBLWRES_EXTERNAL_DATA const char lwres_version[] = VERSION; LIBLWRES_EXTERNAL_DATA const unsigned int lwres_libinterface = LIBINTERFACE; LIBLWRES_EXTERNAL_DATA const unsigned int lwres_librevision = LIBREVISION; LIBLWRES_EXTERNAL_DATA const unsigned int lwres_libage = LIBAGE; bind9-9.10.3.dfsg.P4/lib/lwres/win32/socket.c0000644000470500017500000000234012664710322017670 0ustar lamontlamont/* * Copyright (C) 2007, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: socket.c,v 1.3 2007/06/18 23:47:51 tbox Exp $ */ #include #include #include #include void InitSockets(void) { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(2, 0); err = WSAStartup( wVersionRequested, &wsaData ); if (err != 0) { fprintf(stderr, "WSAStartup() failed: %d\n", err); exit(1); } } void DestroySockets(void) { WSACleanup(); } bind9-9.10.3.dfsg.P4/lib/lwres/win32/Makefile.in0000644000470500017500000000175412664710322020311 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.4 2007/06/19 23:47:23 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = include TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/lwres/win32/liblwres.dsp.in0000644000470500017500000001557212664710322021207 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="liblwres" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Dynamic-Link Library" 0x0102 CFG=liblwres - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "liblwres.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "liblwres.mak" CFG="liblwres - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "liblwres - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE "liblwres - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "liblwres_EXPORTS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../lib/lwres/win32/include/lwres" /I "include" /I "../include" /I "../../../" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isc/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ /D "LIBLWRES_EXPORTS" @COPTY@ /FD /c # SUBTRACT CPP /X # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll @MACHINE@ # ADD LINK32 user32.lib advapi32.lib ws2_32.lib iphlpapi.lib /nologo /dll @MACHINE@ /out:"../../../Build/Release/liblwres.dll" !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "liblwres_EXPORTS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../lib/lwres/win32/include/lwres" /I "include" /I "../include" /I "../../../" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isc/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ /D "LIBLWRES_EXPORTS" /FR @COPTY@ /FD /GZ /c # SUBTRACT CPP /X # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib ws2_32.lib iphlpapi.lib /nologo /dll /debug @MACHINE@ /out:"../../../Build/Debug/liblwres.dll" /pdbtype:sept !ENDIF # Begin Target # Name "liblwres - @PLATFORM@ Release" # Name "liblwres - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\compat.c # End Source File # Begin Source File SOURCE=..\context.c # End Source File # Begin Source File SOURCE=.\DLLMain.c # End Source File # Begin Source File SOURCE=..\gai_strerror.c # End Source File # Begin Source File SOURCE=..\getaddrinfo.c # End Source File # Begin Source File SOURCE=..\gethost.c # End Source File # Begin Source File SOURCE=..\getipnode.c # End Source File # Begin Source File SOURCE=..\getnameinfo.c # End Source File # Begin Source File SOURCE=..\getrrset.c # End Source File # Begin Source File SOURCE=..\herror.c # End Source File # Begin Source File SOURCE=..\lwbuffer.c # End Source File # Begin Source File SOURCE=.\lwconfig.c # End Source File # Begin Source File SOURCE=..\lwinetaton.c # End Source File # Begin Source File SOURCE=..\lwinetntop.c # End Source File # Begin Source File SOURCE=..\lwinetpton.c # End Source File # Begin Source File SOURCE=..\lwpacket.c # End Source File # Begin Source File SOURCE=..\lwres_gabn.c # End Source File # Begin Source File SOURCE=..\lwres_gnba.c # End Source File # Begin Source File SOURCE=..\lwres_grbn.c # End Source File # Begin Source File SOURCE=..\lwres_noop.c # End Source File # Begin Source File SOURCE=..\lwresutil.c # End Source File # Begin Source File SOURCE=.\socket.c # End Source File # Begin Source File SOURCE=.\version.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=..\include\lwres\context.h # End Source File # Begin Source File SOURCE=.\include\lwres\int.h # End Source File # Begin Source File SOURCE=..\include\lwres\ipv6.h # End Source File # Begin Source File SOURCE=..\include\lwres\lang.h # End Source File # Begin Source File SOURCE=..\include\lwres\list.h # End Source File # Begin Source File SOURCE=..\include\lwres\lwbuffer.h # End Source File # Begin Source File SOURCE=..\include\lwres\lwpacket.h # End Source File # Begin Source File SOURCE=..\include\lwres\lwres.h # End Source File # Begin Source File SOURCE=.\include\lwres\net.h # End Source File # Begin Source File SOURCE=.\include\lwres\netdb.h # End Source File # Begin Source File SOURCE=.\include\lwres\platform.h # End Source File # Begin Source File SOURCE=..\include\lwres\result.h # End Source File # Begin Source File SOURCE=..\include\lwres\stdlib.h # End Source File # Begin Source File SOURCE=..\include\lwres\string.h # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # Begin Source File SOURCE=.\liblwres.def # End Source File # End Target # End Project bind9-9.10.3.dfsg.P4/lib/lwres/win32/liblwres.dsw0000644000470500017500000000103512664710322020576 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "liblwres"=".\liblwres.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/lib/lwres/win32/DLLMain.c0000644000470500017500000000313512664710322017623 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: DLLMain.c,v 1.5 2007/06/18 23:47:51 tbox Exp $ */ #include #include /* * Called when we enter the DLL */ __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { /* * The DLL is loading due to process * initialization or a call to LoadLibrary. */ case DLL_PROCESS_ATTACH: break; /* The attached process creates a new thread. */ case DLL_THREAD_ATTACH: break; /* The thread of the attached process terminates. */ case DLL_THREAD_DETACH: break; /* * The DLL is unloading from a process due to * process termination or a call to FreeLibrary. */ case DLL_PROCESS_DETACH: break; default: break; } return (TRUE); } bind9-9.10.3.dfsg.P4/lib/lwres/win32/liblwres.vcxproj.user0000644000470500017500000000021712664710322022452 0ustar lamontlamont bind9-9.10.3.dfsg.P4/lib/lwres/win32/include/0002755000470500017500000000000012672612753017672 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/lwres/win32/include/Makefile.in0000644000470500017500000000175212664710322021732 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.4 2007/06/19 23:47:23 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = lwres TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/lwres/win32/include/lwres/0002755000470500017500000000000012664730166021026 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/lwres/win32/include/lwres/int.h0000644000470500017500000000236412664710322021764 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: int.h,v 1.4 2007/06/19 23:47:23 tbox Exp $ */ #ifndef LWRES_INT_H #define LWRES_INT_H 1 typedef char lwres_int8_t; typedef unsigned char lwres_uint8_t; typedef short lwres_int16_t; typedef unsigned short lwres_uint16_t; typedef int lwres_int32_t; typedef unsigned int lwres_uint32_t; typedef __int64 lwres_int64_t; typedef unsigned __int64 lwres_uint64_t; #endif /* LWRES_INT_H */ bind9-9.10.3.dfsg.P4/lib/lwres/win32/include/lwres/Makefile.in0000644000470500017500000000230012664710322023054 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.4 2007/06/19 23:47:23 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ HEADERS = net.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/lwres install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/lwres ; \ done bind9-9.10.3.dfsg.P4/lib/lwres/win32/include/lwres/net.h0000644000470500017500000001361112664710322021755 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: net.h,v 1.6 2007/06/19 23:47:23 tbox Exp $ */ #ifndef LWRES_NET_H #define LWRES_NET_H 1 /***** ***** Module Info *****/ /* * Basic Networking Types * * This module is responsible for defining the following basic networking * types: * * struct in_addr * struct in6_addr * struct sockaddr * struct sockaddr_in * struct sockaddr_in6 * * It ensures that the AF_ and PF_ macros are defined. * * It declares ntoh[sl]() and hton[sl](). * * It declares lwres_net_aton(), lwres_net_ntop(), and lwres_net_pton(). * * It ensures that INADDR_LOOPBACK, INADDR_ANY and IN6ADDR_ANY_INIT * are defined. */ /*** *** Imports. ***/ /* * Because of some sort of problem in the MS header files, this cannot * be simple "#include ", because winsock2.h tries to include * windows.h, which then generates an error out of mswsock.h. _You_ * figure it out. */ #ifndef _WINSOCKAPI_ #define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */ #endif #include #include #include #include /* Required for LWRES_PLATFORM_*. */ #include #ifndef INADDR_LOOPBACK #define INADDR_LOOPBACK 0x7f000001UL #endif /* * Fix the FD_SET and FD_CLR Macros to properly cast */ #undef FD_CLR #define FD_CLR(fd, set) do { \ u_int __i; \ for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { \ if (((fd_set FAR *)(set))->fd_array[__i] == (SOCKET) fd) { \ while (__i < ((fd_set FAR *)(set))->fd_count-1) { \ ((fd_set FAR *)(set))->fd_array[__i] = \ ((fd_set FAR *)(set))->fd_array[__i+1]; \ __i++; \ } \ ((fd_set FAR *)(set))->fd_count--; \ break; \ } \ } \ } while (0) #undef FD_SET #define FD_SET(fd, set) do { \ u_int __i; \ for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { \ if (((fd_set FAR *)(set))->fd_array[__i] == (SOCKET)(fd)) { \ break; \ } \ } \ if (__i == ((fd_set FAR *)(set))->fd_count) { \ if (((fd_set FAR *)(set))->fd_count < FD_SETSIZE) { \ ((fd_set FAR *)(set))->fd_array[__i] = (SOCKET)(fd); \ ((fd_set FAR *)(set))->fd_count++; \ } \ } \ } while (0) /* * Windows Sockets errors redefined as regular Berkeley error constants. * These are usually commented out in Windows NT to avoid conflicts with errno.h. * Use the WSA constants instead. */ #include #ifndef EWOULDBLOCK #define EWOULDBLOCK WSAEWOULDBLOCK #endif #ifndef EINPROGRESS #define EINPROGRESS WSAEINPROGRESS #endif #ifndef EALREADY #define EALREADY WSAEALREADY #endif #ifndef ENOTSOCK #define ENOTSOCK WSAENOTSOCK #endif #ifndef EDESTADDRREQ #define EDESTADDRREQ WSAEDESTADDRREQ #endif #ifndef EMSGSIZE #define EMSGSIZE WSAEMSGSIZE #endif #ifndef EPROTOTYPE #define EPROTOTYPE WSAEPROTOTYPE #endif #ifndef ENOPROTOOPT #define ENOPROTOOPT WSAENOPROTOOPT #endif #ifndef EPROTONOSUPPORT #define EPROTONOSUPPORT WSAEPROTONOSUPPORT #endif #ifndef ESOCKTNOSUPPORT #define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT #endif #ifndef EOPNOTSUPP #define EOPNOTSUPP WSAEOPNOTSUPP #endif #ifndef EPFNOSUPPORT #define EPFNOSUPPORT WSAEPFNOSUPPORT #endif #ifndef EAFNOSUPPORT #define EAFNOSUPPORT WSAEAFNOSUPPORT #endif #ifndef EADDRINUSE #define EADDRINUSE WSAEADDRINUSE #endif #ifndef EADDRNOTAVAIL #define EADDRNOTAVAIL WSAEADDRNOTAVAIL #endif #ifndef ENETDOWN #define ENETDOWN WSAENETDOWN #endif #ifndef ENETUNREACH #define ENETUNREACH WSAENETUNREACH #endif #ifndef ENETRESET #define ENETRESET WSAENETRESET #endif #ifndef ECONNABORTED #define ECONNABORTED WSAECONNABORTED #endif #ifndef ECONNRESET #define ECONNRESET WSAECONNRESET #endif #ifndef ENOBUFS #define ENOBUFS WSAENOBUFS #endif #ifndef EISCONN #define EISCONN WSAEISCONN #endif #ifndef ENOTCONN #define ENOTCONN WSAENOTCONN #endif #ifndef ESHUTDOWN #define ESHUTDOWN WSAESHUTDOWN #endif #ifndef ETOOMANYREFS #define ETOOMANYREFS WSAETOOMANYREFS #endif #ifndef ETIMEDOUT #define ETIMEDOUT WSAETIMEDOUT #endif #ifndef ECONNREFUSED #define ECONNREFUSED WSAECONNREFUSED #endif #ifndef ELOOP #define ELOOP WSAELOOP #endif #ifndef EHOSTDOWN #define EHOSTDOWN WSAEHOSTDOWN #endif #ifndef EHOSTUNREACH #define EHOSTUNREACH WSAEHOSTUNREACH #endif #ifndef EPROCLIM #define EPROCLIM WSAEPROCLIM #endif #ifndef EUSERS #define EUSERS WSAEUSERS #endif #ifndef EDQUOT #define EDQUOT WSAEDQUOT #endif #ifndef ESTALE #define ESTALE WSAESTALE #endif #ifndef EREMOTE #define EREMOTE WSAEREMOTE #endif LWRES_LANG_BEGINDECLS const char * lwres_net_ntop(int af, const void *src, char *dst, size_t size); int lwres_net_pton(int af, const char *src, void *dst); int lwres_net_aton(const char *cp, struct in_addr *addr); LWRES_LANG_ENDDECLS #endif /* LWRES_NET_H */ bind9-9.10.3.dfsg.P4/lib/lwres/win32/include/lwres/platform.h0000644000470500017500000000514512664710322023016 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: platform.h,v 1.7 2007/06/18 23:47:52 tbox Exp $ */ #ifndef LWRES_PLATFORM_H #define LWRES_PLATFORM_H 1 /***** ***** Platform-dependent defines. *****/ /*** *** Network. ***/ /* * Define if this system needs the header file for IPv6. */ /*@LWRES_PLATFORM_NEEDNETINETIN6H@ */ /* * Define if this system needs the header file for IPv6. */ /*@LWRES_PLATFORM_NEEDNETINET6IN6H@ */ /* * If sockaddrs on this system have an sa_len field, LWRES_PLATFORM_HAVESALEN * will be defined. */ /*@LWRES_PLATFORM_HAVESALEN@ */ /* * If this system has the IPv6 structure definitions, LWRES_PLATFORM_HAVEIPV6 * will be defined. */ /*@LWRES_PLATFORM_HAVEIPV6@ */ /* * If this system is missing in6addr_any, LWRES_PLATFORM_NEEDIN6ADDRANY will * be defined. */ #define LWRES_PLATFORM_NEEDIN6ADDRANY /* * If this system has in_addr6, rather than in6_addr, * LWRES_PLATFORM_HAVEINADDR6 will be defined. */ /*@LWRES_PLATFORM_HAVEINADDR6@ */ /* * Defined if unistd.h does not cause fd_set to be delared. */ /*@LWRES_PLATFORM_NEEDSYSSELECTH@ */ /* VS2005 does not provide strlcpy() */ #define LWRES_PLATFORM_NEEDSTRLCPY /* * Define some Macros */ #ifdef LIBLWRES_EXPORTS #define LIBLWRES_EXTERNAL_DATA __declspec(dllexport) #else #define LIBLWRES_EXTERNAL_DATA __declspec(dllimport) #endif /* * Define the MAKE_NONBLOCKING Macro here since it can get used in * a number of places. */ #define MAKE_NONBLOCKING(sd, retval) \ do { \ int _on = 1; \ retval = ioctlsocket((SOCKET) sd, FIONBIO, &_on); \ } while (0) /* * Need to define close here since lwres closes sockets and not files */ #undef close #define close closesocket /* * Internal to liblwres. */ void InitSockets(void); void DestroySockets(void); #endif /* LWRES_PLATFORM_H */ bind9-9.10.3.dfsg.P4/lib/lwres/win32/include/lwres/netdb.h0000644000470500017500000003115712664710322022270 0ustar lamontlamont/* * Copyright (C) 2004, 2006, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: netdb.h,v 1.7 2007/06/19 23:47:23 tbox Exp $ */ #ifndef LWRES_NETDB_H #define LWRES_NETDB_H 1 #include /* Required on FreeBSD (and others?) for size_t. */ #define off_t _off_t #include #include #include /* * Define if does not declare struct addrinfo. */ #if _MSC_VER < 1600 #define ISC_LWRES_NEEDADDRINFO 1 #endif #ifdef ISC_LWRES_NEEDADDRINFO struct addrinfo { int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ int ai_family; /* PF_xxx */ int ai_socktype; /* SOCK_xxx */ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ size_t ai_addrlen; /* Length of ai_addr */ char *ai_canonname; /* Canonical name for hostname */ struct sockaddr *ai_addr; /* Binary address */ struct addrinfo *ai_next; /* Next structure in linked list */ }; #endif /* * Undefine all \#defines we are interested in as may or may not have * defined them. */ /* * Error return codes from gethostbyname() and gethostbyaddr() * (left in extern int h_errno). */ #undef NETDB_INTERNAL #undef NETDB_SUCCESS #undef HOST_NOT_FOUND #undef TRY_AGAIN #undef NO_RECOVERY #undef NO_DATA #undef NO_ADDRESS #define NETDB_INTERNAL -1 /* see errno */ #define NETDB_SUCCESS 0 /* no problem */ #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */ #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL */ #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ #define NO_DATA 4 /* Valid name, no data record of requested type */ #define NO_ADDRESS NO_DATA /* no address, look for MX record */ /* * Error return codes from getaddrinfo() */ #undef EAI_ADDRFAMILY #undef EAI_AGAIN #undef EAI_BADFLAGS #undef EAI_FAIL #undef EAI_FAMILY #undef EAI_MEMORY #undef EAI_NODATA #undef EAI_NONAME #undef EAI_SERVICE #undef EAI_SOCKTYPE #undef EAI_SYSTEM #undef EAI_BADHINTS #undef EAI_PROTOCOL #undef EAI_MAX #define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ #define EAI_AGAIN 2 /* temporary failure in name resolution */ #define EAI_BADFLAGS 3 /* invalid value for ai_flags */ #define EAI_FAIL 4 /* non-recoverable failure in name resolution */ #define EAI_FAMILY 5 /* ai_family not supported */ #define EAI_MEMORY 6 /* memory allocation failure */ #define EAI_NODATA 7 /* no address associated with hostname */ #define EAI_NONAME 8 /* hostname nor servname provided, or not known */ #define EAI_SERVICE 9 /* servname not supported for ai_socktype */ #define EAI_SOCKTYPE 10 /* ai_socktype not supported */ #define EAI_SYSTEM 11 /* system error returned in errno */ #define EAI_BADHINTS 12 #define EAI_PROTOCOL 13 #define EAI_MAX 14 /* * Flag values for getaddrinfo() */ #undef AI_PASSIVE #undef AI_CANONNAME #undef AI_NUMERICHOST #define AI_PASSIVE 0x00000001 #define AI_CANONNAME 0x00000002 #define AI_NUMERICHOST 0x00000004 /* * Flag values for getipnodebyname() */ #undef AI_V4MAPPED #undef AI_ALL #undef AI_ADDRCONFIG #undef AI_DEFAULT #define AI_V4MAPPED 0x00000008 #define AI_ALL 0x00000010 #define AI_ADDRCONFIG 0x00000020 #define AI_DEFAULT (AI_V4MAPPED|AI_ADDRCONFIG) /* * Constants for lwres_getnameinfo() */ #undef NI_MAXHOST #undef NI_MAXSERV #define NI_MAXHOST 1025 #define NI_MAXSERV 32 /* * Flag values for lwres_getnameinfo() */ #undef NI_NOFQDN #undef NI_NUMERICHOST #undef NI_NAMEREQD #undef NI_NUMERICSERV #undef NI_DGRAM #undef NI_NUMERICSCOPE #define NI_NOFQDN 0x00000001 #define NI_NUMERICHOST 0x00000002 #define NI_NAMEREQD 0x00000004 #define NI_NUMERICSERV 0x00000008 #define NI_DGRAM 0x00000010 #define NI_NUMERICSCOPE 0x00000020 /*2553bis-00*/ /* * Structures for getrrsetbyname() */ struct rdatainfo { unsigned int rdi_length; unsigned char *rdi_data; }; struct rrsetinfo { unsigned int rri_flags; int rri_rdclass; int rri_rdtype; unsigned int rri_ttl; unsigned int rri_nrdatas; unsigned int rri_nsigs; char *rri_name; struct rdatainfo *rri_rdatas; struct rdatainfo *rri_sigs; }; /* * Flags for getrrsetbyname() */ #define RRSET_VALIDATED 0x00000001 /* Set was dnssec validated */ /* * Return codes for getrrsetbyname() */ #define ERRSET_SUCCESS 0 #define ERRSET_NOMEMORY 1 #define ERRSET_FAIL 2 #define ERRSET_INVAL 3 #define ERRSET_NONAME 4 #define ERRSET_NODATA 5 /* * Define to map into lwres_ namespace. */ #define LWRES_NAMESPACE #ifdef LWRES_NAMESPACE /* * Use our versions not the ones from the C library. */ #ifdef getnameinfo #undef getnameinfo #endif #define getnameinfo lwres_getnameinfo #ifdef getaddrinfo #undef getaddrinfo #endif #define getaddrinfo lwres_getaddrinfo #ifdef freeaddrinfo #undef freeaddrinfo #endif #define freeaddrinfo lwres_freeaddrinfo #ifdef gai_strerror #undef gai_strerror #endif #define gai_strerror lwres_gai_strerror #ifdef herror #undef herror #endif #define herror lwres_herror #ifdef hstrerror #undef hstrerror #endif #define hstrerror lwres_hstrerror #ifdef getipnodebyname #undef getipnodebyname #endif #define getipnodebyname lwres_getipnodebyname #ifdef getipnodebyaddr #undef getipnodebyaddr #endif #define getipnodebyaddr lwres_getipnodebyaddr #ifdef freehostent #undef freehostent #endif #define freehostent lwres_freehostent #ifdef gethostbyname #undef gethostbyname #endif #define gethostbyname lwres_gethostbyname #ifdef gethostbyname2 #undef gethostbyname2 #endif #define gethostbyname2 lwres_gethostbyname2 #ifdef gethostbyaddr #undef gethostbyaddr #endif #define gethostbyaddr lwres_gethostbyaddr #ifdef gethostent #undef gethostent #endif #define gethostent lwres_gethostent #ifdef sethostent #undef sethostent #endif #define sethostent lwres_sethostent #ifdef endhostent #undef endhostent #endif #define endhostent lwres_endhostent /* #define sethostfile lwres_sethostfile */ #ifdef gethostbyname_r #undef gethostbyname_r #endif #define gethostbyname_r lwres_gethostbyname_r #ifdef gethostbyaddr_r #undef gethostbyaddr_r #endif #define gethostbyaddr_r lwres_gethostbyaddr_r #ifdef gethostent_r #undef gethostent_r #endif #define gethostent_r lwres_gethostent_r #ifdef sethostent_r #undef sethostent_r #endif #define sethostent_r lwres_sethostent_r #ifdef endhostent_r #undef endhostent_r #endif #define endhostent_r lwres_endhostent_r #ifdef getrrsetbyname #undef getrrsetbyname #endif #define getrrsetbyname lwres_getrrsetbyname #ifdef freerrset #undef freerrset #endif #define freerrset lwres_freerrset #ifdef notyet #define getservbyname lwres_getservbyname #define getservbyport lwres_getservbyport #define getservent lwres_getservent #define setservent lwres_setservent #define endservent lwres_endservent #define getservbyname_r lwres_getservbyname_r #define getservbyport_r lwres_getservbyport_r #define getservent_r lwres_getservent_r #define setservent_r lwres_setservent_r #define endservent_r lwres_endservent_r #define getprotobyname lwres_getprotobyname #define getprotobynumber lwres_getprotobynumber #define getprotoent lwres_getprotoent #define setprotoent lwres_setprotoent #define endprotoent lwres_endprotoent #define getprotobyname_r lwres_getprotobyname_r #define getprotobynumber_r lwres_getprotobynumber_r #define getprotoent_r lwres_getprotoent_r #define setprotoent_r lwres_setprotoent_r #define endprotoent_r lwres_endprotoent_r #ifdef getnetbyname #undef getnetbyname #endif #define getnetbyname lwres_getnetbyname #ifdef getnetbyaddr #undef getnetbyaddr #endif #define getnetbyaddr lwres_getnetbyaddr #ifdef getnetent #undef getnetent #endif #define getnetent lwres_getnetent #ifdef setnetent #undef setnetent #endif #define setnetent lwres_setnetent #ifdef endnetent #undef endnetent #endif #define endnetent lwres_endnetent #ifdef getnetbyname_r #undef getnetbyname_r #endif #define getnetbyname_r lwres_getnetbyname_r #ifdef getnetbyaddr_r #undef getnetbyaddr_r #endif #define getnetbyaddr_r lwres_getnetbyaddr_r #ifdef getnetent_r #undef getnetent_r #endif #define getnetent_r lwres_getnetent_r #ifdef setnetent_r #undef setnetent_r #endif #define setnetent_r lwres_setnetent_r #ifdef endnetent_r #undef endnetent_r #endif #define endnetent_r lwres_endnetent_r #endif /* notyet */ #ifdef h_errno #undef h_errno #endif #define h_errno lwres_h_errno #endif /* LWRES_NAMESPACE */ LWRES_LANG_BEGINDECLS LIBLWRES_EXTERNAL_DATA extern int lwres_h_errno; int lwres_getaddrinfo(const char *, const char *, const struct addrinfo *, struct addrinfo **); int lwres_getnameinfo(const struct sockaddr *, size_t, char *, size_t, char *, size_t, int); void lwres_freeaddrinfo(struct addrinfo *); char *lwres_gai_strerror(int); struct hostent *lwres_gethostbyaddr(const char *, int, int); struct hostent *lwres_gethostbyname(const char *); struct hostent *lwres_gethostbyname2(const char *, int); struct hostent *lwres_gethostent(void); struct hostent *lwres_getipnodebyname(const char *, int, int, int *); struct hostent *lwres_getipnodebyaddr(const void *, size_t, int, int *); void lwres_endhostent(void); void lwres_sethostent(int); /* void lwres_sethostfile(const char *); */ void lwres_freehostent(struct hostent *); int lwres_getrrsetbyname(const char *, unsigned int, unsigned int, unsigned int, struct rrsetinfo **); void lwres_freerrset(struct rrsetinfo *); #ifdef notyet struct netent *lwres_getnetbyaddr(unsigned long, int); struct netent *lwres_getnetbyname(const char *); struct netent *lwres_getnetent(void); void lwres_endnetent(void); void lwres_setnetent(int); struct protoent *lwres_getprotobyname(const char *); struct protoent *lwres_getprotobynumber(int); struct protoent *lwres_getprotoent(void); void lwres_endprotoent(void); void lwres_setprotoent(int); struct servent *lwres_getservbyname(const char *, const char *); struct servent *lwres_getservbyport(int, const char *); struct servent *lwres_getservent(void); void lwres_endservent(void); void lwres_setservent(int); #endif /* notyet */ void lwres_herror(const char *); const char *lwres_hstrerror(int); #ifdef _REENTRANT struct hostent *lwres_gethostbyaddr_r(const char *, int, int, struct hostent *, char *, int, int *); struct hostent *lwres_gethostbyname_r(const char *, struct hostent *, char *, int, int *); struct hostent *lwres_gethostent_r(struct hostent *, char *, int, int *); void lwres_sethostent_r(int); void lwres_endhostent_r(void); #ifdef notyet struct netent *lwres_getnetbyname_r(const char *, struct netent *, char *, int); struct netent *lwres_getnetbyaddr_r(long, int, struct netent *, char *, int); struct netent *lwres_getnetent_r(struct netent *, char *, int); void lwres_setnetent_r(int); void lwres_endnetent_r(void); struct protoent *lwres_getprotobyname_r(const char *, struct protoent *, char *, int); struct protoent *lwres_getprotobynumber_r(int, struct protoent *, char *, int); struct protoent *lwres_getprotoent_r(struct protoent *, char *, int); void lwres_setprotoent_r(int); void lwres_endprotoent_r(void); struct servent *lwres_getservbyname_r(const char *name, const char *, struct servent *, char *, int); struct servent *lwres_getservbyport_r(int port, const char *, struct servent *, char *, int); struct servent *lwres_getservent_r(struct servent *, char *, int); void lwres_setservent_r(int); void lwres_endservent_r(void); #endif /* notyet */ #endif /* _REENTRANT */ LWRES_LANG_ENDDECLS #ifdef notyet /* This is nec'y to make this include file properly replace the sun version. */ #ifdef sun #ifdef __GNU_LIBRARY__ #include /* Required. */ #else /* !__GNU_LIBRARY__ */ struct rpcent { char *r_name; /* name of server for this rpc program */ char **r_aliases; /* alias list */ int r_number; /* rpc program number */ }; struct rpcent *lwres_getrpcbyname(); struct rpcent *lwres_getrpcbynumber(), struct rpcent *lwres_getrpcent(); #endif /* __GNU_LIBRARY__ */ #endif /* sun */ #endif /* notyet */ /* * Tell Emacs to use C mode on this file. * Local variables: * mode: c * End: */ #endif /* LWRES_NETDB_H */ bind9-9.10.3.dfsg.P4/lib/lwres/win32/liblwres.vcxproj.in0000644000470500017500000002015612664710322022106 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {EBDB30A3-E8EB-4E1D-915E-06720600A84E} Win32Proj liblwres DynamicLibrary true MultiByte DynamicLibrary false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ Level3 Disabled WIN32;USE_MD5;@CRYPTO@_DEBUG;_WINDOWS;_USRDLL;LIBLWRES_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions) .\;..\..\lwres\win32\include;..\..\..\;include;..\include;..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;..\..\dns\include;%(AdditionalIncludeDirectories) false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true Console true ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) .\$(Configuration)\$(ProjectName).lib ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) $(ProjectName).def Level3 MaxSpeed true @INTRINSIC@ WIN32;USE_MD5;@CRYPTO@NDEBUG;_WINDOWS;_USRDLL;LIBLWRES_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions) .\;..\..\lwres\win32\include;..\..\..\;include;..\include;..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;..\..\dns\include;%(AdditionalIncludeDirectories) OnlyExplicitInline false true .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb Console false true true ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) Default .\$(Configuration)\$(ProjectName).lib ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) $(ProjectName).def bind9-9.10.3.dfsg.P4/lib/lwres/win32/liblwres.def0000644000470500017500000000311612664710322020541 0ustar lamontlamontLIBRARY liblwres ; Exported Functions EXPORTS lwres_addr_parse lwres_buffer_add lwres_buffer_back lwres_buffer_clear lwres_buffer_first lwres_buffer_forward lwres_buffer_getmem lwres_buffer_getuint16 lwres_buffer_getuint32 lwres_buffer_getuint8 lwres_buffer_init lwres_buffer_invalidate lwres_buffer_putmem lwres_buffer_putuint16 lwres_buffer_putuint32 lwres_buffer_putuint8 lwres_buffer_subtract lwres_conf_clear lwres_conf_get lwres_conf_init lwres_conf_parse lwres_conf_print lwres_context_allocmem lwres_context_create lwres_context_destroy lwres_context_freemem lwres_context_getsocket lwres_context_initserial lwres_context_nextserial lwres_context_recv lwres_context_send lwres_context_sendrecv lwres_data_parse lwres_freeaddrinfo lwres_gabnrequest_free lwres_gabnrequest_parse lwres_gabnrequest_render lwres_gabnresponse_free lwres_gabnresponse_parse lwres_gabnresponse_render lwres_gai_strerror lwres_getaddrinfo lwres_getaddrsbyname lwres_gethostbyname lwres_getnamebyaddr lwres_getrdatabyname lwres_gnbarequest_free lwres_gnbarequest_parse lwres_gnbarequest_render lwres_gnbaresponse_free lwres_gnbaresponse_parse lwres_gnbaresponse_render lwres_grbnrequest_free lwres_grbnrequest_parse lwres_grbnrequest_render lwres_grbnresponse_free lwres_grbnresponse_parse lwres_grbnresponse_render lwres_lwpacket_parseheader lwres_lwpacket_renderheader lwres_net_aton lwres_net_ntop lwres_net_pton lwres_nooprequest_free lwres_nooprequest_parse lwres_nooprequest_render lwres_noopresponse_free lwres_noopresponse_parse lwres_noopresponse_render lwres_string_parse ; Exported Data EXPORTS ;lwres_h_errno DATA bind9-9.10.3.dfsg.P4/lib/lwres/win32/liblwres.vcxproj.filters.in0000644000470500017500000001107412664710322023554 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files bind9-9.10.3.dfsg.P4/lib/lwres/win32/liblwres.mak.in0000644000470500017500000004503312664710322021164 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on liblwres.dsp !IF "$(CFG)" == "" CFG=liblwres - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to liblwres - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "liblwres - @PLATFORM@ Release" && "$(CFG)" != "liblwres - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "liblwres.mak" CFG="liblwres - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "liblwres - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE "liblwres - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release ALL : "..\..\..\Build\Release\liblwres.dll" CLEAN : -@erase "$(INTDIR)\context.obj" -@erase "$(INTDIR)\DLLMain.obj" -@erase "$(INTDIR)\gai_strerror.obj" -@erase "$(INTDIR)\getaddrinfo.obj" -@erase "$(INTDIR)\gethost.obj" -@erase "$(INTDIR)\getipnode.obj" -@erase "$(INTDIR)\getnameinfo.obj" -@erase "$(INTDIR)\getrrset.obj" -@erase "$(INTDIR)\herror.obj" -@erase "$(INTDIR)\lwbuffer.obj" -@erase "$(INTDIR)\lwconfig.obj" -@erase "$(INTDIR)\lwinetaton.obj" -@erase "$(INTDIR)\lwinetntop.obj" -@erase "$(INTDIR)\lwinetpton.obj" -@erase "$(INTDIR)\lwpacket.obj" -@erase "$(INTDIR)\lwres_gabn.obj" -@erase "$(INTDIR)\lwres_gnba.obj" -@erase "$(INTDIR)\lwres_grbn.obj" -@erase "$(INTDIR)\lwres_noop.obj" -@erase "$(INTDIR)\lwresutil.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\socket.obj" -@erase "$(INTDIR)\version.obj" -@erase "$(OUTDIR)\liblwres.exp" -@erase "$(OUTDIR)\liblwres.lib" -@erase "..\..\..\Build\Release\liblwres.dll" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../lib/lwres/win32/include/lwres" /I "include" /I "../include" /I "../../../" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isc/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ /D "LIBLWRES_EXPORTS" /Fp"$(INTDIR)\liblwres.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\liblwres.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib iphlpapi.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\liblwres.pdb" @MACHINE@ /def:".\liblwres.def" /out:"../../../Build/Release/liblwres.dll" /implib:"$(OUTDIR)\liblwres.lib" DEF_FILE= \ ".\liblwres.def" LINK32_OBJS= \ "$(INTDIR)\context.obj" \ "$(INTDIR)\DLLMain.obj" \ "$(INTDIR)\gai_strerror.obj" \ "$(INTDIR)\getaddrinfo.obj" \ "$(INTDIR)\gethost.obj" \ "$(INTDIR)\getipnode.obj" \ "$(INTDIR)\getnameinfo.obj" \ "$(INTDIR)\getrrset.obj" \ "$(INTDIR)\herror.obj" \ "$(INTDIR)\lwbuffer.obj" \ "$(INTDIR)\lwinetaton.obj" \ "$(INTDIR)\lwinetntop.obj" \ "$(INTDIR)\lwinetpton.obj" \ "$(INTDIR)\lwpacket.obj" \ "$(INTDIR)\lwres_gabn.obj" \ "$(INTDIR)\lwres_gnba.obj" \ "$(INTDIR)\lwres_grbn.obj" \ "$(INTDIR)\lwres_noop.obj" \ "$(INTDIR)\lwresutil.obj" \ "$(INTDIR)\socket.obj" \ "$(INTDIR)\version.obj" \ "$(INTDIR)\lwconfig.obj" "..\..\..\Build\Release\liblwres.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_DLL) !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros ALL : "..\..\..\Build\Debug\liblwres.dll" "$(OUTDIR)\liblwres.bsc" CLEAN : -@erase "$(INTDIR)\context.obj" -@erase "$(INTDIR)\context.sbr" -@erase "$(INTDIR)\DLLMain.obj" -@erase "$(INTDIR)\DLLMain.sbr" -@erase "$(INTDIR)\gai_strerror.obj" -@erase "$(INTDIR)\gai_strerror.sbr" -@erase "$(INTDIR)\getaddrinfo.obj" -@erase "$(INTDIR)\getaddrinfo.sbr" -@erase "$(INTDIR)\gethost.obj" -@erase "$(INTDIR)\gethost.sbr" -@erase "$(INTDIR)\getipnode.obj" -@erase "$(INTDIR)\getipnode.sbr" -@erase "$(INTDIR)\getnameinfo.obj" -@erase "$(INTDIR)\getnameinfo.sbr" -@erase "$(INTDIR)\getrrset.obj" -@erase "$(INTDIR)\getrrset.sbr" -@erase "$(INTDIR)\herror.obj" -@erase "$(INTDIR)\herror.sbr" -@erase "$(INTDIR)\lwbuffer.obj" -@erase "$(INTDIR)\lwbuffer.sbr" -@erase "$(INTDIR)\lwconfig.obj" -@erase "$(INTDIR)\lwconfig.sbr" -@erase "$(INTDIR)\lwinetaton.obj" -@erase "$(INTDIR)\lwinetaton.sbr" -@erase "$(INTDIR)\lwinetntop.obj" -@erase "$(INTDIR)\lwinetntop.sbr" -@erase "$(INTDIR)\lwinetpton.obj" -@erase "$(INTDIR)\lwinetpton.sbr" -@erase "$(INTDIR)\lwpacket.obj" -@erase "$(INTDIR)\lwpacket.sbr" -@erase "$(INTDIR)\lwres_gabn.obj" -@erase "$(INTDIR)\lwres_gabn.sbr" -@erase "$(INTDIR)\lwres_gnba.obj" -@erase "$(INTDIR)\lwres_gnba.sbr" -@erase "$(INTDIR)\lwres_grbn.obj" -@erase "$(INTDIR)\lwres_grbn.sbr" -@erase "$(INTDIR)\lwres_noop.obj" -@erase "$(INTDIR)\lwres_noop.sbr" -@erase "$(INTDIR)\lwresutil.obj" -@erase "$(INTDIR)\lwresutil.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(INTDIR)\socket.obj" -@erase "$(INTDIR)\socket.sbr" -@erase "$(INTDIR)\version.obj" -@erase "$(INTDIR)\version.sbr" -@erase "$(OUTDIR)\liblwres.bsc" -@erase "$(OUTDIR)\liblwres.exp" -@erase "$(OUTDIR)\liblwres.lib" -@erase "$(OUTDIR)\liblwres.pdb" -@erase "..\..\..\Build\Debug\liblwres.dll" -@erase "..\..\..\Build\Debug\liblwres.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../lib/lwres/win32/include/lwres" /I "include" /I "../include" /I "../../../" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isc/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ /D "LIBLWRES_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\liblwres.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\liblwres.bsc" BSC32_SBRS= \ "$(INTDIR)\context.sbr" \ "$(INTDIR)\DLLMain.sbr" \ "$(INTDIR)\gai_strerror.sbr" \ "$(INTDIR)\getaddrinfo.sbr" \ "$(INTDIR)\gethost.sbr" \ "$(INTDIR)\getipnode.sbr" \ "$(INTDIR)\getnameinfo.sbr" \ "$(INTDIR)\getrrset.sbr" \ "$(INTDIR)\herror.sbr" \ "$(INTDIR)\lwbuffer.sbr" \ "$(INTDIR)\lwinetaton.sbr" \ "$(INTDIR)\lwinetntop.sbr" \ "$(INTDIR)\lwinetpton.sbr" \ "$(INTDIR)\lwpacket.sbr" \ "$(INTDIR)\lwres_gabn.sbr" \ "$(INTDIR)\lwres_gnba.sbr" \ "$(INTDIR)\lwres_grbn.sbr" \ "$(INTDIR)\lwres_noop.sbr" \ "$(INTDIR)\lwresutil.sbr" \ "$(INTDIR)\socket.sbr" \ "$(INTDIR)\version.sbr" \ "$(INTDIR)\lwconfig.sbr" "$(OUTDIR)\liblwres.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib iphlpapi.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\liblwres.pdb" /debug @MACHINE@ /def:".\liblwres.def" /out:"../../../Build/Debug/liblwres.dll" /implib:"$(OUTDIR)\liblwres.lib" /pdbtype:sept DEF_FILE= \ ".\liblwres.def" LINK32_OBJS= \ "$(INTDIR)\context.obj" \ "$(INTDIR)\DLLMain.obj" \ "$(INTDIR)\gai_strerror.obj" \ "$(INTDIR)\getaddrinfo.obj" \ "$(INTDIR)\gethost.obj" \ "$(INTDIR)\getipnode.obj" \ "$(INTDIR)\getnameinfo.obj" \ "$(INTDIR)\getrrset.obj" \ "$(INTDIR)\herror.obj" \ "$(INTDIR)\lwbuffer.obj" \ "$(INTDIR)\lwinetaton.obj" \ "$(INTDIR)\lwinetntop.obj" \ "$(INTDIR)\lwinetpton.obj" \ "$(INTDIR)\lwpacket.obj" \ "$(INTDIR)\lwres_gabn.obj" \ "$(INTDIR)\lwres_gnba.obj" \ "$(INTDIR)\lwres_grbn.obj" \ "$(INTDIR)\lwres_noop.obj" \ "$(INTDIR)\lwresutil.obj" \ "$(INTDIR)\socket.obj" \ "$(INTDIR)\version.obj" \ "$(INTDIR)\lwconfig.obj" "..\..\..\Build\Debug\liblwres.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_DLL) !ENDIF .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("liblwres.dep") !INCLUDE "liblwres.dep" !ELSE !MESSAGE Warning: cannot find "liblwres.dep" !ENDIF !ENDIF !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" || "$(CFG)" == "liblwres - @PLATFORM@ Debug" SOURCE=..\compat.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\compat.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\compat.obj" "$(INTDIR)\compat.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\context.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\context.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\context.obj" "$(INTDIR)\context.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=.\DLLMain.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\DLLMain.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\DLLMain.obj" "$(INTDIR)\DLLMain.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=..\gai_strerror.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\gai_strerror.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\gai_strerror.obj" "$(INTDIR)\gai_strerror.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\getaddrinfo.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\getaddrinfo.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\getaddrinfo.obj" "$(INTDIR)\getaddrinfo.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\gethost.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\gethost.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\gethost.obj" "$(INTDIR)\gethost.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\getipnode.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\getipnode.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\getipnode.obj" "$(INTDIR)\getipnode.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\getnameinfo.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\getnameinfo.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\getnameinfo.obj" "$(INTDIR)\getnameinfo.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\getrrset.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\getrrset.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\getrrset.obj" "$(INTDIR)\getrrset.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\herror.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\herror.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\herror.obj" "$(INTDIR)\herror.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\lwbuffer.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\lwbuffer.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\lwbuffer.obj" "$(INTDIR)\lwbuffer.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=.\lwconfig.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\lwconfig.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\lwconfig.obj" "$(INTDIR)\lwconfig.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=..\lwinetaton.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\lwinetaton.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\lwinetaton.obj" "$(INTDIR)\lwinetaton.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\lwinetntop.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\lwinetntop.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\lwinetntop.obj" "$(INTDIR)\lwinetntop.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\lwinetpton.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\lwinetpton.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\lwinetpton.obj" "$(INTDIR)\lwinetpton.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\lwpacket.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\lwpacket.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\lwpacket.obj" "$(INTDIR)\lwpacket.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\lwres_gabn.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\lwres_gabn.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\lwres_gabn.obj" "$(INTDIR)\lwres_gabn.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\lwres_gnba.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\lwres_gnba.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\lwres_gnba.obj" "$(INTDIR)\lwres_gnba.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\lwres_grbn.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\lwres_grbn.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\lwres_grbn.obj" "$(INTDIR)\lwres_grbn.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\lwres_noop.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\lwres_noop.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\lwres_noop.obj" "$(INTDIR)\lwres_noop.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\lwresutil.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\lwresutil.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\lwresutil.obj" "$(INTDIR)\lwresutil.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=.\socket.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\socket.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\socket.obj" "$(INTDIR)\socket.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\version.c !IF "$(CFG)" == "liblwres - @PLATFORM@ Release" "$(INTDIR)\version.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "liblwres - @PLATFORM@ Debug" "$(INTDIR)\version.obj" "$(INTDIR)\version.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/lib/lwres/lwinetaton.c0000644000470500017500000001440512664710322017627 0ustar lamontlamont/* * Portions Copyright (C) 2004, 2005, 2007, 2012-2014 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1996-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (c) 1983, 1990, 1993 * The Regents of the University of California. 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. Neither the name of the University 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 REGENTS 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. */ /* * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /*! \file lwinetaton.c */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; static char rcsid[] = "$Id: lwinetaton.c,v 1.16 2007/06/19 23:47:22 tbox Exp $"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include "assert_p.h" /*! * Check whether "cp" is a valid ascii representation * of an Internet address and convert to a binary address. * Returns 1 if the address is valid, 0 if not. * This replaces inet_addr, the return value from which * cannot distinguish between failure and a local broadcast address. */ int lwres_net_aton(const char *cp, struct in_addr *addr) { lwres_uint32_t val; int base; ptrdiff_t n; unsigned char c; lwres_uint8_t parts[4]; lwres_uint8_t *pp = parts; int digit; REQUIRE(cp != NULL); c = *cp; for (;;) { /* * Collect number up to ``.''. * Values are specified as for C: * 0x=hex, 0=octal, isdigit=decimal. */ if (!isdigit(c & 0xff)) return (0); val = 0; base = 10; digit = 0; if (c == '0') { c = *++cp; if (c == 'x' || c == 'X') { base = 16; c = *++cp; } else { base = 8; digit = 1; } } for (;;) { /* * isascii() is valid for all integer values, and * when it is true, c is known to be in scope * for isdigit(). No cast necessary. Similar * comment applies for later ctype uses. */ if (isascii(c) && isdigit(c)) { if (base == 8 && (c == '8' || c == '9')) return (0); val = (val * base) + (c - '0'); c = *++cp; digit = 1; } else if (base == 16 && isascii(c) && isxdigit(c)) { val = (val << 4) | (c + 10 - (islower(c) ? 'a' : 'A')); c = *++cp; digit = 1; } else break; } if (c == '.') { /* * Internet format: * a.b.c.d * a.b.c (with c treated as 16 bits) * a.b (with b treated as 24 bits) */ if (pp >= parts + 3 || val > 0xffU) return (0); *pp++ = (lwres_uint8_t)val; c = *++cp; } else break; } /* * Check for trailing characters. */ if (c != '\0' && (!isascii(c) || !isspace(c))) return (0); /* * Did we get a valid digit? */ if (!digit) return (0); /* * Concoct the address according to * the number of parts specified. */ n = pp - parts + 1; switch (n) { case 1: /* a -- 32 bits */ break; case 2: /* a.b -- 8.24 bits */ if (val > 0xffffffU) return (0); val |= parts[0] << 24; break; case 3: /* a.b.c -- 8.8.16 bits */ if (val > 0xffffU) return (0); val |= (parts[0] << 24) | (parts[1] << 16); break; case 4: /* a.b.c.d -- 8.8.8.8 bits */ if (val > 0xffU) return (0); val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); break; } if (addr != NULL) addr->s_addr = htonl(val); return (1); } bind9-9.10.3.dfsg.P4/lib/lwres/print.c0000644000470500017500000002614612664710322016604 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2011, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #include #include /* for sprintf */ #include #define LWRES__PRINT_SOURCE /* Used to get the lwres_print_* prototypes. */ #include #include #include "assert_p.h" #include "print_p.h" #define LWRES_PRINT_QUADFORMAT LWRES_PLATFORM_QUADFORMAT int lwres__print_sprintf(char *str, const char *format, ...) { va_list ap; va_start(ap, format); vsprintf(str, format, ap); va_end(ap); return (strlen(str)); } /* * Return length of string that would have been written if not truncated. */ int lwres__print_snprintf(char *str, size_t size, const char *format, ...) { va_list ap; int ret; va_start(ap, format); ret = vsnprintf(str, size, format, ap); va_end(ap); return (ret); } /* * Return length of string that would have been written if not truncated. */ int lwres__print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { int h; int l; int q; int z; int alt; int zero; int left; int plus; int space; long long tmpi; unsigned long long tmpui; unsigned long width; unsigned long precision; unsigned int length; char buf[1024]; char c; void *v; char *save = str; const char *cp; const char *head; int count = 0; int pad; int zeropad; int dot; double dbl; #ifdef HAVE_LONG_DOUBLE long double ldbl; #endif char fmt[32]; INSIST(str != NULL); INSIST(format != NULL); while (*format != '\0') { if (*format != '%') { if (size > 1U) { *str++ = *format; size--; } count++; format++; continue; } format++; /* * Reset flags. */ dot = space = plus = left = zero = alt = h = l = q = z = 0; width = precision = 0; head = ""; length = pad = zeropad = 0; POST(length); do { if (*format == '#') { alt = 1; format++; } else if (*format == '-') { left = 1; zero = 0; format++; } else if (*format == ' ') { if (!plus) space = 1; format++; } else if (*format == '+') { plus = 1; space = 0; format++; } else if (*format == '0') { if (!left) zero = 1; format++; } else break; } while (1); /* * Width. */ if (*format == '*') { width = va_arg(ap, int); format++; } else if (isdigit((unsigned char)*format)) { char *e; width = strtoul(format, &e, 10); format = e; } /* * Precision. */ if (*format == '.') { format++; dot = 1; if (*format == '*') { precision = va_arg(ap, int); format++; } else if (isdigit((unsigned char)*format)) { char *e; precision = strtoul(format, &e, 10); format = e; } } switch (*format) { case '\0': continue; case '%': if (size > 1U) { *str++ = *format; size--; } count++; break; case 'q': q = 1; format++; goto doint; case 'h': h = 1; format++; goto doint; case 'l': l = 1; format++; if (*format == 'l') { q = 1; format++; } goto doint; case 'z': z = 1; format++; goto doint; case 'n': case 'i': case 'd': case 'o': case 'u': case 'x': case 'X': doint: if (precision != 0U) zero = 0; switch (*format) { case 'n': if (h) { short int *p; p = va_arg(ap, short *); REQUIRE(p != NULL); *p = str - save; } else if (l) { long int *p; p = va_arg(ap, long *); REQUIRE(p != NULL); *p = str - save; } else if (z) { size_t *p; p = va_arg(ap, size_t *); REQUIRE(p != NULL); *p = str - save; } else { int *p; p = va_arg(ap, int *); REQUIRE(p != NULL); *p = str - save; } break; case 'i': case 'd': if (q) tmpi = va_arg(ap, long long int); else if (l) tmpi = va_arg(ap, long int); else if (z) tmpi = va_arg(ap, size_t); else tmpi = va_arg(ap, int); if (tmpi < 0) { head = "-"; tmpui = -tmpi; } else { if (plus) head = "+"; else if (space) head = " "; else head = ""; tmpui = tmpi; } sprintf(buf, "%" LWRES_PRINT_QUADFORMAT "u", tmpui); goto printint; case 'o': if (q) tmpui = va_arg(ap, unsigned long long int); else if (l) tmpui = va_arg(ap, long int); else if (z) tmpui = va_arg(ap, size_t); else tmpui = va_arg(ap, int); sprintf(buf, alt ? "%#" LWRES_PRINT_QUADFORMAT "o" : "%" LWRES_PRINT_QUADFORMAT "o", tmpui); goto printint; case 'u': if (q) tmpui = va_arg(ap, unsigned long long int); else if (l) tmpui = va_arg(ap, unsigned long int); else if (z) tmpui = va_arg(ap, size_t); else tmpui = va_arg(ap, unsigned int); sprintf(buf, "%" LWRES_PRINT_QUADFORMAT "u", tmpui); goto printint; case 'x': if (q) tmpui = va_arg(ap, unsigned long long int); else if (l) tmpui = va_arg(ap, unsigned long int); else if (z) tmpui = va_arg(ap, size_t); else tmpui = va_arg(ap, unsigned int); if (alt) { head = "0x"; if (precision > 2U) precision -= 2; } sprintf(buf, "%" LWRES_PRINT_QUADFORMAT "x", tmpui); goto printint; case 'X': if (q) tmpui = va_arg(ap, unsigned long long int); else if (l) tmpui = va_arg(ap, unsigned long int); else if (z) tmpui = va_arg(ap, size_t); else tmpui = va_arg(ap, unsigned int); if (alt) { head = "0X"; if (precision > 2U) precision -= 2; } sprintf(buf, "%" LWRES_PRINT_QUADFORMAT "X", tmpui); goto printint; printint: if (precision != 0U || width != 0U) { length = strlen(buf); if (length < precision) zeropad = precision - length; else if (length < width && zero) zeropad = width - length; if (width != 0U) { pad = width - length - zeropad - strlen(head); if (pad < 0) pad = 0; } } count += strlen(head) + strlen(buf) + pad + zeropad; if (!left) { while (pad > 0 && size > 1U) { *str++ = ' '; size--; pad--; } } cp = head; while (*cp != '\0' && size > 1U) { *str++ = *cp++; size--; } while (zeropad > 0 && size > 1U) { *str++ = '0'; size--; zeropad--; } cp = buf; while (*cp != '\0' && size > 1U) { *str++ = *cp++; size--; } while (pad > 0 && size > 1U) { *str++ = ' '; size--; pad--; } break; default: break; } break; case 's': cp = va_arg(ap, char *); REQUIRE(cp != NULL); if (precision != 0U) { /* * cp need not be NULL terminated. */ const char *tp; unsigned long n; n = precision; tp = cp; while (n != 0U && *tp != '\0') n--, tp++; length = precision - n; } else { length = strlen(cp); } if (width != 0U) { pad = width - length; if (pad < 0) pad = 0; } count += pad + length; if (!left) while (pad > 0 && size > 1U) { *str++ = ' '; size--; pad--; } if (precision != 0U) while (precision > 0U && *cp != '\0' && size > 1U) { *str++ = *cp++; size--; precision--; } else while (*cp != '\0' && size > 1U) { *str++ = *cp++; size--; } while (pad > 0 && size > 1U) { *str++ = ' '; size--; pad--; } break; case 'c': c = va_arg(ap, int); if (width > 0U) { count += width; width--; if (left) { *str++ = c; size--; } while (width-- > 0U && size > 1U) { *str++ = ' '; size--; } if (!left && size > 1U) { *str++ = c; size--; } } else { count++; if (size > 1U) { *str++ = c; size--; } } break; case 'p': v = va_arg(ap, void *); sprintf(buf, "%p", v); length = strlen(buf); if (precision > length) zeropad = precision - length; if (width > 0U) { pad = width - length - zeropad; if (pad < 0) pad = 0; } count += length + pad + zeropad; if (!left) while (pad > 0 && size > 1U) { *str++ = ' '; size--; pad--; } cp = buf; if (zeropad > 0 && buf[0] == '0' && (buf[1] == 'x' || buf[1] == 'X')) { if (size > 1U) { *str++ = *cp++; size--; } if (size > 1U) { *str++ = *cp++; size--; } while (zeropad > 0 && size > 1U) { *str++ = '0'; size--; zeropad--; } } while (*cp != '\0' && size > 1U) { *str++ = *cp++; size--; } while (pad > 0 && size > 1U) { *str++ = ' '; size--; pad--; } break; case 'D': /*deprecated*/ INSIST("use %ld instead of %D" == NULL); break; case 'O': /*deprecated*/ INSIST("use %lo instead of %O" == NULL); break; case 'U': /*deprecated*/ INSIST("use %lu instead of %U" == NULL); break; case 'L': #ifdef HAVE_LONG_DOUBLE l = 1; #else INSIST("long doubles are not supported" == NULL); #endif /*FALLTHROUGH*/ case 'e': case 'E': case 'f': case 'g': case 'G': if (!dot) precision = 6; /* * IEEE floating point. * MIN 2.2250738585072014E-308 * MAX 1.7976931348623157E+308 * VAX floating point has a smaller range than IEEE. * * precisions > 324 don't make much sense. * if we cap the precision at 512 we will not * overflow buf. */ if (precision > 512U) precision = 512; sprintf(fmt, "%%%s%s.%lu%s%c", alt ? "#" : "", plus ? "+" : space ? " " : "", precision, l ? "L" : "", *format); switch (*format) { case 'e': case 'E': case 'f': case 'g': case 'G': #ifdef HAVE_LONG_DOUBLE if (l) { ldbl = va_arg(ap, long double); sprintf(buf, fmt, ldbl); } else #endif { dbl = va_arg(ap, double); sprintf(buf, fmt, dbl); } length = strlen(buf); if (width > 0U) { pad = width - length; if (pad < 0) pad = 0; } count += length + pad; if (!left) while (pad > 0 && size > 1U) { *str++ = ' '; size--; pad--; } cp = buf; while (*cp != ' ' && size > 1U) { *str++ = *cp++; size--; } while (pad > 0 && size > 1U) { *str++ = ' '; size--; pad--; } break; default: continue; } break; default: continue; } format++; } if (size > 0U) *str = '\0'; return (count); } bind9-9.10.3.dfsg.P4/lib/lwres/lwres_noop.c0000644000470500017500000002420312664710322017627 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lwres_noop.c,v 1.19 2007/06/19 23:47:22 tbox Exp $ */ /*! \file */ /** * These are low-level routines for creating and parsing lightweight * resolver no-op request and response messages. * * The no-op message is analogous to a ping packet: a packet is sent to * the resolver daemon and is simply echoed back. The opcode is intended * to allow a client to determine if the server is operational or not. * * There are four main functions for the no-op opcode. One render * function converts a no-op request structure -- lwres_nooprequest_t -- * to the lighweight resolver's canonical format. It is complemented by a * parse function that converts a packet in this canonical format to a * no-op request structure. Another render function converts the no-op * response structure -- lwres_noopresponse_t to the canonical format. * This is complemented by a parse function which converts a packet in * canonical format to a no-op response structure. * * These structures are defined in \link lwres.h \endlink They are shown below. * * \code * #define LWRES_OPCODE_NOOP 0x00000000U * * typedef struct { * lwres_uint16_t datalength; * unsigned char *data; * } lwres_nooprequest_t; * * typedef struct { * lwres_uint16_t datalength; * unsigned char *data; * } lwres_noopresponse_t; * \endcode * * Although the structures have different types, they are identical. This * is because the no-op opcode simply echos whatever data was sent: the * response is therefore identical to the request. * * lwres_nooprequest_render() uses resolver context ctx to convert no-op * request structure req to canonical format. The packet header structure * pkt is initialised and transferred to buffer b. The contents of *req * are then appended to the buffer in canonical format. * lwres_noopresponse_render() performs the same task, except it converts * a no-op response structure lwres_noopresponse_t to the lightweight * resolver's canonical format. * * lwres_nooprequest_parse() uses context ctx to convert the contents of * packet pkt to a lwres_nooprequest_t structure. Buffer b provides space * to be used for storing this structure. When the function succeeds, the * resulting lwres_nooprequest_t is made available through *structp. * lwres_noopresponse_parse() offers the same semantics as * lwres_nooprequest_parse() except it yields a lwres_noopresponse_t * structure. * * lwres_noopresponse_free() and lwres_nooprequest_free() release the * memory in resolver context ctx that was allocated to the * lwres_noopresponse_t or lwres_nooprequest_t structures referenced via * structp. * * \section lwres_noop_return Return Values * * The no-op opcode functions lwres_nooprequest_render(), * lwres_noopresponse_render() lwres_nooprequest_parse() and * lwres_noopresponse_parse() all return #LWRES_R_SUCCESS on success. They * return #LWRES_R_NOMEMORY if memory allocation fails. * #LWRES_R_UNEXPECTEDEND is returned if the available space in the buffer * b is too small to accommodate the packet header or the * lwres_nooprequest_t and lwres_noopresponse_t structures. * lwres_nooprequest_parse() and lwres_noopresponse_parse() will return * #LWRES_R_UNEXPECTEDEND if the buffer is not empty after decoding the * received packet. These functions will return #LWRES_R_FAILURE if * pktflags in the packet header structure #lwres_lwpacket_t indicate that * the packet is not a response to an earlier query. * * \section lwres_noop_see See Also * * lwpacket.c */ #include #include #include #include #include #include #include #include #include "context_p.h" #include "assert_p.h" /*% Uses resolver context ctx to convert no-op request structure req to canonical format. */ lwres_result_t lwres_nooprequest_render(lwres_context_t *ctx, lwres_nooprequest_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b) { unsigned char *buf; size_t buflen; int ret; size_t payload_length; REQUIRE(ctx != NULL); REQUIRE(req != NULL); REQUIRE(pkt != NULL); REQUIRE(b != NULL); payload_length = sizeof(lwres_uint16_t) + req->datalength; buflen = LWRES_LWPACKET_LENGTH + payload_length; buf = CTXMALLOC(buflen); if (buf == NULL) return (LWRES_R_NOMEMORY); lwres_buffer_init(b, buf, (unsigned int)buflen); pkt->length = (lwres_uint32_t)buflen; pkt->version = LWRES_LWPACKETVERSION_0; pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE; pkt->opcode = LWRES_OPCODE_NOOP; pkt->result = 0; pkt->authtype = 0; pkt->authlength = 0; ret = lwres_lwpacket_renderheader(b, pkt); if (ret != LWRES_R_SUCCESS) { lwres_buffer_invalidate(b); CTXFREE(buf, buflen); return (ret); } INSIST(SPACE_OK(b, payload_length)); /* * Put the length and the data. We know this will fit because we * just checked for it. */ lwres_buffer_putuint16(b, req->datalength); lwres_buffer_putmem(b, req->data, req->datalength); INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0); return (LWRES_R_SUCCESS); } /*% Converts a no-op response structure lwres_noopresponse_t to the lightweight resolver's canonical format. */ lwres_result_t lwres_noopresponse_render(lwres_context_t *ctx, lwres_noopresponse_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b) { unsigned char *buf; size_t buflen; int ret; size_t payload_length; REQUIRE(ctx != NULL); REQUIRE(req != NULL); REQUIRE(pkt != NULL); REQUIRE(b != NULL); payload_length = sizeof(lwres_uint16_t) + req->datalength; buflen = LWRES_LWPACKET_LENGTH + payload_length; buf = CTXMALLOC(buflen); if (buf == NULL) return (LWRES_R_NOMEMORY); lwres_buffer_init(b, buf, (unsigned int)buflen); pkt->length = (lwres_uint32_t)buflen; pkt->version = LWRES_LWPACKETVERSION_0; pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE; pkt->opcode = LWRES_OPCODE_NOOP; pkt->authtype = 0; pkt->authlength = 0; ret = lwres_lwpacket_renderheader(b, pkt); if (ret != LWRES_R_SUCCESS) { lwres_buffer_invalidate(b); CTXFREE(buf, buflen); return (ret); } INSIST(SPACE_OK(b, payload_length)); /* * Put the length and the data. We know this will fit because we * just checked for it. */ lwres_buffer_putuint16(b, req->datalength); lwres_buffer_putmem(b, req->data, req->datalength); INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0); return (LWRES_R_SUCCESS); } /*% Uses context ctx to convert the contents of packet pkt to a lwres_nooprequest_t structure. */ lwres_result_t lwres_nooprequest_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_nooprequest_t **structp) { int ret; lwres_nooprequest_t *req; REQUIRE(ctx != NULL); REQUIRE(b != NULL); REQUIRE(pkt != NULL); REQUIRE(structp != NULL && *structp == NULL); if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0) return (LWRES_R_FAILURE); req = CTXMALLOC(sizeof(lwres_nooprequest_t)); if (req == NULL) return (LWRES_R_NOMEMORY); if (!SPACE_REMAINING(b, sizeof(lwres_uint16_t))) { ret = LWRES_R_UNEXPECTEDEND; goto out; } req->datalength = lwres_buffer_getuint16(b); if (!SPACE_REMAINING(b, req->datalength)) { ret = LWRES_R_UNEXPECTEDEND; goto out; } req->data = b->base + b->current; lwres_buffer_forward(b, req->datalength); if (LWRES_BUFFER_REMAINING(b) != 0) { ret = LWRES_R_TRAILINGDATA; goto out; } /* success! */ *structp = req; return (LWRES_R_SUCCESS); /* Error return */ out: CTXFREE(req, sizeof(lwres_nooprequest_t)); return (ret); } /*% Offers the same semantics as lwres_nooprequest_parse() except it yields a lwres_noopresponse_t structure. */ lwres_result_t lwres_noopresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_noopresponse_t **structp) { int ret; lwres_noopresponse_t *req; REQUIRE(ctx != NULL); REQUIRE(b != NULL); REQUIRE(pkt != NULL); REQUIRE(structp != NULL && *structp == NULL); if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0) return (LWRES_R_FAILURE); req = CTXMALLOC(sizeof(lwres_noopresponse_t)); if (req == NULL) return (LWRES_R_NOMEMORY); if (!SPACE_REMAINING(b, sizeof(lwres_uint16_t))) { ret = LWRES_R_UNEXPECTEDEND; goto out; } req->datalength = lwres_buffer_getuint16(b); if (!SPACE_REMAINING(b, req->datalength)) { ret = LWRES_R_UNEXPECTEDEND; goto out; } req->data = b->base + b->current; lwres_buffer_forward(b, req->datalength); if (LWRES_BUFFER_REMAINING(b) != 0) { ret = LWRES_R_TRAILINGDATA; goto out; } /* success! */ *structp = req; return (LWRES_R_SUCCESS); /* Error return */ out: CTXFREE(req, sizeof(lwres_noopresponse_t)); return (ret); } /*% Release the memory in resolver context ctx. */ void lwres_noopresponse_free(lwres_context_t *ctx, lwres_noopresponse_t **structp) { lwres_noopresponse_t *noop; REQUIRE(ctx != NULL); REQUIRE(structp != NULL && *structp != NULL); noop = *structp; *structp = NULL; CTXFREE(noop, sizeof(lwres_noopresponse_t)); } /*% Release the memory in resolver context ctx. */ void lwres_nooprequest_free(lwres_context_t *ctx, lwres_nooprequest_t **structp) { lwres_nooprequest_t *noop; REQUIRE(ctx != NULL); REQUIRE(structp != NULL && *structp != NULL); noop = *structp; *structp = NULL; CTXFREE(noop, sizeof(lwres_nooprequest_t)); } bind9-9.10.3.dfsg.P4/lib/lwres/context.c0000644000470500017500000003232312664710322017126 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007-2009, 2012-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: context.c,v 1.55 2009/09/02 23:48:03 tbox Exp $ */ /*! \file context.c lwres_context_create() creates a #lwres_context_t structure for use in lightweight resolver operations. It holds a socket and other data needed for communicating with a resolver daemon. The new lwres_context_t is returned through contextp, a pointer to a lwres_context_t pointer. This lwres_context_t pointer must initially be NULL, and is modified to point to the newly created lwres_context_t. When the lightweight resolver needs to perform dynamic memory allocation, it will call malloc_function to allocate memory and free_function to free it. If malloc_function and free_function are NULL, memory is allocated using malloc and free. It is not permitted to have a NULL malloc_function and a non-NULL free_function or vice versa. arg is passed as the first parameter to the memory allocation functions. If malloc_function and free_function are NULL, arg is unused and should be passed as NULL. Once memory for the structure has been allocated, it is initialized using lwres_conf_init() and returned via *contextp. lwres_context_destroy() destroys a #lwres_context_t, closing its socket. contextp is a pointer to a pointer to the context that is to be destroyed. The pointer will be set to NULL when the context has been destroyed. The context holds a serial number that is used to identify resolver request packets and associate responses with the corresponding requests. This serial number is controlled using lwres_context_initserial() and lwres_context_nextserial(). lwres_context_initserial() sets the serial number for context *ctx to serial. lwres_context_nextserial() increments the serial number and returns the previous value. Memory for a lightweight resolver context is allocated and freed using lwres_context_allocmem() and lwres_context_freemem(). These use whatever allocations were defined when the context was created with lwres_context_create(). lwres_context_allocmem() allocates len bytes of memory and if successful returns a pointer to the allocated storage. lwres_context_freemem() frees len bytes of space starting at location mem. lwres_context_sendrecv() performs I/O for the context ctx. Data are read and written from the context's socket. It writes data from sendbase -- typically a lightweight resolver query packet -- and waits for a reply which is copied to the receive buffer at recvbase. The number of bytes that were written to this receive buffer is returned in *recvd_len. \section context_return Return Values lwres_context_create() returns #LWRES_R_NOMEMORY if memory for the struct lwres_context could not be allocated, #LWRES_R_SUCCESS otherwise. Successful calls to the memory allocator lwres_context_allocmem() return a pointer to the start of the allocated space. It returns NULL if memory could not be allocated. #LWRES_R_SUCCESS is returned when lwres_context_sendrecv() completes successfully. #LWRES_R_IOERROR is returned if an I/O error occurs and #LWRES_R_TIMEOUT is returned if lwres_context_sendrecv() times out waiting for a response. \section context_see See Also lwres_conf_init(), malloc, free. */ #include #include #include #include #include #include #include #include #include #include #ifdef LWRES_PLATFORM_NEEDSYSSELECTH #include #endif #include "context_p.h" #include "assert_p.h" /*! * Some systems define the socket length argument as an int, some as size_t, * some as socklen_t. The last is what the current POSIX standard mandates. * This definition is here so it can be portable but easily changed if needed. */ #ifndef LWRES_SOCKADDR_LEN_T #define LWRES_SOCKADDR_LEN_T unsigned int #endif /*! * Make a socket nonblocking. */ #ifndef MAKE_NONBLOCKING #define MAKE_NONBLOCKING(sd, retval) \ do { \ retval = fcntl(sd, F_GETFL, 0); \ if (retval != -1) { \ retval |= O_NONBLOCK; \ retval = fcntl(sd, F_SETFL, retval); \ } \ } while (0) #endif LIBLWRES_EXTERNAL_DATA lwres_uint16_t lwres_udp_port = LWRES_UDP_PORT; LIBLWRES_EXTERNAL_DATA const char *lwres_resolv_conf = LWRES_RESOLV_CONF; static void * lwres_malloc(void *, size_t); static void lwres_free(void *, void *, size_t); /*! * lwres_result_t */ static lwres_result_t context_connect(lwres_context_t *); /*% * Creates a #lwres_context_t structure for use in * lightweight resolver operations. */ lwres_result_t lwres_context_create(lwres_context_t **contextp, void *arg, lwres_malloc_t malloc_function, lwres_free_t free_function, unsigned int flags) { lwres_context_t *ctx; REQUIRE(contextp != NULL && *contextp == NULL); /* * If we were not given anything special to use, use our own * functions. These are just wrappers around malloc() and free(). */ if (malloc_function == NULL || free_function == NULL) { REQUIRE(malloc_function == NULL); REQUIRE(free_function == NULL); malloc_function = lwres_malloc; free_function = lwres_free; } ctx = malloc_function(arg, sizeof(lwres_context_t)); if (ctx == NULL) return (LWRES_R_NOMEMORY); /* * Set up the context. */ ctx->malloc = malloc_function; ctx->free = free_function; ctx->arg = arg; ctx->sock = -1; ctx->timeout = LWRES_DEFAULT_TIMEOUT; #ifndef WIN32 ctx->serial = time(NULL); /* XXXMLG or BEW */ #else ctx->serial = _time32(NULL); #endif ctx->use_ipv4 = 1; ctx->use_ipv6 = 1; if ((flags & (LWRES_CONTEXT_USEIPV4 | LWRES_CONTEXT_USEIPV6)) == LWRES_CONTEXT_USEIPV6) { ctx->use_ipv4 = 0; } if ((flags & (LWRES_CONTEXT_USEIPV4 | LWRES_CONTEXT_USEIPV6)) == LWRES_CONTEXT_USEIPV4) { ctx->use_ipv6 = 0; } /* * Init resolv.conf bits. */ lwres_conf_init(ctx); *contextp = ctx; return (LWRES_R_SUCCESS); } /*% Destroys a #lwres_context_t, closing its socket. contextp is a pointer to a pointer to the context that is to be destroyed. The pointer will be set to NULL when the context has been destroyed. */ void lwres_context_destroy(lwres_context_t **contextp) { lwres_context_t *ctx; REQUIRE(contextp != NULL && *contextp != NULL); ctx = *contextp; *contextp = NULL; if (ctx->sock != -1) { #ifdef WIN32 DestroySockets(); #endif (void)close(ctx->sock); ctx->sock = -1; } CTXFREE(ctx, sizeof(lwres_context_t)); } /*% Increments the serial number and returns the previous value. */ lwres_uint32_t lwres_context_nextserial(lwres_context_t *ctx) { REQUIRE(ctx != NULL); return (ctx->serial++); } /*% Sets the serial number for context *ctx to serial. */ void lwres_context_initserial(lwres_context_t *ctx, lwres_uint32_t serial) { REQUIRE(ctx != NULL); ctx->serial = serial; } /*% Frees len bytes of space starting at location mem. */ void lwres_context_freemem(lwres_context_t *ctx, void *mem, size_t len) { REQUIRE(mem != NULL); REQUIRE(len != 0U); CTXFREE(mem, len); } /*% Allocates len bytes of memory and if successful returns a pointer to the allocated storage. */ void * lwres_context_allocmem(lwres_context_t *ctx, size_t len) { REQUIRE(len != 0U); return (CTXMALLOC(len)); } static void * lwres_malloc(void *arg, size_t len) { void *mem; UNUSED(arg); mem = malloc(len); if (mem == NULL) return (NULL); memset(mem, 0xe5, len); return (mem); } static void lwres_free(void *arg, void *mem, size_t len) { UNUSED(arg); memset(mem, 0xa9, len); free(mem); } static lwres_result_t context_connect(lwres_context_t *ctx) { #ifndef WIN32 int s; #else SOCKET s; #endif int ret; struct sockaddr_in sin; struct sockaddr_in6 sin6; struct sockaddr *sa; LWRES_SOCKADDR_LEN_T salen; int domain; if (ctx->confdata.lwnext != 0) { memmove(&ctx->address, &ctx->confdata.lwservers[0], sizeof(lwres_addr_t)); LWRES_LINK_INIT(&ctx->address, link); } else { /* The default is the IPv4 loopback address 127.0.0.1. */ memset(&ctx->address, 0, sizeof(ctx->address)); ctx->address.family = LWRES_ADDRTYPE_V4; ctx->address.length = 4; ctx->address.address[0] = 127; ctx->address.address[1] = 0; ctx->address.address[2] = 0; ctx->address.address[3] = 1; } if (ctx->address.family == LWRES_ADDRTYPE_V4) { memmove(&sin.sin_addr, ctx->address.address, sizeof(sin.sin_addr)); sin.sin_port = htons(lwres_udp_port); sin.sin_family = AF_INET; sa = (struct sockaddr *)&sin; salen = sizeof(sin); domain = PF_INET; } else if (ctx->address.family == LWRES_ADDRTYPE_V6) { memmove(&sin6.sin6_addr, ctx->address.address, sizeof(sin6.sin6_addr)); sin6.sin6_port = htons(lwres_udp_port); sin6.sin6_family = AF_INET6; sa = (struct sockaddr *)&sin6; salen = sizeof(sin6); domain = PF_INET6; } else return (LWRES_R_IOERROR); #ifdef WIN32 InitSockets(); #endif s = socket(domain, SOCK_DGRAM, IPPROTO_UDP); #ifndef WIN32 if (s < 0) { return (LWRES_R_IOERROR); } #else if (s == INVALID_SOCKET) { DestroySockets(); return (LWRES_R_IOERROR); } #endif ret = connect(s, sa, salen); if (ret != 0) { #ifdef WIN32 DestroySockets(); #endif (void)close(s); return (LWRES_R_IOERROR); } MAKE_NONBLOCKING(s, ret); if (ret < 0) { #ifdef WIN32 DestroySockets(); #endif (void)close(s); return (LWRES_R_IOERROR); } ctx->sock = (int)s; return (LWRES_R_SUCCESS); } int lwres_context_getsocket(lwres_context_t *ctx) { return (ctx->sock); } lwres_result_t lwres_context_send(lwres_context_t *ctx, void *sendbase, int sendlen) { int ret; lwres_result_t lwresult; if (ctx->sock == -1) { lwresult = context_connect(ctx); if (lwresult != LWRES_R_SUCCESS) return (lwresult); INSIST(ctx->sock >= 0); } ret = sendto(ctx->sock, sendbase, sendlen, 0, NULL, 0); if (ret < 0) return (LWRES_R_IOERROR); if (ret != sendlen) return (LWRES_R_IOERROR); return (LWRES_R_SUCCESS); } lwres_result_t lwres_context_recv(lwres_context_t *ctx, void *recvbase, int recvlen, int *recvd_len) { LWRES_SOCKADDR_LEN_T fromlen; struct sockaddr_in sin; struct sockaddr_in6 sin6; struct sockaddr *sa; int ret; if (ctx->address.family == LWRES_ADDRTYPE_V4) { sa = (struct sockaddr *)&sin; fromlen = sizeof(sin); } else { sa = (struct sockaddr *)&sin6; fromlen = sizeof(sin6); } /* * The address of fromlen is cast to void * to shut up compiler * warnings, namely on systems that have the sixth parameter * prototyped as a signed int when LWRES_SOCKADDR_LEN_T is * defined as unsigned. */ ret = recvfrom(ctx->sock, recvbase, recvlen, 0, sa, (void *)&fromlen); if (ret < 0) return (LWRES_R_IOERROR); if (ret == recvlen) return (LWRES_R_TOOLARGE); /* * If we got something other than what we expect, have the caller * wait for another packet. This can happen if an old result * comes in, or if someone is sending us random stuff. */ if (ctx->address.family == LWRES_ADDRTYPE_V4) { if (fromlen != sizeof(sin) || memcmp(&sin.sin_addr, ctx->address.address, sizeof(sin.sin_addr)) != 0 || sin.sin_port != htons(lwres_udp_port)) return (LWRES_R_RETRY); } else { if (fromlen != sizeof(sin6) || memcmp(&sin6.sin6_addr, ctx->address.address, sizeof(sin6.sin6_addr)) != 0 || sin6.sin6_port != htons(lwres_udp_port)) return (LWRES_R_RETRY); } if (recvd_len != NULL) *recvd_len = ret; return (LWRES_R_SUCCESS); } /*% performs I/O for the context ctx. */ lwres_result_t lwres_context_sendrecv(lwres_context_t *ctx, void *sendbase, int sendlen, void *recvbase, int recvlen, int *recvd_len) { lwres_result_t result; int ret2; fd_set readfds; struct timeval timeout; /* * Type of tv_sec is 32 bits long. */ if (ctx->timeout <= 0x7FFFFFFFU) timeout.tv_sec = (int)ctx->timeout; else timeout.tv_sec = 0x7FFFFFFF; timeout.tv_usec = 0; result = lwres_context_send(ctx, sendbase, sendlen); if (result != LWRES_R_SUCCESS) return (result); /* * If this is not checked, select() can overflow, * causing corruption elsewhere. */ if (ctx->sock >= (int)FD_SETSIZE) { close(ctx->sock); ctx->sock = -1; return (LWRES_R_IOERROR); } again: FD_ZERO(&readfds); FD_SET(ctx->sock, &readfds); ret2 = select(ctx->sock + 1, &readfds, NULL, NULL, &timeout); /* * What happened with select? */ if (ret2 < 0) return (LWRES_R_IOERROR); if (ret2 == 0) return (LWRES_R_TIMEOUT); result = lwres_context_recv(ctx, recvbase, recvlen, recvd_len); if (result == LWRES_R_RETRY) goto again; return (result); } bind9-9.10.3.dfsg.P4/lib/lwres/context_p.h0000644000470500017500000000371212664710322017452 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: context_p.h,v 1.19 2008/12/17 23:47:58 tbox Exp $ */ #ifndef LWRES_CONTEXT_P_H #define LWRES_CONTEXT_P_H 1 /*! \file */ /*@{*/ /** * Helper functions, assuming the context is always called "ctx" in * the scope these functions are called from. */ #define CTXMALLOC(len) ctx->malloc(ctx->arg, (len)) #define CTXFREE(addr, len) ctx->free(ctx->arg, (addr), (len)) /*@}*/ #define LWRES_DEFAULT_TIMEOUT 120 /* 120 seconds for a reply */ /** * Not all the attributes here are actually settable by the application at * this time. */ struct lwres_context { unsigned int timeout; /*%< time to wait for reply */ lwres_uint32_t serial; /*%< serial number state */ /* * For network I/O. */ int sock; /*%< socket to send on */ lwres_addr_t address; /*%< address to send to */ int use_ipv4; /*%< use IPv4 transaction */ int use_ipv6; /*%< use IPv6 transaction */ /*@{*/ /* * Function pointers for allocating memory. */ lwres_malloc_t malloc; lwres_free_t free; void *arg; /*@}*/ /*% * resolv.conf-like data */ lwres_conf_t confdata; }; #endif /* LWRES_CONTEXT_P_H */ bind9-9.10.3.dfsg.P4/lib/lwres/lwres_gabn.c0000644000470500017500000003371312664710322017571 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lwres_gabn.c,v 1.33 2007/06/19 23:47:22 tbox Exp $ */ /*! \file lwres_gabn.c These are low-level routines for creating and parsing lightweight resolver name-to-address lookup request and response messages. There are four main functions for the getaddrbyname opcode. One render function converts a getaddrbyname request structure -- lwres_gabnrequest_t -- to the lighweight resolver's canonical format. It is complemented by a parse function that converts a packet in this canonical format to a getaddrbyname request structure. Another render function converts the getaddrbyname response structure -- lwres_gabnresponse_t -- to the canonical format. This is complemented by a parse function which converts a packet in canonical format to a getaddrbyname response structure. These structures are defined in \link lwres.h .\endlink They are shown below. \code #define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U typedef struct lwres_addr lwres_addr_t; typedef LWRES_LIST(lwres_addr_t) lwres_addrlist_t; typedef struct { lwres_uint32_t flags; lwres_uint32_t addrtypes; lwres_uint16_t namelen; char *name; } lwres_gabnrequest_t; typedef struct { lwres_uint32_t flags; lwres_uint16_t naliases; lwres_uint16_t naddrs; char *realname; char **aliases; lwres_uint16_t realnamelen; lwres_uint16_t *aliaslen; lwres_addrlist_t addrs; void *base; size_t baselen; } lwres_gabnresponse_t; \endcode lwres_gabnrequest_render() uses resolver context ctx to convert getaddrbyname request structure req to canonical format. The packet header structure pkt is initialised and transferred to buffer b. The contents of *req are then appended to the buffer in canonical format. lwres_gabnresponse_render() performs the same task, except it converts a getaddrbyname response structure lwres_gabnresponse_t to the lightweight resolver's canonical format. lwres_gabnrequest_parse() uses context ctx to convert the contents of packet pkt to a lwres_gabnrequest_t structure. Buffer b provides space to be used for storing this structure. When the function succeeds, the resulting lwres_gabnrequest_t is made available through *structp. lwres_gabnresponse_parse() offers the same semantics as lwres_gabnrequest_parse() except it yields a lwres_gabnresponse_t structure. lwres_gabnresponse_free() and lwres_gabnrequest_free() release the memory in resolver context ctx that was allocated to the lwres_gabnresponse_t or lwres_gabnrequest_t structures referenced via structp. Any memory associated with ancillary buffers and strings for those structures is also discarded. \section lwres_gabn_return Return Values The getaddrbyname opcode functions lwres_gabnrequest_render(), lwres_gabnresponse_render() lwres_gabnrequest_parse() and lwres_gabnresponse_parse() all return #LWRES_R_SUCCESS on success. They return #LWRES_R_NOMEMORY if memory allocation fails. #LWRES_R_UNEXPECTEDEND is returned if the available space in the buffer b is too small to accommodate the packet header or the lwres_gabnrequest_t and lwres_gabnresponse_t structures. lwres_gabnrequest_parse() and lwres_gabnresponse_parse() will return #LWRES_R_UNEXPECTEDEND if the buffer is not empty after decoding the received packet. These functions will return #LWRES_R_FAILURE if pktflags in the packet header structure #lwres_lwpacket_t indicate that the packet is not a response to an earlier query. \section lwres_gabn_see See Also \link lwpacket.c lwres_lwpacket \endlink */ #include #include #include #include #include #include #include #include #include "context_p.h" #include "assert_p.h" /*% uses resolver context ctx to convert getaddrbyname request structure req to canonical format. */ lwres_result_t lwres_gabnrequest_render(lwres_context_t *ctx, lwres_gabnrequest_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b) { unsigned char *buf; size_t buflen; int ret; size_t payload_length; lwres_uint16_t datalen; REQUIRE(ctx != NULL); REQUIRE(req != NULL); REQUIRE(req->name != NULL); REQUIRE(pkt != NULL); REQUIRE(b != NULL); datalen = strlen(req->name); payload_length = 4 + 4 + 2 + req->namelen + 1; buflen = LWRES_LWPACKET_LENGTH + payload_length; buf = CTXMALLOC(buflen); if (buf == NULL) return (LWRES_R_NOMEMORY); lwres_buffer_init(b, buf, (unsigned int)buflen); pkt->length = (lwres_uint32_t)buflen; pkt->version = LWRES_LWPACKETVERSION_0; pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE; pkt->opcode = LWRES_OPCODE_GETADDRSBYNAME; pkt->result = 0; pkt->authtype = 0; pkt->authlength = 0; ret = lwres_lwpacket_renderheader(b, pkt); if (ret != LWRES_R_SUCCESS) { lwres_buffer_invalidate(b); CTXFREE(buf, buflen); return (ret); } INSIST(SPACE_OK(b, payload_length)); /* * Flags. */ lwres_buffer_putuint32(b, req->flags); /* * Address types we'll accept. */ lwres_buffer_putuint32(b, req->addrtypes); /* * Put the length and the data. We know this will fit because we * just checked for it. */ lwres_buffer_putuint16(b, datalen); lwres_buffer_putmem(b, (unsigned char *)req->name, datalen); lwres_buffer_putuint8(b, 0); /* trailing NUL */ INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0); return (LWRES_R_SUCCESS); } /*% converts a getaddrbyname response structure lwres_gabnresponse_t to the lightweight resolver's canonical format. */ lwres_result_t lwres_gabnresponse_render(lwres_context_t *ctx, lwres_gabnresponse_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b) { unsigned char *buf; size_t buflen; int ret; size_t payload_length; lwres_uint16_t datalen; lwres_addr_t *addr; int x; REQUIRE(ctx != NULL); REQUIRE(req != NULL); REQUIRE(pkt != NULL); REQUIRE(b != NULL); /* naliases, naddrs */ payload_length = 4 + 2 + 2; /* real name encoding */ payload_length += 2 + req->realnamelen + 1; /* each alias */ for (x = 0; x < req->naliases; x++) payload_length += 2 + req->aliaslen[x] + 1; /* each address */ x = 0; addr = LWRES_LIST_HEAD(req->addrs); while (addr != NULL) { payload_length += 4 + 2; payload_length += addr->length; addr = LWRES_LIST_NEXT(addr, link); x++; } INSIST(x == req->naddrs); buflen = LWRES_LWPACKET_LENGTH + payload_length; buf = CTXMALLOC(buflen); if (buf == NULL) return (LWRES_R_NOMEMORY); lwres_buffer_init(b, buf, (unsigned int)buflen); pkt->length = (lwres_uint32_t)buflen; pkt->version = LWRES_LWPACKETVERSION_0; pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE; pkt->opcode = LWRES_OPCODE_GETADDRSBYNAME; pkt->authtype = 0; pkt->authlength = 0; ret = lwres_lwpacket_renderheader(b, pkt); if (ret != LWRES_R_SUCCESS) { lwres_buffer_invalidate(b); CTXFREE(buf, buflen); return (ret); } /* * Check space needed here. */ INSIST(SPACE_OK(b, payload_length)); /* Flags. */ lwres_buffer_putuint32(b, req->flags); /* encode naliases and naddrs */ lwres_buffer_putuint16(b, req->naliases); lwres_buffer_putuint16(b, req->naddrs); /* encode the real name */ datalen = req->realnamelen; lwres_buffer_putuint16(b, datalen); lwres_buffer_putmem(b, (unsigned char *)req->realname, datalen); lwres_buffer_putuint8(b, 0); /* encode the aliases */ for (x = 0; x < req->naliases; x++) { datalen = req->aliaslen[x]; lwres_buffer_putuint16(b, datalen); lwres_buffer_putmem(b, (unsigned char *)req->aliases[x], datalen); lwres_buffer_putuint8(b, 0); } /* encode the addresses */ addr = LWRES_LIST_HEAD(req->addrs); while (addr != NULL) { lwres_buffer_putuint32(b, addr->family); lwres_buffer_putuint16(b, addr->length); lwres_buffer_putmem(b, addr->address, addr->length); addr = LWRES_LIST_NEXT(addr, link); } INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0); INSIST(LWRES_BUFFER_USEDCOUNT(b) == pkt->length); return (LWRES_R_SUCCESS); } /*% Uses context ctx to convert the contents of packet pkt to a lwres_gabnrequest_t structure. */ lwres_result_t lwres_gabnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gabnrequest_t **structp) { int ret; char *name; lwres_gabnrequest_t *gabn; lwres_uint32_t addrtypes; lwres_uint32_t flags; lwres_uint16_t namelen; REQUIRE(ctx != NULL); REQUIRE(pkt != NULL); REQUIRE(b != NULL); REQUIRE(structp != NULL && *structp == NULL); if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0) return (LWRES_R_FAILURE); if (!SPACE_REMAINING(b, 4 + 4)) return (LWRES_R_UNEXPECTEDEND); flags = lwres_buffer_getuint32(b); addrtypes = lwres_buffer_getuint32(b); /* * Pull off the name itself */ ret = lwres_string_parse(b, &name, &namelen); if (ret != LWRES_R_SUCCESS) return (ret); if (LWRES_BUFFER_REMAINING(b) != 0) return (LWRES_R_TRAILINGDATA); gabn = CTXMALLOC(sizeof(lwres_gabnrequest_t)); if (gabn == NULL) return (LWRES_R_NOMEMORY); gabn->flags = flags; gabn->addrtypes = addrtypes; gabn->name = name; gabn->namelen = namelen; *structp = gabn; return (LWRES_R_SUCCESS); } /*% Offers the same semantics as lwres_gabnrequest_parse() except it yields a lwres_gabnresponse_t structure. */ lwres_result_t lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gabnresponse_t **structp) { lwres_result_t ret; unsigned int x; lwres_uint32_t flags; lwres_uint16_t naliases; lwres_uint16_t naddrs; lwres_gabnresponse_t *gabn; lwres_addrlist_t addrlist; lwres_addr_t *addr; REQUIRE(ctx != NULL); REQUIRE(pkt != NULL); REQUIRE(b != NULL); REQUIRE(structp != NULL && *structp == NULL); gabn = NULL; if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0) return (LWRES_R_FAILURE); /* * Pull off the name itself */ if (!SPACE_REMAINING(b, 4 + 2 + 2)) return (LWRES_R_UNEXPECTEDEND); flags = lwres_buffer_getuint32(b); naliases = lwres_buffer_getuint16(b); naddrs = lwres_buffer_getuint16(b); gabn = CTXMALLOC(sizeof(lwres_gabnresponse_t)); if (gabn == NULL) return (LWRES_R_NOMEMORY); gabn->aliases = NULL; gabn->aliaslen = NULL; LWRES_LIST_INIT(gabn->addrs); gabn->base = NULL; gabn->flags = flags; gabn->naliases = naliases; gabn->naddrs = naddrs; LWRES_LIST_INIT(addrlist); if (naliases > 0) { gabn->aliases = CTXMALLOC(sizeof(char *) * naliases); if (gabn->aliases == NULL) { ret = LWRES_R_NOMEMORY; goto out; } gabn->aliaslen = CTXMALLOC(sizeof(lwres_uint16_t) * naliases); if (gabn->aliaslen == NULL) { ret = LWRES_R_NOMEMORY; goto out; } } for (x = 0; x < naddrs; x++) { addr = CTXMALLOC(sizeof(lwres_addr_t)); if (addr == NULL) { ret = LWRES_R_NOMEMORY; goto out; } LWRES_LINK_INIT(addr, link); LWRES_LIST_APPEND(addrlist, addr, link); } /* * Now, pull off the real name. */ ret = lwres_string_parse(b, &gabn->realname, &gabn->realnamelen); if (ret != LWRES_R_SUCCESS) goto out; /* * Parse off the aliases. */ for (x = 0; x < gabn->naliases; x++) { ret = lwres_string_parse(b, &gabn->aliases[x], &gabn->aliaslen[x]); if (ret != LWRES_R_SUCCESS) goto out; } /* * Pull off the addresses. We already strung the linked list * up above. */ addr = LWRES_LIST_HEAD(addrlist); for (x = 0; x < gabn->naddrs; x++) { INSIST(addr != NULL); ret = lwres_addr_parse(b, addr); if (ret != LWRES_R_SUCCESS) goto out; addr = LWRES_LIST_NEXT(addr, link); } if (LWRES_BUFFER_REMAINING(b) != 0) { ret = LWRES_R_TRAILINGDATA; goto out; } gabn->addrs = addrlist; *structp = gabn; return (LWRES_R_SUCCESS); out: if (gabn != NULL) { if (gabn->aliases != NULL) CTXFREE(gabn->aliases, sizeof(char *) * naliases); if (gabn->aliaslen != NULL) CTXFREE(gabn->aliaslen, sizeof(lwres_uint16_t) * naliases); addr = LWRES_LIST_HEAD(addrlist); while (addr != NULL) { LWRES_LIST_UNLINK(addrlist, addr, link); CTXFREE(addr, sizeof(lwres_addr_t)); addr = LWRES_LIST_HEAD(addrlist); } CTXFREE(gabn, sizeof(lwres_gabnresponse_t)); } return (ret); } /*% Release the memory in resolver context ctx that was allocated to the lwres_gabnrequest_t. */ void lwres_gabnrequest_free(lwres_context_t *ctx, lwres_gabnrequest_t **structp) { lwres_gabnrequest_t *gabn; REQUIRE(ctx != NULL); REQUIRE(structp != NULL && *structp != NULL); gabn = *structp; *structp = NULL; CTXFREE(gabn, sizeof(lwres_gabnrequest_t)); } /*% Release the memory in resolver context ctx that was allocated to the lwres_gabnresponse_t. */ void lwres_gabnresponse_free(lwres_context_t *ctx, lwres_gabnresponse_t **structp) { lwres_gabnresponse_t *gabn; lwres_addr_t *addr; REQUIRE(ctx != NULL); REQUIRE(structp != NULL && *structp != NULL); gabn = *structp; *structp = NULL; if (gabn->naliases > 0) { CTXFREE(gabn->aliases, sizeof(char *) * gabn->naliases); CTXFREE(gabn->aliaslen, sizeof(lwres_uint16_t) * gabn->naliases); } addr = LWRES_LIST_HEAD(gabn->addrs); while (addr != NULL) { LWRES_LIST_UNLINK(gabn->addrs, addr, link); CTXFREE(addr, sizeof(lwres_addr_t)); addr = LWRES_LIST_HEAD(gabn->addrs); } if (gabn->base != NULL) CTXFREE(gabn->base, gabn->baselen); CTXFREE(gabn, sizeof(lwres_gabnresponse_t)); } bind9-9.10.3.dfsg.P4/lib/lwres/print_p.h0000644000470500017500000000503212664710322017117 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: print_p.h,v 1.6 2010/08/16 23:46:52 tbox Exp $ */ #ifndef LWRES_PRINT_P_H #define LWRES_PRINT_P_H 1 /*** *** Imports ***/ #include #include /* * This block allows lib/lwres/print.c to be cleanly compiled even if * the platform does not need it. The standard Makefile will still * not compile print.c or archive print.o, so this is just to make test * compilation ("make print.o") easier. */ #if !defined(LWRES_PLATFORM_NEEDVSNPRINTF) && defined(LWRES__PRINT_SOURCE) #define LWRES_PLATFORM_NEEDVSNPRINTF #endif #if !defined(LWRES_PLATFORM_NEEDSPRINTF) && defined(LWRES__PRINT_SOURCE) #define LWRES_PLATFORM_NEEDSPRINTF #endif /*** *** Macros. ***/ #ifdef __GNUC__ #define LWRES_FORMAT_PRINTF(fmt, args) \ __attribute__((__format__(__printf__, fmt, args))) #else #define LWRES_FORMAT_PRINTF(fmt, args) #endif /*** *** Functions ***/ #ifdef LWRES_PLATFORM_NEEDVSNPRINTF #include #include #endif LWRES_LANG_BEGINDECLS #ifdef LWRES_PLATFORM_NEEDVSNPRINTF int lwres__print_vsnprintf(char *str, size_t size, const char *format, va_list ap) LWRES_FORMAT_PRINTF(3, 0); #ifdef vsnprintf #undef vsnprintf #endif #define vsnprintf lwres__print_vsnprintf int lwres__print_snprintf(char *str, size_t size, const char *format, ...) LWRES_FORMAT_PRINTF(3, 4); #ifdef snprintf #undef snprintf #endif #define snprintf lwres__print_snprintf #endif /* LWRES_PLATFORM_NEEDVSNPRINTF */ #ifdef LWRES_PLATFORM_NEEDSPRINTF int lwres__print_sprintf(char *str, const char *format, ...) LWRES_FORMAT_PRINTF(2, 3); #ifdef sprintf #undef sprintf #endif #define sprintf lwres__print_sprintf #endif LWRES_LANG_ENDDECLS #endif /* LWRES_PRINT_P_H */ bind9-9.10.3.dfsg.P4/lib/lwres/getnameinfo.c0000644000470500017500000002347612664710322017747 0ustar lamontlamont/* * Portions Copyright (C) 2004, 2005, 2007, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * 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. Neither the name of the project 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 PROJECT 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 PROJECT 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. */ /* * XXX * Issues to be discussed: * - Return values. There seems to be no standard for return value (RFC2553) * but INRIA implementation returns EAI_xxx defined for getaddrinfo(). */ /** * This function is equivalent to the getnameinfo(3) function defined in * RFC2133. lwres_getnameinfo() returns the hostname for the struct * sockaddr sa which is salen bytes long. The hostname is of length * hostlen and is returned via *host. The maximum length of the hostname * is 1025 bytes: #NI_MAXHOST. * * The name of the service associated with the port number in sa is * returned in *serv. It is servlen bytes long. The maximum length of the * service name is #NI_MAXSERV - 32 bytes. * * The flags argument sets the following bits: * * \li #NI_NOFQDN: * A fully qualified domain name is not required for local hosts. * The local part of the fully qualified domain name is returned * instead. * * \li #NI_NUMERICHOST * Return the address in numeric form, as if calling inet_ntop(), * instead of a host name. * * \li #NI_NAMEREQD * A name is required. If the hostname cannot be found in the DNS * and this flag is set, a non-zero error code is returned. If the * hostname is not found and the flag is not set, the address is * returned in numeric form. * * \li #NI_NUMERICSERV * The service name is returned as a digit string representing the * port number. * * \li #NI_DGRAM * Specifies that the service being looked up is a datagram * service, and causes getservbyport() to be called with a second * argument of "udp" instead of its default of "tcp". This is * required for the few ports (512-514) that have different * services for UDP and TCP. * * \section getnameinfo_return Return Values * * lwres_getnameinfo() returns 0 on success or a non-zero error code if * an error occurs. * * \section getname_see See Also * * RFC2133, getservbyport(), * lwres_getnamebyaddr(). lwres_net_ntop(). * * \section getnameinfo_bugs Bugs * * RFC2133 fails to define what the nonzero return values of * getnameinfo() are. */ #include #include #include #include #include #include #include "print_p.h" #include "assert_p.h" #define SUCCESS 0 /*% afd structure definition */ static struct afd { int a_af; size_t a_addrlen; size_t a_socklen; } afdl [] = { /*! * First entry is linked last... */ { AF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in) }, { AF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6) }, {0, 0, 0}, }; #define ENI_NOSERVNAME 1 #define ENI_NOHOSTNAME 2 #define ENI_MEMORY 3 #define ENI_SYSTEM 4 #define ENI_FAMILY 5 #define ENI_SALEN 6 #define ENI_NOSOCKET 7 /*! * The test against 0 is there to keep the Solaris compiler * from complaining about "end-of-loop code not reached". */ #define ERR(code) \ do { result = (code); \ if (result != 0) goto cleanup; \ } while (0) /*% lightweight resolver socket address structure to hostname and service name */ int lwres_getnameinfo(const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) { struct afd *afd = NULL; struct servent *sp; unsigned short port; #ifdef LWRES_PLATFORM_HAVESALEN size_t len; #endif int family, i; const void *addr; char *p; #if 0 unsigned long v4a; unsigned char pfx; #endif char numserv[sizeof("65000")]; char numaddr[sizeof("abcd:abcd:abcd:abcd:abcd:abcd:255.255.255.255") + 1 + sizeof("4294967295")]; const char *proto; lwres_uint32_t lwf = 0; lwres_context_t *lwrctx = NULL; lwres_gnbaresponse_t *by = NULL; int result = SUCCESS; int n; if (sa == NULL) ERR(ENI_NOSOCKET); #ifdef LWRES_PLATFORM_HAVESALEN len = sa->sa_len; if (len != salen) ERR(ENI_SALEN); #endif family = sa->sa_family; for (i = 0; afdl[i].a_af; i++) if (afdl[i].a_af == family) { afd = &afdl[i]; goto found; } ERR(ENI_FAMILY); found: if (salen != afd->a_socklen) ERR(ENI_SALEN); switch (family) { case AF_INET: port = ((const struct sockaddr_in *)sa)->sin_port; addr = &((const struct sockaddr_in *)sa)->sin_addr.s_addr; break; case AF_INET6: port = ((const struct sockaddr_in6 *)sa)->sin6_port; addr = ((const struct sockaddr_in6 *)sa)->sin6_addr.s6_addr; break; default: port = 0; addr = NULL; POST(port); POST(addr); INSIST(0); } proto = (flags & NI_DGRAM) ? "udp" : "tcp"; if (serv == NULL || servlen == 0U) { /* * Caller does not want service. */ } else if ((flags & NI_NUMERICSERV) != 0 || (sp = getservbyport(port, proto)) == NULL) { snprintf(numserv, sizeof(numserv), "%d", ntohs(port)); if ((strlen(numserv) + 1) > servlen) ERR(ENI_MEMORY); strcpy(serv, numserv); } else { if ((strlen(sp->s_name) + 1) > servlen) ERR(ENI_MEMORY); strcpy(serv, sp->s_name); } #if 0 switch (sa->sa_family) { case AF_INET: v4a = ((struct sockaddr_in *)sa)->sin_addr.s_addr; if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) flags |= NI_NUMERICHOST; v4a >>= IN_CLASSA_NSHIFT; if (v4a == 0 || v4a == IN_LOOPBACKNET) flags |= NI_NUMERICHOST; break; case AF_INET6: pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[0]; if (pfx == 0 || pfx == 0xfe || pfx == 0xff) flags |= NI_NUMERICHOST; break; } #endif if (host == NULL || hostlen == 0U) { /* * What should we do? */ } else if (flags & NI_NUMERICHOST) { if (lwres_net_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) == NULL) ERR(ENI_SYSTEM); #if defined(LWRES_HAVE_SIN6_SCOPE_ID) if (afd->a_af == AF_INET6 && ((const struct sockaddr_in6 *)sa)->sin6_scope_id) { char *p = numaddr + strlen(numaddr); const char *stringscope = NULL; #if 0 if ((flags & NI_NUMERICSCOPE) == 0) { /* * Vendors may want to add support for * non-numeric scope identifier. */ stringscope = foo; } #endif if (stringscope == NULL) { snprintf(p, sizeof(numaddr) - (p - numaddr), "%%%u", ((const struct sockaddr_in6 *)sa)->sin6_scope_id); } else { snprintf(p, sizeof(numaddr) - (p - numaddr), "%%%s", stringscope); } } #endif if (strlen(numaddr) + 1 > hostlen) ERR(ENI_MEMORY); strcpy(host, numaddr); } else { switch (family) { case AF_INET: lwf = LWRES_ADDRTYPE_V4; break; case AF_INET6: lwf = LWRES_ADDRTYPE_V6; break; default: INSIST(0); } n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0); if (n == 0) (void) lwres_conf_parse(lwrctx, lwres_resolv_conf); if (n == 0) n = lwres_getnamebyaddr(lwrctx, lwf, (lwres_uint16_t)afd->a_addrlen, addr, &by); if (n == 0) { if (flags & NI_NOFQDN) { p = strchr(by->realname, '.'); if (p) *p = '\0'; } if ((strlen(by->realname) + 1) > hostlen) ERR(ENI_MEMORY); strcpy(host, by->realname); } else { if (flags & NI_NAMEREQD) ERR(ENI_NOHOSTNAME); if (lwres_net_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) == NULL) ERR(ENI_NOHOSTNAME); if ((strlen(numaddr) + 1) > hostlen) ERR(ENI_MEMORY); strcpy(host, numaddr); } } result = SUCCESS; cleanup: if (by != NULL) lwres_gnbaresponse_free(lwrctx, &by); if (lwrctx != NULL) { lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); } return (result); } bind9-9.10.3.dfsg.P4/lib/lwres/lwresutil.c0000644000470500017500000003462312664710322017501 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lwresutil.c,v 1.34 2007/06/19 23:47:22 tbox Exp $ */ /*! \file */ /** * lwres_string_parse() retrieves a DNS-encoded string starting the * current pointer of lightweight resolver buffer b: i.e. b->current. * When the function returns, the address of the first byte of the * encoded string is returned via *c and the length of that string is * given by *len. The buffer's current pointer is advanced to point at * the character following the string length, the encoded string, and * the trailing NULL character. * * lwres_addr_parse() extracts an address from the buffer b. The * buffer's current pointer b->current is presumed to point at an * encoded address: the address preceded by a 32-bit protocol family * identifier and a 16-bit length field. The encoded address is copied * to addr->address and addr->length indicates the size in bytes of * the address that was copied. b->current is advanced to point at the * next byte of available data in the buffer following the encoded * address. * * lwres_getaddrsbyname() and lwres_getnamebyaddr() use the * lwres_gnbaresponse_t structure defined below: * * \code * typedef struct { * lwres_uint32_t flags; * lwres_uint16_t naliases; * lwres_uint16_t naddrs; * char *realname; * char **aliases; * lwres_uint16_t realnamelen; * lwres_uint16_t *aliaslen; * lwres_addrlist_t addrs; * void *base; * size_t baselen; * } lwres_gabnresponse_t; * \endcode * * The contents of this structure are not manipulated directly but * they are controlled through the \link lwres_gabn.c lwres_gabn*\endlink functions. * * The lightweight resolver uses lwres_getaddrsbyname() to perform * foward lookups. Hostname name is looked up using the resolver * context ctx for memory allocation. addrtypes is a bitmask * indicating which type of addresses are to be looked up. Current * values for this bitmask are #LWRES_ADDRTYPE_V4 for IPv4 addresses * and #LWRES_ADDRTYPE_V6 for IPv6 addresses. Results of the lookup are * returned in *structp. * * lwres_getnamebyaddr() performs reverse lookups. Resolver context * ctx is used for memory allocation. The address type is indicated by * addrtype: #LWRES_ADDRTYPE_V4 or #LWRES_ADDRTYPE_V6. The address to be * looked up is given by addr and its length is addrlen bytes. The * result of the function call is made available through *structp. * * \section lwresutil_return Return Values * * Successful calls to lwres_string_parse() and lwres_addr_parse() * return #LWRES_R_SUCCESS. Both functions return #LWRES_R_FAILURE if * the buffer is corrupt or #LWRES_R_UNEXPECTEDEND if the buffer has * less space than expected for the components of the encoded string * or address. * * lwres_getaddrsbyname() returns #LWRES_R_SUCCESS on success and it * returns #LWRES_R_NOTFOUND if the hostname name could not be found. * * #LWRES_R_SUCCESS is returned by a successful call to * lwres_getnamebyaddr(). * * Both lwres_getaddrsbyname() and lwres_getnamebyaddr() return * #LWRES_R_NOMEMORY when memory allocation requests fail and * #LWRES_R_UNEXPECTEDEND if the buffers used for sending queries and * receiving replies are too small. * * \section lwresutil_see See Also * * lwbuffer.c, lwres_gabn.c */ #include #include #include #include #include #include #include #include #include "assert_p.h" #include "context_p.h" /*% Parse data. */ /*! * Requires: * * The "current" pointer in "b" points to encoded raw data. * * Ensures: * * The address of the first byte of the data is returned via "p", * and the length is returned via "len". If NULL, they are not * set. * * On return, the current pointer of "b" will point to the character * following the data length and the data. * */ lwres_result_t lwres_data_parse(lwres_buffer_t *b, unsigned char **p, lwres_uint16_t *len) { lwres_uint16_t datalen; unsigned char *data; REQUIRE(b != NULL); /* * Pull off the length (2 bytes) */ if (!SPACE_REMAINING(b, 2)) return (LWRES_R_UNEXPECTEDEND); datalen = lwres_buffer_getuint16(b); /* * Set the pointer to this string to the right place, then * advance the buffer pointer. */ if (!SPACE_REMAINING(b, datalen)) return (LWRES_R_UNEXPECTEDEND); data = b->base + b->current; lwres_buffer_forward(b, datalen); if (len != NULL) *len = datalen; if (p != NULL) *p = data; return (LWRES_R_SUCCESS); } /*% Retrieves a DNS-encoded string. */ /*! * Requires: * * The "current" pointer in "b" point to an encoded string. * * Ensures: * * The address of the first byte of the string is returned via "c", * and the length is returned via "len". If NULL, they are not * set. * * On return, the current pointer of "b" will point to the character * following the string length, the string, and the trailing NULL. * */ lwres_result_t lwres_string_parse(lwres_buffer_t *b, char **c, lwres_uint16_t *len) { lwres_uint16_t datalen; char *string; REQUIRE(b != NULL); /* * Pull off the length (2 bytes) */ if (!SPACE_REMAINING(b, 2)) return (LWRES_R_UNEXPECTEDEND); datalen = lwres_buffer_getuint16(b); /* * Set the pointer to this string to the right place, then * advance the buffer pointer. */ if (!SPACE_REMAINING(b, datalen)) return (LWRES_R_UNEXPECTEDEND); string = (char *)b->base + b->current; lwres_buffer_forward(b, datalen); /* * Skip the "must be zero" byte. */ if (!SPACE_REMAINING(b, 1)) return (LWRES_R_UNEXPECTEDEND); if (0 != lwres_buffer_getuint8(b)) return (LWRES_R_FAILURE); if (len != NULL) *len = datalen; if (c != NULL) *c = string; return (LWRES_R_SUCCESS); } /*% Extracts an address from the buffer b. */ lwres_result_t lwres_addr_parse(lwres_buffer_t *b, lwres_addr_t *addr) { REQUIRE(addr != NULL); if (!SPACE_REMAINING(b, 6)) return (LWRES_R_UNEXPECTEDEND); addr->family = lwres_buffer_getuint32(b); addr->length = lwres_buffer_getuint16(b); if (!SPACE_REMAINING(b, addr->length)) return (LWRES_R_UNEXPECTEDEND); if (addr->length > LWRES_ADDR_MAXLEN) return (LWRES_R_FAILURE); lwres_buffer_getmem(b, addr->address, addr->length); return (LWRES_R_SUCCESS); } /*% Used to perform forward lookups. */ lwres_result_t lwres_getaddrsbyname(lwres_context_t *ctx, const char *name, lwres_uint32_t addrtypes, lwres_gabnresponse_t **structp) { lwres_gabnrequest_t request; lwres_gabnresponse_t *response; int ret; int recvlen; lwres_buffer_t b_in, b_out; lwres_lwpacket_t pkt; lwres_uint32_t serial; char *buffer; char target_name[1024]; unsigned int target_length; REQUIRE(ctx != NULL); REQUIRE(name != NULL); REQUIRE(addrtypes != 0); REQUIRE(structp != NULL && *structp == NULL); b_in.base = NULL; b_out.base = NULL; response = NULL; buffer = NULL; serial = lwres_context_nextserial(ctx); buffer = CTXMALLOC(LWRES_RECVLENGTH); if (buffer == NULL) { ret = LWRES_R_NOMEMORY; goto out; } target_length = strlen(name); if (target_length >= sizeof(target_name)) return (LWRES_R_FAILURE); strcpy(target_name, name); /* strcpy is safe */ /* * Set up our request and render it to a buffer. */ request.flags = 0; request.addrtypes = addrtypes; request.name = target_name; request.namelen = target_length; pkt.pktflags = 0; pkt.serial = serial; pkt.result = 0; pkt.recvlength = LWRES_RECVLENGTH; again: ret = lwres_gabnrequest_render(ctx, &request, &pkt, &b_out); if (ret != LWRES_R_SUCCESS) goto out; ret = lwres_context_sendrecv(ctx, b_out.base, b_out.length, buffer, LWRES_RECVLENGTH, &recvlen); if (ret != LWRES_R_SUCCESS) goto out; lwres_buffer_init(&b_in, buffer, recvlen); b_in.used = recvlen; /* * Parse the packet header. */ ret = lwres_lwpacket_parseheader(&b_in, &pkt); if (ret != LWRES_R_SUCCESS) goto out; /* * Sanity check. */ if (pkt.serial != serial) goto again; if (pkt.opcode != LWRES_OPCODE_GETADDRSBYNAME) goto again; /* * Free what we've transmitted */ CTXFREE(b_out.base, b_out.length); b_out.base = NULL; b_out.length = 0; if (pkt.result != LWRES_R_SUCCESS) { ret = pkt.result; goto out; } /* * Parse the response. */ ret = lwres_gabnresponse_parse(ctx, &b_in, &pkt, &response); if (ret != LWRES_R_SUCCESS) goto out; response->base = buffer; response->baselen = LWRES_RECVLENGTH; buffer = NULL; /* don't free this below */ *structp = response; return (LWRES_R_SUCCESS); out: if (b_out.base != NULL) CTXFREE(b_out.base, b_out.length); if (buffer != NULL) CTXFREE(buffer, LWRES_RECVLENGTH); if (response != NULL) lwres_gabnresponse_free(ctx, &response); return (ret); } /*% Used to perform reverse lookups. */ lwres_result_t lwres_getnamebyaddr(lwres_context_t *ctx, lwres_uint32_t addrtype, lwres_uint16_t addrlen, const unsigned char *addr, lwres_gnbaresponse_t **structp) { lwres_gnbarequest_t request; lwres_gnbaresponse_t *response; int ret; int recvlen; lwres_buffer_t b_in, b_out; lwres_lwpacket_t pkt; lwres_uint32_t serial; char *buffer; REQUIRE(ctx != NULL); REQUIRE(addrtype != 0); REQUIRE(addrlen != 0); REQUIRE(addr != NULL); REQUIRE(structp != NULL && *structp == NULL); b_in.base = NULL; b_out.base = NULL; response = NULL; buffer = NULL; serial = lwres_context_nextserial(ctx); buffer = CTXMALLOC(LWRES_RECVLENGTH); if (buffer == NULL) { ret = LWRES_R_NOMEMORY; goto out; } /* * Set up our request and render it to a buffer. */ request.flags = 0; request.addr.family = addrtype; request.addr.length = addrlen; memmove(request.addr.address, addr, addrlen); pkt.pktflags = 0; pkt.serial = serial; pkt.result = 0; pkt.recvlength = LWRES_RECVLENGTH; again: ret = lwres_gnbarequest_render(ctx, &request, &pkt, &b_out); if (ret != LWRES_R_SUCCESS) goto out; ret = lwres_context_sendrecv(ctx, b_out.base, b_out.length, buffer, LWRES_RECVLENGTH, &recvlen); if (ret != LWRES_R_SUCCESS) goto out; lwres_buffer_init(&b_in, buffer, recvlen); b_in.used = recvlen; /* * Parse the packet header. */ ret = lwres_lwpacket_parseheader(&b_in, &pkt); if (ret != LWRES_R_SUCCESS) goto out; /* * Sanity check. */ if (pkt.serial != serial) goto again; if (pkt.opcode != LWRES_OPCODE_GETNAMEBYADDR) goto again; /* * Free what we've transmitted */ CTXFREE(b_out.base, b_out.length); b_out.base = NULL; b_out.length = 0; if (pkt.result != LWRES_R_SUCCESS) { ret = pkt.result; goto out; } /* * Parse the response. */ ret = lwres_gnbaresponse_parse(ctx, &b_in, &pkt, &response); if (ret != LWRES_R_SUCCESS) goto out; response->base = buffer; response->baselen = LWRES_RECVLENGTH; buffer = NULL; /* don't free this below */ *structp = response; return (LWRES_R_SUCCESS); out: if (b_out.base != NULL) CTXFREE(b_out.base, b_out.length); if (buffer != NULL) CTXFREE(buffer, LWRES_RECVLENGTH); if (response != NULL) lwres_gnbaresponse_free(ctx, &response); return (ret); } /*% Get rdata by name. */ lwres_result_t lwres_getrdatabyname(lwres_context_t *ctx, const char *name, lwres_uint16_t rdclass, lwres_uint16_t rdtype, lwres_uint32_t flags, lwres_grbnresponse_t **structp) { int ret; int recvlen; lwres_buffer_t b_in, b_out; lwres_lwpacket_t pkt; lwres_uint32_t serial; char *buffer; lwres_grbnrequest_t request; lwres_grbnresponse_t *response; char target_name[1024]; unsigned int target_length; REQUIRE(ctx != NULL); REQUIRE(name != NULL); REQUIRE(structp != NULL && *structp == NULL); b_in.base = NULL; b_out.base = NULL; response = NULL; buffer = NULL; serial = lwres_context_nextserial(ctx); buffer = CTXMALLOC(LWRES_RECVLENGTH); if (buffer == NULL) { ret = LWRES_R_NOMEMORY; goto out; } target_length = strlen(name); if (target_length >= sizeof(target_name)) return (LWRES_R_FAILURE); strcpy(target_name, name); /* strcpy is safe */ /* * Set up our request and render it to a buffer. */ request.rdclass = rdclass; request.rdtype = rdtype; request.flags = flags; request.name = target_name; request.namelen = target_length; pkt.pktflags = 0; pkt.serial = serial; pkt.result = 0; pkt.recvlength = LWRES_RECVLENGTH; again: ret = lwres_grbnrequest_render(ctx, &request, &pkt, &b_out); if (ret != LWRES_R_SUCCESS) goto out; ret = lwres_context_sendrecv(ctx, b_out.base, b_out.length, buffer, LWRES_RECVLENGTH, &recvlen); if (ret != LWRES_R_SUCCESS) goto out; lwres_buffer_init(&b_in, buffer, recvlen); b_in.used = recvlen; /* * Parse the packet header. */ ret = lwres_lwpacket_parseheader(&b_in, &pkt); if (ret != LWRES_R_SUCCESS) goto out; /* * Sanity check. */ if (pkt.serial != serial) goto again; if (pkt.opcode != LWRES_OPCODE_GETRDATABYNAME) goto again; /* * Free what we've transmitted */ CTXFREE(b_out.base, b_out.length); b_out.base = NULL; b_out.length = 0; if (pkt.result != LWRES_R_SUCCESS) { ret = pkt.result; goto out; } /* * Parse the response. */ ret = lwres_grbnresponse_parse(ctx, &b_in, &pkt, &response); if (ret != LWRES_R_SUCCESS) goto out; response->base = buffer; response->baselen = LWRES_RECVLENGTH; buffer = NULL; /* don't free this below */ *structp = response; return (LWRES_R_SUCCESS); out: if (b_out.base != NULL) CTXFREE(b_out.base, b_out.length); if (buffer != NULL) CTXFREE(buffer, LWRES_RECVLENGTH); if (response != NULL) lwres_grbnresponse_free(ctx, &response); return (ret); } bind9-9.10.3.dfsg.P4/lib/lwres/api0000644000470500017500000000025612664710322015772 0ustar lamontlamont# LIBINTERFACE ranges # 9.6: 50-59, 110-119 # 9.7: 60-79 # 9.8: 80-89, 120-129 # 9.9: 90-109 # 9.9-sub: 130-139 # 9.10: 140-149 LIBINTERFACE = 141 LIBREVISION = 3 LIBAGE = 0 bind9-9.10.3.dfsg.P4/lib/lwres/compat.c0000644000470500017500000001113312664710322016721 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (c) 1990, 1993 * The Regents of the University of California. 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. Neither the name of the University 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 REGENTS 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 */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strtoul.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include #define DE_CONST(konst, var) \ do { \ union { const void *k; void *v; } _u; \ _u.k = konst; \ var = _u.v; \ } while (0) /*! * Convert a string to an unsigned long integer. * * Ignores `locale' stuff. Assumes that the upper and lower case * alphabets and digits are each contiguous. */ unsigned long lwres_strtoul(const char *nptr, char **endptr, int base) { const char *s = nptr; unsigned long acc; unsigned char c; unsigned long cutoff; int neg = 0, any, cutlim; /* * See strtol for comments as to the logic used. */ do { c = *s++; } while (isspace(c)); if (c == '-') { neg = 1; c = *s++; } else if (c == '+') c = *s++; if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == '0' ? 8 : 10; cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; for (acc = 0, any = 0;; c = *s++) { if (!isascii(c)) break; if (isdigit(c)) c -= '0'; else if (isalpha(c)) c -= isupper(c) ? 'A' - 10 : 'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = ULONG_MAX; errno = ERANGE; } else if (neg) /* XXX: acc was declared unsigned! */ acc = -acc; if (endptr != 0) DE_CONST(any ? s - 1 : nptr, *endptr); return (acc); } size_t lwres_strlcpy(char *dst, const char *src, size_t size) { char *d = dst; const char *s = src; size_t n = size; /* Copy as many bytes as will fit */ if (n != 0U && --n != 0U) { do { if ((*d++ = *s++) == 0) break; } while (--n != 0U); } /* Not enough room in dst, add NUL and traverse rest of src */ if (n == 0U) { if (size != 0U) *d = '\0'; /* NUL-terminate dst */ while (*s++) ; } return(s - src - 1); /* count does not include NUL */ } bind9-9.10.3.dfsg.P4/lib/lwres/man/0002755000470500017500000000000012672612753016060 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_buffer.30000644000470500017500000001710512664710322020623 0ustar lamontlamont.\" Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: lwres_buffer .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: June 18, 2007 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "LWRES_BUFFER" "3" "June 18, 2007" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" lwres_buffer_init, lwres_buffer_invalidate, lwres_buffer_add, lwres_buffer_subtract, lwres_buffer_clear, lwres_buffer_first, lwres_buffer_forward, lwres_buffer_back, lwres_buffer_getuint8, lwres_buffer_putuint8, lwres_buffer_getuint16, lwres_buffer_putuint16, lwres_buffer_getuint32, lwres_buffer_putuint32, lwres_buffer_putmem, lwres_buffer_getmem \- lightweight resolver buffer management .SH "SYNOPSIS" .nf #include .fi .HP 23 .BI "void lwres_buffer_init(lwres_buffer_t\ *" "b" ", void\ *" "base" ", unsigned\ int\ " "length" ");" .HP 29 .BI "void lwres_buffer_invalidate(lwres_buffer_t\ *" "b" ");" .HP 22 .BI "void lwres_buffer_add(lwres_buffer_t\ *" "b" ", unsigned\ int\ " "n" ");" .HP 27 .BI "void lwres_buffer_subtract(lwres_buffer_t\ *" "b" ", unsigned\ int\ " "n" ");" .HP 24 .BI "void lwres_buffer_clear(lwres_buffer_t\ *" "b" ");" .HP 24 .BI "void lwres_buffer_first(lwres_buffer_t\ *" "b" ");" .HP 26 .BI "void lwres_buffer_forward(lwres_buffer_t\ *" "b" ", unsigned\ int\ " "n" ");" .HP 23 .BI "void lwres_buffer_back(lwres_buffer_t\ *" "b" ", unsigned\ int\ " "n" ");" .HP 36 .BI "lwres_uint8_t lwres_buffer_getuint8(lwres_buffer_t\ *" "b" ");" .HP 27 .BI "void lwres_buffer_putuint8(lwres_buffer_t\ *" "b" ", lwres_uint8_t\ " "val" ");" .HP 38 .BI "lwres_uint16_t lwres_buffer_getuint16(lwres_buffer_t\ *" "b" ");" .HP 28 .BI "void lwres_buffer_putuint16(lwres_buffer_t\ *" "b" ", lwres_uint16_t\ " "val" ");" .HP 38 .BI "lwres_uint32_t lwres_buffer_getuint32(lwres_buffer_t\ *" "b" ");" .HP 28 .BI "void lwres_buffer_putuint32(lwres_buffer_t\ *" "b" ", lwres_uint32_t\ " "val" ");" .HP 25 .BI "void lwres_buffer_putmem(lwres_buffer_t\ *" "b" ", const\ unsigned\ char\ *" "base" ", unsigned\ int\ " "length" ");" .HP 25 .BI "void lwres_buffer_getmem(lwres_buffer_t\ *" "b" ", unsigned\ char\ *" "base" ", unsigned\ int\ " "length" ");" .SH "DESCRIPTION" .PP These functions provide bounds checked access to a region of memory where data is being read or written. They are based on, and similar to, the isc_buffer_ functions in the ISC library. .PP A buffer is a region of memory, together with a set of related subregions. The \fIused region\fR and the \fIavailable\fR region are disjoint, and their union is the buffer's region. The used region extends from the beginning of the buffer region to the last used byte. The available region extends from one byte greater than the last used byte to the end of the buffer's region. The size of the used region can be changed using various buffer commands. Initially, the used region is empty. .PP The used region is further subdivided into two disjoint regions: the \fIconsumed region\fR and the \fIremaining region\fR. The union of these two regions is the used region. The consumed region extends from the beginning of the used region to the byte before the \fIcurrent\fR offset (if any). The \fIremaining\fR region the current pointer to the end of the used region. The size of the consumed region can be changed using various buffer commands. Initially, the consumed region is empty. .PP The \fIactive region\fR is an (optional) subregion of the remaining region. It extends from the current offset to an offset in the remaining region. Initially, the active region is empty. If the current offset advances beyond the chosen offset, the active region will also be empty. .PP .RS 4 .nf /\-\-\-\-\-\-\-\-\-\-\-\-entire length\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\\\\ /\-\-\-\-\- used region \-\-\-\-\-\\\\/\-\- available \-\-\\\\ +\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ | consumed | remaining | | +\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ a b c d e .fi .RE .sp .PP .RS 4 .nf a == base of buffer. b == current pointer. Can be anywhere between a and d. c == active pointer. Meaningful between b and d. d == used pointer. e == length of buffer. .fi .RE .sp .PP .RS 4 .nf a\-e == entire length of buffer. a\-d == used region. a\-b == consumed region. b\-d == remaining region. b\-c == optional active region. .fi .RE .sp .PP \fBlwres_buffer_init()\fR initializes the \fBlwres_buffer_t\fR \fI*b\fR and assocates it with the memory region of size \fIlength\fR bytes starting at location \fIbase.\fR .PP \fBlwres_buffer_invalidate()\fR marks the buffer \fI*b\fR as invalid. Invalidating a buffer after use is not required, but makes it possible to catch its possible accidental use. .PP The functions \fBlwres_buffer_add()\fR and \fBlwres_buffer_subtract()\fR respectively increase and decrease the used space in buffer \fI*b\fR by \fIn\fR bytes. \fBlwres_buffer_add()\fR checks for buffer overflow and \fBlwres_buffer_subtract()\fR checks for underflow. These functions do not allocate or deallocate memory. They just change the value of used. .PP A buffer is re\-initialised by \fBlwres_buffer_clear()\fR. The function sets used, current and active to zero. .PP \fBlwres_buffer_first\fR makes the consumed region of buffer \fI*p\fR empty by setting current to zero (the start of the buffer). .PP \fBlwres_buffer_forward()\fR increases the consumed region of buffer \fI*b\fR by \fIn\fR bytes, checking for overflow. Similarly, \fBlwres_buffer_back()\fR decreases buffer \fIb\fR's consumed region by \fIn\fR bytes and checks for underflow. .PP \fBlwres_buffer_getuint8()\fR reads an unsigned 8\-bit integer from \fI*b\fR and returns it. \fBlwres_buffer_putuint8()\fR writes the unsigned 8\-bit integer \fIval\fR to buffer \fI*b\fR. .PP \fBlwres_buffer_getuint16()\fR and \fBlwres_buffer_getuint32()\fR are identical to \fBlwres_buffer_putuint8()\fR except that they respectively read an unsigned 16\-bit or 32\-bit integer in network byte order from \fIb\fR. Similarly, \fBlwres_buffer_putuint16()\fR and \fBlwres_buffer_putuint32()\fR writes the unsigned 16\-bit or 32\-bit integer \fIval\fR to buffer \fIb\fR, in network byte order. .PP Arbitrary amounts of data are read or written from a lightweight resolver buffer with \fBlwres_buffer_getmem()\fR and \fBlwres_buffer_putmem()\fR respectively. \fBlwres_buffer_putmem()\fR copies \fIlength\fR bytes of memory at \fIbase\fR to \fIb\fR. Conversely, \fBlwres_buffer_getmem()\fR copies \fIlength\fR bytes of memory from \fIb\fR to \fIbase\fR. .SH "COPYRIGHT" Copyright \(co 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000, 2001 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_getrrsetbyname.html0000644000470500017500000001623212664710322023207 0ustar lamontlamont lwres_getrrsetbyname

Name

lwres_getrrsetbyname, lwres_freerrset — retrieve DNS records

Synopsis

#include <lwres/netdb.h>
int lwres_getrrsetbyname( const char *  hostname,
  unsigned int   rdclass,
  unsigned int   rdtype,
  unsigned int   flags,
  struct rrsetinfo **  res);
void lwres_freerrset( struct rrsetinfo *  rrset);

The following structures are used:

struct  rdatainfo {
        unsigned int            rdi_length;     /* length of data */
        unsigned char           *rdi_data;      /* record data */
};

struct  rrsetinfo {
        unsigned int            rri_flags;      /* RRSET_VALIDATED... */
        unsigned int            rri_rdclass;    /* class number */
        unsigned int            rri_rdtype;     /* RR type number */
        unsigned int            rri_ttl;        /* time to live */
        unsigned int            rri_nrdatas;    /* size of rdatas array */
        unsigned int            rri_nsigs;      /* size of sigs array */
        char                    *rri_name;      /* canonical name */
        struct rdatainfo        *rri_rdatas;    /* individual records */
        struct rdatainfo        *rri_sigs;      /* individual signatures */
};

DESCRIPTION

lwres_getrrsetbyname() gets a set of resource records associated with a hostname, class, and type. hostname is a pointer a to null-terminated string. The flags field is currently unused and must be zero.

After a successful call to lwres_getrrsetbyname(), *res is a pointer to an rrsetinfo structure, containing a list of one or more rdatainfo structures containing resource records and potentially another list of rdatainfo structures containing SIG resource records associated with those records. The members rri_rdclass and rri_rdtype are copied from the parameters. rri_ttl and rri_name are properties of the obtained rrset. The resource records contained in rri_rdatas and rri_sigs are in uncompressed DNS wire format. Properties of the rdataset are represented in the rri_flags bitfield. If the RRSET_VALIDATED bit is set, the data has been DNSSEC validated and the signatures verified.

All of the information returned by lwres_getrrsetbyname() is dynamically allocated: the rrsetinfo and rdatainfo structures, and the canonical host name strings pointed to by the rrsetinfostructure. Memory allocated for the dynamically allocated structures created by a successful call to lwres_getrrsetbyname() is released by lwres_freerrset(). rrset is a pointer to a struct rrset created by a call to lwres_getrrsetbyname().

RETURN VALUES

lwres_getrrsetbyname() returns zero on success, and one of the following error codes if an error occurred:

ERRSET_NONAME

the name does not exist

ERRSET_NODATA

the name exists, but does not have data of the desired type

ERRSET_NOMEMORY

memory could not be allocated

ERRSET_INVAL

a parameter is invalid

ERRSET_FAIL

other failure

SEE ALSO

lwres(3).

bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_gai_strerror.docbook0000644000470500017500000001372012664710322023331 0ustar lamontlamont]> June 18, 2007 lwres_gai_strerror 3 BIND9 2004 2005 2007 2014 Internet Systems Consortium, Inc. ("ISC") 2000 2001 Internet Software Consortium. lwres_gai_strerror print suitable error string #include <lwres/netdb.h> char * gai_strerror int ecode DESCRIPTION lwres_gai_strerror() returns an error message corresponding to an error code returned by getaddrinfo(). The following error codes and their meaning are defined in include/lwres/netdb.h. EAI_ADDRFAMILY address family for hostname not supported EAI_AGAIN temporary failure in name resolution EAI_BADFLAGS invalid value for ai_flags EAI_FAIL non-recoverable failure in name resolution EAI_FAMILY ai_family not supported EAI_MEMORY memory allocation failure EAI_NODATA no address associated with hostname EAI_NONAME hostname or servname not provided, or not known EAI_SERVICE servname not supported for ai_socktype EAI_SOCKTYPE ai_socktype not supported EAI_SYSTEM system error returned in errno The message invalid error code is returned if ecode is out of range. ai_flags, ai_family and ai_socktype are elements of the struct addrinfo used by lwres_getaddrinfo(). SEE ALSO strerror3 , lwres_getaddrinfo3 , getaddrinfo3 , RFC2133 . bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_getnameinfo.html0000644000470500017500000001436612664710322022456 0ustar lamontlamont lwres_getnameinfo

Name

lwres_getnameinfo — lightweight resolver socket address structure to hostname and service name

Synopsis

#include <lwres/netdb.h>
int lwres_getnameinfo( const struct sockaddr *  sa,
  size_t   salen,
  char *  host,
  size_t   hostlen,
  char *  serv,
  size_t   servlen,
  int   flags);

DESCRIPTION

This function is equivalent to the getnameinfo(3) function defined in RFC2133. lwres_getnameinfo() returns the hostname for the struct sockaddr sa which is salen bytes long. The hostname is of length hostlen and is returned via *host. The maximum length of the hostname is 1025 bytes: NI_MAXHOST.

The name of the service associated with the port number in sa is returned in *serv. It is servlen bytes long. The maximum length of the service name is NI_MAXSERV - 32 bytes.

The flags argument sets the following bits:

NI_NOFQDN

A fully qualified domain name is not required for local hosts. The local part of the fully qualified domain name is returned instead.

NI_NUMERICHOST

Return the address in numeric form, as if calling inet_ntop(), instead of a host name.

NI_NAMEREQD

A name is required. If the hostname cannot be found in the DNS and this flag is set, a non-zero error code is returned. If the hostname is not found and the flag is not set, the address is returned in numeric form.

NI_NUMERICSERV

The service name is returned as a digit string representing the port number.

NI_DGRAM

Specifies that the service being looked up is a datagram service, and causes getservbyport() to be called with a second argument of "udp" instead of its default of "tcp". This is required for the few ports (512-514) that have different services for UDP and TCP.

RETURN VALUES

lwres_getnameinfo() returns 0 on success or a non-zero error code if an error occurs.

SEE ALSO

RFC2133, getservbyport(3), lwres(3), lwres_getnameinfo(3), lwres_getnamebyaddr(3). lwres_net_ntop(3).

BUGS

RFC2133 fails to define what the nonzero return values of getnameinfo(3) are.

bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_getaddrinfo.30000644000470500017500000001564412664710322021646 0ustar lamontlamont.\" Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001, 2003 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: lwres_getaddrinfo .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: June 18, 2007 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "LWRES_GETADDRINFO" "3" "June 18, 2007" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" lwres_getaddrinfo, lwres_freeaddrinfo \- socket address structure to host and service name .SH "SYNOPSIS" .nf #include .fi .HP 22 .BI "int lwres_getaddrinfo(const\ char\ *" "hostname" ", const\ char\ *" "servname" ", const\ struct\ addrinfo\ *" "hints" ", struct\ addrinfo\ **" "res" ");" .HP 24 .BI "void lwres_freeaddrinfo(struct\ addrinfo\ *" "ai" ");" .PP If the operating system does not provide a \fBstruct addrinfo\fR, the following structure is used: .PP .RS 4 .nf struct addrinfo { int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ int ai_family; /* PF_xxx */ int ai_socktype; /* SOCK_xxx */ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ size_t ai_addrlen; /* length of ai_addr */ char *ai_canonname; /* canonical name for hostname */ struct sockaddr *ai_addr; /* binary address */ struct addrinfo *ai_next; /* next structure in linked list */ }; .fi .RE .sp .SH "DESCRIPTION" .PP \fBlwres_getaddrinfo()\fR is used to get a list of IP addresses and port numbers for host \fIhostname\fR and service \fIservname\fR. The function is the lightweight resolver's implementation of \fBgetaddrinfo()\fR as defined in RFC2133. \fIhostname\fR and \fIservname\fR are pointers to null\-terminated strings or \fBNULL\fR. \fIhostname\fR is either a host name or a numeric host address string: a dotted decimal IPv4 address or an IPv6 address. \fIservname\fR is either a decimal port number or a service name as listed in \fI/etc/services\fR. .PP \fIhints\fR is an optional pointer to a \fBstruct addrinfo\fR. This structure can be used to provide hints concerning the type of socket that the caller supports or wishes to use. The caller can supply the following structure elements in \fI*hints\fR: .PP \fBai_family\fR .RS 4 The protocol family that should be used. When \fBai_family\fR is set to \fBPF_UNSPEC\fR, it means the caller will accept any protocol family supported by the operating system. .RE .PP \fBai_socktype\fR .RS 4 denotes the type of socket \(em \fBSOCK_STREAM\fR, \fBSOCK_DGRAM\fR or \fBSOCK_RAW\fR \(em that is wanted. When \fBai_socktype\fR is zero the caller will accept any socket type. .RE .PP \fBai_protocol\fR .RS 4 indicates which transport protocol is wanted: IPPROTO_UDP or IPPROTO_TCP. If \fBai_protocol\fR is zero the caller will accept any protocol. .RE .PP \fBai_flags\fR .RS 4 Flag bits. If the \fBAI_CANONNAME\fR bit is set, a successful call to \fBlwres_getaddrinfo()\fR will return a null\-terminated string containing the canonical name of the specified hostname in \fBai_canonname\fR of the first \fBaddrinfo\fR structure returned. Setting the \fBAI_PASSIVE\fR bit indicates that the returned socket address structure is intended for used in a call to \fBbind\fR(2). In this case, if the hostname argument is a \fBNULL\fR pointer, then the IP address portion of the socket address structure will be set to \fBINADDR_ANY\fR for an IPv4 address or \fBIN6ADDR_ANY_INIT\fR for an IPv6 address. .sp When \fBai_flags\fR does not set the \fBAI_PASSIVE\fR bit, the returned socket address structure will be ready for use in a call to \fBconnect\fR(2) for a connection\-oriented protocol or \fBconnect\fR(2), \fBsendto\fR(2), or \fBsendmsg\fR(2) if a connectionless protocol was chosen. The IP address portion of the socket address structure will be set to the loopback address if \fIhostname\fR is a \fBNULL\fR pointer and \fBAI_PASSIVE\fR is not set in \fBai_flags\fR. .sp If \fBai_flags\fR is set to \fBAI_NUMERICHOST\fR it indicates that \fIhostname\fR should be treated as a numeric string defining an IPv4 or IPv6 address and no name resolution should be attempted. .RE .PP All other elements of the \fBstruct addrinfo\fR passed via \fIhints\fR must be zero. .PP A \fIhints\fR of \fBNULL\fR is treated as if the caller provided a \fBstruct addrinfo\fR initialized to zero with \fBai_family\fRset to \fBPF_UNSPEC\fR. .PP After a successful call to \fBlwres_getaddrinfo()\fR, \fI*res\fR is a pointer to a linked list of one or more \fBaddrinfo\fR structures. Each \fBstruct addrinfo\fR in this list cn be processed by following the \fBai_next\fR pointer, until a \fBNULL\fR pointer is encountered. The three members \fBai_family\fR, \fBai_socktype\fR, and \fBai_protocol\fR in each returned \fBaddrinfo\fR structure contain the corresponding arguments for a call to \fBsocket\fR(2). For each \fBaddrinfo\fR structure in the list, the \fBai_addr\fR member points to a filled\-in socket address structure of length \fBai_addrlen\fR. .PP All of the information returned by \fBlwres_getaddrinfo()\fR is dynamically allocated: the addrinfo structures, and the socket address structures and canonical host name strings pointed to by the \fBaddrinfo\fRstructures. Memory allocated for the dynamically allocated structures created by a successful call to \fBlwres_getaddrinfo()\fR is released by \fBlwres_freeaddrinfo()\fR. \fIai\fR is a pointer to a \fBstruct addrinfo\fR created by a call to \fBlwres_getaddrinfo()\fR. .SH "RETURN VALUES" .PP \fBlwres_getaddrinfo()\fR returns zero on success or one of the error codes listed in \fBgai_strerror\fR(3) if an error occurs. If both \fIhostname\fR and \fIservname\fR are \fBNULL\fR \fBlwres_getaddrinfo()\fR returns \fBEAI_NONAME\fR. .SH "SEE ALSO" .PP \fBlwres\fR(3), \fBlwres_getaddrinfo\fR(3), \fBlwres_freeaddrinfo\fR(3), \fBlwres_gai_strerror\fR(3), \fBRFC2133\fR(), \fBgetservbyname\fR(3), \fBbind\fR(2), \fBconnect\fR(2), \fBsendto\fR(2), \fBsendmsg\fR(2), \fBsocket\fR(2). .SH "COPYRIGHT" Copyright \(co 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000, 2001, 2003 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_context.html0000644000470500017500000002522612664710322021643 0ustar lamontlamont lwres_context

Name

lwres_context_create, lwres_context_destroy, lwres_context_nextserial, lwres_context_initserial, lwres_context_freemem, lwres_context_allocmem, lwres_context_sendrecv — lightweight resolver context management

Synopsis

#include <lwres/lwres.h>
lwres_result_t lwres_context_create( lwres_context_t **  contextp,
  void *  arg,
  lwres_malloc_t   malloc_function,
  lwres_free_t   free_function);
lwres_result_t lwres_context_destroy( lwres_context_t **  contextp);
void lwres_context_initserial( lwres_context_t *  ctx,
  lwres_uint32_t   serial);
lwres_uint32_t lwres_context_nextserial( lwres_context_t *  ctx);
void lwres_context_freemem( lwres_context_t *  ctx,
  void *  mem,
  size_t   len);
void lwres_context_allocmem( lwres_context_t *  ctx,
  size_t   len);
void * lwres_context_sendrecv( lwres_context_t *  ctx,
  void *  sendbase,
  int   sendlen,
  void *  recvbase,
  int   recvlen,
  int *  recvd_len);

DESCRIPTION

lwres_context_create() creates a lwres_context_t structure for use in lightweight resolver operations. It holds a socket and other data needed for communicating with a resolver daemon. The new lwres_context_t is returned through contextp, a pointer to a lwres_context_t pointer. This lwres_context_t pointer must initially be NULL, and is modified to point to the newly created lwres_context_t.

When the lightweight resolver needs to perform dynamic memory allocation, it will call malloc_function to allocate memory and free_function to free it. If malloc_function and free_function are NULL, memory is allocated using malloc(3). and free(3). It is not permitted to have a NULL malloc_function and a non-NULL free_function or vice versa. arg is passed as the first parameter to the memory allocation functions. If malloc_function and free_function are NULL, arg is unused and should be passed as NULL.

Once memory for the structure has been allocated, it is initialized using lwres_conf_init(3) and returned via *contextp.

lwres_context_destroy() destroys a lwres_context_t, closing its socket. contextp is a pointer to a pointer to the context that is to be destroyed. The pointer will be set to NULL when the context has been destroyed.

The context holds a serial number that is used to identify resolver request packets and associate responses with the corresponding requests. This serial number is controlled using lwres_context_initserial() and lwres_context_nextserial(). lwres_context_initserial() sets the serial number for context *ctx to serial. lwres_context_nextserial() increments the serial number and returns the previous value.

Memory for a lightweight resolver context is allocated and freed using lwres_context_allocmem() and lwres_context_freemem(). These use whatever allocations were defined when the context was created with lwres_context_create(). lwres_context_allocmem() allocates len bytes of memory and if successful returns a pointer to the allocated storage. lwres_context_freemem() frees len bytes of space starting at location mem.

lwres_context_sendrecv() performs I/O for the context ctx. Data are read and written from the context's socket. It writes data from sendbase — typically a lightweight resolver query packet — and waits for a reply which is copied to the receive buffer at recvbase. The number of bytes that were written to this receive buffer is returned in *recvd_len.

RETURN VALUES

lwres_context_create() returns LWRES_R_NOMEMORY if memory for the struct lwres_context could not be allocated, LWRES_R_SUCCESS otherwise.

Successful calls to the memory allocator lwres_context_allocmem() return a pointer to the start of the allocated space. It returns NULL if memory could not be allocated.

LWRES_R_SUCCESS is returned when lwres_context_sendrecv() completes successfully. LWRES_R_IOERROR is returned if an I/O error occurs and LWRES_R_TIMEOUT is returned if lwres_context_sendrecv() times out waiting for a response.

SEE ALSO

lwres_conf_init(3), malloc(3), free(3).

bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_getipnode.html0000644000470500017500000002364312664710322022136 0ustar lamontlamont lwres_getipnode

Name

lwres_getipnodebyname, lwres_getipnodebyaddr, lwres_freehostent — lightweight resolver nodename / address translation API

Synopsis

#include <lwres/netdb.h>
struct hostent * lwres_getipnodebyname( const char *  name,
  int   af,
  int   flags,
  int *  error_num);
struct hostent * lwres_getipnodebyaddr( const void *  src,
  size_t   len,
  int   af,
  int *  error_num);
void lwres_freehostent( struct hostent *  he);

DESCRIPTION

These functions perform thread safe, protocol independent nodename-to-address and address-to-nodename translation as defined in RFC2553.

They use a struct hostent which is defined in namedb.h:

struct  hostent {
        char    *h_name;        /* official name of host */
        char    **h_aliases;    /* alias list */
        int     h_addrtype;     /* host address type */
        int     h_length;       /* length of address */
        char    **h_addr_list;  /* list of addresses from name server */
};
#define h_addr  h_addr_list[0]  /* address, for backward compatibility */

The members of this structure are:

h_name

The official (canonical) name of the host.

h_aliases

A NULL-terminated array of alternate names (nicknames) for the host.

h_addrtype

The type of address being returned - usually PF_INET or PF_INET6.

h_length

The length of the address in bytes.

h_addr_list

A NULL terminated array of network addresses for the host. Host addresses are returned in network byte order.

lwres_getipnodebyname() looks up addresses of protocol family af for the hostname name. The flags parameter contains ORed flag bits to specify the types of addresses that are searched for, and the types of addresses that are returned. The flag bits are:

AI_V4MAPPED

This is used with an af of AF_INET6, and causes IPv4 addresses to be returned as IPv4-mapped IPv6 addresses.

AI_ALL

This is used with an af of AF_INET6, and causes all known addresses (IPv6 and IPv4) to be returned. If AI_V4MAPPED is also set, the IPv4 addresses are return as mapped IPv6 addresses.

AI_ADDRCONFIG

Only return an IPv6 or IPv4 address if here is an active network interface of that type. This is not currently implemented in the BIND 9 lightweight resolver, and the flag is ignored.

AI_DEFAULT

This default sets the AI_V4MAPPED and AI_ADDRCONFIG flag bits.

lwres_getipnodebyaddr() performs a reverse lookup of address src which is len bytes long. af denotes the protocol family, typically PF_INET or PF_INET6.

lwres_freehostent() releases all the memory associated with the struct hostent pointer he. Any memory allocated for the h_name, h_addr_list and h_aliases is freed, as is the memory for the hostent structure itself.

RETURN VALUES

If an error occurs, lwres_getipnodebyname() and lwres_getipnodebyaddr() set *error_num to an appropriate error code and the function returns a NULL pointer. The error codes and their meanings are defined in <lwres/netdb.h>:

HOST_NOT_FOUND

No such host is known.

NO_ADDRESS

The server recognised the request and the name but no address is available. Another type of request to the name server for the domain might return an answer.

TRY_AGAIN

A temporary and possibly transient error occurred, such as a failure of a server to respond. The request may succeed if retried.

NO_RECOVERY

An unexpected failure occurred, and retrying the request is pointless.

lwres_hstrerror(3) translates these error codes to suitable error messages.

SEE ALSO

RFC2553, lwres(3), lwres_gethostent(3), lwres_getaddrinfo(3), lwres_getnameinfo(3), lwres_hstrerror(3).

bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_gethostent.html0000644000470500017500000004205212664710322022337 0ustar lamontlamont lwres_gethostent

Name

lwres_gethostbyname, lwres_gethostbyname2, lwres_gethostbyaddr, lwres_gethostent, lwres_sethostent, lwres_endhostent, lwres_gethostbyname_r, lwres_gethostbyaddr_r, lwres_gethostent_r, lwres_sethostent_r, lwres_endhostent_r — lightweight resolver get network host entry

Synopsis

#include <lwres/netdb.h>
struct hostent * lwres_gethostbyname( const char *  name);
struct hostent * lwres_gethostbyname2( const char *  name,
  int   af);
struct hostent * lwres_gethostbyaddr( const char *  addr,
  int   len,
  int   type);
struct hostent * lwres_gethostent(   );
void lwres_sethostent( int   stayopen);
void lwres_endhostent(   );
struct hostent * lwres_gethostbyname_r( const char *  name,
  struct hostent *  resbuf,
  char *  buf,
  int   buflen,
  int *  error);
struct hostent * lwres_gethostbyaddr_r( const char *  addr,
  int   len,
  int   type,
  struct hostent *  resbuf,
  char *  buf,
  int   buflen,
  int *  error);
struct hostent * lwres_gethostent_r( struct hostent *  resbuf,
  char *  buf,
  int   buflen,
  int *  error);
void lwres_sethostent_r( int   stayopen);
void lwres_endhostent_r(   );

DESCRIPTION

These functions provide hostname-to-address and address-to-hostname lookups by means of the lightweight resolver. They are similar to the standard gethostent(3) functions provided by most operating systems. They use a struct hostent which is usually defined in <namedb.h>.

struct  hostent {
        char    *h_name;        /* official name of host */
        char    **h_aliases;    /* alias list */
        int     h_addrtype;     /* host address type */
        int     h_length;       /* length of address */
        char    **h_addr_list;  /* list of addresses from name server */
};
#define h_addr  h_addr_list[0]  /* address, for backward compatibility */

The members of this structure are:

h_name

The official (canonical) name of the host.

h_aliases

A NULL-terminated array of alternate names (nicknames) for the host.

h_addrtype

The type of address being returned — PF_INET or PF_INET6.

h_length

The length of the address in bytes.

h_addr_list

A NULL terminated array of network addresses for the host. Host addresses are returned in network byte order.

For backward compatibility with very old software, h_addr is the first address in h_addr_list.

lwres_gethostent(), lwres_sethostent(), lwres_endhostent(), lwres_gethostent_r(), lwres_sethostent_r() and lwres_endhostent_r() provide iteration over the known host entries on systems that provide such functionality through facilities like /etc/hosts or NIS. The lightweight resolver does not currently implement these functions; it only provides them as stub functions that always return failure.

lwres_gethostbyname() and lwres_gethostbyname2() look up the hostname name. lwres_gethostbyname() always looks for an IPv4 address while lwres_gethostbyname2() looks for an address of protocol family af: either PF_INET or PF_INET6 — IPv4 or IPV6 addresses respectively. Successful calls of the functions return a struct hostentfor the name that was looked up. NULL is returned if the lookups by lwres_gethostbyname() or lwres_gethostbyname2() fail.

Reverse lookups of addresses are performed by lwres_gethostbyaddr(). addr is an address of length len bytes and protocol family typePF_INET or PF_INET6. lwres_gethostbyname_r() is a thread-safe function for forward lookups. If an error occurs, an error code is returned in *error. resbuf is a pointer to a struct hostent which is initialised by a successful call to lwres_gethostbyname_r(). buf is a buffer of length len bytes which is used to store the h_name, h_aliases, and h_addr_list elements of the struct hostent returned in resbuf. Successful calls to lwres_gethostbyname_r() return resbuf, which is a pointer to the struct hostent it created.

lwres_gethostbyaddr_r() is a thread-safe function that performs a reverse lookup of address addr which is len bytes long and is of protocol family typePF_INET or PF_INET6. If an error occurs, the error code is returned in *error. The other function parameters are identical to those in lwres_gethostbyname_r(). resbuf is a pointer to a struct hostent which is initialised by a successful call to lwres_gethostbyaddr_r(). buf is a buffer of length len bytes which is used to store the h_name, h_aliases, and h_addr_list elements of the struct hostent returned in resbuf. Successful calls to lwres_gethostbyaddr_r() return resbuf, which is a pointer to the struct hostent() it created.

RETURN VALUES

The functions lwres_gethostbyname(), lwres_gethostbyname2(), lwres_gethostbyaddr(), and lwres_gethostent() return NULL to indicate an error. In this case the global variable lwres_h_errno will contain one of the following error codes defined in <lwres/netdb.h>:

HOST_NOT_FOUND

The host or address was not found.

TRY_AGAIN

A recoverable error occurred, e.g., a timeout. Retrying the lookup may succeed.

NO_RECOVERY

A non-recoverable error occurred.

NO_DATA

The name exists, but has no address information associated with it (or vice versa in the case of a reverse lookup). The code NO_ADDRESS is accepted as a synonym for NO_DATA for backwards compatibility.

lwres_hstrerror(3) translates these error codes to suitable error messages.

lwres_gethostent() and lwres_gethostent_r() always return NULL.

Successful calls to lwres_gethostbyname_r() and lwres_gethostbyaddr_r() return resbuf, a pointer to the struct hostent that was initialised by these functions. They return NULL if the lookups fail or if buf was too small to hold the list of addresses and names referenced by the h_name, h_aliases, and h_addr_list elements of the struct hostent. If buf was too small, both lwres_gethostbyname_r() and lwres_gethostbyaddr_r() set the global variable errno to ERANGE.

SEE ALSO

gethostent(3), lwres_getipnode(3), lwres_hstrerror(3)

BUGS

lwres_gethostbyname(), lwres_gethostbyname2(), lwres_gethostbyaddr() and lwres_endhostent() are not thread safe; they return pointers to static data and provide error codes through a global variable. Thread-safe versions for name and address lookup are provided by lwres_gethostbyname_r(), and lwres_gethostbyaddr_r() respectively.

The resolver daemon does not currently support any non-DNS name services such as /etc/hosts or NIS, consequently the above functions don't, either.

bind9-9.10.3.dfsg.P4/lib/lwres/man/Makefile.in0000644000470500017500000002515512664710322020123 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.9 2007/06/19 23:47:23 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ @BIND9_MAKE_RULES@ # Alphabetically #MANPAGES = lwres.3 lwres_addr_parse.3 lwres_buffer.3 \ # lwres_buffer_add.3 lwres_buffer_back.3 lwres_buffer_clear.3 \ # lwres_buffer_first.3 lwres_buffer_forward.3 \ # lwres_buffer_getmem.3 lwres_buffer_getuint16.3 \ # lwres_buffer_getuint32.3 lwres_buffer_getuint8.3 \ # lwres_buffer_init.3 lwres_buffer_invalidate.3 \ # lwres_buffer_putmem.3 lwres_buffer_putuint16.3 \ # lwres_buffer_putuint32.3 lwres_buffer_putuint8.3 \ # lwres_buffer_subtract.3 lwres_conf_clear.3 \ # lwres_conf_get.3 lwres_conf_init.3 \ # lwres_conf_parse.3 lwres_conf_print.3 \ # lwres_config.3 lwres_context.3 \ # lwres_context_allocmem.3 lwres_context_create.3 \ # lwres_context_destroy.3 lwres_context_freemem.3 \ # lwres_context_initserial.3 lwres_context_nextserial.3 \ # lwres_context_sendrecv.3 lwres_endhostent.3 \ # lwres_endhostent_r.3 lwres_freeaddrinfo.3 \ # lwres_freehostent.3 lwres_gabn.3 \ # lwres_gabnrequest_free.3 lwres_gabnrequest_parse.3 \ # lwres_gabnrequest_render.3 lwres_gabnresponse_free.3 \ # lwres_gabnresponse_parse.3 lwres_gabnresponse_render.3 \ # lwres_gai_strerror.3 lwres_getaddrinfo.3 \ # lwres_getaddrsbyname.3 lwres_gethostbyaddr.3 \ # lwres_gethostbyaddr_r.3 lwres_gethostbyname.3 \ # lwres_gethostbyname2.3 lwres_gethostbyname_r.3 \ # lwres_gethostent.3 lwres_gethostent_r.3 \ # lwres_getipnode.3 lwres_getipnodebyaddr.3 \ # lwres_getipnodebyname.3 lwres_getnamebyaddr.3 \ # lwres_getnameinfo.3 lwres_getrrsetbyname.3 \ # lwres_gnba.3 lwres_gnbarequest_free.3 \ # lwres_gnbarequest_parse.3 lwres_gnbarequest_render.3 \ # lwres_gnbaresponse_free.3 lwres_gnbaresponse_parse.3 \ # lwres_gnbaresponse_render.3 lwres_herror.3 \ # lwres_hstrerror.3 lwres_inetntop.3 \ # lwres_lwpacket_parseheader.3 lwres_lwpacket_renderheader.3 \ # lwres_net_ntop.3 lwres_noop.3 \ # lwres_nooprequest_free.3 lwres_nooprequest_parse.3 \ # lwres_nooprequest_render.3 lwres_noopresponse_free.3 \ # lwres_noopresponse_parse.3 lwres_noopresponse_render.3 \ # lwres_packet.3 lwres_resutil.3 \ # lwres_sethostent.3 lwres_sethostent_r.3 \ # lwres_string_parse.3 MANPAGES = lwres.3 lwres_buffer.3 lwres_config.3 lwres_context.3 \ lwres_gabn.3 lwres_gai_strerror.3 lwres_getaddrinfo.3 \ lwres_gethostent.3 lwres_getipnode.3 lwres_getnameinfo.3 \ lwres_getrrsetbyname.3 lwres_gnba.3 lwres_hstrerror.3 lwres_inetntop.3 \ lwres_noop.3 lwres_packet.3 lwres_resutil.3 HTMLPAGES = lwres.html lwres_buffer.html lwres_config.html lwres_context.html \ lwres_gabn.html lwres_gai_strerror.html lwres_getaddrinfo.html \ lwres_gethostent.html lwres_getipnode.html lwres_getnameinfo.html \ lwres_getrrsetbyname.html lwres_gnba.html lwres_hstrerror.html lwres_inetntop.html \ lwres_noop.html lwres_packet.html lwres_resutil.html MANOBJS = ${MANPAGES} ${HTMLPAGES} doc man:: ${MANOBJS} docclean manclean maintainer-clean:: rm -f ${MANOBJS} installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man3 man3 = ${DESTDIR}${mandir}/man3 install:: installdirs for m in ${MANPAGES}; do ${INSTALL_DATA} ${srcdir}/$$m ${DESTDIR}${mandir}/man3; done rm -f ${man3}/lwres_addr_parse.3 @LN@ ${man3}/lwres_resutil.3 ${man3}/lwres_addr_parse.3 rm -f ${man3}/lwres_buffer_add.3 @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_add.3 rm -f ${man3}/lwres_buffer_back.3 @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_back.3 rm -f ${man3}/lwres_buffer_clear.3 @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_clear.3 rm -f ${man3}/lwres_buffer_first.3 @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_first.3 rm -f ${man3}/lwres_buffer_forward.3 @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_forward.3 rm -f ${man3}/lwres_buffer_getmem.3 @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_getmem.3 rm -f ${man3}/lwres_buffer_getuint16.3 @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_getuint16.3 rm -f ${man3}/lwres_buffer_getuint32.3 @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_getuint32.3 rm -f ${man3}/lwres_buffer_getuint8.3 @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_getuint8.3 rm -f ${man3}/lwres_buffer_init.3 @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_init.3 rm -f ${man3}/lwres_buffer_invalidate.3 @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_invalidate.3 rm -f ${man3}/lwres_buffer_putmem.3 @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_putmem.3 rm -f ${man3}/lwres_buffer_putuint16.3 @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_putuint16.3 rm -f ${man3}/lwres_buffer_putuint32.3 @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_putuint32.3 rm -f ${man3}/lwres_buffer_putuint8.3 @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_putuint8.3 rm -f ${man3}/lwres_buffer_subtract.3 @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_subtract.3 rm -f ${man3}/lwres_conf_clear.3 @LN@ ${man3}/lwres_config.3 ${man3}/lwres_conf_clear.3 rm -f ${man3}/lwres_conf_get.3 @LN@ ${man3}/lwres_config.3 ${man3}/lwres_conf_get.3 rm -f ${man3}/lwres_conf_init.3 @LN@ ${man3}/lwres_config.3 ${man3}/lwres_conf_init.3 rm -f ${man3}/lwres_conf_parse.3 @LN@ ${man3}/lwres_config.3 ${man3}/lwres_conf_parse.3 rm -f ${man3}/lwres_conf_print.3 @LN@ ${man3}/lwres_config.3 ${man3}/lwres_conf_print.3 rm -f ${man3}/lwres_context_allocmem.3 @LN@ ${man3}/lwres_context.3 ${man3}/lwres_context_allocmem.3 rm -f ${man3}/lwres_context_create.3 @LN@ ${man3}/lwres_context.3 ${man3}/lwres_context_create.3 rm -f ${man3}/lwres_context_destroy.3 @LN@ ${man3}/lwres_context.3 ${man3}/lwres_context_destroy.3 rm -f ${man3}/lwres_context_freemem.3 @LN@ ${man3}/lwres_context.3 ${man3}/lwres_context_freemem.3 rm -f ${man3}/lwres_context_initserial.3 @LN@ ${man3}/lwres_context.3 ${man3}/lwres_context_initserial.3 rm -f ${man3}/lwres_context_nextserial.3 @LN@ ${man3}/lwres_context.3 ${man3}/lwres_context_nextserial.3 rm -f ${man3}/lwres_context_sendrecv.3 @LN@ ${man3}/lwres_context.3 ${man3}/lwres_context_sendrecv.3 rm -f ${man3}/lwres_endhostent.3 @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_endhostent.3 rm -f ${man3}/lwres_endhostent_r.3 @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_endhostent_r.3 rm -f ${man3}/lwres_freeaddrinfo.3 @LN@ ${man3}/lwres_getaddrinfo.3 ${man3}/lwres_freeaddrinfo.3 rm -f ${man3}/lwres_freehostent.3 @LN@ ${man3}/lwres_getipnode.3 ${man3}/lwres_freehostent.3 rm -f ${man3}/lwres_gabnrequest_free.3 @LN@ ${man3}/lwres_gabn.3 ${man3}/lwres_gabnrequest_free.3 rm -f ${man3}/lwres_gabnrequest_parse.3 @LN@ ${man3}/lwres_gabn.3 ${man3}/lwres_gabnrequest_parse.3 rm -f ${man3}/lwres_gabnrequest_render.3 @LN@ ${man3}/lwres_gabn.3 ${man3}/lwres_gabnrequest_render.3 rm -f ${man3}/lwres_gabnresponse_free.3 @LN@ ${man3}/lwres_gabn.3 ${man3}/lwres_gabnresponse_free.3 rm -f ${man3}/lwres_gabnresponse_parse.3 @LN@ ${man3}/lwres_gabn.3 ${man3}/lwres_gabnresponse_parse.3 rm -f ${man3}/lwres_gabnresponse_render.3 @LN@ ${man3}/lwres_gabn.3 ${man3}/lwres_gabnresponse_render.3 rm -f ${man3}/lwres_getaddrsbyname.3 @LN@ ${man3}/lwres_resutil.3 ${man3}/lwres_getaddrsbyname.3 rm -f ${man3}/lwres_gethostbyaddr.3 @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_gethostbyaddr.3 rm -f ${man3}/lwres_gethostbyaddr_r.3 @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_gethostbyaddr_r.3 rm -f ${man3}/lwres_gethostbyname.3 @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_gethostbyname.3 rm -f ${man3}/lwres_gethostbyname2.3 @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_gethostbyname2.3 rm -f ${man3}/lwres_gethostbyname_r.3 @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_gethostbyname_r.3 rm -f ${man3}/lwres_gethostent_r.3 @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_gethostent_r.3 rm -f ${man3}/lwres_getipnodebyaddr.3 @LN@ ${man3}/lwres_getipnode.3 ${man3}/lwres_getipnodebyaddr.3 rm -f ${man3}/lwres_getipnodebyname.3 @LN@ ${man3}/lwres_getipnode.3 ${man3}/lwres_getipnodebyname.3 rm -f ${man3}/lwres_getnamebyaddr.3 @LN@ ${man3}/lwres_resutil.3 ${man3}/lwres_getnamebyaddr.3 rm -f ${man3}/lwres_gnbarequest_free.3 @LN@ ${man3}/lwres_gnba.3 ${man3}/lwres_gnbarequest_free.3 rm -f ${man3}/lwres_gnbarequest_parse.3 @LN@ ${man3}/lwres_gnba.3 ${man3}/lwres_gnbarequest_parse.3 rm -f ${man3}/lwres_gnbarequest_render.3 @LN@ ${man3}/lwres_gnba.3 ${man3}/lwres_gnbarequest_render.3 rm -f ${man3}/lwres_gnbaresponse_free.3 @LN@ ${man3}/lwres_gnba.3 ${man3}/lwres_gnbaresponse_free.3 rm -f ${man3}/lwres_gnbaresponse_parse.3 @LN@ ${man3}/lwres_gnba.3 ${man3}/lwres_gnbaresponse_parse.3 rm -f ${man3}/lwres_gnbaresponse_render.3 @LN@ ${man3}/lwres_gnba.3 ${man3}/lwres_gnbaresponse_render.3 rm -f ${man3}/lwres_herror.3 @LN@ ${man3}/lwres_hstrerror.3 ${man3}/lwres_herror.3 rm -f ${man3}/lwres_lwpacket_parseheader.3 @LN@ ${man3}/lwres_packet.3 ${man3}/lwres_lwpacket_parseheader.3 rm -f ${man3}/lwres_lwpacket_renderheader.3 @LN@ ${man3}/lwres_packet.3 ${man3}/lwres_lwpacket_renderheader.3 rm -f ${man3}/lwres_net_ntop.3 @LN@ ${man3}/lwres_inetntop.3 ${man3}/lwres_net_ntop.3 rm -f ${man3}/lwres_nooprequest_free.3 @LN@ ${man3}/lwres_noop.3 ${man3}/lwres_nooprequest_free.3 rm -f ${man3}/lwres_nooprequest_parse.3 @LN@ ${man3}/lwres_noop.3 ${man3}/lwres_nooprequest_parse.3 rm -f ${man3}/lwres_nooprequest_render.3 @LN@ ${man3}/lwres_noop.3 ${man3}/lwres_nooprequest_render.3 rm -f ${man3}/lwres_noopresponse_free.3 @LN@ ${man3}/lwres_noop.3 ${man3}/lwres_noopresponse_free.3 rm -f ${man3}/lwres_noopresponse_parse.3 @LN@ ${man3}/lwres_noop.3 ${man3}/lwres_noopresponse_parse.3 rm -f ${man3}/lwres_noopresponse_render.3 @LN@ ${man3}/lwres_noop.3 ${man3}/lwres_noopresponse_render.3 rm -f ${man3}/lwres_sethostent.3 @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_sethostent.3 rm -f ${man3}/lwres_sethostent_r.3 @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_sethostent_r.3 rm -f ${man3}/lwres_string_parse.3 @LN@ ${man3}/lwres_resutil.3 ${man3}/lwres_string_parse.3 bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_packet.html0000644000470500017500000002176012664710322021425 0ustar lamontlamont lwres_packet

Name

lwres_lwpacket_renderheader, lwres_lwpacket_parseheader — lightweight resolver packet handling functions

Synopsis

#include <lwres/lwpacket.h>
lwres_result_t lwres_lwpacket_renderheader( lwres_buffer_t *  b,
  lwres_lwpacket_t *  pkt);
lwres_result_t lwres_lwpacket_parseheader( lwres_buffer_t *  b,
  lwres_lwpacket_t *  pkt);

DESCRIPTION

These functions rely on a struct lwres_lwpacket which is defined in lwres/lwpacket.h.

typedef struct lwres_lwpacket lwres_lwpacket_t;
      

struct lwres_lwpacket {
        lwres_uint32_t          length;
        lwres_uint16_t          version;
        lwres_uint16_t          pktflags;
        lwres_uint32_t          serial;
        lwres_uint32_t          opcode;
        lwres_uint32_t          result;
        lwres_uint32_t          recvlength;
        lwres_uint16_t          authtype;
        lwres_uint16_t          authlength;
};

The elements of this structure are:

length

the overall packet length, including the entire packet header. This field is filled in by the lwres_gabn_*() and lwres_gnba_*() calls.

version

the header format. There is currently only one format, LWRES_LWPACKETVERSION_0. This field is filled in by the lwres_gabn_*() and lwres_gnba_*() calls.

pktflags

library-defined flags for this packet: for instance whether the packet is a request or a reply. Flag values can be set, but not defined by the caller. This field is filled in by the application wit the exception of the LWRES_LWPACKETFLAG_RESPONSE bit, which is set by the library in the lwres_gabn_*() and lwres_gnba_*() calls.

serial

is set by the requestor and is returned in all replies. If two or more packets from the same source have the same serial number and are from the same source, they are assumed to be duplicates and the latter ones may be dropped. This field must be set by the application.

opcode

indicates the operation. Opcodes between 0x00000000 and 0x03ffffff are reserved for use by the lightweight resolver library. Opcodes between 0x04000000 and 0xffffffff are application defined. This field is filled in by the lwres_gabn_*() and lwres_gnba_*() calls.

result

is only valid for replies. Results between 0x04000000 and 0xffffffff are application defined. Results between 0x00000000 and 0x03ffffff are reserved for library use. This field is filled in by the lwres_gabn_*() and lwres_gnba_*() calls.

recvlength

is the maximum buffer size that the receiver can handle on requests and the size of the buffer needed to satisfy a request when the buffer is too large for replies. This field is supplied by the application.

authtype

defines the packet level authentication that is used. Authorisation types between 0x1000 and 0xffff are application defined and types between 0x0000 and 0x0fff are reserved for library use. Currently these are not used and must be zero.

authlen

gives the length of the authentication data. Since packet authentication is currently not used, this must be zero.

The following opcodes are currently defined:

NOOP

Success is always returned and the packet contents are echoed. The lwres_noop_*() functions should be used for this type.

GETADDRSBYNAME

returns all known addresses for a given name. The lwres_gabn_*() functions should be used for this type.

GETNAMEBYADDR

return the hostname for the given address. The lwres_gnba_*() functions should be used for this type.

lwres_lwpacket_renderheader() transfers the contents of lightweight resolver packet structure lwres_lwpacket_t *pkt in network byte order to the lightweight resolver buffer, *b.

lwres_lwpacket_parseheader() performs the converse operation. It transfers data in network byte order from buffer *b to resolver packet *pkt. The contents of the buffer b should correspond to a lwres_lwpacket_t.

RETURN VALUES

Successful calls to lwres_lwpacket_renderheader() and lwres_lwpacket_parseheader() return LWRES_R_SUCCESS. If there is insufficient space to copy data between the buffer *b and lightweight resolver packet *pkt both functions return LWRES_R_UNEXPECTEDEND.

bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_getnameinfo.30000644000470500017500000000716512664710322021653 0ustar lamontlamont.\" Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: lwres_getnameinfo .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: June 18, 2007 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "LWRES_GETNAMEINFO" "3" "June 18, 2007" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" lwres_getnameinfo \- lightweight resolver socket address structure to hostname and service name .SH "SYNOPSIS" .nf #include .fi .HP 22 .BI "int lwres_getnameinfo(const\ struct\ sockaddr\ *" "sa" ", size_t\ " "salen" ", char\ *" "host" ", size_t\ " "hostlen" ", char\ *" "serv" ", size_t\ " "servlen" ", int\ " "flags" ");" .SH "DESCRIPTION" .PP This function is equivalent to the \fBgetnameinfo\fR(3) function defined in RFC2133. \fBlwres_getnameinfo()\fR returns the hostname for the \fBstruct sockaddr\fR \fIsa\fR which is \fIsalen\fR bytes long. The hostname is of length \fIhostlen\fR and is returned via \fI*host.\fR The maximum length of the hostname is 1025 bytes: \fBNI_MAXHOST\fR. .PP The name of the service associated with the port number in \fIsa\fR is returned in \fI*serv.\fR It is \fIservlen\fR bytes long. The maximum length of the service name is \fBNI_MAXSERV\fR \- 32 bytes. .PP The \fIflags\fR argument sets the following bits: .PP \fBNI_NOFQDN\fR .RS 4 A fully qualified domain name is not required for local hosts. The local part of the fully qualified domain name is returned instead. .RE .PP \fBNI_NUMERICHOST\fR .RS 4 Return the address in numeric form, as if calling inet_ntop(), instead of a host name. .RE .PP \fBNI_NAMEREQD\fR .RS 4 A name is required. If the hostname cannot be found in the DNS and this flag is set, a non\-zero error code is returned. If the hostname is not found and the flag is not set, the address is returned in numeric form. .RE .PP \fBNI_NUMERICSERV\fR .RS 4 The service name is returned as a digit string representing the port number. .RE .PP \fBNI_DGRAM\fR .RS 4 Specifies that the service being looked up is a datagram service, and causes getservbyport() to be called with a second argument of "udp" instead of its default of "tcp". This is required for the few ports (512\-514) that have different services for UDP and TCP. .RE .SH "RETURN VALUES" .PP \fBlwres_getnameinfo()\fR returns 0 on success or a non\-zero error code if an error occurs. .SH "SEE ALSO" .PP \fBRFC2133\fR(), \fBgetservbyport\fR(3), \fBlwres\fR(3), \fBlwres_getnameinfo\fR(3), \fBlwres_getnamebyaddr\fR(3). \fBlwres_net_ntop\fR(3). .SH "BUGS" .PP RFC2133 fails to define what the nonzero return values of \fBgetnameinfo\fR(3) are. .SH "COPYRIGHT" Copyright \(co 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000, 2001 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_hstrerror.docbook0000644000470500017500000001123712664710322022662 0ustar lamontlamont]> June 18, 2007 lwres_hstrerror 3 BIND9 2004 2005 2007 2014 Internet Systems Consortium, Inc. ("ISC") 2000 2001 Internet Software Consortium. lwres_herror lwres_hstrerror lightweight resolver error message generation #include <lwres/netdb.h> void lwres_herror const char *s const char * lwres_hstrerror int err DESCRIPTION lwres_herror() prints the string s on stderr followed by the string generated by lwres_hstrerror() for the error code stored in the global variable lwres_h_errno. lwres_hstrerror() returns an appropriate string for the error code gievn by err. The values of the error codes and messages are as follows: NETDB_SUCCESS Resolver Error 0 (no error) HOST_NOT_FOUND Unknown host TRY_AGAIN Host name lookup failure NO_RECOVERY Unknown server error NO_DATA No address associated with name RETURN VALUES The string Unknown resolver error is returned by lwres_hstrerror() when the value of lwres_h_errno is not a valid error code. SEE ALSO herror3 , lwres_hstrerror3 . bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_resutil.html0000644000470500017500000002220412664710322021637 0ustar lamontlamont lwres_resutil

Name

lwres_string_parse, lwres_addr_parse, lwres_getaddrsbyname, lwres_getnamebyaddr — lightweight resolver utility functions

Synopsis

#include <lwres/lwres.h>
lwres_result_t lwres_string_parse( lwres_buffer_t *  b,
  char **  c,
  lwres_uint16_t *  len);
lwres_result_t lwres_addr_parse( lwres_buffer_t *  b,
  lwres_addr_t *  addr);
lwres_result_t lwres_getaddrsbyname( lwres_context_t *  ctx,
  const char *  name,
  lwres_uint32_t   addrtypes,
  lwres_gabnresponse_t **  structp);
lwres_result_t lwres_getnamebyaddr( lwres_context_t *  ctx,
  lwres_uint32_t   addrtype,
  lwres_uint16_t   addrlen,
  const unsigned char *  addr,
  lwres_gnbaresponse_t **  structp);

DESCRIPTION

lwres_string_parse() retrieves a DNS-encoded string starting the current pointer of lightweight resolver buffer b: i.e. b->current. When the function returns, the address of the first byte of the encoded string is returned via *c and the length of that string is given by *len. The buffer's current pointer is advanced to point at the character following the string length, the encoded string, and the trailing NULL character.

lwres_addr_parse() extracts an address from the buffer b. The buffer's current pointer b->current is presumed to point at an encoded address: the address preceded by a 32-bit protocol family identifier and a 16-bit length field. The encoded address is copied to addr->address and addr->length indicates the size in bytes of the address that was copied. b->current is advanced to point at the next byte of available data in the buffer following the encoded address.

lwres_getaddrsbyname() and lwres_getnamebyaddr() use the lwres_gnbaresponse_t structure defined below:

typedef struct {
        lwres_uint32_t          flags;
        lwres_uint16_t          naliases;
        lwres_uint16_t          naddrs;
        char                   *realname;
        char                  **aliases;
        lwres_uint16_t          realnamelen;
        lwres_uint16_t         *aliaslen;
        lwres_addrlist_t        addrs;
        void                   *base;
        size_t                  baselen;
} lwres_gabnresponse_t;

The contents of this structure are not manipulated directly but they are controlled through the lwres_gabn(3) functions.

The lightweight resolver uses lwres_getaddrsbyname() to perform forward lookups. Hostname name is looked up using the resolver context ctx for memory allocation. addrtypes is a bitmask indicating which type of addresses are to be looked up. Current values for this bitmask are LWRES_ADDRTYPE_V4 for IPv4 addresses and LWRES_ADDRTYPE_V6 for IPv6 addresses. Results of the lookup are returned in *structp.

lwres_getnamebyaddr() performs reverse lookups. Resolver context ctx is used for memory allocation. The address type is indicated by addrtype: LWRES_ADDRTYPE_V4 or LWRES_ADDRTYPE_V6. The address to be looked up is given by addr and its length is addrlen bytes. The result of the function call is made available through *structp.

RETURN VALUES

Successful calls to lwres_string_parse() and lwres_addr_parse() return LWRES_R_SUCCESS. Both functions return LWRES_R_FAILURE if the buffer is corrupt or LWRES_R_UNEXPECTEDEND if the buffer has less space than expected for the components of the encoded string or address.

lwres_getaddrsbyname() returns LWRES_R_SUCCESS on success and it returns LWRES_R_NOTFOUND if the hostname name could not be found.

LWRES_R_SUCCESS is returned by a successful call to lwres_getnamebyaddr().

Both lwres_getaddrsbyname() and lwres_getnamebyaddr() return LWRES_R_NOMEMORY when memory allocation requests fail and LWRES_R_UNEXPECTEDEND if the buffers used for sending queries and receiving replies are too small.

SEE ALSO

lwres_buffer(3), lwres_gabn(3).

bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_noop.html0000644000470500017500000002444712664710322021136 0ustar lamontlamont lwres_noop

Name

lwres_nooprequest_render, lwres_noopresponse_render, lwres_nooprequest_parse, lwres_noopresponse_parse, lwres_noopresponse_free, lwres_nooprequest_free — lightweight resolver no-op message handling

Synopsis

#include <lwres/lwres.h>
lwres_result_t lwres_nooprequest_render( lwres_context_t *  ctx,
  lwres_nooprequest_t *  req,
  lwres_lwpacket_t *  pkt,
  lwres_buffer_t *  b);
lwres_result_t lwres_noopresponse_render( lwres_context_t *  ctx,
  lwres_noopresponse_t *  req,
  lwres_lwpacket_t *  pkt,
  lwres_buffer_t *  b);
lwres_result_t lwres_nooprequest_parse( lwres_context_t *  ctx,
  lwres_buffer_t *  b,
  lwres_lwpacket_t *  pkt,
  lwres_nooprequest_t **  structp);
lwres_result_t lwres_noopresponse_parse( lwres_context_t *  ctx,
  lwres_buffer_t *  b,
  lwres_lwpacket_t *  pkt,
  lwres_noopresponse_t **  structp);
void lwres_noopresponse_free( lwres_context_t *  ctx,
  lwres_noopresponse_t **  structp);
void lwres_nooprequest_free( lwres_context_t *  ctx,
  lwres_nooprequest_t **  structp);

DESCRIPTION

These are low-level routines for creating and parsing lightweight resolver no-op request and response messages.

The no-op message is analogous to a ping packet: a packet is sent to the resolver daemon and is simply echoed back. The opcode is intended to allow a client to determine if the server is operational or not.

There are four main functions for the no-op opcode. One render function converts a no-op request structure — lwres_nooprequest_t — to the lightweight resolver's canonical format. It is complemented by a parse function that converts a packet in this canonical format to a no-op request structure. Another render function converts the no-op response structure — lwres_noopresponse_t to the canonical format. This is complemented by a parse function which converts a packet in canonical format to a no-op response structure.

These structures are defined in lwres/lwres.h. They are shown below.

#define LWRES_OPCODE_NOOP       0x00000000U

typedef struct {
        lwres_uint16_t  datalength;
        unsigned char   *data;
} lwres_nooprequest_t;

typedef struct {
        lwres_uint16_t  datalength;
        unsigned char   *data;
} lwres_noopresponse_t;

Although the structures have different types, they are identical. This is because the no-op opcode simply echos whatever data was sent: the response is therefore identical to the request.

lwres_nooprequest_render() uses resolver context ctx to convert no-op request structure req to canonical format. The packet header structure pkt is initialised and transferred to buffer b. The contents of *req are then appended to the buffer in canonical format. lwres_noopresponse_render() performs the same task, except it converts a no-op response structure lwres_noopresponse_t to the lightweight resolver's canonical format.

lwres_nooprequest_parse() uses context ctx to convert the contents of packet pkt to a lwres_nooprequest_t structure. Buffer b provides space to be used for storing this structure. When the function succeeds, the resulting lwres_nooprequest_t is made available through *structp. lwres_noopresponse_parse() offers the same semantics as lwres_nooprequest_parse() except it yields a lwres_noopresponse_t structure.

lwres_noopresponse_free() and lwres_nooprequest_free() release the memory in resolver context ctx that was allocated to the lwres_noopresponse_t or lwres_nooprequest_t structures referenced via structp.

RETURN VALUES

The no-op opcode functions lwres_nooprequest_render(), lwres_noopresponse_render() lwres_nooprequest_parse() and lwres_noopresponse_parse() all return LWRES_R_SUCCESS on success. They return LWRES_R_NOMEMORY if memory allocation fails. LWRES_R_UNEXPECTEDEND is returned if the available space in the buffer b is too small to accommodate the packet header or the lwres_nooprequest_t and lwres_noopresponse_t structures. lwres_nooprequest_parse() and lwres_noopresponse_parse() will return LWRES_R_UNEXPECTEDEND if the buffer is not empty after decoding the received packet. These functions will return LWRES_R_FAILURE if pktflags in the packet header structure lwres_lwpacket_t indicate that the packet is not a response to an earlier query.

SEE ALSO

lwres_packet(3)

bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_context.docbook0000644000470500017500000002350612664710322022316 0ustar lamontlamont]> June 18, 2007 lwres_context 3 BIND9 2004 2005 2007 2014 Internet Systems Consortium, Inc. ("ISC") 2000 2001 2003 Internet Software Consortium. lwres_context_create lwres_context_destroy lwres_context_nextserial lwres_context_initserial lwres_context_freemem lwres_context_allocmem lwres_context_sendrecv lightweight resolver context management #include <lwres/lwres.h> lwres_result_t lwres_context_create lwres_context_t **contextp void *arg lwres_malloc_t malloc_function lwres_free_t free_function lwres_result_t lwres_context_destroy lwres_context_t **contextp void lwres_context_initserial lwres_context_t *ctx lwres_uint32_t serial lwres_uint32_t lwres_context_nextserial lwres_context_t *ctx void lwres_context_freemem lwres_context_t *ctx void *mem size_t len void lwres_context_allocmem lwres_context_t *ctx size_t len void * lwres_context_sendrecv lwres_context_t *ctx void *sendbase int sendlen void *recvbase int recvlen int *recvd_len DESCRIPTION lwres_context_create() creates a lwres_context_t structure for use in lightweight resolver operations. It holds a socket and other data needed for communicating with a resolver daemon. The new lwres_context_t is returned through contextp, a pointer to a lwres_context_t pointer. This lwres_context_t pointer must initially be NULL, and is modified to point to the newly created lwres_context_t. When the lightweight resolver needs to perform dynamic memory allocation, it will call malloc_function to allocate memory and free_function to free it. If malloc_function and free_function are NULL, memory is allocated using malloc3 . and free3 . It is not permitted to have a NULL malloc_function and a non-NULL free_function or vice versa. arg is passed as the first parameter to the memory allocation functions. If malloc_function and free_function are NULL, arg is unused and should be passed as NULL. Once memory for the structure has been allocated, it is initialized using lwres_conf_init3 and returned via *contextp. lwres_context_destroy() destroys a lwres_context_t, closing its socket. contextp is a pointer to a pointer to the context that is to be destroyed. The pointer will be set to NULL when the context has been destroyed. The context holds a serial number that is used to identify resolver request packets and associate responses with the corresponding requests. This serial number is controlled using lwres_context_initserial() and lwres_context_nextserial(). lwres_context_initserial() sets the serial number for context *ctx to serial. lwres_context_nextserial() increments the serial number and returns the previous value. Memory for a lightweight resolver context is allocated and freed using lwres_context_allocmem() and lwres_context_freemem(). These use whatever allocations were defined when the context was created with lwres_context_create(). lwres_context_allocmem() allocates len bytes of memory and if successful returns a pointer to the allocated storage. lwres_context_freemem() frees len bytes of space starting at location mem. lwres_context_sendrecv() performs I/O for the context ctx. Data are read and written from the context's socket. It writes data from sendbase — typically a lightweight resolver query packet — and waits for a reply which is copied to the receive buffer at recvbase. The number of bytes that were written to this receive buffer is returned in *recvd_len. RETURN VALUES lwres_context_create() returns LWRES_R_NOMEMORY if memory for the struct lwres_context could not be allocated, LWRES_R_SUCCESS otherwise. Successful calls to the memory allocator lwres_context_allocmem() return a pointer to the start of the allocated space. It returns NULL if memory could not be allocated. LWRES_R_SUCCESS is returned when lwres_context_sendrecv() completes successfully. LWRES_R_IOERROR is returned if an I/O error occurs and LWRES_R_TIMEOUT is returned if lwres_context_sendrecv() times out waiting for a response. SEE ALSO lwres_conf_init3 , malloc3 , free3 . bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_resutil.30000644000470500017500000001300712664710322021036 0ustar lamontlamont.\" Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: lwres_resutil .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: June 18, 2007 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "LWRES_RESUTIL" "3" "June 18, 2007" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" lwres_string_parse, lwres_addr_parse, lwres_getaddrsbyname, lwres_getnamebyaddr \- lightweight resolver utility functions .SH "SYNOPSIS" .nf #include .fi .HP 34 .BI "lwres_result_t lwres_string_parse(lwres_buffer_t\ *" "b" ", char\ **" "c" ", lwres_uint16_t\ *" "len" ");" .HP 32 .BI "lwres_result_t lwres_addr_parse(lwres_buffer_t\ *" "b" ", lwres_addr_t\ *" "addr" ");" .HP 36 .BI "lwres_result_t lwres_getaddrsbyname(lwres_context_t\ *" "ctx" ", const\ char\ *" "name" ", lwres_uint32_t\ " "addrtypes" ", lwres_gabnresponse_t\ **" "structp" ");" .HP 35 .BI "lwres_result_t lwres_getnamebyaddr(lwres_context_t\ *" "ctx" ", lwres_uint32_t\ " "addrtype" ", lwres_uint16_t\ " "addrlen" ", const\ unsigned\ char\ *" "addr" ", lwres_gnbaresponse_t\ **" "structp" ");" .SH "DESCRIPTION" .PP \fBlwres_string_parse()\fR retrieves a DNS\-encoded string starting the current pointer of lightweight resolver buffer \fIb\fR: i.e. \fBb\->current\fR. When the function returns, the address of the first byte of the encoded string is returned via \fI*c\fR and the length of that string is given by \fI*len\fR. The buffer's current pointer is advanced to point at the character following the string length, the encoded string, and the trailing \fBNULL\fR character. .PP \fBlwres_addr_parse()\fR extracts an address from the buffer \fIb\fR. The buffer's current pointer \fBb\->current\fR is presumed to point at an encoded address: the address preceded by a 32\-bit protocol family identifier and a 16\-bit length field. The encoded address is copied to \fBaddr\->address\fR and \fBaddr\->length\fR indicates the size in bytes of the address that was copied. \fBb\->current\fR is advanced to point at the next byte of available data in the buffer following the encoded address. .PP \fBlwres_getaddrsbyname()\fR and \fBlwres_getnamebyaddr()\fR use the \fBlwres_gnbaresponse_t\fR structure defined below: .PP .RS 4 .nf typedef struct { lwres_uint32_t flags; lwres_uint16_t naliases; lwres_uint16_t naddrs; char *realname; char **aliases; lwres_uint16_t realnamelen; lwres_uint16_t *aliaslen; lwres_addrlist_t addrs; void *base; size_t baselen; } lwres_gabnresponse_t; .fi .RE .PP The contents of this structure are not manipulated directly but they are controlled through the \fBlwres_gabn\fR(3) functions. .PP The lightweight resolver uses \fBlwres_getaddrsbyname()\fR to perform forward lookups. Hostname \fIname\fR is looked up using the resolver context \fIctx\fR for memory allocation. \fIaddrtypes\fR is a bitmask indicating which type of addresses are to be looked up. Current values for this bitmask are \fBLWRES_ADDRTYPE_V4\fR for IPv4 addresses and \fBLWRES_ADDRTYPE_V6\fR for IPv6 addresses. Results of the lookup are returned in \fI*structp\fR. .PP \fBlwres_getnamebyaddr()\fR performs reverse lookups. Resolver context \fIctx\fR is used for memory allocation. The address type is indicated by \fIaddrtype\fR: \fBLWRES_ADDRTYPE_V4\fR or \fBLWRES_ADDRTYPE_V6\fR. The address to be looked up is given by \fIaddr\fR and its length is \fIaddrlen\fR bytes. The result of the function call is made available through \fI*structp\fR. .SH "RETURN VALUES" .PP Successful calls to \fBlwres_string_parse()\fR and \fBlwres_addr_parse()\fR return \fBLWRES_R_SUCCESS.\fR Both functions return \fBLWRES_R_FAILURE\fR if the buffer is corrupt or \fBLWRES_R_UNEXPECTEDEND\fR if the buffer has less space than expected for the components of the encoded string or address. .PP \fBlwres_getaddrsbyname()\fR returns \fBLWRES_R_SUCCESS\fR on success and it returns \fBLWRES_R_NOTFOUND\fR if the hostname \fIname\fR could not be found. .PP \fBLWRES_R_SUCCESS\fR is returned by a successful call to \fBlwres_getnamebyaddr()\fR. .PP Both \fBlwres_getaddrsbyname()\fR and \fBlwres_getnamebyaddr()\fR return \fBLWRES_R_NOMEMORY\fR when memory allocation requests fail and \fBLWRES_R_UNEXPECTEDEND\fR if the buffers used for sending queries and receiving replies are too small. .SH "SEE ALSO" .PP \fBlwres_buffer\fR(3), \fBlwres_gabn\fR(3). .SH "COPYRIGHT" Copyright \(co 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000, 2001 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_hstrerror.30000644000470500017500000000474612664710322021413 0ustar lamontlamont.\" Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: lwres_hstrerror .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: June 18, 2007 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "LWRES_HSTRERROR" "3" "June 18, 2007" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" lwres_herror, lwres_hstrerror \- lightweight resolver error message generation .SH "SYNOPSIS" .nf #include .fi .HP 18 .BI "void lwres_herror(const\ char\ *" "s" ");" .HP 29 .BI "const char * lwres_hstrerror(int\ " "err" ");" .SH "DESCRIPTION" .PP \fBlwres_herror()\fR prints the string \fIs\fR on \fBstderr\fR followed by the string generated by \fBlwres_hstrerror()\fR for the error code stored in the global variable \fBlwres_h_errno\fR. .PP \fBlwres_hstrerror()\fR returns an appropriate string for the error code gievn by \fIerr\fR. The values of the error codes and messages are as follows: .PP \fBNETDB_SUCCESS\fR .RS 4 Resolver Error 0 (no error) .RE .PP \fBHOST_NOT_FOUND\fR .RS 4 Unknown host .RE .PP \fBTRY_AGAIN\fR .RS 4 Host name lookup failure .RE .PP \fBNO_RECOVERY\fR .RS 4 Unknown server error .RE .PP \fBNO_DATA\fR .RS 4 No address associated with name .RE .SH "RETURN VALUES" .PP The string Unknown resolver error is returned by \fBlwres_hstrerror()\fR when the value of \fBlwres_h_errno\fR is not a valid error code. .SH "SEE ALSO" .PP \fBherror\fR(3), \fBlwres_hstrerror\fR(3). .SH "COPYRIGHT" Copyright \(co 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000, 2001 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_packet.30000644000470500017500000001341712664710322020623 0ustar lamontlamont.\" Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: lwres_packet .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: June 18, 2007 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "LWRES_PACKET" "3" "June 18, 2007" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" lwres_lwpacket_renderheader, lwres_lwpacket_parseheader \- lightweight resolver packet handling functions .SH "SYNOPSIS" .nf #include .fi .HP 43 .BI "lwres_result_t lwres_lwpacket_renderheader(lwres_buffer_t\ *" "b" ", lwres_lwpacket_t\ *" "pkt" ");" .HP 42 .BI "lwres_result_t lwres_lwpacket_parseheader(lwres_buffer_t\ *" "b" ", lwres_lwpacket_t\ *" "pkt" ");" .SH "DESCRIPTION" .PP These functions rely on a \fBstruct lwres_lwpacket\fR which is defined in \fIlwres/lwpacket.h\fR. .PP .RS 4 .nf typedef struct lwres_lwpacket lwres_lwpacket_t; .fi .RE .sp .PP .RS 4 .nf struct lwres_lwpacket { lwres_uint32_t length; lwres_uint16_t version; lwres_uint16_t pktflags; lwres_uint32_t serial; lwres_uint32_t opcode; lwres_uint32_t result; lwres_uint32_t recvlength; lwres_uint16_t authtype; lwres_uint16_t authlength; }; .fi .RE .sp .PP The elements of this structure are: .PP \fBlength\fR .RS 4 the overall packet length, including the entire packet header. This field is filled in by the lwres_gabn_*() and lwres_gnba_*() calls. .RE .PP \fBversion\fR .RS 4 the header format. There is currently only one format, \fBLWRES_LWPACKETVERSION_0\fR. This field is filled in by the lwres_gabn_*() and lwres_gnba_*() calls. .RE .PP \fBpktflags\fR .RS 4 library\-defined flags for this packet: for instance whether the packet is a request or a reply. Flag values can be set, but not defined by the caller. This field is filled in by the application wit the exception of the LWRES_LWPACKETFLAG_RESPONSE bit, which is set by the library in the lwres_gabn_*() and lwres_gnba_*() calls. .RE .PP \fBserial\fR .RS 4 is set by the requestor and is returned in all replies. If two or more packets from the same source have the same serial number and are from the same source, they are assumed to be duplicates and the latter ones may be dropped. This field must be set by the application. .RE .PP \fBopcode\fR .RS 4 indicates the operation. Opcodes between 0x00000000 and 0x03ffffff are reserved for use by the lightweight resolver library. Opcodes between 0x04000000 and 0xffffffff are application defined. This field is filled in by the lwres_gabn_*() and lwres_gnba_*() calls. .RE .PP \fBresult\fR .RS 4 is only valid for replies. Results between 0x04000000 and 0xffffffff are application defined. Results between 0x00000000 and 0x03ffffff are reserved for library use. This field is filled in by the lwres_gabn_*() and lwres_gnba_*() calls. .RE .PP \fBrecvlength\fR .RS 4 is the maximum buffer size that the receiver can handle on requests and the size of the buffer needed to satisfy a request when the buffer is too large for replies. This field is supplied by the application. .RE .PP \fBauthtype\fR .RS 4 defines the packet level authentication that is used. Authorisation types between 0x1000 and 0xffff are application defined and types between 0x0000 and 0x0fff are reserved for library use. Currently these are not used and must be zero. .RE .PP \fBauthlen\fR .RS 4 gives the length of the authentication data. Since packet authentication is currently not used, this must be zero. .RE .PP The following opcodes are currently defined: .PP \fBNOOP\fR .RS 4 Success is always returned and the packet contents are echoed. The lwres_noop_*() functions should be used for this type. .RE .PP \fBGETADDRSBYNAME\fR .RS 4 returns all known addresses for a given name. The lwres_gabn_*() functions should be used for this type. .RE .PP \fBGETNAMEBYADDR\fR .RS 4 return the hostname for the given address. The lwres_gnba_*() functions should be used for this type. .RE .PP \fBlwres_lwpacket_renderheader()\fR transfers the contents of lightweight resolver packet structure \fBlwres_lwpacket_t\fR \fI*pkt\fR in network byte order to the lightweight resolver buffer, \fI*b\fR. .PP \fBlwres_lwpacket_parseheader()\fR performs the converse operation. It transfers data in network byte order from buffer \fI*b\fR to resolver packet \fI*pkt\fR. The contents of the buffer \fIb\fR should correspond to a \fBlwres_lwpacket_t\fR. .SH "RETURN VALUES" .PP Successful calls to \fBlwres_lwpacket_renderheader()\fR and \fBlwres_lwpacket_parseheader()\fR return \fBLWRES_R_SUCCESS\fR. If there is insufficient space to copy data between the buffer \fI*b\fR and lightweight resolver packet \fI*pkt\fR both functions return \fBLWRES_R_UNEXPECTEDEND\fR. .SH "COPYRIGHT" Copyright \(co 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000, 2001 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_inetntop.html0000644000470500017500000000733412664710322022017 0ustar lamontlamont lwres_inetntop

Name

lwres_net_ntop — lightweight resolver IP address presentation

Synopsis

#include <lwres/net.h>
const char * lwres_net_ntop( int   af,
  const void *  src,
  char *  dst,
  size_t   size);

DESCRIPTION

lwres_net_ntop() converts an IP address of protocol family af — IPv4 or IPv6 — at location src from network format to its conventional representation as a string. For IPv4 addresses, that string would be a dotted-decimal. An IPv6 address would be represented in colon notation as described in RFC1884.

The generated string is copied to dst provided size indicates it is long enough to store the ASCII representation of the address.

RETURN VALUES

If successful, the function returns dst: a pointer to a string containing the presentation format of the address. lwres_net_ntop() returns NULL and sets the global variable errno to EAFNOSUPPORT if the protocol family given in af is not supported.

SEE ALSO

RFC1884, inet_ntop(3), errno(3).

bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres.30000644000470500017500000001431012664710322017265 0ustar lamontlamont.\" Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: lwres .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: June 18, 2007 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "LWRES" "3" "June 18, 2007" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" lwres \- introduction to the lightweight resolver library .SH "SYNOPSIS" .nf #include .fi .SH "DESCRIPTION" .PP The BIND 9 lightweight resolver library is a simple, name service independent stub resolver library. It provides hostname\-to\-address and address\-to\-hostname lookup services to applications by transmitting lookup requests to a resolver daemon \fBlwresd\fR running on the local host. The resolver daemon performs the lookup using the DNS or possibly other name service protocols, and returns the results to the application through the library. The library and resolver daemon communicate using a simple UDP\-based protocol. .SH "OVERVIEW" .PP The lwresd library implements multiple name service APIs. The standard \fBgethostbyname()\fR, \fBgethostbyaddr()\fR, \fBgethostbyname_r()\fR, \fBgethostbyaddr_r()\fR, \fBgetaddrinfo()\fR, \fBgetipnodebyname()\fR, and \fBgetipnodebyaddr()\fR functions are all supported. To allow the lwres library to coexist with system libraries that define functions of the same name, the library defines these functions with names prefixed by lwres_. To define the standard names, applications must include the header file \fI\fR which contains macro definitions mapping the standard function names into lwres_ prefixed ones. Operating system vendors who integrate the lwres library into their base distributions should rename the functions in the library proper so that the renaming macros are not needed. .PP The library also provides a native API consisting of the functions \fBlwres_getaddrsbyname()\fR and \fBlwres_getnamebyaddr()\fR. These may be called by applications that require more detailed control over the lookup process than the standard functions provide. .PP In addition to these name service independent address lookup functions, the library implements a new, experimental API for looking up arbitrary DNS resource records, using the \fBlwres_getaddrsbyname()\fR function. .PP Finally, there is a low\-level API for converting lookup requests and responses to and from raw lwres protocol packets. This API can be used by clients requiring nonblocking operation, and is also used when implementing the server side of the lwres protocol, for example in the \fBlwresd\fR resolver daemon. The use of this low\-level API in clients and servers is outlined in the following sections. .SH "CLIENT\-SIDE LOW\-LEVEL API CALL FLOW" .PP When a client program wishes to make an lwres request using the native low\-level API, it typically performs the following sequence of actions. .PP (1) Allocate or use an existing \fBlwres_packet_t\fR, called \fIpkt\fR below. .PP (2) Set pkt.recvlength to the maximum length we will accept. This is done so the receiver of our packets knows how large our receive buffer is. The "default" is a constant in \fIlwres.h\fR: \fBLWRES_RECVLENGTH = 4096\fR. .PP (3) Set pkt.serial to a unique serial number. This value is echoed back to the application by the remote server. .PP (4) Set pkt.pktflags. Usually this is set to 0. .PP (5) Set pkt.result to 0. .PP (6) Call \fBlwres_*request_render()\fR, or marshall in the data using the primitives such as \fBlwres_packet_render()\fR and storing the packet data. .PP (7) Transmit the resulting buffer. .PP (8) Call \fBlwres_*response_parse()\fR to parse any packets received. .PP (9) Verify that the opcode and serial match a request, and process the packet specific information contained in the body. .SH "SERVER\-SIDE LOW\-LEVEL API CALL FLOW" .PP When implementing the server side of the lightweight resolver protocol using the lwres library, a sequence of actions like the following is typically involved in processing each request packet. .PP Note that the same \fBlwres_packet_t\fR is used in both the \fB_parse()\fR and \fB_render()\fR calls, with only a few modifications made to the packet header's contents between uses. This method is recommended as it keeps the serial, opcode, and other fields correct. .PP (1) When a packet is received, call \fBlwres_*request_parse()\fR to unmarshall it. This returns a \fBlwres_packet_t\fR (also called \fIpkt\fR, below) as well as a data specific type, such as \fBlwres_gabnrequest_t\fR. .PP (2) Process the request in the data specific type. .PP (3) Set the pkt.result, pkt.recvlength as above. All other fields can be left untouched since they were filled in by the \fB*_parse()\fR call above. If using \fBlwres_*response_render()\fR, pkt.pktflags will be set up properly. Otherwise, the \fBLWRES_LWPACKETFLAG_RESPONSE\fR bit should be set. .PP (4) Call the data specific rendering function, such as \fBlwres_gabnresponse_render()\fR. .PP (5) Send the resulting packet to the client. .PP .SH "SEE ALSO" .PP \fBlwres_gethostent\fR(3), \fBlwres_getipnode\fR(3), \fBlwres_getnameinfo\fR(3), \fBlwres_noop\fR(3), \fBlwres_gabn\fR(3), \fBlwres_gnba\fR(3), \fBlwres_context\fR(3), \fBlwres_config\fR(3), \fBresolver\fR(5), \fBlwresd\fR(8). .SH "COPYRIGHT" Copyright \(co 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000, 2001 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_gabn.30000644000470500017500000001453712664710322020267 0ustar lamontlamont.\" Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: lwres_gabn .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: June 18, 2007 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "LWRES_GABN" "3" "June 18, 2007" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" lwres_gabnrequest_render, lwres_gabnresponse_render, lwres_gabnrequest_parse, lwres_gabnresponse_parse, lwres_gabnresponse_free, lwres_gabnrequest_free \- lightweight resolver getaddrbyname message handling .SH "SYNOPSIS" .nf #include .fi .HP 40 .BI "lwres_result_t lwres_gabnrequest_render(lwres_context_t\ *" "ctx" ", lwres_gabnrequest_t\ *" "req" ", lwres_lwpacket_t\ *" "pkt" ", lwres_buffer_t\ *" "b" ");" .HP 41 .BI "lwres_result_t lwres_gabnresponse_render(lwres_context_t\ *" "ctx" ", lwres_gabnresponse_t\ *" "req" ", lwres_lwpacket_t\ *" "pkt" ", lwres_buffer_t\ *" "b" ");" .HP 39 .BI "lwres_result_t lwres_gabnrequest_parse(lwres_context_t\ *" "ctx" ", lwres_buffer_t\ *" "b" ", lwres_lwpacket_t\ *" "pkt" ", lwres_gabnrequest_t\ **" "structp" ");" .HP 40 .BI "lwres_result_t lwres_gabnresponse_parse(lwres_context_t\ *" "ctx" ", lwres_buffer_t\ *" "b" ", lwres_lwpacket_t\ *" "pkt" ", lwres_gabnresponse_t\ **" "structp" ");" .HP 29 .BI "void lwres_gabnresponse_free(lwres_context_t\ *" "ctx" ", lwres_gabnresponse_t\ **" "structp" ");" .HP 28 .BI "void lwres_gabnrequest_free(lwres_context_t\ *" "ctx" ", lwres_gabnrequest_t\ **" "structp" ");" .SH "DESCRIPTION" .PP These are low\-level routines for creating and parsing lightweight resolver name\-to\-address lookup request and response messages. .PP There are four main functions for the getaddrbyname opcode. One render function converts a getaddrbyname request structure \(em \fBlwres_gabnrequest_t\fR \(em to the lightweight resolver's canonical format. It is complemented by a parse function that converts a packet in this canonical format to a getaddrbyname request structure. Another render function converts the getaddrbyname response structure \(em \fBlwres_gabnresponse_t\fR \(em to the canonical format. This is complemented by a parse function which converts a packet in canonical format to a getaddrbyname response structure. .PP These structures are defined in \fI\fR. They are shown below. .PP .RS 4 .nf #define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U .fi .RE .sp .PP .RS 4 .nf typedef struct lwres_addr lwres_addr_t; typedef LWRES_LIST(lwres_addr_t) lwres_addrlist_t; .fi .RE .sp .PP .RS 4 .nf typedef struct { lwres_uint32_t flags; lwres_uint32_t addrtypes; lwres_uint16_t namelen; char *name; } lwres_gabnrequest_t; .fi .RE .sp .PP .RS 4 .nf typedef struct { lwres_uint32_t flags; lwres_uint16_t naliases; lwres_uint16_t naddrs; char *realname; char **aliases; lwres_uint16_t realnamelen; lwres_uint16_t *aliaslen; lwres_addrlist_t addrs; void *base; size_t baselen; } lwres_gabnresponse_t; .fi .RE .sp .PP \fBlwres_gabnrequest_render()\fR uses resolver context \fIctx\fR to convert getaddrbyname request structure \fIreq\fR to canonical format. The packet header structure \fIpkt\fR is initialised and transferred to buffer \fIb\fR. The contents of \fI*req\fR are then appended to the buffer in canonical format. \fBlwres_gabnresponse_render()\fR performs the same task, except it converts a getaddrbyname response structure \fBlwres_gabnresponse_t\fR to the lightweight resolver's canonical format. .PP \fBlwres_gabnrequest_parse()\fR uses context \fIctx\fR to convert the contents of packet \fIpkt\fR to a \fBlwres_gabnrequest_t\fR structure. Buffer \fIb\fR provides space to be used for storing this structure. When the function succeeds, the resulting \fBlwres_gabnrequest_t\fR is made available through \fI*structp\fR. \fBlwres_gabnresponse_parse()\fR offers the same semantics as \fBlwres_gabnrequest_parse()\fR except it yields a \fBlwres_gabnresponse_t\fR structure. .PP \fBlwres_gabnresponse_free()\fR and \fBlwres_gabnrequest_free()\fR release the memory in resolver context \fIctx\fR that was allocated to the \fBlwres_gabnresponse_t\fR or \fBlwres_gabnrequest_t\fR structures referenced via \fIstructp\fR. Any memory associated with ancillary buffers and strings for those structures is also discarded. .SH "RETURN VALUES" .PP The getaddrbyname opcode functions \fBlwres_gabnrequest_render()\fR, \fBlwres_gabnresponse_render()\fR \fBlwres_gabnrequest_parse()\fR and \fBlwres_gabnresponse_parse()\fR all return \fBLWRES_R_SUCCESS\fR on success. They return \fBLWRES_R_NOMEMORY\fR if memory allocation fails. \fBLWRES_R_UNEXPECTEDEND\fR is returned if the available space in the buffer \fIb\fR is too small to accommodate the packet header or the \fBlwres_gabnrequest_t\fR and \fBlwres_gabnresponse_t\fR structures. \fBlwres_gabnrequest_parse()\fR and \fBlwres_gabnresponse_parse()\fR will return \fBLWRES_R_UNEXPECTEDEND\fR if the buffer is not empty after decoding the received packet. These functions will return \fBLWRES_R_FAILURE\fR if pktflags in the packet header structure \fBlwres_lwpacket_t\fR indicate that the packet is not a response to an earlier query. .SH "SEE ALSO" .PP \fBlwres_packet\fR(3) .SH "COPYRIGHT" Copyright \(co 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000, 2001 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_gnba.html0000644000470500017500000002411012664710322021055 0ustar lamontlamont lwres_gnba

Name

lwres_gnbarequest_render, lwres_gnbaresponse_render, lwres_gnbarequest_parse, lwres_gnbaresponse_parse, lwres_gnbaresponse_free, lwres_gnbarequest_free — lightweight resolver getnamebyaddress message handling

Synopsis

#include <lwres/lwres.h>
lwres_result_t lwres_gnbarequest_render ( lwres_context_t *  ctx,
  lwres_gnbarequest_t *  req,
  lwres_lwpacket_t *  pkt,
  lwres_buffer_t *  b);
lwres_result_t lwres_gnbaresponse_render ( lwres_context_t *  ctx,
  lwres_gnbaresponse_t *  req,
  lwres_lwpacket_t *  pkt,
  lwres_buffer_t *  b);
lwres_result_t lwres_gnbarequest_parse( lwres_context_t *  ctx,
  lwres_buffer_t *  b,
  lwres_lwpacket_t *  pkt,
  lwres_gnbarequest_t **  structp);
lwres_result_t lwres_gnbaresponse_parse( lwres_context_t *  ctx,
  lwres_buffer_t *  b,
  lwres_lwpacket_t *  pkt,
  lwres_gnbaresponse_t **  structp);
void lwres_gnbaresponse_free ( lwres_context_t *  ctx,
  lwres_gnbaresponse_t **  structp);
void lwres_gnbarequest_free( lwres_context_t *  ctx,
  lwres_gnbarequest_t **  structp);

DESCRIPTION

These are low-level routines for creating and parsing lightweight resolver address-to-name lookup request and response messages.

There are four main functions for the getnamebyaddr opcode. One render function converts a getnamebyaddr request structure — lwres_gnbarequest_t — to the lightweight resolver's canonical format. It is complemented by a parse function that converts a packet in this canonical format to a getnamebyaddr request structure. Another render function converts the getnamebyaddr response structure — lwres_gnbaresponse_t to the canonical format. This is complemented by a parse function which converts a packet in canonical format to a getnamebyaddr response structure.

These structures are defined in lwres/lwres.h. They are shown below.

#define LWRES_OPCODE_GETNAMEBYADDR      0x00010002U

typedef struct {
        lwres_uint32_t  flags;
        lwres_addr_t    addr;
} lwres_gnbarequest_t;

typedef struct {
        lwres_uint32_t  flags;
        lwres_uint16_t  naliases;
        char           *realname;
        char          **aliases;
        lwres_uint16_t  realnamelen;
        lwres_uint16_t *aliaslen;
        void           *base;
        size_t          baselen;
} lwres_gnbaresponse_t;

lwres_gnbarequest_render() uses resolver context ctx to convert getnamebyaddr request structure req to canonical format. The packet header structure pkt is initialised and transferred to buffer b. The contents of *req are then appended to the buffer in canonical format. lwres_gnbaresponse_render() performs the same task, except it converts a getnamebyaddr response structure lwres_gnbaresponse_t to the lightweight resolver's canonical format.

lwres_gnbarequest_parse() uses context ctx to convert the contents of packet pkt to a lwres_gnbarequest_t structure. Buffer b provides space to be used for storing this structure. When the function succeeds, the resulting lwres_gnbarequest_t is made available through *structp. lwres_gnbaresponse_parse() offers the same semantics as lwres_gnbarequest_parse() except it yields a lwres_gnbaresponse_t structure.

lwres_gnbaresponse_free() and lwres_gnbarequest_free() release the memory in resolver context ctx that was allocated to the lwres_gnbaresponse_t or lwres_gnbarequest_t structures referenced via structp. Any memory associated with ancillary buffers and strings for those structures is also discarded.

RETURN VALUES

The getnamebyaddr opcode functions lwres_gnbarequest_render(), lwres_gnbaresponse_render() lwres_gnbarequest_parse() and lwres_gnbaresponse_parse() all return LWRES_R_SUCCESS on success. They return LWRES_R_NOMEMORY if memory allocation fails. LWRES_R_UNEXPECTEDEND is returned if the available space in the buffer b is too small to accommodate the packet header or the lwres_gnbarequest_t and lwres_gnbaresponse_t structures. lwres_gnbarequest_parse() and lwres_gnbaresponse_parse() will return LWRES_R_UNEXPECTEDEND if the buffer is not empty after decoding the received packet. These functions will return LWRES_R_FAILURE if pktflags in the packet header structure lwres_lwpacket_t indicate that the packet is not a response to an earlier query.

SEE ALSO

lwres_packet(3).

bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_inetntop.30000644000470500017500000000473212664710322021214 0ustar lamontlamont.\" Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: lwres_inetntop .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: June 18, 2007 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "LWRES_INETNTOP" "3" "June 18, 2007" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" lwres_net_ntop \- lightweight resolver IP address presentation .SH "SYNOPSIS" .nf #include .fi .HP 28 .BI "const char * lwres_net_ntop(int\ " "af" ", const\ void\ *" "src" ", char\ *" "dst" ", size_t\ " "size" ");" .SH "DESCRIPTION" .PP \fBlwres_net_ntop()\fR converts an IP address of protocol family \fIaf\fR \(em IPv4 or IPv6 \(em at location \fIsrc\fR from network format to its conventional representation as a string. For IPv4 addresses, that string would be a dotted\-decimal. An IPv6 address would be represented in colon notation as described in RFC1884. .PP The generated string is copied to \fIdst\fR provided \fIsize\fR indicates it is long enough to store the ASCII representation of the address. .SH "RETURN VALUES" .PP If successful, the function returns \fIdst\fR: a pointer to a string containing the presentation format of the address. \fBlwres_net_ntop()\fR returns \fBNULL\fR and sets the global variable \fBerrno\fR to \fBEAFNOSUPPORT\fR if the protocol family given in \fIaf\fR is not supported. .SH "SEE ALSO" .PP \fBRFC1884\fR(), \fBinet_ntop\fR(3), \fBerrno\fR(3). .SH "COPYRIGHT" Copyright \(co 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000, 2001 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_buffer.docbook0000644000470500017500000003135212664710322022101 0ustar lamontlamont]> June 18, 2007 lwres_buffer 3 BIND9 2004 2005 2007 2014 Internet Systems Consortium, Inc. ("ISC") 2000 2001 Internet Software Consortium. lwres_buffer_init lwres_buffer_invalidate lwres_buffer_add lwres_buffer_subtract lwres_buffer_clear lwres_buffer_first lwres_buffer_forward lwres_buffer_back lwres_buffer_getuint8 lwres_buffer_putuint8 lwres_buffer_getuint16 lwres_buffer_putuint16 lwres_buffer_getuint32 lwres_buffer_putuint32 lwres_buffer_putmem lwres_buffer_getmem lightweight resolver buffer management #include <lwres/lwbuffer.h> void lwres_buffer_init lwres_buffer_t *b void *base unsigned int length void lwres_buffer_invalidate lwres_buffer_t *b void lwres_buffer_add lwres_buffer_t *b unsigned int n void lwres_buffer_subtract lwres_buffer_t *b unsigned int n void lwres_buffer_clear lwres_buffer_t *b void lwres_buffer_first lwres_buffer_t *b void lwres_buffer_forward lwres_buffer_t *b unsigned int n void lwres_buffer_back lwres_buffer_t *b unsigned int n lwres_uint8_t lwres_buffer_getuint8 lwres_buffer_t *b void lwres_buffer_putuint8 lwres_buffer_t *b lwres_uint8_t val lwres_uint16_t lwres_buffer_getuint16 lwres_buffer_t *b void lwres_buffer_putuint16 lwres_buffer_t *b lwres_uint16_t val lwres_uint32_t lwres_buffer_getuint32 lwres_buffer_t *b void lwres_buffer_putuint32 lwres_buffer_t *b lwres_uint32_t val void lwres_buffer_putmem lwres_buffer_t *b const unsigned char *base unsigned int length void lwres_buffer_getmem lwres_buffer_t *b unsigned char *base unsigned int length DESCRIPTION These functions provide bounds checked access to a region of memory where data is being read or written. They are based on, and similar to, the isc_buffer_ functions in the ISC library. A buffer is a region of memory, together with a set of related subregions. The used region and the available region are disjoint, and their union is the buffer's region. The used region extends from the beginning of the buffer region to the last used byte. The available region extends from one byte greater than the last used byte to the end of the buffer's region. The size of the used region can be changed using various buffer commands. Initially, the used region is empty. The used region is further subdivided into two disjoint regions: the consumed region and the remaining region. The union of these two regions is the used region. The consumed region extends from the beginning of the used region to the byte before the current offset (if any). The remaining region the current pointer to the end of the used region. The size of the consumed region can be changed using various buffer commands. Initially, the consumed region is empty. The active region is an (optional) subregion of the remaining region. It extends from the current offset to an offset in the remaining region. Initially, the active region is empty. If the current offset advances beyond the chosen offset, the active region will also be empty. /------------entire length---------------\\ /----- used region -----\\/-- available --\\ +----------------------------------------+ | consumed | remaining | | +----------------------------------------+ a b c d e a == base of buffer. b == current pointer. Can be anywhere between a and d. c == active pointer. Meaningful between b and d. d == used pointer. e == length of buffer. a-e == entire length of buffer. a-d == used region. a-b == consumed region. b-d == remaining region. b-c == optional active region. lwres_buffer_init() initializes the lwres_buffer_t *b and assocates it with the memory region of size length bytes starting at location base. lwres_buffer_invalidate() marks the buffer *b as invalid. Invalidating a buffer after use is not required, but makes it possible to catch its possible accidental use. The functions lwres_buffer_add() and lwres_buffer_subtract() respectively increase and decrease the used space in buffer *b by n bytes. lwres_buffer_add() checks for buffer overflow and lwres_buffer_subtract() checks for underflow. These functions do not allocate or deallocate memory. They just change the value of used. A buffer is re-initialised by lwres_buffer_clear(). The function sets used, current and active to zero. lwres_buffer_first makes the consumed region of buffer *p empty by setting current to zero (the start of the buffer). lwres_buffer_forward() increases the consumed region of buffer *b by n bytes, checking for overflow. Similarly, lwres_buffer_back() decreases buffer b's consumed region by n bytes and checks for underflow. lwres_buffer_getuint8() reads an unsigned 8-bit integer from *b and returns it. lwres_buffer_putuint8() writes the unsigned 8-bit integer val to buffer *b. lwres_buffer_getuint16() and lwres_buffer_getuint32() are identical to lwres_buffer_putuint8() except that they respectively read an unsigned 16-bit or 32-bit integer in network byte order from b. Similarly, lwres_buffer_putuint16() and lwres_buffer_putuint32() writes the unsigned 16-bit or 32-bit integer val to buffer b, in network byte order. Arbitrary amounts of data are read or written from a lightweight resolver buffer with lwres_buffer_getmem() and lwres_buffer_putmem() respectively. lwres_buffer_putmem() copies length bytes of memory at base to b. Conversely, lwres_buffer_getmem() copies length bytes of memory from b to base. bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_gethostent.30000644000470500017500000002127412664710322021540 0ustar lamontlamont.\" Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2001 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: lwres_gethostent .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: June 18, 2007 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "LWRES_GETHOSTENT" "3" "June 18, 2007" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" lwres_gethostbyname, lwres_gethostbyname2, lwres_gethostbyaddr, lwres_gethostent, lwres_sethostent, lwres_endhostent, lwres_gethostbyname_r, lwres_gethostbyaddr_r, lwres_gethostent_r, lwres_sethostent_r, lwres_endhostent_r \- lightweight resolver get network host entry .SH "SYNOPSIS" .nf #include .fi .HP 37 .BI "struct hostent * lwres_gethostbyname(const\ char\ *" "name" ");" .HP 38 .BI "struct hostent * lwres_gethostbyname2(const\ char\ *" "name" ", int\ " "af" ");" .HP 37 .BI "struct hostent * lwres_gethostbyaddr(const\ char\ *" "addr" ", int\ " "len" ", int\ " "type" ");" .HP 34 .BI "struct hostent * lwres_gethostent(void);" .HP 22 .BI "void lwres_sethostent(int\ " "stayopen" ");" .HP 22 .BI "void lwres_endhostent(void);" .HP 39 .BI "struct hostent * lwres_gethostbyname_r(const\ char\ *" "name" ", struct\ hostent\ *" "resbuf" ", char\ *" "buf" ", int\ " "buflen" ", int\ *" "error" ");" .HP 39 .BI "struct hostent * lwres_gethostbyaddr_r(const\ char\ *" "addr" ", int\ " "len" ", int\ " "type" ", struct\ hostent\ *" "resbuf" ", char\ *" "buf" ", int\ " "buflen" ", int\ *" "error" ");" .HP 36 .BI "struct hostent * lwres_gethostent_r(struct\ hostent\ *" "resbuf" ", char\ *" "buf" ", int\ " "buflen" ", int\ *" "error" ");" .HP 24 .BI "void lwres_sethostent_r(int\ " "stayopen" ");" .HP 24 .BI "void lwres_endhostent_r(void);" .SH "DESCRIPTION" .PP These functions provide hostname\-to\-address and address\-to\-hostname lookups by means of the lightweight resolver. They are similar to the standard \fBgethostent\fR(3) functions provided by most operating systems. They use a \fBstruct hostent\fR which is usually defined in \fI\fR. .PP .RS 4 .nf struct hostent { char *h_name; /* official name of host */ char **h_aliases; /* alias list */ int h_addrtype; /* host address type */ int h_length; /* length of address */ char **h_addr_list; /* list of addresses from name server */ }; #define h_addr h_addr_list[0] /* address, for backward compatibility */ .fi .RE .sp .PP The members of this structure are: .PP \fBh_name\fR .RS 4 The official (canonical) name of the host. .RE .PP \fBh_aliases\fR .RS 4 A NULL\-terminated array of alternate names (nicknames) for the host. .RE .PP \fBh_addrtype\fR .RS 4 The type of address being returned \(em \fBPF_INET\fR or \fBPF_INET6\fR. .RE .PP \fBh_length\fR .RS 4 The length of the address in bytes. .RE .PP \fBh_addr_list\fR .RS 4 A \fBNULL\fR terminated array of network addresses for the host. Host addresses are returned in network byte order. .RE .PP For backward compatibility with very old software, \fBh_addr\fR is the first address in \fBh_addr_list.\fR .PP \fBlwres_gethostent()\fR, \fBlwres_sethostent()\fR, \fBlwres_endhostent()\fR, \fBlwres_gethostent_r()\fR, \fBlwres_sethostent_r()\fR and \fBlwres_endhostent_r()\fR provide iteration over the known host entries on systems that provide such functionality through facilities like \fI/etc/hosts\fR or NIS. The lightweight resolver does not currently implement these functions; it only provides them as stub functions that always return failure. .PP \fBlwres_gethostbyname()\fR and \fBlwres_gethostbyname2()\fR look up the hostname \fIname\fR. \fBlwres_gethostbyname()\fR always looks for an IPv4 address while \fBlwres_gethostbyname2()\fR looks for an address of protocol family \fIaf\fR: either \fBPF_INET\fR or \fBPF_INET6\fR \(em IPv4 or IPV6 addresses respectively. Successful calls of the functions return a \fBstruct hostent\fRfor the name that was looked up. \fBNULL\fR is returned if the lookups by \fBlwres_gethostbyname()\fR or \fBlwres_gethostbyname2()\fR fail. .PP Reverse lookups of addresses are performed by \fBlwres_gethostbyaddr()\fR. \fIaddr\fR is an address of length \fIlen\fR bytes and protocol family \fItype\fR \(em \fBPF_INET\fR or \fBPF_INET6\fR. \fBlwres_gethostbyname_r()\fR is a thread\-safe function for forward lookups. If an error occurs, an error code is returned in \fI*error\fR. \fIresbuf\fR is a pointer to a \fBstruct hostent\fR which is initialised by a successful call to \fBlwres_gethostbyname_r()\fR. \fIbuf\fR is a buffer of length \fIlen\fR bytes which is used to store the \fBh_name\fR, \fBh_aliases\fR, and \fBh_addr_list\fR elements of the \fBstruct hostent\fR returned in \fIresbuf\fR. Successful calls to \fBlwres_gethostbyname_r()\fR return \fIresbuf\fR, which is a pointer to the \fBstruct hostent\fR it created. .PP \fBlwres_gethostbyaddr_r()\fR is a thread\-safe function that performs a reverse lookup of address \fIaddr\fR which is \fIlen\fR bytes long and is of protocol family \fItype\fR \(em \fBPF_INET\fR or \fBPF_INET6\fR. If an error occurs, the error code is returned in \fI*error\fR. The other function parameters are identical to those in \fBlwres_gethostbyname_r()\fR. \fIresbuf\fR is a pointer to a \fBstruct hostent\fR which is initialised by a successful call to \fBlwres_gethostbyaddr_r()\fR. \fIbuf\fR is a buffer of length \fIlen\fR bytes which is used to store the \fBh_name\fR, \fBh_aliases\fR, and \fBh_addr_list\fR elements of the \fBstruct hostent\fR returned in \fIresbuf\fR. Successful calls to \fBlwres_gethostbyaddr_r()\fR return \fIresbuf\fR, which is a pointer to the \fBstruct hostent()\fR it created. .SH "RETURN VALUES" .PP The functions \fBlwres_gethostbyname()\fR, \fBlwres_gethostbyname2()\fR, \fBlwres_gethostbyaddr()\fR, and \fBlwres_gethostent()\fR return NULL to indicate an error. In this case the global variable \fBlwres_h_errno\fR will contain one of the following error codes defined in \fI\fR: .PP \fBHOST_NOT_FOUND\fR .RS 4 The host or address was not found. .RE .PP \fBTRY_AGAIN\fR .RS 4 A recoverable error occurred, e.g., a timeout. Retrying the lookup may succeed. .RE .PP \fBNO_RECOVERY\fR .RS 4 A non\-recoverable error occurred. .RE .PP \fBNO_DATA\fR .RS 4 The name exists, but has no address information associated with it (or vice versa in the case of a reverse lookup). The code NO_ADDRESS is accepted as a synonym for NO_DATA for backwards compatibility. .RE .PP \fBlwres_hstrerror\fR(3) translates these error codes to suitable error messages. .PP \fBlwres_gethostent()\fR and \fBlwres_gethostent_r()\fR always return \fBNULL\fR. .PP Successful calls to \fBlwres_gethostbyname_r()\fR and \fBlwres_gethostbyaddr_r()\fR return \fIresbuf\fR, a pointer to the \fBstruct hostent\fR that was initialised by these functions. They return \fBNULL\fR if the lookups fail or if \fIbuf\fR was too small to hold the list of addresses and names referenced by the \fBh_name\fR, \fBh_aliases\fR, and \fBh_addr_list\fR elements of the \fBstruct hostent\fR. If \fIbuf\fR was too small, both \fBlwres_gethostbyname_r()\fR and \fBlwres_gethostbyaddr_r()\fR set the global variable \fBerrno\fR to \fBERANGE\fR. .SH "SEE ALSO" .PP \fBgethostent\fR(3), \fBlwres_getipnode\fR(3), \fBlwres_hstrerror\fR(3) .SH "BUGS" .PP \fBlwres_gethostbyname()\fR, \fBlwres_gethostbyname2()\fR, \fBlwres_gethostbyaddr()\fR and \fBlwres_endhostent()\fR are not thread safe; they return pointers to static data and provide error codes through a global variable. Thread\-safe versions for name and address lookup are provided by \fBlwres_gethostbyname_r()\fR, and \fBlwres_gethostbyaddr_r()\fR respectively. .PP The resolver daemon does not currently support any non\-DNS name services such as \fI/etc/hosts\fR or \fBNIS\fR, consequently the above functions don't, either. .SH "COPYRIGHT" Copyright \(co 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2001 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_buffer.html0000644000470500017500000003511312664710322021424 0ustar lamontlamont lwres_buffer

Name

lwres_buffer_init, lwres_buffer_invalidate, lwres_buffer_add, lwres_buffer_subtract, lwres_buffer_clear, lwres_buffer_first, lwres_buffer_forward, lwres_buffer_back, lwres_buffer_getuint8, lwres_buffer_putuint8, lwres_buffer_getuint16, lwres_buffer_putuint16, lwres_buffer_getuint32, lwres_buffer_putuint32, lwres_buffer_putmem, lwres_buffer_getmem — lightweight resolver buffer management

Synopsis

#include <lwres/lwbuffer.h>
void lwres_buffer_init( lwres_buffer_t *  b,
  void *  base,
  unsigned int   length);
void lwres_buffer_invalidate( lwres_buffer_t *  b);
void lwres_buffer_add( lwres_buffer_t *  b,
  unsigned int   n);
void lwres_buffer_subtract( lwres_buffer_t *  b,
  unsigned int   n);
void lwres_buffer_clear( lwres_buffer_t *  b);
void lwres_buffer_first( lwres_buffer_t *  b);
void lwres_buffer_forward( lwres_buffer_t *  b,
  unsigned int   n);
void lwres_buffer_back( lwres_buffer_t *  b,
  unsigned int   n);
lwres_uint8_t lwres_buffer_getuint8( lwres_buffer_t *  b);
void lwres_buffer_putuint8( lwres_buffer_t *  b,
  lwres_uint8_t   val);
lwres_uint16_t lwres_buffer_getuint16( lwres_buffer_t *  b);
void lwres_buffer_putuint16( lwres_buffer_t *  b,
  lwres_uint16_t   val);
lwres_uint32_t lwres_buffer_getuint32( lwres_buffer_t *  b);
void lwres_buffer_putuint32( lwres_buffer_t *  b,
  lwres_uint32_t   val);
void lwres_buffer_putmem( lwres_buffer_t *  b,
  const unsigned char *  base,
  unsigned int   length);
void lwres_buffer_getmem( lwres_buffer_t *  b,
  unsigned char *  base,
  unsigned int   length);

DESCRIPTION

These functions provide bounds checked access to a region of memory where data is being read or written. They are based on, and similar to, the isc_buffer_ functions in the ISC library.

A buffer is a region of memory, together with a set of related subregions. The used region and the available region are disjoint, and their union is the buffer's region. The used region extends from the beginning of the buffer region to the last used byte. The available region extends from one byte greater than the last used byte to the end of the buffer's region. The size of the used region can be changed using various buffer commands. Initially, the used region is empty.

The used region is further subdivided into two disjoint regions: the consumed region and the remaining region. The union of these two regions is the used region. The consumed region extends from the beginning of the used region to the byte before the current offset (if any). The remaining region the current pointer to the end of the used region. The size of the consumed region can be changed using various buffer commands. Initially, the consumed region is empty.

The active region is an (optional) subregion of the remaining region. It extends from the current offset to an offset in the remaining region. Initially, the active region is empty. If the current offset advances beyond the chosen offset, the active region will also be empty.

   /------------entire length---------------\\
   /----- used region -----\\/-- available --\\
   +----------------------------------------+
   | consumed  | remaining |                |
   +----------------------------------------+
   a           b     c     d                e
      

  a == base of buffer.
  b == current pointer.  Can be anywhere between a and d.
  c == active pointer.  Meaningful between b and d.
  d == used pointer.
  e == length of buffer.
      

  a-e == entire length of buffer.
  a-d == used region.
  a-b == consumed region.
  b-d == remaining region.
  b-c == optional active region.

lwres_buffer_init() initializes the lwres_buffer_t *b and assocates it with the memory region of size length bytes starting at location base.

lwres_buffer_invalidate() marks the buffer *b as invalid. Invalidating a buffer after use is not required, but makes it possible to catch its possible accidental use.

The functions lwres_buffer_add() and lwres_buffer_subtract() respectively increase and decrease the used space in buffer *b by n bytes. lwres_buffer_add() checks for buffer overflow and lwres_buffer_subtract() checks for underflow. These functions do not allocate or deallocate memory. They just change the value of used.

A buffer is re-initialised by lwres_buffer_clear(). The function sets used, current and active to zero.

lwres_buffer_first makes the consumed region of buffer *p empty by setting current to zero (the start of the buffer).

lwres_buffer_forward() increases the consumed region of buffer *b by n bytes, checking for overflow. Similarly, lwres_buffer_back() decreases buffer b's consumed region by n bytes and checks for underflow.

lwres_buffer_getuint8() reads an unsigned 8-bit integer from *b and returns it. lwres_buffer_putuint8() writes the unsigned 8-bit integer val to buffer *b.

lwres_buffer_getuint16() and lwres_buffer_getuint32() are identical to lwres_buffer_putuint8() except that they respectively read an unsigned 16-bit or 32-bit integer in network byte order from b. Similarly, lwres_buffer_putuint16() and lwres_buffer_putuint32() writes the unsigned 16-bit or 32-bit integer val to buffer b, in network byte order.

Arbitrary amounts of data are read or written from a lightweight resolver buffer with lwres_buffer_getmem() and lwres_buffer_putmem() respectively. lwres_buffer_putmem() copies length bytes of memory at base to b. Conversely, lwres_buffer_getmem() copies length bytes of memory from b to base.

bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_context.30000644000470500017500000001347112664710322021040 0ustar lamontlamont.\" Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001, 2003 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: lwres_context .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: June 18, 2007 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "LWRES_CONTEXT" "3" "June 18, 2007" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" lwres_context_create, lwres_context_destroy, lwres_context_nextserial, lwres_context_initserial, lwres_context_freemem, lwres_context_allocmem, lwres_context_sendrecv \- lightweight resolver context management .SH "SYNOPSIS" .nf #include .fi .HP 36 .BI "lwres_result_t lwres_context_create(lwres_context_t\ **" "contextp" ", void\ *" "arg" ", lwres_malloc_t\ " "malloc_function" ", lwres_free_t\ " "free_function" ");" .HP 37 .BI "lwres_result_t lwres_context_destroy(lwres_context_t\ **" "contextp" ");" .HP 30 .BI "void lwres_context_initserial(lwres_context_t\ *" "ctx" ", lwres_uint32_t\ " "serial" ");" .HP 40 .BI "lwres_uint32_t lwres_context_nextserial(lwres_context_t\ *" "ctx" ");" .HP 27 .BI "void lwres_context_freemem(lwres_context_t\ *" "ctx" ", void\ *" "mem" ", size_t\ " "len" ");" .HP 28 .BI "void lwres_context_allocmem(lwres_context_t\ *" "ctx" ", size_t\ " "len" ");" .HP 30 .BI "void * lwres_context_sendrecv(lwres_context_t\ *" "ctx" ", void\ *" "sendbase" ", int\ " "sendlen" ", void\ *" "recvbase" ", int\ " "recvlen" ", int\ *" "recvd_len" ");" .SH "DESCRIPTION" .PP \fBlwres_context_create()\fR creates a \fBlwres_context_t\fR structure for use in lightweight resolver operations. It holds a socket and other data needed for communicating with a resolver daemon. The new \fBlwres_context_t\fR is returned through \fIcontextp\fR, a pointer to a \fBlwres_context_t\fR pointer. This \fBlwres_context_t\fR pointer must initially be NULL, and is modified to point to the newly created \fBlwres_context_t\fR. .PP When the lightweight resolver needs to perform dynamic memory allocation, it will call \fImalloc_function\fR to allocate memory and \fIfree_function\fR to free it. If \fImalloc_function\fR and \fIfree_function\fR are NULL, memory is allocated using \fBmalloc\fR(3). and \fBfree\fR(3). It is not permitted to have a NULL \fImalloc_function\fR and a non\-NULL \fIfree_function\fR or vice versa. \fIarg\fR is passed as the first parameter to the memory allocation functions. If \fImalloc_function\fR and \fIfree_function\fR are NULL, \fIarg\fR is unused and should be passed as NULL. .PP Once memory for the structure has been allocated, it is initialized using \fBlwres_conf_init\fR(3) and returned via \fI*contextp\fR. .PP \fBlwres_context_destroy()\fR destroys a \fBlwres_context_t\fR, closing its socket. \fIcontextp\fR is a pointer to a pointer to the context that is to be destroyed. The pointer will be set to NULL when the context has been destroyed. .PP The context holds a serial number that is used to identify resolver request packets and associate responses with the corresponding requests. This serial number is controlled using \fBlwres_context_initserial()\fR and \fBlwres_context_nextserial()\fR. \fBlwres_context_initserial()\fR sets the serial number for context \fI*ctx\fR to \fIserial\fR. \fBlwres_context_nextserial()\fR increments the serial number and returns the previous value. .PP Memory for a lightweight resolver context is allocated and freed using \fBlwres_context_allocmem()\fR and \fBlwres_context_freemem()\fR. These use whatever allocations were defined when the context was created with \fBlwres_context_create()\fR. \fBlwres_context_allocmem()\fR allocates \fIlen\fR bytes of memory and if successful returns a pointer to the allocated storage. \fBlwres_context_freemem()\fR frees \fIlen\fR bytes of space starting at location \fImem\fR. .PP \fBlwres_context_sendrecv()\fR performs I/O for the context \fIctx\fR. Data are read and written from the context's socket. It writes data from \fIsendbase\fR \(em typically a lightweight resolver query packet \(em and waits for a reply which is copied to the receive buffer at \fIrecvbase\fR. The number of bytes that were written to this receive buffer is returned in \fI*recvd_len\fR. .SH "RETURN VALUES" .PP \fBlwres_context_create()\fR returns \fBLWRES_R_NOMEMORY\fR if memory for the \fBstruct lwres_context\fR could not be allocated, \fBLWRES_R_SUCCESS\fR otherwise. .PP Successful calls to the memory allocator \fBlwres_context_allocmem()\fR return a pointer to the start of the allocated space. It returns NULL if memory could not be allocated. .PP \fBLWRES_R_SUCCESS\fR is returned when \fBlwres_context_sendrecv()\fR completes successfully. \fBLWRES_R_IOERROR\fR is returned if an I/O error occurs and \fBLWRES_R_TIMEOUT\fR is returned if \fBlwres_context_sendrecv()\fR times out waiting for a response. .SH "SEE ALSO" .PP \fBlwres_conf_init\fR(3), \fBmalloc\fR(3), \fBfree\fR(3). .SH "COPYRIGHT" Copyright \(co 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000, 2001, 2003 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_getaddrinfo.docbook0000644000470500017500000003163712664710322023124 0ustar lamontlamont]> June 18, 2007 lwres_getaddrinfo 3 BIND9 2004 2005 2007 2014 Internet Systems Consortium, Inc. ("ISC") 2000 2001 2003 Internet Software Consortium. lwres_getaddrinfo lwres_freeaddrinfo socket address structure to host and service name #include <lwres/netdb.h> int lwres_getaddrinfo const char *hostname const char *servname const struct addrinfo *hints struct addrinfo **res void lwres_freeaddrinfo struct addrinfo *ai If the operating system does not provide a struct addrinfo, the following structure is used: struct addrinfo { int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ int ai_family; /* PF_xxx */ int ai_socktype; /* SOCK_xxx */ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ size_t ai_addrlen; /* length of ai_addr */ char *ai_canonname; /* canonical name for hostname */ struct sockaddr *ai_addr; /* binary address */ struct addrinfo *ai_next; /* next structure in linked list */ }; DESCRIPTION lwres_getaddrinfo() is used to get a list of IP addresses and port numbers for host hostname and service servname. The function is the lightweight resolver's implementation of getaddrinfo() as defined in RFC2133. hostname and servname are pointers to null-terminated strings or NULL. hostname is either a host name or a numeric host address string: a dotted decimal IPv4 address or an IPv6 address. servname is either a decimal port number or a service name as listed in /etc/services. hints is an optional pointer to a struct addrinfo. This structure can be used to provide hints concerning the type of socket that the caller supports or wishes to use. The caller can supply the following structure elements in *hints: ai_family The protocol family that should be used. When ai_family is set to PF_UNSPEC, it means the caller will accept any protocol family supported by the operating system. ai_socktype denotes the type of socket — SOCK_STREAM, SOCK_DGRAM or SOCK_RAW — that is wanted. When ai_socktype is zero the caller will accept any socket type. ai_protocol indicates which transport protocol is wanted: IPPROTO_UDP or IPPROTO_TCP. If ai_protocol is zero the caller will accept any protocol. ai_flags Flag bits. If the AI_CANONNAME bit is set, a successful call to lwres_getaddrinfo() will return a null-terminated string containing the canonical name of the specified hostname in ai_canonname of the first addrinfo structure returned. Setting the AI_PASSIVE bit indicates that the returned socket address structure is intended for used in a call to bind2 . In this case, if the hostname argument is a NULL pointer, then the IP address portion of the socket address structure will be set to INADDR_ANY for an IPv4 address or IN6ADDR_ANY_INIT for an IPv6 address. When ai_flags does not set the AI_PASSIVE bit, the returned socket address structure will be ready for use in a call to connect2 for a connection-oriented protocol or connect2 , sendto2 , or sendmsg2 if a connectionless protocol was chosen. The IP address portion of the socket address structure will be set to the loopback address if hostname is a NULL pointer and AI_PASSIVE is not set in ai_flags. If ai_flags is set to AI_NUMERICHOST it indicates that hostname should be treated as a numeric string defining an IPv4 or IPv6 address and no name resolution should be attempted. All other elements of the struct addrinfo passed via hints must be zero. A hints of NULL is treated as if the caller provided a struct addrinfo initialized to zero with ai_familyset to PF_UNSPEC. After a successful call to lwres_getaddrinfo(), *res is a pointer to a linked list of one or more addrinfo structures. Each struct addrinfo in this list cn be processed by following the ai_next pointer, until a NULL pointer is encountered. The three members ai_family, ai_socktype, and ai_protocol in each returned addrinfo structure contain the corresponding arguments for a call to socket2 . For each addrinfo structure in the list, the ai_addr member points to a filled-in socket address structure of length ai_addrlen. All of the information returned by lwres_getaddrinfo() is dynamically allocated: the addrinfo structures, and the socket address structures and canonical host name strings pointed to by the addrinfostructures. Memory allocated for the dynamically allocated structures created by a successful call to lwres_getaddrinfo() is released by lwres_freeaddrinfo(). ai is a pointer to a struct addrinfo created by a call to lwres_getaddrinfo(). RETURN VALUES lwres_getaddrinfo() returns zero on success or one of the error codes listed in gai_strerror3 if an error occurs. If both hostname and servname are NULL lwres_getaddrinfo() returns EAI_NONAME. SEE ALSO lwres3 , lwres_getaddrinfo3 , lwres_freeaddrinfo3 , lwres_gai_strerror3 , RFC2133 , getservbyname3 , bind2 , connect2 , sendto2 , sendmsg2 , socket2 . bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_resutil.docbook0000644000470500017500000002117112664710322022315 0ustar lamontlamont]> June 18, 2007 lwres_resutil 3 BIND9 2004 2005 2007 2014 Internet Systems Consortium, Inc. ("ISC") 2000 2001 Internet Software Consortium. lwres_string_parse lwres_addr_parse lwres_getaddrsbyname lwres_getnamebyaddr lightweight resolver utility functions #include <lwres/lwres.h> lwres_result_t lwres_string_parse lwres_buffer_t *b char **c lwres_uint16_t *len lwres_result_t lwres_addr_parse lwres_buffer_t *b lwres_addr_t *addr lwres_result_t lwres_getaddrsbyname lwres_context_t *ctx const char *name lwres_uint32_t addrtypes lwres_gabnresponse_t **structp lwres_result_t lwres_getnamebyaddr lwres_context_t *ctx lwres_uint32_t addrtype lwres_uint16_t addrlen const unsigned char *addr lwres_gnbaresponse_t **structp DESCRIPTION lwres_string_parse() retrieves a DNS-encoded string starting the current pointer of lightweight resolver buffer b: i.e. b->current. When the function returns, the address of the first byte of the encoded string is returned via *c and the length of that string is given by *len. The buffer's current pointer is advanced to point at the character following the string length, the encoded string, and the trailing NULL character. lwres_addr_parse() extracts an address from the buffer b. The buffer's current pointer b->current is presumed to point at an encoded address: the address preceded by a 32-bit protocol family identifier and a 16-bit length field. The encoded address is copied to addr->address and addr->length indicates the size in bytes of the address that was copied. b->current is advanced to point at the next byte of available data in the buffer following the encoded address. lwres_getaddrsbyname() and lwres_getnamebyaddr() use the lwres_gnbaresponse_t structure defined below: typedef struct { lwres_uint32_t flags; lwres_uint16_t naliases; lwres_uint16_t naddrs; char *realname; char **aliases; lwres_uint16_t realnamelen; lwres_uint16_t *aliaslen; lwres_addrlist_t addrs; void *base; size_t baselen; } lwres_gabnresponse_t; The contents of this structure are not manipulated directly but they are controlled through the lwres_gabn3 functions. The lightweight resolver uses lwres_getaddrsbyname() to perform forward lookups. Hostname name is looked up using the resolver context ctx for memory allocation. addrtypes is a bitmask indicating which type of addresses are to be looked up. Current values for this bitmask are LWRES_ADDRTYPE_V4 for IPv4 addresses and LWRES_ADDRTYPE_V6 for IPv6 addresses. Results of the lookup are returned in *structp. lwres_getnamebyaddr() performs reverse lookups. Resolver context ctx is used for memory allocation. The address type is indicated by addrtype: LWRES_ADDRTYPE_V4 or LWRES_ADDRTYPE_V6. The address to be looked up is given by addr and its length is addrlen bytes. The result of the function call is made available through *structp. RETURN VALUES Successful calls to lwres_string_parse() and lwres_addr_parse() return LWRES_R_SUCCESS. Both functions return LWRES_R_FAILURE if the buffer is corrupt or LWRES_R_UNEXPECTEDEND if the buffer has less space than expected for the components of the encoded string or address. lwres_getaddrsbyname() returns LWRES_R_SUCCESS on success and it returns LWRES_R_NOTFOUND if the hostname name could not be found. LWRES_R_SUCCESS is returned by a successful call to lwres_getnamebyaddr(). Both lwres_getaddrsbyname() and lwres_getnamebyaddr() return LWRES_R_NOMEMORY when memory allocation requests fail and LWRES_R_UNEXPECTEDEND if the buffers used for sending queries and receiving replies are too small. SEE ALSO lwres_buffer3 , lwres_gabn3 . bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres.docbook0000644000470500017500000002272112664710322020550 0ustar lamontlamont]> June 18, 2007 lwres 3 BIND9 lwres introduction to the lightweight resolver library 2004 2005 2007 2014 Internet Systems Consortium, Inc. ("ISC") 2000 2001 Internet Software Consortium. #include <lwres/lwres.h> DESCRIPTION The BIND 9 lightweight resolver library is a simple, name service independent stub resolver library. It provides hostname-to-address and address-to-hostname lookup services to applications by transmitting lookup requests to a resolver daemon lwresd running on the local host. The resolver daemon performs the lookup using the DNS or possibly other name service protocols, and returns the results to the application through the library. The library and resolver daemon communicate using a simple UDP-based protocol. OVERVIEW The lwresd library implements multiple name service APIs. The standard gethostbyname(), gethostbyaddr(), gethostbyname_r(), gethostbyaddr_r(), getaddrinfo(), getipnodebyname(), and getipnodebyaddr() functions are all supported. To allow the lwres library to coexist with system libraries that define functions of the same name, the library defines these functions with names prefixed by lwres_. To define the standard names, applications must include the header file <lwres/netdb.h> which contains macro definitions mapping the standard function names into lwres_ prefixed ones. Operating system vendors who integrate the lwres library into their base distributions should rename the functions in the library proper so that the renaming macros are not needed. The library also provides a native API consisting of the functions lwres_getaddrsbyname() and lwres_getnamebyaddr(). These may be called by applications that require more detailed control over the lookup process than the standard functions provide. In addition to these name service independent address lookup functions, the library implements a new, experimental API for looking up arbitrary DNS resource records, using the lwres_getaddrsbyname() function. Finally, there is a low-level API for converting lookup requests and responses to and from raw lwres protocol packets. This API can be used by clients requiring nonblocking operation, and is also used when implementing the server side of the lwres protocol, for example in the lwresd resolver daemon. The use of this low-level API in clients and servers is outlined in the following sections. CLIENT-SIDE LOW-LEVEL API CALL FLOW When a client program wishes to make an lwres request using the native low-level API, it typically performs the following sequence of actions. (1) Allocate or use an existing lwres_packet_t, called pkt below. (2) Set pkt.recvlength to the maximum length we will accept. This is done so the receiver of our packets knows how large our receive buffer is. The "default" is a constant in lwres.h: LWRES_RECVLENGTH = 4096. (3) Set pkt.serial to a unique serial number. This value is echoed back to the application by the remote server. (4) Set pkt.pktflags. Usually this is set to 0. (5) Set pkt.result to 0. (6) Call lwres_*request_render(), or marshall in the data using the primitives such as lwres_packet_render() and storing the packet data. (7) Transmit the resulting buffer. (8) Call lwres_*response_parse() to parse any packets received. (9) Verify that the opcode and serial match a request, and process the packet specific information contained in the body. SERVER-SIDE LOW-LEVEL API CALL FLOW When implementing the server side of the lightweight resolver protocol using the lwres library, a sequence of actions like the following is typically involved in processing each request packet. Note that the same lwres_packet_t is used in both the _parse() and _render() calls, with only a few modifications made to the packet header's contents between uses. This method is recommended as it keeps the serial, opcode, and other fields correct. (1) When a packet is received, call lwres_*request_parse() to unmarshall it. This returns a lwres_packet_t (also called pkt, below) as well as a data specific type, such as lwres_gabnrequest_t. (2) Process the request in the data specific type. (3) Set the pkt.result, pkt.recvlength as above. All other fields can be left untouched since they were filled in by the *_parse() call above. If using lwres_*response_render(), pkt.pktflags will be set up properly. Otherwise, the LWRES_LWPACKETFLAG_RESPONSE bit should be set. (4) Call the data specific rendering function, such as lwres_gabnresponse_render(). (5) Send the resulting packet to the client. SEE ALSO lwres_gethostent3 , lwres_getipnode3 , lwres_getnameinfo3 , lwres_noop3 , lwres_gabn3 , lwres_gnba3 , lwres_context3 , lwres_config3 , resolver5 , lwresd8 . bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_gethostent.docbook0000644000470500017500000003763212664710322023023 0ustar lamontlamont]> June 18, 2007 lwres_gethostent 3 BIND9 2004 2005 2007 2014 Internet Systems Consortium, Inc. ("ISC") 2001 Internet Software Consortium. lwres_gethostbyname lwres_gethostbyname2 lwres_gethostbyaddr lwres_gethostent lwres_sethostent lwres_endhostent lwres_gethostbyname_r lwres_gethostbyaddr_r lwres_gethostent_r lwres_sethostent_r lwres_endhostent_r lightweight resolver get network host entry #include <lwres/netdb.h> struct hostent * lwres_gethostbyname const char *name struct hostent * lwres_gethostbyname2 const char *name int af struct hostent * lwres_gethostbyaddr const char *addr int len int type struct hostent * lwres_gethostent void void lwres_sethostent int stayopen void lwres_endhostent void struct hostent * lwres_gethostbyname_r const char *name struct hostent *resbuf char *buf int buflen int *error struct hostent * lwres_gethostbyaddr_r const char *addr int len int type struct hostent *resbuf char *buf int buflen int *error struct hostent * lwres_gethostent_r struct hostent *resbuf char *buf int buflen int *error void lwres_sethostent_r int stayopen void lwres_endhostent_r void DESCRIPTION These functions provide hostname-to-address and address-to-hostname lookups by means of the lightweight resolver. They are similar to the standard gethostent3 functions provided by most operating systems. They use a struct hostent which is usually defined in <namedb.h>. struct hostent { char *h_name; /* official name of host */ char **h_aliases; /* alias list */ int h_addrtype; /* host address type */ int h_length; /* length of address */ char **h_addr_list; /* list of addresses from name server */ }; #define h_addr h_addr_list[0] /* address, for backward compatibility */ The members of this structure are: h_name The official (canonical) name of the host. h_aliases A NULL-terminated array of alternate names (nicknames) for the host. h_addrtype The type of address being returned — PF_INET or PF_INET6. h_length The length of the address in bytes. h_addr_list A NULL terminated array of network addresses for the host. Host addresses are returned in network byte order. For backward compatibility with very old software, h_addr is the first address in h_addr_list. lwres_gethostent(), lwres_sethostent(), lwres_endhostent(), lwres_gethostent_r(), lwres_sethostent_r() and lwres_endhostent_r() provide iteration over the known host entries on systems that provide such functionality through facilities like /etc/hosts or NIS. The lightweight resolver does not currently implement these functions; it only provides them as stub functions that always return failure. lwres_gethostbyname() and lwres_gethostbyname2() look up the hostname name. lwres_gethostbyname() always looks for an IPv4 address while lwres_gethostbyname2() looks for an address of protocol family af: either PF_INET or PF_INET6 — IPv4 or IPV6 addresses respectively. Successful calls of the functions return a struct hostentfor the name that was looked up. NULL is returned if the lookups by lwres_gethostbyname() or lwres_gethostbyname2() fail. Reverse lookups of addresses are performed by lwres_gethostbyaddr(). addr is an address of length len bytes and protocol family typePF_INET or PF_INET6. lwres_gethostbyname_r() is a thread-safe function for forward lookups. If an error occurs, an error code is returned in *error. resbuf is a pointer to a struct hostent which is initialised by a successful call to lwres_gethostbyname_r(). buf is a buffer of length len bytes which is used to store the h_name, h_aliases, and h_addr_list elements of the struct hostent returned in resbuf. Successful calls to lwres_gethostbyname_r() return resbuf, which is a pointer to the struct hostent it created. lwres_gethostbyaddr_r() is a thread-safe function that performs a reverse lookup of address addr which is len bytes long and is of protocol family typePF_INET or PF_INET6. If an error occurs, the error code is returned in *error. The other function parameters are identical to those in lwres_gethostbyname_r(). resbuf is a pointer to a struct hostent which is initialised by a successful call to lwres_gethostbyaddr_r(). buf is a buffer of length len bytes which is used to store the h_name, h_aliases, and h_addr_list elements of the struct hostent returned in resbuf. Successful calls to lwres_gethostbyaddr_r() return resbuf, which is a pointer to the struct hostent() it created. RETURN VALUES The functions lwres_gethostbyname(), lwres_gethostbyname2(), lwres_gethostbyaddr(), and lwres_gethostent() return NULL to indicate an error. In this case the global variable lwres_h_errno will contain one of the following error codes defined in <lwres/netdb.h>: HOST_NOT_FOUND The host or address was not found. TRY_AGAIN A recoverable error occurred, e.g., a timeout. Retrying the lookup may succeed. NO_RECOVERY A non-recoverable error occurred. NO_DATA The name exists, but has no address information associated with it (or vice versa in the case of a reverse lookup). The code NO_ADDRESS is accepted as a synonym for NO_DATA for backwards compatibility. lwres_hstrerror3 translates these error codes to suitable error messages. lwres_gethostent() and lwres_gethostent_r() always return NULL. Successful calls to lwres_gethostbyname_r() and lwres_gethostbyaddr_r() return resbuf, a pointer to the struct hostent that was initialised by these functions. They return NULL if the lookups fail or if buf was too small to hold the list of addresses and names referenced by the h_name, h_aliases, and h_addr_list elements of the struct hostent. If buf was too small, both lwres_gethostbyname_r() and lwres_gethostbyaddr_r() set the global variable errno to ERANGE. SEE ALSO gethostent3 , lwres_getipnode3 , lwres_hstrerror3 BUGS lwres_gethostbyname(), lwres_gethostbyname2(), lwres_gethostbyaddr() and lwres_endhostent() are not thread safe; they return pointers to static data and provide error codes through a global variable. Thread-safe versions for name and address lookup are provided by lwres_gethostbyname_r(), and lwres_gethostbyaddr_r() respectively. The resolver daemon does not currently support any non-DNS name services such as /etc/hosts or NIS, consequently the above functions don't, either. bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_hstrerror.html0000644000470500017500000001025012664710322022200 0ustar lamontlamont lwres_hstrerror

Name

lwres_herror, lwres_hstrerror — lightweight resolver error message generation

Synopsis

#include <lwres/netdb.h>
void lwres_herror( const char *  s);
const char * lwres_hstrerror( int   err);

DESCRIPTION

lwres_herror() prints the string s on stderr followed by the string generated by lwres_hstrerror() for the error code stored in the global variable lwres_h_errno.

lwres_hstrerror() returns an appropriate string for the error code gievn by err. The values of the error codes and messages are as follows:

NETDB_SUCCESS

Resolver Error 0 (no error)

HOST_NOT_FOUND

Unknown host

TRY_AGAIN

Host name lookup failure

NO_RECOVERY

Unknown server error

NO_DATA

No address associated with name

RETURN VALUES

The string Unknown resolver error is returned by lwres_hstrerror() when the value of lwres_h_errno is not a valid error code.

SEE ALSO

herror(3), lwres_hstrerror(3).

bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_gabn.docbook0000644000470500017500000002334112664710322021536 0ustar lamontlamont]> June 18, 2007 lwres_gabn 3 BIND9 2004 2005 2007 2014 Internet Systems Consortium, Inc. ("ISC") 2000 2001 Internet Software Consortium. lwres_gabnrequest_render lwres_gabnresponse_render lwres_gabnrequest_parse lwres_gabnresponse_parse lwres_gabnresponse_free lwres_gabnrequest_free lightweight resolver getaddrbyname message handling #include <lwres/lwres.h> lwres_result_t lwres_gabnrequest_render lwres_context_t *ctx lwres_gabnrequest_t *req lwres_lwpacket_t *pkt lwres_buffer_t *b lwres_result_t lwres_gabnresponse_render lwres_context_t *ctx lwres_gabnresponse_t *req lwres_lwpacket_t *pkt lwres_buffer_t *b lwres_result_t lwres_gabnrequest_parse lwres_context_t *ctx lwres_buffer_t *b lwres_lwpacket_t *pkt lwres_gabnrequest_t **structp lwres_result_t lwres_gabnresponse_parse lwres_context_t *ctx lwres_buffer_t *b lwres_lwpacket_t *pkt lwres_gabnresponse_t **structp void lwres_gabnresponse_free lwres_context_t *ctx lwres_gabnresponse_t **structp void lwres_gabnrequest_free lwres_context_t *ctx lwres_gabnrequest_t **structp DESCRIPTION These are low-level routines for creating and parsing lightweight resolver name-to-address lookup request and response messages. There are four main functions for the getaddrbyname opcode. One render function converts a getaddrbyname request structure — lwres_gabnrequest_t — to the lightweight resolver's canonical format. It is complemented by a parse function that converts a packet in this canonical format to a getaddrbyname request structure. Another render function converts the getaddrbyname response structure — lwres_gabnresponse_t — to the canonical format. This is complemented by a parse function which converts a packet in canonical format to a getaddrbyname response structure. These structures are defined in <lwres/lwres.h>. They are shown below. #define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U typedef struct lwres_addr lwres_addr_t; typedef LWRES_LIST(lwres_addr_t) lwres_addrlist_t; typedef struct { lwres_uint32_t flags; lwres_uint32_t addrtypes; lwres_uint16_t namelen; char *name; } lwres_gabnrequest_t; typedef struct { lwres_uint32_t flags; lwres_uint16_t naliases; lwres_uint16_t naddrs; char *realname; char **aliases; lwres_uint16_t realnamelen; lwres_uint16_t *aliaslen; lwres_addrlist_t addrs; void *base; size_t baselen; } lwres_gabnresponse_t; lwres_gabnrequest_render() uses resolver context ctx to convert getaddrbyname request structure req to canonical format. The packet header structure pkt is initialised and transferred to buffer b. The contents of *req are then appended to the buffer in canonical format. lwres_gabnresponse_render() performs the same task, except it converts a getaddrbyname response structure lwres_gabnresponse_t to the lightweight resolver's canonical format. lwres_gabnrequest_parse() uses context ctx to convert the contents of packet pkt to a lwres_gabnrequest_t structure. Buffer b provides space to be used for storing this structure. When the function succeeds, the resulting lwres_gabnrequest_t is made available through *structp. lwres_gabnresponse_parse() offers the same semantics as lwres_gabnrequest_parse() except it yields a lwres_gabnresponse_t structure. lwres_gabnresponse_free() and lwres_gabnrequest_free() release the memory in resolver context ctx that was allocated to the lwres_gabnresponse_t or lwres_gabnrequest_t structures referenced via structp. Any memory associated with ancillary buffers and strings for those structures is also discarded. RETURN VALUES The getaddrbyname opcode functions lwres_gabnrequest_render(), lwres_gabnresponse_render() lwres_gabnrequest_parse() and lwres_gabnresponse_parse() all return LWRES_R_SUCCESS on success. They return LWRES_R_NOMEMORY if memory allocation fails. LWRES_R_UNEXPECTEDEND is returned if the available space in the buffer b is too small to accommodate the packet header or the lwres_gabnrequest_t and lwres_gabnresponse_t structures. lwres_gabnrequest_parse() and lwres_gabnresponse_parse() will return LWRES_R_UNEXPECTEDEND if the buffer is not empty after decoding the received packet. These functions will return LWRES_R_FAILURE if pktflags in the packet header structure lwres_lwpacket_t indicate that the packet is not a response to an earlier query. SEE ALSO lwres_packet3 bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_gnba.docbook0000644000470500017500000002251212664710322021535 0ustar lamontlamont]> June 18, 2007 lwres_gnba 3 BIND9 2004 2005 2007 2014 Internet Systems Consortium, Inc. ("ISC") 2000 2001 Internet Software Consortium. lwres_gnbarequest_render lwres_gnbaresponse_render lwres_gnbarequest_parse lwres_gnbaresponse_parse lwres_gnbaresponse_free lwres_gnbarequest_free lightweight resolver getnamebyaddress message handling #include <lwres/lwres.h> lwres_result_t lwres_gnbarequest_render lwres_context_t *ctx lwres_gnbarequest_t *req lwres_lwpacket_t *pkt lwres_buffer_t *b lwres_result_t lwres_gnbaresponse_render lwres_context_t *ctx lwres_gnbaresponse_t *req lwres_lwpacket_t *pkt lwres_buffer_t *b lwres_result_t lwres_gnbarequest_parse lwres_context_t *ctx lwres_buffer_t *b lwres_lwpacket_t *pkt lwres_gnbarequest_t **structp lwres_result_t lwres_gnbaresponse_parse lwres_context_t *ctx lwres_buffer_t *b lwres_lwpacket_t *pkt lwres_gnbaresponse_t **structp void lwres_gnbaresponse_free lwres_context_t *ctx lwres_gnbaresponse_t **structp void lwres_gnbarequest_free lwres_context_t *ctx lwres_gnbarequest_t **structp DESCRIPTION These are low-level routines for creating and parsing lightweight resolver address-to-name lookup request and response messages. There are four main functions for the getnamebyaddr opcode. One render function converts a getnamebyaddr request structure — lwres_gnbarequest_t — to the lightweight resolver's canonical format. It is complemented by a parse function that converts a packet in this canonical format to a getnamebyaddr request structure. Another render function converts the getnamebyaddr response structure — lwres_gnbaresponse_t to the canonical format. This is complemented by a parse function which converts a packet in canonical format to a getnamebyaddr response structure. These structures are defined in lwres/lwres.h. They are shown below. #define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U typedef struct { lwres_uint32_t flags; lwres_addr_t addr; } lwres_gnbarequest_t; typedef struct { lwres_uint32_t flags; lwres_uint16_t naliases; char *realname; char **aliases; lwres_uint16_t realnamelen; lwres_uint16_t *aliaslen; void *base; size_t baselen; } lwres_gnbaresponse_t; lwres_gnbarequest_render() uses resolver context ctx to convert getnamebyaddr request structure req to canonical format. The packet header structure pkt is initialised and transferred to buffer b. The contents of *req are then appended to the buffer in canonical format. lwres_gnbaresponse_render() performs the same task, except it converts a getnamebyaddr response structure lwres_gnbaresponse_t to the lightweight resolver's canonical format. lwres_gnbarequest_parse() uses context ctx to convert the contents of packet pkt to a lwres_gnbarequest_t structure. Buffer b provides space to be used for storing this structure. When the function succeeds, the resulting lwres_gnbarequest_t is made available through *structp. lwres_gnbaresponse_parse() offers the same semantics as lwres_gnbarequest_parse() except it yields a lwres_gnbaresponse_t structure. lwres_gnbaresponse_free() and lwres_gnbarequest_free() release the memory in resolver context ctx that was allocated to the lwres_gnbaresponse_t or lwres_gnbarequest_t structures referenced via structp. Any memory associated with ancillary buffers and strings for those structures is also discarded. RETURN VALUES The getnamebyaddr opcode functions lwres_gnbarequest_render(), lwres_gnbaresponse_render() lwres_gnbarequest_parse() and lwres_gnbaresponse_parse() all return LWRES_R_SUCCESS on success. They return LWRES_R_NOMEMORY if memory allocation fails. LWRES_R_UNEXPECTEDEND is returned if the available space in the buffer b is too small to accommodate the packet header or the lwres_gnbarequest_t and lwres_gnbaresponse_t structures. lwres_gnbarequest_parse() and lwres_gnbaresponse_parse() will return LWRES_R_UNEXPECTEDEND if the buffer is not empty after decoding the received packet. These functions will return LWRES_R_FAILURE if pktflags in the packet header structure lwres_lwpacket_t indicate that the packet is not a response to an earlier query. SEE ALSO lwres_packet3 . bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_noop.30000644000470500017500000001406612664710322020330 0ustar lamontlamont.\" Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: lwres_noop .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: June 18, 2007 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "LWRES_NOOP" "3" "June 18, 2007" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" lwres_nooprequest_render, lwres_noopresponse_render, lwres_nooprequest_parse, lwres_noopresponse_parse, lwres_noopresponse_free, lwres_nooprequest_free \- lightweight resolver no\-op message handling .SH "SYNOPSIS" .nf #include .fi .HP 40 .BI "lwres_result_t lwres_nooprequest_render(lwres_context_t\ *" "ctx" ", lwres_nooprequest_t\ *" "req" ", lwres_lwpacket_t\ *" "pkt" ", lwres_buffer_t\ *" "b" ");" .HP 41 .BI "lwres_result_t lwres_noopresponse_render(lwres_context_t\ *" "ctx" ", lwres_noopresponse_t\ *" "req" ", lwres_lwpacket_t\ *" "pkt" ", lwres_buffer_t\ *" "b" ");" .HP 39 .BI "lwres_result_t lwres_nooprequest_parse(lwres_context_t\ *" "ctx" ", lwres_buffer_t\ *" "b" ", lwres_lwpacket_t\ *" "pkt" ", lwres_nooprequest_t\ **" "structp" ");" .HP 40 .BI "lwres_result_t lwres_noopresponse_parse(lwres_context_t\ *" "ctx" ", lwres_buffer_t\ *" "b" ", lwres_lwpacket_t\ *" "pkt" ", lwres_noopresponse_t\ **" "structp" ");" .HP 29 .BI "void lwres_noopresponse_free(lwres_context_t\ *" "ctx" ", lwres_noopresponse_t\ **" "structp" ");" .HP 28 .BI "void lwres_nooprequest_free(lwres_context_t\ *" "ctx" ", lwres_nooprequest_t\ **" "structp" ");" .SH "DESCRIPTION" .PP These are low\-level routines for creating and parsing lightweight resolver no\-op request and response messages. .PP The no\-op message is analogous to a \fBping\fR packet: a packet is sent to the resolver daemon and is simply echoed back. The opcode is intended to allow a client to determine if the server is operational or not. .PP There are four main functions for the no\-op opcode. One render function converts a no\-op request structure \(em \fBlwres_nooprequest_t\fR \(em to the lightweight resolver's canonical format. It is complemented by a parse function that converts a packet in this canonical format to a no\-op request structure. Another render function converts the no\-op response structure \(em \fBlwres_noopresponse_t\fR to the canonical format. This is complemented by a parse function which converts a packet in canonical format to a no\-op response structure. .PP These structures are defined in \fIlwres/lwres.h\fR. They are shown below. .PP .RS 4 .nf #define LWRES_OPCODE_NOOP 0x00000000U .fi .RE .sp .PP .RS 4 .nf typedef struct { lwres_uint16_t datalength; unsigned char *data; } lwres_nooprequest_t; .fi .RE .sp .PP .RS 4 .nf typedef struct { lwres_uint16_t datalength; unsigned char *data; } lwres_noopresponse_t; .fi .RE .sp .PP Although the structures have different types, they are identical. This is because the no\-op opcode simply echos whatever data was sent: the response is therefore identical to the request. .PP \fBlwres_nooprequest_render()\fR uses resolver context \fIctx\fR to convert no\-op request structure \fIreq\fR to canonical format. The packet header structure \fIpkt\fR is initialised and transferred to buffer \fIb\fR. The contents of \fI*req\fR are then appended to the buffer in canonical format. \fBlwres_noopresponse_render()\fR performs the same task, except it converts a no\-op response structure \fBlwres_noopresponse_t\fR to the lightweight resolver's canonical format. .PP \fBlwres_nooprequest_parse()\fR uses context \fIctx\fR to convert the contents of packet \fIpkt\fR to a \fBlwres_nooprequest_t\fR structure. Buffer \fIb\fR provides space to be used for storing this structure. When the function succeeds, the resulting \fBlwres_nooprequest_t\fR is made available through \fI*structp\fR. \fBlwres_noopresponse_parse()\fR offers the same semantics as \fBlwres_nooprequest_parse()\fR except it yields a \fBlwres_noopresponse_t\fR structure. .PP \fBlwres_noopresponse_free()\fR and \fBlwres_nooprequest_free()\fR release the memory in resolver context \fIctx\fR that was allocated to the \fBlwres_noopresponse_t\fR or \fBlwres_nooprequest_t\fR structures referenced via \fIstructp\fR. .SH "RETURN VALUES" .PP The no\-op opcode functions \fBlwres_nooprequest_render()\fR, \fBlwres_noopresponse_render()\fR \fBlwres_nooprequest_parse()\fR and \fBlwres_noopresponse_parse()\fR all return \fBLWRES_R_SUCCESS\fR on success. They return \fBLWRES_R_NOMEMORY\fR if memory allocation fails. \fBLWRES_R_UNEXPECTEDEND\fR is returned if the available space in the buffer \fIb\fR is too small to accommodate the packet header or the \fBlwres_nooprequest_t\fR and \fBlwres_noopresponse_t\fR structures. \fBlwres_nooprequest_parse()\fR and \fBlwres_noopresponse_parse()\fR will return \fBLWRES_R_UNEXPECTEDEND\fR if the buffer is not empty after decoding the received packet. These functions will return \fBLWRES_R_FAILURE\fR if \fBpktflags\fR in the packet header structure \fBlwres_lwpacket_t\fR indicate that the packet is not a response to an earlier query. .SH "SEE ALSO" .PP \fBlwres_packet\fR(3) .SH "COPYRIGHT" Copyright \(co 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000, 2001 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_packet.docbook0000644000470500017500000002357712664710322022111 0ustar lamontlamont]> June 18, 2007 lwres_packet 3 BIND9 2004 2005 2007 2014 Internet Systems Consortium, Inc. ("ISC") 2000 2001 Internet Software Consortium. lwres_lwpacket_renderheader lwres_lwpacket_parseheader lightweight resolver packet handling functions #include <lwres/lwpacket.h> lwres_result_t lwres_lwpacket_renderheader lwres_buffer_t *b lwres_lwpacket_t *pkt lwres_result_t lwres_lwpacket_parseheader lwres_buffer_t *b lwres_lwpacket_t *pkt DESCRIPTION These functions rely on a struct lwres_lwpacket which is defined in lwres/lwpacket.h. typedef struct lwres_lwpacket lwres_lwpacket_t; struct lwres_lwpacket { lwres_uint32_t length; lwres_uint16_t version; lwres_uint16_t pktflags; lwres_uint32_t serial; lwres_uint32_t opcode; lwres_uint32_t result; lwres_uint32_t recvlength; lwres_uint16_t authtype; lwres_uint16_t authlength; }; The elements of this structure are: length the overall packet length, including the entire packet header. This field is filled in by the lwres_gabn_*() and lwres_gnba_*() calls. version the header format. There is currently only one format, LWRES_LWPACKETVERSION_0. This field is filled in by the lwres_gabn_*() and lwres_gnba_*() calls. pktflags library-defined flags for this packet: for instance whether the packet is a request or a reply. Flag values can be set, but not defined by the caller. This field is filled in by the application wit the exception of the LWRES_LWPACKETFLAG_RESPONSE bit, which is set by the library in the lwres_gabn_*() and lwres_gnba_*() calls. serial is set by the requestor and is returned in all replies. If two or more packets from the same source have the same serial number and are from the same source, they are assumed to be duplicates and the latter ones may be dropped. This field must be set by the application. opcode indicates the operation. Opcodes between 0x00000000 and 0x03ffffff are reserved for use by the lightweight resolver library. Opcodes between 0x04000000 and 0xffffffff are application defined. This field is filled in by the lwres_gabn_*() and lwres_gnba_*() calls. result is only valid for replies. Results between 0x04000000 and 0xffffffff are application defined. Results between 0x00000000 and 0x03ffffff are reserved for library use. This field is filled in by the lwres_gabn_*() and lwres_gnba_*() calls. recvlength is the maximum buffer size that the receiver can handle on requests and the size of the buffer needed to satisfy a request when the buffer is too large for replies. This field is supplied by the application. authtype defines the packet level authentication that is used. Authorisation types between 0x1000 and 0xffff are application defined and types between 0x0000 and 0x0fff are reserved for library use. Currently these are not used and must be zero. authlen gives the length of the authentication data. Since packet authentication is currently not used, this must be zero. The following opcodes are currently defined: NOOP Success is always returned and the packet contents are echoed. The lwres_noop_*() functions should be used for this type. GETADDRSBYNAME returns all known addresses for a given name. The lwres_gabn_*() functions should be used for this type. GETNAMEBYADDR return the hostname for the given address. The lwres_gnba_*() functions should be used for this type. lwres_lwpacket_renderheader() transfers the contents of lightweight resolver packet structure lwres_lwpacket_t *pkt in network byte order to the lightweight resolver buffer, *b. lwres_lwpacket_parseheader() performs the converse operation. It transfers data in network byte order from buffer *b to resolver packet *pkt. The contents of the buffer b should correspond to a lwres_lwpacket_t. RETURN VALUES Successful calls to lwres_lwpacket_renderheader() and lwres_lwpacket_parseheader() return LWRES_R_SUCCESS. If there is insufficient space to copy data between the buffer *b and lightweight resolver packet *pkt both functions return LWRES_R_UNEXPECTEDEND. bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_config.docbook0000644000470500017500000001234112664710322022072 0ustar lamontlamont]> June 18, 2007 lwres_config 3 BIND9 2004 2005 2007 2014 Internet Systems Consortium, Inc. ("ISC") 2000 2001 Internet Software Consortium. lwres_conf_init lwres_conf_clear lwres_conf_parse lwres_conf_print lwres_conf_get lightweight resolver configuration #include <lwres/lwres.h> void lwres_conf_init lwres_context_t *ctx void lwres_conf_clear lwres_context_t *ctx lwres_result_t lwres_conf_parse lwres_context_t *ctx const char *filename lwres_result_t lwres_conf_print lwres_context_t *ctx FILE *fp lwres_conf_t * lwres_conf_get lwres_context_t *ctx DESCRIPTION lwres_conf_init() creates an empty lwres_conf_t structure for lightweight resolver context ctx. lwres_conf_clear() frees up all the internal memory used by that lwres_conf_t structure in resolver context ctx. lwres_conf_parse() opens the file filename and parses it to initialise the resolver context ctx's lwres_conf_t structure. lwres_conf_print() prints the lwres_conf_t structure for resolver context ctx to the FILE fp. RETURN VALUES lwres_conf_parse() returns LWRES_R_SUCCESS if it successfully read and parsed filename. It returns LWRES_R_FAILURE if filename could not be opened or contained incorrect resolver statements. lwres_conf_print() returns LWRES_R_SUCCESS unless an error occurred when converting the network addresses to a numeric host address string. If this happens, the function returns LWRES_R_FAILURE. SEE ALSO stdio3 , resolver5 . FILES /etc/resolv.conf bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_config.html0000644000470500017500000001302612664710322021417 0ustar lamontlamont lwres_config

Name

lwres_conf_init, lwres_conf_clear, lwres_conf_parse, lwres_conf_print, lwres_conf_get — lightweight resolver configuration

Synopsis

#include <lwres/lwres.h>
void lwres_conf_init( lwres_context_t *  ctx);
void lwres_conf_clear( lwres_context_t *  ctx);
lwres_result_t lwres_conf_parse( lwres_context_t *  ctx,
  const char *  filename);
lwres_result_t lwres_conf_print( lwres_context_t *  ctx,
  FILE *  fp);
lwres_conf_t * lwres_conf_get( lwres_context_t *  ctx);

DESCRIPTION

lwres_conf_init() creates an empty lwres_conf_t structure for lightweight resolver context ctx.

lwres_conf_clear() frees up all the internal memory used by that lwres_conf_t structure in resolver context ctx.

lwres_conf_parse() opens the file filename and parses it to initialise the resolver context ctx's lwres_conf_t structure.

lwres_conf_print() prints the lwres_conf_t structure for resolver context ctx to the FILE fp.

RETURN VALUES

lwres_conf_parse() returns LWRES_R_SUCCESS if it successfully read and parsed filename. It returns LWRES_R_FAILURE if filename could not be opened or contained incorrect resolver statements.

lwres_conf_print() returns LWRES_R_SUCCESS unless an error occurred when converting the network addresses to a numeric host address string. If this happens, the function returns LWRES_R_FAILURE.

SEE ALSO

stdio(3), resolver(5).

FILES

/etc/resolv.conf

bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_getipnode.30000644000470500017500000001271312664710322021330 0ustar lamontlamont.\" Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001, 2003 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: lwres_getipnode .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: June 18, 2007 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "LWRES_GETIPNODE" "3" "June 18, 2007" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" lwres_getipnodebyname, lwres_getipnodebyaddr, lwres_freehostent \- lightweight resolver nodename / address translation API .SH "SYNOPSIS" .nf #include .fi .HP 39 .BI "struct hostent * lwres_getipnodebyname(const\ char\ *" "name" ", int\ " "af" ", int\ " "flags" ", int\ *" "error_num" ");" .HP 39 .BI "struct hostent * lwres_getipnodebyaddr(const\ void\ *" "src" ", size_t\ " "len" ", int\ " "af" ", int\ *" "error_num" ");" .HP 23 .BI "void lwres_freehostent(struct\ hostent\ *" "he" ");" .SH "DESCRIPTION" .PP These functions perform thread safe, protocol independent nodename\-to\-address and address\-to\-nodename translation as defined in RFC2553. .PP They use a \fBstruct hostent\fR which is defined in \fInamedb.h\fR: .PP .RS 4 .nf struct hostent { char *h_name; /* official name of host */ char **h_aliases; /* alias list */ int h_addrtype; /* host address type */ int h_length; /* length of address */ char **h_addr_list; /* list of addresses from name server */ }; #define h_addr h_addr_list[0] /* address, for backward compatibility */ .fi .RE .sp .PP The members of this structure are: .PP \fBh_name\fR .RS 4 The official (canonical) name of the host. .RE .PP \fBh_aliases\fR .RS 4 A NULL\-terminated array of alternate names (nicknames) for the host. .RE .PP \fBh_addrtype\fR .RS 4 The type of address being returned \- usually \fBPF_INET\fR or \fBPF_INET6\fR. .RE .PP \fBh_length\fR .RS 4 The length of the address in bytes. .RE .PP \fBh_addr_list\fR .RS 4 A \fBNULL\fR terminated array of network addresses for the host. Host addresses are returned in network byte order. .RE .PP \fBlwres_getipnodebyname()\fR looks up addresses of protocol family \fIaf\fR for the hostname \fIname\fR. The \fIflags\fR parameter contains ORed flag bits to specify the types of addresses that are searched for, and the types of addresses that are returned. The flag bits are: .PP \fBAI_V4MAPPED\fR .RS 4 This is used with an \fIaf\fR of AF_INET6, and causes IPv4 addresses to be returned as IPv4\-mapped IPv6 addresses. .RE .PP \fBAI_ALL\fR .RS 4 This is used with an \fIaf\fR of AF_INET6, and causes all known addresses (IPv6 and IPv4) to be returned. If AI_V4MAPPED is also set, the IPv4 addresses are return as mapped IPv6 addresses. .RE .PP \fBAI_ADDRCONFIG\fR .RS 4 Only return an IPv6 or IPv4 address if here is an active network interface of that type. This is not currently implemented in the BIND 9 lightweight resolver, and the flag is ignored. .RE .PP \fBAI_DEFAULT\fR .RS 4 This default sets the \fBAI_V4MAPPED\fR and \fBAI_ADDRCONFIG\fR flag bits. .RE .PP \fBlwres_getipnodebyaddr()\fR performs a reverse lookup of address \fIsrc\fR which is \fIlen\fR bytes long. \fIaf\fR denotes the protocol family, typically \fBPF_INET\fR or \fBPF_INET6\fR. .PP \fBlwres_freehostent()\fR releases all the memory associated with the \fBstruct hostent\fR pointer \fIhe\fR. Any memory allocated for the \fBh_name\fR, \fBh_addr_list\fR and \fBh_aliases\fR is freed, as is the memory for the \fBhostent\fR structure itself. .SH "RETURN VALUES" .PP If an error occurs, \fBlwres_getipnodebyname()\fR and \fBlwres_getipnodebyaddr()\fR set \fI*error_num\fR to an appropriate error code and the function returns a \fBNULL\fR pointer. The error codes and their meanings are defined in \fI\fR: .PP \fBHOST_NOT_FOUND\fR .RS 4 No such host is known. .RE .PP \fBNO_ADDRESS\fR .RS 4 The server recognised the request and the name but no address is available. Another type of request to the name server for the domain might return an answer. .RE .PP \fBTRY_AGAIN\fR .RS 4 A temporary and possibly transient error occurred, such as a failure of a server to respond. The request may succeed if retried. .RE .PP \fBNO_RECOVERY\fR .RS 4 An unexpected failure occurred, and retrying the request is pointless. .RE .PP \fBlwres_hstrerror\fR(3) translates these error codes to suitable error messages. .SH "SEE ALSO" .PP \fBRFC2553\fR(), \fBlwres\fR(3), \fBlwres_gethostent\fR(3), \fBlwres_getaddrinfo\fR(3), \fBlwres_getnameinfo\fR(3), \fBlwres_hstrerror\fR(3). .SH "COPYRIGHT" Copyright \(co 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000, 2001, 2003 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_getrrsetbyname.30000644000470500017500000001117412664710322022405 0ustar lamontlamont.\" Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: lwres_getrrsetbyname .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: June 18, 2007 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "LWRES_GETRRSETBYNAME" "3" "June 18, 2007" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" lwres_getrrsetbyname, lwres_freerrset \- retrieve DNS records .SH "SYNOPSIS" .nf #include .fi .HP 25 .BI "int lwres_getrrsetbyname(const\ char\ *" "hostname" ", unsigned\ int\ " "rdclass" ", unsigned\ int\ " "rdtype" ", unsigned\ int\ " "flags" ", struct\ rrsetinfo\ **" "res" ");" .HP 21 .BI "void lwres_freerrset(struct\ rrsetinfo\ *" "rrset" ");" .PP The following structures are used: .PP .RS 4 .nf struct rdatainfo { unsigned int rdi_length; /* length of data */ unsigned char *rdi_data; /* record data */ }; .fi .RE .sp .PP .RS 4 .nf struct rrsetinfo { unsigned int rri_flags; /* RRSET_VALIDATED... */ unsigned int rri_rdclass; /* class number */ unsigned int rri_rdtype; /* RR type number */ unsigned int rri_ttl; /* time to live */ unsigned int rri_nrdatas; /* size of rdatas array */ unsigned int rri_nsigs; /* size of sigs array */ char *rri_name; /* canonical name */ struct rdatainfo *rri_rdatas; /* individual records */ struct rdatainfo *rri_sigs; /* individual signatures */ }; .fi .RE .sp .SH "DESCRIPTION" .PP \fBlwres_getrrsetbyname()\fR gets a set of resource records associated with a \fIhostname\fR, \fIclass\fR, and \fItype\fR. \fIhostname\fR is a pointer a to null\-terminated string. The \fIflags\fR field is currently unused and must be zero. .PP After a successful call to \fBlwres_getrrsetbyname()\fR, \fI*res\fR is a pointer to an \fBrrsetinfo\fR structure, containing a list of one or more \fBrdatainfo\fR structures containing resource records and potentially another list of \fBrdatainfo\fR structures containing SIG resource records associated with those records. The members \fBrri_rdclass\fR and \fBrri_rdtype\fR are copied from the parameters. \fBrri_ttl\fR and \fBrri_name\fR are properties of the obtained rrset. The resource records contained in \fBrri_rdatas\fR and \fBrri_sigs\fR are in uncompressed DNS wire format. Properties of the rdataset are represented in the \fBrri_flags\fR bitfield. If the RRSET_VALIDATED bit is set, the data has been DNSSEC validated and the signatures verified. .PP All of the information returned by \fBlwres_getrrsetbyname()\fR is dynamically allocated: the \fBrrsetinfo\fR and \fBrdatainfo\fR structures, and the canonical host name strings pointed to by the \fBrrsetinfo\fRstructure. Memory allocated for the dynamically allocated structures created by a successful call to \fBlwres_getrrsetbyname()\fR is released by \fBlwres_freerrset()\fR. \fIrrset\fR is a pointer to a \fBstruct rrset\fR created by a call to \fBlwres_getrrsetbyname()\fR. .PP .SH "RETURN VALUES" .PP \fBlwres_getrrsetbyname()\fR returns zero on success, and one of the following error codes if an error occurred: .PP \fBERRSET_NONAME\fR .RS 4 the name does not exist .RE .PP \fBERRSET_NODATA\fR .RS 4 the name exists, but does not have data of the desired type .RE .PP \fBERRSET_NOMEMORY\fR .RS 4 memory could not be allocated .RE .PP \fBERRSET_INVAL\fR .RS 4 a parameter is invalid .RE .PP \fBERRSET_FAIL\fR .RS 4 other failure .RE .PP .RS 4 .RE .SH "SEE ALSO" .PP \fBlwres\fR(3). .SH "COPYRIGHT" Copyright \(co 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000, 2001 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_getaddrinfo.html0000644000470500017500000003122712664710322022443 0ustar lamontlamont lwres_getaddrinfo

Name

lwres_getaddrinfo, lwres_freeaddrinfo — socket address structure to host and service name

Synopsis

#include <lwres/netdb.h>
int lwres_getaddrinfo( const char *  hostname,
  const char *  servname,
  const struct addrinfo *  hints,
  struct addrinfo **  res);
void lwres_freeaddrinfo( struct addrinfo *  ai);

If the operating system does not provide a struct addrinfo, the following structure is used:

struct  addrinfo {
        int             ai_flags;       /* AI_PASSIVE, AI_CANONNAME */
        int             ai_family;      /* PF_xxx */
        int             ai_socktype;    /* SOCK_xxx */
        int             ai_protocol;    /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
        size_t          ai_addrlen;     /* length of ai_addr */
        char            *ai_canonname;  /* canonical name for hostname */
        struct sockaddr *ai_addr;       /* binary address */
        struct addrinfo *ai_next;       /* next structure in linked list */
};

DESCRIPTION

lwres_getaddrinfo() is used to get a list of IP addresses and port numbers for host hostname and service servname. The function is the lightweight resolver's implementation of getaddrinfo() as defined in RFC2133. hostname and servname are pointers to null-terminated strings or NULL. hostname is either a host name or a numeric host address string: a dotted decimal IPv4 address or an IPv6 address. servname is either a decimal port number or a service name as listed in /etc/services.

hints is an optional pointer to a struct addrinfo. This structure can be used to provide hints concerning the type of socket that the caller supports or wishes to use. The caller can supply the following structure elements in *hints:

ai_family

The protocol family that should be used. When ai_family is set to PF_UNSPEC, it means the caller will accept any protocol family supported by the operating system.

ai_socktype

denotes the type of socket — SOCK_STREAM, SOCK_DGRAM or SOCK_RAW — that is wanted. When ai_socktype is zero the caller will accept any socket type.

ai_protocol

indicates which transport protocol is wanted: IPPROTO_UDP or IPPROTO_TCP. If ai_protocol is zero the caller will accept any protocol.

ai_flags

Flag bits. If the AI_CANONNAME bit is set, a successful call to lwres_getaddrinfo() will return a null-terminated string containing the canonical name of the specified hostname in ai_canonname of the first addrinfo structure returned. Setting the AI_PASSIVE bit indicates that the returned socket address structure is intended for used in a call to bind(2). In this case, if the hostname argument is a NULL pointer, then the IP address portion of the socket address structure will be set to INADDR_ANY for an IPv4 address or IN6ADDR_ANY_INIT for an IPv6 address.

When ai_flags does not set the AI_PASSIVE bit, the returned socket address structure will be ready for use in a call to connect(2) for a connection-oriented protocol or connect(2), sendto(2), or sendmsg(2) if a connectionless protocol was chosen. The IP address portion of the socket address structure will be set to the loopback address if hostname is a NULL pointer and AI_PASSIVE is not set in ai_flags.

If ai_flags is set to AI_NUMERICHOST it indicates that hostname should be treated as a numeric string defining an IPv4 or IPv6 address and no name resolution should be attempted.

All other elements of the struct addrinfo passed via hints must be zero.

A hints of NULL is treated as if the caller provided a struct addrinfo initialized to zero with ai_familyset to PF_UNSPEC.

After a successful call to lwres_getaddrinfo(), *res is a pointer to a linked list of one or more addrinfo structures. Each struct addrinfo in this list cn be processed by following the ai_next pointer, until a NULL pointer is encountered. The three members ai_family, ai_socktype, and ai_protocol in each returned addrinfo structure contain the corresponding arguments for a call to socket(2). For each addrinfo structure in the list, the ai_addr member points to a filled-in socket address structure of length ai_addrlen.

All of the information returned by lwres_getaddrinfo() is dynamically allocated: the addrinfo structures, and the socket address structures and canonical host name strings pointed to by the addrinfostructures. Memory allocated for the dynamically allocated structures created by a successful call to lwres_getaddrinfo() is released by lwres_freeaddrinfo(). ai is a pointer to a struct addrinfo created by a call to lwres_getaddrinfo().

RETURN VALUES

lwres_getaddrinfo() returns zero on success or one of the error codes listed in gai_strerror(3) if an error occurs. If both hostname and servname are NULL lwres_getaddrinfo() returns EAI_NONAME.

SEE ALSO

lwres(3), lwres_getaddrinfo(3), lwres_freeaddrinfo(3), lwres_gai_strerror(3), RFC2133, getservbyname(3), bind(2), connect(2), sendto(2), sendmsg(2), socket(2).

bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_getnameinfo.docbook0000644000470500017500000001545412664710322023131 0ustar lamontlamont]> June 18, 2007 lwres_getnameinfo 3 BIND9 2004 2005 2007 2014 Internet Systems Consortium, Inc. ("ISC") 2000 2001 Internet Software Consortium. lwres_getnameinfo lightweight resolver socket address structure to hostname and service name #include <lwres/netdb.h> int lwres_getnameinfo const struct sockaddr *sa size_t salen char *host size_t hostlen char *serv size_t servlen int flags DESCRIPTION This function is equivalent to the getnameinfo3 function defined in RFC2133. lwres_getnameinfo() returns the hostname for the struct sockaddr sa which is salen bytes long. The hostname is of length hostlen and is returned via *host. The maximum length of the hostname is 1025 bytes: NI_MAXHOST. The name of the service associated with the port number in sa is returned in *serv. It is servlen bytes long. The maximum length of the service name is NI_MAXSERV - 32 bytes. The flags argument sets the following bits: NI_NOFQDN A fully qualified domain name is not required for local hosts. The local part of the fully qualified domain name is returned instead. NI_NUMERICHOST Return the address in numeric form, as if calling inet_ntop(), instead of a host name. NI_NAMEREQD A name is required. If the hostname cannot be found in the DNS and this flag is set, a non-zero error code is returned. If the hostname is not found and the flag is not set, the address is returned in numeric form. NI_NUMERICSERV The service name is returned as a digit string representing the port number. NI_DGRAM Specifies that the service being looked up is a datagram service, and causes getservbyport() to be called with a second argument of "udp" instead of its default of "tcp". This is required for the few ports (512-514) that have different services for UDP and TCP. RETURN VALUES lwres_getnameinfo() returns 0 on success or a non-zero error code if an error occurs. SEE ALSO RFC2133 , getservbyport3 , lwres3 , lwres_getnameinfo3 , lwres_getnamebyaddr3 . lwres_net_ntop3 . BUGS RFC2133 fails to define what the nonzero return values of getnameinfo3 are. bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_noop.docbook0000644000470500017500000002271512664710322021606 0ustar lamontlamont]> June 18, 2007 lwres_noop 3 BIND9 2004 2005 2007 2014 Internet Systems Consortium, Inc. ("ISC") 2000 2001 Internet Software Consortium. lwres_nooprequest_render lwres_noopresponse_render lwres_nooprequest_parse lwres_noopresponse_parse lwres_noopresponse_free lwres_nooprequest_free lightweight resolver no-op message handling #include <lwres/lwres.h> lwres_result_t lwres_nooprequest_render lwres_context_t *ctx lwres_nooprequest_t *req lwres_lwpacket_t *pkt lwres_buffer_t *b lwres_result_t lwres_noopresponse_render lwres_context_t *ctx lwres_noopresponse_t *req lwres_lwpacket_t *pkt lwres_buffer_t *b lwres_result_t lwres_nooprequest_parse lwres_context_t *ctx lwres_buffer_t *b lwres_lwpacket_t *pkt lwres_nooprequest_t **structp lwres_result_t lwres_noopresponse_parse lwres_context_t *ctx lwres_buffer_t *b lwres_lwpacket_t *pkt lwres_noopresponse_t **structp void lwres_noopresponse_free lwres_context_t *ctx lwres_noopresponse_t **structp void lwres_nooprequest_free lwres_context_t *ctx lwres_nooprequest_t **structp DESCRIPTION These are low-level routines for creating and parsing lightweight resolver no-op request and response messages. The no-op message is analogous to a ping packet: a packet is sent to the resolver daemon and is simply echoed back. The opcode is intended to allow a client to determine if the server is operational or not. There are four main functions for the no-op opcode. One render function converts a no-op request structure — lwres_nooprequest_t — to the lightweight resolver's canonical format. It is complemented by a parse function that converts a packet in this canonical format to a no-op request structure. Another render function converts the no-op response structure — lwres_noopresponse_t to the canonical format. This is complemented by a parse function which converts a packet in canonical format to a no-op response structure. These structures are defined in lwres/lwres.h. They are shown below. #define LWRES_OPCODE_NOOP 0x00000000U typedef struct { lwres_uint16_t datalength; unsigned char *data; } lwres_nooprequest_t; typedef struct { lwres_uint16_t datalength; unsigned char *data; } lwres_noopresponse_t; Although the structures have different types, they are identical. This is because the no-op opcode simply echos whatever data was sent: the response is therefore identical to the request. lwres_nooprequest_render() uses resolver context ctx to convert no-op request structure req to canonical format. The packet header structure pkt is initialised and transferred to buffer b. The contents of *req are then appended to the buffer in canonical format. lwres_noopresponse_render() performs the same task, except it converts a no-op response structure lwres_noopresponse_t to the lightweight resolver's canonical format. lwres_nooprequest_parse() uses context ctx to convert the contents of packet pkt to a lwres_nooprequest_t structure. Buffer b provides space to be used for storing this structure. When the function succeeds, the resulting lwres_nooprequest_t is made available through *structp. lwres_noopresponse_parse() offers the same semantics as lwres_nooprequest_parse() except it yields a lwres_noopresponse_t structure. lwres_noopresponse_free() and lwres_nooprequest_free() release the memory in resolver context ctx that was allocated to the lwres_noopresponse_t or lwres_nooprequest_t structures referenced via structp. RETURN VALUES The no-op opcode functions lwres_nooprequest_render(), lwres_noopresponse_render() lwres_nooprequest_parse() and lwres_noopresponse_parse() all return LWRES_R_SUCCESS on success. They return LWRES_R_NOMEMORY if memory allocation fails. LWRES_R_UNEXPECTEDEND is returned if the available space in the buffer b is too small to accommodate the packet header or the lwres_nooprequest_t and lwres_noopresponse_t structures. lwres_nooprequest_parse() and lwres_noopresponse_parse() will return LWRES_R_UNEXPECTEDEND if the buffer is not empty after decoding the received packet. These functions will return LWRES_R_FAILURE if pktflags in the packet header structure lwres_lwpacket_t indicate that the packet is not a response to an earlier query. SEE ALSO lwres_packet3 bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_gai_strerror.30000644000470500017500000000546412664710322022061 0ustar lamontlamont.\" Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: lwres_gai_strerror .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: June 18, 2007 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "LWRES_GAI_STRERROR" "3" "June 18, 2007" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" lwres_gai_strerror \- print suitable error string .SH "SYNOPSIS" .nf #include .fi .HP 20 .BI "char * gai_strerror(int\ " "ecode" ");" .SH "DESCRIPTION" .PP \fBlwres_gai_strerror()\fR returns an error message corresponding to an error code returned by \fBgetaddrinfo()\fR. The following error codes and their meaning are defined in \fIinclude/lwres/netdb.h\fR. .PP \fBEAI_ADDRFAMILY\fR .RS 4 address family for hostname not supported .RE .PP \fBEAI_AGAIN\fR .RS 4 temporary failure in name resolution .RE .PP \fBEAI_BADFLAGS\fR .RS 4 invalid value for \fBai_flags\fR .RE .PP \fBEAI_FAIL\fR .RS 4 non\-recoverable failure in name resolution .RE .PP \fBEAI_FAMILY\fR .RS 4 \fBai_family\fR not supported .RE .PP \fBEAI_MEMORY\fR .RS 4 memory allocation failure .RE .PP \fBEAI_NODATA\fR .RS 4 no address associated with hostname .RE .PP \fBEAI_NONAME\fR .RS 4 hostname or servname not provided, or not known .RE .PP \fBEAI_SERVICE\fR .RS 4 servname not supported for \fBai_socktype\fR .RE .PP \fBEAI_SOCKTYPE\fR .RS 4 \fBai_socktype\fR not supported .RE .PP \fBEAI_SYSTEM\fR .RS 4 system error returned in errno .RE The message invalid error code is returned if \fIecode\fR is out of range. .PP \fBai_flags\fR, \fBai_family\fR and \fBai_socktype\fR are elements of the \fBstruct addrinfo\fR used by \fBlwres_getaddrinfo()\fR. .SH "SEE ALSO" .PP \fBstrerror\fR(3), \fBlwres_getaddrinfo\fR(3), \fBgetaddrinfo\fR(3), \fBRFC2133\fR(). .SH "COPYRIGHT" Copyright \(co 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000, 2001 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_getrrsetbyname.docbook0000644000470500017500000001674612664710322023675 0ustar lamontlamont]> June 18, 2007 lwres_getrrsetbyname 3 BIND9 2004 2005 2007 2014 Internet Systems Consortium, Inc. ("ISC") 2000 2001 Internet Software Consortium. lwres_getrrsetbyname lwres_freerrset retrieve DNS records #include <lwres/netdb.h> int lwres_getrrsetbyname const char *hostname unsigned int rdclass unsigned int rdtype unsigned int flags struct rrsetinfo **res void lwres_freerrset struct rrsetinfo *rrset The following structures are used: struct rdatainfo { unsigned int rdi_length; /* length of data */ unsigned char *rdi_data; /* record data */ }; struct rrsetinfo { unsigned int rri_flags; /* RRSET_VALIDATED... */ unsigned int rri_rdclass; /* class number */ unsigned int rri_rdtype; /* RR type number */ unsigned int rri_ttl; /* time to live */ unsigned int rri_nrdatas; /* size of rdatas array */ unsigned int rri_nsigs; /* size of sigs array */ char *rri_name; /* canonical name */ struct rdatainfo *rri_rdatas; /* individual records */ struct rdatainfo *rri_sigs; /* individual signatures */ }; DESCRIPTION lwres_getrrsetbyname() gets a set of resource records associated with a hostname, class, and type. hostname is a pointer a to null-terminated string. The flags field is currently unused and must be zero. After a successful call to lwres_getrrsetbyname(), *res is a pointer to an rrsetinfo structure, containing a list of one or more rdatainfo structures containing resource records and potentially another list of rdatainfo structures containing SIG resource records associated with those records. The members rri_rdclass and rri_rdtype are copied from the parameters. rri_ttl and rri_name are properties of the obtained rrset. The resource records contained in rri_rdatas and rri_sigs are in uncompressed DNS wire format. Properties of the rdataset are represented in the rri_flags bitfield. If the RRSET_VALIDATED bit is set, the data has been DNSSEC validated and the signatures verified. All of the information returned by lwres_getrrsetbyname() is dynamically allocated: the rrsetinfo and rdatainfo structures, and the canonical host name strings pointed to by the rrsetinfostructure. Memory allocated for the dynamically allocated structures created by a successful call to lwres_getrrsetbyname() is released by lwres_freerrset(). rrset is a pointer to a struct rrset created by a call to lwres_getrrsetbyname(). RETURN VALUES lwres_getrrsetbyname() returns zero on success, and one of the following error codes if an error occurred: ERRSET_NONAME the name does not exist ERRSET_NODATA the name exists, but does not have data of the desired type ERRSET_NOMEMORY memory could not be allocated ERRSET_INVAL a parameter is invalid ERRSET_FAIL other failure SEE ALSO lwres3 . bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_gai_strerror.html0000644000470500017500000001155212664710322022656 0ustar lamontlamont lwres_gai_strerror

Name

lwres_gai_strerror — print suitable error string

Synopsis

#include <lwres/netdb.h>
char * gai_strerror( int   ecode);

DESCRIPTION

lwres_gai_strerror() returns an error message corresponding to an error code returned by getaddrinfo(). The following error codes and their meaning are defined in include/lwres/netdb.h.

EAI_ADDRFAMILY

address family for hostname not supported

EAI_AGAIN

temporary failure in name resolution

EAI_BADFLAGS

invalid value for ai_flags

EAI_FAIL

non-recoverable failure in name resolution

EAI_FAMILY

ai_family not supported

EAI_MEMORY

memory allocation failure

EAI_NODATA

no address associated with hostname

EAI_NONAME

hostname or servname not provided, or not known

EAI_SERVICE

servname not supported for ai_socktype

EAI_SOCKTYPE

ai_socktype not supported

EAI_SYSTEM

system error returned in errno

The message invalid error code is returned if ecode is out of range.

ai_flags, ai_family and ai_socktype are elements of the struct addrinfo used by lwres_getaddrinfo().

SEE ALSO

strerror(3), lwres_getaddrinfo(3), getaddrinfo(3), RFC2133.

bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_getipnode.docbook0000644000470500017500000002535112664710322022610 0ustar lamontlamont]> June 18, 2007 lwres_getipnode 3 BIND9 2004 2005 2007 2014 Internet Systems Consortium, Inc. ("ISC") 2000 2001 2003 Internet Software Consortium. lwres_getipnodebyname lwres_getipnodebyaddr lwres_freehostent lightweight resolver nodename / address translation API #include <lwres/netdb.h> struct hostent * lwres_getipnodebyname const char *name int af int flags int *error_num struct hostent * lwres_getipnodebyaddr const void *src size_t len int af int *error_num void lwres_freehostent struct hostent *he DESCRIPTION These functions perform thread safe, protocol independent nodename-to-address and address-to-nodename translation as defined in RFC2553. They use a struct hostent which is defined in namedb.h: struct hostent { char *h_name; /* official name of host */ char **h_aliases; /* alias list */ int h_addrtype; /* host address type */ int h_length; /* length of address */ char **h_addr_list; /* list of addresses from name server */ }; #define h_addr h_addr_list[0] /* address, for backward compatibility */ The members of this structure are: h_name The official (canonical) name of the host. h_aliases A NULL-terminated array of alternate names (nicknames) for the host. h_addrtype The type of address being returned - usually PF_INET or PF_INET6. h_length The length of the address in bytes. h_addr_list A NULL terminated array of network addresses for the host. Host addresses are returned in network byte order. lwres_getipnodebyname() looks up addresses of protocol family af for the hostname name. The flags parameter contains ORed flag bits to specify the types of addresses that are searched for, and the types of addresses that are returned. The flag bits are: AI_V4MAPPED This is used with an af of AF_INET6, and causes IPv4 addresses to be returned as IPv4-mapped IPv6 addresses. AI_ALL This is used with an af of AF_INET6, and causes all known addresses (IPv6 and IPv4) to be returned. If AI_V4MAPPED is also set, the IPv4 addresses are return as mapped IPv6 addresses. AI_ADDRCONFIG Only return an IPv6 or IPv4 address if here is an active network interface of that type. This is not currently implemented in the BIND 9 lightweight resolver, and the flag is ignored. AI_DEFAULT This default sets the AI_V4MAPPED and AI_ADDRCONFIG flag bits. lwres_getipnodebyaddr() performs a reverse lookup of address src which is len bytes long. af denotes the protocol family, typically PF_INET or PF_INET6. lwres_freehostent() releases all the memory associated with the struct hostent pointer he. Any memory allocated for the h_name, h_addr_list and h_aliases is freed, as is the memory for the hostent structure itself. RETURN VALUES If an error occurs, lwres_getipnodebyname() and lwres_getipnodebyaddr() set *error_num to an appropriate error code and the function returns a NULL pointer. The error codes and their meanings are defined in <lwres/netdb.h>: HOST_NOT_FOUND No such host is known. NO_ADDRESS The server recognised the request and the name but no address is available. Another type of request to the name server for the domain might return an answer. TRY_AGAIN A temporary and possibly transient error occurred, such as a failure of a server to respond. The request may succeed if retried. NO_RECOVERY An unexpected failure occurred, and retrying the request is pointless. lwres_hstrerror3 translates these error codes to suitable error messages. SEE ALSO RFC2553 , lwres3 , lwres_gethostent3 , lwres_getaddrinfo3 , lwres_getnameinfo3 , lwres_hstrerror3 . bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_gnba.30000644000470500017500000001402412664710322020256 0ustar lamontlamont.\" Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: lwres_gnba .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: June 18, 2007 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "LWRES_GNBA" "3" "June 18, 2007" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" lwres_gnbarequest_render, lwres_gnbaresponse_render, lwres_gnbarequest_parse, lwres_gnbaresponse_parse, lwres_gnbaresponse_free, lwres_gnbarequest_free \- lightweight resolver getnamebyaddress message handling .SH "SYNOPSIS" .nf #include .fi .HP 40 .BI "lwres_result_t lwres_gnbarequest_render(lwres_context_t\ *" "ctx" ", lwres_gnbarequest_t\ *" "req" ", lwres_lwpacket_t\ *" "pkt" ", lwres_buffer_t\ *" "b" ");" .HP 41 .BI "lwres_result_t lwres_gnbaresponse_render(lwres_context_t\ *" "ctx" ", lwres_gnbaresponse_t\ *" "req" ", lwres_lwpacket_t\ *" "pkt" ", lwres_buffer_t\ *" "b" ");" .HP 39 .BI "lwres_result_t lwres_gnbarequest_parse(lwres_context_t\ *" "ctx" ", lwres_buffer_t\ *" "b" ", lwres_lwpacket_t\ *" "pkt" ", lwres_gnbarequest_t\ **" "structp" ");" .HP 40 .BI "lwres_result_t lwres_gnbaresponse_parse(lwres_context_t\ *" "ctx" ", lwres_buffer_t\ *" "b" ", lwres_lwpacket_t\ *" "pkt" ", lwres_gnbaresponse_t\ **" "structp" ");" .HP 29 .BI "void lwres_gnbaresponse_free(lwres_context_t\ *" "ctx" ", lwres_gnbaresponse_t\ **" "structp" ");" .HP 28 .BI "void lwres_gnbarequest_free(lwres_context_t\ *" "ctx" ", lwres_gnbarequest_t\ **" "structp" ");" .SH "DESCRIPTION" .PP These are low\-level routines for creating and parsing lightweight resolver address\-to\-name lookup request and response messages. .PP There are four main functions for the getnamebyaddr opcode. One render function converts a getnamebyaddr request structure \(em \fBlwres_gnbarequest_t\fR \(em to the lightweight resolver's canonical format. It is complemented by a parse function that converts a packet in this canonical format to a getnamebyaddr request structure. Another render function converts the getnamebyaddr response structure \(em \fBlwres_gnbaresponse_t\fR to the canonical format. This is complemented by a parse function which converts a packet in canonical format to a getnamebyaddr response structure. .PP These structures are defined in \fIlwres/lwres.h\fR. They are shown below. .PP .RS 4 .nf #define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U .fi .RE .sp .PP .RS 4 .nf typedef struct { lwres_uint32_t flags; lwres_addr_t addr; } lwres_gnbarequest_t; .fi .RE .sp .PP .RS 4 .nf typedef struct { lwres_uint32_t flags; lwres_uint16_t naliases; char *realname; char **aliases; lwres_uint16_t realnamelen; lwres_uint16_t *aliaslen; void *base; size_t baselen; } lwres_gnbaresponse_t; .fi .RE .sp .PP \fBlwres_gnbarequest_render()\fR uses resolver context \fIctx\fR to convert getnamebyaddr request structure \fIreq\fR to canonical format. The packet header structure \fIpkt\fR is initialised and transferred to buffer \fIb\fR. The contents of \fI*req\fR are then appended to the buffer in canonical format. \fBlwres_gnbaresponse_render()\fR performs the same task, except it converts a getnamebyaddr response structure \fBlwres_gnbaresponse_t\fR to the lightweight resolver's canonical format. .PP \fBlwres_gnbarequest_parse()\fR uses context \fIctx\fR to convert the contents of packet \fIpkt\fR to a \fBlwres_gnbarequest_t\fR structure. Buffer \fIb\fR provides space to be used for storing this structure. When the function succeeds, the resulting \fBlwres_gnbarequest_t\fR is made available through \fI*structp\fR. \fBlwres_gnbaresponse_parse()\fR offers the same semantics as \fBlwres_gnbarequest_parse()\fR except it yields a \fBlwres_gnbaresponse_t\fR structure. .PP \fBlwres_gnbaresponse_free()\fR and \fBlwres_gnbarequest_free()\fR release the memory in resolver context \fIctx\fR that was allocated to the \fBlwres_gnbaresponse_t\fR or \fBlwres_gnbarequest_t\fR structures referenced via \fIstructp\fR. Any memory associated with ancillary buffers and strings for those structures is also discarded. .SH "RETURN VALUES" .PP The getnamebyaddr opcode functions \fBlwres_gnbarequest_render()\fR, \fBlwres_gnbaresponse_render()\fR \fBlwres_gnbarequest_parse()\fR and \fBlwres_gnbaresponse_parse()\fR all return \fBLWRES_R_SUCCESS\fR on success. They return \fBLWRES_R_NOMEMORY\fR if memory allocation fails. \fBLWRES_R_UNEXPECTEDEND\fR is returned if the available space in the buffer \fIb\fR is too small to accommodate the packet header or the \fBlwres_gnbarequest_t\fR and \fBlwres_gnbaresponse_t\fR structures. \fBlwres_gnbarequest_parse()\fR and \fBlwres_gnbaresponse_parse()\fR will return \fBLWRES_R_UNEXPECTEDEND\fR if the buffer is not empty after decoding the received packet. These functions will return \fBLWRES_R_FAILURE\fR if pktflags in the packet header structure \fBlwres_lwpacket_t\fR indicate that the packet is not a response to an earlier query. .SH "SEE ALSO" .PP \fBlwres_packet\fR(3). .SH "COPYRIGHT" Copyright \(co 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000, 2001 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres.html0000644000470500017500000002216212664710322020073 0ustar lamontlamont lwres

Name

lwres — introduction to the lightweight resolver library

Synopsis

#include <lwres/lwres.h>

DESCRIPTION

The BIND 9 lightweight resolver library is a simple, name service independent stub resolver library. It provides hostname-to-address and address-to-hostname lookup services to applications by transmitting lookup requests to a resolver daemon lwresd running on the local host. The resolver daemon performs the lookup using the DNS or possibly other name service protocols, and returns the results to the application through the library. The library and resolver daemon communicate using a simple UDP-based protocol.

OVERVIEW

The lwresd library implements multiple name service APIs. The standard gethostbyname(), gethostbyaddr(), gethostbyname_r(), gethostbyaddr_r(), getaddrinfo(), getipnodebyname(), and getipnodebyaddr() functions are all supported. To allow the lwres library to coexist with system libraries that define functions of the same name, the library defines these functions with names prefixed by lwres_. To define the standard names, applications must include the header file <lwres/netdb.h> which contains macro definitions mapping the standard function names into lwres_ prefixed ones. Operating system vendors who integrate the lwres library into their base distributions should rename the functions in the library proper so that the renaming macros are not needed.

The library also provides a native API consisting of the functions lwres_getaddrsbyname() and lwres_getnamebyaddr(). These may be called by applications that require more detailed control over the lookup process than the standard functions provide.

In addition to these name service independent address lookup functions, the library implements a new, experimental API for looking up arbitrary DNS resource records, using the lwres_getaddrsbyname() function.

Finally, there is a low-level API for converting lookup requests and responses to and from raw lwres protocol packets. This API can be used by clients requiring nonblocking operation, and is also used when implementing the server side of the lwres protocol, for example in the lwresd resolver daemon. The use of this low-level API in clients and servers is outlined in the following sections.

CLIENT-SIDE LOW-LEVEL API CALL FLOW

When a client program wishes to make an lwres request using the native low-level API, it typically performs the following sequence of actions.

(1) Allocate or use an existing lwres_packet_t, called pkt below.

(2) Set pkt.recvlength to the maximum length we will accept. This is done so the receiver of our packets knows how large our receive buffer is. The "default" is a constant in lwres.h: LWRES_RECVLENGTH = 4096.

(3) Set pkt.serial to a unique serial number. This value is echoed back to the application by the remote server.

(4) Set pkt.pktflags. Usually this is set to 0.

(5) Set pkt.result to 0.

(6) Call lwres_*request_render(), or marshall in the data using the primitives such as lwres_packet_render() and storing the packet data.

(7) Transmit the resulting buffer.

(8) Call lwres_*response_parse() to parse any packets received.

(9) Verify that the opcode and serial match a request, and process the packet specific information contained in the body.

SERVER-SIDE LOW-LEVEL API CALL FLOW

When implementing the server side of the lightweight resolver protocol using the lwres library, a sequence of actions like the following is typically involved in processing each request packet.

Note that the same lwres_packet_t is used in both the _parse() and _render() calls, with only a few modifications made to the packet header's contents between uses. This method is recommended as it keeps the serial, opcode, and other fields correct.

(1) When a packet is received, call lwres_*request_parse() to unmarshall it. This returns a lwres_packet_t (also called pkt, below) as well as a data specific type, such as lwres_gabnrequest_t.

(2) Process the request in the data specific type.

(3) Set the pkt.result, pkt.recvlength as above. All other fields can be left untouched since they were filled in by the *_parse() call above. If using lwres_*response_render(), pkt.pktflags will be set up properly. Otherwise, the LWRES_LWPACKETFLAG_RESPONSE bit should be set.

(4) Call the data specific rendering function, such as lwres_gabnresponse_render().

(5) Send the resulting packet to the client.

SEE ALSO

lwres_gethostent(3), lwres_getipnode(3), lwres_getnameinfo(3), lwres_noop(3), lwres_gabn(3), lwres_gnba(3), lwres_context(3), lwres_config(3), resolver(5), lwresd(8).

bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_config.30000644000470500017500000000602112664710322020612 0ustar lamontlamont.\" Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: lwres_config .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: June 18, 2007 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "LWRES_CONFIG" "3" "June 18, 2007" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" lwres_conf_init, lwres_conf_clear, lwres_conf_parse, lwres_conf_print, lwres_conf_get \- lightweight resolver configuration .SH "SYNOPSIS" .nf #include .fi .HP 21 .BI "void lwres_conf_init(lwres_context_t\ *" "ctx" ");" .HP 22 .BI "void lwres_conf_clear(lwres_context_t\ *" "ctx" ");" .HP 32 .BI "lwres_result_t lwres_conf_parse(lwres_context_t\ *" "ctx" ", const\ char\ *" "filename" ");" .HP 32 .BI "lwres_result_t lwres_conf_print(lwres_context_t\ *" "ctx" ", FILE\ *" "fp" ");" .HP 30 .BI "lwres_conf_t * lwres_conf_get(lwres_context_t\ *" "ctx" ");" .SH "DESCRIPTION" .PP \fBlwres_conf_init()\fR creates an empty \fBlwres_conf_t\fR structure for lightweight resolver context \fIctx\fR. .PP \fBlwres_conf_clear()\fR frees up all the internal memory used by that \fBlwres_conf_t\fR structure in resolver context \fIctx\fR. .PP \fBlwres_conf_parse()\fR opens the file \fIfilename\fR and parses it to initialise the resolver context \fIctx\fR's \fBlwres_conf_t\fR structure. .PP \fBlwres_conf_print()\fR prints the \fBlwres_conf_t\fR structure for resolver context \fIctx\fR to the \fBFILE\fR \fIfp\fR. .SH "RETURN VALUES" .PP \fBlwres_conf_parse()\fR returns \fBLWRES_R_SUCCESS\fR if it successfully read and parsed \fIfilename\fR. It returns \fBLWRES_R_FAILURE\fR if \fIfilename\fR could not be opened or contained incorrect resolver statements. .PP \fBlwres_conf_print()\fR returns \fBLWRES_R_SUCCESS\fR unless an error occurred when converting the network addresses to a numeric host address string. If this happens, the function returns \fBLWRES_R_FAILURE\fR. .SH "SEE ALSO" .PP \fBstdio\fR(3), \fBresolver\fR(5). .SH "FILES" .PP \fI/etc/resolv.conf\fR .SH "COPYRIGHT" Copyright \(co 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000, 2001 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_inetntop.docbook0000644000470500017500000000756612664710322022502 0ustar lamontlamont]> June 18, 2007 lwres_inetntop 3 BIND9 2004 2005 2007 2014 Internet Systems Consortium, Inc. ("ISC") 2000 2001 Internet Software Consortium. lwres_net_ntop lightweight resolver IP address presentation #include <lwres/net.h> const char * lwres_net_ntop int af const void *src char *dst size_t size DESCRIPTION lwres_net_ntop() converts an IP address of protocol family af — IPv4 or IPv6 — at location src from network format to its conventional representation as a string. For IPv4 addresses, that string would be a dotted-decimal. An IPv6 address would be represented in colon notation as described in RFC1884. The generated string is copied to dst provided size indicates it is long enough to store the ASCII representation of the address. RETURN VALUES If successful, the function returns dst: a pointer to a string containing the presentation format of the address. lwres_net_ntop() returns NULL and sets the global variable errno to EAFNOSUPPORT if the protocol family given in af is not supported. SEE ALSO RFC1884 , inet_ntop3 , errno3 . bind9-9.10.3.dfsg.P4/lib/lwres/man/lwres_gabn.html0000644000470500017500000002506312664710322021065 0ustar lamontlamont lwres_gabn

Name

lwres_gabnrequest_render, lwres_gabnresponse_render, lwres_gabnrequest_parse, lwres_gabnresponse_parse, lwres_gabnresponse_free, lwres_gabnrequest_free — lightweight resolver getaddrbyname message handling

Synopsis

#include <lwres/lwres.h>
lwres_result_t lwres_gabnrequest_render( lwres_context_t *  ctx,
  lwres_gabnrequest_t *  req,
  lwres_lwpacket_t *  pkt,
  lwres_buffer_t *  b);
lwres_result_t lwres_gabnresponse_render( lwres_context_t *  ctx,
  lwres_gabnresponse_t *  req,
  lwres_lwpacket_t *  pkt,
  lwres_buffer_t *  b);
lwres_result_t lwres_gabnrequest_parse( lwres_context_t *  ctx,
  lwres_buffer_t *  b,
  lwres_lwpacket_t *  pkt,
  lwres_gabnrequest_t **  structp);
lwres_result_t lwres_gabnresponse_parse( lwres_context_t *  ctx,
  lwres_buffer_t *  b,
  lwres_lwpacket_t *  pkt,
  lwres_gabnresponse_t **  structp);
void lwres_gabnresponse_free( lwres_context_t *  ctx,
  lwres_gabnresponse_t **  structp);
void lwres_gabnrequest_free( lwres_context_t *  ctx,
  lwres_gabnrequest_t **  structp);

DESCRIPTION

These are low-level routines for creating and parsing lightweight resolver name-to-address lookup request and response messages.

There are four main functions for the getaddrbyname opcode. One render function converts a getaddrbyname request structure — lwres_gabnrequest_t — to the lightweight resolver's canonical format. It is complemented by a parse function that converts a packet in this canonical format to a getaddrbyname request structure. Another render function converts the getaddrbyname response structure — lwres_gabnresponse_t — to the canonical format. This is complemented by a parse function which converts a packet in canonical format to a getaddrbyname response structure.

These structures are defined in <lwres/lwres.h>. They are shown below.

#define LWRES_OPCODE_GETADDRSBYNAME     0x00010001U

typedef struct lwres_addr lwres_addr_t;
typedef LWRES_LIST(lwres_addr_t) lwres_addrlist_t;

typedef struct {
        lwres_uint32_t  flags;
        lwres_uint32_t  addrtypes;
        lwres_uint16_t  namelen;
        char           *name;
} lwres_gabnrequest_t;

typedef struct {
        lwres_uint32_t          flags;
        lwres_uint16_t          naliases;
        lwres_uint16_t          naddrs;
        char                   *realname;
        char                  **aliases;
        lwres_uint16_t          realnamelen;
        lwres_uint16_t         *aliaslen;
        lwres_addrlist_t        addrs;
        void                   *base;
        size_t                  baselen;
} lwres_gabnresponse_t;

lwres_gabnrequest_render() uses resolver context ctx to convert getaddrbyname request structure req to canonical format. The packet header structure pkt is initialised and transferred to buffer b. The contents of *req are then appended to the buffer in canonical format. lwres_gabnresponse_render() performs the same task, except it converts a getaddrbyname response structure lwres_gabnresponse_t to the lightweight resolver's canonical format.

lwres_gabnrequest_parse() uses context ctx to convert the contents of packet pkt to a lwres_gabnrequest_t structure. Buffer b provides space to be used for storing this structure. When the function succeeds, the resulting lwres_gabnrequest_t is made available through *structp. lwres_gabnresponse_parse() offers the same semantics as lwres_gabnrequest_parse() except it yields a lwres_gabnresponse_t structure.

lwres_gabnresponse_free() and lwres_gabnrequest_free() release the memory in resolver context ctx that was allocated to the lwres_gabnresponse_t or lwres_gabnrequest_t structures referenced via structp. Any memory associated with ancillary buffers and strings for those structures is also discarded.

RETURN VALUES

The getaddrbyname opcode functions lwres_gabnrequest_render(), lwres_gabnresponse_render() lwres_gabnrequest_parse() and lwres_gabnresponse_parse() all return LWRES_R_SUCCESS on success. They return LWRES_R_NOMEMORY if memory allocation fails. LWRES_R_UNEXPECTEDEND is returned if the available space in the buffer b is too small to accommodate the packet header or the lwres_gabnrequest_t and lwres_gabnresponse_t structures. lwres_gabnrequest_parse() and lwres_gabnresponse_parse() will return LWRES_R_UNEXPECTEDEND if the buffer is not empty after decoding the received packet. These functions will return LWRES_R_FAILURE if pktflags in the packet header structure lwres_lwpacket_t indicate that the packet is not a response to an earlier query.

SEE ALSO

lwres_packet(3)

bind9-9.10.3.dfsg.P4/lib/tests/0002755000470500017500000000000012672612753015313 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/tests/Makefile.in0000644000470500017500000000321212664710322017344 0ustar lamontlamont# Copyright (C) 2004, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001, 2003 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.28 2009/12/05 23:31:41 each Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_MAKE_INCLUDES@ CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES} ${TEST_INCLUDES} CDEFINES = CWARNINGS = ISCLIBS = ../../lib/isc/libisc.@A@ ISCCCLIBS = ../../lib/isccc/libisccc.@A@ ISCDEPLIBS = ../../lib/isc/libisc.@A@ ISCCCDEPLIBS = libisccc.@A@ OBJS = t_api.@O@ SRCS = t_api.c SUBDIRS = include TARGETS = timestamp @BIND9_MAKE_RULES@ libt_api.@SA@: ${OBJS} ${AR} ${ARFLAGS} $@ ${OBJS} ${RANLIB} $@ libt_api.la: ${OBJS} ${LIBTOOL_MODE_LINK} \ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libt_api.la -rpath ${libdir} \ ${OBJS} ${ISCLIBS} ${LIBS} @LIBTOOL_ALLOW_UNDEFINED@ @LIBTOOL_IN_MAIN@ timestamp: libt_api.@A@ touch timestamp clean distclean:: rm -f t_api.@O@ libt_api.@A@ timestamp bind9-9.10.3.dfsg.P4/lib/tests/include/0002755000470500017500000000000012672612753016736 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/tests/include/Makefile.in0000644000470500017500000000176012664710322020775 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.11 2007/06/19 23:47:24 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = tests TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/tests/include/tests/0002755000470500017500000000000012664710322020070 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/tests/include/tests/Makefile.in0000644000470500017500000000177212664710322022142 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1999-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.9 2007/06/19 23:47:24 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/tests/include/tests/t_api.h0000644000470500017500000000441412664710322021336 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2010, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: t_api.h,v 1.24 2010/06/08 23:50:24 tbox Exp $ */ #ifndef TESTS_T_API_H #define TESTS_T_API_H 1 /*! \file tests/t_api.h */ #include #include #include #include #include /* * * Result codes. * */ #define T_PASS 0x1 #define T_FAIL 0x2 #define T_UNRESOLVED 0x3 #define T_SKIPPED 0x4 #define T_UNTESTED 0x5 #define T_THREADONLY 0x6 #define T_PKCS11ONLY 0x7 /* * * Assertion class codes. * */ #define T_OPTIONAL 0x0 #define T_REQUIRED 0x1 /* * Misc */ #define T_MAXTOKS 16 #define T_ARG(n) (*(av + (n))) typedef void (*PFV)(void); typedef struct { PFV pfv; const char *func_name; } testspec_t; LIBTESTS_EXTERNAL_DATA extern int T_debug; #ifndef WIN32 extern testspec_t T_testlist[]; #endif ISC_LANG_BEGINDECLS #ifdef WIN32 void t_settests(const testspec_t list[]); int t_main(int argc, char **argv); #endif void t_assert(const char *component, int anum, int class, const char *what, ...) ISC_FORMAT_PRINTF(4, 5); void t_info(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); void t_result(int result); char * t_getenv(const char *name); char * t_fgetbs(FILE *fp); isc_result_t t_dns_result_fromtext(char *result); unsigned int t_dc_method_fromtext(char *dc_method); int t_bustline(char *line, char **toks); int t_eval(const char *filename, int (*func)(char **), int nargs); ISC_LANG_ENDDECLS #endif /* TESTS_T_API_H */ bind9-9.10.3.dfsg.P4/lib/tests/win32/0002755000470500017500000000000012664730167016256 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/tests/win32/libtests.mak.in0000644000470500017500000002474212664710322021204 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on libtests.dsp !IF "$(CFG)" == "" CFG=libtests - @PLATFORM@ Release !MESSAGE No configuration specified. Defaulting to libtests - @PLATFORM@ Release. !ENDIF !IF "$(CFG)" != "libtests - @PLATFORM@ Release" && "$(CFG)" != "libtests - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "libtests.mak" CFG="libtests - @PLATFORM@ Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "libtests - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE "libtests - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "libtests - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "libtests - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release !IF "$(RECURSE)" == "0" ALL : "..\..\..\Build\Release\libtests.dll" !ELSE ALL : "libisc - @PLATFORM@ Release" "libdns - @PLATFORM@ Release" "..\..\..\Build\Release\libtests.dll" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libdns - @PLATFORM@ ReleaseCLEAN" "libisc - @PLATFORM@ ReleaseCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\t_api.obj" -@erase "$(INTDIR)\DLLMain.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "$(OUTDIR)\libtests.exp" -@erase "$(OUTDIR)\libtests.lib" -@erase "..\..\..\Build\Release\libtests.dll" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 @LIBXML2_INC@ /I "../../../lib/dns/win32/include" /I "./" /I "../../../" /I "include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isc/include" /D "NDEBUG" /D "WIN32" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBTESTS_EXPORTS" /Fp"$(INTDIR)\libtests.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\libtests.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Release/libisc.lib ../../dns/win32/Release/libdns.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\libtests.pdb" @MACHINE@ /def:".\libtests.def" /out:"../../../Build/Release/libtests.dll" /implib:"$(OUTDIR)\libtests.lib" DEF_FILE= \ ".\libtests.def" LINK32_OBJS= \ "$(INTDIR)\t_api.obj" \ "$(INTDIR)\DLLMain.obj" \ "..\..\dns\win32\Release\libdns.lib" \ "..\..\isc\win32\Release\libisc.lib" "..\..\..\Build\Release\libtests.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_DLL) !ELSEIF "$(CFG)" == "libtests - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros !IF "$(RECURSE)" == "0" ALL : "..\..\..\Build\Debug\libtests.dll" "$(OUTDIR)\libtests.bsc" !ELSE ALL : "libisc - @PLATFORM@ Debug" "libdns - @PLATFORM@ Debug" "..\..\..\Build\Debug\libtests.dll" "$(OUTDIR)\libtests.bsc" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libdns - @PLATFORM@ DebugCLEAN" "libisc - @PLATFORM@ DebugCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\t_api.obj" -@erase "$(INTDIR)\t_api.sbr" -@erase "$(INTDIR)\DLLMain.obj" -@erase "$(INTDIR)\DLLMain.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\libtests.bsc" -@erase "$(OUTDIR)\libtests.exp" -@erase "$(OUTDIR)\libtests.lib" -@erase "$(OUTDIR)\libtests.pdb" -@erase "..\..\..\Build\Debug\libtests.dll" -@erase "..\..\..\Build\Debug\libtests.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od @LIBXML2_INC@ /I "./" /I "../../../" /I "include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isc/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBTESTS_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\libtests.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\libtests.bsc" BSC32_SBRS= \ "$(INTDIR)\t_api.sbr" \ "$(INTDIR)\DLLMain.sbr" "$(OUTDIR)\libtests.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../isc/win32/debug/libisc.lib ../../dns/win32/debug/libdns.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\libtests.pdb" /debug @MACHINE@ /def:".\libtests.def" /out:"../../../Build/Debug/libtests.dll" /implib:"$(OUTDIR)\libtests.lib" /pdbtype:sept DEF_FILE= \ ".\libtests.def" LINK32_OBJS= \ "$(INTDIR)\t_api.obj" \ "$(INTDIR)\DLLMain.obj" \ "..\..\dns\win32\Debug\libdns.lib" \ "..\..\isc\win32\Debug\libisc.lib" "..\..\..\Build\Debug\libtests.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_DLL) !ENDIF .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("libtests.dep") !INCLUDE "libtests.dep" !ELSE !MESSAGE Warning: cannot find "libtests.dep" !ENDIF !ENDIF !IF "$(CFG)" == "libtests - @PLATFORM@ Release" || "$(CFG)" == "libtests - @PLATFORM@ Debug" SOURCE=..\t_api.c !IF "$(CFG)" == "libtests - @PLATFORM@ Release" "$(INTDIR)\t_api.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libtests - @PLATFORM@ Debug" "$(INTDIR)\t_api.obj" "$(INTDIR)\t_api.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=.\DLLMain.c !IF "$(CFG)" == "libtests - @PLATFORM@ Release" "$(INTDIR)\DLLMain.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libtests - @PLATFORM@ Debug" "$(INTDIR)\DLLMain.obj" "$(INTDIR)\DLLMain.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF !IF "$(CFG)" == "libtests - @PLATFORM@ Release" "libdns - @PLATFORM@ Release" : cd "..\..\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" cd "..\..\tests\win32" "libdns - @PLATFORM@ ReleaseCLEAN" : cd "..\..\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\tests\win32" !ELSEIF "$(CFG)" == "libtests - @PLATFORM@ Debug" "libdns - @PLATFORM@ Debug" : cd "..\..\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" cd "..\..\tests\win32" "libdns - @PLATFORM@ DebugCLEAN" : cd "..\..\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\tests\win32" !ENDIF !IF "$(CFG)" == "libtests - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" cd "..\..\tests\win32" "libisc - @PLATFORM@ ReleaseCLEAN" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\tests\win32" !ELSEIF "$(CFG)" == "libtests - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" cd "..\..\tests\win32" "libisc - @PLATFORM@ DebugCLEAN" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\tests\win32" !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/lib/tests/win32/libtests.vcxproj.user0000644000470500017500000000021712664710322022466 0ustar lamontlamont bind9-9.10.3.dfsg.P4/lib/tests/win32/libtests.dsp.in0000644000470500017500000001130612664710322021212 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="libtests" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Dynamic-Link Library" 0x0102 CFG=libtests - @PLATFORM@ Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "libtests.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "libtests.mak" CFG="libtests - @PLATFORM@ Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "libtests - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE "libtests - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "libtests - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBTESTS_EXPORTS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 @LIBXML2_INC@ /I "../../../lib/dns/win32/include" /I "./" /I "../../../" /I "include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isc/include" /D "NDEBUG" /D "WIN32" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBTESTS_EXPORTS" @COPTY@ /FD /c # SUBTRACT CPP /X # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll @MACHINE@ # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Release/libisc.lib ../../dns/win32/Release/libdns.lib /nologo /dll @MACHINE@ /out:"../../../Build/Release/libtests.dll" !ELSEIF "$(CFG)" == "libtests - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBTESTS_EXPORTS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od @LIBXML2_INC@ /I "./" /I "../../../" /I "include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isc/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBTESTS_EXPORTS" /FR @COPTY@ /FD /GZ /c # SUBTRACT CPP /X # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../isc/win32/debug/libisc.lib ../../dns/win32/debug/libdns.lib /nologo /dll /debug @MACHINE@ /out:"../../../Build/Debug/libtests.dll" /pdbtype:sept !ENDIF # Begin Target # Name "libtests - @PLATFORM@ Release" # Name "libtests - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\t_api.c # End Source File # Begin Source File SOURCE=.\DLLMain.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=..\include\tests\t_api.h # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # Begin Source File SOURCE=.\libtests.def # End Source File # End Target # End Project bind9-9.10.3.dfsg.P4/lib/tests/win32/DLLMain.c0000644000470500017500000000273512664710322017636 0ustar lamontlamont/* * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #include #include /* * Called when we enter the DLL */ __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { /* * The DLL is loading due to process * initialization or a call to LoadLibrary. */ case DLL_PROCESS_ATTACH: break; /* The attached process creates a new thread. */ case DLL_THREAD_ATTACH: break; /* The thread of the attached process terminates. */ case DLL_THREAD_DETACH: break; /* * The DLL is unloading from a process due to * process termination or a call to FreeLibrary. */ case DLL_PROCESS_DETACH: break; default: break; } return (TRUE); } bind9-9.10.3.dfsg.P4/lib/tests/win32/libtests.dsw0000644000470500017500000000103312664710322020610 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "libtests"=.\libtests.dsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/lib/tests/win32/libtests.vcxproj.filters.in0000644000470500017500000000234512664710322023571 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files Source Files Header Files bind9-9.10.3.dfsg.P4/lib/tests/win32/libtests.def0000644000470500017500000000025112664710322020552 0ustar lamontlamontLIBRARY libtests ; Exported Functions EXPORTS t_assert t_bustline t_dc_method_fromtext t_dns_result_fromtext t_eval t_fgetbs t_getenv t_info t_main t_result t_settests bind9-9.10.3.dfsg.P4/lib/tests/win32/libtests.vcxproj.in0000644000470500017500000001547512664710322022132 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {F6F08940-7597-4FEE-9CE0-E09A009C45A3} Win32Proj libtests DynamicLibrary true MultiByte DynamicLibrary false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBTESTS_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions) ./;../../../;include;../include;../../isc/win32;../../isc/win32/include;../../isc/include;../../dns/include;@LIBXML2_INC@%(AdditionalIncludeDirectories) false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true Console true ../../isc/win32/$(Configuration);../../dns/win32/$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies) .\libtests.def .\$(Configuration)\$(ProjectName).lib ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBTESTS_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions) ./;../../../;include;../include;../../isc/win32;../../isc/win32/include;../../isc/include;../../dns/include;@LIBXML2_INC@%(AdditionalIncludeDirectories) OnlyExplicitInline false true .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb Console false true true ../../isc/win32/$(Configuration);../../dns/win32/$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies) .\libtests.def .\$(Configuration)\$(ProjectName).lib Default ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) bind9-9.10.3.dfsg.P4/lib/tests/t_api.c0000644000470500017500000004005212664710322016542 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007-2010, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: t_api.c,v 1.68 2010/12/21 04:20:23 marka Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #ifndef WIN32 #include #else #include #endif #include #include #include #include #include #include #include #include "include/tests/t_api.h" static const char *Usage = "\t-a : run all tests\n" "\t-b : chdir to dir before running tests" "\t-c : use specified config file\n" "\t-d : set debug level to debug_level\n" "\t-h : print test info\n" "\t-u : print usage info\n" "\t-n : run specified test name\n" "\t-t : run specified test number\n" "\t-x : don't execute tests in a subproc\n" "\t-q : use 'timeout' as the timeout value\n"; /*!< * -a --> run all tests * -b dir --> chdir to dir before running tests * -c config --> use config file 'config' * -d --> turn on api debugging * -h --> print out available test names * -u --> print usage info * -n name --> run test named name * -tn --> run test n * -x --> don't execute testcases in a subproc * -q timeout --> use 'timeout' as the timeout value */ #define T_MAXTESTS 256 /*% must be 0 mod 8 */ #define T_MAXENV 256 #define T_DEFAULT_CONFIG "t_config" #define T_BUFSIZ 256 #define T_BIGBUF 4096 #define T_TCTOUT 60 int T_debug; int T_timeout; pid_t T_pid; static const char * T_config; static char T_tvec[T_MAXTESTS / 8]; static char * T_env[T_MAXENV + 1]; static char T_buf[T_BIGBUF]; static char * T_dir; #ifdef WIN32 static testspec_t T_testlist[T_MAXTESTS]; #endif static int t_initconf(const char *path); static int t_dumpconf(const char *path); static int t_putinfo(const char *key, const char *info); static char * t_getdate(char *buf, size_t buflen); static void printhelp(void); static void printusage(void); static int T_int; static void t_sighandler(int sig) { T_int = sig; } int #ifndef WIN32 main(int argc, char **argv) #else t_main(int argc, char **argv) #endif { int c; int tnum; #ifndef WIN32 int subprocs; pid_t deadpid; int status; #endif int len; isc_boolean_t first; testspec_t *pts; #ifndef WIN32 struct sigaction sa; #endif isc_mem_debugging = ISC_MEM_DEBUGRECORD; first = ISC_TRUE; #ifndef WIN32 subprocs = 1; #endif T_timeout = T_TCTOUT; /* * -a option is now default. */ memset(T_tvec, 0xff, sizeof(T_tvec)); /* * Parse args. */ while ((c = isc_commandline_parse(argc, argv, ":at:c:d:n:huxq:b:")) != -1) { if (c == 'a') { /* * Flag all tests to be run. */ memset(T_tvec, 0xff, sizeof(T_tvec)); } else if (c == 'b') { T_dir = isc_commandline_argument; } else if (c == 't') { tnum = atoi(isc_commandline_argument); if ((tnum > 0) && (tnum < T_MAXTESTS)) { if (first) { /* * Turn off effect of -a default * and allow multiple -t and -n * options. */ memset(T_tvec, 0, sizeof(T_tvec)); first = ISC_FALSE; } /* * Flag test tnum to be run. */ tnum -= 1; T_tvec[tnum / 8] |= (0x01 << (tnum % 8)); } } else if (c == 'c') { T_config = isc_commandline_argument; } else if (c == 'd') { T_debug = atoi(isc_commandline_argument); } else if (c == 'n') { pts = &T_testlist[0]; tnum = 0; while (pts->pfv != NULL) { if (! strcmp(pts->func_name, isc_commandline_argument)) { if (first) { memset(T_tvec, 0, sizeof(T_tvec)); first = ISC_FALSE; } T_tvec[tnum/8] |= (0x01 << (tnum%8)); break; } ++pts; ++tnum; } if (pts->pfv == NULL) { fprintf(stderr, "no such test %s\n", isc_commandline_argument); exit(1); } } else if (c == 'h') { printhelp(); exit(0); } else if (c == 'u') { printusage(); exit(0); } else if (c == 'x') { #ifndef WIN32 subprocs = 0; #endif } else if (c == 'q') { T_timeout = atoi(isc_commandline_argument); } else if (c == ':') { fprintf(stderr, "Option -%c requires an argument\n", isc_commandline_option); exit(1); } else if (c == '?') { fprintf(stderr, "Unrecognized option -%c\n", isc_commandline_option); exit(1); } } /* * Set cwd. */ if (T_dir != NULL && chdir(T_dir) != 0) { fprintf(stderr, "chdir %s failed\n", T_dir); exit(1); } /* * We don't want buffered output. */ (void)setbuf(stdout, NULL); (void)setbuf(stderr, NULL); /* * Setup signals. */ #ifndef WIN32 sa.sa_flags = 0; sigfillset(&sa.sa_mask); sa.sa_handler = t_sighandler; (void)sigaction(SIGINT, &sa, NULL); (void)sigaction(SIGALRM, &sa, NULL); #endif /* * Output start stanza to journal. */ snprintf(T_buf, sizeof(T_buf), "%s:", argv[0]); len = strlen(T_buf); (void) t_getdate(T_buf + len, T_BIGBUF - len); t_putinfo("S", T_buf); /* * Setup the test environment using the config file. */ if (T_config == NULL) T_config = T_DEFAULT_CONFIG; t_initconf(T_config); if (T_debug) t_dumpconf(T_config); /* * Now invoke all the test cases. */ tnum = 0; pts = &T_testlist[0]; while (*pts->pfv != NULL) { if (T_tvec[tnum / 8] & (0x01 << (tnum % 8))) { #ifndef WIN32 if (subprocs) { T_pid = fork(); if (T_pid == 0) { (*pts->pfv)(); exit(0); } else if (T_pid > 0) { T_int = 0; sa.sa_handler = t_sighandler; (void)sigaction(SIGALRM, &sa, NULL); alarm(T_timeout); deadpid = (pid_t) -1; while (deadpid != T_pid) { deadpid = waitpid(T_pid, &status, 0); if (deadpid == T_pid) { if (WIFSIGNALED(status)) { if (WTERMSIG(status) == SIGTERM) t_info( "the test case timed out\n"); else t_info( "the test case caused exception %d\n", WTERMSIG(status)); t_result(T_UNRESOLVED); } } else if ((deadpid == -1) && (errno == EINTR) && T_int) { kill(T_pid, SIGTERM); T_int = 0; } else if ((deadpid == -1) && ((errno == ECHILD) || (errno == ESRCH))) break; } alarm(0); sa.sa_handler = SIG_IGN; (void)sigaction(SIGALRM, &sa, NULL); } else { t_info("fork failed, errno == %d\n", errno); t_result(T_UNRESOLVED); } } else { (*pts->pfv)(); } #else (*pts->pfv)(); #endif } ++pts; ++tnum; } snprintf(T_buf, sizeof(T_buf), "%s:", argv[0]); len = strlen(T_buf); (void) t_getdate(T_buf + len, T_BIGBUF - len); t_putinfo("E", T_buf); return(0); } void t_assert(const char *component, int anum, int class, const char *what, ...) { va_list args; char buf[T_BIGBUF]; (void)printf("T:%s:%d:%s\n", component, anum, class == T_REQUIRED ? "A" : "C"); /* * Format text to a buffer. */ va_start(args, what); (void)vsnprintf(buf, sizeof(buf), what, args); va_end(args); (void)t_putinfo("A", buf); (void)printf("\n"); } void t_info(const char *format, ...) { va_list args; char buf[T_BIGBUF]; va_start(args, format); (void) vsnprintf(buf, sizeof(buf), format, args); va_end(args); (void) t_putinfo("I", buf); } void t_result(int result) { const char *p; switch (result) { case T_PASS: p = "PASS"; break; case T_FAIL: p = "FAIL"; break; case T_UNRESOLVED: p = "UNRESOLVED"; break; case T_SKIPPED: p = "SKIPPED"; break; case T_UNTESTED: p = "UNTESTED"; break; case T_THREADONLY: p = "THREADONLY"; break; case T_PKCS11ONLY: p = "PKCS11ONLY"; break; default: p = "UNKNOWN"; break; } printf("R:%s\n", p); } char * t_getenv(const char *name) { char *n; char **p; size_t len; n = NULL; if (name && *name) { p = &T_env[0]; len = strlen(name); while (*p != NULL) { if (strncmp(*p, name, len) == 0) { if ( *(*p + len) == '=') { n = *p + len + 1; break; } } ++p; } } return(n); } /* * * Read in the config file at path, initializing T_env. * * note: no format checking for now ... * */ static int t_initconf(const char *path) { int n; int rval; char **p; FILE *fp; rval = -1; fp = fopen(path, "r"); if (fp != NULL) { n = 0; p = &T_env[0]; while (n < T_MAXENV) { *p = t_fgetbs(fp); if (*p == NULL) break; if ((**p == '#') || (strchr(*p, '=') == NULL)) { /* * Skip comments and other junk. */ (void)free(*p); continue; } ++p; ++n; } (void)fclose(fp); rval = 0; } return (rval); } /* * * Dump T_env to stdout. * */ static int t_dumpconf(const char *path) { int rval; char **p; FILE *fp; rval = -1; fp = fopen(path, "r"); if (fp != NULL) { p = &T_env[0]; while (*p != NULL) { printf("C:%s\n", *p); ++p; } (void) fclose(fp); rval = 0; } return(rval); } /* * * Read a newline or EOF terminated string from fp. * On success: * return a malloc'd buf containing the string with * the newline converted to a '\0'. * On error: * return NULL. * * Caller is responsible for freeing buf. * */ char * t_fgetbs(FILE *fp) { int c; size_t n; size_t size; char *buf, *old; char *p; n = 0; size = T_BUFSIZ; old = buf = (char *) malloc(T_BUFSIZ * sizeof(char)); if (buf != NULL) { p = buf; while ((c = fgetc(fp)) != EOF) { if ((c == '\r') || (c == '\n')) break; *p++ = c; ++n; if ( n >= size ) { size += T_BUFSIZ; buf = (char *)realloc(buf, size * sizeof(char)); if (buf == NULL) goto err; old = buf; p = buf + n; } } *p = '\0'; if (c == EOF && n == 0U) { free(buf); return (NULL); } return (buf); } else { err: if (old != NULL) free(old); fprintf(stderr, "malloc/realloc failed %d", errno); return(NULL); } } /* * * Put info to log, using key. * For now, just dump it out. * Later format into pretty lines. * */ static int t_putinfo(const char *key, const char *info) { int rval; /* * For now. */ rval = printf("%s:%s", key, info); return(rval); } static char * t_getdate(char *buf, size_t buflen) { size_t n; time_t t; struct tm *p; t = time(NULL); p = localtime(&t); n = strftime(buf, buflen - 1, "%A %d %B %H:%M:%S %Y\n", p); return(n != 0U ? buf : NULL); } /* * Some generally used utilities. */ struct dns_errormap { isc_result_t result; const char *text; } dns_errormap[] = { { ISC_R_SUCCESS, "ISC_R_SUCCESS" }, { ISC_R_EXISTS, "ISC_R_EXISTS" }, { ISC_R_NOTFOUND, "ISC_R_NOTFOUND" }, { ISC_R_NOSPACE, "ISC_R_NOSPACE" }, { ISC_R_UNEXPECTED, "ISC_R_UNEXPECTED" }, { ISC_R_UNEXPECTEDEND, "ISC_R_UNEXPECTEDEND" }, { ISC_R_RANGE, "ISC_R_RANGE" }, { DNS_R_LABELTOOLONG, "DNS_R_LABELTOOLONG" }, { DNS_R_BADESCAPE, "DNS_R_BADESCAPE" }, /* { DNS_R_BADBITSTRING, "DNS_R_BADBITSTRING" }, */ /* { DNS_R_BITSTRINGTOOLONG, "DNS_R_BITSTRINGTOOLONG"}, */ { DNS_R_EMPTYLABEL, "DNS_R_EMPTYLABEL" }, { DNS_R_BADDOTTEDQUAD, "DNS_R_BADDOTTEDQUAD" }, { DNS_R_UNKNOWN, "DNS_R_UNKNOWN" }, { DNS_R_BADLABELTYPE, "DNS_R_BADLABELTYPE" }, { DNS_R_BADPOINTER, "DNS_R_BADPOINTER" }, { DNS_R_TOOMANYHOPS, "DNS_R_TOOMANYHOPS" }, { DNS_R_DISALLOWED, "DNS_R_DISALLOWED" }, { DNS_R_EXTRATOKEN, "DNS_R_EXTRATOKEN" }, { DNS_R_EXTRADATA, "DNS_R_EXTRADATA" }, { DNS_R_TEXTTOOLONG, "DNS_R_TEXTTOOLONG" }, { DNS_R_SYNTAX, "DNS_R_SYNTAX" }, { DNS_R_BADCKSUM, "DNS_R_BADCKSUM" }, { DNS_R_BADAAAA, "DNS_R_BADAAAA" }, { DNS_R_NOOWNER, "DNS_R_NOOWNER" }, { DNS_R_NOTTL, "DNS_R_NOTTL" }, { DNS_R_BADCLASS, "DNS_R_BADCLASS" }, { DNS_R_PARTIALMATCH, "DNS_R_PARTIALMATCH" }, { DNS_R_NEWORIGIN, "DNS_R_NEWORIGIN" }, { DNS_R_UNCHANGED, "DNS_R_UNCHANGED" }, { DNS_R_BADTTL, "DNS_R_BADTTL" }, { DNS_R_NOREDATA, "DNS_R_NOREDATA" }, { DNS_R_CONTINUE, "DNS_R_CONTINUE" }, { DNS_R_DELEGATION, "DNS_R_DELEGATION" }, { DNS_R_GLUE, "DNS_R_GLUE" }, { DNS_R_DNAME, "DNS_R_DNAME" }, { DNS_R_CNAME, "DNS_R_CNAME" }, { DNS_R_NXDOMAIN, "DNS_R_NXDOMAIN" }, { DNS_R_NXRRSET, "DNS_R_NXRRSET" }, { DNS_R_BADDB, "DNS_R_BADDB" }, { DNS_R_ZONECUT, "DNS_R_ZONECUT" }, { DNS_R_NOTZONETOP, "DNS_R_NOTZONETOP" }, { DNS_R_SEENINCLUDE, "DNS_R_SEENINCLUDE" }, { DNS_R_SINGLETON, "DNS_R_SINGLETON" }, { (isc_result_t)0, NULL } }; isc_result_t t_dns_result_fromtext(char *name) { isc_result_t result; struct dns_errormap *pmap; result = ISC_R_UNEXPECTED; pmap = dns_errormap; while (pmap->text != NULL) { if (strcmp(name, pmap->text) == 0) break; ++pmap; } if (pmap->text != NULL) result = pmap->result; return (result); } struct dc_method_map { unsigned int dc_method; const char *text; } dc_method_map[] = { { DNS_COMPRESS_NONE, "DNS_COMPRESS_NONE" }, { DNS_COMPRESS_GLOBAL14, "DNS_COMPRESS_GLOBAL14" }, { DNS_COMPRESS_ALL, "DNS_COMPRESS_ALL" }, { 0, NULL } }; unsigned int t_dc_method_fromtext(char *name) { unsigned int dc_method; struct dc_method_map *pmap; dc_method = DNS_COMPRESS_NONE; pmap = dc_method_map; while (pmap->text != NULL) { if (strcmp(name, pmap->text) == 0) break; ++pmap; } if (pmap->text != NULL) dc_method = pmap->dc_method; return(dc_method); } int t_bustline(char *line, char **toks) { int cnt; char *p; cnt = 0; if (line && *line) { while ((p = strtok(line, "\t")) && (cnt < T_MAXTOKS)) { *toks++ = p; line = NULL; ++cnt; } } return(cnt); } static void printhelp(void) { int cnt; testspec_t *pts; cnt = 1; pts = &T_testlist[0]; printf("Available tests:\n"); while (pts->func_name) { printf("\t%d\t%s\n", cnt, pts->func_name); ++pts; ++cnt; } } static void printusage(void) { printf("Usage:\n%s\n", Usage); } int t_eval(const char *filename, int (*func)(char **), int nargs) { FILE *fp; char *p; int line; int cnt; int result; int tresult; int nfails; int nprobs; int npass; char *tokens[T_MAXTOKS + 1]; tresult = T_UNTESTED; npass = 0; nfails = 0; nprobs = 0; fp = fopen(filename, "r"); if (fp != NULL) { line = 0; while ((p = t_fgetbs(fp)) != NULL) { ++line; /* * Skip comment lines. */ if ((isspace((unsigned char)*p)) || (*p == '#')) { (void)free(p); continue; } cnt = t_bustline(p, tokens); if (cnt == nargs) { tresult = func(tokens); switch (tresult) { case T_PASS: ++npass; break; case T_FAIL: ++nfails; break; case T_SKIPPED: case T_UNTESTED: break; default: ++nprobs; break; } } else { t_info("bad format in %s at line %d\n", filename, line); ++nprobs; } (void)free(p); } (void)fclose(fp); } else { t_info("Missing datafile %s\n", filename); ++nprobs; } result = T_UNRESOLVED; if (nfails == 0 && nprobs == 0 && npass > 0) result = T_PASS; else if (nfails > 0) result = T_FAIL; else if (npass == 0) result = tresult; return (result); } #ifdef WIN32 void t_settests(const testspec_t list[]) { int tnum; const testspec_t *pts; memset(T_testlist, 0, sizeof(T_testlist)); pts = &list[0]; for (tnum = 0; tnum < T_MAXTESTS - 1; pts++, tnum++) { if (*pts->pfv == NULL) break; T_testlist[tnum] = *pts; } } #endif bind9-9.10.3.dfsg.P4/lib/tests/T_testlist.imp0000644000470500017500000000002112664710322020137 0ustar lamontlamont#! . T_testlist bind9-9.10.3.dfsg.P4/lib/dns/0002755000470500017500000000000012672612753014735 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/dns/rbt.c0000644000470500017500000026436612664710322015677 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007-2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ /* Principal Authors: DCL */ #include #include #ifdef HAVE_INTTYPES_H #include /* uintptr_t */ #endif #include #include #include #include #include #include #include #include #include #include #include /*% * This define is so dns/name.h (included by dns/fixedname.h) uses more * efficient macro calls instead of functions for a few operations. */ #define DNS_NAME_USEINLINE 1 #include #include #include #include #include #include #define CHECK(x) \ do { \ result = (x); \ if (result != ISC_R_SUCCESS) \ goto cleanup; \ } while (0) #define RBT_MAGIC ISC_MAGIC('R', 'B', 'T', '+') #define VALID_RBT(rbt) ISC_MAGIC_VALID(rbt, RBT_MAGIC) /* * XXXDCL Since parent pointers were added in again, I could remove all of the * chain junk, and replace with dns_rbt_firstnode, _previousnode, _nextnode, * _lastnode. This would involve pretty major change to the API. */ #define CHAIN_MAGIC ISC_MAGIC('0', '-', '0', '-') #define VALID_CHAIN(chain) ISC_MAGIC_VALID(chain, CHAIN_MAGIC) #define RBT_HASH_SIZE 64 #ifdef RBT_MEM_TEST #undef RBT_HASH_SIZE #define RBT_HASH_SIZE 2 /*%< To give the reallocation code a workout. */ #endif struct dns_rbt { unsigned int magic; isc_mem_t * mctx; dns_rbtnode_t * root; void (*data_deleter)(void *, void *); void * deleter_arg; unsigned int nodecount; unsigned int hashsize; dns_rbtnode_t ** hashtable; void * mmap_location; }; #define RED 0 #define BLACK 1 /* * This is the header for map-format RBT images. It is populated, * and then written, as the LAST thing done to the file before returning. * Writing this last (with zeros in the header area initially) will ensure * that the header is only valid when the RBT image is also valid. */ typedef struct file_header file_header_t; /* Pad to 32 bytes */ static char FILE_VERSION[32] = "\0"; /* Header length, always the same size regardless of structure size */ #define HEADER_LENGTH 1024 struct file_header { char version1[32]; isc_uint64_t first_node_offset; /* usually 1024 */ /* * information about the system on which the map file was generated * will be used to tell if we can load the map file or not */ isc_uint32_t ptrsize; unsigned int bigendian:1; /* big or little endian system */ unsigned int rdataset_fixed:1; /* compiled with --enable-rrset-fixed */ unsigned int nodecount; /* shadow from rbt structure */ isc_uint64_t crc; char version2[32]; /* repeated; must match version1 */ }; /* * The following declarations are for the serialization of an RBT: * * step one: write out a zeroed header of 1024 bytes * step two: walk the tree in a depth-first, left-right-down order, writing * out the nodes, reserving space as we go, correcting addresses to point * at the proper offset in the file, and setting a flag for each pointer to * indicate that it is a reference to a location in the file, rather than in * memory. * step three: write out the header, adding the information that will be * needed to re-create the tree object itself. * * The RBTDB object will do this three times, once for each of the three * RBT objects it contains. * * Note: 'file' must point an actual open file that can be mmapped * and fseeked, not to a pipe or stream */ static isc_result_t dns_rbt_zero_header(FILE *file); static isc_result_t write_header(FILE *file, dns_rbt_t *rbt, isc_uint64_t first_node_offset, isc_uint64_t crc); static isc_result_t serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left, uintptr_t right, uintptr_t down, uintptr_t parent, uintptr_t data, isc_uint64_t *crc); static isc_result_t serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent, dns_rbtdatawriter_t datawriter, void *writer_arg, uintptr_t *where, isc_uint64_t *crc); /* * The following functions allow you to get the actual address of a pointer * without having to use an if statement to check to see if that address is * relative or not */ static inline dns_rbtnode_t * getparent(dns_rbtnode_t *node, file_header_t *header) { char *adjusted_address = (char *)(node->parent); adjusted_address += node->parent_is_relative * (uintptr_t)header; return ((dns_rbtnode_t *)adjusted_address); } static inline dns_rbtnode_t * getleft(dns_rbtnode_t *node, file_header_t *header) { char *adjusted_address = (char *)(node->left); adjusted_address += node->left_is_relative * (uintptr_t)header; return ((dns_rbtnode_t *)adjusted_address); } static inline dns_rbtnode_t * getright(dns_rbtnode_t *node, file_header_t *header) { char *adjusted_address = (char *)(node->right); adjusted_address += node->right_is_relative * (uintptr_t)header; return ((dns_rbtnode_t *)adjusted_address); } static inline dns_rbtnode_t * getdown(dns_rbtnode_t *node, file_header_t *header) { char *adjusted_address = (char *)(node->down); adjusted_address += node->down_is_relative * (uintptr_t)header; return ((dns_rbtnode_t *)adjusted_address); } static inline dns_rbtnode_t * getdata(dns_rbtnode_t *node, file_header_t *header) { char *adjusted_address = (char *)(node->data); adjusted_address += node->data_is_relative * (uintptr_t)header; return ((dns_rbtnode_t *)adjusted_address); } /*% * Elements of the rbtnode structure. */ #define PARENT(node) ((node)->parent) #define LEFT(node) ((node)->left) #define RIGHT(node) ((node)->right) #define DOWN(node) ((node)->down) #define DATA(node) ((node)->data) #define IS_EMPTY(node) ((node)->data == NULL) #define HASHNEXT(node) ((node)->hashnext) #define HASHVAL(node) ((node)->hashval) #define COLOR(node) ((node)->color) #define NAMELEN(node) ((node)->namelen) #define OLDNAMELEN(node) ((node)->oldnamelen) #define OFFSETLEN(node) ((node)->offsetlen) #define ATTRS(node) ((node)->attributes) #define IS_ROOT(node) ISC_TF((node)->is_root == 1) #define FINDCALLBACK(node) ISC_TF((node)->find_callback == 1) /*% * Structure elements from the rbtdb.c, not * used as part of the rbt.c algorithms. */ #define DIRTY(node) ((node)->dirty) #define WILD(node) ((node)->wild) #define LOCKNUM(node) ((node)->locknum) /*% * The variable length stuff stored after the node has the following * structure. * * {1..255}{1}{1..128} * * contains the name of the node when it was created. * contains the length of when the node was created. * contains the offets into name for each label when the node was * created. */ #define NAME(node) ((unsigned char *)((node) + 1)) #define OFFSETS(node) (NAME(node) + OLDNAMELEN(node) + 1) #define OLDOFFSETLEN(node) (OFFSETS(node)[-1]) #define NODE_SIZE(node) (sizeof(*node) + \ OLDNAMELEN(node) + OLDOFFSETLEN(node) + 1) /*% * Color management. */ #define IS_RED(node) ((node) != NULL && (node)->color == RED) #define IS_BLACK(node) ((node) == NULL || (node)->color == BLACK) #define MAKE_RED(node) ((node)->color = RED) #define MAKE_BLACK(node) ((node)->color = BLACK) /*% * Chain management. * * The "ancestors" member of chains were removed, with their job now * being wholly handled by parent pointers (which didn't exist, because * of memory concerns, when chains were first implemented). */ #define ADD_LEVEL(chain, node) \ do { \ INSIST((chain)->level_count < DNS_RBT_LEVELBLOCK); \ (chain)->levels[(chain)->level_count++] = (node); \ } while (0) /*% * The following macros directly access normally private name variables. * These macros are used to avoid a lot of function calls in the critical * path of the tree traversal code. */ static inline void NODENAME(dns_rbtnode_t *node, dns_name_t *name) { name->length = NAMELEN(node); name->labels = OFFSETLEN(node); name->ndata = NAME(node); name->offsets = OFFSETS(node); name->attributes = ATTRS(node); name->attributes |= DNS_NAMEATTR_READONLY; } void dns_rbtnode_nodename(dns_rbtnode_t *node, dns_name_t *name) { name->length = NAMELEN(node); name->labels = OFFSETLEN(node); name->ndata = NAME(node); name->offsets = OFFSETS(node); name->attributes = ATTRS(node); name->attributes |= DNS_NAMEATTR_READONLY; } dns_rbtnode_t * dns_rbt_root(dns_rbt_t *rbt) { return rbt->root; } #ifdef DNS_RBT_USEHASH static isc_result_t inithash(dns_rbt_t *rbt); #endif #ifdef DEBUG #define inline /* * A little something to help out in GDB. */ dns_name_t Name(dns_rbtnode_t *node); dns_name_t Name(dns_rbtnode_t *node) { dns_name_t name; dns_name_init(&name, NULL); if (node != NULL) NODENAME(node, &name); return (name); } static void hexdump(const char *desc, unsigned char *data, size_t size) { char hexdump[BUFSIZ * 2 + 1]; isc_buffer_t b; isc_region_t r; isc_result_t result; size_t bytes; fprintf(stderr, "%s: ", desc); do { isc_buffer_init(&b, hexdump, sizeof(hexdump)); r.base = data; r.length = bytes = (size > BUFSIZ) ? BUFSIZ : size; result = isc_hex_totext(&r, 0, "", &b); RUNTIME_CHECK(result == ISC_R_SUCCESS); isc_buffer_putuint8(&b, 0); fprintf(stderr, "%s", hexdump); data += bytes; size -= bytes; } while (size > 0); fprintf(stderr, "\n"); } #endif /* DEBUG */ /* The passed node must not be NULL. */ static inline dns_rbtnode_t * get_subtree_root(dns_rbtnode_t *node) { while (!IS_ROOT(node)) { node = PARENT(node); } return (node); } /* Upper node is the parent of the root of the passed node's * subtree. The passed node must not be NULL. */ static inline dns_rbtnode_t * get_upper_node(dns_rbtnode_t *node) { dns_rbtnode_t *root = get_subtree_root(node); /* * Return the node in the level above the argument node that points * to the level the argument node is in. If the argument node is in * the top level, the return value is NULL. */ return (PARENT(root)); } size_t dns__rbtnode_getdistance(dns_rbtnode_t *node) { size_t nodes = 1; while (node != NULL) { if (IS_ROOT(node)) break; nodes++; node = PARENT(node); } return (nodes); } /* * Forward declarations. */ static isc_result_t create_node(isc_mem_t *mctx, dns_name_t *name, dns_rbtnode_t **nodep); #ifdef DNS_RBT_USEHASH static inline void hash_node(dns_rbt_t *rbt, dns_rbtnode_t *node, dns_name_t *name); static inline void unhash_node(dns_rbt_t *rbt, dns_rbtnode_t *node); static void rehash(dns_rbt_t *rbt, unsigned int newcount); #else #define hash_node(rbt, node, name) #define unhash_node(rbt, node) #define rehash(rbt, newcount) #endif static inline void rotate_left(dns_rbtnode_t *node, dns_rbtnode_t **rootp); static inline void rotate_right(dns_rbtnode_t *node, dns_rbtnode_t **rootp); static void addonlevel(dns_rbtnode_t *node, dns_rbtnode_t *current, int order, dns_rbtnode_t **rootp); static void deletefromlevel(dns_rbtnode_t *delete, dns_rbtnode_t **rootp); static isc_result_t treefix(dns_rbt_t *rbt, void *base, size_t size, dns_rbtnode_t *n, dns_name_t *name, dns_rbtdatafixer_t datafixer, void *fixer_arg, isc_uint64_t *crc); static isc_result_t deletetree(dns_rbt_t *rbt, dns_rbtnode_t *node); static void deletetreeflat(dns_rbt_t *rbt, unsigned int quantum, dns_rbtnode_t **nodep); static void printnodename(dns_rbtnode_t *node, isc_boolean_t quoted, FILE *f); static void freenode(dns_rbt_t *rbt, dns_rbtnode_t **nodep); static isc_result_t dns_rbt_zero_header(FILE *file) { /* * Write out a zeroed header as a placeholder. Doing this ensures * that the file will not read while it is partially written, should * writing fail or be interrupted. */ char buffer[HEADER_LENGTH]; isc_result_t result; memset(buffer, 0, HEADER_LENGTH); result = isc_stdio_write(buffer, 1, HEADER_LENGTH, file, NULL); if (result != ISC_R_SUCCESS) return (result); result = fflush(file); if (result != ISC_R_SUCCESS) return (result); return (ISC_R_SUCCESS); } /* * Write out the real header, including NodeDump version information * and the offset of the first node. * * Any information stored in the rbt object itself should be stored * here. */ static isc_result_t write_header(FILE *file, dns_rbt_t *rbt, isc_uint64_t first_node_offset, isc_uint64_t crc) { file_header_t header; isc_result_t result; off_t location; if (FILE_VERSION[0] == '\0') { memset(FILE_VERSION, 0, sizeof(FILE_VERSION)); snprintf(FILE_VERSION, sizeof(FILE_VERSION), "RBT Image %s %s", dns_major, dns_mapapi); } memset(&header, 0, sizeof(file_header_t)); memmove(header.version1, FILE_VERSION, sizeof(header.version1)); memmove(header.version2, FILE_VERSION, sizeof(header.version2)); header.first_node_offset = first_node_offset; header.ptrsize = (isc_uint32_t) sizeof(void *); header.bigendian = (1 == htonl(1)) ? 1 : 0; #ifdef DNS_RDATASET_FIXED header.rdataset_fixed = 1; #else header.rdataset_fixed = 0; #endif header.nodecount = rbt->nodecount; header.crc = crc; CHECK(isc_stdio_tell(file, &location)); location = dns_rbt_serialize_align(location); CHECK(isc_stdio_seek(file, location, SEEK_SET)); CHECK(isc_stdio_write(&header, 1, sizeof(file_header_t), file, NULL)); CHECK(fflush(file)); /* Ensure we are always at the end of the file. */ CHECK(isc_stdio_seek(file, 0, SEEK_END)); cleanup: return (result); } static isc_result_t serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left, uintptr_t right, uintptr_t down, uintptr_t parent, uintptr_t data, isc_uint64_t *crc) { dns_rbtnode_t temp_node; off_t file_position; unsigned char *node_data; size_t datasize; isc_result_t result; #ifdef DEBUG dns_name_t nodename; #endif INSIST(node != NULL); CHECK(isc_stdio_tell(file, &file_position)); file_position = dns_rbt_serialize_align(file_position); CHECK(isc_stdio_seek(file, file_position, SEEK_SET)); temp_node = *node; temp_node.down_is_relative = 0; temp_node.left_is_relative = 0; temp_node.right_is_relative = 0; temp_node.parent_is_relative = 0; temp_node.data_is_relative = 0; temp_node.is_mmapped = 1; /* * If the next node is not NULL, calculate the next node's location * in the file. Note that this will have to change when the data * structure changes, and it also assumes that we always write the * nodes out in list order (which we currently do.) */ if (temp_node.parent != NULL) { temp_node.parent = (dns_rbtnode_t *)(parent); temp_node.parent_is_relative = 1; } if (temp_node.left != NULL) { temp_node.left = (dns_rbtnode_t *)(left); temp_node.left_is_relative = 1; } if (temp_node.right != NULL) { temp_node.right = (dns_rbtnode_t *)(right); temp_node.right_is_relative = 1; } if (temp_node.down != NULL) { temp_node.down = (dns_rbtnode_t *)(down); temp_node.down_is_relative = 1; } if (temp_node.data != NULL) { temp_node.data = (dns_rbtnode_t *)(data); temp_node.data_is_relative = 1; } node_data = (unsigned char *) node + sizeof(dns_rbtnode_t); datasize = NODE_SIZE(node) - sizeof(dns_rbtnode_t); CHECK(isc_stdio_write(&temp_node, 1, sizeof(dns_rbtnode_t), file, NULL)); CHECK(isc_stdio_write(node_data, 1, datasize, file, NULL)); #ifdef DEBUG dns_name_init(&nodename, NULL); NODENAME(node, &nodename); fprintf(stderr, "serialize "); dns_name_print(&nodename, stderr); fprintf(stderr, "\n"); hexdump("node header", (unsigned char*) &temp_node, sizeof(dns_rbtnode_t)); hexdump("node data", node_data, datasize); #endif isc_crc64_update(crc, (const isc_uint8_t *) &temp_node, sizeof(dns_rbtnode_t)); isc_crc64_update(crc, (const isc_uint8_t *) node_data, datasize); cleanup: return (result); } static isc_result_t serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent, dns_rbtdatawriter_t datawriter, void *writer_arg, uintptr_t *where, isc_uint64_t *crc) { uintptr_t left = 0, right = 0, down = 0, data = 0; off_t location = 0, offset_adjust; isc_result_t result; if (node == NULL) { if (where != NULL) *where = 0; return (ISC_R_SUCCESS); } /* Reserve space for current node. */ CHECK(isc_stdio_tell(file, &location)); location = dns_rbt_serialize_align(location); CHECK(isc_stdio_seek(file, location, SEEK_SET)); offset_adjust = dns_rbt_serialize_align(location + NODE_SIZE(node)); CHECK(isc_stdio_seek(file, offset_adjust, SEEK_SET)); /* * Serialize the rest of the tree. * * WARNING: A change in the order (from left, right, down) * will break the way the crc hash is computed. */ CHECK(serialize_nodes(file, getleft(node, NULL), location, datawriter, writer_arg, &left, crc)); CHECK(serialize_nodes(file, getright(node, NULL), location, datawriter, writer_arg, &right, crc)); CHECK(serialize_nodes(file, getdown(node, NULL), location, datawriter, writer_arg, &down, crc)); if (node->data != NULL) { off_t ret; CHECK(isc_stdio_tell(file, &ret)); ret = dns_rbt_serialize_align(ret); CHECK(isc_stdio_seek(file, ret, SEEK_SET)); data = ret; datawriter(file, node->data, writer_arg, crc); } /* Seek back to reserved space. */ CHECK(isc_stdio_seek(file, location, SEEK_SET)); /* Serialize the current node. */ CHECK(serialize_node(file, node, left, right, down, parent, data, crc)); /* Ensure we are always at the end of the file. */ CHECK(isc_stdio_seek(file, 0, SEEK_END)); if (where != NULL) *where = (uintptr_t) location; cleanup: return (result); } off_t dns_rbt_serialize_align(off_t target) { off_t offset = target % 8; if (offset == 0) return (target); else return (target + 8 - offset); } isc_result_t dns_rbt_serialize_tree(FILE *file, dns_rbt_t *rbt, dns_rbtdatawriter_t datawriter, void *writer_arg, off_t *offset) { isc_result_t result; off_t header_position, node_position, end_position; isc_uint64_t crc; REQUIRE(file != NULL); CHECK(isc_file_isplainfilefd(fileno(file))); isc_crc64_init(&crc); CHECK(isc_stdio_tell(file, &header_position)); /* Write dummy header */ CHECK(dns_rbt_zero_header(file)); /* Serialize nodes */ CHECK(isc_stdio_tell(file, &node_position)); CHECK(serialize_nodes(file, rbt->root, 0, datawriter, writer_arg, NULL, &crc)); CHECK(isc_stdio_tell(file, &end_position)); if (node_position == end_position) { CHECK(isc_stdio_seek(file, header_position, SEEK_SET)); *offset = 0; return (ISC_R_SUCCESS); } isc_crc64_final(&crc); #ifdef DEBUG hexdump("serializing CRC", (unsigned char *)&crc, sizeof(crc)); #endif /* Serialize header */ CHECK(isc_stdio_seek(file, header_position, SEEK_SET)); CHECK(write_header(file, rbt, HEADER_LENGTH, crc)); /* Ensure we are always at the end of the file. */ CHECK(isc_stdio_seek(file, 0, SEEK_END)); *offset = dns_rbt_serialize_align(header_position); cleanup: return (result); } #define CONFIRM(a) do { \ if (! (a)) { \ result = ISC_R_INVALIDFILE; \ goto cleanup; \ } \ } while(0); static isc_result_t treefix(dns_rbt_t *rbt, void *base, size_t filesize, dns_rbtnode_t *n, dns_name_t *name, dns_rbtdatafixer_t datafixer, void *fixer_arg, isc_uint64_t *crc) { isc_result_t result = ISC_R_SUCCESS; dns_fixedname_t fixed; dns_name_t nodename, *fullname; unsigned char *node_data; dns_rbtnode_t header; size_t datasize, nodemax = filesize - sizeof(dns_rbtnode_t); if (n == NULL) return (ISC_R_SUCCESS); CONFIRM((void *) n >= base); CONFIRM((char *) n - (char *) base <= (int) nodemax); CONFIRM(DNS_RBTNODE_VALID(n)); dns_name_init(&nodename, NULL); NODENAME(n, &nodename); fullname = &nodename; CONFIRM(dns_name_isvalid(fullname)); if (!dns_name_isabsolute(&nodename)) { dns_fixedname_init(&fixed); fullname = dns_fixedname_name(&fixed); CHECK(dns_name_concatenate(&nodename, name, fullname, NULL)); } /* memorize header contents prior to fixup */ memmove(&header, n, sizeof(header)); if (n->left_is_relative) { CONFIRM(n->left <= (dns_rbtnode_t *) nodemax); n->left = getleft(n, rbt->mmap_location); n->left_is_relative = 0; CONFIRM(DNS_RBTNODE_VALID(n->left)); } else CONFIRM(n->left == NULL); if (n->right_is_relative) { CONFIRM(n->right <= (dns_rbtnode_t *) nodemax); n->right = getright(n, rbt->mmap_location); n->right_is_relative = 0; CONFIRM(DNS_RBTNODE_VALID(n->right)); } else CONFIRM(n->right == NULL); if (n->down_is_relative) { CONFIRM(n->down <= (dns_rbtnode_t *) nodemax); n->down = getdown(n, rbt->mmap_location); n->down_is_relative = 0; CONFIRM(n->down > (dns_rbtnode_t *) n); CONFIRM(DNS_RBTNODE_VALID(n->down)); } else CONFIRM(n->down == NULL); if (n->parent_is_relative) { CONFIRM(n->parent <= (dns_rbtnode_t *) nodemax); n->parent = getparent(n, rbt->mmap_location); n->parent_is_relative = 0; CONFIRM(n->parent < (dns_rbtnode_t *) n); CONFIRM(DNS_RBTNODE_VALID(n->parent)); } else CONFIRM(n->parent == NULL); if (n->data_is_relative) { CONFIRM(n->data <= (void *) filesize); n->data = getdata(n, rbt->mmap_location); n->data_is_relative = 0; CONFIRM(n->data > (void *) n); } else CONFIRM(n->data == NULL); hash_node(rbt, n, fullname); /* a change in the order (from left, right, down) will break hashing*/ if (n->left != NULL) CHECK(treefix(rbt, base, filesize, n->left, name, datafixer, fixer_arg, crc)); if (n->right != NULL) CHECK(treefix(rbt, base, filesize, n->right, name, datafixer, fixer_arg, crc)); if (n->down != NULL) CHECK(treefix(rbt, base, filesize, n->down, fullname, datafixer, fixer_arg, crc)); if (datafixer != NULL && n->data != NULL) CHECK(datafixer(n, base, filesize, fixer_arg, crc)); rbt->nodecount++; node_data = (unsigned char *) n + sizeof(dns_rbtnode_t); datasize = NODE_SIZE(n) - sizeof(dns_rbtnode_t); #ifdef DEBUG fprintf(stderr, "deserialize "); dns_name_print(&nodename, stderr); fprintf(stderr, "\n"); hexdump("node header", (unsigned char *) &header, sizeof(dns_rbtnode_t)); hexdump("node data", node_data, datasize); #endif isc_crc64_update(crc, (const isc_uint8_t *) &header, sizeof(dns_rbtnode_t)); isc_crc64_update(crc, (const isc_uint8_t *) node_data, datasize); cleanup: return (result); } isc_result_t dns_rbt_deserialize_tree(void *base_address, size_t filesize, off_t header_offset, isc_mem_t *mctx, dns_rbtdeleter_t deleter, void *deleter_arg, dns_rbtdatafixer_t datafixer, void *fixer_arg, dns_rbtnode_t **originp, dns_rbt_t **rbtp) { isc_result_t result = ISC_R_SUCCESS; file_header_t *header; dns_rbt_t *rbt = NULL; isc_uint64_t crc; REQUIRE(originp == NULL || *originp == NULL); REQUIRE(rbtp != NULL && *rbtp == NULL); isc_crc64_init(&crc); CHECK(dns_rbt_create(mctx, deleter, deleter_arg, &rbt)); rbt->mmap_location = base_address; header = (file_header_t *)((char *)base_address + header_offset); #ifdef DNS_RDATASET_FIXED if (header->rdataset_fixed != 1) { result = ISC_R_INVALIDFILE; goto cleanup; } #else if (header->rdataset_fixed != 0) { result = ISC_R_INVALIDFILE; goto cleanup; } #endif if (header->ptrsize != (isc_uint32_t) sizeof(void *)) { result = ISC_R_INVALIDFILE; goto cleanup; } if (header->bigendian != (1 == htonl(1)) ? 1 : 0) { result = ISC_R_INVALIDFILE; goto cleanup; } /* Copy other data items from the header into our rbt. */ rbt->root = (dns_rbtnode_t *)((char *)base_address + header_offset + header->first_node_offset); if ((header->nodecount * sizeof(dns_rbtnode_t)) > filesize) { result = ISC_R_INVALIDFILE; goto cleanup; } rehash(rbt, header->nodecount); CHECK(treefix(rbt, base_address, filesize, rbt->root, dns_rootname, datafixer, fixer_arg, &crc)); isc_crc64_final(&crc); #ifdef DEBUG hexdump("deserializing CRC", (unsigned char *)&crc, sizeof(crc)); #endif /* Check file hash */ if (header->crc != crc) { result = ISC_R_INVALIDFILE; goto cleanup; } *rbtp = rbt; if (originp != NULL) *originp = rbt->root; if (header->nodecount != rbt->nodecount) result = ISC_R_INVALIDFILE; cleanup: if (result != ISC_R_SUCCESS && rbt != NULL) { rbt->root = NULL; rbt->nodecount = 0; dns_rbt_destroy(&rbt); } return (result); } /* * Initialize a red/black tree of trees. */ isc_result_t dns_rbt_create(isc_mem_t *mctx, dns_rbtdeleter_t deleter, void *deleter_arg, dns_rbt_t **rbtp) { #ifdef DNS_RBT_USEHASH isc_result_t result; #endif dns_rbt_t *rbt; REQUIRE(mctx != NULL); REQUIRE(rbtp != NULL && *rbtp == NULL); REQUIRE(deleter == NULL ? deleter_arg == NULL : 1); rbt = (dns_rbt_t *)isc_mem_get(mctx, sizeof(*rbt)); if (rbt == NULL) return (ISC_R_NOMEMORY); rbt->mctx = NULL; isc_mem_attach(mctx, &rbt->mctx); rbt->data_deleter = deleter; rbt->deleter_arg = deleter_arg; rbt->root = NULL; rbt->nodecount = 0; rbt->hashtable = NULL; rbt->hashsize = 0; rbt->mmap_location = NULL; #ifdef DNS_RBT_USEHASH result = inithash(rbt); if (result != ISC_R_SUCCESS) { isc_mem_putanddetach(&rbt->mctx, rbt, sizeof(*rbt)); return (result); } #endif rbt->magic = RBT_MAGIC; *rbtp = rbt; return (ISC_R_SUCCESS); } /* * Deallocate a red/black tree of trees. */ void dns_rbt_destroy(dns_rbt_t **rbtp) { RUNTIME_CHECK(dns_rbt_destroy2(rbtp, 0) == ISC_R_SUCCESS); } isc_result_t dns_rbt_destroy2(dns_rbt_t **rbtp, unsigned int quantum) { dns_rbt_t *rbt; REQUIRE(rbtp != NULL && VALID_RBT(*rbtp)); rbt = *rbtp; deletetreeflat(rbt, quantum, &rbt->root); if (rbt->root != NULL) return (ISC_R_QUOTA); INSIST(rbt->nodecount == 0); rbt->mmap_location = NULL; if (rbt->hashtable != NULL) isc_mem_put(rbt->mctx, rbt->hashtable, rbt->hashsize * sizeof(dns_rbtnode_t *)); rbt->magic = 0; isc_mem_putanddetach(&rbt->mctx, rbt, sizeof(*rbt)); *rbtp = NULL; return (ISC_R_SUCCESS); } unsigned int dns_rbt_nodecount(dns_rbt_t *rbt) { REQUIRE(VALID_RBT(rbt)); return (rbt->nodecount); } unsigned int dns_rbt_hashsize(dns_rbt_t *rbt) { REQUIRE(VALID_RBT(rbt)); return (rbt->hashsize); } static inline isc_result_t chain_name(dns_rbtnodechain_t *chain, dns_name_t *name, isc_boolean_t include_chain_end) { dns_name_t nodename; isc_result_t result = ISC_R_SUCCESS; int i; dns_name_init(&nodename, NULL); if (include_chain_end && chain->end != NULL) { NODENAME(chain->end, &nodename); result = dns_name_copy(&nodename, name, NULL); if (result != ISC_R_SUCCESS) return (result); } else dns_name_reset(name); for (i = (int)chain->level_count - 1; i >= 0; i--) { NODENAME(chain->levels[i], &nodename); result = dns_name_concatenate(name, &nodename, name, NULL); if (result != ISC_R_SUCCESS) return (result); } return (result); } static inline isc_result_t move_chain_to_last(dns_rbtnodechain_t *chain, dns_rbtnode_t *node) { do { /* * Go as far right and then down as much as possible, * as long as the rightmost node has a down pointer. */ while (RIGHT(node) != NULL) node = RIGHT(node); if (DOWN(node) == NULL) break; ADD_LEVEL(chain, node); node = DOWN(node); } while (1); chain->end = node; return (ISC_R_SUCCESS); } /* * Add 'name' to tree, initializing its data pointer with 'data'. */ isc_result_t dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep) { /* * Does this thing have too many variables or what? */ dns_rbtnode_t **root, *parent, *child, *current, *new_current; dns_name_t *add_name, *new_name, current_name, *prefix, *suffix; dns_fixedname_t fixedcopy, fixedprefix, fixedsuffix, fnewname; dns_offsets_t current_offsets; dns_namereln_t compared; isc_result_t result = ISC_R_SUCCESS; dns_rbtnodechain_t chain; unsigned int common_labels; unsigned int nlabels, hlabels; int order; REQUIRE(VALID_RBT(rbt)); REQUIRE(dns_name_isabsolute(name)); REQUIRE(nodep != NULL && *nodep == NULL); /* * Create a copy of the name so the original name structure is * not modified. */ dns_fixedname_init(&fixedcopy); add_name = dns_fixedname_name(&fixedcopy); dns_name_clone(name, add_name); if (rbt->root == NULL) { result = create_node(rbt->mctx, add_name, &new_current); if (result == ISC_R_SUCCESS) { rbt->nodecount++; new_current->is_root = 1; rbt->root = new_current; *nodep = new_current; hash_node(rbt, new_current, name); } return (result); } dns_rbtnodechain_init(&chain, rbt->mctx); dns_fixedname_init(&fixedprefix); dns_fixedname_init(&fixedsuffix); prefix = dns_fixedname_name(&fixedprefix); suffix = dns_fixedname_name(&fixedsuffix); root = &rbt->root; INSIST(IS_ROOT(*root)); parent = NULL; current = NULL; child = *root; dns_name_init(¤t_name, current_offsets); dns_fixedname_init(&fnewname); new_name = dns_fixedname_name(&fnewname); nlabels = dns_name_countlabels(name); hlabels = 0; do { current = child; NODENAME(current, ¤t_name); compared = dns_name_fullcompare(add_name, ¤t_name, &order, &common_labels); if (compared == dns_namereln_equal) { *nodep = current; result = ISC_R_EXISTS; break; } if (compared == dns_namereln_none) { if (order < 0) { parent = current; child = LEFT(current); } else if (order > 0) { parent = current; child = RIGHT(current); } } else { /* * This name has some suffix in common with the * name at the current node. If the name at * the current node is shorter, that means the * new name should be in a subtree. If the * name at the current node is longer, that means * the down pointer to this tree should point * to a new tree that has the common suffix, and * the non-common parts of these two names should * start a new tree. */ hlabels += common_labels; if (compared == dns_namereln_subdomain) { /* * All of the existing labels are in common, * so the new name is in a subtree. * Whack off the common labels for the * not-in-common part to be searched for * in the next level. */ dns_name_split(add_name, common_labels, add_name, NULL); /* * Follow the down pointer (possibly NULL). */ root = &DOWN(current); INSIST(*root == NULL || (IS_ROOT(*root) && PARENT(*root) == current)); parent = NULL; child = DOWN(current); ADD_LEVEL(&chain, current); } else { /* * The number of labels in common is fewer * than the number of labels at the current * node, so the current node must be adjusted * to have just the common suffix, and a down * pointer made to a new tree. */ INSIST(compared == dns_namereln_commonancestor || compared == dns_namereln_contains); /* * Ensure the number of levels in the tree * does not exceed the number of logical * levels allowed by DNSSEC. * * XXXDCL need a better error result? * * XXXDCL Since chain ancestors were removed, * no longer used by addonlevel(), * this is the only real use of chains in the * function. It could be done instead with * a simple integer variable, but I am pressed * for time. */ if (chain.level_count == (sizeof(chain.levels) / sizeof(*chain.levels))) { result = ISC_R_NOSPACE; break; } /* * Split the name into two parts, a prefix * which is the not-in-common parts of the * two names and a suffix that is the common * parts of them. */ dns_name_split(¤t_name, common_labels, prefix, suffix); result = create_node(rbt->mctx, suffix, &new_current); if (result != ISC_R_SUCCESS) break; /* * Reproduce the tree attributes of the * current node. */ new_current->is_root = current->is_root; if (current->nsec == DNS_RBT_NSEC_HAS_NSEC) new_current->nsec = DNS_RBT_NSEC_NORMAL; else new_current->nsec = current->nsec; PARENT(new_current) = PARENT(current); LEFT(new_current) = LEFT(current); RIGHT(new_current) = RIGHT(current); COLOR(new_current) = COLOR(current); /* * Fix pointers that were to the current node. */ if (parent != NULL) { if (LEFT(parent) == current) LEFT(parent) = new_current; else RIGHT(parent) = new_current; } if (LEFT(new_current) != NULL) PARENT(LEFT(new_current)) = new_current; if (RIGHT(new_current) != NULL) PARENT(RIGHT(new_current)) = new_current; if (*root == current) *root = new_current; NAMELEN(current) = prefix->length; OFFSETLEN(current) = prefix->labels; /* * Set up the new root of the next level. * By definition it will not be the top * level tree, so clear DNS_NAMEATTR_ABSOLUTE. */ current->is_root = 1; PARENT(current) = new_current; DOWN(new_current) = current; root = &DOWN(new_current); ADD_LEVEL(&chain, new_current); LEFT(current) = NULL; RIGHT(current) = NULL; MAKE_BLACK(current); ATTRS(current) &= ~DNS_NAMEATTR_ABSOLUTE; rbt->nodecount++; dns_name_getlabelsequence(name, nlabels - hlabels, hlabels, new_name); hash_node(rbt, new_current, new_name); if (common_labels == dns_name_countlabels(add_name)) { /* * The name has been added by pushing * the not-in-common parts down to * a new level. */ *nodep = new_current; return (ISC_R_SUCCESS); } else { /* * The current node has no data, * because it is just a placeholder. * Its data pointer is already NULL * from create_node()), so there's * nothing more to do to it. */ /* * The not-in-common parts of the new * name will be inserted into the new * level following this loop (unless * result != ISC_R_SUCCESS, which * is tested after the loop ends). */ dns_name_split(add_name, common_labels, add_name, NULL); break; } } } } while (child != NULL); if (result == ISC_R_SUCCESS) result = create_node(rbt->mctx, add_name, &new_current); if (result == ISC_R_SUCCESS) { addonlevel(new_current, current, order, root); rbt->nodecount++; *nodep = new_current; hash_node(rbt, new_current, name); } return (result); } /* * Add a name to the tree of trees, associating it with some data. */ isc_result_t dns_rbt_addname(dns_rbt_t *rbt, dns_name_t *name, void *data) { isc_result_t result; dns_rbtnode_t *node; REQUIRE(VALID_RBT(rbt)); REQUIRE(dns_name_isabsolute(name)); node = NULL; result = dns_rbt_addnode(rbt, name, &node); /* * dns_rbt_addnode will report the node exists even when * it does not have data associated with it, but the * dns_rbt_*name functions all behave depending on whether * there is data associated with a node. */ if (result == ISC_R_SUCCESS || (result == ISC_R_EXISTS && DATA(node) == NULL)) { DATA(node) = data; result = ISC_R_SUCCESS; } return (result); } /* * Find the node for "name" in the tree of trees. */ isc_result_t dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname, dns_rbtnode_t **node, dns_rbtnodechain_t *chain, unsigned int options, dns_rbtfindcallback_t callback, void *callback_arg) { dns_rbtnode_t *current, *last_compared, *current_root; dns_rbtnodechain_t localchain; dns_name_t *search_name, current_name, *callback_name; dns_fixedname_t fixedcallbackname, fixedsearchname; dns_namereln_t compared; isc_result_t result, saved_result; unsigned int common_labels; unsigned int hlabels = 0; int order; REQUIRE(VALID_RBT(rbt)); REQUIRE(dns_name_isabsolute(name)); REQUIRE(node != NULL && *node == NULL); REQUIRE((options & (DNS_RBTFIND_NOEXACT | DNS_RBTFIND_NOPREDECESSOR)) != (DNS_RBTFIND_NOEXACT | DNS_RBTFIND_NOPREDECESSOR)); /* * If there is a chain it needs to appear to be in a sane state, * otherwise a chain is still needed to generate foundname and * callback_name. */ if (chain == NULL) { options |= DNS_RBTFIND_NOPREDECESSOR; chain = &localchain; dns_rbtnodechain_init(chain, rbt->mctx); } else dns_rbtnodechain_reset(chain); if (rbt->root == NULL) return (ISC_R_NOTFOUND); /* * Appease GCC about variables it incorrectly thinks are * possibly used uninitialized. */ compared = dns_namereln_none; last_compared = NULL; order = 0; dns_fixedname_init(&fixedcallbackname); callback_name = dns_fixedname_name(&fixedcallbackname); /* * search_name is the name segment being sought in each tree level. * By using a fixedname, the search_name will definitely have offsets * for use by any splitting. * By using dns_name_clone, no name data should be copied thanks to * the lack of bitstring labels. */ dns_fixedname_init(&fixedsearchname); search_name = dns_fixedname_name(&fixedsearchname); dns_name_clone(name, search_name); dns_name_init(¤t_name, NULL); saved_result = ISC_R_SUCCESS; current = rbt->root; current_root = rbt->root; while (current != NULL) { NODENAME(current, ¤t_name); compared = dns_name_fullcompare(search_name, ¤t_name, &order, &common_labels); /* * last_compared is used as a shortcut to start (or * continue rather) finding the stop-node of the search * when hashing was used (see much below in this * function). */ last_compared = current; if (compared == dns_namereln_equal) break; if (compared == dns_namereln_none) { #ifdef DNS_RBT_USEHASH /* * Here, current is pointing at a subtree root * node. We try to find a matching node using * the hashtable. We can get one of 3 results * here: (a) we locate the matching node, (b) we * find a node to which the current node has a * subdomain relation, (c) we fail to find (a) * or (b). */ dns_name_t hash_name; dns_rbtnode_t *hnode; dns_rbtnode_t *up_current; unsigned int nlabels; unsigned int tlabels = 1; unsigned int hash; /* * If there is no hash table, hashing can't be done. */ if (rbt->hashtable == NULL) goto nohash; /* * The case of current != current_root, that * means a left or right pointer was followed, * only happens when the algorithm fell through to * the traditional binary search because of a * bitstring label. Since we dropped the bitstring * support, this should not happen. */ INSIST(current == current_root); nlabels = dns_name_countlabels(search_name); /* * current_root is the root of the current level, so * it's parent is the same as it's "up" pointer. */ up_current = PARENT(current_root); dns_name_init(&hash_name, NULL); hashagain: /* * Compute the hash over the full absolute * name. Look for the smallest suffix match at * this tree level (hlevel), and then at every * iteration, look for the next smallest suffix * match (add another subdomain label to the * absolute name being hashed). */ dns_name_getlabelsequence(name, nlabels - tlabels, hlabels + tlabels, &hash_name); hash = dns_name_fullhash(&hash_name, ISC_FALSE); dns_name_getlabelsequence(search_name, nlabels - tlabels, tlabels, &hash_name); /* * Walk all the nodes in the hash bucket pointed * by the computed hash value. */ for (hnode = rbt->hashtable[hash % rbt->hashsize]; hnode != NULL; hnode = hnode->hashnext) { dns_name_t hnode_name; if (hash != HASHVAL(hnode)) continue; /* * This checks that the hashed label * sequence being looked up is at the * same tree level, so that we don't * match a labelsequence from some other * subdomain. */ if (get_upper_node(hnode) != up_current) continue; dns_name_init(&hnode_name, NULL); NODENAME(hnode, &hnode_name); if (dns_name_equal(&hnode_name, &hash_name)) break; } if (hnode != NULL) { current = hnode; /* * This is an optimization. If hashing found * the right node, the next call to * dns_name_fullcompare() would obviously * return _equal or _subdomain. Determine * which of those would be the case by * checking if the full name was hashed. Then * make it look like dns_name_fullcompare * was called and jump to the right place. */ if (tlabels == nlabels) { compared = dns_namereln_equal; break; } else { common_labels = tlabels; compared = dns_namereln_subdomain; goto subdomain; } } if (tlabels++ < nlabels) goto hashagain; /* * All of the labels have been tried against the hash * table. Since we dropped the support of bitstring * labels, the name isn't in the table. */ current = NULL; continue; nohash: #endif /* DNS_RBT_USEHASH */ /* * Standard binary search tree movement. */ if (order < 0) current = LEFT(current); else current = RIGHT(current); } else { /* * The names have some common suffix labels. * * If the number in common are equal in length to * the current node's name length, then follow the * down pointer and search in the new tree. */ if (compared == dns_namereln_subdomain) { #ifdef DNS_RBT_USEHASH subdomain: #endif /* * Whack off the current node's common parts * for the name to search in the next level. */ dns_name_split(search_name, common_labels, search_name, NULL); hlabels += common_labels; /* * This might be the closest enclosing name. */ if (DATA(current) != NULL || (options & DNS_RBTFIND_EMPTYDATA) != 0) *node = current; /* * Point the chain to the next level. This * needs to be done before 'current' is pointed * there because the callback in the next * block of code needs the current 'current', * but in the event the callback requests that * the search be stopped then the * DNS_R_PARTIALMATCH code at the end of this * function needs the chain pointed to the * next level. */ ADD_LEVEL(chain, current); /* * The caller may want to interrupt the * downward search when certain special nodes * are traversed. If this is a special node, * the callback is used to learn what the * caller wants to do. */ if (callback != NULL && FINDCALLBACK(current)) { result = chain_name(chain, callback_name, ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_rbtnodechain_reset(chain); return (result); } result = (callback)(current, callback_name, callback_arg); if (result != DNS_R_CONTINUE) { saved_result = result; /* * Treat this node as if it * had no down pointer. */ current = NULL; break; } } /* * Finally, head to the next tree level. */ current = DOWN(current); current_root = current; } else { /* * Though there are labels in common, the * entire name at this node is not common * with the search name so the search * name does not exist in the tree. */ INSIST(compared == dns_namereln_commonancestor || compared == dns_namereln_contains); current = NULL; } } } /* * If current is not NULL, NOEXACT is not disallowing exact matches, * and either the node has data or an empty node is ok, return * ISC_R_SUCCESS to indicate an exact match. */ if (current != NULL && (options & DNS_RBTFIND_NOEXACT) == 0 && (DATA(current) != NULL || (options & DNS_RBTFIND_EMPTYDATA) != 0)) { /* * Found an exact match. */ chain->end = current; chain->level_matches = chain->level_count; if (foundname != NULL) result = chain_name(chain, foundname, ISC_TRUE); else result = ISC_R_SUCCESS; if (result == ISC_R_SUCCESS) { *node = current; result = saved_result; } else *node = NULL; } else { /* * Did not find an exact match (or did not want one). */ if (*node != NULL) { /* * ... but found a partially matching superdomain. * Unwind the chain to the partial match node * to set level_matches to the level above the node, * and then to derive the name. * * chain->level_count is guaranteed to be at least 1 * here because by definition of finding a superdomain, * the chain is pointed to at least the first subtree. */ chain->level_matches = chain->level_count - 1; while (chain->levels[chain->level_matches] != *node) { INSIST(chain->level_matches > 0); chain->level_matches--; } if (foundname != NULL) { unsigned int saved_count = chain->level_count; chain->level_count = chain->level_matches + 1; result = chain_name(chain, foundname, ISC_FALSE); chain->level_count = saved_count; } else result = ISC_R_SUCCESS; if (result == ISC_R_SUCCESS) result = DNS_R_PARTIALMATCH; } else result = ISC_R_NOTFOUND; if (current != NULL) { /* * There was an exact match but either * DNS_RBTFIND_NOEXACT was set, or * DNS_RBTFIND_EMPTYDATA was set and the node had no * data. A policy decision was made to set the * chain to the exact match, but this is subject * to change if it becomes apparent that something * else would be more useful. It is important that * this case is handled here, because the predecessor * setting code below assumes the match was not exact. */ INSIST(((options & DNS_RBTFIND_NOEXACT) != 0) || ((options & DNS_RBTFIND_EMPTYDATA) == 0 && DATA(current) == NULL)); chain->end = current; } else if ((options & DNS_RBTFIND_NOPREDECESSOR) != 0) { /* * Ensure the chain points nowhere. */ chain->end = NULL; } else { /* * Since there was no exact match, the chain argument * needs to be pointed at the DNSSEC predecessor of * the search name. */ if (compared == dns_namereln_subdomain) { /* * Attempted to follow a down pointer that was * NULL, which means the searched for name was * a subdomain of a terminal name in the tree. * Since there are no existing subdomains to * order against, the terminal name is the * predecessor. */ INSIST(chain->level_count > 0); INSIST(chain->level_matches < chain->level_count); chain->end = chain->levels[--chain->level_count]; } else { isc_result_t result2; /* * Point current to the node that stopped * the search. * * With the hashing modification that has been * added to the algorithm, the stop node of a * standard binary search is not known. So it * has to be found. There is probably a more * clever way of doing this. * * The assignment of current to NULL when * the relationship is *not* dns_namereln_none, * even though it later gets set to the same * last_compared anyway, is simply to not push * the while loop in one more level of * indentation. */ if (compared == dns_namereln_none) current = last_compared; else current = NULL; while (current != NULL) { NODENAME(current, ¤t_name); compared = dns_name_fullcompare( search_name, ¤t_name, &order, &common_labels); POST(compared); last_compared = current; /* * Standard binary search movement. */ if (order < 0) current = LEFT(current); else current = RIGHT(current); } current = last_compared; /* * Reached a point within a level tree that * positively indicates the name is not * present, but the stop node could be either * less than the desired name (order > 0) or * greater than the desired name (order < 0). * * If the stop node is less, it is not * necessarily the predecessor. If the stop * node has a down pointer, then the real * predecessor is at the end of a level below * (not necessarily the next level). * Move down levels until the rightmost node * does not have a down pointer. * * When the stop node is greater, it is * the successor. All the logic for finding * the predecessor is handily encapsulated * in dns_rbtnodechain_prev. In the event * that the search name is less than anything * else in the tree, the chain is reset. * XXX DCL What is the best way for the caller * to know that the search name has * no predecessor? */ if (order > 0) { if (DOWN(current) != NULL) { ADD_LEVEL(chain, current); result2 = move_chain_to_last(chain, DOWN(current)); if (result2 != ISC_R_SUCCESS) result = result2; } else /* * Ah, the pure and simple * case. The stop node is the * predecessor. */ chain->end = current; } else { INSIST(order < 0); chain->end = current; result2 = dns_rbtnodechain_prev(chain, NULL, NULL); if (result2 == ISC_R_SUCCESS || result2 == DNS_R_NEWORIGIN) ; /* Nothing. */ else if (result2 == ISC_R_NOMORE) /* * There is no predecessor. */ dns_rbtnodechain_reset(chain); else result = result2; } } } } ENSURE(*node == NULL || DNS_RBTNODE_VALID(*node)); return (result); } /* * Get the data pointer associated with 'name'. */ isc_result_t dns_rbt_findname(dns_rbt_t *rbt, dns_name_t *name, unsigned int options, dns_name_t *foundname, void **data) { dns_rbtnode_t *node = NULL; isc_result_t result; REQUIRE(data != NULL && *data == NULL); result = dns_rbt_findnode(rbt, name, foundname, &node, NULL, options, NULL, NULL); if (node != NULL && (DATA(node) != NULL || (options & DNS_RBTFIND_EMPTYDATA) != 0)) *data = DATA(node); else result = ISC_R_NOTFOUND; return (result); } /* * Delete a name from the tree of trees. */ isc_result_t dns_rbt_deletename(dns_rbt_t *rbt, dns_name_t *name, isc_boolean_t recurse) { dns_rbtnode_t *node = NULL; isc_result_t result; REQUIRE(VALID_RBT(rbt)); REQUIRE(dns_name_isabsolute(name)); /* * First, find the node. * * When searching, the name might not have an exact match: * consider a.b.a.com, b.b.a.com and c.b.a.com as the only * elements of a tree, which would make layer 1 a single * node tree of "b.a.com" and layer 2 a three node tree of * a, b, and c. Deleting a.com would find only a partial depth * match in the first layer. Should it be a requirement that * that the name to be deleted have data? For now, it is. * * ->dirty, ->locknum and ->references are ignored; they are * solely the province of rbtdb.c. */ result = dns_rbt_findnode(rbt, name, NULL, &node, NULL, DNS_RBTFIND_NOOPTIONS, NULL, NULL); if (result == ISC_R_SUCCESS) { if (DATA(node) != NULL) result = dns_rbt_deletenode(rbt, node, recurse); else result = ISC_R_NOTFOUND; } else if (result == DNS_R_PARTIALMATCH) result = ISC_R_NOTFOUND; return (result); } /* * Remove a node from the tree of trees. * * NOTE WELL: deletion is *not* symmetric with addition; that is, reversing * a sequence of additions to be deletions will not generally get the * tree back to the state it started in. For example, if the addition * of "b.c" caused the node "a.b.c" to be split, pushing "a" to its own level, * then the subsequent deletion of "b.c" will not cause "a" to be pulled up, * restoring "a.b.c". The RBT *used* to do this kind of rejoining, but it * turned out to be a bad idea because it could corrupt an active nodechain * that had "b.c" as one of its levels -- and the RBT has no idea what * nodechains are in use by callers, so it can't even *try* to helpfully * fix them up (which would probably be doomed to failure anyway). * * Similarly, it is possible to leave the tree in a state where a supposedly * deleted node still exists. The first case of this is obvious; take * the tree which has "b.c" on one level, pointing to "a". Now deleted "b.c". * It was just established in the previous paragraph why we can't pull "a" * back up to its parent level. But what happens when "a" then gets deleted? * "b.c" is left hanging around without data or children. This condition * is actually pretty easy to detect, but ... should it really be removed? * Is a chain pointing to it? An iterator? Who knows! (Note that the * references structure member cannot be looked at because it is private to * rbtdb.) This is ugly and makes me unhappy, but after hours of trying to * make it more aesthetically proper and getting nowhere, this is the way it * is going to stay until such time as it proves to be a *real* problem. * * Finally, for reference, note that the original routine that did node * joining was called join_nodes(). It has been excised, living now only * in the CVS history, but comments have been left behind that point to it just * in case someone wants to muck with this some more. * * The one positive aspect of all of this is that joining used to have a * case where it might fail. Without trying to join, now this function always * succeeds. It still returns isc_result_t, though, so the API wouldn't change. */ isc_result_t dns_rbt_deletenode(dns_rbt_t *rbt, dns_rbtnode_t *node, isc_boolean_t recurse) { dns_rbtnode_t *parent; REQUIRE(VALID_RBT(rbt)); REQUIRE(DNS_RBTNODE_VALID(node)); INSIST(rbt->nodecount != 0); if (DOWN(node) != NULL) { if (recurse) RUNTIME_CHECK(deletetree(rbt, DOWN(node)) == ISC_R_SUCCESS); else { if (DATA(node) != NULL && rbt->data_deleter != NULL) rbt->data_deleter(DATA(node), rbt->deleter_arg); DATA(node) = NULL; /* * Since there is at least one node below this one and * no recursion was requested, the deletion is * complete. The down node from this node might be all * by itself on a single level, so join_nodes() could * be used to collapse the tree (with all the caveats * of the comment at the start of this function). */ return (ISC_R_SUCCESS); } } /* * Note the node that points to the level of the node that is being * deleted. If the deleted node is the top level, parent will be set * to NULL. */ parent = get_upper_node(node); /* * This node now has no down pointer (either because it didn't * have one to start, or because it was recursively removed). * So now the node needs to be removed from this level. */ deletefromlevel(node, parent == NULL ? &rbt->root : &DOWN(parent)); if (DATA(node) != NULL && rbt->data_deleter != NULL) rbt->data_deleter(DATA(node), rbt->deleter_arg); unhash_node(rbt, node); #if DNS_RBT_USEMAGIC node->magic = 0; #endif dns_rbtnode_refdestroy(node); freenode(rbt, &node); /* * There are now two special cases that can exist that would * not have existed if the tree had been created using only * the names that now exist in it. (This is all related to * join_nodes() as described in this function's introductory comment.) * Both cases exist when the deleted node's parent (the node * that pointed to the deleted node's level) is not null but * it has no data: parent != NULL && DATA(parent) == NULL. * * The first case is that the deleted node was the last on its level: * DOWN(parent) == NULL. This case can only exist if the parent was * previously deleted -- and so now, apparently, the parent should go * away. That can't be done though because there might be external * references to it, such as through a nodechain. * * The other case also involves a parent with no data, but with the * deleted node being the next-to-last node instead of the last: * LEFT(DOWN(parent)) == NULL && RIGHT(DOWN(parent)) == NULL. * Presumably now the remaining node on the level should be joined * with the parent, but it's already been described why that can't be * done. */ /* * This function never fails. */ return (ISC_R_SUCCESS); } void dns_rbt_namefromnode(dns_rbtnode_t *node, dns_name_t *name) { REQUIRE(DNS_RBTNODE_VALID(node)); REQUIRE(name != NULL); REQUIRE(name->offsets == NULL); NODENAME(node, name); } isc_result_t dns_rbt_fullnamefromnode(dns_rbtnode_t *node, dns_name_t *name) { dns_name_t current; isc_result_t result; REQUIRE(DNS_RBTNODE_VALID(node)); REQUIRE(name != NULL); REQUIRE(name->buffer != NULL); dns_name_init(¤t, NULL); dns_name_reset(name); do { INSIST(node != NULL); NODENAME(node, ¤t); result = dns_name_concatenate(name, ¤t, name, NULL); if (result != ISC_R_SUCCESS) break; node = get_upper_node(node); } while (! dns_name_isabsolute(name)); return (result); } char * dns_rbt_formatnodename(dns_rbtnode_t *node, char *printname, unsigned int size) { dns_fixedname_t fixedname; dns_name_t *name; isc_result_t result; REQUIRE(DNS_RBTNODE_VALID(node)); REQUIRE(printname != NULL); dns_fixedname_init(&fixedname); name = dns_fixedname_name(&fixedname); result = dns_rbt_fullnamefromnode(node, name); if (result == ISC_R_SUCCESS) dns_name_format(name, printname, size); else snprintf(printname, size, "", dns_result_totext(result)); return (printname); } static isc_result_t create_node(isc_mem_t *mctx, dns_name_t *name, dns_rbtnode_t **nodep) { dns_rbtnode_t *node; isc_region_t region; unsigned int labels; size_t nodelen; REQUIRE(name->offsets != NULL); dns_name_toregion(name, ®ion); labels = dns_name_countlabels(name); ENSURE(labels > 0); /* * Allocate space for the node structure, the name, and the offsets. */ nodelen = sizeof(dns_rbtnode_t) + region.length + labels + 1; node = (dns_rbtnode_t *)isc_mem_get(mctx, nodelen); if (node == NULL) return (ISC_R_NOMEMORY); memset(node, 0, nodelen); node->is_root = 0; PARENT(node) = NULL; RIGHT(node) = NULL; LEFT(node) = NULL; DOWN(node) = NULL; DATA(node) = NULL; node->is_mmapped = 0; node->down_is_relative = 0; node->left_is_relative = 0; node->right_is_relative = 0; node->parent_is_relative = 0; node->data_is_relative = 0; node->rpz = 0; #ifdef DNS_RBT_USEHASH HASHNEXT(node) = NULL; HASHVAL(node) = 0; #endif ISC_LINK_INIT(node, deadlink); LOCKNUM(node) = 0; WILD(node) = 0; DIRTY(node) = 0; dns_rbtnode_refinit(node, 0); node->find_callback = 0; node->nsec = DNS_RBT_NSEC_NORMAL; MAKE_BLACK(node); /* * The following is stored to make reconstructing a name from the * stored value in the node easy: the length of the name, the number * of labels, whether the name is absolute or not, the name itself, * and the name's offsets table. * * XXX RTH * The offsets table could be made smaller by eliminating the * first offset, which is always 0. This requires changes to * lib/dns/name.c. * * Note: OLDOFFSETLEN *must* be assigned *after* OLDNAMELEN is assigned * as it uses OLDNAMELEN. */ OLDNAMELEN(node) = NAMELEN(node) = region.length; OLDOFFSETLEN(node) = OFFSETLEN(node) = labels; ATTRS(node) = name->attributes; memmove(NAME(node), region.base, region.length); memmove(OFFSETS(node), name->offsets, labels); #if DNS_RBT_USEMAGIC node->magic = DNS_RBTNODE_MAGIC; #endif *nodep = node; return (ISC_R_SUCCESS); } #ifdef DNS_RBT_USEHASH static inline void hash_add_node(dns_rbt_t *rbt, dns_rbtnode_t *node, dns_name_t *name) { unsigned int hash; REQUIRE(name != NULL); HASHVAL(node) = dns_name_fullhash(name, ISC_FALSE); hash = HASHVAL(node) % rbt->hashsize; HASHNEXT(node) = rbt->hashtable[hash]; rbt->hashtable[hash] = node; } static isc_result_t inithash(dns_rbt_t *rbt) { unsigned int bytes; rbt->hashsize = RBT_HASH_SIZE; bytes = rbt->hashsize * sizeof(dns_rbtnode_t *); rbt->hashtable = isc_mem_get(rbt->mctx, bytes); if (rbt->hashtable == NULL) return (ISC_R_NOMEMORY); memset(rbt->hashtable, 0, bytes); return (ISC_R_SUCCESS); } static void rehash(dns_rbt_t *rbt, unsigned int newcount) { unsigned int oldsize; dns_rbtnode_t **oldtable; dns_rbtnode_t *node; unsigned int hash; unsigned int i; oldsize = rbt->hashsize; oldtable = rbt->hashtable; do { rbt->hashsize = rbt->hashsize * 2 + 1; } while (newcount >= (rbt->hashsize * 3)); rbt->hashtable = isc_mem_get(rbt->mctx, rbt->hashsize * sizeof(dns_rbtnode_t *)); if (rbt->hashtable == NULL) { rbt->hashtable = oldtable; rbt->hashsize = oldsize; return; } INSIST(rbt->hashsize > 0); for (i = 0; i < rbt->hashsize; i++) rbt->hashtable[i] = NULL; for (i = 0; i < oldsize; i++) { node = oldtable[i]; while (node != NULL) { hash = HASHVAL(node) % rbt->hashsize; oldtable[i] = HASHNEXT(node); HASHNEXT(node) = rbt->hashtable[hash]; rbt->hashtable[hash] = node; node = oldtable[i]; } } isc_mem_put(rbt->mctx, oldtable, oldsize * sizeof(dns_rbtnode_t *)); } static inline void hash_node(dns_rbt_t *rbt, dns_rbtnode_t *node, dns_name_t *name) { REQUIRE(DNS_RBTNODE_VALID(node)); if (rbt->nodecount >= (rbt->hashsize * 3)) rehash(rbt, rbt->nodecount); hash_add_node(rbt, node, name); } static inline void unhash_node(dns_rbt_t *rbt, dns_rbtnode_t *node) { unsigned int bucket; dns_rbtnode_t *bucket_node; REQUIRE(DNS_RBTNODE_VALID(node)); if (rbt->hashtable != NULL) { bucket = HASHVAL(node) % rbt->hashsize; bucket_node = rbt->hashtable[bucket]; if (bucket_node == node) rbt->hashtable[bucket] = HASHNEXT(node); else { while (HASHNEXT(bucket_node) != node) { INSIST(HASHNEXT(bucket_node) != NULL); bucket_node = HASHNEXT(bucket_node); } HASHNEXT(bucket_node) = HASHNEXT(node); } } } #endif /* DNS_RBT_USEHASH */ static inline void rotate_left(dns_rbtnode_t *node, dns_rbtnode_t **rootp) { dns_rbtnode_t *child; REQUIRE(DNS_RBTNODE_VALID(node)); REQUIRE(rootp != NULL); child = RIGHT(node); INSIST(child != NULL); RIGHT(node) = LEFT(child); if (LEFT(child) != NULL) PARENT(LEFT(child)) = node; LEFT(child) = node; PARENT(child) = PARENT(node); if (IS_ROOT(node)) { *rootp = child; child->is_root = 1; node->is_root = 0; } else { if (LEFT(PARENT(node)) == node) LEFT(PARENT(node)) = child; else RIGHT(PARENT(node)) = child; } PARENT(node) = child; } static inline void rotate_right(dns_rbtnode_t *node, dns_rbtnode_t **rootp) { dns_rbtnode_t *child; REQUIRE(DNS_RBTNODE_VALID(node)); REQUIRE(rootp != NULL); child = LEFT(node); INSIST(child != NULL); LEFT(node) = RIGHT(child); if (RIGHT(child) != NULL) PARENT(RIGHT(child)) = node; RIGHT(child) = node; PARENT(child) = PARENT(node); if (IS_ROOT(node)) { *rootp = child; child->is_root = 1; node->is_root = 0; } else { if (LEFT(PARENT(node)) == node) LEFT(PARENT(node)) = child; else RIGHT(PARENT(node)) = child; } PARENT(node) = child; } /* * This is the real workhorse of the insertion code, because it does the * true red/black tree on a single level. */ static void addonlevel(dns_rbtnode_t *node, dns_rbtnode_t *current, int order, dns_rbtnode_t **rootp) { dns_rbtnode_t *child, *root, *parent, *grandparent; dns_name_t add_name, current_name; dns_offsets_t add_offsets, current_offsets; REQUIRE(rootp != NULL); REQUIRE(DNS_RBTNODE_VALID(node) && LEFT(node) == NULL && RIGHT(node) == NULL); REQUIRE(current != NULL); root = *rootp; if (root == NULL) { /* * First node of a level. */ MAKE_BLACK(node); node->is_root = 1; PARENT(node) = current; *rootp = node; return; } child = root; POST(child); dns_name_init(&add_name, add_offsets); NODENAME(node, &add_name); dns_name_init(¤t_name, current_offsets); NODENAME(current, ¤t_name); if (order < 0) { INSIST(LEFT(current) == NULL); LEFT(current) = node; } else { INSIST(RIGHT(current) == NULL); RIGHT(current) = node; } INSIST(PARENT(node) == NULL); PARENT(node) = current; MAKE_RED(node); while (node != root && IS_RED(PARENT(node))) { /* * XXXDCL could do away with separate parent and grandparent * variables. They are vestiges of the days before parent * pointers. However, they make the code a little clearer. */ parent = PARENT(node); grandparent = PARENT(parent); if (parent == LEFT(grandparent)) { child = RIGHT(grandparent); if (child != NULL && IS_RED(child)) { MAKE_BLACK(parent); MAKE_BLACK(child); MAKE_RED(grandparent); node = grandparent; } else { if (node == RIGHT(parent)) { rotate_left(parent, &root); node = parent; parent = PARENT(node); grandparent = PARENT(parent); } MAKE_BLACK(parent); MAKE_RED(grandparent); rotate_right(grandparent, &root); } } else { child = LEFT(grandparent); if (child != NULL && IS_RED(child)) { MAKE_BLACK(parent); MAKE_BLACK(child); MAKE_RED(grandparent); node = grandparent; } else { if (node == LEFT(parent)) { rotate_right(parent, &root); node = parent; parent = PARENT(node); grandparent = PARENT(parent); } MAKE_BLACK(parent); MAKE_RED(grandparent); rotate_left(grandparent, &root); } } } MAKE_BLACK(root); ENSURE(IS_ROOT(root)); *rootp = root; return; } /* * This is the real workhorse of the deletion code, because it does the * true red/black tree on a single level. */ static void deletefromlevel(dns_rbtnode_t *delete, dns_rbtnode_t **rootp) { dns_rbtnode_t *child, *sibling, *parent; dns_rbtnode_t *successor; REQUIRE(delete != NULL); /* * Verify that the parent history is (apparently) correct. */ INSIST((IS_ROOT(delete) && *rootp == delete) || (! IS_ROOT(delete) && (LEFT(PARENT(delete)) == delete || RIGHT(PARENT(delete)) == delete))); child = NULL; if (LEFT(delete) == NULL) { if (RIGHT(delete) == NULL) { if (IS_ROOT(delete)) { /* * This is the only item in the tree. */ *rootp = NULL; return; } } else /* * This node has one child, on the right. */ child = RIGHT(delete); } else if (RIGHT(delete) == NULL) /* * This node has one child, on the left. */ child = LEFT(delete); else { dns_rbtnode_t holder, *tmp = &holder; /* * This node has two children, so it cannot be directly * deleted. Find its immediate in-order successor and * move it to this location, then do the deletion at the * old site of the successor. */ successor = RIGHT(delete); while (LEFT(successor) != NULL) successor = LEFT(successor); /* * The successor cannot possibly have a left child; * if there is any child, it is on the right. */ if (RIGHT(successor) != NULL) child = RIGHT(successor); /* * Swap the two nodes; it would be simpler to just replace * the value being deleted with that of the successor, * but this rigamarole is done so the caller has complete * control over the pointers (and memory allocation) of * all of nodes. If just the key value were removed from * the tree, the pointer to the node would be unchanged. */ /* * First, put the successor in the tree location of the * node to be deleted. Save its existing tree pointer * information, which will be needed when linking up * delete to the successor's old location. */ memmove(tmp, successor, sizeof(dns_rbtnode_t)); if (IS_ROOT(delete)) { *rootp = successor; successor->is_root = ISC_TRUE; delete->is_root = ISC_FALSE; } else if (LEFT(PARENT(delete)) == delete) LEFT(PARENT(delete)) = successor; else RIGHT(PARENT(delete)) = successor; PARENT(successor) = PARENT(delete); LEFT(successor) = LEFT(delete); RIGHT(successor) = RIGHT(delete); COLOR(successor) = COLOR(delete); if (LEFT(successor) != NULL) PARENT(LEFT(successor)) = successor; if (RIGHT(successor) != successor) PARENT(RIGHT(successor)) = successor; /* * Now relink the node to be deleted into the * successor's previous tree location. PARENT(tmp) * is the successor's original parent. */ INSIST(! IS_ROOT(delete)); if (PARENT(tmp) == delete) { /* * Node being deleted was successor's parent. */ RIGHT(successor) = delete; PARENT(delete) = successor; } else { LEFT(PARENT(tmp)) = delete; PARENT(delete) = PARENT(tmp); } /* * Original location of successor node has no left. */ LEFT(delete) = NULL; RIGHT(delete) = RIGHT(tmp); COLOR(delete) = COLOR(tmp); } /* * Remove the node by removing the links from its parent. */ if (! IS_ROOT(delete)) { if (LEFT(PARENT(delete)) == delete) LEFT(PARENT(delete)) = child; else RIGHT(PARENT(delete)) = child; if (child != NULL) PARENT(child) = PARENT(delete); } else { /* * This is the root being deleted, and at this point * it is known to have just one child. */ *rootp = child; child->is_root = 1; PARENT(child) = PARENT(delete); } /* * Fix color violations. */ if (IS_BLACK(delete)) { parent = PARENT(delete); while (child != *rootp && IS_BLACK(child)) { INSIST(child == NULL || ! IS_ROOT(child)); if (LEFT(parent) == child) { sibling = RIGHT(parent); if (IS_RED(sibling)) { MAKE_BLACK(sibling); MAKE_RED(parent); rotate_left(parent, rootp); sibling = RIGHT(parent); } INSIST(sibling != NULL); if (IS_BLACK(LEFT(sibling)) && IS_BLACK(RIGHT(sibling))) { MAKE_RED(sibling); child = parent; } else { if (IS_BLACK(RIGHT(sibling))) { MAKE_BLACK(LEFT(sibling)); MAKE_RED(sibling); rotate_right(sibling, rootp); sibling = RIGHT(parent); } COLOR(sibling) = COLOR(parent); MAKE_BLACK(parent); INSIST(RIGHT(sibling) != NULL); MAKE_BLACK(RIGHT(sibling)); rotate_left(parent, rootp); child = *rootp; } } else { /* * Child is parent's right child. * Everything is done the same as above, * except mirrored. */ sibling = LEFT(parent); if (IS_RED(sibling)) { MAKE_BLACK(sibling); MAKE_RED(parent); rotate_right(parent, rootp); sibling = LEFT(parent); } INSIST(sibling != NULL); if (IS_BLACK(LEFT(sibling)) && IS_BLACK(RIGHT(sibling))) { MAKE_RED(sibling); child = parent; } else { if (IS_BLACK(LEFT(sibling))) { MAKE_BLACK(RIGHT(sibling)); MAKE_RED(sibling); rotate_left(sibling, rootp); sibling = LEFT(parent); } COLOR(sibling) = COLOR(parent); MAKE_BLACK(parent); INSIST(LEFT(sibling) != NULL); MAKE_BLACK(LEFT(sibling)); rotate_right(parent, rootp); child = *rootp; } } parent = PARENT(child); } if (IS_RED(child)) MAKE_BLACK(child); } } /* * This should only be used on the root of a tree, because no color fixup * is done at all. * * NOTE: No root pointer maintenance is done, because the function is only * used for two cases: * + deleting everything DOWN from a node that is itself being deleted, and * + deleting the entire tree of trees from dns_rbt_destroy. * In each case, the root pointer is no longer relevant, so there * is no need for a root parameter to this function. * * If the function is ever intended to be used to delete something where * a pointer needs to be told that this tree no longer exists, * this function would need to adjusted accordingly. */ static isc_result_t deletetree(dns_rbt_t *rbt, dns_rbtnode_t *node) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(VALID_RBT(rbt)); if (node == NULL) return (result); if (LEFT(node) != NULL) { result = deletetree(rbt, LEFT(node)); if (result != ISC_R_SUCCESS) goto done; LEFT(node) = NULL; } if (RIGHT(node) != NULL) { result = deletetree(rbt, RIGHT(node)); if (result != ISC_R_SUCCESS) goto done; RIGHT(node) = NULL; } if (DOWN(node) != NULL) { result = deletetree(rbt, DOWN(node)); if (result != ISC_R_SUCCESS) goto done; DOWN(node) = NULL; } done: if (result != ISC_R_SUCCESS) return (result); if (DATA(node) != NULL && rbt->data_deleter != NULL) rbt->data_deleter(DATA(node), rbt->deleter_arg); unhash_node(rbt, node); #if DNS_RBT_USEMAGIC node->magic = 0; #endif freenode(rbt, &node); return (result); } static void freenode(dns_rbt_t *rbt, dns_rbtnode_t **nodep) { dns_rbtnode_t *node = *nodep; if (node->is_mmapped == 0) { isc_mem_put(rbt->mctx, node, NODE_SIZE(node)); } *nodep = NULL; rbt->nodecount--; } static void deletetreeflat(dns_rbt_t *rbt, unsigned int quantum, dns_rbtnode_t **nodep) { dns_rbtnode_t *parent; dns_rbtnode_t *node = *nodep; REQUIRE(VALID_RBT(rbt)); again: if (node == NULL) { *nodep = NULL; return; } traverse: if (LEFT(node) != NULL) { node = LEFT(node); goto traverse; } if (DOWN(node) != NULL) { node = DOWN(node); goto traverse; } if (DATA(node) != NULL && rbt->data_deleter != NULL) rbt->data_deleter(DATA(node), rbt->deleter_arg); /* * Note: we don't call unhash_node() here as we are destroying * the complete rbt tree. */ #if DNS_RBT_USEMAGIC node->magic = 0; #endif parent = PARENT(node); if (RIGHT(node) != NULL) PARENT(RIGHT(node)) = parent; if (parent != NULL) { if (LEFT(parent) == node) LEFT(parent) = RIGHT(node); else if (DOWN(parent) == node) DOWN(parent) = RIGHT(node); } else parent = RIGHT(node); freenode(rbt, &node); node = parent; if (quantum != 0 && --quantum == 0) { *nodep = node; return; } goto again; } static size_t getheight_helper(dns_rbtnode_t *node) { size_t dl, dr; size_t this_height, down_height; if (node == NULL) return (0); dl = getheight_helper(LEFT(node)); dr = getheight_helper(RIGHT(node)); this_height = ISC_MAX(dl + 1, dr + 1); down_height = getheight_helper(DOWN(node)); return (ISC_MAX(this_height, down_height)); } size_t dns__rbt_getheight(dns_rbt_t *rbt) { return (getheight_helper(rbt->root)); } static isc_boolean_t check_properties_helper(dns_rbtnode_t *node) { if (node == NULL) return (ISC_TRUE); if (IS_RED(node)) { /* Root nodes must be BLACK. */ if (IS_ROOT(node)) return (ISC_FALSE); /* Both children of RED nodes must be BLACK. */ if (IS_RED(LEFT(node)) || IS_RED(RIGHT(node))) return (ISC_FALSE); } /* If node is assigned to the down_ pointer of its parent, it is * a subtree root and must have the flag set. */ if (((!PARENT(node)) || (DOWN(PARENT(node)) == node)) && (!IS_ROOT(node))) { return (ISC_FALSE); } /* Repeat tests with this node's children. */ return (check_properties_helper(LEFT(node)) && check_properties_helper(RIGHT(node)) && check_properties_helper(DOWN(node))); } static isc_boolean_t check_black_distance_helper(dns_rbtnode_t *node, size_t *distance) { size_t dl, dr, dd; if (node == NULL) { *distance = 1; return (ISC_TRUE); } if (!check_black_distance_helper(LEFT(node), &dl)) return (ISC_FALSE); if (!check_black_distance_helper(RIGHT(node), &dr)) return (ISC_FALSE); if (!check_black_distance_helper(DOWN(node), &dd)) return (ISC_FALSE); /* Left and right side black node counts must match. */ if (dl != dr) return (ISC_FALSE); if (IS_BLACK(node)) dl++; *distance = dl; return (ISC_TRUE); } isc_boolean_t dns__rbt_checkproperties(dns_rbt_t *rbt) { size_t dd; if (!check_properties_helper(rbt->root)) return (ISC_FALSE); /* Path from a given node to all its leaves must contain the * same number of BLACK child nodes. This is done separately * here instead of inside check_properties_helper() as * it would take (n log n) complexity otherwise. */ return (check_black_distance_helper(rbt->root, &dd)); } static void dns_rbt_indent(FILE *f, int depth) { int i; fprintf(f, "%4d ", depth); for (i = 0; i < depth; i++) fprintf(f, "- "); } void dns_rbt_printnodeinfo(dns_rbtnode_t *n, FILE *f) { fprintf(f, "Node info for nodename: "); printnodename(n, ISC_TRUE, f); fprintf(f, "\n"); fprintf(f, "n = %p\n", n); fprintf(f, "Relative pointers: %s%s%s%s%s\n", (n->parent_is_relative == 1 ? " P" : ""), (n->right_is_relative == 1 ? " R" : ""), (n->left_is_relative == 1 ? " L" : ""), (n->down_is_relative == 1 ? " D" : ""), (n->data_is_relative == 1 ? " T" : "")); fprintf(f, "node lock address = %d\n", n->locknum); fprintf(f, "Parent: %p\n", n->parent); fprintf(f, "Right: %p\n", n->right); fprintf(f, "Left: %p\n", n->left); fprintf(f, "Down: %p\n", n->down); fprintf(f, "daTa: %p\n", n->data); } static void printnodename(dns_rbtnode_t *node, isc_boolean_t quoted, FILE *f) { isc_region_t r; dns_name_t name; char buffer[DNS_NAME_FORMATSIZE]; dns_offsets_t offsets; r.length = NAMELEN(node); r.base = NAME(node); dns_name_init(&name, offsets); dns_name_fromregion(&name, &r); dns_name_format(&name, buffer, sizeof(buffer)); if (quoted) fprintf(f, "\"%s\"", buffer); else fprintf(f, "%s", buffer); } static void print_text_helper(dns_rbtnode_t *root, dns_rbtnode_t *parent, int depth, const char *direction, void (*data_printer)(FILE *, void *), FILE *f) { dns_rbt_indent(f, depth); if (root != NULL) { printnodename(root, ISC_TRUE, f); fprintf(f, " (%s, %s", direction, IS_RED(root) ? "RED" : "BLACK"); if ((! IS_ROOT(root) && PARENT(root) != parent) || ( IS_ROOT(root) && depth > 0 && DOWN(PARENT(root)) != root)) { fprintf(f, " (BAD parent pointer! -> "); if (PARENT(root) != NULL) printnodename(PARENT(root), ISC_TRUE, f); else fprintf(f, "NULL"); fprintf(f, ")"); } fprintf(f, ")"); if (root->data != NULL && data_printer != NULL) { fprintf(f, " data@%p: ", root->data); data_printer(f, root->data); } fprintf(f, "\n"); depth++; if (IS_RED(root) && IS_RED(LEFT(root))) fprintf(f, "** Red/Red color violation on left\n"); print_text_helper(LEFT(root), root, depth, "left", data_printer, f); if (IS_RED(root) && IS_RED(RIGHT(root))) fprintf(f, "** Red/Red color violation on right\n"); print_text_helper(RIGHT(root), root, depth, "right", data_printer, f); print_text_helper(DOWN(root), NULL, depth, "down", data_printer, f); } else { fprintf(f, "NULL (%s)\n", direction); } } void dns_rbt_printtext(dns_rbt_t *rbt, void (*data_printer)(FILE *, void *), FILE *f) { REQUIRE(VALID_RBT(rbt)); print_text_helper(rbt->root, NULL, 0, "root", data_printer, f); } static int print_dot_helper(dns_rbtnode_t *node, unsigned int *nodecount, isc_boolean_t show_pointers, FILE *f) { unsigned int l, r, d; if (node == NULL) return (0); l = print_dot_helper(LEFT(node), nodecount, show_pointers, f); r = print_dot_helper(RIGHT(node), nodecount, show_pointers, f); d = print_dot_helper(DOWN(node), nodecount, show_pointers, f); *nodecount += 1; fprintf(f, "node%u[label = \" | ", *nodecount); printnodename(node, ISC_FALSE, f); fprintf(f, "|"); if (show_pointers) fprintf(f, "| n=%p| p=%p", node, PARENT(node)); fprintf(f, "\"] ["); if (IS_RED(node)) fprintf(f, "color=red"); else fprintf(f, "color=black"); /* XXXMUKS: verify that IS_ROOT() indicates subtree root and not * forest root. */ if (IS_ROOT(node)) fprintf(f, ",penwidth=3"); if (IS_EMPTY(node)) fprintf(f, ",style=filled,fillcolor=lightgrey"); fprintf(f, "];\n"); if (LEFT(node) != NULL) fprintf(f, "\"node%u\":f0 -> \"node%u\":f1;\n", *nodecount, l); if (DOWN(node) != NULL) fprintf(f, "\"node%u\":f1 -> \"node%u\":f1 [penwidth=5];\n", *nodecount, d); if (RIGHT(node) != NULL) fprintf(f, "\"node%u\":f2 -> \"node%u\":f1;\n", *nodecount, r); return (*nodecount); } void dns_rbt_printdot(dns_rbt_t *rbt, isc_boolean_t show_pointers, FILE *f) { unsigned int nodecount = 0; REQUIRE(VALID_RBT(rbt)); fprintf(f, "digraph g {\n"); fprintf(f, "node [shape = record,height=.1];\n"); print_dot_helper(rbt->root, &nodecount, show_pointers, f); fprintf(f, "}\n"); } /* * Chain Functions */ void dns_rbtnodechain_init(dns_rbtnodechain_t *chain, isc_mem_t *mctx) { REQUIRE(chain != NULL); /* * Initialize 'chain'. */ chain->mctx = mctx; chain->end = NULL; chain->level_count = 0; chain->level_matches = 0; memset(chain->levels, 0, sizeof(chain->levels)); chain->magic = CHAIN_MAGIC; } isc_result_t dns_rbtnodechain_current(dns_rbtnodechain_t *chain, dns_name_t *name, dns_name_t *origin, dns_rbtnode_t **node) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(VALID_CHAIN(chain)); if (node != NULL) *node = chain->end; if (chain->end == NULL) return (ISC_R_NOTFOUND); if (name != NULL) { NODENAME(chain->end, name); if (chain->level_count == 0) { /* * Names in the top level tree are all absolute. * Always make 'name' relative. */ INSIST(dns_name_isabsolute(name)); /* * This is cheaper than dns_name_getlabelsequence(). */ name->labels--; name->length--; name->attributes &= ~DNS_NAMEATTR_ABSOLUTE; } } if (origin != NULL) { if (chain->level_count > 0) result = chain_name(chain, origin, ISC_FALSE); else result = dns_name_copy(dns_rootname, origin, NULL); } return (result); } isc_result_t dns_rbtnodechain_prev(dns_rbtnodechain_t *chain, dns_name_t *name, dns_name_t *origin) { dns_rbtnode_t *current, *previous, *predecessor; isc_result_t result = ISC_R_SUCCESS; isc_boolean_t new_origin = ISC_FALSE; REQUIRE(VALID_CHAIN(chain) && chain->end != NULL); predecessor = NULL; current = chain->end; if (LEFT(current) != NULL) { /* * Moving left one then right as far as possible is the * previous node, at least for this level. */ current = LEFT(current); while (RIGHT(current) != NULL) current = RIGHT(current); predecessor = current; } else { /* * No left links, so move toward the root. If at any point on * the way there the link from parent to child is a right * link, then the parent is the previous node, at least * for this level. */ while (! IS_ROOT(current)) { previous = current; current = PARENT(current); if (RIGHT(current) == previous) { predecessor = current; break; } } } if (predecessor != NULL) { /* * Found a predecessor node in this level. It might not * really be the predecessor, however. */ if (DOWN(predecessor) != NULL) { /* * The predecessor is really down at least one level. * Go down and as far right as possible, and repeat * as long as the rightmost node has a down pointer. */ do { /* * XXX DCL Need to do something about origins * here. See whether to go down, and if so * whether it is truly what Bob calls a * new origin. */ ADD_LEVEL(chain, predecessor); predecessor = DOWN(predecessor); /* XXX DCL duplicated from above; clever * way to unduplicate? */ while (RIGHT(predecessor) != NULL) predecessor = RIGHT(predecessor); } while (DOWN(predecessor) != NULL); /* XXX DCL probably needs work on the concept */ if (origin != NULL) new_origin = ISC_TRUE; } } else if (chain->level_count > 0) { /* * Dang, didn't find a predecessor in this level. * Got to the root of this level without having traversed * any right links. Ascend the tree one level; the * node that points to this tree is the predecessor. */ INSIST(chain->level_count > 0 && IS_ROOT(current)); predecessor = chain->levels[--chain->level_count]; /* XXX DCL probably needs work on the concept */ /* * Don't declare an origin change when the new origin is "." * at the top level tree, because "." is declared as the origin * for the second level tree. */ if (origin != NULL && (chain->level_count > 0 || OFFSETLEN(predecessor) > 1)) new_origin = ISC_TRUE; } if (predecessor != NULL) { chain->end = predecessor; if (new_origin) { result = dns_rbtnodechain_current(chain, name, origin, NULL); if (result == ISC_R_SUCCESS) result = DNS_R_NEWORIGIN; } else result = dns_rbtnodechain_current(chain, name, NULL, NULL); } else result = ISC_R_NOMORE; return (result); } isc_result_t dns_rbtnodechain_down(dns_rbtnodechain_t *chain, dns_name_t *name, dns_name_t *origin) { dns_rbtnode_t *current, *successor; isc_result_t result = ISC_R_SUCCESS; isc_boolean_t new_origin = ISC_FALSE; REQUIRE(VALID_CHAIN(chain) && chain->end != NULL); successor = NULL; current = chain->end; if (DOWN(current) != NULL) { /* * Don't declare an origin change when the new origin is "." * at the second level tree, because "." is already declared * as the origin for the top level tree. */ if (chain->level_count > 0 || OFFSETLEN(current) > 1) new_origin = ISC_TRUE; ADD_LEVEL(chain, current); current = DOWN(current); while (LEFT(current) != NULL) current = LEFT(current); successor = current; } if (successor != NULL) { chain->end = successor; /* * It is not necessary to use dns_rbtnodechain_current like * the other functions because this function will never * find a node in the topmost level. This is because the * root level will never be more than one name, and everything * in the megatree is a successor to that node, down at * the second level or below. */ if (name != NULL) NODENAME(chain->end, name); if (new_origin) { if (origin != NULL) result = chain_name(chain, origin, ISC_FALSE); if (result == ISC_R_SUCCESS) result = DNS_R_NEWORIGIN; } else result = ISC_R_SUCCESS; } else result = ISC_R_NOMORE; return (result); } isc_result_t dns_rbtnodechain_nextflat(dns_rbtnodechain_t *chain, dns_name_t *name) { dns_rbtnode_t *current, *previous, *successor; isc_result_t result = ISC_R_SUCCESS; REQUIRE(VALID_CHAIN(chain) && chain->end != NULL); successor = NULL; current = chain->end; if (RIGHT(current) == NULL) { while (! IS_ROOT(current)) { previous = current; current = PARENT(current); if (LEFT(current) == previous) { successor = current; break; } } } else { current = RIGHT(current); while (LEFT(current) != NULL) current = LEFT(current); successor = current; } if (successor != NULL) { chain->end = successor; if (name != NULL) NODENAME(chain->end, name); result = ISC_R_SUCCESS; } else result = ISC_R_NOMORE; return (result); } isc_result_t dns_rbtnodechain_next(dns_rbtnodechain_t *chain, dns_name_t *name, dns_name_t *origin) { dns_rbtnode_t *current, *previous, *successor; isc_result_t result = ISC_R_SUCCESS; isc_boolean_t new_origin = ISC_FALSE; REQUIRE(VALID_CHAIN(chain) && chain->end != NULL); successor = NULL; current = chain->end; /* * If there is a level below this node, the next node is the leftmost * node of the next level. */ if (DOWN(current) != NULL) { /* * Don't declare an origin change when the new origin is "." * at the second level tree, because "." is already declared * as the origin for the top level tree. */ if (chain->level_count > 0 || OFFSETLEN(current) > 1) new_origin = ISC_TRUE; ADD_LEVEL(chain, current); current = DOWN(current); while (LEFT(current) != NULL) current = LEFT(current); successor = current; } else if (RIGHT(current) == NULL) { /* * The successor is up, either in this level or a previous one. * Head back toward the root of the tree, looking for any path * that was via a left link; the successor is the node that has * that left link. In the event the root of the level is * reached without having traversed any left links, ascend one * level and look for either a right link off the point of * ascent, or search for a left link upward again, repeating * ascends until either case is true. */ do { while (! IS_ROOT(current)) { previous = current; current = PARENT(current); if (LEFT(current) == previous) { successor = current; break; } } if (successor == NULL) { /* * Reached the root without having traversed * any left pointers, so this level is done. */ if (chain->level_count == 0) break; current = chain->levels[--chain->level_count]; new_origin = ISC_TRUE; if (RIGHT(current) != NULL) break; } } while (successor == NULL); } if (successor == NULL && RIGHT(current) != NULL) { current = RIGHT(current); while (LEFT(current) != NULL) current = LEFT(current); successor = current; } if (successor != NULL) { chain->end = successor; /* * It is not necessary to use dns_rbtnodechain_current like * the other functions because this function will never * find a node in the topmost level. This is because the * root level will never be more than one name, and everything * in the megatree is a successor to that node, down at * the second level or below. */ if (name != NULL) NODENAME(chain->end, name); if (new_origin) { if (origin != NULL) result = chain_name(chain, origin, ISC_FALSE); if (result == ISC_R_SUCCESS) result = DNS_R_NEWORIGIN; } else result = ISC_R_SUCCESS; } else result = ISC_R_NOMORE; return (result); } isc_result_t dns_rbtnodechain_first(dns_rbtnodechain_t *chain, dns_rbt_t *rbt, dns_name_t *name, dns_name_t *origin) { isc_result_t result; REQUIRE(VALID_RBT(rbt)); REQUIRE(VALID_CHAIN(chain)); dns_rbtnodechain_reset(chain); chain->end = rbt->root; result = dns_rbtnodechain_current(chain, name, origin, NULL); if (result == ISC_R_SUCCESS) result = DNS_R_NEWORIGIN; return (result); } isc_result_t dns_rbtnodechain_last(dns_rbtnodechain_t *chain, dns_rbt_t *rbt, dns_name_t *name, dns_name_t *origin) { isc_result_t result; REQUIRE(VALID_RBT(rbt)); REQUIRE(VALID_CHAIN(chain)); dns_rbtnodechain_reset(chain); result = move_chain_to_last(chain, rbt->root); if (result != ISC_R_SUCCESS) return (result); result = dns_rbtnodechain_current(chain, name, origin, NULL); if (result == ISC_R_SUCCESS) result = DNS_R_NEWORIGIN; return (result); } void dns_rbtnodechain_reset(dns_rbtnodechain_t *chain) { REQUIRE(VALID_CHAIN(chain)); /* * Free any dynamic storage associated with 'chain', and then * reinitialize 'chain'. */ chain->end = NULL; chain->level_count = 0; chain->level_matches = 0; } void dns_rbtnodechain_invalidate(dns_rbtnodechain_t *chain) { /* * Free any dynamic storage associated with 'chain', and then * invalidate 'chain'. */ dns_rbtnodechain_reset(chain); chain->magic = 0; } /* XXXMUKS: * * - worth removing inline as static functions are inlined automatically * where suitable by modern compilers. * - bump the size of dns_rbt.nodecount to size_t. * - the dumpfile header also contains a nodecount that is unsigned * int. If large files (> 2^32 nodes) are to be supported, the * allocation for this field should be increased. */ bind9-9.10.3.dfsg.P4/lib/dns/dlz.c0000644000470500017500000004141112664710322015661 0ustar lamontlamont/* * Portions Copyright (C) 2005, 2007, 2009-2013, 2015 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all * copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE * USE OR PERFORMANCE OF THIS SOFTWARE. * * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was * conceived and contributed by Rob Butler. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all * copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * ROB BUTLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE * USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ /*** *** Imports ***/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /*** *** Supported DLZ DB Implementations Registry ***/ static ISC_LIST(dns_dlzimplementation_t) dlz_implementations; static isc_rwlock_t dlz_implock; static isc_once_t once = ISC_ONCE_INIT; static void dlz_initialize(void) { RUNTIME_CHECK(isc_rwlock_init(&dlz_implock, 0, 0) == ISC_R_SUCCESS); ISC_LIST_INIT(dlz_implementations); } /*% * Searches the dlz_implementations list for a driver matching name. */ static inline dns_dlzimplementation_t * dlz_impfind(const char *name) { dns_dlzimplementation_t *imp; for (imp = ISC_LIST_HEAD(dlz_implementations); imp != NULL; imp = ISC_LIST_NEXT(imp, link)) if (strcasecmp(name, imp->name) == 0) return (imp); return (NULL); } /*** *** Basic DLZ Methods ***/ isc_result_t dns_dlzallowzonexfr(dns_view_t *view, dns_name_t *name, isc_sockaddr_t *clientaddr, dns_db_t **dbp) { isc_result_t result = ISC_R_NOTFOUND; dns_dlzallowzonexfr_t allowzonexfr; dns_dlzdb_t *dlzdb; /* * Performs checks to make sure data is as we expect it to be. */ REQUIRE(name != NULL); REQUIRE(dbp != NULL && *dbp == NULL); /* * Find a driver in which the zone exists and transfer is supported */ for (dlzdb = ISC_LIST_HEAD(view->dlz_searched); dlzdb != NULL; dlzdb = ISC_LIST_NEXT(dlzdb, link)) { REQUIRE(DNS_DLZ_VALID(dlzdb)); allowzonexfr = dlzdb->implementation->methods->allowzonexfr; result = (*allowzonexfr)(dlzdb->implementation->driverarg, dlzdb->dbdata, dlzdb->mctx, view->rdclass, name, clientaddr, dbp); /* * if ISC_R_NOPERM, we found the right database but * the zone may not transfer. */ if (result == ISC_R_SUCCESS || result == ISC_R_NOPERM) return (result); } if (result == ISC_R_NOTIMPLEMENTED) result = ISC_R_NOTFOUND; return (result); } isc_result_t dns_dlzcreate(isc_mem_t *mctx, const char *dlzname, const char *drivername, unsigned int argc, char *argv[], dns_dlzdb_t **dbp) { dns_dlzimplementation_t *impinfo; isc_result_t result; dns_dlzdb_t *db = NULL; /* * initialize the dlz_implementations list, this is guaranteed * to only really happen once. */ RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS); /* * Performs checks to make sure data is as we expect it to be. */ REQUIRE(dbp != NULL && *dbp == NULL); REQUIRE(dlzname != NULL); REQUIRE(drivername != NULL); REQUIRE(mctx != NULL); /* write log message */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_INFO, "Loading '%s' using driver %s", dlzname, drivername); /* lock the dlz_implementations list so we can search it. */ RWLOCK(&dlz_implock, isc_rwlocktype_read); /* search for the driver implementation */ impinfo = dlz_impfind(drivername); if (impinfo == NULL) { RWUNLOCK(&dlz_implock, isc_rwlocktype_read); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "unsupported DLZ database driver '%s'." " %s not loaded.", drivername, dlzname); return (ISC_R_NOTFOUND); } /* Allocate memory to hold the DLZ database driver */ db = isc_mem_get(mctx, sizeof(dns_dlzdb_t)); if (db == NULL) { RWUNLOCK(&dlz_implock, isc_rwlocktype_read); return (ISC_R_NOMEMORY); } /* Make sure memory region is set to all 0's */ memset(db, 0, sizeof(dns_dlzdb_t)); ISC_LINK_INIT(db, link); db->implementation = impinfo; if (dlzname != NULL) db->dlzname = isc_mem_strdup(mctx, dlzname); /* Create a new database using implementation 'drivername'. */ result = ((impinfo->methods->create)(mctx, dlzname, argc, argv, impinfo->driverarg, &db->dbdata)); /* mark the DLZ driver as valid */ if (result == ISC_R_SUCCESS) { RWUNLOCK(&dlz_implock, isc_rwlocktype_read); db->magic = DNS_DLZ_MAGIC; isc_mem_attach(mctx, &db->mctx); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), "DLZ driver loaded successfully."); *dbp = db; return (ISC_R_SUCCESS); } else { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "DLZ driver failed to load."); } /* impinfo->methods->create failed. */ RWUNLOCK(&dlz_implock, isc_rwlocktype_read); isc_mem_put(mctx, db, sizeof(dns_dlzdb_t)); return (result); } void dns_dlzdestroy(dns_dlzdb_t **dbp) { dns_dlzdestroy_t destroy; dns_dlzdb_t *db; /* Write debugging message to log */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), "Unloading DLZ driver."); /* * Perform checks to make sure data is as we expect it to be. */ REQUIRE(dbp != NULL && DNS_DLZ_VALID(*dbp)); db = *dbp; *dbp = NULL; if (db->ssutable != NULL) dns_ssutable_detach(&db->ssutable); /* call the drivers destroy method */ if (db->dlzname != NULL) isc_mem_free(db->mctx, db->dlzname); destroy = db->implementation->methods->destroy; (*destroy)(db->implementation->driverarg, db->dbdata); /* return memory and detach */ isc_mem_putanddetach(&db->mctx, db, sizeof(dns_dlzdb_t)); } /*% * Registers a DLZ driver. This basically just adds the dlz * driver to the list of available drivers in the dlz_implementations list. */ isc_result_t dns_dlzregister(const char *drivername, const dns_dlzmethods_t *methods, void *driverarg, isc_mem_t *mctx, dns_dlzimplementation_t **dlzimp) { dns_dlzimplementation_t *dlz_imp; /* Write debugging message to log */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), "Registering DLZ driver '%s'", drivername); /* * Performs checks to make sure data is as we expect it to be. */ REQUIRE(drivername != NULL); REQUIRE(methods != NULL); REQUIRE(methods->create != NULL); REQUIRE(methods->destroy != NULL); REQUIRE(methods->findzone != NULL); REQUIRE(mctx != NULL); REQUIRE(dlzimp != NULL && *dlzimp == NULL); /* * initialize the dlz_implementations list, this is guaranteed * to only really happen once. */ RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS); /* lock the dlz_implementations list so we can modify it. */ RWLOCK(&dlz_implock, isc_rwlocktype_write); /* * check that another already registered driver isn't using * the same name */ dlz_imp = dlz_impfind(drivername); if (dlz_imp != NULL) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), "DLZ Driver '%s' already registered", drivername); RWUNLOCK(&dlz_implock, isc_rwlocktype_write); return (ISC_R_EXISTS); } /* * Allocate memory for a dlz_implementation object. Error if * we cannot. */ dlz_imp = isc_mem_get(mctx, sizeof(dns_dlzimplementation_t)); if (dlz_imp == NULL) { RWUNLOCK(&dlz_implock, isc_rwlocktype_write); return (ISC_R_NOMEMORY); } /* Make sure memory region is set to all 0's */ memset(dlz_imp, 0, sizeof(dns_dlzimplementation_t)); /* Store the data passed into this method */ dlz_imp->name = drivername; dlz_imp->methods = methods; dlz_imp->mctx = NULL; dlz_imp->driverarg = driverarg; /* attach the new dlz_implementation object to a memory context */ isc_mem_attach(mctx, &dlz_imp->mctx); /* * prepare the dlz_implementation object to be put in a list, * and append it to the list */ ISC_LINK_INIT(dlz_imp, link); ISC_LIST_APPEND(dlz_implementations, dlz_imp, link); /* Unlock the dlz_implementations list. */ RWUNLOCK(&dlz_implock, isc_rwlocktype_write); /* Pass back the dlz_implementation that we created. */ *dlzimp = dlz_imp; return (ISC_R_SUCCESS); } /*% * Helper function for dns_dlzstrtoargv(). * Pardon the gratuitous recursion. */ static isc_result_t dns_dlzstrtoargvsub(isc_mem_t *mctx, char *s, unsigned int *argcp, char ***argvp, unsigned int n) { isc_result_t result; restart: /* Discard leading whitespace. */ while (*s == ' ' || *s == '\t') s++; if (*s == '\0') { /* We have reached the end of the string. */ *argcp = n; *argvp = isc_mem_get(mctx, n * sizeof(char *)); if (*argvp == NULL) return (ISC_R_NOMEMORY); } else { char *p = s; while (*p != ' ' && *p != '\t' && *p != '\0' && *p != '{') { if (*p == '\n') { *p = ' '; goto restart; } p++; } /* do "grouping", items between { and } are one arg */ if (*p == '{') { char *t = p; /* * shift all characters to left by 1 to get rid of '{' */ while (*t != '\0') { t++; *(t-1) = *t; } while (*p != '\0' && *p != '}') { p++; } /* get rid of '}' character */ if (*p == '}') { *p = '\0'; p++; } /* normal case, no "grouping" */ } else if (*p != '\0') *p++ = '\0'; result = dns_dlzstrtoargvsub(mctx, p, argcp, argvp, n + 1); if (result != ISC_R_SUCCESS) return (result); (*argvp)[n] = s; } return (ISC_R_SUCCESS); } /*% * Tokenize the string "s" into whitespace-separated words, * return the number of words in '*argcp' and an array * of pointers to the words in '*argvp'. The caller * must free the array using isc_mem_put(). The string * is modified in-place. */ isc_result_t dns_dlzstrtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp, char ***argvp) { return(dns_dlzstrtoargvsub(mctx, s, argcp, argvp, 0)); } /*% * Unregisters a DLZ driver. This basically just removes the dlz * driver from the list of available drivers in the dlz_implementations list. */ void dns_dlzunregister(dns_dlzimplementation_t **dlzimp) { dns_dlzimplementation_t *dlz_imp; isc_mem_t *mctx; /* Write debugging message to log */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), "Unregistering DLZ driver."); /* * Performs checks to make sure data is as we expect it to be. */ REQUIRE(dlzimp != NULL && *dlzimp != NULL); /* * initialize the dlz_implementations list, this is guaranteed * to only really happen once. */ RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS); dlz_imp = *dlzimp; /* lock the dlz_implementations list so we can modify it. */ RWLOCK(&dlz_implock, isc_rwlocktype_write); /* remove the dlz_implementation object from the list */ ISC_LIST_UNLINK(dlz_implementations, dlz_imp, link); mctx = dlz_imp->mctx; /* * Return the memory back to the available memory pool and * remove it from the memory context. */ isc_mem_put(mctx, dlz_imp, sizeof(dns_dlzimplementation_t)); isc_mem_detach(&mctx); /* Unlock the dlz_implementations list. */ RWUNLOCK(&dlz_implock, isc_rwlocktype_write); } /* * Create a writeable DLZ zone. This can be called by DLZ drivers * during configure() to create a zone that can be updated. The zone * type is set to dns_zone_dlz, which is equivalent to a master zone * * This function uses a callback setup in dns_dlzconfigure() to call * into the server zone code to setup the remaining pieces of server * specific functionality on the zone */ isc_result_t dns_dlz_writeablezone(dns_view_t *view, dns_dlzdb_t *dlzdb, const char *zone_name) { dns_zone_t *zone = NULL; dns_zone_t *dupzone = NULL; isc_result_t result; isc_buffer_t buffer; dns_fixedname_t fixorigin; dns_name_t *origin; REQUIRE(DNS_DLZ_VALID(dlzdb)); REQUIRE(dlzdb->configure_callback != NULL); isc_buffer_constinit(&buffer, zone_name, strlen(zone_name)); isc_buffer_add(&buffer, strlen(zone_name)); dns_fixedname_init(&fixorigin); result = dns_name_fromtext(dns_fixedname_name(&fixorigin), &buffer, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) goto cleanup; origin = dns_fixedname_name(&fixorigin); if (!dlzdb->search) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_WARNING, "DLZ %s has 'search no;', but attempted to " "register writeable zone %s.", dlzdb->dlzname, zone_name); result = ISC_R_SUCCESS; goto cleanup; } /* See if the zone already exists */ result = dns_view_findzone(view, origin, &dupzone); if (result == ISC_R_SUCCESS) { dns_zone_detach(&dupzone); result = ISC_R_EXISTS; goto cleanup; } INSIST(dupzone == NULL); /* Create it */ result = dns_zone_create(&zone, view->mctx); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_zone_setorigin(zone, origin); if (result != ISC_R_SUCCESS) goto cleanup; dns_zone_setview(zone, view); dns_zone_setadded(zone, ISC_TRUE); if (dlzdb->ssutable == NULL) { result = dns_ssutable_createdlz(dlzdb->mctx, &dlzdb->ssutable, dlzdb); if (result != ISC_R_SUCCESS) goto cleanup; } dns_zone_setssutable(zone, dlzdb->ssutable); result = dlzdb->configure_callback(view, dlzdb, zone); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_view_addzone(view, zone); cleanup: if (zone != NULL) dns_zone_detach(&zone); return (result); } /*% * Configure a DLZ driver. This is optional, and if supplied gives * the backend an opportunity to configure parameters related to DLZ. */ isc_result_t dns_dlzconfigure(dns_view_t *view, dns_dlzdb_t *dlzdb, dlzconfigure_callback_t callback) { dns_dlzimplementation_t *impl; isc_result_t result; REQUIRE(DNS_DLZ_VALID(dlzdb)); REQUIRE(dlzdb->implementation != NULL); impl = dlzdb->implementation; if (impl->methods->configure == NULL) return (ISC_R_SUCCESS); dlzdb->configure_callback = callback; result = impl->methods->configure(impl->driverarg, dlzdb->dbdata, view, dlzdb); return (result); } isc_boolean_t dns_dlz_ssumatch(dns_dlzdb_t *dlzdatabase, dns_name_t *signer, dns_name_t *name, isc_netaddr_t *tcpaddr, dns_rdatatype_t type, const dst_key_t *key) { dns_dlzimplementation_t *impl; isc_boolean_t r; REQUIRE(dlzdatabase != NULL); REQUIRE(dlzdatabase->implementation != NULL); REQUIRE(dlzdatabase->implementation->methods != NULL); impl = dlzdatabase->implementation; if (impl->methods->ssumatch == NULL) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_INFO, "No ssumatch method for DLZ database"); return (ISC_FALSE); } r = impl->methods->ssumatch(signer, name, tcpaddr, type, key, impl->driverarg, dlzdatabase->dbdata); return (r); } bind9-9.10.3.dfsg.P4/lib/dns/rbtdb.c0000644000470500017500000102577512664710322016205 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ /* * Principal Author: Bob Halley */ #include /* #define inline */ #ifdef HAVE_INTTYPES_H #include /* uintptr_t */ #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef WIN32 #include #else #define PROT_READ 0x01 #define PROT_WRITE 0x02 #define MAP_PRIVATE 0x0002 #define MAP_FAILED ((void *)-1) #endif #ifdef DNS_RBTDB_VERSION64 #include "rbtdb64.h" #else #include "rbtdb.h" #endif #ifdef DNS_RBTDB_VERSION64 #define RBTDB_MAGIC ISC_MAGIC('R', 'B', 'D', '8') #else #define RBTDB_MAGIC ISC_MAGIC('R', 'B', 'D', '4') #endif #define CHECK(op) \ do { result = (op); \ if (result != ISC_R_SUCCESS) goto failure; \ } while (0) /* * This is the map file header for RBTDB images. It is populated, and then * written, as the LAST thing done to the file. Writing this last (with * zeros in the header area initially) will ensure that the header is only * valid when the RBTDB image is also valid. */ typedef struct rbtdb_file_header rbtdb_file_header_t; /* Header length, always the same size regardless of structure size */ #define RBTDB_HEADER_LENGTH 1024 struct rbtdb_file_header { char version1[32]; isc_uint32_t ptrsize; unsigned int bigendian:1; isc_uint64_t tree; isc_uint64_t nsec; isc_uint64_t nsec3; char version2[32]; /* repeated; must match version1 */ }; /*% * Note that "impmagic" is not the first four bytes of the struct, so * ISC_MAGIC_VALID cannot be used. */ #define VALID_RBTDB(rbtdb) ((rbtdb) != NULL && \ (rbtdb)->common.impmagic == RBTDB_MAGIC) #ifdef DNS_RBTDB_VERSION64 typedef isc_uint64_t rbtdb_serial_t; /*% * Make casting easier in symbolic debuggers by using different names * for the 64 bit version. */ #define dns_rbtdb_t dns_rbtdb64_t #define rdatasetheader_t rdatasetheader64_t #define rbtdb_version_t rbtdb_version64_t #define once once64 #define FILE_VERSION FILE_VERSION64 #define init_count init_count64 #define cache_methods cache_methods64 #define dbiterator_methods dbiterator_methods64 #define rdataset_methods rdataset_methods64 #define rdatasetiter_methods rdatasetiter_methods64 #define zone_methods zone_methods64 #define acache_callback acache_callback64 #define acache_cancelentry acache_cancelentry64 #define activeempty activeempty64 #define activeemtpynode activeemtpynode64 #define add32 add64 #define add_changed add_changed64 #define add_empty_wildcards add_empty_wildcards64 #define add_wildcard_magic add_wildcard_magic64 #define addrdataset addrdataset64 #define allrdatasets allrdatasets64 #define attach attach64 #define attachnode attachnode64 #define attachversion attachversion64 #define beginload beginload64 #define bind_rdataset bind_rdataset64 #define cache_find cache_find64 #define cache_findrdataset cache_findrdataset64 #define cache_findzonecut cache_findzonecut64 #define cache_zonecut_callback cache_zonecut_callback64 #define check_stale_rdataset check_stale_rdataset64 #define cleanup_dead_nodes cleanup_dead_nodes64 #define cleanup_dead_nodes_callback cleanup_dead_nodes_callback64 #define closeversion closeversion64 #define createiterator createiterator64 #define currentversion currentversion64 #define dbiterator_current dbiterator_current64 #define dbiterator_destroy dbiterator_destroy64 #define dbiterator_first dbiterator_first64 #define dbiterator_last dbiterator_last64 #define dbiterator_next dbiterator_next64 #define dbiterator_origin dbiterator_origin64 #define dbiterator_pause dbiterator_pause64 #define dbiterator_prev dbiterator_prev64 #define dbiterator_seek dbiterator_seek64 #define decrement_reference decrement_reference64 #define delete_callback delete_callback64 #define delete_node delete_node64 #define deleterdataset deleterdataset64 #define deserialize32 deserialize64 #define detach detach64 #define detachnode detachnode64 #define dump dump64 #define endload endload64 #define expire_header expire_header64 #define expirenode expirenode64 #define find_closest_nsec find_closest_nsec64 #define find_coveringnsec find_coveringnsec64 #define find_deepest_zonecut find_deepest_zonecut64 #define findnode findnode64 #define findnodeintree findnodeintree64 #define findnsec3node findnsec3node64 #define flush_deletions flush_deletions64 #define free_acachearray free_acachearray64 #define free_noqname free_noqname64 #define free_rbtdb free_rbtdb64 #define free_rbtdb_callback free_rbtdb_callback64 #define free_rdataset free_rdataset64 #define getnsec3parameters getnsec3parameters64 #define getoriginnode getoriginnode64 #define getrrsetstats getrrsetstats64 #define getsigningtime getsigningtime64 #define hashsize hashsize64 #define init_file_version init_file_version64 #define isdnssec isdnssec64 #define ispersistent ispersistent64 #define issecure issecure64 #define iszonesecure iszonesecure64 #define loading_addrdataset loading_addrdataset64 #define loadnode loadnode64 #define matchparams matchparams64 #define maybe_free_rbtdb maybe_free_rbtdb64 #define new_reference new_reference64 #define newversion newversion64 #define nodecount nodecount64 #define overmem overmem64 #define previous_closest_nsec previous_closest_nsec64 #define printnode printnode64 #define prune_tree prune_tree64 #define rbt_datafixer rbt_datafixer64 #define rbt_datawriter rbt_datawriter64 #define rdataset_clearprefetch rdataset_clearprefetch64 #define rdataset_clone rdataset_clone64 #define rdataset_count rdataset_count64 #define rdataset_current rdataset_current64 #define rdataset_disassociate rdataset_disassociate64 #define rdataset_expire rdataset_expire64 #define rdataset_first rdataset_first64 #define rdataset_getadditional rdataset_getadditional64 #define rdataset_getclosest rdataset_getclosest64 #define rdataset_getnoqname rdataset_getnoqname64 #define rdataset_next rdataset_next64 #define rdataset_putadditional rdataset_putadditional64 #define rdataset_setadditional rdataset_setadditional64 #define rdataset_settrust rdataset_settrust64 #define rdatasetiter_current rdatasetiter_current64 #define rdatasetiter_destroy rdatasetiter_destroy64 #define rdatasetiter_first rdatasetiter_first64 #define rdatasetiter_next rdatasetiter_next64 #define reactivate_node reactivate_node64 #define resign_delete resign_delete64 #define resign_insert resign_insert64 #define resign_sooner resign_sooner64 #define resigned resigned64 #define rpz_attach rpz_attach64 #define rpz_ready rpz_ready64 #define serialize serialize64 #define set_index set_index64 #define set_ttl set_ttl64 #define setcachestats setcachestats64 #define setsigningtime setsigningtime64 #define settask settask64 #define setup_delegation setup_delegation64 #define subtractrdataset subtractrdataset64 #define ttl_sooner ttl_sooner64 #define update_cachestats update_cachestats64 #define update_header update_header64 #define update_newheader update_newheader64 #define update_rrsetstats update_rrsetstats64 #define zone_find zone_find64 #define zone_findrdataset zone_findrdataset64 #define zone_findzonecut zone_findzonecut64 #define zone_zonecut_callback zone_zonecut_callback64 #else typedef isc_uint32_t rbtdb_serial_t; #endif typedef isc_uint32_t rbtdb_rdatatype_t; #define RBTDB_RDATATYPE_BASE(type) ((dns_rdatatype_t)((type) & 0xFFFF)) #define RBTDB_RDATATYPE_EXT(type) ((dns_rdatatype_t)((type) >> 16)) #define RBTDB_RDATATYPE_VALUE(b, e) ((rbtdb_rdatatype_t)((e) << 16) | (b)) #define RBTDB_RDATATYPE_SIGNSEC \ RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_nsec) #define RBTDB_RDATATYPE_SIGNSEC3 \ RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_nsec3) #define RBTDB_RDATATYPE_SIGNS \ RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_ns) #define RBTDB_RDATATYPE_SIGCNAME \ RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_cname) #define RBTDB_RDATATYPE_SIGDNAME \ RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_dname) #define RBTDB_RDATATYPE_SIGDDS \ RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_ds) #define RBTDB_RDATATYPE_NCACHEANY \ RBTDB_RDATATYPE_VALUE(0, dns_rdatatype_any) /* * We use rwlock for DB lock only when ISC_RWLOCK_USEATOMIC is non 0. * Using rwlock is effective with regard to lookup performance only when * it is implemented in an efficient way. * Otherwise, it is generally wise to stick to the simple locking since rwlock * would require more memory or can even make lookups slower due to its own * overhead (when it internally calls mutex locks). */ #ifdef ISC_RWLOCK_USEATOMIC #define DNS_RBTDB_USERWLOCK 1 #else #define DNS_RBTDB_USERWLOCK 0 #endif #if DNS_RBTDB_USERWLOCK #define RBTDB_INITLOCK(l) isc_rwlock_init((l), 0, 0) #define RBTDB_DESTROYLOCK(l) isc_rwlock_destroy(l) #define RBTDB_LOCK(l, t) RWLOCK((l), (t)) #define RBTDB_UNLOCK(l, t) RWUNLOCK((l), (t)) #else #define RBTDB_INITLOCK(l) isc_mutex_init(l) #define RBTDB_DESTROYLOCK(l) DESTROYLOCK(l) #define RBTDB_LOCK(l, t) LOCK(l) #define RBTDB_UNLOCK(l, t) UNLOCK(l) #endif /* * Since node locking is sensitive to both performance and memory footprint, * we need some trick here. If we have both high-performance rwlock and * high performance and small-memory reference counters, we use rwlock for * node lock and isc_refcount for node references. In this case, we don't have * to protect the access to the counters by locks. * Otherwise, we simply use ordinary mutex lock for node locking, and use * simple integers as reference counters which is protected by the lock. * In most cases, we can simply use wrapper macros such as NODE_LOCK and * NODE_UNLOCK. In some other cases, however, we need to protect reference * counters first and then protect other parts of a node as read-only data. * Special additional macros, NODE_STRONGLOCK(), NODE_WEAKLOCK(), etc, are also * provided for these special cases. When we can use the efficient backend * routines, we should only protect the "other members" by NODE_WEAKLOCK(read). * Otherwise, we should use NODE_STRONGLOCK() to protect the entire critical * section including the access to the reference counter. * Note that we cannot use NODE_LOCK()/NODE_UNLOCK() wherever the protected * section is also protected by NODE_STRONGLOCK(). */ #if defined(ISC_RWLOCK_USEATOMIC) && defined(DNS_RBT_USEISCREFCOUNT) typedef isc_rwlock_t nodelock_t; #define NODE_INITLOCK(l) isc_rwlock_init((l), 0, 0) #define NODE_DESTROYLOCK(l) isc_rwlock_destroy(l) #define NODE_LOCK(l, t) RWLOCK((l), (t)) #define NODE_UNLOCK(l, t) RWUNLOCK((l), (t)) #define NODE_TRYUPGRADE(l) isc_rwlock_tryupgrade(l) #define NODE_STRONGLOCK(l) ((void)0) #define NODE_STRONGUNLOCK(l) ((void)0) #define NODE_WEAKLOCK(l, t) NODE_LOCK(l, t) #define NODE_WEAKUNLOCK(l, t) NODE_UNLOCK(l, t) #define NODE_WEAKDOWNGRADE(l) isc_rwlock_downgrade(l) #else typedef isc_mutex_t nodelock_t; #define NODE_INITLOCK(l) isc_mutex_init(l) #define NODE_DESTROYLOCK(l) DESTROYLOCK(l) #define NODE_LOCK(l, t) LOCK(l) #define NODE_UNLOCK(l, t) UNLOCK(l) #define NODE_TRYUPGRADE(l) ISC_R_SUCCESS #define NODE_STRONGLOCK(l) LOCK(l) #define NODE_STRONGUNLOCK(l) UNLOCK(l) #define NODE_WEAKLOCK(l, t) ((void)0) #define NODE_WEAKUNLOCK(l, t) ((void)0) #define NODE_WEAKDOWNGRADE(l) ((void)0) #endif /*% * Whether to rate-limit updating the LRU to avoid possible thread contention. * Our performance measurement has shown the cost is marginal, so it's defined * to be 0 by default either with or without threads. */ #ifndef DNS_RBTDB_LIMITLRUUPDATE #define DNS_RBTDB_LIMITLRUUPDATE 0 #endif /* * Allow clients with a virtual time of up to 5 minutes in the past to see * records that would have otherwise have expired. */ #define RBTDB_VIRTUAL 300 struct noqname { dns_name_t name; void * neg; void * negsig; dns_rdatatype_t type; }; typedef struct acachectl acachectl_t; typedef struct rdatasetheader { /*% * Locked by the owning node's lock. */ rbtdb_serial_t serial; dns_ttl_t rdh_ttl; rbtdb_rdatatype_t type; isc_uint16_t attributes; dns_trust_t trust; struct noqname *noqname; struct noqname *closest; unsigned int is_mmapped : 1; unsigned int next_is_relative : 1; unsigned int node_is_relative : 1; /*%< * We don't use the LIST macros, because the LIST structure has * both head and tail pointers, and is doubly linked. */ struct rdatasetheader *next; /*%< * If this is the top header for an rdataset, 'next' points * to the top header for the next rdataset (i.e., the next type). * Otherwise, it points up to the header whose down pointer points * at this header. */ struct rdatasetheader *down; /*%< * Points to the header for the next older version of * this rdataset. */ isc_uint32_t count; /*%< * Monotonously increased every time this rdataset is bound so that * it is used as the base of the starting point in DNS responses * when the "cyclic" rrset-order is required. Since the ordering * should not be so crucial, no lock is set for the counter for * performance reasons. */ acachectl_t *additional_auth; acachectl_t *additional_glue; dns_rbtnode_t *node; isc_stdtime_t last_used; ISC_LINK(struct rdatasetheader) link; unsigned int heap_index; /*%< * Used for TTL-based cache cleaning. */ isc_stdtime_t resign; } rdatasetheader_t; typedef ISC_LIST(rdatasetheader_t) rdatasetheaderlist_t; typedef ISC_LIST(dns_rbtnode_t) rbtnodelist_t; #define RDATASET_ATTR_NONEXISTENT 0x0001 #define RDATASET_ATTR_STALE 0x0002 #define RDATASET_ATTR_IGNORE 0x0004 #define RDATASET_ATTR_RETAIN 0x0008 #define RDATASET_ATTR_NXDOMAIN 0x0010 #define RDATASET_ATTR_RESIGN 0x0020 #define RDATASET_ATTR_STATCOUNT 0x0040 #define RDATASET_ATTR_OPTOUT 0x0080 #define RDATASET_ATTR_NEGATIVE 0x0100 #define RDATASET_ATTR_PREFETCH 0x0200 typedef struct acache_cbarg { dns_rdatasetadditional_t type; unsigned int count; dns_db_t *db; dns_dbnode_t *node; rdatasetheader_t *header; } acache_cbarg_t; struct acachectl { dns_acacheentry_t *entry; acache_cbarg_t *cbarg; }; /* * XXX * When the cache will pre-expire data (due to memory low or other * situations) before the rdataset's TTL has expired, it MUST * respect the RETAIN bit and not expire the data until its TTL is * expired. */ #undef IGNORE /* WIN32 winbase.h defines this. */ #define EXISTS(header) \ (((header)->attributes & RDATASET_ATTR_NONEXISTENT) == 0) #define NONEXISTENT(header) \ (((header)->attributes & RDATASET_ATTR_NONEXISTENT) != 0) #define IGNORE(header) \ (((header)->attributes & RDATASET_ATTR_IGNORE) != 0) #define RETAIN(header) \ (((header)->attributes & RDATASET_ATTR_RETAIN) != 0) #define NXDOMAIN(header) \ (((header)->attributes & RDATASET_ATTR_NXDOMAIN) != 0) #define STALE(header) \ (((header)->attributes & RDATASET_ATTR_STALE) != 0) #define RESIGN(header) \ (((header)->attributes & RDATASET_ATTR_RESIGN) != 0) #define OPTOUT(header) \ (((header)->attributes & RDATASET_ATTR_OPTOUT) != 0) #define NEGATIVE(header) \ (((header)->attributes & RDATASET_ATTR_NEGATIVE) != 0) #define PREFETCH(header) \ (((header)->attributes & RDATASET_ATTR_PREFETCH) != 0) #define DEFAULT_NODE_LOCK_COUNT 7 /*%< Should be prime. */ /*% * Number of buckets for cache DB entries (locks, LRU lists, TTL heaps). * There is a tradeoff issue about configuring this value: if this is too * small, it may cause heavier contention between threads; if this is too large, * LRU purge algorithm won't work well (entries tend to be purged prematurely). * The default value should work well for most environments, but this can * also be configurable at compilation time via the * DNS_RBTDB_CACHE_NODE_LOCK_COUNT variable. This value must be larger than * 1 due to the assumption of overmem_purge(). */ #ifdef DNS_RBTDB_CACHE_NODE_LOCK_COUNT #if DNS_RBTDB_CACHE_NODE_LOCK_COUNT <= 1 #error "DNS_RBTDB_CACHE_NODE_LOCK_COUNT must be larger than 1" #else #define DEFAULT_CACHE_NODE_LOCK_COUNT DNS_RBTDB_CACHE_NODE_LOCK_COUNT #endif #else #define DEFAULT_CACHE_NODE_LOCK_COUNT 16 #endif /* DNS_RBTDB_CACHE_NODE_LOCK_COUNT */ typedef struct { nodelock_t lock; /* Protected in the refcount routines. */ isc_refcount_t references; /* Locked by lock. */ isc_boolean_t exiting; } rbtdb_nodelock_t; typedef struct rbtdb_changed { dns_rbtnode_t * node; isc_boolean_t dirty; ISC_LINK(struct rbtdb_changed) link; } rbtdb_changed_t; typedef ISC_LIST(rbtdb_changed_t) rbtdb_changedlist_t; typedef enum { dns_db_insecure, dns_db_partial, dns_db_secure } dns_db_secure_t; typedef struct dns_rbtdb dns_rbtdb_t; /* Reason for expiring a record from cache */ typedef enum { expire_lru, expire_ttl, expire_flush } expire_t; typedef struct rbtdb_version { /* Not locked */ rbtdb_serial_t serial; dns_rbtdb_t * rbtdb; /* * Protected in the refcount routines. * XXXJT: should we change the lock policy based on the refcount * performance? */ isc_refcount_t references; /* Locked by database lock. */ isc_boolean_t writer; isc_boolean_t commit_ok; rbtdb_changedlist_t changed_list; rdatasetheaderlist_t resigned_list; ISC_LINK(struct rbtdb_version) link; dns_db_secure_t secure; isc_boolean_t havensec3; /* NSEC3 parameters */ dns_hash_t hash; isc_uint8_t flags; isc_uint16_t iterations; isc_uint8_t salt_length; unsigned char salt[DNS_NSEC3_SALTSIZE]; } rbtdb_version_t; typedef ISC_LIST(rbtdb_version_t) rbtdb_versionlist_t; struct dns_rbtdb { /* Unlocked. */ dns_db_t common; /* Locks the data in this struct */ #if DNS_RBTDB_USERWLOCK isc_rwlock_t lock; #else isc_mutex_t lock; #endif /* Locks the tree structure (prevents nodes appearing/disappearing) */ isc_rwlock_t tree_lock; /* Locks for individual tree nodes */ unsigned int node_lock_count; rbtdb_nodelock_t * node_locks; dns_rbtnode_t * origin_node; dns_stats_t * rrsetstats; /* cache DB only */ isc_stats_t * cachestats; /* cache DB only */ /* Locked by lock. */ unsigned int active; isc_refcount_t references; unsigned int attributes; rbtdb_serial_t current_serial; rbtdb_serial_t least_serial; rbtdb_serial_t next_serial; rbtdb_version_t * current_version; rbtdb_version_t * future_version; rbtdb_versionlist_t open_versions; isc_task_t * task; dns_dbnode_t *soanode; dns_dbnode_t *nsnode; /* * This is a linked list used to implement the LRU cache. There will * be node_lock_count linked lists here. Nodes in bucket 1 will be * placed on the linked list rdatasets[1]. */ rdatasetheaderlist_t *rdatasets; /*% * Temporary storage for stale cache nodes and dynamically deleted * nodes that await being cleaned up. */ rbtnodelist_t *deadnodes; /* * Heaps. These are used for TTL based expiry in a cache, * or for zone resigning in a zone DB. hmctx is the memory * context to use for the heap (which differs from the main * database memory context in the case of a cache). */ isc_mem_t * hmctx; isc_heap_t **heaps; /* * Base values for the mmap() code. */ void * mmap_location; size_t mmap_size; /* Locked by tree_lock. */ dns_rbt_t * tree; dns_rbt_t * nsec; dns_rbt_t * nsec3; dns_rpz_zones_t *rpzs; dns_rpz_num_t rpz_num; dns_rpz_zones_t *load_rpzs; /* Unlocked */ unsigned int quantum; }; #define RBTDB_ATTR_LOADED 0x01 #define RBTDB_ATTR_LOADING 0x02 /*% * Search Context */ typedef struct { dns_rbtdb_t * rbtdb; rbtdb_version_t * rbtversion; rbtdb_serial_t serial; unsigned int options; dns_rbtnodechain_t chain; isc_boolean_t copy_name; isc_boolean_t need_cleanup; isc_boolean_t wild; dns_rbtnode_t * zonecut; rdatasetheader_t * zonecut_rdataset; rdatasetheader_t * zonecut_sigrdataset; dns_fixedname_t zonecut_name; isc_stdtime_t now; } rbtdb_search_t; /*% * Load Context */ typedef struct { dns_rbtdb_t * rbtdb; isc_stdtime_t now; } rbtdb_load_t; static void delete_callback(void *data, void *arg); static void rdataset_disassociate(dns_rdataset_t *rdataset); static isc_result_t rdataset_first(dns_rdataset_t *rdataset); static isc_result_t rdataset_next(dns_rdataset_t *rdataset); static void rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata); static void rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target); static unsigned int rdataset_count(dns_rdataset_t *rdataset); static isc_result_t rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name, dns_rdataset_t *neg, dns_rdataset_t *negsig); static isc_result_t rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name, dns_rdataset_t *neg, dns_rdataset_t *negsig); static isc_result_t rdataset_getadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, dns_rdatatype_t qtype, dns_acache_t *acache, dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp, dns_dbnode_t **nodep, dns_name_t *fname, dns_message_t *msg, isc_stdtime_t now); static isc_result_t rdataset_setadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, dns_rdatatype_t qtype, dns_acache_t *acache, dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, dns_name_t *fname); static isc_result_t rdataset_putadditional(dns_acache_t *acache, dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, dns_rdatatype_t qtype); static inline isc_boolean_t need_headerupdate(rdatasetheader_t *header, isc_stdtime_t now); static void update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, isc_stdtime_t now); static void expire_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, isc_boolean_t tree_locked, expire_t reason); static void overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start, isc_stdtime_t now, isc_boolean_t tree_locked); static isc_result_t resign_insert(dns_rbtdb_t *rbtdb, int idx, rdatasetheader_t *newheader); static void resign_delete(dns_rbtdb_t *rbtdb, rbtdb_version_t *version, rdatasetheader_t *header); static void prune_tree(isc_task_t *task, isc_event_t *event); static void rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust); static void rdataset_expire(dns_rdataset_t *rdataset); static void rdataset_clearprefetch(dns_rdataset_t *rdataset); static dns_rdatasetmethods_t rdataset_methods = { rdataset_disassociate, rdataset_first, rdataset_next, rdataset_current, rdataset_clone, rdataset_count, NULL, rdataset_getnoqname, NULL, rdataset_getclosest, rdataset_getadditional, rdataset_setadditional, rdataset_putadditional, rdataset_settrust, rdataset_expire, rdataset_clearprefetch }; static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp); static isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator); static isc_result_t rdatasetiter_next(dns_rdatasetiter_t *iterator); static void rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset); static dns_rdatasetitermethods_t rdatasetiter_methods = { rdatasetiter_destroy, rdatasetiter_first, rdatasetiter_next, rdatasetiter_current }; typedef struct rbtdb_rdatasetiter { dns_rdatasetiter_t common; rdatasetheader_t * current; } rbtdb_rdatasetiter_t; static void dbiterator_destroy(dns_dbiterator_t **iteratorp); static isc_result_t dbiterator_first(dns_dbiterator_t *iterator); static isc_result_t dbiterator_last(dns_dbiterator_t *iterator); static isc_result_t dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name); static isc_result_t dbiterator_prev(dns_dbiterator_t *iterator); static isc_result_t dbiterator_next(dns_dbiterator_t *iterator); static isc_result_t dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep, dns_name_t *name); static isc_result_t dbiterator_pause(dns_dbiterator_t *iterator); static isc_result_t dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name); static dns_dbiteratormethods_t dbiterator_methods = { dbiterator_destroy, dbiterator_first, dbiterator_last, dbiterator_seek, dbiterator_prev, dbiterator_next, dbiterator_current, dbiterator_pause, dbiterator_origin }; #define DELETION_BATCH_MAX 64 /* * If 'paused' is ISC_TRUE, then the tree lock is not being held. */ typedef struct rbtdb_dbiterator { dns_dbiterator_t common; isc_boolean_t paused; isc_boolean_t new_origin; isc_rwlocktype_t tree_locked; isc_result_t result; dns_fixedname_t name; dns_fixedname_t origin; dns_rbtnodechain_t chain; dns_rbtnodechain_t nsec3chain; dns_rbtnodechain_t *current; dns_rbtnode_t *node; dns_rbtnode_t *deletions[DELETION_BATCH_MAX]; int delete; isc_boolean_t nsec3only; isc_boolean_t nonsec3; } rbtdb_dbiterator_t; #define IS_STUB(rbtdb) (((rbtdb)->common.attributes & DNS_DBATTR_STUB) != 0) #define IS_CACHE(rbtdb) (((rbtdb)->common.attributes & DNS_DBATTR_CACHE) != 0) static void free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event); static void overmem(dns_db_t *db, isc_boolean_t over); static void setnsec3parameters(dns_db_t *db, rbtdb_version_t *version); /* Pad to 32 bytes */ static char FILE_VERSION[32] = "\0"; /*% * 'init_count' is used to initialize 'newheader->count' which inturn * is used to determine where in the cycle rrset-order cyclic starts. * We don't lock this as we don't care about simultaneous updates. * * Note: * Both init_count and header->count can be ISC_UINT32_MAX. * The count on the returned rdataset however can't be as * that indicates that the database does not implement cyclic * processing. */ static unsigned int init_count; /* * Locking * * If a routine is going to lock more than one lock in this module, then * the locking must be done in the following order: * * Tree Lock * * Node Lock (Only one from the set may be locked at one time by * any caller) * * Database Lock * * Failure to follow this hierarchy can result in deadlock. */ /* * Deleting Nodes * * For zone databases the node for the origin of the zone MUST NOT be deleted. */ /* * Debugging routines */ #ifdef DEBUG static void hexdump(const char *desc, unsigned char *data, size_t size) { char hexdump[BUFSIZ * 2 + 1]; isc_buffer_t b; isc_region_t r; isc_result_t result; size_t bytes; fprintf(stderr, "%s: ", desc); do { isc_buffer_init(&b, hexdump, sizeof(hexdump)); r.base = data; r.length = bytes = (size > BUFSIZ) ? BUFSIZ : size; result = isc_hex_totext(&r, 0, "", &b); RUNTIME_CHECK(result == ISC_R_SUCCESS); isc_buffer_putuint8(&b, 0); fprintf(stderr, "%s", hexdump); data += bytes; size -= bytes; } while (size > 0); fprintf(stderr, "\n"); } #endif /* * DB Routines */ static void attach(dns_db_t *source, dns_db_t **targetp) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)source; REQUIRE(VALID_RBTDB(rbtdb)); isc_refcount_increment(&rbtdb->references, NULL); *targetp = source; } static void free_rbtdb_callback(isc_task_t *task, isc_event_t *event) { dns_rbtdb_t *rbtdb = event->ev_arg; UNUSED(task); free_rbtdb(rbtdb, ISC_TRUE, event); } static void update_cachestats(dns_rbtdb_t *rbtdb, isc_result_t result) { INSIST(IS_CACHE(rbtdb)); if (rbtdb->cachestats == NULL) return; switch (result) { case ISC_R_SUCCESS: case DNS_R_CNAME: case DNS_R_DNAME: case DNS_R_DELEGATION: case DNS_R_NCACHENXDOMAIN: case DNS_R_NCACHENXRRSET: isc_stats_increment(rbtdb->cachestats, dns_cachestatscounter_hits); break; default: isc_stats_increment(rbtdb->cachestats, dns_cachestatscounter_misses); } } static void update_rrsetstats(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, isc_boolean_t increment) { dns_rdatastatstype_t statattributes = 0; dns_rdatastatstype_t base = 0; dns_rdatastatstype_t type; /* At the moment we count statistics only for cache DB */ INSIST(IS_CACHE(rbtdb)); if (NEGATIVE(header)) { if (NXDOMAIN(header)) statattributes = DNS_RDATASTATSTYPE_ATTR_NXDOMAIN; else { statattributes = DNS_RDATASTATSTYPE_ATTR_NXRRSET; base = RBTDB_RDATATYPE_EXT(header->type); } } else base = RBTDB_RDATATYPE_BASE(header->type); if (STALE(header)) statattributes |= DNS_RDATASTATSTYPE_ATTR_STALE; type = DNS_RDATASTATSTYPE_VALUE(base, statattributes); if (increment) dns_rdatasetstats_increment(rbtdb->rrsetstats, type); else dns_rdatasetstats_decrement(rbtdb->rrsetstats, type); } static void set_ttl(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, dns_ttl_t newttl) { int idx; isc_heap_t *heap; dns_ttl_t oldttl; if (!IS_CACHE(rbtdb)) { header->rdh_ttl = newttl; return; } oldttl = header->rdh_ttl; header->rdh_ttl = newttl; /* * It's possible the rbtdb is not a cache. If this is the case, * we will not have a heap, and we move on. If we do, though, * we might need to adjust things. */ if (header->heap_index == 0 || newttl == oldttl) return; idx = header->node->locknum; if (rbtdb->heaps == NULL || rbtdb->heaps[idx] == NULL) return; heap = rbtdb->heaps[idx]; if (newttl < oldttl) isc_heap_increased(heap, header->heap_index); else isc_heap_decreased(heap, header->heap_index); } /*% * These functions allow the heap code to rank the priority of each * element. It returns ISC_TRUE if v1 happens "sooner" than v2. */ static isc_boolean_t ttl_sooner(void *v1, void *v2) { rdatasetheader_t *h1 = v1; rdatasetheader_t *h2 = v2; if (h1->rdh_ttl < h2->rdh_ttl) return (ISC_TRUE); return (ISC_FALSE); } static isc_boolean_t resign_sooner(void *v1, void *v2) { rdatasetheader_t *h1 = v1; rdatasetheader_t *h2 = v2; if (isc_serial_lt(h1->resign, h2->resign)) return (ISC_TRUE); return (ISC_FALSE); } /*% * This function sets the heap index into the header. */ static void set_index(void *what, unsigned int idx) { rdatasetheader_t *h = what; h->heap_index = idx; } /*% * Work out how many nodes can be deleted in the time between two * requests to the nameserver. Smooth the resulting number and use it * as a estimate for the number of nodes to be deleted in the next * iteration. */ static unsigned int adjust_quantum(unsigned int old, isc_time_t *start) { unsigned int pps = dns_pps; /* packets per second */ unsigned int interval; isc_uint64_t usecs; isc_time_t end; unsigned int new; if (pps < 100) pps = 100; isc_time_now(&end); interval = 1000000 / pps; /* interval in usec */ if (interval == 0) interval = 1; usecs = isc_time_microdiff(&end, start); if (usecs == 0) { /* * We were unable to measure the amount of time taken. * Double the nodes deleted next time. */ old *= 2; if (old > 1000) old = 1000; return (old); } new = old * interval; new /= (unsigned int)usecs; if (new == 0) new = 1; else if (new > 1000) new = 1000; /* Smooth */ new = (new + old * 3) / 4; if (new != old) isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1), "adjust_quantum: old=%d, new=%d", old, new); return (new); } static void free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) { unsigned int i; isc_ondestroy_t ondest; isc_result_t result; char buf[DNS_NAME_FORMATSIZE]; dns_rbt_t **treep; isc_time_t start; if (IS_CACHE(rbtdb) && rbtdb->common.rdclass == dns_rdataclass_in) overmem((dns_db_t *)rbtdb, (isc_boolean_t)-1); REQUIRE(rbtdb->current_version != NULL || EMPTY(rbtdb->open_versions)); REQUIRE(rbtdb->future_version == NULL); if (rbtdb->current_version != NULL) { unsigned int refs; isc_refcount_decrement(&rbtdb->current_version->references, &refs); INSIST(refs == 0); UNLINK(rbtdb->open_versions, rbtdb->current_version, link); isc_refcount_destroy(&rbtdb->current_version->references); isc_mem_put(rbtdb->common.mctx, rbtdb->current_version, sizeof(rbtdb_version_t)); } /* * We assume the number of remaining dead nodes is reasonably small; * the overhead of unlinking all nodes here should be negligible. */ for (i = 0; i < rbtdb->node_lock_count; i++) { dns_rbtnode_t *node; node = ISC_LIST_HEAD(rbtdb->deadnodes[i]); while (node != NULL) { ISC_LIST_UNLINK(rbtdb->deadnodes[i], node, deadlink); node = ISC_LIST_HEAD(rbtdb->deadnodes[i]); } } if (event == NULL) rbtdb->quantum = (rbtdb->task != NULL) ? 100 : 0; for (;;) { /* * pick the next tree to (start to) destroy */ treep = &rbtdb->tree; if (*treep == NULL) { treep = &rbtdb->nsec; if (*treep == NULL) { treep = &rbtdb->nsec3; /* * we're finished after clear cutting */ if (*treep == NULL) break; } } isc_time_now(&start); result = dns_rbt_destroy2(treep, rbtdb->quantum); if (result == ISC_R_QUOTA) { INSIST(rbtdb->task != NULL); if (rbtdb->quantum != 0) rbtdb->quantum = adjust_quantum(rbtdb->quantum, &start); if (event == NULL) event = isc_event_allocate(rbtdb->common.mctx, NULL, DNS_EVENT_FREESTORAGE, free_rbtdb_callback, rbtdb, sizeof(isc_event_t)); if (event == NULL) continue; isc_task_send(rbtdb->task, &event); return; } INSIST(result == ISC_R_SUCCESS && *treep == NULL); } if (event != NULL) isc_event_free(&event); if (log) { if (dns_name_dynamic(&rbtdb->common.origin)) dns_name_format(&rbtdb->common.origin, buf, sizeof(buf)); else strcpy(buf, ""); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1), "done free_rbtdb(%s)", buf); } if (dns_name_dynamic(&rbtdb->common.origin)) dns_name_free(&rbtdb->common.origin, rbtdb->common.mctx); for (i = 0; i < rbtdb->node_lock_count; i++) { isc_refcount_destroy(&rbtdb->node_locks[i].references); NODE_DESTROYLOCK(&rbtdb->node_locks[i].lock); } /* * Clean up LRU / re-signing order lists. */ if (rbtdb->rdatasets != NULL) { for (i = 0; i < rbtdb->node_lock_count; i++) INSIST(ISC_LIST_EMPTY(rbtdb->rdatasets[i])); isc_mem_put(rbtdb->common.mctx, rbtdb->rdatasets, rbtdb->node_lock_count * sizeof(rdatasetheaderlist_t)); } /* * Clean up dead node buckets. */ if (rbtdb->deadnodes != NULL) { for (i = 0; i < rbtdb->node_lock_count; i++) INSIST(ISC_LIST_EMPTY(rbtdb->deadnodes[i])); isc_mem_put(rbtdb->common.mctx, rbtdb->deadnodes, rbtdb->node_lock_count * sizeof(rbtnodelist_t)); } /* * Clean up heap objects. */ if (rbtdb->heaps != NULL) { for (i = 0; i < rbtdb->node_lock_count; i++) isc_heap_destroy(&rbtdb->heaps[i]); isc_mem_put(rbtdb->hmctx, rbtdb->heaps, rbtdb->node_lock_count * sizeof(isc_heap_t *)); } if (rbtdb->rrsetstats != NULL) dns_stats_detach(&rbtdb->rrsetstats); if (rbtdb->cachestats != NULL) isc_stats_detach(&rbtdb->cachestats); if (rbtdb->load_rpzs != NULL) { /* * We must be cleaning up after a failed zone loading. */ REQUIRE(rbtdb->rpzs != NULL && rbtdb->rpz_num < rbtdb->rpzs->p.num_zones); dns_rpz_detach_rpzs(&rbtdb->load_rpzs); } if (rbtdb->rpzs != NULL) { REQUIRE(rbtdb->rpz_num < rbtdb->rpzs->p.num_zones); dns_rpz_detach_rpzs(&rbtdb->rpzs); } isc_mem_put(rbtdb->common.mctx, rbtdb->node_locks, rbtdb->node_lock_count * sizeof(rbtdb_nodelock_t)); isc_rwlock_destroy(&rbtdb->tree_lock); isc_refcount_destroy(&rbtdb->references); if (rbtdb->task != NULL) isc_task_detach(&rbtdb->task); RBTDB_DESTROYLOCK(&rbtdb->lock); rbtdb->common.magic = 0; rbtdb->common.impmagic = 0; ondest = rbtdb->common.ondest; isc_mem_detach(&rbtdb->hmctx); if (rbtdb->mmap_location != NULL) isc_file_munmap(rbtdb->mmap_location, (size_t) rbtdb->mmap_size); isc_mem_putanddetach(&rbtdb->common.mctx, rbtdb, sizeof(*rbtdb)); isc_ondestroy_notify(&ondest, rbtdb); } static inline void maybe_free_rbtdb(dns_rbtdb_t *rbtdb) { isc_boolean_t want_free = ISC_FALSE; unsigned int i; unsigned int inactive = 0; /* XXX check for open versions here */ if (rbtdb->soanode != NULL) dns_db_detachnode((dns_db_t *)rbtdb, &rbtdb->soanode); if (rbtdb->nsnode != NULL) dns_db_detachnode((dns_db_t *)rbtdb, &rbtdb->nsnode); /* * Even though there are no external direct references, there still * may be nodes in use. */ for (i = 0; i < rbtdb->node_lock_count; i++) { NODE_LOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_write); rbtdb->node_locks[i].exiting = ISC_TRUE; NODE_UNLOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_write); if (isc_refcount_current(&rbtdb->node_locks[i].references) == 0) { inactive++; } } if (inactive != 0) { RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); rbtdb->active -= inactive; if (rbtdb->active == 0) want_free = ISC_TRUE; RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); if (want_free) { char buf[DNS_NAME_FORMATSIZE]; if (dns_name_dynamic(&rbtdb->common.origin)) dns_name_format(&rbtdb->common.origin, buf, sizeof(buf)); else strcpy(buf, ""); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1), "calling free_rbtdb(%s)", buf); free_rbtdb(rbtdb, ISC_TRUE, NULL); } } } static void detach(dns_db_t **dbp) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)(*dbp); unsigned int refs; REQUIRE(VALID_RBTDB(rbtdb)); isc_refcount_decrement(&rbtdb->references, &refs); if (refs == 0) maybe_free_rbtdb(rbtdb); *dbp = NULL; } static void currentversion(dns_db_t *db, dns_dbversion_t **versionp) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; rbtdb_version_t *version; unsigned int refs; REQUIRE(VALID_RBTDB(rbtdb)); RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read); version = rbtdb->current_version; isc_refcount_increment(&version->references, &refs); RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read); *versionp = (dns_dbversion_t *)version; } static inline rbtdb_version_t * allocate_version(isc_mem_t *mctx, rbtdb_serial_t serial, unsigned int references, isc_boolean_t writer) { isc_result_t result; rbtdb_version_t *version; version = isc_mem_get(mctx, sizeof(*version)); if (version == NULL) return (NULL); version->serial = serial; result = isc_refcount_init(&version->references, references); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, version, sizeof(*version)); return (NULL); } version->writer = writer; version->commit_ok = ISC_FALSE; ISC_LIST_INIT(version->changed_list); ISC_LIST_INIT(version->resigned_list); ISC_LINK_INIT(version, link); return (version); } static isc_result_t newversion(dns_db_t *db, dns_dbversion_t **versionp) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; rbtdb_version_t *version; REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(versionp != NULL && *versionp == NULL); REQUIRE(rbtdb->future_version == NULL); RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); RUNTIME_CHECK(rbtdb->next_serial != 0); /* XXX Error? */ version = allocate_version(rbtdb->common.mctx, rbtdb->next_serial, 1, ISC_TRUE); if (version != NULL) { version->rbtdb = rbtdb; version->commit_ok = ISC_TRUE; version->secure = rbtdb->current_version->secure; version->havensec3 = rbtdb->current_version->havensec3; if (version->havensec3) { version->flags = rbtdb->current_version->flags; version->iterations = rbtdb->current_version->iterations; version->hash = rbtdb->current_version->hash; version->salt_length = rbtdb->current_version->salt_length; memmove(version->salt, rbtdb->current_version->salt, version->salt_length); } else { version->flags = 0; version->iterations = 0; version->hash = 0; version->salt_length = 0; memset(version->salt, 0, sizeof(version->salt)); } rbtdb->next_serial++; rbtdb->future_version = version; } RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); if (version == NULL) return (ISC_R_NOMEMORY); *versionp = version; return (ISC_R_SUCCESS); } static void attachversion(dns_db_t *db, dns_dbversion_t *source, dns_dbversion_t **targetp) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; rbtdb_version_t *rbtversion = source; unsigned int refs; REQUIRE(VALID_RBTDB(rbtdb)); INSIST(rbtversion != NULL && rbtversion->rbtdb == rbtdb); isc_refcount_increment(&rbtversion->references, &refs); INSIST(refs > 1); *targetp = rbtversion; } static rbtdb_changed_t * add_changed(dns_rbtdb_t *rbtdb, rbtdb_version_t *version, dns_rbtnode_t *node) { rbtdb_changed_t *changed; unsigned int refs; /* * Caller must be holding the node lock if its reference must be * protected by the lock. */ changed = isc_mem_get(rbtdb->common.mctx, sizeof(*changed)); RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); REQUIRE(version->writer); if (changed != NULL) { dns_rbtnode_refincrement(node, &refs); INSIST(refs != 0); changed->node = node; changed->dirty = ISC_FALSE; ISC_LIST_INITANDAPPEND(version->changed_list, changed, link); } else version->commit_ok = ISC_FALSE; RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); return (changed); } static void free_acachearray(isc_mem_t *mctx, rdatasetheader_t *header, acachectl_t *array) { unsigned int count; unsigned int i; unsigned char *raw; /* RDATASLAB */ /* * The caller must be holding the corresponding node lock. */ if (array == NULL) return; raw = (unsigned char *)header + sizeof(*header); count = raw[0] * 256 + raw[1]; /* * Sanity check: since an additional cache entry has a reference to * the original DB node (in the callback arg), there should be no * acache entries when the node can be freed. */ for (i = 0; i < count; i++) INSIST(array[i].entry == NULL && array[i].cbarg == NULL); isc_mem_put(mctx, array, count * sizeof(acachectl_t)); } static inline void free_noqname(isc_mem_t *mctx, struct noqname **noqname) { if (dns_name_dynamic(&(*noqname)->name)) dns_name_free(&(*noqname)->name, mctx); if ((*noqname)->neg != NULL) isc_mem_put(mctx, (*noqname)->neg, dns_rdataslab_size((*noqname)->neg, 0)); if ((*noqname)->negsig != NULL) isc_mem_put(mctx, (*noqname)->negsig, dns_rdataslab_size((*noqname)->negsig, 0)); isc_mem_put(mctx, *noqname, sizeof(**noqname)); *noqname = NULL; } static inline void init_rdataset(dns_rbtdb_t *rbtdb, rdatasetheader_t *h) { ISC_LINK_INIT(h, link); h->heap_index = 0; h->is_mmapped = 0; h->next_is_relative = 0; h->node_is_relative = 0; #if TRACE_HEADER if (IS_CACHE(rbtdb) && rbtdb->common.rdclass == dns_rdataclass_in) fprintf(stderr, "initialized header: %p\n", h); #else UNUSED(rbtdb); #endif } /* * Update the copied values of 'next' and 'node' if they are relative. */ static void update_newheader(rdatasetheader_t *new, rdatasetheader_t *old) { char *p; if (old->next_is_relative) { p = (char *) old; p += (uintptr_t)old->next; new->next = (rdatasetheader_t *)p; } if (old->node_is_relative) { p = (char *) old; p += (uintptr_t)old->node; new->node = (dns_rbtnode_t *)p; } } static inline rdatasetheader_t * new_rdataset(dns_rbtdb_t *rbtdb, isc_mem_t *mctx) { rdatasetheader_t *h; h = isc_mem_get(mctx, sizeof(*h)); if (h == NULL) return (NULL); #if TRACE_HEADER if (IS_CACHE(rbtdb) && rbtdb->common.rdclass == dns_rdataclass_in) fprintf(stderr, "allocated header: %p\n", h); #endif init_rdataset(rbtdb, h); h->rdh_ttl = 0; return (h); } static inline void free_rdataset(dns_rbtdb_t *rbtdb, isc_mem_t *mctx, rdatasetheader_t *rdataset) { unsigned int size; int idx; if (EXISTS(rdataset) && (rdataset->attributes & RDATASET_ATTR_STATCOUNT) != 0) { update_rrsetstats(rbtdb, rdataset, ISC_FALSE); } idx = rdataset->node->locknum; if (ISC_LINK_LINKED(rdataset, link)) { INSIST(IS_CACHE(rbtdb)); ISC_LIST_UNLINK(rbtdb->rdatasets[idx], rdataset, link); } if (rdataset->heap_index != 0) isc_heap_delete(rbtdb->heaps[idx], rdataset->heap_index); rdataset->heap_index = 0; if (rdataset->noqname != NULL) free_noqname(mctx, &rdataset->noqname); if (rdataset->closest != NULL) free_noqname(mctx, &rdataset->closest); free_acachearray(mctx, rdataset, rdataset->additional_auth); free_acachearray(mctx, rdataset, rdataset->additional_glue); if ((rdataset->attributes & RDATASET_ATTR_NONEXISTENT) != 0) size = sizeof(*rdataset); else size = dns_rdataslab_size((unsigned char *)rdataset, sizeof(*rdataset)); if (rdataset->is_mmapped == 1) return; isc_mem_put(mctx, rdataset, size); } static inline void rollback_node(dns_rbtnode_t *node, rbtdb_serial_t serial) { rdatasetheader_t *header, *dcurrent; isc_boolean_t make_dirty = ISC_FALSE; /* * Caller must hold the node lock. */ /* * We set the IGNORE attribute on rdatasets with serial number * 'serial'. When the reference count goes to zero, these rdatasets * will be cleaned up; until that time, they will be ignored. */ for (header = node->data; header != NULL; header = header->next) { if (header->serial == serial) { header->attributes |= RDATASET_ATTR_IGNORE; make_dirty = ISC_TRUE; } for (dcurrent = header->down; dcurrent != NULL; dcurrent = dcurrent->down) { if (dcurrent->serial == serial) { dcurrent->attributes |= RDATASET_ATTR_IGNORE; make_dirty = ISC_TRUE; } } } if (make_dirty) node->dirty = 1; } static inline void mark_stale_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header) { /* * If we are already stale there is nothing to do. */ if ((header->attributes & RDATASET_ATTR_STALE) != 0) return; header->attributes |= RDATASET_ATTR_STALE; header->node->dirty = 1; /* * If we have not been counted then there is nothing to do. */ if ((header->attributes & RDATASET_ATTR_STATCOUNT) == 0) return; if (EXISTS(header)) update_rrsetstats(rbtdb, header, ISC_TRUE); } static inline void clean_stale_headers(dns_rbtdb_t *rbtdb, isc_mem_t *mctx, rdatasetheader_t *top) { rdatasetheader_t *d, *down_next; for (d = top->down; d != NULL; d = down_next) { down_next = d->down; free_rdataset(rbtdb, mctx, d); } top->down = NULL; } static inline void clean_cache_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) { rdatasetheader_t *current, *top_prev, *top_next; isc_mem_t *mctx = rbtdb->common.mctx; /* * Caller must be holding the node lock. */ top_prev = NULL; for (current = node->data; current != NULL; current = top_next) { top_next = current->next; clean_stale_headers(rbtdb, mctx, current); /* * If current is nonexistent or stale, we can clean it up. */ if ((current->attributes & (RDATASET_ATTR_NONEXISTENT|RDATASET_ATTR_STALE)) != 0) { if (top_prev != NULL) top_prev->next = current->next; else node->data = current->next; free_rdataset(rbtdb, mctx, current); } else top_prev = current; } node->dirty = 0; } static inline void clean_zone_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, rbtdb_serial_t least_serial) { rdatasetheader_t *current, *dcurrent, *down_next, *dparent; rdatasetheader_t *top_prev, *top_next; isc_mem_t *mctx = rbtdb->common.mctx; isc_boolean_t still_dirty = ISC_FALSE; /* * Caller must be holding the node lock. */ REQUIRE(least_serial != 0); top_prev = NULL; for (current = node->data; current != NULL; current = top_next) { top_next = current->next; /* * First, we clean up any instances of multiple rdatasets * with the same serial number, or that have the IGNORE * attribute. */ dparent = current; for (dcurrent = current->down; dcurrent != NULL; dcurrent = down_next) { down_next = dcurrent->down; INSIST(dcurrent->serial <= dparent->serial); if (dcurrent->serial == dparent->serial || IGNORE(dcurrent)) { if (down_next != NULL) down_next->next = dparent; dparent->down = down_next; free_rdataset(rbtdb, mctx, dcurrent); } else dparent = dcurrent; } /* * We've now eliminated all IGNORE datasets with the possible * exception of current, which we now check. */ if (IGNORE(current)) { down_next = current->down; if (down_next == NULL) { if (top_prev != NULL) top_prev->next = current->next; else node->data = current->next; free_rdataset(rbtdb, mctx, current); /* * current no longer exists, so we can * just continue with the loop. */ continue; } else { /* * Pull up current->down, making it the new * current. */ if (top_prev != NULL) top_prev->next = down_next; else node->data = down_next; down_next->next = top_next; free_rdataset(rbtdb, mctx, current); current = down_next; } } /* * We now try to find the first down node less than the * least serial. */ dparent = current; for (dcurrent = current->down; dcurrent != NULL; dcurrent = down_next) { down_next = dcurrent->down; if (dcurrent->serial < least_serial) break; dparent = dcurrent; } /* * If there is a such an rdataset, delete it and any older * versions. */ if (dcurrent != NULL) { do { down_next = dcurrent->down; INSIST(dcurrent->serial <= least_serial); free_rdataset(rbtdb, mctx, dcurrent); dcurrent = down_next; } while (dcurrent != NULL); dparent->down = NULL; } /* * Note. The serial number of 'current' might be less than * least_serial too, but we cannot delete it because it is * the most recent version, unless it is a NONEXISTENT * rdataset. */ if (current->down != NULL) { still_dirty = ISC_TRUE; top_prev = current; } else { /* * If this is a NONEXISTENT rdataset, we can delete it. */ if (NONEXISTENT(current)) { if (top_prev != NULL) top_prev->next = current->next; else node->data = current->next; free_rdataset(rbtdb, mctx, current); } else top_prev = current; } } if (!still_dirty) node->dirty = 0; } static void delete_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) { dns_rbtnode_t *nsecnode; dns_fixedname_t fname; dns_name_t *name; isc_result_t result = ISC_R_UNEXPECTED; unsigned int node_has_rpz; INSIST(!ISC_LINK_LINKED(node, deadlink)); switch (node->nsec) { case DNS_RBT_NSEC_NORMAL: /* * Though this may be wasteful, it has to be done before * node is deleted. */ dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_rbt_fullnamefromnode(node, name); node_has_rpz = node->rpz; result = dns_rbt_deletenode(rbtdb->tree, node, ISC_FALSE); if (result == ISC_R_SUCCESS && rbtdb->rpzs != NULL && node_has_rpz) dns_rpz_delete(rbtdb->rpzs, rbtdb->rpz_num, name); break; case DNS_RBT_NSEC_HAS_NSEC: dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_rbt_fullnamefromnode(node, name); /* * Delete the corresponding node from the auxiliary NSEC * tree before deleting from the main tree. */ nsecnode = NULL; result = dns_rbt_findnode(rbtdb->nsec, name, NULL, &nsecnode, NULL, DNS_RBTFIND_EMPTYDATA, NULL, NULL); if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_WARNING, "delete_node: " "dns_rbt_findnode(nsec): %s", isc_result_totext(result)); } else { result = dns_rbt_deletenode(rbtdb->nsec, nsecnode, ISC_FALSE); if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_WARNING, "delete_node(): " "dns_rbt_deletenode(nsecnode): %s", isc_result_totext(result)); } } node_has_rpz = node->rpz; result = dns_rbt_deletenode(rbtdb->tree, node, ISC_FALSE); if (result == ISC_R_SUCCESS && rbtdb->rpzs != NULL && node_has_rpz) dns_rpz_delete(rbtdb->rpzs, rbtdb->rpz_num, name); break; case DNS_RBT_NSEC_NSEC: result = dns_rbt_deletenode(rbtdb->nsec, node, ISC_FALSE); break; case DNS_RBT_NSEC_NSEC3: result = dns_rbt_deletenode(rbtdb->nsec3, node, ISC_FALSE); break; } if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_WARNING, "delete_node(): " "dns_rbt_deletenode: %s", isc_result_totext(result)); } } /*% * Clean up dead nodes. These are nodes which have no references, and * have no data. They are dead but we could not or chose not to delete * them when we deleted all the data at that node because we did not want * to wait for the tree write lock. * * The caller must hold a tree write lock and bucketnum'th node (write) lock. */ static void cleanup_dead_nodes(dns_rbtdb_t *rbtdb, int bucketnum) { dns_rbtnode_t *node; int count = 10; /* XXXJT: should be adjustable */ node = ISC_LIST_HEAD(rbtdb->deadnodes[bucketnum]); while (node != NULL && count > 0) { ISC_LIST_UNLINK(rbtdb->deadnodes[bucketnum], node, deadlink); /* * Since we're holding a tree write lock, it should be * impossible for this node to be referenced by others. */ INSIST(dns_rbtnode_refcurrent(node) == 0 && node->data == NULL); delete_node(rbtdb, node); node = ISC_LIST_HEAD(rbtdb->deadnodes[bucketnum]); count--; } } /* * Caller must be holding the node lock. */ static inline void new_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) { unsigned int lockrefs, noderefs; isc_refcount_t *lockref; INSIST(!ISC_LINK_LINKED(node, deadlink)); dns_rbtnode_refincrement0(node, &noderefs); if (noderefs == 1) { /* this is the first reference to the node */ lockref = &rbtdb->node_locks[node->locknum].references; isc_refcount_increment0(lockref, &lockrefs); INSIST(lockrefs != 0); } INSIST(noderefs != 0); } /* * This function is assumed to be called when a node is newly referenced * and can be in the deadnode list. In that case the node must be retrieved * from the list because it is going to be used. In addition, if the caller * happens to hold a write lock on the tree, it's a good chance to purge dead * nodes. * Note: while a new reference is gained in multiple places, there are only very * few cases where the node can be in the deadnode list (only empty nodes can * have been added to the list). */ static inline void reactivate_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, isc_rwlocktype_t treelocktype) { isc_rwlocktype_t locktype = isc_rwlocktype_read; nodelock_t *nodelock = &rbtdb->node_locks[node->locknum].lock; isc_boolean_t maybe_cleanup = ISC_FALSE; POST(locktype); NODE_STRONGLOCK(nodelock); NODE_WEAKLOCK(nodelock, locktype); /* * Check if we can possibly cleanup the dead node. If so, upgrade * the node lock below to perform the cleanup. */ if (!ISC_LIST_EMPTY(rbtdb->deadnodes[node->locknum]) && treelocktype == isc_rwlocktype_write) { maybe_cleanup = ISC_TRUE; } if (ISC_LINK_LINKED(node, deadlink) || maybe_cleanup) { /* * Upgrade the lock and test if we still need to unlink. */ NODE_WEAKUNLOCK(nodelock, locktype); locktype = isc_rwlocktype_write; POST(locktype); NODE_WEAKLOCK(nodelock, locktype); if (ISC_LINK_LINKED(node, deadlink)) ISC_LIST_UNLINK(rbtdb->deadnodes[node->locknum], node, deadlink); if (maybe_cleanup) cleanup_dead_nodes(rbtdb, node->locknum); } new_reference(rbtdb, node); NODE_WEAKUNLOCK(nodelock, locktype); NODE_STRONGUNLOCK(nodelock); } /* * Caller must be holding the node lock; either the "strong", read or write * lock. Note that the lock must be held even when node references are * atomically modified; in that case the decrement operation itself does not * have to be protected, but we must avoid a race condition where multiple * threads are decreasing the reference to zero simultaneously and at least * one of them is going to free the node. * This function returns ISC_TRUE if and only if the node reference decreases * to zero. */ static isc_boolean_t decrement_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, rbtdb_serial_t least_serial, isc_rwlocktype_t nlock, isc_rwlocktype_t tlock, isc_boolean_t pruning) { isc_result_t result; isc_boolean_t write_locked; rbtdb_nodelock_t *nodelock; unsigned int refs, nrefs; int bucket = node->locknum; isc_boolean_t no_reference = ISC_TRUE; nodelock = &rbtdb->node_locks[bucket]; #define KEEP_NODE(n, r) \ ((n)->data != NULL || (n)->down != NULL || (n) == (r)->origin_node) /* Handle easy and typical case first. */ if (!node->dirty && KEEP_NODE(node, rbtdb)) { dns_rbtnode_refdecrement(node, &nrefs); INSIST((int)nrefs >= 0); if (nrefs == 0) { isc_refcount_decrement(&nodelock->references, &refs); INSIST((int)refs >= 0); } return ((nrefs == 0) ? ISC_TRUE : ISC_FALSE); } /* Upgrade the lock? */ if (nlock == isc_rwlocktype_read) { NODE_WEAKUNLOCK(&nodelock->lock, isc_rwlocktype_read); NODE_WEAKLOCK(&nodelock->lock, isc_rwlocktype_write); } dns_rbtnode_refdecrement(node, &nrefs); INSIST((int)nrefs >= 0); if (nrefs > 0) { /* Restore the lock? */ if (nlock == isc_rwlocktype_read) NODE_WEAKDOWNGRADE(&nodelock->lock); return (ISC_FALSE); } if (node->dirty) { if (IS_CACHE(rbtdb)) clean_cache_node(rbtdb, node); else { if (least_serial == 0) { /* * Caller doesn't know the least serial. * Get it. */ RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read); least_serial = rbtdb->least_serial; RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read); } clean_zone_node(rbtdb, node, least_serial); } } /* * Attempt to switch to a write lock on the tree. If this fails, * we will add this node to a linked list of nodes in this locking * bucket which we will free later. */ if (tlock != isc_rwlocktype_write) { /* * Locking hierarchy notwithstanding, we don't need to free * the node lock before acquiring the tree write lock because * we only do a trylock. */ if (tlock == isc_rwlocktype_read) result = isc_rwlock_tryupgrade(&rbtdb->tree_lock); else result = isc_rwlock_trylock(&rbtdb->tree_lock, isc_rwlocktype_write); RUNTIME_CHECK(result == ISC_R_SUCCESS || result == ISC_R_LOCKBUSY); write_locked = ISC_TF(result == ISC_R_SUCCESS); } else write_locked = ISC_TRUE; isc_refcount_decrement(&nodelock->references, &refs); INSIST((int)refs >= 0); if (KEEP_NODE(node, rbtdb)) goto restore_locks; #undef KEEP_NODE if (write_locked) { /* * We can now delete the node. */ /* * If this node is the only one in the level it's in, deleting * this node may recursively make its parent the only node in * the parent level; if so, and if no one is currently using * the parent node, this is almost the only opportunity to * clean it up. But the recursive cleanup is not that trivial * since the child and parent may be in different lock buckets, * which would cause a lock order reversal problem. To avoid * the trouble, we'll dispatch a separate event for batch * cleaning. We need to check whether we're deleting the node * as a result of pruning to avoid infinite dispatching. * Note: pruning happens only when a task has been set for the * rbtdb. If the user of the rbtdb chooses not to set a task, * it's their responsibility to purge stale leaves (e.g. by * periodic walk-through). */ if (!pruning && node->parent != NULL && node->parent->down == node && node->left == NULL && node->right == NULL && rbtdb->task != NULL) { isc_event_t *ev; dns_db_t *db; ev = isc_event_allocate(rbtdb->common.mctx, NULL, DNS_EVENT_RBTPRUNE, prune_tree, node, sizeof(isc_event_t)); if (ev != NULL) { new_reference(rbtdb, node); db = NULL; attach((dns_db_t *)rbtdb, &db); ev->ev_sender = db; isc_task_send(rbtdb->task, &ev); no_reference = ISC_FALSE; } else { /* * XXX: this is a weird situation. We could * ignore this error case, but then the stale * node will unlikely be purged except via a * rare condition such as manual cleanup. So * we queue it in the deadnodes list, hoping * the memory shortage is temporary and the node * will be deleted later. */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_INFO, "decrement_reference: failed to " "allocate pruning event"); INSIST(node->data == NULL); INSIST(!ISC_LINK_LINKED(node, deadlink)); ISC_LIST_APPEND(rbtdb->deadnodes[bucket], node, deadlink); } } else { if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(1))) { char printname[DNS_NAME_FORMATSIZE]; isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1), "decrement_reference: " "delete from rbt: %p %s", node, dns_rbt_formatnodename(node, printname, sizeof(printname))); } delete_node(rbtdb, node); } } else { INSIST(node->data == NULL); INSIST(!ISC_LINK_LINKED(node, deadlink)); ISC_LIST_APPEND(rbtdb->deadnodes[bucket], node, deadlink); } restore_locks: /* Restore the lock? */ if (nlock == isc_rwlocktype_read) NODE_WEAKDOWNGRADE(&nodelock->lock); /* * Relock a read lock, or unlock the write lock if no lock was held. */ if (tlock == isc_rwlocktype_none) if (write_locked) RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); if (tlock == isc_rwlocktype_read) if (write_locked) isc_rwlock_downgrade(&rbtdb->tree_lock); return (no_reference); } /* * Prune the tree by recursively cleaning-up single leaves. In the worst * case, the number of iteration is the number of tree levels, which is at * most the maximum number of domain name labels, i.e, 127. In practice, this * should be much smaller (only a few times), and even the worst case would be * acceptable for a single event. */ static void prune_tree(isc_task_t *task, isc_event_t *event) { dns_rbtdb_t *rbtdb = event->ev_sender; dns_rbtnode_t *node = event->ev_arg; dns_rbtnode_t *parent; unsigned int locknum; UNUSED(task); isc_event_free(&event); RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); locknum = node->locknum; NODE_LOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write); do { parent = node->parent; decrement_reference(rbtdb, node, 0, isc_rwlocktype_write, isc_rwlocktype_write, ISC_TRUE); if (parent != NULL && parent->down == NULL) { /* * node was the only down child of the parent and has * just been removed. We'll then need to examine the * parent. Keep the lock if possible; otherwise, * release the old lock and acquire one for the parent. */ if (parent->locknum != locknum) { NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write); locknum = parent->locknum; NODE_LOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write); } /* * We need to gain a reference to the node before * decrementing it in the next iteration. In addition, * if the node is in the dead-nodes list, extract it * from the list beforehand as we do in * reactivate_node(). */ if (ISC_LINK_LINKED(parent, deadlink)) ISC_LIST_UNLINK(rbtdb->deadnodes[locknum], parent, deadlink); new_reference(rbtdb, parent); } else parent = NULL; node = parent; } while (node != NULL); NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write); RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); detach((dns_db_t **)&rbtdb); } static inline void make_least_version(dns_rbtdb_t *rbtdb, rbtdb_version_t *version, rbtdb_changedlist_t *cleanup_list) { /* * Caller must be holding the database lock. */ rbtdb->least_serial = version->serial; *cleanup_list = version->changed_list; ISC_LIST_INIT(version->changed_list); } static inline void cleanup_nondirty(rbtdb_version_t *version, rbtdb_changedlist_t *cleanup_list) { rbtdb_changed_t *changed, *next_changed; /* * If the changed record is dirty, then * an update created multiple versions of * a given rdataset. We keep this list * until we're the least open version, at * which point it's safe to get rid of any * older versions. * * If the changed record isn't dirty, then * we don't need it anymore since we're * committing and not rolling back. * * The caller must be holding the database lock. */ for (changed = HEAD(version->changed_list); changed != NULL; changed = next_changed) { next_changed = NEXT(changed, link); if (!changed->dirty) { UNLINK(version->changed_list, changed, link); APPEND(*cleanup_list, changed, link); } } } static void iszonesecure(dns_db_t *db, rbtdb_version_t *version, dns_dbnode_t *origin) { dns_rdataset_t keyset; dns_rdataset_t nsecset, signsecset; isc_boolean_t haszonekey = ISC_FALSE; isc_boolean_t hasnsec = ISC_FALSE; isc_result_t result; dns_rdataset_init(&keyset); result = dns_db_findrdataset(db, origin, version, dns_rdatatype_dnskey, 0, 0, &keyset, NULL); if (result == ISC_R_SUCCESS) { result = dns_rdataset_first(&keyset); while (result == ISC_R_SUCCESS) { dns_rdata_t keyrdata = DNS_RDATA_INIT; dns_rdataset_current(&keyset, &keyrdata); if (dns_zonekey_iszonekey(&keyrdata)) { haszonekey = ISC_TRUE; break; } result = dns_rdataset_next(&keyset); } dns_rdataset_disassociate(&keyset); } if (!haszonekey) { version->secure = dns_db_insecure; version->havensec3 = ISC_FALSE; return; } dns_rdataset_init(&nsecset); dns_rdataset_init(&signsecset); result = dns_db_findrdataset(db, origin, version, dns_rdatatype_nsec, 0, 0, &nsecset, &signsecset); if (result == ISC_R_SUCCESS) { if (dns_rdataset_isassociated(&signsecset)) { hasnsec = ISC_TRUE; dns_rdataset_disassociate(&signsecset); } dns_rdataset_disassociate(&nsecset); } setnsec3parameters(db, version); /* * Do we have a valid NSEC/NSEC3 chain? */ if (version->havensec3 || hasnsec) version->secure = dns_db_secure; else version->secure = dns_db_insecure; } /*%< * Walk the origin node looking for NSEC3PARAM records. * Cache the nsec3 parameters. */ static void setnsec3parameters(dns_db_t *db, rbtdb_version_t *version) { dns_rbtnode_t *node; dns_rdata_nsec3param_t nsec3param; dns_rdata_t rdata = DNS_RDATA_INIT; isc_region_t region; isc_result_t result; rdatasetheader_t *header, *header_next; unsigned char *raw; /* RDATASLAB */ unsigned int count, length; dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); version->havensec3 = ISC_FALSE; node = rbtdb->origin_node; NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock), isc_rwlocktype_read); for (header = node->data; header != NULL; header = header_next) { header_next = header->next; do { if (header->serial <= version->serial && !IGNORE(header)) { if (NONEXISTENT(header)) header = NULL; break; } else header = header->down; } while (header != NULL); if (header != NULL && (header->type == dns_rdatatype_nsec3param)) { /* * Find A NSEC3PARAM with a supported algorithm. */ raw = (unsigned char *)header + sizeof(*header); count = raw[0] * 256 + raw[1]; /* count */ #if DNS_RDATASET_FIXED raw += count * 4 + 2; #else raw += 2; #endif while (count-- > 0U) { length = raw[0] * 256 + raw[1]; #if DNS_RDATASET_FIXED raw += 4; #else raw += 2; #endif region.base = raw; region.length = length; raw += length; dns_rdata_fromregion(&rdata, rbtdb->common.rdclass, dns_rdatatype_nsec3param, ®ion); result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); INSIST(result == ISC_R_SUCCESS); dns_rdata_reset(&rdata); if (nsec3param.hash != DNS_NSEC3_UNKNOWNALG && !dns_nsec3_supportedhash(nsec3param.hash)) continue; if (nsec3param.flags != 0) continue; memmove(version->salt, nsec3param.salt, nsec3param.salt_length); version->hash = nsec3param.hash; version->salt_length = nsec3param.salt_length; version->iterations = nsec3param.iterations; version->flags = nsec3param.flags; version->havensec3 = ISC_TRUE; /* * Look for a better algorithm than the * unknown test algorithm. */ if (nsec3param.hash != DNS_NSEC3_UNKNOWNALG) goto unlock; } } } unlock: NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock), isc_rwlocktype_read); RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); } static void cleanup_dead_nodes_callback(isc_task_t *task, isc_event_t *event) { dns_rbtdb_t *rbtdb = event->ev_arg; isc_boolean_t again = ISC_FALSE; unsigned int locknum; unsigned int refs; RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); for (locknum = 0; locknum < rbtdb->node_lock_count; locknum++) { NODE_LOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write); cleanup_dead_nodes(rbtdb, locknum); if (ISC_LIST_HEAD(rbtdb->deadnodes[locknum]) != NULL) again = ISC_TRUE; NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write); } RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); if (again) isc_task_send(task, &event); else { isc_event_free(&event); isc_refcount_decrement(&rbtdb->references, &refs); if (refs == 0) maybe_free_rbtdb(rbtdb); } } static void closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; rbtdb_version_t *version, *cleanup_version, *least_greater; isc_boolean_t rollback = ISC_FALSE; rbtdb_changedlist_t cleanup_list; rdatasetheaderlist_t resigned_list; rbtdb_changed_t *changed, *next_changed; rbtdb_serial_t serial, least_serial; dns_rbtnode_t *rbtnode; unsigned int refs; rdatasetheader_t *header; REQUIRE(VALID_RBTDB(rbtdb)); version = (rbtdb_version_t *)*versionp; INSIST(version->rbtdb == rbtdb); cleanup_version = NULL; ISC_LIST_INIT(cleanup_list); ISC_LIST_INIT(resigned_list); isc_refcount_decrement(&version->references, &refs); if (refs > 0) { /* typical and easy case first */ if (commit) { RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read); INSIST(!version->writer); RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read); } goto end; } /* * Update the zone's secure status in version before making * it the current version. */ if (version->writer && commit && !IS_CACHE(rbtdb)) iszonesecure(db, version, rbtdb->origin_node); RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); serial = version->serial; if (version->writer) { if (commit) { unsigned cur_ref; rbtdb_version_t *cur_version; INSIST(version->commit_ok); INSIST(version == rbtdb->future_version); /* * The current version is going to be replaced. * Release the (likely last) reference to it from the * DB itself and unlink it from the open list. */ cur_version = rbtdb->current_version; isc_refcount_decrement(&cur_version->references, &cur_ref); if (cur_ref == 0) { if (cur_version->serial == rbtdb->least_serial) INSIST(EMPTY(cur_version->changed_list)); UNLINK(rbtdb->open_versions, cur_version, link); } if (EMPTY(rbtdb->open_versions)) { /* * We're going to become the least open * version. */ make_least_version(rbtdb, version, &cleanup_list); } else { /* * Some other open version is the * least version. We can't cleanup * records that were changed in this * version because the older versions * may still be in use by an open * version. * * We can, however, discard the * changed records for things that * we've added that didn't exist in * prior versions. */ cleanup_nondirty(version, &cleanup_list); } /* * If the (soon to be former) current version * isn't being used by anyone, we can clean * it up. */ if (cur_ref == 0) { cleanup_version = cur_version; APPENDLIST(version->changed_list, cleanup_version->changed_list, link); } /* * Become the current version. */ version->writer = ISC_FALSE; rbtdb->current_version = version; rbtdb->current_serial = version->serial; rbtdb->future_version = NULL; /* * Keep the current version in the open list, and * gain a reference for the DB itself (see the DB * creation function below). This must be the only * case where we need to increment the counter from * zero and need to use isc_refcount_increment0(). */ isc_refcount_increment0(&version->references, &cur_ref); INSIST(cur_ref == 1); PREPEND(rbtdb->open_versions, rbtdb->current_version, link); resigned_list = version->resigned_list; ISC_LIST_INIT(version->resigned_list); } else { /* * We're rolling back this transaction. */ cleanup_list = version->changed_list; ISC_LIST_INIT(version->changed_list); resigned_list = version->resigned_list; ISC_LIST_INIT(version->resigned_list); rollback = ISC_TRUE; cleanup_version = version; rbtdb->future_version = NULL; } } else { if (version != rbtdb->current_version) { /* * There are no external or internal references * to this version and it can be cleaned up. */ cleanup_version = version; /* * Find the version with the least serial * number greater than ours. */ least_greater = PREV(version, link); if (least_greater == NULL) least_greater = rbtdb->current_version; INSIST(version->serial < least_greater->serial); /* * Is this the least open version? */ if (version->serial == rbtdb->least_serial) { /* * Yes. Install the new least open * version. */ make_least_version(rbtdb, least_greater, &cleanup_list); } else { /* * Add any unexecuted cleanups to * those of the least greater version. */ APPENDLIST(least_greater->changed_list, version->changed_list, link); } } else if (version->serial == rbtdb->least_serial) INSIST(EMPTY(version->changed_list)); UNLINK(rbtdb->open_versions, version, link); } least_serial = rbtdb->least_serial; RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); if (cleanup_version != NULL) { INSIST(EMPTY(cleanup_version->changed_list)); isc_mem_put(rbtdb->common.mctx, cleanup_version, sizeof(*cleanup_version)); } /* * Commit/rollback re-signed headers. */ for (header = HEAD(resigned_list); header != NULL; header = HEAD(resigned_list)) { nodelock_t *lock; ISC_LIST_UNLINK(resigned_list, header, link); lock = &rbtdb->node_locks[header->node->locknum].lock; NODE_LOCK(lock, isc_rwlocktype_write); if (rollback && !IGNORE(header)) { isc_result_t result; result = resign_insert(rbtdb, header->node->locknum, header); if (result != ISC_R_SUCCESS) isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ZONE, ISC_LOG_ERROR, "Unable to reinsert header to " "re-signing heap: %s\n", dns_result_totext(result)); } decrement_reference(rbtdb, header->node, least_serial, isc_rwlocktype_write, isc_rwlocktype_none, ISC_FALSE); NODE_UNLOCK(lock, isc_rwlocktype_write); } if (!EMPTY(cleanup_list)) { isc_event_t *event = NULL; isc_rwlocktype_t tlock = isc_rwlocktype_none; if (rbtdb->task != NULL) event = isc_event_allocate(rbtdb->common.mctx, NULL, DNS_EVENT_RBTDEADNODES, cleanup_dead_nodes_callback, rbtdb, sizeof(isc_event_t)); if (event == NULL) { /* * We acquire a tree write lock here in order to make * sure that stale nodes will be removed in * decrement_reference(). If we didn't have the lock, * those nodes could miss the chance to be removed * until the server stops. The write lock is * expensive, but this event should be rare enough * to justify the cost. */ RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); tlock = isc_rwlocktype_write; } for (changed = HEAD(cleanup_list); changed != NULL; changed = next_changed) { nodelock_t *lock; next_changed = NEXT(changed, link); rbtnode = changed->node; lock = &rbtdb->node_locks[rbtnode->locknum].lock; NODE_LOCK(lock, isc_rwlocktype_write); /* * This is a good opportunity to purge any dead nodes, * so use it. */ if (event == NULL) cleanup_dead_nodes(rbtdb, rbtnode->locknum); if (rollback) rollback_node(rbtnode, serial); decrement_reference(rbtdb, rbtnode, least_serial, isc_rwlocktype_write, tlock, ISC_FALSE); NODE_UNLOCK(lock, isc_rwlocktype_write); isc_mem_put(rbtdb->common.mctx, changed, sizeof(*changed)); } if (event != NULL) { isc_refcount_increment(&rbtdb->references, NULL); isc_task_send(rbtdb->task, &event); } else RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); } end: *versionp = NULL; } /* * Add the necessary magic for the wildcard name 'name' * to be found in 'rbtdb'. * * In order for wildcard matching to work correctly in * zone_find(), we must ensure that a node for the wildcarding * level exists in the database, and has its 'find_callback' * and 'wild' bits set. * * E.g. if the wildcard name is "*.sub.example." then we * must ensure that "sub.example." exists and is marked as * a wildcard level. */ static isc_result_t add_wildcard_magic(dns_rbtdb_t *rbtdb, dns_name_t *name) { isc_result_t result; dns_name_t foundname; dns_offsets_t offsets; unsigned int n; dns_rbtnode_t *node = NULL; dns_name_init(&foundname, offsets); n = dns_name_countlabels(name); INSIST(n >= 2); n--; dns_name_getlabelsequence(name, 1, n, &foundname); result = dns_rbt_addnode(rbtdb->tree, &foundname, &node); if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) return (result); if (result == ISC_R_SUCCESS) node->nsec = DNS_RBT_NSEC_NORMAL; node->find_callback = 1; node->wild = 1; return (ISC_R_SUCCESS); } static isc_result_t add_empty_wildcards(dns_rbtdb_t *rbtdb, dns_name_t *name) { isc_result_t result; dns_name_t foundname; dns_offsets_t offsets; unsigned int n, l, i; dns_name_init(&foundname, offsets); n = dns_name_countlabels(name); l = dns_name_countlabels(&rbtdb->common.origin); i = l + 1; while (i < n) { dns_rbtnode_t *node = NULL; /* dummy */ dns_name_getlabelsequence(name, n - i, i, &foundname); if (dns_name_iswildcard(&foundname)) { result = add_wildcard_magic(rbtdb, &foundname); if (result != ISC_R_SUCCESS) return (result); result = dns_rbt_addnode(rbtdb->tree, &foundname, &node); if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) return (result); if (result == ISC_R_SUCCESS) node->nsec = DNS_RBT_NSEC_NORMAL; } i++; } return (ISC_R_SUCCESS); } static isc_result_t findnodeintree(dns_rbtdb_t *rbtdb, dns_rbt_t *tree, dns_name_t *name, isc_boolean_t create, dns_dbnode_t **nodep) { dns_rbtnode_t *node = NULL; dns_name_t nodename; isc_result_t result; isc_rwlocktype_t locktype = isc_rwlocktype_read; INSIST(tree == rbtdb->tree || tree == rbtdb->nsec3); dns_name_init(&nodename, NULL); RWLOCK(&rbtdb->tree_lock, locktype); result = dns_rbt_findnode(tree, name, NULL, &node, NULL, DNS_RBTFIND_EMPTYDATA, NULL, NULL); if (result != ISC_R_SUCCESS) { RWUNLOCK(&rbtdb->tree_lock, locktype); if (!create) { if (result == DNS_R_PARTIALMATCH) result = ISC_R_NOTFOUND; return (result); } /* * It would be nice to try to upgrade the lock instead of * unlocking then relocking. */ locktype = isc_rwlocktype_write; RWLOCK(&rbtdb->tree_lock, locktype); node = NULL; result = dns_rbt_addnode(tree, name, &node); if (result == ISC_R_SUCCESS) { dns_rbt_namefromnode(node, &nodename); #ifdef DNS_RBT_USEHASH node->locknum = node->hashval % rbtdb->node_lock_count; #else node->locknum = dns_name_hash(&nodename, ISC_TRUE) % rbtdb->node_lock_count; #endif if (tree == rbtdb->tree) { add_empty_wildcards(rbtdb, name); if (dns_name_iswildcard(name)) { result = add_wildcard_magic(rbtdb, name); if (result != ISC_R_SUCCESS) { RWUNLOCK(&rbtdb->tree_lock, locktype); return (result); } } } if (tree == rbtdb->nsec3) node->nsec = DNS_RBT_NSEC_NSEC3; } else if (result != ISC_R_EXISTS) { RWUNLOCK(&rbtdb->tree_lock, locktype); return (result); } } if (tree == rbtdb->nsec3) INSIST(node->nsec == DNS_RBT_NSEC_NSEC3); reactivate_node(rbtdb, node, locktype); /* * Always try to add the policy zone data, because this node might * already have been implicitly created by the previous addition of * a longer domain. A common example is adding *.example.com * (implicitly creating example.com) followed by explicitly adding * example.com. */ if (create && rbtdb->rpzs != NULL && tree == rbtdb->tree) { dns_fixedname_t fnamef; dns_name_t *fname; dns_fixedname_init(&fnamef); fname = dns_fixedname_name(&fnamef); dns_rbt_fullnamefromnode(node, fname); result = dns_rpz_add(rbtdb->rpzs, rbtdb->rpz_num, fname); if (result == ISC_R_SUCCESS) node->rpz = 1; if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) { /* * It is too late to give up, so merely complain. */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, "dns_rpz_add(): %s", isc_result_totext(result)); } } RWUNLOCK(&rbtdb->tree_lock, locktype); *nodep = (dns_dbnode_t *)node; return (ISC_R_SUCCESS); } static isc_result_t findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, dns_dbnode_t **nodep) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(rbtdb)); return (findnodeintree(rbtdb, rbtdb->tree, name, create, nodep)); } static isc_result_t findnsec3node(dns_db_t *db, dns_name_t *name, isc_boolean_t create, dns_dbnode_t **nodep) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(rbtdb)); return (findnodeintree(rbtdb, rbtdb->nsec3, name, create, nodep)); } static isc_result_t zone_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) { rbtdb_search_t *search = arg; rdatasetheader_t *header, *header_next; rdatasetheader_t *dname_header, *sigdname_header, *ns_header; rdatasetheader_t *found; isc_result_t result; dns_rbtnode_t *onode; /* * We only want to remember the topmost zone cut, since it's the one * that counts, so we'll just continue if we've already found a * zonecut. */ if (search->zonecut != NULL) return (DNS_R_CONTINUE); found = NULL; result = DNS_R_CONTINUE; onode = search->rbtdb->origin_node; NODE_LOCK(&(search->rbtdb->node_locks[node->locknum].lock), isc_rwlocktype_read); /* * Look for an NS or DNAME rdataset active in our version. */ ns_header = NULL; dname_header = NULL; sigdname_header = NULL; for (header = node->data; header != NULL; header = header_next) { header_next = header->next; if (header->type == dns_rdatatype_ns || header->type == dns_rdatatype_dname || header->type == RBTDB_RDATATYPE_SIGDNAME) { do { if (header->serial <= search->serial && !IGNORE(header)) { /* * Is this a "this rdataset doesn't * exist" record? */ if (NONEXISTENT(header)) header = NULL; break; } else header = header->down; } while (header != NULL); if (header != NULL) { if (header->type == dns_rdatatype_dname) dname_header = header; else if (header->type == RBTDB_RDATATYPE_SIGDNAME) sigdname_header = header; else if (node != onode || IS_STUB(search->rbtdb)) { /* * We've found an NS rdataset that * isn't at the origin node. We check * that they're not at the origin node, * because otherwise we'd erroneously * treat the zone top as if it were * a delegation. */ ns_header = header; } } } } /* * Did we find anything? */ if (!IS_CACHE(search->rbtdb) && !IS_STUB(search->rbtdb) && ns_header != NULL) { /* * Note that NS has precedence over DNAME if both exist * in a zone. Otherwise DNAME take precedence over NS. */ found = ns_header; search->zonecut_sigrdataset = NULL; } else if (dname_header != NULL) { found = dname_header; search->zonecut_sigrdataset = sigdname_header; } else if (ns_header != NULL) { found = ns_header; search->zonecut_sigrdataset = NULL; } if (found != NULL) { /* * We increment the reference count on node to ensure that * search->zonecut_rdataset will still be valid later. */ new_reference(search->rbtdb, node); search->zonecut = node; search->zonecut_rdataset = found; search->need_cleanup = ISC_TRUE; /* * Since we've found a zonecut, anything beneath it is * glue and is not subject to wildcard matching, so we * may clear search->wild. */ search->wild = ISC_FALSE; if ((search->options & DNS_DBFIND_GLUEOK) == 0) { /* * If the caller does not want to find glue, then * this is the best answer and the search should * stop now. */ result = DNS_R_PARTIALMATCH; } else { dns_name_t *zcname; /* * The search will continue beneath the zone cut. * This may or may not be the best match. In case it * is, we need to remember the node name. */ zcname = dns_fixedname_name(&search->zonecut_name); RUNTIME_CHECK(dns_name_copy(name, zcname, NULL) == ISC_R_SUCCESS); search->copy_name = ISC_TRUE; } } else { /* * There is no zonecut at this node which is active in this * version. * * If this is a "wild" node and the caller hasn't disabled * wildcard matching, remember that we've seen a wild node * in case we need to go searching for wildcard matches * later on. */ if (node->wild && (search->options & DNS_DBFIND_NOWILD) == 0) search->wild = ISC_TRUE; } NODE_UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock), isc_rwlocktype_read); return (result); } static inline void bind_rdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, rdatasetheader_t *header, isc_stdtime_t now, dns_rdataset_t *rdataset) { unsigned char *raw; /* RDATASLAB */ /* * Caller must be holding the node reader lock. * XXXJT: technically, we need a writer lock, since we'll increment * the header count below. However, since the actual counter value * doesn't matter, we prioritize performance here. (We may want to * use atomic increment when available). */ if (rdataset == NULL) return; new_reference(rbtdb, node); INSIST(rdataset->methods == NULL); /* We must be disassociated. */ rdataset->methods = &rdataset_methods; rdataset->rdclass = rbtdb->common.rdclass; rdataset->type = RBTDB_RDATATYPE_BASE(header->type); rdataset->covers = RBTDB_RDATATYPE_EXT(header->type); rdataset->ttl = header->rdh_ttl - now; rdataset->trust = header->trust; if (NEGATIVE(header)) rdataset->attributes |= DNS_RDATASETATTR_NEGATIVE; if (NXDOMAIN(header)) rdataset->attributes |= DNS_RDATASETATTR_NXDOMAIN; if (OPTOUT(header)) rdataset->attributes |= DNS_RDATASETATTR_OPTOUT; if (PREFETCH(header)) rdataset->attributes |= DNS_RDATASETATTR_PREFETCH; rdataset->private1 = rbtdb; rdataset->private2 = node; raw = (unsigned char *)header + sizeof(*header); rdataset->private3 = raw; rdataset->count = header->count++; if (rdataset->count == ISC_UINT32_MAX) rdataset->count = 0; /* * Reset iterator state. */ rdataset->privateuint4 = 0; rdataset->private5 = NULL; /* * Add noqname proof. */ rdataset->private6 = header->noqname; if (rdataset->private6 != NULL) rdataset->attributes |= DNS_RDATASETATTR_NOQNAME; rdataset->private7 = header->closest; if (rdataset->private7 != NULL) rdataset->attributes |= DNS_RDATASETATTR_CLOSEST; /* * Copy out re-signing information. */ if (RESIGN(header)) { rdataset->attributes |= DNS_RDATASETATTR_RESIGN; rdataset->resign = header->resign; } else rdataset->resign = 0; } static inline isc_result_t setup_delegation(rbtdb_search_t *search, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { isc_result_t result; dns_name_t *zcname; rbtdb_rdatatype_t type; dns_rbtnode_t *node; /* * The caller MUST NOT be holding any node locks. */ node = search->zonecut; type = search->zonecut_rdataset->type; /* * If we have to set foundname, we do it before anything else. * If we were to set foundname after we had set nodep or bound the * rdataset, then we'd have to undo that work if dns_name_copy() * failed. By setting foundname first, there's nothing to undo if * we have trouble. */ if (foundname != NULL && search->copy_name) { zcname = dns_fixedname_name(&search->zonecut_name); result = dns_name_copy(zcname, foundname, NULL); if (result != ISC_R_SUCCESS) return (result); } if (nodep != NULL) { /* * Note that we don't have to increment the node's reference * count here because we're going to use the reference we * already have in the search block. */ *nodep = node; search->need_cleanup = ISC_FALSE; } if (rdataset != NULL) { NODE_LOCK(&(search->rbtdb->node_locks[node->locknum].lock), isc_rwlocktype_read); bind_rdataset(search->rbtdb, node, search->zonecut_rdataset, search->now, rdataset); if (sigrdataset != NULL && search->zonecut_sigrdataset != NULL) bind_rdataset(search->rbtdb, node, search->zonecut_sigrdataset, search->now, sigrdataset); NODE_UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock), isc_rwlocktype_read); } if (type == dns_rdatatype_dname) return (DNS_R_DNAME); return (DNS_R_DELEGATION); } static inline isc_boolean_t valid_glue(rbtdb_search_t *search, dns_name_t *name, rbtdb_rdatatype_t type, dns_rbtnode_t *node) { unsigned char *raw; /* RDATASLAB */ unsigned int count, size; dns_name_t ns_name; isc_boolean_t valid = ISC_FALSE; dns_offsets_t offsets; isc_region_t region; rdatasetheader_t *header; /* * No additional locking is required. */ /* * Valid glue types are A, AAAA, A6. NS is also a valid glue type * if it occurs at a zone cut, but is not valid below it. */ if (type == dns_rdatatype_ns) { if (node != search->zonecut) { return (ISC_FALSE); } } else if (type != dns_rdatatype_a && type != dns_rdatatype_aaaa && type != dns_rdatatype_a6) { return (ISC_FALSE); } header = search->zonecut_rdataset; raw = (unsigned char *)header + sizeof(*header); count = raw[0] * 256 + raw[1]; #if DNS_RDATASET_FIXED raw += 2 + (4 * count); #else raw += 2; #endif while (count > 0) { count--; size = raw[0] * 256 + raw[1]; #if DNS_RDATASET_FIXED raw += 4; #else raw += 2; #endif region.base = raw; region.length = size; raw += size; /* * XXX Until we have rdata structures, we have no choice but * to directly access the rdata format. */ dns_name_init(&ns_name, offsets); dns_name_fromregion(&ns_name, ®ion); if (dns_name_compare(&ns_name, name) == 0) { valid = ISC_TRUE; break; } } return (valid); } static inline isc_boolean_t activeempty(rbtdb_search_t *search, dns_rbtnodechain_t *chain, dns_name_t *name) { dns_fixedname_t fnext; dns_fixedname_t forigin; dns_name_t *next; dns_name_t *origin; dns_name_t prefix; dns_rbtdb_t *rbtdb; dns_rbtnode_t *node; isc_result_t result; isc_boolean_t answer = ISC_FALSE; rdatasetheader_t *header; rbtdb = search->rbtdb; dns_name_init(&prefix, NULL); dns_fixedname_init(&fnext); next = dns_fixedname_name(&fnext); dns_fixedname_init(&forigin); origin = dns_fixedname_name(&forigin); result = dns_rbtnodechain_next(chain, NULL, NULL); while (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) { node = NULL; result = dns_rbtnodechain_current(chain, &prefix, origin, &node); if (result != ISC_R_SUCCESS) break; NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock), isc_rwlocktype_read); for (header = node->data; header != NULL; header = header->next) { if (header->serial <= search->serial && !IGNORE(header) && EXISTS(header)) break; } NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock), isc_rwlocktype_read); if (header != NULL) break; result = dns_rbtnodechain_next(chain, NULL, NULL); } if (result == ISC_R_SUCCESS) result = dns_name_concatenate(&prefix, origin, next, NULL); if (result == ISC_R_SUCCESS && dns_name_issubdomain(next, name)) answer = ISC_TRUE; return (answer); } static inline isc_boolean_t activeemtpynode(rbtdb_search_t *search, dns_name_t *qname, dns_name_t *wname) { dns_fixedname_t fnext; dns_fixedname_t forigin; dns_fixedname_t fprev; dns_name_t *next; dns_name_t *origin; dns_name_t *prev; dns_name_t name; dns_name_t rname; dns_name_t tname; dns_rbtdb_t *rbtdb; dns_rbtnode_t *node; dns_rbtnodechain_t chain; isc_boolean_t check_next = ISC_TRUE; isc_boolean_t check_prev = ISC_TRUE; isc_boolean_t answer = ISC_FALSE; isc_result_t result; rdatasetheader_t *header; unsigned int n; rbtdb = search->rbtdb; dns_name_init(&name, NULL); dns_name_init(&tname, NULL); dns_name_init(&rname, NULL); dns_fixedname_init(&fnext); next = dns_fixedname_name(&fnext); dns_fixedname_init(&fprev); prev = dns_fixedname_name(&fprev); dns_fixedname_init(&forigin); origin = dns_fixedname_name(&forigin); /* * Find if qname is at or below a empty node. * Use our own copy of the chain. */ chain = search->chain; do { node = NULL; result = dns_rbtnodechain_current(&chain, &name, origin, &node); if (result != ISC_R_SUCCESS) break; NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock), isc_rwlocktype_read); for (header = node->data; header != NULL; header = header->next) { if (header->serial <= search->serial && !IGNORE(header) && EXISTS(header)) break; } NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock), isc_rwlocktype_read); if (header != NULL) break; result = dns_rbtnodechain_prev(&chain, NULL, NULL); } while (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN); if (result == ISC_R_SUCCESS) result = dns_name_concatenate(&name, origin, prev, NULL); if (result != ISC_R_SUCCESS) check_prev = ISC_FALSE; result = dns_rbtnodechain_next(&chain, NULL, NULL); while (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) { node = NULL; result = dns_rbtnodechain_current(&chain, &name, origin, &node); if (result != ISC_R_SUCCESS) break; NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock), isc_rwlocktype_read); for (header = node->data; header != NULL; header = header->next) { if (header->serial <= search->serial && !IGNORE(header) && EXISTS(header)) break; } NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock), isc_rwlocktype_read); if (header != NULL) break; result = dns_rbtnodechain_next(&chain, NULL, NULL); } if (result == ISC_R_SUCCESS) result = dns_name_concatenate(&name, origin, next, NULL); if (result != ISC_R_SUCCESS) check_next = ISC_FALSE; dns_name_clone(qname, &rname); /* * Remove the wildcard label to find the terminal name. */ n = dns_name_countlabels(wname); dns_name_getlabelsequence(wname, 1, n - 1, &tname); do { if ((check_prev && dns_name_issubdomain(prev, &rname)) || (check_next && dns_name_issubdomain(next, &rname))) { answer = ISC_TRUE; break; } /* * Remove the left hand label. */ n = dns_name_countlabels(&rname); dns_name_getlabelsequence(&rname, 1, n - 1, &rname); } while (!dns_name_equal(&rname, &tname)); return (answer); } static inline isc_result_t find_wildcard(rbtdb_search_t *search, dns_rbtnode_t **nodep, dns_name_t *qname) { unsigned int i, j; dns_rbtnode_t *node, *level_node, *wnode; rdatasetheader_t *header; isc_result_t result = ISC_R_NOTFOUND; dns_name_t name; dns_name_t *wname; dns_fixedname_t fwname; dns_rbtdb_t *rbtdb; isc_boolean_t done, wild, active; dns_rbtnodechain_t wchain; /* * Caller must be holding the tree lock and MUST NOT be holding * any node locks. */ /* * Examine each ancestor level. If the level's wild bit * is set, then construct the corresponding wildcard name and * search for it. If the wildcard node exists, and is active in * this version, we're done. If not, then we next check to see * if the ancestor is active in this version. If so, then there * can be no possible wildcard match and again we're done. If not, * continue the search. */ rbtdb = search->rbtdb; i = search->chain.level_matches; done = ISC_FALSE; node = *nodep; do { NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock), isc_rwlocktype_read); /* * First we try to figure out if this node is active in * the search's version. We do this now, even though we * may not need the information, because it simplifies the * locking and code flow. */ for (header = node->data; header != NULL; header = header->next) { if (header->serial <= search->serial && !IGNORE(header) && EXISTS(header)) break; } if (header != NULL) active = ISC_TRUE; else active = ISC_FALSE; if (node->wild) wild = ISC_TRUE; else wild = ISC_FALSE; NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock), isc_rwlocktype_read); if (wild) { /* * Construct the wildcard name for this level. */ dns_name_init(&name, NULL); dns_rbt_namefromnode(node, &name); dns_fixedname_init(&fwname); wname = dns_fixedname_name(&fwname); result = dns_name_concatenate(dns_wildcardname, &name, wname, NULL); j = i; while (result == ISC_R_SUCCESS && j != 0) { j--; level_node = search->chain.levels[j]; dns_name_init(&name, NULL); dns_rbt_namefromnode(level_node, &name); result = dns_name_concatenate(wname, &name, wname, NULL); } if (result != ISC_R_SUCCESS) break; wnode = NULL; dns_rbtnodechain_init(&wchain, NULL); result = dns_rbt_findnode(rbtdb->tree, wname, NULL, &wnode, &wchain, DNS_RBTFIND_EMPTYDATA, NULL, NULL); if (result == ISC_R_SUCCESS) { nodelock_t *lock; /* * We have found the wildcard node. If it * is active in the search's version, we're * done. */ lock = &rbtdb->node_locks[wnode->locknum].lock; NODE_LOCK(lock, isc_rwlocktype_read); for (header = wnode->data; header != NULL; header = header->next) { if (header->serial <= search->serial && !IGNORE(header) && EXISTS(header)) break; } NODE_UNLOCK(lock, isc_rwlocktype_read); if (header != NULL || activeempty(search, &wchain, wname)) { if (activeemtpynode(search, qname, wname)) { return (ISC_R_NOTFOUND); } /* * The wildcard node is active! * * Note: result is still ISC_R_SUCCESS * so we don't have to set it. */ *nodep = wnode; break; } } else if (result != ISC_R_NOTFOUND && result != DNS_R_PARTIALMATCH) { /* * An error has occurred. Bail out. */ break; } } if (active) { /* * The level node is active. Any wildcarding * present at higher levels has no * effect and we're done. */ result = ISC_R_NOTFOUND; break; } if (i > 0) { i--; node = search->chain.levels[i]; } else done = ISC_TRUE; } while (!done); return (result); } static isc_boolean_t matchparams(rdatasetheader_t *header, rbtdb_search_t *search) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_nsec3_t nsec3; unsigned char *raw; /* RDATASLAB */ unsigned int rdlen, count; isc_region_t region; isc_result_t result; REQUIRE(header->type == dns_rdatatype_nsec3); raw = (unsigned char *)header + sizeof(*header); count = raw[0] * 256 + raw[1]; /* count */ #if DNS_RDATASET_FIXED raw += count * 4 + 2; #else raw += 2; #endif while (count-- > 0) { rdlen = raw[0] * 256 + raw[1]; #if DNS_RDATASET_FIXED raw += 4; #else raw += 2; #endif region.base = raw; region.length = rdlen; dns_rdata_fromregion(&rdata, search->rbtdb->common.rdclass, dns_rdatatype_nsec3, ®ion); raw += rdlen; result = dns_rdata_tostruct(&rdata, &nsec3, NULL); INSIST(result == ISC_R_SUCCESS); if (nsec3.hash == search->rbtversion->hash && nsec3.iterations == search->rbtversion->iterations && nsec3.salt_length == search->rbtversion->salt_length && memcmp(nsec3.salt, search->rbtversion->salt, nsec3.salt_length) == 0) return (ISC_TRUE); dns_rdata_reset(&rdata); } return (ISC_FALSE); } /* * Find node of the NSEC/NSEC3 record that is 'name'. */ static inline isc_result_t previous_closest_nsec(dns_rdatatype_t type, rbtdb_search_t *search, dns_name_t *name, dns_name_t *origin, dns_rbtnode_t **nodep, dns_rbtnodechain_t *nsecchain, isc_boolean_t *firstp) { dns_fixedname_t ftarget; dns_name_t *target; dns_rbtnode_t *nsecnode; isc_result_t result; REQUIRE(nodep != NULL && *nodep == NULL); if (type == dns_rdatatype_nsec3) { result = dns_rbtnodechain_prev(&search->chain, NULL, NULL); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) return (result); result = dns_rbtnodechain_current(&search->chain, name, origin, nodep); return (result); } dns_fixedname_init(&ftarget); target = dns_fixedname_name(&ftarget); for (;;) { if (*firstp) { /* * Construct the name of the second node to check. * It is the first node sought in the NSEC tree. */ *firstp = ISC_FALSE; dns_rbtnodechain_init(nsecchain, NULL); result = dns_name_concatenate(name, origin, target, NULL); if (result != ISC_R_SUCCESS) return (result); nsecnode = NULL; result = dns_rbt_findnode(search->rbtdb->nsec, target, NULL, &nsecnode, nsecchain, DNS_RBTFIND_NOOPTIONS, NULL, NULL); if (result == ISC_R_SUCCESS) { /* * Since this was the first loop, finding the * name in the NSEC tree implies that the first * node checked in the main tree had an * unacceptable NSEC record. * Try the previous node in the NSEC tree. */ result = dns_rbtnodechain_prev(nsecchain, name, origin); if (result == DNS_R_NEWORIGIN) result = ISC_R_SUCCESS; } else if (result == ISC_R_NOTFOUND || result == DNS_R_PARTIALMATCH) { result = dns_rbtnodechain_current(nsecchain, name, origin, NULL); if (result == ISC_R_NOTFOUND) result = ISC_R_NOMORE; } } else { /* * This is a second or later trip through the auxiliary * tree for the name of a third or earlier NSEC node in * the main tree. Previous trips through the NSEC tree * must have found nodes in the main tree with NSEC * records. Perhaps they lacked signature records. */ result = dns_rbtnodechain_prev(nsecchain, name, origin); if (result == DNS_R_NEWORIGIN) result = ISC_R_SUCCESS; } if (result != ISC_R_SUCCESS) return (result); /* * Construct the name to seek in the main tree. */ result = dns_name_concatenate(name, origin, target, NULL); if (result != ISC_R_SUCCESS) return (result); *nodep = NULL; result = dns_rbt_findnode(search->rbtdb->tree, target, NULL, nodep, &search->chain, DNS_RBTFIND_NOOPTIONS, NULL, NULL); if (result == ISC_R_SUCCESS) return (result); /* * There should always be a node in the main tree with the * same name as the node in the auxiliary NSEC tree, except for * nodes in the auxiliary tree that are awaiting deletion. */ if (result != DNS_R_PARTIALMATCH && result != ISC_R_NOTFOUND) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_ERROR, "previous_closest_nsec(): %s", isc_result_totext(result)); return (DNS_R_BADDB); } } } /* * Find the NSEC/NSEC3 which is or before the current point on the * search chain. For NSEC3 records only NSEC3 records that match the * current NSEC3PARAM record are considered. */ static inline isc_result_t find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, dns_rbt_t *tree, dns_db_secure_t secure) { dns_rbtnode_t *node, *prevnode; rdatasetheader_t *header, *header_next, *found, *foundsig; dns_rbtnodechain_t nsecchain; isc_boolean_t empty_node; isc_result_t result; dns_fixedname_t fname, forigin; dns_name_t *name, *origin; dns_rdatatype_t type; rbtdb_rdatatype_t sigtype; isc_boolean_t wraps; isc_boolean_t first = ISC_TRUE; isc_boolean_t need_sig = ISC_TF(secure == dns_db_secure); if (tree == search->rbtdb->nsec3) { type = dns_rdatatype_nsec3; sigtype = RBTDB_RDATATYPE_SIGNSEC3; wraps = ISC_TRUE; } else { type = dns_rdatatype_nsec; sigtype = RBTDB_RDATATYPE_SIGNSEC; wraps = ISC_FALSE; } /* * Use the auxiliary tree only starting with the second node in the * hope that the original node will be right much of the time. */ dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_fixedname_init(&forigin); origin = dns_fixedname_name(&forigin); again: node = NULL; prevnode = NULL; result = dns_rbtnodechain_current(&search->chain, name, origin, &node); if (result != ISC_R_SUCCESS) return (result); do { NODE_LOCK(&(search->rbtdb->node_locks[node->locknum].lock), isc_rwlocktype_read); found = NULL; foundsig = NULL; empty_node = ISC_TRUE; for (header = node->data; header != NULL; header = header_next) { header_next = header->next; /* * Look for an active, extant NSEC or RRSIG NSEC. */ do { if (header->serial <= search->serial && !IGNORE(header)) { /* * Is this a "this rdataset doesn't * exist" record? */ if (NONEXISTENT(header)) header = NULL; break; } else header = header->down; } while (header != NULL); if (header != NULL) { /* * We now know that there is at least one * active rdataset at this node. */ empty_node = ISC_FALSE; if (header->type == type) { found = header; if (foundsig != NULL) break; } else if (header->type == sigtype) { foundsig = header; if (found != NULL) break; } } } if (!empty_node) { if (found != NULL && search->rbtversion->havensec3 && found->type == dns_rdatatype_nsec3 && !matchparams(found, search)) { empty_node = ISC_TRUE; found = NULL; foundsig = NULL; result = previous_closest_nsec(type, search, name, origin, &prevnode, NULL, NULL); } else if (found != NULL && (foundsig != NULL || !need_sig)) { /* * We've found the right NSEC/NSEC3 record. * * Note: for this to really be the right * NSEC record, it's essential that the NSEC * records of any nodes obscured by a zone * cut have been removed; we assume this is * the case. */ result = dns_name_concatenate(name, origin, foundname, NULL); if (result == ISC_R_SUCCESS) { if (nodep != NULL) { new_reference(search->rbtdb, node); *nodep = node; } bind_rdataset(search->rbtdb, node, found, search->now, rdataset); if (foundsig != NULL) bind_rdataset(search->rbtdb, node, foundsig, search->now, sigrdataset); } } else if (found == NULL && foundsig == NULL) { /* * This node is active, but has no NSEC or * RRSIG NSEC. That means it's glue or * other obscured zone data that isn't * relevant for our search. Treat the * node as if it were empty and keep looking. */ empty_node = ISC_TRUE; result = previous_closest_nsec(type, search, name, origin, &prevnode, &nsecchain, &first); } else { /* * We found an active node, but either the * NSEC or the RRSIG NSEC is missing. This * shouldn't happen. */ result = DNS_R_BADDB; } } else { /* * This node isn't active. We've got to keep * looking. */ result = previous_closest_nsec(type, search, name, origin, &prevnode, &nsecchain, &first); } NODE_UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock), isc_rwlocktype_read); node = prevnode; prevnode = NULL; } while (empty_node && result == ISC_R_SUCCESS); if (!first) dns_rbtnodechain_invalidate(&nsecchain); if (result == ISC_R_NOMORE && wraps) { result = dns_rbtnodechain_last(&search->chain, tree, NULL, NULL); if (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) { wraps = ISC_FALSE; goto again; } } /* * If the result is ISC_R_NOMORE, then we got to the beginning of * the database and didn't find a NSEC record. This shouldn't * happen. */ if (result == ISC_R_NOMORE) result = DNS_R_BADDB; return (result); } static isc_result_t zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { dns_rbtnode_t *node = NULL; isc_result_t result; rbtdb_search_t search; isc_boolean_t cname_ok = ISC_TRUE; isc_boolean_t close_version = ISC_FALSE; isc_boolean_t maybe_zonecut = ISC_FALSE; isc_boolean_t at_zonecut = ISC_FALSE; isc_boolean_t wild; isc_boolean_t empty_node; rdatasetheader_t *header, *header_next, *found, *nsecheader; rdatasetheader_t *foundsig, *cnamesig, *nsecsig; rbtdb_rdatatype_t sigtype; isc_boolean_t active; dns_rbtnodechain_t chain; nodelock_t *lock; dns_rbt_t *tree; search.rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(search.rbtdb)); INSIST(version == NULL || ((rbtdb_version_t *)version)->rbtdb == (dns_rbtdb_t *)db); /* * We don't care about 'now'. */ UNUSED(now); /* * If the caller didn't supply a version, attach to the current * version. */ if (version == NULL) { currentversion(db, &version); close_version = ISC_TRUE; } search.rbtversion = version; search.serial = search.rbtversion->serial; search.options = options; search.copy_name = ISC_FALSE; search.need_cleanup = ISC_FALSE; search.wild = ISC_FALSE; search.zonecut = NULL; dns_fixedname_init(&search.zonecut_name); dns_rbtnodechain_init(&search.chain, search.rbtdb->common.mctx); search.now = 0; /* * 'wild' will be true iff. we've matched a wildcard. */ wild = ISC_FALSE; RWLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read); /* * Search down from the root of the tree. If, while going down, we * encounter a callback node, zone_zonecut_callback() will search the * rdatasets at the zone cut for active DNAME or NS rdatasets. */ tree = (options & DNS_DBFIND_FORCENSEC3) != 0 ? search.rbtdb->nsec3 : search.rbtdb->tree; result = dns_rbt_findnode(tree, name, foundname, &node, &search.chain, DNS_RBTFIND_EMPTYDATA, zone_zonecut_callback, &search); if (result == DNS_R_PARTIALMATCH) { partial_match: if (search.zonecut != NULL) { result = setup_delegation(&search, nodep, foundname, rdataset, sigrdataset); goto tree_exit; } if (search.wild) { /* * At least one of the levels in the search chain * potentially has a wildcard. For each such level, * we must see if there's a matching wildcard active * in the current version. */ result = find_wildcard(&search, &node, name); if (result == ISC_R_SUCCESS) { result = dns_name_copy(name, foundname, NULL); if (result != ISC_R_SUCCESS) goto tree_exit; wild = ISC_TRUE; goto found; } else if (result != ISC_R_NOTFOUND) goto tree_exit; } chain = search.chain; active = activeempty(&search, &chain, name); /* * If we're here, then the name does not exist, is not * beneath a zonecut, and there's no matching wildcard. */ if ((search.rbtversion->secure == dns_db_secure && !search.rbtversion->havensec3) || (search.options & DNS_DBFIND_FORCENSEC) != 0 || (search.options & DNS_DBFIND_FORCENSEC3) != 0) { result = find_closest_nsec(&search, nodep, foundname, rdataset, sigrdataset, tree, search.rbtversion->secure); if (result == ISC_R_SUCCESS) result = active ? DNS_R_EMPTYNAME : DNS_R_NXDOMAIN; } else result = active ? DNS_R_EMPTYNAME : DNS_R_NXDOMAIN; goto tree_exit; } else if (result != ISC_R_SUCCESS) goto tree_exit; found: /* * We have found a node whose name is the desired name, or we * have matched a wildcard. */ if (search.zonecut != NULL) { /* * If we're beneath a zone cut, we don't want to look for * CNAMEs because they're not legitimate zone glue. */ cname_ok = ISC_FALSE; } else { /* * The node may be a zone cut itself. If it might be one, * make sure we check for it later. * * DS records live above the zone cut in ordinary zone so * we want to ignore any referral. * * Stub zones don't have anything "above" the delgation so * we always return a referral. */ if (node->find_callback && ((node != search.rbtdb->origin_node && !dns_rdatatype_atparent(type)) || IS_STUB(search.rbtdb))) maybe_zonecut = ISC_TRUE; } /* * Certain DNSSEC types are not subject to CNAME matching * (RFC4035, section 2.5 and RFC3007). * * We don't check for RRSIG, because we don't store RRSIG records * directly. */ if (type == dns_rdatatype_key || type == dns_rdatatype_nsec) cname_ok = ISC_FALSE; /* * We now go looking for rdata... */ lock = &search.rbtdb->node_locks[node->locknum].lock; NODE_LOCK(lock, isc_rwlocktype_read); found = NULL; foundsig = NULL; sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, type); nsecheader = NULL; nsecsig = NULL; cnamesig = NULL; empty_node = ISC_TRUE; for (header = node->data; header != NULL; header = header_next) { header_next = header->next; /* * Look for an active, extant rdataset. */ do { if (header->serial <= search.serial && !IGNORE(header)) { /* * Is this a "this rdataset doesn't * exist" record? */ if (NONEXISTENT(header)) header = NULL; break; } else header = header->down; } while (header != NULL); if (header != NULL) { /* * We now know that there is at least one active * rdataset at this node. */ empty_node = ISC_FALSE; /* * Do special zone cut handling, if requested. */ if (maybe_zonecut && header->type == dns_rdatatype_ns) { /* * We increment the reference count on node to * ensure that search->zonecut_rdataset will * still be valid later. */ new_reference(search.rbtdb, node); search.zonecut = node; search.zonecut_rdataset = header; search.zonecut_sigrdataset = NULL; search.need_cleanup = ISC_TRUE; maybe_zonecut = ISC_FALSE; at_zonecut = ISC_TRUE; /* * It is not clear if KEY should still be * allowed at the parent side of the zone * cut or not. It is needed for RFC3007 * validated updates. */ if ((search.options & DNS_DBFIND_GLUEOK) == 0 && type != dns_rdatatype_nsec && type != dns_rdatatype_key) { /* * Glue is not OK, but any answer we * could return would be glue. Return * the delegation. */ found = NULL; break; } if (found != NULL && foundsig != NULL) break; } /* * If the NSEC3 record doesn't match the chain * we are using behave as if it isn't here. */ if (header->type == dns_rdatatype_nsec3 && !matchparams(header, &search)) { NODE_UNLOCK(lock, isc_rwlocktype_read); goto partial_match; } /* * If we found a type we were looking for, * remember it. */ if (header->type == type || type == dns_rdatatype_any || (header->type == dns_rdatatype_cname && cname_ok)) { /* * We've found the answer! */ found = header; if (header->type == dns_rdatatype_cname && cname_ok) { /* * We may be finding a CNAME instead * of the desired type. * * If we've already got the CNAME RRSIG, * use it, otherwise change sigtype * so that we find it. */ if (cnamesig != NULL) foundsig = cnamesig; else sigtype = RBTDB_RDATATYPE_SIGCNAME; } /* * If we've got all we need, end the search. */ if (!maybe_zonecut && foundsig != NULL) break; } else if (header->type == sigtype) { /* * We've found the RRSIG rdataset for our * target type. Remember it. */ foundsig = header; /* * If we've got all we need, end the search. */ if (!maybe_zonecut && found != NULL) break; } else if (header->type == dns_rdatatype_nsec && !search.rbtversion->havensec3) { /* * Remember a NSEC rdataset even if we're * not specifically looking for it, because * we might need it later. */ nsecheader = header; } else if (header->type == RBTDB_RDATATYPE_SIGNSEC && !search.rbtversion->havensec3) { /* * If we need the NSEC rdataset, we'll also * need its signature. */ nsecsig = header; } else if (cname_ok && header->type == RBTDB_RDATATYPE_SIGCNAME) { /* * If we get a CNAME match, we'll also need * its signature. */ cnamesig = header; } } } if (empty_node) { /* * We have an exact match for the name, but there are no * active rdatasets in the desired version. That means that * this node doesn't exist in the desired version, and that * we really have a partial match. */ if (!wild) { NODE_UNLOCK(lock, isc_rwlocktype_read); goto partial_match; } } /* * If we didn't find what we were looking for... */ if (found == NULL) { if (search.zonecut != NULL) { /* * We were trying to find glue at a node beneath a * zone cut, but didn't. * * Return the delegation. */ NODE_UNLOCK(lock, isc_rwlocktype_read); result = setup_delegation(&search, nodep, foundname, rdataset, sigrdataset); goto tree_exit; } /* * The desired type doesn't exist. */ result = DNS_R_NXRRSET; if (search.rbtversion->secure == dns_db_secure && !search.rbtversion->havensec3 && (nsecheader == NULL || nsecsig == NULL)) { /* * The zone is secure but there's no NSEC, * or the NSEC has no signature! */ if (!wild) { result = DNS_R_BADDB; goto node_exit; } NODE_UNLOCK(lock, isc_rwlocktype_read); result = find_closest_nsec(&search, nodep, foundname, rdataset, sigrdataset, search.rbtdb->tree, search.rbtversion->secure); if (result == ISC_R_SUCCESS) result = DNS_R_EMPTYWILD; goto tree_exit; } if ((search.options & DNS_DBFIND_FORCENSEC) != 0 && nsecheader == NULL) { /* * There's no NSEC record, and we were told * to find one. */ result = DNS_R_BADDB; goto node_exit; } if (nodep != NULL) { new_reference(search.rbtdb, node); *nodep = node; } if ((search.rbtversion->secure == dns_db_secure && !search.rbtversion->havensec3) || (search.options & DNS_DBFIND_FORCENSEC) != 0) { bind_rdataset(search.rbtdb, node, nsecheader, 0, rdataset); if (nsecsig != NULL) bind_rdataset(search.rbtdb, node, nsecsig, 0, sigrdataset); } if (wild) foundname->attributes |= DNS_NAMEATTR_WILDCARD; goto node_exit; } /* * We found what we were looking for, or we found a CNAME. */ if (type != found->type && type != dns_rdatatype_any && found->type == dns_rdatatype_cname) { /* * We weren't doing an ANY query and we found a CNAME instead * of the type we were looking for, so we need to indicate * that result to the caller. */ result = DNS_R_CNAME; } else if (search.zonecut != NULL) { /* * If we're beneath a zone cut, we must indicate that the * result is glue, unless we're actually at the zone cut * and the type is NSEC or KEY. */ if (search.zonecut == node) { /* * It is not clear if KEY should still be * allowed at the parent side of the zone * cut or not. It is needed for RFC3007 * validated updates. */ if (type == dns_rdatatype_nsec || type == dns_rdatatype_nsec3 || type == dns_rdatatype_key) result = ISC_R_SUCCESS; else if (type == dns_rdatatype_any) result = DNS_R_ZONECUT; else result = DNS_R_GLUE; } else result = DNS_R_GLUE; /* * We might have found data that isn't glue, but was occluded * by a dynamic update. If the caller cares about this, they * will have told us to validate glue. * * XXX We should cache the glue validity state! */ if (result == DNS_R_GLUE && (search.options & DNS_DBFIND_VALIDATEGLUE) != 0 && !valid_glue(&search, foundname, type, node)) { NODE_UNLOCK(lock, isc_rwlocktype_read); result = setup_delegation(&search, nodep, foundname, rdataset, sigrdataset); goto tree_exit; } } else { /* * An ordinary successful query! */ result = ISC_R_SUCCESS; } if (nodep != NULL) { if (!at_zonecut) new_reference(search.rbtdb, node); else search.need_cleanup = ISC_FALSE; *nodep = node; } if (type != dns_rdatatype_any) { bind_rdataset(search.rbtdb, node, found, 0, rdataset); if (foundsig != NULL) bind_rdataset(search.rbtdb, node, foundsig, 0, sigrdataset); } if (wild) foundname->attributes |= DNS_NAMEATTR_WILDCARD; node_exit: NODE_UNLOCK(lock, isc_rwlocktype_read); tree_exit: RWUNLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read); /* * If we found a zonecut but aren't going to use it, we have to * let go of it. */ if (search.need_cleanup) { node = search.zonecut; INSIST(node != NULL); lock = &(search.rbtdb->node_locks[node->locknum].lock); NODE_LOCK(lock, isc_rwlocktype_read); decrement_reference(search.rbtdb, node, 0, isc_rwlocktype_read, isc_rwlocktype_none, ISC_FALSE); NODE_UNLOCK(lock, isc_rwlocktype_read); } if (close_version) closeversion(db, &version, ISC_FALSE); dns_rbtnodechain_reset(&search.chain); return (result); } static isc_result_t zone_findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { UNUSED(db); UNUSED(name); UNUSED(options); UNUSED(now); UNUSED(nodep); UNUSED(foundname); UNUSED(rdataset); UNUSED(sigrdataset); FATAL_ERROR(__FILE__, __LINE__, "zone_findzonecut() called!"); /* NOTREACHED */ return (ISC_R_NOTIMPLEMENTED); } static isc_boolean_t check_stale_rdataset(dns_rbtnode_t *node, rdatasetheader_t *header, isc_rwlocktype_t *locktype, nodelock_t *lock, rbtdb_search_t *search, rdatasetheader_t **header_prev) { #if !defined(ISC_RWLOCK_USEATOMIC) || !defined(DNS_RBT_USEISCREFCOUNT) UNUSED(lock); #endif if (header->rdh_ttl < search->now) { /* * This rdataset is stale. If no one else is using the * node, we can clean it up right now, otherwise we mark * it as stale, and the node as dirty, so it will get * cleaned up later. */ if ((header->rdh_ttl < search->now - RBTDB_VIRTUAL) && (*locktype == isc_rwlocktype_write || NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) { /* * We update the node's status only when we can * get write access; otherwise, we leave others * to this work. Periodical cleaning will * eventually take the job as the last resort. * We won't downgrade the lock, since other * rdatasets are probably stale, too. */ *locktype = isc_rwlocktype_write; if (dns_rbtnode_refcurrent(node) == 0) { isc_mem_t *mctx; /* * header->down can be non-NULL if the * refcount has just decremented to 0 * but decrement_reference() has not * performed clean_cache_node(), in * which case we need to purge the stale * headers first. */ mctx = search->rbtdb->common.mctx; clean_stale_headers(search->rbtdb, mctx, header); if (*header_prev != NULL) (*header_prev)->next = header->next; else node->data = header->next; free_rdataset(search->rbtdb, mctx, header); } else { mark_stale_header(search->rbtdb, header); *header_prev = header; } } else *header_prev = header; return (ISC_TRUE); } return (ISC_FALSE); } static isc_result_t cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) { rbtdb_search_t *search = arg; rdatasetheader_t *header, *header_prev, *header_next; rdatasetheader_t *dname_header, *sigdname_header; isc_result_t result; nodelock_t *lock; isc_rwlocktype_t locktype; /* XXX comment */ REQUIRE(search->zonecut == NULL); /* * Keep compiler silent. */ UNUSED(name); lock = &(search->rbtdb->node_locks[node->locknum].lock); locktype = isc_rwlocktype_read; NODE_LOCK(lock, locktype); /* * Look for a DNAME or RRSIG DNAME rdataset. */ dname_header = NULL; sigdname_header = NULL; header_prev = NULL; for (header = node->data; header != NULL; header = header_next) { header_next = header->next; if (check_stale_rdataset(node, header, &locktype, lock, search, &header_prev)) { /* Do nothing. */ } else if (header->type == dns_rdatatype_dname && EXISTS(header)) { dname_header = header; header_prev = header; } else if (header->type == RBTDB_RDATATYPE_SIGDNAME && EXISTS(header)) { sigdname_header = header; header_prev = header; } else header_prev = header; } if (dname_header != NULL && (!DNS_TRUST_PENDING(dname_header->trust) || (search->options & DNS_DBFIND_PENDINGOK) != 0)) { /* * We increment the reference count on node to ensure that * search->zonecut_rdataset will still be valid later. */ new_reference(search->rbtdb, node); INSIST(!ISC_LINK_LINKED(node, deadlink)); search->zonecut = node; search->zonecut_rdataset = dname_header; search->zonecut_sigrdataset = sigdname_header; search->need_cleanup = ISC_TRUE; result = DNS_R_PARTIALMATCH; } else result = DNS_R_CONTINUE; NODE_UNLOCK(lock, locktype); return (result); } static inline isc_result_t find_deepest_zonecut(rbtdb_search_t *search, dns_rbtnode_t *node, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { unsigned int i; dns_rbtnode_t *level_node; rdatasetheader_t *header, *header_prev, *header_next; rdatasetheader_t *found, *foundsig; isc_result_t result = ISC_R_NOTFOUND; dns_name_t name; dns_rbtdb_t *rbtdb; isc_boolean_t done; nodelock_t *lock; isc_rwlocktype_t locktype; /* * Caller must be holding the tree lock. */ rbtdb = search->rbtdb; i = search->chain.level_matches; done = ISC_FALSE; do { locktype = isc_rwlocktype_read; lock = &rbtdb->node_locks[node->locknum].lock; NODE_LOCK(lock, locktype); /* * Look for NS and RRSIG NS rdatasets. */ found = NULL; foundsig = NULL; header_prev = NULL; for (header = node->data; header != NULL; header = header_next) { header_next = header->next; if (check_stale_rdataset(node, header, &locktype, lock, search, &header_prev)) { /* Do nothing. */ } else if (EXISTS(header)) { /* * We've found an extant rdataset. See if * we're interested in it. */ if (header->type == dns_rdatatype_ns) { found = header; if (foundsig != NULL) break; } else if (header->type == RBTDB_RDATATYPE_SIGNS) { foundsig = header; if (found != NULL) break; } header_prev = header; } else header_prev = header; } if (found != NULL) { /* * If we have to set foundname, we do it before * anything else. If we were to set foundname after * we had set nodep or bound the rdataset, then we'd * have to undo that work if dns_name_concatenate() * failed. By setting foundname first, there's * nothing to undo if we have trouble. */ if (foundname != NULL) { dns_name_init(&name, NULL); dns_rbt_namefromnode(node, &name); result = dns_name_copy(&name, foundname, NULL); while (result == ISC_R_SUCCESS && i > 0) { i--; level_node = search->chain.levels[i]; dns_name_init(&name, NULL); dns_rbt_namefromnode(level_node, &name); result = dns_name_concatenate(foundname, &name, foundname, NULL); } if (result != ISC_R_SUCCESS) { *nodep = NULL; goto node_exit; } } result = DNS_R_DELEGATION; if (nodep != NULL) { new_reference(search->rbtdb, node); *nodep = node; } bind_rdataset(search->rbtdb, node, found, search->now, rdataset); if (foundsig != NULL) bind_rdataset(search->rbtdb, node, foundsig, search->now, sigrdataset); if (need_headerupdate(found, search->now) || (foundsig != NULL && need_headerupdate(foundsig, search->now))) { if (locktype != isc_rwlocktype_write) { NODE_UNLOCK(lock, locktype); NODE_LOCK(lock, isc_rwlocktype_write); locktype = isc_rwlocktype_write; POST(locktype); } if (need_headerupdate(found, search->now)) update_header(search->rbtdb, found, search->now); if (foundsig != NULL && need_headerupdate(foundsig, search->now)) { update_header(search->rbtdb, foundsig, search->now); } } } node_exit: NODE_UNLOCK(lock, locktype); if (found == NULL && i > 0) { i--; node = search->chain.levels[i]; } else done = ISC_TRUE; } while (!done); return (result); } static isc_result_t find_coveringnsec(rbtdb_search_t *search, dns_dbnode_t **nodep, isc_stdtime_t now, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { dns_rbtnode_t *node; rdatasetheader_t *header, *header_next, *header_prev; rdatasetheader_t *found, *foundsig; isc_boolean_t empty_node; isc_result_t result; dns_fixedname_t fname, forigin; dns_name_t *name, *origin; rbtdb_rdatatype_t matchtype, sigmatchtype; nodelock_t *lock; isc_rwlocktype_t locktype; matchtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_nsec, 0); sigmatchtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_nsec); do { node = NULL; dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_fixedname_init(&forigin); origin = dns_fixedname_name(&forigin); result = dns_rbtnodechain_current(&search->chain, name, origin, &node); if (result != ISC_R_SUCCESS) return (result); locktype = isc_rwlocktype_read; lock = &(search->rbtdb->node_locks[node->locknum].lock); NODE_LOCK(lock, locktype); found = NULL; foundsig = NULL; empty_node = ISC_TRUE; header_prev = NULL; for (header = node->data; header != NULL; header = header_next) { header_next = header->next; if (check_stale_rdataset(node, header, &locktype, lock, search, &header_prev)) { continue; } if (NONEXISTENT(header) || RBTDB_RDATATYPE_BASE(header->type) == 0) { header_prev = header; continue; } empty_node = ISC_FALSE; if (header->type == matchtype) found = header; else if (header->type == sigmatchtype) foundsig = header; header_prev = header; } if (found != NULL) { result = dns_name_concatenate(name, origin, foundname, NULL); if (result != ISC_R_SUCCESS) goto unlock_node; bind_rdataset(search->rbtdb, node, found, now, rdataset); if (foundsig != NULL) bind_rdataset(search->rbtdb, node, foundsig, now, sigrdataset); new_reference(search->rbtdb, node); *nodep = node; result = DNS_R_COVERINGNSEC; } else if (!empty_node) { result = ISC_R_NOTFOUND; } else result = dns_rbtnodechain_prev(&search->chain, NULL, NULL); unlock_node: NODE_UNLOCK(lock, locktype); } while (empty_node && result == ISC_R_SUCCESS); return (result); } /* * Connect this RBTDB to the response policy zone summary data for the view. */ static void rpz_attach(dns_db_t *db, dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num) { dns_rbtdb_t * rbtdb; rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(rbtdb)); RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); REQUIRE(rbtdb->rpzs == NULL && rbtdb->rpz_num == DNS_RPZ_INVALID_NUM); dns_rpz_attach_rpzs(rpzs, &rbtdb->rpzs); rbtdb->rpz_num = rpz_num; RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); } /* * Enable this RBTDB as a response policy zone. */ static isc_result_t rpz_ready(dns_db_t *db) { dns_rbtdb_t * rbtdb; isc_result_t result; rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(rbtdb)); RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); if (rbtdb->rpzs == NULL) { INSIST(rbtdb->rpz_num == DNS_RPZ_INVALID_NUM); result = ISC_R_SUCCESS; } else { result = dns_rpz_ready(rbtdb->rpzs, &rbtdb->load_rpzs, rbtdb->rpz_num); } RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); return (result); } static isc_result_t cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { dns_rbtnode_t *node = NULL; isc_result_t result; rbtdb_search_t search; isc_boolean_t cname_ok = ISC_TRUE; isc_boolean_t empty_node; nodelock_t *lock; isc_rwlocktype_t locktype; rdatasetheader_t *header, *header_prev, *header_next; rdatasetheader_t *found, *nsheader; rdatasetheader_t *foundsig, *nssig, *cnamesig; rdatasetheader_t *update, *updatesig; rbtdb_rdatatype_t sigtype, negtype; UNUSED(version); search.rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(search.rbtdb)); REQUIRE(version == NULL); if (now == 0) isc_stdtime_get(&now); search.rbtversion = NULL; search.serial = 1; search.options = options; search.copy_name = ISC_FALSE; search.need_cleanup = ISC_FALSE; search.wild = ISC_FALSE; search.zonecut = NULL; dns_fixedname_init(&search.zonecut_name); dns_rbtnodechain_init(&search.chain, search.rbtdb->common.mctx); search.now = now; update = NULL; updatesig = NULL; RWLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read); /* * Search down from the root of the tree. If, while going down, we * encounter a callback node, cache_zonecut_callback() will search the * rdatasets at the zone cut for a DNAME rdataset. */ result = dns_rbt_findnode(search.rbtdb->tree, name, foundname, &node, &search.chain, DNS_RBTFIND_EMPTYDATA, cache_zonecut_callback, &search); if (result == DNS_R_PARTIALMATCH) { if ((search.options & DNS_DBFIND_COVERINGNSEC) != 0) { result = find_coveringnsec(&search, nodep, now, foundname, rdataset, sigrdataset); if (result == DNS_R_COVERINGNSEC) goto tree_exit; } if (search.zonecut != NULL) { result = setup_delegation(&search, nodep, foundname, rdataset, sigrdataset); goto tree_exit; } else { find_ns: result = find_deepest_zonecut(&search, node, nodep, foundname, rdataset, sigrdataset); goto tree_exit; } } else if (result != ISC_R_SUCCESS) goto tree_exit; /* * Certain DNSSEC types are not subject to CNAME matching * (RFC4035, section 2.5 and RFC3007). * * We don't check for RRSIG, because we don't store RRSIG records * directly. */ if (type == dns_rdatatype_key || type == dns_rdatatype_nsec) cname_ok = ISC_FALSE; /* * We now go looking for rdata... */ lock = &(search.rbtdb->node_locks[node->locknum].lock); locktype = isc_rwlocktype_read; NODE_LOCK(lock, locktype); found = NULL; foundsig = NULL; sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, type); negtype = RBTDB_RDATATYPE_VALUE(0, type); nsheader = NULL; nssig = NULL; cnamesig = NULL; empty_node = ISC_TRUE; header_prev = NULL; for (header = node->data; header != NULL; header = header_next) { header_next = header->next; if (check_stale_rdataset(node, header, &locktype, lock, &search, &header_prev)) { /* Do nothing. */ } else if (EXISTS(header)) { /* * We now know that there is at least one active * non-stale rdataset at this node. */ empty_node = ISC_FALSE; /* * If we found a type we were looking for, remember * it. */ if (header->type == type || (type == dns_rdatatype_any && RBTDB_RDATATYPE_BASE(header->type) != 0) || (cname_ok && header->type == dns_rdatatype_cname)) { /* * We've found the answer. */ found = header; if (header->type == dns_rdatatype_cname && cname_ok && cnamesig != NULL) { /* * If we've already got the * CNAME RRSIG, use it. */ foundsig = cnamesig; } } else if (header->type == sigtype) { /* * We've found the RRSIG rdataset for our * target type. Remember it. */ foundsig = header; } else if (header->type == RBTDB_RDATATYPE_NCACHEANY || header->type == negtype) { /* * We've found a negative cache entry. */ found = header; } else if (header->type == dns_rdatatype_ns) { /* * Remember a NS rdataset even if we're * not specifically looking for it, because * we might need it later. */ nsheader = header; } else if (header->type == RBTDB_RDATATYPE_SIGNS) { /* * If we need the NS rdataset, we'll also * need its signature. */ nssig = header; } else if (cname_ok && header->type == RBTDB_RDATATYPE_SIGCNAME) { /* * If we get a CNAME match, we'll also need * its signature. */ cnamesig = header; } header_prev = header; } else header_prev = header; } if (empty_node) { /* * We have an exact match for the name, but there are no * extant rdatasets. That means that this node doesn't * meaningfully exist, and that we really have a partial match. */ NODE_UNLOCK(lock, locktype); goto find_ns; } /* * If we didn't find what we were looking for... */ if (found == NULL || (DNS_TRUST_ADDITIONAL(found->trust) && ((options & DNS_DBFIND_ADDITIONALOK) == 0)) || (found->trust == dns_trust_glue && ((options & DNS_DBFIND_GLUEOK) == 0)) || (DNS_TRUST_PENDING(found->trust) && ((options & DNS_DBFIND_PENDINGOK) == 0))) { /* * If there is an NS rdataset at this node, then this is the * deepest zone cut. */ if (nsheader != NULL) { if (nodep != NULL) { new_reference(search.rbtdb, node); INSIST(!ISC_LINK_LINKED(node, deadlink)); *nodep = node; } bind_rdataset(search.rbtdb, node, nsheader, search.now, rdataset); if (need_headerupdate(nsheader, search.now)) update = nsheader; if (nssig != NULL) { bind_rdataset(search.rbtdb, node, nssig, search.now, sigrdataset); if (need_headerupdate(nssig, search.now)) updatesig = nssig; } result = DNS_R_DELEGATION; goto node_exit; } /* * Go find the deepest zone cut. */ NODE_UNLOCK(lock, locktype); goto find_ns; } /* * We found what we were looking for, or we found a CNAME. */ if (nodep != NULL) { new_reference(search.rbtdb, node); INSIST(!ISC_LINK_LINKED(node, deadlink)); *nodep = node; } if (NEGATIVE(found)) { /* * We found a negative cache entry. */ if (NXDOMAIN(found)) result = DNS_R_NCACHENXDOMAIN; else result = DNS_R_NCACHENXRRSET; } else if (type != found->type && type != dns_rdatatype_any && found->type == dns_rdatatype_cname) { /* * We weren't doing an ANY query and we found a CNAME instead * of the type we were looking for, so we need to indicate * that result to the caller. */ result = DNS_R_CNAME; } else { /* * An ordinary successful query! */ result = ISC_R_SUCCESS; } if (type != dns_rdatatype_any || result == DNS_R_NCACHENXDOMAIN || result == DNS_R_NCACHENXRRSET) { bind_rdataset(search.rbtdb, node, found, search.now, rdataset); if (need_headerupdate(found, search.now)) update = found; if (!NEGATIVE(found) && foundsig != NULL) { bind_rdataset(search.rbtdb, node, foundsig, search.now, sigrdataset); if (need_headerupdate(foundsig, search.now)) updatesig = foundsig; } } node_exit: if ((update != NULL || updatesig != NULL) && locktype != isc_rwlocktype_write) { NODE_UNLOCK(lock, locktype); NODE_LOCK(lock, isc_rwlocktype_write); locktype = isc_rwlocktype_write; POST(locktype); } if (update != NULL && need_headerupdate(update, search.now)) update_header(search.rbtdb, update, search.now); if (updatesig != NULL && need_headerupdate(updatesig, search.now)) update_header(search.rbtdb, updatesig, search.now); NODE_UNLOCK(lock, locktype); tree_exit: RWUNLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read); /* * If we found a zonecut but aren't going to use it, we have to * let go of it. */ if (search.need_cleanup) { node = search.zonecut; INSIST(node != NULL); lock = &(search.rbtdb->node_locks[node->locknum].lock); NODE_LOCK(lock, isc_rwlocktype_read); decrement_reference(search.rbtdb, node, 0, isc_rwlocktype_read, isc_rwlocktype_none, ISC_FALSE); NODE_UNLOCK(lock, isc_rwlocktype_read); } dns_rbtnodechain_reset(&search.chain); update_cachestats(search.rbtdb, result); return (result); } static isc_result_t cache_findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { dns_rbtnode_t *node = NULL; nodelock_t *lock; isc_result_t result; rbtdb_search_t search; rdatasetheader_t *header, *header_prev, *header_next; rdatasetheader_t *found, *foundsig; unsigned int rbtoptions = DNS_RBTFIND_EMPTYDATA; isc_rwlocktype_t locktype; search.rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(search.rbtdb)); if (now == 0) isc_stdtime_get(&now); search.rbtversion = NULL; search.serial = 1; search.options = options; search.copy_name = ISC_FALSE; search.need_cleanup = ISC_FALSE; search.wild = ISC_FALSE; search.zonecut = NULL; dns_fixedname_init(&search.zonecut_name); dns_rbtnodechain_init(&search.chain, search.rbtdb->common.mctx); search.now = now; if ((options & DNS_DBFIND_NOEXACT) != 0) rbtoptions |= DNS_RBTFIND_NOEXACT; RWLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read); /* * Search down from the root of the tree. */ result = dns_rbt_findnode(search.rbtdb->tree, name, foundname, &node, &search.chain, rbtoptions, NULL, &search); if (result == DNS_R_PARTIALMATCH) { find_ns: result = find_deepest_zonecut(&search, node, nodep, foundname, rdataset, sigrdataset); goto tree_exit; } else if (result != ISC_R_SUCCESS) goto tree_exit; /* * We now go looking for an NS rdataset at the node. */ lock = &(search.rbtdb->node_locks[node->locknum].lock); locktype = isc_rwlocktype_read; NODE_LOCK(lock, locktype); found = NULL; foundsig = NULL; header_prev = NULL; for (header = node->data; header != NULL; header = header_next) { header_next = header->next; if (check_stale_rdataset(node, header, &locktype, lock, &search, &header_prev)) { /* Do nothing. */ } else if (EXISTS(header)) { /* * If we found a type we were looking for, remember * it. */ if (header->type == dns_rdatatype_ns) { /* * Remember a NS rdataset even if we're * not specifically looking for it, because * we might need it later. */ found = header; } else if (header->type == RBTDB_RDATATYPE_SIGNS) { /* * If we need the NS rdataset, we'll also * need its signature. */ foundsig = header; } header_prev = header; } else header_prev = header; } if (found == NULL) { /* * No NS records here. */ NODE_UNLOCK(lock, locktype); goto find_ns; } if (nodep != NULL) { new_reference(search.rbtdb, node); INSIST(!ISC_LINK_LINKED(node, deadlink)); *nodep = node; } bind_rdataset(search.rbtdb, node, found, search.now, rdataset); if (foundsig != NULL) bind_rdataset(search.rbtdb, node, foundsig, search.now, sigrdataset); if (need_headerupdate(found, search.now) || (foundsig != NULL && need_headerupdate(foundsig, search.now))) { if (locktype != isc_rwlocktype_write) { NODE_UNLOCK(lock, locktype); NODE_LOCK(lock, isc_rwlocktype_write); locktype = isc_rwlocktype_write; POST(locktype); } if (need_headerupdate(found, search.now)) update_header(search.rbtdb, found, search.now); if (foundsig != NULL && need_headerupdate(foundsig, search.now)) { update_header(search.rbtdb, foundsig, search.now); } } NODE_UNLOCK(lock, locktype); tree_exit: RWUNLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read); INSIST(!search.need_cleanup); dns_rbtnodechain_reset(&search.chain); if (result == DNS_R_DELEGATION) result = ISC_R_SUCCESS; return (result); } static void attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; dns_rbtnode_t *node = (dns_rbtnode_t *)source; unsigned int refs; REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(targetp != NULL && *targetp == NULL); NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock); dns_rbtnode_refincrement(node, &refs); INSIST(refs != 0); NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock); *targetp = source; } static void detachnode(dns_db_t *db, dns_dbnode_t **targetp) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; dns_rbtnode_t *node; isc_boolean_t want_free = ISC_FALSE; isc_boolean_t inactive = ISC_FALSE; rbtdb_nodelock_t *nodelock; REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(targetp != NULL && *targetp != NULL); node = (dns_rbtnode_t *)(*targetp); nodelock = &rbtdb->node_locks[node->locknum]; NODE_LOCK(&nodelock->lock, isc_rwlocktype_read); if (decrement_reference(rbtdb, node, 0, isc_rwlocktype_read, isc_rwlocktype_none, ISC_FALSE)) { if (isc_refcount_current(&nodelock->references) == 0 && nodelock->exiting) { inactive = ISC_TRUE; } } NODE_UNLOCK(&nodelock->lock, isc_rwlocktype_read); *targetp = NULL; if (inactive) { RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); rbtdb->active--; if (rbtdb->active == 0) want_free = ISC_TRUE; RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); if (want_free) { char buf[DNS_NAME_FORMATSIZE]; if (dns_name_dynamic(&rbtdb->common.origin)) dns_name_format(&rbtdb->common.origin, buf, sizeof(buf)); else strcpy(buf, ""); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1), "calling free_rbtdb(%s)", buf); free_rbtdb(rbtdb, ISC_TRUE, NULL); } } } static isc_result_t expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; dns_rbtnode_t *rbtnode = node; rdatasetheader_t *header; isc_boolean_t force_expire = ISC_FALSE; /* * These are the category and module used by the cache cleaner. */ isc_boolean_t log = ISC_FALSE; isc_logcategory_t *category = DNS_LOGCATEGORY_DATABASE; isc_logmodule_t *module = DNS_LOGMODULE_CACHE; int level = ISC_LOG_DEBUG(2); char printname[DNS_NAME_FORMATSIZE]; REQUIRE(VALID_RBTDB(rbtdb)); /* * Caller must hold a tree lock. */ if (now == 0) isc_stdtime_get(&now); if (isc_mem_isovermem(rbtdb->common.mctx)) { isc_uint32_t val; isc_random_get(&val); /* * XXXDCL Could stand to have a better policy, like LRU. */ force_expire = ISC_TF(rbtnode->down == NULL && val % 4 == 0); /* * Note that 'log' can be true IFF overmem is also true. * overmem can currently only be true for cache * databases -- hence all of the "overmem cache" log strings. */ log = ISC_TF(isc_log_wouldlog(dns_lctx, level)); if (log) isc_log_write(dns_lctx, category, module, level, "overmem cache: %s %s", force_expire ? "FORCE" : "check", dns_rbt_formatnodename(rbtnode, printname, sizeof(printname))); } /* * We may not need write access, but this code path is not performance * sensitive, so it should be okay to always lock as a writer. */ NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_write); for (header = rbtnode->data; header != NULL; header = header->next) if (header->rdh_ttl <= now - RBTDB_VIRTUAL) { /* * We don't check if refcurrent(rbtnode) == 0 and try * to free like we do in cache_find(), because * refcurrent(rbtnode) must be non-zero. This is so * because 'node' is an argument to the function. */ mark_stale_header(rbtdb, header); if (log) isc_log_write(dns_lctx, category, module, level, "overmem cache: stale %s", printname); } else if (force_expire) { if (! RETAIN(header)) { set_ttl(rbtdb, header, 0); mark_stale_header(rbtdb, header); } else if (log) { isc_log_write(dns_lctx, category, module, level, "overmem cache: " "reprieve by RETAIN() %s", printname); } } else if (isc_mem_isovermem(rbtdb->common.mctx) && log) isc_log_write(dns_lctx, category, module, level, "overmem cache: saved %s", printname); NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_write); return (ISC_R_SUCCESS); } static void overmem(dns_db_t *db, isc_boolean_t over) { /* This is an empty callback. See adb.c:water() */ UNUSED(db); UNUSED(over); return; } static void printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; dns_rbtnode_t *rbtnode = node; isc_boolean_t first; REQUIRE(VALID_RBTDB(rbtdb)); NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_read); fprintf(out, "node %p, %u references, locknum = %u\n", rbtnode, dns_rbtnode_refcurrent(rbtnode), rbtnode->locknum); if (rbtnode->data != NULL) { rdatasetheader_t *current, *top_next; for (current = rbtnode->data; current != NULL; current = top_next) { top_next = current->next; first = ISC_TRUE; fprintf(out, "\ttype %u", current->type); do { if (!first) fprintf(out, "\t"); first = ISC_FALSE; fprintf(out, "\tserial = %lu, ttl = %u, " "trust = %u, attributes = %u, " "resign = %u\n", (unsigned long)current->serial, current->rdh_ttl, current->trust, current->attributes, current->resign); current = current->down; } while (current != NULL); } } else fprintf(out, "(empty)\n"); NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_read); } static isc_result_t createiterator(dns_db_t *db, unsigned int options, dns_dbiterator_t **iteratorp) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; rbtdb_dbiterator_t *rbtdbiter; REQUIRE(VALID_RBTDB(rbtdb)); rbtdbiter = isc_mem_get(rbtdb->common.mctx, sizeof(*rbtdbiter)); if (rbtdbiter == NULL) return (ISC_R_NOMEMORY); rbtdbiter->common.methods = &dbiterator_methods; rbtdbiter->common.db = NULL; dns_db_attach(db, &rbtdbiter->common.db); rbtdbiter->common.relative_names = ISC_TF((options & DNS_DB_RELATIVENAMES) != 0); rbtdbiter->common.magic = DNS_DBITERATOR_MAGIC; rbtdbiter->common.cleaning = ISC_FALSE; rbtdbiter->paused = ISC_TRUE; rbtdbiter->tree_locked = isc_rwlocktype_none; rbtdbiter->result = ISC_R_SUCCESS; dns_fixedname_init(&rbtdbiter->name); dns_fixedname_init(&rbtdbiter->origin); rbtdbiter->node = NULL; rbtdbiter->delete = 0; rbtdbiter->nsec3only = ISC_TF((options & DNS_DB_NSEC3ONLY) != 0); rbtdbiter->nonsec3 = ISC_TF((options & DNS_DB_NONSEC3) != 0); memset(rbtdbiter->deletions, 0, sizeof(rbtdbiter->deletions)); dns_rbtnodechain_init(&rbtdbiter->chain, db->mctx); dns_rbtnodechain_init(&rbtdbiter->nsec3chain, db->mctx); if (rbtdbiter->nsec3only) rbtdbiter->current = &rbtdbiter->nsec3chain; else rbtdbiter->current = &rbtdbiter->chain; *iteratorp = (dns_dbiterator_t *)rbtdbiter; return (ISC_R_SUCCESS); } static isc_result_t zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdatatype_t type, dns_rdatatype_t covers, isc_stdtime_t now, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node; rdatasetheader_t *header, *header_next, *found, *foundsig; rbtdb_serial_t serial; rbtdb_version_t *rbtversion = version; isc_boolean_t close_version = ISC_FALSE; rbtdb_rdatatype_t matchtype, sigmatchtype; REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(type != dns_rdatatype_any); INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb); if (rbtversion == NULL) { currentversion(db, (dns_dbversion_t **) (void *)(&rbtversion)); close_version = ISC_TRUE; } serial = rbtversion->serial; now = 0; NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_read); found = NULL; foundsig = NULL; matchtype = RBTDB_RDATATYPE_VALUE(type, covers); if (covers == 0) sigmatchtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, type); else sigmatchtype = 0; for (header = rbtnode->data; header != NULL; header = header_next) { header_next = header->next; do { if (header->serial <= serial && !IGNORE(header)) { /* * Is this a "this rdataset doesn't * exist" record? */ if (NONEXISTENT(header)) header = NULL; break; } else header = header->down; } while (header != NULL); if (header != NULL) { /* * We have an active, extant rdataset. If it's a * type we're looking for, remember it. */ if (header->type == matchtype) { found = header; if (foundsig != NULL) break; } else if (header->type == sigmatchtype) { foundsig = header; if (found != NULL) break; } } } if (found != NULL) { bind_rdataset(rbtdb, rbtnode, found, now, rdataset); if (foundsig != NULL) bind_rdataset(rbtdb, rbtnode, foundsig, now, sigrdataset); } NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_read); if (close_version) closeversion(db, (dns_dbversion_t **) (void *)(&rbtversion), ISC_FALSE); if (found == NULL) return (ISC_R_NOTFOUND); return (ISC_R_SUCCESS); } static isc_result_t cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdatatype_t type, dns_rdatatype_t covers, isc_stdtime_t now, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node; rdatasetheader_t *header, *header_next, *found, *foundsig; rbtdb_rdatatype_t matchtype, sigmatchtype, negtype; isc_result_t result; nodelock_t *lock; isc_rwlocktype_t locktype; REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(type != dns_rdatatype_any); UNUSED(version); result = ISC_R_SUCCESS; if (now == 0) isc_stdtime_get(&now); lock = &rbtdb->node_locks[rbtnode->locknum].lock; locktype = isc_rwlocktype_read; NODE_LOCK(lock, locktype); found = NULL; foundsig = NULL; matchtype = RBTDB_RDATATYPE_VALUE(type, covers); negtype = RBTDB_RDATATYPE_VALUE(0, type); if (covers == 0) sigmatchtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, type); else sigmatchtype = 0; for (header = rbtnode->data; header != NULL; header = header_next) { header_next = header->next; if (header->rdh_ttl < now) { if ((header->rdh_ttl < now - RBTDB_VIRTUAL) && (locktype == isc_rwlocktype_write || NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) { /* * We update the node's status only when we * can get write access. */ locktype = isc_rwlocktype_write; /* * We don't check if refcurrent(rbtnode) == 0 * and try to free like we do in cache_find(), * because refcurrent(rbtnode) must be * non-zero. This is so because 'node' is an * argument to the function. */ mark_stale_header(rbtdb, header); } } else if (EXISTS(header)) { if (header->type == matchtype) found = header; else if (header->type == RBTDB_RDATATYPE_NCACHEANY || header->type == negtype) found = header; else if (header->type == sigmatchtype) foundsig = header; } } if (found != NULL) { bind_rdataset(rbtdb, rbtnode, found, now, rdataset); if (!NEGATIVE(found) && foundsig != NULL) bind_rdataset(rbtdb, rbtnode, foundsig, now, sigrdataset); } NODE_UNLOCK(lock, locktype); if (found == NULL) return (ISC_R_NOTFOUND); if (NEGATIVE(found)) { /* * We found a negative cache entry. */ if (NXDOMAIN(found)) result = DNS_R_NCACHENXDOMAIN; else result = DNS_R_NCACHENXRRSET; } update_cachestats(rbtdb, result); return (result); } static isc_result_t allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_stdtime_t now, dns_rdatasetiter_t **iteratorp) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node; rbtdb_version_t *rbtversion = version; rbtdb_rdatasetiter_t *iterator; unsigned int refs; REQUIRE(VALID_RBTDB(rbtdb)); iterator = isc_mem_get(rbtdb->common.mctx, sizeof(*iterator)); if (iterator == NULL) return (ISC_R_NOMEMORY); if ((db->attributes & DNS_DBATTR_CACHE) == 0) { now = 0; if (rbtversion == NULL) currentversion(db, (dns_dbversion_t **) (void *)(&rbtversion)); else { INSIST(rbtversion->rbtdb == rbtdb); isc_refcount_increment(&rbtversion->references, &refs); INSIST(refs > 1); } } else { if (now == 0) isc_stdtime_get(&now); rbtversion = NULL; } iterator->common.magic = DNS_RDATASETITER_MAGIC; iterator->common.methods = &rdatasetiter_methods; iterator->common.db = db; iterator->common.node = node; iterator->common.version = (dns_dbversion_t *)rbtversion; iterator->common.now = now; NODE_STRONGLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); dns_rbtnode_refincrement(rbtnode, &refs); INSIST(refs != 0); iterator->current = NULL; NODE_STRONGUNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); *iteratorp = (dns_rdatasetiter_t *)iterator; return (ISC_R_SUCCESS); } static isc_boolean_t cname_and_other_data(dns_rbtnode_t *node, rbtdb_serial_t serial) { rdatasetheader_t *header, *header_next; isc_boolean_t cname, other_data; dns_rdatatype_t rdtype; /* * The caller must hold the node lock. */ /* * Look for CNAME and "other data" rdatasets active in our version. */ cname = ISC_FALSE; other_data = ISC_FALSE; for (header = node->data; header != NULL; header = header_next) { header_next = header->next; if (header->type == dns_rdatatype_cname) { /* * Look for an active extant CNAME. */ do { if (header->serial <= serial && !IGNORE(header)) { /* * Is this a "this rdataset doesn't * exist" record? */ if (NONEXISTENT(header)) header = NULL; break; } else header = header->down; } while (header != NULL); if (header != NULL) cname = ISC_TRUE; } else { /* * Look for active extant "other data". * * "Other data" is any rdataset whose type is not * KEY, NSEC, SIG or RRSIG. */ rdtype = RBTDB_RDATATYPE_BASE(header->type); if (rdtype != dns_rdatatype_key && rdtype != dns_rdatatype_sig && rdtype != dns_rdatatype_nsec && rdtype != dns_rdatatype_rrsig) { /* * Is it active and extant? */ do { if (header->serial <= serial && !IGNORE(header)) { /* * Is this a "this rdataset * doesn't exist" record? */ if (NONEXISTENT(header)) header = NULL; break; } else header = header->down; } while (header != NULL); if (header != NULL) other_data = ISC_TRUE; } } } if (cname && other_data) return (ISC_TRUE); return (ISC_FALSE); } static isc_result_t resign_insert(dns_rbtdb_t *rbtdb, int idx, rdatasetheader_t *newheader) { isc_result_t result; INSIST(!IS_CACHE(rbtdb)); INSIST(newheader->heap_index == 0); INSIST(!ISC_LINK_LINKED(newheader, link)); result = isc_heap_insert(rbtdb->heaps[idx], newheader); return (result); } static void resign_delete(dns_rbtdb_t *rbtdb, rbtdb_version_t *version, rdatasetheader_t *header) { /* * Remove the old header from the heap */ if (header != NULL && header->heap_index != 0) { isc_heap_delete(rbtdb->heaps[header->node->locknum], header->heap_index); header->heap_index = 0; if (version != NULL) { new_reference(rbtdb, header->node); ISC_LIST_APPEND(version->resigned_list, header, link); } } } static isc_result_t add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, rdatasetheader_t *newheader, unsigned int options, isc_boolean_t loading, dns_rdataset_t *addedrdataset, isc_stdtime_t now) { rbtdb_changed_t *changed = NULL; rdatasetheader_t *topheader, *topheader_prev, *header, *sigheader; unsigned char *merged; isc_result_t result; isc_boolean_t header_nx; isc_boolean_t newheader_nx; isc_boolean_t merge; dns_rdatatype_t rdtype, covers; rbtdb_rdatatype_t negtype, sigtype; dns_trust_t trust; int idx; /* * Add an rdatasetheader_t to a node. */ /* * Caller must be holding the node lock. */ if ((options & DNS_DBADD_MERGE) != 0) { REQUIRE(rbtversion != NULL); merge = ISC_TRUE; } else merge = ISC_FALSE; if ((options & DNS_DBADD_FORCE) != 0) trust = dns_trust_ultimate; else trust = newheader->trust; if (rbtversion != NULL && !loading) { /* * We always add a changed record, even if no changes end up * being made to this node, because it's harmless and * simplifies the code. */ changed = add_changed(rbtdb, rbtversion, rbtnode); if (changed == NULL) { free_rdataset(rbtdb, rbtdb->common.mctx, newheader); return (ISC_R_NOMEMORY); } } newheader_nx = NONEXISTENT(newheader) ? ISC_TRUE : ISC_FALSE; topheader_prev = NULL; sigheader = NULL; negtype = 0; if (rbtversion == NULL && !newheader_nx) { rdtype = RBTDB_RDATATYPE_BASE(newheader->type); covers = RBTDB_RDATATYPE_EXT(newheader->type); sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, covers); if (NEGATIVE(newheader)) { /* * We're adding a negative cache entry. */ for (topheader = rbtnode->data; topheader != NULL; topheader = topheader->next) { /* * If we're adding an negative cache entry * which covers all types (NXDOMAIN, * NODATA(QTYPE=ANY)). * * We make all other data stale so that the * only rdataset that can be found at this * node is the negative cache entry. * * Otherwise look for any RRSIGs of the * given type so they can be marked stale * later. */ if (covers == dns_rdatatype_any) { set_ttl(rbtdb, topheader, 0); mark_stale_header(rbtdb, topheader); } else if (topheader->type == sigtype) sigheader = topheader; } if (covers == dns_rdatatype_any) goto find_header; negtype = RBTDB_RDATATYPE_VALUE(covers, 0); } else { /* * We're adding something that isn't a * negative cache entry. Look for an extant * non-stale NXDOMAIN/NODATA(QTYPE=ANY) negative * cache entry. If we're adding an RRSIG, also * check for an extant non-stale NODATA ncache * entry which covers the same type as the RRSIG. */ for (topheader = rbtnode->data; topheader != NULL; topheader = topheader->next) { if ((topheader->type == RBTDB_RDATATYPE_NCACHEANY) || (newheader->type == sigtype && topheader->type == RBTDB_RDATATYPE_VALUE(0, covers))) { break; } } if (topheader != NULL && EXISTS(topheader) && topheader->rdh_ttl >= now) { /* * Found one. */ if (trust < topheader->trust) { /* * The NXDOMAIN/NODATA(QTYPE=ANY) * is more trusted. */ free_rdataset(rbtdb, rbtdb->common.mctx, newheader); if (addedrdataset != NULL) bind_rdataset(rbtdb, rbtnode, topheader, now, addedrdataset); return (DNS_R_UNCHANGED); } /* * The new rdataset is better. Expire the * ncache entry. */ set_ttl(rbtdb, topheader, 0); mark_stale_header(rbtdb, topheader); topheader = NULL; goto find_header; } negtype = RBTDB_RDATATYPE_VALUE(0, rdtype); } } for (topheader = rbtnode->data; topheader != NULL; topheader = topheader->next) { if (topheader->type == newheader->type || topheader->type == negtype) break; topheader_prev = topheader; } find_header: /* * If header isn't NULL, we've found the right type. There may be * IGNORE rdatasets between the top of the chain and the first real * data. We skip over them. */ header = topheader; while (header != NULL && IGNORE(header)) header = header->down; if (header != NULL) { header_nx = NONEXISTENT(header) ? ISC_TRUE : ISC_FALSE; /* * Deleting an already non-existent rdataset has no effect. */ if (header_nx && newheader_nx) { free_rdataset(rbtdb, rbtdb->common.mctx, newheader); return (DNS_R_UNCHANGED); } /* * Trying to add an rdataset with lower trust to a cache DB * has no effect, provided that the cache data isn't stale. */ if (rbtversion == NULL && trust < header->trust && (header->rdh_ttl >= now || header_nx)) { free_rdataset(rbtdb, rbtdb->common.mctx, newheader); if (addedrdataset != NULL) bind_rdataset(rbtdb, rbtnode, header, now, addedrdataset); return (DNS_R_UNCHANGED); } /* * Don't merge if a nonexistent rdataset is involved. */ if (merge && (header_nx || newheader_nx)) merge = ISC_FALSE; /* * If 'merge' is ISC_TRUE, we'll try to create a new rdataset * that is the union of 'newheader' and 'header'. */ if (merge) { unsigned int flags = 0; INSIST(rbtversion->serial >= header->serial); merged = NULL; result = ISC_R_SUCCESS; if ((options & DNS_DBADD_EXACT) != 0) flags |= DNS_RDATASLAB_EXACT; if ((options & DNS_DBADD_EXACTTTL) != 0 && newheader->rdh_ttl != header->rdh_ttl) result = DNS_R_NOTEXACT; else if (newheader->rdh_ttl != header->rdh_ttl) flags |= DNS_RDATASLAB_FORCE; if (result == ISC_R_SUCCESS) result = dns_rdataslab_merge( (unsigned char *)header, (unsigned char *)newheader, (unsigned int)(sizeof(*newheader)), rbtdb->common.mctx, rbtdb->common.rdclass, (dns_rdatatype_t)header->type, flags, &merged); if (result == ISC_R_SUCCESS) { /* * If 'header' has the same serial number as * we do, we could clean it up now if we knew * that our caller had no references to it. * We don't know this, however, so we leave it * alone. It will get cleaned up when * clean_zone_node() runs. */ free_rdataset(rbtdb, rbtdb->common.mctx, newheader); newheader = (rdatasetheader_t *)merged; init_rdataset(rbtdb, newheader); update_newheader(newheader, header); if (loading && RESIGN(newheader) && RESIGN(header) && header->resign < newheader->resign) newheader->resign = header->resign; } else { free_rdataset(rbtdb, rbtdb->common.mctx, newheader); return (result); } } /* * Don't replace existing NS, A and AAAA RRsets * in the cache if they are already exist. This * prevents named being locked to old servers. * Don't lower trust of existing record if the * update is forced. */ if (IS_CACHE(rbtdb) && header->rdh_ttl >= now && header->type == dns_rdatatype_ns && !header_nx && !newheader_nx && header->trust >= newheader->trust && dns_rdataslab_equalx((unsigned char *)header, (unsigned char *)newheader, (unsigned int)(sizeof(*newheader)), rbtdb->common.rdclass, (dns_rdatatype_t)header->type)) { /* * Honour the new ttl if it is less than the * older one. */ if (header->rdh_ttl > newheader->rdh_ttl) set_ttl(rbtdb, header, newheader->rdh_ttl); if (header->noqname == NULL && newheader->noqname != NULL) { header->noqname = newheader->noqname; newheader->noqname = NULL; } if (header->closest == NULL && newheader->closest != NULL) { header->closest = newheader->closest; newheader->closest = NULL; } free_rdataset(rbtdb, rbtdb->common.mctx, newheader); if (addedrdataset != NULL) bind_rdataset(rbtdb, rbtnode, header, now, addedrdataset); return (ISC_R_SUCCESS); } /* * If we have will be replacing a NS RRset force its TTL * to be no more than the current NS RRset's TTL. This * ensures the delegations that are withdrawn are honoured. */ if (IS_CACHE(rbtdb) && header->rdh_ttl >= now && header->type == dns_rdatatype_ns && !header_nx && !newheader_nx && header->trust <= newheader->trust) { if (newheader->rdh_ttl > header->rdh_ttl) { newheader->rdh_ttl = header->rdh_ttl; } } if (IS_CACHE(rbtdb) && header->rdh_ttl >= now && (options & DNS_DBADD_PREFETCH) == 0 && (header->type == dns_rdatatype_a || header->type == dns_rdatatype_aaaa || header->type == dns_rdatatype_ds || header->type == RBTDB_RDATATYPE_SIGDDS) && !header_nx && !newheader_nx && header->trust >= newheader->trust && dns_rdataslab_equal((unsigned char *)header, (unsigned char *)newheader, (unsigned int)(sizeof(*newheader)))) { /* * Honour the new ttl if it is less than the * older one. */ if (header->rdh_ttl > newheader->rdh_ttl) set_ttl(rbtdb, header, newheader->rdh_ttl); if (header->noqname == NULL && newheader->noqname != NULL) { header->noqname = newheader->noqname; newheader->noqname = NULL; } if (header->closest == NULL && newheader->closest != NULL) { header->closest = newheader->closest; newheader->closest = NULL; } free_rdataset(rbtdb, rbtdb->common.mctx, newheader); if (addedrdataset != NULL) bind_rdataset(rbtdb, rbtnode, header, now, addedrdataset); return (ISC_R_SUCCESS); } INSIST(rbtversion == NULL || rbtversion->serial >= topheader->serial); if (topheader_prev != NULL) topheader_prev->next = newheader; else rbtnode->data = newheader; newheader->next = topheader->next; if (loading) { /* * There are no other references to 'header' when * loading, so we MAY clean up 'header' now. * Since we don't generate changed records when * loading, we MUST clean up 'header' now. */ newheader->down = NULL; free_rdataset(rbtdb, rbtdb->common.mctx, header); idx = newheader->node->locknum; if (IS_CACHE(rbtdb)) { ISC_LIST_PREPEND(rbtdb->rdatasets[idx], newheader, link); INSIST(rbtdb->heaps != NULL); (void)isc_heap_insert(rbtdb->heaps[idx], newheader); } else if (RESIGN(newheader)) { result = resign_insert(rbtdb, idx, newheader); if (result != ISC_R_SUCCESS) return (result); } } else { newheader->down = topheader; topheader->next = newheader; rbtnode->dirty = 1; if (changed != NULL) changed->dirty = ISC_TRUE; if (rbtversion == NULL) { set_ttl(rbtdb, header, 0); mark_stale_header(rbtdb, header); if (sigheader != NULL) { set_ttl(rbtdb, sigheader, 0); mark_stale_header(rbtdb, sigheader); } } idx = newheader->node->locknum; if (IS_CACHE(rbtdb)) { ISC_LIST_PREPEND(rbtdb->rdatasets[idx], newheader, link); /* * XXXMLG We don't check the return value * here. If it fails, we will not do TTL * based expiry on this node. However, we * will do it on the LRU side, so memory * will not leak... for long. */ INSIST(rbtdb->heaps != NULL); (void)isc_heap_insert(rbtdb->heaps[idx], newheader); } else if (RESIGN(newheader)) { resign_delete(rbtdb, rbtversion, header); result = resign_insert(rbtdb, idx, newheader); if (result != ISC_R_SUCCESS) return (result); } } } else { /* * No non-IGNORED rdatasets of the given type exist at * this node. */ /* * If we're trying to delete the type, don't bother. */ if (newheader_nx) { free_rdataset(rbtdb, rbtdb->common.mctx, newheader); return (DNS_R_UNCHANGED); } if (topheader != NULL) { /* * We have an list of rdatasets of the given type, * but they're all marked IGNORE. We simply insert * the new rdataset at the head of the list. * * Ignored rdatasets cannot occur during loading, so * we INSIST on it. */ INSIST(!loading); INSIST(rbtversion == NULL || rbtversion->serial >= topheader->serial); if (topheader_prev != NULL) topheader_prev->next = newheader; else rbtnode->data = newheader; newheader->next = topheader->next; newheader->down = topheader; topheader->next = newheader; rbtnode->dirty = 1; if (changed != NULL) changed->dirty = ISC_TRUE; } else { /* * No rdatasets of the given type exist at the node. */ newheader->next = rbtnode->data; newheader->down = NULL; rbtnode->data = newheader; } idx = newheader->node->locknum; if (IS_CACHE(rbtdb)) { ISC_LIST_PREPEND(rbtdb->rdatasets[idx], newheader, link); isc_heap_insert(rbtdb->heaps[idx], newheader); } else if (RESIGN(newheader)) { resign_delete(rbtdb, rbtversion, header); result = resign_insert(rbtdb, idx, newheader); if (result != ISC_R_SUCCESS) return (result); } } /* * Check if the node now contains CNAME and other data. */ if (rbtversion != NULL && cname_and_other_data(rbtnode, rbtversion->serial)) return (DNS_R_CNAMEANDOTHER); if (addedrdataset != NULL) bind_rdataset(rbtdb, rbtnode, newheader, now, addedrdataset); return (ISC_R_SUCCESS); } static inline isc_boolean_t delegating_type(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, rbtdb_rdatatype_t type) { if (IS_CACHE(rbtdb)) { if (type == dns_rdatatype_dname) return (ISC_TRUE); else return (ISC_FALSE); } else if (type == dns_rdatatype_dname || (type == dns_rdatatype_ns && (node != rbtdb->origin_node || IS_STUB(rbtdb)))) return (ISC_TRUE); return (ISC_FALSE); } static inline isc_result_t addnoqname(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader, dns_rdataset_t *rdataset) { struct noqname *noqname; isc_mem_t *mctx = rbtdb->common.mctx; dns_name_t name; dns_rdataset_t neg, negsig; isc_result_t result; isc_region_t r; dns_name_init(&name, NULL); dns_rdataset_init(&neg); dns_rdataset_init(&negsig); result = dns_rdataset_getnoqname(rdataset, &name, &neg, &negsig); RUNTIME_CHECK(result == ISC_R_SUCCESS); noqname = isc_mem_get(mctx, sizeof(*noqname)); if (noqname == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } dns_name_init(&noqname->name, NULL); noqname->neg = NULL; noqname->negsig = NULL; noqname->type = neg.type; result = dns_name_dup(&name, mctx, &noqname->name); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_rdataslab_fromrdataset(&neg, mctx, &r, 0); if (result != ISC_R_SUCCESS) goto cleanup; noqname->neg = r.base; result = dns_rdataslab_fromrdataset(&negsig, mctx, &r, 0); if (result != ISC_R_SUCCESS) goto cleanup; noqname->negsig = r.base; dns_rdataset_disassociate(&neg); dns_rdataset_disassociate(&negsig); newheader->noqname = noqname; return (ISC_R_SUCCESS); cleanup: dns_rdataset_disassociate(&neg); dns_rdataset_disassociate(&negsig); if (noqname != NULL) free_noqname(mctx, &noqname); return(result); } static inline isc_result_t addclosest(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader, dns_rdataset_t *rdataset) { struct noqname *closest; isc_mem_t *mctx = rbtdb->common.mctx; dns_name_t name; dns_rdataset_t neg, negsig; isc_result_t result; isc_region_t r; dns_name_init(&name, NULL); dns_rdataset_init(&neg); dns_rdataset_init(&negsig); result = dns_rdataset_getclosest(rdataset, &name, &neg, &negsig); RUNTIME_CHECK(result == ISC_R_SUCCESS); closest = isc_mem_get(mctx, sizeof(*closest)); if (closest == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } dns_name_init(&closest->name, NULL); closest->neg = NULL; closest->negsig = NULL; closest->type = neg.type; result = dns_name_dup(&name, mctx, &closest->name); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_rdataslab_fromrdataset(&neg, mctx, &r, 0); if (result != ISC_R_SUCCESS) goto cleanup; closest->neg = r.base; result = dns_rdataslab_fromrdataset(&negsig, mctx, &r, 0); if (result != ISC_R_SUCCESS) goto cleanup; closest->negsig = r.base; dns_rdataset_disassociate(&neg); dns_rdataset_disassociate(&negsig); newheader->closest = closest; return (ISC_R_SUCCESS); cleanup: dns_rdataset_disassociate(&neg); dns_rdataset_disassociate(&negsig); if (closest != NULL) free_noqname(mctx, &closest); return(result); } static dns_dbmethods_t zone_methods; static isc_result_t addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options, dns_rdataset_t *addedrdataset) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node; rbtdb_version_t *rbtversion = version; isc_region_t region; rdatasetheader_t *newheader; rdatasetheader_t *header; isc_result_t result; isc_boolean_t delegating; isc_boolean_t newnsec; isc_boolean_t tree_locked = ISC_FALSE; isc_boolean_t cache_is_overmem = ISC_FALSE; REQUIRE(VALID_RBTDB(rbtdb)); INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb); if (rbtdb->common.methods == &zone_methods) REQUIRE(((rbtnode->nsec == DNS_RBT_NSEC_NSEC3 && (rdataset->type == dns_rdatatype_nsec3 || rdataset->covers == dns_rdatatype_nsec3)) || (rbtnode->nsec != DNS_RBT_NSEC_NSEC3 && rdataset->type != dns_rdatatype_nsec3 && rdataset->covers != dns_rdatatype_nsec3))); if (rbtversion == NULL) { if (now == 0) isc_stdtime_get(&now); } else now = 0; result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx, ®ion, sizeof(rdatasetheader_t)); if (result != ISC_R_SUCCESS) return (result); newheader = (rdatasetheader_t *)region.base; init_rdataset(rbtdb, newheader); set_ttl(rbtdb, newheader, rdataset->ttl + now); newheader->type = RBTDB_RDATATYPE_VALUE(rdataset->type, rdataset->covers); newheader->attributes = 0; newheader->noqname = NULL; newheader->closest = NULL; newheader->count = init_count++; newheader->trust = rdataset->trust; newheader->additional_auth = NULL; newheader->additional_glue = NULL; newheader->last_used = now; newheader->node = rbtnode; if (rbtversion != NULL) { newheader->serial = rbtversion->serial; now = 0; if ((rdataset->attributes & DNS_RDATASETATTR_RESIGN) != 0) { newheader->attributes |= RDATASET_ATTR_RESIGN; newheader->resign = rdataset->resign; } else newheader->resign = 0; } else { newheader->serial = 1; newheader->resign = 0; if ((rdataset->attributes & DNS_RDATASETATTR_PREFETCH) != 0) newheader->attributes |= RDATASET_ATTR_PREFETCH; if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) newheader->attributes |= RDATASET_ATTR_NEGATIVE; if ((rdataset->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0) newheader->attributes |= RDATASET_ATTR_NXDOMAIN; if ((rdataset->attributes & DNS_RDATASETATTR_OPTOUT) != 0) newheader->attributes |= RDATASET_ATTR_OPTOUT; if ((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0) { result = addnoqname(rbtdb, newheader, rdataset); if (result != ISC_R_SUCCESS) { free_rdataset(rbtdb, rbtdb->common.mctx, newheader); return (result); } } if ((rdataset->attributes & DNS_RDATASETATTR_CLOSEST) != 0) { result = addclosest(rbtdb, newheader, rdataset); if (result != ISC_R_SUCCESS) { free_rdataset(rbtdb, rbtdb->common.mctx, newheader); return (result); } } } /* * If we're adding a delegation type (e.g. NS or DNAME for a zone, * just DNAME for the cache), then we need to set the callback bit * on the node. */ if (delegating_type(rbtdb, rbtnode, rdataset->type)) delegating = ISC_TRUE; else delegating = ISC_FALSE; /* * Add to the auxiliary NSEC tree if we're adding an NSEC record. */ if (rbtnode->nsec != DNS_RBT_NSEC_HAS_NSEC && rdataset->type == dns_rdatatype_nsec) newnsec = ISC_TRUE; else newnsec = ISC_FALSE; /* * If we're adding a delegation type, adding to the auxiliary NSEC tree, * or the DB is a cache in an overmem state, hold an exclusive lock on * the tree. In the latter case the lock does not necessarily have to * be acquired but it will help purge stale entries more effectively. */ if (IS_CACHE(rbtdb) && isc_mem_isovermem(rbtdb->common.mctx)) cache_is_overmem = ISC_TRUE; if (delegating || newnsec || cache_is_overmem) { tree_locked = ISC_TRUE; RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); } if (cache_is_overmem) overmem_purge(rbtdb, rbtnode->locknum, now, tree_locked); NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_write); if (rbtdb->rrsetstats != NULL) { newheader->attributes |= RDATASET_ATTR_STATCOUNT; update_rrsetstats(rbtdb, newheader, ISC_TRUE); } if (IS_CACHE(rbtdb)) { if (tree_locked) cleanup_dead_nodes(rbtdb, rbtnode->locknum); header = isc_heap_element(rbtdb->heaps[rbtnode->locknum], 1); if (header && header->rdh_ttl < now - RBTDB_VIRTUAL) expire_header(rbtdb, header, tree_locked, expire_ttl); /* * If we've been holding a write lock on the tree just for * cleaning, we can release it now. However, we still need the * node lock. */ if (tree_locked && !delegating && !newnsec) { RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); tree_locked = ISC_FALSE; } } result = ISC_R_SUCCESS; if (newnsec) { dns_fixedname_t fname; dns_name_t *name; dns_rbtnode_t *nsecnode; dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_rbt_fullnamefromnode(rbtnode, name); nsecnode = NULL; result = dns_rbt_addnode(rbtdb->nsec, name, &nsecnode); if (result == ISC_R_SUCCESS) { nsecnode->nsec = DNS_RBT_NSEC_NSEC; rbtnode->nsec = DNS_RBT_NSEC_HAS_NSEC; } else if (result == ISC_R_EXISTS) { rbtnode->nsec = DNS_RBT_NSEC_HAS_NSEC; result = ISC_R_SUCCESS; } } if (result == ISC_R_SUCCESS) result = add32(rbtdb, rbtnode, rbtversion, newheader, options, ISC_FALSE, addedrdataset, now); if (result == ISC_R_SUCCESS && delegating) rbtnode->find_callback = 1; NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_write); if (tree_locked) RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); /* * Update the zone's secure status. If version is non-NULL * this is deferred until closeversion() is called. */ if (result == ISC_R_SUCCESS && version == NULL && !IS_CACHE(rbtdb)) iszonesecure(db, version, rbtdb->origin_node); return (result); } static isc_result_t subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdataset_t *rdataset, unsigned int options, dns_rdataset_t *newrdataset) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node; rbtdb_version_t *rbtversion = version; rdatasetheader_t *topheader, *topheader_prev, *header, *newheader; unsigned char *subresult; isc_region_t region; isc_result_t result; rbtdb_changed_t *changed; REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(rbtversion != NULL && rbtversion->rbtdb == rbtdb); if (rbtdb->common.methods == &zone_methods) REQUIRE(((rbtnode->nsec == DNS_RBT_NSEC_NSEC3 && (rdataset->type == dns_rdatatype_nsec3 || rdataset->covers == dns_rdatatype_nsec3)) || (rbtnode->nsec != DNS_RBT_NSEC_NSEC3 && rdataset->type != dns_rdatatype_nsec3 && rdataset->covers != dns_rdatatype_nsec3))); result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx, ®ion, sizeof(rdatasetheader_t)); if (result != ISC_R_SUCCESS) return (result); newheader = (rdatasetheader_t *)region.base; init_rdataset(rbtdb, newheader); set_ttl(rbtdb, newheader, rdataset->ttl); newheader->type = RBTDB_RDATATYPE_VALUE(rdataset->type, rdataset->covers); newheader->attributes = 0; newheader->serial = rbtversion->serial; newheader->trust = 0; newheader->noqname = NULL; newheader->closest = NULL; newheader->count = init_count++; newheader->additional_auth = NULL; newheader->additional_glue = NULL; newheader->last_used = 0; newheader->node = rbtnode; if ((rdataset->attributes & DNS_RDATASETATTR_RESIGN) != 0) { newheader->attributes |= RDATASET_ATTR_RESIGN; newheader->resign = rdataset->resign; } else newheader->resign = 0; NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_write); changed = add_changed(rbtdb, rbtversion, rbtnode); if (changed == NULL) { free_rdataset(rbtdb, rbtdb->common.mctx, newheader); NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_write); return (ISC_R_NOMEMORY); } topheader_prev = NULL; for (topheader = rbtnode->data; topheader != NULL; topheader = topheader->next) { if (topheader->type == newheader->type) break; topheader_prev = topheader; } /* * If header isn't NULL, we've found the right type. There may be * IGNORE rdatasets between the top of the chain and the first real * data. We skip over them. */ header = topheader; while (header != NULL && IGNORE(header)) header = header->down; if (header != NULL && EXISTS(header)) { unsigned int flags = 0; subresult = NULL; result = ISC_R_SUCCESS; if ((options & DNS_DBSUB_EXACT) != 0) { flags |= DNS_RDATASLAB_EXACT; if (newheader->rdh_ttl != header->rdh_ttl) result = DNS_R_NOTEXACT; } if (result == ISC_R_SUCCESS) result = dns_rdataslab_subtract( (unsigned char *)header, (unsigned char *)newheader, (unsigned int)(sizeof(*newheader)), rbtdb->common.mctx, rbtdb->common.rdclass, (dns_rdatatype_t)header->type, flags, &subresult); if (result == ISC_R_SUCCESS) { free_rdataset(rbtdb, rbtdb->common.mctx, newheader); newheader = (rdatasetheader_t *)subresult; init_rdataset(rbtdb, newheader); update_newheader(newheader, header); /* * We have to set the serial since the rdataslab * subtraction routine copies the reserved portion of * header, not newheader. */ newheader->serial = rbtversion->serial; /* * XXXJT: dns_rdataslab_subtract() copied the pointers * to additional info. We need to clear these fields * to avoid having duplicated references. */ newheader->additional_auth = NULL; newheader->additional_glue = NULL; } else if (result == DNS_R_NXRRSET) { /* * This subtraction would remove all of the rdata; * add a nonexistent header instead. */ free_rdataset(rbtdb, rbtdb->common.mctx, newheader); newheader = new_rdataset(rbtdb, rbtdb->common.mctx); if (newheader == NULL) { result = ISC_R_NOMEMORY; goto unlock; } init_rdataset(rbtdb, newheader); set_ttl(rbtdb, newheader, 0); newheader->type = topheader->type; newheader->attributes = RDATASET_ATTR_NONEXISTENT; newheader->trust = 0; newheader->serial = rbtversion->serial; newheader->noqname = NULL; newheader->closest = NULL; newheader->count = 0; newheader->additional_auth = NULL; newheader->additional_glue = NULL; newheader->node = rbtnode; newheader->resign = 0; newheader->last_used = 0; } else { free_rdataset(rbtdb, rbtdb->common.mctx, newheader); goto unlock; } /* * If we're here, we want to link newheader in front of * topheader. */ INSIST(rbtversion->serial >= topheader->serial); if (topheader_prev != NULL) topheader_prev->next = newheader; else rbtnode->data = newheader; newheader->next = topheader->next; newheader->down = topheader; topheader->next = newheader; rbtnode->dirty = 1; changed->dirty = ISC_TRUE; resign_delete(rbtdb, rbtversion, header); } else { /* * The rdataset doesn't exist, so we don't need to do anything * to satisfy the deletion request. */ free_rdataset(rbtdb, rbtdb->common.mctx, newheader); if ((options & DNS_DBSUB_EXACT) != 0) result = DNS_R_NOTEXACT; else result = DNS_R_UNCHANGED; } if (result == ISC_R_SUCCESS && newrdataset != NULL) bind_rdataset(rbtdb, rbtnode, newheader, 0, newrdataset); unlock: NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_write); /* * Update the zone's secure status. If version is non-NULL * this is deferred until closeversion() is called. */ if (result == ISC_R_SUCCESS && version == NULL && !IS_CACHE(rbtdb)) iszonesecure(db, rbtdb->current_version, rbtdb->origin_node); return (result); } static isc_result_t deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdatatype_t type, dns_rdatatype_t covers) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node; rbtdb_version_t *rbtversion = version; isc_result_t result; rdatasetheader_t *newheader; REQUIRE(VALID_RBTDB(rbtdb)); INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb); if (type == dns_rdatatype_any) return (ISC_R_NOTIMPLEMENTED); if (type == dns_rdatatype_rrsig && covers == 0) return (ISC_R_NOTIMPLEMENTED); newheader = new_rdataset(rbtdb, rbtdb->common.mctx); if (newheader == NULL) return (ISC_R_NOMEMORY); init_rdataset(rbtdb, newheader); set_ttl(rbtdb, newheader, 0); newheader->type = RBTDB_RDATATYPE_VALUE(type, covers); newheader->attributes = RDATASET_ATTR_NONEXISTENT; newheader->trust = 0; newheader->noqname = NULL; newheader->closest = NULL; newheader->additional_auth = NULL; newheader->additional_glue = NULL; if (rbtversion != NULL) newheader->serial = rbtversion->serial; else newheader->serial = 0; newheader->count = 0; newheader->last_used = 0; newheader->node = rbtnode; NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_write); result = add32(rbtdb, rbtnode, rbtversion, newheader, DNS_DBADD_FORCE, ISC_FALSE, NULL, 0); NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_write); /* * Update the zone's secure status. If version is non-NULL * this is deferred until closeversion() is called. */ if (result == ISC_R_SUCCESS && version == NULL && !IS_CACHE(rbtdb)) iszonesecure(db, rbtdb->current_version, rbtdb->origin_node); return (result); } /* * load a non-NSEC3 node in the main tree and optionally to the auxiliary NSEC */ static isc_result_t loadnode(dns_rbtdb_t *rbtdb, dns_name_t *name, dns_rbtnode_t **nodep, isc_boolean_t hasnsec) { isc_result_t noderesult, rpzresult, nsecresult, tmpresult; dns_rbtnode_t *nsecnode = NULL, *node = NULL; noderesult = dns_rbt_addnode(rbtdb->tree, name, &node); if (rbtdb->rpzs != NULL && (noderesult == ISC_R_SUCCESS || noderesult == ISC_R_EXISTS)) { rpzresult = dns_rpz_add(rbtdb->load_rpzs, rbtdb->rpz_num, name); if (rpzresult == ISC_R_SUCCESS) { node->rpz = 1; } else if (noderesult != ISC_R_EXISTS) { /* * Remove the node we just added above. */ tmpresult = dns_rbt_deletenode(rbtdb->tree, node, ISC_FALSE); if (tmpresult != ISC_R_SUCCESS) isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_WARNING, "loading_addrdataset: " "dns_rbt_deletenode: %s after " "dns_rbt_addnode(NSEC): %s", isc_result_totext(tmpresult), isc_result_totext(ISC_R_SUCCESS)); } } if (!hasnsec) goto done; if (noderesult == ISC_R_EXISTS) { /* * Add a node to the auxiliary NSEC tree for an old node * just now getting an NSEC record. */ if (node->nsec == DNS_RBT_NSEC_HAS_NSEC) goto done; } else if (noderesult != ISC_R_SUCCESS) goto done; /* * Build the auxiliary tree for NSECs as we go. * This tree speeds searches for closest NSECs that would otherwise * need to examine many irrelevant nodes in large TLDs. * * Add nodes to the auxiliary tree after corresponding nodes have * been added to the main tree. */ nsecresult = dns_rbt_addnode(rbtdb->nsec, name, &nsecnode); if (nsecresult == ISC_R_SUCCESS) { nsecnode->nsec = DNS_RBT_NSEC_NSEC; node->nsec = DNS_RBT_NSEC_HAS_NSEC; goto done; } if (nsecresult == ISC_R_EXISTS) { #if 1 /* 0 */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_WARNING, "addnode: NSEC node already exists"); #endif node->nsec = DNS_RBT_NSEC_HAS_NSEC; goto done; } if (noderesult == ISC_R_SUCCESS) { unsigned int node_has_rpz; /* * Remove the node we just added above. */ node_has_rpz = node->rpz; tmpresult = dns_rbt_deletenode(rbtdb->tree, node, ISC_FALSE); if (tmpresult == ISC_R_SUCCESS) { /* * Clean rpz entries added above. */ if (rbtdb->rpzs != NULL && node_has_rpz) dns_rpz_delete(rbtdb->load_rpzs, rbtdb->rpz_num, name); } else { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_WARNING, "loading_addrdataset: " "dns_rbt_deletenode: %s after " "dns_rbt_addnode(NSEC): %s", isc_result_totext(tmpresult), isc_result_totext(noderesult)); } } /* * Set the error condition to be returned. */ noderesult = nsecresult; done: if (noderesult == ISC_R_SUCCESS || noderesult == ISC_R_EXISTS) *nodep = node; return (noderesult); } static isc_result_t loading_addrdataset(void *arg, dns_name_t *name, dns_rdataset_t *rdataset) { rbtdb_load_t *loadctx = arg; dns_rbtdb_t *rbtdb = loadctx->rbtdb; dns_rbtnode_t *node; isc_result_t result; isc_region_t region; rdatasetheader_t *newheader; /* * This routine does no node locking. See comments in * 'load' below for more information on loading and * locking. */ /* * SOA records are only allowed at top of zone. */ if (rdataset->type == dns_rdatatype_soa && !IS_CACHE(rbtdb) && !dns_name_equal(name, &rbtdb->common.origin)) return (DNS_R_NOTZONETOP); if (rdataset->type != dns_rdatatype_nsec3 && rdataset->covers != dns_rdatatype_nsec3) add_empty_wildcards(rbtdb, name); if (dns_name_iswildcard(name)) { /* * NS record owners cannot legally be wild cards. */ if (rdataset->type == dns_rdatatype_ns) return (DNS_R_INVALIDNS); /* * NSEC3 record owners cannot legally be wild cards. */ if (rdataset->type == dns_rdatatype_nsec3) return (DNS_R_INVALIDNSEC3); result = add_wildcard_magic(rbtdb, name); if (result != ISC_R_SUCCESS) return (result); } node = NULL; if (rdataset->type == dns_rdatatype_nsec3 || rdataset->covers == dns_rdatatype_nsec3) { result = dns_rbt_addnode(rbtdb->nsec3, name, &node); if (result == ISC_R_SUCCESS) node->nsec = DNS_RBT_NSEC_NSEC3; } else if (rdataset->type == dns_rdatatype_nsec) { result = loadnode(rbtdb, name, &node, ISC_TRUE); } else { result = loadnode(rbtdb, name, &node, ISC_FALSE); } if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) return (result); if (result == ISC_R_SUCCESS) { dns_name_t foundname; dns_name_init(&foundname, NULL); dns_rbt_namefromnode(node, &foundname); #ifdef DNS_RBT_USEHASH node->locknum = node->hashval % rbtdb->node_lock_count; #else node->locknum = dns_name_hash(&foundname, ISC_TRUE) % rbtdb->node_lock_count; #endif } result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx, ®ion, sizeof(rdatasetheader_t)); if (result != ISC_R_SUCCESS) return (result); newheader = (rdatasetheader_t *)region.base; init_rdataset(rbtdb, newheader); set_ttl(rbtdb, newheader, rdataset->ttl + loadctx->now); /* XXX overflow check */ newheader->type = RBTDB_RDATATYPE_VALUE(rdataset->type, rdataset->covers); newheader->attributes = 0; newheader->trust = rdataset->trust; newheader->serial = 1; newheader->noqname = NULL; newheader->closest = NULL; newheader->count = init_count++; newheader->additional_auth = NULL; newheader->additional_glue = NULL; newheader->last_used = 0; newheader->node = node; if ((rdataset->attributes & DNS_RDATASETATTR_RESIGN) != 0) { newheader->attributes |= RDATASET_ATTR_RESIGN; newheader->resign = rdataset->resign; } else newheader->resign = 0; result = add32(rbtdb, node, rbtdb->current_version, newheader, DNS_DBADD_MERGE, ISC_TRUE, NULL, 0); if (result == ISC_R_SUCCESS && delegating_type(rbtdb, node, rdataset->type)) node->find_callback = 1; else if (result == DNS_R_UNCHANGED) result = ISC_R_SUCCESS; return (result); } static isc_result_t rbt_datafixer(dns_rbtnode_t *rbtnode, void *base, size_t filesize, void *arg, isc_uint64_t *crc) { isc_result_t result; dns_rbtdb_t *rbtdb = (dns_rbtdb_t *) arg; rdatasetheader_t *header; unsigned char *limit = ((unsigned char *) base) + filesize; unsigned char *p; size_t size; REQUIRE(rbtnode != NULL); for (header = rbtnode->data; header != NULL; header = header->next) { p = (unsigned char *) header; size = dns_rdataslab_size(p, sizeof(*header)); isc_crc64_update(crc, p, size); #ifdef DEBUG hexdump("hashing header", p, sizeof(rdatasetheader_t)); hexdump("hashing slab", p + sizeof(rdatasetheader_t), size - sizeof(rdatasetheader_t)); #endif header->serial = 1; header->is_mmapped = 1; header->node = rbtnode; header->node_is_relative = 0; if (rbtdb != NULL && RESIGN(header) && header->resign != 0) { int idx = header->node->locknum; result = isc_heap_insert(rbtdb->heaps[idx], header); if (result != ISC_R_SUCCESS) return (result); } if (header->next != NULL) { size_t cooked = dns_rbt_serialize_align(size); if ((uintptr_t)header->next != (p - (unsigned char *)base) + cooked) return (ISC_R_INVALIDFILE); header->next = (rdatasetheader_t *)(p + cooked); header->next_is_relative = 0; if ((header->next < (rdatasetheader_t *) base) || (header->next > (rdatasetheader_t *) limit)) return (ISC_R_INVALIDFILE); } } return (ISC_R_SUCCESS); } /* * Load the RBT database from the image in 'f' */ static isc_result_t deserialize32(void *arg, FILE *f, off_t offset) { isc_result_t result; rbtdb_load_t *loadctx = arg; dns_rbtdb_t *rbtdb = loadctx->rbtdb; rbtdb_file_header_t *header; int fd; off_t filesize = 0; char *base; dns_rbt_t *temporary_rbt = NULL; int protect, flags; REQUIRE(VALID_RBTDB(rbtdb)); /* * TODO CKB: since this is read-write (had to be to add nodes later) * we will need to lock the file or the nodes in it before modifying * the nodes in the file. */ /* Map in the whole file in one go */ fd = fileno(f); isc_file_getsizefd(fd, &filesize); protect = PROT_READ|PROT_WRITE; flags = MAP_PRIVATE; #ifdef MAP_FILE flags |= MAP_FILE; #endif base = isc_file_mmap(NULL, filesize, protect, flags, fd, 0); if (base == NULL || base == MAP_FAILED) return (ISC_R_FAILURE); header = (rbtdb_file_header_t *)(base + offset); rbtdb->mmap_location = base; rbtdb->mmap_size = (size_t) filesize; rbtdb->origin_node = NULL; if (header->tree != 0) { result = dns_rbt_deserialize_tree(base, filesize, (off_t) header->tree, rbtdb->common.mctx, delete_callback, rbtdb, rbt_datafixer, rbtdb, &rbtdb->origin_node, &temporary_rbt); if (temporary_rbt != NULL) { dns_rbt_destroy(&rbtdb->tree); rbtdb->tree = temporary_rbt; temporary_rbt = NULL; rbtdb->origin_node = (dns_rbtnode_t *)(header->tree + base + 1024); } if (result != ISC_R_SUCCESS) return (result); } if (header->nsec != 0) { result = dns_rbt_deserialize_tree(base, filesize, (off_t) header->nsec, rbtdb->common.mctx, delete_callback, rbtdb, rbt_datafixer, rbtdb, NULL, &temporary_rbt); if (temporary_rbt != NULL) { dns_rbt_destroy(&rbtdb->nsec); rbtdb->nsec = temporary_rbt; temporary_rbt = NULL; } if (result != ISC_R_SUCCESS) return (result); } if (header->nsec3 != 0) { result = dns_rbt_deserialize_tree(base, filesize, (off_t) header->nsec3, rbtdb->common.mctx, delete_callback, rbtdb, rbt_datafixer, rbtdb, NULL, &temporary_rbt); if (temporary_rbt != NULL) { dns_rbt_destroy(&rbtdb->nsec3); rbtdb->nsec3 = temporary_rbt; temporary_rbt = NULL; } if (result != ISC_R_SUCCESS) return (result); } return (ISC_R_SUCCESS); } static isc_result_t beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) { rbtdb_load_t *loadctx; dns_rbtdb_t *rbtdb; rbtdb = (dns_rbtdb_t *)db; REQUIRE(DNS_CALLBACK_VALID(callbacks)); REQUIRE(VALID_RBTDB(rbtdb)); loadctx = isc_mem_get(rbtdb->common.mctx, sizeof(*loadctx)); if (loadctx == NULL) return (ISC_R_NOMEMORY); loadctx->rbtdb = rbtdb; if (IS_CACHE(rbtdb)) isc_stdtime_get(&loadctx->now); else loadctx->now = 0; RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); if (rbtdb->rpzs != NULL) { isc_result_t result; result = dns_rpz_beginload(&rbtdb->load_rpzs, rbtdb->rpzs, rbtdb->rpz_num); if (result != ISC_R_SUCCESS) { isc_mem_put(rbtdb->common.mctx, loadctx, sizeof(*loadctx)); return (result); } } REQUIRE((rbtdb->attributes & (RBTDB_ATTR_LOADED|RBTDB_ATTR_LOADING)) == 0); rbtdb->attributes |= RBTDB_ATTR_LOADING; RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); callbacks->add = loading_addrdataset; callbacks->add_private = loadctx; callbacks->deserialize = deserialize32; callbacks->deserialize_private = loadctx; return (ISC_R_SUCCESS); } static isc_result_t endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) { rbtdb_load_t *loadctx; dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(DNS_CALLBACK_VALID(callbacks)); loadctx = callbacks->add_private; REQUIRE(loadctx != NULL); REQUIRE(loadctx->rbtdb == rbtdb); RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); REQUIRE((rbtdb->attributes & RBTDB_ATTR_LOADING) != 0); REQUIRE((rbtdb->attributes & RBTDB_ATTR_LOADED) == 0); rbtdb->attributes &= ~RBTDB_ATTR_LOADING; rbtdb->attributes |= RBTDB_ATTR_LOADED; RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); /* * If there's a KEY rdataset at the zone origin containing a * zone key, we consider the zone secure. */ if (! IS_CACHE(rbtdb) && rbtdb->origin_node != NULL) iszonesecure(db, rbtdb->current_version, rbtdb->origin_node); callbacks->add = NULL; callbacks->add_private = NULL; callbacks->deserialize = NULL; callbacks->deserialize_private = NULL; isc_mem_put(rbtdb->common.mctx, loadctx, sizeof(*loadctx)); return (ISC_R_SUCCESS); } /* * helper function to handle writing out the rdataset data pointed to * by the void *data pointer in the dns_rbtnode */ static isc_result_t rbt_datawriter(FILE *rbtfile, unsigned char *data, void *arg, isc_uint64_t *crc) { rbtdb_version_t *version = (rbtdb_version_t *) arg; rbtdb_serial_t serial; rdatasetheader_t newheader; rdatasetheader_t *header = (rdatasetheader_t *) data, *next; off_t where; size_t cooked, size; unsigned char *p; isc_result_t result = ISC_R_SUCCESS; char pad[sizeof(char *)]; uintptr_t off; REQUIRE(rbtfile != NULL); REQUIRE(data != NULL); REQUIRE(version != NULL); serial = version->serial; for (; header != NULL; header = next) { next = header->next; do { if (header->serial <= serial && !IGNORE(header)) { if (NONEXISTENT(header)) header = NULL; break; } else header = header->down; } while (header != NULL); if (header == NULL) continue; CHECK(isc_stdio_tell(rbtfile, &where)); size = dns_rdataslab_size((unsigned char *) header, sizeof(rdatasetheader_t)); p = (unsigned char *) header; memmove(&newheader, p, sizeof(rdatasetheader_t)); newheader.down = NULL; newheader.next = NULL; off = where; if ((off_t)off != where) return (ISC_R_RANGE); newheader.node = (dns_rbtnode_t *) off; newheader.node_is_relative = 1; newheader.serial = 1; /* * Round size up to the next pointer sized offset so it * will be properly aligned when read back in. */ cooked = dns_rbt_serialize_align(size); if (next != NULL) { newheader.next = (rdatasetheader_t *) (off + cooked); newheader.next_is_relative = 1; } #ifdef DEBUG hexdump("writing header", (unsigned char *) &newheader, sizeof(rdatasetheader_t)); hexdump("writing slab", p + sizeof(rdatasetheader_t), size - sizeof(rdatasetheader_t)); #endif isc_crc64_update(crc, (unsigned char *) &newheader, sizeof(rdatasetheader_t)); CHECK(isc_stdio_write(&newheader, sizeof(rdatasetheader_t), 1, rbtfile, NULL)); isc_crc64_update(crc, p + sizeof(rdatasetheader_t), size - sizeof(rdatasetheader_t)); CHECK(isc_stdio_write(p + sizeof(rdatasetheader_t), size - sizeof(rdatasetheader_t), 1, rbtfile, NULL)); /* * Pad to force alignment. */ if (size != (size_t) cooked) { memset(pad, 0, sizeof(pad)); CHECK(isc_stdio_write(pad, cooked - size, 1, rbtfile, NULL)); } } failure: return (result); } /* * Write out a zeroed header as a placeholder. Doing this ensures * that the file will not read while it is partially written, should * writing fail or be interrupted. */ static isc_result_t rbtdb_zero_header(FILE *rbtfile) { char buffer[RBTDB_HEADER_LENGTH]; isc_result_t result; memset(buffer, 0, RBTDB_HEADER_LENGTH); result = isc_stdio_write(buffer, 1, RBTDB_HEADER_LENGTH, rbtfile, NULL); fflush(rbtfile); return (result); } static isc_once_t once = ISC_ONCE_INIT; static void init_file_version(void) { int n; memset(FILE_VERSION, 0, sizeof(FILE_VERSION)); n = snprintf(FILE_VERSION, sizeof(FILE_VERSION), "RBTDB Image %s %s", dns_major, dns_mapapi); INSIST(n > 0 && (unsigned int)n < sizeof(FILE_VERSION)); } /* * Write the file header out, recording the locations of the three * RBT's used in the rbtdb: tree, nsec, and nsec3, and including NodeDump * version information and any information stored in the rbtdb object * itself that should be stored here. */ static isc_result_t rbtdb_write_header(FILE *rbtfile, off_t tree_location, off_t nsec_location, off_t nsec3_location) { rbtdb_file_header_t header; isc_result_t result; RUNTIME_CHECK(isc_once_do(&once, init_file_version) == ISC_R_SUCCESS); memset(&header, 0, sizeof(rbtdb_file_header_t)); memmove(header.version1, FILE_VERSION, sizeof(header.version1)); memmove(header.version2, FILE_VERSION, sizeof(header.version2)); header.ptrsize = (isc_uint32_t) sizeof(void *); header.bigendian = (1 == htonl(1)) ? 1 : 0; header.tree = (isc_uint64_t) tree_location; header.nsec = (isc_uint64_t) nsec_location; header.nsec3 = (isc_uint64_t) nsec3_location; result = isc_stdio_write(&header, 1, sizeof(rbtdb_file_header_t), rbtfile, NULL); fflush(rbtfile); return (result); } static isc_result_t serialize(dns_db_t *db, dns_dbversion_t *ver, FILE *rbtfile) { rbtdb_version_t *version = (rbtdb_version_t *) ver; dns_rbtdb_t *rbtdb; isc_result_t result; off_t tree_location, nsec_location, nsec3_location, header_location; rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(rbtfile != NULL); /* Ensure we're writing to a plain file */ CHECK(isc_file_isplainfilefd(fileno(rbtfile))); /* * first, write out a zeroed header to store rbtdb information * * then for each of the three trees, store the current position * in the file and call dns_rbt_serialize_tree * * finally, write out the rbtdb header, storing the locations of the * rbtheaders * * NOTE: need to do something better with the return codes, &= will * not work. */ CHECK(isc_stdio_tell(rbtfile, &header_location)); CHECK(rbtdb_zero_header(rbtfile)); CHECK(dns_rbt_serialize_tree(rbtfile, rbtdb->tree, rbt_datawriter, version, &tree_location)); CHECK(dns_rbt_serialize_tree(rbtfile, rbtdb->nsec, rbt_datawriter, version, &nsec_location)); CHECK(dns_rbt_serialize_tree(rbtfile, rbtdb->nsec3, rbt_datawriter, version, &nsec3_location)); CHECK(isc_stdio_seek(rbtfile, header_location, SEEK_SET)); CHECK(rbtdb_write_header(rbtfile, tree_location, nsec_location, nsec3_location)); failure: return (result); } static isc_result_t dump(dns_db_t *db, dns_dbversion_t *version, const char *filename, dns_masterformat_t masterformat) { dns_rbtdb_t *rbtdb; rbtdb_version_t *rbtversion = version; rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(rbtdb)); INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb); return (dns_master_dump2(rbtdb->common.mctx, db, version, &dns_master_style_default, filename, masterformat)); } static void delete_callback(void *data, void *arg) { dns_rbtdb_t *rbtdb = arg; rdatasetheader_t *current, *next; unsigned int locknum; current = data; locknum = current->node->locknum; NODE_LOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write); while (current != NULL) { next = current->next; free_rdataset(rbtdb, rbtdb->common.mctx, current); current = next; } NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write); } static isc_boolean_t issecure(dns_db_t *db) { dns_rbtdb_t *rbtdb; isc_boolean_t secure; rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(rbtdb)); RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); secure = ISC_TF(rbtdb->current_version->secure == dns_db_secure); RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); return (secure); } static isc_boolean_t isdnssec(dns_db_t *db) { dns_rbtdb_t *rbtdb; isc_boolean_t dnssec; rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(rbtdb)); RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); dnssec = ISC_TF(rbtdb->current_version->secure != dns_db_insecure); RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); return (dnssec); } static unsigned int nodecount(dns_db_t *db) { dns_rbtdb_t *rbtdb; unsigned int count; rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(rbtdb)); RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); count = dns_rbt_nodecount(rbtdb->tree); RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); return (count); } static unsigned int hashsize(dns_db_t *db) { dns_rbtdb_t *rbtdb; unsigned int count; rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(rbtdb)); RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); count = dns_rbt_hashsize(rbtdb->tree); RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); return (count); } static void settask(dns_db_t *db, isc_task_t *task) { dns_rbtdb_t *rbtdb; rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(rbtdb)); RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); if (rbtdb->task != NULL) isc_task_detach(&rbtdb->task); if (task != NULL) isc_task_attach(task, &rbtdb->task); RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); } static isc_boolean_t ispersistent(dns_db_t *db) { UNUSED(db); return (ISC_FALSE); } static isc_result_t getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; dns_rbtnode_t *onode; isc_result_t result = ISC_R_SUCCESS; REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(nodep != NULL && *nodep == NULL); /* Note that the access to origin_node doesn't require a DB lock */ onode = (dns_rbtnode_t *)rbtdb->origin_node; if (onode != NULL) { NODE_STRONGLOCK(&rbtdb->node_locks[onode->locknum].lock); new_reference(rbtdb, onode); NODE_STRONGUNLOCK(&rbtdb->node_locks[onode->locknum].lock); *nodep = rbtdb->origin_node; } else { INSIST(IS_CACHE(rbtdb)); result = ISC_R_NOTFOUND; } return (result); } static isc_result_t getnsec3parameters(dns_db_t *db, dns_dbversion_t *version, dns_hash_t *hash, isc_uint8_t *flags, isc_uint16_t *iterations, unsigned char *salt, size_t *salt_length) { dns_rbtdb_t *rbtdb; isc_result_t result = ISC_R_NOTFOUND; rbtdb_version_t *rbtversion = version; rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(rbtdb)); INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb); RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); if (rbtversion == NULL) rbtversion = rbtdb->current_version; if (rbtversion->havensec3) { if (hash != NULL) *hash = rbtversion->hash; if (salt != NULL && salt_length != NULL) { REQUIRE(*salt_length >= rbtversion->salt_length); memmove(salt, rbtversion->salt, rbtversion->salt_length); } if (salt_length != NULL) *salt_length = rbtversion->salt_length; if (iterations != NULL) *iterations = rbtversion->iterations; if (flags != NULL) *flags = rbtversion->flags; result = ISC_R_SUCCESS; } RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); return (result); } static isc_result_t setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, isc_stdtime_t resign) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; isc_stdtime_t oldresign; isc_result_t result = ISC_R_SUCCESS; rdatasetheader_t *header; REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(!IS_CACHE(rbtdb)); REQUIRE(rdataset != NULL); header = rdataset->private3; header--; NODE_LOCK(&rbtdb->node_locks[header->node->locknum].lock, isc_rwlocktype_write); oldresign = header->resign; header->resign = resign; if (header->heap_index != 0) { INSIST(RESIGN(header)); if (resign == 0) { isc_heap_delete(rbtdb->heaps[header->node->locknum], header->heap_index); header->heap_index = 0; } else if (resign < oldresign) isc_heap_increased(rbtdb->heaps[header->node->locknum], header->heap_index); else if (resign > oldresign) isc_heap_decreased(rbtdb->heaps[header->node->locknum], header->heap_index); } else if (resign && header->heap_index == 0) { header->attributes |= RDATASET_ATTR_RESIGN; result = resign_insert(rbtdb, header->node->locknum, header); } NODE_UNLOCK(&rbtdb->node_locks[header->node->locknum].lock, isc_rwlocktype_write); return (result); } static isc_result_t getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, dns_name_t *foundname) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; rdatasetheader_t *header = NULL, *this; unsigned int i; isc_result_t result = ISC_R_NOTFOUND; unsigned int locknum; REQUIRE(VALID_RBTDB(rbtdb)); RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); for (i = 0; i < rbtdb->node_lock_count; i++) { NODE_LOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_read); this = isc_heap_element(rbtdb->heaps[i], 1); if (this == NULL) { NODE_UNLOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_read); continue; } if (header == NULL) header = this; else if (isc_serial_lt(this->resign, header->resign)) { locknum = header->node->locknum; NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_read); header = this; } else NODE_UNLOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_read); } if (header == NULL) goto unlock; bind_rdataset(rbtdb, header->node, header, 0, rdataset); if (foundname != NULL) dns_rbt_fullnamefromnode(header->node, foundname); NODE_UNLOCK(&rbtdb->node_locks[header->node->locknum].lock, isc_rwlocktype_read); result = ISC_R_SUCCESS; unlock: RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); return (result); } static void resigned(dns_db_t *db, dns_rdataset_t *rdataset, dns_dbversion_t *version) { rbtdb_version_t *rbtversion = (rbtdb_version_t *)version; dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; dns_rbtnode_t *node; rdatasetheader_t *header; REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(rdataset != NULL); REQUIRE(rdataset->methods == &rdataset_methods); REQUIRE(rbtdb->future_version == rbtversion); REQUIRE(rbtversion != NULL); REQUIRE(rbtversion->writer); REQUIRE(rbtversion->rbtdb == rbtdb); node = rdataset->private2; INSIST(node != NULL); header = rdataset->private3; INSIST(header != NULL); header--; if (header->heap_index == 0) return; RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); NODE_LOCK(&rbtdb->node_locks[node->locknum].lock, isc_rwlocktype_write); /* * Delete from heap and save to re-signed list so that it can * be restored if we backout of this change. */ resign_delete(rbtdb, rbtversion, header); NODE_UNLOCK(&rbtdb->node_locks[node->locknum].lock, isc_rwlocktype_write); RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); } static isc_result_t setcachestats(dns_db_t *db, isc_stats_t *stats) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(IS_CACHE(rbtdb)); /* current restriction */ REQUIRE(stats != NULL); isc_stats_attach(stats, &rbtdb->cachestats); return (ISC_R_SUCCESS); } static dns_stats_t * getrrsetstats(dns_db_t *db) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(IS_CACHE(rbtdb)); /* current restriction */ return (rbtdb->rrsetstats); } static dns_dbmethods_t zone_methods = { attach, detach, beginload, endload, serialize, dump, currentversion, newversion, attachversion, closeversion, findnode, zone_find, zone_findzonecut, attachnode, detachnode, expirenode, printnode, createiterator, zone_findrdataset, allrdatasets, addrdataset, subtractrdataset, deleterdataset, issecure, nodecount, ispersistent, overmem, settask, getoriginnode, NULL, getnsec3parameters, findnsec3node, setsigningtime, getsigningtime, resigned, isdnssec, NULL, rpz_attach, rpz_ready, NULL, NULL, NULL, hashsize }; static dns_dbmethods_t cache_methods = { attach, detach, beginload, endload, NULL, dump, currentversion, newversion, attachversion, closeversion, findnode, cache_find, cache_findzonecut, attachnode, detachnode, expirenode, printnode, createiterator, cache_findrdataset, allrdatasets, addrdataset, subtractrdataset, deleterdataset, issecure, nodecount, ispersistent, overmem, settask, getoriginnode, NULL, NULL, NULL, NULL, NULL, NULL, isdnssec, getrrsetstats, NULL, NULL, NULL, NULL, setcachestats, hashsize }; isc_result_t #ifdef DNS_RBTDB_VERSION64 dns_rbtdb64_create #else dns_rbtdb_create #endif (isc_mem_t *mctx, dns_name_t *origin, dns_dbtype_t type, dns_rdataclass_t rdclass, unsigned int argc, char *argv[], void *driverarg, dns_db_t **dbp) { dns_rbtdb_t *rbtdb; isc_result_t result; int i; dns_name_t name; isc_boolean_t (*sooner)(void *, void *); isc_mem_t *hmctx = mctx; /* Keep the compiler happy. */ UNUSED(driverarg); rbtdb = isc_mem_get(mctx, sizeof(*rbtdb)); if (rbtdb == NULL) return (ISC_R_NOMEMORY); /* * If argv[0] exists, it points to a memory context to use for heap */ if (argc != 0) hmctx = (isc_mem_t *) argv[0]; memset(rbtdb, '\0', sizeof(*rbtdb)); dns_name_init(&rbtdb->common.origin, NULL); rbtdb->common.attributes = 0; if (type == dns_dbtype_cache) { rbtdb->common.methods = &cache_methods; rbtdb->common.attributes |= DNS_DBATTR_CACHE; } else if (type == dns_dbtype_stub) { rbtdb->common.methods = &zone_methods; rbtdb->common.attributes |= DNS_DBATTR_STUB; } else rbtdb->common.methods = &zone_methods; rbtdb->common.rdclass = rdclass; rbtdb->common.mctx = NULL; result = RBTDB_INITLOCK(&rbtdb->lock); if (result != ISC_R_SUCCESS) goto cleanup_rbtdb; result = isc_rwlock_init(&rbtdb->tree_lock, 0, 0); if (result != ISC_R_SUCCESS) goto cleanup_lock; /* * Initialize node_lock_count in a generic way to support future * extension which allows the user to specify this value on creation. * Note that when specified for a cache DB it must be larger than 1 * as commented with the definition of DEFAULT_CACHE_NODE_LOCK_COUNT. */ if (rbtdb->node_lock_count == 0) { if (IS_CACHE(rbtdb)) rbtdb->node_lock_count = DEFAULT_CACHE_NODE_LOCK_COUNT; else rbtdb->node_lock_count = DEFAULT_NODE_LOCK_COUNT; } else if (rbtdb->node_lock_count < 2 && IS_CACHE(rbtdb)) { result = ISC_R_RANGE; goto cleanup_tree_lock; } INSIST(rbtdb->node_lock_count < (1 << DNS_RBT_LOCKLENGTH)); rbtdb->node_locks = isc_mem_get(mctx, rbtdb->node_lock_count * sizeof(rbtdb_nodelock_t)); if (rbtdb->node_locks == NULL) { result = ISC_R_NOMEMORY; goto cleanup_tree_lock; } rbtdb->cachestats = NULL; rbtdb->rrsetstats = NULL; if (IS_CACHE(rbtdb)) { result = dns_rdatasetstats_create(mctx, &rbtdb->rrsetstats); if (result != ISC_R_SUCCESS) goto cleanup_node_locks; rbtdb->rdatasets = isc_mem_get(mctx, rbtdb->node_lock_count * sizeof(rdatasetheaderlist_t)); if (rbtdb->rdatasets == NULL) { result = ISC_R_NOMEMORY; goto cleanup_rrsetstats; } for (i = 0; i < (int)rbtdb->node_lock_count; i++) ISC_LIST_INIT(rbtdb->rdatasets[i]); } else rbtdb->rdatasets = NULL; /* * Create the heaps. */ rbtdb->heaps = isc_mem_get(hmctx, rbtdb->node_lock_count * sizeof(isc_heap_t *)); if (rbtdb->heaps == NULL) { result = ISC_R_NOMEMORY; goto cleanup_rdatasets; } for (i = 0; i < (int)rbtdb->node_lock_count; i++) rbtdb->heaps[i] = NULL; sooner = IS_CACHE(rbtdb) ? ttl_sooner : resign_sooner; for (i = 0; i < (int)rbtdb->node_lock_count; i++) { result = isc_heap_create(hmctx, sooner, set_index, 0, &rbtdb->heaps[i]); if (result != ISC_R_SUCCESS) goto cleanup_heaps; } /* * Create deadnode lists. */ rbtdb->deadnodes = isc_mem_get(mctx, rbtdb->node_lock_count * sizeof(rbtnodelist_t)); if (rbtdb->deadnodes == NULL) { result = ISC_R_NOMEMORY; goto cleanup_heaps; } for (i = 0; i < (int)rbtdb->node_lock_count; i++) ISC_LIST_INIT(rbtdb->deadnodes[i]); rbtdb->active = rbtdb->node_lock_count; for (i = 0; i < (int)(rbtdb->node_lock_count); i++) { result = NODE_INITLOCK(&rbtdb->node_locks[i].lock); if (result == ISC_R_SUCCESS) { result = isc_refcount_init(&rbtdb->node_locks[i].references, 0); if (result != ISC_R_SUCCESS) NODE_DESTROYLOCK(&rbtdb->node_locks[i].lock); } if (result != ISC_R_SUCCESS) { while (i-- > 0) { NODE_DESTROYLOCK(&rbtdb->node_locks[i].lock); isc_refcount_decrement(&rbtdb->node_locks[i].references, NULL); isc_refcount_destroy(&rbtdb->node_locks[i].references); } goto cleanup_deadnodes; } rbtdb->node_locks[i].exiting = ISC_FALSE; } /* * Attach to the mctx. The database will persist so long as there * are references to it, and attaching to the mctx ensures that our * mctx won't disappear out from under us. */ isc_mem_attach(mctx, &rbtdb->common.mctx); isc_mem_attach(hmctx, &rbtdb->hmctx); /* * Must be initialized before free_rbtdb() is called. */ isc_ondestroy_init(&rbtdb->common.ondest); /* * Make a copy of the origin name. */ result = dns_name_dupwithoffsets(origin, mctx, &rbtdb->common.origin); if (result != ISC_R_SUCCESS) { free_rbtdb(rbtdb, ISC_FALSE, NULL); return (result); } /* * Make the Red-Black Trees. */ result = dns_rbt_create(mctx, delete_callback, rbtdb, &rbtdb->tree); if (result != ISC_R_SUCCESS) { free_rbtdb(rbtdb, ISC_FALSE, NULL); return (result); } result = dns_rbt_create(mctx, delete_callback, rbtdb, &rbtdb->nsec); if (result != ISC_R_SUCCESS) { free_rbtdb(rbtdb, ISC_FALSE, NULL); return (result); } result = dns_rbt_create(mctx, delete_callback, rbtdb, &rbtdb->nsec3); if (result != ISC_R_SUCCESS) { free_rbtdb(rbtdb, ISC_FALSE, NULL); return (result); } /* * In order to set the node callback bit correctly in zone databases, * we need to know if the node has the origin name of the zone. * In loading_addrdataset() we could simply compare the new name * to the origin name, but this is expensive. Also, we don't know the * node name in addrdataset(), so we need another way of knowing the * zone's top. * * We now explicitly create a node for the zone's origin, and then * we simply remember the node's address. This is safe, because * the top-of-zone node can never be deleted, nor can its address * change. */ if (!IS_CACHE(rbtdb)) { dns_rbtnode_t *nsec3node; rbtdb->origin_node = NULL; result = dns_rbt_addnode(rbtdb->tree, &rbtdb->common.origin, &rbtdb->origin_node); if (result != ISC_R_SUCCESS) { INSIST(result != ISC_R_EXISTS); free_rbtdb(rbtdb, ISC_FALSE, NULL); return (result); } rbtdb->origin_node->nsec = DNS_RBT_NSEC_NORMAL; /* * We need to give the origin node the right locknum. */ dns_name_init(&name, NULL); dns_rbt_namefromnode(rbtdb->origin_node, &name); #ifdef DNS_RBT_USEHASH rbtdb->origin_node->locknum = rbtdb->origin_node->hashval % rbtdb->node_lock_count; #else rbtdb->origin_node->locknum = dns_name_hash(&name, ISC_TRUE) % rbtdb->node_lock_count; #endif /* * Add an apex node to the NSEC3 tree so that NSEC3 searches * return partial matches when there is only a single NSEC3 * record in the tree. */ nsec3node = NULL; result = dns_rbt_addnode(rbtdb->nsec3, &rbtdb->common.origin, &nsec3node); if (result != ISC_R_SUCCESS) { INSIST(result != ISC_R_EXISTS); free_rbtdb(rbtdb, ISC_FALSE, NULL); return (result); } nsec3node->nsec = DNS_RBT_NSEC_NSEC3; /* * We need to give the nsec3 origin node the right locknum. */ dns_name_init(&name, NULL); dns_rbt_namefromnode(nsec3node, &name); #ifdef DNS_RBT_USEHASH nsec3node->locknum = nsec3node->hashval % rbtdb->node_lock_count; #else nsec3node->locknum = dns_name_hash(&name, ISC_TRUE) % rbtdb->node_lock_count; #endif } /* * Misc. Initialization. */ result = isc_refcount_init(&rbtdb->references, 1); if (result != ISC_R_SUCCESS) { free_rbtdb(rbtdb, ISC_FALSE, NULL); return (result); } rbtdb->attributes = 0; rbtdb->task = NULL; rbtdb->rpzs = NULL; rbtdb->load_rpzs = NULL; rbtdb->rpz_num = DNS_RPZ_INVALID_NUM; /* * Version Initialization. */ rbtdb->current_serial = 1; rbtdb->least_serial = 1; rbtdb->next_serial = 2; rbtdb->current_version = allocate_version(mctx, 1, 1, ISC_FALSE); if (rbtdb->current_version == NULL) { isc_refcount_decrement(&rbtdb->references, NULL); isc_refcount_destroy(&rbtdb->references); free_rbtdb(rbtdb, ISC_FALSE, NULL); return (ISC_R_NOMEMORY); } rbtdb->current_version->rbtdb = rbtdb; rbtdb->current_version->secure = dns_db_insecure; rbtdb->current_version->havensec3 = ISC_FALSE; rbtdb->current_version->flags = 0; rbtdb->current_version->iterations = 0; rbtdb->current_version->hash = 0; rbtdb->current_version->salt_length = 0; memset(rbtdb->current_version->salt, 0, sizeof(rbtdb->current_version->salt)); rbtdb->future_version = NULL; ISC_LIST_INIT(rbtdb->open_versions); /* * Keep the current version in the open list so that list operation * won't happen in normal lookup operations. */ PREPEND(rbtdb->open_versions, rbtdb->current_version, link); rbtdb->common.magic = DNS_DB_MAGIC; rbtdb->common.impmagic = RBTDB_MAGIC; *dbp = (dns_db_t *)rbtdb; return (ISC_R_SUCCESS); cleanup_deadnodes: isc_mem_put(mctx, rbtdb->deadnodes, rbtdb->node_lock_count * sizeof(rbtnodelist_t)); cleanup_heaps: if (rbtdb->heaps != NULL) { for (i = 0 ; i < (int)rbtdb->node_lock_count ; i++) if (rbtdb->heaps[i] != NULL) isc_heap_destroy(&rbtdb->heaps[i]); isc_mem_put(hmctx, rbtdb->heaps, rbtdb->node_lock_count * sizeof(isc_heap_t *)); } cleanup_rdatasets: if (rbtdb->rdatasets != NULL) isc_mem_put(mctx, rbtdb->rdatasets, rbtdb->node_lock_count * sizeof(rdatasetheaderlist_t)); cleanup_rrsetstats: if (rbtdb->rrsetstats != NULL) dns_stats_detach(&rbtdb->rrsetstats); cleanup_node_locks: isc_mem_put(mctx, rbtdb->node_locks, rbtdb->node_lock_count * sizeof(rbtdb_nodelock_t)); cleanup_tree_lock: isc_rwlock_destroy(&rbtdb->tree_lock); cleanup_lock: RBTDB_DESTROYLOCK(&rbtdb->lock); cleanup_rbtdb: isc_mem_put(mctx, rbtdb, sizeof(*rbtdb)); return (result); } /* * Slabbed Rdataset Methods */ static void rdataset_disassociate(dns_rdataset_t *rdataset) { dns_db_t *db = rdataset->private1; dns_dbnode_t *node = rdataset->private2; detachnode(db, &node); } static isc_result_t rdataset_first(dns_rdataset_t *rdataset) { unsigned char *raw = rdataset->private3; /* RDATASLAB */ unsigned int count; count = raw[0] * 256 + raw[1]; if (count == 0) { rdataset->private5 = NULL; return (ISC_R_NOMORE); } #if DNS_RDATASET_FIXED if ((rdataset->attributes & DNS_RDATASETATTR_LOADORDER) == 0) raw += 2 + (4 * count); else #endif raw += 2; /* * The privateuint4 field is the number of rdata beyond the * cursor position, so we decrement the total count by one * before storing it. * * If DNS_RDATASETATTR_LOADORDER is not set 'raw' points to the * first record. If DNS_RDATASETATTR_LOADORDER is set 'raw' points * to the first entry in the offset table. */ count--; rdataset->privateuint4 = count; rdataset->private5 = raw; return (ISC_R_SUCCESS); } static isc_result_t rdataset_next(dns_rdataset_t *rdataset) { unsigned int count; unsigned int length; unsigned char *raw; /* RDATASLAB */ count = rdataset->privateuint4; if (count == 0) return (ISC_R_NOMORE); count--; rdataset->privateuint4 = count; /* * Skip forward one record (length + 4) or one offset (4). */ raw = rdataset->private5; #if DNS_RDATASET_FIXED if ((rdataset->attributes & DNS_RDATASETATTR_LOADORDER) == 0) { #endif length = raw[0] * 256 + raw[1]; raw += length; #if DNS_RDATASET_FIXED } rdataset->private5 = raw + 4; /* length(2) + order(2) */ #else rdataset->private5 = raw + 2; /* length(2) */ #endif return (ISC_R_SUCCESS); } static void rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) { unsigned char *raw = rdataset->private5; /* RDATASLAB */ #if DNS_RDATASET_FIXED unsigned int offset; #endif unsigned int length; isc_region_t r; unsigned int flags = 0; REQUIRE(raw != NULL); /* * Find the start of the record if not already in private5 * then skip the length and order fields. */ #if DNS_RDATASET_FIXED if ((rdataset->attributes & DNS_RDATASETATTR_LOADORDER) != 0) { offset = (raw[0] << 24) + (raw[1] << 16) + (raw[2] << 8) + raw[3]; raw = rdataset->private3; raw += offset; } #endif length = raw[0] * 256 + raw[1]; #if DNS_RDATASET_FIXED raw += 4; #else raw += 2; #endif if (rdataset->type == dns_rdatatype_rrsig) { if (*raw & DNS_RDATASLAB_OFFLINE) flags |= DNS_RDATA_OFFLINE; length--; raw++; } r.length = length; r.base = raw; dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r); rdata->flags |= flags; } static void rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { dns_db_t *db = source->private1; dns_dbnode_t *node = source->private2; dns_dbnode_t *cloned_node = NULL; attachnode(db, node, &cloned_node); INSIST(!ISC_LINK_LINKED(target, link)); *target = *source; ISC_LINK_INIT(target, link); /* * Reset iterator state. */ target->privateuint4 = 0; target->private5 = NULL; } static unsigned int rdataset_count(dns_rdataset_t *rdataset) { unsigned char *raw = rdataset->private3; /* RDATASLAB */ unsigned int count; count = raw[0] * 256 + raw[1]; return (count); } static isc_result_t rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name, dns_rdataset_t *nsec, dns_rdataset_t *nsecsig) { dns_db_t *db = rdataset->private1; dns_dbnode_t *node = rdataset->private2; dns_dbnode_t *cloned_node; struct noqname *noqname = rdataset->private6; cloned_node = NULL; attachnode(db, node, &cloned_node); nsec->methods = &rdataset_methods; nsec->rdclass = db->rdclass; nsec->type = noqname->type; nsec->covers = 0; nsec->ttl = rdataset->ttl; nsec->trust = rdataset->trust; nsec->private1 = rdataset->private1; nsec->private2 = rdataset->private2; nsec->private3 = noqname->neg; nsec->privateuint4 = 0; nsec->private5 = NULL; nsec->private6 = NULL; nsec->private7 = NULL; cloned_node = NULL; attachnode(db, node, &cloned_node); nsecsig->methods = &rdataset_methods; nsecsig->rdclass = db->rdclass; nsecsig->type = dns_rdatatype_rrsig; nsecsig->covers = noqname->type; nsecsig->ttl = rdataset->ttl; nsecsig->trust = rdataset->trust; nsecsig->private1 = rdataset->private1; nsecsig->private2 = rdataset->private2; nsecsig->private3 = noqname->negsig; nsecsig->privateuint4 = 0; nsecsig->private5 = NULL; nsec->private6 = NULL; nsec->private7 = NULL; dns_name_clone(&noqname->name, name); return (ISC_R_SUCCESS); } static isc_result_t rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name, dns_rdataset_t *nsec, dns_rdataset_t *nsecsig) { dns_db_t *db = rdataset->private1; dns_dbnode_t *node = rdataset->private2; dns_dbnode_t *cloned_node; struct noqname *closest = rdataset->private7; cloned_node = NULL; attachnode(db, node, &cloned_node); nsec->methods = &rdataset_methods; nsec->rdclass = db->rdclass; nsec->type = closest->type; nsec->covers = 0; nsec->ttl = rdataset->ttl; nsec->trust = rdataset->trust; nsec->private1 = rdataset->private1; nsec->private2 = rdataset->private2; nsec->private3 = closest->neg; nsec->privateuint4 = 0; nsec->private5 = NULL; nsec->private6 = NULL; nsec->private7 = NULL; cloned_node = NULL; attachnode(db, node, &cloned_node); nsecsig->methods = &rdataset_methods; nsecsig->rdclass = db->rdclass; nsecsig->type = dns_rdatatype_rrsig; nsecsig->covers = closest->type; nsecsig->ttl = rdataset->ttl; nsecsig->trust = rdataset->trust; nsecsig->private1 = rdataset->private1; nsecsig->private2 = rdataset->private2; nsecsig->private3 = closest->negsig; nsecsig->privateuint4 = 0; nsecsig->private5 = NULL; nsec->private6 = NULL; nsec->private7 = NULL; dns_name_clone(&closest->name, name); return (ISC_R_SUCCESS); } static void rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) { dns_rbtdb_t *rbtdb = rdataset->private1; dns_rbtnode_t *rbtnode = rdataset->private2; rdatasetheader_t *header = rdataset->private3; header--; NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_write); header->trust = rdataset->trust = trust; NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_write); } static void rdataset_expire(dns_rdataset_t *rdataset) { dns_rbtdb_t *rbtdb = rdataset->private1; dns_rbtnode_t *rbtnode = rdataset->private2; rdatasetheader_t *header = rdataset->private3; header--; NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_write); expire_header(rbtdb, header, ISC_FALSE, expire_flush); NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_write); } static void rdataset_clearprefetch(dns_rdataset_t *rdataset) { dns_rbtdb_t *rbtdb = rdataset->private1; dns_rbtnode_t *rbtnode = rdataset->private2; rdatasetheader_t *header = rdataset->private3; header--; NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_write); header->attributes &= ~RDATASET_ATTR_PREFETCH; NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_write); } /* * Rdataset Iterator Methods */ static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) { rbtdb_rdatasetiter_t *rbtiterator; rbtiterator = (rbtdb_rdatasetiter_t *)(*iteratorp); if (rbtiterator->common.version != NULL) closeversion(rbtiterator->common.db, &rbtiterator->common.version, ISC_FALSE); detachnode(rbtiterator->common.db, &rbtiterator->common.node); isc_mem_put(rbtiterator->common.db->mctx, rbtiterator, sizeof(*rbtiterator)); *iteratorp = NULL; } static isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator) { rbtdb_rdatasetiter_t *rbtiterator = (rbtdb_rdatasetiter_t *)iterator; dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)(rbtiterator->common.db); dns_rbtnode_t *rbtnode = rbtiterator->common.node; rbtdb_version_t *rbtversion = rbtiterator->common.version; rdatasetheader_t *header, *top_next; rbtdb_serial_t serial; isc_stdtime_t now; if (IS_CACHE(rbtdb)) { serial = 1; now = rbtiterator->common.now; } else { serial = rbtversion->serial; now = 0; } NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_read); for (header = rbtnode->data; header != NULL; header = top_next) { top_next = header->next; do { if (header->serial <= serial && !IGNORE(header)) { /* * Is this a "this rdataset doesn't exist" * record? Or is it too old in the cache? * * Note: unlike everywhere else, we * check for now > header->rdh_ttl instead * of now >= header->rdh_ttl. This allows * ANY and RRSIG queries for 0 TTL * rdatasets to work. */ if (NONEXISTENT(header) || (now != 0 && now > header->rdh_ttl)) header = NULL; break; } else header = header->down; } while (header != NULL); if (header != NULL) break; } NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_read); rbtiterator->current = header; if (header == NULL) return (ISC_R_NOMORE); return (ISC_R_SUCCESS); } static isc_result_t rdatasetiter_next(dns_rdatasetiter_t *iterator) { rbtdb_rdatasetiter_t *rbtiterator = (rbtdb_rdatasetiter_t *)iterator; dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)(rbtiterator->common.db); dns_rbtnode_t *rbtnode = rbtiterator->common.node; rbtdb_version_t *rbtversion = rbtiterator->common.version; rdatasetheader_t *header, *top_next; rbtdb_serial_t serial; isc_stdtime_t now; rbtdb_rdatatype_t type, negtype; dns_rdatatype_t rdtype, covers; header = rbtiterator->current; if (header == NULL) return (ISC_R_NOMORE); if (IS_CACHE(rbtdb)) { serial = 1; now = rbtiterator->common.now; } else { serial = rbtversion->serial; now = 0; } NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_read); type = header->type; rdtype = RBTDB_RDATATYPE_BASE(header->type); if (NEGATIVE(header)) { covers = RBTDB_RDATATYPE_EXT(header->type); negtype = RBTDB_RDATATYPE_VALUE(covers, 0); } else negtype = RBTDB_RDATATYPE_VALUE(0, rdtype); for (header = header->next; header != NULL; header = top_next) { top_next = header->next; /* * If not walking back up the down list. */ if (header->type != type && header->type != negtype) { do { if (header->serial <= serial && !IGNORE(header)) { /* * Is this a "this rdataset doesn't * exist" record? * * Note: unlike everywhere else, we * check for now > header->ttl instead * of now >= header->ttl. This allows * ANY and RRSIG queries for 0 TTL * rdatasets to work. */ if ((header->attributes & RDATASET_ATTR_NONEXISTENT) != 0 || (now != 0 && now > header->rdh_ttl)) header = NULL; break; } else header = header->down; } while (header != NULL); if (header != NULL) break; } } NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_read); rbtiterator->current = header; if (header == NULL) return (ISC_R_NOMORE); return (ISC_R_SUCCESS); } static void rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) { rbtdb_rdatasetiter_t *rbtiterator = (rbtdb_rdatasetiter_t *)iterator; dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)(rbtiterator->common.db); dns_rbtnode_t *rbtnode = rbtiterator->common.node; rdatasetheader_t *header; header = rbtiterator->current; REQUIRE(header != NULL); NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_read); bind_rdataset(rbtdb, rbtnode, header, rbtiterator->common.now, rdataset); NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_read); } /* * Database Iterator Methods */ static inline void reference_iter_node(rbtdb_dbiterator_t *rbtdbiter) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)rbtdbiter->common.db; dns_rbtnode_t *node = rbtdbiter->node; if (node == NULL) return; INSIST(rbtdbiter->tree_locked != isc_rwlocktype_none); reactivate_node(rbtdb, node, rbtdbiter->tree_locked); } static inline void dereference_iter_node(rbtdb_dbiterator_t *rbtdbiter) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)rbtdbiter->common.db; dns_rbtnode_t *node = rbtdbiter->node; nodelock_t *lock; if (node == NULL) return; lock = &rbtdb->node_locks[node->locknum].lock; NODE_LOCK(lock, isc_rwlocktype_read); decrement_reference(rbtdb, node, 0, isc_rwlocktype_read, rbtdbiter->tree_locked, ISC_FALSE); NODE_UNLOCK(lock, isc_rwlocktype_read); rbtdbiter->node = NULL; } static void flush_deletions(rbtdb_dbiterator_t *rbtdbiter) { dns_rbtnode_t *node; dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)rbtdbiter->common.db; isc_boolean_t was_read_locked = ISC_FALSE; nodelock_t *lock; int i; if (rbtdbiter->delete != 0) { /* * Note that "%d node of %d in tree" can report things like * "flush_deletions: 59 nodes of 41 in tree". This means * That some nodes appear on the deletions list more than * once. Only the last occurence will actually be deleted. */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1), "flush_deletions: %d nodes of %d in tree", rbtdbiter->delete, dns_rbt_nodecount(rbtdb->tree)); if (rbtdbiter->tree_locked == isc_rwlocktype_read) { RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); was_read_locked = ISC_TRUE; } RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); rbtdbiter->tree_locked = isc_rwlocktype_write; for (i = 0; i < rbtdbiter->delete; i++) { node = rbtdbiter->deletions[i]; lock = &rbtdb->node_locks[node->locknum].lock; NODE_LOCK(lock, isc_rwlocktype_read); decrement_reference(rbtdb, node, 0, isc_rwlocktype_read, rbtdbiter->tree_locked, ISC_FALSE); NODE_UNLOCK(lock, isc_rwlocktype_read); } rbtdbiter->delete = 0; RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); if (was_read_locked) { RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); rbtdbiter->tree_locked = isc_rwlocktype_read; } else { rbtdbiter->tree_locked = isc_rwlocktype_none; } } } static inline void resume_iteration(rbtdb_dbiterator_t *rbtdbiter) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)rbtdbiter->common.db; REQUIRE(rbtdbiter->paused); REQUIRE(rbtdbiter->tree_locked == isc_rwlocktype_none); RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); rbtdbiter->tree_locked = isc_rwlocktype_read; rbtdbiter->paused = ISC_FALSE; } static void dbiterator_destroy(dns_dbiterator_t **iteratorp) { rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)(*iteratorp); dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)rbtdbiter->common.db; dns_db_t *db = NULL; if (rbtdbiter->tree_locked == isc_rwlocktype_read) { RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); rbtdbiter->tree_locked = isc_rwlocktype_none; } else INSIST(rbtdbiter->tree_locked == isc_rwlocktype_none); dereference_iter_node(rbtdbiter); flush_deletions(rbtdbiter); dns_db_attach(rbtdbiter->common.db, &db); dns_db_detach(&rbtdbiter->common.db); dns_rbtnodechain_reset(&rbtdbiter->chain); dns_rbtnodechain_reset(&rbtdbiter->nsec3chain); isc_mem_put(db->mctx, rbtdbiter, sizeof(*rbtdbiter)); dns_db_detach(&db); *iteratorp = NULL; } static isc_result_t dbiterator_first(dns_dbiterator_t *iterator) { isc_result_t result; rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator; dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db; dns_name_t *name, *origin; if (rbtdbiter->result != ISC_R_SUCCESS && rbtdbiter->result != ISC_R_NOMORE) return (rbtdbiter->result); if (rbtdbiter->paused) resume_iteration(rbtdbiter); dereference_iter_node(rbtdbiter); name = dns_fixedname_name(&rbtdbiter->name); origin = dns_fixedname_name(&rbtdbiter->origin); dns_rbtnodechain_reset(&rbtdbiter->chain); dns_rbtnodechain_reset(&rbtdbiter->nsec3chain); if (rbtdbiter->nsec3only) { rbtdbiter->current = &rbtdbiter->nsec3chain; result = dns_rbtnodechain_first(rbtdbiter->current, rbtdb->nsec3, name, origin); } else { rbtdbiter->current = &rbtdbiter->chain; result = dns_rbtnodechain_first(rbtdbiter->current, rbtdb->tree, name, origin); if (!rbtdbiter->nonsec3 && result == ISC_R_NOTFOUND) { rbtdbiter->current = &rbtdbiter->nsec3chain; result = dns_rbtnodechain_first(rbtdbiter->current, rbtdb->nsec3, name, origin); } } if (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) { result = dns_rbtnodechain_current(rbtdbiter->current, NULL, NULL, &rbtdbiter->node); if (result == ISC_R_SUCCESS) { rbtdbiter->new_origin = ISC_TRUE; reference_iter_node(rbtdbiter); } } else { INSIST(result == ISC_R_NOTFOUND); result = ISC_R_NOMORE; /* The tree is empty. */ } rbtdbiter->result = result; return (result); } static isc_result_t dbiterator_last(dns_dbiterator_t *iterator) { isc_result_t result; rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator; dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db; dns_name_t *name, *origin; if (rbtdbiter->result != ISC_R_SUCCESS && rbtdbiter->result != ISC_R_NOMORE) return (rbtdbiter->result); if (rbtdbiter->paused) resume_iteration(rbtdbiter); dereference_iter_node(rbtdbiter); name = dns_fixedname_name(&rbtdbiter->name); origin = dns_fixedname_name(&rbtdbiter->origin); dns_rbtnodechain_reset(&rbtdbiter->chain); dns_rbtnodechain_reset(&rbtdbiter->nsec3chain); result = ISC_R_NOTFOUND; if (rbtdbiter->nsec3only && !rbtdbiter->nonsec3) { rbtdbiter->current = &rbtdbiter->nsec3chain; result = dns_rbtnodechain_last(rbtdbiter->current, rbtdb->nsec3, name, origin); } if (!rbtdbiter->nsec3only && result == ISC_R_NOTFOUND) { rbtdbiter->current = &rbtdbiter->chain; result = dns_rbtnodechain_last(rbtdbiter->current, rbtdb->tree, name, origin); } if (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) { result = dns_rbtnodechain_current(rbtdbiter->current, NULL, NULL, &rbtdbiter->node); if (result == ISC_R_SUCCESS) { rbtdbiter->new_origin = ISC_TRUE; reference_iter_node(rbtdbiter); } } else { INSIST(result == ISC_R_NOTFOUND); result = ISC_R_NOMORE; /* The tree is empty. */ } rbtdbiter->result = result; return (result); } static isc_result_t dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) { isc_result_t result, tresult; rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator; dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db; dns_name_t *iname, *origin; if (rbtdbiter->result != ISC_R_SUCCESS && rbtdbiter->result != ISC_R_NOTFOUND && rbtdbiter->result != ISC_R_NOMORE) return (rbtdbiter->result); if (rbtdbiter->paused) resume_iteration(rbtdbiter); dereference_iter_node(rbtdbiter); iname = dns_fixedname_name(&rbtdbiter->name); origin = dns_fixedname_name(&rbtdbiter->origin); dns_rbtnodechain_reset(&rbtdbiter->chain); dns_rbtnodechain_reset(&rbtdbiter->nsec3chain); if (rbtdbiter->nsec3only) { rbtdbiter->current = &rbtdbiter->nsec3chain; result = dns_rbt_findnode(rbtdb->nsec3, name, NULL, &rbtdbiter->node, rbtdbiter->current, DNS_RBTFIND_EMPTYDATA, NULL, NULL); } else if (rbtdbiter->nonsec3) { rbtdbiter->current = &rbtdbiter->chain; result = dns_rbt_findnode(rbtdb->tree, name, NULL, &rbtdbiter->node, rbtdbiter->current, DNS_RBTFIND_EMPTYDATA, NULL, NULL); } else { /* * Stay on main chain if not found on either chain. */ rbtdbiter->current = &rbtdbiter->chain; result = dns_rbt_findnode(rbtdb->tree, name, NULL, &rbtdbiter->node, rbtdbiter->current, DNS_RBTFIND_EMPTYDATA, NULL, NULL); if (result == DNS_R_PARTIALMATCH) { dns_rbtnode_t *node = NULL; tresult = dns_rbt_findnode(rbtdb->nsec3, name, NULL, &node, &rbtdbiter->nsec3chain, DNS_RBTFIND_EMPTYDATA, NULL, NULL); if (tresult == ISC_R_SUCCESS) { rbtdbiter->node = node; rbtdbiter->current = &rbtdbiter->nsec3chain; result = tresult; } } } #if 1 if (result == ISC_R_SUCCESS) { result = dns_rbtnodechain_current(rbtdbiter->current, iname, origin, NULL); if (result == ISC_R_SUCCESS) { rbtdbiter->new_origin = ISC_TRUE; reference_iter_node(rbtdbiter); } } else if (result == DNS_R_PARTIALMATCH) { result = ISC_R_NOTFOUND; rbtdbiter->node = NULL; } rbtdbiter->result = result; #else if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { isc_result_t tresult; tresult = dns_rbtnodechain_current(rbtdbiter->current, iname, origin, NULL); if (tresult == ISC_R_SUCCESS) { rbtdbiter->new_origin = ISC_TRUE; reference_iter_node(rbtdbiter); } else { result = tresult; rbtdbiter->node = NULL; } } else rbtdbiter->node = NULL; rbtdbiter->result = (result == DNS_R_PARTIALMATCH) ? ISC_R_SUCCESS : result; #endif return (result); } static isc_result_t dbiterator_prev(dns_dbiterator_t *iterator) { isc_result_t result; rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator; dns_name_t *name, *origin; dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db; REQUIRE(rbtdbiter->node != NULL); if (rbtdbiter->result != ISC_R_SUCCESS) return (rbtdbiter->result); if (rbtdbiter->paused) resume_iteration(rbtdbiter); name = dns_fixedname_name(&rbtdbiter->name); origin = dns_fixedname_name(&rbtdbiter->origin); result = dns_rbtnodechain_prev(rbtdbiter->current, name, origin); if (result == ISC_R_NOMORE && !rbtdbiter->nsec3only && !rbtdbiter->nonsec3 && &rbtdbiter->nsec3chain == rbtdbiter->current) { rbtdbiter->current = &rbtdbiter->chain; dns_rbtnodechain_reset(rbtdbiter->current); result = dns_rbtnodechain_last(rbtdbiter->current, rbtdb->tree, name, origin); if (result == ISC_R_NOTFOUND) result = ISC_R_NOMORE; } dereference_iter_node(rbtdbiter); if (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) { rbtdbiter->new_origin = ISC_TF(result == DNS_R_NEWORIGIN); result = dns_rbtnodechain_current(rbtdbiter->current, NULL, NULL, &rbtdbiter->node); } if (result == ISC_R_SUCCESS) reference_iter_node(rbtdbiter); rbtdbiter->result = result; return (result); } static isc_result_t dbiterator_next(dns_dbiterator_t *iterator) { isc_result_t result; rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator; dns_name_t *name, *origin; dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db; REQUIRE(rbtdbiter->node != NULL); if (rbtdbiter->result != ISC_R_SUCCESS) return (rbtdbiter->result); if (rbtdbiter->paused) resume_iteration(rbtdbiter); name = dns_fixedname_name(&rbtdbiter->name); origin = dns_fixedname_name(&rbtdbiter->origin); result = dns_rbtnodechain_next(rbtdbiter->current, name, origin); if (result == ISC_R_NOMORE && !rbtdbiter->nsec3only && !rbtdbiter->nonsec3 && &rbtdbiter->chain == rbtdbiter->current) { rbtdbiter->current = &rbtdbiter->nsec3chain; dns_rbtnodechain_reset(rbtdbiter->current); result = dns_rbtnodechain_first(rbtdbiter->current, rbtdb->nsec3, name, origin); if (result == ISC_R_NOTFOUND) result = ISC_R_NOMORE; } dereference_iter_node(rbtdbiter); if (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) { rbtdbiter->new_origin = ISC_TF(result == DNS_R_NEWORIGIN); result = dns_rbtnodechain_current(rbtdbiter->current, NULL, NULL, &rbtdbiter->node); } if (result == ISC_R_SUCCESS) reference_iter_node(rbtdbiter); rbtdbiter->result = result; return (result); } static isc_result_t dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep, dns_name_t *name) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db; rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator; dns_rbtnode_t *node = rbtdbiter->node; isc_result_t result; dns_name_t *nodename = dns_fixedname_name(&rbtdbiter->name); dns_name_t *origin = dns_fixedname_name(&rbtdbiter->origin); REQUIRE(rbtdbiter->result == ISC_R_SUCCESS); REQUIRE(rbtdbiter->node != NULL); if (rbtdbiter->paused) resume_iteration(rbtdbiter); if (name != NULL) { if (rbtdbiter->common.relative_names) origin = NULL; result = dns_name_concatenate(nodename, origin, name, NULL); if (result != ISC_R_SUCCESS) return (result); if (rbtdbiter->common.relative_names && rbtdbiter->new_origin) result = DNS_R_NEWORIGIN; } else result = ISC_R_SUCCESS; NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock); new_reference(rbtdb, node); NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock); *nodep = rbtdbiter->node; if (iterator->cleaning && result == ISC_R_SUCCESS) { isc_result_t expire_result; /* * If the deletion array is full, flush it before trying * to expire the current node. The current node can't * fully deleted while the iteration cursor is still on it. */ if (rbtdbiter->delete == DELETION_BATCH_MAX) flush_deletions(rbtdbiter); expire_result = expirenode(iterator->db, *nodep, 0); /* * expirenode() currently always returns success. */ if (expire_result == ISC_R_SUCCESS && node->down == NULL) { unsigned int refs; rbtdbiter->deletions[rbtdbiter->delete++] = node; NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock); dns_rbtnode_refincrement(node, &refs); INSIST(refs != 0); NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock); } } return (result); } static isc_result_t dbiterator_pause(dns_dbiterator_t *iterator) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)iterator->db; rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator; if (rbtdbiter->result != ISC_R_SUCCESS && rbtdbiter->result != ISC_R_NOMORE) return (rbtdbiter->result); if (rbtdbiter->paused) return (ISC_R_SUCCESS); rbtdbiter->paused = ISC_TRUE; if (rbtdbiter->tree_locked != isc_rwlocktype_none) { INSIST(rbtdbiter->tree_locked == isc_rwlocktype_read); RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); rbtdbiter->tree_locked = isc_rwlocktype_none; } flush_deletions(rbtdbiter); return (ISC_R_SUCCESS); } static isc_result_t dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) { rbtdb_dbiterator_t *rbtdbiter = (rbtdb_dbiterator_t *)iterator; dns_name_t *origin = dns_fixedname_name(&rbtdbiter->origin); if (rbtdbiter->result != ISC_R_SUCCESS) return (rbtdbiter->result); return (dns_name_copy(origin, name, NULL)); } /*% * Additional cache routines. */ static isc_result_t rdataset_getadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, dns_rdatatype_t qtype, dns_acache_t *acache, dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp, dns_dbnode_t **nodep, dns_name_t *fname, dns_message_t *msg, isc_stdtime_t now) { dns_rbtdb_t *rbtdb = rdataset->private1; dns_rbtnode_t *rbtnode = rdataset->private2; unsigned char *raw = rdataset->private3; /* RDATASLAB */ unsigned int current_count = rdataset->privateuint4; unsigned int count; rdatasetheader_t *header; nodelock_t *nodelock; unsigned int total_count; acachectl_t *acarray; dns_acacheentry_t *entry; isc_result_t result; UNUSED(qtype); /* we do not use this value at least for now */ UNUSED(acache); header = (struct rdatasetheader *)(raw - sizeof(*header)); total_count = raw[0] * 256 + raw[1]; INSIST(total_count > current_count); count = total_count - current_count - 1; acarray = NULL; nodelock = &rbtdb->node_locks[rbtnode->locknum].lock; NODE_LOCK(nodelock, isc_rwlocktype_read); switch (type) { case dns_rdatasetadditional_fromauth: acarray = header->additional_auth; break; case dns_rdatasetadditional_fromcache: acarray = NULL; break; case dns_rdatasetadditional_fromglue: acarray = header->additional_glue; break; default: INSIST(0); } if (acarray == NULL) { if (type != dns_rdatasetadditional_fromcache) dns_acache_countquerymiss(acache); NODE_UNLOCK(nodelock, isc_rwlocktype_read); return (ISC_R_NOTFOUND); } if (acarray[count].entry == NULL) { dns_acache_countquerymiss(acache); NODE_UNLOCK(nodelock, isc_rwlocktype_read); return (ISC_R_NOTFOUND); } entry = NULL; dns_acache_attachentry(acarray[count].entry, &entry); NODE_UNLOCK(nodelock, isc_rwlocktype_read); result = dns_acache_getentry(entry, zonep, dbp, versionp, nodep, fname, msg, now); dns_acache_detachentry(&entry); return (result); } static void acache_callback(dns_acacheentry_t *entry, void **arg) { dns_rbtdb_t *rbtdb; dns_rbtnode_t *rbtnode; nodelock_t *nodelock; acachectl_t *acarray = NULL; acache_cbarg_t *cbarg; unsigned int count; REQUIRE(arg != NULL); cbarg = *arg; /* * The caller must hold the entry lock. */ rbtdb = (dns_rbtdb_t *)cbarg->db; rbtnode = (dns_rbtnode_t *)cbarg->node; nodelock = &rbtdb->node_locks[rbtnode->locknum].lock; NODE_LOCK(nodelock, isc_rwlocktype_write); switch (cbarg->type) { case dns_rdatasetadditional_fromauth: acarray = cbarg->header->additional_auth; break; case dns_rdatasetadditional_fromglue: acarray = cbarg->header->additional_glue; break; default: INSIST(0); } count = cbarg->count; if (acarray != NULL && acarray[count].entry == entry) { acarray[count].entry = NULL; INSIST(acarray[count].cbarg == cbarg); acarray[count].cbarg = NULL; isc_mem_put(rbtdb->common.mctx, cbarg, sizeof(acache_cbarg_t)); dns_acache_detachentry(&entry); } NODE_UNLOCK(nodelock, isc_rwlocktype_write); dns_db_detachnode((dns_db_t *)rbtdb, (dns_dbnode_t **)(void*)&rbtnode); dns_db_detach((dns_db_t **)(void*)&rbtdb); *arg = NULL; } static void acache_cancelentry(isc_mem_t *mctx, dns_acacheentry_t *entry, acache_cbarg_t **cbargp) { acache_cbarg_t *cbarg; REQUIRE(mctx != NULL); REQUIRE(entry != NULL); REQUIRE(cbargp != NULL && *cbargp != NULL); cbarg = *cbargp; if (dns_acache_cancelentry(entry)) { dns_db_detachnode(cbarg->db, &cbarg->node); dns_db_detach(&cbarg->db); } isc_mem_put(mctx, cbarg, sizeof(acache_cbarg_t)); *cbargp = NULL; } static isc_result_t rdataset_setadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, dns_rdatatype_t qtype, dns_acache_t *acache, dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, dns_name_t *fname) { dns_rbtdb_t *rbtdb = rdataset->private1; dns_rbtnode_t *rbtnode = rdataset->private2; unsigned char *raw = rdataset->private3; /* RDATASLAB */ unsigned int current_count = rdataset->privateuint4; rdatasetheader_t *header; unsigned int total_count, count; nodelock_t *nodelock; isc_result_t result; acachectl_t *acarray; dns_acacheentry_t *newentry, *oldentry = NULL; acache_cbarg_t *newcbarg, *oldcbarg = NULL; UNUSED(qtype); if (type == dns_rdatasetadditional_fromcache) return (ISC_R_SUCCESS); header = (struct rdatasetheader *)(raw - sizeof(*header)); total_count = raw[0] * 256 + raw[1]; INSIST(total_count > current_count); count = total_count - current_count - 1; /* should be private data */ newcbarg = isc_mem_get(rbtdb->common.mctx, sizeof(*newcbarg)); if (newcbarg == NULL) return (ISC_R_NOMEMORY); newcbarg->type = type; newcbarg->count = count; newcbarg->header = header; newcbarg->db = NULL; dns_db_attach((dns_db_t *)rbtdb, &newcbarg->db); newcbarg->node = NULL; dns_db_attachnode((dns_db_t *)rbtdb, (dns_dbnode_t *)rbtnode, &newcbarg->node); newentry = NULL; result = dns_acache_createentry(acache, (dns_db_t *)rbtdb, acache_callback, newcbarg, &newentry); if (result != ISC_R_SUCCESS) goto fail; /* Set cache data in the new entry. */ result = dns_acache_setentry(acache, newentry, zone, db, version, node, fname); if (result != ISC_R_SUCCESS) goto fail; nodelock = &rbtdb->node_locks[rbtnode->locknum].lock; NODE_LOCK(nodelock, isc_rwlocktype_write); acarray = NULL; switch (type) { case dns_rdatasetadditional_fromauth: acarray = header->additional_auth; break; case dns_rdatasetadditional_fromglue: acarray = header->additional_glue; break; default: INSIST(0); } if (acarray == NULL) { unsigned int i; acarray = isc_mem_get(rbtdb->common.mctx, total_count * sizeof(acachectl_t)); if (acarray == NULL) { NODE_UNLOCK(nodelock, isc_rwlocktype_write); goto fail; } for (i = 0; i < total_count; i++) { acarray[i].entry = NULL; acarray[i].cbarg = NULL; } } switch (type) { case dns_rdatasetadditional_fromauth: header->additional_auth = acarray; break; case dns_rdatasetadditional_fromglue: header->additional_glue = acarray; break; default: INSIST(0); } if (acarray[count].entry != NULL) { /* * Swap the entry. Delay cleaning-up the old entry since * it would require a node lock. */ oldentry = acarray[count].entry; INSIST(acarray[count].cbarg != NULL); oldcbarg = acarray[count].cbarg; } acarray[count].entry = newentry; acarray[count].cbarg = newcbarg; NODE_UNLOCK(nodelock, isc_rwlocktype_write); if (oldentry != NULL) { acache_cancelentry(rbtdb->common.mctx, oldentry, &oldcbarg); dns_acache_detachentry(&oldentry); } return (ISC_R_SUCCESS); fail: if (newcbarg != NULL) { if (newentry != NULL) { acache_cancelentry(rbtdb->common.mctx, newentry, &newcbarg); dns_acache_detachentry(&newentry); } else { dns_db_detachnode((dns_db_t *)rbtdb, &newcbarg->node); dns_db_detach(&newcbarg->db); isc_mem_put(rbtdb->common.mctx, newcbarg, sizeof(*newcbarg)); } } return (result); } static isc_result_t rdataset_putadditional(dns_acache_t *acache, dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, dns_rdatatype_t qtype) { dns_rbtdb_t *rbtdb = rdataset->private1; dns_rbtnode_t *rbtnode = rdataset->private2; unsigned char *raw = rdataset->private3; /* RDATASLAB */ unsigned int current_count = rdataset->privateuint4; rdatasetheader_t *header; nodelock_t *nodelock; unsigned int total_count, count; acachectl_t *acarray; dns_acacheentry_t *entry; acache_cbarg_t *cbarg; UNUSED(qtype); /* we do not use this value at least for now */ UNUSED(acache); if (type == dns_rdatasetadditional_fromcache) return (ISC_R_SUCCESS); header = (struct rdatasetheader *)(raw - sizeof(*header)); total_count = raw[0] * 256 + raw[1]; INSIST(total_count > current_count); count = total_count - current_count - 1; acarray = NULL; entry = NULL; nodelock = &rbtdb->node_locks[rbtnode->locknum].lock; NODE_LOCK(nodelock, isc_rwlocktype_write); switch (type) { case dns_rdatasetadditional_fromauth: acarray = header->additional_auth; break; case dns_rdatasetadditional_fromglue: acarray = header->additional_glue; break; default: INSIST(0); } if (acarray == NULL) { NODE_UNLOCK(nodelock, isc_rwlocktype_write); return (ISC_R_NOTFOUND); } entry = acarray[count].entry; if (entry == NULL) { NODE_UNLOCK(nodelock, isc_rwlocktype_write); return (ISC_R_NOTFOUND); } acarray[count].entry = NULL; cbarg = acarray[count].cbarg; acarray[count].cbarg = NULL; NODE_UNLOCK(nodelock, isc_rwlocktype_write); if (entry != NULL) { if (cbarg != NULL) acache_cancelentry(rbtdb->common.mctx, entry, &cbarg); dns_acache_detachentry(&entry); } return (ISC_R_SUCCESS); } /*% * Routines for LRU-based cache management. */ /*% * See if a given cache entry that is being reused needs to be updated * in the LRU-list. From the LRU management point of view, this function is * expected to return true for almost all cases. When used with threads, * however, this may cause a non-negligible performance penalty because a * writer lock will have to be acquired before updating the list. * If DNS_RBTDB_LIMITLRUUPDATE is defined to be non 0 at compilation time, this * function returns true if the entry has not been updated for some period of * time. We differentiate the NS or glue address case and the others since * experiments have shown that the former tends to be accessed relatively * infrequently and the cost of cache miss is higher (e.g., a missing NS records * may cause external queries at a higher level zone, involving more * transactions). * * Caller must hold the node (read or write) lock. */ static inline isc_boolean_t need_headerupdate(rdatasetheader_t *header, isc_stdtime_t now) { if ((header->attributes & (RDATASET_ATTR_NONEXISTENT|RDATASET_ATTR_STALE)) != 0) return (ISC_FALSE); #if DNS_RBTDB_LIMITLRUUPDATE if (header->type == dns_rdatatype_ns || (header->trust == dns_trust_glue && (header->type == dns_rdatatype_a || header->type == dns_rdatatype_aaaa))) { /* * Glue records are updated if at least 60 seconds have passed * since the previous update time. */ return (header->last_used + 60 <= now); } /* Other records are updated if 5 minutes have passed. */ return (header->last_used + 300 <= now); #else UNUSED(now); return (ISC_TRUE); #endif } /*% * Update the timestamp of a given cache entry and move it to the head * of the corresponding LRU list. * * Caller must hold the node (write) lock. * * Note that the we do NOT touch the heap here, as the TTL has not changed. */ static void update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, isc_stdtime_t now) { INSIST(IS_CACHE(rbtdb)); /* To be checked: can we really assume this? XXXMLG */ INSIST(ISC_LINK_LINKED(header, link)); ISC_LIST_UNLINK(rbtdb->rdatasets[header->node->locknum], header, link); header->last_used = now; ISC_LIST_PREPEND(rbtdb->rdatasets[header->node->locknum], header, link); } /*% * Purge some expired and/or stale (i.e. unused for some period) cache entries * under an overmem condition. To recover from this condition quickly, up to * 2 entries will be purged. This process is triggered while adding a new * entry, and we specifically avoid purging entries in the same LRU bucket as * the one to which the new entry will belong. Otherwise, we might purge * entries of the same name of different RR types while adding RRsets from a * single response (consider the case where we're adding A and AAAA glue records * of the same NS name). */ static void overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start, isc_stdtime_t now, isc_boolean_t tree_locked) { rdatasetheader_t *header, *header_prev; unsigned int locknum; int purgecount = 2; for (locknum = (locknum_start + 1) % rbtdb->node_lock_count; locknum != locknum_start && purgecount > 0; locknum = (locknum + 1) % rbtdb->node_lock_count) { NODE_LOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write); header = isc_heap_element(rbtdb->heaps[locknum], 1); if (header && header->rdh_ttl < now - RBTDB_VIRTUAL) { expire_header(rbtdb, header, tree_locked, expire_ttl); purgecount--; } for (header = ISC_LIST_TAIL(rbtdb->rdatasets[locknum]); header != NULL && purgecount > 0; header = header_prev) { header_prev = ISC_LIST_PREV(header, link); /* * Unlink the entry at this point to avoid checking it * again even if it's currently used someone else and * cannot be purged at this moment. This entry won't be * referenced any more (so unlinking is safe) since the * TTL was reset to 0. */ ISC_LIST_UNLINK(rbtdb->rdatasets[locknum], header, link); expire_header(rbtdb, header, tree_locked, expire_lru); purgecount--; } NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write); } } static void expire_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, isc_boolean_t tree_locked, expire_t reason) { set_ttl(rbtdb, header, 0); mark_stale_header(rbtdb, header); /* * Caller must hold the node (write) lock. */ if (dns_rbtnode_refcurrent(header->node) == 0) { /* * If no one else is using the node, we can clean it up now. * We first need to gain a new reference to the node to meet a * requirement of decrement_reference(). */ new_reference(rbtdb, header->node); decrement_reference(rbtdb, header->node, 0, isc_rwlocktype_write, tree_locked ? isc_rwlocktype_write : isc_rwlocktype_none, ISC_FALSE); if (rbtdb->cachestats == NULL) return; switch (reason) { case expire_ttl: isc_stats_increment(rbtdb->cachestats, dns_cachestatscounter_deletettl); break; case expire_lru: isc_stats_increment(rbtdb->cachestats, dns_cachestatscounter_deletelru); break; default: break; } } } bind9-9.10.3.dfsg.P4/lib/dns/rcode.c0000644000470500017500000003430112664710322016164 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define RETERR(x) \ do { \ isc_result_t _r = (x); \ if (_r != ISC_R_SUCCESS) \ return (_r); \ } while (0) #define NUMBERSIZE sizeof("037777777777") /* 2^32-1 octal + NUL */ #define RCODENAMES \ /* standard rcodes */ \ { dns_rcode_noerror, "NOERROR", 0}, \ { dns_rcode_formerr, "FORMERR", 0}, \ { dns_rcode_servfail, "SERVFAIL", 0}, \ { dns_rcode_nxdomain, "NXDOMAIN", 0}, \ { dns_rcode_notimp, "NOTIMP", 0}, \ { dns_rcode_refused, "REFUSED", 0}, \ { dns_rcode_yxdomain, "YXDOMAIN", 0}, \ { dns_rcode_yxrrset, "YXRRSET", 0}, \ { dns_rcode_nxrrset, "NXRRSET", 0}, \ { dns_rcode_notauth, "NOTAUTH", 0}, \ { dns_rcode_notzone, "NOTZONE", 0}, #define ERCODENAMES \ /* extended rcodes */ \ { dns_rcode_badvers, "BADVERS", 0}, \ { dns_rcode_badcookie, "BADCOOKIE", 0}, \ { 0, NULL, 0 } #define TSIGRCODENAMES \ /* extended rcodes */ \ { dns_tsigerror_badsig, "BADSIG", 0}, \ { dns_tsigerror_badkey, "BADKEY", 0}, \ { dns_tsigerror_badtime, "BADTIME", 0}, \ { dns_tsigerror_badmode, "BADMODE", 0}, \ { dns_tsigerror_badname, "BADNAME", 0}, \ { dns_tsigerror_badalg, "BADALG", 0}, \ { dns_tsigerror_badtrunc, "BADTRUNC", 0}, \ { 0, NULL, 0 } /* RFC4398 section 2.1 */ #define CERTNAMES \ { 1, "PKIX", 0}, \ { 2, "SPKI", 0}, \ { 3, "PGP", 0}, \ { 4, "IPKIX", 0}, \ { 5, "ISPKI", 0}, \ { 6, "IPGP", 0}, \ { 7, "ACPKIX", 0}, \ { 8, "IACPKIX", 0}, \ { 253, "URI", 0}, \ { 254, "OID", 0}, \ { 0, NULL, 0} /* RFC2535 section 7, RFC3110 */ #define SECALGNAMES \ { DNS_KEYALG_RSAMD5, "RSAMD5", 0 }, \ { DNS_KEYALG_RSAMD5, "RSA", 0 }, \ { DNS_KEYALG_DH, "DH", 0 }, \ { DNS_KEYALG_DSA, "DSA", 0 }, \ { DNS_KEYALG_NSEC3DSA, "NSEC3DSA", 0 }, \ { DNS_KEYALG_ECC, "ECC", 0 }, \ { DNS_KEYALG_RSASHA1, "RSASHA1", 0 }, \ { DNS_KEYALG_NSEC3RSASHA1, "NSEC3RSASHA1", 0 }, \ { DNS_KEYALG_RSASHA256, "RSASHA256", 0 }, \ { DNS_KEYALG_RSASHA512, "RSASHA512", 0 }, \ { DNS_KEYALG_ECCGOST, "ECCGOST", 0 }, \ { DNS_KEYALG_ECDSA256, "ECDSAP256SHA256", 0 }, \ { DNS_KEYALG_ECDSA384, "ECDSAP384SHA384", 0 }, \ { DNS_KEYALG_INDIRECT, "INDIRECT", 0 }, \ { DNS_KEYALG_PRIVATEDNS, "PRIVATEDNS", 0 }, \ { DNS_KEYALG_PRIVATEOID, "PRIVATEOID", 0 }, \ { 0, NULL, 0} /* RFC2535 section 7.1 */ #define SECPROTONAMES \ { 0, "NONE", 0 }, \ { 1, "TLS", 0 }, \ { 2, "EMAIL", 0 }, \ { 3, "DNSSEC", 0 }, \ { 4, "IPSEC", 0 }, \ { 255, "ALL", 0 }, \ { 0, NULL, 0} #define HASHALGNAMES \ { 1, "SHA-1", 0 }, \ { 0, NULL, 0 } /* RFC3658, RFC4509, RFC5933, RFC6605 */ #define DSDIGESTNAMES \ { DNS_DSDIGEST_SHA1, "SHA-1", 0 }, \ { DNS_DSDIGEST_SHA256, "SHA-256", 0 }, \ { DNS_DSDIGEST_GOST, "GOST", 0 }, \ { DNS_DSDIGEST_SHA384, "SHA-384", 0 }, \ { 0, NULL, 0} struct tbl { unsigned int value; const char *name; int flags; }; static struct tbl rcodes[] = { RCODENAMES ERCODENAMES }; static struct tbl tsigrcodes[] = { RCODENAMES TSIGRCODENAMES }; static struct tbl certs[] = { CERTNAMES }; static struct tbl secalgs[] = { SECALGNAMES }; static struct tbl secprotos[] = { SECPROTONAMES }; static struct tbl hashalgs[] = { HASHALGNAMES }; static struct tbl dsdigests[] = { DSDIGESTNAMES }; static struct keyflag { const char *name; unsigned int value; unsigned int mask; } keyflags[] = { { "NOCONF", 0x4000, 0xC000 }, { "NOAUTH", 0x8000, 0xC000 }, { "NOKEY", 0xC000, 0xC000 }, { "FLAG2", 0x2000, 0x2000 }, { "EXTEND", 0x1000, 0x1000 }, { "FLAG4", 0x0800, 0x0800 }, { "FLAG5", 0x0400, 0x0400 }, { "USER", 0x0000, 0x0300 }, { "ZONE", 0x0100, 0x0300 }, { "HOST", 0x0200, 0x0300 }, { "NTYP3", 0x0300, 0x0300 }, { "FLAG8", 0x0080, 0x0080 }, { "FLAG9", 0x0040, 0x0040 }, { "FLAG10", 0x0020, 0x0020 }, { "FLAG11", 0x0010, 0x0010 }, { "SIG0", 0x0000, 0x000F }, { "SIG1", 0x0001, 0x000F }, { "SIG2", 0x0002, 0x000F }, { "SIG3", 0x0003, 0x000F }, { "SIG4", 0x0004, 0x000F }, { "SIG5", 0x0005, 0x000F }, { "SIG6", 0x0006, 0x000F }, { "SIG7", 0x0007, 0x000F }, { "SIG8", 0x0008, 0x000F }, { "SIG9", 0x0009, 0x000F }, { "SIG10", 0x000A, 0x000F }, { "SIG11", 0x000B, 0x000F }, { "SIG12", 0x000C, 0x000F }, { "SIG13", 0x000D, 0x000F }, { "SIG14", 0x000E, 0x000F }, { "SIG15", 0x000F, 0x000F }, { "KSK", DNS_KEYFLAG_KSK, DNS_KEYFLAG_KSK }, { NULL, 0, 0 } }; static isc_result_t str_totext(const char *source, isc_buffer_t *target) { unsigned int l; isc_region_t region; isc_buffer_availableregion(target, ®ion); l = strlen(source); if (l > region.length) return (ISC_R_NOSPACE); memmove(region.base, source, l); isc_buffer_add(target, l); return (ISC_R_SUCCESS); } static isc_result_t maybe_numeric(unsigned int *valuep, isc_textregion_t *source, unsigned int max, isc_boolean_t hex_allowed) { isc_result_t result; isc_uint32_t n; char buffer[NUMBERSIZE]; if (! isdigit(source->base[0] & 0xff) || source->length > NUMBERSIZE - 1) return (ISC_R_BADNUMBER); /* * We have a potential number. Try to parse it with * isc_parse_uint32(). isc_parse_uint32() requires * null termination, so we must make a copy. */ strncpy(buffer, source->base, sizeof(buffer)); buffer[sizeof(buffer) - 1] = '\0'; INSIST(buffer[source->length] == '\0'); result = isc_parse_uint32(&n, buffer, 10); if (result == ISC_R_BADNUMBER && hex_allowed) result = isc_parse_uint32(&n, buffer, 16); if (result != ISC_R_SUCCESS) return (result); if (n > max) return (ISC_R_RANGE); *valuep = n; return (ISC_R_SUCCESS); } static isc_result_t dns_mnemonic_fromtext(unsigned int *valuep, isc_textregion_t *source, struct tbl *table, unsigned int max) { isc_result_t result; int i; result = maybe_numeric(valuep, source, max, ISC_FALSE); if (result != ISC_R_BADNUMBER) return (result); for (i = 0; table[i].name != NULL; i++) { unsigned int n; n = strlen(table[i].name); if (n == source->length && strncasecmp(source->base, table[i].name, n) == 0) { *valuep = table[i].value; return (ISC_R_SUCCESS); } } return (DNS_R_UNKNOWN); } static isc_result_t dns_mnemonic_totext(unsigned int value, isc_buffer_t *target, struct tbl *table) { int i = 0; char buf[sizeof("4294967296")]; while (table[i].name != NULL) { if (table[i].value == value) { return (str_totext(table[i].name, target)); } i++; } snprintf(buf, sizeof(buf), "%u", value); return (str_totext(buf, target)); } isc_result_t dns_rcode_fromtext(dns_rcode_t *rcodep, isc_textregion_t *source) { unsigned int value; RETERR(dns_mnemonic_fromtext(&value, source, rcodes, 0xffff)); *rcodep = value; return (ISC_R_SUCCESS); } isc_result_t dns_rcode_totext(dns_rcode_t rcode, isc_buffer_t *target) { return (dns_mnemonic_totext(rcode, target, rcodes)); } isc_result_t dns_tsigrcode_fromtext(dns_rcode_t *rcodep, isc_textregion_t *source) { unsigned int value; RETERR(dns_mnemonic_fromtext(&value, source, tsigrcodes, 0xffff)); *rcodep = value; return (ISC_R_SUCCESS); } isc_result_t dns_tsigrcode_totext(dns_rcode_t rcode, isc_buffer_t *target) { return (dns_mnemonic_totext(rcode, target, tsigrcodes)); } isc_result_t dns_cert_fromtext(dns_cert_t *certp, isc_textregion_t *source) { unsigned int value; RETERR(dns_mnemonic_fromtext(&value, source, certs, 0xffff)); *certp = value; return (ISC_R_SUCCESS); } isc_result_t dns_cert_totext(dns_cert_t cert, isc_buffer_t *target) { return (dns_mnemonic_totext(cert, target, certs)); } isc_result_t dns_secalg_fromtext(dns_secalg_t *secalgp, isc_textregion_t *source) { unsigned int value; RETERR(dns_mnemonic_fromtext(&value, source, secalgs, 0xff)); *secalgp = value; return (ISC_R_SUCCESS); } isc_result_t dns_secalg_totext(dns_secalg_t secalg, isc_buffer_t *target) { return (dns_mnemonic_totext(secalg, target, secalgs)); } void dns_secalg_format(dns_secalg_t alg, char *cp, unsigned int size) { isc_buffer_t b; isc_region_t r; isc_result_t result; REQUIRE(cp != NULL && size > 0); isc_buffer_init(&b, cp, size - 1); result = dns_secalg_totext(alg, &b); isc_buffer_usedregion(&b, &r); r.base[r.length] = 0; if (result != ISC_R_SUCCESS) r.base[0] = 0; } isc_result_t dns_secproto_fromtext(dns_secproto_t *secprotop, isc_textregion_t *source) { unsigned int value; RETERR(dns_mnemonic_fromtext(&value, source, secprotos, 0xff)); *secprotop = value; return (ISC_R_SUCCESS); } isc_result_t dns_secproto_totext(dns_secproto_t secproto, isc_buffer_t *target) { return (dns_mnemonic_totext(secproto, target, secprotos)); } isc_result_t dns_hashalg_fromtext(unsigned char *hashalg, isc_textregion_t *source) { unsigned int value; RETERR(dns_mnemonic_fromtext(&value, source, hashalgs, 0xff)); *hashalg = value; return (ISC_R_SUCCESS); } isc_result_t dns_keyflags_fromtext(dns_keyflags_t *flagsp, isc_textregion_t *source) { isc_result_t result; char *text, *end; unsigned int value, mask; result = maybe_numeric(&value, source, 0xffff, ISC_TRUE); if (result == ISC_R_SUCCESS) { *flagsp = value; return (ISC_R_SUCCESS); } if (result != ISC_R_BADNUMBER) return (result); text = source->base; end = source->base + source->length; value = mask = 0; while (text < end) { struct keyflag *p; unsigned int len; char *delim = memchr(text, '|', end - text); if (delim != NULL) len = (unsigned int)(delim - text); else len = (unsigned int)(end - text); for (p = keyflags; p->name != NULL; p++) { if (strncasecmp(p->name, text, len) == 0) break; } if (p->name == NULL) return (DNS_R_UNKNOWNFLAG); value |= p->value; #ifdef notyet if ((mask & p->mask) != 0) warn("overlapping key flags"); #endif mask |= p->mask; text += len; if (delim != NULL) text++; /* Skip "|" */ } *flagsp = value; return (ISC_R_SUCCESS); } isc_result_t dns_dsdigest_fromtext(dns_dsdigest_t *dsdigestp, isc_textregion_t *source) { unsigned int value; RETERR(dns_mnemonic_fromtext(&value, source, dsdigests, 0xff)); *dsdigestp = value; return (ISC_R_SUCCESS); } isc_result_t dns_dsdigest_totext(dns_dsdigest_t dsdigest, isc_buffer_t *target) { return (dns_mnemonic_totext(dsdigest, target, dsdigests)); } void dns_dsdigest_format(dns_dsdigest_t typ, char *cp, unsigned int size) { isc_buffer_t b; isc_region_t r; isc_result_t result; REQUIRE(cp != NULL && size > 0); isc_buffer_init(&b, cp, size - 1); result = dns_dsdigest_totext(typ, &b); isc_buffer_usedregion(&b, &r); r.base[r.length] = 0; if (result != ISC_R_SUCCESS) r.base[0] = 0; } /* * This uses lots of hard coded values, but how often do we actually * add classes? */ isc_result_t dns_rdataclass_fromtext(dns_rdataclass_t *classp, isc_textregion_t *source) { #define COMPARE(string, rdclass) \ if (((sizeof(string) - 1) == source->length) \ && (strncasecmp(source->base, string, source->length) == 0)) { \ *classp = rdclass; \ return (ISC_R_SUCCESS); \ } switch (tolower((unsigned char)source->base[0])) { case 'a': COMPARE("any", dns_rdataclass_any); break; case 'c': /* * RFC1035 says the mnemonic for the CHAOS class is CH, * but historical BIND practice is to call it CHAOS. * We will accept both forms, but only generate CH. */ COMPARE("ch", dns_rdataclass_chaos); COMPARE("chaos", dns_rdataclass_chaos); if (source->length > 5 && source->length < (5 + sizeof("65000")) && strncasecmp("class", source->base, 5) == 0) { char buf[sizeof("65000")]; char *endp; unsigned int val; strncpy(buf, source->base + 5, source->length - 5); buf[source->length - 5] = '\0'; val = strtoul(buf, &endp, 10); if (*endp == '\0' && val <= 0xffff) { *classp = (dns_rdataclass_t)val; return (ISC_R_SUCCESS); } } break; case 'h': COMPARE("hs", dns_rdataclass_hs); COMPARE("hesiod", dns_rdataclass_hs); break; case 'i': COMPARE("in", dns_rdataclass_in); break; case 'n': COMPARE("none", dns_rdataclass_none); break; case 'r': COMPARE("reserved0", dns_rdataclass_reserved0); break; } #undef COMPARE return (DNS_R_UNKNOWN); } isc_result_t dns_rdataclass_totext(dns_rdataclass_t rdclass, isc_buffer_t *target) { char buf[sizeof("CLASS65535")]; switch (rdclass) { case dns_rdataclass_any: return (str_totext("ANY", target)); case dns_rdataclass_chaos: return (str_totext("CH", target)); case dns_rdataclass_hs: return (str_totext("HS", target)); case dns_rdataclass_in: return (str_totext("IN", target)); case dns_rdataclass_none: return (str_totext("NONE", target)); case dns_rdataclass_reserved0: return (str_totext("RESERVED0", target)); default: snprintf(buf, sizeof(buf), "CLASS%u", rdclass); return (str_totext(buf, target)); } } void dns_rdataclass_format(dns_rdataclass_t rdclass, char *array, unsigned int size) { isc_result_t result; isc_buffer_t buf; if (size == 0U) return; isc_buffer_init(&buf, array, size); result = dns_rdataclass_totext(rdclass, &buf); /* * Null terminate. */ if (result == ISC_R_SUCCESS) { if (isc_buffer_availablelength(&buf) >= 1) isc_buffer_putuint8(&buf, 0); else result = ISC_R_NOSPACE; } if (result != ISC_R_SUCCESS) strlcpy(array, "", size); } bind9-9.10.3.dfsg.P4/lib/dns/spnego_asn1.pl0000644000470500017500000001436212664710322017503 0ustar lamontlamont#!/bin/bin/perl -w # # Copyright (C) 2006, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: spnego_asn1.pl,v 1.4 2007/06/19 23:47:16 tbox Exp $ # Our SPNEGO implementation uses some functions generated by the # Heimdal ASN.1 compiler, which this script then whacks a bit to make # them work properly in this stripped down implementation. We don't # want to require our users to have a copy of the compiler, so we ship # the output of this script, but we need to keep the script around in # any case to cope with future changes to the SPNEGO ASN.1 code, so we # might as well supply the script for users who want it. # Overall plan: run the ASN.1 compiler, run each of its output files # through indent, fix up symbols and whack everything to be static. # We use indent for two reasons: (1) to whack the Heimdal compiler's # output into something closer to ISC's coding standard, and (2) to # make it easier for this script to parse the result. # Output from this script is C code which we expect to be #included # into another C file, which is why everything generated by this # script is marked "static". The intent is to minimize the number of # extern symbols exported by the SPNEGO implementation, to avoid # potential conflicts with the GSSAPI libraries. ### # Filename of the ASN.1 specification. Hardcoded for the moment # since this script is intended for compiling exactly one module. my $asn1_source = $ENV{ASN1_SOURCE} || "spnego.asn1"; # Heimdal ASN.1 compiler. This script was written using the version # from Heimdal 0.7.1. To build this, download a copy of # heimdal-0.7.1.tar.gz, configure and build with the default options, # then look for the compiler in heimdal-0.7.1/lib/asn1/asn1_compile. my $asn1_compile = $ENV{ASN1_COMPILE} || "asn1_compile"; # BSD indent program. This script was written using the version of # indent that comes with FreeBSD 4.11-STABLE. The GNU project, as # usual, couldn't resist the temptation to monkey with indent's # command line syntax, so this probably won't work with GNU indent. my $indent = $ENV{INDENT} || "indent"; ### # Step 1: run the compiler. Input is the ASN.1 file. Outputs are a # header file (name specified on command line without the .h suffix), # a file called "asn1_files" listing the names of the other output # files, and a set of files containing C code generated by the # compiler for each data type that the compiler found. if (! -r $asn1_source || system($asn1_compile, $asn1_source, "asn1")) { die("Couldn't compile ASN.1 source file $asn1_source\n"); } my @files = ("asn1.h"); open(F, "asn1_files") or die("Couldn't open asn1_files: $!\n"); push(@files, split) while (); close(F); unlink("asn1_files"); ### # Step 2: generate header block. print(q~/* * Copyright (C) 2006 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: spnego_asn1.pl,v 1.4 2007/06/19 23:47:16 tbox Exp $ */ /*! \file * \brief Method routines generated from SPNEGO ASN.1 module. * See spnego_asn1.pl for details. Do not edit. */ ~); ### # Step 3: read and process each generated file, then delete it. my $output; for my $file (@files) { my $is_static = 0; system($indent, "-di1", "-ldi1", $file) == 0 or die("Couldn't indent $file"); unlink("$file.BAK"); open(F, $file) or die("Couldn't open $file: $!"); while () { # Symbol name fixups s/heim_general_string/general_string/g; s/heim_octet_string/octet_string/g; s/heim_oid/oid/g; s/heim_utf8_string/utf8_string/g; # Convert all externs to statics if (/^static/) { $is_static = 1; } if (!/^typedef/ && !$is_static && /^[A-Za-z_][0-9A-Za-z_]*[ \t]*($|[^:0-9A-Za-z_])/) { $_ = "static " . $_; $is_static = 1; } if (/[{};]/) { $is_static = 0; } # Suppress file inclusion, pass anything else through if (!/#include/) { $output .= $_; } } close(F); unlink($file); } # Step 4: Delete unused stuff to avoid code bloat and compiler warnings. my @unused_functions = qw(ContextFlags2int int2ContextFlags asn1_ContextFlags_units length_NegTokenInit copy_NegTokenInit length_NegTokenResp copy_NegTokenResp length_MechTypeList length_MechType copy_MechTypeList length_ContextFlags copy_ContextFlags copy_MechType); $output =~ s<^static [^\n]+\n$_\(.+?^}>ms foreach (@unused_functions); $output =~ s<^static .+$_\(.*\);$>m foreach (@unused_functions); $output =~ s<^static struct units ContextFlags_units\[\].+?^};> ms; $output =~ s<^static int asn1_NegotiationToken_dummy_holder = 1;> ms; $output =~ s<^static void\nfree_ContextFlags\(ContextFlags \* data\)\n{\n> <$&\t(void)data;\n>ms; # Step 5: Write the result. print($output); bind9-9.10.3.dfsg.P4/lib/dns/forward.c0000644000470500017500000001537212664710322016543 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: forward.c,v 1.14 2009/09/02 23:48:02 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include struct dns_fwdtable { /* Unlocked. */ unsigned int magic; isc_mem_t *mctx; isc_rwlock_t rwlock; /* Locked by lock. */ dns_rbt_t *table; }; #define FWDTABLEMAGIC ISC_MAGIC('F', 'w', 'd', 'T') #define VALID_FWDTABLE(ft) ISC_MAGIC_VALID(ft, FWDTABLEMAGIC) static void auto_detach(void *, void *); isc_result_t dns_fwdtable_create(isc_mem_t *mctx, dns_fwdtable_t **fwdtablep) { dns_fwdtable_t *fwdtable; isc_result_t result; REQUIRE(fwdtablep != NULL && *fwdtablep == NULL); fwdtable = isc_mem_get(mctx, sizeof(dns_fwdtable_t)); if (fwdtable == NULL) return (ISC_R_NOMEMORY); fwdtable->table = NULL; result = dns_rbt_create(mctx, auto_detach, fwdtable, &fwdtable->table); if (result != ISC_R_SUCCESS) goto cleanup_fwdtable; result = isc_rwlock_init(&fwdtable->rwlock, 0, 0); if (result != ISC_R_SUCCESS) goto cleanup_rbt; fwdtable->mctx = NULL; isc_mem_attach(mctx, &fwdtable->mctx); fwdtable->magic = FWDTABLEMAGIC; *fwdtablep = fwdtable; return (ISC_R_SUCCESS); cleanup_rbt: dns_rbt_destroy(&fwdtable->table); cleanup_fwdtable: isc_mem_put(mctx, fwdtable, sizeof(dns_fwdtable_t)); return (result); } isc_result_t dns_fwdtable_addfwd(dns_fwdtable_t *fwdtable, dns_name_t *name, dns_forwarderlist_t *fwdrs, dns_fwdpolicy_t fwdpolicy) { isc_result_t result; dns_forwarders_t *forwarders; dns_forwarder_t *fwd, *nfwd; REQUIRE(VALID_FWDTABLE(fwdtable)); forwarders = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarders_t)); if (forwarders == NULL) return (ISC_R_NOMEMORY); ISC_LIST_INIT(forwarders->fwdrs); for (fwd = ISC_LIST_HEAD(*fwdrs); fwd != NULL; fwd = ISC_LIST_NEXT(fwd, link)) { nfwd = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarder_t)); if (nfwd == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } *nfwd = *fwd; ISC_LINK_INIT(nfwd, link); ISC_LIST_APPEND(forwarders->fwdrs, nfwd, link); } forwarders->fwdpolicy = fwdpolicy; RWLOCK(&fwdtable->rwlock, isc_rwlocktype_write); result = dns_rbt_addname(fwdtable->table, name, forwarders); RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_write); if (result != ISC_R_SUCCESS) goto cleanup; return (ISC_R_SUCCESS); cleanup: while (!ISC_LIST_EMPTY(forwarders->fwdrs)) { fwd = ISC_LIST_HEAD(forwarders->fwdrs); ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link); isc_mem_put(fwdtable->mctx, fwd, sizeof(isc_sockaddr_t)); } isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t)); return (result); } isc_result_t dns_fwdtable_add(dns_fwdtable_t *fwdtable, dns_name_t *name, isc_sockaddrlist_t *addrs, dns_fwdpolicy_t fwdpolicy) { isc_result_t result; dns_forwarders_t *forwarders; dns_forwarder_t *fwd; isc_sockaddr_t *sa; REQUIRE(VALID_FWDTABLE(fwdtable)); forwarders = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarders_t)); if (forwarders == NULL) return (ISC_R_NOMEMORY); ISC_LIST_INIT(forwarders->fwdrs); for (sa = ISC_LIST_HEAD(*addrs); sa != NULL; sa = ISC_LIST_NEXT(sa, link)) { fwd = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarder_t)); if (fwd == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } fwd->addr = *sa; fwd->dscp = -1; ISC_LINK_INIT(fwd, link); ISC_LIST_APPEND(forwarders->fwdrs, fwd, link); } forwarders->fwdpolicy = fwdpolicy; RWLOCK(&fwdtable->rwlock, isc_rwlocktype_write); result = dns_rbt_addname(fwdtable->table, name, forwarders); RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_write); if (result != ISC_R_SUCCESS) goto cleanup; return (ISC_R_SUCCESS); cleanup: while (!ISC_LIST_EMPTY(forwarders->fwdrs)) { fwd = ISC_LIST_HEAD(forwarders->fwdrs); ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link); isc_mem_put(fwdtable->mctx, fwd, sizeof(dns_forwarder_t)); } isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t)); return (result); } isc_result_t dns_fwdtable_delete(dns_fwdtable_t *fwdtable, dns_name_t *name) { isc_result_t result; REQUIRE(VALID_FWDTABLE(fwdtable)); RWLOCK(&fwdtable->rwlock, isc_rwlocktype_write); result = dns_rbt_deletename(fwdtable->table, name, ISC_FALSE); RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_write); if (result == DNS_R_PARTIALMATCH) result = ISC_R_NOTFOUND; return (result); } isc_result_t dns_fwdtable_find(dns_fwdtable_t *fwdtable, dns_name_t *name, dns_forwarders_t **forwardersp) { return (dns_fwdtable_find2(fwdtable, name, NULL, forwardersp)); } isc_result_t dns_fwdtable_find2(dns_fwdtable_t *fwdtable, dns_name_t *name, dns_name_t *foundname, dns_forwarders_t **forwardersp) { isc_result_t result; REQUIRE(VALID_FWDTABLE(fwdtable)); RWLOCK(&fwdtable->rwlock, isc_rwlocktype_read); result = dns_rbt_findname(fwdtable->table, name, 0, foundname, (void **)forwardersp); if (result == DNS_R_PARTIALMATCH) result = ISC_R_SUCCESS; RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_read); return (result); } void dns_fwdtable_destroy(dns_fwdtable_t **fwdtablep) { dns_fwdtable_t *fwdtable; isc_mem_t *mctx; REQUIRE(fwdtablep != NULL && VALID_FWDTABLE(*fwdtablep)); fwdtable = *fwdtablep; dns_rbt_destroy(&fwdtable->table); isc_rwlock_destroy(&fwdtable->rwlock); fwdtable->magic = 0; mctx = fwdtable->mctx; isc_mem_put(mctx, fwdtable, sizeof(dns_fwdtable_t)); isc_mem_detach(&mctx); *fwdtablep = NULL; } /*** *** Private ***/ static void auto_detach(void *data, void *arg) { dns_forwarders_t *forwarders = data; dns_fwdtable_t *fwdtable = arg; dns_forwarder_t *fwd; UNUSED(arg); while (!ISC_LIST_EMPTY(forwarders->fwdrs)) { fwd = ISC_LIST_HEAD(forwarders->fwdrs); ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link); isc_mem_put(fwdtable->mctx, fwd, sizeof(dns_forwarder_t)); } isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t)); } bind9-9.10.3.dfsg.P4/lib/dns/gssapictx.c0000644000470500017500000005370712664710322017110 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: gssapictx.c,v 1.29 2011/08/29 06:33:25 marka Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dst_internal.h" /* * If we're using our own SPNEGO implementation (see configure.in), * pull it in now. Otherwise, we just use whatever GSSAPI supplies. */ #if defined(GSSAPI) && defined(USE_ISC_SPNEGO) #include "spnego.h" #define gss_accept_sec_context gss_accept_sec_context_spnego #define gss_init_sec_context gss_init_sec_context_spnego #endif /* * Solaris8 apparently needs an explicit OID set, and Solaris10 needs * one for anything but Kerberos. Supplying an explicit OID set * doesn't appear to hurt anything in other implementations, so we * always use one. If we're not using our own SPNEGO implementation, * we include SPNEGO's OID. */ #ifdef GSSAPI #ifdef WIN32 #include #else #include ISC_PLATFORM_KRB5HEADER #endif static unsigned char krb5_mech_oid_bytes[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02 }; #ifndef USE_ISC_SPNEGO static unsigned char spnego_mech_oid_bytes[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x02 }; #endif static gss_OID_desc mech_oid_set_array[] = { { sizeof(krb5_mech_oid_bytes), krb5_mech_oid_bytes }, #ifndef USE_ISC_SPNEGO { sizeof(spnego_mech_oid_bytes), spnego_mech_oid_bytes }, #endif }; static gss_OID_set_desc mech_oid_set = { sizeof(mech_oid_set_array) / sizeof(*mech_oid_set_array), mech_oid_set_array }; #endif #define REGION_TO_GBUFFER(r, gb) \ do { \ (gb).length = (r).length; \ (gb).value = (r).base; \ } while (0) #define GBUFFER_TO_REGION(gb, r) \ do { \ (r).length = (unsigned int)(gb).length; \ (r).base = (gb).value; \ } while (0) #define RETERR(x) do { \ result = (x); \ if (result != ISC_R_SUCCESS) \ goto out; \ } while (0) #ifdef GSSAPI static inline void name_to_gbuffer(dns_name_t *name, isc_buffer_t *buffer, gss_buffer_desc *gbuffer) { dns_name_t tname, *namep; isc_region_t r; isc_result_t result; if (!dns_name_isabsolute(name)) namep = name; else { unsigned int labels; dns_name_init(&tname, NULL); labels = dns_name_countlabels(name); dns_name_getlabelsequence(name, 0, labels - 1, &tname); namep = &tname; } result = dns_name_toprincipal(namep, buffer); RUNTIME_CHECK(result == ISC_R_SUCCESS); isc_buffer_putuint8(buffer, 0); isc_buffer_usedregion(buffer, &r); REGION_TO_GBUFFER(r, *gbuffer); } static void log_cred(const gss_cred_id_t cred) { OM_uint32 gret, minor, lifetime; gss_name_t gname; gss_buffer_desc gbuffer; gss_cred_usage_t usage; const char *usage_text; char buf[1024]; gret = gss_inquire_cred(&minor, cred, &gname, &lifetime, &usage, NULL); if (gret != GSS_S_COMPLETE) { gss_log(3, "failed gss_inquire_cred: %s", gss_error_tostring(gret, minor, buf, sizeof(buf))); return; } gret = gss_display_name(&minor, gname, &gbuffer, NULL); if (gret != GSS_S_COMPLETE) gss_log(3, "failed gss_display_name: %s", gss_error_tostring(gret, minor, buf, sizeof(buf))); else { switch (usage) { case GSS_C_BOTH: usage_text = "GSS_C_BOTH"; break; case GSS_C_INITIATE: usage_text = "GSS_C_INITIATE"; break; case GSS_C_ACCEPT: usage_text = "GSS_C_ACCEPT"; break; default: usage_text = "???"; } gss_log(3, "gss cred: \"%s\", %s, %lu", (char *)gbuffer.value, usage_text, (unsigned long)lifetime); } if (gret == GSS_S_COMPLETE) { if (gbuffer.length != 0U) { gret = gss_release_buffer(&minor, &gbuffer); if (gret != GSS_S_COMPLETE) gss_log(3, "failed gss_release_buffer: %s", gss_error_tostring(gret, minor, buf, sizeof(buf))); } } gret = gss_release_name(&minor, &gname); if (gret != GSS_S_COMPLETE) gss_log(3, "failed gss_release_name: %s", gss_error_tostring(gret, minor, buf, sizeof(buf))); } #endif #ifdef GSSAPI /* * check for the most common configuration errors. * * The errors checked for are: * - tkey-gssapi-credential doesn't start with DNS/ * - the default realm in /etc/krb5.conf and the * tkey-gssapi-credential bind config option don't match * * Note that if tkey-gssapi-keytab is set then these configure checks * are not performed, and runtime errors from gssapi are used instead */ static void check_config(const char *gss_name) { const char *p; krb5_context krb5_ctx; char *krb5_realm_name = NULL; if (strncasecmp(gss_name, "DNS/", 4) != 0) { gss_log(ISC_LOG_ERROR, "tkey-gssapi-credential (%s) " "should start with 'DNS/'", gss_name); return; } if (krb5_init_context(&krb5_ctx) != 0) { gss_log(ISC_LOG_ERROR, "Unable to initialise krb5 context"); return; } if (krb5_get_default_realm(krb5_ctx, &krb5_realm_name) != 0) { gss_log(ISC_LOG_ERROR, "Unable to get krb5 default realm"); krb5_free_context(krb5_ctx); return; } p = strchr(gss_name, '@'); if (p == NULL) { gss_log(ISC_LOG_ERROR, "badly formatted " "tkey-gssapi-credentials (%s)", gss_name); krb5_free_context(krb5_ctx); return; } if (strcasecmp(p + 1, krb5_realm_name) != 0) { gss_log(ISC_LOG_ERROR, "default realm from krb5.conf (%s) " "does not match tkey-gssapi-credential (%s)", krb5_realm_name, gss_name); krb5_free_context(krb5_ctx); return; } krb5_free_context(krb5_ctx); } #endif isc_result_t dst_gssapi_acquirecred(dns_name_t *name, isc_boolean_t initiate, gss_cred_id_t *cred) { #ifdef GSSAPI isc_result_t result; isc_buffer_t namebuf; gss_name_t gname; gss_buffer_desc gnamebuf; unsigned char array[DNS_NAME_MAXTEXT + 1]; OM_uint32 gret, minor; OM_uint32 lifetime; gss_cred_usage_t usage; char buf[1024]; REQUIRE(cred != NULL && *cred == NULL); /* * XXXSRA In theory we could use GSS_C_NT_HOSTBASED_SERVICE * here when we're in the acceptor role, which would let us * default the hostname and use a compiled in default service * name of "DNS", giving one less thing to configure in * named.conf. Unfortunately, this creates a circular * dependency due to DNS-based realm lookup in at least one * GSSAPI implementation (Heimdal). Oh well. */ if (name != NULL) { isc_buffer_init(&namebuf, array, sizeof(array)); name_to_gbuffer(name, &namebuf, &gnamebuf); gret = gss_import_name(&minor, &gnamebuf, GSS_C_NO_OID, &gname); if (gret != GSS_S_COMPLETE) { check_config((char *)array); gss_log(3, "failed gss_import_name: %s", gss_error_tostring(gret, minor, buf, sizeof(buf))); return (ISC_R_FAILURE); } } else gname = NULL; /* Get the credentials. */ if (gname != NULL) gss_log(3, "acquiring credentials for %s", (char *)gnamebuf.value); else { /* XXXDCL does this even make any sense? */ gss_log(3, "acquiring credentials for ?"); } if (initiate) usage = GSS_C_INITIATE; else usage = GSS_C_ACCEPT; gret = gss_acquire_cred(&minor, gname, GSS_C_INDEFINITE, &mech_oid_set, usage, cred, NULL, &lifetime); if (gret != GSS_S_COMPLETE) { gss_log(3, "failed to acquire %s credentials for %s: %s", initiate ? "initiate" : "accept", (gname != NULL) ? (char *)gnamebuf.value : "?", gss_error_tostring(gret, minor, buf, sizeof(buf))); if (gname != NULL) check_config((char *)array); result = ISC_R_FAILURE; goto cleanup; } gss_log(4, "acquired %s credentials for %s", initiate ? "initiate" : "accept", (gname != NULL) ? (char *)gnamebuf.value : "?"); log_cred(*cred); result = ISC_R_SUCCESS; cleanup: if (gname != NULL) { gret = gss_release_name(&minor, &gname); if (gret != GSS_S_COMPLETE) gss_log(3, "failed gss_release_name: %s", gss_error_tostring(gret, minor, buf, sizeof(buf))); } return (result); #else REQUIRE(cred != NULL && *cred == NULL); UNUSED(name); UNUSED(initiate); UNUSED(cred); return (ISC_R_NOTIMPLEMENTED); #endif } isc_boolean_t dst_gssapi_identitymatchesrealmkrb5(dns_name_t *signer, dns_name_t *name, dns_name_t *realm) { #ifdef GSSAPI char sbuf[DNS_NAME_FORMATSIZE]; char nbuf[DNS_NAME_FORMATSIZE]; char rbuf[DNS_NAME_FORMATSIZE]; char *sname; char *rname; isc_buffer_t buffer; isc_result_t result; /* * It is far, far easier to write the names we are looking at into * a string, and do string operations on them. */ isc_buffer_init(&buffer, sbuf, sizeof(sbuf)); result = dns_name_toprincipal(signer, &buffer); RUNTIME_CHECK(result == ISC_R_SUCCESS); isc_buffer_putuint8(&buffer, 0); if (name != NULL) dns_name_format(name, nbuf, sizeof(nbuf)); dns_name_format(realm, rbuf, sizeof(rbuf)); /* * Find the realm portion. This is the part after the @. If it * does not exist, we don't have something we like, so we fail our * compare. */ rname = strchr(sbuf, '@'); if (rname == NULL) return (isc_boolean_false); *rname = '\0'; rname++; /* * Find the host portion of the signer's name. We do this by * searching for the first / character. We then check to make * certain the instance name is "host" * * This will work for * host/example.com@EXAMPLE.COM */ sname = strchr(sbuf, '/'); if (sname == NULL) return (isc_boolean_false); *sname = '\0'; sname++; if (strcmp(sbuf, "host") != 0) return (isc_boolean_false); /* * Now, we do a simple comparison between the name and the realm. */ if (name != NULL) { if ((strcasecmp(sname, nbuf) == 0) && (strcmp(rname, rbuf) == 0)) return (isc_boolean_true); } else { if (strcmp(rname, rbuf) == 0) return (isc_boolean_true); } return (isc_boolean_false); #else UNUSED(signer); UNUSED(name); UNUSED(realm); return (isc_boolean_false); #endif } isc_boolean_t dst_gssapi_identitymatchesrealmms(dns_name_t *signer, dns_name_t *name, dns_name_t *realm) { #ifdef GSSAPI char sbuf[DNS_NAME_FORMATSIZE]; char nbuf[DNS_NAME_FORMATSIZE]; char rbuf[DNS_NAME_FORMATSIZE]; char *sname; char *nname; char *rname; isc_buffer_t buffer; isc_result_t result; /* * It is far, far easier to write the names we are looking at into * a string, and do string operations on them. */ isc_buffer_init(&buffer, sbuf, sizeof(sbuf)); result = dns_name_toprincipal(signer, &buffer); RUNTIME_CHECK(result == ISC_R_SUCCESS); isc_buffer_putuint8(&buffer, 0); if (name != NULL) dns_name_format(name, nbuf, sizeof(nbuf)); dns_name_format(realm, rbuf, sizeof(rbuf)); /* * Find the realm portion. This is the part after the @. If it * does not exist, we don't have something we like, so we fail our * compare. */ rname = strchr(sbuf, '@'); if (rname == NULL) return (isc_boolean_false); sname = strchr(sbuf, '$'); if (sname == NULL) return (isc_boolean_false); /* * Verify that the $ and @ follow one another. */ if (rname - sname != 1) return (isc_boolean_false); /* * Find the host portion of the signer's name. Zero out the $ so * it terminates the signer's name, and skip past the @ for * the realm. * * All service principals in Microsoft format seem to be in * machinename$@EXAMPLE.COM * format. */ rname++; *sname = '\0'; sname = sbuf; /* * Find the first . in the target name, and make it the end of * the string. The rest of the name has to match the realm. */ if (name != NULL) { nname = strchr(nbuf, '.'); if (nname == NULL) return (isc_boolean_false); *nname++ = '\0'; } /* * Now, we do a simple comparison between the name and the realm. */ if (name != NULL) { if ((strcasecmp(sname, nbuf) == 0) && (strcmp(rname, rbuf) == 0) && (strcasecmp(nname, rbuf) == 0)) return (isc_boolean_true); } else { if (strcmp(rname, rbuf) == 0) return (isc_boolean_true); } return (isc_boolean_false); #else UNUSED(signer); UNUSED(name); UNUSED(realm); return (isc_boolean_false); #endif } isc_result_t dst_gssapi_releasecred(gss_cred_id_t *cred) { #ifdef GSSAPI OM_uint32 gret, minor; char buf[1024]; REQUIRE(cred != NULL && *cred != NULL); gret = gss_release_cred(&minor, cred); if (gret != GSS_S_COMPLETE) { /* Log the error, but still free the credential's memory */ gss_log(3, "failed releasing credential: %s", gss_error_tostring(gret, minor, buf, sizeof(buf))); } *cred = NULL; return(ISC_R_SUCCESS); #else UNUSED(cred); return (ISC_R_NOTIMPLEMENTED); #endif } #ifdef GSSAPI /* * Format a gssapi error message info into a char ** on the given memory * context. This is used to return gssapi error messages back up the * call chain for reporting to the user. */ static void gss_err_message(isc_mem_t *mctx, isc_uint32_t major, isc_uint32_t minor, char **err_message) { char buf[1024]; char *estr; if (err_message == NULL || mctx == NULL) { /* the caller doesn't want any error messages */ return; } estr = gss_error_tostring(major, minor, buf, sizeof(buf)); if (estr != NULL) (*err_message) = isc_mem_strdup(mctx, estr); } #endif isc_result_t dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken, isc_buffer_t *outtoken, gss_ctx_id_t *gssctx, isc_mem_t *mctx, char **err_message) { #ifdef GSSAPI isc_region_t r; isc_buffer_t namebuf; gss_name_t gname; OM_uint32 gret, minor, ret_flags, flags; gss_buffer_desc gintoken, *gintokenp, gouttoken = GSS_C_EMPTY_BUFFER; isc_result_t result; gss_buffer_desc gnamebuf; unsigned char array[DNS_NAME_MAXTEXT + 1]; /* Client must pass us a valid gss_ctx_id_t here */ REQUIRE(gssctx != NULL); REQUIRE(mctx != NULL); isc_buffer_init(&namebuf, array, sizeof(array)); name_to_gbuffer(name, &namebuf, &gnamebuf); /* Get the name as a GSS name */ gret = gss_import_name(&minor, &gnamebuf, GSS_C_NO_OID, &gname); if (gret != GSS_S_COMPLETE) { gss_err_message(mctx, gret, minor, err_message); result = ISC_R_FAILURE; goto out; } if (intoken != NULL) { /* Don't call gss_release_buffer for gintoken! */ REGION_TO_GBUFFER(*intoken, gintoken); gintokenp = &gintoken; } else { gintokenp = NULL; } /* * Note that we don't set GSS_C_SEQUENCE_FLAG as Windows DNS * servers don't like it. */ flags = GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG; gret = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, gssctx, gname, GSS_SPNEGO_MECHANISM, flags, 0, NULL, gintokenp, NULL, &gouttoken, &ret_flags, NULL); if (gret != GSS_S_COMPLETE && gret != GSS_S_CONTINUE_NEEDED) { gss_err_message(mctx, gret, minor, err_message); if (err_message != NULL && *err_message != NULL) gss_log(3, "Failure initiating security context: %s", *err_message); else gss_log(3, "Failure initiating security context"); result = ISC_R_FAILURE; goto out; } /* * XXXSRA Not handled yet: RFC 3645 3.1.1: check ret_flags * MUTUAL and INTEG flags, fail if either not set. */ /* * RFC 2744 states the a valid output token has a non-zero length. */ if (gouttoken.length != 0U) { GBUFFER_TO_REGION(gouttoken, r); RETERR(isc_buffer_copyregion(outtoken, &r)); } if (gret == GSS_S_COMPLETE) result = ISC_R_SUCCESS; else result = DNS_R_CONTINUE; out: if (gouttoken.length != 0U) (void)gss_release_buffer(&minor, &gouttoken); (void)gss_release_name(&minor, &gname); return (result); #else UNUSED(name); UNUSED(intoken); UNUSED(outtoken); UNUSED(gssctx); UNUSED(mctx); UNUSED(err_message); return (ISC_R_NOTIMPLEMENTED); #endif } isc_result_t dst_gssapi_acceptctx(gss_cred_id_t cred, const char *gssapi_keytab, isc_region_t *intoken, isc_buffer_t **outtoken, gss_ctx_id_t *ctxout, dns_name_t *principal, isc_mem_t *mctx) { #ifdef GSSAPI isc_region_t r; isc_buffer_t namebuf; gss_buffer_desc gnamebuf = GSS_C_EMPTY_BUFFER, gintoken, gouttoken = GSS_C_EMPTY_BUFFER; OM_uint32 gret, minor; gss_ctx_id_t context = GSS_C_NO_CONTEXT; gss_name_t gname = NULL; isc_result_t result; char buf[1024]; REQUIRE(outtoken != NULL && *outtoken == NULL); REGION_TO_GBUFFER(*intoken, gintoken); if (*ctxout == NULL) context = GSS_C_NO_CONTEXT; else context = *ctxout; if (gssapi_keytab != NULL) { #if defined(ISC_PLATFORM_GSSAPI_KRB5_HEADER) || defined(WIN32) gret = gsskrb5_register_acceptor_identity(gssapi_keytab); if (gret != GSS_S_COMPLETE) { gss_log(3, "failed " "gsskrb5_register_acceptor_identity(%s): %s", gssapi_keytab, gss_error_tostring(gret, 0, buf, sizeof(buf))); return (DNS_R_INVALIDTKEY); } #else /* * Minimize memory leakage by only setting KRB5_KTNAME * if it needs to change. */ const char *old = getenv("KRB5_KTNAME"); if (old == NULL || strcmp(old, gssapi_keytab) != 0) { char *kt = malloc(strlen(gssapi_keytab) + 13); if (kt == NULL) return (ISC_R_NOMEMORY); sprintf(kt, "KRB5_KTNAME=%s", gssapi_keytab); if (putenv(kt) != 0) return (ISC_R_NOMEMORY); } #endif } log_cred(cred); gret = gss_accept_sec_context(&minor, &context, cred, &gintoken, GSS_C_NO_CHANNEL_BINDINGS, &gname, NULL, &gouttoken, NULL, NULL, NULL); result = ISC_R_FAILURE; switch (gret) { case GSS_S_COMPLETE: result = ISC_R_SUCCESS; break; case GSS_S_CONTINUE_NEEDED: result = DNS_R_CONTINUE; break; case GSS_S_DEFECTIVE_TOKEN: case GSS_S_DEFECTIVE_CREDENTIAL: case GSS_S_BAD_SIG: case GSS_S_DUPLICATE_TOKEN: case GSS_S_OLD_TOKEN: case GSS_S_NO_CRED: case GSS_S_CREDENTIALS_EXPIRED: case GSS_S_BAD_BINDINGS: case GSS_S_NO_CONTEXT: case GSS_S_BAD_MECH: case GSS_S_FAILURE: result = DNS_R_INVALIDTKEY; /* fall through */ default: gss_log(3, "failed gss_accept_sec_context: %s", gss_error_tostring(gret, minor, buf, sizeof(buf))); return (result); } if (gouttoken.length > 0U) { RETERR(isc_buffer_allocate(mctx, outtoken, (unsigned int)gouttoken.length)); GBUFFER_TO_REGION(gouttoken, r); RETERR(isc_buffer_copyregion(*outtoken, &r)); (void)gss_release_buffer(&minor, &gouttoken); } if (gret == GSS_S_COMPLETE) { gret = gss_display_name(&minor, gname, &gnamebuf, NULL); if (gret != GSS_S_COMPLETE) { gss_log(3, "failed gss_display_name: %s", gss_error_tostring(gret, minor, buf, sizeof(buf))); RETERR(ISC_R_FAILURE); } /* * Compensate for a bug in Solaris8's implementation * of gss_display_name(). Should be harmless in any * case, since principal names really should not * contain null characters. */ if (gnamebuf.length > 0U && ((char *)gnamebuf.value)[gnamebuf.length - 1] == '\0') gnamebuf.length--; gss_log(3, "gss-api source name (accept) is %.*s", (int)gnamebuf.length, (char *)gnamebuf.value); GBUFFER_TO_REGION(gnamebuf, r); isc_buffer_init(&namebuf, r.base, r.length); isc_buffer_add(&namebuf, r.length); RETERR(dns_name_fromtext(principal, &namebuf, dns_rootname, 0, NULL)); if (gnamebuf.length != 0U) { gret = gss_release_buffer(&minor, &gnamebuf); if (gret != GSS_S_COMPLETE) gss_log(3, "failed gss_release_buffer: %s", gss_error_tostring(gret, minor, buf, sizeof(buf))); } } *ctxout = context; out: if (gname != NULL) { gret = gss_release_name(&minor, &gname); if (gret != GSS_S_COMPLETE) gss_log(3, "failed gss_release_name: %s", gss_error_tostring(gret, minor, buf, sizeof(buf))); } return (result); #else UNUSED(cred); UNUSED(gssapi_keytab); UNUSED(intoken); UNUSED(outtoken); UNUSED(ctxout); UNUSED(principal); UNUSED(mctx); return (ISC_R_NOTIMPLEMENTED); #endif } isc_result_t dst_gssapi_deletectx(isc_mem_t *mctx, gss_ctx_id_t *gssctx) { #ifdef GSSAPI OM_uint32 gret, minor; char buf[1024]; UNUSED(mctx); REQUIRE(gssctx != NULL && *gssctx != NULL); /* Delete the context from the GSS provider */ gret = gss_delete_sec_context(&minor, gssctx, GSS_C_NO_BUFFER); if (gret != GSS_S_COMPLETE) { /* Log the error, but still free the context's memory */ gss_log(3, "Failure deleting security context %s", gss_error_tostring(gret, minor, buf, sizeof(buf))); } return(ISC_R_SUCCESS); #else UNUSED(mctx); UNUSED(gssctx); return (ISC_R_NOTIMPLEMENTED); #endif } char * gss_error_tostring(isc_uint32_t major, isc_uint32_t minor, char *buf, size_t buflen) { #ifdef GSSAPI gss_buffer_desc msg_minor = GSS_C_EMPTY_BUFFER, msg_major = GSS_C_EMPTY_BUFFER; OM_uint32 msg_ctx, minor_stat; /* Handle major status */ msg_ctx = 0; (void)gss_display_status(&minor_stat, major, GSS_C_GSS_CODE, GSS_C_NULL_OID, &msg_ctx, &msg_major); /* Handle minor status */ msg_ctx = 0; (void)gss_display_status(&minor_stat, minor, GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &msg_minor); snprintf(buf, buflen, "GSSAPI error: Major = %s, Minor = %s.", (char *)msg_major.value, (char *)msg_minor.value); if (msg_major.length != 0U) (void)gss_release_buffer(&minor_stat, &msg_major); if (msg_minor.length != 0U) (void)gss_release_buffer(&minor_stat, &msg_minor); return(buf); #else snprintf(buf, buflen, "GSSAPI error: Major = %u, Minor = %u.", major, minor); return (buf); #endif } void gss_log(int level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_TKEY, ISC_LOG_DEBUG(level), fmt, ap); va_end(ap); } /*! \file */ bind9-9.10.3.dfsg.P4/lib/dns/callbacks.c0000644000470500017500000000566412664710322017021 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2011, 2012, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: callbacks.c,v 1.19.40.1 2012/02/07 00:44:13 each Exp $ */ /*! \file */ #include #include #include #include #include static void stdio_error_warn_callback(dns_rdatacallbacks_t *, const char *, ...) ISC_FORMAT_PRINTF(2, 3); static void isclog_error_callback(dns_rdatacallbacks_t *callbacks, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3); static void isclog_warn_callback(dns_rdatacallbacks_t *callbacks, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3); /* * Private */ static void stdio_error_warn_callback(dns_rdatacallbacks_t *callbacks, const char *fmt, ...) { va_list ap; UNUSED(callbacks); va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); fprintf(stderr, "\n"); } static void isclog_error_callback(dns_rdatacallbacks_t *callbacks, const char *fmt, ...) { va_list ap; UNUSED(callbacks); va_start(ap, fmt); isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER, /* XXX */ ISC_LOG_ERROR, fmt, ap); va_end(ap); } static void isclog_warn_callback(dns_rdatacallbacks_t *callbacks, const char *fmt, ...) { va_list ap; UNUSED(callbacks); va_start(ap, fmt); isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER, /* XXX */ ISC_LOG_WARNING, fmt, ap); va_end(ap); } static void dns_rdatacallbacks_initcommon(dns_rdatacallbacks_t *callbacks) { REQUIRE(callbacks != NULL); callbacks->magic = DNS_CALLBACK_MAGIC; callbacks->add = NULL; callbacks->rawdata = NULL; callbacks->zone = NULL; callbacks->add_private = NULL; callbacks->error_private = NULL; callbacks->warn_private = NULL; } /* * Public. */ void dns_rdatacallbacks_init(dns_rdatacallbacks_t *callbacks) { dns_rdatacallbacks_initcommon(callbacks); callbacks->error = isclog_error_callback; callbacks->warn = isclog_warn_callback; } void dns_rdatacallbacks_init_stdio(dns_rdatacallbacks_t *callbacks) { dns_rdatacallbacks_initcommon(callbacks); callbacks->error = stdio_error_warn_callback; callbacks->warn = stdio_error_warn_callback; } bind9-9.10.3.dfsg.P4/lib/dns/pkcs11dh_link.c0000644000470500017500000007614012664710322017532 0ustar lamontlamont/* * Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef PKCS11CRYPTO #include #include #include #include #include #include #include "dst_internal.h" #include "dst_parse.h" #include "dst_pkcs11.h" #include #include #define WANT_DH_PRIMES #include #include /* * PKCS#3 DH keys: * mechanisms: * CKM_DH_PKCS_PARAMETER_GEN, * CKM_DH_PKCS_KEY_PAIR_GEN, * CKM_DH_PKCS_DERIVE * domain parameters: * object class CKO_DOMAIN_PARAMETERS * key type CKK_DH * attribute CKA_PRIME (prime p) * attribute CKA_BASE (base g) * optional attribute CKA_PRIME_BITS (p length in bits) * public key: * object class CKO_PUBLIC_KEY * key type CKK_DH * attribute CKA_PRIME (prime p) * attribute CKA_BASE (base g) * attribute CKA_VALUE (public value y) * private key: * object class CKO_PRIVATE_KEY * key type CKK_DH * attribute CKA_PRIME (prime p) * attribute CKA_BASE (base g) * attribute CKA_VALUE (private value x) * optional attribute CKA_VALUE_BITS (x length in bits) * reuse CKA_PRIVATE_EXPONENT for key pair private value */ #define CKA_VALUE2 CKA_PRIVATE_EXPONENT static CK_BBOOL truevalue = TRUE; static CK_BBOOL falsevalue = FALSE; #define DST_RET(a) {ret = a; goto err;} static void pkcs11dh_destroy(dst_key_t *key); static isc_result_t pkcs11dh_todns(const dst_key_t *key, isc_buffer_t *data); static isc_result_t pkcs11dh_loadpriv(const dst_key_t *key, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hKey) { CK_RV rv; CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; CK_KEY_TYPE keyType = CKK_DH; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_DERIVE, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_PRIME, NULL, 0 }, { CKA_BASE, NULL, 0 }, { CKA_VALUE, NULL, 0 } }; CK_ATTRIBUTE *attr; const pk11_object_t *priv; isc_result_t ret; unsigned int i; priv = key->keydata.pkey; if ((priv->object != CK_INVALID_HANDLE) && priv->ontoken) { *hKey = priv->object; return (ISC_R_SUCCESS); } attr = pk11_attribute_bytype(priv, CKA_PRIME); if (attr == NULL) return (DST_R_INVALIDPRIVATEKEY); keyTemplate[6].pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (keyTemplate[6].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[6].pValue, attr->pValue, attr->ulValueLen); keyTemplate[6].ulValueLen = attr->ulValueLen; attr = pk11_attribute_bytype(priv, CKA_BASE); if (attr == NULL) DST_RET(DST_R_INVALIDPRIVATEKEY); keyTemplate[7].pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (keyTemplate[7].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[7].pValue, attr->pValue, attr->ulValueLen); keyTemplate[7].ulValueLen = attr->ulValueLen; attr = pk11_attribute_bytype(priv, CKA_VALUE2); if (attr == NULL) DST_RET(DST_R_INVALIDPRIVATEKEY); keyTemplate[8].pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (keyTemplate[8].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[8].pValue, attr->pValue, attr->ulValueLen); keyTemplate[8].ulValueLen = attr->ulValueLen; PK11_CALL(pkcs_C_CreateObject, (session, keyTemplate, (CK_ULONG) 9, hKey), DST_R_COMPUTESECRETFAILURE); if (rv == CKR_OK) ret = ISC_R_SUCCESS; err: for (i = 6; i <= 8; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(key->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } return (ret); } static isc_result_t pkcs11dh_computesecret(const dst_key_t *pub, const dst_key_t *priv, isc_buffer_t *secret) { CK_RV rv; CK_MECHANISM mech = { CKM_DH_PKCS_DERIVE, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; CK_OBJECT_HANDLE hDerived = CK_INVALID_HANDLE; CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; CK_ATTRIBUTE *attr; CK_ULONG secLen; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_VALUE_LEN, &secLen, (CK_ULONG) sizeof(secLen) } }; CK_ATTRIBUTE valTemplate[] = { { CKA_VALUE, NULL, 0 } }; CK_BYTE *secValue; pk11_context_t ctx; isc_result_t ret; unsigned int i; isc_region_t r; REQUIRE(pub->keydata.pkey != NULL); REQUIRE(priv->keydata.pkey != NULL); REQUIRE(priv->keydata.pkey->repr != NULL); attr = pk11_attribute_bytype(pub->keydata.pkey, CKA_PRIME); if (attr == NULL) return (DST_R_INVALIDPUBLICKEY); REQUIRE(attr != NULL); secLen = attr->ulValueLen; attr = pk11_attribute_bytype(pub->keydata.pkey, CKA_VALUE); if (attr == NULL) return (DST_R_INVALIDPUBLICKEY); ret = pk11_get_session(&ctx, OP_DH, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_DH)); if (ret != ISC_R_SUCCESS) return (ret); mech.ulParameterLen = attr->ulValueLen; mech.pParameter = isc_mem_get(pub->mctx, mech.ulParameterLen); if (mech.pParameter == NULL) DST_RET(ISC_R_NOMEMORY); memmove(mech.pParameter, attr->pValue, mech.ulParameterLen); ret = pkcs11dh_loadpriv(priv, ctx.session, &hKey); if (ret != ISC_R_SUCCESS) goto err; PK11_RET(pkcs_C_DeriveKey, (ctx.session, &mech, hKey, keyTemplate, (CK_ULONG) 6, &hDerived), DST_R_COMPUTESECRETFAILURE); attr = valTemplate; PK11_RET(pkcs_C_GetAttributeValue, (ctx.session, hDerived, attr, (CK_ULONG) 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(pub->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (ctx.session, hDerived, attr, (CK_ULONG) 1), DST_R_CRYPTOFAILURE); /* strip leading zeros */ secValue = (CK_BYTE_PTR) attr->pValue; for (i = 0; i < attr->ulValueLen; i++) if (secValue[i] != 0) break; isc_buffer_availableregion(secret, &r); if (r.length < attr->ulValueLen - i) DST_RET(ISC_R_NOSPACE); memmove(r.base, secValue + i, attr->ulValueLen - i); isc_buffer_add(secret, attr->ulValueLen - i); ret = ISC_R_SUCCESS; err: if (hDerived != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx.session, hDerived); if (valTemplate[0].pValue != NULL) { memset(valTemplate[0].pValue, 0, valTemplate[0].ulValueLen); isc_mem_put(pub->mctx, valTemplate[0].pValue, valTemplate[0].ulValueLen); } if ((hKey != CK_INVALID_HANDLE) && !priv->keydata.pkey->ontoken) (void) pkcs_C_DestroyObject(ctx.session, hKey); if (mech.pParameter != NULL) { memset(mech.pParameter, 0, mech.ulParameterLen); isc_mem_put(pub->mctx, mech.pParameter, mech.ulParameterLen); } pk11_return_session(&ctx); return (ret); } static isc_boolean_t pkcs11dh_compare(const dst_key_t *key1, const dst_key_t *key2) { pk11_object_t *dh1, *dh2; CK_ATTRIBUTE *attr1, *attr2; dh1 = key1->keydata.pkey; dh2 = key2->keydata.pkey; if ((dh1 == NULL) && (dh2 == NULL)) return (ISC_TRUE); else if ((dh1 == NULL) || (dh2 == NULL)) return (ISC_FALSE); attr1 = pk11_attribute_bytype(dh1, CKA_PRIME); attr2 = pk11_attribute_bytype(dh2, CKA_PRIME); if ((attr1 == NULL) && (attr2 == NULL)) return (ISC_TRUE); else if ((attr1 == NULL) || (attr2 == NULL) || (attr1->ulValueLen != attr2->ulValueLen) || !isc_safe_memequal(attr1->pValue, attr2->pValue, attr1->ulValueLen)) return (ISC_FALSE); attr1 = pk11_attribute_bytype(dh1, CKA_BASE); attr2 = pk11_attribute_bytype(dh2, CKA_BASE); if ((attr1 == NULL) && (attr2 == NULL)) return (ISC_TRUE); else if ((attr1 == NULL) || (attr2 == NULL) || (attr1->ulValueLen != attr2->ulValueLen) || !isc_safe_memequal(attr1->pValue, attr2->pValue, attr1->ulValueLen)) return (ISC_FALSE); attr1 = pk11_attribute_bytype(dh1, CKA_VALUE); attr2 = pk11_attribute_bytype(dh2, CKA_VALUE); if ((attr1 == NULL) && (attr2 == NULL)) return (ISC_TRUE); else if ((attr1 == NULL) || (attr2 == NULL) || (attr1->ulValueLen != attr2->ulValueLen) || !isc_safe_memequal(attr1->pValue, attr2->pValue, attr1->ulValueLen)) return (ISC_FALSE); attr1 = pk11_attribute_bytype(dh1, CKA_VALUE2); attr2 = pk11_attribute_bytype(dh2, CKA_VALUE2); if (((attr1 != NULL) || (attr2 != NULL)) && ((attr1 == NULL) || (attr2 == NULL) || (attr1->ulValueLen != attr2->ulValueLen) || !isc_safe_memequal(attr1->pValue, attr2->pValue, attr1->ulValueLen))) return (ISC_FALSE); if (!dh1->ontoken && !dh2->ontoken) return (ISC_TRUE); else if (dh1->ontoken || dh2->ontoken || (dh1->object != dh2->object)) return (ISC_FALSE); return (ISC_TRUE); } static isc_boolean_t pkcs11dh_paramcompare(const dst_key_t *key1, const dst_key_t *key2) { pk11_object_t *dh1, *dh2; CK_ATTRIBUTE *attr1, *attr2; dh1 = key1->keydata.pkey; dh2 = key2->keydata.pkey; if ((dh1 == NULL) && (dh2 == NULL)) return (ISC_TRUE); else if ((dh1 == NULL) || (dh2 == NULL)) return (ISC_FALSE); attr1 = pk11_attribute_bytype(dh1, CKA_PRIME); attr2 = pk11_attribute_bytype(dh2, CKA_PRIME); if ((attr1 == NULL) && (attr2 == NULL)) return (ISC_TRUE); else if ((attr1 == NULL) || (attr2 == NULL) || (attr1->ulValueLen != attr2->ulValueLen) || !isc_safe_memequal(attr1->pValue, attr2->pValue, attr1->ulValueLen)) return (ISC_FALSE); attr1 = pk11_attribute_bytype(dh1, CKA_BASE); attr2 = pk11_attribute_bytype(dh2, CKA_BASE); if ((attr1 == NULL) && (attr2 == NULL)) return (ISC_TRUE); else if ((attr1 == NULL) || (attr2 == NULL) || (attr1->ulValueLen != attr2->ulValueLen) || !isc_safe_memequal(attr1->pValue, attr2->pValue, attr1->ulValueLen)) return (ISC_FALSE); return (ISC_TRUE); } static isc_result_t pkcs11dh_generate(dst_key_t *key, int generator, void (*callback)(int)) { CK_RV rv; CK_MECHANISM mech = { CKM_DH_PKCS_PARAMETER_GEN, NULL, 0 }; CK_OBJECT_HANDLE domainparams = CK_INVALID_HANDLE; CK_OBJECT_CLASS dClass = CKO_DOMAIN_PARAMETERS; CK_KEY_TYPE keyType = CKK_DH; CK_ULONG bits = 0; CK_ATTRIBUTE dTemplate[] = { { CKA_CLASS, &dClass, (CK_ULONG) sizeof(dClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIME_BITS, &bits, (CK_ULONG) sizeof(bits) } }; CK_ATTRIBUTE pTemplate[] = { { CKA_PRIME, NULL, 0 }, { CKA_BASE, NULL, 0 } }; CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; CK_ATTRIBUTE pubTemplate[] = { { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, { CKA_KEY_TYPE,&keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIME, NULL, 0 }, { CKA_BASE, NULL, 0 }, }; CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY; CK_ATTRIBUTE privTemplate[] = { { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_DERIVE, &truevalue, (CK_ULONG) sizeof(truevalue) }, }; CK_ATTRIBUTE *attr; pk11_object_t *dh = NULL; pk11_context_t *pk11_ctx; isc_result_t ret; UNUSED(callback); pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_DH, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_DH)); if (ret != ISC_R_SUCCESS) goto err; bits = key->key_size; if ((generator == 0) && ((bits == 768) || (bits == 1024) || (bits == 1536))) { if (bits == 768) { pubTemplate[4].pValue = isc_mem_get(key->mctx, sizeof(pk11_dh_bn768)); if (pubTemplate[4].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(pubTemplate[4].pValue, pk11_dh_bn768, sizeof(pk11_dh_bn768)); pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn768); } else if (bits == 1024) { pubTemplate[4].pValue = isc_mem_get(key->mctx, sizeof(pk11_dh_bn1024)); if (pubTemplate[4].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(pubTemplate[4].pValue, pk11_dh_bn1024, sizeof(pk11_dh_bn1024)); pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn1024); } else { pubTemplate[4].pValue = isc_mem_get(key->mctx, sizeof(pk11_dh_bn1536)); if (pubTemplate[4].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(pubTemplate[4].pValue, pk11_dh_bn1536, sizeof(pk11_dh_bn1536)); pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn1536); } pubTemplate[5].pValue = isc_mem_get(key->mctx, sizeof(pk11_dh_bn2)); if (pubTemplate[5].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(pubTemplate[5].pValue, pk11_dh_bn2, sizeof(pk11_dh_bn2)); pubTemplate[5].ulValueLen = sizeof(pk11_dh_bn2); } else { PK11_RET(pkcs_C_GenerateKey, (pk11_ctx->session, &mech, dTemplate, (CK_ULONG) 5, &domainparams), DST_R_CRYPTOFAILURE); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, domainparams, pTemplate, (CK_ULONG) 2), DST_R_CRYPTOFAILURE); pTemplate[0].pValue = isc_mem_get(key->mctx, pTemplate[0].ulValueLen); if (pTemplate[0].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(pTemplate[0].pValue, 0, pTemplate[0].ulValueLen); pTemplate[1].pValue = isc_mem_get(key->mctx, pTemplate[1].ulValueLen); if (pTemplate[1].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(pTemplate[1].pValue, 0, pTemplate[1].ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, domainparams, pTemplate, (CK_ULONG) 2), DST_R_CRYPTOFAILURE); pubTemplate[4].pValue = pTemplate[0].pValue; pubTemplate[4].ulValueLen = pTemplate[0].ulValueLen; pTemplate[0].pValue = NULL; pubTemplate[5].pValue = pTemplate[1].pValue; pubTemplate[5].ulValueLen = pTemplate[1].ulValueLen; pTemplate[1].pValue = NULL; } mech.mechanism = CKM_DH_PKCS_KEY_PAIR_GEN; PK11_RET(pkcs_C_GenerateKeyPair, (pk11_ctx->session, &mech, pubTemplate, (CK_ULONG) 6, privTemplate, (CK_ULONG) 7, &pub, &priv), DST_R_CRYPTOFAILURE); dh = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dh)); if (dh == NULL) DST_RET(ISC_R_NOMEMORY); memset(dh, 0, sizeof(*dh)); key->keydata.pkey = dh; dh->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 4); if (dh->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(dh->repr, 0, sizeof(*attr) * 4); dh->attrcnt = 4; attr = dh->repr; attr[0].type = CKA_PRIME; attr[0].pValue = pubTemplate[4].pValue; attr[0].ulValueLen = pubTemplate[4].ulValueLen; pubTemplate[4].pValue = NULL; attr[1].type = CKA_BASE; attr[1].pValue = pubTemplate[5].pValue; attr[1].ulValueLen = pubTemplate[5].ulValueLen; pubTemplate[5].pValue =NULL; attr += 2; attr->type = CKA_VALUE; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr++; attr->type = CKA_VALUE; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); attr->type = CKA_VALUE2; (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); (void) pkcs_C_DestroyObject(pk11_ctx->session, domainparams); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ISC_R_SUCCESS); err: pkcs11dh_destroy(key); if (priv != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); if (pub != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); if (domainparams != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, domainparams); if (pubTemplate[4].pValue != NULL) { memset(pubTemplate[4].pValue, 0, pubTemplate[4].ulValueLen); isc_mem_put(key->mctx, pubTemplate[4].pValue, pubTemplate[4].ulValueLen); } if (pubTemplate[5].pValue != NULL) { memset(pubTemplate[5].pValue, 0, pubTemplate[5].ulValueLen); isc_mem_put(key->mctx, pubTemplate[5].pValue, pubTemplate[5].ulValueLen); } if (pTemplate[0].pValue != NULL) { memset(pTemplate[0].pValue, 0, pTemplate[0].ulValueLen); isc_mem_put(key->mctx, pTemplate[0].pValue, pTemplate[0].ulValueLen); } if (pTemplate[1].pValue != NULL) { memset(pTemplate[1].pValue, 0, pTemplate[1].ulValueLen); isc_mem_put(key->mctx, pTemplate[1].pValue, pTemplate[1].ulValueLen); } pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); } static isc_boolean_t pkcs11dh_isprivate(const dst_key_t *key) { pk11_object_t *dh = key->keydata.pkey; CK_ATTRIBUTE *attr; if (dh == NULL) return (ISC_FALSE); attr = pk11_attribute_bytype(dh, CKA_VALUE2); return (ISC_TF((attr != NULL) || dh->ontoken)); } static void pkcs11dh_destroy(dst_key_t *key) { pk11_object_t *dh = key->keydata.pkey; CK_ATTRIBUTE *attr; if (dh == NULL) return; INSIST((dh->object == CK_INVALID_HANDLE) || dh->ontoken); for (attr = pk11_attribute_first(dh); attr != NULL; attr = pk11_attribute_next(dh, attr)) switch (attr->type) { case CKA_VALUE: case CKA_VALUE2: case CKA_PRIME: case CKA_BASE: if (attr->pValue != NULL) { memset(attr->pValue, 0, attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); } break; } if (dh->repr != NULL) { memset(dh->repr, 0, dh->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, dh->repr, dh->attrcnt * sizeof(*attr)); } memset(dh, 0, sizeof(*dh)); isc_mem_put(key->mctx, dh, sizeof(*dh)); key->keydata.pkey = NULL; } static void uint16_toregion(isc_uint16_t val, isc_region_t *region) { *region->base = (val & 0xff00) >> 8; isc_region_consume(region, 1); *region->base = (val & 0x00ff); isc_region_consume(region, 1); } static isc_uint16_t uint16_fromregion(isc_region_t *region) { isc_uint16_t val; unsigned char *cp = region->base; val = ((unsigned int)(cp[0])) << 8; val |= ((unsigned int)(cp[1])); isc_region_consume(region, 2); return (val); } static isc_result_t pkcs11dh_todns(const dst_key_t *key, isc_buffer_t *data) { pk11_object_t *dh; CK_ATTRIBUTE *attr; isc_region_t r; isc_uint16_t dnslen, plen = 0, glen = 0, publen = 0; CK_BYTE *prime = NULL, *base = NULL, *pub = NULL; REQUIRE(key->keydata.pkey != NULL); dh = key->keydata.pkey; for (attr = pk11_attribute_first(dh); attr != NULL; attr = pk11_attribute_next(dh, attr)) switch (attr->type) { case CKA_VALUE: pub = (CK_BYTE *) attr->pValue; publen = (isc_uint16_t) attr->ulValueLen; break; case CKA_PRIME: prime = (CK_BYTE *) attr->pValue; plen = (isc_uint16_t) attr->ulValueLen; break; case CKA_BASE: base = (CK_BYTE *) attr->pValue; glen = (isc_uint16_t) attr->ulValueLen; break; } REQUIRE((prime != NULL) && (base != NULL) && (pub != NULL)); isc_buffer_availableregion(data, &r); if ((glen == 1) && isc_safe_memequal(pk11_dh_bn2, base, glen) && (((plen == sizeof(pk11_dh_bn768)) && isc_safe_memequal(pk11_dh_bn768, prime, plen)) || ((plen == sizeof(pk11_dh_bn1024)) && isc_safe_memequal(pk11_dh_bn1024, prime, plen)) || ((plen == sizeof(pk11_dh_bn1536)) && isc_safe_memequal(pk11_dh_bn1536, prime, plen)))) { plen = 1; glen = 0; } dnslen = plen + glen + publen + 6; if (r.length < (unsigned int) dnslen) return (ISC_R_NOSPACE); uint16_toregion(plen, &r); if (plen == 1) { if (isc_safe_memequal(pk11_dh_bn768, prime, sizeof(pk11_dh_bn768))) *r.base = 1; else if (isc_safe_memequal(pk11_dh_bn1024, prime, sizeof(pk11_dh_bn1024))) *r.base = 2; else *r.base = 3; } else memmove(r.base, prime, plen); isc_region_consume(&r, plen); uint16_toregion(glen, &r); if (glen > 0) memmove(r.base, base, glen); isc_region_consume(&r, glen); uint16_toregion(publen, &r); memmove(r.base, pub, publen); isc_region_consume(&r, publen); isc_buffer_add(data, dnslen); return (ISC_R_SUCCESS); } static isc_result_t pkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) { pk11_object_t *dh; isc_region_t r; isc_uint16_t plen, glen, plen_, glen_, publen; CK_BYTE *prime = NULL, *base = NULL, *pub = NULL; CK_ATTRIBUTE *attr; int special = 0; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); dh = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dh)); if (dh == NULL) return (ISC_R_NOMEMORY); memset(dh, 0, sizeof(*dh)); /* * Read the prime length. 1 & 2 are table entries, > 16 means a * prime follows, otherwise an error. */ if (r.length < 2) { memset(dh, 0, sizeof(*dh)); isc_mem_put(key->mctx, dh, sizeof(*dh)); return (DST_R_INVALIDPUBLICKEY); } plen = uint16_fromregion(&r); if (plen < 16 && plen != 1 && plen != 2) { memset(dh, 0, sizeof(*dh)); isc_mem_put(key->mctx, dh, sizeof(*dh)); return (DST_R_INVALIDPUBLICKEY); } if (r.length < plen) { memset(dh, 0, sizeof(*dh)); isc_mem_put(key->mctx, dh, sizeof(*dh)); return (DST_R_INVALIDPUBLICKEY); } plen_ = plen; if (plen == 1 || plen == 2) { if (plen == 1) { special = *r.base; isc_region_consume(&r, 1); } else { special = uint16_fromregion(&r); } switch (special) { case 1: prime = pk11_dh_bn768; plen_ = sizeof(pk11_dh_bn768); break; case 2: prime = pk11_dh_bn1024; plen_ = sizeof(pk11_dh_bn1024); break; case 3: prime = pk11_dh_bn1536; plen_ = sizeof(pk11_dh_bn1536); break; default: memset(dh, 0, sizeof(*dh)); isc_mem_put(key->mctx, dh, sizeof(*dh)); return (DST_R_INVALIDPUBLICKEY); } } else { prime = r.base; isc_region_consume(&r, plen); } /* * Read the generator length. This should be 0 if the prime was * special, but it might not be. If it's 0 and the prime is not * special, we have a problem. */ if (r.length < 2) { memset(dh, 0, sizeof(*dh)); isc_mem_put(key->mctx, dh, sizeof(*dh)); return (DST_R_INVALIDPUBLICKEY); } glen = uint16_fromregion(&r); if (r.length < glen) { memset(dh, 0, sizeof(*dh)); isc_mem_put(key->mctx, dh, sizeof(*dh)); return (DST_R_INVALIDPUBLICKEY); } glen_ = glen; if (special != 0) { if (glen == 0) { base = pk11_dh_bn2; glen_ = sizeof(pk11_dh_bn2); } else { base = r.base; if (isc_safe_memequal(base, pk11_dh_bn2, glen)) { base = pk11_dh_bn2; glen_ = sizeof(pk11_dh_bn2); } else { memset(dh, 0, sizeof(*dh)); isc_mem_put(key->mctx, dh, sizeof(*dh)); return (DST_R_INVALIDPUBLICKEY); } } } else { if (glen == 0) { memset(dh, 0, sizeof(*dh)); isc_mem_put(key->mctx, dh, sizeof(*dh)); return (DST_R_INVALIDPUBLICKEY); } base = r.base; } isc_region_consume(&r, glen); if (r.length < 2) { memset(dh, 0, sizeof(*dh)); isc_mem_put(key->mctx, dh, sizeof(*dh)); return (DST_R_INVALIDPUBLICKEY); } publen = uint16_fromregion(&r); if (r.length < publen) { memset(dh, 0, sizeof(*dh)); isc_mem_put(key->mctx, dh, sizeof(*dh)); return (DST_R_INVALIDPUBLICKEY); } pub = r.base; isc_region_consume(&r, publen); key->key_size = pk11_numbits(prime, plen_); dh->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 3); if (dh->repr == NULL) goto nomemory; memset(dh->repr, 0, sizeof(*attr) * 3); dh->attrcnt = 3; attr = dh->repr; attr[0].type = CKA_PRIME; attr[0].pValue = isc_mem_get(key->mctx, plen_); if (attr[0].pValue == NULL) goto nomemory; memmove(attr[0].pValue, prime, plen_); attr[0].ulValueLen = (CK_ULONG) plen_; attr[1].type = CKA_BASE; attr[1].pValue = isc_mem_get(key->mctx, glen_); if (attr[1].pValue == NULL) goto nomemory; memmove(attr[1].pValue, base, glen_); attr[1].ulValueLen = (CK_ULONG) glen_; attr[2].type = CKA_VALUE; attr[2].pValue = isc_mem_get(key->mctx, publen); if (attr[2].pValue == NULL) goto nomemory; memmove(attr[2].pValue, pub, publen); attr[2].ulValueLen = (CK_ULONG) publen; isc_buffer_forward(data, plen + glen + publen + 6); key->keydata.pkey = dh; return (ISC_R_SUCCESS); nomemory: for (attr = pk11_attribute_first(dh); attr != NULL; attr = pk11_attribute_next(dh, attr)) switch (attr->type) { case CKA_VALUE: case CKA_PRIME: case CKA_BASE: if (attr->pValue != NULL) { memset(attr->pValue, 0, attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); } break; } if (dh->repr != NULL) { memset(dh->repr, 0, dh->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, dh->repr, dh->attrcnt * sizeof(*attr)); } memset(dh, 0, sizeof(*dh)); isc_mem_put(key->mctx, dh, sizeof(*dh)); return (ISC_R_NOMEMORY); } static isc_result_t pkcs11dh_tofile(const dst_key_t *key, const char *directory) { int i; pk11_object_t *dh; CK_ATTRIBUTE *attr; CK_ATTRIBUTE *prime = NULL, *base = NULL, *pub = NULL, *prv = NULL; dst_private_t priv; unsigned char *bufs[4]; isc_result_t result; if (key->keydata.pkey == NULL) return (DST_R_NULLKEY); if (key->external) return (DST_R_EXTERNALKEY); dh = key->keydata.pkey; for (attr = pk11_attribute_first(dh); attr != NULL; attr = pk11_attribute_next(dh, attr)) switch (attr->type) { case CKA_VALUE: pub = attr; break; case CKA_VALUE2: prv = attr; break; case CKA_PRIME: prime = attr; break; case CKA_BASE: base = attr; break; } if ((prime == NULL) || (base == NULL) || (pub == NULL) || (prv == NULL)) return (DST_R_NULLKEY); memset(bufs, 0, sizeof(bufs)); for (i = 0; i < 4; i++) { bufs[i] = isc_mem_get(key->mctx, prime->ulValueLen); if (bufs[i] == NULL) { result = ISC_R_NOMEMORY; goto fail; } memset(bufs[i], 0, prime->ulValueLen); } i = 0; priv.elements[i].tag = TAG_DH_PRIME; priv.elements[i].length = (unsigned short) prime->ulValueLen; memmove(bufs[i], prime->pValue, prime->ulValueLen); priv.elements[i].data = bufs[i]; i++; priv.elements[i].tag = TAG_DH_GENERATOR; priv.elements[i].length = (unsigned short) base->ulValueLen; memmove(bufs[i], base->pValue, base->ulValueLen); priv.elements[i].data = bufs[i]; i++; priv.elements[i].tag = TAG_DH_PRIVATE; priv.elements[i].length = (unsigned short) prv->ulValueLen; memmove(bufs[i], prv->pValue, prv->ulValueLen); priv.elements[i].data = bufs[i]; i++; priv.elements[i].tag = TAG_DH_PUBLIC; priv.elements[i].length = (unsigned short) pub->ulValueLen; memmove(bufs[i], pub->pValue, pub->ulValueLen); priv.elements[i].data = bufs[i]; i++; priv.nelements = i; result = dst__privstruct_writefile(key, &priv, directory); fail: for (i = 0; i < 4; i++) { if (bufs[i] == NULL) break; memset(bufs[i], 0, prime->ulValueLen); isc_mem_put(key->mctx, bufs[i], prime->ulValueLen); } return (result); } static isc_result_t pkcs11dh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t ret; int i; pk11_object_t *dh = NULL; CK_ATTRIBUTE *attr; isc_mem_t *mctx; UNUSED(pub); mctx = key->mctx; /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_DH, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) return (ret); if (key->external) DST_RET(DST_R_EXTERNALKEY); dh = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dh)); if (dh == NULL) DST_RET(ISC_R_NOMEMORY); memset(dh, 0, sizeof(*dh)); key->keydata.pkey = dh; dh->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 4); if (dh->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(dh->repr, 0, sizeof(*attr) * 4); dh->attrcnt = 4; attr = dh->repr; attr[0].type = CKA_PRIME; attr[1].type = CKA_BASE; attr[2].type = CKA_VALUE; attr[3].type = CKA_VALUE2; for (i = 0; i < priv.nelements; i++) { CK_BYTE *bn; bn = isc_mem_get(key->mctx, priv.elements[i].length); if (bn == NULL) DST_RET(ISC_R_NOMEMORY); memmove(bn, priv.elements[i].data, priv.elements[i].length); switch (priv.elements[i].tag) { case TAG_DH_PRIME: attr = pk11_attribute_bytype(dh, CKA_PRIME); INSIST(attr != NULL); attr->pValue = bn; attr->ulValueLen = priv.elements[i].length; break; case TAG_DH_GENERATOR: attr = pk11_attribute_bytype(dh, CKA_BASE); INSIST(attr != NULL); attr->pValue = bn; attr->ulValueLen = priv.elements[i].length; break; case TAG_DH_PRIVATE: attr = pk11_attribute_bytype(dh, CKA_VALUE2); INSIST(attr != NULL); attr->pValue = bn; attr->ulValueLen = priv.elements[i].length; break; case TAG_DH_PUBLIC: attr = pk11_attribute_bytype(dh, CKA_VALUE); INSIST(attr != NULL); attr->pValue = bn; attr->ulValueLen = priv.elements[i].length; break; } } dst__privstruct_free(&priv, mctx); attr = pk11_attribute_bytype(dh, CKA_PRIME); INSIST(attr != NULL); key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); return (ISC_R_SUCCESS); err: pkcs11dh_destroy(key); dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ret); } static dst_func_t pkcs11dh_functions = { NULL, /*%< createctx */ NULL, /*%< createctx2 */ NULL, /*%< destroyctx */ NULL, /*%< adddata */ NULL, /*%< sign */ NULL, /*%< verify */ NULL, /*%< verify2 */ pkcs11dh_computesecret, pkcs11dh_compare, pkcs11dh_paramcompare, pkcs11dh_generate, pkcs11dh_isprivate, pkcs11dh_destroy, pkcs11dh_todns, pkcs11dh_fromdns, pkcs11dh_tofile, pkcs11dh_parse, NULL, /*%< cleanup */ NULL, /*%< fromlabel */ NULL, /*%< dump */ NULL, /*%< restore */ }; isc_result_t dst__pkcs11dh_init(dst_func_t **funcp) { REQUIRE(funcp != NULL); if (*funcp == NULL) *funcp = &pkcs11dh_functions; return (ISC_R_SUCCESS); } #else /* PKCS11CRYPTO */ #include EMPTY_TRANSLATION_UNIT #endif /* PKCS11CRYPTO */ /*! \file */ bind9-9.10.3.dfsg.P4/lib/dns/opensslecdsa_link.c0000644000470500017500000003642412664710322020600 0ustar lamontlamont/* * Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #if defined(OPENSSL) && defined(HAVE_OPENSSL_ECDSA) #if !defined(HAVE_EVP_SHA256) || !defined(HAVE_EVP_SHA384) #error "ECDSA without EVP for SHA2?" #endif #include #include #include #include #include #include #include #include "dst_internal.h" #include "dst_openssl.h" #include "dst_parse.h" #include #include #include #include #ifndef NID_X9_62_prime256v1 #error "P-256 group is not known (NID_X9_62_prime256v1)" #endif #ifndef NID_secp384r1 #error "P-384 group is not known (NID_secp384r1)" #endif #define DST_RET(a) {ret = a; goto err;} static isc_result_t opensslecdsa_todns(const dst_key_t *key, isc_buffer_t *data); static isc_result_t opensslecdsa_createctx(dst_key_t *key, dst_context_t *dctx) { EVP_MD_CTX *evp_md_ctx; const EVP_MD *type = NULL; UNUSED(key); REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || dctx->key->key_alg == DST_ALG_ECDSA384); evp_md_ctx = EVP_MD_CTX_create(); if (evp_md_ctx == NULL) return (ISC_R_NOMEMORY); if (dctx->key->key_alg == DST_ALG_ECDSA256) type = EVP_sha256(); else type = EVP_sha384(); if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) { EVP_MD_CTX_destroy(evp_md_ctx); return (dst__openssl_toresult3(dctx->category, "EVP_DigestInit_ex", ISC_R_FAILURE)); } dctx->ctxdata.evp_md_ctx = evp_md_ctx; return (ISC_R_SUCCESS); } static void opensslecdsa_destroyctx(dst_context_t *dctx) { EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || dctx->key->key_alg == DST_ALG_ECDSA384); if (evp_md_ctx != NULL) { EVP_MD_CTX_destroy(evp_md_ctx); dctx->ctxdata.evp_md_ctx = NULL; } } static isc_result_t opensslecdsa_adddata(dst_context_t *dctx, const isc_region_t *data) { EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || dctx->key->key_alg == DST_ALG_ECDSA384); if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) return (dst__openssl_toresult3(dctx->category, "EVP_DigestUpdate", ISC_R_FAILURE)); return (ISC_R_SUCCESS); } static int BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf, int size) { int bytes = size - BN_num_bytes(bn); while (bytes-- > 0) *buf++ = 0; BN_bn2bin(bn, buf); return (size); } static isc_result_t opensslecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { isc_result_t ret; dst_key_t *key = dctx->key; isc_region_t r; ECDSA_SIG *ecdsasig; EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; EVP_PKEY *pkey = key->keydata.pkey; EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey); unsigned int dgstlen, siglen; unsigned char digest[EVP_MAX_MD_SIZE]; REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); if (eckey == NULL) return (ISC_R_FAILURE); if (key->key_alg == DST_ALG_ECDSA256) siglen = DNS_SIG_ECDSA256SIZE; else siglen = DNS_SIG_ECDSA384SIZE; isc_buffer_availableregion(sig, &r); if (r.length < siglen) DST_RET(ISC_R_NOSPACE); if (!EVP_DigestFinal(evp_md_ctx, digest, &dgstlen)) DST_RET(dst__openssl_toresult3(dctx->category, "EVP_DigestFinal", ISC_R_FAILURE)); ecdsasig = ECDSA_do_sign(digest, dgstlen, eckey); if (ecdsasig == NULL) DST_RET(dst__openssl_toresult3(dctx->category, "ECDSA_do_sign", DST_R_SIGNFAILURE)); BN_bn2bin_fixed(ecdsasig->r, r.base, siglen / 2); isc_region_consume(&r, siglen / 2); BN_bn2bin_fixed(ecdsasig->s, r.base, siglen / 2); isc_region_consume(&r, siglen / 2); ECDSA_SIG_free(ecdsasig); isc_buffer_add(sig, siglen); ret = ISC_R_SUCCESS; err: if (eckey != NULL) EC_KEY_free(eckey); return (ret); } static isc_result_t opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) { isc_result_t ret; dst_key_t *key = dctx->key; int status; unsigned char *cp = sig->base; ECDSA_SIG *ecdsasig = NULL; EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; EVP_PKEY *pkey = key->keydata.pkey; EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey); unsigned int dgstlen, siglen; unsigned char digest[EVP_MAX_MD_SIZE]; REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); if (eckey == NULL) return (ISC_R_FAILURE); if (key->key_alg == DST_ALG_ECDSA256) siglen = DNS_SIG_ECDSA256SIZE; else siglen = DNS_SIG_ECDSA384SIZE; if (sig->length != siglen) return (DST_R_VERIFYFAILURE); if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &dgstlen)) DST_RET (dst__openssl_toresult3(dctx->category, "EVP_DigestFinal_ex", ISC_R_FAILURE)); ecdsasig = ECDSA_SIG_new(); if (ecdsasig == NULL) DST_RET (ISC_R_NOMEMORY); if (ecdsasig->r != NULL) BN_free(ecdsasig->r); ecdsasig->r = BN_bin2bn(cp, siglen / 2, NULL); cp += siglen / 2; if (ecdsasig->s != NULL) BN_free(ecdsasig->s); ecdsasig->s = BN_bin2bn(cp, siglen / 2, NULL); /* cp += siglen / 2; */ status = ECDSA_do_verify(digest, dgstlen, ecdsasig, eckey); switch (status) { case 1: ret = ISC_R_SUCCESS; break; case 0: ret = dst__openssl_toresult(DST_R_VERIFYFAILURE); break; default: ret = dst__openssl_toresult3(dctx->category, "ECDSA_do_verify", DST_R_VERIFYFAILURE); break; } err: if (ecdsasig != NULL) ECDSA_SIG_free(ecdsasig); if (eckey != NULL) EC_KEY_free(eckey); return (ret); } static isc_boolean_t opensslecdsa_compare(const dst_key_t *key1, const dst_key_t *key2) { isc_boolean_t ret; int status; EVP_PKEY *pkey1 = key1->keydata.pkey; EVP_PKEY *pkey2 = key2->keydata.pkey; EC_KEY *eckey1 = NULL; EC_KEY *eckey2 = NULL; const BIGNUM *priv1, *priv2; if (pkey1 == NULL && pkey2 == NULL) return (ISC_TRUE); else if (pkey1 == NULL || pkey2 == NULL) return (ISC_FALSE); eckey1 = EVP_PKEY_get1_EC_KEY(pkey1); eckey2 = EVP_PKEY_get1_EC_KEY(pkey2); if (eckey1 == NULL && eckey2 == NULL) { DST_RET (ISC_TRUE); } else if (eckey1 == NULL || eckey2 == NULL) DST_RET (ISC_FALSE); status = EVP_PKEY_cmp(pkey1, pkey2); if (status != 1) DST_RET (ISC_FALSE); priv1 = EC_KEY_get0_private_key(eckey1); priv2 = EC_KEY_get0_private_key(eckey2); if (priv1 != NULL || priv2 != NULL) { if (priv1 == NULL || priv2 == NULL) DST_RET (ISC_FALSE); if (BN_cmp(priv1, priv2) != 0) DST_RET (ISC_FALSE); } ret = ISC_TRUE; err: if (eckey1 != NULL) EC_KEY_free(eckey1); if (eckey2 != NULL) EC_KEY_free(eckey2); return (ret); } static isc_result_t opensslecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { isc_result_t ret; EVP_PKEY *pkey; EC_KEY *eckey = NULL; int group_nid; REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); UNUSED(unused); UNUSED(callback); if (key->key_alg == DST_ALG_ECDSA256) { group_nid = NID_X9_62_prime256v1; key->key_size = DNS_KEY_ECDSA256SIZE * 4; } else { group_nid = NID_secp384r1; key->key_size = DNS_KEY_ECDSA384SIZE * 4; } eckey = EC_KEY_new_by_curve_name(group_nid); if (eckey == NULL) return (dst__openssl_toresult2("EC_KEY_new_by_curve_name", DST_R_OPENSSLFAILURE)); if (EC_KEY_generate_key(eckey) != 1) DST_RET (dst__openssl_toresult2("EC_KEY_generate_key", DST_R_OPENSSLFAILURE)); pkey = EVP_PKEY_new(); if (pkey == NULL) DST_RET (ISC_R_NOMEMORY); if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) { EVP_PKEY_free(pkey); DST_RET (ISC_R_FAILURE); } key->keydata.pkey = pkey; ret = ISC_R_SUCCESS; err: if (eckey != NULL) EC_KEY_free(eckey); return (ret); } static isc_boolean_t opensslecdsa_isprivate(const dst_key_t *key) { isc_boolean_t ret; EVP_PKEY *pkey = key->keydata.pkey; EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey); ret = ISC_TF(eckey != NULL && EC_KEY_get0_private_key(eckey) != NULL); if (eckey != NULL) EC_KEY_free(eckey); return (ret); } static void opensslecdsa_destroy(dst_key_t *key) { EVP_PKEY *pkey = key->keydata.pkey; EVP_PKEY_free(pkey); key->keydata.pkey = NULL; } static isc_result_t opensslecdsa_todns(const dst_key_t *key, isc_buffer_t *data) { isc_result_t ret; EVP_PKEY *pkey; EC_KEY *eckey = NULL; isc_region_t r; int len; unsigned char *cp; unsigned char buf[DNS_KEY_ECDSA384SIZE + 1]; REQUIRE(key->keydata.pkey != NULL); pkey = key->keydata.pkey; eckey = EVP_PKEY_get1_EC_KEY(pkey); if (eckey == NULL) return (dst__openssl_toresult(ISC_R_FAILURE)); len = i2o_ECPublicKey(eckey, NULL); /* skip form */ len--; isc_buffer_availableregion(data, &r); if (r.length < (unsigned int) len) DST_RET (ISC_R_NOSPACE); cp = buf; if (!i2o_ECPublicKey(eckey, &cp)) DST_RET (dst__openssl_toresult(ISC_R_FAILURE)); memmove(r.base, buf + 1, len); isc_buffer_add(data, len); ret = ISC_R_SUCCESS; err: if (eckey != NULL) EC_KEY_free(eckey); return (ret); } static isc_result_t opensslecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) { isc_result_t ret; EVP_PKEY *pkey; EC_KEY *eckey = NULL; isc_region_t r; int group_nid; unsigned int len; const unsigned char *cp; unsigned char buf[DNS_KEY_ECDSA384SIZE + 1]; REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); if (key->key_alg == DST_ALG_ECDSA256) { len = DNS_KEY_ECDSA256SIZE; group_nid = NID_X9_62_prime256v1; } else { len = DNS_KEY_ECDSA384SIZE; group_nid = NID_secp384r1; } isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); if (r.length < len) return (DST_R_INVALIDPUBLICKEY); eckey = EC_KEY_new_by_curve_name(group_nid); if (eckey == NULL) return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); buf[0] = POINT_CONVERSION_UNCOMPRESSED; memmove(buf + 1, r.base, len); cp = buf; if (o2i_ECPublicKey(&eckey, (const unsigned char **) &cp, (long) len + 1) == NULL) DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY)); if (EC_KEY_check_key(eckey) != 1) DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY)); pkey = EVP_PKEY_new(); if (pkey == NULL) DST_RET (ISC_R_NOMEMORY); if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) { EVP_PKEY_free(pkey); DST_RET (dst__openssl_toresult(ISC_R_FAILURE)); } isc_buffer_forward(data, len); key->keydata.pkey = pkey; key->key_size = len * 4; ret = ISC_R_SUCCESS; err: if (eckey != NULL) EC_KEY_free(eckey); return (ret); } static isc_result_t opensslecdsa_tofile(const dst_key_t *key, const char *directory) { isc_result_t ret; EVP_PKEY *pkey; EC_KEY *eckey = NULL; const BIGNUM *privkey; dst_private_t priv; unsigned char *buf = NULL; if (key->keydata.pkey == NULL) return (DST_R_NULLKEY); if (key->external) { priv.nelements = 0; return (dst__privstruct_writefile(key, &priv, directory)); } pkey = key->keydata.pkey; eckey = EVP_PKEY_get1_EC_KEY(pkey); if (eckey == NULL) return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); privkey = EC_KEY_get0_private_key(eckey); if (privkey == NULL) DST_RET (ISC_R_FAILURE); buf = isc_mem_get(key->mctx, BN_num_bytes(privkey)); if (buf == NULL) DST_RET (ISC_R_NOMEMORY); priv.elements[0].tag = TAG_ECDSA_PRIVATEKEY; priv.elements[0].length = BN_num_bytes(privkey); BN_bn2bin(privkey, buf); priv.elements[0].data = buf; priv.nelements = 1; ret = dst__privstruct_writefile(key, &priv, directory); err: if (eckey != NULL) EC_KEY_free(eckey); if (buf != NULL) isc_mem_put(key->mctx, buf, BN_num_bytes(privkey)); return (ret); } static isc_result_t ecdsa_check(EC_KEY *eckey, dst_key_t *pub) { isc_result_t ret = ISC_R_FAILURE; EVP_PKEY *pkey; EC_KEY *pubeckey = NULL; const EC_POINT *pubkey; if (pub == NULL) return (ISC_R_SUCCESS); pkey = pub->keydata.pkey; if (pkey == NULL) return (ISC_R_SUCCESS); pubeckey = EVP_PKEY_get1_EC_KEY(pkey); if (pubeckey == NULL) return (ISC_R_SUCCESS); pubkey = EC_KEY_get0_public_key(pubeckey); if (pubkey == NULL) DST_RET (ISC_R_SUCCESS); if (EC_KEY_set_public_key(eckey, pubkey) != 1) DST_RET (ISC_R_SUCCESS); if (EC_KEY_check_key(eckey) == 1) DST_RET (ISC_R_SUCCESS); err: if (pubeckey != NULL) EC_KEY_free(pubeckey); return (ret); } static isc_result_t opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t ret; EVP_PKEY *pkey; EC_KEY *eckey = NULL; BIGNUM *privkey = NULL; int group_nid; isc_mem_t *mctx = key->mctx; REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) goto err; if (key->external) { if (priv.nelements != 0) DST_RET(DST_R_INVALIDPRIVATEKEY); if (pub == NULL) DST_RET(DST_R_INVALIDPRIVATEKEY); key->keydata.pkey = pub->keydata.pkey; pub->keydata.pkey = NULL; dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ISC_R_SUCCESS); } if (key->key_alg == DST_ALG_ECDSA256) group_nid = NID_X9_62_prime256v1; else group_nid = NID_secp384r1; eckey = EC_KEY_new_by_curve_name(group_nid); if (eckey == NULL) return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); privkey = BN_bin2bn(priv.elements[0].data, priv.elements[0].length, NULL); if (privkey == NULL) DST_RET(ISC_R_NOMEMORY); if (!EC_KEY_set_private_key(eckey, privkey)) DST_RET(ISC_R_NOMEMORY); if (ecdsa_check(eckey, pub) != ISC_R_SUCCESS) DST_RET(DST_R_INVALIDPRIVATEKEY); pkey = EVP_PKEY_new(); if (pkey == NULL) DST_RET (ISC_R_NOMEMORY); if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) { EVP_PKEY_free(pkey); DST_RET (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); } key->keydata.pkey = pkey; if (key->key_alg == DST_ALG_ECDSA256) key->key_size = DNS_KEY_ECDSA256SIZE * 4; else key->key_size = DNS_KEY_ECDSA384SIZE * 4; ret = ISC_R_SUCCESS; err: if (privkey != NULL) BN_clear_free(privkey); if (eckey != NULL) EC_KEY_free(eckey); dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ret); } static dst_func_t opensslecdsa_functions = { opensslecdsa_createctx, NULL, /*%< createctx2 */ opensslecdsa_destroyctx, opensslecdsa_adddata, opensslecdsa_sign, opensslecdsa_verify, NULL, /*%< verify2 */ NULL, /*%< computesecret */ opensslecdsa_compare, NULL, /*%< paramcompare */ opensslecdsa_generate, opensslecdsa_isprivate, opensslecdsa_destroy, opensslecdsa_todns, opensslecdsa_fromdns, opensslecdsa_tofile, opensslecdsa_parse, NULL, /*%< cleanup */ NULL, /*%< fromlabel */ NULL, /*%< dump */ NULL, /*%< restore */ }; isc_result_t dst__opensslecdsa_init(dst_func_t **funcp) { REQUIRE(funcp != NULL); if (*funcp == NULL) *funcp = &opensslecdsa_functions; return (ISC_R_SUCCESS); } #else /* HAVE_OPENSSL_ECDSA */ #include EMPTY_TRANSLATION_UNIT #endif /* HAVE_OPENSSL_ECDSA */ /*! \file */ bind9-9.10.3.dfsg.P4/lib/dns/version.c0000644000470500017500000000231212664710322016552 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: version.c,v 1.15.1234.1 2012/02/11 22:37:57 each Exp $ */ /*! \file */ #include const char dns_version[] = VERSION; const char dns_major[] = MAJOR; const char dns_mapapi[] = MAPAPI; const unsigned int dns_libinterface = LIBINTERFACE; const unsigned int dns_librevision = LIBREVISION; const unsigned int dns_libage = LIBAGE; bind9-9.10.3.dfsg.P4/lib/dns/rdatalist_p.h0000644000470500017500000000364612664710322017413 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rdatalist_p.h,v 1.11 2008/09/25 04:02:38 tbox Exp $ */ #ifndef DNS_RDATALIST_P_H #define DNS_RDATALIST_P_H /*! \file */ #include #include ISC_LANG_BEGINDECLS void isc__rdatalist_disassociate(dns_rdataset_t *rdatasetp); isc_result_t isc__rdatalist_first(dns_rdataset_t *rdataset); isc_result_t isc__rdatalist_next(dns_rdataset_t *rdataset); void isc__rdatalist_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata); void isc__rdatalist_clone(dns_rdataset_t *source, dns_rdataset_t *target); unsigned int isc__rdatalist_count(dns_rdataset_t *rdataset); isc_result_t isc__rdatalist_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name); isc_result_t isc__rdatalist_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name, dns_rdataset_t *neg, dns_rdataset_t *negsig); isc_result_t isc__rdatalist_addclosest(dns_rdataset_t *rdataset, dns_name_t *name); isc_result_t isc__rdatalist_getclosest(dns_rdataset_t *rdataset, dns_name_t *name, dns_rdataset_t *neg, dns_rdataset_t *negsig); ISC_LANG_ENDDECLS #endif /* DNS_RDATALIST_P_H */ bind9-9.10.3.dfsg.P4/lib/dns/ncache.c0000644000470500017500000004670612664710322016325 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2008, 2010-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #define DNS_NCACHE_RDATA 20U /* * The format of an ncache rdata is a sequence of zero or more records of * the following format: * * owner name * type * trust * rdata count * rdata length These two occur 'rdata count' * rdata times. * */ static isc_result_t addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, isc_boolean_t optout, isc_boolean_t secure, dns_rdataset_t *addedrdataset); static inline isc_result_t copy_rdataset(dns_rdataset_t *rdataset, isc_buffer_t *buffer) { isc_result_t result; unsigned int count; isc_region_t ar, r; dns_rdata_t rdata = DNS_RDATA_INIT; /* * Copy the rdataset count to the buffer. */ isc_buffer_availableregion(buffer, &ar); if (ar.length < 2) return (ISC_R_NOSPACE); count = dns_rdataset_count(rdataset); INSIST(count <= 65535); isc_buffer_putuint16(buffer, (isc_uint16_t)count); result = dns_rdataset_first(rdataset); while (result == ISC_R_SUCCESS) { dns_rdataset_current(rdataset, &rdata); dns_rdata_toregion(&rdata, &r); INSIST(r.length <= 65535); isc_buffer_availableregion(buffer, &ar); if (ar.length < 2) return (ISC_R_NOSPACE); /* * Copy the rdata length to the buffer. */ isc_buffer_putuint16(buffer, (isc_uint16_t)r.length); /* * Copy the rdata to the buffer. */ result = isc_buffer_copyregion(buffer, &r); if (result != ISC_R_SUCCESS) return (result); dns_rdata_reset(&rdata); result = dns_rdataset_next(rdataset); } if (result != ISC_R_NOMORE) return (result); return (ISC_R_SUCCESS); } isc_result_t dns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, dns_rdataset_t *addedrdataset) { return (addoptout(message, cache, node, covers, now, maxttl, ISC_FALSE, ISC_FALSE, addedrdataset)); } isc_result_t dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, isc_boolean_t optout, dns_rdataset_t *addedrdataset) { return (addoptout(message, cache, node, covers, now, maxttl, optout, ISC_TRUE, addedrdataset)); } static isc_result_t addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, isc_boolean_t optout, isc_boolean_t secure, dns_rdataset_t *addedrdataset) { isc_result_t result; isc_buffer_t buffer; isc_region_t r; dns_rdataset_t *rdataset; dns_rdatatype_t type; dns_name_t *name; dns_ttl_t ttl; dns_trust_t trust; dns_rdata_t rdata[DNS_NCACHE_RDATA]; dns_rdataset_t ncrdataset; dns_rdatalist_t ncrdatalist; unsigned char data[4096]; unsigned int next = 0; /* * Convert the authority data from 'message' into a negative cache * rdataset, and store it in 'cache' at 'node'. */ REQUIRE(message != NULL); /* * We assume that all data in the authority section has been * validated by the caller. */ /* * Initialize the list. */ dns_rdatalist_init(&ncrdatalist); ncrdatalist.rdclass = dns_db_class(cache); ncrdatalist.covers = covers; ncrdatalist.ttl = maxttl; /* * Build an ncache rdatas into buffer. */ ttl = maxttl; trust = 0xffff; isc_buffer_init(&buffer, data, sizeof(data)); if (message->counts[DNS_SECTION_AUTHORITY]) result = dns_message_firstname(message, DNS_SECTION_AUTHORITY); else result = ISC_R_NOMORE; while (result == ISC_R_SUCCESS) { name = NULL; dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name); if ((name->attributes & DNS_NAMEATTR_NCACHE) != 0) { for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if ((rdataset->attributes & DNS_RDATASETATTR_NCACHE) == 0) continue; type = rdataset->type; if (type == dns_rdatatype_rrsig) type = rdataset->covers; if (type == dns_rdatatype_soa || type == dns_rdatatype_nsec || type == dns_rdatatype_nsec3) { if (ttl > rdataset->ttl) ttl = rdataset->ttl; if (trust > rdataset->trust) trust = rdataset->trust; /* * Copy the owner name to the buffer. */ dns_name_toregion(name, &r); result = isc_buffer_copyregion(&buffer, &r); if (result != ISC_R_SUCCESS) return (result); /* * Copy the type to the buffer. */ isc_buffer_availableregion(&buffer, &r); if (r.length < 3) return (ISC_R_NOSPACE); isc_buffer_putuint16(&buffer, rdataset->type); isc_buffer_putuint8(&buffer, (unsigned char)rdataset->trust); /* * Copy the rdataset into the buffer. */ result = copy_rdataset(rdataset, &buffer); if (result != ISC_R_SUCCESS) return (result); if (next >= DNS_NCACHE_RDATA) return (ISC_R_NOSPACE); dns_rdata_init(&rdata[next]); isc_buffer_remainingregion(&buffer, &r); rdata[next].data = r.base; rdata[next].length = r.length; rdata[next].rdclass = ncrdatalist.rdclass; rdata[next].type = 0; rdata[next].flags = 0; ISC_LIST_APPEND(ncrdatalist.rdata, &rdata[next], link); isc_buffer_forward(&buffer, r.length); next++; } } } result = dns_message_nextname(message, DNS_SECTION_AUTHORITY); } if (result != ISC_R_NOMORE) return (result); if (trust == 0xffff) { if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 && message->counts[DNS_SECTION_ANSWER] == 0) { /* * The response has aa set and we haven't followed * any CNAME or DNAME chains. */ trust = dns_trust_authauthority; } else trust = dns_trust_additional; ttl = 0; } INSIST(trust != 0xffff); ncrdatalist.ttl = ttl; dns_rdataset_init(&ncrdataset); RUNTIME_CHECK(dns_rdatalist_tordataset(&ncrdatalist, &ncrdataset) == ISC_R_SUCCESS); if (!secure && trust > dns_trust_answer) trust = dns_trust_answer; ncrdataset.trust = trust; ncrdataset.attributes |= DNS_RDATASETATTR_NEGATIVE; if (message->rcode == dns_rcode_nxdomain) ncrdataset.attributes |= DNS_RDATASETATTR_NXDOMAIN; if (optout) ncrdataset.attributes |= DNS_RDATASETATTR_OPTOUT; return (dns_db_addrdataset(cache, node, NULL, now, &ncrdataset, 0, addedrdataset)); } isc_result_t dns_ncache_towire(dns_rdataset_t *rdataset, dns_compress_t *cctx, isc_buffer_t *target, unsigned int options, unsigned int *countp) { dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; isc_region_t remaining, tavailable; isc_buffer_t source, savedbuffer, rdlen; dns_name_t name; dns_rdatatype_t type; unsigned int i, rcount, count; /* * Convert the negative caching rdataset 'rdataset' to wire format, * compressing names as specified in 'cctx', and storing the result in * 'target'. */ REQUIRE(rdataset != NULL); REQUIRE(rdataset->type == 0); REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0); savedbuffer = *target; count = 0; result = dns_rdataset_first(rdataset); while (result == ISC_R_SUCCESS) { dns_rdataset_current(rdataset, &rdata); isc_buffer_init(&source, rdata.data, rdata.length); isc_buffer_add(&source, rdata.length); dns_name_init(&name, NULL); isc_buffer_remainingregion(&source, &remaining); dns_name_fromregion(&name, &remaining); INSIST(remaining.length >= name.length); isc_buffer_forward(&source, name.length); remaining.length -= name.length; INSIST(remaining.length >= 5); type = isc_buffer_getuint16(&source); isc_buffer_forward(&source, 1); rcount = isc_buffer_getuint16(&source); for (i = 0; i < rcount; i++) { /* * Get the length of this rdata and set up an * rdata structure for it. */ isc_buffer_remainingregion(&source, &remaining); INSIST(remaining.length >= 2); dns_rdata_reset(&rdata); rdata.length = isc_buffer_getuint16(&source); isc_buffer_remainingregion(&source, &remaining); rdata.data = remaining.base; rdata.type = type; rdata.rdclass = rdataset->rdclass; INSIST(remaining.length >= rdata.length); isc_buffer_forward(&source, rdata.length); if ((options & DNS_NCACHETOWIRE_OMITDNSSEC) != 0 && dns_rdatatype_isdnssec(type)) continue; /* * Write the name. */ dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); result = dns_name_towire(&name, cctx, target); if (result != ISC_R_SUCCESS) goto rollback; /* * See if we have space for type, class, ttl, and * rdata length. Write the type, class, and ttl. */ isc_buffer_availableregion(target, &tavailable); if (tavailable.length < 10) { result = ISC_R_NOSPACE; goto rollback; } isc_buffer_putuint16(target, type); isc_buffer_putuint16(target, rdataset->rdclass); isc_buffer_putuint32(target, rdataset->ttl); /* * Save space for rdata length. */ rdlen = *target; isc_buffer_add(target, 2); /* * Write the rdata. */ result = dns_rdata_towire(&rdata, cctx, target); if (result != ISC_R_SUCCESS) goto rollback; /* * Set the rdata length field to the compressed * length. */ INSIST((target->used >= rdlen.used + 2) && (target->used - rdlen.used - 2 < 65536)); isc_buffer_putuint16(&rdlen, (isc_uint16_t)(target->used - rdlen.used - 2)); count++; } INSIST(isc_buffer_remaininglength(&source) == 0); result = dns_rdataset_next(rdataset); dns_rdata_reset(&rdata); } if (result != ISC_R_NOMORE) goto rollback; *countp = count; return (ISC_R_SUCCESS); rollback: INSIST(savedbuffer.used < 65536); dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used); *countp = 0; *target = savedbuffer; return (result); } static void rdataset_disassociate(dns_rdataset_t *rdataset) { UNUSED(rdataset); } static isc_result_t rdataset_first(dns_rdataset_t *rdataset) { unsigned char *raw = rdataset->private3; unsigned int count; count = raw[0] * 256 + raw[1]; if (count == 0) { rdataset->private5 = NULL; return (ISC_R_NOMORE); } raw += 2; /* * The privateuint4 field is the number of rdata beyond the cursor * position, so we decrement the total count by one before storing * it. */ count--; rdataset->privateuint4 = count; rdataset->private5 = raw; return (ISC_R_SUCCESS); } static isc_result_t rdataset_next(dns_rdataset_t *rdataset) { unsigned int count; unsigned int length; unsigned char *raw; count = rdataset->privateuint4; if (count == 0) return (ISC_R_NOMORE); count--; rdataset->privateuint4 = count; raw = rdataset->private5; length = raw[0] * 256 + raw[1]; raw += length + 2; rdataset->private5 = raw; return (ISC_R_SUCCESS); } static void rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) { unsigned char *raw = rdataset->private5; isc_region_t r; REQUIRE(raw != NULL); r.length = raw[0] * 256 + raw[1]; raw += 2; r.base = raw; dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r); } static void rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { *target = *source; /* * Reset iterator state. */ target->privateuint4 = 0; target->private5 = NULL; } static unsigned int rdataset_count(dns_rdataset_t *rdataset) { unsigned char *raw = rdataset->private3; unsigned int count; count = raw[0] * 256 + raw[1]; return (count); } static void rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) { unsigned char *raw = rdataset->private3; raw[-1] = (unsigned char)trust; } static dns_rdatasetmethods_t rdataset_methods = { rdataset_disassociate, rdataset_first, rdataset_next, rdataset_current, rdataset_clone, rdataset_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL, rdataset_settrust, NULL, NULL }; isc_result_t dns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name, dns_rdatatype_t type, dns_rdataset_t *rdataset) { isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; isc_region_t remaining; isc_buffer_t source; dns_name_t tname; dns_rdatatype_t ttype; dns_trust_t trust = dns_trust_none; dns_rdataset_t clone; REQUIRE(ncacherdataset != NULL); REQUIRE(ncacherdataset->type == 0); REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0); REQUIRE(name != NULL); REQUIRE(!dns_rdataset_isassociated(rdataset)); REQUIRE(type != dns_rdatatype_rrsig); dns_rdataset_init(&clone); dns_rdataset_clone(ncacherdataset, &clone); result = dns_rdataset_first(&clone); while (result == ISC_R_SUCCESS) { dns_rdataset_current(&clone, &rdata); isc_buffer_init(&source, rdata.data, rdata.length); isc_buffer_add(&source, rdata.length); dns_name_init(&tname, NULL); isc_buffer_remainingregion(&source, &remaining); dns_name_fromregion(&tname, &remaining); INSIST(remaining.length >= tname.length); isc_buffer_forward(&source, tname.length); remaining.length -= tname.length; INSIST(remaining.length >= 3); ttype = isc_buffer_getuint16(&source); if (ttype == type && dns_name_equal(&tname, name)) { trust = isc_buffer_getuint8(&source); INSIST(trust <= dns_trust_ultimate); isc_buffer_remainingregion(&source, &remaining); break; } result = dns_rdataset_next(&clone); dns_rdata_reset(&rdata); } dns_rdataset_disassociate(&clone); if (result == ISC_R_NOMORE) return (ISC_R_NOTFOUND); if (result != ISC_R_SUCCESS) return (result); INSIST(remaining.length != 0); rdataset->methods = &rdataset_methods; rdataset->rdclass = ncacherdataset->rdclass; rdataset->type = type; rdataset->covers = 0; rdataset->ttl = ncacherdataset->ttl; rdataset->trust = trust; rdataset->private1 = NULL; rdataset->private2 = NULL; rdataset->private3 = remaining.base; /* * Reset iterator state. */ rdataset->privateuint4 = 0; rdataset->private5 = NULL; rdataset->private6 = NULL; return (ISC_R_SUCCESS); } isc_result_t dns_ncache_getsigrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name, dns_rdatatype_t covers, dns_rdataset_t *rdataset) { dns_name_t tname; dns_rdata_rrsig_t rrsig; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_t clone; dns_rdatatype_t type; dns_trust_t trust = dns_trust_none; isc_buffer_t source; isc_region_t remaining, sigregion; isc_result_t result; unsigned char *raw; unsigned int count; REQUIRE(ncacherdataset != NULL); REQUIRE(ncacherdataset->type == 0); REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0); REQUIRE(name != NULL); REQUIRE(!dns_rdataset_isassociated(rdataset)); dns_rdataset_init(&clone); dns_rdataset_clone(ncacherdataset, &clone); result = dns_rdataset_first(&clone); while (result == ISC_R_SUCCESS) { dns_rdataset_current(&clone, &rdata); isc_buffer_init(&source, rdata.data, rdata.length); isc_buffer_add(&source, rdata.length); dns_name_init(&tname, NULL); isc_buffer_remainingregion(&source, &remaining); dns_name_fromregion(&tname, &remaining); INSIST(remaining.length >= tname.length); isc_buffer_forward(&source, tname.length); isc_region_consume(&remaining, tname.length); INSIST(remaining.length >= 2); type = isc_buffer_getuint16(&source); isc_region_consume(&remaining, 2); if (type != dns_rdatatype_rrsig || !dns_name_equal(&tname, name)) { result = dns_rdataset_next(&clone); dns_rdata_reset(&rdata); continue; } INSIST(remaining.length >= 1); trust = isc_buffer_getuint8(&source); INSIST(trust <= dns_trust_ultimate); isc_region_consume(&remaining, 1); raw = remaining.base; count = raw[0] * 256 + raw[1]; INSIST(count > 0); raw += 2; sigregion.length = raw[0] * 256 + raw[1]; raw += 2; sigregion.base = raw; dns_rdata_reset(&rdata); dns_rdata_fromregion(&rdata, rdataset->rdclass, dns_rdatatype_rrsig, &sigregion); (void)dns_rdata_tostruct(&rdata, &rrsig, NULL); if (rrsig.covered == covers) { isc_buffer_remainingregion(&source, &remaining); break; } result = dns_rdataset_next(&clone); dns_rdata_reset(&rdata); } dns_rdataset_disassociate(&clone); if (result == ISC_R_NOMORE) return (ISC_R_NOTFOUND); if (result != ISC_R_SUCCESS) return (result); INSIST(remaining.length != 0); rdataset->methods = &rdataset_methods; rdataset->rdclass = ncacherdataset->rdclass; rdataset->type = dns_rdatatype_rrsig; rdataset->covers = covers; rdataset->ttl = ncacherdataset->ttl; rdataset->trust = trust; rdataset->private1 = NULL; rdataset->private2 = NULL; rdataset->private3 = remaining.base; /* * Reset iterator state. */ rdataset->privateuint4 = 0; rdataset->private5 = NULL; rdataset->private6 = NULL; return (ISC_R_SUCCESS); } void dns_ncache_current(dns_rdataset_t *ncacherdataset, dns_name_t *found, dns_rdataset_t *rdataset) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_trust_t trust; isc_region_t remaining, sigregion; isc_buffer_t source; dns_name_t tname; dns_rdatatype_t type; unsigned int count; dns_rdata_rrsig_t rrsig; unsigned char *raw; REQUIRE(ncacherdataset != NULL); REQUIRE(ncacherdataset->type == 0); REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0); REQUIRE(found != NULL); REQUIRE(!dns_rdataset_isassociated(rdataset)); dns_rdataset_current(ncacherdataset, &rdata); isc_buffer_init(&source, rdata.data, rdata.length); isc_buffer_add(&source, rdata.length); dns_name_init(&tname, NULL); isc_buffer_remainingregion(&source, &remaining); dns_name_fromregion(found, &remaining); INSIST(remaining.length >= found->length); isc_buffer_forward(&source, found->length); remaining.length -= found->length; INSIST(remaining.length >= 5); type = isc_buffer_getuint16(&source); trust = isc_buffer_getuint8(&source); INSIST(trust <= dns_trust_ultimate); isc_buffer_remainingregion(&source, &remaining); rdataset->methods = &rdataset_methods; rdataset->rdclass = ncacherdataset->rdclass; rdataset->type = type; if (type == dns_rdatatype_rrsig) { /* * Extract covers from RRSIG. */ raw = remaining.base; count = raw[0] * 256 + raw[1]; INSIST(count > 0); raw += 2; sigregion.length = raw[0] * 256 + raw[1]; raw += 2; sigregion.base = raw; dns_rdata_reset(&rdata); dns_rdata_fromregion(&rdata, rdataset->rdclass, rdataset->type, &sigregion); (void)dns_rdata_tostruct(&rdata, &rrsig, NULL); rdataset->covers = rrsig.covered; } else rdataset->covers = 0; rdataset->ttl = ncacherdataset->ttl; rdataset->trust = trust; rdataset->private1 = NULL; rdataset->private2 = NULL; rdataset->private3 = remaining.base; /* * Reset iterator state. */ rdataset->privateuint4 = 0; rdataset->private5 = NULL; rdataset->private6 = NULL; } bind9-9.10.3.dfsg.P4/lib/dns/spnego.h0000644000470500017500000000444112664710322016372 0ustar lamontlamont/* * Copyright (C) 2006, 2007 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: spnego.h,v 1.4 2007/06/19 23:47:16 tbox Exp $ */ /*! \file * \brief * Entry points into portable SPNEGO implementation. * See spnego.c for information on the SPNEGO implementation itself. */ #ifndef _SPNEGO_H_ #define _SPNEGO_H_ /*% * Wrapper for GSSAPI gss_init_sec_context(), using portable SPNEGO * implementation instead of the one that's part of the GSSAPI * library. Takes arguments identical to the standard GSSAPI * function, uses standard gss_init_sec_context() to handle * everything inside the SPNEGO wrapper. */ OM_uint32 gss_init_sec_context_spnego(OM_uint32 *, const gss_cred_id_t, gss_ctx_id_t *, const gss_name_t, const gss_OID, OM_uint32, OM_uint32, const gss_channel_bindings_t, const gss_buffer_t, gss_OID *, gss_buffer_t, OM_uint32 *, OM_uint32 *); /*% * Wrapper for GSSAPI gss_accept_sec_context(), using portable SPNEGO * implementation instead of the one that's part of the GSSAPI * library. Takes arguments identical to the standard GSSAPI * function. Checks the OID of the input token to see if it's SPNEGO; * if so, processes it, otherwise hands the call off to the standard * gss_accept_sec_context() function. */ OM_uint32 gss_accept_sec_context_spnego(OM_uint32 *, gss_ctx_id_t *, const gss_cred_id_t, const gss_buffer_t, const gss_channel_bindings_t, gss_name_t *, gss_OID *, gss_buffer_t, OM_uint32 *, OM_uint32 *, gss_cred_id_t *); #endif bind9-9.10.3.dfsg.P4/lib/dns/opensslgost_link.c0000644000470500017500000003523312664710322020472 0ustar lamontlamont/* * Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #if defined(OPENSSL) && defined(HAVE_OPENSSL_GOST) #include #include #include #include #include #include #include "dst_internal.h" #include "dst_openssl.h" #include "dst_parse.h" #include "dst_gost.h" #include #include #include #include static ENGINE *e = NULL; static const EVP_MD *opensslgost_digest; extern const EVP_MD *EVP_gost(void); const EVP_MD *EVP_gost(void) { return (opensslgost_digest); } /* ISC methods */ isc_result_t isc_gost_init(isc_gost_t *ctx) { const EVP_MD *md; int ret; INSIST(ctx != NULL); md = EVP_gost(); if (md == NULL) return (DST_R_CRYPTOFAILURE); EVP_MD_CTX_init(ctx); ret = EVP_DigestInit(ctx, md); if (ret != 1) return (DST_R_CRYPTOFAILURE); return (ISC_R_SUCCESS); } void isc_gost_invalidate(isc_gost_t *ctx) { EVP_MD_CTX_cleanup(ctx); } isc_result_t isc_gost_update(isc_gost_t *ctx, const unsigned char *data, unsigned int len) { int ret; INSIST(ctx != NULL); INSIST(data != NULL); ret = EVP_DigestUpdate(ctx, (const void *) data, (size_t) len); if (ret != 1) return (DST_R_CRYPTOFAILURE); return (ISC_R_SUCCESS); } isc_result_t isc_gost_final(isc_gost_t *ctx, unsigned char *digest) { int ret; INSIST(ctx != NULL); INSIST(digest != NULL); ret = EVP_DigestFinal(ctx, digest, NULL); if (ret != 1) return (DST_R_CRYPTOFAILURE); return (ISC_R_SUCCESS); } /* DST methods */ #define DST_RET(a) {ret = a; goto err;} static isc_result_t opensslgost_todns(const dst_key_t *key, isc_buffer_t *data); static isc_result_t opensslgost_createctx(dst_key_t *key, dst_context_t *dctx) { EVP_MD_CTX *evp_md_ctx; const EVP_MD *md = EVP_gost(); UNUSED(key); if (md == NULL) return (DST_R_OPENSSLFAILURE); evp_md_ctx = EVP_MD_CTX_create(); if (evp_md_ctx == NULL) return (ISC_R_NOMEMORY); if (!EVP_DigestInit_ex(evp_md_ctx, md, NULL)) { EVP_MD_CTX_destroy(evp_md_ctx); return (ISC_R_FAILURE); } dctx->ctxdata.evp_md_ctx = evp_md_ctx; return (ISC_R_SUCCESS); } static void opensslgost_destroyctx(dst_context_t *dctx) { EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; if (evp_md_ctx != NULL) { EVP_MD_CTX_destroy(evp_md_ctx); dctx->ctxdata.evp_md_ctx = NULL; } } static isc_result_t opensslgost_adddata(dst_context_t *dctx, const isc_region_t *data) { EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) return (ISC_R_FAILURE); return (ISC_R_SUCCESS); } static isc_result_t opensslgost_sign(dst_context_t *dctx, isc_buffer_t *sig) { dst_key_t *key = dctx->key; isc_region_t r; unsigned int siglen = 0; EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; EVP_PKEY *pkey = key->keydata.pkey; isc_buffer_availableregion(sig, &r); if (r.length < (unsigned int) EVP_PKEY_size(pkey)) return (ISC_R_NOSPACE); if (!EVP_SignFinal(evp_md_ctx, r.base, &siglen, pkey)) return (ISC_R_FAILURE); isc_buffer_add(sig, siglen); return (ISC_R_SUCCESS); } static isc_result_t opensslgost_verify(dst_context_t *dctx, const isc_region_t *sig) { dst_key_t *key = dctx->key; int status = 0; EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; EVP_PKEY *pkey = key->keydata.pkey; status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey); switch (status) { case 1: return (ISC_R_SUCCESS); case 0: return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); default: return (dst__openssl_toresult3(dctx->category, "EVP_VerifyFinal", DST_R_VERIFYFAILURE)); } } static isc_boolean_t opensslgost_compare(const dst_key_t *key1, const dst_key_t *key2) { EVP_PKEY *pkey1, *pkey2; pkey1 = key1->keydata.pkey; pkey2 = key2->keydata.pkey; if (pkey1 == NULL && pkey2 == NULL) return (ISC_TRUE); else if (pkey1 == NULL || pkey2 == NULL) return (ISC_FALSE); if (EVP_PKEY_cmp(pkey1, pkey2) != 1) return (ISC_FALSE); return (ISC_TRUE); } static int progress_cb(EVP_PKEY_CTX *ctx) { union { void *dptr; void (*fptr)(int); } u; int p; u.dptr = EVP_PKEY_CTX_get_app_data(ctx); p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); if (u.fptr != NULL) u.fptr(p); return (1); } static isc_result_t opensslgost_generate(dst_key_t *key, int unused, void (*callback)(int)) { EVP_PKEY_CTX *ctx; union { void *dptr; void (*fptr)(int); } u; EVP_PKEY *pkey = NULL; isc_result_t ret; UNUSED(unused); ctx = EVP_PKEY_CTX_new_id(NID_id_GostR3410_2001, NULL); if (ctx == NULL) DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_new_id", DST_R_OPENSSLFAILURE)); if (callback != NULL) { u.fptr = callback; EVP_PKEY_CTX_set_app_data(ctx, u.dptr); EVP_PKEY_CTX_set_cb(ctx, &progress_cb); } if (EVP_PKEY_keygen_init(ctx) <= 0) DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen_init", DST_R_OPENSSLFAILURE)); if (EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0) DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_ctrl_str", DST_R_OPENSSLFAILURE)); if (EVP_PKEY_keygen(ctx, &pkey) <= 0) DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen", DST_R_OPENSSLFAILURE)); key->keydata.pkey = pkey; key->key_size = EVP_PKEY_bits(pkey); EVP_PKEY_CTX_free(ctx); return (ISC_R_SUCCESS); err: if (pkey != NULL) EVP_PKEY_free(pkey); if (ctx != NULL) EVP_PKEY_CTX_free(ctx); return (ret); } static isc_boolean_t opensslgost_isprivate(const dst_key_t *key) { EVP_PKEY *pkey = key->keydata.pkey; EC_KEY *ec; INSIST(pkey != NULL); ec = EVP_PKEY_get0(pkey); return (ISC_TF(ec != NULL && EC_KEY_get0_private_key(ec) != NULL)); } static void opensslgost_destroy(dst_key_t *key) { EVP_PKEY *pkey = key->keydata.pkey; EVP_PKEY_free(pkey); key->keydata.pkey = NULL; } unsigned char gost_prefix[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 }; static isc_result_t opensslgost_todns(const dst_key_t *key, isc_buffer_t *data) { EVP_PKEY *pkey; isc_region_t r; unsigned char der[37 + 64], *p; int len; REQUIRE(key->keydata.pkey != NULL); pkey = key->keydata.pkey; isc_buffer_availableregion(data, &r); if (r.length < 64) return (ISC_R_NOSPACE); p = der; len = i2d_PUBKEY(pkey, &p); INSIST(len == sizeof(der)); INSIST(isc_safe_memequal(gost_prefix, der, 37)); memmove(r.base, der + 37, 64); isc_buffer_add(data, 64); return (ISC_R_SUCCESS); } static isc_result_t opensslgost_fromdns(dst_key_t *key, isc_buffer_t *data) { isc_region_t r; EVP_PKEY *pkey = NULL; unsigned char der[37 + 64]; const unsigned char *p; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); if (r.length != 64) return (DST_R_INVALIDPUBLICKEY); memmove(der, gost_prefix, 37); memmove(der + 37, r.base, 64); isc_buffer_forward(data, 64); p = der; if (d2i_PUBKEY(&pkey, &p, (long) sizeof(der)) == NULL) return (dst__openssl_toresult2("d2i_PUBKEY", DST_R_OPENSSLFAILURE)); key->keydata.pkey = pkey; key->key_size = EVP_PKEY_bits(pkey); return (ISC_R_SUCCESS); } #ifdef PREFER_GOSTASN1 static isc_result_t opensslgost_tofile(const dst_key_t *key, const char *directory) { EVP_PKEY *pkey; dst_private_t priv; isc_result_t result; unsigned char *der, *p; int len; if (key->keydata.pkey == NULL) return (DST_R_NULLKEY); if (key->external) { priv.nelements = 0; return (dst__privstruct_writefile(key, &priv, directory)); } pkey = key->keydata.pkey; len = i2d_PrivateKey(pkey, NULL); der = isc_mem_get(key->mctx, (size_t) len); if (der == NULL) return (ISC_R_NOMEMORY); p = der; if (i2d_PrivateKey(pkey, &p) != len) { result = dst__openssl_toresult2("i2d_PrivateKey", DST_R_OPENSSLFAILURE); goto fail; } priv.elements[0].tag = TAG_GOST_PRIVASN1; priv.elements[0].length = len; priv.elements[0].data = der; priv.nelements = 1; result = dst__privstruct_writefile(key, &priv, directory); fail: if (der != NULL) isc_mem_put(key->mctx, der, (size_t) len); return (result); } #else static isc_result_t opensslgost_tofile(const dst_key_t *key, const char *directory) { EVP_PKEY *pkey; EC_KEY *eckey; const BIGNUM *privkey; dst_private_t priv; isc_result_t ret; unsigned char *buf = NULL; if (key->keydata.pkey == NULL) return (DST_R_NULLKEY); if (key->external) { priv.nelements = 0; return (dst__privstruct_writefile(key, &priv, directory)); } pkey = key->keydata.pkey; eckey = EVP_PKEY_get0(pkey); if (eckey == NULL) return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); privkey = EC_KEY_get0_private_key(eckey); if (privkey == NULL) return (ISC_R_FAILURE); buf = isc_mem_get(key->mctx, BN_num_bytes(privkey)); if (buf == NULL) return (ISC_R_NOMEMORY); priv.elements[0].tag = TAG_GOST_PRIVRAW; priv.elements[0].length = BN_num_bytes(privkey); BN_bn2bin(privkey, buf); priv.elements[0].data = buf; priv.nelements = 1; ret = dst__privstruct_writefile(key, &priv, directory); if (buf != NULL) isc_mem_put(key->mctx, buf, BN_num_bytes(privkey)); return (ret); } #endif static unsigned char gost_dummy_key[71] = { 0x30, 0x45, 0x02, 0x01, 0x00, 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, 0x04, 0x22, 0x02, 0x20, 0x1b, 0x3f, 0x94, 0xf7, 0x1a, 0x5f, 0x2f, 0xe7, 0xe5, 0x74, 0x0b, 0x8c, 0xd4, 0xb7, 0x18, 0xdd, 0x65, 0x68, 0x26, 0xd1, 0x54, 0xfb, 0x77, 0xba, 0x63, 0x72, 0xd9, 0xf0, 0x63, 0x87, 0xe0, 0xd6 }; static isc_result_t opensslgost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t ret; isc_mem_t *mctx = key->mctx; EVP_PKEY *pkey = NULL; EC_KEY *eckey; const EC_POINT *pubkey = NULL; BIGNUM *privkey = NULL; const unsigned char *p; /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_ECCGOST, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) return (ret); if (key->external) { if (priv.nelements != 0) DST_RET(DST_R_INVALIDPRIVATEKEY); if (pub == NULL) DST_RET(DST_R_INVALIDPRIVATEKEY); key->keydata.pkey = pub->keydata.pkey; pub->keydata.pkey = NULL; key->key_size = pub->key_size; dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ISC_R_SUCCESS); } INSIST((priv.elements[0].tag == TAG_GOST_PRIVASN1) || (priv.elements[0].tag == TAG_GOST_PRIVRAW)); if (priv.elements[0].tag == TAG_GOST_PRIVASN1) { p = priv.elements[0].data; if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, (long) priv.elements[0].length) == NULL) DST_RET(dst__openssl_toresult2( "d2i_PrivateKey", DST_R_INVALIDPRIVATEKEY)); } else { if ((pub != NULL) && (pub->keydata.pkey != NULL)) { eckey = EVP_PKEY_get0(pub->keydata.pkey); pubkey = EC_KEY_get0_public_key(eckey); } privkey = BN_bin2bn(priv.elements[0].data, priv.elements[0].length, NULL); if (privkey == NULL) DST_RET(ISC_R_NOMEMORY); /* can't create directly the whole key */ p = gost_dummy_key; if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, (long) sizeof(gost_dummy_key)) == NULL) DST_RET(dst__openssl_toresult2( "d2i_PrivateKey", DST_R_INVALIDPRIVATEKEY)); eckey = EVP_PKEY_get0(pkey); if (eckey == NULL) return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); if (!EC_KEY_set_private_key(eckey, privkey)) DST_RET(ISC_R_NOMEMORY); /* have to (re)set the public key */ #ifdef notyet (void) gost2001_compute_public(eckey); #else if ((pubkey != NULL) && !EC_KEY_set_public_key(eckey, pubkey)) DST_RET(ISC_R_NOMEMORY); #endif BN_clear_free(privkey); privkey = NULL; } key->keydata.pkey = pkey; key->key_size = EVP_PKEY_bits(pkey); dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ISC_R_SUCCESS); err: if (privkey != NULL) BN_clear_free(privkey); if (pkey != NULL) EVP_PKEY_free(pkey); opensslgost_destroy(key); dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ret); } static void opensslgost_cleanup(void) { if (e != NULL) { ENGINE_finish(e); ENGINE_free(e); e = NULL; } } static dst_func_t opensslgost_functions = { opensslgost_createctx, NULL, /*%< createctx2 */ opensslgost_destroyctx, opensslgost_adddata, opensslgost_sign, opensslgost_verify, NULL, /*%< verify2 */ NULL, /*%< computesecret */ opensslgost_compare, NULL, /*%< paramcompare */ opensslgost_generate, opensslgost_isprivate, opensslgost_destroy, opensslgost_todns, opensslgost_fromdns, opensslgost_tofile, opensslgost_parse, opensslgost_cleanup, NULL, /*%< fromlabel */ NULL, /*%< dump */ NULL /*%< restore */ }; isc_result_t dst__opensslgost_init(dst_func_t **funcp) { isc_result_t ret; REQUIRE(funcp != NULL); /* check if the gost engine works properly */ e = ENGINE_by_id("gost"); if (e == NULL) return (dst__openssl_toresult2("ENGINE_by_id", DST_R_OPENSSLFAILURE)); if (ENGINE_init(e) <= 0) { ENGINE_free(e); e = NULL; return (dst__openssl_toresult2("ENGINE_init", DST_R_OPENSSLFAILURE)); } /* better than to rely on digest_gost symbol */ opensslgost_digest = ENGINE_get_digest(e, NID_id_GostR3411_94); if (opensslgost_digest == NULL) DST_RET(dst__openssl_toresult2("ENGINE_get_digest", DST_R_OPENSSLFAILURE)); /* from openssl.cnf */ if (ENGINE_register_pkey_asn1_meths(e) <= 0) DST_RET(dst__openssl_toresult2( "ENGINE_register_pkey_asn1_meths", DST_R_OPENSSLFAILURE)); if (ENGINE_ctrl_cmd_string(e, "CRYPT_PARAMS", "id-Gost28147-89-CryptoPro-A-ParamSet", 0) <= 0) DST_RET(dst__openssl_toresult2("ENGINE_ctrl_cmd_string", DST_R_OPENSSLFAILURE)); if (*funcp == NULL) *funcp = &opensslgost_functions; return (ISC_R_SUCCESS); err: ENGINE_finish(e); ENGINE_free(e); e = NULL; return (ret); } #else /* HAVE_OPENSSL_GOST */ #include EMPTY_TRANSLATION_UNIT #endif /* HAVE_OPENSSL_GOST */ /*! \file */ bind9-9.10.3.dfsg.P4/lib/dns/rdatasetiter.c0000644000470500017500000000411312664710322017561 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rdatasetiter.c,v 1.16 2007/06/19 23:47:16 tbox Exp $ */ /*! \file */ #include #include #include #include #include void dns_rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) { /* * Destroy '*iteratorp'. */ REQUIRE(iteratorp != NULL); REQUIRE(DNS_RDATASETITER_VALID(*iteratorp)); (*iteratorp)->methods->destroy(iteratorp); ENSURE(*iteratorp == NULL); } isc_result_t dns_rdatasetiter_first(dns_rdatasetiter_t *iterator) { /* * Move the rdataset cursor to the first rdataset at the node (if any). */ REQUIRE(DNS_RDATASETITER_VALID(iterator)); return (iterator->methods->first(iterator)); } isc_result_t dns_rdatasetiter_next(dns_rdatasetiter_t *iterator) { /* * Move the rdataset cursor to the next rdataset at the node (if any). */ REQUIRE(DNS_RDATASETITER_VALID(iterator)); return (iterator->methods->next(iterator)); } void dns_rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) { /* * Return the current rdataset. */ REQUIRE(DNS_RDATASETITER_VALID(iterator)); REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(! dns_rdataset_isassociated(rdataset)); iterator->methods->current(iterator, rdataset); } bind9-9.10.3.dfsg.P4/lib/dns/nsec.c0000644000470500017500000003005012664710322016015 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007-2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define RETERR(x) do { \ result = (x); \ if (result != ISC_R_SUCCESS) \ goto failure; \ } while (0) void dns_nsec_setbit(unsigned char *array, unsigned int type, unsigned int bit) { unsigned int shift, mask; shift = 7 - (type % 8); mask = 1 << shift; if (bit != 0) array[type / 8] |= mask; else array[type / 8] &= (~mask & 0xFF); } isc_boolean_t dns_nsec_isset(const unsigned char *array, unsigned int type) { unsigned int byte, shift, mask; byte = array[type / 8]; shift = 7 - (type % 8); mask = 1 << shift; return (ISC_TF(byte & mask)); } unsigned int dns_nsec_compressbitmap(unsigned char *map, const unsigned char *raw, unsigned int max_type) { unsigned char *start = map; unsigned int window; int octet; if (raw == NULL) return (0); for (window = 0; window < 256; window++) { if (window * 256 > max_type) break; for (octet = 31; octet >= 0; octet--) if (*(raw + octet) != 0) break; if (octet < 0) { raw += 32; continue; } *map++ = window; *map++ = octet + 1; /* * Note: potential overlapping move. */ memmove(map, raw, octet + 1); map += octet + 1; raw += 32; } return (unsigned int)(map - start); } isc_result_t dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, dns_name_t *target, unsigned char *buffer, dns_rdata_t *rdata) { isc_result_t result; dns_rdataset_t rdataset; isc_region_t r; unsigned int i; unsigned char *nsec_bits, *bm; unsigned int max_type; dns_rdatasetiter_t *rdsiter; memset(buffer, 0, DNS_NSEC_BUFFERSIZE); dns_name_toregion(target, &r); memmove(buffer, r.base, r.length); r.base = buffer; /* * Use the end of the space for a raw bitmap leaving enough * space for the window identifiers and length octets. */ bm = r.base + r.length + 512; nsec_bits = r.base + r.length; dns_nsec_setbit(bm, dns_rdatatype_rrsig, 1); dns_nsec_setbit(bm, dns_rdatatype_nsec, 1); max_type = dns_rdatatype_nsec; dns_rdataset_init(&rdataset); rdsiter = NULL; result = dns_db_allrdatasets(db, node, version, 0, &rdsiter); if (result != ISC_R_SUCCESS) return (result); for (result = dns_rdatasetiter_first(rdsiter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsiter)) { dns_rdatasetiter_current(rdsiter, &rdataset); if (rdataset.type != dns_rdatatype_nsec && rdataset.type != dns_rdatatype_nsec3 && rdataset.type != dns_rdatatype_rrsig) { if (rdataset.type > max_type) max_type = rdataset.type; dns_nsec_setbit(bm, rdataset.type, 1); } dns_rdataset_disassociate(&rdataset); } /* * At zone cuts, deny the existence of glue in the parent zone. */ if (dns_nsec_isset(bm, dns_rdatatype_ns) && ! dns_nsec_isset(bm, dns_rdatatype_soa)) { for (i = 0; i <= max_type; i++) { if (dns_nsec_isset(bm, i) && ! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i)) dns_nsec_setbit(bm, i, 0); } } dns_rdatasetiter_destroy(&rdsiter); if (result != ISC_R_NOMORE) return (result); nsec_bits += dns_nsec_compressbitmap(nsec_bits, bm, max_type); r.length = (unsigned int)(nsec_bits - r.base); INSIST(r.length <= DNS_NSEC_BUFFERSIZE); dns_rdata_fromregion(rdata, dns_db_class(db), dns_rdatatype_nsec, &r); return (ISC_R_SUCCESS); } isc_result_t dns_nsec_build(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, dns_name_t *target, dns_ttl_t ttl) { isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; unsigned char data[DNS_NSEC_BUFFERSIZE]; dns_rdatalist_t rdatalist; dns_rdataset_t rdataset; dns_rdataset_init(&rdataset); dns_rdata_init(&rdata); RETERR(dns_nsec_buildrdata(db, version, node, target, data, &rdata)); dns_rdatalist_init(&rdatalist); rdatalist.rdclass = dns_db_class(db); rdatalist.type = dns_rdatatype_nsec; rdatalist.ttl = ttl; ISC_LIST_APPEND(rdatalist.rdata, &rdata, link); RETERR(dns_rdatalist_tordataset(&rdatalist, &rdataset)); result = dns_db_addrdataset(db, node, version, 0, &rdataset, 0, NULL); if (result == DNS_R_UNCHANGED) result = ISC_R_SUCCESS; failure: if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); return (result); } isc_boolean_t dns_nsec_typepresent(dns_rdata_t *nsec, dns_rdatatype_t type) { dns_rdata_nsec_t nsecstruct; isc_result_t result; isc_boolean_t present; unsigned int i, len, window; REQUIRE(nsec != NULL); REQUIRE(nsec->type == dns_rdatatype_nsec); /* This should never fail */ result = dns_rdata_tostruct(nsec, &nsecstruct, NULL); INSIST(result == ISC_R_SUCCESS); present = ISC_FALSE; for (i = 0; i < nsecstruct.len; i += len) { INSIST(i + 2 <= nsecstruct.len); window = nsecstruct.typebits[i]; len = nsecstruct.typebits[i + 1]; INSIST(len > 0 && len <= 32); i += 2; INSIST(i + len <= nsecstruct.len); if (window * 256 > type) break; if ((window + 1) * 256 <= type) continue; if (type < (window * 256) + len * 8) present = ISC_TF(dns_nsec_isset(&nsecstruct.typebits[i], type % 256)); break; } dns_rdata_freestruct(&nsecstruct); return (present); } isc_result_t dns_nsec_nseconly(dns_db_t *db, dns_dbversion_t *version, isc_boolean_t *answer) { dns_dbnode_t *node = NULL; dns_rdataset_t rdataset; dns_rdata_dnskey_t dnskey; isc_result_t result; REQUIRE(answer != NULL); dns_rdataset_init(&rdataset); result = dns_db_getoriginnode(db, &node); if (result != ISC_R_SUCCESS) return (result); result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, 0, 0, &rdataset, NULL); dns_db_detachnode(db, &node); if (result == ISC_R_NOTFOUND) *answer = ISC_FALSE; if (result != ISC_R_SUCCESS) return (result); for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &dnskey, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (dnskey.algorithm == DST_ALG_RSAMD5 || dnskey.algorithm == DST_ALG_RSASHA1 || dnskey.algorithm == DST_ALG_DSA || dnskey.algorithm == DST_ALG_ECC) break; } dns_rdataset_disassociate(&rdataset); if (result == ISC_R_SUCCESS) *answer = ISC_TRUE; if (result == ISC_R_NOMORE) { *answer = ISC_FALSE; result = ISC_R_SUCCESS; } return (result); } /*% * Return ISC_R_SUCCESS if we can determine that the name doesn't exist * or we can determine whether there is data or not at the name. * If the name does not exist return the wildcard name. * * Return ISC_R_IGNORE when the NSEC is not the appropriate one. */ isc_result_t dns_nsec_noexistnodata(dns_rdatatype_t type, dns_name_t *name, dns_name_t *nsecname, dns_rdataset_t *nsecset, isc_boolean_t *exists, isc_boolean_t *data, dns_name_t *wild, dns_nseclog_t logit, void *arg) { int order; dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; dns_namereln_t relation; unsigned int olabels, nlabels, labels; dns_rdata_nsec_t nsec; isc_boolean_t atparent; isc_boolean_t ns; isc_boolean_t soa; REQUIRE(exists != NULL); REQUIRE(data != NULL); REQUIRE(nsecset != NULL && nsecset->type == dns_rdatatype_nsec); result = dns_rdataset_first(nsecset); if (result != ISC_R_SUCCESS) { (*logit)(arg, ISC_LOG_DEBUG(3), "failure processing NSEC set"); return (result); } dns_rdataset_current(nsecset, &rdata); (*logit)(arg, ISC_LOG_DEBUG(3), "looking for relevant NSEC"); relation = dns_name_fullcompare(name, nsecname, &order, &olabels); if (order < 0) { /* * The name is not within the NSEC range. */ (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC does not cover name, before NSEC"); return (ISC_R_IGNORE); } if (order == 0) { /* * The names are the same. If we are validating "." * then atparent should not be set as there is no parent. */ atparent = (olabels != 1) && dns_rdatatype_atparent(type); ns = dns_nsec_typepresent(&rdata, dns_rdatatype_ns); soa = dns_nsec_typepresent(&rdata, dns_rdatatype_soa); if (ns && !soa) { if (!atparent) { /* * This NSEC record is from somewhere higher in * the DNS, and at the parent of a delegation. * It can not be legitimately used here. */ (*logit)(arg, ISC_LOG_DEBUG(3), "ignoring parent nsec"); return (ISC_R_IGNORE); } } else if (atparent && ns && soa) { /* * This NSEC record is from the child. * It can not be legitimately used here. */ (*logit)(arg, ISC_LOG_DEBUG(3), "ignoring child nsec"); return (ISC_R_IGNORE); } if (type == dns_rdatatype_cname || type == dns_rdatatype_nxt || type == dns_rdatatype_nsec || type == dns_rdatatype_key || !dns_nsec_typepresent(&rdata, dns_rdatatype_cname)) { *exists = ISC_TRUE; *data = dns_nsec_typepresent(&rdata, type); (*logit)(arg, ISC_LOG_DEBUG(3), "nsec proves name exists (owner) data=%d", *data); return (ISC_R_SUCCESS); } (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC proves CNAME exists"); return (ISC_R_IGNORE); } if (relation == dns_namereln_subdomain && dns_nsec_typepresent(&rdata, dns_rdatatype_ns) && !dns_nsec_typepresent(&rdata, dns_rdatatype_soa)) { /* * This NSEC record is from somewhere higher in * the DNS, and at the parent of a delegation. * It can not be legitimately used here. */ (*logit)(arg, ISC_LOG_DEBUG(3), "ignoring parent nsec"); return (ISC_R_IGNORE); } result = dns_rdata_tostruct(&rdata, &nsec, NULL); if (result != ISC_R_SUCCESS) return (result); relation = dns_name_fullcompare(&nsec.next, name, &order, &nlabels); if (order == 0) { dns_rdata_freestruct(&nsec); (*logit)(arg, ISC_LOG_DEBUG(3), "ignoring nsec matches next name"); return (ISC_R_IGNORE); } if (order < 0 && !dns_name_issubdomain(nsecname, &nsec.next)) { /* * The name is not within the NSEC range. */ dns_rdata_freestruct(&nsec); (*logit)(arg, ISC_LOG_DEBUG(3), "ignoring nsec because name is past end of range"); return (ISC_R_IGNORE); } if (order > 0 && relation == dns_namereln_subdomain) { (*logit)(arg, ISC_LOG_DEBUG(3), "nsec proves name exist (empty)"); dns_rdata_freestruct(&nsec); *exists = ISC_TRUE; *data = ISC_FALSE; return (ISC_R_SUCCESS); } if (wild != NULL) { dns_name_t common; dns_name_init(&common, NULL); if (olabels > nlabels) { labels = dns_name_countlabels(nsecname); dns_name_getlabelsequence(nsecname, labels - olabels, olabels, &common); } else { labels = dns_name_countlabels(&nsec.next); dns_name_getlabelsequence(&nsec.next, labels - nlabels, nlabels, &common); } result = dns_name_concatenate(dns_wildcardname, &common, wild, NULL); if (result != ISC_R_SUCCESS) { dns_rdata_freestruct(&nsec); (*logit)(arg, ISC_LOG_DEBUG(3), "failure generating wildcard name"); return (result); } } dns_rdata_freestruct(&nsec); (*logit)(arg, ISC_LOG_DEBUG(3), "nsec range ok"); *exists = ISC_FALSE; return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/dns/lib.c0000644000470500017500000000712312664710322015640 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lib.c,v 1.19 2009/09/03 00:12:23 each Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include /*** *** Globals ***/ LIBDNS_EXTERNAL_DATA unsigned int dns_pps = 0U; LIBDNS_EXTERNAL_DATA isc_msgcat_t * dns_msgcat = NULL; /*** *** Private ***/ static isc_once_t msgcat_once = ISC_ONCE_INIT; /*** *** Functions ***/ static void open_msgcat(void) { isc_msgcat_open("libdns.cat", &dns_msgcat); } void dns_lib_initmsgcat(void) { /* * Initialize the DNS library's message catalog, dns_msgcat, if it * has not already been initialized. */ RUNTIME_CHECK(isc_once_do(&msgcat_once, open_msgcat) == ISC_R_SUCCESS); } static isc_once_t init_once = ISC_ONCE_INIT; static isc_mem_t *dns_g_mctx = NULL; static dns_dbimplementation_t *dbimp = NULL; static isc_boolean_t initialize_done = ISC_FALSE; static isc_mutex_t reflock; static unsigned int references = 0; static void initialize(void) { isc_result_t result; REQUIRE(initialize_done == ISC_FALSE); result = isc_mem_create(0, 0, &dns_g_mctx); if (result != ISC_R_SUCCESS) return; dns_result_register(); result = dns_ecdb_register(dns_g_mctx, &dbimp); if (result != ISC_R_SUCCESS) goto cleanup_mctx; result = isc_hash_create(dns_g_mctx, NULL, DNS_NAME_MAXWIRE); if (result != ISC_R_SUCCESS) goto cleanup_db; result = dst_lib_init(dns_g_mctx, NULL, 0); if (result != ISC_R_SUCCESS) goto cleanup_hash; result = isc_mutex_init(&reflock); if (result != ISC_R_SUCCESS) goto cleanup_dst; initialize_done = ISC_TRUE; return; cleanup_dst: dst_lib_destroy(); cleanup_hash: isc_hash_destroy(); cleanup_db: if (dbimp != NULL) dns_ecdb_unregister(&dbimp); cleanup_mctx: if (dns_g_mctx != NULL) isc_mem_detach(&dns_g_mctx); } isc_result_t dns_lib_init(void) { isc_result_t result; /* * Since this routine is expected to be used by a normal application, * it should be better to return an error, instead of an emergency * abort, on any failure. */ result = isc_once_do(&init_once, initialize); if (result != ISC_R_SUCCESS) return (result); if (!initialize_done) return (ISC_R_FAILURE); LOCK(&reflock); references++; UNLOCK(&reflock); return (ISC_R_SUCCESS); } void dns_lib_shutdown(void) { isc_boolean_t cleanup_ok = ISC_FALSE; LOCK(&reflock); if (--references == 0) cleanup_ok = ISC_TRUE; UNLOCK(&reflock); if (!cleanup_ok) return; dst_lib_destroy(); isc_hash_destroy(); if (dbimp != NULL) dns_ecdb_unregister(&dbimp); if (dns_g_mctx != NULL) isc_mem_detach(&dns_g_mctx); } bind9-9.10.3.dfsg.P4/lib/dns/tcpmsg.c0000644000470500017500000001346512664710322016375 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: tcpmsg.c,v 1.31 2007/06/19 23:47:16 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #ifdef TCPMSG_DEBUG #include /* Required for printf. */ #define XDEBUG(x) printf x #else #define XDEBUG(x) #endif #define TCPMSG_MAGIC ISC_MAGIC('T', 'C', 'P', 'm') #define VALID_TCPMSG(foo) ISC_MAGIC_VALID(foo, TCPMSG_MAGIC) static void recv_length(isc_task_t *, isc_event_t *); static void recv_message(isc_task_t *, isc_event_t *); static void recv_length(isc_task_t *task, isc_event_t *ev_in) { isc_socketevent_t *ev = (isc_socketevent_t *)ev_in; isc_event_t *dev; dns_tcpmsg_t *tcpmsg = ev_in->ev_arg; isc_region_t region; isc_result_t result; INSIST(VALID_TCPMSG(tcpmsg)); dev = &tcpmsg->event; tcpmsg->address = ev->address; if (ev->result != ISC_R_SUCCESS) { tcpmsg->result = ev->result; goto send_and_free; } /* * Success. */ tcpmsg->size = ntohs(tcpmsg->size); if (tcpmsg->size == 0) { tcpmsg->result = ISC_R_UNEXPECTEDEND; goto send_and_free; } if (tcpmsg->size > tcpmsg->maxsize) { tcpmsg->result = ISC_R_RANGE; goto send_and_free; } region.base = isc_mem_get(tcpmsg->mctx, tcpmsg->size); region.length = tcpmsg->size; if (region.base == NULL) { tcpmsg->result = ISC_R_NOMEMORY; goto send_and_free; } XDEBUG(("Allocated %d bytes\n", tcpmsg->size)); isc_buffer_init(&tcpmsg->buffer, region.base, region.length); result = isc_socket_recv(tcpmsg->sock, ®ion, 0, task, recv_message, tcpmsg); if (result != ISC_R_SUCCESS) { tcpmsg->result = result; goto send_and_free; } isc_event_free(&ev_in); return; send_and_free: isc_task_send(tcpmsg->task, &dev); tcpmsg->task = NULL; isc_event_free(&ev_in); return; } static void recv_message(isc_task_t *task, isc_event_t *ev_in) { isc_socketevent_t *ev = (isc_socketevent_t *)ev_in; isc_event_t *dev; dns_tcpmsg_t *tcpmsg = ev_in->ev_arg; (void)task; INSIST(VALID_TCPMSG(tcpmsg)); dev = &tcpmsg->event; tcpmsg->address = ev->address; if (ev->result != ISC_R_SUCCESS) { tcpmsg->result = ev->result; goto send_and_free; } tcpmsg->result = ISC_R_SUCCESS; isc_buffer_add(&tcpmsg->buffer, ev->n); XDEBUG(("Received %d bytes (of %d)\n", ev->n, tcpmsg->size)); send_and_free: isc_task_send(tcpmsg->task, &dev); tcpmsg->task = NULL; isc_event_free(&ev_in); } void dns_tcpmsg_init(isc_mem_t *mctx, isc_socket_t *sock, dns_tcpmsg_t *tcpmsg) { REQUIRE(mctx != NULL); REQUIRE(sock != NULL); REQUIRE(tcpmsg != NULL); tcpmsg->magic = TCPMSG_MAGIC; tcpmsg->size = 0; tcpmsg->buffer.base = NULL; tcpmsg->buffer.length = 0; tcpmsg->maxsize = 65535; /* Largest message possible. */ tcpmsg->mctx = mctx; tcpmsg->sock = sock; tcpmsg->task = NULL; /* None yet. */ tcpmsg->result = ISC_R_UNEXPECTED; /* None yet. */ /* * Should probably initialize the event here, but it can wait. */ } void dns_tcpmsg_setmaxsize(dns_tcpmsg_t *tcpmsg, unsigned int maxsize) { REQUIRE(VALID_TCPMSG(tcpmsg)); REQUIRE(maxsize < 65536); tcpmsg->maxsize = maxsize; } isc_result_t dns_tcpmsg_readmessage(dns_tcpmsg_t *tcpmsg, isc_task_t *task, isc_taskaction_t action, void *arg) { isc_result_t result; isc_region_t region; REQUIRE(VALID_TCPMSG(tcpmsg)); REQUIRE(task != NULL); REQUIRE(tcpmsg->task == NULL); /* not currently in use */ if (tcpmsg->buffer.base != NULL) { isc_mem_put(tcpmsg->mctx, tcpmsg->buffer.base, tcpmsg->buffer.length); tcpmsg->buffer.base = NULL; tcpmsg->buffer.length = 0; } tcpmsg->task = task; tcpmsg->action = action; tcpmsg->arg = arg; tcpmsg->result = ISC_R_UNEXPECTED; /* unknown right now */ ISC_EVENT_INIT(&tcpmsg->event, sizeof(isc_event_t), 0, 0, DNS_EVENT_TCPMSG, action, arg, tcpmsg, NULL, NULL); region.base = (unsigned char *)&tcpmsg->size; region.length = 2; /* isc_uint16_t */ result = isc_socket_recv(tcpmsg->sock, ®ion, 0, tcpmsg->task, recv_length, tcpmsg); if (result != ISC_R_SUCCESS) tcpmsg->task = NULL; return (result); } void dns_tcpmsg_cancelread(dns_tcpmsg_t *tcpmsg) { REQUIRE(VALID_TCPMSG(tcpmsg)); isc_socket_cancel(tcpmsg->sock, NULL, ISC_SOCKCANCEL_RECV); } void dns_tcpmsg_keepbuffer(dns_tcpmsg_t *tcpmsg, isc_buffer_t *buffer) { REQUIRE(VALID_TCPMSG(tcpmsg)); REQUIRE(buffer != NULL); *buffer = tcpmsg->buffer; tcpmsg->buffer.base = NULL; tcpmsg->buffer.length = 0; } #if 0 void dns_tcpmsg_freebuffer(dns_tcpmsg_t *tcpmsg) { REQUIRE(VALID_TCPMSG(tcpmsg)); if (tcpmsg->buffer.base == NULL) return; isc_mem_put(tcpmsg->mctx, tcpmsg->buffer.base, tcpmsg->buffer.length); tcpmsg->buffer.base = NULL; tcpmsg->buffer.length = 0; } #endif void dns_tcpmsg_invalidate(dns_tcpmsg_t *tcpmsg) { REQUIRE(VALID_TCPMSG(tcpmsg)); tcpmsg->magic = 0; if (tcpmsg->buffer.base != NULL) { isc_mem_put(tcpmsg->mctx, tcpmsg->buffer.base, tcpmsg->buffer.length); tcpmsg->buffer.base = NULL; tcpmsg->buffer.length = 0; } } bind9-9.10.3.dfsg.P4/lib/dns/clientinfo.c0000644000470500017500000000237512664710322017230 0ustar lamontlamont/* * Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: clientinfo.c,v 1.3 2011/10/11 00:25:12 marka Exp $ */ /*! \file */ #include "config.h" #include void dns_clientinfomethods_init(dns_clientinfomethods_t *methods, dns_clientinfo_sourceip_t sourceip) { methods->version = DNS_CLIENTINFOMETHODS_VERSION; methods->age = DNS_CLIENTINFOMETHODS_AGE; methods->sourceip = sourceip; } void dns_clientinfo_init(dns_clientinfo_t *ci, void *data) { ci->version = DNS_CLIENTINFO_VERSION; ci->data = data; } bind9-9.10.3.dfsg.P4/lib/dns/ssu_external.c0000644000470500017500000001553012664710322017607 0ustar lamontlamont/* * Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* * This implements external update-policy rules. This allows permission * to update a zone to be checked by consulting an external daemon (e.g., * kerberos). */ #include #include #include #ifdef ISC_PLATFORM_HAVESYSUNH #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include static void ssu_e_log(int level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_SECURITY, DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(level), fmt, ap); va_end(ap); } /* * Connect to a UNIX domain socket. */ static int ux_socket_connect(const char *path) { int fd = -1; #ifdef ISC_PLATFORM_HAVESYSUNH struct sockaddr_un addr; REQUIRE(path != NULL); if (strlen(path) > sizeof(addr.sun_path)) { ssu_e_log(3, "ssu_external: socket path '%s' " "longer than system maximum %u", path, sizeof(addr.sun_path)); return (-1); } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strlcpy(addr.sun_path, path, sizeof(addr.sun_path)); fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd == -1) { char strbuf[ISC_STRERRORSIZE]; isc__strerror(errno, strbuf, sizeof(strbuf)); ssu_e_log(3, "ssu_external: unable to create socket - %s", strbuf); return (-1); } if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { char strbuf[ISC_STRERRORSIZE]; isc__strerror(errno, strbuf, sizeof(strbuf)); ssu_e_log(3, "ssu_external: unable to connect to " "socket '%s' - %s", path, strbuf); close(fd); return (-1); } #endif return (fd); } /* Change this version if you update the format of the request */ #define SSU_EXTERNAL_VERSION 1 /* * Perform an update-policy rule check against an external application * over a socket. * * This currently only supports local: for unix domain datagram sockets. * * Note that by using a datagram socket and creating a new socket each * time we avoid the need for locking and allow for parallel access to * the authorization server. */ isc_boolean_t dns_ssu_external_match(dns_name_t *identity, dns_name_t *signer, dns_name_t *name, isc_netaddr_t *tcpaddr, dns_rdatatype_t type, const dst_key_t *key, isc_mem_t *mctx) { char b_identity[DNS_NAME_FORMATSIZE]; char b_signer[DNS_NAME_FORMATSIZE]; char b_name[DNS_NAME_FORMATSIZE]; char b_addr[ISC_NETADDR_FORMATSIZE]; char b_type[DNS_RDATATYPE_FORMATSIZE]; char b_key[DST_KEY_FORMATSIZE]; isc_buffer_t *tkey_token = NULL; int fd; const char *sock_path; unsigned int req_len; isc_region_t token_region; unsigned char *data; isc_buffer_t buf; isc_uint32_t token_len = 0; isc_uint32_t reply; ssize_t ret; /* The identity contains local:/path/to/socket */ dns_name_format(identity, b_identity, sizeof(b_identity)); /* For now only local: is supported */ if (strncmp(b_identity, "local:", 6) != 0) { ssu_e_log(3, "ssu_external: invalid socket path '%s'", b_identity); return (ISC_FALSE); } sock_path = &b_identity[6]; fd = ux_socket_connect(sock_path); if (fd == -1) return (ISC_FALSE); if (key != NULL) { dst_key_format(key, b_key, sizeof(b_key)); tkey_token = dst_key_tkeytoken(key); } else b_key[0] = 0; if (tkey_token != NULL) { isc_buffer_region(tkey_token, &token_region); token_len = token_region.length; } /* Format the request elements */ if (signer != NULL) dns_name_format(signer, b_signer, sizeof(b_signer)); else b_signer[0] = 0; dns_name_format(name, b_name, sizeof(b_name)); if (tcpaddr != NULL) isc_netaddr_format(tcpaddr, b_addr, sizeof(b_addr)); else b_addr[0] = 0; dns_rdatatype_format(type, b_type, sizeof(b_type)); /* Work out how big the request will be */ req_len = sizeof(isc_uint32_t) + /* Format version */ sizeof(isc_uint32_t) + /* Length */ strlen(b_signer) + 1 + /* Signer */ strlen(b_name) + 1 + /* Name */ strlen(b_addr) + 1 + /* Address */ strlen(b_type) + 1 + /* Type */ strlen(b_key) + 1 + /* Key */ sizeof(isc_uint32_t) + /* tkey_token length */ token_len; /* tkey_token */ /* format the buffer */ data = isc_mem_allocate(mctx, req_len); if (data == NULL) { close(fd); return (ISC_FALSE); } isc_buffer_init(&buf, data, req_len); isc_buffer_putuint32(&buf, SSU_EXTERNAL_VERSION); isc_buffer_putuint32(&buf, req_len); /* Strings must be null-terminated */ isc_buffer_putstr(&buf, b_signer); isc_buffer_putuint8(&buf, 0); isc_buffer_putstr(&buf, b_name); isc_buffer_putuint8(&buf, 0); isc_buffer_putstr(&buf, b_addr); isc_buffer_putuint8(&buf, 0); isc_buffer_putstr(&buf, b_type); isc_buffer_putuint8(&buf, 0); isc_buffer_putstr(&buf, b_key); isc_buffer_putuint8(&buf, 0); isc_buffer_putuint32(&buf, token_len); if (tkey_token && token_len != 0) isc_buffer_putmem(&buf, token_region.base, token_len); ENSURE(isc_buffer_availablelength(&buf) == 0); /* Send the request */ ret = write(fd, data, req_len); isc_mem_free(mctx, data); if (ret != (ssize_t) req_len) { char strbuf[ISC_STRERRORSIZE]; isc__strerror(errno, strbuf, sizeof(strbuf)); ssu_e_log(3, "ssu_external: unable to send request - %s", strbuf); close(fd); return (ISC_FALSE); } /* Receive the reply */ ret = read(fd, &reply, sizeof(isc_uint32_t)); if (ret != (ssize_t) sizeof(isc_uint32_t)) { char strbuf[ISC_STRERRORSIZE]; isc__strerror(errno, strbuf, sizeof(strbuf)); ssu_e_log(3, "ssu_external: unable to receive reply - %s", strbuf); close(fd); return (ISC_FALSE); } close(fd); reply = ntohl(reply); if (reply == 0) { ssu_e_log(3, "ssu_external: denied external auth for '%s'", b_name); return (ISC_FALSE); } else if (reply == 1) { ssu_e_log(3, "ssu_external: allowed external auth for '%s'", b_name); return (ISC_TRUE); } ssu_e_log(3, "ssu_external: invalid reply 0x%08x", reply); return (ISC_FALSE); } bind9-9.10.3.dfsg.P4/lib/dns/rrl.c0000644000470500017500000010320512664710322015667 0ustar lamontlamont/* * Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ /* * Rate limit DNS responses. */ /* #define ISC_LIST_CHECKINIT */ #include #include #include #include #include #include #include #include #include #include #include #include static void log_end(dns_rrl_t *rrl, dns_rrl_entry_t *e, isc_boolean_t early, char *log_buf, unsigned int log_buf_len); /* * Get a modulus for a hash function that is tolerably likely to be * relatively prime to most inputs. Of course, we get a prime for for initial * values not larger than the square of the last prime. We often get a prime * after that. * This works well in practice for hash tables up to at least 100 * times the square of the last prime and better than a multiplicative hash. */ static int hash_divisor(unsigned int initial) { static isc_uint16_t primes[] = { 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, #if 0 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997,1009, #endif }; int divisions, tries; unsigned int result; isc_uint16_t *pp, p; result = initial; if (primes[sizeof(primes)/sizeof(primes[0])-1] >= result) { pp = primes; while (*pp < result) ++pp; return (*pp); } if ((result & 1) == 0) ++result; divisions = 0; tries = 1; pp = primes; do { p = *pp++; ++divisions; if ((result % p) == 0) { ++tries; result += 2; pp = primes; } } while (pp < &primes[sizeof(primes) / sizeof(primes[0])]); if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DEBUG3)) isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DEBUG3, "%d hash_divisor() divisions in %d tries" " to get %d from %d", divisions, tries, result, initial); return (result); } /* * Convert a timestamp to a number of seconds in the past. */ static inline int delta_rrl_time(isc_stdtime_t ts, isc_stdtime_t now) { int delta; delta = now - ts; if (delta >= 0) return (delta); /* * The timestamp is in the future. That future might result from * re-ordered requests, because we use timestamps on requests * instead of consulting a clock. Timestamps in the distant future are * assumed to result from clock changes. When the clock changes to * the past, make existing timestamps appear to be in the past. */ if (delta < -DNS_RRL_MAX_TIME_TRAVEL) return (DNS_RRL_FOREVER); return (0); } static inline int get_age(const dns_rrl_t *rrl, const dns_rrl_entry_t *e, isc_stdtime_t now) { if (!e->ts_valid) return (DNS_RRL_FOREVER); return (delta_rrl_time(e->ts + rrl->ts_bases[e->ts_gen], now)); } static inline void set_age(dns_rrl_t *rrl, dns_rrl_entry_t *e, isc_stdtime_t now) { dns_rrl_entry_t *e_old; unsigned int ts_gen; int i, ts; ts_gen = rrl->ts_gen; ts = now - rrl->ts_bases[ts_gen]; if (ts < 0) { if (ts < -DNS_RRL_MAX_TIME_TRAVEL) ts = DNS_RRL_FOREVER; else ts = 0; } /* * Make a new timestamp base if the current base is too old. * All entries older than DNS_RRL_MAX_WINDOW seconds are ancient, * useless history. Their timestamps can be treated as if they are * all the same. * We only do arithmetic on more recent timestamps, so bases for * older timestamps can be recycled provided the old timestamps are * marked as ancient history. * This loop is almost always very short because most entries are * recycled after one second and any entries that need to be marked * are older than (DNS_RRL_TS_BASES)*DNS_RRL_MAX_TS seconds. */ if (ts >= DNS_RRL_MAX_TS) { ts_gen = (ts_gen + 1) % DNS_RRL_TS_BASES; for (e_old = ISC_LIST_TAIL(rrl->lru), i = 0; e_old != NULL && (e_old->ts_gen == ts_gen || !ISC_LINK_LINKED(e_old, hlink)); e_old = ISC_LIST_PREV(e_old, lru), ++i) { e_old->ts_valid = ISC_FALSE; } if (i != 0) isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DEBUG1, "rrl new time base scanned %d entries" " at %d for %d %d %d %d", i, now, rrl->ts_bases[ts_gen], rrl->ts_bases[(ts_gen + 1) % DNS_RRL_TS_BASES], rrl->ts_bases[(ts_gen + 2) % DNS_RRL_TS_BASES], rrl->ts_bases[(ts_gen + 3) % DNS_RRL_TS_BASES]); rrl->ts_gen = ts_gen; rrl->ts_bases[ts_gen] = now; ts = 0; } e->ts_gen = ts_gen; e->ts = ts; e->ts_valid = ISC_TRUE; } static isc_result_t expand_entries(dns_rrl_t *rrl, int new) { unsigned int bsize; dns_rrl_block_t *b; dns_rrl_entry_t *e; double rate; int i; if (rrl->num_entries + new >= rrl->max_entries && rrl->max_entries != 0) { new = rrl->max_entries - rrl->num_entries; if (new <= 0) return (ISC_R_SUCCESS); } /* * Log expansions so that the user can tune max-table-size * and min-table-size. */ if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DROP) && rrl->hash != NULL) { rate = rrl->probes; if (rrl->searches != 0) rate /= rrl->searches; isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DROP, "increase from %d to %d RRL entries with" " %d bins; average search length %.1f", rrl->num_entries, rrl->num_entries+new, rrl->hash->length, rate); } bsize = sizeof(dns_rrl_block_t) + (new-1)*sizeof(dns_rrl_entry_t); b = isc_mem_get(rrl->mctx, bsize); if (b == NULL) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_FAIL, "isc_mem_get(%d) failed for RRL entries", bsize); return (ISC_R_NOMEMORY); } memset(b, 0, bsize); b->size = bsize; e = b->entries; for (i = 0; i < new; ++i, ++e) { ISC_LINK_INIT(e, hlink); ISC_LIST_INITANDAPPEND(rrl->lru, e, lru); } rrl->num_entries += new; ISC_LIST_INITANDAPPEND(rrl->blocks, b, link); return (ISC_R_SUCCESS); } static inline dns_rrl_bin_t * get_bin(dns_rrl_hash_t *hash, unsigned int hval) { INSIST(hash != NULL); return (&hash->bins[hval % hash->length]); } static void free_old_hash(dns_rrl_t *rrl) { dns_rrl_hash_t *old_hash; dns_rrl_bin_t *old_bin; dns_rrl_entry_t *e, *e_next; old_hash = rrl->old_hash; for (old_bin = &old_hash->bins[0]; old_bin < &old_hash->bins[old_hash->length]; ++old_bin) { for (e = ISC_LIST_HEAD(*old_bin); e != NULL; e = e_next) { e_next = ISC_LIST_NEXT(e, hlink); ISC_LINK_INIT(e, hlink); } } isc_mem_put(rrl->mctx, old_hash, sizeof(*old_hash) + (old_hash->length - 1) * sizeof(old_hash->bins[0])); rrl->old_hash = NULL; } static isc_result_t expand_rrl_hash(dns_rrl_t *rrl, isc_stdtime_t now) { dns_rrl_hash_t *hash; int old_bins, new_bins, hsize; double rate; if (rrl->old_hash != NULL) free_old_hash(rrl); /* * Most searches fail and so go to the end of the chain. * Use a small hash table load factor. */ old_bins = (rrl->hash == NULL) ? 0 : rrl->hash->length; new_bins = old_bins/8 + old_bins; if (new_bins < rrl->num_entries) new_bins = rrl->num_entries; new_bins = hash_divisor(new_bins); hsize = sizeof(dns_rrl_hash_t) + (new_bins-1)*sizeof(hash->bins[0]); hash = isc_mem_get(rrl->mctx, hsize); if (hash == NULL) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_FAIL, "isc_mem_get(%d) failed for" " RRL hash table", hsize); return (ISC_R_NOMEMORY); } memset(hash, 0, hsize); hash->length = new_bins; rrl->hash_gen ^= 1; hash->gen = rrl->hash_gen; if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DROP) && old_bins != 0) { rate = rrl->probes; if (rrl->searches != 0) rate /= rrl->searches; isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DROP, "increase from %d to %d RRL bins for" " %d entries; average search length %.1f", old_bins, new_bins, rrl->num_entries, rate); } rrl->old_hash = rrl->hash; if (rrl->old_hash != NULL) rrl->old_hash->check_time = now; rrl->hash = hash; return (ISC_R_SUCCESS); } static void ref_entry(dns_rrl_t *rrl, dns_rrl_entry_t *e, int probes, isc_stdtime_t now) { /* * Make the entry most recently used. */ if (ISC_LIST_HEAD(rrl->lru) != e) { if (e == rrl->last_logged) rrl->last_logged = ISC_LIST_PREV(e, lru); ISC_LIST_UNLINK(rrl->lru, e, lru); ISC_LIST_PREPEND(rrl->lru, e, lru); } /* * Expand the hash table if it is time and necessary. * This will leave the newly referenced entry in a chain in the * old hash table. It will migrate to the new hash table the next * time it is used or be cut loose when the old hash table is destroyed. */ rrl->probes += probes; ++rrl->searches; if (rrl->searches > 100 && delta_rrl_time(rrl->hash->check_time, now) > 1) { if (rrl->probes/rrl->searches > 2) expand_rrl_hash(rrl, now); rrl->hash->check_time = now; rrl->probes = 0; rrl->searches = 0; } } static inline isc_boolean_t key_cmp(const dns_rrl_key_t *a, const dns_rrl_key_t *b) { if (memcmp(a, b, sizeof(dns_rrl_key_t)) == 0) return (ISC_TRUE); return (ISC_FALSE); } static inline isc_uint32_t hash_key(const dns_rrl_key_t *key) { isc_uint32_t hval; int i; hval = key->w[0]; for (i = sizeof(key->w) / sizeof(key->w[0]) - 1; i >= 0; --i) { hval = key->w[i] + (hval<<1); } return (hval); } /* * Construct the hash table key. * Use a hash of the DNS query name to save space in the database. * Collisions result in legitimate rate limiting responses for one * query name also limiting responses for other names to the * same client. This is rare and benign enough given the large * space costs compared to keeping the entire name in the database * entry or the time costs of dynamic allocation. */ static void make_key(const dns_rrl_t *rrl, dns_rrl_key_t *key, const isc_sockaddr_t *client_addr, dns_rdatatype_t qtype, dns_name_t *qname, dns_rdataclass_t qclass, dns_rrl_rtype_t rtype) { dns_name_t base; dns_offsets_t base_offsets; int labels, i; memset(key, 0, sizeof(*key)); key->s.rtype = rtype; if (rtype == DNS_RRL_RTYPE_QUERY) { key->s.qtype = qtype; key->s.qclass = qclass & 0xff; } else if (rtype == DNS_RRL_RTYPE_REFERRAL || rtype == DNS_RRL_RTYPE_NODATA) { /* * Because there is no qtype in the empty answer sections of * referral and NODATA responses, count them as the same. */ key->s.qclass = qclass & 0xff; } if (qname != NULL && qname->labels != 0) { /* * Ignore the first label of wildcards. */ if ((qname->attributes & DNS_NAMEATTR_WILDCARD) != 0 && (labels = dns_name_countlabels(qname)) > 1) { dns_name_init(&base, base_offsets); dns_name_getlabelsequence(qname, 1, labels-1, &base); key->s.qname_hash = dns_name_hashbylabel(&base, ISC_FALSE); } else { key->s.qname_hash = dns_name_hashbylabel(qname, ISC_FALSE); } } switch (client_addr->type.sa.sa_family) { case AF_INET: key->s.ip[0] = (client_addr->type.sin.sin_addr.s_addr & rrl->ipv4_mask); break; case AF_INET6: key->s.ipv6 = ISC_TRUE; memmove(key->s.ip, &client_addr->type.sin6.sin6_addr, sizeof(key->s.ip)); for (i = 0; i < DNS_RRL_MAX_PREFIX/32; ++i) key->s.ip[i] &= rrl->ipv6_mask[i]; break; } } static inline dns_rrl_rate_t * get_rate(dns_rrl_t *rrl, dns_rrl_rtype_t rtype) { switch (rtype) { case DNS_RRL_RTYPE_QUERY: return (&rrl->responses_per_second); case DNS_RRL_RTYPE_REFERRAL: return (&rrl->referrals_per_second); case DNS_RRL_RTYPE_NODATA: return (&rrl->nodata_per_second); case DNS_RRL_RTYPE_NXDOMAIN: return (&rrl->nxdomains_per_second); case DNS_RRL_RTYPE_ERROR: return (&rrl->errors_per_second); case DNS_RRL_RTYPE_ALL: return (&rrl->all_per_second); default: INSIST(0); } return (NULL); } static int response_balance(dns_rrl_t *rrl, const dns_rrl_entry_t *e, int age) { dns_rrl_rate_t *ratep; int balance, rate; if (e->key.s.rtype == DNS_RRL_RTYPE_TCP) { rate = 1; } else { ratep = get_rate(rrl, e->key.s.rtype); rate = ratep->scaled; } balance = e->responses + age * rate; if (balance > rate) balance = rate; return (balance); } /* * Search for an entry for a response and optionally create it. */ static dns_rrl_entry_t * get_entry(dns_rrl_t *rrl, const isc_sockaddr_t *client_addr, dns_rdataclass_t qclass, dns_rdatatype_t qtype, dns_name_t *qname, dns_rrl_rtype_t rtype, isc_stdtime_t now, isc_boolean_t create, char *log_buf, unsigned int log_buf_len) { dns_rrl_key_t key; isc_uint32_t hval; dns_rrl_entry_t *e; dns_rrl_hash_t *hash; dns_rrl_bin_t *new_bin, *old_bin; int probes, age; make_key(rrl, &key, client_addr, qtype, qname, qclass, rtype); hval = hash_key(&key); /* * Look for the entry in the current hash table. */ new_bin = get_bin(rrl->hash, hval); probes = 1; e = ISC_LIST_HEAD(*new_bin); while (e != NULL) { if (key_cmp(&e->key, &key)) { ref_entry(rrl, e, probes, now); return (e); } ++probes; e = ISC_LIST_NEXT(e, hlink); } /* * Look in the old hash table. */ if (rrl->old_hash != NULL) { old_bin = get_bin(rrl->old_hash, hval); e = ISC_LIST_HEAD(*old_bin); while (e != NULL) { if (key_cmp(&e->key, &key)) { ISC_LIST_UNLINK(*old_bin, e, hlink); ISC_LIST_PREPEND(*new_bin, e, hlink); e->hash_gen = rrl->hash_gen; ref_entry(rrl, e, probes, now); return (e); } e = ISC_LIST_NEXT(e, hlink); } /* * Discard prevous hash table when all of its entries are old. */ age = delta_rrl_time(rrl->old_hash->check_time, now); if (age > rrl->window) free_old_hash(rrl); } if (!create) return (NULL); /* * The entry does not exist, so create it by finding a free entry. * Keep currently penalized and logged entries. * Try to make more entries if none are idle. * Steal the oldest entry if we cannot create more. */ for (e = ISC_LIST_TAIL(rrl->lru); e != NULL; e = ISC_LIST_PREV(e, lru)) { if (!ISC_LINK_LINKED(e, hlink)) break; age = get_age(rrl, e, now); if (age <= 1) { e = NULL; break; } if (!e->logged && response_balance(rrl, e, age) > 0) break; } if (e == NULL) { expand_entries(rrl, ISC_MIN((rrl->num_entries+1)/2, 1000)); e = ISC_LIST_TAIL(rrl->lru); } if (e->logged) log_end(rrl, e, ISC_TRUE, log_buf, log_buf_len); if (ISC_LINK_LINKED(e, hlink)) { if (e->hash_gen == rrl->hash_gen) hash = rrl->hash; else hash = rrl->old_hash; old_bin = get_bin(hash, hash_key(&e->key)); ISC_LIST_UNLINK(*old_bin, e, hlink); } ISC_LIST_PREPEND(*new_bin, e, hlink); e->hash_gen = rrl->hash_gen; e->key = key; e->ts_valid = ISC_FALSE; ref_entry(rrl, e, probes, now); return (e); } static void debit_log(const dns_rrl_entry_t *e, int age, const char *action) { char buf[sizeof("age=12345678")]; const char *age_str; if (age == DNS_RRL_FOREVER) { age_str = ""; } else { snprintf(buf, sizeof(buf), "age=%d", age); age_str = buf; } isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DEBUG3, "rrl %08x %6s responses=%-3d %s", hash_key(&e->key), age_str, e->responses, action); } static inline dns_rrl_result_t debit_rrl_entry(dns_rrl_t *rrl, dns_rrl_entry_t *e, double qps, double scale, const isc_sockaddr_t *client_addr, isc_stdtime_t now, char *log_buf, unsigned int log_buf_len) { int rate, new_rate, slip, new_slip, age, log_secs, min; dns_rrl_rate_t *ratep; dns_rrl_entry_t const *credit_e; /* * Pick the rate counter. * Optionally adjust the rate by the estimated query/second rate. */ ratep = get_rate(rrl, e->key.s.rtype); rate = ratep->r; if (rate == 0) return (DNS_RRL_RESULT_OK); if (scale < 1.0) { /* * The limit for clients that have used TCP is not scaled. */ credit_e = get_entry(rrl, client_addr, 0, dns_rdatatype_none, NULL, DNS_RRL_RTYPE_TCP, now, ISC_FALSE, log_buf, log_buf_len); if (credit_e != NULL) { age = get_age(rrl, e, now); if (age < rrl->window) scale = 1.0; } } if (scale < 1.0) { new_rate = (int) (rate * scale); if (new_rate < 1) new_rate = 1; if (ratep->scaled != new_rate) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DEBUG1, "%d qps scaled %s by %.2f" " from %d to %d", (int)qps, ratep->str, scale, rate, new_rate); rate = new_rate; ratep->scaled = rate; } } min = -rrl->window * rate; /* * Treat time jumps into the recent past as no time. * Treat entries older than the window as if they were just created * Credit other entries. */ age = get_age(rrl, e, now); if (age > 0) { /* * Credit tokens earned during elapsed time. */ if (age > rrl->window) { e->responses = rate; e->slip_cnt = 0; } else { e->responses += rate*age; if (e->responses > rate) { e->responses = rate; e->slip_cnt = 0; } } /* * Find the seconds since last log message without overflowing * small counter. This counter is reset when an entry is * created. It is not necessarily reset when some requests * are answered provided other requests continue to be dropped * or slipped. This can happen when the request rate is just * at the limit. */ if (e->logged) { log_secs = e->log_secs; log_secs += age; if (log_secs > DNS_RRL_MAX_LOG_SECS || log_secs < 0) log_secs = DNS_RRL_MAX_LOG_SECS; e->log_secs = log_secs; } } set_age(rrl, e, now); /* * Debit the entry for this response. */ if (--e->responses >= 0) { if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DEBUG3)) debit_log(e, age, ""); return (DNS_RRL_RESULT_OK); } if (e->responses < min) e->responses = min; /* * Drop this response unless it should slip or leak. */ slip = rrl->slip.r; if (slip > 2 && scale < 1.0) { new_slip = (int) (slip * scale); if (new_slip < 2) new_slip = 2; if (rrl->slip.scaled != new_slip) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DEBUG1, "%d qps scaled slip" " by %.2f from %d to %d", (int)qps, scale, slip, new_slip); slip = new_slip; rrl->slip.scaled = slip; } } if (slip != 0 && e->key.s.rtype != DNS_RRL_RTYPE_ALL) { if (e->slip_cnt++ == 0) { if ((int) e->slip_cnt >= slip) e->slip_cnt = 0; if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DEBUG3)) debit_log(e, age, "slip"); return (DNS_RRL_RESULT_SLIP); } else if ((int) e->slip_cnt >= slip) { e->slip_cnt = 0; } } if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DEBUG3)) debit_log(e, age, "drop"); return (DNS_RRL_RESULT_DROP); } static inline dns_rrl_qname_buf_t * get_qname(dns_rrl_t *rrl, const dns_rrl_entry_t *e) { dns_rrl_qname_buf_t *qbuf; qbuf = rrl->qnames[e->log_qname]; if (qbuf == NULL || qbuf->e != e) return (NULL); return (qbuf); } static inline void free_qname(dns_rrl_t *rrl, dns_rrl_entry_t *e) { dns_rrl_qname_buf_t *qbuf; qbuf = get_qname(rrl, e); if (qbuf != NULL) { qbuf->e = NULL; ISC_LIST_APPEND(rrl->qname_free, qbuf, link); } } static void add_log_str(isc_buffer_t *lb, const char *str, unsigned int str_len) { isc_region_t region; isc_buffer_availableregion(lb, ®ion); if (str_len >= region.length) { if (region.length <= 0) return; str_len = region.length; } memmove(region.base, str, str_len); isc_buffer_add(lb, str_len); } #define ADD_LOG_CSTR(eb, s) add_log_str(eb, s, sizeof(s)-1) /* * Build strings for the logs */ static void make_log_buf(dns_rrl_t *rrl, dns_rrl_entry_t *e, const char *str1, const char *str2, isc_boolean_t plural, dns_name_t *qname, isc_boolean_t save_qname, dns_rrl_result_t rrl_result, isc_result_t resp_result, char *log_buf, unsigned int log_buf_len) { isc_buffer_t lb; dns_rrl_qname_buf_t *qbuf; isc_netaddr_t cidr; char strbuf[ISC_MAX(sizeof("/123"), sizeof(" (12345678)"))]; const char *rstr; isc_result_t msg_result; if (log_buf_len <= 1) { if (log_buf_len == 1) log_buf[0] = '\0'; return; } isc_buffer_init(&lb, log_buf, log_buf_len-1); if (str1 != NULL) add_log_str(&lb, str1, strlen(str1)); if (str2 != NULL) add_log_str(&lb, str2, strlen(str2)); switch (rrl_result) { case DNS_RRL_RESULT_OK: break; case DNS_RRL_RESULT_DROP: ADD_LOG_CSTR(&lb, "drop "); break; case DNS_RRL_RESULT_SLIP: ADD_LOG_CSTR(&lb, "slip "); break; default: INSIST(0); break; } switch (e->key.s.rtype) { case DNS_RRL_RTYPE_QUERY: break; case DNS_RRL_RTYPE_REFERRAL: ADD_LOG_CSTR(&lb, "referral "); break; case DNS_RRL_RTYPE_NODATA: ADD_LOG_CSTR(&lb, "NODATA "); break; case DNS_RRL_RTYPE_NXDOMAIN: ADD_LOG_CSTR(&lb, "NXDOMAIN "); break; case DNS_RRL_RTYPE_ERROR: if (resp_result == ISC_R_SUCCESS) { ADD_LOG_CSTR(&lb, "error "); } else { rstr = isc_result_totext(resp_result); add_log_str(&lb, rstr, strlen(rstr)); ADD_LOG_CSTR(&lb, " error "); } break; case DNS_RRL_RTYPE_ALL: ADD_LOG_CSTR(&lb, "all "); break; default: INSIST(0); } if (plural) ADD_LOG_CSTR(&lb, "responses to "); else ADD_LOG_CSTR(&lb, "response to "); memset(&cidr, 0, sizeof(cidr)); if (e->key.s.ipv6) { snprintf(strbuf, sizeof(strbuf), "/%d", rrl->ipv6_prefixlen); cidr.family = AF_INET6; memset(&cidr.type.in6, 0, sizeof(cidr.type.in6)); memmove(&cidr.type.in6, e->key.s.ip, sizeof(e->key.s.ip)); } else { snprintf(strbuf, sizeof(strbuf), "/%d", rrl->ipv4_prefixlen); cidr.family = AF_INET; cidr.type.in.s_addr = e->key.s.ip[0]; } msg_result = isc_netaddr_totext(&cidr, &lb); if (msg_result != ISC_R_SUCCESS) ADD_LOG_CSTR(&lb, "?"); add_log_str(&lb, strbuf, strlen(strbuf)); if (e->key.s.rtype == DNS_RRL_RTYPE_QUERY || e->key.s.rtype == DNS_RRL_RTYPE_REFERRAL || e->key.s.rtype == DNS_RRL_RTYPE_NODATA || e->key.s.rtype == DNS_RRL_RTYPE_NXDOMAIN) { qbuf = get_qname(rrl, e); if (save_qname && qbuf == NULL && qname != NULL && dns_name_isabsolute(qname)) { /* * Capture the qname for the "stop limiting" message. */ qbuf = ISC_LIST_TAIL(rrl->qname_free); if (qbuf != NULL) { ISC_LIST_UNLINK(rrl->qname_free, qbuf, link); } else if (rrl->num_qnames < DNS_RRL_QNAMES) { qbuf = isc_mem_get(rrl->mctx, sizeof(*qbuf)); if (qbuf != NULL) { memset(qbuf, 0, sizeof(*qbuf)); ISC_LINK_INIT(qbuf, link); qbuf->index = rrl->num_qnames; rrl->qnames[rrl->num_qnames++] = qbuf; } else { isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_FAIL, "isc_mem_get(%d)" " failed for RRL qname", (int)sizeof(*qbuf)); } } if (qbuf != NULL) { e->log_qname = qbuf->index; qbuf->e = e; dns_fixedname_init(&qbuf->qname); dns_name_copy(qname, dns_fixedname_name(&qbuf->qname), NULL); } } if (qbuf != NULL) qname = dns_fixedname_name(&qbuf->qname); if (qname != NULL) { ADD_LOG_CSTR(&lb, " for "); (void)dns_name_totext(qname, ISC_TRUE, &lb); } else { ADD_LOG_CSTR(&lb, " for (?)"); } if (e->key.s.rtype != DNS_RRL_RTYPE_NXDOMAIN) { ADD_LOG_CSTR(&lb, " "); (void)dns_rdataclass_totext(e->key.s.qclass, &lb); if (e->key.s.rtype == DNS_RRL_RTYPE_QUERY) { ADD_LOG_CSTR(&lb, " "); (void)dns_rdatatype_totext(e->key.s.qtype, &lb); } } snprintf(strbuf, sizeof(strbuf), " (%08x)", e->key.s.qname_hash); add_log_str(&lb, strbuf, strlen(strbuf)); } /* * We saved room for '\0'. */ log_buf[isc_buffer_usedlength(&lb)] = '\0'; } static void log_end(dns_rrl_t *rrl, dns_rrl_entry_t *e, isc_boolean_t early, char *log_buf, unsigned int log_buf_len) { if (e->logged) { make_log_buf(rrl, e, early ? "*" : NULL, rrl->log_only ? "would stop limiting " : "stop limiting ", ISC_TRUE, NULL, ISC_FALSE, DNS_RRL_RESULT_OK, ISC_R_SUCCESS, log_buf, log_buf_len); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DROP, "%s", log_buf); free_qname(rrl, e); e->logged = ISC_FALSE; --rrl->num_logged; } } /* * Log messages for streams that have stopped being rate limited. */ static void log_stops(dns_rrl_t *rrl, isc_stdtime_t now, int limit, char *log_buf, unsigned int log_buf_len) { dns_rrl_entry_t *e; int age; for (e = rrl->last_logged; e != NULL; e = ISC_LIST_PREV(e, lru)) { if (!e->logged) continue; if (now != 0) { age = get_age(rrl, e, now); if (age < DNS_RRL_STOP_LOG_SECS || response_balance(rrl, e, age) < 0) break; } log_end(rrl, e, now == 0, log_buf, log_buf_len); if (rrl->num_logged <= 0) break; /* * Too many messages could stall real work. */ if (--limit < 0) { rrl->last_logged = ISC_LIST_PREV(e, lru); return; } } if (e == NULL) { INSIST(rrl->num_logged == 0); rrl->log_stops_time = now; } rrl->last_logged = e; } /* * Main rate limit interface. */ dns_rrl_result_t dns_rrl(dns_view_t *view, const isc_sockaddr_t *client_addr, isc_boolean_t is_tcp, dns_rdataclass_t qclass, dns_rdatatype_t qtype, dns_name_t *qname, isc_result_t resp_result, isc_stdtime_t now, isc_boolean_t wouldlog, char *log_buf, unsigned int log_buf_len) { dns_rrl_t *rrl; dns_rrl_rtype_t rtype; dns_rrl_entry_t *e; isc_netaddr_t netclient; int secs; double qps, scale; int exempt_match; isc_result_t result; dns_rrl_result_t rrl_result; INSIST(log_buf != NULL && log_buf_len > 0); rrl = view->rrl; if (rrl->exempt != NULL) { isc_netaddr_fromsockaddr(&netclient, client_addr); result = dns_acl_match(&netclient, NULL, rrl->exempt, &view->aclenv, &exempt_match, NULL); if (result == ISC_R_SUCCESS && exempt_match > 0) return (DNS_RRL_RESULT_OK); } LOCK(&rrl->lock); /* * Estimate total query per second rate when scaling by qps. */ if (rrl->qps_scale == 0) { qps = 0.0; scale = 1.0; } else { ++rrl->qps_responses; secs = delta_rrl_time(rrl->qps_time, now); if (secs <= 0) { qps = rrl->qps; } else { qps = (1.0*rrl->qps_responses) / secs; if (secs >= rrl->window) { if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DEBUG3)) isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DEBUG3, "%d responses/%d seconds" " = %d qps", rrl->qps_responses, secs, (int)qps); rrl->qps = qps; rrl->qps_responses = 0; rrl->qps_time = now; } else if (qps < rrl->qps) { qps = rrl->qps; } } scale = rrl->qps_scale / qps; } /* * Do maintenance once per second. */ if (rrl->num_logged > 0 && rrl->log_stops_time != now) log_stops(rrl, now, 8, log_buf, log_buf_len); /* * Notice TCP responses when scaling limits by qps. * Do not try to rate limit TCP responses. */ if (is_tcp) { if (scale < 1.0) { e = get_entry(rrl, client_addr, 0, dns_rdatatype_none, NULL, DNS_RRL_RTYPE_TCP, now, ISC_TRUE, log_buf, log_buf_len); if (e != NULL) { e->responses = -(rrl->window+1); set_age(rrl, e, now); } } UNLOCK(&rrl->lock); return (ISC_R_SUCCESS); } /* * Find the right kind of entry, creating it if necessary. * If that is impossible, then nothing more can be done */ switch (resp_result) { case ISC_R_SUCCESS: rtype = DNS_RRL_RTYPE_QUERY; break; case DNS_R_DELEGATION: rtype = DNS_RRL_RTYPE_REFERRAL; break; case DNS_R_NXRRSET: rtype = DNS_RRL_RTYPE_NODATA; break; case DNS_R_NXDOMAIN: rtype = DNS_RRL_RTYPE_NXDOMAIN; break; default: rtype = DNS_RRL_RTYPE_ERROR; break; } e = get_entry(rrl, client_addr, qclass, qtype, qname, rtype, now, ISC_TRUE, log_buf, log_buf_len); if (e == NULL) { UNLOCK(&rrl->lock); return (DNS_RRL_RESULT_OK); } if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DEBUG1)) { /* * Do not worry about speed or releasing the lock. * This message appears before messages from debit_rrl_entry(). */ make_log_buf(rrl, e, "consider limiting ", NULL, ISC_FALSE, qname, ISC_FALSE, DNS_RRL_RESULT_OK, resp_result, log_buf, log_buf_len); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DEBUG1, "%s", log_buf); } rrl_result = debit_rrl_entry(rrl, e, qps, scale, client_addr, now, log_buf, log_buf_len); if (rrl->all_per_second.r != 0) { /* * We must debit the all-per-second token bucket if we have * an all-per-second limit for the IP address. * The all-per-second limit determines the log message * when both limits are hit. * The response limiting must continue if the * all-per-second limiting lapses. */ dns_rrl_entry_t *e_all; dns_rrl_result_t rrl_all_result; e_all = get_entry(rrl, client_addr, 0, dns_rdatatype_none, NULL, DNS_RRL_RTYPE_ALL, now, ISC_TRUE, log_buf, log_buf_len); if (e_all == NULL) { UNLOCK(&rrl->lock); return (DNS_RRL_RESULT_OK); } rrl_all_result = debit_rrl_entry(rrl, e_all, qps, scale, client_addr, now, log_buf, log_buf_len); if (rrl_all_result != DNS_RRL_RESULT_OK) { e = e_all; rrl_result = rrl_all_result; if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DEBUG1)) { make_log_buf(rrl, e, "prefer all-per-second limiting ", NULL, ISC_TRUE, qname, ISC_FALSE, DNS_RRL_RESULT_OK, resp_result, log_buf, log_buf_len); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DEBUG1, "%s", log_buf); } } } if (rrl_result == DNS_RRL_RESULT_OK) { UNLOCK(&rrl->lock); return (DNS_RRL_RESULT_OK); } /* * Log occassionally in the rate-limit category. */ if ((!e->logged || e->log_secs >= DNS_RRL_MAX_LOG_SECS) && isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DROP)) { make_log_buf(rrl, e, rrl->log_only ? "would " : NULL, e->logged ? "continue limiting " : "limit ", ISC_TRUE, qname, ISC_TRUE, DNS_RRL_RESULT_OK, resp_result, log_buf, log_buf_len); if (!e->logged) { e->logged = ISC_TRUE; if (++rrl->num_logged <= 1) rrl->last_logged = e; } e->log_secs = 0; /* * Avoid holding the lock. */ if (!wouldlog) { UNLOCK(&rrl->lock); e = NULL; } isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL, DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DROP, "%s", log_buf); } /* * Make a log message for the caller. */ if (wouldlog) make_log_buf(rrl, e, rrl->log_only ? "would rate limit " : "rate limit ", NULL, ISC_FALSE, qname, ISC_FALSE, rrl_result, resp_result, log_buf, log_buf_len); if (e != NULL) { /* * Do not save the qname unless we might need it for * the ending log message. */ if (!e->logged) free_qname(rrl, e); UNLOCK(&rrl->lock); } return (rrl_result); } void dns_rrl_view_destroy(dns_view_t *view) { dns_rrl_t *rrl; dns_rrl_block_t *b; dns_rrl_hash_t *h; char log_buf[DNS_RRL_LOG_BUF_LEN]; int i; rrl = view->rrl; if (rrl == NULL) return; view->rrl = NULL; /* * Assume the caller takes care of locking the view and anything else. */ if (rrl->num_logged > 0) log_stops(rrl, 0, ISC_INT32_MAX, log_buf, sizeof(log_buf)); for (i = 0; i < DNS_RRL_QNAMES; ++i) { if (rrl->qnames[i] == NULL) break; isc_mem_put(rrl->mctx, rrl->qnames[i], sizeof(*rrl->qnames[i])); } if (rrl->exempt != NULL) dns_acl_detach(&rrl->exempt); DESTROYLOCK(&rrl->lock); while (!ISC_LIST_EMPTY(rrl->blocks)) { b = ISC_LIST_HEAD(rrl->blocks); ISC_LIST_UNLINK(rrl->blocks, b, link); isc_mem_put(rrl->mctx, b, b->size); } h = rrl->hash; if (h != NULL) isc_mem_put(rrl->mctx, h, sizeof(*h) + (h->length - 1) * sizeof(h->bins[0])); h = rrl->old_hash; if (h != NULL) isc_mem_put(rrl->mctx, h, sizeof(*h) + (h->length - 1) * sizeof(h->bins[0])); isc_mem_putanddetach(&rrl->mctx, rrl, sizeof(*rrl)); } isc_result_t dns_rrl_init(dns_rrl_t **rrlp, dns_view_t *view, int min_entries) { dns_rrl_t *rrl; isc_result_t result; *rrlp = NULL; rrl = isc_mem_get(view->mctx, sizeof(*rrl)); if (rrl == NULL) return (ISC_R_NOMEMORY); memset(rrl, 0, sizeof(*rrl)); isc_mem_attach(view->mctx, &rrl->mctx); result = isc_mutex_init(&rrl->lock); if (result != ISC_R_SUCCESS) { isc_mem_putanddetach(&rrl->mctx, rrl, sizeof(*rrl)); return (result); } isc_stdtime_get(&rrl->ts_bases[0]); view->rrl = rrl; result = expand_entries(rrl, min_entries); if (result != ISC_R_SUCCESS) { dns_rrl_view_destroy(view); return (result); } result = expand_rrl_hash(rrl, 0); if (result != ISC_R_SUCCESS) { dns_rrl_view_destroy(view); return (result); } *rrlp = rrl; return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/dns/ecdb.c0000644000470500017500000004743612664710322016002 0ustar lamontlamont/* * Copyright (C) 2009-2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #define ECDB_MAGIC ISC_MAGIC('E', 'C', 'D', 'B') #define VALID_ECDB(db) ((db) != NULL && \ (db)->common.impmagic == ECDB_MAGIC) #define ECDBNODE_MAGIC ISC_MAGIC('E', 'C', 'D', 'N') #define VALID_ECDBNODE(ecdbn) ISC_MAGIC_VALID(ecdbn, ECDBNODE_MAGIC) /*% * The 'ephemeral' cache DB (ecdb) implementation. An ecdb just provides * temporary storage for ongoing name resolution with the common DB interfaces. * It actually doesn't cache anything. The implementation expects any stored * data is released within a short period, and does not care about the * scalability in terms of the number of nodes. */ typedef struct dns_ecdb { /* Unlocked */ dns_db_t common; isc_mutex_t lock; /* Locked */ unsigned int references; ISC_LIST(struct dns_ecdbnode) nodes; } dns_ecdb_t; typedef struct dns_ecdbnode { /* Unlocked */ unsigned int magic; isc_mutex_t lock; dns_ecdb_t *ecdb; dns_name_t name; ISC_LINK(struct dns_ecdbnode) link; /* Locked */ ISC_LIST(struct rdatasetheader) rdatasets; unsigned int references; } dns_ecdbnode_t; typedef struct rdatasetheader { dns_rdatatype_t type; dns_ttl_t ttl; dns_trust_t trust; dns_rdatatype_t covers; unsigned int attributes; ISC_LINK(struct rdatasetheader) link; } rdatasetheader_t; /* Copied from rbtdb.c */ #define RDATASET_ATTR_NXDOMAIN 0x0010 #define RDATASET_ATTR_NEGATIVE 0x0100 #define NXDOMAIN(header) \ (((header)->attributes & RDATASET_ATTR_NXDOMAIN) != 0) #define NEGATIVE(header) \ (((header)->attributes & RDATASET_ATTR_NEGATIVE) != 0) static isc_result_t dns_ecdb_create(isc_mem_t *mctx, dns_name_t *origin, dns_dbtype_t type, dns_rdataclass_t rdclass, unsigned int argc, char *argv[], void *driverarg, dns_db_t **dbp); static void rdataset_disassociate(dns_rdataset_t *rdataset); static isc_result_t rdataset_first(dns_rdataset_t *rdataset); static isc_result_t rdataset_next(dns_rdataset_t *rdataset); static void rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata); static void rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target); static unsigned int rdataset_count(dns_rdataset_t *rdataset); static void rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust); static dns_rdatasetmethods_t rdataset_methods = { rdataset_disassociate, rdataset_first, rdataset_next, rdataset_current, rdataset_clone, rdataset_count, NULL, /* addnoqname */ NULL, /* getnoqname */ NULL, /* addclosest */ NULL, /* getclosest */ NULL, /* getadditional */ NULL, /* setadditional */ NULL, /* putadditional */ rdataset_settrust, /* settrust */ NULL, /* expire */ NULL /* clearprefetch */ }; typedef struct ecdb_rdatasetiter { dns_rdatasetiter_t common; rdatasetheader_t *current; } ecdb_rdatasetiter_t; static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp); static isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator); static isc_result_t rdatasetiter_next(dns_rdatasetiter_t *iterator); static void rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset); static dns_rdatasetitermethods_t rdatasetiter_methods = { rdatasetiter_destroy, rdatasetiter_first, rdatasetiter_next, rdatasetiter_current }; isc_result_t dns_ecdb_register(isc_mem_t *mctx, dns_dbimplementation_t **dbimp) { REQUIRE(mctx != NULL); REQUIRE(dbimp != NULL && *dbimp == NULL); return (dns_db_register("ecdb", dns_ecdb_create, NULL, mctx, dbimp)); } void dns_ecdb_unregister(dns_dbimplementation_t **dbimp) { REQUIRE(dbimp != NULL && *dbimp != NULL); dns_db_unregister(dbimp); } /*% * DB routines */ static void attach(dns_db_t *source, dns_db_t **targetp) { dns_ecdb_t *ecdb = (dns_ecdb_t *)source; REQUIRE(VALID_ECDB(ecdb)); REQUIRE(targetp != NULL && *targetp == NULL); LOCK(&ecdb->lock); ecdb->references++; UNLOCK(&ecdb->lock); *targetp = source; } static void destroy_ecdb(dns_ecdb_t **ecdbp) { dns_ecdb_t *ecdb = *ecdbp; isc_mem_t *mctx = ecdb->common.mctx; if (dns_name_dynamic(&ecdb->common.origin)) dns_name_free(&ecdb->common.origin, mctx); DESTROYLOCK(&ecdb->lock); ecdb->common.impmagic = 0; ecdb->common.magic = 0; isc_mem_putanddetach(&mctx, ecdb, sizeof(*ecdb)); *ecdbp = NULL; } static void detach(dns_db_t **dbp) { dns_ecdb_t *ecdb; isc_boolean_t need_destroy = ISC_FALSE; REQUIRE(dbp != NULL); ecdb = (dns_ecdb_t *)*dbp; REQUIRE(VALID_ECDB(ecdb)); LOCK(&ecdb->lock); ecdb->references--; if (ecdb->references == 0 && ISC_LIST_EMPTY(ecdb->nodes)) need_destroy = ISC_TRUE; UNLOCK(&ecdb->lock); if (need_destroy) destroy_ecdb(&ecdb); *dbp = NULL; } static void attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) { dns_ecdb_t *ecdb = (dns_ecdb_t *)db; dns_ecdbnode_t *node = (dns_ecdbnode_t *)source; REQUIRE(VALID_ECDB(ecdb)); REQUIRE(VALID_ECDBNODE(node)); REQUIRE(targetp != NULL && *targetp == NULL); LOCK(&node->lock); INSIST(node->references > 0); node->references++; INSIST(node->references != 0); /* Catch overflow. */ UNLOCK(&node->lock); *targetp = node; } static void destroynode(dns_ecdbnode_t *node) { isc_mem_t *mctx; dns_ecdb_t *ecdb = node->ecdb; isc_boolean_t need_destroydb = ISC_FALSE; rdatasetheader_t *header; mctx = ecdb->common.mctx; LOCK(&ecdb->lock); ISC_LIST_UNLINK(ecdb->nodes, node, link); if (ecdb->references == 0 && ISC_LIST_EMPTY(ecdb->nodes)) need_destroydb = ISC_TRUE; UNLOCK(&ecdb->lock); dns_name_free(&node->name, mctx); while ((header = ISC_LIST_HEAD(node->rdatasets)) != NULL) { unsigned int headersize; ISC_LIST_UNLINK(node->rdatasets, header, link); headersize = dns_rdataslab_size((unsigned char *)header, sizeof(*header)); isc_mem_put(mctx, header, headersize); } DESTROYLOCK(&node->lock); node->magic = 0; isc_mem_put(mctx, node, sizeof(*node)); if (need_destroydb) destroy_ecdb(&ecdb); } static void detachnode(dns_db_t *db, dns_dbnode_t **nodep) { dns_ecdb_t *ecdb = (dns_ecdb_t *)db; dns_ecdbnode_t *node; isc_boolean_t need_destroy = ISC_FALSE; REQUIRE(VALID_ECDB(ecdb)); REQUIRE(nodep != NULL); node = (dns_ecdbnode_t *)*nodep; REQUIRE(VALID_ECDBNODE(node)); UNUSED(ecdb); /* in case REQUIRE() is empty */ LOCK(&node->lock); INSIST(node->references > 0); node->references--; if (node->references == 0) need_destroy = ISC_TRUE; UNLOCK(&node->lock); if (need_destroy) destroynode(node); *nodep = NULL; } static isc_result_t find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { dns_ecdb_t *ecdb = (dns_ecdb_t *)db; REQUIRE(VALID_ECDB(ecdb)); UNUSED(name); UNUSED(version); UNUSED(type); UNUSED(options); UNUSED(now); UNUSED(nodep); UNUSED(foundname); UNUSED(rdataset); UNUSED(sigrdataset); return (ISC_R_NOTFOUND); } static isc_result_t findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { dns_ecdb_t *ecdb = (dns_ecdb_t *)db; REQUIRE(VALID_ECDB(ecdb)); UNUSED(name); UNUSED(options); UNUSED(now); UNUSED(nodep); UNUSED(foundname); UNUSED(rdataset); UNUSED(sigrdataset); return (ISC_R_NOTFOUND); } static isc_result_t findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, dns_dbnode_t **nodep) { dns_ecdb_t *ecdb = (dns_ecdb_t *)db; isc_mem_t *mctx; dns_ecdbnode_t *node; isc_result_t result; REQUIRE(VALID_ECDB(ecdb)); REQUIRE(nodep != NULL && *nodep == NULL); UNUSED(name); if (create != ISC_TRUE) { /* an 'ephemeral' node is never reused. */ return (ISC_R_NOTFOUND); } mctx = ecdb->common.mctx; node = isc_mem_get(mctx, sizeof(*node)); if (node == NULL) return (ISC_R_NOMEMORY); result = isc_mutex_init(&node->lock); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_mutex_init() failed: %s", isc_result_totext(result)); isc_mem_put(mctx, node, sizeof(*node)); return (ISC_R_UNEXPECTED); } dns_name_init(&node->name, NULL); result = dns_name_dup(name, mctx, &node->name); if (result != ISC_R_SUCCESS) { DESTROYLOCK(&node->lock); isc_mem_put(mctx, node, sizeof(*node)); return (result); } node->ecdb= ecdb; node->references = 1; ISC_LIST_INIT(node->rdatasets); ISC_LINK_INIT(node, link); LOCK(&ecdb->lock); ISC_LIST_APPEND(ecdb->nodes, node, link); UNLOCK(&ecdb->lock); node->magic = ECDBNODE_MAGIC; *nodep = node; return (ISC_R_SUCCESS); } static void bind_rdataset(dns_ecdb_t *ecdb, dns_ecdbnode_t *node, rdatasetheader_t *header, dns_rdataset_t *rdataset) { unsigned char *raw; /* * Caller must be holding the node lock. */ REQUIRE(!dns_rdataset_isassociated(rdataset)); rdataset->methods = &rdataset_methods; rdataset->rdclass = ecdb->common.rdclass; rdataset->type = header->type; rdataset->covers = header->covers; rdataset->ttl = header->ttl; rdataset->trust = header->trust; if (NXDOMAIN(header)) rdataset->attributes |= DNS_RDATASETATTR_NXDOMAIN; if (NEGATIVE(header)) rdataset->attributes |= DNS_RDATASETATTR_NEGATIVE; rdataset->private1 = ecdb; rdataset->private2 = node; raw = (unsigned char *)header + sizeof(*header); rdataset->private3 = raw; rdataset->count = 0; /* * Reset iterator state. */ rdataset->privateuint4 = 0; rdataset->private5 = NULL; INSIST(node->references > 0); node->references++; } static isc_result_t addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options, dns_rdataset_t *addedrdataset) { dns_ecdb_t *ecdb = (dns_ecdb_t *)db; isc_region_t r; isc_result_t result = ISC_R_SUCCESS; isc_mem_t *mctx; dns_ecdbnode_t *ecdbnode = (dns_ecdbnode_t *)node; rdatasetheader_t *header; REQUIRE(VALID_ECDB(ecdb)); REQUIRE(VALID_ECDBNODE(ecdbnode)); UNUSED(version); UNUSED(now); UNUSED(options); mctx = ecdb->common.mctx; LOCK(&ecdbnode->lock); /* * Sanity check: this implementation does not allow overriding an * existing rdataset of the same type. */ for (header = ISC_LIST_HEAD(ecdbnode->rdatasets); header != NULL; header = ISC_LIST_NEXT(header, link)) { INSIST(header->type != rdataset->type || header->covers != rdataset->covers); } result = dns_rdataslab_fromrdataset(rdataset, mctx, &r, sizeof(rdatasetheader_t)); if (result != ISC_R_SUCCESS) goto unlock; header = (rdatasetheader_t *)r.base; header->type = rdataset->type; header->ttl = rdataset->ttl; header->trust = rdataset->trust; header->covers = rdataset->covers; header->attributes = 0; if ((rdataset->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0) header->attributes |= RDATASET_ATTR_NXDOMAIN; if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) header->attributes |= RDATASET_ATTR_NEGATIVE; ISC_LINK_INIT(header, link); ISC_LIST_APPEND(ecdbnode->rdatasets, header, link); if (addedrdataset == NULL) goto unlock; bind_rdataset(ecdb, ecdbnode, header, addedrdataset); unlock: UNLOCK(&ecdbnode->lock); return (result); } static isc_result_t deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdatatype_t type, dns_rdatatype_t covers) { UNUSED(db); UNUSED(node); UNUSED(version); UNUSED(type); UNUSED(covers); return (ISC_R_NOTIMPLEMENTED); } static isc_result_t createiterator(dns_db_t *db, unsigned int options, dns_dbiterator_t **iteratorp) { UNUSED(db); UNUSED(options); UNUSED(iteratorp); return (ISC_R_NOTIMPLEMENTED); } static isc_result_t allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_stdtime_t now, dns_rdatasetiter_t **iteratorp) { dns_ecdb_t *ecdb = (dns_ecdb_t *)db; dns_ecdbnode_t *ecdbnode = (dns_ecdbnode_t *)node; isc_mem_t *mctx; ecdb_rdatasetiter_t *iterator; REQUIRE(VALID_ECDB(ecdb)); REQUIRE(VALID_ECDBNODE(ecdbnode)); mctx = ecdb->common.mctx; iterator = isc_mem_get(mctx, sizeof(ecdb_rdatasetiter_t)); if (iterator == NULL) return (ISC_R_NOMEMORY); iterator->common.magic = DNS_RDATASETITER_MAGIC; iterator->common.methods = &rdatasetiter_methods; iterator->common.db = db; iterator->common.node = NULL; attachnode(db, node, &iterator->common.node); iterator->common.version = version; iterator->common.now = now; *iteratorp = (dns_rdatasetiter_t *)iterator; return (ISC_R_SUCCESS); } static dns_dbmethods_t ecdb_methods = { attach, detach, NULL, /* beginload */ NULL, /* endload */ NULL, /* serialize */ NULL, /* dump */ NULL, /* currentversion */ NULL, /* newversion */ NULL, /* attachversion */ NULL, /* closeversion */ findnode, find, findzonecut, attachnode, detachnode, NULL, /* expirenode */ NULL, /* printnode */ createiterator, /* createiterator */ NULL, /* findrdataset */ allrdatasets, addrdataset, NULL, /* subtractrdataset */ deleterdataset, NULL, /* issecure */ NULL, /* nodecount */ NULL, /* ispersistent */ NULL, /* overmem */ NULL, /* settask */ NULL, /* getoriginnode */ NULL, /* transfernode */ NULL, /* getnsec3parameters */ NULL, /* findnsec3node */ NULL, /* setsigningtime */ NULL, /* getsigningtime */ NULL, /* resigned */ NULL, /* isdnssec */ NULL, /* getrrsetstats */ NULL, /* rpz_attach */ NULL, /* rpz_ready */ NULL, /* findnodeext */ NULL, /* findext */ NULL, /* setcachestats */ NULL /* hashsize */ }; static isc_result_t dns_ecdb_create(isc_mem_t *mctx, dns_name_t *origin, dns_dbtype_t type, dns_rdataclass_t rdclass, unsigned int argc, char *argv[], void *driverarg, dns_db_t **dbp) { dns_ecdb_t *ecdb; isc_result_t result; REQUIRE(mctx != NULL); REQUIRE(origin == dns_rootname); REQUIRE(type == dns_dbtype_cache); REQUIRE(dbp != NULL && *dbp == NULL); UNUSED(argc); UNUSED(argv); UNUSED(driverarg); ecdb = isc_mem_get(mctx, sizeof(*ecdb)); if (ecdb == NULL) return (ISC_R_NOMEMORY); ecdb->common.attributes = DNS_DBATTR_CACHE; ecdb->common.rdclass = rdclass; ecdb->common.methods = &ecdb_methods; dns_name_init(&ecdb->common.origin, NULL); result = dns_name_dupwithoffsets(origin, mctx, &ecdb->common.origin); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, ecdb, sizeof(*ecdb)); return (result); } result = isc_mutex_init(&ecdb->lock); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_mutex_init() failed: %s", isc_result_totext(result)); if (dns_name_dynamic(&ecdb->common.origin)) dns_name_free(&ecdb->common.origin, mctx); isc_mem_put(mctx, ecdb, sizeof(*ecdb)); return (ISC_R_UNEXPECTED); } ecdb->references = 1; ISC_LIST_INIT(ecdb->nodes); ecdb->common.mctx = NULL; isc_mem_attach(mctx, &ecdb->common.mctx); ecdb->common.impmagic = ECDB_MAGIC; ecdb->common.magic = DNS_DB_MAGIC; *dbp = (dns_db_t *)ecdb; return (ISC_R_SUCCESS); } /*% * Rdataset Methods */ static void rdataset_disassociate(dns_rdataset_t *rdataset) { dns_db_t *db = rdataset->private1; dns_dbnode_t *node = rdataset->private2; dns_db_detachnode(db, &node); } static isc_result_t rdataset_first(dns_rdataset_t *rdataset) { unsigned char *raw = rdataset->private3; unsigned int count; count = raw[0] * 256 + raw[1]; if (count == 0) { rdataset->private5 = NULL; return (ISC_R_NOMORE); } #if DNS_RDATASET_FIXED raw += 2 + (4 * count); #else raw += 2; #endif /* * The privateuint4 field is the number of rdata beyond the cursor * position, so we decrement the total count by one before storing * it. */ count--; rdataset->privateuint4 = count; rdataset->private5 = raw; return (ISC_R_SUCCESS); } static isc_result_t rdataset_next(dns_rdataset_t *rdataset) { unsigned int count; unsigned int length; unsigned char *raw; count = rdataset->privateuint4; if (count == 0) return (ISC_R_NOMORE); count--; rdataset->privateuint4 = count; raw = rdataset->private5; length = raw[0] * 256 + raw[1]; #if DNS_RDATASET_FIXED raw += length + 4; #else raw += length + 2; #endif rdataset->private5 = raw; return (ISC_R_SUCCESS); } static void rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) { unsigned char *raw = rdataset->private5; isc_region_t r; unsigned int length; unsigned int flags = 0; REQUIRE(raw != NULL); length = raw[0] * 256 + raw[1]; #if DNS_RDATASET_FIXED raw += 4; #else raw += 2; #endif if (rdataset->type == dns_rdatatype_rrsig) { if (*raw & DNS_RDATASLAB_OFFLINE) flags |= DNS_RDATA_OFFLINE; length--; raw++; } r.length = length; r.base = raw; dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r); rdata->flags |= flags; } static void rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { dns_db_t *db = source->private1; dns_dbnode_t *node = source->private2; dns_dbnode_t *cloned_node = NULL; attachnode(db, node, &cloned_node); *target = *source; /* * Reset iterator state. */ target->privateuint4 = 0; target->private5 = NULL; } static unsigned int rdataset_count(dns_rdataset_t *rdataset) { unsigned char *raw = rdataset->private3; unsigned int count; count = raw[0] * 256 + raw[1]; return (count); } static void rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) { rdatasetheader_t *header = rdataset->private3; header--; header->trust = rdataset->trust = trust; } /* * Rdataset Iterator Methods */ static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) { isc_mem_t *mctx; union { dns_rdatasetiter_t *rdatasetiterator; ecdb_rdatasetiter_t *ecdbiterator; } u; REQUIRE(iteratorp != NULL); REQUIRE(DNS_RDATASETITER_VALID(*iteratorp)); u.rdatasetiterator = *iteratorp; mctx = u.ecdbiterator->common.db->mctx; u.ecdbiterator->common.magic = 0; dns_db_detachnode(u.ecdbiterator->common.db, &u.ecdbiterator->common.node); isc_mem_put(mctx, u.ecdbiterator, sizeof(ecdb_rdatasetiter_t)); *iteratorp = NULL; } static isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator) { ecdb_rdatasetiter_t *ecdbiterator = (ecdb_rdatasetiter_t *)iterator; dns_ecdbnode_t *ecdbnode = (dns_ecdbnode_t *)iterator->node; REQUIRE(DNS_RDATASETITER_VALID(iterator)); if (ISC_LIST_EMPTY(ecdbnode->rdatasets)) return (ISC_R_NOMORE); ecdbiterator->current = ISC_LIST_HEAD(ecdbnode->rdatasets); return (ISC_R_SUCCESS); } static isc_result_t rdatasetiter_next(dns_rdatasetiter_t *iterator) { ecdb_rdatasetiter_t *ecdbiterator = (ecdb_rdatasetiter_t *)iterator; REQUIRE(DNS_RDATASETITER_VALID(iterator)); ecdbiterator->current = ISC_LIST_NEXT(ecdbiterator->current, link); if (ecdbiterator->current == NULL) return (ISC_R_NOMORE); else return (ISC_R_SUCCESS); } static void rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) { ecdb_rdatasetiter_t *ecdbiterator = (ecdb_rdatasetiter_t *)iterator; dns_ecdb_t *ecdb; ecdb = (dns_ecdb_t *)iterator->db; REQUIRE(VALID_ECDB(ecdb)); bind_rdataset(ecdb, iterator->node, ecdbiterator->current, rdataset); } bind9-9.10.3.dfsg.P4/lib/dns/tkey.c0000644000470500017500000011776412664710322016063 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dst_internal.h" #define TEMP_BUFFER_SZ 8192 #define TKEY_RANDOM_AMOUNT 16 #ifdef PKCS11CRYPTO #include #endif #define RETERR(x) do { \ result = (x); \ if (result != ISC_R_SUCCESS) \ goto failure; \ } while (0) static void tkey_log(const char *fmt, ...) ISC_FORMAT_PRINTF(1, 2); static void tkey_log(const char *fmt, ...) { va_list ap; va_start(ap, fmt); isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_REQUEST, ISC_LOG_DEBUG(4), fmt, ap); va_end(ap); } static void dumpmessage(dns_message_t *msg) { isc_buffer_t outbuf; unsigned char *output; int len = TEMP_BUFFER_SZ; isc_result_t result; for (;;) { output = isc_mem_get(msg->mctx, len); if (output == NULL) return; isc_buffer_init(&outbuf, output, len); result = dns_message_totext(msg, &dns_master_style_debug, 0, &outbuf); if (result == ISC_R_NOSPACE) { isc_mem_put(msg->mctx, output, len); len *= 2; continue; } if (result == ISC_R_SUCCESS) tkey_log("%.*s", (int)isc_buffer_usedlength(&outbuf), (char *)isc_buffer_base(&outbuf)); else tkey_log("Warning: dns_message_totext: %s", dns_result_totext(result)); break; } if (output != NULL) isc_mem_put(msg->mctx, output, len); } isc_result_t dns_tkeyctx_create(isc_mem_t *mctx, isc_entropy_t *ectx, dns_tkeyctx_t **tctxp) { dns_tkeyctx_t *tctx; REQUIRE(mctx != NULL); REQUIRE(ectx != NULL); REQUIRE(tctxp != NULL && *tctxp == NULL); tctx = isc_mem_get(mctx, sizeof(dns_tkeyctx_t)); if (tctx == NULL) return (ISC_R_NOMEMORY); tctx->mctx = NULL; isc_mem_attach(mctx, &tctx->mctx); tctx->ectx = NULL; isc_entropy_attach(ectx, &tctx->ectx); tctx->dhkey = NULL; tctx->domain = NULL; tctx->gsscred = NULL; tctx->gssapi_keytab = NULL; *tctxp = tctx; return (ISC_R_SUCCESS); } void dns_tkeyctx_destroy(dns_tkeyctx_t **tctxp) { isc_mem_t *mctx; dns_tkeyctx_t *tctx; REQUIRE(tctxp != NULL && *tctxp != NULL); tctx = *tctxp; mctx = tctx->mctx; if (tctx->dhkey != NULL) dst_key_free(&tctx->dhkey); if (tctx->domain != NULL) { if (dns_name_dynamic(tctx->domain)) dns_name_free(tctx->domain, mctx); isc_mem_put(mctx, tctx->domain, sizeof(dns_name_t)); } if (tctx->gssapi_keytab != NULL) { isc_mem_free(mctx, tctx->gssapi_keytab); } if (tctx->gsscred != NULL) dst_gssapi_releasecred(&tctx->gsscred); isc_entropy_detach(&tctx->ectx); isc_mem_put(mctx, tctx, sizeof(dns_tkeyctx_t)); isc_mem_detach(&mctx); *tctxp = NULL; } static isc_result_t add_rdata_to_list(dns_message_t *msg, dns_name_t *name, dns_rdata_t *rdata, isc_uint32_t ttl, dns_namelist_t *namelist) { isc_result_t result; isc_region_t r, newr; dns_rdata_t *newrdata = NULL; dns_name_t *newname = NULL; dns_rdatalist_t *newlist = NULL; dns_rdataset_t *newset = NULL; isc_buffer_t *tmprdatabuf = NULL; RETERR(dns_message_gettemprdata(msg, &newrdata)); dns_rdata_toregion(rdata, &r); RETERR(isc_buffer_allocate(msg->mctx, &tmprdatabuf, r.length)); isc_buffer_availableregion(tmprdatabuf, &newr); memmove(newr.base, r.base, r.length); dns_rdata_fromregion(newrdata, rdata->rdclass, rdata->type, &newr); dns_message_takebuffer(msg, &tmprdatabuf); RETERR(dns_message_gettempname(msg, &newname)); dns_name_init(newname, NULL); RETERR(dns_name_dup(name, msg->mctx, newname)); RETERR(dns_message_gettemprdatalist(msg, &newlist)); newlist->rdclass = newrdata->rdclass; newlist->type = newrdata->type; newlist->ttl = ttl; ISC_LIST_APPEND(newlist->rdata, newrdata, link); RETERR(dns_message_gettemprdataset(msg, &newset)); RETERR(dns_rdatalist_tordataset(newlist, newset)); ISC_LIST_INIT(newname->list); ISC_LIST_APPEND(newname->list, newset, link); ISC_LIST_APPEND(*namelist, newname, link); return (ISC_R_SUCCESS); failure: if (newrdata != NULL) { if (ISC_LINK_LINKED(newrdata, link)) { INSIST(newlist != NULL); ISC_LIST_UNLINK(newlist->rdata, newrdata, link); } dns_message_puttemprdata(msg, &newrdata); } if (newname != NULL) dns_message_puttempname(msg, &newname); if (newset != NULL) { dns_rdataset_disassociate(newset); dns_message_puttemprdataset(msg, &newset); } if (newlist != NULL) dns_message_puttemprdatalist(msg, &newlist); return (result); } static void free_namelist(dns_message_t *msg, dns_namelist_t *namelist) { dns_name_t *name; dns_rdataset_t *set; while (!ISC_LIST_EMPTY(*namelist)) { name = ISC_LIST_HEAD(*namelist); ISC_LIST_UNLINK(*namelist, name, link); while (!ISC_LIST_EMPTY(name->list)) { set = ISC_LIST_HEAD(name->list); ISC_LIST_UNLINK(name->list, set, link); dns_message_puttemprdataset(msg, &set); } dns_message_puttempname(msg, &name); } } static isc_result_t compute_secret(isc_buffer_t *shared, isc_region_t *queryrandomness, isc_region_t *serverrandomness, isc_buffer_t *secret) { isc_md5_t md5ctx; isc_region_t r, r2; unsigned char digests[32]; unsigned int i; isc_buffer_usedregion(shared, &r); /* * MD5 ( query data | DH value ). */ isc_md5_init(&md5ctx); isc_md5_update(&md5ctx, queryrandomness->base, queryrandomness->length); isc_md5_update(&md5ctx, r.base, r.length); isc_md5_final(&md5ctx, digests); /* * MD5 ( server data | DH value ). */ isc_md5_init(&md5ctx); isc_md5_update(&md5ctx, serverrandomness->base, serverrandomness->length); isc_md5_update(&md5ctx, r.base, r.length); isc_md5_final(&md5ctx, &digests[ISC_MD5_DIGESTLENGTH]); /* * XOR ( DH value, MD5-1 | MD5-2). */ isc_buffer_availableregion(secret, &r); isc_buffer_usedregion(shared, &r2); if (r.length < sizeof(digests) || r.length < r2.length) return (ISC_R_NOSPACE); if (r2.length > sizeof(digests)) { memmove(r.base, r2.base, r2.length); for (i = 0; i < sizeof(digests); i++) r.base[i] ^= digests[i]; isc_buffer_add(secret, r2.length); } else { memmove(r.base, digests, sizeof(digests)); for (i = 0; i < r2.length; i++) r.base[i] ^= r2.base[i]; isc_buffer_add(secret, sizeof(digests)); } return (ISC_R_SUCCESS); } static isc_result_t process_dhtkey(dns_message_t *msg, dns_name_t *signer, dns_name_t *name, dns_rdata_tkey_t *tkeyin, dns_tkeyctx_t *tctx, dns_rdata_tkey_t *tkeyout, dns_tsig_keyring_t *ring, dns_namelist_t *namelist) { isc_result_t result = ISC_R_SUCCESS; dns_name_t *keyname, ourname; dns_rdataset_t *keyset = NULL; dns_rdata_t keyrdata = DNS_RDATA_INIT, ourkeyrdata = DNS_RDATA_INIT; isc_boolean_t found_key = ISC_FALSE, found_incompatible = ISC_FALSE; dst_key_t *pubkey = NULL; isc_buffer_t ourkeybuf, *shared = NULL; isc_region_t r, r2, ourkeyr; unsigned char keydata[DST_KEY_MAXSIZE]; unsigned int sharedsize; isc_buffer_t secret; unsigned char *randomdata = NULL, secretdata[256]; dns_ttl_t ttl = 0; if (tctx->dhkey == NULL) { tkey_log("process_dhtkey: tkey-dhkey not defined"); tkeyout->error = dns_tsigerror_badalg; return (DNS_R_REFUSED); } if (!dns_name_equal(&tkeyin->algorithm, DNS_TSIG_HMACMD5_NAME)) { tkey_log("process_dhtkey: algorithms other than " "hmac-md5 are not supported"); tkeyout->error = dns_tsigerror_badalg; return (ISC_R_SUCCESS); } /* * Look for a DH KEY record that will work with ours. */ for (result = dns_message_firstname(msg, DNS_SECTION_ADDITIONAL); result == ISC_R_SUCCESS && !found_key; result = dns_message_nextname(msg, DNS_SECTION_ADDITIONAL)) { keyname = NULL; dns_message_currentname(msg, DNS_SECTION_ADDITIONAL, &keyname); keyset = NULL; result = dns_message_findtype(keyname, dns_rdatatype_key, 0, &keyset); if (result != ISC_R_SUCCESS) continue; for (result = dns_rdataset_first(keyset); result == ISC_R_SUCCESS && !found_key; result = dns_rdataset_next(keyset)) { dns_rdataset_current(keyset, &keyrdata); pubkey = NULL; result = dns_dnssec_keyfromrdata(keyname, &keyrdata, msg->mctx, &pubkey); if (result != ISC_R_SUCCESS) { dns_rdata_reset(&keyrdata); continue; } if (dst_key_alg(pubkey) == DNS_KEYALG_DH) { if (dst_key_paramcompare(pubkey, tctx->dhkey)) { found_key = ISC_TRUE; ttl = keyset->ttl; break; } else found_incompatible = ISC_TRUE; } dst_key_free(&pubkey); dns_rdata_reset(&keyrdata); } } if (!found_key) { if (found_incompatible) { tkey_log("process_dhtkey: found an incompatible key"); tkeyout->error = dns_tsigerror_badkey; return (ISC_R_SUCCESS); } else { tkey_log("process_dhtkey: failed to find a key"); return (DNS_R_FORMERR); } } RETERR(add_rdata_to_list(msg, keyname, &keyrdata, ttl, namelist)); isc_buffer_init(&ourkeybuf, keydata, sizeof(keydata)); RETERR(dst_key_todns(tctx->dhkey, &ourkeybuf)); isc_buffer_usedregion(&ourkeybuf, &ourkeyr); dns_rdata_fromregion(&ourkeyrdata, dns_rdataclass_any, dns_rdatatype_key, &ourkeyr); dns_name_init(&ourname, NULL); dns_name_clone(dst_key_name(tctx->dhkey), &ourname); /* * XXXBEW The TTL should be obtained from the database, if it exists. */ RETERR(add_rdata_to_list(msg, &ourname, &ourkeyrdata, 0, namelist)); RETERR(dst_key_secretsize(tctx->dhkey, &sharedsize)); RETERR(isc_buffer_allocate(msg->mctx, &shared, sharedsize)); result = dst_key_computesecret(pubkey, tctx->dhkey, shared); if (result != ISC_R_SUCCESS) { tkey_log("process_dhtkey: failed to compute shared secret: %s", isc_result_totext(result)); goto failure; } dst_key_free(&pubkey); isc_buffer_init(&secret, secretdata, sizeof(secretdata)); randomdata = isc_mem_get(tkeyout->mctx, TKEY_RANDOM_AMOUNT); if (randomdata == NULL) goto failure; result = dst__entropy_getdata(randomdata, TKEY_RANDOM_AMOUNT, ISC_FALSE); if (result != ISC_R_SUCCESS) { tkey_log("process_dhtkey: failed to obtain entropy: %s", isc_result_totext(result)); goto failure; } r.base = randomdata; r.length = TKEY_RANDOM_AMOUNT; r2.base = tkeyin->key; r2.length = tkeyin->keylen; RETERR(compute_secret(shared, &r2, &r, &secret)); isc_buffer_free(&shared); RETERR(dns_tsigkey_create(name, &tkeyin->algorithm, isc_buffer_base(&secret), isc_buffer_usedlength(&secret), ISC_TRUE, signer, tkeyin->inception, tkeyin->expire, ring->mctx, ring, NULL)); /* This key is good for a long time */ tkeyout->inception = tkeyin->inception; tkeyout->expire = tkeyin->expire; tkeyout->key = randomdata; tkeyout->keylen = TKEY_RANDOM_AMOUNT; return (ISC_R_SUCCESS); failure: if (!ISC_LIST_EMPTY(*namelist)) free_namelist(msg, namelist); if (shared != NULL) isc_buffer_free(&shared); if (pubkey != NULL) dst_key_free(&pubkey); if (randomdata != NULL) isc_mem_put(tkeyout->mctx, randomdata, TKEY_RANDOM_AMOUNT); return (result); } static isc_result_t process_gsstkey(dns_name_t *name, dns_rdata_tkey_t *tkeyin, dns_tkeyctx_t *tctx, dns_rdata_tkey_t *tkeyout, dns_tsig_keyring_t *ring) { isc_result_t result = ISC_R_SUCCESS; dst_key_t *dstkey = NULL; dns_tsigkey_t *tsigkey = NULL; dns_fixedname_t principal; isc_stdtime_t now; isc_region_t intoken; isc_buffer_t *outtoken = NULL; gss_ctx_id_t gss_ctx = NULL; /* * You have to define either a gss credential (principal) to * accept with tkey-gssapi-credential, or you have to * configure a specific keytab (with tkey-gssapi-keytab) in * order to use gsstkey */ if (tctx->gsscred == NULL && tctx->gssapi_keytab == NULL) { tkey_log("process_gsstkey(): no tkey-gssapi-credential " "or tkey-gssapi-keytab configured"); return (ISC_R_NOPERM); } if (!dns_name_equal(&tkeyin->algorithm, DNS_TSIG_GSSAPI_NAME) && !dns_name_equal(&tkeyin->algorithm, DNS_TSIG_GSSAPIMS_NAME)) { tkeyout->error = dns_tsigerror_badalg; tkey_log("process_gsstkey(): dns_tsigerror_badalg"); /* XXXSRA */ return (ISC_R_SUCCESS); } /* * XXXDCL need to check for key expiry per 4.1.1 * XXXDCL need a way to check fully established, perhaps w/key_flags */ intoken.base = tkeyin->key; intoken.length = tkeyin->keylen; result = dns_tsigkey_find(&tsigkey, name, &tkeyin->algorithm, ring); if (result == ISC_R_SUCCESS) gss_ctx = dst_key_getgssctx(tsigkey->key); dns_fixedname_init(&principal); /* * Note that tctx->gsscred may be NULL if tctx->gssapi_keytab is set */ result = dst_gssapi_acceptctx(tctx->gsscred, tctx->gssapi_keytab, &intoken, &outtoken, &gss_ctx, dns_fixedname_name(&principal), tctx->mctx); if (result == DNS_R_INVALIDTKEY) { if (tsigkey != NULL) dns_tsigkey_detach(&tsigkey); tkeyout->error = dns_tsigerror_badkey; tkey_log("process_gsstkey(): dns_tsigerror_badkey"); /* XXXSRA */ return (ISC_R_SUCCESS); } if (result != DNS_R_CONTINUE && result != ISC_R_SUCCESS) goto failure; /* * XXXDCL Section 4.1.3: Limit GSS_S_CONTINUE_NEEDED to 10 times. */ isc_stdtime_get(&now); if (tsigkey == NULL) { #ifdef GSSAPI OM_uint32 gret, minor, lifetime; #endif isc_uint32_t expire; RETERR(dst_key_fromgssapi(name, gss_ctx, ring->mctx, &dstkey, &intoken)); /* * Limit keys to 1 hour or the context's lifetime whichever * is smaller. */ expire = now + 3600; #ifdef GSSAPI gret = gss_context_time(&minor, gss_ctx, &lifetime); if (gret == GSS_S_COMPLETE && now + lifetime < expire) expire = now + lifetime; #endif RETERR(dns_tsigkey_createfromkey(name, &tkeyin->algorithm, dstkey, ISC_TRUE, dns_fixedname_name(&principal), now, expire, ring->mctx, ring, NULL)); dst_key_free(&dstkey); tkeyout->inception = now; tkeyout->expire = expire; } else { tkeyout->inception = tsigkey->inception; tkeyout->expire = tsigkey->expire; dns_tsigkey_detach(&tsigkey); } if (outtoken) { tkeyout->key = isc_mem_get(tkeyout->mctx, isc_buffer_usedlength(outtoken)); if (tkeyout->key == NULL) { result = ISC_R_NOMEMORY; goto failure; } tkeyout->keylen = isc_buffer_usedlength(outtoken); memmove(tkeyout->key, isc_buffer_base(outtoken), isc_buffer_usedlength(outtoken)); isc_buffer_free(&outtoken); } else { tkeyout->key = isc_mem_get(tkeyout->mctx, tkeyin->keylen); if (tkeyout->key == NULL) { result = ISC_R_NOMEMORY; goto failure; } tkeyout->keylen = tkeyin->keylen; memmove(tkeyout->key, tkeyin->key, tkeyin->keylen); } tkeyout->error = dns_rcode_noerror; tkey_log("process_gsstkey(): dns_tsigerror_noerror"); /* XXXSRA */ return (ISC_R_SUCCESS); failure: if (tsigkey != NULL) dns_tsigkey_detach(&tsigkey); if (dstkey != NULL) dst_key_free(&dstkey); if (outtoken != NULL) isc_buffer_free(&outtoken); tkey_log("process_gsstkey(): %s", isc_result_totext(result)); /* XXXSRA */ return (result); } static isc_result_t process_deletetkey(dns_name_t *signer, dns_name_t *name, dns_rdata_tkey_t *tkeyin, dns_rdata_tkey_t *tkeyout, dns_tsig_keyring_t *ring) { isc_result_t result; dns_tsigkey_t *tsigkey = NULL; dns_name_t *identity; result = dns_tsigkey_find(&tsigkey, name, &tkeyin->algorithm, ring); if (result != ISC_R_SUCCESS) { tkeyout->error = dns_tsigerror_badname; return (ISC_R_SUCCESS); } /* * Only allow a delete if the identity that created the key is the * same as the identity that signed the message. */ identity = dns_tsigkey_identity(tsigkey); if (identity == NULL || !dns_name_equal(identity, signer)) { dns_tsigkey_detach(&tsigkey); return (DNS_R_REFUSED); } /* * Set the key to be deleted when no references are left. If the key * was not generated with TKEY and is in the config file, it may be * reloaded later. */ dns_tsigkey_setdeleted(tsigkey); /* Release the reference */ dns_tsigkey_detach(&tsigkey); return (ISC_R_SUCCESS); } isc_result_t dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx, dns_tsig_keyring_t *ring) { isc_result_t result = ISC_R_SUCCESS; dns_rdata_tkey_t tkeyin, tkeyout; isc_boolean_t freetkeyin = ISC_FALSE; dns_name_t *qname, *name, *keyname, *signer, tsigner; dns_fixedname_t fkeyname; dns_rdataset_t *tkeyset; dns_rdata_t rdata; dns_namelist_t namelist; char tkeyoutdata[512]; isc_buffer_t tkeyoutbuf; REQUIRE(msg != NULL); REQUIRE(tctx != NULL); REQUIRE(ring != NULL); ISC_LIST_INIT(namelist); /* * Interpret the question section. */ result = dns_message_firstname(msg, DNS_SECTION_QUESTION); if (result != ISC_R_SUCCESS) return (DNS_R_FORMERR); qname = NULL; dns_message_currentname(msg, DNS_SECTION_QUESTION, &qname); /* * Look for a TKEY record that matches the question. */ tkeyset = NULL; name = NULL; result = dns_message_findname(msg, DNS_SECTION_ADDITIONAL, qname, dns_rdatatype_tkey, 0, &name, &tkeyset); if (result != ISC_R_SUCCESS) { /* * Try the answer section, since that's where Win2000 * puts it. */ name = NULL; if (dns_message_findname(msg, DNS_SECTION_ANSWER, qname, dns_rdatatype_tkey, 0, &name, &tkeyset) != ISC_R_SUCCESS) { result = DNS_R_FORMERR; tkey_log("dns_tkey_processquery: couldn't find a TKEY " "matching the question"); goto failure; } } result = dns_rdataset_first(tkeyset); if (result != ISC_R_SUCCESS) { result = DNS_R_FORMERR; goto failure; } dns_rdata_init(&rdata); dns_rdataset_current(tkeyset, &rdata); RETERR(dns_rdata_tostruct(&rdata, &tkeyin, NULL)); freetkeyin = ISC_TRUE; if (tkeyin.error != dns_rcode_noerror) { result = DNS_R_FORMERR; goto failure; } /* * Before we go any farther, verify that the message was signed. * GSSAPI TKEY doesn't require a signature, the rest do. */ dns_name_init(&tsigner, NULL); result = dns_message_signer(msg, &tsigner); if (result != ISC_R_SUCCESS) { if (tkeyin.mode == DNS_TKEYMODE_GSSAPI && result == ISC_R_NOTFOUND) signer = NULL; else { tkey_log("dns_tkey_processquery: query was not " "properly signed - rejecting"); result = DNS_R_FORMERR; goto failure; } } else signer = &tsigner; tkeyout.common.rdclass = tkeyin.common.rdclass; tkeyout.common.rdtype = tkeyin.common.rdtype; ISC_LINK_INIT(&tkeyout.common, link); tkeyout.mctx = msg->mctx; dns_name_init(&tkeyout.algorithm, NULL); dns_name_clone(&tkeyin.algorithm, &tkeyout.algorithm); tkeyout.inception = tkeyout.expire = 0; tkeyout.mode = tkeyin.mode; tkeyout.error = 0; tkeyout.keylen = tkeyout.otherlen = 0; tkeyout.key = tkeyout.other = NULL; /* * A delete operation must have a fully specified key name. If this * is not a delete, we do the following: * if (qname != ".") * keyname = qname + defaultdomain * else * keyname = + defaultdomain */ if (tkeyin.mode != DNS_TKEYMODE_DELETE) { dns_tsigkey_t *tsigkey = NULL; if (tctx->domain == NULL && tkeyin.mode != DNS_TKEYMODE_GSSAPI) { tkey_log("dns_tkey_processquery: tkey-domain not set"); result = DNS_R_REFUSED; goto failure; } dns_fixedname_init(&fkeyname); keyname = dns_fixedname_name(&fkeyname); if (!dns_name_equal(qname, dns_rootname)) { unsigned int n = dns_name_countlabels(qname); RUNTIME_CHECK(dns_name_copy(qname, keyname, NULL) == ISC_R_SUCCESS); dns_name_getlabelsequence(keyname, 0, n - 1, keyname); } else { static char hexdigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; unsigned char randomdata[16]; char randomtext[32]; isc_buffer_t b; unsigned int i, j; result = isc_entropy_getdata(tctx->ectx, randomdata, sizeof(randomdata), NULL, 0); if (result != ISC_R_SUCCESS) goto failure; for (i = 0, j = 0; i < sizeof(randomdata); i++) { unsigned char val = randomdata[i]; randomtext[j++] = hexdigits[val >> 4]; randomtext[j++] = hexdigits[val & 0xF]; } isc_buffer_init(&b, randomtext, sizeof(randomtext)); isc_buffer_add(&b, sizeof(randomtext)); result = dns_name_fromtext(keyname, &b, NULL, 0, NULL); if (result != ISC_R_SUCCESS) goto failure; } if (tkeyin.mode == DNS_TKEYMODE_GSSAPI) { /* Yup. This is a hack */ result = dns_name_concatenate(keyname, dns_rootname, keyname, NULL); if (result != ISC_R_SUCCESS) goto failure; } else { result = dns_name_concatenate(keyname, tctx->domain, keyname, NULL); if (result != ISC_R_SUCCESS) goto failure; } result = dns_tsigkey_find(&tsigkey, keyname, NULL, ring); if (result == ISC_R_SUCCESS) { tkeyout.error = dns_tsigerror_badname; dns_tsigkey_detach(&tsigkey); goto failure_with_tkey; } else if (result != ISC_R_NOTFOUND) goto failure; } else keyname = qname; switch (tkeyin.mode) { case DNS_TKEYMODE_DIFFIEHELLMAN: tkeyout.error = dns_rcode_noerror; RETERR(process_dhtkey(msg, signer, keyname, &tkeyin, tctx, &tkeyout, ring, &namelist)); break; case DNS_TKEYMODE_GSSAPI: tkeyout.error = dns_rcode_noerror; RETERR(process_gsstkey(keyname, &tkeyin, tctx, &tkeyout, ring)); break; case DNS_TKEYMODE_DELETE: tkeyout.error = dns_rcode_noerror; RETERR(process_deletetkey(signer, keyname, &tkeyin, &tkeyout, ring)); break; case DNS_TKEYMODE_SERVERASSIGNED: case DNS_TKEYMODE_RESOLVERASSIGNED: result = DNS_R_NOTIMP; goto failure; default: tkeyout.error = dns_tsigerror_badmode; } failure_with_tkey: dns_rdata_init(&rdata); isc_buffer_init(&tkeyoutbuf, tkeyoutdata, sizeof(tkeyoutdata)); result = dns_rdata_fromstruct(&rdata, tkeyout.common.rdclass, tkeyout.common.rdtype, &tkeyout, &tkeyoutbuf); if (freetkeyin) { dns_rdata_freestruct(&tkeyin); freetkeyin = ISC_FALSE; } if (tkeyout.key != NULL) isc_mem_put(tkeyout.mctx, tkeyout.key, tkeyout.keylen); if (tkeyout.other != NULL) isc_mem_put(tkeyout.mctx, tkeyout.other, tkeyout.otherlen); if (result != ISC_R_SUCCESS) goto failure; RETERR(add_rdata_to_list(msg, keyname, &rdata, 0, &namelist)); RETERR(dns_message_reply(msg, ISC_TRUE)); name = ISC_LIST_HEAD(namelist); while (name != NULL) { dns_name_t *next = ISC_LIST_NEXT(name, link); ISC_LIST_UNLINK(namelist, name, link); dns_message_addname(msg, name, DNS_SECTION_ANSWER); name = next; } return (ISC_R_SUCCESS); failure: if (freetkeyin) dns_rdata_freestruct(&tkeyin); if (!ISC_LIST_EMPTY(namelist)) free_namelist(msg, &namelist); return (result); } static isc_result_t buildquery(dns_message_t *msg, dns_name_t *name, dns_rdata_tkey_t *tkey, isc_boolean_t win2k) { dns_name_t *qname = NULL, *aname = NULL; dns_rdataset_t *question = NULL, *tkeyset = NULL; dns_rdatalist_t *tkeylist = NULL; dns_rdata_t *rdata = NULL; isc_buffer_t *dynbuf = NULL, *anamebuf = NULL, *qnamebuf = NULL; isc_result_t result; unsigned int len; REQUIRE(msg != NULL); REQUIRE(name != NULL); REQUIRE(tkey != NULL); RETERR(dns_message_gettempname(msg, &qname)); RETERR(dns_message_gettempname(msg, &aname)); RETERR(dns_message_gettemprdataset(msg, &question)); dns_rdataset_makequestion(question, dns_rdataclass_any, dns_rdatatype_tkey); len = 16 + tkey->algorithm.length + tkey->keylen + tkey->otherlen; RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, len)); RETERR(isc_buffer_allocate(msg->mctx, &anamebuf, name->length)); RETERR(isc_buffer_allocate(msg->mctx, &qnamebuf, name->length)); RETERR(dns_message_gettemprdata(msg, &rdata)); RETERR(dns_rdata_fromstruct(rdata, dns_rdataclass_any, dns_rdatatype_tkey, tkey, dynbuf)); dns_message_takebuffer(msg, &dynbuf); RETERR(dns_message_gettemprdatalist(msg, &tkeylist)); tkeylist->rdclass = dns_rdataclass_any; tkeylist->type = dns_rdatatype_tkey; ISC_LIST_APPEND(tkeylist->rdata, rdata, link); RETERR(dns_message_gettemprdataset(msg, &tkeyset)); RETERR(dns_rdatalist_tordataset(tkeylist, tkeyset)); dns_name_init(qname, NULL); RETERR(dns_name_copy(name, qname, qnamebuf)); dns_name_init(aname, NULL); RETERR(dns_name_copy(name, aname, anamebuf)); ISC_LIST_APPEND(qname->list, question, link); ISC_LIST_APPEND(aname->list, tkeyset, link); dns_message_addname(msg, qname, DNS_SECTION_QUESTION); dns_message_takebuffer(msg, &qnamebuf); /* * Windows 2000 needs this in the answer section, not the additional * section where the RFC specifies. */ if (win2k) dns_message_addname(msg, aname, DNS_SECTION_ANSWER); else dns_message_addname(msg, aname, DNS_SECTION_ADDITIONAL); dns_message_takebuffer(msg, &anamebuf); return (ISC_R_SUCCESS); failure: if (qname != NULL) dns_message_puttempname(msg, &qname); if (aname != NULL) dns_message_puttempname(msg, &aname); if (question != NULL) { dns_rdataset_disassociate(question); dns_message_puttemprdataset(msg, &question); } if (dynbuf != NULL) isc_buffer_free(&dynbuf); if (qnamebuf != NULL) isc_buffer_free(&qnamebuf); if (anamebuf != NULL) isc_buffer_free(&anamebuf); return (result); } isc_result_t dns_tkey_builddhquery(dns_message_t *msg, dst_key_t *key, dns_name_t *name, dns_name_t *algorithm, isc_buffer_t *nonce, isc_uint32_t lifetime) { dns_rdata_tkey_t tkey; dns_rdata_t *rdata = NULL; isc_buffer_t *dynbuf = NULL; isc_region_t r; dns_name_t keyname; dns_namelist_t namelist; isc_result_t result; isc_stdtime_t now; REQUIRE(msg != NULL); REQUIRE(key != NULL); REQUIRE(dst_key_alg(key) == DNS_KEYALG_DH); REQUIRE(dst_key_isprivate(key)); REQUIRE(name != NULL); REQUIRE(algorithm != NULL); tkey.common.rdclass = dns_rdataclass_any; tkey.common.rdtype = dns_rdatatype_tkey; ISC_LINK_INIT(&tkey.common, link); tkey.mctx = msg->mctx; dns_name_init(&tkey.algorithm, NULL); dns_name_clone(algorithm, &tkey.algorithm); isc_stdtime_get(&now); tkey.inception = now; tkey.expire = now + lifetime; tkey.mode = DNS_TKEYMODE_DIFFIEHELLMAN; if (nonce != NULL) isc_buffer_usedregion(nonce, &r); else { r.base = isc_mem_get(msg->mctx, 0); r.length = 0; } tkey.error = 0; tkey.key = r.base; tkey.keylen = r.length; tkey.other = NULL; tkey.otherlen = 0; RETERR(buildquery(msg, name, &tkey, ISC_FALSE)); if (nonce == NULL) isc_mem_put(msg->mctx, r.base, 0); RETERR(dns_message_gettemprdata(msg, &rdata)); RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, 1024)); RETERR(dst_key_todns(key, dynbuf)); isc_buffer_usedregion(dynbuf, &r); dns_rdata_fromregion(rdata, dns_rdataclass_any, dns_rdatatype_key, &r); dns_message_takebuffer(msg, &dynbuf); dns_name_init(&keyname, NULL); dns_name_clone(dst_key_name(key), &keyname); ISC_LIST_INIT(namelist); RETERR(add_rdata_to_list(msg, &keyname, rdata, 0, &namelist)); name = ISC_LIST_HEAD(namelist); while (name != NULL) { dns_name_t *next = ISC_LIST_NEXT(name, link); ISC_LIST_UNLINK(namelist, name, link); dns_message_addname(msg, name, DNS_SECTION_ADDITIONAL); name = next; } return (ISC_R_SUCCESS); failure: if (dynbuf != NULL) isc_buffer_free(&dynbuf); return (result); } isc_result_t dns_tkey_buildgssquery(dns_message_t *msg, dns_name_t *name, dns_name_t *gname, isc_buffer_t *intoken, isc_uint32_t lifetime, gss_ctx_id_t *context, isc_boolean_t win2k, isc_mem_t *mctx, char **err_message) { dns_rdata_tkey_t tkey; isc_result_t result; isc_stdtime_t now; isc_buffer_t token; unsigned char array[TEMP_BUFFER_SZ]; UNUSED(intoken); REQUIRE(msg != NULL); REQUIRE(name != NULL); REQUIRE(gname != NULL); REQUIRE(context != NULL); REQUIRE(mctx != NULL); isc_buffer_init(&token, array, sizeof(array)); result = dst_gssapi_initctx(gname, NULL, &token, context, mctx, err_message); if (result != DNS_R_CONTINUE && result != ISC_R_SUCCESS) return (result); tkey.common.rdclass = dns_rdataclass_any; tkey.common.rdtype = dns_rdatatype_tkey; ISC_LINK_INIT(&tkey.common, link); tkey.mctx = NULL; dns_name_init(&tkey.algorithm, NULL); if (win2k) dns_name_clone(DNS_TSIG_GSSAPIMS_NAME, &tkey.algorithm); else dns_name_clone(DNS_TSIG_GSSAPI_NAME, &tkey.algorithm); isc_stdtime_get(&now); tkey.inception = now; tkey.expire = now + lifetime; tkey.mode = DNS_TKEYMODE_GSSAPI; tkey.error = 0; tkey.key = isc_buffer_base(&token); tkey.keylen = isc_buffer_usedlength(&token); tkey.other = NULL; tkey.otherlen = 0; return (buildquery(msg, name, &tkey, win2k)); } isc_result_t dns_tkey_builddeletequery(dns_message_t *msg, dns_tsigkey_t *key) { dns_rdata_tkey_t tkey; REQUIRE(msg != NULL); REQUIRE(key != NULL); tkey.common.rdclass = dns_rdataclass_any; tkey.common.rdtype = dns_rdatatype_tkey; ISC_LINK_INIT(&tkey.common, link); tkey.mctx = msg->mctx; dns_name_init(&tkey.algorithm, NULL); dns_name_clone(key->algorithm, &tkey.algorithm); tkey.inception = tkey.expire = 0; tkey.mode = DNS_TKEYMODE_DELETE; tkey.error = 0; tkey.keylen = tkey.otherlen = 0; tkey.key = tkey.other = NULL; return (buildquery(msg, &key->name, &tkey, ISC_FALSE)); } static isc_result_t find_tkey(dns_message_t *msg, dns_name_t **name, dns_rdata_t *rdata, int section) { dns_rdataset_t *tkeyset; isc_result_t result; result = dns_message_firstname(msg, section); while (result == ISC_R_SUCCESS) { *name = NULL; dns_message_currentname(msg, section, name); tkeyset = NULL; result = dns_message_findtype(*name, dns_rdatatype_tkey, 0, &tkeyset); if (result == ISC_R_SUCCESS) { result = dns_rdataset_first(tkeyset); if (result != ISC_R_SUCCESS) return (result); dns_rdataset_current(tkeyset, rdata); return (ISC_R_SUCCESS); } result = dns_message_nextname(msg, section); } if (result == ISC_R_NOMORE) return (ISC_R_NOTFOUND); return (result); } isc_result_t dns_tkey_processdhresponse(dns_message_t *qmsg, dns_message_t *rmsg, dst_key_t *key, isc_buffer_t *nonce, dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring) { dns_rdata_t qtkeyrdata = DNS_RDATA_INIT, rtkeyrdata = DNS_RDATA_INIT; dns_name_t keyname, *tkeyname, *theirkeyname, *ourkeyname, *tempname; dns_rdataset_t *theirkeyset = NULL, *ourkeyset = NULL; dns_rdata_t theirkeyrdata = DNS_RDATA_INIT; dst_key_t *theirkey = NULL; dns_rdata_tkey_t qtkey, rtkey; unsigned char secretdata[256]; unsigned int sharedsize; isc_buffer_t *shared = NULL, secret; isc_region_t r, r2; isc_result_t result; isc_boolean_t freertkey = ISC_FALSE; REQUIRE(qmsg != NULL); REQUIRE(rmsg != NULL); REQUIRE(key != NULL); REQUIRE(dst_key_alg(key) == DNS_KEYALG_DH); REQUIRE(dst_key_isprivate(key)); if (outkey != NULL) REQUIRE(*outkey == NULL); if (rmsg->rcode != dns_rcode_noerror) return (ISC_RESULTCLASS_DNSRCODE + rmsg->rcode); RETERR(find_tkey(rmsg, &tkeyname, &rtkeyrdata, DNS_SECTION_ANSWER)); RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, NULL)); freertkey = ISC_TRUE; RETERR(find_tkey(qmsg, &tempname, &qtkeyrdata, DNS_SECTION_ADDITIONAL)); RETERR(dns_rdata_tostruct(&qtkeyrdata, &qtkey, NULL)); if (rtkey.error != dns_rcode_noerror || rtkey.mode != DNS_TKEYMODE_DIFFIEHELLMAN || rtkey.mode != qtkey.mode || !dns_name_equal(&rtkey.algorithm, &qtkey.algorithm) || rmsg->rcode != dns_rcode_noerror) { tkey_log("dns_tkey_processdhresponse: tkey mode invalid " "or error set(1)"); result = DNS_R_INVALIDTKEY; dns_rdata_freestruct(&qtkey); goto failure; } dns_rdata_freestruct(&qtkey); dns_name_init(&keyname, NULL); dns_name_clone(dst_key_name(key), &keyname); ourkeyname = NULL; ourkeyset = NULL; RETERR(dns_message_findname(rmsg, DNS_SECTION_ANSWER, &keyname, dns_rdatatype_key, 0, &ourkeyname, &ourkeyset)); result = dns_message_firstname(rmsg, DNS_SECTION_ANSWER); while (result == ISC_R_SUCCESS) { theirkeyname = NULL; dns_message_currentname(rmsg, DNS_SECTION_ANSWER, &theirkeyname); if (dns_name_equal(theirkeyname, ourkeyname)) goto next; theirkeyset = NULL; result = dns_message_findtype(theirkeyname, dns_rdatatype_key, 0, &theirkeyset); if (result == ISC_R_SUCCESS) { RETERR(dns_rdataset_first(theirkeyset)); break; } next: result = dns_message_nextname(rmsg, DNS_SECTION_ANSWER); } if (theirkeyset == NULL) { tkey_log("dns_tkey_processdhresponse: failed to find server " "key"); result = ISC_R_NOTFOUND; goto failure; } dns_rdataset_current(theirkeyset, &theirkeyrdata); RETERR(dns_dnssec_keyfromrdata(theirkeyname, &theirkeyrdata, rmsg->mctx, &theirkey)); RETERR(dst_key_secretsize(key, &sharedsize)); RETERR(isc_buffer_allocate(rmsg->mctx, &shared, sharedsize)); RETERR(dst_key_computesecret(theirkey, key, shared)); isc_buffer_init(&secret, secretdata, sizeof(secretdata)); r.base = rtkey.key; r.length = rtkey.keylen; if (nonce != NULL) isc_buffer_usedregion(nonce, &r2); else { r2.base = isc_mem_get(rmsg->mctx, 0); r2.length = 0; } RETERR(compute_secret(shared, &r2, &r, &secret)); if (nonce == NULL) isc_mem_put(rmsg->mctx, r2.base, 0); isc_buffer_usedregion(&secret, &r); result = dns_tsigkey_create(tkeyname, &rtkey.algorithm, r.base, r.length, ISC_TRUE, NULL, rtkey.inception, rtkey.expire, rmsg->mctx, ring, outkey); isc_buffer_free(&shared); dns_rdata_freestruct(&rtkey); dst_key_free(&theirkey); return (result); failure: if (shared != NULL) isc_buffer_free(&shared); if (theirkey != NULL) dst_key_free(&theirkey); if (freertkey) dns_rdata_freestruct(&rtkey); return (result); } isc_result_t dns_tkey_processgssresponse(dns_message_t *qmsg, dns_message_t *rmsg, dns_name_t *gname, gss_ctx_id_t *context, isc_buffer_t *outtoken, dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring, char **err_message) { dns_rdata_t rtkeyrdata = DNS_RDATA_INIT, qtkeyrdata = DNS_RDATA_INIT; dns_name_t *tkeyname; dns_rdata_tkey_t rtkey, qtkey; dst_key_t *dstkey = NULL; isc_buffer_t intoken; isc_result_t result; unsigned char array[1024]; REQUIRE(outtoken != NULL); REQUIRE(qmsg != NULL); REQUIRE(rmsg != NULL); REQUIRE(gname != NULL); REQUIRE(ring != NULL); if (outkey != NULL) REQUIRE(*outkey == NULL); if (rmsg->rcode != dns_rcode_noerror) return (ISC_RESULTCLASS_DNSRCODE + rmsg->rcode); RETERR(find_tkey(rmsg, &tkeyname, &rtkeyrdata, DNS_SECTION_ANSWER)); RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, NULL)); /* * Win2k puts the item in the ANSWER section, while the RFC * specifies it should be in the ADDITIONAL section. Check first * where it should be, and then where it may be. */ result = find_tkey(qmsg, &tkeyname, &qtkeyrdata, DNS_SECTION_ADDITIONAL); if (result == ISC_R_NOTFOUND) result = find_tkey(qmsg, &tkeyname, &qtkeyrdata, DNS_SECTION_ANSWER); if (result != ISC_R_SUCCESS) goto failure; RETERR(dns_rdata_tostruct(&qtkeyrdata, &qtkey, NULL)); if (rtkey.error != dns_rcode_noerror || rtkey.mode != DNS_TKEYMODE_GSSAPI || !dns_name_equal(&rtkey.algorithm, &qtkey.algorithm)) { tkey_log("dns_tkey_processgssresponse: tkey mode invalid " "or error set(2) %d", rtkey.error); dumpmessage(qmsg); dumpmessage(rmsg); result = DNS_R_INVALIDTKEY; goto failure; } isc_buffer_init(outtoken, array, sizeof(array)); isc_buffer_init(&intoken, rtkey.key, rtkey.keylen); RETERR(dst_gssapi_initctx(gname, &intoken, outtoken, context, ring->mctx, err_message)); RETERR(dst_key_fromgssapi(dns_rootname, *context, rmsg->mctx, &dstkey, NULL)); RETERR(dns_tsigkey_createfromkey(tkeyname, DNS_TSIG_GSSAPI_NAME, dstkey, ISC_FALSE, NULL, rtkey.inception, rtkey.expire, ring->mctx, ring, outkey)); dst_key_free(&dstkey); dns_rdata_freestruct(&rtkey); return (result); failure: /* * XXXSRA This probably leaks memory from rtkey and qtkey. */ if (dstkey != NULL) dst_key_free(&dstkey); return (result); } isc_result_t dns_tkey_processdeleteresponse(dns_message_t *qmsg, dns_message_t *rmsg, dns_tsig_keyring_t *ring) { dns_rdata_t qtkeyrdata = DNS_RDATA_INIT, rtkeyrdata = DNS_RDATA_INIT; dns_name_t *tkeyname, *tempname; dns_rdata_tkey_t qtkey, rtkey; dns_tsigkey_t *tsigkey = NULL; isc_result_t result; REQUIRE(qmsg != NULL); REQUIRE(rmsg != NULL); if (rmsg->rcode != dns_rcode_noerror) return(ISC_RESULTCLASS_DNSRCODE + rmsg->rcode); RETERR(find_tkey(rmsg, &tkeyname, &rtkeyrdata, DNS_SECTION_ANSWER)); RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, NULL)); RETERR(find_tkey(qmsg, &tempname, &qtkeyrdata, DNS_SECTION_ADDITIONAL)); RETERR(dns_rdata_tostruct(&qtkeyrdata, &qtkey, NULL)); if (rtkey.error != dns_rcode_noerror || rtkey.mode != DNS_TKEYMODE_DELETE || rtkey.mode != qtkey.mode || !dns_name_equal(&rtkey.algorithm, &qtkey.algorithm) || rmsg->rcode != dns_rcode_noerror) { tkey_log("dns_tkey_processdeleteresponse: tkey mode invalid " "or error set(3)"); result = DNS_R_INVALIDTKEY; dns_rdata_freestruct(&qtkey); dns_rdata_freestruct(&rtkey); goto failure; } dns_rdata_freestruct(&qtkey); RETERR(dns_tsigkey_find(&tsigkey, tkeyname, &rtkey.algorithm, ring)); dns_rdata_freestruct(&rtkey); /* * Mark the key as deleted. */ dns_tsigkey_setdeleted(tsigkey); /* * Release the reference. */ dns_tsigkey_detach(&tsigkey); failure: return (result); } isc_result_t dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg, dns_name_t *server, gss_ctx_id_t *context, dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring, isc_boolean_t win2k, char **err_message) { dns_rdata_t rtkeyrdata = DNS_RDATA_INIT, qtkeyrdata = DNS_RDATA_INIT; dns_name_t *tkeyname; dns_rdata_tkey_t rtkey, qtkey; isc_buffer_t intoken, outtoken; dst_key_t *dstkey = NULL; isc_result_t result; unsigned char array[1024]; isc_boolean_t freertkey = ISC_FALSE; REQUIRE(qmsg != NULL); REQUIRE(rmsg != NULL); REQUIRE(server != NULL); if (outkey != NULL) REQUIRE(*outkey == NULL); if (rmsg->rcode != dns_rcode_noerror) return (ISC_RESULTCLASS_DNSRCODE + rmsg->rcode); RETERR(find_tkey(rmsg, &tkeyname, &rtkeyrdata, DNS_SECTION_ANSWER)); RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, NULL)); freertkey = ISC_TRUE; if (win2k == ISC_TRUE) RETERR(find_tkey(qmsg, &tkeyname, &qtkeyrdata, DNS_SECTION_ANSWER)); else RETERR(find_tkey(qmsg, &tkeyname, &qtkeyrdata, DNS_SECTION_ADDITIONAL)); RETERR(dns_rdata_tostruct(&qtkeyrdata, &qtkey, NULL)); if (rtkey.error != dns_rcode_noerror || rtkey.mode != DNS_TKEYMODE_GSSAPI || !dns_name_equal(&rtkey.algorithm, &qtkey.algorithm)) { tkey_log("dns_tkey_processdhresponse: tkey mode invalid " "or error set(4)"); result = DNS_R_INVALIDTKEY; goto failure; } isc_buffer_init(&intoken, rtkey.key, rtkey.keylen); isc_buffer_init(&outtoken, array, sizeof(array)); result = dst_gssapi_initctx(server, &intoken, &outtoken, context, ring->mctx, err_message); if (result != DNS_R_CONTINUE && result != ISC_R_SUCCESS) return (result); RETERR(dst_key_fromgssapi(dns_rootname, *context, rmsg->mctx, &dstkey, NULL)); /* * XXXSRA This seems confused. If we got CONTINUE from initctx, * the GSS negotiation hasn't completed yet, so we can't sign * anything yet. */ RETERR(dns_tsigkey_createfromkey(tkeyname, (win2k ? DNS_TSIG_GSSAPIMS_NAME : DNS_TSIG_GSSAPI_NAME), dstkey, ISC_TRUE, NULL, rtkey.inception, rtkey.expire, ring->mctx, ring, outkey)); dst_key_free(&dstkey); dns_rdata_freestruct(&rtkey); return (result); failure: /* * XXXSRA This probably leaks memory from qtkey. */ if (freertkey) dns_rdata_freestruct(&rtkey); if (dstkey != NULL) dst_key_free(&dstkey); return (result); } bind9-9.10.3.dfsg.P4/lib/dns/openssl_link.c0000644000470500017500000002204212664710322017567 0ustar lamontlamont/* * Portions Copyright (C) 2004-2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * Principal Author: Brian Wellington * $Id$ */ #ifdef OPENSSL #include #include #include #include #include #include #include #include #include #include #include "dst_internal.h" #include "dst_openssl.h" #ifdef USE_ENGINE #include #endif static RAND_METHOD *rm = NULL; static isc_mutex_t *locks = NULL; static int nlocks; #ifdef USE_ENGINE static ENGINE *e = NULL; #endif static int entropy_get(unsigned char *buf, int num) { isc_result_t result; if (num < 0) return (-1); result = dst__entropy_getdata(buf, (unsigned int) num, ISC_FALSE); return (result == ISC_R_SUCCESS ? 1 : -1); } static int entropy_status(void) { return (dst__entropy_status() > 32); } static int entropy_getpseudo(unsigned char *buf, int num) { isc_result_t result; if (num < 0) return (-1); result = dst__entropy_getdata(buf, (unsigned int) num, ISC_TRUE); return (result == ISC_R_SUCCESS ? 1 : -1); } #if OPENSSL_VERSION_NUMBER < 0x10100000L static void entropy_add(const void *buf, int num, double entropy) { /* * Do nothing. The only call to this provides no useful data anyway. */ UNUSED(buf); UNUSED(num); UNUSED(entropy); } #else static int entropy_add(const void *buf, int num, double entropy) { /* * Do nothing. The only call to this provides no useful data anyway. */ UNUSED(buf); UNUSED(num); UNUSED(entropy); return (1); } #endif static void lock_callback(int mode, int type, const char *file, int line) { UNUSED(file); UNUSED(line); if ((mode & CRYPTO_LOCK) != 0) LOCK(&locks[type]); else UNLOCK(&locks[type]); } #if OPENSSL_VERSION_NUMBER < 0x10100000L static unsigned long id_callback(void) { return ((unsigned long)isc_thread_self()); } #endif static void * mem_alloc(size_t size) { #ifdef OPENSSL_LEAKS void *ptr; INSIST(dst__memory_pool != NULL); ptr = isc_mem_allocate(dst__memory_pool, size); return (ptr); #else INSIST(dst__memory_pool != NULL); return (isc_mem_allocate(dst__memory_pool, size)); #endif } static void mem_free(void *ptr) { INSIST(dst__memory_pool != NULL); if (ptr != NULL) isc_mem_free(dst__memory_pool, ptr); } static void * mem_realloc(void *ptr, size_t size) { #ifdef OPENSSL_LEAKS void *rptr; INSIST(dst__memory_pool != NULL); rptr = isc_mem_reallocate(dst__memory_pool, ptr, size); return (rptr); #else INSIST(dst__memory_pool != NULL); return (isc_mem_reallocate(dst__memory_pool, ptr, size)); #endif } isc_result_t dst__openssl_init(const char *engine) { isc_result_t result; #ifdef USE_ENGINE ENGINE *re; #else UNUSED(engine); #endif #ifdef DNS_CRYPTO_LEAKS CRYPTO_malloc_debug_init(); CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); #endif CRYPTO_set_mem_functions(mem_alloc, mem_realloc, mem_free); nlocks = CRYPTO_num_locks(); locks = mem_alloc(sizeof(isc_mutex_t) * nlocks); if (locks == NULL) return (ISC_R_NOMEMORY); result = isc_mutexblock_init(locks, nlocks); if (result != ISC_R_SUCCESS) goto cleanup_mutexalloc; CRYPTO_set_locking_callback(lock_callback); #if OPENSSL_VERSION_NUMBER < 0x10100000L CRYPTO_set_id_callback(id_callback); #endif ERR_load_crypto_strings(); rm = mem_alloc(sizeof(RAND_METHOD)); if (rm == NULL) { result = ISC_R_NOMEMORY; goto cleanup_mutexinit; } rm->seed = NULL; rm->bytes = entropy_get; rm->cleanup = NULL; rm->add = entropy_add; rm->pseudorand = entropy_getpseudo; rm->status = entropy_status; #ifdef USE_ENGINE OPENSSL_config(NULL); if (engine != NULL && *engine == '\0') engine = NULL; if (engine != NULL) { e = ENGINE_by_id(engine); if (e == NULL) { result = DST_R_NOENGINE; goto cleanup_rm; } /* This will init the engine. */ if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) { result = DST_R_NOENGINE; goto cleanup_rm; } } re = ENGINE_get_default_RAND(); if (re == NULL) { re = ENGINE_new(); if (re == NULL) { result = ISC_R_NOMEMORY; goto cleanup_rm; } ENGINE_set_RAND(re, rm); ENGINE_set_default_RAND(re); ENGINE_free(re); } else ENGINE_finish(re); #else RAND_set_rand_method(rm); #endif /* USE_ENGINE */ return (ISC_R_SUCCESS); #ifdef USE_ENGINE cleanup_rm: if (e != NULL) ENGINE_free(e); e = NULL; mem_free(rm); rm = NULL; #endif cleanup_mutexinit: CRYPTO_set_locking_callback(NULL); DESTROYMUTEXBLOCK(locks, nlocks); cleanup_mutexalloc: mem_free(locks); locks = NULL; return (result); } void dst__openssl_destroy(void) { /* * Sequence taken from apps_shutdown() in . */ if (rm != NULL) { #if OPENSSL_VERSION_NUMBER >= 0x00907000L RAND_cleanup(); #endif mem_free(rm); rm = NULL; } #if (OPENSSL_VERSION_NUMBER >= 0x00907000L) CONF_modules_free(); #endif OBJ_cleanup(); EVP_cleanup(); #if defined(USE_ENGINE) if (e != NULL) ENGINE_free(e); e = NULL; #if defined(USE_ENGINE) && OPENSSL_VERSION_NUMBER >= 0x00907000L ENGINE_cleanup(); #endif #endif #if (OPENSSL_VERSION_NUMBER >= 0x00907000L) CRYPTO_cleanup_all_ex_data(); #endif ERR_clear_error(); #if OPENSSL_VERSION_NUMBER < 0x10100000L ERR_remove_state(0); #endif ERR_free_strings(); #ifdef DNS_CRYPTO_LEAKS CRYPTO_mem_leaks_fp(stderr); #endif if (locks != NULL) { CRYPTO_set_locking_callback(NULL); DESTROYMUTEXBLOCK(locks, nlocks); mem_free(locks); locks = NULL; } } static isc_result_t toresult(isc_result_t fallback) { isc_result_t result = fallback; unsigned long err = ERR_get_error(); #ifdef HAVE_OPENSSL_ECDSA int lib = ERR_GET_LIB(err); #endif int reason = ERR_GET_REASON(err); switch (reason) { /* * ERR_* errors are globally unique; others * are unique per sublibrary */ case ERR_R_MALLOC_FAILURE: result = ISC_R_NOMEMORY; break; default: #ifdef HAVE_OPENSSL_ECDSA if (lib == ERR_R_ECDSA_LIB && reason == ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED) { result = ISC_R_NOENTROPY; break; } #endif break; } return (result); } isc_result_t dst__openssl_toresult(isc_result_t fallback) { isc_result_t result; result = toresult(fallback); ERR_clear_error(); return (result); } isc_result_t dst__openssl_toresult2(const char *funcname, isc_result_t fallback) { return (dst__openssl_toresult3(DNS_LOGCATEGORY_GENERAL, funcname, fallback)); } isc_result_t dst__openssl_toresult3(isc_logcategory_t *category, const char *funcname, isc_result_t fallback) { isc_result_t result; unsigned long err; const char *file, *data; int line, flags; char buf[256]; result = toresult(fallback); isc_log_write(dns_lctx, category, DNS_LOGMODULE_CRYPTO, ISC_LOG_WARNING, "%s failed (%s)", funcname, isc_result_totext(result)); if (result == ISC_R_NOMEMORY) goto done; for (;;) { err = ERR_get_error_line_data(&file, &line, &data, &flags); if (err == 0U) goto done; ERR_error_string_n(err, buf, sizeof(buf)); isc_log_write(dns_lctx, category, DNS_LOGMODULE_CRYPTO, ISC_LOG_INFO, "%s:%s:%d:%s", buf, file, line, (flags & ERR_TXT_STRING) ? data : ""); } done: ERR_clear_error(); return (result); } #if defined(USE_ENGINE) ENGINE * dst__openssl_getengine(const char *engine) { if (engine == NULL) return (NULL); if (e == NULL) return (NULL); if (strcmp(engine, ENGINE_get_id(e)) == 0) return (e); return (NULL); } #endif #else /* OPENSSL */ #include EMPTY_TRANSLATION_UNIT #endif /* OPENSSL */ /*! \file */ bind9-9.10.3.dfsg.P4/lib/dns/cache.c0000644000470500017500000011754612664710322016150 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2011-2013, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: cache.c,v 1.91 2011/08/26 05:12:56 marka Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "rbtdb.h" #define CACHE_MAGIC ISC_MAGIC('$', '$', '$', '$') #define VALID_CACHE(cache) ISC_MAGIC_VALID(cache, CACHE_MAGIC) /*! * Control incremental cleaning. * DNS_CACHE_MINSIZE is how many bytes is the floor for dns_cache_setcachesize(). * See also DNS_CACHE_CLEANERINCREMENT */ #define DNS_CACHE_MINSIZE 2097152U /*%< Bytes. 2097152 = 2 MB */ /*! * Control incremental cleaning. * CLEANERINCREMENT is how many nodes are examined in one pass. * See also DNS_CACHE_MINSIZE */ #define DNS_CACHE_CLEANERINCREMENT 1000U /*%< Number of nodes. */ /*** *** Types ***/ /* * A cache_cleaner_t encapsulates the state of the periodic * cache cleaning. */ typedef struct cache_cleaner cache_cleaner_t; typedef enum { cleaner_s_idle, /*%< Waiting for cleaning-interval to expire. */ cleaner_s_busy, /*%< Currently cleaning. */ cleaner_s_done /*%< Freed enough memory after being overmem. */ } cleaner_state_t; /* * Convenience macros for comprehensive assertion checking. */ #define CLEANER_IDLE(c) ((c)->state == cleaner_s_idle && \ (c)->resched_event != NULL) #define CLEANER_BUSY(c) ((c)->state == cleaner_s_busy && \ (c)->iterator != NULL && \ (c)->resched_event == NULL) /*% * Accesses to a cache cleaner object are synchronized through * task/event serialization, or locked from the cache object. */ struct cache_cleaner { isc_mutex_t lock; /*%< * Locks overmem_event, overmem. Note: never allocate memory * while holding this lock - that could lead to deadlock since * the lock is take by water() which is called from the memory * allocator. */ dns_cache_t *cache; isc_task_t *task; unsigned int cleaning_interval; /*% The cleaning-interval from named.conf, in seconds. */ isc_timer_t *cleaning_timer; isc_event_t *resched_event; /*% Sent by cleaner task to itself to reschedule */ isc_event_t *overmem_event; dns_dbiterator_t *iterator; unsigned int increment; /*% Number of names to clean in one increment */ cleaner_state_t state; /*% Idle/Busy. */ isc_boolean_t overmem; /*% The cache is in an overmem state. */ isc_boolean_t replaceiterator; }; /*% * The actual cache object. */ struct dns_cache { /* Unlocked. */ unsigned int magic; isc_mutex_t lock; isc_mutex_t filelock; isc_mem_t *mctx; /* Main cache memory */ isc_mem_t *hmctx; /* Heap memory */ char *name; /* Locked by 'lock'. */ int references; int live_tasks; dns_rdataclass_t rdclass; dns_db_t *db; cache_cleaner_t cleaner; char *db_type; int db_argc; char **db_argv; size_t size; isc_stats_t *stats; /* Locked by 'filelock'. */ char *filename; /* Access to the on-disk cache file is also locked by 'filelock'. */ }; /*** *** Functions ***/ static isc_result_t cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr, cache_cleaner_t *cleaner); static void cleaning_timer_action(isc_task_t *task, isc_event_t *event); static void incremental_cleaning_action(isc_task_t *task, isc_event_t *event); static void cleaner_shutdown_action(isc_task_t *task, isc_event_t *event); static void overmem_cleaning_action(isc_task_t *task, isc_event_t *event); static inline isc_result_t cache_create_db(dns_cache_t *cache, dns_db_t **db) { return (dns_db_create(cache->mctx, cache->db_type, dns_rootname, dns_dbtype_cache, cache->rdclass, cache->db_argc, cache->db_argv, db)); } isc_result_t dns_cache_create(isc_mem_t *cmctx, isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr, dns_rdataclass_t rdclass, const char *db_type, unsigned int db_argc, char **db_argv, dns_cache_t **cachep) { return (dns_cache_create3(cmctx, cmctx, taskmgr, timermgr, rdclass, "", db_type, db_argc, db_argv, cachep)); } isc_result_t dns_cache_create2(isc_mem_t *cmctx, isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr, dns_rdataclass_t rdclass, const char *cachename, const char *db_type, unsigned int db_argc, char **db_argv, dns_cache_t **cachep) { return (dns_cache_create3(cmctx, cmctx, taskmgr, timermgr, rdclass, cachename, db_type, db_argc, db_argv, cachep)); } isc_result_t dns_cache_create3(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr, dns_rdataclass_t rdclass, const char *cachename, const char *db_type, unsigned int db_argc, char **db_argv, dns_cache_t **cachep) { isc_result_t result; dns_cache_t *cache; int i, extra = 0; isc_task_t *dbtask; REQUIRE(cachep != NULL); REQUIRE(*cachep == NULL); REQUIRE(cmctx != NULL); REQUIRE(hmctx != NULL); REQUIRE(cachename != NULL); cache = isc_mem_get(cmctx, sizeof(*cache)); if (cache == NULL) return (ISC_R_NOMEMORY); cache->mctx = cache->hmctx = NULL; isc_mem_attach(cmctx, &cache->mctx); isc_mem_attach(hmctx, &cache->hmctx); cache->name = NULL; if (cachename != NULL) { cache->name = isc_mem_strdup(cmctx, cachename); if (cache->name == NULL) { result = ISC_R_NOMEMORY; goto cleanup_mem; } } result = isc_mutex_init(&cache->lock); if (result != ISC_R_SUCCESS) goto cleanup_mem; result = isc_mutex_init(&cache->filelock); if (result != ISC_R_SUCCESS) goto cleanup_lock; cache->references = 1; cache->live_tasks = 0; cache->rdclass = rdclass; cache->stats = NULL; result = isc_stats_create(cmctx, &cache->stats, dns_cachestatscounter_max); if (result != ISC_R_SUCCESS) goto cleanup_filelock; cache->db_type = isc_mem_strdup(cmctx, db_type); if (cache->db_type == NULL) { result = ISC_R_NOMEMORY; goto cleanup_stats; } /* * For databases of type "rbt" we pass hmctx to dns_db_create() * via cache->db_argv, followed by the rest of the arguments in * db_argv (of which there really shouldn't be any). */ if (strcmp(cache->db_type, "rbt") == 0) extra = 1; cache->db_argc = db_argc + extra; cache->db_argv = NULL; if (cache->db_argc != 0) { cache->db_argv = isc_mem_get(cmctx, cache->db_argc * sizeof(char *)); if (cache->db_argv == NULL) { result = ISC_R_NOMEMORY; goto cleanup_dbtype; } for (i = 0; i < cache->db_argc; i++) cache->db_argv[i] = NULL; cache->db_argv[0] = (char *) hmctx; for (i = extra; i < cache->db_argc; i++) { cache->db_argv[i] = isc_mem_strdup(cmctx, db_argv[i - extra]); if (cache->db_argv[i] == NULL) { result = ISC_R_NOMEMORY; goto cleanup_dbargv; } } } /* * Create the database */ cache->db = NULL; result = cache_create_db(cache, &cache->db); if (result != ISC_R_SUCCESS) goto cleanup_dbargv; if (taskmgr != NULL) { dbtask = NULL; result = isc_task_create(taskmgr, 1, &dbtask); if (result != ISC_R_SUCCESS) goto cleanup_db; dns_db_settask(cache->db, dbtask); isc_task_detach(&dbtask); } cache->filename = NULL; cache->magic = CACHE_MAGIC; /* * RBT-type cache DB has its own mechanism of cache cleaning and doesn't * need the control of the generic cleaner. */ if (strcmp(db_type, "rbt") == 0) result = cache_cleaner_init(cache, NULL, NULL, &cache->cleaner); else { result = cache_cleaner_init(cache, taskmgr, timermgr, &cache->cleaner); } if (result != ISC_R_SUCCESS) goto cleanup_db; result = dns_db_setcachestats(cache->db, cache->stats); if (result != ISC_R_SUCCESS) goto cleanup_db; *cachep = cache; return (ISC_R_SUCCESS); cleanup_db: dns_db_detach(&cache->db); cleanup_dbargv: for (i = extra; i < cache->db_argc; i++) if (cache->db_argv[i] != NULL) isc_mem_free(cmctx, cache->db_argv[i]); if (cache->db_argv != NULL) isc_mem_put(cmctx, cache->db_argv, cache->db_argc * sizeof(char *)); cleanup_dbtype: isc_mem_free(cmctx, cache->db_type); cleanup_filelock: DESTROYLOCK(&cache->filelock); cleanup_stats: isc_stats_detach(&cache->stats); cleanup_lock: DESTROYLOCK(&cache->lock); cleanup_mem: if (cache->name != NULL) isc_mem_free(cmctx, cache->name); isc_mem_detach(&cache->hmctx); isc_mem_putanddetach(&cache->mctx, cache, sizeof(*cache)); return (result); } static void cache_free(dns_cache_t *cache) { int i; REQUIRE(VALID_CACHE(cache)); REQUIRE(cache->references == 0); isc_mem_setwater(cache->mctx, NULL, NULL, 0, 0); if (cache->cleaner.task != NULL) isc_task_detach(&cache->cleaner.task); if (cache->cleaner.overmem_event != NULL) isc_event_free(&cache->cleaner.overmem_event); if (cache->cleaner.resched_event != NULL) isc_event_free(&cache->cleaner.resched_event); if (cache->cleaner.iterator != NULL) dns_dbiterator_destroy(&cache->cleaner.iterator); DESTROYLOCK(&cache->cleaner.lock); if (cache->filename) { isc_mem_free(cache->mctx, cache->filename); cache->filename = NULL; } if (cache->db != NULL) dns_db_detach(&cache->db); if (cache->db_argv != NULL) { /* * We don't free db_argv[0] in "rbt" cache databases * as it's a pointer to hmctx */ int extra = 0; if (strcmp(cache->db_type, "rbt") == 0) extra = 1; for (i = extra; i < cache->db_argc; i++) if (cache->db_argv[i] != NULL) isc_mem_free(cache->mctx, cache->db_argv[i]); isc_mem_put(cache->mctx, cache->db_argv, cache->db_argc * sizeof(char *)); } if (cache->db_type != NULL) isc_mem_free(cache->mctx, cache->db_type); if (cache->name != NULL) isc_mem_free(cache->mctx, cache->name); if (cache->stats != NULL) isc_stats_detach(&cache->stats); DESTROYLOCK(&cache->lock); DESTROYLOCK(&cache->filelock); cache->magic = 0; isc_mem_detach(&cache->hmctx); isc_mem_putanddetach(&cache->mctx, cache, sizeof(*cache)); } void dns_cache_attach(dns_cache_t *cache, dns_cache_t **targetp) { REQUIRE(VALID_CACHE(cache)); REQUIRE(targetp != NULL && *targetp == NULL); LOCK(&cache->lock); cache->references++; UNLOCK(&cache->lock); *targetp = cache; } void dns_cache_detach(dns_cache_t **cachep) { dns_cache_t *cache; isc_boolean_t free_cache = ISC_FALSE; REQUIRE(cachep != NULL); cache = *cachep; REQUIRE(VALID_CACHE(cache)); LOCK(&cache->lock); REQUIRE(cache->references > 0); cache->references--; if (cache->references == 0) { cache->cleaner.overmem = ISC_FALSE; free_cache = ISC_TRUE; } *cachep = NULL; if (free_cache) { /* * When the cache is shut down, dump it to a file if one is * specified. */ isc_result_t result = dns_cache_dump(cache); if (result != ISC_R_SUCCESS) isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_WARNING, "error dumping cache: %s ", isc_result_totext(result)); /* * If the cleaner task exists, let it free the cache. */ if (cache->live_tasks > 0) { isc_task_shutdown(cache->cleaner.task); free_cache = ISC_FALSE; } } UNLOCK(&cache->lock); if (free_cache) cache_free(cache); } void dns_cache_attachdb(dns_cache_t *cache, dns_db_t **dbp) { REQUIRE(VALID_CACHE(cache)); REQUIRE(dbp != NULL && *dbp == NULL); REQUIRE(cache->db != NULL); LOCK(&cache->lock); dns_db_attach(cache->db, dbp); UNLOCK(&cache->lock); } isc_result_t dns_cache_setfilename(dns_cache_t *cache, const char *filename) { char *newname; REQUIRE(VALID_CACHE(cache)); REQUIRE(filename != NULL); newname = isc_mem_strdup(cache->mctx, filename); if (newname == NULL) return (ISC_R_NOMEMORY); LOCK(&cache->filelock); if (cache->filename) isc_mem_free(cache->mctx, cache->filename); cache->filename = newname; UNLOCK(&cache->filelock); return (ISC_R_SUCCESS); } isc_result_t dns_cache_load(dns_cache_t *cache) { isc_result_t result; REQUIRE(VALID_CACHE(cache)); if (cache->filename == NULL) return (ISC_R_SUCCESS); LOCK(&cache->filelock); result = dns_db_load(cache->db, cache->filename); UNLOCK(&cache->filelock); return (result); } isc_result_t dns_cache_dump(dns_cache_t *cache) { isc_result_t result; REQUIRE(VALID_CACHE(cache)); if (cache->filename == NULL) return (ISC_R_SUCCESS); LOCK(&cache->filelock); result = dns_master_dump(cache->mctx, cache->db, NULL, &dns_master_style_cache, cache->filename); UNLOCK(&cache->filelock); return (result); } void dns_cache_setcleaninginterval(dns_cache_t *cache, unsigned int t) { isc_interval_t interval; isc_result_t result; LOCK(&cache->lock); /* * It may be the case that the cache has already shut down. * If so, it has no timer. */ if (cache->cleaner.cleaning_timer == NULL) goto unlock; cache->cleaner.cleaning_interval = t; if (t == 0) { result = isc_timer_reset(cache->cleaner.cleaning_timer, isc_timertype_inactive, NULL, NULL, ISC_TRUE); } else { isc_interval_set(&interval, cache->cleaner.cleaning_interval, 0); result = isc_timer_reset(cache->cleaner.cleaning_timer, isc_timertype_ticker, NULL, &interval, ISC_FALSE); } if (result != ISC_R_SUCCESS) isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_WARNING, "could not set cache cleaning interval: %s", isc_result_totext(result)); unlock: UNLOCK(&cache->lock); } unsigned int dns_cache_getcleaninginterval(dns_cache_t *cache) { unsigned int t; REQUIRE(VALID_CACHE(cache)); LOCK(&cache->lock); t = cache->cleaner.cleaning_interval; UNLOCK(&cache->lock); return (t); } const char * dns_cache_getname(dns_cache_t *cache) { REQUIRE(VALID_CACHE(cache)); return (cache->name); } /* * Initialize the cache cleaner object at *cleaner. * Space for the object must be allocated by the caller. */ static isc_result_t cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr, cache_cleaner_t *cleaner) { isc_result_t result; result = isc_mutex_init(&cleaner->lock); if (result != ISC_R_SUCCESS) goto fail; cleaner->increment = DNS_CACHE_CLEANERINCREMENT; cleaner->state = cleaner_s_idle; cleaner->cache = cache; cleaner->iterator = NULL; cleaner->overmem = ISC_FALSE; cleaner->replaceiterator = ISC_FALSE; cleaner->task = NULL; cleaner->cleaning_timer = NULL; cleaner->resched_event = NULL; cleaner->overmem_event = NULL; cleaner->cleaning_interval = 0; /* Initially turned off. */ result = dns_db_createiterator(cleaner->cache->db, ISC_FALSE, &cleaner->iterator); if (result != ISC_R_SUCCESS) goto cleanup; if (taskmgr != NULL && timermgr != NULL) { result = isc_task_create(taskmgr, 1, &cleaner->task); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_task_create() failed: %s", dns_result_totext(result)); result = ISC_R_UNEXPECTED; goto cleanup; } cleaner->cache->live_tasks++; isc_task_setname(cleaner->task, "cachecleaner", cleaner); result = isc_task_onshutdown(cleaner->task, cleaner_shutdown_action, cache); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "cache cleaner: " "isc_task_onshutdown() failed: %s", dns_result_totext(result)); goto cleanup; } result = isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL, cleaner->task, cleaning_timer_action, cleaner, &cleaner->cleaning_timer); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_timer_create() failed: %s", dns_result_totext(result)); result = ISC_R_UNEXPECTED; goto cleanup; } cleaner->resched_event = isc_event_allocate(cache->mctx, cleaner, DNS_EVENT_CACHECLEAN, incremental_cleaning_action, cleaner, sizeof(isc_event_t)); if (cleaner->resched_event == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } cleaner->overmem_event = isc_event_allocate(cache->mctx, cleaner, DNS_EVENT_CACHEOVERMEM, overmem_cleaning_action, cleaner, sizeof(isc_event_t)); if (cleaner->overmem_event == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } } return (ISC_R_SUCCESS); cleanup: if (cleaner->overmem_event != NULL) isc_event_free(&cleaner->overmem_event); if (cleaner->resched_event != NULL) isc_event_free(&cleaner->resched_event); if (cleaner->cleaning_timer != NULL) isc_timer_detach(&cleaner->cleaning_timer); if (cleaner->task != NULL) isc_task_detach(&cleaner->task); if (cleaner->iterator != NULL) dns_dbiterator_destroy(&cleaner->iterator); DESTROYLOCK(&cleaner->lock); fail: return (result); } static void begin_cleaning(cache_cleaner_t *cleaner) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(CLEANER_IDLE(cleaner)); /* * Create an iterator, if it does not already exist, and * position it at the beginning of the cache. */ if (cleaner->iterator == NULL) result = dns_db_createiterator(cleaner->cache->db, ISC_FALSE, &cleaner->iterator); if (result != ISC_R_SUCCESS) isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_WARNING, "cache cleaner could not create " "iterator: %s", isc_result_totext(result)); else { dns_dbiterator_setcleanmode(cleaner->iterator, ISC_TRUE); result = dns_dbiterator_first(cleaner->iterator); } if (result != ISC_R_SUCCESS) { /* * If the result is ISC_R_NOMORE, the database is empty, * so there is nothing to be cleaned. */ if (result != ISC_R_NOMORE && cleaner->iterator != NULL) { UNEXPECTED_ERROR(__FILE__, __LINE__, "cache cleaner: " "dns_dbiterator_first() failed: %s", dns_result_totext(result)); dns_dbiterator_destroy(&cleaner->iterator); } else if (cleaner->iterator != NULL) { result = dns_dbiterator_pause(cleaner->iterator); RUNTIME_CHECK(result == ISC_R_SUCCESS); } } else { /* * Pause the iterator to free its lock. */ result = dns_dbiterator_pause(cleaner->iterator); RUNTIME_CHECK(result == ISC_R_SUCCESS); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1), "begin cache cleaning, mem inuse %lu", (unsigned long)isc_mem_inuse(cleaner->cache->mctx)); cleaner->state = cleaner_s_busy; isc_task_send(cleaner->task, &cleaner->resched_event); } return; } static void end_cleaning(cache_cleaner_t *cleaner, isc_event_t *event) { isc_result_t result; REQUIRE(CLEANER_BUSY(cleaner)); REQUIRE(event != NULL); result = dns_dbiterator_pause(cleaner->iterator); if (result != ISC_R_SUCCESS) dns_dbiterator_destroy(&cleaner->iterator); dns_cache_setcleaninginterval(cleaner->cache, cleaner->cleaning_interval); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1), "end cache cleaning, mem inuse %lu", (unsigned long)isc_mem_inuse(cleaner->cache->mctx)); cleaner->state = cleaner_s_idle; cleaner->resched_event = event; } /* * This is run once for every cache-cleaning-interval as defined in named.conf. */ static void cleaning_timer_action(isc_task_t *task, isc_event_t *event) { cache_cleaner_t *cleaner = event->ev_arg; UNUSED(task); INSIST(task == cleaner->task); INSIST(event->ev_type == ISC_TIMEREVENT_TICK); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1), "cache cleaning timer fired, " "cleaner state = %d", cleaner->state); if (cleaner->state == cleaner_s_idle) begin_cleaning(cleaner); isc_event_free(&event); } /* * This is called when the cache either surpasses its upper limit * or shrinks beyond its lower limit. */ static void overmem_cleaning_action(isc_task_t *task, isc_event_t *event) { cache_cleaner_t *cleaner = event->ev_arg; isc_boolean_t want_cleaning = ISC_FALSE; UNUSED(task); INSIST(task == cleaner->task); INSIST(event->ev_type == DNS_EVENT_CACHEOVERMEM); INSIST(cleaner->overmem_event == NULL); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1), "overmem_cleaning_action called, " "overmem = %d, state = %d", cleaner->overmem, cleaner->state); LOCK(&cleaner->lock); if (cleaner->overmem) { if (cleaner->state == cleaner_s_idle) want_cleaning = ISC_TRUE; } else { if (cleaner->state == cleaner_s_busy) /* * end_cleaning() can't be called here because * then both cleaner->overmem_event and * cleaner->resched_event will point to this * event. Set the state to done, and then * when the incremental_cleaning_action() event * is posted, it will handle the end_cleaning. */ cleaner->state = cleaner_s_done; } cleaner->overmem_event = event; UNLOCK(&cleaner->lock); if (want_cleaning) begin_cleaning(cleaner); } /* * Do incremental cleaning. */ static void incremental_cleaning_action(isc_task_t *task, isc_event_t *event) { cache_cleaner_t *cleaner = event->ev_arg; isc_result_t result; unsigned int n_names; isc_time_t start; UNUSED(task); INSIST(task == cleaner->task); INSIST(event->ev_type == DNS_EVENT_CACHECLEAN); if (cleaner->state == cleaner_s_done) { cleaner->state = cleaner_s_busy; end_cleaning(cleaner, event); LOCK(&cleaner->cache->lock); LOCK(&cleaner->lock); if (cleaner->replaceiterator) { dns_dbiterator_destroy(&cleaner->iterator); (void) dns_db_createiterator(cleaner->cache->db, ISC_FALSE, &cleaner->iterator); cleaner->replaceiterator = ISC_FALSE; } UNLOCK(&cleaner->lock); UNLOCK(&cleaner->cache->lock); return; } INSIST(CLEANER_BUSY(cleaner)); n_names = cleaner->increment; REQUIRE(DNS_DBITERATOR_VALID(cleaner->iterator)); isc_time_now(&start); while (n_names-- > 0) { dns_dbnode_t *node = NULL; result = dns_dbiterator_current(cleaner->iterator, &node, NULL); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "cache cleaner: dns_dbiterator_current() " "failed: %s", dns_result_totext(result)); end_cleaning(cleaner, event); return; } /* * The node was not needed, but was required by * dns_dbiterator_current(). Give up its reference. */ dns_db_detachnode(cleaner->cache->db, &node); /* * Step to the next node. */ result = dns_dbiterator_next(cleaner->iterator); if (result != ISC_R_SUCCESS) { /* * Either the end was reached (ISC_R_NOMORE) or * some error was signaled. If the cache is still * overmem and no error was encountered, * keep trying to clean it, otherwise stop cleaning. */ if (result != ISC_R_NOMORE) UNEXPECTED_ERROR(__FILE__, __LINE__, "cache cleaner: " "dns_dbiterator_next() " "failed: %s", dns_result_totext(result)); else if (cleaner->overmem) { result = dns_dbiterator_first(cleaner-> iterator); if (result == ISC_R_SUCCESS) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1), "cache cleaner: " "still overmem, " "reset and try again"); continue; } } end_cleaning(cleaner, event); return; } } /* * We have successfully performed a cleaning increment but have * not gone through the entire cache. Free the iterator locks * and reschedule another batch. If it fails, just try to continue * anyway. */ result = dns_dbiterator_pause(cleaner->iterator); RUNTIME_CHECK(result == ISC_R_SUCCESS); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1), "cache cleaner: checked %u nodes, " "mem inuse %lu, sleeping", cleaner->increment, (unsigned long)isc_mem_inuse(cleaner->cache->mctx)); isc_task_send(task, &event); INSIST(CLEANER_BUSY(cleaner)); return; } /* * Do immediate cleaning. */ isc_result_t dns_cache_clean(dns_cache_t *cache, isc_stdtime_t now) { isc_result_t result; dns_dbiterator_t *iterator = NULL; REQUIRE(VALID_CACHE(cache)); result = dns_db_createiterator(cache->db, 0, &iterator); if (result != ISC_R_SUCCESS) return result; result = dns_dbiterator_first(iterator); while (result == ISC_R_SUCCESS) { dns_dbnode_t *node = NULL; result = dns_dbiterator_current(iterator, &node, (dns_name_t *)NULL); if (result != ISC_R_SUCCESS) break; /* * Check TTLs, mark expired rdatasets stale. */ result = dns_db_expirenode(cache->db, node, now); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "cache cleaner: dns_db_expirenode() " "failed: %s", dns_result_totext(result)); /* * Continue anyway. */ } /* * This is where the actual freeing takes place. */ dns_db_detachnode(cache->db, &node); result = dns_dbiterator_next(iterator); } dns_dbiterator_destroy(&iterator); if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; return (result); } static void water(void *arg, int mark) { dns_cache_t *cache = arg; isc_boolean_t overmem = ISC_TF(mark == ISC_MEM_HIWATER); REQUIRE(VALID_CACHE(cache)); LOCK(&cache->cleaner.lock); if (overmem != cache->cleaner.overmem) { dns_db_overmem(cache->db, overmem); cache->cleaner.overmem = overmem; isc_mem_waterack(cache->mctx, mark); } if (cache->cleaner.overmem_event != NULL) isc_task_send(cache->cleaner.task, &cache->cleaner.overmem_event); UNLOCK(&cache->cleaner.lock); } void dns_cache_setcachesize(dns_cache_t *cache, size_t size) { size_t hiwater, lowater; REQUIRE(VALID_CACHE(cache)); /* * Impose a minimum cache size; pathological things happen if there * is too little room. */ if (size != 0U && size < DNS_CACHE_MINSIZE) size = DNS_CACHE_MINSIZE; LOCK(&cache->lock); cache->size = size; UNLOCK(&cache->lock); hiwater = size - (size >> 3); /* Approximately 7/8ths. */ lowater = size - (size >> 2); /* Approximately 3/4ths. */ /* * If the cache was overmem and cleaning, but now with the new limits * it is no longer in an overmem condition, then the next * isc_mem_put for cache memory will do the right thing and trigger * water(). */ if (size == 0U || hiwater == 0U || lowater == 0U) /* * Disable cache memory limiting. */ isc_mem_setwater(cache->mctx, water, cache, 0, 0); else /* * Establish new cache memory limits (either for the first * time, or replacing other limits). */ isc_mem_setwater(cache->mctx, water, cache, hiwater, lowater); } size_t dns_cache_getcachesize(dns_cache_t *cache) { size_t size; REQUIRE(VALID_CACHE(cache)); LOCK(&cache->lock); size = cache->size; UNLOCK(&cache->lock); return (size); } /* * The cleaner task is shutting down; do the necessary cleanup. */ static void cleaner_shutdown_action(isc_task_t *task, isc_event_t *event) { dns_cache_t *cache = event->ev_arg; isc_boolean_t should_free = ISC_FALSE; UNUSED(task); INSIST(task == cache->cleaner.task); INSIST(event->ev_type == ISC_TASKEVENT_SHUTDOWN); if (CLEANER_BUSY(&cache->cleaner)) end_cleaning(&cache->cleaner, event); else isc_event_free(&event); LOCK(&cache->lock); cache->live_tasks--; INSIST(cache->live_tasks == 0); if (cache->references == 0) should_free = ISC_TRUE; /* * By detaching the timer in the context of its task, * we are guaranteed that there will be no further timer * events. */ if (cache->cleaner.cleaning_timer != NULL) isc_timer_detach(&cache->cleaner.cleaning_timer); /* Make sure we don't reschedule anymore. */ (void)isc_task_purge(task, NULL, DNS_EVENT_CACHECLEAN, NULL); UNLOCK(&cache->lock); if (should_free) cache_free(cache); } isc_result_t dns_cache_flush(dns_cache_t *cache) { dns_db_t *db = NULL, *olddb; dns_dbiterator_t *dbiterator = NULL, *olddbiterator = NULL; isc_result_t result; result = cache_create_db(cache, &db); if (result != ISC_R_SUCCESS) return (result); result = dns_db_createiterator(db, ISC_FALSE, &dbiterator); if (result != ISC_R_SUCCESS) { dns_db_detach(&db); return (result); } LOCK(&cache->lock); LOCK(&cache->cleaner.lock); if (cache->cleaner.state == cleaner_s_idle) { olddbiterator = cache->cleaner.iterator; cache->cleaner.iterator = dbiterator; dbiterator = NULL; } else { if (cache->cleaner.state == cleaner_s_busy) cache->cleaner.state = cleaner_s_done; cache->cleaner.replaceiterator = ISC_TRUE; } olddb = cache->db; cache->db = db; dns_db_setcachestats(cache->db, cache->stats); UNLOCK(&cache->cleaner.lock); UNLOCK(&cache->lock); if (dbiterator != NULL) dns_dbiterator_destroy(&dbiterator); if (olddbiterator != NULL) dns_dbiterator_destroy(&olddbiterator); dns_db_detach(&olddb); return (ISC_R_SUCCESS); } static isc_result_t clearnode(dns_db_t *db, dns_dbnode_t *node) { isc_result_t result; dns_rdatasetiter_t *iter = NULL; result = dns_db_allrdatasets(db, node, NULL, (isc_stdtime_t)0, &iter); if (result != ISC_R_SUCCESS) return (result); for (result = dns_rdatasetiter_first(iter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(iter)) { dns_rdataset_t rdataset; dns_rdataset_init(&rdataset); dns_rdatasetiter_current(iter, &rdataset); result = dns_db_deleterdataset(db, node, NULL, rdataset.type, rdataset.covers); dns_rdataset_disassociate(&rdataset); if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED) break; } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; dns_rdatasetiter_destroy(&iter); return (result); } static isc_result_t cleartree(dns_db_t *db, dns_name_t *name) { isc_result_t result, answer = ISC_R_SUCCESS; dns_dbiterator_t *iter = NULL; dns_dbnode_t *node = NULL; dns_fixedname_t fnodename; dns_name_t *nodename; dns_fixedname_init(&fnodename); nodename = dns_fixedname_name(&fnodename); result = dns_db_createiterator(db, 0, &iter); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_dbiterator_seek(iter, name); if (result != ISC_R_SUCCESS) goto cleanup; while (result == ISC_R_SUCCESS) { result = dns_dbiterator_current(iter, &node, nodename); if (result == DNS_R_NEWORIGIN) result = ISC_R_SUCCESS; if (result != ISC_R_SUCCESS) goto cleanup; /* * Are we done? */ if (! dns_name_issubdomain(nodename, name)) goto cleanup; /* * If clearnode fails record and move onto the next node. */ result = clearnode(db, node); if (result != ISC_R_SUCCESS && answer == ISC_R_SUCCESS) answer = result; dns_db_detachnode(db, &node); result = dns_dbiterator_next(iter); } cleanup: if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND) result = ISC_R_SUCCESS; if (result != ISC_R_SUCCESS && answer == ISC_R_SUCCESS) answer = result; if (node != NULL) dns_db_detachnode(db, &node); if (iter != NULL) dns_dbiterator_destroy(&iter); return (answer); } isc_result_t dns_cache_flushname(dns_cache_t *cache, dns_name_t *name) { return (dns_cache_flushnode(cache, name, ISC_FALSE)); } isc_result_t dns_cache_flushnode(dns_cache_t *cache, dns_name_t *name, isc_boolean_t tree) { isc_result_t result; dns_dbnode_t *node = NULL; dns_db_t *db = NULL; if (dns_name_equal(name, dns_rootname)) return (dns_cache_flush(cache)); LOCK(&cache->lock); if (cache->db != NULL) dns_db_attach(cache->db, &db); UNLOCK(&cache->lock); if (db == NULL) return (ISC_R_SUCCESS); if (tree) { result = cleartree(cache->db, name); } else { result = dns_db_findnode(cache->db, name, ISC_FALSE, &node); if (result == ISC_R_NOTFOUND) { result = ISC_R_SUCCESS; goto cleanup_db; } if (result != ISC_R_SUCCESS) goto cleanup_db; result = clearnode(cache->db, node); dns_db_detachnode(cache->db, &node); } cleanup_db: dns_db_detach(&db); return (result); } isc_stats_t * dns_cache_getstats(dns_cache_t *cache) { REQUIRE(VALID_CACHE(cache)); return (cache->stats); } void dns_cache_updatestats(dns_cache_t *cache, isc_result_t result) { REQUIRE(VALID_CACHE(cache)); if (cache->stats == NULL) return; switch (result) { case ISC_R_SUCCESS: case DNS_R_NCACHENXDOMAIN: case DNS_R_NCACHENXRRSET: case DNS_R_CNAME: case DNS_R_DNAME: case DNS_R_GLUE: case DNS_R_ZONECUT: isc_stats_increment(cache->stats, dns_cachestatscounter_queryhits); break; default: isc_stats_increment(cache->stats, dns_cachestatscounter_querymisses); } } /* * XXX: Much of the following code has been copied in from statschannel.c. * We should refactor this into a generic function in stats.c that can be * called from both places. */ typedef struct cache_dumparg { isc_statsformat_t type; void *arg; /* type dependent argument */ int ncounters; /* for general statistics */ int *counterindices; /* for general statistics */ isc_uint64_t *countervalues; /* for general statistics */ isc_result_t result; } cache_dumparg_t; static void getcounter(isc_statscounter_t counter, isc_uint64_t val, void *arg) { cache_dumparg_t *dumparg = arg; REQUIRE(counter < dumparg->ncounters); dumparg->countervalues[counter] = val; } static void getcounters(isc_stats_t *stats, isc_statsformat_t type, int ncounters, int *indices, isc_uint64_t *values) { cache_dumparg_t dumparg; memset(values, 0, sizeof(values[0]) * ncounters); dumparg.type = type; dumparg.ncounters = ncounters; dumparg.counterindices = indices; dumparg.countervalues = values; isc_stats_dump(stats, getcounter, &dumparg, ISC_STATSDUMP_VERBOSE); } void dns_cache_dumpstats(dns_cache_t *cache, FILE *fp) { int indices[dns_cachestatscounter_max]; isc_uint64_t values[dns_cachestatscounter_max]; REQUIRE(VALID_CACHE(cache)); getcounters(cache->stats, isc_statsformat_file, dns_cachestatscounter_max, indices, values); fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n", values[dns_cachestatscounter_hits], "cache hits"); fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n", values[dns_cachestatscounter_misses], "cache misses"); fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n", values[dns_cachestatscounter_queryhits], "cache hits (from query)"); fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n", values[dns_cachestatscounter_querymisses], "cache misses (from query)"); fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n", values[dns_cachestatscounter_deletelru], "cache records deleted due to memory exhaustion"); fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n", values[dns_cachestatscounter_deletettl], "cache records deleted due to TTL expiration"); fprintf(fp, "%20u %s\n", dns_db_nodecount(cache->db), "cache database nodes"); fprintf(fp, "%20u %s\n", dns_db_hashsize(cache->db), "cache database hash buckets"); fprintf(fp, "%20u %s\n", (unsigned int) isc_mem_total(cache->mctx), "cache tree memory total"); fprintf(fp, "%20u %s\n", (unsigned int) isc_mem_inuse(cache->mctx), "cache tree memory in use"); fprintf(fp, "%20u %s\n", (unsigned int) isc_mem_maxinuse(cache->mctx), "cache tree highest memory in use"); fprintf(fp, "%20u %s\n", (unsigned int) isc_mem_total(cache->hmctx), "cache heap memory total"); fprintf(fp, "%20u %s\n", (unsigned int) isc_mem_inuse(cache->hmctx), "cache heap memory in use"); fprintf(fp, "%20u %s\n", (unsigned int) isc_mem_maxinuse(cache->hmctx), "cache heap highest memory in use"); } #ifdef HAVE_LIBXML2 #define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0) static int renderstat(const char *name, isc_uint64_t value, xmlTextWriterPtr writer) { int xmlrc; TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter")); TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name", ISC_XMLCHAR name)); TRY0(xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", value)); TRY0(xmlTextWriterEndElement(writer)); /* counter */ error: return (xmlrc); } int dns_cache_renderxml(dns_cache_t *cache, xmlTextWriterPtr writer) { int indices[dns_cachestatscounter_max]; isc_uint64_t values[dns_cachestatscounter_max]; int xmlrc; REQUIRE(VALID_CACHE(cache)); getcounters(cache->stats, isc_statsformat_file, dns_cachestatscounter_max, indices, values); TRY0(renderstat("CacheHits", values[dns_cachestatscounter_hits], writer)); TRY0(renderstat("CacheMisses", values[dns_cachestatscounter_misses], writer)); TRY0(renderstat("QueryHits", values[dns_cachestatscounter_queryhits], writer)); TRY0(renderstat("QueryMisses", values[dns_cachestatscounter_querymisses], writer)); TRY0(renderstat("DeleteLRU", values[dns_cachestatscounter_deletelru], writer)); TRY0(renderstat("DeleteTTL", values[dns_cachestatscounter_deletettl], writer)); TRY0(renderstat("CacheNodes", dns_db_nodecount(cache->db), writer)); TRY0(renderstat("CacheBuckets", dns_db_hashsize(cache->db), writer)); TRY0(renderstat("TreeMemTotal", isc_mem_total(cache->mctx), writer)); TRY0(renderstat("TreeMemInUse", isc_mem_inuse(cache->mctx), writer)); TRY0(renderstat("TreeMemMax", isc_mem_maxinuse(cache->mctx), writer)); TRY0(renderstat("HeapMemTotal", isc_mem_total(cache->hmctx), writer)); TRY0(renderstat("HeapMemInUse", isc_mem_inuse(cache->hmctx), writer)); TRY0(renderstat("HeapMemMax", isc_mem_maxinuse(cache->hmctx), writer)); error: return (xmlrc); } #endif #ifdef HAVE_JSON #define CHECKMEM(m) do { \ if (m == NULL) { \ result = ISC_R_NOMEMORY;\ goto error;\ } \ } while(0) isc_result_t dns_cache_renderjson(dns_cache_t *cache, json_object *cstats) { isc_result_t result = ISC_R_SUCCESS; int indices[dns_cachestatscounter_max]; isc_uint64_t values[dns_cachestatscounter_max]; json_object *obj; REQUIRE(VALID_CACHE(cache)); getcounters(cache->stats, isc_statsformat_file, dns_cachestatscounter_max, indices, values); obj = json_object_new_int64(values[dns_cachestatscounter_hits]); CHECKMEM(obj); json_object_object_add(cstats, "CacheHits", obj); obj = json_object_new_int64(values[dns_cachestatscounter_misses]); CHECKMEM(obj); json_object_object_add(cstats, "CacheMisses", obj); obj = json_object_new_int64(values[dns_cachestatscounter_queryhits]); CHECKMEM(obj); json_object_object_add(cstats, "QueryHits", obj); obj = json_object_new_int64(values[dns_cachestatscounter_querymisses]); CHECKMEM(obj); json_object_object_add(cstats, "QueryMisses", obj); obj = json_object_new_int64(values[dns_cachestatscounter_deletelru]); CHECKMEM(obj); json_object_object_add(cstats, "DeleteLRU", obj); obj = json_object_new_int64(values[dns_cachestatscounter_deletettl]); CHECKMEM(obj); json_object_object_add(cstats, "DeleteTTL", obj); obj = json_object_new_int64(dns_db_nodecount(cache->db)); CHECKMEM(obj); json_object_object_add(cstats, "CacheNodes", obj); obj = json_object_new_int64(dns_db_hashsize(cache->db)); CHECKMEM(obj); json_object_object_add(cstats, "CacheBuckets", obj); obj = json_object_new_int64(isc_mem_total(cache->mctx)); CHECKMEM(obj); json_object_object_add(cstats, "TreeMemTotal", obj); obj = json_object_new_int64(isc_mem_inuse(cache->mctx)); CHECKMEM(obj); json_object_object_add(cstats, "TreeMemInUse", obj); obj = json_object_new_int64(isc_mem_maxinuse(cache->mctx)); CHECKMEM(obj); json_object_object_add(cstats, "HeapMemMax", obj); obj = json_object_new_int64(isc_mem_total(cache->hmctx)); CHECKMEM(obj); json_object_object_add(cstats, "HeapMemTotal", obj); obj = json_object_new_int64(isc_mem_inuse(cache->hmctx)); CHECKMEM(obj); json_object_object_add(cstats, "HeapMemInUse", obj); obj = json_object_new_int64(isc_mem_maxinuse(cache->hmctx)); CHECKMEM(obj); json_object_object_add(cstats, "HeapMemMax", obj); result = ISC_R_SUCCESS; error: return (result); } #endif bind9-9.10.3.dfsg.P4/lib/dns/dst_internal.h0000644000470500017500000002165312664710322017571 0ustar lamontlamont/* * Portions Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: dst_internal.h,v 1.31 2011/10/20 21:20:02 marka Exp $ */ #ifndef DST_DST_INTERNAL_H #define DST_DST_INTERNAL_H 1 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef OPENSSL #include #include #include #include #include #include #endif ISC_LANG_BEGINDECLS #define KEY_MAGIC ISC_MAGIC('D','S','T','K') #define CTX_MAGIC ISC_MAGIC('D','S','T','C') #define VALID_KEY(x) ISC_MAGIC_VALID(x, KEY_MAGIC) #define VALID_CTX(x) ISC_MAGIC_VALID(x, CTX_MAGIC) extern isc_mem_t *dst__memory_pool; /*** *** Types ***/ typedef struct dst_func dst_func_t; typedef struct dst_hmacmd5_key dst_hmacmd5_key_t; typedef struct dst_hmacsha1_key dst_hmacsha1_key_t; typedef struct dst_hmacsha224_key dst_hmacsha224_key_t; typedef struct dst_hmacsha256_key dst_hmacsha256_key_t; typedef struct dst_hmacsha384_key dst_hmacsha384_key_t; typedef struct dst_hmacsha512_key dst_hmacsha512_key_t; /*% * Indicate whether a DST context will be used for signing * or for verification */ typedef enum { DO_SIGN, DO_VERIFY } dst_use_t; /*% DST Key Structure */ struct dst_key { unsigned int magic; isc_refcount_t refs; dns_name_t * key_name; /*%< name of the key */ unsigned int key_size; /*%< size of the key in bits */ unsigned int key_proto; /*%< protocols this key is used for */ unsigned int key_alg; /*%< algorithm of the key */ isc_uint32_t key_flags; /*%< flags of the public key */ isc_uint16_t key_id; /*%< identifier of the key */ isc_uint16_t key_rid; /*%< identifier of the key when revoked */ isc_uint16_t key_bits; /*%< hmac digest bits */ dns_rdataclass_t key_class; /*%< class of the key record */ dns_ttl_t key_ttl; /*%< default/initial dnskey ttl */ isc_mem_t *mctx; /*%< memory context */ char *engine; /*%< engine name (HSM) */ char *label; /*%< engine label (HSM) */ union { void *generic; gss_ctx_id_t gssctx; #ifdef OPENSSL #if !defined(USE_EVP) || !USE_EVP RSA *rsa; #endif DSA *dsa; DH *dh; EVP_PKEY *pkey; #elif PKCS11CRYPTO pk11_object_t *pkey; #endif dst_hmacmd5_key_t *hmacmd5; dst_hmacsha1_key_t *hmacsha1; dst_hmacsha224_key_t *hmacsha224; dst_hmacsha256_key_t *hmacsha256; dst_hmacsha384_key_t *hmacsha384; dst_hmacsha512_key_t *hmacsha512; } keydata; /*%< pointer to key in crypto pkg fmt */ isc_stdtime_t times[DST_MAX_TIMES + 1]; /*%< timing metadata */ isc_boolean_t timeset[DST_MAX_TIMES + 1]; /*%< data set? */ isc_stdtime_t nums[DST_MAX_NUMERIC + 1]; /*%< numeric metadata */ isc_boolean_t numset[DST_MAX_NUMERIC + 1]; /*%< data set? */ isc_boolean_t inactive; /*%< private key not present as it is inactive */ isc_boolean_t external; /*%< external key */ int fmt_major; /*%< private key format, major version */ int fmt_minor; /*%< private key format, minor version */ dst_func_t * func; /*%< crypto package specific functions */ isc_buffer_t *key_tkeytoken; /*%< TKEY token data */ }; struct dst_context { unsigned int magic; dst_use_t use; dst_key_t *key; isc_mem_t *mctx; isc_logcategory_t *category; union { void *generic; dst_gssapi_signverifyctx_t *gssctx; isc_md5_t *md5ctx; isc_sha1_t *sha1ctx; isc_sha256_t *sha256ctx; isc_sha512_t *sha512ctx; isc_hmacmd5_t *hmacmd5ctx; isc_hmacsha1_t *hmacsha1ctx; isc_hmacsha224_t *hmacsha224ctx; isc_hmacsha256_t *hmacsha256ctx; isc_hmacsha384_t *hmacsha384ctx; isc_hmacsha512_t *hmacsha512ctx; #ifdef OPENSSL EVP_MD_CTX *evp_md_ctx; #elif PKCS11CRYPTO pk11_context_t *pk11_ctx; #endif } ctxdata; }; struct dst_func { /* * Context functions */ isc_result_t (*createctx)(dst_key_t *key, dst_context_t *dctx); isc_result_t (*createctx2)(dst_key_t *key, int maxbits, dst_context_t *dctx); void (*destroyctx)(dst_context_t *dctx); isc_result_t (*adddata)(dst_context_t *dctx, const isc_region_t *data); /* * Key operations */ isc_result_t (*sign)(dst_context_t *dctx, isc_buffer_t *sig); isc_result_t (*verify)(dst_context_t *dctx, const isc_region_t *sig); isc_result_t (*verify2)(dst_context_t *dctx, int maxbits, const isc_region_t *sig); isc_result_t (*computesecret)(const dst_key_t *pub, const dst_key_t *priv, isc_buffer_t *secret); isc_boolean_t (*compare)(const dst_key_t *key1, const dst_key_t *key2); isc_boolean_t (*paramcompare)(const dst_key_t *key1, const dst_key_t *key2); isc_result_t (*generate)(dst_key_t *key, int parms, void (*callback)(int)); isc_boolean_t (*isprivate)(const dst_key_t *key); void (*destroy)(dst_key_t *key); /* conversion functions */ isc_result_t (*todns)(const dst_key_t *key, isc_buffer_t *data); isc_result_t (*fromdns)(dst_key_t *key, isc_buffer_t *data); isc_result_t (*tofile)(const dst_key_t *key, const char *directory); isc_result_t (*parse)(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub); /* cleanup */ void (*cleanup)(void); isc_result_t (*fromlabel)(dst_key_t *key, const char *engine, const char *label, const char *pin); isc_result_t (*dump)(dst_key_t *key, isc_mem_t *mctx, char **buffer, int *length); isc_result_t (*restore)(dst_key_t *key, const char *keystr); }; /*% * Initializers */ isc_result_t dst__openssl_init(const char *engine); #define dst__pkcs11_init pk11_initialize isc_result_t dst__hmacmd5_init(struct dst_func **funcp); isc_result_t dst__hmacsha1_init(struct dst_func **funcp); isc_result_t dst__hmacsha224_init(struct dst_func **funcp); isc_result_t dst__hmacsha256_init(struct dst_func **funcp); isc_result_t dst__hmacsha384_init(struct dst_func **funcp); isc_result_t dst__hmacsha512_init(struct dst_func **funcp); isc_result_t dst__opensslrsa_init(struct dst_func **funcp, unsigned char algorithm); isc_result_t dst__pkcs11rsa_init(struct dst_func **funcp); isc_result_t dst__openssldsa_init(struct dst_func **funcp); isc_result_t dst__pkcs11dsa_init(struct dst_func **funcp); isc_result_t dst__openssldh_init(struct dst_func **funcp); isc_result_t dst__pkcs11dh_init(struct dst_func **funcp); isc_result_t dst__gssapi_init(struct dst_func **funcp); #ifdef HAVE_OPENSSL_ECDSA isc_result_t dst__opensslecdsa_init(struct dst_func **funcp); #endif #ifdef HAVE_PKCS11_ECDSA isc_result_t dst__pkcs11ecdsa_init(struct dst_func **funcp); #endif #ifdef HAVE_OPENSSL_GOST isc_result_t dst__opensslgost_init(struct dst_func **funcp); #endif #ifdef HAVE_PKCS11_GOST isc_result_t dst__pkcs11gost_init(struct dst_func **funcp); #endif /*% * Destructors */ void dst__openssl_destroy(void); #define dst__pkcs11_destroy pk11_finalize /*% * Memory allocators using the DST memory pool. */ void * dst__mem_alloc(size_t size); void dst__mem_free(void *ptr); void * dst__mem_realloc(void *ptr, size_t size); /*% * Entropy retriever using the DST entropy pool. */ isc_result_t dst__entropy_getdata(void *buf, unsigned int len, isc_boolean_t pseudo); /* * Entropy status hook. */ unsigned int dst__entropy_status(void); ISC_LANG_ENDDECLS #endif /* DST_DST_INTERNAL_H */ /*! \file */ bind9-9.10.3.dfsg.P4/lib/dns/spnego.asn10000644000470500017500000000254312664710322017006 0ustar lamontlamont-- Copyright (C) The Internet Society 2005. This version of -- this module is part of RFC 4178; see the RFC itself for -- full legal notices. -- (The above copyright notice is per RFC 3978 5.6 (a), q.v.) -- $Id: spnego.asn1,v 1.2 2006/12/04 01:52:46 marka Exp $ -- This is the SPNEGO ASN.1 module from RFC 4178, tweaked -- to get the Heimdal ASN.1 compiler to accept it. SPNEGOASNOneSpec DEFINITIONS ::= BEGIN MechType ::= OBJECT IDENTIFIER MechTypeList ::= SEQUENCE OF MechType ContextFlags ::= BIT STRING { delegFlag (0), mutualFlag (1), replayFlag (2), sequenceFlag (3), anonFlag (4), confFlag (5), integFlag (6) } NegTokenInit ::= SEQUENCE { mechTypes [0] MechTypeList, reqFlags [1] ContextFlags OPTIONAL, mechToken [2] OCTET STRING OPTIONAL, mechListMIC [3] OCTET STRING OPTIONAL } NegTokenResp ::= SEQUENCE { negState [0] ENUMERATED { accept-completed (0), accept-incomplete (1), reject (2), request-mic (3) } OPTIONAL, supportedMech [1] MechType OPTIONAL, responseToken [2] OCTET STRING OPTIONAL, mechListMIC [3] OCTET STRING OPTIONAL } NegotiationToken ::= CHOICE { negTokenInit [0] NegTokenInit, negTokenResp [1] NegTokenResp } END bind9-9.10.3.dfsg.P4/lib/dns/result.c0000644000470500017500000002435112664710322016412 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007-2013, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include static const char *text[DNS_R_NRESULTS] = { "label too long", /*%< 0 DNS_R_LABELTOOLONG */ "bad escape", /*%< 1 DNS_R_BADESCAPE */ /*! * Note that DNS_R_BADBITSTRING and DNS_R_BITSTRINGTOOLONG are * deprecated. */ "bad bitstring", /*%< 2 DNS_R_BADBITSTRING */ "bitstring too long", /*%< 3 DNS_R_BITSTRINGTOOLONG */ "empty label", /*%< 4 DNS_R_EMPTYLABEL */ "bad dotted quad", /*%< 5 DNS_R_BADDOTTEDQUAD */ "invalid NS owner name (wildcard)", /*%< 6 DNS_R_INVALIDNS */ "unknown class/type", /*%< 7 DNS_R_UNKNOWN */ "bad label type", /*%< 8 DNS_R_BADLABELTYPE */ "bad compression pointer", /*%< 9 DNS_R_BADPOINTER */ "too many hops", /*%< 10 DNS_R_TOOMANYHOPS */ "disallowed (by application policy)", /*%< 11 DNS_R_DISALLOWED */ "extra input text", /*%< 12 DNS_R_EXTRATOKEN */ "extra input data", /*%< 13 DNS_R_EXTRADATA */ "text too long", /*%< 14 DNS_R_TEXTTOOLONG */ "not at top of zone", /*%< 15 DNS_R_NOTZONETOP */ "syntax error", /*%< 16 DNS_R_SYNTAX */ "bad checksum", /*%< 17 DNS_R_BADCKSUM */ "bad IPv6 address", /*%< 18 DNS_R_BADAAAA */ "no owner", /*%< 19 DNS_R_NOOWNER */ "no ttl", /*%< 20 DNS_R_NOTTL */ "bad class", /*%< 21 DNS_R_BADCLASS */ "name too long", /*%< 22 DNS_R_NAMETOOLONG */ "partial match", /*%< 23 DNS_R_PARTIALMATCH */ "new origin", /*%< 24 DNS_R_NEWORIGIN */ "unchanged", /*%< 25 DNS_R_UNCHANGED */ "bad ttl", /*%< 26 DNS_R_BADTTL */ "more data needed/to be rendered", /*%< 27 DNS_R_NOREDATA */ "continue", /*%< 28 DNS_R_CONTINUE */ "delegation", /*%< 29 DNS_R_DELEGATION */ "glue", /*%< 30 DNS_R_GLUE */ "dname", /*%< 31 DNS_R_DNAME */ "cname", /*%< 32 DNS_R_CNAME */ "bad database", /*%< 33 DNS_R_BADDB */ "zonecut", /*%< 34 DNS_R_ZONECUT */ "bad zone", /*%< 35 DNS_R_BADZONE */ "more data", /*%< 36 DNS_R_MOREDATA */ "up to date", /*%< 37 DNS_R_UPTODATE */ "tsig verify failure", /*%< 38 DNS_R_TSIGVERIFYFAILURE */ "tsig indicates error", /*%< 39 DNS_R_TSIGERRORSET */ "RRSIG failed to verify", /*%< 40 DNS_R_SIGINVALID */ "RRSIG has expired", /*%< 41 DNS_R_SIGEXPIRED */ "RRSIG validity period has not begun", /*%< 42 DNS_R_SIGFUTURE */ "key is unauthorized to sign data", /*%< 43 DNS_R_KEYUNAUTHORIZED */ "invalid time", /*%< 44 DNS_R_INVALIDTIME */ "expected a TSIG or SIG(0)", /*%< 45 DNS_R_EXPECTEDTSIG */ "did not expect a TSIG or SIG(0)", /*%< 46 DNS_R_UNEXPECTEDTSIG */ "TKEY is unacceptable", /*%< 47 DNS_R_INVALIDTKEY */ "hint", /*%< 48 DNS_R_HINT */ "drop", /*%< 49 DNS_R_DROP */ "zone not loaded", /*%< 50 DNS_R_NOTLOADED */ "ncache nxdomain", /*%< 51 DNS_R_NCACHENXDOMAIN */ "ncache nxrrset", /*%< 52 DNS_R_NCACHENXRRSET */ "wait", /*%< 53 DNS_R_WAIT */ "not verified yet", /*%< 54 DNS_R_NOTVERIFIEDYET */ "no identity", /*%< 55 DNS_R_NOIDENTITY */ "no journal", /*%< 56 DNS_R_NOJOURNAL */ "alias", /*%< 57 DNS_R_ALIAS */ "use TCP", /*%< 58 DNS_R_USETCP */ "no valid RRSIG", /*%< 59 DNS_R_NOVALIDSIG */ "no valid NSEC", /*%< 60 DNS_R_NOVALIDNSEC */ "insecurity proof failed", /*%< 61 DNS_R_NOTINSECURE */ "unknown service", /*%< 62 DNS_R_UNKNOWNSERVICE */ "recoverable error occurred", /*%< 63 DNS_R_RECOVERABLE */ "unknown opt attribute record", /*%< 64 DNS_R_UNKNOWNOPT */ "unexpected message id", /*%< 65 DNS_R_UNEXPECTEDID */ "seen include file", /*%< 66 DNS_R_SEENINCLUDE */ "not exact", /*%< 67 DNS_R_NOTEXACT */ "address blackholed", /*%< 68 DNS_R_BLACKHOLED */ "bad algorithm", /*%< 69 DNS_R_BADALG */ "invalid use of a meta type", /*%< 70 DNS_R_METATYPE */ "CNAME and other data", /*%< 71 DNS_R_CNAMEANDOTHER */ "multiple RRs of singleton type", /*%< 72 DNS_R_SINGLETON */ "hint nxrrset", /*%< 73 DNS_R_HINTNXRRSET */ "no master file configured", /*%< 74 DNS_R_NOMASTERFILE */ "unknown protocol", /*%< 75 DNS_R_UNKNOWNPROTO */ "clocks are unsynchronized", /*%< 76 DNS_R_CLOCKSKEW */ "IXFR failed", /*%< 77 DNS_R_BADIXFR */ "not authoritative", /*%< 78 DNS_R_NOTAUTHORITATIVE */ "no valid KEY", /*%< 79 DNS_R_NOVALIDKEY */ "obsolete", /*%< 80 DNS_R_OBSOLETE */ "already frozen", /*%< 81 DNS_R_FROZEN */ "unknown flag", /*%< 82 DNS_R_UNKNOWNFLAG */ "expected a response", /*%< 83 DNS_R_EXPECTEDRESPONSE */ "no valid DS", /*%< 84 DNS_R_NOVALIDDS */ "NS is an address", /*%< 85 DNS_R_NSISADDRESS */ "received FORMERR", /*%< 86 DNS_R_REMOTEFORMERR */ "truncated TCP response", /*%< 87 DNS_R_TRUNCATEDTCP */ "lame server detected", /*%< 88 DNS_R_LAME */ "unexpected RCODE", /*%< 89 DNS_R_UNEXPECTEDRCODE */ "unexpected OPCODE", /*%< 90 DNS_R_UNEXPECTEDOPCODE */ "chase DS servers", /*%< 91 DNS_R_CHASEDSSERVERS */ "empty name", /*%< 92 DNS_R_EMPTYNAME */ "empty wild", /*%< 93 DNS_R_EMPTYWILD */ "bad bitmap", /*%< 94 DNS_R_BADBITMAP */ "from wildcard", /*%< 95 DNS_R_FROMWILDCARD */ "bad owner name (check-names)", /*%< 96 DNS_R_BADOWNERNAME */ "bad name (check-names)", /*%< 97 DNS_R_BADNAME */ "dynamic zone", /*%< 98 DNS_R_DYNAMIC */ "unknown command", /*%< 99 DNS_R_UNKNOWNCOMMAND */ "must-be-secure", /*%< 100 DNS_R_MUSTBESECURE */ "covering NSEC record returned", /*%< 101 DNS_R_COVERINGNSEC */ "MX is an address", /*%< 102 DNS_R_MXISADDRESS */ "duplicate query", /*%< 103 DNS_R_DUPLICATE */ "invalid NSEC3 owner name (wildcard)", /*%< 104 DNS_R_INVALIDNSEC3 */ "not master", /*%< 105 DNS_R_NOTMASTER */ "broken trust chain", /*%< 106 DNS_R_BROKENCHAIN */ "expired", /*%< 107 DNS_R_EXPIRED */ "not dynamic", /*%< 108 DNS_R_NOTDYNAMIC */ "bad EUI", /*%< 109 DNS_R_BADEUI */ "covered by negative trust anchor", /*%< 110 DNS_R_NTACOVERED */ "bad CDS", /*%< 111 DNS_R_BADCSD */ "bad CDNSKEY", /*%< 112 DNS_R_BADCDNSKEY */ "malformed OPT option" /*%< 113 DNS_R_OPTERR */ }; static const char *rcode_text[DNS_R_NRCODERESULTS] = { "NOERROR", /*%< 0 DNS_R_NOEROR */ "FORMERR", /*%< 1 DNS_R_FORMERR */ "SERVFAIL", /*%< 2 DNS_R_SERVFAIL */ "NXDOMAIN", /*%< 3 DNS_R_NXDOMAIN */ "NOTIMP", /*%< 4 DNS_R_NOTIMP */ "REFUSED", /*%< 5 DNS_R_REFUSED */ "YXDOMAIN", /*%< 6 DNS_R_YXDOMAIN */ "YXRRSET", /*%< 7 DNS_R_YXRRSET */ "NXRRSET", /*%< 8 DNS_R_NXRRSET */ "NOTAUTH", /*%< 9 DNS_R_NOTAUTH */ "NOTZONE", /*%< 10 DNS_R_NOTZONE */ "", /*%< 11 has no macro */ "", /*%< 12 has no macro */ "", /*%< 13 has no macro */ "", /*%< 14 has no macro */ "", /*%< 15 has no macro */ "BADVERS", /*%< 16 DNS_R_BADVERS */ }; #define DNS_RESULT_RESULTSET 2 #define DNS_RESULT_RCODERESULTSET 3 static isc_once_t once = ISC_ONCE_INIT; static void initialize_action(void) { isc_result_t result; result = isc_result_register(ISC_RESULTCLASS_DNS, DNS_R_NRESULTS, text, dns_msgcat, DNS_RESULT_RESULTSET); if (result == ISC_R_SUCCESS) result = isc_result_register(ISC_RESULTCLASS_DNSRCODE, DNS_R_NRCODERESULTS, rcode_text, dns_msgcat, DNS_RESULT_RCODERESULTSET); if (result != ISC_R_SUCCESS) UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_result_register() failed: %u", result); } static void initialize(void) { dns_lib_initmsgcat(); RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); } const char * dns_result_totext(isc_result_t result) { initialize(); return (isc_result_totext(result)); } void dns_result_register(void) { initialize(); } dns_rcode_t dns_result_torcode(isc_result_t result) { dns_rcode_t rcode = dns_rcode_servfail; if (DNS_RESULT_ISRCODE(result)) { /* * Rcodes can't be bigger than 12 bits, which is why we * AND with 0xFFF instead of 0xFFFF. */ return ((dns_rcode_t)((result) & 0xFFF)); } /* * Try to supply an appropriate rcode. */ switch (result) { case ISC_R_SUCCESS: rcode = dns_rcode_noerror; break; case ISC_R_BADBASE64: case ISC_R_NOSPACE: case ISC_R_RANGE: case ISC_R_UNEXPECTEDEND: case DNS_R_BADAAAA: /* case DNS_R_BADBITSTRING: deprecated */ case DNS_R_BADCKSUM: case DNS_R_BADCLASS: case DNS_R_BADLABELTYPE: case DNS_R_BADPOINTER: case DNS_R_BADTTL: case DNS_R_BADZONE: /* case DNS_R_BITSTRINGTOOLONG: deprecated */ case DNS_R_EXTRADATA: case DNS_R_LABELTOOLONG: case DNS_R_NOREDATA: case DNS_R_SYNTAX: case DNS_R_TEXTTOOLONG: case DNS_R_TOOMANYHOPS: case DNS_R_TSIGERRORSET: case DNS_R_UNKNOWN: case DNS_R_NAMETOOLONG: case DNS_R_OPTERR: rcode = dns_rcode_formerr; break; case DNS_R_DISALLOWED: rcode = dns_rcode_refused; break; case DNS_R_TSIGVERIFYFAILURE: case DNS_R_CLOCKSKEW: rcode = dns_rcode_notauth; break; default: rcode = dns_rcode_servfail; } return (rcode); } bind9-9.10.3.dfsg.P4/lib/dns/peer.c0000644000470500017500000004351012664710322016025 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2012-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: peer.c,v 1.33 2009/09/02 23:48:02 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include /*% * Bit positions in the dns_peer_t structure flags field */ #define BOGUS_BIT 0 #define SERVER_TRANSFER_FORMAT_BIT 1 #define TRANSFERS_BIT 2 #define PROVIDE_IXFR_BIT 3 #define REQUEST_IXFR_BIT 4 #define SUPPORT_EDNS_BIT 5 #define SERVER_UDPSIZE_BIT 6 #define SERVER_MAXUDP_BIT 7 #define REQUEST_NSID_BIT 8 #define REQUEST_SIT_BIT 9 #define NOTIFY_DSCP_BIT 10 #define TRANSFER_DSCP_BIT 11 #define QUERY_DSCP_BIT 12 static void peerlist_delete(dns_peerlist_t **list); static void peer_delete(dns_peer_t **peer); isc_result_t dns_peerlist_new(isc_mem_t *mem, dns_peerlist_t **list) { dns_peerlist_t *l; REQUIRE(list != NULL); l = isc_mem_get(mem, sizeof(*l)); if (l == NULL) return (ISC_R_NOMEMORY); ISC_LIST_INIT(l->elements); l->mem = mem; l->refs = 1; l->magic = DNS_PEERLIST_MAGIC; *list = l; return (ISC_R_SUCCESS); } void dns_peerlist_attach(dns_peerlist_t *source, dns_peerlist_t **target) { REQUIRE(DNS_PEERLIST_VALID(source)); REQUIRE(target != NULL); REQUIRE(*target == NULL); source->refs++; ENSURE(source->refs != 0xffffffffU); *target = source; } void dns_peerlist_detach(dns_peerlist_t **list) { dns_peerlist_t *plist; REQUIRE(list != NULL); REQUIRE(*list != NULL); REQUIRE(DNS_PEERLIST_VALID(*list)); plist = *list; *list = NULL; REQUIRE(plist->refs > 0); plist->refs--; if (plist->refs == 0) peerlist_delete(&plist); } static void peerlist_delete(dns_peerlist_t **list) { dns_peerlist_t *l; dns_peer_t *server, *stmp; REQUIRE(list != NULL); REQUIRE(DNS_PEERLIST_VALID(*list)); l = *list; REQUIRE(l->refs == 0); server = ISC_LIST_HEAD(l->elements); while (server != NULL) { stmp = ISC_LIST_NEXT(server, next); ISC_LIST_UNLINK(l->elements, server, next); dns_peer_detach(&server); server = stmp; } l->magic = 0; isc_mem_put(l->mem, l, sizeof(*l)); *list = NULL; } void dns_peerlist_addpeer(dns_peerlist_t *peers, dns_peer_t *peer) { dns_peer_t *p = NULL; dns_peer_attach(peer, &p); /* * More specifics to front of list. */ for (p = ISC_LIST_HEAD(peers->elements); p != NULL; p = ISC_LIST_NEXT(p, next)) if (p->prefixlen < peer->prefixlen) break; if (p != NULL) ISC_LIST_INSERTBEFORE(peers->elements, p, peer, next); else ISC_LIST_APPEND(peers->elements, peer, next); } isc_result_t dns_peerlist_peerbyaddr(dns_peerlist_t *servers, isc_netaddr_t *addr, dns_peer_t **retval) { dns_peer_t *server; isc_result_t res; REQUIRE(retval != NULL); REQUIRE(DNS_PEERLIST_VALID(servers)); server = ISC_LIST_HEAD(servers->elements); while (server != NULL) { if (isc_netaddr_eqprefix(addr, &server->address, server->prefixlen)) break; server = ISC_LIST_NEXT(server, next); } if (server != NULL) { *retval = server; res = ISC_R_SUCCESS; } else { res = ISC_R_NOTFOUND; } return (res); } isc_result_t dns_peerlist_currpeer(dns_peerlist_t *peers, dns_peer_t **retval) { dns_peer_t *p = NULL; p = ISC_LIST_TAIL(peers->elements); dns_peer_attach(p, retval); return (ISC_R_SUCCESS); } isc_result_t dns_peer_new(isc_mem_t *mem, isc_netaddr_t *addr, dns_peer_t **peerptr) { unsigned int prefixlen = 0; REQUIRE(peerptr != NULL); switch(addr->family) { case AF_INET: prefixlen = 32; break; case AF_INET6: prefixlen = 128; break; default: INSIST(0); } return (dns_peer_newprefix(mem, addr, prefixlen, peerptr)); } isc_result_t dns_peer_newprefix(isc_mem_t *mem, isc_netaddr_t *addr, unsigned int prefixlen, dns_peer_t **peerptr) { dns_peer_t *peer; REQUIRE(peerptr != NULL); peer = isc_mem_get(mem, sizeof(*peer)); if (peer == NULL) return (ISC_R_NOMEMORY); peer->magic = DNS_PEER_MAGIC; peer->address = *addr; peer->prefixlen = prefixlen; peer->mem = mem; peer->bogus = ISC_FALSE; peer->transfer_format = dns_one_answer; peer->transfers = 0; peer->request_ixfr = ISC_FALSE; peer->provide_ixfr = ISC_FALSE; peer->key = NULL; peer->refs = 1; peer->transfer_source = NULL; peer->notify_source = NULL; peer->query_source = NULL; memset(&peer->bitflags, 0x0, sizeof(peer->bitflags)); ISC_LINK_INIT(peer, next); *peerptr = peer; return (ISC_R_SUCCESS); } void dns_peer_attach(dns_peer_t *source, dns_peer_t **target) { REQUIRE(DNS_PEER_VALID(source)); REQUIRE(target != NULL); REQUIRE(*target == NULL); source->refs++; ENSURE(source->refs != 0xffffffffU); *target = source; } void dns_peer_detach(dns_peer_t **peer) { dns_peer_t *p; REQUIRE(peer != NULL); REQUIRE(*peer != NULL); REQUIRE(DNS_PEER_VALID(*peer)); p = *peer; REQUIRE(p->refs > 0); *peer = NULL; p->refs--; if (p->refs == 0) peer_delete(&p); } static void peer_delete(dns_peer_t **peer) { dns_peer_t *p; isc_mem_t *mem; REQUIRE(peer != NULL); REQUIRE(DNS_PEER_VALID(*peer)); p = *peer; REQUIRE(p->refs == 0); mem = p->mem; p->mem = NULL; p->magic = 0; if (p->key != NULL) { dns_name_free(p->key, mem); isc_mem_put(mem, p->key, sizeof(dns_name_t)); } if (p->query_source != NULL) isc_mem_put(mem, p->query_source, sizeof(*p->query_source)); if (p->notify_source != NULL) isc_mem_put(mem, p->notify_source, sizeof(*p->notify_source)); if (p->transfer_source != NULL) isc_mem_put(mem, p->transfer_source, sizeof(*p->transfer_source)); isc_mem_put(mem, p, sizeof(*p)); *peer = NULL; } isc_result_t dns_peer_setbogus(dns_peer_t *peer, isc_boolean_t newval) { isc_boolean_t existed; REQUIRE(DNS_PEER_VALID(peer)); existed = DNS_BIT_CHECK(BOGUS_BIT, &peer->bitflags); peer->bogus = newval; DNS_BIT_SET(BOGUS_BIT, &peer->bitflags); return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); } isc_result_t dns_peer_getbogus(dns_peer_t *peer, isc_boolean_t *retval) { REQUIRE(DNS_PEER_VALID(peer)); REQUIRE(retval != NULL); if (DNS_BIT_CHECK(BOGUS_BIT, &peer->bitflags)) { *retval = peer->bogus; return (ISC_R_SUCCESS); } else return (ISC_R_NOTFOUND); } isc_result_t dns_peer_setprovideixfr(dns_peer_t *peer, isc_boolean_t newval) { isc_boolean_t existed; REQUIRE(DNS_PEER_VALID(peer)); existed = DNS_BIT_CHECK(PROVIDE_IXFR_BIT, &peer->bitflags); peer->provide_ixfr = newval; DNS_BIT_SET(PROVIDE_IXFR_BIT, &peer->bitflags); return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); } isc_result_t dns_peer_getprovideixfr(dns_peer_t *peer, isc_boolean_t *retval) { REQUIRE(DNS_PEER_VALID(peer)); REQUIRE(retval != NULL); if (DNS_BIT_CHECK(PROVIDE_IXFR_BIT, &peer->bitflags)) { *retval = peer->provide_ixfr; return (ISC_R_SUCCESS); } else { return (ISC_R_NOTFOUND); } } isc_result_t dns_peer_setrequestixfr(dns_peer_t *peer, isc_boolean_t newval) { isc_boolean_t existed; REQUIRE(DNS_PEER_VALID(peer)); existed = DNS_BIT_CHECK(REQUEST_IXFR_BIT, &peer->bitflags); peer->request_ixfr = newval; DNS_BIT_SET(REQUEST_IXFR_BIT, &peer->bitflags); return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); } isc_result_t dns_peer_getrequestixfr(dns_peer_t *peer, isc_boolean_t *retval) { REQUIRE(DNS_PEER_VALID(peer)); REQUIRE(retval != NULL); if (DNS_BIT_CHECK(REQUEST_IXFR_BIT, &peer->bitflags)) { *retval = peer->request_ixfr; return (ISC_R_SUCCESS); } else return (ISC_R_NOTFOUND); } isc_result_t dns_peer_setsupportedns(dns_peer_t *peer, isc_boolean_t newval) { isc_boolean_t existed; REQUIRE(DNS_PEER_VALID(peer)); existed = DNS_BIT_CHECK(SUPPORT_EDNS_BIT, &peer->bitflags); peer->support_edns = newval; DNS_BIT_SET(SUPPORT_EDNS_BIT, &peer->bitflags); return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); } isc_result_t dns_peer_getsupportedns(dns_peer_t *peer, isc_boolean_t *retval) { REQUIRE(DNS_PEER_VALID(peer)); REQUIRE(retval != NULL); if (DNS_BIT_CHECK(SUPPORT_EDNS_BIT, &peer->bitflags)) { *retval = peer->support_edns; return (ISC_R_SUCCESS); } else return (ISC_R_NOTFOUND); } isc_result_t dns_peer_setrequestnsid(dns_peer_t *peer, isc_boolean_t newval) { isc_boolean_t existed; REQUIRE(DNS_PEER_VALID(peer)); existed = DNS_BIT_CHECK(REQUEST_NSID_BIT, &peer->bitflags); peer->request_nsid = newval; DNS_BIT_SET(REQUEST_NSID_BIT, &peer->bitflags); return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); } isc_result_t dns_peer_getrequestnsid(dns_peer_t *peer, isc_boolean_t *retval) { REQUIRE(DNS_PEER_VALID(peer)); REQUIRE(retval != NULL); if (DNS_BIT_CHECK(REQUEST_NSID_BIT, &peer->bitflags)) { *retval = peer->request_nsid; return (ISC_R_SUCCESS); } else return (ISC_R_NOTFOUND); } isc_result_t dns_peer_setrequestsit(dns_peer_t *peer, isc_boolean_t newval) { isc_boolean_t existed; REQUIRE(DNS_PEER_VALID(peer)); existed = DNS_BIT_CHECK(REQUEST_SIT_BIT, &peer->bitflags); peer->request_sit = newval; DNS_BIT_SET(REQUEST_SIT_BIT, &peer->bitflags); return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); } isc_result_t dns_peer_getrequestsit(dns_peer_t *peer, isc_boolean_t *retval) { REQUIRE(DNS_PEER_VALID(peer)); REQUIRE(retval != NULL); if (DNS_BIT_CHECK(REQUEST_SIT_BIT, &peer->bitflags)) { *retval = peer->request_sit; return (ISC_R_SUCCESS); } else return (ISC_R_NOTFOUND); } isc_result_t dns_peer_settransfers(dns_peer_t *peer, isc_uint32_t newval) { isc_boolean_t existed; REQUIRE(DNS_PEER_VALID(peer)); existed = DNS_BIT_CHECK(TRANSFERS_BIT, &peer->bitflags); peer->transfers = newval; DNS_BIT_SET(TRANSFERS_BIT, &peer->bitflags); return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); } isc_result_t dns_peer_gettransfers(dns_peer_t *peer, isc_uint32_t *retval) { REQUIRE(DNS_PEER_VALID(peer)); REQUIRE(retval != NULL); if (DNS_BIT_CHECK(TRANSFERS_BIT, &peer->bitflags)) { *retval = peer->transfers; return (ISC_R_SUCCESS); } else { return (ISC_R_NOTFOUND); } } isc_result_t dns_peer_settransferformat(dns_peer_t *peer, dns_transfer_format_t newval) { isc_boolean_t existed; REQUIRE(DNS_PEER_VALID(peer)); existed = DNS_BIT_CHECK(SERVER_TRANSFER_FORMAT_BIT, &peer->bitflags); peer->transfer_format = newval; DNS_BIT_SET(SERVER_TRANSFER_FORMAT_BIT, &peer->bitflags); return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); } isc_result_t dns_peer_gettransferformat(dns_peer_t *peer, dns_transfer_format_t *retval) { REQUIRE(DNS_PEER_VALID(peer)); REQUIRE(retval != NULL); if (DNS_BIT_CHECK(SERVER_TRANSFER_FORMAT_BIT, &peer->bitflags)) { *retval = peer->transfer_format; return (ISC_R_SUCCESS); } else { return (ISC_R_NOTFOUND); } } isc_result_t dns_peer_getkey(dns_peer_t *peer, dns_name_t **retval) { REQUIRE(DNS_PEER_VALID(peer)); REQUIRE(retval != NULL); if (peer->key != NULL) { *retval = peer->key; } return (peer->key == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS); } isc_result_t dns_peer_setkey(dns_peer_t *peer, dns_name_t **keyval) { isc_boolean_t exists = ISC_FALSE; if (peer->key != NULL) { dns_name_free(peer->key, peer->mem); isc_mem_put(peer->mem, peer->key, sizeof(dns_name_t)); exists = ISC_TRUE; } peer->key = *keyval; *keyval = NULL; return (exists ? ISC_R_EXISTS : ISC_R_SUCCESS); } isc_result_t dns_peer_setkeybycharp(dns_peer_t *peer, const char *keyval) { isc_buffer_t b; dns_fixedname_t fname; dns_name_t *name; isc_result_t result; dns_fixedname_init(&fname); isc_buffer_constinit(&b, keyval, strlen(keyval)); isc_buffer_add(&b, strlen(keyval)); result = dns_name_fromtext(dns_fixedname_name(&fname), &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) return (result); name = isc_mem_get(peer->mem, sizeof(dns_name_t)); if (name == NULL) return (ISC_R_NOMEMORY); dns_name_init(name, NULL); result = dns_name_dup(dns_fixedname_name(&fname), peer->mem, name); if (result != ISC_R_SUCCESS) { isc_mem_put(peer->mem, name, sizeof(dns_name_t)); return (result); } result = dns_peer_setkey(peer, &name); if (result != ISC_R_SUCCESS) isc_mem_put(peer->mem, name, sizeof(dns_name_t)); return (result); } isc_result_t dns_peer_settransfersource(dns_peer_t *peer, const isc_sockaddr_t *transfer_source) { REQUIRE(DNS_PEER_VALID(peer)); if (peer->transfer_source != NULL) { isc_mem_put(peer->mem, peer->transfer_source, sizeof(*peer->transfer_source)); peer->transfer_source = NULL; } if (transfer_source != NULL) { peer->transfer_source = isc_mem_get(peer->mem, sizeof(*peer->transfer_source)); if (peer->transfer_source == NULL) return (ISC_R_NOMEMORY); *peer->transfer_source = *transfer_source; } return (ISC_R_SUCCESS); } isc_result_t dns_peer_gettransfersource(dns_peer_t *peer, isc_sockaddr_t *transfer_source) { REQUIRE(DNS_PEER_VALID(peer)); REQUIRE(transfer_source != NULL); if (peer->transfer_source == NULL) return (ISC_R_NOTFOUND); *transfer_source = *peer->transfer_source; return (ISC_R_SUCCESS); } isc_result_t dns_peer_setnotifysource(dns_peer_t *peer, const isc_sockaddr_t *notify_source) { REQUIRE(DNS_PEER_VALID(peer)); if (peer->notify_source != NULL) { isc_mem_put(peer->mem, peer->notify_source, sizeof(*peer->notify_source)); peer->notify_source = NULL; } if (notify_source != NULL) { peer->notify_source = isc_mem_get(peer->mem, sizeof(*peer->notify_source)); if (peer->notify_source == NULL) return (ISC_R_NOMEMORY); *peer->notify_source = *notify_source; } return (ISC_R_SUCCESS); } isc_result_t dns_peer_getnotifysource(dns_peer_t *peer, isc_sockaddr_t *notify_source) { REQUIRE(DNS_PEER_VALID(peer)); REQUIRE(notify_source != NULL); if (peer->notify_source == NULL) return (ISC_R_NOTFOUND); *notify_source = *peer->notify_source; return (ISC_R_SUCCESS); } isc_result_t dns_peer_setquerysource(dns_peer_t *peer, const isc_sockaddr_t *query_source) { REQUIRE(DNS_PEER_VALID(peer)); if (peer->query_source != NULL) { isc_mem_put(peer->mem, peer->query_source, sizeof(*peer->query_source)); peer->query_source = NULL; } if (query_source != NULL) { peer->query_source = isc_mem_get(peer->mem, sizeof(*peer->query_source)); if (peer->query_source == NULL) return (ISC_R_NOMEMORY); *peer->query_source = *query_source; } return (ISC_R_SUCCESS); } isc_result_t dns_peer_getquerysource(dns_peer_t *peer, isc_sockaddr_t *query_source) { REQUIRE(DNS_PEER_VALID(peer)); REQUIRE(query_source != NULL); if (peer->query_source == NULL) return (ISC_R_NOTFOUND); *query_source = *peer->query_source; return (ISC_R_SUCCESS); } isc_result_t dns_peer_setudpsize(dns_peer_t *peer, isc_uint16_t udpsize) { isc_boolean_t existed; REQUIRE(DNS_PEER_VALID(peer)); existed = DNS_BIT_CHECK(SERVER_UDPSIZE_BIT, &peer->bitflags); peer->udpsize = udpsize; DNS_BIT_SET(SERVER_UDPSIZE_BIT, &peer->bitflags); return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); } isc_result_t dns_peer_getudpsize(dns_peer_t *peer, isc_uint16_t *udpsize) { REQUIRE(DNS_PEER_VALID(peer)); REQUIRE(udpsize != NULL); if (DNS_BIT_CHECK(SERVER_UDPSIZE_BIT, &peer->bitflags)) { *udpsize = peer->udpsize; return (ISC_R_SUCCESS); } else { return (ISC_R_NOTFOUND); } } isc_result_t dns_peer_setmaxudp(dns_peer_t *peer, isc_uint16_t maxudp) { isc_boolean_t existed; REQUIRE(DNS_PEER_VALID(peer)); existed = DNS_BIT_CHECK(SERVER_MAXUDP_BIT, &peer->bitflags); peer->maxudp = maxudp; DNS_BIT_SET(SERVER_MAXUDP_BIT, &peer->bitflags); return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); } isc_result_t dns_peer_getmaxudp(dns_peer_t *peer, isc_uint16_t *maxudp) { REQUIRE(DNS_PEER_VALID(peer)); REQUIRE(maxudp != NULL); if (DNS_BIT_CHECK(SERVER_MAXUDP_BIT, &peer->bitflags)) { *maxudp = peer->maxudp; return (ISC_R_SUCCESS); } else { return (ISC_R_NOTFOUND); } } isc_result_t dns_peer_setnotifydscp(dns_peer_t *peer, isc_dscp_t dscp) { REQUIRE(DNS_PEER_VALID(peer)); REQUIRE(dscp < 64); peer->notify_dscp = dscp; DNS_BIT_SET(NOTIFY_DSCP_BIT, &peer->bitflags); return (ISC_R_SUCCESS); } isc_result_t dns_peer_getnotifydscp(dns_peer_t *peer, isc_dscp_t *dscpp) { REQUIRE(DNS_PEER_VALID(peer)); REQUIRE(dscpp != NULL); if (DNS_BIT_CHECK(NOTIFY_DSCP_BIT, &peer->bitflags)) { *dscpp = peer->notify_dscp; return (ISC_R_SUCCESS); } return (ISC_R_NOTFOUND); } isc_result_t dns_peer_settransferdscp(dns_peer_t *peer, isc_dscp_t dscp) { REQUIRE(DNS_PEER_VALID(peer)); REQUIRE(dscp < 64); peer->transfer_dscp = dscp; DNS_BIT_SET(TRANSFER_DSCP_BIT, &peer->bitflags); return (ISC_R_SUCCESS); } isc_result_t dns_peer_gettransferdscp(dns_peer_t *peer, isc_dscp_t *dscpp) { REQUIRE(DNS_PEER_VALID(peer)); REQUIRE(dscpp != NULL); if (DNS_BIT_CHECK(TRANSFER_DSCP_BIT, &peer->bitflags)) { *dscpp = peer->transfer_dscp; return (ISC_R_SUCCESS); } return (ISC_R_NOTFOUND); } isc_result_t dns_peer_setquerydscp(dns_peer_t *peer, isc_dscp_t dscp) { REQUIRE(DNS_PEER_VALID(peer)); REQUIRE(dscp < 64); peer->query_dscp = dscp; DNS_BIT_SET(QUERY_DSCP_BIT, &peer->bitflags); return (ISC_R_SUCCESS); } isc_result_t dns_peer_getquerydscp(dns_peer_t *peer, isc_dscp_t *dscpp) { REQUIRE(DNS_PEER_VALID(peer)); REQUIRE(dscpp != NULL); if (DNS_BIT_CHECK(QUERY_DSCP_BIT, &peer->bitflags)) { *dscpp = peer->query_dscp; return (ISC_R_SUCCESS); } return (ISC_R_NOTFOUND); } bind9-9.10.3.dfsg.P4/lib/dns/db.c0000644000470500017500000006117712664710322015470 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ /*** *** Imports ***/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /*** *** Private Types ***/ struct dns_dbimplementation { const char * name; dns_dbcreatefunc_t create; isc_mem_t * mctx; void * driverarg; ISC_LINK(dns_dbimplementation_t) link; }; /*** *** Supported DB Implementations Registry ***/ /* * Built in database implementations are registered here. */ #include "rbtdb.h" #include "rbtdb64.h" static ISC_LIST(dns_dbimplementation_t) implementations; static isc_rwlock_t implock; static isc_once_t once = ISC_ONCE_INIT; static dns_dbimplementation_t rbtimp; static dns_dbimplementation_t rbt64imp; static void initialize(void) { RUNTIME_CHECK(isc_rwlock_init(&implock, 0, 0) == ISC_R_SUCCESS); rbtimp.name = "rbt"; rbtimp.create = dns_rbtdb_create; rbtimp.mctx = NULL; rbtimp.driverarg = NULL; ISC_LINK_INIT(&rbtimp, link); rbt64imp.name = "rbt64"; rbt64imp.create = dns_rbtdb64_create; rbt64imp.mctx = NULL; rbt64imp.driverarg = NULL; ISC_LINK_INIT(&rbt64imp, link); ISC_LIST_INIT(implementations); ISC_LIST_APPEND(implementations, &rbtimp, link); ISC_LIST_APPEND(implementations, &rbt64imp, link); } static inline dns_dbimplementation_t * impfind(const char *name) { dns_dbimplementation_t *imp; for (imp = ISC_LIST_HEAD(implementations); imp != NULL; imp = ISC_LIST_NEXT(imp, link)) if (strcasecmp(name, imp->name) == 0) return (imp); return (NULL); } /*** *** Basic DB Methods ***/ isc_result_t dns_db_create(isc_mem_t *mctx, const char *db_type, dns_name_t *origin, dns_dbtype_t type, dns_rdataclass_t rdclass, unsigned int argc, char *argv[], dns_db_t **dbp) { dns_dbimplementation_t *impinfo; RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); /* * Create a new database using implementation 'db_type'. */ REQUIRE(dbp != NULL && *dbp == NULL); REQUIRE(dns_name_isabsolute(origin)); RWLOCK(&implock, isc_rwlocktype_read); impinfo = impfind(db_type); if (impinfo != NULL) { isc_result_t result; result = ((impinfo->create)(mctx, origin, type, rdclass, argc, argv, impinfo->driverarg, dbp)); RWUNLOCK(&implock, isc_rwlocktype_read); return (result); } RWUNLOCK(&implock, isc_rwlocktype_read); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DB, ISC_LOG_ERROR, "unsupported database type '%s'", db_type); return (ISC_R_NOTFOUND); } void dns_db_attach(dns_db_t *source, dns_db_t **targetp) { /* * Attach *targetp to source. */ REQUIRE(DNS_DB_VALID(source)); REQUIRE(targetp != NULL && *targetp == NULL); (source->methods->attach)(source, targetp); ENSURE(*targetp == source); } void dns_db_detach(dns_db_t **dbp) { /* * Detach *dbp from its database. */ REQUIRE(dbp != NULL); REQUIRE(DNS_DB_VALID(*dbp)); ((*dbp)->methods->detach)(dbp); ENSURE(*dbp == NULL); } isc_result_t dns_db_ondestroy(dns_db_t *db, isc_task_t *task, isc_event_t **eventp) { REQUIRE(DNS_DB_VALID(db)); return (isc_ondestroy_register(&db->ondest, task, eventp)); } isc_boolean_t dns_db_iscache(dns_db_t *db) { /* * Does 'db' have cache semantics? */ REQUIRE(DNS_DB_VALID(db)); if ((db->attributes & DNS_DBATTR_CACHE) != 0) return (ISC_TRUE); return (ISC_FALSE); } isc_boolean_t dns_db_iszone(dns_db_t *db) { /* * Does 'db' have zone semantics? */ REQUIRE(DNS_DB_VALID(db)); if ((db->attributes & (DNS_DBATTR_CACHE|DNS_DBATTR_STUB)) == 0) return (ISC_TRUE); return (ISC_FALSE); } isc_boolean_t dns_db_isstub(dns_db_t *db) { /* * Does 'db' have stub semantics? */ REQUIRE(DNS_DB_VALID(db)); if ((db->attributes & DNS_DBATTR_STUB) != 0) return (ISC_TRUE); return (ISC_FALSE); } isc_boolean_t dns_db_isdnssec(dns_db_t *db) { /* * Is 'db' secure or partially secure? */ REQUIRE(DNS_DB_VALID(db)); REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0); if (db->methods->isdnssec != NULL) return ((db->methods->isdnssec)(db)); return ((db->methods->issecure)(db)); } isc_boolean_t dns_db_issecure(dns_db_t *db) { /* * Is 'db' secure? */ REQUIRE(DNS_DB_VALID(db)); REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0); return ((db->methods->issecure)(db)); } isc_boolean_t dns_db_ispersistent(dns_db_t *db) { /* * Is 'db' persistent? */ REQUIRE(DNS_DB_VALID(db)); return ((db->methods->ispersistent)(db)); } dns_name_t * dns_db_origin(dns_db_t *db) { /* * The origin of the database. */ REQUIRE(DNS_DB_VALID(db)); return (&db->origin); } dns_rdataclass_t dns_db_class(dns_db_t *db) { /* * The class of the database. */ REQUIRE(DNS_DB_VALID(db)); return (db->rdclass); } isc_result_t dns_db_beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) { /* * Begin loading 'db'. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE(DNS_CALLBACK_VALID(callbacks)); return ((db->methods->beginload)(db, callbacks)); } isc_result_t dns_db_endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) { /* * Finish loading 'db'. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE(DNS_CALLBACK_VALID(callbacks)); REQUIRE(callbacks->add_private != NULL); return ((db->methods->endload)(db, callbacks)); } isc_result_t dns_db_load(dns_db_t *db, const char *filename) { return (dns_db_load3(db, filename, dns_masterformat_text, 0)); } isc_result_t dns_db_load2(dns_db_t *db, const char *filename, dns_masterformat_t format) { return (dns_db_load3(db, filename, format, 0)); } isc_result_t dns_db_load3(dns_db_t *db, const char *filename, dns_masterformat_t format, unsigned int options) { isc_result_t result, eresult; dns_rdatacallbacks_t callbacks; /* * Load master file 'filename' into 'db'. */ REQUIRE(DNS_DB_VALID(db)); if ((db->attributes & DNS_DBATTR_CACHE) != 0) options |= DNS_MASTER_AGETTL; dns_rdatacallbacks_init(&callbacks); result = dns_db_beginload(db, &callbacks); if (result != ISC_R_SUCCESS) return (result); result = dns_master_loadfile2(filename, &db->origin, &db->origin, db->rdclass, options, &callbacks, db->mctx, format); eresult = dns_db_endload(db, &callbacks); /* * We always call dns_db_endload(), but we only want to return its * result if dns_master_loadfile() succeeded. If dns_master_loadfile() * failed, we want to return the result code it gave us. */ if (eresult != ISC_R_SUCCESS && (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE)) result = eresult; return (result); } isc_result_t dns_db_serialize(dns_db_t *db, dns_dbversion_t *version, FILE *file) { REQUIRE(DNS_DB_VALID(db)); if (db->methods->serialize == NULL) return (ISC_R_NOTIMPLEMENTED); return ((db->methods->serialize)(db, version, file)); } isc_result_t dns_db_dump(dns_db_t *db, dns_dbversion_t *version, const char *filename) { return ((db->methods->dump)(db, version, filename, dns_masterformat_text)); } isc_result_t dns_db_dump2(dns_db_t *db, dns_dbversion_t *version, const char *filename, dns_masterformat_t masterformat) { /* * Dump 'db' into master file 'filename' in the 'masterformat' format. * XXXJT: is it okay to modify the interface to the existing "dump" * method? */ REQUIRE(DNS_DB_VALID(db)); return ((db->methods->dump)(db, version, filename, masterformat)); } /*** *** Version Methods ***/ void dns_db_currentversion(dns_db_t *db, dns_dbversion_t **versionp) { /* * Open the current version for reading. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0); REQUIRE(versionp != NULL && *versionp == NULL); (db->methods->currentversion)(db, versionp); } isc_result_t dns_db_newversion(dns_db_t *db, dns_dbversion_t **versionp) { /* * Open a new version for reading and writing. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0); REQUIRE(versionp != NULL && *versionp == NULL); return ((db->methods->newversion)(db, versionp)); } void dns_db_attachversion(dns_db_t *db, dns_dbversion_t *source, dns_dbversion_t **targetp) { /* * Attach '*targetp' to 'source'. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0); REQUIRE(source != NULL); REQUIRE(targetp != NULL && *targetp == NULL); (db->methods->attachversion)(db, source, targetp); ENSURE(*targetp != NULL); } void dns_db_closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) { /* * Close version '*versionp'. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0); REQUIRE(versionp != NULL && *versionp != NULL); (db->methods->closeversion)(db, versionp, commit); ENSURE(*versionp == NULL); } /*** *** Node Methods ***/ isc_result_t dns_db_findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, dns_dbnode_t **nodep) { /* * Find the node with name 'name'. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE(nodep != NULL && *nodep == NULL); if (db->methods->findnode != NULL) return ((db->methods->findnode)(db, name, create, nodep)); else return ((db->methods->findnodeext)(db, name, create, NULL, NULL, nodep)); } isc_result_t dns_db_findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep) { /* * Find the node with name 'name', passing 'arg' to the database * implementation. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE(nodep != NULL && *nodep == NULL); if (db->methods->findnodeext != NULL) return ((db->methods->findnodeext)(db, name, create, methods, clientinfo, nodep)); else return ((db->methods->findnode)(db, name, create, nodep)); } isc_result_t dns_db_findnsec3node(dns_db_t *db, dns_name_t *name, isc_boolean_t create, dns_dbnode_t **nodep) { /* * Find the node with name 'name'. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE(nodep != NULL && *nodep == NULL); return ((db->methods->findnsec3node)(db, name, create, nodep)); } isc_result_t dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { /* * Find the best match for 'name' and 'type' in version 'version' * of 'db'. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE(type != dns_rdatatype_rrsig); REQUIRE(nodep == NULL || (nodep != NULL && *nodep == NULL)); REQUIRE(dns_name_hasbuffer(foundname)); REQUIRE(rdataset == NULL || (DNS_RDATASET_VALID(rdataset) && ! dns_rdataset_isassociated(rdataset))); REQUIRE(sigrdataset == NULL || (DNS_RDATASET_VALID(sigrdataset) && ! dns_rdataset_isassociated(sigrdataset))); if (db->methods->find != NULL) return ((db->methods->find)(db, name, version, type, options, now, nodep, foundname, rdataset, sigrdataset)); else return ((db->methods->findext)(db, name, version, type, options, now, nodep, foundname, NULL, NULL, rdataset, sigrdataset)); } isc_result_t dns_db_findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { /* * Find the best match for 'name' and 'type' in version 'version' * of 'db', passing in 'arg'. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE(type != dns_rdatatype_rrsig); REQUIRE(nodep == NULL || (nodep != NULL && *nodep == NULL)); REQUIRE(dns_name_hasbuffer(foundname)); REQUIRE(rdataset == NULL || (DNS_RDATASET_VALID(rdataset) && ! dns_rdataset_isassociated(rdataset))); REQUIRE(sigrdataset == NULL || (DNS_RDATASET_VALID(sigrdataset) && ! dns_rdataset_isassociated(sigrdataset))); if (db->methods->findext != NULL) return ((db->methods->findext)(db, name, version, type, options, now, nodep, foundname, methods, clientinfo, rdataset, sigrdataset)); else return ((db->methods->find)(db, name, version, type, options, now, nodep, foundname, rdataset, sigrdataset)); } isc_result_t dns_db_findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { /* * Find the deepest known zonecut which encloses 'name' in 'db'. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE((db->attributes & DNS_DBATTR_CACHE) != 0); REQUIRE(nodep == NULL || (nodep != NULL && *nodep == NULL)); REQUIRE(dns_name_hasbuffer(foundname)); REQUIRE(sigrdataset == NULL || (DNS_RDATASET_VALID(sigrdataset) && ! dns_rdataset_isassociated(sigrdataset))); return ((db->methods->findzonecut)(db, name, options, now, nodep, foundname, rdataset, sigrdataset)); } void dns_db_attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) { /* * Attach *targetp to source. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE(source != NULL); REQUIRE(targetp != NULL && *targetp == NULL); (db->methods->attachnode)(db, source, targetp); } void dns_db_detachnode(dns_db_t *db, dns_dbnode_t **nodep) { /* * Detach *nodep from its node. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE(nodep != NULL && *nodep != NULL); (db->methods->detachnode)(db, nodep); ENSURE(*nodep == NULL); } void dns_db_transfernode(dns_db_t *db, dns_dbnode_t **sourcep, dns_dbnode_t **targetp) { REQUIRE(DNS_DB_VALID(db)); REQUIRE(targetp != NULL && *targetp == NULL); /* * This doesn't check the implementation magic. If we find that * we need such checks in future then this will be done in the * method. */ REQUIRE(sourcep != NULL && *sourcep != NULL); UNUSED(db); if (db->methods->transfernode == NULL) { *targetp = *sourcep; *sourcep = NULL; } else (db->methods->transfernode)(db, sourcep, targetp); ENSURE(*sourcep == NULL); } isc_result_t dns_db_expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { /* * Mark as stale all records at 'node' which expire at or before 'now'. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE((db->attributes & DNS_DBATTR_CACHE) != 0); REQUIRE(node != NULL); return ((db->methods->expirenode)(db, node, now)); } void dns_db_printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) { /* * Print a textual representation of the contents of the node to * 'out'. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE(node != NULL); (db->methods->printnode)(db, node, out); } /*** *** DB Iterator Creation ***/ isc_result_t dns_db_createiterator(dns_db_t *db, unsigned int flags, dns_dbiterator_t **iteratorp) { /* * Create an iterator for version 'version' of 'db'. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE(iteratorp != NULL && *iteratorp == NULL); return (db->methods->createiterator(db, flags, iteratorp)); } /*** *** Rdataset Methods ***/ isc_result_t dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdatatype_t type, dns_rdatatype_t covers, isc_stdtime_t now, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { REQUIRE(DNS_DB_VALID(db)); REQUIRE(node != NULL); REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(! dns_rdataset_isassociated(rdataset)); REQUIRE(covers == 0 || type == dns_rdatatype_rrsig); REQUIRE(type != dns_rdatatype_any); REQUIRE(sigrdataset == NULL || (DNS_RDATASET_VALID(sigrdataset) && ! dns_rdataset_isassociated(sigrdataset))); return ((db->methods->findrdataset)(db, node, version, type, covers, now, rdataset, sigrdataset)); } isc_result_t dns_db_allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_stdtime_t now, dns_rdatasetiter_t **iteratorp) { /* * Make '*iteratorp' an rdataset iteratator for all rdatasets at * 'node' in version 'version' of 'db'. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE(iteratorp != NULL && *iteratorp == NULL); return ((db->methods->allrdatasets)(db, node, version, now, iteratorp)); } isc_result_t dns_db_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options, dns_rdataset_t *addedrdataset) { /* * Add 'rdataset' to 'node' in version 'version' of 'db'. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE(node != NULL); REQUIRE(((db->attributes & DNS_DBATTR_CACHE) == 0 && version != NULL)|| ((db->attributes & DNS_DBATTR_CACHE) != 0 && version == NULL && (options & DNS_DBADD_MERGE) == 0)); REQUIRE((options & DNS_DBADD_EXACT) == 0 || (options & DNS_DBADD_MERGE) != 0); REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(dns_rdataset_isassociated(rdataset)); REQUIRE(rdataset->rdclass == db->rdclass); REQUIRE(addedrdataset == NULL || (DNS_RDATASET_VALID(addedrdataset) && ! dns_rdataset_isassociated(addedrdataset))); return ((db->methods->addrdataset)(db, node, version, now, rdataset, options, addedrdataset)); } isc_result_t dns_db_subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdataset_t *rdataset, unsigned int options, dns_rdataset_t *newrdataset) { /* * Remove any rdata in 'rdataset' from 'node' in version 'version' of * 'db'. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE(node != NULL); REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0 && version != NULL); REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(dns_rdataset_isassociated(rdataset)); REQUIRE(rdataset->rdclass == db->rdclass); REQUIRE(newrdataset == NULL || (DNS_RDATASET_VALID(newrdataset) && ! dns_rdataset_isassociated(newrdataset))); return ((db->methods->subtractrdataset)(db, node, version, rdataset, options, newrdataset)); } isc_result_t dns_db_deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdatatype_t type, dns_rdatatype_t covers) { /* * Make it so that no rdataset of type 'type' exists at 'node' in * version version 'version' of 'db'. */ REQUIRE(DNS_DB_VALID(db)); REQUIRE(node != NULL); REQUIRE(((db->attributes & DNS_DBATTR_CACHE) == 0 && version != NULL)|| ((db->attributes & DNS_DBATTR_CACHE) != 0 && version == NULL)); return ((db->methods->deleterdataset)(db, node, version, type, covers)); } void dns_db_overmem(dns_db_t *db, isc_boolean_t overmem) { REQUIRE(DNS_DB_VALID(db)); (db->methods->overmem)(db, overmem); } isc_result_t dns_db_getsoaserial(dns_db_t *db, dns_dbversion_t *ver, isc_uint32_t *serialp) { isc_result_t result; dns_dbnode_t *node = NULL; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; isc_buffer_t buffer; REQUIRE(dns_db_iszone(db) || dns_db_isstub(db)); result = dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node); if (result != ISC_R_SUCCESS) return (result); dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0, (isc_stdtime_t)0, &rdataset, NULL); if (result != ISC_R_SUCCESS) goto freenode; result = dns_rdataset_first(&rdataset); if (result != ISC_R_SUCCESS) goto freerdataset; dns_rdataset_current(&rdataset, &rdata); result = dns_rdataset_next(&rdataset); INSIST(result == ISC_R_NOMORE); INSIST(rdata.length > 20); isc_buffer_init(&buffer, rdata.data, rdata.length); isc_buffer_add(&buffer, rdata.length); isc_buffer_forward(&buffer, rdata.length - 20); *serialp = isc_buffer_getuint32(&buffer); result = ISC_R_SUCCESS; freerdataset: dns_rdataset_disassociate(&rdataset); freenode: dns_db_detachnode(db, &node); return (result); } unsigned int dns_db_nodecount(dns_db_t *db) { REQUIRE(DNS_DB_VALID(db)); return ((db->methods->nodecount)(db)); } unsigned int dns_db_hashsize(dns_db_t *db) { REQUIRE(DNS_DB_VALID(db)); if (db->methods->hashsize == NULL) return (ISC_R_NOTIMPLEMENTED); return ((db->methods->hashsize)(db)); } void dns_db_settask(dns_db_t *db, isc_task_t *task) { REQUIRE(DNS_DB_VALID(db)); (db->methods->settask)(db, task); } isc_result_t dns_db_register(const char *name, dns_dbcreatefunc_t create, void *driverarg, isc_mem_t *mctx, dns_dbimplementation_t **dbimp) { dns_dbimplementation_t *imp; REQUIRE(name != NULL); REQUIRE(dbimp != NULL && *dbimp == NULL); RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); RWLOCK(&implock, isc_rwlocktype_write); imp = impfind(name); if (imp != NULL) { RWUNLOCK(&implock, isc_rwlocktype_write); return (ISC_R_EXISTS); } imp = isc_mem_get(mctx, sizeof(dns_dbimplementation_t)); if (imp == NULL) { RWUNLOCK(&implock, isc_rwlocktype_write); return (ISC_R_NOMEMORY); } imp->name = name; imp->create = create; imp->mctx = NULL; imp->driverarg = driverarg; isc_mem_attach(mctx, &imp->mctx); ISC_LINK_INIT(imp, link); ISC_LIST_APPEND(implementations, imp, link); RWUNLOCK(&implock, isc_rwlocktype_write); *dbimp = imp; return (ISC_R_SUCCESS); } void dns_db_unregister(dns_dbimplementation_t **dbimp) { dns_dbimplementation_t *imp; isc_mem_t *mctx; REQUIRE(dbimp != NULL && *dbimp != NULL); RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); imp = *dbimp; *dbimp = NULL; RWLOCK(&implock, isc_rwlocktype_write); ISC_LIST_UNLINK(implementations, imp, link); mctx = imp->mctx; isc_mem_put(mctx, imp, sizeof(dns_dbimplementation_t)); isc_mem_detach(&mctx); RWUNLOCK(&implock, isc_rwlocktype_write); ENSURE(*dbimp == NULL); } isc_result_t dns_db_getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) { REQUIRE(DNS_DB_VALID(db)); REQUIRE(dns_db_iszone(db) == ISC_TRUE); REQUIRE(nodep != NULL && *nodep == NULL); if (db->methods->getoriginnode != NULL) return ((db->methods->getoriginnode)(db, nodep)); return (ISC_R_NOTFOUND); } dns_stats_t * dns_db_getrrsetstats(dns_db_t *db) { REQUIRE(DNS_DB_VALID(db)); if (db->methods->getrrsetstats != NULL) return ((db->methods->getrrsetstats)(db)); return (NULL); } isc_result_t dns_db_setcachestats(dns_db_t *db, isc_stats_t *stats) { REQUIRE(DNS_DB_VALID(db)); if (db->methods->setcachestats != NULL) return ((db->methods->setcachestats)(db, stats)); return (ISC_R_NOTIMPLEMENTED); } isc_result_t dns_db_getnsec3parameters(dns_db_t *db, dns_dbversion_t *version, dns_hash_t *hash, isc_uint8_t *flags, isc_uint16_t *iterations, unsigned char *salt, size_t *salt_length) { REQUIRE(DNS_DB_VALID(db)); REQUIRE(dns_db_iszone(db) == ISC_TRUE); if (db->methods->getnsec3parameters != NULL) return ((db->methods->getnsec3parameters)(db, version, hash, flags, iterations, salt, salt_length)); return (ISC_R_NOTFOUND); } isc_result_t dns_db_setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, isc_stdtime_t resign) { if (db->methods->setsigningtime != NULL) return ((db->methods->setsigningtime)(db, rdataset, resign)); return (ISC_R_NOTIMPLEMENTED); } isc_result_t dns_db_getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, dns_name_t *name) { if (db->methods->getsigningtime != NULL) return ((db->methods->getsigningtime)(db, rdataset, name)); return (ISC_R_NOTFOUND); } void dns_db_resigned(dns_db_t *db, dns_rdataset_t *rdataset, dns_dbversion_t *version) { if (db->methods->resigned != NULL) (db->methods->resigned)(db, rdataset, version); } /* * Attach a database to policy zone databases. * This should only happen when the caller has already ensured that * it is dealing with a database that understands response policy zones. */ void dns_db_rpz_attach(dns_db_t *db, dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num) { REQUIRE(db->methods->rpz_attach != NULL); (db->methods->rpz_attach)(db, rpzs, rpz_num); } /* * Finish loading a response policy zone. */ isc_result_t dns_db_rpz_ready(dns_db_t *db) { if (db->methods->rpz_ready == NULL) return (ISC_R_SUCCESS); return ((db->methods->rpz_ready)(db)); } bind9-9.10.3.dfsg.P4/lib/dns/Makefile.in0000644000470500017500000001444512664710322017000 0ustar lamontlamont# Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2003 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ # Attempt to disable parallel processing. .NOTPARALLEL: .NO_PARALLEL: @BIND9_VERSION@ @BIND9_MAJOR@ @LIBDNS_MAPAPI@ @LIBDNS_API@ @BIND9_MAKE_INCLUDES@ USE_ISC_SPNEGO = @USE_ISC_SPNEGO@ CINCLUDES = -I. -I${top_srcdir}/lib/dns -Iinclude ${DNS_INCLUDES} \ ${ISC_INCLUDES} @DST_OPENSSL_INC@ @DST_GSSAPI_INC@ CDEFINES = -DUSE_MD5 @CRYPTO@ @USE_GSSAPI@ ${USE_ISC_SPNEGO} CWARNINGS = ISCLIBS = ../../lib/isc/libisc.@A@ ISCDEPLIBS = ../../lib/isc/libisc.@A@ LIBS = @LIBS@ # Alphabetically OPENSSLGOSTLINKOBJS = opensslgost_link.@O@ OPENSSLLINKOBJS = openssl_link.@O@ openssldh_link.@O@ openssldsa_link.@O@ \ opensslecdsa_link.@O@ @OPENSSLGOSTLINKOBJS@ \ opensslrsa_link.@O@ PKCS11LINKOBJS = pkcs11dh_link.@O@ pkcs11dsa_link.@O@ pkcs11rsa_link.@O@ \ pkcs11ecdsa_link.@O@ pkcs11gost_link.@O@ pkcs11.@O@ DSTOBJS = @DST_EXTRA_OBJS@ @OPENSSLLINKOBJS@ @PKCS11LINKOBJS@ \ dst_api.@O@ dst_lib.@O@ dst_parse.@O@ dst_result.@O@ \ gssapi_link.@O@ gssapictx.@O@ hmac_link.@O@ key.@O@ GEOIPLINKOBJS = geoip.@O@ # Alphabetically DNSOBJS = acache.@O@ acl.@O@ adb.@O@ byaddr.@O@ \ cache.@O@ callbacks.@O@ clientinfo.@O@ compress.@O@ \ db.@O@ dbiterator.@O@ dbtable.@O@ diff.@O@ dispatch.@O@ \ dlz.@O@ dns64.@O@ dnssec.@O@ ds.@O@ forward.@O@ \ iptable.@O@ journal.@O@ keydata.@O@ keytable.@O@ \ lib.@O@ log.@O@ lookup.@O@ \ master.@O@ masterdump.@O@ message.@O@ \ name.@O@ ncache.@O@ nsec.@O@ nsec3.@O@ order.@O@ peer.@O@ \ portlist.@O@ private.@O@ \ rbt.@O@ rbtdb.@O@ rbtdb64.@O@ rcode.@O@ rdata.@O@ \ rdatalist.@O@ rdataset.@O@ rdatasetiter.@O@ rdataslab.@O@ \ request.@O@ resolver.@O@ result.@O@ rootns.@O@ \ rpz.@O@ rrl.@O@ rriterator.@O@ sdb.@O@ \ sdlz.@O@ soa.@O@ ssu.@O@ ssu_external.@O@ \ stats.@O@ tcpmsg.@O@ time.@O@ timer.@O@ tkey.@O@ \ tsec.@O@ tsig.@O@ ttl.@O@ update.@O@ validator.@O@ \ version.@O@ view.@O@ xfrin.@O@ zone.@O@ zonekey.@O@ zt.@O@ PORTDNSOBJS = client.@O@ ecdb.@O@ OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS} ${PORTDNSOBJS} \ @GEOIPLINKOBJS@ # Alphabetically OPENSSLGOSTLINKSRCS = opensslgost_link.c OPENSSLLINKSRCS = openssl_link.c openssldh_link.c openssldsa_link.c \ opensslecdsa_link.c @OPENSSLGOSTLINKSRCS@ opensslrsa_link.c PKCS11LINKSRCS = pkcs11dh_link.c pkcs11dsa_link.c pkcs11rsa_link.c \ pkcs11ecdsa_link.c pkcs11gost_link.c pkcs11.c DSTSRCS = @DST_EXTRA_SRCS@ @OPENSSLLINKSRCS@ @PKCS11LINKSRCS@ \ dst_api.c dst_lib.c dst_parse.c \ dst_result.c gssapi_link.c gssapictx.c \ hmac_link.c key.c GEOIOLINKSRCS = geoip.c DNSSRCS = acache.c acl.c adb.c byaddr.c \ cache.c callbacks.c clientinfo.c compress.c \ db.c dbiterator.c dbtable.c diff.c dispatch.c \ dlz.c dns64.c dnssec.c ds.c forward.c geoip.c \ iptable.c journal.c keydata.c keytable.c lib.c log.c \ lookup.c master.c masterdump.c message.c \ name.c ncache.c nsec.c nsec3.c order.c peer.c portlist.c \ rbt.c rbtdb.c rbtdb64.c rcode.c rdata.c rdatalist.c \ rdataset.c rdatasetiter.c rdataslab.c request.c \ resolver.c result.c rootns.c rpz.c rrl.c rriterator.c \ sdb.c sdlz.c soa.c ssu.c ssu_external.c \ stats.c tcpmsg.c time.c timer.c tkey.c \ tsec.c tsig.c ttl.c update.c validator.c \ version.c view.c xfrin.c zone.c zonekey.c zt.c ${OTHERSRCS} PORTDNSSRCS = client.c ecdb.c SRCS = ${DSTSRCS} ${DNSSRCS} ${PORTDNSSRCS} @GEOIPLINKSRCS@ SUBDIRS = include TARGETS = include/dns/enumtype.h include/dns/enumclass.h \ include/dns/rdatastruct.h timestamp TESTDIRS = @UNITTESTS@ DEPENDEXTRA = ./gen -F include/dns/rdatastruct.h \ -s ${srcdir} -d >> Makefile ; @BIND9_MAKE_RULES@ version.@O@: version.c ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ -DVERSION=\"${VERSION}\" \ -DMAJOR=\"${MAJOR}\" \ -DMAPAPI=\"${MAPAPI}\" \ -DLIBINTERFACE=${LIBINTERFACE} \ -DLIBREVISION=${LIBREVISION} \ -DLIBAGE=${LIBAGE} \ -c ${srcdir}/version.c libdns.@SA@: ${OBJS} ${AR} ${ARFLAGS} $@ ${OBJS} ${RANLIB} $@ libdns.la: ${OBJS} ${LIBTOOL_MODE_LINK} \ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libdns.la -rpath ${libdir} \ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \ ${OBJS} ${ISCLIBS} @DNS_CRYPTO_LIBS@ ${LIBS} timestamp: libdns.@A@ touch timestamp installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${libdir} install:: timestamp installdirs ${LIBTOOL_MODE_INSTALL} ${INSTALL_LIBRARY} libdns.@A@ ${DESTDIR}${libdir} clean distclean:: rm -f libdns.@A@ timestamp rm -f gen code.h include/dns/enumtype.h include/dns/enumclass.h rm -f include/dns/rdatastruct.h newrr:: rm -f code.h include/dns/enumtype.h include/dns/enumclass.h rm -f include/dns/rdatastruct.h include: include/dns/enumtype.h include/dns/enumclass.h \ include/dns/rdatastruct.h rdata.@O@: code.h include/dns/enumtype.h: gen ./gen -s ${srcdir} -t > $@ include/dns/enumclass.h: gen ./gen -s ${srcdir} -c > $@ include/dns/rdatastruct.h: gen \ ${srcdir}/rdata/rdatastructpre.h \ ${srcdir}/rdata/rdatastructsuf.h ./gen -s ${srcdir} -i \ -P ${srcdir}/rdata/rdatastructpre.h \ -S ${srcdir}/rdata/rdatastructsuf.h > $@ code.h: gen ./gen -s ${srcdir} > code.h gen: gen.c ${BUILD_CC} ${BUILD_CFLAGS} -I${top_srcdir}/lib/isc/include \ ${BUILD_CPPFLAGS} ${BUILD_LDFLAGS} -o $@ ${srcdir}/gen.c ${BUILD_LIBS} rbtdb64.@O@: rbtdb64.c rbtdb.c depend: include/dns/enumtype.h include/dns/enumclass.h \ include/dns/rdatastruct.h code.h subdirs: include/dns/enumtype.h include/dns/enumclass.h \ include/dns/rdatastruct.h code.h ${OBJS}: include/dns/enumtype.h include/dns/enumclass.h \ include/dns/rdatastruct.h spnego.@O@: spnego_asn1.c spnego.h bind9-9.10.3.dfsg.P4/lib/dns/rootns.c0000644000470500017500000004162412664710322016422 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2008, 2010, 2012-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rootns.c,v 1.40.476.1 2012/02/07 00:44:14 each Exp $ */ /*! \file */ #include #include #include /* Required for HP/UX (and others?) */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static char root_ns[] = ";\n" "; Internet Root Nameservers\n" ";\n" "$TTL 518400\n" ". 518400 IN NS A.ROOT-SERVERS.NET.\n" ". 518400 IN NS B.ROOT-SERVERS.NET.\n" ". 518400 IN NS C.ROOT-SERVERS.NET.\n" ". 518400 IN NS D.ROOT-SERVERS.NET.\n" ". 518400 IN NS E.ROOT-SERVERS.NET.\n" ". 518400 IN NS F.ROOT-SERVERS.NET.\n" ". 518400 IN NS G.ROOT-SERVERS.NET.\n" ". 518400 IN NS H.ROOT-SERVERS.NET.\n" ". 518400 IN NS I.ROOT-SERVERS.NET.\n" ". 518400 IN NS J.ROOT-SERVERS.NET.\n" ". 518400 IN NS K.ROOT-SERVERS.NET.\n" ". 518400 IN NS L.ROOT-SERVERS.NET.\n" ". 518400 IN NS M.ROOT-SERVERS.NET.\n" "A.ROOT-SERVERS.NET. 3600000 IN A 198.41.0.4\n" "A.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:503:BA3E::2:30\n" "B.ROOT-SERVERS.NET. 3600000 IN A 192.228.79.201\n" "C.ROOT-SERVERS.NET. 3600000 IN A 192.33.4.12\n" "C.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:2::c\n" "D.ROOT-SERVERS.NET. 3600000 IN A 199.7.91.13\n" "D.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:2d::d\n" "E.ROOT-SERVERS.NET. 3600000 IN A 192.203.230.10\n" "F.ROOT-SERVERS.NET. 3600000 IN A 192.5.5.241\n" "F.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:2F::F\n" "G.ROOT-SERVERS.NET. 3600000 IN A 192.112.36.4\n" "H.ROOT-SERVERS.NET. 3600000 IN A 198.97.190.53\n" "H.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:1::53\n" "I.ROOT-SERVERS.NET. 3600000 IN A 192.36.148.17\n" "I.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:7fe::53\n" "J.ROOT-SERVERS.NET. 3600000 IN A 192.58.128.30\n" "J.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:503:C27::2:30\n" "K.ROOT-SERVERS.NET. 3600000 IN A 193.0.14.129\n" "K.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:7FD::1\n" "L.ROOT-SERVERS.NET. 3600000 IN A 199.7.83.42\n" "L.ROOT-SERVERS.NET. 604800 IN AAAA 2001:500:3::42\n" "M.ROOT-SERVERS.NET. 3600000 IN A 202.12.27.33\n" "M.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:DC3::35\n"; static isc_result_t in_rootns(dns_rdataset_t *rootns, dns_name_t *name) { isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_ns_t ns; if (!dns_rdataset_isassociated(rootns)) return (ISC_R_NOTFOUND); result = dns_rdataset_first(rootns); while (result == ISC_R_SUCCESS) { dns_rdataset_current(rootns, &rdata); result = dns_rdata_tostruct(&rdata, &ns, NULL); if (result != ISC_R_SUCCESS) return (result); if (dns_name_compare(name, &ns.name) == 0) return (ISC_R_SUCCESS); result = dns_rdataset_next(rootns); dns_rdata_reset(&rdata); } if (result == ISC_R_NOMORE) result = ISC_R_NOTFOUND; return (result); } static isc_result_t check_node(dns_rdataset_t *rootns, dns_name_t *name, dns_rdatasetiter_t *rdsiter) { isc_result_t result; dns_rdataset_t rdataset; dns_rdataset_init(&rdataset); result = dns_rdatasetiter_first(rdsiter); while (result == ISC_R_SUCCESS) { dns_rdatasetiter_current(rdsiter, &rdataset); switch (rdataset.type) { case dns_rdatatype_a: case dns_rdatatype_aaaa: result = in_rootns(rootns, name); if (result != ISC_R_SUCCESS) goto cleanup; break; case dns_rdatatype_ns: if (dns_name_compare(name, dns_rootname) == 0) break; /*FALLTHROUGH*/ default: result = ISC_R_FAILURE; goto cleanup; } dns_rdataset_disassociate(&rdataset); result = dns_rdatasetiter_next(rdsiter); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; cleanup: if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); return (result); } static isc_result_t check_hints(dns_db_t *db) { isc_result_t result; dns_rdataset_t rootns; dns_dbiterator_t *dbiter = NULL; dns_dbnode_t *node = NULL; isc_stdtime_t now; dns_fixedname_t fixname; dns_name_t *name; dns_rdatasetiter_t *rdsiter = NULL; isc_stdtime_get(&now); dns_fixedname_init(&fixname); name = dns_fixedname_name(&fixname); dns_rdataset_init(&rootns); (void)dns_db_find(db, dns_rootname, NULL, dns_rdatatype_ns, 0, now, NULL, name, &rootns, NULL); result = dns_db_createiterator(db, 0, &dbiter); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_dbiterator_first(dbiter); while (result == ISC_R_SUCCESS) { result = dns_dbiterator_current(dbiter, &node, name); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_db_allrdatasets(db, node, NULL, now, &rdsiter); if (result != ISC_R_SUCCESS) goto cleanup; result = check_node(&rootns, name, rdsiter); if (result != ISC_R_SUCCESS) goto cleanup; dns_rdatasetiter_destroy(&rdsiter); dns_db_detachnode(db, &node); result = dns_dbiterator_next(dbiter); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; cleanup: if (dns_rdataset_isassociated(&rootns)) dns_rdataset_disassociate(&rootns); if (rdsiter != NULL) dns_rdatasetiter_destroy(&rdsiter); if (node != NULL) dns_db_detachnode(db, &node); if (dbiter != NULL) dns_dbiterator_destroy(&dbiter); return (result); } isc_result_t dns_rootns_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, const char *filename, dns_db_t **target) { isc_result_t result, eresult; isc_buffer_t source; unsigned int len; dns_rdatacallbacks_t callbacks; dns_db_t *db = NULL; REQUIRE(target != NULL && *target == NULL); result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, rdclass, 0, NULL, &db); if (result != ISC_R_SUCCESS) goto failure; len = strlen(root_ns); isc_buffer_init(&source, root_ns, len); isc_buffer_add(&source, len); dns_rdatacallbacks_init(&callbacks); result = dns_db_beginload(db, &callbacks); if (result != ISC_R_SUCCESS) goto failure; if (filename != NULL) { /* * Load the hints from the specified filename. */ result = dns_master_loadfile(filename, &db->origin, &db->origin, db->rdclass, DNS_MASTER_HINT, &callbacks, db->mctx); } else if (rdclass == dns_rdataclass_in) { /* * Default to using the Internet root servers. */ result = dns_master_loadbuffer(&source, &db->origin, &db->origin, db->rdclass, DNS_MASTER_HINT, &callbacks, db->mctx); } else result = ISC_R_NOTFOUND; eresult = dns_db_endload(db, &callbacks); if (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) result = eresult; if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) goto failure; if (check_hints(db) != ISC_R_SUCCESS) isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_HINTS, ISC_LOG_WARNING, "extra data in root hints '%s'", (filename != NULL) ? filename : ""); *target = db; return (ISC_R_SUCCESS); failure: isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_HINTS, ISC_LOG_ERROR, "could not configure root hints from " "'%s': %s", (filename != NULL) ? filename : "", isc_result_totext(result)); if (db != NULL) dns_db_detach(&db); return (result); } static void report(dns_view_t *view, dns_name_t *name, isc_boolean_t missing, dns_rdata_t *rdata) { const char *viewname = "", *sep = ""; char namebuf[DNS_NAME_FORMATSIZE]; char typebuf[DNS_RDATATYPE_FORMATSIZE]; char databuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123")]; isc_buffer_t buffer; isc_result_t result; if (strcmp(view->name, "_bind") != 0 && strcmp(view->name, "_default") != 0) { viewname = view->name; sep = ": view "; } dns_name_format(name, namebuf, sizeof(namebuf)); dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf)); isc_buffer_init(&buffer, databuf, sizeof(databuf) - 1); result = dns_rdata_totext(rdata, NULL, &buffer); RUNTIME_CHECK(result == ISC_R_SUCCESS); databuf[isc_buffer_usedlength(&buffer)] = '\0'; if (missing) isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_HINTS, ISC_LOG_WARNING, "checkhints%s%s: %s/%s (%s) missing from hints", sep, viewname, namebuf, typebuf, databuf); else isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_HINTS, ISC_LOG_WARNING, "checkhints%s%s: %s/%s (%s) extra record " "in hints", sep, viewname, namebuf, typebuf, databuf); } static isc_boolean_t inrrset(dns_rdataset_t *rrset, dns_rdata_t *rdata) { isc_result_t result; dns_rdata_t current = DNS_RDATA_INIT; result = dns_rdataset_first(rrset); while (result == ISC_R_SUCCESS) { dns_rdataset_current(rrset, ¤t); if (dns_rdata_compare(rdata, ¤t) == 0) return (ISC_TRUE); dns_rdata_reset(¤t); result = dns_rdataset_next(rrset); } return (ISC_FALSE); } /* * Check that the address RRsets match. * * Note we don't complain about missing glue records. */ static void check_address_records(dns_view_t *view, dns_db_t *hints, dns_db_t *db, dns_name_t *name, isc_stdtime_t now) { isc_result_t hresult, rresult, result; dns_rdataset_t hintrrset, rootrrset; dns_rdata_t rdata = DNS_RDATA_INIT; dns_name_t *foundname; dns_fixedname_t fixed; dns_rdataset_init(&hintrrset); dns_rdataset_init(&rootrrset); dns_fixedname_init(&fixed); foundname = dns_fixedname_name(&fixed); hresult = dns_db_find(hints, name, NULL, dns_rdatatype_a, 0, now, NULL, foundname, &hintrrset, NULL); rresult = dns_db_find(db, name, NULL, dns_rdatatype_a, DNS_DBFIND_GLUEOK, now, NULL, foundname, &rootrrset, NULL); if (hresult == ISC_R_SUCCESS && (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) { result = dns_rdataset_first(&rootrrset); while (result == ISC_R_SUCCESS) { dns_rdata_reset(&rdata); dns_rdataset_current(&rootrrset, &rdata); if (!inrrset(&hintrrset, &rdata)) report(view, name, ISC_TRUE, &rdata); result = dns_rdataset_next(&rootrrset); } result = dns_rdataset_first(&hintrrset); while (result == ISC_R_SUCCESS) { dns_rdata_reset(&rdata); dns_rdataset_current(&hintrrset, &rdata); if (!inrrset(&rootrrset, &rdata)) report(view, name, ISC_FALSE, &rdata); result = dns_rdataset_next(&hintrrset); } } if (hresult == ISC_R_NOTFOUND && (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) { result = dns_rdataset_first(&rootrrset); while (result == ISC_R_SUCCESS) { dns_rdata_reset(&rdata); dns_rdataset_current(&rootrrset, &rdata); report(view, name, ISC_TRUE, &rdata); result = dns_rdataset_next(&rootrrset); } } if (dns_rdataset_isassociated(&rootrrset)) dns_rdataset_disassociate(&rootrrset); if (dns_rdataset_isassociated(&hintrrset)) dns_rdataset_disassociate(&hintrrset); /* * Check AAAA records. */ hresult = dns_db_find(hints, name, NULL, dns_rdatatype_aaaa, 0, now, NULL, foundname, &hintrrset, NULL); rresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, DNS_DBFIND_GLUEOK, now, NULL, foundname, &rootrrset, NULL); if (hresult == ISC_R_SUCCESS && (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) { result = dns_rdataset_first(&rootrrset); while (result == ISC_R_SUCCESS) { dns_rdata_reset(&rdata); dns_rdataset_current(&rootrrset, &rdata); if (!inrrset(&hintrrset, &rdata)) report(view, name, ISC_TRUE, &rdata); dns_rdata_reset(&rdata); result = dns_rdataset_next(&rootrrset); } result = dns_rdataset_first(&hintrrset); while (result == ISC_R_SUCCESS) { dns_rdata_reset(&rdata); dns_rdataset_current(&hintrrset, &rdata); if (!inrrset(&rootrrset, &rdata)) report(view, name, ISC_FALSE, &rdata); dns_rdata_reset(&rdata); result = dns_rdataset_next(&hintrrset); } } if (hresult == ISC_R_NOTFOUND && (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) { result = dns_rdataset_first(&rootrrset); while (result == ISC_R_SUCCESS) { dns_rdata_reset(&rdata); dns_rdataset_current(&rootrrset, &rdata); report(view, name, ISC_TRUE, &rdata); dns_rdata_reset(&rdata); result = dns_rdataset_next(&rootrrset); } } if (dns_rdataset_isassociated(&rootrrset)) dns_rdataset_disassociate(&rootrrset); if (dns_rdataset_isassociated(&hintrrset)) dns_rdataset_disassociate(&hintrrset); } void dns_root_checkhints(dns_view_t *view, dns_db_t *hints, dns_db_t *db) { isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_ns_t ns; dns_rdataset_t hintns, rootns; const char *viewname = "", *sep = ""; isc_stdtime_t now; dns_name_t *name; dns_fixedname_t fixed; REQUIRE(hints != NULL); REQUIRE(db != NULL); REQUIRE(view != NULL); isc_stdtime_get(&now); if (strcmp(view->name, "_bind") != 0 && strcmp(view->name, "_default") != 0) { viewname = view->name; sep = ": view "; } dns_rdataset_init(&hintns); dns_rdataset_init(&rootns); dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); result = dns_db_find(hints, dns_rootname, NULL, dns_rdatatype_ns, 0, now, NULL, name, &hintns, NULL); if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_HINTS, ISC_LOG_WARNING, "checkhints%s%s: unable to get root NS rrset " "from hints: %s", sep, viewname, dns_result_totext(result)); goto cleanup; } result = dns_db_find(db, dns_rootname, NULL, dns_rdatatype_ns, 0, now, NULL, name, &rootns, NULL); if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_HINTS, ISC_LOG_WARNING, "checkhints%s%s: unable to get root NS rrset " "from cache: %s", sep, viewname, dns_result_totext(result)); goto cleanup; } /* * Look for missing root NS names. */ result = dns_rdataset_first(&rootns); while (result == ISC_R_SUCCESS) { dns_rdataset_current(&rootns, &rdata); result = dns_rdata_tostruct(&rdata, &ns, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); result = in_rootns(&hintns, &ns.name); if (result != ISC_R_SUCCESS) { char namebuf[DNS_NAME_FORMATSIZE]; /* missing from hints */ dns_name_format(&ns.name, namebuf, sizeof(namebuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_HINTS, ISC_LOG_WARNING, "checkhints%s%s: unable to find root " "NS '%s' in hints", sep, viewname, namebuf); } else check_address_records(view, hints, db, &ns.name, now); dns_rdata_reset(&rdata); result = dns_rdataset_next(&rootns); } if (result != ISC_R_NOMORE) { goto cleanup; } /* * Look for extra root NS names. */ result = dns_rdataset_first(&hintns); while (result == ISC_R_SUCCESS) { dns_rdataset_current(&hintns, &rdata); result = dns_rdata_tostruct(&rdata, &ns, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); result = in_rootns(&rootns, &ns.name); if (result != ISC_R_SUCCESS) { char namebuf[DNS_NAME_FORMATSIZE]; /* extra entry in hints */ dns_name_format(&ns.name, namebuf, sizeof(namebuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_HINTS, ISC_LOG_WARNING, "checkhints%s%s: extra NS '%s' in hints", sep, viewname, namebuf); } dns_rdata_reset(&rdata); result = dns_rdataset_next(&hintns); } if (result != ISC_R_NOMORE) { goto cleanup; } cleanup: if (dns_rdataset_isassociated(&rootns)) dns_rdataset_disassociate(&rootns); if (dns_rdataset_isassociated(&hintns)) dns_rdataset_disassociate(&hintns); } bind9-9.10.3.dfsg.P4/lib/dns/rbtdb64.c0000644000470500017500000000173112664710322016340 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rbtdb64.c,v 1.11 2007/06/19 23:47:16 tbox Exp $ */ /*! \file */ #define DNS_RBTDB_VERSION64 1 #include "rbtdb.c" bind9-9.10.3.dfsg.P4/lib/dns/pkcs11dsa_link.c0000644000470500017500000007515312664710322017711 0ustar lamontlamont/* * Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef PKCS11CRYPTO #include #include #include #include #include #include #include #include "dst_internal.h" #include "dst_parse.h" #include "dst_pkcs11.h" #include /* * FIPS 186-2 DSA keys: * mechanisms: * CKM_DSA_SHA1, * CKM_DSA_KEY_PAIR_GEN, * CKM_DSA_PARAMETER_GEN * domain parameters: * object class CKO_DOMAIN_PARAMETERS * key type CKK_DSA * attribute CKA_PRIME (prime p) * attribute CKA_SUBPRIME (subprime q) * attribute CKA_BASE (base g) * optional attribute CKA_PRIME_BITS (p length in bits) * public keys: * object class CKO_PUBLIC_KEY * key type CKK_DSA * attribute CKA_PRIME (prime p) * attribute CKA_SUBPRIME (subprime q) * attribute CKA_BASE (base g) * attribute CKA_VALUE (public value y) * private keys: * object class CKO_PRIVATE_KEY * key type CKK_DSA * attribute CKA_PRIME (prime p) * attribute CKA_SUBPRIME (subprime q) * attribute CKA_BASE (base g) * attribute CKA_VALUE (private value x) * reuse CKA_PRIVATE_EXPONENT for key pair private value */ #define CKA_VALUE2 CKA_PRIVATE_EXPONENT #define DST_RET(a) {ret = a; goto err;} static CK_BBOOL truevalue = TRUE; static CK_BBOOL falsevalue = FALSE; static isc_result_t pkcs11dsa_todns(const dst_key_t *key, isc_buffer_t *data); static void pkcs11dsa_destroy(dst_key_t *key); static isc_result_t pkcs11dsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) { CK_RV rv; CK_MECHANISM mech = { CKM_DSA_SHA1, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; CK_KEY_TYPE keyType = CKK_DSA; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_PRIME, NULL, 0 }, { CKA_SUBPRIME, NULL, 0 }, { CKA_BASE, NULL, 0 }, { CKA_VALUE, NULL, 0 } }; CK_ATTRIBUTE *attr; pk11_object_t *dsa; pk11_context_t *pk11_ctx; isc_result_t ret; unsigned int i; pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_DSA, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_DSA)); if (ret != ISC_R_SUCCESS) goto err; dsa = key->keydata.pkey; if (dsa->ontoken && (dsa->object != CK_INVALID_HANDLE)) { pk11_ctx->ontoken = dsa->ontoken; pk11_ctx->object = dsa->object; goto token_key; } for (attr = pk11_attribute_first(dsa); attr != NULL; attr = pk11_attribute_next(dsa, attr)) switch (attr->type) { case CKA_PRIME: INSIST(keyTemplate[6].type == attr->type); keyTemplate[6].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[6].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[6].pValue, attr->pValue, attr->ulValueLen); keyTemplate[6].ulValueLen = attr->ulValueLen; break; case CKA_SUBPRIME: INSIST(keyTemplate[7].type == attr->type); keyTemplate[7].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[7].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[7].pValue, attr->pValue, attr->ulValueLen); keyTemplate[7].ulValueLen = attr->ulValueLen; break; case CKA_BASE: INSIST(keyTemplate[8].type == attr->type); keyTemplate[8].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[8].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[8].pValue, attr->pValue, attr->ulValueLen); keyTemplate[8].ulValueLen = attr->ulValueLen; break; case CKA_VALUE2: INSIST(keyTemplate[9].type == CKA_VALUE); keyTemplate[9].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[9].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[9].pValue, attr->pValue, attr->ulValueLen); keyTemplate[9].ulValueLen = attr->ulValueLen; break; } pk11_ctx->object = CK_INVALID_HANDLE; pk11_ctx->ontoken = ISC_FALSE; PK11_RET(pkcs_C_CreateObject, (pk11_ctx->session, keyTemplate, (CK_ULONG) 10, &pk11_ctx->object), ISC_R_FAILURE); token_key: PK11_RET(pkcs_C_SignInit, (pk11_ctx->session, &mech, pk11_ctx->object), ISC_R_FAILURE); dctx->ctxdata.pk11_ctx = pk11_ctx; for (i = 6; i <= 9; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } return (ISC_R_SUCCESS); err: if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); for (i = 6; i <= 9; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); } static isc_result_t pkcs11dsa_createctx_verify(dst_key_t *key, dst_context_t *dctx) { CK_RV rv; CK_MECHANISM mech = { CKM_DSA_SHA1, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; CK_KEY_TYPE keyType = CKK_DSA; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_PRIME, NULL, 0 }, { CKA_SUBPRIME, NULL, 0 }, { CKA_BASE, NULL, 0 }, { CKA_VALUE, NULL, 0 } }; CK_ATTRIBUTE *attr; pk11_object_t *dsa; pk11_context_t *pk11_ctx; isc_result_t ret; unsigned int i; pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_DSA, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_DSA)); if (ret != ISC_R_SUCCESS) goto err; dsa = key->keydata.pkey; if (dsa->ontoken && (dsa->object != CK_INVALID_HANDLE)) { pk11_ctx->ontoken = dsa->ontoken; pk11_ctx->object = dsa->object; goto token_key; } for (attr = pk11_attribute_first(dsa); attr != NULL; attr = pk11_attribute_next(dsa, attr)) switch (attr->type) { case CKA_PRIME: INSIST(keyTemplate[5].type == attr->type); keyTemplate[5].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[5].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[5].pValue, attr->pValue, attr->ulValueLen); keyTemplate[5].ulValueLen = attr->ulValueLen; break; case CKA_SUBPRIME: INSIST(keyTemplate[6].type == attr->type); keyTemplate[6].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[6].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[6].pValue, attr->pValue, attr->ulValueLen); keyTemplate[6].ulValueLen = attr->ulValueLen; break; case CKA_BASE: INSIST(keyTemplate[7].type == attr->type); keyTemplate[7].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[7].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[7].pValue, attr->pValue, attr->ulValueLen); keyTemplate[7].ulValueLen = attr->ulValueLen; break; case CKA_VALUE: INSIST(keyTemplate[8].type == attr->type); keyTemplate[8].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[8].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[8].pValue, attr->pValue, attr->ulValueLen); keyTemplate[8].ulValueLen = attr->ulValueLen; break; } pk11_ctx->object = CK_INVALID_HANDLE; pk11_ctx->ontoken = ISC_FALSE; PK11_RET(pkcs_C_CreateObject, (pk11_ctx->session, keyTemplate, (CK_ULONG) 9, &pk11_ctx->object), ISC_R_FAILURE); token_key: PK11_RET(pkcs_C_VerifyInit, (pk11_ctx->session, &mech, pk11_ctx->object), ISC_R_FAILURE); dctx->ctxdata.pk11_ctx = pk11_ctx; for (i = 5; i <= 8; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } return (ISC_R_SUCCESS); err: if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); for (i = 5; i <= 8; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); } static isc_result_t pkcs11dsa_createctx(dst_key_t *key, dst_context_t *dctx) { if (dctx->use == DO_SIGN) return (pkcs11dsa_createctx_sign(key, dctx)); else return (pkcs11dsa_createctx_verify(key, dctx)); } static void pkcs11dsa_destroyctx(dst_context_t *dctx) { pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; if (pk11_ctx != NULL) { if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); dctx->ctxdata.pk11_ctx = NULL; } } static isc_result_t pkcs11dsa_adddata(dst_context_t *dctx, const isc_region_t *data) { CK_RV rv; pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; isc_result_t ret = ISC_R_SUCCESS; if (dctx->use == DO_SIGN) PK11_CALL(pkcs_C_SignUpdate, (pk11_ctx->session, (CK_BYTE_PTR) data->base, (CK_ULONG) data->length), ISC_R_FAILURE); else PK11_CALL(pkcs_C_VerifyUpdate, (pk11_ctx->session, (CK_BYTE_PTR) data->base, (CK_ULONG) data->length), ISC_R_FAILURE); return (ret); } static isc_result_t pkcs11dsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { CK_RV rv; CK_ULONG siglen = ISC_SHA1_DIGESTLENGTH * 2; isc_region_t r; pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; isc_result_t ret = ISC_R_SUCCESS; unsigned int klen; isc_buffer_availableregion(sig, &r); if (r.length < ISC_SHA1_DIGESTLENGTH * 2 + 1) return (ISC_R_NOSPACE); PK11_RET(pkcs_C_SignFinal, (pk11_ctx->session, (CK_BYTE_PTR) r.base + 1, &siglen), DST_R_SIGNFAILURE); if (siglen != ISC_SHA1_DIGESTLENGTH * 2) return (DST_R_SIGNFAILURE); klen = (dctx->key->key_size - 512)/64; if (klen > 255) return (ISC_R_FAILURE); *r.base = klen; isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH * 2 + 1); err: return (ret); } static isc_result_t pkcs11dsa_verify(dst_context_t *dctx, const isc_region_t *sig) { CK_RV rv; pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; isc_result_t ret = ISC_R_SUCCESS; PK11_CALL(pkcs_C_VerifyFinal, (pk11_ctx->session, (CK_BYTE_PTR) sig->base + 1, (CK_ULONG) sig->length - 1), DST_R_VERIFYFAILURE); return (ret); } static isc_boolean_t pkcs11dsa_compare(const dst_key_t *key1, const dst_key_t *key2) { pk11_object_t *dsa1, *dsa2; CK_ATTRIBUTE *attr1, *attr2; dsa1 = key1->keydata.pkey; dsa2 = key2->keydata.pkey; if ((dsa1 == NULL) && (dsa2 == NULL)) return (ISC_TRUE); else if ((dsa1 == NULL) || (dsa2 == NULL)) return (ISC_FALSE); attr1 = pk11_attribute_bytype(dsa1, CKA_PRIME); attr2 = pk11_attribute_bytype(dsa2, CKA_PRIME); if ((attr1 == NULL) && (attr2 == NULL)) return (ISC_TRUE); else if ((attr1 == NULL) || (attr2 == NULL) || (attr1->ulValueLen != attr2->ulValueLen) || !isc_safe_memequal(attr1->pValue, attr2->pValue, attr1->ulValueLen)) return (ISC_FALSE); attr1 = pk11_attribute_bytype(dsa1, CKA_SUBPRIME); attr2 = pk11_attribute_bytype(dsa2, CKA_SUBPRIME); if ((attr1 == NULL) && (attr2 == NULL)) return (ISC_TRUE); else if ((attr1 == NULL) || (attr2 == NULL) || (attr1->ulValueLen != attr2->ulValueLen) || !isc_safe_memequal(attr1->pValue, attr2->pValue, attr1->ulValueLen)) return (ISC_FALSE); attr1 = pk11_attribute_bytype(dsa1, CKA_BASE); attr2 = pk11_attribute_bytype(dsa2, CKA_BASE); if ((attr1 == NULL) && (attr2 == NULL)) return (ISC_TRUE); else if ((attr1 == NULL) || (attr2 == NULL) || (attr1->ulValueLen != attr2->ulValueLen) || !isc_safe_memequal(attr1->pValue, attr2->pValue, attr1->ulValueLen)) return (ISC_FALSE); attr1 = pk11_attribute_bytype(dsa1, CKA_VALUE); attr2 = pk11_attribute_bytype(dsa2, CKA_VALUE); if ((attr1 == NULL) && (attr2 == NULL)) return (ISC_TRUE); else if ((attr1 == NULL) || (attr2 == NULL) || (attr1->ulValueLen != attr2->ulValueLen) || !isc_safe_memequal(attr1->pValue, attr2->pValue, attr1->ulValueLen)) return (ISC_FALSE); attr1 = pk11_attribute_bytype(dsa1, CKA_VALUE2); attr2 = pk11_attribute_bytype(dsa2, CKA_VALUE2); if (((attr1 != NULL) || (attr2 != NULL)) && ((attr1 == NULL) || (attr2 == NULL) || (attr1->ulValueLen != attr2->ulValueLen) || !isc_safe_memequal(attr1->pValue, attr2->pValue, attr1->ulValueLen))) return (ISC_FALSE); if (!dsa1->ontoken && !dsa2->ontoken) return (ISC_TRUE); else if (dsa1->ontoken || dsa2->ontoken || (dsa1->object != dsa2->object)) return (ISC_FALSE); return (ISC_TRUE); } static isc_result_t pkcs11dsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { CK_RV rv; CK_MECHANISM mech = { CKM_DSA_PARAMETER_GEN, NULL, 0 }; CK_OBJECT_HANDLE dp = CK_INVALID_HANDLE; CK_OBJECT_CLASS dpClass = CKO_DOMAIN_PARAMETERS; CK_KEY_TYPE keyType = CKK_DSA; CK_ULONG bits = 0; CK_ATTRIBUTE dpTemplate[] = { { CKA_CLASS, &dpClass, (CK_ULONG) sizeof(dpClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIME_BITS, &bits, (CK_ULONG) sizeof(bits) }, }; CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; CK_ATTRIBUTE pubTemplate[] = { { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_PRIME, NULL, 0 }, { CKA_SUBPRIME, NULL, 0 }, { CKA_BASE, NULL, 0 } }; CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY; CK_ATTRIBUTE privTemplate[] = { { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, }; CK_ATTRIBUTE *attr; pk11_object_t *dsa; pk11_context_t *pk11_ctx; isc_result_t ret; unsigned int i; UNUSED(unused); UNUSED(callback); pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_DSA, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_DSA)); if (ret != ISC_R_SUCCESS) goto err; bits = key->key_size; PK11_RET(pkcs_C_GenerateKey, (pk11_ctx->session, &mech, dpTemplate, (CK_ULONG) 5, &dp), DST_R_CRYPTOFAILURE); dsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dsa)); if (dsa == NULL) DST_RET(ISC_R_NOMEMORY); memset(dsa, 0, sizeof(*dsa)); key->keydata.pkey = dsa; dsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 5); if (dsa->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(dsa->repr, 0, sizeof(*attr) * 5); dsa->attrcnt = 5; attr = dsa->repr; attr[0].type = CKA_PRIME; attr[1].type = CKA_SUBPRIME; attr[2].type = CKA_BASE; attr[3].type = CKA_VALUE; attr[4].type = CKA_VALUE2; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, dp, attr, 3), DST_R_CRYPTOFAILURE); for (i = 0; i <= 2; i++) { attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); if (attr[i].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr[i].pValue, 0, attr[i].ulValueLen); } PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, dp, attr, 3), DST_R_CRYPTOFAILURE); pubTemplate[5].pValue = attr[0].pValue; pubTemplate[5].ulValueLen = attr[0].ulValueLen; pubTemplate[6].pValue = attr[1].pValue; pubTemplate[6].ulValueLen = attr[1].ulValueLen; pubTemplate[7].pValue = attr[2].pValue; pubTemplate[7].ulValueLen = attr[2].ulValueLen; mech.mechanism = CKM_DSA_KEY_PAIR_GEN; PK11_RET(pkcs_C_GenerateKeyPair, (pk11_ctx->session, &mech, pubTemplate, (CK_ULONG) 8, privTemplate, (CK_ULONG) 7, &pub, &priv), DST_R_CRYPTOFAILURE); attr = dsa->repr; attr += 3; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr++; attr->type = CKA_VALUE; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); attr->type = CKA_VALUE2; (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); (void) pkcs_C_DestroyObject(pk11_ctx->session, dp); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ISC_R_SUCCESS); err: pkcs11dsa_destroy(key); if (priv != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); if (pub != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); if (dp != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, dp); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); } static isc_boolean_t pkcs11dsa_isprivate(const dst_key_t *key) { pk11_object_t *dsa = key->keydata.pkey; CK_ATTRIBUTE *attr; if (dsa == NULL) return (ISC_FALSE); attr = pk11_attribute_bytype(dsa, CKA_VALUE2); return (ISC_TF((attr != NULL) || dsa->ontoken)); } static void pkcs11dsa_destroy(dst_key_t *key) { pk11_object_t *dsa = key->keydata.pkey; CK_ATTRIBUTE *attr; if (dsa == NULL) return; INSIST((dsa->object == CK_INVALID_HANDLE) || dsa->ontoken); for (attr = pk11_attribute_first(dsa); attr != NULL; attr = pk11_attribute_next(dsa, attr)) switch (attr->type) { case CKA_PRIME: case CKA_SUBPRIME: case CKA_BASE: case CKA_VALUE: case CKA_VALUE2: if (attr->pValue != NULL) { memset(attr->pValue, 0, attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); } break; } if (dsa->repr != NULL) { memset(dsa->repr, 0, dsa->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, dsa->repr, dsa->attrcnt * sizeof(*attr)); } memset(dsa, 0, sizeof(*dsa)); isc_mem_put(key->mctx, dsa, sizeof(*dsa)); key->keydata.pkey = NULL; } static isc_result_t pkcs11dsa_todns(const dst_key_t *key, isc_buffer_t *data) { pk11_object_t *dsa; CK_ATTRIBUTE *attr; isc_region_t r; int dnslen; unsigned int t, p_bytes; CK_ATTRIBUTE *prime = NULL, *subprime = NULL; CK_ATTRIBUTE *base = NULL, *pub_key = NULL; CK_BYTE *cp; REQUIRE(key->keydata.pkey != NULL); dsa = key->keydata.pkey; for (attr = pk11_attribute_first(dsa); attr != NULL; attr = pk11_attribute_next(dsa, attr)) switch (attr->type) { case CKA_PRIME: prime = attr; break; case CKA_SUBPRIME: subprime = attr; break; case CKA_BASE: base = attr; break; case CKA_VALUE: pub_key = attr; break; } REQUIRE((prime != NULL) && (subprime != NULL) && (base != NULL) && (pub_key != NULL)); isc_buffer_availableregion(data, &r); t = (prime->ulValueLen - 64) / 8; if (t > 8) return (DST_R_INVALIDPUBLICKEY); p_bytes = 64 + 8 * t; dnslen = 1 + (key->key_size * 3)/8 + ISC_SHA1_DIGESTLENGTH; if (r.length < (unsigned int) dnslen) return (ISC_R_NOSPACE); memset(r.base, 0, dnslen); *r.base = t; isc_region_consume(&r, 1); cp = (CK_BYTE *) subprime->pValue; memmove(r.base + ISC_SHA1_DIGESTLENGTH - subprime->ulValueLen, cp, subprime->ulValueLen); isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); cp = (CK_BYTE *) prime->pValue; memmove(r.base + key->key_size/8 - prime->ulValueLen, cp, prime->ulValueLen); isc_region_consume(&r, p_bytes); cp = (CK_BYTE *) base->pValue; memmove(r.base + key->key_size/8 - base->ulValueLen, cp, base->ulValueLen); isc_region_consume(&r, p_bytes); cp = (CK_BYTE *) pub_key->pValue; memmove(r.base + key->key_size/8 - pub_key->ulValueLen, cp, pub_key->ulValueLen); isc_region_consume(&r, p_bytes); isc_buffer_add(data, dnslen); return (ISC_R_SUCCESS); } static isc_result_t pkcs11dsa_fromdns(dst_key_t *key, isc_buffer_t *data) { pk11_object_t *dsa; isc_region_t r; unsigned int t, p_bytes; CK_BYTE *prime, *subprime, *base, *pub_key; CK_ATTRIBUTE *attr; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); dsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dsa)); if (dsa == NULL) return (ISC_R_NOMEMORY); memset(dsa, 0, sizeof(*dsa)); t = (unsigned int) *r.base; isc_region_consume(&r, 1); if (t > 8) { memset(dsa, 0, sizeof(*dsa)); isc_mem_put(key->mctx, dsa, sizeof(*dsa)); return (DST_R_INVALIDPUBLICKEY); } p_bytes = 64 + 8 * t; if (r.length < ISC_SHA1_DIGESTLENGTH + 3 * p_bytes) { memset(dsa, 0, sizeof(*dsa)); isc_mem_put(key->mctx, dsa, sizeof(*dsa)); return (DST_R_INVALIDPUBLICKEY); } subprime = r.base; isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); prime = r.base; isc_region_consume(&r, p_bytes); base = r.base; isc_region_consume(&r, p_bytes); pub_key = r.base; isc_region_consume(&r, p_bytes); key->key_size = p_bytes * 8; isc_buffer_forward(data, 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes); dsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 4); if (dsa->repr == NULL) goto nomemory; memset(dsa->repr, 0, sizeof(*attr) * 4); dsa->attrcnt = 4; attr = dsa->repr; attr[0].type = CKA_PRIME; attr[0].pValue = isc_mem_get(key->mctx, p_bytes); if (attr[0].pValue == NULL) goto nomemory; memmove(attr[0].pValue, prime, p_bytes); attr[0].ulValueLen = p_bytes; attr[1].type = CKA_SUBPRIME; attr[1].pValue = isc_mem_get(key->mctx, ISC_SHA1_DIGESTLENGTH); if (attr[1].pValue == NULL) goto nomemory; memmove(attr[1].pValue, subprime, ISC_SHA1_DIGESTLENGTH); attr[1].ulValueLen = ISC_SHA1_DIGESTLENGTH; attr[2].type = CKA_BASE; attr[2].pValue = isc_mem_get(key->mctx, p_bytes); if (attr[2].pValue == NULL) goto nomemory; memmove(attr[2].pValue, base, p_bytes); attr[2].ulValueLen = p_bytes; attr[3].type = CKA_VALUE; attr[3].pValue = isc_mem_get(key->mctx, p_bytes); if (attr[3].pValue == NULL) goto nomemory; memmove(attr[3].pValue, pub_key, p_bytes); attr[3].ulValueLen = p_bytes; key->keydata.pkey = dsa; return (ISC_R_SUCCESS); nomemory: for (attr = pk11_attribute_first(dsa); attr != NULL; attr = pk11_attribute_next(dsa, attr)) switch (attr->type) { case CKA_PRIME: case CKA_SUBPRIME: case CKA_BASE: case CKA_VALUE: if (attr->pValue != NULL) { memset(attr->pValue, 0, attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); } break; } if (dsa->repr != NULL) { memset(dsa->repr, 0, dsa->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, dsa->repr, dsa->attrcnt * sizeof(*attr)); } memset(dsa, 0, sizeof(*dsa)); isc_mem_put(key->mctx, dsa, sizeof(*dsa)); return (ISC_R_NOMEMORY); } static isc_result_t pkcs11dsa_tofile(const dst_key_t *key, const char *directory) { int cnt = 0; pk11_object_t *dsa; CK_ATTRIBUTE *attr; CK_ATTRIBUTE *prime = NULL, *subprime = NULL, *base = NULL; CK_ATTRIBUTE *pub_key = NULL, *priv_key = NULL; dst_private_t priv; unsigned char bufs[5][128]; if (key->keydata.pkey == NULL) return (DST_R_NULLKEY); if (key->external) { priv.nelements = 0; return (dst__privstruct_writefile(key, &priv, directory)); } dsa = key->keydata.pkey; for (attr = pk11_attribute_first(dsa); attr != NULL; attr = pk11_attribute_next(dsa, attr)) switch (attr->type) { case CKA_PRIME: prime = attr; break; case CKA_SUBPRIME: subprime = attr; break; case CKA_BASE: base = attr; break; case CKA_VALUE: pub_key = attr; break; case CKA_VALUE2: priv_key = attr; break; } if ((prime == NULL) || (subprime == NULL) || (base == NULL) || (pub_key == NULL) || (priv_key ==NULL)) return (DST_R_NULLKEY); priv.elements[cnt].tag = TAG_DSA_PRIME; priv.elements[cnt].length = (unsigned short) prime->ulValueLen; memmove(bufs[cnt], prime->pValue, prime->ulValueLen); priv.elements[cnt].data = bufs[cnt]; cnt++; priv.elements[cnt].tag = TAG_DSA_SUBPRIME; priv.elements[cnt].length = (unsigned short) subprime->ulValueLen; memmove(bufs[cnt], subprime->pValue, subprime->ulValueLen); priv.elements[cnt].data = bufs[cnt]; cnt++; priv.elements[cnt].tag = TAG_DSA_BASE; priv.elements[cnt].length = (unsigned short) base->ulValueLen; memmove(bufs[cnt], base->pValue, base->ulValueLen); priv.elements[cnt].data = bufs[cnt]; cnt++; priv.elements[cnt].tag = TAG_DSA_PRIVATE; priv.elements[cnt].length = (unsigned short) priv_key->ulValueLen; memmove(bufs[cnt], priv_key->pValue, priv_key->ulValueLen); priv.elements[cnt].data = bufs[cnt]; cnt++; priv.elements[cnt].tag = TAG_DSA_PUBLIC; priv.elements[cnt].length = (unsigned short) pub_key->ulValueLen; memmove(bufs[cnt], pub_key->pValue, pub_key->ulValueLen); priv.elements[cnt].data = bufs[cnt]; cnt++; priv.nelements = cnt; return (dst__privstruct_writefile(key, &priv, directory)); } static isc_result_t pkcs11dsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t ret; int i; pk11_object_t *dsa = NULL; CK_ATTRIBUTE *attr; isc_mem_t *mctx = key->mctx; /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_DSA, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) return (ret); if (key->external) { if (priv.nelements != 0) DST_RET(DST_R_INVALIDPRIVATEKEY); if (pub == NULL) DST_RET(DST_R_INVALIDPRIVATEKEY); key->keydata.pkey = pub->keydata.pkey; pub->keydata.pkey = NULL; key->key_size = pub->key_size; dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ISC_R_SUCCESS); } dsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dsa)); if (dsa == NULL) DST_RET(ISC_R_NOMEMORY); memset(dsa, 0, sizeof(*dsa)); key->keydata.pkey = dsa; dsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 5); if (dsa->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(dsa->repr, 0, sizeof(*attr) * 5); dsa->attrcnt = 5; attr = dsa->repr; attr[0].type = CKA_PRIME; attr[1].type = CKA_SUBPRIME; attr[2].type = CKA_BASE; attr[3].type = CKA_VALUE; attr[4].type = CKA_VALUE2; for (i = 0; i < priv.nelements; i++) { CK_BYTE *bn; bn = isc_mem_get(key->mctx, priv.elements[i].length); if (bn == NULL) DST_RET(ISC_R_NOMEMORY); memmove(bn, priv.elements[i].data, priv.elements[i].length); switch (priv.elements[i].tag) { case TAG_DSA_PRIME: attr = pk11_attribute_bytype(dsa, CKA_PRIME); INSIST(attr != NULL); attr->pValue = bn; attr->ulValueLen = priv.elements[i].length; break; case TAG_DSA_SUBPRIME: attr = pk11_attribute_bytype(dsa, CKA_SUBPRIME); INSIST(attr != NULL); attr->pValue = bn; attr->ulValueLen = priv.elements[i].length; break; case TAG_DSA_BASE: attr = pk11_attribute_bytype(dsa, CKA_BASE); INSIST(attr != NULL); attr->pValue = bn; attr->ulValueLen = priv.elements[i].length; break; case TAG_DSA_PRIVATE: attr = pk11_attribute_bytype(dsa, CKA_VALUE2); INSIST(attr != NULL); attr->pValue = bn; attr->ulValueLen = priv.elements[i].length; break; case TAG_DSA_PUBLIC: attr = pk11_attribute_bytype(dsa, CKA_VALUE); INSIST(attr != NULL); attr->pValue = bn; attr->ulValueLen = priv.elements[i].length; break; } } dst__privstruct_free(&priv, mctx); attr = pk11_attribute_bytype(dsa, CKA_PRIME); INSIST(attr != NULL); key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); return (ISC_R_SUCCESS); err: pkcs11dsa_destroy(key); dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ret); } static dst_func_t pkcs11dsa_functions = { pkcs11dsa_createctx, NULL, /*%< createctx2 */ pkcs11dsa_destroyctx, pkcs11dsa_adddata, pkcs11dsa_sign, pkcs11dsa_verify, NULL, /*%< verify2 */ NULL, /*%< computesecret */ pkcs11dsa_compare, NULL, /*%< paramcompare */ pkcs11dsa_generate, pkcs11dsa_isprivate, pkcs11dsa_destroy, pkcs11dsa_todns, pkcs11dsa_fromdns, pkcs11dsa_tofile, pkcs11dsa_parse, NULL, /*%< cleanup */ NULL, /*%< fromlabel */ NULL, /*%< dump */ NULL, /*%< restore */ }; isc_result_t dst__pkcs11dsa_init(dst_func_t **funcp) { REQUIRE(funcp != NULL); if (*funcp == NULL) *funcp = &pkcs11dsa_functions; return (ISC_R_SUCCESS); } #else /* PKCS11CRYPTO */ #include EMPTY_TRANSLATION_UNIT #endif /* PKCS11CRYPTO */ /*! \file */ bind9-9.10.3.dfsg.P4/lib/dns/masterdump.c0000644000470500017500000014631512664710322017262 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define DNS_DCTX_MAGIC ISC_MAGIC('D', 'c', 't', 'x') #define DNS_DCTX_VALID(d) ISC_MAGIC_VALID(d, DNS_DCTX_MAGIC) #define RETERR(x) do { \ isc_result_t _r = (x); \ if (_r != ISC_R_SUCCESS) \ return (_r); \ } while (0) #define CHECK(x) do { \ if ((x) != ISC_R_SUCCESS) \ goto cleanup; \ } while (0) struct dns_master_style { unsigned int flags; /* DNS_STYLEFLAG_* */ unsigned int ttl_column; unsigned int class_column; unsigned int type_column; unsigned int rdata_column; unsigned int line_length; unsigned int tab_width; unsigned int split_width; }; /*% * The maximum length of the newline+indentation that is output * when inserting a line break in an RR. This effectively puts an * upper limits on the value of "rdata_column", because if it is * very large, the tabs and spaces needed to reach it will not fit. */ #define DNS_TOTEXT_LINEBREAK_MAXLEN 100 /*% * Context structure for a masterfile dump in progress. */ typedef struct dns_totext_ctx { dns_master_style_t style; isc_boolean_t class_printed; char * linebreak; char linebreak_buf[DNS_TOTEXT_LINEBREAK_MAXLEN]; dns_name_t * origin; dns_name_t * neworigin; dns_fixedname_t origin_fixname; isc_uint32_t current_ttl; isc_boolean_t current_ttl_valid; } dns_totext_ctx_t; LIBDNS_EXTERNAL_DATA const dns_master_style_t dns_master_style_keyzone = { DNS_STYLEFLAG_OMIT_OWNER | DNS_STYLEFLAG_OMIT_CLASS | DNS_STYLEFLAG_REL_OWNER | DNS_STYLEFLAG_REL_DATA | DNS_STYLEFLAG_OMIT_TTL | DNS_STYLEFLAG_TTL | DNS_STYLEFLAG_COMMENT | DNS_STYLEFLAG_RRCOMMENT | DNS_STYLEFLAG_MULTILINE | DNS_STYLEFLAG_KEYDATA, 24, 24, 24, 32, 80, 8, UINT_MAX }; LIBDNS_EXTERNAL_DATA const dns_master_style_t dns_master_style_default = { DNS_STYLEFLAG_OMIT_OWNER | DNS_STYLEFLAG_OMIT_CLASS | DNS_STYLEFLAG_REL_OWNER | DNS_STYLEFLAG_REL_DATA | DNS_STYLEFLAG_OMIT_TTL | DNS_STYLEFLAG_TTL | DNS_STYLEFLAG_COMMENT | DNS_STYLEFLAG_RRCOMMENT | DNS_STYLEFLAG_MULTILINE, 24, 24, 24, 32, 80, 8, UINT_MAX }; LIBDNS_EXTERNAL_DATA const dns_master_style_t dns_master_style_full = { DNS_STYLEFLAG_COMMENT | DNS_STYLEFLAG_RESIGN, 46, 46, 46, 64, 120, 8, UINT_MAX }; LIBDNS_EXTERNAL_DATA const dns_master_style_t dns_master_style_explicitttl = { DNS_STYLEFLAG_OMIT_OWNER | DNS_STYLEFLAG_OMIT_CLASS | DNS_STYLEFLAG_REL_OWNER | DNS_STYLEFLAG_REL_DATA | DNS_STYLEFLAG_COMMENT | DNS_STYLEFLAG_RRCOMMENT | DNS_STYLEFLAG_MULTILINE, 24, 32, 32, 40, 80, 8, UINT_MAX }; LIBDNS_EXTERNAL_DATA const dns_master_style_t dns_master_style_cache = { DNS_STYLEFLAG_OMIT_OWNER | DNS_STYLEFLAG_OMIT_CLASS | DNS_STYLEFLAG_MULTILINE | DNS_STYLEFLAG_RRCOMMENT | DNS_STYLEFLAG_TRUST | DNS_STYLEFLAG_NCACHE, 24, 32, 32, 40, 80, 8, UINT_MAX }; LIBDNS_EXTERNAL_DATA const dns_master_style_t dns_master_style_simple = { 0, 24, 32, 32, 40, 80, 8, UINT_MAX }; /*% * A style suitable for dns_rdataset_totext(). */ LIBDNS_EXTERNAL_DATA const dns_master_style_t dns_master_style_debug = { DNS_STYLEFLAG_REL_OWNER, 24, 32, 40, 48, 80, 8, UINT_MAX }; /*% * Similar, but with each line commented out. */ LIBDNS_EXTERNAL_DATA const dns_master_style_t dns_master_style_comment = { DNS_STYLEFLAG_REL_OWNER | DNS_STYLEFLAG_MULTILINE | DNS_STYLEFLAG_RRCOMMENT | DNS_STYLEFLAG_COMMENTDATA, 24, 32, 40, 48, 80, 8, UINT_MAX }; #define N_SPACES 10 static char spaces[N_SPACES+1] = " "; #define N_TABS 10 static char tabs[N_TABS+1] = "\t\t\t\t\t\t\t\t\t\t"; struct dns_dumpctx { unsigned int magic; isc_mem_t *mctx; isc_mutex_t lock; unsigned int references; isc_boolean_t canceled; isc_boolean_t first; isc_boolean_t do_date; isc_stdtime_t now; FILE *f; dns_db_t *db; dns_dbversion_t *version; dns_dbiterator_t *dbiter; dns_totext_ctx_t tctx; isc_task_t *task; dns_dumpdonefunc_t done; void *done_arg; unsigned int nodes; /* dns_master_dumpinc() */ char *file; char *tmpfile; dns_masterformat_t format; dns_masterrawheader_t header; isc_result_t (*dumpsets)(isc_mem_t *mctx, dns_name_t *name, dns_rdatasetiter_t *rdsiter, dns_totext_ctx_t *ctx, isc_buffer_t *buffer, FILE *f); }; #define NXDOMAIN(x) (((x)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0) /*% * Output tabs and spaces to go from column '*current' to * column 'to', and update '*current' to reflect the new * current column. */ static isc_result_t indent(unsigned int *current, unsigned int to, int tabwidth, isc_buffer_t *target) { isc_region_t r; unsigned char *p; unsigned int from; int ntabs, nspaces, t; from = *current; if (to < from + 1) to = from + 1; ntabs = to / tabwidth - from / tabwidth; if (ntabs < 0) ntabs = 0; if (ntabs > 0) { isc_buffer_availableregion(target, &r); if (r.length < (unsigned) ntabs) return (ISC_R_NOSPACE); p = r.base; t = ntabs; while (t) { int n = t; if (n > N_TABS) n = N_TABS; memmove(p, tabs, n); p += n; t -= n; } isc_buffer_add(target, ntabs); from = (to / tabwidth) * tabwidth; } nspaces = to - from; INSIST(nspaces >= 0); isc_buffer_availableregion(target, &r); if (r.length < (unsigned) nspaces) return (ISC_R_NOSPACE); p = r.base; t = nspaces; while (t) { int n = t; if (n > N_SPACES) n = N_SPACES; memmove(p, spaces, n); p += n; t -= n; } isc_buffer_add(target, nspaces); *current = to; return (ISC_R_SUCCESS); } static isc_result_t totext_ctx_init(const dns_master_style_t *style, dns_totext_ctx_t *ctx) { isc_result_t result; REQUIRE(style->tab_width != 0); ctx->style = *style; ctx->class_printed = ISC_FALSE; dns_fixedname_init(&ctx->origin_fixname); /* * Set up the line break string if needed. */ if ((ctx->style.flags & DNS_STYLEFLAG_MULTILINE) != 0) { isc_buffer_t buf; isc_region_t r; unsigned int col = 0; isc_buffer_init(&buf, ctx->linebreak_buf, sizeof(ctx->linebreak_buf)); isc_buffer_availableregion(&buf, &r); if (r.length < 1) return (DNS_R_TEXTTOOLONG); r.base[0] = '\n'; isc_buffer_add(&buf, 1); if ((ctx->style.flags & DNS_STYLEFLAG_COMMENTDATA) != 0) { isc_buffer_availableregion(&buf, &r); if (r.length < 1) return (DNS_R_TEXTTOOLONG); r.base[0] = ';'; isc_buffer_add(&buf, 1); } result = indent(&col, ctx->style.rdata_column, ctx->style.tab_width, &buf); /* * Do not return ISC_R_NOSPACE if the line break string * buffer is too small, because that would just make * dump_rdataset() retry indefinitely with ever * bigger target buffers. That's a different buffer, * so it won't help. Use DNS_R_TEXTTOOLONG as a substitute. */ if (result == ISC_R_NOSPACE) return (DNS_R_TEXTTOOLONG); if (result != ISC_R_SUCCESS) return (result); isc_buffer_availableregion(&buf, &r); if (r.length < 1) return (DNS_R_TEXTTOOLONG); r.base[0] = '\0'; isc_buffer_add(&buf, 1); ctx->linebreak = ctx->linebreak_buf; } else { ctx->linebreak = NULL; } ctx->origin = NULL; ctx->neworigin = NULL; ctx->current_ttl = 0; ctx->current_ttl_valid = ISC_FALSE; return (ISC_R_SUCCESS); } #define INDENT_TO(col) \ do { \ if ((result = indent(&column, ctx->style.col, \ ctx->style.tab_width, target)) \ != ISC_R_SUCCESS) \ return (result); \ } while (0) static isc_result_t str_totext(const char *source, isc_buffer_t *target) { unsigned int l; isc_region_t region; isc_buffer_availableregion(target, ®ion); l = strlen(source); if (l > region.length) return (ISC_R_NOSPACE); memmove(region.base, source, l); isc_buffer_add(target, l); return (ISC_R_SUCCESS); } static isc_result_t ncache_summary(dns_rdataset_t *rdataset, isc_boolean_t omit_final_dot, isc_buffer_t *target) { isc_result_t result = ISC_R_SUCCESS; dns_rdataset_t rds; dns_name_t name; dns_rdataset_init(&rds); dns_name_init(&name, NULL); do { dns_ncache_current(rdataset, &name, &rds); for (result = dns_rdataset_first(&rds); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rds)) { CHECK(str_totext("; ", target)); CHECK(dns_name_totext(&name, omit_final_dot, target)); CHECK(str_totext(" ", target)); CHECK(dns_rdatatype_totext(rds.type, target)); if (rds.type == dns_rdatatype_rrsig) { CHECK(str_totext(" ", target)); CHECK(dns_rdatatype_totext(rds.covers, target)); CHECK(str_totext(" ...\n", target)); } else { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&rds, &rdata); CHECK(str_totext(" ", target)); CHECK(dns_rdata_tofmttext(&rdata, dns_rootname, 0, 0, 0, " ", target)); CHECK(str_totext("\n", target)); } } dns_rdataset_disassociate(&rds); result = dns_rdataset_next(rdataset); } while (result == ISC_R_SUCCESS); if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; cleanup: if (dns_rdataset_isassociated(&rds)) dns_rdataset_disassociate(&rds); return (result); } /* * Convert 'rdataset' to master file text format according to 'ctx', * storing the result in 'target'. If 'owner_name' is NULL, it * is omitted; otherwise 'owner_name' must be valid and have at least * one label. */ static isc_result_t rdataset_totext(dns_rdataset_t *rdataset, dns_name_t *owner_name, dns_totext_ctx_t *ctx, isc_boolean_t omit_final_dot, isc_buffer_t *target) { isc_result_t result; unsigned int column; isc_boolean_t first = ISC_TRUE; isc_uint32_t current_ttl; isc_boolean_t current_ttl_valid; dns_rdatatype_t type; unsigned int type_start; REQUIRE(DNS_RDATASET_VALID(rdataset)); rdataset->attributes |= DNS_RDATASETATTR_LOADORDER; result = dns_rdataset_first(rdataset); current_ttl = ctx->current_ttl; current_ttl_valid = ctx->current_ttl_valid; while (result == ISC_R_SUCCESS) { column = 0; /* * Comment? */ if ((ctx->style.flags & DNS_STYLEFLAG_COMMENTDATA) != 0) RETERR(str_totext(";", target)); /* * Owner name. */ if (owner_name != NULL && ! ((ctx->style.flags & DNS_STYLEFLAG_OMIT_OWNER) != 0 && !first)) { unsigned int name_start = target->used; RETERR(dns_name_totext(owner_name, omit_final_dot, target)); column += target->used - name_start; } /* * TTL. */ if ((ctx->style.flags & DNS_STYLEFLAG_NO_TTL) == 0 && !((ctx->style.flags & DNS_STYLEFLAG_OMIT_TTL) != 0 && current_ttl_valid && rdataset->ttl == current_ttl)) { char ttlbuf[64]; isc_region_t r; unsigned int length; INDENT_TO(ttl_column); length = snprintf(ttlbuf, sizeof(ttlbuf), "%u", rdataset->ttl); INSIST(length <= sizeof(ttlbuf)); isc_buffer_availableregion(target, &r); if (r.length < length) return (ISC_R_NOSPACE); memmove(r.base, ttlbuf, length); isc_buffer_add(target, length); column += length; /* * If the $TTL directive is not in use, the TTL we * just printed becomes the default for subsequent RRs. */ if ((ctx->style.flags & DNS_STYLEFLAG_TTL) == 0) { current_ttl = rdataset->ttl; current_ttl_valid = ISC_TRUE; } } /* * Class. */ if ((ctx->style.flags & DNS_STYLEFLAG_NO_CLASS) == 0 && ((ctx->style.flags & DNS_STYLEFLAG_OMIT_CLASS) == 0 || ctx->class_printed == ISC_FALSE)) { unsigned int class_start; INDENT_TO(class_column); class_start = target->used; result = dns_rdataclass_totext(rdataset->rdclass, target); if (result != ISC_R_SUCCESS) return (result); column += (target->used - class_start); } /* * Type. */ if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) { type = rdataset->covers; } else { type = rdataset->type; } INDENT_TO(type_column); type_start = target->used; if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) RETERR(str_totext("\\-", target)); switch (type) { case dns_rdatatype_keydata: #define KEYDATA "KEYDATA" if ((ctx->style.flags & DNS_STYLEFLAG_KEYDATA) != 0) { if (isc_buffer_availablelength(target) < (sizeof(KEYDATA) - 1)) return (ISC_R_NOSPACE); isc_buffer_putstr(target, KEYDATA); break; } /* FALLTHROUGH */ default: result = dns_rdatatype_totext(type, target); if (result != ISC_R_SUCCESS) return (result); } column += (target->used - type_start); /* * Rdata. */ INDENT_TO(rdata_column); if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) { if (NXDOMAIN(rdataset)) RETERR(str_totext(";-$NXDOMAIN\n", target)); else RETERR(str_totext(";-$NXRRSET\n", target)); /* * Print a summary of the cached records which make * up the negative response. */ RETERR(ncache_summary(rdataset, omit_final_dot, target)); break; } else { dns_rdata_t rdata = DNS_RDATA_INIT; isc_region_t r; dns_rdataset_current(rdataset, &rdata); RETERR(dns_rdata_tofmttext(&rdata, ctx->origin, ctx->style.flags, ctx->style.line_length - ctx->style.rdata_column, ctx->style.split_width, ctx->linebreak, target)); isc_buffer_availableregion(target, &r); if (r.length < 1) return (ISC_R_NOSPACE); r.base[0] = '\n'; isc_buffer_add(target, 1); } first = ISC_FALSE; result = dns_rdataset_next(rdataset); } if (result != ISC_R_NOMORE) return (result); /* * Update the ctx state to reflect what we just printed. * This is done last, only when we are sure we will return * success, because this function may be called multiple * times with increasing buffer sizes until it succeeds, * and failed attempts must not update the state prematurely. */ ctx->class_printed = ISC_TRUE; ctx->current_ttl= current_ttl; ctx->current_ttl_valid = current_ttl_valid; return (ISC_R_SUCCESS); } /* * Print the name, type, and class of an empty rdataset, * such as those used to represent the question section * of a DNS message. */ static isc_result_t question_totext(dns_rdataset_t *rdataset, dns_name_t *owner_name, dns_totext_ctx_t *ctx, isc_boolean_t omit_final_dot, isc_buffer_t *target) { unsigned int column; isc_result_t result; isc_region_t r; REQUIRE(DNS_RDATASET_VALID(rdataset)); result = dns_rdataset_first(rdataset); REQUIRE(result == ISC_R_NOMORE); column = 0; /* Owner name */ { unsigned int name_start = target->used; RETERR(dns_name_totext(owner_name, omit_final_dot, target)); column += target->used - name_start; } /* Class */ { unsigned int class_start; INDENT_TO(class_column); class_start = target->used; result = dns_rdataclass_totext(rdataset->rdclass, target); if (result != ISC_R_SUCCESS) return (result); column += (target->used - class_start); } /* Type */ { unsigned int type_start; INDENT_TO(type_column); type_start = target->used; result = dns_rdatatype_totext(rdataset->type, target); if (result != ISC_R_SUCCESS) return (result); column += (target->used - type_start); } isc_buffer_availableregion(target, &r); if (r.length < 1) return (ISC_R_NOSPACE); r.base[0] = '\n'; isc_buffer_add(target, 1); return (ISC_R_SUCCESS); } isc_result_t dns_rdataset_totext(dns_rdataset_t *rdataset, dns_name_t *owner_name, isc_boolean_t omit_final_dot, isc_boolean_t question, isc_buffer_t *target) { dns_totext_ctx_t ctx; isc_result_t result; result = totext_ctx_init(&dns_master_style_debug, &ctx); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "could not set master file style"); return (ISC_R_UNEXPECTED); } /* * The caller might want to give us an empty owner * name (e.g. if they are outputting into a master * file and this rdataset has the same name as the * previous one.) */ if (dns_name_countlabels(owner_name) == 0) owner_name = NULL; if (question) return (question_totext(rdataset, owner_name, &ctx, omit_final_dot, target)); else return (rdataset_totext(rdataset, owner_name, &ctx, omit_final_dot, target)); } isc_result_t dns_master_rdatasettotext(dns_name_t *owner_name, dns_rdataset_t *rdataset, const dns_master_style_t *style, isc_buffer_t *target) { dns_totext_ctx_t ctx; isc_result_t result; result = totext_ctx_init(style, &ctx); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "could not set master file style"); return (ISC_R_UNEXPECTED); } return (rdataset_totext(rdataset, owner_name, &ctx, ISC_FALSE, target)); } isc_result_t dns_master_questiontotext(dns_name_t *owner_name, dns_rdataset_t *rdataset, const dns_master_style_t *style, isc_buffer_t *target) { dns_totext_ctx_t ctx; isc_result_t result; result = totext_ctx_init(style, &ctx); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "could not set master file style"); return (ISC_R_UNEXPECTED); } return (question_totext(rdataset, owner_name, &ctx, ISC_FALSE, target)); } /* * Print an rdataset. 'buffer' is a scratch buffer, which must have been * dynamically allocated by the caller. It must be large enough to * hold the result from dns_ttl_totext(). If more than that is needed, * the buffer will be grown automatically. */ static isc_result_t dump_rdataset(isc_mem_t *mctx, dns_name_t *name, dns_rdataset_t *rdataset, dns_totext_ctx_t *ctx, isc_buffer_t *buffer, FILE *f) { isc_region_t r; isc_result_t result; REQUIRE(buffer->length > 0); /* * Output a $TTL directive if needed. */ if ((ctx->style.flags & DNS_STYLEFLAG_TTL) != 0) { if (ctx->current_ttl_valid == ISC_FALSE || ctx->current_ttl != rdataset->ttl) { if ((ctx->style.flags & DNS_STYLEFLAG_COMMENT) != 0) { isc_buffer_clear(buffer); result = dns_ttl_totext(rdataset->ttl, ISC_TRUE, buffer); INSIST(result == ISC_R_SUCCESS); isc_buffer_usedregion(buffer, &r); fprintf(f, "$TTL %u\t; %.*s\n", rdataset->ttl, (int) r.length, (char *) r.base); } else { fprintf(f, "$TTL %u\n", rdataset->ttl); } ctx->current_ttl = rdataset->ttl; ctx->current_ttl_valid = ISC_TRUE; } } isc_buffer_clear(buffer); /* * Generate the text representation of the rdataset into * the buffer. If the buffer is too small, grow it. */ for (;;) { int newlength; void *newmem; result = rdataset_totext(rdataset, name, ctx, ISC_FALSE, buffer); if (result != ISC_R_NOSPACE) break; newlength = buffer->length * 2; newmem = isc_mem_get(mctx, newlength); if (newmem == NULL) return (ISC_R_NOMEMORY); isc_mem_put(mctx, buffer->base, buffer->length); isc_buffer_init(buffer, newmem, newlength); } if (result != ISC_R_SUCCESS) return (result); /* * Write the buffer contents to the master file. */ isc_buffer_usedregion(buffer, &r); result = isc_stdio_write(r.base, 1, (size_t)r.length, f, NULL); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "master file write failed: %s", isc_result_totext(result)); return (result); } return (ISC_R_SUCCESS); } /* * Define the order in which rdatasets should be printed in zone * files. We will print SOA and NS records before others, SIGs * immediately following the things they sign, and order everything * else by RR number. This is all just for aesthetics and * compatibility with buggy software that expects the SOA to be first; * the DNS specifications allow any order. */ static int dump_order(const dns_rdataset_t *rds) { int t; int sig; if (rds->type == dns_rdatatype_rrsig) { t = rds->covers; sig = 1; } else { t = rds->type; sig = 0; } switch (t) { case dns_rdatatype_soa: t = 0; break; case dns_rdatatype_ns: t = 1; break; default: t += 2; break; } return (t << 1) + sig; } static int dump_order_compare(const void *a, const void *b) { return (dump_order(*((const dns_rdataset_t * const *) a)) - dump_order(*((const dns_rdataset_t * const *) b))); } /* * Dump all the rdatasets of a domain name to a master file. We make * a "best effort" attempt to sort the RRsets in a nice order, but if * there are more than MAXSORT RRsets, we punt and only sort them in * groups of MAXSORT. This is not expected to ever happen in practice * since much less than 64 RR types have been registered with the * IANA, so far, and the output will be correct (though not * aesthetically pleasing) even if it does happen. */ #define MAXSORT 64 static isc_result_t dump_rdatasets_text(isc_mem_t *mctx, dns_name_t *name, dns_rdatasetiter_t *rdsiter, dns_totext_ctx_t *ctx, isc_buffer_t *buffer, FILE *f) { isc_result_t itresult, dumpresult; isc_region_t r; dns_rdataset_t rdatasets[MAXSORT]; dns_rdataset_t *sorted[MAXSORT]; int i, n; itresult = dns_rdatasetiter_first(rdsiter); dumpresult = ISC_R_SUCCESS; if (itresult == ISC_R_SUCCESS && ctx->neworigin != NULL) { isc_buffer_clear(buffer); itresult = dns_name_totext(ctx->neworigin, ISC_FALSE, buffer); RUNTIME_CHECK(itresult == ISC_R_SUCCESS); isc_buffer_usedregion(buffer, &r); fprintf(f, "$ORIGIN %.*s\n", (int) r.length, (char *) r.base); ctx->neworigin = NULL; } again: for (i = 0; itresult == ISC_R_SUCCESS && i < MAXSORT; itresult = dns_rdatasetiter_next(rdsiter), i++) { dns_rdataset_init(&rdatasets[i]); dns_rdatasetiter_current(rdsiter, &rdatasets[i]); sorted[i] = &rdatasets[i]; } n = i; INSIST(n <= MAXSORT); qsort(sorted, n, sizeof(sorted[0]), dump_order_compare); for (i = 0; i < n; i++) { dns_rdataset_t *rds = sorted[i]; if (ctx->style.flags & DNS_STYLEFLAG_TRUST) fprintf(f, "; %s\n", dns_trust_totext(rds->trust)); if (((rds->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) && (ctx->style.flags & DNS_STYLEFLAG_NCACHE) == 0) { /* Omit negative cache entries */ } else { isc_result_t result = dump_rdataset(mctx, name, rds, ctx, buffer, f); if (result != ISC_R_SUCCESS) dumpresult = result; if ((ctx->style.flags & DNS_STYLEFLAG_OMIT_OWNER) != 0) name = NULL; } if (ctx->style.flags & DNS_STYLEFLAG_RESIGN && rds->attributes & DNS_RDATASETATTR_RESIGN) { isc_buffer_t b; char buf[sizeof("YYYYMMDDHHMMSS")]; memset(buf, 0, sizeof(buf)); isc_buffer_init(&b, buf, sizeof(buf) - 1); dns_time64_totext((isc_uint64_t)rds->resign, &b); fprintf(f, "; resign=%s\n", buf); } dns_rdataset_disassociate(rds); } if (dumpresult != ISC_R_SUCCESS) return (dumpresult); /* * If we got more data than could be sorted at once, * go handle the rest. */ if (itresult == ISC_R_SUCCESS) goto again; if (itresult == ISC_R_NOMORE) itresult = ISC_R_SUCCESS; return (itresult); } /* * Dump given RRsets in the "raw" format. */ static isc_result_t dump_rdataset_raw(isc_mem_t *mctx, dns_name_t *name, dns_rdataset_t *rdataset, isc_buffer_t *buffer, FILE *f) { isc_result_t result; isc_uint32_t totallen; isc_uint16_t dlen; isc_region_t r, r_hdr; REQUIRE(buffer->length > 0); REQUIRE(DNS_RDATASET_VALID(rdataset)); rdataset->attributes |= DNS_RDATASETATTR_LOADORDER; restart: totallen = 0; result = dns_rdataset_first(rdataset); REQUIRE(result == ISC_R_SUCCESS); isc_buffer_clear(buffer); /* * Common header and owner name (length followed by name) * These fields should be in a moderate length, so we assume we * can store all of them in the initial buffer. */ isc_buffer_availableregion(buffer, &r_hdr); INSIST(r_hdr.length >= sizeof(dns_masterrawrdataset_t)); isc_buffer_putuint32(buffer, totallen); /* XXX: leave space */ isc_buffer_putuint16(buffer, rdataset->rdclass); /* 16-bit class */ isc_buffer_putuint16(buffer, rdataset->type); /* 16-bit type */ isc_buffer_putuint16(buffer, rdataset->covers); /* same as type */ isc_buffer_putuint32(buffer, rdataset->ttl); /* 32-bit TTL */ isc_buffer_putuint32(buffer, dns_rdataset_count(rdataset)); totallen = isc_buffer_usedlength(buffer); INSIST(totallen <= sizeof(dns_masterrawrdataset_t)); dns_name_toregion(name, &r); INSIST(isc_buffer_availablelength(buffer) >= (sizeof(dlen) + r.length)); dlen = (isc_uint16_t)r.length; isc_buffer_putuint16(buffer, dlen); isc_buffer_copyregion(buffer, &r); totallen += sizeof(dlen) + r.length; do { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(rdataset, &rdata); dns_rdata_toregion(&rdata, &r); INSIST(r.length <= 0xffffU); dlen = (isc_uint16_t)r.length; /* * Copy the rdata into the buffer. If the buffer is too small, * grow it. This should be rare, so we'll simply restart the * entire procedure (or should we copy the old data and * continue?). */ if (isc_buffer_availablelength(buffer) < sizeof(dlen) + r.length) { int newlength; void *newmem; newlength = buffer->length * 2; newmem = isc_mem_get(mctx, newlength); if (newmem == NULL) return (ISC_R_NOMEMORY); isc_mem_put(mctx, buffer->base, buffer->length); isc_buffer_init(buffer, newmem, newlength); goto restart; } isc_buffer_putuint16(buffer, dlen); isc_buffer_copyregion(buffer, &r); totallen += sizeof(dlen) + r.length; result = dns_rdataset_next(rdataset); } while (result == ISC_R_SUCCESS); if (result != ISC_R_NOMORE) return (result); /* * Fill in the total length field. * XXX: this is a bit tricky. Since we have already "used" the space * for the total length in the buffer, we first remember the entire * buffer length in the region, "rewind", and then write the value. */ isc_buffer_usedregion(buffer, &r); isc_buffer_clear(buffer); isc_buffer_putuint32(buffer, totallen); INSIST(isc_buffer_usedlength(buffer) < totallen); /* * Write the buffer contents to the raw master file. */ result = isc_stdio_write(r.base, 1, (size_t)r.length, f, NULL); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "raw master file write failed: %s", isc_result_totext(result)); return (result); } return (result); } static isc_result_t dump_rdatasets_raw(isc_mem_t *mctx, dns_name_t *name, dns_rdatasetiter_t *rdsiter, dns_totext_ctx_t *ctx, isc_buffer_t *buffer, FILE *f) { isc_result_t result; dns_rdataset_t rdataset; for (result = dns_rdatasetiter_first(rdsiter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsiter)) { dns_rdataset_init(&rdataset); dns_rdatasetiter_current(rdsiter, &rdataset); if (((rdataset.attributes & DNS_RDATASETATTR_NEGATIVE) != 0) && (ctx->style.flags & DNS_STYLEFLAG_NCACHE) == 0) { /* Omit negative cache entries */ } else { result = dump_rdataset_raw(mctx, name, &rdataset, buffer, f); } dns_rdataset_disassociate(&rdataset); if (result != ISC_R_SUCCESS) return (result); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; return (result); } static isc_result_t dump_rdatasets_map(isc_mem_t *mctx, dns_name_t *name, dns_rdatasetiter_t *rdsiter, dns_totext_ctx_t *ctx, isc_buffer_t *buffer, FILE *f) { UNUSED(mctx); UNUSED(name); UNUSED(rdsiter); UNUSED(ctx); UNUSED(buffer); UNUSED(f); return (ISC_R_NOTIMPLEMENTED); } /* * Initial size of text conversion buffer. The buffer is used * for several purposes: converting origin names, rdatasets, * $DATE timestamps, and comment strings for $TTL directives. * * When converting rdatasets, it is dynamically resized, but * when converting origins, timestamps, etc it is not. Therefore, * the initial size must large enough to hold the longest possible * text representation of any domain name (for $ORIGIN). */ static const int initial_buffer_length = 1200; static isc_result_t dumptostreaminc(dns_dumpctx_t *dctx); static void dumpctx_destroy(dns_dumpctx_t *dctx) { dctx->magic = 0; DESTROYLOCK(&dctx->lock); dns_dbiterator_destroy(&dctx->dbiter); if (dctx->version != NULL) dns_db_closeversion(dctx->db, &dctx->version, ISC_FALSE); dns_db_detach(&dctx->db); if (dctx->task != NULL) isc_task_detach(&dctx->task); if (dctx->file != NULL) isc_mem_free(dctx->mctx, dctx->file); if (dctx->tmpfile != NULL) isc_mem_free(dctx->mctx, dctx->tmpfile); isc_mem_putanddetach(&dctx->mctx, dctx, sizeof(*dctx)); } void dns_dumpctx_attach(dns_dumpctx_t *source, dns_dumpctx_t **target) { REQUIRE(DNS_DCTX_VALID(source)); REQUIRE(target != NULL && *target == NULL); LOCK(&source->lock); INSIST(source->references > 0); source->references++; INSIST(source->references != 0); /* Overflow? */ UNLOCK(&source->lock); *target = source; } void dns_dumpctx_detach(dns_dumpctx_t **dctxp) { dns_dumpctx_t *dctx; isc_boolean_t need_destroy = ISC_FALSE; REQUIRE(dctxp != NULL); dctx = *dctxp; REQUIRE(DNS_DCTX_VALID(dctx)); *dctxp = NULL; LOCK(&dctx->lock); INSIST(dctx->references != 0); dctx->references--; if (dctx->references == 0) need_destroy = ISC_TRUE; UNLOCK(&dctx->lock); if (need_destroy) dumpctx_destroy(dctx); } dns_dbversion_t * dns_dumpctx_version(dns_dumpctx_t *dctx) { REQUIRE(DNS_DCTX_VALID(dctx)); return (dctx->version); } dns_db_t * dns_dumpctx_db(dns_dumpctx_t *dctx) { REQUIRE(DNS_DCTX_VALID(dctx)); return (dctx->db); } void dns_dumpctx_cancel(dns_dumpctx_t *dctx) { REQUIRE(DNS_DCTX_VALID(dctx)); LOCK(&dctx->lock); dctx->canceled = ISC_TRUE; UNLOCK(&dctx->lock); } static isc_result_t flushandsync(FILE *f, isc_result_t result, const char *temp) { isc_boolean_t logit = ISC_TF(result == ISC_R_SUCCESS); if (result == ISC_R_SUCCESS) result = isc_stdio_flush(f); if (result != ISC_R_SUCCESS && logit) { if (temp != NULL) isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, "dumping to master file: %s: flush: %s", temp, isc_result_totext(result)); else isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, "dumping to stream: flush: %s", isc_result_totext(result)); logit = ISC_FALSE; } if (result == ISC_R_SUCCESS) result = isc_stdio_sync(f); if (result != ISC_R_SUCCESS && logit) { if (temp != NULL) isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, "dumping to master file: %s: fsync: %s", temp, isc_result_totext(result)); else isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, "dumping to stream: fsync: %s", isc_result_totext(result)); } return (result); } static isc_result_t closeandrename(FILE *f, isc_result_t result, const char *temp, const char *file) { isc_result_t tresult; isc_boolean_t logit = ISC_TF(result == ISC_R_SUCCESS); result = flushandsync(f, result, temp); if (result != ISC_R_SUCCESS) logit = ISC_FALSE; tresult = isc_stdio_close(f); if (result == ISC_R_SUCCESS) result = tresult; if (result != ISC_R_SUCCESS && logit) { isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, "dumping master file: %s: fclose: %s", temp, isc_result_totext(result)); logit = ISC_FALSE; } if (result == ISC_R_SUCCESS) result = isc_file_rename(temp, file); else (void)isc_file_remove(temp); if (result != ISC_R_SUCCESS && logit) { isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, "dumping master file: rename: %s: %s", file, isc_result_totext(result)); } return (result); } static void dump_quantum(isc_task_t *task, isc_event_t *event) { isc_result_t result; isc_result_t tresult; dns_dumpctx_t *dctx; REQUIRE(event != NULL); dctx = event->ev_arg; REQUIRE(DNS_DCTX_VALID(dctx)); if (dctx->canceled) result = ISC_R_CANCELED; else result = dumptostreaminc(dctx); if (result == DNS_R_CONTINUE) { event->ev_arg = dctx; isc_task_send(task, &event); return; } if (dctx->file != NULL) { tresult = closeandrename(dctx->f, result, dctx->tmpfile, dctx->file); if (tresult != ISC_R_SUCCESS && result == ISC_R_SUCCESS) result = tresult; } else result = flushandsync(dctx->f, result, NULL); (dctx->done)(dctx->done_arg, result); isc_event_free(&event); dns_dumpctx_detach(&dctx); } static isc_result_t task_send(dns_dumpctx_t *dctx) { isc_event_t *event; event = isc_event_allocate(dctx->mctx, NULL, DNS_EVENT_DUMPQUANTUM, dump_quantum, dctx, sizeof(*event)); if (event == NULL) return (ISC_R_NOMEMORY); isc_task_send(dctx->task, &event); return (ISC_R_SUCCESS); } static isc_result_t dumpctx_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, FILE *f, dns_dumpctx_t **dctxp, dns_masterformat_t format, dns_masterrawheader_t *header) { dns_dumpctx_t *dctx; isc_result_t result; unsigned int options; dctx = isc_mem_get(mctx, sizeof(*dctx)); if (dctx == NULL) return (ISC_R_NOMEMORY); dctx->mctx = NULL; dctx->f = f; dctx->dbiter = NULL; dctx->db = NULL; dctx->version = NULL; dctx->done = NULL; dctx->done_arg = NULL; dctx->task = NULL; dctx->nodes = 0; dctx->first = ISC_TRUE; dctx->canceled = ISC_FALSE; dctx->file = NULL; dctx->tmpfile = NULL; dctx->format = format; if (header == NULL) dns_master_initrawheader(&dctx->header); else dctx->header = *header; switch (format) { case dns_masterformat_text: dctx->dumpsets = dump_rdatasets_text; break; case dns_masterformat_raw: dctx->dumpsets = dump_rdatasets_raw; break; case dns_masterformat_map: dctx->dumpsets = dump_rdatasets_map; break; default: INSIST(0); break; } result = totext_ctx_init(style, &dctx->tctx); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "could not set master file style"); goto cleanup; } isc_stdtime_get(&dctx->now); dns_db_attach(db, &dctx->db); dctx->do_date = dns_db_iscache(dctx->db); if (dctx->format == dns_masterformat_text && (dctx->tctx.style.flags & DNS_STYLEFLAG_REL_OWNER) != 0) { options = DNS_DB_RELATIVENAMES; } else options = 0; result = dns_db_createiterator(dctx->db, options, &dctx->dbiter); if (result != ISC_R_SUCCESS) goto cleanup; result = isc_mutex_init(&dctx->lock); if (result != ISC_R_SUCCESS) goto cleanup; if (version != NULL) dns_db_attachversion(dctx->db, version, &dctx->version); else if (!dns_db_iscache(db)) dns_db_currentversion(dctx->db, &dctx->version); isc_mem_attach(mctx, &dctx->mctx); dctx->references = 1; dctx->magic = DNS_DCTX_MAGIC; *dctxp = dctx; return (ISC_R_SUCCESS); cleanup: if (dctx->dbiter != NULL) dns_dbiterator_destroy(&dctx->dbiter); if (dctx->db != NULL) dns_db_detach(&dctx->db); if (dctx != NULL) isc_mem_put(mctx, dctx, sizeof(*dctx)); return (result); } static isc_result_t writeheader(dns_dumpctx_t *dctx) { isc_result_t result = ISC_R_SUCCESS; isc_buffer_t buffer; char *bufmem; isc_region_t r; dns_masterrawheader_t rawheader; isc_uint32_t rawversion, now32; bufmem = isc_mem_get(dctx->mctx, initial_buffer_length); if (bufmem == NULL) return (ISC_R_NOMEMORY); isc_buffer_init(&buffer, bufmem, initial_buffer_length); switch (dctx->format) { case dns_masterformat_text: /* * If the database has cache semantics, output an * RFC2540 $DATE directive so that the TTLs can be * adjusted when it is reloaded. For zones it is not * really needed, and it would make the file * incompatible with pre-RFC2540 software, so we omit * it in the zone case. */ if (dctx->do_date) { result = dns_time32_totext(dctx->now, &buffer); RUNTIME_CHECK(result == ISC_R_SUCCESS); isc_buffer_usedregion(&buffer, &r); fprintf(dctx->f, "$DATE %.*s\n", (int) r.length, (char *) r.base); } break; case dns_masterformat_raw: case dns_masterformat_map: r.base = (unsigned char *)&rawheader; r.length = sizeof(rawheader); isc_buffer_region(&buffer, &r); #if !defined(STDTIME_ON_32BITS) || (STDTIME_ON_32BITS + 0) != 1 /* * We assume isc_stdtime_t is a 32-bit integer, * which should be the case on most platforms. * If it turns out to be uncommon, we'll need * to bump the version number and revise the * header format. */ isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTERDUMP, ISC_LOG_INFO, "dumping master file in raw " "format: stdtime is not 32bits"); now32 = 0; #else now32 = dctx->now; #endif rawversion = 1; if ((dctx->header.flags & DNS_MASTERRAW_COMPAT) != 0) rawversion = 0; isc_buffer_putuint32(&buffer, dctx->format); isc_buffer_putuint32(&buffer, rawversion); isc_buffer_putuint32(&buffer, now32); if (rawversion == 1) { isc_buffer_putuint32(&buffer, dctx->header.flags); isc_buffer_putuint32(&buffer, dctx->header.sourceserial); isc_buffer_putuint32(&buffer, dctx->header.lastxfrin); } INSIST(isc_buffer_usedlength(&buffer) <= sizeof(rawheader)); result = isc_stdio_write(buffer.base, 1, isc_buffer_usedlength(&buffer), dctx->f, NULL); if (result != ISC_R_SUCCESS) break; break; default: INSIST(0); } isc_mem_put(dctx->mctx, buffer.base, buffer.length); return (result); } static isc_result_t dumptostreaminc(dns_dumpctx_t *dctx) { isc_result_t result = ISC_R_SUCCESS; isc_buffer_t buffer; char *bufmem; dns_name_t *name; dns_fixedname_t fixname; unsigned int nodes; isc_time_t start; bufmem = isc_mem_get(dctx->mctx, initial_buffer_length); if (bufmem == NULL) return (ISC_R_NOMEMORY); isc_buffer_init(&buffer, bufmem, initial_buffer_length); dns_fixedname_init(&fixname); name = dns_fixedname_name(&fixname); if (dctx->first) { CHECK(writeheader(dctx)); /* * Fast format is not currently written incrementally, * so we make the call to dns_db_serialize() here. * If the database is anything other than an rbtdb, * this should result in not implemented */ if (dctx->format == dns_masterformat_map) { result = dns_db_serialize(dctx->db, dctx->version, dctx->f); goto cleanup; } result = dns_dbiterator_first(dctx->dbiter); if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE) goto cleanup; dctx->first = ISC_FALSE; } else result = ISC_R_SUCCESS; nodes = dctx->nodes; isc_time_now(&start); while (result == ISC_R_SUCCESS && (dctx->nodes == 0 || nodes--)) { dns_rdatasetiter_t *rdsiter = NULL; dns_dbnode_t *node = NULL; result = dns_dbiterator_current(dctx->dbiter, &node, name); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) break; if (result == DNS_R_NEWORIGIN) { dns_name_t *origin = dns_fixedname_name(&dctx->tctx.origin_fixname); result = dns_dbiterator_origin(dctx->dbiter, origin); RUNTIME_CHECK(result == ISC_R_SUCCESS); if ((dctx->tctx.style.flags & DNS_STYLEFLAG_REL_DATA) != 0) dctx->tctx.origin = origin; dctx->tctx.neworigin = origin; } result = dns_db_allrdatasets(dctx->db, node, dctx->version, dctx->now, &rdsiter); if (result != ISC_R_SUCCESS) { dns_db_detachnode(dctx->db, &node); goto cleanup; } result = (dctx->dumpsets)(dctx->mctx, name, rdsiter, &dctx->tctx, &buffer, dctx->f); dns_rdatasetiter_destroy(&rdsiter); if (result != ISC_R_SUCCESS) { dns_db_detachnode(dctx->db, &node); goto cleanup; } dns_db_detachnode(dctx->db, &node); result = dns_dbiterator_next(dctx->dbiter); } /* * Work out how many nodes can be written in the time between * two requests to the nameserver. Smooth the resulting number and * use it as a estimate for the number of nodes to be written in the * next iteration. */ if (dctx->nodes != 0 && result == ISC_R_SUCCESS) { unsigned int pps = dns_pps; /* packets per second */ unsigned int interval; isc_uint64_t usecs; isc_time_t end; isc_time_now(&end); if (pps < 100) pps = 100; interval = 1000000 / pps; /* interval in usecs */ if (interval == 0) interval = 1; usecs = isc_time_microdiff(&end, &start); if (usecs == 0) { dctx->nodes = dctx->nodes * 2; if (dctx->nodes > 1000) dctx->nodes = 1000; } else { nodes = dctx->nodes * interval; nodes /= (unsigned int)usecs; if (nodes == 0) nodes = 1; else if (nodes > 1000) nodes = 1000; /* Smooth and assign. */ dctx->nodes = (nodes + dctx->nodes * 7) / 8; isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTERDUMP, ISC_LOG_DEBUG(1), "dumptostreaminc(%p) new nodes -> %d\n", dctx, dctx->nodes); } result = DNS_R_CONTINUE; } else if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; cleanup: RUNTIME_CHECK(dns_dbiterator_pause(dctx->dbiter) == ISC_R_SUCCESS); isc_mem_put(dctx->mctx, buffer.base, buffer.length); return (result); } isc_result_t dns_master_dumptostreaminc(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, FILE *f, isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, dns_dumpctx_t **dctxp) { dns_dumpctx_t *dctx = NULL; isc_result_t result; REQUIRE(task != NULL); REQUIRE(f != NULL); REQUIRE(done != NULL); result = dumpctx_create(mctx, db, version, style, f, &dctx, dns_masterformat_text, NULL); if (result != ISC_R_SUCCESS) return (result); isc_task_attach(task, &dctx->task); dctx->done = done; dctx->done_arg = done_arg; dctx->nodes = 100; result = task_send(dctx); if (result == ISC_R_SUCCESS) { dns_dumpctx_attach(dctx, dctxp); return (DNS_R_CONTINUE); } dns_dumpctx_detach(&dctx); return (result); } /* * Dump an entire database into a master file. */ isc_result_t dns_master_dumptostream(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, FILE *f) { return (dns_master_dumptostream3(mctx, db, version, style, dns_masterformat_text, NULL, f)); } isc_result_t dns_master_dumptostream2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, dns_masterformat_t format, FILE *f) { return (dns_master_dumptostream3(mctx, db, version, style, format, NULL, f)); } isc_result_t dns_master_dumptostream3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, dns_masterformat_t format, dns_masterrawheader_t *header, FILE *f) { dns_dumpctx_t *dctx = NULL; isc_result_t result; result = dumpctx_create(mctx, db, version, style, f, &dctx, format, header); if (result != ISC_R_SUCCESS) return (result); result = dumptostreaminc(dctx); INSIST(result != DNS_R_CONTINUE); dns_dumpctx_detach(&dctx); result = flushandsync(f, result, NULL); return (result); } static isc_result_t opentmp(isc_mem_t *mctx, dns_masterformat_t format, const char *file, char **tempp, FILE **fp) { FILE *f = NULL; isc_result_t result; char *tempname = NULL; int tempnamelen; tempnamelen = strlen(file) + 20; tempname = isc_mem_allocate(mctx, tempnamelen); if (tempname == NULL) return (ISC_R_NOMEMORY); result = isc_file_mktemplate(file, tempname, tempnamelen); if (result != ISC_R_SUCCESS) goto cleanup; if (format == dns_masterformat_text) result = isc_file_openunique(tempname, &f); else result = isc_file_bopenunique(tempname, &f); if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, "dumping master file: %s: open: %s", tempname, isc_result_totext(result)); goto cleanup; } *tempp = tempname; *fp = f; return (ISC_R_SUCCESS); cleanup: isc_mem_free(mctx, tempname); return (result); } isc_result_t dns_master_dumpinc(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, const char *filename, isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, dns_dumpctx_t **dctxp) { return (dns_master_dumpinc3(mctx, db, version, style, filename, task, done, done_arg, dctxp, dns_masterformat_text, NULL)); } isc_result_t dns_master_dumpinc2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, const char *filename, isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, dns_dumpctx_t **dctxp, dns_masterformat_t format) { return (dns_master_dumpinc3(mctx, db, version, style, filename, task, done, done_arg, dctxp, format, NULL)); } isc_result_t dns_master_dumpinc3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, const char *filename, isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, dns_dumpctx_t **dctxp, dns_masterformat_t format, dns_masterrawheader_t *header) { FILE *f = NULL; isc_result_t result; char *tempname = NULL; char *file = NULL; dns_dumpctx_t *dctx = NULL; file = isc_mem_strdup(mctx, filename); if (file == NULL) return (ISC_R_NOMEMORY); result = opentmp(mctx, format, filename, &tempname, &f); if (result != ISC_R_SUCCESS) goto cleanup; result = dumpctx_create(mctx, db, version, style, f, &dctx, format, header); if (result != ISC_R_SUCCESS) { (void)isc_stdio_close(f); (void)isc_file_remove(tempname); goto cleanup; } isc_task_attach(task, &dctx->task); dctx->done = done; dctx->done_arg = done_arg; dctx->nodes = 100; dctx->file = file; file = NULL; dctx->tmpfile = tempname; tempname = NULL; result = task_send(dctx); if (result == ISC_R_SUCCESS) { dns_dumpctx_attach(dctx, dctxp); return (DNS_R_CONTINUE); } cleanup: if (dctx != NULL) dns_dumpctx_detach(&dctx); if (file != NULL) isc_mem_free(mctx, file); if (tempname != NULL) isc_mem_free(mctx, tempname); return (result); } isc_result_t dns_master_dump(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, const char *filename) { return (dns_master_dump3(mctx, db, version, style, filename, dns_masterformat_text, NULL)); } isc_result_t dns_master_dump2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, const char *filename, dns_masterformat_t format) { return (dns_master_dump3(mctx, db, version, style, filename, format, NULL)); } isc_result_t dns_master_dump3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, const char *filename, dns_masterformat_t format, dns_masterrawheader_t *header) { FILE *f = NULL; isc_result_t result; char *tempname; dns_dumpctx_t *dctx = NULL; result = opentmp(mctx, format, filename, &tempname, &f); if (result != ISC_R_SUCCESS) return (result); result = dumpctx_create(mctx, db, version, style, f, &dctx, format, header); if (result != ISC_R_SUCCESS) goto cleanup; result = dumptostreaminc(dctx); INSIST(result != DNS_R_CONTINUE); dns_dumpctx_detach(&dctx); result = closeandrename(f, result, tempname, filename); cleanup: isc_mem_free(mctx, tempname); return (result); } /* * Dump a database node into a master file. * XXX: this function assumes the text format. */ isc_result_t dns_master_dumpnodetostream(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, dns_name_t *name, const dns_master_style_t *style, FILE *f) { isc_result_t result; isc_buffer_t buffer; char *bufmem; isc_stdtime_t now; dns_totext_ctx_t ctx; dns_rdatasetiter_t *rdsiter = NULL; result = totext_ctx_init(style, &ctx); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "could not set master file style"); return (ISC_R_UNEXPECTED); } isc_stdtime_get(&now); bufmem = isc_mem_get(mctx, initial_buffer_length); if (bufmem == NULL) return (ISC_R_NOMEMORY); isc_buffer_init(&buffer, bufmem, initial_buffer_length); result = dns_db_allrdatasets(db, node, version, now, &rdsiter); if (result != ISC_R_SUCCESS) goto failure; result = dump_rdatasets_text(mctx, name, rdsiter, &ctx, &buffer, f); if (result != ISC_R_SUCCESS) goto failure; dns_rdatasetiter_destroy(&rdsiter); result = ISC_R_SUCCESS; failure: isc_mem_put(mctx, buffer.base, buffer.length); return (result); } isc_result_t dns_master_dumpnode(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, dns_name_t *name, const dns_master_style_t *style, const char *filename) { FILE *f = NULL; isc_result_t result; result = isc_stdio_open(filename, "w", &f); if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, "dumping node to file: %s: open: %s", filename, isc_result_totext(result)); return (ISC_R_UNEXPECTED); } result = dns_master_dumpnodetostream(mctx, db, version, node, name, style, f); if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, "dumping master file: %s: dump: %s", filename, isc_result_totext(result)); (void)isc_stdio_close(f); return (ISC_R_UNEXPECTED); } result = isc_stdio_close(f); if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, "dumping master file: %s: close: %s", filename, isc_result_totext(result)); return (ISC_R_UNEXPECTED); } return (result); } isc_result_t dns_master_stylecreate(dns_master_style_t **stylep, unsigned int flags, unsigned int ttl_column, unsigned int class_column, unsigned int type_column, unsigned int rdata_column, unsigned int line_length, unsigned int tab_width, isc_mem_t *mctx) { return (dns_master_stylecreate2(stylep, flags, ttl_column, class_column, type_column, rdata_column, line_length, tab_width, 0xffffffff, mctx)); } isc_result_t dns_master_stylecreate2(dns_master_style_t **stylep, unsigned int flags, unsigned int ttl_column, unsigned int class_column, unsigned int type_column, unsigned int rdata_column, unsigned int line_length, unsigned int tab_width, unsigned int split_width, isc_mem_t *mctx) { dns_master_style_t *style; REQUIRE(stylep != NULL && *stylep == NULL); style = isc_mem_get(mctx, sizeof(*style)); if (style == NULL) return (ISC_R_NOMEMORY); style->flags = flags; style->ttl_column = ttl_column; style->class_column = class_column; style->type_column = type_column; style->rdata_column = rdata_column; style->line_length = line_length; style->tab_width = tab_width; style->split_width = split_width; *stylep = style; return (ISC_R_SUCCESS); } void dns_master_styledestroy(dns_master_style_t **stylep, isc_mem_t *mctx) { dns_master_style_t *style; REQUIRE(stylep != NULL && *stylep != NULL); style = *stylep; *stylep = NULL; isc_mem_put(mctx, style, sizeof(*style)); } bind9-9.10.3.dfsg.P4/lib/dns/xfrin.c0000644000470500017500000011676412664710322016234 0ustar lamontlamont/* * Copyright (C) 2004-2008, 2011-2013, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include /* Required for HP/UX (and others?) */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* * Incoming AXFR and IXFR. */ /*% * It would be non-sensical (or at least obtuse) to use FAIL() with an * ISC_R_SUCCESS code, but the test is there to keep the Solaris compiler * from complaining about "end-of-loop code not reached". */ #define FAIL(code) \ do { result = (code); \ if (result != ISC_R_SUCCESS) goto failure; \ } while (0) #define CHECK(op) \ do { result = (op); \ if (result != ISC_R_SUCCESS) goto failure; \ } while (0) /*% * The states of the *XFR state machine. We handle both IXFR and AXFR * with a single integrated state machine because they cannot be distinguished * immediately - an AXFR response to an IXFR request can only be detected * when the first two (2) response RRs have already been received. */ typedef enum { XFRST_SOAQUERY, XFRST_GOTSOA, XFRST_INITIALSOA, XFRST_FIRSTDATA, XFRST_IXFR_DELSOA, XFRST_IXFR_DEL, XFRST_IXFR_ADDSOA, XFRST_IXFR_ADD, XFRST_IXFR_END, XFRST_AXFR, XFRST_AXFR_END } xfrin_state_t; /*% * Incoming zone transfer context. */ struct dns_xfrin_ctx { unsigned int magic; isc_mem_t *mctx; dns_zone_t *zone; int refcount; isc_task_t *task; isc_timer_t *timer; isc_socketmgr_t *socketmgr; int connects; /*%< Connect in progress */ int sends; /*%< Send in progress */ int recvs; /*%< Receive in progress */ isc_boolean_t shuttingdown; isc_result_t shutdown_result; dns_name_t name; /*%< Name of zone to transfer */ dns_rdataclass_t rdclass; isc_boolean_t checkid; dns_messageid_t id; /*% * Requested transfer type (dns_rdatatype_axfr or * dns_rdatatype_ixfr). The actual transfer type * may differ due to IXFR->AXFR fallback. */ dns_rdatatype_t reqtype; isc_dscp_t dscp; isc_sockaddr_t masteraddr; isc_sockaddr_t sourceaddr; isc_socket_t *socket; /*% Buffer for IXFR/AXFR request message */ isc_buffer_t qbuffer; unsigned char qbuffer_data[512]; /*% Incoming reply TCP message */ dns_tcpmsg_t tcpmsg; isc_boolean_t tcpmsg_valid; dns_db_t *db; dns_dbversion_t *ver; dns_diff_t diff; /*%< Pending database changes */ int difflen; /*%< Number of pending tuples */ xfrin_state_t state; isc_uint32_t end_serial; isc_boolean_t is_ixfr; unsigned int nmsg; /*%< Number of messages recvd */ unsigned int nrecs; /*%< Number of records recvd */ isc_uint64_t nbytes; /*%< Number of bytes received */ isc_time_t start; /*%< Start time of the transfer */ isc_time_t end; /*%< End time of the transfer */ dns_tsigkey_t *tsigkey; /*%< Key used to create TSIG */ isc_buffer_t *lasttsig; /*%< The last TSIG */ dst_context_t *tsigctx; /*%< TSIG verification context */ unsigned int sincetsig; /*%< recvd since the last TSIG */ dns_xfrindone_t done; /*% * AXFR- and IXFR-specific data. Only one is used at a time * according to the is_ixfr flag, so this could be a union, * but keeping them separate makes it a bit simpler to clean * things up when destroying the context. */ dns_rdatacallbacks_t axfr; struct { isc_uint32_t request_serial; isc_uint32_t current_serial; dns_journal_t *journal; } ixfr; }; #define XFRIN_MAGIC ISC_MAGIC('X', 'f', 'r', 'I') #define VALID_XFRIN(x) ISC_MAGIC_VALID(x, XFRIN_MAGIC) /**************************************************************************/ /* * Forward declarations. */ static isc_result_t xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_task_t *task, isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, dns_name_t *zonename, dns_rdataclass_t rdclass, dns_rdatatype_t reqtype, isc_sockaddr_t *masteraddr, isc_sockaddr_t *sourceaddr, isc_dscp_t dscp, dns_tsigkey_t *tsigkey, dns_xfrin_ctx_t **xfrp); static isc_result_t axfr_init(dns_xfrin_ctx_t *xfr); static isc_result_t axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp); static isc_result_t axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata); static isc_result_t axfr_apply(dns_xfrin_ctx_t *xfr); static isc_result_t axfr_commit(dns_xfrin_ctx_t *xfr); static isc_result_t axfr_finalize(dns_xfrin_ctx_t *xfr); static isc_result_t ixfr_init(dns_xfrin_ctx_t *xfr); static isc_result_t ixfr_apply(dns_xfrin_ctx_t *xfr); static isc_result_t ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata); static isc_result_t ixfr_commit(dns_xfrin_ctx_t *xfr); static isc_result_t xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, isc_uint32_t ttl, dns_rdata_t *rdata); static isc_result_t xfrin_start(dns_xfrin_ctx_t *xfr); static void xfrin_connect_done(isc_task_t *task, isc_event_t *event); static isc_result_t xfrin_send_request(dns_xfrin_ctx_t *xfr); static void xfrin_send_done(isc_task_t *task, isc_event_t *event); static void xfrin_recv_done(isc_task_t *task, isc_event_t *event); static void xfrin_timeout(isc_task_t *task, isc_event_t *event); static void maybe_free(dns_xfrin_ctx_t *xfr); static void xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg); static isc_result_t render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf); static void xfrin_logv(int level, const char *zonetext, isc_sockaddr_t *masteraddr, const char *fmt, va_list ap) ISC_FORMAT_PRINTF(4, 0); static void xfrin_log1(int level, const char *zonetext, isc_sockaddr_t *masteraddr, const char *fmt, ...) ISC_FORMAT_PRINTF(4, 5); static void xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4); /**************************************************************************/ /* * AXFR handling */ static isc_result_t axfr_init(dns_xfrin_ctx_t *xfr) { isc_result_t result; xfr->is_ixfr = ISC_FALSE; if (xfr->db != NULL) dns_db_detach(&xfr->db); CHECK(axfr_makedb(xfr, &xfr->db)); dns_rdatacallbacks_init(&xfr->axfr); CHECK(dns_db_beginload(xfr->db, &xfr->axfr)); result = ISC_R_SUCCESS; failure: return (result); } static isc_result_t axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp) { isc_result_t result; result = dns_db_create(xfr->mctx, /* XXX */ "rbt", /* XXX guess */ &xfr->name, dns_dbtype_zone, xfr->rdclass, 0, NULL, /* XXX guess */ dbp); if (result == ISC_R_SUCCESS) dns_zone_rpz_enable_db(xfr->zone, *dbp); return (result); } static isc_result_t axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) { isc_result_t result; dns_difftuple_t *tuple = NULL; CHECK(dns_zone_checknames(xfr->zone, name, rdata)); CHECK(dns_difftuple_create(xfr->diff.mctx, op, name, ttl, rdata, &tuple)); dns_diff_append(&xfr->diff, &tuple); if (++xfr->difflen > 100) CHECK(axfr_apply(xfr)); result = ISC_R_SUCCESS; failure: return (result); } /* * Store a set of AXFR RRs in the database. */ static isc_result_t axfr_apply(dns_xfrin_ctx_t *xfr) { isc_result_t result; CHECK(dns_diff_load(&xfr->diff, xfr->axfr.add, xfr->axfr.add_private)); xfr->difflen = 0; dns_diff_clear(&xfr->diff); result = ISC_R_SUCCESS; failure: return (result); } static isc_result_t axfr_commit(dns_xfrin_ctx_t *xfr) { isc_result_t result; CHECK(axfr_apply(xfr)); CHECK(dns_db_endload(xfr->db, &xfr->axfr)); result = ISC_R_SUCCESS; failure: return (result); } static isc_result_t axfr_finalize(dns_xfrin_ctx_t *xfr) { isc_result_t result; CHECK(dns_zone_replacedb(xfr->zone, xfr->db, ISC_TRUE)); result = ISC_R_SUCCESS; failure: return (result); } /**************************************************************************/ /* * IXFR handling */ static isc_result_t ixfr_init(dns_xfrin_ctx_t *xfr) { isc_result_t result; char *journalfile; if (xfr->reqtype != dns_rdatatype_ixfr) { xfrin_log(xfr, ISC_LOG_ERROR, "got incremental response to AXFR request"); return (DNS_R_FORMERR); } xfr->is_ixfr = ISC_TRUE; INSIST(xfr->db != NULL); xfr->difflen = 0; journalfile = dns_zone_getjournal(xfr->zone); if (journalfile != NULL) CHECK(dns_journal_open(xfr->mctx, journalfile, DNS_JOURNAL_CREATE, &xfr->ixfr.journal)); result = ISC_R_SUCCESS; failure: return (result); } static isc_result_t ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) { isc_result_t result; dns_difftuple_t *tuple = NULL; if (op == DNS_DIFFOP_ADD) CHECK(dns_zone_checknames(xfr->zone, name, rdata)); CHECK(dns_difftuple_create(xfr->diff.mctx, op, name, ttl, rdata, &tuple)); dns_diff_append(&xfr->diff, &tuple); if (++xfr->difflen > 100) CHECK(ixfr_apply(xfr)); result = ISC_R_SUCCESS; failure: return (result); } /* * Apply a set of IXFR changes to the database. */ static isc_result_t ixfr_apply(dns_xfrin_ctx_t *xfr) { isc_result_t result; if (xfr->ver == NULL) { CHECK(dns_db_newversion(xfr->db, &xfr->ver)); if (xfr->ixfr.journal != NULL) CHECK(dns_journal_begin_transaction(xfr->ixfr.journal)); } CHECK(dns_diff_apply(&xfr->diff, xfr->db, xfr->ver)); if (xfr->ixfr.journal != NULL) { result = dns_journal_writediff(xfr->ixfr.journal, &xfr->diff); if (result != ISC_R_SUCCESS) goto failure; } dns_diff_clear(&xfr->diff); xfr->difflen = 0; result = ISC_R_SUCCESS; failure: return (result); } static isc_result_t ixfr_commit(dns_xfrin_ctx_t *xfr) { isc_result_t result; CHECK(ixfr_apply(xfr)); if (xfr->ver != NULL) { /* XXX enter ready-to-commit state here */ if (xfr->ixfr.journal != NULL) CHECK(dns_journal_commit(xfr->ixfr.journal)); dns_db_closeversion(xfr->db, &xfr->ver, ISC_TRUE); dns_zone_markdirty(xfr->zone); } result = ISC_R_SUCCESS; failure: return (result); } /**************************************************************************/ /* * Common AXFR/IXFR protocol code */ /* * Handle a single incoming resource record according to the current * state. */ static isc_result_t xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, isc_uint32_t ttl, dns_rdata_t *rdata) { isc_result_t result; xfr->nrecs++; if (rdata->type == dns_rdatatype_none || dns_rdatatype_ismeta(rdata->type)) FAIL(DNS_R_FORMERR); redo: switch (xfr->state) { case XFRST_SOAQUERY: if (rdata->type != dns_rdatatype_soa) { xfrin_log(xfr, ISC_LOG_ERROR, "non-SOA response to SOA query"); FAIL(DNS_R_FORMERR); } xfr->end_serial = dns_soa_getserial(rdata); if (!DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial) && !dns_zone_isforced(xfr->zone)) { xfrin_log(xfr, ISC_LOG_DEBUG(3), "requested serial %u, " "master has %u, not updating", xfr->ixfr.request_serial, xfr->end_serial); FAIL(DNS_R_UPTODATE); } xfr->state = XFRST_GOTSOA; break; case XFRST_GOTSOA: /* * Skip other records in the answer section. */ break; case XFRST_INITIALSOA: if (rdata->type != dns_rdatatype_soa) { xfrin_log(xfr, ISC_LOG_ERROR, "first RR in zone transfer must be SOA"); FAIL(DNS_R_FORMERR); } /* * Remember the serial number in the initial SOA. * We need it to recognize the end of an IXFR. */ xfr->end_serial = dns_soa_getserial(rdata); if (xfr->reqtype == dns_rdatatype_ixfr && ! DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial) && !dns_zone_isforced(xfr->zone)) { /* * This must be the single SOA record that is * sent when the current version on the master * is not newer than the version in the request. */ xfrin_log(xfr, ISC_LOG_DEBUG(3), "requested serial %u, " "master has %u, not updating", xfr->ixfr.request_serial, xfr->end_serial); FAIL(DNS_R_UPTODATE); } if (xfr->reqtype == dns_rdatatype_axfr) xfr->checkid = ISC_FALSE; xfr->state = XFRST_FIRSTDATA; break; case XFRST_FIRSTDATA: /* * If the transfer begins with one SOA record, it is an AXFR, * if it begins with two SOAs, it is an IXFR. */ if (xfr->reqtype == dns_rdatatype_ixfr && rdata->type == dns_rdatatype_soa && xfr->ixfr.request_serial == dns_soa_getserial(rdata)) { xfrin_log(xfr, ISC_LOG_DEBUG(3), "got incremental response"); CHECK(ixfr_init(xfr)); xfr->state = XFRST_IXFR_DELSOA; } else { xfrin_log(xfr, ISC_LOG_DEBUG(3), "got nonincremental response"); CHECK(axfr_init(xfr)); xfr->state = XFRST_AXFR; } goto redo; case XFRST_IXFR_DELSOA: INSIST(rdata->type == dns_rdatatype_soa); CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata)); xfr->state = XFRST_IXFR_DEL; break; case XFRST_IXFR_DEL: if (rdata->type == dns_rdatatype_soa) { isc_uint32_t soa_serial = dns_soa_getserial(rdata); xfr->state = XFRST_IXFR_ADDSOA; xfr->ixfr.current_serial = soa_serial; goto redo; } CHECK(ixfr_putdata(xfr, DNS_DIFFOP_DEL, name, ttl, rdata)); break; case XFRST_IXFR_ADDSOA: INSIST(rdata->type == dns_rdatatype_soa); CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata)); xfr->state = XFRST_IXFR_ADD; break; case XFRST_IXFR_ADD: if (rdata->type == dns_rdatatype_soa) { isc_uint32_t soa_serial = dns_soa_getserial(rdata); if (soa_serial == xfr->end_serial) { CHECK(ixfr_commit(xfr)); xfr->state = XFRST_IXFR_END; break; } else if (soa_serial != xfr->ixfr.current_serial) { xfrin_log(xfr, ISC_LOG_ERROR, "IXFR out of sync: " "expected serial %u, got %u", xfr->ixfr.current_serial, soa_serial); FAIL(DNS_R_FORMERR); } else { CHECK(ixfr_commit(xfr)); xfr->state = XFRST_IXFR_DELSOA; goto redo; } } if (rdata->type == dns_rdatatype_ns && dns_name_iswildcard(name)) FAIL(DNS_R_INVALIDNS); CHECK(ixfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata)); break; case XFRST_AXFR: /* * Old BINDs sent cross class A records for non IN classes. */ if (rdata->type == dns_rdatatype_a && rdata->rdclass != xfr->rdclass && xfr->rdclass != dns_rdataclass_in) break; CHECK(axfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata)); if (rdata->type == dns_rdatatype_soa) { CHECK(axfr_commit(xfr)); xfr->state = XFRST_AXFR_END; break; } break; case XFRST_AXFR_END: case XFRST_IXFR_END: FAIL(DNS_R_EXTRADATA); /* NOTREACHED */ default: INSIST(0); break; } result = ISC_R_SUCCESS; failure: return (result); } isc_result_t dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype, isc_sockaddr_t *masteraddr, dns_tsigkey_t *tsigkey, isc_mem_t *mctx, isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, isc_task_t *task, dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp) { isc_sockaddr_t sourceaddr; isc_dscp_t dscp; switch (isc_sockaddr_pf(masteraddr)) { case PF_INET: sourceaddr = *dns_zone_getxfrsource4(zone); dscp = dns_zone_getxfrsource4dscp(zone); break; case PF_INET6: sourceaddr = *dns_zone_getxfrsource6(zone); dscp = dns_zone_getxfrsource6dscp(zone); break; default: INSIST(0); } return(dns_xfrin_create3(zone, xfrtype, masteraddr, &sourceaddr, dscp, tsigkey, mctx, timermgr, socketmgr, task, done, xfrp)); } isc_result_t dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype, isc_sockaddr_t *masteraddr, isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey, isc_mem_t *mctx, isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, isc_task_t *task, dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp) { return (dns_xfrin_create3(zone, xfrtype, masteraddr, sourceaddr, -1, tsigkey, mctx, timermgr, socketmgr, task, done, xfrp)); } isc_result_t dns_xfrin_create3(dns_zone_t *zone, dns_rdatatype_t xfrtype, isc_sockaddr_t *masteraddr, isc_sockaddr_t *sourceaddr, isc_dscp_t dscp, dns_tsigkey_t *tsigkey, isc_mem_t *mctx, isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, isc_task_t *task, dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp) { dns_name_t *zonename = dns_zone_getorigin(zone); dns_xfrin_ctx_t *xfr = NULL; isc_result_t result; dns_db_t *db = NULL; REQUIRE(xfrp != NULL && *xfrp == NULL); (void)dns_zone_getdb(zone, &db); if (xfrtype == dns_rdatatype_soa || xfrtype == dns_rdatatype_ixfr) REQUIRE(db != NULL); CHECK(xfrin_create(mctx, zone, db, task, timermgr, socketmgr, zonename, dns_zone_getclass(zone), xfrtype, masteraddr, sourceaddr, dscp, tsigkey, &xfr)); CHECK(xfrin_start(xfr)); xfr->done = done; if (xfr->done != NULL) xfr->refcount++; *xfrp = xfr; failure: if (db != NULL) dns_db_detach(&db); if (result != ISC_R_SUCCESS) { char zonetext[DNS_NAME_MAXTEXT+32]; dns_zone_name(zone, zonetext, sizeof(zonetext)); xfrin_log1(ISC_LOG_ERROR, zonetext, masteraddr, "zone transfer setup failed"); } return (result); } void dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr) { if (! xfr->shuttingdown) xfrin_fail(xfr, ISC_R_CANCELED, "shut down"); } void dns_xfrin_attach(dns_xfrin_ctx_t *source, dns_xfrin_ctx_t **target) { REQUIRE(target != NULL && *target == NULL); source->refcount++; *target = source; } void dns_xfrin_detach(dns_xfrin_ctx_t **xfrp) { dns_xfrin_ctx_t *xfr = *xfrp; INSIST(xfr->refcount > 0); xfr->refcount--; maybe_free(xfr); *xfrp = NULL; } static void xfrin_cancelio(dns_xfrin_ctx_t *xfr) { if (xfr->connects > 0) { isc_socket_cancel(xfr->socket, xfr->task, ISC_SOCKCANCEL_CONNECT); } else if (xfr->recvs > 0) { dns_tcpmsg_cancelread(&xfr->tcpmsg); } else if (xfr->sends > 0) { isc_socket_cancel(xfr->socket, xfr->task, ISC_SOCKCANCEL_SEND); } } static void xfrin_reset(dns_xfrin_ctx_t *xfr) { REQUIRE(VALID_XFRIN(xfr)); xfrin_log(xfr, ISC_LOG_INFO, "resetting"); xfrin_cancelio(xfr); if (xfr->socket != NULL) isc_socket_detach(&xfr->socket); if (xfr->lasttsig != NULL) isc_buffer_free(&xfr->lasttsig); dns_diff_clear(&xfr->diff); xfr->difflen = 0; if (xfr->ixfr.journal != NULL) dns_journal_destroy(&xfr->ixfr.journal); if (xfr->axfr.add_private != NULL) (void)dns_db_endload(xfr->db, &xfr->axfr); if (xfr->tcpmsg_valid) { dns_tcpmsg_invalidate(&xfr->tcpmsg); xfr->tcpmsg_valid = ISC_FALSE; } if (xfr->ver != NULL) dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE); } static void xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, const char *msg) { if (result != DNS_R_UPTODATE) { xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s", msg, isc_result_totext(result)); if (xfr->is_ixfr) /* Pass special result code to force AXFR retry */ result = DNS_R_BADIXFR; } xfrin_cancelio(xfr); /* * Close the journal. */ if (xfr->ixfr.journal != NULL) dns_journal_destroy(&xfr->ixfr.journal); if (xfr->done != NULL) { (xfr->done)(xfr->zone, result); xfr->done = NULL; } xfr->shuttingdown = ISC_TRUE; xfr->shutdown_result = result; maybe_free(xfr); } static isc_result_t xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_task_t *task, isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, dns_name_t *zonename, dns_rdataclass_t rdclass, dns_rdatatype_t reqtype, isc_sockaddr_t *masteraddr, isc_sockaddr_t *sourceaddr, isc_dscp_t dscp, dns_tsigkey_t *tsigkey, dns_xfrin_ctx_t **xfrp) { dns_xfrin_ctx_t *xfr = NULL; isc_result_t result; isc_uint32_t tmp; xfr = isc_mem_get(mctx, sizeof(*xfr)); if (xfr == NULL) return (ISC_R_NOMEMORY); xfr->mctx = NULL; isc_mem_attach(mctx, &xfr->mctx); xfr->refcount = 0; xfr->zone = NULL; dns_zone_iattach(zone, &xfr->zone); xfr->task = NULL; isc_task_attach(task, &xfr->task); xfr->timer = NULL; xfr->socketmgr = socketmgr; xfr->done = NULL; xfr->connects = 0; xfr->sends = 0; xfr->recvs = 0; xfr->shuttingdown = ISC_FALSE; xfr->shutdown_result = ISC_R_UNSET; dns_name_init(&xfr->name, NULL); xfr->rdclass = rdclass; isc_random_get(&tmp); xfr->checkid = ISC_TRUE; xfr->id = (isc_uint16_t)(tmp & 0xffff); xfr->reqtype = reqtype; xfr->dscp = dscp; /* sockaddr */ xfr->socket = NULL; /* qbuffer */ /* qbuffer_data */ /* tcpmsg */ xfr->tcpmsg_valid = ISC_FALSE; xfr->db = NULL; if (db != NULL) dns_db_attach(db, &xfr->db); xfr->ver = NULL; dns_diff_init(xfr->mctx, &xfr->diff); xfr->difflen = 0; if (reqtype == dns_rdatatype_soa) xfr->state = XFRST_SOAQUERY; else xfr->state = XFRST_INITIALSOA; /* end_serial */ xfr->nmsg = 0; xfr->nrecs = 0; xfr->nbytes = 0; isc_time_now(&xfr->start); xfr->tsigkey = NULL; if (tsigkey != NULL) dns_tsigkey_attach(tsigkey, &xfr->tsigkey); xfr->lasttsig = NULL; xfr->tsigctx = NULL; xfr->sincetsig = 0; xfr->is_ixfr = ISC_FALSE; /* ixfr.request_serial */ /* ixfr.current_serial */ xfr->ixfr.journal = NULL; xfr->axfr.add = NULL; xfr->axfr.add_private = NULL; CHECK(dns_name_dup(zonename, mctx, &xfr->name)); CHECK(isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL, task, xfrin_timeout, xfr, &xfr->timer)); CHECK(dns_timer_setidle(xfr->timer, dns_zone_getmaxxfrin(xfr->zone), dns_zone_getidlein(xfr->zone), ISC_FALSE)); xfr->masteraddr = *masteraddr; INSIST(isc_sockaddr_pf(masteraddr) == isc_sockaddr_pf(sourceaddr)); xfr->sourceaddr = *sourceaddr; isc_sockaddr_setport(&xfr->sourceaddr, 0); /* * Reserve 2 bytes for TCP length at the begining of the buffer. */ isc_buffer_init(&xfr->qbuffer, &xfr->qbuffer_data[2], sizeof(xfr->qbuffer_data) - 2); xfr->magic = XFRIN_MAGIC; *xfrp = xfr; return (ISC_R_SUCCESS); failure: if (xfr->timer != NULL) isc_timer_detach(&xfr->timer); if (dns_name_dynamic(&xfr->name)) dns_name_free(&xfr->name, xfr->mctx); if (xfr->tsigkey != NULL) dns_tsigkey_detach(&xfr->tsigkey); if (xfr->db != NULL) dns_db_detach(&xfr->db); isc_task_detach(&xfr->task); dns_zone_idetach(&xfr->zone); isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr)); return (result); } static isc_result_t xfrin_start(dns_xfrin_ctx_t *xfr) { isc_result_t result; CHECK(isc_socket_create(xfr->socketmgr, isc_sockaddr_pf(&xfr->sourceaddr), isc_sockettype_tcp, &xfr->socket)); isc_socket_setname(xfr->socket, "xfrin", NULL); #ifndef BROKEN_TCP_BIND_BEFORE_CONNECT CHECK(isc_socket_bind(xfr->socket, &xfr->sourceaddr, ISC_SOCKET_REUSEADDRESS)); #endif isc_socket_dscp(xfr->socket, xfr->dscp); CHECK(isc_socket_connect(xfr->socket, &xfr->masteraddr, xfr->task, xfrin_connect_done, xfr)); xfr->connects++; return (ISC_R_SUCCESS); failure: xfrin_fail(xfr, result, "failed setting up socket"); return (result); } /* XXX the resolver could use this, too */ static isc_result_t render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf) { dns_compress_t cctx; isc_boolean_t cleanup_cctx = ISC_FALSE; isc_result_t result; CHECK(dns_compress_init(&cctx, -1, mctx)); cleanup_cctx = ISC_TRUE; CHECK(dns_message_renderbegin(msg, &cctx, buf)); CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0)); CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0)); CHECK(dns_message_rendersection(msg, DNS_SECTION_AUTHORITY, 0)); CHECK(dns_message_rendersection(msg, DNS_SECTION_ADDITIONAL, 0)); CHECK(dns_message_renderend(msg)); result = ISC_R_SUCCESS; failure: if (cleanup_cctx) dns_compress_invalidate(&cctx); return (result); } /* * A connection has been established. */ static void xfrin_connect_done(isc_task_t *task, isc_event_t *event) { isc_socket_connev_t *cev = (isc_socket_connev_t *) event; dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg; isc_result_t result = cev->result; char sourcetext[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_t sockaddr; dns_zonemgr_t * zmgr; isc_time_t now; REQUIRE(VALID_XFRIN(xfr)); UNUSED(task); INSIST(event->ev_type == ISC_SOCKEVENT_CONNECT); isc_event_free(&event); xfr->connects--; if (xfr->shuttingdown) { maybe_free(xfr); return; } zmgr = dns_zone_getmgr(xfr->zone); if (zmgr != NULL) { if (result != ISC_R_SUCCESS) { TIME_NOW(&now); dns_zonemgr_unreachableadd(zmgr, &xfr->masteraddr, &xfr->sourceaddr, &now); goto failure; } else dns_zonemgr_unreachabledel(zmgr, &xfr->masteraddr, &xfr->sourceaddr); } result = isc_socket_getsockname(xfr->socket, &sockaddr); if (result == ISC_R_SUCCESS) { isc_sockaddr_format(&sockaddr, sourcetext, sizeof(sourcetext)); } else strcpy(sourcetext, ""); xfrin_log(xfr, ISC_LOG_INFO, "connected using %s", sourcetext); dns_tcpmsg_init(xfr->mctx, xfr->socket, &xfr->tcpmsg); xfr->tcpmsg_valid = ISC_TRUE; CHECK(xfrin_send_request(xfr)); failure: if (result != ISC_R_SUCCESS) xfrin_fail(xfr, result, "failed to connect"); } /* * Convert a tuple into a dns_name_t suitable for inserting * into the given dns_message_t. */ static isc_result_t tuple2msgname(dns_difftuple_t *tuple, dns_message_t *msg, dns_name_t **target) { isc_result_t result; dns_rdata_t *rdata = NULL; dns_rdatalist_t *rdl = NULL; dns_rdataset_t *rds = NULL; dns_name_t *name = NULL; REQUIRE(target != NULL && *target == NULL); CHECK(dns_message_gettemprdata(msg, &rdata)); dns_rdata_init(rdata); dns_rdata_clone(&tuple->rdata, rdata); CHECK(dns_message_gettemprdatalist(msg, &rdl)); dns_rdatalist_init(rdl); rdl->type = tuple->rdata.type; rdl->rdclass = tuple->rdata.rdclass; rdl->ttl = tuple->ttl; ISC_LIST_APPEND(rdl->rdata, rdata, link); CHECK(dns_message_gettemprdataset(msg, &rds)); CHECK(dns_rdatalist_tordataset(rdl, rds)); CHECK(dns_message_gettempname(msg, &name)); dns_name_init(name, NULL); dns_name_clone(&tuple->name, name); ISC_LIST_APPEND(name->list, rds, link); *target = name; return (ISC_R_SUCCESS); failure: if (rds != NULL) { dns_rdataset_disassociate(rds); dns_message_puttemprdataset(msg, &rds); } if (rdl != NULL) { ISC_LIST_UNLINK(rdl->rdata, rdata, link); dns_message_puttemprdatalist(msg, &rdl); } if (rdata != NULL) dns_message_puttemprdata(msg, &rdata); return (result); } /* * Build an *XFR request and send its length prefix. */ static isc_result_t xfrin_send_request(dns_xfrin_ctx_t *xfr) { isc_result_t result; isc_region_t region; dns_rdataset_t *qrdataset = NULL; dns_message_t *msg = NULL; dns_difftuple_t *soatuple = NULL; dns_name_t *qname = NULL; dns_dbversion_t *ver = NULL; dns_name_t *msgsoaname = NULL; /* Create the request message */ CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &msg)); CHECK(dns_message_settsigkey(msg, xfr->tsigkey)); /* Create a name for the question section. */ CHECK(dns_message_gettempname(msg, &qname)); dns_name_init(qname, NULL); dns_name_clone(&xfr->name, qname); /* Formulate the question and attach it to the question name. */ CHECK(dns_message_gettemprdataset(msg, &qrdataset)); dns_rdataset_makequestion(qrdataset, xfr->rdclass, xfr->reqtype); ISC_LIST_APPEND(qname->list, qrdataset, link); qrdataset = NULL; dns_message_addname(msg, qname, DNS_SECTION_QUESTION); qname = NULL; if (xfr->reqtype == dns_rdatatype_ixfr) { /* Get the SOA and add it to the authority section. */ /* XXX is using the current version the right thing? */ dns_db_currentversion(xfr->db, &ver); CHECK(dns_db_createsoatuple(xfr->db, ver, xfr->mctx, DNS_DIFFOP_EXISTS, &soatuple)); xfr->ixfr.request_serial = dns_soa_getserial(&soatuple->rdata); xfr->ixfr.current_serial = xfr->ixfr.request_serial; xfrin_log(xfr, ISC_LOG_DEBUG(3), "requesting IXFR for serial %u", xfr->ixfr.request_serial); CHECK(tuple2msgname(soatuple, msg, &msgsoaname)); dns_message_addname(msg, msgsoaname, DNS_SECTION_AUTHORITY); } else if (xfr->reqtype == dns_rdatatype_soa) CHECK(dns_db_getsoaserial(xfr->db, NULL, &xfr->ixfr.request_serial)); xfr->checkid = ISC_TRUE; xfr->id++; xfr->nmsg = 0; xfr->nrecs = 0; xfr->nbytes = 0; isc_time_now(&xfr->start); msg->id = xfr->id; if (xfr->tsigctx != NULL) dst_context_destroy(&xfr->tsigctx); CHECK(render(msg, xfr->mctx, &xfr->qbuffer)); /* * Free the last tsig, if there is one. */ if (xfr->lasttsig != NULL) isc_buffer_free(&xfr->lasttsig); /* * Save the query TSIG and don't let message_destroy free it. */ CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig)); isc_buffer_usedregion(&xfr->qbuffer, ®ion); INSIST(region.length <= 65535); /* * Record message length and adjust region to include TCP * length field. */ xfr->qbuffer_data[0] = (region.length >> 8) & 0xff; xfr->qbuffer_data[1] = region.length & 0xff; region.base -= 2; region.length += 2; CHECK(isc_socket_send(xfr->socket, ®ion, xfr->task, xfrin_send_done, xfr)); xfr->sends++; failure: if (qname != NULL) dns_message_puttempname(msg, &qname); if (qrdataset != NULL) dns_message_puttemprdataset(msg, &qrdataset); if (msg != NULL) dns_message_destroy(&msg); if (soatuple != NULL) dns_difftuple_free(&soatuple); if (ver != NULL) dns_db_closeversion(xfr->db, &ver, ISC_FALSE); return (result); } static void xfrin_send_done(isc_task_t *task, isc_event_t *event) { isc_socketevent_t *sev = (isc_socketevent_t *) event; dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg; isc_result_t result; REQUIRE(VALID_XFRIN(xfr)); UNUSED(task); INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE); xfr->sends--; xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request data"); CHECK(sev->result); CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task, xfrin_recv_done, xfr)); xfr->recvs++; failure: isc_event_free(&event); if (result != ISC_R_SUCCESS) xfrin_fail(xfr, result, "failed sending request data"); } static void xfrin_recv_done(isc_task_t *task, isc_event_t *ev) { dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) ev->ev_arg; isc_result_t result; dns_message_t *msg = NULL; dns_name_t *name; dns_tcpmsg_t *tcpmsg; dns_name_t *tsigowner = NULL; REQUIRE(VALID_XFRIN(xfr)); UNUSED(task); INSIST(ev->ev_type == DNS_EVENT_TCPMSG); tcpmsg = ev->ev_sender; isc_event_free(&ev); xfr->recvs--; if (xfr->shuttingdown) { maybe_free(xfr); return; } CHECK(tcpmsg->result); xfrin_log(xfr, ISC_LOG_DEBUG(7), "received %u bytes", tcpmsg->buffer.used); CHECK(isc_timer_touch(xfr->timer)); CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTPARSE, &msg)); CHECK(dns_message_settsigkey(msg, xfr->tsigkey)); CHECK(dns_message_setquerytsig(msg, xfr->lasttsig)); msg->tsigctx = xfr->tsigctx; xfr->tsigctx = NULL; dns_message_setclass(msg, xfr->rdclass); if (xfr->nmsg > 0) msg->tcp_continuation = 1; result = dns_message_parse(msg, &tcpmsg->buffer, DNS_MESSAGEPARSE_PRESERVEORDER); if (result == ISC_R_SUCCESS) dns_message_logpacket(msg, "received message:\n", DNS_LOGCATEGORY_XFER_IN, DNS_LOGMODULE_XFER_IN, ISC_LOG_DEBUG(10), xfr->mctx); else xfrin_log(xfr, ISC_LOG_DEBUG(10), "dns_message_parse: %s", dns_result_totext(result)); if (result != ISC_R_SUCCESS || msg->rcode != dns_rcode_noerror || (xfr->checkid && msg->id != xfr->id)) { if (result == ISC_R_SUCCESS) result = ISC_RESULTCLASS_DNSRCODE + msg->rcode; /*XXX*/ if (result == ISC_R_SUCCESS || result == DNS_R_NOERROR) result = DNS_R_UNEXPECTEDID; if (xfr->reqtype == dns_rdatatype_axfr || xfr->reqtype == dns_rdatatype_soa) goto failure; xfrin_log(xfr, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR", isc_result_totext(result)); try_axfr: dns_message_destroy(&msg); xfrin_reset(xfr); xfr->reqtype = dns_rdatatype_soa; xfr->state = XFRST_SOAQUERY; (void)xfrin_start(xfr); return; } /* * Does the server know about IXFR? If it doesn't we will get * a message with a empty answer section or a potentially a CNAME / * DNAME, the later is handled by xfr_rr() which will return FORMERR * if the first RR in the answer section is not a SOA record. */ if (xfr->reqtype == dns_rdatatype_ixfr && xfr->state == XFRST_INITIALSOA && msg->counts[DNS_SECTION_ANSWER] == 0) { xfrin_log(xfr, ISC_LOG_DEBUG(3), "empty answer section, retrying with AXFR"); goto try_axfr; } if (xfr->reqtype == dns_rdatatype_soa && (msg->flags & DNS_MESSAGEFLAG_AA) == 0) { FAIL(DNS_R_NOTAUTHORITATIVE); } result = dns_message_checksig(msg, dns_zone_getview(xfr->zone)); if (result != ISC_R_SUCCESS) { xfrin_log(xfr, ISC_LOG_DEBUG(3), "TSIG check failed: %s", isc_result_totext(result)); goto failure; } for (result = dns_message_firstname(msg, DNS_SECTION_ANSWER); result == ISC_R_SUCCESS; result = dns_message_nextname(msg, DNS_SECTION_ANSWER)) { dns_rdataset_t *rds; name = NULL; dns_message_currentname(msg, DNS_SECTION_ANSWER, &name); for (rds = ISC_LIST_HEAD(name->list); rds != NULL; rds = ISC_LIST_NEXT(rds, link)) { for (result = dns_rdataset_first(rds); result == ISC_R_SUCCESS; result = dns_rdataset_next(rds)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(rds, &rdata); CHECK(xfr_rr(xfr, name, rds->ttl, &rdata)); } } } if (result != ISC_R_NOMORE) goto failure; if (dns_message_gettsig(msg, &tsigowner) != NULL) { /* * Reset the counter. */ xfr->sincetsig = 0; /* * Free the last tsig, if there is one. */ if (xfr->lasttsig != NULL) isc_buffer_free(&xfr->lasttsig); /* * Update the last tsig pointer. */ CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig)); } else if (dns_message_gettsigkey(msg) != NULL) { xfr->sincetsig++; if (xfr->sincetsig > 100 || xfr->nmsg == 0 || xfr->state == XFRST_AXFR_END || xfr->state == XFRST_IXFR_END) { result = DNS_R_EXPECTEDTSIG; goto failure; } } /* * Update the number of messages received. */ xfr->nmsg++; /* * Update the number of bytes received. */ xfr->nbytes += tcpmsg->buffer.used; /* * Take the context back. */ INSIST(xfr->tsigctx == NULL); xfr->tsigctx = msg->tsigctx; msg->tsigctx = NULL; dns_message_destroy(&msg); switch (xfr->state) { case XFRST_GOTSOA: xfr->reqtype = dns_rdatatype_axfr; xfr->state = XFRST_INITIALSOA; CHECK(xfrin_send_request(xfr)); break; case XFRST_AXFR_END: CHECK(axfr_finalize(xfr)); /* FALLTHROUGH */ case XFRST_IXFR_END: /* * Close the journal. */ if (xfr->ixfr.journal != NULL) dns_journal_destroy(&xfr->ixfr.journal); /* * Inform the caller we succeeded. */ if (xfr->done != NULL) { (xfr->done)(xfr->zone, ISC_R_SUCCESS); xfr->done = NULL; } /* * We should have no outstanding events at this * point, thus maybe_free() should succeed. */ xfr->shuttingdown = ISC_TRUE; xfr->shutdown_result = ISC_R_SUCCESS; maybe_free(xfr); break; default: /* * Read the next message. */ CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task, xfrin_recv_done, xfr)); xfr->recvs++; } return; failure: if (msg != NULL) dns_message_destroy(&msg); if (result != ISC_R_SUCCESS) xfrin_fail(xfr, result, "failed while receiving responses"); } static void xfrin_timeout(isc_task_t *task, isc_event_t *event) { dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg; REQUIRE(VALID_XFRIN(xfr)); UNUSED(task); isc_event_free(&event); /* * This will log "giving up: timeout". */ xfrin_fail(xfr, ISC_R_TIMEDOUT, "giving up"); } static void maybe_free(dns_xfrin_ctx_t *xfr) { isc_uint64_t msecs; isc_uint64_t persec; const char *result_str; REQUIRE(VALID_XFRIN(xfr)); if (! xfr->shuttingdown || xfr->refcount != 0 || xfr->connects != 0 || xfr->sends != 0 || xfr->recvs != 0) return; INSIST(! xfr->shuttingdown || xfr->shutdown_result != ISC_R_UNSET); /* If we're called through dns_xfrin_detach() and are not * shutting down, we can't know what the transfer status is as * we are only called when the last reference is lost. */ result_str = (xfr->shuttingdown ? isc_result_totext(xfr->shutdown_result) : "unknown"); xfrin_log(xfr, ISC_LOG_INFO, "Transfer status: %s", result_str); /* * Calculate the length of time the transfer took, * and print a log message with the bytes and rate. */ isc_time_now(&xfr->end); msecs = isc_time_microdiff(&xfr->end, &xfr->start) / 1000; if (msecs == 0) msecs = 1; persec = (xfr->nbytes * 1000) / msecs; xfrin_log(xfr, ISC_LOG_INFO, "Transfer completed: %d messages, %d records, " "%" ISC_PRINT_QUADFORMAT "u bytes, " "%u.%03u secs (%u bytes/sec)", xfr->nmsg, xfr->nrecs, xfr->nbytes, (unsigned int) (msecs / 1000), (unsigned int) (msecs % 1000), (unsigned int) persec); if (xfr->socket != NULL) isc_socket_detach(&xfr->socket); if (xfr->timer != NULL) isc_timer_detach(&xfr->timer); if (xfr->task != NULL) isc_task_detach(&xfr->task); if (xfr->tsigkey != NULL) dns_tsigkey_detach(&xfr->tsigkey); if (xfr->lasttsig != NULL) isc_buffer_free(&xfr->lasttsig); dns_diff_clear(&xfr->diff); if (xfr->ixfr.journal != NULL) dns_journal_destroy(&xfr->ixfr.journal); if (xfr->axfr.add_private != NULL) (void)dns_db_endload(xfr->db, &xfr->axfr); if (xfr->tcpmsg_valid) dns_tcpmsg_invalidate(&xfr->tcpmsg); if (xfr->tsigctx != NULL) dst_context_destroy(&xfr->tsigctx); if ((xfr->name.attributes & DNS_NAMEATTR_DYNAMIC) != 0) dns_name_free(&xfr->name, xfr->mctx); if (xfr->ver != NULL) dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE); if (xfr->db != NULL) dns_db_detach(&xfr->db); if (xfr->zone != NULL) dns_zone_idetach(&xfr->zone); isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr)); } /* * Log incoming zone transfer messages in a format like * transfer of from
: */ static void xfrin_logv(int level, const char *zonetext, isc_sockaddr_t *masteraddr, const char *fmt, va_list ap) { char mastertext[ISC_SOCKADDR_FORMATSIZE]; char msgtext[2048]; isc_sockaddr_format(masteraddr, mastertext, sizeof(mastertext)); vsnprintf(msgtext, sizeof(msgtext), fmt, ap); isc_log_write(dns_lctx, DNS_LOGCATEGORY_XFER_IN, DNS_LOGMODULE_XFER_IN, level, "transfer of '%s' from %s: %s", zonetext, mastertext, msgtext); } /* * Logging function for use when a xfrin_ctx_t has not yet been created. */ static void xfrin_log1(int level, const char *zonetext, isc_sockaddr_t *masteraddr, const char *fmt, ...) { va_list ap; if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) return; va_start(ap, fmt); xfrin_logv(level, zonetext, masteraddr, fmt, ap); va_end(ap); } /* * Logging function for use when there is a xfrin_ctx_t. */ static void xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...) { va_list ap; char zonetext[DNS_NAME_MAXTEXT+32]; if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) return; dns_zone_name(xfr->zone, zonetext, sizeof(zonetext)); va_start(ap, fmt); xfrin_logv(level, zonetext, &xfr->masteraddr, fmt, ap); va_end(ap); } bind9-9.10.3.dfsg.P4/lib/dns/compress.c0000644000470500017500000001733612664710322016734 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: compress.c,v 1.59 2007/06/19 23:47:16 tbox Exp $ */ /*! \file */ #define DNS_NAME_USEINLINE 1 #include #include #include #include #include #include #include #include #define CCTX_MAGIC ISC_MAGIC('C', 'C', 'T', 'X') #define VALID_CCTX(x) ISC_MAGIC_VALID(x, CCTX_MAGIC) #define DCTX_MAGIC ISC_MAGIC('D', 'C', 'T', 'X') #define VALID_DCTX(x) ISC_MAGIC_VALID(x, DCTX_MAGIC) /*** *** Compression ***/ isc_result_t dns_compress_init(dns_compress_t *cctx, int edns, isc_mem_t *mctx) { unsigned int i; REQUIRE(cctx != NULL); REQUIRE(mctx != NULL); /* See: rdataset.c:towiresorted(). */ cctx->allowed = 0; cctx->edns = edns; for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) cctx->table[i] = NULL; cctx->mctx = mctx; cctx->count = 0; cctx->magic = CCTX_MAGIC; return (ISC_R_SUCCESS); } void dns_compress_invalidate(dns_compress_t *cctx) { dns_compressnode_t *node; unsigned int i; REQUIRE(VALID_CCTX(cctx)); cctx->magic = 0; for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) { while (cctx->table[i] != NULL) { node = cctx->table[i]; cctx->table[i] = cctx->table[i]->next; if (node->count < DNS_COMPRESS_INITIALNODES) continue; isc_mem_put(cctx->mctx, node, sizeof(*node)); } } cctx->allowed = 0; cctx->edns = -1; } void dns_compress_setmethods(dns_compress_t *cctx, unsigned int allowed) { REQUIRE(VALID_CCTX(cctx)); cctx->allowed &= ~DNS_COMPRESS_ALL; cctx->allowed |= (allowed & DNS_COMPRESS_ALL); } unsigned int dns_compress_getmethods(dns_compress_t *cctx) { REQUIRE(VALID_CCTX(cctx)); return (cctx->allowed & DNS_COMPRESS_ALL); } void dns_compress_setsensitive(dns_compress_t *cctx, isc_boolean_t sensitive) { REQUIRE(VALID_CCTX(cctx)); if (sensitive) cctx->allowed |= DNS_COMPRESS_CASESENSITIVE; else cctx->allowed &= ~DNS_COMPRESS_CASESENSITIVE; } isc_boolean_t dns_compress_getsensitive(dns_compress_t *cctx) { REQUIRE(VALID_CCTX(cctx)); return (ISC_TF((cctx->allowed & DNS_COMPRESS_CASESENSITIVE) != 0)); } int dns_compress_getedns(dns_compress_t *cctx) { REQUIRE(VALID_CCTX(cctx)); return (cctx->edns); } #define NODENAME(node, name) \ do { \ (name)->length = (node)->r.length; \ (name)->labels = (node)->labels; \ (name)->ndata = (node)->r.base; \ (name)->attributes = DNS_NAMEATTR_ABSOLUTE; \ } while (0) /* * Find the longest match of name in the table. * If match is found return ISC_TRUE. prefix, suffix and offset are updated. * If no match is found return ISC_FALSE. */ isc_boolean_t dns_compress_findglobal(dns_compress_t *cctx, const dns_name_t *name, dns_name_t *prefix, isc_uint16_t *offset) { dns_name_t tname, nname; dns_compressnode_t *node = NULL; unsigned int labels, hash, n; REQUIRE(VALID_CCTX(cctx)); REQUIRE(dns_name_isabsolute(name) == ISC_TRUE); REQUIRE(offset != NULL); if (cctx->count == 0) return (ISC_FALSE); labels = dns_name_countlabels(name); INSIST(labels > 0); dns_name_init(&tname, NULL); dns_name_init(&nname, NULL); for (n = 0; n < labels - 1; n++) { dns_name_getlabelsequence(name, n, labels - n, &tname); hash = dns_name_hash(&tname, ISC_FALSE) % DNS_COMPRESS_TABLESIZE; for (node = cctx->table[hash]; node != NULL; node = node->next) { NODENAME(node, &nname); if ((cctx->allowed & DNS_COMPRESS_CASESENSITIVE) != 0) { if (dns_name_caseequal(&nname, &tname)) break; } else { if (dns_name_equal(&nname, &tname)) break; } } if (node != NULL) break; } /* * If node == NULL, we found no match at all. */ if (node == NULL) return (ISC_FALSE); if (n == 0) dns_name_reset(prefix); else dns_name_getlabelsequence(name, 0, n, prefix); *offset = node->offset; return (ISC_TRUE); } static inline unsigned int name_length(const dns_name_t *name) { isc_region_t r; dns_name_toregion(name, &r); return (r.length); } void dns_compress_add(dns_compress_t *cctx, const dns_name_t *name, const dns_name_t *prefix, isc_uint16_t offset) { dns_name_t tname; unsigned int start; unsigned int n; unsigned int count; unsigned int hash; dns_compressnode_t *node; unsigned int length; unsigned int tlength; isc_uint16_t toffset; REQUIRE(VALID_CCTX(cctx)); REQUIRE(dns_name_isabsolute(name)); dns_name_init(&tname, NULL); n = dns_name_countlabels(name); count = dns_name_countlabels(prefix); if (dns_name_isabsolute(prefix)) count--; start = 0; length = name_length(name); while (count > 0) { if (offset >= 0x4000) break; dns_name_getlabelsequence(name, start, n, &tname); hash = dns_name_hash(&tname, ISC_FALSE) % DNS_COMPRESS_TABLESIZE; tlength = name_length(&tname); toffset = (isc_uint16_t)(offset + (length - tlength)); /* * Create a new node and add it. */ if (cctx->count < DNS_COMPRESS_INITIALNODES) node = &cctx->initialnodes[cctx->count]; else { node = isc_mem_get(cctx->mctx, sizeof(dns_compressnode_t)); if (node == NULL) return; } node->count = cctx->count++; node->offset = toffset; dns_name_toregion(&tname, &node->r); node->labels = (isc_uint8_t)dns_name_countlabels(&tname); node->next = cctx->table[hash]; cctx->table[hash] = node; start++; n--; count--; } } void dns_compress_rollback(dns_compress_t *cctx, isc_uint16_t offset) { unsigned int i; dns_compressnode_t *node; REQUIRE(VALID_CCTX(cctx)); for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) { node = cctx->table[i]; /* * This relies on nodes with greater offsets being * closer to the beginning of the list, and the * items with the greatest offsets being at the end * of the initialnodes[] array. */ while (node != NULL && node->offset >= offset) { cctx->table[i] = node->next; if (node->count >= DNS_COMPRESS_INITIALNODES) isc_mem_put(cctx->mctx, node, sizeof(*node)); cctx->count--; node = cctx->table[i]; } } } /*** *** Decompression ***/ void dns_decompress_init(dns_decompress_t *dctx, int edns, dns_decompresstype_t type) { REQUIRE(dctx != NULL); REQUIRE(edns >= -1 && edns <= 255); dctx->allowed = DNS_COMPRESS_NONE; dctx->edns = edns; dctx->type = type; dctx->magic = DCTX_MAGIC; } void dns_decompress_invalidate(dns_decompress_t *dctx) { REQUIRE(VALID_DCTX(dctx)); dctx->magic = 0; } void dns_decompress_setmethods(dns_decompress_t *dctx, unsigned int allowed) { REQUIRE(VALID_DCTX(dctx)); switch (dctx->type) { case DNS_DECOMPRESS_ANY: dctx->allowed = DNS_COMPRESS_ALL; break; case DNS_DECOMPRESS_NONE: dctx->allowed = DNS_COMPRESS_NONE; break; case DNS_DECOMPRESS_STRICT: dctx->allowed = allowed; break; } } unsigned int dns_decompress_getmethods(dns_decompress_t *dctx) { REQUIRE(VALID_DCTX(dctx)); return (dctx->allowed); } int dns_decompress_edns(dns_decompress_t *dctx) { REQUIRE(VALID_DCTX(dctx)); return (dctx->edns); } dns_decompresstype_t dns_decompress_type(dns_decompress_t *dctx) { REQUIRE(VALID_DCTX(dctx)); return (dctx->type); } bind9-9.10.3.dfsg.P4/lib/dns/portlist.c0000644000470500017500000001532612664710322016756 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: portlist.c,v 1.13 2007/06/19 23:47:16 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define DNS_PORTLIST_MAGIC ISC_MAGIC('P','L','S','T') #define DNS_VALID_PORTLIST(p) ISC_MAGIC_VALID(p, DNS_PORTLIST_MAGIC) typedef struct dns_element { in_port_t port; isc_uint16_t flags; } dns_element_t; struct dns_portlist { unsigned int magic; isc_mem_t *mctx; isc_refcount_t refcount; isc_mutex_t lock; dns_element_t *list; unsigned int allocated; unsigned int active; }; #define DNS_PL_INET 0x0001 #define DNS_PL_INET6 0x0002 #define DNS_PL_ALLOCATE 16 static int compare(const void *arg1, const void *arg2) { const dns_element_t *e1 = (const dns_element_t *)arg1; const dns_element_t *e2 = (const dns_element_t *)arg2; if (e1->port < e2->port) return (-1); if (e1->port > e2->port) return (1); return (0); } isc_result_t dns_portlist_create(isc_mem_t *mctx, dns_portlist_t **portlistp) { dns_portlist_t *portlist; isc_result_t result; REQUIRE(portlistp != NULL && *portlistp == NULL); portlist = isc_mem_get(mctx, sizeof(*portlist)); if (portlist == NULL) return (ISC_R_NOMEMORY); result = isc_mutex_init(&portlist->lock); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, portlist, sizeof(*portlist)); return (result); } result = isc_refcount_init(&portlist->refcount, 1); if (result != ISC_R_SUCCESS) { DESTROYLOCK(&portlist->lock); isc_mem_put(mctx, portlist, sizeof(*portlist)); return (result); } portlist->list = NULL; portlist->allocated = 0; portlist->active = 0; portlist->mctx = NULL; isc_mem_attach(mctx, &portlist->mctx); portlist->magic = DNS_PORTLIST_MAGIC; *portlistp = portlist; return (ISC_R_SUCCESS); } static dns_element_t * find_port(dns_element_t *list, unsigned int len, in_port_t port) { unsigned int xtry = len / 2; unsigned int min = 0; unsigned int max = len - 1; unsigned int last = len; for (;;) { if (list[xtry].port == port) return (&list[xtry]); if (port > list[xtry].port) { if (xtry == max) break; min = xtry; xtry = xtry + (max - xtry + 1) / 2; INSIST(xtry <= max); if (xtry == last) break; last = min; } else { if (xtry == min) break; max = xtry; xtry = xtry - (xtry - min + 1) / 2; INSIST(xtry >= min); if (xtry == last) break; last = max; } } return (NULL); } isc_result_t dns_portlist_add(dns_portlist_t *portlist, int af, in_port_t port) { dns_element_t *el; isc_result_t result; REQUIRE(DNS_VALID_PORTLIST(portlist)); REQUIRE(af == AF_INET || af == AF_INET6); LOCK(&portlist->lock); if (portlist->active != 0) { el = find_port(portlist->list, portlist->active, port); if (el != NULL) { if (af == AF_INET) el->flags |= DNS_PL_INET; else el->flags |= DNS_PL_INET6; result = ISC_R_SUCCESS; goto unlock; } } if (portlist->allocated <= portlist->active) { unsigned int allocated; allocated = portlist->allocated + DNS_PL_ALLOCATE; el = isc_mem_get(portlist->mctx, sizeof(*el) * allocated); if (el == NULL) { result = ISC_R_NOMEMORY; goto unlock; } if (portlist->list != NULL) { memmove(el, portlist->list, portlist->allocated * sizeof(*el)); isc_mem_put(portlist->mctx, portlist->list, portlist->allocated * sizeof(*el)); } portlist->list = el; portlist->allocated = allocated; } portlist->list[portlist->active].port = port; if (af == AF_INET) portlist->list[portlist->active].flags = DNS_PL_INET; else portlist->list[portlist->active].flags = DNS_PL_INET6; portlist->active++; qsort(portlist->list, portlist->active, sizeof(*el), compare); result = ISC_R_SUCCESS; unlock: UNLOCK(&portlist->lock); return (result); } void dns_portlist_remove(dns_portlist_t *portlist, int af, in_port_t port) { dns_element_t *el; REQUIRE(DNS_VALID_PORTLIST(portlist)); REQUIRE(af == AF_INET || af == AF_INET6); LOCK(&portlist->lock); if (portlist->active != 0) { el = find_port(portlist->list, portlist->active, port); if (el != NULL) { if (af == AF_INET) el->flags &= ~DNS_PL_INET; else el->flags &= ~DNS_PL_INET6; if (el->flags == 0) { *el = portlist->list[portlist->active]; portlist->active--; qsort(portlist->list, portlist->active, sizeof(*el), compare); } } } UNLOCK(&portlist->lock); } isc_boolean_t dns_portlist_match(dns_portlist_t *portlist, int af, in_port_t port) { dns_element_t *el; isc_boolean_t result = ISC_FALSE; REQUIRE(DNS_VALID_PORTLIST(portlist)); REQUIRE(af == AF_INET || af == AF_INET6); LOCK(&portlist->lock); if (portlist->active != 0) { el = find_port(portlist->list, portlist->active, port); if (el != NULL) { if (af == AF_INET && (el->flags & DNS_PL_INET) != 0) result = ISC_TRUE; if (af == AF_INET6 && (el->flags & DNS_PL_INET6) != 0) result = ISC_TRUE; } } UNLOCK(&portlist->lock); return (result); } void dns_portlist_attach(dns_portlist_t *portlist, dns_portlist_t **portlistp) { REQUIRE(DNS_VALID_PORTLIST(portlist)); REQUIRE(portlistp != NULL && *portlistp == NULL); isc_refcount_increment(&portlist->refcount, NULL); *portlistp = portlist; } void dns_portlist_detach(dns_portlist_t **portlistp) { dns_portlist_t *portlist; unsigned int count; REQUIRE(portlistp != NULL); portlist = *portlistp; REQUIRE(DNS_VALID_PORTLIST(portlist)); *portlistp = NULL; isc_refcount_decrement(&portlist->refcount, &count); if (count == 0) { portlist->magic = 0; isc_refcount_destroy(&portlist->refcount); if (portlist->list != NULL) isc_mem_put(portlist->mctx, portlist->list, portlist->allocated * sizeof(*portlist->list)); DESTROYLOCK(&portlist->lock); isc_mem_putanddetach(&portlist->mctx, portlist, sizeof(*portlist)); } } bind9-9.10.3.dfsg.P4/lib/dns/dst_lib.c0000644000470500017500000000307712664710322016516 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Principal Author: Brian Wellington * $Id: dst_lib.c,v 1.5 2007/06/19 23:47:16 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include /*** *** Globals ***/ LIBDNS_EXTERNAL_DATA isc_msgcat_t * dst_msgcat = NULL; /*** *** Private ***/ static isc_once_t msgcat_once = ISC_ONCE_INIT; /*** *** Functions ***/ static void open_msgcat(void) { isc_msgcat_open("libdst.cat", &dst_msgcat); } void dst_lib_initmsgcat(void) { /* * Initialize the DST library's message catalog, dst_msgcat, if it * has not already been initialized. */ RUNTIME_CHECK(isc_once_do(&msgcat_once, open_msgcat) == ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/dns/lookup.c0000644000470500017500000003163212664710322016405 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lookup.c,v 1.21 2007/06/18 23:47:40 tbox Exp $ */ /*! \file */ #include #include #include #include /* Required for HP/UX (and others?) */ #include #include #include #include #include #include #include #include #include #include #include struct dns_lookup { /* Unlocked. */ unsigned int magic; isc_mem_t * mctx; isc_mutex_t lock; dns_rdatatype_t type; dns_fixedname_t name; /* Locked by lock. */ unsigned int options; isc_task_t * task; dns_view_t * view; dns_lookupevent_t * event; dns_fetch_t * fetch; unsigned int restarts; isc_boolean_t canceled; dns_rdataset_t rdataset; dns_rdataset_t sigrdataset; }; #define LOOKUP_MAGIC ISC_MAGIC('l', 'o', 'o', 'k') #define VALID_LOOKUP(l) ISC_MAGIC_VALID((l), LOOKUP_MAGIC) #define MAX_RESTARTS 16 static void lookup_find(dns_lookup_t *lookup, dns_fetchevent_t *event); static void fetch_done(isc_task_t *task, isc_event_t *event) { dns_lookup_t *lookup = event->ev_arg; dns_fetchevent_t *fevent; UNUSED(task); REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); REQUIRE(VALID_LOOKUP(lookup)); REQUIRE(lookup->task == task); fevent = (dns_fetchevent_t *)event; REQUIRE(fevent->fetch == lookup->fetch); lookup_find(lookup, fevent); } static inline isc_result_t start_fetch(dns_lookup_t *lookup) { isc_result_t result; /* * The caller must be holding the lookup's lock. */ REQUIRE(lookup->fetch == NULL); result = dns_resolver_createfetch(lookup->view->resolver, dns_fixedname_name(&lookup->name), lookup->type, NULL, NULL, NULL, 0, lookup->task, fetch_done, lookup, &lookup->rdataset, &lookup->sigrdataset, &lookup->fetch); return (result); } static isc_result_t build_event(dns_lookup_t *lookup) { dns_name_t *name = NULL; dns_rdataset_t *rdataset = NULL; dns_rdataset_t *sigrdataset = NULL; isc_result_t result; name = isc_mem_get(lookup->mctx, sizeof(dns_name_t)); if (name == NULL) { result = ISC_R_NOMEMORY; goto fail; } dns_name_init(name, NULL); result = dns_name_dup(dns_fixedname_name(&lookup->name), lookup->mctx, name); if (result != ISC_R_SUCCESS) goto fail; if (dns_rdataset_isassociated(&lookup->rdataset)) { rdataset = isc_mem_get(lookup->mctx, sizeof(dns_rdataset_t)); if (rdataset == NULL) { result = ISC_R_NOMEMORY; goto fail; } dns_rdataset_init(rdataset); dns_rdataset_clone(&lookup->rdataset, rdataset); } if (dns_rdataset_isassociated(&lookup->sigrdataset)) { sigrdataset = isc_mem_get(lookup->mctx, sizeof(dns_rdataset_t)); if (sigrdataset == NULL) { result = ISC_R_NOMEMORY; goto fail; } dns_rdataset_init(sigrdataset); dns_rdataset_clone(&lookup->sigrdataset, sigrdataset); } lookup->event->name = name; lookup->event->rdataset = rdataset; lookup->event->sigrdataset = sigrdataset; return (ISC_R_SUCCESS); fail: if (name != NULL) { if (dns_name_dynamic(name)) dns_name_free(name, lookup->mctx); isc_mem_put(lookup->mctx, name, sizeof(dns_name_t)); } if (rdataset != NULL) { if (dns_rdataset_isassociated(rdataset)) dns_rdataset_disassociate(rdataset); isc_mem_put(lookup->mctx, rdataset, sizeof(dns_rdataset_t)); } return (result); } static isc_result_t view_find(dns_lookup_t *lookup, dns_name_t *foundname) { isc_result_t result; dns_name_t *name = dns_fixedname_name(&lookup->name); dns_rdatatype_t type; if (lookup->type == dns_rdatatype_rrsig) type = dns_rdatatype_any; else type = lookup->type; result = dns_view_find(lookup->view, name, type, 0, 0, ISC_FALSE, &lookup->event->db, &lookup->event->node, foundname, &lookup->rdataset, &lookup->sigrdataset); return (result); } static void lookup_find(dns_lookup_t *lookup, dns_fetchevent_t *event) { isc_result_t result; isc_boolean_t want_restart; isc_boolean_t send_event; dns_name_t *name, *fname, *prefix; dns_fixedname_t foundname, fixed; dns_rdata_t rdata = DNS_RDATA_INIT; unsigned int nlabels; int order; dns_namereln_t namereln; dns_rdata_cname_t cname; dns_rdata_dname_t dname; REQUIRE(VALID_LOOKUP(lookup)); LOCK(&lookup->lock); result = ISC_R_SUCCESS; name = dns_fixedname_name(&lookup->name); do { lookup->restarts++; want_restart = ISC_FALSE; send_event = ISC_TRUE; if (event == NULL && !lookup->canceled) { dns_fixedname_init(&foundname); fname = dns_fixedname_name(&foundname); INSIST(!dns_rdataset_isassociated(&lookup->rdataset)); INSIST(!dns_rdataset_isassociated (&lookup->sigrdataset)); /* * If we have restarted then clear the old node. */ if (lookup->event->node != NULL) { INSIST(lookup->event->db != NULL); dns_db_detachnode(lookup->event->db, &lookup->event->node); } if (lookup->event->db != NULL) dns_db_detach(&lookup->event->db); result = view_find(lookup, fname); if (result == ISC_R_NOTFOUND) { /* * We don't know anything about the name. * Launch a fetch. */ if (lookup->event->node != NULL) { INSIST(lookup->event->db != NULL); dns_db_detachnode(lookup->event->db, &lookup->event->node); } if (lookup->event->db != NULL) dns_db_detach(&lookup->event->db); result = start_fetch(lookup); if (result == ISC_R_SUCCESS) send_event = ISC_FALSE; goto done; } } else if (event != NULL) { result = event->result; fname = dns_fixedname_name(&event->foundname); dns_resolver_destroyfetch(&lookup->fetch); INSIST(event->rdataset == &lookup->rdataset); INSIST(event->sigrdataset == &lookup->sigrdataset); } else fname = NULL; /* Silence compiler warning. */ /* * If we've been canceled, forget about the result. */ if (lookup->canceled) result = ISC_R_CANCELED; switch (result) { case ISC_R_SUCCESS: result = build_event(lookup); if (event == NULL) break; if (event->db != NULL) dns_db_attach(event->db, &lookup->event->db); if (event->node != NULL) dns_db_attachnode(lookup->event->db, event->node, &lookup->event->node); break; case DNS_R_CNAME: /* * Copy the CNAME's target into the lookup's * query name and start over. */ result = dns_rdataset_first(&lookup->rdataset); if (result != ISC_R_SUCCESS) break; dns_rdataset_current(&lookup->rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &cname, NULL); dns_rdata_reset(&rdata); if (result != ISC_R_SUCCESS) break; result = dns_name_copy(&cname.cname, name, NULL); dns_rdata_freestruct(&cname); if (result == ISC_R_SUCCESS) { want_restart = ISC_TRUE; send_event = ISC_FALSE; } break; case DNS_R_DNAME: namereln = dns_name_fullcompare(name, fname, &order, &nlabels); INSIST(namereln == dns_namereln_subdomain); /* * Get the target name of the DNAME. */ result = dns_rdataset_first(&lookup->rdataset); if (result != ISC_R_SUCCESS) break; dns_rdataset_current(&lookup->rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &dname, NULL); dns_rdata_reset(&rdata); if (result != ISC_R_SUCCESS) break; /* * Construct the new query name and start over. */ dns_fixedname_init(&fixed); prefix = dns_fixedname_name(&fixed); dns_name_split(name, nlabels, prefix, NULL); result = dns_name_concatenate(prefix, &dname.dname, name, NULL); dns_rdata_freestruct(&dname); if (result == ISC_R_SUCCESS) { want_restart = ISC_TRUE; send_event = ISC_FALSE; } break; default: send_event = ISC_TRUE; } if (dns_rdataset_isassociated(&lookup->rdataset)) dns_rdataset_disassociate(&lookup->rdataset); if (dns_rdataset_isassociated(&lookup->sigrdataset)) dns_rdataset_disassociate(&lookup->sigrdataset); done: if (event != NULL) { if (event->node != NULL) dns_db_detachnode(event->db, &event->node); if (event->db != NULL) dns_db_detach(&event->db); isc_event_free(ISC_EVENT_PTR(&event)); } /* * Limit the number of restarts. */ if (want_restart && lookup->restarts == MAX_RESTARTS) { want_restart = ISC_FALSE; result = ISC_R_QUOTA; send_event = ISC_TRUE; } } while (want_restart); if (send_event) { lookup->event->result = result; lookup->event->ev_sender = lookup; isc_task_sendanddetach(&lookup->task, (isc_event_t **)&lookup->event); dns_view_detach(&lookup->view); } UNLOCK(&lookup->lock); } static void levent_destroy(isc_event_t *event) { dns_lookupevent_t *levent; isc_mem_t *mctx; REQUIRE(event->ev_type == DNS_EVENT_LOOKUPDONE); mctx = event->ev_destroy_arg; levent = (dns_lookupevent_t *)event; if (levent->name != NULL) { if (dns_name_dynamic(levent->name)) dns_name_free(levent->name, mctx); isc_mem_put(mctx, levent->name, sizeof(dns_name_t)); } if (levent->rdataset != NULL) { dns_rdataset_disassociate(levent->rdataset); isc_mem_put(mctx, levent->rdataset, sizeof(dns_rdataset_t)); } if (levent->sigrdataset != NULL) { dns_rdataset_disassociate(levent->sigrdataset); isc_mem_put(mctx, levent->sigrdataset, sizeof(dns_rdataset_t)); } if (levent->node != NULL) dns_db_detachnode(levent->db, &levent->node); if (levent->db != NULL) dns_db_detach(&levent->db); isc_mem_put(mctx, event, event->ev_size); } isc_result_t dns_lookup_create(isc_mem_t *mctx, dns_name_t *name, dns_rdatatype_t type, dns_view_t *view, unsigned int options, isc_task_t *task, isc_taskaction_t action, void *arg, dns_lookup_t **lookupp) { isc_result_t result; dns_lookup_t *lookup; isc_event_t *ievent; lookup = isc_mem_get(mctx, sizeof(*lookup)); if (lookup == NULL) return (ISC_R_NOMEMORY); lookup->mctx = NULL; isc_mem_attach(mctx, &lookup->mctx); lookup->options = options; ievent = isc_event_allocate(mctx, lookup, DNS_EVENT_LOOKUPDONE, action, arg, sizeof(*lookup->event)); if (ievent == NULL) { result = ISC_R_NOMEMORY; goto cleanup_lookup; } lookup->event = (dns_lookupevent_t *)ievent; lookup->event->ev_destroy = levent_destroy; lookup->event->ev_destroy_arg = mctx; lookup->event->result = ISC_R_FAILURE; lookup->event->name = NULL; lookup->event->rdataset = NULL; lookup->event->sigrdataset = NULL; lookup->event->db = NULL; lookup->event->node = NULL; lookup->task = NULL; isc_task_attach(task, &lookup->task); result = isc_mutex_init(&lookup->lock); if (result != ISC_R_SUCCESS) goto cleanup_event; dns_fixedname_init(&lookup->name); result = dns_name_copy(name, dns_fixedname_name(&lookup->name), NULL); if (result != ISC_R_SUCCESS) goto cleanup_lock; lookup->type = type; lookup->view = NULL; dns_view_attach(view, &lookup->view); lookup->fetch = NULL; lookup->restarts = 0; lookup->canceled = ISC_FALSE; dns_rdataset_init(&lookup->rdataset); dns_rdataset_init(&lookup->sigrdataset); lookup->magic = LOOKUP_MAGIC; *lookupp = lookup; lookup_find(lookup, NULL); return (ISC_R_SUCCESS); cleanup_lock: DESTROYLOCK(&lookup->lock); cleanup_event: ievent = (isc_event_t *)lookup->event; isc_event_free(&ievent); lookup->event = NULL; isc_task_detach(&lookup->task); cleanup_lookup: isc_mem_putanddetach(&mctx, lookup, sizeof(*lookup)); return (result); } void dns_lookup_cancel(dns_lookup_t *lookup) { REQUIRE(VALID_LOOKUP(lookup)); LOCK(&lookup->lock); if (!lookup->canceled) { lookup->canceled = ISC_TRUE; if (lookup->fetch != NULL) { INSIST(lookup->view != NULL); dns_resolver_cancelfetch(lookup->fetch); } } UNLOCK(&lookup->lock); } void dns_lookup_destroy(dns_lookup_t **lookupp) { dns_lookup_t *lookup; REQUIRE(lookupp != NULL); lookup = *lookupp; REQUIRE(VALID_LOOKUP(lookup)); REQUIRE(lookup->event == NULL); REQUIRE(lookup->task == NULL); REQUIRE(lookup->view == NULL); if (dns_rdataset_isassociated(&lookup->rdataset)) dns_rdataset_disassociate(&lookup->rdataset); if (dns_rdataset_isassociated(&lookup->sigrdataset)) dns_rdataset_disassociate(&lookup->sigrdataset); DESTROYLOCK(&lookup->lock); lookup->magic = 0; isc_mem_putanddetach(&lookup->mctx, lookup, sizeof(*lookup)); *lookupp = NULL; } bind9-9.10.3.dfsg.P4/lib/dns/dns64.c0000644000470500017500000001754312664710322016037 0ustar lamontlamont/* * Copyright (C) 2010, 2011, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: dns64.c,v 1.8 2011/03/12 04:59:47 tbox Exp $ */ #include #include #include #include #include #include #include #include #include #include #include struct dns_dns64 { unsigned char bits[16]; /* * Prefix + suffix bits. */ dns_acl_t * clients; /* * Which clients get mapped * addresses. */ dns_acl_t * mapped; /* * IPv4 addresses to be mapped. */ dns_acl_t * excluded; /* * IPv6 addresses that are * treated as not existing. */ unsigned int prefixlen; /* * Start of mapped address. */ unsigned int flags; isc_mem_t * mctx; ISC_LINK(dns_dns64_t) link; }; isc_result_t dns_dns64_create(isc_mem_t *mctx, isc_netaddr_t *prefix, unsigned int prefixlen, isc_netaddr_t *suffix, dns_acl_t *clients, dns_acl_t *mapped, dns_acl_t *excluded, unsigned int flags, dns_dns64_t **dns64) { dns_dns64_t *new; unsigned int nbytes = 16; REQUIRE(prefix != NULL && prefix->family == AF_INET6); /* Legal prefix lengths from rfc6052.txt. */ REQUIRE(prefixlen == 32 || prefixlen == 40 || prefixlen == 48 || prefixlen == 56 || prefixlen == 64 || prefixlen == 96); REQUIRE(isc_netaddr_prefixok(prefix, prefixlen) == ISC_R_SUCCESS); REQUIRE(dns64 != NULL && *dns64 == NULL); if (suffix != NULL) { static const unsigned char zeros[16]; REQUIRE(prefix->family == AF_INET6); nbytes = prefixlen / 8 + 4; /* Bits 64-71 are zeros. rfc6052.txt */ if (prefixlen >= 32 && prefixlen <= 64) nbytes++; REQUIRE(memcmp(suffix->type.in6.s6_addr, zeros, nbytes) == 0); } new = isc_mem_get(mctx, sizeof(dns_dns64_t)); if (new == NULL) return (ISC_R_NOMEMORY); memset(new->bits, 0, sizeof(new->bits)); memmove(new->bits, prefix->type.in6.s6_addr, prefixlen / 8); if (suffix != NULL) memmove(new->bits + nbytes, suffix->type.in6.s6_addr + nbytes, 16 - nbytes); new->clients = NULL; if (clients != NULL) dns_acl_attach(clients, &new->clients); new->mapped = NULL; if (mapped != NULL) dns_acl_attach(mapped, &new->mapped); new->excluded = NULL; if (excluded != NULL) dns_acl_attach(excluded, &new->excluded); new->prefixlen = prefixlen; new->flags = flags; ISC_LINK_INIT(new, link); new->mctx = NULL; isc_mem_attach(mctx, &new->mctx); *dns64 = new; return (ISC_R_SUCCESS); } void dns_dns64_destroy(dns_dns64_t **dns64p) { dns_dns64_t *dns64; REQUIRE(dns64p != NULL && *dns64p != NULL); dns64 = *dns64p; *dns64p = NULL; REQUIRE(!ISC_LINK_LINKED(dns64, link)); if (dns64->clients != NULL) dns_acl_detach(&dns64->clients); if (dns64->mapped != NULL) dns_acl_detach(&dns64->mapped); if (dns64->excluded != NULL) dns_acl_detach(&dns64->excluded); isc_mem_putanddetach(&dns64->mctx, dns64, sizeof(*dns64)); } isc_result_t dns_dns64_aaaafroma(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr, const dns_name_t *reqsigner, const dns_aclenv_t *env, unsigned int flags, unsigned char *a, unsigned char *aaaa) { unsigned int nbytes, i; isc_result_t result; int match; if ((dns64->flags & DNS_DNS64_RECURSIVE_ONLY) != 0 && (flags & DNS_DNS64_RECURSIVE) == 0) return (DNS_R_DISALLOWED); if ((dns64->flags & DNS_DNS64_BREAK_DNSSEC) == 0 && (flags & DNS_DNS64_DNSSEC) != 0) return (DNS_R_DISALLOWED); if (dns64->clients != NULL) { result = dns_acl_match(reqaddr, reqsigner, dns64->clients, env, &match, NULL); if (result != ISC_R_SUCCESS) return (result); if (match <= 0) return (DNS_R_DISALLOWED); } if (dns64->mapped != NULL) { struct in_addr ina; isc_netaddr_t netaddr; memmove(&ina.s_addr, a, 4); isc_netaddr_fromin(&netaddr, &ina); result = dns_acl_match(&netaddr, NULL, dns64->mapped, env, &match, NULL); if (result != ISC_R_SUCCESS) return (result); if (match <= 0) return (DNS_R_DISALLOWED); } nbytes = dns64->prefixlen / 8; INSIST(nbytes <= 12); /* Copy prefix. */ memmove(aaaa, dns64->bits, nbytes); /* Bits 64-71 are zeros. rfc6052.txt */ if (nbytes == 8) aaaa[nbytes++] = 0; /* Copy mapped address. */ for (i = 0; i < 4U; i++) { aaaa[nbytes++] = a[i]; /* Bits 64-71 are zeros. rfc6052.txt */ if (nbytes == 8) aaaa[nbytes++] = 0; } /* Copy suffix. */ memmove(aaaa + nbytes, dns64->bits + nbytes, 16 - nbytes); return (ISC_R_SUCCESS); } dns_dns64_t * dns_dns64_next(dns_dns64_t *dns64) { dns64 = ISC_LIST_NEXT(dns64, link); return (dns64); } void dns_dns64_append(dns_dns64list_t *list, dns_dns64_t *dns64) { ISC_LIST_APPEND(*list, dns64, link); } void dns_dns64_unlink(dns_dns64list_t *list, dns_dns64_t *dns64) { ISC_LIST_UNLINK(*list, dns64, link); } isc_boolean_t dns_dns64_aaaaok(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr, const dns_name_t *reqsigner, const dns_aclenv_t *env, unsigned int flags, dns_rdataset_t *rdataset, isc_boolean_t *aaaaok, size_t aaaaoklen) { struct in6_addr in6; isc_netaddr_t netaddr; isc_result_t result; int match; isc_boolean_t answer = ISC_FALSE; isc_boolean_t found = ISC_FALSE; unsigned int i, ok; REQUIRE(rdataset != NULL); REQUIRE(rdataset->type == dns_rdatatype_aaaa); REQUIRE(rdataset->rdclass == dns_rdataclass_in); if (aaaaok != NULL) REQUIRE(aaaaoklen == dns_rdataset_count(rdataset)); for (;dns64 != NULL; dns64 = ISC_LIST_NEXT(dns64, link)) { if ((dns64->flags & DNS_DNS64_RECURSIVE_ONLY) != 0 && (flags & DNS_DNS64_RECURSIVE) == 0) continue; if ((dns64->flags & DNS_DNS64_BREAK_DNSSEC) == 0 && (flags & DNS_DNS64_DNSSEC) != 0) continue; /* * Work out if this dns64 structure applies to this client. */ if (dns64->clients != NULL) { result = dns_acl_match(reqaddr, reqsigner, dns64->clients, env, &match, NULL); if (result != ISC_R_SUCCESS) continue; if (match <= 0) continue; } if (!found && aaaaok != NULL) { for (i = 0; i < aaaaoklen; i++) aaaaok[i] = ISC_FALSE; } found = ISC_TRUE; /* * If we are not excluding any addresses then any AAAA * will do. */ if (dns64->excluded == NULL) { answer = ISC_TRUE; if (aaaaok == NULL) goto done; for (i = 0; i < aaaaoklen; i++) aaaaok[i] = ISC_TRUE; goto done; } i = 0; ok = 0; for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; if (aaaaok == NULL || !aaaaok[i]) { dns_rdataset_current(rdataset, &rdata); memmove(&in6.s6_addr, rdata.data, 16); isc_netaddr_fromin6(&netaddr, &in6); result = dns_acl_match(&netaddr, NULL, dns64->excluded, env, &match, NULL); if (result == ISC_R_SUCCESS && match <= 0) { answer = ISC_TRUE; if (aaaaok == NULL) goto done; aaaaok[i] = ISC_TRUE; ok++; } } else ok++; i++; } /* * Are all addresses ok? */ if (aaaaok != NULL && ok == aaaaoklen) goto done; } done: if (!found && aaaaok != NULL) { for (i = 0; i < aaaaoklen; i++) aaaaok[i] = ISC_TRUE; } return (found ? answer : ISC_TRUE); } bind9-9.10.3.dfsg.P4/lib/dns/dispatch.c0000644000470500017500000030174712664710322016702 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: dispatch.c,v 1.175 2011/11/29 01:03:47 marka Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include typedef ISC_LIST(dns_dispentry_t) dns_displist_t; typedef struct dispsocket dispsocket_t; typedef ISC_LIST(dispsocket_t) dispsocketlist_t; typedef struct dispportentry dispportentry_t; typedef ISC_LIST(dispportentry_t) dispportlist_t; /* ARC4 Random generator state */ typedef struct arc4ctx { isc_uint8_t i; isc_uint8_t j; isc_uint8_t s[256]; int count; isc_entropy_t *entropy; /*%< entropy source for ARC4 */ isc_mutex_t *lock; } arc4ctx_t; typedef struct dns_qid { unsigned int magic; unsigned int qid_nbuckets; /*%< hash table size */ unsigned int qid_increment; /*%< id increment on collision */ isc_mutex_t lock; dns_displist_t *qid_table; /*%< the table itself */ dispsocketlist_t *sock_table; /*%< socket table */ } dns_qid_t; struct dns_dispatchmgr { /* Unlocked. */ unsigned int magic; isc_mem_t *mctx; dns_acl_t *blackhole; dns_portlist_t *portlist; isc_stats_t *stats; isc_entropy_t *entropy; /*%< entropy source */ /* Locked by "lock". */ isc_mutex_t lock; unsigned int state; ISC_LIST(dns_dispatch_t) list; /* Locked by arc4_lock. */ isc_mutex_t arc4_lock; arc4ctx_t arc4ctx; /*%< ARC4 context for QID */ /* locked by buffer lock */ dns_qid_t *qid; isc_mutex_t buffer_lock; unsigned int buffers; /*%< allocated buffers */ unsigned int buffersize; /*%< size of each buffer */ unsigned int maxbuffers; /*%< max buffers */ /* Locked internally. */ isc_mutex_t depool_lock; isc_mempool_t *depool; /*%< pool for dispatch events */ isc_mutex_t rpool_lock; isc_mempool_t *rpool; /*%< pool for replies */ isc_mutex_t dpool_lock; isc_mempool_t *dpool; /*%< dispatch allocations */ isc_mutex_t bpool_lock; isc_mempool_t *bpool; /*%< pool for buffers */ isc_mutex_t spool_lock; isc_mempool_t *spool; /*%< pool for dispsocks */ /*% * Locked by qid->lock if qid exists; otherwise, can be used without * being locked. * Memory footprint considerations: this is a simple implementation of * available ports, i.e., an ordered array of the actual port numbers. * This will require about 256KB of memory in the worst case (128KB for * each of IPv4 and IPv6). We could reduce it by representing it as a * more sophisticated way such as a list (or array) of ranges that are * searched to identify a specific port. Our decision here is the saved * memory isn't worth the implementation complexity, considering the * fact that the whole BIND9 process (which is mainly named) already * requires a pretty large memory footprint. We may, however, have to * revisit the decision when we want to use it as a separate module for * an environment where memory requirement is severer. */ in_port_t *v4ports; /*%< available ports for IPv4 */ unsigned int nv4ports; /*%< # of available ports for IPv4 */ in_port_t *v6ports; /*%< available ports for IPv4 */ unsigned int nv6ports; /*%< # of available ports for IPv4 */ }; #define MGR_SHUTTINGDOWN 0x00000001U #define MGR_IS_SHUTTINGDOWN(l) (((l)->state & MGR_SHUTTINGDOWN) != 0) #define IS_PRIVATE(d) (((d)->attributes & DNS_DISPATCHATTR_PRIVATE) != 0) struct dns_dispentry { unsigned int magic; dns_dispatch_t *disp; dns_messageid_t id; in_port_t port; unsigned int bucket; isc_sockaddr_t host; isc_task_t *task; isc_taskaction_t action; void *arg; isc_boolean_t item_out; dispsocket_t *dispsocket; ISC_LIST(dns_dispatchevent_t) items; ISC_LINK(dns_dispentry_t) link; }; /*% * Maximum number of dispatch sockets that can be pooled for reuse. The * appropriate value may vary, but experiments have shown a busy caching server * may need more than 1000 sockets concurrently opened. The maximum allowable * number of dispatch sockets (per manager) will be set to the double of this * value. */ #ifndef DNS_DISPATCH_POOLSOCKS #define DNS_DISPATCH_POOLSOCKS 2048 #endif /*% * Quota to control the number of dispatch sockets. If a dispatch has more * than the quota of sockets, new queries will purge oldest ones, so that * a massive number of outstanding queries won't prevent subsequent queries * (especially if the older ones take longer time and result in timeout). */ #ifndef DNS_DISPATCH_SOCKSQUOTA #define DNS_DISPATCH_SOCKSQUOTA 3072 #endif struct dispsocket { unsigned int magic; isc_socket_t *socket; dns_dispatch_t *disp; isc_sockaddr_t host; in_port_t localport; /* XXX: should be removed later */ dispportentry_t *portentry; dns_dispentry_t *resp; isc_task_t *task; ISC_LINK(dispsocket_t) link; unsigned int bucket; ISC_LINK(dispsocket_t) blink; }; /*% * A port table entry. We remember every port we first open in a table with a * reference counter so that we can 'reuse' the same port (with different * destination addresses) using the SO_REUSEADDR socket option. */ struct dispportentry { in_port_t port; unsigned int refs; ISC_LINK(struct dispportentry) link; }; #ifndef DNS_DISPATCH_PORTTABLESIZE #define DNS_DISPATCH_PORTTABLESIZE 1024 #endif #define INVALID_BUCKET (0xffffdead) /*% * Number of tasks for each dispatch that use separate sockets for different * transactions. This must be a power of 2 as it will divide 32 bit numbers * to get an uniformly random tasks selection. See get_dispsocket(). */ #define MAX_INTERNAL_TASKS 64 struct dns_dispatch { /* Unlocked. */ unsigned int magic; /*%< magic */ dns_dispatchmgr_t *mgr; /*%< dispatch manager */ int ntasks; /*% * internal task buckets. We use multiple tasks to distribute various * socket events well when using separate dispatch sockets. We use the * 1st task (task[0]) for internal control events. */ isc_task_t *task[MAX_INTERNAL_TASKS]; isc_socket_t *socket; /*%< isc socket attached to */ isc_sockaddr_t local; /*%< local address */ in_port_t localport; /*%< local UDP port */ isc_dscp_t dscp; /*%< "listen-on" DSCP value */ unsigned int maxrequests; /*%< max requests */ isc_event_t *ctlevent; isc_mutex_t sepool_lock; isc_mempool_t *sepool; /*%< pool for socket events */ /*% Locked by mgr->lock. */ ISC_LINK(dns_dispatch_t) link; /* Locked by "lock". */ isc_mutex_t lock; /*%< locks all below */ isc_sockettype_t socktype; unsigned int attributes; unsigned int refcount; /*%< number of users */ dns_dispatchevent_t *failsafe_ev; /*%< failsafe cancel event */ unsigned int shutting_down : 1, shutdown_out : 1, connected : 1, tcpmsg_valid : 1, recv_pending : 1; /*%< is a recv() pending? */ isc_result_t shutdown_why; ISC_LIST(dispsocket_t) activesockets; ISC_LIST(dispsocket_t) inactivesockets; unsigned int nsockets; unsigned int requests; /*%< how many requests we have */ unsigned int tcpbuffers; /*%< allocated buffers */ dns_tcpmsg_t tcpmsg; /*%< for tcp streams */ dns_qid_t *qid; arc4ctx_t arc4ctx; /*%< for QID/UDP port num */ dispportlist_t *port_table; /*%< hold ports 'owned' by us */ isc_mempool_t *portpool; /*%< port table entries */ }; #define QID_MAGIC ISC_MAGIC('Q', 'i', 'd', ' ') #define VALID_QID(e) ISC_MAGIC_VALID((e), QID_MAGIC) #define RESPONSE_MAGIC ISC_MAGIC('D', 'r', 's', 'p') #define VALID_RESPONSE(e) ISC_MAGIC_VALID((e), RESPONSE_MAGIC) #define DISPSOCK_MAGIC ISC_MAGIC('D', 's', 'o', 'c') #define VALID_DISPSOCK(e) ISC_MAGIC_VALID((e), DISPSOCK_MAGIC) #define DISPATCH_MAGIC ISC_MAGIC('D', 'i', 's', 'p') #define VALID_DISPATCH(e) ISC_MAGIC_VALID((e), DISPATCH_MAGIC) #define DNS_DISPATCHMGR_MAGIC ISC_MAGIC('D', 'M', 'g', 'r') #define VALID_DISPATCHMGR(e) ISC_MAGIC_VALID((e), DNS_DISPATCHMGR_MAGIC) #define DNS_QID(disp) ((disp)->socktype == isc_sockettype_tcp) ? \ (disp)->qid : (disp)->mgr->qid #define DISP_ARC4CTX(disp) ((disp)->socktype == isc_sockettype_udp) ? \ (&(disp)->arc4ctx) : (&(disp)->mgr->arc4ctx) /*% * Locking a query port buffer is a bit tricky. We access the buffer without * locking until qid is created. Technically, there is a possibility of race * between the creation of qid and access to the port buffer; in practice, * however, this should be safe because qid isn't created until the first * dispatch is created and there should be no contending situation until then. */ #define PORTBUFLOCK(mgr) if ((mgr)->qid != NULL) LOCK(&((mgr)->qid->lock)) #define PORTBUFUNLOCK(mgr) if ((mgr)->qid != NULL) UNLOCK((&(mgr)->qid->lock)) /* * Statics. */ static dns_dispentry_t *entry_search(dns_qid_t *, isc_sockaddr_t *, dns_messageid_t, in_port_t, unsigned int); static isc_boolean_t destroy_disp_ok(dns_dispatch_t *); static void destroy_disp(isc_task_t *task, isc_event_t *event); static void destroy_dispsocket(dns_dispatch_t *, dispsocket_t **); static void deactivate_dispsocket(dns_dispatch_t *, dispsocket_t *); static void udp_exrecv(isc_task_t *, isc_event_t *); static void udp_shrecv(isc_task_t *, isc_event_t *); static void udp_recv(isc_event_t *, dns_dispatch_t *, dispsocket_t *); static void tcp_recv(isc_task_t *, isc_event_t *); static isc_result_t startrecv(dns_dispatch_t *, dispsocket_t *); static isc_uint32_t dns_hash(dns_qid_t *, isc_sockaddr_t *, dns_messageid_t, in_port_t); static void free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len); static void *allocate_udp_buffer(dns_dispatch_t *disp); static inline void free_devent(dns_dispatch_t *disp, dns_dispatchevent_t *ev); static inline dns_dispatchevent_t *allocate_devent(dns_dispatch_t *disp); static void do_cancel(dns_dispatch_t *disp); static dns_dispentry_t *linear_first(dns_qid_t *disp); static dns_dispentry_t *linear_next(dns_qid_t *disp, dns_dispentry_t *resp); static void dispatch_free(dns_dispatch_t **dispp); static isc_result_t get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp, isc_socketmgr_t *sockmgr, isc_sockaddr_t *localaddr, isc_socket_t **sockp, isc_socket_t *dup_socket); static isc_result_t dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr, unsigned int maxrequests, unsigned int attributes, dns_dispatch_t **dispp, isc_socket_t *dup_socket); static isc_boolean_t destroy_mgr_ok(dns_dispatchmgr_t *mgr); static void destroy_mgr(dns_dispatchmgr_t **mgrp); static isc_result_t qid_allocate(dns_dispatchmgr_t *mgr, unsigned int buckets, unsigned int increment, dns_qid_t **qidp, isc_boolean_t needaddrtable); static void qid_destroy(isc_mem_t *mctx, dns_qid_t **qidp); static isc_result_t open_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local, unsigned int options, isc_socket_t **sockp, isc_socket_t *dup_socket); static isc_boolean_t portavailable(dns_dispatchmgr_t *mgr, isc_socket_t *sock, isc_sockaddr_t *sockaddrp); #define LVL(x) ISC_LOG_DEBUG(x) static void mgr_log(dns_dispatchmgr_t *mgr, int level, const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4); static void mgr_log(dns_dispatchmgr_t *mgr, int level, const char *fmt, ...) { char msgbuf[2048]; va_list ap; if (! isc_log_wouldlog(dns_lctx, level)) return; va_start(ap, fmt); vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); va_end(ap); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH, DNS_LOGMODULE_DISPATCH, level, "dispatchmgr %p: %s", mgr, msgbuf); } static inline void inc_stats(dns_dispatchmgr_t *mgr, isc_statscounter_t counter) { if (mgr->stats != NULL) isc_stats_increment(mgr->stats, counter); } static inline void dec_stats(dns_dispatchmgr_t *mgr, isc_statscounter_t counter) { if (mgr->stats != NULL) isc_stats_decrement(mgr->stats, counter); } static void dispatch_log(dns_dispatch_t *disp, int level, const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4); static void dispatch_log(dns_dispatch_t *disp, int level, const char *fmt, ...) { char msgbuf[2048]; va_list ap; if (! isc_log_wouldlog(dns_lctx, level)) return; va_start(ap, fmt); vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); va_end(ap); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH, DNS_LOGMODULE_DISPATCH, level, "dispatch %p: %s", disp, msgbuf); } static void request_log(dns_dispatch_t *disp, dns_dispentry_t *resp, int level, const char *fmt, ...) ISC_FORMAT_PRINTF(4, 5); static void request_log(dns_dispatch_t *disp, dns_dispentry_t *resp, int level, const char *fmt, ...) { char msgbuf[2048]; char peerbuf[256]; va_list ap; if (! isc_log_wouldlog(dns_lctx, level)) return; va_start(ap, fmt); vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); va_end(ap); if (VALID_RESPONSE(resp)) { isc_sockaddr_format(&resp->host, peerbuf, sizeof(peerbuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH, DNS_LOGMODULE_DISPATCH, level, "dispatch %p response %p %s: %s", disp, resp, peerbuf, msgbuf); } else { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH, DNS_LOGMODULE_DISPATCH, level, "dispatch %p req/resp %p: %s", disp, resp, msgbuf); } } /*% * ARC4 random number generator derived from OpenBSD. * Only dispatch_random() and dispatch_uniformrandom() are expected * to be called from general dispatch routines; the rest of them are subroutines * for these two. * * The original copyright follows: * Copyright (c) 1996, David Mazieres * Copyright (c) 2008, Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ static void dispatch_initrandom(arc4ctx_t *actx, isc_entropy_t *entropy, isc_mutex_t *lock) { int n; for (n = 0; n < 256; n++) actx->s[n] = n; actx->i = 0; actx->j = 0; actx->count = 0; actx->entropy = entropy; /* don't have to attach */ actx->lock = lock; } static void dispatch_arc4addrandom(arc4ctx_t *actx, unsigned char *dat, int datlen) { int n; isc_uint8_t si; actx->i--; for (n = 0; n < 256; n++) { actx->i = (actx->i + 1); si = actx->s[actx->i]; actx->j = (actx->j + si + dat[n % datlen]); actx->s[actx->i] = actx->s[actx->j]; actx->s[actx->j] = si; } actx->j = actx->i; } static inline isc_uint8_t dispatch_arc4get8(arc4ctx_t *actx) { isc_uint8_t si, sj; actx->i = (actx->i + 1); si = actx->s[actx->i]; actx->j = (actx->j + si); sj = actx->s[actx->j]; actx->s[actx->i] = sj; actx->s[actx->j] = si; return (actx->s[(si + sj) & 0xff]); } static inline isc_uint16_t dispatch_arc4get16(arc4ctx_t *actx) { isc_uint16_t val; val = dispatch_arc4get8(actx) << 8; val |= dispatch_arc4get8(actx); return (val); } static void dispatch_arc4stir(arc4ctx_t *actx) { int i; union { unsigned char rnd[128]; isc_uint32_t rnd32[32]; } rnd; isc_result_t result; if (actx->entropy != NULL) { /* * We accept any quality of random data to avoid blocking. */ result = isc_entropy_getdata(actx->entropy, rnd.rnd, sizeof(rnd), NULL, 0); RUNTIME_CHECK(result == ISC_R_SUCCESS); } else { for (i = 0; i < 32; i++) isc_random_get(&rnd.rnd32[i]); } dispatch_arc4addrandom(actx, rnd.rnd, sizeof(rnd.rnd)); /* * Discard early keystream, as per recommendations in: * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps */ for (i = 0; i < 256; i++) (void)dispatch_arc4get8(actx); /* * Derived from OpenBSD's implementation. The rationale is not clear, * but should be conservative enough in safety, and reasonably large * for efficiency. */ actx->count = 1600000; } static isc_uint16_t dispatch_random(arc4ctx_t *actx) { isc_uint16_t result; if (actx->lock != NULL) LOCK(actx->lock); actx->count -= sizeof(isc_uint16_t); if (actx->count <= 0) dispatch_arc4stir(actx); result = dispatch_arc4get16(actx); if (actx->lock != NULL) UNLOCK(actx->lock); return (result); } static isc_uint16_t dispatch_uniformrandom(arc4ctx_t *actx, isc_uint16_t upper_bound) { isc_uint16_t min, r; if (upper_bound < 2) return (0); /* * Ensure the range of random numbers [min, 0xffff] be a multiple of * upper_bound and contain at least a half of the 16 bit range. */ if (upper_bound > 0x8000) min = 1 + ~upper_bound; /* 0x8000 - upper_bound */ else min = (isc_uint16_t)(0x10000 % (isc_uint32_t)upper_bound); /* * This could theoretically loop forever but each retry has * p > 0.5 (worst case, usually far better) of selecting a * number inside the range we need, so it should rarely need * to re-roll. */ for (;;) { r = dispatch_random(actx); if (r >= min) break; } return (r % upper_bound); } /* * Return a hash of the destination and message id. */ static isc_uint32_t dns_hash(dns_qid_t *qid, isc_sockaddr_t *dest, dns_messageid_t id, in_port_t port) { unsigned int ret; ret = isc_sockaddr_hash(dest, ISC_TRUE); ret ^= (id << 16) | port; ret %= qid->qid_nbuckets; INSIST(ret < qid->qid_nbuckets); return (ret); } /* * Find the first entry in 'qid'. Returns NULL if there are no entries. */ static dns_dispentry_t * linear_first(dns_qid_t *qid) { dns_dispentry_t *ret; unsigned int bucket; bucket = 0; while (bucket < qid->qid_nbuckets) { ret = ISC_LIST_HEAD(qid->qid_table[bucket]); if (ret != NULL) return (ret); bucket++; } return (NULL); } /* * Find the next entry after 'resp' in 'qid'. Return NULL if there are * no more entries. */ static dns_dispentry_t * linear_next(dns_qid_t *qid, dns_dispentry_t *resp) { dns_dispentry_t *ret; unsigned int bucket; ret = ISC_LIST_NEXT(resp, link); if (ret != NULL) return (ret); bucket = resp->bucket; bucket++; while (bucket < qid->qid_nbuckets) { ret = ISC_LIST_HEAD(qid->qid_table[bucket]); if (ret != NULL) return (ret); bucket++; } return (NULL); } /* * The dispatch must be locked. */ static isc_boolean_t destroy_disp_ok(dns_dispatch_t *disp) { if (disp->refcount != 0) return (ISC_FALSE); if (disp->recv_pending != 0) return (ISC_FALSE); if (!ISC_LIST_EMPTY(disp->activesockets)) return (ISC_FALSE); if (disp->shutting_down == 0) return (ISC_FALSE); return (ISC_TRUE); } /* * Called when refcount reaches 0 (and safe to destroy). * * The dispatcher must be locked. * The manager must not be locked. */ static void destroy_disp(isc_task_t *task, isc_event_t *event) { dns_dispatch_t *disp; dns_dispatchmgr_t *mgr; isc_boolean_t killmgr; dispsocket_t *dispsocket; int i; INSIST(event->ev_type == DNS_EVENT_DISPATCHCONTROL); UNUSED(task); disp = event->ev_arg; mgr = disp->mgr; LOCK(&mgr->lock); ISC_LIST_UNLINK(mgr->list, disp, link); dispatch_log(disp, LVL(90), "shutting down; detaching from sock %p, task %p", disp->socket, disp->task[0]); /* XXXX */ if (disp->sepool != NULL) { isc_mempool_destroy(&disp->sepool); (void)isc_mutex_destroy(&disp->sepool_lock); } if (disp->socket != NULL) isc_socket_detach(&disp->socket); while ((dispsocket = ISC_LIST_HEAD(disp->inactivesockets)) != NULL) { ISC_LIST_UNLINK(disp->inactivesockets, dispsocket, link); destroy_dispsocket(disp, &dispsocket); } for (i = 0; i < disp->ntasks; i++) isc_task_detach(&disp->task[i]); isc_event_free(&event); dispatch_free(&disp); killmgr = destroy_mgr_ok(mgr); UNLOCK(&mgr->lock); if (killmgr) destroy_mgr(&mgr); } /*% * Manipulate port table per dispatch: find an entry for a given port number, * create a new entry, and decrement a given entry with possible clean-up. */ static dispportentry_t * port_search(dns_dispatch_t *disp, in_port_t port) { dispportentry_t *portentry; REQUIRE(disp->port_table != NULL); portentry = ISC_LIST_HEAD(disp->port_table[port % DNS_DISPATCH_PORTTABLESIZE]); while (portentry != NULL) { if (portentry->port == port) return (portentry); portentry = ISC_LIST_NEXT(portentry, link); } return (NULL); } static dispportentry_t * new_portentry(dns_dispatch_t *disp, in_port_t port) { dispportentry_t *portentry; dns_qid_t *qid; REQUIRE(disp->port_table != NULL); portentry = isc_mempool_get(disp->portpool); if (portentry == NULL) return (portentry); portentry->port = port; portentry->refs = 1; ISC_LINK_INIT(portentry, link); qid = DNS_QID(disp); LOCK(&qid->lock); ISC_LIST_APPEND(disp->port_table[port % DNS_DISPATCH_PORTTABLESIZE], portentry, link); UNLOCK(&qid->lock); return (portentry); } /*% * The caller must not hold the qid->lock. */ static void deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) { dispportentry_t *portentry = *portentryp; dns_qid_t *qid; REQUIRE(disp->port_table != NULL); REQUIRE(portentry != NULL && portentry->refs > 0); qid = DNS_QID(disp); LOCK(&qid->lock); portentry->refs--; if (portentry->refs == 0) { ISC_LIST_UNLINK(disp->port_table[portentry->port % DNS_DISPATCH_PORTTABLESIZE], portentry, link); isc_mempool_put(disp->portpool, portentry); } /* * Set '*portentryp' to NULL inside the lock so that * dispsock->portentry does not change in socket_search. */ *portentryp = NULL; UNLOCK(&qid->lock); } /*% * Find a dispsocket for socket address 'dest', and port number 'port'. * Return NULL if no such entry exists. Requires qid->lock to be held. */ static dispsocket_t * socket_search(dns_qid_t *qid, isc_sockaddr_t *dest, in_port_t port, unsigned int bucket) { dispsocket_t *dispsock; REQUIRE(VALID_QID(qid)); REQUIRE(bucket < qid->qid_nbuckets); dispsock = ISC_LIST_HEAD(qid->sock_table[bucket]); while (dispsock != NULL) { if (dispsock->portentry != NULL && dispsock->portentry->port == port && isc_sockaddr_equal(dest, &dispsock->host)) return (dispsock); dispsock = ISC_LIST_NEXT(dispsock, blink); } return (NULL); } /*% * Make a new socket for a single dispatch with a random port number. * The caller must hold the disp->lock */ static isc_result_t get_dispsocket(dns_dispatch_t *disp, isc_sockaddr_t *dest, isc_socketmgr_t *sockmgr, dispsocket_t **dispsockp, in_port_t *portp) { int i; isc_uint32_t r; dns_dispatchmgr_t *mgr = disp->mgr; isc_socket_t *sock = NULL; isc_result_t result = ISC_R_FAILURE; in_port_t port; isc_sockaddr_t localaddr; unsigned int bucket = 0; dispsocket_t *dispsock; unsigned int nports; in_port_t *ports; unsigned int bindoptions; dispportentry_t *portentry = NULL; dns_qid_t *qid; if (isc_sockaddr_pf(&disp->local) == AF_INET) { nports = disp->mgr->nv4ports; ports = disp->mgr->v4ports; } else { nports = disp->mgr->nv6ports; ports = disp->mgr->v6ports; } if (nports == 0) return (ISC_R_ADDRNOTAVAIL); dispsock = ISC_LIST_HEAD(disp->inactivesockets); if (dispsock != NULL) { ISC_LIST_UNLINK(disp->inactivesockets, dispsock, link); sock = dispsock->socket; dispsock->socket = NULL; } else { dispsock = isc_mempool_get(mgr->spool); if (dispsock == NULL) return (ISC_R_NOMEMORY); disp->nsockets++; dispsock->socket = NULL; dispsock->disp = disp; dispsock->resp = NULL; dispsock->portentry = NULL; isc_random_get(&r); dispsock->task = NULL; isc_task_attach(disp->task[r % disp->ntasks], &dispsock->task); ISC_LINK_INIT(dispsock, link); ISC_LINK_INIT(dispsock, blink); dispsock->magic = DISPSOCK_MAGIC; } /* * Pick up a random UDP port and open a new socket with it. Avoid * choosing ports that share the same destination because it will be * very likely to fail in bind(2) or connect(2). */ localaddr = disp->local; qid = DNS_QID(disp); for (i = 0; i < 64; i++) { port = ports[dispatch_uniformrandom(DISP_ARC4CTX(disp), nports)]; isc_sockaddr_setport(&localaddr, port); LOCK(&qid->lock); bucket = dns_hash(qid, dest, 0, port); if (socket_search(qid, dest, port, bucket) != NULL) { UNLOCK(&qid->lock); continue; } UNLOCK(&qid->lock); bindoptions = 0; portentry = port_search(disp, port); if (portentry != NULL) bindoptions |= ISC_SOCKET_REUSEADDRESS; result = open_socket(sockmgr, &localaddr, bindoptions, &sock, NULL); if (result == ISC_R_SUCCESS) { if (portentry == NULL) { portentry = new_portentry(disp, port); if (portentry == NULL) { result = ISC_R_NOMEMORY; break; } } else { LOCK(&qid->lock); portentry->refs++; UNLOCK(&qid->lock); } break; } else if (result == ISC_R_NOPERM) { char buf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(&localaddr, buf, sizeof(buf)); dispatch_log(disp, ISC_LOG_WARNING, "open_socket(%s) -> %s: continuing", buf, isc_result_totext(result)); } else if (result != ISC_R_ADDRINUSE) break; } if (result == ISC_R_SUCCESS) { dispsock->socket = sock; dispsock->host = *dest; dispsock->portentry = portentry; dispsock->bucket = bucket; LOCK(&qid->lock); ISC_LIST_APPEND(qid->sock_table[bucket], dispsock, blink); UNLOCK(&qid->lock); *dispsockp = dispsock; *portp = port; } else { /* * We could keep it in the inactive list, but since this should * be an exceptional case and might be resource shortage, we'd * rather destroy it. */ if (sock != NULL) isc_socket_detach(&sock); destroy_dispsocket(disp, &dispsock); } return (result); } /*% * Destroy a dedicated dispatch socket. */ static void destroy_dispsocket(dns_dispatch_t *disp, dispsocket_t **dispsockp) { dispsocket_t *dispsock; dns_qid_t *qid; /* * The dispatch must be locked. */ REQUIRE(dispsockp != NULL && *dispsockp != NULL); dispsock = *dispsockp; REQUIRE(!ISC_LINK_LINKED(dispsock, link)); disp->nsockets--; dispsock->magic = 0; if (dispsock->portentry != NULL) deref_portentry(disp, &dispsock->portentry); if (dispsock->socket != NULL) isc_socket_detach(&dispsock->socket); if (ISC_LINK_LINKED(dispsock, blink)) { qid = DNS_QID(disp); LOCK(&qid->lock); ISC_LIST_UNLINK(qid->sock_table[dispsock->bucket], dispsock, blink); UNLOCK(&qid->lock); } if (dispsock->task != NULL) isc_task_detach(&dispsock->task); isc_mempool_put(disp->mgr->spool, dispsock); *dispsockp = NULL; } /*% * Deactivate a dedicated dispatch socket. Move it to the inactive list for * future reuse unless the total number of sockets are exceeding the maximum. */ static void deactivate_dispsocket(dns_dispatch_t *disp, dispsocket_t *dispsock) { isc_result_t result; dns_qid_t *qid; /* * The dispatch must be locked. */ ISC_LIST_UNLINK(disp->activesockets, dispsock, link); if (dispsock->resp != NULL) { INSIST(dispsock->resp->dispsocket == dispsock); dispsock->resp->dispsocket = NULL; } INSIST(dispsock->portentry != NULL); deref_portentry(disp, &dispsock->portentry); if (disp->nsockets > DNS_DISPATCH_POOLSOCKS) destroy_dispsocket(disp, &dispsock); else { result = isc_socket_close(dispsock->socket); qid = DNS_QID(disp); LOCK(&qid->lock); ISC_LIST_UNLINK(qid->sock_table[dispsock->bucket], dispsock, blink); UNLOCK(&qid->lock); if (result == ISC_R_SUCCESS) ISC_LIST_APPEND(disp->inactivesockets, dispsock, link); else { /* * If the underlying system does not allow this * optimization, destroy this temporary structure (and * create a new one for a new transaction). */ INSIST(result == ISC_R_NOTIMPLEMENTED); destroy_dispsocket(disp, &dispsock); } } } /* * Find an entry for query ID 'id', socket address 'dest', and port number * 'port'. * Return NULL if no such entry exists. */ static dns_dispentry_t * entry_search(dns_qid_t *qid, isc_sockaddr_t *dest, dns_messageid_t id, in_port_t port, unsigned int bucket) { dns_dispentry_t *res; REQUIRE(VALID_QID(qid)); REQUIRE(bucket < qid->qid_nbuckets); res = ISC_LIST_HEAD(qid->qid_table[bucket]); while (res != NULL) { if (res->id == id && isc_sockaddr_equal(dest, &res->host) && res->port == port) { return (res); } res = ISC_LIST_NEXT(res, link); } return (NULL); } static void free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) { isc_mempool_t *bpool; INSIST(buf != NULL && len != 0); switch (disp->socktype) { case isc_sockettype_tcp: INSIST(disp->tcpbuffers > 0); disp->tcpbuffers--; isc_mem_put(disp->mgr->mctx, buf, len); break; case isc_sockettype_udp: LOCK(&disp->mgr->buffer_lock); INSIST(disp->mgr->buffers > 0); INSIST(len == disp->mgr->buffersize); disp->mgr->buffers--; bpool = disp->mgr->bpool; UNLOCK(&disp->mgr->buffer_lock); isc_mempool_put(bpool, buf); break; default: INSIST(0); break; } } static void * allocate_udp_buffer(dns_dispatch_t *disp) { isc_mempool_t *bpool; void *temp; LOCK(&disp->mgr->buffer_lock); bpool = disp->mgr->bpool; disp->mgr->buffers++; UNLOCK(&disp->mgr->buffer_lock); temp = isc_mempool_get(bpool); if (temp == NULL) { LOCK(&disp->mgr->buffer_lock); disp->mgr->buffers--; UNLOCK(&disp->mgr->buffer_lock); } return (temp); } static inline void free_sevent(isc_event_t *ev) { isc_mempool_t *pool = ev->ev_destroy_arg; isc_socketevent_t *sev = (isc_socketevent_t *) ev; isc_mempool_put(pool, sev); } static inline isc_socketevent_t * allocate_sevent(dns_dispatch_t *disp, isc_socket_t *sock, isc_eventtype_t type, isc_taskaction_t action, const void *arg) { isc_socketevent_t *ev; void *deconst_arg; ev = isc_mempool_get(disp->sepool); if (ev == NULL) return (NULL); DE_CONST(arg, deconst_arg); ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, type, action, deconst_arg, sock, free_sevent, disp->sepool); ev->result = ISC_R_UNSET; ISC_LINK_INIT(ev, ev_link); ISC_LIST_INIT(ev->bufferlist); ev->region.base = NULL; ev->n = 0; ev->offset = 0; ev->attributes = 0; return (ev); } static inline void free_devent(dns_dispatch_t *disp, dns_dispatchevent_t *ev) { if (disp->failsafe_ev == ev) { INSIST(disp->shutdown_out == 1); disp->shutdown_out = 0; return; } isc_mempool_put(disp->mgr->depool, ev); } static inline dns_dispatchevent_t * allocate_devent(dns_dispatch_t *disp) { dns_dispatchevent_t *ev; ev = isc_mempool_get(disp->mgr->depool); if (ev == NULL) return (NULL); ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, 0, NULL, NULL, NULL, NULL, NULL); return (ev); } static void udp_exrecv(isc_task_t *task, isc_event_t *ev) { dispsocket_t *dispsock = ev->ev_arg; UNUSED(task); REQUIRE(VALID_DISPSOCK(dispsock)); udp_recv(ev, dispsock->disp, dispsock); } static void udp_shrecv(isc_task_t *task, isc_event_t *ev) { dns_dispatch_t *disp = ev->ev_arg; UNUSED(task); REQUIRE(VALID_DISPATCH(disp)); udp_recv(ev, disp, NULL); } /* * General flow: * * If I/O result == CANCELED or error, free the buffer. * * If query, free the buffer, restart. * * If response: * Allocate event, fill in details. * If cannot allocate, free buffer, restart. * find target. If not found, free buffer, restart. * if event queue is not empty, queue. else, send. * restart. */ static void udp_recv(isc_event_t *ev_in, dns_dispatch_t *disp, dispsocket_t *dispsock) { isc_socketevent_t *ev = (isc_socketevent_t *)ev_in; dns_messageid_t id; isc_result_t dres; isc_buffer_t source; unsigned int flags; dns_dispentry_t *resp = NULL; dns_dispatchevent_t *rev; unsigned int bucket; isc_boolean_t killit; isc_boolean_t queue_response; dns_dispatchmgr_t *mgr; dns_qid_t *qid; isc_netaddr_t netaddr; int match; int result; isc_boolean_t qidlocked = ISC_FALSE; LOCK(&disp->lock); mgr = disp->mgr; qid = mgr->qid; dispatch_log(disp, LVL(90), "got packet: requests %d, buffers %d, recvs %d", disp->requests, disp->mgr->buffers, disp->recv_pending); if (dispsock == NULL && ev->ev_type == ISC_SOCKEVENT_RECVDONE) { /* * Unless the receive event was imported from a listening * interface, in which case the event type is * DNS_EVENT_IMPORTRECVDONE, receive operation must be pending. */ INSIST(disp->recv_pending != 0); disp->recv_pending = 0; } if (dispsock != NULL && (ev->result == ISC_R_CANCELED || dispsock->resp == NULL)) { /* * dispsock->resp can be NULL if this transaction was canceled * just after receiving a response. Since this socket is * exclusively used and there should be at most one receive * event the canceled event should have been no effect. So * we can (and should) deactivate the socket right now. */ deactivate_dispsocket(disp, dispsock); dispsock = NULL; } if (disp->shutting_down) { /* * This dispatcher is shutting down. */ free_buffer(disp, ev->region.base, ev->region.length); isc_event_free(&ev_in); ev = NULL; killit = destroy_disp_ok(disp); UNLOCK(&disp->lock); if (killit) isc_task_send(disp->task[0], &disp->ctlevent); return; } if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) { if (dispsock != NULL) { resp = dispsock->resp; id = resp->id; if (ev->result != ISC_R_SUCCESS) { /* * This is most likely a network error on a * connected socket. It makes no sense to * check the address or parse the packet, but it * will help to return the error to the caller. */ goto sendresponse; } } else { free_buffer(disp, ev->region.base, ev->region.length); isc_event_free(&ev_in); UNLOCK(&disp->lock); return; } } else if (ev->result != ISC_R_SUCCESS) { free_buffer(disp, ev->region.base, ev->region.length); if (ev->result != ISC_R_CANCELED) dispatch_log(disp, ISC_LOG_ERROR, "odd socket result in udp_recv(): %s", isc_result_totext(ev->result)); isc_event_free(&ev_in); UNLOCK(&disp->lock); return; } /* * If this is from a blackholed address, drop it. */ isc_netaddr_fromsockaddr(&netaddr, &ev->address); if (disp->mgr->blackhole != NULL && dns_acl_match(&netaddr, NULL, disp->mgr->blackhole, NULL, &match, NULL) == ISC_R_SUCCESS && match > 0) { if (isc_log_wouldlog(dns_lctx, LVL(10))) { char netaddrstr[ISC_NETADDR_FORMATSIZE]; isc_netaddr_format(&netaddr, netaddrstr, sizeof(netaddrstr)); dispatch_log(disp, LVL(10), "blackholed packet from %s", netaddrstr); } free_buffer(disp, ev->region.base, ev->region.length); goto restart; } /* * Peek into the buffer to see what we can see. */ isc_buffer_init(&source, ev->region.base, ev->region.length); isc_buffer_add(&source, ev->n); dres = dns_message_peekheader(&source, &id, &flags); if (dres != ISC_R_SUCCESS) { free_buffer(disp, ev->region.base, ev->region.length); dispatch_log(disp, LVL(10), "got garbage packet"); goto restart; } dispatch_log(disp, LVL(92), "got valid DNS message header, /QR %c, id %u", ((flags & DNS_MESSAGEFLAG_QR) ? '1' : '0'), id); /* * Look at flags. If query, drop it. If response, * look to see where it goes. */ if ((flags & DNS_MESSAGEFLAG_QR) == 0) { /* query */ free_buffer(disp, ev->region.base, ev->region.length); goto restart; } /* * Search for the corresponding response. If we are using an exclusive * socket, we've already identified it and we can skip the search; but * the ID and the address must match the expected ones. */ if (resp == NULL) { bucket = dns_hash(qid, &ev->address, id, disp->localport); LOCK(&qid->lock); qidlocked = ISC_TRUE; resp = entry_search(qid, &ev->address, id, disp->localport, bucket); dispatch_log(disp, LVL(90), "search for response in bucket %d: %s", bucket, (resp == NULL ? "not found" : "found")); if (resp == NULL) { inc_stats(mgr, dns_resstatscounter_mismatch); free_buffer(disp, ev->region.base, ev->region.length); goto unlock; } } else if (resp->id != id || !isc_sockaddr_equal(&ev->address, &resp->host)) { dispatch_log(disp, LVL(90), "response to an exclusive socket doesn't match"); inc_stats(mgr, dns_resstatscounter_mismatch); free_buffer(disp, ev->region.base, ev->region.length); goto unlock; } /* * Now that we have the original dispatch the query was sent * from check that the address and port the response was * sent to make sense. */ if (disp != resp->disp) { isc_sockaddr_t a1; isc_sockaddr_t a2; /* * Check that the socket types and ports match. */ if (disp->socktype != resp->disp->socktype || isc_sockaddr_getport(&disp->local) != isc_sockaddr_getport(&resp->disp->local)) { free_buffer(disp, ev->region.base, ev->region.length); goto unlock; } /* * If each dispatch is bound to a different address * then fail. * * Note under Linux a packet can be sent out via IPv4 socket * and the response be received via a IPv6 socket. * * Requests sent out via IPv6 should always come back in * via IPv6. */ if (isc_sockaddr_pf(&resp->disp->local) == PF_INET6 && isc_sockaddr_pf(&disp->local) != PF_INET6) { free_buffer(disp, ev->region.base, ev->region.length); goto unlock; } isc_sockaddr_anyofpf(&a1, isc_sockaddr_pf(&resp->disp->local)); isc_sockaddr_anyofpf(&a2, isc_sockaddr_pf(&disp->local)); if (!isc_sockaddr_eqaddr(&disp->local, &resp->disp->local) && !isc_sockaddr_eqaddr(&a1, &resp->disp->local) && !isc_sockaddr_eqaddr(&a2, &disp->local)) { free_buffer(disp, ev->region.base, ev->region.length); goto unlock; } } sendresponse: queue_response = resp->item_out; rev = allocate_devent(resp->disp); if (rev == NULL) { free_buffer(disp, ev->region.base, ev->region.length); goto unlock; } /* * At this point, rev contains the event we want to fill in, and * resp contains the information on the place to send it to. * Send the event off. */ isc_buffer_init(&rev->buffer, ev->region.base, ev->region.length); isc_buffer_add(&rev->buffer, ev->n); rev->result = ev->result; rev->id = id; rev->addr = ev->address; rev->pktinfo = ev->pktinfo; rev->attributes = ev->attributes; if (queue_response) { ISC_LIST_APPEND(resp->items, rev, ev_link); } else { ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL, DNS_EVENT_DISPATCH, resp->action, resp->arg, resp, NULL, NULL); request_log(disp, resp, LVL(90), "[a] Sent event %p buffer %p len %d to task %p", rev, rev->buffer.base, rev->buffer.length, resp->task); resp->item_out = ISC_TRUE; isc_task_send(resp->task, ISC_EVENT_PTR(&rev)); } unlock: if (qidlocked) UNLOCK(&qid->lock); /* * Restart recv() to get the next packet. */ restart: result = startrecv(disp, dispsock); if (result != ISC_R_SUCCESS && dispsock != NULL) { /* * XXX: wired. There seems to be no recovery process other than * deactivate this socket anyway (since we cannot start * receiving, we won't be able to receive a cancel event * from the user). */ deactivate_dispsocket(disp, dispsock); } isc_event_free(&ev_in); UNLOCK(&disp->lock); } /* * General flow: * * If I/O result == CANCELED, EOF, or error, notify everyone as the * various queues drain. * * If query, restart. * * If response: * Allocate event, fill in details. * If cannot allocate, restart. * find target. If not found, restart. * if event queue is not empty, queue. else, send. * restart. */ static void tcp_recv(isc_task_t *task, isc_event_t *ev_in) { dns_dispatch_t *disp = ev_in->ev_arg; dns_tcpmsg_t *tcpmsg = &disp->tcpmsg; dns_messageid_t id; isc_result_t dres; unsigned int flags; dns_dispentry_t *resp; dns_dispatchevent_t *rev; unsigned int bucket; isc_boolean_t killit; isc_boolean_t queue_response; dns_qid_t *qid; int level; char buf[ISC_SOCKADDR_FORMATSIZE]; UNUSED(task); REQUIRE(VALID_DISPATCH(disp)); qid = disp->qid; dispatch_log(disp, LVL(90), "got TCP packet: requests %d, buffers %d, recvs %d", disp->requests, disp->tcpbuffers, disp->recv_pending); LOCK(&disp->lock); INSIST(disp->recv_pending != 0); disp->recv_pending = 0; if (disp->refcount == 0) { /* * This dispatcher is shutting down. Force cancelation. */ tcpmsg->result = ISC_R_CANCELED; } if (tcpmsg->result != ISC_R_SUCCESS) { switch (tcpmsg->result) { case ISC_R_CANCELED: break; case ISC_R_EOF: dispatch_log(disp, LVL(90), "shutting down on EOF"); do_cancel(disp); break; case ISC_R_CONNECTIONRESET: level = ISC_LOG_INFO; goto logit; default: level = ISC_LOG_ERROR; logit: isc_sockaddr_format(&tcpmsg->address, buf, sizeof(buf)); dispatch_log(disp, level, "shutting down due to TCP " "receive error: %s: %s", buf, isc_result_totext(tcpmsg->result)); do_cancel(disp); break; } /* * The event is statically allocated in the tcpmsg * structure, and destroy_disp() frees the tcpmsg, so we must * free the event *before* calling destroy_disp(). */ isc_event_free(&ev_in); disp->shutting_down = 1; disp->shutdown_why = tcpmsg->result; /* * If the recv() was canceled pass the word on. */ killit = destroy_disp_ok(disp); UNLOCK(&disp->lock); if (killit) isc_task_send(disp->task[0], &disp->ctlevent); return; } dispatch_log(disp, LVL(90), "result %d, length == %d, addr = %p", tcpmsg->result, tcpmsg->buffer.length, tcpmsg->buffer.base); /* * Peek into the buffer to see what we can see. */ dres = dns_message_peekheader(&tcpmsg->buffer, &id, &flags); if (dres != ISC_R_SUCCESS) { dispatch_log(disp, LVL(10), "got garbage packet"); goto restart; } dispatch_log(disp, LVL(92), "got valid DNS message header, /QR %c, id %u", ((flags & DNS_MESSAGEFLAG_QR) ? '1' : '0'), id); /* * Allocate an event to send to the query or response client, and * allocate a new buffer for our use. */ /* * Look at flags. If query, drop it. If response, * look to see where it goes. */ if ((flags & DNS_MESSAGEFLAG_QR) == 0) { /* * Query. */ goto restart; } /* * Response. */ bucket = dns_hash(qid, &tcpmsg->address, id, disp->localport); LOCK(&qid->lock); resp = entry_search(qid, &tcpmsg->address, id, disp->localport, bucket); dispatch_log(disp, LVL(90), "search for response in bucket %d: %s", bucket, (resp == NULL ? "not found" : "found")); if (resp == NULL) goto unlock; queue_response = resp->item_out; rev = allocate_devent(disp); if (rev == NULL) goto unlock; /* * At this point, rev contains the event we want to fill in, and * resp contains the information on the place to send it to. * Send the event off. */ dns_tcpmsg_keepbuffer(tcpmsg, &rev->buffer); disp->tcpbuffers++; rev->result = ISC_R_SUCCESS; rev->id = id; rev->addr = tcpmsg->address; if (queue_response) { ISC_LIST_APPEND(resp->items, rev, ev_link); } else { ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL, DNS_EVENT_DISPATCH, resp->action, resp->arg, resp, NULL, NULL); request_log(disp, resp, LVL(90), "[b] Sent event %p buffer %p len %d to task %p", rev, rev->buffer.base, rev->buffer.length, resp->task); resp->item_out = ISC_TRUE; isc_task_send(resp->task, ISC_EVENT_PTR(&rev)); } unlock: UNLOCK(&qid->lock); /* * Restart recv() to get the next packet. */ restart: (void)startrecv(disp, NULL); isc_event_free(&ev_in); UNLOCK(&disp->lock); } /* * disp must be locked. */ static isc_result_t startrecv(dns_dispatch_t *disp, dispsocket_t *dispsock) { isc_result_t res; isc_region_t region; isc_socket_t *sock; if (disp->shutting_down == 1) return (ISC_R_SUCCESS); if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0) return (ISC_R_SUCCESS); if (disp->recv_pending != 0 && dispsock == NULL) return (ISC_R_SUCCESS); if (disp->mgr->buffers >= disp->mgr->maxbuffers) return (ISC_R_NOMEMORY); if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0 && dispsock == NULL) return (ISC_R_SUCCESS); if (dispsock != NULL) sock = dispsock->socket; else sock = disp->socket; INSIST(sock != NULL); switch (disp->socktype) { /* * UDP reads are always maximal. */ case isc_sockettype_udp: region.length = disp->mgr->buffersize; region.base = allocate_udp_buffer(disp); if (region.base == NULL) return (ISC_R_NOMEMORY); if (dispsock != NULL) { isc_task_t *dt = dispsock->task; isc_socketevent_t *sev = allocate_sevent(disp, sock, ISC_SOCKEVENT_RECVDONE, udp_exrecv, dispsock); if (sev == NULL) { free_buffer(disp, region.base, region.length); return (ISC_R_NOMEMORY); } res = isc_socket_recv2(sock, ®ion, 1, dt, sev, 0); if (res != ISC_R_SUCCESS) { free_buffer(disp, region.base, region.length); return (res); } } else { isc_task_t *dt = disp->task[0]; isc_socketevent_t *sev = allocate_sevent(disp, sock, ISC_SOCKEVENT_RECVDONE, udp_shrecv, disp); if (sev == NULL) { free_buffer(disp, region.base, region.length); return (ISC_R_NOMEMORY); } res = isc_socket_recv2(sock, ®ion, 1, dt, sev, 0); if (res != ISC_R_SUCCESS) { free_buffer(disp, region.base, region.length); disp->shutdown_why = res; disp->shutting_down = 1; do_cancel(disp); return (ISC_R_SUCCESS); /* recover by cancel */ } INSIST(disp->recv_pending == 0); disp->recv_pending = 1; } break; case isc_sockettype_tcp: res = dns_tcpmsg_readmessage(&disp->tcpmsg, disp->task[0], tcp_recv, disp); if (res != ISC_R_SUCCESS) { disp->shutdown_why = res; disp->shutting_down = 1; do_cancel(disp); return (ISC_R_SUCCESS); /* recover by cancel */ } INSIST(disp->recv_pending == 0); disp->recv_pending = 1; break; default: INSIST(0); break; } return (ISC_R_SUCCESS); } /* * Mgr must be locked when calling this function. */ static isc_boolean_t destroy_mgr_ok(dns_dispatchmgr_t *mgr) { mgr_log(mgr, LVL(90), "destroy_mgr_ok: shuttingdown=%d, listnonempty=%d, " "depool=%d, rpool=%d, dpool=%d", MGR_IS_SHUTTINGDOWN(mgr), !ISC_LIST_EMPTY(mgr->list), isc_mempool_getallocated(mgr->depool), isc_mempool_getallocated(mgr->rpool), isc_mempool_getallocated(mgr->dpool)); if (!MGR_IS_SHUTTINGDOWN(mgr)) return (ISC_FALSE); if (!ISC_LIST_EMPTY(mgr->list)) return (ISC_FALSE); if (isc_mempool_getallocated(mgr->depool) != 0) return (ISC_FALSE); if (isc_mempool_getallocated(mgr->rpool) != 0) return (ISC_FALSE); if (isc_mempool_getallocated(mgr->dpool) != 0) return (ISC_FALSE); return (ISC_TRUE); } /* * Mgr must be unlocked when calling this function. */ static void destroy_mgr(dns_dispatchmgr_t **mgrp) { isc_mem_t *mctx; dns_dispatchmgr_t *mgr; mgr = *mgrp; *mgrp = NULL; mctx = mgr->mctx; mgr->magic = 0; mgr->mctx = NULL; DESTROYLOCK(&mgr->lock); mgr->state = 0; DESTROYLOCK(&mgr->arc4_lock); isc_mempool_destroy(&mgr->depool); isc_mempool_destroy(&mgr->rpool); isc_mempool_destroy(&mgr->dpool); if (mgr->bpool != NULL) isc_mempool_destroy(&mgr->bpool); if (mgr->spool != NULL) isc_mempool_destroy(&mgr->spool); DESTROYLOCK(&mgr->spool_lock); DESTROYLOCK(&mgr->bpool_lock); DESTROYLOCK(&mgr->dpool_lock); DESTROYLOCK(&mgr->rpool_lock); DESTROYLOCK(&mgr->depool_lock); if (mgr->entropy != NULL) isc_entropy_detach(&mgr->entropy); if (mgr->qid != NULL) qid_destroy(mctx, &mgr->qid); DESTROYLOCK(&mgr->buffer_lock); if (mgr->blackhole != NULL) dns_acl_detach(&mgr->blackhole); if (mgr->stats != NULL) isc_stats_detach(&mgr->stats); if (mgr->v4ports != NULL) { isc_mem_put(mctx, mgr->v4ports, mgr->nv4ports * sizeof(in_port_t)); } if (mgr->v6ports != NULL) { isc_mem_put(mctx, mgr->v6ports, mgr->nv6ports * sizeof(in_port_t)); } isc_mem_put(mctx, mgr, sizeof(dns_dispatchmgr_t)); isc_mem_detach(&mctx); } static isc_result_t open_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local, unsigned int options, isc_socket_t **sockp, isc_socket_t *dup_socket) { isc_socket_t *sock; isc_result_t result; sock = *sockp; if (sock != NULL) { result = isc_socket_open(sock); if (result != ISC_R_SUCCESS) return (result); } else if (dup_socket != NULL) { result = isc_socket_dup(dup_socket, &sock); if (result != ISC_R_SUCCESS) return (result); isc_socket_setname(sock, "dispatcher", NULL); *sockp = sock; return (ISC_R_SUCCESS); } else { result = isc_socket_create(mgr, isc_sockaddr_pf(local), isc_sockettype_udp, &sock); if (result != ISC_R_SUCCESS) return (result); } isc_socket_setname(sock, "dispatcher", NULL); #ifndef ISC_ALLOW_MAPPED isc_socket_ipv6only(sock, ISC_TRUE); #endif result = isc_socket_bind(sock, local, options); if (result != ISC_R_SUCCESS) { if (*sockp == NULL) isc_socket_detach(&sock); else { isc_socket_close(sock); } return (result); } *sockp = sock; return (ISC_R_SUCCESS); } /*% * Create a temporary port list to set the initial default set of dispatch * ports: [1024, 65535]. This is almost meaningless as the application will * normally set the ports explicitly, but is provided to fill some minor corner * cases. */ static isc_result_t create_default_portset(isc_mem_t *mctx, isc_portset_t **portsetp) { isc_result_t result; result = isc_portset_create(mctx, portsetp); if (result != ISC_R_SUCCESS) return (result); isc_portset_addrange(*portsetp, 1024, 65535); return (ISC_R_SUCCESS); } /* * Publics. */ isc_result_t dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy, dns_dispatchmgr_t **mgrp) { dns_dispatchmgr_t *mgr; isc_result_t result; isc_portset_t *v4portset = NULL; isc_portset_t *v6portset = NULL; REQUIRE(mctx != NULL); REQUIRE(mgrp != NULL && *mgrp == NULL); mgr = isc_mem_get(mctx, sizeof(dns_dispatchmgr_t)); if (mgr == NULL) return (ISC_R_NOMEMORY); mgr->mctx = NULL; isc_mem_attach(mctx, &mgr->mctx); mgr->blackhole = NULL; mgr->stats = NULL; result = isc_mutex_init(&mgr->lock); if (result != ISC_R_SUCCESS) goto deallocate; result = isc_mutex_init(&mgr->arc4_lock); if (result != ISC_R_SUCCESS) goto kill_lock; result = isc_mutex_init(&mgr->buffer_lock); if (result != ISC_R_SUCCESS) goto kill_arc4_lock; result = isc_mutex_init(&mgr->depool_lock); if (result != ISC_R_SUCCESS) goto kill_buffer_lock; result = isc_mutex_init(&mgr->rpool_lock); if (result != ISC_R_SUCCESS) goto kill_depool_lock; result = isc_mutex_init(&mgr->dpool_lock); if (result != ISC_R_SUCCESS) goto kill_rpool_lock; result = isc_mutex_init(&mgr->bpool_lock); if (result != ISC_R_SUCCESS) goto kill_dpool_lock; result = isc_mutex_init(&mgr->spool_lock); if (result != ISC_R_SUCCESS) goto kill_bpool_lock; mgr->depool = NULL; if (isc_mempool_create(mgr->mctx, sizeof(dns_dispatchevent_t), &mgr->depool) != ISC_R_SUCCESS) { result = ISC_R_NOMEMORY; goto kill_spool_lock; } mgr->rpool = NULL; if (isc_mempool_create(mgr->mctx, sizeof(dns_dispentry_t), &mgr->rpool) != ISC_R_SUCCESS) { result = ISC_R_NOMEMORY; goto kill_depool; } mgr->dpool = NULL; if (isc_mempool_create(mgr->mctx, sizeof(dns_dispatch_t), &mgr->dpool) != ISC_R_SUCCESS) { result = ISC_R_NOMEMORY; goto kill_rpool; } isc_mempool_setname(mgr->depool, "dispmgr_depool"); isc_mempool_setmaxalloc(mgr->depool, 32768); isc_mempool_setfreemax(mgr->depool, 32768); isc_mempool_associatelock(mgr->depool, &mgr->depool_lock); isc_mempool_setfillcount(mgr->depool, 32); isc_mempool_setname(mgr->rpool, "dispmgr_rpool"); isc_mempool_setmaxalloc(mgr->rpool, 32768); isc_mempool_setfreemax(mgr->rpool, 32768); isc_mempool_associatelock(mgr->rpool, &mgr->rpool_lock); isc_mempool_setfillcount(mgr->rpool, 32); isc_mempool_setname(mgr->dpool, "dispmgr_dpool"); isc_mempool_setmaxalloc(mgr->dpool, 32768); isc_mempool_setfreemax(mgr->dpool, 32768); isc_mempool_associatelock(mgr->dpool, &mgr->dpool_lock); isc_mempool_setfillcount(mgr->dpool, 32); mgr->buffers = 0; mgr->buffersize = 0; mgr->maxbuffers = 0; mgr->bpool = NULL; mgr->spool = NULL; mgr->entropy = NULL; mgr->qid = NULL; mgr->state = 0; ISC_LIST_INIT(mgr->list); mgr->v4ports = NULL; mgr->v6ports = NULL; mgr->nv4ports = 0; mgr->nv6ports = 0; mgr->magic = DNS_DISPATCHMGR_MAGIC; result = create_default_portset(mctx, &v4portset); if (result == ISC_R_SUCCESS) { result = create_default_portset(mctx, &v6portset); if (result == ISC_R_SUCCESS) { result = dns_dispatchmgr_setavailports(mgr, v4portset, v6portset); } } if (v4portset != NULL) isc_portset_destroy(mctx, &v4portset); if (v6portset != NULL) isc_portset_destroy(mctx, &v6portset); if (result != ISC_R_SUCCESS) goto kill_dpool; if (entropy != NULL) isc_entropy_attach(entropy, &mgr->entropy); dispatch_initrandom(&mgr->arc4ctx, mgr->entropy, &mgr->arc4_lock); *mgrp = mgr; return (ISC_R_SUCCESS); kill_dpool: isc_mempool_destroy(&mgr->dpool); kill_rpool: isc_mempool_destroy(&mgr->rpool); kill_depool: isc_mempool_destroy(&mgr->depool); kill_spool_lock: DESTROYLOCK(&mgr->spool_lock); kill_bpool_lock: DESTROYLOCK(&mgr->bpool_lock); kill_dpool_lock: DESTROYLOCK(&mgr->dpool_lock); kill_rpool_lock: DESTROYLOCK(&mgr->rpool_lock); kill_depool_lock: DESTROYLOCK(&mgr->depool_lock); kill_buffer_lock: DESTROYLOCK(&mgr->buffer_lock); kill_arc4_lock: DESTROYLOCK(&mgr->arc4_lock); kill_lock: DESTROYLOCK(&mgr->lock); deallocate: isc_mem_put(mctx, mgr, sizeof(dns_dispatchmgr_t)); isc_mem_detach(&mctx); return (result); } void dns_dispatchmgr_setblackhole(dns_dispatchmgr_t *mgr, dns_acl_t *blackhole) { REQUIRE(VALID_DISPATCHMGR(mgr)); if (mgr->blackhole != NULL) dns_acl_detach(&mgr->blackhole); dns_acl_attach(blackhole, &mgr->blackhole); } dns_acl_t * dns_dispatchmgr_getblackhole(dns_dispatchmgr_t *mgr) { REQUIRE(VALID_DISPATCHMGR(mgr)); return (mgr->blackhole); } void dns_dispatchmgr_setblackportlist(dns_dispatchmgr_t *mgr, dns_portlist_t *portlist) { REQUIRE(VALID_DISPATCHMGR(mgr)); UNUSED(portlist); /* This function is deprecated: use dns_dispatchmgr_setavailports(). */ return; } dns_portlist_t * dns_dispatchmgr_getblackportlist(dns_dispatchmgr_t *mgr) { REQUIRE(VALID_DISPATCHMGR(mgr)); return (NULL); /* this function is deprecated */ } isc_result_t dns_dispatchmgr_setavailports(dns_dispatchmgr_t *mgr, isc_portset_t *v4portset, isc_portset_t *v6portset) { in_port_t *v4ports, *v6ports, p; unsigned int nv4ports, nv6ports, i4, i6; REQUIRE(VALID_DISPATCHMGR(mgr)); nv4ports = isc_portset_nports(v4portset); nv6ports = isc_portset_nports(v6portset); v4ports = NULL; if (nv4ports != 0) { v4ports = isc_mem_get(mgr->mctx, sizeof(in_port_t) * nv4ports); if (v4ports == NULL) return (ISC_R_NOMEMORY); } v6ports = NULL; if (nv6ports != 0) { v6ports = isc_mem_get(mgr->mctx, sizeof(in_port_t) * nv6ports); if (v6ports == NULL) { if (v4ports != NULL) { isc_mem_put(mgr->mctx, v4ports, sizeof(in_port_t) * isc_portset_nports(v4portset)); } return (ISC_R_NOMEMORY); } } p = 0; i4 = 0; i6 = 0; do { if (isc_portset_isset(v4portset, p)) { INSIST(i4 < nv4ports); v4ports[i4++] = p; } if (isc_portset_isset(v6portset, p)) { INSIST(i6 < nv6ports); v6ports[i6++] = p; } } while (p++ < 65535); INSIST(i4 == nv4ports && i6 == nv6ports); PORTBUFLOCK(mgr); if (mgr->v4ports != NULL) { isc_mem_put(mgr->mctx, mgr->v4ports, mgr->nv4ports * sizeof(in_port_t)); } mgr->v4ports = v4ports; mgr->nv4ports = nv4ports; if (mgr->v6ports != NULL) { isc_mem_put(mgr->mctx, mgr->v6ports, mgr->nv6ports * sizeof(in_port_t)); } mgr->v6ports = v6ports; mgr->nv6ports = nv6ports; PORTBUFUNLOCK(mgr); return (ISC_R_SUCCESS); } static isc_result_t dns_dispatchmgr_setudp(dns_dispatchmgr_t *mgr, unsigned int buffersize, unsigned int maxbuffers, unsigned int maxrequests, unsigned int buckets, unsigned int increment) { isc_result_t result; REQUIRE(VALID_DISPATCHMGR(mgr)); REQUIRE(buffersize >= 512 && buffersize < (64 * 1024)); REQUIRE(maxbuffers > 0); REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */ REQUIRE(increment > buckets); /* * Keep some number of items around. This should be a config * option. For now, keep 8, but later keep at least two even * if the caller wants less. This allows us to ensure certain * things, like an event can be "freed" and the next allocation * will always succeed. * * Note that if limits are placed on anything here, we use one * event internally, so the actual limit should be "wanted + 1." * * XXXMLG */ if (maxbuffers < 8) maxbuffers = 8; LOCK(&mgr->buffer_lock); /* Create or adjust buffer pool */ if (mgr->bpool != NULL) { /* * We only increase the maxbuffers to avoid accidental buffer * shortage. Ideally we'd separate the manager-wide maximum * from per-dispatch limits and respect the latter within the * global limit. But at this moment that's deemed to be * overkilling and isn't worth additional implementation * complexity. */ if (maxbuffers > mgr->maxbuffers) { isc_mempool_setmaxalloc(mgr->bpool, maxbuffers); isc_mempool_setfreemax(mgr->bpool, maxbuffers); mgr->maxbuffers = maxbuffers; } } else { result = isc_mempool_create(mgr->mctx, buffersize, &mgr->bpool); if (result != ISC_R_SUCCESS) { UNLOCK(&mgr->buffer_lock); return (result); } isc_mempool_setname(mgr->bpool, "dispmgr_bpool"); isc_mempool_setmaxalloc(mgr->bpool, maxbuffers); isc_mempool_setfreemax(mgr->bpool, maxbuffers); isc_mempool_associatelock(mgr->bpool, &mgr->bpool_lock); isc_mempool_setfillcount(mgr->bpool, 32); } /* Create or adjust socket pool */ if (mgr->spool != NULL) { if (maxrequests < DNS_DISPATCH_POOLSOCKS * 2) { isc_mempool_setmaxalloc(mgr->spool, DNS_DISPATCH_POOLSOCKS * 2); isc_mempool_setfreemax(mgr->spool, DNS_DISPATCH_POOLSOCKS * 2); } UNLOCK(&mgr->buffer_lock); return (ISC_R_SUCCESS); } result = isc_mempool_create(mgr->mctx, sizeof(dispsocket_t), &mgr->spool); if (result != ISC_R_SUCCESS) { UNLOCK(&mgr->buffer_lock); goto cleanup; } isc_mempool_setname(mgr->spool, "dispmgr_spool"); isc_mempool_setmaxalloc(mgr->spool, maxrequests); isc_mempool_setfreemax(mgr->spool, maxrequests); isc_mempool_associatelock(mgr->spool, &mgr->spool_lock); isc_mempool_setfillcount(mgr->spool, 32); result = qid_allocate(mgr, buckets, increment, &mgr->qid, ISC_TRUE); if (result != ISC_R_SUCCESS) goto cleanup; mgr->buffersize = buffersize; mgr->maxbuffers = maxbuffers; UNLOCK(&mgr->buffer_lock); return (ISC_R_SUCCESS); cleanup: isc_mempool_destroy(&mgr->bpool); if (mgr->spool != NULL) isc_mempool_destroy(&mgr->spool); UNLOCK(&mgr->buffer_lock); return (result); } void dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp) { dns_dispatchmgr_t *mgr; isc_boolean_t killit; REQUIRE(mgrp != NULL); REQUIRE(VALID_DISPATCHMGR(*mgrp)); mgr = *mgrp; *mgrp = NULL; LOCK(&mgr->lock); mgr->state |= MGR_SHUTTINGDOWN; killit = destroy_mgr_ok(mgr); UNLOCK(&mgr->lock); mgr_log(mgr, LVL(90), "destroy: killit=%d", killit); if (killit) destroy_mgr(&mgr); } void dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, isc_stats_t *stats) { REQUIRE(VALID_DISPATCHMGR(mgr)); REQUIRE(ISC_LIST_EMPTY(mgr->list)); REQUIRE(mgr->stats == NULL); isc_stats_attach(stats, &mgr->stats); } static int port_cmp(const void *key, const void *ent) { in_port_t p1 = *(const in_port_t *)key; in_port_t p2 = *(const in_port_t *)ent; if (p1 < p2) return (-1); else if (p1 == p2) return (0); else return (1); } static isc_boolean_t portavailable(dns_dispatchmgr_t *mgr, isc_socket_t *sock, isc_sockaddr_t *sockaddrp) { isc_sockaddr_t sockaddr; isc_result_t result; in_port_t *ports, port; unsigned int nports; isc_boolean_t available = ISC_FALSE; REQUIRE(sock != NULL || sockaddrp != NULL); PORTBUFLOCK(mgr); if (sock != NULL) { sockaddrp = &sockaddr; result = isc_socket_getsockname(sock, sockaddrp); if (result != ISC_R_SUCCESS) goto unlock; } if (isc_sockaddr_pf(sockaddrp) == AF_INET) { ports = mgr->v4ports; nports = mgr->nv4ports; } else { ports = mgr->v6ports; nports = mgr->nv6ports; } if (ports == NULL) goto unlock; port = isc_sockaddr_getport(sockaddrp); if (bsearch(&port, ports, nports, sizeof(in_port_t), port_cmp) != NULL) available = ISC_TRUE; unlock: PORTBUFUNLOCK(mgr); return (available); } #define ATTRMATCH(_a1, _a2, _mask) (((_a1) & (_mask)) == ((_a2) & (_mask))) static isc_boolean_t local_addr_match(dns_dispatch_t *disp, isc_sockaddr_t *addr) { isc_sockaddr_t sockaddr; isc_result_t result; REQUIRE(disp->socket != NULL); if (addr == NULL) return (ISC_TRUE); /* * Don't match wildcard ports unless the port is available in the * current configuration. */ if (isc_sockaddr_getport(addr) == 0 && isc_sockaddr_getport(&disp->local) == 0 && !portavailable(disp->mgr, disp->socket, NULL)) { return (ISC_FALSE); } /* * Check if we match the binding . * Wildcard ports match/fail here. */ if (isc_sockaddr_equal(&disp->local, addr)) return (ISC_TRUE); if (isc_sockaddr_getport(addr) == 0) return (ISC_FALSE); /* * Check if we match a bound wildcard port . */ if (!isc_sockaddr_eqaddr(&disp->local, addr)) return (ISC_FALSE); result = isc_socket_getsockname(disp->socket, &sockaddr); if (result != ISC_R_SUCCESS) return (ISC_FALSE); return (isc_sockaddr_equal(&sockaddr, addr)); } /* * Requires mgr be locked. * * No dispatcher can be locked by this thread when calling this function. * * * NOTE: * If a matching dispatcher is found, it is locked after this function * returns, and must be unlocked by the caller. */ static isc_result_t dispatch_find(dns_dispatchmgr_t *mgr, isc_sockaddr_t *local, unsigned int attributes, unsigned int mask, dns_dispatch_t **dispp) { dns_dispatch_t *disp; isc_result_t result; /* * Make certain that we will not match a private or exclusive dispatch. */ attributes &= ~(DNS_DISPATCHATTR_PRIVATE|DNS_DISPATCHATTR_EXCLUSIVE); mask |= (DNS_DISPATCHATTR_PRIVATE|DNS_DISPATCHATTR_EXCLUSIVE); disp = ISC_LIST_HEAD(mgr->list); while (disp != NULL) { LOCK(&disp->lock); if ((disp->shutting_down == 0) && ATTRMATCH(disp->attributes, attributes, mask) && local_addr_match(disp, local)) break; UNLOCK(&disp->lock); disp = ISC_LIST_NEXT(disp, link); } if (disp == NULL) { result = ISC_R_NOTFOUND; goto out; } *dispp = disp; result = ISC_R_SUCCESS; out: return (result); } static isc_result_t qid_allocate(dns_dispatchmgr_t *mgr, unsigned int buckets, unsigned int increment, dns_qid_t **qidp, isc_boolean_t needsocktable) { dns_qid_t *qid; unsigned int i; isc_result_t result; REQUIRE(VALID_DISPATCHMGR(mgr)); REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */ REQUIRE(increment > buckets); REQUIRE(qidp != NULL && *qidp == NULL); qid = isc_mem_get(mgr->mctx, sizeof(*qid)); if (qid == NULL) return (ISC_R_NOMEMORY); qid->qid_table = isc_mem_get(mgr->mctx, buckets * sizeof(dns_displist_t)); if (qid->qid_table == NULL) { isc_mem_put(mgr->mctx, qid, sizeof(*qid)); return (ISC_R_NOMEMORY); } qid->sock_table = NULL; if (needsocktable) { qid->sock_table = isc_mem_get(mgr->mctx, buckets * sizeof(dispsocketlist_t)); if (qid->sock_table == NULL) { isc_mem_put(mgr->mctx, qid->qid_table, buckets * sizeof(dns_displist_t)); isc_mem_put(mgr->mctx, qid, sizeof(*qid)); return (ISC_R_NOMEMORY); } } result = isc_mutex_init(&qid->lock); if (result != ISC_R_SUCCESS) { if (qid->sock_table != NULL) { isc_mem_put(mgr->mctx, qid->sock_table, buckets * sizeof(dispsocketlist_t)); } isc_mem_put(mgr->mctx, qid->qid_table, buckets * sizeof(dns_displist_t)); isc_mem_put(mgr->mctx, qid, sizeof(*qid)); return (result); } for (i = 0; i < buckets; i++) { ISC_LIST_INIT(qid->qid_table[i]); if (qid->sock_table != NULL) ISC_LIST_INIT(qid->sock_table[i]); } qid->qid_nbuckets = buckets; qid->qid_increment = increment; qid->magic = QID_MAGIC; *qidp = qid; return (ISC_R_SUCCESS); } static void qid_destroy(isc_mem_t *mctx, dns_qid_t **qidp) { dns_qid_t *qid; REQUIRE(qidp != NULL); qid = *qidp; REQUIRE(VALID_QID(qid)); *qidp = NULL; qid->magic = 0; isc_mem_put(mctx, qid->qid_table, qid->qid_nbuckets * sizeof(dns_displist_t)); if (qid->sock_table != NULL) { isc_mem_put(mctx, qid->sock_table, qid->qid_nbuckets * sizeof(dispsocketlist_t)); } DESTROYLOCK(&qid->lock); isc_mem_put(mctx, qid, sizeof(*qid)); } /* * Allocate and set important limits. */ static isc_result_t dispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests, dns_dispatch_t **dispp) { dns_dispatch_t *disp; isc_result_t result; REQUIRE(VALID_DISPATCHMGR(mgr)); REQUIRE(dispp != NULL && *dispp == NULL); /* * Set up the dispatcher, mostly. Don't bother setting some of * the options that are controlled by tcp vs. udp, etc. */ disp = isc_mempool_get(mgr->dpool); if (disp == NULL) return (ISC_R_NOMEMORY); disp->magic = 0; disp->mgr = mgr; disp->maxrequests = maxrequests; disp->attributes = 0; ISC_LINK_INIT(disp, link); disp->refcount = 1; disp->recv_pending = 0; memset(&disp->local, 0, sizeof(disp->local)); disp->localport = 0; disp->shutting_down = 0; disp->shutdown_out = 0; disp->connected = 0; disp->tcpmsg_valid = 0; disp->shutdown_why = ISC_R_UNEXPECTED; disp->requests = 0; disp->tcpbuffers = 0; disp->qid = NULL; ISC_LIST_INIT(disp->activesockets); ISC_LIST_INIT(disp->inactivesockets); disp->nsockets = 0; dispatch_initrandom(&disp->arc4ctx, mgr->entropy, NULL); disp->port_table = NULL; disp->portpool = NULL; disp->dscp = -1; result = isc_mutex_init(&disp->lock); if (result != ISC_R_SUCCESS) goto deallocate; disp->failsafe_ev = allocate_devent(disp); if (disp->failsafe_ev == NULL) { result = ISC_R_NOMEMORY; goto kill_lock; } disp->magic = DISPATCH_MAGIC; *dispp = disp; return (ISC_R_SUCCESS); /* * error returns */ kill_lock: DESTROYLOCK(&disp->lock); deallocate: isc_mempool_put(mgr->dpool, disp); return (result); } /* * MUST be unlocked, and not used by anything. */ static void dispatch_free(dns_dispatch_t **dispp) { dns_dispatch_t *disp; dns_dispatchmgr_t *mgr; int i; REQUIRE(VALID_DISPATCH(*dispp)); disp = *dispp; *dispp = NULL; mgr = disp->mgr; REQUIRE(VALID_DISPATCHMGR(mgr)); if (disp->tcpmsg_valid) { dns_tcpmsg_invalidate(&disp->tcpmsg); disp->tcpmsg_valid = 0; } INSIST(disp->tcpbuffers == 0); INSIST(disp->requests == 0); INSIST(disp->recv_pending == 0); INSIST(ISC_LIST_EMPTY(disp->activesockets)); INSIST(ISC_LIST_EMPTY(disp->inactivesockets)); isc_mempool_put(mgr->depool, disp->failsafe_ev); disp->failsafe_ev = NULL; if (disp->qid != NULL) qid_destroy(mgr->mctx, &disp->qid); if (disp->port_table != NULL) { for (i = 0; i < DNS_DISPATCH_PORTTABLESIZE; i++) INSIST(ISC_LIST_EMPTY(disp->port_table[i])); isc_mem_put(mgr->mctx, disp->port_table, sizeof(disp->port_table[0]) * DNS_DISPATCH_PORTTABLESIZE); } if (disp->portpool != NULL) isc_mempool_destroy(&disp->portpool); disp->mgr = NULL; DESTROYLOCK(&disp->lock); disp->magic = 0; isc_mempool_put(mgr->dpool, disp); } isc_result_t dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock, isc_taskmgr_t *taskmgr, unsigned int buffersize, unsigned int maxbuffers, unsigned int maxrequests, unsigned int buckets, unsigned int increment, unsigned int attributes, dns_dispatch_t **dispp) { isc_result_t result; dns_dispatch_t *disp; UNUSED(maxbuffers); UNUSED(buffersize); REQUIRE(VALID_DISPATCHMGR(mgr)); REQUIRE(isc_socket_gettype(sock) == isc_sockettype_tcp); REQUIRE((attributes & DNS_DISPATCHATTR_TCP) != 0); REQUIRE((attributes & DNS_DISPATCHATTR_UDP) == 0); attributes |= DNS_DISPATCHATTR_PRIVATE; /* XXXMLG */ LOCK(&mgr->lock); /* * dispatch_allocate() checks mgr for us. * qid_allocate() checks buckets and increment for us. */ disp = NULL; result = dispatch_allocate(mgr, maxrequests, &disp); if (result != ISC_R_SUCCESS) { UNLOCK(&mgr->lock); return (result); } result = qid_allocate(mgr, buckets, increment, &disp->qid, ISC_FALSE); if (result != ISC_R_SUCCESS) goto deallocate_dispatch; disp->socktype = isc_sockettype_tcp; disp->socket = NULL; isc_socket_attach(sock, &disp->socket); disp->sepool = NULL; disp->ntasks = 1; disp->task[0] = NULL; result = isc_task_create(taskmgr, 0, &disp->task[0]); if (result != ISC_R_SUCCESS) goto kill_socket; disp->ctlevent = isc_event_allocate(mgr->mctx, disp, DNS_EVENT_DISPATCHCONTROL, destroy_disp, disp, sizeof(isc_event_t)); if (disp->ctlevent == NULL) { result = ISC_R_NOMEMORY; goto kill_task; } isc_task_setname(disp->task[0], "tcpdispatch", disp); dns_tcpmsg_init(mgr->mctx, disp->socket, &disp->tcpmsg); disp->tcpmsg_valid = 1; disp->attributes = attributes; /* * Append it to the dispatcher list. */ ISC_LIST_APPEND(mgr->list, disp, link); UNLOCK(&mgr->lock); mgr_log(mgr, LVL(90), "created TCP dispatcher %p", disp); dispatch_log(disp, LVL(90), "created task %p", disp->task[0]); *dispp = disp; return (ISC_R_SUCCESS); /* * Error returns. */ kill_task: isc_task_detach(&disp->task[0]); kill_socket: isc_socket_detach(&disp->socket); deallocate_dispatch: dispatch_free(&disp); UNLOCK(&mgr->lock); return (result); } isc_result_t dns_dispatch_getudp_dup(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr, unsigned int buffersize, unsigned int maxbuffers, unsigned int maxrequests, unsigned int buckets, unsigned int increment, unsigned int attributes, unsigned int mask, dns_dispatch_t **dispp, dns_dispatch_t *dup_dispatch) { isc_result_t result; dns_dispatch_t *disp = NULL; REQUIRE(VALID_DISPATCHMGR(mgr)); REQUIRE(sockmgr != NULL); REQUIRE(localaddr != NULL); REQUIRE(taskmgr != NULL); REQUIRE(buffersize >= 512 && buffersize < (64 * 1024)); REQUIRE(maxbuffers > 0); REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */ REQUIRE(increment > buckets); REQUIRE(dispp != NULL && *dispp == NULL); REQUIRE((attributes & DNS_DISPATCHATTR_TCP) == 0); result = dns_dispatchmgr_setudp(mgr, buffersize, maxbuffers, maxrequests, buckets, increment); if (result != ISC_R_SUCCESS) return (result); LOCK(&mgr->lock); if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) { REQUIRE(isc_sockaddr_getport(localaddr) == 0); goto createudp; } /* * See if we have a dispatcher that matches. */ if (dup_dispatch == NULL) { result = dispatch_find(mgr, localaddr, attributes, mask, &disp); if (result == ISC_R_SUCCESS) { disp->refcount++; if (disp->maxrequests < maxrequests) disp->maxrequests = maxrequests; if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) == 0 && (attributes & DNS_DISPATCHATTR_NOLISTEN) != 0) { disp->attributes |= DNS_DISPATCHATTR_NOLISTEN; if (disp->recv_pending != 0) isc_socket_cancel(disp->socket, disp->task[0], ISC_SOCKCANCEL_RECV); } UNLOCK(&disp->lock); UNLOCK(&mgr->lock); *dispp = disp; return (ISC_R_SUCCESS); } } createudp: /* * Nope, create one. */ result = dispatch_createudp(mgr, sockmgr, taskmgr, localaddr, maxrequests, attributes, &disp, dup_dispatch == NULL ? NULL : dup_dispatch->socket); if (result != ISC_R_SUCCESS) { UNLOCK(&mgr->lock); return (result); } UNLOCK(&mgr->lock); *dispp = disp; return (ISC_R_SUCCESS); } isc_result_t dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr, unsigned int buffersize, unsigned int maxbuffers, unsigned int maxrequests, unsigned int buckets, unsigned int increment, unsigned int attributes, unsigned int mask, dns_dispatch_t **dispp) { return (dns_dispatch_getudp_dup(mgr, sockmgr, taskmgr, localaddr, buffersize, maxbuffers, maxrequests, buckets, increment, attributes, mask, dispp, NULL)); } /* * mgr should be locked. */ #ifndef DNS_DISPATCH_HELD #define DNS_DISPATCH_HELD 20U #endif static isc_result_t get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp, isc_socketmgr_t *sockmgr, isc_sockaddr_t *localaddr, isc_socket_t **sockp, isc_socket_t *dup_socket) { unsigned int i, j; isc_socket_t *held[DNS_DISPATCH_HELD]; isc_sockaddr_t localaddr_bound; isc_socket_t *sock = NULL; isc_result_t result = ISC_R_SUCCESS; isc_boolean_t anyport; INSIST(sockp != NULL && *sockp == NULL); localaddr_bound = *localaddr; anyport = ISC_TF(isc_sockaddr_getport(localaddr) == 0); if (anyport) { unsigned int nports; in_port_t *ports; /* * If no port is specified, we first try to pick up a random * port by ourselves. */ if (isc_sockaddr_pf(localaddr) == AF_INET) { nports = disp->mgr->nv4ports; ports = disp->mgr->v4ports; } else { nports = disp->mgr->nv6ports; ports = disp->mgr->v6ports; } if (nports == 0) return (ISC_R_ADDRNOTAVAIL); for (i = 0; i < 1024; i++) { in_port_t prt; prt = ports[dispatch_uniformrandom( DISP_ARC4CTX(disp), nports)]; isc_sockaddr_setport(&localaddr_bound, prt); result = open_socket(sockmgr, &localaddr_bound, 0, &sock, NULL); /* * Continue if the port choosen is already in use * or the OS has reserved it. */ if (result == ISC_R_NOPERM || result == ISC_R_ADDRINUSE) continue; disp->localport = prt; *sockp = sock; return (result); } /* * If this fails 1024 times, we then ask the kernel for * choosing one. */ } else { /* Allow to reuse address for non-random ports. */ result = open_socket(sockmgr, localaddr, ISC_SOCKET_REUSEADDRESS, &sock, dup_socket); if (result == ISC_R_SUCCESS) *sockp = sock; return (result); } memset(held, 0, sizeof(held)); i = 0; for (j = 0; j < 0xffffU; j++) { result = open_socket(sockmgr, localaddr, 0, &sock, NULL); if (result != ISC_R_SUCCESS) goto end; else if (portavailable(mgr, sock, NULL)) break; if (held[i] != NULL) isc_socket_detach(&held[i]); held[i++] = sock; sock = NULL; if (i == DNS_DISPATCH_HELD) i = 0; } if (j == 0xffffU) { mgr_log(mgr, ISC_LOG_ERROR, "avoid-v%s-udp-ports: unable to allocate " "an available port", isc_sockaddr_pf(localaddr) == AF_INET ? "4" : "6"); result = ISC_R_FAILURE; goto end; } *sockp = sock; end: for (i = 0; i < DNS_DISPATCH_HELD; i++) { if (held[i] != NULL) isc_socket_detach(&held[i]); } return (result); } static isc_result_t dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr, unsigned int maxrequests, unsigned int attributes, dns_dispatch_t **dispp, isc_socket_t *dup_socket) { isc_result_t result; dns_dispatch_t *disp; isc_socket_t *sock = NULL; int i = 0; /* * dispatch_allocate() checks mgr for us. */ disp = NULL; result = dispatch_allocate(mgr, maxrequests, &disp); if (result != ISC_R_SUCCESS) return (result); disp->socktype = isc_sockettype_udp; if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0) { result = get_udpsocket(mgr, disp, sockmgr, localaddr, &sock, dup_socket); if (result != ISC_R_SUCCESS) goto deallocate_dispatch; if (isc_log_wouldlog(dns_lctx, 90)) { char addrbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(localaddr, addrbuf, ISC_SOCKADDR_FORMATSIZE); mgr_log(mgr, LVL(90), "dns_dispatch_createudp: Created" " UDP dispatch for %s with socket fd %d\n", addrbuf, isc_socket_getfd(sock)); } } else { isc_sockaddr_t sa_any; /* * For dispatches using exclusive sockets with a specific * source address, we only check if the specified address is * available on the system. Query sockets will be created later * on demand. */ isc_sockaddr_anyofpf(&sa_any, isc_sockaddr_pf(localaddr)); if (!isc_sockaddr_eqaddr(&sa_any, localaddr)) { result = open_socket(sockmgr, localaddr, 0, &sock, NULL); if (sock != NULL) isc_socket_detach(&sock); if (result != ISC_R_SUCCESS) goto deallocate_dispatch; } disp->port_table = isc_mem_get(mgr->mctx, sizeof(disp->port_table[0]) * DNS_DISPATCH_PORTTABLESIZE); if (disp->port_table == NULL) goto deallocate_dispatch; for (i = 0; i < DNS_DISPATCH_PORTTABLESIZE; i++) ISC_LIST_INIT(disp->port_table[i]); result = isc_mempool_create(mgr->mctx, sizeof(dispportentry_t), &disp->portpool); if (result != ISC_R_SUCCESS) goto deallocate_dispatch; isc_mempool_setname(disp->portpool, "disp_portpool"); isc_mempool_setfreemax(disp->portpool, 128); } disp->socket = sock; disp->local = *localaddr; if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) disp->ntasks = MAX_INTERNAL_TASKS; else disp->ntasks = 1; for (i = 0; i < disp->ntasks; i++) { disp->task[i] = NULL; result = isc_task_create(taskmgr, 0, &disp->task[i]); if (result != ISC_R_SUCCESS) { while (--i >= 0) { isc_task_shutdown(disp->task[i]); isc_task_detach(&disp->task[i]); } goto kill_socket; } isc_task_setname(disp->task[i], "udpdispatch", disp); } disp->ctlevent = isc_event_allocate(mgr->mctx, disp, DNS_EVENT_DISPATCHCONTROL, destroy_disp, disp, sizeof(isc_event_t)); if (disp->ctlevent == NULL) { result = ISC_R_NOMEMORY; goto kill_task; } disp->sepool = NULL; if (isc_mempool_create(mgr->mctx, sizeof(isc_socketevent_t), &disp->sepool) != ISC_R_SUCCESS) { result = ISC_R_NOMEMORY; goto kill_ctlevent; } result = isc_mutex_init(&disp->sepool_lock); if (result != ISC_R_SUCCESS) goto kill_sepool; isc_mempool_setname(disp->sepool, "disp_sepool"); isc_mempool_setmaxalloc(disp->sepool, 32768); isc_mempool_setfreemax(disp->sepool, 32768); isc_mempool_associatelock(disp->sepool, &disp->sepool_lock); isc_mempool_setfillcount(disp->sepool, 16); attributes &= ~DNS_DISPATCHATTR_TCP; attributes |= DNS_DISPATCHATTR_UDP; disp->attributes = attributes; /* * Append it to the dispatcher list. */ ISC_LIST_APPEND(mgr->list, disp, link); mgr_log(mgr, LVL(90), "created UDP dispatcher %p", disp); dispatch_log(disp, LVL(90), "created task %p", disp->task[0]); /* XXX */ if (disp->socket != NULL) dispatch_log(disp, LVL(90), "created socket %p", disp->socket); *dispp = disp; return (result); /* * Error returns. */ kill_sepool: isc_mempool_destroy(&disp->sepool); kill_ctlevent: isc_event_free(&disp->ctlevent); kill_task: for (i = 0; i < disp->ntasks; i++) isc_task_detach(&disp->task[i]); kill_socket: if (disp->socket != NULL) isc_socket_detach(&disp->socket); deallocate_dispatch: dispatch_free(&disp); return (result); } void dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp) { REQUIRE(VALID_DISPATCH(disp)); REQUIRE(dispp != NULL && *dispp == NULL); LOCK(&disp->lock); disp->refcount++; UNLOCK(&disp->lock); *dispp = disp; } /* * It is important to lock the manager while we are deleting the dispatch, * since dns_dispatch_getudp will call dispatch_find, which returns to * the caller a dispatch but does not attach to it until later. _getudp * locks the manager, however, so locking it here will keep us from attaching * to a dispatcher that is in the process of going away. */ void dns_dispatch_detach(dns_dispatch_t **dispp) { dns_dispatch_t *disp; dispsocket_t *dispsock; isc_boolean_t killit; REQUIRE(dispp != NULL && VALID_DISPATCH(*dispp)); disp = *dispp; *dispp = NULL; LOCK(&disp->lock); INSIST(disp->refcount > 0); disp->refcount--; if (disp->refcount == 0) { if (disp->recv_pending > 0) isc_socket_cancel(disp->socket, disp->task[0], ISC_SOCKCANCEL_RECV); for (dispsock = ISC_LIST_HEAD(disp->activesockets); dispsock != NULL; dispsock = ISC_LIST_NEXT(dispsock, link)) { isc_socket_cancel(dispsock->socket, dispsock->task, ISC_SOCKCANCEL_RECV); } disp->shutting_down = 1; } dispatch_log(disp, LVL(90), "detach: refcount %d", disp->refcount); killit = destroy_disp_ok(disp); UNLOCK(&disp->lock); if (killit) isc_task_send(disp->task[0], &disp->ctlevent); } isc_result_t dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest, isc_task_t *task, isc_taskaction_t action, void *arg, dns_messageid_t *idp, dns_dispentry_t **resp, isc_socketmgr_t *sockmgr) { return (dns_dispatch_addresponse3(disp, 0, dest, task, action, arg, idp, resp, sockmgr)); } isc_result_t dns_dispatch_addresponse3(dns_dispatch_t *disp, unsigned int options, isc_sockaddr_t *dest, isc_task_t *task, isc_taskaction_t action, void *arg, dns_messageid_t *idp, dns_dispentry_t **resp, isc_socketmgr_t *sockmgr) { dns_dispentry_t *res; unsigned int bucket; in_port_t localport = 0; dns_messageid_t id; int i; isc_boolean_t ok; dns_qid_t *qid; dispsocket_t *dispsocket = NULL; isc_result_t result; REQUIRE(VALID_DISPATCH(disp)); REQUIRE(task != NULL); REQUIRE(dest != NULL); REQUIRE(resp != NULL && *resp == NULL); REQUIRE(idp != NULL); if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) REQUIRE(sockmgr != NULL); LOCK(&disp->lock); if (disp->shutting_down == 1) { UNLOCK(&disp->lock); return (ISC_R_SHUTTINGDOWN); } if (disp->requests >= disp->maxrequests) { UNLOCK(&disp->lock); return (ISC_R_QUOTA); } if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0 && disp->nsockets > DNS_DISPATCH_SOCKSQUOTA) { dispsocket_t *oldestsocket; dns_dispentry_t *oldestresp; dns_dispatchevent_t *rev; /* * Kill oldest outstanding query if the number of sockets * exceeds the quota to keep the room for new queries. */ oldestsocket = ISC_LIST_HEAD(disp->activesockets); oldestresp = oldestsocket->resp; if (oldestresp != NULL && !oldestresp->item_out) { rev = allocate_devent(oldestresp->disp); if (rev != NULL) { rev->buffer.base = NULL; rev->result = ISC_R_CANCELED; rev->id = oldestresp->id; ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL, DNS_EVENT_DISPATCH, oldestresp->action, oldestresp->arg, oldestresp, NULL, NULL); oldestresp->item_out = ISC_TRUE; isc_task_send(oldestresp->task, ISC_EVENT_PTR(&rev)); inc_stats(disp->mgr, dns_resstatscounter_dispabort); } } /* * Move this entry to the tail so that it won't (easily) be * examined before actually being canceled. */ ISC_LIST_UNLINK(disp->activesockets, oldestsocket, link); ISC_LIST_APPEND(disp->activesockets, oldestsocket, link); } qid = DNS_QID(disp); if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) { /* * Get a separate UDP socket with a random port number. */ result = get_dispsocket(disp, dest, sockmgr, &dispsocket, &localport); if (result != ISC_R_SUCCESS) { UNLOCK(&disp->lock); inc_stats(disp->mgr, dns_resstatscounter_dispsockfail); return (result); } } else { localport = disp->localport; } /* * Try somewhat hard to find an unique ID unless FIXEDID is set * in which case we use the id passed in via *idp. */ LOCK(&qid->lock); if ((options & DNS_DISPATCHOPT_FIXEDID) != 0) id = *idp; else id = (dns_messageid_t)dispatch_random(DISP_ARC4CTX(disp)); ok = ISC_FALSE; i = 0; do { bucket = dns_hash(qid, dest, id, localport); if (entry_search(qid, dest, id, localport, bucket) == NULL) { ok = ISC_TRUE; break; } if ((disp->attributes & DNS_DISPATCHATTR_FIXEDID) != 0) break; id += qid->qid_increment; id &= 0x0000ffff; } while (i++ < 64); UNLOCK(&qid->lock); if (!ok) { UNLOCK(&disp->lock); return (ISC_R_NOMORE); } res = isc_mempool_get(disp->mgr->rpool); if (res == NULL) { if (dispsocket != NULL) destroy_dispsocket(disp, &dispsocket); UNLOCK(&disp->lock); return (ISC_R_NOMEMORY); } disp->refcount++; disp->requests++; res->task = NULL; isc_task_attach(task, &res->task); res->disp = disp; res->id = id; res->port = localport; res->bucket = bucket; res->host = *dest; res->action = action; res->arg = arg; res->dispsocket = dispsocket; if (dispsocket != NULL) dispsocket->resp = res; res->item_out = ISC_FALSE; ISC_LIST_INIT(res->items); ISC_LINK_INIT(res, link); res->magic = RESPONSE_MAGIC; LOCK(&qid->lock); ISC_LIST_APPEND(qid->qid_table[bucket], res, link); UNLOCK(&qid->lock); inc_stats(disp->mgr, (qid == disp->mgr->qid) ? dns_resstatscounter_disprequdp : dns_resstatscounter_dispreqtcp); request_log(disp, res, LVL(90), "attached to task %p", res->task); if (((disp->attributes & DNS_DISPATCHATTR_UDP) != 0) || ((disp->attributes & DNS_DISPATCHATTR_CONNECTED) != 0)) { result = startrecv(disp, dispsocket); if (result != ISC_R_SUCCESS) { LOCK(&qid->lock); ISC_LIST_UNLINK(qid->qid_table[bucket], res, link); UNLOCK(&qid->lock); if (dispsocket != NULL) destroy_dispsocket(disp, &dispsocket); disp->refcount--; disp->requests--; dec_stats(disp->mgr, (qid == disp->mgr->qid) ? dns_resstatscounter_disprequdp : dns_resstatscounter_dispreqtcp); UNLOCK(&disp->lock); isc_task_detach(&res->task); isc_mempool_put(disp->mgr->rpool, res); return (result); } } if (dispsocket != NULL) ISC_LIST_APPEND(disp->activesockets, dispsocket, link); UNLOCK(&disp->lock); *idp = id; *resp = res; if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) INSIST(res->dispsocket != NULL); return (ISC_R_SUCCESS); } isc_result_t dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest, isc_task_t *task, isc_taskaction_t action, void *arg, dns_messageid_t *idp, dns_dispentry_t **resp) { REQUIRE(VALID_DISPATCH(disp)); REQUIRE((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0); return (dns_dispatch_addresponse3(disp, 0, dest, task, action, arg, idp, resp, NULL)); } void dns_dispatch_starttcp(dns_dispatch_t *disp) { REQUIRE(VALID_DISPATCH(disp)); dispatch_log(disp, LVL(90), "starttcp %p", disp->task[0]); LOCK(&disp->lock); disp->attributes |= DNS_DISPATCHATTR_CONNECTED; (void)startrecv(disp, NULL); UNLOCK(&disp->lock); } void dns_dispatch_removeresponse(dns_dispentry_t **resp, dns_dispatchevent_t **sockevent) { dns_dispatchmgr_t *mgr; dns_dispatch_t *disp; dns_dispentry_t *res; dispsocket_t *dispsock; dns_dispatchevent_t *ev; unsigned int bucket; isc_boolean_t killit; unsigned int n; isc_eventlist_t events; dns_qid_t *qid; REQUIRE(resp != NULL); REQUIRE(VALID_RESPONSE(*resp)); res = *resp; *resp = NULL; disp = res->disp; REQUIRE(VALID_DISPATCH(disp)); mgr = disp->mgr; REQUIRE(VALID_DISPATCHMGR(mgr)); qid = DNS_QID(disp); if (sockevent != NULL) { REQUIRE(*sockevent != NULL); ev = *sockevent; *sockevent = NULL; } else { ev = NULL; } LOCK(&disp->lock); INSIST(disp->requests > 0); disp->requests--; dec_stats(disp->mgr, (qid == disp->mgr->qid) ? dns_resstatscounter_disprequdp : dns_resstatscounter_dispreqtcp); INSIST(disp->refcount > 0); disp->refcount--; if (disp->refcount == 0) { if (disp->recv_pending > 0) isc_socket_cancel(disp->socket, disp->task[0], ISC_SOCKCANCEL_RECV); for (dispsock = ISC_LIST_HEAD(disp->activesockets); dispsock != NULL; dispsock = ISC_LIST_NEXT(dispsock, link)) { isc_socket_cancel(dispsock->socket, dispsock->task, ISC_SOCKCANCEL_RECV); } disp->shutting_down = 1; } bucket = res->bucket; LOCK(&qid->lock); ISC_LIST_UNLINK(qid->qid_table[bucket], res, link); UNLOCK(&qid->lock); if (ev == NULL && res->item_out) { /* * We've posted our event, but the caller hasn't gotten it * yet. Take it back. */ ISC_LIST_INIT(events); n = isc_task_unsend(res->task, res, DNS_EVENT_DISPATCH, NULL, &events); /* * We had better have gotten it back. */ INSIST(n == 1); ev = (dns_dispatchevent_t *)ISC_LIST_HEAD(events); } if (ev != NULL) { REQUIRE(res->item_out == ISC_TRUE); res->item_out = ISC_FALSE; if (ev->buffer.base != NULL) free_buffer(disp, ev->buffer.base, ev->buffer.length); free_devent(disp, ev); } request_log(disp, res, LVL(90), "detaching from task %p", res->task); isc_task_detach(&res->task); if (res->dispsocket != NULL) { isc_socket_cancel(res->dispsocket->socket, res->dispsocket->task, ISC_SOCKCANCEL_RECV); res->dispsocket->resp = NULL; } /* * Free any buffered requests as well */ ev = ISC_LIST_HEAD(res->items); while (ev != NULL) { ISC_LIST_UNLINK(res->items, ev, ev_link); if (ev->buffer.base != NULL) free_buffer(disp, ev->buffer.base, ev->buffer.length); free_devent(disp, ev); ev = ISC_LIST_HEAD(res->items); } res->magic = 0; isc_mempool_put(disp->mgr->rpool, res); if (disp->shutting_down == 1) do_cancel(disp); else (void)startrecv(disp, NULL); killit = destroy_disp_ok(disp); UNLOCK(&disp->lock); if (killit) isc_task_send(disp->task[0], &disp->ctlevent); } static void do_cancel(dns_dispatch_t *disp) { dns_dispatchevent_t *ev; dns_dispentry_t *resp; dns_qid_t *qid; if (disp->shutdown_out == 1) return; qid = DNS_QID(disp); /* * Search for the first response handler without packets outstanding * unless a specific hander is given. */ LOCK(&qid->lock); for (resp = linear_first(qid); resp != NULL && resp->item_out; /* Empty. */) resp = linear_next(qid, resp); /* * No one to send the cancel event to, so nothing to do. */ if (resp == NULL) goto unlock; /* * Send the shutdown failsafe event to this resp. */ ev = disp->failsafe_ev; ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, DNS_EVENT_DISPATCH, resp->action, resp->arg, resp, NULL, NULL); ev->result = disp->shutdown_why; ev->buffer.base = NULL; ev->buffer.length = 0; disp->shutdown_out = 1; request_log(disp, resp, LVL(10), "cancel: failsafe event %p -> task %p", ev, resp->task); resp->item_out = ISC_TRUE; isc_task_send(resp->task, ISC_EVENT_PTR(&ev)); unlock: UNLOCK(&qid->lock); } isc_socket_t * dns_dispatch_getsocket(dns_dispatch_t *disp) { REQUIRE(VALID_DISPATCH(disp)); return (disp->socket); } isc_socket_t * dns_dispatch_getentrysocket(dns_dispentry_t *resp) { REQUIRE(VALID_RESPONSE(resp)); if (resp->dispsocket != NULL) return (resp->dispsocket->socket); else return (NULL); } isc_result_t dns_dispatch_getlocaladdress(dns_dispatch_t *disp, isc_sockaddr_t *addrp) { REQUIRE(VALID_DISPATCH(disp)); REQUIRE(addrp != NULL); if (disp->socktype == isc_sockettype_udp) { *addrp = disp->local; return (ISC_R_SUCCESS); } return (ISC_R_NOTIMPLEMENTED); } void dns_dispatch_cancel(dns_dispatch_t *disp) { REQUIRE(VALID_DISPATCH(disp)); LOCK(&disp->lock); if (disp->shutting_down == 1) { UNLOCK(&disp->lock); return; } disp->shutdown_why = ISC_R_CANCELED; disp->shutting_down = 1; do_cancel(disp); UNLOCK(&disp->lock); return; } unsigned int dns_dispatch_getattributes(dns_dispatch_t *disp) { REQUIRE(VALID_DISPATCH(disp)); /* * We don't bother locking disp here; it's the caller's responsibility * to use only non volatile flags. */ return (disp->attributes); } void dns_dispatch_changeattributes(dns_dispatch_t *disp, unsigned int attributes, unsigned int mask) { REQUIRE(VALID_DISPATCH(disp)); /* Exclusive attribute can only be set on creation */ REQUIRE((attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0); /* Also, a dispatch with randomport specified cannot start listening */ REQUIRE((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0 || (attributes & DNS_DISPATCHATTR_NOLISTEN) == 0); /* XXXMLG * Should check for valid attributes here! */ LOCK(&disp->lock); if ((mask & DNS_DISPATCHATTR_NOLISTEN) != 0) { if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0 && (attributes & DNS_DISPATCHATTR_NOLISTEN) == 0) { disp->attributes &= ~DNS_DISPATCHATTR_NOLISTEN; (void)startrecv(disp, NULL); } else if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) == 0 && (attributes & DNS_DISPATCHATTR_NOLISTEN) != 0) { disp->attributes |= DNS_DISPATCHATTR_NOLISTEN; if (disp->recv_pending != 0) isc_socket_cancel(disp->socket, disp->task[0], ISC_SOCKCANCEL_RECV); } } disp->attributes &= ~mask; disp->attributes |= (attributes & mask); UNLOCK(&disp->lock); } void dns_dispatch_importrecv(dns_dispatch_t *disp, isc_event_t *event) { void *buf; isc_socketevent_t *sevent, *newsevent; REQUIRE(VALID_DISPATCH(disp)); REQUIRE((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0); REQUIRE(event != NULL); sevent = (isc_socketevent_t *)event; INSIST(sevent->n <= disp->mgr->buffersize); newsevent = (isc_socketevent_t *) isc_event_allocate(disp->mgr->mctx, NULL, DNS_EVENT_IMPORTRECVDONE, udp_shrecv, disp, sizeof(isc_socketevent_t)); if (newsevent == NULL) return; buf = allocate_udp_buffer(disp); if (buf == NULL) { isc_event_free(ISC_EVENT_PTR(&newsevent)); return; } memmove(buf, sevent->region.base, sevent->n); newsevent->region.base = buf; newsevent->region.length = disp->mgr->buffersize; newsevent->n = sevent->n; newsevent->result = sevent->result; newsevent->address = sevent->address; newsevent->timestamp = sevent->timestamp; newsevent->pktinfo = sevent->pktinfo; newsevent->attributes = sevent->attributes; isc_task_send(disp->task[0], ISC_EVENT_PTR(&newsevent)); } dns_dispatch_t * dns_dispatchset_get(dns_dispatchset_t *dset) { dns_dispatch_t *disp; /* check that dispatch set is configured */ if (dset == NULL || dset->ndisp == 0) return (NULL); LOCK(&dset->lock); disp = dset->dispatches[dset->cur]; dset->cur++; if (dset->cur == dset->ndisp) dset->cur = 0; UNLOCK(&dset->lock); return (disp); } isc_result_t dns_dispatchset_create(isc_mem_t *mctx, isc_socketmgr_t *sockmgr, isc_taskmgr_t *taskmgr, dns_dispatch_t *source, dns_dispatchset_t **dsetp, int n) { isc_result_t result; dns_dispatchset_t *dset; dns_dispatchmgr_t *mgr; int i, j; REQUIRE(VALID_DISPATCH(source)); REQUIRE((source->attributes & DNS_DISPATCHATTR_UDP) != 0); REQUIRE(dsetp != NULL && *dsetp == NULL); mgr = source->mgr; dset = isc_mem_get(mctx, sizeof(dns_dispatchset_t)); if (dset == NULL) return (ISC_R_NOMEMORY); memset(dset, 0, sizeof(*dset)); result = isc_mutex_init(&dset->lock); if (result != ISC_R_SUCCESS) goto fail_alloc; dset->dispatches = isc_mem_get(mctx, sizeof(dns_dispatch_t *) * n); if (dset->dispatches == NULL) { result = ISC_R_NOMEMORY; goto fail_lock; } isc_mem_attach(mctx, &dset->mctx); dset->ndisp = n; dset->cur = 0; dset->dispatches[0] = NULL; dns_dispatch_attach(source, &dset->dispatches[0]); LOCK(&mgr->lock); for (i = 1; i < n; i++) { dset->dispatches[i] = NULL; result = dispatch_createudp(mgr, sockmgr, taskmgr, &source->local, source->maxrequests, source->attributes, &dset->dispatches[i], source->socket); if (result != ISC_R_SUCCESS) goto fail; } UNLOCK(&mgr->lock); *dsetp = dset; return (ISC_R_SUCCESS); fail: UNLOCK(&mgr->lock); for (j = 0; j < i; j++) dns_dispatch_detach(&(dset->dispatches[j])); isc_mem_put(mctx, dset->dispatches, sizeof(dns_dispatch_t *) * n); if (dset->mctx == mctx) isc_mem_detach(&dset->mctx); fail_lock: DESTROYLOCK(&dset->lock); fail_alloc: isc_mem_put(mctx, dset, sizeof(dns_dispatchset_t)); return (result); } void dns_dispatchset_cancelall(dns_dispatchset_t *dset, isc_task_t *task) { int i; REQUIRE(dset != NULL); for (i = 0; i < dset->ndisp; i++) { isc_socket_t *sock; sock = dns_dispatch_getsocket(dset->dispatches[i]); isc_socket_cancel(sock, task, ISC_SOCKCANCEL_ALL); } } void dns_dispatchset_destroy(dns_dispatchset_t **dsetp) { dns_dispatchset_t *dset; int i; REQUIRE(dsetp != NULL && *dsetp != NULL); dset = *dsetp; for (i = 0; i < dset->ndisp; i++) dns_dispatch_detach(&(dset->dispatches[i])); isc_mem_put(dset->mctx, dset->dispatches, sizeof(dns_dispatch_t *) * dset->ndisp); DESTROYLOCK(&dset->lock); isc_mem_putanddetach(&dset->mctx, dset, sizeof(dns_dispatchset_t)); *dsetp = NULL; } void dns_dispatch_setdscp(dns_dispatch_t *disp, isc_dscp_t dscp) { REQUIRE(VALID_DISPATCH(disp)); disp->dscp = dscp; } isc_dscp_t dns_dispatch_getdscp(dns_dispatch_t *disp) { REQUIRE(VALID_DISPATCH(disp)); return (disp->dscp); } #if 0 void dns_dispatchmgr_dump(dns_dispatchmgr_t *mgr) { dns_dispatch_t *disp; char foo[1024]; disp = ISC_LIST_HEAD(mgr->list); while (disp != NULL) { isc_sockaddr_format(&disp->local, foo, sizeof(foo)); printf("\tdispatch %p, addr %s\n", disp, foo); disp = ISC_LIST_NEXT(disp, link); } } #endif bind9-9.10.3.dfsg.P4/lib/dns/request.c0000644000470500017500000012350412664710322016564 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define REQUESTMGR_MAGIC ISC_MAGIC('R', 'q', 'u', 'M') #define VALID_REQUESTMGR(mgr) ISC_MAGIC_VALID(mgr, REQUESTMGR_MAGIC) #define REQUEST_MAGIC ISC_MAGIC('R', 'q', 'u', '!') #define VALID_REQUEST(request) ISC_MAGIC_VALID(request, REQUEST_MAGIC) typedef ISC_LIST(dns_request_t) dns_requestlist_t; #define DNS_REQUEST_NLOCKS 7 struct dns_requestmgr { unsigned int magic; isc_mutex_t lock; isc_mem_t *mctx; /* locked */ isc_int32_t eref; isc_int32_t iref; isc_timermgr_t *timermgr; isc_socketmgr_t *socketmgr; isc_taskmgr_t *taskmgr; dns_dispatchmgr_t *dispatchmgr; dns_dispatch_t *dispatchv4; dns_dispatch_t *dispatchv6; isc_boolean_t exiting; isc_eventlist_t whenshutdown; unsigned int hash; isc_mutex_t locks[DNS_REQUEST_NLOCKS]; dns_requestlist_t requests; }; struct dns_request { unsigned int magic; unsigned int hash; isc_mem_t *mctx; isc_int32_t flags; ISC_LINK(dns_request_t) link; isc_buffer_t *query; isc_buffer_t *answer; dns_requestevent_t *event; dns_dispatch_t *dispatch; dns_dispentry_t *dispentry; isc_timer_t *timer; dns_requestmgr_t *requestmgr; isc_buffer_t *tsig; dns_tsigkey_t *tsigkey; isc_event_t ctlevent; isc_boolean_t canceling; /* ctlevent outstanding */ isc_sockaddr_t destaddr; unsigned int udpcount; isc_dscp_t dscp; }; #define DNS_REQUEST_F_CONNECTING 0x0001 #define DNS_REQUEST_F_SENDING 0x0002 #define DNS_REQUEST_F_CANCELED 0x0004 /*%< ctlevent received, or otherwise synchronously canceled */ #define DNS_REQUEST_F_TIMEDOUT 0x0008 /*%< canceled due to a timeout */ #define DNS_REQUEST_F_TCP 0x0010 /*%< This request used TCP */ #define DNS_REQUEST_CANCELED(r) \ (((r)->flags & DNS_REQUEST_F_CANCELED) != 0) #define DNS_REQUEST_CONNECTING(r) \ (((r)->flags & DNS_REQUEST_F_CONNECTING) != 0) #define DNS_REQUEST_SENDING(r) \ (((r)->flags & DNS_REQUEST_F_SENDING) != 0) #define DNS_REQUEST_TIMEDOUT(r) \ (((r)->flags & DNS_REQUEST_F_TIMEDOUT) != 0) /*** *** Forward ***/ static void mgr_destroy(dns_requestmgr_t *requestmgr); static void mgr_shutdown(dns_requestmgr_t *requestmgr); static unsigned int mgr_gethash(dns_requestmgr_t *requestmgr); static void send_shutdown_events(dns_requestmgr_t *requestmgr); static isc_result_t req_render(dns_message_t *message, isc_buffer_t **buffer, unsigned int options, isc_mem_t *mctx); static void req_senddone(isc_task_t *task, isc_event_t *event); static void req_response(isc_task_t *task, isc_event_t *event); static void req_timeout(isc_task_t *task, isc_event_t *event); static isc_socket_t * req_getsocket(dns_request_t *request); static void req_connected(isc_task_t *task, isc_event_t *event); static void req_sendevent(dns_request_t *request, isc_result_t result); static void req_cancel(dns_request_t *request); static void req_destroy(dns_request_t *request); static void req_log(int level, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3); static void do_cancel(isc_task_t *task, isc_event_t *event); /*** *** Public ***/ isc_result_t dns_requestmgr_create(isc_mem_t *mctx, isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, isc_taskmgr_t *taskmgr, dns_dispatchmgr_t *dispatchmgr, dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6, dns_requestmgr_t **requestmgrp) { dns_requestmgr_t *requestmgr; isc_socket_t *sock; isc_result_t result; int i; unsigned int dispattr; req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_create"); REQUIRE(requestmgrp != NULL && *requestmgrp == NULL); REQUIRE(timermgr != NULL); REQUIRE(socketmgr != NULL); REQUIRE(taskmgr != NULL); REQUIRE(dispatchmgr != NULL); UNUSED(sock); if (dispatchv4 != NULL) { dispattr = dns_dispatch_getattributes(dispatchv4); REQUIRE((dispattr & DNS_DISPATCHATTR_UDP) != 0); } if (dispatchv6 != NULL) { dispattr = dns_dispatch_getattributes(dispatchv6); REQUIRE((dispattr & DNS_DISPATCHATTR_UDP) != 0); } requestmgr = isc_mem_get(mctx, sizeof(*requestmgr)); if (requestmgr == NULL) return (ISC_R_NOMEMORY); result = isc_mutex_init(&requestmgr->lock); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, requestmgr, sizeof(*requestmgr)); return (result); } for (i = 0; i < DNS_REQUEST_NLOCKS; i++) { result = isc_mutex_init(&requestmgr->locks[i]); if (result != ISC_R_SUCCESS) { while (--i >= 0) DESTROYLOCK(&requestmgr->locks[i]); DESTROYLOCK(&requestmgr->lock); isc_mem_put(mctx, requestmgr, sizeof(*requestmgr)); return (result); } } requestmgr->timermgr = timermgr; requestmgr->socketmgr = socketmgr; requestmgr->taskmgr = taskmgr; requestmgr->dispatchmgr = dispatchmgr; requestmgr->dispatchv4 = NULL; if (dispatchv4 != NULL) dns_dispatch_attach(dispatchv4, &requestmgr->dispatchv4); requestmgr->dispatchv6 = NULL; if (dispatchv6 != NULL) dns_dispatch_attach(dispatchv6, &requestmgr->dispatchv6); requestmgr->mctx = NULL; isc_mem_attach(mctx, &requestmgr->mctx); requestmgr->eref = 1; /* implicit attach */ requestmgr->iref = 0; ISC_LIST_INIT(requestmgr->whenshutdown); ISC_LIST_INIT(requestmgr->requests); requestmgr->exiting = ISC_FALSE; requestmgr->hash = 0; requestmgr->magic = REQUESTMGR_MAGIC; req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_create: %p", requestmgr); *requestmgrp = requestmgr; return (ISC_R_SUCCESS); } void dns_requestmgr_whenshutdown(dns_requestmgr_t *requestmgr, isc_task_t *task, isc_event_t **eventp) { isc_task_t *clone; isc_event_t *event; req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_whenshutdown"); REQUIRE(VALID_REQUESTMGR(requestmgr)); REQUIRE(eventp != NULL); event = *eventp; *eventp = NULL; LOCK(&requestmgr->lock); if (requestmgr->exiting) { /* * We're already shutdown. Send the event. */ event->ev_sender = requestmgr; isc_task_send(task, &event); } else { clone = NULL; isc_task_attach(task, &clone); event->ev_sender = clone; ISC_LIST_APPEND(requestmgr->whenshutdown, event, ev_link); } UNLOCK(&requestmgr->lock); } void dns_requestmgr_shutdown(dns_requestmgr_t *requestmgr) { REQUIRE(VALID_REQUESTMGR(requestmgr)); req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_shutdown: %p", requestmgr); LOCK(&requestmgr->lock); mgr_shutdown(requestmgr); UNLOCK(&requestmgr->lock); } static void mgr_shutdown(dns_requestmgr_t *requestmgr) { dns_request_t *request; /* * Caller holds lock. */ if (!requestmgr->exiting) { requestmgr->exiting = ISC_TRUE; for (request = ISC_LIST_HEAD(requestmgr->requests); request != NULL; request = ISC_LIST_NEXT(request, link)) { dns_request_cancel(request); } if (requestmgr->iref == 0) { INSIST(ISC_LIST_EMPTY(requestmgr->requests)); send_shutdown_events(requestmgr); } } } static void requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp) { /* * Locked by caller. */ REQUIRE(VALID_REQUESTMGR(source)); REQUIRE(targetp != NULL && *targetp == NULL); REQUIRE(!source->exiting); source->iref++; *targetp = source; req_log(ISC_LOG_DEBUG(3), "requestmgr_attach: %p: eref %d iref %d", source, source->eref, source->iref); } static void requestmgr_detach(dns_requestmgr_t **requestmgrp) { dns_requestmgr_t *requestmgr; isc_boolean_t need_destroy = ISC_FALSE; REQUIRE(requestmgrp != NULL); requestmgr = *requestmgrp; REQUIRE(VALID_REQUESTMGR(requestmgr)); *requestmgrp = NULL; LOCK(&requestmgr->lock); INSIST(requestmgr->iref > 0); requestmgr->iref--; req_log(ISC_LOG_DEBUG(3), "requestmgr_detach: %p: eref %d iref %d", requestmgr, requestmgr->eref, requestmgr->iref); if (requestmgr->iref == 0 && requestmgr->exiting) { INSIST(ISC_LIST_HEAD(requestmgr->requests) == NULL); send_shutdown_events(requestmgr); if (requestmgr->eref == 0) need_destroy = ISC_TRUE; } UNLOCK(&requestmgr->lock); if (need_destroy) mgr_destroy(requestmgr); } void dns_requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp) { REQUIRE(VALID_REQUESTMGR(source)); REQUIRE(targetp != NULL && *targetp == NULL); REQUIRE(!source->exiting); LOCK(&source->lock); source->eref++; *targetp = source; UNLOCK(&source->lock); req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_attach: %p: eref %d iref %d", source, source->eref, source->iref); } void dns_requestmgr_detach(dns_requestmgr_t **requestmgrp) { dns_requestmgr_t *requestmgr; isc_boolean_t need_destroy = ISC_FALSE; REQUIRE(requestmgrp != NULL); requestmgr = *requestmgrp; REQUIRE(VALID_REQUESTMGR(requestmgr)); LOCK(&requestmgr->lock); INSIST(requestmgr->eref > 0); requestmgr->eref--; req_log(ISC_LOG_DEBUG(3), "dns_requestmgr_detach: %p: eref %d iref %d", requestmgr, requestmgr->eref, requestmgr->iref); if (requestmgr->eref == 0 && requestmgr->iref == 0) { INSIST(requestmgr->exiting && ISC_LIST_HEAD(requestmgr->requests) == NULL); need_destroy = ISC_TRUE; } UNLOCK(&requestmgr->lock); if (need_destroy) mgr_destroy(requestmgr); *requestmgrp = NULL; } static void send_shutdown_events(dns_requestmgr_t *requestmgr) { isc_event_t *event, *next_event; isc_task_t *etask; req_log(ISC_LOG_DEBUG(3), "send_shutdown_events: %p", requestmgr); /* * Caller must be holding the manager lock. */ for (event = ISC_LIST_HEAD(requestmgr->whenshutdown); event != NULL; event = next_event) { next_event = ISC_LIST_NEXT(event, ev_link); ISC_LIST_UNLINK(requestmgr->whenshutdown, event, ev_link); etask = event->ev_sender; event->ev_sender = requestmgr; isc_task_sendanddetach(&etask, &event); } } static void mgr_destroy(dns_requestmgr_t *requestmgr) { int i; isc_mem_t *mctx; req_log(ISC_LOG_DEBUG(3), "mgr_destroy"); REQUIRE(requestmgr->eref == 0); REQUIRE(requestmgr->iref == 0); DESTROYLOCK(&requestmgr->lock); for (i = 0; i < DNS_REQUEST_NLOCKS; i++) DESTROYLOCK(&requestmgr->locks[i]); if (requestmgr->dispatchv4 != NULL) dns_dispatch_detach(&requestmgr->dispatchv4); if (requestmgr->dispatchv6 != NULL) dns_dispatch_detach(&requestmgr->dispatchv6); requestmgr->magic = 0; mctx = requestmgr->mctx; isc_mem_put(mctx, requestmgr, sizeof(*requestmgr)); isc_mem_detach(&mctx); } static unsigned int mgr_gethash(dns_requestmgr_t *requestmgr) { req_log(ISC_LOG_DEBUG(3), "mgr_gethash"); /* * Locked by caller. */ requestmgr->hash++; return (requestmgr->hash % DNS_REQUEST_NLOCKS); } static inline isc_result_t req_send(dns_request_t *request, isc_task_t *task, isc_sockaddr_t *address) { isc_region_t r; isc_socket_t *sock; isc_socketevent_t *sendevent; isc_result_t result; req_log(ISC_LOG_DEBUG(3), "req_send: request %p", request); REQUIRE(VALID_REQUEST(request)); sock = req_getsocket(request); isc_buffer_usedregion(request->query, &r); /* * We could connect the socket when we are using an exclusive dispatch * as we do in resolver.c, but we prefer implementation simplicity * at this moment. */ sendevent = isc_socket_socketevent(request->mctx, sock, ISC_SOCKEVENT_SENDDONE, req_senddone, request); if (sendevent == NULL) return (ISC_R_NOMEMORY); if (request->dscp == -1) { sendevent->attributes &= ~ISC_SOCKEVENTATTR_DSCP; sendevent->dscp = 0; } else { sendevent->attributes |= ISC_SOCKEVENTATTR_DSCP; sendevent->dscp = request->dscp; } result = isc_socket_sendto2(sock, &r, task, address, NULL, sendevent, 0); if (result == ISC_R_SUCCESS) request->flags |= DNS_REQUEST_F_SENDING; return (result); } static isc_result_t new_request(isc_mem_t *mctx, dns_request_t **requestp) { dns_request_t *request; request = isc_mem_get(mctx, sizeof(*request)); if (request == NULL) return (ISC_R_NOMEMORY); /* * Zero structure. */ request->magic = 0; request->mctx = NULL; request->flags = 0; ISC_LINK_INIT(request, link); request->query = NULL; request->answer = NULL; request->event = NULL; request->dispatch = NULL; request->dispentry = NULL; request->timer = NULL; request->requestmgr = NULL; request->tsig = NULL; request->tsigkey = NULL; request->dscp = -1; ISC_EVENT_INIT(&request->ctlevent, sizeof(request->ctlevent), 0, NULL, DNS_EVENT_REQUESTCONTROL, do_cancel, request, NULL, NULL, NULL); request->canceling = ISC_FALSE; request->udpcount = 0; isc_mem_attach(mctx, &request->mctx); request->magic = REQUEST_MAGIC; *requestp = request; return (ISC_R_SUCCESS); } static isc_boolean_t isblackholed(dns_dispatchmgr_t *dispatchmgr, isc_sockaddr_t *destaddr) { dns_acl_t *blackhole; isc_netaddr_t netaddr; int match; isc_boolean_t drop = ISC_FALSE; char netaddrstr[ISC_NETADDR_FORMATSIZE]; blackhole = dns_dispatchmgr_getblackhole(dispatchmgr); if (blackhole != NULL) { isc_netaddr_fromsockaddr(&netaddr, destaddr); if (dns_acl_match(&netaddr, NULL, blackhole, NULL, &match, NULL) == ISC_R_SUCCESS && match > 0) drop = ISC_TRUE; } if (drop) { isc_netaddr_format(&netaddr, netaddrstr, sizeof(netaddrstr)); req_log(ISC_LOG_DEBUG(10), "blackholed address %s", netaddrstr); } return (drop); } static isc_result_t create_tcp_dispatch(dns_requestmgr_t *requestmgr, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, isc_dscp_t dscp, dns_dispatch_t **dispatchp) { isc_result_t result; isc_socket_t *sock = NULL; isc_sockaddr_t src; unsigned int attrs; isc_sockaddr_t bind_any; result = isc_socket_create(requestmgr->socketmgr, isc_sockaddr_pf(destaddr), isc_sockettype_tcp, &sock); if (result != ISC_R_SUCCESS) return (result); #ifndef BROKEN_TCP_BIND_BEFORE_CONNECT if (srcaddr == NULL) { isc_sockaddr_anyofpf(&bind_any, isc_sockaddr_pf(destaddr)); result = isc_socket_bind(sock, &bind_any, 0); } else { src = *srcaddr; isc_sockaddr_setport(&src, 0); result = isc_socket_bind(sock, &src, 0); } if (result != ISC_R_SUCCESS) goto cleanup; #endif attrs = 0; attrs |= DNS_DISPATCHATTR_TCP; attrs |= DNS_DISPATCHATTR_PRIVATE; if (isc_sockaddr_pf(destaddr) == AF_INET) attrs |= DNS_DISPATCHATTR_IPV4; else attrs |= DNS_DISPATCHATTR_IPV6; attrs |= DNS_DISPATCHATTR_MAKEQUERY; isc_socket_dscp(sock, dscp); result = dns_dispatch_createtcp(requestmgr->dispatchmgr, sock, requestmgr->taskmgr, 4096, 2, 1, 1, 3, attrs, dispatchp); cleanup: isc_socket_detach(&sock); return (result); } static isc_result_t find_udp_dispatch(dns_requestmgr_t *requestmgr, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, dns_dispatch_t **dispatchp) { dns_dispatch_t *disp = NULL; unsigned int attrs, attrmask; if (srcaddr == NULL) { switch (isc_sockaddr_pf(destaddr)) { case PF_INET: disp = requestmgr->dispatchv4; break; case PF_INET6: disp = requestmgr->dispatchv6; break; default: return (ISC_R_NOTIMPLEMENTED); } if (disp == NULL) return (ISC_R_FAMILYNOSUPPORT); dns_dispatch_attach(disp, dispatchp); return (ISC_R_SUCCESS); } attrs = 0; attrs |= DNS_DISPATCHATTR_UDP; switch (isc_sockaddr_pf(srcaddr)) { case PF_INET: attrs |= DNS_DISPATCHATTR_IPV4; break; case PF_INET6: attrs |= DNS_DISPATCHATTR_IPV6; break; default: return (ISC_R_NOTIMPLEMENTED); } attrmask = 0; attrmask |= DNS_DISPATCHATTR_UDP; attrmask |= DNS_DISPATCHATTR_TCP; attrmask |= DNS_DISPATCHATTR_IPV4; attrmask |= DNS_DISPATCHATTR_IPV6; return (dns_dispatch_getudp(requestmgr->dispatchmgr, requestmgr->socketmgr, requestmgr->taskmgr, srcaddr, 4096, 32768, 32768, 16411, 16433, attrs, attrmask, dispatchp)); } static isc_result_t get_dispatch(isc_boolean_t tcp, dns_requestmgr_t *requestmgr, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, isc_dscp_t dscp, dns_dispatch_t **dispatchp) { isc_result_t result; if (tcp) result = create_tcp_dispatch(requestmgr, srcaddr, destaddr, dscp, dispatchp); else result = find_udp_dispatch(requestmgr, srcaddr, destaddr, dispatchp); return (result); } static isc_result_t set_timer(isc_timer_t *timer, unsigned int timeout, unsigned int udpresend) { isc_time_t expires; isc_interval_t interval; isc_result_t result; isc_timertype_t timertype; isc_interval_set(&interval, timeout, 0); result = isc_time_nowplusinterval(&expires, &interval); isc_interval_set(&interval, udpresend, 0); timertype = udpresend != 0 ? isc_timertype_limited : isc_timertype_once; if (result == ISC_R_SUCCESS) result = isc_timer_reset(timer, timertype, &expires, &interval, ISC_FALSE); return (result); } isc_result_t dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, unsigned int options, unsigned int timeout, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp) { return(dns_request_createraw4(requestmgr, msgbuf, srcaddr, destaddr, -1, options, timeout, 0, 0, task, action, arg, requestp)); } isc_result_t dns_request_createraw2(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, unsigned int options, unsigned int timeout, unsigned int udptimeout, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp) { unsigned int udpretries = 0; if (udptimeout != 0) udpretries = timeout / udptimeout; return (dns_request_createraw4(requestmgr, msgbuf, srcaddr, destaddr, -1, options, timeout, udptimeout, udpretries, task, action, arg, requestp)); } isc_result_t dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, unsigned int options, unsigned int timeout, unsigned int udptimeout, unsigned int udpretries, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp) { return (dns_request_createraw4(requestmgr, msgbuf, srcaddr, destaddr, -1, options, timeout, udptimeout, udpretries, task, action, arg, requestp)); } isc_result_t dns_request_createraw4(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, isc_dscp_t dscp, unsigned int options, unsigned int timeout, unsigned int udptimeout, unsigned int udpretries, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp) { dns_request_t *request = NULL; isc_task_t *tclone = NULL; isc_socket_t *sock = NULL; isc_result_t result; isc_mem_t *mctx; dns_messageid_t id; isc_boolean_t tcp = ISC_FALSE; isc_region_t r; unsigned int dispopt = 0; REQUIRE(VALID_REQUESTMGR(requestmgr)); REQUIRE(msgbuf != NULL); REQUIRE(destaddr != NULL); REQUIRE(task != NULL); REQUIRE(action != NULL); REQUIRE(requestp != NULL && *requestp == NULL); REQUIRE(timeout > 0); if (srcaddr != NULL) REQUIRE(isc_sockaddr_pf(srcaddr) == isc_sockaddr_pf(destaddr)); mctx = requestmgr->mctx; req_log(ISC_LOG_DEBUG(3), "dns_request_createraw"); if (isblackholed(requestmgr->dispatchmgr, destaddr)) return (DNS_R_BLACKHOLED); request = NULL; result = new_request(mctx, &request); if (result != ISC_R_SUCCESS) return (result); if (udptimeout == 0 && udpretries != 0) { udptimeout = timeout / (udpretries + 1); if (udptimeout == 0) udptimeout = 1; } request->udpcount = udpretries; request->dscp = dscp; /* * Create timer now. We will set it below once. */ result = isc_timer_create(requestmgr->timermgr, isc_timertype_inactive, NULL, NULL, task, req_timeout, request, &request->timer); if (result != ISC_R_SUCCESS) goto cleanup; request->event = (dns_requestevent_t *) isc_event_allocate(mctx, task, DNS_EVENT_REQUESTDONE, action, arg, sizeof(dns_requestevent_t)); if (request->event == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } isc_task_attach(task, &tclone); request->event->ev_sender = task; request->event->request = request; request->event->result = ISC_R_FAILURE; isc_buffer_usedregion(msgbuf, &r); if (r.length < DNS_MESSAGE_HEADERLEN || r.length > 65535) { result = DNS_R_FORMERR; goto cleanup; } if ((options & DNS_REQUESTOPT_TCP) != 0 || r.length > 512) tcp = ISC_TRUE; result = get_dispatch(tcp, requestmgr, srcaddr, destaddr, dscp, &request->dispatch); if (result != ISC_R_SUCCESS) goto cleanup; if ((options & DNS_REQUESTOPT_FIXEDID) != 0) { id = (r.base[0] << 8) | r.base[1]; dispopt |= DNS_DISPATCHOPT_FIXEDID; } result = dns_dispatch_addresponse3(request->dispatch, dispopt, destaddr, task, req_response, request, &id, &request->dispentry, requestmgr->socketmgr); if (result != ISC_R_SUCCESS) goto cleanup; sock = req_getsocket(request); INSIST(sock != NULL); result = isc_buffer_allocate(mctx, &request->query, r.length + (tcp ? 2 : 0)); if (result != ISC_R_SUCCESS) goto cleanup; if (tcp) isc_buffer_putuint16(request->query, (isc_uint16_t)r.length); result = isc_buffer_copyregion(request->query, &r); if (result != ISC_R_SUCCESS) goto cleanup; /* Add message ID. */ isc_buffer_usedregion(request->query, &r); if (tcp) isc_region_consume(&r, 2); r.base[0] = (id>>8) & 0xff; r.base[1] = id & 0xff; LOCK(&requestmgr->lock); if (requestmgr->exiting) { UNLOCK(&requestmgr->lock); result = ISC_R_SHUTTINGDOWN; goto cleanup; } requestmgr_attach(requestmgr, &request->requestmgr); request->hash = mgr_gethash(requestmgr); ISC_LIST_APPEND(requestmgr->requests, request, link); UNLOCK(&requestmgr->lock); result = set_timer(request->timer, timeout, tcp ? 0 : udptimeout); if (result != ISC_R_SUCCESS) goto unlink; request->destaddr = *destaddr; if (tcp) { result = isc_socket_connect(sock, destaddr, task, req_connected, request); if (result != ISC_R_SUCCESS) goto unlink; request->flags |= DNS_REQUEST_F_CONNECTING|DNS_REQUEST_F_TCP; } else { result = req_send(request, task, destaddr); if (result != ISC_R_SUCCESS) goto unlink; } req_log(ISC_LOG_DEBUG(3), "dns_request_createraw: request %p", request); *requestp = request; return (ISC_R_SUCCESS); unlink: LOCK(&requestmgr->lock); ISC_LIST_UNLINK(requestmgr->requests, request, link); UNLOCK(&requestmgr->lock); cleanup: if (tclone != NULL) isc_task_detach(&tclone); req_destroy(request); req_log(ISC_LOG_DEBUG(3), "dns_request_createraw: failed %s", dns_result_totext(result)); return (result); } isc_result_t dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message, isc_sockaddr_t *address, unsigned int options, dns_tsigkey_t *key, unsigned int timeout, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp) { return (dns_request_createvia4(requestmgr, message, NULL, address, -1, options, key, timeout, 0, 0, task, action, arg, requestp)); } isc_result_t dns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, unsigned int options, dns_tsigkey_t *key, unsigned int timeout, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp) { return(dns_request_createvia4(requestmgr, message, srcaddr, destaddr, -1, options, key, timeout, 0, 0, task, action, arg, requestp)); } isc_result_t dns_request_createvia2(dns_requestmgr_t *requestmgr, dns_message_t *message, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, unsigned int options, dns_tsigkey_t *key, unsigned int timeout, unsigned int udptimeout, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp) { unsigned int udpretries = 0; if (udptimeout != 0) udpretries = timeout / udptimeout; return (dns_request_createvia4(requestmgr, message, srcaddr, destaddr, -1, options, key, timeout, udptimeout, udpretries, task, action, arg, requestp)); } isc_result_t dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, unsigned int options, dns_tsigkey_t *key, unsigned int timeout, unsigned int udptimeout, unsigned int udpretries, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp) { return (dns_request_createvia4(requestmgr, message, srcaddr, destaddr, -1, options, key, timeout, udptimeout, udpretries, task, action, arg, requestp)); } isc_result_t dns_request_createvia4(dns_requestmgr_t *requestmgr, dns_message_t *message, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, isc_dscp_t dscp, unsigned int options, dns_tsigkey_t *key, unsigned int timeout, unsigned int udptimeout, unsigned int udpretries, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp) { dns_request_t *request = NULL; isc_task_t *tclone = NULL; isc_socket_t *sock = NULL; isc_result_t result; isc_mem_t *mctx; dns_messageid_t id; isc_boolean_t tcp; isc_boolean_t settsigkey = ISC_TRUE; REQUIRE(VALID_REQUESTMGR(requestmgr)); REQUIRE(message != NULL); REQUIRE(destaddr != NULL); REQUIRE(task != NULL); REQUIRE(action != NULL); REQUIRE(requestp != NULL && *requestp == NULL); REQUIRE(timeout > 0); mctx = requestmgr->mctx; req_log(ISC_LOG_DEBUG(3), "dns_request_createvia"); if (srcaddr != NULL && isc_sockaddr_pf(srcaddr) != isc_sockaddr_pf(destaddr)) return (ISC_R_FAMILYMISMATCH); if (isblackholed(requestmgr->dispatchmgr, destaddr)) return (DNS_R_BLACKHOLED); request = NULL; result = new_request(mctx, &request); if (result != ISC_R_SUCCESS) return (result); if (udptimeout == 0 && udpretries != 0) { udptimeout = timeout / (udpretries + 1); if (udptimeout == 0) udptimeout = 1; } request->udpcount = udpretries; request->dscp = dscp; /* * Create timer now. We will set it below once. */ result = isc_timer_create(requestmgr->timermgr, isc_timertype_inactive, NULL, NULL, task, req_timeout, request, &request->timer); if (result != ISC_R_SUCCESS) goto cleanup; request->event = (dns_requestevent_t *) isc_event_allocate(mctx, task, DNS_EVENT_REQUESTDONE, action, arg, sizeof(dns_requestevent_t)); if (request->event == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } isc_task_attach(task, &tclone); request->event->ev_sender = task; request->event->request = request; request->event->result = ISC_R_FAILURE; if (key != NULL) dns_tsigkey_attach(key, &request->tsigkey); use_tcp: tcp = ISC_TF((options & DNS_REQUESTOPT_TCP) != 0); result = get_dispatch(tcp, requestmgr, srcaddr, destaddr, dscp, &request->dispatch); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_dispatch_addresponse2(request->dispatch, destaddr, task, req_response, request, &id, &request->dispentry, requestmgr->socketmgr); if (result != ISC_R_SUCCESS) goto cleanup; sock = req_getsocket(request); INSIST(sock != NULL); message->id = id; if (settsigkey) { result = dns_message_settsigkey(message, request->tsigkey); if (result != ISC_R_SUCCESS) goto cleanup; } result = req_render(message, &request->query, options, mctx); if (result == DNS_R_USETCP && (options & DNS_REQUESTOPT_TCP) == 0) { /* * Try again using TCP. */ dns_message_renderreset(message); dns_dispatch_removeresponse(&request->dispentry, NULL); dns_dispatch_detach(&request->dispatch); sock = NULL; options |= DNS_REQUESTOPT_TCP; settsigkey = ISC_FALSE; goto use_tcp; } if (result != ISC_R_SUCCESS) goto cleanup; result = dns_message_getquerytsig(message, mctx, &request->tsig); if (result != ISC_R_SUCCESS) goto cleanup; LOCK(&requestmgr->lock); if (requestmgr->exiting) { UNLOCK(&requestmgr->lock); result = ISC_R_SHUTTINGDOWN; goto cleanup; } requestmgr_attach(requestmgr, &request->requestmgr); request->hash = mgr_gethash(requestmgr); ISC_LIST_APPEND(requestmgr->requests, request, link); UNLOCK(&requestmgr->lock); result = set_timer(request->timer, timeout, tcp ? 0 : udptimeout); if (result != ISC_R_SUCCESS) goto unlink; request->destaddr = *destaddr; if (tcp) { result = isc_socket_connect(sock, destaddr, task, req_connected, request); if (result != ISC_R_SUCCESS) goto unlink; request->flags |= DNS_REQUEST_F_CONNECTING|DNS_REQUEST_F_TCP; } else { result = req_send(request, task, destaddr); if (result != ISC_R_SUCCESS) goto unlink; } req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: request %p", request); *requestp = request; return (ISC_R_SUCCESS); unlink: LOCK(&requestmgr->lock); ISC_LIST_UNLINK(requestmgr->requests, request, link); UNLOCK(&requestmgr->lock); cleanup: if (tclone != NULL) isc_task_detach(&tclone); req_destroy(request); req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: failed %s", dns_result_totext(result)); return (result); } static isc_result_t req_render(dns_message_t *message, isc_buffer_t **bufferp, unsigned int options, isc_mem_t *mctx) { isc_buffer_t *buf1 = NULL; isc_buffer_t *buf2 = NULL; isc_result_t result; isc_region_t r; isc_boolean_t tcp = ISC_FALSE; dns_compress_t cctx; isc_boolean_t cleanup_cctx = ISC_FALSE; REQUIRE(bufferp != NULL && *bufferp == NULL); req_log(ISC_LOG_DEBUG(3), "request_render"); /* * Create buffer able to hold largest possible message. */ result = isc_buffer_allocate(mctx, &buf1, 65535); if (result != ISC_R_SUCCESS) return (result); result = dns_compress_init(&cctx, -1, mctx); if (result != ISC_R_SUCCESS) return (result); cleanup_cctx = ISC_TRUE; if ((options & DNS_REQUESTOPT_CASE) != 0) dns_compress_setsensitive(&cctx, ISC_TRUE); /* * Render message. */ result = dns_message_renderbegin(message, &cctx, buf1); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_message_rendersection(message, DNS_SECTION_QUESTION, 0); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_message_rendersection(message, DNS_SECTION_ANSWER, 0); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_message_rendersection(message, DNS_SECTION_AUTHORITY, 0); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_message_rendersection(message, DNS_SECTION_ADDITIONAL, 0); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_message_renderend(message); if (result != ISC_R_SUCCESS) goto cleanup; dns_compress_invalidate(&cctx); cleanup_cctx = ISC_FALSE; /* * Copy rendered message to exact sized buffer. */ isc_buffer_usedregion(buf1, &r); if ((options & DNS_REQUESTOPT_TCP) != 0) { tcp = ISC_TRUE; } else if (r.length > 512) { result = DNS_R_USETCP; goto cleanup; } result = isc_buffer_allocate(mctx, &buf2, r.length + (tcp ? 2 : 0)); if (result != ISC_R_SUCCESS) goto cleanup; if (tcp) isc_buffer_putuint16(buf2, (isc_uint16_t)r.length); result = isc_buffer_copyregion(buf2, &r); if (result != ISC_R_SUCCESS) goto cleanup; /* * Cleanup and return. */ isc_buffer_free(&buf1); *bufferp = buf2; return (ISC_R_SUCCESS); cleanup: dns_message_renderreset(message); if (buf1 != NULL) isc_buffer_free(&buf1); if (buf2 != NULL) isc_buffer_free(&buf2); if (cleanup_cctx) dns_compress_invalidate(&cctx); return (result); } /* * If this request is no longer waiting for events, * send the completion event. This will ultimately * cause the request to be destroyed. * * Requires: * 'request' is locked by the caller. */ static void send_if_done(dns_request_t *request, isc_result_t result) { if (request->event != NULL && !request->canceling) req_sendevent(request, result); } /* * Handle the control event. */ static void do_cancel(isc_task_t *task, isc_event_t *event) { dns_request_t *request = event->ev_arg; UNUSED(task); INSIST(event->ev_type == DNS_EVENT_REQUESTCONTROL); LOCK(&request->requestmgr->locks[request->hash]); request->canceling = ISC_FALSE; if (!DNS_REQUEST_CANCELED(request)) req_cancel(request); send_if_done(request, ISC_R_CANCELED); UNLOCK(&request->requestmgr->locks[request->hash]); } void dns_request_cancel(dns_request_t *request) { REQUIRE(VALID_REQUEST(request)); req_log(ISC_LOG_DEBUG(3), "dns_request_cancel: request %p", request); REQUIRE(VALID_REQUEST(request)); LOCK(&request->requestmgr->locks[request->hash]); if (!request->canceling && !DNS_REQUEST_CANCELED(request)) { isc_event_t *ev = &request->ctlevent; isc_task_send(request->event->ev_sender, &ev); request->canceling = ISC_TRUE; } UNLOCK(&request->requestmgr->locks[request->hash]); } isc_result_t dns_request_getresponse(dns_request_t *request, dns_message_t *message, unsigned int options) { isc_result_t result; REQUIRE(VALID_REQUEST(request)); REQUIRE(request->answer != NULL); req_log(ISC_LOG_DEBUG(3), "dns_request_getresponse: request %p", request); result = dns_message_setquerytsig(message, request->tsig); if (result != ISC_R_SUCCESS) return (result); result = dns_message_settsigkey(message, request->tsigkey); if (result != ISC_R_SUCCESS) return (result); result = dns_message_parse(message, request->answer, options); if (result != ISC_R_SUCCESS) return (result); if (request->tsigkey != NULL) result = dns_tsig_verify(request->answer, message, NULL, NULL); return (result); } isc_boolean_t dns_request_usedtcp(dns_request_t *request) { REQUIRE(VALID_REQUEST(request)); return (ISC_TF((request->flags & DNS_REQUEST_F_TCP) != 0)); } void dns_request_destroy(dns_request_t **requestp) { dns_request_t *request; REQUIRE(requestp != NULL && VALID_REQUEST(*requestp)); request = *requestp; req_log(ISC_LOG_DEBUG(3), "dns_request_destroy: request %p", request); LOCK(&request->requestmgr->lock); LOCK(&request->requestmgr->locks[request->hash]); ISC_LIST_UNLINK(request->requestmgr->requests, request, link); INSIST(!DNS_REQUEST_CONNECTING(request)); INSIST(!DNS_REQUEST_SENDING(request)); UNLOCK(&request->requestmgr->locks[request->hash]); UNLOCK(&request->requestmgr->lock); /* * These should have been cleaned up by req_cancel() before * the completion event was sent. */ INSIST(!ISC_LINK_LINKED(request, link)); INSIST(request->dispentry == NULL); INSIST(request->dispatch == NULL); INSIST(request->timer == NULL); req_destroy(request); *requestp = NULL; } /*** *** Private: request. ***/ static isc_socket_t * req_getsocket(dns_request_t *request) { unsigned int dispattr; isc_socket_t *sock; dispattr = dns_dispatch_getattributes(request->dispatch); if ((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0) { INSIST(request->dispentry != NULL); sock = dns_dispatch_getentrysocket(request->dispentry); } else sock = dns_dispatch_getsocket(request->dispatch); return (sock); } static void req_connected(isc_task_t *task, isc_event_t *event) { isc_socketevent_t *sevent = (isc_socketevent_t *)event; isc_result_t result; dns_request_t *request = event->ev_arg; REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT); REQUIRE(VALID_REQUEST(request)); REQUIRE(DNS_REQUEST_CONNECTING(request)); req_log(ISC_LOG_DEBUG(3), "req_connected: request %p", request); LOCK(&request->requestmgr->locks[request->hash]); request->flags &= ~DNS_REQUEST_F_CONNECTING; if (DNS_REQUEST_CANCELED(request)) { /* * Send delayed event. */ if (DNS_REQUEST_TIMEDOUT(request)) send_if_done(request, ISC_R_TIMEDOUT); else send_if_done(request, ISC_R_CANCELED); } else { dns_dispatch_starttcp(request->dispatch); result = sevent->result; if (result == ISC_R_SUCCESS) result = req_send(request, task, NULL); if (result != ISC_R_SUCCESS) { req_cancel(request); send_if_done(request, ISC_R_CANCELED); } } UNLOCK(&request->requestmgr->locks[request->hash]); isc_event_free(&event); } static void req_senddone(isc_task_t *task, isc_event_t *event) { isc_socketevent_t *sevent = (isc_socketevent_t *)event; dns_request_t *request = event->ev_arg; REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE); REQUIRE(VALID_REQUEST(request)); REQUIRE(DNS_REQUEST_SENDING(request)); req_log(ISC_LOG_DEBUG(3), "req_senddone: request %p", request); UNUSED(task); LOCK(&request->requestmgr->locks[request->hash]); request->flags &= ~DNS_REQUEST_F_SENDING; if (DNS_REQUEST_CANCELED(request)) { /* * Send delayed event. */ if (DNS_REQUEST_TIMEDOUT(request)) send_if_done(request, ISC_R_TIMEDOUT); else send_if_done(request, ISC_R_CANCELED); } else if (sevent->result != ISC_R_SUCCESS) { req_cancel(request); send_if_done(request, ISC_R_CANCELED); } UNLOCK(&request->requestmgr->locks[request->hash]); isc_event_free(&event); } static void req_response(isc_task_t *task, isc_event_t *event) { isc_result_t result; dns_request_t *request = event->ev_arg; dns_dispatchevent_t *devent = (dns_dispatchevent_t *)event; isc_region_t r; REQUIRE(VALID_REQUEST(request)); REQUIRE(event->ev_type == DNS_EVENT_DISPATCH); UNUSED(task); req_log(ISC_LOG_DEBUG(3), "req_response: request %p: %s", request, dns_result_totext(devent->result)); LOCK(&request->requestmgr->locks[request->hash]); result = devent->result; if (result != ISC_R_SUCCESS) goto done; /* * Copy buffer to request. */ isc_buffer_usedregion(&devent->buffer, &r); result = isc_buffer_allocate(request->mctx, &request->answer, r.length); if (result != ISC_R_SUCCESS) goto done; result = isc_buffer_copyregion(request->answer, &r); if (result != ISC_R_SUCCESS) isc_buffer_free(&request->answer); done: /* * Cleanup. */ dns_dispatch_removeresponse(&request->dispentry, &devent); req_cancel(request); /* * Send completion event. */ send_if_done(request, result); UNLOCK(&request->requestmgr->locks[request->hash]); } static void req_timeout(isc_task_t *task, isc_event_t *event) { dns_request_t *request = event->ev_arg; isc_result_t result; REQUIRE(VALID_REQUEST(request)); req_log(ISC_LOG_DEBUG(3), "req_timeout: request %p", request); UNUSED(task); LOCK(&request->requestmgr->locks[request->hash]); if (event->ev_type == ISC_TIMEREVENT_TICK && request->udpcount-- != 0) { if (! DNS_REQUEST_SENDING(request)) { result = req_send(request, task, &request->destaddr); if (result != ISC_R_SUCCESS) { req_cancel(request); send_if_done(request, result); } } } else { request->flags |= DNS_REQUEST_F_TIMEDOUT; req_cancel(request); send_if_done(request, ISC_R_TIMEDOUT); } UNLOCK(&request->requestmgr->locks[request->hash]); isc_event_free(&event); } static void req_sendevent(dns_request_t *request, isc_result_t result) { isc_task_t *task; REQUIRE(VALID_REQUEST(request)); req_log(ISC_LOG_DEBUG(3), "req_sendevent: request %p", request); /* * Lock held by caller. */ task = request->event->ev_sender; request->event->ev_sender = request; request->event->result = result; isc_task_sendanddetach(&task, (isc_event_t **)&request->event); } static void req_destroy(dns_request_t *request) { isc_mem_t *mctx; REQUIRE(VALID_REQUEST(request)); req_log(ISC_LOG_DEBUG(3), "req_destroy: request %p", request); request->magic = 0; if (request->query != NULL) isc_buffer_free(&request->query); if (request->answer != NULL) isc_buffer_free(&request->answer); if (request->event != NULL) isc_event_free((isc_event_t **)&request->event); if (request->dispentry != NULL) dns_dispatch_removeresponse(&request->dispentry, NULL); if (request->dispatch != NULL) dns_dispatch_detach(&request->dispatch); if (request->timer != NULL) isc_timer_detach(&request->timer); if (request->tsig != NULL) isc_buffer_free(&request->tsig); if (request->tsigkey != NULL) dns_tsigkey_detach(&request->tsigkey); if (request->requestmgr != NULL) requestmgr_detach(&request->requestmgr); mctx = request->mctx; isc_mem_put(mctx, request, sizeof(*request)); isc_mem_detach(&mctx); } /* * Stop the current request. Must be called from the request's task. */ static void req_cancel(dns_request_t *request) { isc_socket_t *sock; unsigned int dispattr; REQUIRE(VALID_REQUEST(request)); req_log(ISC_LOG_DEBUG(3), "req_cancel: request %p", request); /* * Lock held by caller. */ request->flags |= DNS_REQUEST_F_CANCELED; if (request->timer != NULL) isc_timer_detach(&request->timer); dispattr = dns_dispatch_getattributes(request->dispatch); sock = NULL; if (DNS_REQUEST_CONNECTING(request) || DNS_REQUEST_SENDING(request)) { if ((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0) { if (request->dispentry != NULL) { sock = dns_dispatch_getentrysocket( request->dispentry); } } else sock = dns_dispatch_getsocket(request->dispatch); if (DNS_REQUEST_CONNECTING(request) && sock != NULL) isc_socket_cancel(sock, NULL, ISC_SOCKCANCEL_CONNECT); if (DNS_REQUEST_SENDING(request) && sock != NULL) isc_socket_cancel(sock, NULL, ISC_SOCKCANCEL_SEND); } if (request->dispentry != NULL) dns_dispatch_removeresponse(&request->dispentry, NULL); dns_dispatch_detach(&request->dispatch); } static void req_log(int level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_REQUEST, level, fmt, ap); va_end(ap); } bind9-9.10.3.dfsg.P4/lib/dns/iptable.c0000644000470500017500000001142312664710322016510 0ustar lamontlamont/* * Copyright (C) 2007-2009, 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: iptable.c,v 1.15 2009/02/18 23:47:48 tbox Exp $ */ #include #include #include #include static void destroy_iptable(dns_iptable_t *dtab); /* * Create a new IP table and the underlying radix structure */ isc_result_t dns_iptable_create(isc_mem_t *mctx, dns_iptable_t **target) { isc_result_t result; dns_iptable_t *tab; tab = isc_mem_get(mctx, sizeof(*tab)); if (tab == NULL) return (ISC_R_NOMEMORY); tab->mctx = NULL; isc_mem_attach(mctx, &tab->mctx); isc_refcount_init(&tab->refcount, 1); tab->radix = NULL; tab->magic = DNS_IPTABLE_MAGIC; result = isc_radix_create(mctx, &tab->radix, RADIX_MAXBITS); if (result != ISC_R_SUCCESS) goto cleanup; *target = tab; return (ISC_R_SUCCESS); cleanup: dns_iptable_detach(&tab); return (result); } isc_boolean_t dns_iptable_neg = ISC_FALSE; isc_boolean_t dns_iptable_pos = ISC_TRUE; /* * Add an IP prefix to an existing IP table */ isc_result_t dns_iptable_addprefix(dns_iptable_t *tab, isc_netaddr_t *addr, isc_uint16_t bitlen, isc_boolean_t pos) { isc_result_t result; isc_prefix_t pfx; isc_radix_node_t *node = NULL; int family; INSIST(DNS_IPTABLE_VALID(tab)); INSIST(tab->radix); NETADDR_TO_PREFIX_T(addr, pfx, bitlen); result = isc_radix_insert(tab->radix, &node, NULL, &pfx); if (result != ISC_R_SUCCESS) { isc_refcount_destroy(&pfx.refcount); return(result); } /* If a node already contains data, don't overwrite it */ family = pfx.family; if (family == AF_UNSPEC) { /* "any" or "none" */ INSIST(pfx.bitlen == 0); if (pos) { if (node->data[0] == NULL) node->data[0] = &dns_iptable_pos; if (node->data[1] == NULL) node->data[1] = &dns_iptable_pos; } else { if (node->data[0] == NULL) node->data[0] = &dns_iptable_neg; if (node->data[1] == NULL) node->data[1] = &dns_iptable_neg; } } else { /* any other prefix */ if (node->data[ISC_IS6(family)] == NULL) { if (pos) node->data[ISC_IS6(family)] = &dns_iptable_pos; else node->data[ISC_IS6(family)] = &dns_iptable_neg; } } isc_refcount_destroy(&pfx.refcount); return (ISC_R_SUCCESS); } /* * Merge one IP table into another one. */ isc_result_t dns_iptable_merge(dns_iptable_t *tab, dns_iptable_t *source, isc_boolean_t pos) { isc_result_t result; isc_radix_node_t *node, *new_node; int max_node = 0; RADIX_WALK (source->radix->head, node) { new_node = NULL; result = isc_radix_insert (tab->radix, &new_node, node, NULL); if (result != ISC_R_SUCCESS) return(result); /* * If we're negating a nested ACL, then we should * reverse the sense of every node. However, this * could lead to a negative node in a nested ACL * becoming a positive match in the parent, which * could be a security risk. To prevent this, we * just leave the negative nodes negative. */ if (!pos) { if (node->data[0] && *(isc_boolean_t *) node->data[0] == ISC_TRUE) new_node->data[0] = &dns_iptable_neg; if (node->data[1] && *(isc_boolean_t *) node->data[1] == ISC_TRUE) new_node->data[1] = &dns_iptable_neg; } if (node->node_num[0] > max_node) max_node = node->node_num[0]; if (node->node_num[1] > max_node) max_node = node->node_num[1]; } RADIX_WALK_END; tab->radix->num_added_node += max_node; return (ISC_R_SUCCESS); } void dns_iptable_attach(dns_iptable_t *source, dns_iptable_t **target) { REQUIRE(DNS_IPTABLE_VALID(source)); isc_refcount_increment(&source->refcount, NULL); *target = source; } void dns_iptable_detach(dns_iptable_t **tabp) { dns_iptable_t *tab = *tabp; unsigned int refs; REQUIRE(DNS_IPTABLE_VALID(tab)); isc_refcount_decrement(&tab->refcount, &refs); if (refs == 0) destroy_iptable(tab); *tabp = NULL; } static void destroy_iptable(dns_iptable_t *dtab) { REQUIRE(DNS_IPTABLE_VALID(dtab)); if (dtab->radix != NULL) { isc_radix_destroy(dtab->radix, NULL); dtab->radix = NULL; } isc_refcount_destroy(&dtab->refcount); dtab->magic = 0; isc_mem_putanddetach(&dtab->mctx, dtab, sizeof(*dtab)); } bind9-9.10.3.dfsg.P4/lib/dns/tests/0002755000470500017500000000000012672612753016077 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/dns/tests/update_test.c0000644000470500017500000001512412664710322020555 0ustar lamontlamont/* * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include "dnstest.h" static isc_uint32_t mystdtime; static void set_mystdtime(int year, int month, int day) { struct tm tm; memset(&tm, 0, sizeof(tm)); tm.tm_year = year - 1900; tm.tm_mon = month; tm.tm_mday = day; mystdtime = timegm(&tm) ; } void isc_stdtime_get(isc_stdtime_t *now) { *now = mystdtime; } /* * Individual unit tests */ ATF_TC(increment); ATF_TC_HEAD(increment, tc) { atf_tc_set_md_var(tc, "descr", "simple increment by 1"); } ATF_TC_BODY(increment, tc) { isc_uint32_t old = 50; isc_uint32_t new; isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); new = dns_update_soaserial(old, dns_updatemethod_increment); ATF_REQUIRE_EQ(isc_serial_lt(old, new), ISC_TRUE); ATF_CHECK_MSG(new != 0, "new (%d) should not equal 0", new); ATF_REQUIRE_EQ(new, 51); dns_test_end(); } /* 0xfffffffff -> 1 */ ATF_TC(increment_past_zero); ATF_TC_HEAD(increment_past_zero, tc) { atf_tc_set_md_var(tc, "descr", "increment past zero, ffffffff -> 1"); } ATF_TC_BODY(increment_past_zero, tc) { isc_uint32_t old = 0xffffffffu; isc_uint32_t new; isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); new = dns_update_soaserial(old, dns_updatemethod_increment); ATF_REQUIRE_EQ(isc_serial_lt(old, new), ISC_TRUE); ATF_CHECK(new != 0); ATF_REQUIRE_EQ(new, 1u); dns_test_end(); } ATF_TC(past_to_unix); ATF_TC_HEAD(past_to_unix, tc) { atf_tc_set_md_var(tc, "descr", "past to unixtime"); } ATF_TC_BODY(past_to_unix, tc) { isc_uint32_t old; isc_uint32_t new; isc_result_t result; UNUSED(tc); set_mystdtime(2011, 6, 22); old = mystdtime - 1; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); new = dns_update_soaserial(old, dns_updatemethod_unixtime); ATF_REQUIRE_EQ(isc_serial_lt(old, new), ISC_TRUE); ATF_CHECK(new != 0); ATF_REQUIRE_EQ(new, mystdtime); dns_test_end(); } ATF_TC(now_to_unix); ATF_TC_HEAD(now_to_unix, tc) { atf_tc_set_md_var(tc, "descr", "now to unixtime"); } ATF_TC_BODY(now_to_unix, tc) { isc_uint32_t old; isc_uint32_t new; isc_result_t result; UNUSED(tc); set_mystdtime(2011, 6, 22); old = mystdtime; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); new = dns_update_soaserial(old, dns_updatemethod_unixtime); ATF_REQUIRE_EQ(isc_serial_lt(old, new), ISC_TRUE); ATF_CHECK(new != 0); ATF_REQUIRE_EQ(new, old+1); dns_test_end(); } ATF_TC(future_to_unix); ATF_TC_HEAD(future_to_unix, tc) { atf_tc_set_md_var(tc, "descr", "future to unixtime"); } ATF_TC_BODY(future_to_unix, tc) { isc_uint32_t old; isc_uint32_t new; isc_result_t result; UNUSED(tc); set_mystdtime(2011, 6, 22); old = mystdtime + 1; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); new = dns_update_soaserial(old, dns_updatemethod_unixtime); ATF_REQUIRE_EQ(isc_serial_lt(old, new), ISC_TRUE); ATF_CHECK(new != 0); ATF_REQUIRE_EQ(new, old+1); dns_test_end(); } ATF_TC(undefined_plus1_to_unix); ATF_TC_HEAD(undefined_plus1_to_unix, tc) { atf_tc_set_md_var(tc, "descr", "undefined plus 1 to unixtime"); } ATF_TC_BODY(undefined_plus1_to_unix, tc) { isc_uint32_t old; isc_uint32_t new; isc_result_t result; UNUSED(tc); set_mystdtime(2011, 6, 22); old = mystdtime ^ 0x80000000u; old += 1; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); new = dns_update_soaserial(old, dns_updatemethod_unixtime); ATF_REQUIRE_EQ(isc_serial_lt(old, new), ISC_TRUE); ATF_CHECK(new != 0); ATF_REQUIRE_EQ(new, mystdtime); dns_test_end(); } ATF_TC(undefined_minus1_to_unix); ATF_TC_HEAD(undefined_minus1_to_unix, tc) { atf_tc_set_md_var(tc, "descr", "undefined minus 1 to unixtime"); } ATF_TC_BODY(undefined_minus1_to_unix, tc) { isc_uint32_t old; isc_uint32_t new; isc_result_t result; UNUSED(tc); set_mystdtime(2011, 6, 22); old = mystdtime ^ 0x80000000u; old -= 1; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); new = dns_update_soaserial(old, dns_updatemethod_unixtime); ATF_REQUIRE_EQ(isc_serial_lt(old, new), ISC_TRUE); ATF_CHECK(new != 0); ATF_REQUIRE_EQ(new, old+1); dns_test_end(); } ATF_TC(undefined_to_unix); ATF_TC_HEAD(undefined_to_unix, tc) { atf_tc_set_md_var(tc, "descr", "undefined to unixtime"); } ATF_TC_BODY(undefined_to_unix, tc) { isc_uint32_t old; isc_uint32_t new; isc_result_t result; UNUSED(tc); set_mystdtime(2011, 6, 22); old = mystdtime ^ 0x80000000u; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); new = dns_update_soaserial(old, dns_updatemethod_unixtime); ATF_REQUIRE_EQ(isc_serial_lt(old, new), ISC_TRUE); ATF_CHECK(new != 0); ATF_REQUIRE_EQ(new, old+1); dns_test_end(); } ATF_TC(unixtime_zero); ATF_TC_HEAD(unixtime_zero, tc) { atf_tc_set_md_var(tc, "descr", "handle unixtime being zero"); } ATF_TC_BODY(unixtime_zero, tc) { isc_uint32_t old; isc_uint32_t new; isc_result_t result; UNUSED(tc); mystdtime = 0; old = 0xfffffff0; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); new = dns_update_soaserial(old, dns_updatemethod_unixtime); ATF_REQUIRE_EQ(isc_serial_lt(old, new), ISC_TRUE); ATF_CHECK(new != 0); ATF_REQUIRE_EQ(new, old+1); dns_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, increment); ATF_TP_ADD_TC(tp, increment_past_zero); ATF_TP_ADD_TC(tp, past_to_unix); ATF_TP_ADD_TC(tp, now_to_unix); ATF_TP_ADD_TC(tp, future_to_unix); ATF_TP_ADD_TC(tp, undefined_to_unix); ATF_TP_ADD_TC(tp, undefined_plus1_to_unix); ATF_TP_ADD_TC(tp, undefined_minus1_to_unix); ATF_TP_ADD_TC(tp, unixtime_zero); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/0002755000470500017500000000000012672612753017710 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/nsec3/0002755000470500017500000000000012672612753020723 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/nsec3/2048.db0000644000470500017500000000227512664710322021623 0ustar lamontlamont; Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above ; copyright notice and this permission notice appear in all copies. ; ; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. ; $Id$ $TTL 0 test. SOA . . 0 0 0 0 0 test. NS . ; 2048 bits test. IN DNSKEY 256 3 5 AwEAAcfQX59iZr9gK+XzhTZQ5KWrfCLA0iYHTqheEIhC2dXS8gUSppQS g9SmzH2129u/LSSb7gqJSoLLAsn36iinqCqUXl2BT6xzwznbSP3mn0hn N6DegsykcYhHycKH6ifjZiMN+SGGeNsi5rhoW5Cj9ptw3C3yQnrFNDbS GZCT97z5lpQU3ZcvP4RDNk7dhri7Bh3SJeaCFoqx00NgFvlBR48hosSG bGUbUKzNf58GBTkW4Us2jIWsreZx8LLLev232Hy7NU9L19k+hVq7pJOf Uvtrn5fmGSutWOzsR+8EacOnh0lwssCKjutk5MSmfdFC5P7CTZkdq58L 8he13HGmr00= bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/nsec3/1024.db0000644000470500017500000000202212664710322021602 0ustar lamontlamont; Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above ; copyright notice and this permission notice appear in all copies. ; ; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. ; $Id$ $TTL 0 test. SOA . . 0 0 0 0 0 test. NS . ; 1024 bit key. test. IN DNSKEY 256 3 5 AwEAAd5oKx06HRE6NRrTDz49lljdRmxgp/4YB/cyMkpwUMkaLhDNCfTq hql84ab2LRbtUWLHFXGWENvxPGQzVHeleXu+3ThNfFOwIaySedxHmLGT lTtBRDhPc8iSb+2IYDemmA+ut8kwHhCVz/tDMbD/dgAswdOtmXCpQyJk Q1HqY3Xj bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/nsec3/min-1024.db0000644000470500017500000000417212664710322022373 0ustar lamontlamont; Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above ; copyright notice and this permission notice appear in all copies. ; ; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. ; $Id$ $TTL 0 test. SOA . . 0 0 0 0 0 test. NS . ; 1024 bit key. test. IN DNSKEY 256 3 5 AwEAAd5oKx06HRE6NRrTDz49lljdRmxgp/4YB/cyMkpwUMkaLhDNCfTq hql84ab2LRbtUWLHFXGWENvxPGQzVHeleXu+3ThNfFOwIaySedxHmLGT lTtBRDhPc8iSb+2IYDemmA+ut8kwHhCVz/tDMbD/dgAswdOtmXCpQyJk Q1HqY3Xj ; 2048 bits test. IN DNSKEY 256 3 5 AwEAAcfQX59iZr9gK+XzhTZQ5KWrfCLA0iYHTqheEIhC2dXS8gUSppQS g9SmzH2129u/LSSb7gqJSoLLAsn36iinqCqUXl2BT6xzwznbSP3mn0hn N6DegsykcYhHycKH6ifjZiMN+SGGeNsi5rhoW5Cj9ptw3C3yQnrFNDbS GZCT97z5lpQU3ZcvP4RDNk7dhri7Bh3SJeaCFoqx00NgFvlBR48hosSG bGUbUKzNf58GBTkW4Us2jIWsreZx8LLLev232Hy7NU9L19k+hVq7pJOf Uvtrn5fmGSutWOzsR+8EacOnh0lwssCKjutk5MSmfdFC5P7CTZkdq58L 8he13HGmr00= ; 4096 bits test. IN DNSKEY 256 3 5 AwEAAbYlqbKxXoq9mzkqdsAaSZ3XywBVAb2sCTgrQBCExyGEYNpWw3LN +imCrLQi7jHKQW6GZIqKNgQaiFEwr3zK8nPWbwNwyKU9a2hhINv/gim1 5iA87Vu7DiiJrQ0O79ospvsGsKknBQ41zaaQMp3Q/W1S6WNe4uyh4C/f R0qmxT+8MyXEqCpTGb+e+YT6BuqpNQPuYYYvUJ1/HJltzY/lY2b9RZ+Q ZJ23Zje79YIRM0kJapqj11fDUDeynhDL1DUikYCwRfQiO/blChhOHjIa uTK1qqRY3fqanLGOufpLTr7GRpL7RxeRIMJfDzmcjFLmCsMA1AJ56Bxq jiXr3ODgn9D30vAB74Lr7lqLQSWyrSlJjoZLLhmPrEP/nnuCxEhOhDRA XJpJWpcQ4Hdu+yb5K/qldnsGLLI1Hr0GmhLTDHsxDb6BxM7/8rv8QeQY GKSGshBqD2lO1xUVT8inbi8uXI1iyN68vHX6xoFT5wsjls70PxSZPO5i F40vn6BWNsHtKWOCDqMKYx8hYwiv0zETVwxBaj58vylFwYGU+g1wIQmF Pgi2HKv4KaxgikUvdFISre5rxVoG5VrmmXWiNJcLTbwZ+tE1xujCNU1c V31CaIB5hdSnkEvQADr5V64RTxWAKuSLNMU+XUqTkaJHasSm3OPJOteo SPj2uoesuxNFYps3 bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/nsec3/4096.db0000644000470500017500000000302712664710322021624 0ustar lamontlamont; Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above ; copyright notice and this permission notice appear in all copies. ; ; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. ; $Id$ $TTL 0 test. SOA . . 0 0 0 0 0 test. NS . ; 4096 bits test. IN DNSKEY 256 3 5 AwEAAbYlqbKxXoq9mzkqdsAaSZ3XywBVAb2sCTgrQBCExyGEYNpWw3LN +imCrLQi7jHKQW6GZIqKNgQaiFEwr3zK8nPWbwNwyKU9a2hhINv/gim1 5iA87Vu7DiiJrQ0O79ospvsGsKknBQ41zaaQMp3Q/W1S6WNe4uyh4C/f R0qmxT+8MyXEqCpTGb+e+YT6BuqpNQPuYYYvUJ1/HJltzY/lY2b9RZ+Q ZJ23Zje79YIRM0kJapqj11fDUDeynhDL1DUikYCwRfQiO/blChhOHjIa uTK1qqRY3fqanLGOufpLTr7GRpL7RxeRIMJfDzmcjFLmCsMA1AJ56Bxq jiXr3ODgn9D30vAB74Lr7lqLQSWyrSlJjoZLLhmPrEP/nnuCxEhOhDRA XJpJWpcQ4Hdu+yb5K/qldnsGLLI1Hr0GmhLTDHsxDb6BxM7/8rv8QeQY GKSGshBqD2lO1xUVT8inbi8uXI1iyN68vHX6xoFT5wsjls70PxSZPO5i F40vn6BWNsHtKWOCDqMKYx8hYwiv0zETVwxBaj58vylFwYGU+g1wIQmF Pgi2HKv4KaxgikUvdFISre5rxVoG5VrmmXWiNJcLTbwZ+tE1xujCNU1c V31CaIB5hdSnkEvQADr5V64RTxWAKuSLNMU+XUqTkaJHasSm3OPJOteo SPj2uoesuxNFYps3 bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/nsec3/min-2048.db0000644000470500017500000000363612664710322022406 0ustar lamontlamont; Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above ; copyright notice and this permission notice appear in all copies. ; ; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. ; $Id$ $TTL 0 test. SOA . . 0 0 0 0 0 test. NS . ; 2048 bits test. IN DNSKEY 256 3 5 AwEAAcfQX59iZr9gK+XzhTZQ5KWrfCLA0iYHTqheEIhC2dXS8gUSppQS g9SmzH2129u/LSSb7gqJSoLLAsn36iinqCqUXl2BT6xzwznbSP3mn0hn N6DegsykcYhHycKH6ifjZiMN+SGGeNsi5rhoW5Cj9ptw3C3yQnrFNDbS GZCT97z5lpQU3ZcvP4RDNk7dhri7Bh3SJeaCFoqx00NgFvlBR48hosSG bGUbUKzNf58GBTkW4Us2jIWsreZx8LLLev232Hy7NU9L19k+hVq7pJOf Uvtrn5fmGSutWOzsR+8EacOnh0lwssCKjutk5MSmfdFC5P7CTZkdq58L 8he13HGmr00= ; 4096 bits test. IN DNSKEY 256 3 5 AwEAAbYlqbKxXoq9mzkqdsAaSZ3XywBVAb2sCTgrQBCExyGEYNpWw3LN +imCrLQi7jHKQW6GZIqKNgQaiFEwr3zK8nPWbwNwyKU9a2hhINv/gim1 5iA87Vu7DiiJrQ0O79ospvsGsKknBQ41zaaQMp3Q/W1S6WNe4uyh4C/f R0qmxT+8MyXEqCpTGb+e+YT6BuqpNQPuYYYvUJ1/HJltzY/lY2b9RZ+Q ZJ23Zje79YIRM0kJapqj11fDUDeynhDL1DUikYCwRfQiO/blChhOHjIa uTK1qqRY3fqanLGOufpLTr7GRpL7RxeRIMJfDzmcjFLmCsMA1AJ56Bxq jiXr3ODgn9D30vAB74Lr7lqLQSWyrSlJjoZLLhmPrEP/nnuCxEhOhDRA XJpJWpcQ4Hdu+yb5K/qldnsGLLI1Hr0GmhLTDHsxDb6BxM7/8rv8QeQY GKSGshBqD2lO1xUVT8inbi8uXI1iyN68vHX6xoFT5wsjls70PxSZPO5i F40vn6BWNsHtKWOCDqMKYx8hYwiv0zETVwxBaj58vylFwYGU+g1wIQmF Pgi2HKv4KaxgikUvdFISre5rxVoG5VrmmXWiNJcLTbwZ+tE1xujCNU1c V31CaIB5hdSnkEvQADr5V64RTxWAKuSLNMU+XUqTkaJHasSm3OPJOteo SPj2uoesuxNFYps3 bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/master/0002755000470500017500000000000012672612753021203 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/master/master8.data0000644000470500017500000000012312664710322023403 0ustar lamontlamont; ; master7.data contains a good zone file ; $include testdata/master/master7.data bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/master/master6.data0000644000470500017500000000210312664710322023401 0ustar lamontlamont $TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum secure1 3600 IN DNSKEY ( FLAG2|FLAG4|FLAG5|NTYP3|FLAG8|FLAG9|FLAG10|FLAG11|SIG15 3 3 ArT0a8FtOZWEONG2YQVl9+RA34op30JPz4NPEroCxm2yImT2 2OYggnPIzrgayyepgKU1PfTTypnJDTwrSrtISyEsj7tjM7/n 03DP8VWSn0aLwpUuc7Sx9vtM1Wi+YeiA4Bv2Oz1VB9de4qql sIq+KLn8J4wz95bGnJ0mHUB7oTDJ3Hl1zeaCMdX69Kr46yAY AvGJJdGGDYxYgxzx2zNdzypkYSkxpdsNqUt38tabSfdvCn12 pnmSWjlVJsjHhsaYnrPhouN5acOXMNbxNVbGU5LZ8Es6EYbV /7YMt8VUkA8/8UCszBBT7XAJ3OFjiMO8mvxrZZFzvwJlPBQ1 oFq/TNZlSe+N ) secure2 3600 in DNSKEY ( flag2|flag4|flag5|ntyp3|flag8|flag9|flag10|flag11|sig15 3 3 ArT0a8FtOZWEONG2YQVl9+RA34op30JPz4NPEroCxm2yImT2 2OYggnPIzrgayyepgKU1PfTTypnJDTwrSrtISyEsj7tjM7/n 03DP8VWSn0aLwpUuc7Sx9vtM1Wi+YeiA4Bv2Oz1VB9de4qql sIq+KLn8J4wz95bGnJ0mHUB7oTDJ3Hl1zeaCMdX69Kr46yAY AvGJJdGGDYxYgxzx2zNdzypkYSkxpdsNqUt38tabSfdvCn12 pnmSWjlVJsjHhsaYnrPhouN5acOXMNbxNVbGU5LZ8Es6EYbV /7YMt8VUkA8/8UCszBBT7XAJ3OFjiMO8mvxrZZFzvwJlPBQ1 oFq/TNZlSe+N ) bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/master/master4.data0000644000470500017500000000034512664710322023405 0ustar lamontlamont @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a in ns ns.vix.com. a in ns ns2vix.com. a in ns ns3vix.com. b in a 1.2.3.4 bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/master/master17.data0000644000470500017500000000042312664710322023466 0ustar lamontlamont$ORIGIN test. $TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum in ns ns.test. in ns ns2.test. in ns ns3.test. b in a 1.2.3.4 $ORIGIN sub.test. in a 4.3.2.1 bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/master/master7.data0000644000470500017500000000054712664710322023414 0ustar lamontlamont $TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum secure1 3600 IN DNSKEY ( NOKEY|FLAG2|FLAG4|FLAG5|NTYP3|FLAG8|FLAG9|FLAG10|FLAG11|SIG15 3 3 ) secure2 3600 in DNSKEY ( nokey|flag2|flag4|flag5|ntyp3|flag8|flag9|flag10|flag11|sig15 3 3 ) bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/master/master13.data.in0000644000470500017500000000064312664710322024073 0ustar lamontlamont00000002000000014ed7337f00000000000000000000000000000051000100060000000003e80000000100060474657374000035096c6f63616c686f7374000a706f73746d6173746572096c6f63616c686f73740076cb8ab100000e100000070800093a8000000e1000000046000100020000000003e8000000030006047465737400000c026e730376697803636f6d00000d036e73320376697803636f6d00000d036e73330376697803636f6d0000000022000100010000000003e80000000100080162047465737400000401020304 bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/master/master9.data0000644000470500017500000000010012664710322023377 0ustar lamontlamont; ; master5.data is bad ; $include testdata/master/master5.data bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/master/master1.data0000644000470500017500000000035512664710322023403 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum in ns ns.vix.com. in ns ns2.vix.com. in ns ns3.vix.com. b in a 1.2.3.4 bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/master/master14.data.in0000644000470500017500000000064312664710322024074 0ustar lamontlamont00000002000000014ed7337f0000000277df41e50000000000000051000100060000000003e80000000100060474657374000035096c6f63616c686f7374000a706f73746d6173746572096c6f63616c686f73740076cb8ab100000e100000070800093a8000000e1000000046000100020000000003e8000000030006047465737400000c026e730376697803636f6d00000d036e73320376697803636f6d00000d036e73330376697803636f6d0000000022000100010000000003e80000000100080162047465737400000401020304 bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/master/master12.data.in0000644000470500017500000000061312664710322024067 0ustar lamontlamont00000002000000004ed7306600000051000100060000000003e80000000100060474657374000035096c6f63616c686f7374000a706f73746d6173746572096c6f63616c686f73740076cb8ab100000e100000070800093a8000000e1000000046000100020000000003e8000000030006047465737400000c026e730376697803636f6d00000d036e73320376697803636f6d00000d036e73330376697803636f6d0000000022000100010000000003e80000000100080162047465737400000401020304 bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/master/master16.data0000644000470500017500000022312112664710322023467 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum in ns ns.vix.com. in ns ns2.vix.com. in ns ns3.vix.com. b in a 1.2.3.4 c in txt ( MAXSIZSEMAXSIZSEMAXSIZSEMAXSIZSMAX 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 ) bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/master/master3.data0000644000470500017500000000035212664710322023402 0ustar lamontlamont$TTL 1000 in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum in ns ns.vix.com in ns ns2vix.com. a in ns ns3vix.com. b in a 1.2.3.4 bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/master/master5.data0000644000470500017500000000035712664710322023411 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a any ns ns.vix.com. a in ns ns2vix.com. a in ns ns3vix.com. b in a 1.2.3.4 bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/master/master2.data0000644000470500017500000000034212664710322023400 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a in ns a in ns ns2vix.com. a in ns ns3vix.com. b in a 1.2.3.4 bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/master/master10.data0000644000470500017500000000011112664710322023451 0ustar lamontlamont; ; the following black line contains spaces ; @ 300 IN A 10.0.0.1 ; ; bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/master/master15.data0000644000470500017500000022312212664710322023467 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum in ns ns.vix.com. in ns ns2.vix.com. in ns ns3.vix.com. b in a 1.2.3.4 c in txt ( TOOBIGTOOBIGTOOBIGTOOBIGTOOBIGTOOBI 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 ) bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/master/master11.data0000644000470500017500000000031112664710322023454 0ustar lamontlamont; ; The following serial number contains a leading 0 and a 9 so the ; we can catch cases where it is incorrectly treated as a octal ; number. ; @ 300 IN SOA ns hostmaster 00090000 1200 3600 604800 300 bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/zt/0002755000470500017500000000000012664710322020335 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/zt/zone1.db0000644000470500017500000000177712664710322021712 0ustar lamontlamont; Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above ; copyright notice and this permission notice appear in all copies. ; ; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. ; $Id$ $TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum in ns ns.vix.com. in ns ns2.vix.com. in ns ns3.vix.com. a in a 1.2.3.4 bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/dbiterator/0002755000470500017500000000000012672612753022047 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/dbiterator/zone2.data0000644000470500017500000003255312664710322023735 0ustar lamontlamont; File written on Mon Aug 15 16:51:56 2011 ; dnssec_signzone version 9.7.3rc1 test. 600 IN SOA localhost. postmaster.localhost. ( 2011080901 ; serial 3600 ; refresh (1 hour) 1800 ; retry (30 minutes) 604800 ; expire (1 week) 600 ; minimum (10 minutes) ) 600 RRSIG SOA 7 1 600 20110914225156 ( 20110815225156 39833 test. IoQPcpx+Y2btVBBdM2H/9ppRMjphB1thwrdh midhKH+MXDAauUIENucugi3zLsc1o2ke8LnQ v3lCLd/bb5MD1otuS8vOw1GWEFhXOUBZU6wS QwEIcG4BiSlz7/GvOlRa2znkOmZ3c8bD/J3Y XUWDI3BEDPgrZqfxEvoMyPEWjO8= ) 600 NS ns.test. 600 NS ns2.test. 600 RRSIG NS 7 1 600 20110914225156 ( 20110815225156 39833 test. OgEimhmFIAqlH0hyQy3pTsveBHKyqs9WfO1S uDPRj3DFgFEAjoY473T8GxG2C+jTVL/UMVcb BTZ8wIAiUHhqKLcmr0q/1X+kNUs7tNi+6oMn /jxaOuRL6c8Kf2gl2t4g6JTwQqLQhUHTfQP+ bEfKUr75VsVfxCQZIHlZ3/AlxZM= ) 600 DNSKEY 256 3 7 ( AwEAAc0FzrE7jUiaKIGZpIaFE8E989topAJN dWIQUQ7BSKabmpBP2M+SXHwIiQ/yC25iqudO IxjRcK7nHB1VoP84xU2oMj6eeSqQHf/bYaji Y8IfR7lgrzoDWzq+0rtnKMJc/JM8SMkcoBAS llvxarDJTZheZjlrCvhpRJC+FAkBsx81 ) ; key id = 39833 600 DNSKEY 257 3 7 ( AwEAAc55LPDhBLqfDUpjYYbBt+N63CiZtKrD UDGeFAerbw0MWIUi3PgMr7yGVrj8e5Qjp9UN zBUax6NdhlYVtFA8CwMTXGBjxgyqUoWpce08 lswxfE70BpgUA6w5efs0/mYtX9/A76etCaSI oNH2vfa47BCdCPDfC1uTgyeuNuDvhszHaSiD 8OY7tLa/voecUlq38sdqi2raf2DvgOm7rdFa reXOS/WIj7zd4XYrV1JGthxOMVlQ7zdv9rVd UNUIF2d4hwCZJQr0ejhmvB3m/DuNmNOPYmnv KTmLSE+IJ6baqYvKOVxwV+SaCnuJEjv+3Yrx 8WQYD/iS9WBhC9FUit0dy+0= ) ; key id = 57183 600 RRSIG DNSKEY 7 1 600 20110914225156 ( 20110815225156 39833 test. xPV+bSGUlbxA5MKBeeRbwUDh3Qc+dm77+OHQ BHIr1L8/kRP5o5J7MqPA37kea6nhyltYf9xM RsxyiaBGUUeLyWg/q6hTtkNgAHifOPAhiDz8 AJDSTdSsq9RVtjdobAD0jyzz9sWnB+TPSOmj Nlyd7VtPVEuSYljgawwfBBO3Kho= ) 600 RRSIG DNSKEY 7 1 600 20110914225156 ( 20110815225156 57183 test. S3jkC7AvyFc4ShfHt6AWgS4zpx9DzWHBK9gV 2H23OJzy8H1At/CjKxWVHLJ/io+ygryVnt/I 47Jyhh9i43TnXj8il475YsweGnXGZSorrcXA 3IsD2lOuRYnp3yetxe2ZrMGNDqqImE6X4x1a UJI0cbE2UMZfUt8Rm5USiGzwAEgFD1OXxvMD UT3flyp+Ote9FConK8gewV4wlJuBFemWT7BZ lUYnoqfuAeEn2+1pIBS0iA0LNFjNBaEgtcjo QeweN32yKoApau47Dl/Klw7KFT8+PLZ0QPbt XAkJU7q94Q5aucDuHCSCTCc+2vZxdEnXKvRY rfLuG8r/V5Kn+1iYrQ== ) 0 NSEC3PARAM 1 0 10 - 0 RRSIG NSEC3PARAM 7 1 0 20110914225156 ( 20110815225156 39833 test. kghSSeP8AZiQ/zmxgxAyG0itoUMo5adG5pxD p8T3ZmbxEUSyG5acxBFkmeY39wVU0Cda8tWc HHrMbB5e2GN8z6xJ0A4rVyXfKSYJSz+iKWfk 7sOFRjd8OLYE3di6PwIpk6ORUiRPMFLDQCH0 Q27hLsSoKyd50orKKI+ncjz7WzU= ) a.test. 600 IN TXT "test" 600 RRSIG TXT 7 2 600 20110914225156 ( 20110815225156 39833 test. UEVOlnL6CDRNCfk/Xge2oaGYCV1+ewwi5zJ0 CX4DdwiNEkItL4HgBe8xXfxgFC3qySdsSYPE 1krdFyIkAclMCwHECd1UwZbGlMTEUGrE1KOB 8vQY+OhIV9TAhqNwnjbu7s2ZdNUv3wiUPcfk hCJ4rzP6yeV2inLwZulXnhxb6Pk= ) b.test. 600 IN TXT "test" 600 RRSIG TXT 7 2 600 20110914225156 ( 20110815225156 39833 test. HcyQlO9io6Rc5e4vVqlRmK5PacOaFQJmdERG 5Aobpgm1FuCLC7F+IMZ0d1XvBWnsw9iDzV43 UKzTGqUSmDiSBzs4QzHlacGickIW8EOV4xyJ +mcJ0FZh4YNbkt6CiX+8SF6IxfCMhRMjpSsK rWqJMG3LXkI6W9stShzsYAFBOzQ= ) e.test. 600 IN TXT "test" 600 RRSIG TXT 7 2 600 20110914225156 ( 20110815225156 39833 test. jUn5FGRTL9OcFU7tvfkUnSwY8jA+8JynE0hi ZJbYXDU5CiWGmR2B3yPHxUCewRqouyVCV8bc xZsSuBxvcdYKryYDbjsmB83GlSEuxE9J7XZs 8SxUP8PobLVqzXgEZS/XRU2G+R915ZDP9/iL z9oYwc9TkeyXbp8J/ZsH88tG980= ) c.test. 600 IN TXT "test" 600 RRSIG TXT 7 2 600 20110914225156 ( 20110815225156 39833 test. cRxAj45oFDDCd8xQXxD1F0Qq8XeBWAj8EYS3 7nFXAgAy8sTczFvYCNGj79o7BALJwM4vc/wx 6rjsiO/sHgfTMEBDq6lH9Wql72uhwavI2SrL /h/wBP5q4BXlQ4xp6cLhhdifOWhNTvLP+Fe5 U6yjvqneiKspze9SiFbcmRDiJds= ) d.e.f.test. 600 IN TXT "test" 600 RRSIG TXT 7 4 600 20110914225156 ( 20110815225156 39833 test. ENjCzr/P9rJmj5OJLzYwWtHtBg2Uz+qJDucz I97Pq9F819/c5sxNfT4hgICCw6ZfT4ffbzye fFJ0JVrh2cYOzu68ozlgek/Uml1UW0pDQVdI s4zEgp4XK9wXUxtWChSqp5YXMdeHegZFu32i IMNTbJDudwYSwhr2FyG92ZRi8Y8= ) f.g.h.test. 600 IN TXT "test" 600 RRSIG TXT 7 4 600 20110914225156 ( 20110815225156 39833 test. HT7iocFsfDjeX6j9RJdE3xfVGkIxhajFHgM/ T/mJj/al4HKV6Ajia8DhpdfDrgM2m7r+Pgcn FSIstfebQsuFCnHX/gIalDND/grHKsetQnMP Y7O4QLsRnTV53fdlqQ4eT+jBW6fzJdGySVN+ bg6kNJZS8DebjmlKtZz7tXjkP+4= ) f.g.i.test. 600 IN TXT "test" 600 RRSIG TXT 7 4 600 20110914225156 ( 20110815225156 39833 test. kHJJeNSL1rz4QRYqOzhGMQl1yIdio7l8Lg8H f0TsvFLa6BudVtwKUm+Kz2QiDn7/Lew8w0KX vVHxX/Vwl3Ixk54YgMKLNogz2TEvnh/VGiS7 8r0oSUrg0CFd+xDfxnLeRqX5NNfMuSJap5WH Aw7IVeRjXDwJFYnytMEnTrhHHHg= ) f.g.j.test. 600 IN TXT "test" 600 RRSIG TXT 7 4 600 20110914225156 ( 20110815225156 39833 test. lIEHEhDFhOWK8W/F2xWELU2p/X77S2KTivm9 sY4k3RPsLNHE7p+lF8p72Lcb79rtltnoVYtE pTIiaUcmgGwfaI4cwfXbeuEgnuTiLg7Xrefx 3GT86Q+8gfgbMXUmRA/eouWZhCOaYJN99gYz urzDMiRLYmILHmLlnvo82SgXeuk= ) k.test. 600 IN TXT "test" 600 RRSIG TXT 7 2 600 20110914225156 ( 20110815225156 39833 test. wC3zgYWsuLga8Vu3QFu/Ci8SzRbA5bvjSmDj NzcpjU5cvJBxtgzatCr02AaUC94bI0JzNrEB nFyWCYw55lyy+bAHU1u05UcQmz0n5yxkvmHX i8ZjMyQkAvNKodJHaFQqUKKIDuSHD2EziKqg eNn55YRS11ihkODehUVNl7TnYeA= ) ns.test. 600 IN A 10.0.0.1 600 RRSIG A 7 2 600 20110914225156 ( 20110815225156 39833 test. VyK/WlQ6ikXdjF/arGzyAyYhOc8IYNBp4QLW gtYjvbjIcV5+9JINWmUs61VjJ14nES1sI0xb 9vQJuiPXTM1awUAnvOKLhaX6fbJaEiR1w6Cf RT5QKBMxNBKVStqdabHcigY4DUuc1PQk1vCw yMUJt3nHNVMZk+XAycNHzBeYjik= ) ns2.test. 600 IN A 10.0.0.2 600 RRSIG A 7 2 600 20110914225156 ( 20110815225156 39833 test. CX6UlZL+5NQJViKfbe/E3uIJk/wjUzoiHBhY B6gS8nxZzlRPdTTXyMZoRa4etTZEbrRjnyXk 1rP47faCUwbh//XqukN9f7FZ4Y39NpPS2XpX 0Lx6M93Jz46lbzmseMFs2YmNMzzhN4uhRvl/ 8gPtYsn9KMXnAlFfa4XrE5LNVyY= ) 1F3JQ6EANHNHOCMUPQTVNM339VDTR51C.test. 600 IN NSEC3 1 0 10 - 7QKPELF33JOK9BVJ7CKE99AHG40B0SH7 A RRSIG 600 RRSIG NSEC3 7 2 600 20110914225156 ( 20110815225156 39833 test. w7aS12lxLNh+G1B/2kEq1BO6IzYvyC8n/MGV 0jvFnapNXGZMPrPxGeO2wkw1JXepuXCv98be M4SjQywaH+VP6ZMTIfjxRxtcCM+aLAFhiz0l /MILEkjemmxjAfvV7emRVMwCGcoGI7qC3Xxq q5g8EzJiYyTCOnI5LKRggn97wGg= ) 7QKPELF33JOK9BVJ7CKE99AHG40B0SH7.test. 600 IN NSEC3 1 0 10 - 94Q15K1V1VE5F87EI37T2B9A39EEC368 TXT RRSIG 600 RRSIG NSEC3 7 2 600 20110914225156 ( 20110815225156 39833 test. J4ObL3p4eN0jWh06M+rX2SSPANQoKfnosElB KcKE7fLqEjKK7N6Yh6KUlbEP25tfeZ7W6GBJ b7q6Nh0Ax8fYdc/6JVvmxcwWcx5Lw1TfITGB ttFntJlbp1A8lwP3pn8Ksql1X2ogh78AsgTb X5kmXVukC1oEzt98EAa/V/an8QA= ) CS8M3UVG0UJDR6USBES4U9SNUGQI2RJE.test. 600 IN NSEC3 1 0 10 - ETEQB5V431INUIIE547FKSOF7O4DJ62J A RRSIG 600 RRSIG NSEC3 7 2 600 20110914225156 ( 20110815225156 39833 test. Vyd/2b0S15fACJ8TiPXKtScV9A/ZztVumZAm o2S6jaVJKWik+8orDW+WiJ4/PEl26PK2m1uv HD2beuUCHj9EnYkN/dzL3Bsc302qr9xqsh0q VFS2moznoNG415ZV3vgYR7L9DAp43ZeFuw6I 7sr21hLYLUeo31xBsJg7RlOL+4s= ) ETEQB5V431INUIIE547FKSOF7O4DJ62J.test. 600 IN NSEC3 1 0 10 - F8G1MB0JUEU3FBI11CAVFIPGEA3POOIM 600 RRSIG NSEC3 7 2 600 20110914225156 ( 20110815225156 39833 test. oOHs1eb3JYeOMOnzE2PS6NIXBNzSoTYPIxo/ P0d/ihsLKra3yNJNPTlu4kf+FZoNYAGtMK/D 6dZWFvtdswDdi2C5WSgsanuHqXq5Lr3A1nCe cQI5PO4RrLymB+MtYg15CNKcnc0WmJO8deSR WzNOarC+Iz1Xj3FkKDS4FFr+02Q= ) 94Q15K1V1VE5F87EI37T2B9A39EEC368.test. 600 IN NSEC3 1 0 10 - CS8M3UVG0UJDR6USBES4U9SNUGQI2RJE 600 RRSIG NSEC3 7 2 600 20110914225156 ( 20110815225156 39833 test. K0PvN7YtHQ63x/x2yXXa2S9GBGuTNJywDZ8M wyMSwytCb9mn4hnKD5mJHaXGTw3YX7usbnEO ce6hiJdN/VhMfbRMOvUpgyblOj4kXiYVZY1a SyycfugK/Hu1j4az7lIhhnnx58GChA6mg8Vx 3Uz6cNDDCSTBTl09NyeUUrKWsHQ= ) FBH6B0LHT9PPQB1P98D228HA1H52L8PO.test. 600 IN NSEC3 1 0 10 - JGU2L7C3LKLHAKC5RHUOORTI2DCKK3KL 600 RRSIG NSEC3 7 2 600 20110914225156 ( 20110815225156 39833 test. giXRE+4ZeIzDrhx1XkFSpIKGFd3UGzlrLZnO Ur9nMUfwvU5A3fitEkdayo3ZDH7MQGpSotaH ReiFXx3Z6Hm2NIN/RHYZQr9e0vbMYSjkANdu HWBA1SrSq5SHyuy970mPd4jfTHiABCo6fJGB ykGClZGou0WSaB+Ak19fMbeQ2Wo= ) JGU2L7C3LKLHAKC5RHUOORTI2DCKK3KL.test. 600 IN NSEC3 1 0 10 - KFMJ88CKMKUQQJE59IKFBOLLLD4DF55H TXT RRSIG 600 RRSIG NSEC3 7 2 600 20110914225156 ( 20110815225156 39833 test. BHTDUgZdWNLgz3xHYMqvlWK/IJ0xrXESoREc 6D3sO9bcLTMYPO9t80itOlipwp4AmaVOBXPt cKSdgsUXDEtHqNSxtGbNr5xQ+Aqsep0GX71V HkcIuiNdTUw83dkajCHMkmQCbEjp9mbdiTmS haNW2EsscldfaS1aq5tYUhCT3l4= ) L993U6VC0DUV5QJ8TRPD2IQLM8FJ7AT9.test. 600 IN NSEC3 1 0 10 - LSMRLLNBQGGK8J6V40KLM2LG5TE4FS0P 600 RRSIG NSEC3 7 2 600 20110914225156 ( 20110815225156 39833 test. vE7K0Nrju4qLFDYkIyMY5bIMT0wu8MJdxL6u 7WVA4HepccKQcUnvVoBAcrA9+MUeteyrad8Y SJvQIt7sz5t7FViWSq5IMPVPujWtW5J30LhJ mOLd1KmnFWoVthJ1oFNzBM80A60seKNnEw1M lV6Y+v0gNYIQensUb9w6SVMTpxE= ) F8G1MB0JUEU3FBI11CAVFIPGEA3POOIM.test. 600 IN NSEC3 1 0 10 - FA1T7MKUUV9SD4VDBJQ3GRFK1IDTCKL7 600 RRSIG NSEC3 7 2 600 20110914225156 ( 20110815225156 39833 test. DkL9ONc0vpsKdG20ol8XPAaVfLb7kf1wnKbR rQUB1trGSHm/Igo06of43zm9J+56htFJg1xD I2de0sCUBQYyHVBBDiBAd1g+ZvcpUlLP0w8M NxMviMiG/WQAdGXHwYfUimwMWD7gNGl1m05H HwYmzGs+d1bClDNBrFhdfdL2+iA= ) LSMRLLNBQGGK8J6V40KLM2LG5TE4FS0P.test. 600 IN NSEC3 1 0 10 - LUAN2Q3I2OCVSD41MP08HNA9JP22D38K 600 RRSIG NSEC3 7 2 600 20110914225156 ( 20110815225156 39833 test. ZgiWuMqodQuhwuAF6CIiJTsdRahi+poOiZAM WXNP0wXfdptcG2uhbdDwy+0crhe3tuybhwcb CuiaQUh0XNPhgF+qmXpGobaqBhCEvCF4K9qY OCIoMfsI1pIBVbMw0+YXVarFZ8+mfNU/+6n6 yy2+1nCg3k4XR2Dpv4CeDBfcAuM= ) NAL1UIEBM38NKMN6RQOKE8T781IA7UKI.test. 600 IN NSEC3 1 0 10 - OUSGP0LO9FGAROHDULQVSTI3OLQIBB39 TXT RRSIG 600 RRSIG NSEC3 7 2 600 20110914225156 ( 20110815225156 39833 test. x8JiXPI+EXHz8ZO/VW0/+9wWsBNqeSMxXZIV ibOnogSg7Wi7Yq1xftKC2+xEevNxSZnBibEy Sgro5xKTf0n7pD9hHVBLoYmOOnbXY3QNQ2EQ y3LdPT355WmwVddVOOxNpNRp2zQyqg7BhVA3 wxY7tyVQd4x1+95ATUQBnFditdE= ) KFMJ88CKMKUQQJE59IKFBOLLLD4DF55H.test. 600 IN NSEC3 1 0 10 - L993U6VC0DUV5QJ8TRPD2IQLM8FJ7AT9 TXT RRSIG 600 RRSIG NSEC3 7 2 600 20110914225156 ( 20110815225156 39833 test. KQPaN2Ecebifbl4Bz5Yo0x2DgGmZiVhpSydm oy/5NtMjt7G472JrKlqByap+VxW0bpzo3IER 3P8Dsv7pfBD4/Cl5sFqwZL7wYy7RB4dQLVCi Pepc/Mr3gR2XmL91fpGttMj5jGscnVQJCyFa obzhsVaVImUQZFDPb0UQUHwIhOA= ) LUAN2Q3I2OCVSD41MP08HNA9JP22D38K.test. 600 IN NSEC3 1 0 10 - NAL1UIEBM38NKMN6RQOKE8T781IA7UKI TXT RRSIG 600 RRSIG NSEC3 7 2 600 20110914225156 ( 20110815225156 39833 test. NJ+X3d0qh2+fbSnG0iQPxAeDIOzX5NTmY9fS x7IO/DDcgUhPvl1YYdz5J999cec1zzOKp10J YbsIAzg0w/Y4D4CBUw3IkcOrUFOODb6eJQGb rVFRqmp3BUP4qOAWUZvx4oQ0KG4K/h/KJMbU Vcdl7PF7G5O5hMyR9UWg4zal7Sk= ) OUSGP0LO9FGAROHDULQVSTI3OLQIBB39.test. 600 IN NSEC3 1 0 10 - PQQ28M3U2MM08GGFV3JKR76G2H9IUJPC TXT RRSIG 600 RRSIG NSEC3 7 2 600 20110914225156 ( 20110815225156 39833 test. A/qxYrSE/smBGbST8j8eGPCrRnwvVa25kDha IuA3nv0vzXhFvlruc9f0HRGwsq6A2pw3I5W+ xo2/JxsNyFOotdwaDDEBzqPkJmrzupxQS4Hm rHSLnRnNw4QzvzNjAGWMYAoe3OeHC47wmAtI qE91EHZTlPP28CUXOMo+7sCaOa8= ) U0UVS2SUP89P2TM3PJO4TC1GPJ2O6519.test. 600 IN NSEC3 1 0 10 - VA2VG5BEMCKQP6MS5NHHGL18031BIA7M NS SOA RRSIG DNSKEY NSEC3PARAM 600 RRSIG NSEC3 7 2 600 20110914225156 ( 20110815225156 39833 test. rahhkfiF+Rk6oqbWTdu9qcwhmj5hbDuIFdiJ GmaG+cFSv5Mjp+txNVCvBK9Hq/VpW0ypen/3 JC0sVAugSX+HAKAgyaMKmgWCvoQZ6ZSJUh7o LRPcT+oxVXQAqjovxpaV8k6sYo44tpljPdOD UluWAP5SrmJKjzCxs27KGRx8MK4= ) VA2VG5BEMCKQP6MS5NHHGL18031BIA7M.test. 600 IN NSEC3 1 0 10 - VAKOQ2TPD7S25NFBJT73J3C4OGU10RJ5 TXT RRSIG 600 RRSIG NSEC3 7 2 600 20110914225156 ( 20110815225156 39833 test. XcBeZ8lo9Qo8z56+1FdGDjh6ZHCfO+MQ/wnY TEUo/aWLkPTyq39nLhe0qVBJxmDpM+KQFuG9 cjQT5fvrlrY+lv6dedB64EBMYy4kKbIv7N5+ r6+sfWlvtKsfXxysLSk2+jLEm5NuLFrOdNas WLVsq741D3YcWt4kM1HCyk3DNF8= ) FA1T7MKUUV9SD4VDBJQ3GRFK1IDTCKL7.test. 600 IN NSEC3 1 0 10 - FBH6B0LHT9PPQB1P98D228HA1H52L8PO TXT RRSIG 600 RRSIG NSEC3 7 2 600 20110914225156 ( 20110815225156 39833 test. jB/vLrvx4sQQD7J3ZacAAyhcFmIPh7LH3ljw IAIaeLb10oX5q1/nQKYdfq976TMy5sWpBcmd i91WLxd+T/gOSumyP8bC3g+SUoyZ9wxY6A6a MMx1rn0QA9IKrxMqojs9M3urJ8QAeIS+KyAn rbyyJuG+EVm0prqlPZtzUi28WCI= ) PQQ28M3U2MM08GGFV3JKR76G2H9IUJPC.test. 600 IN NSEC3 1 0 10 - U0UVS2SUP89P2TM3PJO4TC1GPJ2O6519 600 RRSIG NSEC3 7 2 600 20110914225156 ( 20110815225156 39833 test. asCOU9OkVWMvUU2IUpwMgdYf0faA04zPbaFf qywYsv3NH01Lky6G3a0WUPAbBm7TAYx/ln8a 559vlpp/gpXEl9CcLrjO6wy5i0ryp8gVHtKJ rQlEc/uw4SY+S5t7FuZc2rNRdAbxVMYuwrvm HBsKDPblre3e06ZZFEmnGFzCgmg= ) VAKOQ2TPD7S25NFBJT73J3C4OGU10RJ5.test. 600 IN NSEC3 1 0 10 - VNCCJH8JPOLGLAGVMV3FKS09M7RRDU47 TXT RRSIG 600 RRSIG NSEC3 7 2 600 20110914225156 ( 20110815225156 39833 test. Pt4tKB1p/jsyLYab9LSt5MF1KTRT18nRTOox q0IACkXkKx7W5xv6nSYXIB+nQzNp1Y1hhoXn 9IFi0liPnIAOp73w4vybhfIdTFiEmHPHT6O9 VIx5cSriqBI6Qda8GtfeIb96P8SojbUk5BDI g18iYjviGhQYRgpU3tg1qd7pbcc= ) VNCCJH8JPOLGLAGVMV3FKS09M7RRDU47.test. 600 IN NSEC3 1 0 10 - 1F3JQ6EANHNHOCMUPQTVNM339VDTR51C 600 RRSIG NSEC3 7 2 600 20110914225156 ( 20110815225156 39833 test. ZMZPHawhkuzSV7C7zkgghH/jpw9CQVR1JUXq pAeY2iIIWwNhfuskJaLgtu/5SuKnJtrv6D4N g+lfEkBReia5xO/SCcHv8/hXEPH8vZ4xe1C9 6GVB6ip2hKw2g5HpyF7X18WgwZ0cqPWVg+Q+ xRLpXH+53391Wt5rG7qJswn5RLE= ) bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/dbiterator/zone1.data0000644000470500017500000000222712664710322023727 0ustar lamontlamont; Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above ; copyright notice and this permission notice appear in all copies. ; ; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. ; $Id$ $TTL 600 @ in soa localhost. postmaster.localhost. ( 2011080901 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 600 ) ;minimum in ns ns in ns ns2 ns in a 10.0.0.1 ns2 in a 10.0.0.2 a in txt "test" b in txt "test" c in txt "test" d.e.f in txt "test" e in txt "test" f.g.h in txt "test" f.g.i in txt "test" f.g.j in txt "test" k in txt "test" bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/diff/0002755000470500017500000000000012672612753020620 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/diff/zone3.data0000644000470500017500000000150012664710322022473 0ustar lamontlamont; Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above ; copyright notice and this permission notice appear in all copies. ; ; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. ; $Id$ @ 0 SOA . . 0 0 0 0 0 @ 0 NS @ @ 0 A 1.2.3.4 bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/diff/zone2.data0000644000470500017500000000154512664710322022503 0ustar lamontlamont; Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above ; copyright notice and this permission notice appear in all copies. ; ; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. ; $Id$ @ 0 SOA . . 0 0 0 0 0 @ 0 NS @ @ 0 A 1.2.3.4 remove 0 A 5.6.7.8 added 0 A 5.6.7.8 bind9-9.10.3.dfsg.P4/lib/dns/tests/testdata/diff/zone1.data0000644000470500017500000000152312664710322022476 0ustar lamontlamont; Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above ; copyright notice and this permission notice appear in all copies. ; ; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. ; $Id$ @ 0 SOA . . 0 0 0 0 0 @ 0 NS @ @ 0 A 1.2.3.4 remove 0 A 5.6.7.8 bind9-9.10.3.dfsg.P4/lib/dns/tests/dbversion_test.c0000644000470500017500000004171512664710322021273 0ustar lamontlamont/* * Copyright (C) 2011, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dnstest.h" static char tempname[11] = "dtXXXXXXXX"; static void local_callback(const char *file, int line, isc_assertiontype_t type, const char *cond) { UNUSED(file); UNUSED(line); UNUSED(type); UNUSED(cond); if (strcmp(tempname, "dtXXXXXXXX")) unlink(tempname); atf_tc_pass(); exit(0); } static dns_db_t *db1 = NULL, *db2 = NULL; static dns_dbversion_t *v1 = NULL, *v2 = NULL; static void setup_db(void) { isc_result_t result; result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, dns_rdataclass_in, 0, NULL, &db1); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_db_newversion(db1, &v1); result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, dns_rdataclass_in, 0, NULL, &db2); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_db_newversion(db2, &v2); } static void close_db(void) { if (v1 != NULL) { dns_db_closeversion(db1, &v1, ISC_FALSE); ATF_REQUIRE_EQ(v1, NULL); } if (db1 != NULL) { dns_db_detach(&db1); ATF_REQUIRE_EQ(db1, NULL); } if (v2 != NULL) { dns_db_closeversion(db2, &v2, ISC_FALSE); ATF_REQUIRE_EQ(v2, NULL); } if (db2 != NULL) { dns_db_detach(&db2); ATF_REQUIRE_EQ(db2, NULL); } } #define VERSION(callback) ((callback == NULL) ? v1 : v2) #define VERSIONP(callback) ((callback == NULL) ? &v1 : &v2) /* * Individual unit tests */ static void attachversion(isc_assertioncallback_t callback) { isc_result_t result; dns_dbversion_t *v = NULL; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); setup_db(); isc_assertion_setcallback(callback); dns_db_attachversion(db1, VERSION(callback), &v); if (callback != NULL) atf_tc_fail("dns_db_attachversion did not assert"); ATF_REQUIRE_EQ(v, v1); dns_db_closeversion(db1, &v, ISC_FALSE); ATF_REQUIRE_EQ(v, NULL); close_db(); dns_test_end(); } ATF_TC(attachversion); ATF_TC_HEAD(attachversion, tc) { atf_tc_set_md_var(tc, "descr", "check dns_db_attachversion passes with matching db/verison"); } ATF_TC_BODY(attachversion, tc) { UNUSED(tc); attachversion(NULL); } ATF_TC(attachversion_bad); ATF_TC_HEAD(attachversion_bad, tc) { atf_tc_set_md_var(tc, "descr", "check dns_db_attachversion aborts with mis-matching db/verison"); } ATF_TC_BODY(attachversion_bad, tc) { UNUSED(tc); attachversion(local_callback); } static void closeversion(isc_assertioncallback_t callback) { isc_result_t result; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); setup_db(); isc_assertion_setcallback(callback); dns_db_closeversion(db1, VERSIONP(callback), ISC_FALSE); if (callback != NULL) atf_tc_fail("dns_db_closeversion did not assert"); ATF_REQUIRE_EQ(v1, NULL); close_db(); dns_test_end(); } ATF_TC(closeversion); ATF_TC_HEAD(closeversion, tc) { atf_tc_set_md_var(tc, "descr", "check dns_db_closeversion passes with matching db/verison"); } ATF_TC_BODY(closeversion, tc) { UNUSED(tc); closeversion(NULL); } ATF_TC(closeversion_bad); ATF_TC_HEAD(closeversion_bad, tc) { atf_tc_set_md_var(tc, "descr", "check dns_db_closeversion asserts with mis-matching db/verison"); } ATF_TC_BODY(closeversion_bad, tc) { UNUSED(tc); closeversion(local_callback); } static void find(isc_assertioncallback_t callback) { isc_result_t result; dns_rdataset_t rdataset; dns_fixedname_t fixed; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); setup_db(); dns_rdataset_init(&rdataset); dns_fixedname_init(&fixed); isc_assertion_setcallback(callback); result = dns_db_find(db1, dns_rootname, VERSION(callback), dns_rdatatype_soa, 0, 0, NULL, dns_fixedname_name(&fixed), &rdataset, NULL); if (callback != NULL) atf_tc_fail("dns_db_find did not assert"); ATF_REQUIRE_EQ(result, DNS_R_NXDOMAIN); close_db(); dns_test_end(); } ATF_TC(find); ATF_TC_HEAD(find, tc) { atf_tc_set_md_var(tc, "descr", "check dns_db_find passes with matching db/version"); } ATF_TC_BODY(find, tc) { UNUSED(tc); find(NULL); } ATF_TC(find_bad); ATF_TC_HEAD(find_bad, tc) { atf_tc_set_md_var(tc, "descr", "check dns_db_find asserts with mis-matching db/version"); } ATF_TC_BODY(find_bad, tc) { UNUSED(tc); find(local_callback); } static void allrdatasets(isc_assertioncallback_t callback) { isc_result_t result; dns_dbnode_t *node = NULL; dns_rdatasetiter_t *iterator = NULL; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); setup_db(); result = dns_db_findnode(db1, dns_rootname, ISC_FALSE, &node); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); isc_assertion_setcallback(callback); result = dns_db_allrdatasets(db1, node, VERSION(callback), 0, &iterator); if (callback != NULL) atf_tc_fail("dns_db_allrdatasets did not assert"); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_rdatasetiter_destroy(&iterator); ATF_REQUIRE_EQ(iterator, NULL); dns_db_detachnode(db1, &node); ATF_REQUIRE_EQ(node, NULL); close_db(); dns_test_end(); } ATF_TC(allrdatasets); ATF_TC_HEAD(allrdatasets, tc) { atf_tc_set_md_var(tc, "descr", "check dns_db_allrdatasets passes with matching db/version"); } ATF_TC_BODY(allrdatasets, tc) { UNUSED(tc); allrdatasets(NULL); } ATF_TC(allrdatasets_bad); ATF_TC_HEAD(allrdatasets_bad, tc) { atf_tc_set_md_var(tc, "descr", "check dns_db_allrdatasets aborts with mis-matching db/version"); } ATF_TC_BODY(allrdatasets_bad, tc) { UNUSED(tc); allrdatasets(local_callback); } static void findrdataset(isc_assertioncallback_t callback) { isc_result_t result; dns_rdataset_t rdataset; dns_fixedname_t fixed; dns_dbnode_t *node = NULL; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); setup_db(); dns_rdataset_init(&rdataset); dns_fixedname_init(&fixed); result = dns_db_findnode(db1, dns_rootname, ISC_FALSE, &node); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); isc_assertion_setcallback(callback); result = dns_db_findrdataset(db1, node, VERSION(callback), dns_rdatatype_soa, 0, 0, &rdataset, NULL); if (callback != NULL) atf_tc_fail("dns_db_findrdataset did not assert"); ATF_REQUIRE_EQ(result, ISC_R_NOTFOUND); dns_db_detachnode(db1, &node); ATF_REQUIRE_EQ(node, NULL); close_db(); dns_test_end(); } ATF_TC(findrdataset); ATF_TC_HEAD(findrdataset, tc) { atf_tc_set_md_var(tc, "descr", "check dns_db_findrdataset passes with matching db/version"); } ATF_TC_BODY(findrdataset, tc) { UNUSED(tc); findrdataset(NULL); } ATF_TC(findrdataset_bad); ATF_TC_HEAD(findrdataset_bad, tc) { atf_tc_set_md_var(tc, "descr", "check dns_db_findrdataset aborts with mis-matching db/version"); } ATF_TC_BODY(findrdataset_bad, tc) { UNUSED(tc); findrdataset(local_callback); } static void deleterdataset(isc_assertioncallback_t callback) { isc_result_t result; dns_rdataset_t rdataset; dns_fixedname_t fixed; dns_dbnode_t *node = NULL; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); setup_db(); dns_rdataset_init(&rdataset); dns_fixedname_init(&fixed); result = dns_db_findnode(db1, dns_rootname, ISC_FALSE, &node); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); isc_assertion_setcallback(callback); result = dns_db_deleterdataset(db1, node, VERSION(callback), dns_rdatatype_soa, 0); if (callback != NULL) atf_tc_fail("dns_db_deleterdataset did not assert"); ATF_REQUIRE_EQ(result, DNS_R_UNCHANGED); dns_db_detachnode(db1, &node); ATF_REQUIRE_EQ(node, NULL); close_db(); dns_test_end(); } ATF_TC(deleterdataset); ATF_TC_HEAD(deleterdataset, tc) { atf_tc_set_md_var(tc, "descr", "check dns_db_deleterdataset passes with matching db/version"); } ATF_TC_BODY(deleterdataset, tc) { UNUSED(tc); deleterdataset(NULL); } ATF_TC(deleterdataset_bad); ATF_TC_HEAD(deleterdataset_bad, tc) { atf_tc_set_md_var(tc, "descr", "check dns_db_deleterdataset aborts with mis-matching db/version"); } ATF_TC_BODY(deleterdataset_bad, tc) { UNUSED(tc); deleterdataset(local_callback); } static void subtract(isc_assertioncallback_t callback) { isc_result_t result; dns_rdataset_t rdataset; dns_fixedname_t fixed; dns_dbnode_t *node = NULL; dns_rdatalist_t rdatalist; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); setup_db(); dns_rdataset_init(&rdataset); dns_rdatalist_init(&rdatalist); dns_fixedname_init(&fixed); rdatalist.rdclass = dns_rdataclass_in; result = dns_rdatalist_tordataset(&rdatalist, &rdataset); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_findnode(db1, dns_rootname, ISC_FALSE, &node); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); isc_assertion_setcallback(callback); result = dns_db_subtractrdataset(db1, node, VERSION(callback), &rdataset, 0, NULL); if (callback != NULL) atf_tc_fail("dns_db_dns_db_subtractrdataset did not assert"); ATF_REQUIRE_EQ(result, DNS_R_UNCHANGED); dns_db_detachnode(db1, &node); ATF_REQUIRE_EQ(node, NULL); close_db(); dns_test_end(); } ATF_TC(subtractrdataset); ATF_TC_HEAD(subtractrdataset, tc) { atf_tc_set_md_var(tc, "descr", "check dns_db_subtractrdataset passes with matching db/version"); } ATF_TC_BODY(subtractrdataset, tc) { UNUSED(tc); subtract(NULL); } ATF_TC(subtractrdataset_bad); ATF_TC_HEAD(subtractrdataset_bad, tc) { atf_tc_set_md_var(tc, "descr", "check dns_db_subtractrdataset aborts with mis-matching db/version"); } ATF_TC_BODY(subtractrdataset_bad, tc) { UNUSED(tc); subtract(local_callback); } static void dump(isc_assertioncallback_t callback) { isc_result_t result; FILE *f = NULL; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); setup_db(); result = isc_file_openunique(tempname, &f); fclose(f); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); isc_assertion_setcallback(callback); result = dns_db_dump(db1, VERSION(callback), tempname); (void)unlink(tempname); if (callback != NULL) atf_tc_fail("dns_db_dump did not assert"); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); close_db(); dns_test_end(); } ATF_TC(dump); ATF_TC_HEAD(dump, tc) { atf_tc_set_md_var(tc, "descr", "check dns_db_dump passes with matching db/version"); } ATF_TC_BODY(dump, tc) { UNUSED(tc); dump(NULL); } ATF_TC(dump_bad); ATF_TC_HEAD(dump_bad, tc) { atf_tc_set_md_var(tc, "descr", "check dns_db_dump aborts with mis-matching db/version"); } ATF_TC_BODY(dump_bad, tc) { UNUSED(tc); dump(local_callback); } static void addrdataset(isc_assertioncallback_t callback) { isc_result_t result; dns_rdataset_t rdataset; dns_fixedname_t fixed; dns_dbnode_t *node = NULL; dns_rdatalist_t rdatalist; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); setup_db(); dns_rdataset_init(&rdataset); dns_rdatalist_init(&rdatalist); dns_fixedname_init(&fixed); rdatalist.rdclass = dns_rdataclass_in; result = dns_rdatalist_tordataset(&rdatalist, &rdataset); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_findnode(db1, dns_rootname, ISC_FALSE, &node); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); isc_assertion_setcallback(callback); result = dns_db_addrdataset(db1, node, VERSION(callback), 0, &rdataset, 0, NULL); if (callback != NULL) atf_tc_fail("dns_db_adddataset did not assert"); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_db_detachnode(db1, &node); ATF_REQUIRE_EQ(node, NULL); close_db(); dns_test_end(); } ATF_TC(addrdataset); ATF_TC_HEAD(addrdataset, tc) { atf_tc_set_md_var(tc, "descr", "check dns_db_addrdataset passes with matching db/version"); } ATF_TC_BODY(addrdataset, tc) { UNUSED(tc); addrdataset(NULL); } ATF_TC(addrdataset_bad); ATF_TC_HEAD(addrdataset_bad, tc) { atf_tc_set_md_var(tc, "descr", "check dns_db_addrdataset aborts with mis-matching db/version"); } ATF_TC_BODY(addrdataset_bad, tc) { UNUSED(tc); addrdataset(local_callback); } static void getnsec3parameters(isc_assertioncallback_t callback) { isc_result_t result; dns_hash_t hash; isc_uint8_t flags; isc_uint16_t iterations; unsigned char salt[DNS_NSEC3_SALTSIZE]; size_t salt_length = sizeof(salt); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); setup_db(); isc_assertion_setcallback(callback); result = dns_db_getnsec3parameters(db1, VERSION(callback), &hash, &flags, &iterations, salt, &salt_length); if (callback != NULL) atf_tc_fail("dns_db_dump did not assert"); ATF_REQUIRE_EQ(result, ISC_R_NOTFOUND); close_db(); dns_test_end(); } ATF_TC(getnsec3parameters); ATF_TC_HEAD(getnsec3parameters, tc) { atf_tc_set_md_var(tc, "descr", "check dns_db_getnsec3parameters passes with matching db/version"); } ATF_TC_BODY(getnsec3parameters, tc) { UNUSED(tc); getnsec3parameters(NULL); } ATF_TC(getnsec3parameters_bad); ATF_TC_HEAD(getnsec3parameters_bad, tc) { atf_tc_set_md_var(tc, "descr", "check dns_db_getnsec3parameters aborts with mis-matching db/version"); } ATF_TC_BODY(getnsec3parameters_bad, tc) { UNUSED(tc); getnsec3parameters(local_callback); } static void resigned(isc_assertioncallback_t callback) { isc_result_t result; dns_rdataset_t rdataset, added; dns_dbnode_t *node = NULL; dns_rdatalist_t rdatalist; dns_rdata_rrsig_t rrsig; dns_rdata_t rdata = DNS_RDATA_INIT; isc_buffer_t b; unsigned char buf[1024]; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); setup_db(); /* * Create a dummy RRSIG record and set a resigning time. */ dns_rdataset_init(&added); dns_rdataset_init(&rdataset); dns_rdatalist_init(&rdatalist); isc_buffer_init(&b, buf, sizeof(buf)); DNS_RDATACOMMON_INIT(&rrsig, dns_rdatatype_rrsig, dns_rdataclass_in); rrsig.covered = dns_rdatatype_a; rrsig.algorithm = 100; rrsig.labels = 0; rrsig.originalttl = 0; rrsig.timeexpire = 3600; rrsig.timesigned = 0; rrsig.keyid = 0; dns_name_init(&rrsig.signer, NULL); dns_name_clone(dns_rootname, &rrsig.signer); rrsig.siglen = 0; rrsig.signature = NULL; result = dns_rdata_fromstruct(&rdata, dns_rdataclass_in, dns_rdatatype_rrsig, &rrsig, &b); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); rdatalist.rdclass = dns_rdataclass_in; rdatalist.type = dns_rdatatype_rrsig; ISC_LIST_APPEND(rdatalist.rdata, &rdata, link); result = dns_rdatalist_tordataset(&rdatalist, &rdataset); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); rdataset.attributes |= DNS_RDATASETATTR_RESIGN; rdataset.resign = 7200; result = dns_db_findnode(db1, dns_rootname, ISC_FALSE, &node); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_addrdataset(db1, node, v1, 0, &rdataset, 0, &added); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_db_detachnode(db1, &node); ATF_REQUIRE_EQ(node, NULL); isc_assertion_setcallback(callback); dns_db_resigned(db1, &added, VERSION(callback)); if (callback != NULL) atf_tc_fail("dns_db_resigned did not assert"); dns_rdataset_disassociate(&added); close_db(); dns_test_end(); } ATF_TC(resigned); ATF_TC_HEAD(resigned, tc) { atf_tc_set_md_var(tc, "descr", "check dns_rdataset_resigned passes with matching db/version"); } ATF_TC_BODY(resigned, tc) { UNUSED(tc); resigned(NULL); } ATF_TC(resigned_bad); ATF_TC_HEAD(resigned_bad, tc) { atf_tc_set_md_var(tc, "descr", "check dns_rdataset_resigned aborts with mis-matching db/version"); } ATF_TC_BODY(resigned_bad, tc) { UNUSED(tc); resigned(local_callback); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, dump); ATF_TP_ADD_TC(tp, dump_bad); ATF_TP_ADD_TC(tp, find); ATF_TP_ADD_TC(tp, find_bad); ATF_TP_ADD_TC(tp, allrdatasets); ATF_TP_ADD_TC(tp, allrdatasets_bad); ATF_TP_ADD_TC(tp, findrdataset); ATF_TP_ADD_TC(tp, findrdataset_bad); ATF_TP_ADD_TC(tp, addrdataset); ATF_TP_ADD_TC(tp, addrdataset_bad); ATF_TP_ADD_TC(tp, deleterdataset); ATF_TP_ADD_TC(tp, deleterdataset_bad); ATF_TP_ADD_TC(tp, subtractrdataset); ATF_TP_ADD_TC(tp, subtractrdataset_bad); ATF_TP_ADD_TC(tp, attachversion); ATF_TP_ADD_TC(tp, attachversion_bad); ATF_TP_ADD_TC(tp, closeversion); ATF_TP_ADD_TC(tp, closeversion_bad); ATF_TP_ADD_TC(tp, getnsec3parameters); ATF_TP_ADD_TC(tp, getnsec3parameters_bad); ATF_TP_ADD_TC(tp, resigned); ATF_TP_ADD_TC(tp, resigned_bad); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/dns/tests/Makefile.in0000644000470500017500000001646712664710322020150 0ustar lamontlamont# Copyright (C) 2011-2014 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id$ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ # Attempt to disable parallel processing. .NOTPARALLEL: .NO_PARALLEL: @BIND9_VERSION@ @BIND9_MAKE_INCLUDES@ CINCLUDES = -I. -Iinclude ${DNS_INCLUDES} ${ISC_INCLUDES} \ @DST_OPENSSL_INC@ CDEFINES = @CRYPTO@ -DTESTS="\"${top_builddir}/lib/dns/tests/\"" ISCLIBS = ../../isc/libisc.@A@ ISCDEPLIBS = ../../isc/libisc.@A@ DNSLIBS = ../libdns.@A@ @DNS_CRYPTO_LIBS@ DNSDEPLIBS = ../libdns.@A@ LIBS = @LIBS@ @ATFLIBS@ OBJS = dnstest.@O@ SRCS = db_test.c \ dbdiff_test.c \ dbiterator_test.c \ dh_test.c \ dispatch_test.c \ dnstest.c \ geoip_test.c \ gost_test.c \ master_test.c \ name_test.c \ nsec3_test.c \ peer_test.c \ private_test.c \ rbt_test.c \ rbt_serialize_test.c \ rdata_test.c \ rdataset_test.c \ rdatasetstats_test.c \ time_test.c \ update_test.c \ zonemgr_test.c \ zt_test.c SUBDIRS = TARGETS = db_test@EXEEXT@ \ dbdiff_test@EXEEXT@ \ dbiterator_test@EXEEXT@ \ dbversion_test@EXEEXT@ \ dh_test@EXEEXT@ \ dispatch_test@EXEEXT@ \ geoip_test@EXEEXT@ \ gost_test@EXEEXT@ \ master_test@EXEEXT@ \ name_test@EXEEXT@ \ nsec3_test@EXEEXT@ \ peer_test@EXEEXT@ \ private_test@EXEEXT@ \ rbt_test@EXEEXT@ \ rbt_serialize_test@EXEEXT@ \ rdata_test@EXEEXT@ \ rdataset_test@EXEEXT@ \ rdatasetstats_test@EXEEXT@ \ time_test@EXEEXT@ \ update_test@EXEEXT@ \ zonemgr_test@EXEEXT@ \ zt_test@EXEEXT@ @BIND9_MAKE_RULES@ master_test@EXEEXT@: master_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} test -d testdata || mkdir testdata test -d testdata/master || mkdir testdata/master ${PERL} ${srcdir}/mkraw.pl < ${srcdir}/testdata/master/master12.data.in \ > testdata/master/master12.data ${PERL} ${srcdir}/mkraw.pl < ${srcdir}/testdata/master/master13.data.in \ > testdata/master/master13.data ${PERL} ${srcdir}/mkraw.pl < ${srcdir}/testdata/master/master14.data.in \ > testdata/master/master14.data ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ master_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} time_test@EXEEXT@: time_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ time_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} peer_test@EXEEXT@: peer_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ peer_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} private_test@EXEEXT@: private_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ private_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} update_test@EXEEXT@: update_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ update_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} zonemgr_test@EXEEXT@: zonemgr_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ zonemgr_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} dbiterator_test@EXEEXT@: dbiterator_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ dbiterator_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} dbdiff_test@EXEEXT@: dbdiff_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ dbdiff_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} dbversion_test@EXEEXT@: dbversion_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ dbversion_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} zt_test@EXEEXT@: zt_test.@O@ dnstest.@O@ \ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ zt_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} name_test@EXEEXT@: name_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ name_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} nsec3_test@EXEEXT@: nsec3_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ nsec3_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} rdataset_test@EXEEXT@: rdataset_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ rdataset_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} dispatch_test@EXEEXT@: dispatch_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ dispatch_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} rdatasetstats_test@EXEEXT@: rdatasetstats_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ rdatasetstats_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} rbt_test@EXEEXT@: rbt_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ rbt_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} rbt_serialize_test@EXEEXT@: rbt_serialize_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ rbt_serialize_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} rdata_test@EXEEXT@: rdata_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ rdata_test.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} geoip_test@EXEEXT@: geoip_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ geoip_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} db_test@EXEEXT@: db_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ db_test.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} gost_test@EXEEXT@: gost_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ gost_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} dh_test@EXEEXT@: dh_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ dh_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} unit:: sh ${top_srcdir}/unit/unittest.sh clean distclean:: rm -f ${TARGETS} rm -f atf.out rm -f testdata/master/master12.data testdata/master/master13.data \ testdata/master/master14.data rm -f zone.bin bind9-9.10.3.dfsg.P4/lib/dns/tests/rdataset_test.c0000644000470500017500000000635712664710322021112 0ustar lamontlamont/* * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include "dnstest.h" /* * Individual unit tests */ /* Successful load test */ ATF_TC(trimttl); ATF_TC_HEAD(trimttl, tc) { atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() loads a " "valid master file and returns success"); } ATF_TC_BODY(trimttl, tc) { isc_result_t result; dns_rdataset_t rdataset, sigrdataset; dns_rdata_rrsig_t rrsig; isc_stdtime_t ttltimenow, ttltimeexpire; ttltimenow = 10000000; ttltimeexpire = ttltimenow + 800; UNUSED(tc); dns_rdataset_init(&rdataset); dns_rdataset_init(&sigrdataset); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); rdataset.ttl = 900; sigrdataset.ttl = 1000; rrsig.timeexpire = ttltimeexpire; rrsig.originalttl = 1000; dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow, ISC_TRUE); ATF_REQUIRE_EQ(rdataset.ttl, 800); ATF_REQUIRE_EQ(sigrdataset.ttl, 800); rdataset.ttl = 900; sigrdataset.ttl = 1000; rrsig.timeexpire = ttltimenow - 200; rrsig.originalttl = 1000; dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow, ISC_TRUE); ATF_REQUIRE_EQ(rdataset.ttl, 120); ATF_REQUIRE_EQ(sigrdataset.ttl, 120); rdataset.ttl = 900; sigrdataset.ttl = 1000; rrsig.timeexpire = ttltimenow - 200; rrsig.originalttl = 1000; dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow, ISC_FALSE); ATF_REQUIRE_EQ(rdataset.ttl, 0); ATF_REQUIRE_EQ(sigrdataset.ttl, 0); sigrdataset.ttl = 900; rdataset.ttl = 1000; rrsig.timeexpire = ttltimeexpire; rrsig.originalttl = 1000; dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow, ISC_TRUE); ATF_REQUIRE_EQ(rdataset.ttl, 800); ATF_REQUIRE_EQ(sigrdataset.ttl, 800); sigrdataset.ttl = 900; rdataset.ttl = 1000; rrsig.timeexpire = ttltimenow - 200; rrsig.originalttl = 1000; dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow, ISC_TRUE); ATF_REQUIRE_EQ(rdataset.ttl, 120); ATF_REQUIRE_EQ(sigrdataset.ttl, 120); sigrdataset.ttl = 900; rdataset.ttl = 1000; rrsig.timeexpire = ttltimenow - 200; rrsig.originalttl = 1000; dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow, ISC_FALSE); ATF_REQUIRE_EQ(rdataset.ttl, 0); ATF_REQUIRE_EQ(sigrdataset.ttl, 0); dns_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, trimttl); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/dns/tests/peer_test.c0000644000470500017500000000750712664710322020234 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #include #include "dnstest.h" /* * Individual unit tests */ ATF_TC(dscp); ATF_TC_HEAD(dscp, tc) { atf_tc_set_md_var(tc, "descr", "Test DSCP set/get functions"); } ATF_TC_BODY(dscp, tc) { isc_result_t result; isc_netaddr_t netaddr; struct in_addr ina; dns_peer_t *peer = NULL; isc_dscp_t dscp; result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* * Create peer structure for the loopback address. */ ina.s_addr = INADDR_LOOPBACK; isc_netaddr_fromin(&netaddr, &ina); result = dns_peer_new(mctx, &netaddr, &peer); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* * All should be not set on creation. * 'dscp' should remain unchanged. */ dscp = 100; result = dns_peer_getquerydscp(peer, &dscp); ATF_REQUIRE_EQ(result, ISC_R_NOTFOUND); ATF_REQUIRE_EQ(dscp, 100); result = dns_peer_getnotifydscp(peer, &dscp); ATF_REQUIRE_EQ(result, ISC_R_NOTFOUND); ATF_REQUIRE_EQ(dscp, 100); result = dns_peer_gettransferdscp(peer, &dscp); ATF_REQUIRE_EQ(result, ISC_R_NOTFOUND); ATF_REQUIRE_EQ(dscp, 100); /* * Test that setting query dscp does not affect the other * dscp values. 'dscp' should remain unchanged until * dns_peer_getquerydscp is called. */ dscp = 100; result = dns_peer_setquerydscp(peer, 1); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_peer_getnotifydscp(peer, &dscp); ATF_REQUIRE_EQ(result, ISC_R_NOTFOUND); ATF_REQUIRE_EQ(dscp, 100); result = dns_peer_gettransferdscp(peer, &dscp); ATF_REQUIRE_EQ(result, ISC_R_NOTFOUND); ATF_REQUIRE_EQ(dscp, 100); result = dns_peer_getquerydscp(peer, &dscp); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(dscp, 1); /* * Test that setting notify dscp does not affect the other * dscp values. 'dscp' should remain unchanged until * dns_peer_getquerydscp is called then should change again * on dns_peer_getnotifydscp. */ dscp = 100; result = dns_peer_setnotifydscp(peer, 2); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_peer_gettransferdscp(peer, &dscp); ATF_REQUIRE_EQ(result, ISC_R_NOTFOUND); ATF_REQUIRE_EQ(dscp, 100); result = dns_peer_getquerydscp(peer, &dscp); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(dscp, 1); result = dns_peer_getnotifydscp(peer, &dscp); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(dscp, 2); /* * Test that setting notify dscp does not affect the other * dscp values. Check that appropriate values are returned. */ dscp = 100; result = dns_peer_settransferdscp(peer, 3); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_peer_getquerydscp(peer, &dscp); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(dscp, 1); result = dns_peer_getnotifydscp(peer, &dscp); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(dscp, 2); result = dns_peer_gettransferdscp(peer, &dscp); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(dscp, 3); dns_peer_detach(&peer); dns_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, dscp); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/dns/tests/rdatasetstats_test.c0000644000470500017500000001104012664710322022152 0ustar lamontlamont/* * Copyright (C) 2012, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include "dnstest.h" /* * Helper functions */ static void set_typestats(dns_stats_t *stats, dns_rdatatype_t type, isc_boolean_t stale) { dns_rdatastatstype_t which; unsigned int attributes; attributes = 0; if (stale) attributes |= DNS_RDATASTATSTYPE_ATTR_STALE; which = DNS_RDATASTATSTYPE_VALUE(type, attributes); dns_rdatasetstats_increment(stats, which); attributes = DNS_RDATASTATSTYPE_ATTR_NXRRSET; if (stale) attributes |= DNS_RDATASTATSTYPE_ATTR_STALE; which = DNS_RDATASTATSTYPE_VALUE(type, attributes); dns_rdatasetstats_increment(stats, which); } static void set_nxdomainstats(dns_stats_t *stats, isc_boolean_t stale) { dns_rdatastatstype_t which; unsigned int attributes; attributes = DNS_RDATASTATSTYPE_ATTR_NXDOMAIN; if (stale) attributes |= DNS_RDATASTATSTYPE_ATTR_STALE; which = DNS_RDATASTATSTYPE_VALUE(0, attributes); dns_rdatasetstats_increment(stats, which); } static void checkit1(dns_rdatastatstype_t which, isc_uint64_t value, void *arg) { unsigned int attributes; #if debug unsigned int type; #endif UNUSED(which); UNUSED(arg); attributes = DNS_RDATASTATSTYPE_ATTR(which); #if debug type = DNS_RDATASTATSTYPE_BASE(which); fprintf(stderr, "%s%s%s%s/%u, %u\n", attributes & DNS_RDATASTATSTYPE_ATTR_OTHERTYPE ? "O" : " ", attributes & DNS_RDATASTATSTYPE_ATTR_NXRRSET ? "!" : " ", attributes & DNS_RDATASTATSTYPE_ATTR_STALE ? "#" : " ", attributes & DNS_RDATASTATSTYPE_ATTR_NXDOMAIN ? "X" : " ", type, (unsigned)value); #endif if ((attributes & DNS_RDATASTATSTYPE_ATTR_STALE) == 0) ATF_REQUIRE_EQ(value, 1); else ATF_REQUIRE_EQ(value, 0); } static void checkit2(dns_rdatastatstype_t which, isc_uint64_t value, void *arg) { unsigned int attributes; #if debug unsigned int type; #endif UNUSED(which); UNUSED(arg); attributes = DNS_RDATASTATSTYPE_ATTR(which); #if debug type = DNS_RDATASTATSTYPE_BASE(which); fprintf(stderr, "%s%s%s%s/%u, %u\n", attributes & DNS_RDATASTATSTYPE_ATTR_OTHERTYPE ? "O" : " ", attributes & DNS_RDATASTATSTYPE_ATTR_NXRRSET ? "!" : " ", attributes & DNS_RDATASTATSTYPE_ATTR_STALE ? "#" : " ", attributes & DNS_RDATASTATSTYPE_ATTR_NXDOMAIN ? "X" : " ", type, (unsigned)value); #endif if ((attributes & DNS_RDATASTATSTYPE_ATTR_STALE) == 0) ATF_REQUIRE_EQ(value, 0); else ATF_REQUIRE_EQ(value, 1); } /* * Individual unit tests */ ATF_TC(rdatasetstats); ATF_TC_HEAD(rdatasetstats, tc) { atf_tc_set_md_var(tc, "descr", "test that rdatasetstats counters are properly set"); } ATF_TC_BODY(rdatasetstats, tc) { unsigned int i; dns_stats_t *stats = NULL; isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_rdatasetstats_create(mctx, &stats); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* First 256 types. */ for (i = 0; i <= 255; i++) set_typestats(stats, (dns_rdatatype_t)i, ISC_FALSE); /* Specials */ set_typestats(stats, dns_rdatatype_dlv, ISC_FALSE); set_typestats(stats, (dns_rdatatype_t)1000, ISC_FALSE); set_nxdomainstats(stats, ISC_FALSE); /* * Check that all counters are set to appropriately. */ dns_rdatasetstats_dump(stats, checkit1, NULL, 1); /* First 256 types. */ for (i = 0; i <= 255; i++) set_typestats(stats, (dns_rdatatype_t)i, ISC_TRUE); /* Specials */ set_typestats(stats, dns_rdatatype_dlv, ISC_TRUE); set_typestats(stats, (dns_rdatatype_t)1000, ISC_TRUE); set_nxdomainstats(stats, ISC_TRUE); /* * Check that all counters are set to appropriately. */ dns_rdatasetstats_dump(stats, checkit2, NULL, 1); dns_stats_detach(&stats); dns_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, rdatasetstats); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/dns/tests/mkraw.pl0000644000470500017500000000216412664710322017546 0ustar lamontlamont#!/usr/bin/perl -w # # Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id$ # Convert a hexdump to binary format. # # To convert binary data to the input format for this command, # use the following: # # perl -e 'while (read(STDIN, my $byte, 1)) { # print unpack("H2", $byte); # } # print "\n";' < file > file.in use strict; chomp(my $line = ); print pack("H*", $line); bind9-9.10.3.dfsg.P4/lib/dns/tests/time_test.c0000644000470500017500000001367112664710322020236 0ustar lamontlamont/* * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include "dnstest.h" #define TEST_ORIGIN "test" /* * Individual unit tests */ /* value = 0xfffffffff <-> 19691231235959 */ ATF_TC(epoch_minus_one); ATF_TC_HEAD(epoch_minus_one, tc) { atf_tc_set_md_var(tc, "descr", "0xffffffff <-> 19691231235959"); } ATF_TC_BODY(epoch_minus_one, tc) { const char *test_text = "19691231235959"; const isc_uint32_t test_time = 0xffffffff; isc_result_t result; isc_buffer_t target; isc_uint32_t when; char buf[128]; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); memset(buf, 0, sizeof(buf)); isc_buffer_init(&target, buf, sizeof(buf)); result = dns_time32_totext(test_time, &target); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_STREQ(buf, test_text); result = dns_time32_fromtext(test_text, &when); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(when, test_time); dns_test_end(); } /* value = 0x000000000 <-> 19700101000000*/ ATF_TC(epoch); ATF_TC_HEAD(epoch, tc) { atf_tc_set_md_var(tc, "descr", "0x00000000 <-> 19700101000000"); } ATF_TC_BODY(epoch, tc) { const char *test_text = "19700101000000"; const isc_uint32_t test_time = 0x00000000; isc_result_t result; isc_buffer_t target; isc_uint32_t when; char buf[128]; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); memset(buf, 0, sizeof(buf)); isc_buffer_init(&target, buf, sizeof(buf)); result = dns_time32_totext(test_time, &target); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_STREQ(buf, test_text); result = dns_time32_fromtext(test_text, &when); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(when, test_time); dns_test_end(); } /* value = 0x7fffffff <-> 20380119031407 */ ATF_TC(half_maxint); ATF_TC_HEAD(half_maxint, tc) { atf_tc_set_md_var(tc, "descr", "0x7fffffff <-> 20380119031407"); } ATF_TC_BODY(half_maxint, tc) { const char *test_text = "20380119031407"; const isc_uint32_t test_time = 0x7fffffff; isc_result_t result; isc_buffer_t target; isc_uint32_t when; char buf[128]; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); memset(buf, 0, sizeof(buf)); isc_buffer_init(&target, buf, sizeof(buf)); result = dns_time32_totext(test_time, &target); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_STREQ(buf, test_text); result = dns_time32_fromtext(test_text, &when); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(when, test_time); dns_test_end(); } /* value = 0x80000000 <-> 20380119031408 */ ATF_TC(half_plus_one); ATF_TC_HEAD(half_plus_one, tc) { atf_tc_set_md_var(tc, "descr", "0x80000000 <-> 20380119031408"); } ATF_TC_BODY(half_plus_one, tc) { const char *test_text = "20380119031408"; const isc_uint32_t test_time = 0x80000000; isc_result_t result; isc_buffer_t target; isc_uint32_t when; char buf[128]; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); memset(buf, 0, sizeof(buf)); isc_buffer_init(&target, buf, sizeof(buf)); result = dns_time32_totext(test_time, &target); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_STREQ(buf, test_text); result = dns_time32_fromtext(test_text, &when); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(when, test_time); dns_test_end(); } /* value = 0xef68f5d0 <-> 19610307130000 */ ATF_TC(fifty_before); ATF_TC_HEAD(fifty_before, tc) { atf_tc_set_md_var(tc, "descr", "0xef68f5d0 <-> 19610307130000"); } ATF_TC_BODY(fifty_before, tc) { isc_result_t result; const char *test_text = "19610307130000"; const isc_uint32_t test_time = 0xef68f5d0; isc_buffer_t target; isc_uint32_t when; char buf[128]; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); memset(buf, 0, sizeof(buf)); isc_buffer_init(&target, buf, sizeof(buf)); result = dns_time32_totext(test_time, &target); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_STREQ(buf, test_text); result = dns_time32_fromtext(test_text, &when); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(when, test_time); dns_test_end(); } /* value = 0x4d74d6d0 <-> 20110307130000 */ ATF_TC(some_ago); ATF_TC_HEAD(some_ago, tc) { atf_tc_set_md_var(tc, "descr", "0x4d74d6d0 <-> 20110307130000"); } ATF_TC_BODY(some_ago, tc) { const char *test_text = "20110307130000"; const isc_uint32_t test_time = 0x4d74d6d0; isc_result_t result; isc_buffer_t target; isc_uint32_t when; char buf[128]; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); memset(buf, 0, sizeof(buf)); isc_buffer_init(&target, buf, sizeof(buf)); result = dns_time32_totext(test_time, &target); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_STREQ(buf, test_text); result = dns_time32_fromtext(test_text, &when); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(when, test_time); dns_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, epoch_minus_one); ATF_TP_ADD_TC(tp, epoch); ATF_TP_ADD_TC(tp, half_maxint); ATF_TP_ADD_TC(tp, half_plus_one); ATF_TP_ADD_TC(tp, fifty_before); ATF_TP_ADD_TC(tp, some_ago); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/dns/tests/Atffile0000644000470500017500000000014012664710322017355 0ustar lamontlamontContent-Type: application/X-atf-atffile; version="1" prop: test-suite = bind9 tp-glob: *_test bind9-9.10.3.dfsg.P4/lib/dns/tests/master_test.c0000644000470500017500000004174412664710322020575 0ustar lamontlamont/* * Copyright (C) 2011-2013, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dnstest.h" /* * Helper functions */ #define BUFLEN 255 #define BIGBUFLEN (70 * 1024) #define TEST_ORIGIN "test" static dns_masterrawheader_t header; static isc_boolean_t headerset; dns_name_t dns_origin; char origin[sizeof(TEST_ORIGIN)]; unsigned char name_buf[BUFLEN]; dns_rdatacallbacks_t callbacks; char *include_file = NULL; static isc_result_t add_callback(void *arg, dns_name_t *owner, dns_rdataset_t *dataset); static void rawdata_callback(dns_zone_t *zone, dns_masterrawheader_t *header); static isc_result_t add_callback(void *arg, dns_name_t *owner, dns_rdataset_t *dataset) { char buf[BIGBUFLEN]; isc_buffer_t target; isc_result_t result; UNUSED(arg); isc_buffer_init(&target, buf, BIGBUFLEN); result = dns_rdataset_totext(dataset, owner, ISC_FALSE, ISC_FALSE, &target); return(result); } static void rawdata_callback(dns_zone_t *zone, dns_masterrawheader_t *h) { UNUSED(zone); header = *h; headerset = ISC_TRUE; } static isc_result_t setup_master(void (*warn)(struct dns_rdatacallbacks *, const char *, ...), void (*error)(struct dns_rdatacallbacks *, const char *, ...)) { isc_result_t result; int len; isc_buffer_t source; isc_buffer_t target; strcpy(origin, TEST_ORIGIN); len = strlen(origin); isc_buffer_init(&source, origin, len); isc_buffer_add(&source, len); isc_buffer_setactive(&source, len); isc_buffer_init(&target, name_buf, BUFLEN); dns_name_init(&dns_origin, NULL); dns_master_initrawheader(&header); result = dns_name_fromtext(&dns_origin, &source, dns_rootname, 0, &target); if (result != ISC_R_SUCCESS) return(result); dns_rdatacallbacks_init_stdio(&callbacks); callbacks.add = add_callback; callbacks.rawdata = rawdata_callback; callbacks.zone = NULL; if (warn != NULL) callbacks.warn = warn; if (error != NULL) callbacks.error = error; headerset = ISC_FALSE; return (result); } static isc_result_t test_master(const char *testfile, dns_masterformat_t format, void (*warn)(struct dns_rdatacallbacks *, const char *, ...), void (*error)(struct dns_rdatacallbacks *, const char *, ...)) { isc_result_t result; result = setup_master(warn, error); if (result != ISC_R_SUCCESS) return(result); result = dns_master_loadfile2(testfile, &dns_origin, &dns_origin, dns_rdataclass_in, ISC_TRUE, &callbacks, mctx, format); return (result); } static void include_callback(const char *filename, void *arg) { char **argp = (char **) arg; *argp = isc_mem_strdup(mctx, filename); } /* * Individual unit tests */ /* Successful load test */ ATF_TC(load); ATF_TC_HEAD(load, tc) { atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() loads a " "valid master file and returns success"); } ATF_TC_BODY(load, tc) { isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = test_master("testdata/master/master1.data", dns_masterformat_text, NULL, NULL); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_test_end(); } /* Unepxected end of file test */ ATF_TC(unexpected); ATF_TC_HEAD(unexpected, tc) { atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() returns " "DNS_R_UNEXPECTED when file ends " "too soon"); } ATF_TC_BODY(unexpected, tc) { isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = test_master("testdata/master/master2.data", dns_masterformat_text, NULL, NULL); ATF_REQUIRE_EQ(result, ISC_R_UNEXPECTEDEND); dns_test_end(); } /* No owner test */ ATF_TC(noowner); ATF_TC_HEAD(noowner, tc) { atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() accepts broken " "zones with no TTL for first record " "if it is an SOA"); } ATF_TC_BODY(noowner, tc) { isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = test_master("testdata/master/master3.data", dns_masterformat_text, NULL, NULL); ATF_REQUIRE_EQ(result, DNS_R_NOOWNER); dns_test_end(); } /* No TTL test */ ATF_TC(nottl); ATF_TC_HEAD(nottl, tc) { atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() returns " "DNS_R_NOOWNER when no owner name " "is specified"); } ATF_TC_BODY(nottl, tc) { isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = test_master("testdata/master/master4.data", dns_masterformat_text, NULL, NULL); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_test_end(); } /* Bad class test */ ATF_TC(badclass); ATF_TC_HEAD(badclass, tc) { atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() returns " "DNS_R_BADCLASS when record class " "doesn't match zone class"); } ATF_TC_BODY(badclass, tc) { isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = test_master("testdata/master/master5.data", dns_masterformat_text, NULL, NULL); ATF_REQUIRE_EQ(result, DNS_R_BADCLASS); dns_test_end(); } /* Too big rdata test */ ATF_TC(toobig); ATF_TC_HEAD(toobig, tc) { atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() returns " "ISC_R_NOSPACE when record is too big"); } ATF_TC_BODY(toobig, tc) { isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = test_master("testdata/master/master15.data", dns_masterformat_text, NULL, NULL); ATF_REQUIRE_EQ(result, ISC_R_NOSPACE); dns_test_end(); } /* Maximum rdata test */ ATF_TC(maxrdata); ATF_TC_HEAD(maxrdata, tc) { atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() returns " "ISC_R_SUCCESS when record is maximum " "size"); } ATF_TC_BODY(maxrdata, tc) { isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = test_master("testdata/master/master16.data", dns_masterformat_text, NULL, NULL); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_test_end(); } /* DNSKEY test */ ATF_TC(dnskey); ATF_TC_HEAD(dnskey, tc) { atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() understands " "DNSKEY with key material"); } ATF_TC_BODY(dnskey, tc) { isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = test_master("testdata/master/master6.data", dns_masterformat_text, NULL, NULL); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_test_end(); } /* DNSKEY with no key material test */ ATF_TC(dnsnokey); ATF_TC_HEAD(dnsnokey, tc) { atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() understands " "DNSKEY with no key material"); } ATF_TC_BODY(dnsnokey, tc) { isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = test_master("testdata/master/master7.data", dns_masterformat_text, NULL, NULL); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_test_end(); } /* Include test */ ATF_TC(include); ATF_TC_HEAD(include, tc) { atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() understands " "$INCLUDE"); } ATF_TC_BODY(include, tc) { isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = test_master("testdata/master/master8.data", dns_masterformat_text, NULL, NULL); ATF_REQUIRE_EQ(result, DNS_R_SEENINCLUDE); dns_test_end(); } /* Include file list test */ ATF_TC(master_includelist); ATF_TC_HEAD(master_includelist, tc) { atf_tc_set_md_var(tc, "descr", "dns_master_loadfile4() returns " "names of included file"); } ATF_TC_BODY(master_includelist, tc) { isc_result_t result; char *filename = NULL; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = setup_master(NULL, NULL); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_master_loadfile4("testdata/master/master8.data", &dns_origin, &dns_origin, dns_rdataclass_in, 0, ISC_TRUE, &callbacks, include_callback, &filename, mctx, dns_masterformat_text); ATF_CHECK_EQ(result, DNS_R_SEENINCLUDE); ATF_CHECK(filename != NULL); if (filename != NULL) { ATF_CHECK_STREQ(filename, "testdata/master/master7.data"); isc_mem_free(mctx, filename); } dns_test_end(); } /* Include failure test */ ATF_TC(includefail); ATF_TC_HEAD(includefail, tc) { atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() understands " "$INCLUDE failures"); } ATF_TC_BODY(includefail, tc) { isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = test_master("testdata/master/master9.data", dns_masterformat_text, NULL, NULL); ATF_REQUIRE_EQ(result, DNS_R_BADCLASS); dns_test_end(); } /* Non-empty blank lines test */ ATF_TC(blanklines); ATF_TC_HEAD(blanklines, tc) { atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() handles " "non-empty blank lines"); } ATF_TC_BODY(blanklines, tc) { isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = test_master("testdata/master/master10.data", dns_masterformat_text, NULL, NULL); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_test_end(); } /* SOA leading zeroes test */ ATF_TC(leadingzero); ATF_TC_HEAD(leadingzero, tc) { atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() allows " "leading zeroes in SOA"); } ATF_TC_BODY(leadingzero, tc) { isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = test_master("testdata/master/master11.data", dns_masterformat_text, NULL, NULL); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_test_end(); } ATF_TC(totext); ATF_TC_HEAD(totext, tc) { atf_tc_set_md_var(tc, "descr", "masterfile totext tests"); } ATF_TC_BODY(totext, tc) { isc_result_t result; dns_rdataset_t rdataset; dns_rdatalist_t rdatalist; isc_buffer_t target; unsigned char buf[BIGBUFLEN]; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* First, test with an empty rdataset */ dns_rdatalist_init(&rdatalist); rdatalist.rdclass = dns_rdataclass_in; rdatalist.type = dns_rdatatype_none; rdatalist.covers = dns_rdatatype_none; dns_rdataset_init(&rdataset); result = dns_rdatalist_tordataset(&rdatalist, &rdataset); ATF_CHECK_EQ(result, ISC_R_SUCCESS); isc_buffer_init(&target, buf, BIGBUFLEN); result = dns_master_rdatasettotext(dns_rootname, &rdataset, &dns_master_style_debug, &target); ATF_CHECK_EQ(result, ISC_R_SUCCESS); ATF_CHECK_EQ(isc_buffer_usedlength(&target), 0); /* * XXX: We will also need to add tests for dumping various * rdata types, classes, etc, and comparing the results against * known-good output. */ dns_test_end(); } /* Raw load */ ATF_TC(loadraw); ATF_TC_HEAD(loadraw, tc) { atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() loads a " "valid raw file and returns success"); } ATF_TC_BODY(loadraw, tc) { isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* Raw format version 0 */ result = test_master("testdata/master/master12.data", dns_masterformat_raw, NULL, NULL); ATF_CHECK_STREQ(isc_result_totext(result), "success"); ATF_CHECK(headerset); ATF_CHECK_EQ(header.flags, 0); /* Raw format version 1, no source serial */ result = test_master("testdata/master/master13.data", dns_masterformat_raw, NULL, NULL); ATF_CHECK_STREQ(isc_result_totext(result), "success"); ATF_CHECK(headerset); ATF_CHECK_EQ(header.flags, 0); /* Raw format version 1, source serial == 2011120101 */ result = test_master("testdata/master/master14.data", dns_masterformat_raw, NULL, NULL); ATF_CHECK_STREQ(isc_result_totext(result), "success"); ATF_CHECK(headerset); ATF_CHECK((header.flags & DNS_MASTERRAW_SOURCESERIALSET) != 0); ATF_CHECK_EQ(header.sourceserial, 2011120101); dns_test_end(); } /* Raw dump*/ ATF_TC(dumpraw); ATF_TC_HEAD(dumpraw, tc) { atf_tc_set_md_var(tc, "descr", "dns_master_dump*() functions " "dump valid raw files"); } ATF_TC_BODY(dumpraw, tc) { isc_result_t result; dns_db_t *db = NULL; dns_dbversion_t *version = NULL; char myorigin[sizeof(TEST_ORIGIN)]; dns_name_t dnsorigin; isc_buffer_t source, target; unsigned char namebuf[BUFLEN]; int len; UNUSED(tc); strcpy(myorigin, TEST_ORIGIN); len = strlen(myorigin); isc_buffer_init(&source, myorigin, len); isc_buffer_add(&source, len); isc_buffer_setactive(&source, len); isc_buffer_init(&target, namebuf, BUFLEN); dns_name_init(&dnsorigin, NULL); result = dns_name_fromtext(&dnsorigin, &source, dns_rootname, 0, &target); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_create(mctx, "rbt", &dnsorigin, dns_dbtype_zone, dns_rdataclass_in, 0, NULL, &db); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_load(db, "testdata/master/master1.data"); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_db_currentversion(db, &version); result = dns_master_dump2(mctx, db, version, &dns_master_style_default, "test.dump", dns_masterformat_raw); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = test_master("test.dump", dns_masterformat_raw, NULL, NULL); ATF_CHECK_STREQ(isc_result_totext(result), "success"); ATF_CHECK(headerset); ATF_CHECK_EQ(header.flags, 0); dns_master_initrawheader(&header); header.sourceserial = 12345; header.flags |= DNS_MASTERRAW_SOURCESERIALSET; unlink("test.dump"); result = dns_master_dump3(mctx, db, version, &dns_master_style_default, "test.dump", dns_masterformat_raw, &header); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = test_master("test.dump", dns_masterformat_raw, NULL, NULL); ATF_CHECK_STREQ(isc_result_totext(result), "success"); ATF_CHECK(headerset); ATF_CHECK((header.flags & DNS_MASTERRAW_SOURCESERIALSET) != 0); ATF_CHECK_EQ(header.sourceserial, 12345); unlink("test.dump"); dns_db_closeversion(db, &version, ISC_FALSE); dns_db_detach(&db); dns_test_end(); } static const char *warn_expect_value; static isc_boolean_t warn_expect_result; static void warn_expect(struct dns_rdatacallbacks *mycallbacks, const char *fmt, ...) { char buf[4096]; va_list ap; UNUSED(mycallbacks); va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); if (warn_expect_value != NULL && strstr(buf, warn_expect_value) != NULL) warn_expect_result = ISC_TRUE; } /* Origin change test */ ATF_TC(neworigin); ATF_TC_HEAD(neworigin, tc) { atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() rejects " "zones with inherited name following " "$ORIGIN"); } ATF_TC_BODY(neworigin, tc) { isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); warn_expect_value = "record with inherited owner"; warn_expect_result = ISC_FALSE; result = test_master("testdata/master/master17.data", dns_masterformat_text, warn_expect, NULL); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_CHECK_MSG(warn_expect_result, "'%s' warning not emitted", warn_expect_value); dns_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, load); ATF_TP_ADD_TC(tp, unexpected); ATF_TP_ADD_TC(tp, noowner); ATF_TP_ADD_TC(tp, nottl); ATF_TP_ADD_TC(tp, badclass); ATF_TP_ADD_TC(tp, dnskey); ATF_TP_ADD_TC(tp, dnsnokey); ATF_TP_ADD_TC(tp, include); ATF_TP_ADD_TC(tp, master_includelist); ATF_TP_ADD_TC(tp, includefail); ATF_TP_ADD_TC(tp, blanklines); ATF_TP_ADD_TC(tp, leadingzero); ATF_TP_ADD_TC(tp, totext); ATF_TP_ADD_TC(tp, loadraw); ATF_TP_ADD_TC(tp, dumpraw); ATF_TP_ADD_TC(tp, toobig); ATF_TP_ADD_TC(tp, maxrdata); ATF_TP_ADD_TC(tp, neworigin); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/dns/tests/dispatch_test.c0000644000470500017500000000711612664710322021074 0ustar lamontlamont/* * Copyright (C) 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include "dnstest.h" dns_dispatchmgr_t *dispatchmgr = NULL; dns_dispatchset_t *dset = NULL; static isc_result_t make_dispatchset(unsigned int ndisps) { isc_result_t result; isc_sockaddr_t any; unsigned int attrs; dns_dispatch_t *disp = NULL; result = dns_dispatchmgr_create(mctx, NULL, &dispatchmgr); if (result != ISC_R_SUCCESS) return (result); isc_sockaddr_any(&any); attrs = DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_UDP; result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, &any, 512, 6, 1024, 17, 19, attrs, attrs, &disp); if (result != ISC_R_SUCCESS) return (result); result = dns_dispatchset_create(mctx, socketmgr, taskmgr, disp, &dset, ndisps); dns_dispatch_detach(&disp); return (result); } static void teardown(void) { if (dset != NULL) dns_dispatchset_destroy(&dset); if (dispatchmgr != NULL) dns_dispatchmgr_destroy(&dispatchmgr); } /* * Individual unit tests */ ATF_TC(dispatchset_create); ATF_TC_HEAD(dispatchset_create, tc) { atf_tc_set_md_var(tc, "descr", "create dispatch set"); } ATF_TC_BODY(dispatchset_create, tc) { isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = make_dispatchset(1); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); teardown(); result = make_dispatchset(10); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); teardown(); dns_test_end(); } ATF_TC(dispatchset_get); ATF_TC_HEAD(dispatchset_get, tc) { atf_tc_set_md_var(tc, "descr", "test dispatch set round-robin"); } ATF_TC_BODY(dispatchset_get, tc) { isc_result_t result; dns_dispatch_t *d1, *d2, *d3, *d4, *d5; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = make_dispatchset(1); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); d1 = dns_dispatchset_get(dset); d2 = dns_dispatchset_get(dset); d3 = dns_dispatchset_get(dset); d4 = dns_dispatchset_get(dset); d5 = dns_dispatchset_get(dset); ATF_CHECK_EQ(d1, d2); ATF_CHECK_EQ(d2, d3); ATF_CHECK_EQ(d3, d4); ATF_CHECK_EQ(d4, d5); teardown(); result = make_dispatchset(4); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); d1 = dns_dispatchset_get(dset); d2 = dns_dispatchset_get(dset); d3 = dns_dispatchset_get(dset); d4 = dns_dispatchset_get(dset); d5 = dns_dispatchset_get(dset); ATF_CHECK_EQ(d1, d5); ATF_CHECK(d1 != d2); ATF_CHECK(d2 != d3); ATF_CHECK(d3 != d4); ATF_CHECK(d4 != d5); teardown(); dns_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, dispatchset_create); ATF_TP_ADD_TC(tp, dispatchset_get); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/dns/tests/zonemgr_test.c0000644000470500017500000001610312664710322020752 0ustar lamontlamont/* * Copyright (C) 2011-2013, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include "dnstest.h" /* * Individual unit tests */ ATF_TC(zonemgr_create); ATF_TC_HEAD(zonemgr_create, tc) { atf_tc_set_md_var(tc, "descr", "create zone manager"); } ATF_TC_BODY(zonemgr_create, tc) { dns_zonemgr_t *myzonemgr = NULL; isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_zonemgr_create(mctx, taskmgr, timermgr, socketmgr, &myzonemgr); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_zonemgr_shutdown(myzonemgr); dns_zonemgr_detach(&myzonemgr); ATF_REQUIRE_EQ(myzonemgr, NULL); dns_test_end(); } ATF_TC(zonemgr_managezone); ATF_TC_HEAD(zonemgr_managezone, tc) { atf_tc_set_md_var(tc, "descr", "manage and release a zone"); } ATF_TC_BODY(zonemgr_managezone, tc) { dns_zonemgr_t *myzonemgr = NULL; dns_zone_t *zone = NULL; isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_zonemgr_create(mctx, taskmgr, timermgr, socketmgr, &myzonemgr); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_makezone("foo", &zone, NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* This should not succeed until the dns_zonemgr_setsize() is run */ result = dns_zonemgr_managezone(myzonemgr, zone); ATF_REQUIRE_EQ(result, ISC_R_FAILURE); ATF_REQUIRE_EQ(dns_zonemgr_getcount(myzonemgr, DNS_ZONESTATE_ANY), 0); result = dns_zonemgr_setsize(myzonemgr, 1); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* Now it should succeed */ result = dns_zonemgr_managezone(myzonemgr, zone); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(dns_zonemgr_getcount(myzonemgr, DNS_ZONESTATE_ANY), 1); dns_zonemgr_releasezone(myzonemgr, zone); dns_zone_detach(&zone); ATF_REQUIRE_EQ(dns_zonemgr_getcount(myzonemgr, DNS_ZONESTATE_ANY), 0); dns_zonemgr_shutdown(myzonemgr); dns_zonemgr_detach(&myzonemgr); ATF_REQUIRE_EQ(myzonemgr, NULL); dns_test_end(); } ATF_TC(zonemgr_createzone); ATF_TC_HEAD(zonemgr_createzone, tc) { atf_tc_set_md_var(tc, "descr", "create and release a zone"); } ATF_TC_BODY(zonemgr_createzone, tc) { dns_zonemgr_t *myzonemgr = NULL; dns_zone_t *zone = NULL; isc_result_t result; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_zonemgr_create(mctx, taskmgr, timermgr, socketmgr, &myzonemgr); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* This should not succeed until the dns_zonemgr_setsize() is run */ result = dns_zonemgr_createzone(myzonemgr, &zone); ATF_REQUIRE_EQ(result, ISC_R_FAILURE); result = dns_zonemgr_setsize(myzonemgr, 1); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* Now it should succeed */ result = dns_zonemgr_createzone(myzonemgr, &zone); ATF_CHECK_EQ(result, ISC_R_SUCCESS); ATF_CHECK(zone != NULL); if (zone != NULL) dns_zone_detach(&zone); dns_zonemgr_shutdown(myzonemgr); dns_zonemgr_detach(&myzonemgr); ATF_REQUIRE_EQ(myzonemgr, NULL); dns_test_end(); } ATF_TC(zonemgr_unreachable); ATF_TC_HEAD(zonemgr_unreachable, tc) { atf_tc_set_md_var(tc, "descr", "manage and release a zone"); } ATF_TC_BODY(zonemgr_unreachable, tc) { dns_zonemgr_t *myzonemgr = NULL; dns_zone_t *zone = NULL; isc_sockaddr_t addr1, addr2; struct in_addr in; isc_result_t result; isc_time_t now; UNUSED(tc); TIME_NOW(&now); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_zonemgr_create(mctx, taskmgr, timermgr, socketmgr, &myzonemgr); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_makezone("foo", &zone, NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_zonemgr_setsize(myzonemgr, 1); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_zonemgr_managezone(myzonemgr, zone); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); in.s_addr = inet_addr("10.53.0.1"); isc_sockaddr_fromin(&addr1, &in, 2112); in.s_addr = inet_addr("10.53.0.2"); isc_sockaddr_fromin(&addr2, &in, 5150); ATF_CHECK(! dns_zonemgr_unreachable(myzonemgr, &addr1, &addr2, &now)); /* * We require multiple unreachableadd calls to mark a server as * unreachable. */ dns_zonemgr_unreachableadd(myzonemgr, &addr1, &addr2, &now); ATF_CHECK(! dns_zonemgr_unreachable(myzonemgr, &addr1, &addr2, &now)); dns_zonemgr_unreachableadd(myzonemgr, &addr1, &addr2, &now); ATF_CHECK(dns_zonemgr_unreachable(myzonemgr, &addr1, &addr2, &now)); in.s_addr = inet_addr("10.53.0.3"); isc_sockaddr_fromin(&addr2, &in, 5150); ATF_CHECK(! dns_zonemgr_unreachable(myzonemgr, &addr1, &addr2, &now)); /* * We require multiple unreachableadd calls to mark a server as * unreachable. */ dns_zonemgr_unreachableadd(myzonemgr, &addr1, &addr2, &now); dns_zonemgr_unreachableadd(myzonemgr, &addr1, &addr2, &now); ATF_CHECK(dns_zonemgr_unreachable(myzonemgr, &addr1, &addr2, &now)); dns_zonemgr_unreachabledel(myzonemgr, &addr1, &addr2); ATF_CHECK(! dns_zonemgr_unreachable(myzonemgr, &addr1, &addr2, &now)); in.s_addr = inet_addr("10.53.0.2"); isc_sockaddr_fromin(&addr2, &in, 5150); ATF_CHECK(dns_zonemgr_unreachable(myzonemgr, &addr1, &addr2, &now)); dns_zonemgr_unreachabledel(myzonemgr, &addr1, &addr2); ATF_CHECK(! dns_zonemgr_unreachable(myzonemgr, &addr1, &addr2, &now)); dns_zonemgr_releasezone(myzonemgr, zone); dns_zone_detach(&zone); dns_zonemgr_shutdown(myzonemgr); dns_zonemgr_detach(&myzonemgr); ATF_REQUIRE_EQ(myzonemgr, NULL); dns_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, zonemgr_create); ATF_TP_ADD_TC(tp, zonemgr_managezone); ATF_TP_ADD_TC(tp, zonemgr_createzone); ATF_TP_ADD_TC(tp, zonemgr_unreachable); return (atf_no_error()); } /* * XXX: * dns_zonemgr API calls that are not yet part of this unit test: * * - dns_zonemgr_attach * - dns_zonemgr_forcemaint * - dns_zonemgr_resumexfrs * - dns_zonemgr_shutdown * - dns_zonemgr_setsize * - dns_zonemgr_settransfersin * - dns_zonemgr_getttransfersin * - dns_zonemgr_settransfersperns * - dns_zonemgr_getttransfersperns * - dns_zonemgr_setiolimit * - dns_zonemgr_getiolimit * - dns_zonemgr_dbdestroyed * - dns_zonemgr_setserialqueryrate * - dns_zonemgr_getserialqueryrate */ bind9-9.10.3.dfsg.P4/lib/dns/tests/dnstest.h0000644000470500017500000000377312664710322017734 0ustar lamontlamont/* * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #define CHECK(r) \ do { \ result = (r); \ if (result != ISC_R_SUCCESS) \ goto cleanup; \ } while (0) extern isc_mem_t *mctx; extern isc_entropy_t *ectx; extern isc_log_t *lctx; extern isc_taskmgr_t *taskmgr; extern isc_task_t *maintask; extern isc_timermgr_t *timermgr; extern isc_socketmgr_t *socketmgr; extern dns_zonemgr_t *zonemgr; extern isc_boolean_t app_running; extern int ncpus; isc_result_t dns_test_begin(FILE *logfile, isc_boolean_t create_managers); void dns_test_end(void); isc_result_t dns_test_makezone(const char *name, dns_zone_t **zonep, dns_view_t *view, isc_boolean_t keepview); isc_result_t dns_test_setupzonemgr(void); isc_result_t dns_test_managezone(dns_zone_t *zone); void dns_test_releasezone(dns_zone_t *zone); void dns_test_closezonemgr(void); void dns_test_nap(isc_uint32_t usec); isc_result_t dns_test_loaddb(dns_db_t **db, dns_dbtype_t dbtype, const char *origin, const char *testfile); bind9-9.10.3.dfsg.P4/lib/dns/tests/dbiterator_test.c0000644000470500017500000002533412664710322021436 0ustar lamontlamont/* * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include "dnstest.h" /* * Helper functions */ #define BUFLEN 255 #define BIGBUFLEN (64 * 1024) #define TEST_ORIGIN "test" static isc_result_t make_name(const char *src, dns_name_t *name) { isc_buffer_t b; isc_buffer_constinit(&b, src, strlen(src)); isc_buffer_add(&b, strlen(src)); return (dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); } /* * Individual unit tests */ /* create: make sure we can create a dbiterator */ static void test_create(const atf_tc_t *tc) { isc_result_t result; dns_db_t *db = NULL; dns_dbiterator_t *iter = NULL; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN, atf_tc_get_md_var(tc, "X-filename")); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_createiterator(db, 0, &iter); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_dbiterator_destroy(&iter); dns_db_detach(&db); dns_test_end(); } ATF_TC(create); ATF_TC_HEAD(create, tc) { atf_tc_set_md_var(tc, "descr", "create a database iterator"); atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone1.data"); } ATF_TC_BODY(create, tc) { test_create(tc); } ATF_TC(create_nsec3); ATF_TC_HEAD(create_nsec3, tc) { atf_tc_set_md_var(tc, "descr", "create a database iterator (NSEC3)"); atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone2.data"); } ATF_TC_BODY(create_nsec3, tc) { test_create(tc); } /* walk: walk a database */ static void test_walk(const atf_tc_t *tc) { isc_result_t result; dns_db_t *db = NULL; dns_dbiterator_t *iter = NULL; dns_dbnode_t *node = NULL; dns_name_t *name; dns_fixedname_t f; int i = 0; UNUSED(tc); dns_fixedname_init(&f); name = dns_fixedname_name(&f); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN, atf_tc_get_md_var(tc, "X-filename")); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_createiterator(db, 0, &iter); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); for (result = dns_dbiterator_first(iter); result == ISC_R_SUCCESS; result = dns_dbiterator_next(iter)) { result = dns_dbiterator_current(iter, &node, name); if (result == DNS_R_NEWORIGIN) result = ISC_R_SUCCESS; ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_db_detachnode(db, &node); i++; } ATF_CHECK_EQ(i, atoi(atf_tc_get_md_var(tc, "X-nodes"))); dns_dbiterator_destroy(&iter); dns_db_detach(&db); dns_test_end(); } ATF_TC(walk); ATF_TC_HEAD(walk, tc) { atf_tc_set_md_var(tc, "descr", "walk database"); atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone1.data"); atf_tc_set_md_var(tc, "X-nodes", "12"); } ATF_TC_BODY(walk, tc) { test_walk(tc); } ATF_TC(walk_nsec3); ATF_TC_HEAD(walk_nsec3, tc) { atf_tc_set_md_var(tc, "descr", "walk database"); atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone2.data"); atf_tc_set_md_var(tc, "X-nodes", "33"); } ATF_TC_BODY(walk_nsec3, tc) { test_walk(tc); } /* reverse: walk database backwards */ static void test_reverse(const atf_tc_t *tc) { isc_result_t result; dns_db_t *db = NULL; dns_dbiterator_t *iter = NULL; dns_dbnode_t *node = NULL; dns_name_t *name; dns_fixedname_t f; int i = 0; UNUSED(tc); dns_fixedname_init(&f); name = dns_fixedname_name(&f); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN, atf_tc_get_md_var(tc, "X-filename")); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_createiterator(db, 0, &iter); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); for (result = dns_dbiterator_last(iter); result == ISC_R_SUCCESS; result = dns_dbiterator_prev(iter)) { result = dns_dbiterator_current(iter, &node, name); if (result == DNS_R_NEWORIGIN) result = ISC_R_SUCCESS; ATF_CHECK_EQ(result, ISC_R_SUCCESS); dns_db_detachnode(db, &node); i++; } ATF_CHECK_EQ(i, 12); dns_dbiterator_destroy(&iter); dns_db_detach(&db); dns_test_end(); } ATF_TC(reverse); ATF_TC_HEAD(reverse, tc) { atf_tc_set_md_var(tc, "descr", "walk database backwards"); atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone1.data"); } ATF_TC_BODY(reverse, tc) { test_reverse(tc); } ATF_TC(reverse_nsec3); ATF_TC_HEAD(reverse_nsec3, tc) { atf_tc_set_md_var(tc, "descr", "walk database backwards"); atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone2.data"); } ATF_TC_BODY(reverse_nsec3, tc) { test_reverse(tc); } /* seek: walk database starting at a particular node */ static void test_seek(const atf_tc_t *tc) { isc_result_t result; dns_db_t *db = NULL; dns_dbiterator_t *iter = NULL; dns_dbnode_t *node = NULL; dns_name_t *name, *seekname; dns_fixedname_t f1, f2; int i = 0; UNUSED(tc); dns_fixedname_init(&f1); name = dns_fixedname_name(&f1); dns_fixedname_init(&f2); seekname = dns_fixedname_name(&f2); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN, atf_tc_get_md_var(tc, "X-filename")); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_createiterator(db, 0, &iter); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = make_name("c." TEST_ORIGIN, seekname); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_dbiterator_seek(iter, seekname); ATF_CHECK_EQ(result, ISC_R_SUCCESS); while (result == ISC_R_SUCCESS) { result = dns_dbiterator_current(iter, &node, name); if (result == DNS_R_NEWORIGIN) result = ISC_R_SUCCESS; ATF_CHECK_EQ(result, ISC_R_SUCCESS); dns_db_detachnode(db, &node); result = dns_dbiterator_next(iter); i++; } ATF_CHECK_EQ(i, atoi(atf_tc_get_md_var(tc, "X-nodes"))); dns_dbiterator_destroy(&iter); dns_db_detach(&db); dns_test_end(); } ATF_TC(seek); ATF_TC_HEAD(seek, tc) { atf_tc_set_md_var(tc, "descr", "walk database starting at " "a particular node"); atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone1.data"); atf_tc_set_md_var(tc, "X-nodes", "9"); } ATF_TC_BODY(seek, tc) { test_seek(tc); } ATF_TC(seek_nsec3); ATF_TC_HEAD(seek_nsec3, tc) { atf_tc_set_md_var(tc, "descr", "walk database starting at " "a particular node"); atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone2.data"); atf_tc_set_md_var(tc, "X-nodes", "30"); } ATF_TC_BODY(seek_nsec3, tc) { test_seek(tc); } /* * seek_emty: walk database starting at an empty nonterminal node * (should fail) */ static void test_seek_empty(const atf_tc_t *tc) { isc_result_t result; dns_db_t *db = NULL; dns_dbiterator_t *iter = NULL; dns_name_t *seekname; dns_fixedname_t f1; UNUSED(tc); dns_fixedname_init(&f1); seekname = dns_fixedname_name(&f1); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN, atf_tc_get_md_var(tc, "X-filename")); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_createiterator(db, 0, &iter); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = make_name("d." TEST_ORIGIN, seekname); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_dbiterator_seek(iter, seekname); ATF_CHECK_EQ(result, ISC_R_NOTFOUND); dns_dbiterator_destroy(&iter); dns_db_detach(&db); dns_test_end(); } ATF_TC(seek_empty); ATF_TC_HEAD(seek_empty, tc) { atf_tc_set_md_var(tc, "descr", "walk database starting at an " "empty nonterminal node"); atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone1.data"); } ATF_TC_BODY(seek_empty, tc) { test_seek_empty(tc); } ATF_TC(seek_empty_nsec3); ATF_TC_HEAD(seek_empty_nsec3, tc) { atf_tc_set_md_var(tc, "descr", "walk database starting at an " "empty nonterminal node"); atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone2.data"); } ATF_TC_BODY(seek_empty_nsec3, tc) { test_seek_empty(tc); } /* * seek_emty: walk database starting at an empty nonterminal node * (should fail) */ static void test_seek_nx(const atf_tc_t *tc) { isc_result_t result; dns_db_t *db = NULL; dns_dbiterator_t *iter = NULL; dns_name_t *seekname; dns_fixedname_t f1; UNUSED(tc); dns_fixedname_init(&f1); seekname = dns_fixedname_name(&f1); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN, atf_tc_get_md_var(tc, "X-filename")); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_createiterator(db, 0, &iter); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = make_name("nonexistent." TEST_ORIGIN, seekname); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_dbiterator_seek(iter, seekname); ATF_CHECK_EQ(result, ISC_R_NOTFOUND); dns_dbiterator_destroy(&iter); dns_db_detach(&db); dns_test_end(); } ATF_TC(seek_nx); ATF_TC_HEAD(seek_nx, tc) { atf_tc_set_md_var(tc, "descr", "attempt to walk database starting " "at a nonexistent node"); atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone1.data"); } ATF_TC_BODY(seek_nx, tc) { test_seek_nx(tc); } ATF_TC(seek_nx_nsec3); ATF_TC_HEAD(seek_nx_nsec3, tc) { atf_tc_set_md_var(tc, "descr", "attempt to walk database starting " "at a nonexistent node"); atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone2.data"); } ATF_TC_BODY(seek_nx_nsec3, tc) { test_seek_nx(tc); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, create); ATF_TP_ADD_TC(tp, create_nsec3); ATF_TP_ADD_TC(tp, walk); ATF_TP_ADD_TC(tp, walk_nsec3); ATF_TP_ADD_TC(tp, reverse); ATF_TP_ADD_TC(tp, reverse_nsec3); ATF_TP_ADD_TC(tp, seek); ATF_TP_ADD_TC(tp, seek_nsec3); ATF_TP_ADD_TC(tp, seek_empty); ATF_TP_ADD_TC(tp, seek_empty_nsec3); ATF_TP_ADD_TC(tp, seek_nx); ATF_TP_ADD_TC(tp, seek_nx_nsec3); return (atf_no_error()); } /* * XXX: * dns_dbiterator API calls that are not yet part of this unit test: * * dns_dbiterator_pause * dns_dbiterator_origin * dns_dbiterator_setcleanmode */ bind9-9.10.3.dfsg.P4/lib/dns/tests/zt_test.c0000644000470500017500000001561312664710322017733 0ustar lamontlamont/* * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include "dnstest.h" struct args { void *arg1; void *arg2; }; /* * Helper functions */ static isc_result_t count_zone(dns_zone_t *zone, void *uap) { int *nzones = (int *)uap; UNUSED(zone); *nzones += 1; return (ISC_R_SUCCESS); } static isc_result_t load_done(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task) { /* We treat zt as a pointer to a boolean for testing purposes */ isc_boolean_t *done = (isc_boolean_t *) zt; UNUSED(zone); UNUSED(task); *done = ISC_TRUE; isc_app_shutdown(); return (ISC_R_SUCCESS); } static isc_result_t all_done(void *arg) { isc_boolean_t *done = (isc_boolean_t *) arg; *done = ISC_TRUE; isc_app_shutdown(); return (ISC_R_SUCCESS); } static void start_zt_asyncload(isc_task_t *task, isc_event_t *event) { struct args *args = (struct args *)(event->ev_arg); UNUSED(task); dns_zt_asyncload(args->arg1, all_done, args->arg2); isc_event_free(&event); } static void start_zone_asyncload(isc_task_t *task, isc_event_t *event) { struct args *args = (struct args *)(event->ev_arg); UNUSED(task); dns_zone_asyncload(args->arg1, load_done, args->arg2); isc_event_free(&event); } /* * Individual unit tests */ ATF_TC(apply); ATF_TC_HEAD(apply, tc) { atf_tc_set_md_var(tc, "descr", "apply a function to a zone table"); } ATF_TC_BODY(apply, tc) { isc_result_t result; dns_zone_t *zone = NULL; dns_view_t *view = NULL; int nzones = 0; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_makezone("foo", &zone, NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); view = dns_zone_getview(zone); ATF_REQUIRE(view->zonetable != NULL); ATF_CHECK_EQ(0, nzones); result = dns_zt_apply(view->zonetable, ISC_FALSE, count_zone, &nzones); ATF_CHECK_EQ(result, ISC_R_SUCCESS); ATF_CHECK_EQ(1, nzones); /* These steps are necessary so the zone can be detached properly */ result = dns_test_setupzonemgr(); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_managezone(zone); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_test_releasezone(zone); dns_test_closezonemgr(); /* The view was left attached in dns_test_makezone() */ dns_view_detach(&view); dns_zone_detach(&zone); dns_test_end(); } ATF_TC(asyncload_zone); ATF_TC_HEAD(asyncload_zone, tc) { atf_tc_set_md_var(tc, "descr", "asynchronous zone load"); } ATF_TC_BODY(asyncload_zone, tc) { isc_result_t result; dns_zone_t *zone = NULL; dns_view_t *view = NULL; dns_db_t *db = NULL; isc_boolean_t done = ISC_FALSE; int i = 0; struct args args; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_makezone("foo", &zone, NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_setupzonemgr(); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_managezone(zone); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); view = dns_zone_getview(zone); ATF_REQUIRE(view->zonetable != NULL); ATF_CHECK(!dns__zone_loadpending(zone)); ATF_CHECK(!done); dns_zone_setfile(zone, "testdata/zt/zone1.db"); args.arg1 = zone; args.arg2 = &done; isc_app_onrun(mctx, maintask, start_zone_asyncload, &args); isc_app_run(); while (dns__zone_loadpending(zone) && i++ < 5000) dns_test_nap(1000); ATF_CHECK(done); /* The zone should now be loaded; test it */ result = dns_zone_getdb(zone, &db); ATF_CHECK_EQ(result, ISC_R_SUCCESS); ATF_CHECK(db != NULL); if (db != NULL) dns_db_detach(&db); dns_test_releasezone(zone); dns_test_closezonemgr(); dns_zone_detach(&zone); dns_view_detach(&view); dns_test_end(); } ATF_TC(asyncload_zt); ATF_TC_HEAD(asyncload_zt, tc) { atf_tc_set_md_var(tc, "descr", "asynchronous zone table load"); } ATF_TC_BODY(asyncload_zt, tc) { isc_result_t result; dns_zone_t *zone1 = NULL, *zone2 = NULL, *zone3 = NULL; dns_view_t *view; dns_zt_t *zt; dns_db_t *db = NULL; isc_boolean_t done = ISC_FALSE; int i = 0; struct args args; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_makezone("foo", &zone1, NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_zone_setfile(zone1, "testdata/zt/zone1.db"); view = dns_zone_getview(zone1); result = dns_test_makezone("bar", &zone2, view, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_zone_setfile(zone2, "testdata/zt/zone1.db"); /* This one will fail to load */ result = dns_test_makezone("fake", &zone3, view, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_zone_setfile(zone3, "testdata/zt/nonexistent.db"); zt = view->zonetable; ATF_REQUIRE(zt != NULL); result = dns_test_setupzonemgr(); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_managezone(zone1); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_managezone(zone2); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_managezone(zone3); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_CHECK(!dns__zone_loadpending(zone1)); ATF_CHECK(!dns__zone_loadpending(zone2)); ATF_CHECK(!done); args.arg1 = zt; args.arg2 = &done; isc_app_onrun(mctx, maintask, start_zt_asyncload, &args); isc_app_run(); while (!done && i++ < 5000) dns_test_nap(1000); ATF_CHECK(done); /* Both zones should now be loaded; test them */ result = dns_zone_getdb(zone1, &db); ATF_CHECK_EQ(result, ISC_R_SUCCESS); ATF_CHECK(db != NULL); if (db != NULL) dns_db_detach(&db); result = dns_zone_getdb(zone2, &db); ATF_CHECK_EQ(result, ISC_R_SUCCESS); ATF_CHECK(db != NULL); if (db != NULL) dns_db_detach(&db); dns_test_releasezone(zone3); dns_test_releasezone(zone2); dns_test_releasezone(zone1); dns_test_closezonemgr(); dns_zone_detach(&zone1); dns_zone_detach(&zone2); dns_zone_detach(&zone3); dns_view_detach(&view); dns_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, apply); ATF_TP_ADD_TC(tp, asyncload_zone); ATF_TP_ADD_TC(tp, asyncload_zt); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/dns/tests/Kdh.+002+18602.key0000644000470500017500000000024012664710322020330 0ustar lamontlamontdh. IN KEY 0 2 2 AAEBAAAAYIHI/wjtOagNga9GILSoS02IVelgLilPE/TfhtvShsiDAXqb IfxQcj2JkuOnNLs5ttb2WZXWl5/jsSjIxHMwMF2XY4gwt/lwHBf/vgYH r7aIxnKXov1jk9rymTLHGKIOtg== bind9-9.10.3.dfsg.P4/lib/dns/tests/nsec3_test.c0000644000470500017500000000462112664710322020306 0ustar lamontlamont/* * Copyright (C) 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include "dnstest.h" #if defined(OPENSSL) || defined(PKCS11CRYPTO) /* * Helper functions */ static void iteration_test(const char* file, unsigned int expected) { isc_result_t result; dns_db_t *db = NULL; unsigned int iterations; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_loaddb(&db, dns_dbtype_zone, "test", file); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_nsec3_maxiterations(db, NULL, mctx, &iterations); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(iterations, expected); dns_db_detach(&db); dns_test_end(); } /* * Individual unit tests */ ATF_TC(max_iterations); ATF_TC_HEAD(max_iterations, tc) { atf_tc_set_md_var(tc, "descr", "check that appropriate max iterations " " is returned for different key size mixes"); } ATF_TC_BODY(max_iterations, tc) { UNUSED(tc); iteration_test("testdata/nsec3/1024.db", 150); iteration_test("testdata/nsec3/2048.db", 500); iteration_test("testdata/nsec3/4096.db", 2500); iteration_test("testdata/nsec3/min-1024.db", 150); iteration_test("testdata/nsec3/min-2048.db", 500); } #else ATF_TC(untested); ATF_TC_HEAD(untested, tc) { atf_tc_set_md_var(tc, "descr", "skipping nsec3 test"); } ATF_TC_BODY(untested, tc) { UNUSED(tc); atf_tc_skip("DNSSEC not available"); } #endif /* * Main */ ATF_TP_ADD_TCS(tp) { #if defined(OPENSSL) || defined(PKCS11CRYPTO) ATF_TP_ADD_TC(tp, max_iterations); #else ATF_TP_ADD_TC(tp, untested); #endif return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/dns/tests/rbt_test.c0000644000470500017500000007753112664710322020074 0ustar lamontlamont/* * Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rbt_test.c,v 1.1.14.8 2012/02/10 16:24:37 ckb Exp $ */ /* ! \file */ #include #include #include #include #include #include #include #ifdef HAVE_INTTYPES_H #include /* uintptr_t */ #endif #include #include #include #include #include "dnstest.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include typedef struct { dns_rbt_t *rbt; dns_rbt_t *rbt_distances; } test_context_t; /* The initial structure of domain tree will be as follows: * * . * | * b * / \ * a d.e.f * / | \ * c | g.h * | | * w.y i * / | \ \ * x | z k * | | * p j * / \ * o q */ /* The full absolute names of the nodes in the tree (the tree also * contains "." which is not included in this list). */ static const char * const domain_names[] = { "c", "b", "a", "x.d.e.f", "z.d.e.f", "g.h", "i.g.h", "o.w.y.d.e.f", "j.z.d.e.f", "p.w.y.d.e.f", "q.w.y.d.e.f", "k.g.h" }; static const size_t domain_names_count = (sizeof(domain_names) / sizeof(domain_names[0])); /* These are set as the node data for the tree used in distances check * (for the names in domain_names[] above). */ static const int node_distances[] = { 3, 1, 2, 2, 2, 3, 1, 2, 1, 1, 2, 2 }; /* * The domain order should be: * ., a, b, c, d.e.f, x.d.e.f, w.y.d.e.f, o.w.y.d.e.f, p.w.y.d.e.f, * q.w.y.d.e.f, z.d.e.f, j.z.d.e.f, g.h, i.g.h, k.g.h * . (no data, can't be found) * | * b * / \ * a d.e.f * / | \ * c | g.h * | | * w.y i * / | \ \ * x | z k * | | * p j * / \ * o q */ static const char * const ordered_names[] = { "a", "b", "c", "d.e.f", "x.d.e.f", "w.y.d.e.f", "o.w.y.d.e.f", "p.w.y.d.e.f", "q.w.y.d.e.f", "z.d.e.f", "j.z.d.e.f", "g.h", "i.g.h", "k.g.h"}; static const size_t ordered_names_count = (sizeof(ordered_names) / sizeof(*ordered_names)); static void delete_data(void *data, void *arg) { UNUSED(arg); isc_mem_put(mctx, data, sizeof(size_t)); } static void build_name_from_str(const char *namestr, dns_fixedname_t *fname) { size_t length; isc_buffer_t *b = NULL; isc_result_t result; dns_name_t *name; length = strlen(namestr); result = isc_buffer_allocate(mctx, &b, length); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); isc_buffer_putmem(b, (const unsigned char *) namestr, length); dns_fixedname_init(fname); name = dns_fixedname_name(fname); ATF_REQUIRE(name != NULL); result = dns_name_fromtext(name, b, dns_rootname, 0, NULL); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); isc_buffer_free(&b); } static test_context_t * test_context_setup(void) { test_context_t *ctx; isc_result_t result; size_t i; ctx = isc_mem_get(mctx, sizeof(*ctx)); ATF_REQUIRE(ctx != NULL); ctx->rbt = NULL; result = dns_rbt_create(mctx, delete_data, NULL, &ctx->rbt); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ctx->rbt_distances = NULL; result = dns_rbt_create(mctx, delete_data, NULL, &ctx->rbt_distances); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); for (i = 0; i < domain_names_count; i++) { size_t *n; dns_fixedname_t fname; dns_name_t *name; build_name_from_str(domain_names[i], &fname); name = dns_fixedname_name(&fname); n = isc_mem_get(mctx, sizeof(size_t)); *n = i + 1; result = dns_rbt_addname(ctx->rbt, name, n); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); n = isc_mem_get(mctx, sizeof(size_t)); *n = node_distances[i]; result = dns_rbt_addname(ctx->rbt_distances, name, n); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); } return (ctx); } static void test_context_teardown(test_context_t *ctx) { dns_rbt_destroy(&ctx->rbt); dns_rbt_destroy(&ctx->rbt_distances); isc_mem_put(mctx, ctx, sizeof(*ctx)); } /* * Walk the tree and ensure that all the test nodes are present. */ static void check_test_data(dns_rbt_t *rbt) { dns_fixedname_t fixed; isc_result_t result; dns_name_t *foundname; size_t i; dns_fixedname_init(&fixed); foundname = dns_fixedname_name(&fixed); for (i = 0; i < domain_names_count; i++) { dns_fixedname_t fname; dns_name_t *name; size_t *n; build_name_from_str(domain_names[i], &fname); name = dns_fixedname_name(&fname); n = NULL; result = dns_rbt_findname(rbt, name, 0, foundname, (void *) &n); ATF_CHECK_EQ(result, ISC_R_SUCCESS); ATF_CHECK_EQ(*n, i + 1); } } ATF_TC(rbt_create); ATF_TC_HEAD(rbt_create, tc) { atf_tc_set_md_var(tc, "descr", "Test the creation of an rbt"); } ATF_TC_BODY(rbt_create, tc) { isc_result_t result; test_context_t *ctx; isc_boolean_t tree_ok; UNUSED(tc); isc_mem_debugging = ISC_MEM_DEBUGRECORD; result = dns_test_begin(NULL, ISC_TRUE); ATF_CHECK_EQ(result, ISC_R_SUCCESS); ctx = test_context_setup(); check_test_data(ctx->rbt); tree_ok = dns__rbt_checkproperties(ctx->rbt); ATF_CHECK_EQ(tree_ok, ISC_TRUE); test_context_teardown(ctx); dns_test_end(); } ATF_TC(rbt_nodecount); ATF_TC_HEAD(rbt_nodecount, tc) { atf_tc_set_md_var(tc, "descr", "Test dns_rbt_nodecount() on a tree"); } ATF_TC_BODY(rbt_nodecount, tc) { isc_result_t result; test_context_t *ctx; UNUSED(tc); isc_mem_debugging = ISC_MEM_DEBUGRECORD; result = dns_test_begin(NULL, ISC_TRUE); ATF_CHECK_EQ(result, ISC_R_SUCCESS); ctx = test_context_setup(); ATF_CHECK_EQ(15, dns_rbt_nodecount(ctx->rbt)); test_context_teardown(ctx); dns_test_end(); } ATF_TC(rbtnode_get_distance); ATF_TC_HEAD(rbtnode_get_distance, tc) { atf_tc_set_md_var(tc, "descr", "Test dns_rbtnode_get_distance() on a tree"); } ATF_TC_BODY(rbtnode_get_distance, tc) { isc_result_t result; test_context_t *ctx; const char *name_str = "a"; dns_fixedname_t fname; dns_name_t *name; dns_rbtnode_t *node = NULL; dns_rbtnodechain_t chain; UNUSED(tc); isc_mem_debugging = ISC_MEM_DEBUGRECORD; result = dns_test_begin(NULL, ISC_TRUE); ATF_CHECK_EQ(result, ISC_R_SUCCESS); ctx = test_context_setup(); build_name_from_str(name_str, &fname); name = dns_fixedname_name(&fname); dns_rbtnodechain_init(&chain, mctx); result = dns_rbt_findnode(ctx->rbt_distances, name, NULL, &node, &chain, 0, NULL, NULL); ATF_CHECK_EQ(result, ISC_R_SUCCESS); while (node != NULL) { const size_t *distance = (const size_t *) node->data; if (distance != NULL) ATF_CHECK_EQ(*distance, dns__rbtnode_getdistance(node)); result = dns_rbtnodechain_next(&chain, NULL, NULL); if (result == ISC_R_NOMORE) break; dns_rbtnodechain_current(&chain, NULL, NULL, &node); } ATF_CHECK_EQ(result, ISC_R_NOMORE); dns_rbtnodechain_invalidate(&chain); test_context_teardown(ctx); dns_test_end(); } ATF_TC(rbt_check_distance_random); ATF_TC_HEAD(rbt_check_distance_random, tc) { atf_tc_set_md_var(tc, "descr", "Test tree balance, inserting names in random order"); } ATF_TC_BODY(rbt_check_distance_random, tc) { /* This test checks an important performance-related property of * the red-black tree, which is important for us: the longest * path from a sub-tree's root to a node is no more than * 2log(n). This check verifies that the tree is balanced. */ dns_rbt_t *mytree = NULL; const unsigned int log_num_nodes = 16; int i; isc_result_t result; isc_boolean_t tree_ok; UNUSED(tc); isc_mem_debugging = ISC_MEM_DEBUGRECORD; result = dns_test_begin(NULL, ISC_TRUE); ATF_CHECK_EQ(result, ISC_R_SUCCESS); result = dns_rbt_create(mctx, delete_data, NULL, &mytree); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* Names are inserted in random order. */ /* Make a large 65536 node top-level domain tree, i.e., the * following code inserts names such as: * * savoucnsrkrqzpkqypbygwoiliawpbmz. * wkadamcbbpjtundbxcmuayuycposvngx. * wzbpznemtooxdpjecdxynsfztvnuyfao. * yueojmhyffslpvfmgyfwioxegfhepnqq. */ for (i = 0; i < (1 << log_num_nodes); i++) { size_t *n; char namebuf[34]; n = isc_mem_get(mctx, sizeof(size_t)); *n = i + 1; while (1) { int j; dns_fixedname_t fname; dns_name_t *name; for (j = 0; j < 32; j++) { isc_uint32_t v; isc_random_get(&v); namebuf[j] = 'a' + (v % 26); } namebuf[32] = '.'; namebuf[33] = 0; build_name_from_str(namebuf, &fname); name = dns_fixedname_name(&fname); result = dns_rbt_addname(mytree, name, n); if (result == ISC_R_SUCCESS) break; } } /* 1 (root . node) + (1 << log_num_nodes) */ ATF_CHECK_EQ(1U + (1U << log_num_nodes), dns_rbt_nodecount(mytree)); /* The distance from each node to its sub-tree root must be less * than 2 * log(n). */ ATF_CHECK((2U * log_num_nodes) >= dns__rbt_getheight(mytree)); /* Also check RB tree properties */ tree_ok = dns__rbt_checkproperties(mytree); ATF_CHECK_EQ(tree_ok, ISC_TRUE); dns_rbt_destroy(&mytree); dns_test_end(); } ATF_TC(rbt_check_distance_ordered); ATF_TC_HEAD(rbt_check_distance_ordered, tc) { atf_tc_set_md_var(tc, "descr", "Test tree balance, inserting names in sorted order"); } ATF_TC_BODY(rbt_check_distance_ordered, tc) { /* This test checks an important performance-related property of * the red-black tree, which is important for us: the longest * path from a sub-tree's root to a node is no more than * 2log(n). This check verifies that the tree is balanced. */ dns_rbt_t *mytree = NULL; const unsigned int log_num_nodes = 16; int i; isc_result_t result; isc_boolean_t tree_ok; UNUSED(tc); isc_mem_debugging = ISC_MEM_DEBUGRECORD; result = dns_test_begin(NULL, ISC_TRUE); ATF_CHECK_EQ(result, ISC_R_SUCCESS); result = dns_rbt_create(mctx, delete_data, NULL, &mytree); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* Names are inserted in sorted order. */ /* Make a large 65536 node top-level domain tree, i.e., the * following code inserts names such as: * * name00000000. * name00000001. * name00000002. * name00000003. */ for (i = 0; i < (1 << log_num_nodes); i++) { size_t *n; char namebuf[14]; dns_fixedname_t fname; dns_name_t *name; n = isc_mem_get(mctx, sizeof(size_t)); *n = i + 1; snprintf(namebuf, sizeof(namebuf), "name%08x.", i); build_name_from_str(namebuf, &fname); name = dns_fixedname_name(&fname); result = dns_rbt_addname(mytree, name, n); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); } /* 1 (root . node) + (1 << log_num_nodes) */ ATF_CHECK_EQ(1U + (1U << log_num_nodes), dns_rbt_nodecount(mytree)); /* The distance from each node to its sub-tree root must be less * than 2 * log(n). */ ATF_CHECK((2U * log_num_nodes) >= dns__rbt_getheight(mytree)); /* Also check RB tree properties */ tree_ok = dns__rbt_checkproperties(mytree); ATF_CHECK_EQ(tree_ok, ISC_TRUE); dns_rbt_destroy(&mytree); dns_test_end(); } static isc_result_t insert_helper(dns_rbt_t *rbt, const char *namestr, dns_rbtnode_t **node) { dns_fixedname_t fname; dns_name_t *name; build_name_from_str(namestr, &fname); name = dns_fixedname_name(&fname); return (dns_rbt_addnode(rbt, name, node)); } static isc_boolean_t compare_labelsequences(dns_rbtnode_t *node, const char *labelstr) { dns_name_t name; isc_result_t result; char *nodestr = NULL; isc_boolean_t is_equal; dns_name_init(&name, NULL); dns_rbt_namefromnode(node, &name); result = dns_name_tostring(&name, &nodestr, mctx); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); is_equal = strcmp(labelstr, nodestr) == 0 ? ISC_TRUE : ISC_FALSE; isc_mem_free(mctx, nodestr); return (is_equal); } ATF_TC(rbt_insert); ATF_TC_HEAD(rbt_insert, tc) { atf_tc_set_md_var(tc, "descr", "Test insertion into a tree"); } ATF_TC_BODY(rbt_insert, tc) { isc_result_t result; test_context_t *ctx; dns_rbtnode_t *node; UNUSED(tc); isc_mem_debugging = ISC_MEM_DEBUGRECORD; result = dns_test_begin(NULL, ISC_TRUE); ATF_CHECK_EQ(result, ISC_R_SUCCESS); ctx = test_context_setup(); /* Check node count before beginning. */ ATF_CHECK_EQ(15, dns_rbt_nodecount(ctx->rbt)); /* Try to insert a node that already exists. */ node = NULL; result = insert_helper(ctx->rbt, "d.e.f", &node); ATF_CHECK_EQ(result, ISC_R_EXISTS); /* Node count must not have changed. */ ATF_CHECK_EQ(15, dns_rbt_nodecount(ctx->rbt)); /* Try to insert a node that doesn't exist. */ node = NULL; result = insert_helper(ctx->rbt, "0", &node); ATF_CHECK_EQ(result, ISC_R_SUCCESS); ATF_CHECK_EQ(compare_labelsequences(node, "0"), ISC_TRUE); /* Node count must have increased. */ ATF_CHECK_EQ(16, dns_rbt_nodecount(ctx->rbt)); /* Another. */ node = NULL; result = insert_helper(ctx->rbt, "example.com", &node); ATF_CHECK_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE(node != NULL); ATF_CHECK_EQ(node->data, NULL); /* Node count must have increased. */ ATF_CHECK_EQ(17, dns_rbt_nodecount(ctx->rbt)); /* Re-adding it should return EXISTS */ node = NULL; result = insert_helper(ctx->rbt, "example.com", &node); ATF_CHECK_EQ(result, ISC_R_EXISTS); /* Node count must not have changed. */ ATF_CHECK_EQ(17, dns_rbt_nodecount(ctx->rbt)); /* Fission the node d.e.f */ node = NULL; result = insert_helper(ctx->rbt, "k.e.f", &node); ATF_CHECK_EQ(result, ISC_R_SUCCESS); ATF_CHECK_EQ(compare_labelsequences(node, "k"), ISC_TRUE); /* Node count must have incremented twice ("d.e.f" fissioned to * "d" and "e.f", and the newly added "k"). */ ATF_CHECK_EQ(19, dns_rbt_nodecount(ctx->rbt)); /* Fission the node "g.h" */ node = NULL; result = insert_helper(ctx->rbt, "h", &node); ATF_CHECK_EQ(result, ISC_R_SUCCESS); ATF_CHECK_EQ(compare_labelsequences(node, "h"), ISC_TRUE); /* Node count must have incremented ("g.h" fissioned to "g" and * "h"). */ ATF_CHECK_EQ(20, dns_rbt_nodecount(ctx->rbt)); /* Add child domains */ node = NULL; result = insert_helper(ctx->rbt, "m.p.w.y.d.e.f", &node); ATF_CHECK_EQ(result, ISC_R_SUCCESS); ATF_CHECK_EQ(compare_labelsequences(node, "m"), ISC_TRUE); ATF_CHECK_EQ(21, dns_rbt_nodecount(ctx->rbt)); node = NULL; result = insert_helper(ctx->rbt, "n.p.w.y.d.e.f", &node); ATF_CHECK_EQ(result, ISC_R_SUCCESS); ATF_CHECK_EQ(compare_labelsequences(node, "n"), ISC_TRUE); ATF_CHECK_EQ(22, dns_rbt_nodecount(ctx->rbt)); node = NULL; result = insert_helper(ctx->rbt, "l.a", &node); ATF_CHECK_EQ(result, ISC_R_SUCCESS); ATF_CHECK_EQ(compare_labelsequences(node, "l"), ISC_TRUE); ATF_CHECK_EQ(23, dns_rbt_nodecount(ctx->rbt)); node = NULL; result = insert_helper(ctx->rbt, "r.d.e.f", &node); ATF_CHECK_EQ(result, ISC_R_SUCCESS); node = NULL; result = insert_helper(ctx->rbt, "s.d.e.f", &node); ATF_CHECK_EQ(result, ISC_R_SUCCESS); ATF_CHECK_EQ(25, dns_rbt_nodecount(ctx->rbt)); node = NULL; result = insert_helper(ctx->rbt, "h.w.y.d.e.f", &node); ATF_CHECK_EQ(result, ISC_R_SUCCESS); /* Add more nodes one by one to cover left and right rotation * functions. */ node = NULL; result = insert_helper(ctx->rbt, "f", &node); ATF_CHECK_EQ(result, ISC_R_SUCCESS); node = NULL; result = insert_helper(ctx->rbt, "m", &node); ATF_CHECK_EQ(result, ISC_R_SUCCESS); node = NULL; result = insert_helper(ctx->rbt, "nm", &node); ATF_CHECK_EQ(result, ISC_R_SUCCESS); node = NULL; result = insert_helper(ctx->rbt, "om", &node); ATF_CHECK_EQ(result, ISC_R_SUCCESS); node = NULL; result = insert_helper(ctx->rbt, "k", &node); ATF_CHECK_EQ(result, ISC_R_SUCCESS); node = NULL; result = insert_helper(ctx->rbt, "l", &node); ATF_CHECK_EQ(result, ISC_R_SUCCESS); node = NULL; result = insert_helper(ctx->rbt, "fe", &node); ATF_CHECK_EQ(result, ISC_R_SUCCESS); node = NULL; result = insert_helper(ctx->rbt, "ge", &node); ATF_CHECK_EQ(result, ISC_R_SUCCESS); node = NULL; result = insert_helper(ctx->rbt, "i", &node); ATF_CHECK_EQ(result, ISC_R_SUCCESS); node = NULL; result = insert_helper(ctx->rbt, "ae", &node); ATF_CHECK_EQ(result, ISC_R_SUCCESS); node = NULL; result = insert_helper(ctx->rbt, "n", &node); ATF_CHECK_EQ(result, ISC_R_SUCCESS); test_context_teardown(ctx); dns_test_end(); } ATF_TC(rbt_remove); ATF_TC_HEAD(rbt_remove, tc) { atf_tc_set_md_var(tc, "descr", "Test removal from a tree"); } ATF_TC_BODY(rbt_remove, tc) { /* * This testcase checks that after node removal, the * binary-search tree is valid and all nodes that are supposed * to exist are present in the correct order. It mainly tests * DomainTree as a BST, and not particularly as a red-black * tree. This test checks node deletion when upper nodes have * data. */ isc_result_t result; size_t j; UNUSED(tc); isc_mem_debugging = ISC_MEM_DEBUGRECORD; result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* * Delete single nodes and check if the rest of the nodes exist. */ for (j = 0; j < ordered_names_count; j++) { dns_rbt_t *mytree = NULL; dns_rbtnode_t *node; size_t i; size_t *n; isc_boolean_t tree_ok; dns_rbtnodechain_t chain; size_t start_node; /* Create a tree. */ result = dns_rbt_create(mctx, delete_data, NULL, &mytree); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* Insert test data into the tree. */ for (i = 0; i < domain_names_count; i++) { node = NULL; result = insert_helper(mytree, domain_names[i], &node); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); } /* Check that all names exist in order. */ for (i = 0; i < ordered_names_count; i++) { dns_fixedname_t fname; dns_name_t *name; build_name_from_str(ordered_names[i], &fname); name = dns_fixedname_name(&fname); node = NULL; result = dns_rbt_findnode(mytree, name, NULL, &node, NULL, DNS_RBTFIND_EMPTYDATA, NULL, NULL); ATF_CHECK_EQ(result, ISC_R_SUCCESS); /* Add node data */ ATF_REQUIRE(node != NULL); ATF_REQUIRE_EQ(node->data, NULL); n = isc_mem_get(mctx, sizeof(size_t)); *n = i; node->data = n; } /* Now, delete the j'th node from the tree. */ { dns_fixedname_t fname; dns_name_t *name; build_name_from_str(ordered_names[j], &fname); name = dns_fixedname_name(&fname); result = dns_rbt_deletename(mytree, name, ISC_FALSE); ATF_CHECK_EQ(result, ISC_R_SUCCESS); } /* Check RB tree properties. */ tree_ok = dns__rbt_checkproperties(mytree); ATF_CHECK_EQ(tree_ok, ISC_TRUE); dns_rbtnodechain_init(&chain, mctx); /* Now, walk through nodes in order. */ if (j == 0) { /* * Node for ordered_names[0] was already deleted * above. We start from node 1. */ dns_fixedname_t fname; dns_name_t *name; build_name_from_str(ordered_names[0], &fname); name = dns_fixedname_name(&fname); node = NULL; result = dns_rbt_findnode(mytree, name, NULL, &node, NULL, 0, NULL, NULL); ATF_CHECK_EQ(result, ISC_R_NOTFOUND); build_name_from_str(ordered_names[1], &fname); name = dns_fixedname_name(&fname); node = NULL; result = dns_rbt_findnode(mytree, name, NULL, &node, &chain, 0, NULL, NULL); ATF_CHECK_EQ(result, ISC_R_SUCCESS); start_node = 1; } else { /* Start from node 0. */ dns_fixedname_t fname; dns_name_t *name; build_name_from_str(ordered_names[0], &fname); name = dns_fixedname_name(&fname); node = NULL; result = dns_rbt_findnode(mytree, name, NULL, &node, &chain, 0, NULL, NULL); ATF_CHECK_EQ(result, ISC_R_SUCCESS); start_node = 0; } /* * node and chain have been set by the code above at * this point. */ for (i = start_node; i < ordered_names_count; i++) { dns_fixedname_t fname_j, fname_i; dns_name_t *name_j, *name_i; build_name_from_str(ordered_names[j], &fname_j); name_j = dns_fixedname_name(&fname_j); build_name_from_str(ordered_names[i], &fname_i); name_i = dns_fixedname_name(&fname_i); if (dns_name_equal(name_i, name_j)) { /* * This may be true for the last node if * we seek ahead in the loop using * dns_rbtnodechain_next() below. */ if (node == NULL) { break; } /* All ordered nodes have data * initially. If any node is empty, it * means it was removed, but an empty * node exists because it is a * super-domain. Just skip it. */ if (node->data == NULL) { result = dns_rbtnodechain_next(&chain, NULL, NULL); if (result == ISC_R_NOMORE) { node = NULL; } else { dns_rbtnodechain_current(&chain, NULL, NULL, &node); } } continue; } ATF_REQUIRE(node != NULL); n = (size_t *) node->data; if (n != NULL) { /* printf("n=%zu, i=%zu\n", *n, i); */ ATF_CHECK_EQ(*n, i); } result = dns_rbtnodechain_next(&chain, NULL, NULL); if (result == ISC_R_NOMORE) { node = NULL; } else { dns_rbtnodechain_current(&chain, NULL, NULL, &node); } } /* We should have reached the end of the tree. */ ATF_REQUIRE_EQ(node, NULL); dns_rbt_destroy(&mytree); } dns_test_end(); } ATF_TC(rbt_remove_empty); ATF_TC_HEAD(rbt_remove_empty, tc) { atf_tc_set_md_var(tc, "descr", "Test removal from a tree when " "upper nodes are empty"); } ATF_TC_BODY(rbt_remove_empty, tc) { /* * This test is similar to the rbt_remove test, but checks node * deletion when upper nodes are empty. */ isc_result_t result; size_t j; UNUSED(tc); isc_mem_debugging = ISC_MEM_DEBUGRECORD; result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* * Delete single nodes and check if the rest of the nodes exist. */ for (j = 0; j < ordered_names_count; j++) { dns_rbt_t *mytree = NULL; dns_rbtnode_t *node; size_t i; isc_boolean_t tree_ok; dns_rbtnodechain_t chain; size_t start_node; /* Create a tree. */ result = dns_rbt_create(mctx, delete_data, NULL, &mytree); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* Insert test data into the tree. */ for (i = 0; i < domain_names_count; i++) { node = NULL; result = insert_helper(mytree, domain_names[i], &node); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); } /* Check that all names exist in order. */ for (i = 0; i < ordered_names_count; i++) { dns_fixedname_t fname; dns_name_t *name; build_name_from_str(ordered_names[i], &fname); name = dns_fixedname_name(&fname); node = NULL; result = dns_rbt_findnode(mytree, name, NULL, &node, NULL, DNS_RBTFIND_EMPTYDATA, NULL, NULL); ATF_CHECK_EQ(result, ISC_R_SUCCESS); /* Check that node data is empty */ ATF_REQUIRE(node != NULL); ATF_REQUIRE_EQ(node->data, NULL); } /* Now, delete the j'th node from the tree. */ { dns_fixedname_t fname; dns_name_t *name; build_name_from_str(ordered_names[j], &fname); name = dns_fixedname_name(&fname); node = NULL; result = dns_rbt_findnode(mytree, name, NULL, &node, NULL, DNS_RBTFIND_EMPTYDATA, NULL, NULL); ATF_CHECK_EQ(result, ISC_R_SUCCESS); result = dns_rbt_deletenode(mytree, node, ISC_FALSE); ATF_CHECK_EQ(result, ISC_R_SUCCESS); } /* Check RB tree properties. */ tree_ok = dns__rbt_checkproperties(mytree); ATF_CHECK_EQ(tree_ok, ISC_TRUE); dns_rbtnodechain_init(&chain, mctx); /* Now, walk through nodes in order. */ if (j == 0) { /* * Node for ordered_names[0] was already deleted * above. We start from node 1. */ dns_fixedname_t fname; dns_name_t *name; build_name_from_str(ordered_names[0], &fname); name = dns_fixedname_name(&fname); node = NULL; result = dns_rbt_findnode(mytree, name, NULL, &node, NULL, DNS_RBTFIND_EMPTYDATA, NULL, NULL); ATF_CHECK(result != ISC_R_SUCCESS); build_name_from_str(ordered_names[1], &fname); name = dns_fixedname_name(&fname); node = NULL; result = dns_rbt_findnode(mytree, name, NULL, &node, &chain, DNS_RBTFIND_EMPTYDATA, NULL, NULL); ATF_CHECK_EQ(result, ISC_R_SUCCESS); start_node = 1; } else { /* Start from node 0. */ dns_fixedname_t fname; dns_name_t *name; build_name_from_str(ordered_names[0], &fname); name = dns_fixedname_name(&fname); node = NULL; result = dns_rbt_findnode(mytree, name, NULL, &node, &chain, DNS_RBTFIND_EMPTYDATA, NULL, NULL); ATF_CHECK_EQ(result, ISC_R_SUCCESS); start_node = 0; } /* * node and chain have been set by the code above at * this point. */ for (i = start_node; i < ordered_names_count; i++) { dns_fixedname_t fntmp1, fntmp2; dns_name_t *ntmp1, *ntmp2; dns_fixedname_t fname_j, fname_i; dns_name_t *name_j, *name_i; build_name_from_str("j.z.d.e.f", &fntmp1); ntmp1 = dns_fixedname_name(&fntmp1); build_name_from_str("z.d.e.f", &fntmp2); ntmp2 = dns_fixedname_name(&fntmp2); build_name_from_str(ordered_names[j], &fname_j); name_j = dns_fixedname_name(&fname_j); build_name_from_str(ordered_names[i], &fname_i); name_i = dns_fixedname_name(&fname_i); if (dns_name_equal(name_j, ntmp1) && dns_name_equal(name_j, ntmp2)) { /* * The only special case in the * tree. Here, "z.d.e.f" will not exist * as it would have been removed during * removal of "j.z.d.e.f". */ continue; } if (dns_name_equal(name_i, name_j)) { dns_fixedname_t fntmp3, fntmp4, fntmp5, fntmp6; dns_name_t *ntmp3, *ntmp4, *ntmp5, *ntmp6; /* * This may be true for the last node if * we seek ahead in the loop using * dns_rbtnodechain_next() below. */ if (node == NULL) { break; } /* * All ordered nodes are empty * initially. If an empty removed node * exists because it is a super-domain, * just skip it. */ build_name_from_str("d.e.f", &fntmp3); ntmp3 = dns_fixedname_name(&fntmp3); build_name_from_str("w.y.d.e.f", &fntmp4); ntmp4 = dns_fixedname_name(&fntmp4); build_name_from_str("z.d.e.f", &fntmp5); ntmp5 = dns_fixedname_name(&fntmp5); build_name_from_str("g.h", &fntmp6); ntmp6 = dns_fixedname_name(&fntmp6); if (dns_name_equal(name_j, ntmp3) || dns_name_equal(name_j, ntmp4) || dns_name_equal(name_j, ntmp5) || dns_name_equal(name_j, ntmp6)) { result = dns_rbtnodechain_next(&chain, NULL, NULL); if (result == ISC_R_NOMORE) { node = NULL; } else { dns_rbtnodechain_current(&chain, NULL, NULL, &node); } } continue; } ATF_REQUIRE(node != NULL); result = dns_rbtnodechain_next(&chain, NULL, NULL); if (result == ISC_R_NOMORE) { node = NULL; } else { dns_rbtnodechain_current(&chain, NULL, NULL, &node); } } /* We should have reached the end of the tree. */ ATF_REQUIRE_EQ(node, NULL); dns_rbt_destroy(&mytree); } dns_test_end(); } static void insert_nodes(dns_rbt_t *mytree, char **names, size_t *names_count, isc_uint32_t num_names) { isc_uint32_t i; for (i = 0; i < num_names; i++) { size_t *n; char namebuf[34]; n = isc_mem_get(mctx, sizeof(size_t)); ATF_REQUIRE(n != NULL); *n = i; /* Unused value */ while (1) { int j; dns_fixedname_t fname; dns_name_t *name; isc_result_t result; for (j = 0; j < 32; j++) { isc_uint32_t v; isc_random_get(&v); namebuf[j] = 'a' + (v % 26); } namebuf[32] = '.'; namebuf[33] = 0; build_name_from_str(namebuf, &fname); name = dns_fixedname_name(&fname); result = dns_rbt_addname(mytree, name, n); if (result == ISC_R_SUCCESS) { names[*names_count] = isc_mem_strdup(mctx, namebuf); *names_count += 1; break; } } } } static void remove_nodes(dns_rbt_t *mytree, char **names, size_t *names_count, isc_uint32_t num_names) { isc_uint32_t i; UNUSED(mytree); for (i = 0; i < num_names; i++) { isc_uint32_t node; dns_fixedname_t fname; dns_name_t *name; isc_result_t result; isc_random_get(&node); node %= *names_count; build_name_from_str(names[node], &fname); name = dns_fixedname_name(&fname); result = dns_rbt_deletename(mytree, name, ISC_FALSE); ATF_CHECK_EQ(result, ISC_R_SUCCESS); isc_mem_free(mctx, names[node]); if (*names_count > 0) { names[node] = names[*names_count - 1]; names[*names_count - 1] = NULL; *names_count -= 1; } } } static void check_tree(dns_rbt_t *mytree, char **names, size_t names_count) { isc_boolean_t tree_ok; UNUSED(names); ATF_CHECK_EQ(names_count + 1, dns_rbt_nodecount(mytree)); /* * The distance from each node to its sub-tree root must be less * than 2 * log_2(1024). */ ATF_CHECK((2 * 10) >= dns__rbt_getheight(mytree)); /* Also check RB tree properties */ tree_ok = dns__rbt_checkproperties(mytree); ATF_CHECK_EQ(tree_ok, ISC_TRUE); } ATF_TC(rbt_insert_and_remove); ATF_TC_HEAD(rbt_insert_and_remove, tc) { atf_tc_set_md_var(tc, "descr", "Test insert and remove in a loop"); } ATF_TC_BODY(rbt_insert_and_remove, tc) { /* * What is the best way to test our red-black tree code? It is * not a good method to test every case handled in the actual * code itself. This is because our approach itself may be * incorrect. * * We test our code at the interface level here by exercising the * tree randomly multiple times, checking that red-black tree * properties are valid, and all the nodes that are supposed to be * in the tree exist and are in order. * * NOTE: These tests are run within a single tree level in the * forest. The number of nodes in the tree level doesn't grow * over 1024. */ isc_result_t result; dns_rbt_t *mytree = NULL; /* * We use an array for storing names instead of a set * structure. It's slow, but works and is good enough for tests. */ char *names[1024]; size_t names_count; int i; UNUSED(tc); isc_mem_debugging = ISC_MEM_DEBUGRECORD; result = dns_test_begin(NULL, ISC_TRUE); ATF_CHECK_EQ(result, ISC_R_SUCCESS); result = dns_rbt_create(mctx, delete_data, NULL, &mytree); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); memset(names, 0, sizeof(names)); names_count = 0; /* Repeat the insert/remove test some 4096 times */ for (i = 0; i < 4096; i++) { isc_uint32_t num_names; isc_random_get(&num_names); if (names_count < 1024) { num_names %= 1024 - names_count; num_names++; } else { num_names = 0; } insert_nodes(mytree, names, &names_count, num_names); check_tree(mytree, names, names_count); isc_random_get(&num_names); if (names_count > 0) { num_names %= names_count; num_names++; } else { num_names = 0; } remove_nodes(mytree, names, &names_count, num_names); check_tree(mytree, names, names_count); } /* Remove the rest of the nodes */ remove_nodes(mytree, names, &names_count, names_count); check_tree(mytree, names, names_count); for (i = 0; i < 1024; i++) { if (names[i] != NULL) { isc_mem_free(mctx, names[i]); } } dns_rbt_destroy(&mytree); dns_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, rbt_create); ATF_TP_ADD_TC(tp, rbt_nodecount); ATF_TP_ADD_TC(tp, rbtnode_get_distance); ATF_TP_ADD_TC(tp, rbt_check_distance_random); ATF_TP_ADD_TC(tp, rbt_check_distance_ordered); ATF_TP_ADD_TC(tp, rbt_insert); ATF_TP_ADD_TC(tp, rbt_remove); ATF_TP_ADD_TC(tp, rbt_remove_empty); ATF_TP_ADD_TC(tp, rbt_insert_and_remove); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/dns/tests/name_test.c0000644000470500017500000000716512664710322020221 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include "dnstest.h" /* * Individual unit tests */ ATF_TC(fullcompare); ATF_TC_HEAD(fullcompare, tc) { atf_tc_set_md_var(tc, "descr", "dns_name_fullcompare test"); } ATF_TC_BODY(fullcompare, tc) { dns_fixedname_t fixed1; dns_fixedname_t fixed2; dns_name_t *name1; dns_name_t *name2; dns_namereln_t relation; int i; isc_result_t result; struct { const char *name1; const char *name2; dns_namereln_t relation; int order; unsigned int nlabels; } data[] = { /* relative */ { "", "", dns_namereln_equal, 0, 0 }, { "foo", "", dns_namereln_subdomain, 1, 0 }, { "", "foo", dns_namereln_contains, -1, 0 }, { "foo", "bar", dns_namereln_none, 4, 0 }, { "bar", "foo", dns_namereln_none, -4, 0 }, { "bar.foo", "foo", dns_namereln_subdomain, 1, 1 }, { "foo", "bar.foo", dns_namereln_contains, -1, 1 }, { "baz.bar.foo", "bar.foo", dns_namereln_subdomain, 1, 2 }, { "bar.foo", "baz.bar.foo", dns_namereln_contains, -1, 2 }, { "foo.example", "bar.example", dns_namereln_commonancestor, 4, 1 }, /* absolute */ { ".", ".", dns_namereln_equal, 0, 1 }, { "foo.", "bar.", dns_namereln_commonancestor, 4, 1 }, { "bar.", "foo.", dns_namereln_commonancestor, -4, 1 }, { "foo.example.", "bar.example.", dns_namereln_commonancestor, 4, 2 }, { "bar.foo.", "foo.", dns_namereln_subdomain, 1, 2 }, { "foo.", "bar.foo.", dns_namereln_contains, -1, 2 }, { "baz.bar.foo.", "bar.foo.", dns_namereln_subdomain, 1, 3 }, { "bar.foo.", "baz.bar.foo.", dns_namereln_contains, -1, 3 }, { NULL, NULL, dns_namereln_none, 0, 0 } }; UNUSED(tc); dns_fixedname_init(&fixed1); name1 = dns_fixedname_name(&fixed1); dns_fixedname_init(&fixed2); name2 = dns_fixedname_name(&fixed2); for (i = 0; data[i].name1 != NULL; i++) { int order = 3000; unsigned int nlabels = 3000; if (data[i].name1[0] == 0) { dns_fixedname_init(&fixed1); } else { result = dns_name_fromstring2(name1, data[i].name1, NULL, 0, NULL); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); } if (data[i].name2[0] == 0) { dns_fixedname_init(&fixed2); } else { result = dns_name_fromstring2(name2, data[i].name2, NULL, 0, NULL); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); } relation = dns_name_fullcompare(name1, name1, &order, &nlabels); ATF_REQUIRE_EQ(relation, dns_namereln_equal); ATF_REQUIRE_EQ(order, 0); ATF_REQUIRE_EQ(nlabels, name1->labels); /* Some random initializer */ order = 3001; nlabels = 3001; relation = dns_name_fullcompare(name1, name2, &order, &nlabels); ATF_REQUIRE_EQ(relation, data[i].relation); ATF_REQUIRE_EQ(order, data[i].order); ATF_REQUIRE_EQ(nlabels, data[i].nlabels); } } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, fullcompare); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/dns/tests/gost_test.c0000644000470500017500000002430412664710322020247 0ustar lamontlamont/* * Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* ! \file */ #include #include #include #include #include #include #include #include "dnstest.h" #ifdef HAVE_OPENSSL_GOST #include "../dst_gost.h" #include #include #include #include #include #endif #ifdef HAVE_PKCS11_GOST #include "../dst_gost.h" #include #define WANT_GOST_PARAMS #include #include #endif #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) /* * Test data from Wikipedia GOST (hash function) */ unsigned char digest[ISC_GOST_DIGESTLENGTH]; unsigned char buffer[1024]; const char *s; char str[2 * ISC_GOST_DIGESTLENGTH + 1]; int i = 0; isc_result_t tohexstr(unsigned char *d, unsigned int len, char *out); /* * Precondition: a hexadecimal number in *d, the length of that number in len, * and a pointer to a character array to put the output (*out). * Postcondition: A String representation of the given hexadecimal number is * placed into the array *out * * 'out' MUST point to an array of at least len * 2 + 1 * * Return values: ISC_R_SUCCESS if the operation is sucessful */ isc_result_t tohexstr(unsigned char *d, unsigned int len, char *out) { out[0]='\0'; char c_ret[] = "AA"; unsigned int j; strcat(out, "0x"); for (j = 0; j < len; j++) { sprintf(c_ret, "%02X", d[j]); strcat(out, c_ret); } strcat(out, "\0"); return (ISC_R_SUCCESS); } #define TEST_INPUT(x) (x), sizeof(x)-1 typedef struct hash_testcase { const char *input; size_t input_len; const char *result; int repeats; } hash_testcase_t; ATF_TC(isc_gost_md); ATF_TC_HEAD(isc_gost_md, tc) { atf_tc_set_md_var(tc, "descr", "GOST R 34.11-94 examples from Wikipedia"); } ATF_TC_BODY(isc_gost_md, tc) { isc_gost_t gost; isc_result_t result; UNUSED(tc); /* * These are the various test vectors. All of these are passed * through the hash function and the results are compared to the * result specified here. */ hash_testcase_t testcases[] = { /* Test 1 */ { TEST_INPUT(""), "0x981E5F3CA30C841487830F84FB433E1" "3AC1101569B9C13584AC483234CD656C0", 1 }, /* Test 2 */ { TEST_INPUT("a"), "0xE74C52DD282183BF37AF0079C9F7805" "5715A103F17E3133CEFF1AACF2F403011", 1 }, /* Test 3 */ { TEST_INPUT("abc"), "0xB285056DBF18D7392D7677369524DD1" "4747459ED8143997E163B2986F92FD42C", 1 }, /* Test 4 */ { TEST_INPUT("message digest"), "0xBC6041DD2AA401EBFA6E9886734174F" "EBDB4729AA972D60F549AC39B29721BA0", 1 }, /* Test 5 */ { TEST_INPUT("The quick brown fox jumps " "over the lazy dog"), "0x9004294A361A508C586FE53D1F1B027" "46765E71B765472786E4770D565830A76", 1 }, /* Test 6 */ { TEST_INPUT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcde" "fghijklmnopqrstuvwxyz0123456789"), "0x73B70A39497DE53A6E08C67B6D4DB85" "3540F03E9389299D9B0156EF7E85D0F61", 1 }, /* Test 7 */ { TEST_INPUT("1234567890123456789012345678901" "2345678901234567890123456789012" "345678901234567890"), "0x6BC7B38989B28CF93AE8842BF9D7529" "05910A7528A61E5BCE0782DE43E610C90", 1 }, /* Test 8 */ { TEST_INPUT("This is message, length=32 bytes"), "0x2CEFC2F7B7BDC514E18EA57FA74FF35" "7E7FA17D652C75F69CB1BE7893EDE48EB", 1 }, /* Test 9 */ { TEST_INPUT("Suppose the original message " "has length = 50 bytes"), "0xC3730C5CBCCACF915AC292676F21E8B" "D4EF75331D9405E5F1A61DC3130A65011", 1 }, /* Test 10 */ { TEST_INPUT("U") /* times 128 */, "0x1C4AC7614691BBF427FA2316216BE8F" "10D92EDFD37CD1027514C1008F649C4E8", 128 }, /* Test 11 */ { TEST_INPUT("a") /* times 1000000 */, "0x8693287AA62F9478F7CB312EC0866B6" "C4E4A0F11160441E8F4FFCD2715DD554F", 1000000 }, { NULL, 0, NULL, 1 } }; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE(result == ISC_R_SUCCESS); hash_testcase_t *testcase = testcases; while (testcase->input != NULL && testcase->result != NULL) { result = isc_gost_init(&gost); ATF_REQUIRE(result == ISC_R_SUCCESS); for(i = 0; i < testcase->repeats; i++) { result = isc_gost_update(&gost, (const isc_uint8_t *) testcase->input, testcase->input_len); ATF_REQUIRE(result == ISC_R_SUCCESS); } result = isc_gost_final(&gost, digest); ATF_REQUIRE(result == ISC_R_SUCCESS); tohexstr(digest, ISC_GOST_DIGESTLENGTH, str); ATF_CHECK_STREQ(str, testcase->result); testcase++; } dns_test_end(); } ATF_TC(isc_gost_private); ATF_TC_HEAD(isc_gost_private, tc) { atf_tc_set_md_var(tc, "descr", "GOST R 34.10-2001 private key"); } ATF_TC_BODY(isc_gost_private, tc) { isc_result_t result; unsigned char privraw[31] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e }; #ifdef HAVE_OPENSSL_GOST unsigned char rbuf[32]; unsigned char privasn1[70] = { 0x30, 0x44, 0x02, 0x01, 0x00, 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, 0x04, 0x21, 0x02, 0x1f, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e }; unsigned char abuf[71]; unsigned char gost_dummy_key[71] = { 0x30, 0x45, 0x02, 0x01, 0x00, 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, 0x04, 0x22, 0x02, 0x20, 0x1b, 0x3f, 0x94, 0xf7, 0x1a, 0x5f, 0x2f, 0xe7, 0xe5, 0x74, 0x0b, 0x8c, 0xd4, 0xb7, 0x18, 0xdd, 0x65, 0x68, 0x26, 0xd1, 0x54, 0xfb, 0x77, 0xba, 0x63, 0x72, 0xd9, 0xf0, 0x63, 0x87, 0xe0, 0xd6 }; EVP_PKEY *pkey; EC_KEY *eckey; BIGNUM *privkey; const BIGNUM *privkey1; const unsigned char *p; int len; unsigned char *q; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE(result == ISC_R_SUCCESS); /* raw parse */ privkey = BN_bin2bn(privraw, (int) sizeof(privraw), NULL); ATF_REQUIRE(privkey != NULL); p = gost_dummy_key; pkey = NULL; ATF_REQUIRE(d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, (long) sizeof(gost_dummy_key)) != NULL); ATF_REQUIRE(pkey != NULL); ATF_REQUIRE(EVP_PKEY_bits(pkey) == 256); eckey = EVP_PKEY_get0(pkey); ATF_REQUIRE(eckey != NULL); ATF_REQUIRE(EC_KEY_set_private_key(eckey, privkey) == 1); BN_clear_free(privkey); /* asn1 tofile */ len = i2d_PrivateKey(pkey, NULL); ATF_REQUIRE(len == 70); q = abuf; ATF_REQUIRE(i2d_PrivateKey(pkey, &q) == len); ATF_REQUIRE(memcmp(abuf, privasn1, len) == 0); EVP_PKEY_free(pkey); /* asn1 parse */ p = privasn1; pkey = NULL; ATF_REQUIRE(d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, (long) len) != NULL); ATF_REQUIRE(pkey != NULL); eckey = EVP_PKEY_get0(pkey); ATF_REQUIRE(eckey != NULL); privkey1 = EC_KEY_get0_private_key(eckey); len = BN_num_bytes(privkey1); ATF_REQUIRE(len == 31); ATF_REQUIRE(BN_bn2bin(privkey1, rbuf) == len); ATF_REQUIRE(memcmp(rbuf, privraw, len) == 0); dns_test_end(); #else CK_BBOOL truevalue = TRUE; CK_BBOOL falsevalue = FALSE; CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; CK_KEY_TYPE keyType = CKK_GOSTR3410; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_VALUE, privraw, sizeof(privraw) }, { CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset, (CK_ULONG) sizeof(pk11_gost_a_paramset) }, { CKA_GOSTR3411_PARAMS, pk11_gost_paramset, (CK_ULONG) sizeof(pk11_gost_paramset) } }; CK_MECHANISM mech = { CKM_GOSTR3410_WITH_GOSTR3411, NULL, 0 }; CK_BYTE sig[64]; CK_ULONG siglen; pk11_context_t pk11_ctx; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE(result == ISC_R_SUCCESS); /* create the private key */ memset(&pk11_ctx, 0, sizeof(pk11_ctx)); ATF_REQUIRE(pk11_get_session(&pk11_ctx, OP_GOST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_GOST)) == ISC_R_SUCCESS); pk11_ctx.object = CK_INVALID_HANDLE; pk11_ctx.ontoken = ISC_FALSE; ATF_REQUIRE(pkcs_C_CreateObject(pk11_ctx.session, keyTemplate, (CK_ULONG) 9, &pk11_ctx.object) == CKR_OK); ATF_REQUIRE(pk11_ctx.object != CK_INVALID_HANDLE); /* sign something */ ATF_REQUIRE(pkcs_C_SignInit(pk11_ctx.session, &mech, pk11_ctx.object) == CKR_OK); siglen = 0; ATF_REQUIRE(pkcs_C_Sign(pk11_ctx.session, sig, 64, NULL, &siglen) == CKR_OK); ATF_REQUIRE(siglen == 64); ATF_REQUIRE(pkcs_C_Sign(pk11_ctx.session, sig, 64, sig, &siglen) == CKR_OK); ATF_REQUIRE(siglen == 64); dns_test_end(); #endif }; #else ATF_TC(untested); ATF_TC_HEAD(untested, tc) { atf_tc_set_md_var(tc, "descr", "skipping gost test"); } ATF_TC_BODY(untested, tc) { UNUSED(tc); atf_tc_skip("GOST not available"); } #endif /* * Main */ ATF_TP_ADD_TCS(tp) { #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) ATF_TP_ADD_TC(tp, isc_gost_md); ATF_TP_ADD_TC(tp, isc_gost_private); #else ATF_TP_ADD_TC(tp, untested); #endif return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/dns/tests/geoip_test.c0000644000470500017500000003664512664710322020411 0ustar lamontlamont/* * Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include "dnstest.h" #ifdef HAVE_GEOIP #include /* We use GeoIP databases from the 'geoip' system test */ #define TEST_GEOIP_DATA "../../../bin/tests/system/geoip/data" /* * Helper functions * (Mostly copied from bin/named/geoip.c) */ static dns_geoip_databases_t geoip = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static void init_geoip_db(GeoIP **dbp, GeoIPDBTypes edition, GeoIPDBTypes fallback, GeoIPOptions method, const char *name) { char *info; GeoIP *db; REQUIRE(dbp != NULL); db = *dbp; if (db != NULL) { GeoIP_delete(db); db = *dbp = NULL; } if (! GeoIP_db_avail(edition)) { fprintf(stderr, "GeoIP %s (type %d) DB not available\n", name, edition); goto fail; } fprintf(stderr, "initializing GeoIP %s (type %d) DB\n", name, edition); db = GeoIP_open_type(edition, method); if (db == NULL) { fprintf(stderr, "failed to initialize GeoIP %s (type %d) DB%s\n", name, edition, fallback == 0 ? "; geoip matches using this database will fail" : ""); goto fail; } info = GeoIP_database_info(db); if (info != NULL) fprintf(stderr, "%s\n", info); *dbp = db; return; fail: if (fallback != 0) init_geoip_db(dbp, fallback, 0, method, name); } static void load_geoip(const char *dir) { GeoIPOptions method; #ifdef _WIN32 method = GEOIP_STANDARD; #else method = GEOIP_MMAP_CACHE; #endif if (dir != NULL) { char *p; DE_CONST(dir, p); GeoIP_setup_custom_directory(p); } init_geoip_db(&geoip.country_v4, GEOIP_COUNTRY_EDITION, 0, method, "Country (IPv4)"); #ifdef HAVE_GEOIP_V6 init_geoip_db(&geoip.country_v6, GEOIP_COUNTRY_EDITION_V6, 0, method, "Country (IPv6)"); #endif init_geoip_db(&geoip.city_v4, GEOIP_CITY_EDITION_REV1, GEOIP_CITY_EDITION_REV0, method, "City (IPv4)"); #if defined(HAVE_GEOIP_V6) && defined(HAVE_GEOIP_CITY_V6) init_geoip_db(&geoip.city_v6, GEOIP_CITY_EDITION_REV1_V6, GEOIP_CITY_EDITION_REV0_V6, method, "City (IPv6)"); #endif init_geoip_db(&geoip.region, GEOIP_REGION_EDITION_REV1, GEOIP_REGION_EDITION_REV0, method, "Region"); init_geoip_db(&geoip.isp, GEOIP_ISP_EDITION, 0, method, "ISP"); init_geoip_db(&geoip.org, GEOIP_ORG_EDITION, 0, method, "Org"); init_geoip_db(&geoip.as, GEOIP_ASNUM_EDITION, 0, method, "AS"); init_geoip_db(&geoip.domain, GEOIP_DOMAIN_EDITION, 0, method, "Domain"); init_geoip_db(&geoip.netspeed, GEOIP_NETSPEED_EDITION, 0, method, "NetSpeed"); } static isc_boolean_t do_lookup_string(const char *addr, dns_geoip_subtype_t subtype, const char *string) { dns_geoip_elem_t elt; struct in_addr in4; isc_netaddr_t na; inet_pton(AF_INET, addr, &in4); isc_netaddr_fromin(&na, &in4); elt.subtype = subtype; strcpy(elt.as_string, string); return (dns_geoip_match(&na, &geoip, &elt)); } static isc_boolean_t do_lookup_string_v6(const char *addr, dns_geoip_subtype_t subtype, const char *string) { dns_geoip_elem_t elt; struct in6_addr in6; isc_netaddr_t na; inet_pton(AF_INET6, addr, &in6); isc_netaddr_fromin6(&na, &in6); elt.subtype = subtype; strcpy(elt.as_string, string); return (dns_geoip_match(&na, &geoip, &elt)); } static isc_boolean_t do_lookup_int(const char *addr, dns_geoip_subtype_t subtype, int id) { dns_geoip_elem_t elt; struct in_addr in4; isc_netaddr_t na; inet_pton(AF_INET, addr, &in4); isc_netaddr_fromin(&na, &in4); elt.subtype = subtype; elt.as_int = id; return (dns_geoip_match(&na, &geoip, &elt)); } /* * Individual unit tests */ /* GeoIP country matching */ ATF_TC(country); ATF_TC_HEAD(country, tc) { atf_tc_set_md_var(tc, "descr", "test country database matching"); } ATF_TC_BODY(country, tc) { isc_result_t result; isc_boolean_t match; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE(result == ISC_R_SUCCESS); /* Use databases from the geoip system test */ load_geoip(TEST_GEOIP_DATA); if (geoip.country_v4 == NULL) { dns_test_end(); atf_tc_skip("Database not available"); } match = do_lookup_string("10.53.0.1", dns_geoip_country_code, "AU"); ATF_CHECK(match); match = do_lookup_string("10.53.0.1", dns_geoip_country_code3, "AUS"); ATF_CHECK(match); match = do_lookup_string("10.53.0.1", dns_geoip_country_name, "Australia"); ATF_CHECK(match); dns_test_end(); } /* GeoIP country (ipv6) matching */ ATF_TC(country_v6); ATF_TC_HEAD(country_v6, tc) { atf_tc_set_md_var(tc, "descr", "test country (ipv6) database matching"); } ATF_TC_BODY(country_v6, tc) { isc_result_t result; isc_boolean_t match; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE(result == ISC_R_SUCCESS); /* Use databases from the geoip system test */ load_geoip(TEST_GEOIP_DATA); if (geoip.country_v6 == NULL) { dns_test_end(); atf_tc_skip("Database not available"); } match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", dns_geoip_country_code, "AU"); ATF_CHECK(match); match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", dns_geoip_country_code3, "AUS"); ATF_CHECK(match); match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", dns_geoip_country_name, "Australia"); ATF_CHECK(match); dns_test_end(); } /* GeoIP city (ipv4) matching */ ATF_TC(city); ATF_TC_HEAD(city, tc) { atf_tc_set_md_var(tc, "descr", "test city database matching"); } ATF_TC_BODY(city, tc) { isc_result_t result; isc_boolean_t match; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE(result == ISC_R_SUCCESS); /* Use databases from the geoip system test */ load_geoip(TEST_GEOIP_DATA); if (geoip.city_v4 == NULL) { dns_test_end(); atf_tc_skip("Database not available"); } match = do_lookup_string("10.53.0.1", dns_geoip_city_continentcode, "NA"); ATF_CHECK(match); match = do_lookup_string("10.53.0.1", dns_geoip_city_countrycode, "US"); ATF_CHECK(match); match = do_lookup_string("10.53.0.1", dns_geoip_city_countrycode3, "USA"); ATF_CHECK(match); match = do_lookup_string("10.53.0.1", dns_geoip_city_countryname, "United States"); ATF_CHECK(match); match = do_lookup_string("10.53.0.1", dns_geoip_city_region, "CA"); ATF_CHECK(match); match = do_lookup_string("10.53.0.1", dns_geoip_city_regionname, "California"); ATF_CHECK(match); match = do_lookup_string("10.53.0.1", dns_geoip_city_name, "Redwood City"); ATF_CHECK(match); match = do_lookup_string("10.53.0.1", dns_geoip_city_postalcode, "94063"); ATF_CHECK(match); match = do_lookup_int("10.53.0.1", dns_geoip_city_areacode, 650); ATF_CHECK(match); match = do_lookup_int("10.53.0.1", dns_geoip_city_metrocode, 807); ATF_CHECK(match); dns_test_end(); } /* GeoIP city (ipv6) matching */ ATF_TC(city_v6); ATF_TC_HEAD(city_v6, tc) { atf_tc_set_md_var(tc, "descr", "test city (ipv6) database matching"); } ATF_TC_BODY(city_v6, tc) { isc_result_t result; isc_boolean_t match; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE(result == ISC_R_SUCCESS); /* Use databases from the geoip system test */ load_geoip(TEST_GEOIP_DATA); if (geoip.city_v6 == NULL) { dns_test_end(); atf_tc_skip("Database not available"); } match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", dns_geoip_city_continentcode, "NA"); ATF_CHECK(match); match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", dns_geoip_city_countrycode, "US"); ATF_CHECK(match); match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", dns_geoip_city_countrycode3, "USA"); ATF_CHECK(match); match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", dns_geoip_city_countryname, "United States"); ATF_CHECK(match); match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", dns_geoip_city_region, "CA"); ATF_CHECK(match); match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", dns_geoip_city_regionname, "California"); ATF_CHECK(match); match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", dns_geoip_city_name, "Redwood City"); ATF_CHECK(match); match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", dns_geoip_city_postalcode, "94063"); ATF_CHECK(match); dns_test_end(); } /* GeoIP region matching */ ATF_TC(region); ATF_TC_HEAD(region, tc) { atf_tc_set_md_var(tc, "descr", "test region database matching"); } ATF_TC_BODY(region, tc) { isc_result_t result; isc_boolean_t match; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE(result == ISC_R_SUCCESS); /* Use databases from the geoip system test */ load_geoip(TEST_GEOIP_DATA); if (geoip.region == NULL) { dns_test_end(); atf_tc_skip("Database not available"); } match = do_lookup_string("10.53.0.1", dns_geoip_region_code, "CA"); ATF_CHECK(match); match = do_lookup_string("10.53.0.1", dns_geoip_region_name, "California"); ATF_CHECK(match); match = do_lookup_string("10.53.0.1", dns_geoip_region_countrycode, "US"); ATF_CHECK(match); dns_test_end(); } /* * GeoIP best-database matching * (With no specified databse and a city database available, answers * should come from city database. With city database unavailable, region * database. Region database unavailable, country database.) */ ATF_TC(best); ATF_TC_HEAD(best, tc) { atf_tc_set_md_var(tc, "descr", "test best database matching"); } ATF_TC_BODY(best, tc) { isc_result_t result; isc_boolean_t match; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE(result == ISC_R_SUCCESS); /* Use databases from the geoip system test */ load_geoip(TEST_GEOIP_DATA); if (geoip.region == NULL) { dns_test_end(); atf_tc_skip("Database not available"); } match = do_lookup_string("10.53.0.4", dns_geoip_countrycode, "US"); ATF_CHECK(match); match = do_lookup_string("10.53.0.4", dns_geoip_countrycode3, "USA"); ATF_CHECK(match); match = do_lookup_string("10.53.0.4", dns_geoip_countryname, "United States"); ATF_CHECK(match); match = do_lookup_string("10.53.0.4", dns_geoip_regionname, "Virginia"); ATF_CHECK(match); match = do_lookup_string("10.53.0.4", dns_geoip_region, "VA"); ATF_CHECK(match); GeoIP_delete(geoip.city_v4); geoip.city_v4 = NULL; match = do_lookup_string("10.53.0.4", dns_geoip_countrycode, "AU"); ATF_CHECK(match); /* * Note, region doesn't support code3 or countryname, so * the next two would be answered from the country database instead */ match = do_lookup_string("10.53.0.4", dns_geoip_countrycode3, "CAN"); ATF_CHECK(match); match = do_lookup_string("10.53.0.4", dns_geoip_countryname, "Canada"); ATF_CHECK(match); GeoIP_delete(geoip.region); geoip.region = NULL; match = do_lookup_string("10.53.0.4", dns_geoip_countrycode, "CA"); ATF_CHECK(match); match = do_lookup_string("10.53.0.4", dns_geoip_countrycode3, "CAN"); ATF_CHECK(match); match = do_lookup_string("10.53.0.4", dns_geoip_countryname, "Canada"); ATF_CHECK(match); dns_test_end(); } /* GeoIP asnum matching */ ATF_TC(asnum); ATF_TC_HEAD(asnum, tc) { atf_tc_set_md_var(tc, "descr", "test asnum database matching"); } ATF_TC_BODY(asnum, tc) { isc_result_t result; isc_boolean_t match; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE(result == ISC_R_SUCCESS); /* Use databases from the geoip system test */ load_geoip(TEST_GEOIP_DATA); if (geoip.as == NULL) { dns_test_end(); atf_tc_skip("Database not available"); } match = do_lookup_string("10.53.0.3", dns_geoip_as_asnum, "AS100003 Three Network Labs"); ATF_CHECK(match); dns_test_end(); } /* GeoIP isp matching */ ATF_TC(isp); ATF_TC_HEAD(isp, tc) { atf_tc_set_md_var(tc, "descr", "test isp database matching"); } ATF_TC_BODY(isp, tc) { isc_result_t result; isc_boolean_t match; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE(result == ISC_R_SUCCESS); /* Use databases from the geoip system test */ load_geoip(TEST_GEOIP_DATA); if (geoip.isp == NULL) { dns_test_end(); atf_tc_skip("Database not available"); } match = do_lookup_string("10.53.0.1", dns_geoip_isp_name, "One Systems, Inc."); ATF_CHECK(match); dns_test_end(); } /* GeoIP org matching */ ATF_TC(org); ATF_TC_HEAD(org, tc) { atf_tc_set_md_var(tc, "descr", "test org database matching"); } ATF_TC_BODY(org, tc) { isc_result_t result; isc_boolean_t match; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE(result == ISC_R_SUCCESS); /* Use databases from the geoip system test */ load_geoip(TEST_GEOIP_DATA); if (geoip.org == NULL) { dns_test_end(); atf_tc_skip("Database not available"); } match = do_lookup_string("10.53.0.2", dns_geoip_org_name, "Two Technology Ltd."); ATF_CHECK(match); dns_test_end(); } /* GeoIP domain matching */ ATF_TC(domain); ATF_TC_HEAD(domain, tc) { atf_tc_set_md_var(tc, "descr", "test domain database matching"); } ATF_TC_BODY(domain, tc) { isc_result_t result; isc_boolean_t match; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE(result == ISC_R_SUCCESS); /* Use databases from the geoip system test */ load_geoip(TEST_GEOIP_DATA); if (geoip.domain == NULL) { dns_test_end(); atf_tc_skip("Database not available"); } match = do_lookup_string("10.53.0.4", dns_geoip_domain_name, "four.com"); ATF_CHECK(match); dns_test_end(); } /* GeoIP netspeed matching */ ATF_TC(netspeed); ATF_TC_HEAD(netspeed, tc) { atf_tc_set_md_var(tc, "descr", "test netspeed database matching"); } ATF_TC_BODY(netspeed, tc) { isc_result_t result; isc_boolean_t match; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE(result == ISC_R_SUCCESS); /* Use databases from the geoip system test */ load_geoip(TEST_GEOIP_DATA); if (geoip.netspeed == NULL) { dns_test_end(); atf_tc_skip("Database not available"); } match = do_lookup_int("10.53.0.1", dns_geoip_netspeed_id, 0); ATF_CHECK(match); match = do_lookup_int("10.53.0.2", dns_geoip_netspeed_id, 1); ATF_CHECK(match); match = do_lookup_int("10.53.0.3", dns_geoip_netspeed_id, 2); ATF_CHECK(match); match = do_lookup_int("10.53.0.4", dns_geoip_netspeed_id, 3); ATF_CHECK(match); dns_test_end(); } #else ATF_TC(untested); ATF_TC_HEAD(untested, tc) { atf_tc_set_md_var(tc, "descr", "skipping geoip test"); } ATF_TC_BODY(untested, tc) { UNUSED(tc); atf_tc_skip("GeoIP not available"); } #endif /* * Main */ ATF_TP_ADD_TCS(tp) { #ifdef HAVE_GEOIP ATF_TP_ADD_TC(tp, country); ATF_TP_ADD_TC(tp, country_v6); ATF_TP_ADD_TC(tp, city); ATF_TP_ADD_TC(tp, city_v6); ATF_TP_ADD_TC(tp, region); ATF_TP_ADD_TC(tp, best); ATF_TP_ADD_TC(tp, asnum); ATF_TP_ADD_TC(tp, isp); ATF_TP_ADD_TC(tp, org); ATF_TP_ADD_TC(tp, domain); ATF_TP_ADD_TC(tp, netspeed); #else ATF_TP_ADD_TC(tp, untested); #endif return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/dns/tests/db_test.c0000644000470500017500000000413312664710322017656 0ustar lamontlamont/* * Copyright (C) 2013, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include "dnstest.h" /* * Helper functions */ #define BUFLEN 255 #define BIGBUFLEN (64 * 1024) #define TEST_ORIGIN "test" /* * Individual unit tests */ ATF_TC(getoriginnode); ATF_TC_HEAD(getoriginnode, tc) { atf_tc_set_md_var(tc, "descr", "test multiple calls to dns_db_getoriginnode"); } ATF_TC_BODY(getoriginnode, tc) { dns_db_t *db = NULL; dns_dbnode_t *node = NULL; isc_mem_t *mymctx = NULL; isc_result_t result; result = isc_mem_create(0, 0, &mymctx); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_hash_create(mymctx, NULL, 256); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_create(mymctx, "rbt", dns_rootname, dns_dbtype_zone, dns_rdataclass_in, 0, NULL, &db); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_getoriginnode(db, &node); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_db_detachnode(db, &node); result = dns_db_getoriginnode(db, &node); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_db_detachnode(db, &node); dns_db_detach(&db); isc_mem_detach(&mymctx); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, getoriginnode); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/dns/tests/dnstest.c0000644000470500017500000001702612664710322017723 0ustar lamontlamont/* * Copyright (C) 2011-2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dnstest.h" isc_mem_t *mctx = NULL; isc_entropy_t *ectx = NULL; isc_log_t *lctx = NULL; isc_taskmgr_t *taskmgr = NULL; isc_task_t *maintask = NULL; isc_timermgr_t *timermgr = NULL; isc_socketmgr_t *socketmgr = NULL; dns_zonemgr_t *zonemgr = NULL; isc_boolean_t app_running = ISC_FALSE; int ncpus; static isc_boolean_t hash_active = ISC_FALSE, dst_active = ISC_FALSE; /* * Logging categories: this needs to match the list in bin/named/log.c. */ static isc_logcategory_t categories[] = { { "", 0 }, { "client", 0 }, { "network", 0 }, { "update", 0 }, { "queries", 0 }, { "unmatched", 0 }, { "update-security", 0 }, { "query-errors", 0 }, { NULL, 0 } }; static void cleanup_managers(void) { if (app_running) isc_app_finish(); if (socketmgr != NULL) isc_socketmgr_destroy(&socketmgr); if (maintask != NULL) isc_task_destroy(&maintask); if (taskmgr != NULL) isc_taskmgr_destroy(&taskmgr); if (timermgr != NULL) isc_timermgr_destroy(&timermgr); } static isc_result_t create_managers(void) { isc_result_t result; #ifdef ISC_PLATFORM_USETHREADS ncpus = isc_os_ncpus(); #else ncpus = 1; #endif CHECK(isc_taskmgr_create(mctx, ncpus, 0, &taskmgr)); CHECK(isc_timermgr_create(mctx, &timermgr)); CHECK(isc_socketmgr_create(mctx, &socketmgr)); CHECK(isc_task_create(taskmgr, 0, &maintask)); return (ISC_R_SUCCESS); cleanup: cleanup_managers(); return (result); } isc_result_t dns_test_begin(FILE *logfile, isc_boolean_t start_managers) { isc_result_t result; if (start_managers) CHECK(isc_app_start()); isc_mem_debugging |= ISC_MEM_DEBUGRECORD; CHECK(isc_mem_create(0, 0, &mctx)); CHECK(isc_entropy_create(mctx, &ectx)); CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)); hash_active = ISC_TRUE; CHECK(dst_lib_init(mctx, ectx, ISC_ENTROPY_BLOCKING)); dst_active = ISC_TRUE; if (logfile != NULL) { isc_logdestination_t destination; isc_logconfig_t *logconfig = NULL; CHECK(isc_log_create(mctx, &lctx, &logconfig)); isc_log_registercategories(lctx, categories); isc_log_setcontext(lctx); dns_log_init(lctx); dns_log_setcontext(lctx); destination.file.stream = logfile; destination.file.name = NULL; destination.file.versions = ISC_LOG_ROLLNEVER; destination.file.maximum_size = 0; CHECK(isc_log_createchannel(logconfig, "stderr", ISC_LOG_TOFILEDESC, ISC_LOG_DYNAMIC, &destination, 0)); CHECK(isc_log_usechannel(logconfig, "stderr", NULL, NULL)); } dns_result_register(); if (start_managers) CHECK(create_managers()); /* * atf-run changes us to a /tmp directory, so tests * that access test data files must first chdir to the proper * location. */ if (chdir(TESTS) == -1) CHECK(ISC_R_FAILURE); return (ISC_R_SUCCESS); cleanup: dns_test_end(); return (result); } void dns_test_end(void) { if (lctx != NULL) isc_log_destroy(&lctx); if (dst_active) { dst_lib_destroy(); dst_active = ISC_FALSE; } if (hash_active) { isc_hash_destroy(); hash_active = ISC_FALSE; } if (ectx != NULL) isc_entropy_detach(&ectx); cleanup_managers(); if (mctx != NULL) isc_mem_destroy(&mctx); } /* * Create a zone with origin 'name', return a pointer to the zone object in * 'zonep'. If 'view' is set, add the zone to that view; otherwise, create * a new view for the purpose. * * If the created view is going to be needed by the caller subsequently, * then 'keepview' should be set to true; this will prevent the view * from being detached. In this case, the caller is responsible for * detaching the view. */ isc_result_t dns_test_makezone(const char *name, dns_zone_t **zonep, dns_view_t *view, isc_boolean_t keepview) { isc_result_t result; dns_zone_t *zone = NULL; isc_buffer_t buffer; dns_fixedname_t fixorigin; dns_name_t *origin; if (view == NULL) CHECK(dns_view_create(mctx, dns_rdataclass_in, "view", &view)); else if (!keepview) keepview = ISC_TRUE; zone = *zonep; if (zone == NULL) CHECK(dns_zone_create(&zone, mctx)); isc_buffer_constinit(&buffer, name, strlen(name)); isc_buffer_add(&buffer, strlen(name)); dns_fixedname_init(&fixorigin); origin = dns_fixedname_name(&fixorigin); CHECK(dns_name_fromtext(origin, &buffer, dns_rootname, 0, NULL)); CHECK(dns_zone_setorigin(zone, origin)); dns_zone_setview(zone, view); dns_zone_settype(zone, dns_zone_master); dns_zone_setclass(zone, view->rdclass); dns_view_addzone(view, zone); if (!keepview) dns_view_detach(&view); *zonep = zone; return (ISC_R_SUCCESS); cleanup: if (zone != NULL) dns_zone_detach(&zone); if (view != NULL) dns_view_detach(&view); return (result); } isc_result_t dns_test_setupzonemgr(void) { isc_result_t result; REQUIRE(zonemgr == NULL); result = dns_zonemgr_create(mctx, taskmgr, timermgr, socketmgr, &zonemgr); return (result); } isc_result_t dns_test_managezone(dns_zone_t *zone) { isc_result_t result; REQUIRE(zonemgr != NULL); result = dns_zonemgr_setsize(zonemgr, 1); if (result != ISC_R_SUCCESS) return (result); result = dns_zonemgr_managezone(zonemgr, zone); return (result); } void dns_test_releasezone(dns_zone_t *zone) { REQUIRE(zonemgr != NULL); dns_zonemgr_releasezone(zonemgr, zone); } void dns_test_closezonemgr(void) { REQUIRE(zonemgr != NULL); dns_zonemgr_shutdown(zonemgr); dns_zonemgr_detach(&zonemgr); } /* * Sleep for 'usec' microseconds. */ void dns_test_nap(isc_uint32_t usec) { #ifdef HAVE_NANOSLEEP struct timespec ts; ts.tv_sec = usec / 1000000; ts.tv_nsec = (usec % 1000000) * 1000; nanosleep(&ts, NULL); #elif HAVE_USLEEP usleep(usec); #else /* * No fractional-second sleep function is available, so we * round up to the nearest second and sleep instead */ sleep((usec / 1000000) + 1); #endif } isc_result_t dns_test_loaddb(dns_db_t **db, dns_dbtype_t dbtype, const char *origin, const char *testfile) { isc_result_t result; dns_fixedname_t fixed; dns_name_t *name; dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); result = dns_name_fromstring(name, origin, 0, NULL); if (result != ISC_R_SUCCESS) return(result); result = dns_db_create(mctx, "rbt", name, dbtype, dns_rdataclass_in, 0, NULL, db); if (result != ISC_R_SUCCESS) return (result); result = dns_db_load(*db, testfile); return (result); } bind9-9.10.3.dfsg.P4/lib/dns/tests/private_test.c0000644000470500017500000001263612664710322020752 0ustar lamontlamont/* * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include "dnstest.h" static dns_rdatatype_t privatetype = 65534; typedef struct { unsigned char alg; dns_keytag_t keyid; isc_boolean_t remove; isc_boolean_t complete; } signing_testcase_t; typedef struct { unsigned char hash; unsigned char flags; unsigned int iterations; unsigned long salt; isc_boolean_t remove; isc_boolean_t pending; isc_boolean_t nonsec; } nsec3_testcase_t; /* * Helper functions */ static void make_signing(signing_testcase_t *testcase, dns_rdata_t *private, unsigned char *buf, size_t len) { dns_rdata_init(private); buf[0] = testcase->alg; buf[1] = (testcase->keyid & 0xff00) >> 8; buf[2] = (testcase->keyid & 0xff); buf[3] = testcase->remove; buf[4] = testcase->complete; private->data = buf; private->length = len; private->type = privatetype; private->rdclass = dns_rdataclass_in; } static void make_nsec3(nsec3_testcase_t *testcase, dns_rdata_t *private, unsigned char *pbuf) { dns_rdata_nsec3param_t params; dns_rdata_t nsec3param = DNS_RDATA_INIT; unsigned char bufdata[BUFSIZ]; isc_buffer_t buf; isc_uint32_t salt; unsigned char *sp; int slen = 4; /* for simplicity, we're using a maximum salt length of 4 */ salt = htonl(testcase->salt); sp = (unsigned char *) &salt; while (*sp == '\0' && slen > 0) { slen--; sp++; } params.common.rdclass = dns_rdataclass_in; params.common.rdtype = dns_rdatatype_nsec3param; params.hash = testcase->hash; params.iterations = testcase->iterations; params.salt = sp; params.salt_length = slen; params.flags = testcase->flags; if (testcase->remove) { params.flags |= DNS_NSEC3FLAG_REMOVE; if (testcase->nonsec) params.flags |= DNS_NSEC3FLAG_NONSEC; } else { params.flags |= DNS_NSEC3FLAG_CREATE; if (testcase->pending) params.flags |= DNS_NSEC3FLAG_INITIAL; } isc_buffer_init(&buf, bufdata, sizeof(bufdata)); dns_rdata_fromstruct(&nsec3param, dns_rdataclass_in, dns_rdatatype_nsec3param, ¶ms, &buf); dns_rdata_init(private); dns_nsec3param_toprivate(&nsec3param, private, privatetype, pbuf, DNS_NSEC3PARAM_BUFFERSIZE + 1); } /* * Individual unit tests */ ATF_TC(private_signing_totext); ATF_TC_HEAD(private_signing_totext, tc) { atf_tc_set_md_var(tc, "descr", "convert private signing records to text"); } ATF_TC_BODY(private_signing_totext, tc) { isc_result_t result; dns_rdata_t private; int i; signing_testcase_t testcases[] = { { DST_ALG_RSASHA512, 12345, 0, 0 }, { DST_ALG_RSASHA256, 54321, 1, 0 }, { DST_ALG_NSEC3RSASHA1, 22222, 0, 1 }, { DST_ALG_RSASHA1, 33333, 1, 1 } }; const char *results[] = { "Signing with key 12345/RSASHA512", "Removing signatures for key 54321/RSASHA256", "Done signing with key 22222/NSEC3RSASHA1", "Done removing signatures for key 33333/RSASHA1" }; int ncases = 4; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); for (i = 0; i < ncases; i++) { unsigned char data[5]; char output[BUFSIZ]; isc_buffer_t buf; isc_buffer_init(&buf, output, sizeof(output)); make_signing(&testcases[i], &private, data, sizeof(data)); dns_private_totext(&private, &buf); ATF_CHECK_STREQ(output, results[i]); } dns_test_end(); } ATF_TC(private_nsec3_totext); ATF_TC_HEAD(private_nsec3_totext, tc) { atf_tc_set_md_var(tc, "descr", "convert private chain records to text"); } ATF_TC_BODY(private_nsec3_totext, tc) { isc_result_t result; dns_rdata_t private; int i; nsec3_testcase_t testcases[] = { { 1, 0, 1, 0xbeef, 0, 0, 0 }, { 1, 1, 10, 0xdadd, 0, 0, 0 }, { 1, 0, 20, 0xbead, 0, 1, 0 }, { 1, 0, 30, 0xdeaf, 1, 0, 0 }, { 1, 0, 100, 0xfeedabee, 1, 0, 1 }, }; const char *results[] = { "Creating NSEC3 chain 1 0 1 BEEF", "Creating NSEC3 chain 1 1 10 DADD", "Pending NSEC3 chain 1 0 20 BEAD", "Removing NSEC3 chain 1 0 30 DEAF / creating NSEC chain", "Removing NSEC3 chain 1 0 100 FEEDABEE" }; int ncases = 5; UNUSED(tc); result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); for (i = 0; i < ncases; i++) { unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1]; char output[BUFSIZ]; isc_buffer_t buf; isc_buffer_init(&buf, output, sizeof(output)); make_nsec3(&testcases[i], &private, data); dns_private_totext(&private, &buf); ATF_CHECK_STREQ(output, results[i]); } dns_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, private_signing_totext); ATF_TP_ADD_TC(tp, private_nsec3_totext); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/dns/tests/rbt_serialize_test.c0000644000470500017500000002607412664710322022137 0ustar lamontlamont/* * Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rbt_test.c,v 1.1.14.8 2012/02/10 16:24:37 ckb Exp $ */ /* ! \file */ #include #include #include #include #include #include #include #include #include #ifdef HAVE_INTTYPES_H #include /* uintptr_t */ #endif #include #include #include #include #include "dnstest.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef MAP_FILE #define MAP_FILE 0 #endif typedef struct data_holder { int len; const char *data; } data_holder_t; typedef struct rbt_testdata { const char *name; size_t name_len; data_holder_t data; } rbt_testdata_t; #define DATA_ITEM(name) { (name), sizeof(name) - 1, { sizeof(name), (name) } } rbt_testdata_t testdata[] = { DATA_ITEM("first.com."), DATA_ITEM("one.net."), DATA_ITEM("two.com."), DATA_ITEM("three.org."), DATA_ITEM("asdf.com."), DATA_ITEM("ghjkl.com."), DATA_ITEM("1.edu."), DATA_ITEM("2.edu."), DATA_ITEM("3.edu."), DATA_ITEM("123.edu."), DATA_ITEM("1236.com."), DATA_ITEM("and_so_forth.com."), DATA_ITEM("thisisalongname.com."), DATA_ITEM("a.b."), DATA_ITEM("test.net."), DATA_ITEM("whoknows.org."), DATA_ITEM("blargh.com."), DATA_ITEM("www.joe.com."), DATA_ITEM("test.com."), DATA_ITEM("isc.org."), DATA_ITEM("uiop.mil."), DATA_ITEM("last.fm."), { NULL, 0, { 0, NULL } } }; static void delete_data(void *data, void *arg) { UNUSED(arg); UNUSED(data); } static isc_result_t write_data(FILE *file, unsigned char *datap, void *arg, isc_uint64_t *crc) { isc_result_t result; size_t ret = 0; data_holder_t *data = (data_holder_t *)datap; data_holder_t temp; off_t where; UNUSED(arg); REQUIRE(file != NULL); REQUIRE(crc != NULL); REQUIRE(data != NULL); REQUIRE((data->len == 0 && data->data == NULL) || (data->len != 0 && data->data != NULL)); result = isc_stdio_tell(file, &where); if (result != ISC_R_SUCCESS) return (result); temp = *data; temp.data = (data->len == 0 ? NULL : (char *)((uintptr_t)where + sizeof(data_holder_t))); isc_crc64_update(crc, (void *)&temp, sizeof(temp)); ret = fwrite(&temp, sizeof(data_holder_t), 1, file); if (ret != 1) return (ISC_R_FAILURE); if (data->len > 0) { isc_crc64_update(crc, (const void *)data->data, data->len); ret = fwrite(data->data, data->len, 1, file); if (ret != 1) return (ISC_R_FAILURE); } return (ISC_R_SUCCESS); } static isc_result_t fix_data(dns_rbtnode_t *p, void *base, size_t max, void *arg, isc_uint64_t *crc) { data_holder_t *data = p->data; size_t size; UNUSED(base); UNUSED(max); UNUSED(arg); REQUIRE(crc != NULL); REQUIRE(p != NULL); if (data == NULL) printf("fixing data: data NULL\n"); else printf("fixing data: len %d, data %p\n", data->len, data->data); if (data == NULL || (data->len == 0 && data->data != NULL) || (data->len != 0 && data->data == NULL)) return (ISC_R_INVALIDFILE); size = max - ((char *)p - (char *)base); if (data->len > (int) size || data->data > (const char *) max) { printf("data invalid\n"); return (ISC_R_INVALIDFILE); } isc_crc64_update(crc, (void *)data, sizeof(*data)); data->data = (data->len == 0) ? NULL : (char *)data + sizeof(data_holder_t); if (data->len > 0) isc_crc64_update(crc, (const void *)data->data, data->len); return (ISC_R_SUCCESS); } /* * Load test data into the RBT. */ static void add_test_data(isc_mem_t *mymctx, dns_rbt_t *rbt) { char buffer[1024]; isc_buffer_t b; isc_result_t result; dns_fixedname_t fname; dns_name_t *name; dns_compress_t cctx; rbt_testdata_t *testdatap = testdata; dns_compress_init(&cctx, -1, mymctx); while (testdatap->name != NULL && testdatap->data.data != NULL) { memmove(buffer, testdatap->name, testdatap->name_len); isc_buffer_init(&b, buffer, testdatap->name_len); isc_buffer_add(&b, testdatap->name_len); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) { testdatap++; continue; } if (name != NULL) { result = dns_rbt_addname(rbt, name, &testdatap->data); ATF_CHECK_STREQ(dns_result_totext(result), "success"); } testdatap++; } dns_compress_invalidate(&cctx); } /* * Walk the tree and ensure that all the test nodes are present. */ static void check_test_data(dns_rbt_t *rbt) { char buffer[1024]; char *arg; dns_fixedname_t fname; dns_fixedname_t fixed; dns_name_t *name; isc_buffer_t b; data_holder_t *data; isc_result_t result; dns_name_t *foundname; rbt_testdata_t *testdatap = testdata; dns_fixedname_init(&fixed); foundname = dns_fixedname_name(&fixed); while (testdatap->name != NULL && testdatap->data.data != NULL) { memmove(buffer, testdatap->name, testdatap->name_len + 1); arg = buffer; isc_buffer_init(&b, arg, testdatap->name_len); isc_buffer_add(&b, testdatap->name_len); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) { testdatap++; continue; } data = NULL; result = dns_rbt_findname(rbt, name, 0, foundname, (void *) &data); ATF_CHECK_STREQ(dns_result_totext(result), "success"); testdatap++; } } static void data_printer(FILE *out, void *datap) { data_holder_t *data = (data_holder_t *)datap; fprintf(out, "%d bytes, %s", data->len, data->data); } ATF_TC(serialize); ATF_TC_HEAD(serialize, tc) { atf_tc_set_md_var(tc, "descr", "Test writing an rbt to file"); } ATF_TC_BODY(serialize, tc) { dns_rbt_t *rbt = NULL; isc_result_t result; FILE *rbtfile = NULL; dns_rbt_t *rbt_deserialized = NULL; off_t offset; int fd; off_t filesize = 0; char *base; UNUSED(tc); isc_mem_debugging = ISC_MEM_DEBUGRECORD; result = dns_test_begin(NULL, ISC_TRUE); ATF_CHECK_STREQ(dns_result_totext(result), "success"); result = dns_rbt_create(mctx, delete_data, NULL, &rbt); ATF_CHECK_STREQ(dns_result_totext(result), "success"); add_test_data(mctx, rbt); dns_rbt_printtext(rbt, data_printer, stdout); /* * Serialize the tree. */ printf("serialization begins.\n"); rbtfile = fopen("./zone.bin", "w+b"); ATF_REQUIRE(rbtfile != NULL); result = dns_rbt_serialize_tree(rbtfile, rbt, write_data, NULL, &offset); ATF_REQUIRE(result == ISC_R_SUCCESS); dns_rbt_destroy(&rbt); /* * Deserialize the tree */ printf("deserialization begins.\n"); /* * Map in the whole file in one go */ fd = open("zone.bin", O_RDWR); isc_file_getsizefd(fd, &filesize); base = mmap(NULL, filesize, PROT_READ|PROT_WRITE, MAP_FILE|MAP_PRIVATE, fd, 0); ATF_REQUIRE(base != NULL && base != MAP_FAILED); close(fd); result = dns_rbt_deserialize_tree(base, filesize, 0, mctx, delete_data, NULL, fix_data, NULL, NULL, &rbt_deserialized); /* Test to make sure we have a valid tree */ ATF_REQUIRE(result == ISC_R_SUCCESS); if (rbt_deserialized == NULL) atf_tc_fail("deserialized rbt is null!"); /* Abort execution. */ check_test_data(rbt_deserialized); dns_rbt_printtext(rbt_deserialized, data_printer, stdout); dns_rbt_destroy(&rbt_deserialized); munmap(base, filesize); unlink("zone.bin"); dns_test_end(); } ATF_TC(deserialize_corrupt); ATF_TC_HEAD(deserialize_corrupt, tc) { atf_tc_set_md_var(tc, "descr", "Test reading a corrupt map file"); } ATF_TC_BODY(deserialize_corrupt, tc) { dns_rbt_t *rbt = NULL; isc_result_t result; FILE *rbtfile = NULL; off_t offset; int fd; off_t filesize = 0; char *base, *p, *q; isc_uint32_t r; int i; UNUSED(tc); isc_mem_debugging = ISC_MEM_DEBUGRECORD; result = dns_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* Set up map file */ result = dns_rbt_create(mctx, delete_data, NULL, &rbt); ATF_CHECK_EQ(result, ISC_R_SUCCESS); add_test_data(mctx, rbt); rbtfile = fopen("./zone.bin", "w+b"); ATF_REQUIRE(rbtfile != NULL); result = dns_rbt_serialize_tree(rbtfile, rbt, write_data, NULL, &offset); ATF_REQUIRE(result == ISC_R_SUCCESS); dns_rbt_destroy(&rbt); /* Read back with random fuzzing */ for (i = 0; i < 256; i++) { dns_rbt_t *rbt_deserialized = NULL; fd = open("zone.bin", O_RDWR); isc_file_getsizefd(fd, &filesize); base = mmap(NULL, filesize, PROT_READ|PROT_WRITE, MAP_FILE|MAP_PRIVATE, fd, 0); ATF_REQUIRE(base != NULL && base != MAP_FAILED); close(fd); /* Randomly fuzz a portion of the memory */ isc_random_get(&r); p = base + (r % filesize); q = base + filesize; isc_random_get(&r); q -= (r % (q - p)); while (p++ < q) { isc_random_get(&r); *p = r & 0xff; } result = dns_rbt_deserialize_tree(base, filesize, 0, mctx, delete_data, NULL, fix_data, NULL, NULL, &rbt_deserialized); printf("%d: %s\n", i, isc_result_totext(result)); /* Test to make sure we have a valid tree */ ATF_REQUIRE(result == ISC_R_SUCCESS || result == ISC_R_INVALIDFILE); if (result != ISC_R_SUCCESS) ATF_REQUIRE(rbt_deserialized == NULL); if (rbt_deserialized != NULL) dns_rbt_destroy(&rbt_deserialized); munmap(base, filesize); } unlink("zone.bin"); dns_test_end(); } ATF_TC(serialize_align); ATF_TC_HEAD(serialize_align, tc) { atf_tc_set_md_var(tc, "descr", "Test the dns_rbt_serialize_align() function."); } ATF_TC_BODY(serialize_align, tc) { UNUSED(tc); ATF_CHECK(dns_rbt_serialize_align(0) == 0); ATF_CHECK(dns_rbt_serialize_align(1) == 8); ATF_CHECK(dns_rbt_serialize_align(2) == 8); ATF_CHECK(dns_rbt_serialize_align(3) == 8); ATF_CHECK(dns_rbt_serialize_align(4) == 8); ATF_CHECK(dns_rbt_serialize_align(5) == 8); ATF_CHECK(dns_rbt_serialize_align(6) == 8); ATF_CHECK(dns_rbt_serialize_align(7) == 8); ATF_CHECK(dns_rbt_serialize_align(8) == 8); ATF_CHECK(dns_rbt_serialize_align(9) == 16); ATF_CHECK(dns_rbt_serialize_align(0xff) == 0x100); ATF_CHECK(dns_rbt_serialize_align(0x301) == 0x308); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, serialize); ATF_TP_ADD_TC(tp, deserialize_corrupt); ATF_TP_ADD_TC(tp, serialize_align); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/dns/tests/rdata_test.c0000644000470500017500000002171412664710322020370 0ustar lamontlamont/* * Copyright (C) 2012, 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include "dnstest.h" /* * Individual unit tests */ /* Successful load test */ ATF_TC(hip); ATF_TC_HEAD(hip, tc) { atf_tc_set_md_var(tc, "descr", "that a oversized HIP record will " "be rejected"); } ATF_TC_BODY(hip, tc) { unsigned char hipwire[DNS_RDATA_MAXLENGTH] = { 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x41, 0x42, 0x43, 0x44, 0x00 }; unsigned char buf[1024*1024]; isc_buffer_t source, target; dns_rdata_t rdata; dns_decompress_t dctx; isc_result_t result; size_t i; UNUSED(tc); /* * Fill the rest of input buffer with compression pointers. */ for (i = 12; i < sizeof(hipwire) - 2; i += 2) { hipwire[i] = 0xc0; hipwire[i+1] = 0x06; } isc_buffer_init(&source, hipwire, sizeof(hipwire)); isc_buffer_add(&source, sizeof(hipwire)); isc_buffer_setactive(&source, i); isc_buffer_init(&target, buf, sizeof(buf)); dns_rdata_init(&rdata); dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY); result = dns_rdata_fromwire(&rdata, dns_rdataclass_in, dns_rdatatype_hip, &source, &dctx, 0, &target); dns_decompress_invalidate(&dctx); ATF_REQUIRE_EQ(result, DNS_R_FORMERR); } ATF_TC(edns_client_subnet); ATF_TC_HEAD(edns_client_subnet, tc) { atf_tc_set_md_var(tc, "descr", "check EDNS client subnet option parsing"); } ATF_TC_BODY(edns_client_subnet, tc) { struct { unsigned char data[64]; size_t len; isc_boolean_t ok; } test_data[] = { { /* option code with no content */ { 0x00, 0x08, 0x0, 0x00 }, 4, ISC_FALSE }, { /* Option code family 0, source 0, scope 0 */ { 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00 }, 8, ISC_TRUE }, { /* Option code family 1 (ipv4), source 0, scope 0 */ { 0x00, 0x08, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00 }, 8, ISC_TRUE }, { /* Option code family 2 (ipv6) , source 0, scope 0 */ { 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00 }, 8, ISC_TRUE }, { /* extra octet */ { 0x00, 0x08, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 }, 9, ISC_FALSE }, { /* source too long for IPv4 */ { 0x00, 0x08, 0x00, 8, 0x00, 0x01, 33, 0x00, 0x00, 0x00, 0x00, 0x00 }, 12, ISC_FALSE }, { /* source too long for IPv6 */ { 0x00, 0x08, 0x00, 20, 0x00, 0x02, 129, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 24, ISC_FALSE }, { /* scope too long for IPv4 */ { 0x00, 0x08, 0x00, 8, 0x00, 0x01, 0x00, 33, 0x00, 0x00, 0x00, 0x00 }, 12, ISC_FALSE }, { /* scope too long for IPv6 */ { 0x00, 0x08, 0x00, 20, 0x00, 0x02, 0x00, 129, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 24, ISC_FALSE }, { /* length too short for source generic */ { 0x00, 0x08, 0x00, 5, 0x00, 0x00, 17, 0x00, 0x00, 0x00, }, 19, ISC_FALSE }, { /* length too short for source ipv4 */ { 0x00, 0x08, 0x00, 7, 0x00, 0x01, 32, 0x00, 0x00, 0x00, 0x00, 0x00 }, 11, ISC_FALSE }, { /* length too short for source ipv6 */ { 0x00, 0x08, 0x00, 19, 0x00, 0x02, 128, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 23, ISC_FALSE }, { /* sentinal */ { 0x00 }, 0, ISC_FALSE } }; unsigned char buf[1024*1024]; isc_buffer_t source, target; dns_rdata_t rdata; dns_decompress_t dctx; isc_result_t result; size_t i; UNUSED(tc); for (i = 0; test_data[i].len != 0; i++) { isc_buffer_init(&source, test_data[i].data, test_data[i].len); isc_buffer_add(&source, test_data[i].len); isc_buffer_setactive(&source, test_data[i].len); isc_buffer_init(&target, buf, sizeof(buf)); dns_rdata_init(&rdata); dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY); result = dns_rdata_fromwire(&rdata, dns_rdataclass_in, dns_rdatatype_opt, &source, &dctx, 0, &target); dns_decompress_invalidate(&dctx); if (test_data[i].ok) ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); else ATF_REQUIRE(result != ISC_R_SUCCESS); } } ATF_TC(wks); ATF_TC_HEAD(wks, tc) { atf_tc_set_md_var(tc, "descr", "wks to/from struct"); } ATF_TC_BODY(wks, tc) { struct { unsigned char data[64]; size_t len; isc_boolean_t ok; } test_data[] = { { /* too short */ { 0x00, 0x08, 0x0, 0x00 }, 4, ISC_FALSE }, { /* minimal TCP */ { 0x00, 0x08, 0x0, 0x00, 6 }, 5, ISC_TRUE }, { /* minimal UDP */ { 0x00, 0x08, 0x0, 0x00, 17 }, 5, ISC_TRUE }, { /* minimal other */ { 0x00, 0x08, 0x0, 0x00, 1 }, 5, ISC_TRUE }, { /* sentinal */ { 0x00 }, 0, ISC_FALSE } }; unsigned char buf1[1024]; unsigned char buf2[1024]; isc_buffer_t source, target1, target2; dns_rdata_t rdata; dns_decompress_t dctx; isc_result_t result; size_t i; dns_rdata_in_wks_t wks; UNUSED(tc); for (i = 0; test_data[i].len != 0; i++) { isc_buffer_init(&source, test_data[i].data, test_data[i].len); isc_buffer_add(&source, test_data[i].len); isc_buffer_setactive(&source, test_data[i].len); isc_buffer_init(&target1, buf1, sizeof(buf1)); dns_rdata_init(&rdata); dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY); result = dns_rdata_fromwire(&rdata, dns_rdataclass_in, dns_rdatatype_wks, &source, &dctx, 0, &target1); dns_decompress_invalidate(&dctx); if (test_data[i].ok) ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); else ATF_REQUIRE(result != ISC_R_SUCCESS); if (result != ISC_R_SUCCESS) continue; result = dns_rdata_tostruct(&rdata, &wks, NULL); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); isc_buffer_init(&target2, buf2, sizeof(buf2)); dns_rdata_reset(&rdata); result = dns_rdata_fromstruct(&rdata, dns_rdataclass_in, dns_rdatatype_wks, &wks, &target2); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(isc_buffer_usedlength(&target2), test_data[i].len); ATF_REQUIRE_EQ(memcmp(buf2, test_data[i].data, test_data[i].len), 0); } } ATF_TC(isdn); ATF_TC_HEAD(isdn, tc) { atf_tc_set_md_var(tc, "descr", "isdn to/from struct"); } ATF_TC_BODY(isdn, tc) { struct { unsigned char data[64]; size_t len; isc_boolean_t ok; } test_data[] = { { /* "" */ { 0x00 }, 1, ISC_TRUE }, { /* "\001" */ { 0x1, 0x01 }, 2, ISC_TRUE }, { /* "\001" "" */ { 0x1, 0x01, 0x00 }, 3, ISC_TRUE }, { /* "\000" "\001" */ { 0x1, 0x01, 0x01, 0x01 }, 4, ISC_TRUE }, { /* sentinal */ { 0x00 }, 0, ISC_FALSE } }; unsigned char buf1[1024]; unsigned char buf2[1024]; isc_buffer_t source, target1, target2; dns_rdata_t rdata; dns_decompress_t dctx; isc_result_t result; size_t i; dns_rdata_isdn_t isdn; UNUSED(tc); for (i = 0; test_data[i].len != 0; i++) { isc_buffer_init(&source, test_data[i].data, test_data[i].len); isc_buffer_add(&source, test_data[i].len); isc_buffer_setactive(&source, test_data[i].len); isc_buffer_init(&target1, buf1, sizeof(buf1)); dns_rdata_init(&rdata); dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY); result = dns_rdata_fromwire(&rdata, dns_rdataclass_in, dns_rdatatype_isdn, &source, &dctx, 0, &target1); dns_decompress_invalidate(&dctx); if (test_data[i].ok) ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); else ATF_REQUIRE(result != ISC_R_SUCCESS); if (result != ISC_R_SUCCESS) continue; result = dns_rdata_tostruct(&rdata, &isdn, NULL); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); isc_buffer_init(&target2, buf2, sizeof(buf2)); dns_rdata_reset(&rdata); result = dns_rdata_fromstruct(&rdata, dns_rdataclass_in, dns_rdatatype_isdn, &isdn, &target2); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(isc_buffer_usedlength(&target2), test_data[i].len); ATF_REQUIRE_EQ(memcmp(buf2, test_data[i].data, test_data[i].len), 0); } } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, hip); ATF_TP_ADD_TC(tp, edns_client_subnet); ATF_TP_ADD_TC(tp, wks); ATF_TP_ADD_TC(tp, isdn); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/dns/tests/dbdiff_test.c0000644000470500017500000001047512664710322020515 0ustar lamontlamont/* * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include "dnstest.h" /* * Helper functions */ #define BUFLEN 255 #define BIGBUFLEN (64 * 1024) #define TEST_ORIGIN "test" static void test_create(const atf_tc_t *tc, dns_db_t **old, dns_db_t **new) { isc_result_t result; result = dns_test_loaddb(old, dns_dbtype_zone, TEST_ORIGIN, atf_tc_get_md_var(tc, "X-old")); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_loaddb(new, dns_dbtype_zone, TEST_ORIGIN, atf_tc_get_md_var(tc, "X-new")); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); } /* * Individual unit tests */ ATF_TC(diffx_same); ATF_TC_HEAD(diffx_same, tc) { atf_tc_set_md_var(tc, "descr", "dns_db_diffx of identical content"); atf_tc_set_md_var(tc, "X-old", "testdata/diff/zone1.data"); atf_tc_set_md_var(tc, "X-new", "testdata/diff/zone1.data"); } ATF_TC_BODY(diffx_same, tc) { dns_db_t *new = NULL, *old = NULL; isc_result_t result; dns_diff_t diff; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); test_create(tc, &old, &new); dns_diff_init(mctx, &diff); result = dns_db_diffx(&diff, new, NULL, old, NULL, NULL); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(ISC_LIST_EMPTY(diff.tuples), ISC_TRUE); dns_diff_clear(&diff); dns_db_detach(&new); dns_db_detach(&old); dns_test_end(); } ATF_TC(diffx_add); ATF_TC_HEAD(diffx_add, tc) { atf_tc_set_md_var(tc, "descr", "dns_db_diffx of zone with record added"); atf_tc_set_md_var(tc, "X-old", "testdata/diff/zone1.data"); atf_tc_set_md_var(tc, "X-new", "testdata/diff/zone2.data"); } ATF_TC_BODY(diffx_add, tc) { dns_db_t *new = NULL, *old = NULL; dns_difftuple_t *tuple; isc_result_t result; dns_diff_t diff; int count = 0; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); test_create(tc, &old, &new); dns_diff_init(mctx, &diff); result = dns_db_diffx(&diff, new, NULL, old, NULL, NULL); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(ISC_LIST_EMPTY(diff.tuples), ISC_FALSE); for (tuple = ISC_LIST_HEAD(diff.tuples); tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link)) { ATF_REQUIRE_EQ(tuple->op, DNS_DIFFOP_ADD); count++; } ATF_REQUIRE_EQ(count, 1); dns_diff_clear(&diff); dns_db_detach(&new); dns_db_detach(&old); dns_test_end(); } ATF_TC(diffx_remove); ATF_TC_HEAD(diffx_remove, tc) { atf_tc_set_md_var(tc, "descr", "dns_db_diffx of zone with record removed"); atf_tc_set_md_var(tc, "X-old", "testdata/diff/zone1.data"); atf_tc_set_md_var(tc, "X-new", "testdata/diff/zone3.data"); } ATF_TC_BODY(diffx_remove, tc) { dns_db_t *new = NULL, *old = NULL; dns_difftuple_t *tuple; isc_result_t result; dns_diff_t diff; int count = 0; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); test_create(tc, &old, &new); dns_diff_init(mctx, &diff); result = dns_db_diffx(&diff, new, NULL, old, NULL, NULL); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(ISC_LIST_EMPTY(diff.tuples), ISC_FALSE); for (tuple = ISC_LIST_HEAD(diff.tuples); tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link)) { ATF_REQUIRE_EQ(tuple->op, DNS_DIFFOP_DEL); count++; } ATF_REQUIRE_EQ(count, 1); dns_diff_clear(&diff); dns_db_detach(&new); dns_db_detach(&old); dns_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, diffx_same); ATF_TP_ADD_TC(tp, diffx_add); ATF_TP_ADD_TC(tp, diffx_remove); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/dns/tests/dh_test.c0000644000470500017500000000465512664710322017675 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* ! \file */ #include #include #include #include #include #include #include #include "../dst_internal.h" #include "dnstest.h" #ifdef OPENSSL ATF_TC(isc_dh_computesecret); ATF_TC_HEAD(isc_dh_computesecret, tc) { atf_tc_set_md_var(tc, "descr", "OpenSSL DH_compute_key() failure"); } ATF_TC_BODY(isc_dh_computesecret, tc) { dst_key_t *key = NULL; isc_buffer_t buf; unsigned char array[1024]; isc_result_t ret; dns_fixedname_t fname; dns_name_t *name; UNUSED(tc); ret = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(ret, ISC_R_SUCCESS); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); isc_buffer_constinit(&buf, "dh.", 3); isc_buffer_add(&buf, 3); ret = dns_name_fromtext(name, &buf, NULL, 0, NULL); ATF_REQUIRE_EQ(ret, ISC_R_SUCCESS); ret = dst_key_fromfile(name, 18602, DST_ALG_DH, DST_TYPE_PUBLIC | DST_TYPE_KEY, "./", mctx, &key); ATF_REQUIRE_EQ(ret, ISC_R_SUCCESS); isc_buffer_init(&buf, array, sizeof(array)); ret = dst_key_computesecret(key, key, &buf); ATF_REQUIRE_EQ(ret, DST_R_NOTPRIVATEKEY); ret = key->func->computesecret(key, key, &buf); ATF_REQUIRE_EQ(ret, DST_R_COMPUTESECRETFAILURE); dst_key_free(&key); dns_test_end(); } #else ATF_TC(untested); ATF_TC_HEAD(untested, tc) { atf_tc_set_md_var(tc, "descr", "skipping OpenSSL DH test"); } ATF_TC_BODY(untested, tc) { UNUSED(tc); atf_tc_skip("OpenSSL DH not compiled in"); } #endif /* * Main */ ATF_TP_ADD_TCS(tp) { #ifdef OPENSSL ATF_TP_ADD_TC(tp, isc_dh_computesecret); #else ATF_TP_ADD_TC(tp, untested); #endif return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/dns/ssu.c0000644000470500017500000004016712664710322015711 0ustar lamontlamont/* * Copyright (C) 2004-2008, 2010, 2011, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ /* * $Id: ssu.c,v 1.38 2011/01/06 23:47:00 tbox Exp $ * Principal Author: Brian Wellington */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define SSUTABLEMAGIC ISC_MAGIC('S', 'S', 'U', 'T') #define VALID_SSUTABLE(table) ISC_MAGIC_VALID(table, SSUTABLEMAGIC) #define SSURULEMAGIC ISC_MAGIC('S', 'S', 'U', 'R') #define VALID_SSURULE(table) ISC_MAGIC_VALID(table, SSURULEMAGIC) struct dns_ssurule { unsigned int magic; isc_boolean_t grant; /*%< is this a grant or a deny? */ unsigned int matchtype; /*%< which type of pattern match? */ dns_name_t *identity; /*%< the identity to match */ dns_name_t *name; /*%< the name being updated */ unsigned int ntypes; /*%< number of data types covered */ dns_rdatatype_t *types; /*%< the data types. Can include ANY, */ /*%< defaults to all but SIG,SOA,NS if NULL */ ISC_LINK(dns_ssurule_t) link; }; struct dns_ssutable { unsigned int magic; isc_mem_t *mctx; unsigned int references; isc_mutex_t lock; dns_dlzdb_t *dlzdatabase; ISC_LIST(dns_ssurule_t) rules; }; isc_result_t dns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **tablep) { isc_result_t result; dns_ssutable_t *table; REQUIRE(tablep != NULL && *tablep == NULL); REQUIRE(mctx != NULL); table = isc_mem_get(mctx, sizeof(dns_ssutable_t)); if (table == NULL) return (ISC_R_NOMEMORY); result = isc_mutex_init(&table->lock); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, table, sizeof(dns_ssutable_t)); return (result); } table->references = 1; table->mctx = NULL; isc_mem_attach(mctx, &table->mctx); ISC_LIST_INIT(table->rules); table->magic = SSUTABLEMAGIC; *tablep = table; return (ISC_R_SUCCESS); } static inline void destroy(dns_ssutable_t *table) { isc_mem_t *mctx; REQUIRE(VALID_SSUTABLE(table)); mctx = table->mctx; while (!ISC_LIST_EMPTY(table->rules)) { dns_ssurule_t *rule = ISC_LIST_HEAD(table->rules); if (rule->identity != NULL) { dns_name_free(rule->identity, mctx); isc_mem_put(mctx, rule->identity, sizeof(dns_name_t)); } if (rule->name != NULL) { dns_name_free(rule->name, mctx); isc_mem_put(mctx, rule->name, sizeof(dns_name_t)); } if (rule->types != NULL) isc_mem_put(mctx, rule->types, rule->ntypes * sizeof(dns_rdatatype_t)); ISC_LIST_UNLINK(table->rules, rule, link); rule->magic = 0; isc_mem_put(mctx, rule, sizeof(dns_ssurule_t)); } DESTROYLOCK(&table->lock); table->magic = 0; isc_mem_putanddetach(&table->mctx, table, sizeof(dns_ssutable_t)); } void dns_ssutable_attach(dns_ssutable_t *source, dns_ssutable_t **targetp) { REQUIRE(VALID_SSUTABLE(source)); REQUIRE(targetp != NULL && *targetp == NULL); LOCK(&source->lock); INSIST(source->references > 0); source->references++; INSIST(source->references != 0); UNLOCK(&source->lock); *targetp = source; } void dns_ssutable_detach(dns_ssutable_t **tablep) { dns_ssutable_t *table; isc_boolean_t done = ISC_FALSE; REQUIRE(tablep != NULL); table = *tablep; REQUIRE(VALID_SSUTABLE(table)); LOCK(&table->lock); INSIST(table->references > 0); if (--table->references == 0) done = ISC_TRUE; UNLOCK(&table->lock); *tablep = NULL; if (done) destroy(table); } isc_result_t dns_ssutable_addrule(dns_ssutable_t *table, isc_boolean_t grant, dns_name_t *identity, unsigned int matchtype, dns_name_t *name, unsigned int ntypes, dns_rdatatype_t *types) { dns_ssurule_t *rule; isc_mem_t *mctx; isc_result_t result; REQUIRE(VALID_SSUTABLE(table)); REQUIRE(dns_name_isabsolute(identity)); REQUIRE(dns_name_isabsolute(name)); REQUIRE(matchtype <= DNS_SSUMATCHTYPE_MAX); if (matchtype == DNS_SSUMATCHTYPE_WILDCARD) REQUIRE(dns_name_iswildcard(name)); if (ntypes > 0) REQUIRE(types != NULL); mctx = table->mctx; rule = isc_mem_get(mctx, sizeof(dns_ssurule_t)); if (rule == NULL) return (ISC_R_NOMEMORY); rule->identity = NULL; rule->name = NULL; rule->types = NULL; rule->grant = grant; rule->identity = isc_mem_get(mctx, sizeof(dns_name_t)); if (rule->identity == NULL) { result = ISC_R_NOMEMORY; goto failure; } dns_name_init(rule->identity, NULL); result = dns_name_dup(identity, mctx, rule->identity); if (result != ISC_R_SUCCESS) goto failure; rule->name = isc_mem_get(mctx, sizeof(dns_name_t)); if (rule->name == NULL) { result = ISC_R_NOMEMORY; goto failure; } dns_name_init(rule->name, NULL); result = dns_name_dup(name, mctx, rule->name); if (result != ISC_R_SUCCESS) goto failure; rule->matchtype = matchtype; rule->ntypes = ntypes; if (ntypes > 0) { rule->types = isc_mem_get(mctx, ntypes * sizeof(dns_rdatatype_t)); if (rule->types == NULL) { result = ISC_R_NOMEMORY; goto failure; } memmove(rule->types, types, ntypes * sizeof(dns_rdatatype_t)); } else rule->types = NULL; rule->magic = SSURULEMAGIC; ISC_LIST_INITANDAPPEND(table->rules, rule, link); return (ISC_R_SUCCESS); failure: if (rule->identity != NULL) { if (dns_name_dynamic(rule->identity)) dns_name_free(rule->identity, mctx); isc_mem_put(mctx, rule->identity, sizeof(dns_name_t)); } if (rule->name != NULL) { if (dns_name_dynamic(rule->name)) dns_name_free(rule->name, mctx); isc_mem_put(mctx, rule->name, sizeof(dns_name_t)); } if (rule->types != NULL) isc_mem_put(mctx, rule->types, ntypes * sizeof(dns_rdatatype_t)); isc_mem_put(mctx, rule, sizeof(dns_ssurule_t)); return (result); } static inline isc_boolean_t isusertype(dns_rdatatype_t type) { return (ISC_TF(type != dns_rdatatype_ns && type != dns_rdatatype_soa && type != dns_rdatatype_rrsig)); } static void reverse_from_address(dns_name_t *tcpself, isc_netaddr_t *tcpaddr) { char buf[16 * 4 + sizeof("IP6.ARPA.")]; isc_result_t result; unsigned char *ap; isc_buffer_t b; unsigned long l; switch (tcpaddr->family) { case AF_INET: l = ntohl(tcpaddr->type.in.s_addr); result = isc_string_printf(buf, sizeof(buf), "%lu.%lu.%lu.%lu.IN-ADDR.ARPA.", (l >> 0) & 0xff, (l >> 8) & 0xff, (l >> 16) & 0xff, (l >> 24) & 0xff); RUNTIME_CHECK(result == ISC_R_SUCCESS); break; case AF_INET6: ap = tcpaddr->type.in6.s6_addr; result = isc_string_printf(buf, sizeof(buf), "%x.%x.%x.%x.%x.%x.%x.%x." "%x.%x.%x.%x.%x.%x.%x.%x." "%x.%x.%x.%x.%x.%x.%x.%x." "%x.%x.%x.%x.%x.%x.%x.%x." "IP6.ARPA.", ap[15] & 0x0f, (ap[15] >> 4) & 0x0f, ap[14] & 0x0f, (ap[14] >> 4) & 0x0f, ap[13] & 0x0f, (ap[13] >> 4) & 0x0f, ap[12] & 0x0f, (ap[12] >> 4) & 0x0f, ap[11] & 0x0f, (ap[11] >> 4) & 0x0f, ap[10] & 0x0f, (ap[10] >> 4) & 0x0f, ap[9] & 0x0f, (ap[9] >> 4) & 0x0f, ap[8] & 0x0f, (ap[8] >> 4) & 0x0f, ap[7] & 0x0f, (ap[7] >> 4) & 0x0f, ap[6] & 0x0f, (ap[6] >> 4) & 0x0f, ap[5] & 0x0f, (ap[5] >> 4) & 0x0f, ap[4] & 0x0f, (ap[4] >> 4) & 0x0f, ap[3] & 0x0f, (ap[3] >> 4) & 0x0f, ap[2] & 0x0f, (ap[2] >> 4) & 0x0f, ap[1] & 0x0f, (ap[1] >> 4) & 0x0f, ap[0] & 0x0f, (ap[0] >> 4) & 0x0f); RUNTIME_CHECK(result == ISC_R_SUCCESS); break; default: INSIST(0); } isc_buffer_init(&b, buf, strlen(buf)); isc_buffer_add(&b, strlen(buf)); result = dns_name_fromtext(tcpself, &b, dns_rootname, 0, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); } static void stf_from_address(dns_name_t *stfself, isc_netaddr_t *tcpaddr) { char buf[sizeof("X.X.X.X.Y.Y.Y.Y.2.0.0.2.IP6.ARPA.")]; isc_result_t result; unsigned char *ap; isc_buffer_t b; unsigned long l; switch(tcpaddr->family) { case AF_INET: l = ntohl(tcpaddr->type.in.s_addr); result = isc_string_printf(buf, sizeof(buf), "%lx.%lx.%lx.%lx.%lx.%lx.%lx.%lx" "2.0.0.2.IP6.ARPA.", l & 0xf, (l >> 4) & 0xf, (l >> 8) & 0xf, (l >> 12) & 0xf, (l >> 16) & 0xf, (l >> 20) & 0xf, (l >> 24) & 0xf, (l >> 28) & 0xf); RUNTIME_CHECK(result == ISC_R_SUCCESS); break; case AF_INET6: ap = tcpaddr->type.in6.s6_addr; result = isc_string_printf(buf, sizeof(buf), "%x.%x.%x.%x.%x.%x.%x.%x." "%x.%x.%x.%x.IP6.ARPA.", ap[5] & 0x0f, (ap[5] >> 4) & 0x0f, ap[4] & 0x0f, (ap[4] >> 4) & 0x0f, ap[3] & 0x0f, (ap[3] >> 4) & 0x0f, ap[2] & 0x0f, (ap[2] >> 4) & 0x0f, ap[1] & 0x0f, (ap[1] >> 4) & 0x0f, ap[0] & 0x0f, (ap[0] >> 4) & 0x0f); RUNTIME_CHECK(result == ISC_R_SUCCESS); break; default: INSIST(0); } isc_buffer_init(&b, buf, strlen(buf)); isc_buffer_add(&b, strlen(buf)); result = dns_name_fromtext(stfself, &b, dns_rootname, 0, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); } isc_boolean_t dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer, dns_name_t *name, isc_netaddr_t *tcpaddr, dns_rdatatype_t type, const dst_key_t *key) { dns_ssurule_t *rule; unsigned int i; dns_fixedname_t fixed; dns_name_t *wildcard; dns_name_t *tcpself; dns_name_t *stfself; isc_result_t result; REQUIRE(VALID_SSUTABLE(table)); REQUIRE(signer == NULL || dns_name_isabsolute(signer)); REQUIRE(dns_name_isabsolute(name)); if (signer == NULL && tcpaddr == NULL) return (ISC_FALSE); for (rule = ISC_LIST_HEAD(table->rules); rule != NULL; rule = ISC_LIST_NEXT(rule, link)) { switch (rule->matchtype) { case DNS_SSUMATCHTYPE_NAME: case DNS_SSUMATCHTYPE_SUBDOMAIN: case DNS_SSUMATCHTYPE_WILDCARD: case DNS_SSUMATCHTYPE_SELF: case DNS_SSUMATCHTYPE_SELFSUB: case DNS_SSUMATCHTYPE_SELFWILD: if (signer == NULL) continue; if (dns_name_iswildcard(rule->identity)) { if (!dns_name_matcheswildcard(signer, rule->identity)) continue; } else { if (!dns_name_equal(signer, rule->identity)) continue; } break; case DNS_SSUMATCHTYPE_SELFKRB5: case DNS_SSUMATCHTYPE_SELFMS: case DNS_SSUMATCHTYPE_SUBDOMAINKRB5: case DNS_SSUMATCHTYPE_SUBDOMAINMS: if (signer == NULL) continue; break; case DNS_SSUMATCHTYPE_TCPSELF: case DNS_SSUMATCHTYPE_6TO4SELF: if (tcpaddr == NULL) continue; break; } switch (rule->matchtype) { case DNS_SSUMATCHTYPE_NAME: if (!dns_name_equal(name, rule->name)) continue; break; case DNS_SSUMATCHTYPE_SUBDOMAIN: if (!dns_name_issubdomain(name, rule->name)) continue; break; case DNS_SSUMATCHTYPE_WILDCARD: if (!dns_name_matcheswildcard(name, rule->name)) continue; break; case DNS_SSUMATCHTYPE_SELF: if (!dns_name_equal(signer, name)) continue; break; case DNS_SSUMATCHTYPE_SELFSUB: if (!dns_name_issubdomain(name, signer)) continue; break; case DNS_SSUMATCHTYPE_SELFWILD: dns_fixedname_init(&fixed); wildcard = dns_fixedname_name(&fixed); result = dns_name_concatenate(dns_wildcardname, signer, wildcard, NULL); if (result != ISC_R_SUCCESS) continue; if (!dns_name_matcheswildcard(name, wildcard)) continue; break; case DNS_SSUMATCHTYPE_SELFKRB5: if (!dst_gssapi_identitymatchesrealmkrb5(signer, name, rule->identity)) continue; break; case DNS_SSUMATCHTYPE_SELFMS: if (!dst_gssapi_identitymatchesrealmms(signer, name, rule->identity)) continue; break; case DNS_SSUMATCHTYPE_SUBDOMAINKRB5: if (!dns_name_issubdomain(name, rule->name)) continue; if (!dst_gssapi_identitymatchesrealmkrb5(signer, NULL, rule->identity)) continue; break; case DNS_SSUMATCHTYPE_SUBDOMAINMS: if (!dns_name_issubdomain(name, rule->name)) continue; if (!dst_gssapi_identitymatchesrealmms(signer, NULL, rule->identity)) continue; break; case DNS_SSUMATCHTYPE_TCPSELF: dns_fixedname_init(&fixed); tcpself = dns_fixedname_name(&fixed); reverse_from_address(tcpself, tcpaddr); if (dns_name_iswildcard(rule->identity)) { if (!dns_name_matcheswildcard(tcpself, rule->identity)) continue; } else { if (!dns_name_equal(tcpself, rule->identity)) continue; } if (!dns_name_equal(tcpself, name)) continue; break; case DNS_SSUMATCHTYPE_6TO4SELF: dns_fixedname_init(&fixed); stfself = dns_fixedname_name(&fixed); stf_from_address(stfself, tcpaddr); if (dns_name_iswildcard(rule->identity)) { if (!dns_name_matcheswildcard(stfself, rule->identity)) continue; } else { if (!dns_name_equal(stfself, rule->identity)) continue; } if (!dns_name_equal(stfself, name)) continue; break; case DNS_SSUMATCHTYPE_EXTERNAL: if (!dns_ssu_external_match(rule->identity, signer, name, tcpaddr, type, key, table->mctx)) continue; break; case DNS_SSUMATCHTYPE_DLZ: if (!dns_dlz_ssumatch(table->dlzdatabase, signer, name, tcpaddr, type, key)) continue; break; } if (rule->ntypes == 0) { /* * If this is a DLZ rule, then the DLZ ssu * checks will have already checked * the type. */ if (rule->matchtype != DNS_SSUMATCHTYPE_DLZ && !isusertype(type)) continue; } else { for (i = 0; i < rule->ntypes; i++) { if (rule->types[i] == dns_rdatatype_any || rule->types[i] == type) break; } if (i == rule->ntypes) continue; } return (rule->grant); } return (ISC_FALSE); } isc_boolean_t dns_ssurule_isgrant(const dns_ssurule_t *rule) { REQUIRE(VALID_SSURULE(rule)); return (rule->grant); } dns_name_t * dns_ssurule_identity(const dns_ssurule_t *rule) { REQUIRE(VALID_SSURULE(rule)); return (rule->identity); } unsigned int dns_ssurule_matchtype(const dns_ssurule_t *rule) { REQUIRE(VALID_SSURULE(rule)); return (rule->matchtype); } dns_name_t * dns_ssurule_name(const dns_ssurule_t *rule) { REQUIRE(VALID_SSURULE(rule)); return (rule->name); } unsigned int dns_ssurule_types(const dns_ssurule_t *rule, dns_rdatatype_t **types) { REQUIRE(VALID_SSURULE(rule)); REQUIRE(types != NULL && *types != NULL); *types = rule->types; return (rule->ntypes); } isc_result_t dns_ssutable_firstrule(const dns_ssutable_t *table, dns_ssurule_t **rule) { REQUIRE(VALID_SSUTABLE(table)); REQUIRE(rule != NULL && *rule == NULL); *rule = ISC_LIST_HEAD(table->rules); return (*rule != NULL ? ISC_R_SUCCESS : ISC_R_NOMORE); } isc_result_t dns_ssutable_nextrule(dns_ssurule_t *rule, dns_ssurule_t **nextrule) { REQUIRE(VALID_SSURULE(rule)); REQUIRE(nextrule != NULL && *nextrule == NULL); *nextrule = ISC_LIST_NEXT(rule, link); return (*nextrule != NULL ? ISC_R_SUCCESS : ISC_R_NOMORE); } /* * Create a specialised SSU table that points at an external DLZ database */ isc_result_t dns_ssutable_createdlz(isc_mem_t *mctx, dns_ssutable_t **tablep, dns_dlzdb_t *dlzdatabase) { isc_result_t result; dns_ssurule_t *rule; dns_ssutable_t *table = NULL; REQUIRE(tablep != NULL && *tablep == NULL); result = dns_ssutable_create(mctx, &table); if (result != ISC_R_SUCCESS) return (result); table->dlzdatabase = dlzdatabase; rule = isc_mem_get(table->mctx, sizeof(dns_ssurule_t)); if (rule == NULL) { dns_ssutable_detach(&table); return (ISC_R_NOMEMORY); } rule->identity = NULL; rule->name = NULL; rule->types = NULL; rule->grant = ISC_TRUE; rule->matchtype = DNS_SSUMATCHTYPE_DLZ; rule->ntypes = 0; rule->types = NULL; rule->magic = SSURULEMAGIC; ISC_LIST_INITANDAPPEND(table->rules, rule, link); *tablep = table; return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/dns/pkcs11ecdsa_link.c0000644000470500017500000010107112664710322020206 0ustar lamontlamont/* * Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #if defined(PKCS11CRYPTO) && defined(HAVE_PKCS11_ECDSA) #include #include #include #include #include #include #include #include "dst_internal.h" #include "dst_parse.h" #include "dst_pkcs11.h" #include #include #define WANT_ECC_CURVES #include #include /* * FIPS 186-3 ECDSA keys: * mechanisms: * CKM_ECDSA, * CKM_EC_KEY_PAIR_GEN * domain parameters: * CKA_EC_PARAMS (choice with OID namedCurve) * public keys: * object class CKO_PUBLIC_KEY * key type CKK_EC * attribute CKA_EC_PARAMS (choice with OID namedCurve) * attribute CKA_EC_POINT (point Q) * private keys: * object class CKO_PRIVATE_KEY * key type CKK_EC * attribute CKA_EC_PARAMS (choice with OID namedCurve) * attribute CKA_VALUE (big int d) * point format: 0x04 (octet-string) <2*size+1> 0x4 (uncompressed) */ #define TAG_OCTECT_STRING 0x04 #define UNCOMPRESSED 0x04 #define DST_RET(a) {ret = a; goto err;} static CK_BBOOL truevalue = TRUE; static CK_BBOOL falsevalue = FALSE; static isc_result_t pkcs11ecdsa_todns(const dst_key_t *key, isc_buffer_t *data); static void pkcs11ecdsa_destroy(dst_key_t *key); static isc_result_t pkcs11ecdsa_fetch(dst_key_t *key, const char *engine, const char *label, dst_key_t *pub); static isc_result_t pkcs11ecdsa_createctx(dst_key_t *key, dst_context_t *dctx) { CK_RV rv; CK_MECHANISM mech = {0, NULL, 0 }; CK_SLOT_ID slotid; pk11_context_t *pk11_ctx; pk11_object_t *ec = key->keydata.pkey; isc_result_t ret; UNUSED(key); REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || dctx->key->key_alg == DST_ALG_ECDSA384); if (dctx->key->key_alg == DST_ALG_ECDSA256) mech.mechanism = CKM_SHA256; else mech.mechanism = CKM_SHA384; pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); if (ec->ontoken && (dctx->use == DO_SIGN)) slotid = ec->slot; else slotid = pk11_get_best_token(OP_EC); ret = pk11_get_session(pk11_ctx, OP_EC, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, slotid); if (ret != ISC_R_SUCCESS) goto err; PK11_RET(pkcs_C_DigestInit, (pk11_ctx->session, &mech), ISC_R_FAILURE); dctx->ctxdata.pk11_ctx = pk11_ctx; return (ISC_R_SUCCESS); err: pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); } static void pkcs11ecdsa_destroyctx(dst_context_t *dctx) { CK_BYTE garbage[ISC_SHA384_DIGESTLENGTH]; CK_ULONG len = ISC_SHA384_DIGESTLENGTH; pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || dctx->key->key_alg == DST_ALG_ECDSA384); if (pk11_ctx != NULL) { (void) pkcs_C_DigestFinal(pk11_ctx->session, garbage, &len); memset(garbage, 0, sizeof(garbage)); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); dctx->ctxdata.pk11_ctx = NULL; } } static isc_result_t pkcs11ecdsa_adddata(dst_context_t *dctx, const isc_region_t *data) { CK_RV rv; pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; isc_result_t ret = ISC_R_SUCCESS; REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || dctx->key->key_alg == DST_ALG_ECDSA384); PK11_CALL(pkcs_C_DigestUpdate, (pk11_ctx->session, (CK_BYTE_PTR) data->base, (CK_ULONG) data->length), ISC_R_FAILURE); return (ret); } static isc_result_t pkcs11ecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { CK_RV rv; CK_MECHANISM mech = { CKM_ECDSA, NULL, 0 }; CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; CK_KEY_TYPE keyType = CKK_EC; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_EC_PARAMS, NULL, 0 }, { CKA_VALUE, NULL, 0 } }; CK_ATTRIBUTE *attr; CK_BYTE digest[ISC_SHA384_DIGESTLENGTH]; CK_ULONG dgstlen; CK_ULONG siglen; pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; dst_key_t *key = dctx->key; pk11_object_t *ec = key->keydata.pkey; isc_region_t r; isc_result_t ret = ISC_R_SUCCESS; unsigned int i; REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); REQUIRE(ec != NULL); if (key->key_alg == DST_ALG_ECDSA256) { dgstlen = ISC_SHA256_DIGESTLENGTH; siglen = DNS_SIG_ECDSA256SIZE; } else { siglen = DNS_SIG_ECDSA384SIZE; dgstlen = ISC_SHA384_DIGESTLENGTH; } PK11_RET(pkcs_C_DigestFinal, (pk11_ctx->session, digest, &dgstlen), ISC_R_FAILURE); isc_buffer_availableregion(sig, &r); if (r.length < siglen) DST_RET(ISC_R_NOSPACE); if (ec->ontoken && (ec->object != CK_INVALID_HANDLE)) { pk11_ctx->ontoken = ec->ontoken; pk11_ctx->object = ec->object; goto token_key; } for (attr = pk11_attribute_first(ec); attr != NULL; attr = pk11_attribute_next(ec, attr)) switch (attr->type) { case CKA_EC_PARAMS: INSIST(keyTemplate[5].type == attr->type); keyTemplate[5].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[5].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[5].pValue, attr->pValue, attr->ulValueLen); keyTemplate[5].ulValueLen = attr->ulValueLen; break; case CKA_VALUE: INSIST(keyTemplate[6].type == attr->type); keyTemplate[6].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[6].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[6].pValue, attr->pValue, attr->ulValueLen); keyTemplate[6].ulValueLen = attr->ulValueLen; break; } pk11_ctx->object = CK_INVALID_HANDLE; pk11_ctx->ontoken = ISC_FALSE; PK11_RET(pkcs_C_CreateObject, (pk11_ctx->session, keyTemplate, (CK_ULONG) 7, &hKey), ISC_R_FAILURE); token_key: PK11_RET(pkcs_C_SignInit, (pk11_ctx->session, &mech, pk11_ctx->ontoken ? pk11_ctx->object : hKey), ISC_R_FAILURE); PK11_RET(pkcs_C_Sign, (pk11_ctx->session, digest, dgstlen, (CK_BYTE_PTR) r.base, &siglen), DST_R_SIGNFAILURE); isc_buffer_add(sig, (unsigned int) siglen); err: if (hKey != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, hKey); for (i = 5; i <= 6; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); dctx->ctxdata.pk11_ctx = NULL; return (ret); } static isc_result_t pkcs11ecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) { CK_RV rv; CK_MECHANISM mech = { CKM_ECDSA, NULL, 0 }; CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; CK_KEY_TYPE keyType = CKK_EC; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_EC_PARAMS, NULL, 0 }, { CKA_EC_POINT, NULL, 0 } }; CK_ATTRIBUTE *attr; CK_BYTE digest[ISC_SHA384_DIGESTLENGTH]; CK_ULONG dgstlen; pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; dst_key_t *key = dctx->key; pk11_object_t *ec = key->keydata.pkey; isc_result_t ret = ISC_R_SUCCESS; unsigned int i; REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); REQUIRE(ec != NULL); if (key->key_alg == DST_ALG_ECDSA256) dgstlen = ISC_SHA256_DIGESTLENGTH; else dgstlen = ISC_SHA384_DIGESTLENGTH; PK11_RET(pkcs_C_DigestFinal, (pk11_ctx->session, digest, &dgstlen), ISC_R_FAILURE); for (attr = pk11_attribute_first(ec); attr != NULL; attr = pk11_attribute_next(ec, attr)) switch (attr->type) { case CKA_EC_PARAMS: INSIST(keyTemplate[5].type == attr->type); keyTemplate[5].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[5].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[5].pValue, attr->pValue, attr->ulValueLen); keyTemplate[5].ulValueLen = attr->ulValueLen; break; case CKA_EC_POINT: INSIST(keyTemplate[6].type == attr->type); keyTemplate[6].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[6].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[6].pValue, attr->pValue, attr->ulValueLen); keyTemplate[6].ulValueLen = attr->ulValueLen; break; } pk11_ctx->object = CK_INVALID_HANDLE; pk11_ctx->ontoken = ISC_FALSE; PK11_RET(pkcs_C_CreateObject, (pk11_ctx->session, keyTemplate, (CK_ULONG) 7, &hKey), ISC_R_FAILURE); PK11_RET(pkcs_C_VerifyInit, (pk11_ctx->session, &mech, hKey), ISC_R_FAILURE); PK11_RET(pkcs_C_Verify, (pk11_ctx->session, digest, dgstlen, (CK_BYTE_PTR) sig->base, (CK_ULONG) sig->length), DST_R_SIGNFAILURE); err: if (hKey != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, hKey); for (i = 5; i <= 6; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); dctx->ctxdata.pk11_ctx = NULL; return (ret); } static isc_boolean_t pkcs11ecdsa_compare(const dst_key_t *key1, const dst_key_t *key2) { pk11_object_t *ec1, *ec2; CK_ATTRIBUTE *attr1, *attr2; ec1 = key1->keydata.pkey; ec2 = key2->keydata.pkey; if ((ec1 == NULL) && (ec2 == NULL)) return (ISC_TRUE); else if ((ec1 == NULL) || (ec2 == NULL)) return (ISC_FALSE); attr1 = pk11_attribute_bytype(ec1, CKA_EC_PARAMS); attr2 = pk11_attribute_bytype(ec2, CKA_EC_PARAMS); if ((attr1 == NULL) && (attr2 == NULL)) return (ISC_TRUE); else if ((attr1 == NULL) || (attr2 == NULL) || (attr1->ulValueLen != attr2->ulValueLen) || !isc_safe_memequal(attr1->pValue, attr2->pValue, attr1->ulValueLen)) return (ISC_FALSE); attr1 = pk11_attribute_bytype(ec1, CKA_EC_POINT); attr2 = pk11_attribute_bytype(ec2, CKA_EC_POINT); if ((attr1 == NULL) && (attr2 == NULL)) return (ISC_TRUE); else if ((attr1 == NULL) || (attr2 == NULL) || (attr1->ulValueLen != attr2->ulValueLen) || !isc_safe_memequal(attr1->pValue, attr2->pValue, attr1->ulValueLen)) return (ISC_FALSE); attr1 = pk11_attribute_bytype(ec1, CKA_VALUE); attr2 = pk11_attribute_bytype(ec2, CKA_VALUE); if (((attr1 != NULL) || (attr2 != NULL)) && ((attr1 == NULL) || (attr2 == NULL) || (attr1->ulValueLen != attr2->ulValueLen) || !isc_safe_memequal(attr1->pValue, attr2->pValue, attr1->ulValueLen))) return (ISC_FALSE); if (!ec1->ontoken && !ec2->ontoken) return (ISC_TRUE); else if (ec1->ontoken || ec2->ontoken || (ec1->object != ec2->object)) return (ISC_FALSE); return (ISC_TRUE); } #define SETCURVE() \ if (key->key_alg == DST_ALG_ECDSA256) { \ attr->pValue = isc_mem_get(key->mctx, \ sizeof(pk11_ecc_prime256v1)); \ if (attr->pValue == NULL) \ DST_RET(ISC_R_NOMEMORY); \ memmove(attr->pValue, \ pk11_ecc_prime256v1, sizeof(pk11_ecc_prime256v1)); \ attr->ulValueLen = sizeof(pk11_ecc_prime256v1); \ } else { \ attr->pValue = isc_mem_get(key->mctx, \ sizeof(pk11_ecc_secp384r1)); \ if (attr->pValue == NULL) \ DST_RET(ISC_R_NOMEMORY); \ memmove(attr->pValue, \ pk11_ecc_secp384r1, sizeof(pk11_ecc_secp384r1)); \ attr->ulValueLen = sizeof(pk11_ecc_secp384r1); \ } #define FREECURVE() \ if (attr->pValue != NULL) { \ memset(attr->pValue, 0, attr->ulValueLen); \ isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); \ attr->pValue = NULL; \ } static isc_result_t pkcs11ecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { CK_RV rv; CK_MECHANISM mech = { CKM_EC_KEY_PAIR_GEN, NULL, 0 }; CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; CK_KEY_TYPE keyType = CKK_EC; CK_ATTRIBUTE pubTemplate[] = { { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_EC_PARAMS, NULL, 0 } }; CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY; CK_ATTRIBUTE privTemplate[] = { { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) } }; CK_ATTRIBUTE *attr; pk11_object_t *ec; pk11_context_t *pk11_ctx; isc_result_t ret; REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); UNUSED(unused); UNUSED(callback); pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_EC, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_EC)); if (ret != ISC_R_SUCCESS) goto err; ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec)); if (ec == NULL) DST_RET(ISC_R_NOMEMORY); memset(ec, 0, sizeof(*ec)); key->keydata.pkey = ec; ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 3); if (ec->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(ec->repr, 0, sizeof(*attr) * 3); ec->attrcnt = 3; attr = ec->repr; attr[0].type = CKA_EC_PARAMS; attr[1].type = CKA_EC_POINT; attr[2].type = CKA_VALUE; attr = &pubTemplate[5]; SETCURVE(); PK11_RET(pkcs_C_GenerateKeyPair, (pk11_ctx->session, &mech, pubTemplate, (CK_ULONG) 6, privTemplate, (CK_ULONG) 7, &pub, &priv), DST_R_CRYPTOFAILURE); attr = &pubTemplate[5]; FREECURVE(); attr = ec->repr; SETCURVE(); attr++; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr++; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); if (key->key_alg == DST_ALG_ECDSA256) key->key_size = DNS_KEY_ECDSA256SIZE * 4; else key->key_size = DNS_KEY_ECDSA384SIZE * 4; return (ISC_R_SUCCESS); err: pkcs11ecdsa_destroy(key); if (priv != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); if (pub != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); } static isc_boolean_t pkcs11ecdsa_isprivate(const dst_key_t *key) { pk11_object_t *ec = key->keydata.pkey; CK_ATTRIBUTE *attr; if (ec == NULL) return (ISC_FALSE); attr = pk11_attribute_bytype(ec, CKA_VALUE); return (ISC_TF((attr != NULL) || ec->ontoken)); } static void pkcs11ecdsa_destroy(dst_key_t *key) { pk11_object_t *ec = key->keydata.pkey; CK_ATTRIBUTE *attr; if (ec == NULL) return; INSIST((ec->object == CK_INVALID_HANDLE) || ec->ontoken); for (attr = pk11_attribute_first(ec); attr != NULL; attr = pk11_attribute_next(ec, attr)) switch (attr->type) { case CKA_LABEL: case CKA_ID: case CKA_EC_PARAMS: case CKA_EC_POINT: case CKA_VALUE: FREECURVE(); break; } if (ec->repr != NULL) { memset(ec->repr, 0, ec->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, ec->repr, ec->attrcnt * sizeof(*attr)); } memset(ec, 0, sizeof(*ec)); isc_mem_put(key->mctx, ec, sizeof(*ec)); key->keydata.pkey = NULL; } static isc_result_t pkcs11ecdsa_todns(const dst_key_t *key, isc_buffer_t *data) { pk11_object_t *ec; isc_region_t r; unsigned int len; CK_ATTRIBUTE *attr; REQUIRE(key->keydata.pkey != NULL); if (key->key_alg == DST_ALG_ECDSA256) len = DNS_KEY_ECDSA256SIZE; else len = DNS_KEY_ECDSA384SIZE; ec = key->keydata.pkey; attr = pk11_attribute_bytype(ec, CKA_EC_POINT); if ((attr == NULL) || (attr->ulValueLen != len + 3) || (((CK_BYTE_PTR) attr->pValue)[0] != TAG_OCTECT_STRING) || (((CK_BYTE_PTR) attr->pValue)[1] != len + 1) || (((CK_BYTE_PTR) attr->pValue)[2] != UNCOMPRESSED)) return (ISC_R_FAILURE); isc_buffer_availableregion(data, &r); if (r.length < len) return (ISC_R_NOSPACE); memmove(r.base, (CK_BYTE_PTR) attr->pValue + 3, len); isc_buffer_add(data, len); return (ISC_R_SUCCESS); } static isc_result_t pkcs11ecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) { pk11_object_t *ec; isc_region_t r; unsigned int len; CK_ATTRIBUTE *attr; REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); if (key->key_alg == DST_ALG_ECDSA256) len = DNS_KEY_ECDSA256SIZE; else len = DNS_KEY_ECDSA384SIZE; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); if (r.length != len) return (DST_R_INVALIDPUBLICKEY); ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec)); if (ec == NULL) return (ISC_R_NOMEMORY); memset(ec, 0, sizeof(*ec)); ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); if (ec->repr == NULL) goto nomemory; ec->attrcnt = 2; attr = ec->repr; attr->type = CKA_EC_PARAMS; if (key->key_alg == DST_ALG_ECDSA256) { attr->pValue = isc_mem_get(key->mctx, sizeof(pk11_ecc_prime256v1)); if (attr->pValue == NULL) goto nomemory; memmove(attr->pValue, pk11_ecc_prime256v1, sizeof(pk11_ecc_prime256v1)); attr->ulValueLen = sizeof(pk11_ecc_prime256v1); } else { attr->pValue = isc_mem_get(key->mctx, sizeof(pk11_ecc_secp384r1)); if (attr->pValue == NULL) goto nomemory; memmove(attr->pValue, pk11_ecc_secp384r1, sizeof(pk11_ecc_secp384r1)); attr->ulValueLen = sizeof(pk11_ecc_secp384r1); } attr++; attr->type = CKA_EC_POINT; attr->pValue = isc_mem_get(key->mctx, len + 3); if (attr->pValue == NULL) goto nomemory; ((CK_BYTE_PTR) attr->pValue)[0] = TAG_OCTECT_STRING; ((CK_BYTE_PTR) attr->pValue)[1] = len + 1; ((CK_BYTE_PTR) attr->pValue)[2] = UNCOMPRESSED; memmove((CK_BYTE_PTR) attr->pValue + 3, r.base, len); attr->ulValueLen = len + 3; isc_buffer_forward(data, len); key->keydata.pkey = ec; key->key_size = len * 4; return (ISC_R_SUCCESS); nomemory: for (attr = pk11_attribute_first(ec); attr != NULL; attr = pk11_attribute_next(ec, attr)) switch (attr->type) { case CKA_EC_PARAMS: case CKA_EC_POINT: FREECURVE(); break; } if (ec->repr != NULL) { memset(ec->repr, 0, ec->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, ec->repr, ec->attrcnt * sizeof(*attr)); } memset(ec, 0, sizeof(*ec)); isc_mem_put(key->mctx, ec, sizeof(*ec)); return (ISC_R_NOMEMORY); } static isc_result_t pkcs11ecdsa_tofile(const dst_key_t *key, const char *directory) { isc_result_t ret; pk11_object_t *ec; dst_private_t priv; unsigned char *buf = NULL; unsigned int i = 0; CK_ATTRIBUTE *attr; if (key->keydata.pkey == NULL) return (DST_R_NULLKEY); if (key->external) { priv.nelements = 0; return (dst__privstruct_writefile(key, &priv, directory)); } ec = key->keydata.pkey; attr = pk11_attribute_bytype(ec, CKA_VALUE); if (attr != NULL) { buf = isc_mem_get(key->mctx, attr->ulValueLen); if (buf == NULL) return (ISC_R_NOMEMORY); priv.elements[i].tag = TAG_ECDSA_PRIVATEKEY; priv.elements[i].length = (unsigned short) attr->ulValueLen; memmove(buf, attr->pValue, attr->ulValueLen); priv.elements[i].data = buf; i++; } if (key->engine != NULL) { priv.elements[i].tag = TAG_ECDSA_ENGINE; priv.elements[i].length = strlen(key->engine) + 1; priv.elements[i].data = (unsigned char *)key->engine; i++; } if (key->label != NULL) { priv.elements[i].tag = TAG_ECDSA_LABEL; priv.elements[i].length = strlen(key->label) + 1; priv.elements[i].data = (unsigned char *)key->label; i++; } priv.nelements = i; ret = dst__privstruct_writefile(key, &priv, directory); if (buf != NULL) { memset(buf, 0, attr->ulValueLen); isc_mem_put(key->mctx, buf, attr->ulValueLen); } return (ret); } static isc_result_t pkcs11ecdsa_fetch(dst_key_t *key, const char *engine, const char *label, dst_key_t *pub) { CK_RV rv; CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; CK_KEY_TYPE keyType = CKK_EC; CK_ATTRIBUTE searchTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_LABEL, NULL, 0 } }; CK_ULONG cnt; CK_ATTRIBUTE *attr; CK_ATTRIBUTE *pubattr; pk11_object_t *ec; pk11_object_t *pubec; pk11_context_t *pk11_ctx = NULL; isc_result_t ret; if (label == NULL) return (DST_R_NOENGINE); ec = key->keydata.pkey; pubec = pub->keydata.pkey; ec->object = CK_INVALID_HANDLE; ec->ontoken = ISC_TRUE; ec->reqlogon = ISC_TRUE; ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); if (ec->repr == NULL) return (ISC_R_NOMEMORY); memset(ec->repr, 0, sizeof(*attr) * 2); ec->attrcnt = 2; attr = ec->repr; attr->type = CKA_EC_PARAMS; pubattr = pk11_attribute_bytype(pubec, CKA_EC_PARAMS); attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen); attr->ulValueLen = pubattr->ulValueLen; attr++; attr->type = CKA_EC_POINT; pubattr = pk11_attribute_bytype(pubec, CKA_EC_POINT); attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen); attr->ulValueLen = pubattr->ulValueLen; ret = pk11_parse_uri(ec, label, key->mctx, OP_EC); if (ret != ISC_R_SUCCESS) goto err; pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) DST_RET(ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_EC, ISC_TRUE, ISC_FALSE, ec->reqlogon, NULL, ec->slot); if (ret != ISC_R_SUCCESS) goto err; attr = pk11_attribute_bytype(ec, CKA_LABEL); if (attr == NULL) { attr = pk11_attribute_bytype(ec, CKA_ID); INSIST(attr != NULL); searchTemplate[3].type = CKA_ID; } searchTemplate[3].pValue = attr->pValue; searchTemplate[3].ulValueLen = attr->ulValueLen; PK11_RET(pkcs_C_FindObjectsInit, (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), DST_R_CRYPTOFAILURE); PK11_RET(pkcs_C_FindObjects, (pk11_ctx->session, &ec->object, (CK_ULONG) 1, &cnt), DST_R_CRYPTOFAILURE); (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); if (cnt == 0) DST_RET(ISC_R_NOTFOUND); if (cnt > 1) DST_RET(ISC_R_EXISTS); if (engine != NULL) { key->engine = isc_mem_strdup(key->mctx, engine); if (key->engine == NULL) DST_RET(ISC_R_NOMEMORY); } key->label = isc_mem_strdup(key->mctx, label); if (key->label == NULL) DST_RET(ISC_R_NOMEMORY); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ISC_R_SUCCESS); err: if (pk11_ctx != NULL) { pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); } return (ret); } static isc_result_t pkcs11ecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t ret; pk11_object_t *ec = NULL; CK_ATTRIBUTE *attr, *pattr; isc_mem_t *mctx = key->mctx; unsigned int i; const char *engine = NULL, *label = NULL; REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); if ((pub == NULL) || (pub->keydata.pkey == NULL)) DST_RET(DST_R_INVALIDPRIVATEKEY); /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) return (ret); if (key->external) { if (priv.nelements != 0) DST_RET(DST_R_INVALIDPRIVATEKEY); key->keydata.pkey = pub->keydata.pkey; pub->keydata.pkey = NULL; key->key_size = pub->key_size; dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ISC_R_SUCCESS); } for (i = 0; i < priv.nelements; i++) { switch (priv.elements[i].tag) { case TAG_ECDSA_ENGINE: engine = (char *)priv.elements[i].data; break; case TAG_ECDSA_LABEL: label = (char *)priv.elements[i].data; break; default: break; } } ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec)); if (ec == NULL) DST_RET(ISC_R_NOMEMORY); memset(ec, 0, sizeof(*ec)); key->keydata.pkey = ec; /* Is this key is stored in a HSM? See if we can fetch it. */ if ((label != NULL) || (engine != NULL)) { ret = pkcs11ecdsa_fetch(key, engine, label, pub); if (ret != ISC_R_SUCCESS) goto err; dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ret); } ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 3); if (ec->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(ec->repr, 0, sizeof(*attr) * 3); ec->attrcnt = 3; attr = ec->repr; attr->type = CKA_EC_PARAMS; pattr = pk11_attribute_bytype(pub->keydata.pkey, CKA_EC_PARAMS); INSIST(pattr != NULL); attr->pValue = isc_mem_get(key->mctx, pattr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(attr->pValue, pattr->pValue, pattr->ulValueLen); attr->ulValueLen = pattr->ulValueLen; attr++; attr->type = CKA_EC_POINT; pattr = pk11_attribute_bytype(pub->keydata.pkey, CKA_EC_POINT); INSIST(pattr != NULL); attr->pValue = isc_mem_get(key->mctx, pattr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(attr->pValue, pattr->pValue, pattr->ulValueLen); attr->ulValueLen = pattr->ulValueLen; attr++; attr->type = CKA_VALUE; attr->pValue = isc_mem_get(key->mctx, priv.elements[0].length); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(attr->pValue, priv.elements[0].data, priv.elements[0].length); attr->ulValueLen = priv.elements[0].length; dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); if (key->key_alg == DST_ALG_ECDSA256) key->key_size = DNS_KEY_ECDSA256SIZE * 4; else key->key_size = DNS_KEY_ECDSA384SIZE * 4; return (ISC_R_SUCCESS); err: pkcs11ecdsa_destroy(key); dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ret); } static isc_result_t pkcs11ecdsa_fromlabel(dst_key_t *key, const char *engine, const char *label, const char *pin) { CK_RV rv; CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; CK_KEY_TYPE keyType = CKK_EC; CK_ATTRIBUTE searchTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_LABEL, NULL, 0 } }; CK_ULONG cnt; CK_ATTRIBUTE *attr; pk11_object_t *ec; pk11_context_t *pk11_ctx = NULL; isc_result_t ret; unsigned int i; UNUSED(pin); ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec)); if (ec == NULL) return (ISC_R_NOMEMORY); memset(ec, 0, sizeof(*ec)); ec->object = CK_INVALID_HANDLE; ec->ontoken = ISC_TRUE; ec->reqlogon = ISC_TRUE; key->keydata.pkey = ec; ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); if (ec->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(ec->repr, 0, sizeof(*attr) * 2); ec->attrcnt = 2; attr = ec->repr; attr[0].type = CKA_EC_PARAMS; attr[1].type = CKA_EC_POINT; ret = pk11_parse_uri(ec, label, key->mctx, OP_EC); if (ret != ISC_R_SUCCESS) goto err; pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) DST_RET(ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_EC, ISC_TRUE, ISC_FALSE, ec->reqlogon, NULL, ec->slot); if (ret != ISC_R_SUCCESS) goto err; attr = pk11_attribute_bytype(ec, CKA_LABEL); if (attr == NULL) { attr = pk11_attribute_bytype(ec, CKA_ID); INSIST(attr != NULL); searchTemplate[3].type = CKA_ID; } searchTemplate[3].pValue = attr->pValue; searchTemplate[3].ulValueLen = attr->ulValueLen; PK11_RET(pkcs_C_FindObjectsInit, (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), DST_R_CRYPTOFAILURE); PK11_RET(pkcs_C_FindObjects, (pk11_ctx->session, &hKey, (CK_ULONG) 1, &cnt), DST_R_CRYPTOFAILURE); (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); if (cnt == 0) DST_RET(ISC_R_NOTFOUND); if (cnt > 1) DST_RET(ISC_R_EXISTS); attr = ec->repr; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, hKey, attr, 2), DST_R_CRYPTOFAILURE); for (i = 0; i <= 1; i++) { attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); if (attr[i].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr[i].pValue, 0, attr[i].ulValueLen); } PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, hKey, attr, 2), DST_R_CRYPTOFAILURE); keyClass = CKO_PRIVATE_KEY; PK11_RET(pkcs_C_FindObjectsInit, (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), DST_R_CRYPTOFAILURE); PK11_RET(pkcs_C_FindObjects, (pk11_ctx->session, &ec->object, (CK_ULONG) 1, &cnt), DST_R_CRYPTOFAILURE); (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); if (cnt == 0) DST_RET(ISC_R_NOTFOUND); if (cnt > 1) DST_RET(ISC_R_EXISTS); if (engine != NULL) { key->engine = isc_mem_strdup(key->mctx, engine); if (key->engine == NULL) DST_RET(ISC_R_NOMEMORY); } key->label = isc_mem_strdup(key->mctx, label); if (key->label == NULL) DST_RET(ISC_R_NOMEMORY); if (key->key_alg == DST_ALG_ECDSA256) key->key_size = DNS_KEY_ECDSA256SIZE * 4; else key->key_size = DNS_KEY_ECDSA384SIZE * 4; pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ISC_R_SUCCESS); err: pkcs11ecdsa_destroy(key); if (pk11_ctx != NULL) { pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); } return (ret); } static dst_func_t pkcs11ecdsa_functions = { pkcs11ecdsa_createctx, NULL, /*%< createctx2 */ pkcs11ecdsa_destroyctx, pkcs11ecdsa_adddata, pkcs11ecdsa_sign, pkcs11ecdsa_verify, NULL, /*%< verify2 */ NULL, /*%< computesecret */ pkcs11ecdsa_compare, NULL, /*%< paramcompare */ pkcs11ecdsa_generate, pkcs11ecdsa_isprivate, pkcs11ecdsa_destroy, pkcs11ecdsa_todns, pkcs11ecdsa_fromdns, pkcs11ecdsa_tofile, pkcs11ecdsa_parse, NULL, /*%< cleanup */ pkcs11ecdsa_fromlabel, NULL, /*%< dump */ NULL, /*%< restore */ }; isc_result_t dst__pkcs11ecdsa_init(dst_func_t **funcp) { REQUIRE(funcp != NULL); if (*funcp == NULL) *funcp = &pkcs11ecdsa_functions; return (ISC_R_SUCCESS); } #else /* PKCS11CRYPTO && HAVE_PKCS11_ECDSA */ #include EMPTY_TRANSLATION_UNIT #endif /* PKCS11CRYPTO && HAVE_PKCS11_ECDSA */ /*! \file */ bind9-9.10.3.dfsg.P4/lib/dns/rdataslab.c0000644000470500017500000006302012664710322017025 0ustar lamontlamont/* * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include /* Required for HP/UX (and others?) */ #include #include #include #include #include /* * The rdataslab structure allows iteration to occur in both load order * and DNSSEC order. The structure is as follows: * * header (reservelen bytes) * record count (2 bytes) * offset table (4 x record count bytes in load order) * data records * data length (2 bytes) * order (2 bytes) * meta data (1 byte for RRSIG's) * data (data length bytes) * * If DNS_RDATASET_FIXED is defined to be zero (0) the format of a * rdataslab is as follows: * * header (reservelen bytes) * record count (2 bytes) * data records * data length (2 bytes) * meta data (1 byte for RRSIG's) * data (data length bytes) * * Offsets are from the end of the header. * * Load order traversal is performed by walking the offset table to find * the start of the record (DNS_RDATASET_FIXED = 1). * * DNSSEC order traversal is performed by walking the data records. * * The order is stored with record to allow for efficient reconstruction * of the offset table following a merge or subtraction. * * The iterator methods here currently only support DNSSEC order iteration. * * The iterator methods in rbtdb support both load order and DNSSEC order * iteration. * * WARNING: * rbtdb.c directly interacts with the slab's raw structures. If the * structure changes then rbtdb.c also needs to be updated to reflect * the changes. See the areas tagged with "RDATASLAB". */ struct xrdata { dns_rdata_t rdata; unsigned int order; }; /*% Note: the "const void *" are just to make qsort happy. */ static int compare_rdata(const void *p1, const void *p2) { const struct xrdata *x1 = p1; const struct xrdata *x2 = p2; return (dns_rdata_compare(&x1->rdata, &x2->rdata)); } #if DNS_RDATASET_FIXED static void fillin_offsets(unsigned char *offsetbase, unsigned int *offsettable, unsigned length) { unsigned int i, j; unsigned char *raw; for (i = 0, j = 0; i < length; i++) { if (offsettable[i] == 0) continue; /* * Fill in offset table. */ raw = &offsetbase[j*4 + 2]; *raw++ = (offsettable[i] & 0xff000000) >> 24; *raw++ = (offsettable[i] & 0xff0000) >> 16; *raw++ = (offsettable[i] & 0xff00) >> 8; *raw = offsettable[i] & 0xff; /* * Fill in table index. */ raw = offsetbase + offsettable[i] + 2; *raw++ = (j & 0xff00) >> 8; *raw = j++ & 0xff; } } #endif isc_result_t dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, isc_region_t *region, unsigned int reservelen) { /* * Use &removed as a sentinal pointer for duplicate * rdata as rdata.data == NULL is valid. */ static unsigned char removed; struct xrdata *x; unsigned char *rawbuf; #if DNS_RDATASET_FIXED unsigned char *offsetbase; #endif unsigned int buflen; isc_result_t result; unsigned int nitems; unsigned int nalloc; unsigned int i; #if DNS_RDATASET_FIXED unsigned int *offsettable; #endif unsigned int length; buflen = reservelen + 2; nitems = dns_rdataset_count(rdataset); /* * If there are no rdata then we can just need to allocate a header * with zero a record count. */ if (nitems == 0) { if (rdataset->type != 0) return (ISC_R_FAILURE); rawbuf = isc_mem_get(mctx, buflen); if (rawbuf == NULL) return (ISC_R_NOMEMORY); region->base = rawbuf; region->length = buflen; rawbuf += reservelen; *rawbuf++ = 0; *rawbuf = 0; return (ISC_R_SUCCESS); } if (nitems > 0xffff) return (ISC_R_NOSPACE); /* * Remember the original number of items. */ nalloc = nitems; x = isc_mem_get(mctx, nalloc * sizeof(struct xrdata)); if (x == NULL) return (ISC_R_NOMEMORY); /* * Save all of the rdata members into an array. */ result = dns_rdataset_first(rdataset); if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE) goto free_rdatas; for (i = 0; i < nalloc && result == ISC_R_SUCCESS; i++) { INSIST(result == ISC_R_SUCCESS); dns_rdata_init(&x[i].rdata); dns_rdataset_current(rdataset, &x[i].rdata); INSIST(x[i].rdata.data != &removed); #if DNS_RDATASET_FIXED x[i].order = i; #endif result = dns_rdataset_next(rdataset); } if (i != nalloc || result != ISC_R_NOMORE) { /* * Somehow we iterated over fewer rdatas than * dns_rdataset_count() said there were or there * were more items than dns_rdataset_count said * there were. */ result = ISC_R_FAILURE; goto free_rdatas; } /* * Put into DNSSEC order. */ if (nalloc > 1U) qsort(x, nalloc, sizeof(struct xrdata), compare_rdata); /* * Remove duplicates and compute the total storage required. * * If an rdata is not a duplicate, accumulate the storage size * required for the rdata. We do not store the class, type, etc, * just the rdata, so our overhead is 2 bytes for the number of * records, and 8 for each rdata, (length(2), offset(4) and order(2)) * and then the rdata itself. */ for (i = 1; i < nalloc; i++) { if (compare_rdata(&x[i-1].rdata, &x[i].rdata) == 0) { x[i-1].rdata.data = &removed; #if DNS_RDATASET_FIXED /* * Preserve the least order so A, B, A -> A, B * after duplicate removal. */ if (x[i-1].order < x[i].order) x[i].order = x[i-1].order; #endif nitems--; } else { #if DNS_RDATASET_FIXED buflen += (8 + x[i-1].rdata.length); #else buflen += (2 + x[i-1].rdata.length); #endif /* * Provide space to store the per RR meta data. */ if (rdataset->type == dns_rdatatype_rrsig) buflen++; } } /* * Don't forget the last item! */ #if DNS_RDATASET_FIXED buflen += (8 + x[i-1].rdata.length); #else buflen += (2 + x[i-1].rdata.length); #endif /* * Provide space to store the per RR meta data. */ if (rdataset->type == dns_rdatatype_rrsig) buflen++; /* * Ensure that singleton types are actually singletons. */ if (nitems > 1 && dns_rdatatype_issingleton(rdataset->type)) { /* * We have a singleton type, but there's more than one * RR in the rdataset. */ result = DNS_R_SINGLETON; goto free_rdatas; } /* * Allocate the memory, set up a buffer, start copying in * data. */ rawbuf = isc_mem_get(mctx, buflen); if (rawbuf == NULL) { result = ISC_R_NOMEMORY; goto free_rdatas; } #if DNS_RDATASET_FIXED /* Allocate temporary offset table. */ offsettable = isc_mem_get(mctx, nalloc * sizeof(unsigned int)); if (offsettable == NULL) { isc_mem_put(mctx, rawbuf, buflen); result = ISC_R_NOMEMORY; goto free_rdatas; } memset(offsettable, 0, nalloc * sizeof(unsigned int)); #endif region->base = rawbuf; region->length = buflen; rawbuf += reservelen; #if DNS_RDATASET_FIXED offsetbase = rawbuf; #endif *rawbuf++ = (nitems & 0xff00) >> 8; *rawbuf++ = (nitems & 0x00ff); #if DNS_RDATASET_FIXED /* Skip load order table. Filled in later. */ rawbuf += nitems * 4; #endif for (i = 0; i < nalloc; i++) { if (x[i].rdata.data == &removed) continue; #if DNS_RDATASET_FIXED offsettable[x[i].order] = rawbuf - offsetbase; #endif length = x[i].rdata.length; if (rdataset->type == dns_rdatatype_rrsig) length++; INSIST(length <= 0xffff); *rawbuf++ = (length & 0xff00) >> 8; *rawbuf++ = (length & 0x00ff); #if DNS_RDATASET_FIXED rawbuf += 2; /* filled in later */ #endif /* * Store the per RR meta data. */ if (rdataset->type == dns_rdatatype_rrsig) { *rawbuf++ |= (x[i].rdata.flags & DNS_RDATA_OFFLINE) ? DNS_RDATASLAB_OFFLINE : 0; } memmove(rawbuf, x[i].rdata.data, x[i].rdata.length); rawbuf += x[i].rdata.length; } #if DNS_RDATASET_FIXED fillin_offsets(offsetbase, offsettable, nalloc); isc_mem_put(mctx, offsettable, nalloc * sizeof(unsigned int)); #endif result = ISC_R_SUCCESS; free_rdatas: isc_mem_put(mctx, x, nalloc * sizeof(struct xrdata)); return (result); } static void rdataset_disassociate(dns_rdataset_t *rdataset) { UNUSED(rdataset); } static isc_result_t rdataset_first(dns_rdataset_t *rdataset) { unsigned char *raw = rdataset->private3; unsigned int count; count = raw[0] * 256 + raw[1]; if (count == 0) { rdataset->private5 = NULL; return (ISC_R_NOMORE); } #if DNS_RDATASET_FIXED raw += 2 + (4 * count); #else raw += 2; #endif /* * The privateuint4 field is the number of rdata beyond the cursor * position, so we decrement the total count by one before storing * it. */ count--; rdataset->privateuint4 = count; rdataset->private5 = raw; return (ISC_R_SUCCESS); } static isc_result_t rdataset_next(dns_rdataset_t *rdataset) { unsigned int count; unsigned int length; unsigned char *raw; count = rdataset->privateuint4; if (count == 0) return (ISC_R_NOMORE); count--; rdataset->privateuint4 = count; raw = rdataset->private5; length = raw[0] * 256 + raw[1]; #if DNS_RDATASET_FIXED raw += length + 4; #else raw += length + 2; #endif rdataset->private5 = raw; return (ISC_R_SUCCESS); } static void rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) { unsigned char *raw = rdataset->private5; isc_region_t r; unsigned int length; unsigned int flags = 0; REQUIRE(raw != NULL); length = raw[0] * 256 + raw[1]; #if DNS_RDATASET_FIXED raw += 4; #else raw += 2; #endif if (rdataset->type == dns_rdatatype_rrsig) { if (*raw & DNS_RDATASLAB_OFFLINE) flags |= DNS_RDATA_OFFLINE; length--; raw++; } r.length = length; r.base = raw; dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r); rdata->flags |= flags; } static void rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { *target = *source; /* * Reset iterator state. */ target->privateuint4 = 0; target->private5 = NULL; } static unsigned int rdataset_count(dns_rdataset_t *rdataset) { unsigned char *raw = rdataset->private3; unsigned int count; count = raw[0] * 256 + raw[1]; return (count); } static dns_rdatasetmethods_t rdataset_methods = { rdataset_disassociate, rdataset_first, rdataset_next, rdataset_current, rdataset_clone, rdataset_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; void dns_rdataslab_tordataset(unsigned char *slab, unsigned int reservelen, dns_rdataclass_t rdclass, dns_rdatatype_t rdtype, dns_rdatatype_t covers, dns_ttl_t ttl, dns_rdataset_t *rdataset) { REQUIRE(slab != NULL); REQUIRE(!dns_rdataset_isassociated(rdataset)); rdataset->methods = &rdataset_methods; rdataset->rdclass = rdclass; rdataset->type = rdtype; rdataset->covers = covers; rdataset->ttl = ttl; rdataset->trust = 0; rdataset->private1 = NULL; rdataset->private2 = NULL; rdataset->private3 = slab + reservelen; /* * Reset iterator state. */ rdataset->privateuint4 = 0; rdataset->private5 = NULL; } unsigned int dns_rdataslab_size(unsigned char *slab, unsigned int reservelen) { unsigned int count, length; unsigned char *current; REQUIRE(slab != NULL); current = slab + reservelen; count = *current++ * 256; count += *current++; #if DNS_RDATASET_FIXED current += (4 * count); #endif while (count > 0) { count--; length = *current++ * 256; length += *current++; #if DNS_RDATASET_FIXED current += length + 2; #else current += length; #endif } return ((unsigned int)(current - slab)); } /* * Make the dns_rdata_t 'rdata' refer to the slab item * beginning at '*current', which is part of a slab of type * 'type' and class 'rdclass', and advance '*current' to * point to the next item in the slab. */ static inline void rdata_from_slab(unsigned char **current, dns_rdataclass_t rdclass, dns_rdatatype_t type, dns_rdata_t *rdata) { unsigned char *tcurrent = *current; isc_region_t region; unsigned int length; isc_boolean_t offline = ISC_FALSE; length = *tcurrent++ * 256; length += *tcurrent++; if (type == dns_rdatatype_rrsig) { if ((*tcurrent & DNS_RDATASLAB_OFFLINE) != 0) offline = ISC_TRUE; length--; tcurrent++; } region.length = length; #if DNS_RDATASET_FIXED tcurrent += 2; #endif region.base = tcurrent; tcurrent += region.length; dns_rdata_fromregion(rdata, rdclass, type, ®ion); if (offline) rdata->flags |= DNS_RDATA_OFFLINE; *current = tcurrent; } /* * Return true iff 'slab' (slab data of type 'type' and class 'rdclass') * contains an rdata identical to 'rdata'. This does case insensitive * comparisons per DNSSEC. */ static inline isc_boolean_t rdata_in_slab(unsigned char *slab, unsigned int reservelen, dns_rdataclass_t rdclass, dns_rdatatype_t type, dns_rdata_t *rdata) { unsigned int count, i; unsigned char *current; dns_rdata_t trdata = DNS_RDATA_INIT; int n; current = slab + reservelen; count = *current++ * 256; count += *current++; #if DNS_RDATASET_FIXED current += (4 * count); #endif for (i = 0; i < count; i++) { rdata_from_slab(¤t, rdclass, type, &trdata); n = dns_rdata_compare(&trdata, rdata); if (n == 0) return (ISC_TRUE); if (n > 0) /* In DNSSEC order. */ break; dns_rdata_reset(&trdata); } return (ISC_FALSE); } isc_result_t dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab, unsigned int reservelen, isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_rdatatype_t type, unsigned int flags, unsigned char **tslabp) { unsigned char *ocurrent, *ostart, *ncurrent, *tstart, *tcurrent, *data; unsigned int ocount, ncount, count, olength, tlength, tcount, length; dns_rdata_t ordata = DNS_RDATA_INIT; dns_rdata_t nrdata = DNS_RDATA_INIT; isc_boolean_t added_something = ISC_FALSE; unsigned int oadded = 0; unsigned int nadded = 0; unsigned int nncount = 0; #if DNS_RDATASET_FIXED unsigned int oncount; unsigned int norder = 0; unsigned int oorder = 0; unsigned char *offsetbase; unsigned int *offsettable; #endif /* * XXX Need parameter to allow "delete rdatasets in nslab" merge, * or perhaps another merge routine for this purpose. */ REQUIRE(tslabp != NULL && *tslabp == NULL); REQUIRE(oslab != NULL && nslab != NULL); ocurrent = oslab + reservelen; ocount = *ocurrent++ * 256; ocount += *ocurrent++; #if DNS_RDATASET_FIXED ocurrent += (4 * ocount); #endif ostart = ocurrent; ncurrent = nslab + reservelen; ncount = *ncurrent++ * 256; ncount += *ncurrent++; #if DNS_RDATASET_FIXED ncurrent += (4 * ncount); #endif INSIST(ocount > 0 && ncount > 0); #if DNS_RDATASET_FIXED oncount = ncount; #endif /* * Yes, this is inefficient! */ /* * Figure out the length of the old slab's data. */ olength = 0; for (count = 0; count < ocount; count++) { length = *ocurrent++ * 256; length += *ocurrent++; #if DNS_RDATASET_FIXED olength += length + 8; ocurrent += length + 2; #else olength += length + 2; ocurrent += length; #endif } /* * Start figuring out the target length and count. */ tlength = reservelen + 2 + olength; tcount = ocount; /* * Add in the length of rdata in the new slab that aren't in * the old slab. */ do { dns_rdata_init(&nrdata); rdata_from_slab(&ncurrent, rdclass, type, &nrdata); if (!rdata_in_slab(oslab, reservelen, rdclass, type, &nrdata)) { /* * This rdata isn't in the old slab. */ #if DNS_RDATASET_FIXED tlength += nrdata.length + 8; #else tlength += nrdata.length + 2; #endif if (type == dns_rdatatype_rrsig) tlength++; tcount++; nncount++; added_something = ISC_TRUE; } ncount--; } while (ncount > 0); ncount = nncount; if (((flags & DNS_RDATASLAB_EXACT) != 0) && (tcount != ncount + ocount)) return (DNS_R_NOTEXACT); if (!added_something && (flags & DNS_RDATASLAB_FORCE) == 0) return (DNS_R_UNCHANGED); /* * Ensure that singleton types are actually singletons. */ if (tcount > 1 && dns_rdatatype_issingleton(type)) { /* * We have a singleton type, but there's more than one * RR in the rdataset. */ return (DNS_R_SINGLETON); } if (tcount > 0xffff) return (ISC_R_NOSPACE); /* * Copy the reserved area from the new slab. */ tstart = isc_mem_get(mctx, tlength); if (tstart == NULL) return (ISC_R_NOMEMORY); memmove(tstart, nslab, reservelen); tcurrent = tstart + reservelen; #if DNS_RDATASET_FIXED offsetbase = tcurrent; #endif /* * Write the new count. */ *tcurrent++ = (tcount & 0xff00) >> 8; *tcurrent++ = (tcount & 0x00ff); #if DNS_RDATASET_FIXED /* * Skip offset table. */ tcurrent += (tcount * 4); offsettable = isc_mem_get(mctx, (ocount + oncount) * sizeof(unsigned int)); if (offsettable == NULL) { isc_mem_put(mctx, tstart, tlength); return (ISC_R_NOMEMORY); } memset(offsettable, 0, (ocount + oncount) * sizeof(unsigned int)); #endif /* * Merge the two slabs. */ ocurrent = ostart; INSIST(ocount != 0); #if DNS_RDATASET_FIXED oorder = ocurrent[2] * 256 + ocurrent[3]; INSIST(oorder < ocount); #endif rdata_from_slab(&ocurrent, rdclass, type, &ordata); ncurrent = nslab + reservelen + 2; #if DNS_RDATASET_FIXED ncurrent += (4 * oncount); #endif if (ncount > 0) { do { dns_rdata_reset(&nrdata); #if DNS_RDATASET_FIXED norder = ncurrent[2] * 256 + ncurrent[3]; INSIST(norder < oncount); #endif rdata_from_slab(&ncurrent, rdclass, type, &nrdata); } while (rdata_in_slab(oslab, reservelen, rdclass, type, &nrdata)); } while (oadded < ocount || nadded < ncount) { isc_boolean_t fromold; if (oadded == ocount) fromold = ISC_FALSE; else if (nadded == ncount) fromold = ISC_TRUE; else fromold = ISC_TF(compare_rdata(&ordata, &nrdata) < 0); if (fromold) { #if DNS_RDATASET_FIXED offsettable[oorder] = tcurrent - offsetbase; #endif length = ordata.length; data = ordata.data; if (type == dns_rdatatype_rrsig) { length++; data--; } *tcurrent++ = (length & 0xff00) >> 8; *tcurrent++ = (length & 0x00ff); #if DNS_RDATASET_FIXED tcurrent += 2; /* fill in later */ #endif memmove(tcurrent, data, length); tcurrent += length; oadded++; if (oadded < ocount) { dns_rdata_reset(&ordata); #if DNS_RDATASET_FIXED oorder = ocurrent[2] * 256 + ocurrent[3]; INSIST(oorder < ocount); #endif rdata_from_slab(&ocurrent, rdclass, type, &ordata); } } else { #if DNS_RDATASET_FIXED offsettable[ocount + norder] = tcurrent - offsetbase; #endif length = nrdata.length; data = nrdata.data; if (type == dns_rdatatype_rrsig) { length++; data--; } *tcurrent++ = (length & 0xff00) >> 8; *tcurrent++ = (length & 0x00ff); #if DNS_RDATASET_FIXED tcurrent += 2; /* fill in later */ #endif memmove(tcurrent, data, length); tcurrent += length; nadded++; if (nadded < ncount) { do { dns_rdata_reset(&nrdata); #if DNS_RDATASET_FIXED norder = ncurrent[2] * 256 + ncurrent[3]; INSIST(norder < oncount); #endif rdata_from_slab(&ncurrent, rdclass, type, &nrdata); } while (rdata_in_slab(oslab, reservelen, rdclass, type, &nrdata)); } } } #if DNS_RDATASET_FIXED fillin_offsets(offsetbase, offsettable, ocount + oncount); isc_mem_put(mctx, offsettable, (ocount + oncount) * sizeof(unsigned int)); #endif INSIST(tcurrent == tstart + tlength); *tslabp = tstart; return (ISC_R_SUCCESS); } isc_result_t dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab, unsigned int reservelen, isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_rdatatype_t type, unsigned int flags, unsigned char **tslabp) { unsigned char *mcurrent, *sstart, *scurrent, *tstart, *tcurrent; unsigned int mcount, scount, rcount ,count, tlength, tcount, i; dns_rdata_t srdata = DNS_RDATA_INIT; dns_rdata_t mrdata = DNS_RDATA_INIT; #if DNS_RDATASET_FIXED unsigned char *offsetbase; unsigned int *offsettable; unsigned int order; #endif REQUIRE(tslabp != NULL && *tslabp == NULL); REQUIRE(mslab != NULL && sslab != NULL); mcurrent = mslab + reservelen; mcount = *mcurrent++ * 256; mcount += *mcurrent++; scurrent = sslab + reservelen; scount = *scurrent++ * 256; scount += *scurrent++; INSIST(mcount > 0 && scount > 0); /* * Yes, this is inefficient! */ /* * Start figuring out the target length and count. */ tlength = reservelen + 2; tcount = 0; rcount = 0; #if DNS_RDATASET_FIXED mcurrent += 4 * mcount; scurrent += 4 * scount; #endif sstart = scurrent; /* * Add in the length of rdata in the mslab that aren't in * the sslab. */ for (i = 0; i < mcount; i++) { unsigned char *mrdatabegin = mcurrent; rdata_from_slab(&mcurrent, rdclass, type, &mrdata); scurrent = sstart; for (count = 0; count < scount; count++) { dns_rdata_reset(&srdata); rdata_from_slab(&scurrent, rdclass, type, &srdata); if (dns_rdata_compare(&mrdata, &srdata) == 0) break; } if (count == scount) { /* * This rdata isn't in the sslab, and thus isn't * being subtracted. */ tlength += (unsigned int)(mcurrent - mrdatabegin); tcount++; } else rcount++; dns_rdata_reset(&mrdata); } #if DNS_RDATASET_FIXED tlength += (4 * tcount); #endif /* * Check that all the records originally existed. The numeric * check only works as rdataslabs do not contain duplicates. */ if (((flags & DNS_RDATASLAB_EXACT) != 0) && (rcount != scount)) return (DNS_R_NOTEXACT); /* * Don't continue if the new rdataslab would be empty. */ if (tcount == 0) return (DNS_R_NXRRSET); /* * If nothing is going to change, we can stop. */ if (rcount == 0) return (DNS_R_UNCHANGED); /* * Copy the reserved area from the mslab. */ tstart = isc_mem_get(mctx, tlength); if (tstart == NULL) return (ISC_R_NOMEMORY); memmove(tstart, mslab, reservelen); tcurrent = tstart + reservelen; #if DNS_RDATASET_FIXED offsetbase = tcurrent; offsettable = isc_mem_get(mctx, mcount * sizeof(unsigned int)); if (offsettable == NULL) { isc_mem_put(mctx, tstart, tlength); return (ISC_R_NOMEMORY); } memset(offsettable, 0, mcount * sizeof(unsigned int)); #endif /* * Write the new count. */ *tcurrent++ = (tcount & 0xff00) >> 8; *tcurrent++ = (tcount & 0x00ff); #if DNS_RDATASET_FIXED tcurrent += (4 * tcount); #endif /* * Copy the parts of mslab not in sslab. */ mcurrent = mslab + reservelen; mcount = *mcurrent++ * 256; mcount += *mcurrent++; #if DNS_RDATASET_FIXED mcurrent += (4 * mcount); #endif for (i = 0; i < mcount; i++) { unsigned char *mrdatabegin = mcurrent; #if DNS_RDATASET_FIXED order = mcurrent[2] * 256 + mcurrent[3]; INSIST(order < mcount); #endif rdata_from_slab(&mcurrent, rdclass, type, &mrdata); scurrent = sstart; for (count = 0; count < scount; count++) { dns_rdata_reset(&srdata); rdata_from_slab(&scurrent, rdclass, type, &srdata); if (dns_rdata_compare(&mrdata, &srdata) == 0) break; } if (count == scount) { /* * This rdata isn't in the sslab, and thus should be * copied to the tslab. */ unsigned int length; length = (unsigned int)(mcurrent - mrdatabegin); #if DNS_RDATASET_FIXED offsettable[order] = tcurrent - offsetbase; #endif memmove(tcurrent, mrdatabegin, length); tcurrent += length; } dns_rdata_reset(&mrdata); } #if DNS_RDATASET_FIXED fillin_offsets(offsetbase, offsettable, mcount); isc_mem_put(mctx, offsettable, mcount * sizeof(unsigned int)); #endif INSIST(tcurrent == tstart + tlength); *tslabp = tstart; return (ISC_R_SUCCESS); } isc_boolean_t dns_rdataslab_equal(unsigned char *slab1, unsigned char *slab2, unsigned int reservelen) { unsigned char *current1, *current2; unsigned int count1, count2; unsigned int length1, length2; current1 = slab1 + reservelen; count1 = *current1++ * 256; count1 += *current1++; current2 = slab2 + reservelen; count2 = *current2++ * 256; count2 += *current2++; if (count1 != count2) return (ISC_FALSE); #if DNS_RDATASET_FIXED current1 += (4 * count1); current2 += (4 * count2); #endif while (count1 > 0) { length1 = *current1++ * 256; length1 += *current1++; length2 = *current2++ * 256; length2 += *current2++; #if DNS_RDATASET_FIXED current1 += 2; current2 += 2; #endif if (length1 != length2 || memcmp(current1, current2, length1) != 0) return (ISC_FALSE); current1 += length1; current2 += length1; count1--; } return (ISC_TRUE); } isc_boolean_t dns_rdataslab_equalx(unsigned char *slab1, unsigned char *slab2, unsigned int reservelen, dns_rdataclass_t rdclass, dns_rdatatype_t type) { unsigned char *current1, *current2; unsigned int count1, count2; dns_rdata_t rdata1 = DNS_RDATA_INIT; dns_rdata_t rdata2 = DNS_RDATA_INIT; current1 = slab1 + reservelen; count1 = *current1++ * 256; count1 += *current1++; current2 = slab2 + reservelen; count2 = *current2++ * 256; count2 += *current2++; if (count1 != count2) return (ISC_FALSE); #if DNS_RDATASET_FIXED current1 += (4 * count1); current2 += (4 * count2); #endif while (count1-- > 0) { rdata_from_slab(¤t1, rdclass, type, &rdata1); rdata_from_slab(¤t2, rdclass, type, &rdata2); if (dns_rdata_compare(&rdata1, &rdata2) != 0) return (ISC_FALSE); dns_rdata_reset(&rdata1); dns_rdata_reset(&rdata2); } return (ISC_TRUE); } bind9-9.10.3.dfsg.P4/lib/dns/pkcs11.c0000644000470500017500000000264512664710322016200 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef PKCS11CRYPTO #include #include #include #include #include #include "dst_pkcs11.h" isc_result_t dst__pkcs11_toresult(const char *funcname, const char *file, int line, isc_result_t fallback, CK_RV rv) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_CRYPTO, ISC_LOG_WARNING, "%s:%d: %s: Error = 0x%.8lX\n", file, line, funcname, rv); if (rv == CKR_HOST_MEMORY) return (ISC_R_NOMEMORY); return (fallback); } #else /* PKCS11CRYPTO */ #include EMPTY_TRANSLATION_UNIT #endif /* PKCS11CRYPTO */ /*! \file */ bind9-9.10.3.dfsg.P4/lib/dns/dst_pkcs11.h0000644000470500017500000000272412664710322017055 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef DST_PKCS11_H #define DST_PKCS11_H 1 #include #include #include ISC_LANG_BEGINDECLS isc_result_t dst__pkcs11_toresult(const char *funcname, const char *file, int line, isc_result_t fallback, CK_RV rv); #define PK11_CALL(func, args, fallback) \ ((void) (((rv = (func) args) == CKR_OK) || \ ((ret = dst__pkcs11_toresult(#func, __FILE__, __LINE__, \ fallback, rv)), 0))) #define PK11_RET(func, args, fallback) \ ((void) (((rv = (func) args) == CKR_OK) || \ ((ret = dst__pkcs11_toresult(#func, __FILE__, __LINE__, \ fallback, rv)), 0))); \ if (rv != CKR_OK) goto err; ISC_LANG_ENDDECLS #endif /* DST_PKCS11_H */ bind9-9.10.3.dfsg.P4/lib/dns/key.c0000644000470500017500000001040012664710322015652 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: key.c,v 1.11 2011/10/20 21:20:02 marka Exp $ */ #include #include #include #include #include #include #include #include "dst_internal.h" isc_uint16_t dst_region_computeid(const isc_region_t *source, unsigned int alg) { isc_uint32_t ac; const unsigned char *p; int size; REQUIRE(source != NULL); REQUIRE(source->length >= 4); p = source->base; size = source->length; if (alg == DST_ALG_RSAMD5) return ((p[size - 3] << 8) + p[size - 2]); for (ac = 0; size > 1; size -= 2, p += 2) ac += ((*p) << 8) + *(p + 1); if (size > 0) ac += ((*p) << 8); ac += (ac >> 16) & 0xffff; return ((isc_uint16_t)(ac & 0xffff)); } isc_uint16_t dst_region_computerid(const isc_region_t *source, unsigned int alg) { isc_uint32_t ac; const unsigned char *p; int size; REQUIRE(source != NULL); REQUIRE(source->length >= 4); p = source->base; size = source->length; if (alg == DST_ALG_RSAMD5) return ((p[size - 3] << 8) + p[size - 2]); ac = ((*p) << 8) + *(p + 1); ac |= DNS_KEYFLAG_REVOKE; for (size -= 2, p +=2; size > 1; size -= 2, p += 2) ac += ((*p) << 8) + *(p + 1); if (size > 0) ac += ((*p) << 8); ac += (ac >> 16) & 0xffff; return ((isc_uint16_t)(ac & 0xffff)); } dns_name_t * dst_key_name(const dst_key_t *key) { REQUIRE(VALID_KEY(key)); return (key->key_name); } unsigned int dst_key_size(const dst_key_t *key) { REQUIRE(VALID_KEY(key)); return (key->key_size); } unsigned int dst_key_proto(const dst_key_t *key) { REQUIRE(VALID_KEY(key)); return (key->key_proto); } unsigned int dst_key_alg(const dst_key_t *key) { REQUIRE(VALID_KEY(key)); return (key->key_alg); } isc_uint32_t dst_key_flags(const dst_key_t *key) { REQUIRE(VALID_KEY(key)); return (key->key_flags); } dns_keytag_t dst_key_id(const dst_key_t *key) { REQUIRE(VALID_KEY(key)); return (key->key_id); } dns_keytag_t dst_key_rid(const dst_key_t *key) { REQUIRE(VALID_KEY(key)); return (key->key_rid); } dns_rdataclass_t dst_key_class(const dst_key_t *key) { REQUIRE(VALID_KEY(key)); return (key->key_class); } isc_boolean_t dst_key_iszonekey(const dst_key_t *key) { REQUIRE(VALID_KEY(key)); if ((key->key_flags & DNS_KEYTYPE_NOAUTH) != 0) return (ISC_FALSE); if ((key->key_flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE) return (ISC_FALSE); if (key->key_proto != DNS_KEYPROTO_DNSSEC && key->key_proto != DNS_KEYPROTO_ANY) return (ISC_FALSE); return (ISC_TRUE); } isc_boolean_t dst_key_isnullkey(const dst_key_t *key) { REQUIRE(VALID_KEY(key)); if ((key->key_flags & DNS_KEYFLAG_TYPEMASK) != DNS_KEYTYPE_NOKEY) return (ISC_FALSE); if ((key->key_flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE) return (ISC_FALSE); if (key->key_proto != DNS_KEYPROTO_DNSSEC && key->key_proto != DNS_KEYPROTO_ANY) return (ISC_FALSE); return (ISC_TRUE); } void dst_key_setbits(dst_key_t *key, isc_uint16_t bits) { unsigned int maxbits; REQUIRE(VALID_KEY(key)); if (bits != 0) { RUNTIME_CHECK(dst_key_sigsize(key, &maxbits) == ISC_R_SUCCESS); maxbits *= 8; REQUIRE(bits <= maxbits); } key->key_bits = bits; } isc_uint16_t dst_key_getbits(const dst_key_t *key) { REQUIRE(VALID_KEY(key)); return (key->key_bits); } void dst_key_setttl(dst_key_t *key, dns_ttl_t ttl) { REQUIRE(VALID_KEY(key)); key->key_ttl = ttl; } dns_ttl_t dst_key_getttl(const dst_key_t *key) { REQUIRE(VALID_KEY(key)); return (key->key_ttl); } /*! \file */ bind9-9.10.3.dfsg.P4/lib/dns/hmac_link.c0000644000470500017500000012776612664710322017037 0ustar lamontlamont/* * Portions Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * Principal Author: Brian Wellington * $Id: hmac_link.c,v 1.19 2011/01/11 23:47:13 tbox Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include "dst_internal.h" #include "dst_parse.h" static isc_result_t hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data); struct dst_hmacmd5_key { unsigned char key[ISC_MD5_BLOCK_LENGTH]; }; static isc_result_t getkeybits(dst_key_t *key, struct dst_private_element *element) { if (element->length != 2) return (DST_R_INVALIDPRIVATEKEY); key->key_bits = (element->data[0] << 8) + element->data[1]; return (ISC_R_SUCCESS); } static isc_result_t hmacmd5_createctx(dst_key_t *key, dst_context_t *dctx) { isc_hmacmd5_t *hmacmd5ctx; dst_hmacmd5_key_t *hkey = key->keydata.hmacmd5; hmacmd5ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacmd5_t)); if (hmacmd5ctx == NULL) return (ISC_R_NOMEMORY); isc_hmacmd5_init(hmacmd5ctx, hkey->key, ISC_MD5_BLOCK_LENGTH); dctx->ctxdata.hmacmd5ctx = hmacmd5ctx; return (ISC_R_SUCCESS); } static void hmacmd5_destroyctx(dst_context_t *dctx) { isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx; if (hmacmd5ctx != NULL) { isc_hmacmd5_invalidate(hmacmd5ctx); isc_mem_put(dctx->mctx, hmacmd5ctx, sizeof(isc_hmacmd5_t)); dctx->ctxdata.hmacmd5ctx = NULL; } } static isc_result_t hmacmd5_adddata(dst_context_t *dctx, const isc_region_t *data) { isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx; isc_hmacmd5_update(hmacmd5ctx, data->base, data->length); return (ISC_R_SUCCESS); } static isc_result_t hmacmd5_sign(dst_context_t *dctx, isc_buffer_t *sig) { isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx; unsigned char *digest; if (isc_buffer_availablelength(sig) < ISC_MD5_DIGESTLENGTH) return (ISC_R_NOSPACE); digest = isc_buffer_used(sig); isc_hmacmd5_sign(hmacmd5ctx, digest); isc_buffer_add(sig, ISC_MD5_DIGESTLENGTH); return (ISC_R_SUCCESS); } static isc_result_t hmacmd5_verify(dst_context_t *dctx, const isc_region_t *sig) { isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx; if (sig->length > ISC_MD5_DIGESTLENGTH) return (DST_R_VERIFYFAILURE); if (isc_hmacmd5_verify2(hmacmd5ctx, sig->base, sig->length)) return (ISC_R_SUCCESS); else return (DST_R_VERIFYFAILURE); } static isc_boolean_t hmacmd5_compare(const dst_key_t *key1, const dst_key_t *key2) { dst_hmacmd5_key_t *hkey1, *hkey2; hkey1 = key1->keydata.hmacmd5; hkey2 = key2->keydata.hmacmd5; if (hkey1 == NULL && hkey2 == NULL) return (ISC_TRUE); else if (hkey1 == NULL || hkey2 == NULL) return (ISC_FALSE); if (isc_safe_memequal(hkey1->key, hkey2->key, ISC_MD5_BLOCK_LENGTH)) return (ISC_TRUE); else return (ISC_FALSE); } static isc_result_t hmacmd5_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) { isc_buffer_t b; isc_result_t ret; unsigned int bytes; unsigned char data[ISC_MD5_BLOCK_LENGTH]; UNUSED(callback); bytes = (key->key_size + 7) / 8; if (bytes > ISC_MD5_BLOCK_LENGTH) { bytes = ISC_MD5_BLOCK_LENGTH; key->key_size = ISC_MD5_BLOCK_LENGTH * 8; } memset(data, 0, ISC_MD5_BLOCK_LENGTH); ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0)); if (ret != ISC_R_SUCCESS) return (ret); isc_buffer_init(&b, data, bytes); isc_buffer_add(&b, bytes); ret = hmacmd5_fromdns(key, &b); memset(data, 0, ISC_MD5_BLOCK_LENGTH); return (ret); } static isc_boolean_t hmacmd5_isprivate(const dst_key_t *key) { UNUSED(key); return (ISC_TRUE); } static void hmacmd5_destroy(dst_key_t *key) { dst_hmacmd5_key_t *hkey = key->keydata.hmacmd5; memset(hkey, 0, sizeof(dst_hmacmd5_key_t)); isc_mem_put(key->mctx, hkey, sizeof(dst_hmacmd5_key_t)); key->keydata.hmacmd5 = NULL; } static isc_result_t hmacmd5_todns(const dst_key_t *key, isc_buffer_t *data) { dst_hmacmd5_key_t *hkey; unsigned int bytes; REQUIRE(key->keydata.hmacmd5 != NULL); hkey = key->keydata.hmacmd5; bytes = (key->key_size + 7) / 8; if (isc_buffer_availablelength(data) < bytes) return (ISC_R_NOSPACE); isc_buffer_putmem(data, hkey->key, bytes); return (ISC_R_SUCCESS); } static isc_result_t hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data) { dst_hmacmd5_key_t *hkey; int keylen; isc_region_t r; isc_md5_t md5ctx; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); hkey = isc_mem_get(key->mctx, sizeof(dst_hmacmd5_key_t)); if (hkey == NULL) return (ISC_R_NOMEMORY); memset(hkey->key, 0, sizeof(hkey->key)); if (r.length > ISC_MD5_BLOCK_LENGTH) { isc_md5_init(&md5ctx); isc_md5_update(&md5ctx, r.base, r.length); isc_md5_final(&md5ctx, hkey->key); keylen = ISC_MD5_DIGESTLENGTH; } else { memmove(hkey->key, r.base, r.length); keylen = r.length; } key->key_size = keylen * 8; key->keydata.hmacmd5 = hkey; isc_buffer_forward(data, r.length); return (ISC_R_SUCCESS); } static isc_result_t hmacmd5_tofile(const dst_key_t *key, const char *directory) { int cnt = 0; dst_hmacmd5_key_t *hkey; dst_private_t priv; int bytes = (key->key_size + 7) / 8; unsigned char buf[2]; if (key->keydata.hmacmd5 == NULL) return (DST_R_NULLKEY); if (key->external) return (DST_R_EXTERNALKEY); hkey = key->keydata.hmacmd5; priv.elements[cnt].tag = TAG_HMACMD5_KEY; priv.elements[cnt].length = bytes; priv.elements[cnt++].data = hkey->key; buf[0] = (key->key_bits >> 8) & 0xffU; buf[1] = key->key_bits & 0xffU; priv.elements[cnt].tag = TAG_HMACMD5_BITS; priv.elements[cnt].data = buf; priv.elements[cnt++].length = 2; priv.nelements = cnt; return (dst__privstruct_writefile(key, &priv, directory)); } static isc_result_t hmacmd5_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t result, tresult; isc_buffer_t b; isc_mem_t *mctx = key->mctx; unsigned int i; UNUSED(pub); /* read private key file */ result = dst__privstruct_parse(key, DST_ALG_HMACMD5, lexer, mctx, &priv); if (result != ISC_R_SUCCESS) return (result); if (key->external) result = DST_R_EXTERNALKEY; key->key_bits = 0; for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { switch (priv.elements[i].tag) { case TAG_HMACMD5_KEY: isc_buffer_init(&b, priv.elements[i].data, priv.elements[i].length); isc_buffer_add(&b, priv.elements[i].length); tresult = hmacmd5_fromdns(key, &b); if (tresult != ISC_R_SUCCESS) result = tresult; break; case TAG_HMACMD5_BITS: tresult = getkeybits(key, &priv.elements[i]); if (tresult != ISC_R_SUCCESS) result = tresult; break; default: result = DST_R_INVALIDPRIVATEKEY; break; } } dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (result); } static dst_func_t hmacmd5_functions = { hmacmd5_createctx, NULL, /*%< createctx2 */ hmacmd5_destroyctx, hmacmd5_adddata, hmacmd5_sign, hmacmd5_verify, NULL, /*%< verify2 */ NULL, /*%< computesecret */ hmacmd5_compare, NULL, /*%< paramcompare */ hmacmd5_generate, hmacmd5_isprivate, hmacmd5_destroy, hmacmd5_todns, hmacmd5_fromdns, hmacmd5_tofile, hmacmd5_parse, NULL, /*%< cleanup */ NULL, /*%< fromlabel */ NULL, /*%< dump */ NULL, /*%< restore */ }; isc_result_t dst__hmacmd5_init(dst_func_t **funcp) { REQUIRE(funcp != NULL); if (*funcp == NULL) *funcp = &hmacmd5_functions; return (ISC_R_SUCCESS); } static isc_result_t hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data); struct dst_hmacsha1_key { unsigned char key[ISC_SHA1_BLOCK_LENGTH]; }; static isc_result_t hmacsha1_createctx(dst_key_t *key, dst_context_t *dctx) { isc_hmacsha1_t *hmacsha1ctx; dst_hmacsha1_key_t *hkey = key->keydata.hmacsha1; hmacsha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha1_t)); if (hmacsha1ctx == NULL) return (ISC_R_NOMEMORY); isc_hmacsha1_init(hmacsha1ctx, hkey->key, ISC_SHA1_BLOCK_LENGTH); dctx->ctxdata.hmacsha1ctx = hmacsha1ctx; return (ISC_R_SUCCESS); } static void hmacsha1_destroyctx(dst_context_t *dctx) { isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx; if (hmacsha1ctx != NULL) { isc_hmacsha1_invalidate(hmacsha1ctx); isc_mem_put(dctx->mctx, hmacsha1ctx, sizeof(isc_hmacsha1_t)); dctx->ctxdata.hmacsha1ctx = NULL; } } static isc_result_t hmacsha1_adddata(dst_context_t *dctx, const isc_region_t *data) { isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx; isc_hmacsha1_update(hmacsha1ctx, data->base, data->length); return (ISC_R_SUCCESS); } static isc_result_t hmacsha1_sign(dst_context_t *dctx, isc_buffer_t *sig) { isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx; unsigned char *digest; if (isc_buffer_availablelength(sig) < ISC_SHA1_DIGESTLENGTH) return (ISC_R_NOSPACE); digest = isc_buffer_used(sig); isc_hmacsha1_sign(hmacsha1ctx, digest, ISC_SHA1_DIGESTLENGTH); isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH); return (ISC_R_SUCCESS); } static isc_result_t hmacsha1_verify(dst_context_t *dctx, const isc_region_t *sig) { isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx; if (sig->length > ISC_SHA1_DIGESTLENGTH || sig->length == 0) return (DST_R_VERIFYFAILURE); if (isc_hmacsha1_verify(hmacsha1ctx, sig->base, sig->length)) return (ISC_R_SUCCESS); else return (DST_R_VERIFYFAILURE); } static isc_boolean_t hmacsha1_compare(const dst_key_t *key1, const dst_key_t *key2) { dst_hmacsha1_key_t *hkey1, *hkey2; hkey1 = key1->keydata.hmacsha1; hkey2 = key2->keydata.hmacsha1; if (hkey1 == NULL && hkey2 == NULL) return (ISC_TRUE); else if (hkey1 == NULL || hkey2 == NULL) return (ISC_FALSE); if (isc_safe_memequal(hkey1->key, hkey2->key, ISC_SHA1_BLOCK_LENGTH)) return (ISC_TRUE); else return (ISC_FALSE); } static isc_result_t hmacsha1_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) { isc_buffer_t b; isc_result_t ret; unsigned int bytes; unsigned char data[ISC_SHA1_BLOCK_LENGTH]; UNUSED(callback); bytes = (key->key_size + 7) / 8; if (bytes > ISC_SHA1_BLOCK_LENGTH) { bytes = ISC_SHA1_BLOCK_LENGTH; key->key_size = ISC_SHA1_BLOCK_LENGTH * 8; } memset(data, 0, ISC_SHA1_BLOCK_LENGTH); ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0)); if (ret != ISC_R_SUCCESS) return (ret); isc_buffer_init(&b, data, bytes); isc_buffer_add(&b, bytes); ret = hmacsha1_fromdns(key, &b); memset(data, 0, ISC_SHA1_BLOCK_LENGTH); return (ret); } static isc_boolean_t hmacsha1_isprivate(const dst_key_t *key) { UNUSED(key); return (ISC_TRUE); } static void hmacsha1_destroy(dst_key_t *key) { dst_hmacsha1_key_t *hkey = key->keydata.hmacsha1; memset(hkey, 0, sizeof(dst_hmacsha1_key_t)); isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha1_key_t)); key->keydata.hmacsha1 = NULL; } static isc_result_t hmacsha1_todns(const dst_key_t *key, isc_buffer_t *data) { dst_hmacsha1_key_t *hkey; unsigned int bytes; REQUIRE(key->keydata.hmacsha1 != NULL); hkey = key->keydata.hmacsha1; bytes = (key->key_size + 7) / 8; if (isc_buffer_availablelength(data) < bytes) return (ISC_R_NOSPACE); isc_buffer_putmem(data, hkey->key, bytes); return (ISC_R_SUCCESS); } static isc_result_t hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data) { dst_hmacsha1_key_t *hkey; int keylen; isc_region_t r; isc_sha1_t sha1ctx; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha1_key_t)); if (hkey == NULL) return (ISC_R_NOMEMORY); memset(hkey->key, 0, sizeof(hkey->key)); if (r.length > ISC_SHA1_BLOCK_LENGTH) { isc_sha1_init(&sha1ctx); isc_sha1_update(&sha1ctx, r.base, r.length); isc_sha1_final(&sha1ctx, hkey->key); keylen = ISC_SHA1_DIGESTLENGTH; } else { memmove(hkey->key, r.base, r.length); keylen = r.length; } key->key_size = keylen * 8; key->keydata.hmacsha1 = hkey; isc_buffer_forward(data, r.length); return (ISC_R_SUCCESS); } static isc_result_t hmacsha1_tofile(const dst_key_t *key, const char *directory) { int cnt = 0; dst_hmacsha1_key_t *hkey; dst_private_t priv; int bytes = (key->key_size + 7) / 8; unsigned char buf[2]; if (key->keydata.hmacsha1 == NULL) return (DST_R_NULLKEY); if (key->external) return (DST_R_EXTERNALKEY); hkey = key->keydata.hmacsha1; priv.elements[cnt].tag = TAG_HMACSHA1_KEY; priv.elements[cnt].length = bytes; priv.elements[cnt++].data = hkey->key; buf[0] = (key->key_bits >> 8) & 0xffU; buf[1] = key->key_bits & 0xffU; priv.elements[cnt].tag = TAG_HMACSHA1_BITS; priv.elements[cnt].data = buf; priv.elements[cnt++].length = 2; priv.nelements = cnt; return (dst__privstruct_writefile(key, &priv, directory)); } static isc_result_t hmacsha1_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t result, tresult; isc_buffer_t b; isc_mem_t *mctx = key->mctx; unsigned int i; UNUSED(pub); /* read private key file */ result = dst__privstruct_parse(key, DST_ALG_HMACSHA1, lexer, mctx, &priv); if (result != ISC_R_SUCCESS) return (result); if (key->external) result = DST_R_EXTERNALKEY; key->key_bits = 0; for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { switch (priv.elements[i].tag) { case TAG_HMACSHA1_KEY: isc_buffer_init(&b, priv.elements[i].data, priv.elements[i].length); isc_buffer_add(&b, priv.elements[i].length); tresult = hmacsha1_fromdns(key, &b); if (tresult != ISC_R_SUCCESS) result = tresult; break; case TAG_HMACSHA1_BITS: tresult = getkeybits(key, &priv.elements[i]); if (tresult != ISC_R_SUCCESS) result = tresult; break; default: result = DST_R_INVALIDPRIVATEKEY; break; } } dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (result); } static dst_func_t hmacsha1_functions = { hmacsha1_createctx, NULL, /*%< createctx2 */ hmacsha1_destroyctx, hmacsha1_adddata, hmacsha1_sign, hmacsha1_verify, NULL, /* verify2 */ NULL, /* computesecret */ hmacsha1_compare, NULL, /* paramcompare */ hmacsha1_generate, hmacsha1_isprivate, hmacsha1_destroy, hmacsha1_todns, hmacsha1_fromdns, hmacsha1_tofile, hmacsha1_parse, NULL, /* cleanup */ NULL, /* fromlabel */ NULL, /* dump */ NULL, /* restore */ }; isc_result_t dst__hmacsha1_init(dst_func_t **funcp) { REQUIRE(funcp != NULL); if (*funcp == NULL) *funcp = &hmacsha1_functions; return (ISC_R_SUCCESS); } static isc_result_t hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data); struct dst_hmacsha224_key { unsigned char key[ISC_SHA224_BLOCK_LENGTH]; }; static isc_result_t hmacsha224_createctx(dst_key_t *key, dst_context_t *dctx) { isc_hmacsha224_t *hmacsha224ctx; dst_hmacsha224_key_t *hkey = key->keydata.hmacsha224; hmacsha224ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha224_t)); if (hmacsha224ctx == NULL) return (ISC_R_NOMEMORY); isc_hmacsha224_init(hmacsha224ctx, hkey->key, ISC_SHA224_BLOCK_LENGTH); dctx->ctxdata.hmacsha224ctx = hmacsha224ctx; return (ISC_R_SUCCESS); } static void hmacsha224_destroyctx(dst_context_t *dctx) { isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx; if (hmacsha224ctx != NULL) { isc_hmacsha224_invalidate(hmacsha224ctx); isc_mem_put(dctx->mctx, hmacsha224ctx, sizeof(isc_hmacsha224_t)); dctx->ctxdata.hmacsha224ctx = NULL; } } static isc_result_t hmacsha224_adddata(dst_context_t *dctx, const isc_region_t *data) { isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx; isc_hmacsha224_update(hmacsha224ctx, data->base, data->length); return (ISC_R_SUCCESS); } static isc_result_t hmacsha224_sign(dst_context_t *dctx, isc_buffer_t *sig) { isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx; unsigned char *digest; if (isc_buffer_availablelength(sig) < ISC_SHA224_DIGESTLENGTH) return (ISC_R_NOSPACE); digest = isc_buffer_used(sig); isc_hmacsha224_sign(hmacsha224ctx, digest, ISC_SHA224_DIGESTLENGTH); isc_buffer_add(sig, ISC_SHA224_DIGESTLENGTH); return (ISC_R_SUCCESS); } static isc_result_t hmacsha224_verify(dst_context_t *dctx, const isc_region_t *sig) { isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx; if (sig->length > ISC_SHA224_DIGESTLENGTH || sig->length == 0) return (DST_R_VERIFYFAILURE); if (isc_hmacsha224_verify(hmacsha224ctx, sig->base, sig->length)) return (ISC_R_SUCCESS); else return (DST_R_VERIFYFAILURE); } static isc_boolean_t hmacsha224_compare(const dst_key_t *key1, const dst_key_t *key2) { dst_hmacsha224_key_t *hkey1, *hkey2; hkey1 = key1->keydata.hmacsha224; hkey2 = key2->keydata.hmacsha224; if (hkey1 == NULL && hkey2 == NULL) return (ISC_TRUE); else if (hkey1 == NULL || hkey2 == NULL) return (ISC_FALSE); if (isc_safe_memequal(hkey1->key, hkey2->key, ISC_SHA224_BLOCK_LENGTH)) return (ISC_TRUE); else return (ISC_FALSE); } static isc_result_t hmacsha224_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) { isc_buffer_t b; isc_result_t ret; unsigned int bytes; unsigned char data[ISC_SHA224_BLOCK_LENGTH]; UNUSED(callback); bytes = (key->key_size + 7) / 8; if (bytes > ISC_SHA224_BLOCK_LENGTH) { bytes = ISC_SHA224_BLOCK_LENGTH; key->key_size = ISC_SHA224_BLOCK_LENGTH * 8; } memset(data, 0, ISC_SHA224_BLOCK_LENGTH); ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0)); if (ret != ISC_R_SUCCESS) return (ret); isc_buffer_init(&b, data, bytes); isc_buffer_add(&b, bytes); ret = hmacsha224_fromdns(key, &b); memset(data, 0, ISC_SHA224_BLOCK_LENGTH); return (ret); } static isc_boolean_t hmacsha224_isprivate(const dst_key_t *key) { UNUSED(key); return (ISC_TRUE); } static void hmacsha224_destroy(dst_key_t *key) { dst_hmacsha224_key_t *hkey = key->keydata.hmacsha224; memset(hkey, 0, sizeof(dst_hmacsha224_key_t)); isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha224_key_t)); key->keydata.hmacsha224 = NULL; } static isc_result_t hmacsha224_todns(const dst_key_t *key, isc_buffer_t *data) { dst_hmacsha224_key_t *hkey; unsigned int bytes; REQUIRE(key->keydata.hmacsha224 != NULL); hkey = key->keydata.hmacsha224; bytes = (key->key_size + 7) / 8; if (isc_buffer_availablelength(data) < bytes) return (ISC_R_NOSPACE); isc_buffer_putmem(data, hkey->key, bytes); return (ISC_R_SUCCESS); } static isc_result_t hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data) { dst_hmacsha224_key_t *hkey; int keylen; isc_region_t r; isc_sha224_t sha224ctx; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha224_key_t)); if (hkey == NULL) return (ISC_R_NOMEMORY); memset(hkey->key, 0, sizeof(hkey->key)); if (r.length > ISC_SHA224_BLOCK_LENGTH) { isc_sha224_init(&sha224ctx); isc_sha224_update(&sha224ctx, r.base, r.length); isc_sha224_final(hkey->key, &sha224ctx); keylen = ISC_SHA224_DIGESTLENGTH; } else { memmove(hkey->key, r.base, r.length); keylen = r.length; } key->key_size = keylen * 8; key->keydata.hmacsha224 = hkey; isc_buffer_forward(data, r.length); return (ISC_R_SUCCESS); } static isc_result_t hmacsha224_tofile(const dst_key_t *key, const char *directory) { int cnt = 0; dst_hmacsha224_key_t *hkey; dst_private_t priv; int bytes = (key->key_size + 7) / 8; unsigned char buf[2]; if (key->keydata.hmacsha224 == NULL) return (DST_R_NULLKEY); if (key->external) return (DST_R_EXTERNALKEY); hkey = key->keydata.hmacsha224; priv.elements[cnt].tag = TAG_HMACSHA224_KEY; priv.elements[cnt].length = bytes; priv.elements[cnt++].data = hkey->key; buf[0] = (key->key_bits >> 8) & 0xffU; buf[1] = key->key_bits & 0xffU; priv.elements[cnt].tag = TAG_HMACSHA224_BITS; priv.elements[cnt].data = buf; priv.elements[cnt++].length = 2; priv.nelements = cnt; return (dst__privstruct_writefile(key, &priv, directory)); } static isc_result_t hmacsha224_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t result, tresult; isc_buffer_t b; isc_mem_t *mctx = key->mctx; unsigned int i; UNUSED(pub); /* read private key file */ result = dst__privstruct_parse(key, DST_ALG_HMACSHA224, lexer, mctx, &priv); if (result != ISC_R_SUCCESS) return (result); if (key->external) result = DST_R_EXTERNALKEY; key->key_bits = 0; for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { switch (priv.elements[i].tag) { case TAG_HMACSHA224_KEY: isc_buffer_init(&b, priv.elements[i].data, priv.elements[i].length); isc_buffer_add(&b, priv.elements[i].length); tresult = hmacsha224_fromdns(key, &b); if (tresult != ISC_R_SUCCESS) result = tresult; break; case TAG_HMACSHA224_BITS: tresult = getkeybits(key, &priv.elements[i]); if (tresult != ISC_R_SUCCESS) result = tresult; break; default: result = DST_R_INVALIDPRIVATEKEY; break; } } dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (result); } static dst_func_t hmacsha224_functions = { hmacsha224_createctx, NULL, /*%< createctx2 */ hmacsha224_destroyctx, hmacsha224_adddata, hmacsha224_sign, hmacsha224_verify, NULL, /* verify2 */ NULL, /* computesecret */ hmacsha224_compare, NULL, /* paramcompare */ hmacsha224_generate, hmacsha224_isprivate, hmacsha224_destroy, hmacsha224_todns, hmacsha224_fromdns, hmacsha224_tofile, hmacsha224_parse, NULL, /* cleanup */ NULL, /* fromlabel */ NULL, /* dump */ NULL, /* restore */ }; isc_result_t dst__hmacsha224_init(dst_func_t **funcp) { REQUIRE(funcp != NULL); if (*funcp == NULL) *funcp = &hmacsha224_functions; return (ISC_R_SUCCESS); } static isc_result_t hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data); struct dst_hmacsha256_key { unsigned char key[ISC_SHA256_BLOCK_LENGTH]; }; static isc_result_t hmacsha256_createctx(dst_key_t *key, dst_context_t *dctx) { isc_hmacsha256_t *hmacsha256ctx; dst_hmacsha256_key_t *hkey = key->keydata.hmacsha256; hmacsha256ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha256_t)); if (hmacsha256ctx == NULL) return (ISC_R_NOMEMORY); isc_hmacsha256_init(hmacsha256ctx, hkey->key, ISC_SHA256_BLOCK_LENGTH); dctx->ctxdata.hmacsha256ctx = hmacsha256ctx; return (ISC_R_SUCCESS); } static void hmacsha256_destroyctx(dst_context_t *dctx) { isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx; if (hmacsha256ctx != NULL) { isc_hmacsha256_invalidate(hmacsha256ctx); isc_mem_put(dctx->mctx, hmacsha256ctx, sizeof(isc_hmacsha256_t)); dctx->ctxdata.hmacsha256ctx = NULL; } } static isc_result_t hmacsha256_adddata(dst_context_t *dctx, const isc_region_t *data) { isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx; isc_hmacsha256_update(hmacsha256ctx, data->base, data->length); return (ISC_R_SUCCESS); } static isc_result_t hmacsha256_sign(dst_context_t *dctx, isc_buffer_t *sig) { isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx; unsigned char *digest; if (isc_buffer_availablelength(sig) < ISC_SHA256_DIGESTLENGTH) return (ISC_R_NOSPACE); digest = isc_buffer_used(sig); isc_hmacsha256_sign(hmacsha256ctx, digest, ISC_SHA256_DIGESTLENGTH); isc_buffer_add(sig, ISC_SHA256_DIGESTLENGTH); return (ISC_R_SUCCESS); } static isc_result_t hmacsha256_verify(dst_context_t *dctx, const isc_region_t *sig) { isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx; if (sig->length > ISC_SHA256_DIGESTLENGTH || sig->length == 0) return (DST_R_VERIFYFAILURE); if (isc_hmacsha256_verify(hmacsha256ctx, sig->base, sig->length)) return (ISC_R_SUCCESS); else return (DST_R_VERIFYFAILURE); } static isc_boolean_t hmacsha256_compare(const dst_key_t *key1, const dst_key_t *key2) { dst_hmacsha256_key_t *hkey1, *hkey2; hkey1 = key1->keydata.hmacsha256; hkey2 = key2->keydata.hmacsha256; if (hkey1 == NULL && hkey2 == NULL) return (ISC_TRUE); else if (hkey1 == NULL || hkey2 == NULL) return (ISC_FALSE); if (isc_safe_memequal(hkey1->key, hkey2->key, ISC_SHA256_BLOCK_LENGTH)) return (ISC_TRUE); else return (ISC_FALSE); } static isc_result_t hmacsha256_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) { isc_buffer_t b; isc_result_t ret; unsigned int bytes; unsigned char data[ISC_SHA256_BLOCK_LENGTH]; UNUSED(callback); bytes = (key->key_size + 7) / 8; if (bytes > ISC_SHA256_BLOCK_LENGTH) { bytes = ISC_SHA256_BLOCK_LENGTH; key->key_size = ISC_SHA256_BLOCK_LENGTH * 8; } memset(data, 0, ISC_SHA256_BLOCK_LENGTH); ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0)); if (ret != ISC_R_SUCCESS) return (ret); isc_buffer_init(&b, data, bytes); isc_buffer_add(&b, bytes); ret = hmacsha256_fromdns(key, &b); memset(data, 0, ISC_SHA256_BLOCK_LENGTH); return (ret); } static isc_boolean_t hmacsha256_isprivate(const dst_key_t *key) { UNUSED(key); return (ISC_TRUE); } static void hmacsha256_destroy(dst_key_t *key) { dst_hmacsha256_key_t *hkey = key->keydata.hmacsha256; memset(hkey, 0, sizeof(dst_hmacsha256_key_t)); isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha256_key_t)); key->keydata.hmacsha256 = NULL; } static isc_result_t hmacsha256_todns(const dst_key_t *key, isc_buffer_t *data) { dst_hmacsha256_key_t *hkey; unsigned int bytes; REQUIRE(key->keydata.hmacsha256 != NULL); hkey = key->keydata.hmacsha256; bytes = (key->key_size + 7) / 8; if (isc_buffer_availablelength(data) < bytes) return (ISC_R_NOSPACE); isc_buffer_putmem(data, hkey->key, bytes); return (ISC_R_SUCCESS); } static isc_result_t hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data) { dst_hmacsha256_key_t *hkey; int keylen; isc_region_t r; isc_sha256_t sha256ctx; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha256_key_t)); if (hkey == NULL) return (ISC_R_NOMEMORY); memset(hkey->key, 0, sizeof(hkey->key)); if (r.length > ISC_SHA256_BLOCK_LENGTH) { isc_sha256_init(&sha256ctx); isc_sha256_update(&sha256ctx, r.base, r.length); isc_sha256_final(hkey->key, &sha256ctx); keylen = ISC_SHA256_DIGESTLENGTH; } else { memmove(hkey->key, r.base, r.length); keylen = r.length; } key->key_size = keylen * 8; key->keydata.hmacsha256 = hkey; isc_buffer_forward(data, r.length); return (ISC_R_SUCCESS); } static isc_result_t hmacsha256_tofile(const dst_key_t *key, const char *directory) { int cnt = 0; dst_hmacsha256_key_t *hkey; dst_private_t priv; int bytes = (key->key_size + 7) / 8; unsigned char buf[2]; if (key->keydata.hmacsha256 == NULL) return (DST_R_NULLKEY); if (key->external) return (DST_R_EXTERNALKEY); hkey = key->keydata.hmacsha256; priv.elements[cnt].tag = TAG_HMACSHA256_KEY; priv.elements[cnt].length = bytes; priv.elements[cnt++].data = hkey->key; buf[0] = (key->key_bits >> 8) & 0xffU; buf[1] = key->key_bits & 0xffU; priv.elements[cnt].tag = TAG_HMACSHA256_BITS; priv.elements[cnt].data = buf; priv.elements[cnt++].length = 2; priv.nelements = cnt; return (dst__privstruct_writefile(key, &priv, directory)); } static isc_result_t hmacsha256_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t result, tresult; isc_buffer_t b; isc_mem_t *mctx = key->mctx; unsigned int i; UNUSED(pub); /* read private key file */ result = dst__privstruct_parse(key, DST_ALG_HMACSHA256, lexer, mctx, &priv); if (result != ISC_R_SUCCESS) return (result); if (key->external) result = DST_R_EXTERNALKEY; key->key_bits = 0; for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { switch (priv.elements[i].tag) { case TAG_HMACSHA256_KEY: isc_buffer_init(&b, priv.elements[i].data, priv.elements[i].length); isc_buffer_add(&b, priv.elements[i].length); tresult = hmacsha256_fromdns(key, &b); if (tresult != ISC_R_SUCCESS) result = tresult; break; case TAG_HMACSHA256_BITS: tresult = getkeybits(key, &priv.elements[i]); if (tresult != ISC_R_SUCCESS) result = tresult; break; default: result = DST_R_INVALIDPRIVATEKEY; break; } } dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (result); } static dst_func_t hmacsha256_functions = { hmacsha256_createctx, NULL, /*%< createctx2 */ hmacsha256_destroyctx, hmacsha256_adddata, hmacsha256_sign, hmacsha256_verify, NULL, /* verify2 */ NULL, /* computesecret */ hmacsha256_compare, NULL, /* paramcompare */ hmacsha256_generate, hmacsha256_isprivate, hmacsha256_destroy, hmacsha256_todns, hmacsha256_fromdns, hmacsha256_tofile, hmacsha256_parse, NULL, /* cleanup */ NULL, /* fromlabel */ NULL, /* dump */ NULL, /* restore */ }; isc_result_t dst__hmacsha256_init(dst_func_t **funcp) { REQUIRE(funcp != NULL); if (*funcp == NULL) *funcp = &hmacsha256_functions; return (ISC_R_SUCCESS); } static isc_result_t hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data); struct dst_hmacsha384_key { unsigned char key[ISC_SHA384_BLOCK_LENGTH]; }; static isc_result_t hmacsha384_createctx(dst_key_t *key, dst_context_t *dctx) { isc_hmacsha384_t *hmacsha384ctx; dst_hmacsha384_key_t *hkey = key->keydata.hmacsha384; hmacsha384ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha384_t)); if (hmacsha384ctx == NULL) return (ISC_R_NOMEMORY); isc_hmacsha384_init(hmacsha384ctx, hkey->key, ISC_SHA384_BLOCK_LENGTH); dctx->ctxdata.hmacsha384ctx = hmacsha384ctx; return (ISC_R_SUCCESS); } static void hmacsha384_destroyctx(dst_context_t *dctx) { isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx; if (hmacsha384ctx != NULL) { isc_hmacsha384_invalidate(hmacsha384ctx); isc_mem_put(dctx->mctx, hmacsha384ctx, sizeof(isc_hmacsha384_t)); dctx->ctxdata.hmacsha384ctx = NULL; } } static isc_result_t hmacsha384_adddata(dst_context_t *dctx, const isc_region_t *data) { isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx; isc_hmacsha384_update(hmacsha384ctx, data->base, data->length); return (ISC_R_SUCCESS); } static isc_result_t hmacsha384_sign(dst_context_t *dctx, isc_buffer_t *sig) { isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx; unsigned char *digest; if (isc_buffer_availablelength(sig) < ISC_SHA384_DIGESTLENGTH) return (ISC_R_NOSPACE); digest = isc_buffer_used(sig); isc_hmacsha384_sign(hmacsha384ctx, digest, ISC_SHA384_DIGESTLENGTH); isc_buffer_add(sig, ISC_SHA384_DIGESTLENGTH); return (ISC_R_SUCCESS); } static isc_result_t hmacsha384_verify(dst_context_t *dctx, const isc_region_t *sig) { isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx; if (sig->length > ISC_SHA384_DIGESTLENGTH || sig->length == 0) return (DST_R_VERIFYFAILURE); if (isc_hmacsha384_verify(hmacsha384ctx, sig->base, sig->length)) return (ISC_R_SUCCESS); else return (DST_R_VERIFYFAILURE); } static isc_boolean_t hmacsha384_compare(const dst_key_t *key1, const dst_key_t *key2) { dst_hmacsha384_key_t *hkey1, *hkey2; hkey1 = key1->keydata.hmacsha384; hkey2 = key2->keydata.hmacsha384; if (hkey1 == NULL && hkey2 == NULL) return (ISC_TRUE); else if (hkey1 == NULL || hkey2 == NULL) return (ISC_FALSE); if (isc_safe_memequal(hkey1->key, hkey2->key, ISC_SHA384_BLOCK_LENGTH)) return (ISC_TRUE); else return (ISC_FALSE); } static isc_result_t hmacsha384_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) { isc_buffer_t b; isc_result_t ret; unsigned int bytes; unsigned char data[ISC_SHA384_BLOCK_LENGTH]; UNUSED(callback); bytes = (key->key_size + 7) / 8; if (bytes > ISC_SHA384_BLOCK_LENGTH) { bytes = ISC_SHA384_BLOCK_LENGTH; key->key_size = ISC_SHA384_BLOCK_LENGTH * 8; } memset(data, 0, ISC_SHA384_BLOCK_LENGTH); ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0)); if (ret != ISC_R_SUCCESS) return (ret); isc_buffer_init(&b, data, bytes); isc_buffer_add(&b, bytes); ret = hmacsha384_fromdns(key, &b); memset(data, 0, ISC_SHA384_BLOCK_LENGTH); return (ret); } static isc_boolean_t hmacsha384_isprivate(const dst_key_t *key) { UNUSED(key); return (ISC_TRUE); } static void hmacsha384_destroy(dst_key_t *key) { dst_hmacsha384_key_t *hkey = key->keydata.hmacsha384; memset(hkey, 0, sizeof(dst_hmacsha384_key_t)); isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha384_key_t)); key->keydata.hmacsha384 = NULL; } static isc_result_t hmacsha384_todns(const dst_key_t *key, isc_buffer_t *data) { dst_hmacsha384_key_t *hkey; unsigned int bytes; REQUIRE(key->keydata.hmacsha384 != NULL); hkey = key->keydata.hmacsha384; bytes = (key->key_size + 7) / 8; if (isc_buffer_availablelength(data) < bytes) return (ISC_R_NOSPACE); isc_buffer_putmem(data, hkey->key, bytes); return (ISC_R_SUCCESS); } static isc_result_t hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data) { dst_hmacsha384_key_t *hkey; int keylen; isc_region_t r; isc_sha384_t sha384ctx; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha384_key_t)); if (hkey == NULL) return (ISC_R_NOMEMORY); memset(hkey->key, 0, sizeof(hkey->key)); if (r.length > ISC_SHA384_BLOCK_LENGTH) { isc_sha384_init(&sha384ctx); isc_sha384_update(&sha384ctx, r.base, r.length); isc_sha384_final(hkey->key, &sha384ctx); keylen = ISC_SHA384_DIGESTLENGTH; } else { memmove(hkey->key, r.base, r.length); keylen = r.length; } key->key_size = keylen * 8; key->keydata.hmacsha384 = hkey; isc_buffer_forward(data, r.length); return (ISC_R_SUCCESS); } static isc_result_t hmacsha384_tofile(const dst_key_t *key, const char *directory) { int cnt = 0; dst_hmacsha384_key_t *hkey; dst_private_t priv; int bytes = (key->key_size + 7) / 8; unsigned char buf[2]; if (key->keydata.hmacsha384 == NULL) return (DST_R_NULLKEY); if (key->external) return (DST_R_EXTERNALKEY); hkey = key->keydata.hmacsha384; priv.elements[cnt].tag = TAG_HMACSHA384_KEY; priv.elements[cnt].length = bytes; priv.elements[cnt++].data = hkey->key; buf[0] = (key->key_bits >> 8) & 0xffU; buf[1] = key->key_bits & 0xffU; priv.elements[cnt].tag = TAG_HMACSHA384_BITS; priv.elements[cnt].data = buf; priv.elements[cnt++].length = 2; priv.nelements = cnt; return (dst__privstruct_writefile(key, &priv, directory)); } static isc_result_t hmacsha384_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t result, tresult; isc_buffer_t b; isc_mem_t *mctx = key->mctx; unsigned int i; UNUSED(pub); /* read private key file */ result = dst__privstruct_parse(key, DST_ALG_HMACSHA384, lexer, mctx, &priv); if (result != ISC_R_SUCCESS) return (result); if (key->external) result = DST_R_EXTERNALKEY; key->key_bits = 0; for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { switch (priv.elements[i].tag) { case TAG_HMACSHA384_KEY: isc_buffer_init(&b, priv.elements[i].data, priv.elements[i].length); isc_buffer_add(&b, priv.elements[i].length); tresult = hmacsha384_fromdns(key, &b); if (tresult != ISC_R_SUCCESS) result = tresult; break; case TAG_HMACSHA384_BITS: tresult = getkeybits(key, &priv.elements[i]); if (tresult != ISC_R_SUCCESS) result = tresult; break; default: result = DST_R_INVALIDPRIVATEKEY; break; } } dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (result); } static dst_func_t hmacsha384_functions = { hmacsha384_createctx, NULL, /*%< createctx2 */ hmacsha384_destroyctx, hmacsha384_adddata, hmacsha384_sign, hmacsha384_verify, NULL, /* verify2 */ NULL, /* computesecret */ hmacsha384_compare, NULL, /* paramcompare */ hmacsha384_generate, hmacsha384_isprivate, hmacsha384_destroy, hmacsha384_todns, hmacsha384_fromdns, hmacsha384_tofile, hmacsha384_parse, NULL, /* cleanup */ NULL, /* fromlabel */ NULL, /* dump */ NULL, /* restore */ }; isc_result_t dst__hmacsha384_init(dst_func_t **funcp) { REQUIRE(funcp != NULL); if (*funcp == NULL) *funcp = &hmacsha384_functions; return (ISC_R_SUCCESS); } static isc_result_t hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data); struct dst_hmacsha512_key { unsigned char key[ISC_SHA512_BLOCK_LENGTH]; }; static isc_result_t hmacsha512_createctx(dst_key_t *key, dst_context_t *dctx) { isc_hmacsha512_t *hmacsha512ctx; dst_hmacsha512_key_t *hkey = key->keydata.hmacsha512; hmacsha512ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha512_t)); if (hmacsha512ctx == NULL) return (ISC_R_NOMEMORY); isc_hmacsha512_init(hmacsha512ctx, hkey->key, ISC_SHA512_BLOCK_LENGTH); dctx->ctxdata.hmacsha512ctx = hmacsha512ctx; return (ISC_R_SUCCESS); } static void hmacsha512_destroyctx(dst_context_t *dctx) { isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx; if (hmacsha512ctx != NULL) { isc_hmacsha512_invalidate(hmacsha512ctx); isc_mem_put(dctx->mctx, hmacsha512ctx, sizeof(isc_hmacsha512_t)); dctx->ctxdata.hmacsha512ctx = NULL; } } static isc_result_t hmacsha512_adddata(dst_context_t *dctx, const isc_region_t *data) { isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx; isc_hmacsha512_update(hmacsha512ctx, data->base, data->length); return (ISC_R_SUCCESS); } static isc_result_t hmacsha512_sign(dst_context_t *dctx, isc_buffer_t *sig) { isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx; unsigned char *digest; if (isc_buffer_availablelength(sig) < ISC_SHA512_DIGESTLENGTH) return (ISC_R_NOSPACE); digest = isc_buffer_used(sig); isc_hmacsha512_sign(hmacsha512ctx, digest, ISC_SHA512_DIGESTLENGTH); isc_buffer_add(sig, ISC_SHA512_DIGESTLENGTH); return (ISC_R_SUCCESS); } static isc_result_t hmacsha512_verify(dst_context_t *dctx, const isc_region_t *sig) { isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx; if (sig->length > ISC_SHA512_DIGESTLENGTH || sig->length == 0) return (DST_R_VERIFYFAILURE); if (isc_hmacsha512_verify(hmacsha512ctx, sig->base, sig->length)) return (ISC_R_SUCCESS); else return (DST_R_VERIFYFAILURE); } static isc_boolean_t hmacsha512_compare(const dst_key_t *key1, const dst_key_t *key2) { dst_hmacsha512_key_t *hkey1, *hkey2; hkey1 = key1->keydata.hmacsha512; hkey2 = key2->keydata.hmacsha512; if (hkey1 == NULL && hkey2 == NULL) return (ISC_TRUE); else if (hkey1 == NULL || hkey2 == NULL) return (ISC_FALSE); if (isc_safe_memequal(hkey1->key, hkey2->key, ISC_SHA512_BLOCK_LENGTH)) return (ISC_TRUE); else return (ISC_FALSE); } static isc_result_t hmacsha512_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) { isc_buffer_t b; isc_result_t ret; unsigned int bytes; unsigned char data[ISC_SHA512_BLOCK_LENGTH]; UNUSED(callback); bytes = (key->key_size + 7) / 8; if (bytes > ISC_SHA512_BLOCK_LENGTH) { bytes = ISC_SHA512_BLOCK_LENGTH; key->key_size = ISC_SHA512_BLOCK_LENGTH * 8; } memset(data, 0, ISC_SHA512_BLOCK_LENGTH); ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0)); if (ret != ISC_R_SUCCESS) return (ret); isc_buffer_init(&b, data, bytes); isc_buffer_add(&b, bytes); ret = hmacsha512_fromdns(key, &b); memset(data, 0, ISC_SHA512_BLOCK_LENGTH); return (ret); } static isc_boolean_t hmacsha512_isprivate(const dst_key_t *key) { UNUSED(key); return (ISC_TRUE); } static void hmacsha512_destroy(dst_key_t *key) { dst_hmacsha512_key_t *hkey = key->keydata.hmacsha512; memset(hkey, 0, sizeof(dst_hmacsha512_key_t)); isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha512_key_t)); key->keydata.hmacsha512 = NULL; } static isc_result_t hmacsha512_todns(const dst_key_t *key, isc_buffer_t *data) { dst_hmacsha512_key_t *hkey; unsigned int bytes; REQUIRE(key->keydata.hmacsha512 != NULL); hkey = key->keydata.hmacsha512; bytes = (key->key_size + 7) / 8; if (isc_buffer_availablelength(data) < bytes) return (ISC_R_NOSPACE); isc_buffer_putmem(data, hkey->key, bytes); return (ISC_R_SUCCESS); } static isc_result_t hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data) { dst_hmacsha512_key_t *hkey; int keylen; isc_region_t r; isc_sha512_t sha512ctx; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha512_key_t)); if (hkey == NULL) return (ISC_R_NOMEMORY); memset(hkey->key, 0, sizeof(hkey->key)); if (r.length > ISC_SHA512_BLOCK_LENGTH) { isc_sha512_init(&sha512ctx); isc_sha512_update(&sha512ctx, r.base, r.length); isc_sha512_final(hkey->key, &sha512ctx); keylen = ISC_SHA512_DIGESTLENGTH; } else { memmove(hkey->key, r.base, r.length); keylen = r.length; } key->key_size = keylen * 8; key->keydata.hmacsha512 = hkey; isc_buffer_forward(data, r.length); return (ISC_R_SUCCESS); } static isc_result_t hmacsha512_tofile(const dst_key_t *key, const char *directory) { int cnt = 0; dst_hmacsha512_key_t *hkey; dst_private_t priv; int bytes = (key->key_size + 7) / 8; unsigned char buf[2]; if (key->keydata.hmacsha512 == NULL) return (DST_R_NULLKEY); if (key->external) return (DST_R_EXTERNALKEY); hkey = key->keydata.hmacsha512; priv.elements[cnt].tag = TAG_HMACSHA512_KEY; priv.elements[cnt].length = bytes; priv.elements[cnt++].data = hkey->key; buf[0] = (key->key_bits >> 8) & 0xffU; buf[1] = key->key_bits & 0xffU; priv.elements[cnt].tag = TAG_HMACSHA512_BITS; priv.elements[cnt].data = buf; priv.elements[cnt++].length = 2; priv.nelements = cnt; return (dst__privstruct_writefile(key, &priv, directory)); } static isc_result_t hmacsha512_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t result, tresult; isc_buffer_t b; isc_mem_t *mctx = key->mctx; unsigned int i; UNUSED(pub); /* read private key file */ result = dst__privstruct_parse(key, DST_ALG_HMACSHA512, lexer, mctx, &priv); if (result != ISC_R_SUCCESS) return (result); if (key->external) result = DST_R_EXTERNALKEY; key->key_bits = 0; for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { switch (priv.elements[i].tag) { case TAG_HMACSHA512_KEY: isc_buffer_init(&b, priv.elements[i].data, priv.elements[i].length); isc_buffer_add(&b, priv.elements[i].length); tresult = hmacsha512_fromdns(key, &b); if (tresult != ISC_R_SUCCESS) result = tresult; break; case TAG_HMACSHA512_BITS: tresult = getkeybits(key, &priv.elements[i]); if (tresult != ISC_R_SUCCESS) result = tresult; break; default: result = DST_R_INVALIDPRIVATEKEY; break; } } dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (result); } static dst_func_t hmacsha512_functions = { hmacsha512_createctx, NULL, /*%< createctx2 */ hmacsha512_destroyctx, hmacsha512_adddata, hmacsha512_sign, hmacsha512_verify, NULL, /* verify2 */ NULL, /* computesecret */ hmacsha512_compare, NULL, /* paramcompare */ hmacsha512_generate, hmacsha512_isprivate, hmacsha512_destroy, hmacsha512_todns, hmacsha512_fromdns, hmacsha512_tofile, hmacsha512_parse, NULL, /* cleanup */ NULL, /* fromlabel */ NULL, /* dump */ NULL, /* restore */ }; isc_result_t dst__hmacsha512_init(dst_func_t **funcp) { REQUIRE(funcp != NULL); if (*funcp == NULL) *funcp = &hmacsha512_functions; return (ISC_R_SUCCESS); } /*! \file */ bind9-9.10.3.dfsg.P4/lib/dns/spnego.c0000644000470500017500000012041012664710322016360 0ustar lamontlamont/* * Copyright (C) 2006-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file * \brief * Portable SPNEGO implementation. * * This is part of a portable implementation of the SPNEGO protocol * (RFCs 2478 and 4178). This implementation uses the RFC 4178 ASN.1 * module but is not a full implementation of the RFC 4178 protocol; * at the moment, we only support GSS-TSIG with Kerberos * authentication, so we only need enough of the SPNEGO protocol to * support that. * * The files that make up this portable SPNEGO implementation are: * \li spnego.c (this file) * \li spnego.h (API SPNEGO exports to the rest of lib/dns) * \li spnego.asn1 (SPNEGO ASN.1 module) * \li spnego_asn1.c (routines generated from spngo.asn1) * \li spnego_asn1.pl (perl script to generate spnego_asn1.c) * * Everything but the functions exported in spnego.h is static, to * avoid possible conflicts with other libraries (particularly Heimdal, * since much of this code comes from Heimdal by way of mod_auth_kerb). * * spnego_asn1.c is shipped as part of lib/dns because generating it * requires both Perl and the Heimdal ASN.1 compiler. See * spnego_asn1.pl for further details. We've tried to eliminate all * compiler warnings from the generated code, but you may see a few * when using a compiler version we haven't tested yet. */ /* * Portions of this code were derived from mod_auth_kerb and Heimdal. * These packages are available from: * * http://modauthkerb.sourceforge.net/ * http://www.pdc.kth.se/heimdal/ * * and were released under the following licenses: * * ---------------------------------------------------------------- * * Copyright (c) 2004 Masarykova universita * (Masaryk University, Brno, Czech Republic) * 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. Neither the name of the University 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 COPYRIGHT OWNER 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. * * ---------------------------------------------------------------- * * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * 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. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. */ /* * XXXSRA We should omit this file entirely in Makefile.in via autoconf, * but this will keep it from generating errors until that's written. */ #ifdef GSSAPI /* * XXXSRA Some of the following files are almost certainly unnecessary, * but using this list (borrowed from gssapictx.c) gets rid of some * whacky compilation errors when building with MSVC and should be * harmless in any case. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dst_internal.h" /* * The API we export */ #include "spnego.h" /* asn1_err.h */ /* Generated from ../../../lib/asn1/asn1_err.et */ #ifndef ERROR_TABLE_BASE_asn1 /* these may be brought in already via gssapi_krb5.h */ typedef enum asn1_error_number { ASN1_BAD_TIMEFORMAT = 1859794432, ASN1_MISSING_FIELD = 1859794433, ASN1_MISPLACED_FIELD = 1859794434, ASN1_TYPE_MISMATCH = 1859794435, ASN1_OVERFLOW = 1859794436, ASN1_OVERRUN = 1859794437, ASN1_BAD_ID = 1859794438, ASN1_BAD_LENGTH = 1859794439, ASN1_BAD_FORMAT = 1859794440, ASN1_PARSE_ERROR = 1859794441 } asn1_error_number; #define ERROR_TABLE_BASE_asn1 1859794432 #endif #define __asn1_common_definitions__ typedef struct octet_string { size_t length; void *data; } octet_string; typedef char *general_string; typedef char *utf8_string; typedef struct oid { size_t length; unsigned *components; } oid; /* der.h */ typedef enum { ASN1_C_UNIV = 0, ASN1_C_APPL = 1, ASN1_C_CONTEXT = 2, ASN1_C_PRIVATE = 3 } Der_class; typedef enum { PRIM = 0, CONS = 1 } Der_type; /* Universal tags */ enum { UT_Boolean = 1, UT_Integer = 2, UT_BitString = 3, UT_OctetString = 4, UT_Null = 5, UT_OID = 6, UT_Enumerated = 10, UT_Sequence = 16, UT_Set = 17, UT_PrintableString = 19, UT_IA5String = 22, UT_UTCTime = 23, UT_GeneralizedTime = 24, UT_VisibleString = 26, UT_GeneralString = 27 }; #define ASN1_INDEFINITE 0xdce0deed static int der_get_length(const unsigned char *p, size_t len, size_t * val, size_t * size); static int der_get_octet_string(const unsigned char *p, size_t len, octet_string * data, size_t * size); static int der_get_oid(const unsigned char *p, size_t len, oid * data, size_t * size); static int der_get_tag(const unsigned char *p, size_t len, Der_class * class, Der_type * type, int *tag, size_t * size); static int der_match_tag(const unsigned char *p, size_t len, Der_class class, Der_type type, int tag, size_t * size); static int der_match_tag_and_length(const unsigned char *p, size_t len, Der_class class, Der_type type, int tag, size_t * length_ret, size_t * size); static int decode_oid(const unsigned char *p, size_t len, oid * k, size_t * size); static int decode_enumerated(const unsigned char *p, size_t len, void *num, size_t *size); static int decode_octet_string(const unsigned char *, size_t, octet_string *, size_t *); static int der_put_int(unsigned char *p, size_t len, int val, size_t *); static int der_put_length(unsigned char *p, size_t len, size_t val, size_t *); static int der_put_octet_string(unsigned char *p, size_t len, const octet_string * data, size_t *); static int der_put_oid(unsigned char *p, size_t len, const oid * data, size_t * size); static int der_put_tag(unsigned char *p, size_t len, Der_class class, Der_type type, int tag, size_t *); static int der_put_length_and_tag(unsigned char *, size_t, size_t, Der_class, Der_type, int, size_t *); static int encode_enumerated(unsigned char *p, size_t len, const void *data, size_t *); static int encode_octet_string(unsigned char *p, size_t len, const octet_string * k, size_t *); static int encode_oid(unsigned char *p, size_t len, const oid * k, size_t *); static void free_octet_string(octet_string * k); static void free_oid (oid * k); static size_t length_len(size_t len); static int fix_dce(size_t reallen, size_t * len); /* * Include stuff generated by the ASN.1 compiler. */ #include "spnego_asn1.c" static unsigned char gss_krb5_mech_oid_bytes[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02 }; static gss_OID_desc gss_krb5_mech_oid_desc = { sizeof(gss_krb5_mech_oid_bytes), gss_krb5_mech_oid_bytes }; static gss_OID GSS_KRB5_MECH = &gss_krb5_mech_oid_desc; static unsigned char gss_mskrb5_mech_oid_bytes[] = { 0x2a, 0x86, 0x48, 0x82, 0xf7, 0x12, 0x01, 0x02, 0x02 }; static gss_OID_desc gss_mskrb5_mech_oid_desc = { sizeof(gss_mskrb5_mech_oid_bytes), gss_mskrb5_mech_oid_bytes }; static gss_OID GSS_MSKRB5_MECH = &gss_mskrb5_mech_oid_desc; static unsigned char gss_spnego_mech_oid_bytes[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x02 }; static gss_OID_desc gss_spnego_mech_oid_desc = { sizeof(gss_spnego_mech_oid_bytes), gss_spnego_mech_oid_bytes }; static gss_OID GSS_SPNEGO_MECH = &gss_spnego_mech_oid_desc; /* spnegokrb5_locl.h */ static OM_uint32 gssapi_spnego_encapsulate(OM_uint32 *, unsigned char *, size_t, gss_buffer_t, const gss_OID); static OM_uint32 gssapi_spnego_decapsulate(OM_uint32 *, gss_buffer_t, unsigned char **, size_t *, const gss_OID); /* mod_auth_kerb.c */ static int cmp_gss_type(gss_buffer_t token, gss_OID gssoid) { unsigned char *p; size_t len; if (token->length == 0U) return (GSS_S_DEFECTIVE_TOKEN); p = token->value; if (*p++ != 0x60) return (GSS_S_DEFECTIVE_TOKEN); len = *p++; if (len & 0x80) { if ((len & 0x7f) > 4U) return (GSS_S_DEFECTIVE_TOKEN); p += len & 0x7f; } if (*p++ != 0x06) return (GSS_S_DEFECTIVE_TOKEN); if (((OM_uint32) *p++) != gssoid->length) return (GSS_S_DEFECTIVE_TOKEN); return (isc_safe_memcompare(p, gssoid->elements, gssoid->length)); } /* accept_sec_context.c */ /* * SPNEGO wrapper for Kerberos5 GSS-API kouril@ics.muni.cz, 2003 (mostly * based on Heimdal code) */ static OM_uint32 code_NegTokenArg(OM_uint32 * minor_status, const NegTokenResp * resp, unsigned char **outbuf, size_t * outbuf_size) { OM_uint32 ret; u_char *buf; size_t buf_size, buf_len = 0; buf_size = 1024; buf = malloc(buf_size); if (buf == NULL) { *minor_status = ENOMEM; return (GSS_S_FAILURE); } do { ret = encode_NegTokenResp(buf + buf_size - 1, buf_size, resp, &buf_len); if (ret == 0) { size_t tmp; ret = der_put_length_and_tag(buf + buf_size - buf_len - 1, buf_size - buf_len, buf_len, ASN1_C_CONTEXT, CONS, 1, &tmp); if (ret == 0) buf_len += tmp; } if (ret) { if (ret == ASN1_OVERFLOW) { u_char *tmp; buf_size *= 2; tmp = realloc(buf, buf_size); if (tmp == NULL) { *minor_status = ENOMEM; free(buf); return (GSS_S_FAILURE); } buf = tmp; } else { *minor_status = ret; free(buf); return (GSS_S_FAILURE); } } } while (ret == ASN1_OVERFLOW); *outbuf = malloc(buf_len); if (*outbuf == NULL) { *minor_status = ENOMEM; free(buf); return (GSS_S_FAILURE); } memmove(*outbuf, buf + buf_size - buf_len, buf_len); *outbuf_size = buf_len; free(buf); return (GSS_S_COMPLETE); } static OM_uint32 send_reject(OM_uint32 * minor_status, gss_buffer_t output_token) { NegTokenResp resp; OM_uint32 ret; resp.negState = malloc(sizeof(*resp.negState)); if (resp.negState == NULL) { *minor_status = ENOMEM; return (GSS_S_FAILURE); } *(resp.negState) = reject; resp.supportedMech = NULL; resp.responseToken = NULL; resp.mechListMIC = NULL; ret = code_NegTokenArg(minor_status, &resp, (unsigned char **)&output_token->value, &output_token->length); free_NegTokenResp(&resp); if (ret) return (ret); return (GSS_S_BAD_MECH); } static OM_uint32 send_accept(OM_uint32 * minor_status, gss_buffer_t output_token, gss_buffer_t mech_token, const gss_OID pref) { NegTokenResp resp; OM_uint32 ret; memset(&resp, 0, sizeof(resp)); resp.negState = malloc(sizeof(*resp.negState)); if (resp.negState == NULL) { *minor_status = ENOMEM; return (GSS_S_FAILURE); } *(resp.negState) = accept_completed; resp.supportedMech = malloc(sizeof(*resp.supportedMech)); if (resp.supportedMech == NULL) { free_NegTokenResp(&resp); *minor_status = ENOMEM; return (GSS_S_FAILURE); } ret = der_get_oid(pref->elements, pref->length, resp.supportedMech, NULL); if (ret) { free_NegTokenResp(&resp); *minor_status = ENOMEM; return (GSS_S_FAILURE); } if (mech_token != NULL && mech_token->length != 0U) { resp.responseToken = malloc(sizeof(*resp.responseToken)); if (resp.responseToken == NULL) { free_NegTokenResp(&resp); *minor_status = ENOMEM; return (GSS_S_FAILURE); } resp.responseToken->length = mech_token->length; resp.responseToken->data = mech_token->value; } ret = code_NegTokenArg(minor_status, &resp, (unsigned char **)&output_token->value, &output_token->length); if (resp.responseToken != NULL) { free(resp.responseToken); resp.responseToken = NULL; } free_NegTokenResp(&resp); if (ret) return (ret); return (GSS_S_COMPLETE); } OM_uint32 gss_accept_sec_context_spnego(OM_uint32 *minor_status, gss_ctx_id_t *context_handle, const gss_cred_id_t acceptor_cred_handle, const gss_buffer_t input_token_buffer, const gss_channel_bindings_t input_chan_bindings, gss_name_t *src_name, gss_OID *mech_type, gss_buffer_t output_token, OM_uint32 *ret_flags, OM_uint32 *time_rec, gss_cred_id_t *delegated_cred_handle) { NegTokenInit init_token; OM_uint32 major_status; OM_uint32 minor_status2; gss_buffer_desc ibuf, obuf; gss_buffer_t ot = NULL; gss_OID pref = GSS_KRB5_MECH; unsigned char *buf; size_t buf_size; size_t len, taglen, ni_len; int found = 0; int ret; unsigned i; /* * Before doing anything else, see whether this is a SPNEGO * PDU. If not, dispatch to the GSSAPI library and get out. */ if (cmp_gss_type(input_token_buffer, GSS_SPNEGO_MECH)) return (gss_accept_sec_context(minor_status, context_handle, acceptor_cred_handle, input_token_buffer, input_chan_bindings, src_name, mech_type, output_token, ret_flags, time_rec, delegated_cred_handle)); /* * If we get here, it's SPNEGO. */ memset(&init_token, 0, sizeof(init_token)); ret = gssapi_spnego_decapsulate(minor_status, input_token_buffer, &buf, &buf_size, GSS_SPNEGO_MECH); if (ret) return (ret); ret = der_match_tag_and_length(buf, buf_size, ASN1_C_CONTEXT, CONS, 0, &len, &taglen); if (ret) return (ret); ret = decode_NegTokenInit(buf + taglen, len, &init_token, &ni_len); if (ret) { *minor_status = EINVAL; /* XXX */ return (GSS_S_DEFECTIVE_TOKEN); } for (i = 0; !found && i < init_token.mechTypes.len; ++i) { unsigned char mechbuf[17]; size_t mech_len; ret = der_put_oid(mechbuf + sizeof(mechbuf) - 1, sizeof(mechbuf), &init_token.mechTypes.val[i], &mech_len); if (ret) { free_NegTokenInit(&init_token); return (GSS_S_DEFECTIVE_TOKEN); } if (mech_len == GSS_KRB5_MECH->length && isc_safe_memequal(GSS_KRB5_MECH->elements, mechbuf + sizeof(mechbuf) - mech_len, mech_len)) { found = 1; break; } if (mech_len == GSS_MSKRB5_MECH->length && isc_safe_memequal(GSS_MSKRB5_MECH->elements, mechbuf + sizeof(mechbuf) - mech_len, mech_len)) { found = 1; if (i == 0) pref = GSS_MSKRB5_MECH; break; } } if (!found) { free_NegTokenInit(&init_token); return (send_reject(minor_status, output_token)); } if (i == 0 && init_token.mechToken != NULL) { ibuf.length = init_token.mechToken->length; ibuf.value = init_token.mechToken->data; major_status = gss_accept_sec_context(minor_status, context_handle, acceptor_cred_handle, &ibuf, input_chan_bindings, src_name, mech_type, &obuf, ret_flags, time_rec, delegated_cred_handle); if (GSS_ERROR(major_status)) { free_NegTokenInit(&init_token); send_reject(&minor_status2, output_token); return (major_status); } ot = &obuf; } ret = send_accept(&minor_status2, output_token, ot, pref); free_NegTokenInit(&init_token); if (ot != NULL && ot->length != 0U) gss_release_buffer(&minor_status2, ot); return (ret); } /* decapsulate.c */ static OM_uint32 gssapi_verify_mech_header(u_char ** str, size_t total_len, const gss_OID mech) { size_t len, len_len, mech_len, foo; int e; u_char *p = *str; if (total_len < 1U) return (GSS_S_DEFECTIVE_TOKEN); if (*p++ != 0x60) return (GSS_S_DEFECTIVE_TOKEN); e = der_get_length(p, total_len - 1, &len, &len_len); if (e || 1 + len_len + len != total_len) return (GSS_S_DEFECTIVE_TOKEN); p += len_len; if (*p++ != 0x06) return (GSS_S_DEFECTIVE_TOKEN); e = der_get_length(p, total_len - 1 - len_len - 1, &mech_len, &foo); if (e) return (GSS_S_DEFECTIVE_TOKEN); p += foo; if (mech_len != mech->length) return (GSS_S_BAD_MECH); if (!isc_safe_memequal(p, mech->elements, mech->length)) return (GSS_S_BAD_MECH); p += mech_len; *str = p; return (GSS_S_COMPLETE); } /* * Remove the GSS-API wrapping from `in_token' giving `buf and buf_size' Does * not copy data, so just free `in_token'. */ static OM_uint32 gssapi_spnego_decapsulate(OM_uint32 *minor_status, gss_buffer_t input_token_buffer, unsigned char **buf, size_t *buf_len, const gss_OID mech) { u_char *p; OM_uint32 ret; p = input_token_buffer->value; ret = gssapi_verify_mech_header(&p, input_token_buffer->length, mech); if (ret) { *minor_status = ret; return (GSS_S_FAILURE); } *buf_len = input_token_buffer->length - (p - (u_char *) input_token_buffer->value); *buf = p; return (GSS_S_COMPLETE); } /* der_free.c */ static void free_octet_string(octet_string *k) { free(k->data); k->data = NULL; } static void free_oid(oid *k) { free(k->components); k->components = NULL; } /* der_get.c */ /* * All decoding functions take a pointer `p' to first position in which to * read, from the left, `len' which means the maximum number of characters we * are able to read, `ret' were the value will be returned and `size' where * the number of used bytes is stored. Either 0 or an error code is returned. */ static int der_get_unsigned(const unsigned char *p, size_t len, unsigned *ret, size_t *size) { unsigned val = 0; size_t oldlen = len; while (len--) val = val * 256 + *p++; *ret = val; if (size) *size = oldlen; return (0); } static int der_get_int(const unsigned char *p, size_t len, int *ret, size_t *size) { int val = 0; size_t oldlen = len; if (len > 0U) { val = (signed char)*p++; while (--len) val = val * 256 + *p++; } *ret = val; if (size) *size = oldlen; return (0); } static int der_get_length(const unsigned char *p, size_t len, size_t *val, size_t *size) { size_t v; if (len <= 0U) return (ASN1_OVERRUN); --len; v = *p++; if (v < 128U) { *val = v; if (size) *size = 1; } else { int e; size_t l; unsigned tmp; if (v == 0x80U) { *val = ASN1_INDEFINITE; if (size) *size = 1; return (0); } v &= 0x7F; if (len < v) return (ASN1_OVERRUN); e = der_get_unsigned(p, v, &tmp, &l); if (e) return (e); *val = tmp; if (size) *size = l + 1; } return (0); } static int der_get_octet_string(const unsigned char *p, size_t len, octet_string *data, size_t *size) { data->length = len; if (len != 0U) { data->data = malloc(len); if (data->data == NULL) return (ENOMEM); memmove(data->data, p, len); } else data->data = NULL; if (size) *size = len; return (0); } static int der_get_oid(const unsigned char *p, size_t len, oid *data, size_t *size) { int n; size_t oldlen = len; data->components = NULL; data->length = 0; if (len < 1U) return (ASN1_OVERRUN); data->components = malloc(len * sizeof(*data->components)); if (data->components == NULL && len != 0U) return (ENOMEM); data->components[0] = (*p) / 40; data->components[1] = (*p) % 40; --len; ++p; for (n = 2; len > 0U; ++n) { unsigned u = 0; do { --len; u = u * 128 + (*p++ % 128); } while (len > 0U && p[-1] & 0x80); data->components[n] = u; } if (p[-1] & 0x80) { free_oid(data); return (ASN1_OVERRUN); } data->length = n; if (size) *size = oldlen; return (0); } static int der_get_tag(const unsigned char *p, size_t len, Der_class *class, Der_type *type, int *tag, size_t *size) { if (len < 1U) return (ASN1_OVERRUN); *class = (Der_class) (((*p) >> 6) & 0x03); *type = (Der_type) (((*p) >> 5) & 0x01); *tag = (*p) & 0x1F; if (size) *size = 1; return (0); } static int der_match_tag(const unsigned char *p, size_t len, Der_class class, Der_type type, int tag, size_t *size) { size_t l; Der_class thisclass; Der_type thistype; int thistag; int e; e = der_get_tag(p, len, &thisclass, &thistype, &thistag, &l); if (e) return (e); if (class != thisclass || type != thistype) return (ASN1_BAD_ID); if (tag > thistag) return (ASN1_MISPLACED_FIELD); if (tag < thistag) return (ASN1_MISSING_FIELD); if (size) *size = l; return (0); } static int der_match_tag_and_length(const unsigned char *p, size_t len, Der_class class, Der_type type, int tag, size_t *length_ret, size_t *size) { size_t l, ret = 0; int e; e = der_match_tag(p, len, class, type, tag, &l); if (e) return (e); p += l; len -= l; ret += l; e = der_get_length(p, len, length_ret, &l); if (e) return (e); /* p += l; */ len -= l; POST(len); ret += l; if (size) *size = ret; return (0); } static int decode_enumerated(const unsigned char *p, size_t len, void *num, size_t *size) { size_t ret = 0; size_t l, reallen; int e; e = der_match_tag(p, len, ASN1_C_UNIV, PRIM, UT_Enumerated, &l); if (e) return (e); p += l; len -= l; ret += l; e = der_get_length(p, len, &reallen, &l); if (e) return (e); p += l; len -= l; ret += l; e = der_get_int(p, reallen, num, &l); if (e) return (e); p += l; len -= l; POST(p); POST(len); ret += l; if (size) *size = ret; return (0); } static int decode_octet_string(const unsigned char *p, size_t len, octet_string *k, size_t *size) { size_t ret = 0; size_t l; int e; size_t slen; k->data = NULL; k->length = 0; e = der_match_tag(p, len, ASN1_C_UNIV, PRIM, UT_OctetString, &l); if (e) return (e); p += l; len -= l; ret += l; e = der_get_length(p, len, &slen, &l); if (e) return (e); p += l; len -= l; ret += l; if (len < slen) return (ASN1_OVERRUN); e = der_get_octet_string(p, slen, k, &l); if (e) return (e); p += l; len -= l; POST(p); POST(len); ret += l; if (size) *size = ret; return (0); } static int decode_oid(const unsigned char *p, size_t len, oid *k, size_t *size) { size_t ret = 0; size_t l; int e; size_t slen; e = der_match_tag(p, len, ASN1_C_UNIV, PRIM, UT_OID, &l); if (e) return (e); p += l; len -= l; ret += l; e = der_get_length(p, len, &slen, &l); if (e) return (e); p += l; len -= l; ret += l; if (len < slen) return (ASN1_OVERRUN); e = der_get_oid(p, slen, k, &l); if (e) return (e); p += l; len -= l; POST(p); POST(len); ret += l; if (size) *size = ret; return (0); } static int fix_dce(size_t reallen, size_t *len) { if (reallen == ASN1_INDEFINITE) return (1); if (*len < reallen) return (-1); *len = reallen; return (0); } /* der_length.c */ static size_t len_unsigned(unsigned val) { size_t ret = 0; do { ++ret; val /= 256; } while (val); return (ret); } static size_t length_len(size_t len) { if (len < 128U) return (1); else return (len_unsigned((unsigned int)len) + 1); } /* der_put.c */ /* * All encoding functions take a pointer `p' to first position in which to * write, from the right, `len' which means the maximum number of characters * we are able to write. The function returns the number of characters * written in `size' (if non-NULL). The return value is 0 or an error. */ static int der_put_unsigned(unsigned char *p, size_t len, unsigned val, size_t *size) { unsigned char *base = p; if (val) { while (len > 0U && val) { *p-- = val % 256; val /= 256; --len; } if (val != 0) return (ASN1_OVERFLOW); else { *size = base - p; return (0); } } else if (len < 1U) return (ASN1_OVERFLOW); else { *p = 0; *size = 1; return (0); } } static int der_put_int(unsigned char *p, size_t len, int val, size_t *size) { unsigned char *base = p; if (val >= 0) { do { if (len < 1U) return (ASN1_OVERFLOW); *p-- = val % 256; len--; val /= 256; } while (val); if (p[1] >= 128) { if (len < 1U) return (ASN1_OVERFLOW); *p-- = 0; len--; } } else { val = ~val; do { if (len < 1U) return (ASN1_OVERFLOW); *p-- = ~(val % 256); len--; val /= 256; } while (val); if (p[1] < 128) { if (len < 1U) return (ASN1_OVERFLOW); *p-- = 0xff; len--; } } *size = base - p; return (0); } static int der_put_length(unsigned char *p, size_t len, size_t val, size_t *size) { if (len < 1U) return (ASN1_OVERFLOW); if (val < 128U) { *p = (unsigned char)val; *size = 1; return (0); } else { size_t l; int e; e = der_put_unsigned(p, len - 1, (unsigned int)val, &l); if (e) return (e); p -= l; *p = 0x80 | (unsigned char)l; *size = l + 1; return (0); } } static int der_put_octet_string(unsigned char *p, size_t len, const octet_string *data, size_t *size) { if (len < data->length) return (ASN1_OVERFLOW); p -= data->length; len -= data->length; POST(len); memmove(p + 1, data->data, data->length); *size = data->length; return (0); } static int der_put_oid(unsigned char *p, size_t len, const oid *data, size_t *size) { unsigned char *base = p; size_t n; for (n = data->length; n >= 3u; --n) { unsigned u = data->components[n - 1]; if (len < 1U) return (ASN1_OVERFLOW); *p-- = u % 128; u /= 128; --len; while (u > 0) { if (len < 1U) return (ASN1_OVERFLOW); *p-- = 128 + u % 128; u /= 128; --len; } } if (len < 1U) return (ASN1_OVERFLOW); *p-- = 40 * data->components[0] + data->components[1]; *size = base - p; return (0); } static int der_put_tag(unsigned char *p, size_t len, Der_class class, Der_type type, int tag, size_t *size) { if (len < 1U) return (ASN1_OVERFLOW); *p = (class << 6) | (type << 5) | tag; /* XXX */ *size = 1; return (0); } static int der_put_length_and_tag(unsigned char *p, size_t len, size_t len_val, Der_class class, Der_type type, int tag, size_t *size) { size_t ret = 0; size_t l; int e; e = der_put_length(p, len, len_val, &l); if (e) return (e); p -= l; len -= l; ret += l; e = der_put_tag(p, len, class, type, tag, &l); if (e) return (e); p -= l; len -= l; POST(p); POST(len); ret += l; *size = ret; return (0); } static int encode_enumerated(unsigned char *p, size_t len, const void *data, size_t *size) { unsigned num = *(const unsigned *)data; size_t ret = 0; size_t l; int e; e = der_put_int(p, len, num, &l); if (e) return (e); p -= l; len -= l; ret += l; e = der_put_length_and_tag(p, len, l, ASN1_C_UNIV, PRIM, UT_Enumerated, &l); if (e) return (e); p -= l; len -= l; POST(p); POST(len); ret += l; *size = ret; return (0); } static int encode_octet_string(unsigned char *p, size_t len, const octet_string *k, size_t *size) { size_t ret = 0; size_t l; int e; e = der_put_octet_string(p, len, k, &l); if (e) return (e); p -= l; len -= l; ret += l; e = der_put_length_and_tag(p, len, l, ASN1_C_UNIV, PRIM, UT_OctetString, &l); if (e) return (e); p -= l; len -= l; POST(p); POST(len); ret += l; *size = ret; return (0); } static int encode_oid(unsigned char *p, size_t len, const oid *k, size_t *size) { size_t ret = 0; size_t l; int e; e = der_put_oid(p, len, k, &l); if (e) return (e); p -= l; len -= l; ret += l; e = der_put_length_and_tag(p, len, l, ASN1_C_UNIV, PRIM, UT_OID, &l); if (e) return (e); p -= l; len -= l; POST(p); POST(len); ret += l; *size = ret; return (0); } /* encapsulate.c */ static void gssapi_encap_length(size_t data_len, size_t *len, size_t *total_len, const gss_OID mech) { size_t len_len; *len = 1 + 1 + mech->length + data_len; len_len = length_len(*len); *total_len = 1 + len_len + *len; } static u_char * gssapi_mech_make_header(u_char *p, size_t len, const gss_OID mech) { int e; size_t len_len, foo; *p++ = 0x60; len_len = length_len(len); e = der_put_length(p + len_len - 1, len_len, len, &foo); if (e || foo != len_len) return (NULL); p += len_len; *p++ = 0x06; *p++ = mech->length; memmove(p, mech->elements, mech->length); p += mech->length; return (p); } /* * Give it a krb5_data and it will encapsulate with extra GSS-API wrappings. */ static OM_uint32 gssapi_spnego_encapsulate(OM_uint32 * minor_status, unsigned char *buf, size_t buf_size, gss_buffer_t output_token, const gss_OID mech) { size_t len, outer_len; u_char *p; gssapi_encap_length(buf_size, &len, &outer_len, mech); output_token->length = outer_len; output_token->value = malloc(outer_len); if (output_token->value == NULL) { *minor_status = ENOMEM; return (GSS_S_FAILURE); } p = gssapi_mech_make_header(output_token->value, len, mech); if (p == NULL) { if (output_token->length != 0U) gss_release_buffer(minor_status, output_token); return (GSS_S_FAILURE); } memmove(p, buf, buf_size); return (GSS_S_COMPLETE); } /* init_sec_context.c */ /* * SPNEGO wrapper for Kerberos5 GSS-API kouril@ics.muni.cz, 2003 (mostly * based on Heimdal code) */ static int add_mech(MechTypeList * mech_list, gss_OID mech) { MechType *tmp; int ret; tmp = realloc(mech_list->val, (mech_list->len + 1) * sizeof(*tmp)); if (tmp == NULL) return (ENOMEM); mech_list->val = tmp; ret = der_get_oid(mech->elements, mech->length, &mech_list->val[mech_list->len], NULL); if (ret) return (ret); mech_list->len++; return (0); } /* * return the length of the mechanism in token or -1 * (which implies that the token was bad - GSS_S_DEFECTIVE_TOKEN */ static ssize_t gssapi_krb5_get_mech(const u_char *ptr, size_t total_len, const u_char **mech_ret) { size_t len, len_len, mech_len, foo; const u_char *p = ptr; int e; if (total_len < 1U) return (-1); if (*p++ != 0x60) return (-1); e = der_get_length (p, total_len - 1, &len, &len_len); if (e || 1 + len_len + len != total_len) return (-1); p += len_len; if (*p++ != 0x06) return (-1); e = der_get_length (p, total_len - 1 - len_len - 1, &mech_len, &foo); if (e) return (-1); p += foo; *mech_ret = p; return (mech_len); } static OM_uint32 spnego_initial(OM_uint32 *minor_status, const gss_cred_id_t initiator_cred_handle, gss_ctx_id_t *context_handle, const gss_name_t target_name, const gss_OID mech_type, OM_uint32 req_flags, OM_uint32 time_req, const gss_channel_bindings_t input_chan_bindings, const gss_buffer_t input_token, gss_OID *actual_mech_type, gss_buffer_t output_token, OM_uint32 *ret_flags, OM_uint32 *time_rec) { NegTokenInit token_init; OM_uint32 major_status, minor_status2; gss_buffer_desc krb5_output_token = GSS_C_EMPTY_BUFFER; unsigned char *buf = NULL; size_t buf_size; size_t len; int ret; (void)mech_type; memset(&token_init, 0, sizeof(token_init)); ret = add_mech(&token_init.mechTypes, GSS_KRB5_MECH); if (ret) { *minor_status = ret; ret = GSS_S_FAILURE; goto end; } major_status = gss_init_sec_context(minor_status, initiator_cred_handle, context_handle, target_name, GSS_KRB5_MECH, req_flags, time_req, input_chan_bindings, input_token, actual_mech_type, &krb5_output_token, ret_flags, time_rec); if (GSS_ERROR(major_status)) { ret = major_status; goto end; } if (krb5_output_token.length > 0U) { token_init.mechToken = malloc(sizeof(*token_init.mechToken)); if (token_init.mechToken == NULL) { *minor_status = ENOMEM; ret = GSS_S_FAILURE; goto end; } token_init.mechToken->data = krb5_output_token.value; token_init.mechToken->length = krb5_output_token.length; } /* * The MS implementation of SPNEGO seems to not like the mechListMIC * field, so we omit it (it's optional anyway) */ buf_size = 1024; buf = malloc(buf_size); if (buf == NULL) { *minor_status = ENOMEM; ret = GSS_S_FAILURE; goto end; } do { ret = encode_NegTokenInit(buf + buf_size - 1, buf_size, &token_init, &len); if (ret == 0) { size_t tmp; ret = der_put_length_and_tag(buf + buf_size - len - 1, buf_size - len, len, ASN1_C_CONTEXT, CONS, 0, &tmp); if (ret == 0) len += tmp; } if (ret) { if (ret == ASN1_OVERFLOW) { u_char *tmp; buf_size *= 2; tmp = realloc(buf, buf_size); if (tmp == NULL) { *minor_status = ENOMEM; ret = GSS_S_FAILURE; goto end; } buf = tmp; } else { *minor_status = ret; ret = GSS_S_FAILURE; goto end; } } } while (ret == ASN1_OVERFLOW); ret = gssapi_spnego_encapsulate(minor_status, buf + buf_size - len, len, output_token, GSS_SPNEGO_MECH); if (ret == GSS_S_COMPLETE) ret = major_status; end: if (token_init.mechToken != NULL) { free(token_init.mechToken); token_init.mechToken = NULL; } free_NegTokenInit(&token_init); if (krb5_output_token.length != 0U) gss_release_buffer(&minor_status2, &krb5_output_token); if (buf) free(buf); return (ret); } static OM_uint32 spnego_reply(OM_uint32 *minor_status, const gss_cred_id_t initiator_cred_handle, gss_ctx_id_t *context_handle, const gss_name_t target_name, const gss_OID mech_type, OM_uint32 req_flags, OM_uint32 time_req, const gss_channel_bindings_t input_chan_bindings, const gss_buffer_t input_token, gss_OID *actual_mech_type, gss_buffer_t output_token, OM_uint32 *ret_flags, OM_uint32 *time_rec) { OM_uint32 ret; NegTokenResp resp; unsigned char *buf; size_t buf_size; u_char oidbuf[17]; size_t oidlen; gss_buffer_desc sub_token; ssize_t mech_len; const u_char *p; size_t len, taglen; (void)mech_type; output_token->length = 0; output_token->value = NULL; /* * SPNEGO doesn't include gss wrapping on SubsequentContextToken * like the Kerberos 5 mech does. But lets check for it anyway. */ mech_len = gssapi_krb5_get_mech(input_token->value, input_token->length, &p); if (mech_len < 0) { buf = input_token->value; buf_size = input_token->length; } else if ((size_t)mech_len == GSS_KRB5_MECH->length && isc_safe_memequal(GSS_KRB5_MECH->elements, p, mech_len)) return (gss_init_sec_context(minor_status, initiator_cred_handle, context_handle, target_name, GSS_KRB5_MECH, req_flags, time_req, input_chan_bindings, input_token, actual_mech_type, output_token, ret_flags, time_rec)); else if ((size_t)mech_len == GSS_SPNEGO_MECH->length && isc_safe_memequal(GSS_SPNEGO_MECH->elements, p, mech_len)) { ret = gssapi_spnego_decapsulate(minor_status, input_token, &buf, &buf_size, GSS_SPNEGO_MECH); if (ret) return (ret); } else return (GSS_S_BAD_MECH); ret = der_match_tag_and_length(buf, buf_size, ASN1_C_CONTEXT, CONS, 1, &len, &taglen); if (ret) return (ret); if(len > buf_size - taglen) return (ASN1_OVERRUN); ret = decode_NegTokenResp(buf + taglen, len, &resp, NULL); if (ret) { free_NegTokenResp(&resp); *minor_status = ENOMEM; return (GSS_S_FAILURE); } if (resp.negState == NULL || *(resp.negState) == reject || resp.supportedMech == NULL) { free_NegTokenResp(&resp); return (GSS_S_BAD_MECH); } ret = der_put_oid(oidbuf + sizeof(oidbuf) - 1, sizeof(oidbuf), resp.supportedMech, &oidlen); if (ret || oidlen != GSS_KRB5_MECH->length || !isc_safe_memequal(oidbuf + sizeof(oidbuf) - oidlen, GSS_KRB5_MECH->elements, oidlen)) { free_NegTokenResp(&resp); return GSS_S_BAD_MECH; } if (resp.responseToken != NULL) { sub_token.length = resp.responseToken->length; sub_token.value = resp.responseToken->data; } else { sub_token.length = 0; sub_token.value = NULL; } ret = gss_init_sec_context(minor_status, initiator_cred_handle, context_handle, target_name, GSS_KRB5_MECH, req_flags, time_req, input_chan_bindings, &sub_token, actual_mech_type, output_token, ret_flags, time_rec); if (ret) { free_NegTokenResp(&resp); return (ret); } /* * XXXSRA I don't think this limited implementation ever needs * to check the MIC -- our preferred mechanism (Kerberos) * authenticates its own messages and is the only mechanism * we'll accept, so if the mechanism negotiation completes * successfully, we don't need the MIC. See RFC 4178. */ free_NegTokenResp(&resp); return (ret); } OM_uint32 gss_init_sec_context_spnego(OM_uint32 *minor_status, const gss_cred_id_t initiator_cred_handle, gss_ctx_id_t *context_handle, const gss_name_t target_name, const gss_OID mech_type, OM_uint32 req_flags, OM_uint32 time_req, const gss_channel_bindings_t input_chan_bindings, const gss_buffer_t input_token, gss_OID *actual_mech_type, gss_buffer_t output_token, OM_uint32 *ret_flags, OM_uint32 *time_rec) { /* Dirty trick to suppress compiler warnings */ /* Figure out whether we're starting over or processing a reply */ if (input_token == GSS_C_NO_BUFFER || input_token->length == 0U) return (spnego_initial(minor_status, initiator_cred_handle, context_handle, target_name, mech_type, req_flags, time_req, input_chan_bindings, input_token, actual_mech_type, output_token, ret_flags, time_rec)); else return (spnego_reply(minor_status, initiator_cred_handle, context_handle, target_name, mech_type, req_flags, time_req, input_chan_bindings, input_token, actual_mech_type, output_token, ret_flags, time_rec)); } #endif /* GSSAPI */ bind9-9.10.3.dfsg.P4/lib/dns/tsig.c0000644000470500017500000014365712664710322016055 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include /* Required for HP/UX (and others?) */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define TSIG_MAGIC ISC_MAGIC('T', 'S', 'I', 'G') #define VALID_TSIG_KEY(x) ISC_MAGIC_VALID(x, TSIG_MAGIC) #ifndef DNS_TSIG_MAXGENERATEDKEYS #define DNS_TSIG_MAXGENERATEDKEYS 4096 #endif #define is_response(msg) (msg->flags & DNS_MESSAGEFLAG_QR) #define algname_is_allocated(algname) \ ((algname) != dns_tsig_hmacmd5_name && \ (algname) != dns_tsig_hmacsha1_name && \ (algname) != dns_tsig_hmacsha224_name && \ (algname) != dns_tsig_hmacsha256_name && \ (algname) != dns_tsig_hmacsha384_name && \ (algname) != dns_tsig_hmacsha512_name && \ (algname) != dns_tsig_gssapi_name && \ (algname) != dns_tsig_gssapims_name) #define BADTIMELEN 6 static unsigned char hmacmd5_ndata[] = "\010hmac-md5\007sig-alg\003reg\003int"; static unsigned char hmacmd5_offsets[] = { 0, 9, 17, 21, 25 }; static dns_name_t hmacmd5 = { DNS_NAME_MAGIC, hmacmd5_ndata, 26, 5, DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, hmacmd5_offsets, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} }; dns_name_t *dns_tsig_hmacmd5_name = &hmacmd5; static unsigned char gsstsig_ndata[] = "\010gss-tsig"; static unsigned char gsstsig_offsets[] = { 0, 9 }; static dns_name_t gsstsig = { DNS_NAME_MAGIC, gsstsig_ndata, 10, 2, DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, gsstsig_offsets, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} }; LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_gssapi_name = &gsstsig; /* * Since Microsoft doesn't follow its own standard, we will use this * alternate name as a second guess. */ static unsigned char gsstsigms_ndata[] = "\003gss\011microsoft\003com"; static unsigned char gsstsigms_offsets[] = { 0, 4, 14, 18 }; static dns_name_t gsstsigms = { DNS_NAME_MAGIC, gsstsigms_ndata, 19, 4, DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, gsstsigms_offsets, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} }; LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_gssapims_name = &gsstsigms; static unsigned char hmacsha1_ndata[] = "\011hmac-sha1"; static unsigned char hmacsha1_offsets[] = { 0, 10 }; static dns_name_t hmacsha1 = { DNS_NAME_MAGIC, hmacsha1_ndata, 11, 2, DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, hmacsha1_offsets, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} }; LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_hmacsha1_name = &hmacsha1; static unsigned char hmacsha224_ndata[] = "\013hmac-sha224"; static unsigned char hmacsha224_offsets[] = { 0, 12 }; static dns_name_t hmacsha224 = { DNS_NAME_MAGIC, hmacsha224_ndata, 13, 2, DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, hmacsha224_offsets, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} }; LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_hmacsha224_name = &hmacsha224; static unsigned char hmacsha256_ndata[] = "\013hmac-sha256"; static unsigned char hmacsha256_offsets[] = { 0, 12 }; static dns_name_t hmacsha256 = { DNS_NAME_MAGIC, hmacsha256_ndata, 13, 2, DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, hmacsha256_offsets, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} }; LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_hmacsha256_name = &hmacsha256; static unsigned char hmacsha384_ndata[] = "\013hmac-sha384"; static unsigned char hmacsha384_offsets[] = { 0, 12 }; static dns_name_t hmacsha384 = { DNS_NAME_MAGIC, hmacsha384_ndata, 13, 2, DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, hmacsha384_offsets, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} }; LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_hmacsha384_name = &hmacsha384; static unsigned char hmacsha512_ndata[] = "\013hmac-sha512"; static unsigned char hmacsha512_offsets[] = { 0, 12 }; static dns_name_t hmacsha512 = { DNS_NAME_MAGIC, hmacsha512_ndata, 13, 2, DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, hmacsha512_offsets, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} }; LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_hmacsha512_name = &hmacsha512; static isc_result_t tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg); static void tsig_log(dns_tsigkey_t *key, int level, const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4); static void cleanup_ring(dns_tsig_keyring_t *ring); static void tsigkey_free(dns_tsigkey_t *key); static void tsig_log(dns_tsigkey_t *key, int level, const char *fmt, ...) { va_list ap; char message[4096]; char namestr[DNS_NAME_FORMATSIZE]; char creatorstr[DNS_NAME_FORMATSIZE]; if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) return; if (key != NULL) dns_name_format(&key->name, namestr, sizeof(namestr)); else strcpy(namestr, ""); if (key != NULL && key->generated && key->creator) dns_name_format(key->creator, creatorstr, sizeof(creatorstr)); else strcpy(creatorstr, ""); va_start(ap, fmt); vsnprintf(message, sizeof(message), fmt, ap); va_end(ap); if (key != NULL && key->generated) isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_TSIG, level, "tsig key '%s' (%s): %s", namestr, creatorstr, message); else isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_TSIG, level, "tsig key '%s': %s", namestr, message); } static void remove_fromring(dns_tsigkey_t *tkey) { if (tkey->generated) { ISC_LIST_UNLINK(tkey->ring->lru, tkey, link); tkey->ring->generated--; } (void)dns_rbt_deletename(tkey->ring->keys, &tkey->name, ISC_FALSE); } static void adjust_lru(dns_tsigkey_t *tkey) { if (tkey->generated) { RWLOCK(&tkey->ring->lock, isc_rwlocktype_write); /* * We may have been removed from the LRU list between * removing the read lock and aquiring the write lock. */ if (ISC_LINK_LINKED(tkey, link) && tkey->ring->lru.tail != tkey) { ISC_LIST_UNLINK(tkey->ring->lru, tkey, link); ISC_LIST_APPEND(tkey->ring->lru, tkey, link); } RWUNLOCK(&tkey->ring->lock, isc_rwlocktype_write); } } /* * A supplemental routine just to add a key to ring. Note that reference * counter should be counted separately because we may be adding the key * as part of creation of the key, in which case the reference counter was * already initialized. Also note we don't need RWLOCK for the reference * counter: it's protected by a separate lock. */ static isc_result_t keyring_add(dns_tsig_keyring_t *ring, dns_name_t *name, dns_tsigkey_t *tkey) { isc_result_t result; RWLOCK(&ring->lock, isc_rwlocktype_write); ring->writecount++; /* * Do on the fly cleaning. Find some nodes we might not * want around any more. */ if (ring->writecount > 10) { cleanup_ring(ring); ring->writecount = 0; } result = dns_rbt_addname(ring->keys, name, tkey); if (result == ISC_R_SUCCESS && tkey->generated) { /* * Add the new key to the LRU list and remove the least * recently used key if there are too many keys on the list. */ ISC_LIST_APPEND(ring->lru, tkey, link); if (ring->generated++ > ring->maxgenerated) remove_fromring(ISC_LIST_HEAD(ring->lru)); } RWUNLOCK(&ring->lock, isc_rwlocktype_write); return (result); } isc_result_t dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm, dst_key_t *dstkey, isc_boolean_t generated, dns_name_t *creator, isc_stdtime_t inception, isc_stdtime_t expire, isc_mem_t *mctx, dns_tsig_keyring_t *ring, dns_tsigkey_t **key) { dns_tsigkey_t *tkey; isc_result_t ret; unsigned int refs = 0; REQUIRE(key == NULL || *key == NULL); REQUIRE(name != NULL); REQUIRE(algorithm != NULL); REQUIRE(mctx != NULL); REQUIRE(key != NULL || ring != NULL); tkey = (dns_tsigkey_t *) isc_mem_get(mctx, sizeof(dns_tsigkey_t)); if (tkey == NULL) return (ISC_R_NOMEMORY); dns_name_init(&tkey->name, NULL); ret = dns_name_dup(name, mctx, &tkey->name); if (ret != ISC_R_SUCCESS) goto cleanup_key; (void)dns_name_downcase(&tkey->name, &tkey->name, NULL); if (dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME)) { tkey->algorithm = DNS_TSIG_HMACMD5_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACMD5) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA1_NAME)) { tkey->algorithm = DNS_TSIG_HMACSHA1_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA1) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA224_NAME)) { tkey->algorithm = DNS_TSIG_HMACSHA224_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA224) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA256_NAME)) { tkey->algorithm = DNS_TSIG_HMACSHA256_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA256) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA384_NAME)) { tkey->algorithm = DNS_TSIG_HMACSHA384_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA384) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA512_NAME)) { tkey->algorithm = DNS_TSIG_HMACSHA512_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA512) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPI_NAME)) { tkey->algorithm = DNS_TSIG_GSSAPI_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_GSSAPI) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPIMS_NAME)) { tkey->algorithm = DNS_TSIG_GSSAPIMS_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_GSSAPI) { ret = DNS_R_BADALG; goto cleanup_name; } } else { if (dstkey != NULL) { ret = DNS_R_BADALG; goto cleanup_name; } tkey->algorithm = isc_mem_get(mctx, sizeof(dns_name_t)); if (tkey->algorithm == NULL) { ret = ISC_R_NOMEMORY; goto cleanup_name; } dns_name_init(tkey->algorithm, NULL); ret = dns_name_dup(algorithm, mctx, tkey->algorithm); if (ret != ISC_R_SUCCESS) goto cleanup_algorithm; (void)dns_name_downcase(tkey->algorithm, tkey->algorithm, NULL); } if (creator != NULL) { tkey->creator = isc_mem_get(mctx, sizeof(dns_name_t)); if (tkey->creator == NULL) { ret = ISC_R_NOMEMORY; goto cleanup_algorithm; } dns_name_init(tkey->creator, NULL); ret = dns_name_dup(creator, mctx, tkey->creator); if (ret != ISC_R_SUCCESS) { isc_mem_put(mctx, tkey->creator, sizeof(dns_name_t)); goto cleanup_algorithm; } } else tkey->creator = NULL; tkey->key = NULL; if (dstkey != NULL) dst_key_attach(dstkey, &tkey->key); tkey->ring = ring; if (key != NULL) refs = 1; if (ring != NULL) refs++; ret = isc_refcount_init(&tkey->refs, refs); if (ret != ISC_R_SUCCESS) goto cleanup_creator; tkey->generated = generated; tkey->inception = inception; tkey->expire = expire; tkey->mctx = NULL; isc_mem_attach(mctx, &tkey->mctx); ISC_LINK_INIT(tkey, link); tkey->magic = TSIG_MAGIC; if (ring != NULL) { ret = keyring_add(ring, name, tkey); if (ret != ISC_R_SUCCESS) goto cleanup_refs; } /* * Ignore this if it's a GSS key, since the key size is meaningless. */ if (dstkey != NULL && dst_key_size(dstkey) < 64 && !dns_name_equal(algorithm, DNS_TSIG_GSSAPI_NAME) && !dns_name_equal(algorithm, DNS_TSIG_GSSAPIMS_NAME)) { char namestr[DNS_NAME_FORMATSIZE]; dns_name_format(name, namestr, sizeof(namestr)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_TSIG, ISC_LOG_INFO, "the key '%s' is too short to be secure", namestr); } if (key != NULL) *key = tkey; return (ISC_R_SUCCESS); cleanup_refs: tkey->magic = 0; while (refs-- > 0) isc_refcount_decrement(&tkey->refs, NULL); isc_refcount_destroy(&tkey->refs); cleanup_creator: if (tkey->key != NULL) dst_key_free(&tkey->key); if (tkey->creator != NULL) { dns_name_free(tkey->creator, mctx); isc_mem_put(mctx, tkey->creator, sizeof(dns_name_t)); } cleanup_algorithm: if (algname_is_allocated(tkey->algorithm)) { if (dns_name_dynamic(tkey->algorithm)) dns_name_free(tkey->algorithm, mctx); isc_mem_put(mctx, tkey->algorithm, sizeof(dns_name_t)); } cleanup_name: dns_name_free(&tkey->name, mctx); cleanup_key: isc_mem_put(mctx, tkey, sizeof(dns_tsigkey_t)); return (ret); } /* * Find a few nodes to destroy if possible. */ static void cleanup_ring(dns_tsig_keyring_t *ring) { isc_result_t result; dns_rbtnodechain_t chain; dns_name_t foundname; dns_fixedname_t fixedorigin; dns_name_t *origin; isc_stdtime_t now; dns_rbtnode_t *node; dns_tsigkey_t *tkey; /* * Start up a new iterator each time. */ isc_stdtime_get(&now); dns_name_init(&foundname, NULL); dns_fixedname_init(&fixedorigin); origin = dns_fixedname_name(&fixedorigin); again: dns_rbtnodechain_init(&chain, ring->mctx); result = dns_rbtnodechain_first(&chain, ring->keys, &foundname, origin); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { dns_rbtnodechain_invalidate(&chain); return; } for (;;) { node = NULL; dns_rbtnodechain_current(&chain, &foundname, origin, &node); tkey = node->data; if (tkey != NULL) { if (tkey->generated && isc_refcount_current(&tkey->refs) == 1 && tkey->inception != tkey->expire && tkey->expire < now) { tsig_log(tkey, 2, "tsig expire: deleting"); /* delete the key */ dns_rbtnodechain_invalidate(&chain); remove_fromring(tkey); goto again; } } result = dns_rbtnodechain_next(&chain, &foundname, origin); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { dns_rbtnodechain_invalidate(&chain); return; } } } static void destroyring(dns_tsig_keyring_t *ring) { dns_rbt_destroy(&ring->keys); isc_rwlock_destroy(&ring->lock); isc_mem_putanddetach(&ring->mctx, ring, sizeof(dns_tsig_keyring_t)); } static unsigned int dst_alg_fromname(dns_name_t *algorithm) { if (dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME)) { return (DST_ALG_HMACMD5); } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA1_NAME)) { return (DST_ALG_HMACSHA1); } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA224_NAME)) { return (DST_ALG_HMACSHA224); } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA256_NAME)) { return (DST_ALG_HMACSHA256); } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA384_NAME)) { return (DST_ALG_HMACSHA384); } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA512_NAME)) { return (DST_ALG_HMACSHA512); } else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPI_NAME)) { return (DST_ALG_GSSAPI); } else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPIMS_NAME)) { return (DST_ALG_GSSAPI); } else return (0); } static isc_result_t restore_key(dns_tsig_keyring_t *ring, isc_stdtime_t now, FILE *fp) { dst_key_t *dstkey = NULL; char namestr[1024]; char creatorstr[1024]; char algorithmstr[1024]; char keystr[4096]; unsigned int inception, expire; int n; isc_buffer_t b; dns_name_t *name, *creator, *algorithm; dns_fixedname_t fname, fcreator, falgorithm; isc_result_t result; unsigned int dstalg; n = fscanf(fp, "%1023s %1023s %u %u %1023s %4095s\n", namestr, creatorstr, &inception, &expire, algorithmstr, keystr); if (n == EOF) return (ISC_R_NOMORE); if (n != 6) return (ISC_R_FAILURE); if (isc_serial_lt(expire, now)) return (DNS_R_EXPIRED); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); isc_buffer_init(&b, namestr, strlen(namestr)); isc_buffer_add(&b, strlen(namestr)); result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) return (result); dns_fixedname_init(&fcreator); creator = dns_fixedname_name(&fcreator); isc_buffer_init(&b, creatorstr, strlen(creatorstr)); isc_buffer_add(&b, strlen(creatorstr)); result = dns_name_fromtext(creator, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) return (result); dns_fixedname_init(&falgorithm); algorithm = dns_fixedname_name(&falgorithm); isc_buffer_init(&b, algorithmstr, strlen(algorithmstr)); isc_buffer_add(&b, strlen(algorithmstr)); result = dns_name_fromtext(algorithm, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) return (result); dstalg = dst_alg_fromname(algorithm); if (dstalg == 0) return (DNS_R_BADALG); result = dst_key_restore(name, dstalg, DNS_KEYOWNER_ENTITY, DNS_KEYPROTO_DNSSEC, dns_rdataclass_in, ring->mctx, keystr, &dstkey); if (result != ISC_R_SUCCESS) return (result); result = dns_tsigkey_createfromkey(name, algorithm, dstkey, ISC_TRUE, creator, inception, expire, ring->mctx, ring, NULL); if (dstkey != NULL) dst_key_free(&dstkey); return (result); } static void dump_key(dns_tsigkey_t *tkey, FILE *fp) { char *buffer = NULL; int length = 0; char namestr[DNS_NAME_FORMATSIZE]; char creatorstr[DNS_NAME_FORMATSIZE]; char algorithmstr[DNS_NAME_FORMATSIZE]; isc_result_t result; REQUIRE(tkey != NULL); REQUIRE(fp != NULL); dns_name_format(&tkey->name, namestr, sizeof(namestr)); dns_name_format(tkey->creator, creatorstr, sizeof(creatorstr)); dns_name_format(tkey->algorithm, algorithmstr, sizeof(algorithmstr)); result = dst_key_dump(tkey->key, tkey->mctx, &buffer, &length); if (result == ISC_R_SUCCESS) fprintf(fp, "%s %s %u %u %s %.*s\n", namestr, creatorstr, tkey->inception, tkey->expire, algorithmstr, length, buffer); if (buffer != NULL) isc_mem_put(tkey->mctx, buffer, length); } isc_result_t dns_tsigkeyring_dumpanddetach(dns_tsig_keyring_t **ringp, FILE *fp) { isc_result_t result; dns_rbtnodechain_t chain; dns_name_t foundname; dns_fixedname_t fixedorigin; dns_name_t *origin; isc_stdtime_t now; dns_rbtnode_t *node; dns_tsigkey_t *tkey; dns_tsig_keyring_t *ring; unsigned int references; REQUIRE(ringp != NULL && *ringp != NULL); ring = *ringp; *ringp = NULL; RWLOCK(&ring->lock, isc_rwlocktype_write); INSIST(ring->references > 0); ring->references--; references = ring->references; RWUNLOCK(&ring->lock, isc_rwlocktype_write); if (references != 0) return (DNS_R_CONTINUE); isc_stdtime_get(&now); dns_name_init(&foundname, NULL); dns_fixedname_init(&fixedorigin); origin = dns_fixedname_name(&fixedorigin); dns_rbtnodechain_init(&chain, ring->mctx); result = dns_rbtnodechain_first(&chain, ring->keys, &foundname, origin); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { dns_rbtnodechain_invalidate(&chain); goto destroy; } for (;;) { node = NULL; dns_rbtnodechain_current(&chain, &foundname, origin, &node); tkey = node->data; if (tkey != NULL && tkey->generated && tkey->expire >= now) dump_key(tkey, fp); result = dns_rbtnodechain_next(&chain, &foundname, origin); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { dns_rbtnodechain_invalidate(&chain); if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; goto destroy; } } destroy: destroyring(ring); return (result); } isc_result_t dns_tsigkey_create(dns_name_t *name, dns_name_t *algorithm, unsigned char *secret, int length, isc_boolean_t generated, dns_name_t *creator, isc_stdtime_t inception, isc_stdtime_t expire, isc_mem_t *mctx, dns_tsig_keyring_t *ring, dns_tsigkey_t **key) { dst_key_t *dstkey = NULL; isc_result_t result; REQUIRE(length >= 0); if (length > 0) REQUIRE(secret != NULL); if (dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME)) { if (secret != NULL) { isc_buffer_t b; isc_buffer_init(&b, secret, length); isc_buffer_add(&b, length); result = dst_key_frombuffer(name, DST_ALG_HMACMD5, DNS_KEYOWNER_ENTITY, DNS_KEYPROTO_DNSSEC, dns_rdataclass_in, &b, mctx, &dstkey); if (result != ISC_R_SUCCESS) return (result); } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA1_NAME)) { if (secret != NULL) { isc_buffer_t b; isc_buffer_init(&b, secret, length); isc_buffer_add(&b, length); result = dst_key_frombuffer(name, DST_ALG_HMACSHA1, DNS_KEYOWNER_ENTITY, DNS_KEYPROTO_DNSSEC, dns_rdataclass_in, &b, mctx, &dstkey); if (result != ISC_R_SUCCESS) return (result); } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA224_NAME)) { if (secret != NULL) { isc_buffer_t b; isc_buffer_init(&b, secret, length); isc_buffer_add(&b, length); result = dst_key_frombuffer(name, DST_ALG_HMACSHA224, DNS_KEYOWNER_ENTITY, DNS_KEYPROTO_DNSSEC, dns_rdataclass_in, &b, mctx, &dstkey); if (result != ISC_R_SUCCESS) return (result); } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA256_NAME)) { if (secret != NULL) { isc_buffer_t b; isc_buffer_init(&b, secret, length); isc_buffer_add(&b, length); result = dst_key_frombuffer(name, DST_ALG_HMACSHA256, DNS_KEYOWNER_ENTITY, DNS_KEYPROTO_DNSSEC, dns_rdataclass_in, &b, mctx, &dstkey); if (result != ISC_R_SUCCESS) return (result); } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA384_NAME)) { if (secret != NULL) { isc_buffer_t b; isc_buffer_init(&b, secret, length); isc_buffer_add(&b, length); result = dst_key_frombuffer(name, DST_ALG_HMACSHA384, DNS_KEYOWNER_ENTITY, DNS_KEYPROTO_DNSSEC, dns_rdataclass_in, &b, mctx, &dstkey); if (result != ISC_R_SUCCESS) return (result); } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA512_NAME)) { if (secret != NULL) { isc_buffer_t b; isc_buffer_init(&b, secret, length); isc_buffer_add(&b, length); result = dst_key_frombuffer(name, DST_ALG_HMACSHA512, DNS_KEYOWNER_ENTITY, DNS_KEYPROTO_DNSSEC, dns_rdataclass_in, &b, mctx, &dstkey); if (result != ISC_R_SUCCESS) return (result); } } else if (length > 0) return (DNS_R_BADALG); result = dns_tsigkey_createfromkey(name, algorithm, dstkey, generated, creator, inception, expire, mctx, ring, key); if (dstkey != NULL) dst_key_free(&dstkey); return (result); } void dns_tsigkey_attach(dns_tsigkey_t *source, dns_tsigkey_t **targetp) { REQUIRE(VALID_TSIG_KEY(source)); REQUIRE(targetp != NULL && *targetp == NULL); isc_refcount_increment(&source->refs, NULL); *targetp = source; } static void tsigkey_free(dns_tsigkey_t *key) { REQUIRE(VALID_TSIG_KEY(key)); key->magic = 0; dns_name_free(&key->name, key->mctx); if (algname_is_allocated(key->algorithm)) { dns_name_free(key->algorithm, key->mctx); isc_mem_put(key->mctx, key->algorithm, sizeof(dns_name_t)); } if (key->key != NULL) dst_key_free(&key->key); if (key->creator != NULL) { dns_name_free(key->creator, key->mctx); isc_mem_put(key->mctx, key->creator, sizeof(dns_name_t)); } isc_refcount_destroy(&key->refs); isc_mem_putanddetach(&key->mctx, key, sizeof(dns_tsigkey_t)); } void dns_tsigkey_detach(dns_tsigkey_t **keyp) { dns_tsigkey_t *key; unsigned int refs; REQUIRE(keyp != NULL); REQUIRE(VALID_TSIG_KEY(*keyp)); key = *keyp; isc_refcount_decrement(&key->refs, &refs); if (refs == 0) tsigkey_free(key); *keyp = NULL; } void dns_tsigkey_setdeleted(dns_tsigkey_t *key) { REQUIRE(VALID_TSIG_KEY(key)); REQUIRE(key->ring != NULL); RWLOCK(&key->ring->lock, isc_rwlocktype_write); remove_fromring(key); RWUNLOCK(&key->ring->lock, isc_rwlocktype_write); } isc_result_t dns_tsig_sign(dns_message_t *msg) { dns_tsigkey_t *key; dns_rdata_any_tsig_t tsig, querytsig; unsigned char data[128]; isc_buffer_t databuf, sigbuf; isc_buffer_t *dynbuf; dns_name_t *owner; dns_rdata_t *rdata = NULL; dns_rdatalist_t *datalist; dns_rdataset_t *dataset; isc_region_t r; isc_stdtime_t now; isc_mem_t *mctx; dst_context_t *ctx = NULL; isc_result_t ret; unsigned char badtimedata[BADTIMELEN]; unsigned int sigsize = 0; isc_boolean_t response = is_response(msg); REQUIRE(msg != NULL); REQUIRE(VALID_TSIG_KEY(dns_message_gettsigkey(msg))); /* * If this is a response, there should be a query tsig. */ if (response && msg->querytsig == NULL) return (DNS_R_EXPECTEDTSIG); dynbuf = NULL; mctx = msg->mctx; key = dns_message_gettsigkey(msg); tsig.mctx = mctx; tsig.common.rdclass = dns_rdataclass_any; tsig.common.rdtype = dns_rdatatype_tsig; ISC_LINK_INIT(&tsig.common, link); dns_name_init(&tsig.algorithm, NULL); dns_name_clone(key->algorithm, &tsig.algorithm); isc_stdtime_get(&now); tsig.timesigned = now + msg->timeadjust; tsig.fudge = DNS_TSIG_FUDGE; tsig.originalid = msg->id; isc_buffer_init(&databuf, data, sizeof(data)); if (response) tsig.error = msg->querytsigstatus; else tsig.error = dns_rcode_noerror; if (tsig.error != dns_tsigerror_badtime) { tsig.otherlen = 0; tsig.other = NULL; } else { isc_buffer_t otherbuf; tsig.otherlen = BADTIMELEN; tsig.other = badtimedata; isc_buffer_init(&otherbuf, tsig.other, tsig.otherlen); isc_buffer_putuint48(&otherbuf, tsig.timesigned); } if (key->key != NULL && tsig.error != dns_tsigerror_badsig) { unsigned char header[DNS_MESSAGE_HEADERLEN]; isc_buffer_t headerbuf; isc_uint16_t digestbits; ret = dst_context_create3(key->key, mctx, DNS_LOGCATEGORY_DNSSEC, ISC_TRUE, &ctx); if (ret != ISC_R_SUCCESS) return (ret); /* * If this is a response, digest the query signature. */ if (response) { dns_rdata_t querytsigrdata = DNS_RDATA_INIT; ret = dns_rdataset_first(msg->querytsig); if (ret != ISC_R_SUCCESS) goto cleanup_context; dns_rdataset_current(msg->querytsig, &querytsigrdata); ret = dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL); if (ret != ISC_R_SUCCESS) goto cleanup_context; isc_buffer_putuint16(&databuf, querytsig.siglen); if (isc_buffer_availablelength(&databuf) < querytsig.siglen) { ret = ISC_R_NOSPACE; goto cleanup_context; } isc_buffer_putmem(&databuf, querytsig.signature, querytsig.siglen); isc_buffer_usedregion(&databuf, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; } #if defined(__clang__) && \ ( __clang_major__ < 3 || \ (__clang_major__ == 3 && __clang_minor__ < 2) || \ (__clang_major__ == 4 && __clang_minor__ < 2)) /* false positive: http://llvm.org/bugs/show_bug.cgi?id=14461 */ else memset(&querytsig, 0, sizeof(querytsig)); #endif /* * Digest the header. */ isc_buffer_init(&headerbuf, header, sizeof(header)); dns_message_renderheader(msg, &headerbuf); isc_buffer_usedregion(&headerbuf, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; /* * Digest the remainder of the message. */ isc_buffer_usedregion(msg->buffer, &r); isc_region_consume(&r, DNS_MESSAGE_HEADERLEN); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; if (msg->tcp_continuation == 0) { /* * Digest the name, class, ttl, alg. */ dns_name_toregion(&key->name, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; isc_buffer_clear(&databuf); isc_buffer_putuint16(&databuf, dns_rdataclass_any); isc_buffer_putuint32(&databuf, 0); /* ttl */ isc_buffer_usedregion(&databuf, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; dns_name_toregion(&tsig.algorithm, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; } /* Digest the timesigned and fudge */ isc_buffer_clear(&databuf); if (tsig.error == dns_tsigerror_badtime) { INSIST(response); tsig.timesigned = querytsig.timesigned; } isc_buffer_putuint48(&databuf, tsig.timesigned); isc_buffer_putuint16(&databuf, tsig.fudge); isc_buffer_usedregion(&databuf, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; if (msg->tcp_continuation == 0) { /* * Digest the error and other data length. */ isc_buffer_clear(&databuf); isc_buffer_putuint16(&databuf, tsig.error); isc_buffer_putuint16(&databuf, tsig.otherlen); isc_buffer_usedregion(&databuf, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; /* * Digest other data. */ if (tsig.otherlen > 0) { r.length = tsig.otherlen; r.base = tsig.other; ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; } } ret = dst_key_sigsize(key->key, &sigsize); if (ret != ISC_R_SUCCESS) goto cleanup_context; tsig.signature = (unsigned char *) isc_mem_get(mctx, sigsize); if (tsig.signature == NULL) { ret = ISC_R_NOMEMORY; goto cleanup_context; } isc_buffer_init(&sigbuf, tsig.signature, sigsize); ret = dst_context_sign(ctx, &sigbuf); if (ret != ISC_R_SUCCESS) goto cleanup_signature; dst_context_destroy(&ctx); digestbits = dst_key_getbits(key->key); if (digestbits != 0) { unsigned int bytes = (digestbits + 1) / 8; if (response && bytes < querytsig.siglen) bytes = querytsig.siglen; if (bytes > isc_buffer_usedlength(&sigbuf)) bytes = isc_buffer_usedlength(&sigbuf); tsig.siglen = bytes; } else tsig.siglen = isc_buffer_usedlength(&sigbuf); } else { tsig.siglen = 0; tsig.signature = NULL; } ret = dns_message_gettemprdata(msg, &rdata); if (ret != ISC_R_SUCCESS) goto cleanup_signature; ret = isc_buffer_allocate(msg->mctx, &dynbuf, 512); if (ret != ISC_R_SUCCESS) goto cleanup_rdata; ret = dns_rdata_fromstruct(rdata, dns_rdataclass_any, dns_rdatatype_tsig, &tsig, dynbuf); if (ret != ISC_R_SUCCESS) goto cleanup_dynbuf; dns_message_takebuffer(msg, &dynbuf); if (tsig.signature != NULL) { isc_mem_put(mctx, tsig.signature, sigsize); tsig.signature = NULL; } owner = NULL; ret = dns_message_gettempname(msg, &owner); if (ret != ISC_R_SUCCESS) goto cleanup_rdata; dns_name_init(owner, NULL); ret = dns_name_dup(&key->name, msg->mctx, owner); if (ret != ISC_R_SUCCESS) goto cleanup_owner; datalist = NULL; ret = dns_message_gettemprdatalist(msg, &datalist); if (ret != ISC_R_SUCCESS) goto cleanup_owner; dataset = NULL; ret = dns_message_gettemprdataset(msg, &dataset); if (ret != ISC_R_SUCCESS) goto cleanup_rdatalist; datalist->rdclass = dns_rdataclass_any; datalist->type = dns_rdatatype_tsig; ISC_LIST_APPEND(datalist->rdata, rdata, link); RUNTIME_CHECK(dns_rdatalist_tordataset(datalist, dataset) == ISC_R_SUCCESS); msg->tsig = dataset; msg->tsigname = owner; /* Windows does not like the tsig name being compressed. */ msg->tsigname->attributes |= DNS_NAMEATTR_NOCOMPRESS; return (ISC_R_SUCCESS); cleanup_rdatalist: dns_message_puttemprdatalist(msg, &datalist); cleanup_owner: dns_message_puttempname(msg, &owner); goto cleanup_rdata; cleanup_dynbuf: isc_buffer_free(&dynbuf); cleanup_rdata: dns_message_puttemprdata(msg, &rdata); cleanup_signature: if (tsig.signature != NULL) isc_mem_put(mctx, tsig.signature, sigsize); cleanup_context: if (ctx != NULL) dst_context_destroy(&ctx); return (ret); } isc_result_t dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg, dns_tsig_keyring_t *ring1, dns_tsig_keyring_t *ring2) { dns_rdata_any_tsig_t tsig, querytsig; isc_region_t r, source_r, header_r, sig_r; isc_buffer_t databuf; unsigned char data[32]; dns_name_t *keyname; dns_rdata_t rdata = DNS_RDATA_INIT; isc_stdtime_t now; isc_result_t ret; dns_tsigkey_t *tsigkey; dst_key_t *key = NULL; unsigned char header[DNS_MESSAGE_HEADERLEN]; dst_context_t *ctx = NULL; isc_mem_t *mctx; isc_uint16_t addcount, id; unsigned int siglen; unsigned int alg; isc_boolean_t response; REQUIRE(source != NULL); REQUIRE(DNS_MESSAGE_VALID(msg)); tsigkey = dns_message_gettsigkey(msg); response = is_response(msg); REQUIRE(tsigkey == NULL || VALID_TSIG_KEY(tsigkey)); msg->verify_attempted = 1; if (msg->tcp_continuation) { if (tsigkey == NULL || msg->querytsig == NULL) return (DNS_R_UNEXPECTEDTSIG); return (tsig_verify_tcp(source, msg)); } /* * There should be a TSIG record... */ if (msg->tsig == NULL) return (DNS_R_EXPECTEDTSIG); /* * If this is a response and there's no key or query TSIG, there * shouldn't be one on the response. */ if (response && (tsigkey == NULL || msg->querytsig == NULL)) return (DNS_R_UNEXPECTEDTSIG); mctx = msg->mctx; /* * If we're here, we know the message is well formed and contains a * TSIG record. */ keyname = msg->tsigname; ret = dns_rdataset_first(msg->tsig); if (ret != ISC_R_SUCCESS) return (ret); dns_rdataset_current(msg->tsig, &rdata); ret = dns_rdata_tostruct(&rdata, &tsig, NULL); if (ret != ISC_R_SUCCESS) return (ret); dns_rdata_reset(&rdata); if (response) { ret = dns_rdataset_first(msg->querytsig); if (ret != ISC_R_SUCCESS) return (ret); dns_rdataset_current(msg->querytsig, &rdata); ret = dns_rdata_tostruct(&rdata, &querytsig, NULL); if (ret != ISC_R_SUCCESS) return (ret); } #if defined(__clang__) && \ ( __clang_major__ < 3 || \ (__clang_major__ == 3 && __clang_minor__ < 2) || \ (__clang_major__ == 4 && __clang_minor__ < 2)) /* false positive: http://llvm.org/bugs/show_bug.cgi?id=14461 */ else memset(&querytsig, 0, sizeof(querytsig)); #endif /* * Do the key name and algorithm match that of the query? */ if (response && (!dns_name_equal(keyname, &tsigkey->name) || !dns_name_equal(&tsig.algorithm, &querytsig.algorithm))) { msg->tsigstatus = dns_tsigerror_badkey; tsig_log(msg->tsigkey, 2, "key name and algorithm do not match"); return (DNS_R_TSIGVERIFYFAILURE); } /* * Get the current time. */ isc_stdtime_get(&now); /* * Find dns_tsigkey_t based on keyname. */ if (tsigkey == NULL) { ret = ISC_R_NOTFOUND; if (ring1 != NULL) ret = dns_tsigkey_find(&tsigkey, keyname, &tsig.algorithm, ring1); if (ret == ISC_R_NOTFOUND && ring2 != NULL) ret = dns_tsigkey_find(&tsigkey, keyname, &tsig.algorithm, ring2); if (ret != ISC_R_SUCCESS) { msg->tsigstatus = dns_tsigerror_badkey; ret = dns_tsigkey_create(keyname, &tsig.algorithm, NULL, 0, ISC_FALSE, NULL, now, now, mctx, NULL, &msg->tsigkey); if (ret != ISC_R_SUCCESS) return (ret); tsig_log(msg->tsigkey, 2, "unknown key"); return (DNS_R_TSIGVERIFYFAILURE); } msg->tsigkey = tsigkey; } key = tsigkey->key; /* * Is the time ok? */ if (now + msg->timeadjust > tsig.timesigned + tsig.fudge) { msg->tsigstatus = dns_tsigerror_badtime; tsig_log(msg->tsigkey, 2, "signature has expired"); return (DNS_R_CLOCKSKEW); } else if (now + msg->timeadjust < tsig.timesigned - tsig.fudge) { msg->tsigstatus = dns_tsigerror_badtime; tsig_log(msg->tsigkey, 2, "signature is in the future"); return (DNS_R_CLOCKSKEW); } /* * Check digest length. */ alg = dst_key_alg(key); ret = dst_key_sigsize(key, &siglen); if (ret != ISC_R_SUCCESS) return (ret); if (alg == DST_ALG_HMACMD5 || alg == DST_ALG_HMACSHA1 || alg == DST_ALG_HMACSHA224 || alg == DST_ALG_HMACSHA256 || alg == DST_ALG_HMACSHA384 || alg == DST_ALG_HMACSHA512) { isc_uint16_t digestbits = dst_key_getbits(key); if (tsig.siglen > siglen) { tsig_log(msg->tsigkey, 2, "signature length too big"); return (DNS_R_FORMERR); } if (tsig.siglen > 0 && (tsig.siglen < 10 || tsig.siglen < ((siglen + 1) / 2))) { tsig_log(msg->tsigkey, 2, "signature length below minimum"); return (DNS_R_FORMERR); } if (tsig.siglen > 0 && digestbits != 0 && tsig.siglen < ((digestbits + 1) / 8)) { msg->tsigstatus = dns_tsigerror_badtrunc; tsig_log(msg->tsigkey, 2, "truncated signature length too small"); return (DNS_R_TSIGVERIFYFAILURE); } if (tsig.siglen > 0 && digestbits == 0 && tsig.siglen < siglen) { msg->tsigstatus = dns_tsigerror_badtrunc; tsig_log(msg->tsigkey, 2, "signature length too small"); return (DNS_R_TSIGVERIFYFAILURE); } } if (tsig.siglen > 0) { isc_uint16_t addcount_n; sig_r.base = tsig.signature; sig_r.length = tsig.siglen; ret = dst_context_create3(key, mctx, DNS_LOGCATEGORY_DNSSEC, ISC_FALSE, &ctx); if (ret != ISC_R_SUCCESS) return (ret); if (response) { isc_buffer_init(&databuf, data, sizeof(data)); isc_buffer_putuint16(&databuf, querytsig.siglen); isc_buffer_usedregion(&databuf, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; if (querytsig.siglen > 0) { r.length = querytsig.siglen; r.base = querytsig.signature; ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; } } /* * Extract the header. */ isc_buffer_usedregion(source, &r); memmove(header, r.base, DNS_MESSAGE_HEADERLEN); isc_region_consume(&r, DNS_MESSAGE_HEADERLEN); /* * Decrement the additional field counter. */ memmove(&addcount, &header[DNS_MESSAGE_HEADERLEN - 2], 2); addcount_n = ntohs(addcount); addcount = htons((isc_uint16_t)(addcount_n - 1)); memmove(&header[DNS_MESSAGE_HEADERLEN - 2], &addcount, 2); /* * Put in the original id. */ id = htons(tsig.originalid); memmove(&header[0], &id, 2); /* * Digest the modified header. */ header_r.base = (unsigned char *) header; header_r.length = DNS_MESSAGE_HEADERLEN; ret = dst_context_adddata(ctx, &header_r); if (ret != ISC_R_SUCCESS) goto cleanup_context; /* * Digest all non-TSIG records. */ isc_buffer_usedregion(source, &source_r); r.base = source_r.base + DNS_MESSAGE_HEADERLEN; r.length = msg->sigstart - DNS_MESSAGE_HEADERLEN; ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; /* * Digest the key name. */ dns_name_toregion(&tsigkey->name, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; isc_buffer_init(&databuf, data, sizeof(data)); isc_buffer_putuint16(&databuf, tsig.common.rdclass); isc_buffer_putuint32(&databuf, msg->tsig->ttl); isc_buffer_usedregion(&databuf, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; /* * Digest the key algorithm. */ dns_name_toregion(tsigkey->algorithm, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; isc_buffer_clear(&databuf); isc_buffer_putuint48(&databuf, tsig.timesigned); isc_buffer_putuint16(&databuf, tsig.fudge); isc_buffer_putuint16(&databuf, tsig.error); isc_buffer_putuint16(&databuf, tsig.otherlen); isc_buffer_usedregion(&databuf, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; if (tsig.otherlen > 0) { r.base = tsig.other; r.length = tsig.otherlen; ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; } ret = dst_context_verify(ctx, &sig_r); if (ret == DST_R_VERIFYFAILURE) { msg->tsigstatus = dns_tsigerror_badsig; ret = DNS_R_TSIGVERIFYFAILURE; tsig_log(msg->tsigkey, 2, "signature failed to verify(1)"); goto cleanup_context; } else if (ret != ISC_R_SUCCESS) goto cleanup_context; dst_context_destroy(&ctx); } else if (tsig.error != dns_tsigerror_badsig && tsig.error != dns_tsigerror_badkey) { msg->tsigstatus = dns_tsigerror_badsig; tsig_log(msg->tsigkey, 2, "signature was empty"); return (DNS_R_TSIGVERIFYFAILURE); } msg->tsigstatus = dns_rcode_noerror; if (tsig.error != dns_rcode_noerror) { if (tsig.error == dns_tsigerror_badtime) return (DNS_R_CLOCKSKEW); else return (DNS_R_TSIGERRORSET); } msg->verified_sig = 1; return (ISC_R_SUCCESS); cleanup_context: if (ctx != NULL) dst_context_destroy(&ctx); return (ret); } static isc_result_t tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) { dns_rdata_any_tsig_t tsig, querytsig; isc_region_t r, source_r, header_r, sig_r; isc_buffer_t databuf; unsigned char data[32]; dns_name_t *keyname; dns_rdata_t rdata = DNS_RDATA_INIT; isc_stdtime_t now; isc_result_t ret; dns_tsigkey_t *tsigkey; dst_key_t *key = NULL; unsigned char header[DNS_MESSAGE_HEADERLEN]; isc_uint16_t addcount, id; isc_boolean_t has_tsig = ISC_FALSE; isc_mem_t *mctx; REQUIRE(source != NULL); REQUIRE(msg != NULL); REQUIRE(dns_message_gettsigkey(msg) != NULL); REQUIRE(msg->tcp_continuation == 1); REQUIRE(msg->querytsig != NULL); if (!is_response(msg)) return (DNS_R_EXPECTEDRESPONSE); mctx = msg->mctx; tsigkey = dns_message_gettsigkey(msg); /* * Extract and parse the previous TSIG */ ret = dns_rdataset_first(msg->querytsig); if (ret != ISC_R_SUCCESS) return (ret); dns_rdataset_current(msg->querytsig, &rdata); ret = dns_rdata_tostruct(&rdata, &querytsig, NULL); if (ret != ISC_R_SUCCESS) return (ret); dns_rdata_reset(&rdata); /* * If there is a TSIG in this message, do some checks. */ if (msg->tsig != NULL) { has_tsig = ISC_TRUE; keyname = msg->tsigname; ret = dns_rdataset_first(msg->tsig); if (ret != ISC_R_SUCCESS) goto cleanup_querystruct; dns_rdataset_current(msg->tsig, &rdata); ret = dns_rdata_tostruct(&rdata, &tsig, NULL); if (ret != ISC_R_SUCCESS) goto cleanup_querystruct; /* * Do the key name and algorithm match that of the query? */ if (!dns_name_equal(keyname, &tsigkey->name) || !dns_name_equal(&tsig.algorithm, &querytsig.algorithm)) { msg->tsigstatus = dns_tsigerror_badkey; ret = DNS_R_TSIGVERIFYFAILURE; tsig_log(msg->tsigkey, 2, "key name and algorithm do not match"); goto cleanup_querystruct; } /* * Is the time ok? */ isc_stdtime_get(&now); if (now + msg->timeadjust > tsig.timesigned + tsig.fudge) { msg->tsigstatus = dns_tsigerror_badtime; tsig_log(msg->tsigkey, 2, "signature has expired"); ret = DNS_R_CLOCKSKEW; goto cleanup_querystruct; } else if (now + msg->timeadjust < tsig.timesigned - tsig.fudge) { msg->tsigstatus = dns_tsigerror_badtime; tsig_log(msg->tsigkey, 2, "signature is in the future"); ret = DNS_R_CLOCKSKEW; goto cleanup_querystruct; } } key = tsigkey->key; if (msg->tsigctx == NULL) { ret = dst_context_create3(key, mctx, DNS_LOGCATEGORY_DNSSEC, ISC_FALSE, &msg->tsigctx); if (ret != ISC_R_SUCCESS) goto cleanup_querystruct; /* * Digest the length of the query signature */ isc_buffer_init(&databuf, data, sizeof(data)); isc_buffer_putuint16(&databuf, querytsig.siglen); isc_buffer_usedregion(&databuf, &r); ret = dst_context_adddata(msg->tsigctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; /* * Digest the data of the query signature */ if (querytsig.siglen > 0) { r.length = querytsig.siglen; r.base = querytsig.signature; ret = dst_context_adddata(msg->tsigctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; } } /* * Extract the header. */ isc_buffer_usedregion(source, &r); memmove(header, r.base, DNS_MESSAGE_HEADERLEN); isc_region_consume(&r, DNS_MESSAGE_HEADERLEN); /* * Decrement the additional field counter if necessary. */ if (has_tsig) { isc_uint16_t addcount_n; memmove(&addcount, &header[DNS_MESSAGE_HEADERLEN - 2], 2); addcount_n = ntohs(addcount); addcount = htons((isc_uint16_t)(addcount_n - 1)); memmove(&header[DNS_MESSAGE_HEADERLEN - 2], &addcount, 2); } /* * Put in the original id. */ /* XXX Can TCP transfers be forwarded? How would that work? */ if (has_tsig) { id = htons(tsig.originalid); memmove(&header[0], &id, 2); } /* * Digest the modified header. */ header_r.base = (unsigned char *) header; header_r.length = DNS_MESSAGE_HEADERLEN; ret = dst_context_adddata(msg->tsigctx, &header_r); if (ret != ISC_R_SUCCESS) goto cleanup_context; /* * Digest all non-TSIG records. */ isc_buffer_usedregion(source, &source_r); r.base = source_r.base + DNS_MESSAGE_HEADERLEN; if (has_tsig) r.length = msg->sigstart - DNS_MESSAGE_HEADERLEN; else r.length = source_r.length - DNS_MESSAGE_HEADERLEN; ret = dst_context_adddata(msg->tsigctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; /* * Digest the time signed and fudge. */ if (has_tsig) { isc_buffer_init(&databuf, data, sizeof(data)); isc_buffer_putuint48(&databuf, tsig.timesigned); isc_buffer_putuint16(&databuf, tsig.fudge); isc_buffer_usedregion(&databuf, &r); ret = dst_context_adddata(msg->tsigctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; sig_r.base = tsig.signature; sig_r.length = tsig.siglen; if (tsig.siglen == 0) { if (tsig.error != dns_rcode_noerror) { if (tsig.error == dns_tsigerror_badtime) ret = DNS_R_CLOCKSKEW; else ret = DNS_R_TSIGERRORSET; } else { tsig_log(msg->tsigkey, 2, "signature is empty"); ret = DNS_R_TSIGVERIFYFAILURE; } goto cleanup_context; } ret = dst_context_verify(msg->tsigctx, &sig_r); if (ret == DST_R_VERIFYFAILURE) { msg->tsigstatus = dns_tsigerror_badsig; tsig_log(msg->tsigkey, 2, "signature failed to verify(2)"); ret = DNS_R_TSIGVERIFYFAILURE; goto cleanup_context; } else if (ret != ISC_R_SUCCESS) goto cleanup_context; dst_context_destroy(&msg->tsigctx); } msg->tsigstatus = dns_rcode_noerror; return (ISC_R_SUCCESS); cleanup_context: dst_context_destroy(&msg->tsigctx); cleanup_querystruct: dns_rdata_freestruct(&querytsig); return (ret); } isc_result_t dns_tsigkey_find(dns_tsigkey_t **tsigkey, dns_name_t *name, dns_name_t *algorithm, dns_tsig_keyring_t *ring) { dns_tsigkey_t *key; isc_stdtime_t now; isc_result_t result; REQUIRE(tsigkey != NULL); REQUIRE(*tsigkey == NULL); REQUIRE(name != NULL); REQUIRE(ring != NULL); RWLOCK(&ring->lock, isc_rwlocktype_write); cleanup_ring(ring); RWUNLOCK(&ring->lock, isc_rwlocktype_write); isc_stdtime_get(&now); RWLOCK(&ring->lock, isc_rwlocktype_read); key = NULL; result = dns_rbt_findname(ring->keys, name, 0, NULL, (void *)&key); if (result == DNS_R_PARTIALMATCH || result == ISC_R_NOTFOUND) { RWUNLOCK(&ring->lock, isc_rwlocktype_read); return (ISC_R_NOTFOUND); } if (algorithm != NULL && !dns_name_equal(key->algorithm, algorithm)) { RWUNLOCK(&ring->lock, isc_rwlocktype_read); return (ISC_R_NOTFOUND); } if (key->inception != key->expire && isc_serial_lt(key->expire, now)) { /* * The key has expired. */ RWUNLOCK(&ring->lock, isc_rwlocktype_read); RWLOCK(&ring->lock, isc_rwlocktype_write); remove_fromring(key); RWUNLOCK(&ring->lock, isc_rwlocktype_write); return (ISC_R_NOTFOUND); } #if 0 /* * MPAXXX We really should look at the inception time. */ if (key->inception != key->expire && isc_serial_lt(key->inception, now)) { RWUNLOCK(&ring->lock, isc_rwlocktype_read); adjust_lru(key); return (ISC_R_NOTFOUND); } #endif isc_refcount_increment(&key->refs, NULL); RWUNLOCK(&ring->lock, isc_rwlocktype_read); adjust_lru(key); *tsigkey = key; return (ISC_R_SUCCESS); } static void free_tsignode(void *node, void *_unused) { dns_tsigkey_t *key; REQUIRE(node != NULL); UNUSED(_unused); key = node; if (key->generated) { if (ISC_LINK_LINKED(key, link)) ISC_LIST_UNLINK(key->ring->lru, key, link); } dns_tsigkey_detach(&key); } isc_result_t dns_tsigkeyring_create(isc_mem_t *mctx, dns_tsig_keyring_t **ringp) { isc_result_t result; dns_tsig_keyring_t *ring; REQUIRE(mctx != NULL); REQUIRE(ringp != NULL); REQUIRE(*ringp == NULL); ring = isc_mem_get(mctx, sizeof(dns_tsig_keyring_t)); if (ring == NULL) return (ISC_R_NOMEMORY); result = isc_rwlock_init(&ring->lock, 0, 0); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, ring, sizeof(dns_tsig_keyring_t)); return (result); } ring->keys = NULL; result = dns_rbt_create(mctx, free_tsignode, NULL, &ring->keys); if (result != ISC_R_SUCCESS) { isc_rwlock_destroy(&ring->lock); isc_mem_put(mctx, ring, sizeof(dns_tsig_keyring_t)); return (result); } ring->writecount = 0; ring->mctx = NULL; ring->generated = 0; ring->maxgenerated = DNS_TSIG_MAXGENERATEDKEYS; ISC_LIST_INIT(ring->lru); isc_mem_attach(mctx, &ring->mctx); ring->references = 1; *ringp = ring; return (ISC_R_SUCCESS); } isc_result_t dns_tsigkeyring_add(dns_tsig_keyring_t *ring, dns_name_t *name, dns_tsigkey_t *tkey) { isc_result_t result; result = keyring_add(ring, name, tkey); if (result == ISC_R_SUCCESS) isc_refcount_increment(&tkey->refs, NULL); return (result); } void dns_tsigkeyring_attach(dns_tsig_keyring_t *source, dns_tsig_keyring_t **target) { REQUIRE(source != NULL); REQUIRE(target != NULL && *target == NULL); RWLOCK(&source->lock, isc_rwlocktype_write); INSIST(source->references > 0); source->references++; INSIST(source->references > 0); *target = source; RWUNLOCK(&source->lock, isc_rwlocktype_write); } void dns_tsigkeyring_detach(dns_tsig_keyring_t **ringp) { dns_tsig_keyring_t *ring; unsigned int references; REQUIRE(ringp != NULL); REQUIRE(*ringp != NULL); ring = *ringp; *ringp = NULL; RWLOCK(&ring->lock, isc_rwlocktype_write); INSIST(ring->references > 0); ring->references--; references = ring->references; RWUNLOCK(&ring->lock, isc_rwlocktype_write); if (references == 0) destroyring(ring); } void dns_keyring_restore(dns_tsig_keyring_t *ring, FILE *fp) { isc_stdtime_t now; isc_result_t result; isc_stdtime_get(&now); do { result = restore_key(ring, now, fp); if (result == ISC_R_NOMORE) return; if (result == DNS_R_BADALG || result == DNS_R_EXPIRED) result = ISC_R_SUCCESS; } while (result == ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/dns/keytable.c0000644000470500017500000003770512664710322016703 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2010, 2013-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: keytable.c,v 1.41 2010/06/25 23:46:51 tbox Exp $ */ /*! \file */ #include #include #include #include #include /* Required for HP/UX (and others?) */ #include #include #include #include #include static void free_keynode(void *node, void *arg) { dns_keynode_t *keynode = node; isc_mem_t *mctx = arg; dns_keynode_detachall(mctx, &keynode); } isc_result_t dns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep) { dns_keytable_t *keytable; isc_result_t result; /* * Create a keytable. */ REQUIRE(keytablep != NULL && *keytablep == NULL); keytable = isc_mem_get(mctx, sizeof(*keytable)); if (keytable == NULL) return (ISC_R_NOMEMORY); keytable->table = NULL; result = dns_rbt_create(mctx, free_keynode, mctx, &keytable->table); if (result != ISC_R_SUCCESS) goto cleanup_keytable; result = isc_mutex_init(&keytable->lock); if (result != ISC_R_SUCCESS) goto cleanup_rbt; result = isc_rwlock_init(&keytable->rwlock, 0, 0); if (result != ISC_R_SUCCESS) goto cleanup_lock; keytable->mctx = NULL; isc_mem_attach(mctx, &keytable->mctx); keytable->active_nodes = 0; keytable->references = 1; keytable->magic = KEYTABLE_MAGIC; *keytablep = keytable; return (ISC_R_SUCCESS); cleanup_lock: DESTROYLOCK(&keytable->lock); cleanup_rbt: dns_rbt_destroy(&keytable->table); cleanup_keytable: isc_mem_putanddetach(&mctx, keytable, sizeof(*keytable)); return (result); } void dns_keytable_attach(dns_keytable_t *source, dns_keytable_t **targetp) { /* * Attach *targetp to source. */ REQUIRE(VALID_KEYTABLE(source)); REQUIRE(targetp != NULL && *targetp == NULL); RWLOCK(&source->rwlock, isc_rwlocktype_write); INSIST(source->references > 0); source->references++; INSIST(source->references != 0); RWUNLOCK(&source->rwlock, isc_rwlocktype_write); *targetp = source; } void dns_keytable_detach(dns_keytable_t **keytablep) { isc_boolean_t destroy = ISC_FALSE; dns_keytable_t *keytable; /* * Detach *keytablep from its keytable. */ REQUIRE(keytablep != NULL && VALID_KEYTABLE(*keytablep)); keytable = *keytablep; RWLOCK(&keytable->rwlock, isc_rwlocktype_write); INSIST(keytable->references > 0); keytable->references--; LOCK(&keytable->lock); if (keytable->references == 0 && keytable->active_nodes == 0) destroy = ISC_TRUE; UNLOCK(&keytable->lock); RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write); if (destroy) { dns_rbt_destroy(&keytable->table); isc_rwlock_destroy(&keytable->rwlock); DESTROYLOCK(&keytable->lock); keytable->magic = 0; isc_mem_putanddetach(&keytable->mctx, keytable, sizeof(*keytable)); } *keytablep = NULL; } static isc_result_t insert(dns_keytable_t *keytable, isc_boolean_t managed, dns_name_t *keyname, dst_key_t **keyp) { isc_result_t result; dns_keynode_t *knode = NULL; dns_rbtnode_t *node; REQUIRE(keyp == NULL || *keyp != NULL); REQUIRE(VALID_KEYTABLE(keytable)); result = dns_keynode_create(keytable->mctx, &knode); if (result != ISC_R_SUCCESS) return (result); knode->managed = managed; RWLOCK(&keytable->rwlock, isc_rwlocktype_write); node = NULL; result = dns_rbt_addnode(keytable->table, keyname, &node); if (keyp != NULL) { if (result == ISC_R_EXISTS) { /* Key already in table? */ dns_keynode_t *k; for (k = node->data; k != NULL; k = k->next) { if (k->key == NULL) { k->key = *keyp; *keyp = NULL; /* transfer ownership */ break; } if (dst_key_compare(k->key, *keyp) == ISC_TRUE) break; } if (k == NULL) result = ISC_R_SUCCESS; else if (*keyp != NULL) dst_key_free(keyp); } if (result == ISC_R_SUCCESS) { knode->key = *keyp; knode->next = node->data; *keyp = NULL; } } if (result == ISC_R_SUCCESS) { node->data = knode; knode = NULL; } /* Key was already there? That's the same as a success */ if (result == ISC_R_EXISTS) result = ISC_R_SUCCESS; RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write); if (knode != NULL) dns_keynode_detach(keytable->mctx, &knode); return (result); } isc_result_t dns_keytable_add(dns_keytable_t *keytable, isc_boolean_t managed, dst_key_t **keyp) { REQUIRE(keyp != NULL && *keyp != NULL); return (insert(keytable, managed, dst_key_name(*keyp), keyp)); } isc_result_t dns_keytable_marksecure(dns_keytable_t *keytable, dns_name_t *name) { return (insert(keytable, ISC_TRUE, name, NULL)); } isc_result_t dns_keytable_delete(dns_keytable_t *keytable, dns_name_t *keyname) { isc_result_t result; dns_rbtnode_t *node = NULL; REQUIRE(VALID_KEYTABLE(keytable)); REQUIRE(keyname != NULL); RWLOCK(&keytable->rwlock, isc_rwlocktype_write); result = dns_rbt_findnode(keytable->table, keyname, NULL, &node, NULL, DNS_RBTFIND_NOOPTIONS, NULL, NULL); if (result == ISC_R_SUCCESS) { if (node->data != NULL) result = dns_rbt_deletenode(keytable->table, node, ISC_FALSE); else result = ISC_R_NOTFOUND; } else if (result == DNS_R_PARTIALMATCH) result = ISC_R_NOTFOUND; RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write); return (result); } isc_result_t dns_keytable_deletekeynode(dns_keytable_t *keytable, dst_key_t *dstkey) { isc_result_t result; dns_name_t *keyname; dns_rbtnode_t *node = NULL; dns_keynode_t *knode = NULL, **kprev = NULL; REQUIRE(VALID_KEYTABLE(keytable)); REQUIRE(dstkey != NULL); keyname = dst_key_name(dstkey); RWLOCK(&keytable->rwlock, isc_rwlocktype_write); result = dns_rbt_findnode(keytable->table, keyname, NULL, &node, NULL, DNS_RBTFIND_NOOPTIONS, NULL, NULL); if (result == DNS_R_PARTIALMATCH) result = ISC_R_NOTFOUND; if (result != ISC_R_SUCCESS) goto finish; if (node->data == NULL) { result = ISC_R_NOTFOUND; goto finish; } knode = node->data; if (knode->next == NULL && knode->key != NULL && dst_key_compare(knode->key, dstkey) == ISC_TRUE) { result = dns_rbt_deletenode(keytable->table, node, ISC_FALSE); goto finish; } kprev = (dns_keynode_t **) &node->data; while (knode != NULL) { if (knode->key != NULL && dst_key_compare(knode->key, dstkey) == ISC_TRUE) break; kprev = &knode->next; knode = knode->next; } if (knode != NULL) { if (knode->key != NULL) dst_key_free(&knode->key); /* * This is equivalent to: * dns_keynode_attach(knode->next, &tmp); * dns_keynode_detach(kprev); * dns_keynode_attach(tmp, &kprev); * dns_keynode_detach(&tmp); */ *kprev = knode->next; knode->next = NULL; dns_keynode_detach(keytable->mctx, &knode); } else result = DNS_R_PARTIALMATCH; finish: RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write); return (result); } isc_result_t dns_keytable_find(dns_keytable_t *keytable, dns_name_t *keyname, dns_keynode_t **keynodep) { isc_result_t result; dns_rbtnode_t *node = NULL; REQUIRE(VALID_KEYTABLE(keytable)); REQUIRE(keyname != NULL); REQUIRE(keynodep != NULL && *keynodep == NULL); RWLOCK(&keytable->rwlock, isc_rwlocktype_read); result = dns_rbt_findnode(keytable->table, keyname, NULL, &node, NULL, DNS_RBTFIND_NOOPTIONS, NULL, NULL); if (result == ISC_R_SUCCESS) { if (node->data != NULL) { LOCK(&keytable->lock); keytable->active_nodes++; UNLOCK(&keytable->lock); dns_keynode_attach(node->data, keynodep); } else result = ISC_R_NOTFOUND; } else if (result == DNS_R_PARTIALMATCH) result = ISC_R_NOTFOUND; RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read); return (result); } isc_result_t dns_keytable_nextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode, dns_keynode_t **nextnodep) { /* * Return the next key after 'keynode', regardless of * properties. */ REQUIRE(VALID_KEYTABLE(keytable)); REQUIRE(VALID_KEYNODE(keynode)); REQUIRE(nextnodep != NULL && *nextnodep == NULL); if (keynode->next == NULL) return (ISC_R_NOTFOUND); dns_keynode_attach(keynode->next, nextnodep); LOCK(&keytable->lock); keytable->active_nodes++; UNLOCK(&keytable->lock); return (ISC_R_SUCCESS); } isc_result_t dns_keytable_findkeynode(dns_keytable_t *keytable, dns_name_t *name, dns_secalg_t algorithm, dns_keytag_t tag, dns_keynode_t **keynodep) { isc_result_t result; dns_keynode_t *knode; void *data; /* * Search for a key named 'name', matching 'algorithm' and 'tag' in * 'keytable'. */ REQUIRE(VALID_KEYTABLE(keytable)); REQUIRE(dns_name_isabsolute(name)); REQUIRE(keynodep != NULL && *keynodep == NULL); RWLOCK(&keytable->rwlock, isc_rwlocktype_read); /* * Note we don't want the DNS_R_PARTIALMATCH from dns_rbt_findname() * as that indicates that 'name' was not found. * * DNS_R_PARTIALMATCH indicates that the name was found but we * didn't get a match on algorithm and key id arguments. */ knode = NULL; data = NULL; result = dns_rbt_findname(keytable->table, name, 0, NULL, &data); if (result == ISC_R_SUCCESS) { INSIST(data != NULL); for (knode = data; knode != NULL; knode = knode->next) { if (knode->key == NULL) { knode = NULL; break; } if (algorithm == dst_key_alg(knode->key) && tag == dst_key_id(knode->key)) break; } if (knode != NULL) { LOCK(&keytable->lock); keytable->active_nodes++; UNLOCK(&keytable->lock); dns_keynode_attach(knode, keynodep); } else result = DNS_R_PARTIALMATCH; } else if (result == DNS_R_PARTIALMATCH) result = ISC_R_NOTFOUND; RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read); return (result); } isc_result_t dns_keytable_findnextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode, dns_keynode_t **nextnodep) { isc_result_t result; dns_keynode_t *knode; /* * Search for the next key with the same properties as 'keynode' in * 'keytable'. */ REQUIRE(VALID_KEYTABLE(keytable)); REQUIRE(VALID_KEYNODE(keynode)); REQUIRE(nextnodep != NULL && *nextnodep == NULL); for (knode = keynode->next; knode != NULL; knode = knode->next) { if (knode->key == NULL) { knode = NULL; break; } if (dst_key_alg(keynode->key) == dst_key_alg(knode->key) && dst_key_id(keynode->key) == dst_key_id(knode->key)) break; } if (knode != NULL) { LOCK(&keytable->lock); keytable->active_nodes++; UNLOCK(&keytable->lock); result = ISC_R_SUCCESS; dns_keynode_attach(knode, nextnodep); } else result = ISC_R_NOTFOUND; return (result); } isc_result_t dns_keytable_finddeepestmatch(dns_keytable_t *keytable, dns_name_t *name, dns_name_t *foundname) { isc_result_t result; void *data; /* * Search for the deepest match in 'keytable'. */ REQUIRE(VALID_KEYTABLE(keytable)); REQUIRE(dns_name_isabsolute(name)); REQUIRE(foundname != NULL); RWLOCK(&keytable->rwlock, isc_rwlocktype_read); data = NULL; result = dns_rbt_findname(keytable->table, name, 0, foundname, &data); if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) result = ISC_R_SUCCESS; RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read); return (result); } void dns_keytable_attachkeynode(dns_keytable_t *keytable, dns_keynode_t *source, dns_keynode_t **target) { /* * Give back a keynode found via dns_keytable_findkeynode(). */ REQUIRE(VALID_KEYTABLE(keytable)); REQUIRE(VALID_KEYNODE(source)); REQUIRE(target != NULL && *target == NULL); LOCK(&keytable->lock); keytable->active_nodes++; UNLOCK(&keytable->lock); dns_keynode_attach(source, target); } void dns_keytable_detachkeynode(dns_keytable_t *keytable, dns_keynode_t **keynodep) { /* * Give back a keynode found via dns_keytable_findkeynode(). */ REQUIRE(VALID_KEYTABLE(keytable)); REQUIRE(keynodep != NULL && VALID_KEYNODE(*keynodep)); LOCK(&keytable->lock); INSIST(keytable->active_nodes > 0); keytable->active_nodes--; UNLOCK(&keytable->lock); dns_keynode_detach(keytable->mctx, keynodep); } isc_result_t dns_keytable_issecuredomain(dns_keytable_t *keytable, dns_name_t *name, isc_boolean_t *wantdnssecp) { isc_result_t result; void *data; /* * Is 'name' at or beneath a trusted key? */ REQUIRE(VALID_KEYTABLE(keytable)); REQUIRE(dns_name_isabsolute(name)); REQUIRE(wantdnssecp != NULL); RWLOCK(&keytable->rwlock, isc_rwlocktype_read); data = NULL; result = dns_rbt_findname(keytable->table, name, 0, NULL, &data); if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { INSIST(data != NULL); *wantdnssecp = ISC_TRUE; result = ISC_R_SUCCESS; } else if (result == ISC_R_NOTFOUND) { *wantdnssecp = ISC_FALSE; result = ISC_R_SUCCESS; } RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read); return (result); } isc_result_t dns_keytable_dump(dns_keytable_t *keytable, FILE *fp) { isc_result_t result; dns_keynode_t *knode; dns_rbtnode_t *node; dns_rbtnodechain_t chain; REQUIRE(VALID_KEYTABLE(keytable)); RWLOCK(&keytable->rwlock, isc_rwlocktype_read); dns_rbtnodechain_init(&chain, keytable->mctx); result = dns_rbtnodechain_first(&chain, keytable->table, NULL, NULL); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) goto cleanup; for (;;) { char pbuf[DST_KEY_FORMATSIZE]; dns_rbtnodechain_current(&chain, NULL, NULL, &node); for (knode = node->data; knode != NULL; knode = knode->next) { if (knode->key == NULL) continue; dst_key_format(knode->key, pbuf, sizeof(pbuf)); fprintf(fp, "%s ; %s\n", pbuf, knode->managed ? "managed" : "trusted"); } result = dns_rbtnodechain_next(&chain, NULL, NULL); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; break; } } cleanup: dns_rbtnodechain_invalidate(&chain); RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read); return (result); } dst_key_t * dns_keynode_key(dns_keynode_t *keynode) { /* * Get the DST key associated with keynode. */ REQUIRE(VALID_KEYNODE(keynode)); return (keynode->key); } isc_boolean_t dns_keynode_managed(dns_keynode_t *keynode) { /* * Is this a managed key? */ REQUIRE(VALID_KEYNODE(keynode)); return (keynode->managed); } isc_result_t dns_keynode_create(isc_mem_t *mctx, dns_keynode_t **target) { isc_result_t result; dns_keynode_t *knode = NULL; REQUIRE(target != NULL && *target == NULL); knode = isc_mem_get(mctx, sizeof(dns_keynode_t)); if (knode == NULL) return (ISC_R_NOMEMORY); knode->magic = KEYNODE_MAGIC; knode->managed = ISC_FALSE; knode->key = NULL; knode->next = NULL; result = isc_refcount_init(&knode->refcount, 1); if (result != ISC_R_SUCCESS) return (result); *target = knode; return (ISC_R_SUCCESS); } void dns_keynode_attach(dns_keynode_t *source, dns_keynode_t **target) { REQUIRE(VALID_KEYNODE(source)); isc_refcount_increment(&source->refcount, NULL); *target = source; } void dns_keynode_detach(isc_mem_t *mctx, dns_keynode_t **keynode) { unsigned int refs; dns_keynode_t *node = *keynode; REQUIRE(VALID_KEYNODE(node)); isc_refcount_decrement(&node->refcount, &refs); if (refs == 0) { if (node->key != NULL) dst_key_free(&node->key); isc_refcount_destroy(&node->refcount); isc_mem_put(mctx, node, sizeof(dns_keynode_t)); } *keynode = NULL; } void dns_keynode_detachall(isc_mem_t *mctx, dns_keynode_t **keynode) { dns_keynode_t *next = NULL, *node = *keynode; REQUIRE(VALID_KEYNODE(node)); while (node != NULL) { next = node->next; dns_keynode_detach(mctx, &node); node = next; } *keynode = NULL; } bind9-9.10.3.dfsg.P4/lib/dns/dst_parse.h0000644000470500017500000001254512664710322017067 0ustar lamontlamont/* * Portions Copyright (C) 2004-2010, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: dst_parse.h,v 1.17 2010/12/23 23:47:08 tbox Exp $ */ /*! \file */ #ifndef DST_DST_PARSE_H #define DST_DST_PARSE_H 1 #include #include #define MAXFIELDSIZE 512 /* * Maximum number of fields in a private file is 18 (12 algorithm- * specific fields for RSA, plus 6 generic fields). */ #define MAXFIELDS 12+6 #define TAG_SHIFT 4 #define TAG_ALG(tag) ((unsigned int)(tag) >> TAG_SHIFT) #define TAG(alg, off) (((alg) << TAG_SHIFT) + (off)) /* These are used by both RSA-MD5 and RSA-SHA1 */ #define RSA_NTAGS 11 #define TAG_RSA_MODULUS ((DST_ALG_RSAMD5 << TAG_SHIFT) + 0) #define TAG_RSA_PUBLICEXPONENT ((DST_ALG_RSAMD5 << TAG_SHIFT) + 1) #define TAG_RSA_PRIVATEEXPONENT ((DST_ALG_RSAMD5 << TAG_SHIFT) + 2) #define TAG_RSA_PRIME1 ((DST_ALG_RSAMD5 << TAG_SHIFT) + 3) #define TAG_RSA_PRIME2 ((DST_ALG_RSAMD5 << TAG_SHIFT) + 4) #define TAG_RSA_EXPONENT1 ((DST_ALG_RSAMD5 << TAG_SHIFT) + 5) #define TAG_RSA_EXPONENT2 ((DST_ALG_RSAMD5 << TAG_SHIFT) + 6) #define TAG_RSA_COEFFICIENT ((DST_ALG_RSAMD5 << TAG_SHIFT) + 7) #define TAG_RSA_ENGINE ((DST_ALG_RSAMD5 << TAG_SHIFT) + 8) #define TAG_RSA_LABEL ((DST_ALG_RSAMD5 << TAG_SHIFT) + 9) #define DH_NTAGS 4 #define TAG_DH_PRIME ((DST_ALG_DH << TAG_SHIFT) + 0) #define TAG_DH_GENERATOR ((DST_ALG_DH << TAG_SHIFT) + 1) #define TAG_DH_PRIVATE ((DST_ALG_DH << TAG_SHIFT) + 2) #define TAG_DH_PUBLIC ((DST_ALG_DH << TAG_SHIFT) + 3) #define DSA_NTAGS 5 #define TAG_DSA_PRIME ((DST_ALG_DSA << TAG_SHIFT) + 0) #define TAG_DSA_SUBPRIME ((DST_ALG_DSA << TAG_SHIFT) + 1) #define TAG_DSA_BASE ((DST_ALG_DSA << TAG_SHIFT) + 2) #define TAG_DSA_PRIVATE ((DST_ALG_DSA << TAG_SHIFT) + 3) #define TAG_DSA_PUBLIC ((DST_ALG_DSA << TAG_SHIFT) + 4) #define GOST_NTAGS 1 #define TAG_GOST_PRIVASN1 ((DST_ALG_ECCGOST << TAG_SHIFT) + 0) #define TAG_GOST_PRIVRAW ((DST_ALG_ECCGOST << TAG_SHIFT) + 1) #define ECDSA_NTAGS 4 #define TAG_ECDSA_PRIVATEKEY ((DST_ALG_ECDSA256 << TAG_SHIFT) + 0) #define TAG_ECDSA_ENGINE ((DST_ALG_ECDSA256 << TAG_SHIFT) + 1) #define TAG_ECDSA_LABEL ((DST_ALG_ECDSA256 << TAG_SHIFT) + 2) #define OLD_HMACMD5_NTAGS 1 #define HMACMD5_NTAGS 2 #define TAG_HMACMD5_KEY ((DST_ALG_HMACMD5 << TAG_SHIFT) + 0) #define TAG_HMACMD5_BITS ((DST_ALG_HMACMD5 << TAG_SHIFT) + 1) #define HMACSHA1_NTAGS 2 #define TAG_HMACSHA1_KEY ((DST_ALG_HMACSHA1 << TAG_SHIFT) + 0) #define TAG_HMACSHA1_BITS ((DST_ALG_HMACSHA1 << TAG_SHIFT) + 1) #define HMACSHA224_NTAGS 2 #define TAG_HMACSHA224_KEY ((DST_ALG_HMACSHA224 << TAG_SHIFT) + 0) #define TAG_HMACSHA224_BITS ((DST_ALG_HMACSHA224 << TAG_SHIFT) + 1) #define HMACSHA256_NTAGS 2 #define TAG_HMACSHA256_KEY ((DST_ALG_HMACSHA256 << TAG_SHIFT) + 0) #define TAG_HMACSHA256_BITS ((DST_ALG_HMACSHA256 << TAG_SHIFT) + 1) #define HMACSHA384_NTAGS 2 #define TAG_HMACSHA384_KEY ((DST_ALG_HMACSHA384 << TAG_SHIFT) + 0) #define TAG_HMACSHA384_BITS ((DST_ALG_HMACSHA384 << TAG_SHIFT) + 1) #define HMACSHA512_NTAGS 2 #define TAG_HMACSHA512_KEY ((DST_ALG_HMACSHA512 << TAG_SHIFT) + 0) #define TAG_HMACSHA512_BITS ((DST_ALG_HMACSHA512 << TAG_SHIFT) + 1) struct dst_private_element { unsigned short tag; unsigned short length; unsigned char *data; }; typedef struct dst_private_element dst_private_element_t; struct dst_private { unsigned short nelements; dst_private_element_t elements[MAXFIELDS]; }; typedef struct dst_private dst_private_t; ISC_LANG_BEGINDECLS void dst__privstruct_free(dst_private_t *priv, isc_mem_t *mctx); isc_result_t dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex, isc_mem_t *mctx, dst_private_t *priv); isc_result_t dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv, const char *directory); ISC_LANG_ENDDECLS #endif /* DST_DST_PARSE_H */ bind9-9.10.3.dfsg.P4/lib/dns/openssldh_link.c0000644000470500017500000004013612664710322020107 0ustar lamontlamont/* * Portions Copyright (C) 2004-2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * Principal Author: Brian Wellington * $Id: openssldh_link.c,v 1.20 2011/01/11 23:47:13 tbox Exp $ */ #ifdef OPENSSL #include #include #include #include #include #include #include "dst_internal.h" #include "dst_openssl.h" #include "dst_parse.h" #define PRIME768 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088" \ "A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25" \ "F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF" #define PRIME1024 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" \ "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF2" \ "5F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406" \ "B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF" #define PRIME1536 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \ "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \ "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \ "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF" static isc_result_t openssldh_todns(const dst_key_t *key, isc_buffer_t *data); static BIGNUM *bn2, *bn768, *bn1024, *bn1536; static isc_result_t openssldh_computesecret(const dst_key_t *pub, const dst_key_t *priv, isc_buffer_t *secret) { DH *dhpub, *dhpriv; int ret; isc_region_t r; unsigned int len; REQUIRE(pub->keydata.dh != NULL); REQUIRE(priv->keydata.dh != NULL); dhpub = pub->keydata.dh; dhpriv = priv->keydata.dh; len = DH_size(dhpriv); isc_buffer_availableregion(secret, &r); if (r.length < len) return (ISC_R_NOSPACE); ret = DH_compute_key(r.base, dhpub->pub_key, dhpriv); if (ret <= 0) return (dst__openssl_toresult2("DH_compute_key", DST_R_COMPUTESECRETFAILURE)); isc_buffer_add(secret, len); return (ISC_R_SUCCESS); } static isc_boolean_t openssldh_compare(const dst_key_t *key1, const dst_key_t *key2) { int status; DH *dh1, *dh2; dh1 = key1->keydata.dh; dh2 = key2->keydata.dh; if (dh1 == NULL && dh2 == NULL) return (ISC_TRUE); else if (dh1 == NULL || dh2 == NULL) return (ISC_FALSE); status = BN_cmp(dh1->p, dh2->p) || BN_cmp(dh1->g, dh2->g) || BN_cmp(dh1->pub_key, dh2->pub_key); if (status != 0) return (ISC_FALSE); if (dh1->priv_key != NULL || dh2->priv_key != NULL) { if (dh1->priv_key == NULL || dh2->priv_key == NULL) return (ISC_FALSE); if (BN_cmp(dh1->priv_key, dh2->priv_key) != 0) return (ISC_FALSE); } return (ISC_TRUE); } static isc_boolean_t openssldh_paramcompare(const dst_key_t *key1, const dst_key_t *key2) { int status; DH *dh1, *dh2; dh1 = key1->keydata.dh; dh2 = key2->keydata.dh; if (dh1 == NULL && dh2 == NULL) return (ISC_TRUE); else if (dh1 == NULL || dh2 == NULL) return (ISC_FALSE); status = BN_cmp(dh1->p, dh2->p) || BN_cmp(dh1->g, dh2->g); if (status != 0) return (ISC_FALSE); return (ISC_TRUE); } #if OPENSSL_VERSION_NUMBER > 0x00908000L static int progress_cb(int p, int n, BN_GENCB *cb) { union { void *dptr; void (*fptr)(int); } u; UNUSED(n); u.dptr = BN_GENCB_get_arg(cb); if (u.fptr != NULL) u.fptr(p); return (1); } #endif static isc_result_t openssldh_generate(dst_key_t *key, int generator, void (*callback)(int)) { DH *dh = NULL; #if OPENSSL_VERSION_NUMBER > 0x00908000L BN_GENCB *cb; #if OPENSSL_VERSION_NUMBER < 0x10100000L BN_GENCB _cb; #endif union { void *dptr; void (*fptr)(int); } u; #else UNUSED(callback); #endif if (generator == 0) { if (key->key_size == 768 || key->key_size == 1024 || key->key_size == 1536) { dh = DH_new(); if (dh == NULL) return (dst__openssl_toresult(ISC_R_NOMEMORY)); if (key->key_size == 768) dh->p = bn768; else if (key->key_size == 1024) dh->p = bn1024; else dh->p = bn1536; dh->g = bn2; } else generator = 2; } if (generator != 0) { #if OPENSSL_VERSION_NUMBER > 0x00908000L dh = DH_new(); if (dh == NULL) return (dst__openssl_toresult(ISC_R_NOMEMORY)); cb = BN_GENCB_new(); #if OPENSSL_VERSION_NUMBER >= 0x10100000L if (cb == NULL) { DH_free(dh); return (dst__openssl_toresult(ISC_R_NOMEMORY)); } #endif if (callback == NULL) { BN_GENCB_set_old(cb, NULL, NULL); } else { u.fptr = callback; BN_GENCB_set(cb, &progress_cb, u.dptr); } if (!DH_generate_parameters_ex(dh, key->key_size, generator, cb)) { DH_free(dh); BN_GENCB_free(cb); return (dst__openssl_toresult2( "DH_generate_parameters_ex", DST_R_OPENSSLFAILURE)); } BN_GENCB_free(cb); #else dh = DH_generate_parameters(key->key_size, generator, NULL, NULL); if (dh == NULL) return (dst__openssl_toresult2( "DH_generate_parameters", DST_R_OPENSSLFAILURE)); #endif } if (DH_generate_key(dh) == 0) { DH_free(dh); return (dst__openssl_toresult2("DH_generate_key", DST_R_OPENSSLFAILURE)); } dh->flags &= ~DH_FLAG_CACHE_MONT_P; key->keydata.dh = dh; return (ISC_R_SUCCESS); } static isc_boolean_t openssldh_isprivate(const dst_key_t *key) { DH *dh = key->keydata.dh; return (ISC_TF(dh != NULL && dh->priv_key != NULL)); } static void openssldh_destroy(dst_key_t *key) { DH *dh = key->keydata.dh; if (dh == NULL) return; if (dh->p == bn768 || dh->p == bn1024 || dh->p == bn1536) dh->p = NULL; if (dh->g == bn2) dh->g = NULL; DH_free(dh); key->keydata.dh = NULL; } static void uint16_toregion(isc_uint16_t val, isc_region_t *region) { *region->base = (val & 0xff00) >> 8; isc_region_consume(region, 1); *region->base = (val & 0x00ff); isc_region_consume(region, 1); } static isc_uint16_t uint16_fromregion(isc_region_t *region) { isc_uint16_t val; unsigned char *cp = region->base; val = ((unsigned int)(cp[0])) << 8; val |= ((unsigned int)(cp[1])); isc_region_consume(region, 2); return (val); } static isc_result_t openssldh_todns(const dst_key_t *key, isc_buffer_t *data) { DH *dh; isc_region_t r; isc_uint16_t dnslen, plen, glen, publen; REQUIRE(key->keydata.dh != NULL); dh = key->keydata.dh; isc_buffer_availableregion(data, &r); if (dh->g == bn2 && (dh->p == bn768 || dh->p == bn1024 || dh->p == bn1536)) { plen = 1; glen = 0; } else { plen = BN_num_bytes(dh->p); glen = BN_num_bytes(dh->g); } publen = BN_num_bytes(dh->pub_key); dnslen = plen + glen + publen + 6; if (r.length < (unsigned int) dnslen) return (ISC_R_NOSPACE); uint16_toregion(plen, &r); if (plen == 1) { if (dh->p == bn768) *r.base = 1; else if (dh->p == bn1024) *r.base = 2; else *r.base = 3; } else BN_bn2bin(dh->p, r.base); isc_region_consume(&r, plen); uint16_toregion(glen, &r); if (glen > 0) BN_bn2bin(dh->g, r.base); isc_region_consume(&r, glen); uint16_toregion(publen, &r); BN_bn2bin(dh->pub_key, r.base); isc_region_consume(&r, publen); isc_buffer_add(data, dnslen); return (ISC_R_SUCCESS); } static isc_result_t openssldh_fromdns(dst_key_t *key, isc_buffer_t *data) { DH *dh; isc_region_t r; isc_uint16_t plen, glen, publen; int special = 0; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); dh = DH_new(); if (dh == NULL) return (dst__openssl_toresult(ISC_R_NOMEMORY)); dh->flags &= ~DH_FLAG_CACHE_MONT_P; /* * Read the prime length. 1 & 2 are table entries, > 16 means a * prime follows, otherwise an error. */ if (r.length < 2) { DH_free(dh); return (DST_R_INVALIDPUBLICKEY); } plen = uint16_fromregion(&r); if (plen < 16 && plen != 1 && plen != 2) { DH_free(dh); return (DST_R_INVALIDPUBLICKEY); } if (r.length < plen) { DH_free(dh); return (DST_R_INVALIDPUBLICKEY); } if (plen == 1 || plen == 2) { if (plen == 1) { special = *r.base; isc_region_consume(&r, 1); } else { special = uint16_fromregion(&r); } switch (special) { case 1: dh->p = bn768; break; case 2: dh->p = bn1024; break; case 3: dh->p = bn1536; break; default: DH_free(dh); return (DST_R_INVALIDPUBLICKEY); } } else { dh->p = BN_bin2bn(r.base, plen, NULL); isc_region_consume(&r, plen); } /* * Read the generator length. This should be 0 if the prime was * special, but it might not be. If it's 0 and the prime is not * special, we have a problem. */ if (r.length < 2) { DH_free(dh); return (DST_R_INVALIDPUBLICKEY); } glen = uint16_fromregion(&r); if (r.length < glen) { DH_free(dh); return (DST_R_INVALIDPUBLICKEY); } if (special != 0) { if (glen == 0) dh->g = bn2; else { dh->g = BN_bin2bn(r.base, glen, NULL); if (BN_cmp(dh->g, bn2) == 0) { BN_free(dh->g); dh->g = bn2; } else { DH_free(dh); return (DST_R_INVALIDPUBLICKEY); } } } else { if (glen == 0) { DH_free(dh); return (DST_R_INVALIDPUBLICKEY); } dh->g = BN_bin2bn(r.base, glen, NULL); } isc_region_consume(&r, glen); if (r.length < 2) { DH_free(dh); return (DST_R_INVALIDPUBLICKEY); } publen = uint16_fromregion(&r); if (r.length < publen) { DH_free(dh); return (DST_R_INVALIDPUBLICKEY); } dh->pub_key = BN_bin2bn(r.base, publen, NULL); isc_region_consume(&r, publen); key->key_size = BN_num_bits(dh->p); isc_buffer_forward(data, plen + glen + publen + 6); key->keydata.dh = dh; return (ISC_R_SUCCESS); } static isc_result_t openssldh_tofile(const dst_key_t *key, const char *directory) { int i; DH *dh; dst_private_t priv; unsigned char *bufs[4]; isc_result_t result; if (key->keydata.dh == NULL) return (DST_R_NULLKEY); if (key->external) return (DST_R_EXTERNALKEY); dh = key->keydata.dh; memset(bufs, 0, sizeof(bufs)); for (i = 0; i < 4; i++) { bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(dh->p)); if (bufs[i] == NULL) { result = ISC_R_NOMEMORY; goto fail; } } i = 0; priv.elements[i].tag = TAG_DH_PRIME; priv.elements[i].length = BN_num_bytes(dh->p); BN_bn2bin(dh->p, bufs[i]); priv.elements[i].data = bufs[i]; i++; priv.elements[i].tag = TAG_DH_GENERATOR; priv.elements[i].length = BN_num_bytes(dh->g); BN_bn2bin(dh->g, bufs[i]); priv.elements[i].data = bufs[i]; i++; priv.elements[i].tag = TAG_DH_PRIVATE; priv.elements[i].length = BN_num_bytes(dh->priv_key); BN_bn2bin(dh->priv_key, bufs[i]); priv.elements[i].data = bufs[i]; i++; priv.elements[i].tag = TAG_DH_PUBLIC; priv.elements[i].length = BN_num_bytes(dh->pub_key); BN_bn2bin(dh->pub_key, bufs[i]); priv.elements[i].data = bufs[i]; i++; priv.nelements = i; result = dst__privstruct_writefile(key, &priv, directory); fail: for (i = 0; i < 4; i++) { if (bufs[i] == NULL) break; isc_mem_put(key->mctx, bufs[i], BN_num_bytes(dh->p)); } return (result); } static isc_result_t openssldh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t ret; int i; DH *dh = NULL; isc_mem_t *mctx; #define DST_RET(a) {ret = a; goto err;} UNUSED(pub); mctx = key->mctx; /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_DH, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) return (ret); if (key->external) DST_RET(DST_R_EXTERNALKEY); dh = DH_new(); if (dh == NULL) DST_RET(ISC_R_NOMEMORY); dh->flags &= ~DH_FLAG_CACHE_MONT_P; key->keydata.dh = dh; for (i = 0; i < priv.nelements; i++) { BIGNUM *bn; bn = BN_bin2bn(priv.elements[i].data, priv.elements[i].length, NULL); if (bn == NULL) DST_RET(ISC_R_NOMEMORY); switch (priv.elements[i].tag) { case TAG_DH_PRIME: dh->p = bn; break; case TAG_DH_GENERATOR: dh->g = bn; break; case TAG_DH_PRIVATE: dh->priv_key = bn; break; case TAG_DH_PUBLIC: dh->pub_key = bn; break; } } dst__privstruct_free(&priv, mctx); key->key_size = BN_num_bits(dh->p); if ((key->key_size == 768 || key->key_size == 1024 || key->key_size == 1536) && BN_cmp(dh->g, bn2) == 0) { if (key->key_size == 768 && BN_cmp(dh->p, bn768) == 0) { BN_free(dh->p); BN_free(dh->g); dh->p = bn768; dh->g = bn2; } else if (key->key_size == 1024 && BN_cmp(dh->p, bn1024) == 0) { BN_free(dh->p); BN_free(dh->g); dh->p = bn1024; dh->g = bn2; } else if (key->key_size == 1536 && BN_cmp(dh->p, bn1536) == 0) { BN_free(dh->p); BN_free(dh->g); dh->p = bn1536; dh->g = bn2; } } return (ISC_R_SUCCESS); err: openssldh_destroy(key); dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ret); } static void BN_fromhex(BIGNUM *b, const char *str) { static const char hexdigits[] = "0123456789abcdef"; unsigned char data[512]; unsigned int i; BIGNUM *out; RUNTIME_CHECK(strlen(str) < 1024U && strlen(str) % 2 == 0U); for (i = 0; i < strlen(str); i += 2) { char *s; unsigned int high, low; s = strchr(hexdigits, tolower((unsigned char)str[i])); RUNTIME_CHECK(s != NULL); high = (unsigned int)(s - hexdigits); s = strchr(hexdigits, tolower((unsigned char)str[i + 1])); RUNTIME_CHECK(s != NULL); low = (unsigned int)(s - hexdigits); data[i/2] = (unsigned char)((high << 4) + low); } out = BN_bin2bn(data, strlen(str)/2, b); RUNTIME_CHECK(out != NULL); } static void openssldh_cleanup(void) { BN_free(bn2); BN_free(bn768); BN_free(bn1024); BN_free(bn1536); } static dst_func_t openssldh_functions = { NULL, /*%< createctx */ NULL, /*%< createctx2 */ NULL, /*%< destroyctx */ NULL, /*%< adddata */ NULL, /*%< openssldh_sign */ NULL, /*%< openssldh_verify */ NULL, /*%< openssldh_verify2 */ openssldh_computesecret, openssldh_compare, openssldh_paramcompare, openssldh_generate, openssldh_isprivate, openssldh_destroy, openssldh_todns, openssldh_fromdns, openssldh_tofile, openssldh_parse, openssldh_cleanup, NULL, /*%< fromlabel */ NULL, /*%< dump */ NULL, /*%< restore */ }; isc_result_t dst__openssldh_init(dst_func_t **funcp) { REQUIRE(funcp != NULL); if (*funcp == NULL) { bn2 = BN_new(); bn768 = BN_new(); bn1024 = BN_new(); bn1536 = BN_new(); if (bn2 == NULL || bn768 == NULL || bn1024 == NULL || bn1536 == NULL) goto cleanup; BN_set_word(bn2, 2); BN_fromhex(bn768, PRIME768); BN_fromhex(bn1024, PRIME1024); BN_fromhex(bn1536, PRIME1536); *funcp = &openssldh_functions; } return (ISC_R_SUCCESS); cleanup: if (bn2 != NULL) BN_free(bn2); if (bn768 != NULL) BN_free(bn768); if (bn1024 != NULL) BN_free(bn1024); if (bn1536 != NULL) BN_free(bn1536); return (ISC_R_NOMEMORY); } #else /* OPENSSL */ #include EMPTY_TRANSLATION_UNIT #endif /* OPENSSL */ /*! \file */ bind9-9.10.3.dfsg.P4/lib/dns/gen-unix.h0000644000470500017500000000476612664710322016643 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: gen-unix.h,v 1.21 2009/01/17 23:47:42 tbox Exp $ */ /*! \file * \brief * This file is responsible for defining two operations that are not * directly portable between Unix-like systems and Windows NT, option * parsing and directory scanning. It is here because it was decided * that the "gen" build utility was not to depend on libisc.a, so * the functions declared in isc/commandline.h and isc/dir.h could not * be used. * * The commandline stuff is really just a wrapper around getopt(). * The dir stuff was shrunk to fit the needs of gen.c. */ #ifndef DNS_GEN_UNIX_H #define DNS_GEN_UNIX_H 1 #include /* Required on some systems for dirent.h. */ #include #include /* XXXDCL Required for ?. */ #include #include #ifdef NEED_OPTARG extern char *optarg; #endif #define isc_commandline_parse getopt #define isc_commandline_argument optarg typedef struct { DIR *handle; char *filename; } isc_dir_t; ISC_LANG_BEGINDECLS static isc_boolean_t start_directory(const char *path, isc_dir_t *dir) { dir->handle = opendir(path); if (dir->handle != NULL) return (ISC_TRUE); else return (ISC_FALSE); } static isc_boolean_t next_file(isc_dir_t *dir) { struct dirent *dirent; dir->filename = NULL; if (dir->handle != NULL) { dirent = readdir(dir->handle); if (dirent != NULL) dir->filename = dirent->d_name; } if (dir->filename != NULL) return (ISC_TRUE); else return (ISC_FALSE); } static void end_directory(isc_dir_t *dir) { if (dir->handle != NULL) (void)closedir(dir->handle); dir->handle = NULL; } ISC_LANG_ENDDECLS #endif /* DNS_GEN_UNIX_H */ bind9-9.10.3.dfsg.P4/lib/dns/tsec.c0000644000470500017500000000721712664710322016034 0ustar lamontlamont/* * Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: tsec.c,v 1.7 2010/12/09 00:54:34 marka Exp $ */ #include #include #include #include #include #include #define DNS_TSEC_MAGIC ISC_MAGIC('T', 's', 'e', 'c') #define DNS_TSEC_VALID(t) ISC_MAGIC_VALID(t, DNS_TSEC_MAGIC) /*% * DNS Transaction Security object. We assume this is not shared by * multiple threads, and so the structure does not contain a lock. */ struct dns_tsec { unsigned int magic; dns_tsectype_t type; isc_mem_t *mctx; union { dns_tsigkey_t *tsigkey; dst_key_t *key; } ukey; }; isc_result_t dns_tsec_create(isc_mem_t *mctx, dns_tsectype_t type, dst_key_t *key, dns_tsec_t **tsecp) { isc_result_t result; dns_tsec_t *tsec; dns_tsigkey_t *tsigkey = NULL; dns_name_t *algname; REQUIRE(mctx != NULL); REQUIRE(tsecp != NULL && *tsecp == NULL); tsec = isc_mem_get(mctx, sizeof(*tsec)); if (tsec == NULL) return (ISC_R_NOMEMORY); tsec->type = type; tsec->mctx = mctx; switch (type) { case dns_tsectype_tsig: switch (dst_key_alg(key)) { case DST_ALG_HMACMD5: algname = dns_tsig_hmacmd5_name; break; case DST_ALG_HMACSHA1: algname = dns_tsig_hmacsha1_name; break; case DST_ALG_HMACSHA224: algname = dns_tsig_hmacsha224_name; break; case DST_ALG_HMACSHA256: algname = dns_tsig_hmacsha256_name; break; case DST_ALG_HMACSHA384: algname = dns_tsig_hmacsha384_name; break; case DST_ALG_HMACSHA512: algname = dns_tsig_hmacsha512_name; break; default: isc_mem_put(mctx, tsec, sizeof(*tsec)); return (DNS_R_BADALG); } result = dns_tsigkey_createfromkey(dst_key_name(key), algname, key, ISC_FALSE, NULL, 0, 0, mctx, NULL, &tsigkey); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, tsec, sizeof(*tsec)); return (result); } tsec->ukey.tsigkey = tsigkey; break; case dns_tsectype_sig0: tsec->ukey.key = key; break; default: INSIST(0); } tsec->magic = DNS_TSEC_MAGIC; *tsecp = tsec; return (ISC_R_SUCCESS); } void dns_tsec_destroy(dns_tsec_t **tsecp) { dns_tsec_t *tsec; REQUIRE(tsecp != NULL && *tsecp != NULL); tsec = *tsecp; REQUIRE(DNS_TSEC_VALID(tsec)); switch (tsec->type) { case dns_tsectype_tsig: dns_tsigkey_detach(&tsec->ukey.tsigkey); break; case dns_tsectype_sig0: dst_key_free(&tsec->ukey.key); break; default: INSIST(0); } tsec->magic = 0; isc_mem_put(tsec->mctx, tsec, sizeof(*tsec)); *tsecp = NULL; } dns_tsectype_t dns_tsec_gettype(dns_tsec_t *tsec) { REQUIRE(DNS_TSEC_VALID(tsec)); return (tsec->type); } void dns_tsec_getkey(dns_tsec_t *tsec, void *keyp) { REQUIRE(DNS_TSEC_VALID(tsec)); REQUIRE(keyp != NULL); switch (tsec->type) { case dns_tsectype_tsig: dns_tsigkey_attach(tsec->ukey.tsigkey, (dns_tsigkey_t **)keyp); break; case dns_tsectype_sig0: *(dst_key_t **)keyp = tsec->ukey.key; break; default: INSIST(0); } } bind9-9.10.3.dfsg.P4/lib/dns/acl.c0000644000470500017500000004065412664710322015637 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2011, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: acl.c,v 1.55 2011/06/17 23:47:49 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include /* * Create a new ACL, including an IP table and an array with room * for 'n' ACL elements. The elements are uninitialized and the * length is 0. */ isc_result_t dns_acl_create(isc_mem_t *mctx, int n, dns_acl_t **target) { isc_result_t result; dns_acl_t *acl; /* * Work around silly limitation of isc_mem_get(). */ if (n == 0) n = 1; acl = isc_mem_get(mctx, sizeof(*acl)); if (acl == NULL) return (ISC_R_NOMEMORY); acl->mctx = NULL; isc_mem_attach(mctx, &acl->mctx); acl->name = NULL; result = isc_refcount_init(&acl->refcount, 1); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, acl, sizeof(*acl)); return (result); } result = dns_iptable_create(mctx, &acl->iptable); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, acl, sizeof(*acl)); return (result); } acl->elements = NULL; acl->alloc = 0; acl->length = 0; acl->has_negatives = ISC_FALSE; ISC_LINK_INIT(acl, nextincache); /* * Must set magic early because we use dns_acl_detach() to clean up. */ acl->magic = DNS_ACL_MAGIC; acl->elements = isc_mem_get(mctx, n * sizeof(dns_aclelement_t)); if (acl->elements == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } acl->alloc = n; memset(acl->elements, 0, n * sizeof(dns_aclelement_t)); *target = acl; return (ISC_R_SUCCESS); cleanup: dns_acl_detach(&acl); return (result); } /* * Create a new ACL and initialize it with the value "any" or "none", * depending on the value of the "neg" parameter. * "any" is a positive iptable entry with bit length 0. * "none" is the same as "!any". */ static isc_result_t dns_acl_anyornone(isc_mem_t *mctx, isc_boolean_t neg, dns_acl_t **target) { isc_result_t result; dns_acl_t *acl = NULL; result = dns_acl_create(mctx, 0, &acl); if (result != ISC_R_SUCCESS) return (result); result = dns_iptable_addprefix(acl->iptable, NULL, 0, ISC_TF(!neg)); if (result != ISC_R_SUCCESS) { dns_acl_detach(&acl); return (result); } *target = acl; return (result); } /* * Create a new ACL that matches everything. */ isc_result_t dns_acl_any(isc_mem_t *mctx, dns_acl_t **target) { return (dns_acl_anyornone(mctx, ISC_FALSE, target)); } /* * Create a new ACL that matches nothing. */ isc_result_t dns_acl_none(isc_mem_t *mctx, dns_acl_t **target) { return (dns_acl_anyornone(mctx, ISC_TRUE, target)); } /* * If pos is ISC_TRUE, test whether acl is set to "{ any; }" * If pos is ISC_FALSE, test whether acl is set to "{ none; }" */ static isc_boolean_t dns_acl_isanyornone(dns_acl_t *acl, isc_boolean_t pos) { /* Should never happen but let's be safe */ if (acl == NULL || acl->iptable == NULL || acl->iptable->radix == NULL || acl->iptable->radix->head == NULL || acl->iptable->radix->head->prefix == NULL) return (ISC_FALSE); if (acl->length != 0 || acl->node_count != 1) return (ISC_FALSE); if (acl->iptable->radix->head->prefix->bitlen == 0 && acl->iptable->radix->head->data[0] != NULL && acl->iptable->radix->head->data[0] == acl->iptable->radix->head->data[1] && *(isc_boolean_t *) (acl->iptable->radix->head->data[0]) == pos) return (ISC_TRUE); return (ISC_FALSE); /* All others */ } /* * Test whether acl is set to "{ any; }" */ isc_boolean_t dns_acl_isany(dns_acl_t *acl) { return (dns_acl_isanyornone(acl, ISC_TRUE)); } /* * Test whether acl is set to "{ none; }" */ isc_boolean_t dns_acl_isnone(dns_acl_t *acl) { return (dns_acl_isanyornone(acl, ISC_FALSE)); } /* * Determine whether a given address or signer matches a given ACL. * For a match with a positive ACL element or iptable radix entry, * return with a positive value in match; for a match with a negated ACL * element or radix entry, return with a negative value in match. */ isc_result_t dns_acl_match(const isc_netaddr_t *reqaddr, const dns_name_t *reqsigner, const dns_acl_t *acl, const dns_aclenv_t *env, int *match, const dns_aclelement_t **matchelt) { isc_uint16_t bitlen, family; isc_prefix_t pfx; isc_radix_node_t *node = NULL; const isc_netaddr_t *addr; isc_netaddr_t v4addr; isc_result_t result; int match_num = -1; unsigned int i; REQUIRE(reqaddr != NULL); REQUIRE(matchelt == NULL || *matchelt == NULL); if (env == NULL || env->match_mapped == ISC_FALSE || reqaddr->family != AF_INET6 || !IN6_IS_ADDR_V4MAPPED(&reqaddr->type.in6)) addr = reqaddr; else { isc_netaddr_fromv4mapped(&v4addr, reqaddr); addr = &v4addr; } /* Always match with host addresses. */ family = addr->family; bitlen = family == AF_INET6 ? 128 : 32; NETADDR_TO_PREFIX_T(addr, pfx, bitlen); /* Assume no match. */ *match = 0; /* Search radix. */ result = isc_radix_search(acl->iptable->radix, &node, &pfx); /* Found a match. */ if (result == ISC_R_SUCCESS && node != NULL) { match_num = node->node_num[ISC_IS6(family)]; if (*(isc_boolean_t *) node->data[ISC_IS6(family)] == ISC_TRUE) *match = match_num; else *match = -match_num; } /* Now search non-radix elements for a match with a lower node_num. */ for (i = 0; i < acl->length; i++) { dns_aclelement_t *e = &acl->elements[i]; /* Already found a better match? */ if (match_num != -1 && match_num < e->node_num) { isc_refcount_destroy(&pfx.refcount); return (ISC_R_SUCCESS); } if (dns_aclelement_match(reqaddr, reqsigner, e, env, matchelt)) { if (match_num == -1 || e->node_num < match_num) { if (e->negative == ISC_TRUE) *match = -e->node_num; else *match = e->node_num; } isc_refcount_destroy(&pfx.refcount); return (ISC_R_SUCCESS); } } isc_refcount_destroy(&pfx.refcount); return (ISC_R_SUCCESS); } /* * Merge the contents of one ACL into another. Call dns_iptable_merge() * for the IP tables, then concatenate the element arrays. * * If pos is set to false, then the nested ACL is to be negated. This * means reverse the sense of each *positive* element or IP table node, * but leave negatives alone, so as to prevent a double-negative causing * an unexpected positive match in the parent ACL. */ isc_result_t dns_acl_merge(dns_acl_t *dest, dns_acl_t *source, isc_boolean_t pos) { isc_result_t result; unsigned int newalloc, nelem, i; int max_node = 0, nodes; /* Resize the element array if needed. */ if (dest->length + source->length > dest->alloc) { void *newmem; newalloc = dest->alloc + source->alloc; if (newalloc < 4) newalloc = 4; newmem = isc_mem_get(dest->mctx, newalloc * sizeof(dns_aclelement_t)); if (newmem == NULL) return (ISC_R_NOMEMORY); /* Zero. */ memset(newmem, 0, newalloc * sizeof(dns_aclelement_t)); /* Copy in the original elements */ memmove(newmem, dest->elements, dest->length * sizeof(dns_aclelement_t)); /* Release the memory for the old elements array */ isc_mem_put(dest->mctx, dest->elements, dest->alloc * sizeof(dns_aclelement_t)); dest->elements = newmem; dest->alloc = newalloc; } /* * Now copy in the new elements, increasing their node_num * values so as to keep the new ACL consistent. If we're * negating, then negate positive elements, but keep negative * elements the same for security reasons. */ nelem = dest->length; dest->length += source->length; for (i = 0; i < source->length; i++) { if (source->elements[i].node_num > max_node) max_node = source->elements[i].node_num; /* Copy type. */ dest->elements[nelem + i].type = source->elements[i].type; /* Adjust node numbering. */ dest->elements[nelem + i].node_num = source->elements[i].node_num + dest->node_count; /* Duplicate nested acl. */ if (source->elements[i].type == dns_aclelementtype_nestedacl && source->elements[i].nestedacl != NULL) dns_acl_attach(source->elements[i].nestedacl, &dest->elements[nelem + i].nestedacl); /* Duplicate key name. */ if (source->elements[i].type == dns_aclelementtype_keyname) { dns_name_init(&dest->elements[nelem+i].keyname, NULL); result = dns_name_dup(&source->elements[i].keyname, dest->mctx, &dest->elements[nelem+i].keyname); if (result != ISC_R_SUCCESS) return result; } #ifdef HAVE_GEOIP /* Duplicate GeoIP data */ if (source->elements[i].type == dns_aclelementtype_geoip) { dest->elements[nelem + i].geoip_elem = source->elements[i].geoip_elem; } #endif /* reverse sense of positives if this is a negative acl */ if (!pos && source->elements[i].negative == ISC_FALSE) { dest->elements[nelem + i].negative = ISC_TRUE; } else { dest->elements[nelem + i].negative = source->elements[i].negative; } } /* * Merge the iptables. Make sure the destination ACL's * node_count value is set correctly afterward. */ nodes = max_node + dest->node_count; result = dns_iptable_merge(dest->iptable, source->iptable, pos); if (result != ISC_R_SUCCESS) return (result); if (nodes > dest->node_count) dest->node_count = nodes; return (ISC_R_SUCCESS); } /* * Like dns_acl_match, but matches against the single ACL element 'e' * rather than a complete ACL, and returns ISC_TRUE iff it matched. * * To determine whether the match was positive or negative, the * caller should examine e->negative. Since the element 'e' may be * a reference to a named ACL or a nested ACL, a matching element * returned through 'matchelt' is not necessarily 'e' itself. */ isc_boolean_t dns_aclelement_match(const isc_netaddr_t *reqaddr, const dns_name_t *reqsigner, const dns_aclelement_t *e, const dns_aclenv_t *env, const dns_aclelement_t **matchelt) { dns_acl_t *inner = NULL; int indirectmatch; isc_result_t result; switch (e->type) { case dns_aclelementtype_keyname: if (reqsigner != NULL && dns_name_equal(reqsigner, &e->keyname)) { if (matchelt != NULL) *matchelt = e; return (ISC_TRUE); } else return (ISC_FALSE); case dns_aclelementtype_nestedacl: inner = e->nestedacl; break; case dns_aclelementtype_localhost: if (env == NULL || env->localhost == NULL) return (ISC_FALSE); inner = env->localhost; break; case dns_aclelementtype_localnets: if (env == NULL || env->localnets == NULL) return (ISC_FALSE); inner = env->localnets; break; #ifdef HAVE_GEOIP case dns_aclelementtype_geoip: if (env == NULL || env->geoip == NULL) return (ISC_FALSE); return (dns_geoip_match(reqaddr, env->geoip, &e->geoip_elem)); #endif default: /* Should be impossible. */ INSIST(0); } result = dns_acl_match(reqaddr, reqsigner, inner, env, &indirectmatch, matchelt); INSIST(result == ISC_R_SUCCESS); /* * Treat negative matches in indirect ACLs as "no match". * That way, a negated indirect ACL will never become a * surprise positive match through double negation. * XXXDCL this should be documented. */ if (indirectmatch > 0) { if (matchelt != NULL) *matchelt = e; return (ISC_TRUE); } /* * A negative indirect match may have set *matchelt, but we don't * want it set when we return. */ if (matchelt != NULL) *matchelt = NULL; return (ISC_FALSE); } void dns_acl_attach(dns_acl_t *source, dns_acl_t **target) { REQUIRE(DNS_ACL_VALID(source)); isc_refcount_increment(&source->refcount, NULL); *target = source; } static void destroy(dns_acl_t *dacl) { unsigned int i; INSIST(!ISC_LINK_LINKED(dacl, nextincache)); for (i = 0; i < dacl->length; i++) { dns_aclelement_t *de = &dacl->elements[i]; if (de->type == dns_aclelementtype_keyname) { dns_name_free(&de->keyname, dacl->mctx); } else if (de->type == dns_aclelementtype_nestedacl) { dns_acl_detach(&de->nestedacl); } } if (dacl->elements != NULL) isc_mem_put(dacl->mctx, dacl->elements, dacl->alloc * sizeof(dns_aclelement_t)); if (dacl->name != NULL) isc_mem_free(dacl->mctx, dacl->name); if (dacl->iptable != NULL) dns_iptable_detach(&dacl->iptable); isc_refcount_destroy(&dacl->refcount); dacl->magic = 0; isc_mem_putanddetach(&dacl->mctx, dacl, sizeof(*dacl)); } void dns_acl_detach(dns_acl_t **aclp) { dns_acl_t *acl = *aclp; unsigned int refs; REQUIRE(DNS_ACL_VALID(acl)); isc_refcount_decrement(&acl->refcount, &refs); if (refs == 0) destroy(acl); *aclp = NULL; } static isc_once_t insecure_prefix_once = ISC_ONCE_INIT; static isc_mutex_t insecure_prefix_lock; static isc_boolean_t insecure_prefix_found; static void initialize_action(void) { RUNTIME_CHECK(isc_mutex_init(&insecure_prefix_lock) == ISC_R_SUCCESS); } /* * Called via isc_radix_walk() to find IP table nodes that are * insecure. */ static void is_insecure(isc_prefix_t *prefix, void **data) { isc_boolean_t secure; int bitlen, family; bitlen = prefix->bitlen; family = prefix->family; /* Negated entries are always secure. */ secure = * (isc_boolean_t *)data[ISC_IS6(family)]; if (!secure) { return; } /* If loopback prefix found, return */ switch (family) { case AF_INET: if (bitlen == 32 && htonl(prefix->add.sin.s_addr) == INADDR_LOOPBACK) return; break; case AF_INET6: if (bitlen == 128 && IN6_IS_ADDR_LOOPBACK(&prefix->add.sin6)) return; break; default: break; } /* Non-negated, non-loopback */ insecure_prefix_found = ISC_TRUE; /* LOCKED */ return; } /* * Return ISC_TRUE iff the acl 'a' is considered insecure, that is, * if it contains IP addresses other than those of the local host. * This is intended for applications such as printing warning * messages for suspect ACLs; it is not intended for making access * control decisions. We make no guarantee that an ACL for which * this function returns ISC_FALSE is safe. */ isc_boolean_t dns_acl_isinsecure(const dns_acl_t *a) { unsigned int i; isc_boolean_t insecure; RUNTIME_CHECK(isc_once_do(&insecure_prefix_once, initialize_action) == ISC_R_SUCCESS); /* * Walk radix tree to find out if there are any non-negated, * non-loopback prefixes. */ LOCK(&insecure_prefix_lock); insecure_prefix_found = ISC_FALSE; isc_radix_process(a->iptable->radix, is_insecure); insecure = insecure_prefix_found; UNLOCK(&insecure_prefix_lock); if (insecure) return (ISC_TRUE); /* Now check non-radix elements */ for (i = 0; i < a->length; i++) { dns_aclelement_t *e = &a->elements[i]; /* A negated match can never be insecure. */ if (e->negative) continue; switch (e->type) { case dns_aclelementtype_keyname: case dns_aclelementtype_localhost: continue; case dns_aclelementtype_nestedacl: if (dns_acl_isinsecure(e->nestedacl)) return (ISC_TRUE); continue; case dns_aclelementtype_localnets: return (ISC_TRUE); default: INSIST(0); return (ISC_TRUE); } } /* No insecure elements were found. */ return (ISC_FALSE); } /* * Initialize ACL environment, setting up localhost and localnets ACLs */ isc_result_t dns_aclenv_init(isc_mem_t *mctx, dns_aclenv_t *env) { isc_result_t result; env->localhost = NULL; env->localnets = NULL; result = dns_acl_create(mctx, 0, &env->localhost); if (result != ISC_R_SUCCESS) goto cleanup_nothing; result = dns_acl_create(mctx, 0, &env->localnets); if (result != ISC_R_SUCCESS) goto cleanup_localhost; env->match_mapped = ISC_FALSE; #ifdef HAVE_GEOIP env->geoip = NULL; #endif return (ISC_R_SUCCESS); cleanup_localhost: dns_acl_detach(&env->localhost); cleanup_nothing: return (result); } void dns_aclenv_copy(dns_aclenv_t *t, dns_aclenv_t *s) { dns_acl_detach(&t->localhost); dns_acl_attach(s->localhost, &t->localhost); dns_acl_detach(&t->localnets); dns_acl_attach(s->localnets, &t->localnets); t->match_mapped = s->match_mapped; } void dns_aclenv_destroy(dns_aclenv_t *env) { dns_acl_detach(&env->localhost); dns_acl_detach(&env->localnets); } bind9-9.10.3.dfsg.P4/lib/dns/ttl.c0000644000470500017500000001222212664710322015671 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2011-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define RETERR(x) do { \ isc_result_t _r = (x); \ if (_r != ISC_R_SUCCESS) \ return (_r); \ } while (0) static isc_result_t bind_ttl(isc_textregion_t *source, isc_uint32_t *ttl); /* * Helper for dns_ttl_totext(). */ static isc_result_t ttlfmt(unsigned int t, const char *s, isc_boolean_t verbose, isc_boolean_t space, isc_buffer_t *target) { char tmp[60]; unsigned int len; isc_region_t region; if (verbose) len = snprintf(tmp, sizeof(tmp), "%s%u %s%s", space ? " " : "", t, s, t == 1 ? "" : "s"); else len = snprintf(tmp, sizeof(tmp), "%u%c", t, s[0]); INSIST(len + 1 <= sizeof(tmp)); isc_buffer_availableregion(target, ®ion); if (len > region.length) return (ISC_R_NOSPACE); memmove(region.base, tmp, len); isc_buffer_add(target, len); return (ISC_R_SUCCESS); } /* * Derived from bind8 ns_format_ttl(). */ isc_result_t dns_ttl_totext(isc_uint32_t src, isc_boolean_t verbose, isc_buffer_t *target) { unsigned secs, mins, hours, days, weeks, x; secs = src % 60; src /= 60; mins = src % 60; src /= 60; hours = src % 24; src /= 24; days = src % 7; src /= 7; weeks = src; src = 0; POST(src); x = 0; if (weeks != 0) { RETERR(ttlfmt(weeks, "week", verbose, ISC_TF(x > 0), target)); x++; } if (days != 0) { RETERR(ttlfmt(days, "day", verbose, ISC_TF(x > 0), target)); x++; } if (hours != 0) { RETERR(ttlfmt(hours, "hour", verbose, ISC_TF(x > 0), target)); x++; } if (mins != 0) { RETERR(ttlfmt(mins, "minute", verbose, ISC_TF(x > 0), target)); x++; } if (secs != 0 || (weeks == 0 && days == 0 && hours == 0 && mins == 0)) { RETERR(ttlfmt(secs, "second", verbose, ISC_TF(x > 0), target)); x++; } INSIST (x > 0); /* * If only a single unit letter is printed, print it * in upper case. (Why? Because BIND 8 does that. * Presumably it has a reason.) */ if (x == 1 && !verbose) { isc_region_t region; /* * The unit letter is the last character in the * used region of the buffer. * * toupper() does not need its argument to be masked of cast * here because region.base is type unsigned char *. */ isc_buffer_usedregion(target, ®ion); region.base[region.length - 1] = toupper(region.base[region.length - 1]); } return (ISC_R_SUCCESS); } isc_result_t dns_counter_fromtext(isc_textregion_t *source, isc_uint32_t *ttl) { return (bind_ttl(source, ttl)); } isc_result_t dns_ttl_fromtext(isc_textregion_t *source, isc_uint32_t *ttl) { isc_result_t result; result = bind_ttl(source, ttl); if (result != ISC_R_SUCCESS && result != ISC_R_RANGE) result = DNS_R_BADTTL; return (result); } static isc_result_t bind_ttl(isc_textregion_t *source, isc_uint32_t *ttl) { isc_uint64_t tmp = 0ULL; isc_uint32_t n; char *s; char buf[64]; char nbuf[64]; /* Number buffer */ /* * Copy the buffer as it may not be NULL terminated. * No legal counter / ttl is longer that 63 characters. */ if (source->length > sizeof(buf) - 1) return (DNS_R_SYNTAX); strncpy(buf, source->base, source->length); buf[source->length] = '\0'; s = buf; do { isc_result_t result; char *np = nbuf; while (*s != '\0' && isdigit((unsigned char)*s)) *np++ = *s++; *np++ = '\0'; INSIST(np - nbuf <= (int)sizeof(nbuf)); result = isc_parse_uint32(&n, nbuf, 10); if (result != ISC_R_SUCCESS) return (DNS_R_SYNTAX); switch (*s) { case 'w': case 'W': tmp += (isc_uint64_t) n * 7 * 24 * 3600; s++; break; case 'd': case 'D': tmp += (isc_uint64_t) n * 24 * 3600; s++; break; case 'h': case 'H': tmp += (isc_uint64_t) n * 3600; s++; break; case 'm': case 'M': tmp += (isc_uint64_t) n * 60; s++; break; case 's': case 'S': tmp += (isc_uint64_t) n; s++; break; case '\0': /* Plain number? */ if (tmp != 0ULL) return (DNS_R_SYNTAX); tmp = n; break; default: return (DNS_R_SYNTAX); } } while (*s != '\0'); if (tmp > 0xffffffffULL) return (ISC_R_RANGE); *ttl = (isc_uint32_t)(tmp & 0xffffffffUL); return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/dns/Atffile0000644000470500017500000000013212664710322016214 0ustar lamontlamontContent-Type: application/X-atf-atffile; version="1" prop: test-suite = bind9 tp: tests bind9-9.10.3.dfsg.P4/lib/dns/rpz.c0000644000470500017500000017602712664710322015717 0ustar lamontlamont/* * Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* * Parallel radix trees for databases of response policy IP addresses * * The radix or patricia trees are somewhat specialized to handle response * policy addresses by representing the two sets of IP addresses and name * server IP addresses in a single tree. One set of IP addresses is * for rpz-ip policies or policies triggered by addresses in A or * AAAA records in responses. * The second set is for rpz-nsip policies or policies triggered by addresses * in A or AAAA records for NS records that are authorities for responses. * * Each leaf indicates that an IP address is listed in the IP address or the * name server IP address policy sub-zone (or both) of the corresponding * response policy zone. The policy data such as a CNAME or an A record * is kept in the policy zone. After an IP address has been found in a radix * tree, the node in the policy zone's database is found by converting * the IP address to a domain name in a canonical form. * * * The response policy zone canonical form of an IPv6 address is one of: * prefix.W.W.W.W.W.W.W.W * prefix.WORDS.zz * prefix.WORDS.zz.WORDS * prefix.zz.WORDS * where * prefix is the prefix length of the IPv6 address between 1 and 128 * W is a number between 0 and 65535 * WORDS is one or more numbers W separated with "." * zz corresponds to :: in the standard IPv6 text representation * * The canonical form of IPv4 addresses is: * prefix.B.B.B.B * where * prefix is the prefix length of the address between 1 and 32 * B is a number between 0 and 255 * * Names for IPv4 addresses are distinguished from IPv6 addresses by having * 5 labels all of which are numbers, and a prefix between 1 and 32. */ /* * Use a private definition of IPv6 addresses because s6_addr32 is not * always defined and our IPv6 addresses are in non-standard byte order */ typedef isc_uint32_t dns_rpz_cidr_word_t; #define DNS_RPZ_CIDR_WORD_BITS ((int)sizeof(dns_rpz_cidr_word_t)*8) #define DNS_RPZ_CIDR_KEY_BITS ((int)sizeof(dns_rpz_cidr_key_t)*8) #define DNS_RPZ_CIDR_WORDS (128/DNS_RPZ_CIDR_WORD_BITS) typedef struct { dns_rpz_cidr_word_t w[DNS_RPZ_CIDR_WORDS]; } dns_rpz_cidr_key_t; #define ADDR_V4MAPPED 0xffff #define KEY_IS_IPV4(prefix,ip) ((prefix) >= 96 && (ip)->w[0] == 0 && \ (ip)->w[1] == 0 && (ip)->w[2] == ADDR_V4MAPPED) #define DNS_RPZ_WORD_MASK(b) ((b) == 0 ? (dns_rpz_cidr_word_t)(-1) \ : ((dns_rpz_cidr_word_t)(-1) \ << (DNS_RPZ_CIDR_WORD_BITS - (b)))) /* * Get bit #n from the array of words of an IP address. */ #define DNS_RPZ_IP_BIT(ip, n) (1 & ((ip)->w[(n)/DNS_RPZ_CIDR_WORD_BITS] >> \ (DNS_RPZ_CIDR_WORD_BITS \ - 1 - ((n) % DNS_RPZ_CIDR_WORD_BITS)))) /* * A triplet of arrays of bits flagging the existence of * client-IP, IP, and NSIP policy triggers. */ typedef struct dns_rpz_addr_zbits dns_rpz_addr_zbits_t; struct dns_rpz_addr_zbits { dns_rpz_zbits_t client_ip; dns_rpz_zbits_t ip; dns_rpz_zbits_t nsip; }; /* * A CIDR or radix tree node. */ struct dns_rpz_cidr_node { dns_rpz_cidr_node_t *parent; dns_rpz_cidr_node_t *child[2]; dns_rpz_cidr_key_t ip; dns_rpz_prefix_t prefix; dns_rpz_addr_zbits_t set; dns_rpz_addr_zbits_t sum; }; /* * A pair of arrays of bits flagging the existence of * QNAME and NSDNAME policy triggers. */ typedef struct dns_rpz_nm_zbits dns_rpz_nm_zbits_t; struct dns_rpz_nm_zbits { dns_rpz_zbits_t qname; dns_rpz_zbits_t ns; }; /* * The data in a RBT node has two pairs of bits for policy zones. * One pair is for the corresponding name of the node such as example.com * and the other pair is for a wildcard child such as *.example.com. */ typedef struct dns_rpz_nm_data dns_rpz_nm_data_t; struct dns_rpz_nm_data { dns_rpz_nm_zbits_t set; dns_rpz_nm_zbits_t wild; }; #if 0 /* * Catch a name while debugging. */ static void catch_name(const dns_name_t *src_name, const char *tgt, const char *str) { dns_fixedname_t tgt_namef; dns_name_t *tgt_name; dns_fixedname_init(&tgt_namef); tgt_name = dns_fixedname_name(&tgt_namef); dns_name_fromstring(tgt_name, tgt, DNS_NAME_DOWNCASE, NULL); if (dns_name_equal(src_name, tgt_name)) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, "rpz hit failed: %s %s", str, tgt); } } #endif const char * dns_rpz_type2str(dns_rpz_type_t type) { switch (type) { case DNS_RPZ_TYPE_CLIENT_IP: return ("CLIENT-IP"); case DNS_RPZ_TYPE_QNAME: return ("QNAME"); case DNS_RPZ_TYPE_IP: return ("IP"); case DNS_RPZ_TYPE_NSIP: return ("NSIP"); case DNS_RPZ_TYPE_NSDNAME: return ("NSDNAME"); case DNS_RPZ_TYPE_BAD: break; } FATAL_ERROR(__FILE__, __LINE__, "impossible rpz type %d", type); return ("impossible"); } dns_rpz_policy_t dns_rpz_str2policy(const char *str) { static struct { const char *str; dns_rpz_policy_t policy; } tbl[] = { {"given", DNS_RPZ_POLICY_GIVEN}, {"disabled", DNS_RPZ_POLICY_DISABLED}, {"passthru", DNS_RPZ_POLICY_PASSTHRU}, {"drop", DNS_RPZ_POLICY_DROP}, {"tcp-only", DNS_RPZ_POLICY_TCP_ONLY}, {"nxdomain", DNS_RPZ_POLICY_NXDOMAIN}, {"nodata", DNS_RPZ_POLICY_NODATA}, {"cname", DNS_RPZ_POLICY_CNAME}, {"no-op", DNS_RPZ_POLICY_PASSTHRU}, /* old passthru */ }; unsigned int n; if (str == NULL) return (DNS_RPZ_POLICY_ERROR); for (n = 0; n < sizeof(tbl)/sizeof(tbl[0]); ++n) { if (!strcasecmp(tbl[n].str, str)) return (tbl[n].policy); } return (DNS_RPZ_POLICY_ERROR); } const char * dns_rpz_policy2str(dns_rpz_policy_t policy) { const char *str; switch (policy) { case DNS_RPZ_POLICY_PASSTHRU: str = "PASSTHRU"; break; case DNS_RPZ_POLICY_DROP: str = "DROP"; break; case DNS_RPZ_POLICY_TCP_ONLY: str = "TCP-ONLY"; break; case DNS_RPZ_POLICY_NXDOMAIN: str = "NXDOMAIN"; break; case DNS_RPZ_POLICY_NODATA: str = "NODATA"; break; case DNS_RPZ_POLICY_RECORD: str = "Local-Data"; break; case DNS_RPZ_POLICY_CNAME: case DNS_RPZ_POLICY_WILDCNAME: str = "CNAME"; break; case DNS_RPZ_POLICY_MISS: str = "MISS"; break; default: str = ""; POST(str); INSIST(0); } return (str); } /* * Return the bit number of the highest set bit in 'zbit'. * (for example, 0x01 returns 0, 0xFF returns 7, etc.) */ static int zbit_to_num(dns_rpz_zbits_t zbit) { dns_rpz_num_t rpz_num; REQUIRE(zbit != 0); rpz_num = 0; #if DNS_RPZ_MAX_ZONES > 32 if ((zbit & 0xffffffff00000000L) != 0) { zbit >>= 32; rpz_num += 32; } #endif if ((zbit & 0xffff0000) != 0) { zbit >>= 16; rpz_num += 16; } if ((zbit & 0xff00) != 0) { zbit >>= 8; rpz_num += 8; } if ((zbit & 0xf0) != 0) { zbit >>= 4; rpz_num += 4; } if ((zbit & 0xc) != 0) { zbit >>= 2; rpz_num += 2; } if ((zbit & 2) != 0) ++rpz_num; return (rpz_num); } /* * Make a set of bit masks given one or more bits and their type. */ static void make_addr_set(dns_rpz_addr_zbits_t *tgt_set, dns_rpz_zbits_t zbits, dns_rpz_type_t type) { switch (type) { case DNS_RPZ_TYPE_CLIENT_IP: tgt_set->client_ip = zbits; tgt_set->ip = 0; tgt_set->nsip = 0; break; case DNS_RPZ_TYPE_IP: tgt_set->client_ip = 0; tgt_set->ip = zbits; tgt_set->nsip = 0; break; case DNS_RPZ_TYPE_NSIP: tgt_set->client_ip = 0; tgt_set->ip = 0; tgt_set->nsip = zbits; break; default: INSIST(0); break; } } static void make_nm_set(dns_rpz_nm_zbits_t *tgt_set, dns_rpz_num_t rpz_num, dns_rpz_type_t type) { switch (type) { case DNS_RPZ_TYPE_QNAME: tgt_set->qname = DNS_RPZ_ZBIT(rpz_num); tgt_set->ns = 0; break; case DNS_RPZ_TYPE_NSDNAME: tgt_set->qname = 0; tgt_set->ns = DNS_RPZ_ZBIT(rpz_num); break; default: INSIST(0); break; } } /* * Mark a node and all of its parents as having client-IP, IP, or NSIP data */ static void set_sum_pair(dns_rpz_cidr_node_t *cnode) { dns_rpz_cidr_node_t *child; dns_rpz_addr_zbits_t sum; do { sum = cnode->set; child = cnode->child[0]; if (child != NULL) { sum.client_ip |= child->sum.client_ip; sum.ip |= child->sum.ip; sum.nsip |= child->sum.nsip; } child = cnode->child[1]; if (child != NULL) { sum.client_ip |= child->sum.client_ip; sum.ip |= child->sum.ip; sum.nsip |= child->sum.nsip; } if (cnode->sum.client_ip == sum.client_ip && cnode->sum.ip == sum.ip && cnode->sum.nsip == sum.nsip) break; cnode->sum = sum; cnode = cnode->parent; } while (cnode != NULL); } /* Caller must hold rpzs->maint_lock */ static void fix_qname_skip_recurse(dns_rpz_zones_t *rpzs) { dns_rpz_zbits_t mask; /* * qname_wait_recurse and qname_skip_recurse are used to * implement the "qname-wait-recurse" config option. * * By default, "qname-wait-recurse" is yes, so no * processing happens without recursion. In this case, * qname_wait_recurse is true, and qname_skip_recurse * (a bit field indicating which policy zones can be * processed without recursion) is set to all 0's by * fix_qname_skip_recurse(). * * When "qname-wait-recurse" is no, qname_skip_recurse may be * set to a non-zero value by fix_qname_skip_recurse(). The mask * has to have bits set for the policy zones for which * processing may continue without recursion, and bits cleared * for the rest. * * (1) The ARM says: * * The "qname-wait-recurse no" option overrides that default * behavior when recursion cannot change a non-error * response. The option does not affect QNAME or client-IP * triggers in policy zones listed after other zones * containing IP, NSIP and NSDNAME triggers, because those may * depend on the A, AAAA, and NS records that would be found * during recursive resolution. * * Let's consider the following: * * zbits_req = (rpzs->have.ipv4 | rpzs->have.ipv6 | * rpzs->have.nsdname | * rpzs->have.nsipv4 | rpzs->have.nsipv6); * * zbits_req now contains bits set for zones which require * recursion. * * But going by the description in the ARM, if the first policy * zone requires recursion, then all zones after that (higher * order bits) have to wait as well. If the Nth zone requires * recursion, then (N+1)th zone onwards all need to wait. * * So mapping this, examples: * * zbits_req = 0b000 mask = 0xffffffff (no zones have to wait for * recursion) * zbits_req = 0b001 mask = 0x00000000 (all zones have to wait) * zbits_req = 0b010 mask = 0x00000001 (the first zone doesn't have to * wait, second zone onwards need * to wait) * zbits_req = 0b011 mask = 0x00000000 (all zones have to wait) * zbits_req = 0b100 mask = 0x00000011 (the 1st and 2nd zones don't * have to wait, third zone * onwards need to wait) * * More generally, we have to count the number of trailing 0 * bits in zbits_req and only these can be processed without * recursion. All the rest need to wait. * * (2) The ARM says that "qname-wait-recurse no" option * overrides the default behavior when recursion cannot change a * non-error response. So, in the order of listing of policy * zones, within the first policy zone where recursion may be * required, we should first allow CLIENT-IP and QNAME policy * records to be attempted without recursion. */ /* * Get a mask covering all policy zones that are not subordinate to * other policy zones containing triggers that require that the * qname be resolved before they can be checked. */ rpzs->have.client_ip = rpzs->have.client_ipv4 | rpzs->have.client_ipv6; rpzs->have.ip = rpzs->have.ipv4 | rpzs->have.ipv6; rpzs->have.nsip = rpzs->have.nsipv4 | rpzs->have.nsipv6; if (rpzs->p.qname_wait_recurse) { mask = 0; } else { dns_rpz_zbits_t zbits_req; dns_rpz_zbits_t zbits_notreq; dns_rpz_zbits_t mask2; dns_rpz_zbits_t req_mask; /* * Get the masks of zones with policies that * do/don't require recursion */ zbits_req = (rpzs->have.ipv4 | rpzs->have.ipv6 | rpzs->have.nsdname | rpzs->have.nsipv4 | rpzs->have.nsipv6); zbits_notreq = (rpzs->have.client_ip | rpzs->have.qname); if (zbits_req == 0) { mask = DNS_RPZ_ALL_ZBITS; goto set; } /* * req_mask is a mask covering used bits in * zbits_req. (For instance, 0b1 => 0b1, 0b101 => 0b111, * 0b11010101 => 0b11111111). */ req_mask = zbits_req; req_mask |= req_mask >> 1; req_mask |= req_mask >> 2; req_mask |= req_mask >> 4; req_mask |= req_mask >> 8; req_mask |= req_mask >> 16; #if DNS_RPZ_MAX_ZONES > 32 req_mask |= req_mask >> 32; #endif /* * There's no point in skipping recursion for a later * zone if it is required in a previous zone. */ if ((zbits_notreq & req_mask) == 0) { mask = 0; goto set; } /* * This bit arithmetic creates a mask of zones in which * it is okay to skip recursion. After the first zone * that has to wait for recursion, all the others have * to wait as well, so we want to create a mask in which * all the trailing zeroes in zbits_req are are 1, and * more significant bits are 0. (For instance, * 0x0700 => 0x00ff, 0x0007 => 0x0000) */ mask = ~(zbits_req | ((~zbits_req) + 1)); /* * As mentioned in (2) above, the zone corresponding to * the least significant zero could have its CLIENT-IP * and QNAME policies checked before recursion, if it * has any of those policies. So if it does, we * can set its 0 to 1. * * Locate the least significant 0 bit in the mask (for * instance, 0xff => 0x100)... */ mask2 = (mask << 1) & ~mask; /* * Also set the bit for zone 0, because if it's in * zbits_notreq then it's definitely okay to attempt to * skip recursion for zone 0... */ mask2 |= 1; /* Clear any bits *not* in zbits_notreq... */ mask2 &= zbits_notreq; /* And merge the result into the skip-recursion mask */ mask |= mask2; } set: isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB, DNS_RPZ_DEBUG_QUIET, "computed RPZ qname_skip_recurse mask=0x%llx", (isc_uint64_t) mask); rpzs->have.qname_skip_recurse = mask; } static void adj_trigger_cnt(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, dns_rpz_type_t rpz_type, const dns_rpz_cidr_key_t *tgt_ip, dns_rpz_prefix_t tgt_prefix, isc_boolean_t inc) { dns_rpz_trigger_counter_t *cnt; dns_rpz_zbits_t *have; switch (rpz_type) { case DNS_RPZ_TYPE_CLIENT_IP: REQUIRE(tgt_ip != NULL); if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) { cnt = &rpzs->triggers[rpz_num].client_ipv4; have = &rpzs->have.client_ipv4; } else { cnt = &rpzs->triggers[rpz_num].client_ipv6; have = &rpzs->have.client_ipv6; } break; case DNS_RPZ_TYPE_QNAME: cnt = &rpzs->triggers[rpz_num].qname; have = &rpzs->have.qname; break; case DNS_RPZ_TYPE_IP: REQUIRE(tgt_ip != NULL); if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) { cnt = &rpzs->triggers[rpz_num].ipv4; have = &rpzs->have.ipv4; } else { cnt = &rpzs->triggers[rpz_num].ipv6; have = &rpzs->have.ipv6; } break; case DNS_RPZ_TYPE_NSDNAME: cnt = &rpzs->triggers[rpz_num].nsdname; have = &rpzs->have.nsdname; break; case DNS_RPZ_TYPE_NSIP: REQUIRE(tgt_ip != NULL); if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) { cnt = &rpzs->triggers[rpz_num].nsipv4; have = &rpzs->have.nsipv4; } else { cnt = &rpzs->triggers[rpz_num].nsipv6; have = &rpzs->have.nsipv6; } break; default: INSIST(0); } if (inc) { if (++*cnt == 1U) { *have |= DNS_RPZ_ZBIT(rpz_num); fix_qname_skip_recurse(rpzs); } } else { REQUIRE(*cnt != 0U); if (--*cnt == 0U) { *have &= ~DNS_RPZ_ZBIT(rpz_num); fix_qname_skip_recurse(rpzs); } } } static dns_rpz_cidr_node_t * new_node(dns_rpz_zones_t *rpzs, const dns_rpz_cidr_key_t *ip, dns_rpz_prefix_t prefix, const dns_rpz_cidr_node_t *child) { dns_rpz_cidr_node_t *new; int i, words, wlen; new = isc_mem_get(rpzs->mctx, sizeof(*new)); if (new == NULL) return (NULL); memset(new, 0, sizeof(*new)); if (child != NULL) new->sum = child->sum; new->prefix = prefix; words = prefix / DNS_RPZ_CIDR_WORD_BITS; wlen = prefix % DNS_RPZ_CIDR_WORD_BITS; i = 0; while (i < words) { new->ip.w[i] = ip->w[i]; ++i; } if (wlen != 0) { new->ip.w[i] = ip->w[i] & DNS_RPZ_WORD_MASK(wlen); ++i; } while (i < DNS_RPZ_CIDR_WORDS) new->ip.w[i++] = 0; return (new); } static void badname(int level, dns_name_t *name, const char *str1, const char *str2) { char namebuf[DNS_NAME_FORMATSIZE]; /* * bin/tests/system/rpz/tests.sh looks for "invalid rpz". */ if (level < DNS_RPZ_DEBUG_QUIET && isc_log_wouldlog(dns_lctx, level)) { dns_name_format(name, namebuf, sizeof(namebuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB, level, "invalid rpz IP address \"%s\"%s%s", namebuf, str1, str2); } } /* * Convert an IP address from radix tree binary (host byte order) to * to its canonical response policy domain name without the origin of the * policy zone. */ static isc_result_t ip2name(const dns_rpz_cidr_key_t *tgt_ip, dns_rpz_prefix_t tgt_prefix, dns_name_t *base_name, dns_name_t *ip_name) { #ifndef INET6_ADDRSTRLEN #define INET6_ADDRSTRLEN 46 #endif int w[DNS_RPZ_CIDR_WORDS*2]; char str[1+8+1+INET6_ADDRSTRLEN+1]; isc_buffer_t buffer; isc_result_t result; isc_boolean_t zeros; int i, n, len; if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) { len = snprintf(str, sizeof(str), "%d.%d.%d.%d.%d", tgt_prefix - 96, tgt_ip->w[3] & 0xff, (tgt_ip->w[3]>>8) & 0xff, (tgt_ip->w[3]>>16) & 0xff, (tgt_ip->w[3]>>24) & 0xff); if (len < 0 || len > (int)sizeof(str)) return (ISC_R_FAILURE); } else { for (i = 0; i < DNS_RPZ_CIDR_WORDS; i++) { w[i*2+1] = ((tgt_ip->w[DNS_RPZ_CIDR_WORDS-1-i] >> 16) & 0xffff); w[i*2] = tgt_ip->w[DNS_RPZ_CIDR_WORDS-1-i] & 0xffff; } zeros = ISC_FALSE; len = snprintf(str, sizeof(str), "%d", tgt_prefix); if (len == -1) return (ISC_R_FAILURE); i = 0; while (i < DNS_RPZ_CIDR_WORDS * 2) { if (w[i] != 0 || zeros || i >= DNS_RPZ_CIDR_WORDS * 2 - 1 || w[i+1] != 0) { INSIST((size_t)len <= sizeof(str)); n = snprintf(&str[len], sizeof(str) - len, ".%x", w[i++]); if (n < 0) return (ISC_R_FAILURE); len += n; } else { zeros = ISC_TRUE; INSIST((size_t)len <= sizeof(str)); n = snprintf(&str[len], sizeof(str) - len, ".zz"); if (n < 0) return (ISC_R_FAILURE); len += n; i += 2; while (i < DNS_RPZ_CIDR_WORDS * 2 && w[i] == 0) ++i; } if (len >= (int)sizeof(str)) return (ISC_R_FAILURE); } } isc_buffer_init(&buffer, str, sizeof(str)); isc_buffer_add(&buffer, len); result = dns_name_fromtext(ip_name, &buffer, base_name, 0, NULL); return (result); } /* * Determine the type a of a name in a response policy zone. */ static dns_rpz_type_t type_from_name(dns_rpz_zone_t *rpz, dns_name_t *name) { if (dns_name_issubdomain(name, &rpz->ip)) return (DNS_RPZ_TYPE_IP); if (dns_name_issubdomain(name, &rpz->client_ip)) return (DNS_RPZ_TYPE_CLIENT_IP); #ifdef ENABLE_RPZ_NSIP if (dns_name_issubdomain(name, &rpz->nsip)) return (DNS_RPZ_TYPE_NSIP); #endif #ifdef ENABLE_RPZ_NSDNAME if (dns_name_issubdomain(name, &rpz->nsdname)) return (DNS_RPZ_TYPE_NSDNAME); #endif return (DNS_RPZ_TYPE_QNAME); } /* * Convert an IP address from canonical response policy domain name form * to radix tree binary (host byte order) for adding or deleting IP or NSIP * data. */ static isc_result_t name2ipkey(int log_level, const dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, dns_rpz_type_t rpz_type, dns_name_t *src_name, dns_rpz_cidr_key_t *tgt_ip, dns_rpz_prefix_t *tgt_prefix, dns_rpz_addr_zbits_t *new_set) { dns_rpz_zone_t *rpz; char ip_str[DNS_NAME_FORMATSIZE]; dns_offsets_t ip_name_offsets; dns_fixedname_t ip_name2f; dns_name_t ip_name, *ip_name2; const char *prefix_str, *cp, *end; char *cp2; int ip_labels; dns_rpz_prefix_t prefix; unsigned long prefix_num, l; isc_result_t result; int i; REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones); rpz = rpzs->zones[rpz_num]; REQUIRE(rpz != NULL); make_addr_set(new_set, DNS_RPZ_ZBIT(rpz_num), rpz_type); ip_labels = dns_name_countlabels(src_name); if (rpz_type == DNS_RPZ_TYPE_QNAME) ip_labels -= dns_name_countlabels(&rpz->origin); else ip_labels -= dns_name_countlabels(&rpz->nsdname); if (ip_labels < 2) { badname(log_level, src_name, "; too short", ""); return (ISC_R_FAILURE); } dns_name_init(&ip_name, ip_name_offsets); dns_name_getlabelsequence(src_name, 0, ip_labels, &ip_name); /* * Get text for the IP address */ dns_name_format(&ip_name, ip_str, sizeof(ip_str)); end = &ip_str[strlen(ip_str)+1]; prefix_str = ip_str; prefix_num = strtoul(prefix_str, &cp2, 10); if (*cp2 != '.') { badname(log_level, src_name, "; invalid leading prefix length", ""); return (ISC_R_FAILURE); } *cp2 = '\0'; if (prefix_num < 1U || prefix_num > 128U) { badname(log_level, src_name, "; invalid prefix length of ", prefix_str); return (ISC_R_FAILURE); } cp = cp2+1; if (--ip_labels == 4 && !strchr(cp, 'z')) { /* * Convert an IPv4 address * from the form "prefix.z.y.x.w" */ if (prefix_num > 32U) { badname(log_level, src_name, "; invalid IPv4 prefix length of ", prefix_str); return (ISC_R_FAILURE); } prefix_num += 96; *tgt_prefix = (dns_rpz_prefix_t)prefix_num; tgt_ip->w[0] = 0; tgt_ip->w[1] = 0; tgt_ip->w[2] = ADDR_V4MAPPED; tgt_ip->w[3] = 0; for (i = 0; i < 32; i += 8) { l = strtoul(cp, &cp2, 10); if (l > 255U || (*cp2 != '.' && *cp2 != '\0')) { if (*cp2 == '.') *cp2 = '\0'; badname(log_level, src_name, "; invalid IPv4 octet ", cp); return (ISC_R_FAILURE); } tgt_ip->w[3] |= l << i; cp = cp2 + 1; } } else { /* * Convert a text IPv6 address. */ *tgt_prefix = (dns_rpz_prefix_t)prefix_num; for (i = 0; ip_labels > 0 && i < DNS_RPZ_CIDR_WORDS * 2; ip_labels--) { if (cp[0] == 'z' && cp[1] == 'z' && (cp[2] == '.' || cp[2] == '\0') && i <= 6) { do { if ((i & 1) == 0) tgt_ip->w[3-i/2] = 0; ++i; } while (ip_labels + i <= 8); cp += 3; } else { l = strtoul(cp, &cp2, 16); if (l > 0xffffu || (*cp2 != '.' && *cp2 != '\0')) { if (*cp2 == '.') *cp2 = '\0'; badname(log_level, src_name, "; invalid IPv6 word ", cp); return (ISC_R_FAILURE); } if ((i & 1) == 0) tgt_ip->w[3-i/2] = l; else tgt_ip->w[3-i/2] |= l << 16; i++; cp = cp2 + 1; } } } if (cp != end) { badname(log_level, src_name, "", ""); return (ISC_R_FAILURE); } /* * Check for 1s after the prefix length. */ prefix = (dns_rpz_prefix_t)prefix_num; while (prefix < DNS_RPZ_CIDR_KEY_BITS) { dns_rpz_cidr_word_t aword; i = prefix % DNS_RPZ_CIDR_WORD_BITS; aword = tgt_ip->w[prefix / DNS_RPZ_CIDR_WORD_BITS]; if ((aword & ~DNS_RPZ_WORD_MASK(i)) != 0) { badname(log_level, src_name, "; too small prefix length of ", prefix_str); return (ISC_R_FAILURE); } prefix -= i; prefix += DNS_RPZ_CIDR_WORD_BITS; } /* * XXXMUKS: Should the following check be enabled in a * production build? It can be expensive for large IP zones * from 3rd parties. */ /* * Convert the address back to a canonical domain name * to ensure that the original name is in canonical form. */ dns_fixedname_init(&ip_name2f); ip_name2 = dns_fixedname_name(&ip_name2f); result = ip2name(tgt_ip, (dns_rpz_prefix_t)prefix_num, NULL, ip_name2); if (result != ISC_R_SUCCESS || !dns_name_equal(&ip_name, ip_name2)) { badname(log_level, src_name, "; not canonical", ""); return (ISC_R_FAILURE); } return (ISC_R_SUCCESS); } /* * Get trigger name and data bits for adding or deleting summary NSDNAME * or QNAME data. */ static void name2data(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, dns_rpz_type_t rpz_type, const dns_name_t *src_name, dns_name_t *trig_name, dns_rpz_nm_data_t *new_data) { dns_rpz_zone_t *rpz; dns_offsets_t tmp_name_offsets; dns_name_t tmp_name; unsigned int prefix_len, n; REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones); rpz = rpzs->zones[rpz_num]; REQUIRE(rpz != NULL); /* * Handle wildcards by putting only the parent into the * summary RBT. The summary database only causes a check of the * real policy zone where wildcards will be handled. */ if (dns_name_iswildcard(src_name)) { prefix_len = 1; memset(&new_data->set, 0, sizeof(new_data->set)); make_nm_set(&new_data->wild, rpz_num, rpz_type); } else { prefix_len = 0; make_nm_set(&new_data->set, rpz_num, rpz_type); memset(&new_data->wild, 0, sizeof(new_data->wild)); } dns_name_init(&tmp_name, tmp_name_offsets); n = dns_name_countlabels(src_name); n -= prefix_len; if (rpz_type == DNS_RPZ_TYPE_QNAME) n -= dns_name_countlabels(&rpz->origin); else n -= dns_name_countlabels(&rpz->nsdname); dns_name_getlabelsequence(src_name, prefix_len, n, &tmp_name); (void)dns_name_concatenate(&tmp_name, dns_rootname, trig_name, NULL); } /* * Find the first differing bit in a key (IP address) word. */ static inline int ffs_keybit(dns_rpz_cidr_word_t w) { int bit; bit = DNS_RPZ_CIDR_WORD_BITS-1; if ((w & 0xffff0000) != 0) { w >>= 16; bit -= 16; } if ((w & 0xff00) != 0) { w >>= 8; bit -= 8; } if ((w & 0xf0) != 0) { w >>= 4; bit -= 4; } if ((w & 0xc) != 0) { w >>= 2; bit -= 2; } if ((w & 2) != 0) --bit; return (bit); } /* * Find the first differing bit in two keys (IP addresses). */ static int diff_keys(const dns_rpz_cidr_key_t *key1, dns_rpz_prefix_t prefix1, const dns_rpz_cidr_key_t *key2, dns_rpz_prefix_t prefix2) { dns_rpz_cidr_word_t delta; dns_rpz_prefix_t maxbit, bit; int i; bit = 0; maxbit = ISC_MIN(prefix1, prefix2); /* * find the first differing words */ for (i = 0; bit < maxbit; i++, bit += DNS_RPZ_CIDR_WORD_BITS) { delta = key1->w[i] ^ key2->w[i]; if (delta != 0) { bit += ffs_keybit(delta); break; } } return (ISC_MIN(bit, maxbit)); } /* * Given a hit while searching the radix trees, * clear all bits for higher numbered zones. */ static inline dns_rpz_zbits_t trim_zbits(dns_rpz_zbits_t zbits, dns_rpz_zbits_t found) { dns_rpz_zbits_t x; /* * Isolate the first or smallest numbered hit bit. * Make a mask of that bit and all smaller numbered bits. */ x = zbits & found; x &= (~x + 1); x = (x << 1) - 1; return (zbits &= x); } /* * Search a radix tree for an IP address for ordinary lookup * or for a CIDR block adding or deleting an entry * * Return ISC_R_SUCCESS, DNS_R_PARTIALMATCH, ISC_R_NOTFOUND, * and *found=longest match node * or with create==ISC_TRUE, ISC_R_EXISTS or ISC_R_NOMEMORY */ static isc_result_t search(dns_rpz_zones_t *rpzs, const dns_rpz_cidr_key_t *tgt_ip, dns_rpz_prefix_t tgt_prefix, const dns_rpz_addr_zbits_t *tgt_set, isc_boolean_t create, dns_rpz_cidr_node_t **found) { dns_rpz_cidr_node_t *cur, *parent, *child, *new_parent, *sibling; dns_rpz_addr_zbits_t set; int cur_num, child_num; dns_rpz_prefix_t dbit; isc_result_t find_result; set = *tgt_set; find_result = ISC_R_NOTFOUND; *found = NULL; cur = rpzs->cidr; parent = NULL; cur_num = 0; for (;;) { if (cur == NULL) { /* * No child so we cannot go down. * Quit with whatever we already found * or add the target as a child of the current parent. */ if (!create) return (find_result); child = new_node(rpzs, tgt_ip, tgt_prefix, NULL); if (child == NULL) return (ISC_R_NOMEMORY); if (parent == NULL) rpzs->cidr = child; else parent->child[cur_num] = child; child->parent = parent; child->set.client_ip |= tgt_set->client_ip; child->set.ip |= tgt_set->ip; child->set.nsip |= tgt_set->nsip; set_sum_pair(child); *found = child; return (ISC_R_SUCCESS); } if ((cur->sum.client_ip & set.client_ip) == 0 && (cur->sum.ip & set.ip) == 0 && (cur->sum.nsip & set.nsip) == 0) { /* * This node has no relevant data * and is in none of the target trees. * Pretend it does not exist if we are not adding. * * If we are adding, continue down to eventually add * a node and mark/put this node in the correct tree. */ if (!create) return (find_result); } dbit = diff_keys(tgt_ip, tgt_prefix, &cur->ip, cur->prefix); /* * dbit <= tgt_prefix and dbit <= cur->prefix always. * We are finished searching if we matched all of the target. */ if (dbit == tgt_prefix) { if (tgt_prefix == cur->prefix) { /* * The node's key matches the target exactly. */ if ((cur->set.client_ip & set.client_ip) != 0 || (cur->set.ip & set.ip) != 0 || (cur->set.nsip & set.nsip) != 0) { /* * It is the answer if it has data. */ *found = cur; if (create) { find_result = ISC_R_EXISTS; } else { find_result = ISC_R_SUCCESS; } } else if (create) { /* * The node lacked relevant data, * but will have it now. */ cur->set.client_ip |= tgt_set->client_ip; cur->set.ip |= tgt_set->ip; cur->set.nsip |= tgt_set->nsip; set_sum_pair(cur); *found = cur; find_result = ISC_R_SUCCESS; } return (find_result); } /* * We know tgt_prefix < cur->prefix which means that * the target is shorter than the current node. * Add the target as the current node's parent. */ if (!create) return (find_result); new_parent = new_node(rpzs, tgt_ip, tgt_prefix, cur); if (new_parent == NULL) return (ISC_R_NOMEMORY); new_parent->parent = parent; if (parent == NULL) rpzs->cidr = new_parent; else parent->child[cur_num] = new_parent; child_num = DNS_RPZ_IP_BIT(&cur->ip, tgt_prefix+1); new_parent->child[child_num] = cur; cur->parent = new_parent; new_parent->set = *tgt_set; set_sum_pair(new_parent); *found = new_parent; return (ISC_R_SUCCESS); } if (dbit == cur->prefix) { if ((cur->set.client_ip & set.client_ip) != 0 || (cur->set.ip & set.ip) != 0 || (cur->set.nsip & set.nsip) != 0) { /* * We have a partial match between of all of the * current node but only part of the target. * Continue searching for other hits in the * same or lower numbered trees. */ find_result = DNS_R_PARTIALMATCH; *found = cur; set.client_ip = trim_zbits(set.client_ip, cur->set.client_ip); set.ip = trim_zbits(set.ip, cur->set.ip); set.nsip = trim_zbits(set.nsip, cur->set.nsip); } parent = cur; cur_num = DNS_RPZ_IP_BIT(tgt_ip, dbit); cur = cur->child[cur_num]; continue; } /* * dbit < tgt_prefix and dbit < cur->prefix, * so we failed to match both the target and the current node. * Insert a fork of a parent above the current node and * add the target as a sibling of the current node */ if (!create) return (find_result); sibling = new_node(rpzs, tgt_ip, tgt_prefix, NULL); if (sibling == NULL) return (ISC_R_NOMEMORY); new_parent = new_node(rpzs, tgt_ip, dbit, cur); if (new_parent == NULL) { isc_mem_put(rpzs->mctx, sibling, sizeof(*sibling)); return (ISC_R_NOMEMORY); } new_parent->parent = parent; if (parent == NULL) rpzs->cidr = new_parent; else parent->child[cur_num] = new_parent; child_num = DNS_RPZ_IP_BIT(tgt_ip, dbit); new_parent->child[child_num] = sibling; new_parent->child[1-child_num] = cur; cur->parent = new_parent; sibling->parent = new_parent; sibling->set = *tgt_set; set_sum_pair(sibling); *found = sibling; return (ISC_R_SUCCESS); } } /* * Add an IP address to the radix tree. */ static isc_result_t add_cidr(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, dns_rpz_type_t rpz_type, dns_name_t *src_name) { dns_rpz_cidr_key_t tgt_ip; dns_rpz_prefix_t tgt_prefix; dns_rpz_addr_zbits_t set; dns_rpz_cidr_node_t *found; isc_result_t result; result = name2ipkey(DNS_RPZ_ERROR_LEVEL, rpzs, rpz_num, rpz_type, src_name, &tgt_ip, &tgt_prefix, &set); /* * Log complaints about bad owner names but let the zone load. */ if (result != ISC_R_SUCCESS) return (ISC_R_SUCCESS); result = search(rpzs, &tgt_ip, tgt_prefix, &set, ISC_TRUE, &found); if (result != ISC_R_SUCCESS) { char namebuf[DNS_NAME_FORMATSIZE]; /* * Do not worry if the radix tree already exists, * because diff_apply() likes to add nodes before deleting. */ if (result == ISC_R_EXISTS) return (ISC_R_SUCCESS); /* * bin/tests/system/rpz/tests.sh looks for "rpz.*failed". */ dns_name_format(src_name, namebuf, sizeof(namebuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, "rpz add_cidr(%s) failed: %s", namebuf, isc_result_totext(result)); return (result); } adj_trigger_cnt(rpzs, rpz_num, rpz_type, &tgt_ip, tgt_prefix, ISC_TRUE); return (result); } static isc_result_t add_nm(dns_rpz_zones_t *rpzs, dns_name_t *trig_name, const dns_rpz_nm_data_t *new_data) { dns_rbtnode_t *nmnode; dns_rpz_nm_data_t *nm_data; isc_result_t result; nmnode = NULL; result = dns_rbt_addnode(rpzs->rbt, trig_name, &nmnode); switch (result) { case ISC_R_SUCCESS: case ISC_R_EXISTS: nm_data = nmnode->data; if (nm_data == NULL) { nm_data = isc_mem_get(rpzs->mctx, sizeof(*nm_data)); if (nm_data == NULL) return (ISC_R_NOMEMORY); *nm_data = *new_data; nmnode->data = nm_data; return (ISC_R_SUCCESS); } break; default: return (result); } /* * Do not count bits that are already present */ if ((nm_data->set.qname & new_data->set.qname) != 0 || (nm_data->set.ns & new_data->set.ns) != 0 || (nm_data->wild.qname & new_data->wild.qname) != 0 || (nm_data->wild.ns & new_data->wild.ns) != 0) return (ISC_R_EXISTS); nm_data->set.qname |= new_data->set.qname; nm_data->set.ns |= new_data->set.ns; nm_data->wild.qname |= new_data->wild.qname; nm_data->wild.ns |= new_data->wild.ns; return (ISC_R_SUCCESS); } static isc_result_t add_name(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, dns_rpz_type_t rpz_type, dns_name_t *src_name) { dns_rpz_nm_data_t new_data; dns_fixedname_t trig_namef; dns_name_t *trig_name; isc_result_t result; /* * We need a summary database of names even with 1 policy zone, * because wildcard triggers are handled differently. */ dns_fixedname_init(&trig_namef); trig_name = dns_fixedname_name(&trig_namef); name2data(rpzs, rpz_num, rpz_type, src_name, trig_name, &new_data); result = add_nm(rpzs, trig_name, &new_data); /* * Do not worry if the node already exists, * because diff_apply() likes to add nodes before deleting. */ if (result == ISC_R_EXISTS) return (ISC_R_SUCCESS); if (result == ISC_R_SUCCESS) adj_trigger_cnt(rpzs, rpz_num, rpz_type, NULL, 0, ISC_TRUE); return (result); } /* * Callback to free the data for a node in the summary RBT database. */ static void rpz_node_deleter(void *nm_data, void *mctx) { isc_mem_put(mctx, nm_data, sizeof(dns_rpz_nm_data_t)); } /* * Get ready for a new set of policy zones. */ isc_result_t dns_rpz_new_zones(dns_rpz_zones_t **rpzsp, isc_mem_t *mctx) { dns_rpz_zones_t *new; isc_result_t result; REQUIRE(rpzsp != NULL && *rpzsp == NULL); *rpzsp = NULL; new = isc_mem_get(mctx, sizeof(*new)); if (new == NULL) return (ISC_R_NOMEMORY); memset(new, 0, sizeof(*new)); result = isc_rwlock_init(&new->search_lock, 0, 0); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, new, sizeof(*new)); return (result); } result = isc_mutex_init(&new->maint_lock); if (result != ISC_R_SUCCESS) { isc_rwlock_destroy(&new->search_lock); isc_mem_put(mctx, new, sizeof(*new)); return (result); } result = isc_refcount_init(&new->refs, 1); if (result != ISC_R_SUCCESS) { DESTROYLOCK(&new->maint_lock); isc_rwlock_destroy(&new->search_lock); isc_mem_put(mctx, new, sizeof(*new)); return (result); } result = dns_rbt_create(mctx, rpz_node_deleter, mctx, &new->rbt); if (result != ISC_R_SUCCESS) { isc_refcount_decrement(&new->refs, NULL); isc_refcount_destroy(&new->refs); DESTROYLOCK(&new->maint_lock); isc_rwlock_destroy(&new->search_lock); isc_mem_put(mctx, new, sizeof(*new)); return (result); } isc_mem_attach(mctx, &new->mctx); *rpzsp = new; return (ISC_R_SUCCESS); } /* * Free the radix tree of a response policy database. */ static void cidr_free(dns_rpz_zones_t *rpzs) { dns_rpz_cidr_node_t *cur, *child, *parent; cur = rpzs->cidr; while (cur != NULL) { /* Depth first. */ child = cur->child[0]; if (child != NULL) { cur = child; continue; } child = cur->child[1]; if (child != NULL) { cur = child; continue; } /* Delete this leaf and go up. */ parent = cur->parent; if (parent == NULL) rpzs->cidr = NULL; else parent->child[parent->child[1] == cur] = NULL; isc_mem_put(rpzs->mctx, cur, sizeof(*cur)); cur = parent; } } /* * Discard a response policy zone blob * before discarding the overall rpz structure. */ static void rpz_detach(dns_rpz_zone_t **rpzp, dns_rpz_zones_t *rpzs) { dns_rpz_zone_t *rpz; unsigned int refs; rpz = *rpzp; *rpzp = NULL; isc_refcount_decrement(&rpz->refs, &refs); if (refs != 0) return; isc_refcount_destroy(&rpz->refs); if (dns_name_dynamic(&rpz->origin)) dns_name_free(&rpz->origin, rpzs->mctx); if (dns_name_dynamic(&rpz->client_ip)) dns_name_free(&rpz->client_ip, rpzs->mctx); if (dns_name_dynamic(&rpz->ip)) dns_name_free(&rpz->ip, rpzs->mctx); if (dns_name_dynamic(&rpz->nsdname)) dns_name_free(&rpz->nsdname, rpzs->mctx); if (dns_name_dynamic(&rpz->nsip)) dns_name_free(&rpz->nsip, rpzs->mctx); if (dns_name_dynamic(&rpz->passthru)) dns_name_free(&rpz->passthru, rpzs->mctx); if (dns_name_dynamic(&rpz->drop)) dns_name_free(&rpz->drop, rpzs->mctx); if (dns_name_dynamic(&rpz->tcp_only)) dns_name_free(&rpz->tcp_only, rpzs->mctx); if (dns_name_dynamic(&rpz->cname)) dns_name_free(&rpz->cname, rpzs->mctx); isc_mem_put(rpzs->mctx, rpz, sizeof(*rpz)); } void dns_rpz_attach_rpzs(dns_rpz_zones_t *rpzs, dns_rpz_zones_t **rpzsp) { REQUIRE(rpzsp != NULL && *rpzsp == NULL); isc_refcount_increment(&rpzs->refs, NULL); *rpzsp = rpzs; } /* * Forget a view's policy zones. */ void dns_rpz_detach_rpzs(dns_rpz_zones_t **rpzsp) { dns_rpz_zones_t *rpzs; dns_rpz_zone_t *rpz; dns_rpz_num_t rpz_num; unsigned int refs; REQUIRE(rpzsp != NULL); rpzs = *rpzsp; REQUIRE(rpzs != NULL); *rpzsp = NULL; isc_refcount_decrement(&rpzs->refs, &refs); /* * Forget the last of view's rpz machinery after the last reference. */ if (refs == 0) { for (rpz_num = 0; rpz_num < DNS_RPZ_MAX_ZONES; ++rpz_num) { rpz = rpzs->zones[rpz_num]; rpzs->zones[rpz_num] = NULL; if (rpz != NULL) rpz_detach(&rpz, rpzs); } cidr_free(rpzs); dns_rbt_destroy(&rpzs->rbt); DESTROYLOCK(&rpzs->maint_lock); isc_rwlock_destroy(&rpzs->search_lock); isc_refcount_destroy(&rpzs->refs); isc_mem_putanddetach(&rpzs->mctx, rpzs, sizeof(*rpzs)); } } /* * Create empty summary database to load one zone. * The RBTDB write tree lock must be held. */ isc_result_t dns_rpz_beginload(dns_rpz_zones_t **load_rpzsp, dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num) { dns_rpz_zones_t *load_rpzs; dns_rpz_zone_t *rpz; dns_rpz_zbits_t tgt; isc_result_t result; REQUIRE(rpz_num < rpzs->p.num_zones); rpz = rpzs->zones[rpz_num]; REQUIRE(rpz != NULL); /* * When reloading a zone, there are usually records among the summary * data for the zone. Some of those records might be deleted by the * reloaded zone data. To deal with that case: * reload the new zone data into a new blank summary database * if the reload fails, discard the new summary database * if the new zone data is acceptable, copy the records for the * other zones into the new summary CIDR and RBT databases * and replace the old summary databases with the new, and * correct the triggers and have values for the updated * zone. * * At the first attempt to load a zone, there is no summary data * for the zone and so no records that need to be deleted. * This is also the most common case of policy zone loading. * Most policy zone maintenance should be by incremental changes * and so by the addition and deletion of individual records. * Detect that case and load records the first time into the * operational summary database */ tgt = DNS_RPZ_ZBIT(rpz_num); LOCK(&rpzs->maint_lock); RWLOCK(&rpzs->search_lock, isc_rwlocktype_write); if ((rpzs->load_begun & tgt) == 0) { /* * There is no existing version of the target zone. */ rpzs->load_begun |= tgt; dns_rpz_attach_rpzs(rpzs, load_rpzsp); } else { /* * Setup the new RPZ struct with empty summary trees. */ result = dns_rpz_new_zones(load_rpzsp, rpzs->mctx); if (result != ISC_R_SUCCESS) return (result); load_rpzs = *load_rpzsp; /* * Initialize some members so that dns_rpz_add() works. */ load_rpzs->p.num_zones = rpzs->p.num_zones; memset(&load_rpzs->triggers, 0, sizeof(load_rpzs->triggers)); load_rpzs->zones[rpz_num] = rpz; isc_refcount_increment(&rpz->refs, NULL); } RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write); UNLOCK(&rpzs->maint_lock); return (ISC_R_SUCCESS); } /* * This function updates "have" bits and also the qname_skip_recurse * mask. It must be called when holding a write lock on rpzs->search_lock. */ static void fix_triggers(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num) { dns_rpz_num_t n; dns_rpz_triggers_t old_totals; dns_rpz_zbits_t zbit; char namebuf[DNS_NAME_FORMATSIZE]; /* * rpzs->total_triggers is only used to log a message below. */ memmove(&old_totals, &rpzs->total_triggers, sizeof(old_totals)); memset(&rpzs->total_triggers, 0, sizeof(rpzs->total_triggers)); #define SET_TRIG(n, zbit, type) \ if (rpzs->triggers[n].type == 0U) { \ rpzs->have.type &= ~zbit; \ } else { \ rpzs->total_triggers.type += rpzs->triggers[n].type; \ rpzs->have.type |= zbit; \ } for (n = 0; n < rpzs->p.num_zones; ++n) { zbit = DNS_RPZ_ZBIT(n); SET_TRIG(n, zbit, client_ipv4); SET_TRIG(n, zbit, client_ipv6); SET_TRIG(n, zbit, qname); SET_TRIG(n, zbit, ipv4); SET_TRIG(n, zbit, ipv6); SET_TRIG(n, zbit, nsdname); SET_TRIG(n, zbit, nsipv4); SET_TRIG(n, zbit, nsipv6); } #undef SET_TRIG fix_qname_skip_recurse(rpzs); dns_name_format(&rpzs->zones[rpz_num]->origin, namebuf, sizeof(namebuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB, DNS_RPZ_INFO_LEVEL, "(re)loading policy zone '%s' changed from" " %lu to %lu qname, %lu to %lu nsdname," " %lu to %lu IP, %lu to %lu NSIP," " %lu to %lu CLIENTIP entries", namebuf, (unsigned long) old_totals.qname, (unsigned long) rpzs->total_triggers.qname, (unsigned long) old_totals.nsdname, (unsigned long) rpzs->total_triggers.nsdname, (unsigned long) old_totals.ipv4 + old_totals.ipv6, (unsigned long) (rpzs->total_triggers.ipv4 + rpzs->total_triggers.ipv6), (unsigned long) old_totals.nsipv4 + old_totals.nsipv6, (unsigned long) (rpzs->total_triggers.nsipv4 + rpzs->total_triggers.nsipv6), (unsigned long) old_totals.client_ipv4 + old_totals.client_ipv6, (unsigned long) (rpzs->total_triggers.client_ipv4 + rpzs->total_triggers.client_ipv6)); } /* * Finish loading one zone. This function is called during a commit when * a RPZ zone loading is complete. The RBTDB write tree lock must be * held. * * Here, rpzs is a pointer to the view's common rpzs * structure. *load_rpzsp is a rpzs structure that is local to the * RBTDB, which is used during a single zone's load. * * During the zone load, i.e., between dns_rpz_beginload() and * dns_rpz_ready(), only the zone that is being loaded updates * *load_rpzsp. These updates in the summary databases inside load_rpzsp * are made only for the rpz_num (and corresponding bit) of that * zone. Nothing else reads or writes *load_rpzsp. The view's common * rpzs is used during this time for queries. * * When zone loading is complete and we arrive here, the parts of the * summary databases (CIDR and nsdname+qname RBT trees) from the view's * common rpzs struct have to be merged into the summary databases of * *load_rpzsp, as the summary databases of the view's common rpzs * struct may have changed during the time the zone was being loaded. * * The function below carries out the merge. During the merge, it holds * the maint_lock of the view's common rpzs struct so that it is not * updated while the merging is taking place. * * After the merging is carried out, *load_rpzsp contains the most * current state of the rpzs structure, i.e., the summary trees contain * data for the new zone that was just loaded, as well as all other * zones. * * Pointers to the summary databases of *load_rpzsp (CIDR and * nsdname+qname RBT trees) are then swapped into the view's common rpz * struct, so that the query path can continue using it. During the * swap, the search_lock of the view's common rpz struct is acquired so * that queries are paused while this swap occurs. * * The trigger counts for the new zone are also copied into the view's * common rpz struct, and some other summary counts and masks are * updated. */ isc_result_t dns_rpz_ready(dns_rpz_zones_t *rpzs, dns_rpz_zones_t **load_rpzsp, dns_rpz_num_t rpz_num) { dns_rpz_zones_t *load_rpzs; const dns_rpz_cidr_node_t *cnode, *next_cnode, *parent_cnode; dns_rpz_cidr_node_t *found; dns_rpz_zbits_t new_bit; dns_rpz_addr_zbits_t new_ip; dns_rbt_t *rbt; dns_rbtnodechain_t chain; dns_rbtnode_t *nmnode; dns_rpz_nm_data_t *nm_data, new_data; dns_fixedname_t labelf, originf, namef; dns_name_t *label, *origin, *name; isc_result_t result; INSIST(rpzs != NULL); LOCK(&rpzs->maint_lock); load_rpzs = *load_rpzsp; INSIST(load_rpzs != NULL); if (load_rpzs == rpzs) { /* * This is a successful initial zone loading, perhaps * for a new instance of a view. */ RWLOCK(&rpzs->search_lock, isc_rwlocktype_write); fix_triggers(rpzs, rpz_num); RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write); UNLOCK(&rpzs->maint_lock); dns_rpz_detach_rpzs(load_rpzsp); return (ISC_R_SUCCESS); } LOCK(&load_rpzs->maint_lock); RWLOCK(&load_rpzs->search_lock, isc_rwlocktype_write); /* * Unless there is only one policy zone, copy the other policy zones * from the old policy structure to the new summary databases. */ if (rpzs->p.num_zones > 1) { new_bit = ~DNS_RPZ_ZBIT(rpz_num); /* * Copy to the radix tree. */ for (cnode = rpzs->cidr; cnode != NULL; cnode = next_cnode) { new_ip.ip = cnode->set.ip & new_bit; new_ip.client_ip = cnode->set.client_ip & new_bit; new_ip.nsip = cnode->set.nsip & new_bit; if (new_ip.client_ip != 0 || new_ip.ip != 0 || new_ip.nsip != 0) { result = search(load_rpzs, &cnode->ip, cnode->prefix, &new_ip, ISC_TRUE, &found); if (result == ISC_R_NOMEMORY) goto unlock_and_detach; INSIST(result == ISC_R_SUCCESS); } /* * Do down and to the left as far as possible. */ next_cnode = cnode->child[0]; if (next_cnode != NULL) continue; /* * Go up until we find a branch to the right where * we previously took the branch to the left. */ for (;;) { parent_cnode = cnode->parent; if (parent_cnode == NULL) break; if (parent_cnode->child[0] == cnode) { next_cnode = parent_cnode->child[1]; if (next_cnode != NULL) break; } cnode = parent_cnode; } } /* * Copy to the summary RBT. */ dns_fixedname_init(&namef); name = dns_fixedname_name(&namef); dns_fixedname_init(&labelf); label = dns_fixedname_name(&labelf); dns_fixedname_init(&originf); origin = dns_fixedname_name(&originf); dns_rbtnodechain_init(&chain, NULL); result = dns_rbtnodechain_first(&chain, rpzs->rbt, NULL, NULL); while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) { result = dns_rbtnodechain_current(&chain, label, origin, &nmnode); INSIST(result == ISC_R_SUCCESS); nm_data = nmnode->data; if (nm_data != NULL) { new_data.set.qname = (nm_data->set.qname & new_bit); new_data.set.ns = nm_data->set.ns & new_bit; new_data.wild.qname = (nm_data->wild.qname & new_bit); new_data.wild.ns = nm_data->wild.ns & new_bit; if (new_data.set.qname != 0 || new_data.set.ns != 0 || new_data.wild.qname != 0 || new_data.wild.ns != 0) { result = dns_name_concatenate(label, origin, name, NULL); INSIST(result == ISC_R_SUCCESS); result = add_nm(load_rpzs, name, &new_data); if (result != ISC_R_SUCCESS) goto unlock_and_detach; } } result = dns_rbtnodechain_next(&chain, NULL, NULL); } if (result != ISC_R_NOMORE && result != ISC_R_NOTFOUND) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, "dns_rpz_ready(): unexpected %s", isc_result_totext(result)); goto unlock_and_detach; } } /* * Exchange the summary databases. */ RWLOCK(&rpzs->search_lock, isc_rwlocktype_write); rpzs->triggers[rpz_num] = load_rpzs->triggers[rpz_num]; fix_triggers(rpzs, rpz_num); found = rpzs->cidr; rpzs->cidr = load_rpzs->cidr; load_rpzs->cidr = found; rbt = rpzs->rbt; rpzs->rbt = load_rpzs->rbt; load_rpzs->rbt = rbt; RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write); result = ISC_R_SUCCESS; unlock_and_detach: UNLOCK(&rpzs->maint_lock); RWUNLOCK(&load_rpzs->search_lock, isc_rwlocktype_write); UNLOCK(&load_rpzs->maint_lock); dns_rpz_detach_rpzs(load_rpzsp); return (result); } /* * Add an IP address to the radix tree or a name to the summary database. */ isc_result_t dns_rpz_add(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, dns_name_t *src_name) { dns_rpz_zone_t *rpz; dns_rpz_type_t rpz_type; isc_result_t result = ISC_R_FAILURE; REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones); rpz = rpzs->zones[rpz_num]; REQUIRE(rpz != NULL); rpz_type = type_from_name(rpz, src_name); LOCK(&rpzs->maint_lock); RWLOCK(&rpzs->search_lock, isc_rwlocktype_write); switch (rpz_type) { case DNS_RPZ_TYPE_QNAME: case DNS_RPZ_TYPE_NSDNAME: result = add_name(rpzs, rpz_num, rpz_type, src_name); break; case DNS_RPZ_TYPE_CLIENT_IP: case DNS_RPZ_TYPE_IP: case DNS_RPZ_TYPE_NSIP: result = add_cidr(rpzs, rpz_num, rpz_type, src_name); break; case DNS_RPZ_TYPE_BAD: break; } RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write); UNLOCK(&rpzs->maint_lock); return (result); } /* * Remove an IP address from the radix tree. */ static void del_cidr(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, dns_rpz_type_t rpz_type, dns_name_t *src_name) { isc_result_t result; dns_rpz_cidr_key_t tgt_ip; dns_rpz_prefix_t tgt_prefix; dns_rpz_addr_zbits_t tgt_set; dns_rpz_cidr_node_t *tgt, *parent, *child; /* * Do not worry about invalid rpz IP address names. If we * are here, then something relevant was added and so was * valid. Invalid names here are usually internal RBTDB nodes. */ result = name2ipkey(DNS_RPZ_DEBUG_QUIET, rpzs, rpz_num, rpz_type, src_name, &tgt_ip, &tgt_prefix, &tgt_set); if (result != ISC_R_SUCCESS) return; result = search(rpzs, &tgt_ip, tgt_prefix, &tgt_set, ISC_FALSE, &tgt); if (result != ISC_R_SUCCESS) { INSIST(result == ISC_R_NOTFOUND || result == DNS_R_PARTIALMATCH); /* * Do not worry about missing summary RBT nodes that probably * correspond to RBTDB nodes that were implicit RBT nodes * that were later added for (often empty) wildcards * and then to the RBTDB deferred cleanup list. */ return; } /* * Mark the node and its parents to reflect the deleted IP address. * Do not count bits that are already clear for internal RBTDB nodes. */ tgt_set.client_ip &= tgt->set.client_ip; tgt_set.ip &= tgt->set.ip; tgt_set.nsip &= tgt->set.nsip; tgt->set.client_ip &= ~tgt_set.client_ip; tgt->set.ip &= ~tgt_set.ip; tgt->set.nsip &= ~tgt_set.nsip; set_sum_pair(tgt); adj_trigger_cnt(rpzs, rpz_num, rpz_type, &tgt_ip, tgt_prefix, ISC_FALSE); /* * We might need to delete 2 nodes. */ do { /* * The node is now useless if it has no data of its own * and 0 or 1 children. We are finished if it is not useless. */ if ((child = tgt->child[0]) != NULL) { if (tgt->child[1] != NULL) break; } else { child = tgt->child[1]; } if (tgt->set.client_ip != 0 || tgt->set.ip != 0 || tgt->set.nsip != 0) break; /* * Replace the pointer to this node in the parent with * the remaining child or NULL. */ parent = tgt->parent; if (parent == NULL) { rpzs->cidr = child; } else { parent->child[parent->child[1] == tgt] = child; } /* * If the child exists fix up its parent pointer. */ if (child != NULL) child->parent = parent; isc_mem_put(rpzs->mctx, tgt, sizeof(*tgt)); tgt = parent; } while (tgt != NULL); } static void del_name(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, dns_rpz_type_t rpz_type, dns_name_t *src_name) { char namebuf[DNS_NAME_FORMATSIZE]; dns_fixedname_t trig_namef; dns_name_t *trig_name; dns_rbtnode_t *nmnode; dns_rpz_nm_data_t *nm_data, del_data; isc_result_t result; /* * We need a summary database of names even with 1 policy zone, * because wildcard triggers are handled differently. */ dns_fixedname_init(&trig_namef); trig_name = dns_fixedname_name(&trig_namef); name2data(rpzs, rpz_num, rpz_type, src_name, trig_name, &del_data); nmnode = NULL; result = dns_rbt_findnode(rpzs->rbt, trig_name, NULL, &nmnode, NULL, 0, NULL, NULL); if (result != ISC_R_SUCCESS) { /* * Do not worry about missing summary RBT nodes that probably * correspond to RBTDB nodes that were implicit RBT nodes * that were later added for (often empty) wildcards * and then to the RBTDB deferred cleanup list. */ if (result == ISC_R_NOTFOUND || result == DNS_R_PARTIALMATCH) return; dns_name_format(src_name, namebuf, sizeof(namebuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, "rpz del_name(%s) node search failed: %s", namebuf, isc_result_totext(result)); return; } nm_data = nmnode->data; INSIST(nm_data != NULL); /* * Do not count bits that next existed for RBT nodes that would we * would not have found in a summary for a single RBTDB tree. */ del_data.set.qname &= nm_data->set.qname; del_data.set.ns &= nm_data->set.ns; del_data.wild.qname &= nm_data->wild.qname; del_data.wild.ns &= nm_data->wild.ns; nm_data->set.qname &= ~del_data.set.qname; nm_data->set.ns &= ~del_data.set.ns; nm_data->wild.qname &= ~del_data.wild.qname; nm_data->wild.ns &= ~del_data.wild.ns; if (nm_data->set.qname == 0 && nm_data->set.ns == 0 && nm_data->wild.qname == 0 && nm_data->wild.ns == 0) { result = dns_rbt_deletenode(rpzs->rbt, nmnode, ISC_FALSE); if (result != ISC_R_SUCCESS) { /* * bin/tests/system/rpz/tests.sh looks for "rpz.*failed". */ dns_name_format(src_name, namebuf, sizeof(namebuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, "rpz del_name(%s) node delete failed: %s", namebuf, isc_result_totext(result)); } } adj_trigger_cnt(rpzs, rpz_num, rpz_type, NULL, 0, ISC_FALSE); } /* * Remove an IP address from the radix tree or a name from the summary database. */ void dns_rpz_delete(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, dns_name_t *src_name) { dns_rpz_zone_t *rpz; dns_rpz_type_t rpz_type; REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones); rpz = rpzs->zones[rpz_num]; REQUIRE(rpz != NULL); rpz_type = type_from_name(rpz, src_name); LOCK(&rpzs->maint_lock); RWLOCK(&rpzs->search_lock, isc_rwlocktype_write); switch (rpz_type) { case DNS_RPZ_TYPE_QNAME: case DNS_RPZ_TYPE_NSDNAME: del_name(rpzs, rpz_num, rpz_type, src_name); break; case DNS_RPZ_TYPE_CLIENT_IP: case DNS_RPZ_TYPE_IP: case DNS_RPZ_TYPE_NSIP: del_cidr(rpzs, rpz_num, rpz_type, src_name); break; case DNS_RPZ_TYPE_BAD: break; } RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write); UNLOCK(&rpzs->maint_lock); } /* * Search the summary radix tree to get a relative owner name in a * policy zone relevant to a triggering IP address. * rpz_type and zbits limit the search for IP address netaddr * return the policy zone's number or DNS_RPZ_INVALID_NUM * ip_name is the relative owner name found and * *prefixp is its prefix length. */ dns_rpz_num_t dns_rpz_find_ip(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type, dns_rpz_zbits_t zbits, const isc_netaddr_t *netaddr, dns_name_t *ip_name, dns_rpz_prefix_t *prefixp) { dns_rpz_cidr_key_t tgt_ip; dns_rpz_addr_zbits_t tgt_set; dns_rpz_cidr_node_t *found; isc_result_t result; dns_rpz_num_t rpz_num; dns_rpz_have_t have; int i; LOCK(&rpzs->maint_lock); have = rpzs->have; UNLOCK(&rpzs->maint_lock); /* * Convert IP address to CIDR tree key. */ if (netaddr->family == AF_INET) { tgt_ip.w[0] = 0; tgt_ip.w[1] = 0; tgt_ip.w[2] = ADDR_V4MAPPED; tgt_ip.w[3] = ntohl(netaddr->type.in.s_addr); switch (rpz_type) { case DNS_RPZ_TYPE_CLIENT_IP: zbits &= have.client_ipv4; break; case DNS_RPZ_TYPE_IP: zbits &= have.ipv4; break; case DNS_RPZ_TYPE_NSIP: zbits &= have.nsipv4; break; default: INSIST(0); break; } } else if (netaddr->family == AF_INET6) { dns_rpz_cidr_key_t src_ip6; /* * Given the int aligned struct in_addr member of netaddr->type * one could cast netaddr->type.in6 to dns_rpz_cidr_key_t *, * but some people object. */ memmove(src_ip6.w, &netaddr->type.in6, sizeof(src_ip6.w)); for (i = 0; i < 4; i++) { tgt_ip.w[i] = ntohl(src_ip6.w[i]); } switch (rpz_type) { case DNS_RPZ_TYPE_CLIENT_IP: zbits &= have.client_ipv6; break; case DNS_RPZ_TYPE_IP: zbits &= have.ipv6; break; case DNS_RPZ_TYPE_NSIP: zbits &= have.nsipv6; break; default: INSIST(0); break; } } else { return (DNS_RPZ_INVALID_NUM); } if (zbits == 0) return (DNS_RPZ_INVALID_NUM); make_addr_set(&tgt_set, zbits, rpz_type); RWLOCK(&rpzs->search_lock, isc_rwlocktype_read); result = search(rpzs, &tgt_ip, 128, &tgt_set, ISC_FALSE, &found); if (result == ISC_R_NOTFOUND) { /* * There are no eligible zones for this IP address. */ RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); return (DNS_RPZ_INVALID_NUM); } /* * Construct the trigger name for the longest matching trigger * in the first eligible zone with a match. */ *prefixp = found->prefix; switch (rpz_type) { case DNS_RPZ_TYPE_CLIENT_IP: rpz_num = zbit_to_num(found->set.client_ip & tgt_set.client_ip); break; case DNS_RPZ_TYPE_IP: rpz_num = zbit_to_num(found->set.ip & tgt_set.ip); break; case DNS_RPZ_TYPE_NSIP: rpz_num = zbit_to_num(found->set.nsip & tgt_set.nsip); break; default: INSIST(0); break; } result = ip2name(&found->ip, found->prefix, dns_rootname, ip_name); RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); if (result != ISC_R_SUCCESS) { /* * bin/tests/system/rpz/tests.sh looks for "rpz.*failed". */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, "rpz ip2name() failed: %s", isc_result_totext(result)); return (DNS_RPZ_INVALID_NUM); } return (rpz_num); } /* * Search the summary radix tree for policy zones with triggers matching * a name. */ dns_rpz_zbits_t dns_rpz_find_name(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type, dns_rpz_zbits_t zbits, dns_name_t *trig_name) { char namebuf[DNS_NAME_FORMATSIZE]; dns_rbtnode_t *nmnode; const dns_rpz_nm_data_t *nm_data; dns_rpz_zbits_t found_zbits; isc_result_t result; if (zbits == 0) return (0); found_zbits = 0; RWLOCK(&rpzs->search_lock, isc_rwlocktype_read); nmnode = NULL; result = dns_rbt_findnode(rpzs->rbt, trig_name, NULL, &nmnode, NULL, DNS_RBTFIND_EMPTYDATA, NULL, NULL); switch (result) { case ISC_R_SUCCESS: nm_data = nmnode->data; if (nm_data != NULL) { if (rpz_type == DNS_RPZ_TYPE_QNAME) found_zbits = nm_data->set.qname; else found_zbits = nm_data->set.ns; } nmnode = nmnode->parent; /* fall thru */ case DNS_R_PARTIALMATCH: while (nmnode != NULL) { nm_data = nmnode->data; if (nm_data != NULL) { if (rpz_type == DNS_RPZ_TYPE_QNAME) found_zbits |= nm_data->wild.qname; else found_zbits |= nm_data->wild.ns; } nmnode = nmnode->parent; } break; case ISC_R_NOTFOUND: break; default: /* * bin/tests/system/rpz/tests.sh looks for "rpz.*failed". */ dns_name_format(trig_name, namebuf, sizeof(namebuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, "dns_rpz_find_name(%s) failed: %s", namebuf, isc_result_totext(result)); break; } RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); return (zbits & found_zbits); } /* * Translate CNAME rdata to a QNAME response policy action. */ dns_rpz_policy_t dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset, dns_name_t *selfname) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_cname_t cname; isc_result_t result; result = dns_rdataset_first(rdataset); INSIST(result == ISC_R_SUCCESS); dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &cname, NULL); INSIST(result == ISC_R_SUCCESS); dns_rdata_reset(&rdata); /* * CNAME . means NXDOMAIN */ if (dns_name_equal(&cname.cname, dns_rootname)) return (DNS_RPZ_POLICY_NXDOMAIN); if (dns_name_iswildcard(&cname.cname)) { /* * CNAME *. means NODATA */ if (dns_name_countlabels(&cname.cname) == 2) return (DNS_RPZ_POLICY_NODATA); /* * A qname of www.evil.com and a policy of * *.evil.com CNAME *.garden.net * gives a result of * evil.com CNAME evil.com.garden.net */ if (dns_name_countlabels(&cname.cname) > 2) return (DNS_RPZ_POLICY_WILDCNAME); } /* * CNAME rpz-tcp-only. means "send truncated UDP responses." */ if (dns_name_equal(&cname.cname, &rpz->tcp_only)) return (DNS_RPZ_POLICY_TCP_ONLY); /* * CNAME rpz-drop. means "do not respond." */ if (dns_name_equal(&cname.cname, &rpz->drop)) return (DNS_RPZ_POLICY_DROP); /* * CNAME rpz-passthru. means "do not rewrite." */ if (dns_name_equal(&cname.cname, &rpz->passthru)) return (DNS_RPZ_POLICY_PASSTHRU); /* * 128.1.0.127.rpz-ip CNAME 128.1.0.0.127. is obsolete PASSTHRU */ if (selfname != NULL && dns_name_equal(&cname.cname, selfname)) return (DNS_RPZ_POLICY_PASSTHRU); /* * Any other rdata gives a response consisting of the rdata. */ return (DNS_RPZ_POLICY_RECORD); } bind9-9.10.3.dfsg.P4/lib/dns/include/0002755000470500017500000000000012672612753016360 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/dns/include/dst/0002755000470500017500000000000012664710322017142 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/dns/include/dst/dst.h0000644000470500017500000006065112664710322020113 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: dst.h,v 1.34 2011/10/20 21:20:02 marka Exp $ */ #ifndef DST_DST_H #define DST_DST_H 1 /*! \file dst/dst.h */ #include #include #include #include #include #include #include #include #include ISC_LANG_BEGINDECLS /*** *** Types ***/ /*% * The dst_key structure is opaque. Applications should use the accessor * functions provided to retrieve key attributes. If an application needs * to set attributes, new accessor functions will be written. */ typedef struct dst_key dst_key_t; typedef struct dst_context dst_context_t; /* DST algorithm codes */ #define DST_ALG_UNKNOWN 0 #define DST_ALG_RSAMD5 1 #define DST_ALG_RSA DST_ALG_RSAMD5 /*%< backwards compatibility */ #define DST_ALG_DH 2 #define DST_ALG_DSA 3 #define DST_ALG_ECC 4 #define DST_ALG_RSASHA1 5 #define DST_ALG_NSEC3DSA 6 #define DST_ALG_NSEC3RSASHA1 7 #define DST_ALG_RSASHA256 8 #define DST_ALG_RSASHA512 10 #define DST_ALG_ECCGOST 12 #define DST_ALG_ECDSA256 13 #define DST_ALG_ECDSA384 14 #define DST_ALG_HMACMD5 157 #define DST_ALG_GSSAPI 160 #define DST_ALG_HMACSHA1 161 /* XXXMPA */ #define DST_ALG_HMACSHA224 162 /* XXXMPA */ #define DST_ALG_HMACSHA256 163 /* XXXMPA */ #define DST_ALG_HMACSHA384 164 /* XXXMPA */ #define DST_ALG_HMACSHA512 165 /* XXXMPA */ #define DST_ALG_INDIRECT 252 #define DST_ALG_PRIVATE 254 #define DST_ALG_EXPAND 255 #define DST_MAX_ALGS 255 /*% A buffer of this size is large enough to hold any key */ #define DST_KEY_MAXSIZE 1280 /*% * A buffer of this size is large enough to hold the textual representation * of any key */ #define DST_KEY_MAXTEXTSIZE 2048 /*% 'Type' for dst_read_key() */ #define DST_TYPE_KEY 0x1000000 /* KEY key */ #define DST_TYPE_PRIVATE 0x2000000 #define DST_TYPE_PUBLIC 0x4000000 /* Key timing metadata definitions */ #define DST_TIME_CREATED 0 #define DST_TIME_PUBLISH 1 #define DST_TIME_ACTIVATE 2 #define DST_TIME_REVOKE 3 #define DST_TIME_INACTIVE 4 #define DST_TIME_DELETE 5 #define DST_TIME_DSPUBLISH 6 #define DST_MAX_TIMES 6 /* Numeric metadata definitions */ #define DST_NUM_PREDECESSOR 0 #define DST_NUM_SUCCESSOR 1 #define DST_NUM_MAXTTL 2 #define DST_NUM_ROLLPERIOD 3 #define DST_MAX_NUMERIC 3 /* * Current format version number of the private key parser. * * When parsing a key file with the same major number but a higher minor * number, the key parser will ignore any fields it does not recognize. * Thus, DST_MINOR_VERSION should be incremented whenever new * fields are added to the private key file (such as new metadata). * * When rewriting these keys, those fields will be dropped, and the * format version set back to the current one.. * * When a key is seen with a higher major number, the key parser will * reject it as invalid. Thus, DST_MAJOR_VERSION should be incremented * and DST_MINOR_VERSION set to zero whenever there is a format change * which is not backward compatible to previous versions of the dst_key * parser, such as change in the syntax of an existing field, the removal * of a currently mandatory field, or a new field added which would * alter the functioning of the key if it were absent. */ #define DST_MAJOR_VERSION 1 #define DST_MINOR_VERSION 3 /*** *** Functions ***/ isc_result_t dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags); isc_result_t dst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx, const char *engine, unsigned int eflags); /*%< * Initializes the DST subsystem. * * Requires: * \li "mctx" is a valid memory context * \li "ectx" is a valid entropy context * * Returns: * \li ISC_R_SUCCESS * \li ISC_R_NOMEMORY * \li DST_R_NOENGINE * * Ensures: * \li DST is properly initialized. */ void dst_lib_destroy(void); /*%< * Releases all resources allocated by DST. */ isc_boolean_t dst_algorithm_supported(unsigned int alg); /*%< * Checks that a given algorithm is supported by DST. * * Returns: * \li ISC_TRUE * \li ISC_FALSE */ isc_boolean_t dst_ds_digest_supported(unsigned int digest_type); /*%< * Checks that a given digest algorithm is supported by DST. * * Returns: * \li ISC_TRUE * \li ISC_FALSE */ isc_result_t dst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp); isc_result_t dst_context_create2(dst_key_t *key, isc_mem_t *mctx, isc_logcategory_t *category, dst_context_t **dctxp); isc_result_t dst_context_create3(dst_key_t *key, isc_mem_t *mctx, isc_logcategory_t *category, isc_boolean_t useforsigning, dst_context_t **dctxp); isc_result_t dst_context_create4(dst_key_t *key, isc_mem_t *mctx, isc_logcategory_t *category, isc_boolean_t useforsigning, int maxbits, dst_context_t **dctxp); /*%< * Creates a context to be used for a sign or verify operation. * * Requires: * \li "key" is a valid key. * \li "mctx" is a valid memory context. * \li dctxp != NULL && *dctxp == NULL * * Returns: * \li ISC_R_SUCCESS * \li ISC_R_NOMEMORY * * Ensures: * \li *dctxp will contain a usable context. */ void dst_context_destroy(dst_context_t **dctxp); /*%< * Destroys all memory associated with a context. * * Requires: * \li *dctxp != NULL && *dctxp == NULL * * Ensures: * \li *dctxp == NULL */ isc_result_t dst_context_adddata(dst_context_t *dctx, const isc_region_t *data); /*%< * Incrementally adds data to the context to be used in a sign or verify * operation. * * Requires: * \li "dctx" is a valid context * \li "data" is a valid region * * Returns: * \li ISC_R_SUCCESS * \li DST_R_SIGNFAILURE * \li all other errors indicate failure */ isc_result_t dst_context_sign(dst_context_t *dctx, isc_buffer_t *sig); /*%< * Computes a signature using the data and key stored in the context. * * Requires: * \li "dctx" is a valid context. * \li "sig" is a valid buffer. * * Returns: * \li ISC_R_SUCCESS * \li DST_R_VERIFYFAILURE * \li all other errors indicate failure * * Ensures: * \li "sig" will contain the signature */ isc_result_t dst_context_verify(dst_context_t *dctx, isc_region_t *sig); isc_result_t dst_context_verify2(dst_context_t *dctx, unsigned int maxbits, isc_region_t *sig); /*%< * Verifies the signature using the data and key stored in the context. * * 'maxbits' specifies the maximum number of bits permitted in the RSA * exponent. * * Requires: * \li "dctx" is a valid context. * \li "sig" is a valid region. * * Returns: * \li ISC_R_SUCCESS * \li all other errors indicate failure * * Ensures: * \li "sig" will contain the signature */ isc_result_t dst_key_computesecret(const dst_key_t *pub, const dst_key_t *priv, isc_buffer_t *secret); /*%< * Computes a shared secret from two (Diffie-Hellman) keys. * * Requires: * \li "pub" is a valid key that can be used to derive a shared secret * \li "priv" is a valid private key that can be used to derive a shared secret * \li "secret" is a valid buffer * * Returns: * \li ISC_R_SUCCESS * \li any other result indicates failure * * Ensures: * \li If successful, secret will contain the derived shared secret. */ isc_result_t dst_key_fromfile(dns_name_t *name, dns_keytag_t id, unsigned int alg, int type, const char *directory, isc_mem_t *mctx, dst_key_t **keyp); /*%< * Reads a key from permanent storage. The key can either be a public or * private key, and is specified by name, algorithm, and id. If a private key * is specified, the public key must also be present. If directory is NULL, * the current directory is assumed. * * Requires: * \li "name" is a valid absolute dns name. * \li "id" is a valid key tag identifier. * \li "alg" is a supported key algorithm. * \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union. * DST_TYPE_KEY look for a KEY record otherwise DNSKEY * \li "mctx" is a valid memory context. * \li "keyp" is not NULL and "*keyp" is NULL. * * Returns: * \li ISC_R_SUCCESS * \li any other result indicates failure * * Ensures: * \li If successful, *keyp will contain a valid key. */ isc_result_t dst_key_fromnamedfile(const char *filename, const char *dirname, int type, isc_mem_t *mctx, dst_key_t **keyp); /*%< * Reads a key from permanent storage. The key can either be a public or * key, and is specified by filename. If a private key is specified, the * public key must also be present. * * If 'dirname' is not NULL, and 'filename' is a relative path, * then the file is looked up relative to the given directory. * If 'filename' is an absolute path, 'dirname' is ignored. * * Requires: * \li "filename" is not NULL * \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union * DST_TYPE_KEY look for a KEY record otherwise DNSKEY * \li "mctx" is a valid memory context * \li "keyp" is not NULL and "*keyp" is NULL. * * Returns: * \li ISC_R_SUCCESS * \li any other result indicates failure * * Ensures: * \li If successful, *keyp will contain a valid key. */ isc_result_t dst_key_read_public(const char *filename, int type, isc_mem_t *mctx, dst_key_t **keyp); /*%< * Reads a public key from permanent storage. The key must be a public key. * * Requires: * \li "filename" is not NULL * \li "type" is DST_TYPE_KEY look for a KEY record otherwise DNSKEY * \li "mctx" is a valid memory context * \li "keyp" is not NULL and "*keyp" is NULL. * * Returns: * \li ISC_R_SUCCESS * \li DST_R_BADKEYTYPE if the key type is not the expected one * \li ISC_R_UNEXPECTEDTOKEN if the file can not be parsed as a public key * \li any other result indicates failure * * Ensures: * \li If successful, *keyp will contain a valid key. */ isc_result_t dst_key_tofile(const dst_key_t *key, int type, const char *directory); /*%< * Writes a key to permanent storage. The key can either be a public or * private key. Public keys are written in DNS format and private keys * are written as a set of base64 encoded values. If directory is NULL, * the current directory is assumed. * * Requires: * \li "key" is a valid key. * \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union * * Returns: * \li ISC_R_SUCCESS * \li any other result indicates failure */ isc_result_t dst_key_fromdns(dns_name_t *name, dns_rdataclass_t rdclass, isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp); /*%< * Converts a DNS KEY record into a DST key. * * Requires: * \li "name" is a valid absolute dns name. * \li "source" is a valid buffer. There must be at least 4 bytes available. * \li "mctx" is a valid memory context. * \li "keyp" is not NULL and "*keyp" is NULL. * * Returns: * \li ISC_R_SUCCESS * \li any other result indicates failure * * Ensures: * \li If successful, *keyp will contain a valid key, and the consumed * pointer in data will be advanced. */ isc_result_t dst_key_todns(const dst_key_t *key, isc_buffer_t *target); /*%< * Converts a DST key into a DNS KEY record. * * Requires: * \li "key" is a valid key. * \li "target" is a valid buffer. There must be at least 4 bytes unused. * * Returns: * \li ISC_R_SUCCESS * \li any other result indicates failure * * Ensures: * \li If successful, the used pointer in 'target' is advanced by at least 4. */ isc_result_t dst_key_frombuffer(dns_name_t *name, unsigned int alg, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp); /*%< * Converts a buffer containing DNS KEY RDATA into a DST key. * * Requires: *\li "name" is a valid absolute dns name. *\li "alg" is a supported key algorithm. *\li "source" is a valid buffer. *\li "mctx" is a valid memory context. *\li "keyp" is not NULL and "*keyp" is NULL. * * Returns: *\li ISC_R_SUCCESS * \li any other result indicates failure * * Ensures: *\li If successful, *keyp will contain a valid key, and the consumed * pointer in source will be advanced. */ isc_result_t dst_key_tobuffer(const dst_key_t *key, isc_buffer_t *target); /*%< * Converts a DST key into DNS KEY RDATA format. * * Requires: *\li "key" is a valid key. *\li "target" is a valid buffer. * * Returns: *\li ISC_R_SUCCESS * \li any other result indicates failure * * Ensures: *\li If successful, the used pointer in 'target' is advanced. */ isc_result_t dst_key_privatefrombuffer(dst_key_t *key, isc_buffer_t *buffer); /*%< * Converts a public key into a private key, reading the private key * information from the buffer. The buffer should contain the same data * as the .private key file would. * * Requires: *\li "key" is a valid public key. *\li "buffer" is not NULL. * * Returns: *\li ISC_R_SUCCESS * \li any other result indicates failure * * Ensures: *\li If successful, key will contain a valid private key. */ gss_ctx_id_t dst_key_getgssctx(const dst_key_t *key); /*%< * Returns the opaque key data. * Be cautions when using this value unless you know what you are doing. * * Requires: *\li "key" is not NULL. * * Returns: *\li gssctx key data, possibly NULL. */ isc_result_t dst_key_fromgssapi(dns_name_t *name, gss_ctx_id_t gssctx, isc_mem_t *mctx, dst_key_t **keyp, isc_region_t *intoken); /*%< * Converts a GSSAPI opaque context id into a DST key. * * Requires: *\li "name" is a valid absolute dns name. *\li "gssctx" is a GSSAPI context id. *\li "mctx" is a valid memory context. *\li "keyp" is not NULL and "*keyp" is NULL. * * Returns: *\li ISC_R_SUCCESS * \li any other result indicates failure * * Ensures: *\li If successful, *keyp will contain a valid key and be responsible for * the context id. */ #ifdef DST_KEY_INTERNAL isc_result_t dst_key_buildinternal(dns_name_t *name, unsigned int alg, unsigned int bits, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, void *data, isc_mem_t *mctx, dst_key_t **keyp); #endif isc_result_t dst_key_fromlabel(dns_name_t *name, int alg, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, const char *engine, const char *label, const char *pin, isc_mem_t *mctx, dst_key_t **keyp); isc_result_t dst_key_generate(dns_name_t *name, unsigned int alg, unsigned int bits, unsigned int param, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, isc_mem_t *mctx, dst_key_t **keyp); isc_result_t dst_key_generate2(dns_name_t *name, unsigned int alg, unsigned int bits, unsigned int param, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, isc_mem_t *mctx, dst_key_t **keyp, void (*callback)(int)); /*%< * Generate a DST key (or keypair) with the supplied parameters. The * interpretation of the "param" field depends on the algorithm: * \code * RSA: exponent * 0 use exponent 3 * !0 use Fermat4 (2^16 + 1) * DH: generator * 0 default - use well known prime if bits == 768 or 1024, * otherwise use 2 as the generator. * !0 use this value as the generator. * DSA: unused * HMACMD5: entropy * 0 default - require good entropy * !0 lack of good entropy is ok *\endcode * * Requires: *\li "name" is a valid absolute dns name. *\li "keyp" is not NULL and "*keyp" is NULL. * * Returns: *\li ISC_R_SUCCESS * \li any other result indicates failure * * Ensures: *\li If successful, *keyp will contain a valid key. */ isc_boolean_t dst_key_compare(const dst_key_t *key1, const dst_key_t *key2); /*%< * Compares two DST keys. Returns true if they match, false otherwise. * * Keys ARE NOT considered to match if one of them is the revoked version * of the other. * * Requires: *\li "key1" is a valid key. *\li "key2" is a valid key. * * Returns: *\li ISC_TRUE * \li ISC_FALSE */ isc_boolean_t dst_key_pubcompare(const dst_key_t *key1, const dst_key_t *key2, isc_boolean_t match_revoked_key); /*%< * Compares only the public portions of two DST keys. Returns true * if they match, false otherwise. This allows us, for example, to * determine whether a public key found in a zone matches up with a * key pair found on disk. * * If match_revoked_key is TRUE, then keys ARE considered to match if one * of them is the revoked version of the other. Otherwise, they are not. * * Requires: *\li "key1" is a valid key. *\li "key2" is a valid key. * * Returns: *\li ISC_TRUE * \li ISC_FALSE */ isc_boolean_t dst_key_paramcompare(const dst_key_t *key1, const dst_key_t *key2); /*%< * Compares the parameters of two DST keys. This is used to determine if * two (Diffie-Hellman) keys can be used to derive a shared secret. * * Requires: *\li "key1" is a valid key. *\li "key2" is a valid key. * * Returns: *\li ISC_TRUE * \li ISC_FALSE */ void dst_key_attach(dst_key_t *source, dst_key_t **target); /* * Attach to a existing key increasing the reference count. * * Requires: *\li 'source' to be a valid key. *\li 'target' to be non-NULL and '*target' to be NULL. */ void dst_key_free(dst_key_t **keyp); /*%< * Decrement the key's reference counter and, when it reaches zero, * release all memory associated with the key. * * Requires: *\li "keyp" is not NULL and "*keyp" is a valid key. *\li reference counter greater than zero. * * Ensures: *\li All memory associated with "*keyp" will be freed. *\li *keyp == NULL */ /*%< * Accessor functions to obtain key fields. * * Require: *\li "key" is a valid key. */ dns_name_t * dst_key_name(const dst_key_t *key); unsigned int dst_key_size(const dst_key_t *key); unsigned int dst_key_proto(const dst_key_t *key); unsigned int dst_key_alg(const dst_key_t *key); isc_uint32_t dst_key_flags(const dst_key_t *key); dns_keytag_t dst_key_id(const dst_key_t *key); dns_keytag_t dst_key_rid(const dst_key_t *key); dns_rdataclass_t dst_key_class(const dst_key_t *key); isc_boolean_t dst_key_isprivate(const dst_key_t *key); isc_boolean_t dst_key_iszonekey(const dst_key_t *key); isc_boolean_t dst_key_isnullkey(const dst_key_t *key); isc_result_t dst_key_buildfilename(const dst_key_t *key, int type, const char *directory, isc_buffer_t *out); /*%< * Generates the filename used by dst to store the specified key. * If directory is NULL, the current directory is assumed. * * Requires: *\li "key" is a valid key *\li "type" is either DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or 0 for no suffix. *\li "out" is a valid buffer * * Ensures: *\li the file name will be written to "out", and the used pointer will * be advanced. */ isc_result_t dst_key_sigsize(const dst_key_t *key, unsigned int *n); /*%< * Computes the size of a signature generated by the given key. * * Requires: *\li "key" is a valid key. *\li "n" is not NULL * * Returns: *\li #ISC_R_SUCCESS *\li DST_R_UNSUPPORTEDALG * * Ensures: *\li "n" stores the size of a generated signature */ isc_result_t dst_key_secretsize(const dst_key_t *key, unsigned int *n); /*%< * Computes the size of a shared secret generated by the given key. * * Requires: *\li "key" is a valid key. *\li "n" is not NULL * * Returns: *\li #ISC_R_SUCCESS *\li DST_R_UNSUPPORTEDALG * * Ensures: *\li "n" stores the size of a generated shared secret */ isc_uint16_t dst_region_computeid(const isc_region_t *source, unsigned int alg); isc_uint16_t dst_region_computerid(const isc_region_t *source, unsigned int alg); /*%< * Computes the (revoked) key id of the key stored in the provided * region with the given algorithm. * * Requires: *\li "source" contains a valid, non-NULL region. * * Returns: *\li the key id */ isc_uint16_t dst_key_getbits(const dst_key_t *key); /*%< * Get the number of digest bits required (0 == MAX). * * Requires: * "key" is a valid key. */ void dst_key_setbits(dst_key_t *key, isc_uint16_t bits); /*%< * Set the number of digest bits required (0 == MAX). * * Requires: * "key" is a valid key. */ void dst_key_setttl(dst_key_t *key, dns_ttl_t ttl); /*%< * Set the default TTL to use when converting the key * to a KEY or DNSKEY RR. * * Requires: * "key" is a valid key. */ dns_ttl_t dst_key_getttl(const dst_key_t *key); /*%< * Get the default TTL to use when converting the key * to a KEY or DNSKEY RR. * * Requires: * "key" is a valid key. */ isc_result_t dst_key_setflags(dst_key_t *key, isc_uint32_t flags); /* * Set the key flags, and recompute the key ID. * * Requires: * "key" is a valid key. */ isc_result_t dst_key_getnum(const dst_key_t *key, int type, isc_uint32_t *valuep); /*%< * Get a member of the numeric metadata array and place it in '*valuep'. * * Requires: * "key" is a valid key. * "type" is no larger than DST_MAX_NUMERIC * "timep" is not null. */ void dst_key_setnum(dst_key_t *key, int type, isc_uint32_t value); /*%< * Set a member of the numeric metadata array. * * Requires: * "key" is a valid key. * "type" is no larger than DST_MAX_NUMERIC */ void dst_key_unsetnum(dst_key_t *key, int type); /*%< * Flag a member of the numeric metadata array as "not set". * * Requires: * "key" is a valid key. * "type" is no larger than DST_MAX_NUMERIC */ isc_result_t dst_key_gettime(const dst_key_t *key, int type, isc_stdtime_t *timep); /*%< * Get a member of the timing metadata array and place it in '*timep'. * * Requires: * "key" is a valid key. * "type" is no larger than DST_MAX_TIMES * "timep" is not null. */ void dst_key_settime(dst_key_t *key, int type, isc_stdtime_t when); /*%< * Set a member of the timing metadata array. * * Requires: * "key" is a valid key. * "type" is no larger than DST_MAX_TIMES */ void dst_key_unsettime(dst_key_t *key, int type); /*%< * Flag a member of the timing metadata array as "not set". * * Requires: * "key" is a valid key. * "type" is no larger than DST_MAX_TIMES */ isc_result_t dst_key_getprivateformat(const dst_key_t *key, int *majorp, int *minorp); /*%< * Get the private key format version number. (If the key does not have * a private key associated with it, the version will be 0.0.) The major * version number is placed in '*majorp', and the minor version number in * '*minorp'. * * Requires: * "key" is a valid key. * "majorp" is not NULL. * "minorp" is not NULL. */ void dst_key_setprivateformat(dst_key_t *key, int major, int minor); /*%< * Set the private key format version number. * * Requires: * "key" is a valid key. */ #define DST_KEY_FORMATSIZE (DNS_NAME_FORMATSIZE + DNS_SECALG_FORMATSIZE + 7) void dst_key_format(const dst_key_t *key, char *cp, unsigned int size); /*%< * Write the uniquely identifying information about the key (name, * algorithm, key ID) into a string 'cp' of size 'size'. */ isc_buffer_t * dst_key_tkeytoken(const dst_key_t *key); /*%< * Return the token from the TKEY request, if any. If this key was * not negotiated via TKEY, return NULL. * * Requires: * "key" is a valid key. */ isc_result_t dst_key_dump(dst_key_t *key, isc_mem_t *mctx, char **buffer, int *length); /*%< * Allocate 'buffer' and dump the key into it in base64 format. The buffer * is not NUL terminated. The length of the buffer is returned in *length. * * 'buffer' needs to be freed using isc_mem_put(mctx, buffer, length); * * Requires: * 'buffer' to be non NULL and *buffer to be NULL. * 'length' to be non NULL and *length to be zero. * * Returns: * ISC_R_SUCCESS * ISC_R_NOMEMORY * ISC_R_NOTIMPLEMENTED * others. */ isc_result_t dst_key_restore(dns_name_t *name, unsigned int alg, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, isc_mem_t *mctx, const char *keystr, dst_key_t **keyp); isc_boolean_t dst_key_inactive(const dst_key_t *key); /*%< * Determines if the private key is missing due the key being deemed inactive. * * Requires: * 'key' to be valid. */ void dst_key_setinactive(dst_key_t *key, isc_boolean_t inactive); /*%< * Set key inactive state. * * Requires: * 'key' to be valid. */ void dst_key_setexternal(dst_key_t *key, isc_boolean_t value); isc_boolean_t dst_key_isexternal(dst_key_t *key); ISC_LANG_ENDDECLS #endif /* DST_DST_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dst/Makefile.in0000644000470500017500000000235412664710322021211 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.4 2007/12/11 20:28:55 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ HEADERS = dst.h gssapi.h lib.h result.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/dst install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/dst ; \ done bind9-9.10.3.dfsg.P4/lib/dns/include/dst/lib.h0000644000470500017500000000240012664710322020053 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lib.h,v 1.7 2007/06/19 23:47:17 tbox Exp $ */ #ifndef DST_LIB_H #define DST_LIB_H 1 /*! \file dst/lib.h */ #include #include ISC_LANG_BEGINDECLS LIBDNS_EXTERNAL_DATA extern isc_msgcat_t *dst_msgcat; void dst_lib_initmsgcat(void); /* * Initialize the DST library's message catalog, dst_msgcat, if it * has not already been initialized. */ ISC_LANG_ENDDECLS #endif /* DST_LIB_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dst/result.h0000644000470500017500000000516312664710322020634 0ustar lamontlamont/* * Copyright (C) 2004-2008, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: result.h,v 1.9 2008/04/01 23:47:10 tbox Exp $ */ #ifndef DST_RESULT_H #define DST_RESULT_H 1 /*! \file dst/result.h */ #include #include /* * Nothing in this file truly depends on , but the * DST result codes are considered to be publicly derived from * the ISC result codes, so including this file buys you the ISC_R_ * namespace too. */ #include /* Contractual promise. */ #define DST_R_UNSUPPORTEDALG (ISC_RESULTCLASS_DST + 0) #define DST_R_CRYPTOFAILURE (ISC_RESULTCLASS_DST + 1) /* compat */ #define DST_R_OPENSSLFAILURE DST_R_CRYPTOFAILURE #define DST_R_NOCRYPTO (ISC_RESULTCLASS_DST + 2) #define DST_R_NULLKEY (ISC_RESULTCLASS_DST + 3) #define DST_R_INVALIDPUBLICKEY (ISC_RESULTCLASS_DST + 4) #define DST_R_INVALIDPRIVATEKEY (ISC_RESULTCLASS_DST + 5) /* 6 is unused */ #define DST_R_WRITEERROR (ISC_RESULTCLASS_DST + 7) #define DST_R_INVALIDPARAM (ISC_RESULTCLASS_DST + 8) /* 9 is unused */ /* 10 is unused */ #define DST_R_SIGNFAILURE (ISC_RESULTCLASS_DST + 11) /* 12 is unused */ /* 13 is unused */ #define DST_R_VERIFYFAILURE (ISC_RESULTCLASS_DST + 14) #define DST_R_NOTPUBLICKEY (ISC_RESULTCLASS_DST + 15) #define DST_R_NOTPRIVATEKEY (ISC_RESULTCLASS_DST + 16) #define DST_R_KEYCANNOTCOMPUTESECRET (ISC_RESULTCLASS_DST + 17) #define DST_R_COMPUTESECRETFAILURE (ISC_RESULTCLASS_DST + 18) #define DST_R_NORANDOMNESS (ISC_RESULTCLASS_DST + 19) #define DST_R_BADKEYTYPE (ISC_RESULTCLASS_DST + 20) #define DST_R_NOENGINE (ISC_RESULTCLASS_DST + 21) #define DST_R_EXTERNALKEY (ISC_RESULTCLASS_DST + 22) #define DST_R_NRESULTS 23 /* Number of results */ ISC_LANG_BEGINDECLS const char * dst_result_totext(isc_result_t); void dst_result_register(void); ISC_LANG_ENDDECLS #endif /* DST_RESULT_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dst/gssapi.h0000644000470500017500000001427312664710322020606 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009-2011, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: gssapi.h,v 1.16 2011/01/08 23:47:01 tbox Exp $ */ #ifndef DST_GSSAPI_H #define DST_GSSAPI_H 1 /*! \file dst/gssapi.h */ #include #include #include #include #include #ifdef GSSAPI #ifdef WIN32 /* * MSVC does not like macros in #include lines. */ #include #include #else #include ISC_PLATFORM_GSSAPIHEADER #ifdef ISC_PLATFORM_GSSAPI_KRB5_HEADER #include ISC_PLATFORM_GSSAPI_KRB5_HEADER #endif #endif #ifndef GSS_SPNEGO_MECHANISM #define GSS_SPNEGO_MECHANISM ((void*)0) #endif #endif ISC_LANG_BEGINDECLS /*** *** Types ***/ /*** *** Functions ***/ isc_result_t dst_gssapi_acquirecred(dns_name_t *name, isc_boolean_t initiate, gss_cred_id_t *cred); /* * Acquires GSS credentials. * * Requires: * 'name' is a valid name, preferably one known by the GSS provider * 'initiate' indicates whether the credentials are for initiating or * accepting contexts * 'cred' is a pointer to NULL, which will be allocated with the * credential handle. Call dst_gssapi_releasecred to free * the memory. * * Returns: * ISC_R_SUCCESS msg was successfully updated to include the * query to be sent * other an error occurred while building the message */ isc_result_t dst_gssapi_releasecred(gss_cred_id_t *cred); /* * Releases GSS credentials. Calling this function does release the * memory allocated for the credential in dst_gssapi_acquirecred() * * Requires: * 'mctx' is a valid memory context * 'cred' is a pointer to the credential to be released * * Returns: * ISC_R_SUCCESS credential was released successfully * other an error occurred while releaseing * the credential */ isc_result_t dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken, isc_buffer_t *outtoken, gss_ctx_id_t *gssctx, isc_mem_t *mctx, char **err_message); /* * Initiates a GSS context. * * Requires: * 'name' is a valid name, preferably one known by the GSS * provider * 'intoken' is a token received from the acceptor, or NULL if * there isn't one * 'outtoken' is a buffer to receive the token generated by * gss_init_sec_context() to be sent to the acceptor * 'context' is a pointer to a valid gss_ctx_id_t * (which may have the value GSS_C_NO_CONTEXT) * * Returns: * ISC_R_SUCCESS msg was successfully updated to include the * query to be sent * other an error occurred while building the message * *err_message optional error message */ isc_result_t dst_gssapi_acceptctx(gss_cred_id_t cred, const char *gssapi_keytab, isc_region_t *intoken, isc_buffer_t **outtoken, gss_ctx_id_t *context, dns_name_t *principal, isc_mem_t *mctx); /* * Accepts a GSS context. * * Requires: * 'mctx' is a valid memory context * 'cred' is the acceptor's valid GSS credential handle * 'intoken' is a token received from the initiator * 'outtoken' is a pointer a buffer pointer used to return the token * generated by gss_accept_sec_context() to be sent to the * initiator * 'context' is a valid pointer to receive the generated context handle. * On the initial call, it should be a pointer to NULL, which * will be allocated as a gss_ctx_id_t. Subsequent calls * should pass in the handle generated on the first call. * Call dst_gssapi_releasecred to delete the context and free * the memory. * * Requires: * 'outtoken' to != NULL && *outtoken == NULL. * * Returns: * ISC_R_SUCCESS msg was successfully updated to include the * query to be sent * other an error occurred while building the message */ isc_result_t dst_gssapi_deletectx(isc_mem_t *mctx, gss_ctx_id_t *gssctx); /* * Destroys a GSS context. This function deletes the context from the GSS * provider and then frees the memory used by the context pointer. * * Requires: * 'mctx' is a valid memory context * 'context' is a valid GSS context * * Returns: * ISC_R_SUCCESS */ void gss_log(int level, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3); /* * Logging function for GSS. * * Requires * 'level' is the log level to be used, as an integer * 'fmt' is a printf format specifier */ char * gss_error_tostring(isc_uint32_t major, isc_uint32_t minor, char *buf, size_t buflen); /* * Render a GSS major status/minor status pair into a string * * Requires: * 'major' is a GSS major status code * 'minor' is a GSS minor status code * * Returns: * A string containing the text representation of the error codes. * Users should copy the string if they wish to keep it. */ isc_boolean_t dst_gssapi_identitymatchesrealmkrb5(dns_name_t *signer, dns_name_t *name, dns_name_t *realm); /* * Compare a "signer" (in the format of a Kerberos-format Kerberos5 * principal: host/example.com@EXAMPLE.COM) to the realm name stored * in "name" (which represents the realm name). * */ isc_boolean_t dst_gssapi_identitymatchesrealmms(dns_name_t *signer, dns_name_t *name, dns_name_t *realm); /* * Compare a "signer" (in the format of a Kerberos-format Kerberos5 * principal: host/example.com@EXAMPLE.COM) to the realm name stored * in "name" (which represents the realm name). * */ ISC_LANG_ENDDECLS #endif /* DST_GSSAPI_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/Makefile.in0000644000470500017500000000176212664710322020421 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.15 2007/06/19 23:47:16 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = dns dst TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/0002755000470500017500000000000012672612753017144 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/dns/include/dns/db.h0000644000470500017500000012555112664710322017701 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef DNS_DB_H #define DNS_DB_H 1 /***** ***** Module Info *****/ /*! \file dns/db.h * \brief * The DNS DB interface allows named rdatasets to be stored and retrieved. * * The dns_db_t type is like a "virtual class". To actually use * DBs, an implementation of the class is required. * * XXX more XXX * * MP: * \li The module ensures appropriate synchronization of data structures it * creates and manipulates. * * Reliability: * \li No anticipated impact. * * Resources: * \li TBS * * Security: * \li No anticipated impact. * * Standards: * \li None. */ /***** ***** Imports *****/ #include #include #include #include #include #include #include #include #include #include #include #include ISC_LANG_BEGINDECLS /***** ***** Types *****/ typedef struct dns_dbmethods { void (*attach)(dns_db_t *source, dns_db_t **targetp); void (*detach)(dns_db_t **dbp); isc_result_t (*beginload)(dns_db_t *db, dns_rdatacallbacks_t *callbacks); isc_result_t (*endload)(dns_db_t *db, dns_rdatacallbacks_t *callbacks); isc_result_t (*serialize)(dns_db_t *db, dns_dbversion_t *version, FILE *file); isc_result_t (*dump)(dns_db_t *db, dns_dbversion_t *version, const char *filename, dns_masterformat_t masterformat); void (*currentversion)(dns_db_t *db, dns_dbversion_t **versionp); isc_result_t (*newversion)(dns_db_t *db, dns_dbversion_t **versionp); void (*attachversion)(dns_db_t *db, dns_dbversion_t *source, dns_dbversion_t **targetp); void (*closeversion)(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit); isc_result_t (*findnode)(dns_db_t *db, dns_name_t *name, isc_boolean_t create, dns_dbnode_t **nodep); isc_result_t (*find)(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); isc_result_t (*findzonecut)(dns_db_t *db, dns_name_t *name, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); void (*attachnode)(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp); void (*detachnode)(dns_db_t *db, dns_dbnode_t **targetp); isc_result_t (*expirenode)(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now); void (*printnode)(dns_db_t *db, dns_dbnode_t *node, FILE *out); isc_result_t (*createiterator)(dns_db_t *db, unsigned int options, dns_dbiterator_t **iteratorp); isc_result_t (*findrdataset)(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdatatype_t type, dns_rdatatype_t covers, isc_stdtime_t now, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); isc_result_t (*allrdatasets)(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_stdtime_t now, dns_rdatasetiter_t **iteratorp); isc_result_t (*addrdataset)(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options, dns_rdataset_t *addedrdataset); isc_result_t (*subtractrdataset)(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdataset_t *rdataset, unsigned int options, dns_rdataset_t *newrdataset); isc_result_t (*deleterdataset)(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdatatype_t type, dns_rdatatype_t covers); isc_boolean_t (*issecure)(dns_db_t *db); unsigned int (*nodecount)(dns_db_t *db); isc_boolean_t (*ispersistent)(dns_db_t *db); void (*overmem)(dns_db_t *db, isc_boolean_t overmem); void (*settask)(dns_db_t *db, isc_task_t *); isc_result_t (*getoriginnode)(dns_db_t *db, dns_dbnode_t **nodep); void (*transfernode)(dns_db_t *db, dns_dbnode_t **sourcep, dns_dbnode_t **targetp); isc_result_t (*getnsec3parameters)(dns_db_t *db, dns_dbversion_t *version, dns_hash_t *hash, isc_uint8_t *flags, isc_uint16_t *iterations, unsigned char *salt, size_t *salt_len); isc_result_t (*findnsec3node)(dns_db_t *db, dns_name_t *name, isc_boolean_t create, dns_dbnode_t **nodep); isc_result_t (*setsigningtime)(dns_db_t *db, dns_rdataset_t *rdataset, isc_stdtime_t resign); isc_result_t (*getsigningtime)(dns_db_t *db, dns_rdataset_t *rdataset, dns_name_t *name); void (*resigned)(dns_db_t *db, dns_rdataset_t *rdataset, dns_dbversion_t *version); isc_boolean_t (*isdnssec)(dns_db_t *db); dns_stats_t *(*getrrsetstats)(dns_db_t *db); void (*rpz_attach)(dns_db_t *db, dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num); isc_result_t (*rpz_ready)(dns_db_t *db); isc_result_t (*findnodeext)(dns_db_t *db, dns_name_t *name, isc_boolean_t create, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep); isc_result_t (*findext)(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); isc_result_t (*setcachestats)(dns_db_t *db, isc_stats_t *stats); unsigned int (*hashsize)(dns_db_t *db); } dns_dbmethods_t; typedef isc_result_t (*dns_dbcreatefunc_t)(isc_mem_t *mctx, dns_name_t *name, dns_dbtype_t type, dns_rdataclass_t rdclass, unsigned int argc, char *argv[], void *driverarg, dns_db_t **dbp); #define DNS_DB_MAGIC ISC_MAGIC('D','N','S','D') #define DNS_DB_VALID(db) ISC_MAGIC_VALID(db, DNS_DB_MAGIC) /*% * This structure is actually just the common prefix of a DNS db * implementation's version of a dns_db_t. * \brief * Direct use of this structure by clients is forbidden. DB implementations * may change the structure. 'magic' must be DNS_DB_MAGIC for any of the * dns_db_ routines to work. DB implementations must maintain all DB * invariants. */ struct dns_db { unsigned int magic; unsigned int impmagic; dns_dbmethods_t * methods; isc_uint16_t attributes; dns_rdataclass_t rdclass; dns_name_t origin; isc_ondestroy_t ondest; isc_mem_t * mctx; }; #define DNS_DBATTR_CACHE 0x01 #define DNS_DBATTR_STUB 0x02 /*@{*/ /*% * Options that can be specified for dns_db_find(). */ #define DNS_DBFIND_GLUEOK 0x0001 #define DNS_DBFIND_VALIDATEGLUE 0x0002 #define DNS_DBFIND_NOWILD 0x0004 #define DNS_DBFIND_PENDINGOK 0x0008 #define DNS_DBFIND_NOEXACT 0x0010 #define DNS_DBFIND_FORCENSEC 0x0020 #define DNS_DBFIND_COVERINGNSEC 0x0040 #define DNS_DBFIND_FORCENSEC3 0x0080 #define DNS_DBFIND_ADDITIONALOK 0x0100 /*@}*/ /*@{*/ /*% * Options that can be specified for dns_db_addrdataset(). */ #define DNS_DBADD_MERGE 0x01 #define DNS_DBADD_FORCE 0x02 #define DNS_DBADD_EXACT 0x04 #define DNS_DBADD_EXACTTTL 0x08 #define DNS_DBADD_PREFETCH 0x10 /*@}*/ /*% * Options that can be specified for dns_db_subtractrdataset(). */ #define DNS_DBSUB_EXACT 0x01 /*@{*/ /*% * Iterator options */ #define DNS_DB_RELATIVENAMES 0x1 #define DNS_DB_NSEC3ONLY 0x2 #define DNS_DB_NONSEC3 0x4 /*@}*/ /***** ***** Methods *****/ /*** *** Basic DB Methods ***/ isc_result_t dns_db_create(isc_mem_t *mctx, const char *db_type, dns_name_t *origin, dns_dbtype_t type, dns_rdataclass_t rdclass, unsigned int argc, char *argv[], dns_db_t **dbp); /*%< * Create a new database using implementation 'db_type'. * * Notes: * \li All names in the database must be subdomains of 'origin' and in class * 'rdclass'. The database makes its own copy of the origin, so the * caller may do whatever they like with 'origin' and its storage once the * call returns. * * \li DB implementation-specific parameters are passed using argc and argv. * * Requires: * * \li dbp != NULL and *dbp == NULL * * \li 'origin' is a valid absolute domain name. * * \li mctx is a valid memory context * * Ensures: * * \li A copy of 'origin' has been made for the databases use, and the * caller is free to do whatever they want with the name and storage * associated with 'origin'. * * Returns: * * \li #ISC_R_SUCCESS * \li #ISC_R_NOMEMORY * \li #ISC_R_NOTFOUND db_type not found * * \li Many other errors are possible, depending on what db_type was * specified. */ void dns_db_attach(dns_db_t *source, dns_db_t **targetp); /*%< * Attach *targetp to source. * * Requires: * * \li 'source' is a valid database. * * \li 'targetp' points to a NULL dns_db_t *. * * Ensures: * * \li *targetp is attached to source. */ void dns_db_detach(dns_db_t **dbp); /*%< * Detach *dbp from its database. * * Requires: * * \li 'dbp' points to a valid database. * * Ensures: * * \li *dbp is NULL. * * \li If '*dbp' is the last reference to the database, * all resources used by the database will be freed */ isc_result_t dns_db_ondestroy(dns_db_t *db, isc_task_t *task, isc_event_t **eventp); /*%< * Causes 'eventp' to be sent to be sent to 'task' when the database is * destroyed. * * Note; ownership of the eventp is taken from the caller (and *eventp is * set to NULL). The sender field of the event is set to 'db' before it is * sent to the task. */ isc_boolean_t dns_db_iscache(dns_db_t *db); /*%< * Does 'db' have cache semantics? * * Requires: * * \li 'db' is a valid database. * * Returns: * \li #ISC_TRUE 'db' has cache semantics * \li #ISC_FALSE otherwise */ isc_boolean_t dns_db_iszone(dns_db_t *db); /*%< * Does 'db' have zone semantics? * * Requires: * * \li 'db' is a valid database. * * Returns: * \li #ISC_TRUE 'db' has zone semantics * \li #ISC_FALSE otherwise */ isc_boolean_t dns_db_isstub(dns_db_t *db); /*%< * Does 'db' have stub semantics? * * Requires: * * \li 'db' is a valid database. * * Returns: * \li #ISC_TRUE 'db' has zone semantics * \li #ISC_FALSE otherwise */ isc_boolean_t dns_db_issecure(dns_db_t *db); /*%< * Is 'db' secure? * * Requires: * * \li 'db' is a valid database with zone semantics. * * Returns: * \li #ISC_TRUE 'db' is secure. * \li #ISC_FALSE 'db' is not secure. */ isc_boolean_t dns_db_isdnssec(dns_db_t *db); /*%< * Is 'db' secure or partially secure? * * Requires: * * \li 'db' is a valid database with zone semantics. * * Returns: * \li #ISC_TRUE 'db' is secure or is partially. * \li #ISC_FALSE 'db' is not secure. */ dns_name_t * dns_db_origin(dns_db_t *db); /*%< * The origin of the database. * * Note: caller must not try to change this name. * * Requires: * * \li 'db' is a valid database. * * Returns: * * \li The origin of the database. */ dns_rdataclass_t dns_db_class(dns_db_t *db); /*%< * The class of the database. * * Requires: * * \li 'db' is a valid database. * * Returns: * * \li The class of the database. */ isc_result_t dns_db_beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks); /*%< * Begin loading 'db'. * * Requires: * * \li 'db' is a valid database. * * \li This is the first attempt to load 'db'. * * \li 'callbacks' is a pointer to an initialized dns_rdatacallbacks_t * structure. * * Ensures: * * \li On success, callbacks->add will be a valid dns_addrdatasetfunc_t * suitable for loading records into 'db' from a raw or text zone * file. callbacks->add_private will be a valid DB load context * which should be used as 'arg' when callbacks->add is called. * callbacks->deserialize will be a valid dns_deserialize_func_t * suitable for loading 'db' from a map format zone file. * * Returns: * * \li #ISC_R_SUCCESS * \li #ISC_R_NOMEMORY * * \li Other results are possible, depending upon the database * implementation used, syntax errors in the master file, etc. */ isc_result_t dns_db_endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks); /*%< * Finish loading 'db'. * * Requires: * * \li 'db' is a valid database that is being loaded. * * \li 'callbacks' is a valid dns_rdatacallbacks_t structure. * * \li callbacks->add_private is not NULL and is a valid database load context. * * Ensures: * * \li 'callbacks' is returned to its state prior to calling dns_db_beginload() * * Returns: * * \li #ISC_R_SUCCESS * \li #ISC_R_NOMEMORY * * \li Other results are possible, depending upon the database * implementation used, syntax errors in the master file, etc. */ isc_result_t dns_db_load(dns_db_t *db, const char *filename); isc_result_t dns_db_load2(dns_db_t *db, const char *filename, dns_masterformat_t format); isc_result_t dns_db_load3(dns_db_t *db, const char *filename, dns_masterformat_t format, unsigned int options); /*%< * Load master file 'filename' into 'db'. * * Notes: * \li This routine is equivalent to calling * *\code * dns_db_beginload(); * dns_master_loadfile(); * dns_db_endload(); *\endcode * * Requires: * * \li 'db' is a valid database. * * \li This is the first attempt to load 'db'. * * Returns: * * \li #ISC_R_SUCCESS * \li #ISC_R_NOMEMORY * * \li Other results are possible, depending upon the database * implementation used, syntax errors in the master file, etc. */ isc_result_t dns_db_serialize(dns_db_t *db, dns_dbversion_t *version, FILE *rbtfile); /*%< * Dump version 'version' of 'db' to map-format file 'filename'. * * Requires: * * \li 'db' is a valid database. * * \li 'version' is a valid version. * * Returns: * * \li #ISC_R_SUCCESS * \li #ISC_R_NOMEMORY * * \li Other results are possible, depending upon the database * implementation used, OS file errors, etc. */ isc_result_t dns_db_dump(dns_db_t *db, dns_dbversion_t *version, const char *filename); isc_result_t dns_db_dump2(dns_db_t *db, dns_dbversion_t *version, const char *filename, dns_masterformat_t masterformat); /*%< * Dump version 'version' of 'db' to master file 'filename'. * * Requires: * * \li 'db' is a valid database. * * \li 'version' is a valid version. * * Returns: * * \li #ISC_R_SUCCESS * \li #ISC_R_NOMEMORY * * \li Other results are possible, depending upon the database * implementation used, OS file errors, etc. */ /*** *** Version Methods ***/ void dns_db_currentversion(dns_db_t *db, dns_dbversion_t **versionp); /*%< * Open the current version for reading. * * Requires: * * \li 'db' is a valid database with zone semantics. * * \li versionp != NULL && *verisonp == NULL * * Ensures: * * \li On success, '*versionp' is attached to the current version. * */ isc_result_t dns_db_newversion(dns_db_t *db, dns_dbversion_t **versionp); /*%< * Open a new version for reading and writing. * * Requires: * * \li 'db' is a valid database with zone semantics. * * \li versionp != NULL && *verisonp == NULL * * Ensures: * * \li On success, '*versionp' is attached to the current version. * * Returns: * * \li #ISC_R_SUCCESS * \li #ISC_R_NOMEMORY * * \li Other results are possible, depending upon the database * implementation used. */ void dns_db_attachversion(dns_db_t *db, dns_dbversion_t *source, dns_dbversion_t **targetp); /*%< * Attach '*targetp' to 'source'. * * Requires: * * \li 'db' is a valid database with zone semantics. * * \li source is a valid open version * * \li targetp != NULL && *targetp == NULL * * Ensures: * * \li '*targetp' is attached to source. */ void dns_db_closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit); /*%< * Close version '*versionp'. * * Note: if '*versionp' is a read-write version and 'commit' is ISC_TRUE, * then all changes made in the version will take effect, otherwise they * will be rolled back. The value of 'commit' is ignored for read-only * versions. * * Requires: * * \li 'db' is a valid database with zone semantics. * * \li '*versionp' refers to a valid version. * * \li If committing a writable version, then there must be no other * outstanding references to the version (e.g. an active rdataset * iterator). * * Ensures: * * \li *versionp == NULL * * \li If *versionp is a read-write version, and commit is ISC_TRUE, then * the version will become the current version. If !commit, then all * changes made in the version will be undone, and the version will * not become the current version. */ /*** *** Node Methods ***/ isc_result_t dns_db_findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, dns_dbnode_t **nodep); isc_result_t dns_db_findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep); /*%< * Find the node with name 'name'. * * dns_db_findnodeext() (findnode extended) also accepts parameters * 'methods' and 'clientinfo', which, when provided, enable the database to * retreive information about the client from the caller, and modify its * response on the basis of that information. * * Notes: * \li If 'create' is ISC_TRUE and no node with name 'name' exists, then * such a node will be created. * * \li This routine is for finding or creating a node with the specified * name. There are no partial matches. It is not suitable for use * in building responses to ordinary DNS queries; clients which wish * to do that should use dns_db_find() instead. * * Requires: * * \li 'db' is a valid database. * * \li 'name' is a valid, non-empty, absolute name. * * \li nodep != NULL && *nodep == NULL * * Ensures: * * \li On success, *nodep is attached to the node with name 'name'. * * Returns: * * \li #ISC_R_SUCCESS * \li #ISC_R_NOTFOUND If !create and name not found. * \li #ISC_R_NOMEMORY Can only happen if create is ISC_TRUE. * * \li Other results are possible, depending upon the database * implementation used. */ isc_result_t dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); isc_result_t dns_db_findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); /*%< * Find the best match for 'name' and 'type' in version 'version' of 'db'. * * dns_db_findext() (find extended) also accepts parameters 'methods' * and 'clientinfo', which when provided enable the database to retreive * information about the client from the caller, and modify its response * on the basis of this information. * * Notes: * * \li If type == dns_rdataset_any, then rdataset will not be bound. * * \li If 'options' does not have #DNS_DBFIND_GLUEOK set, then no glue will * be returned. For zone databases, glue is as defined in RFC2181. * For cache databases, glue is any rdataset with a trust of * dns_trust_glue. * * \li If 'options' does not have #DNS_DBFIND_ADDITIONALOK set, then no * additional records will be returned. Only caches can have * rdataset with trust dns_trust_additional. * * \li If 'options' does not have #DNS_DBFIND_PENDINGOK set, then no * pending data will be returned. This option is only meaningful for * cache databases. * * \li If the #DNS_DBFIND_NOWILD option is set, then wildcard matching will * be disabled. This option is only meaningful for zone databases. * * \li If the #DNS_DBFIND_FORCENSEC option is set, the database is assumed to * have NSEC records, and these will be returned when appropriate. This * is only necessary when querying a database that was not secure * when created. * * \li If the DNS_DBFIND_COVERINGNSEC option is set, then look for a * NSEC record that potentially covers 'name' if a answer cannot * be found. Note the returned NSEC needs to be checked to ensure * that it is correct. This only affects answers returned from the * cache. * * \li In the #DNS_DBFIND_FORCENSEC3 option is set, then we are looking * in the NSEC3 tree and not the main tree. Without this option being * set NSEC3 records will not be found. * * \li To respond to a query for SIG records, the caller should create a * rdataset iterator and extract the signatures from each rdataset. * * \li Making queries of type ANY with #DNS_DBFIND_GLUEOK is not recommended, * because the burden of determining whether a given rdataset is valid * glue or not falls upon the caller. * * \li The 'now' field is ignored if 'db' is a zone database. If 'db' is a * cache database, an rdataset will not be found unless it expires after * 'now'. Any ANY query will not match unless at least one rdataset at * the node expires after 'now'. If 'now' is zero, then the current time * will be used. * * Requires: * * \li 'db' is a valid database. * * \li 'type' is not SIG, or a meta-RR type other than 'ANY' (e.g. 'OPT'). * * \li 'nodep' is NULL, or nodep is a valid pointer and *nodep == NULL. * * \li 'foundname' is a valid name with a dedicated buffer. * * \li 'rdataset' is NULL, or is a valid unassociated rdataset. * * Ensures, * on a non-error completion: * * \li If nodep != NULL, then it is bound to the found node. * * \li If foundname != NULL, then it contains the full name of the * found node. * * \li If rdataset != NULL and type != dns_rdatatype_any, then * rdataset is bound to the found rdataset. * * Non-error results are: * * \li #ISC_R_SUCCESS The desired node and type were * found. * * \li #DNS_R_WILDCARD The desired node and type were * found after performing * wildcard matching. This is * only returned if the * #DNS_DBFIND_INDICATEWILD * option is set; otherwise * #ISC_R_SUCCESS is returned. * * \li #DNS_R_GLUE The desired node and type were * found, but are glue. This * result can only occur if * the DNS_DBFIND_GLUEOK option * is set. This result can only * occur if 'db' is a zone * database. If type == * dns_rdatatype_any, then the * node returned may contain, or * consist entirely of invalid * glue (i.e. data occluded by a * zone cut). The caller must * take care not to return invalid * glue to a client. * * \li #DNS_R_DELEGATION The data requested is beneath * a zone cut. node, foundname, * and rdataset reference the * NS RRset of the zone cut. * If 'db' is a cache database, * then this is the deepest known * delegation. * * \li #DNS_R_ZONECUT type == dns_rdatatype_any, and * the desired node is a zonecut. * The caller must take care not * to return inappropriate glue * to a client. This result can * only occur if 'db' is a zone * database and DNS_DBFIND_GLUEOK * is set. * * \li #DNS_R_DNAME The data requested is beneath * a DNAME. node, foundname, * and rdataset reference the * DNAME RRset. * * \li #DNS_R_CNAME The rdataset requested was not * found, but there is a CNAME * at the desired name. node, * foundname, and rdataset * reference the CNAME RRset. * * \li #DNS_R_NXDOMAIN The desired name does not * exist. * * \li #DNS_R_NXRRSET The desired name exists, but * the desired type does not. * * \li #ISC_R_NOTFOUND The desired name does not * exist, and no delegation could * be found. This result can only * occur if 'db' is a cache * database. The caller should * use its nameserver(s) of last * resort (e.g. root hints). * * \li #DNS_R_NCACHENXDOMAIN The desired name does not * exist. 'node' is bound to the * cache node with the desired * name, and 'rdataset' contains * the negative caching proof. * * \li #DNS_R_NCACHENXRRSET The desired type does not * exist. 'node' is bound to the * cache node with the desired * name, and 'rdataset' contains * the negative caching proof. * * \li #DNS_R_EMPTYNAME The name exists but there is * no data at the name. * * \li #DNS_R_COVERINGNSEC The returned data is a NSEC * that potentially covers 'name'. * * \li #DNS_R_EMPTYWILD The name is a wildcard without * resource records. * * Error results: * * \li #ISC_R_NOMEMORY * * \li #DNS_R_BADDB Data that is required to be * present in the DB, e.g. an NSEC * record in a secure zone, is not * present. * * \li Other results are possible, and should all be treated as * errors. */ isc_result_t dns_db_findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); /*%< * Find the deepest known zonecut which encloses 'name' in 'db'. * * Notes: * * \li If the #DNS_DBFIND_NOEXACT option is set, then the zonecut returned * (if any) will be the deepest known ancestor of 'name'. * * \li If 'now' is zero, then the current time will be used. * * Requires: * * \li 'db' is a valid database with cache semantics. * * \li 'nodep' is NULL, or nodep is a valid pointer and *nodep == NULL. * * \li 'foundname' is a valid name with a dedicated buffer. * * \li 'rdataset' is NULL, or is a valid unassociated rdataset. * * Ensures, on a non-error completion: * * \li If nodep != NULL, then it is bound to the found node. * * \li If foundname != NULL, then it contains the full name of the * found node. * * \li If rdataset != NULL and type != dns_rdatatype_any, then * rdataset is bound to the found rdataset. * * Non-error results are: * * \li #ISC_R_SUCCESS * * \li #ISC_R_NOTFOUND * * \li Other results are possible, and should all be treated as * errors. */ void dns_db_attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp); /*%< * Attach *targetp to source. * * Requires: * * \li 'db' is a valid database. * * \li 'source' is a valid node. * * \li 'targetp' points to a NULL dns_dbnode_t *. * * Ensures: * * \li *targetp is attached to source. */ void dns_db_detachnode(dns_db_t *db, dns_dbnode_t **nodep); /*%< * Detach *nodep from its node. * * Requires: * * \li 'db' is a valid database. * * \li 'nodep' points to a valid node. * * Ensures: * * \li *nodep is NULL. */ void dns_db_transfernode(dns_db_t *db, dns_dbnode_t **sourcep, dns_dbnode_t **targetp); /*%< * Transfer a node between pointer. * * This is equivalent to calling dns_db_attachnode() then dns_db_detachnode(). * * Requires: * * \li 'db' is a valid database. * * \li '*sourcep' is a valid node. * * \li 'targetp' points to a NULL dns_dbnode_t *. * * Ensures: * * \li '*sourcep' is NULL. */ isc_result_t dns_db_expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now); /*%< * Mark as stale all records at 'node' which expire at or before 'now'. * * Note: if 'now' is zero, then the current time will be used. * * Requires: * * \li 'db' is a valid cache database. * * \li 'node' is a valid node. */ void dns_db_printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out); /*%< * Print a textual representation of the contents of the node to * 'out'. * * Note: this function is intended for debugging, not general use. * * Requires: * * \li 'db' is a valid database. * * \li 'node' is a valid node. */ /*** *** DB Iterator Creation ***/ isc_result_t dns_db_createiterator(dns_db_t *db, unsigned int options, dns_dbiterator_t **iteratorp); /*%< * Create an iterator for version 'version' of 'db'. * * Notes: * * \li One or more of the following options can be set. * #DNS_DB_RELATIVENAMES * #DNS_DB_NSEC3ONLY * #DNS_DB_NONSEC3 * * Requires: * * \li 'db' is a valid database. * * \li iteratorp != NULL && *iteratorp == NULL * * Ensures: * * \li On success, *iteratorp will be a valid database iterator. * * Returns: * * \li #ISC_R_SUCCESS * \li #ISC_R_NOMEMORY */ /*** *** Rdataset Methods ***/ /* * XXXRTH Should we check for glue and pending data in dns_db_findrdataset()? */ isc_result_t dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdatatype_t type, dns_rdatatype_t covers, isc_stdtime_t now, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); /*%< * Search for an rdataset of type 'type' at 'node' that are in version * 'version' of 'db'. If found, make 'rdataset' refer to it. * * Notes: * * \li If 'version' is NULL, then the current version will be used. * * \li Care must be used when using this routine to build a DNS response: * 'node' should have been found with dns_db_find(), not * dns_db_findnode(). No glue checking is done. No checking for * pending data is done. * * \li The 'now' field is ignored if 'db' is a zone database. If 'db' is a * cache database, an rdataset will not be found unless it expires after * 'now'. If 'now' is zero, then the current time will be used. * * Requires: * * \li 'db' is a valid database. * * \li 'node' is a valid node. * * \li 'rdataset' is a valid, disassociated rdataset. * * \li 'sigrdataset' is a valid, disassociated rdataset, or it is NULL. * * \li If 'covers' != 0, 'type' must be SIG. * * \li 'type' is not a meta-RR type such as 'ANY' or 'OPT'. * * Ensures: * * \li On success, 'rdataset' is associated with the found rdataset. * * Returns: * * \li #ISC_R_SUCCESS * \li #ISC_R_NOTFOUND * * \li Other results are possible, depending upon the database * implementation used. */ isc_result_t dns_db_allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_stdtime_t now, dns_rdatasetiter_t **iteratorp); /*%< * Make '*iteratorp' an rdataset iterator for all rdatasets at 'node' in * version 'version' of 'db'. * * Notes: * * \li If 'version' is NULL, then the current version will be used. * * \li The 'now' field is ignored if 'db' is a zone database. If 'db' is a * cache database, an rdataset will not be found unless it expires after * 'now'. Any ANY query will not match unless at least one rdataset at * the node expires after 'now'. If 'now' is zero, then the current time * will be used. * * Requires: * * \li 'db' is a valid database. * * \li 'node' is a valid node. * * \li iteratorp != NULL && *iteratorp == NULL * * Ensures: * * \li On success, '*iteratorp' is a valid rdataset iterator. * * Returns: * * \li #ISC_R_SUCCESS * \li #ISC_R_NOTFOUND * * \li Other results are possible, depending upon the database * implementation used. */ isc_result_t dns_db_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options, dns_rdataset_t *addedrdataset); /*%< * Add 'rdataset' to 'node' in version 'version' of 'db'. * * Notes: * * \li If the database has zone semantics, the #DNS_DBADD_MERGE option is set, * and an rdataset of the same type as 'rdataset' already exists at * 'node' then the contents of 'rdataset' will be merged with the existing * rdataset. If the option is not set, then rdataset will replace any * existing rdataset of the same type. If not merging and the * #DNS_DBADD_FORCE option is set, then the data will update the database * without regard to trust levels. If not forcing the data, then the * rdataset will only be added if its trust level is >= the trust level of * any existing rdataset. Forcing is only meaningful for cache databases. * If #DNS_DBADD_EXACT is set then there must be no rdata in common between * the old and new rdata sets. If #DNS_DBADD_EXACTTTL is set then both * the old and new rdata sets must have the same ttl. * * \li The 'now' field is ignored if 'db' is a zone database. If 'db' is * a cache database, then the added rdataset will expire no later than * now + rdataset->ttl. * * \li If 'addedrdataset' is not NULL, then it will be attached to the * resulting new rdataset in the database, or to the existing data if * the existing data was better. * * Requires: * * \li 'db' is a valid database. * * \li 'node' is a valid node. * * \li 'rdataset' is a valid, associated rdataset with the same class * as 'db'. * * \li 'addedrdataset' is NULL, or a valid, unassociated rdataset. * * \li The database has zone semantics and 'version' is a valid * read-write version, or the database has cache semantics * and version is NULL. * * \li If the database has cache semantics, the #DNS_DBADD_MERGE option must * not be set. * * Returns: * * \li #ISC_R_SUCCESS * \li #DNS_R_UNCHANGED The operation did not change anything. * \li #ISC_R_NOMEMORY * \li #DNS_R_NOTEXACT * * \li Other results are possible, depending upon the database * implementation used. */ isc_result_t dns_db_subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdataset_t *rdataset, unsigned int options, dns_rdataset_t *newrdataset); /*%< * Remove any rdata in 'rdataset' from 'node' in version 'version' of * 'db'. * * Notes: * * \li If 'newrdataset' is not NULL, then it will be attached to the * resulting new rdataset in the database, unless the rdataset has * become nonexistent. If DNS_DBSUB_EXACT is set then all elements * of 'rdataset' must exist at 'node'. * * Requires: * * \li 'db' is a valid database. * * \li 'node' is a valid node. * * \li 'rdataset' is a valid, associated rdataset with the same class * as 'db'. * * \li 'newrdataset' is NULL, or a valid, unassociated rdataset. * * \li The database has zone semantics and 'version' is a valid * read-write version. * * Returns: * * \li #ISC_R_SUCCESS * \li #DNS_R_UNCHANGED The operation did not change anything. * \li #DNS_R_NXRRSET All rdata of the same type as those * in 'rdataset' have been deleted. * \li #DNS_R_NOTEXACT Some part of 'rdataset' did not * exist and DNS_DBSUB_EXACT was set. * * \li Other results are possible, depending upon the database * implementation used. */ isc_result_t dns_db_deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdatatype_t type, dns_rdatatype_t covers); /*%< * Make it so that no rdataset of type 'type' exists at 'node' in version * version 'version' of 'db'. * * Notes: * * \li If 'type' is dns_rdatatype_any, then no rdatasets will exist in * 'version' (provided that the dns_db_deleterdataset() isn't followed * by one or more dns_db_addrdataset() calls). * * Requires: * * \li 'db' is a valid database. * * \li 'node' is a valid node. * * \li The database has zone semantics and 'version' is a valid * read-write version, or the database has cache semantics * and version is NULL. * * \li 'type' is not a meta-RR type, except for dns_rdatatype_any, which is * allowed. * * \li If 'covers' != 0, 'type' must be SIG. * * Returns: * * \li #ISC_R_SUCCESS * \li #DNS_R_UNCHANGED No rdatasets of 'type' existed before * the operation was attempted. * * \li Other results are possible, depending upon the database * implementation used. */ isc_result_t dns_db_getsoaserial(dns_db_t *db, dns_dbversion_t *ver, isc_uint32_t *serialp); /*%< * Get the current SOA serial number from a zone database. * * Requires: * \li 'db' is a valid database with zone semantics. * \li 'ver' is a valid version. */ void dns_db_overmem(dns_db_t *db, isc_boolean_t overmem); /*%< * Enable / disable aggressive cache cleaning. */ unsigned int dns_db_nodecount(dns_db_t *db); /*%< * Count the number of nodes in 'db'. * * Requires: * * \li 'db' is a valid database. * * Returns: * \li The number of nodes in the database */ unsigned int dns_db_hashsize(dns_db_t *db); /*%< * For database implementations using a hash table, report the * current number of buckets. * * Requires: * * \li 'db' is a valid database. * * Returns: * \li The number of buckets in the database's hash table, or * ISC_R_NOTIMPLEMENTED. */ void dns_db_settask(dns_db_t *db, isc_task_t *task); /*%< * If task is set then the final detach maybe performed asynchronously. * * Requires: * \li 'db' is a valid database. * \li 'task' to be valid or NULL. */ isc_boolean_t dns_db_ispersistent(dns_db_t *db); /*%< * Is 'db' persistent? A persistent database does not need to be loaded * from disk or written to disk. * * Requires: * * \li 'db' is a valid database. * * Returns: * \li #ISC_TRUE 'db' is persistent. * \li #ISC_FALSE 'db' is not persistent. */ isc_result_t dns_db_register(const char *name, dns_dbcreatefunc_t create, void *driverarg, isc_mem_t *mctx, dns_dbimplementation_t **dbimp); /*%< * Register a new database implementation and add it to the list of * supported implementations. * * Requires: * * \li 'name' is not NULL * \li 'order' is a valid function pointer * \li 'mctx' is a valid memory context * \li dbimp != NULL && *dbimp == NULL * * Returns: * \li #ISC_R_SUCCESS The registration succeeded * \li #ISC_R_NOMEMORY Out of memory * \li #ISC_R_EXISTS A database implementation with the same name exists * * Ensures: * * \li *dbimp points to an opaque structure which must be passed to * dns_db_unregister(). */ void dns_db_unregister(dns_dbimplementation_t **dbimp); /*%< * Remove a database implementation from the list of supported * implementations. No databases of this type can be active when this * is called. * * Requires: * \li dbimp != NULL && *dbimp == NULL * * Ensures: * * \li Any memory allocated in *dbimp will be freed. */ isc_result_t dns_db_getoriginnode(dns_db_t *db, dns_dbnode_t **nodep); /*%< * Get the origin DB node corresponding to the DB's zone. This function * should typically succeed unless the underlying DB implementation doesn't * support the feature. * * Requires: * * \li 'db' is a valid zone database. * \li 'nodep' != NULL && '*nodep' == NULL * * Ensures: * \li On success, '*nodep' will point to the DB node of the zone's origin. * * Returns: * \li #ISC_R_SUCCESS * \li #ISC_R_NOTFOUND - the DB implementation does not support this feature. */ isc_result_t dns_db_getnsec3parameters(dns_db_t *db, dns_dbversion_t *version, dns_hash_t *hash, isc_uint8_t *flags, isc_uint16_t *interations, unsigned char *salt, size_t *salt_length); /*%< * Get the NSEC3 parameters that are associated with this zone. * * Requires: * \li 'db' is a valid zone database. * * Returns: * \li #ISC_R_SUCCESS * \li #ISC_R_NOTFOUND - the DB implementation does not support this feature * or this zone does not have NSEC3 records. */ isc_result_t dns_db_findnsec3node(dns_db_t *db, dns_name_t *name, isc_boolean_t create, dns_dbnode_t **nodep); /*%< * Find the NSEC3 node with name 'name'. * * Notes: * \li If 'create' is ISC_TRUE and no node with name 'name' exists, then * such a node will be created. * * Requires: * * \li 'db' is a valid database. * * \li 'name' is a valid, non-empty, absolute name. * * \li nodep != NULL && *nodep == NULL * * Ensures: * * \li On success, *nodep is attached to the node with name 'name'. * * Returns: * * \li #ISC_R_SUCCESS * \li #ISC_R_NOTFOUND If !create and name not found. * \li #ISC_R_NOMEMORY Can only happen if create is ISC_TRUE. * * \li Other results are possible, depending upon the database * implementation used. */ isc_result_t dns_db_setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, isc_stdtime_t resign); /*%< * Sets the re-signing time associated with 'rdataset' to 'resign'. * * Requires: * \li 'db' is a valid zone database. * \li 'rdataset' is or is to be associated with 'db'. * \li 'rdataset' is not pending removed from the heap via an * uncommitted call to dns_db_resigned(). * * Returns: * \li #ISC_R_SUCCESS * \li #ISC_R_NOMEMORY * \li #ISC_R_NOTIMPLEMENTED - Not supported by this DB implementation. */ isc_result_t dns_db_getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, dns_name_t *name); /*%< * Return the rdataset with the earliest signing time in the zone. * Note: the rdataset is version agnostic. * * Requires: * \li 'db' is a valid zone database. * \li 'rdataset' to be initialized but not associated. * \li 'name' to be NULL or have a buffer associated with it. * * Returns: * \li #ISC_R_SUCCESS * \li #ISC_R_NOTFOUND - No dataset exists. */ void dns_db_resigned(dns_db_t *db, dns_rdataset_t *rdataset, dns_dbversion_t *version); /*%< * Mark 'rdataset' as not being available to be returned by * dns_db_getsigningtime(). If the changes associated with 'version' * are committed this will be permanent. If the version is not committed * this change will be rolled back when the version is closed. Until * 'version' is either committed or rolled back, 'rdataset' can no longer * be acted upon by dns_db_setsigningtime(). * * Requires: * \li 'db' is a valid zone database. * \li 'rdataset' to be associated with 'db'. * \li 'version' to be open for writing. */ dns_stats_t * dns_db_getrrsetstats(dns_db_t *db); /*%< * Get statistics information counting RRsets stored in the DB, when available. * The statistics may not be available depending on the DB implementation. * * Requires: * * \li 'db' is a valid database (cache only). * * Returns: * \li when available, a pointer to a statistics object created by * dns_rdatasetstats_create(); otherwise NULL. */ isc_result_t dns_db_setcachestats(dns_db_t *db, isc_stats_t *stats); /*%< * Set the location in which to collect cache statistics. * This option may not exist depending on the DB implementation. * * Requires: * * \li 'db' is a valid database (cache only). * * Returns: * \li when available, a pointer to a statistics object created by * dns_rdatasetstats_create(); otherwise NULL. */ void dns_db_rpz_attach(dns_db_t *db, dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num); /*%< * Attach the response policy information for a view to a database for a * zone for the view. */ isc_result_t dns_db_rpz_ready(dns_db_t *db); /*%< * Finish loading a response policy zone. */ ISC_LANG_ENDDECLS #endif /* DNS_DB_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/adb.h0000644000470500017500000005470712664710322020046 0ustar lamontlamont/* * Copyright (C) 2004-2008, 2011, 2013-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: adb.h,v 1.88 2011/12/05 17:10:51 each Exp $ */ #ifndef DNS_ADB_H #define DNS_ADB_H 1 /***** ***** Module Info *****/ /*! \file dns/adb.h *\brief * DNS Address Database * * This module implements an address database (ADB) for mapping a name * to an isc_sockaddr_t. It also provides statistical information on * how good that address might be. * * A client will pass in a dns_name_t, and the ADB will walk through * the rdataset looking up addresses associated with the name. If it * is found on the internal lists, a structure is filled in with the * address information and stats for found addresses. * * If the name cannot be found on the internal lists, a new entry will * be created for a name if all the information needed can be found * in the zone table or cache. This new address will then be returned. * * If a request must be made to remote servers to satisfy a name lookup, * this module will start fetches to try to complete these addresses. When * at least one more completes, an event is sent to the caller. If none of * them resolve before the fetch times out, an event indicating this is * sent instead. * * Records are stored internally until a timer expires. The timer is the * smaller of the TTL or signature validity period. * * Lameness is stored per tuple, and this data hangs off each * address field. When an address is marked lame for a given tuple the address * will not be returned to a caller. * * * MP: * *\li The ADB takes care of all necessary locking. * *\li Only the task which initiated the name lookup can cancel the lookup. * * * Security: * *\li None, since all data stored is required to be pre-filtered. * (Cache needs to be sane, fetches return bounds-checked and sanity- * checked data, caller passes a good dns_name_t for the zone, etc) */ /*** *** Imports ***/ #include #include #include #include #include #include ISC_LANG_BEGINDECLS /*** *** Magic number checks ***/ #define DNS_ADBFIND_MAGIC ISC_MAGIC('a','d','b','H') #define DNS_ADBFIND_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFIND_MAGIC) #define DNS_ADBADDRINFO_MAGIC ISC_MAGIC('a','d','A','I') #define DNS_ADBADDRINFO_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBADDRINFO_MAGIC) /*** *** TYPES ***/ typedef struct dns_adbname dns_adbname_t; /*! *\brief * Represents a lookup for a single name. * * On return, the client can safely use "list", and can reorder the list. * Items may not be _deleted_ from this list, however, or added to it * other than by using the dns_adb_*() API. */ struct dns_adbfind { /* Public */ unsigned int magic; /*%< RO: magic */ dns_adbaddrinfolist_t list; /*%< RO: list of addrs */ unsigned int query_pending; /*%< RO: partial list */ unsigned int partial_result; /*%< RO: addrs missing */ unsigned int options; /*%< RO: options */ isc_result_t result_v4; /*%< RO: v4 result */ isc_result_t result_v6; /*%< RO: v6 result */ ISC_LINK(dns_adbfind_t) publink; /*%< RW: client use */ /* Private */ isc_mutex_t lock; /* locks all below */ in_port_t port; int name_bucket; unsigned int flags; dns_adbname_t *adbname; dns_adb_t *adb; isc_event_t event; ISC_LINK(dns_adbfind_t) plink; }; /* * _INET: * _INET6: * return addresses of that type. * * _EMPTYEVENT: * Only schedule an event if no addresses are known. * Must set _WANTEVENT for this to be meaningful. * * _WANTEVENT: * An event is desired. Check this bit in the returned find to see * if one will actually be generated. * * _AVOIDFETCHES: * If set, fetches will not be generated unless no addresses are * available in any of the address families requested. * * _STARTATZONE: * Fetches will start using the closest zone data or use the root servers. * This is useful for reestablishing glue that has expired. * * _GLUEOK: * _HINTOK: * Glue or hints are ok. These are used when matching names already * in the adb, and when dns databases are searched. * * _RETURNLAME: * Return lame servers in a find, so that all addresses are returned. * * _LAMEPRUNED: * At least one address was omitted from the list because it was lame. * This bit will NEVER be set if _RETURNLAME is set in the createfind(). */ /*% Return addresses of type INET. */ #define DNS_ADBFIND_INET 0x00000001 /*% Return addresses of type INET6. */ #define DNS_ADBFIND_INET6 0x00000002 #define DNS_ADBFIND_ADDRESSMASK 0x00000003 /*% * Only schedule an event if no addresses are known. * Must set _WANTEVENT for this to be meaningful. */ #define DNS_ADBFIND_EMPTYEVENT 0x00000004 /*% * An event is desired. Check this bit in the returned find to see * if one will actually be generated. */ #define DNS_ADBFIND_WANTEVENT 0x00000008 /*% * If set, fetches will not be generated unless no addresses are * available in any of the address families requested. */ #define DNS_ADBFIND_AVOIDFETCHES 0x00000010 /*% * Fetches will start using the closest zone data or use the root servers. * This is useful for reestablishing glue that has expired. */ #define DNS_ADBFIND_STARTATZONE 0x00000020 /*% * Glue or hints are ok. These are used when matching names already * in the adb, and when dns databases are searched. */ #define DNS_ADBFIND_GLUEOK 0x00000040 /*% * Glue or hints are ok. These are used when matching names already * in the adb, and when dns databases are searched. */ #define DNS_ADBFIND_HINTOK 0x00000080 /*% * Return lame servers in a find, so that all addresses are returned. */ #define DNS_ADBFIND_RETURNLAME 0x00000100 /*% * Only schedule an event if no addresses are known. * Must set _WANTEVENT for this to be meaningful. */ #define DNS_ADBFIND_LAMEPRUNED 0x00000200 /*% * The server's fetch quota is exceeded; it will be treated as * lame for this query. */ #define DNS_ADBFIND_OVERQUOTA 0x00000400 /*% * The answers to queries come back as a list of these. */ struct dns_adbaddrinfo { unsigned int magic; /*%< private */ isc_sockaddr_t sockaddr; /*%< [rw] */ unsigned int srtt; /*%< [rw] microsecs */ isc_dscp_t dscp; unsigned int flags; /*%< [rw] */ dns_adbentry_t *entry; /*%< private */ ISC_LINK(dns_adbaddrinfo_t) publink; }; /*!< * The event sent to the caller task is just a plain old isc_event_t. It * contains no data other than a simple status, passed in the "type" field * to indicate that another address resolved, or all partially resolved * addresses have failed to resolve. * * "sender" is the dns_adbfind_t used to issue this query. * * This is simply a standard event, with the "type" set to: * *\li #DNS_EVENT_ADBMOREADDRESSES -- another address resolved. *\li #DNS_EVENT_ADBNOMOREADDRESSES -- all pending addresses failed, * were canceled, or otherwise will * not be usable. *\li #DNS_EVENT_ADBCANCELED -- The request was canceled by a * 3rd party. *\li #DNS_EVENT_ADBNAMEDELETED -- The name was deleted, so this request * was canceled. * * In each of these cases, the addresses returned by the initial call * to dns_adb_createfind() can still be used until they are no longer needed. */ /**** **** FUNCTIONS ****/ isc_result_t dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *tmgr, isc_taskmgr_t *taskmgr, dns_adb_t **newadb); /*%< * Create a new ADB. * * Notes: * *\li Generally, applications should not create an ADB directly, but * should instead call dns_view_createresolver(). * * Requires: * *\li 'mem' must be a valid memory context. * *\li 'view' be a pointer to a valid view. * *\li 'tmgr' be a pointer to a valid timer manager. * *\li 'taskmgr' be a pointer to a valid task manager. * *\li 'newadb' != NULL && '*newadb' == NULL. * * Returns: * *\li #ISC_R_SUCCESS after happiness. *\li #ISC_R_NOMEMORY after resource allocation failure. */ void dns_adb_attach(dns_adb_t *adb, dns_adb_t **adbp); /*% * Attach to an 'adb' to 'adbp'. * * Requires: *\li 'adb' to be a valid dns_adb_t, created via dns_adb_create(). *\li 'adbp' to be a valid pointer to a *dns_adb_t which is initialized * to NULL. */ void dns_adb_detach(dns_adb_t **adb); /*% * Delete the ADB. Sets *ADB to NULL. Cancels any outstanding requests. * * Requires: * *\li 'adb' be non-NULL and '*adb' be a valid dns_adb_t, created via * dns_adb_create(). */ void dns_adb_whenshutdown(dns_adb_t *adb, isc_task_t *task, isc_event_t **eventp); /*% * Send '*eventp' to 'task' when 'adb' has shutdown. * * Requires: * *\li '*adb' is a valid dns_adb_t. * *\li eventp != NULL && *eventp is a valid event. * * Ensures: * *\li *eventp == NULL * *\li The event's sender field is set to the value of adb when the event * is sent. */ void dns_adb_shutdown(dns_adb_t *adb); /*%< * Shutdown 'adb'. * * Requires: * * \li '*adb' is a valid dns_adb_t. */ isc_result_t dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, void *arg, dns_name_t *name, dns_name_t *qname, dns_rdatatype_t qtype, unsigned int options, isc_stdtime_t now, dns_name_t *target, in_port_t port, dns_adbfind_t **find); isc_result_t dns_adb_createfind2(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, void *arg, dns_name_t *name, dns_name_t *qname, dns_rdatatype_t qtype, unsigned int options, isc_stdtime_t now, dns_name_t *target, in_port_t port, unsigned int depth, isc_counter_t *qc, dns_adbfind_t **find); /*%< * Main interface for clients. The adb will look up the name given in * "name" and will build up a list of found addresses, and perhaps start * internal fetches to resolve names that are unknown currently. * * If other addresses resolve after this call completes, an event will * be sent to the with the sender of that event * set to a pointer to the dns_adbfind_t returned by this function. * * If no events will be generated, the *find->result_v4 and/or result_v6 * members may be examined for address lookup status. The usual #ISC_R_SUCCESS, * #ISC_R_FAILURE, #DNS_R_NXDOMAIN, and #DNS_R_NXRRSET are returned, along with * #ISC_R_NOTFOUND meaning the ADB has not _yet_ found the values. In this * latter case, retrying may produce more addresses. * * If events will be returned, the result_v[46] members are only valid * when that event is actually returned. * * The list of addresses returned is unordered. The caller must impose * any ordering required. The list will not contain "known bad" addresses, * however. For instance, it will not return hosts that are known to be * lame for the zone in question. * * The caller cannot (directly) modify the contents of the address list's * fields other than the "link" field. All values can be read at any * time, however. * * The "now" parameter is used only for determining which entries that * have a specific time to live or expire time should be removed from * the running database. If specified as zero, the current time will * be retrieved and used. * * If 'target' is not NULL and 'name' is an alias (i.e. the name is * CNAME'd or DNAME'd to another name), then 'target' will be updated with * the domain name that 'name' is aliased to. * * All addresses returned will have the sockaddr's port set to 'port.' * The caller may change them directly in the dns_adbaddrinfo_t since * they are copies of the internal address only. * * XXXMLG Document options, especially the flags which control how * events are sent. * * Requires: * *\li *adb be a valid isc_adb_t object. * *\li If events are to be sent, *task be a valid task, * and isc_taskaction_t != NULL. * *\li *name is a valid dns_name_t. * *\li qname != NULL and *qname be a valid dns_name_t. * *\li target == NULL or target is a valid name with a buffer. * *\li find != NULL && *find == NULL. * * Returns: * *\li #ISC_R_SUCCESS Addresses might have been returned, and events will be * delivered for unresolved addresses. *\li #ISC_R_NOMORE Addresses might have been returned, but no events * will ever be posted for this context. This is only * returned if task != NULL. *\li #ISC_R_NOMEMORY insufficient resources *\li #DNS_R_ALIAS 'name' is an alias for another name. * * Calls, and returns error codes from: * *\li isc_stdtime_get() * * Notes: * *\li No internal reference to "name" exists after this function * returns. */ void dns_adb_cancelfind(dns_adbfind_t *find); /*%< * Cancels the find, and sends the event off to the caller. * * It is an error to call dns_adb_cancelfind() on a find where * no event is wanted, or will ever be sent. * * Note: * *\li It is possible that the real completion event was posted just * before the dns_adb_cancelfind() call was made. In this case, * dns_adb_cancelfind() will do nothing. The event callback needs * to be prepared to find this situation (i.e. result is valid but * the caller expects it to be canceled). * * Requires: * *\li 'find' be a valid dns_adbfind_t pointer. * *\li events would have been posted to the task. This can be checked * with (find->options & DNS_ADBFIND_WANTEVENT). * * Ensures: * *\li The event was posted to the task. */ void dns_adb_destroyfind(dns_adbfind_t **find); /*%< * Destroys the find reference. * * Note: * *\li This can only be called after the event was delivered for a * find. Additionally, the event MUST have been freed via * isc_event_free() BEFORE this function is called. * * Requires: * *\li 'find' != NULL and *find be valid dns_adbfind_t pointer. * * Ensures: * *\li No "address found" events will be posted to the originating task * after this function returns. */ void dns_adb_dump(dns_adb_t *adb, FILE *f); /*%< * This function is only used for debugging. It will dump as much of the * state of the running system as possible. * * Requires: * *\li adb be valid. * *\li f != NULL, and is a file open for writing. */ void dns_adb_dumpfind(dns_adbfind_t *find, FILE *f); /*%< * This function is only used for debugging. Dump the data associated * with a find. * * Requires: * *\li find is valid. * * \li f != NULL, and is a file open for writing. */ isc_result_t dns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr, dns_name_t *qname, dns_rdatatype_t type, isc_stdtime_t expire_time); /*%< * Mark the given address as lame for the . expire_time should * be set to the time when the entry should expire. That is, if it is to * expire 10 minutes in the future, it should set it to (now + 10 * 60). * * Requires: * *\li adb be valid. * *\li addr be valid. * *\li qname be the qname used in the dns_adb_createfind() call. * * Returns: * *\li #ISC_R_SUCCESS -- all is well. *\li #ISC_R_NOMEMORY -- could not mark address as lame. */ /* * Reasonable defaults for RTT adjustments * * (Note: these values function both as scaling factors and as * indicators of the type of RTT adjustment operation taking place. * Adjusting the scaling factors is fine, as long as they all remain * unique values.) */ #define DNS_ADB_RTTADJDEFAULT 7 /*%< default scale */ #define DNS_ADB_RTTADJREPLACE 0 /*%< replace with our rtt */ #define DNS_ADB_RTTADJAGE 10 /*%< age this rtt */ void dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int rtt, unsigned int factor); /*%< * Mix the round trip time into the existing smoothed rtt. * * Requires: * *\li adb be valid. * *\li addr be valid. * *\li 0 <= factor <= 10 * * Note: * *\li The srtt in addr will be updated to reflect the new global * srtt value. This may include changes made by others. */ void dns_adb_agesrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, isc_stdtime_t now); /* * dns_adb_agesrtt is equivalent to dns_adb_adjustsrtt with factor * equal to DNS_ADB_RTTADJAGE and the current time passed in. * * Requires: * *\li adb be valid. * *\li addr be valid. * * Note: * *\li The srtt in addr will be updated to reflect the new global * srtt value. This may include changes made by others. */ void dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int bits, unsigned int mask); /*% * Change Flags. * * Set the flags as given by: * *\li newflags = (oldflags & ~mask) | (bits & mask); * * Requires: * *\li adb be valid. * *\li addr be valid. */ void dns_adb_setudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size); /*% * Update seen UDP response size. The largest seen will be returned by * dns_adb_getudpsize(). * * Requires: * *\li adb be valid. * *\li addr be valid. */ unsigned int dns_adb_getudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr); /*% * Return the largest seen UDP response size. * * Requires: * *\li adb be valid. * *\li addr be valid. */ unsigned int dns_adb_probesize(dns_adb_t *adb, dns_adbaddrinfo_t *addr); unsigned int dns_adb_probesize2(dns_adb_t *adb, dns_adbaddrinfo_t *addr, int lookups); /*% * Return suggested EDNS UDP size based on observed responses / failures. * 'lookups' is the number of times the current lookup has been attempted. * * Requires: * *\li adb be valid. * *\li addr be valid. */ void dns_adb_plainresponse(dns_adb_t *adb, dns_adbaddrinfo_t *addr); /*% * Record a successful plain DNS response. * * Requires: * *\li adb be valid. * *\li addr be valid. */ void dns_adb_timeout(dns_adb_t *adb, dns_adbaddrinfo_t *addr); /*% * Record a plain DNS UDP query failed. * * Requires: * *\li adb be valid. * *\li addr be valid. */ void dns_adb_ednsto(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size); /*% * Record a failed EDNS UDP response and the advertised EDNS UDP buffer size * used. * * Requires: * *\li adb be valid. * *\li addr be valid. */ isc_boolean_t dns_adb_noedns(dns_adb_t *adb, dns_adbaddrinfo_t *addr); /*% * Return whether EDNS should be disabled for this server. * * Requires: * *\li adb be valid. * *\li addr be valid. */ isc_result_t dns_adb_findaddrinfo(dns_adb_t *adb, isc_sockaddr_t *sa, dns_adbaddrinfo_t **addrp, isc_stdtime_t now); /*%< * Return a dns_adbaddrinfo_t that is associated with address 'sa'. * * Requires: * *\li adb is valid. * *\li sa is valid. * *\li addrp != NULL && *addrp == NULL * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li #ISC_R_SHUTTINGDOWN */ void dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp); /*%< * Free a dns_adbaddrinfo_t allocated by dns_adb_findaddrinfo(). * * Requires: * *\li adb is valid. * *\li *addrp is a valid dns_adbaddrinfo_t *. */ void dns_adb_flush(dns_adb_t *adb); /*%< * Flushes all cached data from the adb. * * Requires: *\li adb is valid. */ void dns_adb_setadbsize(dns_adb_t *adb, size_t size); /*%< * Set a target memory size. If memory usage exceeds the target * size entries will be removed before they would have expired on * a random basis. * * If 'size' is 0 then memory usage is unlimited. * * Requires: *\li 'adb' is valid. */ void dns_adb_flushname(dns_adb_t *adb, dns_name_t *name); /*%< * Flush 'name' from the adb cache. * * Requires: *\li 'adb' is valid. *\li 'name' is valid. */ void dns_adb_flushnames(dns_adb_t *adb, dns_name_t *name); /*%< * Flush 'name' and all subdomains from the adb cache. * * Requires: *\li 'adb' is valid. *\li 'name' is valid. */ void dns_adb_setsit(dns_adb_t *adb, dns_adbaddrinfo_t *addr, const unsigned char *sit, size_t len); /*%< * Record the Source Identity Token (SIT) associated with this addresss. If * sit is NULL or len is zero. The recorded SIT is cleared. * * Requires: *\li 'adb' is valid. *\li 'addr' is valid. */ size_t dns_adb_getsit(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned char *sit, size_t len); /* * Retieve the saved SIT value and store it in 'sit' which has size 'len'. * * Requires: *\li 'adb' is valid. *\li 'addr' is valid. * * Returns: * The size of the sit token or zero if it doesn't fit in the buffer * or it doesn't exist. */ void dns_adb_setquota(dns_adb_t *adb, isc_uint32_t quota, isc_uint32_t freq, double low, double high, double discount); /*%< * Set the baseline ADB quota, and configure parameters for the * quota adjustment algorithm. * * If the number of fetches currently waiting for responses from this * address exceeds the current quota, then additional fetches are spilled. * * 'quota' is the highest permissible quota; it will adjust itself * downward in response to detected congestion. * * After every 'freq' fetches have either completed or timed out, an * exponentially weighted moving average of the ratio of timeouts * to responses is calculated. If the EWMA goes above a 'high' * threshold, then the quota is adjusted down one step; if it drops * below a 'low' threshold, then the quota is adjusted back up one * step. * * The quota adjustment is based on the function (1 / 1 + (n/10)^(3/2)), * for values of n from 0 to 99. It starts at 100% of the baseline * quota, and descends after 100 steps to 2%. * * 'discount' represents the discount rate of the moving average. Higher * values cause older values to be discounted sooner, providing a faster * response to changes in the timeout ratio. * * Requires: *\li 'adb' is valid. */ isc_boolean_t dns_adbentry_overquota(dns_adbentry_t *entry); /*%< * Returns true if the specified ADB has too many active fetches. * * Requires: *\li 'entry' is valid. */ void dns_adb_beginudpfetch(dns_adb_t *adb, dns_adbaddrinfo_t *addr); void dns_adb_endudpfetch(dns_adb_t *adb, dns_adbaddrinfo_t *addr); /*% * Begin/end a UDP fetch on a particular address. * * These functions increment or decrement the fetch counter for * the ADB entry so that the fetch quota can be enforced. * * Requires: * *\li adb be valid. * *\li addr be valid. */ ISC_LANG_ENDDECLS #endif /* DNS_ADB_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/dlz_dlopen.h0000644000470500017500000001171712664710322021444 0ustar lamontlamont/* * Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file dns/dlz_open.h */ #ifndef DLZ_DLOPEN_H #define DLZ_DLOPEN_H #include ISC_LANG_BEGINDECLS /* * This header provides a minimal set of defines and typedefs needed * for the entry points of an external DLZ module for bind9. */ #define DLZ_DLOPEN_VERSION 3 #define DLZ_DLOPEN_AGE 0 /* * dlz_dlopen_version() is required for all DLZ external drivers. It * should return DLZ_DLOPEN_VERSION */ typedef int dlz_dlopen_version_t(unsigned int *flags); /* * dlz_dlopen_create() is required for all DLZ external drivers. */ typedef isc_result_t dlz_dlopen_create_t(const char *dlzname, unsigned int argc, char *argv[], void **dbdata, ...); /* * dlz_dlopen_destroy() is optional, and will be called when the * driver is unloaded if supplied */ typedef void dlz_dlopen_destroy_t(void *dbdata); /* * dlz_dlopen_findzonedb() is required for all DLZ external drivers */ typedef isc_result_t dlz_dlopen_findzonedb_t(void *dbdata, const char *name, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo); /* * dlz_dlopen_lookup() is required for all DLZ external drivers */ typedef isc_result_t dlz_dlopen_lookup_t(const char *zone, const char *name, void *dbdata, dns_sdlzlookup_t *lookup, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo); /* * dlz_dlopen_authority is optional() if dlz_dlopen_lookup() * supplies authority information for the dns record */ typedef isc_result_t dlz_dlopen_authority_t(const char *zone, void *dbdata, dns_sdlzlookup_t *lookup); /* * dlz_dlopen_allowzonexfr() is optional, and should be supplied if * you want to support zone transfers */ typedef isc_result_t dlz_dlopen_allowzonexfr_t(void *dbdata, const char *name, const char *client); /* * dlz_dlopen_allnodes() is optional, but must be supplied if supply a * dlz_dlopen_allowzonexfr() function */ typedef isc_result_t dlz_dlopen_allnodes_t(const char *zone, void *dbdata, dns_sdlzallnodes_t *allnodes); /* * dlz_dlopen_newversion() is optional. It should be supplied if you * want to support dynamic updates. */ typedef isc_result_t dlz_dlopen_newversion_t(const char *zone, void *dbdata, void **versionp); /* * dlz_closeversion() is optional, but must be supplied if you supply * a dlz_newversion() function */ typedef void dlz_dlopen_closeversion_t(const char *zone, isc_boolean_t commit, void *dbdata, void **versionp); /* * dlz_dlopen_configure() is optional, but must be supplied if you * want to support dynamic updates */ typedef isc_result_t dlz_dlopen_configure_t(dns_view_t *view, dns_dlzdb_t *dlzdb, void *dbdata); /* * dlz_dlopen_setclientcallback() is optional, but must be supplied if you * want to retrieve information about the client (e.g., source address) * before sending a replay. */ typedef isc_result_t dlz_dlopen_setclientcallback_t(dns_view_t *view, void *dbdata); /* * dlz_dlopen_ssumatch() is optional, but must be supplied if you want * to support dynamic updates */ typedef isc_boolean_t dlz_dlopen_ssumatch_t(const char *signer, const char *name, const char *tcpaddr, const char *type, const char *key, isc_uint32_t keydatalen, unsigned char *keydata, void *dbdata); /* * dlz_dlopen_addrdataset() is optional, but must be supplied if you * want to support dynamic updates */ typedef isc_result_t dlz_dlopen_addrdataset_t(const char *name, const char *rdatastr, void *dbdata, void *version); /* * dlz_dlopen_subrdataset() is optional, but must be supplied if you * want to support dynamic updates */ typedef isc_result_t dlz_dlopen_subrdataset_t(const char *name, const char *rdatastr, void *dbdata, void *version); /* * dlz_dlopen_delrdataset() is optional, but must be supplied if you * want to support dynamic updates */ typedef isc_result_t dlz_dlopen_delrdataset_t(const char *name, const char *type, void *dbdata, void *version); ISC_LANG_ENDDECLS #endif bind9-9.10.3.dfsg.P4/lib/dns/include/dns/ssu.h0000644000470500017500000001516512664710322020125 0ustar lamontlamont/* * Copyright (C) 2004-2008, 2010, 2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ssu.h,v 1.28 2011/01/06 23:47:00 tbox Exp $ */ #ifndef DNS_SSU_H #define DNS_SSU_H 1 /*! \file dns/ssu.h */ #include #include #include ISC_LANG_BEGINDECLS #define DNS_SSUMATCHTYPE_NAME 0 #define DNS_SSUMATCHTYPE_SUBDOMAIN 1 #define DNS_SSUMATCHTYPE_WILDCARD 2 #define DNS_SSUMATCHTYPE_SELF 3 #define DNS_SSUMATCHTYPE_SELFSUB 4 #define DNS_SSUMATCHTYPE_SELFWILD 5 #define DNS_SSUMATCHTYPE_SELFKRB5 6 #define DNS_SSUMATCHTYPE_SELFMS 7 #define DNS_SSUMATCHTYPE_SUBDOMAINMS 8 #define DNS_SSUMATCHTYPE_SUBDOMAINKRB5 9 #define DNS_SSUMATCHTYPE_TCPSELF 10 #define DNS_SSUMATCHTYPE_6TO4SELF 11 #define DNS_SSUMATCHTYPE_EXTERNAL 12 #define DNS_SSUMATCHTYPE_DLZ 13 #define DNS_SSUMATCHTYPE_MAX 12 /* max value */ isc_result_t dns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **table); /*%< * Creates a table that will be used to store simple-secure-update rules. * Note: all locking must be provided by the client. * * Requires: *\li 'mctx' is a valid memory context *\li 'table' is not NULL, and '*table' is NULL * * Returns: *\li ISC_R_SUCCESS *\li ISC_R_NOMEMORY */ isc_result_t dns_ssutable_createdlz(isc_mem_t *mctx, dns_ssutable_t **tablep, dns_dlzdb_t *dlzdatabase); /*%< * Create an SSU table that contains a dlzdatabase pointer, and a * single rule with matchtype DNS_SSUMATCHTYPE_DLZ. This type of SSU * table is used by writeable DLZ drivers to offload authorization for * updates to the driver. */ void dns_ssutable_attach(dns_ssutable_t *source, dns_ssutable_t **targetp); /*%< * Attach '*targetp' to 'source'. * * Requires: *\li 'source' is a valid SSU table *\li 'targetp' points to a NULL dns_ssutable_t *. * * Ensures: *\li *targetp is attached to source. */ void dns_ssutable_detach(dns_ssutable_t **tablep); /*%< * Detach '*tablep' from its simple-secure-update rule table. * * Requires: *\li 'tablep' points to a valid dns_ssutable_t * * Ensures: *\li *tablep is NULL *\li If '*tablep' is the last reference to the SSU table, all * resources used by the table will be freed. */ isc_result_t dns_ssutable_addrule(dns_ssutable_t *table, isc_boolean_t grant, dns_name_t *identity, unsigned int matchtype, dns_name_t *name, unsigned int ntypes, dns_rdatatype_t *types); /*%< * Adds a new rule to a simple-secure-update rule table. The rule * either grants or denies update privileges of an identity (or set of * identities) to modify a name (or set of names) or certain types present * at that name. * * Notes: *\li If 'matchtype' is of SELF type, this rule only matches if the * name to be updated matches the signing identity. * *\li If 'ntypes' is 0, this rule applies to all types except * NS, SOA, RRSIG, and NSEC. * *\li If 'types' includes ANY, this rule applies to all types * except NSEC. * * Requires: *\li 'table' is a valid SSU table *\li 'identity' is a valid absolute name *\li 'matchtype' must be one of the defined constants. *\li 'name' is a valid absolute name *\li If 'ntypes' > 0, 'types' must not be NULL * * Returns: *\li ISC_R_SUCCESS *\li ISC_R_NOMEMORY */ isc_boolean_t dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer, dns_name_t *name, isc_netaddr_t *tcpaddr, dns_rdatatype_t type, const dst_key_t *key); /*%< * Checks that the attempted update of (name, type) is allowed according * to the rules specified in the simple-secure-update rule table. If * no rules are matched, access is denied. * * Notes: * 'tcpaddr' should only be set if the request received * via TCP. This provides a weak assurance that the * request was not spoofed. 'tcpaddr' is to to validate * DNS_SSUMATCHTYPE_TCPSELF and DNS_SSUMATCHTYPE_6TO4SELF * rules. * * For DNS_SSUMATCHTYPE_TCPSELF the addresses are mapped to * the standard reverse names under IN-ADDR.ARPA and IP6.ARPA. * RFC 1035, Section 3.5, "IN-ADDR.ARPA domain" and RFC 3596, * Section 2.5, "IP6.ARPA Domain". * * For DNS_SSUMATCHTYPE_6TO4SELF, IPv4 address are converted * to a 6to4 prefix (48 bits) per the rules in RFC 3056. Only * the top 48 bits of the IPv6 address are mapped to the reverse * name. This is independent of whether the most significant 16 * bits match 2002::/16, assigned for 6to4 prefixes, or not. * * Requires: *\li 'table' is a valid SSU table *\li 'signer' is NULL or a valid absolute name *\li 'tcpaddr' is NULL or a valid network address. *\li 'name' is a valid absolute name */ /*% Accessor functions to extract rule components */ isc_boolean_t dns_ssurule_isgrant(const dns_ssurule_t *rule); /*% Accessor functions to extract rule components */ dns_name_t * dns_ssurule_identity(const dns_ssurule_t *rule); /*% Accessor functions to extract rule components */ unsigned int dns_ssurule_matchtype(const dns_ssurule_t *rule); /*% Accessor functions to extract rule components */ dns_name_t * dns_ssurule_name(const dns_ssurule_t *rule); /*% Accessor functions to extract rule components */ unsigned int dns_ssurule_types(const dns_ssurule_t *rule, dns_rdatatype_t **types); isc_result_t dns_ssutable_firstrule(const dns_ssutable_t *table, dns_ssurule_t **rule); /*%< * Initiates a rule iterator. There is no need to maintain any state. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMORE */ isc_result_t dns_ssutable_nextrule(dns_ssurule_t *rule, dns_ssurule_t **nextrule); /*%< * Returns the next rule in the table. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMORE */ /*%< * Check a policy rule via an external application */ isc_boolean_t dns_ssu_external_match(dns_name_t *identity, dns_name_t *signer, dns_name_t *name, isc_netaddr_t *tcpaddr, dns_rdatatype_t type, const dst_key_t *key, isc_mem_t *mctx); ISC_LANG_ENDDECLS #endif /* DNS_SSU_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/client.h0000644000470500017500000005206712664710322020573 0ustar lamontlamont/* * Copyright (C) 2009, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: client.h,v 1.3 2009/09/02 23:48:02 tbox Exp $ */ #ifndef DNS_CLIENT_H #define DNS_CLIENT_H 1 /***** ***** Module Info *****/ /*! \file * * \brief * The DNS client module provides convenient programming interfaces to various * DNS services, such as name resolution with or without DNSSEC validation or * dynamic DNS update. This module is primarily expected to be used by other * applications than BIND9-related ones that need such advanced DNS features. * * MP: *\li In the typical usage of this module, application threads will not share * the same data structures created and manipulated in this module. * However, the module still ensures appropriate synchronization of such * data structures. * * Resources: *\li TBS * * Security: *\li This module does not handle any low-level data directly, and so no * security issue specific to this module is anticipated. */ #include #include #include #include #include typedef enum { updateop_none = 0, updateop_add = 1, updateop_delete = 2, updateop_exist = 3, updateop_notexist = 4, updateop_max = 5 } dns_client_updateop_t; ISC_LANG_BEGINDECLS /*** *** Types ***/ /*% * Optional flags for dns_client_create(x). */ /*%< Enable caching resolution results (experimental). */ #define DNS_CLIENTCREATEOPT_USECACHE 0x8000 /*% * Optional flags for dns_client_(start)resolve. */ /*%< Do not return DNSSEC data (e.g. RRSIGS) with response. */ #define DNS_CLIENTRESOPT_NODNSSEC 0x01 /*%< Allow running external context. */ #define DNS_CLIENTRESOPT_ALLOWRUN 0x02 /*%< Don't validate responses. */ #define DNS_CLIENTRESOPT_NOVALIDATE 0x04 /*%< Don't set the CD flag on upstream queries. */ #define DNS_CLIENTRESOPT_NOCDFLAG 0x08 /*% * Optional flags for dns_client_(start)request. */ /*%< Allow running external context. */ #define DNS_CLIENTREQOPT_ALLOWRUN 0x01 /*% * A dns_clientresevent_t is sent when name resolution performed by a client * completes. 'result' stores the result code of the entire resolution * procedure. 'vresult' specifically stores the result code of DNSSEC * validation if it is performed. When name resolution successfully completes, * 'answerlist' is typically non empty, containing answer names along with * RRsets. It is the receiver's responsibility to free this list by calling * dns_client_freeresanswer() before freeing the event structure. */ typedef struct dns_clientresevent { ISC_EVENT_COMMON(struct dns_clientresevent); isc_result_t result; isc_result_t vresult; dns_namelist_t answerlist; } dns_clientresevent_t; /* too long? */ /*% * Status of a dynamic update procedure. */ typedef enum { dns_clientupdatestate_prepare, /*%< no updates have been sent */ dns_clientupdatestate_sent, /*%< updates were sent, no response */ dns_clientupdatestate_done /*%< update was sent and succeeded */ } dns_clientupdatestate_t; /*% * A dns_clientreqevent_t is sent when a DNS request is completed by a client. * 'result' stores the result code of the entire transaction. * If the transaction is successfully completed but the response packet cannot * be parsed, 'result' will store the result code of dns_message_parse(). * If the response packet is received, 'rmessage' will contain the response * message, whether it is successfully parsed or not. */ typedef struct dns_clientreqevent { ISC_EVENT_COMMON(struct dns_clientreqevent); isc_result_t result; dns_message_t *rmessage; } dns_clientreqevent_t; /* too long? */ /*% * A dns_clientupdateevent_t is sent when dynamic update performed by a client * completes. 'result' stores the result code of the entire update procedure. * 'state' specifies the status of the update procedure when this event is * sent. This can be used as a hint by the receiver to determine whether * the update attempt was ever made. In particular, if the state is * dns_clientupdatestate_prepare, the receiver can be sure that the requested * update was not applied. */ typedef struct dns_clientupdateevent { ISC_EVENT_COMMON(struct dns_clientupdateevent); isc_result_t result; dns_clientupdatestate_t state; } dns_clientupdateevent_t; /* too long? */ isc_result_t dns_client_create(dns_client_t **clientp, unsigned int options); isc_result_t dns_client_createx(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr, isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr, unsigned int options, dns_client_t **clientp); isc_result_t dns_client_createx2(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr, isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr, unsigned int options, dns_client_t **clientp, isc_sockaddr_t *localaddr4, isc_sockaddr_t *localaddr6); /*%< * Create a DNS client. These functions create a new client object with * minimal internal resources such as the default 'view' for the IN class and * IPv4/IPv6 dispatches for the view. * * dns_client_createx() takes 'manager' arguments so that the caller can * control the behavior of the client through the underlying event framework. * On the other hand, dns_client_create() simplifies the interface and creates * the managers internally. A DNS client object created via * dns_client_create() is expected to be used by an application that only needs * simple synchronous services or by a thread-based application. * * dns_client_createx2 takes two additional parameters, 'localaddr4' and * 'localaddr6', to specify the local address to use for each family. If * both are set to NULL, then wildcard addresses will be used for both * families. If only one is NULL, then the other address will be used * as the local address, and the other protocol family will not be used. * * If the DNS_CLIENTCREATEOPT_USECACHE flag is set in 'options', * dns_client_create(x) will create a cache database with the view. * * Requires: * *\li 'mctx' is a valid memory context. * *\li 'actx' is a valid application context. * *\li 'taskmgr' is a valid task manager. * *\li 'socketmgr' is a valid socket manager. * *\li 'timermgr' is a valid timer manager. * *\li clientp != NULL && *clientp == NULL. * * Returns: * *\li #ISC_R_SUCCESS On success. * *\li Anything else Failure. */ void dns_client_destroy(dns_client_t **clientp); /*%< * Destroy 'client'. * * Requires: * *\li '*clientp' is a valid client. * * Ensures: * *\li *clientp == NULL. */ isc_result_t dns_client_setservers(dns_client_t *client, dns_rdataclass_t rdclass, dns_name_t *namespace, isc_sockaddrlist_t *addrs); /*%< * Specify a list of addresses of recursive name servers that the client will * use for name resolution. A view for the 'rdclass' class must be created * beforehand. If 'namespace' is non NULL, the specified server will be used * if and only if the query name is a subdomain of 'namespace'. When servers * for multiple 'namespace's are provided, and a query name is covered by * more than one 'namespace', the servers for the best (longest) matching * namespace will be used. If 'namespace' is NULL, it works as if * dns_rootname (.) were specified. * * Requires: * *\li 'client' is a valid client. * *\li 'namespace' is NULL or a valid name. * *\li 'addrs' != NULL. * * Returns: * *\li #ISC_R_SUCCESS On success. * *\li Anything else Failure. */ isc_result_t dns_client_clearservers(dns_client_t *client, dns_rdataclass_t rdclass, dns_name_t *namespace); /*%< * Remove configured recursive name servers for the 'rdclass' and 'namespace' * from the client. See the description of dns_client_setservers() for * the requirements about 'rdclass' and 'namespace'. * * Requires: * *\li 'client' is a valid client. * *\li 'namespace' is NULL or a valid name. * * Returns: * *\li #ISC_R_SUCCESS On success. * *\li Anything else Failure. */ isc_result_t dns_client_setdlv(dns_client_t *client, dns_rdataclass_t rdclass, const char *dlvname); /*%< * Specify a name to use for DNSSEC lookaside validation (e.g., * "dlv.isc.org"). If a trusted key has been added for that name, * then DLV will be used during validation. If 'dlvname' is NULL, * then DLV will no longer be used for this client. * * Requires: * *\li 'client' is a valid client. * * Returns: * *\li #ISC_R_SUCCESS On success. * *\li Anything else Failure. */ isc_result_t dns_client_resolve(dns_client_t *client, dns_name_t *name, dns_rdataclass_t rdclass, dns_rdatatype_t type, unsigned int options, dns_namelist_t *namelist); isc_result_t dns_client_startresolve(dns_client_t *client, dns_name_t *name, dns_rdataclass_t rdclass, dns_rdatatype_t type, unsigned int options, isc_task_t *task, isc_taskaction_t action, void *arg, dns_clientrestrans_t **transp); /*%< * Perform name resolution for 'name', 'rdclass', and 'type'. * * If any trusted keys are configured and the query name is considered to * belong to a secure zone, these functions also validate the responses * using DNSSEC by default. If the DNS_CLIENTRESOPT_NODNSSEC flag is set * in 'options', DNSSEC validation is disabled regardless of the configured * trusted keys or the query name. * * dns_client_resolve() provides a synchronous service. This function starts * name resolution internally and blocks until it completes. On success, * 'namelist' will contain a list of answer names, each of which has * corresponding RRsets. The caller must provide a valid empty list, and * is responsible for freeing the list content via dns_client_freeresanswer(). * If the name resolution fails due to an error in DNSSEC validation, * dns_client_resolve() returns the result code indicating the validation * error. Otherwise, it returns the result code of the entire resolution * process, either success or failure. * * It is typically expected that the client object passed to * dns_client_resolve() was created via dns_client_create() and has its own * managers and contexts. However, if the DNS_CLIENTRESOPT_ALLOWRUN flag is * set in 'options', this function performs the synchronous service even if * it does not have its own manager and context structures. * * dns_client_startresolve() is an asynchronous version of dns_client_resolve() * and does not block. When name resolution is completed, 'action' will be * called with the argument of a 'dns_clientresevent_t' object, which contains * the resulting list of answer names (on success). On return, '*transp' is * set to an opaque transaction ID so that the caller can cancel this * resolution process. * * Requires: * *\li 'client' is a valid client. * *\li 'addrs' != NULL. * *\li 'name' is a valid name. * *\li 'namelist' != NULL and is not empty. * *\li 'task' is a valid task. * *\li 'transp' != NULL && *transp == NULL; * * Returns: * *\li #ISC_R_SUCCESS On success. * *\li Anything else Failure. */ void dns_client_cancelresolve(dns_clientrestrans_t *trans); /*%< * Cancel an ongoing resolution procedure started via * dns_client_startresolve(). * * Notes: * *\li If the resolution procedure has not completed, post its CLIENTRESDONE * event with a result code of #ISC_R_CANCELED. * * Requires: * *\li 'trans' is a valid transaction ID. */ void dns_client_destroyrestrans(dns_clientrestrans_t **transp); /*%< * Destroy name resolution transaction state identified by '*transp'. * * Requires: * *\li '*transp' is a valid transaction ID. * *\li The caller has received the CLIENTRESDONE event (either because the * resolution completed or because dns_client_cancelresolve() was called). * * Ensures: * *\li *transp == NULL. */ void dns_client_freeresanswer(dns_client_t *client, dns_namelist_t *namelist); /*%< * Free resources allocated for the content of 'namelist'. * * Requires: * *\li 'client' is a valid client. * *\li 'namelist' != NULL. */ isc_result_t dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass, dns_name_t *keyname, isc_buffer_t *keydatabuf); /*%< * Add a DNSSEC trusted key for the 'rdclass' class. A view for the 'rdclass' * class must be created beforehand. 'keyname' is the DNS name of the key, * and 'keydatabuf' stores the resource data of the key. * * Requires: * *\li 'client' is a valid client. * *\li 'keyname' is a valid name. * *\li 'keydatabuf' is a valid buffer. * * Returns: * *\li #ISC_R_SUCCESS On success. * *\li Anything else Failure. */ isc_result_t dns_client_request(dns_client_t *client, dns_message_t *qmessage, dns_message_t *rmessage, isc_sockaddr_t *server, unsigned int options, unsigned int parseoptions, dns_tsec_t *tsec, unsigned int timeout, unsigned int udptimeout, unsigned int udpretries); isc_result_t dns_client_startrequest(dns_client_t *client, dns_message_t *qmessage, dns_message_t *rmessage, isc_sockaddr_t *server, unsigned int options, unsigned int parseoptions, dns_tsec_t *tsec, unsigned int timeout, unsigned int udptimeout, unsigned int udpretries, isc_task_t *task, isc_taskaction_t action, void *arg, dns_clientreqtrans_t **transp); /*%< * Send a DNS request containig a query message 'query' to 'server'. * * 'parseoptions' will be used when the response packet is parsed, and will be * passed to dns_message_parse() via dns_request_getresponse(). See * dns_message_parse() for more details. * * 'tsec' is a transaction security object containing, e.g. a TSIG key for * authenticating the request/response transaction. This is optional and can * be NULL, in which case this library performs the transaction without any * transaction authentication. * * 'timeout', 'udptimeout', and 'udpretries' are passed to * dns_request_createvia3(). See dns_request_createvia3() for more details. * * dns_client_request() provides a synchronous service. This function sends * the request and blocks until a response is received. On success, * 'rmessage' will contain the response message. The caller must provide a * valid initialized message. * * It is usually expected that the client object passed to * dns_client_request() was created via dns_client_create() and has its own * managers and contexts. However, if the DNS_CLIENTREQOPT_ALLOWRUN flag is * set in 'options', this function performs the synchronous service even if * it does not have its own manager and context structures. * * dns_client_startrequest() is an asynchronous version of dns_client_request() * and does not block. When the transaction is completed, 'action' will be * called with the argument of a 'dns_clientreqevent_t' object, which contains * the response message (on success). On return, '*transp' is set to an opaque * transaction ID so that the caller can cancel this request. * * Requires: * *\li 'client' is a valid client. * *\li 'qmessage' and 'rmessage' are valid initialized message. * *\li 'server' is a valid socket address structure. * *\li 'task' is a valid task. * *\li 'transp' != NULL && *transp == NULL; * * Returns: * *\li #ISC_R_SUCCESS On success. * *\li Anything else Failure. * *\li Any result that dns_message_parse() can return. */ void dns_client_cancelrequest(dns_clientreqtrans_t *transp); /*%< * Cancel an ongoing DNS request procedure started via * dns_client_startrequest(). * * Notes: * *\li If the request procedure has not completed, post its CLIENTREQDONE * event with a result code of #ISC_R_CANCELED. * * Requires: * *\li 'trans' is a valid transaction ID. */ void dns_client_destroyreqtrans(dns_clientreqtrans_t **transp); /*% * Destroy DNS request transaction state identified by '*transp'. * * Requires: * *\li '*transp' is a valid transaction ID. * *\li The caller has received the CLIENTREQDONE event (either because the * request completed or because dns_client_cancelrequest() was called). * * Ensures: * *\li *transp == NULL. */ isc_result_t dns_client_update(dns_client_t *client, dns_rdataclass_t rdclass, dns_name_t *zonename, dns_namelist_t *prerequisites, dns_namelist_t *updates, isc_sockaddrlist_t *servers, dns_tsec_t *tsec, unsigned int options); isc_result_t dns_client_startupdate(dns_client_t *client, dns_rdataclass_t rdclass, dns_name_t *zonename, dns_namelist_t *prerequisites, dns_namelist_t *updates, isc_sockaddrlist_t *servers, dns_tsec_t *tsec, unsigned int options, isc_task_t *task, isc_taskaction_t action, void *arg, dns_clientupdatetrans_t **transp); /*%< * Perform DNS dynamic update for 'updates' of the 'rdclass' class with * optional 'prerequisites'. * * 'updates' are a list of names with associated RRsets to be updated. * * 'prerequisites' are a list of names with associated RRsets corresponding to * the prerequisites of the updates. This is optional and can be NULL, in * which case the prerequisite section of the update message will be empty. * * Both 'updates' and 'prerequisites' must be constructed as specified in * RFC2136. * * 'zonename' is the name of the zone in which the updated names exist. * This is optional and can be NULL. In this case, these functions internally * identify the appropriate zone through some queries for the SOA RR starting * with the first name in prerequisites or updates. * * 'servers' is a list of authoritative servers to which the update message * should be sent. This is optional and can be NULL. In this case, these * functions internally identify the appropriate primary server name and its * addresses through some queries for the SOA RR (like the case of zonename) * and supplemental A/AAAA queries for the server name. * Note: The client module generally assumes the given addresses are of the * primary server of the corresponding zone. It will work even if a secondary * server address is specified as long as the server allows update forwarding, * it is generally discouraged to include secondary server addresses unless * there's strong reason to do so. * * 'tsec' is a transaction security object containing, e.g. a TSIG key for * authenticating the update transaction (and the supplemental query/response * transactions if the server is specified). This is optional and can be * NULL, in which case the library tries the update without any transaction * authentication. * * dns_client_update() provides a synchronous service. This function blocks * until the entire update procedure completes, including the additional * queries when necessary. * * dns_client_startupdate() is an asynchronous version of dns_client_update(). * It immediately returns (typically with *transp being set to a non-NULL * pointer), and performs the update procedure through a set of internal * events. All transactions including the additional query exchanges are * performed as a separate event, so none of these events cause blocking * operation. When the update procedure completes, the specified function * 'action' will be called with the argument of a 'dns_clientupdateevent_t' * structure. On return, '*transp' is set to an opaque transaction ID so that * the caller can cancel this update process. * * Notes: *\li No options are currently defined. * * Requires: * *\li 'client' is a valid client. * *\li 'updates' != NULL. * *\li 'task' is a valid task. * *\li 'transp' != NULL && *transp == NULL; * * Returns: * *\li #ISC_R_SUCCESS On success. * *\li Anything else Failure. */ void dns_client_cancelupdate(dns_clientupdatetrans_t *trans); /*%< * Cancel an ongoing dynamic update procedure started via * dns_client_startupdate(). * * Notes: * *\li If the update procedure has not completed, post its UPDATEDONE * event with a result code of #ISC_R_CANCELED. * * Requires: * *\li 'trans' is a valid transaction ID. */ void dns_client_destroyupdatetrans(dns_clientupdatetrans_t **transp); /*%< * Destroy dynamic update transaction identified by '*transp'. * * Requires: * *\li '*transp' is a valid transaction ID. * *\li The caller has received the UPDATEDONE event (either because the * update completed or because dns_client_cancelupdate() was called). * * Ensures: * *\li *transp == NULL. */ isc_result_t dns_client_updaterec(dns_client_updateop_t op, dns_name_t *owner, dns_rdatatype_t type, dns_rdata_t *source, dns_ttl_t ttl, dns_name_t *target, dns_rdataset_t *rdataset, dns_rdatalist_t *rdatalist, dns_rdata_t *rdata, isc_mem_t *mctx); /*%< * TBD */ void dns_client_freeupdate(dns_name_t **namep); /*%< * TBD */ isc_mem_t * dns_client_mctx(dns_client_t *client); ISC_LANG_ENDDECLS #endif /* DNS_CLIENT_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/sdb.h0000644000470500017500000001710012664710322020052 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: sdb.h,v 1.25 2011/10/11 23:46:45 tbox Exp $ */ #ifndef DNS_SDB_H #define DNS_SDB_H 1 /***** ***** Module Info *****/ /*! \file dns/sdb.h * \brief * Simple database API. */ /*** *** Imports ***/ #include #include #include /*** *** Types ***/ /*% * A simple database. This is an opaque type. */ typedef struct dns_sdb dns_sdb_t; /*% * A simple database lookup in progress. This is an opaque type. */ typedef struct dns_sdblookup dns_sdblookup_t; /*% * A simple database traversal in progress. This is an opaque type. */ typedef struct dns_sdballnodes dns_sdballnodes_t; typedef isc_result_t (*dns_sdblookupfunc_t)(const char *zone, const char *name, void *dbdata, dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo); typedef isc_result_t (*dns_sdblookup2func_t)(const dns_name_t *zone, const dns_name_t *name, void *dbdata, dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo); typedef isc_result_t (*dns_sdbauthorityfunc_t)(const char *zone, void *dbdata, dns_sdblookup_t *); typedef isc_result_t (*dns_sdballnodesfunc_t)(const char *zone, void *dbdata, dns_sdballnodes_t *allnodes); typedef isc_result_t (*dns_sdbcreatefunc_t)(const char *zone, int argc, char **argv, void *driverdata, void **dbdata); typedef void (*dns_sdbdestroyfunc_t)(const char *zone, void *driverdata, void **dbdata); typedef struct dns_sdbmethods { dns_sdblookupfunc_t lookup; dns_sdbauthorityfunc_t authority; dns_sdballnodesfunc_t allnodes; dns_sdbcreatefunc_t create; dns_sdbdestroyfunc_t destroy; dns_sdblookup2func_t lookup2; } dns_sdbmethods_t; /*** *** Functions ***/ ISC_LANG_BEGINDECLS #define DNS_SDBFLAG_RELATIVEOWNER 0x00000001U #define DNS_SDBFLAG_RELATIVERDATA 0x00000002U #define DNS_SDBFLAG_THREADSAFE 0x00000004U #define DNS_SDBFLAG_DNS64 0x00000008U isc_result_t dns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods, void *driverdata, unsigned int flags, isc_mem_t *mctx, dns_sdbimplementation_t **sdbimp); /*%< * Register a simple database driver for the database type 'drivername', * implemented by the functions in '*methods'. * * sdbimp must point to a NULL dns_sdbimplementation_t pointer. That is, * sdbimp != NULL && *sdbimp == NULL. It will be assigned a value that * will later be used to identify the driver when deregistering it. * * The name server will perform lookups in the database by calling the * function 'lookup', passing it a printable zone name 'zone', a printable * domain name 'name', and a copy of the argument 'dbdata' that * was potentially returned by the create function. The 'dns_sdblookup_t' * argument to 'lookup' and 'authority' is an opaque pointer to be passed to * ns_sdb_putrr(). * * The lookup function returns the lookup results to the name server * by calling ns_sdb_putrr() once for each record found. On success, * the return value of the lookup function should be ISC_R_SUCCESS. * If the domain name 'name' does not exist, the lookup function should * ISC_R_NOTFOUND. Any other return value is treated as an error. * * Lookups at the zone apex will cause the server to also call the * function 'authority' (if non-NULL), which must provide an SOA record * and NS records for the zone by calling ns_sdb_putrr() once for each of * these records. The 'authority' function may be NULL if invoking * the 'lookup' function on the zone apex will return SOA and NS records. * * The allnodes function, if non-NULL, fills in an opaque structure to be * used by a database iterator. This allows the zone to be transferred. * This may use a considerable amount of memory for large zones, and the * zone transfer may not be fully RFC1035 compliant if the zone is * frequently changed. * * The create function will be called for each zone configured * into the name server using this database type. It can be used * to create a "database object" containing zone specific data, * which can make use of the database arguments specified in the * name server configuration. * * The destroy function will be called to free the database object * when its zone is destroyed. * * The create and destroy functions may be NULL. * * If flags includes DNS_SDBFLAG_RELATIVEOWNER, the lookup and authority * functions will be called with relative names rather than absolute names. * The string "@" represents the zone apex in this case. * * If flags includes DNS_SDBFLAG_RELATIVERDATA, the rdata strings may * include relative names. Otherwise, all names in the rdata string must * be absolute. Be aware that if relative names are allowed, any * absolute names must contain a trailing dot. * * If flags includes DNS_SDBFLAG_THREADSAFE, the driver must be able to * handle multiple lookups in parallel. Otherwise, calls into the driver * are serialized. */ void dns_sdb_unregister(dns_sdbimplementation_t **sdbimp); /*%< * Removes the simple database driver from the list of registered database * types. There must be no active databases of this type when this function * is called. */ /*% See dns_sdb_putradata() */ isc_result_t dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl, const char *data); isc_result_t dns_sdb_putrdata(dns_sdblookup_t *lookup, dns_rdatatype_t type, dns_ttl_t ttl, const unsigned char *rdata, unsigned int rdlen); /*%< * Add a single resource record to the lookup structure to be * returned in the query response. dns_sdb_putrr() takes the * resource record in master file text format as a null-terminated * string, and dns_sdb_putrdata() takes the raw RDATA in * uncompressed wire format. */ /*% See dns_sdb_putnamerdata() */ isc_result_t dns_sdb_putnamedrr(dns_sdballnodes_t *allnodes, const char *name, const char *type, dns_ttl_t ttl, const char *data); isc_result_t dns_sdb_putnamedrdata(dns_sdballnodes_t *allnodes, const char *name, dns_rdatatype_t type, dns_ttl_t ttl, const void *rdata, unsigned int rdlen); /*%< * Add a single resource record to the allnodes structure to be * included in a zone transfer response, in text or wire * format as above. */ isc_result_t dns_sdb_putsoa(dns_sdblookup_t *lookup, const char *mname, const char *rname, isc_uint32_t serial); /*%< * This function may optionally be called from the 'authority' callback * to simplify construction of the SOA record for 'zone'. It will * provide a SOA listing 'mname' as as the master server and 'rname' as * the responsible person mailbox. It is the responsibility of the * driver to increment the serial number between responses if necessary. * All other SOA fields will have reasonable default values. */ ISC_LANG_ENDDECLS #endif /* DNS_SDB_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/master.h0000644000470500017500000002715712664710322020612 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: master.h,v 1.57.8.1 2012/02/07 00:44:16 each Exp $ */ #ifndef DNS_MASTER_H #define DNS_MASTER_H 1 /*! \file dns/master.h */ /*** *** Imports ***/ #include #include #include /* * Flags to be passed in the 'options' argument in the functions below. */ #define DNS_MASTER_AGETTL 0x00000001 /*%< Age the ttl based on $DATE. */ #define DNS_MASTER_MANYERRORS 0x00000002 /*%< Continue processing on errors. */ #define DNS_MASTER_NOINCLUDE 0x00000004 /*%< Disallow $INCLUDE directives. */ #define DNS_MASTER_ZONE 0x00000008 /*%< Loading a zone master file. */ #define DNS_MASTER_HINT 0x00000010 /*%< Loading a hint master file. */ #define DNS_MASTER_SLAVE 0x00000020 /*%< Loading a slave master file. */ #define DNS_MASTER_CHECKNS 0x00000040 /*%< * Check NS records to see * if they are an address */ #define DNS_MASTER_FATALNS 0x00000080 /*%< * Treat DNS_MASTER_CHECKNS * matches as fatal */ #define DNS_MASTER_CHECKNAMES 0x00000100 #define DNS_MASTER_CHECKNAMESFAIL 0x00000200 #define DNS_MASTER_CHECKWILDCARD 0x00000400 /* Check for internal wildcards. */ #define DNS_MASTER_CHECKMX 0x00000800 #define DNS_MASTER_CHECKMXFAIL 0x00001000 #define DNS_MASTER_RESIGN 0x00002000 #define DNS_MASTER_KEY 0x00004000 /*%< Loading a key zone master file. */ #define DNS_MASTER_NOTTL 0x00008000 /*%< Don't require ttl. */ #define DNS_MASTER_CHECKTTL 0x00010000 /*%< Check max-zone-ttl */ ISC_LANG_BEGINDECLS /* * Structures that implement the "raw" format for master dump. * These are provided for a reference purpose only; in the actual * encoding, we directly read/write each field so that the encoded data * is always "packed", regardless of the hardware architecture. */ #define DNS_RAWFORMAT_VERSION 1 /* * Flags to indicate the status of the data in the raw file header */ #define DNS_MASTERRAW_COMPAT 0x01 #define DNS_MASTERRAW_SOURCESERIALSET 0x02 #define DNS_MASTERRAW_LASTXFRINSET 0x04 /* Common header */ struct dns_masterrawheader { isc_uint32_t format; /* must be * dns_masterformat_raw * or * dns_masterformat_map */ isc_uint32_t version; /* compatibility for future * extensions */ isc_uint32_t dumptime; /* timestamp on creation * (currently unused) */ isc_uint32_t flags; /* Flags */ isc_uint32_t sourceserial; /* Source serial number (used * by inline-signing zones) */ isc_uint32_t lastxfrin; /* timestamp of last transfer * (used by slave zones) */ }; /* The structure for each RRset */ typedef struct { isc_uint32_t totallen; /* length of the data for this * RRset, including the * "header" part */ dns_rdataclass_t rdclass; /* 16-bit class */ dns_rdatatype_t type; /* 16-bit type */ dns_rdatatype_t covers; /* same as type */ dns_ttl_t ttl; /* 32-bit TTL */ isc_uint32_t nrdata; /* number of RRs in this set */ /* followed by encoded owner name, and then rdata */ } dns_masterrawrdataset_t; /* * Method prototype: a callback to register each include file as * it is encountered. */ typedef void (*dns_masterincludecb_t)(const char *file, void *arg); /*** *** Function ***/ isc_result_t dns_master_loadfile(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx); isc_result_t dns_master_loadfile2(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx, dns_masterformat_t format); isc_result_t dns_master_loadfile3(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, isc_uint32_t resign, dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx, dns_masterformat_t format); isc_result_t dns_master_loadfile4(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, isc_uint32_t resign, dns_rdatacallbacks_t *callbacks, dns_masterincludecb_t include_cb, void *include_arg, isc_mem_t *mctx, dns_masterformat_t format); isc_result_t dns_master_loadfile5(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, isc_uint32_t resign, dns_rdatacallbacks_t *callbacks, dns_masterincludecb_t include_cb, void *include_arg, isc_mem_t *mctx, dns_masterformat_t format, dns_ttl_t maxttl); isc_result_t dns_master_loadstream(FILE *stream, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx); isc_result_t dns_master_loadbuffer(isc_buffer_t *buffer, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx); isc_result_t dns_master_loadlexer(isc_lex_t *lex, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx); isc_result_t dns_master_loadfileinc(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_task_t *task, dns_loaddonefunc_t done, void *done_arg, dns_loadctx_t **ctxp, isc_mem_t *mctx); isc_result_t dns_master_loadfileinc2(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_task_t *task, dns_loaddonefunc_t done, void *done_arg, dns_loadctx_t **ctxp, isc_mem_t *mctx, dns_masterformat_t format); isc_result_t dns_master_loadfileinc3(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, isc_uint32_t resign, dns_rdatacallbacks_t *callbacks, isc_task_t *task, dns_loaddonefunc_t done, void *done_arg, dns_loadctx_t **ctxp, isc_mem_t *mctx, dns_masterformat_t format); isc_result_t dns_master_loadfileinc4(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, isc_uint32_t resign, dns_rdatacallbacks_t *callbacks, isc_task_t *task, dns_loaddonefunc_t done, void *done_arg, dns_loadctx_t **ctxp, dns_masterincludecb_t include_cb, void *include_arg, isc_mem_t *mctx, dns_masterformat_t format); isc_result_t dns_master_loadfileinc5(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, isc_uint32_t resign, dns_rdatacallbacks_t *callbacks, isc_task_t *task, dns_loaddonefunc_t done, void *done_arg, dns_loadctx_t **ctxp, dns_masterincludecb_t include_cb, void *include_arg, isc_mem_t *mctx, dns_masterformat_t format, isc_uint32_t maxttl); isc_result_t dns_master_loadstreaminc(FILE *stream, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_task_t *task, dns_loaddonefunc_t done, void *done_arg, dns_loadctx_t **ctxp, isc_mem_t *mctx); isc_result_t dns_master_loadbufferinc(isc_buffer_t *buffer, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_task_t *task, dns_loaddonefunc_t done, void *done_arg, dns_loadctx_t **ctxp, isc_mem_t *mctx); isc_result_t dns_master_loadlexerinc(isc_lex_t *lex, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_task_t *task, dns_loaddonefunc_t done, void *done_arg, dns_loadctx_t **ctxp, isc_mem_t *mctx); /*%< * Loads a RFC1305 master file from a file, stream, buffer, or existing * lexer into rdatasets and then calls 'callbacks->commit' to commit the * rdatasets. Rdata memory belongs to dns_master_load and will be * reused / released when the callback completes. dns_load_master will * abort if callbacks->commit returns any value other than ISC_R_SUCCESS. * * If 'DNS_MASTER_AGETTL' is set and the master file contains one or more * $DATE directives, the TTLs of the data will be aged accordingly. * * 'callbacks->commit' is assumed to call 'callbacks->error' or * 'callbacks->warn' to generate any error messages required. * * 'done' is called with 'done_arg' and a result code when the loading * is completed or has failed. If the initial setup fails 'done' is * not called. * * 'resign' the number of seconds before a RRSIG expires that it should * be re-signed. 0 is used if not provided. * * Requires: *\li 'master_file' points to a valid string. *\li 'lexer' points to a valid lexer. *\li 'top' points to a valid name. *\li 'origin' points to a valid name. *\li 'callbacks->commit' points to a valid function. *\li 'callbacks->error' points to a valid function. *\li 'callbacks->warn' points to a valid function. *\li 'mctx' points to a valid memory context. *\li 'task' and 'done' to be valid. *\li 'lmgr' to be valid. *\li 'ctxp != NULL && ctxp == NULL'. * * Returns: *\li ISC_R_SUCCESS upon successfully loading the master file. *\li ISC_R_SEENINCLUDE upon successfully loading the master file with * a $INCLUDE statement. *\li ISC_R_NOMEMORY out of memory. *\li ISC_R_UNEXPECTEDEND expected to be able to read a input token and * there was not one. *\li ISC_R_UNEXPECTED *\li DNS_R_NOOWNER failed to specify a ownername. *\li DNS_R_NOTTL failed to specify a ttl. *\li DNS_R_BADCLASS record class did not match zone class. *\li DNS_R_CONTINUE load still in progress (dns_master_load*inc() only). *\li Any dns_rdata_fromtext() error code. *\li Any error code from callbacks->commit(). */ void dns_loadctx_detach(dns_loadctx_t **ctxp); /*%< * Detach from the load context. * * Requires: *\li '*ctxp' to be valid. * * Ensures: *\li '*ctxp == NULL' */ void dns_loadctx_attach(dns_loadctx_t *source, dns_loadctx_t **target); /*%< * Attach to the load context. * * Requires: *\li 'source' to be valid. *\li 'target != NULL && *target == NULL'. */ void dns_loadctx_cancel(dns_loadctx_t *ctx); /*%< * Cancel loading the zone file associated with this load context. * * Requires: *\li 'ctx' to be valid */ void dns_master_initrawheader(dns_masterrawheader_t *header); /*%< * Initializes the header for a raw master file, setting all * values to zero. */ ISC_LANG_ENDDECLS #endif /* DNS_MASTER_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/secalg.h0000644000470500017500000000427312664710322020547 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: secalg.h,v 1.21 2009/10/12 23:48:02 tbox Exp $ */ #ifndef DNS_SECALG_H #define DNS_SECALG_H 1 /*! \file dns/secalg.h */ #include #include ISC_LANG_BEGINDECLS isc_result_t dns_secalg_fromtext(dns_secalg_t *secalgp, isc_textregion_t *source); /*%< * Convert the text 'source' refers to into a DNSSEC security algorithm value. * The text may contain either a mnemonic algorithm name or a decimal algorithm * number. * * Requires: *\li 'secalgp' is a valid pointer. * *\li 'source' is a valid text region. * * Returns: *\li ISC_R_SUCCESS on success *\li ISC_R_RANGE numeric type is out of range *\li DNS_R_UNKNOWN mnemonic type is unknown */ isc_result_t dns_secalg_totext(dns_secalg_t secalg, isc_buffer_t *target); /*%< * Put a textual representation of the DNSSEC security algorithm 'secalg' * into 'target'. * * Requires: *\li 'secalg' is a valid secalg. * *\li 'target' is a valid text buffer. * * Ensures, * if the result is success: *\li The used space in 'target' is updated. * * Returns: *\li ISC_R_SUCCESS on success *\li ISC_R_NOSPACE target buffer is too small */ #define DNS_SECALG_FORMATSIZE 20 void dns_secalg_format(dns_secalg_t alg, char *cp, unsigned int size); /*%< * Wrapper for dns_secalg_totext(), writing text into 'cp' */ ISC_LANG_ENDDECLS #endif /* DNS_SECALG_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/dlz.h0000644000470500017500000002556312664710322020107 0ustar lamontlamont/* * Portions Copyright (C) 2005-2007, 2009-2013 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all * copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE * USE OR PERFORMANCE OF THIS SOFTWARE. * * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was * conceived and contributed by Rob Butler. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all * copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * ROB BUTLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE * USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file dns/dlz.h */ #ifndef DLZ_H #define DLZ_H 1 /***** ***** Module Info *****/ /* * DLZ Interface * * The DLZ interface allows zones to be looked up using a driver instead of * Bind's default in memory zone table. * * * Reliability: * No anticipated impact. * * Resources: * * Security: * No anticipated impact. * * Standards: * None. */ /***** ***** Imports *****/ #include #include #include #include #include #include ISC_LANG_BEGINDECLS /*** *** Types ***/ #define DNS_DLZ_MAGIC ISC_MAGIC('D','L','Z','D') #define DNS_DLZ_VALID(dlz) ISC_MAGIC_VALID(dlz, DNS_DLZ_MAGIC) typedef isc_result_t (*dns_dlzallowzonexfr_t)(void *driverarg, void *dbdata, isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_name_t *name, isc_sockaddr_t *clientaddr, dns_db_t **dbp); /*%< * Method prototype. Drivers implementing the DLZ interface MUST * supply an allow zone transfer method. This method is called when * the DNS server is performing a zone transfer query. The driver's * method should return ISC_R_SUCCESS and a database pointer to the * name server if the zone is supported by the database, and zone * transfer is allowed. Otherwise it will return ISC_R_NOTFOUND if * the zone is not supported by the database, or ISC_R_NOPERM if zone * transfers are not allowed. If an error occurs it should return a * result code indicating the type of error. */ typedef isc_result_t (*dns_dlzcreate_t)(isc_mem_t *mctx, const char *dlzname, unsigned int argc, char *argv[], void *driverarg, void **dbdata); /*%< * Method prototype. Drivers implementing the DLZ interface MUST * supply a create method. This method is called when the DNS server * is starting up and creating drivers for use later. */ typedef void (*dns_dlzdestroy_t)(void *driverarg, void **dbdata); /*%< * Method prototype. Drivers implementing the DLZ interface MUST * supply a destroy method. This method is called when the DNS server * is shutting down and no longer needs the driver. */ typedef isc_result_t (*dns_dlzfindzone_t)(void *driverarg, void *dbdata, isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_name_t *name, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, dns_db_t **dbp); /*%< * Method prototype. Drivers implementing the DLZ interface MUST * supply a find zone method. This method is called when the DNS * server is performing a query. The find zone method will be called * with the longest possible name first, and continue to be called * with successively shorter domain names, until any of the following * occur: * * \li 1) a match is found, and the function returns (ISC_R_SUCCESS) * * \li 2) a problem occurs, and the functions returns anything other * than (ISC_R_NOTFOUND) * \li 3) we run out of domain name labels. I.E. we have tried the * shortest domain name * \li 4) the number of labels in the domain name is less than * min_labels for dns_dlzfindzone * * The driver's find zone method should return ISC_R_SUCCESS and a * database pointer to the name server if the zone is supported by the * database. Otherwise it will return ISC_R_NOTFOUND, and a null * pointer if the zone is not supported. If an error occurs it should * return a result code indicating the type of error. */ typedef isc_result_t (*dns_dlzconfigure_t)(void *driverarg, void *dbdata, dns_view_t *view, dns_dlzdb_t *dlzdb); /*%< * Method prototype. Drivers implementing the DLZ interface may * optionally supply a configure method. If supplied, this will be * called immediately after the create method is called. The driver * may call configuration functions during the configure call */ typedef isc_boolean_t (*dns_dlzssumatch_t)(dns_name_t *signer, dns_name_t *name, isc_netaddr_t *tcpaddr, dns_rdatatype_t type, const dst_key_t *key, void *driverarg, void *dbdata); /*%< * Method prototype. Drivers implementing the DLZ interface may * optionally supply a ssumatch method. If supplied, this will be * called to authorize update requests */ /*% the methods supplied by a DLZ driver */ typedef struct dns_dlzmethods { dns_dlzcreate_t create; dns_dlzdestroy_t destroy; dns_dlzfindzone_t findzone; dns_dlzallowzonexfr_t allowzonexfr; dns_dlzconfigure_t configure; dns_dlzssumatch_t ssumatch; } dns_dlzmethods_t; /*% information about a DLZ driver */ struct dns_dlzimplementation { const char *name; const dns_dlzmethods_t *methods; isc_mem_t *mctx; void *driverarg; ISC_LINK(dns_dlzimplementation_t) link; }; typedef isc_result_t (*dlzconfigure_callback_t)(dns_view_t *, dns_dlzdb_t *, dns_zone_t *); /*% An instance of a DLZ driver */ struct dns_dlzdb { unsigned int magic; isc_mem_t *mctx; dns_dlzimplementation_t *implementation; void *dbdata; dlzconfigure_callback_t configure_callback; isc_boolean_t search; char *dlzname; ISC_LINK(dns_dlzdb_t) link; dns_ssutable_t *ssutable; }; /*** *** Method declarations ***/ isc_result_t dns_dlzallowzonexfr(dns_view_t *view, dns_name_t *name, isc_sockaddr_t *clientaddr, dns_db_t **dbp); /*%< * This method is called when the DNS server is performing a zone * transfer query. It will call the DLZ driver's allow zone transfer * method. */ isc_result_t dns_dlzcreate(isc_mem_t *mctx, const char *dlzname, const char *drivername, unsigned int argc, char *argv[], dns_dlzdb_t **dbp); /*%< * This method is called when the DNS server is starting up and * creating drivers for use later. It will search the DLZ driver list * for 'drivername' and return a DLZ driver via dbp if a match is * found. If the DLZ driver supplies a create method, this function * will call it. */ void dns_dlzdestroy(dns_dlzdb_t **dbp); /*%< * This method is called when the DNS server is shutting down and no * longer needs the driver. If the DLZ driver supplies a destroy * methods, this function will call it. */ isc_result_t dns_dlzregister(const char *drivername, const dns_dlzmethods_t *methods, void *driverarg, isc_mem_t *mctx, dns_dlzimplementation_t **dlzimp); /*%< * Register a dynamically loadable zones (DLZ) driver for the database * type 'drivername', implemented by the functions in '*methods'. * * dlzimp must point to a NULL dlz_implementation_t pointer. That is, * dlzimp != NULL && *dlzimp == NULL. It will be assigned a value that * will later be used to identify the driver when deregistering it. */ isc_result_t dns_dlzstrtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp, char ***argvp); /*%< * This method is called when the name server is starting up to parse * the DLZ driver command line from named.conf. Basically it splits * up a string into and argc / argv. The primary difference of this * method is items between braces { } are considered only 1 word. for * example the command line "this is { one grouped phrase } and this * isn't" would be parsed into: * * \li argv[0]: "this" * \li argv[1]: "is" * \li argv{2]: " one grouped phrase " * \li argv[3]: "and" * \li argv[4]: "this" * \li argv{5}: "isn't" * * braces should NOT be nested, more than one grouping in the command * line is allowed. Notice, argv[2] has an extra space at the * beginning and end. Extra spaces are not stripped between a * grouping. You can do so in your driver if needed, or be sure not * to put extra spaces before / after the braces. */ void dns_dlzunregister(dns_dlzimplementation_t **dlzimp); /*%< * Removes the dlz driver from the list of registered dlz drivers. * There must be no active dlz drivers of this type when this function * is called. */ typedef isc_result_t dns_dlz_writeablezone_t(dns_view_t *view, dns_dlzdb_t *dlzdb, const char *zone_name); dns_dlz_writeablezone_t dns_dlz_writeablezone; /*%< * creates a writeable DLZ zone. Must be called from within the * configure() method of a DLZ driver. */ isc_result_t dns_dlzconfigure(dns_view_t *view, dns_dlzdb_t *dlzdb, dlzconfigure_callback_t callback); /*%< * call a DLZ drivers configure method, if supplied */ isc_boolean_t dns_dlz_ssumatch(dns_dlzdb_t *dlzdatabase, dns_name_t *signer, dns_name_t *name, isc_netaddr_t *tcpaddr, dns_rdatatype_t type, const dst_key_t *key); /*%< * call a DLZ drivers ssumatch method, if supplied. Otherwise return ISC_FALSE */ ISC_LANG_ENDDECLS #endif /* DLZ_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/diff.h0000644000470500017500000001652412664710322020223 0ustar lamontlamont/* * Copyright (C) 2004-2010, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: diff.h,v 1.19 2010/06/04 23:51:14 tbox Exp $ */ #ifndef DNS_DIFF_H #define DNS_DIFF_H 1 /***** ***** Module Info *****/ /*! \file dns/diff.h * \brief * A diff is a convenience type representing a list of changes to be * made to a database. */ /*** *** Imports ***/ #include #include #include #include #include /*** *** Types ***/ /*% * A dns_difftuple_t represents a single RR being added or deleted. * The RR type and class are in the 'rdata' member; the class is always * the real one, not a DynDNS meta-class, so that the rdatas can be * compared using dns_rdata_compare(). The TTL is significant * even for deletions, because a deletion/addition pair cannot * be canceled out if the TTL differs (it might be an explicit * TTL update). * * Tuples are also used to represent complete RRs with owner * names for a couple of other purposes, such as the * individual RRs of a "RRset exists (value dependent)" * prerequisite set. In this case, op==DNS_DIFFOP_EXISTS, * and the TTL is ignored. * * DNS_DIFFOP_*RESIGN will cause the 'resign' attribute of the resulting * RRset to be recomputed to be 'resign' seconds before the earliest RRSIG * timeexpire. */ typedef enum { DNS_DIFFOP_ADD = 0, /*%< Add an RR. */ DNS_DIFFOP_DEL = 1, /*%< Delete an RR. */ DNS_DIFFOP_EXISTS = 2, /*%< Assert RR existence. */ DNS_DIFFOP_ADDRESIGN = 4, /*%< ADD + RESIGN. */ DNS_DIFFOP_DELRESIGN = 5 /*%< DEL + RESIGN. */ } dns_diffop_t; typedef struct dns_difftuple dns_difftuple_t; #define DNS_DIFFTUPLE_MAGIC ISC_MAGIC('D','I','F','T') #define DNS_DIFFTUPLE_VALID(t) ISC_MAGIC_VALID(t, DNS_DIFFTUPLE_MAGIC) struct dns_difftuple { unsigned int magic; isc_mem_t *mctx; dns_diffop_t op; dns_name_t name; dns_ttl_t ttl; dns_rdata_t rdata; ISC_LINK(dns_difftuple_t) link; /* Variable-size name data and rdata follows. */ }; /*% * A dns_diff_t represents a set of changes being applied to * a zone. Diffs are also used to represent "RRset exists * (value dependent)" prerequisites. */ typedef struct dns_diff dns_diff_t; #define DNS_DIFF_MAGIC ISC_MAGIC('D','I','F','F') #define DNS_DIFF_VALID(t) ISC_MAGIC_VALID(t, DNS_DIFF_MAGIC) struct dns_diff { unsigned int magic; isc_mem_t * mctx; ISC_LIST(dns_difftuple_t) tuples; }; /* Type of comparison function for sorting diffs. */ typedef int dns_diff_compare_func(const void *, const void *); /*** *** Functions ***/ ISC_LANG_BEGINDECLS /**************************************************************************/ /* * Manipulation of diffs and tuples. */ isc_result_t dns_difftuple_create(isc_mem_t *mctx, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata, dns_difftuple_t **tp); /*%< * Create a tuple. Deep copies are made of the name and rdata, so * they need not remain valid after the call. * * Requires: *\li *tp != NULL && *tp == NULL. * * Returns: *\li ISC_R_SUCCESS * \li ISC_R_NOMEMORY */ void dns_difftuple_free(dns_difftuple_t **tp); /*%< * Free a tuple. * * Requires: * \li **tp is a valid tuple. * * Ensures: * \li *tp == NULL * \li All memory used by the tuple is freed. */ isc_result_t dns_difftuple_copy(dns_difftuple_t *orig, dns_difftuple_t **copyp); /*%< * Copy a tuple. * * Requires: * \li 'orig' points to a valid tuple *\li copyp != NULL && *copyp == NULL */ void dns_diff_init(isc_mem_t *mctx, dns_diff_t *diff); /*%< * Initialize a diff. * * Requires: * \li 'diff' points to an uninitialized dns_diff_t * \li allocated by the caller. * * Ensures: * \li '*diff' is a valid, empty diff. */ void dns_diff_clear(dns_diff_t *diff); /*%< * Clear a diff, destroying all its tuples. * * Requires: * \li 'diff' points to a valid dns_diff_t. * * Ensures: * \li Any tuples in the diff are destroyed. * The diff now empty, but it is still valid * and may be reused without calling dns_diff_init * again. The only memory used is that of the * dns_diff_t structure itself. * * Notes: * \li Managing the memory of the dns_diff_t structure itself * is the caller's responsibility. */ void dns_diff_append(dns_diff_t *diff, dns_difftuple_t **tuple); /*%< * Append a single tuple to a diff. * *\li 'diff' is a valid diff. * \li '*tuple' is a valid tuple. * * Ensures: *\li *tuple is NULL. *\li The tuple has been freed, or will be freed when the diff is cleared. */ void dns_diff_appendminimal(dns_diff_t *diff, dns_difftuple_t **tuple); /*%< * Append 'tuple' to 'diff', removing any duplicate * or conflicting updates as needed to create a minimal diff. * * Requires: *\li 'diff' is a minimal diff. * * Ensures: *\li 'diff' is still a minimal diff. * \li *tuple is NULL. * \li The tuple has been freed, or will be freed when the diff is cleared. * */ isc_result_t dns_diff_sort(dns_diff_t *diff, dns_diff_compare_func *compare); /*%< * Sort 'diff' in-place according to the comparison function 'compare'. */ isc_result_t dns_diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver); isc_result_t dns_diff_applysilently(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver); /*%< * Apply 'diff' to the database 'db'. * * dns_diff_apply() logs warnings about updates with no effect or * with inconsistent TTLs; dns_diff_applysilently() does not. * * For efficiency, the diff should be sorted by owner name. * If it is not sorted, operation will still be correct, * but less efficient. * * Requires: *\li *diff is a valid diff (possibly empty), containing * tuples of type #DNS_DIFFOP_ADD and/or * For #DNS_DIFFOP_DEL tuples, the TTL is ignored. * */ isc_result_t dns_diff_load(dns_diff_t *diff, dns_addrdatasetfunc_t addfunc, void *add_private); /*%< * Like dns_diff_apply, but for use when loading a new database * instead of modifying an existing one. This bypasses the * database transaction mechanisms. * * Requires: *\li 'addfunc' is a valid dns_addradatasetfunc_t obtained from * dns_db_beginload() * *\li 'add_private' points to a corresponding dns_dbload_t * * (XXX why is it a void pointer, then?) */ isc_result_t dns_diff_print(dns_diff_t *diff, FILE *file); /*%< * Print the differences to 'file' or if 'file' is NULL via the * logging system. * * Require: *\li 'diff' to be valid. *\li 'file' to refer to a open file or NULL. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li #ISC_R_UNEXPECTED *\li any error from dns_rdataset_totext() */ ISC_LANG_ENDDECLS #endif /* DNS_DIFF_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/keytable.h0000644000470500017500000002374412664710322021115 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: keytable.h,v 1.23 2010/06/25 03:24:05 marka Exp $ */ #ifndef DNS_KEYTABLE_H #define DNS_KEYTABLE_H 1 /***** ***** Module Info *****/ /*! \file * \brief * The keytable module provides services for storing and retrieving DNSSEC * trusted keys, as well as the ability to find the deepest matching key * for a given domain name. * * MP: *\li The module ensures appropriate synchronization of data structures it * creates and manipulates. * * Resources: *\li TBS * * Security: *\li No anticipated impact. */ #include #include #include #include #include #include #include ISC_LANG_BEGINDECLS struct dns_keytable { /* Unlocked. */ unsigned int magic; isc_mem_t *mctx; isc_mutex_t lock; isc_rwlock_t rwlock; /* Locked by lock. */ isc_uint32_t active_nodes; /* Locked by rwlock. */ isc_uint32_t references; dns_rbt_t *table; }; #define KEYTABLE_MAGIC ISC_MAGIC('K', 'T', 'b', 'l') #define VALID_KEYTABLE(kt) ISC_MAGIC_VALID(kt, KEYTABLE_MAGIC) struct dns_keynode { unsigned int magic; isc_refcount_t refcount; dst_key_t * key; isc_boolean_t managed; struct dns_keynode * next; }; #define KEYNODE_MAGIC ISC_MAGIC('K', 'N', 'o', 'd') #define VALID_KEYNODE(kn) ISC_MAGIC_VALID(kn, KEYNODE_MAGIC) isc_result_t dns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep); /*%< * Create a keytable. * * Requires: * *\li 'mctx' is a valid memory context. * *\li keytablep != NULL && *keytablep == NULL * * Ensures: * *\li On success, *keytablep is a valid, empty key table. * * Returns: * *\li ISC_R_SUCCESS * *\li Any other result indicates failure. */ void dns_keytable_attach(dns_keytable_t *source, dns_keytable_t **targetp); /*%< * Attach *targetp to source. * * Requires: * *\li 'source' is a valid keytable. * *\li 'targetp' points to a NULL dns_keytable_t *. * * Ensures: * *\li *targetp is attached to source. */ void dns_keytable_detach(dns_keytable_t **keytablep); /*%< * Detach *keytablep from its keytable. * * Requires: * *\li 'keytablep' points to a valid keytable. * * Ensures: * *\li *keytablep is NULL. * *\li If '*keytablep' is the last reference to the keytable, * all resources used by the keytable will be freed */ isc_result_t dns_keytable_add(dns_keytable_t *keytable, isc_boolean_t managed, dst_key_t **keyp); /*%< * Add '*keyp' to 'keytable' (using the name in '*keyp'). * The value of keynode->managed is set to 'managed' * * Notes: * *\li Ownership of *keyp is transferred to the keytable. *\li If the key already exists in the table, ISC_R_EXISTS is * returned and the new key is freed. * * Requires: * *\li 'keytable' points to a valid keytable. * *\li keyp != NULL && *keyp is a valid dst_key_t *. * * Ensures: * *\li On success, *keyp == NULL * * Returns: * *\li ISC_R_SUCCESS *\li ISC_R_EXISTS * *\li Any other result indicates failure. */ isc_result_t dns_keytable_marksecure(dns_keytable_t *keytable, dns_name_t *name); /*%< * Add a null key to 'keytable' for name 'name'. This marks the * name as a secure domain, but doesn't supply any key data to allow the * domain to be validated. (Used when automated trust anchor management * has gotten broken by a zone misconfiguration; for example, when the * active key has been revoked but the stand-by key was still in its 30-day * waiting period for validity.) * * Notes: * *\li If a key already exists in the table, ISC_R_EXISTS is * returned and nothing is done. * * Requires: * *\li 'keytable' points to a valid keytable. * *\li keyp != NULL && *keyp is a valid dst_key_t *. * * Returns: * *\li ISC_R_SUCCESS *\li ISC_R_EXISTS * *\li Any other result indicates failure. */ isc_result_t dns_keytable_delete(dns_keytable_t *keytable, dns_name_t *keyname); /*%< * Delete node(s) from 'keytable' matching name 'keyname' * * Requires: * *\li 'keytable' points to a valid keytable. * *\li 'name' is not NULL * * Returns: * *\li ISC_R_SUCCESS * *\li Any other result indicates failure. */ isc_result_t dns_keytable_deletekeynode(dns_keytable_t *keytable, dst_key_t *dstkey); /*%< * Delete node(s) from 'keytable' containing copies of the key pointed * to by 'dstkey' * * Requires: * *\li 'keytable' points to a valid keytable. *\li 'dstkey' is not NULL * * Returns: * *\li ISC_R_SUCCESS * *\li Any other result indicates failure. */ isc_result_t dns_keytable_find(dns_keytable_t *keytable, dns_name_t *keyname, dns_keynode_t **keynodep); /*%< * Search for the first instance of a key named 'name' in 'keytable', * without regard to keyid and algorithm. Use dns_keytable_nextkeynode() * to find subsequent instances. * * Requires: * *\li 'keytable' is a valid keytable. * *\li 'name' is a valid absolute name. * *\li keynodep != NULL && *keynodep == NULL * * Returns: * *\li ISC_R_SUCCESS *\li ISC_R_NOTFOUND * *\li Any other result indicates an error. */ isc_result_t dns_keytable_nextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode, dns_keynode_t **nextnodep); /*%< * Return for the next key after 'keynode' in 'keytable', without regard to * keyid and algorithm. * * Requires: * *\li 'keytable' is a valid keytable. * *\li 'keynode' is a valid keynode. * *\li nextnodep != NULL && *nextnodep == NULL * * Returns: * *\li ISC_R_SUCCESS *\li ISC_R_NOTFOUND * *\li Any other result indicates an error. */ isc_result_t dns_keytable_findkeynode(dns_keytable_t *keytable, dns_name_t *name, dns_secalg_t algorithm, dns_keytag_t tag, dns_keynode_t **keynodep); /*%< * Search for a key named 'name', matching 'algorithm' and 'tag' in * 'keytable'. This finds the first instance which matches. Use * dns_keytable_findnextkeynode() to find other instances. * * Requires: * *\li 'keytable' is a valid keytable. * *\li 'name' is a valid absolute name. * *\li keynodep != NULL && *keynodep == NULL * * Returns: * *\li ISC_R_SUCCESS *\li DNS_R_PARTIALMATCH the name existed in the keytable. *\li ISC_R_NOTFOUND * *\li Any other result indicates an error. */ isc_result_t dns_keytable_findnextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode, dns_keynode_t **nextnodep); /*%< * Search for the next key with the same properties as 'keynode' in * 'keytable' as found by dns_keytable_findkeynode(). * * Requires: * *\li 'keytable' is a valid keytable. * *\li 'keynode' is a valid keynode. * *\li nextnodep != NULL && *nextnodep == NULL * * Returns: * *\li ISC_R_SUCCESS *\li ISC_R_NOTFOUND * *\li Any other result indicates an error. */ isc_result_t dns_keytable_finddeepestmatch(dns_keytable_t *keytable, dns_name_t *name, dns_name_t *foundname); /*%< * Search for the deepest match of 'name' in 'keytable'. * * Requires: * *\li 'keytable' is a valid keytable. * *\li 'name' is a valid absolute name. * *\li 'foundname' is a name with a dedicated buffer. * * Returns: * *\li ISC_R_SUCCESS *\li ISC_R_NOTFOUND * *\li Any other result indicates an error. */ void dns_keytable_attachkeynode(dns_keytable_t *keytable, dns_keynode_t *source, dns_keynode_t **target); /*%< * Attach a keynode and and increment the active_nodes counter in a * corresponding keytable. * * Requires: * *\li 'keytable' is a valid keytable. * *\li 'source' is a valid keynode. * *\li 'target' is not null and '*target' is null. */ void dns_keytable_detachkeynode(dns_keytable_t *keytable, dns_keynode_t **keynodep); /*%< * Give back a keynode found via dns_keytable_findkeynode(). * * Requires: * *\li 'keytable' is a valid keytable. * *\li *keynodep is a valid keynode returned by a call to * dns_keytable_findkeynode(). * * Ensures: * *\li *keynodep == NULL */ isc_result_t dns_keytable_issecuredomain(dns_keytable_t *keytable, dns_name_t *name, isc_boolean_t *wantdnssecp); /*%< * Is 'name' at or beneath a trusted key? * * Requires: * *\li 'keytable' is a valid keytable. * *\li 'name' is a valid absolute name. * *\li '*wantsdnssecp' is a valid isc_boolean_t. * * Ensures: * *\li On success, *wantsdnssecp will be ISC_TRUE if and only if 'name' * is at or beneath a trusted key. * * Returns: * *\li ISC_R_SUCCESS * *\li Any other result is an error. */ isc_result_t dns_keytable_dump(dns_keytable_t *keytable, FILE *fp); /*%< * Dump the keytable on fp. */ dst_key_t * dns_keynode_key(dns_keynode_t *keynode); /*%< * Get the DST key associated with keynode. */ isc_boolean_t dns_keynode_managed(dns_keynode_t *keynode); /*%< * Is this flagged as a managed key? */ isc_result_t dns_keynode_create(isc_mem_t *mctx, dns_keynode_t **target); /*%< * Allocate space for a keynode */ void dns_keynode_attach(dns_keynode_t *source, dns_keynode_t **target); /*%< * Attach keynode 'source' to '*target' */ void dns_keynode_detach(isc_mem_t *mctx, dns_keynode_t **target); /*%< * Detach a single keynode, without touching any keynodes that * may be pointed to by its 'next' pointer */ void dns_keynode_detachall(isc_mem_t *mctx, dns_keynode_t **target); /*%< * Detach a keynode and all its succesors. */ ISC_LANG_ENDDECLS #endif /* DNS_KEYTABLE_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/events.h0000644000470500017500000001022712664710322020611 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009-2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: events.h,v 1.61 2011/10/28 06:20:06 each Exp $ */ #ifndef DNS_EVENTS_H #define DNS_EVENTS_H 1 #include /*! \file dns/events.h * \brief * Registry of DNS event numbers. */ #define DNS_EVENT_FETCHCONTROL (ISC_EVENTCLASS_DNS + 0) #define DNS_EVENT_FETCHDONE (ISC_EVENTCLASS_DNS + 1) #define DNS_EVENT_VIEWRESSHUTDOWN (ISC_EVENTCLASS_DNS + 2) #define DNS_EVENT_VIEWADBSHUTDOWN (ISC_EVENTCLASS_DNS + 3) #define DNS_EVENT_UPDATE (ISC_EVENTCLASS_DNS + 4) #define DNS_EVENT_UPDATEDONE (ISC_EVENTCLASS_DNS + 5) #define DNS_EVENT_DISPATCH (ISC_EVENTCLASS_DNS + 6) #define DNS_EVENT_TCPMSG (ISC_EVENTCLASS_DNS + 7) #define DNS_EVENT_ADBMOREADDRESSES (ISC_EVENTCLASS_DNS + 8) #define DNS_EVENT_ADBNOMOREADDRESSES (ISC_EVENTCLASS_DNS + 9) #define DNS_EVENT_ADBCANCELED (ISC_EVENTCLASS_DNS + 10) #define DNS_EVENT_ADBNAMEDELETED (ISC_EVENTCLASS_DNS + 11) #define DNS_EVENT_ADBSHUTDOWN (ISC_EVENTCLASS_DNS + 12) #define DNS_EVENT_ADBEXPIRED (ISC_EVENTCLASS_DNS + 13) #define DNS_EVENT_ADBCONTROL (ISC_EVENTCLASS_DNS + 14) #define DNS_EVENT_CACHECLEAN (ISC_EVENTCLASS_DNS + 15) #define DNS_EVENT_BYADDRDONE (ISC_EVENTCLASS_DNS + 16) #define DNS_EVENT_ZONECONTROL (ISC_EVENTCLASS_DNS + 17) #define DNS_EVENT_DBDESTROYED (ISC_EVENTCLASS_DNS + 18) #define DNS_EVENT_VALIDATORDONE (ISC_EVENTCLASS_DNS + 19) #define DNS_EVENT_REQUESTDONE (ISC_EVENTCLASS_DNS + 20) #define DNS_EVENT_VALIDATORSTART (ISC_EVENTCLASS_DNS + 21) #define DNS_EVENT_VIEWREQSHUTDOWN (ISC_EVENTCLASS_DNS + 22) #define DNS_EVENT_NOTIFYSENDTOADDR (ISC_EVENTCLASS_DNS + 23) #define DNS_EVENT_ZONE (ISC_EVENTCLASS_DNS + 24) #define DNS_EVENT_ZONESTARTXFRIN (ISC_EVENTCLASS_DNS + 25) #define DNS_EVENT_MASTERQUANTUM (ISC_EVENTCLASS_DNS + 26) #define DNS_EVENT_CACHEOVERMEM (ISC_EVENTCLASS_DNS + 27) #define DNS_EVENT_MASTERNEXTZONE (ISC_EVENTCLASS_DNS + 28) #define DNS_EVENT_IOREADY (ISC_EVENTCLASS_DNS + 29) #define DNS_EVENT_LOOKUPDONE (ISC_EVENTCLASS_DNS + 30) #define DNS_EVENT_RBTDEADNODES (ISC_EVENTCLASS_DNS + 31) #define DNS_EVENT_DISPATCHCONTROL (ISC_EVENTCLASS_DNS + 32) #define DNS_EVENT_REQUESTCONTROL (ISC_EVENTCLASS_DNS + 33) #define DNS_EVENT_DUMPQUANTUM (ISC_EVENTCLASS_DNS + 34) #define DNS_EVENT_IMPORTRECVDONE (ISC_EVENTCLASS_DNS + 35) #define DNS_EVENT_FREESTORAGE (ISC_EVENTCLASS_DNS + 36) #define DNS_EVENT_VIEWACACHESHUTDOWN (ISC_EVENTCLASS_DNS + 37) #define DNS_EVENT_ACACHECONTROL (ISC_EVENTCLASS_DNS + 38) #define DNS_EVENT_ACACHECLEAN (ISC_EVENTCLASS_DNS + 39) #define DNS_EVENT_ACACHEOVERMEM (ISC_EVENTCLASS_DNS + 40) #define DNS_EVENT_RBTPRUNE (ISC_EVENTCLASS_DNS + 41) #define DNS_EVENT_MANAGEKEYS (ISC_EVENTCLASS_DNS + 42) #define DNS_EVENT_CLIENTRESDONE (ISC_EVENTCLASS_DNS + 43) #define DNS_EVENT_CLIENTREQDONE (ISC_EVENTCLASS_DNS + 44) #define DNS_EVENT_ADBGROWENTRIES (ISC_EVENTCLASS_DNS + 45) #define DNS_EVENT_ADBGROWNAMES (ISC_EVENTCLASS_DNS + 46) #define DNS_EVENT_ZONESECURESERIAL (ISC_EVENTCLASS_DNS + 47) #define DNS_EVENT_ZONESECUREDB (ISC_EVENTCLASS_DNS + 48) #define DNS_EVENT_ZONELOAD (ISC_EVENTCLASS_DNS + 49) #define DNS_EVENT_KEYDONE (ISC_EVENTCLASS_DNS + 50) #define DNS_EVENT_SETNSEC3PARAM (ISC_EVENTCLASS_DNS + 51) #define DNS_EVENT_FIRSTEVENT (ISC_EVENTCLASS_DNS + 0) #define DNS_EVENT_LASTEVENT (ISC_EVENTCLASS_DNS + 65535) #endif /* DNS_EVENTS_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/bit.h0000644000470500017500000000254212664710322020064 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: bit.h,v 1.14 2007/06/19 23:47:16 tbox Exp $ */ #ifndef DNS_BIT_H #define DNS_BIT_H 1 /*! \file dns/bit.h */ #include #include typedef isc_uint64_t dns_bitset_t; #define DNS_BIT_SET(bit, bitset) \ (*(bitset) |= ((dns_bitset_t)1 << (bit))) #define DNS_BIT_CLEAR(bit, bitset) \ (*(bitset) &= ~((dns_bitset_t)1 << (bit))) #define DNS_BIT_CHECK(bit, bitset) \ ISC_TF((*(bitset) & ((dns_bitset_t)1 << (bit))) \ == ((dns_bitset_t)1 << (bit))) #endif /* DNS_BIT_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/xfrin.h0000644000470500017500000000661012664710322020434 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: xfrin.h,v 1.30 2009/01/17 23:47:43 tbox Exp $ */ #ifndef DNS_XFRIN_H #define DNS_XFRIN_H 1 /***** ***** Module Info *****/ /*! \file dns/xfrin.h * \brief * Incoming zone transfers (AXFR + IXFR). */ /*** *** Imports ***/ #include #include /*** *** Types ***/ /*% * A transfer in progress. This is an opaque type. */ typedef struct dns_xfrin_ctx dns_xfrin_ctx_t; /*** *** Functions ***/ ISC_LANG_BEGINDECLS /*% see dns_xfrin_create2() */ isc_result_t dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype, isc_sockaddr_t *masteraddr, dns_tsigkey_t *tsigkey, isc_mem_t *mctx, isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, isc_task_t *task, dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp); isc_result_t dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype, isc_sockaddr_t *masteraddr, isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey, isc_mem_t *mctx, isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, isc_task_t *task, dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp); isc_result_t dns_xfrin_create3(dns_zone_t *zone, dns_rdatatype_t xfrtype, isc_sockaddr_t *masteraddr, isc_sockaddr_t *sourceaddr, isc_dscp_t dscp, dns_tsigkey_t *tsigkey, isc_mem_t *mctx, isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, isc_task_t *task, dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp); /*%< * Attempt to start an incoming zone transfer of 'zone' * from 'masteraddr', creating a dns_xfrin_ctx_t object to * manage it. Attach '*xfrp' to the newly created object. * * Iff ISC_R_SUCCESS is returned, '*done' is guaranteed to be * called in the context of 'task', with 'zone' and a result * code as arguments when the transfer finishes. * * Requires: *\li 'xfrtype' is dns_rdatatype_axfr, dns_rdatatype_ixfr * or dns_rdatatype_soa (soa query followed by axfr if * serial is greater than current serial). * *\li If 'xfrtype' is dns_rdatatype_ixfr or dns_rdatatype_soa, * the zone has a database. */ void dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr); /*%< * If the zone transfer 'xfr' has already finished, * do nothing. Otherwise, abort it and cause it to call * its done callback with a status of ISC_R_CANCELED. */ void dns_xfrin_detach(dns_xfrin_ctx_t **xfrp); /*%< * Detach a reference to a zone transfer object. * Caller to maintain external locking if required. */ void dns_xfrin_attach(dns_xfrin_ctx_t *source, dns_xfrin_ctx_t **target); /*%< * Caller to maintain external locking if required. */ ISC_LANG_ENDDECLS #endif /* DNS_XFRIN_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/tsig.h0000644000470500017500000002102712664710322020253 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009-2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: tsig.h,v 1.59 2011/01/11 23:47:13 tbox Exp $ */ #ifndef DNS_TSIG_H #define DNS_TSIG_H 1 /*! \file dns/tsig.h */ #include #include #include #include #include #include #include #include /* * Algorithms. */ LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacmd5_name; #define DNS_TSIG_HMACMD5_NAME dns_tsig_hmacmd5_name LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_gssapi_name; #define DNS_TSIG_GSSAPI_NAME dns_tsig_gssapi_name LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_gssapims_name; #define DNS_TSIG_GSSAPIMS_NAME dns_tsig_gssapims_name LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha1_name; #define DNS_TSIG_HMACSHA1_NAME dns_tsig_hmacsha1_name LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha224_name; #define DNS_TSIG_HMACSHA224_NAME dns_tsig_hmacsha224_name LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha256_name; #define DNS_TSIG_HMACSHA256_NAME dns_tsig_hmacsha256_name LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha384_name; #define DNS_TSIG_HMACSHA384_NAME dns_tsig_hmacsha384_name LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha512_name; #define DNS_TSIG_HMACSHA512_NAME dns_tsig_hmacsha512_name /*% * Default fudge value. */ #define DNS_TSIG_FUDGE 300 struct dns_tsig_keyring { dns_rbt_t *keys; unsigned int writecount; isc_rwlock_t lock; isc_mem_t *mctx; /* * LRU list of generated key along with a count of the keys on the * list and a maximum size. */ unsigned int generated; unsigned int maxgenerated; ISC_LIST(dns_tsigkey_t) lru; unsigned int references; }; struct dns_tsigkey { /* Unlocked */ unsigned int magic; /*%< Magic number. */ isc_mem_t *mctx; dst_key_t *key; /*%< Key */ dns_name_t name; /*%< Key name */ dns_name_t *algorithm; /*%< Algorithm name */ dns_name_t *creator; /*%< name that created secret */ isc_boolean_t generated; /*%< was this generated? */ isc_stdtime_t inception; /*%< start of validity period */ isc_stdtime_t expire; /*%< end of validity period */ dns_tsig_keyring_t *ring; /*%< the enclosing keyring */ isc_refcount_t refs; /*%< reference counter */ ISC_LINK(dns_tsigkey_t) link; }; #define dns_tsigkey_identity(tsigkey) \ ((tsigkey) == NULL ? NULL : \ (tsigkey)->generated ? ((tsigkey)->creator) : \ (&((tsigkey)->name))) ISC_LANG_BEGINDECLS isc_result_t dns_tsigkey_create(dns_name_t *name, dns_name_t *algorithm, unsigned char *secret, int length, isc_boolean_t generated, dns_name_t *creator, isc_stdtime_t inception, isc_stdtime_t expire, isc_mem_t *mctx, dns_tsig_keyring_t *ring, dns_tsigkey_t **key); isc_result_t dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm, dst_key_t *dstkey, isc_boolean_t generated, dns_name_t *creator, isc_stdtime_t inception, isc_stdtime_t expire, isc_mem_t *mctx, dns_tsig_keyring_t *ring, dns_tsigkey_t **key); /*%< * Creates a tsig key structure and saves it in the keyring. If key is * not NULL, *key will contain a copy of the key. The keys validity * period is specified by (inception, expire), and will not expire if * inception == expire. If the key was generated, the creating identity, * if there is one, should be in the creator parameter. Specifying an * unimplemented algorithm will cause failure only if dstkey != NULL; this * allows a transient key with an invalid algorithm to exist long enough * to generate a BADKEY response. * * If dns_tsigkey_createfromkey is successful a new reference to 'dstkey' * will have been made. * * Requires: *\li 'name' is a valid dns_name_t *\li 'algorithm' is a valid dns_name_t *\li 'secret' is a valid pointer *\li 'length' is an integer >= 0 *\li 'dstkey' is a valid dst key or NULL *\li 'creator' points to a valid dns_name_t or is NULL *\li 'mctx' is a valid memory context *\li 'ring' is a valid TSIG keyring or NULL *\li 'key' or '*key' must be NULL * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_EXISTS - a key with this name already exists *\li #ISC_R_NOTIMPLEMENTED - algorithm is not implemented *\li #ISC_R_NOMEMORY */ void dns_tsigkey_attach(dns_tsigkey_t *source, dns_tsigkey_t **targetp); /*%< * Attach '*targetp' to 'source'. * * Requires: *\li 'key' is a valid TSIG key * * Ensures: *\li *targetp is attached to source. */ void dns_tsigkey_detach(dns_tsigkey_t **keyp); /*%< * Detaches from the tsig key structure pointed to by '*key'. * * Requires: *\li 'keyp' is not NULL and '*keyp' is a valid TSIG key * * Ensures: *\li 'keyp' points to NULL */ void dns_tsigkey_setdeleted(dns_tsigkey_t *key); /*%< * Prevents this key from being used again. It will be deleted when * no references exist. * * Requires: *\li 'key' is a valid TSIG key on a keyring */ isc_result_t dns_tsig_sign(dns_message_t *msg); /*%< * Generates a TSIG record for this message * * Requires: *\li 'msg' is a valid message *\li 'msg->tsigkey' is a valid TSIG key *\li 'msg->tsig' is NULL * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li #ISC_R_NOSPACE *\li #DNS_R_EXPECTEDTSIG * - this is a response & msg->querytsig is NULL */ isc_result_t dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg, dns_tsig_keyring_t *ring1, dns_tsig_keyring_t *ring2); /*%< * Verifies the TSIG record in this message * * Requires: *\li 'source' is a valid buffer containing the unparsed message *\li 'msg' is a valid message *\li 'msg->tsigkey' is a valid TSIG key if this is a response *\li 'msg->tsig' is NULL *\li 'msg->querytsig' is not NULL if this is a response *\li 'ring1' and 'ring2' are each either a valid keyring or NULL * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li #DNS_R_EXPECTEDTSIG - A TSIG was expected but not seen *\li #DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected *\li #DNS_R_TSIGERRORSET - the TSIG verified but ->error was set * and this is a query *\li #DNS_R_CLOCKSKEW - the TSIG failed to verify because of * the time was out of the allowed range. *\li #DNS_R_TSIGVERIFYFAILURE - the TSIG failed to verify *\li #DNS_R_EXPECTEDRESPONSE - the message was set over TCP and * should have been a response, * but was not. */ isc_result_t dns_tsigkey_find(dns_tsigkey_t **tsigkey, dns_name_t *name, dns_name_t *algorithm, dns_tsig_keyring_t *ring); /*%< * Returns the TSIG key corresponding to this name and (possibly) * algorithm. Also increments the key's reference counter. * * Requires: *\li 'tsigkey' is not NULL *\li '*tsigkey' is NULL *\li 'name' is a valid dns_name_t *\li 'algorithm' is a valid dns_name_t or NULL *\li 'ring' is a valid keyring * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOTFOUND */ isc_result_t dns_tsigkeyring_create(isc_mem_t *mctx, dns_tsig_keyring_t **ringp); /*%< * Create an empty TSIG key ring. * * Requires: *\li 'mctx' is not NULL *\li 'ringp' is not NULL, and '*ringp' is NULL * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY */ isc_result_t dns_tsigkeyring_add(dns_tsig_keyring_t *ring, dns_name_t *name, dns_tsigkey_t *tkey); /*%< * Place a TSIG key onto a key ring. * * Requires: *\li 'ring', 'name' and 'tkey' are not NULL * * Returns: *\li #ISC_R_SUCCESS *\li Any other value indicates failure. */ void dns_tsigkeyring_attach(dns_tsig_keyring_t *source, dns_tsig_keyring_t **target); void dns_tsigkeyring_detach(dns_tsig_keyring_t **ringp); isc_result_t dns_tsigkeyring_dumpanddetach(dns_tsig_keyring_t **ringp, FILE *fp); /*%< * Destroy a TSIG key ring. * * Requires: *\li 'ringp' is not NULL */ void dns_keyring_restore(dns_tsig_keyring_t *ring, FILE *fp); ISC_LANG_ENDDECLS #endif /* DNS_TSIG_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/callbacks.h0000644000470500017500000000537512664710322021234 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: callbacks.h,v 1.26.40.1 2012/02/07 00:44:16 each Exp $ */ #ifndef DNS_CALLBACKS_H #define DNS_CALLBACKS_H 1 /*! \file dns/callbacks.h */ /*** *** Imports ***/ #include #include #include ISC_LANG_BEGINDECLS /*** *** Types ***/ #define DNS_CALLBACK_MAGIC ISC_MAGIC('C','L','L','B') #define DNS_CALLBACK_VALID(cb) ISC_MAGIC_VALID(cb, DNS_CALLBACK_MAGIC) struct dns_rdatacallbacks { unsigned int magic; /*% * dns_load_master calls this when it has rdatasets to commit. */ dns_addrdatasetfunc_t add; /*% * This is called when reading in a database image from a 'map' * format zone file. */ dns_deserializefunc_t deserialize; /*% * dns_master_load*() call this when loading a raw zonefile, * to pass back information obtained from the file header */ dns_rawdatafunc_t rawdata; dns_zone_t *zone; /*% * dns_load_master / dns_rdata_fromtext call this to issue a error. */ void (*error)(struct dns_rdatacallbacks *, const char *, ...); /*% * dns_load_master / dns_rdata_fromtext call this to issue a warning. */ void (*warn)(struct dns_rdatacallbacks *, const char *, ...); /*% * Private data handles for use by the above callback functions. */ void *add_private; void *deserialize_private; void *error_private; void *warn_private; }; /*** *** Initialization ***/ void dns_rdatacallbacks_init(dns_rdatacallbacks_t *callbacks); /*%< * Initialize 'callbacks'. * * \li 'magic' is set to DNS_CALLBACK_MAGIC * * \li 'error' and 'warn' are set to default callbacks that print the * error message through the DNS library log context. * *\li All other elements are initialized to NULL. * * Requires: * \li 'callbacks' is a valid dns_rdatacallbacks_t, */ void dns_rdatacallbacks_init_stdio(dns_rdatacallbacks_t *callbacks); /*%< * Like dns_rdatacallbacks_init, but logs to stdio. */ ISC_LANG_ENDDECLS #endif /* DNS_CALLBACKS_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/keyvalues.h0000644000470500017500000001064412664710322021320 0ustar lamontlamont/* * Copyright (C) 2004-2010, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: keyvalues.h,v 1.29 2010/12/23 23:47:08 tbox Exp $ */ #ifndef DNS_KEYVALUES_H #define DNS_KEYVALUES_H 1 /*! \file dns/keyvalues.h */ /* * Flags field of the KEY RR rdata */ #define DNS_KEYFLAG_TYPEMASK 0xC000 /*%< Mask for "type" bits */ #define DNS_KEYTYPE_AUTHCONF 0x0000 /*%< Key usable for both */ #define DNS_KEYTYPE_CONFONLY 0x8000 /*%< Key usable for confidentiality */ #define DNS_KEYTYPE_AUTHONLY 0x4000 /*%< Key usable for authentication */ #define DNS_KEYTYPE_NOKEY 0xC000 /*%< No key usable for either; no key */ #define DNS_KEYTYPE_NOAUTH DNS_KEYTYPE_CONFONLY #define DNS_KEYTYPE_NOCONF DNS_KEYTYPE_AUTHONLY #define DNS_KEYFLAG_RESERVED2 0x2000 /*%< reserved - must be zero */ #define DNS_KEYFLAG_EXTENDED 0x1000 /*%< key has extended flags */ #define DNS_KEYFLAG_RESERVED4 0x0800 /*%< reserved - must be zero */ #define DNS_KEYFLAG_RESERVED5 0x0400 /*%< reserved - must be zero */ #define DNS_KEYFLAG_OWNERMASK 0x0300 /*%< these bits determine the type */ #define DNS_KEYOWNER_USER 0x0000 /*%< key is assoc. with user */ #define DNS_KEYOWNER_ENTITY 0x0200 /*%< key is assoc. with entity eg host */ #define DNS_KEYOWNER_ZONE 0x0100 /*%< key is zone key */ #define DNS_KEYOWNER_RESERVED 0x0300 /*%< reserved meaning */ #define DNS_KEYFLAG_REVOKE 0x0080 /*%< key revoked (per rfc5011) */ #define DNS_KEYFLAG_RESERVED9 0x0040 /*%< reserved - must be zero */ #define DNS_KEYFLAG_RESERVED10 0x0020 /*%< reserved - must be zero */ #define DNS_KEYFLAG_RESERVED11 0x0010 /*%< reserved - must be zero */ #define DNS_KEYFLAG_SIGNATORYMASK 0x000F /*%< key can sign RR's of same name */ #define DNS_KEYFLAG_RESERVEDMASK (DNS_KEYFLAG_RESERVED2 | \ DNS_KEYFLAG_RESERVED4 | \ DNS_KEYFLAG_RESERVED5 | \ DNS_KEYFLAG_RESERVED9 | \ DNS_KEYFLAG_RESERVED10 | \ DNS_KEYFLAG_RESERVED11 ) #define DNS_KEYFLAG_KSK 0x0001 /*%< key signing key */ #define DNS_KEYFLAG_RESERVEDMASK2 0xFFFF /*%< no bits defined here */ /* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */ #define DNS_KEYALG_RSAMD5 1 /*%< RSA with MD5 */ #define DNS_KEYALG_RSA DNS_KEYALG_RSAMD5 #define DNS_KEYALG_DH 2 /*%< Diffie Hellman KEY */ #define DNS_KEYALG_DSA 3 /*%< DSA KEY */ #define DNS_KEYALG_NSEC3DSA 6 #define DNS_KEYALG_DSS DNS_ALG_DSA #define DNS_KEYALG_ECC 4 #define DNS_KEYALG_RSASHA1 5 #define DNS_KEYALG_NSEC3RSASHA1 7 #define DNS_KEYALG_RSASHA256 8 #define DNS_KEYALG_RSASHA512 10 #define DNS_KEYALG_ECCGOST 12 #define DNS_KEYALG_ECDSA256 13 #define DNS_KEYALG_ECDSA384 14 #define DNS_KEYALG_INDIRECT 252 #define DNS_KEYALG_PRIVATEDNS 253 #define DNS_KEYALG_PRIVATEOID 254 /*%< Key begins with OID giving alg */ /* Protocol values */ #define DNS_KEYPROTO_RESERVED 0 #define DNS_KEYPROTO_TLS 1 #define DNS_KEYPROTO_EMAIL 2 #define DNS_KEYPROTO_DNSSEC 3 #define DNS_KEYPROTO_IPSEC 4 #define DNS_KEYPROTO_ANY 255 /* Signatures */ #define DNS_SIG_RSAMINBITS 512 /*%< Size of a mod or exp in bits */ #define DNS_SIG_RSAMAXBITS 2552 /* Total of binary mod and exp */ #define DNS_SIG_RSAMAXBYTES ((DNS_SIG_RSAMAXBITS+7/8)*2+3) /*%< Max length of text sig block */ #define DNS_SIG_RSAMAXBASE64 (((DNS_SIG_RSAMAXBYTES+2)/3)*4) #define DNS_SIG_RSAMINSIZE ((DNS_SIG_RSAMINBITS+7)/8) #define DNS_SIG_RSAMAXSIZE ((DNS_SIG_RSAMAXBITS+7)/8) #define DNS_SIG_DSASIGSIZE 41 #define DNS_SIG_DSAMINBITS 512 #define DNS_SIG_DSAMAXBITS 1024 #define DNS_SIG_DSAMINBYTES 213 #define DNS_SIG_DSAMAXBYTES 405 #define DNS_SIG_GOSTSIGSIZE 64 #define DNS_SIG_ECDSA256SIZE 64 #define DNS_SIG_ECDSA384SIZE 96 #define DNS_KEY_ECDSA256SIZE 64 #define DNS_KEY_ECDSA384SIZE 96 #endif /* DNS_KEYVALUES_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/secproto.h0000644000470500017500000000404212664710322021141 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: secproto.h,v 1.16 2007/06/19 23:47:17 tbox Exp $ */ #ifndef DNS_SECPROTO_H #define DNS_SECPROTO_H 1 /*! \file dns/secproto.h */ #include #include ISC_LANG_BEGINDECLS isc_result_t dns_secproto_fromtext(dns_secproto_t *secprotop, isc_textregion_t *source); /*%< * Convert the text 'source' refers to into a DNSSEC security protocol value. * The text may contain either a mnemonic protocol name or a decimal protocol * number. * * Requires: *\li 'secprotop' is a valid pointer. * *\li 'source' is a valid text region. * * Returns: *\li ISC_R_SUCCESS on success *\li ISC_R_RANGE numeric type is out of range *\li DNS_R_UNKNOWN mnemonic type is unknown */ isc_result_t dns_secproto_totext(dns_secproto_t secproto, isc_buffer_t *target); /*%< * Put a textual representation of the DNSSEC security protocol 'secproto' * into 'target'. * * Requires: *\li 'secproto' is a valid secproto. * *\li 'target' is a valid text buffer. * * Ensures, * if the result is success: * \li The used space in 'target' is updated. * * Returns: *\li ISC_R_SUCCESS on success *\li ISC_R_NOSPACE target buffer is too small */ ISC_LANG_ENDDECLS #endif /* DNS_SECPROTO_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/lookup.h0000644000470500017500000000657612664710322020632 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lookup.h,v 1.14 2009/01/17 23:47:43 tbox Exp $ */ #ifndef DNS_LOOKUP_H #define DNS_LOOKUP_H 1 /***** ***** Module Info *****/ /*! \file dns/lookup.h * \brief * The lookup module performs simple DNS lookups. It implements * the full resolver algorithm, both looking for local data and * resolving external names as necessary. * * MP: *\li The module ensures appropriate synchronization of data structures it * creates and manipulates. * * Reliability: *\li No anticipated impact. * * Resources: *\li TBS * * Security: *\li No anticipated impact. * * Standards: *\li RFCs: 1034, 1035, 2181, TBS *\li Drafts: TBS */ #include #include #include ISC_LANG_BEGINDECLS /*% * A 'dns_lookupevent_t' is returned when a lookup completes. * The sender field will be set to the lookup that completed. If 'result' * is ISC_R_SUCCESS, then 'names' will contain a list of names associated * with the address. The recipient of the event must not change the list * and must not refer to any of the name data after the event is freed. */ typedef struct dns_lookupevent { ISC_EVENT_COMMON(struct dns_lookupevent); isc_result_t result; dns_name_t *name; dns_rdataset_t *rdataset; dns_rdataset_t *sigrdataset; dns_db_t *db; dns_dbnode_t *node; } dns_lookupevent_t; isc_result_t dns_lookup_create(isc_mem_t *mctx, dns_name_t *name, dns_rdatatype_t type, dns_view_t *view, unsigned int options, isc_task_t *task, isc_taskaction_t action, void *arg, dns_lookup_t **lookupp); /*%< * Finds the rrsets matching 'name' and 'type'. * * Requires: * *\li 'mctx' is a valid mctx. * *\li 'name' is a valid name. * *\li 'view' is a valid view which has a resolver. * *\li 'task' is a valid task. * *\li lookupp != NULL && *lookupp == NULL * * Returns: * *\li ISC_R_SUCCESS *\li ISC_R_NOMEMORY * *\li Any resolver-related error (e.g. ISC_R_SHUTTINGDOWN) may also be * returned. */ void dns_lookup_cancel(dns_lookup_t *lookup); /*%< * Cancel 'lookup'. * * Notes: * *\li If 'lookup' has not completed, post its LOOKUPDONE event with a * result code of ISC_R_CANCELED. * * Requires: * *\li 'lookup' is a valid lookup. */ void dns_lookup_destroy(dns_lookup_t **lookupp); /*%< * Destroy 'lookup'. * * Requires: * *\li '*lookupp' is a valid lookup. * *\li The caller has received the LOOKUPDONE event (either because the * lookup completed or because dns_lookup_cancel() was called). * * Ensures: * *\li *lookupp == NULL. */ ISC_LANG_ENDDECLS #endif /* DNS_LOOKUP_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/stats.h0000644000470500017500000003040212664710322020440 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef DNS_STATS_H #define DNS_STATS_H 1 /*! \file dns/stats.h */ #include /*% * Statistics counters. Used as isc_statscounter_t values. */ enum { /*% * Resolver statistics counters. */ dns_resstatscounter_queryv4 = 0, dns_resstatscounter_queryv6 = 1, dns_resstatscounter_responsev4 = 2, dns_resstatscounter_responsev6 = 3, dns_resstatscounter_nxdomain = 4, dns_resstatscounter_servfail = 5, dns_resstatscounter_formerr = 6, dns_resstatscounter_othererror = 7, dns_resstatscounter_edns0fail = 8, dns_resstatscounter_mismatch = 9, dns_resstatscounter_truncated = 10, dns_resstatscounter_lame = 11, dns_resstatscounter_retry = 12, dns_resstatscounter_gluefetchv4 = 13, dns_resstatscounter_gluefetchv6 = 14, dns_resstatscounter_gluefetchv4fail = 15, dns_resstatscounter_gluefetchv6fail = 16, dns_resstatscounter_val = 17, dns_resstatscounter_valsuccess = 18, dns_resstatscounter_valnegsuccess = 19, dns_resstatscounter_valfail = 20, dns_resstatscounter_dispabort = 21, dns_resstatscounter_dispsockfail = 22, dns_resstatscounter_querytimeout = 23, dns_resstatscounter_queryrtt0 = 24, dns_resstatscounter_queryrtt1 = 25, dns_resstatscounter_queryrtt2 = 26, dns_resstatscounter_queryrtt3 = 27, dns_resstatscounter_queryrtt4 = 28, dns_resstatscounter_queryrtt5 = 29, dns_resstatscounter_nfetch = 30, dns_resstatscounter_disprequdp = 31, dns_resstatscounter_dispreqtcp = 32, dns_resstatscounter_buckets = 33, dns_resstatscounter_refused = 34, dns_resstatscounter_sitcc = 35, dns_resstatscounter_sitout = 36, dns_resstatscounter_sitin = 37, dns_resstatscounter_sitok = 38, dns_resstatscounter_badvers = 39, dns_resstatscounter_zonequota = 40, dns_resstatscounter_serverquota = 41, dns_resstatscounter_max = 42, /* * DNSSEC stats. */ dns_dnssecstats_asis = 0, dns_dnssecstats_downcase = 1, dns_dnssecstats_wildcard = 2, dns_dnssecstats_fail = 3, dns_dnssecstats_max = 4, /*% * Zone statistics counters. */ dns_zonestatscounter_notifyoutv4 = 0, dns_zonestatscounter_notifyoutv6 = 1, dns_zonestatscounter_notifyinv4 = 2, dns_zonestatscounter_notifyinv6 = 3, dns_zonestatscounter_notifyrej = 4, dns_zonestatscounter_soaoutv4 = 5, dns_zonestatscounter_soaoutv6 = 6, dns_zonestatscounter_axfrreqv4 = 7, dns_zonestatscounter_axfrreqv6 = 8, dns_zonestatscounter_ixfrreqv4 = 9, dns_zonestatscounter_ixfrreqv6 = 10, dns_zonestatscounter_xfrsuccess = 11, dns_zonestatscounter_xfrfail = 12, dns_zonestatscounter_max = 13, /* * Adb statistics values. */ dns_adbstats_nentries = 0, dns_adbstats_entriescnt = 1, dns_adbstats_nnames = 2, dns_adbstats_namescnt = 3, dns_adbstats_max = 4, /* * Cache statistics values. */ dns_cachestatscounter_hits = 1, dns_cachestatscounter_misses = 2, dns_cachestatscounter_queryhits = 3, dns_cachestatscounter_querymisses = 4, dns_cachestatscounter_deletelru = 5, dns_cachestatscounter_deletettl = 6, dns_cachestatscounter_max = 7, /*% * Query statistics counters (obsolete). */ dns_statscounter_success = 0, /*%< Successful lookup */ dns_statscounter_referral = 1, /*%< Referral result */ dns_statscounter_nxrrset = 2, /*%< NXRRSET result */ dns_statscounter_nxdomain = 3, /*%< NXDOMAIN result */ dns_statscounter_recursion = 4, /*%< Recursion was used */ dns_statscounter_failure = 5, /*%< Some other failure */ dns_statscounter_duplicate = 6, /*%< Duplicate query */ dns_statscounter_dropped = 7 /*%< Duplicate query (dropped) */ }; #define DNS_STATS_NCOUNTERS 8 #if 0 /*%< * Flag(s) for dns_xxxstats_dump(). DNS_STATSDUMP_VERBOSE is obsolete. * ISC_STATSDUMP_VERBOSE should be used instead. These two values are * intentionally defined to be the same value to ensure binary compatibility. */ #define DNS_STATSDUMP_VERBOSE 0x00000001 /*%< dump 0-value counters */ #endif /*%< * (Obsoleted) */ LIBDNS_EXTERNAL_DATA extern const char *dns_statscounter_names[]; /*% * Attributes for statistics counters of RRset and Rdatatype types. * * _OTHERTYPE * The rdata type is not explicitly supported and the corresponding counter * is counted for other such types, too. When this attribute is set, * the base type is of no use. * * _NXRRSET * RRset type counters only. Indicates the RRset is non existent. * * _NXDOMAIN * RRset type counters only. Indicates a non existent name. When this * attribute is set, the base type is of no use. * * _STALE * RRset type counters only. This indicates a record that marked for * removal. * * Note: incrementing _STALE will decrement the corresponding non-stale * counter. */ #define DNS_RDATASTATSTYPE_ATTR_OTHERTYPE 0x0001 #define DNS_RDATASTATSTYPE_ATTR_NXRRSET 0x0002 #define DNS_RDATASTATSTYPE_ATTR_NXDOMAIN 0x0004 #define DNS_RDATASTATSTYPE_ATTR_STALE 0x0008 /*%< * Conversion macros among dns_rdatatype_t, attributes and isc_statscounter_t. */ #define DNS_RDATASTATSTYPE_BASE(type) ((dns_rdatatype_t)((type) & 0xFFFF)) #define DNS_RDATASTATSTYPE_ATTR(type) ((type) >> 16) #define DNS_RDATASTATSTYPE_VALUE(b, a) (((a) << 16) | (b)) /*%< * Types of dump callbacks. */ typedef void (*dns_generalstats_dumper_t)(isc_statscounter_t, isc_uint64_t, void *); typedef void (*dns_rdatatypestats_dumper_t)(dns_rdatastatstype_t, isc_uint64_t, void *); typedef void (*dns_opcodestats_dumper_t)(dns_opcode_t, isc_uint64_t, void *); ISC_LANG_BEGINDECLS isc_result_t dns_generalstats_create(isc_mem_t *mctx, dns_stats_t **statsp, int ncounters); /*%< * Create a statistics counter structure of general type. It counts a general * set of counters indexed by an ID between 0 and ncounters -1. * This function is obsolete. A more general function, isc_stats_create(), * should be used. * * Requires: *\li 'mctx' must be a valid memory context. * *\li 'statsp' != NULL && '*statsp' == NULL. * * Returns: *\li ISC_R_SUCCESS -- all ok * *\li anything else -- failure */ isc_result_t dns_rdatatypestats_create(isc_mem_t *mctx, dns_stats_t **statsp); /*%< * Create a statistics counter structure per rdatatype. * * Requires: *\li 'mctx' must be a valid memory context. * *\li 'statsp' != NULL && '*statsp' == NULL. * * Returns: *\li ISC_R_SUCCESS -- all ok * *\li anything else -- failure */ isc_result_t dns_rdatasetstats_create(isc_mem_t *mctx, dns_stats_t **statsp); /*%< * Create a statistics counter structure per RRset. * * Requires: *\li 'mctx' must be a valid memory context. * *\li 'statsp' != NULL && '*statsp' == NULL. * * Returns: *\li ISC_R_SUCCESS -- all ok * *\li anything else -- failure */ isc_result_t dns_opcodestats_create(isc_mem_t *mctx, dns_stats_t **statsp); /*%< * Create a statistics counter structure per opcode. * * Requires: *\li 'mctx' must be a valid memory context. * *\li 'statsp' != NULL && '*statsp' == NULL. * * Returns: *\li ISC_R_SUCCESS -- all ok * *\li anything else -- failure */ void dns_stats_attach(dns_stats_t *stats, dns_stats_t **statsp); /*%< * Attach to a statistics set. * * Requires: *\li 'stats' is a valid dns_stats_t. * *\li 'statsp' != NULL && '*statsp' == NULL */ void dns_stats_detach(dns_stats_t **statsp); /*%< * Detaches from the statistics set. * * Requires: *\li 'statsp' != NULL and '*statsp' is a valid dns_stats_t. */ void dns_generalstats_increment(dns_stats_t *stats, isc_statscounter_t counter); /*%< * Increment the counter-th counter of stats. This function is obsolete. * A more general function, isc_stats_increment(), should be used. * * Requires: *\li 'stats' is a valid dns_stats_t created by dns_generalstats_create(). * *\li counter is less than the maximum available ID for the stats specified * on creation. */ void dns_rdatatypestats_increment(dns_stats_t *stats, dns_rdatatype_t type); /*%< * Increment the statistics counter for 'type'. * * Requires: *\li 'stats' is a valid dns_stats_t created by dns_rdatatypestats_create(). */ void dns_rdatasetstats_increment(dns_stats_t *stats, dns_rdatastatstype_t rrsettype); /*%< * Increment the statistics counter for 'rrsettype'. * * Note: if 'rrsettype' has the _STALE attribute set the corresponding * non-stale counter will be decremented. * * Requires: *\li 'stats' is a valid dns_stats_t created by dns_rdatasetstats_create(). */ void dns_rdatasetstats_decrement(dns_stats_t *stats, dns_rdatastatstype_t rrsettype); /*%< * Decrement the statistics counter for 'rrsettype'. * * Requires: *\li 'stats' is a valid dns_stats_t created by dns_rdatasetstats_create(). */ void dns_opcodestats_increment(dns_stats_t *stats, dns_opcode_t code); /*%< * Increment the statistics counter for 'code'. * * Requires: *\li 'stats' is a valid dns_stats_t created by dns_opcodestats_create(). */ void dns_generalstats_dump(dns_stats_t *stats, dns_generalstats_dumper_t dump_fn, void *arg, unsigned int options); /*%< * Dump the current statistics counters in a specified way. For each counter * in stats, dump_fn is called with its current value and the given argument * arg. By default counters that have a value of 0 is skipped; if options has * the ISC_STATSDUMP_VERBOSE flag, even such counters are dumped. * * This function is obsolete. A more general function, isc_stats_dump(), * should be used. * * Requires: *\li 'stats' is a valid dns_stats_t created by dns_generalstats_create(). */ void dns_rdatatypestats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn, void *arg, unsigned int options); /*%< * Dump the current statistics counters in a specified way. For each counter * in stats, dump_fn is called with the corresponding type in the form of * dns_rdatastatstype_t, the current counter value and the given argument * arg. By default counters that have a value of 0 is skipped; if options has * the ISC_STATSDUMP_VERBOSE flag, even such counters are dumped. * * Requires: *\li 'stats' is a valid dns_stats_t created by dns_generalstats_create(). */ void dns_rdatasetstats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn, void *arg, unsigned int options); /*%< * Dump the current statistics counters in a specified way. For each counter * in stats, dump_fn is called with the corresponding type in the form of * dns_rdatastatstype_t, the current counter value and the given argument * arg. By default counters that have a value of 0 is skipped; if options has * the ISC_STATSDUMP_VERBOSE flag, even such counters are dumped. * * Requires: *\li 'stats' is a valid dns_stats_t created by dns_generalstats_create(). */ void dns_opcodestats_dump(dns_stats_t *stats, dns_opcodestats_dumper_t dump_fn, void *arg, unsigned int options); /*%< * Dump the current statistics counters in a specified way. For each counter * in stats, dump_fn is called with the corresponding opcode, the current * counter value and the given argument arg. By default counters that have a * value of 0 is skipped; if options has the ISC_STATSDUMP_VERBOSE flag, even * such counters are dumped. * * Requires: *\li 'stats' is a valid dns_stats_t created by dns_generalstats_create(). */ isc_result_t dns_stats_alloccounters(isc_mem_t *mctx, isc_uint64_t **ctrp); /*%< * Allocate an array of query statistics counters from the memory * context 'mctx'. * * This function is obsoleted. Use dns_xxxstats_create() instead. */ void dns_stats_freecounters(isc_mem_t *mctx, isc_uint64_t **ctrp); /*%< * Free an array of query statistics counters allocated from the memory * context 'mctx'. * * This function is obsoleted. Use dns_stats_destroy() instead. */ ISC_LANG_ENDDECLS #endif /* DNS_STATS_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/order.h0000644000470500017500000000472212664710322020423 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: order.h,v 1.9 2007/06/19 23:47:17 tbox Exp $ */ #ifndef DNS_ORDER_H #define DNS_ORDER_H 1 /*! \file dns/order.h */ #include #include #include ISC_LANG_BEGINDECLS isc_result_t dns_order_create(isc_mem_t *mctx, dns_order_t **orderp); /*%< * Create a order object. * * Requires: * \li 'orderp' to be non NULL and '*orderp == NULL'. *\li 'mctx' to be valid. * * Returns: *\li ISC_R_SUCCESS *\li ISC_R_NOMEMORY */ isc_result_t dns_order_add(dns_order_t *order, dns_name_t *name, dns_rdatatype_t rdtype, dns_rdataclass_t rdclass, unsigned int mode); /*%< * Add a entry to the end of the order list. * * Requires: * \li 'order' to be valid. *\li 'name' to be valid. *\li 'mode' to be one of #DNS_RDATASERATTR_RANDOMIZE, * #DNS_RDATASERATTR_RANDOMIZE or zero (#DNS_RDATASERATTR_CYCLIC). * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY */ unsigned int dns_order_find(dns_order_t *order, dns_name_t *name, dns_rdatatype_t rdtype, dns_rdataclass_t rdclass); /*%< * Find the first matching entry on the list. * * Requires: *\li 'order' to be valid. *\li 'name' to be valid. * * Returns the mode set by dns_order_add() or zero. */ void dns_order_attach(dns_order_t *source, dns_order_t **target); /*%< * Attach to the 'source' object. * * Requires: * \li 'source' to be valid. *\li 'target' to be non NULL and '*target == NULL'. */ void dns_order_detach(dns_order_t **orderp); /*%< * Detach from the object. Clean up if last this was the last * reference. * * Requires: *\li '*orderp' to be valid. */ ISC_LANG_ENDDECLS #endif /* DNS_ORDER_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/Makefile.in0000644000470500017500000000424712664710322021206 0ustar lamontlamont# Copyright (C) 2004, 2007-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2003 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.60 2011/11/14 18:32:34 each Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ HEADERS = acache.h acl.h adb.h bit.h byaddr.h cache.h callbacks.h cert.h \ client.h clientinfo.h compress.h \ db.h dbiterator.h dbtable.h diff.h dispatch.h \ dlz.h dlz_dlopen.h dns64.h dnssec.h ds.h dsdigest.h \ ecdb.h events.h fixedname.h forward.h geoip.h iptable.h \ journal.h keydata.h keyflags.h keytable.h keyvalues.h \ lib.h lookup.h log.h master.h masterdump.h message.h \ name.h ncache.h nsec.h nsec3.h opcode.h order.h \ peer.h portlist.h private.h \ rbt.h rcode.h rdata.h rdataclass.h rdatalist.h \ rdataset.h rdatasetiter.h rdataslab.h rdatatype.h request.h \ resolver.h result.h rootns.h rpz.h rriterator.h rrl.h \ sdb.h sdlz.h secalg.h secproto.h soa.h ssu.h stats.h \ tcpmsg.h time.h timer.h tkey.h tsec.h tsig.h ttl.h types.h \ update.h validator.h version.h view.h xfrin.h \ zone.h zonekey.h zt.h GENHEADERS = enumclass.h enumtype.h rdatastruct.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/dns install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/dns ; \ done for i in ${GENHEADERS}; do \ ${INSTALL_DATA} $$i ${DESTDIR}${includedir}/dns ; \ done bind9-9.10.3.dfsg.P4/lib/dns/include/dns/acl.h0000644000470500017500000001534212664710322020047 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2011, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: acl.h,v 1.35 2011/06/17 23:47:49 tbox Exp $ */ #ifndef DNS_ACL_H #define DNS_ACL_H 1 /***** ***** Module Info *****/ /*! \file dns/acl.h * \brief * Address match list handling. */ /*** *** Imports ***/ #include #include #include #include #ifdef HAVE_GEOIP #include #endif #include #include #include #ifdef HAVE_GEOIP #include #endif /*** *** Types ***/ typedef enum { dns_aclelementtype_ipprefix, dns_aclelementtype_keyname, dns_aclelementtype_nestedacl, dns_aclelementtype_localhost, dns_aclelementtype_localnets, #ifdef HAVE_GEOIP dns_aclelementtype_geoip, #endif /* HAVE_GEOIP */ dns_aclelementtype_any } dns_aclelementtype_t; typedef struct dns_aclipprefix dns_aclipprefix_t; struct dns_aclipprefix { isc_netaddr_t address; /* IP4/IP6 */ unsigned int prefixlen; }; struct dns_aclelement { dns_aclelementtype_t type; isc_boolean_t negative; dns_name_t keyname; #ifdef HAVE_GEOIP dns_geoip_elem_t geoip_elem; #endif /* HAVE_GEOIP */ dns_acl_t *nestedacl; int node_num; }; struct dns_acl { unsigned int magic; isc_mem_t *mctx; isc_refcount_t refcount; dns_iptable_t *iptable; #define node_count iptable->radix->num_added_node dns_aclelement_t *elements; isc_boolean_t has_negatives; unsigned int alloc; /*%< Elements allocated */ unsigned int length; /*%< Elements initialized */ char *name; /*%< Temporary use only */ ISC_LINK(dns_acl_t) nextincache; /*%< Ditto */ }; struct dns_aclenv { dns_acl_t *localhost; dns_acl_t *localnets; isc_boolean_t match_mapped; #ifdef HAVE_GEOIP dns_geoip_databases_t *geoip; #endif }; #define DNS_ACL_MAGIC ISC_MAGIC('D','a','c','l') #define DNS_ACL_VALID(a) ISC_MAGIC_VALID(a, DNS_ACL_MAGIC) /*** *** Functions ***/ ISC_LANG_BEGINDECLS isc_result_t dns_acl_create(isc_mem_t *mctx, int n, dns_acl_t **target); /*%< * Create a new ACL, including an IP table and an array with room * for 'n' ACL elements. The elements are uninitialized and the * length is 0. */ isc_result_t dns_acl_any(isc_mem_t *mctx, dns_acl_t **target); /*%< * Create a new ACL that matches everything. */ isc_result_t dns_acl_none(isc_mem_t *mctx, dns_acl_t **target); /*%< * Create a new ACL that matches nothing. */ isc_boolean_t dns_acl_isany(dns_acl_t *acl); /*%< * Test whether ACL is set to "{ any; }" */ isc_boolean_t dns_acl_isnone(dns_acl_t *acl); /*%< * Test whether ACL is set to "{ none; }" */ isc_result_t dns_acl_merge(dns_acl_t *dest, dns_acl_t *source, isc_boolean_t pos); /*%< * Merge the contents of one ACL into another. Call dns_iptable_merge() * for the IP tables, then concatenate the element arrays. * * If pos is set to false, then the nested ACL is to be negated. This * means reverse the sense of each *positive* element or IP table node, * but leave negatives alone, so as to prevent a double-negative causing * an unexpected positive match in the parent ACL. */ void dns_acl_attach(dns_acl_t *source, dns_acl_t **target); /*%< * Attach to acl 'source'. * * Requires: *\li 'source' to be a valid acl. *\li 'target' to be non NULL and '*target' to be NULL. */ void dns_acl_detach(dns_acl_t **aclp); /*%< * Detach the acl. On final detach the acl must not be linked on any * list. * * Requires: *\li '*aclp' to be a valid acl. * * Insists: *\li '*aclp' is not linked on final detach. */ isc_boolean_t dns_acl_isinsecure(const dns_acl_t *a); /*%< * Return #ISC_TRUE iff the acl 'a' is considered insecure, that is, * if it contains IP addresses other than those of the local host. * This is intended for applications such as printing warning * messages for suspect ACLs; it is not intended for making access * control decisions. We make no guarantee that an ACL for which * this function returns #ISC_FALSE is safe. */ isc_result_t dns_aclenv_init(isc_mem_t *mctx, dns_aclenv_t *env); /*%< * Initialize ACL environment, setting up localhost and localnets ACLs */ void dns_aclenv_copy(dns_aclenv_t *t, dns_aclenv_t *s); void dns_aclenv_destroy(dns_aclenv_t *env); isc_result_t dns_acl_match(const isc_netaddr_t *reqaddr, const dns_name_t *reqsigner, const dns_acl_t *acl, const dns_aclenv_t *env, int *match, const dns_aclelement_t **matchelt); /*%< * General, low-level ACL matching. This is expected to * be useful even for weird stuff like the topology and sortlist statements. * * Match the address 'reqaddr', and optionally the key name 'reqsigner', * against 'acl'. 'reqsigner' may be NULL. * * If there is a match, '*match' will be set to an integer whose absolute * value corresponds to the order in which the matching value was inserted * into the ACL. For a positive match, this value will be positive; for a * negative match, it will be negative. * * If there is no match, *match will be set to zero. * * If there is a match in the element list (either positive or negative) * and 'matchelt' is non-NULL, *matchelt will be pointed to the matching * element. * * 'env' points to the current ACL environment, including the * current values of localhost and localnets and (if applicable) * the GeoIP context. * * Returns: *\li #ISC_R_SUCCESS Always succeeds. */ isc_boolean_t dns_aclelement_match(const isc_netaddr_t *reqaddr, const dns_name_t *reqsigner, const dns_aclelement_t *e, const dns_aclenv_t *env, const dns_aclelement_t **matchelt); /*%< * Like dns_acl_match, but matches against the single ACL element 'e' * rather than a complete ACL, and returns ISC_TRUE iff it matched. * * To determine whether the match was positive or negative, the * caller should examine e->negative. Since the element 'e' may be * a reference to a named ACL or a nested ACL, a matching element * returned through 'matchelt' is not necessarily 'e' itself. */ ISC_LANG_ENDDECLS #endif /* DNS_ACL_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/rdataclass.h0000644000470500017500000000441512664710322021430 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rdataclass.h,v 1.24 2007/06/19 23:47:17 tbox Exp $ */ #ifndef DNS_RDATACLASS_H #define DNS_RDATACLASS_H 1 /*! \file dns/rdataclass.h */ #include #include ISC_LANG_BEGINDECLS isc_result_t dns_rdataclass_fromtext(dns_rdataclass_t *classp, isc_textregion_t *source); /*%< * Convert the text 'source' refers to into a DNS class. * * Requires: *\li 'classp' is a valid pointer. * *\li 'source' is a valid text region. * * Returns: *\li #ISC_R_SUCCESS on success *\li #DNS_R_UNKNOWN class is unknown */ isc_result_t dns_rdataclass_totext(dns_rdataclass_t rdclass, isc_buffer_t *target); /*%< * Put a textual representation of class 'rdclass' into 'target'. * * Requires: *\li 'rdclass' is a valid class. * *\li 'target' is a valid text buffer. * * Ensures, * if the result is success: *\li The used space in 'target' is updated. * * Returns: *\li #ISC_R_SUCCESS on success *\li #ISC_R_NOSPACE target buffer is too small */ void dns_rdataclass_format(dns_rdataclass_t rdclass, char *array, unsigned int size); /*%< * Format a human-readable representation of the class 'rdclass' * into the character array 'array', which is of size 'size'. * The resulting string is guaranteed to be null-terminated. */ #define DNS_RDATACLASS_FORMATSIZE sizeof("CLASS65535") /*%< * Minimum size of array to pass to dns_rdataclass_format(). */ ISC_LANG_ENDDECLS #endif /* DNS_RDATACLASS_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/zone.h0000644000470500017500000015745212664710322020274 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef DNS_ZONE_H #define DNS_ZONE_H 1 /*! \file dns/zone.h */ /*** *** Imports ***/ #include #include #include #include #include #include #include #include #include #include typedef enum { dns_zone_none, dns_zone_master, dns_zone_slave, dns_zone_stub, dns_zone_staticstub, dns_zone_key, dns_zone_dlz, dns_zone_redirect } dns_zonetype_t; typedef enum { dns_zonestat_none = 0, dns_zonestat_terse, dns_zonestat_full } dns_zonestat_level_t; #define DNS_ZONEOPT_SERVERS 0x00000001U /*%< perform server checks */ #define DNS_ZONEOPT_PARENTS 0x00000002U /*%< perform parent checks */ #define DNS_ZONEOPT_CHILDREN 0x00000004U /*%< perform child checks */ #define DNS_ZONEOPT_NOTIFY 0x00000008U /*%< perform NOTIFY */ #define DNS_ZONEOPT_MANYERRORS 0x00000010U /*%< return many errors on load */ #define DNS_ZONEOPT_IXFRFROMDIFFS 0x00000020U /*%< calculate differences */ #define DNS_ZONEOPT_NOMERGE 0x00000040U /*%< don't merge journal */ #define DNS_ZONEOPT_CHECKNS 0x00000080U /*%< check if NS's are addresses */ #define DNS_ZONEOPT_FATALNS 0x00000100U /*%< DNS_ZONEOPT_CHECKNS is fatal */ #define DNS_ZONEOPT_MULTIMASTER 0x00000200U /*%< this zone has multiple masters */ #define DNS_ZONEOPT_USEALTXFRSRC 0x00000400U /*%< use alternate transfer sources */ #define DNS_ZONEOPT_CHECKNAMES 0x00000800U /*%< check-names */ #define DNS_ZONEOPT_CHECKNAMESFAIL 0x00001000U /*%< fatal check-name failures */ #define DNS_ZONEOPT_CHECKWILDCARD 0x00002000U /*%< check for internal wildcards */ #define DNS_ZONEOPT_CHECKMX 0x00004000U /*%< check-mx */ #define DNS_ZONEOPT_CHECKMXFAIL 0x00008000U /*%< fatal check-mx failures */ #define DNS_ZONEOPT_CHECKINTEGRITY 0x00010000U /*%< perform integrity checks */ #define DNS_ZONEOPT_CHECKSIBLING 0x00020000U /*%< perform sibling glue checks */ #define DNS_ZONEOPT_NOCHECKNS 0x00040000U /*%< disable IN NS address checks */ #define DNS_ZONEOPT_WARNMXCNAME 0x00080000U /*%< warn on MX CNAME check */ #define DNS_ZONEOPT_IGNOREMXCNAME 0x00100000U /*%< ignore MX CNAME check */ #define DNS_ZONEOPT_WARNSRVCNAME 0x00200000U /*%< warn on SRV CNAME check */ #define DNS_ZONEOPT_IGNORESRVCNAME 0x00400000U /*%< ignore SRV CNAME check */ #define DNS_ZONEOPT_UPDATECHECKKSK 0x00800000U /*%< check dnskey KSK flag */ #define DNS_ZONEOPT_TRYTCPREFRESH 0x01000000U /*%< try tcp refresh on udp failure */ #define DNS_ZONEOPT_NOTIFYTOSOA 0x02000000U /*%< Notify the SOA MNAME */ #define DNS_ZONEOPT_NSEC3TESTZONE 0x04000000U /*%< nsec3-test-zone */ #define DNS_ZONEOPT_SECURETOINSECURE 0x08000000U /*%< dnssec-secure-to-insecure */ #define DNS_ZONEOPT_DNSKEYKSKONLY 0x10000000U /*%< dnssec-dnskey-kskonly */ #define DNS_ZONEOPT_CHECKDUPRR 0x20000000U /*%< check-dup-records */ #define DNS_ZONEOPT_CHECKDUPRRFAIL 0x40000000U /*%< fatal check-dup-records failures */ #define DNS_ZONEOPT_CHECKSPF 0x80000000U /*%< check SPF records */ /* * The following zone options are shifted left into the * higher-order 32 bits of the options. */ #define DNS_ZONEOPT2_CHECKTTL 0x00000001 /*%< check max-zone-ttl */ #ifndef NOMINUM_PUBLIC /* * Nominum specific options build down. */ #define DNS_ZONEOPT_NOTIFYFORWARD 0x80000000U /* forward notify to master */ #endif /* NOMINUM_PUBLIC */ /* * Zone key maintenance options */ #define DNS_ZONEKEY_ALLOW 0x00000001U /*%< fetch keys on command */ #define DNS_ZONEKEY_MAINTAIN 0x00000002U /*%< publish/sign on schedule */ #define DNS_ZONEKEY_CREATE 0x00000004U /*%< make keys when needed */ #define DNS_ZONEKEY_FULLSIGN 0x00000008U /*%< roll to new keys immediately */ #define DNS_ZONEKEY_NORESIGN 0x00000010U /*%< no automatic resigning */ #ifndef DNS_ZONE_MINREFRESH #define DNS_ZONE_MINREFRESH 300 /*%< 5 minutes */ #endif #ifndef DNS_ZONE_MAXREFRESH #define DNS_ZONE_MAXREFRESH 2419200 /*%< 4 weeks */ #endif #ifndef DNS_ZONE_DEFAULTREFRESH #define DNS_ZONE_DEFAULTREFRESH 3600 /*%< 1 hour */ #endif #ifndef DNS_ZONE_MINRETRY #define DNS_ZONE_MINRETRY 300 /*%< 5 minutes */ #endif #ifndef DNS_ZONE_MAXRETRY #define DNS_ZONE_MAXRETRY 1209600 /*%< 2 weeks */ #endif #ifndef DNS_ZONE_DEFAULTRETRY #define DNS_ZONE_DEFAULTRETRY 60 /*%< 1 minute, subject to exponential backoff */ #endif #define DNS_ZONESTATE_XFERRUNNING 1 #define DNS_ZONESTATE_XFERDEFERRED 2 #define DNS_ZONESTATE_SOAQUERY 3 #define DNS_ZONESTATE_ANY 4 ISC_LANG_BEGINDECLS /*** *** Functions ***/ isc_result_t dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx); /*%< * Creates a new empty zone and attach '*zonep' to it. * * Requires: *\li 'zonep' to point to a NULL pointer. *\li 'mctx' to be a valid memory context. * * Ensures: *\li '*zonep' refers to a valid zone. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li #ISC_R_UNEXPECTED */ void dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass); /*%< * Sets the class of a zone. This operation can only be performed * once on a zone. * * Require: *\li 'zone' to be a valid zone. *\li dns_zone_setclass() not to have been called since the zone was * created. *\li 'rdclass' != dns_rdataclass_none. */ dns_rdataclass_t dns_zone_getclass(dns_zone_t *zone); /*%< * Returns the current zone class. * * Requires: *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp); isc_uint32_t dns_zone_getserial(dns_zone_t *zone); /*%< * Returns the current serial number of the zone. On success, the SOA * serial of the zone will be copied into '*serialp'. * dns_zone_getserial() cannot catch failure cases and is deprecated by * dns_zone_getserial2(). * * Requires: *\li 'zone' to be a valid zone. *\li 'serialp' to be non NULL * * Returns: *\li #ISC_R_SUCCESS *\li #DNS_R_NOTLOADED zone DB is not loaded */ void dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type); /*%< * Sets the zone type. This operation can only be performed once on * a zone. * * Requires: *\li 'zone' to be a valid zone. *\li dns_zone_settype() not to have been called since the zone was * created. *\li 'type' != dns_zone_none */ void dns_zone_setview(dns_zone_t *zone, dns_view_t *view); /*%< * Associate the zone with a view. * * Require: *\li 'zone' to be a valid zone. */ dns_view_t * dns_zone_getview(dns_zone_t *zone); /*%< * Returns the zone's associated view. * * Requires: *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin); /*%< * Sets the zones origin to 'origin'. * * Require: *\li 'zone' to be a valid zone. *\li 'origin' to be non NULL. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY */ dns_name_t * dns_zone_getorigin(dns_zone_t *zone); /*%< * Returns the value of the origin. * * Require: *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_setfile(dns_zone_t *zone, const char *file); isc_result_t dns_zone_setfile2(dns_zone_t *zone, const char *file, dns_masterformat_t format); /*%< * Sets the name of the master file in the format of 'format' from which * the zone loads its database to 'file'. * * For zones that have no associated master file, 'file' will be NULL. * * For zones with persistent databases, the file name * setting is ignored. * * dns_zone_setfile() is a backward-compatible form of * dns_zone_setfile2(), which always specifies the * dns_masterformat_text (RFC1035) format. * * Require: *\li 'zone' to be a valid zone. * * Returns: *\li #ISC_R_NOMEMORY *\li #ISC_R_SUCCESS */ const char * dns_zone_getfile(dns_zone_t *zone); /*%< * Gets the name of the zone's master file, if any. * * Requires: *\li 'zone' to be valid initialised zone. * * Returns: *\li Pointer to null-terminated file name, or NULL. */ void dns_zone_setmaxttl(dns_zone_t *zone, isc_uint32_t maxttl); /*%< * Sets the max ttl of the zone. * * Requires: *\li 'zone' to be valid initialised zone. * * Returns: *\li void */ dns_ttl_t dns_zone_getmaxttl(dns_zone_t *zone); /*%< * Gets the max ttl of the zone. * * Requires: *\li 'zone' to be valid initialised zone. * * Returns: *\li isc_uint32_t maxttl. */ isc_result_t dns_zone_load(dns_zone_t *zone); isc_result_t dns_zone_loadnew(dns_zone_t *zone); isc_result_t dns_zone_loadandthaw(dns_zone_t *zone); /*%< * Cause the database to be loaded from its backing store. * Confirm that the minimum requirements for the zone type are * met, otherwise DNS_R_BADZONE is returned. * * dns_zone_loadnew() only loads zones that are not yet loaded. * dns_zone_load() also loads zones that are already loaded and * and whose master file has changed since the last load. * dns_zone_loadandthaw() is similar to dns_zone_load() but will * also re-enable DNS UPDATEs when the load completes. * * Require: *\li 'zone' to be a valid zone. * * Returns: *\li #ISC_R_UNEXPECTED *\li #ISC_R_SUCCESS *\li DNS_R_CONTINUE Incremental load has been queued. *\li DNS_R_UPTODATE The zone has already been loaded based on * file system timestamps. *\li DNS_R_BADZONE *\li Any result value from dns_db_load(). */ isc_result_t dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg); /*%< * Cause the database to be loaded from its backing store asynchronously. * Other zone maintenance functions are suspended until this is complete. * When finished, 'done' is called to inform the caller, with 'arg' as * its first argument and 'zone' as its second. (Normally, 'arg' is * expected to point to the zone table but is left undefined for testing * purposes.) * * Require: *\li 'zone' to be a valid zone. * * Returns: *\li #ISC_R_ALREADYRUNNING *\li #ISC_R_SUCCESS *\li #ISC_R_FAILURE *\li #ISC_R_NOMEMORY */ isc_boolean_t dns__zone_loadpending(dns_zone_t *zone); /*%< * Indicates whether the zone is waiting to be loaded asynchronously. * (Not currently intended for use outside of this module and associated * tests.) */ void dns_zone_attach(dns_zone_t *source, dns_zone_t **target); /*%< * Attach '*target' to 'source' incrementing its external * reference count. * * Require: *\li 'zone' to be a valid zone. *\li 'target' to be non NULL and '*target' to be NULL. */ void dns_zone_detach(dns_zone_t **zonep); /*%< * Detach from a zone decrementing its external reference count. * If this was the last external reference to the zone it will be * shut down and eventually freed. * * Require: *\li 'zonep' to point to a valid zone. */ void dns_zone_iattach(dns_zone_t *source, dns_zone_t **target); /*%< * Attach '*target' to 'source' incrementing its internal * reference count. This is intended for use by operations * such as zone transfers that need to prevent the zone * object from being freed but not from shutting down. * * Require: *\li The caller is running in the context of the zone's task. *\li 'zone' to be a valid zone. *\li 'target' to be non NULL and '*target' to be NULL. */ void dns_zone_idetach(dns_zone_t **zonep); /*%< * Detach from a zone decrementing its internal reference count. * If there are no more internal or external references to the * zone, it will be freed. * * Require: *\li The caller is running in the context of the zone's task. *\li 'zonep' to point to a valid zone. */ void dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value); /*%< * Sets ('value' == 'ISC_TRUE') / clears ('value' == 'IS_FALSE') * zone flags. Valid flag bits are DNS_ZONE_F_*. * * Requires *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_getdb(dns_zone_t *zone, dns_db_t **dbp); /*%< * Attach '*dbp' to the database to if it exists otherwise * return DNS_R_NOTLOADED. * * Require: *\li 'zone' to be a valid zone. *\li 'dbp' to be != NULL && '*dbp' == NULL. * * Returns: *\li #ISC_R_SUCCESS *\li DNS_R_NOTLOADED */ void dns_zone_setdb(dns_zone_t *zone, dns_db_t *db); /*%< * Sets the zone database to 'db'. * * This function is expected to be used to configure a zone with a * database which is not loaded from a file or zone transfer. * It can be used for a general purpose zone, but right now its use * is limited to static-stub zones to avoid possible undiscovered * problems in the general cases. * * Require: *\li 'zone' to be a valid zone of static-stub. *\li zone doesn't have a database. */ isc_result_t dns_zone_setdbtype(dns_zone_t *zone, unsigned int dbargc, const char * const *dbargv); /*%< * Sets the database type to dbargv[0] and database arguments * to subsequent dbargv elements. * 'db_type' is not checked to see if it is a valid database type. * * Require: *\li 'zone' to be a valid zone. *\li 'database' to be non NULL. *\li 'dbargc' to be >= 1 *\li 'dbargv' to point to dbargc NULL-terminated strings * * Returns: *\li #ISC_R_NOMEMORY *\li #ISC_R_SUCCESS */ isc_result_t dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx); /*%< * Returns the current dbtype. isc_mem_free() should be used * to free 'argv' after use. * * Require: *\li 'zone' to be a valid zone. *\li 'argv' to be non NULL and *argv to be NULL. *\li 'mctx' to be valid. * * Returns: *\li #ISC_R_NOMEMORY *\li #ISC_R_SUCCESS */ void dns_zone_markdirty(dns_zone_t *zone); /*%< * Mark a zone as 'dirty'. * * Require: *\li 'zone' to be a valid zone. */ void dns_zone_expire(dns_zone_t *zone); /*%< * Mark the zone as expired. If the zone requires dumping cause it to * be initiated. Set the refresh and retry intervals to there default * values and unload the zone. * * Require *\li 'zone' to be a valid zone. */ void dns_zone_refresh(dns_zone_t *zone); /*%< * Initiate zone up to date checks. The zone must already be being * managed. * * Require *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_flush(dns_zone_t *zone); /*%< * Write the zone to database if there are uncommitted changes. * * Require: *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_dump(dns_zone_t *zone); /*%< * Write the zone to database. * * Require: *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_dumptostream(dns_zone_t *zone, FILE *fd); isc_result_t dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, const dns_master_style_t *style); isc_result_t dns_zone_dumptostream3(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, const dns_master_style_t *style, const isc_uint32_t rawversion); /*%< * Write the zone to stream 'fd' in the specified 'format'. * If the 'format' is dns_masterformat_text (RFC1035), 'style' also * specifies the file style (e.g., &dns_master_style_default). * * dns_zone_dumptostream() is a backward-compatible form of * dns_zone_dumptostream2(), which always uses the dns_masterformat_text * format and the dns_master_style_default style. * * dns_zone_dumptostream2() is a backward-compatible form of * dns_zone_dumptostream3(), which always uses the current * default raw file format version. * * Note that dns_zone_dumptostream3() is the most flexible form. It * can also provide the functionality of dns_zone_fulldumptostream(). * * Require: *\li 'zone' to be a valid zone. *\li 'fd' to be a stream open for writing. */ isc_result_t dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd); /*%< * The same as dns_zone_dumptostream, but dumps the zone with * different dump settings (dns_master_style_full). * * Require: *\li 'zone' to be a valid zone. *\li 'fd' to be a stream open for writing. */ void dns_zone_maintenance(dns_zone_t *zone); /*%< * Perform regular maintenance on the zone. This is called as a * result of a zone being managed. * * Require *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters, isc_uint32_t count); isc_result_t dns_zone_setmasterswithkeys(dns_zone_t *zone, const isc_sockaddr_t *masters, dns_name_t **keynames, isc_uint32_t count); /*%< * Set the list of master servers for the zone. * * Require: *\li 'zone' to be a valid zone. *\li 'masters' array of isc_sockaddr_t with port set or NULL. *\li 'count' the number of masters. *\li 'keynames' array of dns_name_t's for tsig keys or NULL. * * \li dns_zone_setmasters() is just a wrapper to setmasterswithkeys(), * passing NULL in the keynames field. * * \li If 'masters' is NULL then 'count' must be zero. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li Any result dns_name_dup() can return, if keynames!=NULL */ isc_result_t dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify, isc_uint32_t count); isc_result_t dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify, dns_name_t **keynames, isc_uint32_t count); isc_result_t dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify, const isc_dscp_t *dscps, dns_name_t **keynames, isc_uint32_t count); /*%< * Set the list of additional servers to be notified when * a zone changes. To clear the list use 'count = 0'. * * dns_zone_alsonotifywithkeys() allows each notify address to * be associated with a TSIG key. * * Require: *\li 'zone' to be a valid zone. *\li 'notify' to be non-NULL if count != 0. *\li 'count' to be the number of notifiees. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY */ void dns_zone_unload(dns_zone_t *zone); /*%< * detach the database from the zone structure. * * Require: *\li 'zone' to be a valid zone. */ void dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value); void dns_zone_setoption2(dns_zone_t *zone, unsigned int option, isc_boolean_t value); /*%< * Set the given options on ('value' == ISC_TRUE) or off * ('value' == #ISC_FALSE). * * dns_zone_setoption2() has been introduced because the number * of options needed now exceeds the 32 bits in the zone->options * field; it should be used set options with names beginning * with DNS_ZONEOPT2_. * * Require: *\li 'zone' to be a valid zone. */ unsigned int dns_zone_getoptions(dns_zone_t *zone); unsigned int dns_zone_getoptions2(dns_zone_t *zone); /*%< * Returns the current zone options. * * Callers should be aware there is now more than one set of zone * options. dns_zone_getoptions2() has been introduced because the * number of options needed now exceeds the 32 bits in the * zone->options field. It returns the options whose names begin * with DNS_ZONEOPT2_. * * Require: *\li 'zone' to be a valid zone. */ void dns_zone_setkeyopt(dns_zone_t *zone, unsigned int option, isc_boolean_t value); /*%< * Set key options on ('value' == ISC_TRUE) or off ('value' == * #ISC_FALSE). * * Require: *\li 'zone' to be a valid zone. */ unsigned int dns_zone_getkeyopts(dns_zone_t *zone); /*%< * Returns the current zone key options. * * Require: *\li 'zone' to be a valid zone. */ void dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val); /*%< * Set the minimum refresh time. * * Requires: *\li 'zone' is valid. *\li val > 0. */ void dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val); /*%< * Set the maximum refresh time. * * Requires: *\li 'zone' is valid. *\li val > 0. */ void dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val); /*%< * Set the minimum retry time. * * Requires: *\li 'zone' is valid. *\li val > 0. */ void dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val); /*%< * Set the maximum retry time. * * Requires: *\li 'zone' is valid. * val > 0. */ isc_result_t dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource); isc_result_t dns_zone_setaltxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource); /*%< * Set the source address to be used in IPv4 zone transfers. * * Require: *\li 'zone' to be a valid zone. *\li 'xfrsource' to contain the address. * * Returns: *\li #ISC_R_SUCCESS */ isc_sockaddr_t * dns_zone_getxfrsource4(dns_zone_t *zone); isc_sockaddr_t * dns_zone_getaltxfrsource4(dns_zone_t *zone); /*%< * Returns the source address set by a previous dns_zone_setxfrsource4 * call, or the default of inaddr_any, port 0. * * Require: *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_setxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp); isc_result_t dns_zone_setaltxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp); /*%< * Set the DSCP value associated with the transfer/alt-transfer source. * * Require: *\li 'zone' to be a valid zone. * * Returns: *\li #ISC_R_SUCCESS */ isc_dscp_t dns_zone_getxfrsource4dscp(dns_zone_t *zone); isc_dscp_t dns_zone_getaltxfrsource4dscp(dns_zone_t *zone); /*%/ * Get the DSCP value associated with the transfer/alt-transfer source. * * Require: *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource); isc_result_t dns_zone_setaltxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource); /*%< * Set the source address to be used in IPv6 zone transfers. * * Require: *\li 'zone' to be a valid zone. *\li 'xfrsource' to contain the address. * * Returns: *\li #ISC_R_SUCCESS */ isc_sockaddr_t * dns_zone_getxfrsource6(dns_zone_t *zone); isc_sockaddr_t * dns_zone_getaltxfrsource6(dns_zone_t *zone); /*%< * Returns the source address set by a previous dns_zone_setxfrsource6 * call, or the default of in6addr_any, port 0. * * Require: *\li 'zone' to be a valid zone. */ isc_dscp_t dns_zone_getxfrsource6dscp(dns_zone_t *zone); isc_dscp_t dns_zone_getaltxfrsource6dscp(dns_zone_t *zone); /*%/ * Get the DSCP value associated with the transfer/alt-transfer source. * * Require: *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_setxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp); isc_result_t dns_zone_setaltxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp); /*%< * Set the DSCP value associated with the transfer/alt-transfer source. * * Require: *\li 'zone' to be a valid zone. * * Returns: *\li #ISC_R_SUCCESS */ isc_result_t dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc); /*%< * Set the source address to be used with IPv4 NOTIFY messages. * * Require: *\li 'zone' to be a valid zone. *\li 'notifysrc' to contain the address. * * Returns: *\li #ISC_R_SUCCESS */ isc_sockaddr_t * dns_zone_getnotifysrc4(dns_zone_t *zone); /*%< * Returns the source address set by a previous dns_zone_setnotifysrc4 * call, or the default of inaddr_any, port 0. * * Require: *\li 'zone' to be a valid zone. */ isc_dscp_t dns_zone_getnotifysrc4dscp(dns_zone_t *zone); /*%/ * Get the DSCP value associated with the notify source. * * Require: *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_setnotifysrc4dscp(dns_zone_t *zone, isc_dscp_t dscp); /*%< * Set the DSCP value associated with the notify source. * * Require: *\li 'zone' to be a valid zone. * * Returns: *\li #ISC_R_SUCCESS */ isc_result_t dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc); /*%< * Set the source address to be used with IPv6 NOTIFY messages. * * Require: *\li 'zone' to be a valid zone. *\li 'notifysrc' to contain the address. * * Returns: *\li #ISC_R_SUCCESS */ isc_sockaddr_t * dns_zone_getnotifysrc6(dns_zone_t *zone); /*%< * Returns the source address set by a previous dns_zone_setnotifysrc6 * call, or the default of in6addr_any, port 0. * * Require: *\li 'zone' to be a valid zone. */ isc_dscp_t dns_zone_getnotifysrc6dscp(dns_zone_t *zone); /*%/ * Get the DSCP value associated with the notify source. * * Require: *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_setnotifysrc6dscp(dns_zone_t *zone, isc_dscp_t dscp); /*%< * Set the DSCP value associated with the notify source. * * Require: *\li 'zone' to be a valid zone. * * Returns: *\li #ISC_R_SUCCESS */ void dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl); /*%< * Sets the notify acl list for the zone. * * Require: *\li 'zone' to be a valid zone. *\li 'acl' to be a valid acl. */ void dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl); /*%< * Sets the query acl list for the zone. * * Require: *\li 'zone' to be a valid zone. *\li 'acl' to be a valid acl. */ void dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl); /*%< * Sets the query-on acl list for the zone. * * Require: *\li 'zone' to be a valid zone. *\li 'acl' to be a valid acl. */ void dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl); /*%< * Sets the update acl list for the zone. * * Require: *\li 'zone' to be a valid zone. *\li 'acl' to be valid acl. */ void dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl); /*%< * Sets the forward unsigned updates acl list for the zone. * * Require: *\li 'zone' to be a valid zone. *\li 'acl' to be valid acl. */ void dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl); /*%< * Sets the transfer acl list for the zone. * * Require: *\li 'zone' to be a valid zone. *\li 'acl' to be valid acl. */ dns_acl_t * dns_zone_getnotifyacl(dns_zone_t *zone); /*%< * Returns the current notify acl or NULL. * * Require: *\li 'zone' to be a valid zone. * * Returns: *\li acl a pointer to the acl. *\li NULL */ dns_acl_t * dns_zone_getqueryacl(dns_zone_t *zone); /*%< * Returns the current query acl or NULL. * * Require: *\li 'zone' to be a valid zone. * * Returns: *\li acl a pointer to the acl. *\li NULL */ dns_acl_t * dns_zone_getqueryonacl(dns_zone_t *zone); /*%< * Returns the current query-on acl or NULL. * * Require: *\li 'zone' to be a valid zone. * * Returns: *\li acl a pointer to the acl. *\li NULL */ dns_acl_t * dns_zone_getupdateacl(dns_zone_t *zone); /*%< * Returns the current update acl or NULL. * * Require: *\li 'zone' to be a valid zone. * * Returns: *\li acl a pointer to the acl. *\li NULL */ dns_acl_t * dns_zone_getforwardacl(dns_zone_t *zone); /*%< * Returns the current forward unsigned updates acl or NULL. * * Require: *\li 'zone' to be a valid zone. * * Returns: *\li acl a pointer to the acl. *\li NULL */ dns_acl_t * dns_zone_getxfracl(dns_zone_t *zone); /*%< * Returns the current transfer acl or NULL. * * Require: *\li 'zone' to be a valid zone. * * Returns: *\li acl a pointer to the acl. *\li NULL */ void dns_zone_clearupdateacl(dns_zone_t *zone); /*%< * Clear the current update acl. * * Require: *\li 'zone' to be a valid zone. */ void dns_zone_clearforwardacl(dns_zone_t *zone); /*%< * Clear the current forward unsigned updates acl. * * Require: *\li 'zone' to be a valid zone. */ void dns_zone_clearnotifyacl(dns_zone_t *zone); /*%< * Clear the current notify acl. * * Require: *\li 'zone' to be a valid zone. */ void dns_zone_clearqueryacl(dns_zone_t *zone); /*%< * Clear the current query acl. * * Require: *\li 'zone' to be a valid zone. */ void dns_zone_clearqueryonacl(dns_zone_t *zone); /*%< * Clear the current query-on acl. * * Require: *\li 'zone' to be a valid zone. */ void dns_zone_clearxfracl(dns_zone_t *zone); /*%< * Clear the current transfer acl. * * Require: *\li 'zone' to be a valid zone. */ isc_boolean_t dns_zone_getupdatedisabled(dns_zone_t *zone); /*%< * Return update disabled. * Transient unless called when running in isc_task_exclusive() mode. */ void dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state); /*%< * Set update disabled. * Should only be called only when running in isc_task_exclusive() mode. * Failure to do so may result in updates being committed after the * call has been made. */ isc_boolean_t dns_zone_getzeronosoattl(dns_zone_t *zone); /*%< * Return zero-no-soa-ttl status. */ void dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state); /*%< * Set zero-no-soa-ttl status. */ void dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity); /*%< * Set the severity of name checking when loading a zone. * * Require: * \li 'zone' to be a valid zone. */ dns_severity_t dns_zone_getchecknames(dns_zone_t *zone); /*%< * Return the current severity of name checking. * * Require: *\li 'zone' to be a valid zone. */ void dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size); /*%< * Sets the journal size for the zone. * * Requires: *\li 'zone' to be a valid zone. */ isc_int32_t dns_zone_getjournalsize(dns_zone_t *zone); /*%< * Return the journal size as set with a previous call to * dns_zone_setjournalsize(). * * Requires: *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, dns_message_t *msg); /*%< * Tell the zone that it has received a NOTIFY message from another * server. This may cause some zone maintenance activity to occur. * * Requires: *\li 'zone' to be a valid zone. *\li '*from' to contain the address of the server from which 'msg' * was received. *\li 'msg' a message with opcode NOTIFY and qr clear. * * Returns: *\li DNS_R_REFUSED *\li DNS_R_NOTIMP *\li DNS_R_FORMERR *\li DNS_R_SUCCESS */ void dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin); /*%< * Set the maximum time (in seconds) that a zone transfer in (AXFR/IXFR) * of this zone will use before being aborted. * * Requires: * \li 'zone' to be valid initialised zone. */ isc_uint32_t dns_zone_getmaxxfrin(dns_zone_t *zone); /*%< * Returns the maximum transfer time for this zone. This will be * either the value set by the last call to dns_zone_setmaxxfrin() or * the default value of 1 hour. * * Requires: *\li 'zone' to be valid initialised zone. */ void dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout); /*%< * Set the maximum time (in seconds) that a zone transfer out (AXFR/IXFR) * of this zone will use before being aborted. * * Requires: * \li 'zone' to be valid initialised zone. */ isc_uint32_t dns_zone_getmaxxfrout(dns_zone_t *zone); /*%< * Returns the maximum transfer time for this zone. This will be * either the value set by the last call to dns_zone_setmaxxfrout() or * the default value of 1 hour. * * Requires: *\li 'zone' to be valid initialised zone. */ isc_result_t dns_zone_setjournal(dns_zone_t *zone, const char *journal); /*%< * Sets the filename used for journaling updates / IXFR transfers. * The default journal name is set by dns_zone_setfile() to be * "file.jnl". If 'journal' is NULL, the zone will have no * journal name. * * Requires: *\li 'zone' to be a valid zone. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY */ char * dns_zone_getjournal(dns_zone_t *zone); /*%< * Returns the journal name associated with this zone. * If no journal has been set this will be NULL. * * Requires: *\li 'zone' to be valid initialised zone. */ dns_zonetype_t dns_zone_gettype(dns_zone_t *zone); /*%< * Returns the type of the zone (master/slave/etc.) * * Requires: *\li 'zone' to be valid initialised zone. */ void dns_zone_settask(dns_zone_t *zone, isc_task_t *task); /*%< * Give a zone a task to work with. Any current task will be detached. * * Requires: *\li 'zone' to be valid. *\li 'task' to be valid. */ void dns_zone_gettask(dns_zone_t *zone, isc_task_t **target); /*%< * Attach '*target' to the zone's task. * * Requires: *\li 'zone' to be valid initialised zone. *\li 'zone' to have a task. *\li 'target' to be != NULL && '*target' == NULL. */ void dns_zone_notify(dns_zone_t *zone); /*%< * Generate notify events for this zone. * * Requires: *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump); /*%< * Replace the database of "zone" with a new database "db". * * If "dump" is ISC_TRUE, then the new zone contents are dumped * into to the zone's master file for persistence. When replacing * a zone database by one just loaded from a master file, set * "dump" to ISC_FALSE to avoid a redundant redump of the data just * loaded. Otherwise, it should be set to ISC_TRUE. * * If the "diff-on-reload" option is enabled in the configuration file, * the differences between the old and the new database are added to the * journal file, and the master file dump is postponed. * * Requires: * \li 'zone' to be a valid zone. * * Returns: * \li DNS_R_SUCCESS * \li DNS_R_BADZONE zone failed basic consistency checks: * * a single SOA must exist * * some NS records must exist. * Others */ isc_uint32_t dns_zone_getidlein(dns_zone_t *zone); /*%< * Requires: * \li 'zone' to be a valid zone. * * Returns: * \li number of seconds of idle time before we abort the transfer in. */ void dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein); /*%< * \li Set the idle timeout for transfer the. * \li Zero set the default value, 1 hour. * * Requires: * \li 'zone' to be a valid zone. */ isc_uint32_t dns_zone_getidleout(dns_zone_t *zone); /*%< * * Requires: * \li 'zone' to be a valid zone. * * Returns: * \li number of seconds of idle time before we abort a transfer out. */ void dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout); /*%< * \li Set the idle timeout for transfers out. * \li Zero set the default value, 1 hour. * * Requires: * \li 'zone' to be a valid zone. */ void dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table); /*%< * Get the simple-secure-update policy table. * * Requires: * \li 'zone' to be a valid zone. */ void dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table); /*%< * Set / clear the simple-secure-update policy table. * * Requires: * \li 'zone' to be a valid zone. */ isc_mem_t * dns_zone_getmctx(dns_zone_t *zone); /*%< * Get the memory context of a zone. * * Requires: * \li 'zone' to be a valid zone. */ dns_zonemgr_t * dns_zone_getmgr(dns_zone_t *zone); /*%< * If 'zone' is managed return the zone manager otherwise NULL. * * Requires: * \li 'zone' to be a valid zone. */ void dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval); /*%< * Set the zone's RRSIG validity interval. This is the length of time * for which DNSSEC signatures created as a result of dynamic updates * to secure zones will remain valid, in seconds. * * Requires: * \li 'zone' to be a valid zone. */ isc_uint32_t dns_zone_getsigvalidityinterval(dns_zone_t *zone); /*%< * Get the zone's RRSIG validity interval. * * Requires: * \li 'zone' to be a valid zone. */ void dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval); /*%< * Set the zone's RRSIG re-signing interval. A dynamic zone's RRSIG's * will be re-signed 'interval' amount of time before they expire. * * Requires: * \li 'zone' to be a valid zone. */ isc_uint32_t dns_zone_getsigresigninginterval(dns_zone_t *zone); /*%< * Get the zone's RRSIG re-signing interval. * * Requires: * \li 'zone' to be a valid zone. */ void dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype); /*%< * Sets zone notify method to "notifytype" */ isc_result_t dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg, dns_updatecallback_t callback, void *callback_arg); /*%< * Forward 'msg' to each master in turn until we get an answer or we * have exhausted the list of masters. 'callback' will be called with * ISC_R_SUCCESS if we get an answer and the returned message will be * passed as 'answer_message', otherwise a non ISC_R_SUCCESS result code * will be passed and answer_message will be NULL. The callback function * is responsible for destroying 'answer_message'. * (callback)(callback_arg, result, answer_message); * * Require: *\li 'zone' to be valid *\li 'msg' to be valid. *\li 'callback' to be non NULL. * Returns: *\li #ISC_R_SUCCESS if the message has been forwarded, *\li #ISC_R_NOMEMORY *\li Others */ isc_result_t dns_zone_next(dns_zone_t *zone, dns_zone_t **next); /*%< * Find the next zone in the list of managed zones. * * Requires: *\li 'zone' to be valid *\li The zone manager for the indicated zone MUST be locked * by the caller. This is not checked. *\li 'next' be non-NULL, and '*next' be NULL. * * Ensures: *\li 'next' points to a valid zone (result ISC_R_SUCCESS) or to NULL * (result ISC_R_NOMORE). */ isc_result_t dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first); /*%< * Find the first zone in the list of managed zones. * * Requires: *\li 'zonemgr' to be valid *\li The zone manager for the indicated zone MUST be locked * by the caller. This is not checked. *\li 'first' be non-NULL, and '*first' be NULL * * Ensures: *\li 'first' points to a valid zone (result ISC_R_SUCCESS) or to NULL * (result ISC_R_NOMORE). */ isc_result_t dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory); /*%< * Sets the name of the directory where private keys used for * online signing of dynamic zones are found. * * Require: *\li 'zone' to be a valid zone. * * Returns: *\li #ISC_R_NOMEMORY *\li #ISC_R_SUCCESS */ const char * dns_zone_getkeydirectory(dns_zone_t *zone); /*%< * Gets the name of the directory where private keys used for * online signing of dynamic zones are found. * * Requires: *\li 'zone' to be valid initialised zone. * * Returns: * Pointer to null-terminated file name, or NULL. */ isc_result_t dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, dns_zonemgr_t **zmgrp); /*%< * Create a zone manager. Note: the zone manager will not be able to * manage any zones until dns_zonemgr_setsize() has been run. * * Requires: *\li 'mctx' to be a valid memory context. *\li 'taskmgr' to be a valid task manager. *\li 'timermgr' to be a valid timer manager. *\li 'zmgrp' to point to a NULL pointer. */ isc_result_t dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones); /*%< * Set the size of the zone manager task pool. This must be run * before zmgr can be used for managing zones. Currently, it can only * be run once; the task pool cannot be resized. * * Requires: *\li zmgr is a valid zone manager. *\li zmgr->zonetasks has been initialized. */ isc_result_t dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep); /*%< * Allocate a new zone using a memory context from the * zone manager's memory context pool. * * Require: *\li 'zmgr' to be a valid zone manager. *\li 'zonep' != NULL and '*zonep' == NULL. */ isc_result_t dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone); /*%< * Bring the zone under control of a zone manager. * * Require: *\li 'zmgr' to be a valid zone manager. *\li 'zone' to be a valid zone. */ isc_result_t dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr); /*%< * Force zone maintenance of all loaded zones managed by 'zmgr' * to take place at the system's earliest convenience. */ void dns__zonemgr_run(isc_task_t *task, isc_event_t *event); /*%< * Event handler to call dns_zonemgr_forcemaint(); used to start * zone operations from a unit test. Not intended for use outside * libdns or related tests. */ void dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr); /*%< * Attempt to start any stalled zone transfers. */ void dns_zonemgr_shutdown(dns_zonemgr_t *zmgr); /*%< * Shut down the zone manager. * * Requires: *\li 'zmgr' to be a valid zone manager. */ void dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target); /*%< * Attach '*target' to 'source' incrementing its external * reference count. * * Require: *\li 'zone' to be a valid zone. *\li 'target' to be non NULL and '*target' to be NULL. */ void dns_zonemgr_detach(dns_zonemgr_t **zmgrp); /*%< * Detach from a zone manager. * * Requires: *\li '*zmgrp' is a valid, non-NULL zone manager pointer. * * Ensures: *\li '*zmgrp' is NULL. */ void dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone); /*%< * Release 'zone' from the managed by 'zmgr'. 'zmgr' is implicitly * detached from 'zone'. * * Requires: *\li 'zmgr' to be a valid zone manager. *\li 'zone' to be a valid zone. *\li 'zmgr' == 'zone->zmgr' * * Ensures: *\li 'zone->zmgr' == NULL; */ void dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value); /*%< * Set the maximum number of simultaneous transfers in allowed by * the zone manager. * * Requires: *\li 'zmgr' to be a valid zone manager. */ isc_uint32_t dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr); /*%< * Return the maximum number of simultaneous transfers in allowed. * * Requires: *\li 'zmgr' to be a valid zone manager. */ void dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value); /*%< * Set the number of zone transfers allowed per nameserver. * * Requires: *\li 'zmgr' to be a valid zone manager */ isc_uint32_t dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr); /*%< * Return the number of transfers allowed per nameserver. * * Requires: *\li 'zmgr' to be a valid zone manager. */ void dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit); /*%< * Set the number of simultaneous file descriptors available for * reading and writing masterfiles. * * Requires: *\li 'zmgr' to be a valid zone manager. *\li 'iolimit' to be positive. */ isc_uint32_t dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr); /*%< * Get the number of simultaneous file descriptors available for * reading and writing masterfiles. * * Requires: *\li 'zmgr' to be a valid zone manager. */ void dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value); /*%< * Set the number of SOA queries sent per second. * * Requires: *\li 'zmgr' to be a valid zone manager */ unsigned int dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr); /*%< * Return the number of SOA queries sent per second. * * Requires: *\li 'zmgr' to be a valid zone manager. */ unsigned int dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state); /*%< * Returns the number of zones in the specified state. * * Requires: *\li 'zmgr' to be a valid zone manager. *\li 'state' to be a valid DNS_ZONESTATE_ constant. */ void dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, isc_sockaddr_t *local, isc_time_t *now); /*%< * Add the pair of addresses to the unreachable cache. * * Requires: *\li 'zmgr' to be a valid zone manager. *\li 'remote' to be a valid sockaddr. *\li 'local' to be a valid sockaddr. */ isc_boolean_t dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, isc_sockaddr_t *local, isc_time_t *now); /*%< * Returns ISC_TRUE if the given local/remote address pair * is found in the zone maanger's unreachable cache. * * Requires: *\li 'zmgr' to be a valid zone manager. *\li 'remote' to be a valid sockaddr. *\li 'local' to be a valid sockaddr. *\li 'now' != NULL */ void dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, isc_sockaddr_t *local); /*%< * Remove the pair of addresses from the unreachable cache. * * Requires: *\li 'zmgr' to be a valid zone manager. *\li 'remote' to be a valid sockaddr. *\li 'local' to be a valid sockaddr. */ void dns_zone_forcereload(dns_zone_t *zone); /*%< * Force a reload of specified zone. * * Requires: *\li 'zone' to be a valid zone. */ isc_boolean_t dns_zone_isforced(dns_zone_t *zone); /*%< * Check if the zone is waiting a forced reload. * * Requires: * \li 'zone' to be a valid zone. */ isc_result_t dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on); /*%< * This function is obsoleted by dns_zone_setrequeststats(). */ isc_uint64_t * dns_zone_getstatscounters(dns_zone_t *zone); /*%< * This function is obsoleted by dns_zone_getrequeststats(). */ void dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats); /*%< * Set a general zone-maintenance statistics set 'stats' for 'zone'. This * function is expected to be called only on zone creation (when necessary). * Once installed, it cannot be removed or replaced. Also, there is no * interface to get the installed stats from the zone; the caller must keep the * stats to reference (e.g. dump) it later. * * Requires: * \li 'zone' to be a valid zone and does not have a statistics set already * installed. * *\li stats is a valid statistics supporting zone statistics counters * (see dns/stats.h). */ void dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats); void dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats); /*%< * Set additional statistics sets to zone. These are attached to the zone * but are not counted in the zone module; only the caller updates the * counters. * * Requires: * \li 'zone' to be a valid zone. * *\li stats is a valid statistics. */ isc_stats_t * dns_zone_getrequeststats(dns_zone_t *zone); dns_stats_t * dns_zone_getrcvquerystats(dns_zone_t *zone); /*%< * Get the additional statistics for zone, if one is installed. * * Requires: * \li 'zone' to be a valid zone. * * Returns: * \li when available, a pointer to the statistics set installed in zone; * otherwise NULL. */ void dns_zone_dialup(dns_zone_t *zone); /*%< * Perform dialup-time maintenance on 'zone'. */ void dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup); /*%< * Set the dialup type of 'zone' to 'dialup'. * * Requires: * \li 'zone' to be valid initialised zone. *\li 'dialup' to be a valid dialup type. */ void dns_zone_log(dns_zone_t *zone, int level, const char *msg, ...) ISC_FORMAT_PRINTF(3, 4); /*%< * Log the message 'msg...' at 'level', including text that identifies * the message as applying to 'zone'. */ void dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category, int level, const char *msg, ...) ISC_FORMAT_PRINTF(4, 5); /*%< * Log the message 'msg...' at 'level', including text that identifies * the message as applying to 'zone'. */ void dns_zone_name(dns_zone_t *zone, char *buf, size_t len); /*%< * Return the name of the zone with class and view. * * Requires: *\li 'zone' to be valid. *\li 'buf' to be non NULL. */ void dns_zone_nameonly(dns_zone_t *zone, char *buf, size_t len); /*%< * Return the name of the zone only. * * Requires: *\li 'zone' to be valid. *\li 'buf' to be non NULL. */ isc_result_t dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata); /*%< * Check if this record meets the check-names policy. * * Requires: * 'zone' to be valid. * 'name' to be valid. * 'rdata' to be valid. * * Returns: * DNS_R_SUCCESS passed checks. * DNS_R_BADOWNERNAME failed ownername checks. * DNS_R_BADNAME failed rdata checks. */ void dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache); /*%< * Associate the zone with an additional cache. * * Require: * 'zone' to be a valid zone. * 'acache' to be a non NULL pointer. * * Ensures: * 'zone' will have a reference to 'acache' */ void dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx); /*%< * Set the post load integrity callback function 'checkmx'. * 'checkmx' will be called if the MX TARGET is not within the zone. * * Require: * 'zone' to be a valid zone. */ void dns_zone_setchecksrv(dns_zone_t *zone, dns_checkmxfunc_t checksrv); /*%< * Set the post load integrity callback function 'checksrv'. * 'checksrv' will be called if the SRV TARGET is not within the zone. * * Require: * 'zone' to be a valid zone. */ void dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns); /*%< * Set the post load integrity callback function 'checkns'. * 'checkns' will be called if the NS TARGET is not within the zone. * * Require: * 'zone' to be a valid zone. */ void dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay); /*%< * Set the minimum delay between sets of notify messages. * * Requires: * 'zone' to be valid. */ isc_uint32_t dns_zone_getnotifydelay(dns_zone_t *zone); /*%< * Get the minimum delay between sets of notify messages. * * Requires: * 'zone' to be valid. */ void dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg); /*%< * Set the isself callback function and argument. * * isc_boolean_t * isself(dns_view_t *myview, dns_tsigkey_t *mykey, isc_netaddr_t *srcaddr, * isc_netaddr_t *destaddr, dns_rdataclass_t rdclass, void *arg); * * 'isself' returns ISC_TRUE if a non-recursive query from 'srcaddr' to * 'destaddr' with optional key 'mykey' for class 'rdclass' would be * delivered to 'myview'. */ void dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes); /*%< * Set the number of nodes that will be checked per quantum. */ void dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures); /*%< * Set the number of signatures that will be generated per quantum. */ isc_uint32_t dns_zone_getsignatures(dns_zone_t *zone); /*%< * Get the number of signatures that will be generated per quantum. */ isc_result_t dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid, isc_boolean_t deleteit); /*%< * Initiate/resume signing of the entire zone with the zone DNSKEY(s) * that match the given algorithm and keyid. */ isc_result_t dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param); /*%< * Incrementally add a NSEC3 chain that corresponds to 'nsec3param'. */ void dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type); dns_rdatatype_t dns_zone_getprivatetype(dns_zone_t *zone); /* * Get/Set the private record type. It is expected that these interfaces * will not be permanent. */ void dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign); /*%< * Update the zone's DNSKEY set from the key repository. * * If 'fullsign' is true, trigger an immediate full signing of * the zone with the new key. Otherwise, if there are no keys or * if the new keys are for algorithms that have already signed the * zone, then the zone can be re-signed incrementally. */ isc_result_t dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, unsigned int *errors); /*% * Check if the name servers for the zone are sane (have address, don't * refer to CNAMEs/DNAMEs. The number of constiancy errors detected in * returned in '*errors' * * Requires: * \li 'zone' to be valid. * \li 'db' to be valid. * \li 'version' to be valid or NULL. * \li 'errors' to be non NULL. * * Returns: * ISC_R_SUCCESS if there were no errors examining the zone contents. */ isc_result_t dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version); /*% * Check if CSD, CDNSKEY and DNSKEY are consistent. * * Requires: * \li 'zone' to be valid. * \li 'db' to be valid. * \li 'version' to be valid or NULL. * * Returns: *\li #ISC_R_SUCCESS *\li #DNS_R_BADCDS *\li #DNS_R_BADCDNSKEY * Others */ void dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added); /*% * Sets the value of zone->added, which should be ISC_TRUE for * zones that were originally added by "rndc addzone". * * Requires: * \li 'zone' to be valid. */ isc_boolean_t dns_zone_getadded(dns_zone_t *zone); /*% * Returns ISC_TRUE if the zone was originally added at runtime * using "rndc addzone". * * Requires: * \li 'zone' to be valid. */ isc_result_t dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db); /*% * Load the origin names for a writeable DLZ database. */ isc_boolean_t dns_zone_isdynamic(dns_zone_t *zone, isc_boolean_t ignore_freeze); /*% * Return true iff the zone is "dynamic", in the sense that the zone's * master file (if any) is written by the server, rather than being * updated manually and read by the server. * * This is true for slave zones, stub zones, key zones, and zones that * allow dynamic updates either by having an update policy ("ssutable") * or an "allow-update" ACL with a value other than exactly "{ none; }". * * If 'ignore_freeze' is true, then the zone which has had updates disabled * will still report itself to be dynamic. * * Requires: * \li 'zone' to be valid. */ isc_result_t dns_zone_setrefreshkeyinterval(dns_zone_t *zone, isc_uint32_t interval); /*% * Sets the frequency, in minutes, with which the key repository will be * checked to see if the keys for this zone have been updated. Any value * higher than 1440 minutes (24 hours) will be silently reduced. A * value of zero will return an out-of-range error. * * Requires: * \li 'zone' to be valid. */ isc_boolean_t dns_zone_getrequestixfr(dns_zone_t *zone); /*% * Returns the true/false value of the request-ixfr option in the zone. * * Requires: * \li 'zone' to be valid. */ void dns_zone_setrequestixfr(dns_zone_t *zone, isc_boolean_t flag); /*% * Sets the request-ixfr option for the zone. Either true or false. The * default value is determined by the setting of this option in the view. * * Requires: * \li 'zone' to be valid. */ void dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method); /*% * Sets the update method to use when incrementing the zone serial number * due to a DDNS update. Valid options are dns_updatemethod_increment * and dns_updatemethod_unixtime. * * Requires: * \li 'zone' to be valid. */ dns_updatemethod_t dns_zone_getserialupdatemethod(dns_zone_t *zone); /*% * Returns the update method to be used when incrementing the zone serial * number due to a DDNS update. * * Requires: * \li 'zone' to be valid. */ isc_result_t dns_zone_link(dns_zone_t *zone, dns_zone_t *raw); void dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw); isc_result_t dns_zone_keydone(dns_zone_t *zone, const char *data); isc_result_t dns_zone_setnsec3param(dns_zone_t *zone, isc_uint8_t hash, isc_uint8_t flags, isc_uint16_t iter, isc_uint8_t saltlen, unsigned char *salt, isc_boolean_t replace); /*% * Set the NSEC3 parameters for the zone. * * If 'replace' is ISC_TRUE, then the existing NSEC3 chain, if any, will * be replaced with the new one. If 'hash' is zero, then the replacement * chain will be NSEC rather than NSEC3. * * Requires: * \li 'zone' to be valid. */ void dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header); /*% * Set the data to be included in the header when the zone is dumped in * binary format. */ isc_result_t dns_zone_synckeyzone(dns_zone_t *zone); /*% * Force the managed key zone to synchronize, and start the key * maintenance timer. */ isc_result_t dns_zone_getloadtime(dns_zone_t *zone, isc_time_t *loadtime); /*% * Return the time when the zone was last loaded. */ isc_result_t dns_zone_getrefreshtime(dns_zone_t *zone, isc_time_t *refreshtime); /*% * Return the time when the (slave) zone will need to be refreshed. */ isc_result_t dns_zone_getexpiretime(dns_zone_t *zone, isc_time_t *expiretime); /*% * Return the time when the (slave) zone will expire. */ isc_result_t dns_zone_getrefreshkeytime(dns_zone_t *zone, isc_time_t *refreshkeytime); /*% * Return the time of the next scheduled DNSSEC key event. */ unsigned int dns_zone_getincludes(dns_zone_t *zone, char ***includesp); /*% * Return the number include files that were encountered * during load. If the number is greater than zero, 'includesp' * will point to an array containing the filenames. * * The array and its contents need to be freed using isc_mem_free. */ isc_result_t dns_zone_rpz_enable(dns_zone_t *zone, dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num); /*% * Set the response policy associated with a zone. */ void dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db); /*% * If a zone is a response policy zone, mark its new database. */ dns_rpz_num_t dns_zone_get_rpz_num(dns_zone_t *zone); void dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level); dns_zonestat_level_t dns_zone_getstatlevel(dns_zone_t *zone); /*% * Set and get the statistics reporting level for the zone; * full, terse, or none. */ ISC_LANG_ENDDECLS #endif /* DNS_ZONE_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/validator.h0000644000470500017500000001670312664710322021277 0ustar lamontlamont/* * Copyright (C) 2004-2010, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: validator.h,v 1.46 2010/02/25 05:08:01 tbox Exp $ */ #ifndef DNS_VALIDATOR_H #define DNS_VALIDATOR_H 1 /***** ***** Module Info *****/ /*! \file dns/validator.h * * \brief * DNS Validator * This is the BIND 9 validator, the module responsible for validating the * rdatasets and negative responses (messages). It makes use of zones in * the view and may fetch RRset to complete trust chains. It implements * DNSSEC as specified in RFC 4033, 4034 and 4035. * * It can also optionally implement ISC's DNSSEC look-aside validation. * * Correct operation is critical to preventing spoofed answers from secure * zones being accepted. * * MP: *\li The module ensures appropriate synchronization of data structures it * creates and manipulates. * * Reliability: *\li No anticipated impact. * * Resources: *\li TBS * * Security: *\li No anticipated impact. * * Standards: *\li RFCs: 1034, 1035, 2181, 4033, 4034, 4035. */ #include #include #include #include #include #include #include /* for dns_rdata_rrsig_t */ #include /*% * A dns_validatorevent_t is sent when a 'validation' completes. * \brief * 'name', 'rdataset', 'sigrdataset', and 'message' are the values that were * supplied when dns_validator_create() was called. They are returned to the * caller so that they may be freed. * * If the RESULT is ISC_R_SUCCESS and the answer is secure then * proofs[] will contain the names of the NSEC records that hold the * various proofs. Note the same name may appear multiple times. */ typedef struct dns_validatorevent { ISC_EVENT_COMMON(struct dns_validatorevent); dns_validator_t * validator; isc_result_t result; /* * Name and type of the response to be validated. */ dns_name_t * name; dns_rdatatype_t type; /* * Rdata and RRSIG (if any) for positive responses. */ dns_rdataset_t * rdataset; dns_rdataset_t * sigrdataset; /* * The full response. Required for negative responses. * Also required for positive wildcard responses. */ dns_message_t * message; /* * Proofs to be cached. */ dns_name_t * proofs[4]; /* * Optout proof seen. */ isc_boolean_t optout; /* * Answer is secure. */ isc_boolean_t secure; } dns_validatorevent_t; #define DNS_VALIDATOR_NOQNAMEPROOF 0 #define DNS_VALIDATOR_NODATAPROOF 1 #define DNS_VALIDATOR_NOWILDCARDPROOF 2 #define DNS_VALIDATOR_CLOSESTENCLOSER 3 /*% * A validator object represents a validation in progress. * \brief * Clients are strongly discouraged from using this type directly, with * the exception of the 'link' field, which may be used directly for * whatever purpose the client desires. */ struct dns_validator { /* Unlocked. */ unsigned int magic; isc_mutex_t lock; dns_view_t * view; /* Locked by lock. */ unsigned int options; unsigned int attributes; dns_validatorevent_t * event; dns_fetch_t * fetch; dns_validator_t * subvalidator; dns_validator_t * parent; dns_keytable_t * keytable; dns_keynode_t * keynode; dst_key_t * key; dns_rdata_rrsig_t * siginfo; isc_task_t * task; isc_taskaction_t action; void * arg; unsigned int labels; dns_rdataset_t * currentset; isc_boolean_t seensig; dns_rdataset_t * keyset; dns_rdataset_t * dsset; dns_rdataset_t * soaset; dns_rdataset_t * nsecset; dns_rdataset_t * nsec3set; dns_name_t * soaname; dns_rdataset_t frdataset; dns_rdataset_t fsigrdataset; dns_fixedname_t fname; dns_fixedname_t wild; dns_fixedname_t nearest; dns_fixedname_t closest; ISC_LINK(dns_validator_t) link; dns_rdataset_t dlv; dns_fixedname_t dlvsep; isc_boolean_t havedlvsep; isc_boolean_t mustbesecure; unsigned int dlvlabels; unsigned int depth; unsigned int authcount; unsigned int authfail; }; /*% * dns_validator_create() options. */ #define DNS_VALIDATOR_DLV 0x0001U #define DNS_VALIDATOR_DEFER 0x0002U #define DNS_VALIDATOR_NOCDFLAG 0x0004U ISC_LANG_BEGINDECLS isc_result_t dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, dns_message_t *message, unsigned int options, isc_task_t *task, isc_taskaction_t action, void *arg, dns_validator_t **validatorp); /*%< * Start a DNSSEC validation. * * This validates a response to the question given by * 'name' and 'type'. * * To validate a positive response, the response data is * given by 'rdataset' and 'sigrdataset'. If 'sigrdataset' * is NULL, the data is presumed insecure and an attempt * is made to prove its insecurity by finding the appropriate * null key. * * The complete response message may be given in 'message', * to make available any authority section NSECs that may be * needed for validation of a response resulting from a * wildcard expansion (though no such wildcard validation * is implemented yet). If the complete response message * is not available, 'message' is NULL. * * To validate a negative response, the complete negative response * message is given in 'message'. The 'rdataset', and * 'sigrdataset' arguments must be NULL, but the 'name' and 'type' * arguments must be provided. * * The validation is performed in the context of 'view'. * * When the validation finishes, a dns_validatorevent_t with * the given 'action' and 'arg' are sent to 'task'. * Its 'result' field will be ISC_R_SUCCESS iff the * response was successfully proven to be either secure or * part of a known insecure domain. * * options: * If DNS_VALIDATOR_DLV is set the caller knows there is not a * trusted key and the validator should immediately attempt to validate * the answer by looking for an appropriate DLV RRset. */ void dns_validator_send(dns_validator_t *validator); /*%< * Send a deferred validation request * * Requires: * 'validator' to points to a valid DNSSEC validator. */ void dns_validator_cancel(dns_validator_t *validator); /*%< * Cancel a DNSSEC validation in progress. * * Requires: *\li 'validator' points to a valid DNSSEC validator, which * may or may not already have completed. * * Ensures: *\li It the validator has not already sent its completion * event, it will send it with result code ISC_R_CANCELED. */ void dns_validator_destroy(dns_validator_t **validatorp); /*%< * Destroy a DNSSEC validator. * * Requires: *\li '*validatorp' points to a valid DNSSEC validator. * \li The validator must have completed and sent its completion * event. * * Ensures: *\li All resources used by the validator are freed. */ ISC_LANG_ENDDECLS #endif /* DNS_VALIDATOR_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/ds.h0000644000470500017500000000333312664710322017713 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2010, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ds.h,v 1.12 2010/12/23 23:47:08 tbox Exp $ */ #ifndef DNS_DS_H #define DNS_DS_H 1 #include #include #define DNS_DSDIGEST_SHA1 (1) #define DNS_DSDIGEST_SHA256 (2) #define DNS_DSDIGEST_GOST (3) #define DNS_DSDIGEST_SHA384 (4) /* * Assuming SHA-384 digest type. */ #define DNS_DS_BUFFERSIZE (52) ISC_LANG_BEGINDECLS isc_result_t dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, unsigned int digest_type, unsigned char *buffer, dns_rdata_t *rdata); /*%< * Build the rdata of a DS record. * * Requires: *\li key Points to a valid DNS KEY record. *\li buffer Points to a temporary buffer of at least * #DNS_DS_BUFFERSIZE bytes. *\li rdata Points to an initialized dns_rdata_t. * * Ensures: * \li *rdata Contains a valid DS rdata. The 'data' member refers * to 'buffer'. */ ISC_LANG_ENDDECLS #endif /* DNS_DS_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/rriterator.h0000644000470500017500000001111112664710322021473 0ustar lamontlamont/* * Copyright (C) 2009, 2011 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rriterator.h,v 1.4 2011/11/01 23:47:00 tbox Exp $ */ #ifndef DNS_RRITERATOR_H #define DNS_RRITERATOR_H 1 /***** ***** Module Info *****/ /*! \file dns/rriterator.h * \brief * Functions for "walking" a zone database, visiting each RR or RRset in turn. */ /***** ***** Imports *****/ #include #include #include #include #include #include #include #include #include #include #include #include ISC_LANG_BEGINDECLS /***** ***** Types *****/ /*% * A dns_rriterator_t is an iterator that iterates over an entire database, * returning one RR at a time, in some arbitrary order. */ typedef struct dns_rriterator { unsigned int magic; isc_result_t result; dns_db_t *db; dns_dbiterator_t *dbit; dns_dbversion_t *ver; isc_stdtime_t now; dns_dbnode_t *node; dns_fixedname_t fixedname; dns_rdatasetiter_t *rdatasetit; dns_rdataset_t rdataset; dns_rdata_t rdata; } dns_rriterator_t; #define RRITERATOR_MAGIC ISC_MAGIC('R', 'R', 'I', 't') #define VALID_RRITERATOR(m) ISC_MAGIC_VALID(m, RRITERATOR_MAGIC) isc_result_t dns_rriterator_init(dns_rriterator_t *it, dns_db_t *db, dns_dbversion_t *ver, isc_stdtime_t now); /*% * Initialize an rriterator; sets the cursor to the origin node * of the database. * * Requires: * * \li 'db' is a valid database. * * Returns: * * \li #ISC_R_SUCCESS * \li #ISC_R_NOMEMORY */ isc_result_t dns_rriterator_first(dns_rriterator_t *it); /*%< * Move the rriterator cursor to the first rdata in the database. * * Requires: *\li 'it' is a valid, initialized rriterator * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMORE There are no rdata in the set. */ isc_result_t dns_rriterator_nextrrset(dns_rriterator_t *it); /*%< * Move the rriterator cursor to the next rrset in the database, * skipping over any remaining records that have the same rdatatype * as the current one. * * Requires: *\li 'it' is a valid, initialized rriterator * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMORE No more rrsets in the database */ isc_result_t dns_rriterator_next(dns_rriterator_t *it); /*%< * Move the rriterator cursor to the next rrset in the database, * skipping over any remaining records that have the same rdatatype * as the current one. * * Requires: *\li 'it' is a valid, initialized rriterator * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMORE No more records in the database */ void dns_rriterator_current(dns_rriterator_t *it, dns_name_t **name, isc_uint32_t *ttl, dns_rdataset_t **rdataset, dns_rdata_t **rdata); /*%< * Make '*name' refer to the current name. If 'rdataset' is not NULL, * make '*rdataset' refer to the current * rdataset. If '*rdata' is not * NULL, make '*rdata' refer to the current record. * * Requires: *\li '*name' is a valid name object *\li 'rdataset' is NULL or '*rdataset' is NULL *\li 'rdata' is NULL or '*rdata' is NULL * * Ensures: *\li 'rdata' refers to the rdata at the rdata cursor location of *\li 'rdataset'. */ void dns_rriterator_pause(dns_rriterator_t *it); /*%< * Pause rriterator. Frees any locks held by the database iterator. * Callers should use this routine any time they are not going to * execute another rriterator method in the immediate future. * * Requires: *\li 'it' is a valid iterator. * * Ensures: *\li Any database locks being held for efficiency of iterator access are * released. */ void dns_rriterator_destroy(dns_rriterator_t *it); /*%< * Shut down and free resources in rriterator 'it'. * * Requires: * *\li 'it' is a valid iterator. * * Ensures: * *\li All resources used by the rriterator are freed. */ ISC_LANG_ENDDECLS #endif /* DNS_RRITERATOR_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/request.h0000644000470500017500000002615112664710322021000 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2010, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: request.h,v 1.31 2010/03/04 23:50:34 tbox Exp $ */ #ifndef DNS_REQUEST_H #define DNS_REQUEST_H 1 /***** ***** Module Info *****/ /*! \file dns/request.h * * \brief * The request module provides simple request/response services useful for * sending SOA queries, DNS Notify messages, and dynamic update requests. * * MP: *\li The module ensures appropriate synchronization of data structures it * creates and manipulates. * * Resources: *\li TBS * * Security: *\li No anticipated impact. */ #include #include #include #define DNS_REQUESTOPT_TCP 0x00000001U #define DNS_REQUESTOPT_CASE 0x00000002U #define DNS_REQUESTOPT_FIXEDID 0x00000004U typedef struct dns_requestevent { ISC_EVENT_COMMON(struct dns_requestevent); isc_result_t result; dns_request_t *request; } dns_requestevent_t; ISC_LANG_BEGINDECLS isc_result_t dns_requestmgr_create(isc_mem_t *mctx, isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, isc_taskmgr_t *taskmgr, dns_dispatchmgr_t *dispatchmgr, dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6, dns_requestmgr_t **requestmgrp); /*%< * Create a request manager. * * Requires: * *\li 'mctx' is a valid memory context. * *\li 'timermgr' is a valid timer manager. * *\li 'socketmgr' is a valid socket manager. * *\li 'taskmgr' is a valid task manager. * *\li 'dispatchv4' is a valid dispatcher with an IPv4 UDP socket, or is NULL. * *\li 'dispatchv6' is a valid dispatcher with an IPv6 UDP socket, or is NULL. * *\li requestmgrp != NULL && *requestmgrp == NULL * * Ensures: * *\li On success, *requestmgrp is a valid request manager. * * Returns: * *\li ISC_R_SUCCESS * *\li Any other result indicates failure. */ void dns_requestmgr_whenshutdown(dns_requestmgr_t *requestmgr, isc_task_t *task, isc_event_t **eventp); /*%< * Send '*eventp' to 'task' when 'requestmgr' has completed shutdown. * * Notes: * *\li It is not safe to detach the last reference to 'requestmgr' until * shutdown is complete. * * Requires: * *\li 'requestmgr' is a valid request manager. * *\li 'task' is a valid task. * *\li *eventp is a valid event. * * Ensures: * *\li *eventp == NULL. */ void dns_requestmgr_shutdown(dns_requestmgr_t *requestmgr); /*%< * Start the shutdown process for 'requestmgr'. * * Notes: * *\li This call has no effect if the request manager is already shutting * down. * * Requires: * *\li 'requestmgr' is a valid requestmgr. */ void dns_requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp); /*%< * Attach to the request manager. dns_requestmgr_shutdown() must not * have been called on 'source' prior to calling dns_requestmgr_attach(). * * Requires: * *\li 'source' is a valid requestmgr. * *\li 'targetp' to be non NULL and '*targetp' to be NULL. */ void dns_requestmgr_detach(dns_requestmgr_t **requestmgrp); /*%< * Detach from the given requestmgr. If this is the final detach * requestmgr will be destroyed. dns_requestmgr_shutdown() must * be called before the final detach. * * Requires: * *\li '*requestmgrp' is a valid requestmgr. * * Ensures: *\li '*requestmgrp' is NULL. */ isc_result_t dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message, isc_sockaddr_t *address, unsigned int options, dns_tsigkey_t *key, unsigned int timeout, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp); /*%< * Create and send a request. * * Notes: * *\li 'message' will be rendered and sent to 'address'. If the * #DNS_REQUESTOPT_TCP option is set, TCP will be used. The request * will timeout after 'timeout' seconds. * *\li If the #DNS_REQUESTOPT_CASE option is set, use case sensitive * compression. * *\li When the request completes, successfully, due to a timeout, or * because it was canceled, a completion event will be sent to 'task'. * * Requires: * *\li 'message' is a valid DNS message. * *\li 'address' is a valid sockaddr. * *\li 'timeout' > 0 * *\li 'task' is a valid task. * *\li requestp != NULL && *requestp == NULL */ /*% See dns_request_createvia4() */ isc_result_t dns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, unsigned int options, dns_tsigkey_t *key, unsigned int timeout, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp); /*% See dns_request_createvia4() */ isc_result_t dns_request_createvia2(dns_requestmgr_t *requestmgr, dns_message_t *message, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, unsigned int options, dns_tsigkey_t *key, unsigned int timeout, unsigned int udptimeout, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp); /*% See dns_request_createvia4() */ isc_result_t dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, unsigned int options, dns_tsigkey_t *key, unsigned int timeout, unsigned int udptimeout, unsigned int udpretries, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp); isc_result_t dns_request_createvia4(dns_requestmgr_t *requestmgr, dns_message_t *message, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, isc_dscp_t dscp, unsigned int options, dns_tsigkey_t *key, unsigned int timeout, unsigned int udptimeout, unsigned int udpretries, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp); /*%< * Create and send a request. * * Notes: * *\li 'message' will be rendered and sent to 'address'. If the * #DNS_REQUESTOPT_TCP option is set, TCP will be used. The request * will timeout after 'timeout' seconds. UDP requests will be resent * at 'udptimeout' intervals if non-zero or 'udpretries' is non-zero. * *\li If the #DNS_REQUESTOPT_CASE option is set, use case sensitive * compression. * *\li When the request completes, successfully, due to a timeout, or * because it was canceled, a completion event will be sent to 'task'. * * Requires: * *\li 'message' is a valid DNS message. * *\li 'dstaddr' is a valid sockaddr. * *\li 'srcaddr' is a valid sockaddr or NULL. * *\li 'srcaddr' and 'dstaddr' are the same protocol family. * *\li 'timeout' > 0 * *\li 'task' is a valid task. * *\li requestp != NULL && *requestp == NULL */ /*% See dns_request_createraw4() */ isc_result_t dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, unsigned int options, unsigned int timeout, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp); /*% See dns_request_createraw4() */ isc_result_t dns_request_createraw2(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, unsigned int options, unsigned int timeout, unsigned int udptimeout, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp); /*% See dns_request_createraw4() */ isc_result_t dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, unsigned int options, unsigned int timeout, unsigned int udptimeout, unsigned int udpretries, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp); isc_result_t dns_request_createraw4(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, isc_dscp_t dscp, unsigned int options, unsigned int timeout, unsigned int udptimeout, unsigned int udpretries, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp); /*!< * \brief Create and send a request. * * Notes: * *\li 'msgbuf' will be sent to 'destaddr' after setting the id. If the * #DNS_REQUESTOPT_TCP option is set, TCP will be used. The request * will timeout after 'timeout' seconds. UDP requests will be resent * at 'udptimeout' intervals if non-zero or if 'udpretries' is not zero. * *\li When the request completes, successfully, due to a timeout, or * because it was canceled, a completion event will be sent to 'task'. * * Requires: * *\li 'msgbuf' is a valid DNS message in compressed wire format. * *\li 'destaddr' is a valid sockaddr. * *\li 'srcaddr' is a valid sockaddr or NULL. * *\li 'srcaddr' and 'dstaddr' are the same protocol family. * *\li 'timeout' > 0 * *\li 'task' is a valid task. * *\li requestp != NULL && *requestp == NULL */ void dns_request_cancel(dns_request_t *request); /*%< * Cancel 'request'. * * Requires: * *\li 'request' is a valid request. * * Ensures: * *\li If the completion event for 'request' has not yet been sent, it * will be sent, and the result code will be ISC_R_CANCELED. */ isc_result_t dns_request_getresponse(dns_request_t *request, dns_message_t *message, unsigned int options); /*%< * Get the response to 'request' by filling in 'message'. * * 'options' is passed to dns_message_parse(). See dns_message_parse() * for more details. * * Requires: * *\li 'request' is a valid request for which the caller has received the * completion event. * *\li The result code of the completion event was #ISC_R_SUCCESS. * * Returns: * *\li ISC_R_SUCCESS * *\li Any result that dns_message_parse() can return. */ isc_boolean_t dns_request_usedtcp(dns_request_t *request); /*%< * Return whether this query used TCP or not. Setting #DNS_REQUESTOPT_TCP * in the call to dns_request_create() will cause the function to return * #ISC_TRUE, otherwise the result is based on the query message size. * * Requires: *\li 'request' is a valid request. * * Returns: *\li ISC_TRUE if TCP was used. *\li ISC_FALSE if UDP was used. */ void dns_request_destroy(dns_request_t **requestp); /*%< * Destroy 'request'. * * Requires: * *\li 'request' is a valid request for which the caller has received the * completion event. * * Ensures: * *\li *requestp == NULL */ ISC_LANG_ENDDECLS #endif /* DNS_REQUEST_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/rdataset.h0000644000470500017500000005041412664710322021116 0ustar lamontlamont/* * Copyright (C) 2004-2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rdataset.h,v 1.72 2011/06/08 22:13:51 each Exp $ */ #ifndef DNS_RDATASET_H #define DNS_RDATASET_H 1 /***** ***** Module Info *****/ /*! \file dns/rdataset.h * \brief * A DNS rdataset is a handle that can be associated with a collection of * rdata all having a common owner name, class, and type. * * The dns_rdataset_t type is like a "virtual class". To actually use * rdatasets, an implementation of the method suite (e.g. "slabbed rdata") is * required. * * XXX <more> XXX * * MP: *\li Clients of this module must impose any required synchronization. * * Reliability: *\li No anticipated impact. * * Resources: *\li TBS * * Security: *\li No anticipated impact. * * Standards: *\li None. */ #include #include #include #include #include ISC_LANG_BEGINDECLS typedef enum { dns_rdatasetadditional_fromauth, dns_rdatasetadditional_fromcache, dns_rdatasetadditional_fromglue } dns_rdatasetadditional_t; typedef struct dns_rdatasetmethods { void (*disassociate)(dns_rdataset_t *rdataset); isc_result_t (*first)(dns_rdataset_t *rdataset); isc_result_t (*next)(dns_rdataset_t *rdataset); void (*current)(dns_rdataset_t *rdataset, dns_rdata_t *rdata); void (*clone)(dns_rdataset_t *source, dns_rdataset_t *target); unsigned int (*count)(dns_rdataset_t *rdataset); isc_result_t (*addnoqname)(dns_rdataset_t *rdataset, dns_name_t *name); isc_result_t (*getnoqname)(dns_rdataset_t *rdataset, dns_name_t *name, dns_rdataset_t *neg, dns_rdataset_t *negsig); isc_result_t (*addclosest)(dns_rdataset_t *rdataset, dns_name_t *name); isc_result_t (*getclosest)(dns_rdataset_t *rdataset, dns_name_t *name, dns_rdataset_t *neg, dns_rdataset_t *negsig); isc_result_t (*getadditional)(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, dns_rdatatype_t qtype, dns_acache_t *acache, dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp, dns_dbnode_t **nodep, dns_name_t *fname, dns_message_t *msg, isc_stdtime_t now); isc_result_t (*setadditional)(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, dns_rdatatype_t qtype, dns_acache_t *acache, dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, dns_name_t *fname); isc_result_t (*putadditional)(dns_acache_t *acache, dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, dns_rdatatype_t qtype); void (*settrust)(dns_rdataset_t *rdataset, dns_trust_t trust); void (*expire)(dns_rdataset_t *rdataset); void (*clearprefetch)(dns_rdataset_t *rdataset); } dns_rdatasetmethods_t; #define DNS_RDATASET_MAGIC ISC_MAGIC('D','N','S','R') #define DNS_RDATASET_VALID(set) ISC_MAGIC_VALID(set, DNS_RDATASET_MAGIC) /*% * Direct use of this structure by clients is strongly discouraged, except * for the 'link' field which may be used however the client wishes. The * 'private', 'current', and 'index' fields MUST NOT be changed by clients. * rdataset implementations may change any of the fields. */ struct dns_rdataset { unsigned int magic; /* XXX ? */ dns_rdatasetmethods_t * methods; ISC_LINK(dns_rdataset_t) link; /* * XXX do we need these, or should they be retrieved by methods? * Leaning towards the latter, since they are not frequently required * once you have the rdataset. */ dns_rdataclass_t rdclass; dns_rdatatype_t type; dns_ttl_t ttl; dns_trust_t trust; dns_rdatatype_t covers; /* * attributes */ unsigned int attributes; /*% * the counter provides the starting point in the "cyclic" order. * The value ISC_UINT32_MAX has a special meaning of "picking up a * random value." in order to take care of databases that do not * increment the counter. */ isc_uint32_t count; /* * This RRSIG RRset should be re-generated around this time. * Only valid if DNS_RDATASETATTR_RESIGN is set in attributes. */ isc_stdtime_t resign; /*@{*/ /*% * These are for use by the rdataset implementation, and MUST NOT * be changed by clients. */ void * private1; void * private2; void * private3; unsigned int privateuint4; void * private5; void * private6; void * private7; /*@}*/ }; /*! * \def DNS_RDATASETATTR_RENDERED * Used by message.c to indicate that the rdataset was rendered. * * \def DNS_RDATASETATTR_TTLADJUSTED * Used by message.c to indicate that the rdataset's rdata had differing * TTL values, and the rdataset->ttl holds the smallest. * * \def DNS_RDATASETATTR_LOADORDER * Output the RRset in load order. */ #define DNS_RDATASETATTR_QUESTION 0x00000001 #define DNS_RDATASETATTR_RENDERED 0x00000002 /*%< Used by message.c */ #define DNS_RDATASETATTR_ANSWERED 0x00000004 /*%< Used by server. */ #define DNS_RDATASETATTR_CACHE 0x00000008 /*%< Used by resolver. */ #define DNS_RDATASETATTR_ANSWER 0x00000010 /*%< Used by resolver. */ #define DNS_RDATASETATTR_ANSWERSIG 0x00000020 /*%< Used by resolver. */ #define DNS_RDATASETATTR_EXTERNAL 0x00000040 /*%< Used by resolver. */ #define DNS_RDATASETATTR_NCACHE 0x00000080 /*%< Used by resolver. */ #define DNS_RDATASETATTR_CHAINING 0x00000100 /*%< Used by resolver. */ #define DNS_RDATASETATTR_TTLADJUSTED 0x00000200 /*%< Used by message.c */ #define DNS_RDATASETATTR_FIXEDORDER 0x00000400 #define DNS_RDATASETATTR_RANDOMIZE 0x00000800 #define DNS_RDATASETATTR_CHASE 0x00001000 /*%< Used by resolver. */ #define DNS_RDATASETATTR_NXDOMAIN 0x00002000 #define DNS_RDATASETATTR_NOQNAME 0x00004000 #define DNS_RDATASETATTR_CHECKNAMES 0x00008000 /*%< Used by resolver. */ #define DNS_RDATASETATTR_REQUIRED 0x00010000 #define DNS_RDATASETATTR_REQUIREDGLUE DNS_RDATASETATTR_REQUIRED #define DNS_RDATASETATTR_LOADORDER 0x00020000 #define DNS_RDATASETATTR_RESIGN 0x00040000 #define DNS_RDATASETATTR_CLOSEST 0x00080000 #define DNS_RDATASETATTR_OPTOUT 0x00100000 /*%< OPTOUT proof */ #define DNS_RDATASETATTR_NEGATIVE 0x00200000 #define DNS_RDATASETATTR_PREFETCH 0x00400000 /*% * _OMITDNSSEC: * Omit DNSSEC records when rendering ncache records. */ #define DNS_RDATASETTOWIRE_OMITDNSSEC 0x0001 void dns_rdataset_init(dns_rdataset_t *rdataset); /*%< * Make 'rdataset' a valid, disassociated rdataset. * * Requires: *\li 'rdataset' is not NULL. * * Ensures: *\li 'rdataset' is a valid, disassociated rdataset. */ void dns_rdataset_invalidate(dns_rdataset_t *rdataset); /*%< * Invalidate 'rdataset'. * * Requires: *\li 'rdataset' is a valid, disassociated rdataset. * * Ensures: *\li If assertion checking is enabled, future attempts to use 'rdataset' * without initializing it will cause an assertion failure. */ void dns_rdataset_disassociate(dns_rdataset_t *rdataset); /*%< * Disassociate 'rdataset' from its rdata, allowing it to be reused. * * Notes: *\li The client must ensure it has no references to rdata in the rdataset * before disassociating. * * Requires: *\li 'rdataset' is a valid, associated rdataset. * * Ensures: *\li 'rdataset' is a valid, disassociated rdataset. */ isc_boolean_t dns_rdataset_isassociated(dns_rdataset_t *rdataset); /*%< * Is 'rdataset' associated? * * Requires: *\li 'rdataset' is a valid rdataset. * * Returns: *\li #ISC_TRUE 'rdataset' is associated. *\li #ISC_FALSE 'rdataset' is not associated. */ void dns_rdataset_makequestion(dns_rdataset_t *rdataset, dns_rdataclass_t rdclass, dns_rdatatype_t type); /*%< * Make 'rdataset' a valid, associated, question rdataset, with a * question class of 'rdclass' and type 'type'. * * Notes: *\li Question rdatasets have a class and type, but no rdata. * * Requires: *\li 'rdataset' is a valid, disassociated rdataset. * * Ensures: *\li 'rdataset' is a valid, associated, question rdataset. */ void dns_rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target); /*%< * Make 'target' refer to the same rdataset as 'source'. * * Requires: *\li 'source' is a valid, associated rdataset. * *\li 'target' is a valid, dissociated rdataset. * * Ensures: *\li 'target' references the same rdataset as 'source'. */ unsigned int dns_rdataset_count(dns_rdataset_t *rdataset); /*%< * Return the number of records in 'rdataset'. * * Requires: *\li 'rdataset' is a valid, associated rdataset. * * Returns: *\li The number of records in 'rdataset'. */ isc_result_t dns_rdataset_first(dns_rdataset_t *rdataset); /*%< * Move the rdata cursor to the first rdata in the rdataset (if any). * * Requires: *\li 'rdataset' is a valid, associated rdataset. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMORE There are no rdata in the set. */ isc_result_t dns_rdataset_next(dns_rdataset_t *rdataset); /*%< * Move the rdata cursor to the next rdata in the rdataset (if any). * * Requires: *\li 'rdataset' is a valid, associated rdataset. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMORE There are no more rdata in the set. */ void dns_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata); /*%< * Make 'rdata' refer to the current rdata. * * Notes: * *\li The data returned in 'rdata' is valid for the life of the * rdataset; in particular, subsequent changes in the cursor position * do not invalidate 'rdata'. * * Requires: *\li 'rdataset' is a valid, associated rdataset. * *\li The rdata cursor of 'rdataset' is at a valid location (i.e. the * result of last call to a cursor movement command was ISC_R_SUCCESS). * * Ensures: *\li 'rdata' refers to the rdata at the rdata cursor location of *\li 'rdataset'. */ isc_result_t dns_rdataset_totext(dns_rdataset_t *rdataset, dns_name_t *owner_name, isc_boolean_t omit_final_dot, isc_boolean_t question, isc_buffer_t *target); /*%< * Convert 'rdataset' to text format, storing the result in 'target'. * * Notes: *\li The rdata cursor position will be changed. * *\li The 'question' flag should normally be #ISC_FALSE. If it is * #ISC_TRUE, the TTL and rdata fields are not printed. This is * for use when printing an rdata representing a question section. * *\li This interface is deprecated; use dns_master_rdatasettottext() * and/or dns_master_questiontotext() instead. * * Requires: *\li 'rdataset' is a valid rdataset. * *\li 'rdataset' is not empty. */ isc_result_t dns_rdataset_towire(dns_rdataset_t *rdataset, dns_name_t *owner_name, dns_compress_t *cctx, isc_buffer_t *target, unsigned int options, unsigned int *countp); /*%< * Convert 'rdataset' to wire format, compressing names as specified * in 'cctx', and storing the result in 'target'. * * Notes: *\li The rdata cursor position will be changed. * *\li The number of RRs added to target will be added to *countp. * * Requires: *\li 'rdataset' is a valid rdataset. * *\li 'rdataset' is not empty. * *\li 'countp' is a valid pointer. * * Ensures: *\li On a return of ISC_R_SUCCESS, 'target' contains a wire format * for the data contained in 'rdataset'. Any error return leaves * the buffer unchanged. * *\li *countp has been incremented by the number of RRs added to * target. * * Returns: *\li #ISC_R_SUCCESS - all ok *\li #ISC_R_NOSPACE - 'target' doesn't have enough room * *\li Any error returned by dns_rdata_towire(), dns_rdataset_next(), * dns_name_towire(). */ isc_result_t dns_rdataset_towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name, dns_compress_t *cctx, isc_buffer_t *target, dns_rdatasetorderfunc_t order, const void *order_arg, unsigned int options, unsigned int *countp); /*%< * Like dns_rdataset_towire(), but sorting the rdatasets according to * the integer value returned by 'order' when called with the rdataset * and 'order_arg' as arguments. * * Requires: *\li All the requirements of dns_rdataset_towire(), and * that order_arg is NULL if and only if order is NULL. */ isc_result_t dns_rdataset_towirepartial(dns_rdataset_t *rdataset, const dns_name_t *owner_name, dns_compress_t *cctx, isc_buffer_t *target, dns_rdatasetorderfunc_t order, const void *order_arg, unsigned int options, unsigned int *countp, void **state); /*%< * Like dns_rdataset_towiresorted() except that a partial rdataset * may be written. * * Requires: *\li All the requirements of dns_rdataset_towiresorted(). * If 'state' is non NULL then the current position in the * rdataset will be remembered if the rdataset in not * completely written and should be passed on on subsequent * calls (NOT CURRENTLY IMPLEMENTED). * * Returns: *\li #ISC_R_SUCCESS if all of the records were written. *\li #ISC_R_NOSPACE if unable to fit in all of the records. *countp * will be updated to reflect the number of records * written. */ isc_result_t dns_rdataset_additionaldata(dns_rdataset_t *rdataset, dns_additionaldatafunc_t add, void *arg); /*%< * For each rdata in rdataset, call 'add' for each name and type in the * rdata which is subject to additional section processing. * * Requires: * *\li 'rdataset' is a valid, non-question rdataset. * *\li 'add' is a valid dns_additionaldatafunc_t * * Ensures: * *\li If successful, dns_rdata_additionaldata() will have been called for * each rdata in 'rdataset'. * *\li If a call to dns_rdata_additionaldata() is not successful, the * result returned will be the result of dns_rdataset_additionaldata(). * * Returns: * *\li #ISC_R_SUCCESS * *\li Any error that dns_rdata_additionaldata() can return. */ isc_result_t dns_rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name, dns_rdataset_t *neg, dns_rdataset_t *negsig); /*%< * Return the noqname proof for this record. * * Requires: *\li 'rdataset' to be valid and #DNS_RDATASETATTR_NOQNAME to be set. *\li 'name' to be valid. *\li 'neg' and 'negsig' to be valid and not associated. */ isc_result_t dns_rdataset_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name); /*%< * Associate a noqname proof with this record. * Sets #DNS_RDATASETATTR_NOQNAME if successful. * Adjusts the 'rdataset->ttl' to minimum of the 'rdataset->ttl' and * the 'nsec'/'nsec3' and 'rrsig(nsec)'/'rrsig(nsec3)' ttl. * * Requires: *\li 'rdataset' to be valid and #DNS_RDATASETATTR_NOQNAME to be set. *\li 'name' to be valid and have NSEC or NSEC3 and associated RRSIG * rdatasets. */ isc_result_t dns_rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name, dns_rdataset_t *nsec, dns_rdataset_t *nsecsig); /*%< * Return the closest encloser for this record. * * Requires: *\li 'rdataset' to be valid and #DNS_RDATASETATTR_CLOSEST to be set. *\li 'name' to be valid. *\li 'nsec' and 'nsecsig' to be valid and not associated. */ isc_result_t dns_rdataset_addclosest(dns_rdataset_t *rdataset, dns_name_t *name); /*%< * Associate a closest encloset proof with this record. * Sets #DNS_RDATASETATTR_CLOSEST if successful. * Adjusts the 'rdataset->ttl' to minimum of the 'rdataset->ttl' and * the 'nsec' and 'rrsig(nsec)' ttl. * * Requires: *\li 'rdataset' to be valid and #DNS_RDATASETATTR_CLOSEST to be set. *\li 'name' to be valid and have NSEC3 and RRSIG(NSEC3) rdatasets. */ isc_result_t dns_rdataset_getadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, dns_rdatatype_t qtype, dns_acache_t *acache, dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp, dns_dbnode_t **nodep, dns_name_t *fname, dns_message_t *msg, isc_stdtime_t now); /*%< * Get cached additional information from the DB node for a particular * 'rdataset.' 'type' is one of dns_rdatasetadditional_fromauth, * dns_rdatasetadditional_fromcache, and dns_rdatasetadditional_fromglue, * which specifies the origin of the information. 'qtype' is intended to * be used for specifying a particular rdata type in the cached information. * * Requires: * \li 'rdataset' is a valid rdataset. * \li 'acache' can be NULL, in which case this function will simply return * ISC_R_FAILURE. * \li For the other pointers, see dns_acache_getentry(). * * Ensures: * \li See dns_acache_getentry(). * * Returns: * \li #ISC_R_SUCCESS * \li #ISC_R_FAILURE - additional information caching is not supported. * \li #ISC_R_NOTFOUND - the corresponding DB node has not cached additional * information for 'rdataset.' * \li Any error that dns_acache_getentry() can return. */ isc_result_t dns_rdataset_setadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, dns_rdatatype_t qtype, dns_acache_t *acache, dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, dns_name_t *fname); /*%< * Set cached additional information to the DB node for a particular * 'rdataset.' See dns_rdataset_getadditional for the semantics of 'type' * and 'qtype'. * * Requires: * \li 'rdataset' is a valid rdataset. * \li 'acache' can be NULL, in which case this function will simply return * ISC_R_FAILURE. * \li For the other pointers, see dns_acache_setentry(). * * Ensures: * \li See dns_acache_setentry(). * * Returns: * \li #ISC_R_SUCCESS * \li #ISC_R_FAILURE - additional information caching is not supported. * \li #ISC_R_NOMEMORY * \li Any error that dns_acache_setentry() can return. */ isc_result_t dns_rdataset_putadditional(dns_acache_t *acache, dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, dns_rdatatype_t qtype); /*%< * Discard cached additional information stored in the DB node for a particular * 'rdataset.' See dns_rdataset_getadditional for the semantics of 'type' * and 'qtype'. * * Requires: * \li 'rdataset' is a valid rdataset. * \li 'acache' can be NULL, in which case this function will simply return * ISC_R_FAILURE. * * Ensures: * \li See dns_acache_cancelentry(). * * Returns: * \li #ISC_R_SUCCESS * \li #ISC_R_FAILURE - additional information caching is not supported. * \li #ISC_R_NOTFOUND - the corresponding DB node has not cached additional * information for 'rdataset.' */ void dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust); /*%< * Set the trust of the 'rdataset' to trust in any in the backing database. * The local trust level of 'rdataset' is also set. */ void dns_rdataset_expire(dns_rdataset_t *rdataset); /*%< * Mark the rdataset to be expired in the backing database. */ void dns_rdataset_clearprefetch(dns_rdataset_t *rdataset); /*%< * Clear the PREFETCH attribute for the given rdataset in the * underlying database. * * In the cache database, this signals that the rdataset is not * eligible to be prefetched when the TTL is close to expiring. * It has no function in other databases. */ void dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, dns_rdata_rrsig_t *rrsig, isc_stdtime_t now, isc_boolean_t acceptexpired); /*%< * Trim the ttl of 'rdataset' and 'sigrdataset' so that they will expire * at or before 'rrsig->expiretime'. If 'acceptexpired' is true and the * signature has expired or will expire in the next 120 seconds, limit * the ttl to be no more than 120 seconds. * * The ttl is further limited by the original ttl as stored in 'rrsig' * and the original ttl values of 'rdataset' and 'sigrdataset'. * * Requires: * \li 'rdataset' is a valid rdataset. * \li 'sigrdataset' is a valid rdataset. * \li 'rrsig' is non NULL. */ const char * dns_trust_totext(dns_trust_t trust); /*%< * Display trust in textual form. */ ISC_LANG_ENDDECLS #endif /* DNS_RDATASET_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/rootns.h0000644000470500017500000000262512664710322020634 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rootns.h,v 1.16 2007/06/19 23:47:17 tbox Exp $ */ #ifndef DNS_ROOTNS_H #define DNS_ROOTNS_H 1 /*! \file dns/rootns.h */ #include #include ISC_LANG_BEGINDECLS isc_result_t dns_rootns_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, const char *filename, dns_db_t **target); void dns_root_checkhints(dns_view_t *view, dns_db_t *hints, dns_db_t *db); /* * Reports differences between hints and the real roots. * * Requires view, hints and (cache) db to be valid. */ ISC_LANG_ENDDECLS #endif /* DNS_ROOTNS_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/update.h0000644000470500017500000000407712664710322020575 0ustar lamontlamont/* * Copyright (C) 2011, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: update.h,v 1.5 2011/08/30 23:46:53 tbox Exp $ */ #ifndef DNS_UPDATE_H #define DNS_UPDATE_H 1 /*! \file dns/update.h */ /*** *** Imports ***/ #include #include #include typedef struct { void (*func)(void *arg, dns_zone_t *zone, int level, const char *message); void *arg; } dns_update_log_t; ISC_LANG_BEGINDECLS /*** *** Functions ***/ isc_uint32_t dns_update_soaserial(isc_uint32_t serial, dns_updatemethod_t method); /*%< * Return the next serial number after 'serial', depending on the * update method 'method': * *\li * dns_updatemethod_increment increments the serial number by one *\li * dns_updatemethod_unixtime sets the serial number to the current * time (seconds since UNIX epoch) if possible, or increments by one * if not. */ isc_result_t dns_update_signatures(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *oldver, dns_dbversion_t *newver, dns_diff_t *diff, isc_uint32_t sigvalidityinterval); isc_result_t dns_update_signaturesinc(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *oldver, dns_dbversion_t *newver, dns_diff_t *diff, isc_uint32_t sigvalidityinterval, dns_update_state_t **state); ISC_LANG_ENDDECLS #endif /* DNS_UPDATE_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/message.h0000644000470500017500000011364712664710322020743 0ustar lamontlamont/* * Copyright (C) 2004-2010, 2012-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef DNS_MESSAGE_H #define DNS_MESSAGE_H 1 /*** *** Imports ***/ #include #include #include #include #include #include /*! \file dns/message.h * \brief Message Handling Module * * How this beast works: * * When a dns message is received in a buffer, dns_message_fromwire() is called * on the memory region. Various items are checked including the format * of the message (if counts are right, if counts consume the entire sections, * and if sections consume the entire message) and known pseudo-RRs in the * additional data section are analyzed and removed. * * TSIG checking is also done at this layer, and any DNSSEC transaction * signatures should also be checked here. * * Notes on using the gettemp*() and puttemp*() functions: * * These functions return items (names, rdatasets, etc) allocated from some * internal state of the dns_message_t. * * Names and rdatasets must be put back into the dns_message_t in * one of two ways. Assume a name was allocated via * dns_message_gettempname(): * *\li (1) insert it into a section, using dns_message_addname(). * *\li (2) return it to the message using dns_message_puttempname(). * * The same applies to rdatasets. * * On the other hand, offsets, rdatalists and rdatas allocated using * dns_message_gettemp*() will always be freed automatically * when the message is reset or destroyed; calling dns_message_puttemp*() * on rdatalists and rdatas is optional and serves only to enable the item * to be reused multiple times during the lifetime of the message; offsets * cannot be reused. * * Buffers allocated using isc_buffer_allocate() can be automatically freed * as well by giving the buffer to the message using dns_message_takebuffer(). * Doing this will cause the buffer to be freed using isc_buffer_free() * when the section lists are cleared, such as in a reset or in a destroy. * Since the buffer itself exists until the message is destroyed, this sort * of code can be written: * * \code * buffer = isc_buffer_allocate(mctx, 512); * name = NULL; * name = dns_message_gettempname(message, &name); * dns_name_init(name, NULL); * result = dns_name_fromtext(name, &source, dns_rootname, 0, buffer); * dns_message_takebuffer(message, &buffer); * \endcode * * * TODO: * * XXX Needed: ways to set and retrieve EDNS information, add rdata to a * section, move rdata from one section to another, remove rdata, etc. */ #define DNS_MESSAGEFLAG_QR 0x8000U #define DNS_MESSAGEFLAG_AA 0x0400U #define DNS_MESSAGEFLAG_TC 0x0200U #define DNS_MESSAGEFLAG_RD 0x0100U #define DNS_MESSAGEFLAG_RA 0x0080U #define DNS_MESSAGEFLAG_AD 0x0020U #define DNS_MESSAGEFLAG_CD 0x0010U /*%< EDNS0 extended message flags */ #define DNS_MESSAGEEXTFLAG_DO 0x8000U /*%< EDNS0 extended OPT codes */ #define DNS_OPT_NSID 0x0003 /*%< NSID opt code */ #define DNS_OPT_CLIENT_SUBNET 0x0008 /*%< client subnet opt code */ #define DNS_OPT_EXPIRE 0x0009 /*%< EXPIRE opt code */ #define DNS_OPT_COOKIE 0x000a /*%< COOKIE opt code */ /*%< The number of EDNS options we know about. */ #define DNS_EDNSOPTIONS 4 #define DNS_MESSAGE_REPLYPRESERVE (DNS_MESSAGEFLAG_RD|DNS_MESSAGEFLAG_CD) #define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO) #define DNS_MESSAGE_HEADERLEN 12 /*%< 6 isc_uint16_t's */ #define DNS_MESSAGE_MAGIC ISC_MAGIC('M','S','G','@') #define DNS_MESSAGE_VALID(msg) ISC_MAGIC_VALID(msg, DNS_MESSAGE_MAGIC) /* * Ordering here matters. DNS_SECTION_ANY must be the lowest and negative, * and DNS_SECTION_MAX must be one greater than the last used section. */ typedef int dns_section_t; #define DNS_SECTION_ANY (-1) #define DNS_SECTION_QUESTION 0 #define DNS_SECTION_ANSWER 1 #define DNS_SECTION_AUTHORITY 2 #define DNS_SECTION_ADDITIONAL 3 #define DNS_SECTION_MAX 4 typedef int dns_pseudosection_t; #define DNS_PSEUDOSECTION_ANY (-1) #define DNS_PSEUDOSECTION_OPT 0 #define DNS_PSEUDOSECTION_TSIG 1 #define DNS_PSEUDOSECTION_SIG0 2 #define DNS_PSEUDOSECTION_MAX 3 typedef int dns_messagetextflag_t; #define DNS_MESSAGETEXTFLAG_NOCOMMENTS 0x0001 #define DNS_MESSAGETEXTFLAG_NOHEADERS 0x0002 #define DNS_MESSAGETEXTFLAG_ONESOA 0x0004 #define DNS_MESSAGETEXTFLAG_OMITSOA 0x0008 #define DNS_MESSAGETEXTFLAG_COMMENTDATA 0x0010 /* * Dynamic update names for these sections. */ #define DNS_SECTION_ZONE DNS_SECTION_QUESTION #define DNS_SECTION_PREREQUISITE DNS_SECTION_ANSWER #define DNS_SECTION_UPDATE DNS_SECTION_AUTHORITY /* * These tell the message library how the created dns_message_t will be used. */ #define DNS_MESSAGE_INTENTUNKNOWN 0 /*%< internal use only */ #define DNS_MESSAGE_INTENTPARSE 1 /*%< parsing messages */ #define DNS_MESSAGE_INTENTRENDER 2 /*%< rendering */ /* * Control behavior of parsing */ #define DNS_MESSAGEPARSE_PRESERVEORDER 0x0001 /*%< preserve rdata order */ #define DNS_MESSAGEPARSE_BESTEFFORT 0x0002 /*%< return a message if a recoverable parse error occurs */ #define DNS_MESSAGEPARSE_CLONEBUFFER 0x0004 /*%< save a copy of the source buffer */ #define DNS_MESSAGEPARSE_IGNORETRUNCATION 0x0008 /*%< truncation errors are * not fatal. */ /* * Control behavior of rendering */ #define DNS_MESSAGERENDER_ORDERED 0x0001 /*%< don't change order */ #define DNS_MESSAGERENDER_PARTIAL 0x0002 /*%< allow a partial rdataset */ #define DNS_MESSAGERENDER_OMITDNSSEC 0x0004 /*%< omit DNSSEC records */ #define DNS_MESSAGERENDER_PREFER_A 0x0008 /*%< prefer A records in additional section. */ #define DNS_MESSAGERENDER_PREFER_AAAA 0x0010 /*%< prefer AAAA records in additional section. */ #ifdef ALLOW_FILTER_AAAA #define DNS_MESSAGERENDER_FILTER_AAAA 0x0020 /*%< filter AAAA records */ #endif typedef struct dns_msgblock dns_msgblock_t; struct dns_message { /* public from here down */ unsigned int magic; dns_messageid_t id; unsigned int flags; dns_rcode_t rcode; dns_opcode_t opcode; dns_rdataclass_t rdclass; /* 4 real, 1 pseudo */ unsigned int counts[DNS_SECTION_MAX]; /* private from here down */ dns_namelist_t sections[DNS_SECTION_MAX]; dns_name_t *cursors[DNS_SECTION_MAX]; dns_rdataset_t *opt; dns_rdataset_t *sig0; dns_rdataset_t *tsig; int state; unsigned int from_to_wire : 2; unsigned int header_ok : 1; unsigned int question_ok : 1; unsigned int tcp_continuation : 1; unsigned int verified_sig : 1; unsigned int verify_attempted : 1; unsigned int free_query : 1; unsigned int free_saved : 1; unsigned int sitok : 1; unsigned int sitbad : 1; unsigned int tkey : 1; unsigned int rdclass_set : 1; unsigned int opt_reserved; unsigned int sig_reserved; unsigned int reserved; /* reserved space (render) */ isc_buffer_t *buffer; dns_compress_t *cctx; isc_mem_t *mctx; isc_mempool_t *namepool; isc_mempool_t *rdspool; isc_bufferlist_t scratchpad; isc_bufferlist_t cleanup; ISC_LIST(dns_msgblock_t) rdatas; ISC_LIST(dns_msgblock_t) rdatalists; ISC_LIST(dns_msgblock_t) offsets; ISC_LIST(dns_rdata_t) freerdata; ISC_LIST(dns_rdatalist_t) freerdatalist; dns_rcode_t tsigstatus; dns_rcode_t querytsigstatus; dns_name_t *tsigname; /* Owner name of TSIG, if any */ dns_rdataset_t *querytsig; dns_tsigkey_t *tsigkey; dst_context_t *tsigctx; int sigstart; int timeadjust; dns_name_t *sig0name; /* Owner name of SIG0, if any */ dst_key_t *sig0key; dns_rcode_t sig0status; isc_region_t query; isc_region_t saved; dns_rdatasetorderfunc_t order; const void * order_arg; }; struct dns_ednsopt { isc_uint16_t code; isc_uint16_t length; unsigned char *value; }; /*** *** Functions ***/ ISC_LANG_BEGINDECLS isc_result_t dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp); /*%< * Create msg structure. * * This function will allocate some internal blocks of memory that are * expected to be needed for parsing or rendering nearly any type of message. * * Requires: *\li 'mctx' be a valid memory context. * *\li 'msgp' be non-null and '*msg' be NULL. * *\li 'intent' must be one of DNS_MESSAGE_INTENTPARSE or * #DNS_MESSAGE_INTENTRENDER. * * Ensures: *\li The data in "*msg" is set to indicate an unused and empty msg * structure. * * Returns: *\li #ISC_R_NOMEMORY -- out of memory *\li #ISC_R_SUCCESS -- success */ void dns_message_reset(dns_message_t *msg, unsigned int intent); /*%< * Reset a message structure to default state. All internal lists are freed * or reset to a default state as well. This is simply a more efficient * way to call dns_message_destroy() followed by dns_message_allocate(), * since it avoid many memory allocations. * * If any data loanouts (buffers, names, rdatas, etc) were requested, * the caller must no longer use them after this call. * * The intended next use of the message will be 'intent'. * * Requires: * *\li 'msg' be valid. * *\li 'intent' is DNS_MESSAGE_INTENTPARSE or DNS_MESSAGE_INTENTRENDER */ void dns_message_destroy(dns_message_t **msgp); /*%< * Destroy all state in the message. * * Requires: * *\li 'msgp' be valid. * * Ensures: *\li '*msgp' == NULL */ isc_result_t dns_message_sectiontotext(dns_message_t *msg, dns_section_t section, const dns_master_style_t *style, dns_messagetextflag_t flags, isc_buffer_t *target); isc_result_t dns_message_pseudosectiontotext(dns_message_t *msg, dns_pseudosection_t section, const dns_master_style_t *style, dns_messagetextflag_t flags, isc_buffer_t *target); /*%< * Convert section 'section' or 'pseudosection' of message 'msg' to * a cleartext representation * * Notes: * \li See dns_message_totext for meanings of flags. * * Requires: * *\li 'msg' is a valid message. * *\li 'style' is a valid master dump style. * *\li 'target' is a valid buffer. * *\li 'section' is a valid section label. * * Ensures: * *\li If the result is success: * The used space in 'target' is updated. * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_NOSPACE *\li #ISC_R_NOMORE * *\li Note: On error return, *target may be partially filled with data. */ isc_result_t dns_message_totext(dns_message_t *msg, const dns_master_style_t *style, dns_messagetextflag_t flags, isc_buffer_t *target); /*%< * Convert all sections of message 'msg' to a cleartext representation * * Notes: * \li In flags, If #DNS_MESSAGETEXTFLAG_OMITDOT is set, then the * final '.' in absolute names will not be emitted. If * #DNS_MESSAGETEXTFLAG_NOCOMMENTS is cleared, lines beginning * with ";;" will be emitted indicating section name. If * #DNS_MESSAGETEXTFLAG_NOHEADERS is cleared, header lines will * be emitted. * * If #DNS_MESSAGETEXTFLAG_ONESOA is set then only print the * first SOA record in the answer section. If * #DNS_MESSAGETEXTFLAG_OMITSOA is set don't print any SOA records * in the answer section. These are useful for suppressing the * display of the second SOA record in a AXFR by setting * #DNS_MESSAGETEXTFLAG_ONESOA on the first message in a AXFR stream * and #DNS_MESSAGETEXTFLAG_OMITSOA on subsequent messages. * * Requires: * *\li 'msg' is a valid message. * *\li 'style' is a valid master dump style. * *\li 'target' is a valid buffer. * * Ensures: * *\li If the result is success: * The used space in 'target' is updated. * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_NOSPACE *\li #ISC_R_NOMORE * *\li Note: On error return, *target may be partially filled with data. */ isc_result_t dns_message_parse(dns_message_t *msg, isc_buffer_t *source, unsigned int options); /*%< * Parse raw wire data in 'source' as a DNS message. * * OPT records are detected and stored in the pseudo-section "opt". * TSIGs are detected and stored in the pseudo-section "tsig". * * If #DNS_MESSAGEPARSE_PRESERVEORDER is set, or if the opcode of the message * is UPDATE, a separate dns_name_t object will be created for each RR in the * message. Each such dns_name_t will have a single rdataset containing the * single RR, and the order of the RRs in the message is preserved. * Otherwise, only one dns_name_t object will be created for each unique * owner name in the section, and each such dns_name_t will have a list * of rdatasets. To access the names and their data, use * dns_message_firstname() and dns_message_nextname(). * * If #DNS_MESSAGEPARSE_BESTEFFORT is set, errors in message content will * not be considered FORMERRs. If the entire message can be parsed, it * will be returned and DNS_R_RECOVERABLE will be returned. * * If #DNS_MESSAGEPARSE_IGNORETRUNCATION is set then return as many complete * RR's as possible, DNS_R_RECOVERABLE will be returned. * * OPT and TSIG records are always handled specially, regardless of the * 'preserve_order' setting. * * Requires: *\li "msg" be valid. * *\li "buffer" be a wire format buffer. * * Ensures: *\li The buffer's data format is correct. * *\li The buffer's contents verify as correct regarding header bits, buffer * and rdata sizes, etc. * * Returns: *\li #ISC_R_SUCCESS -- all is well *\li #ISC_R_NOMEMORY -- no memory *\li #DNS_R_RECOVERABLE -- the message parsed properly, but contained * errors. *\li Many other errors possible XXXMLG */ isc_result_t dns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx, isc_buffer_t *buffer); /*%< * Begin rendering on a message. Only one call can be made to this function * per message. * * The compression context is "owned" by the message library until * dns_message_renderend() is called. It must be invalidated by the caller. * * The buffer is "owned" by the message library until dns_message_renderend() * is called. * * Requires: * *\li 'msg' be valid. * *\li 'cctx' be valid. * *\li 'buffer' is a valid buffer. * * Side Effects: * *\li The buffer is cleared before it is used. * * Returns: *\li #ISC_R_SUCCESS -- all is well *\li #ISC_R_NOSPACE -- output buffer is too small */ isc_result_t dns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer); /*%< * Reset the buffer. This can be used after growing the old buffer * on a ISC_R_NOSPACE return from most of the render functions. * * On successful completion, the old buffer is no longer used by the * library. The new buffer is owned by the library until * dns_message_renderend() is called. * * Requires: * *\li 'msg' be valid. * *\li dns_message_renderbegin() was called. * *\li buffer != NULL. * * Returns: *\li #ISC_R_NOSPACE -- new buffer is too small *\li #ISC_R_SUCCESS -- all is well. */ isc_result_t dns_message_renderreserve(dns_message_t *msg, unsigned int space); /*%< * XXXMLG should use size_t rather than unsigned int once the buffer * API is cleaned up * * Reserve "space" bytes in the given buffer. * * Requires: * *\li 'msg' be valid. * *\li dns_message_renderbegin() was called. * * Returns: *\li #ISC_R_SUCCESS -- all is well. *\li #ISC_R_NOSPACE -- not enough free space in the buffer. */ void dns_message_renderrelease(dns_message_t *msg, unsigned int space); /*%< * XXXMLG should use size_t rather than unsigned int once the buffer * API is cleaned up * * Release "space" bytes in the given buffer that was previously reserved. * * Requires: * *\li 'msg' be valid. * *\li 'space' is less than or equal to the total amount of space reserved * via prior calls to dns_message_renderreserve(). * *\li dns_message_renderbegin() was called. */ isc_result_t dns_message_rendersection(dns_message_t *msg, dns_section_t section, unsigned int options); /*%< * Render all names, rdatalists, etc from the given section at the * specified priority or higher. * * Requires: *\li 'msg' be valid. * *\li 'section' be a valid section. * *\li dns_message_renderbegin() was called. * * Returns: *\li #ISC_R_SUCCESS -- all records were written, and there are * no more records for this section. *\li #ISC_R_NOSPACE -- Not enough room in the buffer to write * all records requested. *\li #DNS_R_MOREDATA -- All requested records written, and there * are records remaining for this section. */ void dns_message_renderheader(dns_message_t *msg, isc_buffer_t *target); /*%< * Render the message header. This is implicitly called by * dns_message_renderend(). * * Requires: * *\li 'msg' be a valid message. * *\li dns_message_renderbegin() was called. * *\li 'target' is a valid buffer with enough space to hold a message header */ isc_result_t dns_message_renderend(dns_message_t *msg); /*%< * Finish rendering to the buffer. Note that more data can be in the * 'msg' structure. Destroying the structure will free this, or in a multi- * part EDNS1 message this data can be rendered to another buffer later. * * Requires: * *\li 'msg' be a valid message. * *\li dns_message_renderbegin() was called. * * Returns: *\li #ISC_R_SUCCESS -- all is well. */ void dns_message_renderreset(dns_message_t *msg); /*%< * Reset the message so that it may be rendered again. * * Notes: * *\li If dns_message_renderbegin() has been called, dns_message_renderend() * must be called before calling this function. * * Requires: * *\li 'msg' be a valid message with rendering intent. */ isc_result_t dns_message_firstname(dns_message_t *msg, dns_section_t section); /*%< * Set internal per-section name pointer to the beginning of the section. * * The functions dns_message_firstname() and dns_message_nextname() may * be used for iterating over the owner names in a section. * * Requires: * *\li 'msg' be valid. * *\li 'section' be a valid section. * * Returns: *\li #ISC_R_SUCCESS -- All is well. *\li #ISC_R_NOMORE -- No names on given section. */ isc_result_t dns_message_nextname(dns_message_t *msg, dns_section_t section); /*%< * Sets the internal per-section name pointer to point to the next name * in that section. * * Requires: * * \li 'msg' be valid. * *\li 'section' be a valid section. * *\li dns_message_firstname() must have been called on this section, * and the result was ISC_R_SUCCESS. * * Returns: *\li #ISC_R_SUCCESS -- All is well. *\li #ISC_R_NOMORE -- No more names in given section. */ void dns_message_currentname(dns_message_t *msg, dns_section_t section, dns_name_t **name); /*%< * Sets 'name' to point to the name where the per-section internal name * pointer is currently set. * * This function returns the name in the database, so any data associated * with it (via the name's "list" member) contains the actual rdatasets. * * Requires: * *\li 'msg' be valid. * *\li 'name' be non-NULL, and *name be NULL. * *\li 'section' be a valid section. * *\li dns_message_firstname() must have been called on this section, * and the result of it and any dns_message_nextname() calls was * #ISC_R_SUCCESS. */ isc_result_t dns_message_findname(dns_message_t *msg, dns_section_t section, dns_name_t *target, dns_rdatatype_t type, dns_rdatatype_t covers, dns_name_t **foundname, dns_rdataset_t **rdataset); /*%< * Search for a name in the specified section. If it is found, *name is * set to point to the name, and *rdataset is set to point to the found * rdataset (if type is specified as other than dns_rdatatype_any). * * Requires: *\li 'msg' be valid. * *\li 'section' be a valid section. * *\li If a pointer to the name is desired, 'foundname' should be non-NULL. * If it is non-NULL, '*foundname' MUST be NULL. * *\li If a type other than dns_datatype_any is searched for, 'rdataset' * may be non-NULL, '*rdataset' be NULL, and will point at the found * rdataset. If the type is dns_datatype_any, 'rdataset' must be NULL. * *\li 'target' be a valid name. * *\li 'type' be a valid type. * *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. * Otherwise it should be 0. * * Returns: *\li #ISC_R_SUCCESS -- all is well. *\li #DNS_R_NXDOMAIN -- name does not exist in that section. *\li #DNS_R_NXRRSET -- The name does exist, but the desired * type does not. */ isc_result_t dns_message_findtype(dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers, dns_rdataset_t **rdataset); /*%< * Search the name for the specified type. If it is found, *rdataset is * filled in with a pointer to that rdataset. * * Requires: *\li if '**rdataset' is non-NULL, *rdataset needs to be NULL. * *\li 'type' be a valid type, and NOT dns_rdatatype_any. * *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. * Otherwise it should be 0. * * Returns: *\li #ISC_R_SUCCESS -- all is well. *\li #ISC_R_NOTFOUND -- the desired type does not exist. */ isc_result_t dns_message_find(dns_name_t *name, dns_rdataclass_t rdclass, dns_rdatatype_t type, dns_rdatatype_t covers, dns_rdataset_t **rdataset); /*%< * Search the name for the specified rdclass and type. If it is found, * *rdataset is filled in with a pointer to that rdataset. * * Requires: *\li if '**rdataset' is non-NULL, *rdataset needs to be NULL. * *\li 'type' be a valid type, and NOT dns_rdatatype_any. * *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. * Otherwise it should be 0. * * Returns: *\li #ISC_R_SUCCESS -- all is well. *\li #ISC_R_NOTFOUND -- the desired type does not exist. */ void dns_message_movename(dns_message_t *msg, dns_name_t *name, dns_section_t fromsection, dns_section_t tosection); /*%< * Move a name from one section to another. * * Requires: * *\li 'msg' be valid. * *\li 'name' must be a name already in 'fromsection'. * *\li 'fromsection' must be a valid section. * *\li 'tosection' must be a valid section. */ void dns_message_addname(dns_message_t *msg, dns_name_t *name, dns_section_t section); /*%< * Adds the name to the given section. * * It is the caller's responsibility to enforce any unique name requirements * in a section. * * Requires: * *\li 'msg' be valid, and be a renderable message. * *\li 'name' be a valid absolute name. * *\li 'section' be a named section. */ void dns_message_removename(dns_message_t *msg, dns_name_t *name, dns_section_t section); /*%< * Remove a existing name from a given section. * * It is the caller's responsibility to ensure the name is part of the * given section. * * Requires: * *\li 'msg' be valid, and be a renderable message. * *\li 'name' be a valid absolute name. * *\li 'section' be a named section. */ /* * LOANOUT FUNCTIONS * * Each of these functions loan a particular type of data to the caller. * The storage for these will vanish when the message is destroyed or * reset, and must NOT be used after these operations. */ isc_result_t dns_message_gettempname(dns_message_t *msg, dns_name_t **item); /*%< * Return a name that can be used for any temporary purpose, including * inserting into the message's linked lists. The name must be returned * to the message code using dns_message_puttempname() or inserted into * one of the message's sections before the message is destroyed. * * It is the caller's responsibility to initialize this name. * * Requires: *\li msg be a valid message * *\li item != NULL && *item == NULL * * Returns: *\li #ISC_R_SUCCESS -- All is well. *\li #ISC_R_NOMEMORY -- No item can be allocated. */ isc_result_t dns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item); /*%< * Return an offsets array that can be used for any temporary purpose, * such as attaching to a temporary name. The offsets will be freed * when the message is destroyed or reset. * * Requires: *\li msg be a valid message * *\li item != NULL && *item == NULL * * Returns: *\li #ISC_R_SUCCESS -- All is well. *\li #ISC_R_NOMEMORY -- No item can be allocated. */ isc_result_t dns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item); /*%< * Return a rdata that can be used for any temporary purpose, including * inserting into the message's linked lists. The rdata will be freed * when the message is destroyed or reset. * * Requires: *\li msg be a valid message * *\li item != NULL && *item == NULL * * Returns: *\li #ISC_R_SUCCESS -- All is well. *\li #ISC_R_NOMEMORY -- No item can be allocated. */ isc_result_t dns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item); /*%< * Return a rdataset that can be used for any temporary purpose, including * inserting into the message's linked lists. The name must be returned * to the message code using dns_message_puttempname() or inserted into * one of the message's sections before the message is destroyed. * * Requires: *\li msg be a valid message * *\li item != NULL && *item == NULL * * Returns: *\li #ISC_R_SUCCESS -- All is well. *\li #ISC_R_NOMEMORY -- No item can be allocated. */ isc_result_t dns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item); /*%< * Return a rdatalist that can be used for any temporary purpose, including * inserting into the message's linked lists. The rdatalist will be * destroyed when the message is destroyed or reset. * * Requires: *\li msg be a valid message * *\li item != NULL && *item == NULL * * Returns: *\li #ISC_R_SUCCESS -- All is well. *\li #ISC_R_NOMEMORY -- No item can be allocated. */ void dns_message_puttempname(dns_message_t *msg, dns_name_t **item); /*%< * Return a borrowed name to the message's name free list. * * Requires: *\li msg be a valid message * *\li item != NULL && *item point to a name returned by * dns_message_gettempname() * * Ensures: *\li *item == NULL */ void dns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item); /*%< * Return a borrowed rdata to the message's rdata free list. * * Requires: *\li msg be a valid message * *\li item != NULL && *item point to a rdata returned by * dns_message_gettemprdata() * * Ensures: *\li *item == NULL */ void dns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item); /*%< * Return a borrowed rdataset to the message's rdataset free list. * * Requires: *\li msg be a valid message * *\li item != NULL && *item point to a rdataset returned by * dns_message_gettemprdataset() * * Ensures: *\li *item == NULL */ void dns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item); /*%< * Return a borrowed rdatalist to the message's rdatalist free list. * * Requires: *\li msg be a valid message * *\li item != NULL && *item point to a rdatalist returned by * dns_message_gettemprdatalist() * * Ensures: *\li *item == NULL */ isc_result_t dns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp, unsigned int *flagsp); /*%< * Assume the remaining region of "source" is a DNS message. Peek into * it and fill in "*idp" with the message id, and "*flagsp" with the flags. * * Requires: * *\li source != NULL * * Ensures: * *\li if (idp != NULL) *idp == message id. * *\li if (flagsp != NULL) *flagsp == message flags. * * Returns: * *\li #ISC_R_SUCCESS -- all is well. * *\li #ISC_R_UNEXPECTEDEND -- buffer doesn't contain enough for a header. */ isc_result_t dns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section); /*%< * Start formatting a reply to the query in 'msg'. * * Requires: * *\li 'msg' is a valid message with parsing intent, and contains a query. * * Ensures: * *\li The message will have a rendering intent. If 'want_question_section' * is true, the message opcode is query or notify, and the question * section is present and properly formatted, then the question section * will be included in the reply. All other sections will be cleared. * The QR flag will be set, the RD flag will be preserved, and all other * flags will be cleared. * * Returns: * *\li #ISC_R_SUCCESS -- all is well. * *\li #DNS_R_FORMERR -- the header or question section of the * message is invalid, replying is impossible. * If DNS_R_FORMERR is returned when * want_question_section is ISC_FALSE, then * it's the header section that's bad; * otherwise either of the header or question * sections may be bad. */ dns_rdataset_t * dns_message_getopt(dns_message_t *msg); /*%< * Get the OPT record for 'msg'. * * Requires: * *\li 'msg' is a valid message. * * Returns: * *\li The OPT rdataset of 'msg', or NULL if there isn't one. */ isc_result_t dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt); /*%< * Set the OPT record for 'msg'. * * Requires: * *\li 'msg' is a valid message with rendering intent * and no sections have been rendered. * *\li 'opt' is a valid OPT record. * * Ensures: * *\li The OPT record has either been freed or ownership of it has * been transferred to the message. * *\li If ISC_R_SUCCESS was returned, the OPT record will be rendered * when dns_message_renderend() is called. * * Returns: * *\li #ISC_R_SUCCESS -- all is well. * *\li #ISC_R_NOSPACE -- there is no space for the OPT record. */ dns_rdataset_t * dns_message_gettsig(dns_message_t *msg, dns_name_t **owner); /*%< * Get the TSIG record and owner for 'msg'. * * Requires: * *\li 'msg' is a valid message. *\li 'owner' is NULL or *owner is NULL. * * Returns: * *\li The TSIG rdataset of 'msg', or NULL if there isn't one. * * Ensures: * * \li If 'owner' is not NULL, it will point to the owner name. */ isc_result_t dns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key); /*%< * Set the tsig key for 'msg'. This is only necessary for when rendering a * query or parsing a response. The key (if non-NULL) is attached to, and * will be detached when the message is destroyed. * * Requires: * *\li 'msg' is a valid message with rendering intent, * dns_message_renderbegin() has been called, and no sections have been * rendered. *\li 'key' is a valid tsig key or NULL. * * Returns: * *\li #ISC_R_SUCCESS -- all is well. * *\li #ISC_R_NOSPACE -- there is no space for the TSIG record. */ dns_tsigkey_t * dns_message_gettsigkey(dns_message_t *msg); /*%< * Gets the tsig key for 'msg'. * * Requires: * *\li 'msg' is a valid message */ isc_result_t dns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig); /*%< * Indicates that 'querytsig' is the TSIG from the signed query for which * 'msg' is the response. This is also used for chained TSIGs in TCP * responses. * * Requires: * *\li 'querytsig' is a valid buffer as returned by dns_message_getquerytsig() * or NULL * *\li 'msg' is a valid message * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY */ isc_result_t dns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t **querytsig); /*%< * Gets the tsig from the TSIG from the signed query 'msg'. This is also used * for chained TSIGs in TCP responses. Unlike dns_message_gettsig, this makes * a copy of the data, so can be used if the message is destroyed. * * Requires: * *\li 'msg' is a valid signed message *\li 'mctx' is a valid memory context *\li querytsig != NULL && *querytsig == NULL * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY * * Ensures: *\li 'tsig' points to NULL or an allocated buffer which must be freed * by the caller. */ dns_rdataset_t * dns_message_getsig0(dns_message_t *msg, dns_name_t **owner); /*%< * Get the SIG(0) record and owner for 'msg'. * * Requires: * *\li 'msg' is a valid message. *\li 'owner' is NULL or *owner is NULL. * * Returns: * *\li The SIG(0) rdataset of 'msg', or NULL if there isn't one. * * Ensures: * * \li If 'owner' is not NULL, it will point to the owner name. */ isc_result_t dns_message_setsig0key(dns_message_t *msg, dst_key_t *key); /*%< * Set the SIG(0) key for 'msg'. * * Requires: * *\li 'msg' is a valid message with rendering intent, * dns_message_renderbegin() has been called, and no sections have been * rendered. *\li 'key' is a valid sig key or NULL. * * Returns: * *\li #ISC_R_SUCCESS -- all is well. * *\li #ISC_R_NOSPACE -- there is no space for the SIG(0) record. */ dst_key_t * dns_message_getsig0key(dns_message_t *msg); /*%< * Gets the SIG(0) key for 'msg'. * * Requires: * *\li 'msg' is a valid message */ void dns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer); /*%< * Give the *buffer to the message code to clean up when it is no * longer needed. This is usually when the message is reset or * destroyed. * * Requires: * *\li msg be a valid message. * *\li buffer != NULL && *buffer is a valid isc_buffer_t, which was * dynamically allocated via isc_buffer_allocate(). */ isc_result_t dns_message_signer(dns_message_t *msg, dns_name_t *signer); /*%< * If this message was signed, return the identity of the signer. * Unless ISC_R_NOTFOUND is returned, signer will reflect the name of the * key that signed the message. * * Requires: * *\li msg is a valid parsed message. *\li signer is a valid name * * Returns: * *\li #ISC_R_SUCCESS - the message was signed, and *signer * contains the signing identity * *\li #ISC_R_NOTFOUND - no TSIG or SIG(0) record is present in the * message * *\li #DNS_R_TSIGVERIFYFAILURE - the message was signed by a TSIG, but the * signature failed to verify * *\li #DNS_R_TSIGERRORSET - the message was signed by a TSIG and * verified, but the query was rejected by * the server * *\li #DNS_R_NOIDENTITY - the message was signed by a TSIG and * verified, but the key has no identity since * it was generated by an unsigned TKEY process * *\li #DNS_R_SIGINVALID - the message was signed by a SIG(0), but * the signature failed to verify * *\li #DNS_R_NOTVERIFIEDYET - the message was signed by a TSIG or SIG(0), * but the signature has not been verified yet */ isc_result_t dns_message_checksig(dns_message_t *msg, dns_view_t *view); /*%< * If this message was signed, verify the signature. * * Requires: * *\li msg is a valid parsed message. *\li view is a valid view or NULL * * Returns: * *\li #ISC_R_SUCCESS - the message was unsigned, or the message * was signed correctly. * *\li #DNS_R_EXPECTEDTSIG - A TSIG was expected, but not seen *\li #DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected *\li #DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify */ isc_result_t dns_message_rechecksig(dns_message_t *msg, dns_view_t *view); /*%< * Reset the signature state and then if the message was signed, * verify the message. * * Requires: * *\li msg is a valid parsed message. *\li view is a valid view or NULL * * Returns: * *\li #ISC_R_SUCCESS - the message was unsigned, or the message * was signed correctly. * *\li #DNS_R_EXPECTEDTSIG - A TSIG was expected, but not seen *\li #DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected *\li #DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify */ void dns_message_resetsig(dns_message_t *msg); /*%< * Reset the signature state. * * Requires: *\li 'msg' is a valid parsed message. */ isc_region_t * dns_message_getrawmessage(dns_message_t *msg); /*%< * Retrieve the raw message in compressed wire format. The message must * have been successfully parsed for it to have been saved. * * Requires: *\li msg is a valid parsed message. * * Returns: *\li NULL if there is no saved message. * a pointer to a region which refers the dns message. */ void dns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order, const void *order_arg); /*%< * Define the order in which RR sets get rendered by * dns_message_rendersection() to be the ascending order * defined by the integer value returned by 'order' when * given each RR and 'arg' as arguments. If 'order' and * 'order_arg' are NULL, a default order is used. * * Requires: *\li msg be a valid message. *\li order_arg is NULL if and only if order is NULL. */ void dns_message_settimeadjust(dns_message_t *msg, int timeadjust); /*%< * Adjust the time used to sign/verify a message by timeadjust. * Currently only TSIG. * * Requires: *\li msg be a valid message. */ int dns_message_gettimeadjust(dns_message_t *msg); /*%< * Return the current time adjustment. * * Requires: *\li msg be a valid message. */ void dns_message_logpacket(dns_message_t *message, const char *description, isc_logcategory_t *category, isc_logmodule_t *module, int level, isc_mem_t *mctx); void dns_message_logfmtpacket(dns_message_t *message, const char *description, isc_logcategory_t *category, isc_logmodule_t *module, const dns_master_style_t *style, int level, isc_mem_t *mctx); /*%< * Log 'message' at the specified logging parameters. * 'description' will be emitted at the start of the message and will * normally end with a newline. */ isc_result_t dns_message_buildopt(dns_message_t *msg, dns_rdataset_t **opt, unsigned int version, isc_uint16_t udpsize, unsigned int flags, dns_ednsopt_t *ednsopts, size_t count); /*%< * Built a opt record. * * Requires: * \li msg be a valid message. * \li opt to be a non NULL and *opt to be NULL. * * Returns: * \li ISC_R_SUCCESS on success. * \li ISC_R_NOMEMORY * \li ISC_R_NOSPACE * \li other. */ void dns_message_setclass(dns_message_t *msg, dns_rdataclass_t rdclass); /*%< * Set the expected class of records in the response. * * Requires: * \li msg be a valid message with parsing intent. */ ISC_LANG_ENDDECLS #endif /* DNS_MESSAGE_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/timer.h0000644000470500017500000000303412664710322020423 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: timer.h,v 1.9 2007/06/19 23:47:17 tbox Exp $ */ #ifndef DNS_TIMER_H #define DNS_TIMER_H 1 /*! \file dns/timer.h */ /*** *** Imports ***/ #include #include ISC_LANG_BEGINDECLS /*** *** Functions ***/ isc_result_t dns_timer_setidle(isc_timer_t *timer, unsigned int maxtime, unsigned int idletime, isc_boolean_t purge); /*%< * Convenience function for setting up simple, one-second-granularity * idle timers as used by zone transfers. * \brief * Set the timer 'timer' to go off after 'idletime' seconds of inactivity, * or after 'maxtime' at the very latest. Events are purged iff * 'purge' is ISC_TRUE. */ ISC_LANG_ENDDECLS #endif /* DNS_TIMER_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/tsec.h0000644000470500017500000000653312664710322020250 0ustar lamontlamont/* * Copyright (C) 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: tsec.h,v 1.6 2010/12/09 00:54:34 marka Exp $ */ #ifndef DNS_TSEC_H #define DNS_TSEC_H 1 /***** ***** Module Info *****/ /*! \file * * \brief * The TSEC (Transaction Security) module is an abstraction layer for managing * DNS transaction mechanisms such as TSIG or SIG(0). A TSEC structure is a * mechanism-independent object containing key information specific to the * mechanism, and is expected to be used as an argument to other modules * that use transaction security in a mechanism-independent manner. * * MP: *\li A TSEC structure is expected to be thread-specific. No inter-thread * synchronization is ensured in multiple access to a single TSEC * structure. * * Resources: *\li TBS * * Security: *\li This module does not handle any low-level data directly, and so no * security issue specific to this module is anticipated. */ #include #include ISC_LANG_BEGINDECLS /*** *** Types ***/ /*% * Transaction security types. */ typedef enum { dns_tsectype_none, dns_tsectype_tsig, dns_tsectype_sig0 } dns_tsectype_t; isc_result_t dns_tsec_create(isc_mem_t *mctx, dns_tsectype_t type, dst_key_t *key, dns_tsec_t **tsecp); /*%< * Create a TSEC structure and stores a type-dependent key structure in it. * For a TSIG key (type is dns_tsectype_tsig), dns_tsec_create() creates a * TSIG key structure from '*key' and keeps it in the structure. For other * types, this function simply retains '*key' in the structure. In either * case, the ownership of '*key' is transferred to the TSEC module; the caller * must not modify or destroy it after the call to dns_tsec_create(). * * Requires: * *\li 'mctx' is a valid memory context. * *\li 'type' is a valid value of dns_tsectype_t (see above). * *\li 'key' is a valid key. * *\li tsecp != NULL && *tsecp == NULL. * * Returns: * *\li #ISC_R_SUCCESS On success. * *\li Anything else Failure. */ void dns_tsec_destroy(dns_tsec_t **tsecp); /*%< * Destroy the TSEC structure. The stored key is also detached or destroyed. * * Requires * *\li '*tsecp' is a valid TSEC structure. * * Ensures * *\li *tsecp == NULL. * */ dns_tsectype_t dns_tsec_gettype(dns_tsec_t *tsec); /*%< * Return the TSEC type of '*tsec'. * * Requires * *\li 'tsec' is a valid TSEC structure. * */ void dns_tsec_getkey(dns_tsec_t *tsec, void *keyp); /*%< * Return the TSEC key of '*tsec' in '*keyp'. * * Requires * *\li keyp != NULL * * Ensures * *\li *tsecp points to a valid key structure depending on the TSEC type. */ ISC_LANG_ENDDECLS #endif /* DNS_TSEC_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/forward.h0000644000470500017500000000757412664710322020764 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: forward.h,v 1.13 2009/09/02 23:48:02 tbox Exp $ */ #ifndef DNS_FORWARD_H #define DNS_FORWARD_H 1 /*! \file dns/forward.h */ #include #include #include ISC_LANG_BEGINDECLS struct dns_forwarder { isc_sockaddr_t addr; isc_dscp_t dscp; ISC_LINK(dns_forwarder_t) link; }; typedef ISC_LIST(struct dns_forwarder) dns_forwarderlist_t; struct dns_forwarders { dns_forwarderlist_t fwdrs; dns_fwdpolicy_t fwdpolicy; }; isc_result_t dns_fwdtable_create(isc_mem_t *mctx, dns_fwdtable_t **fwdtablep); /*%< * Creates a new forwarding table. * * Requires: * \li mctx is a valid memory context. * \li fwdtablep != NULL && *fwdtablep == NULL * * Returns: * \li #ISC_R_SUCCESS * \li #ISC_R_NOMEMORY */ isc_result_t dns_fwdtable_addfwd(dns_fwdtable_t *fwdtable, dns_name_t *name, dns_forwarderlist_t *fwdrs, dns_fwdpolicy_t policy); isc_result_t dns_fwdtable_add(dns_fwdtable_t *fwdtable, dns_name_t *name, isc_sockaddrlist_t *addrs, dns_fwdpolicy_t policy); /*%< * Adds an entry to the forwarding table. The entry associates * a domain with a list of forwarders and a forwarding policy. The * addrs/fwdrs list is copied if not empty, so the caller should free * its copy. * * Requires: * \li fwdtable is a valid forwarding table. * \li name is a valid name * \li addrs/fwdrs is a valid list of isc_sockaddr/dns_forwarder * structures, which may be empty. * * Returns: * \li #ISC_R_SUCCESS * \li #ISC_R_NOMEMORY */ isc_result_t dns_fwdtable_delete(dns_fwdtable_t *fwdtable, dns_name_t *name); /*%< * Removes an entry for 'name' from the forwarding table. If an entry * that exactly matches 'name' does not exist, ISC_R_NOTFOUND will be returned. * * Requires: * \li fwdtable is a valid forwarding table. * \li name is a valid name * * Returns: * \li #ISC_R_SUCCESS * \li #ISC_R_NOTFOUND */ isc_result_t dns_fwdtable_find(dns_fwdtable_t *fwdtable, dns_name_t *name, dns_forwarders_t **forwardersp); /*%< * Finds a domain in the forwarding table. The closest matching parent * domain is returned. * * Requires: * \li fwdtable is a valid forwarding table. * \li name is a valid name * \li forwardersp != NULL && *forwardersp == NULL * * Returns: * \li #ISC_R_SUCCESS * \li #ISC_R_NOTFOUND */ isc_result_t dns_fwdtable_find2(dns_fwdtable_t *fwdtable, dns_name_t *name, dns_name_t *foundname, dns_forwarders_t **forwardersp); /*%< * Finds a domain in the forwarding table. The closest matching parent * domain is returned. * * Requires: * \li fwdtable is a valid forwarding table. * \li name is a valid name * \li forwardersp != NULL && *forwardersp == NULL * \li foundname to be NULL or a valid name with buffer. * * Returns: * \li #ISC_R_SUCCESS * \li #ISC_R_NOTFOUND */ void dns_fwdtable_destroy(dns_fwdtable_t **fwdtablep); /*%< * Destroys a forwarding table. * * Requires: * \li fwtablep != NULL && *fwtablep != NULL * * Ensures: * \li all memory associated with the forwarding table is freed. */ ISC_LANG_ENDDECLS #endif /* DNS_FORWARD_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/name.h0000644000470500017500000010630412664710322020227 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009-2013, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: name.h,v 1.137 2011/01/13 04:59:26 tbox Exp $ */ #ifndef DNS_NAME_H #define DNS_NAME_H 1 /***** ***** Module Info *****/ /*! \file dns/name.h * \brief * Provides facilities for manipulating DNS names and labels, including * conversions to and from wire format and text format. * * Given the large number of names possible in a nameserver, and because * names occur in rdata, it was important to come up with a very efficient * way of storing name data, but at the same time allow names to be * manipulated. The decision was to store names in uncompressed wire format, * and not to make them fully abstracted objects; i.e. certain parts of the * server know names are stored that way. This saves a lot of memory, and * makes adding names to messages easy. Having much of the server know * the representation would be perilous, and we certainly don't want each * user of names to be manipulating such a low-level structure. This is * where the Names and Labels module comes in. The module allows name or * label handles to be created and attached to uncompressed wire format * regions. All name operations and conversions are done through these * handles. * * MP: *\li Clients of this module must impose any required synchronization. * * Reliability: *\li This module deals with low-level byte streams. Errors in any of * the functions are likely to crash the server or corrupt memory. * * Resources: *\li None. * * Security: * *\li *** WARNING *** * *\li dns_name_fromwire() deals with raw network data. An error in * this routine could result in the failure or hijacking of the server. * * Standards: *\li RFC1035 *\li Draft EDNS0 (0) *\li Draft Binary Labels (2) * */ /*** *** Imports ***/ #include #include #include #include #include /* Required for storage size of dns_label_t. */ #include ISC_LANG_BEGINDECLS /***** ***** Labels ***** ***** A 'label' is basically a region. It contains one DNS wire format ***** label of type 00 (ordinary). *****/ /***** ***** Names ***** ***** A 'name' is a handle to a binary region. It contains a sequence of one ***** or more DNS wire format labels of type 00 (ordinary). ***** Note that all names are not required to end with the root label, ***** as they are in the actual DNS wire protocol. *****/ /*** *** Types ***/ /*% * Clients are strongly discouraged from using this type directly, with * the exception of the 'link' and 'list' fields which may be used directly * for whatever purpose the client desires. */ struct dns_name { unsigned int magic; unsigned char * ndata; unsigned int length; unsigned int labels; unsigned int attributes; unsigned char * offsets; isc_buffer_t * buffer; ISC_LINK(dns_name_t) link; ISC_LIST(dns_rdataset_t) list; }; #define DNS_NAME_MAGIC ISC_MAGIC('D','N','S','n') #define DNS_NAMEATTR_ABSOLUTE 0x00000001 #define DNS_NAMEATTR_READONLY 0x00000002 #define DNS_NAMEATTR_DYNAMIC 0x00000004 #define DNS_NAMEATTR_DYNOFFSETS 0x00000008 #define DNS_NAMEATTR_NOCOMPRESS 0x00000010 /* * Attributes below 0x0100 reserved for name.c usage. */ #define DNS_NAMEATTR_CACHE 0x00000100 /*%< Used by resolver. */ #define DNS_NAMEATTR_ANSWER 0x00000200 /*%< Used by resolver. */ #define DNS_NAMEATTR_NCACHE 0x00000400 /*%< Used by resolver. */ #define DNS_NAMEATTR_CHAINING 0x00000800 /*%< Used by resolver. */ #define DNS_NAMEATTR_CHASE 0x00001000 /*%< Used by resolver. */ #define DNS_NAMEATTR_WILDCARD 0x00002000 /*%< Used by server. */ #define DNS_NAMEATTR_PREREQUISITE 0x00004000 /*%< Used by client. */ #define DNS_NAMEATTR_UPDATE 0x00008000 /*%< Used by client. */ #define DNS_NAMEATTR_HASUPDATEREC 0x00010000 /*%< Used by client. */ /* * Various flags. */ #define DNS_NAME_DOWNCASE 0x0001 #define DNS_NAME_CHECKNAMES 0x0002 /*%< Used by rdata. */ #define DNS_NAME_CHECKNAMESFAIL 0x0004 /*%< Used by rdata. */ #define DNS_NAME_CHECKREVERSE 0x0008 /*%< Used by rdata. */ #define DNS_NAME_CHECKMX 0x0010 /*%< Used by rdata. */ #define DNS_NAME_CHECKMXFAIL 0x0020 /*%< Used by rdata. */ LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_rootname; LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_wildcardname; /*% * Standard size of a wire format name */ #define DNS_NAME_MAXWIRE 255 /* * Text output filter procedure. * 'target' is the buffer to be converted. The region to be converted * is from 'buffer'->base + 'used_org' to the end of the used region. */ typedef isc_result_t (*dns_name_totextfilter_t)(isc_buffer_t *target, unsigned int used_org, isc_boolean_t absolute); /*** *** Initialization ***/ void dns_name_init(dns_name_t *name, unsigned char *offsets); /*%< * Initialize 'name'. * * Notes: * \li 'offsets' is never required to be non-NULL, but specifying a * dns_offsets_t for 'offsets' will improve the performance of most * name operations if the name is used more than once. * * Requires: * \li 'name' is not NULL and points to a struct dns_name. * * \li offsets == NULL or offsets is a dns_offsets_t. * * Ensures: * \li 'name' is a valid name. * \li dns_name_countlabels(name) == 0 * \li dns_name_isabsolute(name) == ISC_FALSE */ void dns_name_reset(dns_name_t *name); /*%< * Reinitialize 'name'. * * Notes: * \li This function distinguishes itself from dns_name_init() in two * key ways: * * \li + If any buffer is associated with 'name' (via dns_name_setbuffer() * or by being part of a dns_fixedname_t) the link to the buffer * is retained but the buffer itself is cleared. * * \li + Of the attributes associated with 'name', all are retained except * DNS_NAMEATTR_ABSOLUTE. * * Requires: * \li 'name' is a valid name. * * Ensures: * \li 'name' is a valid name. * \li dns_name_countlabels(name) == 0 * \li dns_name_isabsolute(name) == ISC_FALSE */ void dns_name_invalidate(dns_name_t *name); /*%< * Make 'name' invalid. * * Requires: * \li 'name' is a valid name. * * Ensures: * \li If assertion checking is enabled, future attempts to use 'name' * without initializing it will cause an assertion failure. * * \li If the name had a dedicated buffer, that association is ended. */ isc_boolean_t dns_name_isvalid(const dns_name_t *name); /*%< * Check whether 'name' points to a valid dns_name */ /*** *** Dedicated Buffers ***/ void dns_name_setbuffer(dns_name_t *name, isc_buffer_t *buffer); /*%< * Dedicate a buffer for use with 'name'. * * Notes: * \li Specification of a target buffer in dns_name_fromwire(), * dns_name_fromtext(), and dns_name_concatenate() is optional if * 'name' has a dedicated buffer. * * \li The caller must not write to buffer until the name has been * invalidated or is otherwise known not to be in use. * * \li If buffer is NULL and the name previously had a dedicated buffer, * than that buffer is no longer dedicated to use with this name. * The caller is responsible for ensuring that the storage used by * the name remains valid. * * Requires: * \li 'name' is a valid name. * * \li 'buffer' is a valid binary buffer and 'name' doesn't have a * dedicated buffer already, or 'buffer' is NULL. */ isc_boolean_t dns_name_hasbuffer(const dns_name_t *name); /*%< * Does 'name' have a dedicated buffer? * * Requires: * \li 'name' is a valid name. * * Returns: * \li ISC_TRUE 'name' has a dedicated buffer. * \li ISC_FALSE 'name' does not have a dedicated buffer. */ /*** *** Properties ***/ isc_boolean_t dns_name_isabsolute(const dns_name_t *name); /*%< * Does 'name' end in the root label? * * Requires: * \li 'name' is a valid name * * Returns: * \li TRUE The last label in 'name' is the root label. * \li FALSE The last label in 'name' is not the root label. */ isc_boolean_t dns_name_iswildcard(const dns_name_t *name); /*%< * Is 'name' a wildcard name? * * Requires: * \li 'name' is a valid name * * \li dns_name_countlabels(name) > 0 * * Returns: * \li TRUE The least significant label of 'name' is '*'. * \li FALSE The least significant label of 'name' is not '*'. */ unsigned int dns_name_hash(dns_name_t *name, isc_boolean_t case_sensitive); /*%< * Provide a hash value for 'name'. * * Note: if 'case_sensitive' is ISC_FALSE, then names which differ only in * case will have the same hash value. * * Requires: * \li 'name' is a valid name * * Returns: * \li A hash value */ unsigned int dns_name_fullhash(dns_name_t *name, isc_boolean_t case_sensitive); /*%< * Provide a hash value for 'name'. Unlike dns_name_hash(), this function * always takes into account of the entire name to calculate the hash value. * * Note: if 'case_sensitive' is ISC_FALSE, then names which differ only in * case will have the same hash value. * * Requires: *\li 'name' is a valid name * * Returns: *\li A hash value */ unsigned int dns_name_hashbylabel(dns_name_t *name, isc_boolean_t case_sensitive); /*%< * Provide a hash value for 'name', where the hash value is the sum * of the hash values of each label. * * Note: if 'case_sensitive' is ISC_FALSE, then names which differ only in * case will have the same hash value. * * Requires: *\li 'name' is a valid name * * Returns: *\li A hash value */ /* *** Comparisons ***/ dns_namereln_t dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2, int *orderp, unsigned int *nlabelsp); /*%< * Determine the relative ordering under the DNSSEC order relation of * 'name1' and 'name2', and also determine the hierarchical * relationship of the names. * * Note: It makes no sense for one of the names to be relative and the * other absolute. If both names are relative, then to be meaningfully * compared the caller must ensure that they are both relative to the * same domain. * * Requires: *\li 'name1' is a valid name * *\li dns_name_countlabels(name1) > 0 * *\li 'name2' is a valid name * *\li dns_name_countlabels(name2) > 0 * *\li orderp and nlabelsp are valid pointers. * *\li Either name1 is absolute and name2 is absolute, or neither is. * * Ensures: * *\li *orderp is < 0 if name1 < name2, 0 if name1 = name2, > 0 if * name1 > name2. * *\li *nlabelsp is the number of common significant labels. * * Returns: *\li dns_namereln_none There's no hierarchical relationship * between name1 and name2. *\li dns_namereln_contains name1 properly contains name2; i.e. * name2 is a proper subdomain of name1. *\li dns_namereln_subdomain name1 is a proper subdomain of name2. *\li dns_namereln_equal name1 and name2 are equal. *\li dns_namereln_commonancestor name1 and name2 share a common * ancestor. */ int dns_name_compare(const dns_name_t *name1, const dns_name_t *name2); /*%< * Determine the relative ordering under the DNSSEC order relation of * 'name1' and 'name2'. * * Note: It makes no sense for one of the names to be relative and the * other absolute. If both names are relative, then to be meaningfully * compared the caller must ensure that they are both relative to the * same domain. * * Requires: * \li 'name1' is a valid name * * \li 'name2' is a valid name * * \li Either name1 is absolute and name2 is absolute, or neither is. * * Returns: * \li < 0 'name1' is less than 'name2' * \li 0 'name1' is equal to 'name2' * \li > 0 'name1' is greater than 'name2' */ isc_boolean_t dns_name_equal(const dns_name_t *name1, const dns_name_t *name2); /*%< * Are 'name1' and 'name2' equal? * * Notes: * \li Because it only needs to test for equality, dns_name_equal() can be * significantly faster than dns_name_fullcompare() or dns_name_compare(). * * \li Offsets tables are not used in the comparision. * * \li It makes no sense for one of the names to be relative and the * other absolute. If both names are relative, then to be meaningfully * compared the caller must ensure that they are both relative to the * same domain. * * Requires: * \li 'name1' is a valid name * * \li 'name2' is a valid name * * \li Either name1 is absolute and name2 is absolute, or neither is. * * Returns: * \li ISC_TRUE 'name1' and 'name2' are equal * \li ISC_FALSE 'name1' and 'name2' are not equal */ isc_boolean_t dns_name_caseequal(const dns_name_t *name1, const dns_name_t *name2); /*%< * Case sensitive version of dns_name_equal(). */ int dns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2); /*%< * Compare two names as if they are part of rdata in DNSSEC canonical * form. * * Requires: * \li 'name1' is a valid absolute name * * \li dns_name_countlabels(name1) > 0 * * \li 'name2' is a valid absolute name * * \li dns_name_countlabels(name2) > 0 * * Returns: * \li < 0 'name1' is less than 'name2' * \li 0 'name1' is equal to 'name2' * \li > 0 'name1' is greater than 'name2' */ isc_boolean_t dns_name_issubdomain(const dns_name_t *name1, const dns_name_t *name2); /*%< * Is 'name1' a subdomain of 'name2'? * * Notes: * \li name1 is a subdomain of name2 if name1 is contained in name2, or * name1 equals name2. * * \li It makes no sense for one of the names to be relative and the * other absolute. If both names are relative, then to be meaningfully * compared the caller must ensure that they are both relative to the * same domain. * * Requires: * \li 'name1' is a valid name * * \li 'name2' is a valid name * * \li Either name1 is absolute and name2 is absolute, or neither is. * * Returns: * \li TRUE 'name1' is a subdomain of 'name2' * \li FALSE 'name1' is not a subdomain of 'name2' */ isc_boolean_t dns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname); /*%< * Does 'name' match the wildcard specified in 'wname'? * * Notes: * \li name matches the wildcard specified in wname if all labels * following the wildcard in wname are identical to the same number * of labels at the end of name. * * \li It makes no sense for one of the names to be relative and the * other absolute. If both names are relative, then to be meaningfully * compared the caller must ensure that they are both relative to the * same domain. * * Requires: * \li 'name' is a valid name * * \li dns_name_countlabels(name) > 0 * * \li 'wname' is a valid name * * \li dns_name_countlabels(wname) > 0 * * \li dns_name_iswildcard(wname) is true * * \li Either name is absolute and wname is absolute, or neither is. * * Returns: * \li TRUE 'name' matches the wildcard specified in 'wname' * \li FALSE 'name' does not match the wildcard specified in 'wname' */ /*** *** Labels ***/ unsigned int dns_name_countlabels(const dns_name_t *name); /*%< * How many labels does 'name' have? * * Notes: * \li In this case, as in other places, a 'label' is an ordinary label. * * Requires: * \li 'name' is a valid name * * Ensures: * \li The result is <= 128. * * Returns: * \li The number of labels in 'name'. */ void dns_name_getlabel(const dns_name_t *name, unsigned int n, dns_label_t *label); /*%< * Make 'label' refer to the 'n'th least significant label of 'name'. * * Notes: * \li Numbering starts at 0. * * \li Given "rc.vix.com.", the label 0 is "rc", and label 3 is the * root label. * * \li 'label' refers to the same memory as 'name', so 'name' must not * be changed while 'label' is still in use. * * Requires: * \li n < dns_name_countlabels(name) */ void dns_name_getlabelsequence(const dns_name_t *source, unsigned int first, unsigned int n, dns_name_t *target); /*%< * Make 'target' refer to the 'n' labels including and following 'first' * in 'source'. * * Notes: * \li Numbering starts at 0. * * \li Given "rc.vix.com.", the label 0 is "rc", and label 3 is the * root label. * * \li 'target' refers to the same memory as 'source', so 'source' * must not be changed while 'target' is still in use. * * Requires: * \li 'source' and 'target' are valid names. * * \li first < dns_name_countlabels(name) * * \li first + n <= dns_name_countlabels(name) */ void dns_name_clone(const dns_name_t *source, dns_name_t *target); /*%< * Make 'target' refer to the same name as 'source'. * * Notes: * * \li 'target' refers to the same memory as 'source', so 'source' * must not be changed while 'target' is still in use. * * \li This call is functionally equivalent to: * * \code * dns_name_getlabelsequence(source, 0, * dns_name_countlabels(source), * target); * \endcode * * but is more efficient. Also, dns_name_clone() works even if 'source' * is empty. * * Requires: * * \li 'source' is a valid name. * * \li 'target' is a valid name that is not read-only. */ /*** *** Conversions ***/ void dns_name_fromregion(dns_name_t *name, const isc_region_t *r); /*%< * Make 'name' refer to region 'r'. * * Note: * \li If the conversion encounters a root label before the end of the * region the conversion stops and the length is set to the length * so far converted. A maximum of 255 bytes is converted. * * Requires: * \li The data in 'r' is a sequence of one or more type 00 or type 01000001 * labels. */ void dns_name_toregion(dns_name_t *name, isc_region_t *r); /*%< * Make 'r' refer to 'name'. * * Requires: * * \li 'name' is a valid name. * * \li 'r' is a valid region. */ isc_result_t dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, dns_decompress_t *dctx, unsigned int options, isc_buffer_t *target); /*%< * Copy the possibly-compressed name at source (active region) into target, * decompressing it. * * Notes: * \li Decompression policy is controlled by 'dctx'. * * \li If DNS_NAME_DOWNCASE is set, any uppercase letters in 'source' will be * downcased when they are copied into 'target'. * * Security: * * \li *** WARNING *** * * \li This routine will often be used when 'source' contains raw network * data. A programming error in this routine could result in a denial * of service, or in the hijacking of the server. * * Requires: * * \li 'name' is a valid name. * * \li 'source' is a valid buffer and the first byte of the active * region should be the first byte of a DNS wire format domain name. * * \li 'target' is a valid buffer or 'target' is NULL and 'name' has * a dedicated buffer. * * \li 'dctx' is a valid decompression context. * * Ensures: * * If result is success: * \li If 'target' is not NULL, 'name' is attached to it. * * \li Uppercase letters are downcased in the copy iff * DNS_NAME_DOWNCASE is set in options. * * \li The current location in source is advanced, and the used space * in target is updated. * * Result: * \li Success * \li Bad Form: Label Length * \li Bad Form: Unknown Label Type * \li Bad Form: Name Length * \li Bad Form: Compression type not allowed * \li Bad Form: Bad compression pointer * \li Bad Form: Input too short * \li Resource Limit: Too many compression pointers * \li Resource Limit: Not enough space in buffer */ isc_result_t dns_name_towire(const dns_name_t *name, dns_compress_t *cctx, isc_buffer_t *target); /*%< * Convert 'name' into wire format, compressing it as specified by the * compression context 'cctx', and storing the result in 'target'. * * Notes: * \li If the compression context allows global compression, then the * global compression table may be updated. * * Requires: * \li 'name' is a valid name * * \li dns_name_countlabels(name) > 0 * * \li dns_name_isabsolute(name) == TRUE * * \li target is a valid buffer. * * \li Any offsets specified in a global compression table are valid * for buffer. * * Ensures: * * If the result is success: * * \li The used space in target is updated. * * Returns: * \li Success * \li Resource Limit: Not enough space in buffer */ isc_result_t dns_name_fromtext(dns_name_t *name, isc_buffer_t *source, const dns_name_t *origin, unsigned int options, isc_buffer_t *target); /*%< * Convert the textual representation of a DNS name at source * into uncompressed wire form stored in target. * * Notes: * \li Relative domain names will have 'origin' appended to them * unless 'origin' is NULL, in which case relative domain names * will remain relative. * * \li If DNS_NAME_DOWNCASE is set in 'options', any uppercase letters * in 'source' will be downcased when they are copied into 'target'. * * Requires: * * \li 'name' is a valid name. * * \li 'source' is a valid buffer. * * \li 'target' is a valid buffer or 'target' is NULL and 'name' has * a dedicated buffer. * * Ensures: * * If result is success: * \li If 'target' is not NULL, 'name' is attached to it. * * \li Uppercase letters are downcased in the copy iff * DNS_NAME_DOWNCASE is set in 'options'. * * \li The current location in source is advanced, and the used space * in target is updated. * * Result: *\li #ISC_R_SUCCESS *\li #DNS_R_EMPTYLABEL *\li #DNS_R_LABELTOOLONG *\li #DNS_R_BADESCAPE *\li (#DNS_R_BADBITSTRING: should not be returned) *\li (#DNS_R_BITSTRINGTOOLONG: should not be returned) *\li #DNS_R_BADDOTTEDQUAD *\li #ISC_R_NOSPACE *\li #ISC_R_UNEXPECTEDEND */ #define DNS_NAME_OMITFINALDOT 0x01U #define DNS_NAME_MASTERFILE 0x02U /* escape $ and @ */ isc_result_t dns_name_toprincipal(dns_name_t *name, isc_buffer_t *target); isc_result_t dns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot, isc_buffer_t *target); isc_result_t dns_name_totext2(dns_name_t *name, unsigned int options, isc_buffer_t *target); /*%< * Convert 'name' into text format, storing the result in 'target'. * * Notes: *\li If 'omit_final_dot' is true, then the final '.' in absolute * names other than the root name will be omitted. * *\li If DNS_NAME_OMITFINALDOT is set in options, then the final '.' * in absolute names other than the root name will be omitted. * *\li If DNS_NAME_MASTERFILE is set in options, '$' and '@' will also * be escaped. * *\li If dns_name_countlabels == 0, the name will be "@", representing the * current origin as described by RFC1035. * *\li The name is not NUL terminated. * * Requires: * *\li 'name' is a valid name * *\li 'target' is a valid buffer. * *\li if dns_name_isabsolute == FALSE, then omit_final_dot == FALSE * * Ensures: * *\li If the result is success: * the used space in target is updated. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOSPACE */ #define DNS_NAME_MAXTEXT 1023 /*%< * The maximum length of the text representation of a domain * name as generated by dns_name_totext(). This does not * include space for a terminating NULL. * * This definition is conservative - the actual maximum * is 1004, derived as follows: * * A backslash-decimal escaped character takes 4 bytes. * A wire-encoded name can be up to 255 bytes and each * label is one length byte + at most 63 bytes of data. * Maximizing the label lengths gives us a name of * three 63-octet labels, one 61-octet label, and the * root label: * * 1 + 63 + 1 + 63 + 1 + 63 + 1 + 61 + 1 = 255 * * When printed, this is (3 * 63 + 61) * 4 * bytes for the escaped label data + 4 bytes for the * dot terminating each label = 1004 bytes total. */ isc_result_t dns_name_tofilenametext(dns_name_t *name, isc_boolean_t omit_final_dot, isc_buffer_t *target); /*%< * Convert 'name' into an alternate text format appropriate for filenames, * storing the result in 'target'. The name data is downcased, guaranteeing * that the filename does not depend on the case of the converted name. * * Notes: *\li If 'omit_final_dot' is true, then the final '.' in absolute * names other than the root name will be omitted. * *\li The name is not NUL terminated. * * Requires: * *\li 'name' is a valid absolute name * *\li 'target' is a valid buffer. * * Ensures: * *\li If the result is success: * the used space in target is updated. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOSPACE */ isc_result_t dns_name_downcase(dns_name_t *source, dns_name_t *name, isc_buffer_t *target); /*%< * Downcase 'source'. * * Requires: * *\li 'source' and 'name' are valid names. * *\li If source == name, then * 'source' must not be read-only * *\li Otherwise, * 'target' is a valid buffer or 'target' is NULL and * 'name' has a dedicated buffer. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOSPACE * * Note: if source == name, then the result will always be ISC_R_SUCCESS. */ isc_result_t dns_name_concatenate(dns_name_t *prefix, dns_name_t *suffix, dns_name_t *name, isc_buffer_t *target); /*%< * Concatenate 'prefix' and 'suffix'. * * Requires: * *\li 'prefix' is a valid name or NULL. * *\li 'suffix' is a valid name or NULL. * *\li 'name' is a valid name or NULL. * *\li 'target' is a valid buffer or 'target' is NULL and 'name' has * a dedicated buffer. * *\li If 'prefix' is absolute, 'suffix' must be NULL or the empty name. * * Ensures: * *\li On success, * If 'target' is not NULL and 'name' is not NULL, then 'name' * is attached to it. * The used space in target is updated. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOSPACE *\li #DNS_R_NAMETOOLONG */ void dns_name_split(dns_name_t *name, unsigned int suffixlabels, dns_name_t *prefix, dns_name_t *suffix); /*%< * * Split 'name' into two pieces on a label boundary. * * Notes: * \li 'name' is split such that 'suffix' holds the most significant * 'suffixlabels' labels. All other labels are stored in 'prefix'. * *\li Copying name data is avoided as much as possible, so 'prefix' * and 'suffix' will end up pointing at the data for 'name'. * *\li It is legitimate to pass a 'prefix' or 'suffix' that has * its name data stored someplace other than the dedicated buffer. * This is useful to avoid name copying in the calling function. * *\li It is also legitimate to pass a 'prefix' or 'suffix' that is * the same dns_name_t as 'name'. * * Requires: *\li 'name' is a valid name. * *\li 'suffixlabels' cannot exceed the number of labels in 'name'. * * \li 'prefix' is a valid name or NULL, and cannot be read-only. * *\li 'suffix' is a valid name or NULL, and cannot be read-only. * * Ensures: * *\li On success: * If 'prefix' is not NULL it will contain the least significant * labels. * If 'suffix' is not NULL it will contain the most significant * labels. dns_name_countlabels(suffix) will be equal to * suffixlabels. * *\li On failure: * Either 'prefix' or 'suffix' is invalidated (depending * on which one the problem was encountered with). * * Returns: *\li #ISC_R_SUCCESS No worries. (This function should always success). */ isc_result_t dns_name_dup(const dns_name_t *source, isc_mem_t *mctx, dns_name_t *target); /*%< * Make 'target' a dynamically allocated copy of 'source'. * * Requires: * *\li 'source' is a valid non-empty name. * *\li 'target' is a valid name that is not read-only. * *\li 'mctx' is a valid memory context. */ isc_result_t dns_name_dupwithoffsets(dns_name_t *source, isc_mem_t *mctx, dns_name_t *target); /*%< * Make 'target' a read-only dynamically allocated copy of 'source'. * 'target' will also have a dynamically allocated offsets table. * * Requires: * *\li 'source' is a valid non-empty name. * *\li 'target' is a valid name that is not read-only. * *\li 'target' has no offsets table. * *\li 'mctx' is a valid memory context. */ void dns_name_free(dns_name_t *name, isc_mem_t *mctx); /*%< * Free 'name'. * * Requires: * *\li 'name' is a valid name created previously in 'mctx' by dns_name_dup(). * *\li 'mctx' is a valid memory context. * * Ensures: * *\li All dynamic resources used by 'name' are freed and the name is * invalidated. */ isc_result_t dns_name_digest(dns_name_t *name, dns_digestfunc_t digest, void *arg); /*%< * Send 'name' in DNSSEC canonical form to 'digest'. * * Requires: * *\li 'name' is a valid name. * *\li 'digest' is a valid dns_digestfunc_t. * * Ensures: * *\li If successful, the DNSSEC canonical form of 'name' will have been * sent to 'digest'. * *\li If digest() returns something other than ISC_R_SUCCESS, that result * will be returned as the result of dns_name_digest(). * * Returns: * *\li #ISC_R_SUCCESS * *\li Many other results are possible if not successful. * */ isc_boolean_t dns_name_dynamic(dns_name_t *name); /*%< * Returns whether there is dynamic memory associated with this name. * * Requires: * *\li 'name' is a valid name. * * Returns: * *\li 'ISC_TRUE' if the name is dynamic otherwise 'ISC_FALSE'. */ isc_result_t dns_name_print(dns_name_t *name, FILE *stream); /*%< * Print 'name' on 'stream'. * * Requires: * *\li 'name' is a valid name. * *\li 'stream' is a valid stream. * * Returns: * *\li #ISC_R_SUCCESS * *\li Any error that dns_name_totext() can return. */ void dns_name_format(dns_name_t *name, char *cp, unsigned int size); /*%< * Format 'name' as text appropriate for use in log messages. * * Store the formatted name at 'cp', writing no more than * 'size' bytes. The resulting string is guaranteed to be * null terminated. * * The formatted name will have a terminating dot only if it is * the root. * * This function cannot fail, instead any errors are indicated * in the returned text. * * Requires: * *\li 'name' is a valid name. * *\li 'cp' points a valid character array of size 'size'. * *\li 'size' > 0. * */ isc_result_t dns_name_tostring(dns_name_t *source, char **target, isc_mem_t *mctx); /*%< * Convert 'name' to string format, allocating sufficient memory to * hold it (free with isc_mem_free()). * * Differs from dns_name_format in that it allocates its own memory. * * Requires: * *\li 'name' is a valid name. *\li 'target' is not NULL. *\li '*target' is NULL. * * Returns: * *\li ISC_R_SUCCESS *\li ISC_R_NOMEMORY * *\li Any error that dns_name_totext() can return. */ isc_result_t dns_name_fromstring(dns_name_t *target, const char *src, unsigned int options, isc_mem_t *mctx); isc_result_t dns_name_fromstring2(dns_name_t *target, const char *src, const dns_name_t *origin, unsigned int options, isc_mem_t *mctx); /*%< * Convert a string to a name and place it in target, allocating memory * as necessary. 'options' has the same semantics as that of * dns_name_fromtext(). * * If 'target' has a buffer then the name will be copied into it rather than * memory being allocated. * * Requires: * * \li 'target' is a valid name that is not read-only. * \li 'src' is not NULL. * * Returns: * *\li #ISC_R_SUCCESS * *\li Any error that dns_name_fromtext() can return. * *\li Any error that dns_name_dup() can return. */ isc_result_t dns_name_settotextfilter(dns_name_totextfilter_t proc); /*%< * Set / clear a thread specific function 'proc' to be called at the * end of dns_name_totext(). * * Note: Under Windows you need to call "dns_name_settotextfilter(NULL);" * prior to exiting the thread otherwise memory will be leaked. * For other platforms, which are pthreads based, this is still a good * idea but not required. * * Returns *\li #ISC_R_SUCCESS *\li #ISC_R_UNEXPECTED */ #define DNS_NAME_FORMATSIZE (DNS_NAME_MAXTEXT + 1) /*%< * Suggested size of buffer passed to dns_name_format(). * Includes space for the terminating NULL. */ isc_result_t dns_name_copy(dns_name_t *source, dns_name_t *dest, isc_buffer_t *target); /*%< * Makes 'dest' refer to a copy of the name in 'source'. The data are * either copied to 'target' or the dedicated buffer in 'dest'. * * Requires: * \li 'source' is a valid name. * * \li 'dest' is an initialized name with a dedicated buffer. * * \li 'target' is NULL or an initialized buffer. * * \li Either dest has a dedicated buffer or target != NULL. * * Ensures: * *\li On success, the used space in target is updated. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOSPACE */ isc_boolean_t dns_name_ishostname(const dns_name_t *name, isc_boolean_t wildcard); /*%< * Return if 'name' is a valid hostname. RFC 952 / RFC 1123. * If 'wildcard' is ISC_TRUE then allow the first label of name to * be a wildcard. * The root is also accepted. * * Requires: * 'name' to be valid. */ isc_boolean_t dns_name_ismailbox(const dns_name_t *name); /*%< * Return if 'name' is a valid mailbox. RFC 821. * * Requires: * \li 'name' to be valid. */ isc_boolean_t dns_name_internalwildcard(const dns_name_t *name); /*%< * Return if 'name' contains a internal wildcard name. * * Requires: * \li 'name' to be valid. */ void dns_name_destroy(void); /*%< * Cleanup dns_name_settotextfilter() / dns_name_totext() state. * * This should be called as part of the final cleanup process. * * Note: dns_name_settotextfilter(NULL); should be called for all * threads which have called dns_name_settotextfilter() with a * non-NULL argument prior to calling dns_name_destroy(); */ isc_boolean_t dns_name_isdnssd(const dns_name_t *owner); /*%< * Determine if the 'owner' is a DNS-SD prefix. */ ISC_LANG_ENDDECLS /* *** High Performance Macros ***/ /* * WARNING: Use of these macros by applications may require recompilation * of the application in some situations where calling the function * would not. * * WARNING: No assertion checking is done for these macros. */ #define DNS_NAME_INIT(n, o) \ do { \ dns_name_t *_n = (n); \ /* memset(_n, 0, sizeof(*_n)); */ \ _n->magic = DNS_NAME_MAGIC; \ _n->ndata = NULL; \ _n->length = 0; \ _n->labels = 0; \ _n->attributes = 0; \ _n->offsets = (o); \ _n->buffer = NULL; \ ISC_LINK_INIT(_n, link); \ ISC_LIST_INIT(_n->list); \ } while (0) #define DNS_NAME_RESET(n) \ do { \ (n)->ndata = NULL; \ (n)->length = 0; \ (n)->labels = 0; \ (n)->attributes &= ~DNS_NAMEATTR_ABSOLUTE; \ if ((n)->buffer != NULL) \ isc_buffer_clear((n)->buffer); \ } while (0) #define DNS_NAME_SETBUFFER(n, b) \ (n)->buffer = (b) #define DNS_NAME_ISABSOLUTE(n) \ (((n)->attributes & DNS_NAMEATTR_ABSOLUTE) != 0 ? ISC_TRUE : ISC_FALSE) #define DNS_NAME_COUNTLABELS(n) \ ((n)->labels) #define DNS_NAME_TOREGION(n, r) \ do { \ (r)->base = (n)->ndata; \ (r)->length = (n)->length; \ } while (0) #define DNS_NAME_SPLIT(n, l, p, s) \ do { \ dns_name_t *_n = (n); \ dns_name_t *_p = (p); \ dns_name_t *_s = (s); \ unsigned int _l = (l); \ if (_p != NULL) \ dns_name_getlabelsequence(_n, 0, _n->labels - _l, _p); \ if (_s != NULL) \ dns_name_getlabelsequence(_n, _n->labels - _l, _l, _s); \ } while (0) #ifdef DNS_NAME_USEINLINE #define dns_name_init(n, o) DNS_NAME_INIT(n, o) #define dns_name_reset(n) DNS_NAME_RESET(n) #define dns_name_setbuffer(n, b) DNS_NAME_SETBUFFER(n, b) #define dns_name_countlabels(n) DNS_NAME_COUNTLABELS(n) #define dns_name_isabsolute(n) DNS_NAME_ISABSOLUTE(n) #define dns_name_toregion(n, r) DNS_NAME_TOREGION(n, r) #define dns_name_split(n, l, p, s) DNS_NAME_SPLIT(n, l, p, s) #endif /* DNS_NAME_USEINLINE */ #endif /* DNS_NAME_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/log.h0000644000470500017500000001022312664710322020062 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file dns/log.h * \author Principal Authors: DCL */ #ifndef DNS_LOG_H #define DNS_LOG_H 1 #include #include LIBDNS_EXTERNAL_DATA extern isc_log_t *dns_lctx; LIBDNS_EXTERNAL_DATA extern isc_logcategory_t dns_categories[]; LIBDNS_EXTERNAL_DATA extern isc_logmodule_t dns_modules[]; #define DNS_LOGCATEGORY_NOTIFY (&dns_categories[0]) #define DNS_LOGCATEGORY_DATABASE (&dns_categories[1]) #define DNS_LOGCATEGORY_SECURITY (&dns_categories[2]) /* DNS_LOGCATEGORY_CONFIG superseded by CFG_LOGCATEGORY_CONFIG */ #define DNS_LOGCATEGORY_DNSSEC (&dns_categories[4]) #define DNS_LOGCATEGORY_RESOLVER (&dns_categories[5]) #define DNS_LOGCATEGORY_XFER_IN (&dns_categories[6]) #define DNS_LOGCATEGORY_XFER_OUT (&dns_categories[7]) #define DNS_LOGCATEGORY_DISPATCH (&dns_categories[8]) #define DNS_LOGCATEGORY_LAME_SERVERS (&dns_categories[9]) #define DNS_LOGCATEGORY_DELEGATION_ONLY (&dns_categories[10]) #define DNS_LOGCATEGORY_EDNS_DISABLED (&dns_categories[11]) #define DNS_LOGCATEGORY_RPZ (&dns_categories[12]) #define DNS_LOGCATEGORY_RRL (&dns_categories[13]) #define DNS_LOGCATEGORY_CNAME (&dns_categories[14]) #define DNS_LOGCATEGORY_SPILL (&dns_categories[15]) /* Backwards compatibility. */ #define DNS_LOGCATEGORY_GENERAL ISC_LOGCATEGORY_GENERAL #define DNS_LOGMODULE_DB (&dns_modules[0]) #define DNS_LOGMODULE_RBTDB (&dns_modules[1]) #define DNS_LOGMODULE_RBTDB64 (&dns_modules[2]) #define DNS_LOGMODULE_RBT (&dns_modules[3]) #define DNS_LOGMODULE_RDATA (&dns_modules[4]) #define DNS_LOGMODULE_MASTER (&dns_modules[5]) #define DNS_LOGMODULE_MESSAGE (&dns_modules[6]) #define DNS_LOGMODULE_CACHE (&dns_modules[7]) #define DNS_LOGMODULE_CONFIG (&dns_modules[8]) #define DNS_LOGMODULE_RESOLVER (&dns_modules[9]) #define DNS_LOGMODULE_ZONE (&dns_modules[10]) #define DNS_LOGMODULE_JOURNAL (&dns_modules[11]) #define DNS_LOGMODULE_ADB (&dns_modules[12]) #define DNS_LOGMODULE_XFER_IN (&dns_modules[13]) #define DNS_LOGMODULE_XFER_OUT (&dns_modules[14]) #define DNS_LOGMODULE_ACL (&dns_modules[15]) #define DNS_LOGMODULE_VALIDATOR (&dns_modules[16]) #define DNS_LOGMODULE_DISPATCH (&dns_modules[17]) #define DNS_LOGMODULE_REQUEST (&dns_modules[18]) #define DNS_LOGMODULE_MASTERDUMP (&dns_modules[19]) #define DNS_LOGMODULE_TSIG (&dns_modules[20]) #define DNS_LOGMODULE_TKEY (&dns_modules[21]) #define DNS_LOGMODULE_SDB (&dns_modules[22]) #define DNS_LOGMODULE_DIFF (&dns_modules[23]) #define DNS_LOGMODULE_HINTS (&dns_modules[24]) #define DNS_LOGMODULE_ACACHE (&dns_modules[25]) #define DNS_LOGMODULE_DLZ (&dns_modules[26]) #define DNS_LOGMODULE_DNSSEC (&dns_modules[27]) #define DNS_LOGMODULE_CRYPTO (&dns_modules[28]) #define DNS_LOGMODULE_PACKETS (&dns_modules[29]) ISC_LANG_BEGINDECLS void dns_log_init(isc_log_t *lctx); /*% * Make the libdns categories and modules available for use with the * ISC logging library. * * Requires: *\li lctx is a valid logging context. * *\li dns_log_init() is called only once. * * Ensures: * \li The categories and modules defined above are available for * use by isc_log_usechannnel() and isc_log_write(). */ void dns_log_setcontext(isc_log_t *lctx); /*% * Make the libdns library use the provided context for logging internal * messages. * * Requires: *\li lctx is a valid logging context. */ ISC_LANG_ENDDECLS #endif /* DNS_LOG_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/dbtable.h0000644000470500017500000000715312664710322020706 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: dbtable.h,v 1.23 2007/06/19 23:47:16 tbox Exp $ */ #ifndef DNS_DBTABLE_H #define DNS_DBTABLE_H 1 /***** ***** Module Info *****/ /*! \file dns/dbtable.h * \brief * DNS DB Tables * * XXX TBS XXX * * MP: *\li The module ensures appropriate synchronization of data structures it * creates and manipulates. * * Reliability: *\li No anticipated impact. * * Resources: *\li None. * * Security: *\li No anticipated impact. * * Standards: *\li None. */ #include #include #define DNS_DBTABLEFIND_NOEXACT 0x01 ISC_LANG_BEGINDECLS isc_result_t dns_dbtable_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_dbtable_t **dbtablep); /*%< * Make a new dbtable of class 'rdclass' * * Requires: *\li mctx != NULL * \li dbtablep != NULL && *dptablep == NULL *\li 'rdclass' is a valid class * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li #ISC_R_UNEXPECTED */ void dns_dbtable_attach(dns_dbtable_t *source, dns_dbtable_t **targetp); /*%< * Attach '*targetp' to 'source'. * * Requires: * *\li 'source' is a valid dbtable. * *\li 'targetp' points to a NULL dns_dbtable_t *. * * Ensures: * *\li *targetp is attached to source. */ void dns_dbtable_detach(dns_dbtable_t **dbtablep); /*%< * Detach *dbtablep from its dbtable. * * Requires: * *\li '*dbtablep' points to a valid dbtable. * * Ensures: * *\li *dbtablep is NULL. * *\li If '*dbtablep' is the last reference to the dbtable, * all resources used by the dbtable will be freed */ isc_result_t dns_dbtable_add(dns_dbtable_t *dbtable, dns_db_t *db); /*%< * Add 'db' to 'dbtable'. * * Requires: *\li 'dbtable' is a valid dbtable. * *\li 'db' is a valid database with the same class as 'dbtable' */ void dns_dbtable_remove(dns_dbtable_t *dbtable, dns_db_t *db); /*%< * Remove 'db' from 'dbtable'. * * Requires: *\li 'db' was previously added to 'dbtable'. */ void dns_dbtable_adddefault(dns_dbtable_t *dbtable, dns_db_t *db); /*%< * Use 'db' as the result of a dns_dbtable_find() if no better match is * available. */ void dns_dbtable_getdefault(dns_dbtable_t *dbtable, dns_db_t **db); /*%< * Get the 'db' used as the result of a dns_dbtable_find() * if no better match is available. */ void dns_dbtable_removedefault(dns_dbtable_t *dbtable); /*%< * Remove the default db from 'dbtable'. */ isc_result_t dns_dbtable_find(dns_dbtable_t *dbtable, dns_name_t *name, unsigned int options, dns_db_t **dbp); /*%< * Find the deepest match to 'name' in the dbtable, and return it * * Notes: *\li If the DNS_DBTABLEFIND_NOEXACT option is set, the best partial * match (if any) to 'name' will be returned. * * Returns: * \li #ISC_R_SUCCESS on success *\li something else: no default and match */ ISC_LANG_ENDDECLS #endif /* DNS_DBTABLE_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/rbt.h0000644000470500017500000011460012664710322020074 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2012-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rbt.h,v 1.77.666.4 2012/02/08 19:53:30 each Exp $ */ #ifndef DNS_RBT_H #define DNS_RBT_H 1 /*! \file dns/rbt.h */ #include #include #include #include #include ISC_LANG_BEGINDECLS #define DNS_RBT_USEHASH 1 /*@{*/ /*% * Option values for dns_rbt_findnode() and dns_rbt_findname(). * These are used to form a bitmask. */ #define DNS_RBTFIND_NOOPTIONS 0x00 #define DNS_RBTFIND_EMPTYDATA 0x01 #define DNS_RBTFIND_NOEXACT 0x02 #define DNS_RBTFIND_NOPREDECESSOR 0x04 /*@}*/ #ifndef DNS_RBT_USEISCREFCOUNT #ifdef ISC_REFCOUNT_HAVEATOMIC #define DNS_RBT_USEISCREFCOUNT 1 #endif #endif #define DNS_RBT_USEMAGIC 1 /* * These should add up to 30. */ #define DNS_RBT_LOCKLENGTH 10 #define DNS_RBT_REFLENGTH 20 #define DNS_RBTNODE_MAGIC ISC_MAGIC('R','B','N','O') #if DNS_RBT_USEMAGIC #define DNS_RBTNODE_VALID(n) ISC_MAGIC_VALID(n, DNS_RBTNODE_MAGIC) #else #define DNS_RBTNODE_VALID(n) ISC_TRUE #endif /*% * This is the structure that is used for each node in the red/black * tree of trees. NOTE WELL: the implementation manages this as a variable * length structure, with the actual wire-format name and other data * appended to this structure. Allocating a contiguous block of memory for * multiple dns_rbtnode structures will not work. */ typedef struct dns_rbtnode dns_rbtnode_t; enum { DNS_RBT_NSEC_NORMAL=0, /* in main tree */ DNS_RBT_NSEC_HAS_NSEC=1, /* also has node in nsec tree */ DNS_RBT_NSEC_NSEC=2, /* in nsec tree */ DNS_RBT_NSEC_NSEC3=3 /* in nsec3 tree */ }; struct dns_rbtnode { #if DNS_RBT_USEMAGIC unsigned int magic; #endif dns_rbtnode_t *parent; dns_rbtnode_t *left; dns_rbtnode_t *right; dns_rbtnode_t *down; #ifdef DNS_RBT_USEHASH dns_rbtnode_t *hashnext; #endif /*% * Used for LRU cache. This linked list is used to mark nodes which * have no data any longer, but we cannot unlink at that exact moment * because we did not or could not obtain a write lock on the tree. */ ISC_LINK(dns_rbtnode_t) deadlink; /*@{*/ /*! * The following bitfields add up to a total bitwidth of 32. * The range of values necessary for each item is indicated, * but in the case of "attributes" the field is wider to accommodate * possible future expansion. * * In each case below the "range" indicated is what's _necessary_ for * the bitfield to hold, not what it actually _can_ hold. */ unsigned int is_root : 1; /*%< range is 0..1 */ unsigned int color : 1; /*%< range is 0..1 */ unsigned int find_callback : 1; /*%< range is 0..1 */ unsigned int attributes : 3; /*%< range is 0..2 */ unsigned int nsec : 2; /*%< range is 0..3 */ unsigned int namelen : 8; /*%< range is 1..255 */ unsigned int offsetlen : 8; /*%< range is 1..128 */ unsigned int oldnamelen : 8; /*%< range is 1..255 */ /*@}*/ /* flags needed for serialization to file*/ unsigned int is_mmapped : 1; unsigned int parent_is_relative : 1; unsigned int left_is_relative : 1; unsigned int right_is_relative : 1; unsigned int down_is_relative : 1; unsigned int data_is_relative : 1; /* node needs to be cleaned from rpz */ unsigned int rpz : 1; #ifdef DNS_RBT_USEHASH unsigned int hashval; #endif /*@{*/ /*! * These values are used in the RBT DB implementation. The appropriate * node lock must be held before accessing them. */ void *data; unsigned int dirty:1; unsigned int wild:1; unsigned int locknum:DNS_RBT_LOCKLENGTH; #ifndef DNS_RBT_USEISCREFCOUNT unsigned int references:DNS_RBT_REFLENGTH; #else isc_refcount_t references; /* note that this is not in the bitfield */ #endif /*@}*/ }; typedef isc_result_t (*dns_rbtfindcallback_t)(dns_rbtnode_t *node, dns_name_t *name, void *callback_arg); typedef isc_result_t (*dns_rbtdatawriter_t)(FILE *file, unsigned char *data, void *arg, isc_uint64_t *crc); typedef isc_result_t (*dns_rbtdatafixer_t)(dns_rbtnode_t *rbtnode, void *base, size_t offset, void *arg, isc_uint64_t *crc); typedef void (*dns_rbtdeleter_t)(void *, void *); /***** ***** Chain Info *****/ /*! * A chain is used to keep track of the sequence of nodes to reach any given * node from the root of the tree. Originally nodes did not have parent * pointers in them (for memory usage reasons) so there was no way to find * the path back to the root from any given node. Now that nodes have parent * pointers, chains might be going away in a future release, though the * movement functionality would remain. * * In any event, parent information, whether via parent pointers or chains, is * necessary information for iterating through the tree or for basic internal * tree maintenance issues (ie, the rotations that are done to rebalance the * tree when a node is added). The obvious implication of this is that for a * chain to remain valid, the tree has to be locked down against writes for the * duration of the useful life of the chain, because additions or removals can * change the path from the root to the node the chain has targeted. * * The dns_rbtnodechain_ functions _first, _last, _prev and _next all take * dns_name_t parameters for the name and the origin, which can be NULL. If * non-NULL, 'name' will end up pointing to the name data and offsets that are * stored at the node (and thus it will be read-only), so it should be a * regular dns_name_t that has been initialized with dns_name_init. When * 'origin' is non-NULL, it will get the name of the origin stored in it, so it * needs to have its own buffer space and offsets, which is most easily * accomplished with a dns_fixedname_t. It is _not_ necessary to reinitialize * either 'name' or 'origin' between calls to the chain functions. * * NOTE WELL: even though the name data at the root of the tree of trees will * be absolute (typically just "."), it will will be made into a relative name * with an origin of "." -- an empty name when the node is ".". This is * because a common on operation on 'name' and 'origin' is to use * dns_name_concatenate() on them to generate the complete name. An empty name * can be detected when dns_name_countlabels == 0, and is printed by * dns_name_totext()/dns_name_format() as "@", consistent with RFC1035's * definition of "@" as the current origin. * * dns_rbtnodechain_current is similar to the _first, _last, _prev and _next * functions but additionally can provide the node to which the chain points. */ /*% * The number of level blocks to allocate at a time. Currently the maximum * number of levels is allocated directly in the structure, but future * revisions of this code might have a static initial block with dynamic * growth. Allocating space for 256 levels when the tree is almost never that * deep is wasteful, but it's not clear that it matters, since the waste is * only 2MB for 1000 concurrently active chains on a system with 64-bit * pointers. */ #define DNS_RBT_LEVELBLOCK 254 typedef struct dns_rbtnodechain { unsigned int magic; isc_mem_t * mctx; /*% * The terminal node of the chain. It is not in levels[]. * This is ostensibly private ... but in a pinch it could be * used tell that the chain points nowhere without needing to * call dns_rbtnodechain_current(). */ dns_rbtnode_t * end; /*% * The maximum number of labels in a name is 128; bitstrings mean * a conceptually very large number (which I have not bothered to * compute) of logical levels because splitting can potentially occur * at each bit. However, DNSSEC restricts the number of "logical" * labels in a name to 255, meaning only 254 pointers are needed * in the worst case. */ dns_rbtnode_t * levels[DNS_RBT_LEVELBLOCK]; /*% * level_count indicates how deep the chain points into the * tree of trees, and is the index into the levels[] array. * Thus, levels[level_count - 1] is the last level node stored. * A chain that points to the top level of the tree of trees has * a level_count of 0, the first level has a level_count of 1, and * so on. */ unsigned int level_count; /*% * level_matches tells how many levels matched above the node * returned by dns_rbt_findnode(). A match (partial or exact) found * in the first level thus results in level_matches being set to 1. * This is used by the rbtdb to set the start point for a recursive * search of superdomains until the RR it is looking for is found. */ unsigned int level_matches; } dns_rbtnodechain_t; /***** ***** Public interfaces. *****/ isc_result_t dns_rbt_create(isc_mem_t *mctx, dns_rbtdeleter_t deleter, void *deleter_arg, dns_rbt_t **rbtp); /*%< * Initialize a red-black tree of trees. * * Notes: *\li The deleter argument, if non-null, points to a function that is * responsible for cleaning up any memory associated with the data * pointer of a node when the node is deleted. It is passed the * deleted node's data pointer as its first argument and deleter_arg * as its second argument. * * Requires: * \li mctx is a pointer to a valid memory context. *\li rbtp != NULL && *rbtp == NULL *\li arg == NULL iff deleter == NULL * * Ensures: *\li If result is ISC_R_SUCCESS: * *rbtp points to a valid red-black tree manager * *\li If result is failure: * *rbtp does not point to a valid red-black tree manager. * * Returns: *\li #ISC_R_SUCCESS Success *\li #ISC_R_NOMEMORY Resource limit: Out of Memory */ isc_result_t dns_rbt_addname(dns_rbt_t *rbt, dns_name_t *name, void *data); /*%< * Add 'name' to the tree of trees, associated with 'data'. * * Notes: *\li 'data' is never required to be non-NULL, but specifying it * when the name is added is faster than searching for 'name' * again and then setting the data pointer. The lack of a data pointer * for a node also has other ramifications regarding whether * dns_rbt_findname considers a node to exist, or dns_rbt_deletename * joins nodes. * * Requires: *\li rbt is a valid rbt manager. *\li dns_name_isabsolute(name) == TRUE * * Ensures: *\li 'name' is not altered in any way. * *\li Any external references to nodes in the tree are unaffected by * node splits that are necessary to insert the new name. * *\li If result is #ISC_R_SUCCESS: * 'name' is findable in the red/black tree of trees in O(log N). * The data pointer of the node for 'name' is set to 'data'. * *\li If result is #ISC_R_EXISTS or #ISC_R_NOSPACE: * The tree of trees is unaltered. * *\li If result is #ISC_R_NOMEMORY: * No guarantees. * * Returns: *\li #ISC_R_SUCCESS Success *\li #ISC_R_EXISTS The name already exists with associated data. *\li #ISC_R_NOSPACE The name had more logical labels than are allowed. *\li #ISC_R_NOMEMORY Resource Limit: Out of Memory */ isc_result_t dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep); /*%< * Just like dns_rbt_addname, but returns the address of the node. * * Requires: *\li rbt is a valid rbt structure. *\li dns_name_isabsolute(name) == TRUE *\li nodep != NULL && *nodep == NULL * * Ensures: *\li 'name' is not altered in any way. * *\li Any external references to nodes in the tree are unaffected by * node splits that are necessary to insert the new name. * *\li If result is ISC_R_SUCCESS: * 'name' is findable in the red/black tree of trees in O(log N). * *nodep is the node that was added for 'name'. * *\li If result is ISC_R_EXISTS: * The tree of trees is unaltered. * *nodep is the existing node for 'name'. * *\li If result is ISC_R_NOMEMORY: * No guarantees. * * Returns: *\li #ISC_R_SUCCESS Success *\li #ISC_R_EXISTS The name already exists, possibly without data. *\li #ISC_R_NOMEMORY Resource Limit: Out of Memory */ isc_result_t dns_rbt_findname(dns_rbt_t *rbt, dns_name_t *name, unsigned int options, dns_name_t *foundname, void **data); /*%< * Get the data pointer associated with 'name'. * * Notes: *\li When #DNS_RBTFIND_NOEXACT is set, the closest matching superdomain is * returned (also subject to #DNS_RBTFIND_EMPTYDATA), even when there is * an exact match in the tree. * *\li A node that has no data is considered not to exist for this function, * unless the #DNS_RBTFIND_EMPTYDATA option is set. * * Requires: *\li rbt is a valid rbt manager. *\li dns_name_isabsolute(name) == TRUE *\li data != NULL && *data == NULL * * Ensures: *\li 'name' and the tree are not altered in any way. * *\li If result is ISC_R_SUCCESS: * *data is the data associated with 'name'. * *\li If result is DNS_R_PARTIALMATCH: * *data is the data associated with the deepest superdomain * of 'name' which has data. * *\li If result is ISC_R_NOTFOUND: * Neither the name nor a superdomain was found with data. * * Returns: *\li #ISC_R_SUCCESS Success *\li #DNS_R_PARTIALMATCH Superdomain found with data *\li #ISC_R_NOTFOUND No match *\li #ISC_R_NOSPACE Concatenating nodes to form foundname failed */ isc_result_t dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname, dns_rbtnode_t **node, dns_rbtnodechain_t *chain, unsigned int options, dns_rbtfindcallback_t callback, void *callback_arg); /*%< * Find the node for 'name'. * * Notes: *\li A node that has no data is considered not to exist for this function, * unless the DNS_RBTFIND_EMPTYDATA option is set. This applies to both * exact matches and partial matches. * *\li If the chain parameter is non-NULL, then the path through the tree * to the DNSSEC predecessor of the searched for name is maintained, * unless the DNS_RBTFIND_NOPREDECESSOR or DNS_RBTFIND_NOEXACT option * is used. (For more details on those options, see below.) * *\li If there is no predecessor, then the chain will point to nowhere, as * indicated by chain->end being NULL or dns_rbtnodechain_current * returning ISC_R_NOTFOUND. Note that in a normal Internet DNS RBT * there will always be a predecessor for all names except the root * name, because '.' will exist and '.' is the predecessor of * everything. But you can certainly construct a trivial tree and a * search for it that has no predecessor. * *\li Within the chain structure, the 'levels' member of the structure holds * the root node of each level except the first. * *\li The 'level_count' of the chain indicates how deep the chain to the * predecessor name is, as an index into the 'levels[]' array. It does * not count name elements, per se, but only levels of the tree of trees, * the distinction arising because multiple labels from a name can be * stored on only one level. It is also does not include the level * that has the node, since that level is not stored in levels[]. * *\li The chain's 'level_matches' is not directly related to the predecessor. * It is the number of levels above the level of the found 'node', * regardless of whether it was a partial match or exact match. When * the node is found in the top level tree, or no node is found at all, * level_matches is 0. * *\li When DNS_RBTFIND_NOEXACT is set, the closest matching superdomain is * returned (also subject to DNS_RBTFIND_EMPTYDATA), even when * there is an exact match in the tree. In this case, the chain * will not point to the DNSSEC predecessor, but will instead point * to the exact match, if there was any. Thus the preceding paragraphs * should have "exact match" substituted for "predecessor" to describe * how the various elements of the chain are set. This was done to * ensure that the chain's state was sane, and to prevent problems that * occurred when running the predecessor location code under conditions * it was not designed for. It is not clear *where* the chain should * point when DNS_RBTFIND_NOEXACT is set, so if you end up using a chain * with this option because you want a particular node, let us know * where you want the chain pointed, so this can be made more firm. * * Requires: *\li rbt is a valid rbt manager. *\li dns_name_isabsolute(name) == TRUE. *\li node != NULL && *node == NULL. *\li #DNS_RBTFIND_NOEXACT and DNS_RBTFIND_NOPREDECESSOR are mutually * exclusive. * * Ensures: *\li 'name' and the tree are not altered in any way. * *\li If result is ISC_R_SUCCESS: *\verbatim * *node is the terminal node for 'name'. * 'foundname' and 'name' represent the same name (though not * the same memory). * 'chain' points to the DNSSEC predecessor, if any, of 'name'. * * chain->level_matches and chain->level_count are equal. *\endverbatim * * If result is DNS_R_PARTIALMATCH: *\verbatim * *node is the data associated with the deepest superdomain * of 'name' which has data. * * 'foundname' is the name of deepest superdomain (which has * data, unless the DNS_RBTFIND_EMPTYDATA option is set). * * 'chain' points to the DNSSEC predecessor, if any, of 'name'. *\endverbatim * *\li If result is ISC_R_NOTFOUND: *\verbatim * Neither the name nor a superdomain was found. *node is NULL. * * 'chain' points to the DNSSEC predecessor, if any, of 'name'. * * chain->level_matches is 0. *\endverbatim * * Returns: *\li #ISC_R_SUCCESS Success *\li #DNS_R_PARTIALMATCH Superdomain found with data *\li #ISC_R_NOTFOUND No match, or superdomain with no data *\li #ISC_R_NOSPACE Concatenating nodes to form foundname failed */ isc_result_t dns_rbt_deletename(dns_rbt_t *rbt, dns_name_t *name, isc_boolean_t recurse); /*%< * Delete 'name' from the tree of trees. * * Notes: *\li When 'name' is removed, if recurse is ISC_TRUE then all of its * subnames are removed too. * * Requires: *\li rbt is a valid rbt manager. *\li dns_name_isabsolute(name) == TRUE * * Ensures: *\li 'name' is not altered in any way. * *\li Does NOT ensure that any external references to nodes in the tree * are unaffected by node joins. * *\li If result is ISC_R_SUCCESS: * 'name' does not appear in the tree with data; however, * the node for the name might still exist which can be * found with dns_rbt_findnode (but not dns_rbt_findname). * *\li If result is ISC_R_NOTFOUND: * 'name' does not appear in the tree with data, because * it did not appear in the tree before the function was called. * *\li If result is something else: * See result codes for dns_rbt_findnode (if it fails, the * node is not deleted) or dns_rbt_deletenode (if it fails, * the node is deleted, but the tree is not optimized when * it could have been). * * Returns: *\li #ISC_R_SUCCESS Success *\li #ISC_R_NOTFOUND No match *\li something_else Any return code from dns_rbt_findnode except * DNS_R_PARTIALMATCH (which causes ISC_R_NOTFOUND * to be returned instead), and any code from * dns_rbt_deletenode. */ isc_result_t dns_rbt_deletenode(dns_rbt_t *rbt, dns_rbtnode_t *node, isc_boolean_t recurse); /*%< * Delete 'node' from the tree of trees. * * Notes: *\li When 'node' is removed, if recurse is ISC_TRUE then all nodes * in levels down from it are removed too. * * Requires: *\li rbt is a valid rbt manager. *\li node != NULL. * * Ensures: *\li Does NOT ensure that any external references to nodes in the tree * are unaffected by node joins. * *\li If result is ISC_R_SUCCESS: * 'node' does not appear in the tree with data; however, * the node might still exist if it serves as a pointer to * a lower tree level as long as 'recurse' was false, hence * the node could can be found with dns_rbt_findnode when * that function's empty_data_ok parameter is true. * *\li If result is ISC_R_NOMEMORY or ISC_R_NOSPACE: * The node was deleted, but the tree structure was not * optimized. * * Returns: *\li #ISC_R_SUCCESS Success *\li #ISC_R_NOMEMORY Resource Limit: Out of Memory when joining nodes. *\li #ISC_R_NOSPACE dns_name_concatenate failed when joining nodes. */ void dns_rbt_namefromnode(dns_rbtnode_t *node, dns_name_t *name); /*%< * Convert the sequence of labels stored at 'node' into a 'name'. * * Notes: *\li This function does not return the full name, from the root, but * just the labels at the indicated node. * *\li The name data pointed to by 'name' is the information stored * in the node, not a copy. Altering the data at this pointer * will likely cause grief. * * Requires: * \li name->offsets == NULL * * Ensures: * \li 'name' is DNS_NAMEATTR_READONLY. * * \li 'name' will point directly to the labels stored after the * dns_rbtnode_t struct. * * \li 'name' will have offsets that also point to the information stored * as part of the node. */ isc_result_t dns_rbt_fullnamefromnode(dns_rbtnode_t *node, dns_name_t *name); /*%< * Like dns_rbt_namefromnode, but returns the full name from the root. * * Notes: * \li Unlike dns_rbt_namefromnode, the name will not point directly * to node data. Rather, dns_name_concatenate will be used to copy * the name data from each node into the 'name' argument. * * Requires: * \li name != NULL * \li name has a dedicated buffer. * * Returns: * \li ISC_R_SUCCESS * \li ISC_R_NOSPACE (possible via dns_name_concatenate) * \li DNS_R_NAMETOOLONG (possible via dns_name_concatenate) */ char * dns_rbt_formatnodename(dns_rbtnode_t *node, char *printname, unsigned int size); /*%< * Format the full name of a node for printing, using dns_name_format(). * * Notes: * \li 'size' is the length of the printname buffer. This should be * DNS_NAME_FORMATSIZE or larger. * * Requires: * \li node and printname are not NULL. * * Returns: * \li The 'printname' pointer. */ unsigned int dns_rbt_nodecount(dns_rbt_t *rbt); /*%< * Obtain the number of nodes in the tree of trees. * * Requires: * \li rbt is a valid rbt manager. */ unsigned int dns_rbt_hashsize(dns_rbt_t *rbt); /*%< * Obtain the current number of buckets in the 'rbt' hash table. * * Requires: * \li rbt is a valid rbt manager. */ void dns_rbt_destroy(dns_rbt_t **rbtp); isc_result_t dns_rbt_destroy2(dns_rbt_t **rbtp, unsigned int quantum); /*%< * Stop working with a red-black tree of trees. * If 'quantum' is zero then the entire tree will be destroyed. * If 'quantum' is non zero then up to 'quantum' nodes will be destroyed * allowing the rbt to be incrementally destroyed by repeated calls to * dns_rbt_destroy2(). Once dns_rbt_destroy2() has been called no other * operations than dns_rbt_destroy()/dns_rbt_destroy2() should be * performed on the tree of trees. * * Requires: * \li *rbt is a valid rbt manager. * * Ensures on ISC_R_SUCCESS: * \li All space allocated by the RBT library has been returned. * * \li *rbt is invalidated as an rbt manager. * * Returns: * \li ISC_R_SUCCESS * \li ISC_R_QUOTA if 'quantum' nodes have been destroyed. */ off_t dns_rbt_serialize_align(off_t target); /*%< * Align the provided integer to a pointer-size boundary. * This should be used if, during serialization of data to a will-be * mmap()ed file, a pointer alignment is needed for some data. */ isc_result_t dns_rbt_serialize_tree(FILE *file, dns_rbt_t *rbt, dns_rbtdatawriter_t datawriter, void *writer_arg, off_t *offset); /*%< * Write out the RBT structure and its data to a file. * * Notes: * \li The file must be an actual file which allows seek() calls, so it cannot * be a stream. Returns ISC_R_INVALIDFILE if not. */ isc_result_t dns_rbt_deserialize_tree(void *base_address, size_t filesize, off_t header_offset, isc_mem_t *mctx, dns_rbtdeleter_t deleter, void *deleter_arg, dns_rbtdatafixer_t datafixer, void *fixer_arg, dns_rbtnode_t **originp, dns_rbt_t **rbtp); /*%< * Read a RBT structure and its data from a file. * * If 'originp' is not NULL, then it is pointed to the root node of the RBT. * * Notes: * \li The file must be an actual file which allows seek() calls, so it cannot * be a stream. This condition is not checked in the code. */ void dns_rbt_printtext(dns_rbt_t *rbt, void (*data_printer)(FILE *, void *), FILE *f); /*%< * Print an ASCII representation of the internal structure of the red-black * tree of trees to the passed stream. * * data_printer is a callback function that is called to print the data * in a node. It should print it to the passed FILE stream. * * Notes: * \li The name stored at each node, along with the node's color, is printed. * Then the down pointer, left and right pointers are displayed * recursively in turn. NULL down pointers are silently omitted; * NULL left and right pointers are printed. */ void dns_rbt_printdot(dns_rbt_t *rbt, isc_boolean_t show_pointers, FILE *f); /*%< * Print a GraphViz dot representation of the internal structure of the * red-black tree of trees to the passed stream. * * If show_pointers is TRUE, pointers are also included in the generated * graph. * * Notes: * \li The name stored at each node, along with the node's color is displayed. * Then the down pointer, left and right pointers are displayed * recursively in turn. NULL left, right and down pointers are * silently omitted. */ void dns_rbt_printnodeinfo(dns_rbtnode_t *n, FILE *f); /*%< * Print out various information about a node * * Requires: *\li 'n' is a valid pointer. * *\li 'f' points to a valid open FILE structure that allows writing. */ size_t dns__rbt_getheight(dns_rbt_t *rbt); /*%< * Return the maximum height of sub-root nodes found in the red-black * forest. * * The height of a node is defined as the number of nodes in the longest * path from the node to a leaf. For each subtree in the forest, this * function determines the height of its root node. Then it returns the * maximum such height in the forest. * * Note: This function exists for testing purposes. Non-test code must * not use it. * * Requires: * \li rbt is a valid rbt manager. */ isc_boolean_t dns__rbt_checkproperties(dns_rbt_t *rbt); /*%< * Check red-black properties of the forest. * * Note: This function exists for testing purposes. Non-test code must * not use it. * * Requires: * \li rbt is a valid rbt manager. */ size_t dns__rbtnode_getdistance(dns_rbtnode_t *node); /*%< * Return the distance (in nodes) from the node to its upper node of its * subtree. The root node has a distance of 1. A child of the root node * has a distance of 2. */ /***** ***** Chain Functions *****/ void dns_rbtnodechain_init(dns_rbtnodechain_t *chain, isc_mem_t *mctx); /*%< * Initialize 'chain'. * * Requires: *\li 'chain' is a valid pointer. * *\li 'mctx' is a valid memory context. * * Ensures: *\li 'chain' is suitable for use. */ void dns_rbtnodechain_reset(dns_rbtnodechain_t *chain); /*%< * Free any dynamic storage associated with 'chain', and then reinitialize * 'chain'. * * Requires: *\li 'chain' is a valid pointer. * * Ensures: *\li 'chain' is suitable for use, and uses no dynamic storage. */ void dns_rbtnodechain_invalidate(dns_rbtnodechain_t *chain); /*%< * Free any dynamic storage associated with 'chain', and then invalidates it. * * Notes: *\li Future calls to any dns_rbtnodechain_ function will need to call * dns_rbtnodechain_init on the chain first (except, of course, * dns_rbtnodechain_init itself). * * Requires: *\li 'chain' is a valid chain. * * Ensures: *\li 'chain' is no longer suitable for use, and uses no dynamic storage. */ isc_result_t dns_rbtnodechain_current(dns_rbtnodechain_t *chain, dns_name_t *name, dns_name_t *origin, dns_rbtnode_t **node); /*%< * Provide the name, origin and node to which the chain is currently pointed. * * Notes: *\li The tree need not have be locked against additions for the chain * to remain valid, however there are no guarantees if any deletion * has been made since the chain was established. * * Requires: *\li 'chain' is a valid chain. * * Ensures: *\li 'node', if non-NULL, is the node to which the chain was pointed * by dns_rbt_findnode, dns_rbtnodechain_first or dns_rbtnodechain_last. * If none were called for the chain since it was initialized or reset, * or if the was no predecessor to the name searched for with * dns_rbt_findnode, then '*node' is NULL and ISC_R_NOTFOUND is returned. * *\li 'name', if non-NULL, is the name stored at the terminal level of * the chain. This is typically a single label, like the "www" of * "www.isc.org", but need not be so. At the root of the tree of trees, * if the node is "." then 'name' is ".", otherwise it is relative to ".". * (Minimalist and atypical case: if the tree has just the name * "isc.org." then the root node's stored name is "isc.org." but 'name' * will be "isc.org".) * *\li 'origin', if non-NULL, is the sequence of labels in the levels * above the terminal level, such as "isc.org." in the above example. * 'origin' is always "." for the root node. * * * Returns: *\li #ISC_R_SUCCESS name, origin & node were successfully set. *\li #ISC_R_NOTFOUND The chain does not point to any node. *\li <something_else> Any error return from dns_name_concatenate. */ isc_result_t dns_rbtnodechain_first(dns_rbtnodechain_t *chain, dns_rbt_t *rbt, dns_name_t *name, dns_name_t *origin); /*%< * Set the chain to the lexically first node in the tree of trees. * * Notes: *\li By the definition of ordering for DNS names, the root of the tree of * trees is the very first node, since everything else in the megatree * uses it as a common suffix. * * Requires: *\li 'chain' is a valid chain. *\li 'rbt' is a valid rbt manager. * * Ensures: *\li The chain points to the very first node of the tree. * *\li 'name' and 'origin', if non-NULL, are set as described for * dns_rbtnodechain_current. Thus 'origin' will always be ".". * * Returns: *\li #DNS_R_NEWORIGIN The name & origin were successfully set. *\li <something_else> Any error result from dns_rbtnodechain_current. */ isc_result_t dns_rbtnodechain_last(dns_rbtnodechain_t *chain, dns_rbt_t *rbt, dns_name_t *name, dns_name_t *origin); /*%< * Set the chain to the lexically last node in the tree of trees. * * Requires: *\li 'chain' is a valid chain. *\li 'rbt' is a valid rbt manager. * * Ensures: *\li The chain points to the very last node of the tree. * *\li 'name' and 'origin', if non-NULL, are set as described for * dns_rbtnodechain_current. * * Returns: *\li #DNS_R_NEWORIGIN The name & origin were successfully set. *\li #ISC_R_NOMEMORY Resource Limit: Out of Memory building chain. *\li <something_else> Any error result from dns_name_concatenate. */ isc_result_t dns_rbtnodechain_prev(dns_rbtnodechain_t *chain, dns_name_t *name, dns_name_t *origin); /*%< * Adjusts chain to point the DNSSEC predecessor of the name to which it * is currently pointed. * * Requires: *\li 'chain' is a valid chain. *\li 'chain' has been pointed somewhere in the tree with dns_rbt_findnode, * dns_rbtnodechain_first or dns_rbtnodechain_last -- and remember that * dns_rbt_findnode is not guaranteed to point the chain somewhere, * since there may have been no predecessor to the searched for name. * * Ensures: *\li The chain is pointed to the predecessor of its current target. * *\li 'name' and 'origin', if non-NULL, are set as described for * dns_rbtnodechain_current. * *\li 'origin' is only if a new origin was found. * * Returns: *\li #ISC_R_SUCCESS The predecessor was found and 'name' was set. *\li #DNS_R_NEWORIGIN The predecessor was found with a different * origin and 'name' and 'origin' were set. *\li #ISC_R_NOMORE There was no predecessor. *\li <something_else> Any error result from dns_rbtnodechain_current. */ isc_result_t dns_rbtnodechain_next(dns_rbtnodechain_t *chain, dns_name_t *name, dns_name_t *origin); /*%< * Adjusts chain to point the DNSSEC successor of the name to which it * is currently pointed. * * Requires: *\li 'chain' is a valid chain. *\li 'chain' has been pointed somewhere in the tree with dns_rbt_findnode, * dns_rbtnodechain_first or dns_rbtnodechain_last -- and remember that * dns_rbt_findnode is not guaranteed to point the chain somewhere, * since there may have been no predecessor to the searched for name. * * Ensures: *\li The chain is pointed to the successor of its current target. * *\li 'name' and 'origin', if non-NULL, are set as described for * dns_rbtnodechain_current. * *\li 'origin' is only if a new origin was found. * * Returns: *\li #ISC_R_SUCCESS The successor was found and 'name' was set. *\li #DNS_R_NEWORIGIN The successor was found with a different * origin and 'name' and 'origin' were set. *\li #ISC_R_NOMORE There was no successor. *\li <something_else> Any error result from dns_name_concatenate. */ isc_result_t dns_rbtnodechain_down(dns_rbtnodechain_t *chain, dns_name_t *name, dns_name_t *origin); /*%< * Descend down if possible. */ isc_result_t dns_rbtnodechain_nextflat(dns_rbtnodechain_t *chain, dns_name_t *name); /*%< * Find the next node at the current depth in DNSSEC order. */ /* * Wrapper macros for manipulating the rbtnode reference counter: * Since we selectively use isc_refcount_t for the reference counter of * a rbtnode, operations on the counter depend on the actual type of it. * The following macros provide a common interface to these operations, * hiding the back-end. The usage is the same as that of isc_refcount_xxx(). */ #ifdef DNS_RBT_USEISCREFCOUNT #define dns_rbtnode_refinit(node, n) \ do { \ isc_refcount_init(&(node)->references, (n)); \ } while (0) #define dns_rbtnode_refdestroy(node) \ do { \ isc_refcount_destroy(&(node)->references); \ } while (0) #define dns_rbtnode_refcurrent(node) \ isc_refcount_current(&(node)->references) #define dns_rbtnode_refincrement0(node, refs) \ do { \ isc_refcount_increment0(&(node)->references, (refs)); \ } while (0) #define dns_rbtnode_refincrement(node, refs) \ do { \ isc_refcount_increment(&(node)->references, (refs)); \ } while (0) #define dns_rbtnode_refdecrement(node, refs) \ do { \ isc_refcount_decrement(&(node)->references, (refs)); \ } while (0) #else /* DNS_RBT_USEISCREFCOUNT */ #define dns_rbtnode_refinit(node, n) ((node)->references = (n)) #define dns_rbtnode_refdestroy(node) REQUIRE((node)->references == 0) #define dns_rbtnode_refcurrent(node) ((node)->references) #if (__STDC_VERSION__ + 0) >= 199901L || defined __GNUC__ static inline void dns_rbtnode_refincrement0(dns_rbtnode_t *node, unsigned int *refs) { node->references++; if (refs != NULL) *refs = node->references; } static inline void dns_rbtnode_refincrement(dns_rbtnode_t *node, unsigned int *refs) { REQUIRE(node->references > 0); node->references++; if (refs != NULL) *refs = node->references; } static inline void dns_rbtnode_refdecrement(dns_rbtnode_t *node, unsigned int *refs) { REQUIRE(node->references > 0); node->references--; if (refs != NULL) *refs = node->references; } #else #define dns_rbtnode_refincrement0(node, refs) \ do { \ unsigned int *_tmp = (unsigned int *)(refs); \ (node)->references++; \ if ((_tmp) != NULL) \ (*_tmp) = (node)->references; \ } while (0) #define dns_rbtnode_refincrement(node, refs) \ do { \ REQUIRE((node)->references > 0); \ (node)->references++; \ if ((refs) != NULL) \ (*refs) = (node)->references; \ } while (0) #define dns_rbtnode_refdecrement(node, refs) \ do { \ REQUIRE((node)->references > 0); \ (node)->references--; \ if ((refs) != NULL) \ (*refs) = (node)->references; \ } while (0) #endif #endif /* DNS_RBT_USEISCREFCOUNT */ void dns_rbtnode_nodename(dns_rbtnode_t *node, dns_name_t *name); dns_rbtnode_t * dns_rbt_root(dns_rbt_t *rbt); ISC_LANG_ENDDECLS #endif /* DNS_RBT_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/tkey.h0000644000470500017500000001772112664710322020267 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009-2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: tkey.h,v 1.32 2011/01/08 23:47:01 tbox Exp $ */ #ifndef DNS_TKEY_H #define DNS_TKEY_H 1 /*! \file dns/tkey.h */ #include #include #include #include ISC_LANG_BEGINDECLS /* Key agreement modes */ #define DNS_TKEYMODE_SERVERASSIGNED 1 #define DNS_TKEYMODE_DIFFIEHELLMAN 2 #define DNS_TKEYMODE_GSSAPI 3 #define DNS_TKEYMODE_RESOLVERASSIGNED 4 #define DNS_TKEYMODE_DELETE 5 struct dns_tkeyctx { dst_key_t *dhkey; dns_name_t *domain; gss_cred_id_t gsscred; isc_mem_t *mctx; isc_entropy_t *ectx; char *gssapi_keytab; }; isc_result_t dns_tkeyctx_create(isc_mem_t *mctx, isc_entropy_t *ectx, dns_tkeyctx_t **tctxp); /*%< * Create an empty TKEY context. * * Requires: *\li 'mctx' is not NULL *\li 'tctx' is not NULL *\li '*tctx' is NULL * * Returns *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li return codes from dns_name_fromtext() */ void dns_tkeyctx_destroy(dns_tkeyctx_t **tctxp); /*%< * Frees all data associated with the TKEY context * * Requires: *\li 'tctx' is not NULL *\li '*tctx' is not NULL */ isc_result_t dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx, dns_tsig_keyring_t *ring); /*%< * Processes a query containing a TKEY record, adding or deleting TSIG * keys if necessary, and modifies the message to contain the response. * * Requires: *\li 'msg' is a valid message *\li 'tctx' is a valid TKEY context *\li 'ring' is a valid TSIG keyring * * Returns *\li #ISC_R_SUCCESS msg was updated (the TKEY operation succeeded, * or msg now includes a TKEY with an error set) * DNS_R_FORMERR the packet was malformed (missing a TKEY * or KEY). *\li other An error occurred while processing the message */ isc_result_t dns_tkey_builddhquery(dns_message_t *msg, dst_key_t *key, dns_name_t *name, dns_name_t *algorithm, isc_buffer_t *nonce, isc_uint32_t lifetime); /*%< * Builds a query containing a TKEY that will generate a shared * secret using a Diffie-Hellman key exchange. The shared key * will be of the specified algorithm (only DNS_TSIG_HMACMD5_NAME * is supported), and will be named either 'name', * 'name' + server chosen domain, or random data + server chosen domain * if 'name' == dns_rootname. If nonce is not NULL, it supplies * random data used in the shared secret computation. The key is * requested to have the specified lifetime (in seconds) * * * Requires: *\li 'msg' is a valid message *\li 'key' is a valid Diffie Hellman dst key *\li 'name' is a valid name *\li 'algorithm' is a valid name * * Returns: *\li #ISC_R_SUCCESS msg was successfully updated to include the * query to be sent *\li other an error occurred while building the message */ isc_result_t dns_tkey_buildgssquery(dns_message_t *msg, dns_name_t *name, dns_name_t *gname, isc_buffer_t *intoken, isc_uint32_t lifetime, gss_ctx_id_t *context, isc_boolean_t win2k, isc_mem_t *mctx, char **err_message); /*%< * Builds a query containing a TKEY that will generate a GSSAPI context. * The key is requested to have the specified lifetime (in seconds). * * Requires: *\li 'msg' is a valid message *\li 'name' is a valid name *\li 'gname' is a valid name *\li 'context' is a pointer to a valid gss_ctx_id_t * (which may have the value GSS_C_NO_CONTEXT) *\li 'win2k' when true says to turn on some hacks to work * with the non-standard GSS-TSIG of Windows 2000 * * Returns: *\li ISC_R_SUCCESS msg was successfully updated to include the * query to be sent *\li other an error occurred while building the message *\li *err_message optional error message */ isc_result_t dns_tkey_builddeletequery(dns_message_t *msg, dns_tsigkey_t *key); /*%< * Builds a query containing a TKEY record that will delete the * specified shared secret from the server. * * Requires: *\li 'msg' is a valid message *\li 'key' is a valid TSIG key * * Returns: *\li #ISC_R_SUCCESS msg was successfully updated to include the * query to be sent *\li other an error occurred while building the message */ isc_result_t dns_tkey_processdhresponse(dns_message_t *qmsg, dns_message_t *rmsg, dst_key_t *key, isc_buffer_t *nonce, dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring); /*%< * Processes a response to a query containing a TKEY that was * designed to generate a shared secret using a Diffie-Hellman key * exchange. If the query was successful, a new shared key * is created and added to the list of shared keys. * * Requires: *\li 'qmsg' is a valid message (the query) *\li 'rmsg' is a valid message (the response) *\li 'key' is a valid Diffie Hellman dst key *\li 'outkey' is either NULL or a pointer to NULL *\li 'ring' is a valid keyring or NULL * * Returns: *\li #ISC_R_SUCCESS the shared key was successfully added *\li #ISC_R_NOTFOUND an error occurred while looking for a * component of the query or response */ isc_result_t dns_tkey_processgssresponse(dns_message_t *qmsg, dns_message_t *rmsg, dns_name_t *gname, gss_ctx_id_t *context, isc_buffer_t *outtoken, dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring, char **err_message); /*%< * XXX */ isc_result_t dns_tkey_processdeleteresponse(dns_message_t *qmsg, dns_message_t *rmsg, dns_tsig_keyring_t *ring); /*%< * Processes a response to a query containing a TKEY that was * designed to delete a shared secret. If the query was successful, * the shared key is deleted from the list of shared keys. * * Requires: *\li 'qmsg' is a valid message (the query) *\li 'rmsg' is a valid message (the response) *\li 'ring' is not NULL * * Returns: *\li #ISC_R_SUCCESS the shared key was successfully deleted *\li #ISC_R_NOTFOUND an error occurred while looking for a * component of the query or response */ isc_result_t dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg, dns_name_t *server, gss_ctx_id_t *context, dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring, isc_boolean_t win2k, char **err_message); /* * Client side negotiation of GSS-TSIG. Process the response * to a TKEY, and establish a TSIG key if negotiation was successful. * Build a response to the input TKEY message. Can take multiple * calls to successfully establish the context. * * Requires: * 'qmsg' is a valid message, the original TKEY request; * it will be filled with the new message to send * 'rmsg' is a valid message, the incoming TKEY message * 'server' is the server name * 'context' is the input context handle * 'outkey' receives the established key, if non-NULL; * if non-NULL must point to NULL * 'ring' is the keyring in which to establish the key, * or NULL * 'win2k' when true says to turn on some hacks to work * with the non-standard GSS-TSIG of Windows 2000 * * Returns: * ISC_R_SUCCESS context was successfully established * ISC_R_NOTFOUND couldn't find a needed part of the query * or response * DNS_R_CONTINUE additional context negotiation is required; * send the new qmsg to the server */ ISC_LANG_ENDDECLS #endif /* DNS_TKEY_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/private.h0000644000470500017500000000456612664710322020770 0ustar lamontlamont/* * Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: private.h,v 1.5 2011/10/28 12:20:31 tbox Exp $ */ #include #include #include #include #ifndef DNS_PRIVATE_H #define DNS_PRIVATE_H ISC_LANG_BEGINDECLS isc_result_t dns_private_chains(dns_db_t *db, dns_dbversion_t *ver, dns_rdatatype_t privatetype, isc_boolean_t *build_nsec, isc_boolean_t *build_nsec3); /*%< * Examine the NSEC, NSEC3PARAM and privatetype RRsets at the apex of the * database to determine which of NSEC or NSEC3 chains we are currently * maintaining. In normal operations only one of NSEC or NSEC3 is being * maintained but when we are transitiong between NSEC and NSEC3 we need * to update both sets of chains. If 'privatetype' is zero then the * privatetype RRset will not be examined. * * Requires: * \li 'db' is valid. * \li 'version' is valid or NULL. * \li 'build_nsec' is a pointer to a isc_boolean_t or NULL. * \li 'build_nsec3' is a pointer to a isc_boolean_t or NULL. * * Returns: * \li ISC_R_SUCCESS, 'build_nsec' and 'build_nsec3' will be valid. * \li other on error */ isc_result_t dns_private_totext(dns_rdata_t *privaterdata, isc_buffer_t *buffer); /*%< * Convert a private-type RR 'privaterdata' to human-readable form, * and place the result in 'buffer'. The text should indicate * which action the private-type record specifies and whether the * action has been completed. * * Requires: * \li 'privaterdata' is a valid rdata containing at least five bytes * \li 'buffer' is a valid buffer * * Returns: * \li ISC_R_SUCCESS * \li other on error */ ISC_LANG_ENDDECLS #endif bind9-9.10.3.dfsg.P4/lib/dns/include/dns/sdlz.h0000644000470500017500000003456012664710322020267 0ustar lamontlamont/* * Portions Copyright (C) 2005-2007, 2009-2012 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all * copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE * USE OR PERFORMANCE OF THIS SOFTWARE. * * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was * conceived and contributed by Rob Butler. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all * copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * ROB BUTLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE * USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file dns/sdlz.h */ #ifndef SDLZ_H #define SDLZ_H 1 #include #include ISC_LANG_BEGINDECLS #define DNS_SDLZFLAG_THREADSAFE 0x00000001U #define DNS_SDLZFLAG_RELATIVEOWNER 0x00000002U #define DNS_SDLZFLAG_RELATIVERDATA 0x00000004U /* A simple DLZ database. */ typedef struct dns_sdlz_db dns_sdlz_db_t; /* A simple DLZ database lookup in progress. */ typedef struct dns_sdlzlookup dns_sdlzlookup_t; /* A simple DLZ database traversal in progress. */ typedef struct dns_sdlzallnodes dns_sdlzallnodes_t; typedef isc_result_t (*dns_sdlzallnodesfunc_t)(const char *zone, void *driverarg, void *dbdata, dns_sdlzallnodes_t *allnodes); /*%< * Method prototype. Drivers implementing the SDLZ interface may * supply an all nodes method. This method is called when the DNS * server is performing a zone transfer query, after the allow zone * transfer method has been called. This method is only called if the * allow zone transfer method returned ISC_R_SUCCESS. This method and * the allow zone transfer method are both required for zone transfers * to be supported. If the driver generates data dynamically (instead * of searching in a database for it) it should not implement this * function as a zone transfer would be meaningless. A SDLZ driver * does not have to implement an all nodes method. */ typedef isc_result_t (*dns_sdlzallowzonexfr_t)(void *driverarg, void *dbdata, const char *name, const char *client); /*%< * Method prototype. Drivers implementing the SDLZ interface may * supply an allow zone transfer method. This method is called when * the DNS server is performing a zone transfer query, before the all * nodes method can be called. This method and the all node method * are both required for zone transfers to be supported. If the * driver generates data dynamically (instead of searching in a * database for it) it should not implement this function as a zone * transfer would be meaningless. A SDLZ driver does not have to * implement an allow zone transfer method. * * This method should return ISC_R_SUCCESS if the zone is supported by * the database and a zone transfer is allowed for the specified * client. If the zone is supported by the database, but zone * transfers are not allowed for the specified client this method * should return ISC_R_NOPERM.. Lastly the method should return * ISC_R_NOTFOUND if the zone is not supported by the database. If an * error occurs it should return a result code indicating the type of * error. */ typedef isc_result_t (*dns_sdlzauthorityfunc_t)(const char *zone, void *driverarg, void *dbdata, dns_sdlzlookup_t *lookup); /*%< * Method prototype. Drivers implementing the SDLZ interface may * supply an authority method. This method is called when the DNS * server is performing a query, after both the find zone and lookup * methods have been called. This method is required if the lookup * function does not supply authority information for the dns * record. A SDLZ driver does not have to implement an authority * method. */ typedef isc_result_t (*dns_sdlzcreate_t)(const char *dlzname, unsigned int argc, char *argv[], void *driverarg, void **dbdata); /*%< * Method prototype. Drivers implementing the SDLZ interface may * supply a create method. This method is called when the DNS server * is starting up and creating drivers for use later. A SDLZ driver * does not have to implement a create method. */ typedef void (*dns_sdlzdestroy_t)(void *driverarg, void *dbdata); /*%< * Method prototype. Drivers implementing the SDLZ interface may * supply a destroy method. This method is called when the DNS server * is shutting down and no longer needs the driver. A SDLZ driver does * not have to implement a destroy method. */ typedef isc_result_t (*dns_sdlzfindzone_t)(void *driverarg, void *dbdata, const char *name, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo); /*%< * Method prototype. Drivers implementing the SDLZ interface MUST * supply a find zone method. This method is called when the DNS * server is performing a query to to determine if 'name' is a * supported dns zone. The find zone method will be called with the * longest possible name first, and continue to be called with * successively shorter domain names, until any of the following * occur: * * \li 1) the function returns (ISC_R_SUCCESS) indicating a zone name * match. * * \li 2) a problem occurs, and the functions returns anything other than * (ISC_R_NOTFOUND) * * \li 3) we run out of domain name labels. I.E. we have tried the * shortest domain name * * \li 4) the number of labels in the domain name is less than min_labels * for dns_dlzfindzone * * The driver's find zone method should return ISC_R_SUCCESS if the * zone is supported by the database. Otherwise it should return * ISC_R_NOTFOUND, if the zone is not supported. If an error occurs * it should return a result code indicating the type of error. */ typedef isc_result_t (*dns_sdlzlookupfunc_t)(const char *zone, const char *name, void *driverarg, void *dbdata, dns_sdlzlookup_t *lookup, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo); /*%< * Method prototype. Drivers implementing the SDLZ interface MUST * supply a lookup method. This method is called when the * DNS server is performing a query, after the find zone and before any * other methods have been called. This function returns DNS record * information using the dns_sdlz_putrr and dns_sdlz_putsoa functions. * If this function supplies authority information for the DNS record * the authority method is not required. If it does not, the * authority function is required. * * The 'methods' and 'clientinfo' args allow an SDLZ driver to retrieve * information about the querying client (such as source IP address) * from the caller. */ typedef isc_result_t (*dns_sdlznewversion_t)(const char *zone, void *driverarg, void *dbdata, void **versionp); /*%< * Method prototype. Drivers implementing the SDLZ interface may * supply a newversion method. This method is called to start a * write transaction on a zone and should only be implemented by * writeable backends. * When implemented, the driver should create a new transaction, and * fill *versionp with a pointer to the transaction state. The * closeversion function will be called to close the transaction. */ typedef void (*dns_sdlzcloseversion_t)(const char *zone, isc_boolean_t commit, void *driverarg, void *dbdata, void **versionp); /*%< * Method prototype. Drivers implementing the SDLZ interface must * supply a closeversion method if they supply a newversion method. * When implemented, the driver should close the given transaction, * committing changes if 'commit' is ISC_TRUE. If 'commit' is not true * then all changes should be discarded and the database rolled back. * If the call is successful then *versionp should be set to NULL */ typedef isc_result_t (*dns_sdlzconfigure_t)(dns_view_t *view, dns_dlzdb_t *dlzdb, void *driverarg, void *dbdata); /*%< * Method prototype. Drivers implementing the SDLZ interface may * supply a configure method. When supplied, it will be called * immediately after the create method to give the driver a chance * to configure writeable zones */ typedef isc_boolean_t (*dns_sdlzssumatch_t)(const char *signer, const char *name, const char *tcpaddr, const char *type, const char *key, isc_uint32_t keydatalen, unsigned char *keydata, void *driverarg, void *dbdata); /*%< * Method prototype. Drivers implementing the SDLZ interface may * supply a ssumatch method. If supplied, then ssumatch will be * called to authorize any zone updates. The driver should return * ISC_TRUE to allow the update, and ISC_FALSE to deny it. For a DLZ * controlled zone, this is the only access control on updates. */ typedef isc_result_t (*dns_sdlzmodrdataset_t)(const char *name, const char *rdatastr, void *driverarg, void *dbdata, void *version); /*%< * Method prototype. Drivers implementing the SDLZ interface may * supply addrdataset and subtractrdataset methods. If supplied, then these * will be called when rdatasets are added/subtracted during * updates. The version parameter comes from a call to the sdlz * newversion() method from the driver. The rdataset parameter is a * linearise string representation of the rdataset change. The format * is the same as used by dig when displaying records. The fields are * tab delimited. */ typedef isc_result_t (*dns_sdlzdelrdataset_t)(const char *name, const char *type, void *driverarg, void *dbdata, void *version); /*%< * Method prototype. Drivers implementing the SDLZ interface may * supply a delrdataset method. If supplied, then this * function will be called when rdatasets are deleted during * updates. The call should remove all rdatasets of the given type for * the specified name. */ typedef struct dns_sdlzmethods { dns_sdlzcreate_t create; dns_sdlzdestroy_t destroy; dns_sdlzfindzone_t findzone; dns_sdlzlookupfunc_t lookup; dns_sdlzauthorityfunc_t authority; dns_sdlzallnodesfunc_t allnodes; dns_sdlzallowzonexfr_t allowzonexfr; dns_sdlznewversion_t newversion; dns_sdlzcloseversion_t closeversion; dns_sdlzconfigure_t configure; dns_sdlzssumatch_t ssumatch; dns_sdlzmodrdataset_t addrdataset; dns_sdlzmodrdataset_t subtractrdataset; dns_sdlzdelrdataset_t delrdataset; } dns_sdlzmethods_t; isc_result_t dns_sdlzregister(const char *drivername, const dns_sdlzmethods_t *methods, void *driverarg, unsigned int flags, isc_mem_t *mctx, dns_sdlzimplementation_t **sdlzimp); /*%< * Register a dynamically loadable zones (dlz) driver for the database * type 'drivername', implemented by the functions in '*methods'. * * sdlzimp must point to a NULL dns_sdlzimplementation_t pointer. * That is, sdlzimp != NULL && *sdlzimp == NULL. It will be assigned * a value that will later be used to identify the driver when * deregistering it. */ void dns_sdlzunregister(dns_sdlzimplementation_t **sdlzimp); /*%< * Removes the sdlz driver from the list of registered sdlz drivers. * There must be no active sdlz drivers of this type when this * function is called. */ typedef isc_result_t dns_sdlz_putnamedrr_t(dns_sdlzallnodes_t *allnodes, const char *name, const char *type, dns_ttl_t ttl, const char *data); dns_sdlz_putnamedrr_t dns_sdlz_putnamedrr; /*%< * Add a single resource record to the allnodes structure to be later * parsed into a zone transfer response. */ typedef isc_result_t dns_sdlz_putrr_t(dns_sdlzlookup_t *lookup, const char *type, dns_ttl_t ttl, const char *data); dns_sdlz_putrr_t dns_sdlz_putrr; /*%< * Add a single resource record to the lookup structure to be later * parsed into a query response. */ typedef isc_result_t dns_sdlz_putsoa_t(dns_sdlzlookup_t *lookup, const char *mname, const char *rname, isc_uint32_t serial); dns_sdlz_putsoa_t dns_sdlz_putsoa; /*%< * This function may optionally be called from the 'authority' * callback to simplify construction of the SOA record for 'zone'. It * will provide a SOA listing 'mname' as as the master server and * 'rname' as the responsible person mailbox. It is the * responsibility of the driver to increment the serial number between * responses if necessary. All other SOA fields will have reasonable * default values. */ typedef isc_result_t dns_sdlz_setdb_t(dns_dlzdb_t *dlzdatabase, dns_rdataclass_t rdclass, dns_name_t *name, dns_db_t **dbp); dns_sdlz_setdb_t dns_sdlz_setdb; /*%< * Create the database pointers for a writeable SDLZ zone */ ISC_LANG_ENDDECLS #endif /* SDLZ_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/types.h0000644000470500017500000003167412664710322020462 0ustar lamontlamont/* * Copyright (C) 2004-2013, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef DNS_TYPES_H #define DNS_TYPES_H 1 /*! \file dns/types.h * \brief * Including this file gives you type declarations suitable for use in * .h files, which lets us avoid circular type reference problems. * \brief * To actually use a type or get declarations of its methods, you must * include the appropriate .h file too. */ #include #include typedef struct dns_acache dns_acache_t; typedef struct dns_acacheentry dns_acacheentry_t; typedef struct dns_acachestats dns_acachestats_t; typedef struct dns_acl dns_acl_t; typedef struct dns_aclelement dns_aclelement_t; typedef struct dns_aclenv dns_aclenv_t; typedef struct dns_adb dns_adb_t; typedef struct dns_adbaddrinfo dns_adbaddrinfo_t; typedef ISC_LIST(dns_adbaddrinfo_t) dns_adbaddrinfolist_t; typedef struct dns_adbentry dns_adbentry_t; typedef struct dns_adbfind dns_adbfind_t; typedef ISC_LIST(dns_adbfind_t) dns_adbfindlist_t; typedef struct dns_byaddr dns_byaddr_t; typedef struct dns_client dns_client_t; typedef void dns_clientrestrans_t; typedef void dns_clientreqtrans_t; typedef void dns_clientupdatetrans_t; typedef struct dns_cache dns_cache_t; typedef isc_uint16_t dns_cert_t; typedef struct dns_compress dns_compress_t; typedef struct dns_db dns_db_t; typedef struct dns_dbimplementation dns_dbimplementation_t; typedef struct dns_dbiterator dns_dbiterator_t; typedef void dns_dbload_t; typedef void dns_dbnode_t; typedef struct dns_dbtable dns_dbtable_t; typedef void dns_dbversion_t; typedef struct dns_dlzimplementation dns_dlzimplementation_t; typedef struct dns_dlzdb dns_dlzdb_t; typedef ISC_LIST(dns_dlzdb_t) dns_dlzdblist_t; typedef struct dns_sdlzimplementation dns_sdlzimplementation_t; typedef struct dns_decompress dns_decompress_t; typedef struct dns_dispatch dns_dispatch_t; typedef struct dns_dispatchevent dns_dispatchevent_t; typedef struct dns_dispatchlist dns_dispatchlist_t; typedef struct dns_dispatchset dns_dispatchset_t; typedef struct dns_dispatchmgr dns_dispatchmgr_t; typedef struct dns_dispentry dns_dispentry_t; typedef struct dns_dns64 dns_dns64_t; typedef ISC_LIST(dns_dns64_t) dns_dns64list_t; typedef struct dns_dnsseckey dns_dnsseckey_t; typedef ISC_LIST(dns_dnsseckey_t) dns_dnsseckeylist_t; typedef isc_uint8_t dns_dsdigest_t; typedef struct dns_dumpctx dns_dumpctx_t; typedef struct dns_ednsopt dns_ednsopt_t; typedef struct dns_fetch dns_fetch_t; typedef struct dns_fixedname dns_fixedname_t; typedef struct dns_forwarders dns_forwarders_t; typedef struct dns_forwarder dns_forwarder_t; typedef struct dns_fwdtable dns_fwdtable_t; typedef struct dns_iptable dns_iptable_t; typedef isc_uint32_t dns_iterations_t; typedef isc_uint16_t dns_keyflags_t; typedef struct dns_keynode dns_keynode_t; typedef ISC_LIST(dns_keynode_t) dns_keynodelist_t; typedef struct dns_keytable dns_keytable_t; typedef isc_uint16_t dns_keytag_t; typedef struct dns_loadctx dns_loadctx_t; typedef struct dns_loadmgr dns_loadmgr_t; typedef struct dns_masterrawheader dns_masterrawheader_t; typedef struct dns_message dns_message_t; typedef isc_uint16_t dns_messageid_t; typedef isc_region_t dns_label_t; typedef struct dns_lookup dns_lookup_t; typedef struct dns_name dns_name_t; typedef ISC_LIST(dns_name_t) dns_namelist_t; typedef isc_uint16_t dns_opcode_t; typedef unsigned char dns_offsets_t[128]; typedef struct dns_order dns_order_t; typedef struct dns_peer dns_peer_t; typedef struct dns_peerlist dns_peerlist_t; typedef struct dns_portlist dns_portlist_t; typedef struct dns_rbt dns_rbt_t; typedef isc_uint16_t dns_rcode_t; typedef struct dns_rdata dns_rdata_t; typedef struct dns_rdatacallbacks dns_rdatacallbacks_t; typedef isc_uint16_t dns_rdataclass_t; typedef struct dns_rdatalist dns_rdatalist_t; typedef struct dns_rdataset dns_rdataset_t; typedef ISC_LIST(dns_rdataset_t) dns_rdatasetlist_t; typedef struct dns_rdatasetiter dns_rdatasetiter_t; typedef isc_uint16_t dns_rdatatype_t; typedef struct dns_request dns_request_t; typedef struct dns_requestmgr dns_requestmgr_t; typedef struct dns_resolver dns_resolver_t; typedef struct dns_sdbimplementation dns_sdbimplementation_t; typedef isc_uint8_t dns_secalg_t; typedef isc_uint8_t dns_secproto_t; typedef struct dns_signature dns_signature_t; typedef struct dns_ssurule dns_ssurule_t; typedef struct dns_ssutable dns_ssutable_t; typedef struct dns_stats dns_stats_t; typedef isc_uint32_t dns_rdatastatstype_t; typedef struct dns_tkeyctx dns_tkeyctx_t; typedef isc_uint16_t dns_trust_t; typedef struct dns_tsec dns_tsec_t; typedef struct dns_tsig_keyring dns_tsig_keyring_t; typedef struct dns_tsigkey dns_tsigkey_t; typedef isc_uint32_t dns_ttl_t; typedef struct dns_update_state dns_update_state_t; typedef struct dns_validator dns_validator_t; typedef struct dns_view dns_view_t; typedef ISC_LIST(dns_view_t) dns_viewlist_t; typedef struct dns_zone dns_zone_t; typedef ISC_LIST(dns_zone_t) dns_zonelist_t; typedef struct dns_zonemgr dns_zonemgr_t; typedef struct dns_zt dns_zt_t; /* * If we are not using GSSAPI, define the types we use as opaque types here. */ #ifndef GSSAPI typedef struct not_defined_gss_cred_id *gss_cred_id_t; typedef struct not_defined_gss_ctx *gss_ctx_id_t; #endif typedef struct dst_gssapi_signverifyctx dst_gssapi_signverifyctx_t; typedef enum { dns_hash_sha1 = 1 } dns_hash_t; typedef enum { dns_fwdpolicy_none = 0, dns_fwdpolicy_first = 1, dns_fwdpolicy_only = 2 } dns_fwdpolicy_t; typedef enum { dns_namereln_none = 0, dns_namereln_contains = 1, dns_namereln_subdomain = 2, dns_namereln_equal = 3, dns_namereln_commonancestor = 4 } dns_namereln_t; typedef enum { dns_one_answer, dns_many_answers } dns_transfer_format_t; typedef enum { dns_dbtype_zone = 0, dns_dbtype_cache = 1, dns_dbtype_stub = 3 } dns_dbtype_t; typedef enum { dns_notifytype_no = 0, dns_notifytype_yes = 1, dns_notifytype_explicit = 2, dns_notifytype_masteronly = 3 } dns_notifytype_t; typedef enum { dns_dialuptype_no = 0, dns_dialuptype_yes = 1, dns_dialuptype_notify = 2, dns_dialuptype_notifypassive = 3, dns_dialuptype_refresh = 4, dns_dialuptype_passive = 5 } dns_dialuptype_t; typedef enum { dns_masterformat_none = 0, dns_masterformat_text = 1, dns_masterformat_raw = 2, dns_masterformat_map = 3 } dns_masterformat_t; typedef enum { dns_aaaa_ok = 0, dns_aaaa_filter = 1, dns_aaaa_break_dnssec = 2 } dns_aaaa_t; /* * These are generated by gen.c. */ #include /* Provides dns_rdatatype_t. */ #include /* Provides dns_rdataclass_t. */ /*% * rcodes. */ enum { /* * Standard rcodes. */ dns_rcode_noerror = 0, #define dns_rcode_noerror ((dns_rcode_t)dns_rcode_noerror) dns_rcode_formerr = 1, #define dns_rcode_formerr ((dns_rcode_t)dns_rcode_formerr) dns_rcode_servfail = 2, #define dns_rcode_servfail ((dns_rcode_t)dns_rcode_servfail) dns_rcode_nxdomain = 3, #define dns_rcode_nxdomain ((dns_rcode_t)dns_rcode_nxdomain) dns_rcode_notimp = 4, #define dns_rcode_notimp ((dns_rcode_t)dns_rcode_notimp) dns_rcode_refused = 5, #define dns_rcode_refused ((dns_rcode_t)dns_rcode_refused) dns_rcode_yxdomain = 6, #define dns_rcode_yxdomain ((dns_rcode_t)dns_rcode_yxdomain) dns_rcode_yxrrset = 7, #define dns_rcode_yxrrset ((dns_rcode_t)dns_rcode_yxrrset) dns_rcode_nxrrset = 8, #define dns_rcode_nxrrset ((dns_rcode_t)dns_rcode_nxrrset) dns_rcode_notauth = 9, #define dns_rcode_notauth ((dns_rcode_t)dns_rcode_notauth) dns_rcode_notzone = 10, #define dns_rcode_notzone ((dns_rcode_t)dns_rcode_notzone) /* * Extended rcodes. */ dns_rcode_badvers = 16, #define dns_rcode_badvers ((dns_rcode_t)dns_rcode_badvers) dns_rcode_badcookie = 23 #define dns_rcode_badcookie ((dns_rcode_t)dns_rcode_badcookie) /* Private space [3841..4095] */ }; /*% * TSIG errors. */ enum { dns_tsigerror_badsig = 16, dns_tsigerror_badkey = 17, dns_tsigerror_badtime = 18, dns_tsigerror_badmode = 19, dns_tsigerror_badname = 20, dns_tsigerror_badalg = 21, dns_tsigerror_badtrunc = 22 }; /*% * Opcodes. */ enum { dns_opcode_query = 0, #define dns_opcode_query ((dns_opcode_t)dns_opcode_query) dns_opcode_iquery = 1, #define dns_opcode_iquery ((dns_opcode_t)dns_opcode_iquery) dns_opcode_status = 2, #define dns_opcode_status ((dns_opcode_t)dns_opcode_status) dns_opcode_notify = 4, #define dns_opcode_notify ((dns_opcode_t)dns_opcode_notify) dns_opcode_update = 5 /* dynamic update */ #define dns_opcode_update ((dns_opcode_t)dns_opcode_update) }; /*% * Trust levels. Must be kept in sync with trustnames[] in masterdump.c. */ enum { /* Sentinel value; no data should have this trust level. */ dns_trust_none = 0, #define dns_trust_none ((dns_trust_t)dns_trust_none) /*% * Subject to DNSSEC validation but has not yet been validated * dns_trust_pending_additional (from the additional section). */ dns_trust_pending_additional = 1, #define dns_trust_pending_additional \ ((dns_trust_t)dns_trust_pending_additional) dns_trust_pending_answer = 2, #define dns_trust_pending_answer ((dns_trust_t)dns_trust_pending_answer) /*% Received in the additional section of a response. */ dns_trust_additional = 3, #define dns_trust_additional ((dns_trust_t)dns_trust_additional) /* Received in a referral response. */ dns_trust_glue = 4, #define dns_trust_glue ((dns_trust_t)dns_trust_glue) /* Answer from a non-authoritative server */ dns_trust_answer = 5, #define dns_trust_answer ((dns_trust_t)dns_trust_answer) /* Received in the authority section as part of an authoritative response */ dns_trust_authauthority = 6, #define dns_trust_authauthority ((dns_trust_t)dns_trust_authauthority) /* Answer from an authoritative server */ dns_trust_authanswer = 7, #define dns_trust_authanswer ((dns_trust_t)dns_trust_authanswer) /* Successfully DNSSEC validated */ dns_trust_secure = 8, #define dns_trust_secure ((dns_trust_t)dns_trust_secure) /* This server is authoritative */ dns_trust_ultimate = 9 #define dns_trust_ultimate ((dns_trust_t)dns_trust_ultimate) }; #define DNS_TRUST_PENDING(x) ((x) == dns_trust_pending_answer || \ (x) == dns_trust_pending_additional) #define DNS_TRUST_ADDITIONAL(x) ((x) == dns_trust_additional || \ (x) == dns_trust_pending_additional) #define DNS_TRUST_GLUE(x) ((x) == dns_trust_glue) #define DNS_TRUST_ANSWER(x) ((x) == dns_trust_answer) /*% * Name checking severities. */ typedef enum { dns_severity_ignore, dns_severity_warn, dns_severity_fail } dns_severity_t; /*% * DNS Serial Number Update Method. * * \li _increment: Add one to the current serial, skipping 0. * \li _unixtime: Set to the seconds since 00:00 Jan 1, 1970, * if possible. * \li _yyyymmvv: Set to Year, Month, Version, if possible. * (Not yet implemented) */ typedef enum { dns_updatemethod_increment = 0, dns_updatemethod_unixtime } dns_updatemethod_t; /* * Functions. */ typedef void (*dns_dumpdonefunc_t)(void *, isc_result_t); typedef void (*dns_loaddonefunc_t)(void *, isc_result_t); typedef void (*dns_rawdatafunc_t)(dns_zone_t *, dns_masterrawheader_t *); typedef isc_result_t (*dns_addrdatasetfunc_t)(void *, dns_name_t *, dns_rdataset_t *); typedef isc_result_t (*dns_additionaldatafunc_t)(void *, dns_name_t *, dns_rdatatype_t); typedef isc_result_t (*dns_digestfunc_t)(void *, isc_region_t *); typedef void (*dns_xfrindone_t)(dns_zone_t *, isc_result_t); typedef void (*dns_updatecallback_t)(void *, isc_result_t, dns_message_t *); typedef int (*dns_rdatasetorderfunc_t)(const dns_rdata_t *, const void *); typedef isc_boolean_t (*dns_checkmxfunc_t)(dns_zone_t *, dns_name_t *, dns_name_t *); typedef isc_boolean_t (*dns_checksrvfunc_t)(dns_zone_t *, dns_name_t *, dns_name_t *); typedef isc_boolean_t (*dns_checknsfunc_t)(dns_zone_t *, dns_name_t *, dns_name_t *, dns_rdataset_t *, dns_rdataset_t *); typedef isc_boolean_t (*dns_isselffunc_t)(dns_view_t *, dns_tsigkey_t *, isc_sockaddr_t *, isc_sockaddr_t *, dns_rdataclass_t, void *); typedef isc_result_t (*dns_deserializefunc_t)(void *, FILE *, off_t); typedef void (*dns_nseclog_t)(void *val, int , const char *, ...); #endif /* DNS_TYPES_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/dsdigest.h0000644000470500017500000000412712664710322021115 0ustar lamontlamont/* * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef DNS_DSDIGEST_H #define DNS_DSDIGEST_H 1 /*! \file dns/dsdigest.h */ #include #include ISC_LANG_BEGINDECLS isc_result_t dns_dsdigest_fromtext(dns_dsdigest_t *dsdigestp, isc_textregion_t *source); /*%< * Convert the text 'source' refers to into a DS/DLV digest type value. * The text may contain either a mnemonic digest name or a decimal * digest number. * * Requires: *\li 'dsdigestp' is a valid pointer. * *\li 'source' is a valid text region. * * Returns: *\li ISC_R_SUCCESS on success *\li ISC_R_RANGE numeric type is out of range *\li DNS_R_UNKNOWN mnemonic type is unknown */ isc_result_t dns_dsdigest_totext(dns_dsdigest_t dsdigest, isc_buffer_t *target); /*%< * Put a textual representation of the DS/DLV digest type 'dsdigest' * into 'target'. * * Requires: *\li 'dsdigest' is a valid dsdigest. * *\li 'target' is a valid text buffer. * * Ensures, * if the result is success: *\li The used space in 'target' is updated. * * Returns: *\li ISC_R_SUCCESS on success *\li ISC_R_NOSPACE target buffer is too small */ #define DNS_DSDIGEST_FORMATSIZE 20 void dns_dsdigest_format(dns_dsdigest_t typ, char *cp, unsigned int size); /*%< * Wrapper for dns_dsdigest_totext(), writing text into 'cp' */ ISC_LANG_ENDDECLS #endif /* DNS_DSDIGEST_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/nsec.h0000644000470500017500000000664612664710322020247 0ustar lamontlamont/* * Copyright (C) 2004-2008, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: nsec.h,v 1.14 2011/06/10 23:47:32 tbox Exp $ */ #ifndef DNS_NSEC_H #define DNS_NSEC_H 1 /*! \file dns/nsec.h */ #include #include #include #define DNS_NSEC_BUFFERSIZE (DNS_NAME_MAXWIRE + 8192 + 512) ISC_LANG_BEGINDECLS isc_result_t dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, dns_name_t *target, unsigned char *buffer, dns_rdata_t *rdata); /*%< * Build the rdata of a NSEC record. * * Requires: *\li buffer Points to a temporary buffer of at least * DNS_NSEC_BUFFERSIZE bytes. *\li rdata Points to an initialized dns_rdata_t. * * Ensures: * \li *rdata Contains a valid NSEC rdata. The 'data' member refers * to 'buffer'. */ isc_result_t dns_nsec_build(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, dns_name_t *target, dns_ttl_t ttl); /*%< * Build a NSEC record and add it to a database. */ isc_boolean_t dns_nsec_typepresent(dns_rdata_t *nsec, dns_rdatatype_t type); /*%< * Determine if a type is marked as present in an NSEC record. * * Requires: *\li 'nsec' points to a valid rdataset of type NSEC */ isc_result_t dns_nsec_nseconly(dns_db_t *db, dns_dbversion_t *version, isc_boolean_t *answer); /* * Report whether the DNSKEY RRset has a NSEC only algorithm. Unknown * algorithms are assumed to support NSEC3. If DNSKEY is not found, * *answer is set to ISC_FALSE, and ISC_R_NOTFOUND is returned. * * Requires: * 'answer' to be non NULL. */ unsigned int dns_nsec_compressbitmap(unsigned char *map, const unsigned char *raw, unsigned int max_type); /*%< * Convert a raw bitmap into a compressed windowed bit map. 'map' and 'raw' * may overlap. * * Returns the length of the compressed windowed bit map. */ void dns_nsec_setbit(unsigned char *array, unsigned int type, unsigned int bit); /*%< * Set type bit in raw 'array' to 'bit'. */ isc_boolean_t dns_nsec_isset(const unsigned char *array, unsigned int type); /*%< * Test if the corresponding 'type' bit is set in 'array'. */ isc_result_t dns_nsec_noexistnodata(dns_rdatatype_t type, dns_name_t *name, dns_name_t *nsecname, dns_rdataset_t *nsecset, isc_boolean_t *exists, isc_boolean_t *data, dns_name_t *wild, dns_nseclog_t log, void *arg); /*% * Return ISC_R_SUCCESS if we can determine that the name doesn't exist * or we can determine whether there is data or not at the name. * If the name does not exist return the wildcard name. * * Return ISC_R_IGNORE when the NSEC is not the appropriate one. */ ISC_LANG_ENDDECLS #endif /* DNS_NSEC_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/rdataslab.h0000644000470500017500000001110712664710322021240 0ustar lamontlamont/* * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rdataslab.h,v 1.33 2008/04/01 23:47:10 tbox Exp $ */ #ifndef DNS_RDATASLAB_H #define DNS_RDATASLAB_H 1 /*! \file dns/rdataslab.h * \brief * Implements storage of rdatasets into slabs of memory. * * MP: *\li Clients of this module must impose any required synchronization. * * Reliability: *\li This module deals with low-level byte streams. Errors in any of * the functions are likely to crash the server or corrupt memory. * *\li If the caller passes invalid memory references, these functions are * likely to crash the server or corrupt memory. * * Resources: *\li None. * * Security: *\li None. * * Standards: *\li None. */ /*** *** Imports ***/ #include #include ISC_LANG_BEGINDECLS #define DNS_RDATASLAB_FORCE 0x1 #define DNS_RDATASLAB_EXACT 0x2 #define DNS_RDATASLAB_OFFLINE 0x01 /* RRSIG is for offline DNSKEY */ #define DNS_RDATASLAB_WARNMASK 0x0E /*%< RRSIG(DNSKEY) expired * warnings number mask. */ #define DNS_RDATASLAB_WARNSHIFT 1 /*%< How many bits to shift to find * remaining expired warning number. */ /*** *** Functions ***/ isc_result_t dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, isc_region_t *region, unsigned int reservelen); /*%< * Slabify a rdataset. The slab area will be allocated and returned * in 'region'. * * Requires: *\li 'rdataset' is valid. * * Ensures: *\li 'region' will have base pointing to the start of allocated memory, * with the slabified region beginning at region->base + reservelen. * region->length contains the total length allocated. * * Returns: *\li ISC_R_SUCCESS - successful completion *\li ISC_R_NOMEMORY - no memory. *\li XXX others */ void dns_rdataslab_tordataset(unsigned char *slab, unsigned int reservelen, dns_rdataclass_t rdclass, dns_rdatatype_t rdtype, dns_rdatatype_t covers, dns_ttl_t ttl, dns_rdataset_t *rdataset); /*%< * Construct an rdataset from a slab. * * Requires: *\li 'slab' points to a slab. *\li 'rdataset' is disassociated. * * Ensures: *\li 'rdataset' is associated and points to a valid rdataest. */ unsigned int dns_rdataslab_size(unsigned char *slab, unsigned int reservelen); /*%< * Return the total size of an rdataslab. * * Requires: *\li 'slab' points to a slab. * * Returns: *\li The number of bytes in the slab, including the reservelen. */ isc_result_t dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab, unsigned int reservelen, isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_rdatatype_t type, unsigned int flags, unsigned char **tslabp); /*%< * Merge 'oslab' and 'nslab'. */ isc_result_t dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab, unsigned int reservelen, isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_rdatatype_t type, unsigned int flags, unsigned char **tslabp); /*%< * Subtract 'sslab' from 'mslab'. If 'exact' is true then all elements * of 'sslab' must exist in 'mslab'. * * XXX * valid flags are DNS_RDATASLAB_EXACT */ isc_boolean_t dns_rdataslab_equal(unsigned char *slab1, unsigned char *slab2, unsigned int reservelen); /*%< * Compare two rdataslabs for equality. This does _not_ do a full * DNSSEC comparison. * * Requires: *\li 'slab1' and 'slab2' point to slabs. * * Returns: *\li ISC_TRUE if the slabs are equal, ISC_FALSE otherwise. */ isc_boolean_t dns_rdataslab_equalx(unsigned char *slab1, unsigned char *slab2, unsigned int reservelen, dns_rdataclass_t rdclass, dns_rdatatype_t type); /*%< * Compare two rdataslabs for DNSSEC equality. * * Requires: *\li 'slab1' and 'slab2' point to slabs. * * Returns: *\li ISC_TRUE if the slabs are equal, #ISC_FALSE otherwise. */ ISC_LANG_ENDDECLS #endif /* DNS_RDATASLAB_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/lib.h0000644000470500017500000000326612664710322020060 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lib.h,v 1.18 2009/09/02 23:48:02 tbox Exp $ */ #ifndef DNS_LIB_H #define DNS_LIB_H 1 /*! \file dns/lib.h */ #include #include ISC_LANG_BEGINDECLS /*% * Tuning: external query load in packets per seconds. */ LIBDNS_EXTERNAL_DATA extern unsigned int dns_pps; LIBDNS_EXTERNAL_DATA extern isc_msgcat_t *dns_msgcat; void dns_lib_initmsgcat(void); /*%< * Initialize the DNS library's message catalog, dns_msgcat, if it * has not already been initialized. */ isc_result_t dns_lib_init(void); /*%< * A set of initialization procedure used in the DNS library. This function * is provided for an application that is not aware of the underlying ISC or * DNS libraries much. */ void dns_lib_shutdown(void); /*%< * Free temporary resources allocated in dns_lib_init(). */ ISC_LANG_ENDDECLS #endif /* DNS_LIB_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/peer.h0000644000470500017500000001401712664710322020241 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: peer.h,v 1.35 2009/01/17 23:47:43 tbox Exp $ */ #ifndef DNS_PEER_H #define DNS_PEER_H 1 /***** ***** Module Info *****/ /*! \file dns/peer.h * \brief * Data structures for peers (e.g. a 'server' config file statement) */ /*** *** Imports ***/ #include #include #include #include #define DNS_PEERLIST_MAGIC ISC_MAGIC('s','e','R','L') #define DNS_PEER_MAGIC ISC_MAGIC('S','E','r','v') #define DNS_PEERLIST_VALID(ptr) ISC_MAGIC_VALID(ptr, DNS_PEERLIST_MAGIC) #define DNS_PEER_VALID(ptr) ISC_MAGIC_VALID(ptr, DNS_PEER_MAGIC) /*** *** Types ***/ struct dns_peerlist { unsigned int magic; isc_uint32_t refs; isc_mem_t *mem; ISC_LIST(dns_peer_t) elements; }; struct dns_peer { unsigned int magic; isc_uint32_t refs; isc_mem_t *mem; isc_netaddr_t address; unsigned int prefixlen; isc_boolean_t bogus; dns_transfer_format_t transfer_format; isc_uint32_t transfers; isc_boolean_t support_ixfr; isc_boolean_t provide_ixfr; isc_boolean_t request_ixfr; isc_boolean_t support_edns; isc_boolean_t request_nsid; isc_boolean_t request_sit; dns_name_t *key; isc_sockaddr_t *transfer_source; isc_dscp_t transfer_dscp; isc_sockaddr_t *notify_source; isc_dscp_t notify_dscp; isc_sockaddr_t *query_source; isc_dscp_t query_dscp; isc_uint16_t udpsize; /* receive size */ isc_uint16_t maxudp; /* transmit size */ isc_uint32_t bitflags; ISC_LINK(dns_peer_t) next; }; /*** *** Functions ***/ ISC_LANG_BEGINDECLS isc_result_t dns_peerlist_new(isc_mem_t *mem, dns_peerlist_t **list); void dns_peerlist_attach(dns_peerlist_t *source, dns_peerlist_t **target); void dns_peerlist_detach(dns_peerlist_t **list); /* * After return caller still holds a reference to peer. */ void dns_peerlist_addpeer(dns_peerlist_t *peers, dns_peer_t *peer); /* * Ditto. */ isc_result_t dns_peerlist_peerbyaddr(dns_peerlist_t *peers, isc_netaddr_t *addr, dns_peer_t **retval); /* * What he said. */ isc_result_t dns_peerlist_currpeer(dns_peerlist_t *peers, dns_peer_t **retval); isc_result_t dns_peer_new(isc_mem_t *mem, isc_netaddr_t *ipaddr, dns_peer_t **peer); isc_result_t dns_peer_newprefix(isc_mem_t *mem, isc_netaddr_t *ipaddr, unsigned int prefixlen, dns_peer_t **peer); void dns_peer_attach(dns_peer_t *source, dns_peer_t **target); void dns_peer_detach(dns_peer_t **list); isc_result_t dns_peer_setbogus(dns_peer_t *peer, isc_boolean_t newval); isc_result_t dns_peer_getbogus(dns_peer_t *peer, isc_boolean_t *retval); isc_result_t dns_peer_setrequestixfr(dns_peer_t *peer, isc_boolean_t newval); isc_result_t dns_peer_getrequestixfr(dns_peer_t *peer, isc_boolean_t *retval); isc_result_t dns_peer_setprovideixfr(dns_peer_t *peer, isc_boolean_t newval); isc_result_t dns_peer_getprovideixfr(dns_peer_t *peer, isc_boolean_t *retval); isc_result_t dns_peer_setrequestnsid(dns_peer_t *peer, isc_boolean_t newval); isc_result_t dns_peer_getrequestnsid(dns_peer_t *peer, isc_boolean_t *retval); isc_result_t dns_peer_setrequestsit(dns_peer_t *peer, isc_boolean_t newval); isc_result_t dns_peer_getrequestsit(dns_peer_t *peer, isc_boolean_t *retval); isc_result_t dns_peer_setsupportedns(dns_peer_t *peer, isc_boolean_t newval); isc_result_t dns_peer_getsupportedns(dns_peer_t *peer, isc_boolean_t *retval); isc_result_t dns_peer_settransfers(dns_peer_t *peer, isc_uint32_t newval); isc_result_t dns_peer_gettransfers(dns_peer_t *peer, isc_uint32_t *retval); isc_result_t dns_peer_settransferformat(dns_peer_t *peer, dns_transfer_format_t newval); isc_result_t dns_peer_gettransferformat(dns_peer_t *peer, dns_transfer_format_t *retval); isc_result_t dns_peer_setkeybycharp(dns_peer_t *peer, const char *keyval); isc_result_t dns_peer_getkey(dns_peer_t *peer, dns_name_t **retval); isc_result_t dns_peer_setkey(dns_peer_t *peer, dns_name_t **keyval); isc_result_t dns_peer_settransfersource(dns_peer_t *peer, const isc_sockaddr_t *transfer_source); isc_result_t dns_peer_gettransfersource(dns_peer_t *peer, isc_sockaddr_t *transfer_source); isc_result_t dns_peer_setudpsize(dns_peer_t *peer, isc_uint16_t udpsize); isc_result_t dns_peer_getudpsize(dns_peer_t *peer, isc_uint16_t *udpsize); isc_result_t dns_peer_setmaxudp(dns_peer_t *peer, isc_uint16_t maxudp); isc_result_t dns_peer_getmaxudp(dns_peer_t *peer, isc_uint16_t *maxudp); isc_result_t dns_peer_setnotifysource(dns_peer_t *peer, const isc_sockaddr_t *notify_source); isc_result_t dns_peer_getnotifysource(dns_peer_t *peer, isc_sockaddr_t *notify_source); isc_result_t dns_peer_setquerysource(dns_peer_t *peer, const isc_sockaddr_t *query_source); isc_result_t dns_peer_getquerysource(dns_peer_t *peer, isc_sockaddr_t *query_source); isc_result_t dns_peer_setnotifydscp(dns_peer_t *peer, isc_dscp_t dscp); isc_result_t dns_peer_getnotifydscp(dns_peer_t *peer, isc_dscp_t *dscpp); isc_result_t dns_peer_settransferdscp(dns_peer_t *peer, isc_dscp_t dscp); isc_result_t dns_peer_gettransferdscp(dns_peer_t *peer, isc_dscp_t *dscpp); isc_result_t dns_peer_setquerydscp(dns_peer_t *peer, isc_dscp_t dscp); isc_result_t dns_peer_getquerydscp(dns_peer_t *peer, isc_dscp_t *dscpp); ISC_LANG_ENDDECLS #endif /* DNS_PEER_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/journal.h0000644000470500017500000002111012664710322020750 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2011, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: journal.h,v 1.43 2011/12/22 07:32:41 each Exp $ */ #ifndef DNS_JOURNAL_H #define DNS_JOURNAL_H 1 /***** ***** Module Info *****/ /*! \file dns/journal.h * \brief * Database journaling. */ /*** *** Imports ***/ #include #include #include #include #include #include /*** *** Defines. ***/ #define DNS_JOURNALOPT_RESIGN 0x00000001 #define DNS_JOURNAL_READ 0x00000000 /* ISC_FALSE */ #define DNS_JOURNAL_CREATE 0x00000001 /* ISC_TRUE */ #define DNS_JOURNAL_WRITE 0x00000002 /*** *** Types ***/ /*% * A dns_journal_t represents an open journal file. This is an opaque type. * * A particular dns_journal_t object may be opened for writing, in which case * it can be used for writing transactions to a journal file, or it can be * opened for reading, in which case it can be used for reading transactions * from (iterating over) a journal file. A single dns_journal_t object may * not be used for both purposes. */ typedef struct dns_journal dns_journal_t; /*** *** Functions ***/ ISC_LANG_BEGINDECLS /**************************************************************************/ isc_result_t dns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx, dns_diffop_t op, dns_difftuple_t **tp); /*!< brief * Create a diff tuple for the current database SOA. * XXX this probably belongs somewhere else. */ /*@{*/ #define DNS_SERIAL_GT(a, b) ((int)(((a) - (b)) & 0xFFFFFFFF) > 0) #define DNS_SERIAL_GE(a, b) ((int)(((a) - (b)) & 0xFFFFFFFF) >= 0) /*!< brief * Compare SOA serial numbers. DNS_SERIAL_GT(a, b) returns true iff * a is "greater than" b where "greater than" is as defined in RFC1982. * DNS_SERIAL_GE(a, b) returns true iff a is "greater than or equal to" b. */ /*@}*/ /**************************************************************************/ /* * Journal object creation and destruction. */ isc_result_t dns_journal_open(isc_mem_t *mctx, const char *filename, unsigned int mode, dns_journal_t **journalp); /*%< * Open the journal file 'filename' and create a dns_journal_t object for it. * * DNS_JOURNAL_CREATE open the journal for reading and writing and create * the journal if it does not exist. * DNS_JOURNAL_WRITE open the journal for reading and writing. * DNS_JOURNAL_READ open the journal for reading only. */ void dns_journal_destroy(dns_journal_t **journalp); /*%< * Destroy a dns_journal_t, closing any open files and freeing its memory. */ /**************************************************************************/ /* * Writing transactions to journals. */ isc_result_t dns_journal_begin_transaction(dns_journal_t *j); /*%< * Prepare to write a new transaction to the open journal file 'j'. * * Requires: * \li 'j' is open for writing. */ isc_result_t dns_journal_writediff(dns_journal_t *j, dns_diff_t *diff); /*%< * Write 'diff' to the current transaction of journal file 'j'. * * Requires: * \li 'j' is open for writing and dns_journal_begin_transaction() * has been called. * *\li 'diff' is a full or partial, correctly ordered IXFR * difference sequence. */ isc_result_t dns_journal_commit(dns_journal_t *j); /*%< * Commit the current transaction of journal file 'j'. * * Requires: * \li 'j' is open for writing and dns_journal_begin_transaction() * has been called. * * \li dns_journal_writediff() has been called one or more times * to form a complete, correctly ordered IXFR difference * sequence. */ isc_result_t dns_journal_write_transaction(dns_journal_t *j, dns_diff_t *diff); /*% * Write a complete transaction at once to a journal file, * sorting it if necessary, and commit it. Equivalent to calling * dns_diff_sort(), dns_journal_begin_transaction(), * dns_journal_writediff(), and dns_journal_commit(). * * Requires: *\li 'j' is open for writing. * * \li 'diff' contains exactly one SOA deletion, one SOA addition * with a greater serial number, and possibly other changes, * in arbitrary order. */ /**************************************************************************/ /* * Reading transactions from journals. */ isc_uint32_t dns_journal_first_serial(dns_journal_t *j); isc_uint32_t dns_journal_last_serial(dns_journal_t *j); /*%< * Get the first and last addressable serial number in the journal. */ isc_result_t dns_journal_iter_init(dns_journal_t *j, isc_uint32_t begin_serial, isc_uint32_t end_serial); /*%< * Prepare to iterate over the transactions that will bring the database * from SOA serial number 'begin_serial' to 'end_serial'. * * Returns: *\li ISC_R_SUCCESS *\li ISC_R_RANGE begin_serial is outside the addressable range. *\li ISC_R_NOTFOUND begin_serial is within the range of addressable * serial numbers covered by the journal, but * this particular serial number does not exist. */ /*@{*/ isc_result_t dns_journal_first_rr(dns_journal_t *j); isc_result_t dns_journal_next_rr(dns_journal_t *j); /*%< * Position the iterator at the first/next RR in a journal * transaction sequence established using dns_journal_iter_init(). * * Requires: * \li dns_journal_iter_init() has been called. * */ /*@}*/ void dns_journal_current_rr(dns_journal_t *j, dns_name_t **name, isc_uint32_t *ttl, dns_rdata_t **rdata); /*%< * Get the name, ttl, and rdata of the current journal RR. * * Requires: * \li The last call to dns_journal_first_rr() or dns_journal_next_rr() * returned ISC_R_SUCCESS. */ /**************************************************************************/ /* * Database roll-forward. */ isc_result_t dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db, unsigned int options, const char *filename); /*%< * Roll forward (play back) the journal file "filename" into the * database "db". This should be called when the server starts * after a shutdown or crash. * * Requires: *\li 'mctx' is a valid memory context. *\li 'db' is a valid database which does not have a version * open for writing. *\li 'filename' is the name of the journal file belonging to 'db'. * * Returns: *\li DNS_R_NOJOURNAL when journal does not exist. *\li ISC_R_NOTFOUND when current serial in not in journal. *\li ISC_R_RANGE when current serial in not in journals range. *\li ISC_R_SUCCESS journal has been applied successfully to database. * others */ isc_result_t dns_journal_print(isc_mem_t *mctx, const char *filename, FILE *file); /* For debugging not general use */ isc_result_t dns_db_diff(isc_mem_t *mctx, dns_db_t *dba, dns_dbversion_t *dbvera, dns_db_t *dbb, dns_dbversion_t *dbverb, const char *journal_filename); isc_result_t dns_db_diffx(dns_diff_t *diff, dns_db_t *dba, dns_dbversion_t *dbvera, dns_db_t *dbb, dns_dbversion_t *dbverb, const char *journal_filename); /*%< * Compare the databases 'dba' and 'dbb' and generate a diff/journal * entry containing the changes to make 'dba' from 'dbb' (note * the order). This journal entry will consist of a single, * possibly very large transaction. Append the journal * entry to the journal file specified by 'journal_filename' if * non-NULL. */ isc_result_t dns_journal_compact(isc_mem_t *mctx, char *filename, isc_uint32_t serial, isc_uint32_t target_size); /*%< * Attempt to compact the journal if it is greater that 'target_size'. * Changes from 'serial' onwards will be preserved. If the journal * exists and is non-empty 'serial' must exist in the journal. */ isc_boolean_t dns_journal_get_sourceserial(dns_journal_t *j, isc_uint32_t *sourceserial); void dns_journal_set_sourceserial(dns_journal_t *j, isc_uint32_t sourceserial); /*%< * Get and set source serial. * * Returns: * ISC_TRUE if sourceserial has previously been set. */ ISC_LANG_ENDDECLS #endif /* DNS_JOURNAL_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/rdatasetiter.h0000644000470500017500000001054712664710322022005 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rdatasetiter.h,v 1.21 2007/06/19 23:47:17 tbox Exp $ */ #ifndef DNS_RDATASETITER_H #define DNS_RDATASETITER_H 1 /***** ***** Module Info *****/ /*! \file dns/rdatasetiter.h * \brief * The DNS Rdataset Iterator interface allows iteration of all of the * rdatasets at a node. * * The dns_rdatasetiter_t type is like a "virtual class". To actually use * it, an implementation of the class is required. This implementation is * supplied by the database. * * It is the client's responsibility to call dns_rdataset_disassociate() * on all rdatasets returned. * * XXX more XXX * * MP: *\li The iterator itself is not locked. The caller must ensure * synchronization. * *\li The iterator methods ensure appropriate database locking. * * Reliability: *\li No anticipated impact. * * Resources: *\li TBS * * Security: *\li No anticipated impact. * * Standards: *\li None. */ /***** ***** Imports *****/ #include #include #include #include ISC_LANG_BEGINDECLS /***** ***** Types *****/ typedef struct dns_rdatasetitermethods { void (*destroy)(dns_rdatasetiter_t **iteratorp); isc_result_t (*first)(dns_rdatasetiter_t *iterator); isc_result_t (*next)(dns_rdatasetiter_t *iterator); void (*current)(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset); } dns_rdatasetitermethods_t; #define DNS_RDATASETITER_MAGIC ISC_MAGIC('D','N','S','i') #define DNS_RDATASETITER_VALID(i) ISC_MAGIC_VALID(i, DNS_RDATASETITER_MAGIC) /*% * This structure is actually just the common prefix of a DNS db * implementation's version of a dns_rdatasetiter_t. * \brief * Direct use of this structure by clients is forbidden. DB implementations * may change the structure. 'magic' must be #DNS_RDATASETITER_MAGIC for * any of the dns_rdatasetiter routines to work. DB implementations must * maintain all DB rdataset iterator invariants. */ struct dns_rdatasetiter { /* Unlocked. */ unsigned int magic; dns_rdatasetitermethods_t * methods; dns_db_t * db; dns_dbnode_t * node; dns_dbversion_t * version; isc_stdtime_t now; }; void dns_rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp); /*%< * Destroy '*iteratorp'. * * Requires: * *\li '*iteratorp' is a valid iterator. * * Ensures: * *\li All resources used by the iterator are freed. * *\li *iteratorp == NULL. */ isc_result_t dns_rdatasetiter_first(dns_rdatasetiter_t *iterator); /*%< * Move the rdataset cursor to the first rdataset at the node (if any). * * Requires: *\li 'iterator' is a valid iterator. * * Returns: *\li ISC_R_SUCCESS *\li ISC_R_NOMORE There are no rdatasets at the node. * *\li Other results are possible, depending on the DB implementation. */ isc_result_t dns_rdatasetiter_next(dns_rdatasetiter_t *iterator); /*%< * Move the rdataset cursor to the next rdataset at the node (if any). * * Requires: *\li 'iterator' is a valid iterator. * * Returns: *\li ISC_R_SUCCESS *\li ISC_R_NOMORE There are no more rdatasets at the * node. * *\li Other results are possible, depending on the DB implementation. */ void dns_rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset); /*%< * Return the current rdataset. * * Requires: *\li 'iterator' is a valid iterator. * *\li 'rdataset' is a valid, disassociated rdataset. * *\li The rdataset cursor of 'iterator' is at a valid location (i.e. the * result of last call to a cursor movement command was #ISC_R_SUCCESS). */ ISC_LANG_ENDDECLS #endif /* DNS_RDATASETITER_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/masterdump.h0000644000470500017500000002655712664710322021503 0ustar lamontlamont/* * Copyright (C) 2004-2008, 2011, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: masterdump.h,v 1.47 2011/12/08 23:46:49 tbox Exp $ */ #ifndef DNS_MASTERDUMP_H #define DNS_MASTERDUMP_H 1 /*! \file dns/masterdump.h */ /*** *** Imports ***/ #include #include #include /*** *** Types ***/ typedef struct dns_master_style dns_master_style_t; /*** *** Definitions ***/ /* * Flags affecting master file formatting. Flags 0x0000FFFF * define the formatting of the rdata part and are defined in * rdata.h. */ /*% Omit the owner name when possible. */ #define DNS_STYLEFLAG_OMIT_OWNER 0x00010000U /*% * Omit the TTL when possible. If DNS_STYLEFLAG_TTL is * also set, this means no TTLs are ever printed * because $TTL directives are generated before every * change in the TTL. In this case, no columns need to * be reserved for the TTL. Master files generated with * these options will be rejected by BIND 4.x because it * does not recognize the $TTL directive. * * If DNS_STYLEFLAG_TTL is not also set, the TTL will be * omitted when it is equal to the previous TTL. * This is correct according to RFC1035, but the * TTLs may be silently misinterpreted by older * versions of BIND which use the SOA MINTTL as a * default TTL value. */ #define DNS_STYLEFLAG_OMIT_TTL 0x00020000U /*% Omit the class when possible. */ #define DNS_STYLEFLAG_OMIT_CLASS 0x00040000U /*% Output $TTL directives. */ #define DNS_STYLEFLAG_TTL 0x00080000U /*% * Output $ORIGIN directives and print owner names relative to * the origin when possible. */ #define DNS_STYLEFLAG_REL_OWNER 0x00100000U /*% Print domain names in RR data in relative form when possible. For this to take effect, DNS_STYLEFLAG_REL_OWNER must also be set. */ #define DNS_STYLEFLAG_REL_DATA 0x00200000U /*% Print the trust level of each rdataset. */ #define DNS_STYLEFLAG_TRUST 0x00400000U /*% Print negative caching entries. */ #define DNS_STYLEFLAG_NCACHE 0x00800000U /*% Never print the TTL. */ #define DNS_STYLEFLAG_NO_TTL 0x01000000U /*% Never print the CLASS. */ #define DNS_STYLEFLAG_NO_CLASS 0x02000000U /*% Report re-signing time. */ #define DNS_STYLEFLAG_RESIGN 0x04000000U /*% Don't printout the cryptographic parts of DNSSEC records. */ #define DNS_STYLEFLAG_NOCRYPTO 0x08000000U /*% Comment out data by prepending with ";" */ #define DNS_STYLEFLAG_COMMENTDATA 0x10000000U ISC_LANG_BEGINDECLS /*** *** Constants ***/ /*% * The default master file style. * * This uses $TTL directives to avoid the need to dedicate a * tab stop for the TTL. The class is only printed for the first * rrset in the file and shares a tab stop with the RR type. */ LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_default; /*% * A master file style that dumps zones to a very generic format easily * imported/checked with external tools. */ LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_full; /*% * A master file style that prints explicit TTL values on each * record line, never using $TTL statements. The TTL has a tab * stop of its own, but the class and type share one. */ LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_explicitttl; /*% * A master style format designed for cache files. It prints explicit TTL * values on each record line and never uses $ORIGIN or relative names. */ LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_cache; /*% * A master style that prints name, ttl, class, type, and value on * every line. Similar to explicitttl above, but more verbose. * Intended for generating master files which can be easily parsed * by perl scripts and similar applications. */ LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_simple; /*% * The style used for debugging, "dig" output, etc. */ LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_debug; /*% * Similar to dns_master_style_debug but data is prepended with ";" */ LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_comment; /*% * The style used for dumping "key" zones. */ LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_keyzone; /*** *** Functions ***/ void dns_dumpctx_attach(dns_dumpctx_t *source, dns_dumpctx_t **target); /*%< * Attach to a dump context. * * Require: *\li 'source' to be valid. *\li 'target' to be non NULL and '*target' to be NULL. */ void dns_dumpctx_detach(dns_dumpctx_t **dctxp); /*%< * Detach from a dump context. * * Require: *\li 'dctxp' to point to a valid dump context. * * Ensures: *\li '*dctxp' is NULL. */ void dns_dumpctx_cancel(dns_dumpctx_t *dctx); /*%< * Cancel a in progress dump. * * Require: *\li 'dctx' to be valid. */ dns_dbversion_t * dns_dumpctx_version(dns_dumpctx_t *dctx); /*%< * Return the version handle (if any) of the database being dumped. * * Require: *\li 'dctx' to be valid. */ dns_db_t * dns_dumpctx_db(dns_dumpctx_t *dctx); /*%< * Return the database being dumped. * * Require: *\li 'dctx' to be valid. */ /*@{*/ isc_result_t dns_master_dumptostreaminc(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, FILE *f, isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, dns_dumpctx_t **dctxp); isc_result_t dns_master_dumptostream(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, FILE *f); isc_result_t dns_master_dumptostream2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, dns_masterformat_t format, FILE *f); isc_result_t dns_master_dumptostream3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, dns_masterformat_t format, dns_masterrawheader_t *header, FILE *f); /*%< * Dump the database 'db' to the steam 'f' in the specified format by * 'format'. If the format is dns_masterformat_text (the RFC1035 format), * 'style' specifies the file style (e.g., &dns_master_style_default). * * dns_master_dumptostream() is an old form of dns_master_dumptostream3(), * which always specifies the dns_masterformat_text format. * dns_master_dumptostream2() is an old form which always specifies * a NULL header. * * If 'format' is dns_masterformat_raw, then 'header' can contain * information to be written to the file header. * * Temporary dynamic memory may be allocated from 'mctx'. * * Require: *\li 'task' to be valid. *\li 'done' to be non NULL. *\li 'dctxp' to be non NULL && '*dctxp' to be NULL. * * Returns: *\li ISC_R_SUCCESS *\li ISC_R_CONTINUE dns_master_dumptostreaminc() only. *\li ISC_R_NOMEMORY *\li Any database or rrset iterator error. *\li Any dns_rdata_totext() error code. */ /*@}*/ /*@{*/ isc_result_t dns_master_dumpinc(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, const char *filename, isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, dns_dumpctx_t **dctxp); isc_result_t dns_master_dumpinc2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, const char *filename, isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, dns_dumpctx_t **dctxp, dns_masterformat_t format); isc_result_t dns_master_dumpinc3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, const char *filename, isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, dns_dumpctx_t **dctxp, dns_masterformat_t format, dns_masterrawheader_t *header); isc_result_t dns_master_dump(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, const char *filename); isc_result_t dns_master_dump2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, const char *filename, dns_masterformat_t format); isc_result_t dns_master_dump3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, const char *filename, dns_masterformat_t format, dns_masterrawheader_t *header); /*%< * Dump the database 'db' to the file 'filename' in the specified format by * 'format'. If the format is dns_masterformat_text (the RFC1035 format), * 'style' specifies the file style (e.g., &dns_master_style_default). * * dns_master_dumpinc() and dns_master_dump() are old forms of _dumpinc3() * and _dump3(), respectively, which always specify the dns_masterformat_text * format. dns_master_dumpinc2() and dns_master_dump2() are old forms which * always specify a NULL header. * * If 'format' is dns_masterformat_raw, then 'header' can contain * information to be written to the file header. * * Temporary dynamic memory may be allocated from 'mctx'. * * Returns: *\li ISC_R_SUCCESS *\li ISC_R_CONTINUE dns_master_dumpinc() only. *\li ISC_R_NOMEMORY *\li Any database or rrset iterator error. *\li Any dns_rdata_totext() error code. */ /*@}*/ isc_result_t dns_master_rdatasettotext(dns_name_t *owner_name, dns_rdataset_t *rdataset, const dns_master_style_t *style, isc_buffer_t *target); /*%< * Convert 'rdataset' to text format, storing the result in 'target'. * * Notes: *\li The rdata cursor position will be changed. * * Requires: *\li 'rdataset' is a valid non-question rdataset. * *\li 'rdataset' is not empty. */ isc_result_t dns_master_questiontotext(dns_name_t *owner_name, dns_rdataset_t *rdataset, const dns_master_style_t *style, isc_buffer_t *target); isc_result_t dns_master_dumpnodetostream(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, dns_name_t *name, const dns_master_style_t *style, FILE *f); isc_result_t dns_master_dumpnode(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, dns_name_t *name, const dns_master_style_t *style, const char *filename); isc_result_t dns_master_stylecreate(dns_master_style_t **style, unsigned int flags, unsigned int ttl_column, unsigned int class_column, unsigned int type_column, unsigned int rdata_column, unsigned int line_length, unsigned int tab_width, isc_mem_t *mctx); isc_result_t dns_master_stylecreate2(dns_master_style_t **style, unsigned int flags, unsigned int ttl_column, unsigned int class_column, unsigned int type_column, unsigned int rdata_column, unsigned int line_length, unsigned int tab_width, unsigned int split_width, isc_mem_t *mctx); void dns_master_styledestroy(dns_master_style_t **style, isc_mem_t *mctx); ISC_LANG_ENDDECLS #endif /* DNS_MASTERDUMP_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/acache.h0000644000470500017500000003463512664710322020522 0ustar lamontlamont/* * Copyright (C) 2004, 2006, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: acache.h,v 1.8 2007/06/19 23:47:16 tbox Exp $ */ #ifndef DNS_ACACHE_H #define DNS_ACACHE_H 1 /***** ***** Module Info *****/ /* * Acache * * The Additional Cache Object * * This module manages internal caching entries that correspond to * the additional section data of a DNS DB node (an RRset header, more * accurately). An additional cache entry is expected to be (somehow) * attached to a particular RR in a particular DB node, and contains a set * of information of an additional data for the DB node. * * An additional cache object is intended to be created as a per-view * object, and manages all cache entries within the view. * * The intended usage of the additional caching is to provide a short cut * to additional glue RRs of an NS RR. For each NS RR, it is often * necessary to look for glue RRs to make a proper response. Once the * glue RRs are known, the additional caching allows the client to * associate the information to the original NS RR so that further * expensive lookups can be avoided for the NS RR. * * Each additional cache entry contains information to identify a * particular DB node and (optionally) an associated RRset. The * information consists of its zone, database, the version of the * database, database node, and RRset. * * A "negative" information can also be cached. For example, if a glue * RR does not exist as an authoritative data in the same zone as that * of the NS RR, this fact can be cached by specifying a NULL pointer * for the database, version, and node. (See the description for * dns_acache_getentry() below for more details.) * * Since each member stored in an additional cache entry holds a reference * to a corresponding object, a stale cache entry may cause unnecessary * memory consumption. For instance, when a zone is reloaded, additional * cache entries that have a reference to the zone (and its DB and/or * DB nodes) can delay the cleanup of the referred objects. In order to * minimize such a bad effect, this module provides several cleanup * mechanisms. * * The first one is a shutdown procedure called when the associated view * is shut down. In this case, dns_acache_shutdown() will be called and * all cache entries will be purged. This mechanism will help the * situation when the configuration is reloaded or the main server is * stopped. * * Per-DB cleanup mechanism is also provided. Each additional cache entry * is associated with related DB, which is expected to have been * registered when the DB was created by dns_acache_setdb(). If a * particular DB is going to be destroyed, the primary holder of the DB, * a typical example of which is a zone, will call dns_acache_putdb(). * Then this module will clean-up all cache entries associated with the * DB. This mechanism is effective when a secondary zone DB is going to * be stale after a zone transfer. * * Finally, this module supports for periodic clean-up of stale entries. * Each cache entry has a timestamp field, which is updated every time * the entry is referred. A periodically invoked cleaner checks the * timestamp of each entry, and purge entries that have not been referred * for a certain period. The cleaner interval can be specified by * dns_acache_setcleaninginterval(). If the periodic clean-up is not * enough, it is also possible to specify the upper limit of entries * in terms of the memory consumption. If the maximum value is * specified, the cleaner is invoked when the memory consumption reaches * the high watermark inferred from the maximum value. In this case, * the cleaner will use more aggressive algorithm to decide the "victim" * entries. The maximum value can be specified by * dns_acache_setcachesize(). * * When a cache entry is going to be purged within this module, the * callback function specified at the creation time will be called. * The callback function is expected to release all internal resources * related to the entry, which will typically be specific to DB * implementation, and to call dns_acache_detachentry(). The callback * mechanism is very important, since the holder of an additional cache * entry may not be able to initiate the clean-up of the entry, due to * the reference ordering. For example, as long as an additional cache * entry has a reference to a DB object, the DB cannot be freed, in which * a DB node may have a reference to the cache entry. * * Credits: * The basic idea of this kind of short-cut for frequently used * information is similar to the "pre-compiled answer" approach adopted * in nsd by NLnet LABS with RIPE NCC. Our work here is an independent * effort, but the success of nsd encouraged us to pursue this path. * * The design and implementation of the periodic memory management and * the upper limitation of memory consumption was derived from the cache * DB implementation of BIND9. * * MP: * There are two main locks in this module. One is for each entry, and * the other is for the additional cache object. * * Reliability: * The callback function for a cache entry is called with holding the * entry lock. Thus, it implicitly assumes the callback function does not * call a function that can require the lock. Typically, the only * function that can be called from the callback function safely is * dns_acache_detachentry(). The breakage of this implicit assumption * may cause a deadlock. * * Resources: * In a 32-bit architecture (such as i386), the following additional * memory is required comparing to the case that disables this module. * - 76 bytes for each additional cache entry * - if the entry has a DNS name and associated RRset, * * 44 bytes + size of the name (1-255 bytes) * * 52 bytes x number_of_RRs * - 28 bytes for each DB related to this module * * Using the additional cache also requires extra memory consumption in * the DB implementation. In the current implementation for rbtdb, we * need: * - two additional pointers for each DB node (8 bytes for a 32-bit * architecture * - for each RR associated to an RR in a DB node, we also need * a pointer and management objects to support the additional cache * function. These are allocated on-demand. The total size is * 32 bytes for a 32-bit architecture. * * Security: * Since this module does not handle any low-level data directly, * no security issue specific to this module is anticipated. * * Standards: * None. */ /*** *** Imports ***/ #include #include #include #include #include /*** *** Functions ***/ ISC_LANG_BEGINDECLS isc_result_t dns_acache_create(dns_acache_t **acachep, isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr); /* * Create a new DNS additional cache object. * * Requires: * * 'mctx' is a valid memory context * * 'taskmgr' is a valid task manager * * 'timermgr' is a valid timer or NULL. If NULL, no periodic cleaning of * the cache will take place. * * 'acachep' is a valid pointer, and *acachep == NULL * * Ensures: * * '*acachep' is attached to the newly created cache * * Returns: * * ISC_R_SUCCESS * ISC_R_NOMEMORY * ISC_R_UNEXPECTED */ void dns_acache_attach(dns_acache_t *source, dns_acache_t **targetp); /* * Attach *targetp to cache. * * Requires: * * 'acache' is a valid additional cache. * * 'targetp' points to a NULL dns_acache_t *. * * Ensures: * * *targetp is attached to the 'source' additional cache. */ void dns_acache_detach(dns_acache_t **acachep); /* * Detach *acachep from its cache. * * Requires: * * '*acachep' points to a valid additional cache. * * Ensures: * * *acachep is NULL. * * If '*acachep' is the last reference to the cache and the additional * cache does not have an outstanding task, all resources used by the * cache will be freed. */ void dns_acache_setcleaninginterval(dns_acache_t *acache, unsigned int t); /* * Set the periodic cleaning interval of an additional cache to 'interval' * seconds. */ void dns_acache_setcachesize(dns_acache_t *acache, size_t size); /* * Set the maximum additional cache size. 0 means unlimited. */ isc_result_t dns_acache_setdb(dns_acache_t *acache, dns_db_t *db); /* * Set 'db' in 'acache' when the db can be referred from acache, in order * to provide a hint for resolving the back reference. * * Requires: * 'acache' is a valid acache pointer. * 'db' is a valid DNS DB pointer. * * Ensures: * 'acache' will have a reference to 'db'. * * Returns: * ISC_R_SUCCESS * ISC_R_EXISTS (which means the specified 'db' is already set) * ISC_R_NOMEMORY */ isc_result_t dns_acache_putdb(dns_acache_t *acache, dns_db_t *db); /* * Release 'db' from 'acache' if it has been set by dns_acache_setdb(). * * Requires: * 'acache' is a valid acache pointer. * 'db' is a valid DNS DB pointer. * * Ensures: * 'acache' will release the reference to 'db'. Additionally, the content * of each cache entry that is related to the 'db' will be released via * the callback function. * * Returns: * ISC_R_SUCCESS * ISC_R_NOTFOUND (which means the specified 'db' is not set in 'acache') * ISC_R_NOMEMORY */ void dns_acache_shutdown(dns_acache_t *acache); /* * Shutdown 'acache'. * * Requires: * * '*acache' is a valid additional cache. */ isc_result_t dns_acache_createentry(dns_acache_t *acache, dns_db_t *origdb, void (*callback)(dns_acacheentry_t *, void **), void *cbarg, dns_acacheentry_t **entryp); /* * Create an additional cache entry. A new entry is created and attached to * the given additional cache object. A callback function is also associated * with the created entry, which will be called when the cache entry is purged * for some reason. * * Requires: * * 'acache' is a valid additional cache. * 'entryp' is a valid pointer, and *entryp == NULL * 'origdb' is a valid DNS DB pointer. * 'callback' and 'cbarg' can be NULL. In this case, however, the entry * is meaningless (and will be cleaned-up in the next periodical * cleaning). * * Ensures: * '*entryp' will point to a new additional cache entry. * * Returns: * ISC_R_SUCCESS * ISC_R_NOMEMORY */ isc_result_t dns_acache_getentry(dns_acacheentry_t *entry, dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp, dns_dbnode_t **nodep, dns_name_t *fname, dns_message_t *msg, isc_stdtime_t now); /* * Get content from a particular additional cache entry. * * Requires: * * 'entry' is a valid additional cache entry. * 'zonep' is a NULL pointer or '*zonep' == NULL (this is the only * optional parameter.) * 'dbp' is a valid pointer, and '*dbp' == NULL * 'versionp' is a valid pointer, and '*versionp' == NULL * 'nodep' is a valid pointer, and '*nodep' == NULL * 'fname' is a valid DNS name. * 'msg' is a valid DNS message. * * Ensures: * Several possible cases can happen according to the content. * 1. For a positive cache entry, * '*zonep' will point to the corresponding zone (if zonep is a valid * pointer), * '*dbp' will point to a DB for the zone, * '*versionp' will point to its version, and * '*nodep' will point to the corresponding DB node. * 'fname' will have the DNS name of the DB node and contain a list of * rdataset for the node (which can be an empty list). * * 2. For a negative cache entry that means no corresponding zone exists, * '*zonep' == NULL (if zonep is a valid pointer) * '*dbp', '*versionp', and '*nodep' will be NULL. * * 3. For a negative cache entry that means no corresponding DB node * exists, '*zonep' will point to the corresponding zone (if zonep is a * valid pointer), * '*dbp' will point to a corresponding DB for zone, * '*versionp' will point to its version. * '*nodep' will be kept as NULL. * 'fname' will not change. * * On failure, no new references will be created. * * Returns: * ISC_R_SUCCESS * ISC_R_NOMEMORY */ isc_result_t dns_acache_setentry(dns_acache_t *acache, dns_acacheentry_t *entry, dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, dns_name_t *fname); /* * Set content to a particular additional cache entry. * * Requires: * 'acache' is a valid additional cache. * 'entry' is a valid additional cache entry. * All the others pointers are NULL or a valid pointer of the * corresponding type. * * Returns: * ISC_R_SUCCESS * ISC_R_NOMEMORY * ISC_R_NOTFOUND */ isc_boolean_t dns_acache_cancelentry(dns_acacheentry_t *entry); /* * Cancel the use of the cache entry 'entry'. This function is supposed to * be called when the node that holds the entry finds the content is not * correct any more. This function will try to release as much dependency as * possible, and will be ready to be cleaned-up. The registered callback * function will be canceled and will never called. * * Requires: * 'entry' is a valid additional cache entry. * * Returns: * ISC_TRUE if the entry was active when canceled */ void dns_acache_attachentry(dns_acacheentry_t *source, dns_acacheentry_t **targetp); /* * Attach *targetp to the cache entry 'source'. * * Requires: * * 'source' is a valid additional cache entry. * * 'targetp' points to a NULL dns_acacheentry_t *. * * Ensures: * * *targetp is attached to 'source'. */ void dns_acache_detachentry(dns_acacheentry_t **entryp); /* * Detach *entryp from its cache. * * Requires: * * '*entryp' points to a valid additional cache entry. * * Ensures: * * *entryp is NULL. * * If '*entryp' is the last reference to the entry, * cache does not have an outstanding task, all resources used by the * entry (including the entry object itself) will be freed. */ void dns_acache_countquerymiss(dns_acache_t *acache); /* * Count up a missed acache query. XXXMLG need more docs. */ ISC_LANG_ENDDECLS #endif /* DNS_ACACHE_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/result.h0000644000470500017500000002116012664710322020621 0ustar lamontlamont/* * Copyright (C) 2004-2013, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: result.h,v 1.123 2011/03/21 07:22:14 each Exp $ */ #ifndef DNS_RESULT_H #define DNS_RESULT_H 1 /*! \file dns/result.h */ #include #include #include /* * Nothing in this file truly depends on , but the * DNS result codes are considered to be publicly derived from * the ISC result codes, so including this file buys you the ISC_R_ * namespace too. */ #include /* Contractual promise. */ /* * DNS library result codes */ #define DNS_R_LABELTOOLONG (ISC_RESULTCLASS_DNS + 0) #define DNS_R_BADESCAPE (ISC_RESULTCLASS_DNS + 1) /* * Since we dropped the support of bitstring labels, deprecate the related * result codes too. #define DNS_R_BADBITSTRING (ISC_RESULTCLASS_DNS + 2) #define DNS_R_BITSTRINGTOOLONG (ISC_RESULTCLASS_DNS + 3) */ #define DNS_R_EMPTYLABEL (ISC_RESULTCLASS_DNS + 4) #define DNS_R_BADDOTTEDQUAD (ISC_RESULTCLASS_DNS + 5) #define DNS_R_INVALIDNS (ISC_RESULTCLASS_DNS + 6) #define DNS_R_UNKNOWN (ISC_RESULTCLASS_DNS + 7) #define DNS_R_BADLABELTYPE (ISC_RESULTCLASS_DNS + 8) #define DNS_R_BADPOINTER (ISC_RESULTCLASS_DNS + 9) #define DNS_R_TOOMANYHOPS (ISC_RESULTCLASS_DNS + 10) #define DNS_R_DISALLOWED (ISC_RESULTCLASS_DNS + 11) #define DNS_R_EXTRATOKEN (ISC_RESULTCLASS_DNS + 12) #define DNS_R_EXTRADATA (ISC_RESULTCLASS_DNS + 13) #define DNS_R_TEXTTOOLONG (ISC_RESULTCLASS_DNS + 14) #define DNS_R_NOTZONETOP (ISC_RESULTCLASS_DNS + 15) #define DNS_R_SYNTAX (ISC_RESULTCLASS_DNS + 16) #define DNS_R_BADCKSUM (ISC_RESULTCLASS_DNS + 17) #define DNS_R_BADAAAA (ISC_RESULTCLASS_DNS + 18) #define DNS_R_NOOWNER (ISC_RESULTCLASS_DNS + 19) #define DNS_R_NOTTL (ISC_RESULTCLASS_DNS + 20) #define DNS_R_BADCLASS (ISC_RESULTCLASS_DNS + 21) #define DNS_R_NAMETOOLONG (ISC_RESULTCLASS_DNS + 22) #define DNS_R_PARTIALMATCH (ISC_RESULTCLASS_DNS + 23) #define DNS_R_NEWORIGIN (ISC_RESULTCLASS_DNS + 24) #define DNS_R_UNCHANGED (ISC_RESULTCLASS_DNS + 25) #define DNS_R_BADTTL (ISC_RESULTCLASS_DNS + 26) #define DNS_R_NOREDATA (ISC_RESULTCLASS_DNS + 27) #define DNS_R_CONTINUE (ISC_RESULTCLASS_DNS + 28) #define DNS_R_DELEGATION (ISC_RESULTCLASS_DNS + 29) #define DNS_R_GLUE (ISC_RESULTCLASS_DNS + 30) #define DNS_R_DNAME (ISC_RESULTCLASS_DNS + 31) #define DNS_R_CNAME (ISC_RESULTCLASS_DNS + 32) #define DNS_R_BADDB (ISC_RESULTCLASS_DNS + 33) #define DNS_R_ZONECUT (ISC_RESULTCLASS_DNS + 34) #define DNS_R_BADZONE (ISC_RESULTCLASS_DNS + 35) #define DNS_R_MOREDATA (ISC_RESULTCLASS_DNS + 36) #define DNS_R_UPTODATE (ISC_RESULTCLASS_DNS + 37) #define DNS_R_TSIGVERIFYFAILURE (ISC_RESULTCLASS_DNS + 38) #define DNS_R_TSIGERRORSET (ISC_RESULTCLASS_DNS + 39) #define DNS_R_SIGINVALID (ISC_RESULTCLASS_DNS + 40) #define DNS_R_SIGEXPIRED (ISC_RESULTCLASS_DNS + 41) #define DNS_R_SIGFUTURE (ISC_RESULTCLASS_DNS + 42) #define DNS_R_KEYUNAUTHORIZED (ISC_RESULTCLASS_DNS + 43) #define DNS_R_INVALIDTIME (ISC_RESULTCLASS_DNS + 44) #define DNS_R_EXPECTEDTSIG (ISC_RESULTCLASS_DNS + 45) #define DNS_R_UNEXPECTEDTSIG (ISC_RESULTCLASS_DNS + 46) #define DNS_R_INVALIDTKEY (ISC_RESULTCLASS_DNS + 47) #define DNS_R_HINT (ISC_RESULTCLASS_DNS + 48) #define DNS_R_DROP (ISC_RESULTCLASS_DNS + 49) #define DNS_R_NOTLOADED (ISC_RESULTCLASS_DNS + 50) #define DNS_R_NCACHENXDOMAIN (ISC_RESULTCLASS_DNS + 51) #define DNS_R_NCACHENXRRSET (ISC_RESULTCLASS_DNS + 52) #define DNS_R_WAIT (ISC_RESULTCLASS_DNS + 53) #define DNS_R_NOTVERIFIEDYET (ISC_RESULTCLASS_DNS + 54) #define DNS_R_NOIDENTITY (ISC_RESULTCLASS_DNS + 55) #define DNS_R_NOJOURNAL (ISC_RESULTCLASS_DNS + 56) #define DNS_R_ALIAS (ISC_RESULTCLASS_DNS + 57) #define DNS_R_USETCP (ISC_RESULTCLASS_DNS + 58) #define DNS_R_NOVALIDSIG (ISC_RESULTCLASS_DNS + 59) #define DNS_R_NOVALIDNSEC (ISC_RESULTCLASS_DNS + 60) #define DNS_R_NOTINSECURE (ISC_RESULTCLASS_DNS + 61) #define DNS_R_UNKNOWNSERVICE (ISC_RESULTCLASS_DNS + 62) #define DNS_R_RECOVERABLE (ISC_RESULTCLASS_DNS + 63) #define DNS_R_UNKNOWNOPT (ISC_RESULTCLASS_DNS + 64) #define DNS_R_UNEXPECTEDID (ISC_RESULTCLASS_DNS + 65) #define DNS_R_SEENINCLUDE (ISC_RESULTCLASS_DNS + 66) #define DNS_R_NOTEXACT (ISC_RESULTCLASS_DNS + 67) #define DNS_R_BLACKHOLED (ISC_RESULTCLASS_DNS + 68) #define DNS_R_BADALG (ISC_RESULTCLASS_DNS + 69) #define DNS_R_METATYPE (ISC_RESULTCLASS_DNS + 70) #define DNS_R_CNAMEANDOTHER (ISC_RESULTCLASS_DNS + 71) #define DNS_R_SINGLETON (ISC_RESULTCLASS_DNS + 72) #define DNS_R_HINTNXRRSET (ISC_RESULTCLASS_DNS + 73) #define DNS_R_NOMASTERFILE (ISC_RESULTCLASS_DNS + 74) #define DNS_R_UNKNOWNPROTO (ISC_RESULTCLASS_DNS + 75) #define DNS_R_CLOCKSKEW (ISC_RESULTCLASS_DNS + 76) #define DNS_R_BADIXFR (ISC_RESULTCLASS_DNS + 77) #define DNS_R_NOTAUTHORITATIVE (ISC_RESULTCLASS_DNS + 78) #define DNS_R_NOVALIDKEY (ISC_RESULTCLASS_DNS + 79) #define DNS_R_OBSOLETE (ISC_RESULTCLASS_DNS + 80) #define DNS_R_FROZEN (ISC_RESULTCLASS_DNS + 81) #define DNS_R_UNKNOWNFLAG (ISC_RESULTCLASS_DNS + 82) #define DNS_R_EXPECTEDRESPONSE (ISC_RESULTCLASS_DNS + 83) #define DNS_R_NOVALIDDS (ISC_RESULTCLASS_DNS + 84) #define DNS_R_NSISADDRESS (ISC_RESULTCLASS_DNS + 85) #define DNS_R_REMOTEFORMERR (ISC_RESULTCLASS_DNS + 86) #define DNS_R_TRUNCATEDTCP (ISC_RESULTCLASS_DNS + 87) #define DNS_R_LAME (ISC_RESULTCLASS_DNS + 88) #define DNS_R_UNEXPECTEDRCODE (ISC_RESULTCLASS_DNS + 89) #define DNS_R_UNEXPECTEDOPCODE (ISC_RESULTCLASS_DNS + 90) #define DNS_R_CHASEDSSERVERS (ISC_RESULTCLASS_DNS + 91) #define DNS_R_EMPTYNAME (ISC_RESULTCLASS_DNS + 92) #define DNS_R_EMPTYWILD (ISC_RESULTCLASS_DNS + 93) #define DNS_R_BADBITMAP (ISC_RESULTCLASS_DNS + 94) #define DNS_R_FROMWILDCARD (ISC_RESULTCLASS_DNS + 95) #define DNS_R_BADOWNERNAME (ISC_RESULTCLASS_DNS + 96) #define DNS_R_BADNAME (ISC_RESULTCLASS_DNS + 97) #define DNS_R_DYNAMIC (ISC_RESULTCLASS_DNS + 98) #define DNS_R_UNKNOWNCOMMAND (ISC_RESULTCLASS_DNS + 99) #define DNS_R_MUSTBESECURE (ISC_RESULTCLASS_DNS + 100) #define DNS_R_COVERINGNSEC (ISC_RESULTCLASS_DNS + 101) #define DNS_R_MXISADDRESS (ISC_RESULTCLASS_DNS + 102) #define DNS_R_DUPLICATE (ISC_RESULTCLASS_DNS + 103) #define DNS_R_INVALIDNSEC3 (ISC_RESULTCLASS_DNS + 104) #define DNS_R_NOTMASTER (ISC_RESULTCLASS_DNS + 105) #define DNS_R_BROKENCHAIN (ISC_RESULTCLASS_DNS + 106) #define DNS_R_EXPIRED (ISC_RESULTCLASS_DNS + 107) #define DNS_R_NOTDYNAMIC (ISC_RESULTCLASS_DNS + 108) #define DNS_R_BADEUI (ISC_RESULTCLASS_DNS + 109) #define DNS_R_NTACOVERED (ISC_RESULTCLASS_DNS + 110) #define DNS_R_BADCDS (ISC_RESULTCLASS_DNS + 111) #define DNS_R_BADCDNSKEY (ISC_RESULTCLASS_DNS + 112) #define DNS_R_OPTERR (ISC_RESULTCLASS_DNS + 113) #define DNS_R_NRESULTS 114 /*%< Number of results */ /* * DNS wire format rcodes. * * By making these their own class we can easily convert them into the * wire-format rcode value simply by masking off the resultclass. */ #define DNS_R_NOERROR (ISC_RESULTCLASS_DNSRCODE + 0) #define DNS_R_FORMERR (ISC_RESULTCLASS_DNSRCODE + 1) #define DNS_R_SERVFAIL (ISC_RESULTCLASS_DNSRCODE + 2) #define DNS_R_NXDOMAIN (ISC_RESULTCLASS_DNSRCODE + 3) #define DNS_R_NOTIMP (ISC_RESULTCLASS_DNSRCODE + 4) #define DNS_R_REFUSED (ISC_RESULTCLASS_DNSRCODE + 5) #define DNS_R_YXDOMAIN (ISC_RESULTCLASS_DNSRCODE + 6) #define DNS_R_YXRRSET (ISC_RESULTCLASS_DNSRCODE + 7) #define DNS_R_NXRRSET (ISC_RESULTCLASS_DNSRCODE + 8) #define DNS_R_NOTAUTH (ISC_RESULTCLASS_DNSRCODE + 9) #define DNS_R_NOTZONE (ISC_RESULTCLASS_DNSRCODE + 10) #define DNS_R_BADVERS (ISC_RESULTCLASS_DNSRCODE + 16) #define DNS_R_NRCODERESULTS 17 /*%< Number of rcode results */ #define DNS_RESULT_ISRCODE(result) \ (ISC_RESULTCLASS_INCLASS(ISC_RESULTCLASS_DNSRCODE, (result))) ISC_LANG_BEGINDECLS const char * dns_result_totext(isc_result_t); void dns_result_register(void); dns_rcode_t dns_result_torcode(isc_result_t result); ISC_LANG_ENDDECLS #endif /* DNS_RESULT_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/dns64.h0000644000470500017500000001373512664710322020252 0ustar lamontlamont/* * Copyright (C) 2010, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: dns64.h,v 1.3 2010/12/08 23:51:56 tbox Exp $ */ #ifndef DNS_DNS64_H #define DNS_DNS64_H 1 #include #include ISC_LANG_BEGINDECLS /* * dns_dns64_create() flags. */ #define DNS_DNS64_RECURSIVE_ONLY 0x01 /* If set then this record * only applies to recursive * queries. */ #define DNS_DNS64_BREAK_DNSSEC 0x02 /* If set then still perform * DNSSEC synthesis even * though the result would * fail validation. */ /* * dns_dns64_aaaaok() and dns_dns64_aaaafroma() flags. */ #define DNS_DNS64_RECURSIVE 0x01 /* Recursive query. */ #define DNS_DNS64_DNSSEC 0x02 /* DNSSEC sensitive query. */ isc_result_t dns_dns64_create(isc_mem_t *mctx, isc_netaddr_t *prefix, unsigned int prefixlen, isc_netaddr_t *suffix, dns_acl_t *client, dns_acl_t *mapped, dns_acl_t *excluded, unsigned int flags, dns_dns64_t **dns64); /* * Create a dns64 record which is used to identify the set of clients * it applies to and how to perform the DNS64 synthesis. * * 'prefix' and 'prefixlen' defined the leading bits of the AAAA records * to be synthesised. 'suffix' defines the bits after the A records bits. * If suffix is NULL zeros will be used for these bits. 'client' defines * for which clients this record applies. If 'client' is NULL then all * clients apply. 'mapped' defines which A records are candidated for * mapping. If 'mapped' is NULL then all A records will be mapped. * 'excluded' defines which AAAA are to be treated as non-existent for the * purposed of determining whether to perform syntesis. If 'excluded' is * NULL then no AAAA records prevent synthesis. * * If DNS_DNS64_RECURSIVE_ONLY is set then the record will only match if * DNS_DNS64_RECURSIVE is set when calling dns_dns64_aaaaok() and * dns_dns64_aaaafroma(). * * If DNS_DNS64_BREAK_DNSSEC is set then the record will still apply if * DNS_DNS64_DNSSEC is set when calling dns_dns64_aaaaok() and * dns_dns64_aaaafroma() otherwise the record will be ignored. * * Requires: * 'mctx' to be valid. * 'prefix' to be valid and the address family to AF_INET6. * 'prefixlen' to be one of 32, 40, 48, 56, 72 and 96. * the bits not covered by prefixlen in prefix to * be zero. * 'suffix' to be NULL or the address family be set to AF_INET6 * and the leading 'prefixlen' + 32 bits of the 'suffix' * to be zero. If 'prefixlen' is 40, 48 or 56 then the * the leading 'prefixlen' + 40 bits of 'suffix' must be * zero. * 'client' to be NULL or a valid acl. * 'mapped' to be NULL or a valid acl. * 'excluded' to be NULL or a valid acl. * * Returns: * ISC_R_SUCCESS * ISC_R_NOMEMORY */ void dns_dns64_destroy(dns_dns64_t **dns64p); /* * Destroys a dns64 record. * * Requires the record to not be linked. */ isc_result_t dns_dns64_aaaafroma(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr, const dns_name_t *reqsigner, const dns_aclenv_t *env, unsigned int flags, unsigned char *a, unsigned char *aaaa); /* * dns_dns64_aaaafroma() determines whether to perform a DNS64 address * synthesis from 'a' based on 'dns64', 'reqaddr', 'reqsigner', 'env', * 'flags' and 'aaaa'. If synthesis is performed then the result is * written to '*aaaa'. * * The synthesised address will be of the form: * * * * If straddle bits 64-71 of the AAAA record, then 8 zero bits will * be inserted at bits 64-71. * * Requires: * 'dns64' to be valid. * 'reqaddr' to be valid. * 'reqsigner' to be NULL or valid. * 'env' to be valid. * 'a' to point to a IPv4 address in network order. * 'aaaa' to point to a IPv6 address buffer in network order. * * Returns: * ISC_R_SUCCESS if synthesis was performed. * DNS_R_DISALLOWED if there is no match. */ dns_dns64_t * dns_dns64_next(dns_dns64_t *dns64); /* * Return the next dns64 record in the list. */ void dns_dns64_append(dns_dns64list_t *list, dns_dns64_t *dns64); /* * Append the dns64 record to the list. */ void dns_dns64_unlink(dns_dns64list_t *list, dns_dns64_t *dns64); /* * Unlink the dns64 record from the list. */ isc_boolean_t dns_dns64_aaaaok(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr, const dns_name_t *reqsigner, const dns_aclenv_t *env, unsigned int flags, dns_rdataset_t *rdataset, isc_boolean_t *aaaaok, size_t aaaaoklen); /* * Determine if there are any non-excluded AAAA records in from the * matching dns64 records in the list starting at 'dns64'. If there * is a non-exluded address return ISC_TRUE. If all addresses are * excluded in the matched records return ISC_FALSE. If no records * match then return ISC_TRUE. * * If aaaaok is defined then dns_dns64_aaaaok() return a array of which * addresses in 'rdataset' were deemed to not be exclude by any matching * record. If there are no matching records then all entries are set * to ISC_TRUE. * * Requires * 'rdataset' to be valid and to be for type AAAA and class IN. * 'aaaaoklen' must match the number of records in 'rdataset' * if 'aaaaok' in non NULL. */ ISC_LANG_ENDDECLS #endif /* DNS_DNS64_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/tcpmsg.h0000644000470500017500000000710112664710322020577 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: tcpmsg.h,v 1.22 2007/06/19 23:47:17 tbox Exp $ */ #ifndef DNS_TCPMSG_H #define DNS_TCPMSG_H 1 /*! \file dns/tcpmsg.h */ #include #include #include typedef struct dns_tcpmsg { /* private (don't touch!) */ unsigned int magic; isc_uint16_t size; isc_buffer_t buffer; unsigned int maxsize; isc_mem_t *mctx; isc_socket_t *sock; isc_task_t *task; isc_taskaction_t action; void *arg; isc_event_t event; /* public (read-only) */ isc_result_t result; isc_sockaddr_t address; } dns_tcpmsg_t; ISC_LANG_BEGINDECLS void dns_tcpmsg_init(isc_mem_t *mctx, isc_socket_t *sock, dns_tcpmsg_t *tcpmsg); /*%< * Associate a tcp message state with a given memory context and * TCP socket. * * Requires: * *\li "mctx" and "sock" be non-NULL and valid types. * *\li "sock" be a read/write TCP socket. * *\li "tcpmsg" be non-NULL and an uninitialized or invalidated structure. * * Ensures: * *\li "tcpmsg" is a valid structure. */ void dns_tcpmsg_setmaxsize(dns_tcpmsg_t *tcpmsg, unsigned int maxsize); /*%< * Set the maximum packet size to "maxsize" * * Requires: * *\li "tcpmsg" be valid. * *\li 512 <= "maxsize" <= 65536 */ isc_result_t dns_tcpmsg_readmessage(dns_tcpmsg_t *tcpmsg, isc_task_t *task, isc_taskaction_t action, void *arg); /*%< * Schedule an event to be delivered when a DNS message is readable, or * when an error occurs on the socket. * * Requires: * *\li "tcpmsg" be valid. * *\li "task", "taskaction", and "arg" be valid. * * Returns: * *\li ISC_R_SUCCESS -- no error *\li Anything that the isc_socket_recv() call can return. XXXMLG * * Notes: * *\li The event delivered is a fully generic event. It will contain no * actual data. The sender will be a pointer to the dns_tcpmsg_t. * The result code inside that structure should be checked to see * what the final result was. */ void dns_tcpmsg_cancelread(dns_tcpmsg_t *tcpmsg); /*%< * Cancel a readmessage() call. The event will still be posted with a * CANCELED result code. * * Requires: * *\li "tcpmsg" be valid. */ void dns_tcpmsg_keepbuffer(dns_tcpmsg_t *tcpmsg, isc_buffer_t *buffer); /*%< * If a dns buffer is to be kept between calls, this function marks the * internal state-machine buffer as invalid, and copies all the contents * of the state into "buffer". * * Requires: * *\li "tcpmsg" be valid. * *\li "buffer" be non-NULL. */ void dns_tcpmsg_invalidate(dns_tcpmsg_t *tcpmsg); /*%< * Clean up all allocated state, and invalidate the structure. * * Requires: * *\li "tcpmsg" be valid. * * Ensures: * *\li "tcpmsg" is invalidated and disassociated with all memory contexts, * sockets, etc. */ ISC_LANG_ENDDECLS #endif /* DNS_TCPMSG_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/rdatatype.h0000644000470500017500000000450312664710322021302 0ustar lamontlamont/* * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rdatatype.h,v 1.26 2008/09/25 04:02:39 tbox Exp $ */ #ifndef DNS_RDATATYPE_H #define DNS_RDATATYPE_H 1 /*! \file dns/rdatatype.h */ #include #include ISC_LANG_BEGINDECLS isc_result_t dns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source); /*%< * Convert the text 'source' refers to into a DNS rdata type. * * Requires: *\li 'typep' is a valid pointer. * *\li 'source' is a valid text region. * * Returns: *\li ISC_R_SUCCESS on success *\li DNS_R_UNKNOWN type is unknown */ isc_result_t dns_rdatatype_totext(dns_rdatatype_t type, isc_buffer_t *target); /*%< * Put a textual representation of type 'type' into 'target'. * * Requires: *\li 'type' is a valid type. * *\li 'target' is a valid text buffer. * * Ensures, * if the result is success: *\li The used space in 'target' is updated. * * Returns: *\li #ISC_R_SUCCESS on success *\li #ISC_R_NOSPACE target buffer is too small */ void dns_rdatatype_format(dns_rdatatype_t rdtype, char *array, unsigned int size); /*%< * Format a human-readable representation of the type 'rdtype' * into the character array 'array', which is of size 'size'. * The resulting string is guaranteed to be null-terminated. */ #define DNS_RDATATYPE_FORMATSIZE sizeof("NSEC3PARAM") /*%< * Minimum size of array to pass to dns_rdatatype_format(). * May need to be adjusted if a new RR type with a very long * name is defined. */ ISC_LANG_ENDDECLS #endif /* DNS_RDATATYPE_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/time.h0000644000470500017500000000425712664710322020251 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: time.h,v 1.19 2012/01/27 23:46:58 tbox Exp $ */ #ifndef DNS_TIME_H #define DNS_TIME_H 1 /*! \file dns/time.h */ /*** *** Imports ***/ #include #include ISC_LANG_BEGINDECLS /*** *** Functions ***/ isc_result_t dns_time64_fromtext(const char *source, isc_int64_t *target); /*%< * Convert a date and time in YYYYMMDDHHMMSS text format at 'source' * into to a 64-bit count of seconds since Jan 1 1970 0:00 GMT. * Store the count at 'target'. */ isc_result_t dns_time32_fromtext(const char *source, isc_uint32_t *target); /*%< * Like dns_time64_fromtext, but returns the second count modulo 2^32 * as per RFC2535. */ isc_result_t dns_time64_totext(isc_int64_t value, isc_buffer_t *target); /*%< * Convert a 64-bit count of seconds since Jan 1 1970 0:00 GMT into * a YYYYMMDDHHMMSS text representation and append it to 'target'. */ isc_result_t dns_time32_totext(isc_uint32_t value, isc_buffer_t *target); /*%< * Like dns_time64_totext, but for a 32-bit cyclic time value. * Of those dates whose counts of seconds since Jan 1 1970 0:00 GMT * are congruent with 'value' modulo 2^32, the one closest to the * current date is chosen. */ isc_int64_t dns_time64_from32(isc_uint32_t value); /*%< * Covert a 32-bit cyclic time value into a 64 bit time stamp. */ ISC_LANG_ENDDECLS #endif /* DNS_TIME_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/keydata.h0000644000470500017500000000274412664710322020734 0ustar lamontlamont/* * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: keydata.h,v 1.2 2009/06/30 02:52:32 each Exp $ */ #ifndef DNS_KEYDATA_H #define DNS_KEYDATA_H 1 /***** ***** Module Info *****/ /*! \file dns/keydata.h * \brief * KEYDATA utilities. */ /*** *** Imports ***/ #include #include #include #include ISC_LANG_BEGINDECLS isc_result_t dns_keydata_todnskey(dns_rdata_keydata_t *keydata, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx); isc_result_t dns_keydata_fromdnskey(dns_rdata_keydata_t *keydata, dns_rdata_dnskey_t *dnskey, isc_uint32_t refresh, isc_uint32_t addhd, isc_uint32_t removehd, isc_mem_t *mctx); ISC_LANG_ENDDECLS #endif /* DNS_KEYDATA_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/view.h0000644000470500017500000007614412664710322020271 0ustar lamontlamont/* * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef DNS_VIEW_H #define DNS_VIEW_H 1 /***** ***** Module Info *****/ /*! \file dns/view.h * \brief * DNS View * * A "view" is a DNS namespace, together with an optional resolver and a * forwarding policy. A "DNS namespace" is a (possibly empty) set of * authoritative zones together with an optional cache and optional * "hints" information. * * Views start out "unfrozen". In this state, core attributes like * the cache, set of zones, and forwarding policy may be set. While * "unfrozen", the caller (e.g. nameserver configuration loading * code), must ensure exclusive access to the view. When the view is * "frozen", the core attributes become immutable, and the view module * will ensure synchronization. Freezing allows the view's core attributes * to be accessed without locking. * * MP: *\li Before the view is frozen, the caller must ensure synchronization. * *\li After the view is frozen, the module guarantees appropriate * synchronization of any data structures it creates and manipulates. * * Reliability: *\li No anticipated impact. * * Resources: *\li TBS * * Security: *\li No anticipated impact. * * Standards: *\li None. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include ISC_LANG_BEGINDECLS struct dns_view { /* Unlocked. */ unsigned int magic; isc_mem_t * mctx; dns_rdataclass_t rdclass; char * name; dns_zt_t * zonetable; dns_resolver_t * resolver; dns_adb_t * adb; dns_requestmgr_t * requestmgr; dns_acache_t * acache; dns_cache_t * cache; dns_db_t * cachedb; dns_db_t * hints; /* * security roots. * internal use only; access via * dns_view_getsecroots() */ dns_keytable_t * secroots_priv; isc_mutex_t lock; isc_boolean_t frozen; isc_task_t * task; isc_event_t resevent; isc_event_t adbevent; isc_event_t reqevent; isc_stats_t * adbstats; isc_stats_t * resstats; dns_stats_t * resquerystats; isc_boolean_t cacheshared; /* Configurable data. */ dns_tsig_keyring_t * statickeys; dns_tsig_keyring_t * dynamickeys; dns_peerlist_t * peers; dns_order_t * order; dns_fwdtable_t * fwdtable; isc_boolean_t recursion; isc_boolean_t auth_nxdomain; isc_boolean_t additionalfromcache; isc_boolean_t additionalfromauth; isc_boolean_t minimalresponses; isc_boolean_t enablednssec; isc_boolean_t enablevalidation; isc_boolean_t acceptexpired; dns_transfer_format_t transfer_format; dns_acl_t * cacheacl; dns_acl_t * cacheonacl; dns_acl_t * queryacl; dns_acl_t * queryonacl; dns_acl_t * recursionacl; dns_acl_t * recursiononacl; dns_acl_t * sortlist; dns_acl_t * notifyacl; dns_acl_t * transferacl; dns_acl_t * updateacl; dns_acl_t * upfwdacl; dns_acl_t * denyansweracl; dns_acl_t * nocasecompress; dns_rbt_t * answeracl_exclude; dns_rbt_t * denyanswernames; dns_rbt_t * answernames_exclude; dns_rrl_t * rrl; isc_boolean_t provideixfr; isc_boolean_t requestnsid; isc_boolean_t requestsit; dns_ttl_t maxcachettl; dns_ttl_t maxncachettl; dns_ttl_t prefetch_trigger; dns_ttl_t prefetch_eligible; in_port_t dstport; dns_aclenv_t aclenv; dns_rdatatype_t preferred_glue; isc_boolean_t flush; dns_namelist_t * delonly; isc_boolean_t rootdelonly; dns_namelist_t * rootexclude; isc_boolean_t checknames; dns_name_t * dlv; dns_fixedname_t dlv_fixed; isc_uint16_t maxudp; isc_uint16_t situdp; unsigned int maxbits; dns_aaaa_t v4_aaaa; dns_aaaa_t v6_aaaa; dns_acl_t * aaaa_acl; dns_dns64list_t dns64; unsigned int dns64cnt; dns_rpz_zones_t *rpzs; dns_dlzdblist_t dlz_searched; dns_dlzdblist_t dlz_unsearched; /* * Configurable data for server use only, * locked by server configuration lock. */ dns_acl_t * matchclients; dns_acl_t * matchdestinations; isc_boolean_t matchrecursiveonly; /* Locked by themselves. */ isc_refcount_t references; /* Locked by lock. */ unsigned int weakrefs; unsigned int attributes; /* Under owner's locking control. */ ISC_LINK(struct dns_view) link; dns_viewlist_t * viewlist; dns_zone_t * managed_keys; dns_zone_t * redirect; /* * File and configuration data for zones added at runtime * (only used in BIND9). * * XXX: This should be a pointer to an opaque type that * named implements. */ char * new_zone_file; void * new_zone_config; void (*cfg_destroy)(void **); unsigned char secret[32]; /* Client secret */ }; #define DNS_VIEW_MAGIC ISC_MAGIC('V','i','e','w') #define DNS_VIEW_VALID(view) ISC_MAGIC_VALID(view, DNS_VIEW_MAGIC) #define DNS_VIEWATTR_RESSHUTDOWN 0x01 #define DNS_VIEWATTR_ADBSHUTDOWN 0x02 #define DNS_VIEWATTR_REQSHUTDOWN 0x04 isc_result_t dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, const char *name, dns_view_t **viewp); /*%< * Create a view. * * Notes: * *\li The newly created view has no cache, no resolver, and an empty * zone table. The view is not frozen. * * Requires: * *\li 'mctx' is a valid memory context. * *\li 'rdclass' is a valid class. * *\li 'name' is a valid C string. * *\li viewp != NULL && *viewp == NULL * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY * *\li Other errors are possible. */ void dns_view_attach(dns_view_t *source, dns_view_t **targetp); /*%< * Attach '*targetp' to 'source'. * * Requires: * *\li 'source' is a valid, frozen view. * *\li 'targetp' points to a NULL dns_view_t *. * * Ensures: * *\li *targetp is attached to source. * *\li While *targetp is attached, the view will not shut down. */ void dns_view_detach(dns_view_t **viewp); /*%< * Detach '*viewp' from its view. * * Requires: * *\li 'viewp' points to a valid dns_view_t * * * Ensures: * *\li *viewp is NULL. */ void dns_view_flushanddetach(dns_view_t **viewp); /*%< * Detach '*viewp' from its view. If this was the last reference * uncommitted changed in zones will be flushed to disk. * * Requires: * *\li 'viewp' points to a valid dns_view_t * * * Ensures: * *\li *viewp is NULL. */ void dns_view_weakattach(dns_view_t *source, dns_view_t **targetp); /*%< * Weakly attach '*targetp' to 'source'. * * Requires: * *\li 'source' is a valid, frozen view. * *\li 'targetp' points to a NULL dns_view_t *. * * Ensures: * *\li *targetp is attached to source. * * \li While *targetp is attached, the view will not be freed. */ void dns_view_weakdetach(dns_view_t **targetp); /*%< * Detach '*viewp' from its view. * * Requires: * *\li 'viewp' points to a valid dns_view_t *. * * Ensures: * *\li *viewp is NULL. */ isc_result_t dns_view_createzonetable(dns_view_t *view); /*%< * Create a zonetable for the view. * * Requires: * *\li 'view' is a valid, unfrozen view. * *\li 'view' does not have a zonetable already. * * Returns: * *\li #ISC_R_SUCCESS * *\li Any error that dns_zt_create() can return. */ isc_result_t dns_view_createresolver(dns_view_t *view, isc_taskmgr_t *taskmgr, unsigned int ntasks, unsigned int ndisp, isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr, unsigned int options, dns_dispatchmgr_t *dispatchmgr, dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6); /*%< * Create a resolver and address database for the view. * * Requires: * *\li 'view' is a valid, unfrozen view. * *\li 'view' does not have a resolver already. * *\li The requirements of dns_resolver_create() apply to 'taskmgr', * 'ntasks', 'socketmgr', 'timermgr', 'options', 'dispatchv4', and * 'dispatchv6'. * * Returns: * *\li #ISC_R_SUCCESS * *\li Any error that dns_resolver_create() can return. */ void dns_view_setcache(dns_view_t *view, dns_cache_t *cache); void dns_view_setcache2(dns_view_t *view, dns_cache_t *cache, isc_boolean_t shared); /*%< * Set the view's cache database. If 'shared' is true, this means the cache * is created by another view and is shared with that view. dns_view_setcache() * is a backward compatible version equivalent to setcache2(..., ISC_FALSE). * * Requires: * *\li 'view' is a valid, unfrozen view. * *\li 'cache' is a valid cache. * * Ensures: * * \li The cache of 'view' is 'cached. * *\li If this is not the first call to dns_view_setcache() for this * view, then previously set cache is detached. */ void dns_view_sethints(dns_view_t *view, dns_db_t *hints); /*%< * Set the view's hints database. * * Requires: * *\li 'view' is a valid, unfrozen view, whose hints database has not been * set. * *\li 'hints' is a valid zone database. * * Ensures: * * \li The hints database of 'view' is 'hints'. */ void dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring); void dns_view_setdynamickeyring(dns_view_t *view, dns_tsig_keyring_t *ring); /*%< * Set the view's static TSIG keys * * Requires: * * \li 'view' is a valid, unfrozen view, whose static TSIG keyring has not * been set. * *\li 'ring' is a valid TSIG keyring * * Ensures: * *\li The static TSIG keyring of 'view' is 'ring'. */ void dns_view_getdynamickeyring(dns_view_t *view, dns_tsig_keyring_t **ringp); /*%< * Return the views dynamic keys. * * \li 'view' is a valid, unfrozen view. * \li 'ringp' != NULL && ringp == NULL. */ void dns_view_setdstport(dns_view_t *view, in_port_t dstport); /*%< * Set the view's destination port. This is the port to * which outgoing queries are sent. The default is 53, * the standard DNS port. * * Requires: * *\li 'view' is a valid view. * *\li 'dstport' is a valid TCP/UDP port number. * * Ensures: *\li External name servers will be assumed to be listening * on 'dstport'. For servers whose address has already * obtained obtained at the time of the call, the view may * continue to use the previously set port until the address * times out from the view's address database. */ isc_result_t dns_view_addzone(dns_view_t *view, dns_zone_t *zone); /*%< * Add zone 'zone' to 'view'. * * Requires: * *\li 'view' is a valid, unfrozen view. * *\li 'zone' is a valid zone. */ void dns_view_freeze(dns_view_t *view); /*%< * Freeze view. No changes can be made to view configuration while frozen. * * Requires: * *\li 'view' is a valid, unfrozen view. * * Ensures: * *\li 'view' is frozen. */ void dns_view_thaw(dns_view_t *view); /*%< * Thaw view. This allows zones to be added or removed at runtime. This is * NOT thread-safe; the caller MUST have run isc_task_exclusive() prior to * thawing the view. * * Requires: * *\li 'view' is a valid, frozen view. * * Ensures: * *\li 'view' is no longer frozen. */ isc_result_t dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints, dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); isc_result_t dns_view_find2(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints, isc_boolean_t use_static_stub, dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); /*%< * Find an rdataset whose owner name is 'name', and whose type is * 'type'. * In general, this function first searches view's zone and cache DBs for the * best match data against 'name'. If nothing found there, and if 'use_hints' * is ISC_TRUE, the view's hint DB (if configured) is searched. * If the view is configured with a static-stub zone which gives the longest * match for 'name' among the zones, however, the cache DB is not consulted * unless 'use_static_stub' is ISC_FALSE (see below about this argument). * * dns_view_find() is a backward compatible version equivalent to * dns_view_find2() with use_static_stub argument being ISC_FALSE. * * Notes: * *\li See the description of dns_db_find() for information about 'options'. * If the caller sets #DNS_DBFIND_GLUEOK, it must ensure that 'name' * and 'type' are appropriate for glue retrieval. * *\li If 'now' is zero, then the current time will be used. * *\li If 'use_hints' is ISC_TRUE, and the view has a hints database, then * it will be searched last. If the answer is found in the hints * database, the result code will be DNS_R_HINT. If the name is found * in the hints database but not the type, the result code will be * #DNS_R_HINTNXRRSET. * *\li If 'use_static_stub' is ISC_FALSE and the longest match zone for 'name' * is a static-stub zone, it's ignored and the cache and/or hints will be * searched. In the majority of the cases this argument should be * ISC_FALSE. The only known usage of this argument being ISC_TRUE is * if this search is for a "bailiwick" glue A or AAAA RRset that may * best match a static-stub zone. Consider the following example: * this view is configured with a static-stub zone "example.com", * and an attempt of recursive resolution needs to send a query for the * zone. In this case it's quite likely that the resolver is trying to * find A/AAAA RRs for the apex name "example.com". And, to honor the * static-stub configuration it needs to return the glue RRs in the * static-stub zone even if that exact RRs coming from the authoritative * zone has been cached. * In other general cases, the requested data is better to be * authoritative, either locally configured or retrieved from an external * server, and the data in the static-stub zone should better be ignored. * *\li 'foundname' must meet the requirements of dns_db_find(). * *\li If 'sigrdataset' is not NULL, and there is a SIG rdataset which * covers 'type', then 'sigrdataset' will be bound to it. * * Requires: * *\li 'view' is a valid, frozen view. * *\li 'name' is valid name. * *\li 'type' is a valid dns_rdatatype_t, and is not a meta query type * except dns_rdatatype_any. * *\li dbp == NULL || *dbp == NULL * *\li nodep == NULL || *nodep == NULL. If nodep != NULL, dbp != NULL. * *\li 'foundname' is a valid name with a dedicated buffer or NULL. * *\li 'rdataset' is a valid, disassociated rdataset. * *\li 'sigrdataset' is NULL, or is a valid, disassociated rdataset. * * Ensures: * *\li In successful cases, 'rdataset', and possibly 'sigrdataset', are * bound to the found data. * *\li If dbp != NULL, it points to the database containing the data. * *\li If nodep != NULL, it points to the database node containing the data. * *\li If foundname != NULL, it contains the full name of the found data. * * Returns: * *\li Any result that dns_db_find() can return, with the exception of * #DNS_R_DELEGATION. */ isc_result_t dns_view_simplefind(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); /*%< * Find an rdataset whose owner name is 'name', and whose type is * 'type'. * * Notes: * *\li This routine is appropriate for simple, exact-match queries of the * view. 'name' must be a canonical name; there is no DNAME or CNAME * processing. * *\li See the description of dns_db_find() for information about 'options'. * If the caller sets DNS_DBFIND_GLUEOK, it must ensure that 'name' * and 'type' are appropriate for glue retrieval. * *\li If 'now' is zero, then the current time will be used. * *\li If 'use_hints' is ISC_TRUE, and the view has a hints database, then * it will be searched last. If the answer is found in the hints * database, the result code will be DNS_R_HINT. If the name is found * in the hints database but not the type, the result code will be * DNS_R_HINTNXRRSET. * *\li If 'sigrdataset' is not NULL, and there is a SIG rdataset which * covers 'type', then 'sigrdataset' will be bound to it. * * Requires: * *\li 'view' is a valid, frozen view. * *\li 'name' is valid name. * *\li 'type' is a valid dns_rdatatype_t, and is not a meta query type * (e.g. dns_rdatatype_any), or dns_rdatatype_rrsig. * *\li 'rdataset' is a valid, disassociated rdataset. * *\li 'sigrdataset' is NULL, or is a valid, disassociated rdataset. * * Ensures: * *\li In successful cases, 'rdataset', and possibly 'sigrdataset', are * bound to the found data. * * Returns: * *\li #ISC_R_SUCCESS Success; result is desired type. *\li DNS_R_GLUE Success; result is glue. *\li DNS_R_HINT Success; result is a hint. *\li DNS_R_NCACHENXDOMAIN Success; result is a ncache entry. *\li DNS_R_NCACHENXRRSET Success; result is a ncache entry. *\li DNS_R_NXDOMAIN The name does not exist. *\li DNS_R_NXRRSET The rrset does not exist. *\li #ISC_R_NOTFOUND No matching data found, * or an error occurred. */ /*% See dns_view_findzonecut2() */ isc_result_t dns_view_findzonecut(dns_view_t *view, dns_name_t *name, dns_name_t *fname, isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); isc_result_t dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname, isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints, isc_boolean_t use_cache, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); /*%< * Find the best known zonecut containing 'name'. * * This uses local authority, cache, and optionally hints data. * No external queries are performed. * * Notes: * *\li If 'now' is zero, then the current time will be used. * *\li If 'use_hints' is ISC_TRUE, and the view has a hints database, then * it will be searched last. * *\li If 'use_cache' is ISC_TRUE, and the view has a cache, then it will be * searched. * *\li If 'sigrdataset' is not NULL, and there is a SIG rdataset which * covers 'type', then 'sigrdataset' will be bound to it. * *\li If the DNS_DBFIND_NOEXACT option is set, then the zonecut returned * (if any) will be the deepest known ancestor of 'name'. * * Requires: * *\li 'view' is a valid, frozen view. * *\li 'name' is valid name. * *\li 'rdataset' is a valid, disassociated rdataset. * *\li 'sigrdataset' is NULL, or is a valid, disassociated rdataset. * * Returns: * *\li #ISC_R_SUCCESS Success. * *\li Many other results are possible. */ isc_result_t dns_viewlist_find(dns_viewlist_t *list, const char *name, dns_rdataclass_t rdclass, dns_view_t **viewp); /*%< * Search for a view with name 'name' and class 'rdclass' in 'list'. * If found, '*viewp' is (strongly) attached to it. * * Requires: * *\li 'viewp' points to a NULL dns_view_t *. * * Returns: * *\li #ISC_R_SUCCESS A matching view was found. *\li #ISC_R_NOTFOUND No matching view was found. */ isc_result_t dns_viewlist_findzone(dns_viewlist_t *list, dns_name_t *name, isc_boolean_t allclasses, dns_rdataclass_t rdclass, dns_zone_t **zonep); /*%< * Search zone with 'name' in view with 'rdclass' in viewlist 'list' * If found, zone is returned in *zonep. If allclasses is set rdclass is ignored * * Returns: *\li #ISC_R_SUCCESS A matching zone was found. *\li #ISC_R_NOTFOUND No matching zone was found. *\li #ISC_R_MULTIPLE Multiple zones with the same name were found. */ isc_result_t dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep); /*%< * Search for the zone 'name' in the zone table of 'view'. * If found, 'zonep' is (strongly) attached to it. There * are no partial matches. * * Requires: * *\li 'zonep' points to a NULL dns_zone_t *. * * Returns: *\li #ISC_R_SUCCESS A matching zone was found. *\li #ISC_R_NOTFOUND No matching zone was found. *\li others An error occurred. */ isc_result_t dns_view_load(dns_view_t *view, isc_boolean_t stop); isc_result_t dns_view_loadnew(dns_view_t *view, isc_boolean_t stop); isc_result_t dns_view_asyncload(dns_view_t *view, dns_zt_allloaded_t callback, void *arg); /*%< * Load zones attached to this view. dns_view_load() loads * all zones whose master file has changed since the last * load; dns_view_loadnew() loads only zones that have never * been loaded. * * dns_view_asyncload() loads zones asynchronously. When all zones * in the view have finished loading, 'callback' is called with argument * 'arg' to inform the caller. * * If 'stop' is ISC_TRUE, stop on the first error and return it. * If 'stop' is ISC_FALSE (or we are loading asynchronously), ignore errors. * * Requires: * *\li 'view' is valid. */ isc_result_t dns_view_gettsig(dns_view_t *view, dns_name_t *keyname, dns_tsigkey_t **keyp); /*%< * Find the TSIG key configured in 'view' with name 'keyname', * if any. * * Requires: *\li keyp points to a NULL dns_tsigkey_t *. * * Returns: *\li #ISC_R_SUCCESS A key was found and '*keyp' now points to it. *\li #ISC_R_NOTFOUND No key was found. *\li others An error occurred. */ isc_result_t dns_view_getpeertsig(dns_view_t *view, isc_netaddr_t *peeraddr, dns_tsigkey_t **keyp); /*%< * Find the TSIG key configured in 'view' for the server whose * address is 'peeraddr', if any. * * Requires: * keyp points to a NULL dns_tsigkey_t *. * * Returns: *\li #ISC_R_SUCCESS A key was found and '*keyp' now points to it. *\li #ISC_R_NOTFOUND No key was found. *\li others An error occurred. */ isc_result_t dns_view_checksig(dns_view_t *view, isc_buffer_t *source, dns_message_t *msg); /*%< * Verifies the signature of a message. * * Requires: * *\li 'view' is a valid view. *\li 'source' is a valid buffer containing the message *\li 'msg' is a valid message * * Returns: *\li see dns_tsig_verify() */ void dns_view_dialup(dns_view_t *view); /*%< * Perform dialup-time maintenance on the zones of 'view'. */ isc_result_t dns_view_dumpdbtostream(dns_view_t *view, FILE *fp); /*%< * Dump the current state of the view 'view' to the stream 'fp' * for purposes of analysis or debugging. * * Currently the dumped state includes the view's cache; in the future * it may also include other state such as the address database. * It will not not include authoritative data since it is voluminous and * easily obtainable by other means. * * Requires: * *\li 'view' is valid. * *\li 'fp' refers to a file open for writing. * * Returns: * \li ISC_R_SUCCESS The cache was successfully dumped. * \li others An error occurred (see dns_master_dump) */ isc_result_t dns_view_flushcache(dns_view_t *view); isc_result_t dns_view_flushcache2(dns_view_t *view, isc_boolean_t fixuponly); /*%< * Flush the view's cache (and ADB). If 'fixuponly' is true, it only updates * the internal reference to the cache DB with omitting actual flush operation. * 'fixuponly' is intended to be used for a view that shares a cache with * a different view. dns_view_flushcache() is a backward compatible version * that always sets fixuponly to false. * * Requires: * 'view' is valid. * * No other tasks are executing. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY */ isc_result_t dns_view_flushnode(dns_view_t *view, dns_name_t *name, isc_boolean_t tree); /*%< * Flush the given name from the view's cache (and optionally ADB/badcache). * * Flush the given name from the cache, ADB, and bad cache. If 'tree' * is true, also flush all subdomains of 'name'. * * Requires: *\li 'view' is valid. *\li 'name' is valid. * * Returns: *\li #ISC_R_SUCCESS * other returns are failures. */ isc_result_t dns_view_flushname(dns_view_t *view, dns_name_t *name); /*%< * Flush the given name from the view's cache, ADB and badcache. * Equivalent to dns_view_flushnode(view, name, ISC_FALSE). * * * Requires: *\li 'view' is valid. *\li 'name' is valid. * * Returns: *\li #ISC_R_SUCCESS * other returns are failures. */ isc_result_t dns_view_adddelegationonly(dns_view_t *view, dns_name_t *name); /*%< * Add the given name to the delegation only table. * * Requires: *\li 'view' is valid. *\li 'name' is valid. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY */ isc_result_t dns_view_excludedelegationonly(dns_view_t *view, dns_name_t *name); /*%< * Add the given name to be excluded from the root-delegation-only. * * * Requires: *\li 'view' is valid. *\li 'name' is valid. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY */ isc_boolean_t dns_view_isdelegationonly(dns_view_t *view, dns_name_t *name); /*%< * Check if 'name' is in the delegation only table or if * rootdelonly is set that name is not being excluded. * * Requires: *\li 'view' is valid. *\li 'name' is valid. * * Returns: *\li #ISC_TRUE if the name is the table. *\li #ISC_FALSE otherwise. */ void dns_view_setrootdelonly(dns_view_t *view, isc_boolean_t value); /*%< * Set the root delegation only flag. * * Requires: *\li 'view' is valid. */ isc_boolean_t dns_view_getrootdelonly(dns_view_t *view); /*%< * Get the root delegation only flag. * * Requires: *\li 'view' is valid. */ isc_result_t dns_view_freezezones(dns_view_t *view, isc_boolean_t freeze); /*%< * Freeze/thaw updates to master zones. * * Requires: * \li 'view' is valid. */ void dns_view_setadbstats(dns_view_t *view, isc_stats_t *stats); /*%< * Set a adb statistics set 'stats' for 'view'. * * Requires: * \li 'view' is valid and is not frozen. * *\li stats is a valid statistics supporting adb statistics * (see dns/stats.h). */ void dns_view_getadbstats(dns_view_t *view, isc_stats_t **statsp); /*%< * Get the adb statistics counter set for 'view'. If a statistics set is * set '*statsp' will be attached to the set; otherwise, '*statsp' will be * untouched. * * Requires: * \li 'view' is valid and is not frozen. * *\li 'statsp' != NULL && '*statsp' != NULL */ void dns_view_setresstats(dns_view_t *view, isc_stats_t *stats); /*%< * Set a general resolver statistics counter set 'stats' for 'view'. * * Requires: * \li 'view' is valid and is not frozen. * *\li stats is a valid statistics supporting resolver statistics counters * (see dns/stats.h). */ void dns_view_getresstats(dns_view_t *view, isc_stats_t **statsp); /*%< * Get the general statistics counter set for 'view'. If a statistics set is * set '*statsp' will be attached to the set; otherwise, '*statsp' will be * untouched. * * Requires: * \li 'view' is valid and is not frozen. * *\li 'statsp' != NULL && '*statsp' != NULL */ void dns_view_setresquerystats(dns_view_t *view, dns_stats_t *stats); /*%< * Set a statistics counter set of rdata type, 'stats', for 'view'. Once the * statistic set is installed, view's resolver will count outgoing queries * per rdata type. * * Requires: * \li 'view' is valid and is not frozen. * *\li stats is a valid statistics created by dns_rdatatypestats_create(). */ void dns_view_getresquerystats(dns_view_t *view, dns_stats_t **statsp); /*%< * Get the rdatatype statistics counter set for 'view'. If a statistics set is * set '*statsp' will be attached to the set; otherwise, '*statsp' will be * untouched. * * Requires: * \li 'view' is valid and is not frozen. * *\li 'statsp' != NULL && '*statsp' != NULL */ isc_boolean_t dns_view_iscacheshared(dns_view_t *view); /*%< * Check if the view shares the cache created by another view. * * Requires: * \li 'view' is valid. * * Returns: *\li #ISC_TRUE if the cache is shared. *\li #ISC_FALSE otherwise. */ isc_result_t dns_view_initsecroots(dns_view_t *view, isc_mem_t *mctx); /*%< * Initialize security roots for the view. (Note that secroots is * NULL until this function is called, so any function using * secroots must check its validity first. One way to do this is * use dns_view_getsecroots() and check its return value.) * * Requires: * \li 'view' is valid. * \li 'view->secroots' is NULL. * * Returns: *\li ISC_R_SUCCESS *\li Any other result indicates failure */ isc_result_t dns_view_getsecroots(dns_view_t *view, dns_keytable_t **ktp); /*%< * Get the security roots for this view. Returns ISC_R_NOTFOUND if * the security roots keytable has not been initialized for the view. * * '*ktp' is attached on success; the caller is responsible for * detaching it with dns_keytable_detach(). * * Requires: * \li 'view' is valid. * \li 'ktp' is not NULL and '*ktp' is NULL. * * Returns: *\li ISC_R_SUCCESS *\li ISC_R_NOTFOUND */ isc_result_t dns_view_issecuredomain(dns_view_t *view, dns_name_t *name, isc_boolean_t *secure_domain); /*%< * Is 'name' at or beneath a trusted key? Put answer in * '*secure_domain'. * * Requires: * \li 'view' is valid. * * Returns: *\li ISC_R_SUCCESS *\li Any other value indicates failure */ void dns_view_untrust(dns_view_t *view, dns_name_t *keyname, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx); /*%< * Remove keys that match 'keyname' and 'dnskey' from the views trust * anchors. * * Requires: * \li 'view' is valid. * \li 'keyname' is valid. * \li 'mctx' is valid. * \li 'dnskey' is valid. */ void dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx, void (*cfg_destroy)(void **)); /*%< * Set whether or not to allow zones to be created or deleted at runtime. * * If 'allow' is ISC_TRUE, determines the filename into which new zone * configuration will be written. Preserves the configuration context * (a pointer to which is passed in 'cfgctx') for use when parsing new * zone configuration. 'cfg_destroy' points to a callback routine to * destroy the configuration context when the view is destroyed. (This * roundabout method is used in order to avoid libdns having a dependency * on libisccfg and libbind9.) * * If 'allow' is ISC_FALSE, removes any existing references to * configuration context and frees any memory. * * Requires: * \li 'view' is valid. */ void dns_view_restorekeyring(dns_view_t *view); isc_result_t dns_view_searchdlz(dns_view_t *view, dns_name_t *name, unsigned int minlabels, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, dns_db_t **dbp); /*%< * Search through the DLZ database(s) in view->dlz_searched to find * one that can answer a query for 'name', using the DLZ driver's * findzone method. If successful, '*dbp' is set to point to the * DLZ database. * * Returns: * \li ISC_R_SUCCESS * \li ISC_R_NOTFOUND * * Requires: * \li 'view' is valid. * \li 'name' is not NULL. * \li 'dbp' is not NULL and *dbp is NULL. */ ISC_LANG_ENDDECLS #endif /* DNS_VIEW_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/dbiterator.h0000644000470500017500000001727712664710322021460 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: dbiterator.h,v 1.25 2007/06/19 23:47:16 tbox Exp $ */ #ifndef DNS_DBITERATOR_H #define DNS_DBITERATOR_H 1 /***** ***** Module Info *****/ /*! \file dns/dbiterator.h * \brief * The DNS DB Iterator interface allows iteration of all of the nodes in a * database. * * The dns_dbiterator_t type is like a "virtual class". To actually use * it, an implementation of the class is required. This implementation is * supplied by the database. * * It is the client's responsibility to call dns_db_detachnode() on all * nodes returned. * * XXX <more> XXX * * MP: *\li The iterator itself is not locked. The caller must ensure * synchronization. * *\li The iterator methods ensure appropriate database locking. * * Reliability: *\li No anticipated impact. * * Resources: *\li TBS * * Security: *\li No anticipated impact. * * Standards: *\li None. */ /***** ***** Imports *****/ #include #include #include ISC_LANG_BEGINDECLS /***** ***** Types *****/ typedef struct dns_dbiteratormethods { void (*destroy)(dns_dbiterator_t **iteratorp); isc_result_t (*first)(dns_dbiterator_t *iterator); isc_result_t (*last)(dns_dbiterator_t *iterator); isc_result_t (*seek)(dns_dbiterator_t *iterator, dns_name_t *name); isc_result_t (*prev)(dns_dbiterator_t *iterator); isc_result_t (*next)(dns_dbiterator_t *iterator); isc_result_t (*current)(dns_dbiterator_t *iterator, dns_dbnode_t **nodep, dns_name_t *name); isc_result_t (*pause)(dns_dbiterator_t *iterator); isc_result_t (*origin)(dns_dbiterator_t *iterator, dns_name_t *name); } dns_dbiteratormethods_t; #define DNS_DBITERATOR_MAGIC ISC_MAGIC('D','N','S','I') #define DNS_DBITERATOR_VALID(dbi) ISC_MAGIC_VALID(dbi, DNS_DBITERATOR_MAGIC) /*% * This structure is actually just the common prefix of a DNS db * implementation's version of a dns_dbiterator_t. * * Clients may use the 'db' field of this structure. Except for that field, * direct use of this structure by clients is forbidden. DB implementations * may change the structure. 'magic' must be DNS_DBITERATOR_MAGIC for any of * the dns_dbiterator routines to work. DB iterator implementations must * maintain all DB iterator invariants. */ struct dns_dbiterator { /* Unlocked. */ unsigned int magic; dns_dbiteratormethods_t * methods; dns_db_t * db; isc_boolean_t relative_names; isc_boolean_t cleaning; }; void dns_dbiterator_destroy(dns_dbiterator_t **iteratorp); /*%< * Destroy '*iteratorp'. * * Requires: * *\li '*iteratorp' is a valid iterator. * * Ensures: * *\li All resources used by the iterator are freed. * *\li *iteratorp == NULL. */ isc_result_t dns_dbiterator_first(dns_dbiterator_t *iterator); /*%< * Move the node cursor to the first node in the database (if any). * * Requires: *\li 'iterator' is a valid iterator. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMORE There are no nodes in the database. * *\li Other results are possible, depending on the DB implementation. */ isc_result_t dns_dbiterator_last(dns_dbiterator_t *iterator); /*%< * Move the node cursor to the last node in the database (if any). * * Requires: *\li 'iterator' is a valid iterator. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMORE There are no nodes in the database. * *\li Other results are possible, depending on the DB implementation. */ isc_result_t dns_dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name); /*%< * Move the node cursor to the node with name 'name'. * * Requires: *\li 'iterator' is a valid iterator. * *\li 'name' is a valid name. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOTFOUND * *\li Other results are possible, depending on the DB implementation. */ isc_result_t dns_dbiterator_prev(dns_dbiterator_t *iterator); /*%< * Move the node cursor to the previous node in the database (if any). * * Requires: *\li 'iterator' is a valid iterator. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMORE There are no more nodes in the * database. * *\li Other results are possible, depending on the DB implementation. */ isc_result_t dns_dbiterator_next(dns_dbiterator_t *iterator); /*%< * Move the node cursor to the next node in the database (if any). * * Requires: *\li 'iterator' is a valid iterator. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMORE There are no more nodes in the * database. * *\li Other results are possible, depending on the DB implementation. */ isc_result_t dns_dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep, dns_name_t *name); /*%< * Return the current node. * * Notes: *\li If 'name' is not NULL, it will be set to the name of the node. * * Requires: *\li 'iterator' is a valid iterator. * *\li nodep != NULL && *nodep == NULL * *\li The node cursor of 'iterator' is at a valid location (i.e. the * result of last call to a cursor movement command was ISC_R_SUCCESS). * *\li 'name' is NULL, or is a valid name with a dedicated buffer. * * Returns: * *\li #ISC_R_SUCCESS *\li #DNS_R_NEWORIGIN If this iterator was created with * 'relative_names' set to ISC_TRUE, * then #DNS_R_NEWORIGIN will be returned * when the origin the names are * relative to changes. This result * can occur only when 'name' is not * NULL. This is also a successful * result. * *\li Other results are possible, depending on the DB implementation. */ isc_result_t dns_dbiterator_pause(dns_dbiterator_t *iterator); /*%< * Pause iteration. * * Calling a cursor movement method or dns_dbiterator_current() may cause * database locks to be acquired. Rather than reacquire these locks every * time one of these routines is called, the locks may simply be held. * Calling dns_dbiterator_pause() releases any such locks. Iterator clients * should call this routine any time they are not going to execute another * iterator method in the immediate future. * * Requires: *\li 'iterator' is a valid iterator. * * Ensures: *\li Any database locks being held for efficiency of iterator access are * released. * * Returns: *\li #ISC_R_SUCCESS * *\li Other results are possible, depending on the DB implementation. */ isc_result_t dns_dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name); /*%< * Return the origin to which returned node names are relative. * * Requires: * *\li 'iterator' is a valid relative_names iterator. * *\li 'name' is a valid name with a dedicated buffer. * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_NOSPACE * *\li Other results are possible, depending on the DB implementation. */ void dns_dbiterator_setcleanmode(dns_dbiterator_t *iterator, isc_boolean_t mode); /*%< * Indicate that the given iterator is/is not cleaning the DB. * * Notes: *\li When 'mode' is ISC_TRUE, * * Requires: *\li 'iterator' is a valid iterator. */ ISC_LANG_ENDDECLS #endif /* DNS_DBITERATOR_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/version.h0000644000470500017500000000246312664710322020775 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: version.h,v 1.9.1234.1 2012/02/11 22:37:57 each Exp $ */ /*! \file dns/version.h */ #include LIBDNS_EXTERNAL_DATA extern const char dns_version[]; LIBDNS_EXTERNAL_DATA extern const char dns_major[]; LIBDNS_EXTERNAL_DATA extern const char dns_mapapi[]; LIBDNS_EXTERNAL_DATA extern const unsigned int dns_libinterface; LIBDNS_EXTERNAL_DATA extern const unsigned int dns_librevision; LIBDNS_EXTERNAL_DATA extern const unsigned int dns_libage; bind9-9.10.3.dfsg.P4/lib/dns/include/dns/keyflags.h0000644000470500017500000000341312664710322021111 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: keyflags.h,v 1.16 2007/06/19 23:47:16 tbox Exp $ */ #ifndef DNS_KEYFLAGS_H #define DNS_KEYFLAGS_H 1 /*! \file dns/keyflags.h */ #include #include ISC_LANG_BEGINDECLS isc_result_t dns_keyflags_fromtext(dns_keyflags_t *flagsp, isc_textregion_t *source); /*%< * Convert the text 'source' refers to into a DNSSEC KEY flags value. * The text may contain either a set of flag mnemonics separated by * vertical bars or a decimal flags value. For compatibility with * older versions of BIND and the DNSSEC signer, octal values * prefixed with a zero and hexadecimal values prefixed with "0x" * are also accepted. * * Requires: *\li 'flagsp' is a valid pointer. * *\li 'source' is a valid text region. * * Returns: *\li ISC_R_SUCCESS on success *\li ISC_R_RANGE numeric flag value is out of range *\li DNS_R_UNKNOWN mnemonic flag is unknown */ ISC_LANG_ENDDECLS #endif /* DNS_KEYFLAGS_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/dnssec.h0000644000470500017500000002734512664710322020575 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef DNS_DNSSEC_H #define DNS_DNSSEC_H 1 /*! \file dns/dnssec.h */ #include #include #include #include #include #include ISC_LANG_BEGINDECLS LIBDNS_EXTERNAL_DATA extern isc_stats_t *dns_dnssec_stats; /*%< Maximum number of keys supported in a zone. */ #define DNS_MAXZONEKEYS 32 /* * Indicates how the signer found this key: in the key repository, at the * zone apex, or specified by the user. */ typedef enum { dns_keysource_unknown, dns_keysource_repository, dns_keysource_zoneapex, dns_keysource_user } dns_keysource_t; /* * A DNSSEC key and hints about its intended use gleaned from metadata */ struct dns_dnsseckey { dst_key_t *key; isc_boolean_t hint_publish; /*% metadata says to publish */ isc_boolean_t force_publish; /*% publish regardless of metadata */ isc_boolean_t hint_sign; /*% metadata says to sign with this key */ isc_boolean_t force_sign; /*% sign with key regardless of metadata */ isc_boolean_t hint_remove; /*% metadata says *don't* publish */ isc_boolean_t is_active; /*% key is already active */ isc_boolean_t first_sign; /*% key is newly becoming active */ unsigned int prepublish; /*% how long until active? */ dns_keysource_t source; /*% how the key was found */ isc_boolean_t ksk; /*% this is a key-signing key */ isc_boolean_t legacy; /*% this is old-style key with no metadata (possibly generated by an older version of BIND9) and should be ignored when searching for keys to import into the zone */ unsigned int index; /*% position in list */ ISC_LINK(dns_dnsseckey_t) link; }; isc_result_t dns_dnssec_keyfromrdata(dns_name_t *name, dns_rdata_t *rdata, isc_mem_t *mctx, dst_key_t **key); /*%< * Creates a DST key from a DNS record. Basically a wrapper around * dst_key_fromdns(). * * Requires: *\li 'name' is not NULL *\li 'rdata' is not NULL *\li 'mctx' is not NULL *\li 'key' is not NULL *\li '*key' is NULL * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li DST_R_INVALIDPUBLICKEY *\li various errors from dns_name_totext */ isc_result_t dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, isc_stdtime_t *inception, isc_stdtime_t *expire, isc_mem_t *mctx, isc_buffer_t *buffer, dns_rdata_t *sigrdata); /*%< * Generates a RRSIG record covering this rdataset. This has no effect * on existing RRSIG records. * * Requires: *\li 'name' (the owner name of the record) is a valid name *\li 'set' is a valid rdataset *\li 'key' is a valid key *\li 'inception' is not NULL *\li 'expire' is not NULL *\li 'mctx' is not NULL *\li 'buffer' is not NULL *\li 'sigrdata' is not NULL * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li #ISC_R_NOSPACE *\li #DNS_R_INVALIDTIME - the expiration is before the inception *\li #DNS_R_KEYUNAUTHORIZED - the key cannot sign this data (either * it is not a zone key or its flags prevent * authentication) *\li DST_R_* */ isc_result_t dns_dnssec_verify(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, isc_boolean_t ignoretime, isc_mem_t *mctx, dns_rdata_t *sigrdata); isc_result_t dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, isc_boolean_t ignoretime, isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild); isc_result_t dns_dnssec_verify3(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, isc_boolean_t ignoretime, unsigned int maxbits, isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild); /*%< * Verifies the RRSIG record covering this rdataset signed by a specific * key. This does not determine if the key's owner is authorized to sign * this record, as this requires a resolver or database. * If 'ignoretime' is ISC_TRUE, temporal validity will not be checked. * * 'maxbits' specifies the maximum number of rsa exponent bits accepted. * * Requires: *\li 'name' (the owner name of the record) is a valid name *\li 'set' is a valid rdataset *\li 'key' is a valid key *\li 'mctx' is not NULL *\li 'sigrdata' is a valid rdata containing a SIG record *\li 'wild' if non-NULL then is a valid and has a buffer. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li #DNS_R_FROMWILDCARD - the signature is valid and is from * a wildcard expansion. dns_dnssec_verify2() only. * 'wild' contains the name of the wildcard if non-NULL. *\li #DNS_R_SIGINVALID - the signature fails to verify *\li #DNS_R_SIGEXPIRED - the signature has expired *\li #DNS_R_SIGFUTURE - the signature's validity period has not begun *\li #DNS_R_KEYUNAUTHORIZED - the key cannot sign this data (either * it is not a zone key or its flags prevent * authentication) *\li DST_R_* */ /*@{*/ isc_result_t dns_dnssec_findzonekeys(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, dns_name_t *name, isc_mem_t *mctx, unsigned int maxkeys, dst_key_t **keys, unsigned int *nkeys); isc_result_t dns_dnssec_findzonekeys2(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, dns_name_t *name, const char *directory, isc_mem_t *mctx, unsigned int maxkeys, dst_key_t **keys, unsigned int *nkeys); /*%< * Finds a set of zone keys. * XXX temporary - this should be handled in dns_zone_t. */ /*@}*/ isc_boolean_t dns_dnssec_keyactive(dst_key_t *key, isc_stdtime_t now); /*%< * * Returns ISC_TRUE if 'key' is active as of the time specified * in 'now' (i.e., if the activation date has passed, inactivation or * deletion date has not yet been reached, and the key is not revoked * -- or if it is a legacy key without metadata). Otherwise returns * ISC_FALSE. * * Requires: *\li 'key' is a valid key */ isc_result_t dns_dnssec_signmessage(dns_message_t *msg, dst_key_t *key); /*%< * Signs a message with a SIG(0) record. This is implicitly called by * dns_message_renderend() if msg->sig0key is not NULL. * * Requires: *\li 'msg' is a valid message *\li 'key' is a valid key that can be used for signing * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li DST_R_* */ isc_result_t dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg, dst_key_t *key); /*%< * Verifies a message signed by a SIG(0) record. This is not * called implicitly by dns_message_parse(). If dns_message_signer() * is called before dns_dnssec_verifymessage(), it will return * #DNS_R_NOTVERIFIEDYET. dns_dnssec_verifymessage() will set * the verified_sig0 flag in msg if the verify succeeds, and * the sig0status field otherwise. * * Requires: *\li 'source' is a valid buffer containing the unparsed message *\li 'msg' is a valid message *\li 'key' is a valid key * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li #ISC_R_NOTFOUND - no SIG(0) was found *\li #DNS_R_SIGINVALID - the SIG record is not well-formed or * was not generated by the key. *\li DST_R_* */ isc_boolean_t dns_dnssec_selfsigns(dns_rdata_t *rdata, dns_name_t *name, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, isc_boolean_t ignoretime, isc_mem_t *mctx); isc_boolean_t dns_dnssec_signs(dns_rdata_t *rdata, dns_name_t *name, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, isc_boolean_t ignoretime, isc_mem_t *mctx); /*%< * Verify that 'rdataset' is validly signed in 'sigrdataset' by * the key in 'rdata'. * * dns_dnssec_selfsigns() requires that rdataset be a DNSKEY or KEY * rrset. dns_dnssec_signs() works on any rrset. */ isc_result_t dns_dnsseckey_create(isc_mem_t *mctx, dst_key_t **dstkey, dns_dnsseckey_t **dkp); /*%< * Create and initialize a dns_dnsseckey_t structure. * * Requires: *\li 'dkp' is not NULL and '*dkp' is NULL. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY */ void dns_dnsseckey_destroy(isc_mem_t *mctx, dns_dnsseckey_t **dkp); /*%< * Reclaim a dns_dnsseckey_t structure. * * Requires: *\li 'dkp' is not NULL and '*dkp' is not NULL. * * Ensures: *\li '*dkp' is NULL. */ isc_result_t dns_dnssec_findmatchingkeys(dns_name_t *origin, const char *directory, isc_mem_t *mctx, dns_dnsseckeylist_t *keylist); /*%< * Search 'directory' for K* key files matching the name in 'origin'. * Append all such keys, along with use hints gleaned from their * metadata, onto 'keylist'. * * Requires: *\li 'keylist' is not NULL * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOTFOUND *\li #ISC_R_NOMEMORY *\li any error returned by dns_name_totext(), isc_dir_open(), or * dst_key_fromnamedfile() * * Ensures: *\li On error, keylist is unchanged */ isc_result_t dns_dnssec_keylistfromrdataset(dns_name_t *origin, const char *directory, isc_mem_t *mctx, dns_rdataset_t *keyset, dns_rdataset_t *keysigs, dns_rdataset_t *soasigs, isc_boolean_t savekeys, isc_boolean_t publickey, dns_dnsseckeylist_t *keylist); /*%< * Append the contents of a DNSKEY rdataset 'keyset' to 'keylist'. * Omit duplicates. If 'publickey' is ISC_FALSE, search 'directory' for * matching key files, and load the private keys that go with * the public ones. If 'savekeys' is ISC_TRUE, mark the keys so * they will not be deleted or inactivated regardless of metadata. * * 'keysigs' and 'soasigs', if not NULL and associated, contain the * RRSIGS for the DNSKEY and SOA records respectively and are used to mark * whether a key is already active in the zone. */ isc_result_t dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys, dns_dnsseckeylist_t *removed, dns_name_t *origin, dns_ttl_t hint_ttl, dns_diff_t *diff, isc_boolean_t allzsk, isc_mem_t *mctx, void (*report)(const char *, ...)); /*%< * Update the list of keys in 'keys' with new key information in 'newkeys'. * * For each key in 'newkeys', see if it has a match in 'keys'. * - If not, and if the metadata says the key should be published: * add it to 'keys', and place a dns_difftuple into 'diff' so * the key can be added to the DNSKEY set. If the metadata says it * should be active, set the first_sign flag. * - If so, and if the metadata says it should be removed: * remove it from 'keys', and place a dns_difftuple into 'diff' so * the key can be removed from the DNSKEY set. if 'removed' is non-NULL, * copy the key into that list; otherwise destroy it. * - Otherwise, make sure keys has current metadata. * * If 'allzsk' is true, we are allowing KSK-flagged keys to be used as * ZSKs. * * 'hint_ttl' is the TTL to use for the DNSKEY RRset if there is no * existing RRset, and if none of the keys to be added has a default TTL * (in which case we would use the shortest one). If the TTL is longer * than the time until a new key will be activated, then we have to delay * the key's activation. * * 'report' points to a function for reporting status. * * On completion, any remaining keys in 'newkeys' are freed. */ ISC_LANG_ENDDECLS #endif /* DNS_DNSSEC_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/dispatch.h0000644000470500017500000003666712664710322021124 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: dispatch.h,v 1.64 2011/07/28 23:47:58 tbox Exp $ */ #ifndef DNS_DISPATCH_H #define DNS_DISPATCH_H 1 /***** ***** Module Info *****/ /*! \file dns/dispatch.h * \brief * DNS Dispatch Management * Shared UDP and single-use TCP dispatches for queries and responses. * * MP: * *\li All locking is performed internally to each dispatch. * Restrictions apply to dns_dispatch_removeresponse(). * * Reliability: * * Resources: * * Security: * *\li Depends on the isc_socket_t and dns_message_t for prevention of * buffer overruns. * * Standards: * *\li None. */ /*** *** Imports ***/ #include #include #include #include #include #include ISC_LANG_BEGINDECLS /*% * This event is sent to a task when a response comes in. * No part of this structure should ever be modified by the caller, * other than parts of the buffer. The holy parts of the buffer are * the base and size of the buffer. All other parts of the buffer may * be used. On event delivery the used region contains the packet. * * "id" is the received message id, * * "addr" is the host that sent it to us, * * "buffer" holds state on the received data. * * The "free" routine for this event will clean up itself as well as * any buffer space allocated from common pools. */ struct dns_dispatchevent { ISC_EVENT_COMMON(dns_dispatchevent_t); /*%< standard event common */ isc_result_t result; /*%< result code */ isc_int32_t id; /*%< message id */ isc_sockaddr_t addr; /*%< address recv'd from */ struct in6_pktinfo pktinfo; /*%< reply info for v6 */ isc_buffer_t buffer; /*%< data buffer */ isc_uint32_t attributes; /*%< mirrored from socket.h */ }; /*% * This is a set of one or more dispatches which can be retrieved * round-robin fashion. */ struct dns_dispatchset { isc_mem_t *mctx; dns_dispatch_t **dispatches; int ndisp; int cur; isc_mutex_t lock; }; /*@{*/ /*% * Attributes for added dispatchers. * * Values with the mask 0xffff0000 are application defined. * Values with the mask 0x0000ffff are library defined. * * Insane values (like setting both TCP and UDP) are not caught. Don't * do that. * * _PRIVATE * The dispatcher cannot be shared. * * _TCP, _UDP * The dispatcher is a TCP or UDP socket. * * _IPV4, _IPV6 * The dispatcher uses an IPv4 or IPv6 socket. * * _NOLISTEN * The dispatcher should not listen on the socket. * * _MAKEQUERY * The dispatcher can be used to issue queries to other servers, and * accept replies from them. * * _RANDOMPORT * Previously used to indicate that the port of a dispatch UDP must be * chosen randomly. This behavior now always applies and the attribute * is obsoleted. * * _EXCLUSIVE * A separate socket will be used on-demand for each transaction. */ #define DNS_DISPATCHATTR_PRIVATE 0x00000001U #define DNS_DISPATCHATTR_TCP 0x00000002U #define DNS_DISPATCHATTR_UDP 0x00000004U #define DNS_DISPATCHATTR_IPV4 0x00000008U #define DNS_DISPATCHATTR_IPV6 0x00000010U #define DNS_DISPATCHATTR_NOLISTEN 0x00000020U #define DNS_DISPATCHATTR_MAKEQUERY 0x00000040U #define DNS_DISPATCHATTR_CONNECTED 0x00000080U #define DNS_DISPATCHATTR_FIXEDID 0x00000100U #define DNS_DISPATCHATTR_EXCLUSIVE 0x00000200U /*@}*/ /* */ #define DNS_DISPATCHOPT_FIXEDID 0x00000001U isc_result_t dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy, dns_dispatchmgr_t **mgrp); /*%< * Creates a new dispatchmgr object. * * Requires: *\li "mctx" be a valid memory context. * *\li mgrp != NULL && *mgrp == NULL * *\li "entropy" may be NULL, in which case an insecure random generator * will be used. If it is non-NULL, it must be a valid entropy * source. * * Returns: *\li ISC_R_SUCCESS -- all ok * *\li anything else -- failure */ void dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp); /*%< * Destroys the dispatchmgr when it becomes empty. This could be * immediately. * * Requires: *\li mgrp != NULL && *mgrp is a valid dispatchmgr. */ void dns_dispatchmgr_setblackhole(dns_dispatchmgr_t *mgr, dns_acl_t *blackhole); /*%< * Sets the dispatcher's "blackhole list," a list of addresses that will * be ignored by all dispatchers created by the dispatchmgr. * * Requires: * \li mgrp is a valid dispatchmgr * \li blackhole is a valid acl */ dns_acl_t * dns_dispatchmgr_getblackhole(dns_dispatchmgr_t *mgr); /*%< * Gets a pointer to the dispatcher's current blackhole list, * without incrementing its reference count. * * Requires: *\li mgr is a valid dispatchmgr * Returns: *\li A pointer to the current blackhole list, or NULL. */ void dns_dispatchmgr_setblackportlist(dns_dispatchmgr_t *mgr, dns_portlist_t *portlist); /*%< * This function is deprecated. Use dns_dispatchmgr_setavailports() instead. * * Requires: *\li mgr is a valid dispatchmgr */ dns_portlist_t * dns_dispatchmgr_getblackportlist(dns_dispatchmgr_t *mgr); /*%< * This function is deprecated and always returns NULL. * * Requires: *\li mgr is a valid dispatchmgr */ isc_result_t dns_dispatchmgr_setavailports(dns_dispatchmgr_t *mgr, isc_portset_t *v4portset, isc_portset_t *v6portset); /*%< * Sets a list of UDP ports that can be used for outgoing UDP messages. * * Requires: *\li mgr is a valid dispatchmgr *\li v4portset is NULL or a valid port set *\li v6portset is NULL or a valid port set */ void dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, isc_stats_t *stats); /*%< * Sets statistics counter for the dispatchmgr. This function is expected to * be called only on zone creation (when necessary). * Once installed, it cannot be removed or replaced. Also, there is no * interface to get the installed stats from the zone; the caller must keep the * stats to reference (e.g. dump) it later. * * Requires: *\li mgr is a valid dispatchmgr with no managed dispatch. *\li stats is a valid statistics supporting resolver statistics counters * (see dns/stats.h). */ isc_result_t dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr, unsigned int buffersize, unsigned int maxbuffers, unsigned int maxrequests, unsigned int buckets, unsigned int increment, unsigned int attributes, unsigned int mask, dns_dispatch_t **dispp); isc_result_t dns_dispatch_getudp_dup(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr, unsigned int buffersize, unsigned int maxbuffers, unsigned int maxrequests, unsigned int buckets, unsigned int increment, unsigned int attributes, unsigned int mask, dns_dispatch_t **dispp, dns_dispatch_t *dup); /*%< * Attach to existing dns_dispatch_t if one is found with dns_dispatchmgr_find, * otherwise create a new UDP dispatch. * * Requires: *\li All pointer parameters be valid for their respective types. * *\li dispp != NULL && *disp == NULL * *\li 512 <= buffersize <= 64k * *\li maxbuffers > 0 * *\li buckets < 2097169 * *\li increment > buckets * *\li (attributes & DNS_DISPATCHATTR_TCP) == 0 * * Returns: *\li ISC_R_SUCCESS -- success. * *\li Anything else -- failure. */ isc_result_t dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock, isc_taskmgr_t *taskmgr, unsigned int buffersize, unsigned int maxbuffers, unsigned int maxrequests, unsigned int buckets, unsigned int increment, unsigned int attributes, dns_dispatch_t **dispp); /*%< * Create a new dns_dispatch and attach it to the provided isc_socket_t. * * For all dispatches, "buffersize" is the maximum packet size we will * accept. * * "maxbuffers" and "maxrequests" control the number of buffers in the * overall system and the number of buffers which can be allocated to * requests. * * "buckets" is the number of buckets to use, and should be prime. * * "increment" is used in a collision avoidance function, and needs to be * a prime > buckets, and not 2. * * Requires: * *\li mgr is a valid dispatch manager. * *\li sock is a valid. * *\li task is a valid task that can be used internally to this dispatcher. * * \li 512 <= buffersize <= 64k * *\li maxbuffers > 0. * *\li maxrequests <= maxbuffers. * *\li buckets < 2097169 (the next prime after 65536 * 32) * *\li increment > buckets (and prime). * *\li attributes includes #DNS_DISPATCHATTR_TCP and does not include * #DNS_DISPATCHATTR_UDP. * * Returns: *\li ISC_R_SUCCESS -- success. * *\li Anything else -- failure. */ void dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp); /*%< * Attach to a dispatch handle. * * Requires: *\li disp is valid. * *\li dispp != NULL && *dispp == NULL */ void dns_dispatch_detach(dns_dispatch_t **dispp); /*%< * Detaches from the dispatch. * * Requires: *\li dispp != NULL and *dispp be a valid dispatch. */ void dns_dispatch_starttcp(dns_dispatch_t *disp); /*%< * Start processing of a TCP dispatch once the socket connects. * * Requires: *\li 'disp' is valid. */ isc_result_t dns_dispatch_addresponse3(dns_dispatch_t *disp, unsigned int options, isc_sockaddr_t *dest, isc_task_t *task, isc_taskaction_t action, void *arg, isc_uint16_t *idp, dns_dispentry_t **resp, isc_socketmgr_t *sockmgr); isc_result_t dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest, isc_task_t *task, isc_taskaction_t action, void *arg, isc_uint16_t *idp, dns_dispentry_t **resp, isc_socketmgr_t *sockmgr); isc_result_t dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest, isc_task_t *task, isc_taskaction_t action, void *arg, isc_uint16_t *idp, dns_dispentry_t **resp); /*%< * Add a response entry for this dispatch. * * "*idp" is filled in with the assigned message ID, and *resp is filled in * to contain the magic token used to request event flow stop. * * Arranges for the given task to get a callback for response packets. When * the event is delivered, it must be returned using dns_dispatch_freeevent() * or through dns_dispatch_removeresponse() for another to be delivered. * * Requires: *\li "idp" be non-NULL. * *\li "task" "action" and "arg" be set as appropriate. * *\li "dest" be non-NULL and valid. * *\li "resp" be non-NULL and *resp be NULL * *\li "sockmgr" be NULL or a valid socket manager. If 'disp' has * the DNS_DISPATCHATTR_EXCLUSIVE attribute, this must not be NULL, * which also means dns_dispatch_addresponse() cannot be used. * * Ensures: * *\li <id, dest> is a unique tuple. That means incoming messages * are identifiable. * * Returns: * *\li ISC_R_SUCCESS -- all is well. *\li ISC_R_NOMEMORY -- memory could not be allocated. *\li ISC_R_NOMORE -- no more message ids can be allocated * for this destination. */ void dns_dispatch_removeresponse(dns_dispentry_t **resp, dns_dispatchevent_t **sockevent); /*%< * Stops the flow of responses for the provided id and destination. * If "sockevent" is non-NULL, the dispatch event and associated buffer is * also returned to the system. * * Requires: *\li "resp" != NULL and "*resp" contain a value previously allocated * by dns_dispatch_addresponse(); * *\li May only be called from within the task given as the 'task' * argument to dns_dispatch_addresponse() when allocating '*resp'. */ isc_socket_t * dns_dispatch_getentrysocket(dns_dispentry_t *resp); isc_socket_t * dns_dispatch_getsocket(dns_dispatch_t *disp); /*%< * Return the socket associated with this dispatcher. * * Requires: *\li disp is valid. * * Returns: *\li The socket the dispatcher is using. */ isc_result_t dns_dispatch_getlocaladdress(dns_dispatch_t *disp, isc_sockaddr_t *addrp); /*%< * Return the local address for this dispatch. * This currently only works for dispatches using UDP sockets. * * Requires: *\li disp is valid. *\li addrp to be non null. * * Returns: *\li ISC_R_SUCCESS *\li ISC_R_NOTIMPLEMENTED */ void dns_dispatch_cancel(dns_dispatch_t *disp); /*%< * cancel outstanding clients * * Requires: *\li disp is valid. */ unsigned int dns_dispatch_getattributes(dns_dispatch_t *disp); /*%< * Return the attributes (DNS_DISPATCHATTR_xxx) of this dispatch. Only the * non-changeable attributes are expected to be referenced by the caller. * * Requires: *\li disp is valid. */ void dns_dispatch_changeattributes(dns_dispatch_t *disp, unsigned int attributes, unsigned int mask); /*%< * Set the bits described by "mask" to the corresponding values in * "attributes". * * That is: * * \code * new = (old & ~mask) | (attributes & mask) * \endcode * * This function has a side effect when #DNS_DISPATCHATTR_NOLISTEN changes. * When the flag becomes off, the dispatch will start receiving on the * corresponding socket. When the flag becomes on, receive events on the * corresponding socket will be canceled. * * Requires: *\li disp is valid. * *\li attributes are reasonable for the dispatch. That is, setting the UDP * attribute on a TCP socket isn't reasonable. */ void dns_dispatch_importrecv(dns_dispatch_t *disp, isc_event_t *event); /*%< * Inform the dispatcher of a socket receive. This is used for sockets * shared between dispatchers and clients. If the dispatcher fails to copy * or send the event, nothing happens. * * Requires: *\li disp is valid, and the attribute DNS_DISPATCHATTR_NOLISTEN is set. * event != NULL */ dns_dispatch_t * dns_dispatchset_get(dns_dispatchset_t *dset); /*%< * Retrieve the next dispatch from dispatch set 'dset', and increment * the round-robin counter. * * Requires: *\li dset != NULL */ isc_result_t dns_dispatchset_create(isc_mem_t *mctx, isc_socketmgr_t *sockmgr, isc_taskmgr_t *taskmgr, dns_dispatch_t *source, dns_dispatchset_t **dsetp, int n); /*%< * Given a valid dispatch 'source', create a dispatch set containing * 'n' UDP dispatches, with the remainder filled out by clones of the * source. * * Requires: *\li source is a valid UDP dispatcher *\li dsetp != NULL, *dsetp == NULL */ void dns_dispatchset_cancelall(dns_dispatchset_t *dset, isc_task_t *task); /*%< * Cancel socket operations for the dispatches in 'dset'. */ void dns_dispatchset_destroy(dns_dispatchset_t **dsetp); /*%< * Dereference all the dispatches in '*dsetp', free the dispatchset * memory, and set *dsetp to NULL. * * Requires: *\li dset is valid */ void dns_dispatch_setdscp(dns_dispatch_t *disp, isc_dscp_t dscp); isc_dscp_t dns_dispatch_getdscp(dns_dispatch_t *disp); /*%< * Set/get the DSCP value to be used when sending responses to clients, * as defined in the "listen-on" or "listen-on-v6" statements. * * Requires: *\li disp is valid. */ ISC_LANG_ENDDECLS #endif /* DNS_DISPATCH_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/ecdb.h0000644000470500017500000000237012664710322020202 0ustar lamontlamont/* * Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ecdb.h,v 1.3 2009/09/02 23:48:02 tbox Exp $ */ #ifndef DNS_ECDB_H #define DNS_ECDB_H 1 /***** ***** Module Info *****/ /* TBD */ /*** *** Imports ***/ #include /*** *** Types ***/ /*** *** Functions ***/ ISC_LANG_BEGINDECLS /* TBD: describe those */ isc_result_t dns_ecdb_register(isc_mem_t *mctx, dns_dbimplementation_t **dbimp); void dns_ecdb_unregister(dns_dbimplementation_t **dbimp); ISC_LANG_ENDDECLS #endif /* DNS_ECDB_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/byaddr.h0000644000470500017500000001064112664710322020552 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: byaddr.h,v 1.22 2007/06/19 23:47:16 tbox Exp $ */ #ifndef DNS_BYADDR_H #define DNS_BYADDR_H 1 /***** ***** Module Info *****/ /*! \file dns/byaddr.h * \brief * The byaddr module provides reverse lookup services for IPv4 and IPv6 * addresses. * * MP: *\li The module ensures appropriate synchronization of data structures it * creates and manipulates. * * Reliability: *\li No anticipated impact. * * Resources: *\li TBS * * Security: *\li No anticipated impact. * * Standards: *\li RFCs: 1034, 1035, 2181, TBS *\li Drafts: TBS */ #include #include #include ISC_LANG_BEGINDECLS /*% * A 'dns_byaddrevent_t' is returned when a byaddr completes. * The sender field will be set to the byaddr that completed. If 'result' * is ISC_R_SUCCESS, then 'names' will contain a list of names associated * with the address. The recipient of the event must not change the list * and must not refer to any of the name data after the event is freed. */ typedef struct dns_byaddrevent { ISC_EVENT_COMMON(struct dns_byaddrevent); isc_result_t result; dns_namelist_t names; } dns_byaddrevent_t; /* * This option is deprecated since we now only consider nibbles. #define DNS_BYADDROPT_IPV6NIBBLE 0x0001 */ /*% Note DNS_BYADDROPT_IPV6NIBBLE is now deprecated. */ #define DNS_BYADDROPT_IPV6INT 0x0002 isc_result_t dns_byaddr_create(isc_mem_t *mctx, isc_netaddr_t *address, dns_view_t *view, unsigned int options, isc_task_t *task, isc_taskaction_t action, void *arg, dns_byaddr_t **byaddrp); /*%< * Find the domain name of 'address'. * * Notes: * *\li There is a reverse lookup format for IPv6 addresses, 'nibble' * *\li The 'nibble' format for that address is * * \code * 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.8.e.f.ip6.arpa. * \endcode * *\li #DNS_BYADDROPT_IPV6INT can be used to get nibble lookups under ip6.int. * * Requires: * *\li 'mctx' is a valid mctx. * *\li 'address' is a valid IPv4 or IPv6 address. * *\li 'view' is a valid view which has a resolver. * *\li 'task' is a valid task. * *\li byaddrp != NULL && *byaddrp == NULL * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY * *\li Any resolver-related error (e.g. #ISC_R_SHUTTINGDOWN) may also be * returned. */ void dns_byaddr_cancel(dns_byaddr_t *byaddr); /*%< * Cancel 'byaddr'. * * Notes: * *\li If 'byaddr' has not completed, post its #DNS_EVENT_BYADDRDONE * event with a result code of #ISC_R_CANCELED. * * Requires: * *\li 'byaddr' is a valid byaddr. */ void dns_byaddr_destroy(dns_byaddr_t **byaddrp); /*%< * Destroy 'byaddr'. * * Requires: * *\li '*byaddrp' is a valid byaddr. * *\li The caller has received the #DNS_EVENT_BYADDRDONE event (either because * the byaddr completed or because dns_byaddr_cancel() was called). * * Ensures: * *\li *byaddrp == NULL. */ isc_result_t dns_byaddr_createptrname(isc_netaddr_t *address, isc_boolean_t nibble, dns_name_t *name); isc_result_t dns_byaddr_createptrname2(isc_netaddr_t *address, unsigned int options, dns_name_t *name); /*%< * Creates a name that would be used in a PTR query for this address. The * nibble flag indicates that the 'nibble' format is to be used if an IPv6 * address is provided, instead of the 'bitstring' format. Since we dropped * the support of the bitstring labels, it is expected that the flag is always * set. 'options' are the same as for dns_byaddr_create(). * * Requires: * * \li 'address' is a valid address. * \li 'name' is a valid name with a dedicated buffer. */ ISC_LANG_ENDDECLS #endif /* DNS_BYADDR_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/rpz.h0000644000470500017500000002455512664710322020131 0ustar lamontlamont/* * Copyright (C) 2011-2013, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef DNS_RPZ_H #define DNS_RPZ_H 1 #include #include #include #include #include #include ISC_LANG_BEGINDECLS #define DNS_RPZ_PREFIX "rpz-" /* * Sub-zones of various trigger types. */ #define DNS_RPZ_CLIENT_IP_ZONE DNS_RPZ_PREFIX"client-ip" #define DNS_RPZ_IP_ZONE DNS_RPZ_PREFIX"ip" #define DNS_RPZ_NSIP_ZONE DNS_RPZ_PREFIX"nsip" #define DNS_RPZ_NSDNAME_ZONE DNS_RPZ_PREFIX"nsdname" /* * Special policies. */ #define DNS_RPZ_PASSTHRU_NAME DNS_RPZ_PREFIX"passthru" #define DNS_RPZ_DROP_NAME DNS_RPZ_PREFIX"drop" #define DNS_RPZ_TCP_ONLY_NAME DNS_RPZ_PREFIX"tcp-only" typedef isc_uint8_t dns_rpz_prefix_t; typedef enum { DNS_RPZ_TYPE_BAD, DNS_RPZ_TYPE_CLIENT_IP, DNS_RPZ_TYPE_QNAME, DNS_RPZ_TYPE_IP, DNS_RPZ_TYPE_NSDNAME, DNS_RPZ_TYPE_NSIP } dns_rpz_type_t; /* * Require DNS_RPZ_POLICY_PASSTHRU < DNS_RPZ_POLICY_DROP * < DNS_RPZ_POLICY_TCP_ONLY DNS_RPZ_POLICY_NXDOMAIN < DNS_RPZ_POLICY_NODATA * < DNS_RPZ_POLICY_CNAME to choose among competing policies. */ typedef enum { DNS_RPZ_POLICY_GIVEN = 0, /* 'given': what policy record says */ DNS_RPZ_POLICY_DISABLED = 1, /* log what would have happened */ DNS_RPZ_POLICY_PASSTHRU = 2, /* 'passthru': do not rewrite */ DNS_RPZ_POLICY_DROP = 3, /* 'drop': do not respond */ DNS_RPZ_POLICY_TCP_ONLY = 4, /* 'tcp-only': answer UDP with TC=1 */ DNS_RPZ_POLICY_NXDOMAIN = 5, /* 'nxdomain': answer with NXDOMAIN */ DNS_RPZ_POLICY_NODATA = 6, /* 'nodata': answer with ANCOUNT=0 */ DNS_RPZ_POLICY_CNAME = 7, /* 'cname x': answer with x's rrsets */ DNS_RPZ_POLICY_RECORD, DNS_RPZ_POLICY_WILDCNAME, DNS_RPZ_POLICY_MISS, DNS_RPZ_POLICY_ERROR } dns_rpz_policy_t; typedef isc_uint8_t dns_rpz_num_t; #define DNS_RPZ_MAX_ZONES 32 #if DNS_RPZ_MAX_ZONES > 32 # if DNS_RPZ_MAX_ZONES > 64 # error "rpz zone bit masks must fit in a word" # endif typedef isc_uint64_t dns_rpz_zbits_t; #else typedef isc_uint32_t dns_rpz_zbits_t; #endif #define DNS_RPZ_ALL_ZBITS ((dns_rpz_zbits_t)-1) #define DNS_RPZ_INVALID_NUM DNS_RPZ_MAX_ZONES #define DNS_RPZ_ZBIT(n) (((dns_rpz_zbits_t)1) << (dns_rpz_num_t)(n)) /* * Mask of the specified and higher numbered policy zones * Avoid hassles with (1<<33) or (1<<65) */ #define DNS_RPZ_ZMASK(n) ((dns_rpz_zbits_t)((((n) >= DNS_RPZ_MAX_ZONES-1) ? \ 0 : (1<<((n)+1))) -1)) /* * The trigger counter type. */ typedef size_t dns_rpz_trigger_counter_t; /* * The number of triggers of each type in a response policy zone. */ typedef struct dns_rpz_triggers dns_rpz_triggers_t; struct dns_rpz_triggers { dns_rpz_trigger_counter_t client_ipv4; dns_rpz_trigger_counter_t client_ipv6; dns_rpz_trigger_counter_t qname; dns_rpz_trigger_counter_t ipv4; dns_rpz_trigger_counter_t ipv6; dns_rpz_trigger_counter_t nsdname; dns_rpz_trigger_counter_t nsipv4; dns_rpz_trigger_counter_t nsipv6; }; /* * A single response policy zone. */ typedef struct dns_rpz_zone dns_rpz_zone_t; struct dns_rpz_zone { isc_refcount_t refs; dns_rpz_num_t num; /* ordinal in list of policy zones */ dns_name_t origin; /* Policy zone name */ dns_name_t client_ip; /* DNS_RPZ_CLIENT_IP_ZONE.origin. */ dns_name_t ip; /* DNS_RPZ_IP_ZONE.origin. */ dns_name_t nsdname; /* DNS_RPZ_NSDNAME_ZONE.origin */ dns_name_t nsip; /* DNS_RPZ_NSIP_ZONE.origin. */ dns_name_t passthru; /* DNS_RPZ_PASSTHRU_NAME. */ dns_name_t drop; /* DNS_RPZ_DROP_NAME. */ dns_name_t tcp_only; /* DNS_RPZ_TCP_ONLY_NAME. */ dns_name_t cname; /* override value for ..._CNAME */ dns_ttl_t max_policy_ttl; dns_rpz_policy_t policy; /* DNS_RPZ_POLICY_GIVEN or override */ }; /* * Radix tree node for response policy IP addresses */ typedef struct dns_rpz_cidr_node dns_rpz_cidr_node_t; /* * Bitfields indicating which policy zones have policies of * which type. */ typedef struct dns_rpz_have dns_rpz_have_t; struct dns_rpz_have { dns_rpz_zbits_t client_ipv4; dns_rpz_zbits_t client_ipv6; dns_rpz_zbits_t client_ip; dns_rpz_zbits_t qname; dns_rpz_zbits_t ipv4; dns_rpz_zbits_t ipv6; dns_rpz_zbits_t ip; dns_rpz_zbits_t nsdname; dns_rpz_zbits_t nsipv4; dns_rpz_zbits_t nsipv6; dns_rpz_zbits_t nsip; dns_rpz_zbits_t qname_skip_recurse; }; /* * Policy options */ typedef struct dns_rpz_popt dns_rpz_popt_t; struct dns_rpz_popt { dns_rpz_zbits_t no_rd_ok; isc_boolean_t break_dnssec; isc_boolean_t qname_wait_recurse; unsigned int min_ns_labels; dns_rpz_num_t num_zones; }; /* * Response policy zones known to a view. */ typedef struct dns_rpz_zones dns_rpz_zones_t; struct dns_rpz_zones { dns_rpz_popt_t p; dns_rpz_zone_t *zones[DNS_RPZ_MAX_ZONES]; dns_rpz_triggers_t triggers[DNS_RPZ_MAX_ZONES]; /* * RPZ policy version number (initially 0, increases whenever * the server is reconfigured with new zones or policy) */ int rpz_ver; dns_rpz_zbits_t defined; /* * The set of records for a policy zone are in one of these states: * never loaded load_begun=0 have=0 * during initial loading load_begun=1 have=0 * and rbtdb->rpzsp == rbtdb->load_rpzsp * after good load load_begun=1 have!=0 * after failed initial load load_begun=1 have=0 * and rbtdb->load_rpzsp == NULL * reloading after failure load_begun=1 have=0 * reloading after success * main rpzs load_begun=1 have!=0 * load rpzs load_begun=1 have=0 */ dns_rpz_zbits_t load_begun; dns_rpz_have_t have; /* * total_triggers maintains the total number of triggers in all * policy zones in the view. It is only used to print summary * statistics after a zone load of how the trigger counts * changed. */ dns_rpz_triggers_t total_triggers; isc_mem_t *mctx; isc_refcount_t refs; /* * One lock for short term read-only search that guarantees the * consistency of the pointers. * A second lock for maintenance that guarantees no other thread * is adding or deleting nodes. */ isc_rwlock_t search_lock; isc_mutex_t maint_lock; dns_rpz_cidr_node_t *cidr; dns_rbt_t *rbt; }; /* * context for finding the best policy */ typedef struct { unsigned int state; # define DNS_RPZ_REWRITTEN 0x0001 # define DNS_RPZ_DONE_CLIENT_IP 0x0002 /* client IP address checked */ # define DNS_RPZ_DONE_QNAME 0x0004 /* qname checked */ # define DNS_RPZ_DONE_QNAME_IP 0x0008 /* IP addresses of qname checked */ # define DNS_RPZ_DONE_NSDNAME 0x0010 /* NS name missed; checking addresses */ # define DNS_RPZ_DONE_IPv4 0x0020 # define DNS_RPZ_RECURSING 0x0040 # define DNS_RPZ_ACTIVE 0x0080 /* * Best match so far. */ struct { dns_rpz_type_t type; dns_rpz_zone_t *rpz; dns_rpz_prefix_t prefix; dns_rpz_policy_t policy; dns_ttl_t ttl; isc_result_t result; dns_zone_t *zone; dns_db_t *db; dns_dbversion_t *version; dns_dbnode_t *node; dns_rdataset_t *rdataset; } m; /* * State for chasing IP addresses and NS names including recursion. */ struct { unsigned int label; dns_db_t *db; dns_rdataset_t *ns_rdataset; dns_rdatatype_t r_type; isc_result_t r_result; dns_rdataset_t *r_rdataset; } r; /* * State of real query while recursing for NSIP or NSDNAME. */ struct { isc_result_t result; isc_boolean_t is_zone; isc_boolean_t authoritative; dns_zone_t *zone; dns_db_t *db; dns_dbnode_t *node; dns_rdataset_t *rdataset; dns_rdataset_t *sigrdataset; dns_rdatatype_t qtype; } q; /* * A copy of the 'have' and 'p' structures and the RPZ * policy version as of the beginning of RPZ processing, * used to avoid problems when policy is updated while * RPZ recursion is ongoing. */ dns_rpz_have_t have; dns_rpz_popt_t popt; int rpz_ver; /* * p_name: current policy owner name * r_name: recursing for this name to possible policy triggers * f_name: saved found name from before recursion */ dns_name_t *p_name; dns_name_t *r_name; dns_name_t *fname; dns_fixedname_t _p_namef; dns_fixedname_t _r_namef; dns_fixedname_t _fnamef; } dns_rpz_st_t; #define DNS_RPZ_TTL_DEFAULT 5 #define DNS_RPZ_MAX_TTL_DEFAULT DNS_RPZ_TTL_DEFAULT /* * So various response policy zone messages can be turned up or down. */ #define DNS_RPZ_ERROR_LEVEL ISC_LOG_WARNING #define DNS_RPZ_INFO_LEVEL ISC_LOG_INFO #define DNS_RPZ_DEBUG_LEVEL1 ISC_LOG_DEBUG(1) #define DNS_RPZ_DEBUG_LEVEL2 ISC_LOG_DEBUG(2) #define DNS_RPZ_DEBUG_LEVEL3 ISC_LOG_DEBUG(3) #define DNS_RPZ_DEBUG_QUIET (DNS_RPZ_DEBUG_LEVEL3+1) const char * dns_rpz_type2str(dns_rpz_type_t type); dns_rpz_policy_t dns_rpz_str2policy(const char *str); const char * dns_rpz_policy2str(dns_rpz_policy_t policy); dns_rpz_policy_t dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset, dns_name_t *selfname); isc_result_t dns_rpz_new_zones(dns_rpz_zones_t **rpzsp, isc_mem_t *mctx); void dns_rpz_attach_rpzs(dns_rpz_zones_t *source, dns_rpz_zones_t **target); void dns_rpz_detach_rpzs(dns_rpz_zones_t **rpzsp); isc_result_t dns_rpz_beginload(dns_rpz_zones_t **load_rpzsp, dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num); isc_result_t dns_rpz_ready(dns_rpz_zones_t *rpzs, dns_rpz_zones_t **load_rpzsp, dns_rpz_num_t rpz_num); isc_result_t dns_rpz_add(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, dns_name_t *name); void dns_rpz_delete(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num, dns_name_t *name); dns_rpz_num_t dns_rpz_find_ip(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type, dns_rpz_zbits_t zbits, const isc_netaddr_t *netaddr, dns_name_t *ip_name, dns_rpz_prefix_t *prefixp); dns_rpz_zbits_t dns_rpz_find_name(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type, dns_rpz_zbits_t zbits, dns_name_t *trig_name); ISC_LANG_ENDDECLS #endif /* DNS_RPZ_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/rrl.h0000644000470500017500000001563312664710322020112 0ustar lamontlamont/* * Copyright (C) 2013, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef DNS_RRL_H #define DNS_RRL_H 1 /* * Rate limit DNS responses. */ #include #include #include #include ISC_LANG_BEGINDECLS /* * Memory allocation or other failures. */ #define DNS_RRL_LOG_FAIL ISC_LOG_WARNING /* * dropped or slipped responses. */ #define DNS_RRL_LOG_DROP ISC_LOG_INFO /* * Major events in dropping or slipping. */ #define DNS_RRL_LOG_DEBUG1 ISC_LOG_DEBUG(3) /* * Limit computations. */ #define DNS_RRL_LOG_DEBUG2 ISC_LOG_DEBUG(4) /* * Even less interesting. */ #define DNS_RRL_LOG_DEBUG3 ISC_LOG_DEBUG(9) #define DNS_RRL_LOG_ERR_LEN 64 #define DNS_RRL_LOG_BUF_LEN (sizeof("would continue limiting") + \ DNS_RRL_LOG_ERR_LEN + \ sizeof(" responses to ") + \ ISC_NETADDR_FORMATSIZE + \ sizeof("/128 for IN ") + \ DNS_RDATATYPE_FORMATSIZE + \ DNS_NAME_FORMATSIZE) typedef struct dns_rrl_hash dns_rrl_hash_t; /* * Response types. */ typedef enum { DNS_RRL_RTYPE_FREE = 0, DNS_RRL_RTYPE_QUERY, DNS_RRL_RTYPE_REFERRAL, DNS_RRL_RTYPE_NODATA, DNS_RRL_RTYPE_NXDOMAIN, DNS_RRL_RTYPE_ERROR, DNS_RRL_RTYPE_ALL, DNS_RRL_RTYPE_TCP, } dns_rrl_rtype_t; /* * A rate limit bucket key. * This should be small to limit the total size of the database. * The hash of the qname should be wide enough to make the probability * of collisions among requests from a single IP address block less than 50%. * We need a 32-bit hash value for 10000 qps (e.g. random qnames forged * by attacker) to collide with legitimate qnames from the target with * probability at most 1%. */ #define DNS_RRL_MAX_PREFIX 64 typedef union dns_rrl_key dns_rrl_key_t; struct dns__rrl_key { isc_uint32_t ip[DNS_RRL_MAX_PREFIX/32]; isc_uint32_t qname_hash; dns_rdatatype_t qtype; isc_uint8_t qclass; dns_rrl_rtype_t rtype :4; /* 3 bits + sign bit */ isc_boolean_t ipv6 :1; }; union dns_rrl_key { struct dns__rrl_key s; isc_uint16_t w[sizeof(struct dns__rrl_key)/sizeof(isc_uint16_t)]; }; /* * A rate-limit entry. * This should be small to limit the total size of the table of entries. */ typedef struct dns_rrl_entry dns_rrl_entry_t; typedef ISC_LIST(dns_rrl_entry_t) dns_rrl_bin_t; struct dns_rrl_entry { ISC_LINK(dns_rrl_entry_t) lru; ISC_LINK(dns_rrl_entry_t) hlink; dns_rrl_key_t key; # define DNS_RRL_RESPONSE_BITS 24 signed int responses :DNS_RRL_RESPONSE_BITS; # define DNS_RRL_QNAMES_BITS 8 unsigned int log_qname :DNS_RRL_QNAMES_BITS; # define DNS_RRL_TS_GEN_BITS 2 unsigned int ts_gen :DNS_RRL_TS_GEN_BITS; isc_boolean_t ts_valid :1; # define DNS_RRL_HASH_GEN_BITS 1 unsigned int hash_gen :DNS_RRL_HASH_GEN_BITS; isc_boolean_t logged :1; # define DNS_RRL_LOG_BITS 11 unsigned int log_secs :DNS_RRL_LOG_BITS; # define DNS_RRL_TS_BITS 12 unsigned int ts :DNS_RRL_TS_BITS; # define DNS_RRL_MAX_SLIP 10 unsigned int slip_cnt :4; }; #define DNS_RRL_MAX_TIME_TRAVEL 5 #define DNS_RRL_FOREVER (1<= DNS_RRL_MAX_TS #error "DNS_RRL_MAX_WINDOW is too large" #endif #define DNS_RRL_MAX_RATE 1000 #if DNS_RRL_MAX_RATE >= (DNS_RRL_MAX_RESPONSES / DNS_RRL_MAX_WINDOW) #error "DNS_RRL_MAX_rate is too large" #endif #if (1<= DNS_RRL_FOREVER #error DNS_RRL_LOG_BITS is too big #endif #define DNS_RRL_MAX_LOG_SECS 1800 #if DNS_RRL_MAX_LOG_SECS >= (1<= (1< #include #include #include #include ISC_LANG_BEGINDECLS /*% * A dns_fetchevent_t is sent when a 'fetch' completes. Any of 'db', * 'node', 'rdataset', and 'sigrdataset' may be bound. It is the * receiver's responsibility to detach before freeing the event. * \brief * 'rdataset', 'sigrdataset', 'client' and 'id' are the values that were * supplied when dns_resolver_createfetch() was called. They are returned * to the caller so that they may be freed. */ typedef struct dns_fetchevent { ISC_EVENT_COMMON(struct dns_fetchevent); dns_fetch_t * fetch; isc_result_t result; dns_rdatatype_t qtype; dns_db_t * db; dns_dbnode_t * node; dns_rdataset_t * rdataset; dns_rdataset_t * sigrdataset; dns_fixedname_t foundname; isc_sockaddr_t * client; dns_messageid_t id; isc_result_t vresult; } dns_fetchevent_t; /*% * The two quota types (fetches-per-zone and fetches-per-server) */ typedef enum { dns_quotatype_zone = 0, dns_quotatype_server } dns_quotatype_t; /* * Options that modify how a 'fetch' is done. */ #define DNS_FETCHOPT_TCP 0x001 /*%< Use TCP. */ #define DNS_FETCHOPT_UNSHARED 0x002 /*%< See below. */ #define DNS_FETCHOPT_RECURSIVE 0x004 /*%< Set RD? */ #define DNS_FETCHOPT_NOEDNS0 0x008 /*%< Do not use EDNS. */ #define DNS_FETCHOPT_FORWARDONLY 0x010 /*%< Only use forwarders. */ #define DNS_FETCHOPT_NOVALIDATE 0x020 /*%< Disable validation. */ #define DNS_FETCHOPT_EDNS512 0x040 /*%< Advertise a 512 byte UDP buffer. */ #define DNS_FETCHOPT_WANTNSID 0x080 /*%< Request NSID */ #define DNS_FETCHOPT_PREFETCH 0x100 /*%< Do prefetch */ #define DNS_FETCHOPT_NOCDFLAG 0x200 /*%< Don't set CD flag. */ /* Reserved in use by adb.c 0x00400000 */ #define DNS_FETCHOPT_EDNSVERSIONSET 0x00800000 #define DNS_FETCHOPT_EDNSVERSIONMASK 0xff000000 #define DNS_FETCHOPT_EDNSVERSIONSHIFT 24 /* * Upper bounds of class of query RTT (ms). Corresponds to * dns_resstatscounter_queryrttX statistics counters. */ #define DNS_RESOLVER_QRYRTTCLASS0 10 #define DNS_RESOLVER_QRYRTTCLASS0STR "10" #define DNS_RESOLVER_QRYRTTCLASS1 100 #define DNS_RESOLVER_QRYRTTCLASS1STR "100" #define DNS_RESOLVER_QRYRTTCLASS2 500 #define DNS_RESOLVER_QRYRTTCLASS2STR "500" #define DNS_RESOLVER_QRYRTTCLASS3 800 #define DNS_RESOLVER_QRYRTTCLASS3STR "800" #define DNS_RESOLVER_QRYRTTCLASS4 1600 #define DNS_RESOLVER_QRYRTTCLASS4STR "1600" /* * XXXRTH Should this API be made semi-private? (I.e. * _dns_resolver_create()). */ #define DNS_RESOLVER_CHECKNAMES 0x01 #define DNS_RESOLVER_CHECKNAMESFAIL 0x02 isc_result_t dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr, unsigned int ntasks, unsigned int ndisp, isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr, unsigned int options, dns_dispatchmgr_t *dispatchmgr, dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6, dns_resolver_t **resp); /*%< * Create a resolver. * * Notes: * *\li Generally, applications should not create a resolver directly, but * should instead call dns_view_createresolver(). * * Requires: * *\li 'view' is a valid view. * *\li 'taskmgr' is a valid task manager. * *\li 'ntasks' > 0. * *\li 'socketmgr' is a valid socket manager. * *\li 'timermgr' is a valid timer manager. * *\li 'dispatchv4' is a dispatch with an IPv4 UDP socket, or is NULL. * If not NULL, 'ndisp' clones of it will be created by the resolver. * *\li 'dispatchv6' is a dispatch with an IPv6 UDP socket, or is NULL. * If not NULL, 'ndisp' clones of it will be created by the resolver. * *\li resp != NULL && *resp == NULL. * * Returns: * *\li #ISC_R_SUCCESS On success. * *\li Anything else Failure. */ void dns_resolver_freeze(dns_resolver_t *res); /*%< * Freeze resolver. * * Notes: * *\li Certain configuration changes cannot be made after the resolver * is frozen. Fetches cannot be created until the resolver is frozen. * * Requires: * *\li 'res' is a valid resolver. * * Ensures: * *\li 'res' is frozen. */ void dns_resolver_prime(dns_resolver_t *res); /*%< * Prime resolver. * * Notes: * *\li Resolvers which have a forwarding policy other than dns_fwdpolicy_only * need to be primed with the root nameservers, otherwise the root * nameserver hints data may be used indefinitely. This function requests * that the resolver start a priming fetch, if it isn't already priming. * * Requires: * *\li 'res' is a valid, frozen resolver. */ void dns_resolver_whenshutdown(dns_resolver_t *res, isc_task_t *task, isc_event_t **eventp); /*%< * Send '*eventp' to 'task' when 'res' has completed shutdown. * * Notes: * *\li It is not safe to detach the last reference to 'res' until * shutdown is complete. * * Requires: * *\li 'res' is a valid resolver. * *\li 'task' is a valid task. * *\li *eventp is a valid event. * * Ensures: * *\li *eventp == NULL. */ void dns_resolver_shutdown(dns_resolver_t *res); /*%< * Start the shutdown process for 'res'. * * Notes: * *\li This call has no effect if the resolver is already shutting down. * * Requires: * *\li 'res' is a valid resolver. */ void dns_resolver_attach(dns_resolver_t *source, dns_resolver_t **targetp); void dns_resolver_detach(dns_resolver_t **resp); isc_result_t dns_resolver_createfetch(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, dns_name_t *domain, dns_rdataset_t *nameservers, dns_forwarders_t *forwarders, unsigned int options, isc_task_t *task, isc_taskaction_t action, void *arg, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, dns_fetch_t **fetchp); isc_result_t dns_resolver_createfetch2(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, dns_name_t *domain, dns_rdataset_t *nameservers, dns_forwarders_t *forwarders, isc_sockaddr_t *client, isc_uint16_t id, unsigned int options, isc_task_t *task, isc_taskaction_t action, void *arg, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, dns_fetch_t **fetchp); isc_result_t dns_resolver_createfetch3(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, dns_name_t *domain, dns_rdataset_t *nameservers, dns_forwarders_t *forwarders, isc_sockaddr_t *client, isc_uint16_t id, unsigned int options, unsigned int depth, isc_counter_t *qc, isc_task_t *task, isc_taskaction_t action, void *arg, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, dns_fetch_t **fetchp); /*%< * Recurse to answer a question. * * Notes: * *\li This call starts a query for 'name', type 'type'. * *\li The 'domain' is a parent domain of 'name' for which * a set of name servers 'nameservers' is known. If no * such name server information is available, set * 'domain' and 'nameservers' to NULL. * *\li 'forwarders' is unimplemented, and subject to change when * we figure out how selective forwarding will work. * *\li When the fetch completes (successfully or otherwise), a * #DNS_EVENT_FETCHDONE event with action 'action' and arg 'arg' will be * posted to 'task'. * *\li The values of 'rdataset' and 'sigrdataset' will be returned in * the FETCHDONE event. * *\li 'client' and 'id' are used for duplicate query detection. '*client' * must remain stable until after 'action' has been called or * dns_resolver_cancelfetch() is called. * * Requires: * *\li 'res' is a valid resolver that has been frozen. * *\li 'name' is a valid name. * *\li 'type' is not a meta type other than ANY. * *\li 'domain' is a valid name or NULL. * *\li 'nameservers' is a valid NS rdataset (whose owner name is 'domain') * iff. 'domain' is not NULL. * *\li 'forwarders' is NULL. * *\li 'client' is a valid sockaddr or NULL. * *\li 'options' contains valid options. * *\li 'rdataset' is a valid, disassociated rdataset. * *\li 'sigrdataset' is NULL, or is a valid, disassociated rdataset. * *\li fetchp != NULL && *fetchp == NULL. * * Returns: * *\li #ISC_R_SUCCESS Success *\li #DNS_R_DUPLICATE *\li #DNS_R_DROP * *\li Many other values are possible, all of which indicate failure. */ void dns_resolver_cancelfetch(dns_fetch_t *fetch); /*%< * Cancel 'fetch'. * * Notes: * *\li If 'fetch' has not completed, post its FETCHDONE event with a * result code of #ISC_R_CANCELED. * * Requires: * *\li 'fetch' is a valid fetch. */ void dns_resolver_destroyfetch(dns_fetch_t **fetchp); /*%< * Destroy 'fetch'. * * Requires: * *\li '*fetchp' is a valid fetch. * *\li The caller has received the FETCHDONE event (either because the * fetch completed or because dns_resolver_cancelfetch() was called). * * Ensures: * *\li *fetchp == NULL. */ void dns_resolver_logfetch(dns_fetch_t *fetch, isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, isc_boolean_t duplicateok); /*%< * Dump a log message on internal state at the completion of given 'fetch'. * 'lctx', 'category', 'module', and 'level' are used to write the log message. * By default, only one log message is written even if the corresponding fetch * context serves multiple clients; if 'duplicateok' is true the suppression * is disabled and the message can be written every time this function is * called. * * Requires: * *\li 'fetch' is a valid fetch, and has completed. */ dns_dispatchmgr_t * dns_resolver_dispatchmgr(dns_resolver_t *resolver); dns_dispatch_t * dns_resolver_dispatchv4(dns_resolver_t *resolver); dns_dispatch_t * dns_resolver_dispatchv6(dns_resolver_t *resolver); isc_socketmgr_t * dns_resolver_socketmgr(dns_resolver_t *resolver); isc_taskmgr_t * dns_resolver_taskmgr(dns_resolver_t *resolver); isc_uint32_t dns_resolver_getlamettl(dns_resolver_t *resolver); /*%< * Get the resolver's lame-ttl. zero => no lame processing. * * Requires: *\li 'resolver' to be valid. */ void dns_resolver_setlamettl(dns_resolver_t *resolver, isc_uint32_t lame_ttl); /*%< * Set the resolver's lame-ttl. zero => no lame processing. * * Requires: *\li 'resolver' to be valid. */ unsigned int dns_resolver_nrunning(dns_resolver_t *resolver); /*%< * Return the number of currently running resolutions in this * resolver. This is may be less than the number of outstanding * fetches due to multiple identical fetches, or more than the * number of of outstanding fetches due to the fact that resolution * can continue even though a fetch has been canceled. */ isc_result_t dns_resolver_addalternate(dns_resolver_t *resolver, isc_sockaddr_t *alt, dns_name_t *name, in_port_t port); /*%< * Add alternate addresses to be tried in the event that the nameservers * for a zone are not available in the address families supported by the * operating system. * * Require: * \li only one of 'name' or 'alt' to be valid. */ void dns_resolver_setudpsize(dns_resolver_t *resolver, isc_uint16_t udpsize); /*%< * Set the EDNS UDP buffer size advertised by the server. */ isc_uint16_t dns_resolver_getudpsize(dns_resolver_t *resolver); /*%< * Get the current EDNS UDP buffer size. */ void dns_resolver_reset_algorithms(dns_resolver_t *resolver); /*%< * Clear the disabled DNSSEC algorithms. */ void dns_resolver_reset_ds_digests(dns_resolver_t *resolver); /*%< * Clear the disabled DS/DLV digest types. */ isc_result_t dns_resolver_disable_algorithm(dns_resolver_t *resolver, dns_name_t *name, unsigned int alg); /*%< * Mark the given DNSSEC algorithm as disabled and below 'name'. * Valid algorithms are less than 256. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_RANGE *\li #ISC_R_NOMEMORY */ isc_result_t dns_resolver_disable_ds_digest(dns_resolver_t *resolver, dns_name_t *name, unsigned int digest_type); /*%< * Mark the given DS/DLV digest type as disabled and below 'name'. * Valid types are less than 256. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_RANGE *\li #ISC_R_NOMEMORY */ isc_boolean_t dns_resolver_algorithm_supported(dns_resolver_t *resolver, dns_name_t *name, unsigned int alg); /*%< * Check if the given algorithm is supported by this resolver. * This checks whether the algorithm has been disabled via * dns_resolver_disable_algorithm(), then checks the underlying * crypto libraries if it was not specifically disabled. */ isc_boolean_t dns_resolver_ds_digest_supported(dns_resolver_t *resolver, dns_name_t *name, unsigned int digest_type); /*%< * Check if the given digest type is supported by this resolver. * This checks whether the digest type has been disabled via * dns_resolver_disable_ds_digest(), then checks the underlying * crypto libraries if it was not specifically disabled. */ void dns_resolver_resetmustbesecure(dns_resolver_t *resolver); isc_result_t dns_resolver_setmustbesecure(dns_resolver_t *resolver, dns_name_t *name, isc_boolean_t value); isc_boolean_t dns_resolver_getmustbesecure(dns_resolver_t *resolver, dns_name_t *name); void dns_resolver_settimeout(dns_resolver_t *resolver, unsigned int seconds); /*%< * Set the length of time the resolver will work on a query, in seconds. * * If timeout is 0, the default timeout will be applied. * * Requires: * \li resolver to be valid. */ unsigned int dns_resolver_gettimeout(dns_resolver_t *resolver); /*%< * Get the current length of time the resolver will work on a query, in seconds. * * Requires: * \li resolver to be valid. */ void dns_resolver_setclientsperquery(dns_resolver_t *resolver, isc_uint32_t min, isc_uint32_t max); void dns_resolver_setfetchesperzone(dns_resolver_t *resolver, isc_uint32_t clients); void dns_resolver_getclientsperquery(dns_resolver_t *resolver, isc_uint32_t *cur, isc_uint32_t *min, isc_uint32_t *max); isc_boolean_t dns_resolver_getzeronosoattl(dns_resolver_t *resolver); void dns_resolver_setzeronosoattl(dns_resolver_t *resolver, isc_boolean_t state); unsigned int dns_resolver_getoptions(dns_resolver_t *resolver); void dns_resolver_addbadcache(dns_resolver_t *resolver, dns_name_t *name, dns_rdatatype_t type, isc_time_t *expire); /*%< * Add a entry to the bad cache for that will expire at 'expire'. * * Requires: * \li resolver to be valid. * \li name to be valid. */ isc_boolean_t dns_resolver_getbadcache(dns_resolver_t *resolver, dns_name_t *name, dns_rdatatype_t type, isc_time_t *now); /*%< * Check to see if there is a unexpired entry in the bad cache for * . * * Requires: * \li resolver to be valid. * \li name to be valid. */ void dns_resolver_flushbadcache(dns_resolver_t *resolver, dns_name_t *name); /*%< * Flush the bad cache of all entries at 'name' if 'name' is non NULL. * Flush the entire bad cache if 'name' is NULL. * * Requires: * \li resolver to be valid. */ void dns_resolver_flushbadnames(dns_resolver_t *resolver, dns_name_t *name); /*%< * Flush the bad cache of all entries at or below 'name'. * * Requires: * \li resolver to be valid. * \li name != NULL */ void dns_resolver_printbadcache(dns_resolver_t *resolver, FILE *fp); /*% * Print out the contents of the bad cache to 'fp'. * * Requires: * \li resolver to be valid. */ void dns_resolver_setquerydscp4(dns_resolver_t *resolver, isc_dscp_t dscp); isc_dscp_t dns_resolver_getquerydscp4(dns_resolver_t *resolver); void dns_resolver_setquerydscp6(dns_resolver_t *resolver, isc_dscp_t dscp); isc_dscp_t dns_resolver_getquerydscp6(dns_resolver_t *resolver); /*% * Get and set the DSCP values for the resolver's IPv4 and IPV6 query * sources. * * Requires: * \li resolver to be valid. */ void dns_resolver_setmaxdepth(dns_resolver_t *resolver, unsigned int maxdepth); unsigned int dns_resolver_getmaxdepth(dns_resolver_t *resolver); /*% * Get and set how many NS indirections will be followed when looking for * nameserver addresses. * * Requires: * \li resolver to be valid. */ void dns_resolver_setmaxqueries(dns_resolver_t *resolver, unsigned int queries); unsigned int dns_resolver_getmaxqueries(dns_resolver_t *resolver); /*% * Get and set how many iterative queries will be allowed before * terminating a recursive query. * * Requires: * \li resolver to be valid. */ void dns_resolver_setquotaresponse(dns_resolver_t *resolver, dns_quotatype_t which, isc_result_t resp); isc_result_t dns_resolver_getquotaresponse(dns_resolver_t *resolver, dns_quotatype_t which); /*% * Get and set the result code that will be used when quotas * are exceeded. If 'which' is set to quotatype "zone", then the * result specified in 'resp' will be used when the fetches-per-zone * quota is exceeded by a fetch. If 'which' is set to quotatype "server", * then the reuslt specified in 'resp' will be used when the * fetches-per-server quota has been exceeded for all the * authoritative servers for a zone. Valid choices are * DNS_R_DROP or DNS_R_SERVFAIL. * * Requires: * \li 'resolver' to be valid. * \li 'which' to be dns_quotatype_zone or dns_quotatype_server * \li 'resp' to be DNS_R_DROP or DNS_R_SERVFAIL. */ void dns_resolver_dumpfetches(dns_resolver_t *resolver, isc_statsformat_t format, FILE *fp); ISC_LANG_ENDDECLS #endif /* DNS_RESOLVER_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/ncache.h0000644000470500017500000001250512664710322020527 0ustar lamontlamont/* * Copyright (C) 2004-2010, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ncache.h,v 1.29 2010/05/14 23:50:40 tbox Exp $ */ #ifndef DNS_NCACHE_H #define DNS_NCACHE_H 1 /***** ***** Module Info *****/ /*! \file dns/ncache.h *\brief * DNS Ncache * * XXX TBS XXX * * MP: *\li The caller must ensure any required synchronization. * * Reliability: *\li No anticipated impact. * * Resources: *\li TBS * * Security: *\li No anticipated impact. * * Standards: *\li RFC2308 */ #include #include #include ISC_LANG_BEGINDECLS /*% * _OMITDNSSEC: * Omit DNSSEC records when rendering. */ #define DNS_NCACHETOWIRE_OMITDNSSEC 0x0001 isc_result_t dns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, dns_rdataset_t *addedrdataset); isc_result_t dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, isc_boolean_t optout, dns_rdataset_t *addedrdataset); /*%< * Convert the authority data from 'message' into a negative cache * rdataset, and store it in 'cache' at 'node' with a TTL limited to * 'maxttl'. * * \li dns_ncache_add produces a negative cache entry with a trust of no * more than answer * \li dns_ncache_addoptout produces a negative cache entry which will have * a trust of secure if all the records that make up the entry are secure. * * The 'covers' argument is the RR type whose nonexistence we are caching, * or dns_rdatatype_any when caching a NXDOMAIN response. * * 'optout' indicates a DNS_RDATASETATTR_OPTOUT should be set. * * Note: *\li If 'addedrdataset' is not NULL, then it will be attached to the added * rdataset. See dns_db_addrdataset() for more details. * * Requires: *\li 'message' is a valid message with a properly formatting negative cache * authority section. * *\li The requirements of dns_db_addrdataset() apply to 'cache', 'node', * 'now', and 'addedrdataset'. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOSPACE * *\li Any result code of dns_db_addrdataset() is a possible result code * of dns_ncache_add(). */ isc_result_t dns_ncache_towire(dns_rdataset_t *rdataset, dns_compress_t *cctx, isc_buffer_t *target, unsigned int options, unsigned int *countp); /*%< * Convert the negative caching rdataset 'rdataset' to wire format, * compressing names as specified in 'cctx', and storing the result in * 'target'. If 'omit_dnssec' is set, DNSSEC records will not * be added to 'target'. * * Notes: *\li The number of RRs added to target will be added to *countp. * * Requires: *\li 'rdataset' is a valid negative caching rdataset. * *\li 'rdataset' is not empty. * *\li 'countp' is a valid pointer. * * Ensures: *\li On a return of ISC_R_SUCCESS, 'target' contains a wire format * for the data contained in 'rdataset'. Any error return leaves * the buffer unchanged. * *\li *countp has been incremented by the number of RRs added to * target. * * Returns: *\li #ISC_R_SUCCESS - all ok *\li #ISC_R_NOSPACE - 'target' doesn't have enough room * *\li Any error returned by dns_rdata_towire(), dns_rdataset_next(), * dns_name_towire(). */ isc_result_t dns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name, dns_rdatatype_t type, dns_rdataset_t *rdataset); /*%< * Search the negative caching rdataset for an rdataset with the * specified name and type. * * Requires: *\li 'ncacherdataset' is a valid negative caching rdataset. * *\li 'ncacherdataset' is not empty. * *\li 'name' is a valid name. * *\li 'type' is not SIG, or a meta-RR type. * *\li 'rdataset' is a valid disassociated rdataset. * * Ensures: *\li On a return of ISC_R_SUCCESS, 'rdataset' is bound to the found * rdataset. * * Returns: *\li #ISC_R_SUCCESS - the rdataset was found. *\li #ISC_R_NOTFOUND - the rdataset was not found. * */ isc_result_t dns_ncache_getsigrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name, dns_rdatatype_t covers, dns_rdataset_t *rdataset); /*%< * Similar to dns_ncache_getrdataset() but get the rrsig that matches. */ void dns_ncache_current(dns_rdataset_t *ncacherdataset, dns_name_t *found, dns_rdataset_t *rdataset); /*%< * Extract the current rdataset and name from a ncache entry. * * Requires: * \li 'ncacherdataset' to be valid and to be a negative cache entry * \li 'found' to be valid. * \li 'rdataset' to be unassociated. */ ISC_LANG_ENDDECLS #endif /* DNS_NCACHE_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/compress.h0000644000470500017500000001412012664710322021134 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: compress.h,v 1.42 2009/01/17 23:47:43 tbox Exp $ */ #ifndef DNS_COMPRESS_H #define DNS_COMPRESS_H 1 #include #include #include ISC_LANG_BEGINDECLS #define DNS_COMPRESS_NONE 0x00 /*%< no compression */ #define DNS_COMPRESS_GLOBAL14 0x01 /*%< "normal" compression. */ #define DNS_COMPRESS_ALL 0x01 /*%< all compression. */ #define DNS_COMPRESS_CASESENSITIVE 0x02 /*%< case sensitive compression. */ /*! \file dns/compress.h * Direct manipulation of the structures is strongly discouraged. */ #define DNS_COMPRESS_TABLESIZE 64 #define DNS_COMPRESS_INITIALNODES 16 typedef struct dns_compressnode dns_compressnode_t; struct dns_compressnode { isc_region_t r; isc_uint16_t offset; isc_uint16_t count; isc_uint8_t labels; dns_compressnode_t *next; }; struct dns_compress { unsigned int magic; /*%< Magic number. */ unsigned int allowed; /*%< Allowed methods. */ int edns; /*%< Edns version or -1. */ /*% Global compression table. */ dns_compressnode_t *table[DNS_COMPRESS_TABLESIZE]; /*% Preallocated nodes for the table. */ dns_compressnode_t initialnodes[DNS_COMPRESS_INITIALNODES]; isc_uint16_t count; /*%< Number of nodes. */ isc_mem_t *mctx; /*%< Memory context. */ }; typedef enum { DNS_DECOMPRESS_ANY, /*%< Any compression */ DNS_DECOMPRESS_STRICT, /*%< Allowed compression */ DNS_DECOMPRESS_NONE /*%< No compression */ } dns_decompresstype_t; struct dns_decompress { unsigned int magic; /*%< Magic number. */ unsigned int allowed; /*%< Allowed methods. */ int edns; /*%< Edns version or -1. */ dns_decompresstype_t type; /*%< Strict checking */ }; isc_result_t dns_compress_init(dns_compress_t *cctx, int edns, isc_mem_t *mctx); /*%< * Initialise the compression context structure pointed to by 'cctx'. * * Requires: * \li 'cctx' is a valid dns_compress_t structure. * \li 'mctx' is an initialized memory context. * Ensures: * \li cctx->global is initialized. * * Returns: * \li #ISC_R_SUCCESS * \li failures from dns_rbt_create() */ void dns_compress_invalidate(dns_compress_t *cctx); /*%< * Invalidate the compression structure pointed to by cctx. * * Requires: *\li 'cctx' to be initialized. */ void dns_compress_setmethods(dns_compress_t *cctx, unsigned int allowed); /*%< * Sets allowed compression methods. * * Requires: *\li 'cctx' to be initialized. */ unsigned int dns_compress_getmethods(dns_compress_t *cctx); /*%< * Gets allowed compression methods. * * Requires: *\li 'cctx' to be initialized. * * Returns: *\li allowed compression bitmap. */ void dns_compress_setsensitive(dns_compress_t *cctx, isc_boolean_t sensitive); /* * Preserve the case of compressed domain names. * * Requires: * 'cctx' to be initialized. */ isc_boolean_t dns_compress_getsensitive(dns_compress_t *cctx); /* * Return whether case is to be preserved when compressing * domain names. * * Requires: * 'cctx' to be initialized. */ int dns_compress_getedns(dns_compress_t *cctx); /*%< * Gets edns value. * * Requires: *\li 'cctx' to be initialized. * * Returns: *\li -1 .. 255 */ isc_boolean_t dns_compress_findglobal(dns_compress_t *cctx, const dns_name_t *name, dns_name_t *prefix, isc_uint16_t *offset); /*%< * Finds longest possible match of 'name' in the global compression table. * * Requires: *\li 'cctx' to be initialized. *\li 'name' to be a absolute name. *\li 'prefix' to be initialized. *\li 'offset' to point to an isc_uint16_t. * * Ensures: *\li 'prefix' and 'offset' are valid if ISC_TRUE is returned. * * Returns: *\li #ISC_TRUE / #ISC_FALSE */ void dns_compress_add(dns_compress_t *cctx, const dns_name_t *name, const dns_name_t *prefix, isc_uint16_t offset); /*%< * Add compression pointers for 'name' to the compression table, * not replacing existing pointers. * * Requires: *\li 'cctx' initialized * *\li 'name' must be initialized and absolute, and must remain * valid until the message compression is complete. * *\li 'prefix' must be a prefix returned by * dns_compress_findglobal(), or the same as 'name'. */ void dns_compress_rollback(dns_compress_t *cctx, isc_uint16_t offset); /*%< * Remove any compression pointers from global table >= offset. * * Requires: *\li 'cctx' is initialized. */ void dns_decompress_init(dns_decompress_t *dctx, int edns, dns_decompresstype_t type); /*%< * Initializes 'dctx'. * Records 'edns' and 'type' into the structure. * * Requires: *\li 'dctx' to be a valid pointer. */ void dns_decompress_invalidate(dns_decompress_t *dctx); /*%< * Invalidates 'dctx'. * * Requires: *\li 'dctx' to be initialized */ void dns_decompress_setmethods(dns_decompress_t *dctx, unsigned int allowed); /*%< * Sets 'dctx->allowed' to 'allowed'. * * Requires: *\li 'dctx' to be initialized */ unsigned int dns_decompress_getmethods(dns_decompress_t *dctx); /*%< * Returns 'dctx->allowed' * * Requires: *\li 'dctx' to be initialized */ int dns_decompress_edns(dns_decompress_t *dctx); /*%< * Returns 'dctx->edns' * * Requires: *\li 'dctx' to be initialized */ dns_decompresstype_t dns_decompress_type(dns_decompress_t *dctx); /*%< * Returns 'dctx->type' * * Requires: *\li 'dctx' to be initialized */ ISC_LANG_ENDDECLS #endif /* DNS_COMPRESS_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/ttl.h0000644000470500017500000000411612664710322020110 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ttl.h,v 1.19 2007/06/19 23:47:17 tbox Exp $ */ #ifndef DNS_TTL_H #define DNS_TTL_H 1 /*! \file dns/ttl.h */ /*** *** Imports ***/ #include #include ISC_LANG_BEGINDECLS /*** *** Functions ***/ isc_result_t dns_ttl_totext(isc_uint32_t src, isc_boolean_t verbose, isc_buffer_t *target); /*%< * Output a TTL or other time interval in a human-readable form. * The time interval is given as a count of seconds in 'src'. * The text representation is appended to 'target'. * * If 'verbose' is ISC_FALSE, use the terse BIND 8 style, like "1w2d3h4m5s". * * If 'verbose' is ISC_TRUE, use a verbose style like the SOA comments * in "dig", like "1 week 2 days 3 hours 4 minutes 5 seconds". * * Returns: * \li ISC_R_SUCCESS * \li ISC_R_NOSPACE */ isc_result_t dns_counter_fromtext(isc_textregion_t *source, isc_uint32_t *ttl); /*%< * Converts a counter from either a plain number or a BIND 8 style value. * * Returns: *\li ISC_R_SUCCESS *\li DNS_R_SYNTAX */ isc_result_t dns_ttl_fromtext(isc_textregion_t *source, isc_uint32_t *ttl); /*%< * Converts a ttl from either a plain number or a BIND 8 style value. * * Returns: *\li ISC_R_SUCCESS *\li DNS_R_BADTTL */ ISC_LANG_ENDDECLS #endif /* DNS_TTL_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/clientinfo.h0000644000470500017500000000457012664710322021443 0ustar lamontlamont/* * Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: clientinfo.h,v 1.3 2011/10/11 23:46:45 tbox Exp $ */ #ifndef DNS_CLIENTINFO_H #define DNS_CLIENTINFO_H 1 /***** ***** Module Info *****/ /*! \file dns/clientinfo.h * \brief * The DNS clientinfo interface allows libdns to retrieve information * about the client from the caller. * * The clientinfo interface is used by the DNS DB and DLZ interfaces; * it allows databases to modify their answers on the basis of information * about the client, such as source IP address. * * dns_clientinfo_t contains a pointer to an opaque structure containing * client information in some form. dns_clientinfomethods_t contains a * list of methods which operate on that opaque structure to return * potentially useful data. Both structures also contain versioning * information. */ /***** ***** Imports *****/ #include #include ISC_LANG_BEGINDECLS /***** ***** Types *****/ #define DNS_CLIENTINFO_VERSION 1 typedef struct dns_clientinfo { isc_uint16_t version; void *data; } dns_clientinfo_t; typedef isc_result_t (*dns_clientinfo_sourceip_t)(dns_clientinfo_t *client, isc_sockaddr_t **addrp); #define DNS_CLIENTINFOMETHODS_VERSION 1 #define DNS_CLIENTINFOMETHODS_AGE 0 typedef struct dns_clientinfomethods { isc_uint16_t version; isc_uint16_t age; dns_clientinfo_sourceip_t sourceip; } dns_clientinfomethods_t; /***** ***** Methods *****/ void dns_clientinfomethods_init(dns_clientinfomethods_t *methods, dns_clientinfo_sourceip_t sourceip); void dns_clientinfo_init(dns_clientinfo_t *ci, void *data); ISC_LANG_ENDDECLS #endif /* DNS_CLIENTINFO_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/rcode.h0000644000470500017500000000567312664710322020412 0ustar lamontlamont/* * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rcode.h,v 1.21 2008/09/25 04:02:39 tbox Exp $ */ #ifndef DNS_RCODE_H #define DNS_RCODE_H 1 /*! \file dns/rcode.h */ #include #include ISC_LANG_BEGINDECLS isc_result_t dns_rcode_fromtext(dns_rcode_t *rcodep, isc_textregion_t *source); /*%< * Convert the text 'source' refers to into a DNS error value. * * Requires: *\li 'rcodep' is a valid pointer. * *\li 'source' is a valid text region. * * Returns: *\li #ISC_R_SUCCESS on success *\li #DNS_R_UNKNOWN type is unknown */ isc_result_t dns_rcode_totext(dns_rcode_t rcode, isc_buffer_t *target); /*%< * Put a textual representation of error 'rcode' into 'target'. * * Requires: *\li 'rcode' is a valid rcode. * *\li 'target' is a valid text buffer. * * Ensures: *\li If the result is success: * The used space in 'target' is updated. * * Returns: *\li #ISC_R_SUCCESS on success *\li #ISC_R_NOSPACE target buffer is too small */ isc_result_t dns_tsigrcode_fromtext(dns_rcode_t *rcodep, isc_textregion_t *source); /*%< * Convert the text 'source' refers to into a TSIG/TKEY error value. * * Requires: *\li 'rcodep' is a valid pointer. * *\li 'source' is a valid text region. * * Returns: *\li #ISC_R_SUCCESS on success *\li #DNS_R_UNKNOWN type is unknown */ isc_result_t dns_tsigrcode_totext(dns_rcode_t rcode, isc_buffer_t *target); /*%< * Put a textual representation of TSIG/TKEY error 'rcode' into 'target'. * * Requires: *\li 'rcode' is a valid TSIG/TKEY error code. * *\li 'target' is a valid text buffer. * * Ensures: *\li If the result is success: * The used space in 'target' is updated. * * Returns: *\li #ISC_R_SUCCESS on success *\li #ISC_R_NOSPACE target buffer is too small */ isc_result_t dns_hashalg_fromtext(unsigned char *hashalg, isc_textregion_t *source); /*%< * Convert the text 'source' refers to into a has algorithm value. * * Requires: *\li 'hashalg' is a valid pointer. * *\li 'source' is a valid text region. * * Returns: *\li #ISC_R_SUCCESS on success *\li #DNS_R_UNKNOWN type is unknown */ ISC_LANG_ENDDECLS #endif /* DNS_RCODE_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/portlist.h0000644000470500017500000000475312664710322021174 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: portlist.h,v 1.9 2007/06/19 23:47:17 tbox Exp $ */ /*! \file dns/portlist.h */ #include #include #include #include ISC_LANG_BEGINDECLS isc_result_t dns_portlist_create(isc_mem_t *mctx, dns_portlist_t **portlistp); /*%< * Create a port list. * * Requires: *\li 'mctx' to be valid. *\li 'portlistp' to be non NULL and '*portlistp' to be NULL; * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li #ISC_R_UNEXPECTED */ isc_result_t dns_portlist_add(dns_portlist_t *portlist, int af, in_port_t port); /*%< * Add the given tuple to the portlist. * * Requires: *\li 'portlist' to be valid. *\li 'af' to be AF_INET or AF_INET6 * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY */ void dns_portlist_remove(dns_portlist_t *portlist, int af, in_port_t port); /*%< * Remove the given tuple to the portlist. * * Requires: *\li 'portlist' to be valid. *\li 'af' to be AF_INET or AF_INET6 */ isc_boolean_t dns_portlist_match(dns_portlist_t *portlist, int af, in_port_t port); /*%< * Find the given tuple to the portlist. * * Requires: *\li 'portlist' to be valid. *\li 'af' to be AF_INET or AF_INET6 * * Returns * \li #ISC_TRUE if the tuple is found, ISC_FALSE otherwise. */ void dns_portlist_attach(dns_portlist_t *portlist, dns_portlist_t **portlistp); /*%< * Attach to a port list. * * Requires: *\li 'portlist' to be valid. *\li 'portlistp' to be non NULL and '*portlistp' to be NULL; */ void dns_portlist_detach(dns_portlist_t **portlistp); /*%< * Detach from a port list. * * Requires: *\li '*portlistp' to be valid. */ ISC_LANG_ENDDECLS bind9-9.10.3.dfsg.P4/lib/dns/include/dns/rdatalist.h0000644000470500017500000000551712664710322021302 0ustar lamontlamont/* * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rdatalist.h,v 1.22 2008/04/03 06:09:05 tbox Exp $ */ #ifndef DNS_RDATALIST_H #define DNS_RDATALIST_H 1 /***** ***** Module Info *****/ /*! \file dns/rdatalist.h * \brief * A DNS rdatalist is a list of rdata of a common type and class. * * MP: *\li Clients of this module must impose any required synchronization. * * Reliability: *\li No anticipated impact. * * Resources: *\li TBS * * Security: *\li No anticipated impact. * * Standards: *\li None. */ #include #include /*% * Clients may use this type directly. */ struct dns_rdatalist { dns_rdataclass_t rdclass; dns_rdatatype_t type; dns_rdatatype_t covers; dns_ttl_t ttl; ISC_LIST(dns_rdata_t) rdata; ISC_LINK(dns_rdatalist_t) link; }; ISC_LANG_BEGINDECLS void dns_rdatalist_init(dns_rdatalist_t *rdatalist); /*%< * Initialize rdatalist. * * Ensures: *\li All fields of rdatalist have been initialized to their default * values. */ isc_result_t dns_rdatalist_tordataset(dns_rdatalist_t *rdatalist, dns_rdataset_t *rdataset); /*%< * Make 'rdataset' refer to the rdata in 'rdatalist'. * * Note: *\li The caller must ensure that 'rdatalist' remains valid and unchanged * while 'rdataset' is associated with it. * * Requires: * *\li 'rdatalist' is a valid rdatalist. * *\li 'rdataset' is a valid rdataset that is not currently associated with * any rdata. * * Ensures, * on success, * *\li 'rdataset' is associated with the rdata in rdatalist. * * Returns: *\li #ISC_R_SUCCESS */ isc_result_t dns_rdatalist_fromrdataset(dns_rdataset_t *rdataset, dns_rdatalist_t **rdatalist); /*%< * Point 'rdatalist' to the rdatalist in 'rdataset'. * * Requires: * *\li 'rdatalist' is a pointer to a NULL dns_rdatalist_t pointer. * *\li 'rdataset' is a valid rdataset associated with an rdatalist. * * Ensures, * on success, * *\li 'rdatalist' is pointed to the rdatalist in rdataset. * * Returns: *\li #ISC_R_SUCCESS */ ISC_LANG_ENDDECLS #endif /* DNS_RDATALIST_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/rdata.h0000644000470500017500000005250512664710322020405 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rdata.h,v 1.80 2011/03/20 02:31:53 marka Exp $ */ #ifndef DNS_RDATA_H #define DNS_RDATA_H 1 /***** ***** Module Info *****/ /*! \file dns/rdata.h * \brief * Provides facilities for manipulating DNS rdata, including conversions to * and from wire format and text format. * * Given the large amount of rdata possible in a nameserver, it was important * to come up with a very efficient way of storing rdata, but at the same * time allow it to be manipulated. * * The decision was to store rdata in uncompressed wire format, * and not to make it a fully abstracted object; i.e. certain parts of the * server know rdata is stored that way. This saves a lot of memory, and * makes adding rdata to messages easy. Having much of the server know * the representation would be perilous, and we certainly don't want each * user of rdata to be manipulating such a low-level structure. This is * where the rdata module comes in. The module allows rdata handles to be * created and attached to uncompressed wire format regions. All rdata * operations and conversions are done through these handles. * * Implementation Notes: * *\li The routines in this module are expected to be synthesized by the * build process from a set of source files, one per rdata type. For * portability, it's probably best that the building be done by a C * program. Adding a new rdata type will be a simple matter of adding * a file to a directory and rebuilding the server. *All* knowledge of * the format of a particular rdata type is in this file. * * MP: *\li Clients of this module must impose any required synchronization. * * Reliability: *\li This module deals with low-level byte streams. Errors in any of * the functions are likely to crash the server or corrupt memory. * *\li Rdata is typed, and the caller must know what type of rdata it has. * A caller that gets this wrong could crash the server. * *\li The fromstruct() and tostruct() routines use a void * pointer to * represent the structure. The caller must ensure that it passes a * pointer to the appropriate type, or the server could crash or memory * could be corrupted. * * Resources: *\li None. * * Security: * *\li *** WARNING *** * dns_rdata_fromwire() deals with raw network data. An error in * this routine could result in the failure or hijacking of the server. * * Standards: *\li RFC1035 *\li Draft EDNS0 (0) *\li Draft EDNS1 (0) *\li Draft Binary Labels (2) *\li Draft Local Compression (1) *\li Various RFCs for particular types; these will be documented in the * sources files of the types. * */ /*** *** Imports ***/ #include #include #include #include ISC_LANG_BEGINDECLS /*** *** Types ***/ /*% ***** An 'rdata' is a handle to a binary region. The handle has an RR ***** class and type, and the data in the binary region is in the format ***** of the given class and type. *****/ /*% * Clients are strongly discouraged from using this type directly, with * the exception of the 'link' field which may be used directly for whatever * purpose the client desires. */ struct dns_rdata { unsigned char * data; unsigned int length; dns_rdataclass_t rdclass; dns_rdatatype_t type; unsigned int flags; ISC_LINK(dns_rdata_t) link; }; #define DNS_RDATA_INIT { NULL, 0, 0, 0, 0, {(void*)(-1), (void *)(-1)}} #define DNS_RDATA_CHECKINITIALIZED #ifdef DNS_RDATA_CHECKINITIALIZED #define DNS_RDATA_INITIALIZED(rdata) \ ((rdata)->data == NULL && (rdata)->length == 0 && \ (rdata)->rdclass == 0 && (rdata)->type == 0 && (rdata)->flags == 0 && \ !ISC_LINK_LINKED((rdata), link)) #else #ifdef ISC_LIST_CHECKINIT #define DNS_RDATA_INITIALIZED(rdata) \ (!ISC_LINK_LINKED((rdata), link)) #else #define DNS_RDATA_INITIALIZED(rdata) ISC_TRUE #endif #endif #define DNS_RDATA_UPDATE 0x0001 /*%< update pseudo record. */ #define DNS_RDATA_OFFLINE 0x0002 /*%< RRSIG has a offline key. */ #define DNS_RDATA_VALIDFLAGS(rdata) \ (((rdata)->flags & ~(DNS_RDATA_UPDATE|DNS_RDATA_OFFLINE)) == 0) /* * The maximum length of a RDATA that can be sent on the wire. * Max packet size (65535) less header (12), less name (1), type (2), * class (2), ttl(4), length (2). * * None of the defined types that support name compression can exceed * this and all new types are to be sent uncompressed. */ #define DNS_RDATA_MAXLENGTH 65512U /* * Flags affecting rdata formatting style. Flags 0xFFFF0000 * are used by masterfile-level formatting and defined elsewhere. * See additional comments at dns_rdata_tofmttext(). */ /*% Split the rdata into multiple lines to try to keep it within the "width". */ #define DNS_STYLEFLAG_MULTILINE 0x00000001U /*% Output explanatory comments. */ #define DNS_STYLEFLAG_COMMENT 0x00000002U #define DNS_STYLEFLAG_RRCOMMENT 0x00000004U /*% Output KEYDATA in human readable format. */ #define DNS_STYLEFLAG_KEYDATA 0x00000008U #define DNS_RDATA_DOWNCASE DNS_NAME_DOWNCASE #define DNS_RDATA_CHECKNAMES DNS_NAME_CHECKNAMES #define DNS_RDATA_CHECKNAMESFAIL DNS_NAME_CHECKNAMESFAIL #define DNS_RDATA_CHECKREVERSE DNS_NAME_CHECKREVERSE #define DNS_RDATA_CHECKMX DNS_NAME_CHECKMX #define DNS_RDATA_CHECKMXFAIL DNS_NAME_CHECKMXFAIL #define DNS_RDATA_UNKNOWNESCAPE 0x80000000 /*** *** Initialization ***/ void dns_rdata_init(dns_rdata_t *rdata); /*%< * Make 'rdata' empty. * * Requires: * 'rdata' is a valid rdata (i.e. not NULL, points to a struct dns_rdata) */ void dns_rdata_reset(dns_rdata_t *rdata); /*%< * Make 'rdata' empty. * * Requires: *\li 'rdata' is a previously initialized rdata and is not linked. */ void dns_rdata_clone(const dns_rdata_t *src, dns_rdata_t *target); /*%< * Clone 'target' from 'src'. * * Requires: *\li 'src' to be initialized. *\li 'target' to be initialized. */ /*** *** Comparisons ***/ int dns_rdata_compare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2); /*%< * Determine the relative ordering under the DNSSEC order relation of * 'rdata1' and 'rdata2'. * * Requires: * *\li 'rdata1' is a valid, non-empty rdata * *\li 'rdata2' is a valid, non-empty rdata * * Returns: *\li < 0 'rdata1' is less than 'rdata2' *\li 0 'rdata1' is equal to 'rdata2' *\li > 0 'rdata1' is greater than 'rdata2' */ int dns_rdata_casecompare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2); /*%< * dns_rdata_casecompare() is similar to dns_rdata_compare() but also * compares domain names case insensitively in known rdata types that * are treated as opaque data by dns_rdata_compare(). * * Requires: * *\li 'rdata1' is a valid, non-empty rdata * *\li 'rdata2' is a valid, non-empty rdata * * Returns: *\li < 0 'rdata1' is less than 'rdata2' *\li 0 'rdata1' is equal to 'rdata2' *\li > 0 'rdata1' is greater than 'rdata2' */ /*** *** Conversions ***/ void dns_rdata_fromregion(dns_rdata_t *rdata, dns_rdataclass_t rdclass, dns_rdatatype_t type, isc_region_t *r); /*%< * Make 'rdata' refer to region 'r'. * * Requires: * *\li The data in 'r' is properly formatted for whatever type it is. */ void dns_rdata_toregion(const dns_rdata_t *rdata, isc_region_t *r); /*%< * Make 'r' refer to 'rdata'. */ isc_result_t dns_rdata_fromwire(dns_rdata_t *rdata, dns_rdataclass_t rdclass, dns_rdatatype_t type, isc_buffer_t *source, dns_decompress_t *dctx, unsigned int options, isc_buffer_t *target); /*%< * Copy the possibly-compressed rdata at source into the target region. * * Notes: *\li Name decompression policy is controlled by 'dctx'. * * 'options' *\li DNS_RDATA_DOWNCASE downcase domain names when they are copied * into target. * * Requires: * *\li 'rdclass' and 'type' are valid. * *\li 'source' is a valid buffer, and the active region of 'source' * references the rdata to be processed. * *\li 'target' is a valid buffer. * *\li 'dctx' is a valid decompression context. * * Ensures, * if result is success: * \li If 'rdata' is not NULL, it is attached to the target. * \li The conditions dns_name_fromwire() ensures for names hold * for all names in the rdata. * \li The current location in source is advanced, and the used space * in target is updated. * * Result: *\li Success *\li Any non-success status from dns_name_fromwire() *\li Various 'Bad Form' class failures depending on class and type *\li Bad Form: Input too short *\li Resource Limit: Not enough space */ isc_result_t dns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx, isc_buffer_t *target); /*%< * Convert 'rdata' into wire format, compressing it as specified by the * compression context 'cctx', and storing the result in 'target'. * * Notes: *\li If the compression context allows global compression, then the * global compression table may be updated. * * Requires: *\li 'rdata' is a valid, non-empty rdata * *\li target is a valid buffer * *\li Any offsets specified in a global compression table are valid * for target. * * Ensures, * if the result is success: * \li The used space in target is updated. * * Returns: *\li Success *\li Any non-success status from dns_name_towire() *\li Resource Limit: Not enough space */ isc_result_t dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass, dns_rdatatype_t type, isc_lex_t *lexer, dns_name_t *origin, unsigned int options, isc_mem_t *mctx, isc_buffer_t *target, dns_rdatacallbacks_t *callbacks); /*%< * Convert the textual representation of a DNS rdata into uncompressed wire * form stored in the target region. Tokens constituting the text of the rdata * are taken from 'lexer'. * * Notes: *\li Relative domain names in the rdata will have 'origin' appended to them. * A NULL origin implies "origin == dns_rootname". * * * 'options' *\li DNS_RDATA_DOWNCASE downcase domain names when they are copied * into target. *\li DNS_RDATA_CHECKNAMES perform checknames checks. *\li DNS_RDATA_CHECKNAMESFAIL fail if the checknames check fail. If * not set a warning will be issued. *\li DNS_RDATA_CHECKREVERSE this should set if the owner name ends * in IP6.ARPA, IP6.INT or IN-ADDR.ARPA. * * Requires: * *\li 'rdclass' and 'type' are valid. * *\li 'lexer' is a valid isc_lex_t. * *\li 'mctx' is a valid isc_mem_t. * *\li 'target' is a valid region. * *\li 'origin' if non NULL it must be absolute. * *\li 'callbacks' to be NULL or callbacks->warn and callbacks->error be * initialized. * * Ensures, * if result is success: *\li If 'rdata' is not NULL, it is attached to the target. *\li The conditions dns_name_fromtext() ensures for names hold * for all names in the rdata. *\li The used space in target is updated. * * Result: *\li Success *\li Translated result codes from isc_lex_gettoken *\li Various 'Bad Form' class failures depending on class and type *\li Bad Form: Input too short *\li Resource Limit: Not enough space *\li Resource Limit: Not enough memory */ isc_result_t dns_rdata_totext(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target); /*%< * Convert 'rdata' into text format, storing the result in 'target'. * The text will consist of a single line, with fields separated by * single spaces. * * Notes: *\li If 'origin' is not NULL, then any names in the rdata that are * subdomains of 'origin' will be made relative it. * *\li XXX Do we *really* want to support 'origin'? I'm inclined towards "no" * at the moment. * * Requires: * *\li 'rdata' is a valid, non-empty rdata * *\li 'origin' is NULL, or is a valid name * *\li 'target' is a valid text buffer * * Ensures, * if the result is success: * * \li The used space in target is updated. * * Returns: *\li Success *\li Any non-success status from dns_name_totext() *\li Resource Limit: Not enough space */ isc_result_t dns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin, unsigned int flags, unsigned int width, unsigned int split_width, const char *linebreak, isc_buffer_t *target); /*%< * Like dns_rdata_totext, but do formatted output suitable for * database dumps. This is intended for use by dns_db_dump(); * library users are discouraged from calling it directly. * * If (flags & #DNS_STYLEFLAG_MULTILINE) != 0, attempt to stay * within 'width' by breaking the text into multiple lines. * The string 'linebreak' is inserted between lines, and parentheses * are added when necessary. Because RRs contain unbreakable elements * such as domain names whose length is variable, unpredictable, and * potentially large, there is no guarantee that the lines will * not exceed 'width' anyway. * * If (flags & #DNS_STYLEFLAG_MULTILINE) == 0, the rdata is always * printed as a single line, and no parentheses are used. * The 'width' and 'linebreak' arguments are ignored. * * If (flags & #DNS_STYLEFLAG_COMMENT) != 0, output explanatory * comments next to things like the SOA timer fields. Some * comments (e.g., the SOA ones) are only printed when multiline * output is selected. * * base64 rdata text (e.g., DNSKEY records) will be split into chunks * of 'split_width' characters. If split_width == 0, the text will * not be split at all. If split_width == UINT_MAX (0xffffffff), then * it is undefined and falls back to the default value of 'width' */ isc_result_t dns_rdata_fromstruct(dns_rdata_t *rdata, dns_rdataclass_t rdclass, dns_rdatatype_t type, void *source, isc_buffer_t *target); /*%< * Convert the C structure representation of an rdata into uncompressed wire * format in 'target'. * * XXX Should we have a 'size' parameter as a sanity check on target? * * Requires: * *\li 'rdclass' and 'type' are valid. * *\li 'source' points to a valid C struct for the class and type. * *\li 'target' is a valid buffer. * *\li All structure pointers to memory blocks should be NULL if their * corresponding length values are zero. * * Ensures, * if result is success: * \li If 'rdata' is not NULL, it is attached to the target. * * \li The used space in 'target' is updated. * * Result: *\li Success *\li Various 'Bad Form' class failures depending on class and type *\li Resource Limit: Not enough space */ isc_result_t dns_rdata_tostruct(dns_rdata_t *rdata, void *target, isc_mem_t *mctx); /*%< * Convert an rdata into its C structure representation. * * If 'mctx' is NULL then 'rdata' must persist while 'target' is being used. * * If 'mctx' is non NULL then memory will be allocated if required. * * Requires: * *\li 'rdata' is a valid, non-empty rdata. * *\li 'target' to point to a valid pointer for the type and class. * * Result: *\li Success *\li Resource Limit: Not enough memory */ void dns_rdata_freestruct(void *source); /*%< * Free dynamic memory attached to 'source' (if any). * * Requires: * *\li 'source' to point to the structure previously filled in by * dns_rdata_tostruct(). */ isc_boolean_t dns_rdatatype_ismeta(dns_rdatatype_t type); /*%< * Return true iff the rdata type 'type' is a meta-type * like ANY or AXFR. */ isc_boolean_t dns_rdatatype_issingleton(dns_rdatatype_t type); /*%< * Return true iff the rdata type 'type' is a singleton type, * like CNAME or SOA. * * Requires: * \li 'type' is a valid rdata type. * */ isc_boolean_t dns_rdataclass_ismeta(dns_rdataclass_t rdclass); /*%< * Return true iff the rdata class 'rdclass' is a meta-class * like ANY or NONE. */ isc_boolean_t dns_rdatatype_isdnssec(dns_rdatatype_t type); /*%< * Return true iff 'type' is one of the DNSSEC * rdata types that may exist alongside a CNAME record. * * Requires: * \li 'type' is a valid rdata type. */ isc_boolean_t dns_rdatatype_iszonecutauth(dns_rdatatype_t type); /*%< * Return true iff rdata of type 'type' is considered authoritative * data (not glue) in the NSEC chain when it occurs in the parent zone * at a zone cut. * * Requires: * \li 'type' is a valid rdata type. * */ isc_boolean_t dns_rdatatype_isknown(dns_rdatatype_t type); /*%< * Return true iff the rdata type 'type' is known. * * Requires: * \li 'type' is a valid rdata type. * */ isc_result_t dns_rdata_additionaldata(dns_rdata_t *rdata, dns_additionaldatafunc_t add, void *arg); /*%< * Call 'add' for each name and type from 'rdata' which is subject to * additional section processing. * * Requires: * *\li 'rdata' is a valid, non-empty rdata. * *\li 'add' is a valid dns_additionalfunc_t. * * Ensures: * *\li If successful, then add() will have been called for each name * and type subject to additional section processing. * *\li If add() returns something other than #ISC_R_SUCCESS, that result * will be returned as the result of dns_rdata_additionaldata(). * * Returns: * *\li ISC_R_SUCCESS * *\li Many other results are possible if not successful. */ isc_result_t dns_rdata_digest(dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg); /*%< * Send 'rdata' in DNSSEC canonical form to 'digest'. * * Note: *\li 'digest' may be called more than once by dns_rdata_digest(). The * concatenation of all the regions, in the order they were given * to 'digest', will be the DNSSEC canonical form of 'rdata'. * * Requires: * *\li 'rdata' is a valid, non-empty rdata. * *\li 'digest' is a valid dns_digestfunc_t. * * Ensures: * *\li If successful, then all of the rdata's data has been sent, in * DNSSEC canonical form, to 'digest'. * *\li If digest() returns something other than ISC_R_SUCCESS, that result * will be returned as the result of dns_rdata_digest(). * * Returns: * *\li ISC_R_SUCCESS * *\li Many other results are possible if not successful. */ isc_boolean_t dns_rdatatype_questiononly(dns_rdatatype_t type); /*%< * Return true iff rdata of type 'type' can only appear in the question * section of a properly formatted message. * * Requires: * \li 'type' is a valid rdata type. * */ isc_boolean_t dns_rdatatype_notquestion(dns_rdatatype_t type); /*%< * Return true iff rdata of type 'type' can not appear in the question * section of a properly formatted message. * * Requires: * \li 'type' is a valid rdata type. * */ isc_boolean_t dns_rdatatype_atparent(dns_rdatatype_t type); /*%< * Return true iff rdata of type 'type' should appear at the parent of * a zone cut. * * Requires: * \li 'type' is a valid rdata type. * */ unsigned int dns_rdatatype_attributes(dns_rdatatype_t rdtype); /*%< * Return attributes for the given type. * * Requires: *\li 'rdtype' are known. * * Returns: *\li a bitmask consisting of the following flags. */ /*% only one may exist for a name */ #define DNS_RDATATYPEATTR_SINGLETON 0x00000001U /*% requires no other data be present */ #define DNS_RDATATYPEATTR_EXCLUSIVE 0x00000002U /*% Is a meta type */ #define DNS_RDATATYPEATTR_META 0x00000004U /*% Is a DNSSEC type, like RRSIG or NSEC */ #define DNS_RDATATYPEATTR_DNSSEC 0x00000008U /*% Is a zone cut authority type */ #define DNS_RDATATYPEATTR_ZONECUTAUTH 0x00000010U /*% Is reserved (unusable) */ #define DNS_RDATATYPEATTR_RESERVED 0x00000020U /*% Is an unknown type */ #define DNS_RDATATYPEATTR_UNKNOWN 0x00000040U /*% Is META, and can only be in a question section */ #define DNS_RDATATYPEATTR_QUESTIONONLY 0x00000080U /*% is META, and can NOT be in a question section */ #define DNS_RDATATYPEATTR_NOTQUESTION 0x00000100U /*% Is present at zone cuts in the parent, not the child */ #define DNS_RDATATYPEATTR_ATPARENT 0x00000200U dns_rdatatype_t dns_rdata_covers(dns_rdata_t *rdata); /*%< * Return the rdatatype that this type covers. * * Requires: *\li 'rdata' is a valid, non-empty rdata. * *\li 'rdata' is a type that covers other rdata types. * * Returns: *\li The type covered. */ isc_boolean_t dns_rdata_checkowner(dns_name_t* name, dns_rdataclass_t rdclass, dns_rdatatype_t type, isc_boolean_t wildcard); /* * Returns whether this is a valid ownername for this . * If wildcard is true allow the first label to be a wildcard if * appropriate. * * Requires: * 'name' is a valid name. */ isc_boolean_t dns_rdata_checknames(dns_rdata_t *rdata, dns_name_t *owner, dns_name_t *bad); /* * Returns whether 'rdata' contains valid domain names. The checks are * sensitive to the owner name. * * If 'bad' is non-NULL and a domain name fails the check the * the offending name will be return in 'bad' by cloning from * the 'rdata' contents. * * Requires: * 'rdata' to be valid. * 'owner' to be valid. * 'bad' to be NULL or valid. */ void dns_rdata_exists(dns_rdata_t *rdata, dns_rdatatype_t type); void dns_rdata_notexist(dns_rdata_t *rdata, dns_rdatatype_t type); void dns_rdata_deleterrset(dns_rdata_t *rdata, dns_rdatatype_t type); void dns_rdata_makedelete(dns_rdata_t *rdata); const char * dns_rdata_updateop(dns_rdata_t *rdata, dns_section_t section); ISC_LANG_ENDDECLS #endif /* DNS_RDATA_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/opcode.h0000644000470500017500000000276412664710322020565 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: opcode.h,v 1.8 2007/06/19 23:47:17 tbox Exp $ */ #ifndef DNS_OPCODE_H #define DNS_OPCODE_H 1 /*! \file dns/opcode.h */ #include #include ISC_LANG_BEGINDECLS isc_result_t dns_opcode_totext(dns_opcode_t opcode, isc_buffer_t *target); /*%< * Put a textual representation of error 'opcode' into 'target'. * * Requires: *\li 'opcode' is a valid opcode. * *\li 'target' is a valid text buffer. * * Ensures: *\li If the result is success: * The used space in 'target' is updated. * * Returns: *\li #ISC_R_SUCCESS on success *\li #ISC_R_NOSPACE target buffer is too small */ ISC_LANG_ENDDECLS #endif /* DNS_OPCODE_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/cache.h0000644000470500017500000002075112664710322020353 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: cache.h,v 1.32 2011/08/02 23:47:52 tbox Exp $ */ #ifndef DNS_CACHE_H #define DNS_CACHE_H 1 /***** ***** Module Info *****/ /*! \file dns/cache.h * \brief * Defines dns_cache_t, the cache object. * * Notes: *\li A cache object contains DNS data of a single class. * Multiple classes will be handled by creating multiple * views, each with a different class and its own cache. * * MP: *\li See notes at the individual functions. * * Reliability: * * Resources: * * Security: * * Standards: */ /*** *** Imports ***/ #include #include #include #include #include ISC_LANG_BEGINDECLS /*** *** Functions ***/ isc_result_t dns_cache_create(isc_mem_t *cmctx, isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr, dns_rdataclass_t rdclass, const char *db_type, unsigned int db_argc, char **db_argv, dns_cache_t **cachep); isc_result_t dns_cache_create2(isc_mem_t *cmctx, isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr, dns_rdataclass_t rdclass, const char *cachename, const char *db_type, unsigned int db_argc, char **db_argv, dns_cache_t **cachep); isc_result_t dns_cache_create3(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr, dns_rdataclass_t rdclass, const char *cachename, const char *db_type, unsigned int db_argc, char **db_argv, dns_cache_t **cachep); /*%< * Create a new DNS cache. * * dns_cache_create2() will create a named cache. * * dns_cache_create3() will create a named cache using two separate memory * contexts, one for cache data which can be cleaned and a separate one for * memory allocated for the heap (which can grow without an upper limit and * has no mechanism for shrinking). * * dns_cache_create() is a backward compatible version that internally * specifies an empty cache name and a single memory context. * * Requires: * *\li 'cmctx' (and 'hmctx' if applicable) is a valid memory context. * *\li 'taskmgr' is a valid task manager and 'timermgr' is a valid timer * manager, or both are NULL. If NULL, no periodic cleaning of the * cache will take place. * *\li 'cachename' is a valid string. This must not be NULL. * *\li 'cachep' is a valid pointer, and *cachep == NULL * * Ensures: * *\li '*cachep' is attached to the newly created cache * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY */ void dns_cache_attach(dns_cache_t *cache, dns_cache_t **targetp); /*%< * Attach *targetp to cache. * * Requires: * *\li 'cache' is a valid cache. * *\li 'targetp' points to a NULL dns_cache_t *. * * Ensures: * *\li *targetp is attached to cache. */ void dns_cache_detach(dns_cache_t **cachep); /*%< * Detach *cachep from its cache. * * Requires: * *\li 'cachep' points to a valid cache. * * Ensures: * *\li *cachep is NULL. * *\li If '*cachep' is the last reference to the cache, * all resources used by the cache will be freed */ void dns_cache_attachdb(dns_cache_t *cache, dns_db_t **dbp); /*%< * Attach *dbp to the cache's database. * * Notes: * *\li This may be used to get a reference to the database for * the purpose of cache lookups (XXX currently it is also * the way to add data to the cache, but having a * separate dns_cache_add() interface instead would allow * more control over memory usage). * The caller should call dns_db_detach() on the reference * when it is no longer needed. * * Requires: * *\li 'cache' is a valid cache. * *\li 'dbp' points to a NULL dns_db *. * * Ensures: * *\li *dbp is attached to the database. */ isc_result_t dns_cache_setfilename(dns_cache_t *cache, const char *filename); /*%< * If 'filename' is non-NULL, make the cache persistent. * The cache's data will be stored in the given file. * If 'filename' is NULL, make the cache non-persistent. * Files that are no longer used are not unlinked automatically. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li Various file-related failures */ isc_result_t dns_cache_load(dns_cache_t *cache); /*%< * If the cache has a file name, load the cache contents from the file. * Previous cache contents are not discarded. * If no file name has been set, do nothing and return success. * * MT: *\li Multiple simultaneous attempts to load or dump the cache * will be serialized with respect to one another, but * the cache may be read and updated while the dump is * in progress. Updates performed during loading * may or may not be preserved, and reads may return * either the old or the newly loaded data. * * Returns: * *\li #ISC_R_SUCCESS * \li Various failures depending on the database implementation type */ isc_result_t dns_cache_dump(dns_cache_t *cache); /*%< * If the cache has a file name, write the cache contents to disk, * overwriting any preexisting file. If no file name has been set, * do nothing and return success. * * MT: *\li Multiple simultaneous attempts to load or dump the cache * will be serialized with respect to one another, but * the cache may be read and updated while the dump is * in progress. Updates performed during the dump may * or may not be reflected in the dumped file. * * Returns: * *\li #ISC_R_SUCCESS * \li Various failures depending on the database implementation type */ isc_result_t dns_cache_clean(dns_cache_t *cache, isc_stdtime_t now); /*%< * Force immediate cleaning of the cache, freeing all rdatasets * whose TTL has expired as of 'now' and that have no pending * references. */ void dns_cache_setcleaninginterval(dns_cache_t *cache, unsigned int interval); /*%< * Set the periodic cache cleaning interval to 'interval' seconds. */ unsigned int dns_cache_getcleaninginterval(dns_cache_t *cache); /*%< * Get the periodic cache cleaning interval to 'interval' seconds. */ const char * dns_cache_getname(dns_cache_t *cache); /*%< * Get the cache name. */ void dns_cache_setcachesize(dns_cache_t *cache, size_t size); /*%< * Set the maximum cache size. 0 means unlimited. */ size_t dns_cache_getcachesize(dns_cache_t *cache); /*%< * Get the maximum cache size. */ isc_result_t dns_cache_flush(dns_cache_t *cache); /*%< * Flushes all data from the cache. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY */ isc_result_t dns_cache_flushnode(dns_cache_t *cache, dns_name_t *name, isc_boolean_t tree); /* * Flush a given name from the cache. If 'tree' is true, then * also flush all names under 'name'. * * Requires: *\li 'cache' to be valid. *\li 'name' to be valid. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li other error returns. */ isc_result_t dns_cache_flushname(dns_cache_t *cache, dns_name_t *name); /* * Flush a given name from the cache. Equivalent to * dns_cache_flushpartial(cache, name, ISC_FALSE). * * Requires: *\li 'cache' to be valid. *\li 'name' to be valid. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li other error returns. */ isc_stats_t * dns_cache_getstats(dns_cache_t *cache); /* * Return a pointer to the stats collection object for 'cache' */ void dns_cache_dumpstats(dns_cache_t *cache, FILE *fp); /* * Dump cache statistics and status in text to 'fp' */ void dns_cache_updatestats(dns_cache_t *cache, isc_result_t result); /* * Update cache statistics based on result code in 'result' */ #ifdef HAVE_LIBXML2 int dns_cache_renderxml(dns_cache_t *cache, xmlTextWriterPtr writer); /* * Render cache statistics and status in XML for 'writer'. */ #endif /* HAVE_LIBXML2 */ #ifdef HAVE_JSON isc_result_t dns_cache_renderjson(dns_cache_t *cache, json_object *cstats); /* * Render cache statistics and status in JSON */ #endif /* HAVE_JSON */ ISC_LANG_ENDDECLS #endif /* DNS_CACHE_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/nsec3.h0000644000470500017500000002042712664710322020323 0ustar lamontlamont/* * Copyright (C) 2008-2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: nsec3.h,v 1.14 2011/10/28 12:20:31 tbox Exp $ */ #ifndef DNS_NSEC3_H #define DNS_NSEC3_H 1 #include #include #include #include #include #include #include #define DNS_NSEC3_SALTSIZE 255 /* * hash = 1, flags =1, iterations = 2, salt length = 1, salt = 255 (max) * hash length = 1, hash = 255 (max), bitmap = 8192 + 512 (max) */ #define DNS_NSEC3_BUFFERSIZE (6 + 255 + 255 + 8192 + 512) /* * hash = 1, flags = 1, iterations = 2, salt length = 1, salt = 255 (max) */ #define DNS_NSEC3PARAM_BUFFERSIZE (5 + 255) /* * Test "unknown" algorithm. Is mapped to dns_hash_sha1. */ #define DNS_NSEC3_UNKNOWNALG ((dns_hash_t)245U) ISC_LANG_BEGINDECLS isc_result_t dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, unsigned int hashalg, unsigned int optin, unsigned int iterations, const unsigned char *salt, size_t salt_length, const unsigned char *nexthash, size_t hash_length, unsigned char *buffer, dns_rdata_t *rdata); /*%< * Build the rdata of a NSEC3 record for the data at 'node'. * Note: 'node' is not the node where the NSEC3 record will be stored. * * Requires: * buffer Points to a temporary buffer of at least * DNS_NSEC_BUFFERSIZE bytes. * rdata Points to an initialized dns_rdata_t. * * Ensures: * *rdata Contains a valid NSEC3 rdata. The 'data' member refers * to 'buffer'. */ isc_boolean_t dns_nsec3_typepresent(dns_rdata_t *nsec, dns_rdatatype_t type); /*%< * Determine if a type is marked as present in an NSEC3 record. * * Requires: * 'nsec' points to a valid rdataset of type NSEC3 */ isc_result_t dns_nsec3_hashname(dns_fixedname_t *result, unsigned char rethash[NSEC3_MAX_HASH_LENGTH], size_t *hash_length, dns_name_t *name, dns_name_t *origin, dns_hash_t hashalg, unsigned int iterations, const unsigned char *salt, size_t saltlength); /*%< * Make a hashed domain name from an unhashed one. If rethash is not NULL * the raw hash is stored there. */ unsigned int dns_nsec3_hashlength(dns_hash_t hash); /*%< * Return the length of the hash produced by the specified algorithm * or zero when unknown. */ isc_boolean_t dns_nsec3_supportedhash(dns_hash_t hash); /*%< * Return whether we support this hash algorithm or not. */ isc_result_t dns_nsec3_addnsec3(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, const dns_rdata_nsec3param_t *nsec3param, dns_ttl_t nsecttl, isc_boolean_t unsecure, dns_diff_t *diff); isc_result_t dns_nsec3_addnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, dns_ttl_t nsecttl, isc_boolean_t unsecure, dns_diff_t *diff); isc_result_t dns_nsec3_addnsec3sx(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, dns_ttl_t nsecttl, isc_boolean_t unsecure, dns_rdatatype_t private, dns_diff_t *diff); /*%< * Add NSEC3 records for 'name', recording the change in 'diff'. * Adjust previous NSEC3 records, if any, to reflect the addition. * The existing NSEC3 records are removed. * * dns_nsec3_addnsec3() will only add records to the chain identified by * 'nsec3param'. * * 'unsecure' should be set to reflect if this is a potentially * unsecure delegation (no DS record). * * dns_nsec3_addnsec3s() will examine the NSEC3PARAM RRset to determine which * chains to be updated. NSEC3PARAM records with the DNS_NSEC3FLAG_CREATE * will be preferentially chosen over NSEC3PARAM records without * DNS_NSEC3FLAG_CREATE set. NSEC3PARAM records with DNS_NSEC3FLAG_REMOVE * set will be ignored by dns_nsec3_addnsec3s(). If DNS_NSEC3FLAG_CREATE * is set then the new NSEC3 will have OPTOUT set to match the that in the * NSEC3PARAM record otherwise OPTOUT will be inherited from the previous * record in the chain. * * dns_nsec3_addnsec3sx() is similar to dns_nsec3_addnsec3s() but 'private' * specifies the type of the private rdataset to be checked in addition to * the nsec3param rdataset at the zone apex. * * Requires: * 'db' to be valid. * 'version' to be valid or NULL. * 'name' to be valid. * 'nsec3param' to be valid. * 'diff' to be valid. */ isc_result_t dns_nsec3_delnsec3(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff); isc_result_t dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, dns_diff_t *diff); isc_result_t dns_nsec3_delnsec3sx(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, dns_rdatatype_t private, dns_diff_t *diff); /*%< * Remove NSEC3 records for 'name', recording the change in 'diff'. * Adjust previous NSEC3 records, if any, to reflect the removal. * * dns_nsec3_delnsec3() performs the above for the chain identified by * 'nsec3param'. * * dns_nsec3_delnsec3s() examines the NSEC3PARAM RRset in a similar manner * to dns_nsec3_addnsec3s(). Unlike dns_nsec3_addnsec3s() updated NSEC3 * records have the OPTOUT flag preserved. * * dns_nsec3_delnsec3sx() is similar to dns_nsec3_delnsec3s() but 'private' * specifies the type of the private rdataset to be checked in addition to * the nsec3param rdataset at the zone apex. * * Requires: * 'db' to be valid. * 'version' to be valid or NULL. * 'name' to be valid. * 'nsec3param' to be valid. * 'diff' to be valid. */ isc_result_t dns_nsec3_active(dns_db_t *db, dns_dbversion_t *version, isc_boolean_t complete, isc_boolean_t *answer); isc_result_t dns_nsec3_activex(dns_db_t *db, dns_dbversion_t *version, isc_boolean_t complete, dns_rdatatype_t private, isc_boolean_t *answer); /*%< * Check if there are any complete/to be built NSEC3 chains. * If 'complete' is ISC_TRUE only complete chains will be recognized. * * dns_nsec3_activex() is similar to dns_nsec3_active() but 'private' * specifies the type of the private rdataset to be checked in addition to * the nsec3param rdataset at the zone apex. * * Requires: * 'db' to be valid. * 'version' to be valid or NULL. * 'answer' to be non NULL. */ isc_result_t dns_nsec3_maxiterations(dns_db_t *db, dns_dbversion_t *version, isc_mem_t *mctx, unsigned int *iterationsp); /*%< * Find the maximum permissible number of iterations allowed based on * the key strength. * * Requires: * 'db' to be valid. * 'version' to be valid or NULL. * 'mctx' to be valid. * 'iterationsp' to be non NULL. */ isc_boolean_t dns_nsec3param_fromprivate(dns_rdata_t *src, dns_rdata_t *target, unsigned char *buf, size_t buflen); /*%< * Convert a private rdata to a nsec3param rdata. * * Return ISC_TRUE if 'src' could be successfully converted. * * 'buf' should be at least DNS_NSEC3PARAM_BUFFERSIZE in size. */ void dns_nsec3param_toprivate(dns_rdata_t *src, dns_rdata_t *target, dns_rdatatype_t privatetype, unsigned char *buf, size_t buflen); /*%< * Convert a nsec3param rdata to a private rdata. * * 'buf' should be at least src->length + 1 in size. */ isc_result_t dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver, dns_zone_t *zone, isc_boolean_t nonsec, dns_diff_t *diff); /*%< * Mark NSEC3PARAM for deletion. */ isc_result_t dns_nsec3_noexistnodata(dns_rdatatype_t type, dns_name_t* name, dns_name_t *nsec3name, dns_rdataset_t *nsec3set, dns_name_t *zonename, isc_boolean_t *exists, isc_boolean_t *data, isc_boolean_t *optout, isc_boolean_t *unknown, isc_boolean_t *setclosest, isc_boolean_t *setnearest, dns_name_t *closest, dns_name_t *nearest, dns_nseclog_t logit, void *arg); ISC_LANG_ENDDECLS #endif /* DNS_NSEC3_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/cert.h0000644000470500017500000000370312664710322020243 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: cert.h,v 1.19 2007/06/19 23:47:16 tbox Exp $ */ #ifndef DNS_CERT_H #define DNS_CERT_H 1 /*! \file dns/cert.h */ #include #include ISC_LANG_BEGINDECLS isc_result_t dns_cert_fromtext(dns_cert_t *certp, isc_textregion_t *source); /*%< * Convert the text 'source' refers to into a certificate type. * The text may contain either a mnemonic type name or a decimal type number. * * Requires: *\li 'certp' is a valid pointer. * *\li 'source' is a valid text region. * * Returns: *\li #ISC_R_SUCCESS on success *\li #ISC_R_RANGE numeric type is out of range *\li #DNS_R_UNKNOWN mnemonic type is unknown */ isc_result_t dns_cert_totext(dns_cert_t cert, isc_buffer_t *target); /*%< * Put a textual representation of certificate type 'cert' into 'target'. * * Requires: *\li 'cert' is a valid cert. * *\li 'target' is a valid text buffer. * * Ensures: *\li If the result is success: * The used space in 'target' is updated. * * Returns: *\li #ISC_R_SUCCESS on success *\li #ISC_R_NOSPACE target buffer is too small */ ISC_LANG_ENDDECLS #endif /* DNS_CERT_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/iptable.h0000644000470500017500000000364012664710322020726 0ustar lamontlamont/* * Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: iptable.h,v 1.4 2007/09/14 01:46:05 marka Exp $ */ #ifndef DNS_IPTABLE_H #define DNS_IPTABLE_H 1 #include #include #include #include struct dns_iptable { unsigned int magic; isc_mem_t *mctx; isc_refcount_t refcount; isc_radix_tree_t *radix; ISC_LINK(dns_iptable_t) nextincache; }; #define DNS_IPTABLE_MAGIC ISC_MAGIC('T','a','b','l') #define DNS_IPTABLE_VALID(a) ISC_MAGIC_VALID(a, DNS_IPTABLE_MAGIC) /*** *** Functions ***/ ISC_LANG_BEGINDECLS isc_result_t dns_iptable_create(isc_mem_t *mctx, dns_iptable_t **target); /* * Create a new IP table and the underlying radix structure */ isc_result_t dns_iptable_addprefix(dns_iptable_t *tab, isc_netaddr_t *addr, isc_uint16_t bitlen, isc_boolean_t pos); /* * Add an IP prefix to an existing IP table */ isc_result_t dns_iptable_merge(dns_iptable_t *tab, dns_iptable_t *source, isc_boolean_t pos); /* * Merge one IP table into another one. */ void dns_iptable_attach(dns_iptable_t *source, dns_iptable_t **target); void dns_iptable_detach(dns_iptable_t **tabp); ISC_LANG_ENDDECLS #endif /* DNS_IPTABLE_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/zonekey.h0000644000470500017500000000240312664710322020766 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: zonekey.h,v 1.10 2007/06/19 23:47:17 tbox Exp $ */ #ifndef DNS_ZONEKEY_H #define DNS_ZONEKEY_H 1 /*! \file dns/zonekey.h */ #include #include ISC_LANG_BEGINDECLS isc_boolean_t dns_zonekey_iszonekey(dns_rdata_t *keyrdata); /*%< * Determines if the key record contained in the rdata is a zone key. * * Requires: * 'keyrdata' is not NULL. */ ISC_LANG_ENDDECLS #endif /* DNS_ZONEKEY_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/geoip.h0000644000470500017500000000533212664710322020411 0ustar lamontlamont/* * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef DNS_GEOIP_H #define DNS_GEOIP_H 1 /***** ***** Module Info *****/ /*! \file dns/acl.h * \brief * Address match list handling. */ /*** *** Imports ***/ #include #include #include #include #include #include #include #ifdef HAVE_GEOIP #include #else typedef void GeoIP; #endif /*** *** Types ***/ typedef enum { dns_geoip_countrycode, dns_geoip_countrycode3, dns_geoip_countryname, dns_geoip_region, dns_geoip_regionname, dns_geoip_country_code, dns_geoip_country_code3, dns_geoip_country_name, dns_geoip_region_countrycode, dns_geoip_region_code, dns_geoip_region_name, dns_geoip_city_countrycode, dns_geoip_city_countrycode3, dns_geoip_city_countryname, dns_geoip_city_region, dns_geoip_city_regionname, dns_geoip_city_name, dns_geoip_city_postalcode, dns_geoip_city_metrocode, dns_geoip_city_areacode, dns_geoip_city_continentcode, dns_geoip_city_timezonecode, dns_geoip_isp_name, dns_geoip_org_name, dns_geoip_as_asnum, dns_geoip_domain_name, dns_geoip_netspeed_id } dns_geoip_subtype_t; typedef struct dns_geoip_elem { dns_geoip_subtype_t subtype; GeoIP *db; union { char as_string[256]; int as_int; }; } dns_geoip_elem_t; typedef struct dns_geoip_databases { GeoIP *country_v4; /* DB 1 */ GeoIP *city_v4; /* DB 2 or 6 */ GeoIP *region; /* DB 3 or 7 */ GeoIP *isp; /* DB 4 */ GeoIP *org; /* DB 5 */ GeoIP *as; /* DB 9 */ GeoIP *netspeed; /* DB 10 */ GeoIP *domain; /* DB 11 */ GeoIP *country_v6; /* DB 12 */ GeoIP *city_v6; /* DB 30 or 31 */ } dns_geoip_databases_t; /*** *** Functions ***/ ISC_LANG_BEGINDECLS isc_boolean_t dns_geoip_match(const isc_netaddr_t *reqaddr, const dns_geoip_databases_t *geoip, const dns_geoip_elem_t *elt); void dns_geoip_shutdown(void); ISC_LANG_ENDDECLS #endif /* DNS_GEOIP_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/soa.h0000644000470500017500000000527612664710322020077 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: soa.h,v 1.12 2009/09/10 01:47:09 each Exp $ */ #ifndef DNS_SOA_H #define DNS_SOA_H 1 /***** ***** Module Info *****/ /*! \file dns/soa.h * \brief * SOA utilities. */ /*** *** Imports ***/ #include #include #include ISC_LANG_BEGINDECLS #define DNS_SOA_BUFFERSIZE ((2 * DNS_NAME_MAXWIRE) + (4 * 5)) isc_result_t dns_soa_buildrdata(dns_name_t *origin, dns_name_t *contact, dns_rdataclass_t rdclass, isc_uint32_t serial, isc_uint32_t refresh, isc_uint32_t retry, isc_uint32_t expire, isc_uint32_t minimum, unsigned char *buffer, dns_rdata_t *rdata); /*%< * Build the rdata of an SOA record. * * Requires: *\li buffer Points to a temporary buffer of at least * DNS_SOA_BUFFERSIZE bytes. *\li rdata Points to an initialized dns_rdata_t. * * Ensures: * \li *rdata Contains a valid SOA rdata. The 'data' member * refers to 'buffer'. */ isc_uint32_t dns_soa_getserial(dns_rdata_t *rdata); isc_uint32_t dns_soa_getrefresh(dns_rdata_t *rdata); isc_uint32_t dns_soa_getretry(dns_rdata_t *rdata); isc_uint32_t dns_soa_getexpire(dns_rdata_t *rdata); isc_uint32_t dns_soa_getminimum(dns_rdata_t *rdata); /* * Extract an integer field from the rdata of a SOA record. * * Requires: * rdata refers to the rdata of a well-formed SOA record. */ void dns_soa_setserial(isc_uint32_t val, dns_rdata_t *rdata); void dns_soa_setrefresh(isc_uint32_t val, dns_rdata_t *rdata); void dns_soa_setretry(isc_uint32_t val, dns_rdata_t *rdata); void dns_soa_setexpire(isc_uint32_t val, dns_rdata_t *rdata); void dns_soa_setminimum(isc_uint32_t val, dns_rdata_t *rdata); /* * Change an integer field of a SOA record by modifying the * rdata in-place. * * Requires: * rdata refers to the rdata of a well-formed SOA record. */ ISC_LANG_ENDDECLS #endif /* DNS_SOA_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/zt.h0000644000470500017500000001273512664710322017750 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: zt.h,v 1.40 2011/09/02 23:46:32 tbox Exp $ */ #ifndef DNS_ZT_H #define DNS_ZT_H 1 /*! \file dns/zt.h */ #include #include #define DNS_ZTFIND_NOEXACT 0x01 ISC_LANG_BEGINDECLS typedef isc_result_t (*dns_zt_allloaded_t)(void *arg); /*%< * Method prototype: when all pending zone loads are complete, * the zone table can inform the caller via a callback function with * this signature. */ typedef isc_result_t (*dns_zt_zoneloaded_t)(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task); /*%< * Method prototype: when a zone finishes loading, the zt object * can be informed via a callback function with this signature. */ isc_result_t dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **zt); /*%< * Creates a new zone table. * * Requires: * \li 'mctx' to be initialized. * * Returns: * \li #ISC_R_SUCCESS on success. * \li #ISC_R_NOMEMORY */ isc_result_t dns_zt_mount(dns_zt_t *zt, dns_zone_t *zone); /*%< * Mounts the zone on the zone table. * * Requires: * \li 'zt' to be valid * \li 'zone' to be valid * * Returns: * \li #ISC_R_SUCCESS * \li #ISC_R_EXISTS * \li #ISC_R_NOSPACE * \li #ISC_R_NOMEMORY */ isc_result_t dns_zt_unmount(dns_zt_t *zt, dns_zone_t *zone); /*%< * Unmount the given zone from the table. * * Requires: * 'zt' to be valid * \li 'zone' to be valid * * Returns: * \li #ISC_R_SUCCESS * \li #ISC_R_NOTFOUND * \li #ISC_R_NOMEMORY */ isc_result_t dns_zt_find(dns_zt_t *zt, dns_name_t *name, unsigned int options, dns_name_t *foundname, dns_zone_t **zone); /*%< * Find the best match for 'name' in 'zt'. If foundname is non NULL * then the name of the zone found is returned. * * Notes: * \li If the DNS_ZTFIND_NOEXACT is set, the best partial match (if any) * to 'name' will be returned. * * Requires: * \li 'zt' to be valid * \li 'name' to be valid * \li 'foundname' to be initialized and associated with a fixedname or NULL * \li 'zone' to be non NULL and '*zone' to be NULL * * Returns: * \li #ISC_R_SUCCESS * \li #DNS_R_PARTIALMATCH * \li #ISC_R_NOTFOUND * \li #ISC_R_NOSPACE */ void dns_zt_detach(dns_zt_t **ztp); /*%< * Detach the given zonetable, if the reference count goes to zero the * zonetable will be freed. In either case 'ztp' is set to NULL. * * Requires: * \li '*ztp' to be valid */ void dns_zt_flushanddetach(dns_zt_t **ztp); /*%< * Detach the given zonetable, if the reference count goes to zero the * zonetable will be flushed and then freed. In either case 'ztp' is * set to NULL. * * Requires: * \li '*ztp' to be valid */ void dns_zt_attach(dns_zt_t *zt, dns_zt_t **ztp); /*%< * Attach 'zt' to '*ztp'. * * Requires: * \li 'zt' to be valid * \li '*ztp' to be NULL */ isc_result_t dns_zt_load(dns_zt_t *zt, isc_boolean_t stop); isc_result_t dns_zt_loadnew(dns_zt_t *zt, isc_boolean_t stop); isc_result_t dns_zt_asyncload(dns_zt_t *zt, dns_zt_allloaded_t alldone, void *arg); /*%< * Load all zones in the table. If 'stop' is ISC_TRUE, * stop on the first error and return it. If 'stop' * is ISC_FALSE, ignore errors. * * dns_zt_loadnew() only loads zones that are not yet loaded. * dns_zt_load() also loads zones that are already loaded and * and whose master file has changed since the last load. * dns_zt_asyncload() loads zones asynchronously; when all * zones in the zone table have finished loaded (or failed due * to errors), the caller is informed by calling 'alldone' * with an argument of 'arg'. * * Requires: * \li 'zt' to be valid */ isc_result_t dns_zt_freezezones(dns_zt_t *zt, isc_boolean_t freeze); /*%< * Freeze/thaw updates to master zones. * Any pending updates will be flushed. * Zones will be reloaded on thaw. */ isc_result_t dns_zt_apply(dns_zt_t *zt, isc_boolean_t stop, isc_result_t (*action)(dns_zone_t *, void *), void *uap); isc_result_t dns_zt_apply2(dns_zt_t *zt, isc_boolean_t stop, isc_result_t *sub, isc_result_t (*action)(dns_zone_t *, void *), void *uap); /*%< * Apply a given 'action' to all zone zones in the table. * If 'stop' is 'ISC_TRUE' then walking the zone tree will stop if * 'action' does not return ISC_R_SUCCESS. * * Requires: * \li 'zt' to be valid. * \li 'action' to be non NULL. * * Returns: * \li ISC_R_SUCCESS if action was applied to all nodes. If 'stop' is * ISC_FALSE and 'sub' is non NULL then the first error (if any) * reported by 'action' is returned in '*sub'; * any error code from 'action'. */ isc_boolean_t dns_zt_loadspending(dns_zt_t *zt); /*%< * Returns ISC_TRUE if and only if there are zones still waiting to * be loaded in zone table 'zt'. * * Requires: * \li 'zt' to be valid. */ ISC_LANG_ENDDECLS #endif /* DNS_ZT_H */ bind9-9.10.3.dfsg.P4/lib/dns/include/dns/fixedname.h0000644000470500017500000000427512664710322021253 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: fixedname.h,v 1.19 2007/06/19 23:47:16 tbox Exp $ */ #ifndef DNS_FIXEDNAME_H #define DNS_FIXEDNAME_H 1 /***** ***** Module Info *****/ /*! \file dns/fixedname.h * \brief * Fixed-size Names * * dns_fixedname_t is a convenience type containing a name, an offsets table, * and a dedicated buffer big enough for the longest possible name. * * MP: *\li The caller must ensure any required synchronization. * * Reliability: *\li No anticipated impact. * * Resources: *\li Per dns_fixedname_t: *\code * sizeof(dns_name_t) + sizeof(dns_offsets_t) + * sizeof(isc_buffer_t) + 255 bytes + structure padding *\endcode * * Security: *\li No anticipated impact. * * Standards: *\li None. */ /***** ***** Imports *****/ #include #include /***** ***** Types *****/ struct dns_fixedname { dns_name_t name; dns_offsets_t offsets; isc_buffer_t buffer; unsigned char data[DNS_NAME_MAXWIRE]; }; #define dns_fixedname_init(fn) \ do { \ dns_name_init(&((fn)->name), (fn)->offsets); \ isc_buffer_init(&((fn)->buffer), (fn)->data, \ DNS_NAME_MAXWIRE); \ dns_name_setbuffer(&((fn)->name), &((fn)->buffer)); \ } while (0) #define dns_fixedname_invalidate(fn) \ dns_name_invalidate(&((fn)->name)) #define dns_fixedname_name(fn) (&((fn)->name)) #endif /* DNS_FIXEDNAME_H */ bind9-9.10.3.dfsg.P4/lib/dns/resolver.c0000644000470500017500000104055012664710322016735 0ustar lamontlamont/* * Copyright (C) 2004-2016 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef AES_SIT #include #else #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef WANT_QUERYTRACE #define RTRACE(m) isc_log_write(dns_lctx, \ DNS_LOGCATEGORY_RESOLVER, \ DNS_LOGMODULE_RESOLVER, \ ISC_LOG_DEBUG(3), \ "res %p: %s", res, (m)) #define RRTRACE(r, m) isc_log_write(dns_lctx, \ DNS_LOGCATEGORY_RESOLVER, \ DNS_LOGMODULE_RESOLVER, \ ISC_LOG_DEBUG(3), \ "res %p: %s", (r), (m)) #define FCTXTRACE(m) \ isc_log_write(dns_lctx, \ DNS_LOGCATEGORY_RESOLVER, \ DNS_LOGMODULE_RESOLVER, \ ISC_LOG_DEBUG(3), \ "fctx %p(%s): %s", \ fctx, fctx->info, (m)) #define FCTXTRACE2(m1, m2) \ isc_log_write(dns_lctx, \ DNS_LOGCATEGORY_RESOLVER, \ DNS_LOGMODULE_RESOLVER, \ ISC_LOG_DEBUG(3), \ "fctx %p(%s): %s %s", \ fctx, fctx->info, (m1), (m2)) #define FCTXTRACE3(m, res) \ isc_log_write(dns_lctx, \ DNS_LOGCATEGORY_RESOLVER, \ DNS_LOGMODULE_RESOLVER, \ ISC_LOG_DEBUG(3), \ "fctx %p(%s): [result: %s] %s", \ fctx, fctx->info, \ isc_result_totext(res), (m)) #define FCTXTRACE4(m1, m2, res) \ isc_log_write(dns_lctx, \ DNS_LOGCATEGORY_RESOLVER, \ DNS_LOGMODULE_RESOLVER, \ ISC_LOG_DEBUG(3), \ "fctx %p(%s): [result: %s] %s %s", \ fctx, fctx->info, \ isc_result_totext(res), (m1), (m2)) #define FTRACE(m) isc_log_write(dns_lctx, \ DNS_LOGCATEGORY_RESOLVER, \ DNS_LOGMODULE_RESOLVER, \ ISC_LOG_DEBUG(3), \ "fetch %p (fctx %p(%s)): %s", \ fetch, fetch->private, \ fetch->private->info, (m)) #define QTRACE(m) isc_log_write(dns_lctx, \ DNS_LOGCATEGORY_RESOLVER, \ DNS_LOGMODULE_RESOLVER, \ ISC_LOG_DEBUG(3), \ "resquery %p (fctx %p(%s)): %s", \ query, query->fctx, \ query->fctx->info, (m)) #else #define RTRACE(m) do { UNUSED(m); } while (0) #define RRTRACE(r, m) do { UNUSED(r); UNUSED(m); } while (0) #define FCTXTRACE(m) do { UNUSED(m); } while (0) #define FCTXTRACE2(m1, m2) do { UNUSED(m1); UNUSED(m2); } while (0) #define FCTXTRACE3(m1, res) do { UNUSED(m1); UNUSED(res); } while (0) #define FCTXTRACE4(m1, m2, res) \ do { UNUSED(m1); UNUSED(m2); UNUSED(res); } while (0) #define FTRACE(m) do { UNUSED(m); } while (0) #define QTRACE(m) do { UNUSED(m); } while (0) #endif /* WANT_QUERYTRACE */ #define US_PER_SEC 1000000U /* * The maximum time we will wait for a single query. */ #define MAX_SINGLE_QUERY_TIMEOUT 9U #define MAX_SINGLE_QUERY_TIMEOUT_US (MAX_SINGLE_QUERY_TIMEOUT*US_PER_SEC) /* * We need to allow a individual query time to complete / timeout. */ #define MINIMUM_QUERY_TIMEOUT (MAX_SINGLE_QUERY_TIMEOUT + 1U) /* The default time in seconds for the whole query to live. */ #ifndef DEFAULT_QUERY_TIMEOUT #define DEFAULT_QUERY_TIMEOUT MINIMUM_QUERY_TIMEOUT #endif /* The maximum time in seconds for the whole query to live. */ #ifndef MAXIMUM_QUERY_TIMEOUT #define MAXIMUM_QUERY_TIMEOUT 30 #endif /* The default maximum number of recursions to follow before giving up. */ #ifndef DEFAULT_RECURSION_DEPTH #define DEFAULT_RECURSION_DEPTH 7 #endif /* The default maximum number of iterative queries to allow before giving up. */ #ifndef DEFAULT_MAX_QUERIES #define DEFAULT_MAX_QUERIES 75 #endif /* Number of hash buckets for zone counters */ #ifndef RES_DOMAIN_BUCKETS #define RES_DOMAIN_BUCKETS 523 #endif #define RES_NOBUCKET 0xffffffff /*% * Maximum EDNS0 input packet size. */ #define RECV_BUFFER_SIZE 4096 /* XXXRTH Constant. */ /*% * This defines the maximum number of timeouts we will permit before we * disable EDNS0 on the query. */ #define MAX_EDNS0_TIMEOUTS 3 typedef struct fetchctx fetchctx_t; typedef struct query { /* Locked by task event serialization. */ unsigned int magic; fetchctx_t * fctx; isc_mem_t * mctx; dns_dispatchmgr_t * dispatchmgr; dns_dispatch_t * dispatch; isc_boolean_t exclusivesocket; dns_adbaddrinfo_t * addrinfo; isc_socket_t * tcpsocket; isc_time_t start; dns_messageid_t id; dns_dispentry_t * dispentry; ISC_LINK(struct query) link; isc_buffer_t buffer; isc_buffer_t *tsig; dns_tsigkey_t *tsigkey; isc_socketevent_t sendevent; isc_dscp_t dscp; int ednsversion; unsigned int options; unsigned int attributes; unsigned int sends; unsigned int connects; unsigned int udpsize; unsigned char data[512]; } resquery_t; struct tried { isc_sockaddr_t addr; unsigned int count; ISC_LINK(struct tried) link; }; #define QUERY_MAGIC ISC_MAGIC('Q', '!', '!', '!') #define VALID_QUERY(query) ISC_MAGIC_VALID(query, QUERY_MAGIC) #define RESQUERY_ATTR_CANCELED 0x02 #define RESQUERY_CONNECTING(q) ((q)->connects > 0) #define RESQUERY_CANCELED(q) (((q)->attributes & \ RESQUERY_ATTR_CANCELED) != 0) #define RESQUERY_SENDING(q) ((q)->sends > 0) typedef enum { fetchstate_init = 0, /*%< Start event has not run yet. */ fetchstate_active, fetchstate_done /*%< FETCHDONE events posted. */ } fetchstate; typedef enum { badns_unreachable = 0, badns_response, badns_validation } badnstype_t; struct fetchctx { /*% Not locked. */ unsigned int magic; dns_resolver_t * res; dns_name_t name; dns_rdatatype_t type; unsigned int options; unsigned int bucketnum; unsigned int dbucketnum; char * info; isc_mem_t * mctx; /*% Locked by appropriate bucket lock. */ fetchstate state; isc_boolean_t want_shutdown; isc_boolean_t cloned; isc_boolean_t spilled; unsigned int references; isc_event_t control_event; ISC_LINK(struct fetchctx) link; ISC_LIST(dns_fetchevent_t) events; /*% Locked by task event serialization. */ dns_name_t domain; dns_rdataset_t nameservers; unsigned int attributes; isc_timer_t * timer; isc_time_t expires; isc_interval_t interval; dns_message_t * qmessage; dns_message_t * rmessage; ISC_LIST(resquery_t) queries; dns_adbfindlist_t finds; dns_adbfind_t * find; dns_adbfindlist_t altfinds; dns_adbfind_t * altfind; dns_adbaddrinfolist_t forwaddrs; dns_adbaddrinfolist_t altaddrs; dns_forwarderlist_t forwarders; dns_fwdpolicy_t fwdpolicy; isc_sockaddrlist_t bad; ISC_LIST(struct tried) edns; ISC_LIST(struct tried) edns512; isc_sockaddrlist_t bad_edns; dns_validator_t * validator; ISC_LIST(dns_validator_t) validators; dns_db_t * cache; dns_adb_t * adb; isc_boolean_t ns_ttl_ok; isc_uint32_t ns_ttl; isc_counter_t * qc; /*% * The number of events we're waiting for. */ unsigned int pending; /*% * The number of times we've "restarted" the current * nameserver set. This acts as a failsafe to prevent * us from pounding constantly on a particular set of * servers that, for whatever reason, are not giving * us useful responses, but are responding in such a * way that they are not marked "bad". */ unsigned int restarts; /*% * The number of timeouts that have occurred since we * last successfully received a response packet. This * is used for EDNS0 black hole detection. */ unsigned int timeouts; /*% * Look aside state for DS lookups. */ dns_name_t nsname; dns_fetch_t * nsfetch; dns_rdataset_t nsrrset; /*% * Number of queries that reference this context. */ unsigned int nqueries; /*% * The reason to print when logging a successful * response to a query. */ const char * reason; /*% * Random numbers to use for mixing up server addresses. */ isc_uint32_t rand_buf; isc_uint32_t rand_bits; /*% * Fetch-local statistics for detailed logging. */ isc_result_t result; /*%< fetch result */ isc_result_t vresult; /*%< validation result */ int exitline; isc_time_t start; isc_uint64_t duration; isc_boolean_t logged; unsigned int querysent; unsigned int referrals; unsigned int lamecount; unsigned int quotacount; unsigned int neterr; unsigned int badresp; unsigned int adberr; unsigned int findfail; unsigned int valfail; isc_boolean_t timeout; dns_adbaddrinfo_t *addrinfo; isc_sockaddr_t *client; unsigned int depth; }; #define FCTX_MAGIC ISC_MAGIC('F', '!', '!', '!') #define VALID_FCTX(fctx) ISC_MAGIC_VALID(fctx, FCTX_MAGIC) #define FCTX_ATTR_HAVEANSWER 0x0001 #define FCTX_ATTR_GLUING 0x0002 #define FCTX_ATTR_ADDRWAIT 0x0004 #define FCTX_ATTR_SHUTTINGDOWN 0x0008 #define FCTX_ATTR_WANTCACHE 0x0010 #define FCTX_ATTR_WANTNCACHE 0x0020 #define FCTX_ATTR_NEEDEDNS0 0x0040 #define FCTX_ATTR_TRIEDFIND 0x0080 #define FCTX_ATTR_TRIEDALT 0x0100 #define HAVE_ANSWER(f) (((f)->attributes & FCTX_ATTR_HAVEANSWER) != \ 0) #define GLUING(f) (((f)->attributes & FCTX_ATTR_GLUING) != \ 0) #define ADDRWAIT(f) (((f)->attributes & FCTX_ATTR_ADDRWAIT) != \ 0) #define SHUTTINGDOWN(f) (((f)->attributes & FCTX_ATTR_SHUTTINGDOWN) \ != 0) #define WANTCACHE(f) (((f)->attributes & FCTX_ATTR_WANTCACHE) != 0) #define WANTNCACHE(f) (((f)->attributes & FCTX_ATTR_WANTNCACHE) != 0) #define NEEDEDNS0(f) (((f)->attributes & FCTX_ATTR_NEEDEDNS0) != 0) #define TRIEDFIND(f) (((f)->attributes & FCTX_ATTR_TRIEDFIND) != 0) #define TRIEDALT(f) (((f)->attributes & FCTX_ATTR_TRIEDALT) != 0) typedef struct { dns_adbaddrinfo_t * addrinfo; fetchctx_t * fctx; } dns_valarg_t; struct dns_fetch { unsigned int magic; isc_mem_t * mctx; fetchctx_t * private; }; #define DNS_FETCH_MAGIC ISC_MAGIC('F', 't', 'c', 'h') #define DNS_FETCH_VALID(fetch) ISC_MAGIC_VALID(fetch, DNS_FETCH_MAGIC) typedef struct fctxbucket { isc_task_t * task; isc_mutex_t lock; ISC_LIST(fetchctx_t) fctxs; isc_boolean_t exiting; isc_mem_t * mctx; } fctxbucket_t; #ifdef ENABLE_FETCHLIMIT typedef struct fctxcount fctxcount_t; struct fctxcount { dns_fixedname_t fdname; dns_name_t *domain; isc_uint32_t count; isc_uint32_t allowed; isc_uint32_t dropped; isc_stdtime_t logged; ISC_LINK(fctxcount_t) link; }; typedef struct zonebucket { isc_mutex_t lock; isc_mem_t *mctx; ISC_LIST(fctxcount_t) list; } zonebucket_t; #endif /* ENABLE_FETCHLIMIT */ typedef struct alternate { isc_boolean_t isaddress; union { isc_sockaddr_t addr; struct { dns_name_t name; in_port_t port; } _n; } _u; ISC_LINK(struct alternate) link; } alternate_t; typedef struct dns_badcache dns_badcache_t; struct dns_badcache { dns_badcache_t * next; dns_rdatatype_t type; isc_time_t expire; unsigned int hashval; dns_name_t name; }; #define DNS_BADCACHE_SIZE 1021 #define DNS_BADCACHE_TTL(fctx) \ (((fctx)->res->lame_ttl > 30 ) ? (fctx)->res->lame_ttl : 30) struct dns_resolver { /* Unlocked. */ unsigned int magic; isc_mem_t * mctx; isc_mutex_t lock; isc_mutex_t nlock; isc_mutex_t primelock; dns_rdataclass_t rdclass; isc_socketmgr_t * socketmgr; isc_timermgr_t * timermgr; isc_taskmgr_t * taskmgr; dns_view_t * view; isc_boolean_t frozen; unsigned int options; dns_dispatchmgr_t * dispatchmgr; dns_dispatchset_t * dispatches4; isc_boolean_t exclusivev4; dns_dispatchset_t * dispatches6; isc_dscp_t querydscp4; isc_dscp_t querydscp6; isc_boolean_t exclusivev6; unsigned int nbuckets; fctxbucket_t * buckets; #ifdef ENABLE_FETCHLIMIT zonebucket_t * dbuckets; #endif /* ENABLE_FETCHLIMIT */ isc_uint32_t lame_ttl; ISC_LIST(alternate_t) alternates; isc_uint16_t udpsize; #if USE_ALGLOCK isc_rwlock_t alglock; #endif dns_rbt_t * algorithms; dns_rbt_t * digests; #if USE_MBSLOCK isc_rwlock_t mbslock; #endif dns_rbt_t * mustbesecure; unsigned int spillatmax; unsigned int spillatmin; isc_timer_t * spillattimer; isc_boolean_t zero_no_soa_ttl; unsigned int query_timeout; unsigned int maxdepth; unsigned int maxqueries; isc_result_t quotaresp[2]; /* Locked by lock. */ unsigned int references; isc_boolean_t exiting; isc_eventlist_t whenshutdown; unsigned int activebuckets; isc_boolean_t priming; unsigned int spillat; /* clients-per-query */ unsigned int zspill; /* fetches-per-zone */ /* Bad cache. */ dns_badcache_t ** badcache; unsigned int badcount; unsigned int badhash; unsigned int badsweep; /* Locked by primelock. */ dns_fetch_t * primefetch; /* Locked by nlock. */ unsigned int nfctx; }; #define RES_MAGIC ISC_MAGIC('R', 'e', 's', '!') #define VALID_RESOLVER(res) ISC_MAGIC_VALID(res, RES_MAGIC) /*% * Private addrinfo flags. These must not conflict with DNS_FETCHOPT_NOEDNS0 * (0x008) which we also use as an addrinfo flag. */ #define FCTX_ADDRINFO_MARK 0x0001 #define FCTX_ADDRINFO_FORWARDER 0x1000 #define FCTX_ADDRINFO_EDNSOK 0x4000 #define FCTX_ADDRINFO_NOSIT 0x8000 #define FCTX_ADDRINFO_BADCOOKIE 0x10000 #define UNMARKED(a) (((a)->flags & FCTX_ADDRINFO_MARK) \ == 0) #define ISFORWARDER(a) (((a)->flags & \ FCTX_ADDRINFO_FORWARDER) != 0) #define NOSIT(a) (((a)->flags & \ FCTX_ADDRINFO_NOSIT) != 0) #define EDNSOK(a) (((a)->flags & \ FCTX_ADDRINFO_EDNSOK) != 0) #define BADCOOKIE(a) (((a)->flags & \ FCTX_ADDRINFO_BADCOOKIE) != 0) #define NXDOMAIN(r) (((r)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0) #define NEGATIVE(r) (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) static void destroy(dns_resolver_t *res); static void empty_bucket(dns_resolver_t *res); static isc_result_t resquery_send(resquery_t *query); static void resquery_response(isc_task_t *task, isc_event_t *event); static void resquery_connected(isc_task_t *task, isc_event_t *event); static void fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, isc_boolean_t badcache); static void fctx_destroy(fetchctx_t *fctx); static isc_boolean_t fctx_unlink(fetchctx_t *fctx); static isc_result_t ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, isc_boolean_t optout, isc_boolean_t secure, dns_rdataset_t *ardataset, isc_result_t *eresultp); static void validated(isc_task_t *task, isc_event_t *event); static isc_boolean_t maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked); static void add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_result_t reason, badnstype_t badtype); static inline isc_result_t findnoqname(fetchctx_t *fctx, dns_name_t *name, dns_rdatatype_t type, dns_name_t **noqname); static void fctx_increference(fetchctx_t *fctx); static isc_boolean_t fctx_decreference(fetchctx_t *fctx); /*% * Increment resolver-related statistics counters. */ static inline void inc_stats(dns_resolver_t *res, isc_statscounter_t counter) { if (res->view->resstats != NULL) isc_stats_increment(res->view->resstats, counter); } static inline void dec_stats(dns_resolver_t *res, isc_statscounter_t counter) { if (res->view->resstats != NULL) isc_stats_decrement(res->view->resstats, counter); } static isc_result_t valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name, dns_rdatatype_t type, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, unsigned int valoptions, isc_task_t *task) { dns_validator_t *validator = NULL; dns_valarg_t *valarg; isc_result_t result; valarg = isc_mem_get(fctx->mctx, sizeof(*valarg)); if (valarg == NULL) return (ISC_R_NOMEMORY); valarg->fctx = fctx; valarg->addrinfo = addrinfo; if (!ISC_LIST_EMPTY(fctx->validators)) INSIST((valoptions & DNS_VALIDATOR_DEFER) != 0); result = dns_validator_create(fctx->res->view, name, type, rdataset, sigrdataset, fctx->rmessage, valoptions, task, validated, valarg, &validator); if (result == ISC_R_SUCCESS) { inc_stats(fctx->res, dns_resstatscounter_val); if ((valoptions & DNS_VALIDATOR_DEFER) == 0) { INSIST(fctx->validator == NULL); fctx->validator = validator; } ISC_LIST_APPEND(fctx->validators, validator, link); } else isc_mem_put(fctx->mctx, valarg, sizeof(*valarg)); return (result); } static isc_boolean_t rrsig_fromchildzone(fetchctx_t *fctx, dns_rdataset_t *rdataset) { dns_namereln_t namereln; dns_rdata_rrsig_t rrsig; dns_rdata_t rdata = DNS_RDATA_INIT; int order; isc_result_t result; unsigned int labels; for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &rrsig, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); namereln = dns_name_fullcompare(&rrsig.signer, &fctx->domain, &order, &labels); if (namereln == dns_namereln_subdomain) return (ISC_TRUE); dns_rdata_reset(&rdata); } return (ISC_FALSE); } static isc_boolean_t fix_mustbedelegationornxdomain(dns_message_t *message, fetchctx_t *fctx) { dns_name_t *name; dns_name_t *domain = &fctx->domain; dns_rdataset_t *rdataset; dns_rdatatype_t type; isc_result_t result; isc_boolean_t keep_auth = ISC_FALSE; if (message->rcode == dns_rcode_nxdomain) return (ISC_FALSE); /* * A DS RRset can appear anywhere in a zone, even for a delegation-only * zone. So a response to an explicit query for this type should be * excluded from delegation-only fixup. * * SOA, NS, and DNSKEY can only exist at a zone apex, so a postive * response to a query for these types can never violate the * delegation-only assumption: if the query name is below a * zone cut, the response should normally be a referral, which should * be accepted; if the query name is below a zone cut but the server * happens to have authority for the zone of the query name, the * response is a (non-referral) answer. But this does not violate * delegation-only because the query name must be in a different zone * due to the "apex-only" nature of these types. Note that if the * remote server happens to have authority for a child zone of a * delegation-only zone, we may still incorrectly "fix" the response * with NXDOMAIN for queries for other types. Unfortunately it's * generally impossible to differentiate this case from violation of * the delegation-only assumption. Once the resolver learns the * correct zone cut, possibly via a separate query for an "apex-only" * type, queries for other types will be resolved correctly. * * A query for type ANY will be accepted if it hits an exceptional * type above in the answer section as it should be from a child * zone. * * Also accept answers with RRSIG records from the child zone. * Direct queries for RRSIG records should not be answered from * the parent zone. */ if (message->counts[DNS_SECTION_ANSWER] != 0 && (fctx->type == dns_rdatatype_ns || fctx->type == dns_rdatatype_ds || fctx->type == dns_rdatatype_soa || fctx->type == dns_rdatatype_any || fctx->type == dns_rdatatype_rrsig || fctx->type == dns_rdatatype_dnskey)) { result = dns_message_firstname(message, DNS_SECTION_ANSWER); while (result == ISC_R_SUCCESS) { name = NULL; dns_message_currentname(message, DNS_SECTION_ANSWER, &name); for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (!dns_name_equal(name, &fctx->name)) continue; type = rdataset->type; /* * RRsig from child? */ if (type == dns_rdatatype_rrsig && rrsig_fromchildzone(fctx, rdataset)) return (ISC_FALSE); /* * Direct query for apex records or DS. */ if (fctx->type == type && (type == dns_rdatatype_ds || type == dns_rdatatype_ns || type == dns_rdatatype_soa || type == dns_rdatatype_dnskey)) return (ISC_FALSE); /* * Indirect query for apex records or DS. */ if (fctx->type == dns_rdatatype_any && (type == dns_rdatatype_ns || type == dns_rdatatype_ds || type == dns_rdatatype_soa || type == dns_rdatatype_dnskey)) return (ISC_FALSE); } result = dns_message_nextname(message, DNS_SECTION_ANSWER); } } /* * A NODATA response to a DS query? */ if (fctx->type == dns_rdatatype_ds && message->counts[DNS_SECTION_ANSWER] == 0) return (ISC_FALSE); /* Look for referral or indication of answer from child zone? */ if (message->counts[DNS_SECTION_AUTHORITY] == 0) goto munge; result = dns_message_firstname(message, DNS_SECTION_AUTHORITY); while (result == ISC_R_SUCCESS) { name = NULL; dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name); for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { type = rdataset->type; if (type == dns_rdatatype_soa && dns_name_equal(name, domain)) keep_auth = ISC_TRUE; if (type != dns_rdatatype_ns && type != dns_rdatatype_soa && type != dns_rdatatype_rrsig) continue; if (type == dns_rdatatype_rrsig) { if (rrsig_fromchildzone(fctx, rdataset)) return (ISC_FALSE); else continue; } /* NS or SOA records. */ if (dns_name_equal(name, domain)) { /* * If a query for ANY causes a negative * response, we can be sure that this is * an empty node. For other type of queries * we cannot differentiate an empty node * from a node that just doesn't have that * type of record. We only accept the former * case. */ if (message->counts[DNS_SECTION_ANSWER] == 0 && fctx->type == dns_rdatatype_any) return (ISC_FALSE); } else if (dns_name_issubdomain(name, domain)) { /* Referral or answer from child zone. */ return (ISC_FALSE); } } result = dns_message_nextname(message, DNS_SECTION_AUTHORITY); } munge: message->rcode = dns_rcode_nxdomain; message->counts[DNS_SECTION_ANSWER] = 0; if (!keep_auth) message->counts[DNS_SECTION_AUTHORITY] = 0; message->counts[DNS_SECTION_ADDITIONAL] = 0; return (ISC_TRUE); } static inline isc_result_t fctx_starttimer(fetchctx_t *fctx) { /* * Start the lifetime timer for fctx. * * This is also used for stopping the idle timer; in that * case we must purge events already posted to ensure that * no further idle events are delivered. */ return (isc_timer_reset(fctx->timer, isc_timertype_once, &fctx->expires, NULL, ISC_TRUE)); } static inline void fctx_stoptimer(fetchctx_t *fctx) { isc_result_t result; /* * We don't return a result if resetting the timer to inactive fails * since there's nothing to be done about it. Resetting to inactive * should never fail anyway, since the code as currently written * cannot fail in that case. */ result = isc_timer_reset(fctx->timer, isc_timertype_inactive, NULL, NULL, ISC_TRUE); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_timer_reset(): %s", isc_result_totext(result)); } } static inline isc_result_t fctx_startidletimer(fetchctx_t *fctx, isc_interval_t *interval) { /* * Start the idle timer for fctx. The lifetime timer continues * to be in effect. */ return (isc_timer_reset(fctx->timer, isc_timertype_once, &fctx->expires, interval, ISC_FALSE)); } /* * Stopping the idle timer is equivalent to calling fctx_starttimer(), but * we use fctx_stopidletimer for readability in the code below. */ #define fctx_stopidletimer fctx_starttimer static inline void resquery_destroy(resquery_t **queryp) { dns_resolver_t *res; isc_boolean_t empty; resquery_t *query; fetchctx_t *fctx; unsigned int bucket; REQUIRE(queryp != NULL); query = *queryp; REQUIRE(!ISC_LINK_LINKED(query, link)); INSIST(query->tcpsocket == NULL); fctx = query->fctx; res = fctx->res; bucket = fctx->bucketnum; fctx->nqueries--; LOCK(&res->buckets[bucket].lock); empty = fctx_decreference(query->fctx); UNLOCK(&res->buckets[bucket].lock); query->magic = 0; isc_mem_put(query->mctx, query, sizeof(*query)); *queryp = NULL; if (empty) empty_bucket(res); } static void fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp, isc_time_t *finish, isc_boolean_t no_response) { fetchctx_t *fctx; resquery_t *query; unsigned int rtt, rttms; unsigned int factor; dns_adbfind_t *find; dns_adbaddrinfo_t *addrinfo; isc_socket_t *sock; isc_stdtime_t now; query = *queryp; fctx = query->fctx; FCTXTRACE("cancelquery"); REQUIRE(!RESQUERY_CANCELED(query)); query->attributes |= RESQUERY_ATTR_CANCELED; /* * Should we update the RTT? */ if (finish != NULL || no_response) { if (finish != NULL) { /* * We have both the start and finish times for this * packet, so we can compute a real RTT. */ rtt = (unsigned int)isc_time_microdiff(finish, &query->start); factor = DNS_ADB_RTTADJDEFAULT; rttms = rtt / 1000; if (rttms < DNS_RESOLVER_QRYRTTCLASS0) { inc_stats(fctx->res, dns_resstatscounter_queryrtt0); } else if (rttms < DNS_RESOLVER_QRYRTTCLASS1) { inc_stats(fctx->res, dns_resstatscounter_queryrtt1); } else if (rttms < DNS_RESOLVER_QRYRTTCLASS2) { inc_stats(fctx->res, dns_resstatscounter_queryrtt2); } else if (rttms < DNS_RESOLVER_QRYRTTCLASS3) { inc_stats(fctx->res, dns_resstatscounter_queryrtt3); } else if (rttms < DNS_RESOLVER_QRYRTTCLASS4) { inc_stats(fctx->res, dns_resstatscounter_queryrtt4); } else { inc_stats(fctx->res, dns_resstatscounter_queryrtt5); } } else { isc_uint32_t value; isc_uint32_t mask; if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) dns_adb_ednsto(fctx->adb, query->addrinfo, query->udpsize); else dns_adb_timeout(fctx->adb, query->addrinfo); /* * We don't have an RTT for this query. Maybe the * packet was lost, or maybe this server is very * slow. We don't know. Increase the RTT. */ INSIST(no_response); isc_random_get(&value); if (query->addrinfo->srtt > 800000) mask = 0x3fff; else if (query->addrinfo->srtt > 400000) mask = 0x7fff; else if (query->addrinfo->srtt > 200000) mask = 0xffff; else if (query->addrinfo->srtt > 100000) mask = 0x1ffff; else if (query->addrinfo->srtt > 50000) mask = 0x3ffff; else if (query->addrinfo->srtt > 25000) mask = 0x7ffff; else mask = 0xfffff; /* * Don't adjust timeout on EDNS queries unless we have * seen a EDNS response. */ if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0 && !EDNSOK(query->addrinfo)) { mask >>= 2; } rtt = query->addrinfo->srtt + (value & mask); if (rtt > MAX_SINGLE_QUERY_TIMEOUT_US) rtt = MAX_SINGLE_QUERY_TIMEOUT_US; /* * Replace the current RTT with our value. */ factor = DNS_ADB_RTTADJREPLACE; } dns_adb_adjustsrtt(fctx->adb, query->addrinfo, rtt, factor); } #ifdef ENABLE_FETCHLIMIT dns_adb_endudpfetch(fctx->adb, query->addrinfo); #endif /* ENABLE_FETCHLIMIT */ /* * Age RTTs of servers not tried. */ isc_stdtime_get(&now); if (finish != NULL) for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs); addrinfo != NULL; addrinfo = ISC_LIST_NEXT(addrinfo, publink)) if (UNMARKED(addrinfo)) dns_adb_agesrtt(fctx->adb, addrinfo, now); if (finish != NULL && TRIEDFIND(fctx)) for (find = ISC_LIST_HEAD(fctx->finds); find != NULL; find = ISC_LIST_NEXT(find, publink)) for (addrinfo = ISC_LIST_HEAD(find->list); addrinfo != NULL; addrinfo = ISC_LIST_NEXT(addrinfo, publink)) if (UNMARKED(addrinfo)) dns_adb_agesrtt(fctx->adb, addrinfo, now); if (finish != NULL && TRIEDALT(fctx)) { for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs); addrinfo != NULL; addrinfo = ISC_LIST_NEXT(addrinfo, publink)) if (UNMARKED(addrinfo)) dns_adb_agesrtt(fctx->adb, addrinfo, now); for (find = ISC_LIST_HEAD(fctx->altfinds); find != NULL; find = ISC_LIST_NEXT(find, publink)) for (addrinfo = ISC_LIST_HEAD(find->list); addrinfo != NULL; addrinfo = ISC_LIST_NEXT(addrinfo, publink)) if (UNMARKED(addrinfo)) dns_adb_agesrtt(fctx->adb, addrinfo, now); } /* * Check for any outstanding socket events. If they exist, cancel * them and let the event handlers finish the cleanup. The resolver * only needs to worry about managing the connect and send events; * the dispatcher manages the recv events. */ if (RESQUERY_CONNECTING(query)) { /* * Cancel the connect. */ if (query->tcpsocket != NULL) { isc_socket_cancel(query->tcpsocket, NULL, ISC_SOCKCANCEL_CONNECT); } else if (query->dispentry != NULL) { INSIST(query->exclusivesocket); sock = dns_dispatch_getentrysocket(query->dispentry); if (sock != NULL) isc_socket_cancel(sock, NULL, ISC_SOCKCANCEL_CONNECT); } } else if (RESQUERY_SENDING(query)) { /* * Cancel the pending send. */ if (query->exclusivesocket && query->dispentry != NULL) sock = dns_dispatch_getentrysocket(query->dispentry); else sock = dns_dispatch_getsocket(query->dispatch); if (sock != NULL) isc_socket_cancel(sock, NULL, ISC_SOCKCANCEL_SEND); } if (query->dispentry != NULL) dns_dispatch_removeresponse(&query->dispentry, deventp); ISC_LIST_UNLINK(fctx->queries, query, link); if (query->tsig != NULL) isc_buffer_free(&query->tsig); if (query->tsigkey != NULL) dns_tsigkey_detach(&query->tsigkey); if (query->dispatch != NULL) dns_dispatch_detach(&query->dispatch); if (! (RESQUERY_CONNECTING(query) || RESQUERY_SENDING(query))) /* * It's safe to destroy the query now. */ resquery_destroy(&query); } static void fctx_cancelqueries(fetchctx_t *fctx, isc_boolean_t no_response) { resquery_t *query, *next_query; FCTXTRACE("cancelqueries"); for (query = ISC_LIST_HEAD(fctx->queries); query != NULL; query = next_query) { next_query = ISC_LIST_NEXT(query, link); fctx_cancelquery(&query, NULL, NULL, no_response); } } static void fctx_cleanupfinds(fetchctx_t *fctx) { dns_adbfind_t *find, *next_find; REQUIRE(ISC_LIST_EMPTY(fctx->queries)); for (find = ISC_LIST_HEAD(fctx->finds); find != NULL; find = next_find) { next_find = ISC_LIST_NEXT(find, publink); ISC_LIST_UNLINK(fctx->finds, find, publink); dns_adb_destroyfind(&find); } fctx->find = NULL; } static void fctx_cleanupaltfinds(fetchctx_t *fctx) { dns_adbfind_t *find, *next_find; REQUIRE(ISC_LIST_EMPTY(fctx->queries)); for (find = ISC_LIST_HEAD(fctx->altfinds); find != NULL; find = next_find) { next_find = ISC_LIST_NEXT(find, publink); ISC_LIST_UNLINK(fctx->altfinds, find, publink); dns_adb_destroyfind(&find); } fctx->altfind = NULL; } static void fctx_cleanupforwaddrs(fetchctx_t *fctx) { dns_adbaddrinfo_t *addr, *next_addr; REQUIRE(ISC_LIST_EMPTY(fctx->queries)); for (addr = ISC_LIST_HEAD(fctx->forwaddrs); addr != NULL; addr = next_addr) { next_addr = ISC_LIST_NEXT(addr, publink); ISC_LIST_UNLINK(fctx->forwaddrs, addr, publink); dns_adb_freeaddrinfo(fctx->adb, &addr); } } static void fctx_cleanupaltaddrs(fetchctx_t *fctx) { dns_adbaddrinfo_t *addr, *next_addr; REQUIRE(ISC_LIST_EMPTY(fctx->queries)); for (addr = ISC_LIST_HEAD(fctx->altaddrs); addr != NULL; addr = next_addr) { next_addr = ISC_LIST_NEXT(addr, publink); ISC_LIST_UNLINK(fctx->altaddrs, addr, publink); dns_adb_freeaddrinfo(fctx->adb, &addr); } } static inline void fctx_stopeverything(fetchctx_t *fctx, isc_boolean_t no_response) { FCTXTRACE("stopeverything"); fctx_cancelqueries(fctx, no_response); fctx_cleanupfinds(fctx); fctx_cleanupaltfinds(fctx); fctx_cleanupforwaddrs(fctx); fctx_cleanupaltaddrs(fctx); fctx_stoptimer(fctx); } #ifdef ENABLE_FETCHLIMIT static void fcount_logspill(fetchctx_t *fctx, fctxcount_t *counter) { char dbuf[DNS_NAME_FORMATSIZE]; isc_stdtime_t now; if (! isc_log_wouldlog(dns_lctx, ISC_LOG_INFO)) return; isc_stdtime_get(&now); if (counter->logged > now - 60) return; dns_name_format(&fctx->domain, dbuf, sizeof(dbuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_SPILL, DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, "too many simultaneous fetches for %s " "(allowed %d spilled %d)", dbuf, counter->allowed, counter->dropped); counter->logged = now; } static isc_result_t fcount_incr(fetchctx_t *fctx, isc_boolean_t force) { isc_result_t result = ISC_R_SUCCESS; zonebucket_t *dbucket; fctxcount_t *counter; unsigned int bucketnum, spill; REQUIRE(fctx != NULL); REQUIRE(fctx->res != NULL); INSIST(fctx->dbucketnum == RES_NOBUCKET); bucketnum = dns_name_fullhash(&fctx->domain, ISC_FALSE) % RES_DOMAIN_BUCKETS; LOCK(&fctx->res->lock); spill = fctx->res->zspill; UNLOCK(&fctx->res->lock); dbucket = &fctx->res->dbuckets[bucketnum]; LOCK(&dbucket->lock); for (counter = ISC_LIST_HEAD(dbucket->list); counter != NULL; counter = ISC_LIST_NEXT(counter, link)) { if (dns_name_equal(counter->domain, &fctx->domain)) break; } if (counter == NULL) { counter = isc_mem_get(dbucket->mctx, sizeof(fctxcount_t)); if (counter == NULL) result = ISC_R_NOMEMORY; else { ISC_LINK_INIT(counter, link); counter->count = 1; counter->logged = 0; counter->allowed = 1; counter->dropped = 0; dns_fixedname_init(&counter->fdname); counter->domain = dns_fixedname_name(&counter->fdname); dns_name_copy(&fctx->domain, counter->domain, NULL); ISC_LIST_APPEND(dbucket->list, counter, link); } } else { if (!force && spill != 0 && counter->count >= spill) { counter->dropped++; fcount_logspill(fctx, counter); result = ISC_R_QUOTA; } else { counter->count++; counter->allowed++; } } UNLOCK(&dbucket->lock); if (result == ISC_R_SUCCESS) fctx->dbucketnum = bucketnum; return (result); } static void fcount_decr(fetchctx_t *fctx) { zonebucket_t *dbucket; fctxcount_t *counter; REQUIRE(fctx != NULL); if (fctx->dbucketnum == RES_NOBUCKET) return; dbucket = &fctx->res->dbuckets[fctx->dbucketnum]; LOCK(&dbucket->lock); for (counter = ISC_LIST_HEAD(dbucket->list); counter != NULL; counter = ISC_LIST_NEXT(counter, link)) { if (dns_name_equal(counter->domain, &fctx->domain)) break; } if (counter != NULL) { INSIST(counter->count != 0); counter->count--; fctx->dbucketnum = RES_NOBUCKET; if (counter->count == 0) { ISC_LIST_UNLINK(dbucket->list, counter, link); isc_mem_put(dbucket->mctx, counter, sizeof(*counter)); } } UNLOCK(&dbucket->lock); } #endif /* ENABLE_FETCHLIMIT */ static inline void fctx_sendevents(fetchctx_t *fctx, isc_result_t result, int line) { dns_fetchevent_t *event, *next_event; isc_task_t *task; unsigned int count = 0; isc_interval_t i; isc_boolean_t logit = ISC_FALSE; isc_time_t now; unsigned int old_spillat; unsigned int new_spillat = 0; /* initialized to silence compiler warnings */ /* * Caller must be holding the appropriate bucket lock. */ REQUIRE(fctx->state == fetchstate_done); FCTXTRACE("sendevents"); /* * Keep some record of fetch result for logging later (if required). */ fctx->result = result; fctx->exitline = line; TIME_NOW(&now); fctx->duration = isc_time_microdiff(&now, &fctx->start); for (event = ISC_LIST_HEAD(fctx->events); event != NULL; event = next_event) { next_event = ISC_LIST_NEXT(event, ev_link); ISC_LIST_UNLINK(fctx->events, event, ev_link); task = event->ev_sender; event->ev_sender = fctx; event->vresult = fctx->vresult; if (!HAVE_ANSWER(fctx)) event->result = result; INSIST(result != ISC_R_SUCCESS || dns_rdataset_isassociated(event->rdataset) || fctx->type == dns_rdatatype_any || fctx->type == dns_rdatatype_rrsig || fctx->type == dns_rdatatype_sig); /* * Negative results must be indicated in event->result. */ if (dns_rdataset_isassociated(event->rdataset) && NEGATIVE(event->rdataset)) { INSIST(event->result == DNS_R_NCACHENXDOMAIN || event->result == DNS_R_NCACHENXRRSET); } isc_task_sendanddetach(&task, ISC_EVENT_PTR(&event)); count++; } if ((fctx->attributes & FCTX_ATTR_HAVEANSWER) != 0 && fctx->spilled && (count < fctx->res->spillatmax || fctx->res->spillatmax == 0)) { LOCK(&fctx->res->lock); if (count == fctx->res->spillat && !fctx->res->exiting) { old_spillat = fctx->res->spillat; fctx->res->spillat += 5; if (fctx->res->spillat > fctx->res->spillatmax && fctx->res->spillatmax != 0) fctx->res->spillat = fctx->res->spillatmax; new_spillat = fctx->res->spillat; if (new_spillat != old_spillat) { logit = ISC_TRUE; } isc_interval_set(&i, 20 * 60, 0); result = isc_timer_reset(fctx->res->spillattimer, isc_timertype_ticker, NULL, &i, ISC_TRUE); RUNTIME_CHECK(result == ISC_R_SUCCESS); } UNLOCK(&fctx->res->lock); if (logit) isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, "clients-per-query increased to %u", new_spillat); } } static inline void log_edns(fetchctx_t *fctx) { char domainbuf[DNS_NAME_FORMATSIZE]; if (fctx->reason == NULL) return; /* * We do not know if fctx->domain is the actual domain the record * lives in or a parent domain so we have a '?' after it. */ dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_EDNS_DISABLED, DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, "success resolving '%s' (in '%s'?) after %s", fctx->info, domainbuf, fctx->reason); fctx->reason = NULL; } static void fctx_done(fetchctx_t *fctx, isc_result_t result, int line) { dns_resolver_t *res; isc_boolean_t no_response; REQUIRE(line >= 0); FCTXTRACE("done"); res = fctx->res; if (result == ISC_R_SUCCESS) { /*% * Log any deferred EDNS timeout messages. */ log_edns(fctx); no_response = ISC_TRUE; } else no_response = ISC_FALSE; fctx->reason = NULL; fctx_stopeverything(fctx, no_response); LOCK(&res->buckets[fctx->bucketnum].lock); fctx->state = fetchstate_done; fctx->attributes &= ~FCTX_ATTR_ADDRWAIT; fctx_sendevents(fctx, result, line); UNLOCK(&res->buckets[fctx->bucketnum].lock); } static void process_sendevent(resquery_t *query, isc_event_t *event) { isc_socketevent_t *sevent = (isc_socketevent_t *)event; isc_boolean_t destroy_query = ISC_FALSE; isc_boolean_t retry = ISC_FALSE; isc_result_t result; fetchctx_t *fctx; fctx = query->fctx; if (RESQUERY_CANCELED(query)) { if (query->sends == 0 && query->connects == 0) { /* * This query was canceled while the * isc_socket_sendto/connect() was in progress. */ if (query->tcpsocket != NULL) isc_socket_detach(&query->tcpsocket); destroy_query = ISC_TRUE; } } else { switch (sevent->result) { case ISC_R_SUCCESS: break; case ISC_R_HOSTUNREACH: case ISC_R_NETUNREACH: case ISC_R_NOPERM: case ISC_R_ADDRNOTAVAIL: case ISC_R_CONNREFUSED: FCTXTRACE3("query canceled in sendevent(): " "no route to host; no response", sevent->result); /* * No route to remote. */ add_bad(fctx, query->addrinfo, sevent->result, badns_unreachable); fctx_cancelquery(&query, NULL, NULL, ISC_TRUE); retry = ISC_TRUE; break; default: FCTXTRACE3("query canceled in sendevent() due to " "unexpected event result; responding", sevent->result); fctx_cancelquery(&query, NULL, NULL, ISC_FALSE); break; } } if (event->ev_type == ISC_SOCKEVENT_CONNECT) isc_event_free(&event); if (retry) { /* * Behave as if the idle timer has expired. For TCP * this may not actually reflect the latest timer. */ fctx->attributes &= ~FCTX_ATTR_ADDRWAIT; result = fctx_stopidletimer(fctx); if (result != ISC_R_SUCCESS) fctx_done(fctx, result, __LINE__); else fctx_try(fctx, ISC_TRUE, ISC_FALSE); } if (destroy_query) resquery_destroy(&query); } static void resquery_udpconnected(isc_task_t *task, isc_event_t *event) { resquery_t *query = event->ev_arg; REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT); QTRACE("udpconnected"); UNUSED(task); INSIST(RESQUERY_CONNECTING(query)); query->connects--; process_sendevent(query, event); } static void resquery_senddone(isc_task_t *task, isc_event_t *event) { resquery_t *query = event->ev_arg; REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE); QTRACE("senddone"); /* * XXXRTH * * Currently we don't wait for the senddone event before retrying * a query. This means that if we get really behind, we may end * up doing extra work! */ UNUSED(task); INSIST(RESQUERY_SENDING(query)); query->sends--; process_sendevent(query, event); } static inline isc_result_t fctx_addopt(dns_message_t *message, unsigned int version, isc_uint16_t udpsize, dns_ednsopt_t *ednsopts, size_t count) { dns_rdataset_t *rdataset = NULL; isc_result_t result; result = dns_message_buildopt(message, &rdataset, version, udpsize, DNS_MESSAGEEXTFLAG_DO, ednsopts, count); if (result != ISC_R_SUCCESS) return (result); return (dns_message_setopt(message, rdataset)); } static inline void fctx_setretryinterval(fetchctx_t *fctx, unsigned int rtt) { unsigned int seconds; unsigned int us; /* * We retry every .8 seconds the first two times through the address * list, and then we do exponential back-off. */ if (fctx->restarts < 3) us = 800000; else us = (800000 << (fctx->restarts - 2)); /* * Add a fudge factor to the expected rtt based on the current * estimate. */ if (rtt < 50000) rtt += 50000; else if (rtt < 100000) rtt += 100000; else rtt += 200000; /* * Always wait for at least the expected rtt. */ if (us < rtt) us = rtt; /* * But don't ever wait for more than 10 seconds. */ if (us > MAX_SINGLE_QUERY_TIMEOUT_US) us = MAX_SINGLE_QUERY_TIMEOUT_US; seconds = us / US_PER_SEC; us -= seconds * US_PER_SEC; isc_interval_set(&fctx->interval, seconds, us * 1000); } static isc_result_t fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, unsigned int options) { dns_resolver_t *res; isc_task_t *task; isc_result_t result; resquery_t *query; isc_sockaddr_t addr; isc_boolean_t have_addr = ISC_FALSE; unsigned int srtt; isc_dscp_t dscp = -1; FCTXTRACE("query"); res = fctx->res; task = res->buckets[fctx->bucketnum].task; srtt = addrinfo->srtt; /* * A forwarder needs to make multiple queries. Give it at least * a second to do these in. */ if (ISFORWARDER(addrinfo) && srtt < 1000000) srtt = 1000000; fctx_setretryinterval(fctx, srtt); result = fctx_startidletimer(fctx, &fctx->interval); if (result != ISC_R_SUCCESS) return (result); INSIST(ISC_LIST_EMPTY(fctx->validators)); dns_message_reset(fctx->rmessage, DNS_MESSAGE_INTENTPARSE); query = isc_mem_get(fctx->mctx, sizeof(*query)); if (query == NULL) { result = ISC_R_NOMEMORY; goto stop_idle_timer; } query->mctx = fctx->mctx; query->options = options; query->attributes = 0; query->sends = 0; query->connects = 0; query->dscp = addrinfo->dscp; /* * Note that the caller MUST guarantee that 'addrinfo' will remain * valid until this query is canceled. */ query->addrinfo = addrinfo; TIME_NOW(&query->start); /* * If this is a TCP query, then we need to make a socket and * a dispatch for it here. Otherwise we use the resolver's * shared dispatch. */ query->dispatchmgr = res->dispatchmgr; query->dispatch = NULL; query->exclusivesocket = ISC_FALSE; query->tcpsocket = NULL; if (res->view->peers != NULL) { dns_peer_t *peer = NULL; isc_netaddr_t dstip; isc_netaddr_fromsockaddr(&dstip, &addrinfo->sockaddr); result = dns_peerlist_peerbyaddr(res->view->peers, &dstip, &peer); if (result == ISC_R_SUCCESS) { result = dns_peer_getquerysource(peer, &addr); if (result == ISC_R_SUCCESS) have_addr = ISC_TRUE; result = dns_peer_getquerydscp(peer, &dscp); if (result == ISC_R_SUCCESS) query->dscp = dscp; } } dscp = -1; if ((query->options & DNS_FETCHOPT_TCP) != 0) { int pf; pf = isc_sockaddr_pf(&addrinfo->sockaddr); if (!have_addr) { switch (pf) { case PF_INET: result = dns_dispatch_getlocaladdress( res->dispatches4->dispatches[0], &addr); dscp = dns_resolver_getquerydscp4(fctx->res); break; case PF_INET6: result = dns_dispatch_getlocaladdress( res->dispatches6->dispatches[0], &addr); dscp = dns_resolver_getquerydscp6(fctx->res); break; default: result = ISC_R_NOTIMPLEMENTED; break; } if (result != ISC_R_SUCCESS) goto cleanup_query; } isc_sockaddr_setport(&addr, 0); if (query->dscp == -1) query->dscp = dscp; result = isc_socket_create(res->socketmgr, pf, isc_sockettype_tcp, &query->tcpsocket); if (result != ISC_R_SUCCESS) goto cleanup_query; #ifndef BROKEN_TCP_BIND_BEFORE_CONNECT result = isc_socket_bind(query->tcpsocket, &addr, 0); if (result != ISC_R_SUCCESS) goto cleanup_socket; #endif /* * A dispatch will be created once the connect succeeds. */ } else { if (have_addr) { unsigned int attrs, attrmask; attrs = DNS_DISPATCHATTR_UDP; switch (isc_sockaddr_pf(&addr)) { case AF_INET: attrs |= DNS_DISPATCHATTR_IPV4; dscp = dns_resolver_getquerydscp4(fctx->res); break; case AF_INET6: attrs |= DNS_DISPATCHATTR_IPV6; dscp = dns_resolver_getquerydscp6(fctx->res); break; default: result = ISC_R_NOTIMPLEMENTED; goto cleanup_query; } attrmask = DNS_DISPATCHATTR_UDP; attrmask |= DNS_DISPATCHATTR_TCP; attrmask |= DNS_DISPATCHATTR_IPV4; attrmask |= DNS_DISPATCHATTR_IPV6; result = dns_dispatch_getudp(res->dispatchmgr, res->socketmgr, res->taskmgr, &addr, 4096, 20000, 32768, 16411, 16433, attrs, attrmask, &query->dispatch); if (result != ISC_R_SUCCESS) goto cleanup_query; } else { switch (isc_sockaddr_pf(&addrinfo->sockaddr)) { case PF_INET: dns_dispatch_attach( dns_resolver_dispatchv4(res), &query->dispatch); query->exclusivesocket = res->exclusivev4; dscp = dns_resolver_getquerydscp4(fctx->res); break; case PF_INET6: dns_dispatch_attach( dns_resolver_dispatchv6(res), &query->dispatch); query->exclusivesocket = res->exclusivev6; dscp = dns_resolver_getquerydscp6(fctx->res); break; default: result = ISC_R_NOTIMPLEMENTED; goto cleanup_query; } } if (query->dscp == -1) query->dscp = dscp; /* * We should always have a valid dispatcher here. If we * don't support a protocol family, then its dispatcher * will be NULL, but we shouldn't be finding addresses for * protocol types we don't support, so the dispatcher * we found should never be NULL. */ INSIST(query->dispatch != NULL); } query->dispentry = NULL; query->fctx = fctx; /* reference added by caller */ query->tsig = NULL; query->tsigkey = NULL; ISC_LINK_INIT(query, link); query->magic = QUERY_MAGIC; if ((query->options & DNS_FETCHOPT_TCP) != 0) { /* * Connect to the remote server. * * XXXRTH Should we attach to the socket? */ if (query->dscp != -1) isc_socket_dscp(query->tcpsocket, query->dscp); result = isc_socket_connect(query->tcpsocket, &addrinfo->sockaddr, task, resquery_connected, query); if (result != ISC_R_SUCCESS) goto cleanup_socket; query->connects++; QTRACE("connecting via TCP"); } else { #ifdef ENABLE_FETCHLIMIT if (dns_adbentry_overquota(addrinfo->entry)) goto cleanup_dispatch; /* Inform the ADB that we're starting a fetch */ dns_adb_beginudpfetch(fctx->adb, addrinfo); #endif /* ENABLE_FETCHLIMIT */ result = resquery_send(query); if (result != ISC_R_SUCCESS) goto cleanup_dispatch; } fctx->querysent++; ISC_LIST_APPEND(fctx->queries, query, link); query->fctx->nqueries++; if (isc_sockaddr_pf(&addrinfo->sockaddr) == PF_INET) inc_stats(res, dns_resstatscounter_queryv4); else inc_stats(res, dns_resstatscounter_queryv6); if (res->view->resquerystats != NULL) dns_rdatatypestats_increment(res->view->resquerystats, fctx->type); return (ISC_R_SUCCESS); cleanup_socket: isc_socket_detach(&query->tcpsocket); cleanup_dispatch: if (query->dispatch != NULL) dns_dispatch_detach(&query->dispatch); cleanup_query: if (query->connects == 0) { query->magic = 0; isc_mem_put(fctx->mctx, query, sizeof(*query)); } stop_idle_timer: RUNTIME_CHECK(fctx_stopidletimer(fctx) == ISC_R_SUCCESS); return (result); } static isc_boolean_t bad_edns(fetchctx_t *fctx, isc_sockaddr_t *address) { isc_sockaddr_t *sa; for (sa = ISC_LIST_HEAD(fctx->bad_edns); sa != NULL; sa = ISC_LIST_NEXT(sa, link)) { if (isc_sockaddr_equal(sa, address)) return (ISC_TRUE); } return (ISC_FALSE); } static void add_bad_edns(fetchctx_t *fctx, isc_sockaddr_t *address) { isc_sockaddr_t *sa; if (bad_edns(fctx, address)) return; sa = isc_mem_get(fctx->mctx, sizeof(*sa)); if (sa == NULL) return; *sa = *address; ISC_LIST_INITANDAPPEND(fctx->bad_edns, sa, link); } static struct tried * triededns(fetchctx_t *fctx, isc_sockaddr_t *address) { struct tried *tried; for (tried = ISC_LIST_HEAD(fctx->edns); tried != NULL; tried = ISC_LIST_NEXT(tried, link)) { if (isc_sockaddr_equal(&tried->addr, address)) return (tried); } return (NULL); } static void add_triededns(fetchctx_t *fctx, isc_sockaddr_t *address) { struct tried *tried; tried = triededns(fctx, address); if (tried != NULL) { tried->count++; return; } tried = isc_mem_get(fctx->mctx, sizeof(*tried)); if (tried == NULL) return; tried->addr = *address; tried->count = 1; ISC_LIST_INITANDAPPEND(fctx->edns, tried, link); } static struct tried * triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) { struct tried *tried; for (tried = ISC_LIST_HEAD(fctx->edns512); tried != NULL; tried = ISC_LIST_NEXT(tried, link)) { if (isc_sockaddr_equal(&tried->addr, address)) return (tried); } return (NULL); } static void add_triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) { struct tried *tried; tried = triededns512(fctx, address); if (tried != NULL) { tried->count++; return; } tried = isc_mem_get(fctx->mctx, sizeof(*tried)); if (tried == NULL) return; tried->addr = *address; tried->count = 1; ISC_LIST_INITANDAPPEND(fctx->edns512, tried, link); } #ifdef ISC_PLATFORM_USESIT static void compute_cc(resquery_t *query, unsigned char *sit, size_t len) { #ifdef AES_SIT unsigned char digest[ISC_AES_BLOCK_LENGTH]; unsigned char input[16]; isc_netaddr_t netaddr; unsigned int i; INSIST(len >= 8U); isc_netaddr_fromsockaddr(&netaddr, &query->addrinfo->sockaddr); switch (netaddr.family) { case AF_INET: memmove(input, (unsigned char *)&netaddr.type.in, 4); memset(input + 4, 0, 12); break; case AF_INET6: memmove(input, (unsigned char *)&netaddr.type.in6, 16); break; } isc_aes128_crypt(query->fctx->res->view->secret, input, digest); for (i = 0; i < 8; i++) digest[i] ^= digest[i + 8]; memmove(sit, digest, 8); #endif #ifdef HMAC_SHA1_SIT unsigned char digest[ISC_SHA1_DIGESTLENGTH]; isc_netaddr_t netaddr; isc_hmacsha1_t hmacsha1; INSIST(len >= 8U); isc_hmacsha1_init(&hmacsha1, query->fctx->res->view->secret, ISC_SHA1_DIGESTLENGTH); isc_netaddr_fromsockaddr(&netaddr, &query->addrinfo->sockaddr); switch (netaddr.family) { case AF_INET: isc_hmacsha1_update(&hmacsha1, (unsigned char *)&netaddr.type.in, 4); break; case AF_INET6: isc_hmacsha1_update(&hmacsha1, (unsigned char *)&netaddr.type.in6, 16); break; } isc_hmacsha1_sign(&hmacsha1, digest, sizeof(digest)); memmove(sit, digest, 8); isc_hmacsha1_invalidate(&hmacsha1); #endif #ifdef HMAC_SHA256_SIT unsigned char digest[ISC_SHA256_DIGESTLENGTH]; isc_netaddr_t netaddr; isc_hmacsha256_t hmacsha256; INSIST(len >= 8U); isc_hmacsha256_init(&hmacsha256, query->fctx->res->view->secret, ISC_SHA256_DIGESTLENGTH); isc_netaddr_fromsockaddr(&netaddr, &query->addrinfo->sockaddr); switch (netaddr.family) { case AF_INET: isc_hmacsha256_update(&hmacsha256, (unsigned char *)&netaddr.type.in, 4); break; case AF_INET6: isc_hmacsha256_update(&hmacsha256, (unsigned char *)&netaddr.type.in6, 16); break; } isc_hmacsha256_sign(&hmacsha256, digest, sizeof(digest)); memmove(sit, digest, 8); isc_hmacsha256_invalidate(&hmacsha256); #endif } #endif static isc_boolean_t wouldvalidate(fetchctx_t *fctx) { isc_boolean_t secure_domain; isc_result_t result; if (!fctx->res->view->enablevalidation) return (ISC_FALSE); if (fctx->res->view->dlv != NULL) return (ISC_TRUE); result = dns_view_issecuredomain(fctx->res->view, &fctx->name, &secure_domain); if (result != ISC_R_SUCCESS) return (ISC_FALSE); return (secure_domain); } static isc_result_t resquery_send(resquery_t *query) { fetchctx_t *fctx; isc_result_t result; dns_name_t *qname = NULL; dns_rdataset_t *qrdataset = NULL; isc_region_t r; dns_resolver_t *res; isc_task_t *task; isc_socket_t *sock; isc_buffer_t tcpbuffer; isc_sockaddr_t *address; isc_buffer_t *buffer; isc_netaddr_t ipaddr; dns_tsigkey_t *tsigkey = NULL; dns_peer_t *peer = NULL; isc_boolean_t useedns; dns_compress_t cctx; isc_boolean_t cleanup_cctx = ISC_FALSE; isc_boolean_t secure_domain; isc_boolean_t connecting = ISC_FALSE; dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS]; unsigned ednsopt = 0; isc_uint16_t hint = 0, udpsize = 0; /* No EDNS */ fctx = query->fctx; QTRACE("send"); res = fctx->res; task = res->buckets[fctx->bucketnum].task; address = NULL; if ((query->options & DNS_FETCHOPT_TCP) != 0) { /* * Reserve space for the TCP message length. */ isc_buffer_init(&tcpbuffer, query->data, sizeof(query->data)); isc_buffer_init(&query->buffer, query->data + 2, sizeof(query->data) - 2); buffer = &tcpbuffer; } else { isc_buffer_init(&query->buffer, query->data, sizeof(query->data)); buffer = &query->buffer; } result = dns_message_gettempname(fctx->qmessage, &qname); if (result != ISC_R_SUCCESS) goto cleanup_temps; result = dns_message_gettemprdataset(fctx->qmessage, &qrdataset); if (result != ISC_R_SUCCESS) goto cleanup_temps; /* * Get a query id from the dispatch. */ result = dns_dispatch_addresponse2(query->dispatch, &query->addrinfo->sockaddr, task, resquery_response, query, &query->id, &query->dispentry, res->socketmgr); if (result != ISC_R_SUCCESS) goto cleanup_temps; fctx->qmessage->opcode = dns_opcode_query; /* * Set up question. */ dns_name_init(qname, NULL); dns_name_clone(&fctx->name, qname); dns_rdataset_makequestion(qrdataset, res->rdclass, fctx->type); ISC_LIST_APPEND(qname->list, qrdataset, link); dns_message_addname(fctx->qmessage, qname, DNS_SECTION_QUESTION); qname = NULL; qrdataset = NULL; /* * Set RD if the client has requested that we do a recursive query, * or if we're sending to a forwarder. */ if ((query->options & DNS_FETCHOPT_RECURSIVE) != 0 || ISFORWARDER(query->addrinfo)) fctx->qmessage->flags |= DNS_MESSAGEFLAG_RD; /* * Set CD if the client says not to validate, or if the * question is under a secure entry point and this is a * recursive/forward query -- unless the client said not to. */ if ((query->options & DNS_FETCHOPT_NOCDFLAG) != 0) /* Do nothing */ ; else if ((query->options & DNS_FETCHOPT_NOVALIDATE) != 0) fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD; else if (res->view->enablevalidation && ((fctx->qmessage->flags & DNS_MESSAGEFLAG_RD) != 0)) { result = dns_view_issecuredomain(res->view, &fctx->name, &secure_domain); if (result != ISC_R_SUCCESS) secure_domain = ISC_FALSE; if (res->view->dlv != NULL) secure_domain = ISC_TRUE; if (secure_domain) fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD; } /* * We don't have to set opcode because it defaults to query. */ fctx->qmessage->id = query->id; /* * Convert the question to wire format. */ result = dns_compress_init(&cctx, -1, fctx->res->mctx); if (result != ISC_R_SUCCESS) goto cleanup_message; cleanup_cctx = ISC_TRUE; result = dns_message_renderbegin(fctx->qmessage, &cctx, &query->buffer); if (result != ISC_R_SUCCESS) goto cleanup_message; result = dns_message_rendersection(fctx->qmessage, DNS_SECTION_QUESTION, 0); if (result != ISC_R_SUCCESS) goto cleanup_message; peer = NULL; isc_netaddr_fromsockaddr(&ipaddr, &query->addrinfo->sockaddr); (void) dns_peerlist_peerbyaddr(fctx->res->view->peers, &ipaddr, &peer); /* * The ADB does not know about servers with "edns no". Check this, * and then inform the ADB for future use. */ if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0 && peer != NULL && dns_peer_getsupportedns(peer, &useedns) == ISC_R_SUCCESS && !useedns) { query->options |= DNS_FETCHOPT_NOEDNS0; dns_adb_changeflags(fctx->adb, query->addrinfo, DNS_FETCHOPT_NOEDNS0, DNS_FETCHOPT_NOEDNS0); } /* Sync NOEDNS0 flag in addrinfo->flags and options now. */ if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) != 0) query->options |= DNS_FETCHOPT_NOEDNS0; /* See if response history indicates that EDNS is not supported. */ if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0 && dns_adb_noedns(fctx->adb, query->addrinfo)) query->options |= DNS_FETCHOPT_NOEDNS0; if (fctx->timeout && (query->options & DNS_FETCHOPT_NOEDNS0) == 0) { isc_sockaddr_t *sockaddr = &query->addrinfo->sockaddr; struct tried *tried; if (fctx->timeouts > (MAX_EDNS0_TIMEOUTS * 2) && (!EDNSOK(query->addrinfo) || !wouldvalidate(fctx))) { query->options |= DNS_FETCHOPT_NOEDNS0; fctx->reason = "disabling EDNS"; } else if ((tried = triededns512(fctx, sockaddr)) != NULL && tried->count >= 2U && (!EDNSOK(query->addrinfo) || !wouldvalidate(fctx))) { query->options |= DNS_FETCHOPT_NOEDNS0; fctx->reason = "disabling EDNS"; } else if ((tried = triededns(fctx, sockaddr)) != NULL) { if (tried->count == 1U) { hint = dns_adb_getudpsize(fctx->adb, query->addrinfo); } else if (tried->count >= 2U) { query->options |= DNS_FETCHOPT_EDNS512; fctx->reason = "reducing the advertised EDNS " "UDP packet size to 512 octets"; } } } fctx->timeout = ISC_FALSE; /* * Use EDNS0, unless the caller doesn't want it, or we know that * the remote server doesn't like it. */ if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) { if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0) { unsigned int version = 0; /* Default version. */ unsigned int flags = query->addrinfo->flags; isc_boolean_t reqnsid = res->view->requestnsid; #ifdef ISC_PLATFORM_USESIT isc_boolean_t reqsit = res->view->requestsit; unsigned char sit[64]; #endif if ((flags & FCTX_ADDRINFO_EDNSOK) != 0 && (query->options & DNS_FETCHOPT_EDNS512) == 0) { udpsize = dns_adb_probesize2(fctx->adb, query->addrinfo, fctx->timeouts); if (udpsize > res->udpsize) udpsize = res->udpsize; } if (peer != NULL) (void)dns_peer_getudpsize(peer, &udpsize); if (udpsize == 0U && res->udpsize == 512U) udpsize = 512; /* * Was the size forced to 512 in the configuration? */ if (udpsize == 512U) query->options |= DNS_FETCHOPT_EDNS512; /* * We have talked to this server before. */ if (hint != 0U) udpsize = hint; /* * We know nothing about the peer's capabilities * so start with minimal EDNS UDP size. */ if (udpsize == 0U) udpsize = 512; if ((flags & DNS_FETCHOPT_EDNSVERSIONSET) != 0) { version = flags & DNS_FETCHOPT_EDNSVERSIONMASK; version >>= DNS_FETCHOPT_EDNSVERSIONSHIFT; } /* Request NSID/SIT for current view or peer? */ if (peer != NULL) { (void) dns_peer_getrequestnsid(peer, &reqnsid); #ifdef ISC_PLATFORM_USESIT (void) dns_peer_getrequestsit(peer, &reqsit); #endif } #ifdef ISC_PLATFORM_USESIT if (NOSIT(query->addrinfo)) reqsit = ISC_FALSE; #endif if (reqnsid) { INSIST(ednsopt < DNS_EDNSOPTIONS); ednsopts[ednsopt].code = DNS_OPT_NSID; ednsopts[ednsopt].length = 0; ednsopts[ednsopt].value = NULL; ednsopt++; } #ifdef ISC_PLATFORM_USESIT if (reqsit) { INSIST(ednsopt < DNS_EDNSOPTIONS); ednsopts[ednsopt].code = DNS_OPT_COOKIE; ednsopts[ednsopt].length = (isc_uint16_t) dns_adb_getsit(fctx->adb, query->addrinfo, sit, sizeof(sit)); if (ednsopts[ednsopt].length != 0) { ednsopts[ednsopt].value = sit; inc_stats(fctx->res, dns_resstatscounter_sitout); } else { compute_cc(query, sit, sizeof(sit)); ednsopts[ednsopt].value = sit; ednsopts[ednsopt].length = 8; inc_stats(fctx->res, dns_resstatscounter_sitcc); } ednsopt++; } #endif query->ednsversion = version; result = fctx_addopt(fctx->qmessage, version, udpsize, ednsopts, ednsopt); if (reqnsid && result == ISC_R_SUCCESS) { query->options |= DNS_FETCHOPT_WANTNSID; } else if (result != ISC_R_SUCCESS) { /* * We couldn't add the OPT, but we'll press on. * We're not using EDNS0, so set the NOEDNS0 * bit. */ query->options |= DNS_FETCHOPT_NOEDNS0; query->ednsversion = -1; udpsize = 0; } } else { /* * We know this server doesn't like EDNS0, so we * won't use it. Set the NOEDNS0 bit since we're * not using EDNS0. */ query->options |= DNS_FETCHOPT_NOEDNS0; query->ednsversion = -1; } } else query->ednsversion = -1; /* * Record the UDP EDNS size choosen. */ query->udpsize = udpsize; /* * If we need EDNS0 to do this query and aren't using it, we lose. */ if (NEEDEDNS0(fctx) && (query->options & DNS_FETCHOPT_NOEDNS0) != 0) { result = DNS_R_SERVFAIL; goto cleanup_message; } if (udpsize > 512U) add_triededns(fctx, &query->addrinfo->sockaddr); if (udpsize == 512U) add_triededns512(fctx, &query->addrinfo->sockaddr); /* * Clear CD if EDNS is not in use. */ if ((query->options & DNS_FETCHOPT_NOEDNS0) != 0) fctx->qmessage->flags &= ~DNS_MESSAGEFLAG_CD; /* * Add TSIG record tailored to the current recipient. */ result = dns_view_getpeertsig(fctx->res->view, &ipaddr, &tsigkey); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) goto cleanup_message; if (tsigkey != NULL) { result = dns_message_settsigkey(fctx->qmessage, tsigkey); dns_tsigkey_detach(&tsigkey); if (result != ISC_R_SUCCESS) goto cleanup_message; } result = dns_message_rendersection(fctx->qmessage, DNS_SECTION_ADDITIONAL, 0); if (result != ISC_R_SUCCESS) goto cleanup_message; result = dns_message_renderend(fctx->qmessage); if (result != ISC_R_SUCCESS) goto cleanup_message; dns_compress_invalidate(&cctx); cleanup_cctx = ISC_FALSE; if (dns_message_gettsigkey(fctx->qmessage) != NULL) { dns_tsigkey_attach(dns_message_gettsigkey(fctx->qmessage), &query->tsigkey); result = dns_message_getquerytsig(fctx->qmessage, fctx->res->mctx, &query->tsig); if (result != ISC_R_SUCCESS) goto cleanup_message; } /* * If using TCP, write the length of the message at the beginning * of the buffer. */ if ((query->options & DNS_FETCHOPT_TCP) != 0) { isc_buffer_usedregion(&query->buffer, &r); isc_buffer_putuint16(&tcpbuffer, (isc_uint16_t)r.length); isc_buffer_add(&tcpbuffer, r.length); } /* * We're now done with the query message. */ dns_message_reset(fctx->qmessage, DNS_MESSAGE_INTENTRENDER); if (query->exclusivesocket) sock = dns_dispatch_getentrysocket(query->dispentry); else sock = dns_dispatch_getsocket(query->dispatch); /* * Send the query! */ if ((query->options & DNS_FETCHOPT_TCP) == 0) { address = &query->addrinfo->sockaddr; if (query->exclusivesocket) { result = isc_socket_connect(sock, address, task, resquery_udpconnected, query); if (result != ISC_R_SUCCESS) goto cleanup_message; connecting = ISC_TRUE; query->connects++; } } isc_buffer_usedregion(buffer, &r); /* * XXXRTH Make sure we don't send to ourselves! We should probably * prune out these addresses when we get them from the ADB. */ memset(&query->sendevent, 0, sizeof(query->sendevent)); ISC_EVENT_INIT(&query->sendevent, sizeof(query->sendevent), 0, NULL, ISC_SOCKEVENT_SENDDONE, resquery_senddone, query, NULL, NULL, NULL); if (query->dscp == -1) { query->sendevent.attributes &= ~ISC_SOCKEVENTATTR_DSCP; query->sendevent.dscp = 0; } else { query->sendevent.attributes |= ISC_SOCKEVENTATTR_DSCP; query->sendevent.dscp = query->dscp; if ((query->options & DNS_FETCHOPT_TCP) != 0) isc_socket_dscp(sock, query->dscp); } result = isc_socket_sendto2(sock, &r, task, address, NULL, &query->sendevent, 0); if (result != ISC_R_SUCCESS) { if (connecting) { /* * This query is still connecting. * Mark it as canceled so that it will just be * cleaned up when the connected event is received. * Keep fctx around until the event is processed. */ query->fctx->nqueries++; query->attributes |= RESQUERY_ATTR_CANCELED; } goto cleanup_message; } query->sends++; QTRACE("sent"); return (ISC_R_SUCCESS); cleanup_message: if (cleanup_cctx) dns_compress_invalidate(&cctx); dns_message_reset(fctx->qmessage, DNS_MESSAGE_INTENTRENDER); /* * Stop the dispatcher from listening. */ dns_dispatch_removeresponse(&query->dispentry, NULL); cleanup_temps: if (qname != NULL) dns_message_puttempname(fctx->qmessage, &qname); if (qrdataset != NULL) dns_message_puttemprdataset(fctx->qmessage, &qrdataset); return (result); } static void resquery_connected(isc_task_t *task, isc_event_t *event) { isc_socketevent_t *sevent = (isc_socketevent_t *)event; resquery_t *query = event->ev_arg; isc_boolean_t retry = ISC_FALSE; isc_interval_t interval; isc_result_t result; unsigned int attrs; fetchctx_t *fctx; REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT); REQUIRE(VALID_QUERY(query)); QTRACE("connected"); UNUSED(task); /* * XXXRTH * * Currently we don't wait for the connect event before retrying * a query. This means that if we get really behind, we may end * up doing extra work! */ query->connects--; fctx = query->fctx; if (RESQUERY_CANCELED(query)) { /* * This query was canceled while the connect() was in * progress. */ isc_socket_detach(&query->tcpsocket); resquery_destroy(&query); } else { switch (sevent->result) { case ISC_R_SUCCESS: /* * Extend the idle timer for TCP. 20 seconds * should be long enough for a TCP connection to be * established, a single DNS request to be sent, * and the response received. */ isc_interval_set(&interval, 20, 0); result = fctx_startidletimer(query->fctx, &interval); if (result != ISC_R_SUCCESS) { FCTXTRACE("query canceled: idle timer failed; " "responding"); fctx_cancelquery(&query, NULL, NULL, ISC_FALSE); fctx_done(fctx, result, __LINE__); break; } /* * We are connected. Create a dispatcher and * send the query. */ attrs = 0; attrs |= DNS_DISPATCHATTR_TCP; attrs |= DNS_DISPATCHATTR_PRIVATE; attrs |= DNS_DISPATCHATTR_CONNECTED; if (isc_sockaddr_pf(&query->addrinfo->sockaddr) == AF_INET) attrs |= DNS_DISPATCHATTR_IPV4; else attrs |= DNS_DISPATCHATTR_IPV6; attrs |= DNS_DISPATCHATTR_MAKEQUERY; result = dns_dispatch_createtcp(query->dispatchmgr, query->tcpsocket, query->fctx->res->taskmgr, 4096, 2, 1, 1, 3, attrs, &query->dispatch); /* * Regardless of whether dns_dispatch_create() * succeeded or not, we don't need our reference * to the socket anymore. */ isc_socket_detach(&query->tcpsocket); if (result == ISC_R_SUCCESS) result = resquery_send(query); if (result != ISC_R_SUCCESS) { FCTXTRACE("query canceled: " "resquery_send() failed; responding"); fctx_cancelquery(&query, NULL, NULL, ISC_FALSE); fctx_done(fctx, result, __LINE__); } break; case ISC_R_NETUNREACH: case ISC_R_HOSTUNREACH: case ISC_R_CONNREFUSED: case ISC_R_NOPERM: case ISC_R_ADDRNOTAVAIL: case ISC_R_CONNECTIONRESET: FCTXTRACE3("query canceled in connected(): " "no route to host; no response", sevent->result); /* * No route to remote. */ isc_socket_detach(&query->tcpsocket); fctx_cancelquery(&query, NULL, NULL, ISC_TRUE); retry = ISC_TRUE; break; default: FCTXTRACE3("query canceled in connected() due to " "unexpected event result; responding", sevent->result); isc_socket_detach(&query->tcpsocket); fctx_cancelquery(&query, NULL, NULL, ISC_FALSE); break; } } isc_event_free(&event); if (retry) { /* * Behave as if the idle timer has expired. For TCP * connections this may not actually reflect the latest timer. */ fctx->attributes &= ~FCTX_ATTR_ADDRWAIT; result = fctx_stopidletimer(fctx); if (result != ISC_R_SUCCESS) fctx_done(fctx, result, __LINE__); else fctx_try(fctx, ISC_TRUE, ISC_FALSE); } } static void fctx_finddone(isc_task_t *task, isc_event_t *event) { fetchctx_t *fctx; dns_adbfind_t *find; dns_resolver_t *res; isc_boolean_t want_try = ISC_FALSE; isc_boolean_t want_done = ISC_FALSE; isc_boolean_t bucket_empty = ISC_FALSE; unsigned int bucketnum; isc_boolean_t dodestroy = ISC_FALSE; find = event->ev_sender; fctx = event->ev_arg; REQUIRE(VALID_FCTX(fctx)); res = fctx->res; UNUSED(task); FCTXTRACE("finddone"); bucketnum = fctx->bucketnum; LOCK(&res->buckets[bucketnum].lock); INSIST(fctx->pending > 0); fctx->pending--; if (ADDRWAIT(fctx)) { /* * The fetch is waiting for a name to be found. */ INSIST(!SHUTTINGDOWN(fctx)); fctx->attributes &= ~FCTX_ATTR_ADDRWAIT; if (event->ev_type == DNS_EVENT_ADBMOREADDRESSES) { want_try = ISC_TRUE; } else { fctx->findfail++; if (fctx->pending == 0) { /* * We've got nothing else to wait for and don't * know the answer. There's nothing to do but * fail the fctx. */ want_done = ISC_TRUE; } } } else if (SHUTTINGDOWN(fctx) && fctx->pending == 0 && fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) { if (fctx->references == 0) { bucket_empty = fctx_unlink(fctx); dodestroy = ISC_TRUE; } } UNLOCK(&res->buckets[bucketnum].lock); isc_event_free(&event); dns_adb_destroyfind(&find); if (want_try) { fctx_try(fctx, ISC_TRUE, ISC_FALSE); } else if (want_done) { FCTXTRACE("fetch failed in finddone(); return ISC_R_FAILURE"); fctx_done(fctx, ISC_R_FAILURE, __LINE__); } else if (dodestroy) { fctx_destroy(fctx); if (bucket_empty) empty_bucket(res); } } static inline isc_boolean_t bad_server(fetchctx_t *fctx, isc_sockaddr_t *address) { isc_sockaddr_t *sa; for (sa = ISC_LIST_HEAD(fctx->bad); sa != NULL; sa = ISC_LIST_NEXT(sa, link)) { if (isc_sockaddr_equal(sa, address)) return (ISC_TRUE); } return (ISC_FALSE); } static inline isc_boolean_t mark_bad(fetchctx_t *fctx) { dns_adbfind_t *curr; dns_adbaddrinfo_t *addrinfo; isc_boolean_t all_bad = ISC_TRUE; /* * Mark all known bad servers, so we don't try to talk to them * again. */ /* * Mark any bad nameservers. */ for (curr = ISC_LIST_HEAD(fctx->finds); curr != NULL; curr = ISC_LIST_NEXT(curr, publink)) { for (addrinfo = ISC_LIST_HEAD(curr->list); addrinfo != NULL; addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { if (bad_server(fctx, &addrinfo->sockaddr)) addrinfo->flags |= FCTX_ADDRINFO_MARK; else all_bad = ISC_FALSE; } } /* * Mark any bad forwarders. */ for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs); addrinfo != NULL; addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { if (bad_server(fctx, &addrinfo->sockaddr)) addrinfo->flags |= FCTX_ADDRINFO_MARK; else all_bad = ISC_FALSE; } /* * Mark any bad alternates. */ for (curr = ISC_LIST_HEAD(fctx->altfinds); curr != NULL; curr = ISC_LIST_NEXT(curr, publink)) { for (addrinfo = ISC_LIST_HEAD(curr->list); addrinfo != NULL; addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { if (bad_server(fctx, &addrinfo->sockaddr)) addrinfo->flags |= FCTX_ADDRINFO_MARK; else all_bad = ISC_FALSE; } } for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs); addrinfo != NULL; addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { if (bad_server(fctx, &addrinfo->sockaddr)) addrinfo->flags |= FCTX_ADDRINFO_MARK; else all_bad = ISC_FALSE; } return (all_bad); } static void add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_result_t reason, badnstype_t badtype) { char namebuf[DNS_NAME_FORMATSIZE]; char addrbuf[ISC_SOCKADDR_FORMATSIZE]; char classbuf[64]; char typebuf[64]; char code[64]; isc_buffer_t b; isc_sockaddr_t *sa; const char *spc = ""; isc_sockaddr_t *address = &addrinfo->sockaddr; if (reason == DNS_R_LAME) fctx->lamecount++; else { switch (badtype) { case badns_unreachable: fctx->neterr++; break; case badns_response: fctx->badresp++; break; case badns_validation: break; /* counted as 'valfail' */ } } if (bad_server(fctx, address)) { /* * We already know this server is bad. */ return; } FCTXTRACE("add_bad"); sa = isc_mem_get(fctx->mctx, sizeof(*sa)); if (sa == NULL) return; *sa = *address; ISC_LIST_INITANDAPPEND(fctx->bad, sa, link); if (reason == DNS_R_LAME) /* already logged */ return; if (reason == DNS_R_UNEXPECTEDRCODE && fctx->rmessage->rcode == dns_rcode_servfail && ISFORWARDER(addrinfo)) return; if (reason == DNS_R_UNEXPECTEDRCODE) { isc_buffer_init(&b, code, sizeof(code) - 1); dns_rcode_totext(fctx->rmessage->rcode, &b); code[isc_buffer_usedlength(&b)] = '\0'; spc = " "; } else if (reason == DNS_R_UNEXPECTEDOPCODE) { isc_buffer_init(&b, code, sizeof(code) - 1); dns_opcode_totext((dns_opcode_t)fctx->rmessage->opcode, &b); code[isc_buffer_usedlength(&b)] = '\0'; spc = " "; } else { code[0] = '\0'; } dns_name_format(&fctx->name, namebuf, sizeof(namebuf)); dns_rdatatype_format(fctx->type, typebuf, sizeof(typebuf)); dns_rdataclass_format(fctx->res->rdclass, classbuf, sizeof(classbuf)); isc_sockaddr_format(address, addrbuf, sizeof(addrbuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_LAME_SERVERS, DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, "%s%s%s resolving '%s/%s/%s': %s", code, spc, dns_result_totext(reason), namebuf, typebuf, classbuf, addrbuf); } /* * Sort addrinfo list by RTT. */ static void sort_adbfind(dns_adbfind_t *find) { dns_adbaddrinfo_t *best, *curr; dns_adbaddrinfolist_t sorted; /* Lame N^2 bubble sort. */ ISC_LIST_INIT(sorted); while (!ISC_LIST_EMPTY(find->list)) { best = ISC_LIST_HEAD(find->list); curr = ISC_LIST_NEXT(best, publink); while (curr != NULL) { if (curr->srtt < best->srtt) best = curr; curr = ISC_LIST_NEXT(curr, publink); } ISC_LIST_UNLINK(find->list, best, publink); ISC_LIST_APPEND(sorted, best, publink); } find->list = sorted; } /* * Sort a list of finds by server RTT. */ static void sort_finds(dns_adbfindlist_t *findlist) { dns_adbfind_t *best, *curr; dns_adbfindlist_t sorted; dns_adbaddrinfo_t *addrinfo, *bestaddrinfo; /* Sort each find's addrinfo list by SRTT. */ for (curr = ISC_LIST_HEAD(*findlist); curr != NULL; curr = ISC_LIST_NEXT(curr, publink)) sort_adbfind(curr); /* Lame N^2 bubble sort. */ ISC_LIST_INIT(sorted); while (!ISC_LIST_EMPTY(*findlist)) { best = ISC_LIST_HEAD(*findlist); bestaddrinfo = ISC_LIST_HEAD(best->list); INSIST(bestaddrinfo != NULL); curr = ISC_LIST_NEXT(best, publink); while (curr != NULL) { addrinfo = ISC_LIST_HEAD(curr->list); INSIST(addrinfo != NULL); if (addrinfo->srtt < bestaddrinfo->srtt) { best = curr; bestaddrinfo = addrinfo; } curr = ISC_LIST_NEXT(curr, publink); } ISC_LIST_UNLINK(*findlist, best, publink); ISC_LIST_APPEND(sorted, best, publink); } *findlist = sorted; } static void findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port, unsigned int options, unsigned int flags, isc_stdtime_t now, isc_boolean_t *overquota, isc_boolean_t *need_alternate) { dns_adbaddrinfo_t *ai; dns_adbfind_t *find; dns_resolver_t *res; isc_boolean_t unshared; isc_result_t result; #ifndef ENABLE_FETCHLIMIT UNUSED(overquota); #endif /* !ENABLE_FETCHLIMIT */ res = fctx->res; unshared = ISC_TF((fctx->options & DNS_FETCHOPT_UNSHARED) != 0); /* * If this name is a subdomain of the query domain, tell * the ADB to start looking using zone/hint data. This keeps us * from getting stuck if the nameserver is beneath the zone cut * and we don't know its address (e.g. because the A record has * expired). */ if (dns_name_issubdomain(name, &fctx->domain)) options |= DNS_ADBFIND_STARTATZONE; options |= DNS_ADBFIND_GLUEOK; options |= DNS_ADBFIND_HINTOK; /* * See what we know about this address. */ find = NULL; result = dns_adb_createfind2(fctx->adb, res->buckets[fctx->bucketnum].task, fctx_finddone, fctx, name, &fctx->name, fctx->type, options, now, NULL, res->view->dstport, fctx->depth + 1, fctx->qc, &find); if (result != ISC_R_SUCCESS) { if (result == DNS_R_ALIAS) { char namebuf[DNS_NAME_FORMATSIZE]; /* * XXXRTH Follow the CNAME/DNAME chain? */ dns_adb_destroyfind(&find); fctx->adberr++; dns_name_format(name, namebuf, sizeof(namebuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_CNAME, DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, "skipping nameserver '%s' because it " "is a CNAME, while resolving '%s'", namebuf, fctx->info); } } else if (!ISC_LIST_EMPTY(find->list)) { /* * We have at least some of the addresses for the * name. */ INSIST((find->options & DNS_ADBFIND_WANTEVENT) == 0); if (flags != 0 || port != 0) { for (ai = ISC_LIST_HEAD(find->list); ai != NULL; ai = ISC_LIST_NEXT(ai, publink)) { ai->flags |= flags; if (port != 0) isc_sockaddr_setport(&ai->sockaddr, port); } } if ((flags & FCTX_ADDRINFO_FORWARDER) != 0) ISC_LIST_APPEND(fctx->altfinds, find, publink); else ISC_LIST_APPEND(fctx->finds, find, publink); } else { /* * We don't know any of the addresses for this * name. */ if ((find->options & DNS_ADBFIND_WANTEVENT) != 0) { /* * We're looking for them and will get an * event about it later. */ fctx->pending++; /* * Bootstrap. */ if (need_alternate != NULL && !*need_alternate && unshared && ((res->dispatches4 == NULL && find->result_v6 != DNS_R_NXDOMAIN) || (res->dispatches6 == NULL && find->result_v4 != DNS_R_NXDOMAIN))) *need_alternate = ISC_TRUE; } else { #ifdef ENABLE_FETCHLIMIT if ((find->options & DNS_ADBFIND_OVERQUOTA) != 0) { if (overquota != NULL) *overquota = ISC_TRUE; fctx->quotacount++; /* quota exceeded */ } else #endif /* ENABLE_FETCHLIMIT */ if ((find->options & DNS_ADBFIND_LAMEPRUNED) != 0) fctx->lamecount++; /* cached lame server */ else fctx->adberr++; /* unreachable server, etc. */ /* * If we know there are no addresses for * the family we are using then try to add * an alternative server. */ if (need_alternate != NULL && !*need_alternate && ((res->dispatches4 == NULL && find->result_v6 == DNS_R_NXRRSET) || (res->dispatches6 == NULL && find->result_v4 == DNS_R_NXRRSET))) *need_alternate = ISC_TRUE; dns_adb_destroyfind(&find); } } } static isc_boolean_t isstrictsubdomain(dns_name_t *name1, dns_name_t *name2) { int order; unsigned int nlabels; dns_namereln_t namereln; namereln = dns_name_fullcompare(name1, name2, &order, &nlabels); return (ISC_TF(namereln == dns_namereln_subdomain)); } static isc_result_t fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) { dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; dns_resolver_t *res; isc_stdtime_t now; unsigned int stdoptions = 0; dns_forwarder_t *fwd; dns_adbaddrinfo_t *ai; isc_boolean_t all_bad; dns_rdata_ns_t ns; isc_boolean_t need_alternate = ISC_FALSE; #ifdef ENABLE_FETCHLIMIT isc_boolean_t all_spilled = ISC_TRUE; #endif /* ENABLE_FETCHLIMIT */ FCTXTRACE("getaddresses"); /* * Don't pound on remote servers. (Failsafe!) */ fctx->restarts++; if (fctx->restarts > 100) { FCTXTRACE("too many restarts"); return (DNS_R_SERVFAIL); } res = fctx->res; if (fctx->depth > res->maxdepth) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3), "too much NS indirection resolving '%s'", fctx->info); return (DNS_R_SERVFAIL); } /* * Forwarders. */ INSIST(ISC_LIST_EMPTY(fctx->forwaddrs)); INSIST(ISC_LIST_EMPTY(fctx->altaddrs)); /* * If this fctx has forwarders, use them; otherwise use any * selective forwarders specified in the view; otherwise use the * resolver's forwarders (if any). */ fwd = ISC_LIST_HEAD(fctx->forwarders); if (fwd == NULL) { dns_forwarders_t *forwarders = NULL; dns_name_t *name = &fctx->name; dns_name_t suffix; unsigned int labels; dns_fixedname_t fixed; dns_name_t *domain; /* * DS records are found in the parent server. * Strip label to get the correct forwarder (if any). */ if (dns_rdatatype_atparent(fctx->type) && dns_name_countlabels(name) > 1) { dns_name_init(&suffix, NULL); labels = dns_name_countlabels(name); dns_name_getlabelsequence(name, 1, labels - 1, &suffix); name = &suffix; } dns_fixedname_init(&fixed); domain = dns_fixedname_name(&fixed); result = dns_fwdtable_find2(res->view->fwdtable, name, domain, &forwarders); if (result == ISC_R_SUCCESS) { fwd = ISC_LIST_HEAD(forwarders->fwdrs); fctx->fwdpolicy = forwarders->fwdpolicy; if (fctx->fwdpolicy == dns_fwdpolicy_only && isstrictsubdomain(domain, &fctx->domain)) { #ifdef ENABLE_FETCHLIMIT fcount_decr(fctx); #endif /* ENABLE_FETCHLIMIT */ dns_name_free(&fctx->domain, fctx->mctx); dns_name_init(&fctx->domain, NULL); result = dns_name_dup(domain, fctx->mctx, &fctx->domain); if (result != ISC_R_SUCCESS) return (result); #ifdef ENABLE_FETCHLIMIT result = fcount_incr(fctx, ISC_TRUE); if (result != ISC_R_SUCCESS) return (result); #endif /* ENABLE_FETCHLIMIT */ } } } while (fwd != NULL) { if ((isc_sockaddr_pf(&fwd->addr) == AF_INET && res->dispatches4 == NULL) || (isc_sockaddr_pf(&fwd->addr) == AF_INET6 && res->dispatches6 == NULL)) { fwd = ISC_LIST_NEXT(fwd, link); continue; } ai = NULL; result = dns_adb_findaddrinfo(fctx->adb, &fwd->addr, &ai, 0); if (result == ISC_R_SUCCESS) { dns_adbaddrinfo_t *cur; ai->flags |= FCTX_ADDRINFO_FORWARDER; ai->dscp = fwd->dscp; cur = ISC_LIST_HEAD(fctx->forwaddrs); while (cur != NULL && cur->srtt < ai->srtt) cur = ISC_LIST_NEXT(cur, publink); if (cur != NULL) ISC_LIST_INSERTBEFORE(fctx->forwaddrs, cur, ai, publink); else ISC_LIST_APPEND(fctx->forwaddrs, ai, publink); } fwd = ISC_LIST_NEXT(fwd, link); } /* * If the forwarding policy is "only", we don't need the addresses * of the nameservers. */ if (fctx->fwdpolicy == dns_fwdpolicy_only) goto out; /* * Normal nameservers. */ stdoptions = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_EMPTYEVENT; if (fctx->restarts == 1) { /* * To avoid sending out a flood of queries likely to * result in NXRRSET, we suppress fetches for address * families we don't have the first time through, * provided that we have addresses in some family we * can use. * * We don't want to set this option all the time, since * if fctx->restarts > 1, we've clearly been having trouble * with the addresses we had, so getting more could help. */ stdoptions |= DNS_ADBFIND_AVOIDFETCHES; } if (res->dispatches4 != NULL) stdoptions |= DNS_ADBFIND_INET; if (res->dispatches6 != NULL) stdoptions |= DNS_ADBFIND_INET6; if ((stdoptions & DNS_ADBFIND_ADDRESSMASK) == 0) return (DNS_R_SERVFAIL); isc_stdtime_get(&now); INSIST(ISC_LIST_EMPTY(fctx->finds)); INSIST(ISC_LIST_EMPTY(fctx->altfinds)); for (result = dns_rdataset_first(&fctx->nameservers); result == ISC_R_SUCCESS; result = dns_rdataset_next(&fctx->nameservers)) { isc_boolean_t overquota = ISC_FALSE; dns_rdataset_current(&fctx->nameservers, &rdata); /* * Extract the name from the NS record. */ result = dns_rdata_tostruct(&rdata, &ns, NULL); if (result != ISC_R_SUCCESS) continue; findname(fctx, &ns.name, 0, stdoptions, 0, now, &overquota, &need_alternate); #ifdef ENABLE_FETCHLIMIT if (!overquota) all_spilled = ISC_FALSE; #endif /* ENABLE_FETCHLIMIT */ dns_rdata_reset(&rdata); dns_rdata_freestruct(&ns); } if (result != ISC_R_NOMORE) return (result); /* * Do we need to use 6 to 4? */ if (need_alternate) { int family; alternate_t *a; family = (res->dispatches6 != NULL) ? AF_INET6 : AF_INET; for (a = ISC_LIST_HEAD(res->alternates); a != NULL; a = ISC_LIST_NEXT(a, link)) { if (!a->isaddress) { findname(fctx, &a->_u._n.name, a->_u._n.port, stdoptions, FCTX_ADDRINFO_FORWARDER, now, NULL, NULL); continue; } if (isc_sockaddr_pf(&a->_u.addr) != family) continue; ai = NULL; result = dns_adb_findaddrinfo(fctx->adb, &a->_u.addr, &ai, 0); if (result == ISC_R_SUCCESS) { dns_adbaddrinfo_t *cur; ai->flags |= FCTX_ADDRINFO_FORWARDER; cur = ISC_LIST_HEAD(fctx->altaddrs); while (cur != NULL && cur->srtt < ai->srtt) cur = ISC_LIST_NEXT(cur, publink); if (cur != NULL) ISC_LIST_INSERTBEFORE(fctx->altaddrs, cur, ai, publink); else ISC_LIST_APPEND(fctx->altaddrs, ai, publink); } } } out: /* * Mark all known bad servers. */ all_bad = mark_bad(fctx); /* * How are we doing? */ if (all_bad) { /* * We've got no addresses. */ if (fctx->pending > 0) { /* * We're fetching the addresses, but don't have any * yet. Tell the caller to wait for an answer. */ result = DNS_R_WAIT; } else { isc_time_t expire; isc_interval_t i; /* * We've lost completely. We don't know any * addresses, and the ADB has told us it can't get * them. */ FCTXTRACE("no addresses"); isc_interval_set(&i, DNS_BADCACHE_TTL(fctx), 0); result = isc_time_nowplusinterval(&expire, &i); if (badcache && (fctx->type == dns_rdatatype_dnskey || fctx->type == dns_rdatatype_dlv || fctx->type == dns_rdatatype_ds) && result == ISC_R_SUCCESS) dns_resolver_addbadcache(res, &fctx->name, fctx->type, &expire); #ifdef ENABLE_FETCHLIMIT /* * If all of the addresses found were over the * fetches-per-server quota, return the configured * response. */ if (all_spilled) { result = res->quotaresp[dns_quotatype_server]; inc_stats(res, dns_resstatscounter_serverquota); } else result = ISC_R_FAILURE; #endif /* ENABLE_FETCHLIMIT */ } } else { /* * We've found some addresses. We might still be looking * for more addresses. */ sort_finds(&fctx->finds); sort_finds(&fctx->altfinds); result = ISC_R_SUCCESS; } return (result); } static inline void possibly_mark(fetchctx_t *fctx, dns_adbaddrinfo_t *addr) { isc_netaddr_t na; char buf[ISC_NETADDR_FORMATSIZE]; isc_sockaddr_t *sa; isc_boolean_t aborted = ISC_FALSE; isc_boolean_t bogus; dns_acl_t *blackhole; isc_netaddr_t ipaddr; dns_peer_t *peer = NULL; dns_resolver_t *res; const char *msg = NULL; sa = &addr->sockaddr; res = fctx->res; isc_netaddr_fromsockaddr(&ipaddr, sa); blackhole = dns_dispatchmgr_getblackhole(res->dispatchmgr); (void) dns_peerlist_peerbyaddr(res->view->peers, &ipaddr, &peer); if (blackhole != NULL) { int match; if (dns_acl_match(&ipaddr, NULL, blackhole, &res->view->aclenv, &match, NULL) == ISC_R_SUCCESS && match > 0) aborted = ISC_TRUE; } if (peer != NULL && dns_peer_getbogus(peer, &bogus) == ISC_R_SUCCESS && bogus) aborted = ISC_TRUE; if (aborted) { addr->flags |= FCTX_ADDRINFO_MARK; msg = "ignoring blackholed / bogus server: "; } else if (isc_sockaddr_ismulticast(sa)) { addr->flags |= FCTX_ADDRINFO_MARK; msg = "ignoring multicast address: "; } else if (isc_sockaddr_isexperimental(sa)) { addr->flags |= FCTX_ADDRINFO_MARK; msg = "ignoring experimental address: "; } else if (sa->type.sa.sa_family != AF_INET6) { return; } else if (IN6_IS_ADDR_V4MAPPED(&sa->type.sin6.sin6_addr)) { addr->flags |= FCTX_ADDRINFO_MARK; msg = "ignoring IPv6 mapped IPV4 address: "; } else if (IN6_IS_ADDR_V4COMPAT(&sa->type.sin6.sin6_addr)) { addr->flags |= FCTX_ADDRINFO_MARK; msg = "ignoring IPv6 compatibility IPV4 address: "; } else return; if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { isc_netaddr_fromsockaddr(&na, sa); isc_netaddr_format(&na, buf, sizeof(buf)); FCTXTRACE2(msg, buf); } } static inline dns_adbaddrinfo_t * fctx_nextaddress(fetchctx_t *fctx) { dns_adbfind_t *find, *start; dns_adbaddrinfo_t *addrinfo; dns_adbaddrinfo_t *faddrinfo; /* * Return the next untried address, if any. */ /* * Find the first unmarked forwarder (if any). */ for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs); addrinfo != NULL; addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { if (!UNMARKED(addrinfo)) continue; possibly_mark(fctx, addrinfo); if (UNMARKED(addrinfo)) { addrinfo->flags |= FCTX_ADDRINFO_MARK; fctx->find = NULL; return (addrinfo); } } /* * No forwarders. Move to the next find. */ fctx->attributes |= FCTX_ATTR_TRIEDFIND; find = fctx->find; if (find == NULL) find = ISC_LIST_HEAD(fctx->finds); else { find = ISC_LIST_NEXT(find, publink); if (find == NULL) find = ISC_LIST_HEAD(fctx->finds); } /* * Find the first unmarked addrinfo. */ addrinfo = NULL; if (find != NULL) { start = find; do { for (addrinfo = ISC_LIST_HEAD(find->list); addrinfo != NULL; addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { if (!UNMARKED(addrinfo)) continue; possibly_mark(fctx, addrinfo); if (UNMARKED(addrinfo)) { addrinfo->flags |= FCTX_ADDRINFO_MARK; break; } } if (addrinfo != NULL) break; find = ISC_LIST_NEXT(find, publink); if (find == NULL) find = ISC_LIST_HEAD(fctx->finds); } while (find != start); } fctx->find = find; if (addrinfo != NULL) return (addrinfo); /* * No nameservers left. Try alternates. */ fctx->attributes |= FCTX_ATTR_TRIEDALT; find = fctx->altfind; if (find == NULL) find = ISC_LIST_HEAD(fctx->altfinds); else { find = ISC_LIST_NEXT(find, publink); if (find == NULL) find = ISC_LIST_HEAD(fctx->altfinds); } /* * Find the first unmarked addrinfo. */ addrinfo = NULL; if (find != NULL) { start = find; do { for (addrinfo = ISC_LIST_HEAD(find->list); addrinfo != NULL; addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { if (!UNMARKED(addrinfo)) continue; possibly_mark(fctx, addrinfo); if (UNMARKED(addrinfo)) { addrinfo->flags |= FCTX_ADDRINFO_MARK; break; } } if (addrinfo != NULL) break; find = ISC_LIST_NEXT(find, publink); if (find == NULL) find = ISC_LIST_HEAD(fctx->altfinds); } while (find != start); } faddrinfo = addrinfo; /* * See if we have a better alternate server by address. */ for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs); addrinfo != NULL; addrinfo = ISC_LIST_NEXT(addrinfo, publink)) { if (!UNMARKED(addrinfo)) continue; possibly_mark(fctx, addrinfo); if (UNMARKED(addrinfo) && (faddrinfo == NULL || addrinfo->srtt < faddrinfo->srtt)) { if (faddrinfo != NULL) faddrinfo->flags &= ~FCTX_ADDRINFO_MARK; addrinfo->flags |= FCTX_ADDRINFO_MARK; break; } } if (addrinfo == NULL) { addrinfo = faddrinfo; fctx->altfind = find; } return (addrinfo); } static void fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, isc_boolean_t badcache) { isc_result_t result; dns_adbaddrinfo_t *addrinfo = NULL; dns_resolver_t *res; unsigned int bucketnum; isc_boolean_t bucket_empty; FCTXTRACE("try"); REQUIRE(!ADDRWAIT(fctx)); res = fctx->res; /* We've already exceeded maximum query count */ if (isc_counter_used(fctx->qc) > res->maxqueries) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3), "exceeded max queries resolving '%s'", fctx->info); fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); return; } #ifdef ENABLE_FETCHLIMIT /* Try to find an address that isn't over quota */ while ((addrinfo = fctx_nextaddress(fctx)) != NULL) if (! dns_adbentry_overquota(addrinfo->entry)) break; #endif /* ENABLE_FETCHLIMIT */ if (addrinfo == NULL) { /* We have no more addresses. Start over. */ fctx_cancelqueries(fctx, ISC_TRUE); fctx_cleanupfinds(fctx); fctx_cleanupaltfinds(fctx); fctx_cleanupforwaddrs(fctx); fctx_cleanupaltaddrs(fctx); result = fctx_getaddresses(fctx, badcache); if (result == DNS_R_WAIT) { /* * Sleep waiting for addresses. */ FCTXTRACE("addrwait"); fctx->attributes |= FCTX_ATTR_ADDRWAIT; return; } else if (result != ISC_R_SUCCESS) { /* * Something bad happened. */ fctx_done(fctx, result, __LINE__); return; } #ifdef ENABLE_FETCHLIMIT while ((addrinfo = fctx_nextaddress(fctx)) != NULL) { if (! dns_adbentry_overquota(addrinfo->entry)) break; } #else addrinfo = fctx_nextaddress(fctx); #endif /* !ENABLE_FETCHLIMIT */ /* * While we may have addresses from the ADB, they * might be bad ones. In this case, return SERVFAIL. */ if (addrinfo == NULL) { fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); return; } } if (dns_name_countlabels(&fctx->domain) > 2) { result = isc_counter_increment(fctx->qc); if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3), "exceeded max queries resolving '%s'", fctx->info); fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); return; } } bucketnum = fctx->bucketnum; fctx_increference(fctx); result = fctx_query(fctx, addrinfo, fctx->options); if (result != ISC_R_SUCCESS) { fctx_done(fctx, result, __LINE__); LOCK(&res->buckets[bucketnum].lock); bucket_empty = fctx_decreference(fctx); UNLOCK(&res->buckets[bucketnum].lock); if (bucket_empty) empty_bucket(res); } else if (retrying) inc_stats(res, dns_resstatscounter_retry); } static isc_boolean_t fctx_unlink(fetchctx_t *fctx) { dns_resolver_t *res; unsigned int bucketnum; /* * Caller must be holding the bucket lock. */ REQUIRE(VALID_FCTX(fctx)); REQUIRE(fctx->state == fetchstate_done || fctx->state == fetchstate_init); REQUIRE(ISC_LIST_EMPTY(fctx->events)); REQUIRE(ISC_LIST_EMPTY(fctx->queries)); REQUIRE(ISC_LIST_EMPTY(fctx->finds)); REQUIRE(ISC_LIST_EMPTY(fctx->altfinds)); REQUIRE(fctx->pending == 0); REQUIRE(fctx->references == 0); REQUIRE(ISC_LIST_EMPTY(fctx->validators)); FCTXTRACE("unlink"); res = fctx->res; bucketnum = fctx->bucketnum; ISC_LIST_UNLINK(res->buckets[bucketnum].fctxs, fctx, link); LOCK(&res->nlock); res->nfctx--; UNLOCK(&res->nlock); dec_stats(res, dns_resstatscounter_nfetch); if (res->buckets[bucketnum].exiting && ISC_LIST_EMPTY(res->buckets[bucketnum].fctxs)) return (ISC_TRUE); return (ISC_FALSE); } static void fctx_destroy(fetchctx_t *fctx) { isc_sockaddr_t *sa, *next_sa; struct tried *tried; REQUIRE(VALID_FCTX(fctx)); REQUIRE(fctx->state == fetchstate_done || fctx->state == fetchstate_init); REQUIRE(ISC_LIST_EMPTY(fctx->events)); REQUIRE(ISC_LIST_EMPTY(fctx->queries)); REQUIRE(ISC_LIST_EMPTY(fctx->finds)); REQUIRE(ISC_LIST_EMPTY(fctx->altfinds)); REQUIRE(fctx->pending == 0); REQUIRE(fctx->references == 0); REQUIRE(ISC_LIST_EMPTY(fctx->validators)); REQUIRE(!ISC_LINK_LINKED(fctx, link)); FCTXTRACE("destroy"); /* * Free bad. */ for (sa = ISC_LIST_HEAD(fctx->bad); sa != NULL; sa = next_sa) { next_sa = ISC_LIST_NEXT(sa, link); ISC_LIST_UNLINK(fctx->bad, sa, link); isc_mem_put(fctx->mctx, sa, sizeof(*sa)); } for (tried = ISC_LIST_HEAD(fctx->edns); tried != NULL; tried = ISC_LIST_HEAD(fctx->edns)) { ISC_LIST_UNLINK(fctx->edns, tried, link); isc_mem_put(fctx->mctx, tried, sizeof(*tried)); } for (tried = ISC_LIST_HEAD(fctx->edns512); tried != NULL; tried = ISC_LIST_HEAD(fctx->edns512)) { ISC_LIST_UNLINK(fctx->edns512, tried, link); isc_mem_put(fctx->mctx, tried, sizeof(*tried)); } for (sa = ISC_LIST_HEAD(fctx->bad_edns); sa != NULL; sa = next_sa) { next_sa = ISC_LIST_NEXT(sa, link); ISC_LIST_UNLINK(fctx->bad_edns, sa, link); isc_mem_put(fctx->mctx, sa, sizeof(*sa)); } isc_counter_detach(&fctx->qc); #ifdef ENABLE_FETCHLIMIT fcount_decr(fctx); #endif /* ENABLE_FETCHLIMIT */ isc_timer_detach(&fctx->timer); dns_message_destroy(&fctx->rmessage); dns_message_destroy(&fctx->qmessage); if (dns_name_countlabels(&fctx->domain) > 0) dns_name_free(&fctx->domain, fctx->mctx); if (dns_rdataset_isassociated(&fctx->nameservers)) dns_rdataset_disassociate(&fctx->nameservers); dns_name_free(&fctx->name, fctx->mctx); dns_db_detach(&fctx->cache); dns_adb_detach(&fctx->adb); isc_mem_free(fctx->mctx, fctx->info); isc_mem_putanddetach(&fctx->mctx, fctx, sizeof(*fctx)); } /* * Fetch event handlers. */ static void fctx_timeout(isc_task_t *task, isc_event_t *event) { fetchctx_t *fctx = event->ev_arg; isc_timerevent_t *tevent = (isc_timerevent_t *)event; resquery_t *query; REQUIRE(VALID_FCTX(fctx)); UNUSED(task); FCTXTRACE("timeout"); inc_stats(fctx->res, dns_resstatscounter_querytimeout); if (event->ev_type == ISC_TIMEREVENT_LIFE) { fctx->reason = NULL; fctx_done(fctx, ISC_R_TIMEDOUT, __LINE__); } else { isc_result_t result; fctx->timeouts++; fctx->timeout = ISC_TRUE; /* * We could cancel the running queries here, or we could let * them keep going. Since we normally use separate sockets for * different queries, we adopt the former approach to reduce * the number of open sockets: cancel the oldest query if it * expired after the query had started (this is usually the * case but is not always so, depending on the task schedule * timing). */ query = ISC_LIST_HEAD(fctx->queries); if (query != NULL && isc_time_compare(&tevent->due, &query->start) >= 0) { FCTXTRACE("query timed out; no response"); fctx_cancelquery(&query, NULL, NULL, ISC_TRUE); } fctx->attributes &= ~FCTX_ATTR_ADDRWAIT; /* * Our timer has triggered. Reestablish the fctx lifetime * timer. */ result = fctx_starttimer(fctx); if (result != ISC_R_SUCCESS) fctx_done(fctx, result, __LINE__); else /* * Keep trying. */ fctx_try(fctx, ISC_TRUE, ISC_FALSE); } isc_event_free(&event); } static void fctx_shutdown(fetchctx_t *fctx) { isc_event_t *cevent; /* * Start the shutdown process for fctx, if it isn't already underway. */ FCTXTRACE("shutdown"); /* * The caller must be holding the appropriate bucket lock. */ if (fctx->want_shutdown) return; fctx->want_shutdown = ISC_TRUE; /* * Unless we're still initializing (in which case the * control event is still outstanding), we need to post * the control event to tell the fetch we want it to * exit. */ if (fctx->state != fetchstate_init) { cevent = &fctx->control_event; isc_task_send(fctx->res->buckets[fctx->bucketnum].task, &cevent); } } static void fctx_doshutdown(isc_task_t *task, isc_event_t *event) { fetchctx_t *fctx = event->ev_arg; isc_boolean_t bucket_empty = ISC_FALSE; dns_resolver_t *res; unsigned int bucketnum; dns_validator_t *validator; isc_boolean_t dodestroy = ISC_FALSE; REQUIRE(VALID_FCTX(fctx)); UNUSED(task); res = fctx->res; bucketnum = fctx->bucketnum; FCTXTRACE("doshutdown"); /* * An fctx that is shutting down is no longer in ADDRWAIT mode. */ fctx->attributes &= ~FCTX_ATTR_ADDRWAIT; /* * Cancel all pending validators. Note that this must be done * without the bucket lock held, since that could cause deadlock. */ validator = ISC_LIST_HEAD(fctx->validators); while (validator != NULL) { dns_validator_cancel(validator); validator = ISC_LIST_NEXT(validator, link); } if (fctx->nsfetch != NULL) dns_resolver_cancelfetch(fctx->nsfetch); /* * Shut down anything that is still running on behalf of this * fetch. To avoid deadlock with the ADB, we must do this * before we lock the bucket lock. */ fctx_stopeverything(fctx, ISC_FALSE); LOCK(&res->buckets[bucketnum].lock); fctx->attributes |= FCTX_ATTR_SHUTTINGDOWN; INSIST(fctx->state == fetchstate_active || fctx->state == fetchstate_done); INSIST(fctx->want_shutdown); if (fctx->state != fetchstate_done) { fctx->state = fetchstate_done; fctx_sendevents(fctx, ISC_R_CANCELED, __LINE__); } if (fctx->references == 0 && fctx->pending == 0 && fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) { bucket_empty = fctx_unlink(fctx); dodestroy = ISC_TRUE; } UNLOCK(&res->buckets[bucketnum].lock); if (dodestroy) { fctx_destroy(fctx); if (bucket_empty) empty_bucket(res); } } static void fctx_start(isc_task_t *task, isc_event_t *event) { fetchctx_t *fctx = event->ev_arg; isc_boolean_t done = ISC_FALSE, bucket_empty = ISC_FALSE; dns_resolver_t *res; unsigned int bucketnum; isc_boolean_t dodestroy = ISC_FALSE; REQUIRE(VALID_FCTX(fctx)); UNUSED(task); res = fctx->res; bucketnum = fctx->bucketnum; FCTXTRACE("start"); LOCK(&res->buckets[bucketnum].lock); INSIST(fctx->state == fetchstate_init); if (fctx->want_shutdown) { /* * We haven't started this fctx yet, and we've been requested * to shut it down. */ fctx->attributes |= FCTX_ATTR_SHUTTINGDOWN; fctx->state = fetchstate_done; fctx_sendevents(fctx, ISC_R_CANCELED, __LINE__); /* * Since we haven't started, we INSIST that we have no * pending ADB finds and no pending validations. */ INSIST(fctx->pending == 0); INSIST(fctx->nqueries == 0); INSIST(ISC_LIST_EMPTY(fctx->validators)); if (fctx->references == 0) { /* * It's now safe to destroy this fctx. */ bucket_empty = fctx_unlink(fctx); dodestroy = ISC_TRUE; } done = ISC_TRUE; } else { /* * Normal fctx startup. */ fctx->state = fetchstate_active; /* * Reset the control event for later use in shutting down * the fctx. */ ISC_EVENT_INIT(event, sizeof(*event), 0, NULL, DNS_EVENT_FETCHCONTROL, fctx_doshutdown, fctx, NULL, NULL, NULL); } UNLOCK(&res->buckets[bucketnum].lock); if (!done) { isc_result_t result; INSIST(!dodestroy); /* * All is well. Start working on the fetch. */ result = fctx_starttimer(fctx); if (result != ISC_R_SUCCESS) fctx_done(fctx, result, __LINE__); else fctx_try(fctx, ISC_FALSE, ISC_FALSE); } else if (dodestroy) { fctx_destroy(fctx); if (bucket_empty) empty_bucket(res); } } /* * Fetch Creation, Joining, and Cancelation. */ static inline isc_result_t fctx_join(fetchctx_t *fctx, isc_task_t *task, isc_sockaddr_t *client, dns_messageid_t id, isc_taskaction_t action, void *arg, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, dns_fetch_t *fetch) { isc_task_t *clone; dns_fetchevent_t *event; FCTXTRACE("join"); /* * We store the task we're going to send this event to in the * sender field. We'll make the fetch the sender when we actually * send the event. */ clone = NULL; isc_task_attach(task, &clone); event = (dns_fetchevent_t *) isc_event_allocate(fctx->res->mctx, clone, DNS_EVENT_FETCHDONE, action, arg, sizeof(*event)); if (event == NULL) { isc_task_detach(&clone); return (ISC_R_NOMEMORY); } event->result = DNS_R_SERVFAIL; event->qtype = fctx->type; event->db = NULL; event->node = NULL; event->rdataset = rdataset; event->sigrdataset = sigrdataset; event->fetch = fetch; event->client = client; event->id = id; dns_fixedname_init(&event->foundname); /* * Make sure that we can store the sigrdataset in the * first event if it is needed by any of the events. */ if (event->sigrdataset != NULL) ISC_LIST_PREPEND(fctx->events, event, ev_link); else ISC_LIST_APPEND(fctx->events, event, ev_link); fctx->references++; fctx->client = client; fetch->magic = DNS_FETCH_MAGIC; fetch->private = fctx; return (ISC_R_SUCCESS); } static inline void log_ns_ttl(fetchctx_t *fctx, const char *where) { char namebuf[DNS_NAME_FORMATSIZE]; char domainbuf[DNS_NAME_FORMATSIZE]; dns_name_format(&fctx->name, namebuf, sizeof(namebuf)); dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(10), "log_ns_ttl: fctx %p: %s: %s (in '%s'?): %u %u", fctx, where, namebuf, domainbuf, fctx->ns_ttl_ok, fctx->ns_ttl); } static isc_result_t fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, dns_name_t *domain, dns_rdataset_t *nameservers, unsigned int options, unsigned int bucketnum, unsigned int depth, isc_counter_t *qc, fetchctx_t **fctxp) { fetchctx_t *fctx; isc_result_t result; isc_result_t iresult; isc_interval_t interval; dns_fixedname_t fixed; unsigned int findoptions = 0; char buf[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE]; char typebuf[DNS_RDATATYPE_FORMATSIZE]; isc_mem_t *mctx; /* * Caller must be holding the lock for bucket number 'bucketnum'. */ REQUIRE(fctxp != NULL && *fctxp == NULL); mctx = res->buckets[bucketnum].mctx; fctx = isc_mem_get(mctx, sizeof(*fctx)); if (fctx == NULL) return (ISC_R_NOMEMORY); fctx->qc = NULL; if (qc != NULL) { isc_counter_attach(qc, &fctx->qc); } else { result = isc_counter_create(res->mctx, res->maxqueries, &fctx->qc); if (result != ISC_R_SUCCESS) goto cleanup_fetch; } /* * Make fctx->info point to a copy of a formatted string * "name/type". */ dns_name_format(name, buf, sizeof(buf)); dns_rdatatype_format(type, typebuf, sizeof(typebuf)); strcat(buf, "/"); /* checked */ strcat(buf, typebuf); /* checked */ fctx->info = isc_mem_strdup(mctx, buf); if (fctx->info == NULL) { result = ISC_R_NOMEMORY; goto cleanup_counter; } FCTXTRACE("create"); dns_name_init(&fctx->name, NULL); result = dns_name_dup(name, mctx, &fctx->name); if (result != ISC_R_SUCCESS) goto cleanup_info; dns_name_init(&fctx->domain, NULL); dns_rdataset_init(&fctx->nameservers); fctx->type = type; fctx->options = options; /* * Note! We do not attach to the task. We are relying on the * resolver to ensure that this task doesn't go away while we are * using it. */ fctx->res = res; fctx->references = 0; fctx->bucketnum = bucketnum; fctx->dbucketnum = RES_NOBUCKET; fctx->state = fetchstate_init; fctx->want_shutdown = ISC_FALSE; fctx->cloned = ISC_FALSE; fctx->depth = depth; ISC_LIST_INIT(fctx->queries); ISC_LIST_INIT(fctx->finds); ISC_LIST_INIT(fctx->altfinds); ISC_LIST_INIT(fctx->forwaddrs); ISC_LIST_INIT(fctx->altaddrs); ISC_LIST_INIT(fctx->forwarders); fctx->fwdpolicy = dns_fwdpolicy_none; ISC_LIST_INIT(fctx->bad); ISC_LIST_INIT(fctx->edns); ISC_LIST_INIT(fctx->edns512); ISC_LIST_INIT(fctx->bad_edns); ISC_LIST_INIT(fctx->validators); fctx->validator = NULL; fctx->find = NULL; fctx->altfind = NULL; fctx->pending = 0; fctx->restarts = 0; fctx->querysent = 0; fctx->referrals = 0; TIME_NOW(&fctx->start); fctx->timeouts = 0; fctx->lamecount = 0; fctx->quotacount = 0; fctx->adberr = 0; fctx->neterr = 0; fctx->badresp = 0; fctx->findfail = 0; fctx->valfail = 0; fctx->result = ISC_R_FAILURE; fctx->vresult = ISC_R_SUCCESS; fctx->exitline = -1; /* sentinel */ fctx->logged = ISC_FALSE; fctx->attributes = 0; fctx->spilled = ISC_FALSE; fctx->nqueries = 0; fctx->reason = NULL; fctx->rand_buf = 0; fctx->rand_bits = 0; fctx->timeout = ISC_FALSE; fctx->addrinfo = NULL; fctx->client = NULL; fctx->ns_ttl = 0; fctx->ns_ttl_ok = ISC_FALSE; dns_name_init(&fctx->nsname, NULL); fctx->nsfetch = NULL; dns_rdataset_init(&fctx->nsrrset); if (domain == NULL) { dns_forwarders_t *forwarders = NULL; unsigned int labels; dns_name_t *fwdname = name; dns_name_t suffix; /* * DS records are found in the parent server. Strip one * leading label from the name (to be used in finding * the forwarder). */ if (dns_rdatatype_atparent(fctx->type) && dns_name_countlabels(name) > 1) { dns_name_init(&suffix, NULL); labels = dns_name_countlabels(name); dns_name_getlabelsequence(name, 1, labels - 1, &suffix); fwdname = &suffix; } /* Find the forwarder for this name. */ dns_fixedname_init(&fixed); domain = dns_fixedname_name(&fixed); result = dns_fwdtable_find2(fctx->res->view->fwdtable, fwdname, domain, &forwarders); if (result == ISC_R_SUCCESS) fctx->fwdpolicy = forwarders->fwdpolicy; if (fctx->fwdpolicy != dns_fwdpolicy_only) { /* * The caller didn't supply a query domain and * nameservers, and we're not in forward-only mode, * so find the best nameservers to use. */ if (dns_rdatatype_atparent(fctx->type)) findoptions |= DNS_DBFIND_NOEXACT; result = dns_view_findzonecut(res->view, name, domain, 0, findoptions, ISC_TRUE, &fctx->nameservers, NULL); if (result != ISC_R_SUCCESS) goto cleanup_name; result = dns_name_dup(domain, mctx, &fctx->domain); if (result != ISC_R_SUCCESS) { dns_rdataset_disassociate(&fctx->nameservers); goto cleanup_name; } fctx->ns_ttl = fctx->nameservers.ttl; fctx->ns_ttl_ok = ISC_TRUE; } else { /* * We're in forward-only mode. Set the query domain. */ result = dns_name_dup(domain, mctx, &fctx->domain); if (result != ISC_R_SUCCESS) goto cleanup_name; } } else { result = dns_name_dup(domain, mctx, &fctx->domain); if (result != ISC_R_SUCCESS) goto cleanup_name; dns_rdataset_clone(nameservers, &fctx->nameservers); fctx->ns_ttl = fctx->nameservers.ttl; fctx->ns_ttl_ok = ISC_TRUE; } #ifdef ENABLE_FETCHLIMIT /* * Are there too many simultaneous queries for this domain? */ result = fcount_incr(fctx, ISC_FALSE); if (result != ISC_R_SUCCESS) { result = fctx->res->quotaresp[dns_quotatype_zone]; inc_stats(res, dns_resstatscounter_zonequota); goto cleanup_domain; } #endif /* ENABLE_FETCHLIMIT */ log_ns_ttl(fctx, "fctx_create"); INSIST(dns_name_issubdomain(&fctx->name, &fctx->domain)); fctx->qmessage = NULL; result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &fctx->qmessage); if (result != ISC_R_SUCCESS) #ifdef ENABLE_FETCHLIMIT goto cleanup_fcount; #else goto cleanup_domain; #endif /* !ENABLE_FETCHLIMIT */ fctx->rmessage = NULL; result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &fctx->rmessage); if (result != ISC_R_SUCCESS) goto cleanup_qmessage; /* * Compute an expiration time for the entire fetch. */ isc_interval_set(&interval, res->query_timeout, 0); iresult = isc_time_nowplusinterval(&fctx->expires, &interval); if (iresult != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_time_nowplusinterval: %s", isc_result_totext(iresult)); result = ISC_R_UNEXPECTED; goto cleanup_rmessage; } /* * Default retry interval initialization. We set the interval now * mostly so it won't be uninitialized. It will be set to the * correct value before a query is issued. */ isc_interval_set(&fctx->interval, 2, 0); /* * Create an inactive timer. It will be made active when the fetch * is actually started. */ fctx->timer = NULL; iresult = isc_timer_create(res->timermgr, isc_timertype_inactive, NULL, NULL, res->buckets[bucketnum].task, fctx_timeout, fctx, &fctx->timer); if (iresult != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_timer_create: %s", isc_result_totext(iresult)); result = ISC_R_UNEXPECTED; goto cleanup_rmessage; } /* * Attach to the view's cache and adb. */ fctx->cache = NULL; dns_db_attach(res->view->cachedb, &fctx->cache); fctx->adb = NULL; dns_adb_attach(res->view->adb, &fctx->adb); fctx->mctx = NULL; isc_mem_attach(mctx, &fctx->mctx); ISC_LIST_INIT(fctx->events); ISC_LINK_INIT(fctx, link); fctx->magic = FCTX_MAGIC; ISC_LIST_APPEND(res->buckets[bucketnum].fctxs, fctx, link); LOCK(&res->nlock); res->nfctx++; UNLOCK(&res->nlock); inc_stats(res, dns_resstatscounter_nfetch); *fctxp = fctx; return (ISC_R_SUCCESS); cleanup_rmessage: dns_message_destroy(&fctx->rmessage); cleanup_qmessage: dns_message_destroy(&fctx->qmessage); #ifdef ENABLE_FETCHLIMIT cleanup_fcount: fcount_decr(fctx); #endif /* ENABLE_FETCHLIMIT */ cleanup_domain: if (dns_name_countlabels(&fctx->domain) > 0) dns_name_free(&fctx->domain, mctx); if (dns_rdataset_isassociated(&fctx->nameservers)) dns_rdataset_disassociate(&fctx->nameservers); cleanup_name: dns_name_free(&fctx->name, mctx); cleanup_info: isc_mem_free(mctx, fctx->info); cleanup_counter: isc_counter_detach(&fctx->qc); cleanup_fetch: isc_mem_put(mctx, fctx, sizeof(*fctx)); return (result); } /* * Handle Responses */ static inline isc_boolean_t is_lame(fetchctx_t *fctx) { dns_message_t *message = fctx->rmessage; dns_name_t *name; dns_rdataset_t *rdataset; isc_result_t result; if (message->rcode != dns_rcode_noerror && message->rcode != dns_rcode_nxdomain) return (ISC_FALSE); if (message->counts[DNS_SECTION_ANSWER] != 0) return (ISC_FALSE); if (message->counts[DNS_SECTION_AUTHORITY] == 0) return (ISC_FALSE); result = dns_message_firstname(message, DNS_SECTION_AUTHORITY); while (result == ISC_R_SUCCESS) { name = NULL; dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name); for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { dns_namereln_t namereln; int order; unsigned int labels; if (rdataset->type != dns_rdatatype_ns) continue; namereln = dns_name_fullcompare(name, &fctx->domain, &order, &labels); if (namereln == dns_namereln_equal && (message->flags & DNS_MESSAGEFLAG_AA) != 0) return (ISC_FALSE); if (namereln == dns_namereln_subdomain) return (ISC_FALSE); return (ISC_TRUE); } result = dns_message_nextname(message, DNS_SECTION_AUTHORITY); } return (ISC_FALSE); } static inline void log_lame(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo) { char namebuf[DNS_NAME_FORMATSIZE]; char domainbuf[DNS_NAME_FORMATSIZE]; char addrbuf[ISC_SOCKADDR_FORMATSIZE]; dns_name_format(&fctx->name, namebuf, sizeof(namebuf)); dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf)); isc_sockaddr_format(&addrinfo->sockaddr, addrbuf, sizeof(addrbuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_LAME_SERVERS, DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, "lame server resolving '%s' (in '%s'?): %s", namebuf, domainbuf, addrbuf); } static inline void log_formerr(fetchctx_t *fctx, const char *format, ...) { char nsbuf[ISC_SOCKADDR_FORMATSIZE]; char clbuf[ISC_SOCKADDR_FORMATSIZE]; const char *clmsg = ""; char msgbuf[2048]; va_list args; va_start(args, format); vsnprintf(msgbuf, sizeof(msgbuf), format, args); va_end(args); isc_sockaddr_format(&fctx->addrinfo->sockaddr, nsbuf, sizeof(nsbuf)); if (fctx->client != NULL) { clmsg = " for client "; isc_sockaddr_format(fctx->client, clbuf, sizeof(clbuf)); } else { clbuf[0] = '\0'; } isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, "DNS format error from %s resolving %s%s%s: %s", nsbuf, fctx->info, clmsg, clbuf, msgbuf); } static inline isc_result_t same_question(fetchctx_t *fctx) { isc_result_t result; dns_message_t *message = fctx->rmessage; dns_name_t *name; dns_rdataset_t *rdataset; /* * Caller must be holding the fctx lock. */ /* * XXXRTH Currently we support only one question. */ if (message->counts[DNS_SECTION_QUESTION] != 1) { log_formerr(fctx, "too many questions"); return (DNS_R_FORMERR); } result = dns_message_firstname(message, DNS_SECTION_QUESTION); if (result != ISC_R_SUCCESS) return (result); name = NULL; dns_message_currentname(message, DNS_SECTION_QUESTION, &name); rdataset = ISC_LIST_HEAD(name->list); INSIST(rdataset != NULL); INSIST(ISC_LIST_NEXT(rdataset, link) == NULL); if (fctx->type != rdataset->type || fctx->res->rdclass != rdataset->rdclass || !dns_name_equal(&fctx->name, name)) { char namebuf[DNS_NAME_FORMATSIZE]; char class[DNS_RDATACLASS_FORMATSIZE]; char type[DNS_RDATATYPE_FORMATSIZE]; dns_name_format(name, namebuf, sizeof(namebuf)); dns_rdataclass_format(rdataset->rdclass, class, sizeof(class)); dns_rdatatype_format(rdataset->type, type, sizeof(type)); log_formerr(fctx, "question section mismatch: got %s/%s/%s", namebuf, class, type); return (DNS_R_FORMERR); } return (ISC_R_SUCCESS); } static void clone_results(fetchctx_t *fctx) { dns_fetchevent_t *event, *hevent; isc_result_t result; dns_name_t *name, *hname; FCTXTRACE("clone_results"); /* * Set up any other events to have the same data as the first * event. * * Caller must be holding the appropriate lock. */ fctx->cloned = ISC_TRUE; hevent = ISC_LIST_HEAD(fctx->events); if (hevent == NULL) return; hname = dns_fixedname_name(&hevent->foundname); for (event = ISC_LIST_NEXT(hevent, ev_link); event != NULL; event = ISC_LIST_NEXT(event, ev_link)) { name = dns_fixedname_name(&event->foundname); result = dns_name_copy(hname, name, NULL); if (result != ISC_R_SUCCESS) event->result = result; else event->result = hevent->result; dns_db_attach(hevent->db, &event->db); dns_db_attachnode(hevent->db, hevent->node, &event->node); INSIST(hevent->rdataset != NULL); INSIST(event->rdataset != NULL); if (dns_rdataset_isassociated(hevent->rdataset)) dns_rdataset_clone(hevent->rdataset, event->rdataset); INSIST(! (hevent->sigrdataset == NULL && event->sigrdataset != NULL)); if (hevent->sigrdataset != NULL && dns_rdataset_isassociated(hevent->sigrdataset) && event->sigrdataset != NULL) dns_rdataset_clone(hevent->sigrdataset, event->sigrdataset); } } #define CACHE(r) (((r)->attributes & DNS_RDATASETATTR_CACHE) != 0) #define ANSWER(r) (((r)->attributes & DNS_RDATASETATTR_ANSWER) != 0) #define ANSWERSIG(r) (((r)->attributes & DNS_RDATASETATTR_ANSWERSIG) != 0) #define EXTERNAL(r) (((r)->attributes & DNS_RDATASETATTR_EXTERNAL) != 0) #define CHAINING(r) (((r)->attributes & DNS_RDATASETATTR_CHAINING) != 0) #define CHASE(r) (((r)->attributes & DNS_RDATASETATTR_CHASE) != 0) #define CHECKNAMES(r) (((r)->attributes & DNS_RDATASETATTR_CHECKNAMES) != 0) /* * Destroy '*fctx' if it is ready to be destroyed (i.e., if it has * no references and is no longer waiting for any events). * * Requires: * '*fctx' is shutting down. * * Returns: * true if the resolver is exiting and this is the last fctx in the bucket. */ static isc_boolean_t maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked) { unsigned int bucketnum; isc_boolean_t bucket_empty = ISC_FALSE; dns_resolver_t *res = fctx->res; dns_validator_t *validator, *next_validator; isc_boolean_t dodestroy = ISC_FALSE; REQUIRE(SHUTTINGDOWN(fctx)); bucketnum = fctx->bucketnum; if (!locked) LOCK(&res->buckets[bucketnum].lock); if (fctx->pending != 0 || fctx->nqueries != 0) goto unlock; for (validator = ISC_LIST_HEAD(fctx->validators); validator != NULL; validator = next_validator) { next_validator = ISC_LIST_NEXT(validator, link); dns_validator_cancel(validator); } if (fctx->references == 0 && ISC_LIST_EMPTY(fctx->validators)) { bucket_empty = fctx_unlink(fctx); dodestroy = ISC_TRUE; } unlock: if (!locked) UNLOCK(&res->buckets[bucketnum].lock); if (dodestroy) fctx_destroy(fctx); return (bucket_empty); } /* * The validator has finished. */ static void validated(isc_task_t *task, isc_event_t *event) { dns_adbaddrinfo_t *addrinfo; dns_dbnode_t *node = NULL; dns_dbnode_t *nsnode = NULL; dns_fetchevent_t *hevent; dns_name_t *name; dns_rdataset_t *ardataset = NULL; dns_rdataset_t *asigrdataset = NULL; dns_rdataset_t *rdataset; dns_rdataset_t *sigrdataset; dns_resolver_t *res; dns_valarg_t *valarg; dns_validatorevent_t *vevent; fetchctx_t *fctx; isc_boolean_t chaining; isc_boolean_t negative; isc_boolean_t sentresponse; isc_result_t eresult = ISC_R_SUCCESS; isc_result_t result = ISC_R_SUCCESS; isc_stdtime_t now; isc_uint32_t ttl; unsigned options; isc_uint32_t bucketnum; UNUSED(task); /* for now */ REQUIRE(event->ev_type == DNS_EVENT_VALIDATORDONE); valarg = event->ev_arg; fctx = valarg->fctx; res = fctx->res; addrinfo = valarg->addrinfo; REQUIRE(VALID_FCTX(fctx)); REQUIRE(!ISC_LIST_EMPTY(fctx->validators)); vevent = (dns_validatorevent_t *)event; fctx->vresult = vevent->result; FCTXTRACE("received validation completion event"); bucketnum = fctx->bucketnum; LOCK(&res->buckets[bucketnum].lock); ISC_LIST_UNLINK(fctx->validators, vevent->validator, link); fctx->validator = NULL; /* * Destroy the validator early so that we can * destroy the fctx if necessary. */ dns_validator_destroy(&vevent->validator); isc_mem_put(fctx->mctx, valarg, sizeof(*valarg)); negative = ISC_TF(vevent->rdataset == NULL); sentresponse = ISC_TF((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0); /* * If shutting down, ignore the results. Check to see if we're * done waiting for validator completions and ADB pending events; if * so, destroy the fctx. */ if (SHUTTINGDOWN(fctx) && !sentresponse) { isc_boolean_t bucket_empty; bucket_empty = maybe_destroy(fctx, ISC_TRUE); UNLOCK(&res->buckets[bucketnum].lock); if (bucket_empty) empty_bucket(res); goto cleanup_event; } isc_stdtime_get(&now); /* * If chaining, we need to make sure that the right result code is * returned, and that the rdatasets are bound. */ if (vevent->result == ISC_R_SUCCESS && !negative && vevent->rdataset != NULL && CHAINING(vevent->rdataset)) { if (vevent->rdataset->type == dns_rdatatype_cname) eresult = DNS_R_CNAME; else { INSIST(vevent->rdataset->type == dns_rdatatype_dname); eresult = DNS_R_DNAME; } chaining = ISC_TRUE; } else chaining = ISC_FALSE; /* * Either we're not shutting down, or we are shutting down but want * to cache the result anyway (if this was a validation started by * a query with cd set) */ hevent = ISC_LIST_HEAD(fctx->events); if (hevent != NULL) { if (!negative && !chaining && (fctx->type == dns_rdatatype_any || fctx->type == dns_rdatatype_rrsig || fctx->type == dns_rdatatype_sig)) { /* * Don't bind rdatasets; the caller * will iterate the node. */ } else { ardataset = hevent->rdataset; asigrdataset = hevent->sigrdataset; } } if (vevent->result != ISC_R_SUCCESS) { FCTXTRACE("validation failed"); inc_stats(res, dns_resstatscounter_valfail); fctx->valfail++; fctx->vresult = vevent->result; if (fctx->vresult != DNS_R_BROKENCHAIN) { result = ISC_R_NOTFOUND; if (vevent->rdataset != NULL) result = dns_db_findnode(fctx->cache, vevent->name, ISC_TRUE, &node); if (result == ISC_R_SUCCESS) (void)dns_db_deleterdataset(fctx->cache, node, NULL, vevent->type, 0); if (result == ISC_R_SUCCESS && vevent->sigrdataset != NULL) (void)dns_db_deleterdataset(fctx->cache, node, NULL, dns_rdatatype_rrsig, vevent->type); if (result == ISC_R_SUCCESS) dns_db_detachnode(fctx->cache, &node); } if (fctx->vresult == DNS_R_BROKENCHAIN && !negative) { /* * Cache the data as pending for later validation. */ result = ISC_R_NOTFOUND; if (vevent->rdataset != NULL) result = dns_db_findnode(fctx->cache, vevent->name, ISC_TRUE, &node); if (result == ISC_R_SUCCESS) { (void)dns_db_addrdataset(fctx->cache, node, NULL, now, vevent->rdataset, 0, NULL); } if (result == ISC_R_SUCCESS && vevent->sigrdataset != NULL) (void)dns_db_addrdataset(fctx->cache, node, NULL, now, vevent->sigrdataset, 0, NULL); if (result == ISC_R_SUCCESS) dns_db_detachnode(fctx->cache, &node); } result = fctx->vresult; add_bad(fctx, addrinfo, result, badns_validation); isc_event_free(&event); UNLOCK(&res->buckets[bucketnum].lock); INSIST(fctx->validator == NULL); fctx->validator = ISC_LIST_HEAD(fctx->validators); if (fctx->validator != NULL) dns_validator_send(fctx->validator); else if (sentresponse) fctx_done(fctx, result, __LINE__); /* Locks bucket. */ else if (result == DNS_R_BROKENCHAIN) { isc_result_t tresult; isc_time_t expire; isc_interval_t i; isc_interval_set(&i, DNS_BADCACHE_TTL(fctx), 0); tresult = isc_time_nowplusinterval(&expire, &i); if (negative && (fctx->type == dns_rdatatype_dnskey || fctx->type == dns_rdatatype_dlv || fctx->type == dns_rdatatype_ds) && tresult == ISC_R_SUCCESS) dns_resolver_addbadcache(res, &fctx->name, fctx->type, &expire); fctx_done(fctx, result, __LINE__); /* Locks bucket. */ } else fctx_try(fctx, ISC_TRUE, ISC_TRUE); /* Locks bucket. */ return; } if (negative) { dns_rdatatype_t covers; FCTXTRACE("nonexistence validation OK"); inc_stats(res, dns_resstatscounter_valnegsuccess); /* * Cache DS NXDOMAIN seperately to other types. */ if (fctx->rmessage->rcode == dns_rcode_nxdomain && fctx->type != dns_rdatatype_ds) covers = dns_rdatatype_any; else covers = fctx->type; result = dns_db_findnode(fctx->cache, vevent->name, ISC_TRUE, &node); if (result != ISC_R_SUCCESS) goto noanswer_response; /* * If we are asking for a SOA record set the cache time * to zero to facilitate locating the containing zone of * a arbitrary zone. */ ttl = res->view->maxncachettl; if (fctx->type == dns_rdatatype_soa && covers == dns_rdatatype_any && res->zero_no_soa_ttl) ttl = 0; result = ncache_adderesult(fctx->rmessage, fctx->cache, node, covers, now, ttl, vevent->optout, vevent->secure, ardataset, &eresult); if (result != ISC_R_SUCCESS) goto noanswer_response; goto answer_response; } else inc_stats(res, dns_resstatscounter_valsuccess); FCTXTRACE("validation OK"); if (vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF] != NULL) { result = dns_rdataset_addnoqname(vevent->rdataset, vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF]); RUNTIME_CHECK(result == ISC_R_SUCCESS); INSIST(vevent->sigrdataset != NULL); vevent->sigrdataset->ttl = vevent->rdataset->ttl; if (vevent->proofs[DNS_VALIDATOR_CLOSESTENCLOSER] != NULL) { result = dns_rdataset_addclosest(vevent->rdataset, vevent->proofs[DNS_VALIDATOR_CLOSESTENCLOSER]); RUNTIME_CHECK(result == ISC_R_SUCCESS); } } else if (vevent->rdataset->trust == dns_trust_answer && vevent->rdataset->type != dns_rdatatype_rrsig) { isc_result_t tresult; dns_name_t *noqname = NULL; tresult = findnoqname(fctx, vevent->name, vevent->rdataset->type, &noqname); if (tresult == ISC_R_SUCCESS && noqname != NULL) { tresult = dns_rdataset_addnoqname(vevent->rdataset, noqname); RUNTIME_CHECK(tresult == ISC_R_SUCCESS); } } /* * The data was already cached as pending data. * Re-cache it as secure and bind the cached * rdatasets to the first event on the fetch * event list. */ result = dns_db_findnode(fctx->cache, vevent->name, ISC_TRUE, &node); if (result != ISC_R_SUCCESS) goto noanswer_response; options = 0; if ((fctx->options & DNS_FETCHOPT_PREFETCH) != 0) options = DNS_DBADD_PREFETCH; result = dns_db_addrdataset(fctx->cache, node, NULL, now, vevent->rdataset, options, ardataset); if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED) goto noanswer_response; if (ardataset != NULL && NEGATIVE(ardataset)) { if (NXDOMAIN(ardataset)) eresult = DNS_R_NCACHENXDOMAIN; else eresult = DNS_R_NCACHENXRRSET; } else if (vevent->sigrdataset != NULL) { result = dns_db_addrdataset(fctx->cache, node, NULL, now, vevent->sigrdataset, 0, asigrdataset); if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED) goto noanswer_response; } if (sentresponse) { isc_boolean_t bucket_empty = ISC_FALSE; /* * If we only deferred the destroy because we wanted to cache * the data, destroy now. */ dns_db_detachnode(fctx->cache, &node); if (SHUTTINGDOWN(fctx)) bucket_empty = maybe_destroy(fctx, ISC_TRUE); UNLOCK(&res->buckets[bucketnum].lock); if (bucket_empty) empty_bucket(res); goto cleanup_event; } if (!ISC_LIST_EMPTY(fctx->validators)) { INSIST(!negative); INSIST(fctx->type == dns_rdatatype_any || fctx->type == dns_rdatatype_rrsig || fctx->type == dns_rdatatype_sig); /* * Don't send a response yet - we have * more rdatasets that still need to * be validated. */ dns_db_detachnode(fctx->cache, &node); UNLOCK(&res->buckets[bucketnum].lock); dns_validator_send(ISC_LIST_HEAD(fctx->validators)); goto cleanup_event; } answer_response: /* * Cache any NS/NSEC records that happened to be validated. */ result = dns_message_firstname(fctx->rmessage, DNS_SECTION_AUTHORITY); while (result == ISC_R_SUCCESS) { name = NULL; dns_message_currentname(fctx->rmessage, DNS_SECTION_AUTHORITY, &name); for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if ((rdataset->type != dns_rdatatype_ns && rdataset->type != dns_rdatatype_nsec) || rdataset->trust != dns_trust_secure) continue; for (sigrdataset = ISC_LIST_HEAD(name->list); sigrdataset != NULL; sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) { if (sigrdataset->type != dns_rdatatype_rrsig || sigrdataset->covers != rdataset->type) continue; break; } if (sigrdataset == NULL || sigrdataset->trust != dns_trust_secure) continue; result = dns_db_findnode(fctx->cache, name, ISC_TRUE, &nsnode); if (result != ISC_R_SUCCESS) continue; result = dns_db_addrdataset(fctx->cache, nsnode, NULL, now, rdataset, 0, NULL); if (result == ISC_R_SUCCESS) result = dns_db_addrdataset(fctx->cache, nsnode, NULL, now, sigrdataset, 0, NULL); dns_db_detachnode(fctx->cache, &nsnode); if (result != ISC_R_SUCCESS) continue; } result = dns_message_nextname(fctx->rmessage, DNS_SECTION_AUTHORITY); } result = ISC_R_SUCCESS; /* * Respond with an answer, positive or negative, * as opposed to an error. 'node' must be non-NULL. */ fctx->attributes |= FCTX_ATTR_HAVEANSWER; if (hevent != NULL) { /* * Negative results must be indicated in event->result. */ if (dns_rdataset_isassociated(hevent->rdataset) && NEGATIVE(hevent->rdataset)) { INSIST(eresult == DNS_R_NCACHENXDOMAIN || eresult == DNS_R_NCACHENXRRSET); } hevent->result = eresult; RUNTIME_CHECK(dns_name_copy(vevent->name, dns_fixedname_name(&hevent->foundname), NULL) == ISC_R_SUCCESS); dns_db_attach(fctx->cache, &hevent->db); dns_db_transfernode(fctx->cache, &node, &hevent->node); clone_results(fctx); } noanswer_response: if (node != NULL) dns_db_detachnode(fctx->cache, &node); UNLOCK(&res->buckets[bucketnum].lock); fctx_done(fctx, result, __LINE__); /* Locks bucket. */ cleanup_event: INSIST(node == NULL); isc_event_free(&event); } static void fctx_log(void *arg, int level, const char *fmt, ...) { char msgbuf[2048]; va_list args; fetchctx_t *fctx = arg; va_start(args, fmt); vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); va_end(args); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, level, "fctx %p(%s): %s", fctx, fctx->info, msgbuf); } static inline isc_result_t findnoqname(fetchctx_t *fctx, dns_name_t *name, dns_rdatatype_t type, dns_name_t **noqnamep) { dns_rdataset_t *nrdataset, *next, *sigrdataset; dns_rdata_rrsig_t rrsig; isc_result_t result; unsigned int labels; dns_section_t section; dns_name_t *zonename; dns_fixedname_t fzonename; dns_name_t *closest; dns_fixedname_t fclosest; dns_name_t *nearest; dns_fixedname_t fnearest; dns_rdatatype_t found = dns_rdatatype_none; dns_name_t *noqname = NULL; FCTXTRACE("findnoqname"); REQUIRE(noqnamep != NULL && *noqnamep == NULL); /* * Find the SIG for this rdataset, if we have it. */ for (sigrdataset = ISC_LIST_HEAD(name->list); sigrdataset != NULL; sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) { if (sigrdataset->type == dns_rdatatype_rrsig && sigrdataset->covers == type) break; } if (sigrdataset == NULL) return (ISC_R_NOTFOUND); labels = dns_name_countlabels(name); for (result = dns_rdataset_first(sigrdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(sigrdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(sigrdataset, &rdata); result = dns_rdata_tostruct(&rdata, &rrsig, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); /* Wildcard has rrsig.labels < labels - 1. */ if (rrsig.labels + 1U >= labels) continue; break; } if (result == ISC_R_NOMORE) return (ISC_R_NOTFOUND); if (result != ISC_R_SUCCESS) return (result); dns_fixedname_init(&fzonename); zonename = dns_fixedname_name(&fzonename); dns_fixedname_init(&fclosest); closest = dns_fixedname_name(&fclosest); dns_fixedname_init(&fnearest); nearest = dns_fixedname_name(&fnearest); #define NXND(x) ((x) == ISC_R_SUCCESS) section = DNS_SECTION_AUTHORITY; for (result = dns_message_firstname(fctx->rmessage, section); result == ISC_R_SUCCESS; result = dns_message_nextname(fctx->rmessage, section)) { dns_name_t *nsec = NULL; dns_message_currentname(fctx->rmessage, section, &nsec); for (nrdataset = ISC_LIST_HEAD(nsec->list); nrdataset != NULL; nrdataset = next) { isc_boolean_t data = ISC_FALSE, exists = ISC_FALSE; isc_boolean_t optout = ISC_FALSE, unknown = ISC_FALSE; isc_boolean_t setclosest = ISC_FALSE; isc_boolean_t setnearest = ISC_FALSE; next = ISC_LIST_NEXT(nrdataset, link); if (nrdataset->type != dns_rdatatype_nsec && nrdataset->type != dns_rdatatype_nsec3) continue; if (nrdataset->type == dns_rdatatype_nsec && NXND(dns_nsec_noexistnodata(type, name, nsec, nrdataset, &exists, &data, NULL, fctx_log, fctx))) { if (!exists) { noqname = nsec; found = dns_rdatatype_nsec; } } if (nrdataset->type == dns_rdatatype_nsec3 && NXND(dns_nsec3_noexistnodata(type, name, nsec, nrdataset, zonename, &exists, &data, &optout, &unknown, &setclosest, &setnearest, closest, nearest, fctx_log, fctx))) { if (!exists && setnearest) { noqname = nsec; found = dns_rdatatype_nsec3; } } } } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; if (noqname != NULL) { for (sigrdataset = ISC_LIST_HEAD(noqname->list); sigrdataset != NULL; sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) { if (sigrdataset->type == dns_rdatatype_rrsig && sigrdataset->covers == found) break; } if (sigrdataset != NULL) *noqnamep = noqname; } return (result); } static inline isc_result_t cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, isc_stdtime_t now) { dns_rdataset_t *rdataset, *sigrdataset; dns_rdataset_t *addedrdataset, *ardataset, *asigrdataset; dns_rdataset_t *valrdataset = NULL, *valsigrdataset = NULL; dns_dbnode_t *node, **anodep; dns_db_t **adbp; dns_name_t *aname; dns_resolver_t *res; isc_boolean_t need_validation, secure_domain, have_answer; isc_result_t result, eresult; dns_fetchevent_t *event; unsigned int options; isc_task_t *task; isc_boolean_t fail; unsigned int valoptions = 0; /* * The appropriate bucket lock must be held. */ res = fctx->res; need_validation = ISC_FALSE; POST(need_validation); secure_domain = ISC_FALSE; have_answer = ISC_FALSE; eresult = ISC_R_SUCCESS; task = res->buckets[fctx->bucketnum].task; /* * Is DNSSEC validation required for this name? */ if (res->view->enablevalidation) { result = dns_view_issecuredomain(res->view, name, &secure_domain); if (result != ISC_R_SUCCESS) return (result); if (!secure_domain && res->view->dlv != NULL) { valoptions = DNS_VALIDATOR_DLV; secure_domain = ISC_TRUE; } } if ((fctx->options & DNS_FETCHOPT_NOCDFLAG) != 0) valoptions |= DNS_VALIDATOR_NOCDFLAG; if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0) need_validation = ISC_FALSE; else need_validation = secure_domain; adbp = NULL; aname = NULL; anodep = NULL; ardataset = NULL; asigrdataset = NULL; event = NULL; if ((name->attributes & DNS_NAMEATTR_ANSWER) != 0 && !need_validation) { have_answer = ISC_TRUE; event = ISC_LIST_HEAD(fctx->events); if (event != NULL) { adbp = &event->db; aname = dns_fixedname_name(&event->foundname); result = dns_name_copy(name, aname, NULL); if (result != ISC_R_SUCCESS) return (result); anodep = &event->node; /* * If this is an ANY, SIG or RRSIG query, we're not * going to return any rdatasets, unless we encountered * a CNAME or DNAME as "the answer". In this case, * we're going to return DNS_R_CNAME or DNS_R_DNAME * and we must set up the rdatasets. */ if ((fctx->type != dns_rdatatype_any && fctx->type != dns_rdatatype_rrsig && fctx->type != dns_rdatatype_sig) || (name->attributes & DNS_NAMEATTR_CHAINING) != 0) { ardataset = event->rdataset; asigrdataset = event->sigrdataset; } } } /* * Find or create the cache node. */ node = NULL; result = dns_db_findnode(fctx->cache, name, ISC_TRUE, &node); if (result != ISC_R_SUCCESS) return (result); /* * Cache or validate each cacheable rdataset. */ fail = ISC_TF((fctx->res->options & DNS_RESOLVER_CHECKNAMESFAIL) != 0); for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (!CACHE(rdataset)) continue; if (CHECKNAMES(rdataset)) { char namebuf[DNS_NAME_FORMATSIZE]; char typebuf[DNS_RDATATYPE_FORMATSIZE]; char classbuf[DNS_RDATATYPE_FORMATSIZE]; dns_name_format(name, namebuf, sizeof(namebuf)); dns_rdatatype_format(rdataset->type, typebuf, sizeof(typebuf)); dns_rdataclass_format(rdataset->rdclass, classbuf, sizeof(classbuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, "check-names %s %s/%s/%s", fail ? "failure" : "warning", namebuf, typebuf, classbuf); if (fail) { if (ANSWER(rdataset)) { dns_db_detachnode(fctx->cache, &node); return (DNS_R_BADNAME); } continue; } } /* * Enforce the configure maximum cache TTL. */ if (rdataset->ttl > res->view->maxcachettl) rdataset->ttl = res->view->maxcachettl; /* * Mark the rdataset as being prefetch eligible. */ if (rdataset->ttl > fctx->res->view->prefetch_eligible) rdataset->attributes |= DNS_RDATASETATTR_PREFETCH; /* * Find the SIG for this rdataset, if we have it. */ for (sigrdataset = ISC_LIST_HEAD(name->list); sigrdataset != NULL; sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) { if (sigrdataset->type == dns_rdatatype_rrsig && sigrdataset->covers == rdataset->type) break; } /* * If this RRset is in a secure domain, is in bailiwick, * and is not glue, attempt DNSSEC validation. (We do not * attempt to validate glue or out-of-bailiwick data--even * though there might be some performance benefit to doing * so--because it makes it simpler and safer to ensure that * records from a secure domain are only cached if validated * within the context of a query to the domain that owns * them.) */ if (secure_domain && rdataset->trust != dns_trust_glue && !EXTERNAL(rdataset)) { dns_trust_t trust; /* * RRSIGs are validated as part of validating the * type they cover. */ if (rdataset->type == dns_rdatatype_rrsig) continue; if (sigrdataset == NULL) { if (!ANSWER(rdataset) && need_validation) { /* * Ignore non-answer rdatasets that * are missing signatures. */ continue; } } /* * Normalize the rdataset and sigrdataset TTLs. */ if (sigrdataset != NULL) { rdataset->ttl = ISC_MIN(rdataset->ttl, sigrdataset->ttl); sigrdataset->ttl = rdataset->ttl; } /* * Mark the rdataset as being prefetch eligible. */ if (rdataset->ttl > fctx->res->view->prefetch_eligible) rdataset->attributes |= DNS_RDATASETATTR_PREFETCH; /* * Cache this rdataset/sigrdataset pair as * pending data. Track whether it was additional * or not. */ if (rdataset->trust == dns_trust_additional) trust = dns_trust_pending_additional; else trust = dns_trust_pending_answer; rdataset->trust = trust; if (sigrdataset != NULL) sigrdataset->trust = trust; if (!need_validation || !ANSWER(rdataset)) { options = 0; if (ANSWER(rdataset) && rdataset->type != dns_rdatatype_rrsig) { isc_result_t tresult; dns_name_t *noqname = NULL; tresult = findnoqname(fctx, name, rdataset->type, &noqname); if (tresult == ISC_R_SUCCESS && noqname != NULL) { tresult = dns_rdataset_addnoqname( rdataset, noqname); RUNTIME_CHECK(tresult == ISC_R_SUCCESS); } } if ((fctx->options & DNS_FETCHOPT_PREFETCH) != 0) options = DNS_DBADD_PREFETCH; addedrdataset = ardataset; result = dns_db_addrdataset(fctx->cache, node, NULL, now, rdataset, options, addedrdataset); if (result == DNS_R_UNCHANGED) { result = ISC_R_SUCCESS; if (!need_validation && ardataset != NULL && NEGATIVE(ardataset)) { /* * The answer in the cache is * better than the answer we * found, and is a negative * cache entry, so we must set * eresult appropriately. */ if (NXDOMAIN(ardataset)) eresult = DNS_R_NCACHENXDOMAIN; else eresult = DNS_R_NCACHENXRRSET; /* * We have a negative response * from the cache so don't * attempt to add the RRSIG * rrset. */ continue; } } if (result != ISC_R_SUCCESS) break; if (sigrdataset != NULL) { addedrdataset = asigrdataset; result = dns_db_addrdataset(fctx->cache, node, NULL, now, sigrdataset, options, addedrdataset); if (result == DNS_R_UNCHANGED) result = ISC_R_SUCCESS; if (result != ISC_R_SUCCESS) break; } else if (!ANSWER(rdataset)) continue; } if (ANSWER(rdataset) && need_validation) { if (fctx->type != dns_rdatatype_any && fctx->type != dns_rdatatype_rrsig && fctx->type != dns_rdatatype_sig) { /* * This is The Answer. We will * validate it, but first we cache * the rest of the response - it may * contain useful keys. */ INSIST(valrdataset == NULL && valsigrdataset == NULL); valrdataset = rdataset; valsigrdataset = sigrdataset; } else { /* * This is one of (potentially) * multiple answers to an ANY * or SIG query. To keep things * simple, we just start the * validator right away rather * than caching first and * having to remember which * rdatasets needed validation. */ result = valcreate(fctx, addrinfo, name, rdataset->type, rdataset, sigrdataset, valoptions, task); /* * Defer any further validations. * This prevents multiple validators * from manipulating fctx->rmessage * simultaneously. */ valoptions |= DNS_VALIDATOR_DEFER; } } else if (CHAINING(rdataset)) { if (rdataset->type == dns_rdatatype_cname) eresult = DNS_R_CNAME; else { INSIST(rdataset->type == dns_rdatatype_dname); eresult = DNS_R_DNAME; } } } else if (!EXTERNAL(rdataset)) { /* * It's OK to cache this rdataset now. */ if (ANSWER(rdataset)) addedrdataset = ardataset; else if (ANSWERSIG(rdataset)) addedrdataset = asigrdataset; else addedrdataset = NULL; if (CHAINING(rdataset)) { if (rdataset->type == dns_rdatatype_cname) eresult = DNS_R_CNAME; else { INSIST(rdataset->type == dns_rdatatype_dname); eresult = DNS_R_DNAME; } } if (rdataset->trust == dns_trust_glue && (rdataset->type == dns_rdatatype_ns || (rdataset->type == dns_rdatatype_rrsig && rdataset->covers == dns_rdatatype_ns))) { /* * If the trust level is 'dns_trust_glue' * then we are adding data from a referral * we got while executing the search algorithm. * New referral data always takes precedence * over the existing cache contents. */ options = DNS_DBADD_FORCE; } else if ((fctx->options & DNS_FETCHOPT_PREFETCH) != 0) options = DNS_DBADD_PREFETCH; else options = 0; if (ANSWER(rdataset) && rdataset->type != dns_rdatatype_rrsig) { isc_result_t tresult; dns_name_t *noqname = NULL; tresult = findnoqname(fctx, name, rdataset->type, &noqname); if (tresult == ISC_R_SUCCESS && noqname != NULL) { tresult = dns_rdataset_addnoqname( rdataset, noqname); RUNTIME_CHECK(tresult == ISC_R_SUCCESS); } } /* * Now we can add the rdataset. */ result = dns_db_addrdataset(fctx->cache, node, NULL, now, rdataset, options, addedrdataset); if (result == DNS_R_UNCHANGED) { if (ANSWER(rdataset) && ardataset != NULL && NEGATIVE(ardataset)) { /* * The answer in the cache is better * than the answer we found, and is * a negative cache entry, so we * must set eresult appropriately. */ if (NXDOMAIN(ardataset)) eresult = DNS_R_NCACHENXDOMAIN; else eresult = DNS_R_NCACHENXRRSET; } result = ISC_R_SUCCESS; } else if (result != ISC_R_SUCCESS) break; } } if (valrdataset != NULL) { dns_rdatatype_t vtype = fctx->type; if (CHAINING(valrdataset)) { if (valrdataset->type == dns_rdatatype_cname) vtype = dns_rdatatype_cname; else vtype = dns_rdatatype_dname; } result = valcreate(fctx, addrinfo, name, vtype, valrdataset, valsigrdataset, valoptions, task); } if (result == ISC_R_SUCCESS && have_answer) { fctx->attributes |= FCTX_ATTR_HAVEANSWER; if (event != NULL) { /* * Negative results must be indicated in event->result. */ if (dns_rdataset_isassociated(event->rdataset) && NEGATIVE(event->rdataset)) { INSIST(eresult == DNS_R_NCACHENXDOMAIN || eresult == DNS_R_NCACHENXRRSET); } event->result = eresult; dns_db_attach(fctx->cache, adbp); dns_db_transfernode(fctx->cache, &node, anodep); clone_results(fctx); } } if (node != NULL) dns_db_detachnode(fctx->cache, &node); return (result); } static inline isc_result_t cache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_stdtime_t now) { isc_result_t result; dns_section_t section; dns_name_t *name; FCTXTRACE("cache_message"); fctx->attributes &= ~FCTX_ATTR_WANTCACHE; LOCK(&fctx->res->buckets[fctx->bucketnum].lock); for (section = DNS_SECTION_ANSWER; section <= DNS_SECTION_ADDITIONAL; section++) { result = dns_message_firstname(fctx->rmessage, section); while (result == ISC_R_SUCCESS) { name = NULL; dns_message_currentname(fctx->rmessage, section, &name); if ((name->attributes & DNS_NAMEATTR_CACHE) != 0) { result = cache_name(fctx, name, addrinfo, now); if (result != ISC_R_SUCCESS) break; } result = dns_message_nextname(fctx->rmessage, section); } if (result != ISC_R_NOMORE) break; } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock); return (result); } /* * Do what dns_ncache_addoptout() does, and then compute an appropriate eresult. */ static isc_result_t ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, isc_boolean_t optout, isc_boolean_t secure, dns_rdataset_t *ardataset, isc_result_t *eresultp) { isc_result_t result; dns_rdataset_t rdataset; if (ardataset == NULL) { dns_rdataset_init(&rdataset); ardataset = &rdataset; } if (secure) result = dns_ncache_addoptout(message, cache, node, covers, now, maxttl, optout, ardataset); else result = dns_ncache_add(message, cache, node, covers, now, maxttl, ardataset); if (result == DNS_R_UNCHANGED || result == ISC_R_SUCCESS) { /* * If the cache now contains a negative entry and we * care about whether it is DNS_R_NCACHENXDOMAIN or * DNS_R_NCACHENXRRSET then extract it. */ if (NEGATIVE(ardataset)) { /* * The cache data is a negative cache entry. */ if (NXDOMAIN(ardataset)) *eresultp = DNS_R_NCACHENXDOMAIN; else *eresultp = DNS_R_NCACHENXRRSET; } else { /* * Either we don't care about the nature of the * cache rdataset (because no fetch is interested * in the outcome), or the cache rdataset is not * a negative cache entry. Whichever case it is, * we can return success. * * XXXRTH There's a CNAME/DNAME problem here. */ *eresultp = ISC_R_SUCCESS; } result = ISC_R_SUCCESS; } if (ardataset == &rdataset && dns_rdataset_isassociated(ardataset)) dns_rdataset_disassociate(ardataset); return (result); } static inline isc_result_t ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_rdatatype_t covers, isc_stdtime_t now) { isc_result_t result, eresult; dns_name_t *name; dns_resolver_t *res; dns_db_t **adbp; dns_dbnode_t *node, **anodep; dns_rdataset_t *ardataset; isc_boolean_t need_validation, secure_domain; dns_name_t *aname; dns_fetchevent_t *event; isc_uint32_t ttl; unsigned int valoptions = 0; FCTXTRACE("ncache_message"); fctx->attributes &= ~FCTX_ATTR_WANTNCACHE; res = fctx->res; need_validation = ISC_FALSE; POST(need_validation); secure_domain = ISC_FALSE; eresult = ISC_R_SUCCESS; name = &fctx->name; node = NULL; /* * XXXMPA remove when we follow cnames and adjust the setting * of FCTX_ATTR_WANTNCACHE in noanswer_response(). */ INSIST(fctx->rmessage->counts[DNS_SECTION_ANSWER] == 0); /* * Is DNSSEC validation required for this name? */ if (fctx->res->view->enablevalidation) { result = dns_view_issecuredomain(res->view, name, &secure_domain); if (result != ISC_R_SUCCESS) return (result); if (!secure_domain && res->view->dlv != NULL) { valoptions = DNS_VALIDATOR_DLV; secure_domain = ISC_TRUE; } } if ((fctx->options & DNS_FETCHOPT_NOCDFLAG) != 0) valoptions |= DNS_VALIDATOR_NOCDFLAG; if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0) need_validation = ISC_FALSE; else need_validation = secure_domain; if (secure_domain) { /* * Mark all rdatasets as pending. */ dns_rdataset_t *trdataset; dns_name_t *tname; result = dns_message_firstname(fctx->rmessage, DNS_SECTION_AUTHORITY); while (result == ISC_R_SUCCESS) { tname = NULL; dns_message_currentname(fctx->rmessage, DNS_SECTION_AUTHORITY, &tname); for (trdataset = ISC_LIST_HEAD(tname->list); trdataset != NULL; trdataset = ISC_LIST_NEXT(trdataset, link)) trdataset->trust = dns_trust_pending_answer; result = dns_message_nextname(fctx->rmessage, DNS_SECTION_AUTHORITY); } if (result != ISC_R_NOMORE) return (result); } if (need_validation) { /* * Do negative response validation. */ result = valcreate(fctx, addrinfo, name, fctx->type, NULL, NULL, valoptions, res->buckets[fctx->bucketnum].task); /* * If validation is necessary, return now. Otherwise continue * to process the message, letting the validation complete * in its own good time. */ return (result); } LOCK(&res->buckets[fctx->bucketnum].lock); adbp = NULL; aname = NULL; anodep = NULL; ardataset = NULL; if (!HAVE_ANSWER(fctx)) { event = ISC_LIST_HEAD(fctx->events); if (event != NULL) { adbp = &event->db; aname = dns_fixedname_name(&event->foundname); result = dns_name_copy(name, aname, NULL); if (result != ISC_R_SUCCESS) goto unlock; anodep = &event->node; ardataset = event->rdataset; } } else event = NULL; result = dns_db_findnode(fctx->cache, name, ISC_TRUE, &node); if (result != ISC_R_SUCCESS) goto unlock; /* * If we are asking for a SOA record set the cache time * to zero to facilitate locating the containing zone of * a arbitrary zone. */ ttl = fctx->res->view->maxncachettl; if (fctx->type == dns_rdatatype_soa && covers == dns_rdatatype_any && fctx->res->zero_no_soa_ttl) ttl = 0; result = ncache_adderesult(fctx->rmessage, fctx->cache, node, covers, now, ttl, ISC_FALSE, ISC_FALSE, ardataset, &eresult); if (result != ISC_R_SUCCESS) goto unlock; if (!HAVE_ANSWER(fctx)) { fctx->attributes |= FCTX_ATTR_HAVEANSWER; if (event != NULL) { event->result = eresult; dns_db_attach(fctx->cache, adbp); dns_db_transfernode(fctx->cache, &node, anodep); clone_results(fctx); } } unlock: UNLOCK(&res->buckets[fctx->bucketnum].lock); if (node != NULL) dns_db_detachnode(fctx->cache, &node); return (result); } static inline void mark_related(dns_name_t *name, dns_rdataset_t *rdataset, isc_boolean_t external, isc_boolean_t gluing) { name->attributes |= DNS_NAMEATTR_CACHE; if (gluing) { rdataset->trust = dns_trust_glue; /* * Glue with 0 TTL causes problems. We force the TTL to * 1 second to prevent this. */ if (rdataset->ttl == 0) rdataset->ttl = 1; } else rdataset->trust = dns_trust_additional; /* * Avoid infinite loops by only marking new rdatasets. */ if (!CACHE(rdataset)) { name->attributes |= DNS_NAMEATTR_CHASE; rdataset->attributes |= DNS_RDATASETATTR_CHASE; } rdataset->attributes |= DNS_RDATASETATTR_CACHE; if (external) rdataset->attributes |= DNS_RDATASETATTR_EXTERNAL; } static isc_result_t check_section(void *arg, dns_name_t *addname, dns_rdatatype_t type, dns_section_t section) { fetchctx_t *fctx = arg; isc_result_t result; dns_name_t *name; dns_rdataset_t *rdataset; isc_boolean_t external; dns_rdatatype_t rtype; isc_boolean_t gluing; REQUIRE(VALID_FCTX(fctx)); #if CHECK_FOR_GLUE_IN_ANSWER if (section == DNS_SECTION_ANSWER && type != dns_rdatatype_a) return (ISC_R_SUCCESS); #endif if (GLUING(fctx)) gluing = ISC_TRUE; else gluing = ISC_FALSE; name = NULL; rdataset = NULL; result = dns_message_findname(fctx->rmessage, section, addname, dns_rdatatype_any, 0, &name, NULL); if (result == ISC_R_SUCCESS) { external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain)); if (type == dns_rdatatype_a) { for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (rdataset->type == dns_rdatatype_rrsig) rtype = rdataset->covers; else rtype = rdataset->type; if (rtype == dns_rdatatype_a || rtype == dns_rdatatype_aaaa) mark_related(name, rdataset, external, gluing); } } else { result = dns_message_findtype(name, type, 0, &rdataset); if (result == ISC_R_SUCCESS) { mark_related(name, rdataset, external, gluing); /* * Do we have its SIG too? */ rdataset = NULL; result = dns_message_findtype(name, dns_rdatatype_rrsig, type, &rdataset); if (result == ISC_R_SUCCESS) mark_related(name, rdataset, external, gluing); } } } return (ISC_R_SUCCESS); } static isc_result_t check_related(void *arg, dns_name_t *addname, dns_rdatatype_t type) { return (check_section(arg, addname, type, DNS_SECTION_ADDITIONAL)); } #ifndef CHECK_FOR_GLUE_IN_ANSWER #define CHECK_FOR_GLUE_IN_ANSWER 0 #endif #if CHECK_FOR_GLUE_IN_ANSWER static isc_result_t check_answer(void *arg, dns_name_t *addname, dns_rdatatype_t type) { return (check_section(arg, addname, type, DNS_SECTION_ANSWER)); } #endif static void chase_additional(fetchctx_t *fctx) { isc_boolean_t rescan; dns_section_t section = DNS_SECTION_ADDITIONAL; isc_result_t result; again: rescan = ISC_FALSE; for (result = dns_message_firstname(fctx->rmessage, section); result == ISC_R_SUCCESS; result = dns_message_nextname(fctx->rmessage, section)) { dns_name_t *name = NULL; dns_rdataset_t *rdataset; dns_message_currentname(fctx->rmessage, DNS_SECTION_ADDITIONAL, &name); if ((name->attributes & DNS_NAMEATTR_CHASE) == 0) continue; name->attributes &= ~DNS_NAMEATTR_CHASE; for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (CHASE(rdataset)) { rdataset->attributes &= ~DNS_RDATASETATTR_CHASE; (void)dns_rdataset_additionaldata(rdataset, check_related, fctx); rescan = ISC_TRUE; } } } if (rescan) goto again; } static inline isc_result_t cname_target(dns_rdataset_t *rdataset, dns_name_t *tname) { isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_cname_t cname; result = dns_rdataset_first(rdataset); if (result != ISC_R_SUCCESS) return (result); dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &cname, NULL); if (result != ISC_R_SUCCESS) return (result); dns_name_init(tname, NULL); dns_name_clone(&cname.cname, tname); dns_rdata_freestruct(&cname); return (ISC_R_SUCCESS); } static inline isc_result_t dname_target(dns_rdataset_t *rdataset, dns_name_t *qname, unsigned int nlabels, dns_fixedname_t *fixeddname) { isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_dname_t dname; dns_fixedname_t prefix; /* * Get the target name of the DNAME. */ result = dns_rdataset_first(rdataset); if (result != ISC_R_SUCCESS) return (result); dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &dname, NULL); if (result != ISC_R_SUCCESS) return (result); dns_fixedname_init(&prefix); dns_name_split(qname, nlabels, dns_fixedname_name(&prefix), NULL); dns_fixedname_init(fixeddname); result = dns_name_concatenate(dns_fixedname_name(&prefix), &dname.dname, dns_fixedname_name(fixeddname), NULL); dns_rdata_freestruct(&dname); return (result); } static isc_boolean_t is_answeraddress_allowed(dns_view_t *view, dns_name_t *name, dns_rdataset_t *rdataset) { isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; struct in_addr ina; struct in6_addr in6a; isc_netaddr_t netaddr; char addrbuf[ISC_NETADDR_FORMATSIZE]; char namebuf[DNS_NAME_FORMATSIZE]; char classbuf[64]; char typebuf[64]; int match; /* By default, we allow any addresses. */ if (view->denyansweracl == NULL) return (ISC_TRUE); /* * If the owner name matches one in the exclusion list, either exactly * or partially, allow it. */ if (view->answeracl_exclude != NULL) { dns_rbtnode_t *node = NULL; result = dns_rbt_findnode(view->answeracl_exclude, name, NULL, &node, NULL, 0, NULL, NULL); if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) return (ISC_TRUE); } /* * Otherwise, search the filter list for a match for each address * record. If a match is found, the address should be filtered, * so should the entire answer. */ for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdata_reset(&rdata); dns_rdataset_current(rdataset, &rdata); if (rdataset->type == dns_rdatatype_a) { INSIST(rdata.length == sizeof(ina.s_addr)); memmove(&ina.s_addr, rdata.data, sizeof(ina.s_addr)); isc_netaddr_fromin(&netaddr, &ina); } else { INSIST(rdata.length == sizeof(in6a.s6_addr)); memmove(in6a.s6_addr, rdata.data, sizeof(in6a.s6_addr)); isc_netaddr_fromin6(&netaddr, &in6a); } result = dns_acl_match(&netaddr, NULL, view->denyansweracl, &view->aclenv, &match, NULL); if (result == ISC_R_SUCCESS && match > 0) { isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf)); dns_name_format(name, namebuf, sizeof(namebuf)); dns_rdatatype_format(rdataset->type, typebuf, sizeof(typebuf)); dns_rdataclass_format(rdataset->rdclass, classbuf, sizeof(classbuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, "answer address %s denied for %s/%s/%s", addrbuf, namebuf, typebuf, classbuf); return (ISC_FALSE); } } return (ISC_TRUE); } static isc_boolean_t is_answertarget_allowed(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, dns_name_t *tname, dns_name_t *domain) { isc_result_t result; dns_rbtnode_t *node = NULL; char qnamebuf[DNS_NAME_FORMATSIZE]; char tnamebuf[DNS_NAME_FORMATSIZE]; char classbuf[64]; char typebuf[64]; /* By default, we allow any target name. */ if (view->denyanswernames == NULL) return (ISC_TRUE); /* * If the owner name matches one in the exclusion list, either exactly * or partially, allow it. */ if (view->answernames_exclude != NULL) { result = dns_rbt_findnode(view->answernames_exclude, name, NULL, &node, NULL, 0, NULL, NULL); if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) return (ISC_TRUE); } /* * If the target name is a subdomain of the search domain, allow it. */ if (dns_name_issubdomain(tname, domain)) return (ISC_TRUE); /* * Otherwise, apply filters. */ result = dns_rbt_findnode(view->denyanswernames, tname, NULL, &node, NULL, 0, NULL, NULL); if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { dns_name_format(name, qnamebuf, sizeof(qnamebuf)); dns_name_format(tname, tnamebuf, sizeof(tnamebuf)); dns_rdatatype_format(type, typebuf, sizeof(typebuf)); dns_rdataclass_format(view->rdclass, classbuf, sizeof(classbuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, "%s target %s denied for %s/%s", typebuf, tnamebuf, qnamebuf, classbuf); return (ISC_FALSE); } return (ISC_TRUE); } static void trim_ns_ttl(fetchctx_t *fctx, dns_name_t *name, dns_rdataset_t *rdataset) { char ns_namebuf[DNS_NAME_FORMATSIZE]; char namebuf[DNS_NAME_FORMATSIZE]; char tbuf[DNS_RDATATYPE_FORMATSIZE]; if (fctx->ns_ttl_ok && rdataset->ttl > fctx->ns_ttl) { dns_name_format(name, ns_namebuf, sizeof(ns_namebuf)); dns_name_format(&fctx->name, namebuf, sizeof(namebuf)); dns_rdatatype_format(fctx->type, tbuf, sizeof(tbuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(10), "fctx %p: trimming ttl of %s/NS for %s/%s: " "%u -> %u", fctx, ns_namebuf, namebuf, tbuf, rdataset->ttl, fctx->ns_ttl); rdataset->ttl = fctx->ns_ttl; } } /* * Handle a no-answer response (NXDOMAIN, NXRRSET, or referral). * If look_in_options has LOOK_FOR_NS_IN_ANSWER then we look in the answer * section for the NS RRset if the query type is NS; if it has * LOOK_FOR_GLUE_IN_ANSWER we look for glue incorrectly returned in the answer * section for A and AAAA queries. */ #define LOOK_FOR_NS_IN_ANSWER 0x1 #define LOOK_FOR_GLUE_IN_ANSWER 0x2 static isc_result_t noanswer_response(fetchctx_t *fctx, dns_name_t *oqname, unsigned int look_in_options) { isc_result_t result; dns_message_t *message; dns_name_t *name, *qname, *ns_name, *soa_name, *ds_name, *save_name; dns_rdataset_t *rdataset, *ns_rdataset; isc_boolean_t aa, negative_response; dns_rdatatype_t type, save_type; dns_section_t section; FCTXTRACE("noanswer_response"); if ((look_in_options & LOOK_FOR_NS_IN_ANSWER) != 0) { INSIST(fctx->type == dns_rdatatype_ns); section = DNS_SECTION_ANSWER; } else section = DNS_SECTION_AUTHORITY; message = fctx->rmessage; /* * Setup qname. */ if (oqname == NULL) { /* * We have a normal, non-chained negative response or * referral. */ if ((message->flags & DNS_MESSAGEFLAG_AA) != 0) aa = ISC_TRUE; else aa = ISC_FALSE; qname = &fctx->name; } else { /* * We're being invoked by answer_response() after it has * followed a CNAME/DNAME chain. */ qname = oqname; aa = ISC_FALSE; /* * If the current qname is not a subdomain of the query * domain, there's no point in looking at the authority * section without doing DNSSEC validation. * * Until we do that validation, we'll just return success * in this case. */ if (!dns_name_issubdomain(qname, &fctx->domain)) return (ISC_R_SUCCESS); } /* * We have to figure out if this is a negative response, or a * referral. */ /* * Sometimes we can tell if its a negative response by looking at * the message header. */ negative_response = ISC_FALSE; if (message->rcode == dns_rcode_nxdomain || (message->counts[DNS_SECTION_ANSWER] == 0 && message->counts[DNS_SECTION_AUTHORITY] == 0)) negative_response = ISC_TRUE; /* * Process the authority section. */ ns_name = NULL; ns_rdataset = NULL; soa_name = NULL; ds_name = NULL; save_name = NULL; save_type = dns_rdatatype_none; result = dns_message_firstname(message, section); while (result == ISC_R_SUCCESS) { name = NULL; dns_message_currentname(message, section, &name); if (dns_name_issubdomain(name, &fctx->domain)) { /* * Look for NS/SOA RRsets first. */ for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { type = rdataset->type; if (type == dns_rdatatype_rrsig) type = rdataset->covers; if (((type == dns_rdatatype_ns || type == dns_rdatatype_soa) && !dns_name_issubdomain(qname, name))) { char qbuf[DNS_NAME_FORMATSIZE]; char nbuf[DNS_NAME_FORMATSIZE]; char tbuf[DNS_RDATATYPE_FORMATSIZE]; dns_rdatatype_format(type, tbuf, sizeof(tbuf)); dns_name_format(name, nbuf, sizeof(nbuf)); dns_name_format(qname, qbuf, sizeof(qbuf)); log_formerr(fctx, "unrelated %s %s in " "%s authority section", tbuf, nbuf, qbuf); goto nextname; } if (type == dns_rdatatype_ns) { /* * NS or RRSIG NS. * * Only one set of NS RRs is allowed. */ if (rdataset->type == dns_rdatatype_ns) { if (ns_name != NULL && name != ns_name) { log_formerr(fctx, "multiple NS " "RRsets in " "authority " "section"); return (DNS_R_FORMERR); } ns_name = name; ns_rdataset = rdataset; } name->attributes |= DNS_NAMEATTR_CACHE; rdataset->attributes |= DNS_RDATASETATTR_CACHE; rdataset->trust = dns_trust_glue; } if (type == dns_rdatatype_soa) { /* * SOA, or RRSIG SOA. * * Only one SOA is allowed. */ if (rdataset->type == dns_rdatatype_soa) { if (soa_name != NULL && name != soa_name) { log_formerr(fctx, "multiple SOA " "RRs in " "authority " "section"); return (DNS_R_FORMERR); } soa_name = name; } name->attributes |= DNS_NAMEATTR_NCACHE; rdataset->attributes |= DNS_RDATASETATTR_NCACHE; if (aa) rdataset->trust = dns_trust_authauthority; else if (ISFORWARDER(fctx->addrinfo)) rdataset->trust = dns_trust_answer; else rdataset->trust = dns_trust_additional; } } } nextname: result = dns_message_nextname(message, section); if (result == ISC_R_NOMORE) break; else if (result != ISC_R_SUCCESS) return (result); } log_ns_ttl(fctx, "noanswer_response"); if (ns_rdataset != NULL && dns_name_equal(&fctx->domain, ns_name) && !dns_name_equal(ns_name, dns_rootname)) trim_ns_ttl(fctx, ns_name, ns_rdataset); /* * A negative response has a SOA record (Type 2) * and a optional NS RRset (Type 1) or it has neither * a SOA or a NS RRset (Type 3, handled above) or * rcode is NXDOMAIN (handled above) in which case * the NS RRset is allowed (Type 4). */ if (soa_name != NULL) negative_response = ISC_TRUE; result = dns_message_firstname(message, section); while (result == ISC_R_SUCCESS) { name = NULL; dns_message_currentname(message, section, &name); if (dns_name_issubdomain(name, &fctx->domain)) { for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { type = rdataset->type; if (type == dns_rdatatype_rrsig) type = rdataset->covers; if (type == dns_rdatatype_nsec || type == dns_rdatatype_nsec3) { /* * NSEC or RRSIG NSEC. */ if (negative_response) { name->attributes |= DNS_NAMEATTR_NCACHE; rdataset->attributes |= DNS_RDATASETATTR_NCACHE; } else if (type == dns_rdatatype_nsec) { name->attributes |= DNS_NAMEATTR_CACHE; rdataset->attributes |= DNS_RDATASETATTR_CACHE; } if (aa) rdataset->trust = dns_trust_authauthority; else if (ISFORWARDER(fctx->addrinfo)) rdataset->trust = dns_trust_answer; else rdataset->trust = dns_trust_additional; /* * No additional data needs to be * marked. */ } else if (type == dns_rdatatype_ds) { /* * DS or SIG DS. * * These should only be here if * this is a referral, and there * should only be one DS RRset. */ if (ns_name == NULL) { log_formerr(fctx, "DS with no " "referral"); return (DNS_R_FORMERR); } if (rdataset->type == dns_rdatatype_ds) { if (ds_name != NULL && name != ds_name) { log_formerr(fctx, "DS doesn't " "match " "referral " "(NS)"); return (DNS_R_FORMERR); } ds_name = name; } name->attributes |= DNS_NAMEATTR_CACHE; rdataset->attributes |= DNS_RDATASETATTR_CACHE; if (aa) rdataset->trust = dns_trust_authauthority; else if (ISFORWARDER(fctx->addrinfo)) rdataset->trust = dns_trust_answer; else rdataset->trust = dns_trust_additional; } } } else { save_name = name; save_type = ISC_LIST_HEAD(name->list)->type; } result = dns_message_nextname(message, section); if (result == ISC_R_NOMORE) break; else if (result != ISC_R_SUCCESS) return (result); } /* * Trigger lookups for DNS nameservers. */ if (negative_response && message->rcode == dns_rcode_noerror && fctx->type == dns_rdatatype_ds && soa_name != NULL && dns_name_equal(soa_name, qname) && !dns_name_equal(qname, dns_rootname)) return (DNS_R_CHASEDSSERVERS); /* * Did we find anything? */ if (!negative_response && ns_name == NULL) { /* * Nope. */ if (oqname != NULL) { /* * We've already got a partial CNAME/DNAME chain, * and haven't found else anything useful here, but * no error has occurred since we have an answer. */ return (ISC_R_SUCCESS); } else { /* * The responder is insane. */ if (save_name == NULL) { log_formerr(fctx, "invalid response"); return (DNS_R_FORMERR); } if (!dns_name_issubdomain(save_name, &fctx->domain)) { char nbuf[DNS_NAME_FORMATSIZE]; char dbuf[DNS_NAME_FORMATSIZE]; char tbuf[DNS_RDATATYPE_FORMATSIZE]; dns_rdatatype_format(save_type, tbuf, sizeof(tbuf)); dns_name_format(save_name, nbuf, sizeof(nbuf)); dns_name_format(&fctx->domain, dbuf, sizeof(dbuf)); log_formerr(fctx, "Name %s (%s) not subdomain" " of zone %s -- invalid response", nbuf, tbuf, dbuf); } else { log_formerr(fctx, "invalid response"); } return (DNS_R_FORMERR); } } /* * If we found both NS and SOA, they should be the same name. */ if (ns_name != NULL && soa_name != NULL && ns_name != soa_name) { log_formerr(fctx, "NS/SOA mismatch"); return (DNS_R_FORMERR); } /* * Do we have a referral? (We only want to follow a referral if * we're not following a chain.) */ if (!negative_response && ns_name != NULL && oqname == NULL) { /* * We already know ns_name is a subdomain of fctx->domain. * If ns_name is equal to fctx->domain, we're not making * progress. We return DNS_R_FORMERR so that we'll keep * trying other servers. */ if (dns_name_equal(ns_name, &fctx->domain)) { log_formerr(fctx, "non-improving referral"); return (DNS_R_FORMERR); } /* * If the referral name is not a parent of the query * name, consider the responder insane. */ if (! dns_name_issubdomain(&fctx->name, ns_name)) { /* Logged twice */ log_formerr(fctx, "referral to non-parent"); FCTXTRACE("referral to non-parent"); return (DNS_R_FORMERR); } /* * Mark any additional data related to this rdataset. * It's important that we do this before we change the * query domain. */ INSIST(ns_rdataset != NULL); fctx->attributes |= FCTX_ATTR_GLUING; (void)dns_rdataset_additionaldata(ns_rdataset, check_related, fctx); #if CHECK_FOR_GLUE_IN_ANSWER /* * Look in the answer section for "glue" that is incorrectly * returned as a answer. This is needed if the server also * minimizes the response size by not adding records to the * additional section that are in the answer section or if * the record gets dropped due to message size constraints. */ if ((look_in_options & LOOK_FOR_GLUE_IN_ANSWER) != 0 && (fctx->type == dns_rdatatype_aaaa || fctx->type == dns_rdatatype_a)) (void)dns_rdataset_additionaldata(ns_rdataset, check_answer, fctx); #endif fctx->attributes &= ~FCTX_ATTR_GLUING; /* * NS rdatasets with 0 TTL cause problems. * dns_view_findzonecut() will not find them when we * try to follow the referral, and we'll SERVFAIL * because the best nameservers are now above QDOMAIN. * We force the TTL to 1 second to prevent this. */ if (ns_rdataset->ttl == 0) ns_rdataset->ttl = 1; /* * Set the current query domain to the referral name. * * XXXRTH We should check if we're in forward-only mode, and * if so we should bail out. */ INSIST(dns_name_countlabels(&fctx->domain) > 0); #ifdef ENABLE_FETCHLIMIT fcount_decr(fctx); #endif /* ENABLE_FETCHLIMIT */ dns_name_free(&fctx->domain, fctx->mctx); if (dns_rdataset_isassociated(&fctx->nameservers)) dns_rdataset_disassociate(&fctx->nameservers); dns_name_init(&fctx->domain, NULL); result = dns_name_dup(ns_name, fctx->mctx, &fctx->domain); if (result != ISC_R_SUCCESS) return (result); #ifdef ENABLE_FETCHLIMIT result = fcount_incr(fctx, ISC_TRUE); if (result != ISC_R_SUCCESS) return (result); #endif /* ENABLE_FETCHLIMIT */ fctx->attributes |= FCTX_ATTR_WANTCACHE; fctx->ns_ttl_ok = ISC_FALSE; log_ns_ttl(fctx, "DELEGATION"); return (DNS_R_DELEGATION); } /* * Since we're not doing a referral, we don't want to cache any * NS RRs we may have found. */ if (ns_name != NULL) ns_name->attributes &= ~DNS_NAMEATTR_CACHE; if (negative_response && oqname == NULL) fctx->attributes |= FCTX_ATTR_WANTNCACHE; return (ISC_R_SUCCESS); } static isc_result_t answer_response(fetchctx_t *fctx) { isc_result_t result; dns_message_t *message; dns_name_t *name, *dname = NULL, *qname, tname, *ns_name; dns_rdataset_t *rdataset, *ns_rdataset; isc_boolean_t done, external, chaining, aa, found, want_chaining; isc_boolean_t have_answer, found_cname, found_type, wanted_chaining; unsigned int aflag; dns_rdatatype_t type; dns_fixedname_t fdname, fqname; dns_view_t *view; FCTXTRACE("answer_response"); message = fctx->rmessage; /* * Examine the answer section, marking those rdatasets which are * part of the answer and should be cached. */ done = ISC_FALSE; found_cname = ISC_FALSE; found_type = ISC_FALSE; chaining = ISC_FALSE; have_answer = ISC_FALSE; want_chaining = ISC_FALSE; POST(want_chaining); if ((message->flags & DNS_MESSAGEFLAG_AA) != 0) aa = ISC_TRUE; else aa = ISC_FALSE; qname = &fctx->name; type = fctx->type; view = fctx->res->view; result = dns_message_firstname(message, DNS_SECTION_ANSWER); while (!done && result == ISC_R_SUCCESS) { dns_namereln_t namereln; int order; unsigned int nlabels; name = NULL; dns_message_currentname(message, DNS_SECTION_ANSWER, &name); external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain)); namereln = dns_name_fullcompare(qname, name, &order, &nlabels); if (namereln == dns_namereln_equal) { wanted_chaining = ISC_FALSE; for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { found = ISC_FALSE; want_chaining = ISC_FALSE; aflag = 0; if (rdataset->type == dns_rdatatype_nsec3) { /* * NSEC3 records are not allowed to * appear in the answer section. */ log_formerr(fctx, "NSEC3 in answer"); return (DNS_R_FORMERR); } /* * Apply filters, if given, on answers to reject * a malicious attempt of rebinding. */ if ((rdataset->type == dns_rdatatype_a || rdataset->type == dns_rdatatype_aaaa) && !is_answeraddress_allowed(view, name, rdataset)) { return (DNS_R_SERVFAIL); } if (rdataset->type == type && !found_cname) { /* * We've found an ordinary answer. */ found = ISC_TRUE; found_type = ISC_TRUE; done = ISC_TRUE; aflag = DNS_RDATASETATTR_ANSWER; } else if (type == dns_rdatatype_any) { /* * We've found an answer matching * an ANY query. There may be * more. */ found = ISC_TRUE; aflag = DNS_RDATASETATTR_ANSWER; } else if (rdataset->type == dns_rdatatype_rrsig && rdataset->covers == type && !found_cname) { /* * We've found a signature that * covers the type we're looking for. */ found = ISC_TRUE; found_type = ISC_TRUE; aflag = DNS_RDATASETATTR_ANSWERSIG; } else if (rdataset->type == dns_rdatatype_cname && !found_type) { /* * We're looking for something else, * but we found a CNAME. * * Getting a CNAME response for some * query types is an error, see * RFC 4035, Section 2.5. */ if (type == dns_rdatatype_rrsig || type == dns_rdatatype_key || type == dns_rdatatype_nsec) { char buf[DNS_RDATATYPE_FORMATSIZE]; dns_rdatatype_format(fctx->type, buf, sizeof(buf)); log_formerr(fctx, "CNAME response " "for %s RR", buf); return (DNS_R_FORMERR); } found = ISC_TRUE; found_cname = ISC_TRUE; want_chaining = ISC_TRUE; aflag = DNS_RDATASETATTR_ANSWER; result = cname_target(rdataset, &tname); if (result != ISC_R_SUCCESS) return (result); /* Apply filters on the target name. */ if (!is_answertarget_allowed(view, name, rdataset->type, &tname, &fctx->domain)) { return (DNS_R_SERVFAIL); } } else if (rdataset->type == dns_rdatatype_rrsig && rdataset->covers == dns_rdatatype_cname && !found_type) { /* * We're looking for something else, * but we found a SIG CNAME. */ found = ISC_TRUE; found_cname = ISC_TRUE; aflag = DNS_RDATASETATTR_ANSWERSIG; } if (found) { /* * We've found an answer to our * question. */ name->attributes |= DNS_NAMEATTR_CACHE; rdataset->attributes |= DNS_RDATASETATTR_CACHE; rdataset->trust = dns_trust_answer; if (!chaining) { /* * This data is "the" answer * to our question only if * we're not chaining (i.e. * if we haven't followed * a CNAME or DNAME). */ INSIST(!external); if (aflag == DNS_RDATASETATTR_ANSWER) { have_answer = ISC_TRUE; name->attributes |= DNS_NAMEATTR_ANSWER; } rdataset->attributes |= aflag; if (aa) rdataset->trust = dns_trust_authanswer; } else if (external) { /* * This data is outside of * our query domain, and * may not be cached. */ rdataset->attributes |= DNS_RDATASETATTR_EXTERNAL; } /* * Mark any additional data related * to this rdataset. */ (void)dns_rdataset_additionaldata( rdataset, check_related, fctx); /* * CNAME chaining. */ if (want_chaining) { wanted_chaining = ISC_TRUE; name->attributes |= DNS_NAMEATTR_CHAINING; rdataset->attributes |= DNS_RDATASETATTR_CHAINING; qname = &tname; } } /* * We could add an "else" clause here and * log that we're ignoring this rdataset. */ } /* * If wanted_chaining is true, we've done * some chaining as the result of processing * this node, and thus we need to set * chaining to true. * * We don't set chaining inside of the * rdataset loop because doing that would * cause us to ignore the signatures of * CNAMEs. */ if (wanted_chaining) chaining = ISC_TRUE; } else { dns_rdataset_t *dnameset = NULL; /* * Look for a DNAME (or its SIG). Anything else is * ignored. */ wanted_chaining = ISC_FALSE; for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { /* * Only pass DNAME or RRSIG(DNAME). */ if (rdataset->type != dns_rdatatype_dname && (rdataset->type != dns_rdatatype_rrsig || rdataset->covers != dns_rdatatype_dname)) continue; /* * If we're not chaining, then the DNAME and * its signature should not be external. */ if (!chaining && external) { char qbuf[DNS_NAME_FORMATSIZE]; char obuf[DNS_NAME_FORMATSIZE]; dns_name_format(name, qbuf, sizeof(qbuf)); dns_name_format(&fctx->domain, obuf, sizeof(obuf)); log_formerr(fctx, "external DNAME or " "RRSIG covering DNAME " "in answer: %s is " "not in %s", qbuf, obuf); return (DNS_R_FORMERR); } if (namereln != dns_namereln_subdomain) { char qbuf[DNS_NAME_FORMATSIZE]; char obuf[DNS_NAME_FORMATSIZE]; dns_name_format(qname, qbuf, sizeof(qbuf)); dns_name_format(name, obuf, sizeof(obuf)); log_formerr(fctx, "unrelated DNAME " "in answer: %s is " "not in %s", qbuf, obuf); return (DNS_R_FORMERR); } aflag = 0; if (rdataset->type == dns_rdatatype_dname) { want_chaining = ISC_TRUE; POST(want_chaining); aflag = DNS_RDATASETATTR_ANSWER; result = dname_target(rdataset, qname, nlabels, &fdname); if (result == ISC_R_NOSPACE) { /* * We can't construct the * DNAME target. Do not * try to continue. */ want_chaining = ISC_FALSE; POST(want_chaining); } else if (result != ISC_R_SUCCESS) return (result); else dnameset = rdataset; dname = dns_fixedname_name(&fdname); if (!is_answertarget_allowed(view, qname, rdataset->type, dname, &fctx->domain)) { return (DNS_R_SERVFAIL); } } else { /* * We've found a signature that * covers the DNAME. */ aflag = DNS_RDATASETATTR_ANSWERSIG; } /* * We've found an answer to our * question. */ name->attributes |= DNS_NAMEATTR_CACHE; rdataset->attributes |= DNS_RDATASETATTR_CACHE; rdataset->trust = dns_trust_answer; if (!chaining) { /* * This data is "the" answer to * our question only if we're * not chaining. */ INSIST(!external); if (aflag == DNS_RDATASETATTR_ANSWER) { have_answer = ISC_TRUE; name->attributes |= DNS_NAMEATTR_ANSWER; } rdataset->attributes |= aflag; if (aa) rdataset->trust = dns_trust_authanswer; } else if (external) { rdataset->attributes |= DNS_RDATASETATTR_EXTERNAL; } } /* * DNAME chaining. */ if (dnameset != NULL) { /* * Copy the dname into the qname fixed name. * * Although we check for failure of the copy * operation, in practice it should never fail * since we already know that the result fits * in a fixedname. */ dns_fixedname_init(&fqname); qname = dns_fixedname_name(&fqname); result = dns_name_copy(dname, qname, NULL); if (result != ISC_R_SUCCESS) return (result); wanted_chaining = ISC_TRUE; name->attributes |= DNS_NAMEATTR_CHAINING; dnameset->attributes |= DNS_RDATASETATTR_CHAINING; } if (wanted_chaining) chaining = ISC_TRUE; } result = dns_message_nextname(message, DNS_SECTION_ANSWER); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; if (result != ISC_R_SUCCESS) return (result); /* * We should have found an answer. */ if (!have_answer) { log_formerr(fctx, "reply has no answer"); return (DNS_R_FORMERR); } /* * This response is now potentially cacheable. */ fctx->attributes |= FCTX_ATTR_WANTCACHE; /* * Did chaining end before we got the final answer? */ if (chaining) { /* * Yes. This may be a negative reply, so hand off * authority section processing to the noanswer code. * If it isn't a noanswer response, no harm will be * done. */ return (noanswer_response(fctx, qname, 0)); } /* * We didn't end with an incomplete chain, so the rcode should be * "no error". */ if (message->rcode != dns_rcode_noerror) { log_formerr(fctx, "CNAME/DNAME chain complete, but RCODE " "indicates error"); return (DNS_R_FORMERR); } /* * Examine the authority section (if there is one). * * We expect there to be only one owner name for all the rdatasets * in this section, and we expect that it is not external. */ done = ISC_FALSE; ns_name = NULL; ns_rdataset = NULL; result = dns_message_firstname(message, DNS_SECTION_AUTHORITY); while (!done && result == ISC_R_SUCCESS) { name = NULL; dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name); external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain)); if (!external) { /* * We expect to find NS or SIG NS rdatasets, and * nothing else. */ for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (rdataset->type == dns_rdatatype_ns || (rdataset->type == dns_rdatatype_rrsig && rdataset->covers == dns_rdatatype_ns)) { name->attributes |= DNS_NAMEATTR_CACHE; rdataset->attributes |= DNS_RDATASETATTR_CACHE; if (aa && !chaining) rdataset->trust = dns_trust_authauthority; else rdataset->trust = dns_trust_additional; if (rdataset->type == dns_rdatatype_ns) { ns_name = name; ns_rdataset = rdataset; } /* * Mark any additional data related * to this rdataset. */ (void)dns_rdataset_additionaldata( rdataset, check_related, fctx); done = ISC_TRUE; } } } result = dns_message_nextname(message, DNS_SECTION_AUTHORITY); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; log_ns_ttl(fctx, "answer_response"); if (ns_rdataset != NULL && dns_name_equal(&fctx->domain, ns_name) && !dns_name_equal(ns_name, dns_rootname)) trim_ns_ttl(fctx, ns_name, ns_rdataset); return (result); } static void fctx_increference(fetchctx_t *fctx) { REQUIRE(VALID_FCTX(fctx)); LOCK(&fctx->res->buckets[fctx->bucketnum].lock); fctx->references++; UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock); } static isc_boolean_t fctx_decreference(fetchctx_t *fctx) { isc_boolean_t bucket_empty = ISC_FALSE; REQUIRE(VALID_FCTX(fctx)); INSIST(fctx->references > 0); fctx->references--; if (fctx->references == 0) { /* * No one cares about the result of this fetch anymore. */ if (fctx->pending == 0 && fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators) && SHUTTINGDOWN(fctx)) { /* * This fctx is already shutdown; we were just * waiting for the last reference to go away. */ bucket_empty = fctx_unlink(fctx); fctx_destroy(fctx); } else { /* * Initiate shutdown. */ fctx_shutdown(fctx); } } return (bucket_empty); } static void resume_dslookup(isc_task_t *task, isc_event_t *event) { dns_fetchevent_t *fevent; dns_resolver_t *res; fetchctx_t *fctx; isc_result_t result; isc_boolean_t bucket_empty; isc_boolean_t locked = ISC_FALSE; unsigned int bucketnum; dns_rdataset_t nameservers; dns_fixedname_t fixed; dns_name_t *domain; REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); fevent = (dns_fetchevent_t *)event; fctx = event->ev_arg; REQUIRE(VALID_FCTX(fctx)); res = fctx->res; UNUSED(task); FCTXTRACE("resume_dslookup"); if (fevent->node != NULL) dns_db_detachnode(fevent->db, &fevent->node); if (fevent->db != NULL) dns_db_detach(&fevent->db); dns_rdataset_init(&nameservers); bucketnum = fctx->bucketnum; if (fevent->result == ISC_R_CANCELED) { dns_resolver_destroyfetch(&fctx->nsfetch); fctx_done(fctx, ISC_R_CANCELED, __LINE__); } else if (fevent->result == ISC_R_SUCCESS) { FCTXTRACE("resuming DS lookup"); dns_resolver_destroyfetch(&fctx->nsfetch); if (dns_rdataset_isassociated(&fctx->nameservers)) dns_rdataset_disassociate(&fctx->nameservers); dns_rdataset_clone(fevent->rdataset, &fctx->nameservers); fctx->ns_ttl = fctx->nameservers.ttl; fctx->ns_ttl_ok = ISC_TRUE; log_ns_ttl(fctx, "resume_dslookup"); #ifdef ENABLE_FETCHLIMIT fcount_decr(fctx); #endif /* ENABLE_FETCHLIMIT */ dns_name_free(&fctx->domain, fctx->mctx); dns_name_init(&fctx->domain, NULL); result = dns_name_dup(&fctx->nsname, fctx->mctx, &fctx->domain); if (result != ISC_R_SUCCESS) { fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); goto cleanup; } #ifdef ENABLE_FETCHLIMIT result = fcount_incr(fctx, ISC_TRUE); if (result != ISC_R_SUCCESS) { fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); goto cleanup; } #endif /* ENABLE_FETCHLIMIT */ /* * Try again. */ fctx_try(fctx, ISC_TRUE, ISC_FALSE); } else { unsigned int n; dns_rdataset_t *nsrdataset = NULL; /* * Retrieve state from fctx->nsfetch before we destroy it. */ dns_fixedname_init(&fixed); domain = dns_fixedname_name(&fixed); dns_name_copy(&fctx->nsfetch->private->domain, domain, NULL); if (dns_name_equal(&fctx->nsname, domain)) { fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); dns_resolver_destroyfetch(&fctx->nsfetch); goto cleanup; } if (dns_rdataset_isassociated( &fctx->nsfetch->private->nameservers)) { dns_rdataset_clone( &fctx->nsfetch->private->nameservers, &nameservers); nsrdataset = &nameservers; } else domain = NULL; dns_resolver_destroyfetch(&fctx->nsfetch); n = dns_name_countlabels(&fctx->nsname); dns_name_getlabelsequence(&fctx->nsname, 1, n - 1, &fctx->nsname); if (dns_rdataset_isassociated(fevent->rdataset)) dns_rdataset_disassociate(fevent->rdataset); FCTXTRACE("continuing to look for parent's NS records"); result = dns_resolver_createfetch(fctx->res, &fctx->nsname, dns_rdatatype_ns, domain, nsrdataset, NULL, fctx->options, task, resume_dslookup, fctx, &fctx->nsrrset, NULL, &fctx->nsfetch); if (result != ISC_R_SUCCESS) fctx_done(fctx, result, __LINE__); else { LOCK(&res->buckets[bucketnum].lock); locked = ISC_TRUE; fctx->references++; } } cleanup: if (dns_rdataset_isassociated(&nameservers)) dns_rdataset_disassociate(&nameservers); if (dns_rdataset_isassociated(fevent->rdataset)) dns_rdataset_disassociate(fevent->rdataset); INSIST(fevent->sigrdataset == NULL); isc_event_free(&event); if (!locked) LOCK(&res->buckets[bucketnum].lock); bucket_empty = fctx_decreference(fctx); UNLOCK(&res->buckets[bucketnum].lock); if (bucket_empty) empty_bucket(res); } static inline void checknamessection(dns_message_t *message, dns_section_t section) { isc_result_t result; dns_name_t *name; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_t *rdataset; for (result = dns_message_firstname(message, section); result == ISC_R_SUCCESS; result = dns_message_nextname(message, section)) { name = NULL; dns_message_currentname(message, section, &name); for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdataset_current(rdataset, &rdata); if (!dns_rdata_checkowner(name, rdata.rdclass, rdata.type, ISC_FALSE) || !dns_rdata_checknames(&rdata, name, NULL)) { rdataset->attributes |= DNS_RDATASETATTR_CHECKNAMES; } dns_rdata_reset(&rdata); } } } } static void checknames(dns_message_t *message) { checknamessection(message, DNS_SECTION_ANSWER); checknamessection(message, DNS_SECTION_AUTHORITY); checknamessection(message, DNS_SECTION_ADDITIONAL); } /* * Log server NSID at log level 'level' */ static void log_nsid(isc_buffer_t *opt, size_t nsid_len, resquery_t *query, int level, isc_mem_t *mctx) { static const char hex[17] = "0123456789abcdef"; char addrbuf[ISC_SOCKADDR_FORMATSIZE]; isc_uint16_t buflen, i; unsigned char *p, *nsid; unsigned char *buf = NULL, *pbuf = NULL; /* Allocate buffer for storing hex version of the NSID */ buflen = (isc_uint16_t)nsid_len * 2 + 1; buf = isc_mem_get(mctx, buflen); if (buf == NULL) goto cleanup; pbuf = isc_mem_get(mctx, nsid_len + 1); if (pbuf == NULL) goto cleanup; /* Convert to hex */ p = buf; nsid = isc_buffer_current(opt); for (i = 0; i < nsid_len; i++) { *p++ = hex[(nsid[i] >> 4) & 0xf]; *p++ = hex[nsid[i] & 0xf]; } *p = '\0'; /* Make printable version */ p = pbuf; for (i = 0; i < nsid_len; i++) { if (isprint(nsid[i])) *p++ = nsid[i]; else *p++ = '.'; } *p = '\0'; isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf, sizeof(addrbuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, level, "received NSID %s (\"%s\") from %s", buf, pbuf, addrbuf); cleanup: if (pbuf != NULL) isc_mem_put(mctx, pbuf, nsid_len + 1); if (buf != NULL) isc_mem_put(mctx, buf, buflen); } static isc_boolean_t iscname(fetchctx_t *fctx) { isc_result_t result; result = dns_message_findname(fctx->rmessage, DNS_SECTION_ANSWER, &fctx->name, dns_rdatatype_cname, 0, NULL, NULL); return (result == ISC_R_SUCCESS ? ISC_TRUE : ISC_FALSE); } static isc_boolean_t betterreferral(fetchctx_t *fctx) { isc_result_t result; dns_name_t *name; dns_rdataset_t *rdataset; dns_message_t *message = fctx->rmessage; for (result = dns_message_firstname(message, DNS_SECTION_AUTHORITY); result == ISC_R_SUCCESS; result = dns_message_nextname(message, DNS_SECTION_AUTHORITY)) { name = NULL; dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name); if (!isstrictsubdomain(name, &fctx->domain)) continue; for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) if (rdataset->type == dns_rdatatype_ns) return (ISC_TRUE); } return (ISC_FALSE); } static void process_opt(resquery_t *query, dns_rdataset_t *opt) { dns_rdata_t rdata; isc_buffer_t optbuf; isc_result_t result; isc_uint16_t optcode; isc_uint16_t optlen; #ifdef ISC_PLATFORM_USESIT unsigned char *sit; dns_adbaddrinfo_t *addrinfo; unsigned char cookie[8]; isc_boolean_t seen_cookie = ISC_FALSE; #endif isc_boolean_t seen_nsid = ISC_FALSE; result = dns_rdataset_first(opt); if (result == ISC_R_SUCCESS) { dns_rdata_init(&rdata); dns_rdataset_current(opt, &rdata); isc_buffer_init(&optbuf, rdata.data, rdata.length); isc_buffer_add(&optbuf, rdata.length); while (isc_buffer_remaininglength(&optbuf) >= 4) { optcode = isc_buffer_getuint16(&optbuf); optlen = isc_buffer_getuint16(&optbuf); INSIST(optlen <= isc_buffer_remaininglength(&optbuf)); switch (optcode) { case DNS_OPT_NSID: if (!seen_nsid && query->options & DNS_FETCHOPT_WANTNSID) log_nsid(&optbuf, optlen, query, ISC_LOG_DEBUG(3), query->fctx->res->mctx); isc_buffer_forward(&optbuf, optlen); seen_nsid = ISC_TRUE; break; #ifdef ISC_PLATFORM_USESIT case DNS_OPT_COOKIE: /* * Only process the first cookie option. */ if (seen_cookie) { isc_buffer_forward(&optbuf, optlen); break; } sit = isc_buffer_current(&optbuf); compute_cc(query, cookie, sizeof(cookie)); INSIST(query->fctx->rmessage->sitbad == 0 && query->fctx->rmessage->sitok == 0); if (optlen >= 8U && memcmp(cookie, sit, 8) == 0) { query->fctx->rmessage->sitok = 1; inc_stats(query->fctx->res, dns_resstatscounter_sitok); addrinfo = query->addrinfo; dns_adb_setsit(query->fctx->adb, addrinfo, sit, optlen); } else query->fctx->rmessage->sitbad = 1; isc_buffer_forward(&optbuf, optlen); inc_stats(query->fctx->res, dns_resstatscounter_sitin); seen_cookie = ISC_TRUE; break; #endif default: isc_buffer_forward(&optbuf, optlen); break; } } INSIST(isc_buffer_remaininglength(&optbuf) == 0U); } } static void resquery_response(isc_task_t *task, isc_event_t *event) { isc_result_t result = ISC_R_SUCCESS; resquery_t *query = event->ev_arg; dns_dispatchevent_t *devent = (dns_dispatchevent_t *)event; isc_boolean_t keep_trying, get_nameservers, resend; isc_boolean_t truncated; dns_message_t *message; dns_rdataset_t *opt; fetchctx_t *fctx; dns_name_t *fname; dns_fixedname_t foundname; isc_stdtime_t now; isc_time_t tnow, *finish; dns_adbaddrinfo_t *addrinfo; unsigned int options; unsigned int findoptions; isc_result_t broken_server; badnstype_t broken_type = badns_response; isc_boolean_t no_response; unsigned int bucketnum; dns_resolver_t *res; isc_boolean_t bucket_empty; REQUIRE(VALID_QUERY(query)); fctx = query->fctx; options = query->options; REQUIRE(VALID_FCTX(fctx)); REQUIRE(event->ev_type == DNS_EVENT_DISPATCH); QTRACE("response"); res = fctx->res; if (isc_sockaddr_pf(&query->addrinfo->sockaddr) == PF_INET) inc_stats(res, dns_resstatscounter_responsev4); else inc_stats(res, dns_resstatscounter_responsev6); (void)isc_timer_touch(fctx->timer); keep_trying = ISC_FALSE; broken_server = ISC_R_SUCCESS; get_nameservers = ISC_FALSE; resend = ISC_FALSE; truncated = ISC_FALSE; finish = NULL; no_response = ISC_FALSE; if (res->exiting) { result = ISC_R_SHUTTINGDOWN; FCTXTRACE("resolver shutting down"); goto done; } fctx->timeouts = 0; fctx->timeout = ISC_FALSE; fctx->addrinfo = query->addrinfo; /* * XXXRTH We should really get the current time just once. We * need a routine to convert from an isc_time_t to an * isc_stdtime_t. */ TIME_NOW(&tnow); finish = &tnow; isc_stdtime_get(&now); /* * Did the dispatcher have a problem? */ if (devent->result != ISC_R_SUCCESS) { if (devent->result == ISC_R_EOF && (query->options & DNS_FETCHOPT_NOEDNS0) == 0) { /* * The problem might be that they * don't understand EDNS0. Turn it * off and try again. */ options |= DNS_FETCHOPT_NOEDNS0; resend = ISC_TRUE; add_bad_edns(fctx, &query->addrinfo->sockaddr); } else { /* * There's no hope for this query. */ keep_trying = ISC_TRUE; /* * If this is a network error on an exclusive query * socket, mark the server as bad so that we won't try * it for this fetch again. Also adjust finish and * no_response so that we penalize this address in SRTT * adjustment later. */ if (query->exclusivesocket && (devent->result == ISC_R_HOSTUNREACH || devent->result == ISC_R_NETUNREACH || devent->result == ISC_R_CONNREFUSED || devent->result == ISC_R_CANCELED)) { broken_server = devent->result; broken_type = badns_unreachable; finish = NULL; no_response = ISC_TRUE; } } FCTXTRACE3("dispatcher failure", devent->result); goto done; } message = fctx->rmessage; if (query->tsig != NULL) { result = dns_message_setquerytsig(message, query->tsig); if (result != ISC_R_SUCCESS) { FCTXTRACE3("unable to set query tsig", result); goto done; } } if (query->tsigkey) { result = dns_message_settsigkey(message, query->tsigkey); if (result != ISC_R_SUCCESS) { FCTXTRACE3("unable to set tsig key", result); goto done; } } dns_message_setclass(message, fctx->res->rdclass); if ((options & DNS_FETCHOPT_TCP) == 0) { if ((options & DNS_FETCHOPT_NOEDNS0) == 0) dns_adb_setudpsize(fctx->adb, query->addrinfo, isc_buffer_usedlength(&devent->buffer)); else dns_adb_plainresponse(fctx->adb, query->addrinfo); } result = dns_message_parse(message, &devent->buffer, 0); if (result != ISC_R_SUCCESS) { FCTXTRACE3("message failed to parse", result); switch (result) { case ISC_R_UNEXPECTEDEND: if (!message->question_ok || (message->flags & DNS_MESSAGEFLAG_TC) == 0 || (options & DNS_FETCHOPT_TCP) != 0) { /* * Either the message ended prematurely, * and/or wasn't marked as being truncated, * and/or this is a response to a query we * sent over TCP. In all of these cases, * something is wrong with the remote * server and we don't want to retry using * TCP. */ if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) { /* * The problem might be that they * don't understand EDNS0. Turn it * off and try again. */ options |= DNS_FETCHOPT_NOEDNS0; resend = ISC_TRUE; add_bad_edns(fctx, &query->addrinfo->sockaddr); inc_stats(res, dns_resstatscounter_edns0fail); } else { broken_server = result; keep_trying = ISC_TRUE; } goto done; } /* * We defer retrying via TCP for a bit so we can * check out this message further. */ truncated = ISC_TRUE; break; case DNS_R_FORMERR: if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) { /* * The problem might be that they * don't understand EDNS0. Turn it * off and try again. */ options |= DNS_FETCHOPT_NOEDNS0; resend = ISC_TRUE; add_bad_edns(fctx, &query->addrinfo->sockaddr); inc_stats(res, dns_resstatscounter_edns0fail); } else { broken_server = DNS_R_UNEXPECTEDRCODE; keep_trying = ISC_TRUE; } goto done; default: /* * Something bad has happened. */ goto done; } } /* * Log the incoming packet. */ dns_message_logfmtpacket(message, "received packet:\n", DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_PACKETS, &dns_master_style_comment, ISC_LOG_DEBUG(10), fctx->res->mctx); if (message->rdclass != res->rdclass) { resend = ISC_TRUE; FCTXTRACE("bad class"); goto done; } /* * Process receive opt record. */ opt = dns_message_getopt(message); if (opt != NULL) process_opt(query, opt); #ifdef notyet #ifdef ISC_PLATFORM_USESIT if (message->sitbad) { /* * If the SIT is bad assume it is a attack and retry. */ resend = ISC_TRUE; /* XXXMPA log it */ FCTXTRACE("bad sit"); goto done; } #endif #endif /* * If the message is signed, check the signature. If not, this * returns success anyway. */ result = dns_message_checksig(message, res->view); if (result != ISC_R_SUCCESS) { FCTXTRACE3("signature check failed", result); goto done; } /* * The dispatcher should ensure we only get responses with QR set. */ INSIST((message->flags & DNS_MESSAGEFLAG_QR) != 0); /* * INSIST() that the message comes from the place we sent it to, * since the dispatch code should ensure this. * * INSIST() that the message id is correct (this should also be * ensured by the dispatch code). */ /* * We have an affirmative response to the query and we have * previously got a response from this server which indicated * EDNS may not be supported so we can now cache the lack of * EDNS support. */ if (opt == NULL && !EDNSOK(query->addrinfo) && (message->rcode == dns_rcode_noerror || message->rcode == dns_rcode_nxdomain || message->rcode == dns_rcode_refused || message->rcode == dns_rcode_yxdomain) && bad_edns(fctx, &query->addrinfo->sockaddr)) { if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { char buf[4096], addrbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf, sizeof(addrbuf)); snprintf(buf, sizeof(buf), "received packet from %s (bad edns):\n", addrbuf); dns_message_logpacket(message, buf, DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3), res->mctx); } dns_adb_changeflags(fctx->adb, query->addrinfo, DNS_FETCHOPT_NOEDNS0, DNS_FETCHOPT_NOEDNS0); } else if (opt == NULL && (message->flags & DNS_MESSAGEFLAG_TC) == 0 && !EDNSOK(query->addrinfo) && (message->rcode == dns_rcode_noerror || message->rcode == dns_rcode_nxdomain) && (query->options & DNS_FETCHOPT_NOEDNS0) == 0) { /* * We didn't get a OPT record in response to a EDNS query. * * Old versions of named incorrectly drop the OPT record * when there is a signed, truncated response so we check * that TC is not set. * * Record that the server is not talking EDNS. While this * should be safe to do for any rcode we limit it to NOERROR * and NXDOMAIN. */ if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { char buf[4096], addrbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf, sizeof(addrbuf)); snprintf(buf, sizeof(buf), "received packet from %s (no opt):\n", addrbuf); dns_message_logpacket(message, buf, DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3), res->mctx); } dns_adb_changeflags(fctx->adb, query->addrinfo, DNS_FETCHOPT_NOEDNS0, DNS_FETCHOPT_NOEDNS0); } /* * If we get a non error EDNS response record the fact so we * won't fallback to plain DNS in the future for this server. */ if (opt != NULL && !EDNSOK(query->addrinfo) && (query->options & DNS_FETCHOPT_NOEDNS0) == 0 && (message->rcode == dns_rcode_noerror || message->rcode == dns_rcode_nxdomain || message->rcode == dns_rcode_refused || message->rcode == dns_rcode_yxdomain)) { dns_adb_changeflags(fctx->adb, query->addrinfo, FCTX_ADDRINFO_EDNSOK, FCTX_ADDRINFO_EDNSOK); } /* * Deal with truncated responses by retrying using TCP. */ if ((message->flags & DNS_MESSAGEFLAG_TC) != 0) truncated = ISC_TRUE; if (truncated) { inc_stats(res, dns_resstatscounter_truncated); if ((options & DNS_FETCHOPT_TCP) != 0) { broken_server = DNS_R_TRUNCATEDTCP; keep_trying = ISC_TRUE; } else { options |= DNS_FETCHOPT_TCP; resend = ISC_TRUE; } FCTXTRACE3("message truncated", result); goto done; } /* * Is it a query response? */ if (message->opcode != dns_opcode_query) { /* XXXRTH Log */ broken_server = DNS_R_UNEXPECTEDOPCODE; keep_trying = ISC_TRUE; FCTXTRACE("invalid message opcode"); goto done; } /* * Update statistics about erroneous responses. */ if (message->rcode != dns_rcode_noerror) { switch (message->rcode) { case dns_rcode_nxdomain: inc_stats(res, dns_resstatscounter_nxdomain); break; case dns_rcode_servfail: inc_stats(res, dns_resstatscounter_servfail); break; case dns_rcode_formerr: inc_stats(res, dns_resstatscounter_formerr); break; case dns_rcode_refused: inc_stats(res, dns_resstatscounter_refused); break; case dns_rcode_badvers: inc_stats(res, dns_resstatscounter_badvers); break; default: inc_stats(res, dns_resstatscounter_othererror); break; } } /* * Is the remote server broken, or does it dislike us? */ if (message->rcode != dns_rcode_noerror && message->rcode != dns_rcode_nxdomain) { isc_buffer_t b; char code[64]; #ifdef ISC_PLATFORM_USESIT unsigned char sit[64]; /* * Some servers do not ignore unknown EDNS options. */ if (!NOSIT(query->addrinfo) && (message->rcode == dns_rcode_formerr || message->rcode == dns_rcode_notimp || message->rcode == dns_rcode_refused) && dns_adb_getsit(fctx->adb, query->addrinfo, sit, sizeof(sit)) == 0U) { dns_adb_changeflags(fctx->adb, query->addrinfo, FCTX_ADDRINFO_NOSIT, FCTX_ADDRINFO_NOSIT); resend = ISC_TRUE; } else #endif if (((message->rcode == dns_rcode_formerr || message->rcode == dns_rcode_notimp) || (message->rcode == dns_rcode_servfail && dns_message_getopt(message) == NULL)) && (query->options & DNS_FETCHOPT_NOEDNS0) == 0) { /* * It's very likely they don't like EDNS0. * If the response code is SERVFAIL, also check if the * response contains an OPT RR and don't cache the * failure since it can be returned for various other * reasons. * * XXXRTH We should check if the question * we're asking requires EDNS0, and * if so, we should bail out. */ options |= DNS_FETCHOPT_NOEDNS0; resend = ISC_TRUE; /* * Remember that they may not like EDNS0. */ add_bad_edns(fctx, &query->addrinfo->sockaddr); inc_stats(res, dns_resstatscounter_edns0fail); } else if (message->rcode == dns_rcode_formerr) { if (ISFORWARDER(query->addrinfo)) { /* * This forwarder doesn't understand us, * but other forwarders might. Keep trying. */ broken_server = DNS_R_REMOTEFORMERR; keep_trying = ISC_TRUE; } else { /* * The server doesn't understand us. Since * all servers for a zone need similar * capabilities, we assume that we will get * FORMERR from all servers, and thus we * cannot make any more progress with this * fetch. */ log_formerr(fctx, "server sent FORMERR"); result = DNS_R_FORMERR; } } else if (message->rcode == dns_rcode_yxdomain) { /* * DNAME mapping failed because the new name * was too long. There's no chance of success * for this fetch. */ result = DNS_R_YXDOMAIN; } else if (message->rcode == dns_rcode_badvers) { unsigned int flags, mask; unsigned int version; #ifdef ISC_PLATFORM_USESIT isc_boolean_t nosit = ISC_FALSE; /* * Some servers return BADVERS to unknown * EDNS options. This cannot be long term * strategy. Do not disable SIT if we have * already have received a SIT from this * server. */ if (dns_adb_getsit(fctx->adb, query->addrinfo, sit, sizeof(sit)) == 0U) { if (!NOSIT(query->addrinfo)) nosit = ISC_TRUE; dns_adb_changeflags(fctx->adb, query->addrinfo, FCTX_ADDRINFO_NOSIT, FCTX_ADDRINFO_NOSIT); } #endif INSIST(opt != NULL); version = (opt->ttl >> 16) & 0xff; flags = (version << DNS_FETCHOPT_EDNSVERSIONSHIFT) | DNS_FETCHOPT_EDNSVERSIONSET; mask = DNS_FETCHOPT_EDNSVERSIONMASK | DNS_FETCHOPT_EDNSVERSIONSET; /* * Record that we got a good EDNS response. */ if (query->ednsversion > (int)version && !EDNSOK(query->addrinfo)) { dns_adb_changeflags(fctx->adb, query->addrinfo, FCTX_ADDRINFO_EDNSOK, FCTX_ADDRINFO_EDNSOK); } /* * Record the supported EDNS version. */ switch (version) { case 0: dns_adb_changeflags(fctx->adb, query->addrinfo, flags, mask); #ifdef ISC_PLATFORM_USESIT if (nosit) { resend = ISC_TRUE; break; } #endif /* FALLTHROUGH */ default: broken_server = DNS_R_BADVERS; keep_trying = ISC_TRUE; break; } } else if (message->rcode == dns_rcode_badcookie && message->sitok) { /* * We have recorded the new cookie. */ if (BADCOOKIE(query->addrinfo)) query->options |= DNS_FETCHOPT_TCP; query->addrinfo->flags |= FCTX_ADDRINFO_BADCOOKIE; resend = ISC_TRUE; } else { /* * XXXRTH log. */ broken_server = DNS_R_UNEXPECTEDRCODE; INSIST(broken_server != ISC_R_SUCCESS); keep_trying = ISC_TRUE; } isc_buffer_init(&b, code, sizeof(code) - 1); dns_rcode_totext(fctx->rmessage->rcode, &b); code[isc_buffer_usedlength(&b)] = '\0'; FCTXTRACE2("remote server broken: returned ", code); goto done; } /* * Is the question the same as the one we asked? */ result = same_question(fctx); if (result != ISC_R_SUCCESS) { /* XXXRTH Log */ if (result == DNS_R_FORMERR) keep_trying = ISC_TRUE; FCTXTRACE3("response did not match question", result); goto done; } /* * Is the server lame? */ if (res->lame_ttl != 0 && !ISFORWARDER(query->addrinfo) && is_lame(fctx)) { inc_stats(res, dns_resstatscounter_lame); log_lame(fctx, query->addrinfo); result = dns_adb_marklame(fctx->adb, query->addrinfo, &fctx->name, fctx->type, now + res->lame_ttl); if (result != ISC_R_SUCCESS) isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, ISC_LOG_ERROR, "could not mark server as lame: %s", isc_result_totext(result)); broken_server = DNS_R_LAME; keep_trying = ISC_TRUE; FCTXTRACE("lame server"); goto done; } /* * Enforce delegations only zones like NET and COM. */ if (!ISFORWARDER(query->addrinfo) && dns_view_isdelegationonly(res->view, &fctx->domain) && !dns_name_equal(&fctx->domain, &fctx->name) && fix_mustbedelegationornxdomain(message, fctx)) { char namebuf[DNS_NAME_FORMATSIZE]; char domainbuf[DNS_NAME_FORMATSIZE]; char addrbuf[ISC_SOCKADDR_FORMATSIZE]; char classbuf[64]; char typebuf[64]; dns_name_format(&fctx->name, namebuf, sizeof(namebuf)); dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf)); dns_rdatatype_format(fctx->type, typebuf, sizeof(typebuf)); dns_rdataclass_format(res->rdclass, classbuf, sizeof(classbuf)); isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf, sizeof(addrbuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DELEGATION_ONLY, DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, "enforced delegation-only for '%s' (%s/%s/%s) " "from %s", domainbuf, namebuf, typebuf, classbuf, addrbuf); } if ((res->options & DNS_RESOLVER_CHECKNAMES) != 0) checknames(message); /* * Clear cache bits. */ fctx->attributes &= ~(FCTX_ATTR_WANTNCACHE | FCTX_ATTR_WANTCACHE); /* * Did we get any answers? */ if (message->counts[DNS_SECTION_ANSWER] > 0 && (message->rcode == dns_rcode_noerror || message->rcode == dns_rcode_nxdomain)) { /* * [normal case] * We've got answers. If it has an authoritative answer or an * answer from a forwarder, we're done. */ if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 || ISFORWARDER(query->addrinfo)) { result = answer_response(fctx); if (result != ISC_R_SUCCESS) FCTXTRACE3("answer_response (AA/fwd)", result); } else if (iscname(fctx) && fctx->type != dns_rdatatype_any && fctx->type != dns_rdatatype_cname) { /* * A BIND8 server could return a non-authoritative * answer when a CNAME is followed. We should treat * it as a valid answer. */ result = answer_response(fctx); if (result != ISC_R_SUCCESS) FCTXTRACE3("answer_response (!ANY/!CNAME)", result); } else if (fctx->type != dns_rdatatype_ns && !betterreferral(fctx)) { /* * Lame response !!!. */ result = answer_response(fctx); if (result != ISC_R_SUCCESS) FCTXTRACE3("answer_response (!NS)", result); } else { if (fctx->type == dns_rdatatype_ns) { /* * A BIND 8 server could incorrectly return a * non-authoritative answer to an NS query * instead of a referral. Since this answer * lacks the SIGs necessary to do DNSSEC * validation, we must invoke the following * special kludge to treat it as a referral. */ result = noanswer_response(fctx, NULL, LOOK_FOR_NS_IN_ANSWER); if (result != ISC_R_SUCCESS) FCTXTRACE3("noanswer_response (NS)", result); } else { /* * Some other servers may still somehow include * an answer when it should return a referral * with an empty answer. Check to see if we can * treat this as a referral by ignoring the * answer. Further more, there may be an * implementation that moves A/AAAA glue records * to the answer section for that type of * delegation when the query is for that glue * record. LOOK_FOR_GLUE_IN_ANSWER will handle * such a corner case. */ result = noanswer_response(fctx, NULL, LOOK_FOR_GLUE_IN_ANSWER); if (result != ISC_R_SUCCESS) FCTXTRACE3("noanswer_response", result); } if (result != DNS_R_DELEGATION) { /* * At this point, AA is not set, the response * is not a referral, and the server is not a * forwarder. It is technically lame and it's * easier to treat it as such than to figure out * some more elaborate course of action. */ broken_server = DNS_R_LAME; keep_trying = ISC_TRUE; goto done; } goto force_referral; } if (result != ISC_R_SUCCESS) { if (result == DNS_R_FORMERR) keep_trying = ISC_TRUE; goto done; } } else if (message->counts[DNS_SECTION_AUTHORITY] > 0 || message->rcode == dns_rcode_noerror || message->rcode == dns_rcode_nxdomain) { /* * NXDOMAIN, NXRDATASET, or referral. */ result = noanswer_response(fctx, NULL, 0); switch (result) { case ISC_R_SUCCESS: case DNS_R_CHASEDSSERVERS: break; case DNS_R_DELEGATION: force_referral: /* * We don't have the answer, but we know a better * place to look. */ get_nameservers = ISC_TRUE; keep_trying = ISC_TRUE; /* * We have a new set of name servers, and it * has not experienced any restarts yet. */ fctx->restarts = 0; /* * Update local statistics counters collected for each * new zone. */ fctx->referrals++; fctx->querysent = 0; fctx->lamecount = 0; fctx->quotacount = 0; fctx->neterr = 0; fctx->badresp = 0; fctx->adberr = 0; result = ISC_R_SUCCESS; break; default: /* * Something has gone wrong. */ if (result == DNS_R_FORMERR) keep_trying = ISC_TRUE; FCTXTRACE3("noanswer_response", result); goto done; } } else { /* * The server is insane. */ /* XXXRTH Log */ broken_server = DNS_R_UNEXPECTEDRCODE; keep_trying = ISC_TRUE; FCTXTRACE("broken server: unexpected rcode"); goto done; } /* * Follow additional section data chains. */ chase_additional(fctx); /* * Cache the cacheable parts of the message. This may also cause * work to be queued to the DNSSEC validator. */ if (WANTCACHE(fctx)) { result = cache_message(fctx, query->addrinfo, now); if (result != ISC_R_SUCCESS) { FCTXTRACE3("cache_message complete", result); goto done; } } /* * Ncache the negatively cacheable parts of the message. This may * also cause work to be queued to the DNSSEC validator. */ if (WANTNCACHE(fctx)) { dns_rdatatype_t covers; /* * Cache DS NXDOMAIN seperately to other types. */ if (message->rcode == dns_rcode_nxdomain && fctx->type != dns_rdatatype_ds) covers = dns_rdatatype_any; else covers = fctx->type; /* * Cache any negative cache entries in the message. */ result = ncache_message(fctx, query->addrinfo, covers, now); if (result != ISC_R_SUCCESS) FCTXTRACE3("ncache_message complete", result); } done: /* * Remember the query's addrinfo, in case we need to mark the * server as broken. */ addrinfo = query->addrinfo; FCTXTRACE4("query canceled in response(); ", no_response ? "no response" : "responding", result); /* * Cancel the query. * * XXXRTH Don't cancel the query if waiting for validation? */ fctx_cancelquery(&query, &devent, finish, no_response); if (keep_trying) { if (result == DNS_R_FORMERR) broken_server = DNS_R_FORMERR; if (broken_server != ISC_R_SUCCESS) { /* * Add this server to the list of bad servers for * this fctx. */ add_bad(fctx, addrinfo, broken_server, broken_type); } if (get_nameservers) { dns_name_t *name; dns_fixedname_init(&foundname); fname = dns_fixedname_name(&foundname); if (result != ISC_R_SUCCESS) { fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); return; } findoptions = 0; if (dns_rdatatype_atparent(fctx->type)) findoptions |= DNS_DBFIND_NOEXACT; if ((options & DNS_FETCHOPT_UNSHARED) == 0) name = &fctx->name; else name = &fctx->domain; result = dns_view_findzonecut(res->view, name, fname, now, findoptions, ISC_TRUE, &fctx->nameservers, NULL); if (result != ISC_R_SUCCESS) { FCTXTRACE("couldn't find a zonecut"); fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); return; } if (!dns_name_issubdomain(fname, &fctx->domain)) { /* * The best nameservers are now above our * QDOMAIN. */ FCTXTRACE("nameservers now above QDOMAIN"); fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); return; } #ifdef ENABLE_FETCHLIMIT fcount_decr(fctx); #endif /* ENABLE_FETCHLIMIT */ dns_name_free(&fctx->domain, fctx->mctx); dns_name_init(&fctx->domain, NULL); result = dns_name_dup(fname, fctx->mctx, &fctx->domain); if (result != ISC_R_SUCCESS) { fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); return; } #ifdef ENABLE_FETCHLIMIT result = fcount_incr(fctx, ISC_TRUE); if (result != ISC_R_SUCCESS) { fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); return; } #endif /* ENABLE_FETCHLIMIT */ fctx->ns_ttl = fctx->nameservers.ttl; fctx->ns_ttl_ok = ISC_TRUE; fctx_cancelqueries(fctx, ISC_TRUE); fctx_cleanupfinds(fctx); fctx_cleanupaltfinds(fctx); fctx_cleanupforwaddrs(fctx); fctx_cleanupaltaddrs(fctx); } /* * Try again. */ fctx_try(fctx, !get_nameservers, ISC_FALSE); } else if (resend) { /* * Resend (probably with changed options). */ FCTXTRACE("resend"); inc_stats(res, dns_resstatscounter_retry); bucketnum = fctx->bucketnum; fctx_increference(fctx); result = fctx_query(fctx, addrinfo, options); if (result != ISC_R_SUCCESS) { fctx_done(fctx, result, __LINE__); LOCK(&res->buckets[bucketnum].lock); bucket_empty = fctx_decreference(fctx); UNLOCK(&res->buckets[bucketnum].lock); if (bucket_empty) empty_bucket(res); } } else if (result == ISC_R_SUCCESS && !HAVE_ANSWER(fctx)) { /* * All has gone well so far, but we are waiting for the * DNSSEC validator to validate the answer. */ FCTXTRACE("wait for validator"); fctx_cancelqueries(fctx, ISC_TRUE); /* * We must not retransmit while the validator is working; * it has references to the current rmessage. */ result = fctx_stopidletimer(fctx); if (result != ISC_R_SUCCESS) fctx_done(fctx, result, __LINE__); } else if (result == DNS_R_CHASEDSSERVERS) { unsigned int n; add_bad(fctx, addrinfo, result, broken_type); fctx_cancelqueries(fctx, ISC_TRUE); fctx_cleanupfinds(fctx); fctx_cleanupforwaddrs(fctx); n = dns_name_countlabels(&fctx->name); dns_name_getlabelsequence(&fctx->name, 1, n - 1, &fctx->nsname); FCTXTRACE("suspending DS lookup to find parent's NS records"); result = dns_resolver_createfetch(res, &fctx->nsname, dns_rdatatype_ns, NULL, NULL, NULL, fctx->options, task, resume_dslookup, fctx, &fctx->nsrrset, NULL, &fctx->nsfetch); if (result != ISC_R_SUCCESS) fctx_done(fctx, result, __LINE__); else { fctx_increference(fctx); result = fctx_stopidletimer(fctx); if (result != ISC_R_SUCCESS) fctx_done(fctx, result, __LINE__); } } else { /* * We're done. */ fctx_done(fctx, result, __LINE__); } } /*** *** Resolver Methods ***/ static void destroy_badcache(dns_resolver_t *res) { dns_badcache_t *bad, *next; unsigned int i; if (res->badcache != NULL) { for (i = 0; i < res->badhash; i++) for (bad = res->badcache[i]; bad != NULL; bad = next) { next = bad->next; isc_mem_put(res->mctx, bad, sizeof(*bad) + bad->name.length); res->badcount--; } isc_mem_put(res->mctx, res->badcache, sizeof(*res->badcache) * res->badhash); res->badcache = NULL; res->badhash = 0; INSIST(res->badcount == 0); } } static void destroy(dns_resolver_t *res) { unsigned int i; alternate_t *a; REQUIRE(res->references == 0); REQUIRE(!res->priming); REQUIRE(res->primefetch == NULL); RTRACE("destroy"); INSIST(res->nfctx == 0); DESTROYLOCK(&res->primelock); DESTROYLOCK(&res->nlock); DESTROYLOCK(&res->lock); for (i = 0; i < res->nbuckets; i++) { INSIST(ISC_LIST_EMPTY(res->buckets[i].fctxs)); isc_task_shutdown(res->buckets[i].task); isc_task_detach(&res->buckets[i].task); DESTROYLOCK(&res->buckets[i].lock); isc_mem_detach(&res->buckets[i].mctx); } isc_mem_put(res->mctx, res->buckets, res->nbuckets * sizeof(fctxbucket_t)); #ifdef ENABLE_FETCHLIMIT for (i = 0; i < RES_DOMAIN_BUCKETS; i++) { INSIST(ISC_LIST_EMPTY(res->dbuckets[i].list)); isc_mem_detach(&res->dbuckets[i].mctx); DESTROYLOCK(&res->dbuckets[i].lock); } isc_mem_put(res->mctx, res->dbuckets, RES_DOMAIN_BUCKETS * sizeof(zonebucket_t)); #endif /* ENABLE_FETCHLIMIT */ if (res->dispatches4 != NULL) dns_dispatchset_destroy(&res->dispatches4); if (res->dispatches6 != NULL) dns_dispatchset_destroy(&res->dispatches6); while ((a = ISC_LIST_HEAD(res->alternates)) != NULL) { ISC_LIST_UNLINK(res->alternates, a, link); if (!a->isaddress) dns_name_free(&a->_u._n.name, res->mctx); isc_mem_put(res->mctx, a, sizeof(*a)); } dns_resolver_reset_algorithms(res); dns_resolver_reset_ds_digests(res); destroy_badcache(res); dns_resolver_resetmustbesecure(res); #if USE_ALGLOCK isc_rwlock_destroy(&res->alglock); #endif #if USE_MBSLOCK isc_rwlock_destroy(&res->mbslock); #endif isc_timer_detach(&res->spillattimer); res->magic = 0; isc_mem_put(res->mctx, res, sizeof(*res)); } static void send_shutdown_events(dns_resolver_t *res) { isc_event_t *event, *next_event; isc_task_t *etask; /* * Caller must be holding the resolver lock. */ for (event = ISC_LIST_HEAD(res->whenshutdown); event != NULL; event = next_event) { next_event = ISC_LIST_NEXT(event, ev_link); ISC_LIST_UNLINK(res->whenshutdown, event, ev_link); etask = event->ev_sender; event->ev_sender = res; isc_task_sendanddetach(&etask, &event); } } static void empty_bucket(dns_resolver_t *res) { RTRACE("empty_bucket"); LOCK(&res->lock); INSIST(res->activebuckets > 0); res->activebuckets--; if (res->activebuckets == 0) send_shutdown_events(res); UNLOCK(&res->lock); } static void spillattimer_countdown(isc_task_t *task, isc_event_t *event) { dns_resolver_t *res = event->ev_arg; isc_result_t result; unsigned int count; isc_boolean_t logit = ISC_FALSE; REQUIRE(VALID_RESOLVER(res)); UNUSED(task); LOCK(&res->lock); INSIST(!res->exiting); if (res->spillat > res->spillatmin) { res->spillat--; logit = ISC_TRUE; } if (res->spillat <= res->spillatmin) { result = isc_timer_reset(res->spillattimer, isc_timertype_inactive, NULL, NULL, ISC_TRUE); RUNTIME_CHECK(result == ISC_R_SUCCESS); } count = res->spillat; UNLOCK(&res->lock); if (logit) isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, "clients-per-query decreased to %u", count); isc_event_free(&event); } isc_result_t dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr, unsigned int ntasks, unsigned int ndisp, isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr, unsigned int options, dns_dispatchmgr_t *dispatchmgr, dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6, dns_resolver_t **resp) { dns_resolver_t *res; isc_result_t result = ISC_R_SUCCESS; unsigned int i, buckets_created = 0; isc_task_t *task = NULL; char name[16]; unsigned dispattr; #ifdef ENABLE_FETCHLIMIT unsigned int dbuckets_created = 0; #endif /* ENABLE_FETCHLIMIT */ /* * Create a resolver. */ REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(ntasks > 0); REQUIRE(ndisp > 0); REQUIRE(resp != NULL && *resp == NULL); REQUIRE(dispatchmgr != NULL); REQUIRE(dispatchv4 != NULL || dispatchv6 != NULL); res = isc_mem_get(view->mctx, sizeof(*res)); if (res == NULL) return (ISC_R_NOMEMORY); RTRACE("create"); res->mctx = view->mctx; res->rdclass = view->rdclass; res->socketmgr = socketmgr; res->timermgr = timermgr; res->taskmgr = taskmgr; res->dispatchmgr = dispatchmgr; res->view = view; res->options = options; res->lame_ttl = 0; ISC_LIST_INIT(res->alternates); res->udpsize = RECV_BUFFER_SIZE; res->algorithms = NULL; res->digests = NULL; res->badcache = NULL; res->badcount = 0; res->badhash = 0; res->badsweep = 0; res->mustbesecure = NULL; res->spillatmin = res->spillat = 10; res->spillatmax = 100; res->spillattimer = NULL; res->zspill = 0; res->zero_no_soa_ttl = ISC_FALSE; res->query_timeout = DEFAULT_QUERY_TIMEOUT; res->maxdepth = DEFAULT_RECURSION_DEPTH; res->maxqueries = DEFAULT_MAX_QUERIES; res->quotaresp[dns_quotatype_zone] = DNS_R_DROP; res->quotaresp[dns_quotatype_server] = DNS_R_SERVFAIL; res->nbuckets = ntasks; if (view->resstats != NULL) isc_stats_set(view->resstats, ntasks, dns_resstatscounter_buckets); res->activebuckets = ntasks; res->buckets = isc_mem_get(view->mctx, ntasks * sizeof(fctxbucket_t)); if (res->buckets == NULL) { result = ISC_R_NOMEMORY; goto cleanup_res; } for (i = 0; i < ntasks; i++) { result = isc_mutex_init(&res->buckets[i].lock); if (result != ISC_R_SUCCESS) goto cleanup_buckets; res->buckets[i].task = NULL; result = isc_task_create(taskmgr, 0, &res->buckets[i].task); if (result != ISC_R_SUCCESS) { DESTROYLOCK(&res->buckets[i].lock); goto cleanup_buckets; } res->buckets[i].mctx = NULL; snprintf(name, sizeof(name), "res%u", i); #ifdef ISC_PLATFORM_USETHREADS /* * Use a separate memory context for each bucket to reduce * contention among multiple threads. Do this only when * enabling threads because it will be require more memory. */ result = isc_mem_create(0, 0, &res->buckets[i].mctx); if (result != ISC_R_SUCCESS) { isc_task_detach(&res->buckets[i].task); DESTROYLOCK(&res->buckets[i].lock); goto cleanup_buckets; } isc_mem_setname(res->buckets[i].mctx, name, NULL); #else isc_mem_attach(view->mctx, &res->buckets[i].mctx); #endif isc_task_setname(res->buckets[i].task, name, res); ISC_LIST_INIT(res->buckets[i].fctxs); res->buckets[i].exiting = ISC_FALSE; buckets_created++; } #ifdef ENABLE_FETCHLIMIT res->dbuckets = isc_mem_get(view->mctx, RES_DOMAIN_BUCKETS * sizeof(zonebucket_t)); if (res->dbuckets == NULL) { result = ISC_R_NOMEMORY; goto cleanup_buckets; } for (i = 0; i < RES_DOMAIN_BUCKETS; i++) { ISC_LIST_INIT(res->dbuckets[i].list); res->dbuckets[i].mctx = NULL; isc_mem_attach(view->mctx, &res->dbuckets[i].mctx); result = isc_mutex_init(&res->dbuckets[i].lock); if (result != ISC_R_SUCCESS) { isc_mem_detach(&res->dbuckets[i].mctx); goto cleanup_dbuckets; } dbuckets_created++; } #endif /* ENABLE_FETCHLIMIT */ res->dispatches4 = NULL; if (dispatchv4 != NULL) { dns_dispatchset_create(view->mctx, socketmgr, taskmgr, dispatchv4, &res->dispatches4, ndisp); dispattr = dns_dispatch_getattributes(dispatchv4); res->exclusivev4 = ISC_TF((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0); } res->dispatches6 = NULL; if (dispatchv6 != NULL) { dns_dispatchset_create(view->mctx, socketmgr, taskmgr, dispatchv6, &res->dispatches6, ndisp); dispattr = dns_dispatch_getattributes(dispatchv6); res->exclusivev6 = ISC_TF((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0); } res->querydscp4 = -1; res->querydscp6 = -1; res->references = 1; res->exiting = ISC_FALSE; res->frozen = ISC_FALSE; ISC_LIST_INIT(res->whenshutdown); res->priming = ISC_FALSE; res->primefetch = NULL; res->nfctx = 0; result = isc_mutex_init(&res->lock); if (result != ISC_R_SUCCESS) goto cleanup_dispatches; result = isc_mutex_init(&res->nlock); if (result != ISC_R_SUCCESS) goto cleanup_lock; result = isc_mutex_init(&res->primelock); if (result != ISC_R_SUCCESS) goto cleanup_nlock; task = NULL; result = isc_task_create(taskmgr, 0, &task); if (result != ISC_R_SUCCESS) goto cleanup_primelock; result = isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL, task, spillattimer_countdown, res, &res->spillattimer); isc_task_detach(&task); if (result != ISC_R_SUCCESS) goto cleanup_primelock; #if USE_ALGLOCK result = isc_rwlock_init(&res->alglock, 0, 0); if (result != ISC_R_SUCCESS) goto cleanup_spillattimer; #endif #if USE_MBSLOCK result = isc_rwlock_init(&res->mbslock, 0, 0); if (result != ISC_R_SUCCESS) goto cleanup_alglock; #endif res->magic = RES_MAGIC; *resp = res; return (ISC_R_SUCCESS); #if USE_MBSLOCK cleanup_alglock: #if USE_ALGLOCK isc_rwlock_destroy(&res->alglock); #endif #endif #if USE_ALGLOCK || USE_MBSLOCK cleanup_spillattimer: isc_timer_detach(&res->spillattimer); #endif cleanup_primelock: DESTROYLOCK(&res->primelock); cleanup_nlock: DESTROYLOCK(&res->nlock); cleanup_lock: DESTROYLOCK(&res->lock); cleanup_dispatches: if (res->dispatches6 != NULL) dns_dispatchset_destroy(&res->dispatches6); if (res->dispatches4 != NULL) dns_dispatchset_destroy(&res->dispatches4); #ifdef ENABLE_FETCHLIMIT cleanup_dbuckets: for (i = 0; i < dbuckets_created; i++) { DESTROYLOCK(&res->dbuckets[i].lock); isc_mem_detach(&res->dbuckets[i].mctx); } isc_mem_put(view->mctx, res->dbuckets, RES_DOMAIN_BUCKETS * sizeof(zonebucket_t)); #endif /* ENABLE_FETCHLIMIT*/ cleanup_buckets: for (i = 0; i < buckets_created; i++) { isc_mem_detach(&res->buckets[i].mctx); DESTROYLOCK(&res->buckets[i].lock); isc_task_shutdown(res->buckets[i].task); isc_task_detach(&res->buckets[i].task); } isc_mem_put(view->mctx, res->buckets, res->nbuckets * sizeof(fctxbucket_t)); cleanup_res: isc_mem_put(view->mctx, res, sizeof(*res)); return (result); } static void prime_done(isc_task_t *task, isc_event_t *event) { dns_resolver_t *res; dns_fetchevent_t *fevent; dns_fetch_t *fetch; dns_db_t *db = NULL; REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); fevent = (dns_fetchevent_t *)event; res = event->ev_arg; REQUIRE(VALID_RESOLVER(res)); UNUSED(task); LOCK(&res->lock); INSIST(res->priming); res->priming = ISC_FALSE; LOCK(&res->primelock); fetch = res->primefetch; res->primefetch = NULL; UNLOCK(&res->primelock); UNLOCK(&res->lock); if (fevent->result == ISC_R_SUCCESS && res->view->cache != NULL && res->view->hints != NULL) { dns_cache_attachdb(res->view->cache, &db); dns_root_checkhints(res->view, res->view->hints, db); dns_db_detach(&db); } if (fevent->node != NULL) dns_db_detachnode(fevent->db, &fevent->node); if (fevent->db != NULL) dns_db_detach(&fevent->db); if (dns_rdataset_isassociated(fevent->rdataset)) dns_rdataset_disassociate(fevent->rdataset); INSIST(fevent->sigrdataset == NULL); isc_mem_put(res->mctx, fevent->rdataset, sizeof(*fevent->rdataset)); isc_event_free(&event); dns_resolver_destroyfetch(&fetch); } void dns_resolver_prime(dns_resolver_t *res) { isc_boolean_t want_priming = ISC_FALSE; dns_rdataset_t *rdataset; isc_result_t result; REQUIRE(VALID_RESOLVER(res)); REQUIRE(res->frozen); RTRACE("dns_resolver_prime"); LOCK(&res->lock); if (!res->exiting && !res->priming) { INSIST(res->primefetch == NULL); res->priming = ISC_TRUE; want_priming = ISC_TRUE; } UNLOCK(&res->lock); if (want_priming) { /* * To avoid any possible recursive locking problems, we * start the priming fetch like any other fetch, and holding * no resolver locks. No one else will try to start it * because we're the ones who set res->priming to true. * Any other callers of dns_resolver_prime() while we're * running will see that res->priming is already true and * do nothing. */ RTRACE("priming"); rdataset = isc_mem_get(res->mctx, sizeof(*rdataset)); if (rdataset == NULL) { LOCK(&res->lock); INSIST(res->priming); INSIST(res->primefetch == NULL); res->priming = ISC_FALSE; UNLOCK(&res->lock); return; } dns_rdataset_init(rdataset); LOCK(&res->primelock); result = dns_resolver_createfetch(res, dns_rootname, dns_rdatatype_ns, NULL, NULL, NULL, 0, res->buckets[0].task, prime_done, res, rdataset, NULL, &res->primefetch); UNLOCK(&res->primelock); if (result != ISC_R_SUCCESS) { LOCK(&res->lock); INSIST(res->priming); res->priming = ISC_FALSE; UNLOCK(&res->lock); } } } void dns_resolver_freeze(dns_resolver_t *res) { /* * Freeze resolver. */ REQUIRE(VALID_RESOLVER(res)); res->frozen = ISC_TRUE; } void dns_resolver_attach(dns_resolver_t *source, dns_resolver_t **targetp) { REQUIRE(VALID_RESOLVER(source)); REQUIRE(targetp != NULL && *targetp == NULL); RRTRACE(source, "attach"); LOCK(&source->lock); REQUIRE(!source->exiting); INSIST(source->references > 0); source->references++; INSIST(source->references != 0); UNLOCK(&source->lock); *targetp = source; } void dns_resolver_whenshutdown(dns_resolver_t *res, isc_task_t *task, isc_event_t **eventp) { isc_task_t *clone; isc_event_t *event; REQUIRE(VALID_RESOLVER(res)); REQUIRE(eventp != NULL); event = *eventp; *eventp = NULL; LOCK(&res->lock); if (res->exiting && res->activebuckets == 0) { /* * We're already shutdown. Send the event. */ event->ev_sender = res; isc_task_send(task, &event); } else { clone = NULL; isc_task_attach(task, &clone); event->ev_sender = clone; ISC_LIST_APPEND(res->whenshutdown, event, ev_link); } UNLOCK(&res->lock); } void dns_resolver_shutdown(dns_resolver_t *res) { unsigned int i; fetchctx_t *fctx; isc_result_t result; REQUIRE(VALID_RESOLVER(res)); RTRACE("shutdown"); LOCK(&res->lock); if (!res->exiting) { RTRACE("exiting"); res->exiting = ISC_TRUE; for (i = 0; i < res->nbuckets; i++) { LOCK(&res->buckets[i].lock); for (fctx = ISC_LIST_HEAD(res->buckets[i].fctxs); fctx != NULL; fctx = ISC_LIST_NEXT(fctx, link)) fctx_shutdown(fctx); if (res->dispatches4 != NULL && !res->exclusivev4) { dns_dispatchset_cancelall(res->dispatches4, res->buckets[i].task); } if (res->dispatches6 != NULL && !res->exclusivev6) { dns_dispatchset_cancelall(res->dispatches6, res->buckets[i].task); } res->buckets[i].exiting = ISC_TRUE; if (ISC_LIST_EMPTY(res->buckets[i].fctxs)) { INSIST(res->activebuckets > 0); res->activebuckets--; } UNLOCK(&res->buckets[i].lock); } if (res->activebuckets == 0) send_shutdown_events(res); result = isc_timer_reset(res->spillattimer, isc_timertype_inactive, NULL, NULL, ISC_TRUE); RUNTIME_CHECK(result == ISC_R_SUCCESS); } UNLOCK(&res->lock); } void dns_resolver_detach(dns_resolver_t **resp) { dns_resolver_t *res; isc_boolean_t need_destroy = ISC_FALSE; REQUIRE(resp != NULL); res = *resp; REQUIRE(VALID_RESOLVER(res)); RTRACE("detach"); LOCK(&res->lock); INSIST(res->references > 0); res->references--; if (res->references == 0) { INSIST(res->exiting && res->activebuckets == 0); need_destroy = ISC_TRUE; } UNLOCK(&res->lock); if (need_destroy) destroy(res); *resp = NULL; } static inline isc_boolean_t fctx_match(fetchctx_t *fctx, dns_name_t *name, dns_rdatatype_t type, unsigned int options) { /* * Don't match fetch contexts that are shutting down. */ if (fctx->cloned || fctx->state == fetchstate_done || ISC_LIST_EMPTY(fctx->events)) return (ISC_FALSE); if (fctx->type != type || fctx->options != options) return (ISC_FALSE); return (dns_name_equal(&fctx->name, name)); } static inline void log_fetch(dns_name_t *name, dns_rdatatype_t type) { char namebuf[DNS_NAME_FORMATSIZE]; char typebuf[DNS_RDATATYPE_FORMATSIZE]; int level = ISC_LOG_DEBUG(1); /* * If there's no chance of logging it, don't render (format) the * name and RDATA type (further below), and return early. */ if (! isc_log_wouldlog(dns_lctx, level)) return; dns_name_format(name, namebuf, sizeof(namebuf)); dns_rdatatype_format(type, typebuf, sizeof(typebuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, level, "fetch: %s/%s", namebuf, typebuf); } isc_result_t dns_resolver_createfetch(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, dns_name_t *domain, dns_rdataset_t *nameservers, dns_forwarders_t *forwarders, unsigned int options, isc_task_t *task, isc_taskaction_t action, void *arg, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, dns_fetch_t **fetchp) { return (dns_resolver_createfetch3(res, name, type, domain, nameservers, forwarders, NULL, 0, options, 0, NULL, task, action, arg, rdataset, sigrdataset, fetchp)); } isc_result_t dns_resolver_createfetch2(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, dns_name_t *domain, dns_rdataset_t *nameservers, dns_forwarders_t *forwarders, isc_sockaddr_t *client, dns_messageid_t id, unsigned int options, isc_task_t *task, isc_taskaction_t action, void *arg, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, dns_fetch_t **fetchp) { return (dns_resolver_createfetch3(res, name, type, domain, nameservers, forwarders, client, id, options, 0, NULL, task, action, arg, rdataset, sigrdataset, fetchp)); } isc_result_t dns_resolver_createfetch3(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, dns_name_t *domain, dns_rdataset_t *nameservers, dns_forwarders_t *forwarders, isc_sockaddr_t *client, dns_messageid_t id, unsigned int options, unsigned int depth, isc_counter_t *qc, isc_task_t *task, isc_taskaction_t action, void *arg, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, dns_fetch_t **fetchp) { dns_fetch_t *fetch; fetchctx_t *fctx = NULL; isc_result_t result = ISC_R_SUCCESS; unsigned int bucketnum; isc_boolean_t new_fctx = ISC_FALSE; isc_event_t *event; unsigned int count = 0; unsigned int spillat; unsigned int spillatmin; isc_boolean_t dodestroy = ISC_FALSE; UNUSED(forwarders); REQUIRE(VALID_RESOLVER(res)); REQUIRE(res->frozen); /* XXXRTH Check for meta type */ if (domain != NULL) { REQUIRE(DNS_RDATASET_VALID(nameservers)); REQUIRE(nameservers->type == dns_rdatatype_ns); } else REQUIRE(nameservers == NULL); REQUIRE(forwarders == NULL); REQUIRE(!dns_rdataset_isassociated(rdataset)); REQUIRE(sigrdataset == NULL || !dns_rdataset_isassociated(sigrdataset)); REQUIRE(fetchp != NULL && *fetchp == NULL); log_fetch(name, type); /* * XXXRTH use a mempool? */ fetch = isc_mem_get(res->mctx, sizeof(*fetch)); if (fetch == NULL) return (ISC_R_NOMEMORY); fetch->mctx = NULL; isc_mem_attach(res->mctx, &fetch->mctx); bucketnum = dns_name_fullhash(name, ISC_FALSE) % res->nbuckets; LOCK(&res->lock); spillat = res->spillat; spillatmin = res->spillatmin; UNLOCK(&res->lock); LOCK(&res->buckets[bucketnum].lock); if (res->buckets[bucketnum].exiting) { result = ISC_R_SHUTTINGDOWN; goto unlock; } if ((options & DNS_FETCHOPT_UNSHARED) == 0) { for (fctx = ISC_LIST_HEAD(res->buckets[bucketnum].fctxs); fctx != NULL; fctx = ISC_LIST_NEXT(fctx, link)) { if (fctx_match(fctx, name, type, options)) break; } } /* * Is this a duplicate? */ if (fctx != NULL && client != NULL) { dns_fetchevent_t *fevent; for (fevent = ISC_LIST_HEAD(fctx->events); fevent != NULL; fevent = ISC_LIST_NEXT(fevent, ev_link)) { if (fevent->client != NULL && fevent->id == id && isc_sockaddr_equal(fevent->client, client)) { result = DNS_R_DUPLICATE; goto unlock; } count++; } } if (count >= spillatmin && spillatmin != 0) { INSIST(fctx != NULL); if (count >= spillat) fctx->spilled = ISC_TRUE; if (fctx->spilled) { result = DNS_R_DROP; goto unlock; } } if (fctx == NULL) { result = fctx_create(res, name, type, domain, nameservers, options, bucketnum, depth, qc, &fctx); if (result != ISC_R_SUCCESS) goto unlock; new_fctx = ISC_TRUE; } else if (fctx->depth > depth) fctx->depth = depth; result = fctx_join(fctx, task, client, id, action, arg, rdataset, sigrdataset, fetch); if (new_fctx) { if (result == ISC_R_SUCCESS) { /* * Launch this fctx. */ event = &fctx->control_event; ISC_EVENT_INIT(event, sizeof(*event), 0, NULL, DNS_EVENT_FETCHCONTROL, fctx_start, fctx, NULL, NULL, NULL); isc_task_send(res->buckets[bucketnum].task, &event); } else { /* * We don't care about the result of fctx_unlink() * since we know we're not exiting. */ (void)fctx_unlink(fctx); dodestroy = ISC_TRUE; } } unlock: UNLOCK(&res->buckets[bucketnum].lock); if (dodestroy) fctx_destroy(fctx); if (result == ISC_R_SUCCESS) { FTRACE("created"); *fetchp = fetch; } else isc_mem_putanddetach(&fetch->mctx, fetch, sizeof(*fetch)); return (result); } void dns_resolver_cancelfetch(dns_fetch_t *fetch) { fetchctx_t *fctx; dns_resolver_t *res; dns_fetchevent_t *event, *next_event; isc_task_t *etask; REQUIRE(DNS_FETCH_VALID(fetch)); fctx = fetch->private; REQUIRE(VALID_FCTX(fctx)); res = fctx->res; FTRACE("cancelfetch"); LOCK(&res->buckets[fctx->bucketnum].lock); /* * Find the completion event for this fetch (as opposed * to those for other fetches that have joined the same * fctx) and send it with result = ISC_R_CANCELED. */ event = NULL; if (fctx->state != fetchstate_done) { for (event = ISC_LIST_HEAD(fctx->events); event != NULL; event = next_event) { next_event = ISC_LIST_NEXT(event, ev_link); if (event->fetch == fetch) { ISC_LIST_UNLINK(fctx->events, event, ev_link); break; } } } if (event != NULL) { etask = event->ev_sender; event->ev_sender = fctx; event->result = ISC_R_CANCELED; isc_task_sendanddetach(&etask, ISC_EVENT_PTR(&event)); } /* * The fctx continues running even if no fetches remain; * the answer is still cached. */ UNLOCK(&res->buckets[fctx->bucketnum].lock); } void dns_resolver_destroyfetch(dns_fetch_t **fetchp) { dns_fetch_t *fetch; dns_resolver_t *res; dns_fetchevent_t *event, *next_event; fetchctx_t *fctx; unsigned int bucketnum; isc_boolean_t bucket_empty; REQUIRE(fetchp != NULL); fetch = *fetchp; REQUIRE(DNS_FETCH_VALID(fetch)); fctx = fetch->private; REQUIRE(VALID_FCTX(fctx)); res = fctx->res; FTRACE("destroyfetch"); bucketnum = fctx->bucketnum; LOCK(&res->buckets[bucketnum].lock); /* * Sanity check: the caller should have gotten its event before * trying to destroy the fetch. */ event = NULL; if (fctx->state != fetchstate_done) { for (event = ISC_LIST_HEAD(fctx->events); event != NULL; event = next_event) { next_event = ISC_LIST_NEXT(event, ev_link); RUNTIME_CHECK(event->fetch != fetch); } } bucket_empty = fctx_decreference(fctx); UNLOCK(&res->buckets[bucketnum].lock); isc_mem_putanddetach(&fetch->mctx, fetch, sizeof(*fetch)); *fetchp = NULL; if (bucket_empty) empty_bucket(res); } void dns_resolver_logfetch(dns_fetch_t *fetch, isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, isc_boolean_t duplicateok) { fetchctx_t *fctx; dns_resolver_t *res; char domainbuf[DNS_NAME_FORMATSIZE]; REQUIRE(DNS_FETCH_VALID(fetch)); fctx = fetch->private; REQUIRE(VALID_FCTX(fctx)); res = fctx->res; LOCK(&res->buckets[fctx->bucketnum].lock); INSIST(fctx->exitline >= 0); if (!fctx->logged || duplicateok) { dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf)); isc_log_write(lctx, category, module, level, "fetch completed at %s:%d for %s in " "%" ISC_PRINT_QUADFORMAT "u." "%06" ISC_PRINT_QUADFORMAT "u: %s/%s " "[domain:%s,referral:%u,restart:%u,qrysent:%u," "timeout:%u,lame:%u," #ifdef ENABLE_FETCHLIMIT "quota:%u," #endif /* ENABLE_FETCHLIMIT */ "neterr:%u," "badresp:%u,adberr:%u,findfail:%u,valfail:%u]", __FILE__, fctx->exitline, fctx->info, fctx->duration / US_PER_SEC, fctx->duration % US_PER_SEC, isc_result_totext(fctx->result), isc_result_totext(fctx->vresult), domainbuf, fctx->referrals, fctx->restarts, fctx->querysent, fctx->timeouts, fctx->lamecount, #ifdef ENABLE_FETCHLIMIT fctx->quotacount, #endif /* ENABLE_FETCHLIMIT */ fctx->neterr, fctx->badresp, fctx->adberr, fctx->findfail, fctx->valfail); fctx->logged = ISC_TRUE; } UNLOCK(&res->buckets[fctx->bucketnum].lock); } dns_dispatchmgr_t * dns_resolver_dispatchmgr(dns_resolver_t *resolver) { REQUIRE(VALID_RESOLVER(resolver)); return (resolver->dispatchmgr); } dns_dispatch_t * dns_resolver_dispatchv4(dns_resolver_t *resolver) { REQUIRE(VALID_RESOLVER(resolver)); return (dns_dispatchset_get(resolver->dispatches4)); } dns_dispatch_t * dns_resolver_dispatchv6(dns_resolver_t *resolver) { REQUIRE(VALID_RESOLVER(resolver)); return (dns_dispatchset_get(resolver->dispatches6)); } isc_socketmgr_t * dns_resolver_socketmgr(dns_resolver_t *resolver) { REQUIRE(VALID_RESOLVER(resolver)); return (resolver->socketmgr); } isc_taskmgr_t * dns_resolver_taskmgr(dns_resolver_t *resolver) { REQUIRE(VALID_RESOLVER(resolver)); return (resolver->taskmgr); } isc_uint32_t dns_resolver_getlamettl(dns_resolver_t *resolver) { REQUIRE(VALID_RESOLVER(resolver)); return (resolver->lame_ttl); } void dns_resolver_setlamettl(dns_resolver_t *resolver, isc_uint32_t lame_ttl) { REQUIRE(VALID_RESOLVER(resolver)); resolver->lame_ttl = lame_ttl; } unsigned int dns_resolver_nrunning(dns_resolver_t *resolver) { unsigned int n; LOCK(&resolver->nlock); n = resolver->nfctx; UNLOCK(&resolver->nlock); return (n); } isc_result_t dns_resolver_addalternate(dns_resolver_t *resolver, isc_sockaddr_t *alt, dns_name_t *name, in_port_t port) { alternate_t *a; isc_result_t result; REQUIRE(VALID_RESOLVER(resolver)); REQUIRE(!resolver->frozen); REQUIRE((alt == NULL) ^ (name == NULL)); a = isc_mem_get(resolver->mctx, sizeof(*a)); if (a == NULL) return (ISC_R_NOMEMORY); if (alt != NULL) { a->isaddress = ISC_TRUE; a->_u.addr = *alt; } else { a->isaddress = ISC_FALSE; a->_u._n.port = port; dns_name_init(&a->_u._n.name, NULL); result = dns_name_dup(name, resolver->mctx, &a->_u._n.name); if (result != ISC_R_SUCCESS) { isc_mem_put(resolver->mctx, a, sizeof(*a)); return (result); } } ISC_LINK_INIT(a, link); ISC_LIST_APPEND(resolver->alternates, a, link); return (ISC_R_SUCCESS); } void dns_resolver_setudpsize(dns_resolver_t *resolver, isc_uint16_t udpsize) { REQUIRE(VALID_RESOLVER(resolver)); resolver->udpsize = udpsize; } isc_uint16_t dns_resolver_getudpsize(dns_resolver_t *resolver) { REQUIRE(VALID_RESOLVER(resolver)); return (resolver->udpsize); } void dns_resolver_flushbadcache(dns_resolver_t *resolver, dns_name_t *name) { unsigned int i; dns_badcache_t *bad, *prev, *next; /* * Drop all entries that match the name, and also all expired * entries from the badcache. */ REQUIRE(VALID_RESOLVER(resolver)); LOCK(&resolver->lock); if (resolver->badcache == NULL) goto unlock; if (name != NULL) { isc_time_t now; isc_result_t result; result = isc_time_now(&now); if (result != ISC_R_SUCCESS) isc_time_settoepoch(&now); i = dns_name_hash(name, ISC_FALSE) % resolver->badhash; prev = NULL; for (bad = resolver->badcache[i]; bad != NULL; bad = next) { int n; next = bad->next; n = isc_time_compare(&bad->expire, &now); if (n < 0 || dns_name_equal(name, &bad->name)) { if (prev == NULL) resolver->badcache[i] = bad->next; else prev->next = bad->next; isc_mem_put(resolver->mctx, bad, sizeof(*bad) + bad->name.length); resolver->badcount--; } else prev = bad; } } else destroy_badcache(resolver); unlock: UNLOCK(&resolver->lock); } void dns_resolver_flushbadnames(dns_resolver_t *resolver, dns_name_t *name) { dns_badcache_t *bad, *prev, *next; unsigned int i; int n; isc_time_t now; isc_result_t result; /* Drop all expired entries from the badcache. */ REQUIRE(VALID_RESOLVER(resolver)); REQUIRE(name != NULL); LOCK(&resolver->lock); if (resolver->badcache == NULL) goto unlock; result = isc_time_now(&now); if (result != ISC_R_SUCCESS) isc_time_settoepoch(&now); for (i = 0; i < resolver->badhash; i++) { prev = NULL; for (bad = resolver->badcache[i]; bad != NULL; bad = next) { next = bad->next; n = isc_time_compare(&bad->expire, &now); if (n < 0 || dns_name_issubdomain(&bad->name, name)) { if (prev == NULL) resolver->badcache[i] = bad->next; else prev->next = bad->next; isc_mem_put(resolver->mctx, bad, sizeof(*bad) + bad->name.length); resolver->badcount--; } else prev = bad; } } unlock: UNLOCK(&resolver->lock); } static void resizehash(dns_resolver_t *resolver, isc_time_t *now, isc_boolean_t grow) { unsigned int newsize; dns_badcache_t **new, *bad, *next; unsigned int i; /* * The number of buckets in the hashtable is modified in this * function. Afterwards, all the entries are remapped into the * corresponding new slot. Rehashing (hash computation) is * unnecessary as the hash values had been saved. */ if (grow) newsize = resolver->badhash * 2 + 1; else newsize = (resolver->badhash - 1) / 2; new = isc_mem_get(resolver->mctx, sizeof(*resolver->badcache) * newsize); if (new == NULL) return; memset(new, 0, sizeof(*resolver->badcache) * newsize); /* * Because the hashtable implements a simple modulus mapping * from hash to bucket (no extendible hashing is used), every * name in the hashtable has to be remapped to its new slot. * Entries that have expired (time) are dropped. */ for (i = 0; i < resolver->badhash; i++) { for (bad = resolver->badcache[i]; bad != NULL; bad = next) { next = bad->next; if (isc_time_compare(&bad->expire, now) < 0) { isc_mem_put(resolver->mctx, bad, sizeof(*bad) + bad->name.length); resolver->badcount--; } else { bad->next = new[bad->hashval % newsize]; new[bad->hashval % newsize] = bad; } } } isc_mem_put(resolver->mctx, resolver->badcache, sizeof(*resolver->badcache) * resolver->badhash); resolver->badhash = newsize; resolver->badcache = new; } void dns_resolver_addbadcache(dns_resolver_t *resolver, dns_name_t *name, dns_rdatatype_t type, isc_time_t *expire) { isc_time_t now; isc_result_t result = ISC_R_SUCCESS; unsigned int i, hashval; dns_badcache_t *bad, *prev, *next; /* * The badcache is implemented as a hashtable keyed on the name, * and each bucket slot points to a linked list (separate * chaining). * * To avoid long list chains, if the number of entries in the * hashtable goes over number-of-buckets * 8, the * number-of-buckets is doubled. Similarly, if the number of * entries goes below number-of-buckets * 2, the number-of-buckets * is halved. See resizehash(). */ REQUIRE(VALID_RESOLVER(resolver)); LOCK(&resolver->lock); if (resolver->badcache == NULL) { resolver->badcache = isc_mem_get(resolver->mctx, sizeof(*resolver->badcache) * DNS_BADCACHE_SIZE); if (resolver->badcache == NULL) goto cleanup; resolver->badhash = DNS_BADCACHE_SIZE; memset(resolver->badcache, 0, sizeof(*resolver->badcache) * resolver->badhash); } result = isc_time_now(&now); if (result != ISC_R_SUCCESS) isc_time_settoepoch(&now); hashval = dns_name_hash(name, ISC_FALSE); i = hashval % resolver->badhash; prev = NULL; for (bad = resolver->badcache[i]; bad != NULL; bad = next) { next = bad->next; if (bad->type == type && dns_name_equal(name, &bad->name)) break; /* Drop expired entries when walking the chain. */ if (isc_time_compare(&bad->expire, &now) < 0) { if (prev == NULL) resolver->badcache[i] = bad->next; else prev->next = bad->next; isc_mem_put(resolver->mctx, bad, sizeof(*bad) + bad->name.length); resolver->badcount--; } else prev = bad; } if (bad == NULL) { /* * Insert the name into the badcache hashtable at the * head of the linked list at the appropriate slot. The * name data follows right after the allocation for the * linked list node. */ isc_buffer_t buffer; bad = isc_mem_get(resolver->mctx, sizeof(*bad) + name->length); if (bad == NULL) goto cleanup; bad->type = type; bad->hashval = hashval; bad->expire = *expire; isc_buffer_init(&buffer, bad + 1, name->length); dns_name_init(&bad->name, NULL); dns_name_copy(name, &bad->name, &buffer); bad->next = resolver->badcache[i]; resolver->badcache[i] = bad; resolver->badcount++; if (resolver->badcount > resolver->badhash * 8) resizehash(resolver, &now, ISC_TRUE); if (resolver->badcount < resolver->badhash * 2 && resolver->badhash > DNS_BADCACHE_SIZE) resizehash(resolver, &now, ISC_FALSE); } else bad->expire = *expire; cleanup: UNLOCK(&resolver->lock); } isc_boolean_t dns_resolver_getbadcache(dns_resolver_t *resolver, dns_name_t *name, dns_rdatatype_t type, isc_time_t *now) { dns_badcache_t *bad, *prev, *next; isc_boolean_t answer = ISC_FALSE; unsigned int i; REQUIRE(VALID_RESOLVER(resolver)); LOCK(&resolver->lock); if (resolver->badcache == NULL) goto unlock; i = dns_name_hash(name, ISC_FALSE) % resolver->badhash; prev = NULL; for (bad = resolver->badcache[i]; bad != NULL; bad = next) { next = bad->next; /* * Search the hash list. Clean out expired records as we go. */ if (isc_time_compare(&bad->expire, now) < 0) { if (prev != NULL) prev->next = bad->next; else resolver->badcache[i] = bad->next; isc_mem_put(resolver->mctx, bad, sizeof(*bad) + bad->name.length); resolver->badcount--; continue; } if (bad->type == type && dns_name_equal(name, &bad->name)) { answer = ISC_TRUE; break; } prev = bad; } /* * Slow sweep to clean out stale records. */ i = resolver->badsweep++ % resolver->badhash; bad = resolver->badcache[i]; if (bad != NULL && isc_time_compare(&bad->expire, now) < 0) { resolver->badcache[i] = bad->next; isc_mem_put(resolver->mctx, bad, sizeof(*bad) + bad->name.length); resolver->badcount--; } unlock: UNLOCK(&resolver->lock); return (answer); } void dns_resolver_printbadcache(dns_resolver_t *resolver, FILE *fp) { char namebuf[DNS_NAME_FORMATSIZE]; char typebuf[DNS_RDATATYPE_FORMATSIZE]; dns_badcache_t *bad, *next, *prev; isc_time_t now; unsigned int i; isc_uint64_t t; LOCK(&resolver->lock); fprintf(fp, ";\n; Bad cache\n;\n"); if (resolver->badcache == NULL) goto unlock; TIME_NOW(&now); for (i = 0; i < resolver->badhash; i++) { prev = NULL; for (bad = resolver->badcache[i]; bad != NULL; bad = next) { next = bad->next; if (isc_time_compare(&bad->expire, &now) < 0) { if (prev != NULL) prev->next = bad->next; else resolver->badcache[i] = bad->next; isc_mem_put(resolver->mctx, bad, sizeof(*bad) + bad->name.length); resolver->badcount--; continue; } prev = bad; dns_name_format(&bad->name, namebuf, sizeof(namebuf)); dns_rdatatype_format(bad->type, typebuf, sizeof(typebuf)); t = isc_time_microdiff(&bad->expire, &now); t /= 1000; fprintf(fp, "; %s/%s [ttl " "%" ISC_PLATFORM_QUADFORMAT "u]\n", namebuf, typebuf, t); } } unlock: UNLOCK(&resolver->lock); } static void free_algorithm(void *node, void *arg) { unsigned char *algorithms = node; isc_mem_t *mctx = arg; isc_mem_put(mctx, algorithms, *algorithms); } void dns_resolver_reset_algorithms(dns_resolver_t *resolver) { REQUIRE(VALID_RESOLVER(resolver)); #if USE_ALGLOCK RWLOCK(&resolver->alglock, isc_rwlocktype_write); #endif if (resolver->algorithms != NULL) dns_rbt_destroy(&resolver->algorithms); #if USE_ALGLOCK RWUNLOCK(&resolver->alglock, isc_rwlocktype_write); #endif } isc_result_t dns_resolver_disable_algorithm(dns_resolver_t *resolver, dns_name_t *name, unsigned int alg) { unsigned int len, mask; unsigned char *new; unsigned char *algorithms; isc_result_t result; dns_rbtnode_t *node = NULL; /* * Whether an algorithm is disabled (or not) is stored in a * per-name bitfield that is stored as the node data of an * RBT. */ REQUIRE(VALID_RESOLVER(resolver)); if (alg > 255) return (ISC_R_RANGE); #if USE_ALGLOCK RWLOCK(&resolver->alglock, isc_rwlocktype_write); #endif if (resolver->algorithms == NULL) { result = dns_rbt_create(resolver->mctx, free_algorithm, resolver->mctx, &resolver->algorithms); if (result != ISC_R_SUCCESS) goto cleanup; } len = alg/8 + 2; mask = 1 << (alg%8); result = dns_rbt_addnode(resolver->algorithms, name, &node); if (result == ISC_R_SUCCESS || result == ISC_R_EXISTS) { algorithms = node->data; /* * If algorithms is set, algorithms[0] contains its * length. */ if (algorithms == NULL || len > *algorithms) { /* * If no bitfield exists in the node data, or if * it is not long enough, allocate a new * bitfield and copy the old (smaller) bitfield * into it if one exists. */ new = isc_mem_get(resolver->mctx, len); if (new == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } memset(new, 0, len); if (algorithms != NULL) memmove(new, algorithms, *algorithms); new[len-1] |= mask; /* new[0] should contain the length of new. */ *new = len; node->data = new; /* Free the older bitfield. */ if (algorithms != NULL) isc_mem_put(resolver->mctx, algorithms, *algorithms); } else algorithms[len-1] |= mask; } result = ISC_R_SUCCESS; cleanup: #if USE_ALGLOCK RWUNLOCK(&resolver->alglock, isc_rwlocktype_write); #endif return (result); } isc_boolean_t dns_resolver_algorithm_supported(dns_resolver_t *resolver, dns_name_t *name, unsigned int alg) { unsigned int len, mask; unsigned char *algorithms; void *data = NULL; isc_result_t result; isc_boolean_t found = ISC_FALSE; REQUIRE(VALID_RESOLVER(resolver)); /* * DH is unsupported for DNSKEYs, see RFC 4034 sec. A.1. */ if ((alg == DST_ALG_DH) || (alg == DST_ALG_INDIRECT)) return (ISC_FALSE); #if USE_ALGLOCK RWLOCK(&resolver->alglock, isc_rwlocktype_read); #endif if (resolver->algorithms == NULL) goto unlock; result = dns_rbt_findname(resolver->algorithms, name, 0, NULL, &data); if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { len = alg/8 + 2; mask = 1 << (alg%8); algorithms = data; if (len <= *algorithms && (algorithms[len-1] & mask) != 0) found = ISC_TRUE; } unlock: #if USE_ALGLOCK RWUNLOCK(&resolver->alglock, isc_rwlocktype_read); #endif if (found) return (ISC_FALSE); return (dst_algorithm_supported(alg)); } static void free_digest(void *node, void *arg) { unsigned char *digests = node; isc_mem_t *mctx = arg; isc_mem_put(mctx, digests, *digests); } void dns_resolver_reset_ds_digests(dns_resolver_t *resolver) { REQUIRE(VALID_RESOLVER(resolver)); #if USE_ALGLOCK RWLOCK(&resolver->alglock, isc_rwlocktype_write); #endif if (resolver->digests != NULL) dns_rbt_destroy(&resolver->digests); #if USE_ALGLOCK RWUNLOCK(&resolver->alglock, isc_rwlocktype_write); #endif } isc_result_t dns_resolver_disable_ds_digest(dns_resolver_t *resolver, dns_name_t *name, unsigned int digest_type) { unsigned int len, mask; unsigned char *new; unsigned char *digests; isc_result_t result; dns_rbtnode_t *node = NULL; /* * Whether a digest is disabled (or not) is stored in a per-name * bitfield that is stored as the node data of an RBT. */ REQUIRE(VALID_RESOLVER(resolver)); if (digest_type > 255) return (ISC_R_RANGE); #if USE_ALGLOCK RWLOCK(&resolver->alglock, isc_rwlocktype_write); #endif if (resolver->digests == NULL) { result = dns_rbt_create(resolver->mctx, free_digest, resolver->mctx, &resolver->digests); if (result != ISC_R_SUCCESS) goto cleanup; } len = digest_type/8 + 2; mask = 1 << (digest_type%8); result = dns_rbt_addnode(resolver->digests, name, &node); if (result == ISC_R_SUCCESS || result == ISC_R_EXISTS) { digests = node->data; /* If digests is set, digests[0] contains its length. */ if (digests == NULL || len > *digests) { /* * If no bitfield exists in the node data, or if * it is not long enough, allocate a new * bitfield and copy the old (smaller) bitfield * into it if one exists. */ new = isc_mem_get(resolver->mctx, len); if (new == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } memset(new, 0, len); if (digests != NULL) memmove(new, digests, *digests); new[len-1] |= mask; /* new[0] should contain the length of new. */ *new = len; node->data = new; /* Free the older bitfield. */ if (digests != NULL) isc_mem_put(resolver->mctx, digests, *digests); } else digests[len-1] |= mask; } result = ISC_R_SUCCESS; cleanup: #if USE_ALGLOCK RWUNLOCK(&resolver->alglock, isc_rwlocktype_write); #endif return (result); } isc_boolean_t dns_resolver_ds_digest_supported(dns_resolver_t *resolver, dns_name_t *name, unsigned int digest_type) { unsigned int len, mask; unsigned char *digests; void *data = NULL; isc_result_t result; isc_boolean_t found = ISC_FALSE; REQUIRE(VALID_RESOLVER(resolver)); #if USE_ALGLOCK RWLOCK(&resolver->alglock, isc_rwlocktype_read); #endif if (resolver->digests == NULL) goto unlock; result = dns_rbt_findname(resolver->digests, name, 0, NULL, &data); if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { len = digest_type/8 + 2; mask = 1 << (digest_type%8); digests = data; if (len <= *digests && (digests[len-1] & mask) != 0) found = ISC_TRUE; } unlock: #if USE_ALGLOCK RWUNLOCK(&resolver->alglock, isc_rwlocktype_read); #endif if (found) return (ISC_FALSE); return (dst_ds_digest_supported(digest_type)); } void dns_resolver_resetmustbesecure(dns_resolver_t *resolver) { REQUIRE(VALID_RESOLVER(resolver)); #if USE_MBSLOCK RWLOCK(&resolver->mbslock, isc_rwlocktype_write); #endif if (resolver->mustbesecure != NULL) dns_rbt_destroy(&resolver->mustbesecure); #if USE_MBSLOCK RWUNLOCK(&resolver->mbslock, isc_rwlocktype_write); #endif } static isc_boolean_t yes = ISC_TRUE, no = ISC_FALSE; isc_result_t dns_resolver_setmustbesecure(dns_resolver_t *resolver, dns_name_t *name, isc_boolean_t value) { isc_result_t result; REQUIRE(VALID_RESOLVER(resolver)); #if USE_MBSLOCK RWLOCK(&resolver->mbslock, isc_rwlocktype_write); #endif if (resolver->mustbesecure == NULL) { result = dns_rbt_create(resolver->mctx, NULL, NULL, &resolver->mustbesecure); if (result != ISC_R_SUCCESS) goto cleanup; } result = dns_rbt_addname(resolver->mustbesecure, name, value ? &yes : &no); cleanup: #if USE_MBSLOCK RWUNLOCK(&resolver->mbslock, isc_rwlocktype_write); #endif return (result); } isc_boolean_t dns_resolver_getmustbesecure(dns_resolver_t *resolver, dns_name_t *name) { void *data = NULL; isc_boolean_t value = ISC_FALSE; isc_result_t result; REQUIRE(VALID_RESOLVER(resolver)); #if USE_MBSLOCK RWLOCK(&resolver->mbslock, isc_rwlocktype_read); #endif if (resolver->mustbesecure == NULL) goto unlock; result = dns_rbt_findname(resolver->mustbesecure, name, 0, NULL, &data); if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) value = *(isc_boolean_t*)data; unlock: #if USE_MBSLOCK RWUNLOCK(&resolver->mbslock, isc_rwlocktype_read); #endif return (value); } void dns_resolver_getclientsperquery(dns_resolver_t *resolver, isc_uint32_t *cur, isc_uint32_t *min, isc_uint32_t *max) { REQUIRE(VALID_RESOLVER(resolver)); LOCK(&resolver->lock); if (cur != NULL) *cur = resolver->spillat; if (min != NULL) *min = resolver->spillatmin; if (max != NULL) *max = resolver->spillatmax; UNLOCK(&resolver->lock); } void dns_resolver_setclientsperquery(dns_resolver_t *resolver, isc_uint32_t min, isc_uint32_t max) { REQUIRE(VALID_RESOLVER(resolver)); LOCK(&resolver->lock); resolver->spillatmin = resolver->spillat = min; resolver->spillatmax = max; UNLOCK(&resolver->lock); } void dns_resolver_setfetchesperzone(dns_resolver_t *resolver, isc_uint32_t clients) { #ifdef ENABLE_FETCHLIMIT REQUIRE(VALID_RESOLVER(resolver)); LOCK(&resolver->lock); resolver->zspill = clients; UNLOCK(&resolver->lock); #else UNUSED(resolver); UNUSED(clients); return; #endif /* !ENABLE_FETCHLIMIT */ } isc_boolean_t dns_resolver_getzeronosoattl(dns_resolver_t *resolver) { REQUIRE(VALID_RESOLVER(resolver)); return (resolver->zero_no_soa_ttl); } void dns_resolver_setzeronosoattl(dns_resolver_t *resolver, isc_boolean_t state) { REQUIRE(VALID_RESOLVER(resolver)); resolver->zero_no_soa_ttl = state; } unsigned int dns_resolver_getoptions(dns_resolver_t *resolver) { REQUIRE(VALID_RESOLVER(resolver)); return (resolver->options); } unsigned int dns_resolver_gettimeout(dns_resolver_t *resolver) { REQUIRE(VALID_RESOLVER(resolver)); return (resolver->query_timeout); } void dns_resolver_settimeout(dns_resolver_t *resolver, unsigned int seconds) { REQUIRE(VALID_RESOLVER(resolver)); if (seconds == 0) seconds = DEFAULT_QUERY_TIMEOUT; if (seconds > MAXIMUM_QUERY_TIMEOUT) seconds = MAXIMUM_QUERY_TIMEOUT; if (seconds < MINIMUM_QUERY_TIMEOUT) seconds = MINIMUM_QUERY_TIMEOUT; resolver->query_timeout = seconds; } void dns_resolver_setquerydscp4(dns_resolver_t *resolver, isc_dscp_t dscp) { REQUIRE(VALID_RESOLVER(resolver)); resolver->querydscp4 = dscp; } isc_dscp_t dns_resolver_getquerydscp4(dns_resolver_t *resolver) { REQUIRE(VALID_RESOLVER(resolver)); return (resolver->querydscp4); } void dns_resolver_setquerydscp6(dns_resolver_t *resolver, isc_dscp_t dscp) { REQUIRE(VALID_RESOLVER(resolver)); resolver->querydscp6 = dscp; } isc_dscp_t dns_resolver_getquerydscp6(dns_resolver_t *resolver) { REQUIRE(VALID_RESOLVER(resolver)); return (resolver->querydscp6); } void dns_resolver_setmaxdepth(dns_resolver_t *resolver, unsigned int maxdepth) { REQUIRE(VALID_RESOLVER(resolver)); resolver->maxdepth = maxdepth; } unsigned int dns_resolver_getmaxdepth(dns_resolver_t *resolver) { REQUIRE(VALID_RESOLVER(resolver)); return (resolver->maxdepth); } void dns_resolver_setmaxqueries(dns_resolver_t *resolver, unsigned int queries) { REQUIRE(VALID_RESOLVER(resolver)); resolver->maxqueries = queries; } unsigned int dns_resolver_getmaxqueries(dns_resolver_t *resolver) { REQUIRE(VALID_RESOLVER(resolver)); return (resolver->maxqueries); } void dns_resolver_dumpfetches(dns_resolver_t *resolver, isc_statsformat_t format, FILE *fp) { #ifdef ENABLE_FETCHLIMIT int i; REQUIRE(VALID_RESOLVER(resolver)); REQUIRE(fp != NULL); REQUIRE(format == isc_statsformat_file); for (i = 0; i < RES_DOMAIN_BUCKETS; i++) { fctxcount_t *fc; LOCK(&resolver->dbuckets[i].lock); for (fc = ISC_LIST_HEAD(resolver->dbuckets[i].list); fc != NULL; fc = ISC_LIST_NEXT(fc, link)) { dns_name_print(fc->domain, fp); fprintf(fp, ": %d active (%d spilled, %d allowed)\n", fc->count, fc->dropped, fc->allowed); } UNLOCK(&resolver->dbuckets[i].lock); } #else UNUSED(resolver); UNUSED(format); UNUSED(fp); return; #endif /* !ENABLE_FETCHLIMIT */ } void dns_resolver_setquotaresponse(dns_resolver_t *resolver, dns_quotatype_t which, isc_result_t resp) { #ifdef ENABLE_FETCHLIMIT REQUIRE(VALID_RESOLVER(resolver)); REQUIRE(which == dns_quotatype_zone || which == dns_quotatype_server); REQUIRE(resp == DNS_R_DROP || resp == DNS_R_SERVFAIL); resolver->quotaresp[which] = resp; #else UNUSED(resolver); UNUSED(which); UNUSED(resp); return; #endif /* !ENABLE_FETCHLIMIT */ } isc_result_t dns_resolver_getquotaresponse(dns_resolver_t *resolver, dns_quotatype_t which) { #ifdef ENABLE_FETCHLIMIT REQUIRE(VALID_RESOLVER(resolver)); REQUIRE(which == dns_quotatype_zone || which == dns_quotatype_server); return (resolver->quotaresp[which]); #else UNUSED(resolver); UNUSED(which); return (ISC_R_NOTIMPLEMENTED); #endif /* !ENABLE_FETCHLIMIT */ } bind9-9.10.3.dfsg.P4/lib/dns/private.c0000644000470500017500000002520212664710322016542 0ustar lamontlamont/* * Copyright (C) 2009, 2011, 2012, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #include "config.h" #include #include #include #include #include #include #include /* * We need to build the relevant chain if there exists a NSEC/NSEC3PARAM * at the apex; normally only one or the other of NSEC/NSEC3PARAM will exist. * * If a NSEC3PARAM RRset exists then we will need to build a NSEC chain * if all the NSEC3PARAM records (and associated chains) are slated for * destruction and we have not been told to NOT build the NSEC chain. * * If the NSEC set exist then check to see if there is a request to create * a NSEC3 chain. * * If neither NSEC/NSEC3PARAM RRsets exist at the origin and the private * type exists then we need to examine it to determine if NSEC3 chain has * been requested to be built otherwise a NSEC chain needs to be built. */ #define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0) #define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0) #define INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 0) #define NONSEC(x) (((x) & DNS_NSEC3FLAG_NONSEC) != 0) #define CHECK(x) do { \ result = (x); \ if (result != ISC_R_SUCCESS) \ goto failure; \ } while (0) /* * Work out if 'param' should be ignored or not (i.e. it is in the process * of being removed). * * Note: we 'belt-and-braces' here by also checking for a CREATE private * record and keep the param record in this case. */ static isc_boolean_t ignore(dns_rdata_t *param, dns_rdataset_t *privateset) { isc_result_t result; for (result = dns_rdataset_first(privateset); result == ISC_R_SUCCESS; result = dns_rdataset_next(privateset)) { unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; dns_rdata_t private = DNS_RDATA_INIT; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(privateset, &private); if (!dns_nsec3param_fromprivate(&private, &rdata, buf, sizeof(buf))) continue; /* * We are going to create a new NSEC3 chain so it * doesn't matter if we are removing this one. */ if (CREATE(rdata.data[1])) return (ISC_FALSE); if (rdata.data[0] != param->data[0] || rdata.data[2] != param->data[2] || rdata.data[3] != param->data[3] || rdata.data[4] != param->data[4] || memcmp(&rdata.data[5], ¶m->data[5], param->data[4])) continue; /* * The removal of this NSEC3 chain does NOT cause a * NSEC chain to be created so we don't need to tell * the caller that it will be removed. */ if (NONSEC(rdata.data[1])) return (ISC_FALSE); return (ISC_TRUE); } return (ISC_FALSE); } isc_result_t dns_private_chains(dns_db_t *db, dns_dbversion_t *ver, dns_rdatatype_t privatetype, isc_boolean_t *build_nsec, isc_boolean_t *build_nsec3) { dns_dbnode_t *node; dns_rdataset_t nsecset, nsec3paramset, privateset; isc_boolean_t nsec3chain; isc_boolean_t signing; isc_result_t result; unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; unsigned int count; node = NULL; dns_rdataset_init(&nsecset); dns_rdataset_init(&nsec3paramset); dns_rdataset_init(&privateset); CHECK(dns_db_getoriginnode(db, &node)); result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, (isc_stdtime_t) 0, &nsecset, NULL); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) goto failure; result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0, (isc_stdtime_t) 0, &nsec3paramset, NULL); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) goto failure; if (dns_rdataset_isassociated(&nsecset) && dns_rdataset_isassociated(&nsec3paramset)) { if (build_nsec != NULL) *build_nsec = ISC_TRUE; if (build_nsec3 != NULL) *build_nsec3 = ISC_TRUE; goto success; } if (privatetype != (dns_rdatatype_t)0) { result = dns_db_findrdataset(db, node, ver, privatetype, 0, (isc_stdtime_t) 0, &privateset, NULL); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) goto failure; } /* * Look to see if we also need to be creating a NSEC3 chain. */ if (dns_rdataset_isassociated(&nsecset)) { if (build_nsec != NULL) *build_nsec = ISC_TRUE; if (build_nsec3 != NULL) *build_nsec3 = ISC_FALSE; if (!dns_rdataset_isassociated(&privateset)) goto success; for (result = dns_rdataset_first(&privateset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&privateset)) { dns_rdata_t private = DNS_RDATA_INIT; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&privateset, &private); if (!dns_nsec3param_fromprivate(&private, &rdata, buf, sizeof(buf))) continue; if (REMOVE(rdata.data[1])) continue; if (build_nsec3 != NULL) *build_nsec3 = ISC_TRUE; break; } goto success; } if (dns_rdataset_isassociated(&nsec3paramset)) { if (build_nsec3 != NULL) *build_nsec3 = ISC_TRUE; if (build_nsec != NULL) *build_nsec = ISC_FALSE; if (!dns_rdataset_isassociated(&privateset)) goto success; /* * If we are in the process of building a new NSEC3 chain * then we don't need to build a NSEC chain. */ for (result = dns_rdataset_first(&privateset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&privateset)) { dns_rdata_t private = DNS_RDATA_INIT; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&privateset, &private); if (!dns_nsec3param_fromprivate(&private, &rdata, buf, sizeof(buf))) continue; if (CREATE(rdata.data[1])) goto success; } /* * Check to see if there will be a active NSEC3CHAIN once * the changes queued complete. */ count = 0; for (result = dns_rdataset_first(&nsec3paramset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&nsec3paramset)) { dns_rdata_t rdata = DNS_RDATA_INIT; /* * If there is more that one NSEC3 chain present then * we don't need to construct a NSEC chain. */ if (++count > 1) goto success; dns_rdataset_current(&nsec3paramset, &rdata); if (ignore(&rdata, &privateset)) continue; /* * We still have a good NSEC3 chain or we are * not creating a NSEC chain as NONSEC is set. */ goto success; } /* * The last NSEC3 chain is being removed and does not have * have NONSEC set. */ if (build_nsec != NULL) *build_nsec = ISC_TRUE; goto success; } if (build_nsec != NULL) *build_nsec = ISC_FALSE; if (build_nsec3 != NULL) *build_nsec3 = ISC_FALSE; if (!dns_rdataset_isassociated(&privateset)) goto success; signing = ISC_FALSE; nsec3chain = ISC_FALSE; for (result = dns_rdataset_first(&privateset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&privateset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_t private = DNS_RDATA_INIT; dns_rdataset_current(&privateset, &private); if (!dns_nsec3param_fromprivate(&private, &rdata, buf, sizeof(buf))) { /* * Look for record that says we are signing the * zone with a key. */ if (private.length == 5 && private.data[0] != 0 && private.data[3] == 0 && private.data[4] == 0) signing = ISC_TRUE; } else { if (CREATE(rdata.data[1])) nsec3chain = ISC_TRUE; } } if (signing) { if (nsec3chain) { if (build_nsec3 != NULL) *build_nsec3 = ISC_TRUE; } else { if (build_nsec != NULL) *build_nsec = ISC_TRUE; } } success: result = ISC_R_SUCCESS; failure: if (dns_rdataset_isassociated(&nsecset)) dns_rdataset_disassociate(&nsecset); if (dns_rdataset_isassociated(&nsec3paramset)) dns_rdataset_disassociate(&nsec3paramset); if (dns_rdataset_isassociated(&privateset)) dns_rdataset_disassociate(&privateset); if (node != NULL) dns_db_detachnode(db, &node); return (result); } isc_result_t dns_private_totext(dns_rdata_t *private, isc_buffer_t *buf) { isc_result_t result; if (private->length < 5) return (ISC_R_NOTFOUND); if (private->data[0] == 0) { unsigned char nsec3buf[DNS_NSEC3PARAM_BUFFERSIZE]; unsigned char newbuf[DNS_NSEC3PARAM_BUFFERSIZE]; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_nsec3param_t nsec3param; isc_boolean_t delete, init, nonsec; isc_buffer_t b; if (!dns_nsec3param_fromprivate(private, &rdata, nsec3buf, sizeof(nsec3buf))) CHECK(ISC_R_FAILURE); CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); delete = ISC_TF((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0); init = ISC_TF((nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0); nonsec = ISC_TF((nsec3param.flags & DNS_NSEC3FLAG_NONSEC) != 0); nsec3param.flags &= ~(DNS_NSEC3FLAG_CREATE| DNS_NSEC3FLAG_REMOVE| DNS_NSEC3FLAG_INITIAL| DNS_NSEC3FLAG_NONSEC); if (init) isc_buffer_putstr(buf, "Pending NSEC3 chain "); else if (delete) isc_buffer_putstr(buf, "Removing NSEC3 chain "); else isc_buffer_putstr(buf, "Creating NSEC3 chain "); dns_rdata_reset(&rdata); isc_buffer_init(&b, newbuf, sizeof(newbuf)); CHECK(dns_rdata_fromstruct(&rdata, dns_rdataclass_in, dns_rdatatype_nsec3param, &nsec3param, &b)); CHECK(dns_rdata_totext(&rdata, NULL, buf)); if (delete && !nonsec) isc_buffer_putstr(buf, " / creating NSEC chain"); } else if (private->length == 5) { unsigned char alg = private->data[0]; dns_keytag_t keyid = (private->data[2] | private->data[1] << 8); char keybuf[BUFSIZ], algbuf[DNS_SECALG_FORMATSIZE]; isc_boolean_t delete = ISC_TF(private->data[3] != 0); isc_boolean_t complete = ISC_TF(private->data[4] != 0); if (delete && complete) isc_buffer_putstr(buf, "Done removing signatures for "); else if (delete) isc_buffer_putstr(buf, "Removing signatures for "); else if (complete) isc_buffer_putstr(buf, "Done signing with "); else isc_buffer_putstr(buf, "Signing with "); dns_secalg_format(alg, algbuf, sizeof(algbuf)); sprintf(keybuf, "key %d/%s", keyid, algbuf); isc_buffer_putstr(buf, keybuf); } else return (ISC_R_NOTFOUND); isc_buffer_putuint8(buf, 0); result = ISC_R_SUCCESS; failure: return (result); } bind9-9.10.3.dfsg.P4/lib/dns/nsec3.c0000644000470500017500000015474312664710322016120 0ustar lamontlamont/* * Copyright (C) 2006, 2008-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define CHECK(x) do { \ result = (x); \ if (result != ISC_R_SUCCESS) \ goto failure; \ } while (0) #define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0) #define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0) #define INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 0) #define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0) isc_result_t dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, unsigned int hashalg, unsigned int flags, unsigned int iterations, const unsigned char *salt, size_t salt_length, const unsigned char *nexthash, size_t hash_length, unsigned char *buffer, dns_rdata_t *rdata) { isc_result_t result; dns_rdataset_t rdataset; isc_region_t r; unsigned int i; isc_boolean_t found; isc_boolean_t found_ns; isc_boolean_t need_rrsig; unsigned char *nsec_bits, *bm; unsigned int max_type; dns_rdatasetiter_t *rdsiter; unsigned char *p; REQUIRE(salt_length < 256U); REQUIRE(hash_length < 256U); REQUIRE(flags <= 0xffU); REQUIRE(hashalg <= 0xffU); REQUIRE(iterations <= 0xffffU); switch (hashalg) { case dns_hash_sha1: REQUIRE(hash_length == ISC_SHA1_DIGESTLENGTH); break; } memset(buffer, 0, DNS_NSEC3_BUFFERSIZE); p = buffer; *p++ = hashalg; *p++ = flags; *p++ = iterations >> 8; *p++ = iterations; *p++ = (unsigned char)salt_length; memmove(p, salt, salt_length); p += salt_length; *p++ = (unsigned char)hash_length; memmove(p, nexthash, hash_length); p += hash_length; r.length = (unsigned int)(p - buffer); r.base = buffer; /* * Use the end of the space for a raw bitmap leaving enough * space for the window identifiers and length octets. */ bm = r.base + r.length + 512; nsec_bits = r.base + r.length; max_type = 0; if (node == NULL) goto collapse_bitmap; dns_rdataset_init(&rdataset); rdsiter = NULL; result = dns_db_allrdatasets(db, node, version, 0, &rdsiter); if (result != ISC_R_SUCCESS) return (result); found = found_ns = need_rrsig = ISC_FALSE; for (result = dns_rdatasetiter_first(rdsiter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsiter)) { dns_rdatasetiter_current(rdsiter, &rdataset); if (rdataset.type != dns_rdatatype_nsec && rdataset.type != dns_rdatatype_nsec3 && rdataset.type != dns_rdatatype_rrsig) { if (rdataset.type > max_type) max_type = rdataset.type; dns_nsec_setbit(bm, rdataset.type, 1); /* * Work out if we need to set the RRSIG bit for * this node. We set the RRSIG bit if either of * the following conditions are met: * 1) We have a SOA or DS then we need to set * the RRSIG bit as both always will be signed. * 2) We set the RRSIG bit if we don't have * a NS record but do have other data. */ if (rdataset.type == dns_rdatatype_soa || rdataset.type == dns_rdatatype_ds) need_rrsig = ISC_TRUE; else if (rdataset.type == dns_rdatatype_ns) found_ns = ISC_TRUE; else found = ISC_TRUE; } dns_rdataset_disassociate(&rdataset); } if ((found && !found_ns) || need_rrsig) { if (dns_rdatatype_rrsig > max_type) max_type = dns_rdatatype_rrsig; dns_nsec_setbit(bm, dns_rdatatype_rrsig, 1); } /* * At zone cuts, deny the existence of glue in the parent zone. */ if (dns_nsec_isset(bm, dns_rdatatype_ns) && ! dns_nsec_isset(bm, dns_rdatatype_soa)) { for (i = 0; i <= max_type; i++) { if (dns_nsec_isset(bm, i) && ! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i)) dns_nsec_setbit(bm, i, 0); } } dns_rdatasetiter_destroy(&rdsiter); if (result != ISC_R_NOMORE) return (result); collapse_bitmap: nsec_bits += dns_nsec_compressbitmap(nsec_bits, bm, max_type); r.length = (unsigned int)(nsec_bits - r.base); INSIST(r.length <= DNS_NSEC3_BUFFERSIZE); dns_rdata_fromregion(rdata, dns_db_class(db), dns_rdatatype_nsec3, &r); return (ISC_R_SUCCESS); } isc_boolean_t dns_nsec3_typepresent(dns_rdata_t *rdata, dns_rdatatype_t type) { dns_rdata_nsec3_t nsec3; isc_result_t result; isc_boolean_t present; unsigned int i, len, window; REQUIRE(rdata != NULL); REQUIRE(rdata->type == dns_rdatatype_nsec3); /* This should never fail */ result = dns_rdata_tostruct(rdata, &nsec3, NULL); INSIST(result == ISC_R_SUCCESS); present = ISC_FALSE; for (i = 0; i < nsec3.len; i += len) { INSIST(i + 2 <= nsec3.len); window = nsec3.typebits[i]; len = nsec3.typebits[i + 1]; INSIST(len > 0 && len <= 32); i += 2; INSIST(i + len <= nsec3.len); if (window * 256 > type) break; if ((window + 1) * 256 <= type) continue; if (type < (window * 256) + len * 8) present = ISC_TF(dns_nsec_isset(&nsec3.typebits[i], type % 256)); break; } dns_rdata_freestruct(&nsec3); return (present); } isc_result_t dns_nsec3_hashname(dns_fixedname_t *result, unsigned char rethash[NSEC3_MAX_HASH_LENGTH], size_t *hash_length, dns_name_t *name, dns_name_t *origin, dns_hash_t hashalg, unsigned int iterations, const unsigned char *salt, size_t saltlength) { unsigned char hash[NSEC3_MAX_HASH_LENGTH]; unsigned char nametext[DNS_NAME_FORMATSIZE]; dns_fixedname_t fixed; dns_name_t *downcased; isc_buffer_t namebuffer; isc_region_t region; size_t len; if (rethash == NULL) rethash = hash; memset(rethash, 0, NSEC3_MAX_HASH_LENGTH); dns_fixedname_init(&fixed); downcased = dns_fixedname_name(&fixed); dns_name_downcase(name, downcased, NULL); /* hash the node name */ len = isc_iterated_hash(rethash, hashalg, iterations, salt, (int)saltlength, downcased->ndata, downcased->length); if (len == 0U) return (DNS_R_BADALG); if (hash_length != NULL) *hash_length = len; /* convert the hash to base32hex non-padded */ region.base = rethash; region.length = (unsigned int)len; isc_buffer_init(&namebuffer, nametext, sizeof nametext); isc_base32hexnp_totext(®ion, 1, "", &namebuffer); /* convert the hex to a domain name */ dns_fixedname_init(result); return (dns_name_fromtext(dns_fixedname_name(result), &namebuffer, origin, 0, NULL)); } unsigned int dns_nsec3_hashlength(dns_hash_t hash) { switch (hash) { case dns_hash_sha1: return(ISC_SHA1_DIGESTLENGTH); } return (0); } isc_boolean_t dns_nsec3_supportedhash(dns_hash_t hash) { switch (hash) { case dns_hash_sha1: return (ISC_TRUE); } return (ISC_FALSE); } /*% * Update a single RR in version 'ver' of 'db' and log the * update in 'diff'. * * Ensures: * \li '*tuple' == NULL. Either the tuple is freed, or its * ownership has been transferred to the diff. */ static isc_result_t do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff) { dns_diff_t temp_diff; isc_result_t result; /* * Create a singleton diff. */ dns_diff_init(diff->mctx, &temp_diff); ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); /* * Apply it to the database. */ result = dns_diff_apply(&temp_diff, db, ver); ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); if (result != ISC_R_SUCCESS) { dns_difftuple_free(tuple); return (result); } /* * Merge it into the current pending journal entry. */ dns_diff_appendminimal(diff, tuple); /* * Do not clear temp_diff. */ return (ISC_R_SUCCESS); } /*% * Set '*exists' to true iff the given name exists, to false otherwise. */ static isc_result_t name_exists(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, isc_boolean_t *exists) { isc_result_t result; dns_dbnode_t *node = NULL; dns_rdatasetiter_t *iter = NULL; result = dns_db_findnode(db, name, ISC_FALSE, &node); if (result == ISC_R_NOTFOUND) { *exists = ISC_FALSE; return (ISC_R_SUCCESS); } if (result != ISC_R_SUCCESS) return (result); result = dns_db_allrdatasets(db, node, version, (isc_stdtime_t) 0, &iter); if (result != ISC_R_SUCCESS) goto cleanup_node; result = dns_rdatasetiter_first(iter); if (result == ISC_R_SUCCESS) { *exists = ISC_TRUE; } else if (result == ISC_R_NOMORE) { *exists = ISC_FALSE; result = ISC_R_SUCCESS; } else *exists = ISC_FALSE; dns_rdatasetiter_destroy(&iter); cleanup_node: dns_db_detachnode(db, &node); return (result); } static isc_boolean_t match_nsec3param(const dns_rdata_nsec3_t *nsec3, const dns_rdata_nsec3param_t *nsec3param) { if (nsec3->hash == nsec3param->hash && nsec3->iterations == nsec3param->iterations && nsec3->salt_length == nsec3param->salt_length && !memcmp(nsec3->salt, nsec3param->salt, nsec3->salt_length)) return (ISC_TRUE); return (ISC_FALSE); } /*% * Delete NSEC3 records at "name" which match "param", recording the * change in "diff". */ static isc_result_t delete(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff) { dns_dbnode_t *node = NULL ; dns_difftuple_t *tuple = NULL; dns_rdata_nsec3_t nsec3; dns_rdataset_t rdataset; isc_result_t result; result = dns_db_findnsec3node(db, name, ISC_FALSE, &node); if (result == ISC_R_NOTFOUND) return (ISC_R_SUCCESS); if (result != ISC_R_SUCCESS) return (result); dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3, 0, (isc_stdtime_t) 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) { result = ISC_R_SUCCESS; goto cleanup_node; } if (result != ISC_R_SUCCESS) goto cleanup_node; for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL)); if (!match_nsec3param(&nsec3, nsec3param)) continue; result = dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, name, rdataset.ttl, &rdata, &tuple); if (result != ISC_R_SUCCESS) goto failure; result = do_one_tuple(&tuple, db, version, diff); if (result != ISC_R_SUCCESS) goto failure; } if (result != ISC_R_NOMORE) goto failure; result = ISC_R_SUCCESS; failure: dns_rdataset_disassociate(&rdataset); cleanup_node: dns_db_detachnode(db, &node); return (result); } static isc_boolean_t better_param(dns_rdataset_t *nsec3paramset, dns_rdata_t *param) { dns_rdataset_t rdataset; isc_result_t result; if (REMOVE(param->data[1])) return (ISC_TRUE); dns_rdataset_init(&rdataset); dns_rdataset_clone(nsec3paramset, &rdataset); for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; if (rdataset.type != dns_rdatatype_nsec3param) { dns_rdata_t tmprdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &tmprdata); if (!dns_nsec3param_fromprivate(&tmprdata, &rdata, buf, sizeof(buf))) continue; } else dns_rdataset_current(&rdataset, &rdata); if (rdata.length != param->length) continue; if (rdata.data[0] != param->data[0] || REMOVE(rdata.data[1]) || rdata.data[2] != param->data[2] || rdata.data[3] != param->data[3] || rdata.data[4] != param->data[4] || memcmp(&rdata.data[5], ¶m->data[5], param->data[4])) continue; if (CREATE(rdata.data[1]) && !CREATE(param->data[1])) { dns_rdataset_disassociate(&rdataset); return (ISC_TRUE); } } dns_rdataset_disassociate(&rdataset); return (ISC_FALSE); } static isc_result_t find_nsec3(dns_rdata_nsec3_t *nsec3, dns_rdataset_t *rdataset, const dns_rdata_nsec3param_t *nsec3param) { isc_result_t result; for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(rdataset, &rdata); CHECK(dns_rdata_tostruct(&rdata, nsec3, NULL)); dns_rdata_reset(&rdata); if (match_nsec3param(nsec3, nsec3param)) break; } failure: return (result); } isc_result_t dns_nsec3_addnsec3(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, const dns_rdata_nsec3param_t *nsec3param, dns_ttl_t nsecttl, isc_boolean_t unsecure, dns_diff_t *diff) { dns_dbiterator_t *dbit = NULL; dns_dbnode_t *node = NULL; dns_dbnode_t *newnode = NULL; dns_difftuple_t *tuple = NULL; dns_fixedname_t fixed; dns_fixedname_t fprev; dns_hash_t hash; dns_name_t *hashname; dns_name_t *origin; dns_name_t *prev; dns_name_t empty; dns_rdata_nsec3_t nsec3; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_t rdataset; int pass; isc_boolean_t exists = ISC_FALSE; isc_boolean_t maybe_remove_unsecure = ISC_FALSE; isc_uint8_t flags; isc_buffer_t buffer; isc_result_t result; unsigned char *old_next; unsigned char *salt; unsigned char nexthash[NSEC3_MAX_HASH_LENGTH]; unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE]; unsigned int iterations; unsigned int labels; size_t next_length; unsigned int old_length; unsigned int salt_length; dns_fixedname_init(&fixed); hashname = dns_fixedname_name(&fixed); dns_fixedname_init(&fprev); prev = dns_fixedname_name(&fprev); dns_rdataset_init(&rdataset); origin = dns_db_origin(db); /* * Chain parameters. */ hash = nsec3param->hash; iterations = nsec3param->iterations; salt_length = nsec3param->salt_length; salt = nsec3param->salt; /* * Default flags for a new chain. */ flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT; /* * If this is the first NSEC3 in the chain nexthash will * remain pointing to itself. */ next_length = sizeof(nexthash); CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length, name, origin, hash, iterations, salt, salt_length)); INSIST(next_length <= sizeof(nexthash)); /* * Create the node if it doesn't exist and hold * a reference to it until we have added the NSEC3. */ CHECK(dns_db_findnsec3node(db, hashname, ISC_TRUE, &newnode)); /* * Seek the iterator to the 'newnode'. */ CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit)); CHECK(dns_dbiterator_seek(dbit, hashname)); CHECK(dns_dbiterator_pause(dbit)); result = dns_db_findrdataset(db, newnode, version, dns_rdatatype_nsec3, 0, (isc_stdtime_t) 0, &rdataset, NULL); /* * If we updating a existing NSEC3 then find its * next field. */ if (result == ISC_R_SUCCESS) { result = find_nsec3(&nsec3, &rdataset, nsec3param); if (result == ISC_R_SUCCESS) { if (!CREATE(nsec3param->flags)) flags = nsec3.flags; next_length = nsec3.next_length; INSIST(next_length <= sizeof(nexthash)); memmove(nexthash, nsec3.next, next_length); dns_rdataset_disassociate(&rdataset); /* * If the NSEC3 is not for a unsecure delegation then * we are just updating it. If it is for a unsecure * delegation then we need find out if we need to * remove the NSEC3 record or not by examining the * previous NSEC3 record. */ if (!unsecure) goto addnsec3; else if (CREATE(nsec3param->flags) && OPTOUT(flags)) { result = dns_nsec3_delnsec3(db, version, name, nsec3param, diff); goto failure; } else maybe_remove_unsecure = ISC_TRUE; } else { dns_rdataset_disassociate(&rdataset); if (result != ISC_R_NOMORE) goto failure; } } /* * Find the previous NSEC3 (if any) and update it if required. */ pass = 0; do { result = dns_dbiterator_prev(dbit); if (result == ISC_R_NOMORE) { pass++; CHECK(dns_dbiterator_last(dbit)); } CHECK(dns_dbiterator_current(dbit, &node, prev)); CHECK(dns_dbiterator_pause(dbit)); result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3, 0, (isc_stdtime_t) 0, &rdataset, NULL); dns_db_detachnode(db, &node); if (result != ISC_R_SUCCESS) continue; result = find_nsec3(&nsec3, &rdataset, nsec3param); if (result == ISC_R_NOMORE) { dns_rdataset_disassociate(&rdataset); continue; } if (result != ISC_R_SUCCESS) goto failure; if (maybe_remove_unsecure) { dns_rdataset_disassociate(&rdataset); /* * If we have OPTOUT set in the previous NSEC3 record * we actually need to delete the NSEC3 record. * Otherwise we just need to replace the NSEC3 record. */ if (OPTOUT(nsec3.flags)) { result = dns_nsec3_delnsec3(db, version, name, nsec3param, diff); goto failure; } goto addnsec3; } else { /* * Is this is a unsecure delegation we are adding? * If so no change is required. */ if (OPTOUT(nsec3.flags) && unsecure) { dns_rdataset_disassociate(&rdataset); goto failure; } } old_next = nsec3.next; old_length = nsec3.next_length; /* * Delete the old previous NSEC3. */ CHECK(delete(db, version, prev, nsec3param, diff)); /* * Fixup the previous NSEC3. */ nsec3.next = nexthash; nsec3.next_length = (unsigned char)next_length; isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf)); CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass, dns_rdatatype_nsec3, &nsec3, &buffer)); CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev, rdataset.ttl, &rdata, &tuple)); CHECK(do_one_tuple(&tuple, db, version, diff)); INSIST(old_length <= sizeof(nexthash)); memmove(nexthash, old_next, old_length); if (!CREATE(nsec3param->flags)) flags = nsec3.flags; dns_rdata_reset(&rdata); dns_rdataset_disassociate(&rdataset); break; } while (pass < 2); addnsec3: /* * Create the NSEC3 RDATA. */ CHECK(dns_db_findnode(db, name, ISC_FALSE, &node)); CHECK(dns_nsec3_buildrdata(db, version, node, hash, flags, iterations, salt, salt_length, nexthash, next_length, nsec3buf, &rdata)); dns_db_detachnode(db, &node); /* * Delete the old NSEC3 and record the change. */ CHECK(delete(db, version, hashname, nsec3param, diff)); /* * Add the new NSEC3 and record the change. */ CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, hashname, nsecttl, &rdata, &tuple)); CHECK(do_one_tuple(&tuple, db, version, diff)); INSIST(tuple == NULL); dns_rdata_reset(&rdata); dns_db_detachnode(db, &newnode); /* * Add missing NSEC3 records for empty nodes */ dns_name_init(&empty, NULL); dns_name_clone(name, &empty); do { labels = dns_name_countlabels(&empty) - 1; if (labels <= dns_name_countlabels(origin)) break; dns_name_getlabelsequence(&empty, 1, labels, &empty); CHECK(name_exists(db, version, &empty, &exists)); if (exists) break; CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length, &empty, origin, hash, iterations, salt, salt_length)); /* * Create the node if it doesn't exist and hold * a reference to it until we have added the NSEC3 * or we discover we don't need to add make a change. */ CHECK(dns_db_findnsec3node(db, hashname, ISC_TRUE, &newnode)); result = dns_db_findrdataset(db, newnode, version, dns_rdatatype_nsec3, 0, (isc_stdtime_t) 0, &rdataset, NULL); if (result == ISC_R_SUCCESS) { result = find_nsec3(&nsec3, &rdataset, nsec3param); dns_rdataset_disassociate(&rdataset); if (result == ISC_R_SUCCESS) { dns_db_detachnode(db, &newnode); break; } if (result != ISC_R_NOMORE) goto failure; } /* * Find the previous NSEC3 and update it. */ CHECK(dns_dbiterator_seek(dbit, hashname)); pass = 0; do { result = dns_dbiterator_prev(dbit); if (result == ISC_R_NOMORE) { pass++; CHECK(dns_dbiterator_last(dbit)); } CHECK(dns_dbiterator_current(dbit, &node, prev)); CHECK(dns_dbiterator_pause(dbit)); result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3, 0, (isc_stdtime_t) 0, &rdataset, NULL); dns_db_detachnode(db, &node); if (result != ISC_R_SUCCESS) continue; result = find_nsec3(&nsec3, &rdataset, nsec3param); if (result == ISC_R_NOMORE) { dns_rdataset_disassociate(&rdataset); continue; } if (result != ISC_R_SUCCESS) goto failure; old_next = nsec3.next; old_length = nsec3.next_length; /* * Delete the old previous NSEC3. */ CHECK(delete(db, version, prev, nsec3param, diff)); /* * Fixup the previous NSEC3. */ nsec3.next = nexthash; nsec3.next_length = (unsigned char)next_length; isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf)); CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass, dns_rdatatype_nsec3, &nsec3, &buffer)); CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev, rdataset.ttl, &rdata, &tuple)); CHECK(do_one_tuple(&tuple, db, version, diff)); INSIST(old_length <= sizeof(nexthash)); memmove(nexthash, old_next, old_length); if (!CREATE(nsec3param->flags)) flags = nsec3.flags; dns_rdata_reset(&rdata); dns_rdataset_disassociate(&rdataset); break; } while (pass < 2); INSIST(pass < 2); /* * Create the NSEC3 RDATA for the empty node. */ CHECK(dns_nsec3_buildrdata(db, version, NULL, hash, flags, iterations, salt, salt_length, nexthash, next_length, nsec3buf, &rdata)); /* * Delete the old NSEC3 and record the change. */ CHECK(delete(db, version, hashname, nsec3param, diff)); /* * Add the new NSEC3 and record the change. */ CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, hashname, nsecttl, &rdata, &tuple)); CHECK(do_one_tuple(&tuple, db, version, diff)); INSIST(tuple == NULL); dns_rdata_reset(&rdata); dns_db_detachnode(db, &newnode); } while (1); /* result cannot be ISC_R_NOMORE here */ INSIST(result != ISC_R_NOMORE); failure: if (dbit != NULL) dns_dbiterator_destroy(&dbit); if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (node != NULL) dns_db_detachnode(db, &node); if (newnode != NULL) dns_db_detachnode(db, &newnode); return (result); } /*% * Add NSEC3 records for "name", recording the change in "diff". * The existing NSEC3 records are removed. */ isc_result_t dns_nsec3_addnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, dns_ttl_t nsecttl, isc_boolean_t unsecure, dns_diff_t *diff) { dns_dbnode_t *node = NULL; dns_rdata_nsec3param_t nsec3param; dns_rdataset_t rdataset; isc_result_t result; dns_rdataset_init(&rdataset); /* * Find the NSEC3 parameters for this zone. */ result = dns_db_getoriginnode(db, &node); if (result != ISC_R_SUCCESS) return (result); result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3param, 0, 0, &rdataset, NULL); dns_db_detachnode(db, &node); if (result == ISC_R_NOTFOUND) return (ISC_R_SUCCESS); if (result != ISC_R_SUCCESS) return (result); /* * Update each active NSEC3 chain. */ for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); if (nsec3param.flags != 0) continue; /* * We have a active chain. Update it. */ CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param, nsecttl, unsecure, diff)); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; failure: if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (node != NULL) dns_db_detachnode(db, &node); return (result); } isc_boolean_t dns_nsec3param_fromprivate(dns_rdata_t *src, dns_rdata_t *target, unsigned char *buf, size_t buflen) { dns_decompress_t dctx; isc_result_t result; isc_buffer_t buf1; isc_buffer_t buf2; /* * Algorithm 0 (reserved by RFC 4034) is used to identify * NSEC3PARAM records from DNSKEY pointers. */ if (src->length < 1 || src->data[0] != 0) return (ISC_FALSE); isc_buffer_init(&buf1, src->data + 1, src->length - 1); isc_buffer_add(&buf1, src->length - 1); isc_buffer_setactive(&buf1, src->length - 1); isc_buffer_init(&buf2, buf, (unsigned int)buflen); dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE); result = dns_rdata_fromwire(target, src->rdclass, dns_rdatatype_nsec3param, &buf1, &dctx, 0, &buf2); dns_decompress_invalidate(&dctx); return (ISC_TF(result == ISC_R_SUCCESS)); } void dns_nsec3param_toprivate(dns_rdata_t *src, dns_rdata_t *target, dns_rdatatype_t privatetype, unsigned char *buf, size_t buflen) { REQUIRE(buflen >= src->length + 1); REQUIRE(DNS_RDATA_INITIALIZED(target)); memmove(buf + 1, src->data, src->length); buf[0] = 0; target->data = buf; target->length = src->length + 1; target->type = privatetype; target->rdclass = src->rdclass; target->flags = 0; ISC_LINK_INIT(target, link); } static isc_result_t rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, const dns_rdata_t *rdata, isc_boolean_t *flag) { dns_rdataset_t rdataset; dns_dbnode_t *node = NULL; isc_result_t result; dns_rdataset_init(&rdataset); if (rdata->type == dns_rdatatype_nsec3) CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node)); else CHECK(dns_db_findnode(db, name, ISC_FALSE, &node)); result = dns_db_findrdataset(db, node, ver, rdata->type, 0, (isc_stdtime_t) 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) { *flag = ISC_FALSE; result = ISC_R_SUCCESS; goto failure; } for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t myrdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &myrdata); if (!dns_rdata_casecompare(&myrdata, rdata)) break; } dns_rdataset_disassociate(&rdataset); if (result == ISC_R_SUCCESS) { *flag = ISC_TRUE; } else if (result == ISC_R_NOMORE) { *flag = ISC_FALSE; result = ISC_R_SUCCESS; } failure: if (node != NULL) dns_db_detachnode(db, &node); return (result); } isc_result_t dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver, dns_zone_t *zone, isc_boolean_t nonsec, dns_diff_t *diff) { dns_dbnode_t *node = NULL; dns_difftuple_t *tuple = NULL; dns_name_t next; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_t rdataset; isc_boolean_t flag; isc_result_t result = ISC_R_SUCCESS; unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE + 1]; dns_name_t *origin = dns_zone_getorigin(zone); dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone); dns_name_init(&next, NULL); dns_rdataset_init(&rdataset); result = dns_db_getoriginnode(db, &node); if (result != ISC_R_SUCCESS) return (result); /* * Cause all NSEC3 chains to be deleted. */ result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0, (isc_stdtime_t) 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) goto try_private; if (result != ISC_R_SUCCESS) goto failure; for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t private = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin, rdataset.ttl, &rdata, &tuple)); CHECK(do_one_tuple(&tuple, db, ver, diff)); INSIST(tuple == NULL); dns_nsec3param_toprivate(&rdata, &private, privatetype, buf, sizeof(buf)); buf[2] = DNS_NSEC3FLAG_REMOVE; if (nonsec) buf[2] |= DNS_NSEC3FLAG_NONSEC; CHECK(rr_exists(db, ver, origin, &private, &flag)); if (!flag) { CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, origin, 0, &private, &tuple)); CHECK(do_one_tuple(&tuple, db, ver, diff)); INSIST(tuple == NULL); } dns_rdata_reset(&rdata); } if (result != ISC_R_NOMORE) goto failure; dns_rdataset_disassociate(&rdataset); try_private: if (privatetype == 0) goto success; result = dns_db_findrdataset(db, node, ver, privatetype, 0, (isc_stdtime_t) 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) goto success; if (result != ISC_R_SUCCESS) goto failure; for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_reset(&rdata); dns_rdataset_current(&rdataset, &rdata); INSIST(rdata.length <= sizeof(buf)); memmove(buf, rdata.data, rdata.length); /* * Private NSEC3 record length >= 6. * <0(1), hash(1), flags(1), iterations(2), saltlen(1)> */ if (rdata.length < 6 || buf[0] != 0 || (buf[2] & DNS_NSEC3FLAG_REMOVE) != 0 || (nonsec && (buf[2] & DNS_NSEC3FLAG_NONSEC) != 0)) continue; CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin, 0, &rdata, &tuple)); CHECK(do_one_tuple(&tuple, db, ver, diff)); INSIST(tuple == NULL); rdata.data = buf; buf[2] = DNS_NSEC3FLAG_REMOVE; if (nonsec) buf[2] |= DNS_NSEC3FLAG_NONSEC; CHECK(rr_exists(db, ver, origin, &rdata, &flag)); if (!flag) { CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, origin, 0, &rdata, &tuple)); CHECK(do_one_tuple(&tuple, db, ver, diff)); INSIST(tuple == NULL); } } if (result != ISC_R_NOMORE) goto failure; success: result = ISC_R_SUCCESS; failure: if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); dns_db_detachnode(db, &node); return (result); } isc_result_t dns_nsec3_addnsec3sx(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, dns_ttl_t nsecttl, isc_boolean_t unsecure, dns_rdatatype_t type, dns_diff_t *diff) { dns_dbnode_t *node = NULL; dns_rdata_nsec3param_t nsec3param; dns_rdataset_t rdataset; dns_rdataset_t prdataset; isc_result_t result; dns_rdataset_init(&rdataset); dns_rdataset_init(&prdataset); /* * Find the NSEC3 parameters for this zone. */ result = dns_db_getoriginnode(db, &node); if (result != ISC_R_SUCCESS) return (result); result = dns_db_findrdataset(db, node, version, type, 0, 0, &prdataset, NULL); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) goto failure; result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3param, 0, 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) goto try_private; if (result != ISC_R_SUCCESS) goto failure; /* * Update each active NSEC3 chain. */ for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); if (nsec3param.flags != 0) continue; /* * We have a active chain. Update it. */ CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param, nsecttl, unsecure, diff)); } if (result != ISC_R_NOMORE) goto failure; dns_rdataset_disassociate(&rdataset); try_private: if (!dns_rdataset_isassociated(&prdataset)) goto success; /* * Update each active NSEC3 chain. */ for (result = dns_rdataset_first(&prdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&prdataset)) { dns_rdata_t rdata1 = DNS_RDATA_INIT; dns_rdata_t rdata2 = DNS_RDATA_INIT; unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; dns_rdataset_current(&prdataset, &rdata1); if (!dns_nsec3param_fromprivate(&rdata1, &rdata2, buf, sizeof(buf))) continue; CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL)); if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) continue; if (better_param(&prdataset, &rdata2)) continue; /* * We have a active chain. Update it. */ CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param, nsecttl, unsecure, diff)); } if (result == ISC_R_NOMORE) success: result = ISC_R_SUCCESS; failure: if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (dns_rdataset_isassociated(&prdataset)) dns_rdataset_disassociate(&prdataset); if (node != NULL) dns_db_detachnode(db, &node); return (result); } /*% * Determine whether any NSEC3 records that were associated with * 'name' should be deleted or if they should continue to exist. * ISC_TRUE indicates they should be deleted. * ISC_FALSE indicates they should be retained. */ static isc_result_t deleteit(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, isc_boolean_t *yesno) { isc_result_t result; dns_fixedname_t foundname; dns_fixedname_init(&foundname); result = dns_db_find(db, name, ver, dns_rdatatype_any, DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD, (isc_stdtime_t) 0, NULL, dns_fixedname_name(&foundname), NULL, NULL); if (result == DNS_R_EMPTYNAME || result == ISC_R_SUCCESS || result == DNS_R_ZONECUT) { *yesno = ISC_FALSE; return (ISC_R_SUCCESS); } if (result == DNS_R_GLUE || result == DNS_R_DNAME || result == DNS_R_DELEGATION || result == DNS_R_NXDOMAIN) { *yesno = ISC_TRUE; return (ISC_R_SUCCESS); } /* * Silence compiler. */ *yesno = ISC_TRUE; return (result); } isc_result_t dns_nsec3_delnsec3(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff) { dns_dbiterator_t *dbit = NULL; dns_dbnode_t *node = NULL; dns_difftuple_t *tuple = NULL; dns_fixedname_t fixed; dns_fixedname_t fprev; dns_hash_t hash; dns_name_t *hashname; dns_name_t *origin; dns_name_t *prev; dns_name_t empty; dns_rdata_nsec3_t nsec3; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_t rdataset; int pass; isc_boolean_t yesno; isc_buffer_t buffer; isc_result_t result; unsigned char *salt; unsigned char nexthash[NSEC3_MAX_HASH_LENGTH]; unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE]; unsigned int iterations; unsigned int labels; size_t next_length; unsigned int salt_length; dns_fixedname_init(&fixed); hashname = dns_fixedname_name(&fixed); dns_fixedname_init(&fprev); prev = dns_fixedname_name(&fprev); dns_rdataset_init(&rdataset); origin = dns_db_origin(db); /* * Chain parameters. */ hash = nsec3param->hash; iterations = nsec3param->iterations; salt_length = nsec3param->salt_length; salt = nsec3param->salt; /* * If this is the first NSEC3 in the chain nexthash will * remain pointing to itself. */ next_length = sizeof(nexthash); CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length, name, origin, hash, iterations, salt, salt_length)); CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit)); result = dns_dbiterator_seek(dbit, hashname); if (result == ISC_R_NOTFOUND) goto success; if (result != ISC_R_SUCCESS) goto failure; CHECK(dns_dbiterator_current(dbit, &node, NULL)); CHECK(dns_dbiterator_pause(dbit)); result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3, 0, (isc_stdtime_t) 0, &rdataset, NULL); dns_db_detachnode(db, &node); if (result == ISC_R_NOTFOUND) goto success; if (result != ISC_R_SUCCESS) goto failure; /* * If we find a existing NSEC3 for this chain then save the * next field. */ result = find_nsec3(&nsec3, &rdataset, nsec3param); if (result == ISC_R_SUCCESS) { next_length = nsec3.next_length; INSIST(next_length <= sizeof(nexthash)); memmove(nexthash, nsec3.next, next_length); } dns_rdataset_disassociate(&rdataset); if (result == ISC_R_NOMORE) goto success; if (result != ISC_R_SUCCESS) goto failure; /* * Find the previous NSEC3 and update it. */ pass = 0; do { result = dns_dbiterator_prev(dbit); if (result == ISC_R_NOMORE) { pass++; CHECK(dns_dbiterator_last(dbit)); } CHECK(dns_dbiterator_current(dbit, &node, prev)); CHECK(dns_dbiterator_pause(dbit)); result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3, 0, (isc_stdtime_t) 0, &rdataset, NULL); dns_db_detachnode(db, &node); if (result != ISC_R_SUCCESS) continue; result = find_nsec3(&nsec3, &rdataset, nsec3param); if (result == ISC_R_NOMORE) { dns_rdataset_disassociate(&rdataset); continue; } if (result != ISC_R_SUCCESS) goto failure; /* * Delete the old previous NSEC3. */ CHECK(delete(db, version, prev, nsec3param, diff)); /* * Fixup the previous NSEC3. */ nsec3.next = nexthash; nsec3.next_length = (unsigned char)next_length; if (CREATE(nsec3param->flags)) nsec3.flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT; isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf)); CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass, dns_rdatatype_nsec3, &nsec3, &buffer)); CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev, rdataset.ttl, &rdata, &tuple)); CHECK(do_one_tuple(&tuple, db, version, diff)); dns_rdata_reset(&rdata); dns_rdataset_disassociate(&rdataset); break; } while (pass < 2); /* * Delete the old NSEC3 and record the change. */ CHECK(delete(db, version, hashname, nsec3param, diff)); /* * Delete NSEC3 records for now non active nodes. */ dns_name_init(&empty, NULL); dns_name_clone(name, &empty); do { labels = dns_name_countlabels(&empty) - 1; if (labels <= dns_name_countlabels(origin)) break; dns_name_getlabelsequence(&empty, 1, labels, &empty); CHECK(deleteit(db, version, &empty, &yesno)); if (!yesno) break; CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length, &empty, origin, hash, iterations, salt, salt_length)); result = dns_dbiterator_seek(dbit, hashname); if (result == ISC_R_NOTFOUND) goto success; if (result != ISC_R_SUCCESS) goto failure; CHECK(dns_dbiterator_current(dbit, &node, NULL)); CHECK(dns_dbiterator_pause(dbit)); result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3, 0, (isc_stdtime_t) 0, &rdataset, NULL); dns_db_detachnode(db, &node); if (result == ISC_R_NOTFOUND) goto success; if (result != ISC_R_SUCCESS) goto failure; result = find_nsec3(&nsec3, &rdataset, nsec3param); if (result == ISC_R_SUCCESS) { next_length = nsec3.next_length; INSIST(next_length <= sizeof(nexthash)); memmove(nexthash, nsec3.next, next_length); } dns_rdataset_disassociate(&rdataset); if (result == ISC_R_NOMORE) goto success; if (result != ISC_R_SUCCESS) goto failure; pass = 0; do { result = dns_dbiterator_prev(dbit); if (result == ISC_R_NOMORE) { pass++; CHECK(dns_dbiterator_last(dbit)); } CHECK(dns_dbiterator_current(dbit, &node, prev)); CHECK(dns_dbiterator_pause(dbit)); result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3, 0, (isc_stdtime_t) 0, &rdataset, NULL); dns_db_detachnode(db, &node); if (result != ISC_R_SUCCESS) continue; result = find_nsec3(&nsec3, &rdataset, nsec3param); if (result == ISC_R_NOMORE) { dns_rdataset_disassociate(&rdataset); continue; } if (result != ISC_R_SUCCESS) goto failure; /* * Delete the old previous NSEC3. */ CHECK(delete(db, version, prev, nsec3param, diff)); /* * Fixup the previous NSEC3. */ nsec3.next = nexthash; nsec3.next_length = (unsigned char)next_length; isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf)); CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass, dns_rdatatype_nsec3, &nsec3, &buffer)); CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev, rdataset.ttl, &rdata, &tuple)); CHECK(do_one_tuple(&tuple, db, version, diff)); dns_rdata_reset(&rdata); dns_rdataset_disassociate(&rdataset); break; } while (pass < 2); INSIST(pass < 2); /* * Delete the old NSEC3 and record the change. */ CHECK(delete(db, version, hashname, nsec3param, diff)); } while (1); success: result = ISC_R_SUCCESS; failure: if (dbit != NULL) dns_dbiterator_destroy(&dbit); if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (node != NULL) dns_db_detachnode(db, &node); return (result); } isc_result_t dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, dns_diff_t *diff) { return (dns_nsec3_delnsec3sx(db, version, name, 0, diff)); } isc_result_t dns_nsec3_delnsec3sx(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, dns_rdatatype_t privatetype, dns_diff_t *diff) { dns_dbnode_t *node = NULL; dns_rdata_nsec3param_t nsec3param; dns_rdataset_t rdataset; isc_result_t result; dns_rdataset_init(&rdataset); /* * Find the NSEC3 parameters for this zone. */ result = dns_db_getoriginnode(db, &node); if (result != ISC_R_SUCCESS) return (result); result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3param, 0, 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) goto try_private; if (result != ISC_R_SUCCESS) goto failure; /* * Update each active NSEC3 chain. */ for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); if (nsec3param.flags != 0) continue; /* * We have a active chain. Update it. */ CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff)); } dns_rdataset_disassociate(&rdataset); try_private: if (privatetype == 0) goto success; result = dns_db_findrdataset(db, node, version, privatetype, 0, 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) goto success; if (result != ISC_R_SUCCESS) goto failure; /* * Update each NSEC3 chain being built. */ for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t rdata1 = DNS_RDATA_INIT; dns_rdata_t rdata2 = DNS_RDATA_INIT; unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; dns_rdataset_current(&rdataset, &rdata1); if (!dns_nsec3param_fromprivate(&rdata1, &rdata2, buf, sizeof(buf))) continue; CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL)); if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) continue; if (better_param(&rdataset, &rdata2)) continue; /* * We have a active chain. Update it. */ CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff)); } if (result == ISC_R_NOMORE) success: result = ISC_R_SUCCESS; failure: if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (node != NULL) dns_db_detachnode(db, &node); return (result); } isc_result_t dns_nsec3_active(dns_db_t *db, dns_dbversion_t *version, isc_boolean_t complete, isc_boolean_t *answer) { return (dns_nsec3_activex(db, version, complete, 0, answer)); } isc_result_t dns_nsec3_activex(dns_db_t *db, dns_dbversion_t *version, isc_boolean_t complete, dns_rdatatype_t privatetype, isc_boolean_t *answer) { dns_dbnode_t *node = NULL; dns_rdataset_t rdataset; dns_rdata_nsec3param_t nsec3param; isc_result_t result; REQUIRE(answer != NULL); dns_rdataset_init(&rdataset); result = dns_db_getoriginnode(db, &node); if (result != ISC_R_SUCCESS) return (result); result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3param, 0, 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) goto try_private; if (result != ISC_R_SUCCESS) { dns_db_detachnode(db, &node); return (result); } for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (nsec3param.flags == 0) break; } dns_rdataset_disassociate(&rdataset); if (result == ISC_R_SUCCESS) { dns_db_detachnode(db, &node); *answer = ISC_TRUE; return (ISC_R_SUCCESS); } if (result == ISC_R_NOMORE) *answer = ISC_FALSE; try_private: if (privatetype == 0 || complete) { *answer = ISC_FALSE; return (ISC_R_SUCCESS); } result = dns_db_findrdataset(db, node, version, privatetype, 0, 0, &rdataset, NULL); dns_db_detachnode(db, &node); if (result == ISC_R_NOTFOUND) { *answer = ISC_FALSE; return (ISC_R_SUCCESS); } if (result != ISC_R_SUCCESS) return (result); for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t rdata1 = DNS_RDATA_INIT; dns_rdata_t rdata2 = DNS_RDATA_INIT; unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; dns_rdataset_current(&rdataset, &rdata1); if (!dns_nsec3param_fromprivate(&rdata1, &rdata2, buf, sizeof(buf))) continue; result = dns_rdata_tostruct(&rdata2, &nsec3param, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (!complete && CREATE(nsec3param.flags)) break; } dns_rdataset_disassociate(&rdataset); if (result == ISC_R_SUCCESS) { *answer = ISC_TRUE; result = ISC_R_SUCCESS; } if (result == ISC_R_NOMORE) { *answer = ISC_FALSE; result = ISC_R_SUCCESS; } return (result); } isc_result_t dns_nsec3_maxiterations(dns_db_t *db, dns_dbversion_t *version, isc_mem_t *mctx, unsigned int *iterationsp) { dns_dbnode_t *node = NULL; dns_rdataset_t rdataset; dst_key_t *key = NULL; isc_buffer_t buffer; isc_result_t result; unsigned int bits, minbits = 4096; result = dns_db_getoriginnode(db, &node); if (result != ISC_R_SUCCESS) return (result); dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, 0, 0, &rdataset, NULL); dns_db_detachnode(db, &node); if (result == ISC_R_NOTFOUND) { *iterationsp = 0; return (ISC_R_SUCCESS); } if (result != ISC_R_SUCCESS) goto failure; for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); isc_buffer_init(&buffer, rdata.data, rdata.length); isc_buffer_add(&buffer, rdata.length); CHECK(dst_key_fromdns(dns_db_origin(db), rdataset.rdclass, &buffer, mctx, &key)); bits = dst_key_size(key); dst_key_free(&key); if (minbits > bits) minbits = bits; } if (result != ISC_R_NOMORE) goto failure; if (minbits <= 1024) *iterationsp = 150; else if (minbits <= 2048) *iterationsp = 500; else *iterationsp = 2500; result = ISC_R_SUCCESS; failure: if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); return (result); } isc_result_t dns_nsec3_noexistnodata(dns_rdatatype_t type, dns_name_t* name, dns_name_t *nsec3name, dns_rdataset_t *nsec3set, dns_name_t *zonename, isc_boolean_t *exists, isc_boolean_t *data, isc_boolean_t *optout, isc_boolean_t *unknown, isc_boolean_t *setclosest, isc_boolean_t *setnearest, dns_name_t *closest, dns_name_t *nearest, dns_nseclog_t logit, void *arg) { char namebuf[DNS_NAME_FORMATSIZE]; dns_fixedname_t fzone; dns_fixedname_t qfixed; dns_label_t hashlabel; dns_name_t *qname; dns_name_t *zone; dns_rdata_nsec3_t nsec3; dns_rdata_t rdata = DNS_RDATA_INIT; int order; int scope; isc_boolean_t atparent; isc_boolean_t first; isc_boolean_t ns; isc_boolean_t soa; isc_buffer_t buffer; isc_result_t answer = ISC_R_IGNORE; isc_result_t result; unsigned char hash[NSEC3_MAX_HASH_LENGTH]; unsigned char owner[NSEC3_MAX_HASH_LENGTH]; unsigned int length; unsigned int qlabels; unsigned int zlabels; REQUIRE((exists == NULL && data == NULL) || (exists != NULL && data != NULL)); REQUIRE(nsec3set != NULL && nsec3set->type == dns_rdatatype_nsec3); REQUIRE((setclosest == NULL && closest == NULL) || (setclosest != NULL && closest != NULL)); REQUIRE((setnearest == NULL && nearest == NULL) || (setnearest != NULL && nearest != NULL)); result = dns_rdataset_first(nsec3set); if (result != ISC_R_SUCCESS) { (*logit)(arg, ISC_LOG_DEBUG(3), "failure processing NSEC3 set"); return (result); } dns_rdataset_current(nsec3set, &rdata); result = dns_rdata_tostruct(&rdata, &nsec3, NULL); if (result != ISC_R_SUCCESS) return (result); (*logit)(arg, ISC_LOG_DEBUG(3), "looking for relevant NSEC3"); dns_fixedname_init(&fzone); zone = dns_fixedname_name(&fzone); zlabels = dns_name_countlabels(nsec3name); /* * NSEC3 records must have two or more labels to be valid. */ if (zlabels < 2) return (ISC_R_IGNORE); /* * Strip off the NSEC3 hash to get the zone. */ zlabels--; dns_name_split(nsec3name, zlabels, NULL, zone); /* * If not below the zone name we can ignore this record. */ if (!dns_name_issubdomain(name, zone)) return (ISC_R_IGNORE); /* * Is this zone the same or deeper than the current zone? */ if (dns_name_countlabels(zonename) == 0 || dns_name_issubdomain(zone, zonename)) dns_name_copy(zone, zonename, NULL); if (!dns_name_equal(zone, zonename)) return (ISC_R_IGNORE); /* * Are we only looking for the most enclosing zone? */ if (exists == NULL || data == NULL) return (ISC_R_SUCCESS); /* * Only set unknown once we are sure that this NSEC3 is from * the deepest covering zone. */ if (!dns_nsec3_supportedhash(nsec3.hash)) { if (unknown != NULL) *unknown = ISC_TRUE; return (ISC_R_IGNORE); } /* * Recover the hash from the first label. */ dns_name_getlabel(nsec3name, 0, &hashlabel); isc_region_consume(&hashlabel, 1); isc_buffer_init(&buffer, owner, sizeof(owner)); result = isc_base32hex_decoderegion(&hashlabel, &buffer); if (result != ISC_R_SUCCESS) return (result); /* * The hash lengths should match. If not ignore the record. */ if (isc_buffer_usedlength(&buffer) != nsec3.next_length) return (ISC_R_IGNORE); /* * Work out what this NSEC3 covers. * Inside (<0) or outside (>=0). */ scope = isc_safe_memcompare(owner, nsec3.next, nsec3.next_length); /* * Prepare to compute all the hashes. */ dns_fixedname_init(&qfixed); qname = dns_fixedname_name(&qfixed); dns_name_downcase(name, qname, NULL); qlabels = dns_name_countlabels(qname); first = ISC_TRUE; while (qlabels >= zlabels) { length = isc_iterated_hash(hash, nsec3.hash, nsec3.iterations, nsec3.salt, nsec3.salt_length, qname->ndata, qname->length); /* * The computed hash length should match. */ if (length != nsec3.next_length) { (*logit)(arg, ISC_LOG_DEBUG(3), "ignoring NSEC bad length %u vs %u", length, nsec3.next_length); return (ISC_R_IGNORE); } order = isc_safe_memcompare(hash, owner, length); if (first && order == 0) { /* * The hashes are the same. */ atparent = dns_rdatatype_atparent(type); ns = dns_nsec3_typepresent(&rdata, dns_rdatatype_ns); soa = dns_nsec3_typepresent(&rdata, dns_rdatatype_soa); if (ns && !soa) { if (!atparent) { /* * This NSEC3 record is from somewhere * higher in the DNS, and at the * parent of a delegation. It can not * be legitimately used here. */ (*logit)(arg, ISC_LOG_DEBUG(3), "ignoring parent NSEC3"); return (ISC_R_IGNORE); } } else if (atparent && ns && soa) { /* * This NSEC3 record is from the child. * It can not be legitimately used here. */ (*logit)(arg, ISC_LOG_DEBUG(3), "ignoring child NSEC3"); return (ISC_R_IGNORE); } if (type == dns_rdatatype_cname || type == dns_rdatatype_nxt || type == dns_rdatatype_nsec || type == dns_rdatatype_key || !dns_nsec3_typepresent(&rdata, dns_rdatatype_cname)) { *exists = ISC_TRUE; *data = dns_nsec3_typepresent(&rdata, type); (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC3 proves name exists (owner) " "data=%d", *data); return (ISC_R_SUCCESS); } (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC3 proves CNAME exists"); return (ISC_R_IGNORE); } if (order == 0 && dns_nsec3_typepresent(&rdata, dns_rdatatype_ns) && !dns_nsec3_typepresent(&rdata, dns_rdatatype_soa)) { /* * This NSEC3 record is from somewhere higher in * the DNS, and at the parent of a delegation. * It can not be legitimately used here. */ (*logit)(arg, ISC_LOG_DEBUG(3), "ignoring parent NSEC3"); return (ISC_R_IGNORE); } /* * Potential closest encloser. */ if (order == 0) { if (closest != NULL && (dns_name_countlabels(closest) == 0 || dns_name_issubdomain(qname, closest)) && !dns_nsec3_typepresent(&rdata, dns_rdatatype_ds) && !dns_nsec3_typepresent(&rdata, dns_rdatatype_dname) && (dns_nsec3_typepresent(&rdata, dns_rdatatype_soa) || !dns_nsec3_typepresent(&rdata, dns_rdatatype_ns))) { dns_name_format(qname, namebuf, sizeof(namebuf)); (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC3 indicates potential closest " "encloser: '%s'", namebuf); dns_name_copy(qname, closest, NULL); *setclosest = ISC_TRUE; } dns_name_format(qname, namebuf, sizeof(namebuf)); (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC3 at super-domain %s", namebuf); return (answer); } /* * Find if the name does not exist. * * We continue as we need to find the name closest to the * closest encloser that doesn't exist. * * We also need to continue to ensure that we are not * proving the non-existence of a record in a sub-zone. * If that would be the case we will return ISC_R_IGNORE * above. */ if ((scope < 0 && order > 0 && memcmp(hash, nsec3.next, length) < 0) || (scope >= 0 && (order > 0 || memcmp(hash, nsec3.next, length) < 0))) { dns_name_format(qname, namebuf, sizeof(namebuf)); (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC3 proves " "name does not exist: '%s'", namebuf); if (nearest != NULL && (dns_name_countlabels(nearest) == 0 || dns_name_issubdomain(nearest, qname))) { dns_name_copy(qname, nearest, NULL); *setnearest = ISC_TRUE; } *exists = ISC_FALSE; *data = ISC_FALSE; if (optout != NULL) { if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0) (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC3 indicates optout"); else (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC3 indicates secure range"); *optout = ISC_TF(nsec3.flags & DNS_NSEC3FLAG_OPTOUT); } answer = ISC_R_SUCCESS; } qlabels--; if (qlabels > 0) dns_name_split(qname, qlabels, NULL, qname); first = ISC_FALSE; } return (answer); } bind9-9.10.3.dfsg.P4/lib/dns/sdb.c0000644000470500017500000011351712664710322015647 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "rdatalist_p.h" struct dns_sdbimplementation { const dns_sdbmethods_t *methods; void *driverdata; unsigned int flags; isc_mem_t *mctx; isc_mutex_t driverlock; dns_dbimplementation_t *dbimp; }; struct dns_sdb { /* Unlocked */ dns_db_t common; char *zone; dns_sdbimplementation_t *implementation; void *dbdata; isc_mutex_t lock; /* Locked */ unsigned int references; }; struct dns_sdblookup { /* Unlocked */ unsigned int magic; dns_sdb_t *sdb; ISC_LIST(dns_rdatalist_t) lists; ISC_LIST(isc_buffer_t) buffers; dns_name_t *name; ISC_LINK(dns_sdblookup_t) link; isc_mutex_t lock; dns_rdatacallbacks_t callbacks; /* Locked */ unsigned int references; }; typedef struct dns_sdblookup dns_sdbnode_t; struct dns_sdballnodes { dns_dbiterator_t common; ISC_LIST(dns_sdbnode_t) nodelist; dns_sdbnode_t *current; dns_sdbnode_t *origin; }; typedef dns_sdballnodes_t sdb_dbiterator_t; typedef struct sdb_rdatasetiter { dns_rdatasetiter_t common; dns_rdatalist_t *current; } sdb_rdatasetiter_t; #define SDB_MAGIC ISC_MAGIC('S', 'D', 'B', '-') /*% * Note that "impmagic" is not the first four bytes of the struct, so * ISC_MAGIC_VALID cannot be used. */ #define VALID_SDB(sdb) ((sdb) != NULL && \ (sdb)->common.impmagic == SDB_MAGIC) #define SDBLOOKUP_MAGIC ISC_MAGIC('S','D','B','L') #define VALID_SDBLOOKUP(sdbl) ISC_MAGIC_VALID(sdbl, SDBLOOKUP_MAGIC) #define VALID_SDBNODE(sdbn) VALID_SDBLOOKUP(sdbn) /* These values are taken from RFC1537 */ #define SDB_DEFAULT_REFRESH (60 * 60 * 8) #define SDB_DEFAULT_RETRY (60 * 60 * 2) #define SDB_DEFAULT_EXPIRE (60 * 60 * 24 * 7) #define SDB_DEFAULT_MINIMUM (60 * 60 * 24) /* This is a reasonable value */ #define SDB_DEFAULT_TTL (60 * 60 * 24) #ifdef __COVERITY__ #define MAYBE_LOCK(sdb) LOCK(&sdb->implementation->driverlock) #define MAYBE_UNLOCK(sdb) UNLOCK(&sdb->implementation->driverlock) #else #define MAYBE_LOCK(sdb) \ do { \ unsigned int flags = sdb->implementation->flags; \ if ((flags & DNS_SDBFLAG_THREADSAFE) == 0) \ LOCK(&sdb->implementation->driverlock); \ } while (0) #define MAYBE_UNLOCK(sdb) \ do { \ unsigned int flags = sdb->implementation->flags; \ if ((flags & DNS_SDBFLAG_THREADSAFE) == 0) \ UNLOCK(&sdb->implementation->driverlock); \ } while (0) #endif static int dummy; static isc_result_t dns_sdb_create(isc_mem_t *mctx, dns_name_t *origin, dns_dbtype_t type, dns_rdataclass_t rdclass, unsigned int argc, char *argv[], void *driverarg, dns_db_t **dbp); static isc_result_t findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdatatype_t type, dns_rdatatype_t covers, isc_stdtime_t now, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); static isc_result_t createnode(dns_sdb_t *sdb, dns_sdbnode_t **nodep); static void destroynode(dns_sdbnode_t *node); static void detachnode(dns_db_t *db, dns_dbnode_t **targetp); static void list_tordataset(dns_rdatalist_t *rdatalist, dns_db_t *db, dns_dbnode_t *node, dns_rdataset_t *rdataset); static void dbiterator_destroy(dns_dbiterator_t **iteratorp); static isc_result_t dbiterator_first(dns_dbiterator_t *iterator); static isc_result_t dbiterator_last(dns_dbiterator_t *iterator); static isc_result_t dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name); static isc_result_t dbiterator_prev(dns_dbiterator_t *iterator); static isc_result_t dbiterator_next(dns_dbiterator_t *iterator); static isc_result_t dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep, dns_name_t *name); static isc_result_t dbiterator_pause(dns_dbiterator_t *iterator); static isc_result_t dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name); static dns_dbiteratormethods_t dbiterator_methods = { dbiterator_destroy, dbiterator_first, dbiterator_last, dbiterator_seek, dbiterator_prev, dbiterator_next, dbiterator_current, dbiterator_pause, dbiterator_origin }; static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp); static isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator); static isc_result_t rdatasetiter_next(dns_rdatasetiter_t *iterator); static void rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset); static dns_rdatasetitermethods_t rdatasetiter_methods = { rdatasetiter_destroy, rdatasetiter_first, rdatasetiter_next, rdatasetiter_current }; /* * Functions used by implementors of simple databases */ isc_result_t dns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods, void *driverdata, unsigned int flags, isc_mem_t *mctx, dns_sdbimplementation_t **sdbimp) { dns_sdbimplementation_t *imp; isc_result_t result; REQUIRE(drivername != NULL); REQUIRE(methods != NULL); REQUIRE(methods->lookup != NULL || methods->lookup2 != NULL); REQUIRE(mctx != NULL); REQUIRE(sdbimp != NULL && *sdbimp == NULL); REQUIRE((flags & ~(DNS_SDBFLAG_RELATIVEOWNER | DNS_SDBFLAG_RELATIVERDATA | DNS_SDBFLAG_THREADSAFE| DNS_SDBFLAG_DNS64)) == 0); imp = isc_mem_get(mctx, sizeof(dns_sdbimplementation_t)); if (imp == NULL) return (ISC_R_NOMEMORY); imp->methods = methods; imp->driverdata = driverdata; imp->flags = flags; imp->mctx = NULL; isc_mem_attach(mctx, &imp->mctx); result = isc_mutex_init(&imp->driverlock); if (result != ISC_R_SUCCESS) goto cleanup_mctx; imp->dbimp = NULL; result = dns_db_register(drivername, dns_sdb_create, imp, mctx, &imp->dbimp); if (result != ISC_R_SUCCESS) goto cleanup_mutex; *sdbimp = imp; return (ISC_R_SUCCESS); cleanup_mutex: DESTROYLOCK(&imp->driverlock); cleanup_mctx: isc_mem_put(mctx, imp, sizeof(dns_sdbimplementation_t)); return (result); } void dns_sdb_unregister(dns_sdbimplementation_t **sdbimp) { dns_sdbimplementation_t *imp; isc_mem_t *mctx; REQUIRE(sdbimp != NULL && *sdbimp != NULL); imp = *sdbimp; dns_db_unregister(&imp->dbimp); DESTROYLOCK(&imp->driverlock); mctx = imp->mctx; isc_mem_put(mctx, imp, sizeof(dns_sdbimplementation_t)); isc_mem_detach(&mctx); *sdbimp = NULL; } static inline unsigned int initial_size(unsigned int len) { unsigned int size; for (size = 1024; size < (64 * 1024); size *= 2) if (len < size) return (size); return (65535); } isc_result_t dns_sdb_putrdata(dns_sdblookup_t *lookup, dns_rdatatype_t typeval, dns_ttl_t ttl, const unsigned char *rdatap, unsigned int rdlen) { dns_rdatalist_t *rdatalist; dns_rdata_t *rdata; isc_buffer_t *rdatabuf = NULL; isc_result_t result; isc_mem_t *mctx; isc_region_t region; mctx = lookup->sdb->common.mctx; rdatalist = ISC_LIST_HEAD(lookup->lists); while (rdatalist != NULL) { if (rdatalist->type == typeval) break; rdatalist = ISC_LIST_NEXT(rdatalist, link); } if (rdatalist == NULL) { rdatalist = isc_mem_get(mctx, sizeof(dns_rdatalist_t)); if (rdatalist == NULL) return (ISC_R_NOMEMORY); dns_rdatalist_init(rdatalist); rdatalist->rdclass = lookup->sdb->common.rdclass; rdatalist->type = typeval; rdatalist->ttl = ttl; ISC_LIST_APPEND(lookup->lists, rdatalist, link); } else if (rdatalist->ttl != ttl) return (DNS_R_BADTTL); rdata = isc_mem_get(mctx, sizeof(dns_rdata_t)); if (rdata == NULL) return (ISC_R_NOMEMORY); result = isc_buffer_allocate(mctx, &rdatabuf, rdlen); if (result != ISC_R_SUCCESS) goto failure; DE_CONST(rdatap, region.base); region.length = rdlen; isc_buffer_copyregion(rdatabuf, ®ion); isc_buffer_usedregion(rdatabuf, ®ion); dns_rdata_init(rdata); dns_rdata_fromregion(rdata, rdatalist->rdclass, rdatalist->type, ®ion); ISC_LIST_APPEND(rdatalist->rdata, rdata, link); ISC_LIST_APPEND(lookup->buffers, rdatabuf, link); rdata = NULL; failure: if (rdata != NULL) isc_mem_put(mctx, rdata, sizeof(dns_rdata_t)); return (result); } isc_result_t dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl, const char *data) { unsigned int datalen; dns_rdatatype_t typeval; isc_textregion_t r; isc_lex_t *lex = NULL; isc_result_t result; unsigned char *p = NULL; unsigned int size = 0; /* Init to suppress compiler warning */ isc_mem_t *mctx; dns_sdbimplementation_t *imp; dns_name_t *origin; isc_buffer_t b; isc_buffer_t rb; REQUIRE(VALID_SDBLOOKUP(lookup)); REQUIRE(type != NULL); REQUIRE(data != NULL); mctx = lookup->sdb->common.mctx; DE_CONST(type, r.base); r.length = strlen(type); result = dns_rdatatype_fromtext(&typeval, &r); if (result != ISC_R_SUCCESS) return (result); imp = lookup->sdb->implementation; if ((imp->flags & DNS_SDBFLAG_RELATIVERDATA) != 0) origin = &lookup->sdb->common.origin; else origin = dns_rootname; result = isc_lex_create(mctx, 64, &lex); if (result != ISC_R_SUCCESS) goto failure; datalen = strlen(data); size = initial_size(datalen); do { isc_buffer_constinit(&b, data, datalen); isc_buffer_add(&b, datalen); result = isc_lex_openbuffer(lex, &b); if (result != ISC_R_SUCCESS) goto failure; if (size >= 65535) size = 65535; p = isc_mem_get(mctx, size); if (p == NULL) { result = ISC_R_NOMEMORY; goto failure; } isc_buffer_init(&rb, p, size); result = dns_rdata_fromtext(NULL, lookup->sdb->common.rdclass, typeval, lex, origin, 0, mctx, &rb, &lookup->callbacks); if (result != ISC_R_NOSPACE) break; /* * Is the RR too big? */ if (size >= 65535) break; isc_mem_put(mctx, p, size); p = NULL; size *= 2; } while (result == ISC_R_NOSPACE); if (result != ISC_R_SUCCESS) goto failure; result = dns_sdb_putrdata(lookup, typeval, ttl, isc_buffer_base(&rb), isc_buffer_usedlength(&rb)); failure: if (p != NULL) isc_mem_put(mctx, p, size); if (lex != NULL) isc_lex_destroy(&lex); return (result); } static isc_result_t getnode(dns_sdballnodes_t *allnodes, const char *name, dns_sdbnode_t **nodep) { dns_name_t *newname, *origin; dns_fixedname_t fnewname; dns_sdb_t *sdb = (dns_sdb_t *)allnodes->common.db; dns_sdbimplementation_t *imp = sdb->implementation; dns_sdbnode_t *sdbnode; isc_mem_t *mctx = sdb->common.mctx; isc_buffer_t b; isc_result_t result; dns_fixedname_init(&fnewname); newname = dns_fixedname_name(&fnewname); if ((imp->flags & DNS_SDBFLAG_RELATIVERDATA) != 0) origin = &sdb->common.origin; else origin = dns_rootname; isc_buffer_constinit(&b, name, strlen(name)); isc_buffer_add(&b, strlen(name)); result = dns_name_fromtext(newname, &b, origin, 0, NULL); if (result != ISC_R_SUCCESS) return (result); if (allnodes->common.relative_names) { /* All names are relative to the root */ unsigned int nlabels = dns_name_countlabels(newname); dns_name_getlabelsequence(newname, 0, nlabels - 1, newname); } sdbnode = ISC_LIST_HEAD(allnodes->nodelist); if (sdbnode == NULL || !dns_name_equal(sdbnode->name, newname)) { sdbnode = NULL; result = createnode(sdb, &sdbnode); if (result != ISC_R_SUCCESS) return (result); sdbnode->name = isc_mem_get(mctx, sizeof(dns_name_t)); if (sdbnode->name == NULL) { destroynode(sdbnode); return (ISC_R_NOMEMORY); } dns_name_init(sdbnode->name, NULL); result = dns_name_dup(newname, mctx, sdbnode->name); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, sdbnode->name, sizeof(dns_name_t)); destroynode(sdbnode); return (result); } ISC_LIST_PREPEND(allnodes->nodelist, sdbnode, link); if (allnodes->origin == NULL && dns_name_equal(newname, &sdb->common.origin)) allnodes->origin = sdbnode; } *nodep = sdbnode; return (ISC_R_SUCCESS); } isc_result_t dns_sdb_putnamedrr(dns_sdballnodes_t *allnodes, const char *name, const char *type, dns_ttl_t ttl, const char *data) { isc_result_t result; dns_sdbnode_t *sdbnode = NULL; result = getnode(allnodes, name, &sdbnode); if (result != ISC_R_SUCCESS) return (result); return (dns_sdb_putrr(sdbnode, type, ttl, data)); } isc_result_t dns_sdb_putnamedrdata(dns_sdballnodes_t *allnodes, const char *name, dns_rdatatype_t type, dns_ttl_t ttl, const void *rdata, unsigned int rdlen) { isc_result_t result; dns_sdbnode_t *sdbnode = NULL; result = getnode(allnodes, name, &sdbnode); if (result != ISC_R_SUCCESS) return (result); return (dns_sdb_putrdata(sdbnode, type, ttl, rdata, rdlen)); } isc_result_t dns_sdb_putsoa(dns_sdblookup_t *lookup, const char *mname, const char *rname, isc_uint32_t serial) { char str[2 * DNS_NAME_MAXTEXT + 5 * (sizeof("2147483647")) + 7]; int n; REQUIRE(mname != NULL); REQUIRE(rname != NULL); n = snprintf(str, sizeof(str), "%s %s %u %u %u %u %u", mname, rname, serial, SDB_DEFAULT_REFRESH, SDB_DEFAULT_RETRY, SDB_DEFAULT_EXPIRE, SDB_DEFAULT_MINIMUM); if (n >= (int)sizeof(str) || n < 0) return (ISC_R_NOSPACE); return (dns_sdb_putrr(lookup, "SOA", SDB_DEFAULT_TTL, str)); } /* * DB routines */ static void attach(dns_db_t *source, dns_db_t **targetp) { dns_sdb_t *sdb = (dns_sdb_t *) source; REQUIRE(VALID_SDB(sdb)); LOCK(&sdb->lock); REQUIRE(sdb->references > 0); sdb->references++; UNLOCK(&sdb->lock); *targetp = source; } static void destroy(dns_sdb_t *sdb) { isc_mem_t *mctx; dns_sdbimplementation_t *imp = sdb->implementation; mctx = sdb->common.mctx; if (imp->methods->destroy != NULL) { MAYBE_LOCK(sdb); imp->methods->destroy(sdb->zone, imp->driverdata, &sdb->dbdata); MAYBE_UNLOCK(sdb); } isc_mem_free(mctx, sdb->zone); DESTROYLOCK(&sdb->lock); sdb->common.magic = 0; sdb->common.impmagic = 0; dns_name_free(&sdb->common.origin, mctx); isc_mem_put(mctx, sdb, sizeof(dns_sdb_t)); isc_mem_detach(&mctx); } static void detach(dns_db_t **dbp) { dns_sdb_t *sdb = (dns_sdb_t *)(*dbp); isc_boolean_t need_destroy = ISC_FALSE; REQUIRE(VALID_SDB(sdb)); LOCK(&sdb->lock); REQUIRE(sdb->references > 0); sdb->references--; if (sdb->references == 0) need_destroy = ISC_TRUE; UNLOCK(&sdb->lock); if (need_destroy) destroy(sdb); *dbp = NULL; } static isc_result_t beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) { UNUSED(db); UNUSED(callbacks); return (ISC_R_NOTIMPLEMENTED); } static isc_result_t endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) { UNUSED(db); UNUSED(callbacks); return (ISC_R_NOTIMPLEMENTED); } static isc_result_t dump(dns_db_t *db, dns_dbversion_t *version, const char *filename, dns_masterformat_t masterformat) { UNUSED(db); UNUSED(version); UNUSED(filename); UNUSED(masterformat); return (ISC_R_NOTIMPLEMENTED); } static void currentversion(dns_db_t *db, dns_dbversion_t **versionp) { REQUIRE(versionp != NULL && *versionp == NULL); UNUSED(db); *versionp = (void *) &dummy; return; } static isc_result_t newversion(dns_db_t *db, dns_dbversion_t **versionp) { UNUSED(db); UNUSED(versionp); return (ISC_R_NOTIMPLEMENTED); } static void attachversion(dns_db_t *db, dns_dbversion_t *source, dns_dbversion_t **targetp) { REQUIRE(source != NULL && source == (void *) &dummy); REQUIRE(targetp != NULL && *targetp == NULL); UNUSED(db); *targetp = source; return; } static void closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) { REQUIRE(versionp != NULL && *versionp == (void *) &dummy); REQUIRE(commit == ISC_FALSE); UNUSED(db); UNUSED(commit); *versionp = NULL; } static isc_result_t createnode(dns_sdb_t *sdb, dns_sdbnode_t **nodep) { dns_sdbnode_t *node; isc_result_t result; node = isc_mem_get(sdb->common.mctx, sizeof(dns_sdbnode_t)); if (node == NULL) return (ISC_R_NOMEMORY); node->sdb = NULL; attach((dns_db_t *)sdb, (dns_db_t **)&node->sdb); ISC_LIST_INIT(node->lists); ISC_LIST_INIT(node->buffers); ISC_LINK_INIT(node, link); node->name = NULL; result = isc_mutex_init(&node->lock); if (result != ISC_R_SUCCESS) { isc_mem_put(sdb->common.mctx, node, sizeof(dns_sdbnode_t)); return (result); } dns_rdatacallbacks_init(&node->callbacks); node->references = 1; node->magic = SDBLOOKUP_MAGIC; *nodep = node; return (ISC_R_SUCCESS); } static void destroynode(dns_sdbnode_t *node) { dns_rdatalist_t *list; dns_rdata_t *rdata; isc_buffer_t *b; dns_sdb_t *sdb; isc_mem_t *mctx; sdb = node->sdb; mctx = sdb->common.mctx; while (!ISC_LIST_EMPTY(node->lists)) { list = ISC_LIST_HEAD(node->lists); while (!ISC_LIST_EMPTY(list->rdata)) { rdata = ISC_LIST_HEAD(list->rdata); ISC_LIST_UNLINK(list->rdata, rdata, link); isc_mem_put(mctx, rdata, sizeof(dns_rdata_t)); } ISC_LIST_UNLINK(node->lists, list, link); isc_mem_put(mctx, list, sizeof(dns_rdatalist_t)); } while (!ISC_LIST_EMPTY(node->buffers)) { b = ISC_LIST_HEAD(node->buffers); ISC_LIST_UNLINK(node->buffers, b, link); isc_buffer_free(&b); } if (node->name != NULL) { dns_name_free(node->name, mctx); isc_mem_put(mctx, node->name, sizeof(dns_name_t)); } DESTROYLOCK(&node->lock); node->magic = 0; isc_mem_put(mctx, node, sizeof(dns_sdbnode_t)); detach((dns_db_t **) (void *)&sdb); } static isc_result_t findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep) { dns_sdb_t *sdb = (dns_sdb_t *)db; dns_sdbnode_t *node = NULL; isc_result_t result; isc_buffer_t b; char namestr[DNS_NAME_MAXTEXT + 1]; isc_boolean_t isorigin; dns_sdbimplementation_t *imp; dns_name_t relname; unsigned int labels; REQUIRE(VALID_SDB(sdb)); REQUIRE(create == ISC_FALSE); REQUIRE(nodep != NULL && *nodep == NULL); UNUSED(name); UNUSED(create); imp = sdb->implementation; isorigin = dns_name_equal(name, &sdb->common.origin); if (imp->methods->lookup2 != NULL) { if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) { labels = dns_name_countlabels(name) - dns_name_countlabels(&db->origin); dns_name_init(&relname, NULL); dns_name_getlabelsequence(name, 0, labels, &relname); name = &relname; } } else { isc_buffer_init(&b, namestr, sizeof(namestr)); if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) { labels = dns_name_countlabels(name) - dns_name_countlabels(&db->origin); dns_name_init(&relname, NULL); dns_name_getlabelsequence(name, 0, labels, &relname); result = dns_name_totext(&relname, ISC_TRUE, &b); if (result != ISC_R_SUCCESS) return (result); } else { result = dns_name_totext(name, ISC_TRUE, &b); if (result != ISC_R_SUCCESS) return (result); } isc_buffer_putuint8(&b, 0); } result = createnode(sdb, &node); if (result != ISC_R_SUCCESS) return (result); MAYBE_LOCK(sdb); if (imp->methods->lookup2 != NULL) result = imp->methods->lookup2(&sdb->common.origin, name, sdb->dbdata, node, methods, clientinfo); else result = imp->methods->lookup(sdb->zone, namestr, sdb->dbdata, node, methods, clientinfo); MAYBE_UNLOCK(sdb); if (result != ISC_R_SUCCESS && !(result == ISC_R_NOTFOUND && isorigin && imp->methods->authority != NULL)) { destroynode(node); return (result); } if (isorigin && imp->methods->authority != NULL) { MAYBE_LOCK(sdb); result = imp->methods->authority(sdb->zone, sdb->dbdata, node); MAYBE_UNLOCK(sdb); if (result != ISC_R_SUCCESS) { destroynode(node); return (result); } } *nodep = node; return (ISC_R_SUCCESS); } static isc_result_t findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { dns_sdb_t *sdb = (dns_sdb_t *)db; dns_dbnode_t *node = NULL; dns_fixedname_t fname; dns_rdataset_t xrdataset; dns_name_t *xname; unsigned int nlabels, olabels; isc_result_t result; unsigned int i; unsigned int flags; REQUIRE(VALID_SDB(sdb)); REQUIRE(nodep == NULL || *nodep == NULL); REQUIRE(version == NULL || version == (void *) &dummy); UNUSED(options); if (!dns_name_issubdomain(name, &db->origin)) return (DNS_R_NXDOMAIN); olabels = dns_name_countlabels(&db->origin); nlabels = dns_name_countlabels(name); dns_fixedname_init(&fname); xname = dns_fixedname_name(&fname); if (rdataset == NULL) { dns_rdataset_init(&xrdataset); rdataset = &xrdataset; } result = DNS_R_NXDOMAIN; flags = sdb->implementation->flags; i = (flags & DNS_SDBFLAG_DNS64) != 0 ? nlabels : olabels; for (; i <= nlabels; i++) { /* * Look up the next label. */ dns_name_getlabelsequence(name, nlabels - i, i, xname); result = findnodeext(db, xname, ISC_FALSE, methods, clientinfo, &node); if (result == ISC_R_NOTFOUND) { /* * No data at zone apex? */ if (i == olabels) return (DNS_R_BADDB); result = DNS_R_NXDOMAIN; continue; } if (result != ISC_R_SUCCESS) return (result); /* * DNS64 zone's don't have DNAME or NS records. */ if ((flags & DNS_SDBFLAG_DNS64) != 0) goto skip; /* * DNS64 zone's don't have DNAME or NS records. */ if ((flags & DNS_SDBFLAG_DNS64) != 0) goto skip; /* * Look for a DNAME at the current label, unless this is * the qname. */ if (i < nlabels) { result = findrdataset(db, node, version, dns_rdatatype_dname, 0, now, rdataset, sigrdataset); if (result == ISC_R_SUCCESS) { result = DNS_R_DNAME; break; } } /* * Look for an NS at the current label, unless this is the * origin or glue is ok. */ if (i != olabels && (options & DNS_DBFIND_GLUEOK) == 0) { result = findrdataset(db, node, version, dns_rdatatype_ns, 0, now, rdataset, sigrdataset); if (result == ISC_R_SUCCESS) { if (i == nlabels && type == dns_rdatatype_any) { result = DNS_R_ZONECUT; dns_rdataset_disassociate(rdataset); if (sigrdataset != NULL && dns_rdataset_isassociated (sigrdataset)) { dns_rdataset_disassociate (sigrdataset); } } else result = DNS_R_DELEGATION; break; } } /* * If the current name is not the qname, add another label * and try again. */ if (i < nlabels) { destroynode(node); node = NULL; continue; } skip: /* * If we're looking for ANY, we're done. */ if (type == dns_rdatatype_any) { result = ISC_R_SUCCESS; break; } /* * Look for the qtype. */ result = findrdataset(db, node, version, type, 0, now, rdataset, sigrdataset); if (result == ISC_R_SUCCESS) break; /* * Look for a CNAME */ if (type != dns_rdatatype_cname) { result = findrdataset(db, node, version, dns_rdatatype_cname, 0, now, rdataset, sigrdataset); if (result == ISC_R_SUCCESS) { result = DNS_R_CNAME; break; } } result = DNS_R_NXRRSET; break; } if (rdataset == &xrdataset && dns_rdataset_isassociated(rdataset)) dns_rdataset_disassociate(rdataset); if (foundname != NULL) { isc_result_t xresult; xresult = dns_name_copy(xname, foundname, NULL); if (xresult != ISC_R_SUCCESS) { if (node != NULL) destroynode(node); if (dns_rdataset_isassociated(rdataset)) dns_rdataset_disassociate(rdataset); return (DNS_R_BADDB); } } if (nodep != NULL) *nodep = node; else if (node != NULL) detachnode(db, &node); return (result); } static isc_result_t findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { UNUSED(db); UNUSED(name); UNUSED(options); UNUSED(now); UNUSED(nodep); UNUSED(foundname); UNUSED(rdataset); UNUSED(sigrdataset); return (ISC_R_NOTIMPLEMENTED); } static void attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) { dns_sdb_t *sdb = (dns_sdb_t *)db; dns_sdbnode_t *node = (dns_sdbnode_t *)source; REQUIRE(VALID_SDB(sdb)); UNUSED(sdb); LOCK(&node->lock); INSIST(node->references > 0); node->references++; INSIST(node->references != 0); /* Catch overflow. */ UNLOCK(&node->lock); *targetp = source; } static void detachnode(dns_db_t *db, dns_dbnode_t **targetp) { dns_sdb_t *sdb = (dns_sdb_t *)db; dns_sdbnode_t *node; isc_boolean_t need_destroy = ISC_FALSE; REQUIRE(VALID_SDB(sdb)); REQUIRE(targetp != NULL && *targetp != NULL); UNUSED(sdb); node = (dns_sdbnode_t *)(*targetp); LOCK(&node->lock); INSIST(node->references > 0); node->references--; if (node->references == 0) need_destroy = ISC_TRUE; UNLOCK(&node->lock); if (need_destroy) destroynode(node); *targetp = NULL; } static isc_result_t expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { UNUSED(db); UNUSED(node); UNUSED(now); INSIST(0); return (ISC_R_UNEXPECTED); } static void printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) { UNUSED(db); UNUSED(node); UNUSED(out); return; } static isc_result_t createiterator(dns_db_t *db, unsigned int options, dns_dbiterator_t **iteratorp) { dns_sdb_t *sdb = (dns_sdb_t *)db; sdb_dbiterator_t *sdbiter; dns_sdbimplementation_t *imp = sdb->implementation; isc_result_t result; REQUIRE(VALID_SDB(sdb)); if (imp->methods->allnodes == NULL) return (ISC_R_NOTIMPLEMENTED); if ((options & DNS_DB_NSEC3ONLY) != 0 || (options & DNS_DB_NONSEC3) != 0) return (ISC_R_NOTIMPLEMENTED); sdbiter = isc_mem_get(sdb->common.mctx, sizeof(sdb_dbiterator_t)); if (sdbiter == NULL) return (ISC_R_NOMEMORY); sdbiter->common.methods = &dbiterator_methods; sdbiter->common.db = NULL; dns_db_attach(db, &sdbiter->common.db); sdbiter->common.relative_names = ISC_TF(options & DNS_DB_RELATIVENAMES); sdbiter->common.magic = DNS_DBITERATOR_MAGIC; ISC_LIST_INIT(sdbiter->nodelist); sdbiter->current = NULL; sdbiter->origin = NULL; MAYBE_LOCK(sdb); result = imp->methods->allnodes(sdb->zone, sdb->dbdata, sdbiter); MAYBE_UNLOCK(sdb); if (result != ISC_R_SUCCESS) { dbiterator_destroy((dns_dbiterator_t **) (void *)&sdbiter); return (result); } if (sdbiter->origin != NULL) { ISC_LIST_UNLINK(sdbiter->nodelist, sdbiter->origin, link); ISC_LIST_PREPEND(sdbiter->nodelist, sdbiter->origin, link); } *iteratorp = (dns_dbiterator_t *)sdbiter; return (ISC_R_SUCCESS); } static isc_result_t findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdatatype_t type, dns_rdatatype_t covers, isc_stdtime_t now, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { dns_rdatalist_t *list; dns_sdbnode_t *sdbnode = (dns_sdbnode_t *)node; REQUIRE(VALID_SDBNODE(node)); UNUSED(db); UNUSED(version); UNUSED(covers); UNUSED(now); UNUSED(sigrdataset); if (type == dns_rdatatype_rrsig) return (ISC_R_NOTIMPLEMENTED); list = ISC_LIST_HEAD(sdbnode->lists); while (list != NULL) { if (list->type == type) break; list = ISC_LIST_NEXT(list, link); } if (list == NULL) return (ISC_R_NOTFOUND); list_tordataset(list, db, node, rdataset); return (ISC_R_SUCCESS); } static isc_result_t allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_stdtime_t now, dns_rdatasetiter_t **iteratorp) { sdb_rdatasetiter_t *iterator; REQUIRE(version == NULL || version == &dummy); UNUSED(version); UNUSED(now); iterator = isc_mem_get(db->mctx, sizeof(sdb_rdatasetiter_t)); if (iterator == NULL) return (ISC_R_NOMEMORY); iterator->common.magic = DNS_RDATASETITER_MAGIC; iterator->common.methods = &rdatasetiter_methods; iterator->common.db = db; iterator->common.node = NULL; attachnode(db, node, &iterator->common.node); iterator->common.version = version; iterator->common.now = now; *iteratorp = (dns_rdatasetiter_t *)iterator; return (ISC_R_SUCCESS); } static isc_result_t addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options, dns_rdataset_t *addedrdataset) { UNUSED(db); UNUSED(node); UNUSED(version); UNUSED(now); UNUSED(rdataset); UNUSED(options); UNUSED(addedrdataset); return (ISC_R_NOTIMPLEMENTED); } static isc_result_t subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdataset_t *rdataset, unsigned int options, dns_rdataset_t *newrdataset) { UNUSED(db); UNUSED(node); UNUSED(version); UNUSED(rdataset); UNUSED(options); UNUSED(newrdataset); return (ISC_R_NOTIMPLEMENTED); } static isc_result_t deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdatatype_t type, dns_rdatatype_t covers) { UNUSED(db); UNUSED(node); UNUSED(version); UNUSED(type); UNUSED(covers); return (ISC_R_NOTIMPLEMENTED); } static isc_boolean_t issecure(dns_db_t *db) { UNUSED(db); return (ISC_FALSE); } static unsigned int nodecount(dns_db_t *db) { UNUSED(db); return (0); } static isc_boolean_t ispersistent(dns_db_t *db) { UNUSED(db); return (ISC_TRUE); } static void overmem(dns_db_t *db, isc_boolean_t over) { UNUSED(db); UNUSED(over); } static void settask(dns_db_t *db, isc_task_t *task) { UNUSED(db); UNUSED(task); } static dns_dbmethods_t sdb_methods = { attach, detach, beginload, endload, NULL, dump, currentversion, newversion, attachversion, closeversion, NULL, NULL, findzonecut, attachnode, detachnode, expirenode, printnode, createiterator, findrdataset, allrdatasets, addrdataset, subtractrdataset, deleterdataset, issecure, nodecount, ispersistent, overmem, settask, NULL, /* getoriginnode */ NULL, /* transfernode */ NULL, /* getnsec3parameters */ NULL, /* findnsec3node */ NULL, /* setsigningtime */ NULL, /* getsigningtime */ NULL, /* resigned */ NULL, /* isdnssec */ NULL, /* getrrsetstats */ NULL, /* rpz_attach */ NULL, /* rpz_ready */ findnodeext, findext, NULL, /* setcachestats */ NULL /* hashsize */ }; static isc_result_t dns_sdb_create(isc_mem_t *mctx, dns_name_t *origin, dns_dbtype_t type, dns_rdataclass_t rdclass, unsigned int argc, char *argv[], void *driverarg, dns_db_t **dbp) { dns_sdb_t *sdb; isc_result_t result; char zonestr[DNS_NAME_MAXTEXT + 1]; isc_buffer_t b; dns_sdbimplementation_t *imp; REQUIRE(driverarg != NULL); imp = driverarg; if (type != dns_dbtype_zone) return (ISC_R_NOTIMPLEMENTED); sdb = isc_mem_get(mctx, sizeof(dns_sdb_t)); if (sdb == NULL) return (ISC_R_NOMEMORY); memset(sdb, 0, sizeof(dns_sdb_t)); dns_name_init(&sdb->common.origin, NULL); sdb->common.attributes = 0; sdb->common.methods = &sdb_methods; sdb->common.rdclass = rdclass; sdb->common.mctx = NULL; sdb->implementation = imp; isc_mem_attach(mctx, &sdb->common.mctx); result = isc_mutex_init(&sdb->lock); if (result != ISC_R_SUCCESS) goto cleanup_mctx; result = dns_name_dupwithoffsets(origin, mctx, &sdb->common.origin); if (result != ISC_R_SUCCESS) goto cleanup_lock; isc_buffer_init(&b, zonestr, sizeof(zonestr)); result = dns_name_totext(origin, ISC_TRUE, &b); if (result != ISC_R_SUCCESS) goto cleanup_origin; isc_buffer_putuint8(&b, 0); sdb->zone = isc_mem_strdup(mctx, zonestr); if (sdb->zone == NULL) { result = ISC_R_NOMEMORY; goto cleanup_origin; } sdb->dbdata = NULL; if (imp->methods->create != NULL) { MAYBE_LOCK(sdb); result = imp->methods->create(sdb->zone, argc, argv, imp->driverdata, &sdb->dbdata); MAYBE_UNLOCK(sdb); if (result != ISC_R_SUCCESS) goto cleanup_zonestr; } sdb->references = 1; sdb->common.magic = DNS_DB_MAGIC; sdb->common.impmagic = SDB_MAGIC; *dbp = (dns_db_t *)sdb; return (ISC_R_SUCCESS); cleanup_zonestr: isc_mem_free(mctx, sdb->zone); cleanup_origin: dns_name_free(&sdb->common.origin, mctx); cleanup_lock: (void)isc_mutex_destroy(&sdb->lock); cleanup_mctx: isc_mem_put(mctx, sdb, sizeof(dns_sdb_t)); isc_mem_detach(&mctx); return (result); } /* * Rdataset Methods */ static void disassociate(dns_rdataset_t *rdataset) { dns_dbnode_t *node = rdataset->private5; dns_sdbnode_t *sdbnode = (dns_sdbnode_t *) node; dns_db_t *db = (dns_db_t *) sdbnode->sdb; detachnode(db, &node); isc__rdatalist_disassociate(rdataset); } static void rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { dns_dbnode_t *node = source->private5; dns_sdbnode_t *sdbnode = (dns_sdbnode_t *) node; dns_db_t *db = (dns_db_t *) sdbnode->sdb; dns_dbnode_t *tempdb = NULL; isc__rdatalist_clone(source, target); attachnode(db, node, &tempdb); source->private5 = tempdb; } static dns_rdatasetmethods_t methods = { disassociate, isc__rdatalist_first, isc__rdatalist_next, isc__rdatalist_current, rdataset_clone, isc__rdatalist_count, isc__rdatalist_addnoqname, isc__rdatalist_getnoqname, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static void list_tordataset(dns_rdatalist_t *rdatalist, dns_db_t *db, dns_dbnode_t *node, dns_rdataset_t *rdataset) { /* * The sdb rdataset is an rdatalist with some additions. * - private1 & private2 are used by the rdatalist. * - private3 & private 4 are unused. * - private5 is the node. */ /* This should never fail. */ RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) == ISC_R_SUCCESS); rdataset->methods = &methods; dns_db_attachnode(db, node, &rdataset->private5); } /* * Database Iterator Methods */ static void dbiterator_destroy(dns_dbiterator_t **iteratorp) { sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)(*iteratorp); dns_sdb_t *sdb = (dns_sdb_t *)sdbiter->common.db; while (!ISC_LIST_EMPTY(sdbiter->nodelist)) { dns_sdbnode_t *node; node = ISC_LIST_HEAD(sdbiter->nodelist); ISC_LIST_UNLINK(sdbiter->nodelist, node, link); destroynode(node); } dns_db_detach(&sdbiter->common.db); isc_mem_put(sdb->common.mctx, sdbiter, sizeof(sdb_dbiterator_t)); *iteratorp = NULL; } static isc_result_t dbiterator_first(dns_dbiterator_t *iterator) { sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; sdbiter->current = ISC_LIST_HEAD(sdbiter->nodelist); if (sdbiter->current == NULL) return (ISC_R_NOMORE); else return (ISC_R_SUCCESS); } static isc_result_t dbiterator_last(dns_dbiterator_t *iterator) { sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; sdbiter->current = ISC_LIST_TAIL(sdbiter->nodelist); if (sdbiter->current == NULL) return (ISC_R_NOMORE); else return (ISC_R_SUCCESS); } static isc_result_t dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) { sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; sdbiter->current = ISC_LIST_HEAD(sdbiter->nodelist); while (sdbiter->current != NULL) { if (dns_name_equal(sdbiter->current->name, name)) return (ISC_R_SUCCESS); sdbiter->current = ISC_LIST_NEXT(sdbiter->current, link); } return (ISC_R_NOTFOUND); } static isc_result_t dbiterator_prev(dns_dbiterator_t *iterator) { sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; sdbiter->current = ISC_LIST_PREV(sdbiter->current, link); if (sdbiter->current == NULL) return (ISC_R_NOMORE); else return (ISC_R_SUCCESS); } static isc_result_t dbiterator_next(dns_dbiterator_t *iterator) { sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; sdbiter->current = ISC_LIST_NEXT(sdbiter->current, link); if (sdbiter->current == NULL) return (ISC_R_NOMORE); else return (ISC_R_SUCCESS); } static isc_result_t dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep, dns_name_t *name) { sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator; attachnode(iterator->db, sdbiter->current, nodep); if (name != NULL) return (dns_name_copy(sdbiter->current->name, name, NULL)); return (ISC_R_SUCCESS); } static isc_result_t dbiterator_pause(dns_dbiterator_t *iterator) { UNUSED(iterator); return (ISC_R_SUCCESS); } static isc_result_t dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) { UNUSED(iterator); return (dns_name_copy(dns_rootname, name, NULL)); } /* * Rdataset Iterator Methods */ static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) { sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)(*iteratorp); detachnode(sdbiterator->common.db, &sdbiterator->common.node); isc_mem_put(sdbiterator->common.db->mctx, sdbiterator, sizeof(sdb_rdatasetiter_t)); *iteratorp = NULL; } static isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator) { sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator; dns_sdbnode_t *sdbnode = (dns_sdbnode_t *)iterator->node; if (ISC_LIST_EMPTY(sdbnode->lists)) return (ISC_R_NOMORE); sdbiterator->current = ISC_LIST_HEAD(sdbnode->lists); return (ISC_R_SUCCESS); } static isc_result_t rdatasetiter_next(dns_rdatasetiter_t *iterator) { sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator; sdbiterator->current = ISC_LIST_NEXT(sdbiterator->current, link); if (sdbiterator->current == NULL) return (ISC_R_NOMORE); else return (ISC_R_SUCCESS); } static void rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) { sdb_rdatasetiter_t *sdbiterator = (sdb_rdatasetiter_t *)iterator; list_tordataset(sdbiterator->current, iterator->db, iterator->node, rdataset); } bind9-9.10.3.dfsg.P4/lib/dns/rdataset.c0000644000470500017500000004635212664710322016710 0ustar lamontlamont/* * Copyright (C) 2004-2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include static const char *trustnames[] = { "none", "pending-additional", "pending-answer", "additional", "glue", "answer", "authauthority", "authanswer", "secure", "local" /* aka ultimate */ }; const char * dns_trust_totext(dns_trust_t trust) { if (trust >= sizeof(trustnames)/sizeof(*trustnames)) return ("bad"); return (trustnames[trust]); } void dns_rdataset_init(dns_rdataset_t *rdataset) { /* * Make 'rdataset' a valid, disassociated rdataset. */ REQUIRE(rdataset != NULL); rdataset->magic = DNS_RDATASET_MAGIC; rdataset->methods = NULL; ISC_LINK_INIT(rdataset, link); rdataset->rdclass = 0; rdataset->type = 0; rdataset->ttl = 0; rdataset->trust = 0; rdataset->covers = 0; rdataset->attributes = 0; rdataset->count = ISC_UINT32_MAX; rdataset->private1 = NULL; rdataset->private2 = NULL; rdataset->private3 = NULL; rdataset->privateuint4 = 0; rdataset->private5 = NULL; rdataset->private6 = NULL; rdataset->private7 = NULL; rdataset->resign = 0; } void dns_rdataset_invalidate(dns_rdataset_t *rdataset) { /* * Invalidate 'rdataset'. */ REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(rdataset->methods == NULL); rdataset->magic = 0; ISC_LINK_INIT(rdataset, link); rdataset->rdclass = 0; rdataset->type = 0; rdataset->ttl = 0; rdataset->trust = 0; rdataset->covers = 0; rdataset->attributes = 0; rdataset->count = ISC_UINT32_MAX; rdataset->private1 = NULL; rdataset->private2 = NULL; rdataset->private3 = NULL; rdataset->privateuint4 = 0; rdataset->private5 = NULL; } void dns_rdataset_disassociate(dns_rdataset_t *rdataset) { /* * Disassociate 'rdataset' from its rdata, allowing it to be reused. */ REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(rdataset->methods != NULL); (rdataset->methods->disassociate)(rdataset); rdataset->methods = NULL; ISC_LINK_INIT(rdataset, link); rdataset->rdclass = 0; rdataset->type = 0; rdataset->ttl = 0; rdataset->trust = 0; rdataset->covers = 0; rdataset->attributes = 0; rdataset->count = ISC_UINT32_MAX; rdataset->private1 = NULL; rdataset->private2 = NULL; rdataset->private3 = NULL; rdataset->privateuint4 = 0; rdataset->private5 = NULL; rdataset->private6 = NULL; } isc_boolean_t dns_rdataset_isassociated(dns_rdataset_t *rdataset) { /* * Is 'rdataset' associated? */ REQUIRE(DNS_RDATASET_VALID(rdataset)); if (rdataset->methods != NULL) return (ISC_TRUE); return (ISC_FALSE); } static void question_disassociate(dns_rdataset_t *rdataset) { UNUSED(rdataset); } static isc_result_t question_cursor(dns_rdataset_t *rdataset) { UNUSED(rdataset); return (ISC_R_NOMORE); } static void question_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) { /* * This routine should never be called. */ UNUSED(rdataset); UNUSED(rdata); REQUIRE(0); } static void question_clone(dns_rdataset_t *source, dns_rdataset_t *target) { *target = *source; } static unsigned int question_count(dns_rdataset_t *rdataset) { /* * This routine should never be called. */ UNUSED(rdataset); REQUIRE(0); return (0); } static dns_rdatasetmethods_t question_methods = { question_disassociate, question_cursor, question_cursor, question_current, question_clone, question_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; void dns_rdataset_makequestion(dns_rdataset_t *rdataset, dns_rdataclass_t rdclass, dns_rdatatype_t type) { /* * Make 'rdataset' a valid, associated, question rdataset, with a * question class of 'rdclass' and type 'type'. */ REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(rdataset->methods == NULL); rdataset->methods = &question_methods; rdataset->rdclass = rdclass; rdataset->type = type; rdataset->attributes |= DNS_RDATASETATTR_QUESTION; } unsigned int dns_rdataset_count(dns_rdataset_t *rdataset) { /* * Return the number of records in 'rdataset'. */ REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(rdataset->methods != NULL); return ((rdataset->methods->count)(rdataset)); } void dns_rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { /* * Make 'target' refer to the same rdataset as 'source'. */ REQUIRE(DNS_RDATASET_VALID(source)); REQUIRE(source->methods != NULL); REQUIRE(DNS_RDATASET_VALID(target)); REQUIRE(target->methods == NULL); (source->methods->clone)(source, target); } isc_result_t dns_rdataset_first(dns_rdataset_t *rdataset) { /* * Move the rdata cursor to the first rdata in the rdataset (if any). */ REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(rdataset->methods != NULL); return ((rdataset->methods->first)(rdataset)); } isc_result_t dns_rdataset_next(dns_rdataset_t *rdataset) { /* * Move the rdata cursor to the next rdata in the rdataset (if any). */ REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(rdataset->methods != NULL); return ((rdataset->methods->next)(rdataset)); } void dns_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) { /* * Make 'rdata' refer to the current rdata. */ REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(rdataset->methods != NULL); (rdataset->methods->current)(rdataset, rdata); } #define MAX_SHUFFLE 32 #define WANT_FIXED(r) (((r)->attributes & DNS_RDATASETATTR_FIXEDORDER) != 0) #define WANT_RANDOM(r) (((r)->attributes & DNS_RDATASETATTR_RANDOMIZE) != 0) struct towire_sort { int key; dns_rdata_t *rdata; }; static int towire_compare(const void *av, const void *bv) { const struct towire_sort *a = (const struct towire_sort *) av; const struct towire_sort *b = (const struct towire_sort *) bv; return (a->key - b->key); } static isc_result_t towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name, dns_compress_t *cctx, isc_buffer_t *target, dns_rdatasetorderfunc_t order, const void *order_arg, isc_boolean_t partial, unsigned int options, unsigned int *countp, void **state) { dns_rdata_t rdata = DNS_RDATA_INIT; isc_region_t r; isc_result_t result; unsigned int i, count = 0, added, choice; isc_buffer_t savedbuffer, rdlen, rrbuffer; unsigned int headlen; isc_boolean_t question = ISC_FALSE; isc_boolean_t shuffle = ISC_FALSE; dns_rdata_t *shuffled = NULL, shuffled_fixed[MAX_SHUFFLE]; struct towire_sort *sorted = NULL, sorted_fixed[MAX_SHUFFLE]; UNUSED(state); /* * Convert 'rdataset' to wire format, compressing names as specified * in cctx, and storing the result in 'target'. */ REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(countp != NULL); REQUIRE((order == NULL) == (order_arg == NULL)); REQUIRE(cctx != NULL && cctx->mctx != NULL); if ((rdataset->attributes & DNS_RDATASETATTR_QUESTION) != 0) { question = ISC_TRUE; count = 1; result = dns_rdataset_first(rdataset); INSIST(result == ISC_R_NOMORE); } else if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) { /* * This is a negative caching rdataset. */ unsigned int ncache_opts = 0; if ((options & DNS_RDATASETTOWIRE_OMITDNSSEC) != 0) ncache_opts |= DNS_NCACHETOWIRE_OMITDNSSEC; return (dns_ncache_towire(rdataset, cctx, target, ncache_opts, countp)); } else { count = (rdataset->methods->count)(rdataset); result = dns_rdataset_first(rdataset); if (result == ISC_R_NOMORE) return (ISC_R_SUCCESS); if (result != ISC_R_SUCCESS) return (result); } /* * Do we want to shuffle this answer? */ if (!question && count > 1 && (!WANT_FIXED(rdataset) || order != NULL) && rdataset->type != dns_rdatatype_rrsig) shuffle = ISC_TRUE; if (shuffle && count > MAX_SHUFFLE) { shuffled = isc_mem_get(cctx->mctx, count * sizeof(*shuffled)); sorted = isc_mem_get(cctx->mctx, count * sizeof(*sorted)); if (shuffled == NULL || sorted == NULL) shuffle = ISC_FALSE; } else { shuffled = shuffled_fixed; sorted = sorted_fixed; } if (shuffle) { /* * First we get handles to all of the rdata. */ i = 0; do { INSIST(i < count); dns_rdata_init(&shuffled[i]); dns_rdataset_current(rdataset, &shuffled[i]); i++; result = dns_rdataset_next(rdataset); } while (result == ISC_R_SUCCESS); if (result != ISC_R_NOMORE) goto cleanup; INSIST(i == count); /* * Now we shuffle. */ if (WANT_FIXED(rdataset)) { /* * 'Fixed' order. */ INSIST(order != NULL); for (i = 0; i < count; i++) { sorted[i].key = (*order)(&shuffled[i], order_arg); sorted[i].rdata = &shuffled[i]; } } else if (WANT_RANDOM(rdataset)) { /* * 'Random' order. */ for (i = 0; i < count; i++) { isc_uint32_t val; isc_random_get(&val); choice = i + (val % (count - i)); rdata = shuffled[i]; shuffled[i] = shuffled[choice]; shuffled[choice] = rdata; if (order != NULL) sorted[i].key = (*order)(&shuffled[i], order_arg); else sorted[i].key = 0; /* Unused */ sorted[i].rdata = &shuffled[i]; } } else { /* * "Cyclic" order. */ isc_uint32_t val; unsigned int j; val = rdataset->count; if (val == ISC_UINT32_MAX) isc_random_get(&val); j = val % count; for (i = 0; i < count; i++) { if (order != NULL) sorted[i].key = (*order)(&shuffled[j], order_arg); else sorted[i].key = 0; /* Unused */ sorted[i].rdata = &shuffled[j]; j++; if (j == count) j = 0; /* Wrap around. */ } } /* * Sorted order. */ if (order != NULL) qsort(sorted, count, sizeof(sorted[0]), towire_compare); } savedbuffer = *target; i = 0; added = 0; do { /* * Copy out the name, type, class, ttl. */ rrbuffer = *target; dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); result = dns_name_towire(owner_name, cctx, target); if (result != ISC_R_SUCCESS) goto rollback; headlen = sizeof(dns_rdataclass_t) + sizeof(dns_rdatatype_t); if (!question) headlen += sizeof(dns_ttl_t) + 2; /* XXX 2 for rdata len */ isc_buffer_availableregion(target, &r); if (r.length < headlen) { result = ISC_R_NOSPACE; goto rollback; } isc_buffer_putuint16(target, rdataset->type); isc_buffer_putuint16(target, rdataset->rdclass); if (!question) { isc_buffer_putuint32(target, rdataset->ttl); /* * Save space for rdlen. */ rdlen = *target; isc_buffer_add(target, 2); /* * Copy out the rdata */ if (shuffle) rdata = *(sorted[i].rdata); else { dns_rdata_reset(&rdata); dns_rdataset_current(rdataset, &rdata); } result = dns_rdata_towire(&rdata, cctx, target); if (result != ISC_R_SUCCESS) goto rollback; INSIST((target->used >= rdlen.used + 2) && (target->used - rdlen.used - 2 < 65536)); isc_buffer_putuint16(&rdlen, (isc_uint16_t)(target->used - rdlen.used - 2)); added++; } if (shuffle) { i++; if (i == count) result = ISC_R_NOMORE; else result = ISC_R_SUCCESS; } else { result = dns_rdataset_next(rdataset); } } while (result == ISC_R_SUCCESS); if (result != ISC_R_NOMORE) goto rollback; *countp += count; result = ISC_R_SUCCESS; goto cleanup; rollback: if (partial && result == ISC_R_NOSPACE) { INSIST(rrbuffer.used < 65536); dns_compress_rollback(cctx, (isc_uint16_t)rrbuffer.used); *countp += added; *target = rrbuffer; goto cleanup; } INSIST(savedbuffer.used < 65536); dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used); *countp = 0; *target = savedbuffer; cleanup: if (sorted != NULL && sorted != sorted_fixed) isc_mem_put(cctx->mctx, sorted, count * sizeof(*sorted)); if (shuffled != NULL && shuffled != shuffled_fixed) isc_mem_put(cctx->mctx, shuffled, count * sizeof(*shuffled)); return (result); } isc_result_t dns_rdataset_towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name, dns_compress_t *cctx, isc_buffer_t *target, dns_rdatasetorderfunc_t order, const void *order_arg, unsigned int options, unsigned int *countp) { return (towiresorted(rdataset, owner_name, cctx, target, order, order_arg, ISC_FALSE, options, countp, NULL)); } isc_result_t dns_rdataset_towirepartial(dns_rdataset_t *rdataset, const dns_name_t *owner_name, dns_compress_t *cctx, isc_buffer_t *target, dns_rdatasetorderfunc_t order, const void *order_arg, unsigned int options, unsigned int *countp, void **state) { REQUIRE(state == NULL); /* XXX remove when implemented */ return (towiresorted(rdataset, owner_name, cctx, target, order, order_arg, ISC_TRUE, options, countp, state)); } isc_result_t dns_rdataset_towire(dns_rdataset_t *rdataset, dns_name_t *owner_name, dns_compress_t *cctx, isc_buffer_t *target, unsigned int options, unsigned int *countp) { return (towiresorted(rdataset, owner_name, cctx, target, NULL, NULL, ISC_FALSE, options, countp, NULL)); } isc_result_t dns_rdataset_additionaldata(dns_rdataset_t *rdataset, dns_additionaldatafunc_t add, void *arg) { dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; /* * For each rdata in rdataset, call 'add' for each name and type in the * rdata which is subject to additional section processing. */ REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE((rdataset->attributes & DNS_RDATASETATTR_QUESTION) == 0); result = dns_rdataset_first(rdataset); if (result != ISC_R_SUCCESS) return (result); do { dns_rdataset_current(rdataset, &rdata); result = dns_rdata_additionaldata(&rdata, add, arg); if (result == ISC_R_SUCCESS) result = dns_rdataset_next(rdataset); dns_rdata_reset(&rdata); } while (result == ISC_R_SUCCESS); if (result != ISC_R_NOMORE) return (result); return (ISC_R_SUCCESS); } isc_result_t dns_rdataset_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name) { REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(rdataset->methods != NULL); if (rdataset->methods->addnoqname == NULL) return (ISC_R_NOTIMPLEMENTED); return((rdataset->methods->addnoqname)(rdataset, name)); } isc_result_t dns_rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name, dns_rdataset_t *neg, dns_rdataset_t *negsig) { REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(rdataset->methods != NULL); if (rdataset->methods->getnoqname == NULL) return (ISC_R_NOTIMPLEMENTED); return((rdataset->methods->getnoqname)(rdataset, name, neg, negsig)); } isc_result_t dns_rdataset_addclosest(dns_rdataset_t *rdataset, dns_name_t *name) { REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(rdataset->methods != NULL); if (rdataset->methods->addclosest == NULL) return (ISC_R_NOTIMPLEMENTED); return((rdataset->methods->addclosest)(rdataset, name)); } isc_result_t dns_rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name, dns_rdataset_t *neg, dns_rdataset_t *negsig) { REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(rdataset->methods != NULL); if (rdataset->methods->getclosest == NULL) return (ISC_R_NOTIMPLEMENTED); return((rdataset->methods->getclosest)(rdataset, name, neg, negsig)); } /* * Additional cache stuff */ isc_result_t dns_rdataset_getadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, dns_rdatatype_t qtype, dns_acache_t *acache, dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp, dns_dbnode_t **nodep, dns_name_t *fname, dns_message_t *msg, isc_stdtime_t now) { REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(rdataset->methods != NULL); REQUIRE(zonep == NULL || *zonep == NULL); REQUIRE(dbp != NULL && *dbp == NULL); REQUIRE(versionp != NULL && *versionp == NULL); REQUIRE(nodep != NULL && *nodep == NULL); REQUIRE(fname != NULL); REQUIRE(msg != NULL); if (acache != NULL && rdataset->methods->getadditional != NULL) { return ((rdataset->methods->getadditional)(rdataset, type, qtype, acache, zonep, dbp, versionp, nodep, fname, msg, now)); } return (ISC_R_FAILURE); } isc_result_t dns_rdataset_setadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, dns_rdatatype_t qtype, dns_acache_t *acache, dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, dns_name_t *fname) { REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(rdataset->methods != NULL); if (acache != NULL && rdataset->methods->setadditional != NULL) { return ((rdataset->methods->setadditional)(rdataset, type, qtype, acache, zone, db, version, node, fname)); } return (ISC_R_FAILURE); } isc_result_t dns_rdataset_putadditional(dns_acache_t *acache, dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, dns_rdatatype_t qtype) { REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(rdataset->methods != NULL); if (acache != NULL && rdataset->methods->putadditional != NULL) { return ((rdataset->methods->putadditional)(acache, rdataset, type, qtype)); } return (ISC_R_FAILURE); } void dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) { REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(rdataset->methods != NULL); if (rdataset->methods->settrust != NULL) (rdataset->methods->settrust)(rdataset, trust); else rdataset->trust = trust; } void dns_rdataset_expire(dns_rdataset_t *rdataset) { REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(rdataset->methods != NULL); if (rdataset->methods->expire != NULL) (rdataset->methods->expire)(rdataset); } void dns_rdataset_clearprefetch(dns_rdataset_t *rdataset) { REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(rdataset->methods != NULL); if (rdataset->methods->clearprefetch != NULL) (rdataset->methods->clearprefetch)(rdataset); } void dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, dns_rdata_rrsig_t *rrsig, isc_stdtime_t now, isc_boolean_t acceptexpired) { isc_uint32_t ttl = 0; REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(DNS_RDATASET_VALID(sigrdataset)); REQUIRE(rrsig != NULL); /* * If we accept expired RRsets keep them for no more than 120 seconds. */ if (acceptexpired && (isc_serial_le(rrsig->timeexpire, ((now + 120) & 0xffffffff)) || isc_serial_le(rrsig->timeexpire, now))) ttl = 120; else if (isc_serial_ge(rrsig->timeexpire, now)) ttl = rrsig->timeexpire - now; ttl = ISC_MIN(ISC_MIN(rdataset->ttl, sigrdataset->ttl), ISC_MIN(rrsig->originalttl, ttl)); rdataset->ttl = ttl; sigrdataset->ttl = ttl; } bind9-9.10.3.dfsg.P4/lib/dns/spnego_asn1.c0000644000470500017500000004767612664710322017330 0ustar lamontlamont/* * Copyright (C) 2006, 2007, 2012, 2013, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: spnego_asn1.c,v 1.4 2007/06/19 23:47:16 tbox Exp $ */ /*! \file * \brief Method routines generated from SPNEGO ASN.1 module. * See spnego_asn1.pl for details. Do not edit. */ /* Generated from spnego.asn1 */ /* Do not edit */ #ifndef __asn1_h__ #define __asn1_h__ #ifndef __asn1_common_definitions__ #define __asn1_common_definitions__ typedef struct octet_string { size_t length; void *data; } octet_string; typedef char *general_string; typedef char *utf8_string; typedef struct oid { size_t length; unsigned *components; } oid; #define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R) \ do { \ (BL) = length_##T((S)); \ (B) = malloc((BL)); \ if((B) == NULL) { \ (R) = ENOMEM; \ } else { \ (R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \ (S), (L)); \ if((R) != 0) { \ free((B)); \ (B) = NULL; \ } \ } \ } while (0) #endif /* * MechType ::= OBJECT IDENTIFIER */ typedef oid MechType; static int encode_MechType(unsigned char *, size_t, const MechType *, size_t *); static int decode_MechType(const unsigned char *, size_t, MechType *, size_t *); static void free_MechType(MechType *); /* unused declaration: length_MechType */ /* unused declaration: copy_MechType */ /* * MechTypeList ::= SEQUENCE OF MechType */ typedef struct MechTypeList { unsigned int len; MechType *val; } MechTypeList; static int encode_MechTypeList(unsigned char *, size_t, const MechTypeList *, size_t *); static int decode_MechTypeList(const unsigned char *, size_t, MechTypeList *, size_t *); static void free_MechTypeList(MechTypeList *); /* unused declaration: length_MechTypeList */ /* unused declaration: copy_MechTypeList */ /* * ContextFlags ::= BIT STRING { delegFlag(0), mutualFlag(1), replayFlag(2), * sequenceFlag(3), anonFlag(4), confFlag(5), integFlag(6) } */ typedef struct ContextFlags { unsigned int delegFlag:1; unsigned int mutualFlag:1; unsigned int replayFlag:1; unsigned int sequenceFlag:1; unsigned int anonFlag:1; unsigned int confFlag:1; unsigned int integFlag:1; } ContextFlags; static int encode_ContextFlags(unsigned char *, size_t, const ContextFlags *, size_t *); static int decode_ContextFlags(const unsigned char *, size_t, ContextFlags *, size_t *); static void free_ContextFlags(ContextFlags *); /* unused declaration: length_ContextFlags */ /* unused declaration: copy_ContextFlags */ /* unused declaration: ContextFlags2int */ /* unused declaration: int2ContextFlags */ /* unused declaration: asn1_ContextFlags_units */ /* * NegTokenInit ::= SEQUENCE { mechTypes[0] MechTypeList, reqFlags[1] * ContextFlags OPTIONAL, mechToken[2] OCTET STRING OPTIONAL, * mechListMIC[3] OCTET STRING OPTIONAL } */ typedef struct NegTokenInit { MechTypeList mechTypes; ContextFlags *reqFlags; octet_string *mechToken; octet_string *mechListMIC; } NegTokenInit; static int encode_NegTokenInit(unsigned char *, size_t, const NegTokenInit *, size_t *); static int decode_NegTokenInit(const unsigned char *, size_t, NegTokenInit *, size_t *); static void free_NegTokenInit(NegTokenInit *); /* unused declaration: length_NegTokenInit */ /* unused declaration: copy_NegTokenInit */ /* * NegTokenResp ::= SEQUENCE { negState[0] ENUMERATED { * accept-completed(0), accept-incomplete(1), reject(2), request-mic(3) } * OPTIONAL, supportedMech[1] MechType OPTIONAL, responseToken[2] OCTET * STRING OPTIONAL, mechListMIC[3] OCTET STRING OPTIONAL } */ typedef struct NegTokenResp { enum { accept_completed = 0, accept_incomplete = 1, reject = 2, request_mic = 3 } *negState; MechType *supportedMech; octet_string *responseToken; octet_string *mechListMIC; } NegTokenResp; static int encode_NegTokenResp(unsigned char *, size_t, const NegTokenResp *, size_t *); static int decode_NegTokenResp(const unsigned char *, size_t, NegTokenResp *, size_t *); static void free_NegTokenResp(NegTokenResp *); /* unused declaration: length_NegTokenResp */ /* unused declaration: copy_NegTokenResp */ #endif /* __asn1_h__ */ /* Generated from spnego.asn1 */ /* Do not edit */ #define BACK if (e) return e; p -= l; len -= l; ret += l; POST(p); POST(len); POST(ret) static int encode_MechType(unsigned char *p, size_t len, const MechType * data, size_t * size) { size_t ret = 0; size_t l; int e; e = encode_oid(p, len, data, &l); BACK; *size = ret; return 0; } #define FORW if(e) goto fail; p += l; len -= l; ret += l; POST(p); POST(len); POST(ret) static int decode_MechType(const unsigned char *p, size_t len, MechType * data, size_t * size) { size_t ret = 0; size_t l; int e; memset(data, 0, sizeof(*data)); e = decode_oid(p, len, data, &l); FORW; if (size) *size = ret; return 0; fail: free_MechType(data); return e; } static void free_MechType(MechType * data) { free_oid(data); } /* unused function: length_MechType */ /* unused function: copy_MechType */ /* Generated from spnego.asn1 */ /* Do not edit */ static int encode_MechTypeList(unsigned char *p, size_t len, const MechTypeList * data, size_t * size) { size_t ret = 0; size_t l; int i, e; for (i = (data)->len - 1; i >= 0; --i) { size_t oldret = ret; ret = 0; e = encode_MechType(p, len, &(data)->val[i], &l); BACK; ret += oldret; } e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l); BACK; *size = ret; return 0; } static int decode_MechTypeList(const unsigned char *p, size_t len, MechTypeList * data, size_t * size) { size_t ret = 0, reallen; size_t l; int e; memset(data, 0, sizeof(*data)); reallen = 0; e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence, &reallen, &l); FORW; if (len < reallen) return ASN1_OVERRUN; len = reallen; { size_t origlen = len; size_t oldret = ret; ret = 0; (data)->len = 0; (data)->val = NULL; while (ret < origlen) { void *old = (data)->val; (data)->len++; (data)->val = realloc((data)->val, sizeof(*((data)->val)) * (data)->len); if ((data)->val == NULL) { (data)->val = old; (data)->len--; return ENOMEM; } e = decode_MechType(p, len, &(data)->val[(data)->len - 1], &l); FORW; len = origlen - ret; } ret += oldret; } if (size) *size = ret; return 0; fail: free_MechTypeList(data); return e; } static void free_MechTypeList(MechTypeList * data) { while ((data)->len) { free_MechType(&(data)->val[(data)->len - 1]); (data)->len--; } free((data)->val); (data)->val = NULL; } /* unused function: length_MechTypeList */ /* unused function: copy_MechTypeList */ /* Generated from spnego.asn1 */ /* Do not edit */ static int encode_ContextFlags(unsigned char *p, size_t len, const ContextFlags * data, size_t * size) { size_t ret = 0; size_t l; int e; { unsigned char c = 0; *p-- = c; len--; ret++; c = 0; *p-- = c; len--; ret++; c = 0; *p-- = c; len--; ret++; c = 0; if (data->integFlag) c |= 1 << 1; if (data->confFlag) c |= 1 << 2; if (data->anonFlag) c |= 1 << 3; if (data->sequenceFlag) c |= 1 << 4; if (data->replayFlag) c |= 1 << 5; if (data->mutualFlag) c |= 1 << 6; if (data->delegFlag) c |= 1 << 7; *p-- = c; *p-- = 0; len -= 2; ret += 2; } e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_BitString, &l); BACK; *size = ret; return 0; } static int decode_ContextFlags(const unsigned char *p, size_t len, ContextFlags * data, size_t * size) { size_t ret = 0, reallen; size_t l; int e; memset(data, 0, sizeof(*data)); reallen = 0; e = der_match_tag_and_length(p, len, ASN1_C_UNIV, PRIM, UT_BitString, &reallen, &l); FORW; if (len < reallen) return ASN1_OVERRUN; p++; len--; reallen--; ret++; data->delegFlag = (*p >> 7) & 1; data->mutualFlag = (*p >> 6) & 1; data->replayFlag = (*p >> 5) & 1; data->sequenceFlag = (*p >> 4) & 1; data->anonFlag = (*p >> 3) & 1; data->confFlag = (*p >> 2) & 1; data->integFlag = (*p >> 1) & 1; ret += reallen; if (size) *size = ret; return 0; fail: free_ContextFlags(data); return e; } static void free_ContextFlags(ContextFlags * data) { (void)data; } /* unused function: length_ContextFlags */ /* unused function: copy_ContextFlags */ /* unused function: ContextFlags2int */ /* unused function: int2ContextFlags */ /* unused variable: ContextFlags_units */ /* unused function: asn1_ContextFlags_units */ /* Generated from spnego.asn1 */ /* Do not edit */ static int encode_NegTokenInit(unsigned char *p, size_t len, const NegTokenInit * data, size_t * size) { size_t ret = 0; size_t l; int e; if ((data)->mechListMIC) { size_t oldret = ret; ret = 0; e = encode_octet_string(p, len, (data)->mechListMIC, &l); BACK; e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 3, &l); BACK; ret += oldret; } if ((data)->mechToken) { size_t oldret = ret; ret = 0; e = encode_octet_string(p, len, (data)->mechToken, &l); BACK; e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 2, &l); BACK; ret += oldret; } if ((data)->reqFlags) { size_t oldret = ret; ret = 0; e = encode_ContextFlags(p, len, (data)->reqFlags, &l); BACK; e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l); BACK; ret += oldret; } { size_t oldret = ret; ret = 0; e = encode_MechTypeList(p, len, &(data)->mechTypes, &l); BACK; e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l); BACK; ret += oldret; } e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l); BACK; *size = ret; return 0; } static int decode_NegTokenInit(const unsigned char *p, size_t len, NegTokenInit * data, size_t * size) { size_t ret = 0, reallen; size_t l; int e; memset(data, 0, sizeof(*data)); reallen = 0; e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence, &reallen, &l); FORW; { int dce_fix; if ((dce_fix = fix_dce(reallen, &len)) < 0) return ASN1_BAD_FORMAT; { size_t newlen, oldlen; e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 0, &l); if (e) return e; else { p += l; len -= l; ret += l; e = der_get_length(p, len, &newlen, &l); FORW; { int mydce_fix; oldlen = len; if ((mydce_fix = fix_dce(newlen, &len)) < 0) return ASN1_BAD_FORMAT; e = decode_MechTypeList(p, len, &(data)->mechTypes, &l); FORW; if (mydce_fix) { e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); FORW; } else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 1, &l); if (e) (data)->reqFlags = NULL; else { p += l; len -= l; ret += l; e = der_get_length(p, len, &newlen, &l); FORW; { int mydce_fix; oldlen = len; if ((mydce_fix = fix_dce(newlen, &len)) < 0) return ASN1_BAD_FORMAT; (data)->reqFlags = malloc(sizeof(*(data)->reqFlags)); if ((data)->reqFlags == NULL) return ENOMEM; e = decode_ContextFlags(p, len, (data)->reqFlags, &l); FORW; if (mydce_fix) { e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); FORW; } else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 2, &l); if (e) (data)->mechToken = NULL; else { p += l; len -= l; ret += l; e = der_get_length(p, len, &newlen, &l); FORW; { int mydce_fix; oldlen = len; if ((mydce_fix = fix_dce(newlen, &len)) < 0) return ASN1_BAD_FORMAT; (data)->mechToken = malloc(sizeof(*(data)->mechToken)); if ((data)->mechToken == NULL) return ENOMEM; e = decode_octet_string(p, len, (data)->mechToken, &l); FORW; if (mydce_fix) { e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); FORW; } else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 3, &l); if (e) (data)->mechListMIC = NULL; else { p += l; len -= l; ret += l; e = der_get_length(p, len, &newlen, &l); FORW; { int mydce_fix; oldlen = len; if ((mydce_fix = fix_dce(newlen, &len)) < 0) return ASN1_BAD_FORMAT; (data)->mechListMIC = malloc(sizeof(*(data)->mechListMIC)); if ((data)->mechListMIC == NULL) return ENOMEM; e = decode_octet_string(p, len, (data)->mechListMIC, &l); FORW; if (mydce_fix) { e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); FORW; } else len = oldlen - newlen; } } } if (dce_fix) { e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); FORW; } } if (size) *size = ret; return 0; fail: free_NegTokenInit(data); return e; } static void free_NegTokenInit(NegTokenInit * data) { free_MechTypeList(&(data)->mechTypes); if ((data)->reqFlags) { free_ContextFlags((data)->reqFlags); free((data)->reqFlags); (data)->reqFlags = NULL; } if ((data)->mechToken) { free_octet_string((data)->mechToken); free((data)->mechToken); (data)->mechToken = NULL; } if ((data)->mechListMIC) { free_octet_string((data)->mechListMIC); free((data)->mechListMIC); (data)->mechListMIC = NULL; } } /* unused function: length_NegTokenInit */ /* unused function: copy_NegTokenInit */ /* Generated from spnego.asn1 */ /* Do not edit */ static int encode_NegTokenResp(unsigned char *p, size_t len, const NegTokenResp * data, size_t * size) { size_t ret = 0; size_t l; int e; if ((data)->mechListMIC) { size_t oldret = ret; ret = 0; e = encode_octet_string(p, len, (data)->mechListMIC, &l); BACK; e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 3, &l); BACK; ret += oldret; } if ((data)->responseToken) { size_t oldret = ret; ret = 0; e = encode_octet_string(p, len, (data)->responseToken, &l); BACK; e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 2, &l); BACK; ret += oldret; } if ((data)->supportedMech) { size_t oldret = ret; ret = 0; e = encode_MechType(p, len, (data)->supportedMech, &l); BACK; e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l); BACK; ret += oldret; } if ((data)->negState) { size_t oldret = ret; ret = 0; e = encode_enumerated(p, len, (data)->negState, &l); BACK; e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l); BACK; ret += oldret; } e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l); BACK; *size = ret; return 0; } static int decode_NegTokenResp(const unsigned char *p, size_t len, NegTokenResp * data, size_t * size) { size_t ret = 0, reallen; size_t l; int e; memset(data, 0, sizeof(*data)); reallen = 0; e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence, &reallen, &l); FORW; { int dce_fix; if ((dce_fix = fix_dce(reallen, &len)) < 0) return ASN1_BAD_FORMAT; { size_t newlen, oldlen; e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 0, &l); if (e) (data)->negState = NULL; else { p += l; len -= l; ret += l; e = der_get_length(p, len, &newlen, &l); FORW; { int mydce_fix; oldlen = len; if ((mydce_fix = fix_dce(newlen, &len)) < 0) return ASN1_BAD_FORMAT; (data)->negState = malloc(sizeof(*(data)->negState)); if ((data)->negState == NULL) return ENOMEM; e = decode_enumerated(p, len, (data)->negState, &l); FORW; if (mydce_fix) { e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); FORW; } else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 1, &l); if (e) (data)->supportedMech = NULL; else { p += l; len -= l; ret += l; e = der_get_length(p, len, &newlen, &l); FORW; { int mydce_fix; oldlen = len; if ((mydce_fix = fix_dce(newlen, &len)) < 0) return ASN1_BAD_FORMAT; (data)->supportedMech = malloc(sizeof(*(data)->supportedMech)); if ((data)->supportedMech == NULL) return ENOMEM; e = decode_MechType(p, len, (data)->supportedMech, &l); FORW; if (mydce_fix) { e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); FORW; } else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 2, &l); if (e) (data)->responseToken = NULL; else { p += l; len -= l; ret += l; e = der_get_length(p, len, &newlen, &l); FORW; { int mydce_fix; oldlen = len; if ((mydce_fix = fix_dce(newlen, &len)) < 0) return ASN1_BAD_FORMAT; (data)->responseToken = malloc(sizeof(*(data)->responseToken)); if ((data)->responseToken == NULL) return ENOMEM; e = decode_octet_string(p, len, (data)->responseToken, &l); FORW; if (mydce_fix) { e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); FORW; } else len = oldlen - newlen; } } } { size_t newlen, oldlen; e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 3, &l); if (e) (data)->mechListMIC = NULL; else { p += l; len -= l; ret += l; e = der_get_length(p, len, &newlen, &l); FORW; { int mydce_fix; oldlen = len; if ((mydce_fix = fix_dce(newlen, &len)) < 0) return ASN1_BAD_FORMAT; (data)->mechListMIC = malloc(sizeof(*(data)->mechListMIC)); if ((data)->mechListMIC == NULL) return ENOMEM; e = decode_octet_string(p, len, (data)->mechListMIC, &l); FORW; if (mydce_fix) { e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); FORW; } else len = oldlen - newlen; } } } if (dce_fix) { e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); FORW; } } if (size) *size = ret; return 0; fail: free_NegTokenResp(data); return e; } static void free_NegTokenResp(NegTokenResp * data) { if ((data)->negState) { free((data)->negState); (data)->negState = NULL; } if ((data)->supportedMech) { free_MechType((data)->supportedMech); free((data)->supportedMech); (data)->supportedMech = NULL; } if ((data)->responseToken) { free_octet_string((data)->responseToken); free((data)->responseToken); (data)->responseToken = NULL; } if ((data)->mechListMIC) { free_octet_string((data)->mechListMIC); free((data)->mechListMIC); (data)->mechListMIC = NULL; } } /* unused function: length_NegTokenResp */ /* unused function: copy_NegTokenResp */ /* Generated from spnego.asn1 */ /* Do not edit */ /* CHOICE */ /* unused variable: asn1_NegotiationToken_dummy_holder */ bind9-9.10.3.dfsg.P4/lib/dns/win32/0002755000470500017500000000000012672612753015677 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/dns/win32/libdns.mak.in0000644000470500017500000016275512664710322020257 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on libdns.dsp !IF "$(CFG)" == "" CFG=libdns - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to libdns - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "libdns - @PLATFORM@ Release" && "$(CFG)" != "libdns - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "libdns.mak" CFG="libdns - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "libdns - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE "libdns - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF !IF "$(CFG)" == "libdns - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "libdns - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release !IF "$(RECURSE)" == "0" ALL : "..\..\..\Build\Release\libdns.dll" !ELSE ALL : "libisc - @PLATFORM@ Release" "..\..\..\Build\Release\libdns.dll" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libisc - @PLATFORM@ ReleaseCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\acache.obj" -@erase "$(INTDIR)\acl.obj" -@erase "$(INTDIR)\adb.obj" -@erase "$(INTDIR)\byaddr.obj" -@erase "$(INTDIR)\cache.obj" -@erase "$(INTDIR)\callbacks.obj" -@erase "$(INTDIR)\client.obj" -@erase "$(INTDIR)\clientinfo.obj" -@erase "$(INTDIR)\compress.obj" -@erase "$(INTDIR)\db.obj" -@erase "$(INTDIR)\dbiterator.obj" -@erase "$(INTDIR)\dbtable.obj" -@erase "$(INTDIR)\diff.obj" -@erase "$(INTDIR)\dispatch.obj" -@erase "$(INTDIR)\dlz.obj" -@erase "$(INTDIR)\DLLMain.obj" -@erase "$(INTDIR)\dns64.obj" -@erase "$(INTDIR)\dnssec.obj" -@erase "$(INTDIR)\ds.obj" -@erase "$(INTDIR)\dst_api.obj" -@erase "$(INTDIR)\dst_lib.obj" -@erase "$(INTDIR)\dst_parse.obj" -@erase "$(INTDIR)\dst_result.obj" -@erase "$(INTDIR)\ecdb.obj" -@erase "$(INTDIR)\forward.obj" @IF GEOIP -@erase "$(INTDIR)\geoip.obj" @END GEOIP -@erase "$(INTDIR)\gssapi_link.obj" -@erase "$(INTDIR)\gssapictx.obj" -@erase "$(INTDIR)\spnego.obj" -@erase "$(INTDIR)\hmac_link.obj" -@erase "$(INTDIR)\iptable.obj" -@erase "$(INTDIR)\journal.obj" -@erase "$(INTDIR)\key.obj" -@erase "$(INTDIR)\keytable.obj" -@erase "$(INTDIR)\lib.obj" -@erase "$(INTDIR)\log.obj" -@erase "$(INTDIR)\lookup.obj" -@erase "$(INTDIR)\master.obj" -@erase "$(INTDIR)\masterdump.obj" -@erase "$(INTDIR)\message.obj" -@erase "$(INTDIR)\name.obj" -@erase "$(INTDIR)\ncache.obj" -@erase "$(INTDIR)\nsec.obj" -@erase "$(INTDIR)\nsec3.obj" @IF OPENSSL -@erase "$(INTDIR)\openssl_link.obj" -@erase "$(INTDIR)\openssldh_link.obj" -@erase "$(INTDIR)\openssldsa_link.obj" -@erase "$(INTDIR)\opensslecdsa_link.obj" -@erase "$(INTDIR)\opensslgost_link.obj" -@erase "$(INTDIR)\opensslrsa_link.obj" @END OPENSSL -@erase "$(INTDIR)\order.obj" -@erase "$(INTDIR)\peer.obj" @IF PKCS11 -@erase "$(INTDIR)\pkcs11.obj" -@erase "$(INTDIR)\pkcs11dh_link.obj" -@erase "$(INTDIR)\pkcs11dsa_link.obj" -@erase "$(INTDIR)\pkcs11ecdsa_link.obj" -@erase "$(INTDIR)\pkcs11gost_link.obj" -@erase "$(INTDIR)\pkcs11rsa_link.obj" @END PKCS11 -@erase "$(INTDIR)\portlist.obj" -@erase "$(INTDIR)\private.obj" -@erase "$(INTDIR)\rbt.obj" -@erase "$(INTDIR)\rbtdb.obj" -@erase "$(INTDIR)\rbtdb64.obj" -@erase "$(INTDIR)\rcode.obj" -@erase "$(INTDIR)\rdata.obj" -@erase "$(INTDIR)\rdatalist.obj" -@erase "$(INTDIR)\rdataset.obj" -@erase "$(INTDIR)\rdatasetiter.obj" -@erase "$(INTDIR)\rdataslab.obj" -@erase "$(INTDIR)\request.obj" -@erase "$(INTDIR)\resolver.obj" -@erase "$(INTDIR)\result.obj" -@erase "$(INTDIR)\rootns.obj" -@erase "$(INTDIR)\rpz.obj" -@erase "$(INTDIR)\rrl.obj" -@erase "$(INTDIR)\sdb.obj" -@erase "$(INTDIR)\sdlz.obj" -@erase "$(INTDIR)\soa.obj" -@erase "$(INTDIR)\ssu.obj" -@erase "$(INTDIR)\ssu_external.obj" -@erase "$(INTDIR)\stats.obj" -@erase "$(INTDIR)\tcpmsg.obj" -@erase "$(INTDIR)\time.obj" -@erase "$(INTDIR)\timer.obj" -@erase "$(INTDIR)\tkey.obj" -@erase "$(INTDIR)\tsec.obj" -@erase "$(INTDIR)\tsig.obj" -@erase "$(INTDIR)\ttl.obj" -@erase "$(INTDIR)\update.obj" -@erase "$(INTDIR)\validator.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\version.obj" -@erase "$(INTDIR)\view.obj" -@erase "$(INTDIR)\xfrin.obj" -@erase "$(INTDIR)\zone.obj" -@erase "$(INTDIR)\zonekey.obj" -@erase "$(INTDIR)\zt.obj" -@erase "$(OUTDIR)\libdns.exp" -@erase "$(OUTDIR)\libdns.lib" -@erase "..\..\..\Build\Release\libdns.dll" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" LIBXML=@LIBXML2_LIB@ CPP=cl.exe CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" /I "include" /I "../include" /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" @OPENSSL_INC@ @LIBXML2_INC@ @GSSAPI_INC@ @GEOIP_INC@ /D "NDEBUG" /D "BIND9" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ @USE_GSSAPI@ @USE_ISC_SPNEGO@ /D "LIBDNS_EXPORTS" /Fp"$(INTDIR)\libdns.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << MTL=midl.exe MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\libdns.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib $(LIBXML) ../../isc/win32/Release/libisc.lib @OPENSSL_LIB@ @GSSAPI_LIB@ @KRB5_LIB@ @GEOIP_LIB@ /nologo /dll /incremental:no /pdb:"$(OUTDIR)\libdns.pdb" @MACHINE@ /def:".\libdns.def" /out:"../../../Build/Release/libdns.dll" /implib:"$(OUTDIR)\libdns.lib" DEF_FILE= \ ".\libdns.def" LINK32_OBJS= \ "$(INTDIR)\acache.obj" \ "$(INTDIR)\acl.obj" \ "$(INTDIR)\adb.obj" \ "$(INTDIR)\byaddr.obj" \ "$(INTDIR)\cache.obj" \ "$(INTDIR)\callbacks.obj" \ "$(INTDIR)\client.obj" \ "$(INTDIR)\clientinfo.obj" \ "$(INTDIR)\compress.obj" \ "$(INTDIR)\db.obj" \ "$(INTDIR)\dbiterator.obj" \ "$(INTDIR)\dbtable.obj" \ "$(INTDIR)\diff.obj" \ "$(INTDIR)\dispatch.obj" \ "$(INTDIR)\dlz.obj" \ "$(INTDIR)\DLLMain.obj" \ "$(INTDIR)\dns64.obj" \ "$(INTDIR)\dnssec.obj" \ "$(INTDIR)\ds.obj" \ "$(INTDIR)\ecdb.obj" \ "$(INTDIR)\forward.obj" \ @IF GEOIP "$(INTDIR)\geoip.obj" \ @END GEOIP "$(INTDIR)\iptable.obj" \ "$(INTDIR)\journal.obj" \ "$(INTDIR)\keydata.obj" \ "$(INTDIR)\keytable.obj" \ "$(INTDIR)\lib.obj" \ "$(INTDIR)\log.obj" \ "$(INTDIR)\lookup.obj" \ "$(INTDIR)\master.obj" \ "$(INTDIR)\masterdump.obj" \ "$(INTDIR)\message.obj" \ "$(INTDIR)\name.obj" \ "$(INTDIR)\ncache.obj" \ "$(INTDIR)\nsec.obj" \ "$(INTDIR)\nsec3.obj" \ "$(INTDIR)\order.obj" \ "$(INTDIR)\peer.obj" \ "$(INTDIR)\portlist.obj" \ "$(INTDIR)\private.obj" \ "$(INTDIR)\rbt.obj" \ "$(INTDIR)\rbtdb.obj" \ "$(INTDIR)\rbtdb64.obj" \ "$(INTDIR)\rcode.obj" \ "$(INTDIR)\rdata.obj" \ "$(INTDIR)\rdatalist.obj" \ "$(INTDIR)\rdataset.obj" \ "$(INTDIR)\rdatasetiter.obj" \ "$(INTDIR)\rdataslab.obj" \ "$(INTDIR)\request.obj" \ "$(INTDIR)\resolver.obj" \ "$(INTDIR)\result.obj" \ "$(INTDIR)\rootns.obj" \ "$(INTDIR)\rpz.obj" \ "$(INTDIR)\rrl.obj" \ "$(INTDIR)\rriterator.obj" \ "$(INTDIR)\sdb.obj" \ "$(INTDIR)\sdlz.obj" \ "$(INTDIR)\soa.obj" \ "$(INTDIR)\ssu.obj" \ "$(INTDIR)\ssu_external.obj" \ "$(INTDIR)\stats.obj" \ "$(INTDIR)\tcpmsg.obj" \ "$(INTDIR)\time.obj" \ "$(INTDIR)\timer.obj" \ "$(INTDIR)\tkey.obj" \ "$(INTDIR)\tsec.obj" \ "$(INTDIR)\tsig.obj" \ "$(INTDIR)\ttl.obj" \ "$(INTDIR)\update.obj" \ "$(INTDIR)\validator.obj" \ "$(INTDIR)\version.obj" \ "$(INTDIR)\view.obj" \ "$(INTDIR)\xfrin.obj" \ "$(INTDIR)\zone.obj" \ "$(INTDIR)\zonekey.obj" \ "$(INTDIR)\zt.obj" \ "$(INTDIR)\dst_api.obj" \ "$(INTDIR)\dst_lib.obj" \ "$(INTDIR)\dst_parse.obj" \ "$(INTDIR)\dst_result.obj" \ "$(INTDIR)\gssapi_link.obj" \ "$(INTDIR)\gssapictx.obj" \ "$(INTDIR)\spnego.obj" \ "$(INTDIR)\hmac_link.obj" \ "$(INTDIR)\key.obj" \ @IF OPENSSL "$(INTDIR)\openssl_link.obj" \ "$(INTDIR)\openssldh_link.obj" \ "$(INTDIR)\openssldsa_link.obj" \ "$(INTDIR)\opensslecdsa_link.obj" \ "$(INTDIR)\opensslgost_link.obj" \ "$(INTDIR)\opensslrsa_link.obj" \ @END OPENSSL @IF PKCS11 "$(INTDIR)\pkcs11.obj" \ "$(INTDIR)\pkcs11dh_link.obj" \ "$(INTDIR)\pkcs11dsa_link.obj" \ "$(INTDIR)\pkcs11ecdsa_link.obj" \ "$(INTDIR)\pkcs11gost_link.obj" \ "$(INTDIR)\pkcs11rsa_link.obj" \ @END PKCS11 "..\..\isc\win32\Release\libisc.lib" "..\..\..\Build\Release\libdns.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_DLL) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros !IF "$(RECURSE)" == "0" ALL : "..\..\..\Build\Debug\libdns.dll" "$(OUTDIR)\libdns.bsc" !ELSE ALL : "libisc - @PLATFORM@ Debug" "..\..\..\Build\Debug\libdns.dll" "$(OUTDIR)\libdns.bsc" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libisc - @PLATFORM@ DebugCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\acache.obj" -@erase "$(INTDIR)\acache.sbr" -@erase "$(INTDIR)\acl.obj" -@erase "$(INTDIR)\acl.sbr" -@erase "$(INTDIR)\adb.obj" -@erase "$(INTDIR)\adb.sbr" -@erase "$(INTDIR)\byaddr.obj" -@erase "$(INTDIR)\byaddr.sbr" -@erase "$(INTDIR)\cache.obj" -@erase "$(INTDIR)\cache.sbr" -@erase "$(INTDIR)\callbacks.obj" -@erase "$(INTDIR)\callbacks.sbr" -@erase "$(INTDIR)\client.obj" -@erase "$(INTDIR)\client.sbr" -@erase "$(INTDIR)\clientinfo.obj" -@erase "$(INTDIR)\clientinfo.sbr" -@erase "$(INTDIR)\compress.obj" -@erase "$(INTDIR)\compress.sbr" -@erase "$(INTDIR)\db.obj" -@erase "$(INTDIR)\db.sbr" -@erase "$(INTDIR)\dbiterator.obj" -@erase "$(INTDIR)\dbiterator.sbr" -@erase "$(INTDIR)\dbtable.obj" -@erase "$(INTDIR)\dbtable.sbr" -@erase "$(INTDIR)\diff.obj" -@erase "$(INTDIR)\diff.sbr" -@erase "$(INTDIR)\dispatch.obj" -@erase "$(INTDIR)\dispatch.sbr" -@erase "$(INTDIR)\dlz.obj" -@erase "$(INTDIR)\dlz.sbr" -@erase "$(INTDIR)\DLLMain.obj" -@erase "$(INTDIR)\DLLMain.sbr" -@erase "$(INTDIR)\dns64.obj" -@erase "$(INTDIR)\dns64.sbr" -@erase "$(INTDIR)\dnssec.obj" -@erase "$(INTDIR)\dnssec.sbr" -@erase "$(INTDIR)\ds.obj" -@erase "$(INTDIR)\ds.sbr" -@erase "$(INTDIR)\dst_api.obj" -@erase "$(INTDIR)\dst_api.sbr" -@erase "$(INTDIR)\dst_lib.obj" -@erase "$(INTDIR)\dst_lib.sbr" -@erase "$(INTDIR)\dst_parse.obj" -@erase "$(INTDIR)\dst_parse.sbr" -@erase "$(INTDIR)\dst_result.obj" -@erase "$(INTDIR)\dst_result.sbr" -@erase "$(INTDIR)\ecdb.obj" -@erase "$(INTDIR)\ecdb.sbr" -@erase "$(INTDIR)\forward.obj" -@erase "$(INTDIR)\forward.sbr" @IF GEOIP -@erase "$(INTDIR)\geoip.obj" -@erase "$(INTDIR)\geoip.sbr" @END GEOIP -@erase "$(INTDIR)\gssapi_link.obj" -@erase "$(INTDIR)\gssapi_link.sbr" -@erase "$(INTDIR)\gssapictx.obj" -@erase "$(INTDIR)\gssapictx.sbr" -@erase "$(INTDIR)\spnego.obj" -@erase "$(INTDIR)\spnego.sbr" -@erase "$(INTDIR)\hmac_link.obj" -@erase "$(INTDIR)\hmac_link.sbr" -@erase "$(INTDIR)\iptable.obj" -@erase "$(INTDIR)\iptable.sbr" -@erase "$(INTDIR)\journal.obj" -@erase "$(INTDIR)\journal.sbr" -@erase "$(INTDIR)\key.obj" -@erase "$(INTDIR)\key.sbr" -@erase "$(INTDIR)\keydata.obj" -@erase "$(INTDIR)\keydata.sbr" -@erase "$(INTDIR)\keytable.obj" -@erase "$(INTDIR)\keytable.sbr" -@erase "$(INTDIR)\lib.obj" -@erase "$(INTDIR)\lib.sbr" -@erase "$(INTDIR)\log.obj" -@erase "$(INTDIR)\log.sbr" -@erase "$(INTDIR)\lookup.obj" -@erase "$(INTDIR)\lookup.sbr" -@erase "$(INTDIR)\master.obj" -@erase "$(INTDIR)\master.sbr" -@erase "$(INTDIR)\masterdump.obj" -@erase "$(INTDIR)\masterdump.sbr" -@erase "$(INTDIR)\message.obj" -@erase "$(INTDIR)\message.sbr" -@erase "$(INTDIR)\name.obj" -@erase "$(INTDIR)\name.sbr" -@erase "$(INTDIR)\ncache.obj" -@erase "$(INTDIR)\ncache.sbr" -@erase "$(INTDIR)\nsec.obj" -@erase "$(INTDIR)\nsec.sbr" -@erase "$(INTDIR)\nsec3.obj" -@erase "$(INTDIR)\nsec3.sbr" @IF OPENSSL -@erase "$(INTDIR)\openssl_link.obj" -@erase "$(INTDIR)\openssl_link.sbr" -@erase "$(INTDIR)\openssldh_link.obj" -@erase "$(INTDIR)\openssldh_link.sbr" -@erase "$(INTDIR)\openssldsa_link.obj" -@erase "$(INTDIR)\openssldsa_link.sbr" -@erase "$(INTDIR)\opensslecdsa_link.obj" -@erase "$(INTDIR)\opensslecdsa_link.sbr" -@erase "$(INTDIR)\opensslgost_link.obj" -@erase "$(INTDIR)\opensslgost_link.sbr" -@erase "$(INTDIR)\opensslrsa_link.obj" -@erase "$(INTDIR)\opensslrsa_link.sbr" @END OPENSSL -@erase "$(INTDIR)\order.obj" -@erase "$(INTDIR)\order.sbr" -@erase "$(INTDIR)\peer.obj" -@erase "$(INTDIR)\peer.sbr" @IF PKCS11 -@erase "$(INTDIR)\pkcs11.obj" -@erase "$(INTDIR)\pkcs11.sbr" -@erase "$(INTDIR)\pkcs11dh_link.obj" -@erase "$(INTDIR)\pkcs11dh_link.sbr" -@erase "$(INTDIR)\pkcs11dsa_link.obj" -@erase "$(INTDIR)\pkcs11dsa_link.sbr" -@erase "$(INTDIR)\pkcs11ecdsa_link.obj" -@erase "$(INTDIR)\pkcs11ecdsa_link.sbr" -@erase "$(INTDIR)\pkcs11gost_link.obj" -@erase "$(INTDIR)\pkcs11gost_link.sbr" -@erase "$(INTDIR)\pkcs11rsa_link.obj" -@erase "$(INTDIR)\pkcs11rsa_link.sbr" @END PKCS11 -@erase "$(INTDIR)\portlist.obj" -@erase "$(INTDIR)\portlist.sbr" -@erase "$(INTDIR)\private.obj" -@erase "$(INTDIR)\private.sbr" -@erase "$(INTDIR)\rbt.obj" -@erase "$(INTDIR)\rbt.sbr" -@erase "$(INTDIR)\rbtdb.obj" -@erase "$(INTDIR)\rbtdb.sbr" -@erase "$(INTDIR)\rbtdb64.obj" -@erase "$(INTDIR)\rbtdb64.sbr" -@erase "$(INTDIR)\rcode.obj" -@erase "$(INTDIR)\rcode.sbr" -@erase "$(INTDIR)\rdata.obj" -@erase "$(INTDIR)\rdata.sbr" -@erase "$(INTDIR)\rdatalist.obj" -@erase "$(INTDIR)\rdatalist.sbr" -@erase "$(INTDIR)\rdataset.obj" -@erase "$(INTDIR)\rdataset.sbr" -@erase "$(INTDIR)\rdatasetiter.obj" -@erase "$(INTDIR)\rdatasetiter.sbr" -@erase "$(INTDIR)\rdataslab.obj" -@erase "$(INTDIR)\rdataslab.sbr" -@erase "$(INTDIR)\request.obj" -@erase "$(INTDIR)\request.sbr" -@erase "$(INTDIR)\resolver.obj" -@erase "$(INTDIR)\resolver.sbr" -@erase "$(INTDIR)\result.obj" -@erase "$(INTDIR)\result.sbr" -@erase "$(INTDIR)\rootns.obj" -@erase "$(INTDIR)\rootns.sbr" -@erase "$(INTDIR)\rpz.obj" -@erase "$(INTDIR)\rpz.sbr" -@erase "$(INTDIR)\rrl.obj" -@erase "$(INTDIR)\rrl.sbr" -@erase "$(INTDIR)\rriterator.obj" -@erase "$(INTDIR)\rriterator.sbr" -@erase "$(INTDIR)\sdb.obj" -@erase "$(INTDIR)\sdb.sbr" -@erase "$(INTDIR)\sdlz.obj" -@erase "$(INTDIR)\sdlz.sbr" -@erase "$(INTDIR)\soa.obj" -@erase "$(INTDIR)\soa.sbr" -@erase "$(INTDIR)\ssu.obj" -@erase "$(INTDIR)\ssu_external.obj" -@erase "$(INTDIR)\ssu.sbr" -@erase "$(INTDIR)\ssu_external.sbr" -@erase "$(INTDIR)\stats.obj" -@erase "$(INTDIR)\stats.sbr" -@erase "$(INTDIR)\tcpmsg.obj" -@erase "$(INTDIR)\tcpmsg.sbr" -@erase "$(INTDIR)\time.obj" -@erase "$(INTDIR)\time.sbr" -@erase "$(INTDIR)\timer.obj" -@erase "$(INTDIR)\timer.sbr" -@erase "$(INTDIR)\tkey.obj" -@erase "$(INTDIR)\tkey.sbr" -@erase "$(INTDIR)\tsec.obj" -@erase "$(INTDIR)\tsec.sbr" -@erase "$(INTDIR)\tsig.obj" -@erase "$(INTDIR)\tsig.sbr" -@erase "$(INTDIR)\ttl.obj" -@erase "$(INTDIR)\ttl.sbr" -@erase "$(INTDIR)\update.obj" -@erase "$(INTDIR)\update.sbr" -@erase "$(INTDIR)\validator.obj" -@erase "$(INTDIR)\validator.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(INTDIR)\version.obj" -@erase "$(INTDIR)\version.sbr" -@erase "$(INTDIR)\view.obj" -@erase "$(INTDIR)\view.sbr" -@erase "$(INTDIR)\xfrin.obj" -@erase "$(INTDIR)\xfrin.sbr" -@erase "$(INTDIR)\zone.obj" -@erase "$(INTDIR)\zone.sbr" -@erase "$(INTDIR)\zonekey.obj" -@erase "$(INTDIR)\zonekey.sbr" -@erase "$(INTDIR)\zt.obj" -@erase "$(INTDIR)\zt.sbr" -@erase "$(OUTDIR)\libdns.bsc" -@erase "$(OUTDIR)\libdns.exp" -@erase "$(OUTDIR)\libdns.lib" -@erase "$(OUTDIR)\libdns.map" -@erase "$(OUTDIR)\libdns.pdb" -@erase "..\..\..\Build\Debug\libdns.dll" -@erase "..\..\..\Build\Debug\libdns.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" /I "include" /I "../include" /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" @OPENSSL_INC@ @LIBXML2_INC@ @GSSAPI_INC@ @GEOIP_INC@ /D "_DEBUG" /D "BIND9" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ @USE_GSSAPI@ @USE_ISC_SPNEGO@ /D "LIBDNS_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\libdns.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << MTL=midl.exe MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\libdns.bsc" BSC32_SBRS= \ "$(INTDIR)\acache.sbr" \ "$(INTDIR)\acl.sbr" \ "$(INTDIR)\adb.sbr" \ "$(INTDIR)\byaddr.sbr" \ "$(INTDIR)\cache.sbr" \ "$(INTDIR)\callbacks.sbr" \ "$(INTDIR)\client.sbr" \ "$(INTDIR)\clientinfo.sbr" \ "$(INTDIR)\compress.sbr" \ "$(INTDIR)\db.sbr" \ "$(INTDIR)\dbiterator.sbr" \ "$(INTDIR)\dbtable.sbr" \ "$(INTDIR)\diff.sbr" \ "$(INTDIR)\dispatch.sbr" \ "$(INTDIR)\dlz.sbr" \ "$(INTDIR)\DLLMain.sbr" \ "$(INTDIR)\dns64.sbr" \ "$(INTDIR)\dnssec.sbr" \ "$(INTDIR)\ds.sbr" \ "$(INTDIR)\ecdb.sbr" \ "$(INTDIR)\forward.sbr" \ @IF GEOIP "$(INTDIR)\geoip.sbr" \ @END GEOIP "$(INTDIR)\iptable.sbr" \ "$(INTDIR)\journal.sbr" \ "$(INTDIR)\keydata.sbr" \ "$(INTDIR)\keytable.sbr" \ "$(INTDIR)\lib.sbr" \ "$(INTDIR)\log.sbr" \ "$(INTDIR)\lookup.sbr" \ "$(INTDIR)\master.sbr" \ "$(INTDIR)\masterdump.sbr" \ "$(INTDIR)\message.sbr" \ "$(INTDIR)\name.sbr" \ "$(INTDIR)\ncache.sbr" \ "$(INTDIR)\nsec.sbr" \ "$(INTDIR)\nsec3.sbr" \ "$(INTDIR)\order.sbr" \ "$(INTDIR)\peer.sbr" \ "$(INTDIR)\portlist.sbr" \ "$(INTDIR)\private.sbr" \ "$(INTDIR)\rbt.sbr" \ "$(INTDIR)\rbtdb.sbr" \ "$(INTDIR)\rbtdb64.sbr" \ "$(INTDIR)\rcode.sbr" \ "$(INTDIR)\rdata.sbr" \ "$(INTDIR)\rdatalist.sbr" \ "$(INTDIR)\rdataset.sbr" \ "$(INTDIR)\rdatasetiter.sbr" \ "$(INTDIR)\rdataslab.sbr" \ "$(INTDIR)\request.sbr" \ "$(INTDIR)\resolver.sbr" \ "$(INTDIR)\result.sbr" \ "$(INTDIR)\rootns.sbr" \ "$(INTDIR)\rpz.sbr" \ "$(INTDIR)\rrl.sbr" \ "$(INTDIR)\rriterator.sbr" \ "$(INTDIR)\sdb.sbr" \ "$(INTDIR)\sdlz.sbr" \ "$(INTDIR)\soa.sbr" \ "$(INTDIR)\ssu.sbr" \ "$(INTDIR)\ssu_external.sbr" \ "$(INTDIR)\stats.sbr" \ "$(INTDIR)\tcpmsg.sbr" \ "$(INTDIR)\time.sbr" \ "$(INTDIR)\timer.sbr" \ "$(INTDIR)\tkey.sbr" \ "$(INTDIR)\tsec.sbr" \ "$(INTDIR)\tsig.sbr" \ "$(INTDIR)\ttl.sbr" \ "$(INTDIR)\update.sbr" \ "$(INTDIR)\validator.sbr" \ "$(INTDIR)\version.sbr" \ "$(INTDIR)\view.sbr" \ "$(INTDIR)\xfrin.sbr" \ "$(INTDIR)\zone.sbr" \ "$(INTDIR)\zonekey.sbr" \ "$(INTDIR)\zt.sbr" \ "$(INTDIR)\dst_api.sbr" \ "$(INTDIR)\dst_lib.sbr" \ "$(INTDIR)\dst_parse.sbr" \ "$(INTDIR)\dst_result.sbr" \ "$(INTDIR)\gssapi_link.sbr" \ "$(INTDIR)\gssapictx.sbr" \ "$(INTDIR)\spnego.sbr" \ "$(INTDIR)\hmac_link.sbr" \ "$(INTDIR)\key.sbr" \ @IF OPENSSL "$(INTDIR)\openssl_link.sbr" \ "$(INTDIR)\openssldh_link.sbr" \ "$(INTDIR)\openssldsa_link.sbr" \ "$(INTDIR)\opensslecdsa_link.sbr" \ "$(INTDIR)\opensslgost_link.sbr" \ "$(INTDIR)\opensslrsa_link.sbr" \ @END OPENSSL @IF PKCS11 "$(INTDIR)\pkcs11.sbr" \ "$(INTDIR)\pkcs11dh_link.sbr" \ "$(INTDIR)\pkcs11dsa_link.sbr" \ "$(INTDIR)\pkcs11ecdsa_link.sbr" \ "$(INTDIR)\pkcs11gost_link.sbr" \ "$(INTDIR)\pkcs11rsa_link.sbr" @END PKCS11 "$(OUTDIR)\libdns.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib $(LIBXML) ../../isc/win32/Debug/libisc.lib @OPENSSL_LIB@ @GSSAPI_LIB@ @KRB5_LIB@ @GEOIP_LIB@ @GEOIP_LIB@ /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\libdns.pdb" /map:"$(INTDIR)\libdns.map" /debug @MACHINE@ /def:".\libdns.def" /out:"../../../Build/Debug/libdns.dll" /implib:"$(OUTDIR)\libdns.lib" /pdbtype:sept DEF_FILE= \ ".\libdns.def" LINK32_OBJS= \ "$(INTDIR)\acache.obj" \ "$(INTDIR)\acl.obj" \ "$(INTDIR)\adb.obj" \ "$(INTDIR)\byaddr.obj" \ "$(INTDIR)\cache.obj" \ "$(INTDIR)\callbacks.obj" \ "$(INTDIR)\client.obj" \ "$(INTDIR)\clientinfo.obj" \ "$(INTDIR)\compress.obj" \ "$(INTDIR)\db.obj" \ "$(INTDIR)\dbiterator.obj" \ "$(INTDIR)\dbtable.obj" \ "$(INTDIR)\diff.obj" \ "$(INTDIR)\dispatch.obj" \ "$(INTDIR)\dlz.obj" \ "$(INTDIR)\DLLMain.obj" \ "$(INTDIR)\dns64.obj" \ "$(INTDIR)\dnssec.obj" \ "$(INTDIR)\ds.obj" \ "$(INTDIR)\ecdb.obj" \ "$(INTDIR)\forward.obj" \ @IF GEOIP "$(INTDIR)\geoip.obj" \ @END GEOIP "$(INTDIR)\iptable.obj" \ "$(INTDIR)\journal.obj" \ "$(INTDIR)\key.obj" \ "$(INTDIR)\keytable.obj" \ "$(INTDIR)\lib.obj" \ "$(INTDIR)\log.obj" \ "$(INTDIR)\lookup.obj" \ "$(INTDIR)\master.obj" \ "$(INTDIR)\masterdump.obj" \ "$(INTDIR)\message.obj" \ "$(INTDIR)\name.obj" \ "$(INTDIR)\ncache.obj" \ "$(INTDIR)\nsec.obj" \ "$(INTDIR)\nsec3.obj" \ "$(INTDIR)\order.obj" \ "$(INTDIR)\peer.obj" \ "$(INTDIR)\portlist.obj" \ "$(INTDIR)\private.obj" \ "$(INTDIR)\rbt.obj" \ "$(INTDIR)\rbtdb.obj" \ "$(INTDIR)\rbtdb64.obj" \ "$(INTDIR)\rcode.obj" \ "$(INTDIR)\rdata.obj" \ "$(INTDIR)\rdatalist.obj" \ "$(INTDIR)\rdataset.obj" \ "$(INTDIR)\rdatasetiter.obj" \ "$(INTDIR)\rdataslab.obj" \ "$(INTDIR)\request.obj" \ "$(INTDIR)\resolver.obj" \ "$(INTDIR)\result.obj" \ "$(INTDIR)\rootns.obj" \ "$(INTDIR)\rpz.obj" \ "$(INTDIR)\rrl.obj" \ "$(INTDIR)\rriterator.obj" \ "$(INTDIR)\sdb.obj" \ "$(INTDIR)\sdlz.obj" \ "$(INTDIR)\soa.obj" \ "$(INTDIR)\ssu.obj" \ "$(INTDIR)\ssu_external.obj" \ "$(INTDIR)\stats.obj" \ "$(INTDIR)\tcpmsg.obj" \ "$(INTDIR)\time.obj" \ "$(INTDIR)\timer.obj" \ "$(INTDIR)\tkey.obj" \ "$(INTDIR)\tsec.obj" \ "$(INTDIR)\tsig.obj" \ "$(INTDIR)\ttl.obj" \ "$(INTDIR)\update.obj" \ "$(INTDIR)\validator.obj" \ "$(INTDIR)\version.obj" \ "$(INTDIR)\view.obj" \ "$(INTDIR)\xfrin.obj" \ "$(INTDIR)\zone.obj" \ "$(INTDIR)\zonekey.obj" \ "$(INTDIR)\zt.obj" \ "$(INTDIR)\dst_api.obj" \ "$(INTDIR)\dst_lib.obj" \ "$(INTDIR)\dst_parse.obj" \ "$(INTDIR)\dst_result.obj" \ "$(INTDIR)\gssapi_link.obj" \ "$(INTDIR)\gssapictx.obj" \ "$(INTDIR)\spnego.obj" \ "$(INTDIR)\hmac_link.obj" \ "$(INTDIR)\key.obj" \ @IF OPENSSL "$(INTDIR)\openssl_link.obj" \ "$(INTDIR)\openssldh_link.obj" \ "$(INTDIR)\openssldsa_link.obj" \ "$(INTDIR)\opensslecdsa_link.obj" \ "$(INTDIR)\opensslgost_link.obj" \ "$(INTDIR)\opensslrsa_link.obj" \ @END OPENSSL @IF PKCS11 "$(INTDIR)\pkcs11.obj" \ "$(INTDIR)\pkcs11dh_link.obj" \ "$(INTDIR)\pkcs11dsa_link.obj" \ "$(INTDIR)\pkcs11ecdsa_link.obj" \ "$(INTDIR)\pkcs11gost_link.obj" \ "$(INTDIR)\pkcs11rsa_link.obj" \ @END PKCS11 "..\..\isc\win32\Debug\libisc.lib" "..\..\..\Build\Debug\libdns.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_DLL) !ENDIF !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("libdns.dep") !INCLUDE "libdns.dep" !ELSE !MESSAGE Warning: cannot find "libdns.dep" !ENDIF !ENDIF !IF "$(CFG)" == "libdns - @PLATFORM@ Release" || "$(CFG)" == "libdns - @PLATFORM@ Debug" SOURCE=..\acache.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\acache.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\acache.obj" "$(INTDIR)\acache.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\acl.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\acl.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\acl.obj" "$(INTDIR)\acl.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\adb.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\adb.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\adb.obj" "$(INTDIR)\adb.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\byaddr.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\byaddr.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\byaddr.obj" "$(INTDIR)\byaddr.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\cache.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\cache.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\cache.obj" "$(INTDIR)\cache.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\callbacks.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\callbacks.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\callbacks.obj" "$(INTDIR)\callbacks.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\client.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\client.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\client.obj" "$(INTDIR)\client.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\clientinfo.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\clientinfo.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\clientinfo.obj" "$(INTDIR)\clientinfo.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\compress.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\compress.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\compress.obj" "$(INTDIR)\compress.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\db.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\db.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\db.obj" "$(INTDIR)\db.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\dbiterator.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\dbiterator.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\dbiterator.obj" "$(INTDIR)\dbiterator.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\dbtable.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\dbtable.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\dbtable.obj" "$(INTDIR)\dbtable.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\diff.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\diff.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\diff.obj" "$(INTDIR)\diff.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\dispatch.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" CPP_SWITCHES=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" /I "include" /I "../include" /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" @OPENSSL_INC@ @LIBXML2_INC@ @GSSAPI_INC@ @GEOIP_INC@ /D "NDEBUG" /D "BIND9" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ @USE_GSSAPI@ @USE_ISC_SPNEGO@ /D "LIBDNS_EXPORTS" /Fp"$(INTDIR)\libdns.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c "$(INTDIR)\dispatch.obj" : $(SOURCE) "$(INTDIR)" $(CPP) @<< $(CPP_SWITCHES) $(SOURCE) << !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" CPP_SWITCHES=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" /I "include" /I "../include" /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" @OPENSSL_INC@ @LIBXML2_INC@ @GSSAPI_INC@ @GEOIP_INC@ /D "_DEBUG" /D "BIND9" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ @USE_GSSAPI@ @USE_ISC_SPNEGO@ /D "LIBDNS_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\libdns.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c "$(INTDIR)\dispatch.obj" "$(INTDIR)\dispatch.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) @<< $(CPP_SWITCHES) $(SOURCE) << !ENDIF SOURCE=..\dlz.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\dlz.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\dlz.obj" "$(INTDIR)\dlz.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=.\DLLMain.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\DLLMain.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\DLLMain.obj" "$(INTDIR)\DLLMain.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=..\dns64.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\dns64.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\dns64.obj" "$(INTDIR)\dns64.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\dnssec.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\dnssec.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\dnssec.obj" "$(INTDIR)\dnssec.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\ds.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\ds.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\ds.obj" "$(INTDIR)\ds.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\ecdb.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\ecdb.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\ecdb.obj" "$(INTDIR)\ecdb.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\forward.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\forward.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\forward.obj" "$(INTDIR)\forward.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF @IF GEOIP SOURCE=..\geoip.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\geoip.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\geoip.obj" "$(INTDIR)\geoip.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF @END GEOIP SOURCE=..\iptable.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\iptable.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\iptable.obj" "$(INTDIR)\iptable.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\journal.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\journal.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\journal.obj" "$(INTDIR)\journal.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\keydata.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\keydata.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\keydata.obj" "$(INTDIR)\keydata.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\keytable.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\keytable.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\keytable.obj" "$(INTDIR)\keytable.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\lib.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\lib.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\lib.obj" "$(INTDIR)\lib.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\log.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\log.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\log.obj" "$(INTDIR)\log.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\lookup.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\lookup.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\lookup.obj" "$(INTDIR)\lookup.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\master.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\master.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\master.obj" "$(INTDIR)\master.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\masterdump.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\masterdump.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\masterdump.obj" "$(INTDIR)\masterdump.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\message.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\message.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\message.obj" "$(INTDIR)\message.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\name.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\name.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\name.obj" "$(INTDIR)\name.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\ncache.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\ncache.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\ncache.obj" "$(INTDIR)\ncache.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\nsec.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\nsec.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\nsec.obj" "$(INTDIR)\nsec.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\nsec3.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\nsec3.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\nsec3.obj" "$(INTDIR)\nsec3.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\order.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\order.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\order.obj" "$(INTDIR)\order.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\peer.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\peer.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\peer.obj" "$(INTDIR)\peer.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\portlist.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\portlist.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\portlist.obj" "$(INTDIR)\portlist.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\private.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\private.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\private.obj" "$(INTDIR)\portlist.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\rbt.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\rbt.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\rbt.obj" "$(INTDIR)\rbt.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\rbtdb.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\rbtdb.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\rbtdb.obj" "$(INTDIR)\rbtdb.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\rbtdb64.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\rbtdb64.obj" : $(SOURCE) "$(INTDIR)" "..\rbtdb.c" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\rbtdb64.obj" "$(INTDIR)\rbtdb64.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\rcode.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\rcode.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\rcode.obj" "$(INTDIR)\rcode.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\rdata.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\rdata.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\rdata.obj" "$(INTDIR)\rdata.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\rdatalist.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\rdatalist.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\rdatalist.obj" "$(INTDIR)\rdatalist.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\rdataset.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\rdataset.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\rdataset.obj" "$(INTDIR)\rdataset.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\rdatasetiter.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\rdatasetiter.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\rdatasetiter.obj" "$(INTDIR)\rdatasetiter.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\rdataslab.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\rdataslab.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\rdataslab.obj" "$(INTDIR)\rdataslab.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\request.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\request.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\request.obj" "$(INTDIR)\request.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\resolver.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\resolver.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\resolver.obj" "$(INTDIR)\resolver.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\result.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\result.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\result.obj" "$(INTDIR)\result.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\rootns.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\rootns.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\rootns.obj" "$(INTDIR)\rootns.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\rpz.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\rpz.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\rpz.obj" "$(INTDIR)\rpz.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\rrl.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\rrl.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\rrl.obj" "$(INTDIR)\rrl.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\rriterator.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\rriterator.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\rriterator.obj" "$(INTDIR)\rriterator.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\sdb.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\sdb.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\sdb.obj" "$(INTDIR)\sdb.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\sdlz.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\sdlz.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\sdlz.obj" "$(INTDIR)\sdlz.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\soa.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\soa.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\soa.obj" "$(INTDIR)\soa.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\ssu.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\ssu.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\ssu.obj" "$(INTDIR)\ssu.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\ssu_external.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\ssu_external.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\ssu_external.obj" "$(INTDIR)\ssu_external.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\stats.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\stats.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\stats.obj" "$(INTDIR)\stats.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\tcpmsg.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\tcpmsg.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\tcpmsg.obj" "$(INTDIR)\tcpmsg.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\time.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\time.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\time.obj" "$(INTDIR)\time.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\timer.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\timer.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\timer.obj" "$(INTDIR)\timer.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\tkey.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\tkey.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\tkey.obj" "$(INTDIR)\tkey.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\tsec.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\tsec.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\tsec.obj" "$(INTDIR)\tsec.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\tsig.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\tsig.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\tsig.obj" "$(INTDIR)\tsig.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\ttl.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\ttl.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\ttl.obj" "$(INTDIR)\ttl.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\update.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\update.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\update.obj" "$(INTDIR)\update.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\validator.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\validator.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\validator.obj" "$(INTDIR)\validator.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=.\version.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\version.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\version.obj" "$(INTDIR)\version.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=..\view.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\view.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\view.obj" "$(INTDIR)\view.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\xfrin.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\xfrin.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\xfrin.obj" "$(INTDIR)\xfrin.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\zone.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\zone.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\zone.obj" "$(INTDIR)\zone.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\zonekey.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\zonekey.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\zonekey.obj" "$(INTDIR)\zonekey.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\zt.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\zt.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\zt.obj" "$(INTDIR)\zt.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\dst_api.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\dst_api.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\dst_api.obj" "$(INTDIR)\dst_api.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\dst_lib.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\dst_lib.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\dst_lib.obj" "$(INTDIR)\dst_lib.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\dst_parse.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\dst_parse.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\dst_parse.obj" "$(INTDIR)\dst_parse.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\dst_result.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\dst_result.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\dst_result.obj" "$(INTDIR)\dst_result.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\gssapi_link.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\gssapi_link.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\gssapi_link.obj" "$(INTDIR)\gssapi_link.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\gssapictx.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\gssapictx.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\gssapictx.obj" "$(INTDIR)\gssapictx.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\spnego.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\spnego.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\spnego.obj" "$(INTDIR)\spnego.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\hmac_link.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\hmac_link.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\hmac_link.obj" "$(INTDIR)\hmac_link.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\key.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\key.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\key.obj" "$(INTDIR)\key.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF @IF OPENSSL SOURCE=..\openssl_link.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\openssl_link.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\openssl_link.obj" "$(INTDIR)\openssl_link.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\openssldh_link.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\openssldh_link.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\openssldh_link.obj" "$(INTDIR)\openssldh_link.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\openssldsa_link.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\openssldsa_link.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\openssldsa_link.obj" "$(INTDIR)\openssldsa_link.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\opensslecdsa_link.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\opensslecdsa_link.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\opensslecdsa_link.obj" "$(INTDIR)\opensslecdsa_link.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\opensslgost_link.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\opensslgost_link.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\opensslgost_link.obj" "$(INTDIR)\opensslgost_link.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\opensslrsa_link.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\opensslrsa_link.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\opensslrsa_link.obj" "$(INTDIR)\opensslrsa_link.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF @END OPENSSL @IF PKCS11 SOURCE=..\pkcs11.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\pkcs11.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\pkcs11.obj" "$(INTDIR)\pkcs11.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\pkcs11dh_link.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\pkcs11dh_link.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\pkcs11dh_link.obj" "$(INTDIR)\pkcs11dh_link.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\pkcs11dsa_link.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\pkcs11dsa_link.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\pkcs11dsa_link.obj" "$(INTDIR)\pkcs11dsa_link.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\pkcs11ecdsa_link.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\pkcs11ecdsa_link.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\pkcs11ecdsa_link.obj" "$(INTDIR)\pkcs11ecdsa_link.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\pkcs11gost_link.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\pkcs11gost_link.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\pkcs11gost_link.obj" "$(INTDIR)\pkcs11gost_link.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\pkcs11rsa_link.c !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "$(INTDIR)\pkcs11rsa_link.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "$(INTDIR)\pkcs11rsa_link.obj" "$(INTDIR)\pkcs11rsa_link.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF @END PKCS11 !IF "$(CFG)" == "libdns - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" cd "..\..\dns\win32" "libisc - @PLATFORM@ ReleaseCLEAN" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\dns\win32" !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" cd "..\..\dns\win32" "libisc - @PLATFORM@ DebugCLEAN" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\dns\win32" !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/lib/dns/win32/version.c0000644000470500017500000000247512664710322017526 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: version.c,v 1.6 2007/06/19 23:47:17 tbox Exp $ */ #include #include LIBDNS_EXTERNAL_DATA const char dns_version[] = VERSION; LIBDNS_EXTERNAL_DATA const char dns_major[] = MAJOR; LIBDNS_EXTERNAL_DATA const char dns_mapapi[] = MAPAPI; LIBDNS_EXTERNAL_DATA const unsigned int dns_libinterface = LIBINTERFACE; LIBDNS_EXTERNAL_DATA const unsigned int dns_librevision = LIBREVISION; LIBDNS_EXTERNAL_DATA const unsigned int dns_libage = LIBAGE; bind9-9.10.3.dfsg.P4/lib/dns/win32/libdns.dsw0000644000470500017500000000103112664710322017652 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "libdns"=".\libdns.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/lib/dns/win32/libdns.vcxproj.in0000644000470500017500000004035612664710322021172 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {5FEBFD4E-CCB0-48B9-B733-E15EEB85C16A} Win32Proj libdns DynamicLibrary true MultiByte DynamicLibrary false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ Level3 Disabled BIND9;WIN32;USE_MD5;@CRYPTO@@USE_GSSAPI@@USE_ISC_SPNEGO@_DEBUG;_WINDOWS;_USRDLL;LIBDNS_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions);%(PreprocessorDefinitions) .\;..\..\..\;include;..\include;..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;@LIBXML2_INC@@OPENSSL_INC@@GSSAPI_INC@@GEOIP_INC@%(AdditionalIncludeDirectories) false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) ..\..\isc\win32\$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;@LIBXML2_LIB@@OPENSSL_LIB@@GSSAPI_LIB@@KRB5_LIB@@GEOIP_LIB@ws2_32.lib;%(AdditionalDependencies) $(ProjectName).def .\$(Configuration)\$(ProjectName).lib Level3 MaxSpeed true @INTRINSIC@ BIND9;WIN32;USE_MD5;@CRYPTO@@USE_GSSAPI@@USE_ISC_SPNEGO@NDEBUG;_WINDOWS;_USRDLL;LIBDNS_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions);%(PreprocessorDefinitions) .\;..\..\..\;include;..\include;..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;@LIBXML2_INC@@OPENSSL_INC@@GSSAPI_INC@@GEOIP_INC@%(AdditionalIncludeDirectories) OnlyExplicitInline true .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb false Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) ..\..\isc\win32\$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;@LIBXML2_LIB@@OPENSSL_LIB@@GSSAPI_LIB@@KRB5_LIB@@GEOIP_LIB@ws2_32.lib;%(AdditionalDependencies) $(ProjectName).def .\$(Configuration)\$(ProjectName).lib Default @IF GEOIP @END GEOIP @IF OPENSSL @END OPENSSL @IF PKCS11 @END PKCS11 @IF OPENSSL @END OPENSSL @IF PKCS11 @END PKCS11 @IF GEOIP @END GEOIP bind9-9.10.3.dfsg.P4/lib/dns/win32/gen.vcxproj.in0000644000470500017500000001444212664710322020465 0ustar lamontlamont Debug @BUILD_PLATFORM@ Release @BUILD_PLATFORM@ {A3F71D12-F38A-4C77-8D87-8E8854CA74A1} Win32Proj gen Application true MultiByte Application false true MultiByte true ..\ .\$(Configuration)\ false ..\ .\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) .\;..\..\..\;..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;%(AdditionalIncludeDirectories) false .\$(Configuration)\$(TargetName).pch $(OutDir)$(TargetName).pdb true MultiThreadedDebugDLL .\$(Configuration)\ .\$(Configuration)\ Console true ..\$(TargetName)$(TargetExt) cd .. gen -s . -t > include\dns\enumtype.h gen -s . -c > include\dns\enumclass.h gen -s . -i -P ./rdata/rdatastructpre.h -S ./rdata/rdatastructsuf.h > include\dns\rdatastruct.h gen -s . > code.h Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) .\;..\..\..\;..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;%(AdditionalIncludeDirectories) OnlyExplicitInline true .\$(Configuration)\$(TargetName).pch $(OutDir)$(TargetName).pdb MultiThreadedDLL false .\$(Configuration)\ .\$(Configuration)\ Console false true true ..\$(TargetName)$(TargetExt) Default cd .. gen -s . -t > include\dns\enumtype.h gen -s . -c > include\dns\enumclass.h gen -s . -i -P ./rdata/rdatastructpre.h -S ./rdata/rdatastructsuf.h > include\dns\rdatastruct.h gen -s . > code.h bind9-9.10.3.dfsg.P4/lib/dns/win32/gen.dsp.in0000644000470500017500000001025312664710322017554 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="gen" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@BUILD_PLATFORM@ (x86) Console Application" 0x0103 CFG=gen - @BUILD_PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "gen.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "gen.mak" CFG="gen - @BUILD_PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "gen - @BUILD_PLATFORM@ Release" (based on "@BUILD_PLATFORM@ (x86) Console Application") !MESSAGE "gen - @BUILD_PLATFORM@ Debug" (based on "@BUILD_PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "gen - @BUILD_PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "LIBISC_EXPORTS" @COPTY@ /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @BUILD_MACHINE@ # ADD LINK32 user32.lib advapi32.lib /nologo /subsystem:console @BUILD_MACHINE@ /out:"../gen.exe" !ELSEIF "$(CFG)" == "gen - @BUILD_PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "LIBISC_EXPORTS" /FR /FD /GZ /c # SUBTRACT CPP /X @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @BUILD_MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib /nologo /subsystem:console /debug @BUILD_MACHINE@ /out:"../gen.exe" /pdbtype:sept !ENDIF # Begin Target # Name "gen - @BUILD_PLATFORM@ Release" # Name "gen - @BUILD_PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\gen.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE="..\gen-win32.h" # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/lib/dns/win32/libdns.vcxproj.user0000644000470500017500000000021712664710322021532 0ustar lamontlamont bind9-9.10.3.dfsg.P4/lib/dns/win32/libdns.dsp.in0000644000470500017500000004112512664710322020260 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="libdns" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Dynamic-Link Library" 0x0102 CFG=libdns - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "libdns.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "libdns.mak" CFG="libdns - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "libdns - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE "libdns - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "libdns - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 @COPTX@ @COPTI@ /O2 /D "BIND9" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "libdns_EXPORTS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" /I "include" /I "../include" /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" @LIBXML2_INC@ @OPENSSL_INC@ @GSSAPI_INC@ @GEOIP_INC@ /D "NDEBUG" /D "BIND9" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ @USE_GSSAPI@ @USE_ISC_SPNEGO@ /D "LIBDNS_EXPORTS" @COPTY@ /FD /c # SUBTRACT CPP /X # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll @MACHINE@ # ADD LINK32 @LIBXML2_LIB@ user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Release/libisc.lib @OPENSSL_LIB@ @GSSAPI_LIB@ @KRB5_LIB@ @GEOIP_LIB@ /nologo /dll @MACHINE@ /out:"../../../Build/Release/libdns.dll" !ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "BIND9" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "libdns_EXPORTS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" /I "include" /I "../include" /I "../../isc/win32" /I "../../isc/win32/include" /I "../../isc/include" @OPENSSL_INC@ @LIBXML2_INC@ @GSSAPI_INC@ @GEOIP_INC@ /D "_DEBUG" /D "BIND9" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ @USE_GSSAPI@ @USE_ISC_SPNEGO@ /D "LIBDNS_EXPORTS" /FR @COPTY@ /FD /GZ /c # SUBTRACT CPP /X # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug @MACHINE@ /pdbtype:sept # ADD LINK32 @LIBXML2_LIB@ user32.lib advapi32.lib ws2_32.lib ../../isc/win32/debug/libisc.lib @OPENSSL_LIB@ @GSSAPI_LIB@ @KRB5_LIB@ @GEOIP_LIB@ /nologo /dll /map /debug @MACHINE@ /out:"../../../Build/Debug/libdns.dll" /pdbtype:sept !ENDIF # Begin Target # Name "libdns - @PLATFORM@ Release" # Name "libdns - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=..\include\dns\acache.h # End Source File # Begin Source File SOURCE=..\include\dns\acl.h # End Source File # Begin Source File SOURCE=..\include\dns\adb.h # End Source File # Begin Source File SOURCE=..\include\dns\bit.h # End Source File # Begin Source File SOURCE=..\include\dns\byaddr.h # End Source File # Begin Source File SOURCE=..\include\dns\cache.h # End Source File # Begin Source File SOURCE=..\include\dns\callbacks.h # End Source File # Begin Source File SOURCE=..\include\dns\cert.h # End Source File # Begin Source File SOURCE=..\include\dns\client.h # End Source File # Begin Source File SOURCE=..\include\dns\clientinfo.h # End Source File # Begin Source File SOURCE=..\code.h # End Source File # Begin Source File SOURCE=..\include\dns\compress.h # End Source File # Begin Source File SOURCE=..\include\dns\db.h # End Source File # Begin Source File SOURCE=..\include\dns\dbiterator.h # End Source File # Begin Source File SOURCE=..\include\dns\dbtable.h # End Source File # Begin Source File SOURCE=..\include\dns\diff.h # End Source File # Begin Source File SOURCE=..\include\dns\dispatch.h # End Source File # Begin Source File SOURCE=..\include\dns\dlz.h # End Source File # Begin Source File SOURCE=..\include\dns\dns64.h # End Source File # Begin Source File SOURCE=..\include\dns\dnssec.h # End Source File # Begin Source File SOURCE=..\include\dns\ds.h # End Source File # Begin Source File SOURCE=..\include\dns\ecdb.h # End Source File # Begin Source File SOURCE=..\include\dns\enumclass.h # End Source File # Begin Source File SOURCE=..\include\dns\enumtype.h # End Source File # Begin Source File SOURCE=..\include\dns\events.h # End Source File # Begin Source File SOURCE=..\include\dns\fixedname.h # End Source File # Begin Source File SOURCE=..\include\dns\forward.h # End Source File @IF GEOIP # Begin Source File SOURCE=..\include\dns\geoip.h # End Source File @END GEOIP # Begin Source File SOURCE=..\include\dns\iptable.h # End Source File # Begin Source File SOURCE=..\include\dns\journal.h # End Source File # Begin Source File SOURCE=..\include\dns\keydata.h # End Source File # Begin Source File SOURCE=..\include\dns\keyflags.h # End Source File # Begin Source File SOURCE=..\include\dns\keytable.h # End Source File # Begin Source File SOURCE=..\include\dns\keyvalues.h # End Source File # Begin Source File SOURCE=..\include\dns\lib.h # End Source File # Begin Source File SOURCE=..\include\dns\log.h # End Source File # Begin Source File SOURCE=..\include\dns\lookup.h # End Source File # Begin Source File SOURCE=..\include\dns\master.h # End Source File # Begin Source File SOURCE=..\include\dns\masterdump.h # End Source File # Begin Source File SOURCE=..\include\dns\message.h # End Source File # Begin Source File SOURCE=..\include\dns\name.h # End Source File # Begin Source File SOURCE=..\include\dns\ncache.h # End Source File # Begin Source File SOURCE=..\include\dns\nsec.h # End Source File # Begin Source File SOURCE=..\include\dns\nsec3.h # End Source File # Begin Source File SOURCE=..\include\dns\order.h # End Source File # Begin Source File SOURCE=..\include\dns\peer.h # End Source File # Begin Source File SOURCE=..\include\dns\portlist.h # End Source File # Begin Source File SOURCE=..\include\dns\private.h # End Source File # Begin Source File SOURCE=..\include\dns\rbt.h # End Source File # Begin Source File SOURCE=..\rbtdb.h # End Source File # Begin Source File SOURCE=..\rbtdb64.h # End Source File # Begin Source File SOURCE=..\include\dns\rcode.h # End Source File # Begin Source File SOURCE=..\include\dns\rdata.h # End Source File # Begin Source File SOURCE=..\include\dns\rdataclass.h # End Source File # Begin Source File SOURCE=..\include\dns\rdatalist.h # End Source File # Begin Source File SOURCE=..\include\dns\rdataset.h # End Source File # Begin Source File SOURCE=..\include\dns\rdatasetiter.h # End Source File # Begin Source File SOURCE=..\include\dns\rdataslab.h # End Source File # Begin Source File SOURCE=..\include\dns\rdatastruct.h # End Source File # Begin Source File SOURCE=..\include\dns\rdatatype.h # End Source File # Begin Source File SOURCE=..\include\dns\request.h # End Source File # Begin Source File SOURCE=..\include\dns\resolver.h # End Source File # Begin Source File SOURCE=..\include\dns\result.h # End Source File # Begin Source File SOURCE=..\include\dns\rootns.h # End Source File # Begin Source File SOURCE=..\include\dns\rpz.h # End Source File # Begin Source File SOURCE=..\include\dns\rrl.h # End Source File # Begin Source File SOURCE=..\include\dns\rriterator.h # End Source File # Begin Source File SOURCE=..\include\dns\sdb.h # End Source File # Begin Source File SOURCE=..\include\dns\sdlz.h # End Source File # Begin Source File SOURCE=..\include\dns\secalg.h # End Source File # Begin Source File SOURCE=..\include\dns\secproto.h # End Source File # Begin Source File SOURCE=..\include\dns\soa.h # End Source File # Begin Source File SOURCE=..\include\dns\ssu.h # End Source File # Begin Source File SOURCE=..\include\dns\stats.h # End Source File # Begin Source File SOURCE=..\include\dns\tcpmsg.h # End Source File # Begin Source File SOURCE=..\include\dns\time.h # End Source File # Begin Source File SOURCE=..\include\dns\timer.h # End Source File # Begin Source File SOURCE=..\include\dns\tkey.h # End Source File # Begin Source File SOURCE=..\include\dns\tsec.h # End Source File # Begin Source File SOURCE=..\include\dns\tsig.h # End Source File # Begin Source File SOURCE=..\include\dns\ttl.h # End Source File # Begin Source File SOURCE=..\include\dns\types.h # End Source File # Begin Source File SOURCE=..\include\dns\update.h # End Source File # Begin Source File SOURCE=..\include\dns\validator.h # End Source File # Begin Source File SOURCE=..\include\dns\version.h # End Source File # Begin Source File SOURCE=..\include\dns\view.h # End Source File # Begin Source File SOURCE=..\include\dns\xfrin.h # End Source File # Begin Source File SOURCE=..\include\dns\zone.h # End Source File # Begin Source File SOURCE=..\include\dns\zonekey.h # End Source File # Begin Source File SOURCE=..\include\dns\zt.h # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # Begin Group "Main Dns Lib" # PROP Default_Filter "c" # Begin Source File SOURCE=..\acache.c # End Source File # Begin Source File SOURCE=..\acl.c # End Source File # Begin Source File SOURCE=..\adb.c # End Source File # Begin Source File SOURCE=..\byaddr.c # End Source File # Begin Source File SOURCE=..\cache.c # End Source File # Begin Source File SOURCE=..\callbacks.c # End Source File # Begin Source File SOURCE=..\client.c # End Source File # Begin Source File SOURCE=..\clientinfo.c # End Source File # Begin Source File SOURCE=..\compress.c # End Source File # Begin Source File SOURCE=..\db.c # End Source File # Begin Source File SOURCE=..\dbiterator.c # End Source File # Begin Source File SOURCE=..\dbtable.c # End Source File # Begin Source File SOURCE=..\diff.c # End Source File # Begin Source File SOURCE=..\dispatch.c # End Source File # Begin Source File SOURCE=..\dlz.c # End Source File # Begin Source File SOURCE=.\DLLMain.c # End Source File # Begin Source File SOURCE=..\dns64.c # End Source File # Begin Source File SOURCE=..\dnssec.c # End Source File # Begin Source File SOURCE=..\ds.c # End Source File # Begin Source File SOURCE=..\ecdb.c # End Source File # Begin Source File SOURCE=..\forward.c # End Source File @IF GEOIP # Begin Source File SOURCE=..\geoip.c # End Source File @END GEOIP # Begin Source File SOURCE=..\iptable.c # End Source File # Begin Source File SOURCE=..\journal.c # End Source File # Begin Source File SOURCE=..\keydata.c # End Source File # Begin Source File SOURCE=..\keytable.c # End Source File # Begin Source File SOURCE=..\lib.c # End Source File # Begin Source File SOURCE=..\log.c # End Source File # Begin Source File SOURCE=..\lookup.c # End Source File # Begin Source File SOURCE=..\master.c # End Source File # Begin Source File SOURCE=..\masterdump.c # End Source File # Begin Source File SOURCE=..\message.c # End Source File # Begin Source File SOURCE=..\name.c # End Source File # Begin Source File SOURCE=..\ncache.c # End Source File # Begin Source File SOURCE=..\nsec.c # End Source File # Begin Source File SOURCE=..\nsec3.c # End Source File # Begin Source File SOURCE=..\order.c # End Source File # Begin Source File SOURCE=..\peer.c # End Source File # Begin Source File SOURCE=..\portlist.c # End Source File # Begin Source File SOURCE=..\private.c # End Source File # Begin Source File SOURCE=..\rbt.c # End Source File # Begin Source File SOURCE=..\rbtdb.c # End Source File # Begin Source File SOURCE=..\rbtdb64.c # End Source File # Begin Source File SOURCE=..\rcode.c # End Source File # Begin Source File SOURCE=..\rdata.c # End Source File # Begin Source File SOURCE=..\rdatalist.c # End Source File # Begin Source File SOURCE=..\rdataset.c # End Source File # Begin Source File SOURCE=..\rdatasetiter.c # End Source File # Begin Source File SOURCE=..\rdataslab.c # End Source File # Begin Source File SOURCE=..\request.c # End Source File # Begin Source File SOURCE=..\resolver.c # End Source File # Begin Source File SOURCE=..\result.c # End Source File # Begin Source File SOURCE=..\rootns.c # End Source File # Begin Source File SOURCE=..\rpz.c # End Source File # Begin Source File SOURCE=..\rrl.c # End Source File # Begin Source File SOURCE=..\rriterator.c # End Source File # Begin Source File SOURCE=..\sdb.c # End Source File # Begin Source File SOURCE=..\soa.c # End Source File # Begin Source File SOURCE=..\sdlz.c # End Source File # Begin Source File SOURCE=..\ssu.c # End Source File # Begin Source File SOURCE=..\ssu_external.c # End Source File # Begin Source File SOURCE=..\stats.c # End Source File # Begin Source File SOURCE=..\tcpmsg.c # End Source File # Begin Source File SOURCE=..\time.c # End Source File # Begin Source File SOURCE=..\timer.c # End Source File # Begin Source File SOURCE=..\tkey.c # End Source File # Begin Source File SOURCE=..\tsec.c # End Source File # Begin Source File SOURCE=..\tsig.c # End Source File # Begin Source File SOURCE=..\ttl.c # End Source File # Begin Source File SOURCE=..\update.c # End Source File # Begin Source File SOURCE=..\validator.c # End Source File # Begin Source File SOURCE=.\version.c # End Source File # Begin Source File SOURCE=..\view.c # End Source File # Begin Source File SOURCE=..\xfrin.c # End Source File # Begin Source File SOURCE=..\zone.c # End Source File # Begin Source File SOURCE=..\zonekey.c # End Source File # Begin Source File SOURCE=..\zt.c # End Source File # End Group # Begin Group "dst" # PROP Default_Filter "c" # Begin Source File SOURCE=..\dst_api.c # End Source File # Begin Source File SOURCE=..\dst_lib.c # End Source File # Begin Source File SOURCE=..\dst_parse.c # End Source File # Begin Source File SOURCE=..\dst_result.c # End Source File # Begin Source File SOURCE=..\gssapi_link.c # End Source File # Begin Source File SOURCE=..\gssapictx.c # End Source File # Begin Source File SOURCE=..\spnego.c # End Source File # Begin Source File SOURCE=..\hmac_link.c # End Source File # Begin Source File SOURCE=..\key.c # End Source File @IF OPENSSL # Begin Source File SOURCE=..\openssl_link.c # End Source File # Begin Source File SOURCE=..\openssldh_link.c # End Source File # Begin Source File SOURCE=..\openssldsa_link.c # End Source File # Begin Source File SOURCE=..\opensslecdsa_link.c # End Source File # Begin Source File SOURCE=..\opensslgost_link.c # End Source File # Begin Source File SOURCE=..\opensslrsa_link.c # End Source File @END OPENSSL @IF PKCS11 # Begin Source File SOURCE=..\pkcs11.c # End Source File # Begin Source File SOURCE=..\pkcs11dh_link.c # End Source File # Begin Source File SOURCE=..\pkcs11dsa_link.c # End Source File # Begin Source File SOURCE=..\pkcs11ecdsa_link.c # End Source File # Begin Source File SOURCE=..\pkcs11gost_link.c # End Source File # Begin Source File SOURCE=..\pkcs11rsa_link.c # End Source File @END PKCS11 # End Group # Begin Source File SOURCE=.\libdns.def # End Source File # End Target # End Project bind9-9.10.3.dfsg.P4/lib/dns/win32/DLLMain.c0000644000470500017500000000313112664710322017247 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: DLLMain.c,v 1.6 2007/06/18 23:47:44 tbox Exp $ */ #include #include /* * Called when we enter the DLL */ __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { /* * The DLL is loading due to process * initialization or a call to LoadLibrary. */ case DLL_PROCESS_ATTACH: break; /* The attached process creates a new thread. */ case DLL_THREAD_ATTACH: break; /* The thread of the attached process terminates. */ case DLL_THREAD_DETACH: break; /* * The DLL is unloading from a process due to * process termination or a call to FreeLibrary. */ case DLL_PROCESS_DETACH: break; default: break; } return (TRUE); } bind9-9.10.3.dfsg.P4/lib/dns/win32/gen.vcxproj.filters.in0000644000470500017500000000207112664710322022127 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files Header Files bind9-9.10.3.dfsg.P4/lib/dns/win32/libdns.vcxproj.filters.in0000644000470500017500000005455312664710322022645 0ustar lamontlamont {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {c76276a2-cee5-4b70-bf37-e0f2ef1ae4d6} {ae84c9c7-5da5-4c0e-9e53-bfc34a5825ae} {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files @IF GEOIP Library Source Files @END GEOIP Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Dst Source Files Dst Source Files Dst Source Files Dst Source Files Dst Source Files Dst Source Files Dst Source Files Dst Source Files @IF OPENSSL Dst Source Files Dst Source Files Dst Source Files Dst Source Files Dst Source Files Dst Source Files @END OPENSSL @IF PKCS11 Dst Source Files Dst Source Files Dst Source Files Dst Source Files Dst Source Files Dst Source Files @END PKCS11 Dst Source Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files @IF GEOIP Library Header Files @END GEOIP Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Dst Header Files Dst Header Files Dst Header Files Dst Header Files Dst Header Files Dst Header Files @IF OPENSSL Dst Header Files @END OPENSSL Dst Header Files @IF PKCS11 Dst Header Files @END PKCS11 Dst Header Files bind9-9.10.3.dfsg.P4/lib/dns/win32/gen.mak.in0000644000470500017500000001537512664710322017550 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on gen.dsp !IF "$(CFG)" == "" CFG=gen - @BUILD_PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to gen - @BUILD_PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "gen - @BUILD_PLATFORM@ Release" && "$(CFG)" != "gen - @BUILD_PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "gen.mak" CFG="gen - @BUILD_PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "gen - @BUILD_PLATFORM@ Release" (based on "@BUILD_PLATFORM@ (x86) Console Application") !MESSAGE "gen - @BUILD_PLATFORM@ Debug" (based on "@BUILD_PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "gen - @BUILD_PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "gen - @BUILD_PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release ALL : "..\gen.exe" CLEAN : -@erase "$(INTDIR)\gen.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "..\gen.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo @COPTML@ /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "LIBISC_EXPORTS" /Fp"$(INTDIR)\gen.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\gen.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\gen.pdb" @BUILD_MACHINE@ /out:"../gen.exe" LINK32_OBJS= \ "$(INTDIR)\gen.obj" "..\gen.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "gen - @BUILD_PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros ALL : "..\gen.exe" "$(OUTDIR)\gen.bsc" CLEAN : -@erase "$(INTDIR)\gen.obj" -@erase "$(INTDIR)\gen.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\gen.bsc" -@erase "$(OUTDIR)\gen.pdb" -@erase "..\gen.exe" -@erase "..\gen.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo @COPTMLD@ /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "LIBISC_EXPORTS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\gen.bsc" BSC32_SBRS= \ "$(INTDIR)\gen.sbr" "$(OUTDIR)\gen.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\gen.pdb" /debug @BUILD_MACHINE@ /out:"../gen.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\gen.obj" "..\gen.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("gen.dep") !INCLUDE "gen.dep" !ELSE !MESSAGE Warning: cannot find "gen.dep" !ENDIF !ENDIF !IF "$(CFG)" == "gen - @BUILD_PLATFORM@ Release" || "$(CFG)" == "gen - @BUILD_PLATFORM@ Debug" SOURCE=..\gen.c !IF "$(CFG)" == "gen - @BUILD_PLATFORM@ Release" "$(INTDIR)\gen.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "gen - @BUILD_PLATFORM@ Debug" "$(INTDIR)\gen.obj" "$(INTDIR)\gen.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/lib/dns/win32/libdns.def.in0000644000470500017500000006551212664710322020236 0ustar lamontlamontLIBRARY libdns ; Exported Functions EXPORTS dns_acache_attach dns_acache_attachentry dns_acache_cancelentry dns_acache_countquerymiss dns_acache_create dns_acache_createentry dns_acache_detach dns_acache_detachentry dns_acache_getentry dns_acache_putdb dns_acache_setcachesize dns_acache_setcleaninginterval dns_acache_setdb dns_acache_setentry dns_acache_shutdown dns_acl_any dns_acl_attach dns_acl_create dns_acl_detach dns_acl_isany dns_acl_isinsecure dns_acl_isnone dns_acl_match dns_acl_merge dns_acl_none dns_aclelement_match dns_aclenv_copy dns_aclenv_destroy dns_aclenv_init dns_adb_agesrtt dns_adb_adjustsrtt dns_adb_attach dns_adb_beginudpfetch dns_adb_cancelfind dns_adb_changeflags dns_adb_create dns_adb_createfind dns_adb_createfind2 dns_adb_destroyfind dns_adb_detach dns_adb_dump dns_adb_dumpfind dns_adb_ednsto dns_adb_endudpfetch dns_adb_findaddrinfo dns_adb_flush dns_adb_flushname dns_adb_flushnames dns_adb_freeaddrinfo dns_adb_getudpsize dns_adb_getsit dns_adb_marklame dns_adb_noedns dns_adb_plainresponse dns_adb_probesize dns_adb_probesize2 dns_adb_setadbsize dns_adb_setudpsize dns_adb_setsit dns_adb_setquota dns_adb_shutdown dns_adb_timeout dns_adb_whenshutdown dns_adbentry_overquota dns_byaddr_cancel dns_byaddr_create dns_byaddr_createptrname dns_byaddr_createptrname2 dns_byaddr_destroy dns_cache_attach dns_cache_attachdb dns_cache_clean dns_cache_create dns_cache_create2 dns_cache_create3 dns_cache_detach dns_cache_dump dns_cache_dumpstats dns_cache_flush dns_cache_flushname dns_cache_flushnode dns_cache_getcachesize dns_cache_getcleaninginterval dns_cache_getname dns_cache_getstats dns_cache_load @IF JSON dns_cache_renderjson @END JSON @IF LIBXML2 dns_cache_renderxml @END LIBXML2 dns_cache_setcachesize dns_cache_setcleaninginterval dns_cache_setfilename dns_cache_updatestats dns_cert_fromtext dns_cert_totext dns_client_addtrustedkey dns_client_cancelrequest dns_client_cancelresolve dns_client_cancelupdate dns_client_clearservers dns_client_create dns_client_createx dns_client_createx2 dns_client_destroy dns_client_destroyreqtrans dns_client_destroyrestrans dns_client_destroyupdatetrans dns_client_freeresanswer dns_client_freeupdate dns_client_mctx dns_client_request dns_client_resolve dns_client_setdlv dns_client_setservers dns_client_startrequest dns_client_startresolve dns_client_startupdate dns_client_update dns_client_updaterec dns_clientinfo_init dns_clientinfomethods_init dns_compress_add dns_compress_findglobal dns_compress_getedns dns_compress_getmethods dns_compress_getsensitive dns_compress_init dns_compress_invalidate dns_compress_rollback dns_compress_setmethods dns_compress_setsensitive dns_counter_fromtext dns_db_addrdataset dns_db_allrdatasets dns_db_attach dns_db_attachnode dns_db_attachversion dns_db_beginload dns_db_class dns_db_closeversion dns_db_create dns_db_createiterator dns_db_createsoatuple dns_db_currentversion dns_db_deleterdataset dns_db_detach dns_db_detachnode dns_db_diff dns_db_diffx dns_db_dump dns_db_dump2 dns_db_endload dns_db_expirenode dns_db_find dns_db_findext dns_db_findnode dns_db_findnodeext dns_db_findnsec3node dns_db_findrdataset dns_db_findzonecut dns_db_getnsec3parameters dns_db_getoriginnode dns_db_getrrsetstats dns_db_getsigningtime dns_db_getsoaserial dns_db_hashsize dns_db_iscache dns_db_isdnssec dns_db_ispersistent dns_db_issecure dns_db_isstub dns_db_iszone dns_db_load dns_db_load2 dns_db_load3 dns_db_newversion dns_db_nodecount dns_db_ondestroy dns_db_origin dns_db_overmem dns_db_printnode dns_db_register dns_db_resigned dns_db_rpz_attach dns_db_rpz_ready dns_db_serialize dns_db_setcachestats dns_db_setsigningtime dns_db_settask dns_db_subtractrdataset dns_db_transfernode dns_db_unregister dns_dbiterator_current dns_dbiterator_destroy dns_dbiterator_first dns_dbiterator_last dns_dbiterator_next dns_dbiterator_origin dns_dbiterator_pause dns_dbiterator_prev dns_dbiterator_seek dns_dbiterator_setcleanmode dns_dbtable_add dns_dbtable_adddefault dns_dbtable_attach dns_dbtable_create dns_dbtable_detach dns_dbtable_find dns_dbtable_getdefault dns_dbtable_remove dns_dbtable_removedefault dns_decompress_edns dns_decompress_getmethods dns_decompress_init dns_decompress_invalidate dns_decompress_setmethods dns_decompress_type dns_diff_append dns_diff_appendminimal dns_diff_apply dns_diff_applysilently dns_diff_clear dns_diff_init dns_diff_load dns_diff_print dns_diff_sort dns_difftuple_copy dns_difftuple_create dns_difftuple_free dns_dispatch_addresponse dns_dispatch_addresponse2 dns_dispatch_addresponse3 dns_dispatch_attach dns_dispatch_cancel dns_dispatch_changeattributes dns_dispatch_createtcp dns_dispatch_detach dns_dispatch_getattributes dns_dispatch_getdscp dns_dispatch_getentrysocket dns_dispatch_getlocaladdress dns_dispatch_getsocket dns_dispatch_getudp dns_dispatch_getudp_dup dns_dispatch_importrecv dns_dispatch_removeresponse dns_dispatch_setdscp dns_dispatch_starttcp dns_dispatchmgr_create dns_dispatchmgr_destroy dns_dispatchmgr_getblackhole dns_dispatchmgr_getblackportlist dns_dispatchmgr_setavailports dns_dispatchmgr_setblackhole dns_dispatchmgr_setblackportlist dns_dispatchmgr_setstats dns_dispatchset_cancelall dns_dispatchset_create dns_dispatchset_destroy dns_dispatchset_get dns_dlz_ssumatch dns_dlz_writeablezone dns_dlzallowzonexfr dns_dlzconfigure dns_dlzcreate dns_dlzdestroy dns_dlzregister dns_dlzstrtoargv dns_dlzunregister dns_dns64_aaaafroma dns_dns64_aaaaok dns_dns64_append dns_dns64_create dns_dns64_destroy dns_dns64_next dns_dns64_unlink dns_dnssec_findmatchingkeys dns_dnssec_findzonekeys dns_dnssec_findzonekeys2 dns_dnssec_keyactive dns_dnssec_keyfromrdata dns_dnssec_keylistfromrdataset dns_dnssec_selfsigns dns_dnssec_sign dns_dnssec_signmessage dns_dnssec_signs dns_dnssec_updatekeys dns_dnssec_verify dns_dnssec_verify2 dns_dnssec_verify3 dns_dnssec_verifymessage dns_dnsseckey_create dns_dnsseckey_destroy dns_ds_buildrdata dns_dsdigest_fromtext dns_dsdigest_format dns_dsdigest_totext dns_dumpctx_attach dns_dumpctx_cancel dns_dumpctx_db dns_dumpctx_detach dns_dumpctx_version dns_ecdb_register dns_ecdb_unregister dns_fwdtable_add dns_fwdtable_addfwd dns_fwdtable_create dns_fwdtable_delete dns_fwdtable_destroy dns_fwdtable_find dns_fwdtable_find2 dns_generalstats_create dns_generalstats_dump dns_generalstats_increment @IF GEOIP dns_geoip_match dns_geoip_shutdown @END GEOIP dns_hashalg_fromtext dns_iptable_addprefix dns_iptable_attach dns_iptable_create dns_iptable_detach dns_iptable_merge dns_journal_begin_transaction dns_journal_commit dns_journal_compact dns_journal_current_rr dns_journal_destroy dns_journal_first_rr dns_journal_first_serial dns_journal_get_sourceserial dns_journal_iter_init dns_journal_last_serial dns_journal_next_rr dns_journal_open dns_journal_print dns_journal_rollforward dns_journal_set_sourceserial dns_journal_write_transaction dns_journal_writediff dns_keydata_fromdnskey dns_keydata_todnskey dns_keyflags_fromtext dns_keynode_attach dns_keynode_create dns_keynode_detach dns_keynode_detachall dns_keynode_key dns_keynode_managed dns_keyring_restore dns_keytable_add dns_keytable_attach dns_keytable_attachkeynode dns_keytable_create dns_keytable_delete dns_keytable_deletekeynode dns_keytable_detach dns_keytable_detachkeynode dns_keytable_dump dns_keytable_find dns_keytable_finddeepestmatch dns_keytable_findkeynode dns_keytable_findnextkeynode dns_keytable_issecuredomain dns_keytable_marksecure dns_keytable_nextkeynode dns_lib_init dns_lib_initmsgcat dns_lib_shutdown dns_loadctx_attach dns_loadctx_cancel dns_loadctx_detach dns_log_init dns_log_setcontext dns_lookup_cancel dns_lookup_create dns_lookup_destroy dns_master_dump dns_master_dump2 dns_master_dump3 dns_master_dumpinc dns_master_dumpinc2 dns_master_dumpinc3 dns_master_dumpnode dns_master_dumpnodetostream dns_master_dumptostream dns_master_dumptostream2 dns_master_dumptostream3 dns_master_dumptostreaminc dns_master_initrawheader dns_master_loadbuffer dns_master_loadbufferinc dns_master_loadfile dns_master_loadfile2 dns_master_loadfile3 dns_master_loadfile4 dns_master_loadfile5 dns_master_loadfileinc dns_master_loadfileinc2 dns_master_loadfileinc3 dns_master_loadfileinc4 dns_master_loadfileinc5 dns_master_loadlexer dns_master_loadlexerinc dns_master_loadstream dns_master_loadstreaminc dns_master_questiontotext dns_master_rdatasettotext dns_master_stylecreate dns_master_stylecreate2 dns_master_styledestroy dns_message_addname dns_message_buildopt dns_message_checksig dns_message_create dns_message_currentname dns_message_destroy dns_message_find dns_message_findname dns_message_findtype dns_message_firstname dns_message_getopt dns_message_getquerytsig dns_message_getrawmessage dns_message_getsig0 dns_message_getsig0key dns_message_gettempname dns_message_gettempoffsets dns_message_gettemprdata dns_message_gettemprdatalist dns_message_gettemprdataset dns_message_gettimeadjust dns_message_gettsig dns_message_gettsigkey dns_message_logpacket dns_message_logfmtpacket dns_message_movename dns_message_nextname dns_message_parse dns_message_peekheader dns_message_pseudosectiontotext dns_message_puttempname dns_message_puttemprdata dns_message_puttemprdatalist dns_message_puttemprdataset dns_message_rechecksig dns_message_removename dns_message_renderbegin dns_message_renderchangebuffer dns_message_renderend dns_message_renderheader dns_message_renderrelease dns_message_renderreserve dns_message_renderreset dns_message_rendersection dns_message_reply dns_message_reset dns_message_resetsig dns_message_sectiontotext dns_message_setclass dns_message_setopt dns_message_setquerytsig dns_message_setsig0key dns_message_setsortorder dns_message_settimeadjust dns_message_settsigkey dns_message_signer dns_message_takebuffer dns_message_totext dns_name_caseequal dns_name_clone dns_name_compare dns_name_concatenate dns_name_copy dns_name_countlabels dns_name_destroy dns_name_digest dns_name_downcase dns_name_dup dns_name_dupwithoffsets dns_name_dynamic dns_name_equal dns_name_format dns_name_free dns_name_fromregion dns_name_fromstring dns_name_fromstring2 dns_name_fromtext dns_name_fromwire dns_name_fullcompare dns_name_fullhash dns_name_getlabel dns_name_getlabelsequence dns_name_hasbuffer dns_name_hash dns_name_hashbylabel dns_name_init dns_name_internalwildcard dns_name_invalidate dns_name_isabsolute dns_name_isdnssd dns_name_ishostname dns_name_ismailbox dns_name_issubdomain dns_name_isvalid dns_name_iswildcard dns_name_matcheswildcard dns_name_print dns_name_rdatacompare dns_name_reset dns_name_setbuffer dns_name_settotextfilter dns_name_split dns_name_tofilenametext dns_name_toprincipal dns_name_toregion dns_name_tostring dns_name_totext dns_name_totext2 dns_name_towire dns_ncache_add dns_ncache_addoptout dns_ncache_current dns_ncache_getrdataset dns_ncache_getsigrdataset dns_ncache_towire dns_nsec3_active dns_nsec3_activex dns_nsec3_addnsec3 dns_nsec3_addnsec3s dns_nsec3_addnsec3sx dns_nsec3_buildrdata dns_nsec3_delnsec3 dns_nsec3_delnsec3s dns_nsec3_delnsec3sx dns_nsec3_hashlength dns_nsec3_hashname dns_nsec3_maxiterations dns_nsec3_noexistnodata dns_nsec3_supportedhash dns_nsec3_typepresent dns_nsec3param_deletechains dns_nsec3param_fromprivate dns_nsec3param_toprivate dns_nsec_build dns_nsec_buildrdata dns_nsec_compressbitmap dns_nsec_isset dns_nsec_nseconly dns_nsec_noexistnodata dns_nsec_setbit dns_nsec_typepresent dns_opcode_totext dns_opcodestats_create dns_opcodestats_dump dns_opcodestats_increment dns_order_add dns_order_attach dns_order_create dns_order_detach dns_order_find dns_peer_attach dns_peer_detach dns_peer_getbogus dns_peer_getkey dns_peer_getmaxudp dns_peer_getnotifydscp dns_peer_getnotifysource dns_peer_getprovideixfr dns_peer_getquerydscp dns_peer_getquerysource dns_peer_getrequestixfr dns_peer_getrequestnsid dns_peer_getrequestsit dns_peer_getsupportedns dns_peer_getudpsize dns_peer_gettransferdscp dns_peer_gettransferformat dns_peer_gettransfers dns_peer_gettransfersource dns_peer_new dns_peer_newprefix dns_peer_setbogus dns_peer_setkey dns_peer_setkeybycharp dns_peer_setmaxudp dns_peer_setnotifydscp dns_peer_setnotifysource dns_peer_setprovideixfr dns_peer_setquerydscp dns_peer_setquerysource dns_peer_setrequestixfr dns_peer_setrequestnsid dns_peer_setrequestsit dns_peer_setsupportedns dns_peer_settransferdscp dns_peer_settransferformat dns_peer_settransfers dns_peer_settransfersource dns_peer_setudpsize dns_peerlist_addpeer dns_peerlist_attach dns_peerlist_currpeer dns_peerlist_detach dns_peerlist_new dns_peerlist_peerbyaddr dns_portlist_add dns_portlist_attach dns_portlist_create dns_portlist_detach dns_portlist_match dns_portlist_remove dns_private_chains dns_private_totext dns_rbt_addname dns_rbt_addnode dns_rbt_create dns_rbt_deletename dns_rbt_deletenode dns_rbt_deserialize_tree dns_rbt_destroy dns_rbt_destroy2 dns_rbt_findname dns_rbt_findnode dns_rbt_formatnodename dns_rbt_fullnamefromnode dns_rbt_hashsize dns_rbt_namefromnode dns_rbt_nodecount dns_rbt_printtext dns_rbt_printdot dns_rbt_printnodeinfo dns_rbt_root dns_rbt_serialize_align dns_rbt_serialize_tree dns_rbtnode_nodename dns_rbtnodechain_current dns_rbtnodechain_down dns_rbtnodechain_first dns_rbtnodechain_init dns_rbtnodechain_invalidate dns_rbtnodechain_last dns_rbtnodechain_next dns_rbtnodechain_nextflat dns_rbtnodechain_prev dns_rbtnodechain_reset dns_rcode_fromtext dns_rcode_totext dns_rdata_additionaldata dns_rdata_casecompare dns_rdata_checknames dns_rdata_checkowner dns_rdata_clone dns_rdata_compare dns_rdata_covers dns_rdata_deleterrset dns_rdata_digest dns_rdata_exists dns_rdata_freestruct dns_rdata_fromregion dns_rdata_fromstruct dns_rdata_fromtext dns_rdata_fromwire dns_rdata_init dns_rdata_makedelete dns_rdata_notexist dns_rdata_reset dns_rdata_tofmttext dns_rdata_toregion dns_rdata_tostruct dns_rdata_totext dns_rdata_towire dns_rdata_updateop dns_rdatacallbacks_init dns_rdatacallbacks_init_stdio dns_rdataclass_format dns_rdataclass_fromtext dns_rdataclass_ismeta dns_rdataclass_totext dns_rdatalist_fromrdataset dns_rdatalist_init dns_rdatalist_tordataset dns_rdataset_addclosest dns_rdataset_additionaldata dns_rdataset_addnoqname dns_rdataset_clearprefetch dns_rdataset_clone dns_rdataset_count dns_rdataset_current dns_rdataset_disassociate dns_rdataset_expire dns_rdataset_first dns_rdataset_getadditional dns_rdataset_getclosest dns_rdataset_getnoqname dns_rdataset_init dns_rdataset_invalidate dns_rdataset_isassociated dns_rdataset_makequestion dns_rdataset_next dns_rdataset_putadditional dns_rdataset_setadditional dns_rdataset_settrust dns_rdataset_totext dns_rdataset_towire dns_rdataset_towirepartial dns_rdataset_towiresorted dns_rdataset_trimttl dns_rdatasetiter_current dns_rdatasetiter_destroy dns_rdatasetiter_first dns_rdatasetiter_next dns_rdatasetstats_create dns_rdatasetstats_decrement dns_rdatasetstats_dump dns_rdatasetstats_increment dns_rdataslab_equal dns_rdataslab_equalx dns_rdataslab_fromrdataset dns_rdataslab_merge dns_rdataslab_size dns_rdataslab_subtract dns_rdataslab_tordataset dns_rdatatype_atparent dns_rdatatype_attributes dns_rdatatype_format dns_rdatatype_fromtext dns_rdatatype_isdnssec dns_rdatatype_isknown dns_rdatatype_ismeta dns_rdatatype_issingleton dns_rdatatype_iszonecutauth dns_rdatatype_notquestion dns_rdatatype_questiononly dns_rdatatype_totext dns_rdatatypestats_create dns_rdatatypestats_dump dns_rdatatypestats_increment dns_request_cancel dns_request_create dns_request_createraw dns_request_createraw2 dns_request_createraw3 dns_request_createraw4 dns_request_createvia dns_request_createvia2 dns_request_createvia3 dns_request_createvia4 dns_request_destroy dns_request_getresponse dns_request_usedtcp dns_requestmgr_attach dns_requestmgr_create dns_requestmgr_detach dns_requestmgr_shutdown dns_requestmgr_whenshutdown dns_resolver_addalternate dns_resolver_addbadcache dns_resolver_algorithm_supported dns_resolver_attach dns_resolver_cancelfetch dns_resolver_create dns_resolver_createfetch dns_resolver_createfetch2 dns_resolver_createfetch3 dns_resolver_destroyfetch dns_resolver_detach dns_resolver_disable_algorithm dns_resolver_disable_ds_digest dns_resolver_dispatchmgr dns_resolver_dispatchv4 dns_resolver_dispatchv6 dns_resolver_ds_digest_supported dns_resolver_dumpfetches dns_resolver_flushbadcache dns_resolver_flushbadnames dns_resolver_freeze dns_resolver_getbadcache dns_resolver_getclientsperquery dns_resolver_getlamettl dns_resolver_getmaxdepth dns_resolver_getmaxqueries dns_resolver_getmustbesecure dns_resolver_getoptions dns_resolver_getquerydscp4 dns_resolver_getquerydscp6 dns_resolver_getquotaresponse dns_resolver_gettimeout dns_resolver_getudpsize dns_resolver_getzeronosoattl dns_resolver_logfetch dns_resolver_nrunning dns_resolver_prime dns_resolver_printbadcache dns_resolver_reset_algorithms dns_resolver_reset_ds_digests dns_resolver_resetmustbesecure dns_resolver_setclientsperquery dns_resolver_setfetchesperzone dns_resolver_setlamettl dns_resolver_setmustbesecure dns_resolver_setmaxdepth dns_resolver_setmaxqueries dns_resolver_setquerydscp4 dns_resolver_setquerydscp6 dns_resolver_setquotaresponse dns_resolver_settimeout dns_resolver_setudpsize dns_resolver_setzeronosoattl dns_resolver_shutdown dns_resolver_socketmgr dns_resolver_taskmgr dns_resolver_whenshutdown dns_result_register dns_result_torcode dns_result_totext dns_root_checkhints dns_rootns_create dns_rpz_add dns_rpz_attach_rpzs dns_rpz_beginload dns_rpz_decode_cname dns_rpz_delete dns_rpz_detach_rpzs dns_rpz_find_ip dns_rpz_find_name dns_rpz_new_zones dns_rpz_policy2str dns_rpz_ready dns_rpz_str2policy dns_rpz_type2str dns_rriterator_current dns_rriterator_destroy dns_rriterator_first dns_rriterator_init dns_rriterator_next dns_rriterator_nextrrset dns_rriterator_pause dns_rrl dns_rrl_init dns_rrl_view_destroy dns_sdb_putnamedrdata dns_sdb_putnamedrr dns_sdb_putrdata dns_sdb_putrr dns_sdb_putsoa dns_sdb_register dns_sdb_unregister dns_sdlz_putnamedrr dns_sdlz_putrr dns_sdlz_putsoa dns_sdlz_setdb dns_sdlzregister dns_sdlzunregister dns_secalg_format dns_secalg_fromtext dns_secalg_totext dns_secproto_fromtext dns_secproto_totext dns_soa_buildrdata dns_soa_getexpire dns_soa_getminimum dns_soa_getrefresh dns_soa_getretry dns_soa_getserial dns_soa_setexpire dns_soa_setminimum dns_soa_setrefresh dns_soa_setretry dns_soa_setserial dns_ssu_external_match dns_ssutable_addrule dns_ssutable_attach dns_ssutable_checkrules dns_ssutable_create dns_ssutable_createdlz dns_ssutable_detach dns_stats_attach dns_stats_alloccounters dns_stats_detach dns_stats_freecounters dns_tcpmsg_cancelread dns_tcpmsg_init dns_tcpmsg_invalidate dns_tcpmsg_keepbuffer dns_tcpmsg_readmessage dns_tcpmsg_setmaxsize dns_time32_fromtext dns_time32_totext dns_time64_from32 dns_time64_fromtext dns_time64_totext dns_timer_setidle dns_tkey_builddeletequery dns_tkey_builddhquery dns_tkey_buildgssquery dns_tkey_gssnegotiate dns_tkey_processdeleteresponse dns_tkey_processdhresponse dns_tkey_processgssresponse dns_tkey_processquery dns_tkeyctx_create dns_tkeyctx_destroy dns_trust_totext dns_tsec_create dns_tsec_destroy dns_tsec_getkey dns_tsec_gettype dns_tsig_sign dns_tsig_verify dns_tsigkey_attach dns_tsigkey_create dns_tsigkey_createfromkey dns_tsigkey_detach dns_tsigkey_find dns_tsigkey_setdeleted dns_tsigkeyring_add dns_tsigkeyring_attach dns_tsigkeyring_create dns_tsigkeyring_detach dns_tsigkeyring_dumpanddetach dns_tsigrcode_fromtext dns_tsigrcode_totext dns_ttl_fromtext dns_ttl_totext dns_update_signatures dns_update_signaturesinc dns_update_soaserial dns_validator_cancel dns_validator_create dns_validator_destroy dns_validator_send dns_view_adddelegationonly dns_view_addzone dns_view_asyncload dns_view_attach dns_view_checksig dns_view_create dns_view_createresolver dns_view_createzonetable dns_view_detach dns_view_dialup dns_view_dumpdbtostream dns_view_excludedelegationonly dns_view_find dns_view_find2 dns_view_findzone dns_view_findzonecut dns_view_findzonecut2 dns_view_flushanddetach dns_view_flushcache dns_view_flushcache2 dns_view_flushname dns_view_flushnode dns_view_freeze dns_view_freezezones dns_view_getadbstats dns_view_getdynamickeyring dns_view_getpeertsig dns_view_getresquerystats dns_view_getresstats dns_view_getrootdelonly dns_view_getsecroots dns_view_gettsig dns_view_initsecroots dns_view_iscacheshared dns_view_isdelegationonly dns_view_issecuredomain dns_view_load dns_view_loadnew dns_view_restorekeyring dns_view_searchdlz dns_view_setadbstats dns_view_setcache dns_view_setcache2 dns_view_setdstport dns_view_setdynamickeyring dns_view_sethints dns_view_setkeyring dns_view_setnewzones dns_view_setresquerystats dns_view_setresstats dns_view_setrootdelonly dns_view_simplefind dns_view_thaw dns_view_untrust dns_view_weakattach dns_view_weakdetach dns_viewlist_find dns_viewlist_findzone dns_xfrin_attach dns_xfrin_create dns_xfrin_create2 dns_xfrin_create3 dns_xfrin_detach dns_xfrin_shutdown dns_zone_addnsec3chain dns_zone_asyncload dns_zone_attach dns_zone_cdscheck dns_zone_checknames dns_zone_clearforwardacl dns_zone_clearnotifyacl dns_zone_clearqueryacl dns_zone_clearqueryonacl dns_zone_clearupdateacl dns_zone_clearxfracl dns_zone_create dns_zone_detach dns_zone_dialup dns_zone_dlzpostload dns_zone_dump dns_zone_dumptostream dns_zone_dumptostream2 dns_zone_dumptostream3 dns_zone_expire dns_zone_first dns_zone_flush dns_zone_forcereload dns_zone_forwardupdate dns_zone_fulldumptostream dns_zone_get_rpz_num dns_zone_getadded dns_zone_getaltxfrsource4 dns_zone_getaltxfrsource4dscp dns_zone_getaltxfrsource6 dns_zone_getaltxfrsource6dscp dns_zone_getchecknames dns_zone_getclass dns_zone_getdb dns_zone_getdbtype dns_zone_getexpiretime dns_zone_getfile dns_zone_getforwardacl dns_zone_getidlein dns_zone_getidleout dns_zone_getincludes dns_zone_getjournal dns_zone_getjournalsize dns_zone_getkeydirectory dns_zone_getkeyopts dns_zone_getloadtime dns_zone_getmaxttl dns_zone_getmaxxfrin dns_zone_getmaxxfrout dns_zone_getmctx dns_zone_getmgr dns_zone_getnotifyacl dns_zone_getnotifydelay dns_zone_getnotifysrc4 dns_zone_getnotifysrc4dscp dns_zone_getnotifysrc6 dns_zone_getnotifysrc6dscp dns_zone_getoptions dns_zone_getoptions2 dns_zone_getorigin dns_zone_getprivatetype dns_zone_getqueryacl dns_zone_getqueryonacl dns_zone_getraw dns_zone_getrcvquerystats dns_zone_getrefreshkeytime dns_zone_getrefreshtime dns_zone_getrequestixfr dns_zone_getrequeststats dns_zone_getserial dns_zone_getserial2 dns_zone_getserialupdatemethod dns_zone_getsignatures dns_zone_getsigresigninginterval dns_zone_getsigvalidityinterval dns_zone_getssutable dns_zone_getstatlevel dns_zone_getstatscounters dns_zone_gettask dns_zone_gettype dns_zone_getupdateacl dns_zone_getupdatedisabled dns_zone_getview dns_zone_getxfracl dns_zone_getxfrsource4 dns_zone_getxfrsource4dscp dns_zone_getxfrsource6 dns_zone_getxfrsource6dscp dns_zone_getzeronosoattl dns_zone_iattach dns_zone_idetach dns_zone_isdynamic dns_zone_isforced dns_zone_keydone dns_zone_link dns_zone_load dns_zone_loadandthaw dns_zone_loadnew dns_zone_log dns_zone_logc dns_zone_maintenance dns_zone_markdirty dns_zone_mkey_hour dns_zone_mkey_day dns_zone_mkey_month dns_zone_name dns_zone_nameonly dns_zone_next dns_zone_notify dns_zone_notifyreceive dns_zone_nscheck dns_zone_refresh dns_zone_rekey dns_zone_replacedb dns_zone_rpz_enable dns_zone_rpz_enable_db dns_zone_setacache dns_zone_setadded dns_zone_setalsonotify dns_zone_setalsonotifydscpkeys dns_zone_setalsonotifywithkeys dns_zone_setaltxfrsource4 dns_zone_setaltxfrsource4dscp dns_zone_setaltxfrsource6 dns_zone_setaltxfrsource6dscp dns_zone_setcheckmx dns_zone_setchecknames dns_zone_setcheckns dns_zone_setchecksrv dns_zone_setclass dns_zone_setdb dns_zone_setdbtype dns_zone_setdialup dns_zone_setfile dns_zone_setfile2 dns_zone_setflag dns_zone_setforwardacl dns_zone_setidlein dns_zone_setidleout dns_zone_setisself dns_zone_setjournal dns_zone_setjournalsize dns_zone_setkeydirectory dns_zone_setkeyopt dns_zone_setmasters dns_zone_setmasterswithkeys dns_zone_setmaxrefreshtime dns_zone_setmaxretrytime dns_zone_setmaxttl dns_zone_setmaxxfrin dns_zone_setmaxxfrout dns_zone_setminrefreshtime dns_zone_setminretrytime dns_zone_setnodes dns_zone_setnotifyacl dns_zone_setnotifydelay dns_zone_setnotifysrc4 dns_zone_setnotifysrc4dscp dns_zone_setnotifysrc6 dns_zone_setnotifysrc6dscp dns_zone_setnotifytype dns_zone_setnsec3param dns_zone_setoption dns_zone_setoption2 dns_zone_setorigin dns_zone_setprivatetype dns_zone_setqueryacl dns_zone_setqueryonacl dns_zone_setrawdata dns_zone_setrcvquerystats dns_zone_setrefreshkeyinterval dns_zone_setrequestixfr dns_zone_setrequeststats dns_zone_setserialupdatemethod dns_zone_setsignatures dns_zone_setsigresigninginterval dns_zone_setsigvalidityinterval dns_zone_setssutable dns_zone_setstatistics dns_zone_setstatlevel dns_zone_setstats dns_zone_settask dns_zone_settype dns_zone_setupdateacl dns_zone_setupdatedisabled dns_zone_setview dns_zone_setxfracl dns_zone_setxfrsource4 dns_zone_setxfrsource4dscp dns_zone_setxfrsource6 dns_zone_setxfrsource6dscp dns_zone_setzeronosoattl dns_zone_signwithkey dns_zone_synckeyzone dns_zone_unload dns_zonekey_iszonekey dns_zonemgr_attach dns_zonemgr_create dns_zonemgr_createzone dns_zonemgr_detach dns_zonemgr_forcemaint dns_zonemgr_getcount dns_zonemgr_getiolimit dns_zonemgr_getserialqueryrate dns_zonemgr_getttransfersin dns_zonemgr_getttransfersperns dns_zonemgr_managezone dns_zonemgr_releasezone dns_zonemgr_resumexfrs dns_zonemgr_setiolimit dns_zonemgr_setserialqueryrate dns_zonemgr_setsize dns_zonemgr_settransfersin dns_zonemgr_settransfersperns dns_zonemgr_shutdown dns_zonemgr_unreachable dns_zonemgr_unreachableadd dns_zonemgr_unreachabledel dns_zt_apply dns_zt_apply2 dns_zt_asyncload dns_zt_attach dns_zt_create dns_zt_detach dns_zt_find dns_zt_flushanddetach dns_zt_freezezones dns_zt_load dns_zt_loadnew dns_zt_mount dns_zt_unmount dst_algorithm_supported dst_context_adddata dst_context_create dst_context_create2 dst_context_create3 dst_context_create4 dst_context_destroy dst_context_sign dst_context_verify dst_context_verify2 dst_ds_digest_supported dst_gssapi_acceptctx dst_gssapi_acquirecred dst_gssapi_deletectx dst_gssapi_identitymatchesrealmkrb5 dst_gssapi_identitymatchesrealmms dst_gssapi_initctx dst_gssapi_releasecred dst_key_alg dst_key_attach dst_key_buildfilename dst_key_buildinternal dst_key_class dst_key_compare dst_key_computesecret dst_key_dump dst_key_flags dst_key_format dst_key_free dst_key_frombuffer dst_key_fromdns dst_key_fromfile dst_key_fromgssapi dst_key_fromlabel dst_key_fromnamedfile dst_key_generate dst_key_generate2 dst_key_getbits dst_key_getgssctx dst_key_getnum dst_key_getprivateformat dst_key_gettime dst_key_getttl dst_key_id dst_key_inactive dst_key_isexternal dst_key_isnullkey dst_key_isprivate dst_key_iszonekey dst_key_name dst_key_paramcompare dst_key_privatefrombuffer dst_key_proto dst_key_pubcompare dst_key_read_public dst_key_restore dst_key_rid dst_key_secretsize dst_key_setbits dst_key_setexternal dst_key_setflags dst_key_setinactive dst_key_setnum dst_key_setprivateformat dst_key_settime dst_key_setttl dst_key_sigsize dst_key_size dst_key_tkeytoken dst_key_tobuffer dst_key_todns dst_key_tofile dst_key_unsetnum dst_key_unsettime dst_lib_destroy dst_lib_init dst_lib_init2 dst_lib_initmsgcat dst_region_computeid dst_region_computerid dst_result_register dst_result_totext @IF NOLONGER ; Exported Data EXPORTS dns_master_style_full DATA @END NOLONGER bind9-9.10.3.dfsg.P4/lib/dns/win32/gen.vcxproj.user0000644000470500017500000000021712664710322021030 0ustar lamontlamont bind9-9.10.3.dfsg.P4/lib/dns/win32/gen.dsw0000644000470500017500000000102312664710322017151 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "gen"=".\gen.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/lib/dns/stats.c0000644000470500017500000002671212664710322016235 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007-2009, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: stats.c,v 1.18 2009/01/27 23:47:54 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #define DNS_STATS_MAGIC ISC_MAGIC('D', 's', 't', 't') #define DNS_STATS_VALID(x) ISC_MAGIC_VALID(x, DNS_STATS_MAGIC) /*% * Statistics types. */ typedef enum { dns_statstype_general = 0, dns_statstype_rdtype = 1, dns_statstype_rdataset = 2, dns_statstype_opcode = 3 } dns_statstype_t; /*% * It doesn't make sense to have 2^16 counters for all possible types since * most of them won't be used. We have counters for the first 256 types and * those explicitly supported in the rdata implementation. * XXXJT: this introduces tight coupling with the rdata implementation. * Ideally, we should have rdata handle this type of details. */ /* * types, !types, nxdomain, stale types, stale !types, stale nxdomain */ enum { /* For 0-255, we use the rdtype value as counter indices */ rdtypecounter_dlv = 256, /* for dns_rdatatype_dlv */ rdtypecounter_others = 257, /* anything else */ rdtypecounter_max = 258, /* The following are used for rdataset */ rdtypenxcounter_max = rdtypecounter_max * 2, rdtypecounter_nxdomain = rdtypenxcounter_max, /* stale counters offset */ rdtypecounter_stale = rdtypecounter_nxdomain + 1, rdatasettypecounter_max = rdtypecounter_stale * 2 }; struct dns_stats { /*% Unlocked */ unsigned int magic; dns_statstype_t type; isc_mem_t *mctx; isc_mutex_t lock; isc_stats_t *counters; /*% Locked by lock */ unsigned int references; }; typedef struct rdatadumparg { dns_rdatatypestats_dumper_t fn; void *arg; } rdatadumparg_t; typedef struct opcodedumparg { dns_opcodestats_dumper_t fn; void *arg; } opcodedumparg_t; void dns_stats_attach(dns_stats_t *stats, dns_stats_t **statsp) { REQUIRE(DNS_STATS_VALID(stats)); REQUIRE(statsp != NULL && *statsp == NULL); LOCK(&stats->lock); stats->references++; UNLOCK(&stats->lock); *statsp = stats; } void dns_stats_detach(dns_stats_t **statsp) { dns_stats_t *stats; REQUIRE(statsp != NULL && DNS_STATS_VALID(*statsp)); stats = *statsp; *statsp = NULL; LOCK(&stats->lock); stats->references--; UNLOCK(&stats->lock); if (stats->references == 0) { isc_stats_detach(&stats->counters); DESTROYLOCK(&stats->lock); isc_mem_putanddetach(&stats->mctx, stats, sizeof(*stats)); } } /*% * Create methods */ static isc_result_t create_stats(isc_mem_t *mctx, dns_statstype_t type, int ncounters, dns_stats_t **statsp) { dns_stats_t *stats; isc_result_t result; stats = isc_mem_get(mctx, sizeof(*stats)); if (stats == NULL) return (ISC_R_NOMEMORY); stats->counters = NULL; stats->references = 1; result = isc_mutex_init(&stats->lock); if (result != ISC_R_SUCCESS) goto clean_stats; result = isc_stats_create(mctx, &stats->counters, ncounters); if (result != ISC_R_SUCCESS) goto clean_mutex; stats->magic = DNS_STATS_MAGIC; stats->type = type; stats->mctx = NULL; isc_mem_attach(mctx, &stats->mctx); *statsp = stats; return (ISC_R_SUCCESS); clean_mutex: DESTROYLOCK(&stats->lock); clean_stats: isc_mem_put(mctx, stats, sizeof(*stats)); return (result); } isc_result_t dns_generalstats_create(isc_mem_t *mctx, dns_stats_t **statsp, int ncounters) { REQUIRE(statsp != NULL && *statsp == NULL); return (create_stats(mctx, dns_statstype_general, ncounters, statsp)); } isc_result_t dns_rdatatypestats_create(isc_mem_t *mctx, dns_stats_t **statsp) { REQUIRE(statsp != NULL && *statsp == NULL); return (create_stats(mctx, dns_statstype_rdtype, rdtypecounter_max, statsp)); } isc_result_t dns_rdatasetstats_create(isc_mem_t *mctx, dns_stats_t **statsp) { REQUIRE(statsp != NULL && *statsp == NULL); return (create_stats(mctx, dns_statstype_rdataset, rdatasettypecounter_max, statsp)); } isc_result_t dns_opcodestats_create(isc_mem_t *mctx, dns_stats_t **statsp) { REQUIRE(statsp != NULL && *statsp == NULL); return (create_stats(mctx, dns_statstype_opcode, 16, statsp)); } /*% * Increment/Decrement methods */ void dns_generalstats_increment(dns_stats_t *stats, isc_statscounter_t counter) { REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_general); isc_stats_increment(stats->counters, counter); } void dns_rdatatypestats_increment(dns_stats_t *stats, dns_rdatatype_t type) { int counter; REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_rdtype); if (type == dns_rdatatype_dlv) counter = rdtypecounter_dlv; else if (type > dns_rdatatype_any) counter = rdtypecounter_others; else counter = (int)type; isc_stats_increment(stats->counters, (isc_statscounter_t)counter); } static inline void update_rdatasetstats(dns_stats_t *stats, dns_rdatastatstype_t rrsettype, isc_boolean_t increment) { int counter; dns_rdatatype_t rdtype; if ((DNS_RDATASTATSTYPE_ATTR(rrsettype) & DNS_RDATASTATSTYPE_ATTR_NXDOMAIN) != 0) { counter = rdtypecounter_nxdomain; } else { rdtype = DNS_RDATASTATSTYPE_BASE(rrsettype); if (rdtype == dns_rdatatype_dlv) counter = (int)rdtypecounter_dlv; else if (rdtype > dns_rdatatype_any) counter = (int)rdtypecounter_others; else counter = (int)rdtype; if ((DNS_RDATASTATSTYPE_ATTR(rrsettype) & DNS_RDATASTATSTYPE_ATTR_NXRRSET) != 0) counter += rdtypecounter_max; } if (increment) { if ((DNS_RDATASTATSTYPE_ATTR(rrsettype) & DNS_RDATASTATSTYPE_ATTR_STALE) != 0) { isc_stats_decrement(stats->counters, counter); counter += rdtypecounter_stale; } isc_stats_increment(stats->counters, counter); } else { if ((DNS_RDATASTATSTYPE_ATTR(rrsettype) & DNS_RDATASTATSTYPE_ATTR_STALE) != 0) counter += rdtypecounter_stale; isc_stats_decrement(stats->counters, counter); } } void dns_rdatasetstats_increment(dns_stats_t *stats, dns_rdatastatstype_t rrsettype) { REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_rdataset); update_rdatasetstats(stats, rrsettype, ISC_TRUE); } void dns_rdatasetstats_decrement(dns_stats_t *stats, dns_rdatastatstype_t rrsettype) { REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_rdataset); update_rdatasetstats(stats, rrsettype, ISC_FALSE); } void dns_opcodestats_increment(dns_stats_t *stats, dns_opcode_t code) { REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_opcode); isc_stats_increment(stats->counters, (isc_statscounter_t)code); } /*% * Dump methods */ void dns_generalstats_dump(dns_stats_t *stats, dns_generalstats_dumper_t dump_fn, void *arg, unsigned int options) { REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_general); isc_stats_dump(stats->counters, (isc_stats_dumper_t)dump_fn, arg, options); } static void dump_rdentry(int rdcounter, isc_uint64_t value, dns_rdatastatstype_t attributes, dns_rdatatypestats_dumper_t dump_fn, void * arg) { dns_rdatatype_t rdtype = dns_rdatatype_none; /* sentinel */ dns_rdatastatstype_t type; if (rdcounter == rdtypecounter_others) attributes |= DNS_RDATASTATSTYPE_ATTR_OTHERTYPE; else { if (rdcounter == rdtypecounter_dlv) rdtype = dns_rdatatype_dlv; else rdtype = (dns_rdatatype_t)rdcounter; } type = DNS_RDATASTATSTYPE_VALUE((dns_rdatastatstype_t)rdtype, attributes); dump_fn(type, value, arg); } static void rdatatype_dumpcb(isc_statscounter_t counter, isc_uint64_t value, void *arg) { rdatadumparg_t *rdatadumparg = arg; dump_rdentry(counter, value, 0, rdatadumparg->fn, rdatadumparg->arg); } void dns_rdatatypestats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn, void *arg0, unsigned int options) { rdatadumparg_t arg; REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_rdtype); arg.fn = dump_fn; arg.arg = arg0; isc_stats_dump(stats->counters, rdatatype_dumpcb, &arg, options); } static void rdataset_dumpcb(isc_statscounter_t counter, isc_uint64_t value, void *arg) { rdatadumparg_t *rdatadumparg = arg; unsigned int attributes; if (counter < rdtypecounter_max) { dump_rdentry(counter, value, 0, rdatadumparg->fn, rdatadumparg->arg); } else if (counter < rdtypecounter_nxdomain) { counter -= rdtypecounter_max; attributes = DNS_RDATASTATSTYPE_ATTR_NXRRSET; dump_rdentry(counter, value, attributes, rdatadumparg->fn, rdatadumparg->arg); } else if (counter == rdtypecounter_nxdomain) { dump_rdentry(0, value, DNS_RDATASTATSTYPE_ATTR_NXDOMAIN, rdatadumparg->fn, rdatadumparg->arg); } else if (counter < rdtypecounter_stale + rdtypecounter_max) { counter -= rdtypecounter_stale; attributes = DNS_RDATASTATSTYPE_ATTR_STALE; dump_rdentry(counter, value, attributes, rdatadumparg->fn, rdatadumparg->arg); } else if (counter < rdtypecounter_stale + rdtypecounter_nxdomain) { counter -= rdtypecounter_stale + rdtypecounter_max; attributes = DNS_RDATASTATSTYPE_ATTR_NXRRSET | DNS_RDATASTATSTYPE_ATTR_STALE; dump_rdentry(counter, value, attributes, rdatadumparg->fn, rdatadumparg->arg); } else { attributes = DNS_RDATASTATSTYPE_ATTR_NXDOMAIN | DNS_RDATASTATSTYPE_ATTR_STALE; dump_rdentry(0, value, attributes, rdatadumparg->fn, rdatadumparg->arg); } } void dns_rdatasetstats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn, void *arg0, unsigned int options) { rdatadumparg_t arg; REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_rdataset); arg.fn = dump_fn; arg.arg = arg0; isc_stats_dump(stats->counters, rdataset_dumpcb, &arg, options); } static void opcode_dumpcb(isc_statscounter_t counter, isc_uint64_t value, void *arg) { opcodedumparg_t *opcodearg = arg; opcodearg->fn((dns_opcode_t)counter, value, opcodearg->arg); } void dns_opcodestats_dump(dns_stats_t *stats, dns_opcodestats_dumper_t dump_fn, void *arg0, unsigned int options) { opcodedumparg_t arg; REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_opcode); arg.fn = dump_fn; arg.arg = arg0; isc_stats_dump(stats->counters, opcode_dumpcb, &arg, options); } /*** *** Obsolete variables and functions follow: ***/ LIBDNS_EXTERNAL_DATA const char *dns_statscounter_names[DNS_STATS_NCOUNTERS] = { "success", "referral", "nxrrset", "nxdomain", "recursion", "failure", "duplicate", "dropped" }; isc_result_t dns_stats_alloccounters(isc_mem_t *mctx, isc_uint64_t **ctrp) { int i; isc_uint64_t *p = isc_mem_get(mctx, DNS_STATS_NCOUNTERS * sizeof(isc_uint64_t)); if (p == NULL) return (ISC_R_NOMEMORY); for (i = 0; i < DNS_STATS_NCOUNTERS; i++) p[i] = 0; *ctrp = p; return (ISC_R_SUCCESS); } void dns_stats_freecounters(isc_mem_t *mctx, isc_uint64_t **ctrp) { isc_mem_put(mctx, *ctrp, DNS_STATS_NCOUNTERS * sizeof(isc_uint64_t)); *ctrp = NULL; } bind9-9.10.3.dfsg.P4/lib/dns/dst_api.c0000644000470500017500000014043012664710322016514 0ustar lamontlamont/* * Portions Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * Principal Author: Brian Wellington * $Id: dst_api.c,v 1.65 2011/10/20 21:20:02 marka Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define DST_KEY_INTERNAL #include #include #include #include #include #include #include #include #include "dst_internal.h" #define DST_AS_STR(t) ((t).value.as_textregion.base) static dst_func_t *dst_t_func[DST_MAX_ALGS]; static isc_entropy_t *dst_entropy_pool = NULL; static unsigned int dst_entropy_flags = 0; static isc_boolean_t dst_initialized = ISC_FALSE; void gss_log(int level, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3); isc_mem_t *dst__memory_pool = NULL; /* * Static functions. */ static dst_key_t * get_key_struct(dns_name_t *name, unsigned int alg, unsigned int flags, unsigned int protocol, unsigned int bits, dns_rdataclass_t rdclass, dns_ttl_t ttl, isc_mem_t *mctx); static isc_result_t write_public_key(const dst_key_t *key, int type, const char *directory); static isc_result_t buildfilename(dns_name_t *name, dns_keytag_t id, unsigned int alg, unsigned int type, const char *directory, isc_buffer_t *out); static isc_result_t computeid(dst_key_t *key); static isc_result_t frombuffer(dns_name_t *name, unsigned int alg, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp); static isc_result_t algorithm_status(unsigned int alg); static isc_result_t addsuffix(char *filename, int len, const char *dirname, const char *ofilename, const char *suffix); #define RETERR(x) \ do { \ result = (x); \ if (result != ISC_R_SUCCESS) \ goto out; \ } while (0) #define CHECKALG(alg) \ do { \ isc_result_t _r; \ _r = algorithm_status(alg); \ if (_r != ISC_R_SUCCESS) \ return (_r); \ } while (0); \ #if defined(OPENSSL) static void * default_memalloc(void *arg, size_t size) { UNUSED(arg); if (size == 0U) size = 1; return (malloc(size)); } static void default_memfree(void *arg, void *ptr) { UNUSED(arg); free(ptr); } #endif isc_result_t dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags) { return (dst_lib_init2(mctx, ectx, NULL, eflags)); } isc_result_t dst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx, const char *engine, unsigned int eflags) { isc_result_t result; REQUIRE(mctx != NULL); REQUIRE(dst_initialized == ISC_FALSE); #if !defined(OPENSSL) && !defined(PKCS11CRYPTO) UNUSED(engine); #endif dst__memory_pool = NULL; #if defined(OPENSSL) UNUSED(mctx); /* * When using --with-openssl, there seems to be no good way of not * leaking memory due to the openssl error handling mechanism. * Avoid assertions by using a local memory context and not checking * for leaks on exit. Note: as there are leaks we cannot use * ISC_MEMFLAG_INTERNAL as it will free up memory still being used * by libcrypto. */ result = isc_mem_createx2(0, 0, default_memalloc, default_memfree, NULL, &dst__memory_pool, 0); if (result != ISC_R_SUCCESS) return (result); isc_mem_setname(dst__memory_pool, "dst", NULL); #ifndef OPENSSL_LEAKS isc_mem_setdestroycheck(dst__memory_pool, ISC_FALSE); #endif #else /* OPENSSL */ isc_mem_attach(mctx, &dst__memory_pool); #endif /* OPENSSL */ if (ectx != NULL) { isc_entropy_attach(ectx, &dst_entropy_pool); dst_entropy_flags = eflags; } dst_result_register(); memset(dst_t_func, 0, sizeof(dst_t_func)); RETERR(dst__hmacmd5_init(&dst_t_func[DST_ALG_HMACMD5])); RETERR(dst__hmacsha1_init(&dst_t_func[DST_ALG_HMACSHA1])); RETERR(dst__hmacsha224_init(&dst_t_func[DST_ALG_HMACSHA224])); RETERR(dst__hmacsha256_init(&dst_t_func[DST_ALG_HMACSHA256])); RETERR(dst__hmacsha384_init(&dst_t_func[DST_ALG_HMACSHA384])); RETERR(dst__hmacsha512_init(&dst_t_func[DST_ALG_HMACSHA512])); #ifdef OPENSSL RETERR(dst__openssl_init(engine)); RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSAMD5], DST_ALG_RSAMD5)); RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA1], DST_ALG_RSASHA1)); RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_NSEC3RSASHA1], DST_ALG_NSEC3RSASHA1)); RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA256], DST_ALG_RSASHA256)); RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA512], DST_ALG_RSASHA512)); #ifdef HAVE_OPENSSL_DSA RETERR(dst__openssldsa_init(&dst_t_func[DST_ALG_DSA])); RETERR(dst__openssldsa_init(&dst_t_func[DST_ALG_NSEC3DSA])); #endif RETERR(dst__openssldh_init(&dst_t_func[DST_ALG_DH])); #ifdef HAVE_OPENSSL_GOST RETERR(dst__opensslgost_init(&dst_t_func[DST_ALG_ECCGOST])); #endif #ifdef HAVE_OPENSSL_ECDSA RETERR(dst__opensslecdsa_init(&dst_t_func[DST_ALG_ECDSA256])); RETERR(dst__opensslecdsa_init(&dst_t_func[DST_ALG_ECDSA384])); #endif #elif PKCS11CRYPTO RETERR(dst__pkcs11_init(mctx, engine)); RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSAMD5])); RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSASHA1])); RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_NSEC3RSASHA1])); RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSASHA256])); RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSASHA512])); RETERR(dst__pkcs11dsa_init(&dst_t_func[DST_ALG_DSA])); RETERR(dst__pkcs11dsa_init(&dst_t_func[DST_ALG_NSEC3DSA])); RETERR(dst__pkcs11dh_init(&dst_t_func[DST_ALG_DH])); #ifdef HAVE_PKCS11_ECDSA RETERR(dst__pkcs11ecdsa_init(&dst_t_func[DST_ALG_ECDSA256])); RETERR(dst__pkcs11ecdsa_init(&dst_t_func[DST_ALG_ECDSA384])); #endif #ifdef HAVE_PKCS11_GOST RETERR(dst__pkcs11gost_init(&dst_t_func[DST_ALG_ECCGOST])); #endif #endif /* if OPENSSL, elif PKCS11CRYPTO */ #ifdef GSSAPI RETERR(dst__gssapi_init(&dst_t_func[DST_ALG_GSSAPI])); #endif dst_initialized = ISC_TRUE; return (ISC_R_SUCCESS); out: /* avoid immediate crash! */ dst_initialized = ISC_TRUE; dst_lib_destroy(); return (result); } void dst_lib_destroy(void) { int i; RUNTIME_CHECK(dst_initialized == ISC_TRUE); dst_initialized = ISC_FALSE; for (i = 0; i < DST_MAX_ALGS; i++) if (dst_t_func[i] != NULL && dst_t_func[i]->cleanup != NULL) dst_t_func[i]->cleanup(); #ifdef OPENSSL dst__openssl_destroy(); #elif PKCS11CRYPTO (void) dst__pkcs11_destroy(); #endif /* if OPENSSL, elif PKCS11CRYPTO */ if (dst__memory_pool != NULL) isc_mem_detach(&dst__memory_pool); if (dst_entropy_pool != NULL) isc_entropy_detach(&dst_entropy_pool); } isc_boolean_t dst_algorithm_supported(unsigned int alg) { REQUIRE(dst_initialized == ISC_TRUE); if (alg >= DST_MAX_ALGS || dst_t_func[alg] == NULL) return (ISC_FALSE); return (ISC_TRUE); } isc_boolean_t dst_ds_digest_supported(unsigned int digest_type) { #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) return (ISC_TF(digest_type == DNS_DSDIGEST_SHA1 || digest_type == DNS_DSDIGEST_SHA256 || digest_type == DNS_DSDIGEST_GOST || digest_type == DNS_DSDIGEST_SHA384)); #else return (ISC_TF(digest_type == DNS_DSDIGEST_SHA1 || digest_type == DNS_DSDIGEST_SHA256 || digest_type == DNS_DSDIGEST_SHA384)); #endif } isc_result_t dst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp) { return (dst_context_create4(key, mctx, DNS_LOGCATEGORY_GENERAL, ISC_TRUE, 0, dctxp)); } isc_result_t dst_context_create2(dst_key_t *key, isc_mem_t *mctx, isc_logcategory_t *category, dst_context_t **dctxp) { return (dst_context_create4(key, mctx, category, ISC_TRUE, 0, dctxp)); } isc_result_t dst_context_create3(dst_key_t *key, isc_mem_t *mctx, isc_logcategory_t *category, isc_boolean_t useforsigning, dst_context_t **dctxp) { return (dst_context_create4(key, mctx, category, useforsigning, 0, dctxp)); } isc_result_t dst_context_create4(dst_key_t *key, isc_mem_t *mctx, isc_logcategory_t *category, isc_boolean_t useforsigning, int maxbits, dst_context_t **dctxp) { dst_context_t *dctx; isc_result_t result; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(VALID_KEY(key)); REQUIRE(mctx != NULL); REQUIRE(dctxp != NULL && *dctxp == NULL); if (key->func->createctx == NULL && key->func->createctx2 == NULL) return (DST_R_UNSUPPORTEDALG); if (key->keydata.generic == NULL) return (DST_R_NULLKEY); dctx = isc_mem_get(mctx, sizeof(dst_context_t)); if (dctx == NULL) return (ISC_R_NOMEMORY); dctx->key = key; dctx->mctx = mctx; dctx->category = category; if (useforsigning) dctx->use = DO_SIGN; else dctx->use = DO_VERIFY; if (key->func->createctx2 != NULL) result = key->func->createctx2(key, maxbits, dctx); else result = key->func->createctx(key, dctx); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, dctx, sizeof(dst_context_t)); return (result); } dctx->magic = CTX_MAGIC; *dctxp = dctx; return (ISC_R_SUCCESS); } void dst_context_destroy(dst_context_t **dctxp) { dst_context_t *dctx; REQUIRE(dctxp != NULL && VALID_CTX(*dctxp)); dctx = *dctxp; INSIST(dctx->key->func->destroyctx != NULL); dctx->key->func->destroyctx(dctx); dctx->magic = 0; isc_mem_put(dctx->mctx, dctx, sizeof(dst_context_t)); *dctxp = NULL; } isc_result_t dst_context_adddata(dst_context_t *dctx, const isc_region_t *data) { REQUIRE(VALID_CTX(dctx)); REQUIRE(data != NULL); INSIST(dctx->key->func->adddata != NULL); return (dctx->key->func->adddata(dctx, data)); } isc_result_t dst_context_sign(dst_context_t *dctx, isc_buffer_t *sig) { dst_key_t *key; REQUIRE(VALID_CTX(dctx)); REQUIRE(sig != NULL); key = dctx->key; CHECKALG(key->key_alg); if (key->keydata.generic == NULL) return (DST_R_NULLKEY); if (key->func->sign == NULL) return (DST_R_NOTPRIVATEKEY); if (key->func->isprivate == NULL || key->func->isprivate(key) == ISC_FALSE) return (DST_R_NOTPRIVATEKEY); return (key->func->sign(dctx, sig)); } isc_result_t dst_context_verify(dst_context_t *dctx, isc_region_t *sig) { REQUIRE(VALID_CTX(dctx)); REQUIRE(sig != NULL); CHECKALG(dctx->key->key_alg); if (dctx->key->keydata.generic == NULL) return (DST_R_NULLKEY); if (dctx->key->func->verify == NULL) return (DST_R_NOTPUBLICKEY); return (dctx->key->func->verify(dctx, sig)); } isc_result_t dst_context_verify2(dst_context_t *dctx, unsigned int maxbits, isc_region_t *sig) { REQUIRE(VALID_CTX(dctx)); REQUIRE(sig != NULL); CHECKALG(dctx->key->key_alg); if (dctx->key->keydata.generic == NULL) return (DST_R_NULLKEY); if (dctx->key->func->verify == NULL && dctx->key->func->verify2 == NULL) return (DST_R_NOTPUBLICKEY); return (dctx->key->func->verify2 != NULL ? dctx->key->func->verify2(dctx, maxbits, sig) : dctx->key->func->verify(dctx, sig)); } isc_result_t dst_key_computesecret(const dst_key_t *pub, const dst_key_t *priv, isc_buffer_t *secret) { REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(VALID_KEY(pub) && VALID_KEY(priv)); REQUIRE(secret != NULL); CHECKALG(pub->key_alg); CHECKALG(priv->key_alg); if (pub->keydata.generic == NULL || priv->keydata.generic == NULL) return (DST_R_NULLKEY); if (pub->key_alg != priv->key_alg || pub->func->computesecret == NULL || priv->func->computesecret == NULL) return (DST_R_KEYCANNOTCOMPUTESECRET); if (dst_key_isprivate(priv) == ISC_FALSE) return (DST_R_NOTPRIVATEKEY); return (pub->func->computesecret(pub, priv, secret)); } isc_result_t dst_key_tofile(const dst_key_t *key, int type, const char *directory) { isc_result_t ret = ISC_R_SUCCESS; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(VALID_KEY(key)); REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0); CHECKALG(key->key_alg); if (key->func->tofile == NULL) return (DST_R_UNSUPPORTEDALG); if (type & DST_TYPE_PUBLIC) { ret = write_public_key(key, type, directory); if (ret != ISC_R_SUCCESS) return (ret); } if ((type & DST_TYPE_PRIVATE) && (key->key_flags & DNS_KEYFLAG_TYPEMASK) != DNS_KEYTYPE_NOKEY) return (key->func->tofile(key, directory)); else return (ISC_R_SUCCESS); } void dst_key_setexternal(dst_key_t *key, isc_boolean_t value) { key->external = value; } isc_boolean_t dst_key_isexternal(dst_key_t *key) { return (key->external); } isc_result_t dst_key_fromfile(dns_name_t *name, dns_keytag_t id, unsigned int alg, int type, const char *directory, isc_mem_t *mctx, dst_key_t **keyp) { char filename[ISC_DIR_NAMEMAX]; isc_buffer_t b; dst_key_t *key; isc_result_t result; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(dns_name_isabsolute(name)); REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0); REQUIRE(mctx != NULL); REQUIRE(keyp != NULL && *keyp == NULL); CHECKALG(alg); isc_buffer_init(&b, filename, sizeof(filename)); result = buildfilename(name, id, alg, type, directory, &b); if (result != ISC_R_SUCCESS) return (result); key = NULL; result = dst_key_fromnamedfile(filename, NULL, type, mctx, &key); if (result != ISC_R_SUCCESS) return (result); result = computeid(key); if (result != ISC_R_SUCCESS) { dst_key_free(&key); return (result); } if (!dns_name_equal(name, key->key_name) || id != key->key_id || alg != key->key_alg) { dst_key_free(&key); return (DST_R_INVALIDPRIVATEKEY); } *keyp = key; return (ISC_R_SUCCESS); } isc_result_t dst_key_fromnamedfile(const char *filename, const char *dirname, int type, isc_mem_t *mctx, dst_key_t **keyp) { isc_result_t result; dst_key_t *pubkey = NULL, *key = NULL; char *newfilename = NULL; int newfilenamelen = 0; isc_lex_t *lex = NULL; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(filename != NULL); REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0); REQUIRE(mctx != NULL); REQUIRE(keyp != NULL && *keyp == NULL); /* If an absolute path is specified, don't use the key directory */ #ifndef WIN32 if (filename[0] == '/') dirname = NULL; #else /* WIN32 */ if (filename[0] == '/' || filename[0] == '\\') dirname = NULL; #endif newfilenamelen = strlen(filename) + 5; if (dirname != NULL) newfilenamelen += strlen(dirname) + 1; newfilename = isc_mem_get(mctx, newfilenamelen); if (newfilename == NULL) return (ISC_R_NOMEMORY); result = addsuffix(newfilename, newfilenamelen, dirname, filename, ".key"); INSIST(result == ISC_R_SUCCESS); result = dst_key_read_public(newfilename, type, mctx, &pubkey); isc_mem_put(mctx, newfilename, newfilenamelen); newfilename = NULL; RETERR(result); if ((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) == DST_TYPE_PUBLIC || (pubkey->key_flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) { result = computeid(pubkey); if (result != ISC_R_SUCCESS) { dst_key_free(&pubkey); return (result); } *keyp = pubkey; return (ISC_R_SUCCESS); } result = algorithm_status(pubkey->key_alg); if (result != ISC_R_SUCCESS) { dst_key_free(&pubkey); return (result); } key = get_key_struct(pubkey->key_name, pubkey->key_alg, pubkey->key_flags, pubkey->key_proto, 0, pubkey->key_class, pubkey->key_ttl, mctx); if (key == NULL) { dst_key_free(&pubkey); return (ISC_R_NOMEMORY); } if (key->func->parse == NULL) RETERR(DST_R_UNSUPPORTEDALG); newfilenamelen = strlen(filename) + 9; if (dirname != NULL) newfilenamelen += strlen(dirname) + 1; newfilename = isc_mem_get(mctx, newfilenamelen); if (newfilename == NULL) RETERR(ISC_R_NOMEMORY); result = addsuffix(newfilename, newfilenamelen, dirname, filename, ".private"); INSIST(result == ISC_R_SUCCESS); RETERR(isc_lex_create(mctx, 1500, &lex)); RETERR(isc_lex_openfile(lex, newfilename)); isc_mem_put(mctx, newfilename, newfilenamelen); RETERR(key->func->parse(key, lex, pubkey)); isc_lex_destroy(&lex); RETERR(computeid(key)); if (pubkey->key_id != key->key_id) RETERR(DST_R_INVALIDPRIVATEKEY); dst_key_free(&pubkey); *keyp = key; return (ISC_R_SUCCESS); out: if (pubkey != NULL) dst_key_free(&pubkey); if (newfilename != NULL) isc_mem_put(mctx, newfilename, newfilenamelen); if (lex != NULL) isc_lex_destroy(&lex); if (key != NULL) dst_key_free(&key); return (result); } isc_result_t dst_key_todns(const dst_key_t *key, isc_buffer_t *target) { REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(VALID_KEY(key)); REQUIRE(target != NULL); CHECKALG(key->key_alg); if (key->func->todns == NULL) return (DST_R_UNSUPPORTEDALG); if (isc_buffer_availablelength(target) < 4) return (ISC_R_NOSPACE); isc_buffer_putuint16(target, (isc_uint16_t)(key->key_flags & 0xffff)); isc_buffer_putuint8(target, (isc_uint8_t)key->key_proto); isc_buffer_putuint8(target, (isc_uint8_t)key->key_alg); if (key->key_flags & DNS_KEYFLAG_EXTENDED) { if (isc_buffer_availablelength(target) < 2) return (ISC_R_NOSPACE); isc_buffer_putuint16(target, (isc_uint16_t)((key->key_flags >> 16) & 0xffff)); } if (key->keydata.generic == NULL) /*%< NULL KEY */ return (ISC_R_SUCCESS); return (key->func->todns(key, target)); } isc_result_t dst_key_fromdns(dns_name_t *name, dns_rdataclass_t rdclass, isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp) { isc_uint8_t alg, proto; isc_uint32_t flags, extflags; dst_key_t *key = NULL; dns_keytag_t id, rid; isc_region_t r; isc_result_t result; REQUIRE(dst_initialized); isc_buffer_remainingregion(source, &r); if (isc_buffer_remaininglength(source) < 4) return (DST_R_INVALIDPUBLICKEY); flags = isc_buffer_getuint16(source); proto = isc_buffer_getuint8(source); alg = isc_buffer_getuint8(source); id = dst_region_computeid(&r, alg); rid = dst_region_computerid(&r, alg); if (flags & DNS_KEYFLAG_EXTENDED) { if (isc_buffer_remaininglength(source) < 2) return (DST_R_INVALIDPUBLICKEY); extflags = isc_buffer_getuint16(source); flags |= (extflags << 16); } result = frombuffer(name, alg, flags, proto, rdclass, source, mctx, &key); if (result != ISC_R_SUCCESS) return (result); key->key_id = id; key->key_rid = rid; *keyp = key; return (ISC_R_SUCCESS); } isc_result_t dst_key_frombuffer(dns_name_t *name, unsigned int alg, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp) { dst_key_t *key = NULL; isc_result_t result; REQUIRE(dst_initialized); result = frombuffer(name, alg, flags, protocol, rdclass, source, mctx, &key); if (result != ISC_R_SUCCESS) return (result); result = computeid(key); if (result != ISC_R_SUCCESS) { dst_key_free(&key); return (result); } *keyp = key; return (ISC_R_SUCCESS); } isc_result_t dst_key_tobuffer(const dst_key_t *key, isc_buffer_t *target) { REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(VALID_KEY(key)); REQUIRE(target != NULL); CHECKALG(key->key_alg); if (key->func->todns == NULL) return (DST_R_UNSUPPORTEDALG); return (key->func->todns(key, target)); } isc_result_t dst_key_privatefrombuffer(dst_key_t *key, isc_buffer_t *buffer) { isc_lex_t *lex = NULL; isc_result_t result = ISC_R_SUCCESS; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(VALID_KEY(key)); REQUIRE(!dst_key_isprivate(key)); REQUIRE(buffer != NULL); if (key->func->parse == NULL) RETERR(DST_R_UNSUPPORTEDALG); RETERR(isc_lex_create(key->mctx, 1500, &lex)); RETERR(isc_lex_openbuffer(lex, buffer)); RETERR(key->func->parse(key, lex, NULL)); out: if (lex != NULL) isc_lex_destroy(&lex); return (result); } gss_ctx_id_t dst_key_getgssctx(const dst_key_t *key) { REQUIRE(key != NULL); return (key->keydata.gssctx); } isc_result_t dst_key_fromgssapi(dns_name_t *name, gss_ctx_id_t gssctx, isc_mem_t *mctx, dst_key_t **keyp, isc_region_t *intoken) { dst_key_t *key; isc_result_t result; REQUIRE(gssctx != NULL); REQUIRE(keyp != NULL && *keyp == NULL); key = get_key_struct(name, DST_ALG_GSSAPI, 0, DNS_KEYPROTO_DNSSEC, 0, dns_rdataclass_in, 0, mctx); if (key == NULL) return (ISC_R_NOMEMORY); if (intoken != NULL) { /* * Keep the token for use by external ssu rules. They may need * to examine the PAC in the kerberos ticket. */ RETERR(isc_buffer_allocate(key->mctx, &key->key_tkeytoken, intoken->length)); RETERR(isc_buffer_copyregion(key->key_tkeytoken, intoken)); } key->keydata.gssctx = gssctx; *keyp = key; result = ISC_R_SUCCESS; out: return result; } isc_result_t dst_key_buildinternal(dns_name_t *name, unsigned int alg, unsigned int bits, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, void *data, isc_mem_t *mctx, dst_key_t **keyp) { dst_key_t *key; isc_result_t result; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(dns_name_isabsolute(name)); REQUIRE(mctx != NULL); REQUIRE(keyp != NULL && *keyp == NULL); REQUIRE(data != NULL); CHECKALG(alg); key = get_key_struct(name, alg, flags, protocol, bits, rdclass, 0, mctx); if (key == NULL) return (ISC_R_NOMEMORY); key->keydata.generic = data; result = computeid(key); if (result != ISC_R_SUCCESS) { dst_key_free(&key); return (result); } *keyp = key; return (ISC_R_SUCCESS); } isc_result_t dst_key_fromlabel(dns_name_t *name, int alg, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, const char *engine, const char *label, const char *pin, isc_mem_t *mctx, dst_key_t **keyp) { dst_key_t *key; isc_result_t result; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(dns_name_isabsolute(name)); REQUIRE(mctx != NULL); REQUIRE(keyp != NULL && *keyp == NULL); REQUIRE(label != NULL); CHECKALG(alg); key = get_key_struct(name, alg, flags, protocol, 0, rdclass, 0, mctx); if (key == NULL) return (ISC_R_NOMEMORY); if (key->func->fromlabel == NULL) { dst_key_free(&key); return (DST_R_UNSUPPORTEDALG); } result = key->func->fromlabel(key, engine, label, pin); if (result != ISC_R_SUCCESS) { dst_key_free(&key); return (result); } result = computeid(key); if (result != ISC_R_SUCCESS) { dst_key_free(&key); return (result); } *keyp = key; return (ISC_R_SUCCESS); } isc_result_t dst_key_generate(dns_name_t *name, unsigned int alg, unsigned int bits, unsigned int param, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, isc_mem_t *mctx, dst_key_t **keyp) { return (dst_key_generate2(name, alg, bits, param, flags, protocol, rdclass, mctx, keyp, NULL)); } isc_result_t dst_key_generate2(dns_name_t *name, unsigned int alg, unsigned int bits, unsigned int param, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, isc_mem_t *mctx, dst_key_t **keyp, void (*callback)(int)) { dst_key_t *key; isc_result_t ret; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(dns_name_isabsolute(name)); REQUIRE(mctx != NULL); REQUIRE(keyp != NULL && *keyp == NULL); CHECKALG(alg); key = get_key_struct(name, alg, flags, protocol, bits, rdclass, 0, mctx); if (key == NULL) return (ISC_R_NOMEMORY); if (bits == 0) { /*%< NULL KEY */ key->key_flags |= DNS_KEYTYPE_NOKEY; *keyp = key; return (ISC_R_SUCCESS); } if (key->func->generate == NULL) { dst_key_free(&key); return (DST_R_UNSUPPORTEDALG); } ret = key->func->generate(key, param, callback); if (ret != ISC_R_SUCCESS) { dst_key_free(&key); return (ret); } ret = computeid(key); if (ret != ISC_R_SUCCESS) { dst_key_free(&key); return (ret); } *keyp = key; return (ISC_R_SUCCESS); } isc_result_t dst_key_getnum(const dst_key_t *key, int type, isc_uint32_t *valuep) { REQUIRE(VALID_KEY(key)); REQUIRE(valuep != NULL); REQUIRE(type <= DST_MAX_NUMERIC); if (!key->numset[type]) return (ISC_R_NOTFOUND); *valuep = key->nums[type]; return (ISC_R_SUCCESS); } void dst_key_setnum(dst_key_t *key, int type, isc_uint32_t value) { REQUIRE(VALID_KEY(key)); REQUIRE(type <= DST_MAX_NUMERIC); key->nums[type] = value; key->numset[type] = ISC_TRUE; } void dst_key_unsetnum(dst_key_t *key, int type) { REQUIRE(VALID_KEY(key)); REQUIRE(type <= DST_MAX_NUMERIC); key->numset[type] = ISC_FALSE; } isc_result_t dst_key_gettime(const dst_key_t *key, int type, isc_stdtime_t *timep) { REQUIRE(VALID_KEY(key)); REQUIRE(timep != NULL); REQUIRE(type <= DST_MAX_TIMES); if (!key->timeset[type]) return (ISC_R_NOTFOUND); *timep = key->times[type]; return (ISC_R_SUCCESS); } void dst_key_settime(dst_key_t *key, int type, isc_stdtime_t when) { REQUIRE(VALID_KEY(key)); REQUIRE(type <= DST_MAX_TIMES); key->times[type] = when; key->timeset[type] = ISC_TRUE; } void dst_key_unsettime(dst_key_t *key, int type) { REQUIRE(VALID_KEY(key)); REQUIRE(type <= DST_MAX_TIMES); key->timeset[type] = ISC_FALSE; } isc_result_t dst_key_getprivateformat(const dst_key_t *key, int *majorp, int *minorp) { REQUIRE(VALID_KEY(key)); REQUIRE(majorp != NULL); REQUIRE(minorp != NULL); *majorp = key->fmt_major; *minorp = key->fmt_minor; return (ISC_R_SUCCESS); } void dst_key_setprivateformat(dst_key_t *key, int major, int minor) { REQUIRE(VALID_KEY(key)); key->fmt_major = major; key->fmt_minor = minor; } static isc_boolean_t comparekeys(const dst_key_t *key1, const dst_key_t *key2, isc_boolean_t match_revoked_key, isc_boolean_t (*compare)(const dst_key_t *key1, const dst_key_t *key2)) { REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(VALID_KEY(key1)); REQUIRE(VALID_KEY(key2)); if (key1 == key2) return (ISC_TRUE); if (key1->key_alg != key2->key_alg) return (ISC_FALSE); if (key1->key_id != key2->key_id) { if (!match_revoked_key) return (ISC_FALSE); if (key1->key_alg == DST_ALG_RSAMD5) return (ISC_FALSE); if ((key1->key_flags & DNS_KEYFLAG_REVOKE) == (key2->key_flags & DNS_KEYFLAG_REVOKE)) return (ISC_FALSE); if (key1->key_id != key2->key_rid && key1->key_rid != key2->key_id) return (ISC_FALSE); } if (compare != NULL) return (compare(key1, key2)); else return (ISC_FALSE); } /* * Compares only the public portion of two keys, by converting them * both to wire format and comparing the results. */ static isc_boolean_t pub_compare(const dst_key_t *key1, const dst_key_t *key2) { isc_result_t result; unsigned char buf1[DST_KEY_MAXSIZE], buf2[DST_KEY_MAXSIZE]; isc_buffer_t b1, b2; isc_region_t r1, r2; isc_buffer_init(&b1, buf1, sizeof(buf1)); result = dst_key_todns(key1, &b1); if (result != ISC_R_SUCCESS) return (ISC_FALSE); /* Zero out flags. */ buf1[0] = buf1[1] = 0; if ((key1->key_flags & DNS_KEYFLAG_EXTENDED) != 0) isc_buffer_subtract(&b1, 2); isc_buffer_init(&b2, buf2, sizeof(buf2)); result = dst_key_todns(key2, &b2); if (result != ISC_R_SUCCESS) return (ISC_FALSE); /* Zero out flags. */ buf2[0] = buf2[1] = 0; if ((key2->key_flags & DNS_KEYFLAG_EXTENDED) != 0) isc_buffer_subtract(&b2, 2); isc_buffer_usedregion(&b1, &r1); /* Remove extended flags. */ if ((key1->key_flags & DNS_KEYFLAG_EXTENDED) != 0) { memmove(&buf1[4], &buf1[6], r1.length - 6); r1.length -= 2; } isc_buffer_usedregion(&b2, &r2); /* Remove extended flags. */ if ((key2->key_flags & DNS_KEYFLAG_EXTENDED) != 0) { memmove(&buf2[4], &buf2[6], r2.length - 6); r2.length -= 2; } return (ISC_TF(isc_region_compare(&r1, &r2) == 0)); } isc_boolean_t dst_key_compare(const dst_key_t *key1, const dst_key_t *key2) { return (comparekeys(key1, key2, ISC_FALSE, key1->func->compare)); } isc_boolean_t dst_key_pubcompare(const dst_key_t *key1, const dst_key_t *key2, isc_boolean_t match_revoked_key) { return (comparekeys(key1, key2, match_revoked_key, pub_compare)); } isc_boolean_t dst_key_paramcompare(const dst_key_t *key1, const dst_key_t *key2) { REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(VALID_KEY(key1)); REQUIRE(VALID_KEY(key2)); if (key1 == key2) return (ISC_TRUE); if (key1->key_alg == key2->key_alg && key1->func->paramcompare != NULL && key1->func->paramcompare(key1, key2) == ISC_TRUE) return (ISC_TRUE); else return (ISC_FALSE); } void dst_key_attach(dst_key_t *source, dst_key_t **target) { REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(target != NULL && *target == NULL); REQUIRE(VALID_KEY(source)); isc_refcount_increment(&source->refs, NULL); *target = source; } void dst_key_free(dst_key_t **keyp) { isc_mem_t *mctx; dst_key_t *key; unsigned int refs; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(keyp != NULL && VALID_KEY(*keyp)); key = *keyp; mctx = key->mctx; isc_refcount_decrement(&key->refs, &refs); if (refs != 0) return; isc_refcount_destroy(&key->refs); if (key->keydata.generic != NULL) { INSIST(key->func->destroy != NULL); key->func->destroy(key); } if (key->engine != NULL) isc_mem_free(mctx, key->engine); if (key->label != NULL) isc_mem_free(mctx, key->label); dns_name_free(key->key_name, mctx); isc_mem_put(mctx, key->key_name, sizeof(dns_name_t)); if (key->key_tkeytoken) { isc_buffer_free(&key->key_tkeytoken); } memset(key, 0, sizeof(dst_key_t)); isc_mem_putanddetach(&mctx, key, sizeof(dst_key_t)); *keyp = NULL; } isc_boolean_t dst_key_isprivate(const dst_key_t *key) { REQUIRE(VALID_KEY(key)); INSIST(key->func->isprivate != NULL); return (key->func->isprivate(key)); } isc_result_t dst_key_buildfilename(const dst_key_t *key, int type, const char *directory, isc_buffer_t *out) { REQUIRE(VALID_KEY(key)); REQUIRE(type == DST_TYPE_PRIVATE || type == DST_TYPE_PUBLIC || type == 0); return (buildfilename(key->key_name, key->key_id, key->key_alg, type, directory, out)); } isc_result_t dst_key_sigsize(const dst_key_t *key, unsigned int *n) { REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(VALID_KEY(key)); REQUIRE(n != NULL); /* XXXVIX this switch statement is too sparse to gen a jump table. */ switch (key->key_alg) { case DST_ALG_RSAMD5: case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: case DST_ALG_RSASHA256: case DST_ALG_RSASHA512: *n = (key->key_size + 7) / 8; break; case DST_ALG_DSA: case DST_ALG_NSEC3DSA: *n = DNS_SIG_DSASIGSIZE; break; case DST_ALG_ECCGOST: *n = DNS_SIG_GOSTSIGSIZE; break; case DST_ALG_ECDSA256: *n = DNS_SIG_ECDSA256SIZE; break; case DST_ALG_ECDSA384: *n = DNS_SIG_ECDSA384SIZE; break; case DST_ALG_HMACMD5: *n = 16; break; case DST_ALG_HMACSHA1: *n = ISC_SHA1_DIGESTLENGTH; break; case DST_ALG_HMACSHA224: *n = ISC_SHA224_DIGESTLENGTH; break; case DST_ALG_HMACSHA256: *n = ISC_SHA256_DIGESTLENGTH; break; case DST_ALG_HMACSHA384: *n = ISC_SHA384_DIGESTLENGTH; break; case DST_ALG_HMACSHA512: *n = ISC_SHA512_DIGESTLENGTH; break; case DST_ALG_GSSAPI: *n = 128; /*%< XXX */ break; case DST_ALG_DH: default: return (DST_R_UNSUPPORTEDALG); } return (ISC_R_SUCCESS); } isc_result_t dst_key_secretsize(const dst_key_t *key, unsigned int *n) { REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(VALID_KEY(key)); REQUIRE(n != NULL); if (key->key_alg == DST_ALG_DH) *n = (key->key_size + 7) / 8; else return (DST_R_UNSUPPORTEDALG); return (ISC_R_SUCCESS); } /*% * Set the flags on a key, then recompute the key ID */ isc_result_t dst_key_setflags(dst_key_t *key, isc_uint32_t flags) { REQUIRE(VALID_KEY(key)); key->key_flags = flags; return (computeid(key)); } void dst_key_format(const dst_key_t *key, char *cp, unsigned int size) { char namestr[DNS_NAME_FORMATSIZE]; char algstr[DNS_NAME_FORMATSIZE]; dns_name_format(dst_key_name(key), namestr, sizeof(namestr)); dns_secalg_format((dns_secalg_t) dst_key_alg(key), algstr, sizeof(algstr)); snprintf(cp, size, "%s/%s/%d", namestr, algstr, dst_key_id(key)); } isc_result_t dst_key_dump(dst_key_t *key, isc_mem_t *mctx, char **buffer, int *length) { REQUIRE(buffer != NULL && *buffer == NULL); REQUIRE(length != NULL && *length == 0); REQUIRE(VALID_KEY(key)); if (key->func->dump == NULL) return (ISC_R_NOTIMPLEMENTED); return (key->func->dump(key, mctx, buffer, length)); } isc_result_t dst_key_restore(dns_name_t *name, unsigned int alg, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, isc_mem_t *mctx, const char *keystr, dst_key_t **keyp) { isc_result_t result; dst_key_t *key; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(keyp != NULL && *keyp == NULL); if (alg >= DST_MAX_ALGS || dst_t_func[alg] == NULL) return (DST_R_UNSUPPORTEDALG); if (dst_t_func[alg]->restore == NULL) return (ISC_R_NOTIMPLEMENTED); key = get_key_struct(name, alg, flags, protocol, 0, rdclass, 0, mctx); if (key == NULL) return (ISC_R_NOMEMORY); result = (dst_t_func[alg]->restore)(key, keystr); if (result == ISC_R_SUCCESS) *keyp = key; else dst_key_free(&key); return (result); } /*** *** Static methods ***/ /*% * Allocates a key structure and fills in some of the fields. */ static dst_key_t * get_key_struct(dns_name_t *name, unsigned int alg, unsigned int flags, unsigned int protocol, unsigned int bits, dns_rdataclass_t rdclass, dns_ttl_t ttl, isc_mem_t *mctx) { dst_key_t *key; isc_result_t result; int i; key = (dst_key_t *) isc_mem_get(mctx, sizeof(dst_key_t)); if (key == NULL) return (NULL); memset(key, 0, sizeof(dst_key_t)); key->key_name = isc_mem_get(mctx, sizeof(dns_name_t)); if (key->key_name == NULL) { isc_mem_put(mctx, key, sizeof(dst_key_t)); return (NULL); } dns_name_init(key->key_name, NULL); result = dns_name_dup(name, mctx, key->key_name); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, key->key_name, sizeof(dns_name_t)); isc_mem_put(mctx, key, sizeof(dst_key_t)); return (NULL); } result = isc_refcount_init(&key->refs, 1); if (result != ISC_R_SUCCESS) { dns_name_free(key->key_name, mctx); isc_mem_put(mctx, key->key_name, sizeof(dns_name_t)); isc_mem_put(mctx, key, sizeof(dst_key_t)); return (NULL); } isc_mem_attach(mctx, &key->mctx); key->key_alg = alg; key->key_flags = flags; key->key_proto = protocol; key->keydata.generic = NULL; key->key_size = bits; key->key_class = rdclass; key->key_ttl = ttl; key->func = dst_t_func[alg]; key->fmt_major = 0; key->fmt_minor = 0; for (i = 0; i < (DST_MAX_TIMES + 1); i++) { key->times[i] = 0; key->timeset[i] = ISC_FALSE; } key->inactive = ISC_FALSE; key->magic = KEY_MAGIC; return (key); } isc_boolean_t dst_key_inactive(const dst_key_t *key) { REQUIRE(VALID_KEY(key)); return (key->inactive); } void dst_key_setinactive(dst_key_t *key, isc_boolean_t inactive) { REQUIRE(VALID_KEY(key)); key->inactive = inactive; } /*% * Reads a public key from disk */ isc_result_t dst_key_read_public(const char *filename, int type, isc_mem_t *mctx, dst_key_t **keyp) { u_char rdatabuf[DST_KEY_MAXSIZE]; isc_buffer_t b; dns_fixedname_t name; isc_lex_t *lex = NULL; isc_token_t token; isc_result_t ret; dns_rdata_t rdata = DNS_RDATA_INIT; unsigned int opt = ISC_LEXOPT_DNSMULTILINE; dns_rdataclass_t rdclass = dns_rdataclass_in; isc_lexspecials_t specials; isc_uint32_t ttl = 0; isc_result_t result; dns_rdatatype_t keytype; /* * Open the file and read its formatted contents * File format: * domain.name [ttl] [class] [KEY|DNSKEY] */ /* 1500 should be large enough for any key */ ret = isc_lex_create(mctx, 1500, &lex); if (ret != ISC_R_SUCCESS) goto cleanup; memset(specials, 0, sizeof(specials)); specials['('] = 1; specials[')'] = 1; specials['"'] = 1; isc_lex_setspecials(lex, specials); isc_lex_setcomments(lex, ISC_LEXCOMMENT_DNSMASTERFILE); ret = isc_lex_openfile(lex, filename); if (ret != ISC_R_SUCCESS) goto cleanup; #define NEXTTOKEN(lex, opt, token) { \ ret = isc_lex_gettoken(lex, opt, token); \ if (ret != ISC_R_SUCCESS) \ goto cleanup; \ } #define BADTOKEN() { \ ret = ISC_R_UNEXPECTEDTOKEN; \ goto cleanup; \ } /* Read the domain name */ NEXTTOKEN(lex, opt, &token); if (token.type != isc_tokentype_string) BADTOKEN(); /* * We don't support "@" in .key files. */ if (!strcmp(DST_AS_STR(token), "@")) BADTOKEN(); dns_fixedname_init(&name); isc_buffer_init(&b, DST_AS_STR(token), strlen(DST_AS_STR(token))); isc_buffer_add(&b, strlen(DST_AS_STR(token))); ret = dns_name_fromtext(dns_fixedname_name(&name), &b, dns_rootname, 0, NULL); if (ret != ISC_R_SUCCESS) goto cleanup; /* Read the next word: either TTL, class, or 'KEY' */ NEXTTOKEN(lex, opt, &token); if (token.type != isc_tokentype_string) BADTOKEN(); /* If it's a TTL, read the next one */ result = dns_ttl_fromtext(&token.value.as_textregion, &ttl); if (result == ISC_R_SUCCESS) NEXTTOKEN(lex, opt, &token); if (token.type != isc_tokentype_string) BADTOKEN(); ret = dns_rdataclass_fromtext(&rdclass, &token.value.as_textregion); if (ret == ISC_R_SUCCESS) NEXTTOKEN(lex, opt, &token); if (token.type != isc_tokentype_string) BADTOKEN(); if (strcasecmp(DST_AS_STR(token), "DNSKEY") == 0) keytype = dns_rdatatype_dnskey; else if (strcasecmp(DST_AS_STR(token), "KEY") == 0) keytype = dns_rdatatype_key; /*%< SIG(0), TKEY */ else BADTOKEN(); if (((type & DST_TYPE_KEY) != 0 && keytype != dns_rdatatype_key) || ((type & DST_TYPE_KEY) == 0 && keytype != dns_rdatatype_dnskey)) { ret = DST_R_BADKEYTYPE; goto cleanup; } isc_buffer_init(&b, rdatabuf, sizeof(rdatabuf)); ret = dns_rdata_fromtext(&rdata, rdclass, keytype, lex, NULL, ISC_FALSE, mctx, &b, NULL); if (ret != ISC_R_SUCCESS) goto cleanup; ret = dst_key_fromdns(dns_fixedname_name(&name), rdclass, &b, mctx, keyp); if (ret != ISC_R_SUCCESS) goto cleanup; dst_key_setttl(*keyp, ttl); cleanup: if (lex != NULL) isc_lex_destroy(&lex); return (ret); } static isc_boolean_t issymmetric(const dst_key_t *key) { REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(VALID_KEY(key)); /* XXXVIX this switch statement is too sparse to gen a jump table. */ switch (key->key_alg) { case DST_ALG_RSAMD5: case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: case DST_ALG_RSASHA256: case DST_ALG_RSASHA512: case DST_ALG_DSA: case DST_ALG_NSEC3DSA: case DST_ALG_DH: case DST_ALG_ECCGOST: case DST_ALG_ECDSA256: case DST_ALG_ECDSA384: return (ISC_FALSE); case DST_ALG_HMACMD5: case DST_ALG_GSSAPI: return (ISC_TRUE); default: return (ISC_FALSE); } } /*% * Write key timing metadata to a file pointer, preceded by 'tag' */ static void printtime(const dst_key_t *key, int type, const char *tag, FILE *stream) { isc_result_t result; #ifdef ISC_PLATFORM_USETHREADS char output[26]; /* Minimum buffer as per ctime_r() specification. */ #else const char *output; #endif isc_stdtime_t when; time_t t; char utc[sizeof("YYYYMMDDHHSSMM")]; isc_buffer_t b; isc_region_t r; result = dst_key_gettime(key, type, &when); if (result == ISC_R_NOTFOUND) return; /* time_t and isc_stdtime_t might be different sizes */ t = when; #ifdef ISC_PLATFORM_USETHREADS #ifdef WIN32 if (ctime_s(output, sizeof(output), &t) != 0) goto error; #else if (ctime_r(&t, output) == NULL) goto error; #endif #else output = ctime(&t); #endif isc_buffer_init(&b, utc, sizeof(utc)); result = dns_time32_totext(when, &b); if (result != ISC_R_SUCCESS) goto error; isc_buffer_usedregion(&b, &r); fprintf(stream, "%s: %.*s (%.*s)\n", tag, (int)r.length, r.base, (int)strlen(output) - 1, output); return; error: fprintf(stream, "%s: (set, unable to display)\n", tag); } /*% * Writes a public key to disk in DNS format. */ static isc_result_t write_public_key(const dst_key_t *key, int type, const char *directory) { FILE *fp; isc_buffer_t keyb, textb, fileb, classb; isc_region_t r; char filename[ISC_DIR_NAMEMAX]; unsigned char key_array[DST_KEY_MAXSIZE]; char text_array[DST_KEY_MAXTEXTSIZE]; char class_array[10]; isc_result_t ret; dns_rdata_t rdata = DNS_RDATA_INIT; isc_fsaccess_t access; REQUIRE(VALID_KEY(key)); isc_buffer_init(&keyb, key_array, sizeof(key_array)); isc_buffer_init(&textb, text_array, sizeof(text_array)); isc_buffer_init(&classb, class_array, sizeof(class_array)); ret = dst_key_todns(key, &keyb); if (ret != ISC_R_SUCCESS) return (ret); isc_buffer_usedregion(&keyb, &r); dns_rdata_fromregion(&rdata, key->key_class, dns_rdatatype_dnskey, &r); ret = dns_rdata_totext(&rdata, (dns_name_t *) NULL, &textb); if (ret != ISC_R_SUCCESS) return (DST_R_INVALIDPUBLICKEY); ret = dns_rdataclass_totext(key->key_class, &classb); if (ret != ISC_R_SUCCESS) return (DST_R_INVALIDPUBLICKEY); /* * Make the filename. */ isc_buffer_init(&fileb, filename, sizeof(filename)); ret = dst_key_buildfilename(key, DST_TYPE_PUBLIC, directory, &fileb); if (ret != ISC_R_SUCCESS) return (ret); /* * Create public key file. */ if ((fp = fopen(filename, "w")) == NULL) return (DST_R_WRITEERROR); if (issymmetric(key)) { access = 0; isc_fsaccess_add(ISC_FSACCESS_OWNER, ISC_FSACCESS_READ | ISC_FSACCESS_WRITE, &access); (void)isc_fsaccess_set(filename, access); } /* Write key information in comments */ if ((type & DST_TYPE_KEY) == 0) { fprintf(fp, "; This is a %s%s-signing key, keyid %d, for ", (key->key_flags & DNS_KEYFLAG_REVOKE) != 0 ? "revoked " : "", (key->key_flags & DNS_KEYFLAG_KSK) != 0 ? "key" : "zone", key->key_id); ret = dns_name_print(key->key_name, fp); if (ret != ISC_R_SUCCESS) { fclose(fp); return (ret); } fputc('\n', fp); printtime(key, DST_TIME_CREATED, "; Created", fp); printtime(key, DST_TIME_PUBLISH, "; Publish", fp); printtime(key, DST_TIME_ACTIVATE, "; Activate", fp); printtime(key, DST_TIME_REVOKE, "; Revoke", fp); printtime(key, DST_TIME_INACTIVE, "; Inactive", fp); printtime(key, DST_TIME_DELETE, "; Delete", fp); } /* Now print the actual key */ ret = dns_name_print(key->key_name, fp); fprintf(fp, " "); if (key->key_ttl != 0) fprintf(fp, "%d ", key->key_ttl); isc_buffer_usedregion(&classb, &r); if ((unsigned) fwrite(r.base, 1, r.length, fp) != r.length) ret = DST_R_WRITEERROR; if ((type & DST_TYPE_KEY) != 0) fprintf(fp, " KEY "); else fprintf(fp, " DNSKEY "); isc_buffer_usedregion(&textb, &r); if ((unsigned) fwrite(r.base, 1, r.length, fp) != r.length) ret = DST_R_WRITEERROR; fputc('\n', fp); fflush(fp); if (ferror(fp)) ret = DST_R_WRITEERROR; fclose(fp); return (ret); } static isc_result_t buildfilename(dns_name_t *name, dns_keytag_t id, unsigned int alg, unsigned int type, const char *directory, isc_buffer_t *out) { const char *suffix = ""; unsigned int len; isc_result_t result; REQUIRE(out != NULL); if ((type & DST_TYPE_PRIVATE) != 0) suffix = ".private"; else if (type == DST_TYPE_PUBLIC) suffix = ".key"; if (directory != NULL) { if (isc_buffer_availablelength(out) < strlen(directory)) return (ISC_R_NOSPACE); isc_buffer_putstr(out, directory); if (strlen(directory) > 0U && directory[strlen(directory) - 1] != '/') isc_buffer_putstr(out, "/"); } if (isc_buffer_availablelength(out) < 1) return (ISC_R_NOSPACE); isc_buffer_putstr(out, "K"); result = dns_name_tofilenametext(name, ISC_FALSE, out); if (result != ISC_R_SUCCESS) return (result); len = 1 + 3 + 1 + 5 + strlen(suffix) + 1; if (isc_buffer_availablelength(out) < len) return (ISC_R_NOSPACE); sprintf((char *) isc_buffer_used(out), "+%03d+%05d%s", alg, id, suffix); isc_buffer_add(out, len); return (ISC_R_SUCCESS); } static isc_result_t computeid(dst_key_t *key) { isc_buffer_t dnsbuf; unsigned char dns_array[DST_KEY_MAXSIZE]; isc_region_t r; isc_result_t ret; isc_buffer_init(&dnsbuf, dns_array, sizeof(dns_array)); ret = dst_key_todns(key, &dnsbuf); if (ret != ISC_R_SUCCESS) return (ret); isc_buffer_usedregion(&dnsbuf, &r); key->key_id = dst_region_computeid(&r, key->key_alg); key->key_rid = dst_region_computerid(&r, key->key_alg); return (ISC_R_SUCCESS); } static isc_result_t frombuffer(dns_name_t *name, unsigned int alg, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp) { dst_key_t *key; isc_result_t ret; REQUIRE(dns_name_isabsolute(name)); REQUIRE(source != NULL); REQUIRE(mctx != NULL); REQUIRE(keyp != NULL && *keyp == NULL); key = get_key_struct(name, alg, flags, protocol, 0, rdclass, 0, mctx); if (key == NULL) return (ISC_R_NOMEMORY); if (isc_buffer_remaininglength(source) > 0) { ret = algorithm_status(alg); if (ret != ISC_R_SUCCESS) { dst_key_free(&key); return (ret); } if (key->func->fromdns == NULL) { dst_key_free(&key); return (DST_R_UNSUPPORTEDALG); } ret = key->func->fromdns(key, source); if (ret != ISC_R_SUCCESS) { dst_key_free(&key); return (ret); } } *keyp = key; return (ISC_R_SUCCESS); } static isc_result_t algorithm_status(unsigned int alg) { REQUIRE(dst_initialized == ISC_TRUE); if (dst_algorithm_supported(alg)) return (ISC_R_SUCCESS); #if !defined(OPENSSL) && !defined(PKCS11CRYPTO) if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 || alg == DST_ALG_DSA || alg == DST_ALG_DH || alg == DST_ALG_HMACMD5 || alg == DST_ALG_NSEC3DSA || alg == DST_ALG_NSEC3RSASHA1 || alg == DST_ALG_RSASHA256 || alg == DST_ALG_RSASHA512 || alg == DST_ALG_ECCGOST || alg == DST_ALG_ECDSA256 || alg == DST_ALG_ECDSA384) return (DST_R_NOCRYPTO); #endif return (DST_R_UNSUPPORTEDALG); } static isc_result_t addsuffix(char *filename, int len, const char *odirname, const char *ofilename, const char *suffix) { int olen = strlen(ofilename); int n; if (olen > 1 && ofilename[olen - 1] == '.') olen -= 1; else if (olen > 8 && strcmp(ofilename + olen - 8, ".private") == 0) olen -= 8; else if (olen > 4 && strcmp(ofilename + olen - 4, ".key") == 0) olen -= 4; if (odirname == NULL) n = snprintf(filename, len, "%.*s%s", olen, ofilename, suffix); else n = snprintf(filename, len, "%s/%.*s%s", odirname, olen, ofilename, suffix); if (n < 0) return (ISC_R_FAILURE); if (n >= len) return (ISC_R_NOSPACE); return (ISC_R_SUCCESS); } isc_result_t dst__entropy_getdata(void *buf, unsigned int len, isc_boolean_t pseudo) { unsigned int flags = dst_entropy_flags; if (dst_entropy_pool == NULL) return (ISC_R_FAILURE); if (len == 0) return (ISC_R_SUCCESS); #ifdef PKCS11CRYPTO UNUSED(pseudo); UNUSED(flags); return (pk11_rand_bytes(buf, len)); #else /* PKCS11CRYPTO */ if (pseudo) flags &= ~ISC_ENTROPY_GOODONLY; else flags |= ISC_ENTROPY_BLOCKING; return (isc_entropy_getdata(dst_entropy_pool, buf, len, NULL, flags)); #endif /* PKCS11CRYPTO */ } unsigned int dst__entropy_status(void) { #ifndef PKCS11CRYPTO #ifdef GSSAPI unsigned int flags = dst_entropy_flags; isc_result_t ret; unsigned char buf[32]; static isc_boolean_t first = ISC_TRUE; if (dst_entropy_pool == NULL) return (0); if (first) { /* Someone believes RAND_status() initializes the PRNG */ flags &= ~ISC_ENTROPY_GOODONLY; ret = isc_entropy_getdata(dst_entropy_pool, buf, sizeof(buf), NULL, flags); INSIST(ret == ISC_R_SUCCESS); isc_entropy_putdata(dst_entropy_pool, buf, sizeof(buf), 2 * sizeof(buf)); first = ISC_FALSE; } #endif return (isc_entropy_status(dst_entropy_pool)); #else return (0); #endif } isc_buffer_t * dst_key_tkeytoken(const dst_key_t *key) { REQUIRE(VALID_KEY(key)); return (key->key_tkeytoken); } bind9-9.10.3.dfsg.P4/lib/dns/pkcs11gost_link.c0000644000470500017500000006322312664710322020111 0ustar lamontlamont/* * Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #if defined(PKCS11CRYPTO) && defined(HAVE_PKCS11_GOST) #include #include #include #include #include #include #include #include #include "dst_internal.h" #include "dst_parse.h" #include "dst_pkcs11.h" #include "dst_gost.h" #include #include #define WANT_GOST_PARAMS #include #include /* * RU CryptoPro GOST keys: * mechanisms: * CKM_GOSTR3411 * CKM_GOSTR3410_WITH_GOSTR3411 * CKM_GOSTR3410_KEY_PAIR_GEN * domain parameters: * CKA_GOSTR3410_PARAMS (fixed BER OID 1.2.643.2.2.35.1) * CKA_GOSTR3411_PARAMS (fixed BER OID 1.2.643.2.2.30.1) * CKA_GOST28147_PARAMS (optional, don't use) * public keys: * object class CKO_PUBLIC_KEY * key type CKK_GOSTR3410 * attribute CKA_VALUE (point Q) * attribute CKA_GOSTR3410_PARAMS * attribute CKA_GOSTR3411_PARAMS * attribute CKA_GOST28147_PARAMS * private keys: * object class CKO_PRIVATE_KEY * key type CKK_GOSTR3410 * attribute CKA_VALUE (big int d) * attribute CKA_GOSTR3410_PARAMS * attribute CKA_GOSTR3411_PARAMS * attribute CKA_GOST28147_PARAMS * point format: (little endian) */ #define CKA_VALUE2 CKA_PRIVATE_EXPONENT #define ISC_GOST_SIGNATURELENGTH 64 #define ISC_GOST_PUBKEYLENGTH 64 #define ISC_GOST_KEYSIZE 256 /* HASH methods */ isc_result_t isc_gost_init(isc_gost_t *ctx) { CK_RV rv; CK_MECHANISM mech = { CKM_GOSTR3411, NULL, 0 }; int ret = ISC_R_SUCCESS; ret = pk11_get_session(ctx, OP_GOST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, 0); if (ret != ISC_R_SUCCESS) return (ret); PK11_CALL(pkcs_C_DigestInit, (ctx->session, &mech), ISC_R_FAILURE); return (ret); } void isc_gost_invalidate(isc_gost_t *ctx) { CK_BYTE garbage[ISC_GOST_DIGESTLENGTH]; CK_ULONG len = ISC_GOST_DIGESTLENGTH; if (ctx->handle == NULL) return; (void) pkcs_C_DigestFinal(ctx->session, garbage, &len); memset(garbage, 0, sizeof(garbage)); pk11_return_session(ctx); } isc_result_t isc_gost_update(isc_gost_t *ctx, const unsigned char *buf, unsigned int len) { CK_RV rv; CK_BYTE_PTR pPart; int ret = ISC_R_SUCCESS; DE_CONST(buf, pPart); PK11_CALL(pkcs_C_DigestUpdate, (ctx->session, pPart, (CK_ULONG) len), ISC_R_FAILURE); return (ret); } isc_result_t isc_gost_final(isc_gost_t *ctx, unsigned char *digest) { CK_RV rv; CK_ULONG len = ISC_GOST_DIGESTLENGTH; int ret = ISC_R_SUCCESS; PK11_CALL(pkcs_C_DigestFinal, (ctx->session, (CK_BYTE_PTR) digest, &len), ISC_R_FAILURE); pk11_return_session(ctx); return (ret); } /* DST methods */ static CK_BBOOL truevalue = TRUE; static CK_BBOOL falsevalue = FALSE; #define DST_RET(a) {ret = a; goto err;} static isc_result_t pkcs11gost_todns(const dst_key_t *key, isc_buffer_t *data); static void pkcs11gost_destroy(dst_key_t *key); static isc_result_t pkcs11gost_createctx_sign(dst_key_t *key, dst_context_t *dctx) { CK_RV rv; CK_MECHANISM mech = { CKM_GOSTR3410_WITH_GOSTR3411, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; CK_KEY_TYPE keyType = CKK_GOSTR3410; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_VALUE, NULL, 0 }, { CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset, (CK_ULONG) sizeof(pk11_gost_a_paramset) }, { CKA_GOSTR3411_PARAMS, pk11_gost_paramset, (CK_ULONG) sizeof(pk11_gost_paramset) } }; CK_ATTRIBUTE *attr; pk11_object_t *gost; pk11_context_t *pk11_ctx; isc_result_t ret; unsigned int i; pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_GOST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_GOST)); if (ret != ISC_R_SUCCESS) goto err; gost = key->keydata.pkey; if (gost->ontoken && (gost->object != CK_INVALID_HANDLE)) { pk11_ctx->ontoken = gost->ontoken; pk11_ctx->object = gost->object; goto token_key; } for (attr = pk11_attribute_first(gost); attr != NULL; attr = pk11_attribute_next(gost, attr)) switch (attr->type) { case CKA_VALUE2: INSIST(keyTemplate[6].type == CKA_VALUE); keyTemplate[6].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[6].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[6].pValue, attr->pValue, attr->ulValueLen); keyTemplate[6].ulValueLen = attr->ulValueLen; break; } pk11_ctx->object = CK_INVALID_HANDLE; pk11_ctx->ontoken = ISC_FALSE; PK11_RET(pkcs_C_CreateObject, (pk11_ctx->session, keyTemplate, (CK_ULONG) 9, &pk11_ctx->object), ISC_R_FAILURE); token_key: PK11_RET(pkcs_C_SignInit, (pk11_ctx->session, &mech, pk11_ctx->object), ISC_R_FAILURE); dctx->ctxdata.pk11_ctx = pk11_ctx; for (i = 6; i <= 6; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } return (ISC_R_SUCCESS); err: if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); for (i = 6; i <= 6; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); } static isc_result_t pkcs11gost_createctx_verify(dst_key_t *key, dst_context_t *dctx) { CK_RV rv; CK_MECHANISM mech = { CKM_GOSTR3410_WITH_GOSTR3411, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; CK_KEY_TYPE keyType = CKK_GOSTR3410; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_VALUE, NULL, 0 }, { CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset, (CK_ULONG) sizeof(pk11_gost_a_paramset) }, { CKA_GOSTR3411_PARAMS, pk11_gost_paramset, (CK_ULONG) sizeof(pk11_gost_paramset) } }; CK_ATTRIBUTE *attr; pk11_object_t *gost; pk11_context_t *pk11_ctx; isc_result_t ret; unsigned int i; pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_GOST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_GOST)); if (ret != ISC_R_SUCCESS) goto err; gost = key->keydata.pkey; if (gost->ontoken && (gost->object != CK_INVALID_HANDLE)) { pk11_ctx->ontoken = gost->ontoken; pk11_ctx->object = gost->object; goto token_key; } for (attr = pk11_attribute_first(gost); attr != NULL; attr = pk11_attribute_next(gost, attr)) switch (attr->type) { case CKA_VALUE: INSIST(keyTemplate[5].type == attr->type); keyTemplate[5].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[5].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[5].pValue, attr->pValue, attr->ulValueLen); keyTemplate[5].ulValueLen = attr->ulValueLen; break; } pk11_ctx->object = CK_INVALID_HANDLE; pk11_ctx->ontoken = ISC_FALSE; PK11_RET(pkcs_C_CreateObject, (pk11_ctx->session, keyTemplate, (CK_ULONG) 8, &pk11_ctx->object), ISC_R_FAILURE); token_key: PK11_RET(pkcs_C_VerifyInit, (pk11_ctx->session, &mech, pk11_ctx->object), ISC_R_FAILURE); dctx->ctxdata.pk11_ctx = pk11_ctx; for (i = 5; i <= 5; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } return (ISC_R_SUCCESS); err: if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); for (i = 5; i <= 5; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); } static isc_result_t pkcs11gost_createctx(dst_key_t *key, dst_context_t *dctx) { if (dctx->use == DO_SIGN) return (pkcs11gost_createctx_sign(key, dctx)); else return (pkcs11gost_createctx_verify(key, dctx)); } static void pkcs11gost_destroyctx(dst_context_t *dctx) { pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; if (pk11_ctx != NULL) { if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); dctx->ctxdata.pk11_ctx = NULL; } } static isc_result_t pkcs11gost_adddata(dst_context_t *dctx, const isc_region_t *data) { CK_RV rv; pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; isc_result_t ret = ISC_R_SUCCESS; if (dctx->use == DO_SIGN) PK11_CALL(pkcs_C_SignUpdate, (pk11_ctx->session, (CK_BYTE_PTR) data->base, (CK_ULONG) data->length), ISC_R_FAILURE); else PK11_CALL(pkcs_C_VerifyUpdate, (pk11_ctx->session, (CK_BYTE_PTR) data->base, (CK_ULONG) data->length), ISC_R_FAILURE); return (ret); } static isc_result_t pkcs11gost_sign(dst_context_t *dctx, isc_buffer_t *sig) { CK_RV rv; CK_ULONG siglen = ISC_GOST_SIGNATURELENGTH; isc_region_t r; pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; isc_result_t ret = ISC_R_SUCCESS; isc_buffer_availableregion(sig, &r); if (r.length < ISC_GOST_SIGNATURELENGTH) return (ISC_R_NOSPACE); PK11_RET(pkcs_C_SignFinal, (pk11_ctx->session, (CK_BYTE_PTR) r.base, &siglen), DST_R_SIGNFAILURE); if (siglen != ISC_GOST_SIGNATURELENGTH) return (DST_R_SIGNFAILURE); isc_buffer_add(sig, ISC_GOST_SIGNATURELENGTH); err: return (ret); } static isc_result_t pkcs11gost_verify(dst_context_t *dctx, const isc_region_t *sig) { CK_RV rv; pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; isc_result_t ret = ISC_R_SUCCESS; PK11_CALL(pkcs_C_VerifyFinal, (pk11_ctx->session, (CK_BYTE_PTR) sig->base, (CK_ULONG) sig->length), DST_R_VERIFYFAILURE); return (ret); } static isc_boolean_t pkcs11gost_compare(const dst_key_t *key1, const dst_key_t *key2) { pk11_object_t *gost1, *gost2; CK_ATTRIBUTE *attr1, *attr2; gost1 = key1->keydata.pkey; gost2 = key2->keydata.pkey; if ((gost1 == NULL) && (gost2 == NULL)) return (ISC_TRUE); else if ((gost1 == NULL) || (gost2 == NULL)) return (ISC_FALSE); attr1 = pk11_attribute_bytype(gost1, CKA_VALUE); attr2 = pk11_attribute_bytype(gost2, CKA_VALUE); if ((attr1 == NULL) && (attr2 == NULL)) return (ISC_TRUE); else if ((attr1 == NULL) || (attr2 == NULL) || (attr1->ulValueLen != attr2->ulValueLen) || !isc_safe_memequal(attr1->pValue, attr2->pValue, attr1->ulValueLen)) return (ISC_FALSE); attr1 = pk11_attribute_bytype(gost1, CKA_VALUE2); attr2 = pk11_attribute_bytype(gost2, CKA_VALUE2); if (((attr1 != NULL) || (attr2 != NULL)) && ((attr1 == NULL) || (attr2 == NULL) || (attr1->ulValueLen != attr2->ulValueLen) || !isc_safe_memequal(attr1->pValue, attr2->pValue, attr1->ulValueLen))) return (ISC_FALSE); if (!gost1->ontoken && !gost2->ontoken) return (ISC_TRUE); else if (gost1->ontoken || gost2->ontoken || (gost1->object != gost2->object)) return (ISC_FALSE); return (ISC_TRUE); } static isc_result_t pkcs11gost_generate(dst_key_t *key, int unused, void (*callback)(int)) { CK_RV rv; CK_MECHANISM mech = { CKM_GOSTR3410_KEY_PAIR_GEN, NULL, 0 }; CK_KEY_TYPE keyType = CKK_GOSTR3410; CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; CK_ATTRIBUTE pubTemplate[] = { { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset, (CK_ULONG) sizeof(pk11_gost_a_paramset) }, { CKA_GOSTR3411_PARAMS, pk11_gost_paramset, (CK_ULONG) sizeof(pk11_gost_paramset) } }; CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY; CK_ATTRIBUTE privTemplate[] = { { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, }; CK_ATTRIBUTE *attr; pk11_object_t *gost; pk11_context_t *pk11_ctx; isc_result_t ret; UNUSED(unused); UNUSED(callback); pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_GOST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_GOST)); if (ret != ISC_R_SUCCESS) goto err; PK11_RET(pkcs_C_GenerateKeyPair, (pk11_ctx->session, &mech, pubTemplate, (CK_ULONG) 7, privTemplate, (CK_ULONG) 7, &pub, &priv), DST_R_CRYPTOFAILURE); gost = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*gost)); if (gost == NULL) DST_RET(ISC_R_NOMEMORY); memset(gost, 0, sizeof(*gost)); key->keydata.pkey = gost; key->key_size = ISC_GOST_KEYSIZE; gost->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); if (gost->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(gost->repr, 0, sizeof(*attr) * 2); gost->attrcnt = 2; attr = gost->repr; attr[0].type = CKA_VALUE; attr[1].type = CKA_VALUE2; attr = gost->repr; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr++; attr->type = CKA_VALUE; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); attr->type = CKA_VALUE2; (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ISC_R_SUCCESS); err: pkcs11gost_destroy(key); if (priv != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); if (pub != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); } static isc_boolean_t pkcs11gost_isprivate(const dst_key_t *key) { pk11_object_t *gost = key->keydata.pkey; CK_ATTRIBUTE *attr; if (gost == NULL) return (ISC_FALSE); attr = pk11_attribute_bytype(gost, CKA_VALUE2); return (ISC_TF((attr != NULL) || gost->ontoken)); } static void pkcs11gost_destroy(dst_key_t *key) { pk11_object_t *gost = key->keydata.pkey; CK_ATTRIBUTE *attr; if (gost == NULL) return; INSIST((gost->object == CK_INVALID_HANDLE) || gost->ontoken); for (attr = pk11_attribute_first(gost); attr != NULL; attr = pk11_attribute_next(gost, attr)) switch (attr->type) { case CKA_VALUE: case CKA_VALUE2: if (attr->pValue != NULL) { memset(attr->pValue, 0, attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); } break; } if (gost->repr != NULL) { memset(gost->repr, 0, gost->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, gost->repr, gost->attrcnt * sizeof(*attr)); } memset(gost, 0, sizeof(*gost)); isc_mem_put(key->mctx, gost, sizeof(*gost)); key->keydata.pkey = NULL; } static isc_result_t pkcs11gost_todns(const dst_key_t *key, isc_buffer_t *data) { pk11_object_t *gost; isc_region_t r; CK_ATTRIBUTE *attr; REQUIRE(key->keydata.pkey != NULL); gost = key->keydata.pkey; attr = pk11_attribute_bytype(gost, CKA_VALUE); if ((attr == NULL) || (attr->ulValueLen != ISC_GOST_PUBKEYLENGTH)) return (ISC_R_FAILURE); isc_buffer_availableregion(data, &r); if (r.length < ISC_GOST_PUBKEYLENGTH) return (ISC_R_NOSPACE); memmove(r.base, (CK_BYTE_PTR) attr->pValue, ISC_GOST_PUBKEYLENGTH); isc_buffer_add(data, ISC_GOST_PUBKEYLENGTH); return (ISC_R_SUCCESS); } static isc_result_t pkcs11gost_fromdns(dst_key_t *key, isc_buffer_t *data) { pk11_object_t *gost; isc_region_t r; CK_ATTRIBUTE *attr; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); if (r.length != ISC_GOST_PUBKEYLENGTH) return (DST_R_INVALIDPUBLICKEY); gost = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*gost)); if (gost == NULL) return (ISC_R_NOMEMORY); memset(gost, 0, sizeof(*gost)); gost->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr)); if (gost->repr == NULL) goto nomemory; gost->attrcnt = 1; attr = gost->repr; attr->type = CKA_VALUE; attr->pValue = isc_mem_get(key->mctx, ISC_GOST_PUBKEYLENGTH); if (attr->pValue == NULL) goto nomemory; memmove((CK_BYTE_PTR) attr->pValue, r.base, ISC_GOST_PUBKEYLENGTH); attr->ulValueLen = ISC_GOST_PUBKEYLENGTH; isc_buffer_forward(data, ISC_GOST_PUBKEYLENGTH); key->keydata.pkey = gost; key->key_size = ISC_GOST_KEYSIZE; return (ISC_R_SUCCESS); nomemory: for (attr = pk11_attribute_first(gost); attr != NULL; attr = pk11_attribute_next(gost, attr)) switch (attr->type) { case CKA_VALUE: if (attr->pValue != NULL) { memset(attr->pValue, 0, attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); } break; } if (gost->repr != NULL) { memset(gost->repr, 0, gost->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, gost->repr, gost->attrcnt * sizeof(*attr)); } memset(gost, 0, sizeof(*gost)); isc_mem_put(key->mctx, gost, sizeof(*gost)); return (ISC_R_NOMEMORY); } static unsigned char gost_private_der[39] = { 0x30, 0x45, 0x02, 0x01, 0x00, 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, 0x04, 0x22, 0x02, 0x20 }; #ifdef PREFER_GOSTASN1 static isc_result_t pkcs11gost_tofile(const dst_key_t *key, const char *directory) { isc_result_t ret; pk11_object_t *gost; dst_private_t priv; unsigned char *buf = NULL; unsigned int i = 0; CK_ATTRIBUTE *attr; int adj; if (key->keydata.pkey == NULL) return (DST_R_NULLKEY); if (key->external) { priv.nelements = 0; return (dst__privstruct_writefile(key, &priv, directory)); } gost = key->keydata.pkey; attr = pk11_attribute_bytype(gost, CKA_VALUE2); if (attr != NULL) { buf = isc_mem_get(key->mctx, attr->ulValueLen + 39); if (buf == NULL) return (ISC_R_NOMEMORY); priv.elements[i].tag = TAG_GOST_PRIVASN1; priv.elements[i].length = (unsigned short) attr->ulValueLen + 39; memmove(buf, gost_private_der, 39); memmove(buf + 39, attr->pValue, attr->ulValueLen); adj = (int) attr->ulValueLen - 32; if (adj != 0) { buf[1] += adj; buf[36] += adj; buf[38] += adj; } priv.elements[i].data = buf; i++; } else return (DST_R_CRYPTOFAILURE); priv.nelements = i; ret = dst__privstruct_writefile(key, &priv, directory); if (buf != NULL) { memset(buf, 0, attr->ulValueLen); isc_mem_put(key->mctx, buf, attr->ulValueLen); } return (ret); } #else static isc_result_t pkcs11gost_tofile(const dst_key_t *key, const char *directory) { isc_result_t ret; pk11_object_t *gost; dst_private_t priv; unsigned char *buf = NULL; unsigned int i = 0; CK_ATTRIBUTE *attr; if (key->keydata.pkey == NULL) return (DST_R_NULLKEY); if (key->external) { priv.nelements = 0; return (dst__privstruct_writefile(key, &priv, directory)); } gost = key->keydata.pkey; attr = pk11_attribute_bytype(gost, CKA_VALUE2); if (attr != NULL) { buf = isc_mem_get(key->mctx, attr->ulValueLen); if (buf == NULL) return (ISC_R_NOMEMORY); priv.elements[i].tag = TAG_GOST_PRIVRAW; priv.elements[i].length = (unsigned short) attr->ulValueLen; memmove(buf, attr->pValue, attr->ulValueLen); priv.elements[i].data = buf; i++; } else return (DST_R_CRYPTOFAILURE); priv.nelements = i; ret = dst__privstruct_writefile(key, &priv, directory); if (buf != NULL) { memset(buf, 0, attr->ulValueLen); isc_mem_put(key->mctx, buf, attr->ulValueLen); } return (ret); } #endif static isc_result_t pkcs11gost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t ret; pk11_object_t *gost = NULL; CK_ATTRIBUTE *attr, *pattr; isc_mem_t *mctx = key->mctx; if ((pub == NULL) || (pub->keydata.pkey == NULL)) DST_RET(DST_R_INVALIDPRIVATEKEY); /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) return (ret); if (key->external) { if (priv.nelements != 0) DST_RET(DST_R_INVALIDPRIVATEKEY); key->keydata.pkey = pub->keydata.pkey; pub->keydata.pkey = NULL; key->key_size = pub->key_size; dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ISC_R_SUCCESS); } if (priv.elements[0].tag == TAG_GOST_PRIVASN1) { int adj = (int) priv.elements[0].length - (39 + 32); unsigned char buf[39]; if ((adj > 0) || (adj < -31)) DST_RET(DST_R_INVALIDPRIVATEKEY); memmove(buf, gost_private_der, 39); if (adj != 0) { buf[1] += adj; buf[36] += adj; buf[38] += adj; } if (!isc_safe_memequal(priv.elements[0].data, buf, 39)) DST_RET(DST_R_INVALIDPRIVATEKEY); priv.elements[0].tag = TAG_GOST_PRIVRAW; priv.elements[0].length -= 39; memmove(priv.elements[0].data, priv.elements[0].data + 39, 32 + adj); } gost = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*gost)); if (gost == NULL) DST_RET(ISC_R_NOMEMORY); memset(gost, 0, sizeof(*gost)); key->keydata.pkey = gost; key->key_size = ISC_GOST_KEYSIZE; gost->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); if (gost->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(gost->repr, 0, sizeof(*attr) * 2); gost->attrcnt = 2; attr = gost->repr; attr->type = CKA_VALUE; pattr = pk11_attribute_bytype(pub->keydata.pkey, CKA_VALUE); INSIST(pattr != NULL); attr->pValue = isc_mem_get(key->mctx, pattr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(attr->pValue, pattr->pValue, pattr->ulValueLen); attr->ulValueLen = pattr->ulValueLen; attr++; attr->type = CKA_VALUE2; attr->pValue = isc_mem_get(key->mctx, priv.elements[0].length); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(attr->pValue, priv.elements[0].data, priv.elements[0].length); attr->ulValueLen = priv.elements[0].length; dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ISC_R_SUCCESS); err: pkcs11gost_destroy(key); dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ret); } static dst_func_t pkcs11gost_functions = { pkcs11gost_createctx, NULL, /*%< createctx2 */ pkcs11gost_destroyctx, pkcs11gost_adddata, pkcs11gost_sign, pkcs11gost_verify, NULL, /*%< verify2 */ NULL, /*%< computesecret */ pkcs11gost_compare, NULL, /*%< paramcompare */ pkcs11gost_generate, pkcs11gost_isprivate, pkcs11gost_destroy, pkcs11gost_todns, pkcs11gost_fromdns, pkcs11gost_tofile, pkcs11gost_parse, NULL, /*%< cleanup */ NULL, /*%< fromlabel */ NULL, /*%< dump */ NULL, /*%< restore */ }; isc_result_t dst__pkcs11gost_init(dst_func_t **funcp) { REQUIRE(funcp != NULL); if (*funcp == NULL) *funcp = &pkcs11gost_functions; return (ISC_R_SUCCESS); } #else /* PKCS11CRYPTO && HAVE_PKCS11_GOST */ #include EMPTY_TRANSLATION_UNIT #endif /* PKCS11CRYPTO && HAVE_PKCS11_GOST */ /*! \file */ bind9-9.10.3.dfsg.P4/lib/dns/gen.c0000644000470500017500000006133412664710322015647 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2012-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #ifdef WIN32 /* * Silence compiler warnings about using strcpy and friends. */ #define _CRT_SECURE_NO_DEPRECATE 1 /* * We use snprintf which was defined late in Windows even it is in C99. */ #if _MSC_VER < 1900 #define snprintf _snprintf #endif #endif #include #include #include #include #include #include #include #ifdef WIN32 #include "gen-win32.h" #else #include "gen-unix.h" #endif #define INSIST(cond) \ if (!(cond)) { \ fprintf(stderr, "%s:%d: INSIST(%s)\n", \ __FILE__, __LINE__, #cond); \ abort(); \ } #define FROMTEXTARGS "rdclass, type, lexer, origin, options, target, callbacks" #define FROMTEXTCLASS "rdclass" #define FROMTEXTTYPE "type" #define FROMTEXTDEF "result = DNS_R_UNKNOWN" #define TOTEXTARGS "rdata, tctx, target" #define TOTEXTCLASS "rdata->rdclass" #define TOTEXTTYPE "rdata->type" #define TOTEXTDEF "use_default = ISC_TRUE" #define FROMWIREARGS "rdclass, type, source, dctx, options, target" #define FROMWIRECLASS "rdclass" #define FROMWIRETYPE "type" #define FROMWIREDEF "use_default = ISC_TRUE" #define TOWIREARGS "rdata, cctx, target" #define TOWIRECLASS "rdata->rdclass" #define TOWIRETYPE "rdata->type" #define TOWIREDEF "use_default = ISC_TRUE" #define FROMSTRUCTARGS "rdclass, type, source, target" #define FROMSTRUCTCLASS "rdclass" #define FROMSTRUCTTYPE "type" #define FROMSTRUCTDEF "use_default = ISC_TRUE" #define TOSTRUCTARGS "rdata, target, mctx" #define TOSTRUCTCLASS "rdata->rdclass" #define TOSTRUCTTYPE "rdata->type" #define TOSTRUCTDEF "use_default = ISC_TRUE" #define FREESTRUCTARGS "source" #define FREESTRUCTCLASS "common->rdclass" #define FREESTRUCTTYPE "common->rdtype" #define FREESTRUCTDEF NULL #define COMPAREARGS "rdata1, rdata2" #define COMPARECLASS "rdata1->rdclass" #define COMPARETYPE "rdata1->type" #define COMPAREDEF "use_default = ISC_TRUE" #define ADDITIONALDATAARGS "rdata, add, arg" #define ADDITIONALDATACLASS "rdata->rdclass" #define ADDITIONALDATATYPE "rdata->type" #define ADDITIONALDATADEF "use_default = ISC_TRUE" #define DIGESTARGS "rdata, digest, arg" #define DIGESTCLASS "rdata->rdclass" #define DIGESTTYPE "rdata->type" #define DIGESTDEF "use_default = ISC_TRUE" #define CHECKOWNERARGS "name, rdclass, type, wildcard" #define CHECKOWNERCLASS "rdclass" #define CHECKOWNERTYPE "type" #define CHECKOWNERDEF "result = ISC_TRUE" #define CHECKNAMESARGS "rdata, owner, bad" #define CHECKNAMESCLASS "rdata->rdclass" #define CHECKNAMESTYPE "rdata->type" #define CHECKNAMESDEF "result = ISC_TRUE" static const char copyright[] = "/*\n" " * Copyright (C) 2004%s Internet Systems Consortium, Inc. (\"ISC\")\n" " * Copyright (C) 1998-2003 Internet Software Consortium.\n" " *\n" " * Permission to use, copy, modify, and distribute this software for any\n" " * purpose with or without fee is hereby granted, provided that the above\n" " * copyright notice and this permission notice appear in all copies.\n" " *\n" " * THE SOFTWARE IS PROVIDED \"AS IS\" AND ISC DISCLAIMS ALL WARRANTIES WITH\n" " * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\n" " * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,\n" " * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\n" " * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE\n" " * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\n" " * PERFORMANCE OF THIS SOFTWARE.\n" " */\n" "\n" "/***************\n" " ***************\n" " *************** THIS FILE IS AUTOMATICALLY GENERATED BY gen.c.\n" " *************** DO NOT EDIT!\n" " ***************\n" " ***************/\n" "\n" "/*! \\file */\n" "\n"; #define STR_EXPAND(tok) #tok #define STR(tok) STR_EXPAND(tok) #define TYPENAMES 256 #define TYPECLASSLEN 20 /* DNS mnemonic size. Must be less than 100. */ #define TYPECLASSBUF (TYPECLASSLEN + 1) #define TYPECLASSFMT "%" STR(TYPECLASSLEN) "[-0-9a-z]_%d" #define ATTRIBUTESIZE 256 #define DIRNAMESIZE 256 static struct cc { struct cc *next; int rdclass; char classname[TYPECLASSBUF]; } *classes; static struct tt { struct tt *next; int rdclass; int type; char classname[TYPECLASSBUF]; char typename[TYPECLASSBUF]; char dirname[DIRNAMESIZE]; /* XXX Should be max path length */ } *types; static struct ttnam { char typename[TYPECLASSBUF]; char macroname[TYPECLASSBUF]; char attr[ATTRIBUTESIZE]; unsigned int sorted; int type; } typenames[TYPENAMES]; static int maxtype = -1; static char * upper(char *); static char * funname(const char *, char *); static void doswitch(const char *, const char *, const char *, const char *, const char *, const char *); static void add(int, const char *, int, const char *, const char *); static void sd(int, const char *, const char *, char); static void insert_into_typenames(int, const char *, const char *); /*% * If you use more than 10 of these in, say, a printf(), you'll have problems. */ static char * upper(char *s) { static int buf_to_use = 0; static char buf[10][256]; char *b; int c; buf_to_use++; if (buf_to_use > 9) buf_to_use = 0; b = buf[buf_to_use]; memset(b, 0, 256); while ((c = (*s++) & 0xff)) *b++ = islower(c) ? toupper(c) : c; *b = '\0'; return (buf[buf_to_use]); } static char * funname(const char *s, char *buf) { char *b = buf; char c; INSIST(strlen(s) < TYPECLASSBUF); while ((c = *s++)) { *b++ = (c == '-') ? '_' : c; } *b = '\0'; return (buf); } static void doswitch(const char *name, const char *function, const char *args, const char *tsw, const char *csw, const char *res) { struct tt *tt; int first = 1; int lasttype = 0; int subswitch = 0; char buf1[TYPECLASSBUF], buf2[TYPECLASSBUF]; const char *result = " result ="; if (res == NULL) result = ""; for (tt = types; tt != NULL; tt = tt->next) { if (first) { fprintf(stdout, "\n#define %s \\\n", name); fprintf(stdout, "\tswitch (%s) { \\\n" /*}*/, tsw); first = 0; } if (tt->type != lasttype && subswitch) { if (res == NULL) fprintf(stdout, "\t\tdefault: break; \\\n"); else fprintf(stdout, "\t\tdefault: %s; break; \\\n", res); fputs(/*{*/ "\t\t} \\\n", stdout); fputs("\t\tbreak; \\\n", stdout); subswitch = 0; } if (tt->rdclass && tt->type != lasttype) { fprintf(stdout, "\tcase %d: switch (%s) { \\\n" /*}*/, tt->type, csw); subswitch = 1; } if (tt->rdclass == 0) fprintf(stdout, "\tcase %d:%s %s_%s(%s); break;", tt->type, result, function, funname(tt->typename, buf1), args); else fprintf(stdout, "\t\tcase %d:%s %s_%s_%s(%s); break;", tt->rdclass, result, function, funname(tt->classname, buf1), funname(tt->typename, buf2), args); fputs(" \\\n", stdout); lasttype = tt->type; } if (subswitch) { if (res == NULL) fprintf(stdout, "\t\tdefault: break; \\\n"); else fprintf(stdout, "\t\tdefault: %s; break; \\\n", res); fputs(/*{*/ "\t\t} \\\n", stdout); fputs("\t\tbreak; \\\n", stdout); } if (first) { if (res == NULL) fprintf(stdout, "\n#define %s\n", name); else fprintf(stdout, "\n#define %s %s;\n", name, res); } else { if (res == NULL) fprintf(stdout, "\tdefault: break; \\\n"); else fprintf(stdout, "\tdefault: %s; break; \\\n", res); fputs(/*{*/ "\t}\n", stdout); } } static struct ttnam * find_typename(int type) { int i; for (i = 0; i < TYPENAMES; i++) { if (typenames[i].typename[0] != 0 && typenames[i].type == type) return (&typenames[i]); } return (NULL); } static void insert_into_typenames(int type, const char *typename, const char *attr) { struct ttnam *ttn = NULL; size_t c; int i, n; char tmp[256]; INSIST(strlen(typename) < TYPECLASSBUF); for (i = 0; i < TYPENAMES; i++) { if (typenames[i].typename[0] != 0 && typenames[i].type == type && strcmp(typename, typenames[i].typename) != 0) { fprintf(stderr, "Error: type %d has two names: %s, %s\n", type, typenames[i].typename, typename); exit(1); } if (typenames[i].typename[0] == 0 && ttn == NULL) ttn = &typenames[i]; } if (ttn == NULL) { fprintf(stderr, "Error: typenames array too small\n"); exit(1); } /* XXXMUKS: This is redundant due to the INSIST above. */ if (strlen(typename) > sizeof(ttn->typename) - 1) { fprintf(stderr, "Error: type name %s is too long\n", typename); exit(1); } strncpy(ttn->typename, typename, sizeof(ttn->typename)); ttn->typename[sizeof(ttn->typename) - 1] = '\0'; strncpy(ttn->macroname, ttn->typename, sizeof(ttn->macroname)); ttn->macroname[sizeof(ttn->macroname) - 1] = '\0'; ttn->type = type; c = strlen(ttn->macroname); while (c > 0) { if (ttn->macroname[c - 1] == '-') ttn->macroname[c - 1] = '_'; c--; } if (attr == NULL) { n = snprintf(tmp, sizeof(tmp), "RRTYPE_%s_ATTRIBUTES", upper(ttn->macroname)); INSIST(n > 0 && (unsigned)n < sizeof(tmp)); attr = tmp; } if (ttn->attr[0] != 0 && strcmp(attr, ttn->attr) != 0) { fprintf(stderr, "Error: type %d has different attributes: " "%s, %s\n", type, ttn->attr, attr); exit(1); } if (strlen(attr) > sizeof(ttn->attr) - 1) { fprintf(stderr, "Error: attr (%s) [name %s] is too long\n", attr, typename); exit(1); } strncpy(ttn->attr, attr, sizeof(ttn->attr)); ttn->attr[sizeof(ttn->attr) - 1] = '\0'; ttn->sorted = 0; if (maxtype < type) maxtype = type; } static void add(int rdclass, const char *classname, int type, const char *typename, const char *dirname) { struct tt *newtt = (struct tt *)malloc(sizeof(*newtt)); struct tt *tt, *oldtt; struct cc *newcc; struct cc *cc, *oldcc; INSIST(strlen(typename) < TYPECLASSBUF); INSIST(strlen(classname) < TYPECLASSBUF); INSIST(strlen(dirname) < DIRNAMESIZE); insert_into_typenames(type, typename, NULL); if (newtt == NULL) { fprintf(stderr, "malloc() failed\n"); exit(1); } newtt->next = NULL; newtt->rdclass = rdclass; newtt->type = type; strncpy(newtt->classname, classname, sizeof(newtt->classname)); newtt->classname[sizeof(newtt->classname) - 1] = '\0'; strncpy(newtt->typename, typename, sizeof(newtt->typename)); newtt->typename[sizeof(newtt->typename) - 1] = '\0'; if (strncmp(dirname, "./", 2) == 0) dirname += 2; strncpy(newtt->dirname, dirname, sizeof(newtt->dirname)); newtt->dirname[sizeof(newtt->dirname) - 1] = '\0'; tt = types; oldtt = NULL; while ((tt != NULL) && (tt->type < type)) { oldtt = tt; tt = tt->next; } while ((tt != NULL) && (tt->type == type) && (tt->rdclass < rdclass)) { if (strcmp(tt->typename, typename) != 0) exit(1); oldtt = tt; tt = tt->next; } if ((tt != NULL) && (tt->type == type) && (tt->rdclass == rdclass)) exit(1); newtt->next = tt; if (oldtt != NULL) oldtt->next = newtt; else types = newtt; /* * Do a class switch for this type. */ if (rdclass == 0) return; newcc = (struct cc *)malloc(sizeof(*newcc)); if (newcc == NULL) { fprintf(stderr, "malloc() failed\n"); exit(1); } newcc->rdclass = rdclass; strncpy(newcc->classname, classname, sizeof(newcc->classname)); newcc->classname[sizeof(newcc->classname) - 1] = '\0'; cc = classes; oldcc = NULL; while ((cc != NULL) && (cc->rdclass < rdclass)) { oldcc = cc; cc = cc->next; } if ((cc != NULL) && cc->rdclass == rdclass) { free((char *)newcc); return; } newcc->next = cc; if (oldcc != NULL) oldcc->next = newcc; else classes = newcc; } static void sd(int rdclass, const char *classname, const char *dirname, char filetype) { char buf[TYPECLASSLEN + sizeof("_65535.h")]; char typename[TYPECLASSBUF]; int type, n; isc_dir_t dir; if (!start_directory(dirname, &dir)) return; while (next_file(&dir)) { if (sscanf(dir.filename, TYPECLASSFMT, typename, &type) != 2) continue; if ((type > 65535) || (type < 0)) continue; n = snprintf(buf, sizeof(buf), "%s_%d.%c", typename, type, filetype); INSIST(n > 0 && (unsigned)n < sizeof(buf)); if (strcmp(buf, dir.filename) != 0) continue; add(rdclass, classname, type, typename, dirname); } end_directory(&dir); } static unsigned int HASH(char *string) { size_t n; unsigned char a, b; n = strlen(string); if (n == 0) { fprintf(stderr, "n == 0?\n"); exit(1); } a = tolower((unsigned char)string[0]); b = tolower((unsigned char)string[n - 1]); return ((a + n) * b) % 256; } int main(int argc, char **argv) { char buf[DIRNAMESIZE]; /* XXX Should be max path length */ char srcdir[DIRNAMESIZE]; /* XXX Should be max path length */ int rdclass; char classname[TYPECLASSBUF]; struct tt *tt; struct cc *cc; struct ttnam *ttn, *ttn2; unsigned int hash; struct tm *tm; time_t now; char year[11]; int lasttype; int code = 1; int class_enum = 0; int type_enum = 0; int structs = 0; int depend = 0; int c, i, j, n; char buf1[TYPECLASSBUF]; char filetype = 'c'; FILE *fd; char *prefix = NULL; char *suffix = NULL; char *file = NULL; isc_dir_t dir; for (i = 0; i < TYPENAMES; i++) memset(&typenames[i], 0, sizeof(typenames[i])); strcpy(srcdir, ""); while ((c = isc_commandline_parse(argc, argv, "cdits:F:P:S:")) != -1) switch (c) { case 'c': code = 0; depend = 0; type_enum = 0; class_enum = 1; filetype = 'c'; structs = 0; break; case 'd': code = 0; depend = 1; class_enum = 0; type_enum = 0; structs = 0; filetype = 'h'; break; case 't': code = 0; depend = 0; class_enum = 0; type_enum = 1; filetype = 'c'; structs = 0; break; case 'i': code = 0; depend = 0; class_enum = 0; type_enum = 0; structs = 1; filetype = 'h'; break; case 's': if (strlen(isc_commandline_argument) > DIRNAMESIZE - 2 * TYPECLASSLEN - sizeof("/rdata/_65535_65535")) { fprintf(stderr, "\"%s\" too long\n", isc_commandline_argument); exit(1); } n = snprintf(srcdir, sizeof(srcdir), "%s/", isc_commandline_argument); INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); break; case 'F': file = isc_commandline_argument; break; case 'P': prefix = isc_commandline_argument; break; case 'S': suffix = isc_commandline_argument; break; case '?': exit(1); } n = snprintf(buf, sizeof(buf), "%srdata", srcdir); INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); if (!start_directory(buf, &dir)) exit(1); while (next_file(&dir)) { if (sscanf(dir.filename, TYPECLASSFMT, classname, &rdclass) != 2) continue; if ((rdclass > 65535) || (rdclass < 0)) continue; n = snprintf(buf, sizeof(buf), "%srdata/%s_%d", srcdir, classname, rdclass); INSIST(n > 0 && (unsigned)n < sizeof(buf)); if (strcmp(buf + 6 + strlen(srcdir), dir.filename) != 0) continue; sd(rdclass, classname, buf, filetype); } end_directory(&dir); n = snprintf(buf, sizeof(buf), "%srdata/generic", srcdir); INSIST(n > 0 && (unsigned)n < sizeof(srcdir)); sd(0, "", buf, filetype); if (time(&now) != -1) { if ((tm = localtime(&now)) != NULL && tm->tm_year > 104) { n = snprintf(year, sizeof(year), "-%d", tm->tm_year + 1900); INSIST(n > 0 && (unsigned)n < sizeof(year)); } else year[0] = 0; } else year[0] = 0; if (!depend) fprintf(stdout, copyright, year); if (code) { fputs("#ifndef DNS_CODE_H\n", stdout); fputs("#define DNS_CODE_H 1\n\n", stdout); fputs("#include \n", stdout); fputs("#include \n\n", stdout); fputs("#include \n\n", stdout); for (tt = types; tt != NULL; tt = tt->next) fprintf(stdout, "#include \"%s/%s_%d.c\"\n", tt->dirname, tt->typename, tt->type); fputs("\n\n", stdout); doswitch("FROMTEXTSWITCH", "fromtext", FROMTEXTARGS, FROMTEXTTYPE, FROMTEXTCLASS, FROMTEXTDEF); doswitch("TOTEXTSWITCH", "totext", TOTEXTARGS, TOTEXTTYPE, TOTEXTCLASS, TOTEXTDEF); doswitch("FROMWIRESWITCH", "fromwire", FROMWIREARGS, FROMWIRETYPE, FROMWIRECLASS, FROMWIREDEF); doswitch("TOWIRESWITCH", "towire", TOWIREARGS, TOWIRETYPE, TOWIRECLASS, TOWIREDEF); doswitch("COMPARESWITCH", "compare", COMPAREARGS, COMPARETYPE, COMPARECLASS, COMPAREDEF); doswitch("CASECOMPARESWITCH", "casecompare", COMPAREARGS, COMPARETYPE, COMPARECLASS, COMPAREDEF); doswitch("FROMSTRUCTSWITCH", "fromstruct", FROMSTRUCTARGS, FROMSTRUCTTYPE, FROMSTRUCTCLASS, FROMSTRUCTDEF); doswitch("TOSTRUCTSWITCH", "tostruct", TOSTRUCTARGS, TOSTRUCTTYPE, TOSTRUCTCLASS, TOSTRUCTDEF); doswitch("FREESTRUCTSWITCH", "freestruct", FREESTRUCTARGS, FREESTRUCTTYPE, FREESTRUCTCLASS, FREESTRUCTDEF); doswitch("ADDITIONALDATASWITCH", "additionaldata", ADDITIONALDATAARGS, ADDITIONALDATATYPE, ADDITIONALDATACLASS, ADDITIONALDATADEF); doswitch("DIGESTSWITCH", "digest", DIGESTARGS, DIGESTTYPE, DIGESTCLASS, DIGESTDEF); doswitch("CHECKOWNERSWITCH", "checkowner", CHECKOWNERARGS, CHECKOWNERTYPE, CHECKOWNERCLASS, CHECKOWNERDEF); doswitch("CHECKNAMESSWITCH", "checknames", CHECKNAMESARGS, CHECKNAMESTYPE, CHECKNAMESCLASS, CHECKNAMESDEF); /* * From here down, we are processing the rdata names and * attributes. */ #define PRINT_COMMA(x) (x == maxtype ? "" : ",") #define METANOTQUESTION "DNS_RDATATYPEATTR_META | " \ "DNS_RDATATYPEATTR_NOTQUESTION" #define METAQUESTIONONLY "DNS_RDATATYPEATTR_META | " \ "DNS_RDATATYPEATTR_QUESTIONONLY" #define RESERVED "DNS_RDATATYPEATTR_RESERVED" /* * Add in reserved/special types. This will let us * sort them without special cases. */ insert_into_typenames(0, "reserved0", RESERVED); insert_into_typenames(31, "eid", RESERVED); insert_into_typenames(32, "nimloc", RESERVED); insert_into_typenames(34, "atma", RESERVED); insert_into_typenames(100, "uinfo", RESERVED); insert_into_typenames(101, "uid", RESERVED); insert_into_typenames(102, "gid", RESERVED); insert_into_typenames(251, "ixfr", METAQUESTIONONLY); insert_into_typenames(252, "axfr", METAQUESTIONONLY); insert_into_typenames(253, "mailb", METAQUESTIONONLY); insert_into_typenames(254, "maila", METAQUESTIONONLY); insert_into_typenames(255, "any", METAQUESTIONONLY); /* * Spit out a quick and dirty hash function. Here, * we walk through the list of type names, and calculate * a hash. This isn't perfect, but it will generate "pretty * good" estimates. Lowercase the characters before * computing in all cases. * * Here, walk the list from top to bottom, calculating * the hash (mod 256) for each name. */ fprintf(stdout, "#define RDATATYPE_COMPARE(_s, _d, _tn, _n, _tp) \\\n"); fprintf(stdout, "\tdo { \\\n"); fprintf(stdout, "\t\tif (sizeof(_s) - 1 == _n && \\\n" "\t\t strncasecmp(_s,(_tn)," "(sizeof(_s) - 1)) == 0) { \\\n"); fprintf(stdout, "\t\t\tif ((dns_rdatatype_attributes(_d) & " "DNS_RDATATYPEATTR_RESERVED) != 0) \\\n"); fprintf(stdout, "\t\t\t\treturn (ISC_R_NOTIMPLEMENTED); \\\n"); fprintf(stdout, "\t\t\t*(_tp) = _d; \\\n"); fprintf(stdout, "\t\t\treturn (ISC_R_SUCCESS); \\\n"); fprintf(stdout, "\t\t} \\\n"); fprintf(stdout, "\t} while (0)\n\n"); fprintf(stdout, "#define RDATATYPE_FROMTEXT_SW(_hash," "_typename,_length,_typep) \\\n"); fprintf(stdout, "\tswitch (_hash) { \\\n"); for (i = 0; i <= maxtype; i++) { ttn = find_typename(i); if (ttn == NULL) continue; /* * Skip entries we already processed. */ if (ttn->sorted != 0) continue; hash = HASH(ttn->typename); fprintf(stdout, "\t\tcase %u: \\\n", hash); /* * Find all other entries that happen to match * this hash. */ for (j = 0; j <= maxtype; j++) { ttn2 = find_typename(j); if (ttn2 == NULL) continue; if (hash == HASH(ttn2->typename)) { fprintf(stdout, "\t\t\tRDATATYPE_COMPARE" "(\"%s\", %u, " "_typename, _length, _typep); \\\n", ttn2->typename, ttn2->type); ttn2->sorted = 1; } } fprintf(stdout, "\t\t\tbreak; \\\n"); } fprintf(stdout, "\t}\n"); fprintf(stdout, "#define RDATATYPE_ATTRIBUTE_SW \\\n"); fprintf(stdout, "\tswitch (type) { \\\n"); for (i = 0; i <= maxtype; i++) { ttn = find_typename(i); if (ttn == NULL) continue; fprintf(stdout, "\tcase %u: return (%s); \\\n", i, upper(ttn->attr)); } fprintf(stdout, "\t}\n"); fprintf(stdout, "#define RDATATYPE_TOTEXT_SW \\\n"); fprintf(stdout, "\tswitch (type) { \\\n"); for (i = 0; i <= maxtype; i++) { ttn = find_typename(i); if (ttn == NULL) continue; /* * Remove KEYDATA (65533) from the type to memonic * translation as it is internal use only. This * stops the tools from displaying KEYDATA instead * of TYPE65533. */ if (i == 65533U) continue; fprintf(stdout, "\tcase %u: return " "(str_totext(\"%s\", target)); \\\n", i, upper(ttn->typename)); } fprintf(stdout, "\t}\n"); fputs("#endif /* DNS_CODE_H */\n", stdout); } else if (type_enum) { char *s; fprintf(stdout, "#ifndef DNS_ENUMTYPE_H\n"); fprintf(stdout, "#define DNS_ENUMTYPE_H 1\n\n"); fprintf(stdout, "enum {\n"); fprintf(stdout, "\tdns_rdatatype_none = 0,\n"); lasttype = 0; for (tt = types; tt != NULL; tt = tt->next) if (tt->type != lasttype) fprintf(stdout, "\tdns_rdatatype_%s = %d,\n", funname(tt->typename, buf1), lasttype = tt->type); fprintf(stdout, "\tdns_rdatatype_ixfr = 251,\n"); fprintf(stdout, "\tdns_rdatatype_axfr = 252,\n"); fprintf(stdout, "\tdns_rdatatype_mailb = 253,\n"); fprintf(stdout, "\tdns_rdatatype_maila = 254,\n"); fprintf(stdout, "\tdns_rdatatype_any = 255\n"); fprintf(stdout, "};\n\n"); fprintf(stdout, "#define dns_rdatatype_none\t" "((dns_rdatatype_t)dns_rdatatype_none)\n"); for (tt = types; tt != NULL; tt = tt->next) if (tt->type != lasttype) { s = funname(tt->typename, buf1); fprintf(stdout, "#define dns_rdatatype_%s\t%s" "((dns_rdatatype_t)dns_rdatatype_%s)" "\n", s, strlen(s) < 2U ? "\t" : "", s); lasttype = tt->type; } fprintf(stdout, "#define dns_rdatatype_ixfr\t" "((dns_rdatatype_t)dns_rdatatype_ixfr)\n"); fprintf(stdout, "#define dns_rdatatype_axfr\t" "((dns_rdatatype_t)dns_rdatatype_axfr)\n"); fprintf(stdout, "#define dns_rdatatype_mailb\t" "((dns_rdatatype_t)dns_rdatatype_mailb)\n"); fprintf(stdout, "#define dns_rdatatype_maila\t" "((dns_rdatatype_t)dns_rdatatype_maila)\n"); fprintf(stdout, "#define dns_rdatatype_any\t" "((dns_rdatatype_t)dns_rdatatype_any)\n"); fprintf(stdout, "\n#endif /* DNS_ENUMTYPE_H */\n"); } else if (class_enum) { char *s; int classnum; fprintf(stdout, "#ifndef DNS_ENUMCLASS_H\n"); fprintf(stdout, "#define DNS_ENUMCLASS_H 1\n\n"); fprintf(stdout, "enum {\n"); fprintf(stdout, "\tdns_rdataclass_reserved0 = 0,\n"); fprintf(stdout, "#define dns_rdataclass_reserved0 \\\n\t\t\t\t" "((dns_rdataclass_t)dns_rdataclass_reserved0)\n"); #define PRINTCLASS(name, num) \ do { \ s = funname(name, buf1); \ classnum = num; \ fprintf(stdout, "\tdns_rdataclass_%s = %d%s\n", s, classnum, \ classnum != 255 ? "," : ""); \ fprintf(stdout, "#define dns_rdataclass_%s\t" \ "((dns_rdataclass_t)dns_rdataclass_%s)\n", s, s); \ } while (0) for (cc = classes; cc != NULL; cc = cc->next) { if (cc->rdclass == 3) PRINTCLASS("chaos", 3); else if (cc->rdclass == 255) PRINTCLASS("none", 254); PRINTCLASS(cc->classname, cc->rdclass); } #undef PRINTCLASS fprintf(stdout, "};\n\n"); fprintf(stdout, "#endif /* DNS_ENUMCLASS_H */\n"); } else if (structs) { if (prefix != NULL) { if ((fd = fopen(prefix,"r")) != NULL) { while (fgets(buf, sizeof(buf), fd) != NULL) fputs(buf, stdout); fclose(fd); } } for (tt = types; tt != NULL; tt = tt->next) { snprintf(buf, sizeof(buf), "%s/%s_%d.h", tt->dirname, tt->typename, tt->type); if ((fd = fopen(buf,"r")) != NULL) { while (fgets(buf, sizeof(buf), fd) != NULL) fputs(buf, stdout); fclose(fd); } } if (suffix != NULL) { if ((fd = fopen(suffix,"r")) != NULL) { while (fgets(buf, sizeof(buf), fd) != NULL) fputs(buf, stdout); fclose(fd); } } } else if (depend) { for (tt = types; tt != NULL; tt = tt->next) fprintf(stdout, "%s:\t%s/%s_%d.h\n", file, tt->dirname, tt->typename, tt->type); } if (ferror(stdout) != 0) exit(1); return (0); } bind9-9.10.3.dfsg.P4/lib/dns/rdata.c0000644000470500017500000014512412664710322016171 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define RETERR(x) \ do { \ isc_result_t _r = (x); \ if (_r != ISC_R_SUCCESS) \ return (_r); \ } while (0) #define RETTOK(x) \ do { \ isc_result_t _r = (x); \ if (_r != ISC_R_SUCCESS) { \ isc_lex_ungettoken(lexer, &token); \ return (_r); \ } \ } while (0) #define DNS_AS_STR(t) ((t).value.as_textregion.base) #define ARGS_FROMTEXT int rdclass, dns_rdatatype_t type, \ isc_lex_t *lexer, dns_name_t *origin, \ unsigned int options, isc_buffer_t *target, \ dns_rdatacallbacks_t *callbacks #define ARGS_TOTEXT dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, \ isc_buffer_t *target #define ARGS_FROMWIRE int rdclass, dns_rdatatype_t type, \ isc_buffer_t *source, dns_decompress_t *dctx, \ unsigned int options, isc_buffer_t *target #define ARGS_TOWIRE dns_rdata_t *rdata, dns_compress_t *cctx, \ isc_buffer_t *target #define ARGS_COMPARE const dns_rdata_t *rdata1, const dns_rdata_t *rdata2 #define ARGS_FROMSTRUCT int rdclass, dns_rdatatype_t type, \ void *source, isc_buffer_t *target #define ARGS_TOSTRUCT dns_rdata_t *rdata, void *target, isc_mem_t *mctx #define ARGS_FREESTRUCT void *source #define ARGS_ADDLDATA dns_rdata_t *rdata, dns_additionaldatafunc_t add, \ void *arg #define ARGS_DIGEST dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg #define ARGS_CHECKOWNER dns_name_t *name, dns_rdataclass_t rdclass, \ dns_rdatatype_t type, isc_boolean_t wildcard #define ARGS_CHECKNAMES dns_rdata_t *rdata, dns_name_t *owner, dns_name_t *bad /*% * Context structure for the totext_ functions. * Contains formatting options for rdata-to-text * conversion. */ typedef struct dns_rdata_textctx { dns_name_t *origin; /*%< Current origin, or NULL. */ unsigned int flags; /*%< DNS_STYLEFLAG_* */ unsigned int width; /*%< Width of rdata column. */ const char *linebreak; /*%< Line break string. */ } dns_rdata_textctx_t; static isc_result_t txt_totext(isc_region_t *source, isc_boolean_t quote, isc_buffer_t *target); static isc_result_t txt_fromtext(isc_textregion_t *source, isc_buffer_t *target); static isc_result_t txt_fromwire(isc_buffer_t *source, isc_buffer_t *target); static isc_result_t multitxt_totext(isc_region_t *source, isc_buffer_t *target); static isc_result_t multitxt_fromtext(isc_textregion_t *source, isc_buffer_t *target); static isc_boolean_t name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target); static unsigned int name_length(dns_name_t *name); static isc_result_t str_totext(const char *source, isc_buffer_t *target); static isc_result_t inet_totext(int af, isc_region_t *src, isc_buffer_t *target); static isc_boolean_t buffer_empty(isc_buffer_t *source); static void buffer_fromregion(isc_buffer_t *buffer, isc_region_t *region); static isc_result_t uint32_tobuffer(isc_uint32_t, isc_buffer_t *target); static isc_result_t uint16_tobuffer(isc_uint32_t, isc_buffer_t *target); static isc_result_t uint8_tobuffer(isc_uint32_t, isc_buffer_t *target); static isc_result_t name_tobuffer(dns_name_t *name, isc_buffer_t *target); static isc_uint32_t uint32_fromregion(isc_region_t *region); static isc_uint16_t uint16_fromregion(isc_region_t *region); static isc_uint8_t uint8_fromregion(isc_region_t *region); static isc_uint8_t uint8_consume_fromregion(isc_region_t *region); static isc_result_t mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length); static int hexvalue(char value); static int decvalue(char value); static isc_result_t btoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target); static isc_result_t atob_tobuffer(isc_lex_t *lexer, isc_buffer_t *target); static void default_fromtext_callback(dns_rdatacallbacks_t *callbacks, const char *, ...) ISC_FORMAT_PRINTF(2, 3); static void fromtext_error(void (*callback)(dns_rdatacallbacks_t *, const char *, ...), dns_rdatacallbacks_t *callbacks, const char *name, unsigned long line, isc_token_t *token, isc_result_t result); static void fromtext_warneof(isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks); static isc_result_t rdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, isc_buffer_t *target); static void warn_badname(dns_name_t *name, isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks); static void warn_badmx(isc_token_t *token, isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks); static isc_uint16_t uint16_consume_fromregion(isc_region_t *region); static isc_result_t unknown_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, isc_buffer_t *target); /*% INT16 Size */ #define NS_INT16SZ 2 /*% IPv6 Address Size */ #define NS_LOCATORSZ 8 /* * Active Diretory gc._msdcs. prefix. */ static unsigned char gc_msdcs_data[] = "\002gc\006_msdcs"; static unsigned char gc_msdcs_offset [] = { 0, 3 }; static const dns_name_t gc_msdcs = { DNS_NAME_MAGIC, gc_msdcs_data, 10, 2, DNS_NAMEATTR_READONLY, gc_msdcs_offset, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} }; /*% * convert presentation level address to network order binary form. * \return * 1 if `src' is a valid [RFC1884 2.2] address, else 0. * \note * (1) does not touch `dst' unless it's returning 1. */ static inline int locator_pton(const char *src, unsigned char *dst) { static const char xdigits_l[] = "0123456789abcdef", xdigits_u[] = "0123456789ABCDEF"; unsigned char tmp[NS_LOCATORSZ]; unsigned char *tp = tmp, *endp; const char *xdigits; int ch, seen_xdigits; unsigned int val; memset(tp, '\0', NS_LOCATORSZ); endp = tp + NS_LOCATORSZ; seen_xdigits = 0; val = 0; while ((ch = *src++) != '\0') { const char *pch; pch = strchr((xdigits = xdigits_l), ch); if (pch == NULL) pch = strchr((xdigits = xdigits_u), ch); if (pch != NULL) { val <<= 4; val |= (pch - xdigits); if (++seen_xdigits > 4) return (0); continue; } if (ch == ':') { if (!seen_xdigits) return (0); if (tp + NS_INT16SZ > endp) return (0); *tp++ = (unsigned char) (val >> 8) & 0xff; *tp++ = (unsigned char) val & 0xff; seen_xdigits = 0; val = 0; continue; } return (0); } if (seen_xdigits) { if (tp + NS_INT16SZ > endp) return (0); *tp++ = (unsigned char) (val >> 8) & 0xff; *tp++ = (unsigned char) val & 0xff; } if (tp != endp) return (0); memmove(dst, tmp, NS_LOCATORSZ); return (1); } static inline int getquad(const void *src, struct in_addr *dst, isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks) { int result; struct in_addr *tmp; result = inet_aton(src, dst); if (result == 1 && callbacks != NULL && inet_pton(AF_INET, src, &tmp) != 1) { const char *name = isc_lex_getsourcename(lexer); if (name == NULL) name = "UNKNOWN"; (*callbacks->warn)(callbacks, "%s:%lu: \"%s\" " "is not a decimal dotted quad", name, isc_lex_getsourceline(lexer), src); } return (result); } static inline isc_result_t name_duporclone(dns_name_t *source, isc_mem_t *mctx, dns_name_t *target) { if (mctx != NULL) return (dns_name_dup(source, mctx, target)); dns_name_clone(source, target); return (ISC_R_SUCCESS); } static inline void * mem_maybedup(isc_mem_t *mctx, void *source, size_t length) { void *copy; if (mctx == NULL) return (source); copy = isc_mem_allocate(mctx, length); if (copy != NULL) memmove(copy, source, length); return (copy); } static const char hexdigits[] = "0123456789abcdef"; static const char decdigits[] = "0123456789"; #include "code.h" #define META 0x0001 #define RESERVED 0x0002 /*** *** Initialization ***/ void dns_rdata_init(dns_rdata_t *rdata) { REQUIRE(rdata != NULL); rdata->data = NULL; rdata->length = 0; rdata->rdclass = 0; rdata->type = 0; rdata->flags = 0; ISC_LINK_INIT(rdata, link); /* ISC_LIST_INIT(rdata->list); */ } void dns_rdata_reset(dns_rdata_t *rdata) { REQUIRE(rdata != NULL); REQUIRE(!ISC_LINK_LINKED(rdata, link)); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); rdata->data = NULL; rdata->length = 0; rdata->rdclass = 0; rdata->type = 0; rdata->flags = 0; } /*** *** ***/ void dns_rdata_clone(const dns_rdata_t *src, dns_rdata_t *target) { REQUIRE(src != NULL); REQUIRE(target != NULL); REQUIRE(DNS_RDATA_INITIALIZED(target)); REQUIRE(DNS_RDATA_VALIDFLAGS(src)); REQUIRE(DNS_RDATA_VALIDFLAGS(target)); target->data = src->data; target->length = src->length; target->rdclass = src->rdclass; target->type = src->type; target->flags = src->flags; } /*** *** Comparisons ***/ int dns_rdata_compare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2) { int result = 0; isc_boolean_t use_default = ISC_FALSE; REQUIRE(rdata1 != NULL); REQUIRE(rdata2 != NULL); REQUIRE(rdata1->length == 0 || rdata1->data != NULL); REQUIRE(rdata2->length == 0 || rdata2->data != NULL); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1)); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2)); if (rdata1->rdclass != rdata2->rdclass) return (rdata1->rdclass < rdata2->rdclass ? -1 : 1); if (rdata1->type != rdata2->type) return (rdata1->type < rdata2->type ? -1 : 1); COMPARESWITCH if (use_default) { isc_region_t r1; isc_region_t r2; dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); result = isc_region_compare(&r1, &r2); } return (result); } int dns_rdata_casecompare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2) { int result = 0; isc_boolean_t use_default = ISC_FALSE; REQUIRE(rdata1 != NULL); REQUIRE(rdata2 != NULL); REQUIRE(rdata1->length == 0 || rdata1->data != NULL); REQUIRE(rdata2->length == 0 || rdata2->data != NULL); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1)); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2)); if (rdata1->rdclass != rdata2->rdclass) return (rdata1->rdclass < rdata2->rdclass ? -1 : 1); if (rdata1->type != rdata2->type) return (rdata1->type < rdata2->type ? -1 : 1); CASECOMPARESWITCH if (use_default) { isc_region_t r1; isc_region_t r2; dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); result = isc_region_compare(&r1, &r2); } return (result); } /*** *** Conversions ***/ void dns_rdata_fromregion(dns_rdata_t *rdata, dns_rdataclass_t rdclass, dns_rdatatype_t type, isc_region_t *r) { REQUIRE(rdata != NULL); REQUIRE(DNS_RDATA_INITIALIZED(rdata)); REQUIRE(r != NULL); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); rdata->data = r->base; rdata->length = r->length; rdata->rdclass = rdclass; rdata->type = type; rdata->flags = 0; } void dns_rdata_toregion(const dns_rdata_t *rdata, isc_region_t *r) { REQUIRE(rdata != NULL); REQUIRE(r != NULL); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); r->base = rdata->data; r->length = rdata->length; } isc_result_t dns_rdata_fromwire(dns_rdata_t *rdata, dns_rdataclass_t rdclass, dns_rdatatype_t type, isc_buffer_t *source, dns_decompress_t *dctx, unsigned int options, isc_buffer_t *target) { isc_result_t result = ISC_R_NOTIMPLEMENTED; isc_region_t region; isc_buffer_t ss; isc_buffer_t st; isc_boolean_t use_default = ISC_FALSE; isc_uint32_t activelength; unsigned int length; REQUIRE(dctx != NULL); if (rdata != NULL) { REQUIRE(DNS_RDATA_INITIALIZED(rdata)); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); } REQUIRE(source != NULL); REQUIRE(target != NULL); if (type == 0) return (DNS_R_FORMERR); ss = *source; st = *target; activelength = isc_buffer_activelength(source); INSIST(activelength < 65536); FROMWIRESWITCH if (use_default) { if (activelength > isc_buffer_availablelength(target)) result = ISC_R_NOSPACE; else { isc_buffer_putmem(target, isc_buffer_current(source), activelength); isc_buffer_forward(source, activelength); result = ISC_R_SUCCESS; } } /* * Reject any rdata that expands out to more than DNS_RDATA_MAXLENGTH * as we cannot transmit it. */ length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st); if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH) result = DNS_R_FORMERR; /* * We should have consumed all of our buffer. */ if (result == ISC_R_SUCCESS && !buffer_empty(source)) result = DNS_R_EXTRADATA; if (rdata != NULL && result == ISC_R_SUCCESS) { region.base = isc_buffer_used(&st); region.length = length; dns_rdata_fromregion(rdata, rdclass, type, ®ion); } if (result != ISC_R_SUCCESS) { *source = ss; *target = st; } return (result); } isc_result_t dns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx, isc_buffer_t *target) { isc_result_t result = ISC_R_NOTIMPLEMENTED; isc_boolean_t use_default = ISC_FALSE; isc_region_t tr; isc_buffer_t st; REQUIRE(rdata != NULL); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); /* * Some DynDNS meta-RRs have empty rdata. */ if ((rdata->flags & DNS_RDATA_UPDATE) != 0) { INSIST(rdata->length == 0); return (ISC_R_SUCCESS); } st = *target; TOWIRESWITCH if (use_default) { isc_buffer_availableregion(target, &tr); if (tr.length < rdata->length) return (ISC_R_NOSPACE); memmove(tr.base, rdata->data, rdata->length); isc_buffer_add(target, rdata->length); return (ISC_R_SUCCESS); } if (result != ISC_R_SUCCESS) { *target = st; INSIST(target->used < 65536); dns_compress_rollback(cctx, (isc_uint16_t)target->used); } return (result); } /* * If the binary data in 'src' is valid uncompressed wire format * rdata of class 'rdclass' and type 'type', return ISC_R_SUCCESS * and copy the validated rdata to 'dest'. Otherwise return an error. */ static isc_result_t rdata_validate(isc_buffer_t *src, isc_buffer_t *dest, dns_rdataclass_t rdclass, dns_rdatatype_t type) { dns_decompress_t dctx; isc_result_t result; dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE); isc_buffer_setactive(src, isc_buffer_usedlength(src)); result = dns_rdata_fromwire(NULL, rdclass, type, src, &dctx, 0, dest); dns_decompress_invalidate(&dctx); return (result); } static isc_result_t unknown_fromtext(dns_rdataclass_t rdclass, dns_rdatatype_t type, isc_lex_t *lexer, isc_mem_t *mctx, isc_buffer_t *target) { isc_result_t result; isc_buffer_t *buf = NULL; isc_token_t token; if (type == 0 || dns_rdatatype_ismeta(type)) return (DNS_R_METATYPE); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 65535U) return (ISC_R_RANGE); result = isc_buffer_allocate(mctx, &buf, token.value.as_ulong); if (result != ISC_R_SUCCESS) return (result); result = isc_hex_tobuffer(lexer, buf, (unsigned int)token.value.as_ulong); if (result != ISC_R_SUCCESS) goto failure; if (isc_buffer_usedlength(buf) != token.value.as_ulong) { result = ISC_R_UNEXPECTEDEND; goto failure; } if (dns_rdatatype_isknown(type)) { result = rdata_validate(buf, target, rdclass, type); } else { isc_region_t r; isc_buffer_usedregion(buf, &r); result = isc_buffer_copyregion(target, &r); } if (result != ISC_R_SUCCESS) goto failure; isc_buffer_free(&buf); return (ISC_R_SUCCESS); failure: isc_buffer_free(&buf); return (result); } isc_result_t dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass, dns_rdatatype_t type, isc_lex_t *lexer, dns_name_t *origin, unsigned int options, isc_mem_t *mctx, isc_buffer_t *target, dns_rdatacallbacks_t *callbacks) { isc_result_t result = ISC_R_NOTIMPLEMENTED; isc_region_t region; isc_buffer_t st; isc_token_t token; unsigned int lexoptions = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF | ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE; char *name; unsigned long line; void (*callback)(dns_rdatacallbacks_t *, const char *, ...); isc_result_t tresult; unsigned int length; isc_boolean_t unknown; REQUIRE(origin == NULL || dns_name_isabsolute(origin) == ISC_TRUE); if (rdata != NULL) { REQUIRE(DNS_RDATA_INITIALIZED(rdata)); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); } if (callbacks != NULL) { REQUIRE(callbacks->warn != NULL); REQUIRE(callbacks->error != NULL); } st = *target; if (callbacks != NULL) callback = callbacks->error; else callback = default_fromtext_callback; result = isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, ISC_FALSE); if (result != ISC_R_SUCCESS) { name = isc_lex_getsourcename(lexer); line = isc_lex_getsourceline(lexer); fromtext_error(callback, callbacks, name, line, NULL, result); return (result); } unknown = ISC_FALSE; if (token.type == isc_tokentype_string && strcmp(DNS_AS_STR(token), "\\#") == 0) { /* * If this is a TXT record '\#' could be a escaped '#'. * Look to see if the next token is a number and if so * treat it as a unknown record format. */ if (type == dns_rdatatype_txt) { result = isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE); if (result == ISC_R_SUCCESS) isc_lex_ungettoken(lexer, &token); } if (result == ISC_R_SUCCESS) { unknown = ISC_TRUE; result = unknown_fromtext(rdclass, type, lexer, mctx, target); } else options |= DNS_RDATA_UNKNOWNESCAPE; } else isc_lex_ungettoken(lexer, &token); if (!unknown) FROMTEXTSWITCH /* * Consume to end of line / file. * If not at end of line initially set error code. * Call callback via fromtext_error once if there was an error. */ do { name = isc_lex_getsourcename(lexer); line = isc_lex_getsourceline(lexer); tresult = isc_lex_gettoken(lexer, lexoptions, &token); if (tresult != ISC_R_SUCCESS) { if (result == ISC_R_SUCCESS) result = tresult; if (callback != NULL) fromtext_error(callback, callbacks, name, line, NULL, result); break; } else if (token.type != isc_tokentype_eol && token.type != isc_tokentype_eof) { if (result == ISC_R_SUCCESS) result = DNS_R_EXTRATOKEN; if (callback != NULL) { fromtext_error(callback, callbacks, name, line, &token, result); callback = NULL; } } else if (result != ISC_R_SUCCESS && callback != NULL) { fromtext_error(callback, callbacks, name, line, &token, result); break; } else { if (token.type == isc_tokentype_eof) fromtext_warneof(lexer, callbacks); break; } } while (1); length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st); if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH) result = ISC_R_NOSPACE; if (rdata != NULL && result == ISC_R_SUCCESS) { region.base = isc_buffer_used(&st); region.length = length; dns_rdata_fromregion(rdata, rdclass, type, ®ion); } if (result != ISC_R_SUCCESS) { *target = st; } return (result); } static isc_result_t unknown_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, isc_buffer_t *target) { isc_result_t result; char buf[sizeof("65535")]; isc_region_t sr; strlcpy(buf, "\\# ", sizeof(buf)); result = str_totext(buf, target); if (result != ISC_R_SUCCESS) return (result); dns_rdata_toregion(rdata, &sr); INSIST(sr.length < 65536); snprintf(buf, sizeof(buf), "%u", sr.length); result = str_totext(buf, target); if (result != ISC_R_SUCCESS) return (result); if (sr.length != 0U) { if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) result = str_totext(" ( ", target); else result = str_totext(" ", target); if (result != ISC_R_SUCCESS) return (result); if (tctx->width == 0) /* No splitting */ result = isc_hex_totext(&sr, 0, "", target); else result = isc_hex_totext(&sr, tctx->width - 2, tctx->linebreak, target); if (result == ISC_R_SUCCESS && (tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) result = str_totext(" )", target); } return (result); } static isc_result_t rdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, isc_buffer_t *target) { isc_result_t result = ISC_R_NOTIMPLEMENTED; isc_boolean_t use_default = ISC_FALSE; unsigned int cur; REQUIRE(rdata != NULL); REQUIRE(tctx->origin == NULL || dns_name_isabsolute(tctx->origin) == ISC_TRUE); /* * Some DynDNS meta-RRs have empty rdata. */ if ((rdata->flags & DNS_RDATA_UPDATE) != 0) { INSIST(rdata->length == 0); return (ISC_R_SUCCESS); } cur = isc_buffer_usedlength(target); TOTEXTSWITCH if (use_default || (result == ISC_R_NOTIMPLEMENTED)) { unsigned int u = isc_buffer_usedlength(target); INSIST(u >= cur); isc_buffer_subtract(target, u - cur); result = unknown_totext(rdata, tctx, target); } return (result); } isc_result_t dns_rdata_totext(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target) { dns_rdata_textctx_t tctx; REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); /* * Set up formatting options for single-line output. */ tctx.origin = origin; tctx.flags = 0; tctx.width = 60; tctx.linebreak = " "; return (rdata_totext(rdata, &tctx, target)); } isc_result_t dns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin, unsigned int flags, unsigned int width, unsigned int split_width, const char *linebreak, isc_buffer_t *target) { dns_rdata_textctx_t tctx; REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); /* * Set up formatting options for formatted output. */ tctx.origin = origin; tctx.flags = flags; if (split_width == 0xffffffff) tctx.width = width; else tctx.width = split_width; if ((flags & DNS_STYLEFLAG_MULTILINE) != 0) tctx.linebreak = linebreak; else { if (split_width == 0xffffffff) tctx.width = 60; /* Used for hex word length only. */ tctx.linebreak = " "; } return (rdata_totext(rdata, &tctx, target)); } isc_result_t dns_rdata_fromstruct(dns_rdata_t *rdata, dns_rdataclass_t rdclass, dns_rdatatype_t type, void *source, isc_buffer_t *target) { isc_result_t result = ISC_R_NOTIMPLEMENTED; isc_buffer_t st; isc_region_t region; isc_boolean_t use_default = ISC_FALSE; unsigned int length; REQUIRE(source != NULL); if (rdata != NULL) { REQUIRE(DNS_RDATA_INITIALIZED(rdata)); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); } st = *target; FROMSTRUCTSWITCH if (use_default) (void)NULL; length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st); if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH) result = ISC_R_NOSPACE; if (rdata != NULL && result == ISC_R_SUCCESS) { region.base = isc_buffer_used(&st); region.length = length; dns_rdata_fromregion(rdata, rdclass, type, ®ion); } if (result != ISC_R_SUCCESS) *target = st; return (result); } isc_result_t dns_rdata_tostruct(dns_rdata_t *rdata, void *target, isc_mem_t *mctx) { isc_result_t result = ISC_R_NOTIMPLEMENTED; isc_boolean_t use_default = ISC_FALSE; REQUIRE(rdata != NULL); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); TOSTRUCTSWITCH if (use_default) (void)NULL; return (result); } void dns_rdata_freestruct(void *source) { dns_rdatacommon_t *common = source; REQUIRE(source != NULL); FREESTRUCTSWITCH } isc_result_t dns_rdata_additionaldata(dns_rdata_t *rdata, dns_additionaldatafunc_t add, void *arg) { isc_result_t result = ISC_R_NOTIMPLEMENTED; isc_boolean_t use_default = ISC_FALSE; /* * Call 'add' for each name and type from 'rdata' which is subject to * additional section processing. */ REQUIRE(rdata != NULL); REQUIRE(add != NULL); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); ADDITIONALDATASWITCH /* No additional processing for unknown types */ if (use_default) result = ISC_R_SUCCESS; return (result); } isc_result_t dns_rdata_digest(dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg) { isc_result_t result = ISC_R_NOTIMPLEMENTED; isc_boolean_t use_default = ISC_FALSE; isc_region_t r; /* * Send 'rdata' in DNSSEC canonical form to 'digest'. */ REQUIRE(rdata != NULL); REQUIRE(digest != NULL); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); DIGESTSWITCH if (use_default) { dns_rdata_toregion(rdata, &r); result = (digest)(arg, &r); } return (result); } isc_boolean_t dns_rdata_checkowner(dns_name_t *name, dns_rdataclass_t rdclass, dns_rdatatype_t type, isc_boolean_t wildcard) { isc_boolean_t result; CHECKOWNERSWITCH return (result); } isc_boolean_t dns_rdata_checknames(dns_rdata_t *rdata, dns_name_t *owner, dns_name_t *bad) { isc_boolean_t result; CHECKNAMESSWITCH return (result); } unsigned int dns_rdatatype_attributes(dns_rdatatype_t type) { RDATATYPE_ATTRIBUTE_SW if (type >= (dns_rdatatype_t)128 && type < (dns_rdatatype_t)255) return (DNS_RDATATYPEATTR_UNKNOWN | DNS_RDATATYPEATTR_META); return (DNS_RDATATYPEATTR_UNKNOWN); } isc_result_t dns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source) { unsigned int hash; unsigned int n; unsigned char a, b; n = source->length; if (n == 0) return (DNS_R_UNKNOWN); a = tolower((unsigned char)source->base[0]); b = tolower((unsigned char)source->base[n - 1]); hash = ((a + n) * b) % 256; /* * This switch block is inlined via \#define, and will use "return" * to return a result to the caller if it is a valid (known) * rdatatype name. */ RDATATYPE_FROMTEXT_SW(hash, source->base, n, typep); if (source->length > 4 && source->length < (4 + sizeof("65000")) && strncasecmp("type", source->base, 4) == 0) { char buf[sizeof("65000")]; char *endp; unsigned int val; strncpy(buf, source->base + 4, source->length - 4); buf[source->length - 4] = '\0'; val = strtoul(buf, &endp, 10); if (*endp == '\0' && val <= 0xffff) { *typep = (dns_rdatatype_t)val; return (ISC_R_SUCCESS); } } return (DNS_R_UNKNOWN); } isc_result_t dns_rdatatype_totext(dns_rdatatype_t type, isc_buffer_t *target) { char buf[sizeof("TYPE65535")]; RDATATYPE_TOTEXT_SW snprintf(buf, sizeof(buf), "TYPE%u", type); return (str_totext(buf, target)); } void dns_rdatatype_format(dns_rdatatype_t rdtype, char *array, unsigned int size) { isc_result_t result; isc_buffer_t buf; if (size == 0U) return; isc_buffer_init(&buf, array, size); result = dns_rdatatype_totext(rdtype, &buf); /* * Null terminate. */ if (result == ISC_R_SUCCESS) { if (isc_buffer_availablelength(&buf) >= 1) isc_buffer_putuint8(&buf, 0); else result = ISC_R_NOSPACE; } if (result != ISC_R_SUCCESS) strlcpy(array, "", size); } /* * Private function. */ static unsigned int name_length(dns_name_t *name) { return (name->length); } static isc_result_t txt_totext(isc_region_t *source, isc_boolean_t quote, isc_buffer_t *target) { unsigned int tl; unsigned int n; unsigned char *sp; char *tp; isc_region_t region; isc_buffer_availableregion(target, ®ion); sp = source->base; tp = (char *)region.base; tl = region.length; n = *sp++; REQUIRE(n + 1 <= source->length); if (n == 0U) REQUIRE(quote == ISC_TRUE); if (quote) { if (tl < 1) return (ISC_R_NOSPACE); *tp++ = '"'; tl--; } while (n--) { /* * \DDD space (0x20) if not quoting. */ if (*sp < (quote ? 0x20 : 0x21) || *sp >= 0x7f) { if (tl < 4) return (ISC_R_NOSPACE); *tp++ = 0x5c; *tp++ = 0x30 + ((*sp / 100) % 10); *tp++ = 0x30 + ((*sp / 10) % 10); *tp++ = 0x30 + (*sp % 10); sp++; tl -= 4; continue; } /* * Escape double quote and backslash. If we are not * enclosing the string in double quotes also escape * at sign and semicolon. */ if (*sp == 0x22 || *sp == 0x5c || (!quote && (*sp == 0x40 || *sp == 0x3b))) { if (tl < 2) return (ISC_R_NOSPACE); *tp++ = '\\'; tl--; } if (tl < 1) return (ISC_R_NOSPACE); *tp++ = *sp++; tl--; } if (quote) { if (tl < 1) return (ISC_R_NOSPACE); *tp++ = '"'; tl--; } isc_buffer_add(target, (unsigned int)(tp - (char *)region.base)); isc_region_consume(source, *source->base + 1); return (ISC_R_SUCCESS); } static isc_result_t txt_fromtext(isc_textregion_t *source, isc_buffer_t *target) { isc_region_t tregion; isc_boolean_t escape; unsigned int n, nrem; char *s; unsigned char *t; int d; int c; isc_buffer_availableregion(target, &tregion); s = source->base; n = source->length; t = tregion.base; nrem = tregion.length; escape = ISC_FALSE; if (nrem < 1) return (ISC_R_NOSPACE); /* * Length byte. */ nrem--; t++; /* * Maximum text string length. */ if (nrem > 255) nrem = 255; while (n-- != 0) { c = (*s++) & 0xff; if (escape && (d = decvalue((char)c)) != -1) { c = d; if (n == 0) return (DNS_R_SYNTAX); n--; if ((d = decvalue(*s++)) != -1) c = c * 10 + d; else return (DNS_R_SYNTAX); if (n == 0) return (DNS_R_SYNTAX); n--; if ((d = decvalue(*s++)) != -1) c = c * 10 + d; else return (DNS_R_SYNTAX); if (c > 255) return (DNS_R_SYNTAX); } else if (!escape && c == '\\') { escape = ISC_TRUE; continue; } escape = ISC_FALSE; if (nrem == 0) return ((tregion.length <= 256U) ? ISC_R_NOSPACE : DNS_R_SYNTAX); *t++ = c; nrem--; } if (escape) return (DNS_R_SYNTAX); *tregion.base = (unsigned char)(t - tregion.base - 1); isc_buffer_add(target, *tregion.base + 1); return (ISC_R_SUCCESS); } static isc_result_t txt_fromwire(isc_buffer_t *source, isc_buffer_t *target) { unsigned int n; isc_region_t sregion; isc_region_t tregion; isc_buffer_activeregion(source, &sregion); if (sregion.length == 0) return (ISC_R_UNEXPECTEDEND); n = *sregion.base + 1; if (n > sregion.length) return (ISC_R_UNEXPECTEDEND); isc_buffer_availableregion(target, &tregion); if (n > tregion.length) return (ISC_R_NOSPACE); if (tregion.base != sregion.base) memmove(tregion.base, sregion.base, n); isc_buffer_forward(source, n); isc_buffer_add(target, n); return (ISC_R_SUCCESS); } /* * Conversion of TXT-like rdata fields without length limits. */ static isc_result_t multitxt_totext(isc_region_t *source, isc_buffer_t *target) { unsigned int tl; unsigned int n0, n; unsigned char *sp; char *tp; isc_region_t region; isc_buffer_availableregion(target, ®ion); sp = source->base; tp = (char *)region.base; tl = region.length; if (tl < 1) return (ISC_R_NOSPACE); *tp++ = '"'; tl--; do { n = source->length; n0 = source->length - 1; while (n--) { if (*sp < 0x20 || *sp >= 0x7f) { if (tl < 4) return (ISC_R_NOSPACE); *tp++ = 0x5c; *tp++ = 0x30 + ((*sp / 100) % 10); *tp++ = 0x30 + ((*sp / 10) % 10); *tp++ = 0x30 + (*sp % 10); sp++; tl -= 4; continue; } /* double quote, semi-colon, backslash */ if (*sp == 0x22 || *sp == 0x3b || *sp == 0x5c) { if (tl < 2) return (ISC_R_NOSPACE); *tp++ = '\\'; tl--; } if (tl < 1) return (ISC_R_NOSPACE); *tp++ = *sp++; tl--; } isc_region_consume(source, n0 + 1); } while (source->length != 0); if (tl < 1) return (ISC_R_NOSPACE); *tp++ = '"'; tl--; isc_buffer_add(target, (unsigned int)(tp - (char *)region.base)); return (ISC_R_SUCCESS); } static isc_result_t multitxt_fromtext(isc_textregion_t *source, isc_buffer_t *target) { isc_region_t tregion; isc_boolean_t escape; unsigned int n, nrem; char *s; unsigned char *t0, *t; int d; int c; s = source->base; n = source->length; escape = ISC_FALSE; do { isc_buffer_availableregion(target, &tregion); t0 = t = tregion.base; nrem = tregion.length; if (nrem < 1) return (ISC_R_NOSPACE); while (n != 0) { --n; c = (*s++) & 0xff; if (escape && (d = decvalue((char)c)) != -1) { c = d; if (n == 0) return (DNS_R_SYNTAX); n--; if ((d = decvalue(*s++)) != -1) c = c * 10 + d; else return (DNS_R_SYNTAX); if (n == 0) return (DNS_R_SYNTAX); n--; if ((d = decvalue(*s++)) != -1) c = c * 10 + d; else return (DNS_R_SYNTAX); if (c > 255) return (DNS_R_SYNTAX); } else if (!escape && c == '\\') { escape = ISC_TRUE; continue; } escape = ISC_FALSE; *t++ = c; nrem--; if (nrem == 0) break; } if (escape) return (DNS_R_SYNTAX); isc_buffer_add(target, (unsigned int)(t - t0)); } while (n != 0); return (ISC_R_SUCCESS); } static isc_boolean_t name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target) { int l1, l2; if (origin == NULL) goto return_false; if (dns_name_compare(origin, dns_rootname) == 0) goto return_false; if (!dns_name_issubdomain(name, origin)) goto return_false; l1 = dns_name_countlabels(name); l2 = dns_name_countlabels(origin); if (l1 == l2) goto return_false; /* Master files should be case preserving. */ dns_name_getlabelsequence(name, l1 - l2, l2, target); if (!dns_name_caseequal(origin, target)) goto return_false; dns_name_getlabelsequence(name, 0, l1 - l2, target); return (ISC_TRUE); return_false: *target = *name; return (ISC_FALSE); } static isc_result_t str_totext(const char *source, isc_buffer_t *target) { unsigned int l; isc_region_t region; isc_buffer_availableregion(target, ®ion); l = strlen(source); if (l > region.length) return (ISC_R_NOSPACE); memmove(region.base, source, l); isc_buffer_add(target, l); return (ISC_R_SUCCESS); } static isc_result_t inet_totext(int af, isc_region_t *src, isc_buffer_t *target) { char tmpbuf[64]; /* Note - inet_ntop doesn't do size checking on its input. */ if (inet_ntop(af, src->base, tmpbuf, sizeof(tmpbuf)) == NULL) return (ISC_R_NOSPACE); if (strlen(tmpbuf) > isc_buffer_availablelength(target)) return (ISC_R_NOSPACE); isc_buffer_putstr(target, tmpbuf); return (ISC_R_SUCCESS); } static isc_boolean_t buffer_empty(isc_buffer_t *source) { return((source->current == source->active) ? ISC_TRUE : ISC_FALSE); } static void buffer_fromregion(isc_buffer_t *buffer, isc_region_t *region) { isc_buffer_init(buffer, region->base, region->length); isc_buffer_add(buffer, region->length); isc_buffer_setactive(buffer, region->length); } static isc_result_t uint32_tobuffer(isc_uint32_t value, isc_buffer_t *target) { isc_region_t region; isc_buffer_availableregion(target, ®ion); if (region.length < 4) return (ISC_R_NOSPACE); isc_buffer_putuint32(target, value); return (ISC_R_SUCCESS); } static isc_result_t uint16_tobuffer(isc_uint32_t value, isc_buffer_t *target) { isc_region_t region; if (value > 0xffff) return (ISC_R_RANGE); isc_buffer_availableregion(target, ®ion); if (region.length < 2) return (ISC_R_NOSPACE); isc_buffer_putuint16(target, (isc_uint16_t)value); return (ISC_R_SUCCESS); } static isc_result_t uint8_tobuffer(isc_uint32_t value, isc_buffer_t *target) { isc_region_t region; if (value > 0xff) return (ISC_R_RANGE); isc_buffer_availableregion(target, ®ion); if (region.length < 1) return (ISC_R_NOSPACE); isc_buffer_putuint8(target, (isc_uint8_t)value); return (ISC_R_SUCCESS); } static isc_result_t name_tobuffer(dns_name_t *name, isc_buffer_t *target) { isc_region_t r; dns_name_toregion(name, &r); return (isc_buffer_copyregion(target, &r)); } static isc_uint32_t uint32_fromregion(isc_region_t *region) { isc_uint32_t value; REQUIRE(region->length >= 4); value = region->base[0] << 24; value |= region->base[1] << 16; value |= region->base[2] << 8; value |= region->base[3]; return(value); } static isc_uint16_t uint16_consume_fromregion(isc_region_t *region) { isc_uint16_t r = uint16_fromregion(region); isc_region_consume(region, 2); return r; } static isc_uint16_t uint16_fromregion(isc_region_t *region) { REQUIRE(region->length >= 2); return ((region->base[0] << 8) | region->base[1]); } static isc_uint8_t uint8_fromregion(isc_region_t *region) { REQUIRE(region->length >= 1); return (region->base[0]); } static isc_uint8_t uint8_consume_fromregion(isc_region_t *region) { isc_uint8_t r = uint8_fromregion(region); isc_region_consume(region, 1); return r; } static isc_result_t mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) { isc_region_t tr; isc_buffer_availableregion(target, &tr); if (length > tr.length) return (ISC_R_NOSPACE); if (tr.base != base) memmove(tr.base, base, length); isc_buffer_add(target, length); return (ISC_R_SUCCESS); } static int hexvalue(char value) { const char *s; unsigned char c; c = (unsigned char)value; if (!isascii(c)) return (-1); if (isupper(c)) c = tolower(c); if ((s = strchr(hexdigits, c)) == NULL) return (-1); return (int)(s - hexdigits); } static int decvalue(char value) { const char *s; /* * isascii() is valid for full range of int values, no need to * mask or cast. */ if (!isascii(value)) return (-1); if ((s = strchr(decdigits, value)) == NULL) return (-1); return (int)(s - decdigits); } static const char atob_digits[86] = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" \ "abcdefghijklmnopqrstu"; /* * Subroutines to convert between 8 bit binary bytes and printable ASCII. * Computes the number of bytes, and three kinds of simple checksums. * Incoming bytes are collected into 32-bit words, then printed in base 85: * exp(85,5) > exp(2,32) * The ASCII characters used are between '!' and 'u'; * 'z' encodes 32-bit zero; 'x' is used to mark the end of encoded data. * * Originally by Paul Rutter (philabs!per) and Joe Orost (petsd!joe) for * the atob/btoa programs, released with the compress program, in mod.sources. * Modified by Mike Schwartz 8/19/86 for use in BIND. * Modified to be re-entrant 3/2/99. */ struct state { isc_int32_t Ceor; isc_int32_t Csum; isc_int32_t Crot; isc_int32_t word; isc_int32_t bcount; }; #define Ceor state->Ceor #define Csum state->Csum #define Crot state->Crot #define word state->word #define bcount state->bcount #define times85(x) ((((((x<<2)+x)<<2)+x)<<2)+x) static isc_result_t byte_atob(int c, isc_buffer_t *target, struct state *state); static isc_result_t putbyte(int c, isc_buffer_t *, struct state *state); static isc_result_t byte_btoa(int c, isc_buffer_t *, struct state *state); /* * Decode ASCII-encoded byte c into binary representation and * place into *bufp, advancing bufp. */ static isc_result_t byte_atob(int c, isc_buffer_t *target, struct state *state) { const char *s; if (c == 'z') { if (bcount != 0) return(DNS_R_SYNTAX); else { RETERR(putbyte(0, target, state)); RETERR(putbyte(0, target, state)); RETERR(putbyte(0, target, state)); RETERR(putbyte(0, target, state)); } } else if ((s = strchr(atob_digits, c)) != NULL) { if (bcount == 0) { word = (isc_int32_t)(s - atob_digits); ++bcount; } else if (bcount < 4) { word = times85(word); word += (isc_int32_t)(s - atob_digits); ++bcount; } else { word = times85(word); word += (isc_int32_t)(s - atob_digits); RETERR(putbyte((word >> 24) & 0xff, target, state)); RETERR(putbyte((word >> 16) & 0xff, target, state)); RETERR(putbyte((word >> 8) & 0xff, target, state)); RETERR(putbyte(word & 0xff, target, state)); word = 0; bcount = 0; } } else return(DNS_R_SYNTAX); return(ISC_R_SUCCESS); } /* * Compute checksum info and place c into target. */ static isc_result_t putbyte(int c, isc_buffer_t *target, struct state *state) { isc_region_t tr; Ceor ^= c; Csum += c; Csum += 1; if ((Crot & 0x80000000)) { Crot <<= 1; Crot += 1; } else { Crot <<= 1; } Crot += c; isc_buffer_availableregion(target, &tr); if (tr.length < 1) return (ISC_R_NOSPACE); tr.base[0] = c; isc_buffer_add(target, 1); return (ISC_R_SUCCESS); } /* * Read the ASCII-encoded data from inbuf, of length inbuflen, and convert * it into T_UNSPEC (binary data) in outbuf, not to exceed outbuflen bytes; * outbuflen must be divisible by 4. (Note: this is because outbuf is filled * in 4 bytes at a time. If the actual data doesn't end on an even 4-byte * boundary, there will be no problem...it will be padded with 0 bytes, and * numbytes will indicate the correct number of bytes. The main point is * that since the buffer is filled in 4 bytes at a time, even if there is * not a full 4 bytes of data at the end, there has to be room to 0-pad the * data, so the buffer must be of size divisible by 4). Place the number of * output bytes in numbytes, and return a failure/success status. */ static isc_result_t atob_tobuffer(isc_lex_t *lexer, isc_buffer_t *target) { long oeor, osum, orot; struct state statebuf, *state= &statebuf; isc_token_t token; char c; char *e; Ceor = Csum = Crot = word = bcount = 0; RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); while (token.value.as_textregion.length != 0) { if ((c = token.value.as_textregion.base[0]) == 'x') { break; } else RETERR(byte_atob(c, target, state)); isc_textregion_consume(&token.value.as_textregion, 1); } /* * Number of bytes. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if ((token.value.as_ulong % 4) != 0U) { unsigned long padding = 4 - (token.value.as_ulong % 4); if (isc_buffer_usedlength(target) < padding) return (DNS_R_SYNTAX); isc_buffer_subtract(target, padding); } /* * Checksum. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); oeor = strtol(DNS_AS_STR(token), &e, 16); if (*e != 0) return (DNS_R_SYNTAX); /* * Checksum. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); osum = strtol(DNS_AS_STR(token), &e, 16); if (*e != 0) return (DNS_R_SYNTAX); /* * Checksum. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); orot = strtol(DNS_AS_STR(token), &e, 16); if (*e != 0) return (DNS_R_SYNTAX); if ((oeor != Ceor) || (osum != Csum) || (orot != Crot)) return(DNS_R_BADCKSUM); return (ISC_R_SUCCESS); } /* * Encode binary byte c into ASCII representation and place into *bufp, * advancing bufp. */ static isc_result_t byte_btoa(int c, isc_buffer_t *target, struct state *state) { isc_region_t tr; isc_buffer_availableregion(target, &tr); Ceor ^= c; Csum += c; Csum += 1; if ((Crot & 0x80000000)) { Crot <<= 1; Crot += 1; } else { Crot <<= 1; } Crot += c; word <<= 8; word |= c; if (bcount == 3) { if (word == 0) { if (tr.length < 1) return (ISC_R_NOSPACE); tr.base[0] = 'z'; isc_buffer_add(target, 1); } else { register int tmp = 0; register isc_int32_t tmpword = word; if (tmpword < 0) { /* * Because some don't support u_long. */ tmp = 32; tmpword -= (isc_int32_t)(85 * 85 * 85 * 85 * 32); } if (tmpword < 0) { tmp = 64; tmpword -= (isc_int32_t)(85 * 85 * 85 * 85 * 32); } if (tr.length < 5) return (ISC_R_NOSPACE); tr.base[0] = atob_digits[(tmpword / (isc_int32_t)(85 * 85 * 85 * 85)) + tmp]; tmpword %= (isc_int32_t)(85 * 85 * 85 * 85); tr.base[1] = atob_digits[tmpword / (85 * 85 * 85)]; tmpword %= (85 * 85 * 85); tr.base[2] = atob_digits[tmpword / (85 * 85)]; tmpword %= (85 * 85); tr.base[3] = atob_digits[tmpword / 85]; tmpword %= 85; tr.base[4] = atob_digits[tmpword]; isc_buffer_add(target, 5); } bcount = 0; } else { bcount += 1; } return (ISC_R_SUCCESS); } /* * Encode the binary data from inbuf, of length inbuflen, into a * target. Return success/failure status */ static isc_result_t btoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target) { int inc; struct state statebuf, *state = &statebuf; char buf[sizeof("x 2000000000 ffffffff ffffffff ffffffff")]; Ceor = Csum = Crot = word = bcount = 0; for (inc = 0; inc < inbuflen; inbuf++, inc++) RETERR(byte_btoa(*inbuf, target, state)); while (bcount != 0) RETERR(byte_btoa(0, target, state)); /* * Put byte count and checksum information at end of buffer, * delimited by 'x' */ snprintf(buf, sizeof(buf), "x %d %x %x %x", inbuflen, Ceor, Csum, Crot); return (str_totext(buf, target)); } static void default_fromtext_callback(dns_rdatacallbacks_t *callbacks, const char *fmt, ...) { va_list ap; UNUSED(callbacks); va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); fprintf(stderr, "\n"); } static void fromtext_warneof(isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks) { if (isc_lex_isfile(lexer) && callbacks != NULL) { const char *name = isc_lex_getsourcename(lexer); if (name == NULL) name = "UNKNOWN"; (*callbacks->warn)(callbacks, "%s:%lu: file does not end with newline", name, isc_lex_getsourceline(lexer)); } } static void warn_badmx(isc_token_t *token, isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks) { const char *file; unsigned long line; if (lexer != NULL) { file = isc_lex_getsourcename(lexer); line = isc_lex_getsourceline(lexer); (*callbacks->warn)(callbacks, "%s:%u: warning: '%s': %s", file, line, DNS_AS_STR(*token), dns_result_totext(DNS_R_MXISADDRESS)); } } static void warn_badname(dns_name_t *name, isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks) { const char *file; unsigned long line; char namebuf[DNS_NAME_FORMATSIZE]; if (lexer != NULL) { file = isc_lex_getsourcename(lexer); line = isc_lex_getsourceline(lexer); dns_name_format(name, namebuf, sizeof(namebuf)); (*callbacks->warn)(callbacks, "%s:%u: warning: %s: %s", file, line, namebuf, dns_result_totext(DNS_R_BADNAME)); } } static void fromtext_error(void (*callback)(dns_rdatacallbacks_t *, const char *, ...), dns_rdatacallbacks_t *callbacks, const char *name, unsigned long line, isc_token_t *token, isc_result_t result) { if (name == NULL) name = "UNKNOWN"; if (token != NULL) { switch (token->type) { case isc_tokentype_eol: (*callback)(callbacks, "%s: %s:%lu: near eol: %s", "dns_rdata_fromtext", name, line, dns_result_totext(result)); break; case isc_tokentype_eof: (*callback)(callbacks, "%s: %s:%lu: near eof: %s", "dns_rdata_fromtext", name, line, dns_result_totext(result)); break; case isc_tokentype_number: (*callback)(callbacks, "%s: %s:%lu: near %lu: %s", "dns_rdata_fromtext", name, line, token->value.as_ulong, dns_result_totext(result)); break; case isc_tokentype_string: case isc_tokentype_qstring: (*callback)(callbacks, "%s: %s:%lu: near '%s': %s", "dns_rdata_fromtext", name, line, DNS_AS_STR(*token), dns_result_totext(result)); break; default: (*callback)(callbacks, "%s: %s:%lu: %s", "dns_rdata_fromtext", name, line, dns_result_totext(result)); break; } } else { (*callback)(callbacks, "dns_rdata_fromtext: %s:%lu: %s", name, line, dns_result_totext(result)); } } dns_rdatatype_t dns_rdata_covers(dns_rdata_t *rdata) { if (rdata->type == 46) return (covers_rrsig(rdata)); return (covers_sig(rdata)); } isc_boolean_t dns_rdatatype_ismeta(dns_rdatatype_t type) { if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_META) != 0) return (ISC_TRUE); return (ISC_FALSE); } isc_boolean_t dns_rdatatype_issingleton(dns_rdatatype_t type) { if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_SINGLETON) != 0) return (ISC_TRUE); return (ISC_FALSE); } isc_boolean_t dns_rdatatype_notquestion(dns_rdatatype_t type) { if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_NOTQUESTION) != 0) return (ISC_TRUE); return (ISC_FALSE); } isc_boolean_t dns_rdatatype_questiononly(dns_rdatatype_t type) { if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_QUESTIONONLY) != 0) return (ISC_TRUE); return (ISC_FALSE); } isc_boolean_t dns_rdatatype_atparent(dns_rdatatype_t type) { if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_ATPARENT) != 0) return (ISC_TRUE); return (ISC_FALSE); } isc_boolean_t dns_rdataclass_ismeta(dns_rdataclass_t rdclass) { if (rdclass == dns_rdataclass_reserved0 || rdclass == dns_rdataclass_none || rdclass == dns_rdataclass_any) return (ISC_TRUE); return (ISC_FALSE); /* Assume it is not a meta class. */ } isc_boolean_t dns_rdatatype_isdnssec(dns_rdatatype_t type) { if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_DNSSEC) != 0) return (ISC_TRUE); return (ISC_FALSE); } isc_boolean_t dns_rdatatype_iszonecutauth(dns_rdatatype_t type) { if ((dns_rdatatype_attributes(type) & (DNS_RDATATYPEATTR_DNSSEC | DNS_RDATATYPEATTR_ZONECUTAUTH)) != 0) return (ISC_TRUE); return (ISC_FALSE); } isc_boolean_t dns_rdatatype_isknown(dns_rdatatype_t type) { if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_UNKNOWN) == 0) return (ISC_TRUE); return (ISC_FALSE); } void dns_rdata_exists(dns_rdata_t *rdata, dns_rdatatype_t type) { REQUIRE(rdata != NULL); REQUIRE(DNS_RDATA_INITIALIZED(rdata)); rdata->data = NULL; rdata->length = 0; rdata->flags = DNS_RDATA_UPDATE; rdata->type = type; rdata->rdclass = dns_rdataclass_any; } void dns_rdata_notexist(dns_rdata_t *rdata, dns_rdatatype_t type) { REQUIRE(rdata != NULL); REQUIRE(DNS_RDATA_INITIALIZED(rdata)); rdata->data = NULL; rdata->length = 0; rdata->flags = DNS_RDATA_UPDATE; rdata->type = type; rdata->rdclass = dns_rdataclass_none; } void dns_rdata_deleterrset(dns_rdata_t *rdata, dns_rdatatype_t type) { REQUIRE(rdata != NULL); REQUIRE(DNS_RDATA_INITIALIZED(rdata)); rdata->data = NULL; rdata->length = 0; rdata->flags = DNS_RDATA_UPDATE; rdata->type = type; rdata->rdclass = dns_rdataclass_any; } void dns_rdata_makedelete(dns_rdata_t *rdata) { REQUIRE(rdata != NULL); rdata->rdclass = dns_rdataclass_none; } const char * dns_rdata_updateop(dns_rdata_t *rdata, dns_section_t section) { REQUIRE(rdata != NULL); REQUIRE(DNS_RDATA_INITIALIZED(rdata)); switch (section) { case DNS_SECTION_PREREQUISITE: switch (rdata->rdclass) { case dns_rdataclass_none: switch (rdata->type) { case dns_rdatatype_any: return ("domain doesn't exist"); default: return ("rrset doesn't exist"); } case dns_rdataclass_any: switch (rdata->type) { case dns_rdatatype_any: return ("domain exists"); default: return ("rrset exists (value independent)"); } default: return ("rrset exists (value dependent)"); } case DNS_SECTION_UPDATE: switch (rdata->rdclass) { case dns_rdataclass_none: return ("delete"); case dns_rdataclass_any: switch (rdata->type) { case dns_rdatatype_any: return ("delete all rrsets"); default: return ("delete rrset"); } default: return ("add"); } } return ("invalid"); } bind9-9.10.3.dfsg.P4/lib/dns/dbiterator.c0000644000470500017500000000664112664710322017235 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: dbiterator.c,v 1.18 2007/06/19 23:47:16 tbox Exp $ */ /*! \file */ #include #include #include #include void dns_dbiterator_destroy(dns_dbiterator_t **iteratorp) { /* * Destroy '*iteratorp'. */ REQUIRE(iteratorp != NULL); REQUIRE(DNS_DBITERATOR_VALID(*iteratorp)); (*iteratorp)->methods->destroy(iteratorp); ENSURE(*iteratorp == NULL); } isc_result_t dns_dbiterator_first(dns_dbiterator_t *iterator) { /* * Move the node cursor to the first node in the database (if any). */ REQUIRE(DNS_DBITERATOR_VALID(iterator)); return (iterator->methods->first(iterator)); } isc_result_t dns_dbiterator_last(dns_dbiterator_t *iterator) { /* * Move the node cursor to the first node in the database (if any). */ REQUIRE(DNS_DBITERATOR_VALID(iterator)); return (iterator->methods->last(iterator)); } isc_result_t dns_dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) { /* * Move the node cursor to the node with name 'name'. */ REQUIRE(DNS_DBITERATOR_VALID(iterator)); return (iterator->methods->seek(iterator, name)); } isc_result_t dns_dbiterator_prev(dns_dbiterator_t *iterator) { /* * Move the node cursor to the previous node in the database (if any). */ REQUIRE(DNS_DBITERATOR_VALID(iterator)); return (iterator->methods->prev(iterator)); } isc_result_t dns_dbiterator_next(dns_dbiterator_t *iterator) { /* * Move the node cursor to the next node in the database (if any). */ REQUIRE(DNS_DBITERATOR_VALID(iterator)); return (iterator->methods->next(iterator)); } isc_result_t dns_dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep, dns_name_t *name) { /* * Return the current node. */ REQUIRE(DNS_DBITERATOR_VALID(iterator)); REQUIRE(nodep != NULL && *nodep == NULL); REQUIRE(name == NULL || dns_name_hasbuffer(name)); return (iterator->methods->current(iterator, nodep, name)); } isc_result_t dns_dbiterator_pause(dns_dbiterator_t *iterator) { /* * Pause iteration. */ REQUIRE(DNS_DBITERATOR_VALID(iterator)); return (iterator->methods->pause(iterator)); } isc_result_t dns_dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) { /* * Return the origin to which returned node names are relative. */ REQUIRE(DNS_DBITERATOR_VALID(iterator)); REQUIRE(iterator->relative_names); REQUIRE(dns_name_hasbuffer(name)); return (iterator->methods->origin(iterator, name)); } void dns_dbiterator_setcleanmode(dns_dbiterator_t *iterator, isc_boolean_t mode) { REQUIRE(DNS_DBITERATOR_VALID(iterator)); iterator->cleaning = mode; } bind9-9.10.3.dfsg.P4/lib/dns/zt.c0000644000470500017500000003002412664710322015523 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include struct dns_zt { /* Unlocked. */ unsigned int magic; isc_mem_t *mctx; dns_rdataclass_t rdclass; isc_rwlock_t rwlock; dns_zt_allloaded_t loaddone; void * loaddone_arg; /* Locked by lock. */ isc_boolean_t flush; isc_uint32_t references; unsigned int loads_pending; dns_rbt_t *table; }; #define ZTMAGIC ISC_MAGIC('Z', 'T', 'b', 'l') #define VALID_ZT(zt) ISC_MAGIC_VALID(zt, ZTMAGIC) static void auto_detach(void *, void *); static isc_result_t load(dns_zone_t *zone, void *uap); static isc_result_t asyncload(dns_zone_t *zone, void *callback); static isc_result_t loadnew(dns_zone_t *zone, void *uap); static isc_result_t freezezones(dns_zone_t *zone, void *uap); static isc_result_t doneloading(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task); isc_result_t dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **ztp) { dns_zt_t *zt; isc_result_t result; REQUIRE(ztp != NULL && *ztp == NULL); zt = isc_mem_get(mctx, sizeof(*zt)); if (zt == NULL) return (ISC_R_NOMEMORY); zt->table = NULL; result = dns_rbt_create(mctx, auto_detach, zt, &zt->table); if (result != ISC_R_SUCCESS) goto cleanup_zt; result = isc_rwlock_init(&zt->rwlock, 0, 0); if (result != ISC_R_SUCCESS) goto cleanup_rbt; zt->mctx = NULL; isc_mem_attach(mctx, &zt->mctx); zt->references = 1; zt->flush = ISC_FALSE; zt->rdclass = rdclass; zt->magic = ZTMAGIC; zt->loaddone = NULL; zt->loaddone_arg = NULL; zt->loads_pending = 0; *ztp = zt; return (ISC_R_SUCCESS); cleanup_rbt: dns_rbt_destroy(&zt->table); cleanup_zt: isc_mem_put(mctx, zt, sizeof(*zt)); return (result); } isc_result_t dns_zt_mount(dns_zt_t *zt, dns_zone_t *zone) { isc_result_t result; dns_zone_t *dummy = NULL; dns_name_t *name; REQUIRE(VALID_ZT(zt)); name = dns_zone_getorigin(zone); RWLOCK(&zt->rwlock, isc_rwlocktype_write); result = dns_rbt_addname(zt->table, name, zone); if (result == ISC_R_SUCCESS) dns_zone_attach(zone, &dummy); RWUNLOCK(&zt->rwlock, isc_rwlocktype_write); return (result); } isc_result_t dns_zt_unmount(dns_zt_t *zt, dns_zone_t *zone) { isc_result_t result; dns_name_t *name; REQUIRE(VALID_ZT(zt)); name = dns_zone_getorigin(zone); RWLOCK(&zt->rwlock, isc_rwlocktype_write); result = dns_rbt_deletename(zt->table, name, ISC_FALSE); RWUNLOCK(&zt->rwlock, isc_rwlocktype_write); return (result); } isc_result_t dns_zt_find(dns_zt_t *zt, dns_name_t *name, unsigned int options, dns_name_t *foundname, dns_zone_t **zonep) { isc_result_t result; dns_zone_t *dummy = NULL; unsigned int rbtoptions = 0; REQUIRE(VALID_ZT(zt)); if ((options & DNS_ZTFIND_NOEXACT) != 0) rbtoptions |= DNS_RBTFIND_NOEXACT; RWLOCK(&zt->rwlock, isc_rwlocktype_read); result = dns_rbt_findname(zt->table, name, rbtoptions, foundname, (void **) (void*)&dummy); if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) dns_zone_attach(dummy, zonep); RWUNLOCK(&zt->rwlock, isc_rwlocktype_read); return (result); } void dns_zt_attach(dns_zt_t *zt, dns_zt_t **ztp) { REQUIRE(VALID_ZT(zt)); REQUIRE(ztp != NULL && *ztp == NULL); RWLOCK(&zt->rwlock, isc_rwlocktype_write); INSIST(zt->references > 0); zt->references++; INSIST(zt->references != 0); RWUNLOCK(&zt->rwlock, isc_rwlocktype_write); *ztp = zt; } static isc_result_t flush(dns_zone_t *zone, void *uap) { UNUSED(uap); return (dns_zone_flush(zone)); } static void zt_destroy(dns_zt_t *zt) { if (zt->flush) (void)dns_zt_apply(zt, ISC_FALSE, flush, NULL); dns_rbt_destroy(&zt->table); isc_rwlock_destroy(&zt->rwlock); zt->magic = 0; isc_mem_putanddetach(&zt->mctx, zt, sizeof(*zt)); } static void zt_flushanddetach(dns_zt_t **ztp, isc_boolean_t need_flush) { isc_boolean_t destroy = ISC_FALSE; dns_zt_t *zt; REQUIRE(ztp != NULL && VALID_ZT(*ztp)); zt = *ztp; RWLOCK(&zt->rwlock, isc_rwlocktype_write); INSIST(zt->references > 0); zt->references--; if (zt->references == 0) destroy = ISC_TRUE; if (need_flush) zt->flush = ISC_TRUE; RWUNLOCK(&zt->rwlock, isc_rwlocktype_write); if (destroy) zt_destroy(zt); *ztp = NULL; } void dns_zt_flushanddetach(dns_zt_t **ztp) { zt_flushanddetach(ztp, ISC_TRUE); } void dns_zt_detach(dns_zt_t **ztp) { zt_flushanddetach(ztp, ISC_FALSE); } isc_result_t dns_zt_load(dns_zt_t *zt, isc_boolean_t stop) { isc_result_t result; REQUIRE(VALID_ZT(zt)); RWLOCK(&zt->rwlock, isc_rwlocktype_read); result = dns_zt_apply(zt, stop, load, NULL); RWUNLOCK(&zt->rwlock, isc_rwlocktype_read); return (result); } static isc_result_t load(dns_zone_t *zone, void *uap) { isc_result_t result; UNUSED(uap); result = dns_zone_load(zone); if (result == DNS_R_CONTINUE || result == DNS_R_UPTODATE) result = ISC_R_SUCCESS; return (result); } isc_result_t dns_zt_asyncload(dns_zt_t *zt, dns_zt_allloaded_t alldone, void *arg) { isc_result_t result; static dns_zt_zoneloaded_t dl = doneloading; int pending; REQUIRE(VALID_ZT(zt)); RWLOCK(&zt->rwlock, isc_rwlocktype_write); INSIST(zt->loads_pending == 0); result = dns_zt_apply2(zt, ISC_FALSE, NULL, asyncload, &dl); pending = zt->loads_pending; if (pending != 0) { zt->loaddone = alldone; zt->loaddone_arg = arg; } RWUNLOCK(&zt->rwlock, isc_rwlocktype_write); if (pending == 0) alldone(arg); return (result); } /* * Initiates asynchronous loading of zone 'zone'. 'callback' is a * pointer to a function which will be used to inform the caller when * the zone loading is complete. */ static isc_result_t asyncload(dns_zone_t *zone, void *callback) { isc_result_t result; dns_zt_zoneloaded_t *loaded = callback; dns_zt_t *zt; REQUIRE(zone != NULL); zt = dns_zone_getview(zone)->zonetable; INSIST(VALID_ZT(zt)); INSIST(zt->references > 0); zt->references++; zt->loads_pending++; result = dns_zone_asyncload(zone, *loaded, zt); if (result != ISC_R_SUCCESS) { zt->references--; zt->loads_pending--; INSIST(zt->references > 0); } return (ISC_R_SUCCESS); } isc_result_t dns_zt_loadnew(dns_zt_t *zt, isc_boolean_t stop) { isc_result_t result; REQUIRE(VALID_ZT(zt)); RWLOCK(&zt->rwlock, isc_rwlocktype_read); result = dns_zt_apply(zt, stop, loadnew, NULL); RWUNLOCK(&zt->rwlock, isc_rwlocktype_read); return (result); } static isc_result_t loadnew(dns_zone_t *zone, void *uap) { isc_result_t result; UNUSED(uap); result = dns_zone_loadnew(zone); if (result == DNS_R_CONTINUE || result == DNS_R_UPTODATE || result == DNS_R_DYNAMIC) result = ISC_R_SUCCESS; return (result); } isc_result_t dns_zt_freezezones(dns_zt_t *zt, isc_boolean_t freeze) { isc_result_t result, tresult; REQUIRE(VALID_ZT(zt)); RWLOCK(&zt->rwlock, isc_rwlocktype_read); result = dns_zt_apply2(zt, ISC_FALSE, &tresult, freezezones, &freeze); RWUNLOCK(&zt->rwlock, isc_rwlocktype_read); if (tresult == ISC_R_NOTFOUND) tresult = ISC_R_SUCCESS; return ((result == ISC_R_SUCCESS) ? tresult : result); } static isc_result_t freezezones(dns_zone_t *zone, void *uap) { isc_boolean_t freeze = *(isc_boolean_t *)uap; isc_boolean_t frozen; isc_result_t result = ISC_R_SUCCESS; char classstr[DNS_RDATACLASS_FORMATSIZE]; char zonename[DNS_NAME_FORMATSIZE]; dns_zone_t *raw = NULL; dns_view_t *view; const char *vname; const char *sep; int level; dns_zone_getraw(zone, &raw); if (raw != NULL) zone = raw; if (dns_zone_gettype(zone) != dns_zone_master) { if (raw != NULL) dns_zone_detach(&raw); return (ISC_R_SUCCESS); } if (!dns_zone_isdynamic(zone, ISC_TRUE)) { if (raw != NULL) dns_zone_detach(&raw); return (ISC_R_SUCCESS); } frozen = dns_zone_getupdatedisabled(zone); if (freeze) { if (frozen) result = DNS_R_FROZEN; if (result == ISC_R_SUCCESS) result = dns_zone_flush(zone); if (result == ISC_R_SUCCESS) dns_zone_setupdatedisabled(zone, freeze); } else { if (frozen) { result = dns_zone_loadandthaw(zone); if (result == DNS_R_CONTINUE || result == DNS_R_UPTODATE) result = ISC_R_SUCCESS; } } view = dns_zone_getview(zone); if (strcmp(view->name, "_bind") == 0 || strcmp(view->name, "_default") == 0) { vname = ""; sep = ""; } else { vname = view->name; sep = " "; } dns_rdataclass_format(dns_zone_getclass(zone), classstr, sizeof(classstr)); dns_name_format(dns_zone_getorigin(zone), zonename, sizeof(zonename)); level = (result != ISC_R_SUCCESS) ? ISC_LOG_ERROR : ISC_LOG_DEBUG(1); isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, level, "%s zone '%s/%s'%s%s: %s", freeze ? "freezing" : "thawing", zonename, classstr, sep, vname, isc_result_totext(result)); if (raw != NULL) dns_zone_detach(&raw); return (result); } isc_result_t dns_zt_apply(dns_zt_t *zt, isc_boolean_t stop, isc_result_t (*action)(dns_zone_t *, void *), void *uap) { return (dns_zt_apply2(zt, stop, NULL, action, uap)); } isc_result_t dns_zt_apply2(dns_zt_t *zt, isc_boolean_t stop, isc_result_t *sub, isc_result_t (*action)(dns_zone_t *, void *), void *uap) { dns_rbtnode_t *node; dns_rbtnodechain_t chain; isc_result_t result, tresult = ISC_R_SUCCESS; dns_zone_t *zone; REQUIRE(VALID_ZT(zt)); REQUIRE(action != NULL); dns_rbtnodechain_init(&chain, zt->mctx); result = dns_rbtnodechain_first(&chain, zt->table, NULL, NULL); if (result == ISC_R_NOTFOUND) { /* * The tree is empty. */ tresult = result; result = ISC_R_NOMORE; } while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) { result = dns_rbtnodechain_current(&chain, NULL, NULL, &node); if (result == ISC_R_SUCCESS) { zone = node->data; if (zone != NULL) result = (action)(zone, uap); if (result != ISC_R_SUCCESS && stop) { tresult = result; goto cleanup; /* don't break */ } else if (result != ISC_R_SUCCESS && tresult == ISC_R_SUCCESS) tresult = result; } result = dns_rbtnodechain_next(&chain, NULL, NULL); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; cleanup: dns_rbtnodechain_invalidate(&chain); if (sub != NULL) *sub = tresult; return (result); } /* * Decrement the loads_pending counter; when counter reaches * zero, call the loaddone callback that was initially set by * dns_zt_asyncload(). */ static isc_result_t doneloading(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task) { isc_boolean_t destroy = ISC_FALSE; dns_zt_allloaded_t alldone = NULL; void *arg = NULL; UNUSED(zone); UNUSED(task); REQUIRE(VALID_ZT(zt)); RWLOCK(&zt->rwlock, isc_rwlocktype_write); INSIST(zt->loads_pending != 0); INSIST(zt->references != 0); zt->references--; if (zt->references == 0) destroy = ISC_TRUE; zt->loads_pending--; if (zt->loads_pending == 0) { alldone = zt->loaddone; arg = zt->loaddone_arg; zt->loaddone = NULL; zt->loaddone_arg = NULL; } RWUNLOCK(&zt->rwlock, isc_rwlocktype_write); if (alldone != NULL) alldone(arg); if (destroy) zt_destroy(zt); return (ISC_R_SUCCESS); } /*** *** Private ***/ static void auto_detach(void *data, void *arg) { dns_zone_t *zone = data; UNUSED(arg); dns_zone_detach(&zone); } bind9-9.10.3.dfsg.P4/lib/dns/geoip.c0000644000470500017500000004636212664710322016205 0ustar lamontlamont/* * Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #include #include #include #include #include #include #ifndef WIN32 #include #else #ifndef _WINSOCKAPI_ #define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */ #endif #include #endif /* WIN32 */ #include #ifdef HAVE_GEOIP #include #include /* * This structure preserves state from the previous GeoIP lookup, * so that successive lookups for the same data from the same IP * address will not require repeated calls into the GeoIP library * to look up data in the database. This should improve performance * somewhat. * * For lookups in the City and Region databases, we preserve pointers * to the GeoIPRecord and GeoIPregion structures; these will need to be * freed by GeoIPRecord_delete() and GeoIPRegion_delete(). * * for lookups in ISP, AS, Org and Domain we prserve a pointer to * the returned name; these must be freed by free(). * * For lookups in Country we preserve a pointer to the text of * the country code, name, etc (we use a different pointer for this * than for the names returned by Org, ISP, etc, because those need * to be freed but country lookups do not). * * For lookups in Netspeed we preserve the returned ID. * * XXX: Currently this mechanism is only used for IPv4 lookups; the * family and addr6 fields are to be used IPv6 is added. */ typedef struct geoip_state { isc_uint16_t subtype; unsigned int family; isc_uint32_t ipnum; geoipv6_t ipnum6; GeoIPRecord *record; GeoIPRegion *region; const char *text; char *name; int id; isc_mem_t *mctx; } geoip_state_t; #ifdef ISC_PLATFORM_USETHREADS static isc_mutex_t key_mutex; static isc_boolean_t state_key_initialized = ISC_FALSE; static isc_thread_key_t state_key; static isc_once_t mutex_once = ISC_ONCE_INIT; static isc_mem_t *state_mctx = NULL; static void key_mutex_init(void) { RUNTIME_CHECK(isc_mutex_init(&key_mutex) == ISC_R_SUCCESS); } static void free_state(void *arg) { geoip_state_t *state = arg; if (state != NULL && state->record != NULL) GeoIPRecord_delete(state->record); if (state != NULL) isc_mem_putanddetach(&state->mctx, state, sizeof(geoip_state_t)); isc_thread_key_setspecific(state_key, NULL); } static isc_result_t state_key_init(void) { isc_result_t result; result = isc_once_do(&mutex_once, key_mutex_init); if (result != ISC_R_SUCCESS) return (result); if (!state_key_initialized) { LOCK(&key_mutex); if (!state_key_initialized) { int ret; if (state_mctx == NULL) result = isc_mem_create2(0, 0, &state_mctx, 0); if (result != ISC_R_SUCCESS) goto unlock; isc_mem_setname(state_mctx, "geoip_state", NULL); isc_mem_setdestroycheck(state_mctx, ISC_FALSE); ret = isc_thread_key_create(&state_key, free_state); if (ret == 0) state_key_initialized = ISC_TRUE; else result = ISC_R_FAILURE; } unlock: UNLOCK(&key_mutex); } return (result); } #else static geoip_state_t saved_state; #endif static void clean_state(geoip_state_t *state) { if (state == NULL) return; if (state->record != NULL) { GeoIPRecord_delete(state->record); state->record = NULL; } if (state->region != NULL) { GeoIPRegion_delete(state->region); state->region = NULL; } if (state->name != NULL) { free (state->name); state->name = NULL; } state->ipnum = 0; state->text = NULL; state->id = 0; } static isc_result_t set_state(unsigned int family, isc_uint32_t ipnum, const geoipv6_t *ipnum6, dns_geoip_subtype_t subtype, GeoIPRecord *record, GeoIPRegion *region, char *name, const char *text, int id) { geoip_state_t *state = NULL; #ifdef ISC_PLATFORM_USETHREADS isc_result_t result; result = state_key_init(); if (result != ISC_R_SUCCESS) return (result); state = (geoip_state_t *) isc_thread_key_getspecific(state_key); if (state == NULL) { state = (geoip_state_t *) isc_mem_get(state_mctx, sizeof(geoip_state_t)); if (state == NULL) return (ISC_R_NOMEMORY); memset(state, 0, sizeof(*state)); result = isc_thread_key_setspecific(state_key, state); if (result != ISC_R_SUCCESS) { isc_mem_put(state_mctx, state, sizeof(geoip_state_t)); return (result); } isc_mem_attach(state_mctx, &state->mctx); } else clean_state(state); #else state = &saved_state; clean_state(state); #endif if (family == AF_INET) state->ipnum = ipnum; else state->ipnum6 = *ipnum6; state->family = family; state->subtype = subtype; state->record = record; state->region = region; state->name = name; state->text = text; state->id = id; return (ISC_R_SUCCESS); } static geoip_state_t * get_state_for(unsigned int family, isc_uint32_t ipnum, const geoipv6_t *ipnum6) { geoip_state_t *state; #ifdef ISC_PLATFORM_USETHREADS isc_result_t result; result = state_key_init(); if (result != ISC_R_SUCCESS) return (NULL); state = (geoip_state_t *) isc_thread_key_getspecific(state_key); if (state == NULL) return (NULL); #else state = &saved_state; #endif if (state->family == family && ((state->family == AF_INET && state->ipnum == ipnum) || (state->family == AF_INET6 && ipnum6 != NULL && memcmp(state->ipnum6.s6_addr, ipnum6->s6_addr, 16) == 0))) return (state); return (NULL); } /* * Country lookups are performed if the previous lookup was from a * different IP address than the current, or was for a search of a * different subtype. */ static const char * country_lookup(GeoIP *db, dns_geoip_subtype_t subtype, unsigned int family, isc_uint32_t ipnum, const geoipv6_t *ipnum6) { geoip_state_t *prev_state = NULL; const char *text = NULL; REQUIRE(db != NULL); #ifndef HAVE_GEOIP_V6 /* no IPv6 support? give up now */ if (family == AF_INET6) return (NULL); #endif prev_state = get_state_for(family, ipnum, ipnum6); if (prev_state != NULL && prev_state->subtype == subtype) text = prev_state->text; if (text == NULL) { switch (subtype) { case dns_geoip_country_code: if (family == AF_INET) text = GeoIP_country_code_by_ipnum(db, ipnum); #ifdef HAVE_GEOIP_V6 else text = GeoIP_country_code_by_ipnum_v6(db, *ipnum6); #endif break; case dns_geoip_country_code3: if (family == AF_INET) text = GeoIP_country_code3_by_ipnum(db, ipnum); #ifdef HAVE_GEOIP_V6 else text = GeoIP_country_code3_by_ipnum_v6(db, *ipnum6); #endif break; case dns_geoip_country_name: if (family == AF_INET) text = GeoIP_country_name_by_ipnum(db, ipnum); #ifdef HAVE_GEOIP_V6 else text = GeoIP_country_name_by_ipnum_v6(db, *ipnum6); #endif break; default: INSIST(0); } set_state(family, ipnum, ipnum6, subtype, NULL, NULL, NULL, text, 0); } return (text); } static char * city_string(GeoIPRecord *record, dns_geoip_subtype_t subtype, int *maxlen) { const char *s; char *deconst; REQUIRE(record != NULL); REQUIRE(maxlen != NULL); /* Set '*maxlen' to the maximum length of this subtype, if any */ switch (subtype) { case dns_geoip_city_countrycode: case dns_geoip_city_region: case dns_geoip_city_continentcode: *maxlen = 2; break; case dns_geoip_city_countrycode3: *maxlen = 3; break; default: /* No fixed length; just use strcasecmp() for comparison */ *maxlen = 255; } switch (subtype) { case dns_geoip_city_countrycode: return (record->country_code); case dns_geoip_city_countrycode3: return (record->country_code3); case dns_geoip_city_countryname: return (record->country_name); case dns_geoip_city_region: return (record->region); case dns_geoip_city_regionname: s = GeoIP_region_name_by_code(record->country_code, record->region); DE_CONST(s, deconst); return (deconst); case dns_geoip_city_name: return (record->city); case dns_geoip_city_postalcode: return (record->postal_code); case dns_geoip_city_continentcode: return (record->continent_code); case dns_geoip_city_timezonecode: s = GeoIP_time_zone_by_country_and_region(record->country_code, record->region); DE_CONST(s, deconst); return (deconst); default: INSIST(0); } } static isc_boolean_t is_city(dns_geoip_subtype_t subtype) { switch (subtype) { case dns_geoip_city_countrycode: case dns_geoip_city_countrycode3: case dns_geoip_city_countryname: case dns_geoip_city_region: case dns_geoip_city_regionname: case dns_geoip_city_name: case dns_geoip_city_postalcode: case dns_geoip_city_continentcode: case dns_geoip_city_timezonecode: case dns_geoip_city_metrocode: case dns_geoip_city_areacode: return (ISC_TRUE); default: return (ISC_FALSE); } } /* * GeoIPRecord lookups are performed if the previous lookup was * from a different IP address than the current, or was for a search * outside the City database. */ static GeoIPRecord * city_lookup(GeoIP *db, dns_geoip_subtype_t subtype, unsigned int family, isc_uint32_t ipnum, const geoipv6_t *ipnum6) { GeoIPRecord *record = NULL; geoip_state_t *prev_state = NULL; REQUIRE(db != NULL); #ifndef HAVE_GEOIP_V6 /* no IPv6 support? give up now */ if (family == AF_INET6) return (NULL); #endif prev_state = get_state_for(family, ipnum, ipnum6); if (prev_state != NULL && is_city(prev_state->subtype)) record = prev_state->record; if (record == NULL) { if (family == AF_INET) record = GeoIP_record_by_ipnum(db, ipnum); #ifdef HAVE_GEOIP_V6 else record = GeoIP_record_by_ipnum_v6(db, *ipnum6); #endif if (record == NULL) return (NULL); set_state(family, ipnum, ipnum6, subtype, record, NULL, NULL, NULL, 0); } return (record); } static char * region_string(GeoIPRegion *region, dns_geoip_subtype_t subtype, int *maxlen) { const char *s; char *deconst; REQUIRE(region != NULL); REQUIRE(maxlen != NULL); switch (subtype) { case dns_geoip_region_countrycode: *maxlen = 2; return (region->country_code); case dns_geoip_region_code: *maxlen = 2; return (region->region); case dns_geoip_region_name: *maxlen = 255; s = GeoIP_region_name_by_code(region->country_code, region->region); DE_CONST(s, deconst); return (deconst); default: INSIST(0); } } static isc_boolean_t is_region(dns_geoip_subtype_t subtype) { switch (subtype) { case dns_geoip_region_countrycode: case dns_geoip_region_code: return (ISC_TRUE); default: return (ISC_FALSE); } } /* * GeoIPRegion lookups are performed if the previous lookup was * from a different IP address than the current, or was for a search * outside the Region database. */ static GeoIPRegion * region_lookup(GeoIP *db, dns_geoip_subtype_t subtype, isc_uint32_t ipnum) { GeoIPRegion *region = NULL; geoip_state_t *prev_state = NULL; REQUIRE(db != NULL); prev_state = get_state_for(AF_INET, ipnum, NULL); if (prev_state != NULL && is_region(prev_state->subtype)) region = prev_state->region; if (region == NULL) { region = GeoIP_region_by_ipnum(db, ipnum); if (region == NULL) return (NULL); set_state(AF_INET, ipnum, NULL, subtype, NULL, region, NULL, NULL, 0); } return (region); } /* * ISP, Organization, AS Number and Domain lookups are performed if * the previous lookup was from a different IP address than the current, * or was for a search of a different subtype. */ static char * name_lookup(GeoIP *db, dns_geoip_subtype_t subtype, isc_uint32_t ipnum) { char *name = NULL; geoip_state_t *prev_state = NULL; REQUIRE(db != NULL); prev_state = get_state_for(AF_INET, ipnum, NULL); if (prev_state != NULL && prev_state->subtype == subtype) name = prev_state->name; if (name == NULL) { name = GeoIP_name_by_ipnum(db, ipnum); if (name == NULL) return (NULL); set_state(AF_INET, ipnum, NULL, subtype, NULL, NULL, name, NULL, 0); } return (name); } /* * Netspeed lookups are performed if the previous lookup was from a * different IP address than the current, or was for a search of a * different subtype. */ static int netspeed_lookup(GeoIP *db, dns_geoip_subtype_t subtype, isc_uint32_t ipnum) { geoip_state_t *prev_state = NULL; isc_boolean_t found = ISC_FALSE; int id = -1; REQUIRE(db != NULL); prev_state = get_state_for(AF_INET, ipnum, NULL); if (prev_state != NULL && prev_state->subtype == subtype) { id = prev_state->id; found = ISC_TRUE; } if (!found) { id = GeoIP_id_by_ipnum(db, ipnum); set_state(AF_INET, ipnum, NULL, subtype, NULL, NULL, NULL, NULL, id); } return (id); } #endif /* HAVE_GEOIP */ #define DB46(addr, geoip, name) \ ((addr->family == AF_INET) ? (geoip->name##_v4) : (geoip->name##_v6)) #ifdef HAVE_GEOIP /* * Find the best database to answer a generic subtype */ static dns_geoip_subtype_t fix_subtype(const isc_netaddr_t *reqaddr, const dns_geoip_databases_t *geoip, dns_geoip_subtype_t subtype) { dns_geoip_subtype_t ret = subtype; switch (subtype) { case dns_geoip_countrycode: if (DB46(reqaddr, geoip, city) != NULL) ret = dns_geoip_city_countrycode; else if (reqaddr->family == AF_INET && geoip->region != NULL) ret = dns_geoip_region_countrycode; else if (DB46(reqaddr, geoip, country) != NULL) ret = dns_geoip_country_code; break; case dns_geoip_countrycode3: if (DB46(reqaddr, geoip, city) != NULL) ret = dns_geoip_city_countrycode3; else if (DB46(reqaddr, geoip, country) != NULL) ret = dns_geoip_country_code3; break; case dns_geoip_countryname: if (DB46(reqaddr, geoip, city) != NULL) ret = dns_geoip_city_countryname; else if (DB46(reqaddr, geoip, country) != NULL) ret = dns_geoip_country_name; break; case dns_geoip_region: if (DB46(reqaddr, geoip, city) != NULL) ret = dns_geoip_city_region; else if (reqaddr->family == AF_INET && geoip->region != NULL) ret = dns_geoip_region_code; break; case dns_geoip_regionname: if (DB46(reqaddr, geoip, city) != NULL) ret = dns_geoip_city_regionname; else if (reqaddr->family == AF_INET && geoip->region != NULL) ret = dns_geoip_region_name; break; default: break; } return (ret); } #endif /* HAVE_GEOIP */ isc_boolean_t dns_geoip_match(const isc_netaddr_t *reqaddr, const dns_geoip_databases_t *geoip, const dns_geoip_elem_t *elt) { #ifndef HAVE_GEOIP UNUSED(reqaddr); UNUSED(geoip); UNUSED(elt); return (ISC_FALSE); #else GeoIP *db; GeoIPRecord *record; GeoIPRegion *region; dns_geoip_subtype_t subtype; isc_uint32_t ipnum = 0; int maxlen = 0, id, family; const char *cs; char *s; #ifdef HAVE_GEOIP_V6 const geoipv6_t *ipnum6 = NULL; #else const void *ipnum6 = NULL; #endif INSIST(geoip != NULL); family = reqaddr->family; switch (family) { case AF_INET: ipnum = ntohl(reqaddr->type.in.s_addr); break; case AF_INET6: #ifdef HAVE_GEOIP_V6 ipnum6 = &reqaddr->type.in6; break; #else return (ISC_FALSE); #endif default: return (ISC_FALSE); } subtype = fix_subtype(reqaddr, geoip, elt->subtype); switch (subtype) { case dns_geoip_country_code: maxlen = 2; goto getcountry; case dns_geoip_country_code3: maxlen = 3; goto getcountry; case dns_geoip_country_name: maxlen = 255; getcountry: db = DB46(reqaddr, geoip, country); if (db == NULL) return (ISC_FALSE); INSIST(elt->as_string != NULL); cs = country_lookup(db, subtype, family, ipnum, ipnum6); if (cs != NULL && strncasecmp(elt->as_string, cs, maxlen) == 0) return (ISC_TRUE); break; case dns_geoip_city_countrycode: case dns_geoip_city_countrycode3: case dns_geoip_city_countryname: case dns_geoip_city_region: case dns_geoip_city_regionname: case dns_geoip_city_name: case dns_geoip_city_postalcode: case dns_geoip_city_continentcode: case dns_geoip_city_timezonecode: INSIST(elt->as_string != NULL); db = DB46(reqaddr, geoip, city); if (db == NULL) return (ISC_FALSE); record = city_lookup(db, subtype, family, ipnum, ipnum6); if (record == NULL) break; s = city_string(record, subtype, &maxlen); INSIST(maxlen != 0); if (s != NULL && strncasecmp(elt->as_string, s, maxlen) == 0) return (ISC_TRUE); break; case dns_geoip_city_metrocode: db = DB46(reqaddr, geoip, city); if (db == NULL) return (ISC_FALSE); record = city_lookup(db, subtype, family, ipnum, ipnum6); if (record == NULL) break; if (elt->as_int == record->metro_code) return (ISC_TRUE); break; case dns_geoip_city_areacode: db = DB46(reqaddr, geoip, city); if (db == NULL) return (ISC_FALSE); record = city_lookup(db, subtype, family, ipnum, ipnum6); if (record == NULL) break; if (elt->as_int == record->area_code) return (ISC_TRUE); break; case dns_geoip_region_countrycode: case dns_geoip_region_code: case dns_geoip_region_name: case dns_geoip_region: if (geoip->region == NULL) return (ISC_FALSE); INSIST(elt->as_string != NULL); /* Region DB is not supported for IPv6 */ if (family == AF_INET6) return (ISC_FALSE); region = region_lookup(geoip->region, subtype, ipnum); if (region == NULL) break; s = region_string(region, subtype, &maxlen); INSIST(maxlen != 0); if (s != NULL && strncasecmp(elt->as_string, s, maxlen) == 0) return (ISC_TRUE); break; case dns_geoip_isp_name: db = geoip->isp; goto getname; case dns_geoip_org_name: db = geoip->org; goto getname; case dns_geoip_as_asnum: db = geoip->as; goto getname; case dns_geoip_domain_name: db = geoip->domain; getname: if (db == NULL) return (ISC_FALSE); INSIST(elt->as_string != NULL); /* ISP, Org, AS, and Domain are not supported for IPv6 */ if (family == AF_INET6) return (ISC_FALSE); s = name_lookup(db, subtype, ipnum); if (s != NULL) { size_t l; if (strcasecmp(elt->as_string, s) == 0) return (ISC_TRUE); if (subtype != dns_geoip_as_asnum) break; /* * Just check if the ASNNNN value matches. */ l = strlen(elt->as_string); if (l > 0U && strchr(elt->as_string, ' ') == NULL && strncasecmp(elt->as_string, s, l) == 0 && s[l] == ' ') return (ISC_TRUE); } break; case dns_geoip_netspeed_id: INSIST(geoip->netspeed != NULL); /* Netspeed DB is not supported for IPv6 */ if (family == AF_INET6) return (ISC_FALSE); id = netspeed_lookup(geoip->netspeed, subtype, ipnum); if (id == elt->as_int) return (ISC_TRUE); break; case dns_geoip_countrycode: case dns_geoip_countrycode3: case dns_geoip_countryname: case dns_geoip_regionname: /* * If these were not remapped by fix_subtype(), * the database was unavailable. Always return false. */ break; default: INSIST(0); } return (ISC_FALSE); #endif } void dns_geoip_shutdown(void) { #ifdef HAVE_GEOIP GeoIP_cleanup(); #ifdef ISC_PLATFORM_USETHREADS if (state_mctx != NULL) isc_mem_detach(&state_mctx); #endif #else return; #endif } bind9-9.10.3.dfsg.P4/lib/dns/byaddr.c0000644000470500017500000001771412664710322016346 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: byaddr.c,v 1.41 2009/09/02 23:48:02 tbox Exp $ */ /*! \file */ #include #include #include #include #include /* Required for HP/UX (and others?) */ #include #include #include #include #include #include #include #include #include #include #include #include /* * XXXRTH We could use a static event... */ static char hex_digits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; isc_result_t dns_byaddr_createptrname(isc_netaddr_t *address, isc_boolean_t nibble, dns_name_t *name) { /* * We dropped bitstring labels, so all lookups will use nibbles. */ UNUSED(nibble); return (dns_byaddr_createptrname2(address, DNS_BYADDROPT_IPV6INT, name)); } isc_result_t dns_byaddr_createptrname2(isc_netaddr_t *address, unsigned int options, dns_name_t *name) { char textname[128]; unsigned char *bytes; int i; char *cp; isc_buffer_t buffer; unsigned int len; REQUIRE(address != NULL); /* * We create the text representation and then convert to a * dns_name_t. This is not maximally efficient, but it keeps all * of the knowledge of wire format in the dns_name_ routines. */ bytes = (unsigned char *)(&address->type); if (address->family == AF_INET) { (void)snprintf(textname, sizeof(textname), "%u.%u.%u.%u.in-addr.arpa.", (bytes[3] & 0xff), (bytes[2] & 0xff), (bytes[1] & 0xff), (bytes[0] & 0xff)); } else if (address->family == AF_INET6) { cp = textname; for (i = 15; i >= 0; i--) { *cp++ = hex_digits[bytes[i] & 0x0f]; *cp++ = '.'; *cp++ = hex_digits[(bytes[i] >> 4) & 0x0f]; *cp++ = '.'; } if ((options & DNS_BYADDROPT_IPV6INT) != 0) strcpy(cp, "ip6.int."); else strcpy(cp, "ip6.arpa."); } else return (ISC_R_NOTIMPLEMENTED); len = (unsigned int)strlen(textname); isc_buffer_init(&buffer, textname, len); isc_buffer_add(&buffer, len); return (dns_name_fromtext(name, &buffer, dns_rootname, 0, NULL)); } struct dns_byaddr { /* Unlocked. */ unsigned int magic; isc_mem_t * mctx; isc_mutex_t lock; dns_fixedname_t name; /* Locked by lock. */ unsigned int options; dns_lookup_t * lookup; isc_task_t * task; dns_byaddrevent_t * event; isc_boolean_t canceled; }; #define BYADDR_MAGIC ISC_MAGIC('B', 'y', 'A', 'd') #define VALID_BYADDR(b) ISC_MAGIC_VALID(b, BYADDR_MAGIC) #define MAX_RESTARTS 16 static inline isc_result_t copy_ptr_targets(dns_byaddr_t *byaddr, dns_rdataset_t *rdataset) { isc_result_t result; dns_name_t *name; dns_rdata_t rdata = DNS_RDATA_INIT; /* * The caller must be holding the byaddr's lock. */ result = dns_rdataset_first(rdataset); while (result == ISC_R_SUCCESS) { dns_rdata_ptr_t ptr; dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &ptr, NULL); if (result != ISC_R_SUCCESS) return (result); name = isc_mem_get(byaddr->mctx, sizeof(*name)); if (name == NULL) { dns_rdata_freestruct(&ptr); return (ISC_R_NOMEMORY); } dns_name_init(name, NULL); result = dns_name_dup(&ptr.ptr, byaddr->mctx, name); dns_rdata_freestruct(&ptr); if (result != ISC_R_SUCCESS) { isc_mem_put(byaddr->mctx, name, sizeof(*name)); return (ISC_R_NOMEMORY); } ISC_LIST_APPEND(byaddr->event->names, name, link); dns_rdata_reset(&rdata); result = dns_rdataset_next(rdataset); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; return (result); } static void lookup_done(isc_task_t *task, isc_event_t *event) { dns_byaddr_t *byaddr = event->ev_arg; dns_lookupevent_t *levent; isc_result_t result; REQUIRE(event->ev_type == DNS_EVENT_LOOKUPDONE); REQUIRE(VALID_BYADDR(byaddr)); REQUIRE(byaddr->task == task); UNUSED(task); levent = (dns_lookupevent_t *)event; if (levent->result == ISC_R_SUCCESS) { result = copy_ptr_targets(byaddr, levent->rdataset); byaddr->event->result = result; } else byaddr->event->result = levent->result; isc_event_free(&event); isc_task_sendanddetach(&byaddr->task, (isc_event_t **)&byaddr->event); } static void bevent_destroy(isc_event_t *event) { dns_byaddrevent_t *bevent; dns_name_t *name, *next_name; isc_mem_t *mctx; REQUIRE(event->ev_type == DNS_EVENT_BYADDRDONE); mctx = event->ev_destroy_arg; bevent = (dns_byaddrevent_t *)event; for (name = ISC_LIST_HEAD(bevent->names); name != NULL; name = next_name) { next_name = ISC_LIST_NEXT(name, link); ISC_LIST_UNLINK(bevent->names, name, link); dns_name_free(name, mctx); isc_mem_put(mctx, name, sizeof(*name)); } isc_mem_put(mctx, event, event->ev_size); } isc_result_t dns_byaddr_create(isc_mem_t *mctx, isc_netaddr_t *address, dns_view_t *view, unsigned int options, isc_task_t *task, isc_taskaction_t action, void *arg, dns_byaddr_t **byaddrp) { isc_result_t result; dns_byaddr_t *byaddr; isc_event_t *ievent; byaddr = isc_mem_get(mctx, sizeof(*byaddr)); if (byaddr == NULL) return (ISC_R_NOMEMORY); byaddr->mctx = NULL; isc_mem_attach(mctx, &byaddr->mctx); byaddr->options = options; byaddr->event = isc_mem_get(mctx, sizeof(*byaddr->event)); if (byaddr->event == NULL) { result = ISC_R_NOMEMORY; goto cleanup_byaddr; } ISC_EVENT_INIT(byaddr->event, sizeof(*byaddr->event), 0, NULL, DNS_EVENT_BYADDRDONE, action, arg, byaddr, bevent_destroy, mctx); byaddr->event->result = ISC_R_FAILURE; ISC_LIST_INIT(byaddr->event->names); byaddr->task = NULL; isc_task_attach(task, &byaddr->task); result = isc_mutex_init(&byaddr->lock); if (result != ISC_R_SUCCESS) goto cleanup_event; dns_fixedname_init(&byaddr->name); result = dns_byaddr_createptrname2(address, options, dns_fixedname_name(&byaddr->name)); if (result != ISC_R_SUCCESS) goto cleanup_lock; byaddr->lookup = NULL; result = dns_lookup_create(mctx, dns_fixedname_name(&byaddr->name), dns_rdatatype_ptr, view, 0, task, lookup_done, byaddr, &byaddr->lookup); if (result != ISC_R_SUCCESS) goto cleanup_lock; byaddr->canceled = ISC_FALSE; byaddr->magic = BYADDR_MAGIC; *byaddrp = byaddr; return (ISC_R_SUCCESS); cleanup_lock: DESTROYLOCK(&byaddr->lock); cleanup_event: ievent = (isc_event_t *)byaddr->event; isc_event_free(&ievent); byaddr->event = NULL; isc_task_detach(&byaddr->task); cleanup_byaddr: isc_mem_putanddetach(&mctx, byaddr, sizeof(*byaddr)); return (result); } void dns_byaddr_cancel(dns_byaddr_t *byaddr) { REQUIRE(VALID_BYADDR(byaddr)); LOCK(&byaddr->lock); if (!byaddr->canceled) { byaddr->canceled = ISC_TRUE; if (byaddr->lookup != NULL) dns_lookup_cancel(byaddr->lookup); } UNLOCK(&byaddr->lock); } void dns_byaddr_destroy(dns_byaddr_t **byaddrp) { dns_byaddr_t *byaddr; REQUIRE(byaddrp != NULL); byaddr = *byaddrp; REQUIRE(VALID_BYADDR(byaddr)); REQUIRE(byaddr->event == NULL); REQUIRE(byaddr->task == NULL); dns_lookup_destroy(&byaddr->lookup); DESTROYLOCK(&byaddr->lock); byaddr->magic = 0; isc_mem_putanddetach(&byaddr->mctx, byaddr, sizeof(*byaddr)); *byaddrp = NULL; } bind9-9.10.3.dfsg.P4/lib/dns/validator.c0000644000470500017500000034037112664710322017064 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /*! \file * \brief * Basic processing sequences. * * \li When called with rdataset and sigrdataset: * validator_start -> validate -> proveunsecure -> startfinddlvsep -> * dlv_validator_start -> validator_start -> validate -> proveunsecure * * validator_start -> validate -> nsecvalidate (secure wildcard answer) * * \li When called with rdataset, sigrdataset and with DNS_VALIDATOR_DLV: * validator_start -> startfinddlvsep -> dlv_validator_start -> * validator_start -> validate -> proveunsecure * * \li When called with rdataset: * validator_start -> proveunsecure -> startfinddlvsep -> * dlv_validator_start -> validator_start -> proveunsecure * * \li When called with rdataset and with DNS_VALIDATOR_DLV: * validator_start -> startfinddlvsep -> dlv_validator_start -> * validator_start -> proveunsecure * * \li When called without a rdataset: * validator_start -> nsecvalidate -> proveunsecure -> startfinddlvsep -> * dlv_validator_start -> validator_start -> nsecvalidate -> proveunsecure * * Note: there isn't a case for DNS_VALIDATOR_DLV here as we want nsecvalidate() * to always validate the authority section even when it does not contain * signatures. * * validator_start: determines what type of validation to do. * validate: attempts to perform a positive validation. * proveunsecure: attempts to prove the answer comes from a unsecure zone. * nsecvalidate: attempts to prove a negative response. * startfinddlvsep: starts the DLV record lookup. * dlv_validator_start: resets state and restarts the lookup using the * DLV RRset found by startfinddlvsep. */ #define VALIDATOR_MAGIC ISC_MAGIC('V', 'a', 'l', '?') #define VALID_VALIDATOR(v) ISC_MAGIC_VALID(v, VALIDATOR_MAGIC) #define VALATTR_SHUTDOWN 0x0001 /*%< Shutting down. */ #define VALATTR_CANCELED 0x0002 /*%< Canceled. */ #define VALATTR_TRIEDVERIFY 0x0004 /*%< We have found a key and * have attempted a verify. */ #define VALATTR_INSECURITY 0x0010 /*%< Attempting proveunsecure. */ #define VALATTR_DLVTRIED 0x0020 /*%< Looked for a DLV record. */ /*! * NSEC proofs to be looked for. */ #define VALATTR_NEEDNOQNAME 0x00000100 #define VALATTR_NEEDNOWILDCARD 0x00000200 #define VALATTR_NEEDNODATA 0x00000400 /*! * NSEC proofs that have been found. */ #define VALATTR_FOUNDNOQNAME 0x00001000 #define VALATTR_FOUNDNOWILDCARD 0x00002000 #define VALATTR_FOUNDNODATA 0x00004000 #define VALATTR_FOUNDCLOSEST 0x00008000 /* * */ #define VALATTR_FOUNDOPTOUT 0x00010000 #define VALATTR_FOUNDUNKNOWN 0x00020000 #define NEEDNODATA(val) ((val->attributes & VALATTR_NEEDNODATA) != 0) #define NEEDNOQNAME(val) ((val->attributes & VALATTR_NEEDNOQNAME) != 0) #define NEEDNOWILDCARD(val) ((val->attributes & VALATTR_NEEDNOWILDCARD) != 0) #define DLVTRIED(val) ((val->attributes & VALATTR_DLVTRIED) != 0) #define FOUNDNODATA(val) ((val->attributes & VALATTR_FOUNDNODATA) != 0) #define FOUNDNOQNAME(val) ((val->attributes & VALATTR_FOUNDNOQNAME) != 0) #define FOUNDNOWILDCARD(val) ((val->attributes & VALATTR_FOUNDNOWILDCARD) != 0) #define FOUNDCLOSEST(val) ((val->attributes & VALATTR_FOUNDCLOSEST) != 0) #define FOUNDOPTOUT(val) ((val->attributes & VALATTR_FOUNDOPTOUT) != 0) #define SHUTDOWN(v) (((v)->attributes & VALATTR_SHUTDOWN) != 0) #define CANCELED(v) (((v)->attributes & VALATTR_CANCELED) != 0) #define NEGATIVE(r) (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) static void destroy(dns_validator_t *val); static isc_result_t get_dst_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo, dns_rdataset_t *rdataset); static isc_result_t validate(dns_validator_t *val, isc_boolean_t resume); static isc_result_t validatezonekey(dns_validator_t *val); static isc_result_t nsecvalidate(dns_validator_t *val, isc_boolean_t resume); static isc_result_t proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume); static void validator_logv(dns_validator_t *val, isc_logcategory_t *category, isc_logmodule_t *module, int level, const char *fmt, va_list ap) ISC_FORMAT_PRINTF(5, 0); static void validator_log(void *val, int level, const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4); static void validator_logcreate(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type, const char *caller, const char *operation); static isc_result_t dlv_validatezonekey(dns_validator_t *val); static void dlv_validator_start(dns_validator_t *val); static isc_result_t finddlvsep(dns_validator_t *val, isc_boolean_t resume); static isc_result_t startfinddlvsep(dns_validator_t *val, dns_name_t *unsecure); /*% * Mark the RRsets as a answer. */ static inline void markanswer(dns_validator_t *val, const char *where) { validator_log(val, ISC_LOG_DEBUG(3), "marking as answer (%s)", where); if (val->event->rdataset != NULL) dns_rdataset_settrust(val->event->rdataset, dns_trust_answer); if (val->event->sigrdataset != NULL) dns_rdataset_settrust(val->event->sigrdataset, dns_trust_answer); } static inline void marksecure(dns_validatorevent_t *event) { dns_rdataset_settrust(event->rdataset, dns_trust_secure); if (event->sigrdataset != NULL) dns_rdataset_settrust(event->sigrdataset, dns_trust_secure); event->secure = ISC_TRUE; } static void validator_done(dns_validator_t *val, isc_result_t result) { isc_task_t *task; if (val->event == NULL) return; /* * Caller must be holding the lock. */ val->event->result = result; task = val->event->ev_sender; val->event->ev_sender = val; val->event->ev_type = DNS_EVENT_VALIDATORDONE; val->event->ev_action = val->action; val->event->ev_arg = val->arg; isc_task_sendanddetach(&task, (isc_event_t **)&val->event); } static inline isc_boolean_t exit_check(dns_validator_t *val) { /* * Caller must be holding the lock. */ if (!SHUTDOWN(val)) return (ISC_FALSE); INSIST(val->event == NULL); if (val->fetch != NULL || val->subvalidator != NULL) return (ISC_FALSE); return (ISC_TRUE); } /* * Check that we have atleast one supported algorithm in the DLV RRset. */ static inline isc_boolean_t dlv_algorithm_supported(dns_validator_t *val) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_dlv_t dlv; isc_result_t result; for (result = dns_rdataset_first(&val->dlv); result == ISC_R_SUCCESS; result = dns_rdataset_next(&val->dlv)) { dns_rdata_reset(&rdata); dns_rdataset_current(&val->dlv, &rdata); result = dns_rdata_tostruct(&rdata, &dlv, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (!dns_resolver_algorithm_supported(val->view->resolver, val->event->name, dlv.algorithm)) continue; if (!dns_resolver_ds_digest_supported(val->view->resolver, val->event->name, dlv.digest_type)) continue; return (ISC_TRUE); } return (ISC_FALSE); } /*% * Look in the NSEC record returned from a DS query to see if there is * a NS RRset at this name. If it is found we are at a delegation point. */ static isc_boolean_t isdelegation(dns_name_t *name, dns_rdataset_t *rdataset, isc_result_t dbresult) { dns_fixedname_t fixed; dns_label_t hashlabel; dns_name_t nsec3name; dns_rdata_nsec3_t nsec3; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_t set; int order; int scope; isc_boolean_t found; isc_buffer_t buffer; isc_result_t result; unsigned char hash[NSEC3_MAX_HASH_LENGTH]; unsigned char owner[NSEC3_MAX_HASH_LENGTH]; unsigned int length; REQUIRE(dbresult == DNS_R_NXRRSET || dbresult == DNS_R_NCACHENXRRSET); dns_rdataset_init(&set); if (dbresult == DNS_R_NXRRSET) dns_rdataset_clone(rdataset, &set); else { result = dns_ncache_getrdataset(rdataset, name, dns_rdatatype_nsec, &set); if (result == ISC_R_NOTFOUND) goto trynsec3; if (result != ISC_R_SUCCESS) return (ISC_FALSE); } INSIST(set.type == dns_rdatatype_nsec); found = ISC_FALSE; result = dns_rdataset_first(&set); if (result == ISC_R_SUCCESS) { dns_rdataset_current(&set, &rdata); found = dns_nsec_typepresent(&rdata, dns_rdatatype_ns); dns_rdata_reset(&rdata); } dns_rdataset_disassociate(&set); return (found); trynsec3: /* * Iterate over the ncache entry. */ found = ISC_FALSE; dns_name_init(&nsec3name, NULL); dns_fixedname_init(&fixed); dns_name_downcase(name, dns_fixedname_name(&fixed), NULL); name = dns_fixedname_name(&fixed); for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_ncache_current(rdataset, &nsec3name, &set); if (set.type != dns_rdatatype_nsec3) { dns_rdataset_disassociate(&set); continue; } dns_name_getlabel(&nsec3name, 0, &hashlabel); isc_region_consume(&hashlabel, 1); isc_buffer_init(&buffer, owner, sizeof(owner)); result = isc_base32hexnp_decoderegion(&hashlabel, &buffer); if (result != ISC_R_SUCCESS) { dns_rdataset_disassociate(&set); continue; } for (result = dns_rdataset_first(&set); result == ISC_R_SUCCESS; result = dns_rdataset_next(&set)) { dns_rdata_reset(&rdata); dns_rdataset_current(&set, &rdata); (void)dns_rdata_tostruct(&rdata, &nsec3, NULL); if (nsec3.hash != 1) continue; length = isc_iterated_hash(hash, nsec3.hash, nsec3.iterations, nsec3.salt, nsec3.salt_length, name->ndata, name->length); if (length != isc_buffer_usedlength(&buffer)) continue; order = memcmp(hash, owner, length); if (order == 0) { found = dns_nsec3_typepresent(&rdata, dns_rdatatype_ns); dns_rdataset_disassociate(&set); return (found); } if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) == 0) continue; /* * Does this optout span cover the name? */ scope = memcmp(owner, nsec3.next, nsec3.next_length); if ((scope < 0 && order > 0 && memcmp(hash, nsec3.next, length) < 0) || (scope >= 0 && (order > 0 || memcmp(hash, nsec3.next, length) < 0))) { dns_rdataset_disassociate(&set); return (ISC_TRUE); } } dns_rdataset_disassociate(&set); } return (found); } /*% * We have been asked to look for a key. * If found resume the validation process. * If not found fail the validation process. */ static void fetch_callback_validator(isc_task_t *task, isc_event_t *event) { dns_fetchevent_t *devent; dns_validator_t *val; dns_rdataset_t *rdataset; isc_boolean_t want_destroy; isc_result_t result; isc_result_t eresult; isc_result_t saved_result; dns_fetch_t *fetch; UNUSED(task); INSIST(event->ev_type == DNS_EVENT_FETCHDONE); devent = (dns_fetchevent_t *)event; val = devent->ev_arg; rdataset = &val->frdataset; eresult = devent->result; /* Free resources which are not of interest. */ if (devent->node != NULL) dns_db_detachnode(devent->db, &devent->node); if (devent->db != NULL) dns_db_detach(&devent->db); if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); isc_event_free(&event); INSIST(val->event != NULL); validator_log(val, ISC_LOG_DEBUG(3), "in fetch_callback_validator"); LOCK(&val->lock); fetch = val->fetch; val->fetch = NULL; if (CANCELED(val)) { validator_done(val, ISC_R_CANCELED); } else if (eresult == ISC_R_SUCCESS) { validator_log(val, ISC_LOG_DEBUG(3), "keyset with trust %s", dns_trust_totext(rdataset->trust)); /* * Only extract the dst key if the keyset is secure. */ if (rdataset->trust >= dns_trust_secure) { result = get_dst_key(val, val->siginfo, rdataset); if (result == ISC_R_SUCCESS) val->keyset = &val->frdataset; } result = validate(val, ISC_TRUE); if (result == DNS_R_NOVALIDSIG && (val->attributes & VALATTR_TRIEDVERIFY) == 0) { saved_result = result; validator_log(val, ISC_LOG_DEBUG(3), "falling back to insecurity proof"); val->attributes |= VALATTR_INSECURITY; result = proveunsecure(val, ISC_FALSE, ISC_FALSE); if (result == DNS_R_NOTINSECURE) result = saved_result; } if (result != DNS_R_WAIT) validator_done(val, result); } else { validator_log(val, ISC_LOG_DEBUG(3), "fetch_callback_validator: got %s", isc_result_totext(eresult)); if (eresult == ISC_R_CANCELED) validator_done(val, eresult); else validator_done(val, DNS_R_BROKENCHAIN); } want_destroy = exit_check(val); UNLOCK(&val->lock); if (fetch != NULL) dns_resolver_destroyfetch(&fetch); if (want_destroy) destroy(val); } /*% * We were asked to look for a DS record as part of following a key chain * upwards. If found resume the validation process. If not found fail the * validation process. */ static void dsfetched(isc_task_t *task, isc_event_t *event) { dns_fetchevent_t *devent; dns_validator_t *val; dns_rdataset_t *rdataset; isc_boolean_t want_destroy; isc_result_t result; isc_result_t eresult; dns_fetch_t *fetch; UNUSED(task); INSIST(event->ev_type == DNS_EVENT_FETCHDONE); devent = (dns_fetchevent_t *)event; val = devent->ev_arg; rdataset = &val->frdataset; eresult = devent->result; /* Free resources which are not of interest. */ if (devent->node != NULL) dns_db_detachnode(devent->db, &devent->node); if (devent->db != NULL) dns_db_detach(&devent->db); if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); isc_event_free(&event); INSIST(val->event != NULL); validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched"); LOCK(&val->lock); fetch = val->fetch; val->fetch = NULL; if (CANCELED(val)) { validator_done(val, ISC_R_CANCELED); } else if (eresult == ISC_R_SUCCESS) { validator_log(val, ISC_LOG_DEBUG(3), "dsset with trust %s", dns_trust_totext(rdataset->trust)); val->dsset = &val->frdataset; result = validatezonekey(val); if (result != DNS_R_WAIT) validator_done(val, result); } else if (eresult == DNS_R_CNAME || eresult == DNS_R_NXRRSET || eresult == DNS_R_NCACHENXRRSET || eresult == DNS_R_SERVFAIL) /* RFC 1034 parent? */ { validator_log(val, ISC_LOG_DEBUG(3), "falling back to insecurity proof (%s)", dns_result_totext(eresult)); val->attributes |= VALATTR_INSECURITY; result = proveunsecure(val, ISC_FALSE, ISC_FALSE); if (result != DNS_R_WAIT) validator_done(val, result); } else { validator_log(val, ISC_LOG_DEBUG(3), "dsfetched: got %s", isc_result_totext(eresult)); if (eresult == ISC_R_CANCELED) validator_done(val, eresult); else validator_done(val, DNS_R_BROKENCHAIN); } want_destroy = exit_check(val); UNLOCK(&val->lock); if (fetch != NULL) dns_resolver_destroyfetch(&fetch); if (want_destroy) destroy(val); } /*% * We were asked to look for the DS record as part of proving that a * name is unsecure. * * If the DS record doesn't exist and the query name corresponds to * a delegation point we are transitioning from a secure zone to a * unsecure zone. * * If the DS record exists it will be secure. We can continue looking * for the break point in the chain of trust. */ static void dsfetched2(isc_task_t *task, isc_event_t *event) { dns_fetchevent_t *devent; dns_validator_t *val; dns_name_t *tname; isc_boolean_t want_destroy; isc_result_t result; isc_result_t eresult; dns_fetch_t *fetch; UNUSED(task); INSIST(event->ev_type == DNS_EVENT_FETCHDONE); devent = (dns_fetchevent_t *)event; val = devent->ev_arg; eresult = devent->result; /* Free resources which are not of interest. */ if (devent->node != NULL) dns_db_detachnode(devent->db, &devent->node); if (devent->db != NULL) dns_db_detach(&devent->db); if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); INSIST(val->event != NULL); validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched2: %s", dns_result_totext(eresult)); LOCK(&val->lock); fetch = val->fetch; val->fetch = NULL; if (CANCELED(val)) { validator_done(val, ISC_R_CANCELED); } else if (eresult == DNS_R_CNAME || eresult == DNS_R_NXRRSET || eresult == DNS_R_NCACHENXRRSET) { /* * There is no DS. If this is a delegation, we're done. */ tname = dns_fixedname_name(&devent->foundname); if (eresult != DNS_R_CNAME && isdelegation(tname, &val->frdataset, eresult)) { if (val->mustbesecure) { validator_log(val, ISC_LOG_WARNING, "must be secure failure, no DS" " and this is a delegation"); validator_done(val, DNS_R_MUSTBESECURE); } else if (val->view->dlv == NULL || DLVTRIED(val)) { markanswer(val, "dsfetched2"); validator_done(val, ISC_R_SUCCESS); } else { result = startfinddlvsep(val, tname); if (result != DNS_R_WAIT) validator_done(val, result); } } else { result = proveunsecure(val, ISC_FALSE, ISC_TRUE); if (result != DNS_R_WAIT) validator_done(val, result); } } else if (eresult == ISC_R_SUCCESS || eresult == DNS_R_NXDOMAIN || eresult == DNS_R_NCACHENXDOMAIN) { /* * There is a DS which may or may not be a zone cut. * In either case we are still in a secure zone resume * validation. */ result = proveunsecure(val, ISC_TF(eresult == ISC_R_SUCCESS), ISC_TRUE); if (result != DNS_R_WAIT) validator_done(val, result); } else { if (eresult == ISC_R_CANCELED) validator_done(val, eresult); else validator_done(val, DNS_R_NOVALIDDS); } isc_event_free(&event); want_destroy = exit_check(val); UNLOCK(&val->lock); if (fetch != NULL) dns_resolver_destroyfetch(&fetch); if (want_destroy) destroy(val); } /*% * Callback from when a DNSKEY RRset has been validated. * * Resumes the stalled validation process. */ static void keyvalidated(isc_task_t *task, isc_event_t *event) { dns_validatorevent_t *devent; dns_validator_t *val; isc_boolean_t want_destroy; isc_result_t result; isc_result_t eresult; isc_result_t saved_result; UNUSED(task); INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE); devent = (dns_validatorevent_t *)event; val = devent->ev_arg; eresult = devent->result; isc_event_free(&event); dns_validator_destroy(&val->subvalidator); INSIST(val->event != NULL); validator_log(val, ISC_LOG_DEBUG(3), "in keyvalidated"); LOCK(&val->lock); if (CANCELED(val)) { validator_done(val, ISC_R_CANCELED); } else if (eresult == ISC_R_SUCCESS) { validator_log(val, ISC_LOG_DEBUG(3), "keyset with trust %s", dns_trust_totext(val->frdataset.trust)); /* * Only extract the dst key if the keyset is secure. */ if (val->frdataset.trust >= dns_trust_secure) (void) get_dst_key(val, val->siginfo, &val->frdataset); result = validate(val, ISC_TRUE); if (result == DNS_R_NOVALIDSIG && (val->attributes & VALATTR_TRIEDVERIFY) == 0) { saved_result = result; validator_log(val, ISC_LOG_DEBUG(3), "falling back to insecurity proof"); val->attributes |= VALATTR_INSECURITY; result = proveunsecure(val, ISC_FALSE, ISC_FALSE); if (result == DNS_R_NOTINSECURE) result = saved_result; } if (result != DNS_R_WAIT) validator_done(val, result); } else { if (eresult != DNS_R_BROKENCHAIN) { if (dns_rdataset_isassociated(&val->frdataset)) dns_rdataset_expire(&val->frdataset); if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_expire(&val->fsigrdataset); } validator_log(val, ISC_LOG_DEBUG(3), "keyvalidated: got %s", isc_result_totext(eresult)); validator_done(val, DNS_R_BROKENCHAIN); } want_destroy = exit_check(val); UNLOCK(&val->lock); if (want_destroy) destroy(val); } /*% * Callback when the DS record has been validated. * * Resumes validation of the zone key or the unsecure zone proof. */ static void dsvalidated(isc_task_t *task, isc_event_t *event) { dns_validatorevent_t *devent; dns_validator_t *val; isc_boolean_t want_destroy; isc_result_t result; isc_result_t eresult; UNUSED(task); INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE); devent = (dns_validatorevent_t *)event; val = devent->ev_arg; eresult = devent->result; isc_event_free(&event); dns_validator_destroy(&val->subvalidator); INSIST(val->event != NULL); validator_log(val, ISC_LOG_DEBUG(3), "in dsvalidated"); LOCK(&val->lock); if (CANCELED(val)) { validator_done(val, ISC_R_CANCELED); } else if (eresult == ISC_R_SUCCESS) { isc_boolean_t have_dsset; dns_name_t *name; validator_log(val, ISC_LOG_DEBUG(3), "%s with trust %s", val->frdataset.type == dns_rdatatype_ds ? "dsset" : "ds non-existance", dns_trust_totext(val->frdataset.trust)); have_dsset = ISC_TF(val->frdataset.type == dns_rdatatype_ds); name = dns_fixedname_name(&val->fname); if ((val->attributes & VALATTR_INSECURITY) != 0 && val->frdataset.covers == dns_rdatatype_ds && NEGATIVE(&val->frdataset) && isdelegation(name, &val->frdataset, DNS_R_NCACHENXRRSET)) { if (val->mustbesecure) { validator_log(val, ISC_LOG_WARNING, "must be secure failure, no DS " "and this is a delegation"); result = DNS_R_MUSTBESECURE; } else if (val->view->dlv == NULL || DLVTRIED(val)) { markanswer(val, "dsvalidated"); result = ISC_R_SUCCESS;; } else result = startfinddlvsep(val, name); } else if ((val->attributes & VALATTR_INSECURITY) != 0) { result = proveunsecure(val, have_dsset, ISC_TRUE); } else result = validatezonekey(val); if (result != DNS_R_WAIT) validator_done(val, result); } else { if (eresult != DNS_R_BROKENCHAIN) { if (dns_rdataset_isassociated(&val->frdataset)) dns_rdataset_expire(&val->frdataset); if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_expire(&val->fsigrdataset); } validator_log(val, ISC_LOG_DEBUG(3), "dsvalidated: got %s", isc_result_totext(eresult)); validator_done(val, DNS_R_BROKENCHAIN); } want_destroy = exit_check(val); UNLOCK(&val->lock); if (want_destroy) destroy(val); } /*% * Callback when the CNAME record has been validated. * * Resumes validation of the unsecure zone proof. */ static void cnamevalidated(isc_task_t *task, isc_event_t *event) { dns_validatorevent_t *devent; dns_validator_t *val; isc_boolean_t want_destroy; isc_result_t result; isc_result_t eresult; UNUSED(task); INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE); devent = (dns_validatorevent_t *)event; val = devent->ev_arg; eresult = devent->result; isc_event_free(&event); dns_validator_destroy(&val->subvalidator); INSIST(val->event != NULL); INSIST((val->attributes & VALATTR_INSECURITY) != 0); validator_log(val, ISC_LOG_DEBUG(3), "in cnamevalidated"); LOCK(&val->lock); if (CANCELED(val)) { validator_done(val, ISC_R_CANCELED); } else if (eresult == ISC_R_SUCCESS) { validator_log(val, ISC_LOG_DEBUG(3), "cname with trust %s", dns_trust_totext(val->frdataset.trust)); result = proveunsecure(val, ISC_FALSE, ISC_TRUE); if (result != DNS_R_WAIT) validator_done(val, result); } else { if (eresult != DNS_R_BROKENCHAIN) { if (dns_rdataset_isassociated(&val->frdataset)) dns_rdataset_expire(&val->frdataset); if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_expire(&val->fsigrdataset); } validator_log(val, ISC_LOG_DEBUG(3), "cnamevalidated: got %s", isc_result_totext(eresult)); validator_done(val, DNS_R_BROKENCHAIN); } want_destroy = exit_check(val); UNLOCK(&val->lock); if (want_destroy) destroy(val); } /*% * Callback for when NSEC records have been validated. * * Looks for NOQNAME, NODATA and OPTOUT proofs. * * Resumes nsecvalidate. */ static void authvalidated(isc_task_t *task, isc_event_t *event) { dns_validatorevent_t *devent; dns_validator_t *val; dns_rdataset_t *rdataset; isc_boolean_t want_destroy; isc_result_t result; isc_boolean_t exists, data; UNUSED(task); INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE); devent = (dns_validatorevent_t *)event; rdataset = devent->rdataset; val = devent->ev_arg; result = devent->result; dns_validator_destroy(&val->subvalidator); INSIST(val->event != NULL); validator_log(val, ISC_LOG_DEBUG(3), "in authvalidated"); LOCK(&val->lock); if (CANCELED(val)) { validator_done(val, ISC_R_CANCELED); } else if (result != ISC_R_SUCCESS) { validator_log(val, ISC_LOG_DEBUG(3), "authvalidated: got %s", isc_result_totext(result)); if (result == DNS_R_BROKENCHAIN) val->authfail++; if (result == ISC_R_CANCELED) validator_done(val, result); else { result = nsecvalidate(val, ISC_TRUE); if (result != DNS_R_WAIT) validator_done(val, result); } } else { dns_name_t **proofs = val->event->proofs; dns_name_t *wild = dns_fixedname_name(&val->wild); if (rdataset->trust == dns_trust_secure) val->seensig = ISC_TRUE; if (rdataset->type == dns_rdatatype_nsec && rdataset->trust == dns_trust_secure && (NEEDNODATA(val) || NEEDNOQNAME(val)) && !FOUNDNODATA(val) && !FOUNDNOQNAME(val) && dns_nsec_noexistnodata(val->event->type, val->event->name, devent->name, rdataset, &exists, &data, wild, validator_log, val) == ISC_R_SUCCESS) { if (exists && !data) { val->attributes |= VALATTR_FOUNDNODATA; if (NEEDNODATA(val)) proofs[DNS_VALIDATOR_NODATAPROOF] = devent->name; } if (!exists) { dns_name_t *closest; unsigned int clabels; val->attributes |= VALATTR_FOUNDNOQNAME; closest = dns_fixedname_name(&val->closest); clabels = dns_name_countlabels(closest); /* * If we are validating a wildcard response * clabels will not be zero. We then need * to check if the generated wilcard from * dns_nsec_noexistnodata is consistent with * the wildcard used to generate the response. */ if (clabels == 0 || dns_name_countlabels(wild) == clabels + 1) val->attributes |= VALATTR_FOUNDCLOSEST; /* * The NSEC noqname proof also contains * the closest encloser. */ if (NEEDNOQNAME(val)) proofs[DNS_VALIDATOR_NOQNAMEPROOF] = devent->name; } } result = nsecvalidate(val, ISC_TRUE); if (result != DNS_R_WAIT) validator_done(val, result); } want_destroy = exit_check(val); UNLOCK(&val->lock); if (want_destroy) destroy(val); /* * Free stuff from the event. */ isc_event_free(&event); } /*% * Looks for the requested name and type in the view (zones and cache). * * When looking for a DLV record also checks to make sure the NSEC record * returns covers the query name as part of aggressive negative caching. * * Returns: * \li ISC_R_SUCCESS * \li ISC_R_NOTFOUND * \li DNS_R_NCACHENXDOMAIN * \li DNS_R_NCACHENXRRSET * \li DNS_R_NXRRSET * \li DNS_R_NXDOMAIN * \li DNS_R_BROKENCHAIN */ static inline isc_result_t view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) { dns_fixedname_t fixedname; dns_name_t *foundname; dns_rdata_nsec_t nsec; dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; unsigned int options; isc_time_t now; char buf1[DNS_NAME_FORMATSIZE]; char buf2[DNS_NAME_FORMATSIZE]; char buf3[DNS_NAME_FORMATSIZE]; char namebuf[DNS_NAME_FORMATSIZE]; char typebuf[DNS_RDATATYPE_FORMATSIZE]; if (dns_rdataset_isassociated(&val->frdataset)) dns_rdataset_disassociate(&val->frdataset); if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); if (isc_time_now(&now) == ISC_R_SUCCESS && dns_resolver_getbadcache(val->view->resolver, name, type, &now)) { dns_name_format(name, namebuf, sizeof(namebuf)); dns_rdatatype_format(type, typebuf, sizeof(typebuf)); validator_log(val, ISC_LOG_INFO, "bad cache hit (%s/%s)", namebuf, typebuf); return (DNS_R_BROKENCHAIN); } options = DNS_DBFIND_PENDINGOK; if (type == dns_rdatatype_dlv) options |= DNS_DBFIND_COVERINGNSEC; dns_fixedname_init(&fixedname); foundname = dns_fixedname_name(&fixedname); result = dns_view_find(val->view, name, type, 0, options, ISC_FALSE, NULL, NULL, foundname, &val->frdataset, &val->fsigrdataset); if (result == DNS_R_NXDOMAIN) { if (dns_rdataset_isassociated(&val->frdataset)) dns_rdataset_disassociate(&val->frdataset); if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); } else if (result == DNS_R_COVERINGNSEC) { validator_log(val, ISC_LOG_DEBUG(3), "DNS_R_COVERINGNSEC"); /* * Check if the returned NSEC covers the name. */ INSIST(type == dns_rdatatype_dlv); if (val->frdataset.trust != dns_trust_secure) { validator_log(val, ISC_LOG_DEBUG(3), "covering nsec: trust %s", dns_trust_totext(val->frdataset.trust)); goto notfound; } result = dns_rdataset_first(&val->frdataset); if (result != ISC_R_SUCCESS) goto notfound; dns_rdataset_current(&val->frdataset, &rdata); if (dns_nsec_typepresent(&rdata, dns_rdatatype_ns) && !dns_nsec_typepresent(&rdata, dns_rdatatype_soa)) { /* Parent NSEC record. */ if (dns_name_issubdomain(name, foundname)) { validator_log(val, ISC_LOG_DEBUG(3), "covering nsec: for parent"); goto notfound; } } result = dns_rdata_tostruct(&rdata, &nsec, NULL); if (result != ISC_R_SUCCESS) goto notfound; if (dns_name_compare(foundname, &nsec.next) >= 0) { /* End of zone chain. */ if (!dns_name_issubdomain(name, &nsec.next)) { /* * XXXMPA We could look for a parent NSEC * at nsec.next and if found retest with * this NSEC. */ dns_rdata_freestruct(&nsec); validator_log(val, ISC_LOG_DEBUG(3), "covering nsec: not in zone"); goto notfound; } } else if (dns_name_compare(name, &nsec.next) >= 0) { /* * XXXMPA We could check if this NSEC is at a zone * apex and if the qname is not below it and look for * a parent NSEC with the same name. This requires * that we can cache both NSEC records which we * currently don't support. */ dns_rdata_freestruct(&nsec); validator_log(val, ISC_LOG_DEBUG(3), "covering nsec: not in range"); goto notfound; } if (isc_log_wouldlog(dns_lctx,ISC_LOG_DEBUG(3))) { dns_name_format(name, buf1, sizeof buf1); dns_name_format(foundname, buf2, sizeof buf2); dns_name_format(&nsec.next, buf3, sizeof buf3); validator_log(val, ISC_LOG_DEBUG(3), "covering nsec found: '%s' '%s' '%s'", buf1, buf2, buf3); } if (dns_rdataset_isassociated(&val->frdataset)) dns_rdataset_disassociate(&val->frdataset); if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); dns_rdata_freestruct(&nsec); result = DNS_R_NCACHENXDOMAIN; } else if (result != ISC_R_SUCCESS && result != DNS_R_NCACHENXDOMAIN && result != DNS_R_NCACHENXRRSET && result != DNS_R_EMPTYNAME && result != DNS_R_NXRRSET && result != ISC_R_NOTFOUND) { goto notfound; } return (result); notfound: if (dns_rdataset_isassociated(&val->frdataset)) dns_rdataset_disassociate(&val->frdataset); if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); return (ISC_R_NOTFOUND); } /*% * Checks to make sure we are not going to loop. As we use a SHARED fetch * the validation process will stall if looping was to occur. */ static inline isc_boolean_t check_deadlock(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { dns_validator_t *parent; for (parent = val; parent != NULL; parent = parent->parent) { if (parent->event != NULL && parent->event->type == type && dns_name_equal(parent->event->name, name) && /* * As NSEC3 records are meta data you sometimes * need to prove a NSEC3 record which says that * itself doesn't exist. */ (parent->event->type != dns_rdatatype_nsec3 || rdataset == NULL || sigrdataset == NULL || parent->event->message == NULL || parent->event->rdataset != NULL || parent->event->sigrdataset != NULL)) { validator_log(val, ISC_LOG_DEBUG(3), "continuing validation would lead to " "deadlock: aborting validation"); return (ISC_TRUE); } } return (ISC_FALSE); } /*% * Start a fetch for the requested name and type. */ static inline isc_result_t create_fetch(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type, isc_taskaction_t callback, const char *caller) { unsigned int fopts = 0; if (dns_rdataset_isassociated(&val->frdataset)) dns_rdataset_disassociate(&val->frdataset); if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); if (check_deadlock(val, name, type, NULL, NULL)) { validator_log(val, ISC_LOG_DEBUG(3), "deadlock found (create_fetch)"); return (DNS_R_NOVALIDSIG); } if ((val->options & DNS_VALIDATOR_NOCDFLAG) != 0) fopts |= DNS_FETCHOPT_NOCDFLAG; validator_logcreate(val, name, type, caller, "fetch"); return (dns_resolver_createfetch(val->view->resolver, name, type, NULL, NULL, NULL, fopts, val->event->ev_sender, callback, val, &val->frdataset, &val->fsigrdataset, &val->fetch)); } /*% * Start a subvalidation process. */ static inline isc_result_t create_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, isc_taskaction_t action, const char *caller) { isc_result_t result; unsigned int vopts = 0; if (check_deadlock(val, name, type, rdataset, sigrdataset)) { validator_log(val, ISC_LOG_DEBUG(3), "deadlock found (create_validator)"); return (DNS_R_NOVALIDSIG); } /* OK to clear other options, but preserve NOCDFLAG */ vopts |= (val->options & DNS_VALIDATOR_NOCDFLAG); validator_logcreate(val, name, type, caller, "validator"); result = dns_validator_create(val->view, name, type, rdataset, sigrdataset, NULL, vopts, val->task, action, val, &val->subvalidator); if (result == ISC_R_SUCCESS) { val->subvalidator->parent = val; val->subvalidator->depth = val->depth + 1; } return (result); } /*% * Try to find a key that could have signed 'siginfo' among those * in 'rdataset'. If found, build a dst_key_t for it and point * val->key at it. * * If val->key is non-NULL, this returns the next matching key. */ static isc_result_t get_dst_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo, dns_rdataset_t *rdataset) { isc_result_t result; isc_buffer_t b; dns_rdata_t rdata = DNS_RDATA_INIT; dst_key_t *oldkey = val->key; isc_boolean_t foundold; if (oldkey == NULL) foundold = ISC_TRUE; else { foundold = ISC_FALSE; val->key = NULL; } result = dns_rdataset_first(rdataset); if (result != ISC_R_SUCCESS) goto failure; do { dns_rdataset_current(rdataset, &rdata); isc_buffer_init(&b, rdata.data, rdata.length); isc_buffer_add(&b, rdata.length); INSIST(val->key == NULL); result = dst_key_fromdns(&siginfo->signer, rdata.rdclass, &b, val->view->mctx, &val->key); if (result != ISC_R_SUCCESS) goto failure; if (siginfo->algorithm == (dns_secalg_t)dst_key_alg(val->key) && siginfo->keyid == (dns_keytag_t)dst_key_id(val->key) && dst_key_iszonekey(val->key)) { if (foundold) /* * This is the key we're looking for. */ return (ISC_R_SUCCESS); else if (dst_key_compare(oldkey, val->key) == ISC_TRUE) { foundold = ISC_TRUE; dst_key_free(&oldkey); } } dst_key_free(&val->key); dns_rdata_reset(&rdata); result = dns_rdataset_next(rdataset); } while (result == ISC_R_SUCCESS); if (result == ISC_R_NOMORE) result = ISC_R_NOTFOUND; failure: if (oldkey != NULL) dst_key_free(&oldkey); return (result); } /*% * Get the key that generated this signature. */ static isc_result_t get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) { isc_result_t result; unsigned int nlabels; int order; dns_namereln_t namereln; /* * Is the signer name appropriate for this signature? * * The signer name must be at the same level as the owner name * or closer to the DNS root. */ namereln = dns_name_fullcompare(val->event->name, &siginfo->signer, &order, &nlabels); if (namereln != dns_namereln_subdomain && namereln != dns_namereln_equal) return (DNS_R_CONTINUE); if (namereln == dns_namereln_equal) { /* * If this is a self-signed keyset, it must not be a zone key * (since get_key is not called from validatezonekey). */ if (val->event->rdataset->type == dns_rdatatype_dnskey) return (DNS_R_CONTINUE); /* * Records appearing in the parent zone at delegation * points cannot be self-signed. */ if (dns_rdatatype_atparent(val->event->rdataset->type)) return (DNS_R_CONTINUE); } else { /* * SOA and NS RRsets can only be signed by a key with * the same name. */ if (val->event->rdataset->type == dns_rdatatype_soa || val->event->rdataset->type == dns_rdatatype_ns) { const char *typename; if (val->event->rdataset->type == dns_rdatatype_soa) typename = "SOA"; else typename = "NS"; validator_log(val, ISC_LOG_DEBUG(3), "%s signer mismatch", typename); return (DNS_R_CONTINUE); } } /* * Do we know about this key? */ result = view_find(val, &siginfo->signer, dns_rdatatype_dnskey); if (result == ISC_R_SUCCESS) { /* * We have an rrset for the given keyname. */ val->keyset = &val->frdataset; if ((DNS_TRUST_PENDING(val->frdataset.trust) || DNS_TRUST_ANSWER(val->frdataset.trust)) && dns_rdataset_isassociated(&val->fsigrdataset)) { /* * We know the key but haven't validated it yet or * we have a key of trust answer but a DS/DLV * record for the zone may have been added. */ result = create_validator(val, &siginfo->signer, dns_rdatatype_dnskey, &val->frdataset, &val->fsigrdataset, keyvalidated, "get_key"); if (result != ISC_R_SUCCESS) return (result); return (DNS_R_WAIT); } else if (DNS_TRUST_PENDING(val->frdataset.trust)) { /* * Having a pending key with no signature means that * something is broken. */ result = DNS_R_CONTINUE; } else if (val->frdataset.trust < dns_trust_secure) { /* * The key is legitimately insecure. There's no * point in even attempting verification. */ val->key = NULL; result = ISC_R_SUCCESS; } else { /* * See if we've got the key used in the signature. */ validator_log(val, ISC_LOG_DEBUG(3), "keyset with trust %s", dns_trust_totext(val->frdataset.trust)); result = get_dst_key(val, siginfo, val->keyset); if (result != ISC_R_SUCCESS) { /* * Either the key we're looking for is not * in the rrset, or something bad happened. * Give up. */ result = DNS_R_CONTINUE; } } } else if (result == ISC_R_NOTFOUND) { /* * We don't know anything about this key. */ result = create_fetch(val, &siginfo->signer, dns_rdatatype_dnskey, fetch_callback_validator, "get_key"); if (result != ISC_R_SUCCESS) return (result); return (DNS_R_WAIT); } else if (result == DNS_R_NCACHENXDOMAIN || result == DNS_R_NCACHENXRRSET || result == DNS_R_EMPTYNAME || result == DNS_R_NXDOMAIN || result == DNS_R_NXRRSET) { /* * This key doesn't exist. */ result = DNS_R_CONTINUE; } else if (result == DNS_R_BROKENCHAIN) return (result); if (dns_rdataset_isassociated(&val->frdataset) && val->keyset != &val->frdataset) dns_rdataset_disassociate(&val->frdataset); if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); return (result); } static dns_keytag_t compute_keytag(dns_rdata_t *rdata, dns_rdata_dnskey_t *key) { isc_region_t r; dns_rdata_toregion(rdata, &r); return (dst_region_computeid(&r, key->algorithm)); } /*% * Is this keyset self-signed? */ static isc_boolean_t isselfsigned(dns_validator_t *val) { dns_rdataset_t *rdataset, *sigrdataset; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_t sigrdata = DNS_RDATA_INIT; dns_rdata_dnskey_t key; dns_rdata_rrsig_t sig; dns_keytag_t keytag; dns_name_t *name; isc_result_t result; dst_key_t *dstkey; isc_mem_t *mctx; isc_boolean_t answer = ISC_FALSE; rdataset = val->event->rdataset; sigrdataset = val->event->sigrdataset; name = val->event->name; mctx = val->view->mctx; if (rdataset->type == dns_rdatatype_cname || rdataset->type == dns_rdatatype_dname) return (answer); INSIST(rdataset->type == dns_rdatatype_dnskey); for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdata_reset(&rdata); dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &key, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); keytag = compute_keytag(&rdata, &key); for (result = dns_rdataset_first(sigrdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(sigrdataset)) { dns_rdata_reset(&sigrdata); dns_rdataset_current(sigrdataset, &sigrdata); result = dns_rdata_tostruct(&sigrdata, &sig, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (sig.algorithm != key.algorithm || sig.keyid != keytag || !dns_name_equal(name, &sig.signer)) continue; dstkey = NULL; result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey); if (result != ISC_R_SUCCESS) continue; result = dns_dnssec_verify3(name, rdataset, dstkey, ISC_TRUE, val->view->maxbits, mctx, &sigrdata, NULL); dst_key_free(&dstkey); if (result != ISC_R_SUCCESS) continue; if ((key.flags & DNS_KEYFLAG_REVOKE) == 0) { answer = ISC_TRUE; continue; } dns_view_untrust(val->view, name, &key, mctx); } } return (answer); } /*% * Attempt to verify the rdataset using the given key and rdata (RRSIG). * The signature was good and from a wildcard record and the QNAME does * not match the wildcard we need to look for a NOQNAME proof. * * Returns: * \li ISC_R_SUCCESS if the verification succeeds. * \li Others if the verification fails. */ static isc_result_t verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata, isc_uint16_t keyid) { isc_result_t result; dns_fixedname_t fixed; isc_boolean_t ignore = ISC_FALSE; dns_name_t *wild; val->attributes |= VALATTR_TRIEDVERIFY; dns_fixedname_init(&fixed); wild = dns_fixedname_name(&fixed); again: result = dns_dnssec_verify3(val->event->name, val->event->rdataset, key, ignore, val->view->maxbits, val->view->mctx, rdata, wild); if ((result == DNS_R_SIGEXPIRED || result == DNS_R_SIGFUTURE) && val->view->acceptexpired) { ignore = ISC_TRUE; goto again; } if (ignore && (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD)) validator_log(val, ISC_LOG_INFO, "accepted expired %sRRSIG (keyid=%u)", (result == DNS_R_FROMWILDCARD) ? "wildcard " : "", keyid); else if (result == DNS_R_SIGEXPIRED || result == DNS_R_SIGFUTURE) validator_log(val, ISC_LOG_INFO, "verify failed due to bad signature (keyid=%u): " "%s", keyid, isc_result_totext(result)); else validator_log(val, ISC_LOG_DEBUG(3), "verify rdataset (keyid=%u): %s", keyid, isc_result_totext(result)); if (result == DNS_R_FROMWILDCARD) { if (!dns_name_equal(val->event->name, wild)) { dns_name_t *closest; unsigned int labels; /* * Compute the closest encloser in case we need it * for the NSEC3 NOQNAME proof. */ closest = dns_fixedname_name(&val->closest); dns_name_copy(wild, closest, NULL); labels = dns_name_countlabels(closest) - 1; dns_name_getlabelsequence(closest, 1, labels, closest); val->attributes |= VALATTR_NEEDNOQNAME; } result = ISC_R_SUCCESS; } return (result); } /*% * Attempts positive response validation of a normal RRset. * * Returns: * \li ISC_R_SUCCESS Validation completed successfully * \li DNS_R_WAIT Validation has started but is waiting * for an event. * \li Other return codes are possible and all indicate failure. */ static isc_result_t validate(dns_validator_t *val, isc_boolean_t resume) { isc_result_t result, vresult = DNS_R_NOVALIDSIG; dns_validatorevent_t *event; dns_rdata_t rdata = DNS_RDATA_INIT; /* * Caller must be holding the validator lock. */ event = val->event; if (resume) { /* * We already have a sigrdataset. */ result = ISC_R_SUCCESS; validator_log(val, ISC_LOG_DEBUG(3), "resuming validate"); } else { result = dns_rdataset_first(event->sigrdataset); } for (; result == ISC_R_SUCCESS; result = dns_rdataset_next(event->sigrdataset)) { dns_rdata_reset(&rdata); dns_rdataset_current(event->sigrdataset, &rdata); if (val->siginfo == NULL) { val->siginfo = isc_mem_get(val->view->mctx, sizeof(*val->siginfo)); if (val->siginfo == NULL) return (ISC_R_NOMEMORY); } result = dns_rdata_tostruct(&rdata, val->siginfo, NULL); if (result != ISC_R_SUCCESS) return (result); /* * At this point we could check that the signature algorithm * was known and "sufficiently good". */ if (!dns_resolver_algorithm_supported(val->view->resolver, event->name, val->siginfo->algorithm)) { resume = ISC_FALSE; continue; } if (!resume) { result = get_key(val, val->siginfo); if (result == DNS_R_CONTINUE) continue; /* Try the next SIG RR. */ if (result != ISC_R_SUCCESS) return (result); } /* * There isn't a secure DNSKEY for this signature so move * onto the next RRSIG. */ if (val->key == NULL) { resume = ISC_FALSE; continue; } do { vresult = verify(val, val->key, &rdata, val->siginfo->keyid); if (vresult == ISC_R_SUCCESS) break; if (val->keynode != NULL) { dns_keynode_t *nextnode = NULL; result = dns_keytable_findnextkeynode( val->keytable, val->keynode, &nextnode); dns_keytable_detachkeynode(val->keytable, &val->keynode); val->keynode = nextnode; if (result != ISC_R_SUCCESS) { val->key = NULL; break; } val->key = dns_keynode_key(val->keynode); if (val->key == NULL) break; } else { if (get_dst_key(val, val->siginfo, val->keyset) != ISC_R_SUCCESS) break; } } while (1); if (vresult != ISC_R_SUCCESS) validator_log(val, ISC_LOG_DEBUG(3), "failed to verify rdataset"); else { isc_stdtime_t now; isc_stdtime_get(&now); dns_rdataset_trimttl(event->rdataset, event->sigrdataset, val->siginfo, now, val->view->acceptexpired); } if (val->keynode != NULL) dns_keytable_detachkeynode(val->keytable, &val->keynode); else { if (val->key != NULL) dst_key_free(&val->key); if (val->keyset != NULL) { dns_rdataset_disassociate(val->keyset); val->keyset = NULL; } } val->key = NULL; if (NEEDNOQNAME(val)) { if (val->event->message == NULL) { validator_log(val, ISC_LOG_DEBUG(3), "no message available for noqname proof"); return (DNS_R_NOVALIDSIG); } validator_log(val, ISC_LOG_DEBUG(3), "looking for noqname proof"); return (nsecvalidate(val, ISC_FALSE)); } else if (vresult == ISC_R_SUCCESS) { marksecure(event); validator_log(val, ISC_LOG_DEBUG(3), "marking as secure, " "noqname proof not needed"); return (ISC_R_SUCCESS); } else { validator_log(val, ISC_LOG_DEBUG(3), "verify failure: %s", isc_result_totext(result)); resume = ISC_FALSE; } } if (result != ISC_R_NOMORE) { validator_log(val, ISC_LOG_DEBUG(3), "failed to iterate signatures: %s", isc_result_totext(result)); return (result); } validator_log(val, ISC_LOG_INFO, "no valid signature found"); return (vresult); } /*% * Check whether this DNSKEY (keyrdata) signed the DNSKEY RRset * (val->event->rdataset). */ static isc_result_t checkkey(dns_validator_t *val, dns_rdata_t *keyrdata, isc_uint16_t keyid, dns_secalg_t algorithm) { dns_rdata_rrsig_t sig; dst_key_t *dstkey = NULL; isc_result_t result; for (result = dns_rdataset_first(val->event->sigrdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(val->event->sigrdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(val->event->sigrdataset, &rdata); result = dns_rdata_tostruct(&rdata, &sig, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (keyid != sig.keyid || algorithm != sig.algorithm) continue; if (dstkey == NULL) { result = dns_dnssec_keyfromrdata(val->event->name, keyrdata, val->view->mctx, &dstkey); if (result != ISC_R_SUCCESS) /* * This really shouldn't happen, but... */ continue; } result = verify(val, dstkey, &rdata, sig.keyid); if (result == ISC_R_SUCCESS) break; } if (dstkey != NULL) dst_key_free(&dstkey); return (result); } /*% * Find the DNSKEY that corresponds to the DS. */ static isc_result_t keyfromds(dns_validator_t *val, dns_rdataset_t *rdataset, dns_rdata_t *dsrdata, isc_uint8_t digest, isc_uint16_t keyid, dns_secalg_t algorithm, dns_rdata_t *keyrdata) { dns_keytag_t keytag; dns_rdata_dnskey_t key; isc_result_t result; unsigned char dsbuf[DNS_DS_BUFFERSIZE]; for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdata_t newdsrdata = DNS_RDATA_INIT; dns_rdata_reset(keyrdata); dns_rdataset_current(rdataset, keyrdata); result = dns_rdata_tostruct(keyrdata, &key, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); keytag = compute_keytag(keyrdata, &key); if (keyid != keytag || algorithm != key.algorithm) continue; dns_rdata_reset(&newdsrdata); result = dns_ds_buildrdata(val->event->name, keyrdata, digest, dsbuf, &newdsrdata); if (result != ISC_R_SUCCESS) { validator_log(val, ISC_LOG_DEBUG(3), "dns_ds_buildrdata() -> %s", dns_result_totext(result)); continue; } if (dns_rdata_compare(dsrdata, &newdsrdata) == 0) break; } return (result); } /*% * Validate the DNSKEY RRset by looking for a DNSKEY that matches a * DLV record and that also verifies the DNSKEY RRset. */ static isc_result_t dlv_validatezonekey(dns_validator_t *val) { dns_rdata_dlv_t dlv; dns_rdata_t dlvrdata = DNS_RDATA_INIT; dns_rdata_t keyrdata = DNS_RDATA_INIT; dns_rdataset_t trdataset; isc_boolean_t supported_algorithm; isc_result_t result; char digest_types[256]; validator_log(val, ISC_LOG_DEBUG(3), "dlv_validatezonekey"); /* * Look through the DLV record and find the keys that can sign the * key set and the matching signature. For each such key, attempt * verification. */ supported_algorithm = ISC_FALSE; /* * If DNS_DSDIGEST_SHA256 is present we are required to prefer * it over DNS_DSDIGEST_SHA1. This in practice means that we * need to ignore DNS_DSDIGEST_SHA1 if a DNS_DSDIGEST_SHA256 * is present. */ memset(digest_types, 1, sizeof(digest_types)); for (result = dns_rdataset_first(&val->dlv); result == ISC_R_SUCCESS; result = dns_rdataset_next(&val->dlv)) { dns_rdata_reset(&dlvrdata); dns_rdataset_current(&val->dlv, &dlvrdata); result = dns_rdata_tostruct(&dlvrdata, &dlv, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (!dns_resolver_algorithm_supported(val->view->resolver, val->event->name, dlv.algorithm)) continue; if (dlv.digest_type == DNS_DSDIGEST_SHA256 && dlv.length == ISC_SHA256_DIGESTLENGTH) { digest_types[DNS_DSDIGEST_SHA1] = 0; break; } } for (result = dns_rdataset_first(&val->dlv); result == ISC_R_SUCCESS; result = dns_rdataset_next(&val->dlv)) { dns_rdata_reset(&dlvrdata); dns_rdataset_current(&val->dlv, &dlvrdata); result = dns_rdata_tostruct(&dlvrdata, &dlv, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (digest_types[dlv.digest_type] == 0) continue; if (!dns_resolver_ds_digest_supported(val->view->resolver, val->event->name, dlv.digest_type)) continue; if (!dns_resolver_algorithm_supported(val->view->resolver, val->event->name, dlv.algorithm)) continue; supported_algorithm = ISC_TRUE; dns_rdataset_init(&trdataset); dns_rdataset_clone(val->event->rdataset, &trdataset); /* * Convert to DLV to DS and find matching DNSKEY. */ dlvrdata.type = dns_rdatatype_ds; result = keyfromds(val, &trdataset, &dlvrdata, dlv.digest_type, dlv.key_tag, dlv.algorithm, &keyrdata); if (result != ISC_R_SUCCESS) { dns_rdataset_disassociate(&trdataset); validator_log(val, ISC_LOG_DEBUG(3), "no DNSKEY matching DLV"); continue; } validator_log(val, ISC_LOG_DEBUG(3), "Found matching DLV record: checking for signature"); /* * Check that this DNSKEY signed the DNSKEY rrset. */ result = checkkey(val, &keyrdata, dlv.key_tag, dlv.algorithm); dns_rdataset_disassociate(&trdataset); if (result == ISC_R_SUCCESS) break; validator_log(val, ISC_LOG_DEBUG(3), "no RRSIG matching DLV key"); } if (result == ISC_R_SUCCESS) { marksecure(val->event); validator_log(val, ISC_LOG_DEBUG(3), "marking as secure (dlv)"); return (result); } else if (result == ISC_R_NOMORE && !supported_algorithm) { if (val->mustbesecure) { validator_log(val, ISC_LOG_WARNING, "must be secure failure," "no supported algorithm/digest (dlv)"); return (DNS_R_MUSTBESECURE); } validator_log(val, ISC_LOG_DEBUG(3), "no supported algorithm/digest (dlv)"); markanswer(val, "dlv_validatezonekey (2)"); return (ISC_R_SUCCESS); } else return (DNS_R_NOVALIDSIG); } /*% * Attempts positive response validation of an RRset containing zone keys * (i.e. a DNSKEY rrset). * * Returns: * \li ISC_R_SUCCESS Validation completed successfully * \li DNS_R_WAIT Validation has started but is waiting * for an event. * \li Other return codes are possible and all indicate failure. */ static isc_result_t validatezonekey(dns_validator_t *val) { isc_result_t result; dns_validatorevent_t *event; dns_rdataset_t trdataset; dns_rdata_t dsrdata = DNS_RDATA_INIT; dns_rdata_t keyrdata = DNS_RDATA_INIT; dns_rdata_t sigrdata = DNS_RDATA_INIT; char namebuf[DNS_NAME_FORMATSIZE]; dns_rdata_ds_t ds; dns_rdata_rrsig_t sig; dst_key_t *dstkey; isc_boolean_t supported_algorithm; isc_boolean_t atsep = ISC_FALSE; char digest_types[256]; /* * Caller must be holding the validator lock. */ event = val->event; if (val->havedlvsep && val->dlv.trust >= dns_trust_secure && dns_name_equal(event->name, dns_fixedname_name(&val->dlvsep))) return (dlv_validatezonekey(val)); if (val->dsset == NULL) { /* * We have a dlv sep. Skip looking up the SEP from * {trusted,managed}-keys. If the dlv sep is for the * root then it will have been handled above so we don't * need to check whether val->event->name is "." prior to * looking up the DS. */ if (val->havedlvsep) goto find_ds; /* * First, see if this key was signed by a trusted key. */ for (result = dns_rdataset_first(val->event->sigrdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(val->event->sigrdataset)) { dns_keynode_t *keynode = NULL; dns_fixedname_t fixed; dns_name_t *found; dns_fixedname_init(&fixed); found = dns_fixedname_name(&fixed); dns_rdata_reset(&sigrdata); dns_rdataset_current(val->event->sigrdataset, &sigrdata); result = dns_rdata_tostruct(&sigrdata, &sig, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (!dns_name_equal(val->event->name, &sig.signer)) continue; result = dns_keytable_findkeynode(val->keytable, val->event->name, sig.algorithm, sig.keyid, &keynode); if (result == ISC_R_NOTFOUND && dns_keytable_finddeepestmatch(val->keytable, val->event->name, found) != ISC_R_SUCCESS) { if (val->mustbesecure) { validator_log(val, ISC_LOG_WARNING, "must be secure failure, " "not beneath secure root"); return (DNS_R_MUSTBESECURE); } else validator_log(val, ISC_LOG_DEBUG(3), "not beneath secure root"); if (val->view->dlv == NULL) { markanswer(val, "validatezonekey (1)"); return (ISC_R_SUCCESS); } return (startfinddlvsep(val, dns_rootname)); } if (result == DNS_R_PARTIALMATCH || result == ISC_R_SUCCESS) atsep = ISC_TRUE; while (result == ISC_R_SUCCESS) { dns_keynode_t *nextnode = NULL; dstkey = dns_keynode_key(keynode); if (dstkey == NULL) { dns_keytable_detachkeynode( val->keytable, &keynode); break; } result = verify(val, dstkey, &sigrdata, sig.keyid); if (result == ISC_R_SUCCESS) { dns_keytable_detachkeynode( val->keytable, &keynode); break; } result = dns_keytable_findnextkeynode( val->keytable, keynode, &nextnode); dns_keytable_detachkeynode(val->keytable, &keynode); keynode = nextnode; } if (result == ISC_R_SUCCESS) { marksecure(event); validator_log(val, ISC_LOG_DEBUG(3), "signed by trusted key; " "marking as secure"); return (result); } } if (atsep) { /* * We have not found a key to verify this DNSKEY * RRset. As this is a SEP we have to assume that * the RRset is invalid. */ dns_name_format(val->event->name, namebuf, sizeof(namebuf)); validator_log(val, ISC_LOG_NOTICE, "unable to find a DNSKEY which verifies " "the DNSKEY RRset and also matches a " "trusted key for '%s'", namebuf); return (DNS_R_NOVALIDKEY); } /* * If this is the root name and there was no trusted key, * give up, since there's no DS at the root. */ if (dns_name_equal(event->name, dns_rootname)) { if ((val->attributes & VALATTR_TRIEDVERIFY) != 0) { validator_log(val, ISC_LOG_DEBUG(3), "root key failed to validate"); return (DNS_R_NOVALIDSIG); } else { validator_log(val, ISC_LOG_DEBUG(3), "no trusted root key"); return (DNS_R_NOVALIDDS); } } find_ds: /* * Otherwise, try to find the DS record. */ result = view_find(val, val->event->name, dns_rdatatype_ds); if (result == ISC_R_SUCCESS) { /* * We have DS records. */ val->dsset = &val->frdataset; if ((DNS_TRUST_PENDING(val->frdataset.trust) || DNS_TRUST_ANSWER(val->frdataset.trust)) && dns_rdataset_isassociated(&val->fsigrdataset)) { result = create_validator(val, val->event->name, dns_rdatatype_ds, &val->frdataset, &val->fsigrdataset, dsvalidated, "validatezonekey"); if (result != ISC_R_SUCCESS) return (result); return (DNS_R_WAIT); } else if (DNS_TRUST_PENDING(val->frdataset.trust)) { /* * There should never be an unsigned DS. */ dns_rdataset_disassociate(&val->frdataset); validator_log(val, ISC_LOG_DEBUG(2), "unsigned DS record"); return (DNS_R_NOVALIDSIG); } else { result = ISC_R_SUCCESS; POST(result); } } else if (result == ISC_R_NOTFOUND) { /* * We don't have the DS. Find it. */ result = create_fetch(val, val->event->name, dns_rdatatype_ds, dsfetched, "validatezonekey"); if (result != ISC_R_SUCCESS) return (result); return (DNS_R_WAIT); } else if (result == DNS_R_NCACHENXDOMAIN || result == DNS_R_NCACHENXRRSET || result == DNS_R_EMPTYNAME || result == DNS_R_NXDOMAIN || result == DNS_R_NXRRSET || result == DNS_R_CNAME) { /* * The DS does not exist. */ if (dns_rdataset_isassociated(&val->frdataset)) dns_rdataset_disassociate(&val->frdataset); if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); validator_log(val, ISC_LOG_DEBUG(2), "no DS record"); return (DNS_R_NOVALIDSIG); } else if (result == DNS_R_BROKENCHAIN) return (result); } /* * We have a DS set. */ INSIST(val->dsset != NULL); if (val->dsset->trust < dns_trust_secure) { if (val->mustbesecure) { validator_log(val, ISC_LOG_WARNING, "must be secure failure," " insecure DS"); return (DNS_R_MUSTBESECURE); } if (val->view->dlv == NULL || DLVTRIED(val)) { markanswer(val, "validatezonekey (2)"); return (ISC_R_SUCCESS); } return (startfinddlvsep(val, val->event->name)); } /* * Look through the DS record and find the keys that can sign the * key set and the matching signature. For each such key, attempt * verification. */ supported_algorithm = ISC_FALSE; /* * If DNS_DSDIGEST_SHA256 is present we are required to prefer * it over DNS_DSDIGEST_SHA1. This in practice means that we * need to ignore DNS_DSDIGEST_SHA1 if a DNS_DSDIGEST_SHA256 * is present. */ memset(digest_types, 1, sizeof(digest_types)); for (result = dns_rdataset_first(val->dsset); result == ISC_R_SUCCESS; result = dns_rdataset_next(val->dsset)) { dns_rdata_reset(&dsrdata); dns_rdataset_current(val->dsset, &dsrdata); result = dns_rdata_tostruct(&dsrdata, &ds, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (!dns_resolver_algorithm_supported(val->view->resolver, val->event->name, ds.algorithm)) continue; if (ds.digest_type == DNS_DSDIGEST_SHA256 && ds.length == ISC_SHA256_DIGESTLENGTH) { digest_types[DNS_DSDIGEST_SHA1] = 0; break; } } for (result = dns_rdataset_first(val->dsset); result == ISC_R_SUCCESS; result = dns_rdataset_next(val->dsset)) { dns_rdata_reset(&dsrdata); dns_rdataset_current(val->dsset, &dsrdata); result = dns_rdata_tostruct(&dsrdata, &ds, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (digest_types[ds.digest_type] == 0) continue; if (!dns_resolver_ds_digest_supported(val->view->resolver, val->event->name, ds.digest_type)) continue; if (!dns_resolver_algorithm_supported(val->view->resolver, val->event->name, ds.algorithm)) continue; supported_algorithm = ISC_TRUE; dns_rdataset_init(&trdataset); dns_rdataset_clone(val->event->rdataset, &trdataset); /* * Find matching DNSKEY from DS. */ result = keyfromds(val, &trdataset, &dsrdata, ds.digest_type, ds.key_tag, ds.algorithm, &keyrdata); if (result != ISC_R_SUCCESS) { dns_rdataset_disassociate(&trdataset); validator_log(val, ISC_LOG_DEBUG(3), "no DNSKEY matching DS"); continue; } /* * Check that this DNSKEY signed the DNSKEY rrset. */ result = checkkey(val, &keyrdata, ds.key_tag, ds.algorithm); dns_rdataset_disassociate(&trdataset); if (result == ISC_R_SUCCESS) break; validator_log(val, ISC_LOG_DEBUG(3), "no RRSIG matching DS key"); } if (result == ISC_R_SUCCESS) { marksecure(event); validator_log(val, ISC_LOG_DEBUG(3), "marking as secure (DS)"); return (result); } else if (result == ISC_R_NOMORE && !supported_algorithm) { if (val->mustbesecure) { validator_log(val, ISC_LOG_WARNING, "must be secure failure, " "no supported algorithm/digest (DS)"); return (DNS_R_MUSTBESECURE); } validator_log(val, ISC_LOG_DEBUG(3), "no supported algorithm/digest (DS)"); markanswer(val, "validatezonekey (3)"); return (ISC_R_SUCCESS); } else { validator_log(val, ISC_LOG_INFO, "no valid signature found (DS)"); return (DNS_R_NOVALIDSIG); } } /*% * Starts a positive response validation. * * Returns: * \li ISC_R_SUCCESS Validation completed successfully * \li DNS_R_WAIT Validation has started but is waiting * for an event. * \li Other return codes are possible and all indicate failure. */ static isc_result_t start_positive_validation(dns_validator_t *val) { /* * If this is not a key, go straight into validate(). */ if (val->event->type != dns_rdatatype_dnskey || !isselfsigned(val)) return (validate(val, ISC_FALSE)); return (validatezonekey(val)); } /*% * val_rdataset_first and val_rdataset_next provide iteration methods * that hide whether we are iterating across a message or a negative * cache rdataset. */ static isc_result_t val_rdataset_first(dns_validator_t *val, dns_name_t **namep, dns_rdataset_t **rdatasetp) { dns_message_t *message = val->event->message; isc_result_t result; REQUIRE(rdatasetp != NULL); REQUIRE(namep != NULL); if (message == NULL) { REQUIRE(*rdatasetp != NULL); REQUIRE(*namep != NULL); } else { REQUIRE(*rdatasetp == NULL); REQUIRE(*namep == NULL); } if (message != NULL) { result = dns_message_firstname(message, DNS_SECTION_AUTHORITY); if (result != ISC_R_SUCCESS) return (result); dns_message_currentname(message, DNS_SECTION_AUTHORITY, namep); *rdatasetp = ISC_LIST_HEAD((*namep)->list); INSIST(*rdatasetp != NULL); } else { result = dns_rdataset_first(val->event->rdataset); if (result == ISC_R_SUCCESS) dns_ncache_current(val->event->rdataset, *namep, *rdatasetp); } return (result); } static isc_result_t val_rdataset_next(dns_validator_t *val, dns_name_t **namep, dns_rdataset_t **rdatasetp) { dns_message_t *message = val->event->message; isc_result_t result = ISC_R_SUCCESS; REQUIRE(rdatasetp != NULL && *rdatasetp != NULL); REQUIRE(namep != NULL && *namep != NULL); if (message != NULL) { dns_rdataset_t *rdataset = *rdatasetp; rdataset = ISC_LIST_NEXT(rdataset, link); if (rdataset == NULL) { *namep = NULL; result = dns_message_nextname(message, DNS_SECTION_AUTHORITY); if (result == ISC_R_SUCCESS) { dns_message_currentname(message, DNS_SECTION_AUTHORITY, namep); rdataset = ISC_LIST_HEAD((*namep)->list); INSIST(rdataset != NULL); } } *rdatasetp = rdataset; } else { dns_rdataset_disassociate(*rdatasetp); result = dns_rdataset_next(val->event->rdataset); if (result == ISC_R_SUCCESS) dns_ncache_current(val->event->rdataset, *namep, *rdatasetp); } return (result); } /*% * Look for NODATA at the wildcard and NOWILDCARD proofs in the * previously validated NSEC records. As these proofs are mutually * exclusive we stop when one is found. * * Returns * \li ISC_R_SUCCESS */ static isc_result_t checkwildcard(dns_validator_t *val, dns_rdatatype_t type, dns_name_t *zonename) { dns_name_t *name, *wild, tname; isc_result_t result; isc_boolean_t exists, data; char namebuf[DNS_NAME_FORMATSIZE]; dns_rdataset_t *rdataset, trdataset; dns_name_init(&tname, NULL); dns_rdataset_init(&trdataset); wild = dns_fixedname_name(&val->wild); if (dns_name_countlabels(wild) == 0) { validator_log(val, ISC_LOG_DEBUG(3), "in checkwildcard: no wildcard to check"); return (ISC_R_SUCCESS); } dns_name_format(wild, namebuf, sizeof(namebuf)); validator_log(val, ISC_LOG_DEBUG(3), "in checkwildcard: %s", namebuf); if (val->event->message == NULL) { name = &tname; rdataset = &trdataset; } else { name = NULL; rdataset = NULL; } for (result = val_rdataset_first(val, &name, &rdataset); result == ISC_R_SUCCESS; result = val_rdataset_next(val, &name, &rdataset)) { if (rdataset->type != type || rdataset->trust != dns_trust_secure) continue; if (rdataset->type == dns_rdatatype_nsec && (NEEDNODATA(val) || NEEDNOWILDCARD(val)) && !FOUNDNODATA(val) && !FOUNDNOWILDCARD(val) && dns_nsec_noexistnodata(val->event->type, wild, name, rdataset, &exists, &data, NULL, validator_log, val) == ISC_R_SUCCESS) { dns_name_t **proofs = val->event->proofs; if (exists && !data) val->attributes |= VALATTR_FOUNDNODATA; if (exists && !data && NEEDNODATA(val)) proofs[DNS_VALIDATOR_NODATAPROOF] = name; if (!exists) val->attributes |= VALATTR_FOUNDNOWILDCARD; if (!exists && NEEDNOQNAME(val)) proofs[DNS_VALIDATOR_NOWILDCARDPROOF] = name; if (dns_rdataset_isassociated(&trdataset)) dns_rdataset_disassociate(&trdataset); return (ISC_R_SUCCESS); } if (rdataset->type == dns_rdatatype_nsec3 && (NEEDNODATA(val) || NEEDNOWILDCARD(val)) && !FOUNDNODATA(val) && !FOUNDNOWILDCARD(val) && dns_nsec3_noexistnodata(val->event->type, wild, name, rdataset, zonename, &exists, &data, NULL, NULL, NULL, NULL, NULL, NULL, validator_log, val) == ISC_R_SUCCESS) { dns_name_t **proofs = val->event->proofs; if (exists && !data) val->attributes |= VALATTR_FOUNDNODATA; if (exists && !data && NEEDNODATA(val)) proofs[DNS_VALIDATOR_NODATAPROOF] = name; if (!exists) val->attributes |= VALATTR_FOUNDNOWILDCARD; if (!exists && NEEDNOQNAME(val)) proofs[DNS_VALIDATOR_NOWILDCARDPROOF] = name; if (dns_rdataset_isassociated(&trdataset)) dns_rdataset_disassociate(&trdataset); return (ISC_R_SUCCESS); } } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; if (dns_rdataset_isassociated(&trdataset)) dns_rdataset_disassociate(&trdataset); return (result); } static isc_result_t findnsec3proofs(dns_validator_t *val) { dns_name_t *name, tname; isc_result_t result; isc_boolean_t exists, data, optout, unknown; isc_boolean_t setclosest, setnearest, *setclosestp; dns_fixedname_t fclosest, fnearest, fzonename; dns_name_t *closest, *nearest, *zonename, *closestp; dns_name_t **proofs = val->event->proofs; dns_rdataset_t *rdataset, trdataset; dns_name_init(&tname, NULL); dns_rdataset_init(&trdataset); dns_fixedname_init(&fclosest); dns_fixedname_init(&fnearest); dns_fixedname_init(&fzonename); closest = dns_fixedname_name(&fclosest); nearest = dns_fixedname_name(&fnearest); zonename = dns_fixedname_name(&fzonename); if (val->event->message == NULL) { name = &tname; rdataset = &trdataset; } else { name = NULL; rdataset = NULL; } for (result = val_rdataset_first(val, &name, &rdataset); result == ISC_R_SUCCESS; result = val_rdataset_next(val, &name, &rdataset)) { if (rdataset->type != dns_rdatatype_nsec3 || rdataset->trust != dns_trust_secure) continue; result = dns_nsec3_noexistnodata(val->event->type, val->event->name, name, rdataset, zonename, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, validator_log, val); if (result != ISC_R_IGNORE && result != ISC_R_SUCCESS) { if (dns_rdataset_isassociated(&trdataset)) dns_rdataset_disassociate(&trdataset); return (result); } } if (result != ISC_R_NOMORE) result = ISC_R_SUCCESS; POST(result); if (dns_name_countlabels(zonename) == 0) return (ISC_R_SUCCESS); /* * If the val->closest is set then we want to use it otherwise * we need to discover it. */ if (dns_name_countlabels(dns_fixedname_name(&val->closest)) != 0) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(dns_fixedname_name(&val->closest), namebuf, sizeof(namebuf)); validator_log(val, ISC_LOG_DEBUG(3), "closest encloser from " "wildcard signature '%s'", namebuf); dns_name_copy(dns_fixedname_name(&val->closest), closest, NULL); closestp = NULL; setclosestp = NULL; } else { closestp = closest; setclosestp = &setclosest; } for (result = val_rdataset_first(val, &name, &rdataset); result == ISC_R_SUCCESS; result = val_rdataset_next(val, &name, &rdataset)) { if (rdataset->type != dns_rdatatype_nsec3 || rdataset->trust != dns_trust_secure) continue; /* * We process all NSEC3 records to find the closest * encloser and nearest name to the closest encloser. */ setclosest = setnearest = ISC_FALSE; optout = ISC_FALSE; unknown = ISC_FALSE; result = dns_nsec3_noexistnodata(val->event->type, val->event->name, name, rdataset, zonename, &exists, &data, &optout, &unknown, setclosestp, &setnearest, closestp, nearest, validator_log, val); if (unknown) val->attributes |= VALATTR_FOUNDUNKNOWN; if (result != ISC_R_SUCCESS) continue; if (setclosest) proofs[DNS_VALIDATOR_CLOSESTENCLOSER] = name; if (exists && !data && NEEDNODATA(val)) { val->attributes |= VALATTR_FOUNDNODATA; proofs[DNS_VALIDATOR_NODATAPROOF] = name; } if (!exists && setnearest) { val->attributes |= VALATTR_FOUNDNOQNAME; proofs[DNS_VALIDATOR_NOQNAMEPROOF] = name; if (optout) val->attributes |= VALATTR_FOUNDOPTOUT; } } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; /* * To know we have a valid noqname and optout proofs we need to also * have a valid closest encloser. Otherwise we could still be looking * at proofs from the parent zone. */ if (dns_name_countlabels(closest) > 0 && dns_name_countlabels(nearest) == dns_name_countlabels(closest) + 1 && dns_name_issubdomain(nearest, closest)) { val->attributes |= VALATTR_FOUNDCLOSEST; result = dns_name_concatenate(dns_wildcardname, closest, dns_fixedname_name(&val->wild), NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); } else { val->attributes &= ~VALATTR_FOUNDNOQNAME; val->attributes &= ~VALATTR_FOUNDOPTOUT; proofs[DNS_VALIDATOR_NOQNAMEPROOF] = NULL; } /* * Do we need to check for the wildcard? */ if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val) && ((NEEDNODATA(val) && !FOUNDNODATA(val)) || NEEDNOWILDCARD(val))) { result = checkwildcard(val, dns_rdatatype_nsec3, zonename); if (result != ISC_R_SUCCESS) return (result); } return (result); } /*% * Validate the authority section records. */ static isc_result_t validate_authority(dns_validator_t *val, isc_boolean_t resume) { dns_name_t *name; dns_message_t *message = val->event->message; isc_result_t result; if (!resume) result = dns_message_firstname(message, DNS_SECTION_AUTHORITY); else result = ISC_R_SUCCESS; for (; result == ISC_R_SUCCESS; result = dns_message_nextname(message, DNS_SECTION_AUTHORITY)) { dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; name = NULL; dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name); if (resume) { rdataset = ISC_LIST_NEXT(val->currentset, link); val->currentset = NULL; resume = ISC_FALSE; } else rdataset = ISC_LIST_HEAD(name->list); for (; rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (rdataset->type == dns_rdatatype_rrsig) continue; for (sigrdataset = ISC_LIST_HEAD(name->list); sigrdataset != NULL; sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) { if (sigrdataset->type == dns_rdatatype_rrsig && sigrdataset->covers == rdataset->type) break; } /* * If a signed zone is missing the zone key, bad * things could happen. A query for data in the zone * would lead to a query for the zone key, which * would return a negative answer, which would contain * an SOA and an NSEC signed by the missing key, which * would trigger another query for the DNSKEY (since * the first one is still in progress), and go into an * infinite loop. Avoid that. */ if (val->event->type == dns_rdatatype_dnskey && rdataset->type == dns_rdatatype_nsec && dns_name_equal(name, val->event->name)) { dns_rdata_t nsec = DNS_RDATA_INIT; result = dns_rdataset_first(rdataset); if (result != ISC_R_SUCCESS) return (result); dns_rdataset_current(rdataset, &nsec); if (dns_nsec_typepresent(&nsec, dns_rdatatype_soa)) continue; } val->currentset = rdataset; result = create_validator(val, name, rdataset->type, rdataset, sigrdataset, authvalidated, "validate_authority"); if (result != ISC_R_SUCCESS) return (result); val->authcount++; return (DNS_R_WAIT); } } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; return (result); } /*% * Validate the ncache elements. */ static isc_result_t validate_ncache(dns_validator_t *val, isc_boolean_t resume) { dns_name_t *name; isc_result_t result; if (!resume) result = dns_rdataset_first(val->event->rdataset); else result = dns_rdataset_next(val->event->rdataset); for (; result == ISC_R_SUCCESS; result = dns_rdataset_next(val->event->rdataset)) { dns_rdataset_t *rdataset, *sigrdataset = NULL; if (dns_rdataset_isassociated(&val->frdataset)) dns_rdataset_disassociate(&val->frdataset); if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); dns_fixedname_init(&val->fname); name = dns_fixedname_name(&val->fname); rdataset = &val->frdataset; dns_ncache_current(val->event->rdataset, name, rdataset); if (val->frdataset.type == dns_rdatatype_rrsig) continue; result = dns_ncache_getsigrdataset(val->event->rdataset, name, rdataset->type, &val->fsigrdataset); if (result == ISC_R_SUCCESS) sigrdataset = &val->fsigrdataset; /* * If a signed zone is missing the zone key, bad * things could happen. A query for data in the zone * would lead to a query for the zone key, which * would return a negative answer, which would contain * an SOA and an NSEC signed by the missing key, which * would trigger another query for the DNSKEY (since * the first one is still in progress), and go into an * infinite loop. Avoid that. */ if (val->event->type == dns_rdatatype_dnskey && rdataset->type == dns_rdatatype_nsec && dns_name_equal(name, val->event->name)) { dns_rdata_t nsec = DNS_RDATA_INIT; result = dns_rdataset_first(rdataset); if (result != ISC_R_SUCCESS) return (result); dns_rdataset_current(rdataset, &nsec); if (dns_nsec_typepresent(&nsec, dns_rdatatype_soa)) continue; } val->currentset = rdataset; result = create_validator(val, name, rdataset->type, rdataset, sigrdataset, authvalidated, "validate_ncache"); if (result != ISC_R_SUCCESS) return (result); val->authcount++; return (DNS_R_WAIT); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; return (result); } /*% * Prove a negative answer is good or that there is a NOQNAME when the * answer is from a wildcard. * * Loop through the authority section looking for NODATA, NOWILDCARD * and NOQNAME proofs in the NSEC records by calling authvalidated(). * * If the required proofs are found we are done. * * If the proofs are not found attempt to prove this is a unsecure * response. */ static isc_result_t nsecvalidate(dns_validator_t *val, isc_boolean_t resume) { isc_result_t result; if (resume) validator_log(val, ISC_LOG_DEBUG(3), "resuming nsecvalidate"); if (val->event->message == NULL) result = validate_ncache(val, resume); else result = validate_authority(val, resume); if (result != ISC_R_SUCCESS) return (result); /* * Do we only need to check for NOQNAME? To get here we must have * had a secure wildcard answer. */ if (!NEEDNODATA(val) && !NEEDNOWILDCARD(val) && NEEDNOQNAME(val)) { if (!FOUNDNOQNAME(val)) findnsec3proofs(val); if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val) && !FOUNDOPTOUT(val)) { validator_log(val, ISC_LOG_DEBUG(3), "marking as secure, noqname proof found"); marksecure(val->event); return (ISC_R_SUCCESS); } else if (FOUNDOPTOUT(val) && dns_name_countlabels(dns_fixedname_name(&val->wild)) != 0) { validator_log(val, ISC_LOG_DEBUG(3), "optout proof found"); val->event->optout = ISC_TRUE; markanswer(val, "nsecvalidate (1)"); return (ISC_R_SUCCESS); } else if ((val->attributes & VALATTR_FOUNDUNKNOWN) != 0) { validator_log(val, ISC_LOG_DEBUG(3), "unknown NSEC3 hash algorithm found"); markanswer(val, "nsecvalidate (2)"); return (ISC_R_SUCCESS); } validator_log(val, ISC_LOG_DEBUG(3), "noqname proof not found"); return (DNS_R_NOVALIDNSEC); } if (!FOUNDNOQNAME(val) && !FOUNDNODATA(val)) findnsec3proofs(val); /* * Do we need to check for the wildcard? */ if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val) && ((NEEDNODATA(val) && !FOUNDNODATA(val)) || NEEDNOWILDCARD(val))) { result = checkwildcard(val, dns_rdatatype_nsec, NULL); if (result != ISC_R_SUCCESS) return (result); } if ((NEEDNODATA(val) && (FOUNDNODATA(val) || FOUNDOPTOUT(val))) || (NEEDNOQNAME(val) && FOUNDNOQNAME(val) && NEEDNOWILDCARD(val) && FOUNDNOWILDCARD(val) && FOUNDCLOSEST(val))) { if ((val->attributes & VALATTR_FOUNDOPTOUT) != 0) val->event->optout = ISC_TRUE; validator_log(val, ISC_LOG_DEBUG(3), "nonexistence proof(s) found"); if (val->event->message == NULL) marksecure(val->event); else val->event->secure = ISC_TRUE; return (ISC_R_SUCCESS); } if (val->authfail != 0 && val->authcount == val->authfail) return (DNS_R_BROKENCHAIN); validator_log(val, ISC_LOG_DEBUG(3), "nonexistence proof(s) not found"); val->attributes |= VALATTR_INSECURITY; return (proveunsecure(val, ISC_FALSE, ISC_FALSE)); } static isc_boolean_t check_ds(dns_validator_t *val, dns_name_t *name, dns_rdataset_t *rdataset) { dns_rdata_t dsrdata = DNS_RDATA_INIT; dns_rdata_ds_t ds; isc_result_t result; for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdataset_current(rdataset, &dsrdata); result = dns_rdata_tostruct(&dsrdata, &ds, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (dns_resolver_ds_digest_supported(val->view->resolver, name, ds.digest_type) && dns_resolver_algorithm_supported(val->view->resolver, name, ds.algorithm)) { dns_rdata_reset(&dsrdata); return (ISC_TRUE); } dns_rdata_reset(&dsrdata); } return (ISC_FALSE); } static void dlvvalidated(isc_task_t *task, isc_event_t *event) { dns_validatorevent_t *devent; dns_validator_t *val; isc_result_t eresult; isc_boolean_t want_destroy; UNUSED(task); INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE); devent = (dns_validatorevent_t *)event; val = devent->ev_arg; eresult = devent->result; isc_event_free(&event); dns_validator_destroy(&val->subvalidator); INSIST(val->event != NULL); validator_log(val, ISC_LOG_DEBUG(3), "in dlvvalidated"); LOCK(&val->lock); if (CANCELED(val)) { validator_done(val, ISC_R_CANCELED); } else if (eresult == ISC_R_SUCCESS) { validator_log(val, ISC_LOG_DEBUG(3), "dlvset with trust %s", dns_trust_totext(val->frdataset.trust)); dns_rdataset_clone(&val->frdataset, &val->dlv); val->havedlvsep = ISC_TRUE; if (dlv_algorithm_supported(val)) dlv_validator_start(val); else { markanswer(val, "dlvvalidated"); validator_done(val, ISC_R_SUCCESS); } } else { if (eresult != DNS_R_BROKENCHAIN) { if (dns_rdataset_isassociated(&val->frdataset)) dns_rdataset_expire(&val->frdataset); if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_expire(&val->fsigrdataset); } validator_log(val, ISC_LOG_DEBUG(3), "dlvvalidated: got %s", isc_result_totext(eresult)); validator_done(val, DNS_R_BROKENCHAIN); } want_destroy = exit_check(val); UNLOCK(&val->lock); if (want_destroy) destroy(val); } /*% * Callback from fetching a DLV record. * * Resumes the DLV lookup process. */ static void dlvfetched(isc_task_t *task, isc_event_t *event) { char namebuf[DNS_NAME_FORMATSIZE]; dns_fetchevent_t *devent; dns_validator_t *val; isc_boolean_t want_destroy; isc_result_t eresult; isc_result_t result; dns_fetch_t *fetch; UNUSED(task); INSIST(event->ev_type == DNS_EVENT_FETCHDONE); devent = (dns_fetchevent_t *)event; val = devent->ev_arg; eresult = devent->result; /* Free resources which are not of interest. */ if (devent->node != NULL) dns_db_detachnode(devent->db, &devent->node); if (devent->db != NULL) dns_db_detach(&devent->db); if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); isc_event_free(&event); INSIST(val->event != NULL); validator_log(val, ISC_LOG_DEBUG(3), "in dlvfetched: %s", dns_result_totext(eresult)); LOCK(&val->lock); fetch = val->fetch; val->fetch = NULL; if (eresult == ISC_R_SUCCESS) { dns_name_format(dns_fixedname_name(&val->dlvsep), namebuf, sizeof(namebuf)); dns_rdataset_clone(&val->frdataset, &val->dlv); val->havedlvsep = ISC_TRUE; if (dlv_algorithm_supported(val)) { validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found", namebuf); dlv_validator_start(val); } else { validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found with no supported algorithms", namebuf); markanswer(val, "dlvfetched (1)"); validator_done(val, ISC_R_SUCCESS); } } else if (eresult == DNS_R_NXRRSET || eresult == DNS_R_NXDOMAIN || eresult == DNS_R_NCACHENXRRSET || eresult == DNS_R_NCACHENXDOMAIN) { result = finddlvsep(val, ISC_TRUE); if (result == ISC_R_SUCCESS) { if (dlv_algorithm_supported(val)) { dns_name_format(dns_fixedname_name(&val->dlvsep), namebuf, sizeof(namebuf)); validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found", namebuf); dlv_validator_start(val); } else { validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found with no supported " "algorithms", namebuf); markanswer(val, "dlvfetched (2)"); validator_done(val, ISC_R_SUCCESS); } } else if (result == ISC_R_NOTFOUND) { validator_log(val, ISC_LOG_DEBUG(3), "DLV not found"); markanswer(val, "dlvfetched (3)"); validator_done(val, ISC_R_SUCCESS); } else { validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s", dns_result_totext(result)); if (result != DNS_R_WAIT) validator_done(val, result); } } else { validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s", dns_result_totext(eresult)); validator_done(val, eresult); } want_destroy = exit_check(val); UNLOCK(&val->lock); if (fetch != NULL) dns_resolver_destroyfetch(&fetch); if (want_destroy) destroy(val); } /*% * Start the DLV lookup process. * * Returns * \li ISC_R_SUCCESS * \li DNS_R_WAIT * \li Others on validation failures. */ static isc_result_t startfinddlvsep(dns_validator_t *val, dns_name_t *unsecure) { char namebuf[DNS_NAME_FORMATSIZE]; isc_result_t result; INSIST(!DLVTRIED(val)); val->attributes |= VALATTR_DLVTRIED; dns_name_format(unsecure, namebuf, sizeof(namebuf)); validator_log(val, ISC_LOG_DEBUG(3), "plain DNSSEC returns unsecure (%s): looking for DLV", namebuf); if (dns_name_issubdomain(val->event->name, val->view->dlv)) { validator_log(val, ISC_LOG_WARNING, "must be secure failure, " " %s is under DLV (startfinddlvsep)", namebuf); return (DNS_R_MUSTBESECURE); } val->dlvlabels = dns_name_countlabels(unsecure) - 1; result = finddlvsep(val, ISC_FALSE); if (result == ISC_R_NOTFOUND) { validator_log(val, ISC_LOG_DEBUG(3), "DLV not found"); markanswer(val, "startfinddlvsep (1)"); return (ISC_R_SUCCESS); } if (result != ISC_R_SUCCESS) { validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s", dns_result_totext(result)); return (result); } dns_name_format(dns_fixedname_name(&val->dlvsep), namebuf, sizeof(namebuf)); if (dlv_algorithm_supported(val)) { validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found", namebuf); dlv_validator_start(val); return (DNS_R_WAIT); } validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found with no supported " "algorithms", namebuf); markanswer(val, "startfinddlvsep (2)"); validator_done(val, ISC_R_SUCCESS); return (ISC_R_SUCCESS); } /*% * Continue the DLV lookup process. * * Returns * \li ISC_R_SUCCESS * \li ISC_R_NOTFOUND * \li DNS_R_WAIT * \li Others on validation failure. */ static isc_result_t finddlvsep(dns_validator_t *val, isc_boolean_t resume) { char namebuf[DNS_NAME_FORMATSIZE]; dns_fixedname_t dlvfixed; dns_name_t *dlvname; dns_name_t *dlvsep; dns_name_t noroot; isc_result_t result; unsigned int labels; INSIST(val->view->dlv != NULL); if (!resume) { if (dns_name_issubdomain(val->event->name, val->view->dlv)) { dns_name_format(val->event->name, namebuf, sizeof(namebuf)); validator_log(val, ISC_LOG_WARNING, "must be secure failure, " "%s is under DLV (finddlvsep)", namebuf); return (DNS_R_MUSTBESECURE); } dns_fixedname_init(&val->dlvsep); dlvsep = dns_fixedname_name(&val->dlvsep); dns_name_copy(val->event->name, dlvsep, NULL); /* * If this is a response to a DS query, we need to look in * the parent zone for the trust anchor. */ if (val->event->type == dns_rdatatype_ds) { labels = dns_name_countlabels(dlvsep); if (labels == 0) return (ISC_R_NOTFOUND); dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep); } } else { dlvsep = dns_fixedname_name(&val->dlvsep); labels = dns_name_countlabels(dlvsep); dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep); } dns_name_init(&noroot, NULL); dns_fixedname_init(&dlvfixed); dlvname = dns_fixedname_name(&dlvfixed); labels = dns_name_countlabels(dlvsep); if (labels == 0) return (ISC_R_NOTFOUND); dns_name_getlabelsequence(dlvsep, 0, labels - 1, &noroot); result = dns_name_concatenate(&noroot, val->view->dlv, dlvname, NULL); while (result == ISC_R_NOSPACE) { labels = dns_name_countlabels(dlvsep); dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep); dns_name_getlabelsequence(dlvsep, 0, labels - 2, &noroot); result = dns_name_concatenate(&noroot, val->view->dlv, dlvname, NULL); } if (result != ISC_R_SUCCESS) { validator_log(val, ISC_LOG_DEBUG(2), "DLV concatenate failed"); return (DNS_R_NOVALIDSIG); } while (dns_name_countlabels(dlvname) >= dns_name_countlabels(val->view->dlv) + val->dlvlabels) { dns_name_format(dlvname, namebuf, sizeof(namebuf)); validator_log(val, ISC_LOG_DEBUG(3), "looking for DLV %s", namebuf); result = view_find(val, dlvname, dns_rdatatype_dlv); if (result == ISC_R_SUCCESS) { if (DNS_TRUST_PENDING(val->frdataset.trust) && dns_rdataset_isassociated(&val->fsigrdataset)) { dns_fixedname_init(&val->fname); dns_name_copy(dlvname, dns_fixedname_name(&val->fname), NULL); result = create_validator(val, dns_fixedname_name(&val->fname), dns_rdatatype_dlv, &val->frdataset, &val->fsigrdataset, dlvvalidated, "finddlvsep"); if (result != ISC_R_SUCCESS) return (result); return (DNS_R_WAIT); } if (val->frdataset.trust < dns_trust_secure) { validator_log(val, ISC_LOG_DEBUG(3), "DLV not validated"); return (DNS_R_NOVALIDSIG); } val->havedlvsep = ISC_TRUE; dns_rdataset_clone(&val->frdataset, &val->dlv); return (ISC_R_SUCCESS); } if (result == ISC_R_NOTFOUND) { result = create_fetch(val, dlvname, dns_rdatatype_dlv, dlvfetched, "finddlvsep"); if (result != ISC_R_SUCCESS) return (result); return (DNS_R_WAIT); } if (result != DNS_R_NXRRSET && result != DNS_R_NXDOMAIN && result != DNS_R_EMPTYNAME && result != DNS_R_NCACHENXRRSET && result != DNS_R_NCACHENXDOMAIN) return (result); /* * Strip first labels from both dlvsep and dlvname. */ labels = dns_name_countlabels(dlvsep); if (labels == 0) break; dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep); labels = dns_name_countlabels(dlvname); dns_name_getlabelsequence(dlvname, 1, labels - 1, dlvname); } return (ISC_R_NOTFOUND); } /*% * proveunsecure walks down from the SEP looking for a break in the * chain of trust. That occurs when we can prove the DS record does * not exist at a delegation point or the DS exists at a delegation * but we don't support the algorithm/digest. * * If DLV is active and we look for a DLV record at or below the * point we go insecure. If found we restart the validation process. * If not found or DLV isn't active we mark the response as a answer. * * Returns: * \li ISC_R_SUCCESS val->event->name is in a unsecure zone * \li DNS_R_WAIT validation is in progress. * \li DNS_R_MUSTBESECURE val->event->name is supposed to be secure * (policy) but we proved that it is unsecure. * \li DNS_R_NOVALIDSIG * \li DNS_R_NOVALIDNSEC * \li DNS_R_NOTINSECURE * \li DNS_R_BROKENCHAIN */ static isc_result_t proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume) { isc_result_t result; dns_fixedname_t fixedsecroot; dns_name_t *secroot; dns_name_t *tname; char namebuf[DNS_NAME_FORMATSIZE]; dns_name_t *found; dns_fixedname_t fixedfound; dns_fixedname_init(&fixedsecroot); secroot = dns_fixedname_name(&fixedsecroot); dns_fixedname_init(&fixedfound); found = dns_fixedname_name(&fixedfound); if (val->havedlvsep) dns_name_copy(dns_fixedname_name(&val->dlvsep), secroot, NULL); else { unsigned int labels; dns_name_copy(val->event->name, secroot, NULL); /* * If this is a response to a DS query, we need to look in * the parent zone for the trust anchor. */ labels = dns_name_countlabels(secroot); if (val->event->type == dns_rdatatype_ds && labels > 1U) dns_name_getlabelsequence(secroot, 1, labels - 1, secroot); result = dns_keytable_finddeepestmatch(val->keytable, secroot, secroot); if (result == ISC_R_NOTFOUND) { if (val->mustbesecure) { validator_log(val, ISC_LOG_WARNING, "must be secure failure, " "not beneath secure root"); result = DNS_R_MUSTBESECURE; goto out; } else validator_log(val, ISC_LOG_DEBUG(3), "not beneath secure root"); if (val->view->dlv == NULL || DLVTRIED(val)) { markanswer(val, "proveunsecure (1)"); return (ISC_R_SUCCESS); } return (startfinddlvsep(val, dns_rootname)); } else if (result != ISC_R_SUCCESS) return (result); } if (!resume) { /* * We are looking for breaks below the SEP so add a label. */ val->labels = dns_name_countlabels(secroot) + 1; } else { validator_log(val, ISC_LOG_DEBUG(3), "resuming proveunsecure"); /* * If we have a DS rdataset and it is secure then check if * the DS rdataset has a supported algorithm combination. * If not this is an insecure delegation as far as this * resolver is concerned. Fall back to DLV if available. */ if (have_ds && val->frdataset.trust >= dns_trust_secure && !check_ds(val, dns_fixedname_name(&val->fname), &val->frdataset)) { dns_name_format(dns_fixedname_name(&val->fname), namebuf, sizeof(namebuf)); if ((val->view->dlv == NULL || DLVTRIED(val)) && val->mustbesecure) { validator_log(val, ISC_LOG_WARNING, "must be secure failure at '%s', " "can't fall back to DLV", namebuf); result = DNS_R_MUSTBESECURE; goto out; } validator_log(val, ISC_LOG_DEBUG(3), "no supported algorithm/digest (%s/DS)", namebuf); if (val->view->dlv == NULL || DLVTRIED(val)) { markanswer(val, "proveunsecure (2)"); result = ISC_R_SUCCESS; goto out; } return(startfinddlvsep(val, dns_fixedname_name(&val->fname))); } val->labels++; } for (; val->labels <= dns_name_countlabels(val->event->name); val->labels++) { dns_fixedname_init(&val->fname); tname = dns_fixedname_name(&val->fname); if (val->labels == dns_name_countlabels(val->event->name)) dns_name_copy(val->event->name, tname, NULL); else dns_name_split(val->event->name, val->labels, NULL, tname); dns_name_format(tname, namebuf, sizeof(namebuf)); validator_log(val, ISC_LOG_DEBUG(3), "checking existence of DS at '%s'", namebuf); result = view_find(val, tname, dns_rdatatype_ds); if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) { /* * There is no DS. If this is a delegation, * we may be done. */ /* * If we have "trust == answer" then this namespace * has switched from insecure to should be secure. */ if (DNS_TRUST_PENDING(val->frdataset.trust) || DNS_TRUST_ANSWER(val->frdataset.trust)) { result = create_validator(val, tname, dns_rdatatype_ds, &val->frdataset, NULL, dsvalidated, "proveunsecure"); if (result != ISC_R_SUCCESS) goto out; return (DNS_R_WAIT); } /* * Zones using NSEC3 don't return a NSEC RRset so * we need to use dns_view_findzonecut2 to find * the zone cut. */ if (result == DNS_R_NXRRSET && !dns_rdataset_isassociated(&val->frdataset) && dns_view_findzonecut2(val->view, tname, found, 0, 0, ISC_FALSE, ISC_FALSE, NULL, NULL) == ISC_R_SUCCESS && dns_name_equal(tname, found)) { if (val->mustbesecure) { validator_log(val, ISC_LOG_WARNING, "must be secure failure, " "no DS at zone cut"); return (DNS_R_MUSTBESECURE); } if (val->view->dlv == NULL || DLVTRIED(val)) { markanswer(val, "proveunsecure (3)"); return (ISC_R_SUCCESS); } return (startfinddlvsep(val, tname)); } if (val->frdataset.trust < dns_trust_secure) { /* * This shouldn't happen, since the negative * response should have been validated. Since * there's no way of validating existing * negative response blobs, give up. */ validator_log(val, ISC_LOG_WARNING, "can't validate existing " "negative responses (no DS)"); result = DNS_R_NOVALIDSIG; goto out; } if (isdelegation(tname, &val->frdataset, result)) { if (val->mustbesecure) { validator_log(val, ISC_LOG_WARNING, "must be secure failure, " "%s is a delegation", namebuf); return (DNS_R_MUSTBESECURE); } if (val->view->dlv == NULL || DLVTRIED(val)) { markanswer(val, "proveunsecure (4)"); return (ISC_R_SUCCESS); } return (startfinddlvsep(val, tname)); } continue; } else if (result == DNS_R_CNAME) { if (DNS_TRUST_PENDING(val->frdataset.trust) || DNS_TRUST_ANSWER(val->frdataset.trust)) { result = create_validator(val, tname, dns_rdatatype_cname, &val->frdataset, NULL, cnamevalidated, "proveunsecure " "(cname)"); if (result != ISC_R_SUCCESS) goto out; return (DNS_R_WAIT); } continue; } else if (result == ISC_R_SUCCESS) { /* * There is a DS here. Verify that it's secure and * continue. */ if (val->frdataset.trust >= dns_trust_secure) { if (!check_ds(val, tname, &val->frdataset)) { validator_log(val, ISC_LOG_DEBUG(3), "no supported algorithm/" "digest (%s/DS)", namebuf); if (val->mustbesecure) { validator_log(val, ISC_LOG_WARNING, "must be secure failure, " "no supported algorithm/" "digest (%s/DS)", namebuf); result = DNS_R_MUSTBESECURE; goto out; } if (val->view->dlv == NULL || DLVTRIED(val)) { markanswer(val, "proveunsecure (5)"); result = ISC_R_SUCCESS; goto out; } return(startfinddlvsep(val, tname)); } continue; } else if (!dns_rdataset_isassociated(&val->fsigrdataset)) { validator_log(val, ISC_LOG_DEBUG(3), "DS is unsigned"); result = DNS_R_NOVALIDSIG; goto out; } /* * Validate / re-validate answer. */ result = create_validator(val, tname, dns_rdatatype_ds, &val->frdataset, &val->fsigrdataset, dsvalidated, "proveunsecure"); if (result != ISC_R_SUCCESS) goto out; return (DNS_R_WAIT); } else if (result == DNS_R_NXDOMAIN || result == DNS_R_NCACHENXDOMAIN) { /* * This is not a zone cut. Assuming things are * as expected, continue. */ if (!dns_rdataset_isassociated(&val->frdataset)) { /* * There should be an NSEC here, since we * are still in a secure zone. */ result = DNS_R_NOVALIDNSEC; goto out; } else if (DNS_TRUST_PENDING(val->frdataset.trust) || DNS_TRUST_ANSWER(val->frdataset.trust)) { /* * If we have "trust == answer" then this namespace * has switched from insecure to should be secure. */ result = create_validator(val, tname, dns_rdatatype_ds, &val->frdataset, NULL, dsvalidated, "proveunsecure"); if (result != ISC_R_SUCCESS) goto out; return (DNS_R_WAIT); } else if (val->frdataset.trust < dns_trust_secure) { /* * This shouldn't happen, since the negative * response should have been validated. Since * there's no way of validating existing * negative response blobs, give up. */ validator_log(val, ISC_LOG_WARNING, "can't validate existing " "negative responses " "(not a zone cut)"); result = DNS_R_NOVALIDSIG; goto out; } continue; } else if (result == ISC_R_NOTFOUND) { /* * We don't know anything about the DS. Find it. */ result = create_fetch(val, tname, dns_rdatatype_ds, dsfetched2, "proveunsecure"); if (result != ISC_R_SUCCESS) goto out; return (DNS_R_WAIT); } else if (result == DNS_R_BROKENCHAIN) return (result); } /* Couldn't complete insecurity proof */ validator_log(val, ISC_LOG_DEBUG(3), "insecurity proof failed"); return (DNS_R_NOTINSECURE); out: if (dns_rdataset_isassociated(&val->frdataset)) dns_rdataset_disassociate(&val->frdataset); if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); return (result); } /*% * Reset state and revalidate the answer using DLV. */ static void dlv_validator_start(dns_validator_t *val) { isc_event_t *event; validator_log(val, ISC_LOG_DEBUG(3), "dlv_validator_start"); /* * Reset state and try again. */ val->attributes &= VALATTR_DLVTRIED; val->options &= ~DNS_VALIDATOR_DLV; event = (isc_event_t *)val->event; isc_task_send(val->task, &event); } /*% * Start the validation process. * * Attempt to validate the answer based on the category it appears to * fall in. * \li 1. secure positive answer. * \li 2. unsecure positive answer. * \li 3. a negative answer (secure or unsecure). * * Note a answer that appears to be a secure positive answer may actually * be an unsecure positive answer. */ static void validator_start(isc_task_t *task, isc_event_t *event) { dns_validator_t *val; dns_validatorevent_t *vevent; isc_boolean_t want_destroy = ISC_FALSE; isc_result_t result = ISC_R_FAILURE; UNUSED(task); REQUIRE(event->ev_type == DNS_EVENT_VALIDATORSTART); vevent = (dns_validatorevent_t *)event; val = vevent->validator; /* If the validator has been canceled, val->event == NULL */ if (val->event == NULL) return; if (DLVTRIED(val)) validator_log(val, ISC_LOG_DEBUG(3), "restarting using DLV"); else validator_log(val, ISC_LOG_DEBUG(3), "starting"); LOCK(&val->lock); if ((val->options & DNS_VALIDATOR_DLV) != 0 && val->event->rdataset != NULL) { validator_log(val, ISC_LOG_DEBUG(3), "looking for DLV"); result = startfinddlvsep(val, dns_rootname); } else if (val->event->rdataset != NULL && val->event->sigrdataset != NULL) { isc_result_t saved_result; /* * This looks like a simple validation. We say "looks like" * because it might end up requiring an insecurity proof. */ validator_log(val, ISC_LOG_DEBUG(3), "attempting positive response validation"); INSIST(dns_rdataset_isassociated(val->event->rdataset)); INSIST(dns_rdataset_isassociated(val->event->sigrdataset)); result = start_positive_validation(val); if (result == DNS_R_NOVALIDSIG && (val->attributes & VALATTR_TRIEDVERIFY) == 0) { saved_result = result; validator_log(val, ISC_LOG_DEBUG(3), "falling back to insecurity proof"); val->attributes |= VALATTR_INSECURITY; result = proveunsecure(val, ISC_FALSE, ISC_FALSE); if (result == DNS_R_NOTINSECURE) result = saved_result; } } else if (val->event->rdataset != NULL && val->event->rdataset->type != 0) { /* * This is either an unsecure subdomain or a response from * a broken server. */ INSIST(dns_rdataset_isassociated(val->event->rdataset)); validator_log(val, ISC_LOG_DEBUG(3), "attempting insecurity proof"); val->attributes |= VALATTR_INSECURITY; result = proveunsecure(val, ISC_FALSE, ISC_FALSE); if (result == DNS_R_NOTINSECURE) validator_log(val, ISC_LOG_INFO, "got insecure response; " "parent indicates it should be secure"); } else if (val->event->rdataset == NULL && val->event->sigrdataset == NULL) { /* * This is a nonexistence validation. */ validator_log(val, ISC_LOG_DEBUG(3), "attempting negative response validation"); if (val->event->message->rcode == dns_rcode_nxdomain) { val->attributes |= VALATTR_NEEDNOQNAME; val->attributes |= VALATTR_NEEDNOWILDCARD; } else val->attributes |= VALATTR_NEEDNODATA; result = nsecvalidate(val, ISC_FALSE); } else if (val->event->rdataset != NULL && NEGATIVE(val->event->rdataset)) { /* * This is a nonexistence validation. */ validator_log(val, ISC_LOG_DEBUG(3), "attempting negative response validation"); if (val->event->rdataset->covers == dns_rdatatype_any) { val->attributes |= VALATTR_NEEDNOQNAME; val->attributes |= VALATTR_NEEDNOWILDCARD; } else val->attributes |= VALATTR_NEEDNODATA; result = nsecvalidate(val, ISC_FALSE); } else { /* * This shouldn't happen. */ INSIST(0); } if (result != DNS_R_WAIT) { want_destroy = exit_check(val); validator_done(val, result); } UNLOCK(&val->lock); if (want_destroy) destroy(val); } isc_result_t dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, dns_message_t *message, unsigned int options, isc_task_t *task, isc_taskaction_t action, void *arg, dns_validator_t **validatorp) { isc_result_t result = ISC_R_FAILURE; dns_validator_t *val; isc_task_t *tclone = NULL; dns_validatorevent_t *event; REQUIRE(name != NULL); REQUIRE(rdataset != NULL || (rdataset == NULL && sigrdataset == NULL && message != NULL)); REQUIRE(validatorp != NULL && *validatorp == NULL); val = isc_mem_get(view->mctx, sizeof(*val)); if (val == NULL) return (ISC_R_NOMEMORY); val->view = NULL; dns_view_weakattach(view, &val->view); event = (dns_validatorevent_t *) isc_event_allocate(view->mctx, task, DNS_EVENT_VALIDATORSTART, validator_start, NULL, sizeof(dns_validatorevent_t)); if (event == NULL) { result = ISC_R_NOMEMORY; goto cleanup_val; } isc_task_attach(task, &tclone); event->validator = val; event->result = ISC_R_FAILURE; event->name = name; event->type = type; event->rdataset = rdataset; event->sigrdataset = sigrdataset; event->message = message; memset(event->proofs, 0, sizeof(event->proofs)); event->optout = ISC_FALSE; event->secure = ISC_FALSE; result = isc_mutex_init(&val->lock); if (result != ISC_R_SUCCESS) goto cleanup_event; val->event = event; val->options = options; val->attributes = 0; val->fetch = NULL; val->subvalidator = NULL; val->parent = NULL; val->keytable = NULL; result = dns_view_getsecroots(val->view, &val->keytable); if (result != ISC_R_SUCCESS) goto cleanup_mutex; val->keynode = NULL; val->key = NULL; val->siginfo = NULL; val->task = task; val->action = action; val->arg = arg; val->labels = 0; val->currentset = NULL; val->keyset = NULL; val->dsset = NULL; dns_rdataset_init(&val->dlv); val->seensig = ISC_FALSE; val->havedlvsep = ISC_FALSE; val->depth = 0; val->authcount = 0; val->authfail = 0; val->mustbesecure = dns_resolver_getmustbesecure(view->resolver, name); dns_rdataset_init(&val->frdataset); dns_rdataset_init(&val->fsigrdataset); dns_fixedname_init(&val->wild); dns_fixedname_init(&val->nearest); dns_fixedname_init(&val->closest); ISC_LINK_INIT(val, link); val->magic = VALIDATOR_MAGIC; if ((options & DNS_VALIDATOR_DEFER) == 0) isc_task_send(task, ISC_EVENT_PTR(&event)); *validatorp = val; return (ISC_R_SUCCESS); cleanup_mutex: DESTROYLOCK(&val->lock); cleanup_event: isc_task_detach(&tclone); isc_event_free(ISC_EVENT_PTR(&event)); cleanup_val: dns_view_weakdetach(&val->view); isc_mem_put(view->mctx, val, sizeof(*val)); return (result); } void dns_validator_send(dns_validator_t *validator) { isc_event_t *event; REQUIRE(VALID_VALIDATOR(validator)); LOCK(&validator->lock); INSIST((validator->options & DNS_VALIDATOR_DEFER) != 0); event = (isc_event_t *)validator->event; validator->options &= ~DNS_VALIDATOR_DEFER; UNLOCK(&validator->lock); isc_task_send(validator->task, ISC_EVENT_PTR(&event)); } void dns_validator_cancel(dns_validator_t *validator) { dns_fetch_t *fetch = NULL; REQUIRE(VALID_VALIDATOR(validator)); LOCK(&validator->lock); validator_log(validator, ISC_LOG_DEBUG(3), "dns_validator_cancel"); if ((validator->attributes & VALATTR_CANCELED) == 0) { validator->attributes |= VALATTR_CANCELED; if (validator->event != NULL) { fetch = validator->fetch; validator->fetch = NULL; if (validator->subvalidator != NULL) dns_validator_cancel(validator->subvalidator); if ((validator->options & DNS_VALIDATOR_DEFER) != 0) { validator->options &= ~DNS_VALIDATOR_DEFER; validator_done(validator, ISC_R_CANCELED); } } } UNLOCK(&validator->lock); /* Need to cancel and destroy the fetch outside validator lock */ if (fetch != NULL) { dns_resolver_cancelfetch(fetch); dns_resolver_destroyfetch(&fetch); } } static void destroy(dns_validator_t *val) { isc_mem_t *mctx; REQUIRE(SHUTDOWN(val)); REQUIRE(val->event == NULL); REQUIRE(val->fetch == NULL); if (val->keynode != NULL) dns_keytable_detachkeynode(val->keytable, &val->keynode); else if (val->key != NULL) dst_key_free(&val->key); if (val->keytable != NULL) dns_keytable_detach(&val->keytable); if (val->subvalidator != NULL) dns_validator_destroy(&val->subvalidator); if (val->havedlvsep) dns_rdataset_disassociate(&val->dlv); if (dns_rdataset_isassociated(&val->frdataset)) dns_rdataset_disassociate(&val->frdataset); if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); mctx = val->view->mctx; if (val->siginfo != NULL) isc_mem_put(mctx, val->siginfo, sizeof(*val->siginfo)); DESTROYLOCK(&val->lock); dns_view_weakdetach(&val->view); val->magic = 0; isc_mem_put(mctx, val, sizeof(*val)); } void dns_validator_destroy(dns_validator_t **validatorp) { dns_validator_t *val; isc_boolean_t want_destroy = ISC_FALSE; REQUIRE(validatorp != NULL); val = *validatorp; REQUIRE(VALID_VALIDATOR(val)); LOCK(&val->lock); val->attributes |= VALATTR_SHUTDOWN; validator_log(val, ISC_LOG_DEBUG(4), "dns_validator_destroy"); want_destroy = exit_check(val); UNLOCK(&val->lock); if (want_destroy) destroy(val); *validatorp = NULL; } static void validator_logv(dns_validator_t *val, isc_logcategory_t *category, isc_logmodule_t *module, int level, const char *fmt, va_list ap) { char msgbuf[2048]; static const char spaces[] = " *"; int depth = val->depth * 2; vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); if ((unsigned int) depth >= sizeof spaces) depth = sizeof spaces - 1; if (val->event != NULL && val->event->name != NULL) { char namebuf[DNS_NAME_FORMATSIZE]; char typebuf[DNS_RDATATYPE_FORMATSIZE]; dns_name_format(val->event->name, namebuf, sizeof(namebuf)); dns_rdatatype_format(val->event->type, typebuf, sizeof(typebuf)); isc_log_write(dns_lctx, category, module, level, "%.*svalidating %s/%s: %s", depth, spaces, namebuf, typebuf, msgbuf); } else { isc_log_write(dns_lctx, category, module, level, "%.*svalidator @%p: %s", depth, spaces, val, msgbuf); } } static void validator_log(void *val, int level, const char *fmt, ...) { va_list ap; if (! isc_log_wouldlog(dns_lctx, level)) return; va_start(ap, fmt); validator_logv(val, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_VALIDATOR, level, fmt, ap); va_end(ap); } static void validator_logcreate(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type, const char *caller, const char *operation) { char namestr[DNS_NAME_FORMATSIZE]; char typestr[DNS_RDATATYPE_FORMATSIZE]; dns_name_format(name, namestr, sizeof(namestr)); dns_rdatatype_format(type, typestr, sizeof(typestr)); validator_log(val, ISC_LOG_DEBUG(9), "%s: creating %s for %s %s", caller, operation, namestr, typestr); } bind9-9.10.3.dfsg.P4/lib/dns/opensslrsa_link.c0000644000470500017500000010326112664710322020300 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Principal Author: Brian Wellington * $Id$ */ #ifdef OPENSSL #include #ifndef USE_EVP #if !defined(HAVE_EVP_SHA256) || !defined(HAVE_EVP_SHA512) #define USE_EVP 0 #else #define USE_EVP 1 #endif #endif #include #include #include #include #include #include #include #include #include #include "dst_internal.h" #include "dst_openssl.h" #include "dst_parse.h" #include #include #include #if OPENSSL_VERSION_NUMBER > 0x00908000L #include #endif #ifdef USE_ENGINE #include #endif /* * Limit the size of public exponents. */ #ifndef RSA_MAX_PUBEXP_BITS #define RSA_MAX_PUBEXP_BITS 35 #endif /* * We don't use configure for windows so enforce the OpenSSL version * here. Unlike with configure we don't support overriding this test. */ #ifdef WIN32 #if !((OPENSSL_VERSION_NUMBER >= 0x009070cfL && \ OPENSSL_VERSION_NUMBER < 0x00908000L) || \ (OPENSSL_VERSION_NUMBER >= 0x0090804fL && \ OPENSSL_VERSION_NUMBER < 0x10002000L) || \ OPENSSL_VERSION_NUMBER >= 0x1000205fL) #error Please upgrade OpenSSL to 0.9.8d/0.9.7l or greater. #endif #endif /* * XXXMPA Temporarily disable RSA_BLINDING as it requires * good quality random data that cannot currently be guaranteed. * XXXMPA Find which versions of openssl use pseudo random data * and set RSA_FLAG_BLINDING for those. */ #if 0 #if OPENSSL_VERSION_NUMBER < 0x0090601fL #define SET_FLAGS(rsa) \ do { \ (rsa)->flags &= ~(RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE); \ (rsa)->flags |= RSA_FLAG_BLINDING; \ } while (0) #else #define SET_FLAGS(rsa) \ do { \ (rsa)->flags |= RSA_FLAG_BLINDING; \ } while (0) #endif #endif #if OPENSSL_VERSION_NUMBER < 0x0090601fL #define SET_FLAGS(rsa) \ do { \ (rsa)->flags &= ~(RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE); \ (rsa)->flags &= ~RSA_FLAG_BLINDING; \ } while (0) #elif defined(RSA_FLAG_NO_BLINDING) #define SET_FLAGS(rsa) \ do { \ (rsa)->flags &= ~RSA_FLAG_BLINDING; \ (rsa)->flags |= RSA_FLAG_NO_BLINDING; \ } while (0) #else #define SET_FLAGS(rsa) \ do { \ (rsa)->flags &= ~RSA_FLAG_BLINDING; \ } while (0) #endif #define DST_RET(a) {ret = a; goto err;} static isc_result_t opensslrsa_todns(const dst_key_t *key, isc_buffer_t *data); static isc_result_t opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) { #if USE_EVP EVP_MD_CTX *evp_md_ctx; const EVP_MD *type = NULL; #endif UNUSED(key); REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 || dctx->key->key_alg == DST_ALG_RSASHA1 || dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || dctx->key->key_alg == DST_ALG_RSASHA256 || dctx->key->key_alg == DST_ALG_RSASHA512); #if USE_EVP evp_md_ctx = EVP_MD_CTX_create(); if (evp_md_ctx == NULL) return (ISC_R_NOMEMORY); switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: type = EVP_md5(); /* MD5 + RSA */ break; case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: type = EVP_sha1(); /* SHA1 + RSA */ break; #ifdef HAVE_EVP_SHA256 case DST_ALG_RSASHA256: type = EVP_sha256(); /* SHA256 + RSA */ break; #endif #ifdef HAVE_EVP_SHA512 case DST_ALG_RSASHA512: type = EVP_sha512(); break; #endif default: INSIST(0); } if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) { EVP_MD_CTX_destroy(evp_md_ctx); return (dst__openssl_toresult3(dctx->category, "EVP_DigestInit_ex", ISC_R_FAILURE)); } dctx->ctxdata.evp_md_ctx = evp_md_ctx; #else switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: { isc_md5_t *md5ctx; md5ctx = isc_mem_get(dctx->mctx, sizeof(isc_md5_t)); if (md5ctx == NULL) return (ISC_R_NOMEMORY); isc_md5_init(md5ctx); dctx->ctxdata.md5ctx = md5ctx; } break; case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: { isc_sha1_t *sha1ctx; sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t)); if (sha1ctx == NULL) return (ISC_R_NOMEMORY); isc_sha1_init(sha1ctx); dctx->ctxdata.sha1ctx = sha1ctx; } break; case DST_ALG_RSASHA256: { isc_sha256_t *sha256ctx; sha256ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha256_t)); if (sha256ctx == NULL) return (ISC_R_NOMEMORY); isc_sha256_init(sha256ctx); dctx->ctxdata.sha256ctx = sha256ctx; } break; case DST_ALG_RSASHA512: { isc_sha512_t *sha512ctx; sha512ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha512_t)); if (sha512ctx == NULL) return (ISC_R_NOMEMORY); isc_sha512_init(sha512ctx); dctx->ctxdata.sha512ctx = sha512ctx; } break; default: INSIST(0); } #endif return (ISC_R_SUCCESS); } static void opensslrsa_destroyctx(dst_context_t *dctx) { #if USE_EVP EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; #endif REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 || dctx->key->key_alg == DST_ALG_RSASHA1 || dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || dctx->key->key_alg == DST_ALG_RSASHA256 || dctx->key->key_alg == DST_ALG_RSASHA512); #if USE_EVP if (evp_md_ctx != NULL) { EVP_MD_CTX_destroy(evp_md_ctx); dctx->ctxdata.evp_md_ctx = NULL; } #else switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: { isc_md5_t *md5ctx = dctx->ctxdata.md5ctx; if (md5ctx != NULL) { isc_md5_invalidate(md5ctx); isc_mem_put(dctx->mctx, md5ctx, sizeof(isc_md5_t)); dctx->ctxdata.md5ctx = NULL; } } break; case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: { isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; if (sha1ctx != NULL) { isc_sha1_invalidate(sha1ctx); isc_mem_put(dctx->mctx, sha1ctx, sizeof(isc_sha1_t)); dctx->ctxdata.sha1ctx = NULL; } } break; case DST_ALG_RSASHA256: { isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx; if (sha256ctx != NULL) { isc_sha256_invalidate(sha256ctx); isc_mem_put(dctx->mctx, sha256ctx, sizeof(isc_sha256_t)); dctx->ctxdata.sha256ctx = NULL; } } break; case DST_ALG_RSASHA512: { isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx; if (sha512ctx != NULL) { isc_sha512_invalidate(sha512ctx); isc_mem_put(dctx->mctx, sha512ctx, sizeof(isc_sha512_t)); dctx->ctxdata.sha512ctx = NULL; } } break; default: INSIST(0); } #endif } static isc_result_t opensslrsa_adddata(dst_context_t *dctx, const isc_region_t *data) { #if USE_EVP EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; #endif REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 || dctx->key->key_alg == DST_ALG_RSASHA1 || dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || dctx->key->key_alg == DST_ALG_RSASHA256 || dctx->key->key_alg == DST_ALG_RSASHA512); #if USE_EVP if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) { return (dst__openssl_toresult3(dctx->category, "EVP_DigestUpdate", ISC_R_FAILURE)); } #else switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: { isc_md5_t *md5ctx = dctx->ctxdata.md5ctx; isc_md5_update(md5ctx, data->base, data->length); } break; case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: { isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; isc_sha1_update(sha1ctx, data->base, data->length); } break; case DST_ALG_RSASHA256: { isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx; isc_sha256_update(sha256ctx, data->base, data->length); } break; case DST_ALG_RSASHA512: { isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx; isc_sha512_update(sha512ctx, data->base, data->length); } break; default: INSIST(0); } #endif return (ISC_R_SUCCESS); } #if ! USE_EVP && OPENSSL_VERSION_NUMBER < 0x00908000L /* * Digest prefixes from RFC 5702. */ static unsigned char sha256_prefix[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}; static unsigned char sha512_prefix[] = { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40}; #define PREFIXLEN sizeof(sha512_prefix) #else #define PREFIXLEN 0 #endif static isc_result_t opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { dst_key_t *key = dctx->key; isc_region_t r; unsigned int siglen = 0; #if USE_EVP EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; EVP_PKEY *pkey = key->keydata.pkey; #else RSA *rsa = key->keydata.rsa; /* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */ unsigned char digest[PREFIXLEN + ISC_SHA512_DIGESTLENGTH]; int status; int type = 0; unsigned int digestlen = 0; #if OPENSSL_VERSION_NUMBER < 0x00908000L unsigned int prefixlen = 0; const unsigned char *prefix = NULL; #endif #endif REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 || dctx->key->key_alg == DST_ALG_RSASHA1 || dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || dctx->key->key_alg == DST_ALG_RSASHA256 || dctx->key->key_alg == DST_ALG_RSASHA512); isc_buffer_availableregion(sig, &r); #if USE_EVP if (r.length < (unsigned int) EVP_PKEY_size(pkey)) return (ISC_R_NOSPACE); if (!EVP_SignFinal(evp_md_ctx, r.base, &siglen, pkey)) { return (dst__openssl_toresult3(dctx->category, "EVP_SignFinal", ISC_R_FAILURE)); } #else if (r.length < (unsigned int) RSA_size(rsa)) return (ISC_R_NOSPACE); switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: { isc_md5_t *md5ctx = dctx->ctxdata.md5ctx; isc_md5_final(md5ctx, digest); type = NID_md5; digestlen = ISC_MD5_DIGESTLENGTH; } break; case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: { isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; isc_sha1_final(sha1ctx, digest); type = NID_sha1; digestlen = ISC_SHA1_DIGESTLENGTH; } break; case DST_ALG_RSASHA256: { isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx; isc_sha256_final(digest, sha256ctx); digestlen = ISC_SHA256_DIGESTLENGTH; #if OPENSSL_VERSION_NUMBER < 0x00908000L prefix = sha256_prefix; prefixlen = sizeof(sha256_prefix); #else type = NID_sha256; #endif } break; case DST_ALG_RSASHA512: { isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx; isc_sha512_final(digest, sha512ctx); digestlen = ISC_SHA512_DIGESTLENGTH; #if OPENSSL_VERSION_NUMBER < 0x00908000L prefix = sha512_prefix; prefixlen = sizeof(sha512_prefix); #else type = NID_sha512; #endif } break; default: INSIST(0); } #if OPENSSL_VERSION_NUMBER < 0x00908000L switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: INSIST(type != 0); status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa); break; case DST_ALG_RSASHA256: case DST_ALG_RSASHA512: INSIST(prefix != NULL); INSIST(prefixlen != 0); INSIST(prefixlen + digestlen <= sizeof(digest)); memmove(digest + prefixlen, digest, digestlen); memmove(digest, prefix, prefixlen); status = RSA_private_encrypt(digestlen + prefixlen, digest, r.base, rsa, RSA_PKCS1_PADDING); if (status < 0) status = 0; else siglen = status; break; default: INSIST(0); } #else INSIST(type != 0); status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa); #endif if (status == 0) return (dst__openssl_toresult3(dctx->category, "RSA_sign", DST_R_OPENSSLFAILURE)); #endif isc_buffer_add(sig, siglen); return (ISC_R_SUCCESS); } static isc_result_t opensslrsa_verify2(dst_context_t *dctx, int maxbits, const isc_region_t *sig) { dst_key_t *key = dctx->key; int status = 0; #if USE_EVP EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; EVP_PKEY *pkey = key->keydata.pkey; RSA *rsa; int bits; #else /* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */ unsigned char digest[ISC_SHA512_DIGESTLENGTH]; int type = 0; unsigned int digestlen = 0; RSA *rsa = key->keydata.rsa; #if OPENSSL_VERSION_NUMBER < 0x00908000L unsigned int prefixlen = 0; const unsigned char *prefix = NULL; #endif #endif REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 || dctx->key->key_alg == DST_ALG_RSASHA1 || dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || dctx->key->key_alg == DST_ALG_RSASHA256 || dctx->key->key_alg == DST_ALG_RSASHA512); #if USE_EVP rsa = EVP_PKEY_get1_RSA(pkey); if (rsa == NULL) return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); bits = BN_num_bits(rsa->e); RSA_free(rsa); if (bits > maxbits && maxbits != 0) return (DST_R_VERIFYFAILURE); status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey); switch (status) { case 1: return (ISC_R_SUCCESS); case 0: return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); default: return (dst__openssl_toresult3(dctx->category, "EVP_VerifyFinal", DST_R_VERIFYFAILURE)); } #else if (BN_num_bits(rsa->e) > maxbits && maxbits != 0) return (DST_R_VERIFYFAILURE); switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: { isc_md5_t *md5ctx = dctx->ctxdata.md5ctx; isc_md5_final(md5ctx, digest); type = NID_md5; digestlen = ISC_MD5_DIGESTLENGTH; } break; case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: { isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; isc_sha1_final(sha1ctx, digest); type = NID_sha1; digestlen = ISC_SHA1_DIGESTLENGTH; } break; case DST_ALG_RSASHA256: { isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx; isc_sha256_final(digest, sha256ctx); digestlen = ISC_SHA256_DIGESTLENGTH; #if OPENSSL_VERSION_NUMBER < 0x00908000L prefix = sha256_prefix; prefixlen = sizeof(sha256_prefix); #else type = NID_sha256; #endif } break; case DST_ALG_RSASHA512: { isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx; isc_sha512_final(digest, sha512ctx); digestlen = ISC_SHA512_DIGESTLENGTH; #if OPENSSL_VERSION_NUMBER < 0x00908000L prefix = sha512_prefix; prefixlen = sizeof(sha512_prefix); #else type = NID_sha512; #endif } break; default: INSIST(0); } if (sig->length != (unsigned int) RSA_size(rsa)) return (DST_R_VERIFYFAILURE); #if OPENSSL_VERSION_NUMBER < 0x00908000L switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: INSIST(type != 0); status = RSA_verify(type, digest, digestlen, sig->base, RSA_size(rsa), rsa); break; case DST_ALG_RSASHA256: case DST_ALG_RSASHA512: { /* * 1024 is big enough for all valid RSA bit sizes * for use with DNSSEC. */ unsigned char original[PREFIXLEN + 1024]; INSIST(prefix != NULL); INSIST(prefixlen != 0U); if (RSA_size(rsa) > (int)sizeof(original)) return (DST_R_VERIFYFAILURE); status = RSA_public_decrypt(sig->length, sig->base, original, rsa, RSA_PKCS1_PADDING); if (status <= 0) return (dst__openssl_toresult3( dctx->category, "RSA_public_decrypt", DST_R_VERIFYFAILURE)); if (status != (int)(prefixlen + digestlen)) return (DST_R_VERIFYFAILURE); if (!isc_safe_memequal(original, prefix, prefixlen)) return (DST_R_VERIFYFAILURE); if (!isc_safe_memequal(original + prefixlen, digest, digestlen)) return (DST_R_VERIFYFAILURE); status = 1; } break; default: INSIST(0); } #else INSIST(type != 0); status = RSA_verify(type, digest, digestlen, sig->base, RSA_size(rsa), rsa); #endif if (status != 1) return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); return (ISC_R_SUCCESS); #endif } static isc_result_t opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) { return (opensslrsa_verify2(dctx, 0, sig)); } static isc_boolean_t opensslrsa_compare(const dst_key_t *key1, const dst_key_t *key2) { int status; RSA *rsa1 = NULL, *rsa2 = NULL; #if USE_EVP EVP_PKEY *pkey1, *pkey2; #endif #if USE_EVP pkey1 = key1->keydata.pkey; pkey2 = key2->keydata.pkey; /* * The pkey reference will keep these around after * the RSA_free() call. */ if (pkey1 != NULL) { rsa1 = EVP_PKEY_get1_RSA(pkey1); RSA_free(rsa1); } if (pkey2 != NULL) { rsa2 = EVP_PKEY_get1_RSA(pkey2); RSA_free(rsa2); } #else rsa1 = key1->keydata.rsa; rsa2 = key2->keydata.rsa; #endif if (rsa1 == NULL && rsa2 == NULL) return (ISC_TRUE); else if (rsa1 == NULL || rsa2 == NULL) return (ISC_FALSE); status = BN_cmp(rsa1->n, rsa2->n) || BN_cmp(rsa1->e, rsa2->e); if (status != 0) return (ISC_FALSE); #if USE_EVP if ((rsa1->flags & RSA_FLAG_EXT_PKEY) != 0 || (rsa2->flags & RSA_FLAG_EXT_PKEY) != 0) { if ((rsa1->flags & RSA_FLAG_EXT_PKEY) == 0 || (rsa2->flags & RSA_FLAG_EXT_PKEY) == 0) return (ISC_FALSE); /* * Can't compare private parameters, BTW does it make sense? */ return (ISC_TRUE); } #endif if (rsa1->d != NULL || rsa2->d != NULL) { if (rsa1->d == NULL || rsa2->d == NULL) return (ISC_FALSE); status = BN_cmp(rsa1->d, rsa2->d) || BN_cmp(rsa1->p, rsa2->p) || BN_cmp(rsa1->q, rsa2->q); if (status != 0) return (ISC_FALSE); } return (ISC_TRUE); } #if OPENSSL_VERSION_NUMBER > 0x00908000L static int progress_cb(int p, int n, BN_GENCB *cb) { union { void *dptr; void (*fptr)(int); } u; UNUSED(n); u.dptr = BN_GENCB_get_arg(cb); if (u.fptr != NULL) u.fptr(p); return (1); } #endif static isc_result_t opensslrsa_generate(dst_key_t *key, int exp, void (*callback)(int)) { #if OPENSSL_VERSION_NUMBER > 0x00908000L isc_result_t ret = DST_R_OPENSSLFAILURE; union { void *dptr; void (*fptr)(int); } u; RSA *rsa = RSA_new(); BIGNUM *e = BN_new(); #if OPENSSL_VERSION_NUMBER < 0x10100000L BN_GENCB _cb; #endif BN_GENCB *cb = BN_GENCB_new(); #if USE_EVP EVP_PKEY *pkey = EVP_PKEY_new(); #endif if (rsa == NULL || e == NULL || cb == NULL) goto err; #if USE_EVP if (pkey == NULL) goto err; if (!EVP_PKEY_set1_RSA(pkey, rsa)) goto err; #endif if (exp == 0) { /* RSA_F4 0x10001 */ BN_set_bit(e, 0); BN_set_bit(e, 16); } else { /* (phased-out) F5 0x100000001 */ BN_set_bit(e, 0); BN_set_bit(e, 32); } if (callback == NULL) { BN_GENCB_set_old(cb, NULL, NULL); } else { u.fptr = callback; BN_GENCB_set(cb, &progress_cb, u.dptr); } if (RSA_generate_key_ex(rsa, key->key_size, e, cb)) { BN_free(e); BN_GENCB_free(cb); SET_FLAGS(rsa); #if USE_EVP key->keydata.pkey = pkey; RSA_free(rsa); #else key->keydata.rsa = rsa; #endif return (ISC_R_SUCCESS); } BN_GENCB_free(cb); ret = dst__openssl_toresult2("RSA_generate_key_ex", DST_R_OPENSSLFAILURE); err: #if USE_EVP if (pkey != NULL) EVP_PKEY_free(pkey); #endif if (e != NULL) BN_free(e); if (rsa != NULL) RSA_free(rsa); if (cb != NULL) BN_GENCB_free(cb); return (dst__openssl_toresult(ret)); #else RSA *rsa; unsigned long e; #if USE_EVP EVP_PKEY *pkey = EVP_PKEY_new(); UNUSED(callback); if (pkey == NULL) return (ISC_R_NOMEMORY); #else UNUSED(callback); #endif if (exp == 0) e = RSA_F4; else e = 0x40000003; rsa = RSA_generate_key(key->key_size, e, NULL, NULL); if (rsa == NULL) { #if USE_EVP EVP_PKEY_free(pkey); #endif return (dst__openssl_toresult2("RSA_generate_key", DST_R_OPENSSLFAILURE)); } SET_FLAGS(rsa); #if USE_EVP if (!EVP_PKEY_set1_RSA(pkey, rsa)) { EVP_PKEY_free(pkey); RSA_free(rsa); return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); } key->keydata.pkey = pkey; RSA_free(rsa); #else key->keydata.rsa = rsa; #endif return (ISC_R_SUCCESS); #endif } static isc_boolean_t opensslrsa_isprivate(const dst_key_t *key) { #if USE_EVP RSA *rsa = EVP_PKEY_get1_RSA(key->keydata.pkey); INSIST(rsa != NULL); RSA_free(rsa); /* key->keydata.pkey still has a reference so rsa is still valid. */ #else RSA *rsa = key->keydata.rsa; #endif if (rsa != NULL && (rsa->flags & RSA_FLAG_EXT_PKEY) != 0) return (ISC_TRUE); return (ISC_TF(rsa != NULL && rsa->d != NULL)); } static void opensslrsa_destroy(dst_key_t *key) { #if USE_EVP EVP_PKEY *pkey = key->keydata.pkey; EVP_PKEY_free(pkey); key->keydata.pkey = NULL; #else RSA *rsa = key->keydata.rsa; RSA_free(rsa); key->keydata.rsa = NULL; #endif } static isc_result_t opensslrsa_todns(const dst_key_t *key, isc_buffer_t *data) { isc_region_t r; unsigned int e_bytes; unsigned int mod_bytes; isc_result_t ret; RSA *rsa; #if USE_EVP EVP_PKEY *pkey; #endif #if USE_EVP REQUIRE(key->keydata.pkey != NULL); #else REQUIRE(key->keydata.rsa != NULL); #endif #if USE_EVP pkey = key->keydata.pkey; rsa = EVP_PKEY_get1_RSA(pkey); if (rsa == NULL) return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); #else rsa = key->keydata.rsa; #endif isc_buffer_availableregion(data, &r); e_bytes = BN_num_bytes(rsa->e); mod_bytes = BN_num_bytes(rsa->n); if (e_bytes < 256) { /*%< key exponent is <= 2040 bits */ if (r.length < 1) DST_RET(ISC_R_NOSPACE); isc_buffer_putuint8(data, (isc_uint8_t) e_bytes); isc_region_consume(&r, 1); } else { if (r.length < 3) DST_RET(ISC_R_NOSPACE); isc_buffer_putuint8(data, 0); isc_buffer_putuint16(data, (isc_uint16_t) e_bytes); isc_region_consume(&r, 3); } if (r.length < e_bytes + mod_bytes) DST_RET(ISC_R_NOSPACE); BN_bn2bin(rsa->e, r.base); isc_region_consume(&r, e_bytes); BN_bn2bin(rsa->n, r.base); isc_buffer_add(data, e_bytes + mod_bytes); ret = ISC_R_SUCCESS; err: #if USE_EVP if (rsa != NULL) RSA_free(rsa); #endif return (ret); } static isc_result_t opensslrsa_fromdns(dst_key_t *key, isc_buffer_t *data) { RSA *rsa; isc_region_t r; unsigned int e_bytes; unsigned int length; #if USE_EVP EVP_PKEY *pkey; #endif isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); length = r.length; rsa = RSA_new(); if (rsa == NULL) return (dst__openssl_toresult(ISC_R_NOMEMORY)); SET_FLAGS(rsa); if (r.length < 1) { RSA_free(rsa); return (DST_R_INVALIDPUBLICKEY); } e_bytes = *r.base; isc_region_consume(&r, 1); if (e_bytes == 0) { if (r.length < 2) { RSA_free(rsa); return (DST_R_INVALIDPUBLICKEY); } e_bytes = (*r.base) << 8; isc_region_consume(&r, 1); e_bytes += *r.base; isc_region_consume(&r, 1); } if (r.length < e_bytes) { RSA_free(rsa); return (DST_R_INVALIDPUBLICKEY); } rsa->e = BN_bin2bn(r.base, e_bytes, NULL); isc_region_consume(&r, e_bytes); rsa->n = BN_bin2bn(r.base, r.length, NULL); key->key_size = BN_num_bits(rsa->n); isc_buffer_forward(data, length); #if USE_EVP pkey = EVP_PKEY_new(); if (pkey == NULL) { RSA_free(rsa); return (ISC_R_NOMEMORY); } if (!EVP_PKEY_set1_RSA(pkey, rsa)) { EVP_PKEY_free(pkey); RSA_free(rsa); return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); } key->keydata.pkey = pkey; RSA_free(rsa); #else key->keydata.rsa = rsa; #endif return (ISC_R_SUCCESS); } static isc_result_t opensslrsa_tofile(const dst_key_t *key, const char *directory) { int i; RSA *rsa; dst_private_t priv; unsigned char *bufs[8]; isc_result_t result; #if USE_EVP if (key->keydata.pkey == NULL) return (DST_R_NULLKEY); rsa = EVP_PKEY_get1_RSA(key->keydata.pkey); if (rsa == NULL) return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); #else if (key->keydata.rsa == NULL) return (DST_R_NULLKEY); rsa = key->keydata.rsa; #endif memset(bufs, 0, sizeof(bufs)); if (key->external) { priv.nelements = 0; result = dst__privstruct_writefile(key, &priv, directory); goto fail; } for (i = 0; i < 8; i++) { bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(rsa->n)); if (bufs[i] == NULL) { result = ISC_R_NOMEMORY; goto fail; } } i = 0; priv.elements[i].tag = TAG_RSA_MODULUS; priv.elements[i].length = BN_num_bytes(rsa->n); BN_bn2bin(rsa->n, bufs[i]); priv.elements[i].data = bufs[i]; i++; priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT; priv.elements[i].length = BN_num_bytes(rsa->e); BN_bn2bin(rsa->e, bufs[i]); priv.elements[i].data = bufs[i]; i++; if (rsa->d != NULL) { priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT; priv.elements[i].length = BN_num_bytes(rsa->d); BN_bn2bin(rsa->d, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (rsa->p != NULL) { priv.elements[i].tag = TAG_RSA_PRIME1; priv.elements[i].length = BN_num_bytes(rsa->p); BN_bn2bin(rsa->p, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (rsa->q != NULL) { priv.elements[i].tag = TAG_RSA_PRIME2; priv.elements[i].length = BN_num_bytes(rsa->q); BN_bn2bin(rsa->q, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (rsa->dmp1 != NULL) { priv.elements[i].tag = TAG_RSA_EXPONENT1; priv.elements[i].length = BN_num_bytes(rsa->dmp1); BN_bn2bin(rsa->dmp1, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (rsa->dmq1 != NULL) { priv.elements[i].tag = TAG_RSA_EXPONENT2; priv.elements[i].length = BN_num_bytes(rsa->dmq1); BN_bn2bin(rsa->dmq1, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (rsa->iqmp != NULL) { priv.elements[i].tag = TAG_RSA_COEFFICIENT; priv.elements[i].length = BN_num_bytes(rsa->iqmp); BN_bn2bin(rsa->iqmp, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (key->engine != NULL) { priv.elements[i].tag = TAG_RSA_ENGINE; priv.elements[i].length = strlen(key->engine) + 1; priv.elements[i].data = (unsigned char *)key->engine; i++; } if (key->label != NULL) { priv.elements[i].tag = TAG_RSA_LABEL; priv.elements[i].length = strlen(key->label) + 1; priv.elements[i].data = (unsigned char *)key->label; i++; } priv.nelements = i; result = dst__privstruct_writefile(key, &priv, directory); fail: #if USE_EVP RSA_free(rsa); #endif for (i = 0; i < 8; i++) { if (bufs[i] == NULL) break; isc_mem_put(key->mctx, bufs[i], BN_num_bytes(rsa->n)); } return (result); } static isc_result_t rsa_check(RSA *rsa, RSA *pub) { /* Public parameters should be the same but if they are not set * copy them from the public key. */ if (pub != NULL) { if (rsa->n != NULL) { if (BN_cmp(rsa->n, pub->n) != 0) return (DST_R_INVALIDPRIVATEKEY); } else { rsa->n = pub->n; pub->n = NULL; } if (rsa->e != NULL) { if (BN_cmp(rsa->e, pub->e) != 0) return (DST_R_INVALIDPRIVATEKEY); } else { rsa->e = pub->e; pub->e = NULL; } } if (rsa->n == NULL || rsa->e == NULL) return (DST_R_INVALIDPRIVATEKEY); return (ISC_R_SUCCESS); } static isc_result_t opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t ret; int i; RSA *rsa = NULL, *pubrsa = NULL; #ifdef USE_ENGINE ENGINE *e = NULL; #endif isc_mem_t *mctx = key->mctx; const char *engine = NULL, *label = NULL; #if defined(USE_ENGINE) || USE_EVP EVP_PKEY *pkey = NULL; #endif /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) goto err; if (key->external) { if (priv.nelements != 0) DST_RET(DST_R_INVALIDPRIVATEKEY); if (pub == NULL) DST_RET(DST_R_INVALIDPRIVATEKEY); key->keydata.pkey = pub->keydata.pkey; pub->keydata.pkey = NULL; key->key_size = pub->key_size; dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ISC_R_SUCCESS); } #if USE_EVP if (pub != NULL && pub->keydata.pkey != NULL) pubrsa = EVP_PKEY_get1_RSA(pub->keydata.pkey); #else if (pub != NULL && pub->keydata.rsa != NULL) { pubrsa = pub->keydata.rsa; pub->keydata.rsa = NULL; } #endif for (i = 0; i < priv.nelements; i++) { switch (priv.elements[i].tag) { case TAG_RSA_ENGINE: engine = (char *)priv.elements[i].data; break; case TAG_RSA_LABEL: label = (char *)priv.elements[i].data; break; default: break; } } /* * Is this key is stored in a HSM? * See if we can fetch it. */ if (label != NULL) { #ifdef USE_ENGINE if (engine == NULL) DST_RET(DST_R_NOENGINE); e = dst__openssl_getengine(engine); if (e == NULL) DST_RET(DST_R_NOENGINE); pkey = ENGINE_load_private_key(e, label, NULL, NULL); if (pkey == NULL) DST_RET(dst__openssl_toresult2( "ENGINE_load_private_key", ISC_R_NOTFOUND)); key->engine = isc_mem_strdup(key->mctx, engine); if (key->engine == NULL) DST_RET(ISC_R_NOMEMORY); key->label = isc_mem_strdup(key->mctx, label); if (key->label == NULL) DST_RET(ISC_R_NOMEMORY); rsa = EVP_PKEY_get1_RSA(pkey); if (rsa == NULL) DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) DST_RET(DST_R_INVALIDPRIVATEKEY); if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS) DST_RET(ISC_R_RANGE); if (pubrsa != NULL) RSA_free(pubrsa); key->key_size = EVP_PKEY_bits(pkey); #if USE_EVP key->keydata.pkey = pkey; RSA_free(rsa); #else key->keydata.rsa = rsa; EVP_PKEY_free(pkey); #endif dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ISC_R_SUCCESS); #else DST_RET(DST_R_NOENGINE); #endif } rsa = RSA_new(); if (rsa == NULL) DST_RET(ISC_R_NOMEMORY); SET_FLAGS(rsa); #if USE_EVP pkey = EVP_PKEY_new(); if (pkey == NULL) DST_RET(ISC_R_NOMEMORY); if (!EVP_PKEY_set1_RSA(pkey, rsa)) DST_RET(ISC_R_FAILURE); key->keydata.pkey = pkey; #else key->keydata.rsa = rsa; #endif for (i = 0; i < priv.nelements; i++) { BIGNUM *bn; switch (priv.elements[i].tag) { case TAG_RSA_ENGINE: continue; case TAG_RSA_LABEL: continue; default: bn = BN_bin2bn(priv.elements[i].data, priv.elements[i].length, NULL); if (bn == NULL) DST_RET(ISC_R_NOMEMORY); } switch (priv.elements[i].tag) { case TAG_RSA_MODULUS: rsa->n = bn; break; case TAG_RSA_PUBLICEXPONENT: rsa->e = bn; break; case TAG_RSA_PRIVATEEXPONENT: rsa->d = bn; break; case TAG_RSA_PRIME1: rsa->p = bn; break; case TAG_RSA_PRIME2: rsa->q = bn; break; case TAG_RSA_EXPONENT1: rsa->dmp1 = bn; break; case TAG_RSA_EXPONENT2: rsa->dmq1 = bn; break; case TAG_RSA_COEFFICIENT: rsa->iqmp = bn; break; } } dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) DST_RET(DST_R_INVALIDPRIVATEKEY); if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS) DST_RET(ISC_R_RANGE); key->key_size = BN_num_bits(rsa->n); if (pubrsa != NULL) RSA_free(pubrsa); #if USE_EVP RSA_free(rsa); #endif return (ISC_R_SUCCESS); err: #if USE_EVP if (pkey != NULL) EVP_PKEY_free(pkey); #endif if (rsa != NULL) RSA_free(rsa); if (pubrsa != NULL) RSA_free(pubrsa); key->keydata.generic = NULL; dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ret); } static isc_result_t opensslrsa_fromlabel(dst_key_t *key, const char *engine, const char *label, const char *pin) { #ifdef USE_ENGINE ENGINE *e = NULL; isc_result_t ret; EVP_PKEY *pkey = NULL; RSA *rsa = NULL, *pubrsa = NULL; char *colon, *tmpengine = NULL; UNUSED(pin); if (engine == NULL) { colon = strchr(label, ':'); if (colon == NULL) DST_RET(DST_R_NOENGINE); tmpengine = isc_mem_strdup(key->mctx, label); if (tmpengine == NULL) DST_RET(ISC_R_NOMEMORY); colon = strchr(tmpengine, ':'); INSIST(colon != NULL); *colon = '\0'; } e = dst__openssl_getengine(engine); if (e == NULL) DST_RET(DST_R_NOENGINE); pkey = ENGINE_load_public_key(e, label, NULL, NULL); if (pkey != NULL) { pubrsa = EVP_PKEY_get1_RSA(pkey); EVP_PKEY_free(pkey); if (pubrsa == NULL) DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); } pkey = ENGINE_load_private_key(e, label, NULL, NULL); if (pkey == NULL) DST_RET(dst__openssl_toresult2("ENGINE_load_private_key", ISC_R_NOTFOUND)); if (tmpengine != NULL) { key->engine = tmpengine; tmpengine = NULL; } else { key->engine = isc_mem_strdup(key->mctx, engine); if (key->engine == NULL) DST_RET(ISC_R_NOMEMORY); } key->label = isc_mem_strdup(key->mctx, label); if (key->label == NULL) DST_RET(ISC_R_NOMEMORY); rsa = EVP_PKEY_get1_RSA(pkey); if (rsa == NULL) DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) DST_RET(DST_R_INVALIDPRIVATEKEY); if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS) DST_RET(ISC_R_RANGE); if (pubrsa != NULL) RSA_free(pubrsa); key->key_size = EVP_PKEY_bits(pkey); #if USE_EVP key->keydata.pkey = pkey; RSA_free(rsa); #else key->keydata.rsa = rsa; EVP_PKEY_free(pkey); #endif return (ISC_R_SUCCESS); err: if (tmpengine != NULL) isc_mem_free(key->mctx, tmpengine); if (rsa != NULL) RSA_free(rsa); if (pubrsa != NULL) RSA_free(pubrsa); if (pkey != NULL) EVP_PKEY_free(pkey); return (ret); #else UNUSED(key); UNUSED(engine); UNUSED(label); UNUSED(pin); return(DST_R_NOENGINE); #endif } static dst_func_t opensslrsa_functions = { opensslrsa_createctx, NULL, /*%< createctx2 */ opensslrsa_destroyctx, opensslrsa_adddata, opensslrsa_sign, opensslrsa_verify, opensslrsa_verify2, NULL, /*%< computesecret */ opensslrsa_compare, NULL, /*%< paramcompare */ opensslrsa_generate, opensslrsa_isprivate, opensslrsa_destroy, opensslrsa_todns, opensslrsa_fromdns, opensslrsa_tofile, opensslrsa_parse, NULL, /*%< cleanup */ opensslrsa_fromlabel, NULL, /*%< dump */ NULL, /*%< restore */ }; isc_result_t dst__opensslrsa_init(dst_func_t **funcp, unsigned char algorithm) { REQUIRE(funcp != NULL); if (*funcp == NULL) { switch (algorithm) { case DST_ALG_RSASHA256: #if defined(HAVE_EVP_SHA256) || !USE_EVP *funcp = &opensslrsa_functions; #endif break; case DST_ALG_RSASHA512: #if defined(HAVE_EVP_SHA512) || !USE_EVP *funcp = &opensslrsa_functions; #endif break; default: *funcp = &opensslrsa_functions; break; } } return (ISC_R_SUCCESS); } #else /* OPENSSL */ #include EMPTY_TRANSLATION_UNIT #endif /* OPENSSL */ /*! \file */ bind9-9.10.3.dfsg.P4/lib/dns/master.c0000644000470500017500000025035612664710322016375 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /*! * Grow the number of dns_rdatalist_t (#RDLSZ) and dns_rdata_t (#RDSZ) structures * by these sizes when we need to. * */ /*% RDLSZ reflects the number of different types with the same name expected. */ #define RDLSZ 32 /*% * RDSZ reflects the number of rdata expected at a give name that can fit into * 64k. */ #define RDSZ 512 #define NBUFS 4 #define MAXWIRESZ 255 /*% * Target buffer size and minimum target size. * MINTSIZ must be big enough to hold the largest rdata record. * \brief * TSIZ >= MINTSIZ */ #define TSIZ (128*1024) /*% * max message size - header - root - type - class - ttl - rdlen */ #define MINTSIZ DNS_RDATA_MAXLENGTH /*% * Size for tokens in the presentation format, * The largest tokens are the base64 blocks in KEY and CERT records, * Largest key allowed is about 1372 bytes but * there is no fixed upper bound on CERT records. * 2K is too small for some X.509s, 8K is overkill. */ #define TOKENSIZ (8*1024) /*% * Buffers sizes for $GENERATE. */ #define DNS_MASTER_LHS 2048 #define DNS_MASTER_RHS MINTSIZ #define CHECKNAMESFAIL(x) (((x) & DNS_MASTER_CHECKNAMESFAIL) != 0) typedef ISC_LIST(dns_rdatalist_t) rdatalist_head_t; typedef struct dns_incctx dns_incctx_t; /*% * Master file load state. */ struct dns_loadctx { unsigned int magic; isc_mem_t *mctx; dns_masterformat_t format; dns_rdatacallbacks_t *callbacks; isc_task_t *task; dns_loaddonefunc_t done; void *done_arg; /* Common methods */ isc_result_t (*openfile)(dns_loadctx_t *lctx, const char *filename); isc_result_t (*load)(dns_loadctx_t *lctx); /* Members used by all formats */ isc_uint32_t maxttl; /* Members specific to the text format: */ isc_lex_t *lex; isc_boolean_t keep_lex; unsigned int options; isc_boolean_t ttl_known; isc_boolean_t default_ttl_known; isc_boolean_t warn_1035; isc_boolean_t warn_tcr; isc_boolean_t warn_sigexpired; isc_boolean_t seen_include; isc_uint32_t ttl; isc_uint32_t default_ttl; dns_rdataclass_t zclass; dns_fixedname_t fixed_top; dns_name_t *top; /*%< top of zone */ /* Members specific to the raw format: */ FILE *f; isc_boolean_t first; dns_masterrawheader_t header; /* Which fixed buffers we are using? */ unsigned int loop_cnt; /*% records per quantum, * 0 => all. */ isc_boolean_t canceled; isc_mutex_t lock; isc_result_t result; /* locked by lock */ isc_uint32_t references; dns_incctx_t *inc; isc_uint32_t resign; dns_masterincludecb_t include_cb; void *include_arg; }; struct dns_incctx { dns_incctx_t *parent; dns_name_t *origin; dns_name_t *current; dns_name_t *glue; dns_fixedname_t fixed[NBUFS]; /* working buffers */ unsigned int in_use[NBUFS]; /* covert to bitmap? */ int glue_in_use; int current_in_use; int origin_in_use; isc_boolean_t origin_changed; isc_boolean_t drop; unsigned int glue_line; unsigned int current_line; }; #define DNS_LCTX_MAGIC ISC_MAGIC('L','c','t','x') #define DNS_LCTX_VALID(lctx) ISC_MAGIC_VALID(lctx, DNS_LCTX_MAGIC) #define DNS_AS_STR(t) ((t).value.as_textregion.base) static isc_result_t openfile_text(dns_loadctx_t *lctx, const char *master_file); static isc_result_t load_text(dns_loadctx_t *lctx); static isc_result_t openfile_raw(dns_loadctx_t *lctx, const char *master_file); static isc_result_t load_raw(dns_loadctx_t *lctx); static isc_result_t openfile_map(dns_loadctx_t *lctx, const char *master_file); static isc_result_t load_map(dns_loadctx_t *lctx); static isc_result_t pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx); static isc_result_t commit(dns_rdatacallbacks_t *, dns_loadctx_t *, rdatalist_head_t *, dns_name_t *, const char *, unsigned int); static isc_boolean_t is_glue(rdatalist_head_t *, dns_name_t *); static dns_rdatalist_t * grow_rdatalist(int, dns_rdatalist_t *, int, rdatalist_head_t *, rdatalist_head_t *, isc_mem_t *mctx); static dns_rdata_t * grow_rdata(int, dns_rdata_t *, int, rdatalist_head_t *, rdatalist_head_t *, isc_mem_t *); static void load_quantum(isc_task_t *task, isc_event_t *event); static isc_result_t task_send(dns_loadctx_t *lctx); static void loadctx_destroy(dns_loadctx_t *lctx); #define GETTOKENERR(lexer, options, token, eol, err) \ do { \ result = gettoken(lexer, options, token, eol, callbacks); \ switch (result) { \ case ISC_R_SUCCESS: \ break; \ case ISC_R_UNEXPECTED: \ goto insist_and_cleanup; \ default: \ if (MANYERRS(lctx, result)) { \ SETRESULT(lctx, result); \ LOGIT(result); \ read_till_eol = ISC_TRUE; \ err \ goto next_line; \ } else \ goto log_and_cleanup; \ } \ if ((token)->type == isc_tokentype_special) { \ result = DNS_R_SYNTAX; \ if (MANYERRS(lctx, result)) { \ SETRESULT(lctx, result); \ LOGIT(result); \ read_till_eol = ISC_TRUE; \ goto next_line; \ } else \ goto log_and_cleanup; \ } \ } while (0) #define GETTOKEN(lexer, options, token, eol) \ GETTOKENERR(lexer, options, token, eol, {} ) #define COMMITALL \ do { \ result = commit(callbacks, lctx, ¤t_list, \ ictx->current, source, ictx->current_line); \ if (MANYERRS(lctx, result)) { \ SETRESULT(lctx, result); \ } else if (result != ISC_R_SUCCESS) \ goto insist_and_cleanup; \ result = commit(callbacks, lctx, &glue_list, \ ictx->glue, source, ictx->glue_line); \ if (MANYERRS(lctx, result)) { \ SETRESULT(lctx, result); \ } else if (result != ISC_R_SUCCESS) \ goto insist_and_cleanup; \ rdcount = 0; \ rdlcount = 0; \ isc_buffer_init(&target, target_mem, target_size); \ rdcount_save = rdcount; \ rdlcount_save = rdlcount; \ } while (0) #define WARNUNEXPECTEDEOF(lexer) \ do { \ if (isc_lex_isfile(lexer)) \ (*callbacks->warn)(callbacks, \ "%s: file does not end with newline", \ source); \ } while (0) #define EXPECTEOL \ do { \ GETTOKEN(lctx->lex, 0, &token, ISC_TRUE); \ if (token.type != isc_tokentype_eol) { \ isc_lex_ungettoken(lctx->lex, &token); \ result = DNS_R_EXTRATOKEN; \ if (MANYERRS(lctx, result)) { \ SETRESULT(lctx, result); \ LOGIT(result); \ read_till_eol = ISC_TRUE; \ break; \ } else if (result != ISC_R_SUCCESS) \ goto log_and_cleanup; \ } \ } while (0) #define MANYERRS(lctx, result) \ ((result != ISC_R_SUCCESS) && \ (result != ISC_R_IOERROR) && \ ((lctx)->options & DNS_MASTER_MANYERRORS) != 0) #define SETRESULT(lctx, r) \ do { \ if ((lctx)->result == ISC_R_SUCCESS) \ (lctx)->result = r; \ } while (0) #define LOGITFILE(result, filename) \ if (result == ISC_R_INVALIDFILE || result == ISC_R_FILENOTFOUND || \ result == ISC_R_IOERROR || result == ISC_R_TOOMANYOPENFILES || \ result == ISC_R_NOPERM) \ (*callbacks->error)(callbacks, "%s: %s:%lu: %s: %s", \ "dns_master_load", source, line, \ filename, dns_result_totext(result)); \ else LOGIT(result) #define LOGIT(result) \ if (result == ISC_R_NOMEMORY) \ (*callbacks->error)(callbacks, "dns_master_load: %s", \ dns_result_totext(result)); \ else \ (*callbacks->error)(callbacks, "%s: %s:%lu: %s", \ "dns_master_load", \ source, line, dns_result_totext(result)) static unsigned char in_addr_arpa_data[] = "\007IN-ADDR\004ARPA"; static unsigned char in_addr_arpa_offsets[] = { 0, 8, 13 }; static const dns_name_t in_addr_arpa = { DNS_NAME_MAGIC, in_addr_arpa_data, 14, 3, DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, in_addr_arpa_offsets, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} }; static unsigned char ip6_int_data[] = "\003IP6\003INT"; static unsigned char ip6_int_offsets[] = { 0, 4, 8 }; static const dns_name_t ip6_int = { DNS_NAME_MAGIC, ip6_int_data, 9, 3, DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, ip6_int_offsets, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} }; static unsigned char ip6_arpa_data[] = "\003IP6\004ARPA"; static unsigned char ip6_arpa_offsets[] = { 0, 4, 9 }; static const dns_name_t ip6_arpa = { DNS_NAME_MAGIC, ip6_arpa_data, 10, 3, DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, ip6_arpa_offsets, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} }; static inline isc_result_t gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *token, isc_boolean_t eol, dns_rdatacallbacks_t *callbacks) { isc_result_t result; options |= ISC_LEXOPT_EOL | ISC_LEXOPT_EOF | ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE; result = isc_lex_gettoken(lex, options, token); if (result != ISC_R_SUCCESS) { switch (result) { case ISC_R_NOMEMORY: return (ISC_R_NOMEMORY); default: (*callbacks->error)(callbacks, "dns_master_load: %s:%lu:" " isc_lex_gettoken() failed: %s", isc_lex_getsourcename(lex), isc_lex_getsourceline(lex), isc_result_totext(result)); return (result); } /*NOTREACHED*/ } if (eol != ISC_TRUE) if (token->type == isc_tokentype_eol || token->type == isc_tokentype_eof) { unsigned long int line; const char *what; const char *file; file = isc_lex_getsourcename(lex); line = isc_lex_getsourceline(lex); if (token->type == isc_tokentype_eol) { line--; what = "line"; } else what = "file"; (*callbacks->error)(callbacks, "dns_master_load: %s:%lu: unexpected end of %s", file, line, what); return (ISC_R_UNEXPECTEDEND); } return (ISC_R_SUCCESS); } void dns_loadctx_attach(dns_loadctx_t *source, dns_loadctx_t **target) { REQUIRE(target != NULL && *target == NULL); REQUIRE(DNS_LCTX_VALID(source)); LOCK(&source->lock); INSIST(source->references > 0); source->references++; INSIST(source->references != 0); /* Overflow? */ UNLOCK(&source->lock); *target = source; } void dns_loadctx_detach(dns_loadctx_t **lctxp) { dns_loadctx_t *lctx; isc_boolean_t need_destroy = ISC_FALSE; REQUIRE(lctxp != NULL); lctx = *lctxp; REQUIRE(DNS_LCTX_VALID(lctx)); LOCK(&lctx->lock); INSIST(lctx->references > 0); lctx->references--; if (lctx->references == 0) need_destroy = ISC_TRUE; UNLOCK(&lctx->lock); if (need_destroy) loadctx_destroy(lctx); *lctxp = NULL; } static void incctx_destroy(isc_mem_t *mctx, dns_incctx_t *ictx) { dns_incctx_t *parent; again: parent = ictx->parent; ictx->parent = NULL; isc_mem_put(mctx, ictx, sizeof(*ictx)); if (parent != NULL) { ictx = parent; goto again; } } static void loadctx_destroy(dns_loadctx_t *lctx) { isc_mem_t *mctx; isc_result_t result; REQUIRE(DNS_LCTX_VALID(lctx)); lctx->magic = 0; if (lctx->inc != NULL) incctx_destroy(lctx->mctx, lctx->inc); if (lctx->f != NULL) { result = isc_stdio_close(lctx->f); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_stdio_close() failed: %s", isc_result_totext(result)); } } /* isc_lex_destroy() will close all open streams */ if (lctx->lex != NULL && !lctx->keep_lex) isc_lex_destroy(&lctx->lex); if (lctx->task != NULL) isc_task_detach(&lctx->task); DESTROYLOCK(&lctx->lock); mctx = NULL; isc_mem_attach(lctx->mctx, &mctx); isc_mem_detach(&lctx->mctx); isc_mem_put(mctx, lctx, sizeof(*lctx)); isc_mem_detach(&mctx); } static isc_result_t incctx_create(isc_mem_t *mctx, dns_name_t *origin, dns_incctx_t **ictxp) { dns_incctx_t *ictx; isc_region_t r; int i; ictx = isc_mem_get(mctx, sizeof(*ictx)); if (ictx == NULL) return (ISC_R_NOMEMORY); for (i = 0; i < NBUFS; i++) { dns_fixedname_init(&ictx->fixed[i]); ictx->in_use[i] = ISC_FALSE; } ictx->origin_in_use = 0; ictx->origin = dns_fixedname_name(&ictx->fixed[ictx->origin_in_use]); ictx->in_use[ictx->origin_in_use] = ISC_TRUE; dns_name_toregion(origin, &r); dns_name_fromregion(ictx->origin, &r); ictx->glue = NULL; ictx->current = NULL; ictx->glue_in_use = -1; ictx->current_in_use = -1; ictx->parent = NULL; ictx->drop = ISC_FALSE; ictx->glue_line = 0; ictx->current_line = 0; ictx->origin_changed = ISC_TRUE; *ictxp = ictx; return (ISC_R_SUCCESS); } static isc_result_t loadctx_create(dns_masterformat_t format, isc_mem_t *mctx, unsigned int options, isc_uint32_t resign, dns_name_t *top, dns_rdataclass_t zclass, dns_name_t *origin, dns_rdatacallbacks_t *callbacks, isc_task_t *task, dns_loaddonefunc_t done, void *done_arg, dns_masterincludecb_t include_cb, void *include_arg, isc_lex_t *lex, dns_loadctx_t **lctxp) { dns_loadctx_t *lctx; isc_result_t result; isc_region_t r; isc_lexspecials_t specials; REQUIRE(lctxp != NULL && *lctxp == NULL); REQUIRE(callbacks != NULL); REQUIRE(callbacks->add != NULL); REQUIRE(callbacks->error != NULL); REQUIRE(callbacks->warn != NULL); REQUIRE(mctx != NULL); REQUIRE(dns_name_isabsolute(top)); REQUIRE(dns_name_isabsolute(origin)); REQUIRE((task == NULL && done == NULL) || (task != NULL && done != NULL)); lctx = isc_mem_get(mctx, sizeof(*lctx)); if (lctx == NULL) return (ISC_R_NOMEMORY); result = isc_mutex_init(&lctx->lock); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, lctx, sizeof(*lctx)); return (result); } lctx->inc = NULL; result = incctx_create(mctx, origin, &lctx->inc); if (result != ISC_R_SUCCESS) goto cleanup_ctx; lctx->maxttl = 0; lctx->format = format; switch (format) { default: INSIST(0); case dns_masterformat_text: lctx->openfile = openfile_text; lctx->load = load_text; break; case dns_masterformat_raw: lctx->openfile = openfile_raw; lctx->load = load_raw; break; case dns_masterformat_map: lctx->openfile = openfile_map; lctx->load = load_map; break; } if (lex != NULL) { lctx->lex = lex; lctx->keep_lex = ISC_TRUE; } else { lctx->lex = NULL; result = isc_lex_create(mctx, TOKENSIZ, &lctx->lex); if (result != ISC_R_SUCCESS) goto cleanup_inc; lctx->keep_lex = ISC_FALSE; memset(specials, 0, sizeof(specials)); specials[0] = 1; specials['('] = 1; specials[')'] = 1; specials['"'] = 1; isc_lex_setspecials(lctx->lex, specials); isc_lex_setcomments(lctx->lex, ISC_LEXCOMMENT_DNSMASTERFILE); } lctx->ttl_known = ISC_TF((options & DNS_MASTER_NOTTL) != 0); lctx->ttl = 0; lctx->default_ttl_known = lctx->ttl_known; lctx->default_ttl = 0; lctx->warn_1035 = ISC_TRUE; /* XXX Argument? */ lctx->warn_tcr = ISC_TRUE; /* XXX Argument? */ lctx->warn_sigexpired = ISC_TRUE; /* XXX Argument? */ lctx->options = options; lctx->seen_include = ISC_FALSE; lctx->zclass = zclass; lctx->resign = resign; lctx->result = ISC_R_SUCCESS; lctx->include_cb = include_cb; lctx->include_arg = include_arg; dns_fixedname_init(&lctx->fixed_top); lctx->top = dns_fixedname_name(&lctx->fixed_top); dns_name_toregion(top, &r); dns_name_fromregion(lctx->top, &r); lctx->f = NULL; lctx->first = ISC_TRUE; dns_master_initrawheader(&lctx->header); lctx->loop_cnt = (done != NULL) ? 100 : 0; lctx->callbacks = callbacks; lctx->task = NULL; if (task != NULL) isc_task_attach(task, &lctx->task); lctx->done = done; lctx->done_arg = done_arg; lctx->canceled = ISC_FALSE; lctx->mctx = NULL; isc_mem_attach(mctx, &lctx->mctx); lctx->references = 1; /* Implicit attach. */ lctx->magic = DNS_LCTX_MAGIC; *lctxp = lctx; return (ISC_R_SUCCESS); cleanup_inc: incctx_destroy(mctx, lctx->inc); cleanup_ctx: isc_mem_put(mctx, lctx, sizeof(*lctx)); return (result); } static const char *hex = "0123456789abcdef0123456789ABCDEF"; /*% * Convert value into a nibble sequence from least significant to most * significant nibble. Zero fill upper most significant nibbles if * required to make the width. * * Returns the number of characters that should have been written without * counting the terminating NUL. */ static unsigned int nibbles(char *numbuf, size_t length, unsigned int width, char mode, int value) { unsigned int count = 0; /* * This reserve space for the NUL string terminator. */ if (length > 0U) { *numbuf = '\0'; length--; } do { char val = hex[(value & 0x0f) + ((mode == 'n') ? 0 : 16)]; value >>= 4; if (length > 0U) { *numbuf++ = val; *numbuf = '\0'; length--; } if (width > 0) width--; count++; /* * If width is non zero then we need to add a label seperator. * If value is non zero then we need to add another label and * that requires a label seperator. */ if (width > 0 || value != 0) { if (length > 0U) { *numbuf++ = '.'; *numbuf = '\0'; length--; } if (width > 0) width--; count++; } } while (value != 0 || width > 0); return (count); } static isc_result_t genname(char *name, int it, char *buffer, size_t length) { char fmt[sizeof("%04000000000d")]; char numbuf[128]; char *cp; char mode[2]; int delta = 0; isc_textregion_t r; unsigned int n; unsigned int width; isc_boolean_t nibblemode; r.base = buffer; r.length = (unsigned int)length; while (*name != '\0') { if (*name == '$') { name++; if (*name == '$') { if (r.length == 0) return (ISC_R_NOSPACE); r.base[0] = *name++; isc_textregion_consume(&r, 1); continue; } nibblemode = ISC_FALSE; strcpy(fmt, "%d"); /* Get format specifier. */ if (*name == '{' ) { n = sscanf(name, "{%d,%u,%1[doxXnN]}", &delta, &width, mode); switch (n) { case 1: break; case 2: n = snprintf(fmt, sizeof(fmt), "%%0%ud", width); break; case 3: if (mode[0] == 'n' || mode[0] == 'N') nibblemode = ISC_TRUE; n = snprintf(fmt, sizeof(fmt), "%%0%u%c", width, mode[0]); break; default: return (DNS_R_SYNTAX); } if (n >= sizeof(fmt)) return (ISC_R_NOSPACE); /* Skip past closing brace. */ while (*name != '\0' && *name++ != '}') continue; } if (nibblemode) n = nibbles(numbuf, sizeof(numbuf), width, mode[0], it + delta); else n = snprintf(numbuf, sizeof(numbuf), fmt, it + delta); if (n >= sizeof(numbuf)) return (ISC_R_NOSPACE); cp = numbuf; while (*cp != '\0') { if (r.length == 0) return (ISC_R_NOSPACE); r.base[0] = *cp++; isc_textregion_consume(&r, 1); } } else if (*name == '\\') { if (r.length == 0) return (ISC_R_NOSPACE); r.base[0] = *name++; isc_textregion_consume(&r, 1); if (*name == '\0') continue; if (r.length == 0) return (ISC_R_NOSPACE); r.base[0] = *name++; isc_textregion_consume(&r, 1); } else { if (r.length == 0) return (ISC_R_NOSPACE); r.base[0] = *name++; isc_textregion_consume(&r, 1); } } if (r.length == 0) return (ISC_R_NOSPACE); r.base[0] = '\0'; return (ISC_R_SUCCESS); } static isc_result_t generate(dns_loadctx_t *lctx, char *range, char *lhs, char *gtype, char *rhs, const char *source, unsigned int line) { char *target_mem = NULL; char *lhsbuf = NULL; char *rhsbuf = NULL; dns_fixedname_t ownerfixed; dns_name_t *owner; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdatacallbacks_t *callbacks; dns_rdatalist_t rdatalist; dns_rdatatype_t type; rdatalist_head_t head; int target_size = MINTSIZ; /* only one rdata at a time */ isc_buffer_t buffer; isc_buffer_t target; isc_result_t result; isc_textregion_t r; int i, n, start, stop, step = 0; dns_incctx_t *ictx; char dummy; ictx = lctx->inc; callbacks = lctx->callbacks; dns_fixedname_init(&ownerfixed); owner = dns_fixedname_name(&ownerfixed); ISC_LIST_INIT(head); target_mem = isc_mem_get(lctx->mctx, target_size); rhsbuf = isc_mem_get(lctx->mctx, DNS_MASTER_RHS); lhsbuf = isc_mem_get(lctx->mctx, DNS_MASTER_LHS); if (target_mem == NULL || rhsbuf == NULL || lhsbuf == NULL) { result = ISC_R_NOMEMORY; goto error_cleanup; } isc_buffer_init(&target, target_mem, target_size); n = sscanf(range, "%d-%d%[/]%d", &start, &stop, &dummy, &step); if ((n != 2 && n != 4) || (start < 0) || (stop < 0) || (n == 4 && step < 1) || (stop < start)) { (*callbacks->error)(callbacks, "%s: %s:%lu: invalid range '%s'", "$GENERATE", source, line, range); result = DNS_R_SYNTAX; goto insist_cleanup; } if (n == 2) step = 1; /* * Get type. */ r.base = gtype; r.length = strlen(gtype); result = dns_rdatatype_fromtext(&type, &r); if (result != ISC_R_SUCCESS) { (*callbacks->error)(callbacks, "%s: %s:%lu: unknown RR type '%s'", "$GENERATE", source, line, gtype); goto insist_cleanup; } for (i = start; i <= stop; i += step) { result = genname(lhs, i, lhsbuf, DNS_MASTER_LHS); if (result != ISC_R_SUCCESS) goto error_cleanup; result = genname(rhs, i, rhsbuf, DNS_MASTER_RHS); if (result != ISC_R_SUCCESS) goto error_cleanup; isc_buffer_init(&buffer, lhsbuf, strlen(lhsbuf)); isc_buffer_add(&buffer, strlen(lhsbuf)); isc_buffer_setactive(&buffer, strlen(lhsbuf)); result = dns_name_fromtext(owner, &buffer, ictx->origin, 0, NULL); if (result != ISC_R_SUCCESS) goto error_cleanup; if ((lctx->options & DNS_MASTER_ZONE) != 0 && (lctx->options & DNS_MASTER_SLAVE) == 0 && (lctx->options & DNS_MASTER_KEY) == 0 && !dns_name_issubdomain(owner, lctx->top)) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(owner, namebuf, sizeof(namebuf)); /* * Ignore out-of-zone data. */ (*callbacks->warn)(callbacks, "%s:%lu: " "ignoring out-of-zone data (%s)", source, line, namebuf); continue; } isc_buffer_init(&buffer, rhsbuf, strlen(rhsbuf)); isc_buffer_add(&buffer, strlen(rhsbuf)); isc_buffer_setactive(&buffer, strlen(rhsbuf)); result = isc_lex_openbuffer(lctx->lex, &buffer); if (result != ISC_R_SUCCESS) goto error_cleanup; isc_buffer_init(&target, target_mem, target_size); result = dns_rdata_fromtext(&rdata, lctx->zclass, type, lctx->lex, ictx->origin, 0, lctx->mctx, &target, callbacks); RUNTIME_CHECK(isc_lex_close(lctx->lex) == ISC_R_SUCCESS); if (result != ISC_R_SUCCESS) goto error_cleanup; dns_rdatalist_init(&rdatalist); rdatalist.type = type; rdatalist.rdclass = lctx->zclass; rdatalist.ttl = lctx->ttl; ISC_LIST_PREPEND(head, &rdatalist, link); ISC_LIST_APPEND(rdatalist.rdata, &rdata, link); result = commit(callbacks, lctx, &head, owner, source, line); ISC_LIST_UNLINK(rdatalist.rdata, &rdata, link); if (result != ISC_R_SUCCESS) goto error_cleanup; dns_rdata_reset(&rdata); } result = ISC_R_SUCCESS; goto cleanup; error_cleanup: if (result == ISC_R_NOMEMORY) (*callbacks->error)(callbacks, "$GENERATE: %s", dns_result_totext(result)); else (*callbacks->error)(callbacks, "$GENERATE: %s:%lu: %s", source, line, dns_result_totext(result)); insist_cleanup: INSIST(result != ISC_R_SUCCESS); cleanup: if (target_mem != NULL) isc_mem_put(lctx->mctx, target_mem, target_size); if (lhsbuf != NULL) isc_mem_put(lctx->mctx, lhsbuf, DNS_MASTER_LHS); if (rhsbuf != NULL) isc_mem_put(lctx->mctx, rhsbuf, DNS_MASTER_RHS); return (result); } static void limit_ttl(dns_rdatacallbacks_t *callbacks, const char *source, unsigned int line, isc_uint32_t *ttlp) { if (*ttlp > 0x7fffffffUL) { (callbacks->warn)(callbacks, "%s: %s:%lu: " "$TTL %lu > MAXTTL, " "setting $TTL to 0", "dns_master_load", source, line, *ttlp); *ttlp = 0; } } static isc_result_t check_ns(dns_loadctx_t *lctx, isc_token_t *token, const char *source, unsigned long line) { char *tmp = NULL; isc_result_t result = ISC_R_SUCCESS; void (*callback)(struct dns_rdatacallbacks *, const char *, ...); if ((lctx->options & DNS_MASTER_FATALNS) != 0) callback = lctx->callbacks->error; else callback = lctx->callbacks->warn; if (token->type == isc_tokentype_string) { struct in_addr addr; struct in6_addr addr6; tmp = isc_mem_strdup(lctx->mctx, DNS_AS_STR(*token)); if (tmp == NULL) return (ISC_R_NOMEMORY); /* * Catch both "1.2.3.4" and "1.2.3.4." */ if (tmp[strlen(tmp) - 1] == '.') tmp[strlen(tmp) - 1] = '\0'; if (inet_aton(tmp, &addr) == 1 || inet_pton(AF_INET6, tmp, &addr6) == 1) result = DNS_R_NSISADDRESS; } if (result != ISC_R_SUCCESS) (*callback)(lctx->callbacks, "%s:%lu: NS record '%s' " "appears to be an address", source, line, DNS_AS_STR(*token)); if (tmp != NULL) isc_mem_free(lctx->mctx, tmp); return (result); } static void check_wildcard(dns_incctx_t *ictx, const char *source, unsigned long line, dns_rdatacallbacks_t *callbacks) { dns_name_t *name; name = (ictx->glue != NULL) ? ictx->glue : ictx->current; if (dns_name_internalwildcard(name)) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(name, namebuf, sizeof(namebuf)); (*callbacks->warn)(callbacks, "%s:%lu: warning: ownername " "'%s' contains an non-terminal wildcard", source, line, namebuf); } } static isc_result_t openfile_text(dns_loadctx_t *lctx, const char *master_file) { return (isc_lex_openfile(lctx->lex, master_file)); } static isc_result_t load_text(dns_loadctx_t *lctx) { dns_rdataclass_t rdclass; dns_rdatatype_t type, covers; isc_uint32_t ttl_offset = 0; dns_name_t *new_name; isc_boolean_t current_has_delegation = ISC_FALSE; isc_boolean_t done = ISC_FALSE; isc_boolean_t finish_origin = ISC_FALSE; isc_boolean_t finish_include = ISC_FALSE; isc_boolean_t read_till_eol = ISC_FALSE; isc_boolean_t initialws; char *include_file = NULL; isc_token_t token; isc_result_t result = ISC_R_UNEXPECTED; rdatalist_head_t glue_list; rdatalist_head_t current_list; dns_rdatalist_t *this; dns_rdatalist_t *rdatalist = NULL; dns_rdatalist_t *new_rdatalist; int rdlcount = 0; int rdlcount_save = 0; int rdatalist_size = 0; isc_buffer_t buffer; isc_buffer_t target; isc_buffer_t target_ft; isc_buffer_t target_save; dns_rdata_t *rdata = NULL; dns_rdata_t *new_rdata; int rdcount = 0; int rdcount_save = 0; int rdata_size = 0; unsigned char *target_mem = NULL; int target_size = TSIZ; int new_in_use; unsigned int loop_cnt = 0; isc_mem_t *mctx; dns_rdatacallbacks_t *callbacks; dns_incctx_t *ictx; char *range = NULL; char *lhs = NULL; char *gtype = NULL; char *rhs = NULL; const char *source = ""; unsigned long line = 0; isc_boolean_t explicit_ttl; isc_stdtime_t now; char classname1[DNS_RDATACLASS_FORMATSIZE]; char classname2[DNS_RDATACLASS_FORMATSIZE]; unsigned int options = 0; REQUIRE(DNS_LCTX_VALID(lctx)); callbacks = lctx->callbacks; mctx = lctx->mctx; ictx = lctx->inc; ISC_LIST_INIT(glue_list); ISC_LIST_INIT(current_list); isc_stdtime_get(&now); /* * Allocate target_size of buffer space. This is greater than twice * the maximum individual RR data size. */ target_mem = isc_mem_get(mctx, target_size); if (target_mem == NULL) { result = ISC_R_NOMEMORY; goto log_and_cleanup; } isc_buffer_init(&target, target_mem, target_size); target_save = target; if ((lctx->options & DNS_MASTER_CHECKNAMES) != 0) options |= DNS_RDATA_CHECKNAMES; if ((lctx->options & DNS_MASTER_CHECKNAMESFAIL) != 0) options |= DNS_RDATA_CHECKNAMESFAIL; if ((lctx->options & DNS_MASTER_CHECKMX) != 0) options |= DNS_RDATA_CHECKMX; if ((lctx->options & DNS_MASTER_CHECKMXFAIL) != 0) options |= DNS_RDATA_CHECKMXFAIL; source = isc_lex_getsourcename(lctx->lex); do { initialws = ISC_FALSE; line = isc_lex_getsourceline(lctx->lex); GETTOKEN(lctx->lex, ISC_LEXOPT_INITIALWS | ISC_LEXOPT_QSTRING, &token, ISC_TRUE); line = isc_lex_getsourceline(lctx->lex); if (token.type == isc_tokentype_eof) { if (read_till_eol) WARNUNEXPECTEDEOF(lctx->lex); /* Pop the include stack? */ if (ictx->parent != NULL) { COMMITALL; lctx->inc = ictx->parent; ictx->parent = NULL; incctx_destroy(lctx->mctx, ictx); RUNTIME_CHECK(isc_lex_close(lctx->lex) == ISC_R_SUCCESS); line = isc_lex_getsourceline(lctx->lex); source = isc_lex_getsourcename(lctx->lex); ictx = lctx->inc; continue; } done = ISC_TRUE; continue; } if (token.type == isc_tokentype_eol) { read_till_eol = ISC_FALSE; continue; /* blank line */ } if (read_till_eol) continue; if (token.type == isc_tokentype_initialws) { /* * Still working on the same name. */ initialws = ISC_TRUE; } else if (token.type == isc_tokentype_string || token.type == isc_tokentype_qstring) { /* * "$" Support. * * "$ORIGIN" and "$INCLUDE" can both take domain names. * The processing of "$ORIGIN" and "$INCLUDE" extends * across the normal domain name processing. */ if (strcasecmp(DNS_AS_STR(token), "$ORIGIN") == 0) { GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); finish_origin = ISC_TRUE; } else if (strcasecmp(DNS_AS_STR(token), "$TTL") == 0) { GETTOKENERR(lctx->lex, 0, &token, ISC_FALSE, lctx->ttl = 0; lctx->default_ttl_known = ISC_TRUE;); result = dns_ttl_fromtext(&token.value.as_textregion, &lctx->ttl); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); lctx->ttl = 0; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; limit_ttl(callbacks, source, line, &lctx->ttl); lctx->default_ttl = lctx->ttl; lctx->default_ttl_known = ISC_TRUE; EXPECTEOL; continue; } else if (strcasecmp(DNS_AS_STR(token), "$INCLUDE") == 0) { COMMITALL; if ((lctx->options & DNS_MASTER_NOINCLUDE) != 0) { (callbacks->error)(callbacks, "%s: %s:%lu: $INCLUDE not allowed", "dns_master_load", source, line); result = DNS_R_REFUSED; goto insist_and_cleanup; } if (ttl_offset != 0) { (callbacks->error)(callbacks, "%s: %s:%lu: $INCLUDE " "may not be used with $DATE", "dns_master_load", source, line); result = DNS_R_SYNTAX; goto insist_and_cleanup; } GETTOKEN(lctx->lex, ISC_LEXOPT_QSTRING, &token, ISC_FALSE); if (include_file != NULL) isc_mem_free(mctx, include_file); include_file = isc_mem_strdup(mctx, DNS_AS_STR(token)); if (include_file == NULL) { result = ISC_R_NOMEMORY; goto log_and_cleanup; } GETTOKEN(lctx->lex, 0, &token, ISC_TRUE); if (token.type == isc_tokentype_eol || token.type == isc_tokentype_eof) { if (token.type == isc_tokentype_eof) WARNUNEXPECTEDEOF(lctx->lex); /* * No origin field. */ result = pushfile(include_file, ictx->origin, lctx); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); LOGITFILE(result, include_file); continue; } else if (result != ISC_R_SUCCESS) { LOGITFILE(result, include_file); goto insist_and_cleanup; } ictx = lctx->inc; source = isc_lex_getsourcename(lctx->lex); line = isc_lex_getsourceline(lctx->lex); POST(line); continue; } /* * There is an origin field. Fall through * to domain name processing code and do * the actual inclusion later. */ finish_include = ISC_TRUE; } else if (strcasecmp(DNS_AS_STR(token), "$DATE") == 0) { isc_int64_t dump_time64; isc_stdtime_t dump_time, current_time; GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); isc_stdtime_get(¤t_time); result = dns_time64_fromtext(DNS_AS_STR(token), &dump_time64); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); LOGIT(result); dump_time64 = 0; } else if (result != ISC_R_SUCCESS) goto log_and_cleanup; dump_time = (isc_stdtime_t)dump_time64; if (dump_time != dump_time64) { UNEXPECTED_ERROR(__FILE__, __LINE__, "%s: %s:%lu: $DATE outside epoch", "dns_master_load", source, line); result = ISC_R_UNEXPECTED; goto insist_and_cleanup; } if (dump_time > current_time) { UNEXPECTED_ERROR(__FILE__, __LINE__, "%s: %s:%lu: " "$DATE in future, using current date", "dns_master_load", source, line); dump_time = current_time; } ttl_offset = current_time - dump_time; EXPECTEOL; continue; } else if (strcasecmp(DNS_AS_STR(token), "$GENERATE") == 0) { /* * Lazy cleanup. */ if (range != NULL) isc_mem_free(mctx, range); if (lhs != NULL) isc_mem_free(mctx, lhs); if (gtype != NULL) isc_mem_free(mctx, gtype); if (rhs != NULL) isc_mem_free(mctx, rhs); range = lhs = gtype = rhs = NULL; /* RANGE */ GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); range = isc_mem_strdup(mctx, DNS_AS_STR(token)); if (range == NULL) { result = ISC_R_NOMEMORY; goto log_and_cleanup; } /* LHS */ GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); lhs = isc_mem_strdup(mctx, DNS_AS_STR(token)); if (lhs == NULL) { result = ISC_R_NOMEMORY; goto log_and_cleanup; } rdclass = 0; explicit_ttl = ISC_FALSE; /* CLASS? */ GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); if (dns_rdataclass_fromtext(&rdclass, &token.value.as_textregion) == ISC_R_SUCCESS) { GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); } /* TTL? */ if (dns_ttl_fromtext(&token.value.as_textregion, &lctx->ttl) == ISC_R_SUCCESS) { limit_ttl(callbacks, source, line, &lctx->ttl); lctx->ttl_known = ISC_TRUE; explicit_ttl = ISC_TRUE; GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); } /* CLASS? */ if (rdclass == 0 && dns_rdataclass_fromtext(&rdclass, &token.value.as_textregion) == ISC_R_SUCCESS) GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); /* TYPE */ gtype = isc_mem_strdup(mctx, DNS_AS_STR(token)); if (gtype == NULL) { result = ISC_R_NOMEMORY; goto log_and_cleanup; } /* RHS */ GETTOKEN(lctx->lex, ISC_LEXOPT_QSTRING, &token, ISC_FALSE); rhs = isc_mem_strdup(mctx, DNS_AS_STR(token)); if (rhs == NULL) { result = ISC_R_NOMEMORY; goto log_and_cleanup; } if (!lctx->ttl_known && !lctx->default_ttl_known) { (*callbacks->error)(callbacks, "%s: %s:%lu: no TTL specified", "dns_master_load", source, line); result = DNS_R_NOTTL; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); lctx->ttl = 0; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } else if (!explicit_ttl && lctx->default_ttl_known) { lctx->ttl = lctx->default_ttl; } /* * If the class specified does not match the * zone's class print out a error message and * exit. */ if (rdclass != 0 && rdclass != lctx->zclass) { goto bad_class; } result = generate(lctx, range, lhs, gtype, rhs, source, line); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; EXPECTEOL; continue; } else if (strncasecmp(DNS_AS_STR(token), "$", 1) == 0) { (callbacks->error)(callbacks, "%s: %s:%lu: " "unknown $ directive '%s'", "dns_master_load", source, line, DNS_AS_STR(token)); result = DNS_R_SYNTAX; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } /* * Normal processing resumes. * * Find a free name buffer. */ for (new_in_use = 0; new_in_use < NBUFS; new_in_use++) if (!ictx->in_use[new_in_use]) break; INSIST(new_in_use < NBUFS); dns_fixedname_init(&ictx->fixed[new_in_use]); new_name = dns_fixedname_name(&ictx->fixed[new_in_use]); isc_buffer_init(&buffer, token.value.as_region.base, token.value.as_region.length); isc_buffer_add(&buffer, token.value.as_region.length); isc_buffer_setactive(&buffer, token.value.as_region.length); result = dns_name_fromtext(new_name, &buffer, ictx->origin, 0, NULL); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); LOGIT(result); read_till_eol = ISC_TRUE; continue; } else if (result != ISC_R_SUCCESS) goto log_and_cleanup; /* * Finish $ORIGIN / $INCLUDE processing if required. */ if (finish_origin) { if (ictx->origin_in_use != -1) ictx->in_use[ictx->origin_in_use] = ISC_FALSE; ictx->origin_in_use = new_in_use; ictx->in_use[ictx->origin_in_use] = ISC_TRUE; ictx->origin = new_name; ictx->origin_changed = ISC_TRUE; finish_origin = ISC_FALSE; EXPECTEOL; continue; } if (finish_include) { finish_include = ISC_FALSE; EXPECTEOL; result = pushfile(include_file, new_name, lctx); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); LOGITFILE(result, include_file); continue; } else if (result != ISC_R_SUCCESS) { LOGITFILE(result, include_file); goto insist_and_cleanup; } ictx = lctx->inc; ictx->origin_changed = ISC_TRUE; source = isc_lex_getsourcename(lctx->lex); line = isc_lex_getsourceline(lctx->lex); POST(line); continue; } /* * "$" Processing Finished */ /* * If we are processing glue and the new name does * not match the current glue name, commit the glue * and pop stacks leaving us in 'normal' processing * state. Linked lists are undone by commit(). */ if (ictx->glue != NULL && dns_name_compare(ictx->glue, new_name) != 0) { result = commit(callbacks, lctx, &glue_list, ictx->glue, source, ictx->glue_line); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; if (ictx->glue_in_use != -1) ictx->in_use[ictx->glue_in_use] = ISC_FALSE; ictx->glue_in_use = -1; ictx->glue = NULL; rdcount = rdcount_save; rdlcount = rdlcount_save; target = target_save; } /* * If we are in 'normal' processing state and the new * name does not match the current name, see if the * new name is for glue and treat it as such, * otherwise we have a new name so commit what we * have. */ if ((ictx->glue == NULL) && (ictx->current == NULL || dns_name_compare(ictx->current, new_name) != 0)) { if (current_has_delegation && is_glue(¤t_list, new_name)) { rdcount_save = rdcount; rdlcount_save = rdlcount; target_save = target; ictx->glue = new_name; ictx->glue_in_use = new_in_use; ictx->in_use[ictx->glue_in_use] = ISC_TRUE; } else { result = commit(callbacks, lctx, ¤t_list, ictx->current, source, ictx->current_line); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; rdcount = 0; rdlcount = 0; if (ictx->current_in_use != -1) ictx->in_use[ictx->current_in_use] = ISC_FALSE; ictx->current_in_use = new_in_use; ictx->in_use[ictx->current_in_use] = ISC_TRUE; ictx->current = new_name; current_has_delegation = ISC_FALSE; isc_buffer_init(&target, target_mem, target_size); } /* * Check for internal wildcards. */ if ((lctx->options & DNS_MASTER_CHECKWILDCARD) != 0) check_wildcard(ictx, source, line, callbacks); } if ((lctx->options & DNS_MASTER_ZONE) != 0 && (lctx->options & DNS_MASTER_SLAVE) == 0 && (lctx->options & DNS_MASTER_KEY) == 0 && !dns_name_issubdomain(new_name, lctx->top)) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(new_name, namebuf, sizeof(namebuf)); /* * Ignore out-of-zone data. */ (*callbacks->warn)(callbacks, "%s:%lu: " "ignoring out-of-zone data (%s)", source, line, namebuf); ictx->drop = ISC_TRUE; } else ictx->drop = ISC_FALSE; } else { UNEXPECTED_ERROR(__FILE__, __LINE__, "%s:%lu: isc_lex_gettoken() returned " "unexpected token type (%d)", source, line, token.type); result = ISC_R_UNEXPECTED; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); LOGIT(result); continue; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } /* * Find TTL, class and type. Both TTL and class are optional * and may occur in any order if they exist. TTL and class * come before type which must exist. * * [] [] * [] [] */ type = 0; rdclass = 0; GETTOKEN(lctx->lex, 0, &token, initialws); if (initialws) { if (token.type == isc_tokentype_eol) { read_till_eol = ISC_FALSE; continue; /* blank line */ } if (token.type == isc_tokentype_eof) { WARNUNEXPECTEDEOF(lctx->lex); read_till_eol = ISC_FALSE; isc_lex_ungettoken(lctx->lex, &token); continue; } if (ictx->current == NULL) { (*callbacks->error)(callbacks, "%s:%lu: no current owner name", source, line); result = DNS_R_NOOWNER; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); read_till_eol = ISC_TRUE; continue; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } if (ictx->origin_changed) { char cbuf[DNS_NAME_FORMATSIZE]; char obuf[DNS_NAME_FORMATSIZE]; dns_name_format(ictx->current, cbuf, sizeof(cbuf)); dns_name_format(ictx->origin, obuf, sizeof(obuf)); (*callbacks->warn)(callbacks, "%s:%lu: record with inherited " "owner (%s) immediately after " "$ORIGIN (%s)", source, line, cbuf, obuf); } } ictx->origin_changed = ISC_FALSE; if (dns_rdataclass_fromtext(&rdclass, &token.value.as_textregion) == ISC_R_SUCCESS) GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); explicit_ttl = ISC_FALSE; result = dns_ttl_fromtext(&token.value.as_textregion, &lctx->ttl); if (result == ISC_R_SUCCESS) { limit_ttl(callbacks, source, line, &lctx->ttl); explicit_ttl = ISC_TRUE; lctx->ttl_known = ISC_TRUE; GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); } if (token.type != isc_tokentype_string) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_lex_gettoken() returned unexpected token type"); result = ISC_R_UNEXPECTED; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); read_till_eol = ISC_TRUE; continue; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } if (rdclass == 0 && dns_rdataclass_fromtext(&rdclass, &token.value.as_textregion) == ISC_R_SUCCESS) GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); if (token.type != isc_tokentype_string) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_lex_gettoken() returned unexpected token type"); result = ISC_R_UNEXPECTED; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); read_till_eol = ISC_TRUE; continue; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } result = dns_rdatatype_fromtext(&type, &token.value.as_textregion); if (result != ISC_R_SUCCESS) { (*callbacks->warn)(callbacks, "%s:%lu: unknown RR type '%.*s'", source, line, token.value.as_textregion.length, token.value.as_textregion.base); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); read_till_eol = ISC_TRUE; continue; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } /* * If the class specified does not match the zone's class * print out a error message and exit. */ if (rdclass != 0 && rdclass != lctx->zclass) { bad_class: dns_rdataclass_format(rdclass, classname1, sizeof(classname1)); dns_rdataclass_format(lctx->zclass, classname2, sizeof(classname2)); (*callbacks->error)(callbacks, "%s:%lu: class '%s' != " "zone class '%s'", source, line, classname1, classname2); result = DNS_R_BADCLASS; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); read_till_eol = ISC_TRUE; continue; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } if (type == dns_rdatatype_ns && ictx->glue == NULL) current_has_delegation = ISC_TRUE; /* * RFC1123: MD and MF are not allowed to be loaded from * master files. */ if ((lctx->options & DNS_MASTER_ZONE) != 0 && (lctx->options & DNS_MASTER_SLAVE) == 0 && (type == dns_rdatatype_md || type == dns_rdatatype_mf)) { char typename[DNS_RDATATYPE_FORMATSIZE]; result = DNS_R_OBSOLETE; dns_rdatatype_format(type, typename, sizeof(typename)); (*callbacks->error)(callbacks, "%s:%lu: %s '%s': %s", source, line, "type", typename, dns_result_totext(result)); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); } else goto insist_and_cleanup; } /* * Find a rdata structure. */ if (rdcount == rdata_size) { new_rdata = grow_rdata(rdata_size + RDSZ, rdata, rdata_size, ¤t_list, &glue_list, mctx); if (new_rdata == NULL) { result = ISC_R_NOMEMORY; goto log_and_cleanup; } rdata_size += RDSZ; rdata = new_rdata; } /* * Peek at the NS record. */ if (type == dns_rdatatype_ns && lctx->zclass == dns_rdataclass_in && (lctx->options & DNS_MASTER_CHECKNS) != 0) { GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); result = check_ns(lctx, &token, source, line); isc_lex_ungettoken(lctx->lex, &token); if ((lctx->options & DNS_MASTER_FATALNS) != 0) { if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } } /* * Check owner name. */ options &= ~DNS_RDATA_CHECKREVERSE; if ((lctx->options & DNS_MASTER_CHECKNAMES) != 0) { isc_boolean_t ok; dns_name_t *name; name = (ictx->glue != NULL) ? ictx->glue : ictx->current; ok = dns_rdata_checkowner(name, lctx->zclass, type, ISC_TRUE); if (!ok) { char namebuf[DNS_NAME_FORMATSIZE]; const char *desc; dns_name_format(name, namebuf, sizeof(namebuf)); result = DNS_R_BADOWNERNAME; desc = dns_result_totext(result); if (CHECKNAMESFAIL(lctx->options) || type == dns_rdatatype_nsec3) { (*callbacks->error)(callbacks, "%s:%lu: %s: %s", source, line, namebuf, desc); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); } else if (result != ISC_R_SUCCESS) goto cleanup; } else { (*callbacks->warn)(callbacks, "%s:%lu: %s: %s", source, line, namebuf, desc); } } if (type == dns_rdatatype_ptr && !dns_name_isdnssd(name) && (dns_name_issubdomain(name, &in_addr_arpa) || dns_name_issubdomain(name, &ip6_arpa) || dns_name_issubdomain(name, &ip6_int))) options |= DNS_RDATA_CHECKREVERSE; } /* * Read rdata contents. */ dns_rdata_init(&rdata[rdcount]); target_ft = target; result = dns_rdata_fromtext(&rdata[rdcount], lctx->zclass, type, lctx->lex, ictx->origin, options, lctx->mctx, &target, callbacks); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); continue; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; if (ictx->drop) { target = target_ft; continue; } if (type == dns_rdatatype_soa && (lctx->options & DNS_MASTER_ZONE) != 0 && dns_name_compare(ictx->current, lctx->top) != 0) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(ictx->current, namebuf, sizeof(namebuf)); (*callbacks->error)(callbacks, "%s:%lu: SOA " "record not at top of zone (%s)", source, line, namebuf); result = DNS_R_NOTZONETOP; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); read_till_eol = ISC_TRUE; target = target_ft; continue; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } if (type == dns_rdatatype_rrsig || type == dns_rdatatype_sig) covers = dns_rdata_covers(&rdata[rdcount]); else covers = 0; if (!lctx->ttl_known && !lctx->default_ttl_known) { if (type == dns_rdatatype_soa) { (*callbacks->warn)(callbacks, "%s:%lu: no TTL specified; " "using SOA MINTTL instead", source, line); lctx->ttl = dns_soa_getminimum(&rdata[rdcount]); limit_ttl(callbacks, source, line, &lctx->ttl); lctx->default_ttl = lctx->ttl; lctx->default_ttl_known = ISC_TRUE; } else if ((lctx->options & DNS_MASTER_HINT) != 0) { /* * Zero TTL's are fine for hints. */ lctx->ttl = 0; lctx->default_ttl = lctx->ttl; lctx->default_ttl_known = ISC_TRUE; } else { (*callbacks->warn)(callbacks, "%s:%lu: no TTL specified; " "zone rejected", source, line); result = DNS_R_NOTTL; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); lctx->ttl = 0; } else { goto insist_and_cleanup; } } } else if (!explicit_ttl && lctx->default_ttl_known) { lctx->ttl = lctx->default_ttl; } else if (!explicit_ttl && lctx->warn_1035) { (*callbacks->warn)(callbacks, "%s:%lu: " "using RFC1035 TTL semantics", source, line); lctx->warn_1035 = ISC_FALSE; } if (type == dns_rdatatype_rrsig && lctx->warn_sigexpired) { dns_rdata_rrsig_t sig; result = dns_rdata_tostruct(&rdata[rdcount], &sig, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (isc_serial_lt(sig.timeexpire, now)) { (*callbacks->warn)(callbacks, "%s:%lu: " "signature has expired", source, line); lctx->warn_sigexpired = ISC_FALSE; } } if ((type == dns_rdatatype_sig || type == dns_rdatatype_nxt) && lctx->warn_tcr && (lctx->options & DNS_MASTER_ZONE) != 0 && (lctx->options & DNS_MASTER_SLAVE) == 0) { (*callbacks->warn)(callbacks, "%s:%lu: old style DNSSEC " " zone detected", source, line); lctx->warn_tcr = ISC_FALSE; } if ((lctx->options & DNS_MASTER_AGETTL) != 0) { /* * Adjust the TTL for $DATE. If the RR has already * expired, ignore it. */ if (lctx->ttl < ttl_offset) continue; lctx->ttl -= ttl_offset; } /* * Find type in rdatalist. * If it does not exist create new one and prepend to list * as this will minimise list traversal. */ if (ictx->glue != NULL) this = ISC_LIST_HEAD(glue_list); else this = ISC_LIST_HEAD(current_list); while (this != NULL) { if (this->type == type && this->covers == covers) break; this = ISC_LIST_NEXT(this, link); } if (this == NULL) { if (rdlcount == rdatalist_size) { new_rdatalist = grow_rdatalist(rdatalist_size + RDLSZ, rdatalist, rdatalist_size, ¤t_list, &glue_list, mctx); if (new_rdatalist == NULL) { result = ISC_R_NOMEMORY; goto log_and_cleanup; } rdatalist = new_rdatalist; rdatalist_size += RDLSZ; } this = &rdatalist[rdlcount++]; dns_rdatalist_init(this); this->type = type; this->covers = covers; this->rdclass = lctx->zclass; this->ttl = lctx->ttl; if (ictx->glue != NULL) ISC_LIST_INITANDPREPEND(glue_list, this, link); else ISC_LIST_INITANDPREPEND(current_list, this, link); } else if (this->ttl != lctx->ttl) { (*callbacks->warn)(callbacks, "%s:%lu: " "TTL set to prior TTL (%lu)", source, line, this->ttl); lctx->ttl = this->ttl; } if ((lctx->options & DNS_MASTER_CHECKTTL) != 0 && lctx->ttl > lctx->maxttl) { (callbacks->error)(callbacks, "dns_master_load: %s:%lu: " "TTL %d exceeds configured max-zone-ttl %d", source, line, lctx->ttl, lctx->maxttl); result = ISC_R_RANGE; goto log_and_cleanup; } ISC_LIST_APPEND(this->rdata, &rdata[rdcount], link); if (ictx->glue != NULL) ictx->glue_line = line; else ictx->current_line = line; rdcount++; /* * We must have at least 64k as rdlen is 16 bits. * If we don't commit everything we have so far. */ if ((target.length - target.used) < MINTSIZ) COMMITALL; next_line: ; } while (!done && (lctx->loop_cnt == 0 || loop_cnt++ < lctx->loop_cnt)); /* * Commit what has not yet been committed. */ result = commit(callbacks, lctx, ¤t_list, ictx->current, source, ictx->current_line); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; result = commit(callbacks, lctx, &glue_list, ictx->glue, source, ictx->glue_line); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; if (!done) { INSIST(lctx->done != NULL && lctx->task != NULL); result = DNS_R_CONTINUE; } else if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS) { result = lctx->result; } else if (result == ISC_R_SUCCESS && lctx->seen_include) result = DNS_R_SEENINCLUDE; goto cleanup; log_and_cleanup: LOGIT(result); insist_and_cleanup: INSIST(result != ISC_R_SUCCESS); cleanup: while ((this = ISC_LIST_HEAD(current_list)) != NULL) ISC_LIST_UNLINK(current_list, this, link); while ((this = ISC_LIST_HEAD(glue_list)) != NULL) ISC_LIST_UNLINK(glue_list, this, link); if (rdatalist != NULL) isc_mem_put(mctx, rdatalist, rdatalist_size * sizeof(*rdatalist)); if (rdata != NULL) isc_mem_put(mctx, rdata, rdata_size * sizeof(*rdata)); if (target_mem != NULL) isc_mem_put(mctx, target_mem, target_size); if (include_file != NULL) isc_mem_free(mctx, include_file); if (range != NULL) isc_mem_free(mctx, range); if (lhs != NULL) isc_mem_free(mctx, lhs); if (gtype != NULL) isc_mem_free(mctx, gtype); if (rhs != NULL) isc_mem_free(mctx, rhs); return (result); } static isc_result_t pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx) { isc_result_t result; dns_incctx_t *ictx; dns_incctx_t *new = NULL; isc_region_t r; int new_in_use; REQUIRE(master_file != NULL); REQUIRE(DNS_LCTX_VALID(lctx)); ictx = lctx->inc; lctx->seen_include = ISC_TRUE; result = incctx_create(lctx->mctx, origin, &new); if (result != ISC_R_SUCCESS) return (result); /* * Push origin_changed. */ new->origin_changed = ictx->origin_changed; /* Set current domain. */ if (ictx->glue != NULL || ictx->current != NULL) { for (new_in_use = 0; new_in_use < NBUFS; new_in_use++) if (!new->in_use[new_in_use]) break; INSIST(new_in_use < NBUFS); new->current_in_use = new_in_use; new->current = dns_fixedname_name(&new->fixed[new->current_in_use]); new->in_use[new->current_in_use] = ISC_TRUE; dns_name_toregion((ictx->glue != NULL) ? ictx->glue : ictx->current, &r); dns_name_fromregion(new->current, &r); new->drop = ictx->drop; } result = (lctx->openfile)(lctx, master_file); if (result != ISC_R_SUCCESS) goto cleanup; new->parent = ictx; lctx->inc = new; if (lctx->include_cb != NULL) lctx->include_cb(master_file, lctx->include_arg); return (ISC_R_SUCCESS); cleanup: incctx_destroy(lctx->mctx, new); return (result); } static inline isc_result_t read_and_check(isc_boolean_t do_read, isc_buffer_t *buffer, size_t len, FILE *f) { isc_result_t result; if (do_read) { INSIST(isc_buffer_availablelength(buffer) >= len); result = isc_stdio_read(isc_buffer_used(buffer), 1, len, f, NULL); if (result != ISC_R_SUCCESS) return (result); isc_buffer_add(buffer, (unsigned int)len); } else if (isc_buffer_remaininglength(buffer) < len) return (ISC_R_RANGE); return (ISC_R_SUCCESS); } static isc_result_t load_header(dns_loadctx_t *lctx) { isc_result_t result = ISC_R_SUCCESS; dns_masterrawheader_t header; dns_rdatacallbacks_t *callbacks; size_t commonlen = sizeof(header.format) + sizeof(header.version); size_t remainder; unsigned char data[sizeof(header)]; isc_buffer_t target; REQUIRE(DNS_LCTX_VALID(lctx)); if (lctx->format != dns_masterformat_raw && lctx->format != dns_masterformat_map) return (ISC_R_NOTIMPLEMENTED); callbacks = lctx->callbacks; dns_master_initrawheader(&header); INSIST(commonlen <= sizeof(header)); isc_buffer_init(&target, data, sizeof(data)); result = isc_stdio_read(data, 1, commonlen, lctx->f, NULL); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_stdio_read failed: %s", isc_result_totext(result)); return (result); } isc_buffer_add(&target, (unsigned int)commonlen); header.format = isc_buffer_getuint32(&target); if (header.format != lctx->format) { (*callbacks->error)(callbacks, "dns_master_load: " "file format mismatch (not %s)", lctx->format == dns_masterformat_map ? "map" : "raw"); return (ISC_R_NOTIMPLEMENTED); } header.version = isc_buffer_getuint32(&target); switch (header.version) { case 0: remainder = sizeof(header.dumptime); break; case DNS_RAWFORMAT_VERSION: remainder = sizeof(header) - commonlen; break; default: (*callbacks->error)(callbacks, "dns_master_load: " "unsupported file format version"); return (ISC_R_NOTIMPLEMENTED); } result = isc_stdio_read(data + commonlen, 1, remainder, lctx->f, NULL); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_stdio_read failed: %s", isc_result_totext(result)); return (result); } isc_buffer_add(&target, (unsigned int)remainder); header.dumptime = isc_buffer_getuint32(&target); if (header.version == DNS_RAWFORMAT_VERSION) { header.flags = isc_buffer_getuint32(&target); header.sourceserial = isc_buffer_getuint32(&target); header.lastxfrin = isc_buffer_getuint32(&target); } lctx->first = ISC_FALSE; lctx->header = header; return (ISC_R_SUCCESS); } static isc_result_t openfile_map(dns_loadctx_t *lctx, const char *master_file) { isc_result_t result; result = isc_stdio_open(master_file, "rb", &lctx->f); if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_stdio_open() failed: %s", isc_result_totext(result)); } return (result); } /* * Load a map format file, using mmap() to access RBT trees directly */ static isc_result_t load_map(dns_loadctx_t *lctx) { isc_result_t result = ISC_R_SUCCESS; dns_rdatacallbacks_t *callbacks; REQUIRE(DNS_LCTX_VALID(lctx)); callbacks = lctx->callbacks; if (lctx->first) { result = load_header(lctx); if (result != ISC_R_SUCCESS) return (result); result = (*callbacks->deserialize) (callbacks->deserialize_private, lctx->f, sizeof(dns_masterrawheader_t)); } return (result); } static isc_result_t openfile_raw(dns_loadctx_t *lctx, const char *master_file) { isc_result_t result; result = isc_stdio_open(master_file, "rb", &lctx->f); if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_stdio_open() failed: %s", isc_result_totext(result)); } return (result); } static isc_result_t load_raw(dns_loadctx_t *lctx) { isc_result_t result = ISC_R_SUCCESS; isc_boolean_t done = ISC_FALSE; unsigned int loop_cnt = 0; dns_rdatacallbacks_t *callbacks; unsigned char namebuf[DNS_NAME_MAXWIRE]; dns_fixedname_t fixed; dns_name_t *name; rdatalist_head_t head, dummy; dns_rdatalist_t rdatalist; isc_mem_t *mctx = lctx->mctx; dns_rdata_t *rdata = NULL; unsigned int rdata_size = 0; int target_size = TSIZ; isc_buffer_t target, buf; unsigned char *target_mem = NULL; dns_decompress_t dctx; REQUIRE(DNS_LCTX_VALID(lctx)); callbacks = lctx->callbacks; dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE); if (lctx->first) { result = load_header(lctx); if (result != ISC_R_SUCCESS) return (result); } ISC_LIST_INIT(head); ISC_LIST_INIT(dummy); /* * Allocate target_size of buffer space. This is greater than twice * the maximum individual RR data size. */ target_mem = isc_mem_get(mctx, target_size); if (target_mem == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } isc_buffer_init(&target, target_mem, target_size); dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); /* * In the following loop, we regard any error fatal regardless of * whether "MANYERRORS" is set in the context option. This is because * normal errors should already have been checked at creation time. * Besides, it is very unlikely that we can recover from an error * in this format, and so trying to continue parsing erroneous data * does not really make sense. */ for (loop_cnt = 0; (lctx->loop_cnt == 0 || loop_cnt < lctx->loop_cnt); loop_cnt++) { unsigned int i, rdcount; isc_uint16_t namelen; isc_uint32_t totallen; size_t minlen, readlen; isc_boolean_t sequential_read = ISC_FALSE; /* Read the data length */ isc_buffer_clear(&target); INSIST(isc_buffer_availablelength(&target) >= sizeof(totallen)); result = isc_stdio_read(target.base, 1, sizeof(totallen), lctx->f, NULL); if (result == ISC_R_EOF) { result = ISC_R_SUCCESS; done = ISC_TRUE; break; } if (result != ISC_R_SUCCESS) goto cleanup; isc_buffer_add(&target, sizeof(totallen)); totallen = isc_buffer_getuint32(&target); /* * Validation: the input data must at least contain the common * header. */ minlen = sizeof(totallen) + sizeof(isc_uint16_t) + sizeof(isc_uint16_t) + sizeof(isc_uint16_t) + sizeof(isc_uint32_t) + sizeof(isc_uint32_t); if (totallen < minlen) { result = ISC_R_RANGE; goto cleanup; } totallen -= sizeof(totallen); isc_buffer_clear(&target); if (totallen > isc_buffer_availablelength(&target)) { /* * The default buffer size should typically be large * enough to store the entire RRset. We could try to * allocate enough space if this is not the case, but * it might cause a hazardous result when "totallen" * is forged. Thus, we'd rather take an inefficient * but robust approach in this atypical case: read * data step by step, and commit partial data when * necessary. Note that the buffer must be large * enough to store the "header part", owner name, and * at least one rdata (however large it is). */ sequential_read = ISC_TRUE; readlen = minlen - sizeof(totallen); } else { /* * Typical case. We can read the whole RRset at once * with the default buffer. */ readlen = totallen; } result = isc_stdio_read(target.base, 1, readlen, lctx->f, NULL); if (result != ISC_R_SUCCESS) goto cleanup; isc_buffer_add(&target, (unsigned int)readlen); /* Construct RRset headers */ dns_rdatalist_init(&rdatalist); rdatalist.rdclass = isc_buffer_getuint16(&target); rdatalist.type = isc_buffer_getuint16(&target); rdatalist.covers = isc_buffer_getuint16(&target); rdatalist.ttl = isc_buffer_getuint32(&target); rdcount = isc_buffer_getuint32(&target); if (rdcount == 0 || rdcount > 0xffff) { result = ISC_R_RANGE; goto cleanup; } INSIST(isc_buffer_consumedlength(&target) <= readlen); /* Owner name: length followed by name */ result = read_and_check(sequential_read, &target, sizeof(namelen), lctx->f); if (result != ISC_R_SUCCESS) goto cleanup; namelen = isc_buffer_getuint16(&target); if (namelen > sizeof(namebuf)) { result = ISC_R_RANGE; goto cleanup; } result = read_and_check(sequential_read, &target, namelen, lctx->f); if (result != ISC_R_SUCCESS) goto cleanup; isc_buffer_setactive(&target, (unsigned int)namelen); result = dns_name_fromwire(name, &target, &dctx, 0, NULL); if (result != ISC_R_SUCCESS) goto cleanup; if ((lctx->options & DNS_MASTER_CHECKTTL) != 0 && rdatalist.ttl > lctx->maxttl) { (callbacks->error)(callbacks, "dns_master_load: " "TTL %d exceeds configured " "max-zone-ttl %d", rdatalist.ttl, lctx->maxttl); result = ISC_R_RANGE; goto cleanup; } /* Rdata contents. */ if (rdcount > rdata_size) { dns_rdata_t *new_rdata = NULL; new_rdata = grow_rdata(rdcount + RDSZ, rdata, rdata_size, &head, &dummy, mctx); if (new_rdata == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } rdata_size = rdcount + RDSZ; rdata = new_rdata; } continue_read: for (i = 0; i < rdcount; i++) { isc_uint16_t rdlen; dns_rdata_init(&rdata[i]); if (sequential_read && isc_buffer_availablelength(&target) < MINTSIZ) { unsigned int j; INSIST(i > 0); /* detect an infinite loop */ /* Partial Commit. */ ISC_LIST_APPEND(head, &rdatalist, link); result = commit(callbacks, lctx, &head, name, NULL, 0); for (j = 0; j < i; j++) { ISC_LIST_UNLINK(rdatalist.rdata, &rdata[j], link); dns_rdata_reset(&rdata[j]); } if (result != ISC_R_SUCCESS) goto cleanup; /* Rewind the buffer and continue */ isc_buffer_clear(&target); rdcount -= i; goto continue_read; } /* rdata length */ result = read_and_check(sequential_read, &target, sizeof(rdlen), lctx->f); if (result != ISC_R_SUCCESS) goto cleanup; rdlen = isc_buffer_getuint16(&target); /* rdata */ result = read_and_check(sequential_read, &target, rdlen, lctx->f); if (result != ISC_R_SUCCESS) goto cleanup; isc_buffer_setactive(&target, (unsigned int)rdlen); /* * It is safe to have the source active region and * the target available region be the same if * decompression is disabled (see dctx above) and we * are not downcasing names (options == 0). */ isc_buffer_init(&buf, isc_buffer_current(&target), (unsigned int)rdlen); result = dns_rdata_fromwire(&rdata[i], rdatalist.rdclass, rdatalist.type, &target, &dctx, 0, &buf); if (result != ISC_R_SUCCESS) goto cleanup; ISC_LIST_APPEND(rdatalist.rdata, &rdata[i], link); } /* * Sanity check. Still having remaining space is not * necessarily critical, but it very likely indicates broken * or malformed data. */ if (isc_buffer_remaininglength(&target) != 0) { result = ISC_R_RANGE; goto cleanup; } ISC_LIST_APPEND(head, &rdatalist, link); /* Commit this RRset. rdatalist will be unlinked. */ result = commit(callbacks, lctx, &head, name, NULL, 0); for (i = 0; i < rdcount; i++) { ISC_LIST_UNLINK(rdatalist.rdata, &rdata[i], link); dns_rdata_reset(&rdata[i]); } if (result != ISC_R_SUCCESS) goto cleanup; } if (!done) { INSIST(lctx->done != NULL && lctx->task != NULL); result = DNS_R_CONTINUE; } else if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS) result = lctx->result; if (result == ISC_R_SUCCESS && callbacks->rawdata != NULL) (*callbacks->rawdata)(callbacks->zone, &lctx->header); cleanup: if (rdata != NULL) isc_mem_put(mctx, rdata, rdata_size * sizeof(*rdata)); if (target_mem != NULL) isc_mem_put(mctx, target_mem, target_size); if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE) { (*callbacks->error)(callbacks, "dns_master_load: %s", dns_result_totext(result)); } return (result); } isc_result_t dns_master_loadfile(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx) { return (dns_master_loadfile5(master_file, top, origin, zclass, options, 0, callbacks, NULL, NULL, mctx, dns_masterformat_text, 0)); } isc_result_t dns_master_loadfile2(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx, dns_masterformat_t format) { return (dns_master_loadfile5(master_file, top, origin, zclass, options, 0, callbacks, NULL, NULL, mctx, format, 0)); } isc_result_t dns_master_loadfile3(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, isc_uint32_t resign, dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx, dns_masterformat_t format) { return (dns_master_loadfile5(master_file, top, origin, zclass, options, resign, callbacks, NULL, NULL, mctx, format, 0)); } isc_result_t dns_master_loadfile4(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, isc_uint32_t resign, dns_rdatacallbacks_t *callbacks, dns_masterincludecb_t include_cb, void *include_arg, isc_mem_t *mctx, dns_masterformat_t format) { return (dns_master_loadfile5(master_file, top, origin, zclass, options, resign, callbacks, include_cb, include_arg, mctx, format, 0)); } isc_result_t dns_master_loadfile5(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, isc_uint32_t resign, dns_rdatacallbacks_t *callbacks, dns_masterincludecb_t include_cb, void *include_arg, isc_mem_t *mctx, dns_masterformat_t format, dns_ttl_t maxttl) { dns_loadctx_t *lctx = NULL; isc_result_t result; result = loadctx_create(format, mctx, options, resign, top, zclass, origin, callbacks, NULL, NULL, NULL, include_cb, include_arg, NULL, &lctx); if (result != ISC_R_SUCCESS) return (result); lctx->maxttl = maxttl; result = (lctx->openfile)(lctx, master_file); if (result != ISC_R_SUCCESS) goto cleanup; result = (lctx->load)(lctx); INSIST(result != DNS_R_CONTINUE); cleanup: dns_loadctx_detach(&lctx); return (result); } isc_result_t dns_master_loadfileinc(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_task_t *task, dns_loaddonefunc_t done, void *done_arg, dns_loadctx_t **lctxp, isc_mem_t *mctx) { return (dns_master_loadfileinc4(master_file, top, origin, zclass, options, 0, callbacks, task, done, done_arg, lctxp, NULL, NULL, mctx, dns_masterformat_text)); } isc_result_t dns_master_loadfileinc2(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_task_t *task, dns_loaddonefunc_t done, void *done_arg, dns_loadctx_t **lctxp, isc_mem_t *mctx, dns_masterformat_t format) { return (dns_master_loadfileinc4(master_file, top, origin, zclass, options, 0, callbacks, task, done, done_arg, lctxp, NULL, NULL, mctx, format)); } isc_result_t dns_master_loadfileinc3(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, isc_uint32_t resign, dns_rdatacallbacks_t *callbacks, isc_task_t *task, dns_loaddonefunc_t done, void *done_arg, dns_loadctx_t **lctxp, isc_mem_t *mctx, dns_masterformat_t format) { return (dns_master_loadfileinc4(master_file, top, origin, zclass, options, resign, callbacks, task, done, done_arg, lctxp, NULL, NULL, mctx, format)); } isc_result_t dns_master_loadfileinc4(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, isc_uint32_t resign, dns_rdatacallbacks_t *callbacks, isc_task_t *task, dns_loaddonefunc_t done, void *done_arg, dns_loadctx_t **lctxp, dns_masterincludecb_t include_cb, void *include_arg, isc_mem_t *mctx, dns_masterformat_t format) { options &= ~DNS_MASTER_CHECKTTL; return (dns_master_loadfileinc5(master_file, top, origin, zclass, options, resign, callbacks, task, done, done_arg, lctxp, include_cb, include_arg, mctx, format, 0)); } isc_result_t dns_master_loadfileinc5(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, isc_uint32_t resign, dns_rdatacallbacks_t *callbacks, isc_task_t *task, dns_loaddonefunc_t done, void *done_arg, dns_loadctx_t **lctxp, dns_masterincludecb_t include_cb, void *include_arg, isc_mem_t *mctx, dns_masterformat_t format, isc_uint32_t maxttl) { dns_loadctx_t *lctx = NULL; isc_result_t result; REQUIRE(task != NULL); REQUIRE(done != NULL); result = loadctx_create(format, mctx, options, resign, top, zclass, origin, callbacks, task, done, done_arg, include_cb, include_arg, NULL, &lctx); if (result != ISC_R_SUCCESS) return (result); lctx->maxttl = maxttl; result = (lctx->openfile)(lctx, master_file); if (result != ISC_R_SUCCESS) goto cleanup; result = task_send(lctx); if (result == ISC_R_SUCCESS) { dns_loadctx_attach(lctx, lctxp); return (DNS_R_CONTINUE); } cleanup: dns_loadctx_detach(&lctx); return (result); } isc_result_t dns_master_loadstream(FILE *stream, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx) { isc_result_t result; dns_loadctx_t *lctx = NULL; REQUIRE(stream != NULL); result = loadctx_create(dns_masterformat_text, mctx, options, 0, top, zclass, origin, callbacks, NULL, NULL, NULL, NULL, NULL, NULL, &lctx); if (result != ISC_R_SUCCESS) goto cleanup; result = isc_lex_openstream(lctx->lex, stream); if (result != ISC_R_SUCCESS) goto cleanup; result = (lctx->load)(lctx); INSIST(result != DNS_R_CONTINUE); cleanup: if (lctx != NULL) dns_loadctx_detach(&lctx); return (result); } isc_result_t dns_master_loadstreaminc(FILE *stream, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_task_t *task, dns_loaddonefunc_t done, void *done_arg, dns_loadctx_t **lctxp, isc_mem_t *mctx) { isc_result_t result; dns_loadctx_t *lctx = NULL; REQUIRE(stream != NULL); REQUIRE(task != NULL); REQUIRE(done != NULL); result = loadctx_create(dns_masterformat_text, mctx, options, 0, top, zclass, origin, callbacks, task, done, done_arg, NULL, NULL, NULL, &lctx); if (result != ISC_R_SUCCESS) goto cleanup; result = isc_lex_openstream(lctx->lex, stream); if (result != ISC_R_SUCCESS) goto cleanup; result = task_send(lctx); if (result == ISC_R_SUCCESS) { dns_loadctx_attach(lctx, lctxp); return (DNS_R_CONTINUE); } cleanup: if (lctx != NULL) dns_loadctx_detach(&lctx); return (result); } isc_result_t dns_master_loadbuffer(isc_buffer_t *buffer, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx) { isc_result_t result; dns_loadctx_t *lctx = NULL; REQUIRE(buffer != NULL); result = loadctx_create(dns_masterformat_text, mctx, options, 0, top, zclass, origin, callbacks, NULL, NULL, NULL, NULL, NULL, NULL, &lctx); if (result != ISC_R_SUCCESS) return (result); result = isc_lex_openbuffer(lctx->lex, buffer); if (result != ISC_R_SUCCESS) goto cleanup; result = (lctx->load)(lctx); INSIST(result != DNS_R_CONTINUE); cleanup: dns_loadctx_detach(&lctx); return (result); } isc_result_t dns_master_loadbufferinc(isc_buffer_t *buffer, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_task_t *task, dns_loaddonefunc_t done, void *done_arg, dns_loadctx_t **lctxp, isc_mem_t *mctx) { isc_result_t result; dns_loadctx_t *lctx = NULL; REQUIRE(buffer != NULL); REQUIRE(task != NULL); REQUIRE(done != NULL); result = loadctx_create(dns_masterformat_text, mctx, options, 0, top, zclass, origin, callbacks, task, done, done_arg, NULL, NULL, NULL, &lctx); if (result != ISC_R_SUCCESS) return (result); result = isc_lex_openbuffer(lctx->lex, buffer); if (result != ISC_R_SUCCESS) goto cleanup; result = task_send(lctx); if (result == ISC_R_SUCCESS) { dns_loadctx_attach(lctx, lctxp); return (DNS_R_CONTINUE); } cleanup: dns_loadctx_detach(&lctx); return (result); } isc_result_t dns_master_loadlexer(isc_lex_t *lex, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx) { isc_result_t result; dns_loadctx_t *lctx = NULL; REQUIRE(lex != NULL); result = loadctx_create(dns_masterformat_text, mctx, options, 0, top, zclass, origin, callbacks, NULL, NULL, NULL, NULL, NULL, lex, &lctx); if (result != ISC_R_SUCCESS) return (result); result = (lctx->load)(lctx); INSIST(result != DNS_R_CONTINUE); dns_loadctx_detach(&lctx); return (result); } isc_result_t dns_master_loadlexerinc(isc_lex_t *lex, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_task_t *task, dns_loaddonefunc_t done, void *done_arg, dns_loadctx_t **lctxp, isc_mem_t *mctx) { isc_result_t result; dns_loadctx_t *lctx = NULL; REQUIRE(lex != NULL); REQUIRE(task != NULL); REQUIRE(done != NULL); result = loadctx_create(dns_masterformat_text, mctx, options, 0, top, zclass, origin, callbacks, task, done, done_arg, NULL, NULL, lex, &lctx); if (result != ISC_R_SUCCESS) return (result); result = task_send(lctx); if (result == ISC_R_SUCCESS) { dns_loadctx_attach(lctx, lctxp); return (DNS_R_CONTINUE); } dns_loadctx_detach(&lctx); return (result); } /* * Grow the slab of dns_rdatalist_t structures. * Re-link glue and current list. */ static dns_rdatalist_t * grow_rdatalist(int new_len, dns_rdatalist_t *old, int old_len, rdatalist_head_t *current, rdatalist_head_t *glue, isc_mem_t *mctx) { dns_rdatalist_t *new; int rdlcount = 0; ISC_LIST(dns_rdatalist_t) save; dns_rdatalist_t *this; new = isc_mem_get(mctx, new_len * sizeof(*new)); if (new == NULL) return (NULL); ISC_LIST_INIT(save); while ((this = ISC_LIST_HEAD(*current)) != NULL) { ISC_LIST_UNLINK(*current, this, link); ISC_LIST_APPEND(save, this, link); } while ((this = ISC_LIST_HEAD(save)) != NULL) { ISC_LIST_UNLINK(save, this, link); INSIST(rdlcount < new_len); new[rdlcount] = *this; ISC_LIST_APPEND(*current, &new[rdlcount], link); rdlcount++; } ISC_LIST_INIT(save); while ((this = ISC_LIST_HEAD(*glue)) != NULL) { ISC_LIST_UNLINK(*glue, this, link); ISC_LIST_APPEND(save, this, link); } while ((this = ISC_LIST_HEAD(save)) != NULL) { ISC_LIST_UNLINK(save, this, link); INSIST(rdlcount < new_len); new[rdlcount] = *this; ISC_LIST_APPEND(*glue, &new[rdlcount], link); rdlcount++; } INSIST(rdlcount == old_len); if (old != NULL) isc_mem_put(mctx, old, old_len * sizeof(*old)); return (new); } /* * Grow the slab of rdata structs. * Re-link the current and glue chains. */ static dns_rdata_t * grow_rdata(int new_len, dns_rdata_t *old, int old_len, rdatalist_head_t *current, rdatalist_head_t *glue, isc_mem_t *mctx) { dns_rdata_t *new; int rdcount = 0; ISC_LIST(dns_rdata_t) save; dns_rdatalist_t *this; dns_rdata_t *rdata; new = isc_mem_get(mctx, new_len * sizeof(*new)); if (new == NULL) return (NULL); memset(new, 0, new_len * sizeof(*new)); /* * Copy current relinking. */ this = ISC_LIST_HEAD(*current); while (this != NULL) { ISC_LIST_INIT(save); while ((rdata = ISC_LIST_HEAD(this->rdata)) != NULL) { ISC_LIST_UNLINK(this->rdata, rdata, link); ISC_LIST_APPEND(save, rdata, link); } while ((rdata = ISC_LIST_HEAD(save)) != NULL) { ISC_LIST_UNLINK(save, rdata, link); INSIST(rdcount < new_len); new[rdcount] = *rdata; ISC_LIST_APPEND(this->rdata, &new[rdcount], link); rdcount++; } this = ISC_LIST_NEXT(this, link); } /* * Copy glue relinking. */ this = ISC_LIST_HEAD(*glue); while (this != NULL) { ISC_LIST_INIT(save); while ((rdata = ISC_LIST_HEAD(this->rdata)) != NULL) { ISC_LIST_UNLINK(this->rdata, rdata, link); ISC_LIST_APPEND(save, rdata, link); } while ((rdata = ISC_LIST_HEAD(save)) != NULL) { ISC_LIST_UNLINK(save, rdata, link); INSIST(rdcount < new_len); new[rdcount] = *rdata; ISC_LIST_APPEND(this->rdata, &new[rdcount], link); rdcount++; } this = ISC_LIST_NEXT(this, link); } INSIST(rdcount == old_len || rdcount == 0); if (old != NULL) isc_mem_put(mctx, old, old_len * sizeof(*old)); return (new); } static isc_uint32_t resign_fromlist(dns_rdatalist_t *this, isc_uint32_t resign) { dns_rdata_t *rdata; dns_rdata_rrsig_t sig; isc_uint32_t when; rdata = ISC_LIST_HEAD(this->rdata); INSIST(rdata != NULL); (void)dns_rdata_tostruct(rdata, &sig, NULL); when = sig.timeexpire - resign; rdata = ISC_LIST_NEXT(rdata, link); while (rdata != NULL) { (void)dns_rdata_tostruct(rdata, &sig, NULL); if (sig.timeexpire - resign < when) when = sig.timeexpire - resign; rdata = ISC_LIST_NEXT(rdata, link); } return (when); } /* * Convert each element from a rdatalist_t to rdataset then call commit. * Unlink each element as we go. */ static isc_result_t commit(dns_rdatacallbacks_t *callbacks, dns_loadctx_t *lctx, rdatalist_head_t *head, dns_name_t *owner, const char *source, unsigned int line) { dns_rdatalist_t *this; dns_rdataset_t dataset; isc_result_t result; char namebuf[DNS_NAME_FORMATSIZE]; void (*error)(struct dns_rdatacallbacks *, const char *, ...); this = ISC_LIST_HEAD(*head); error = callbacks->error; if (this == NULL) return (ISC_R_SUCCESS); do { dns_rdataset_init(&dataset); RUNTIME_CHECK(dns_rdatalist_tordataset(this, &dataset) == ISC_R_SUCCESS); dataset.trust = dns_trust_ultimate; /* * If this is a secure dynamic zone set the re-signing time. */ if (dataset.type == dns_rdatatype_rrsig && (lctx->options & DNS_MASTER_RESIGN) != 0) { dataset.attributes |= DNS_RDATASETATTR_RESIGN; dataset.resign = resign_fromlist(this, lctx->resign); } result = ((*callbacks->add)(callbacks->add_private, owner, &dataset)); if (result == ISC_R_NOMEMORY) { (*error)(callbacks, "dns_master_load: %s", dns_result_totext(result)); } else if (result != ISC_R_SUCCESS) { dns_name_format(owner, namebuf, sizeof(namebuf)); if (source != NULL) { (*error)(callbacks, "%s: %s:%lu: %s: %s", "dns_master_load", source, line, namebuf, dns_result_totext(result)); } else { (*error)(callbacks, "%s: %s: %s", "dns_master_load", namebuf, dns_result_totext(result)); } } if (MANYERRS(lctx, result)) SETRESULT(lctx, result); else if (result != ISC_R_SUCCESS) return (result); ISC_LIST_UNLINK(*head, this, link); this = ISC_LIST_HEAD(*head); } while (this != NULL); return (ISC_R_SUCCESS); } /* * Returns ISC_TRUE if one of the NS rdata's contains 'owner'. */ static isc_boolean_t is_glue(rdatalist_head_t *head, dns_name_t *owner) { dns_rdatalist_t *this; dns_rdata_t *rdata; isc_region_t region; dns_name_t name; /* * Find NS rrset. */ this = ISC_LIST_HEAD(*head); while (this != NULL) { if (this->type == dns_rdatatype_ns) break; this = ISC_LIST_NEXT(this, link); } if (this == NULL) return (ISC_FALSE); rdata = ISC_LIST_HEAD(this->rdata); while (rdata != NULL) { dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); if (dns_name_compare(&name, owner) == 0) return (ISC_TRUE); rdata = ISC_LIST_NEXT(rdata, link); } return (ISC_FALSE); } static void load_quantum(isc_task_t *task, isc_event_t *event) { isc_result_t result; dns_loadctx_t *lctx; REQUIRE(event != NULL); lctx = event->ev_arg; REQUIRE(DNS_LCTX_VALID(lctx)); if (lctx->canceled) result = ISC_R_CANCELED; else result = (lctx->load)(lctx); if (result == DNS_R_CONTINUE) { event->ev_arg = lctx; isc_task_send(task, &event); } else { (lctx->done)(lctx->done_arg, result); isc_event_free(&event); dns_loadctx_detach(&lctx); } } static isc_result_t task_send(dns_loadctx_t *lctx) { isc_event_t *event; event = isc_event_allocate(lctx->mctx, NULL, DNS_EVENT_MASTERQUANTUM, load_quantum, lctx, sizeof(*event)); if (event == NULL) return (ISC_R_NOMEMORY); isc_task_send(lctx->task, &event); return (ISC_R_SUCCESS); } void dns_loadctx_cancel(dns_loadctx_t *lctx) { REQUIRE(DNS_LCTX_VALID(lctx)); LOCK(&lctx->lock); lctx->canceled = ISC_TRUE; UNLOCK(&lctx->lock); } void dns_master_initrawheader(dns_masterrawheader_t *header) { memset(header, 0, sizeof(dns_masterrawheader_t)); } bind9-9.10.3.dfsg.P4/lib/dns/gen-win32.h0000644000470500017500000001770012664710322016612 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. 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. Neither the name of the University 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 REGENTS 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. */ /* $Id: gen-win32.h,v 1.25 2009/01/17 23:47:42 tbox Exp $ */ /*! \file * \author Principal Authors: Computer Systems Research Group at UC Berkeley * \author Principal ISC caretaker: DCL */ /* * \note This file was adapted from the NetBSD project's source tree, RCS ID: * NetBSD: getopt.c,v 1.15 1999/09/20 04:39:37 lukem Exp * * The primary change has been to rename items to the ISC namespace * and format in the ISC coding style. * * This file is responsible for defining two operations that are not * directly portable between Unix-like systems and Windows NT, option * parsing and directory scanning. It is here because it was decided * that the "gen" build utility was not to depend on libisc.a, so * the functions declared in isc/commandline.h and isc/dir.h could not * be used. * * The commandline stuff is pretty much a straight copy from the initial * isc/commandline.c. The dir stuff was shrunk to fit the needs of gen.c. */ #ifndef DNS_GEN_WIN32_H #define DNS_GEN_WIN32_H 1 #include #include #include #include #include int isc_commandline_index = 1; /* Index into parent argv vector. */ int isc_commandline_option; /* Character checked for validity. */ char *isc_commandline_argument; /* Argument associated with option. */ char *isc_commandline_progname; /* For printing error messages. */ isc_boolean_t isc_commandline_errprint = ISC_TRUE; /* Print error messages. */ isc_boolean_t isc_commandline_reset = ISC_TRUE; /* Reset processing. */ #define BADOPT '?' #define BADARG ':' #define ENDOPT "" ISC_LANG_BEGINDECLS /* * getopt -- * Parse argc/argv argument vector. */ int isc_commandline_parse(int argc, char * const *argv, const char *options) { static char *place = ENDOPT; char *option; /* Index into *options of option. */ /* * Update scanning pointer, either because a reset was requested or * the previous argv was finished. */ if (isc_commandline_reset || *place == '\0') { isc_commandline_reset = ISC_FALSE; if (isc_commandline_progname == NULL) isc_commandline_progname = argv[0]; if (isc_commandline_index >= argc || *(place = argv[isc_commandline_index]) != '-') { /* * Index out of range or points to non-option. */ place = ENDOPT; return (-1); } if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { /* * Found '--' to signal end of options. Advance * index to next argv, the first non-option. */ isc_commandline_index++; place = ENDOPT; return (-1); } } isc_commandline_option = *place++; option = strchr(options, isc_commandline_option); /* * Ensure valid option has been passed as specified by options string. * '-:' is never a valid command line option because it could not * distinguish ':' from the argument specifier in the options string. */ if (isc_commandline_option == ':' || option == NULL) { if (*place == '\0') isc_commandline_index++; if (isc_commandline_errprint && *options != ':') fprintf(stderr, "%s: illegal option -- %c\n", isc_commandline_progname, isc_commandline_option); return (BADOPT); } if (*++option != ':') { /* * Option does not take an argument. */ isc_commandline_argument = NULL; /* * Skip to next argv if at the end of the current argv. */ if (*place == '\0') ++isc_commandline_index; } else { /* * Option needs an argument. */ if (*place != '\0') /* * Option is in this argv, -D1 style. */ isc_commandline_argument = place; else if (argc > ++isc_commandline_index) /* * Option is next argv, -D 1 style. */ isc_commandline_argument = argv[isc_commandline_index]; else { /* * Argument needed, but no more argv. */ place = ENDOPT; /* * Silent failure with "missing argument" return * when ':' starts options string, per historical spec. */ if (*options == ':') return (BADARG); if (isc_commandline_errprint) fprintf(stderr, "%s: option requires an argument -- %c\n", isc_commandline_progname, isc_commandline_option); return (BADOPT); } place = ENDOPT; /* * Point to argv that follows argument. */ isc_commandline_index++; } return (isc_commandline_option); } typedef struct { HANDLE handle; WIN32_FIND_DATA find_data; isc_boolean_t first_file; char *filename; } isc_dir_t; isc_boolean_t start_directory(const char *path, isc_dir_t *dir) { char pattern[_MAX_PATH], *p; /* * Need space for slash-splat and final NUL. */ if (strlen(path) + 3 > sizeof(pattern)) return (ISC_FALSE); strcpy(pattern, path); /* * Append slash (if needed) and splat. */ p = pattern + strlen(pattern); if (p != pattern && p[-1] != '\\' && p[-1] != ':') *p++ = '\\'; *p++ = '*'; *p++ = '\0'; dir->first_file = ISC_TRUE; dir->handle = FindFirstFile(pattern, &dir->find_data); if (dir->handle == INVALID_HANDLE_VALUE) { dir->filename = NULL; return (ISC_FALSE); } else { dir->filename = dir->find_data.cFileName; return (ISC_TRUE); } } isc_boolean_t next_file(isc_dir_t *dir) { if (dir->first_file) dir->first_file = ISC_FALSE; else if (dir->handle != INVALID_HANDLE_VALUE) { if (FindNextFile(dir->handle, &dir->find_data) == TRUE) dir->filename = dir->find_data.cFileName; else dir->filename = NULL; } else dir->filename = NULL; if (dir->filename != NULL) return (ISC_TRUE); else return (ISC_FALSE); } void end_directory(isc_dir_t *dir) { if (dir->handle != INVALID_HANDLE_VALUE) FindClose(dir->handle); } ISC_LANG_ENDDECLS #endif /* DNS_GEN_WIN32_H */ bind9-9.10.3.dfsg.P4/lib/dns/dst_result.c0000644000470500017500000000516712664710322017270 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2008, 2012-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*% * Principal Author: Brian Wellington * $Id: dst_result.c,v 1.7 2008/04/01 23:47:10 tbox Exp $ */ #include #include #include #include #include static const char *text[DST_R_NRESULTS] = { "algorithm is unsupported", /*%< 0 */ "crypto failure", /*%< 1 */ "built with no crypto support", /*%< 2 */ "illegal operation for a null key", /*%< 3 */ "public key is invalid", /*%< 4 */ "private key is invalid", /*%< 5 */ "external key", /*%< 6 */ "error occurred writing key to disk", /*%< 7 */ "invalid algorithm specific parameter", /*%< 8 */ "UNUSED9", /*%< 9 */ "UNUSED10", /*%< 10 */ "sign failure", /*%< 11 */ "UNUSED12", /*%< 12 */ "UNUSED13", /*%< 13 */ "verify failure", /*%< 14 */ "not a public key", /*%< 15 */ "not a private key", /*%< 16 */ "not a key that can compute a secret", /*%< 17 */ "failure computing a shared secret", /*%< 18 */ "no randomness available", /*%< 19 */ "bad key type", /*%< 20 */ "no engine", /*%< 21 */ "illegal operation for an external key",/*%< 22 */ }; #define DST_RESULT_RESULTSET 2 static isc_once_t once = ISC_ONCE_INIT; static void initialize_action(void) { isc_result_t result; result = isc_result_register(ISC_RESULTCLASS_DST, DST_R_NRESULTS, text, dst_msgcat, DST_RESULT_RESULTSET); if (result != ISC_R_SUCCESS) UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_result_register() failed: %u", result); } static void initialize(void) { dst_lib_initmsgcat(); RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); } const char * dst_result_totext(isc_result_t result) { initialize(); return (isc_result_totext(result)); } void dst_result_register(void) { initialize(); } /*! \file */ bind9-9.10.3.dfsg.P4/lib/dns/adb.c0000644000470500017500000037327012664710322015631 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file * * \note * In finds, if task == NULL, no events will be generated, and no events * have been sent. If task != NULL but taskaction == NULL, an event has been * posted but not yet freed. If neither are NULL, no event was posted. * */ #include #include #include #include #include #include #include #include /* Required for HP/UX (and others?) */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define DNS_ADB_MAGIC ISC_MAGIC('D', 'a', 'd', 'b') #define DNS_ADB_VALID(x) ISC_MAGIC_VALID(x, DNS_ADB_MAGIC) #define DNS_ADBNAME_MAGIC ISC_MAGIC('a', 'd', 'b', 'N') #define DNS_ADBNAME_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAME_MAGIC) #define DNS_ADBNAMEHOOK_MAGIC ISC_MAGIC('a', 'd', 'N', 'H') #define DNS_ADBNAMEHOOK_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAMEHOOK_MAGIC) #define DNS_ADBLAMEINFO_MAGIC ISC_MAGIC('a', 'd', 'b', 'Z') #define DNS_ADBLAMEINFO_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBLAMEINFO_MAGIC) #define DNS_ADBENTRY_MAGIC ISC_MAGIC('a', 'd', 'b', 'E') #define DNS_ADBENTRY_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBENTRY_MAGIC) #define DNS_ADBFETCH_MAGIC ISC_MAGIC('a', 'd', 'F', '4') #define DNS_ADBFETCH_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH_MAGIC) #define DNS_ADBFETCH6_MAGIC ISC_MAGIC('a', 'd', 'F', '6') #define DNS_ADBFETCH6_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH6_MAGIC) /*! * For type 3 negative cache entries, we will remember that the address is * broken for this long. XXXMLG This is also used for actual addresses, too. * The intent is to keep us from constantly asking about A/AAAA records * if the zone has extremely low TTLs. */ #define ADB_CACHE_MINIMUM 10 /*%< seconds */ #define ADB_CACHE_MAXIMUM 86400 /*%< seconds (86400 = 24 hours) */ #define ADB_ENTRY_WINDOW 1800 /*%< seconds */ /*% * The period in seconds after which an ADB name entry is regarded as stale * and forced to be cleaned up. * TODO: This should probably be configurable at run-time. */ #ifndef ADB_STALE_MARGIN #define ADB_STALE_MARGIN 1800 #endif #define FREE_ITEMS 64 /*%< free count for memory pools */ #define FILL_COUNT 16 /*%< fill count for memory pools */ #define DNS_ADB_INVALIDBUCKET (-1) /*%< invalid bucket address */ #define DNS_ADB_MINADBSIZE (1024U*1024U) /*%< 1 Megabyte */ typedef ISC_LIST(dns_adbname_t) dns_adbnamelist_t; typedef struct dns_adbnamehook dns_adbnamehook_t; typedef ISC_LIST(dns_adbnamehook_t) dns_adbnamehooklist_t; typedef struct dns_adblameinfo dns_adblameinfo_t; typedef ISC_LIST(dns_adbentry_t) dns_adbentrylist_t; typedef struct dns_adbfetch dns_adbfetch_t; typedef struct dns_adbfetch6 dns_adbfetch6_t; /*% dns adb structure */ struct dns_adb { unsigned int magic; isc_mutex_t lock; isc_mutex_t reflock; /*%< Covers irefcnt, erefcnt */ isc_mutex_t overmemlock; /*%< Covers overmem */ isc_mem_t *mctx; dns_view_t *view; isc_taskmgr_t *taskmgr; isc_task_t *task; isc_task_t *excl; isc_interval_t tick_interval; int next_cleanbucket; unsigned int irefcnt; unsigned int erefcnt; isc_mutex_t mplock; isc_mempool_t *nmp; /*%< dns_adbname_t */ isc_mempool_t *nhmp; /*%< dns_adbnamehook_t */ isc_mempool_t *limp; /*%< dns_adblameinfo_t */ isc_mempool_t *emp; /*%< dns_adbentry_t */ isc_mempool_t *ahmp; /*%< dns_adbfind_t */ isc_mempool_t *aimp; /*%< dns_adbaddrinfo_t */ isc_mempool_t *afmp; /*%< dns_adbfetch_t */ /*! * Bucketized locks and lists for names. * * XXXRTH Have a per-bucket structure that contains all of these? */ unsigned int nnames; isc_mutex_t namescntlock; unsigned int namescnt; dns_adbnamelist_t *names; dns_adbnamelist_t *deadnames; isc_mutex_t *namelocks; isc_boolean_t *name_sd; unsigned int *name_refcnt; /*! * Bucketized locks and lists for entries. * * XXXRTH Have a per-bucket structure that contains all of these? */ unsigned int nentries; isc_mutex_t entriescntlock; unsigned int entriescnt; dns_adbentrylist_t *entries; dns_adbentrylist_t *deadentries; isc_mutex_t *entrylocks; isc_boolean_t *entry_sd; /*%< shutting down */ unsigned int *entry_refcnt; isc_event_t cevent; isc_boolean_t cevent_out; isc_boolean_t shutting_down; isc_eventlist_t whenshutdown; isc_event_t growentries; isc_boolean_t growentries_sent; isc_event_t grownames; isc_boolean_t grownames_sent; #ifdef ENABLE_FETCHLIMIT isc_uint32_t quota; isc_uint32_t atr_freq; double atr_low; double atr_high; double atr_discount; #endif /* ENABLE_FETCHLIMIT */ }; /* * XXXMLG Document these structures. */ /*% dns_adbname structure */ struct dns_adbname { unsigned int magic; dns_name_t name; dns_adb_t *adb; unsigned int partial_result; unsigned int flags; int lock_bucket; dns_name_t target; isc_stdtime_t expire_target; isc_stdtime_t expire_v4; isc_stdtime_t expire_v6; unsigned int chains; dns_adbnamehooklist_t v4; dns_adbnamehooklist_t v6; dns_adbfetch_t *fetch_a; dns_adbfetch_t *fetch_aaaa; unsigned int fetch_err; unsigned int fetch6_err; dns_adbfindlist_t finds; /* for LRU-based management */ isc_stdtime_t last_used; ISC_LINK(dns_adbname_t) plink; }; /*% The adbfetch structure */ struct dns_adbfetch { unsigned int magic; dns_fetch_t *fetch; dns_rdataset_t rdataset; unsigned int depth; }; /*% * This is a small widget that dangles off a dns_adbname_t. It contains a * pointer to the address information about this host, and a link to the next * namehook that will contain the next address this host has. */ struct dns_adbnamehook { unsigned int magic; dns_adbentry_t *entry; ISC_LINK(dns_adbnamehook_t) plink; }; /*% * This is a small widget that holds qname-specific information about an * address. Currently limited to lameness, but could just as easily be * extended to other types of information about zones. */ struct dns_adblameinfo { unsigned int magic; dns_name_t qname; dns_rdatatype_t qtype; isc_stdtime_t lame_timer; ISC_LINK(dns_adblameinfo_t) plink; }; /*% * An address entry. It holds quite a bit of information about addresses, * including edns state (in "flags"), rtt, and of course the address of * the host. */ struct dns_adbentry { unsigned int magic; int lock_bucket; unsigned int refcnt; unsigned int nh; unsigned int flags; unsigned int srtt; isc_uint16_t udpsize; unsigned char plain; unsigned char plainto; unsigned char edns; unsigned char to4096; /* Our max. */ #ifdef ENABLE_FETCHLIMIT unsigned int completed; unsigned int timeouts; isc_uint8_t mode; isc_uint32_t quota; isc_uint32_t active; double atr; #endif /* ENABLE_FETCHLIMIT */ /* * Allow for encapsulated IPv4/IPv6 UDP packet over ethernet. * Ethernet 1500 - IP(20) - IP6(40) - UDP(8) = 1432. */ unsigned char to1432; /* Ethernet */ unsigned char to1232; /* IPv6 nofrag */ unsigned char to512; /* plain DNS */ isc_sockaddr_t sockaddr; unsigned char * sit; isc_uint16_t sitlen; isc_stdtime_t expires; isc_stdtime_t lastage; /*%< * A nonzero 'expires' field indicates that the entry should * persist until that time. This allows entries found * using dns_adb_findaddrinfo() to persist for a limited time * even though they are not necessarily associated with a * name. */ ISC_LIST(dns_adblameinfo_t) lameinfo; ISC_LINK(dns_adbentry_t) plink; }; /* * Internal functions (and prototypes). */ static inline dns_adbname_t *new_adbname(dns_adb_t *, dns_name_t *); static inline void free_adbname(dns_adb_t *, dns_adbname_t **); static inline dns_adbnamehook_t *new_adbnamehook(dns_adb_t *, dns_adbentry_t *); static inline void free_adbnamehook(dns_adb_t *, dns_adbnamehook_t **); static inline dns_adblameinfo_t *new_adblameinfo(dns_adb_t *, dns_name_t *, dns_rdatatype_t); static inline void free_adblameinfo(dns_adb_t *, dns_adblameinfo_t **); static inline dns_adbentry_t *new_adbentry(dns_adb_t *); static inline void free_adbentry(dns_adb_t *, dns_adbentry_t **); static inline dns_adbfind_t *new_adbfind(dns_adb_t *); static inline isc_boolean_t free_adbfind(dns_adb_t *, dns_adbfind_t **); static inline dns_adbaddrinfo_t *new_adbaddrinfo(dns_adb_t *, dns_adbentry_t *, in_port_t); static inline dns_adbfetch_t *new_adbfetch(dns_adb_t *); static inline void free_adbfetch(dns_adb_t *, dns_adbfetch_t **); static inline dns_adbname_t *find_name_and_lock(dns_adb_t *, dns_name_t *, unsigned int, int *); static inline dns_adbentry_t *find_entry_and_lock(dns_adb_t *, isc_sockaddr_t *, int *, isc_stdtime_t); static void dump_adb(dns_adb_t *, FILE *, isc_boolean_t debug, isc_stdtime_t); static void print_dns_name(FILE *, dns_name_t *); static void print_namehook_list(FILE *, const char *legend, dns_adb_t *adb, dns_adbnamehooklist_t *list, isc_boolean_t debug, isc_stdtime_t now); static void print_find_list(FILE *, dns_adbname_t *); static void print_fetch_list(FILE *, dns_adbname_t *); static inline isc_boolean_t dec_adb_irefcnt(dns_adb_t *); static inline void inc_adb_irefcnt(dns_adb_t *); static inline void inc_adb_erefcnt(dns_adb_t *); static inline void inc_entry_refcnt(dns_adb_t *, dns_adbentry_t *, isc_boolean_t); static inline isc_boolean_t dec_entry_refcnt(dns_adb_t *, isc_boolean_t, dns_adbentry_t *, isc_boolean_t); static inline void violate_locking_hierarchy(isc_mutex_t *, isc_mutex_t *); static isc_boolean_t clean_namehooks(dns_adb_t *, dns_adbnamehooklist_t *); static void clean_target(dns_adb_t *, dns_name_t *); static void clean_finds_at_name(dns_adbname_t *, isc_eventtype_t, unsigned int); static isc_boolean_t check_expire_namehooks(dns_adbname_t *, isc_stdtime_t); static isc_boolean_t check_expire_entry(dns_adb_t *, dns_adbentry_t **, isc_stdtime_t); static void cancel_fetches_at_name(dns_adbname_t *); static isc_result_t dbfind_name(dns_adbname_t *, isc_stdtime_t, dns_rdatatype_t); static isc_result_t fetch_name(dns_adbname_t *, isc_boolean_t, unsigned int, isc_counter_t *qc, dns_rdatatype_t); static inline void check_exit(dns_adb_t *); static void destroy(dns_adb_t *); static isc_boolean_t shutdown_names(dns_adb_t *); static isc_boolean_t shutdown_entries(dns_adb_t *); static inline void link_name(dns_adb_t *, int, dns_adbname_t *); static inline isc_boolean_t unlink_name(dns_adb_t *, dns_adbname_t *); static inline void link_entry(dns_adb_t *, int, dns_adbentry_t *); static inline isc_boolean_t unlink_entry(dns_adb_t *, dns_adbentry_t *); static isc_boolean_t kill_name(dns_adbname_t **, isc_eventtype_t); static void water(void *, int); static void dump_entry(FILE *, dns_adb_t *, dns_adbentry_t *, isc_boolean_t, isc_stdtime_t); static void adjustsrtt(dns_adbaddrinfo_t *addr, unsigned int rtt, unsigned int factor, isc_stdtime_t now); static void shutdown_task(isc_task_t *task, isc_event_t *ev); #ifdef ENABLE_FETCHLIMIT static void log_quota(dns_adbentry_t *entry, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3); #endif /* ENABLE_FETCHLIMIT */ /* * MUST NOT overlap DNS_ADBFIND_* flags! */ #define FIND_EVENT_SENT 0x40000000 #define FIND_EVENT_FREED 0x80000000 #define FIND_EVENTSENT(h) (((h)->flags & FIND_EVENT_SENT) != 0) #define FIND_EVENTFREED(h) (((h)->flags & FIND_EVENT_FREED) != 0) #define NAME_NEEDS_POKE 0x80000000 #define NAME_IS_DEAD 0x40000000 #define NAME_HINT_OK DNS_ADBFIND_HINTOK #define NAME_GLUE_OK DNS_ADBFIND_GLUEOK #define NAME_STARTATZONE DNS_ADBFIND_STARTATZONE #define NAME_DEAD(n) (((n)->flags & NAME_IS_DEAD) != 0) #define NAME_NEEDSPOKE(n) (((n)->flags & NAME_NEEDS_POKE) != 0) #define NAME_GLUEOK(n) (((n)->flags & NAME_GLUE_OK) != 0) #define NAME_HINTOK(n) (((n)->flags & NAME_HINT_OK) != 0) /* * Private flag(s) for entries. * MUST NOT overlap FCTX_ADDRINFO_xxx and DNS_FETCHOPT_NOEDNS0. */ #define ENTRY_IS_DEAD 0x00400000 /* * To the name, address classes are all that really exist. If it has a * V6 address it doesn't care if it came from a AAAA query. */ #define NAME_HAS_V4(n) (!ISC_LIST_EMPTY((n)->v4)) #define NAME_HAS_V6(n) (!ISC_LIST_EMPTY((n)->v6)) #define NAME_HAS_ADDRS(n) (NAME_HAS_V4(n) || NAME_HAS_V6(n)) /* * Fetches are broken out into A and AAAA types. In some cases, * however, it makes more sense to test for a particular class of fetches, * like V4 or V6 above. * Note: since we have removed the support of A6 in adb, FETCH_A and FETCH_AAAA * are now equal to FETCH_V4 and FETCH_V6, respectively. */ #define NAME_FETCH_A(n) ((n)->fetch_a != NULL) #define NAME_FETCH_AAAA(n) ((n)->fetch_aaaa != NULL) #define NAME_FETCH_V4(n) (NAME_FETCH_A(n)) #define NAME_FETCH_V6(n) (NAME_FETCH_AAAA(n)) #define NAME_FETCH(n) (NAME_FETCH_V4(n) || NAME_FETCH_V6(n)) /* * Find options and tests to see if there are addresses on the list. */ #define FIND_WANTEVENT(fn) (((fn)->options & DNS_ADBFIND_WANTEVENT) != 0) #define FIND_WANTEMPTYEVENT(fn) (((fn)->options & DNS_ADBFIND_EMPTYEVENT) != 0) #define FIND_AVOIDFETCHES(fn) (((fn)->options & DNS_ADBFIND_AVOIDFETCHES) \ != 0) #define FIND_STARTATZONE(fn) (((fn)->options & DNS_ADBFIND_STARTATZONE) \ != 0) #define FIND_HINTOK(fn) (((fn)->options & DNS_ADBFIND_HINTOK) != 0) #define FIND_GLUEOK(fn) (((fn)->options & DNS_ADBFIND_GLUEOK) != 0) #define FIND_HAS_ADDRS(fn) (!ISC_LIST_EMPTY((fn)->list)) #define FIND_RETURNLAME(fn) (((fn)->options & DNS_ADBFIND_RETURNLAME) != 0) /* * These are currently used on simple unsigned ints, so they are * not really associated with any particular type. */ #define WANT_INET(x) (((x) & DNS_ADBFIND_INET) != 0) #define WANT_INET6(x) (((x) & DNS_ADBFIND_INET6) != 0) #define EXPIRE_OK(exp, now) ((exp == INT_MAX) || (exp < now)) /* * Find out if the flags on a name (nf) indicate if it is a hint or * glue, and compare this to the appropriate bits set in o, to see if * this is ok. */ #define GLUE_OK(nf, o) (!NAME_GLUEOK(nf) || (((o) & DNS_ADBFIND_GLUEOK) != 0)) #define HINT_OK(nf, o) (!NAME_HINTOK(nf) || (((o) & DNS_ADBFIND_HINTOK) != 0)) #define GLUEHINT_OK(nf, o) (GLUE_OK(nf, o) || HINT_OK(nf, o)) #define STARTATZONE_MATCHES(nf, o) (((nf)->flags & NAME_STARTATZONE) == \ ((o) & DNS_ADBFIND_STARTATZONE)) #define ENTER_LEVEL ISC_LOG_DEBUG(50) #define EXIT_LEVEL ENTER_LEVEL #define CLEAN_LEVEL ISC_LOG_DEBUG(100) #define DEF_LEVEL ISC_LOG_DEBUG(5) #define NCACHE_LEVEL ISC_LOG_DEBUG(20) #define NCACHE_RESULT(r) ((r) == DNS_R_NCACHENXDOMAIN || \ (r) == DNS_R_NCACHENXRRSET) #define AUTH_NX(r) ((r) == DNS_R_NXDOMAIN || \ (r) == DNS_R_NXRRSET) #define NXDOMAIN_RESULT(r) ((r) == DNS_R_NXDOMAIN || \ (r) == DNS_R_NCACHENXDOMAIN) #define NXRRSET_RESULT(r) ((r) == DNS_R_NCACHENXRRSET || \ (r) == DNS_R_NXRRSET || \ (r) == DNS_R_HINTNXRRSET) /* * Error state rankings. */ #define FIND_ERR_SUCCESS 0 /* highest rank */ #define FIND_ERR_CANCELED 1 #define FIND_ERR_FAILURE 2 #define FIND_ERR_NXDOMAIN 3 #define FIND_ERR_NXRRSET 4 #define FIND_ERR_UNEXPECTED 5 #define FIND_ERR_NOTFOUND 6 #define FIND_ERR_MAX 7 static const char *errnames[] = { "success", "canceled", "failure", "nxdomain", "nxrrset", "unexpected", "not_found" }; #define NEWERR(old, new) (ISC_MIN((old), (new))) static isc_result_t find_err_map[FIND_ERR_MAX] = { ISC_R_SUCCESS, ISC_R_CANCELED, ISC_R_FAILURE, DNS_R_NXDOMAIN, DNS_R_NXRRSET, ISC_R_UNEXPECTED, ISC_R_NOTFOUND /* not YET found */ }; static void DP(int level, const char *format, ...) ISC_FORMAT_PRINTF(2, 3); static void DP(int level, const char *format, ...) { va_list args; va_start(args, format); isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB, level, format, args); va_end(args); } /*% * Increment resolver-related statistics counters. */ static inline void inc_stats(dns_adb_t *adb, isc_statscounter_t counter) { if (adb->view->resstats != NULL) isc_stats_increment(adb->view->resstats, counter); } /*% * Set adb-related statistics counters. */ static inline void set_adbstat(dns_adb_t *adb, isc_uint64_t val, isc_statscounter_t counter) { if (adb->view->adbstats != NULL) isc_stats_set(adb->view->adbstats, val, counter); } static inline void dec_adbstats(dns_adb_t *adb, isc_statscounter_t counter) { if (adb->view->adbstats != NULL) isc_stats_decrement(adb->view->adbstats, counter); } static inline void inc_adbstats(dns_adb_t *adb, isc_statscounter_t counter) { if (adb->view->adbstats != NULL) isc_stats_increment(adb->view->adbstats, counter); } static inline dns_ttl_t ttlclamp(dns_ttl_t ttl) { if (ttl < ADB_CACHE_MINIMUM) ttl = ADB_CACHE_MINIMUM; if (ttl > ADB_CACHE_MAXIMUM) ttl = ADB_CACHE_MAXIMUM; return (ttl); } /* * Hashing is most efficient if the number of buckets is prime. * The sequence below is the closest previous primes to 2^n and * 1.5 * 2^n, for values of n from 10 to 28. (The tables will * no longer grow beyond 2^28 entries.) */ static const unsigned nbuckets[] = { 1021, 1531, 2039, 3067, 4093, 6143, 8191, 12281, 16381, 24571, 32749, 49193, 65521, 98299, 131071, 199603, 262139, 393209, 524287, 768431, 1048573, 1572853, 2097143, 3145721, 4194301, 6291449, 8388593, 12582893, 16777213, 25165813, 33554393, 50331599, 67108859, 100663291, 134217689, 201326557, 268535431, 0 }; static void grow_entries(isc_task_t *task, isc_event_t *ev) { dns_adb_t *adb; dns_adbentry_t *e; dns_adbentrylist_t *newdeadentries = NULL; dns_adbentrylist_t *newentries = NULL; isc_boolean_t *newentry_sd = NULL; isc_mutex_t *newentrylocks = NULL; isc_result_t result; unsigned int *newentry_refcnt = NULL; unsigned int i, n, bucket; adb = ev->ev_arg; INSIST(DNS_ADB_VALID(adb)); isc_event_free(&ev); result = isc_task_beginexclusive(task); if (result != ISC_R_SUCCESS) goto check_exit; i = 0; while (nbuckets[i] != 0 && adb->nentries >= nbuckets[i]) i++; if (nbuckets[i] != 0) n = nbuckets[i]; else goto done; DP(ISC_LOG_INFO, "adb: grow_entries to %u starting", n); /* * Are we shutting down? */ for (i = 0; i < adb->nentries; i++) if (adb->entry_sd[i]) goto cleanup; /* * Grab all the resources we need. */ newentries = isc_mem_get(adb->mctx, sizeof(*newentries) * n); newdeadentries = isc_mem_get(adb->mctx, sizeof(*newdeadentries) * n); newentrylocks = isc_mem_get(adb->mctx, sizeof(*newentrylocks) * n); newentry_sd = isc_mem_get(adb->mctx, sizeof(*newentry_sd) * n); newentry_refcnt = isc_mem_get(adb->mctx, sizeof(*newentry_refcnt) * n); if (newentries == NULL || newdeadentries == NULL || newentrylocks == NULL || newentry_sd == NULL || newentry_refcnt == NULL) goto cleanup; /* * Initialise the new resources. */ result = isc_mutexblock_init(newentrylocks, n); if (result != ISC_R_SUCCESS) goto cleanup; for (i = 0; i < n; i++) { ISC_LIST_INIT(newentries[i]); ISC_LIST_INIT(newdeadentries[i]); newentry_sd[i] = ISC_FALSE; newentry_refcnt[i] = 0; adb->irefcnt++; } /* * Move entries to new arrays. */ for (i = 0; i < adb->nentries; i++) { e = ISC_LIST_HEAD(adb->entries[i]); while (e != NULL) { ISC_LIST_UNLINK(adb->entries[i], e, plink); bucket = isc_sockaddr_hash(&e->sockaddr, ISC_TRUE) % n; e->lock_bucket = bucket; ISC_LIST_APPEND(newentries[bucket], e, plink); INSIST(adb->entry_refcnt[i] > 0); adb->entry_refcnt[i]--; newentry_refcnt[bucket]++; e = ISC_LIST_HEAD(adb->entries[i]); } e = ISC_LIST_HEAD(adb->deadentries[i]); while (e != NULL) { ISC_LIST_UNLINK(adb->deadentries[i], e, plink); bucket = isc_sockaddr_hash(&e->sockaddr, ISC_TRUE) % n; e->lock_bucket = bucket; ISC_LIST_APPEND(newdeadentries[bucket], e, plink); INSIST(adb->entry_refcnt[i] > 0); adb->entry_refcnt[i]--; newentry_refcnt[bucket]++; e = ISC_LIST_HEAD(adb->deadentries[i]); } INSIST(adb->entry_refcnt[i] == 0); adb->irefcnt--; } /* * Cleanup old resources. */ DESTROYMUTEXBLOCK(adb->entrylocks, adb->nentries); isc_mem_put(adb->mctx, adb->entries, sizeof(*adb->entries) * adb->nentries); isc_mem_put(adb->mctx, adb->deadentries, sizeof(*adb->deadentries) * adb->nentries); isc_mem_put(adb->mctx, adb->entrylocks, sizeof(*adb->entrylocks) * adb->nentries); isc_mem_put(adb->mctx, adb->entry_sd, sizeof(*adb->entry_sd) * adb->nentries); isc_mem_put(adb->mctx, adb->entry_refcnt, sizeof(*adb->entry_refcnt) * adb->nentries); /* * Install new resources. */ adb->entries = newentries; adb->deadentries = newdeadentries; adb->entrylocks = newentrylocks; adb->entry_sd = newentry_sd; adb->entry_refcnt = newentry_refcnt; adb->nentries = n; set_adbstat(adb, adb->nentries, dns_adbstats_nentries); /* * Only on success do we set adb->growentries_sent to ISC_FALSE. * This will prevent us being continuously being called on error. */ adb->growentries_sent = ISC_FALSE; goto done; cleanup: if (newentries != NULL) isc_mem_put(adb->mctx, newentries, sizeof(*newentries) * n); if (newdeadentries != NULL) isc_mem_put(adb->mctx, newdeadentries, sizeof(*newdeadentries) * n); if (newentrylocks != NULL) isc_mem_put(adb->mctx, newentrylocks, sizeof(*newentrylocks) * n); if (newentry_sd != NULL) isc_mem_put(adb->mctx, newentry_sd, sizeof(*newentry_sd) * n); if (newentry_refcnt != NULL) isc_mem_put(adb->mctx, newentry_refcnt, sizeof(*newentry_refcnt) * n); done: isc_task_endexclusive(task); check_exit: LOCK(&adb->lock); if (dec_adb_irefcnt(adb)) check_exit(adb); UNLOCK(&adb->lock); DP(ISC_LOG_INFO, "adb: grow_entries finished"); } static void grow_names(isc_task_t *task, isc_event_t *ev) { dns_adb_t *adb; dns_adbname_t *name; dns_adbnamelist_t *newdeadnames = NULL; dns_adbnamelist_t *newnames = NULL; isc_boolean_t *newname_sd = NULL; isc_mutex_t *newnamelocks = NULL; isc_result_t result; unsigned int *newname_refcnt = NULL; unsigned int i, n, bucket; adb = ev->ev_arg; INSIST(DNS_ADB_VALID(adb)); isc_event_free(&ev); result = isc_task_beginexclusive(task); if (result != ISC_R_SUCCESS) goto check_exit; i = 0; while (nbuckets[i] != 0 && adb->nnames >= nbuckets[i]) i++; if (nbuckets[i] != 0) n = nbuckets[i]; else goto done; DP(ISC_LOG_INFO, "adb: grow_names to %u starting", n); /* * Are we shutting down? */ for (i = 0; i < adb->nnames; i++) if (adb->name_sd[i]) goto cleanup; /* * Grab all the resources we need. */ newnames = isc_mem_get(adb->mctx, sizeof(*newnames) * n); newdeadnames = isc_mem_get(adb->mctx, sizeof(*newdeadnames) * n); newnamelocks = isc_mem_get(adb->mctx, sizeof(*newnamelocks) * n); newname_sd = isc_mem_get(adb->mctx, sizeof(*newname_sd) * n); newname_refcnt = isc_mem_get(adb->mctx, sizeof(*newname_refcnt) * n); if (newnames == NULL || newdeadnames == NULL || newnamelocks == NULL || newname_sd == NULL || newname_refcnt == NULL) goto cleanup; /* * Initialise the new resources. */ result = isc_mutexblock_init(newnamelocks, n); if (result != ISC_R_SUCCESS) goto cleanup; for (i = 0; i < n; i++) { ISC_LIST_INIT(newnames[i]); ISC_LIST_INIT(newdeadnames[i]); newname_sd[i] = ISC_FALSE; newname_refcnt[i] = 0; adb->irefcnt++; } /* * Move names to new arrays. */ for (i = 0; i < adb->nnames; i++) { name = ISC_LIST_HEAD(adb->names[i]); while (name != NULL) { ISC_LIST_UNLINK(adb->names[i], name, plink); bucket = dns_name_fullhash(&name->name, ISC_TRUE) % n; name->lock_bucket = bucket; ISC_LIST_APPEND(newnames[bucket], name, plink); INSIST(adb->name_refcnt[i] > 0); adb->name_refcnt[i]--; newname_refcnt[bucket]++; name = ISC_LIST_HEAD(adb->names[i]); } name = ISC_LIST_HEAD(adb->deadnames[i]); while (name != NULL) { ISC_LIST_UNLINK(adb->deadnames[i], name, plink); bucket = dns_name_fullhash(&name->name, ISC_TRUE) % n; name->lock_bucket = bucket; ISC_LIST_APPEND(newdeadnames[bucket], name, plink); INSIST(adb->name_refcnt[i] > 0); adb->name_refcnt[i]--; newname_refcnt[bucket]++; name = ISC_LIST_HEAD(adb->deadnames[i]); } INSIST(adb->name_refcnt[i] == 0); adb->irefcnt--; } /* * Cleanup old resources. */ DESTROYMUTEXBLOCK(adb->namelocks, adb->nnames); isc_mem_put(adb->mctx, adb->names, sizeof(*adb->names) * adb->nnames); isc_mem_put(adb->mctx, adb->deadnames, sizeof(*adb->deadnames) * adb->nnames); isc_mem_put(adb->mctx, adb->namelocks, sizeof(*adb->namelocks) * adb->nnames); isc_mem_put(adb->mctx, adb->name_sd, sizeof(*adb->name_sd) * adb->nnames); isc_mem_put(adb->mctx, adb->name_refcnt, sizeof(*adb->name_refcnt) * adb->nnames); /* * Install new resources. */ adb->names = newnames; adb->deadnames = newdeadnames; adb->namelocks = newnamelocks; adb->name_sd = newname_sd; adb->name_refcnt = newname_refcnt; adb->nnames = n; set_adbstat(adb, adb->nnames, dns_adbstats_nnames); /* * Only on success do we set adb->grownames_sent to ISC_FALSE. * This will prevent us being continuously being called on error. */ adb->grownames_sent = ISC_FALSE; goto done; cleanup: if (newnames != NULL) isc_mem_put(adb->mctx, newnames, sizeof(*newnames) * n); if (newdeadnames != NULL) isc_mem_put(adb->mctx, newdeadnames, sizeof(*newdeadnames) * n); if (newnamelocks != NULL) isc_mem_put(adb->mctx, newnamelocks, sizeof(*newnamelocks) * n); if (newname_sd != NULL) isc_mem_put(adb->mctx, newname_sd, sizeof(*newname_sd) * n); if (newname_refcnt != NULL) isc_mem_put(adb->mctx, newname_refcnt, sizeof(*newname_refcnt) * n); done: isc_task_endexclusive(task); check_exit: LOCK(&adb->lock); if (dec_adb_irefcnt(adb)) check_exit(adb); UNLOCK(&adb->lock); DP(ISC_LOG_INFO, "adb: grow_names finished"); } /* * Requires the adbname bucket be locked and that no entry buckets be locked. * * This code handles A and AAAA rdatasets only. */ static isc_result_t import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset, isc_stdtime_t now) { isc_result_t result; dns_adb_t *adb; dns_adbnamehook_t *nh; dns_adbnamehook_t *anh; dns_rdata_t rdata = DNS_RDATA_INIT; struct in_addr ina; struct in6_addr in6a; isc_sockaddr_t sockaddr; dns_adbentry_t *foundentry; /* NO CLEAN UP! */ int addr_bucket; isc_boolean_t new_addresses_added; dns_rdatatype_t rdtype; unsigned int findoptions; dns_adbnamehooklist_t *hookhead; INSIST(DNS_ADBNAME_VALID(adbname)); adb = adbname->adb; INSIST(DNS_ADB_VALID(adb)); rdtype = rdataset->type; INSIST((rdtype == dns_rdatatype_a) || (rdtype == dns_rdatatype_aaaa)); if (rdtype == dns_rdatatype_a) findoptions = DNS_ADBFIND_INET; else findoptions = DNS_ADBFIND_INET6; addr_bucket = DNS_ADB_INVALIDBUCKET; new_addresses_added = ISC_FALSE; nh = NULL; result = dns_rdataset_first(rdataset); while (result == ISC_R_SUCCESS) { dns_rdata_reset(&rdata); dns_rdataset_current(rdataset, &rdata); if (rdtype == dns_rdatatype_a) { INSIST(rdata.length == 4); memmove(&ina.s_addr, rdata.data, 4); isc_sockaddr_fromin(&sockaddr, &ina, 0); hookhead = &adbname->v4; } else { INSIST(rdata.length == 16); memmove(in6a.s6_addr, rdata.data, 16); isc_sockaddr_fromin6(&sockaddr, &in6a, 0); hookhead = &adbname->v6; } INSIST(nh == NULL); nh = new_adbnamehook(adb, NULL); if (nh == NULL) { adbname->partial_result |= findoptions; result = ISC_R_NOMEMORY; goto fail; } foundentry = find_entry_and_lock(adb, &sockaddr, &addr_bucket, now); if (foundentry == NULL) { dns_adbentry_t *entry; entry = new_adbentry(adb); if (entry == NULL) { adbname->partial_result |= findoptions; result = ISC_R_NOMEMORY; goto fail; } entry->sockaddr = sockaddr; entry->refcnt = 1; entry->nh = 1; nh->entry = entry; link_entry(adb, addr_bucket, entry); } else { for (anh = ISC_LIST_HEAD(*hookhead); anh != NULL; anh = ISC_LIST_NEXT(anh, plink)) if (anh->entry == foundentry) break; if (anh == NULL) { foundentry->refcnt++; foundentry->nh++; nh->entry = foundentry; } else free_adbnamehook(adb, &nh); } new_addresses_added = ISC_TRUE; if (nh != NULL) ISC_LIST_APPEND(*hookhead, nh, plink); nh = NULL; result = dns_rdataset_next(rdataset); } fail: if (nh != NULL) free_adbnamehook(adb, &nh); if (addr_bucket != DNS_ADB_INVALIDBUCKET) UNLOCK(&adb->entrylocks[addr_bucket]); if (rdataset->trust == dns_trust_glue || rdataset->trust == dns_trust_additional) rdataset->ttl = ADB_CACHE_MINIMUM; else if (rdataset->trust == dns_trust_ultimate) rdataset->ttl = 0; else rdataset->ttl = ttlclamp(rdataset->ttl); if (rdtype == dns_rdatatype_a) { DP(NCACHE_LEVEL, "expire_v4 set to MIN(%u,%u) import_rdataset", adbname->expire_v4, now + rdataset->ttl); adbname->expire_v4 = ISC_MIN(adbname->expire_v4, ISC_MIN(now + ADB_ENTRY_WINDOW, now + rdataset->ttl)); } else { DP(NCACHE_LEVEL, "expire_v6 set to MIN(%u,%u) import_rdataset", adbname->expire_v6, now + rdataset->ttl); adbname->expire_v6 = ISC_MIN(adbname->expire_v6, ISC_MIN(now + ADB_ENTRY_WINDOW, now + rdataset->ttl)); } if (new_addresses_added) { /* * Lie a little here. This is more or less so code that cares * can find out if any new information was added or not. */ return (ISC_R_SUCCESS); } return (result); } /* * Requires the name's bucket be locked. */ static isc_boolean_t kill_name(dns_adbname_t **n, isc_eventtype_t ev) { dns_adbname_t *name; isc_boolean_t result = ISC_FALSE; isc_boolean_t result4, result6; int bucket; dns_adb_t *adb; INSIST(n != NULL); name = *n; *n = NULL; INSIST(DNS_ADBNAME_VALID(name)); adb = name->adb; INSIST(DNS_ADB_VALID(adb)); DP(DEF_LEVEL, "killing name %p", name); /* * If we're dead already, just check to see if we should go * away now or not. */ if (NAME_DEAD(name) && !NAME_FETCH(name)) { result = unlink_name(adb, name); free_adbname(adb, &name); if (result) result = dec_adb_irefcnt(adb); return (result); } /* * Clean up the name's various lists. These two are destructive * in that they will always empty the list. */ clean_finds_at_name(name, ev, DNS_ADBFIND_ADDRESSMASK); result4 = clean_namehooks(adb, &name->v4); result6 = clean_namehooks(adb, &name->v6); clean_target(adb, &name->target); result = ISC_TF(result4 || result6); /* * If fetches are running, cancel them. If none are running, we can * just kill the name here. */ if (!NAME_FETCH(name)) { INSIST(result == ISC_FALSE); result = unlink_name(adb, name); free_adbname(adb, &name); if (result) result = dec_adb_irefcnt(adb); } else { cancel_fetches_at_name(name); if (!NAME_DEAD(name)) { bucket = name->lock_bucket; ISC_LIST_UNLINK(adb->names[bucket], name, plink); ISC_LIST_APPEND(adb->deadnames[bucket], name, plink); name->flags |= NAME_IS_DEAD; } } return (result); } /* * Requires the name's bucket be locked and no entry buckets be locked. */ static isc_boolean_t check_expire_namehooks(dns_adbname_t *name, isc_stdtime_t now) { dns_adb_t *adb; isc_boolean_t result4 = ISC_FALSE; isc_boolean_t result6 = ISC_FALSE; INSIST(DNS_ADBNAME_VALID(name)); adb = name->adb; INSIST(DNS_ADB_VALID(adb)); /* * Check to see if we need to remove the v4 addresses */ if (!NAME_FETCH_V4(name) && EXPIRE_OK(name->expire_v4, now)) { if (NAME_HAS_V4(name)) { DP(DEF_LEVEL, "expiring v4 for name %p", name); result4 = clean_namehooks(adb, &name->v4); name->partial_result &= ~DNS_ADBFIND_INET; } name->expire_v4 = INT_MAX; name->fetch_err = FIND_ERR_UNEXPECTED; } /* * Check to see if we need to remove the v6 addresses */ if (!NAME_FETCH_V6(name) && EXPIRE_OK(name->expire_v6, now)) { if (NAME_HAS_V6(name)) { DP(DEF_LEVEL, "expiring v6 for name %p", name); result6 = clean_namehooks(adb, &name->v6); name->partial_result &= ~DNS_ADBFIND_INET6; } name->expire_v6 = INT_MAX; name->fetch6_err = FIND_ERR_UNEXPECTED; } /* * Check to see if we need to remove the alias target. */ if (EXPIRE_OK(name->expire_target, now)) { clean_target(adb, &name->target); name->expire_target = INT_MAX; } return (ISC_TF(result4 || result6)); } /* * Requires the name's bucket be locked. */ static inline void link_name(dns_adb_t *adb, int bucket, dns_adbname_t *name) { INSIST(name->lock_bucket == DNS_ADB_INVALIDBUCKET); ISC_LIST_PREPEND(adb->names[bucket], name, plink); name->lock_bucket = bucket; adb->name_refcnt[bucket]++; } /* * Requires the name's bucket be locked. */ static inline isc_boolean_t unlink_name(dns_adb_t *adb, dns_adbname_t *name) { int bucket; isc_boolean_t result = ISC_FALSE; bucket = name->lock_bucket; INSIST(bucket != DNS_ADB_INVALIDBUCKET); if (NAME_DEAD(name)) ISC_LIST_UNLINK(adb->deadnames[bucket], name, plink); else ISC_LIST_UNLINK(adb->names[bucket], name, plink); name->lock_bucket = DNS_ADB_INVALIDBUCKET; INSIST(adb->name_refcnt[bucket] > 0); adb->name_refcnt[bucket]--; if (adb->name_sd[bucket] && adb->name_refcnt[bucket] == 0) result = ISC_TRUE; return (result); } /* * Requires the entry's bucket be locked. */ static inline void link_entry(dns_adb_t *adb, int bucket, dns_adbentry_t *entry) { int i; dns_adbentry_t *e; if (isc_mem_isovermem(adb->mctx)) { for (i = 0; i < 2; i++) { e = ISC_LIST_TAIL(adb->entries[bucket]); if (e == NULL) break; if (e->refcnt == 0) { unlink_entry(adb, e); free_adbentry(adb, &e); continue; } INSIST((e->flags & ENTRY_IS_DEAD) == 0); e->flags |= ENTRY_IS_DEAD; ISC_LIST_UNLINK(adb->entries[bucket], e, plink); ISC_LIST_PREPEND(adb->deadentries[bucket], e, plink); } } ISC_LIST_PREPEND(adb->entries[bucket], entry, plink); entry->lock_bucket = bucket; adb->entry_refcnt[bucket]++; } /* * Requires the entry's bucket be locked. */ static inline isc_boolean_t unlink_entry(dns_adb_t *adb, dns_adbentry_t *entry) { int bucket; isc_boolean_t result = ISC_FALSE; bucket = entry->lock_bucket; INSIST(bucket != DNS_ADB_INVALIDBUCKET); if ((entry->flags & ENTRY_IS_DEAD) != 0) ISC_LIST_UNLINK(adb->deadentries[bucket], entry, plink); else ISC_LIST_UNLINK(adb->entries[bucket], entry, plink); entry->lock_bucket = DNS_ADB_INVALIDBUCKET; INSIST(adb->entry_refcnt[bucket] > 0); adb->entry_refcnt[bucket]--; if (adb->entry_sd[bucket] && adb->entry_refcnt[bucket] == 0) result = ISC_TRUE; return (result); } static inline void violate_locking_hierarchy(isc_mutex_t *have, isc_mutex_t *want) { if (isc_mutex_trylock(want) != ISC_R_SUCCESS) { UNLOCK(have); LOCK(want); LOCK(have); } } /* * The ADB _MUST_ be locked before calling. Also, exit conditions must be * checked after calling this function. */ static isc_boolean_t shutdown_names(dns_adb_t *adb) { unsigned int bucket; isc_boolean_t result = ISC_FALSE; dns_adbname_t *name; dns_adbname_t *next_name; for (bucket = 0; bucket < adb->nnames; bucket++) { LOCK(&adb->namelocks[bucket]); adb->name_sd[bucket] = ISC_TRUE; name = ISC_LIST_HEAD(adb->names[bucket]); if (name == NULL) { /* * This bucket has no names. We must decrement the * irefcnt ourselves, since it will not be * automatically triggered by a name being unlinked. */ INSIST(result == ISC_FALSE); result = dec_adb_irefcnt(adb); } else { /* * Run through the list. For each name, clean up finds * found there, and cancel any fetches running. When * all the fetches are canceled, the name will destroy * itself. */ while (name != NULL) { next_name = ISC_LIST_NEXT(name, plink); INSIST(result == ISC_FALSE); result = kill_name(&name, DNS_EVENT_ADBSHUTDOWN); name = next_name; } } UNLOCK(&adb->namelocks[bucket]); } return (result); } /* * The ADB _MUST_ be locked before calling. Also, exit conditions must be * checked after calling this function. */ static isc_boolean_t shutdown_entries(dns_adb_t *adb) { unsigned int bucket; isc_boolean_t result = ISC_FALSE; dns_adbentry_t *entry; dns_adbentry_t *next_entry; for (bucket = 0; bucket < adb->nentries; bucket++) { LOCK(&adb->entrylocks[bucket]); adb->entry_sd[bucket] = ISC_TRUE; entry = ISC_LIST_HEAD(adb->entries[bucket]); if (adb->entry_refcnt[bucket] == 0) { /* * This bucket has no entries. We must decrement the * irefcnt ourselves, since it will not be * automatically triggered by an entry being unlinked. */ result = dec_adb_irefcnt(adb); } else { /* * Run through the list. Cleanup any entries not * associated with names, and which are not in use. */ while (entry != NULL) { next_entry = ISC_LIST_NEXT(entry, plink); if (entry->refcnt == 0 && entry->expires != 0) { result = unlink_entry(adb, entry); free_adbentry(adb, &entry); if (result) result = dec_adb_irefcnt(adb); } entry = next_entry; } } UNLOCK(&adb->entrylocks[bucket]); } return (result); } /* * Name bucket must be locked */ static void cancel_fetches_at_name(dns_adbname_t *name) { if (NAME_FETCH_A(name)) dns_resolver_cancelfetch(name->fetch_a->fetch); if (NAME_FETCH_AAAA(name)) dns_resolver_cancelfetch(name->fetch_aaaa->fetch); } /* * Assumes the name bucket is locked. */ static isc_boolean_t clean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) { dns_adbentry_t *entry; dns_adbnamehook_t *namehook; int addr_bucket; isc_boolean_t result = ISC_FALSE; isc_boolean_t overmem = isc_mem_isovermem(adb->mctx); addr_bucket = DNS_ADB_INVALIDBUCKET; namehook = ISC_LIST_HEAD(*namehooks); while (namehook != NULL) { INSIST(DNS_ADBNAMEHOOK_VALID(namehook)); /* * Clean up the entry if needed. */ entry = namehook->entry; if (entry != NULL) { INSIST(DNS_ADBENTRY_VALID(entry)); if (addr_bucket != entry->lock_bucket) { if (addr_bucket != DNS_ADB_INVALIDBUCKET) UNLOCK(&adb->entrylocks[addr_bucket]); addr_bucket = entry->lock_bucket; INSIST(addr_bucket != DNS_ADB_INVALIDBUCKET); LOCK(&adb->entrylocks[addr_bucket]); } entry->nh--; result = dec_entry_refcnt(adb, overmem, entry, ISC_FALSE); } /* * Free the namehook */ namehook->entry = NULL; ISC_LIST_UNLINK(*namehooks, namehook, plink); free_adbnamehook(adb, &namehook); namehook = ISC_LIST_HEAD(*namehooks); } if (addr_bucket != DNS_ADB_INVALIDBUCKET) UNLOCK(&adb->entrylocks[addr_bucket]); return (result); } static void clean_target(dns_adb_t *adb, dns_name_t *target) { if (dns_name_countlabels(target) > 0) { dns_name_free(target, adb->mctx); dns_name_init(target, NULL); } } static isc_result_t set_target(dns_adb_t *adb, dns_name_t *name, dns_name_t *fname, dns_rdataset_t *rdataset, dns_name_t *target) { isc_result_t result; dns_namereln_t namereln; unsigned int nlabels; int order; dns_rdata_t rdata = DNS_RDATA_INIT; dns_fixedname_t fixed1, fixed2; dns_name_t *prefix, *new_target; REQUIRE(dns_name_countlabels(target) == 0); if (rdataset->type == dns_rdatatype_cname) { dns_rdata_cname_t cname; /* * Copy the CNAME's target into the target name. */ result = dns_rdataset_first(rdataset); if (result != ISC_R_SUCCESS) return (result); dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &cname, NULL); if (result != ISC_R_SUCCESS) return (result); result = dns_name_dup(&cname.cname, adb->mctx, target); dns_rdata_freestruct(&cname); if (result != ISC_R_SUCCESS) return (result); } else { dns_rdata_dname_t dname; INSIST(rdataset->type == dns_rdatatype_dname); namereln = dns_name_fullcompare(name, fname, &order, &nlabels); INSIST(namereln == dns_namereln_subdomain); /* * Get the target name of the DNAME. */ result = dns_rdataset_first(rdataset); if (result != ISC_R_SUCCESS) return (result); dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &dname, NULL); if (result != ISC_R_SUCCESS) return (result); /* * Construct the new target name. */ dns_fixedname_init(&fixed1); prefix = dns_fixedname_name(&fixed1); dns_fixedname_init(&fixed2); new_target = dns_fixedname_name(&fixed2); dns_name_split(name, nlabels, prefix, NULL); result = dns_name_concatenate(prefix, &dname.dname, new_target, NULL); dns_rdata_freestruct(&dname); if (result != ISC_R_SUCCESS) return (result); result = dns_name_dup(new_target, adb->mctx, target); if (result != ISC_R_SUCCESS) return (result); } return (ISC_R_SUCCESS); } /* * Assumes nothing is locked, since this is called by the client. */ static void event_free(isc_event_t *event) { dns_adbfind_t *find; INSIST(event != NULL); find = event->ev_destroy_arg; INSIST(DNS_ADBFIND_VALID(find)); LOCK(&find->lock); find->flags |= FIND_EVENT_FREED; event->ev_destroy_arg = NULL; UNLOCK(&find->lock); } /* * Assumes the name bucket is locked. */ static void clean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype, unsigned int addrs) { isc_event_t *ev; isc_task_t *task; dns_adbfind_t *find; dns_adbfind_t *next_find; isc_boolean_t process; unsigned int wanted, notify; DP(ENTER_LEVEL, "ENTER clean_finds_at_name, name %p, evtype %08x, addrs %08x", name, evtype, addrs); find = ISC_LIST_HEAD(name->finds); while (find != NULL) { LOCK(&find->lock); next_find = ISC_LIST_NEXT(find, plink); process = ISC_FALSE; wanted = find->flags & DNS_ADBFIND_ADDRESSMASK; notify = wanted & addrs; switch (evtype) { case DNS_EVENT_ADBMOREADDRESSES: DP(ISC_LOG_DEBUG(3), "DNS_EVENT_ADBMOREADDRESSES"); if ((notify) != 0) { find->flags &= ~addrs; process = ISC_TRUE; } break; case DNS_EVENT_ADBNOMOREADDRESSES: DP(ISC_LOG_DEBUG(3), "DNS_EVENT_ADBNOMOREADDRESSES"); find->flags &= ~addrs; wanted = find->flags & DNS_ADBFIND_ADDRESSMASK; if (wanted == 0) process = ISC_TRUE; break; default: find->flags &= ~addrs; process = ISC_TRUE; } if (process) { DP(DEF_LEVEL, "cfan: processing find %p", find); /* * Unlink the find from the name, letting the caller * call dns_adb_destroyfind() on it to clean it up * later. */ ISC_LIST_UNLINK(name->finds, find, plink); find->adbname = NULL; find->name_bucket = DNS_ADB_INVALIDBUCKET; INSIST(!FIND_EVENTSENT(find)); ev = &find->event; task = ev->ev_sender; ev->ev_sender = find; find->result_v4 = find_err_map[name->fetch_err]; find->result_v6 = find_err_map[name->fetch6_err]; ev->ev_type = evtype; ev->ev_destroy = event_free; ev->ev_destroy_arg = find; DP(DEF_LEVEL, "sending event %p to task %p for find %p", ev, task, find); isc_task_sendanddetach(&task, (isc_event_t **)&ev); find->flags |= FIND_EVENT_SENT; } else { DP(DEF_LEVEL, "cfan: skipping find %p", find); } UNLOCK(&find->lock); find = next_find; } DP(ENTER_LEVEL, "EXIT clean_finds_at_name, name %p", name); } static inline void check_exit(dns_adb_t *adb) { isc_event_t *event; /* * The caller must be holding the adb lock. */ if (adb->shutting_down) { /* * If there aren't any external references either, we're * done. Send the control event to initiate shutdown. */ INSIST(!adb->cevent_out); /* Sanity check. */ ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent), 0, NULL, DNS_EVENT_ADBCONTROL, shutdown_task, adb, adb, NULL, NULL); event = &adb->cevent; isc_task_send(adb->task, &event); adb->cevent_out = ISC_TRUE; } } static inline isc_boolean_t dec_adb_irefcnt(dns_adb_t *adb) { isc_event_t *event; isc_task_t *etask; isc_boolean_t result = ISC_FALSE; LOCK(&adb->reflock); INSIST(adb->irefcnt > 0); adb->irefcnt--; if (adb->irefcnt == 0) { event = ISC_LIST_HEAD(adb->whenshutdown); while (event != NULL) { ISC_LIST_UNLINK(adb->whenshutdown, event, ev_link); etask = event->ev_sender; event->ev_sender = adb; isc_task_sendanddetach(&etask, &event); event = ISC_LIST_HEAD(adb->whenshutdown); } } if (adb->irefcnt == 0 && adb->erefcnt == 0) result = ISC_TRUE; UNLOCK(&adb->reflock); return (result); } static inline void inc_adb_irefcnt(dns_adb_t *adb) { LOCK(&adb->reflock); adb->irefcnt++; UNLOCK(&adb->reflock); } static inline void inc_adb_erefcnt(dns_adb_t *adb) { LOCK(&adb->reflock); adb->erefcnt++; UNLOCK(&adb->reflock); } static inline void inc_entry_refcnt(dns_adb_t *adb, dns_adbentry_t *entry, isc_boolean_t lock) { int bucket; bucket = entry->lock_bucket; if (lock) LOCK(&adb->entrylocks[bucket]); entry->refcnt++; if (lock) UNLOCK(&adb->entrylocks[bucket]); } static inline isc_boolean_t dec_entry_refcnt(dns_adb_t *adb, isc_boolean_t overmem, dns_adbentry_t *entry, isc_boolean_t lock) { int bucket; isc_boolean_t destroy_entry; isc_boolean_t result = ISC_FALSE; bucket = entry->lock_bucket; if (lock) LOCK(&adb->entrylocks[bucket]); INSIST(entry->refcnt > 0); entry->refcnt--; destroy_entry = ISC_FALSE; if (entry->refcnt == 0 && (adb->entry_sd[bucket] || entry->expires == 0 || overmem || (entry->flags & ENTRY_IS_DEAD) != 0)) { destroy_entry = ISC_TRUE; result = unlink_entry(adb, entry); } if (lock) UNLOCK(&adb->entrylocks[bucket]); if (!destroy_entry) return (result); entry->lock_bucket = DNS_ADB_INVALIDBUCKET; free_adbentry(adb, &entry); if (result) result = dec_adb_irefcnt(adb); return (result); } static inline dns_adbname_t * new_adbname(dns_adb_t *adb, dns_name_t *dnsname) { dns_adbname_t *name; name = isc_mempool_get(adb->nmp); if (name == NULL) return (NULL); dns_name_init(&name->name, NULL); if (dns_name_dup(dnsname, adb->mctx, &name->name) != ISC_R_SUCCESS) { isc_mempool_put(adb->nmp, name); return (NULL); } dns_name_init(&name->target, NULL); name->magic = DNS_ADBNAME_MAGIC; name->adb = adb; name->partial_result = 0; name->flags = 0; name->expire_v4 = INT_MAX; name->expire_v6 = INT_MAX; name->expire_target = INT_MAX; name->chains = 0; name->lock_bucket = DNS_ADB_INVALIDBUCKET; ISC_LIST_INIT(name->v4); ISC_LIST_INIT(name->v6); name->fetch_a = NULL; name->fetch_aaaa = NULL; name->fetch_err = FIND_ERR_UNEXPECTED; name->fetch6_err = FIND_ERR_UNEXPECTED; ISC_LIST_INIT(name->finds); ISC_LINK_INIT(name, plink); LOCK(&adb->namescntlock); adb->namescnt++; inc_adbstats(adb, dns_adbstats_namescnt); if (!adb->grownames_sent && adb->excl != NULL && adb->namescnt > (adb->nnames * 8)) { isc_event_t *event = &adb->grownames; inc_adb_irefcnt(adb); isc_task_send(adb->excl, &event); adb->grownames_sent = ISC_TRUE; } UNLOCK(&adb->namescntlock); return (name); } static inline void free_adbname(dns_adb_t *adb, dns_adbname_t **name) { dns_adbname_t *n; INSIST(name != NULL && DNS_ADBNAME_VALID(*name)); n = *name; *name = NULL; INSIST(!NAME_HAS_V4(n)); INSIST(!NAME_HAS_V6(n)); INSIST(!NAME_FETCH(n)); INSIST(ISC_LIST_EMPTY(n->finds)); INSIST(!ISC_LINK_LINKED(n, plink)); INSIST(n->lock_bucket == DNS_ADB_INVALIDBUCKET); INSIST(n->adb == adb); n->magic = 0; dns_name_free(&n->name, adb->mctx); isc_mempool_put(adb->nmp, n); LOCK(&adb->namescntlock); adb->namescnt--; dec_adbstats(adb, dns_adbstats_namescnt); UNLOCK(&adb->namescntlock); } static inline dns_adbnamehook_t * new_adbnamehook(dns_adb_t *adb, dns_adbentry_t *entry) { dns_adbnamehook_t *nh; nh = isc_mempool_get(adb->nhmp); if (nh == NULL) return (NULL); nh->magic = DNS_ADBNAMEHOOK_MAGIC; nh->entry = entry; ISC_LINK_INIT(nh, plink); return (nh); } static inline void free_adbnamehook(dns_adb_t *adb, dns_adbnamehook_t **namehook) { dns_adbnamehook_t *nh; INSIST(namehook != NULL && DNS_ADBNAMEHOOK_VALID(*namehook)); nh = *namehook; *namehook = NULL; INSIST(nh->entry == NULL); INSIST(!ISC_LINK_LINKED(nh, plink)); nh->magic = 0; isc_mempool_put(adb->nhmp, nh); } static inline dns_adblameinfo_t * new_adblameinfo(dns_adb_t *adb, dns_name_t *qname, dns_rdatatype_t qtype) { dns_adblameinfo_t *li; li = isc_mempool_get(adb->limp); if (li == NULL) return (NULL); dns_name_init(&li->qname, NULL); if (dns_name_dup(qname, adb->mctx, &li->qname) != ISC_R_SUCCESS) { isc_mempool_put(adb->limp, li); return (NULL); } li->magic = DNS_ADBLAMEINFO_MAGIC; li->lame_timer = 0; li->qtype = qtype; ISC_LINK_INIT(li, plink); return (li); } static inline void free_adblameinfo(dns_adb_t *adb, dns_adblameinfo_t **lameinfo) { dns_adblameinfo_t *li; INSIST(lameinfo != NULL && DNS_ADBLAMEINFO_VALID(*lameinfo)); li = *lameinfo; *lameinfo = NULL; INSIST(!ISC_LINK_LINKED(li, plink)); dns_name_free(&li->qname, adb->mctx); li->magic = 0; isc_mempool_put(adb->limp, li); } static inline dns_adbentry_t * new_adbentry(dns_adb_t *adb) { dns_adbentry_t *e; isc_uint32_t r; e = isc_mempool_get(adb->emp); if (e == NULL) return (NULL); e->magic = DNS_ADBENTRY_MAGIC; e->lock_bucket = DNS_ADB_INVALIDBUCKET; e->refcnt = 0; e->nh = 0; e->flags = 0; e->udpsize = 0; e->edns = 0; e->plain = 0; e->plainto = 0; e->to4096 = 0; e->to1432 = 0; e->to1232 = 0; e->to512 = 0; e->sit = NULL; e->sitlen = 0; isc_random_get(&r); e->srtt = (r & 0x1f) + 1; e->lastage = 0; e->expires = 0; #ifdef ENABLE_FETCHLIMIT e->completed = 0; e->timeouts = 0; e->active = 0; e->mode = 0; e->quota = adb->quota; e->atr = 0.0; #endif /* ENABLE_FETCHLIMIT */ ISC_LIST_INIT(e->lameinfo); ISC_LINK_INIT(e, plink); LOCK(&adb->entriescntlock); adb->entriescnt++; inc_adbstats(adb, dns_adbstats_entriescnt); if (!adb->growentries_sent && adb->excl != NULL && adb->entriescnt > (adb->nentries * 8)) { isc_event_t *event = &adb->growentries; inc_adb_irefcnt(adb); isc_task_send(adb->excl, &event); adb->growentries_sent = ISC_TRUE; } UNLOCK(&adb->entriescntlock); return (e); } static inline void free_adbentry(dns_adb_t *adb, dns_adbentry_t **entry) { dns_adbentry_t *e; dns_adblameinfo_t *li; INSIST(entry != NULL && DNS_ADBENTRY_VALID(*entry)); e = *entry; *entry = NULL; INSIST(e->lock_bucket == DNS_ADB_INVALIDBUCKET); INSIST(e->refcnt == 0); INSIST(!ISC_LINK_LINKED(e, plink)); e->magic = 0; if (e->sit != NULL) isc_mem_put(adb->mctx, e->sit, e->sitlen); li = ISC_LIST_HEAD(e->lameinfo); while (li != NULL) { ISC_LIST_UNLINK(e->lameinfo, li, plink); free_adblameinfo(adb, &li); li = ISC_LIST_HEAD(e->lameinfo); } isc_mempool_put(adb->emp, e); LOCK(&adb->entriescntlock); adb->entriescnt--; dec_adbstats(adb, dns_adbstats_entriescnt); UNLOCK(&adb->entriescntlock); } static inline dns_adbfind_t * new_adbfind(dns_adb_t *adb) { dns_adbfind_t *h; isc_result_t result; h = isc_mempool_get(adb->ahmp); if (h == NULL) return (NULL); /* * Public members. */ h->magic = 0; h->adb = adb; h->partial_result = 0; h->options = 0; h->flags = 0; h->result_v4 = ISC_R_UNEXPECTED; h->result_v6 = ISC_R_UNEXPECTED; ISC_LINK_INIT(h, publink); ISC_LINK_INIT(h, plink); ISC_LIST_INIT(h->list); h->adbname = NULL; h->name_bucket = DNS_ADB_INVALIDBUCKET; /* * private members */ result = isc_mutex_init(&h->lock); if (result != ISC_R_SUCCESS) { isc_mempool_put(adb->ahmp, h); return (NULL); } ISC_EVENT_INIT(&h->event, sizeof(isc_event_t), 0, 0, 0, NULL, NULL, NULL, NULL, h); inc_adb_irefcnt(adb); h->magic = DNS_ADBFIND_MAGIC; return (h); } static inline dns_adbfetch_t * new_adbfetch(dns_adb_t *adb) { dns_adbfetch_t *f; f = isc_mempool_get(adb->afmp); if (f == NULL) return (NULL); f->magic = 0; f->fetch = NULL; dns_rdataset_init(&f->rdataset); f->magic = DNS_ADBFETCH_MAGIC; return (f); } static inline void free_adbfetch(dns_adb_t *adb, dns_adbfetch_t **fetch) { dns_adbfetch_t *f; INSIST(fetch != NULL && DNS_ADBFETCH_VALID(*fetch)); f = *fetch; *fetch = NULL; f->magic = 0; if (dns_rdataset_isassociated(&f->rdataset)) dns_rdataset_disassociate(&f->rdataset); isc_mempool_put(adb->afmp, f); } static inline isc_boolean_t free_adbfind(dns_adb_t *adb, dns_adbfind_t **findp) { dns_adbfind_t *find; INSIST(findp != NULL && DNS_ADBFIND_VALID(*findp)); find = *findp; *findp = NULL; INSIST(!FIND_HAS_ADDRS(find)); INSIST(!ISC_LINK_LINKED(find, publink)); INSIST(!ISC_LINK_LINKED(find, plink)); INSIST(find->name_bucket == DNS_ADB_INVALIDBUCKET); INSIST(find->adbname == NULL); find->magic = 0; DESTROYLOCK(&find->lock); isc_mempool_put(adb->ahmp, find); return (dec_adb_irefcnt(adb)); } /* * Copy bits from the entry into the newly allocated addrinfo. The entry * must be locked, and the reference count must be bumped up by one * if this function returns a valid pointer. */ static inline dns_adbaddrinfo_t * new_adbaddrinfo(dns_adb_t *adb, dns_adbentry_t *entry, in_port_t port) { dns_adbaddrinfo_t *ai; ai = isc_mempool_get(adb->aimp); if (ai == NULL) return (NULL); ai->magic = DNS_ADBADDRINFO_MAGIC; ai->sockaddr = entry->sockaddr; isc_sockaddr_setport(&ai->sockaddr, port); ai->srtt = entry->srtt; ai->flags = entry->flags; ai->entry = entry; ai->dscp = -1; ISC_LINK_INIT(ai, publink); return (ai); } static inline void free_adbaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **ainfo) { dns_adbaddrinfo_t *ai; INSIST(ainfo != NULL && DNS_ADBADDRINFO_VALID(*ainfo)); ai = *ainfo; *ainfo = NULL; INSIST(ai->entry == NULL); INSIST(!ISC_LINK_LINKED(ai, publink)); ai->magic = 0; isc_mempool_put(adb->aimp, ai); } /* * Search for the name. NOTE: The bucket is kept locked on both * success and failure, so it must always be unlocked by the caller! * * On the first call to this function, *bucketp must be set to * DNS_ADB_INVALIDBUCKET. */ static inline dns_adbname_t * find_name_and_lock(dns_adb_t *adb, dns_name_t *name, unsigned int options, int *bucketp) { dns_adbname_t *adbname; int bucket; bucket = dns_name_fullhash(name, ISC_FALSE) % adb->nnames; if (*bucketp == DNS_ADB_INVALIDBUCKET) { LOCK(&adb->namelocks[bucket]); *bucketp = bucket; } else if (*bucketp != bucket) { UNLOCK(&adb->namelocks[*bucketp]); LOCK(&adb->namelocks[bucket]); *bucketp = bucket; } adbname = ISC_LIST_HEAD(adb->names[bucket]); while (adbname != NULL) { if (!NAME_DEAD(adbname)) { if (dns_name_equal(name, &adbname->name) && GLUEHINT_OK(adbname, options) && STARTATZONE_MATCHES(adbname, options)) return (adbname); } adbname = ISC_LIST_NEXT(adbname, plink); } return (NULL); } /* * Search for the address. NOTE: The bucket is kept locked on both * success and failure, so it must always be unlocked by the caller. * * On the first call to this function, *bucketp must be set to * DNS_ADB_INVALIDBUCKET. This will cause a lock to occur. On * later calls (within the same "lock path") it can be left alone, so * if this function is called multiple times locking is only done if * the bucket changes. */ static inline dns_adbentry_t * find_entry_and_lock(dns_adb_t *adb, isc_sockaddr_t *addr, int *bucketp, isc_stdtime_t now) { dns_adbentry_t *entry, *entry_next; int bucket; bucket = isc_sockaddr_hash(addr, ISC_TRUE) % adb->nentries; if (*bucketp == DNS_ADB_INVALIDBUCKET) { LOCK(&adb->entrylocks[bucket]); *bucketp = bucket; } else if (*bucketp != bucket) { UNLOCK(&adb->entrylocks[*bucketp]); LOCK(&adb->entrylocks[bucket]); *bucketp = bucket; } /* Search the list, while cleaning up expired entries. */ for (entry = ISC_LIST_HEAD(adb->entries[bucket]); entry != NULL; entry = entry_next) { entry_next = ISC_LIST_NEXT(entry, plink); (void)check_expire_entry(adb, &entry, now); if (entry != NULL && (entry->expires == 0 || entry->expires > now) && isc_sockaddr_equal(addr, &entry->sockaddr)) { ISC_LIST_UNLINK(adb->entries[bucket], entry, plink); ISC_LIST_PREPEND(adb->entries[bucket], entry, plink); return (entry); } } return (NULL); } /* * Entry bucket MUST be locked! */ static isc_boolean_t entry_is_lame(dns_adb_t *adb, dns_adbentry_t *entry, dns_name_t *qname, dns_rdatatype_t qtype, isc_stdtime_t now) { dns_adblameinfo_t *li, *next_li; isc_boolean_t is_bad; is_bad = ISC_FALSE; li = ISC_LIST_HEAD(entry->lameinfo); if (li == NULL) return (ISC_FALSE); while (li != NULL) { next_li = ISC_LIST_NEXT(li, plink); /* * Has the entry expired? */ if (li->lame_timer < now) { ISC_LIST_UNLINK(entry->lameinfo, li, plink); free_adblameinfo(adb, &li); } /* * Order tests from least to most expensive. * * We do not break out of the main loop here as * we use the loop for house keeping. */ if (li != NULL && !is_bad && li->qtype == qtype && dns_name_equal(qname, &li->qname)) is_bad = ISC_TRUE; li = next_li; } return (is_bad); } #ifdef ENABLE_FETCHLIMIT static void log_quota(dns_adbentry_t *entry, const char *fmt, ...) { va_list ap; char msgbuf[2048]; char addrbuf[ISC_NETADDR_FORMATSIZE]; isc_netaddr_t netaddr; va_start(ap, fmt); vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); va_end(ap); isc_netaddr_fromsockaddr(&netaddr, &entry->sockaddr); isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB, ISC_LOG_INFO, "adb: quota %s (%d/%d): %s", addrbuf, entry->active, entry->quota, msgbuf); } #endif /* ENABLE_FETCHLIMIT */ static void copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *qname, dns_rdatatype_t qtype, dns_adbname_t *name, isc_stdtime_t now) { dns_adbnamehook_t *namehook; dns_adbaddrinfo_t *addrinfo; dns_adbentry_t *entry; int bucket; bucket = DNS_ADB_INVALIDBUCKET; if (find->options & DNS_ADBFIND_INET) { namehook = ISC_LIST_HEAD(name->v4); while (namehook != NULL) { entry = namehook->entry; bucket = entry->lock_bucket; INSIST(bucket != DNS_ADB_INVALIDBUCKET); LOCK(&adb->entrylocks[bucket]); #ifdef ENABLE_FETCHLIMIT if (entry->quota != 0 && entry->active >= entry->quota) { find->options |= (DNS_ADBFIND_LAMEPRUNED| DNS_ADBFIND_OVERQUOTA); goto nextv4; } #endif /* ENABLE_FETCHLIMIT */ if (!FIND_RETURNLAME(find) && entry_is_lame(adb, entry, qname, qtype, now)) { find->options |= DNS_ADBFIND_LAMEPRUNED; goto nextv4; } addrinfo = new_adbaddrinfo(adb, entry, find->port); if (addrinfo == NULL) { find->partial_result |= DNS_ADBFIND_INET; goto out; } /* * Found a valid entry. Add it to the find's list. */ inc_entry_refcnt(adb, entry, ISC_FALSE); ISC_LIST_APPEND(find->list, addrinfo, publink); addrinfo = NULL; nextv4: UNLOCK(&adb->entrylocks[bucket]); bucket = DNS_ADB_INVALIDBUCKET; namehook = ISC_LIST_NEXT(namehook, plink); } } if (find->options & DNS_ADBFIND_INET6) { namehook = ISC_LIST_HEAD(name->v6); while (namehook != NULL) { entry = namehook->entry; bucket = entry->lock_bucket; INSIST(bucket != DNS_ADB_INVALIDBUCKET); LOCK(&adb->entrylocks[bucket]); #ifdef ENABLE_FETCHLIMIT if (entry->quota != 0 && entry->active >= entry->quota) { find->options |= (DNS_ADBFIND_LAMEPRUNED| DNS_ADBFIND_OVERQUOTA); goto nextv6; } #endif /* ENABLE_FETCHLIMIT */ if (!FIND_RETURNLAME(find) && entry_is_lame(adb, entry, qname, qtype, now)) { find->options |= DNS_ADBFIND_LAMEPRUNED; goto nextv6; } addrinfo = new_adbaddrinfo(adb, entry, find->port); if (addrinfo == NULL) { find->partial_result |= DNS_ADBFIND_INET6; goto out; } /* * Found a valid entry. Add it to the find's list. */ inc_entry_refcnt(adb, entry, ISC_FALSE); ISC_LIST_APPEND(find->list, addrinfo, publink); addrinfo = NULL; nextv6: UNLOCK(&adb->entrylocks[bucket]); bucket = DNS_ADB_INVALIDBUCKET; namehook = ISC_LIST_NEXT(namehook, plink); } } out: if (bucket != DNS_ADB_INVALIDBUCKET) UNLOCK(&adb->entrylocks[bucket]); } static void shutdown_task(isc_task_t *task, isc_event_t *ev) { dns_adb_t *adb; UNUSED(task); adb = ev->ev_arg; INSIST(DNS_ADB_VALID(adb)); isc_event_free(&ev); /* * Wait for lock around check_exit() call to be released. */ LOCK(&adb->lock); UNLOCK(&adb->lock); destroy(adb); } /* * Name bucket must be locked; adb may be locked; no other locks held. */ static isc_boolean_t check_expire_name(dns_adbname_t **namep, isc_stdtime_t now) { dns_adbname_t *name; isc_boolean_t result = ISC_FALSE; INSIST(namep != NULL && DNS_ADBNAME_VALID(*namep)); name = *namep; if (NAME_HAS_V4(name) || NAME_HAS_V6(name)) return (result); if (NAME_FETCH(name)) return (result); if (!EXPIRE_OK(name->expire_v4, now)) return (result); if (!EXPIRE_OK(name->expire_v6, now)) return (result); if (!EXPIRE_OK(name->expire_target, now)) return (result); /* * The name is empty. Delete it. */ result = kill_name(&name, DNS_EVENT_ADBEXPIRED); *namep = NULL; /* * Our caller, or one of its callers, will be calling check_exit() at * some point, so we don't need to do it here. */ return (result); } /*% * Examine the tail entry of the LRU list to see if it expires or is stale * (unused for some period); if so, the name entry will be freed. If the ADB * is in the overmem condition, the tail and the next to tail entries * will be unconditionally removed (unless they have an outstanding fetch). * We don't care about a race on 'overmem' at the risk of causing some * collateral damage or a small delay in starting cleanup, so we don't bother * to lock ADB (if it's not locked). * * Name bucket must be locked; adb may be locked; no other locks held. */ static void check_stale_name(dns_adb_t *adb, int bucket, isc_stdtime_t now) { int victims, max_victims; dns_adbname_t *victim, *next_victim; isc_boolean_t overmem = isc_mem_isovermem(adb->mctx); int scans = 0; INSIST(bucket != DNS_ADB_INVALIDBUCKET); max_victims = overmem ? 2 : 1; /* * We limit the number of scanned entries to 10 (arbitrary choice) * in order to avoid examining too many entries when there are many * tail entries that have fetches (this should be rare, but could * happen). */ victim = ISC_LIST_TAIL(adb->names[bucket]); for (victims = 0; victim != NULL && victims < max_victims && scans < 10; victim = next_victim) { INSIST(!NAME_DEAD(victim)); scans++; next_victim = ISC_LIST_PREV(victim, plink); (void)check_expire_name(&victim, now); if (victim == NULL) { victims++; goto next; } if (!NAME_FETCH(victim) && (overmem || victim->last_used + ADB_STALE_MARGIN <= now)) { RUNTIME_CHECK(kill_name(&victim, DNS_EVENT_ADBCANCELED) == ISC_FALSE); victims++; } next: if (!overmem) break; } } /* * Entry bucket must be locked; adb may be locked; no other locks held. */ static isc_boolean_t check_expire_entry(dns_adb_t *adb, dns_adbentry_t **entryp, isc_stdtime_t now) { dns_adbentry_t *entry; isc_boolean_t result = ISC_FALSE; INSIST(entryp != NULL && DNS_ADBENTRY_VALID(*entryp)); entry = *entryp; if (entry->refcnt != 0) return (result); if (entry->expires == 0 || entry->expires > now) return (result); /* * The entry is not in use. Delete it. */ DP(DEF_LEVEL, "killing entry %p", entry); INSIST(ISC_LINK_LINKED(entry, plink)); result = unlink_entry(adb, entry); free_adbentry(adb, &entry); if (result) dec_adb_irefcnt(adb); *entryp = NULL; return (result); } /* * ADB must be locked, and no other locks held. */ static isc_boolean_t cleanup_names(dns_adb_t *adb, int bucket, isc_stdtime_t now) { dns_adbname_t *name; dns_adbname_t *next_name; isc_boolean_t result = ISC_FALSE; DP(CLEAN_LEVEL, "cleaning name bucket %d", bucket); LOCK(&adb->namelocks[bucket]); if (adb->name_sd[bucket]) { UNLOCK(&adb->namelocks[bucket]); return (result); } name = ISC_LIST_HEAD(adb->names[bucket]); while (name != NULL) { next_name = ISC_LIST_NEXT(name, plink); INSIST(result == ISC_FALSE); result = check_expire_namehooks(name, now); if (!result) result = check_expire_name(&name, now); name = next_name; } UNLOCK(&adb->namelocks[bucket]); return (result); } /* * ADB must be locked, and no other locks held. */ static isc_boolean_t cleanup_entries(dns_adb_t *adb, int bucket, isc_stdtime_t now) { dns_adbentry_t *entry, *next_entry; isc_boolean_t result = ISC_FALSE; DP(CLEAN_LEVEL, "cleaning entry bucket %d", bucket); LOCK(&adb->entrylocks[bucket]); entry = ISC_LIST_HEAD(adb->entries[bucket]); while (entry != NULL) { next_entry = ISC_LIST_NEXT(entry, plink); INSIST(result == ISC_FALSE); result = check_expire_entry(adb, &entry, now); entry = next_entry; } UNLOCK(&adb->entrylocks[bucket]); return (result); } static void destroy(dns_adb_t *adb) { adb->magic = 0; isc_task_detach(&adb->task); if (adb->excl != NULL) isc_task_detach(&adb->excl); isc_mempool_destroy(&adb->nmp); isc_mempool_destroy(&adb->nhmp); isc_mempool_destroy(&adb->limp); isc_mempool_destroy(&adb->emp); isc_mempool_destroy(&adb->ahmp); isc_mempool_destroy(&adb->aimp); isc_mempool_destroy(&adb->afmp); DESTROYMUTEXBLOCK(adb->entrylocks, adb->nentries); isc_mem_put(adb->mctx, adb->entries, sizeof(*adb->entries) * adb->nentries); isc_mem_put(adb->mctx, adb->deadentries, sizeof(*adb->deadentries) * adb->nentries); isc_mem_put(adb->mctx, adb->entrylocks, sizeof(*adb->entrylocks) * adb->nentries); isc_mem_put(adb->mctx, adb->entry_sd, sizeof(*adb->entry_sd) * adb->nentries); isc_mem_put(adb->mctx, adb->entry_refcnt, sizeof(*adb->entry_refcnt) * adb->nentries); DESTROYMUTEXBLOCK(adb->namelocks, adb->nnames); isc_mem_put(adb->mctx, adb->names, sizeof(*adb->names) * adb->nnames); isc_mem_put(adb->mctx, adb->deadnames, sizeof(*adb->deadnames) * adb->nnames); isc_mem_put(adb->mctx, adb->namelocks, sizeof(*adb->namelocks) * adb->nnames); isc_mem_put(adb->mctx, adb->name_sd, sizeof(*adb->name_sd) * adb->nnames); isc_mem_put(adb->mctx, adb->name_refcnt, sizeof(*adb->name_refcnt) * adb->nnames); DESTROYLOCK(&adb->reflock); DESTROYLOCK(&adb->lock); DESTROYLOCK(&adb->mplock); DESTROYLOCK(&adb->overmemlock); DESTROYLOCK(&adb->entriescntlock); DESTROYLOCK(&adb->namescntlock); isc_mem_putanddetach(&adb->mctx, adb, sizeof(dns_adb_t)); } /* * Public functions. */ isc_result_t dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr, isc_taskmgr_t *taskmgr, dns_adb_t **newadb) { dns_adb_t *adb; isc_result_t result; unsigned int i; REQUIRE(mem != NULL); REQUIRE(view != NULL); REQUIRE(timermgr != NULL); /* this is actually unused */ REQUIRE(taskmgr != NULL); REQUIRE(newadb != NULL && *newadb == NULL); UNUSED(timermgr); adb = isc_mem_get(mem, sizeof(dns_adb_t)); if (adb == NULL) return (ISC_R_NOMEMORY); /* * Initialize things here that cannot fail, and especially things * that must be NULL for the error return to work properly. */ adb->magic = 0; adb->erefcnt = 1; adb->irefcnt = 0; adb->nmp = NULL; adb->nhmp = NULL; adb->limp = NULL; adb->emp = NULL; adb->ahmp = NULL; adb->aimp = NULL; adb->afmp = NULL; adb->task = NULL; adb->excl = NULL; adb->mctx = NULL; adb->view = view; adb->taskmgr = taskmgr; adb->next_cleanbucket = 0; ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent), 0, NULL, 0, NULL, NULL, NULL, NULL, NULL); adb->cevent_out = ISC_FALSE; adb->shutting_down = ISC_FALSE; ISC_LIST_INIT(adb->whenshutdown); adb->nentries = nbuckets[0]; adb->entriescnt = 0; adb->entries = NULL; adb->deadentries = NULL; adb->entry_sd = NULL; adb->entry_refcnt = NULL; adb->entrylocks = NULL; ISC_EVENT_INIT(&adb->growentries, sizeof(adb->growentries), 0, NULL, DNS_EVENT_ADBGROWENTRIES, grow_entries, adb, adb, NULL, NULL); adb->growentries_sent = ISC_FALSE; #ifdef ENABLE_FETCHLIMIT adb->quota = 0; adb->atr_freq = 0; adb->atr_low = 0.0; adb->atr_high = 0.0; adb->atr_discount = 0.0; #endif /* ENABLE_FETCHLIMIT */ adb->nnames = nbuckets[0]; adb->namescnt = 0; adb->names = NULL; adb->deadnames = NULL; adb->name_sd = NULL; adb->name_refcnt = NULL; adb->namelocks = NULL; ISC_EVENT_INIT(&adb->grownames, sizeof(adb->grownames), 0, NULL, DNS_EVENT_ADBGROWNAMES, grow_names, adb, adb, NULL, NULL); adb->grownames_sent = ISC_FALSE; result = isc_taskmgr_excltask(adb->taskmgr, &adb->excl); if (result != ISC_R_SUCCESS) { DP(DEF_LEVEL, "adb: task-exclusive mode unavailable, " "intializing table sizes to %u\n", nbuckets[11]); adb->nentries = nbuckets[11]; adb->nnames = nbuckets[11]; } isc_mem_attach(mem, &adb->mctx); result = isc_mutex_init(&adb->lock); if (result != ISC_R_SUCCESS) goto fail0b; result = isc_mutex_init(&adb->mplock); if (result != ISC_R_SUCCESS) goto fail0c; result = isc_mutex_init(&adb->reflock); if (result != ISC_R_SUCCESS) goto fail0d; result = isc_mutex_init(&adb->overmemlock); if (result != ISC_R_SUCCESS) goto fail0e; result = isc_mutex_init(&adb->entriescntlock); if (result != ISC_R_SUCCESS) goto fail0f; result = isc_mutex_init(&adb->namescntlock); if (result != ISC_R_SUCCESS) goto fail0g; #define ALLOCENTRY(adb, el) \ do { \ (adb)->el = isc_mem_get((adb)->mctx, \ sizeof(*(adb)->el) * (adb)->nentries); \ if ((adb)->el == NULL) { \ result = ISC_R_NOMEMORY; \ goto fail1; \ }\ } while (0) ALLOCENTRY(adb, entries); ALLOCENTRY(adb, deadentries); ALLOCENTRY(adb, entrylocks); ALLOCENTRY(adb, entry_sd); ALLOCENTRY(adb, entry_refcnt); #undef ALLOCENTRY #define ALLOCNAME(adb, el) \ do { \ (adb)->el = isc_mem_get((adb)->mctx, \ sizeof(*(adb)->el) * (adb)->nnames); \ if ((adb)->el == NULL) { \ result = ISC_R_NOMEMORY; \ goto fail1; \ }\ } while (0) ALLOCNAME(adb, names); ALLOCNAME(adb, deadnames); ALLOCNAME(adb, namelocks); ALLOCNAME(adb, name_sd); ALLOCNAME(adb, name_refcnt); #undef ALLOCNAME /* * Initialize the bucket locks for names and elements. * May as well initialize the list heads, too. */ result = isc_mutexblock_init(adb->namelocks, adb->nnames); if (result != ISC_R_SUCCESS) goto fail1; for (i = 0; i < adb->nnames; i++) { ISC_LIST_INIT(adb->names[i]); ISC_LIST_INIT(adb->deadnames[i]); adb->name_sd[i] = ISC_FALSE; adb->name_refcnt[i] = 0; adb->irefcnt++; } for (i = 0; i < adb->nentries; i++) { ISC_LIST_INIT(adb->entries[i]); ISC_LIST_INIT(adb->deadentries[i]); adb->entry_sd[i] = ISC_FALSE; adb->entry_refcnt[i] = 0; adb->irefcnt++; } result = isc_mutexblock_init(adb->entrylocks, adb->nentries); if (result != ISC_R_SUCCESS) goto fail2; /* * Memory pools */ #define MPINIT(t, p, n) do { \ result = isc_mempool_create(mem, sizeof(t), &(p)); \ if (result != ISC_R_SUCCESS) \ goto fail3; \ isc_mempool_setfreemax((p), FREE_ITEMS); \ isc_mempool_setfillcount((p), FILL_COUNT); \ isc_mempool_setname((p), n); \ isc_mempool_associatelock((p), &adb->mplock); \ } while (0) MPINIT(dns_adbname_t, adb->nmp, "adbname"); MPINIT(dns_adbnamehook_t, adb->nhmp, "adbnamehook"); MPINIT(dns_adblameinfo_t, adb->limp, "adblameinfo"); MPINIT(dns_adbentry_t, adb->emp, "adbentry"); MPINIT(dns_adbfind_t, adb->ahmp, "adbfind"); MPINIT(dns_adbaddrinfo_t, adb->aimp, "adbaddrinfo"); MPINIT(dns_adbfetch_t, adb->afmp, "adbfetch"); #undef MPINIT /* * Allocate an internal task. */ result = isc_task_create(adb->taskmgr, 0, &adb->task); if (result != ISC_R_SUCCESS) goto fail3; isc_task_setname(adb->task, "ADB", adb); result = isc_stats_create(adb->mctx, &view->adbstats, dns_adbstats_max); if (result != ISC_R_SUCCESS) goto fail3; set_adbstat(adb, adb->nentries, dns_adbstats_nentries); set_adbstat(adb, adb->nnames, dns_adbstats_nnames); /* * Normal return. */ adb->magic = DNS_ADB_MAGIC; *newadb = adb; return (ISC_R_SUCCESS); fail3: if (adb->task != NULL) isc_task_detach(&adb->task); /* clean up entrylocks */ DESTROYMUTEXBLOCK(adb->entrylocks, adb->nentries); fail2: /* clean up namelocks */ DESTROYMUTEXBLOCK(adb->namelocks, adb->nnames); fail1: /* clean up only allocated memory */ if (adb->entries != NULL) isc_mem_put(adb->mctx, adb->entries, sizeof(*adb->entries) * adb->nentries); if (adb->deadentries != NULL) isc_mem_put(adb->mctx, adb->deadentries, sizeof(*adb->deadentries) * adb->nentries); if (adb->entrylocks != NULL) isc_mem_put(adb->mctx, adb->entrylocks, sizeof(*adb->entrylocks) * adb->nentries); if (adb->entry_sd != NULL) isc_mem_put(adb->mctx, adb->entry_sd, sizeof(*adb->entry_sd) * adb->nentries); if (adb->entry_refcnt != NULL) isc_mem_put(adb->mctx, adb->entry_refcnt, sizeof(*adb->entry_refcnt) * adb->nentries); if (adb->names != NULL) isc_mem_put(adb->mctx, adb->names, sizeof(*adb->names) * adb->nnames); if (adb->deadnames != NULL) isc_mem_put(adb->mctx, adb->deadnames, sizeof(*adb->deadnames) * adb->nnames); if (adb->namelocks != NULL) isc_mem_put(adb->mctx, adb->namelocks, sizeof(*adb->namelocks) * adb->nnames); if (adb->name_sd != NULL) isc_mem_put(adb->mctx, adb->name_sd, sizeof(*adb->name_sd) * adb->nnames); if (adb->name_refcnt != NULL) isc_mem_put(adb->mctx, adb->name_refcnt, sizeof(*adb->name_refcnt) * adb->nnames); if (adb->nmp != NULL) isc_mempool_destroy(&adb->nmp); if (adb->nhmp != NULL) isc_mempool_destroy(&adb->nhmp); if (adb->limp != NULL) isc_mempool_destroy(&adb->limp); if (adb->emp != NULL) isc_mempool_destroy(&adb->emp); if (adb->ahmp != NULL) isc_mempool_destroy(&adb->ahmp); if (adb->aimp != NULL) isc_mempool_destroy(&adb->aimp); if (adb->afmp != NULL) isc_mempool_destroy(&adb->afmp); DESTROYLOCK(&adb->namescntlock); fail0g: DESTROYLOCK(&adb->entriescntlock); fail0f: DESTROYLOCK(&adb->overmemlock); fail0e: DESTROYLOCK(&adb->reflock); fail0d: DESTROYLOCK(&adb->mplock); fail0c: DESTROYLOCK(&adb->lock); fail0b: if (adb->excl != NULL) isc_task_detach(&adb->excl); isc_mem_putanddetach(&adb->mctx, adb, sizeof(dns_adb_t)); return (result); } void dns_adb_attach(dns_adb_t *adb, dns_adb_t **adbx) { REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(adbx != NULL && *adbx == NULL); inc_adb_erefcnt(adb); *adbx = adb; } void dns_adb_detach(dns_adb_t **adbx) { dns_adb_t *adb; isc_boolean_t need_exit_check; REQUIRE(adbx != NULL && DNS_ADB_VALID(*adbx)); adb = *adbx; *adbx = NULL; INSIST(adb->erefcnt > 0); LOCK(&adb->reflock); adb->erefcnt--; need_exit_check = ISC_TF(adb->erefcnt == 0 && adb->irefcnt == 0); UNLOCK(&adb->reflock); if (need_exit_check) { LOCK(&adb->lock); INSIST(adb->shutting_down); check_exit(adb); UNLOCK(&adb->lock); } } void dns_adb_whenshutdown(dns_adb_t *adb, isc_task_t *task, isc_event_t **eventp) { isc_task_t *clone; isc_event_t *event; isc_boolean_t zeroirefcnt = ISC_FALSE; /* * Send '*eventp' to 'task' when 'adb' has shutdown. */ REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(eventp != NULL); event = *eventp; *eventp = NULL; LOCK(&adb->lock); LOCK(&adb->reflock); zeroirefcnt = ISC_TF(adb->irefcnt == 0); if (adb->shutting_down && zeroirefcnt && isc_mempool_getallocated(adb->ahmp) == 0) { /* * We're already shutdown. Send the event. */ event->ev_sender = adb; isc_task_send(task, &event); } else { clone = NULL; isc_task_attach(task, &clone); event->ev_sender = clone; ISC_LIST_APPEND(adb->whenshutdown, event, ev_link); } UNLOCK(&adb->reflock); UNLOCK(&adb->lock); } static void shutdown_stage2(isc_task_t *task, isc_event_t *event) { dns_adb_t *adb; UNUSED(task); adb = event->ev_arg; INSIST(DNS_ADB_VALID(adb)); LOCK(&adb->lock); INSIST(adb->shutting_down); adb->cevent_out = ISC_FALSE; (void)shutdown_names(adb); (void)shutdown_entries(adb); if (dec_adb_irefcnt(adb)) check_exit(adb); UNLOCK(&adb->lock); } void dns_adb_shutdown(dns_adb_t *adb) { isc_event_t *event; /* * Shutdown 'adb'. */ LOCK(&adb->lock); if (!adb->shutting_down) { adb->shutting_down = ISC_TRUE; isc_mem_setwater(adb->mctx, water, adb, 0, 0); /* * Isolate shutdown_names and shutdown_entries calls. */ inc_adb_irefcnt(adb); ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent), 0, NULL, DNS_EVENT_ADBCONTROL, shutdown_stage2, adb, adb, NULL, NULL); adb->cevent_out = ISC_TRUE; event = &adb->cevent; isc_task_send(adb->task, &event); } UNLOCK(&adb->lock); } isc_result_t dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, void *arg, dns_name_t *name, dns_name_t *qname, dns_rdatatype_t qtype, unsigned int options, isc_stdtime_t now, dns_name_t *target, in_port_t port, dns_adbfind_t **findp) { return (dns_adb_createfind2(adb, task, action, arg, name, qname, qtype, options, now, target, port, 0, NULL, findp)); } isc_result_t dns_adb_createfind2(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, void *arg, dns_name_t *name, dns_name_t *qname, dns_rdatatype_t qtype, unsigned int options, isc_stdtime_t now, dns_name_t *target, in_port_t port, unsigned int depth, isc_counter_t *qc, dns_adbfind_t **findp) { dns_adbfind_t *find; dns_adbname_t *adbname; int bucket; isc_boolean_t want_event, start_at_zone, alias, have_address; isc_result_t result; unsigned int wanted_addresses; unsigned int wanted_fetches; unsigned int query_pending; char namebuf[DNS_NAME_FORMATSIZE]; REQUIRE(DNS_ADB_VALID(adb)); if (task != NULL) { REQUIRE(action != NULL); } REQUIRE(name != NULL); REQUIRE(qname != NULL); REQUIRE(findp != NULL && *findp == NULL); REQUIRE(target == NULL || dns_name_hasbuffer(target)); REQUIRE((options & DNS_ADBFIND_ADDRESSMASK) != 0); result = ISC_R_UNEXPECTED; POST(result); wanted_addresses = (options & DNS_ADBFIND_ADDRESSMASK); wanted_fetches = 0; query_pending = 0; want_event = ISC_FALSE; start_at_zone = ISC_FALSE; alias = ISC_FALSE; if (now == 0) isc_stdtime_get(&now); /* * XXXMLG Move this comment somewhere else! * * Look up the name in our internal database. * * Possibilities: Note that these are not always exclusive. * * No name found. In this case, allocate a new name header and * an initial namehook or two. If any of these allocations * fail, clean up and return ISC_R_NOMEMORY. * * Name found, valid addresses present. Allocate one addrinfo * structure for each found and append it to the linked list * of addresses for this header. * * Name found, queries pending. In this case, if a task was * passed in, allocate a job id, attach it to the name's job * list and remember to tell the caller that there will be * more info coming later. */ find = new_adbfind(adb); if (find == NULL) return (ISC_R_NOMEMORY); find->port = port; /* * Remember what types of addresses we are interested in. */ find->options = options; find->flags |= wanted_addresses; if (FIND_WANTEVENT(find)) { REQUIRE(task != NULL); } if (isc_log_wouldlog(dns_lctx, DEF_LEVEL)) dns_name_format(name, namebuf, sizeof(namebuf)); else namebuf[0] = 0; /* * Try to see if we know anything about this name at all. */ bucket = DNS_ADB_INVALIDBUCKET; adbname = find_name_and_lock(adb, name, find->options, &bucket); INSIST(bucket != DNS_ADB_INVALIDBUCKET); if (adb->name_sd[bucket]) { DP(DEF_LEVEL, "dns_adb_createfind: returning ISC_R_SHUTTINGDOWN"); RUNTIME_CHECK(free_adbfind(adb, &find) == ISC_FALSE); result = ISC_R_SHUTTINGDOWN; goto out; } /* * Nothing found. Allocate a new adbname structure for this name. */ if (adbname == NULL) { /* * See if there is any stale name at the end of list, and purge * it if so. */ check_stale_name(adb, bucket, now); adbname = new_adbname(adb, name); if (adbname == NULL) { RUNTIME_CHECK(free_adbfind(adb, &find) == ISC_FALSE); result = ISC_R_NOMEMORY; goto out; } link_name(adb, bucket, adbname); if (FIND_HINTOK(find)) adbname->flags |= NAME_HINT_OK; if (FIND_GLUEOK(find)) adbname->flags |= NAME_GLUE_OK; if (FIND_STARTATZONE(find)) adbname->flags |= NAME_STARTATZONE; } else { /* Move this name forward in the LRU list */ ISC_LIST_UNLINK(adb->names[bucket], adbname, plink); ISC_LIST_PREPEND(adb->names[bucket], adbname, plink); } adbname->last_used = now; /* * Expire old entries, etc. */ RUNTIME_CHECK(check_expire_namehooks(adbname, now) == ISC_FALSE); /* * Do we know that the name is an alias? */ if (!EXPIRE_OK(adbname->expire_target, now)) { /* * Yes, it is. */ DP(DEF_LEVEL, "dns_adb_createfind: name %s (%p) is an alias (cached)", namebuf, adbname); alias = ISC_TRUE; goto post_copy; } /* * Try to populate the name from the database and/or * start fetches. First try looking for an A record * in the database. */ if (!NAME_HAS_V4(adbname) && EXPIRE_OK(adbname->expire_v4, now) && WANT_INET(wanted_addresses)) { result = dbfind_name(adbname, now, dns_rdatatype_a); if (result == ISC_R_SUCCESS) { DP(DEF_LEVEL, "dns_adb_createfind: found A for name %s (%p) in db", namebuf, adbname); goto v6; } /* * Did we get a CNAME or DNAME? */ if (result == DNS_R_ALIAS) { DP(DEF_LEVEL, "dns_adb_createfind: name %s (%p) is an alias", namebuf, adbname); alias = ISC_TRUE; goto post_copy; } /* * If the name doesn't exist at all, don't bother with * v6 queries; they won't work. * * If the name does exist but we didn't get our data, go * ahead and try AAAA. * * If the result is neither of these, try a fetch for A. */ if (NXDOMAIN_RESULT(result)) goto fetch; else if (NXRRSET_RESULT(result)) goto v6; if (!NAME_FETCH_V4(adbname)) wanted_fetches |= DNS_ADBFIND_INET; } v6: if (!NAME_HAS_V6(adbname) && EXPIRE_OK(adbname->expire_v6, now) && WANT_INET6(wanted_addresses)) { result = dbfind_name(adbname, now, dns_rdatatype_aaaa); if (result == ISC_R_SUCCESS) { DP(DEF_LEVEL, "dns_adb_createfind: found AAAA for name %s (%p)", namebuf, adbname); goto fetch; } /* * Did we get a CNAME or DNAME? */ if (result == DNS_R_ALIAS) { DP(DEF_LEVEL, "dns_adb_createfind: name %s (%p) is an alias", namebuf, adbname); alias = ISC_TRUE; goto post_copy; } /* * Listen to negative cache hints, and don't start * another query. */ if (NCACHE_RESULT(result) || AUTH_NX(result)) goto fetch; if (!NAME_FETCH_V6(adbname)) wanted_fetches |= DNS_ADBFIND_INET6; } fetch: if ((WANT_INET(wanted_addresses) && NAME_HAS_V4(adbname)) || (WANT_INET6(wanted_addresses) && NAME_HAS_V6(adbname))) have_address = ISC_TRUE; else have_address = ISC_FALSE; if (wanted_fetches != 0 && ! (FIND_AVOIDFETCHES(find) && have_address)) { /* * We're missing at least one address family. Either the * caller hasn't instructed us to avoid fetches, or we don't * know anything about any of the address families that would * be acceptable so we have to launch fetches. */ if (FIND_STARTATZONE(find)) start_at_zone = ISC_TRUE; /* * Start V4. */ if (WANT_INET(wanted_fetches) && fetch_name(adbname, start_at_zone, depth, qc, dns_rdatatype_a) == ISC_R_SUCCESS) { DP(DEF_LEVEL, "dns_adb_createfind: " "started A fetch for name %s (%p)", namebuf, adbname); } /* * Start V6. */ if (WANT_INET6(wanted_fetches) && fetch_name(adbname, start_at_zone, depth, qc, dns_rdatatype_aaaa) == ISC_R_SUCCESS) { DP(DEF_LEVEL, "dns_adb_createfind: " "started AAAA fetch for name %s (%p)", namebuf, adbname); } } /* * Run through the name and copy out the bits we are * interested in. */ copy_namehook_lists(adb, find, qname, qtype, adbname, now); post_copy: if (NAME_FETCH_V4(adbname)) query_pending |= DNS_ADBFIND_INET; if (NAME_FETCH_V6(adbname)) query_pending |= DNS_ADBFIND_INET6; /* * Attach to the name's query list if there are queries * already running, and we have been asked to. */ want_event = ISC_TRUE; if (!FIND_WANTEVENT(find)) want_event = ISC_FALSE; if (FIND_WANTEMPTYEVENT(find) && FIND_HAS_ADDRS(find)) want_event = ISC_FALSE; if ((wanted_addresses & query_pending) == 0) want_event = ISC_FALSE; if (alias) want_event = ISC_FALSE; if (want_event) { find->adbname = adbname; find->name_bucket = bucket; ISC_LIST_APPEND(adbname->finds, find, plink); find->query_pending = (query_pending & wanted_addresses); find->flags &= ~DNS_ADBFIND_ADDRESSMASK; find->flags |= (find->query_pending & DNS_ADBFIND_ADDRESSMASK); DP(DEF_LEVEL, "createfind: attaching find %p to adbname %p", find, adbname); } else { /* * Remove the flag so the caller knows there will never * be an event, and set internal flags to fake that * the event was sent and freed, so dns_adb_destroyfind() will * do the right thing. */ find->query_pending = (query_pending & wanted_addresses); find->options &= ~DNS_ADBFIND_WANTEVENT; find->flags |= (FIND_EVENT_SENT | FIND_EVENT_FREED); find->flags &= ~DNS_ADBFIND_ADDRESSMASK; } find->partial_result |= (adbname->partial_result & wanted_addresses); if (alias) { if (target != NULL) { result = dns_name_copy(&adbname->target, target, NULL); if (result != ISC_R_SUCCESS) goto out; } result = DNS_R_ALIAS; } else result = ISC_R_SUCCESS; /* * Copy out error flags from the name structure into the find. */ find->result_v4 = find_err_map[adbname->fetch_err]; find->result_v6 = find_err_map[adbname->fetch6_err]; out: if (find != NULL) { *findp = find; if (want_event) { isc_task_t *taskp; INSIST((find->flags & DNS_ADBFIND_ADDRESSMASK) != 0); taskp = NULL; isc_task_attach(task, &taskp); find->event.ev_sender = taskp; find->event.ev_action = action; find->event.ev_arg = arg; } } UNLOCK(&adb->namelocks[bucket]); return (result); } void dns_adb_destroyfind(dns_adbfind_t **findp) { dns_adbfind_t *find; dns_adbentry_t *entry; dns_adbaddrinfo_t *ai; int bucket; dns_adb_t *adb; isc_boolean_t overmem; REQUIRE(findp != NULL && DNS_ADBFIND_VALID(*findp)); find = *findp; *findp = NULL; LOCK(&find->lock); DP(DEF_LEVEL, "dns_adb_destroyfind on find %p", find); adb = find->adb; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(FIND_EVENTFREED(find)); bucket = find->name_bucket; INSIST(bucket == DNS_ADB_INVALIDBUCKET); UNLOCK(&find->lock); /* * The find doesn't exist on any list, and nothing is locked. * Return the find to the memory pool, and decrement the adb's * reference count. */ overmem = isc_mem_isovermem(adb->mctx); ai = ISC_LIST_HEAD(find->list); while (ai != NULL) { ISC_LIST_UNLINK(find->list, ai, publink); entry = ai->entry; ai->entry = NULL; INSIST(DNS_ADBENTRY_VALID(entry)); RUNTIME_CHECK(dec_entry_refcnt(adb, overmem, entry, ISC_TRUE) == ISC_FALSE); free_adbaddrinfo(adb, &ai); ai = ISC_LIST_HEAD(find->list); } /* * WARNING: The find is freed with the adb locked. This is done * to avoid a race condition where we free the find, some other * thread tests to see if it should be destroyed, detects it should * be, destroys it, and then we try to lock it for our check, but the * lock is destroyed. */ LOCK(&adb->lock); if (free_adbfind(adb, &find)) check_exit(adb); UNLOCK(&adb->lock); } void dns_adb_cancelfind(dns_adbfind_t *find) { isc_event_t *ev; isc_task_t *task; dns_adb_t *adb; int bucket; int unlock_bucket; LOCK(&find->lock); DP(DEF_LEVEL, "dns_adb_cancelfind on find %p", find); adb = find->adb; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(!FIND_EVENTFREED(find)); REQUIRE(FIND_WANTEVENT(find)); bucket = find->name_bucket; if (bucket == DNS_ADB_INVALIDBUCKET) goto cleanup; /* * We need to get the adbname's lock to unlink the find. */ unlock_bucket = bucket; violate_locking_hierarchy(&find->lock, &adb->namelocks[unlock_bucket]); bucket = find->name_bucket; if (bucket != DNS_ADB_INVALIDBUCKET) { ISC_LIST_UNLINK(find->adbname->finds, find, plink); find->adbname = NULL; find->name_bucket = DNS_ADB_INVALIDBUCKET; } UNLOCK(&adb->namelocks[unlock_bucket]); bucket = DNS_ADB_INVALIDBUCKET; POST(bucket); cleanup: if (!FIND_EVENTSENT(find)) { ev = &find->event; task = ev->ev_sender; ev->ev_sender = find; ev->ev_type = DNS_EVENT_ADBCANCELED; ev->ev_destroy = event_free; ev->ev_destroy_arg = find; find->result_v4 = ISC_R_CANCELED; find->result_v6 = ISC_R_CANCELED; DP(DEF_LEVEL, "sending event %p to task %p for find %p", ev, task, find); isc_task_sendanddetach(&task, (isc_event_t **)&ev); } UNLOCK(&find->lock); } void dns_adb_dump(dns_adb_t *adb, FILE *f) { unsigned int i; isc_stdtime_t now; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(f != NULL); /* * Lock the adb itself, lock all the name buckets, then lock all * the entry buckets. This should put the adb into a state where * nothing can change, so we can iterate through everything and * print at our leisure. */ LOCK(&adb->lock); isc_stdtime_get(&now); for (i = 0; i < adb->nnames; i++) RUNTIME_CHECK(cleanup_names(adb, i, now) == ISC_FALSE); for (i = 0; i < adb->nentries; i++) RUNTIME_CHECK(cleanup_entries(adb, i, now) == ISC_FALSE); dump_adb(adb, f, ISC_FALSE, now); UNLOCK(&adb->lock); } static void dump_ttl(FILE *f, const char *legend, isc_stdtime_t value, isc_stdtime_t now) { if (value == INT_MAX) return; fprintf(f, " [%s TTL %d]", legend, value - now); } static void dump_adb(dns_adb_t *adb, FILE *f, isc_boolean_t debug, isc_stdtime_t now) { unsigned int i; dns_adbname_t *name; dns_adbentry_t *entry; fprintf(f, ";\n; Address database dump\n;\n"); fprintf(f, "; [edns success/4096 timeout/1432 timeout/1232 timeout/" "512 timeout]\n"); fprintf(f, "; [plain success/timeout]\n;\n"); if (debug) fprintf(f, "; addr %p, erefcnt %u, irefcnt %u, finds out %u\n", adb, adb->erefcnt, adb->irefcnt, isc_mempool_getallocated(adb->nhmp)); for (i = 0; i < adb->nnames; i++) LOCK(&adb->namelocks[i]); for (i = 0; i < adb->nentries; i++) LOCK(&adb->entrylocks[i]); /* * Dump the names */ for (i = 0; i < adb->nnames; i++) { name = ISC_LIST_HEAD(adb->names[i]); if (name == NULL) continue; if (debug) fprintf(f, "; bucket %d\n", i); for (; name != NULL; name = ISC_LIST_NEXT(name, plink)) { if (debug) fprintf(f, "; name %p (flags %08x)\n", name, name->flags); fprintf(f, "; "); print_dns_name(f, &name->name); if (dns_name_countlabels(&name->target) > 0) { fprintf(f, " alias "); print_dns_name(f, &name->target); } dump_ttl(f, "v4", name->expire_v4, now); dump_ttl(f, "v6", name->expire_v6, now); dump_ttl(f, "target", name->expire_target, now); fprintf(f, " [v4 %s] [v6 %s]", errnames[name->fetch_err], errnames[name->fetch6_err]); fprintf(f, "\n"); print_namehook_list(f, "v4", adb, &name->v4, debug, now); print_namehook_list(f, "v6", adb, &name->v6, debug, now); if (debug) print_fetch_list(f, name); if (debug) print_find_list(f, name); } } fprintf(f, ";\n; Unassociated entries\n;\n"); for (i = 0; i < adb->nentries; i++) { entry = ISC_LIST_HEAD(adb->entries[i]); while (entry != NULL) { if (entry->nh == 0) dump_entry(f, adb, entry, debug, now); entry = ISC_LIST_NEXT(entry, plink); } } /* * Unlock everything */ for (i = 0; i < adb->nentries; i++) UNLOCK(&adb->entrylocks[i]); for (i = 0; i < adb->nnames; i++) UNLOCK(&adb->namelocks[i]); } static void dump_entry(FILE *f, dns_adb_t *adb, dns_adbentry_t *entry, isc_boolean_t debug, isc_stdtime_t now) { char addrbuf[ISC_NETADDR_FORMATSIZE]; char typebuf[DNS_RDATATYPE_FORMATSIZE]; isc_netaddr_t netaddr; dns_adblameinfo_t *li; #ifndef ENABLE_FETCHLIMIT UNUSED(adb); #endif /* !ENABLE_FETCHLIMIT */ isc_netaddr_fromsockaddr(&netaddr, &entry->sockaddr); isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf)); if (debug) fprintf(f, ";\t%p: refcnt %u\n", entry, entry->refcnt); fprintf(f, ";\t%s [srtt %u] [flags %08x] [edns %u/%u/%u/%u/%u] " "[plain %u/%u]", addrbuf, entry->srtt, entry->flags, entry->edns, entry->to4096, entry->to1432, entry->to1232, entry->to512, entry->plain, entry->plainto); if (entry->udpsize != 0U) fprintf(f, " [udpsize %u]", entry->udpsize); #ifdef ISC_PLATFORM_USESIT if (entry->sit != NULL) { unsigned int i; fprintf(f, " [sit="); for (i = 0; i < entry->sitlen; i++) fprintf(f, "%02x", entry->sit[i]); fprintf(f, "]"); } #endif if (entry->expires != 0) fprintf(f, " [ttl %d]", entry->expires - now); #ifdef ENABLE_FETCHLIMIT if (adb != NULL && adb->quota != 0 && adb->atr_freq != 0) { fprintf(f, " [atr %0.2f] [quota %d]", entry->atr, entry->quota); } #endif /* ENABLE_FETCHLIMIT */ fprintf(f, "\n"); for (li = ISC_LIST_HEAD(entry->lameinfo); li != NULL; li = ISC_LIST_NEXT(li, plink)) { fprintf(f, ";\t\t"); print_dns_name(f, &li->qname); dns_rdatatype_format(li->qtype, typebuf, sizeof(typebuf)); fprintf(f, " %s [lame TTL %d]\n", typebuf, li->lame_timer - now); } } void dns_adb_dumpfind(dns_adbfind_t *find, FILE *f) { char tmp[512]; const char *tmpp; dns_adbaddrinfo_t *ai; isc_sockaddr_t *sa; /* * Not used currently, in the API Just In Case we * want to dump out the name and/or entries too. */ LOCK(&find->lock); fprintf(f, ";Find %p\n", find); fprintf(f, ";\tqpending %08x partial %08x options %08x flags %08x\n", find->query_pending, find->partial_result, find->options, find->flags); fprintf(f, ";\tname_bucket %d, name %p, event sender %p\n", find->name_bucket, find->adbname, find->event.ev_sender); ai = ISC_LIST_HEAD(find->list); if (ai != NULL) fprintf(f, "\tAddresses:\n"); while (ai != NULL) { sa = &ai->sockaddr; switch (sa->type.sa.sa_family) { case AF_INET: tmpp = inet_ntop(AF_INET, &sa->type.sin.sin_addr, tmp, sizeof(tmp)); break; case AF_INET6: tmpp = inet_ntop(AF_INET6, &sa->type.sin6.sin6_addr, tmp, sizeof(tmp)); break; default: tmpp = "UnkFamily"; } if (tmpp == NULL) tmpp = "BadAddress"; fprintf(f, "\t\tentry %p, flags %08x" " srtt %u addr %s\n", ai->entry, ai->flags, ai->srtt, tmpp); ai = ISC_LIST_NEXT(ai, publink); } UNLOCK(&find->lock); } static void print_dns_name(FILE *f, dns_name_t *name) { char buf[DNS_NAME_FORMATSIZE]; INSIST(f != NULL); dns_name_format(name, buf, sizeof(buf)); fprintf(f, "%s", buf); } static void print_namehook_list(FILE *f, const char *legend, dns_adb_t *adb, dns_adbnamehooklist_t *list, isc_boolean_t debug, isc_stdtime_t now) { dns_adbnamehook_t *nh; for (nh = ISC_LIST_HEAD(*list); nh != NULL; nh = ISC_LIST_NEXT(nh, plink)) { if (debug) fprintf(f, ";\tHook(%s) %p\n", legend, nh); dump_entry(f, adb, nh->entry, debug, now); } } static inline void print_fetch(FILE *f, dns_adbfetch_t *ft, const char *type) { fprintf(f, "\t\tFetch(%s): %p -> { fetch %p }\n", type, ft, ft->fetch); } static void print_fetch_list(FILE *f, dns_adbname_t *n) { if (NAME_FETCH_A(n)) print_fetch(f, n->fetch_a, "A"); if (NAME_FETCH_AAAA(n)) print_fetch(f, n->fetch_aaaa, "AAAA"); } static void print_find_list(FILE *f, dns_adbname_t *name) { dns_adbfind_t *find; find = ISC_LIST_HEAD(name->finds); while (find != NULL) { dns_adb_dumpfind(find, f); find = ISC_LIST_NEXT(find, plink); } } static isc_result_t dbfind_name(dns_adbname_t *adbname, isc_stdtime_t now, dns_rdatatype_t rdtype) { isc_result_t result; dns_rdataset_t rdataset; dns_adb_t *adb; dns_fixedname_t foundname; dns_name_t *fname; INSIST(DNS_ADBNAME_VALID(adbname)); adb = adbname->adb; INSIST(DNS_ADB_VALID(adb)); INSIST(rdtype == dns_rdatatype_a || rdtype == dns_rdatatype_aaaa); dns_fixedname_init(&foundname); fname = dns_fixedname_name(&foundname); dns_rdataset_init(&rdataset); if (rdtype == dns_rdatatype_a) adbname->fetch_err = FIND_ERR_UNEXPECTED; else adbname->fetch6_err = FIND_ERR_UNEXPECTED; /* * We need to specify whether to search static-stub zones (if * configured) depending on whether this is a "start at zone" lookup, * i.e., whether it's a "bailiwick" glue. If it's bailiwick (in which * case NAME_STARTATZONE is set) we need to stop the search at any * matching static-stub zone without looking into the cache to honor * the configuration on which server we should send queries to. */ result = dns_view_find2(adb->view, &adbname->name, rdtype, now, NAME_GLUEOK(adbname) ? DNS_DBFIND_GLUEOK : 0, ISC_TF(NAME_HINTOK(adbname)), (adbname->flags & NAME_STARTATZONE) != 0 ? ISC_TRUE : ISC_FALSE, NULL, NULL, fname, &rdataset, NULL); /* XXXVIX this switch statement is too sparse to gen a jump table. */ switch (result) { case DNS_R_GLUE: case DNS_R_HINT: case ISC_R_SUCCESS: /* * Found in the database. Even if we can't copy out * any information, return success, or else a fetch * will be made, which will only make things worse. */ if (rdtype == dns_rdatatype_a) adbname->fetch_err = FIND_ERR_SUCCESS; else adbname->fetch6_err = FIND_ERR_SUCCESS; result = import_rdataset(adbname, &rdataset, now); break; case DNS_R_NXDOMAIN: case DNS_R_NXRRSET: /* * We're authoritative and the data doesn't exist. * Make up a negative cache entry so we don't ask again * for a while. * * XXXRTH What time should we use? I'm putting in 30 seconds * for now. */ if (rdtype == dns_rdatatype_a) { adbname->expire_v4 = now + 30; DP(NCACHE_LEVEL, "adb name %p: Caching auth negative entry for A", adbname); if (result == DNS_R_NXDOMAIN) adbname->fetch_err = FIND_ERR_NXDOMAIN; else adbname->fetch_err = FIND_ERR_NXRRSET; } else { DP(NCACHE_LEVEL, "adb name %p: Caching auth negative entry for AAAA", adbname); adbname->expire_v6 = now + 30; if (result == DNS_R_NXDOMAIN) adbname->fetch6_err = FIND_ERR_NXDOMAIN; else adbname->fetch6_err = FIND_ERR_NXRRSET; } break; case DNS_R_NCACHENXDOMAIN: case DNS_R_NCACHENXRRSET: /* * We found a negative cache entry. Pull the TTL from it * so we won't ask again for a while. */ rdataset.ttl = ttlclamp(rdataset.ttl); if (rdtype == dns_rdatatype_a) { adbname->expire_v4 = rdataset.ttl + now; if (result == DNS_R_NCACHENXDOMAIN) adbname->fetch_err = FIND_ERR_NXDOMAIN; else adbname->fetch_err = FIND_ERR_NXRRSET; DP(NCACHE_LEVEL, "adb name %p: Caching negative entry for A (ttl %u)", adbname, rdataset.ttl); } else { DP(NCACHE_LEVEL, "adb name %p: Caching negative entry for AAAA (ttl %u)", adbname, rdataset.ttl); adbname->expire_v6 = rdataset.ttl + now; if (result == DNS_R_NCACHENXDOMAIN) adbname->fetch6_err = FIND_ERR_NXDOMAIN; else adbname->fetch6_err = FIND_ERR_NXRRSET; } break; case DNS_R_CNAME: case DNS_R_DNAME: /* * Clear the hint and glue flags, so this will match * more often. */ adbname->flags &= ~(DNS_ADBFIND_GLUEOK | DNS_ADBFIND_HINTOK); rdataset.ttl = ttlclamp(rdataset.ttl); clean_target(adb, &adbname->target); adbname->expire_target = INT_MAX; result = set_target(adb, &adbname->name, fname, &rdataset, &adbname->target); if (result == ISC_R_SUCCESS) { result = DNS_R_ALIAS; DP(NCACHE_LEVEL, "adb name %p: caching alias target", adbname); adbname->expire_target = rdataset.ttl + now; } if (rdtype == dns_rdatatype_a) adbname->fetch_err = FIND_ERR_SUCCESS; else adbname->fetch6_err = FIND_ERR_SUCCESS; break; } if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); return (result); } static void fetch_callback(isc_task_t *task, isc_event_t *ev) { dns_fetchevent_t *dev; dns_adbname_t *name; dns_adb_t *adb; dns_adbfetch_t *fetch; int bucket; isc_eventtype_t ev_status; isc_stdtime_t now; isc_result_t result; unsigned int address_type; isc_boolean_t want_check_exit = ISC_FALSE; UNUSED(task); INSIST(ev->ev_type == DNS_EVENT_FETCHDONE); dev = (dns_fetchevent_t *)ev; name = ev->ev_arg; INSIST(DNS_ADBNAME_VALID(name)); adb = name->adb; INSIST(DNS_ADB_VALID(adb)); bucket = name->lock_bucket; LOCK(&adb->namelocks[bucket]); INSIST(NAME_FETCH_A(name) || NAME_FETCH_AAAA(name)); address_type = 0; if (NAME_FETCH_A(name) && (name->fetch_a->fetch == dev->fetch)) { address_type = DNS_ADBFIND_INET; fetch = name->fetch_a; name->fetch_a = NULL; } else if (NAME_FETCH_AAAA(name) && (name->fetch_aaaa->fetch == dev->fetch)) { address_type = DNS_ADBFIND_INET6; fetch = name->fetch_aaaa; name->fetch_aaaa = NULL; } else fetch = NULL; INSIST(address_type != 0 && fetch != NULL); dns_resolver_destroyfetch(&fetch->fetch); dev->fetch = NULL; ev_status = DNS_EVENT_ADBNOMOREADDRESSES; /* * Cleanup things we don't care about. */ if (dev->node != NULL) dns_db_detachnode(dev->db, &dev->node); if (dev->db != NULL) dns_db_detach(&dev->db); /* * If this name is marked as dead, clean up, throwing away * potentially good data. */ if (NAME_DEAD(name)) { free_adbfetch(adb, &fetch); isc_event_free(&ev); want_check_exit = kill_name(&name, DNS_EVENT_ADBCANCELED); UNLOCK(&adb->namelocks[bucket]); if (want_check_exit) { LOCK(&adb->lock); check_exit(adb); UNLOCK(&adb->lock); } return; } isc_stdtime_get(&now); /* * If we got a negative cache response, remember it. */ if (NCACHE_RESULT(dev->result)) { dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl); if (address_type == DNS_ADBFIND_INET) { DP(NCACHE_LEVEL, "adb fetch name %p: " "caching negative entry for A (ttl %u)", name, dev->rdataset->ttl); name->expire_v4 = ISC_MIN(name->expire_v4, dev->rdataset->ttl + now); if (dev->result == DNS_R_NCACHENXDOMAIN) name->fetch_err = FIND_ERR_NXDOMAIN; else name->fetch_err = FIND_ERR_NXRRSET; inc_stats(adb, dns_resstatscounter_gluefetchv4fail); } else { DP(NCACHE_LEVEL, "adb fetch name %p: " "caching negative entry for AAAA (ttl %u)", name, dev->rdataset->ttl); name->expire_v6 = ISC_MIN(name->expire_v6, dev->rdataset->ttl + now); if (dev->result == DNS_R_NCACHENXDOMAIN) name->fetch6_err = FIND_ERR_NXDOMAIN; else name->fetch6_err = FIND_ERR_NXRRSET; inc_stats(adb, dns_resstatscounter_gluefetchv6fail); } goto out; } /* * Handle CNAME/DNAME. */ if (dev->result == DNS_R_CNAME || dev->result == DNS_R_DNAME) { dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl); clean_target(adb, &name->target); name->expire_target = INT_MAX; result = set_target(adb, &name->name, dns_fixedname_name(&dev->foundname), dev->rdataset, &name->target); if (result == ISC_R_SUCCESS) { DP(NCACHE_LEVEL, "adb fetch name %p: caching alias target", name); name->expire_target = dev->rdataset->ttl + now; } goto check_result; } /* * Did we get back junk? If so, and there are no more fetches * sitting out there, tell all the finds about it. */ if (dev->result != ISC_R_SUCCESS) { char buf[DNS_NAME_FORMATSIZE]; dns_name_format(&name->name, buf, sizeof(buf)); DP(DEF_LEVEL, "adb: fetch of '%s' %s failed: %s", buf, address_type == DNS_ADBFIND_INET ? "A" : "AAAA", dns_result_totext(dev->result)); /* * Don't record a failure unless this is the initial * fetch of a chain. */ if (fetch->depth > 1) goto out; /* XXXMLG Don't pound on bad servers. */ if (address_type == DNS_ADBFIND_INET) { name->expire_v4 = ISC_MIN(name->expire_v4, now + 10); name->fetch_err = FIND_ERR_FAILURE; inc_stats(adb, dns_resstatscounter_gluefetchv4fail); } else { name->expire_v6 = ISC_MIN(name->expire_v6, now + 10); name->fetch6_err = FIND_ERR_FAILURE; inc_stats(adb, dns_resstatscounter_gluefetchv6fail); } goto out; } /* * We got something potentially useful. */ result = import_rdataset(name, &fetch->rdataset, now); check_result: if (result == ISC_R_SUCCESS) { ev_status = DNS_EVENT_ADBMOREADDRESSES; if (address_type == DNS_ADBFIND_INET) name->fetch_err = FIND_ERR_SUCCESS; else name->fetch6_err = FIND_ERR_SUCCESS; } out: free_adbfetch(adb, &fetch); isc_event_free(&ev); clean_finds_at_name(name, ev_status, address_type); UNLOCK(&adb->namelocks[bucket]); } static isc_result_t fetch_name(dns_adbname_t *adbname, isc_boolean_t start_at_zone, unsigned int depth, isc_counter_t *qc, dns_rdatatype_t type) { isc_result_t result; dns_adbfetch_t *fetch = NULL; dns_adb_t *adb; dns_fixedname_t fixed; dns_name_t *name; dns_rdataset_t rdataset; dns_rdataset_t *nameservers; unsigned int options; INSIST(DNS_ADBNAME_VALID(adbname)); adb = adbname->adb; INSIST(DNS_ADB_VALID(adb)); INSIST((type == dns_rdatatype_a && !NAME_FETCH_V4(adbname)) || (type == dns_rdatatype_aaaa && !NAME_FETCH_V6(adbname))); adbname->fetch_err = FIND_ERR_NOTFOUND; name = NULL; nameservers = NULL; dns_rdataset_init(&rdataset); options = DNS_FETCHOPT_NOVALIDATE; if (start_at_zone) { DP(ENTER_LEVEL, "fetch_name: starting at zone for name %p", adbname); dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); result = dns_view_findzonecut2(adb->view, &adbname->name, name, 0, 0, ISC_TRUE, ISC_FALSE, &rdataset, NULL); if (result != ISC_R_SUCCESS && result != DNS_R_HINT) goto cleanup; nameservers = &rdataset; options |= DNS_FETCHOPT_UNSHARED; } fetch = new_adbfetch(adb); if (fetch == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } fetch->depth = depth; result = dns_resolver_createfetch3(adb->view->resolver, &adbname->name, type, name, nameservers, NULL, NULL, 0, options, depth, qc, adb->task, fetch_callback, adbname, &fetch->rdataset, NULL, &fetch->fetch); if (result != ISC_R_SUCCESS) goto cleanup; if (type == dns_rdatatype_a) { adbname->fetch_a = fetch; inc_stats(adb, dns_resstatscounter_gluefetchv4); } else { adbname->fetch_aaaa = fetch; inc_stats(adb, dns_resstatscounter_gluefetchv6); } fetch = NULL; /* Keep us from cleaning this up below. */ cleanup: if (fetch != NULL) free_adbfetch(adb, &fetch); if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); return (result); } /* * XXXMLG Needs to take a find argument and an address info, no zone or adb, * since these can be extracted from the find itself. */ isc_result_t dns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr, dns_name_t *qname, dns_rdatatype_t qtype, isc_stdtime_t expire_time) { dns_adblameinfo_t *li; int bucket; isc_result_t result = ISC_R_SUCCESS; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(DNS_ADBADDRINFO_VALID(addr)); REQUIRE(qname != NULL); bucket = addr->entry->lock_bucket; LOCK(&adb->entrylocks[bucket]); li = ISC_LIST_HEAD(addr->entry->lameinfo); while (li != NULL && (li->qtype != qtype || !dns_name_equal(qname, &li->qname))) li = ISC_LIST_NEXT(li, plink); if (li != NULL) { if (expire_time > li->lame_timer) li->lame_timer = expire_time; goto unlock; } li = new_adblameinfo(adb, qname, qtype); if (li == NULL) { result = ISC_R_NOMEMORY; goto unlock; } li->lame_timer = expire_time; ISC_LIST_PREPEND(addr->entry->lameinfo, li, plink); unlock: UNLOCK(&adb->entrylocks[bucket]); return (result); } void dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int rtt, unsigned int factor) { int bucket; isc_stdtime_t now = 0; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(DNS_ADBADDRINFO_VALID(addr)); REQUIRE(factor <= 10); bucket = addr->entry->lock_bucket; LOCK(&adb->entrylocks[bucket]); if (addr->entry->expires == 0 || factor == DNS_ADB_RTTADJAGE) isc_stdtime_get(&now); adjustsrtt(addr, rtt, factor, now); UNLOCK(&adb->entrylocks[bucket]); } void dns_adb_agesrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, isc_stdtime_t now) { int bucket; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(DNS_ADBADDRINFO_VALID(addr)); bucket = addr->entry->lock_bucket; LOCK(&adb->entrylocks[bucket]); adjustsrtt(addr, 0, DNS_ADB_RTTADJAGE, now); UNLOCK(&adb->entrylocks[bucket]); } static void adjustsrtt(dns_adbaddrinfo_t *addr, unsigned int rtt, unsigned int factor, isc_stdtime_t now) { isc_uint64_t new_srtt; if (factor == DNS_ADB_RTTADJAGE) { if (addr->entry->lastage != now) { new_srtt = addr->entry->srtt; new_srtt <<= 9; new_srtt -= addr->entry->srtt; new_srtt >>= 9; addr->entry->lastage = now; } else new_srtt = addr->entry->srtt; } else new_srtt = ((isc_uint64_t)addr->entry->srtt / 10 * factor) + ((isc_uint64_t)rtt / 10 * (10 - factor)); addr->entry->srtt = (unsigned int) new_srtt; addr->srtt = (unsigned int) new_srtt; if (addr->entry->expires == 0) addr->entry->expires = now + ADB_ENTRY_WINDOW; } void dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int bits, unsigned int mask) { int bucket; isc_stdtime_t now; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(DNS_ADBADDRINFO_VALID(addr)); REQUIRE((bits & ENTRY_IS_DEAD) == 0); REQUIRE((mask & ENTRY_IS_DEAD) == 0); bucket = addr->entry->lock_bucket; LOCK(&adb->entrylocks[bucket]); addr->entry->flags = (addr->entry->flags & ~mask) | (bits & mask); if (addr->entry->expires == 0) { isc_stdtime_get(&now); addr->entry->expires = now + ADB_ENTRY_WINDOW; } /* * Note that we do not update the other bits in addr->flags with * the most recent values from addr->entry->flags. */ addr->flags = (addr->flags & ~mask) | (bits & mask); UNLOCK(&adb->entrylocks[bucket]); } #ifdef ENABLE_FETCHLIMIT /* * (10000 / ((10 + n) / 10)^(3/2)) for n in 0..99. * These will be used to make quota adjustments. */ static int quota_adj[] = { 10000, 8668, 7607, 6747, 6037, 5443, 4941, 4512, 4141, 3818, 3536, 3286, 3065, 2867, 2690, 2530, 2385, 2254, 2134, 2025, 1925, 1832, 1747, 1668, 1595, 1527, 1464, 1405, 1350, 1298, 1250, 1205, 1162, 1121, 1083, 1048, 1014, 981, 922, 894, 868, 843, 820, 797, 775, 755, 735, 716, 698, 680, 664, 648, 632, 618, 603, 590, 577, 564, 552, 540, 529, 518, 507, 497, 487, 477, 468, 459, 450, 442, 434, 426, 418, 411, 404, 397, 390, 383, 377, 370, 364, 358, 353, 347, 342, 336, 331, 326, 321, 316, 312, 307, 303, 298, 294, 290, 286, 282, 278 }; /* * Caller must hold adbentry lock */ static void maybe_adjust_quota(dns_adb_t *adb, dns_adbaddrinfo_t *addr, isc_boolean_t timeout) { double tr; UNUSED(adb); if (adb->quota == 0 || adb->atr_freq == 0) return; if (timeout) addr->entry->timeouts++; if (addr->entry->completed++ <= adb->atr_freq) return; /* * Calculate an exponential rolling average of the timeout ratio * * XXX: Integer arithmetic might be better than floating point */ tr = (double) addr->entry->timeouts / addr->entry->completed; addr->entry->timeouts = addr->entry->completed = 0; INSIST(addr->entry->atr >= 0.0); INSIST(addr->entry->atr <= 1.0); INSIST(adb->atr_discount >= 0.0); INSIST(adb->atr_discount <= 1.0); addr->entry->atr *= 1.0 - adb->atr_discount; addr->entry->atr += tr * adb->atr_discount; addr->entry->atr = ISC_CLAMP(addr->entry->atr, 0.0, 1.0); if (addr->entry->atr < adb->atr_low && addr->entry->mode > 0) { addr->entry->quota = adb->quota * quota_adj[--addr->entry->mode] / 10000; log_quota(addr->entry, "atr %0.2f, quota increased to %d", addr->entry->atr, addr->entry->quota); } else if (addr->entry->atr > adb->atr_high && addr->entry->mode < 99) { addr->entry->quota = adb->quota * quota_adj[++addr->entry->mode] / 10000; log_quota(addr->entry, "atr %0.2f, quota decreased to %d", addr->entry->atr, addr->entry->quota); } /* Ensure we don't drop to zero */ if (addr->entry->quota == 0) addr->entry->quota = 1; } #endif /* ENABLE_FETCHLIMIT */ #define EDNSTOS 3U isc_boolean_t dns_adb_noedns(dns_adb_t *adb, dns_adbaddrinfo_t *addr) { int bucket; isc_boolean_t noedns = ISC_FALSE; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(DNS_ADBADDRINFO_VALID(addr)); bucket = addr->entry->lock_bucket; LOCK(&adb->entrylocks[bucket]); if (addr->entry->edns == 0U && (addr->entry->plain > EDNSTOS || addr->entry->to4096 > EDNSTOS)) { if (((addr->entry->plain + addr->entry->to4096) & 0x3f) != 0) { noedns = ISC_TRUE; } else { /* * Increment plain so we don't get stuck. */ addr->entry->plain++; if (addr->entry->plain == 0xff) { addr->entry->edns >>= 1; addr->entry->to4096 >>= 1; addr->entry->to1432 >>= 1; addr->entry->to1232 >>= 1; addr->entry->to512 >>= 1; addr->entry->plain >>= 1; addr->entry->plainto >>= 1; } } } UNLOCK(&adb->entrylocks[bucket]); return (noedns); } void dns_adb_plainresponse(dns_adb_t *adb, dns_adbaddrinfo_t *addr) { int bucket; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(DNS_ADBADDRINFO_VALID(addr)); bucket = addr->entry->lock_bucket; LOCK(&adb->entrylocks[bucket]); #ifdef ENABLE_FETCHLIMIT maybe_adjust_quota(adb, addr, ISC_FALSE); #endif /* ENABLE_FETCHLIMIT */ addr->entry->plain++; if (addr->entry->plain == 0xff) { addr->entry->edns >>= 1; addr->entry->to4096 >>= 1; addr->entry->to1432 >>= 1; addr->entry->to1232 >>= 1; addr->entry->to512 >>= 1; addr->entry->plain >>= 1; addr->entry->plainto >>= 1; } UNLOCK(&adb->entrylocks[bucket]); } void dns_adb_timeout(dns_adb_t *adb, dns_adbaddrinfo_t *addr) { int bucket; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(DNS_ADBADDRINFO_VALID(addr)); bucket = addr->entry->lock_bucket; LOCK(&adb->entrylocks[bucket]); #ifdef ENABLE_FETCHLIMIT maybe_adjust_quota(adb, addr, ISC_TRUE); #endif /* ENABLE_FETCHLIMIT */ /* * If we have not had a successful query then clear all * edns timeout information. */ if (addr->entry->edns == 0 && addr->entry->plain == 0) { addr->entry->to512 = 0; addr->entry->to1232 = 0; addr->entry->to1432 = 0; addr->entry->to4096 = 0; } else { addr->entry->to512 >>= 1; addr->entry->to1232 >>= 1; addr->entry->to1432 >>= 1; addr->entry->to4096 >>= 1; } addr->entry->plainto++; if (addr->entry->plainto == 0xff) { addr->entry->edns >>= 1; addr->entry->plain >>= 1; addr->entry->plainto >>= 1; } UNLOCK(&adb->entrylocks[bucket]); } void dns_adb_ednsto(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size) { int bucket; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(DNS_ADBADDRINFO_VALID(addr)); bucket = addr->entry->lock_bucket; LOCK(&adb->entrylocks[bucket]); #ifdef ENABLE_FETCHLIMIT maybe_adjust_quota(adb, addr, ISC_TRUE); #endif /* ENABLE_FETCHLIMIT */ if (size <= 512U) { if (addr->entry->to512 <= EDNSTOS) { addr->entry->to512++; addr->entry->to1232++; addr->entry->to1432++; addr->entry->to4096++; } } else if (size <= 1232U) { if (addr->entry->to1232 <= EDNSTOS) { addr->entry->to1232++; addr->entry->to1432++; addr->entry->to4096++; } } else if (size <= 1432U) { if (addr->entry->to1432 <= EDNSTOS) { addr->entry->to1432++; addr->entry->to4096++; } } else { if (addr->entry->to4096 <= EDNSTOS) addr->entry->to4096++; } if (addr->entry->to4096 == 0xff) { addr->entry->edns >>= 1; addr->entry->to4096 >>= 1; addr->entry->to1432 >>= 1; addr->entry->to1232 >>= 1; addr->entry->to512 >>= 1; addr->entry->plain >>= 1; addr->entry->plainto >>= 1; } UNLOCK(&adb->entrylocks[bucket]); } void dns_adb_setudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size) { int bucket; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(DNS_ADBADDRINFO_VALID(addr)); bucket = addr->entry->lock_bucket; LOCK(&adb->entrylocks[bucket]); if (size < 512U) size = 512U; if (size > addr->entry->udpsize) addr->entry->udpsize = size; #ifdef ENABLE_FETCHLIMIT maybe_adjust_quota(adb, addr, ISC_FALSE); #endif /* ENABLE_FETCHLIMIT */ addr->entry->edns++; if (addr->entry->edns == 0xff) { addr->entry->edns >>= 1; addr->entry->to4096 >>= 1; addr->entry->to1432 >>= 1; addr->entry->to1232 >>= 1; addr->entry->to512 >>= 1; addr->entry->plain >>= 1; addr->entry->plainto >>= 1; } UNLOCK(&adb->entrylocks[bucket]); } unsigned int dns_adb_getudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr) { int bucket; unsigned int size; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(DNS_ADBADDRINFO_VALID(addr)); bucket = addr->entry->lock_bucket; LOCK(&adb->entrylocks[bucket]); size = addr->entry->udpsize; UNLOCK(&adb->entrylocks[bucket]); return (size); } unsigned int dns_adb_probesize(dns_adb_t *adb, dns_adbaddrinfo_t *addr) { return dns_adb_probesize2(adb, addr, 0); } unsigned int dns_adb_probesize2(dns_adb_t *adb, dns_adbaddrinfo_t *addr, int lookups) { int bucket; unsigned int size; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(DNS_ADBADDRINFO_VALID(addr)); bucket = addr->entry->lock_bucket; LOCK(&adb->entrylocks[bucket]); if (addr->entry->to1232 > EDNSTOS || lookups >= 2) size = 512; else if (addr->entry->to1432 > EDNSTOS || lookups >= 1) size = 1232; else if (addr->entry->to4096 > EDNSTOS) size = 1432; else size = 4096; /* * Don't shrink probe size below what we have seen due to multiple * lookups. */ if (lookups > 0 && size < addr->entry->udpsize && addr->entry->udpsize < 4096) size = addr->entry->udpsize; UNLOCK(&adb->entrylocks[bucket]); return (size); } void dns_adb_setsit(dns_adb_t *adb, dns_adbaddrinfo_t *addr, const unsigned char *sit, size_t len) { int bucket; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(DNS_ADBADDRINFO_VALID(addr)); bucket = addr->entry->lock_bucket; LOCK(&adb->entrylocks[bucket]); if (addr->entry->sit != NULL && (sit == NULL || len != addr->entry->sitlen)) { isc_mem_put(adb->mctx, addr->entry->sit, addr->entry->sitlen); addr->entry->sit = NULL; addr->entry->sitlen = 0; } if (addr->entry->sit == NULL && sit != NULL && len != 0U) { addr->entry->sit = isc_mem_get(adb->mctx, len); if (addr->entry->sit != NULL) addr->entry->sitlen = (isc_uint16_t)len; } if (addr->entry->sit != NULL) memmove(addr->entry->sit, sit, len); UNLOCK(&adb->entrylocks[bucket]); } size_t dns_adb_getsit(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned char *sit, size_t len) { int bucket; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(DNS_ADBADDRINFO_VALID(addr)); bucket = addr->entry->lock_bucket; LOCK(&adb->entrylocks[bucket]); if (sit != NULL && addr->entry->sit != NULL && len >= addr->entry->sitlen) { memmove(sit, addr->entry->sit, addr->entry->sitlen); len = addr->entry->sitlen; } else len = 0; UNLOCK(&adb->entrylocks[bucket]); return (len); } isc_result_t dns_adb_findaddrinfo(dns_adb_t *adb, isc_sockaddr_t *sa, dns_adbaddrinfo_t **addrp, isc_stdtime_t now) { int bucket; dns_adbentry_t *entry; dns_adbaddrinfo_t *addr; isc_result_t result; in_port_t port; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(addrp != NULL && *addrp == NULL); UNUSED(now); result = ISC_R_SUCCESS; bucket = DNS_ADB_INVALIDBUCKET; entry = find_entry_and_lock(adb, sa, &bucket, now); INSIST(bucket != DNS_ADB_INVALIDBUCKET); if (adb->entry_sd[bucket]) { result = ISC_R_SHUTTINGDOWN; goto unlock; } if (entry == NULL) { /* * We don't know anything about this address. */ entry = new_adbentry(adb); if (entry == NULL) { result = ISC_R_NOMEMORY; goto unlock; } entry->sockaddr = *sa; link_entry(adb, bucket, entry); DP(ENTER_LEVEL, "findaddrinfo: new entry %p", entry); } else DP(ENTER_LEVEL, "findaddrinfo: found entry %p", entry); port = isc_sockaddr_getport(sa); addr = new_adbaddrinfo(adb, entry, port); if (addr == NULL) { result = ISC_R_NOMEMORY; } else { inc_entry_refcnt(adb, entry, ISC_FALSE); *addrp = addr; } unlock: UNLOCK(&adb->entrylocks[bucket]); return (result); } void dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp) { dns_adbaddrinfo_t *addr; dns_adbentry_t *entry; int bucket; isc_stdtime_t now; isc_boolean_t want_check_exit = ISC_FALSE; isc_boolean_t overmem; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(addrp != NULL); addr = *addrp; REQUIRE(DNS_ADBADDRINFO_VALID(addr)); entry = addr->entry; REQUIRE(DNS_ADBENTRY_VALID(entry)); *addrp = NULL; overmem = isc_mem_isovermem(adb->mctx); bucket = addr->entry->lock_bucket; LOCK(&adb->entrylocks[bucket]); if (entry->expires == 0) { isc_stdtime_get(&now); entry->expires = now + ADB_ENTRY_WINDOW; } want_check_exit = dec_entry_refcnt(adb, overmem, entry, ISC_FALSE); UNLOCK(&adb->entrylocks[bucket]); addr->entry = NULL; free_adbaddrinfo(adb, &addr); if (want_check_exit) { LOCK(&adb->lock); check_exit(adb); UNLOCK(&adb->lock); } } void dns_adb_flush(dns_adb_t *adb) { unsigned int i; INSIST(DNS_ADB_VALID(adb)); LOCK(&adb->lock); /* * Call our cleanup routines. */ for (i = 0; i < adb->nnames; i++) RUNTIME_CHECK(cleanup_names(adb, i, INT_MAX) == ISC_FALSE); for (i = 0; i < adb->nentries; i++) RUNTIME_CHECK(cleanup_entries(adb, i, INT_MAX) == ISC_FALSE); #ifdef DUMP_ADB_AFTER_CLEANING dump_adb(adb, stdout, ISC_TRUE, INT_MAX); #endif UNLOCK(&adb->lock); } void dns_adb_flushname(dns_adb_t *adb, dns_name_t *name) { dns_adbname_t *adbname; dns_adbname_t *nextname; int bucket; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(name != NULL); LOCK(&adb->lock); bucket = dns_name_hash(name, ISC_FALSE) % adb->nnames; LOCK(&adb->namelocks[bucket]); adbname = ISC_LIST_HEAD(adb->names[bucket]); while (adbname != NULL) { nextname = ISC_LIST_NEXT(adbname, plink); if (!NAME_DEAD(adbname) && dns_name_equal(name, &adbname->name)) { RUNTIME_CHECK(kill_name(&adbname, DNS_EVENT_ADBCANCELED) == ISC_FALSE); } adbname = nextname; } UNLOCK(&adb->namelocks[bucket]); UNLOCK(&adb->lock); } void dns_adb_flushnames(dns_adb_t *adb, dns_name_t *name) { dns_adbname_t *adbname, *nextname; unsigned int i; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(name != NULL); LOCK(&adb->lock); for (i = 0; i < adb->nnames; i++) { LOCK(&adb->namelocks[i]); adbname = ISC_LIST_HEAD(adb->names[i]); while (adbname != NULL) { isc_boolean_t ret; nextname = ISC_LIST_NEXT(adbname, plink); if (!NAME_DEAD(adbname) && dns_name_issubdomain(&adbname->name, name)) { ret = kill_name(&adbname, DNS_EVENT_ADBCANCELED); RUNTIME_CHECK(ret == ISC_FALSE); } adbname = nextname; } UNLOCK(&adb->namelocks[i]); } UNLOCK(&adb->lock); } static void water(void *arg, int mark) { /* * We're going to change the way to handle overmem condition: use * isc_mem_isovermem() instead of storing the state via this callback, * since the latter way tends to cause race conditions. * To minimize the change, and in case we re-enable the callback * approach, however, keep this function at the moment. */ dns_adb_t *adb = arg; isc_boolean_t overmem = ISC_TF(mark == ISC_MEM_HIWATER); REQUIRE(DNS_ADB_VALID(adb)); DP(ISC_LOG_DEBUG(1), "adb reached %s water mark", overmem ? "high" : "low"); } void dns_adb_setadbsize(dns_adb_t *adb, size_t size) { size_t hiwater, lowater; INSIST(DNS_ADB_VALID(adb)); if (size != 0U && size < DNS_ADB_MINADBSIZE) size = DNS_ADB_MINADBSIZE; hiwater = size - (size >> 3); /* Approximately 7/8ths. */ lowater = size - (size >> 2); /* Approximately 3/4ths. */ if (size == 0U || hiwater == 0U || lowater == 0U) isc_mem_setwater(adb->mctx, water, adb, 0, 0); else isc_mem_setwater(adb->mctx, water, adb, hiwater, lowater); } void dns_adb_setquota(dns_adb_t *adb, isc_uint32_t quota, isc_uint32_t freq, double low, double high, double discount) { #ifdef ENABLE_FETCHLIMIT REQUIRE(DNS_ADB_VALID(adb)); adb->quota = quota; adb->atr_freq = freq; adb->atr_low = low; adb->atr_high = high; adb->atr_discount = discount; #else UNUSED(adb); UNUSED(quota); UNUSED(freq); UNUSED(low); UNUSED(high); UNUSED(discount); return; #endif /* !ENABLE_FETCHLIMIT */ } isc_boolean_t dns_adbentry_overquota(dns_adbentry_t *entry) { #ifdef ENABLE_FETCHLIMIT isc_boolean_t block; REQUIRE(DNS_ADBENTRY_VALID(entry)); block = ISC_TF(entry->quota != 0 && entry->active >= entry->quota); return (block); #else UNUSED(entry); return (ISC_FALSE); #endif /* !ENABLE_FETCHLIMIT */ } void dns_adb_beginudpfetch(dns_adb_t *adb, dns_adbaddrinfo_t *addr) { #ifdef ENABLE_FETCHLIMIT int bucket; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(DNS_ADBADDRINFO_VALID(addr)); bucket = addr->entry->lock_bucket; LOCK(&adb->entrylocks[bucket]); addr->entry->active++; UNLOCK(&adb->entrylocks[bucket]); #else UNUSED(adb); UNUSED(addr); return; #endif /* !ENABLE_FETCHLIMIT */ } void dns_adb_endudpfetch(dns_adb_t *adb, dns_adbaddrinfo_t *addr) { #ifdef ENABLE_FETCHLIMIT int bucket; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(DNS_ADBADDRINFO_VALID(addr)); bucket = addr->entry->lock_bucket; LOCK(&adb->entrylocks[bucket]); if (addr->entry->active > 0) addr->entry->active--; UNLOCK(&adb->entrylocks[bucket]); #else UNUSED(adb); UNUSED(addr); return; #endif /* !ENABLE_FETCHLIMIT */ } bind9-9.10.3.dfsg.P4/lib/dns/rdatalist.c0000644000470500017500000002065312664710322017064 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2008, 2010-2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include "rdatalist_p.h" static dns_rdatasetmethods_t methods = { isc__rdatalist_disassociate, isc__rdatalist_first, isc__rdatalist_next, isc__rdatalist_current, isc__rdatalist_clone, isc__rdatalist_count, isc__rdatalist_addnoqname, isc__rdatalist_getnoqname, isc__rdatalist_addclosest, isc__rdatalist_getclosest, NULL, NULL, NULL, NULL, NULL, NULL }; void dns_rdatalist_init(dns_rdatalist_t *rdatalist) { REQUIRE(rdatalist != NULL); /* * Initialize rdatalist. */ rdatalist->rdclass = 0; rdatalist->type = 0; rdatalist->covers = 0; rdatalist->ttl = 0; ISC_LIST_INIT(rdatalist->rdata); ISC_LINK_INIT(rdatalist, link); } isc_result_t dns_rdatalist_tordataset(dns_rdatalist_t *rdatalist, dns_rdataset_t *rdataset) { /* * Make 'rdataset' refer to the rdata in 'rdatalist'. */ REQUIRE(rdatalist != NULL); REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(! dns_rdataset_isassociated(rdataset)); rdataset->methods = &methods; rdataset->rdclass = rdatalist->rdclass; rdataset->type = rdatalist->type; rdataset->covers = rdatalist->covers; rdataset->ttl = rdatalist->ttl; rdataset->trust = 0; rdataset->private1 = rdatalist; rdataset->private2 = NULL; rdataset->private3 = NULL; rdataset->privateuint4 = 0; rdataset->private5 = NULL; return (ISC_R_SUCCESS); } isc_result_t dns_rdatalist_fromrdataset(dns_rdataset_t *rdataset, dns_rdatalist_t **rdatalist) { REQUIRE(rdatalist != NULL && rdataset != NULL); *rdatalist = rdataset->private1; return (ISC_R_SUCCESS); } void isc__rdatalist_disassociate(dns_rdataset_t *rdataset) { UNUSED(rdataset); } isc_result_t isc__rdatalist_first(dns_rdataset_t *rdataset) { dns_rdatalist_t *rdatalist; rdatalist = rdataset->private1; rdataset->private2 = ISC_LIST_HEAD(rdatalist->rdata); if (rdataset->private2 == NULL) return (ISC_R_NOMORE); return (ISC_R_SUCCESS); } isc_result_t isc__rdatalist_next(dns_rdataset_t *rdataset) { dns_rdata_t *rdata; REQUIRE(rdataset != NULL); rdata = rdataset->private2; if (rdata == NULL) return (ISC_R_NOMORE); rdataset->private2 = ISC_LIST_NEXT(rdata, link); if (rdataset->private2 == NULL) return (ISC_R_NOMORE); return (ISC_R_SUCCESS); } void isc__rdatalist_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) { dns_rdata_t *list_rdata; REQUIRE(rdataset != NULL); list_rdata = rdataset->private2; INSIST(list_rdata != NULL); dns_rdata_clone(list_rdata, rdata); } void isc__rdatalist_clone(dns_rdataset_t *source, dns_rdataset_t *target) { REQUIRE(source != NULL); REQUIRE(target != NULL); *target = *source; /* * Reset iterator state. */ target->private2 = NULL; } unsigned int isc__rdatalist_count(dns_rdataset_t *rdataset) { dns_rdatalist_t *rdatalist; dns_rdata_t *rdata; unsigned int count; REQUIRE(rdataset != NULL); rdatalist = rdataset->private1; count = 0; for (rdata = ISC_LIST_HEAD(rdatalist->rdata); rdata != NULL; rdata = ISC_LIST_NEXT(rdata, link)) count++; return (count); } isc_result_t isc__rdatalist_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name) { dns_rdataset_t *neg = NULL; dns_rdataset_t *negsig = NULL; dns_rdataset_t *rdset; dns_ttl_t ttl; REQUIRE(rdataset != NULL); for (rdset = ISC_LIST_HEAD(name->list); rdset != NULL; rdset = ISC_LIST_NEXT(rdset, link)) { if (rdset->rdclass != rdataset->rdclass) continue; if (rdset->type == dns_rdatatype_nsec || rdset->type == dns_rdatatype_nsec3) neg = rdset; } if (neg == NULL) return (ISC_R_NOTFOUND); for (rdset = ISC_LIST_HEAD(name->list); rdset != NULL; rdset = ISC_LIST_NEXT(rdset, link)) { if (rdset->type == dns_rdatatype_rrsig && rdset->covers == neg->type) negsig = rdset; } if (negsig == NULL) return (ISC_R_NOTFOUND); /* * Minimise ttl. */ ttl = rdataset->ttl; if (neg->ttl < ttl) ttl = neg->ttl; if (negsig->ttl < ttl) ttl = negsig->ttl; rdataset->ttl = neg->ttl = negsig->ttl = ttl; rdataset->attributes |= DNS_RDATASETATTR_NOQNAME; rdataset->private6 = name; return (ISC_R_SUCCESS); } isc_result_t isc__rdatalist_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name, dns_rdataset_t *neg, dns_rdataset_t *negsig) { dns_rdataclass_t rdclass = rdataset->rdclass; dns_rdataset_t *tneg = NULL; dns_rdataset_t *tnegsig = NULL; dns_name_t *noqname = rdataset->private6; REQUIRE(rdataset != NULL); REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0); (void)dns_name_dynamic(noqname); /* Sanity Check. */ for (rdataset = ISC_LIST_HEAD(noqname->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (rdataset->rdclass != rdclass) continue; if (rdataset->type == dns_rdatatype_nsec || rdataset->type == dns_rdatatype_nsec3) tneg = rdataset; } if (tneg == NULL) return (ISC_R_NOTFOUND); for (rdataset = ISC_LIST_HEAD(noqname->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (rdataset->type == dns_rdatatype_rrsig && rdataset->covers == tneg->type) tnegsig = rdataset; } if (tnegsig == NULL) return (ISC_R_NOTFOUND); dns_name_clone(noqname, name); dns_rdataset_clone(tneg, neg); dns_rdataset_clone(tnegsig, negsig); return (ISC_R_SUCCESS); } isc_result_t isc__rdatalist_addclosest(dns_rdataset_t *rdataset, dns_name_t *name) { dns_rdataset_t *neg = NULL; dns_rdataset_t *negsig = NULL; dns_rdataset_t *rdset; dns_ttl_t ttl; REQUIRE(rdataset != NULL); for (rdset = ISC_LIST_HEAD(name->list); rdset != NULL; rdset = ISC_LIST_NEXT(rdset, link)) { if (rdset->rdclass != rdataset->rdclass) continue; if (rdset->type == dns_rdatatype_nsec || rdset->type == dns_rdatatype_nsec3) neg = rdset; } if (neg == NULL) return (ISC_R_NOTFOUND); for (rdset = ISC_LIST_HEAD(name->list); rdset != NULL; rdset = ISC_LIST_NEXT(rdset, link)) { if (rdset->type == dns_rdatatype_rrsig && rdset->covers == neg->type) negsig = rdset; } if (negsig == NULL) return (ISC_R_NOTFOUND); /* * Minimise ttl. */ ttl = rdataset->ttl; if (neg->ttl < ttl) ttl = neg->ttl; if (negsig->ttl < ttl) ttl = negsig->ttl; rdataset->ttl = neg->ttl = negsig->ttl = ttl; rdataset->attributes |= DNS_RDATASETATTR_CLOSEST; rdataset->private7 = name; return (ISC_R_SUCCESS); } isc_result_t isc__rdatalist_getclosest(dns_rdataset_t *rdataset, dns_name_t *name, dns_rdataset_t *neg, dns_rdataset_t *negsig) { dns_rdataclass_t rdclass = rdataset->rdclass; dns_rdataset_t *tneg = NULL; dns_rdataset_t *tnegsig = NULL; dns_name_t *closest = rdataset->private7; REQUIRE(rdataset != NULL); REQUIRE((rdataset->attributes & DNS_RDATASETATTR_CLOSEST) != 0); (void)dns_name_dynamic(closest); /* Sanity Check. */ for (rdataset = ISC_LIST_HEAD(closest->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (rdataset->rdclass != rdclass) continue; if (rdataset->type == dns_rdatatype_nsec || rdataset->type == dns_rdatatype_nsec3) tneg = rdataset; } if (tneg == NULL) return (ISC_R_NOTFOUND); for (rdataset = ISC_LIST_HEAD(closest->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (rdataset->type == dns_rdatatype_rrsig && rdataset->covers == tneg->type) tnegsig = rdataset; } if (tnegsig == NULL) return (ISC_R_NOTFOUND); dns_name_clone(closest, name); dns_rdataset_clone(tneg, neg); dns_rdataset_clone(tnegsig, negsig); return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/dns/acache.c0000644000470500017500000013344212664710322016302 0ustar lamontlamont/* * Copyright (C) 2004-2008, 2012, 2013, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: acache.c,v 1.22 2008/02/07 23:46:54 tbox Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define ACACHE_MAGIC ISC_MAGIC('A', 'C', 'H', 'E') #define DNS_ACACHE_VALID(acache) ISC_MAGIC_VALID(acache, ACACHE_MAGIC) #define ACACHEENTRY_MAGIC ISC_MAGIC('A', 'C', 'E', 'T') #define DNS_ACACHEENTRY_VALID(entry) ISC_MAGIC_VALID(entry, ACACHEENTRY_MAGIC) #define DBBUCKETS 67 #if 0 #define ATRACE(m) isc_log_write(dns_lctx, \ DNS_LOGCATEGORY_DATABASE, \ DNS_LOGMODULE_ACACHE, \ ISC_LOG_DEBUG(3), \ "acache %p: %s", acache, (m)) #define AATRACE(a,m) isc_log_write(dns_lctx, \ DNS_LOGCATEGORY_DATABASE, \ DNS_LOGMODULE_ACACHE, \ ISC_LOG_DEBUG(3), \ "acache %p: %s", (a), (m)) #else #define ATRACE(m) #define AATRACE(a, m) #endif /* * The following variables control incremental cleaning. * MINSIZE is how many bytes is the floor for dns_acache_setcachesize(). * CLEANERINCREMENT is how many entries are examined in one pass. * (XXX simply derived from definitions in cache.c There may be better * constants here.) */ #define DNS_ACACHE_MINSIZE 2097152U /* Bytes. 2097152 = 2 MB */ #define DNS_ACACHE_CLEANERINCREMENT 1000 /* Number of entries. */ #define DEFAULT_ACACHE_ENTRY_LOCK_COUNT 1009 /*%< Should be prime. */ #if defined(ISC_RWLOCK_USEATOMIC) && defined(ISC_PLATFORM_HAVEATOMICSTORE) #define ACACHE_USE_RWLOCK 1 #endif #ifdef ACACHE_USE_RWLOCK #define ACACHE_INITLOCK(l) isc_rwlock_init((l), 0, 0) #define ACACHE_DESTROYLOCK(l) isc_rwlock_destroy(l) #define ACACHE_LOCK(l, t) RWLOCK((l), (t)) #define ACACHE_UNLOCK(l, t) RWUNLOCK((l), (t)) #define acache_storetime(entry, t) \ (isc_atomic_store((isc_int32_t *)&(entry)->lastused, (t))) #else #define ACACHE_INITLOCK(l) isc_mutex_init(l) #define ACACHE_DESTROYLOCK(l) DESTROYLOCK(l) #define ACACHE_LOCK(l, t) LOCK(l) #define ACACHE_UNLOCK(l, t) UNLOCK(l) #define acache_storetime(entry, t) ((entry)->lastused = (t)) #endif /* Locked by acache lock */ typedef struct dbentry { ISC_LINK(struct dbentry) link; dns_db_t *db; ISC_LIST(dns_acacheentry_t) originlist; ISC_LIST(dns_acacheentry_t) referlist; } dbentry_t; typedef ISC_LIST(dbentry_t) dbentrylist_t; typedef struct acache_cleaner acache_cleaner_t; typedef enum { cleaner_s_idle, /* Waiting for cleaning-interval to expire. */ cleaner_s_busy, /* Currently cleaning. */ cleaner_s_done /* Freed enough memory after being overmem. */ } cleaner_state_t; /* * Convenience macros for comprehensive assertion checking. */ #define CLEANER_IDLE(c) ((c)->state == cleaner_s_idle && \ (c)->resched_event != NULL) #define CLEANER_BUSY(c) ((c)->state == cleaner_s_busy && \ (c)->resched_event == NULL) struct acache_cleaner { isc_mutex_t lock; /* * Locks overmem_event, overmem. (See cache.c) */ dns_acache_t *acache; unsigned int cleaning_interval; /* The cleaning-interval from named.conf, in seconds. */ isc_stdtime_t last_cleanup_time; /* The time when the last cleanup task completed */ isc_timer_t *cleaning_timer; isc_event_t *resched_event; /* Sent by cleaner task to itself to reschedule */ isc_event_t *overmem_event; dns_acacheentry_t *current_entry; /* The bookmark entry to restart the cleaning. Locked by acache lock. */ int increment; /* Number of entries to clean in one increment */ unsigned long ncleaned; /* Number of entries cleaned up (for logging purposes) */ cleaner_state_t state; /* Idle/Busy/Done. */ isc_boolean_t overmem; /* The acache is in an overmem state. */ }; struct dns_acachestats { unsigned int hits; unsigned int queries; unsigned int misses; unsigned int adds; unsigned int deleted; unsigned int cleaned; unsigned int cleaner_runs; unsigned int overmem; unsigned int overmem_nocreates; unsigned int nomem; }; /* * The actual acache object. */ struct dns_acache { unsigned int magic; isc_mem_t *mctx; isc_refcount_t refs; #ifdef ACACHE_USE_RWLOCK isc_rwlock_t *entrylocks; #else isc_mutex_t *entrylocks; #endif isc_mutex_t lock; int live_cleaners; acache_cleaner_t cleaner; ISC_LIST(dns_acacheentry_t) entries; unsigned int dbentries; dbentrylist_t dbbucket[DBBUCKETS]; isc_boolean_t shutting_down; isc_task_t *task; isc_event_t cevent; isc_boolean_t cevent_sent; dns_acachestats_t stats; }; struct dns_acacheentry { unsigned int magic; unsigned int locknum; isc_refcount_t references; dns_acache_t *acache; /* Data for Management of cache entries */ ISC_LINK(dns_acacheentry_t) link; ISC_LINK(dns_acacheentry_t) olink; ISC_LINK(dns_acacheentry_t) rlink; dns_db_t *origdb; /* reference to the DB holding this entry */ /* Cache data */ dns_zone_t *zone; /* zone this entry belongs to */ dns_db_t *db; /* DB this entry belongs to */ dns_dbversion_t *version; /* the version of the DB */ dns_dbnode_t *node; /* node this entry belongs to */ dns_name_t *foundname; /* corresponding DNS name and rdataset */ /* Callback function and its argument */ void (*callback)(dns_acacheentry_t *, void **); void *cbarg; /* Timestamp of the last time this entry is referred to */ isc_stdtime32_t lastused; }; /* * Internal functions (and prototypes). */ static inline isc_boolean_t check_noentry(dns_acache_t *acache); static void destroy(dns_acache_t *acache); static void shutdown_entries(dns_acache_t *acache); static void shutdown_buckets(dns_acache_t *acache); static void destroy_entry(dns_acacheentry_t *ent); static inline void unlink_dbentries(dns_acache_t *acache, dns_acacheentry_t *ent); static inline isc_result_t finddbent(dns_acache_t *acache, dns_db_t *db, dbentry_t **dbentryp); static inline void clear_entry(dns_acache_t *acache, dns_acacheentry_t *entry); static isc_result_t acache_cleaner_init(dns_acache_t *acache, isc_timermgr_t *timermgr, acache_cleaner_t *cleaner); static void acache_cleaning_timer_action(isc_task_t *task, isc_event_t *event); static void acache_incremental_cleaning_action(isc_task_t *task, isc_event_t *event); static void acache_overmem_cleaning_action(isc_task_t *task, isc_event_t *event); static void acache_cleaner_shutdown_action(isc_task_t *task, isc_event_t *event); /* * acache should be locked. If it is not, the stats can get out of whack, * which is not a big deal for us since this is for debugging / stats */ static void reset_stats(dns_acache_t *acache) { acache->stats.hits = 0; acache->stats.queries = 0; acache->stats.misses = 0; acache->stats.adds = 0; acache->stats.deleted = 0; acache->stats.cleaned = 0; acache->stats.overmem = 0; acache->stats.overmem_nocreates = 0; acache->stats.nomem = 0; } /* * The acache must be locked before calling. */ static inline isc_boolean_t check_noentry(dns_acache_t *acache) { if (ISC_LIST_EMPTY(acache->entries) && acache->dbentries == 0) { return (ISC_TRUE); } return (ISC_FALSE); } /* * The acache must be locked before calling. */ static void shutdown_entries(dns_acache_t *acache) { dns_acacheentry_t *entry, *entry_next; REQUIRE(DNS_ACACHE_VALID(acache)); INSIST(acache->shutting_down); /* * Release the dependency of all entries, and detach them. */ for (entry = ISC_LIST_HEAD(acache->entries); entry != NULL; entry = entry_next) { entry_next = ISC_LIST_NEXT(entry, link); ACACHE_LOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write); /* * If the cleaner holds this entry, it will be unlinked and * freed in the cleaner later. */ if (acache->cleaner.current_entry != entry) ISC_LIST_UNLINK(acache->entries, entry, link); unlink_dbentries(acache, entry); if (entry->callback != NULL) { (entry->callback)(entry, &entry->cbarg); entry->callback = NULL; } ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write); if (acache->cleaner.current_entry != entry) dns_acache_detachentry(&entry); } } /* * The acache must be locked before calling. */ static void shutdown_buckets(dns_acache_t *acache) { int i; dbentry_t *dbent; REQUIRE(DNS_ACACHE_VALID(acache)); INSIST(acache->shutting_down); for (i = 0; i < DBBUCKETS; i++) { while ((dbent = ISC_LIST_HEAD(acache->dbbucket[i])) != NULL) { INSIST(ISC_LIST_EMPTY(dbent->originlist) && ISC_LIST_EMPTY(dbent->referlist)); ISC_LIST_UNLINK(acache->dbbucket[i], dbent, link); dns_db_detach(&dbent->db); isc_mem_put(acache->mctx, dbent, sizeof(*dbent)); acache->dbentries--; } } INSIST(acache->dbentries == 0); } static void shutdown_task(isc_task_t *task, isc_event_t *ev) { dns_acache_t *acache; UNUSED(task); acache = ev->ev_arg; INSIST(DNS_ACACHE_VALID(acache)); isc_event_free(&ev); LOCK(&acache->lock); shutdown_entries(acache); shutdown_buckets(acache); UNLOCK(&acache->lock); dns_acache_detach(&acache); } /* The acache and the entry must be locked before calling. */ static inline void unlink_dbentries(dns_acache_t *acache, dns_acacheentry_t *ent) { isc_result_t result; dbentry_t *dbent; if (ISC_LINK_LINKED(ent, olink)) { INSIST(ent->origdb != NULL); dbent = NULL; result = finddbent(acache, ent->origdb, &dbent); INSIST(result == ISC_R_SUCCESS); ISC_LIST_UNLINK(dbent->originlist, ent, olink); } if (ISC_LINK_LINKED(ent, rlink)) { INSIST(ent->db != NULL); dbent = NULL; result = finddbent(acache, ent->db, &dbent); INSIST(result == ISC_R_SUCCESS); ISC_LIST_UNLINK(dbent->referlist, ent, rlink); } } /* There must not be a reference to this entry. */ static void destroy_entry(dns_acacheentry_t *entry) { dns_acache_t *acache; REQUIRE(DNS_ACACHEENTRY_VALID(entry)); acache = entry->acache; REQUIRE(DNS_ACACHE_VALID(acache)); /* * Since there is no reference to this entry, it is safe to call * clear_entry() here. */ clear_entry(acache, entry); isc_mem_put(acache->mctx, entry, sizeof(*entry)); dns_acache_detach(&acache); } static void destroy(dns_acache_t *acache) { int i; REQUIRE(DNS_ACACHE_VALID(acache)); ATRACE("destroy"); isc_mem_setwater(acache->mctx, NULL, NULL, 0, 0); if (acache->cleaner.overmem_event != NULL) isc_event_free(&acache->cleaner.overmem_event); if (acache->cleaner.resched_event != NULL) isc_event_free(&acache->cleaner.resched_event); if (acache->task != NULL) isc_task_detach(&acache->task); for (i = 0; i < DEFAULT_ACACHE_ENTRY_LOCK_COUNT; i++) ACACHE_DESTROYLOCK(&acache->entrylocks[i]); isc_mem_put(acache->mctx, acache->entrylocks, sizeof(*acache->entrylocks) * DEFAULT_ACACHE_ENTRY_LOCK_COUNT); DESTROYLOCK(&acache->cleaner.lock); DESTROYLOCK(&acache->lock); acache->magic = 0; isc_mem_putanddetach(&acache->mctx, acache, sizeof(*acache)); } static inline isc_result_t finddbent(dns_acache_t *acache, dns_db_t *db, dbentry_t **dbentryp) { int bucket; dbentry_t *dbentry; REQUIRE(DNS_ACACHE_VALID(acache)); REQUIRE(db != NULL); REQUIRE(dbentryp != NULL && *dbentryp == NULL); /* * The caller must be holding the acache lock. */ bucket = isc_hash_calc((const unsigned char *)&db, sizeof(db), ISC_TRUE) % DBBUCKETS; for (dbentry = ISC_LIST_HEAD(acache->dbbucket[bucket]); dbentry != NULL; dbentry = ISC_LIST_NEXT(dbentry, link)) { if (dbentry->db == db) break; } *dbentryp = dbentry; if (dbentry == NULL) return (ISC_R_NOTFOUND); else return (ISC_R_SUCCESS); } static inline void clear_entry(dns_acache_t *acache, dns_acacheentry_t *entry) { REQUIRE(DNS_ACACHE_VALID(acache)); REQUIRE(DNS_ACACHEENTRY_VALID(entry)); /* * The caller must be holing the entry lock. */ if (entry->foundname) { dns_rdataset_t *rdataset, *rdataset_next; for (rdataset = ISC_LIST_HEAD(entry->foundname->list); rdataset != NULL; rdataset = rdataset_next) { rdataset_next = ISC_LIST_NEXT(rdataset, link); ISC_LIST_UNLINK(entry->foundname->list, rdataset, link); dns_rdataset_disassociate(rdataset); isc_mem_put(acache->mctx, rdataset, sizeof(*rdataset)); } if (dns_name_dynamic(entry->foundname)) dns_name_free(entry->foundname, acache->mctx); isc_mem_put(acache->mctx, entry->foundname, sizeof(*entry->foundname)); entry->foundname = NULL; } if (entry->node != NULL) { INSIST(entry->db != NULL); dns_db_detachnode(entry->db, &entry->node); } if (entry->version != NULL) { INSIST(entry->db != NULL); dns_db_closeversion(entry->db, &entry->version, ISC_FALSE); } if (entry->db != NULL) dns_db_detach(&entry->db); if (entry->zone != NULL) dns_zone_detach(&entry->zone); if (entry->origdb != NULL) dns_db_detach(&entry->origdb); } static isc_result_t acache_cleaner_init(dns_acache_t *acache, isc_timermgr_t *timermgr, acache_cleaner_t *cleaner) { int result; ATRACE("acache cleaner init"); result = isc_mutex_init(&cleaner->lock); if (result != ISC_R_SUCCESS) goto fail; cleaner->increment = DNS_ACACHE_CLEANERINCREMENT; cleaner->state = cleaner_s_idle; cleaner->acache = acache; cleaner->overmem = ISC_FALSE; cleaner->cleaning_timer = NULL; cleaner->resched_event = NULL; cleaner->overmem_event = NULL; cleaner->current_entry = NULL; if (timermgr != NULL) { cleaner->acache->live_cleaners++; result = isc_task_onshutdown(acache->task, acache_cleaner_shutdown_action, acache); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "acache cleaner: " "isc_task_onshutdown() failed: %s", dns_result_totext(result)); goto cleanup; } cleaner->cleaning_interval = 0; /* Initially turned off. */ isc_stdtime_get(&cleaner->last_cleanup_time); result = isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL, acache->task, acache_cleaning_timer_action, cleaner, &cleaner->cleaning_timer); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_timer_create() failed: %s", dns_result_totext(result)); result = ISC_R_UNEXPECTED; goto cleanup; } cleaner->resched_event = isc_event_allocate(acache->mctx, cleaner, DNS_EVENT_ACACHECLEAN, acache_incremental_cleaning_action, cleaner, sizeof(isc_event_t)); if (cleaner->resched_event == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } cleaner->overmem_event = isc_event_allocate(acache->mctx, cleaner, DNS_EVENT_ACACHEOVERMEM, acache_overmem_cleaning_action, cleaner, sizeof(isc_event_t)); if (cleaner->overmem_event == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } } return (ISC_R_SUCCESS); cleanup: if (cleaner->overmem_event != NULL) isc_event_free(&cleaner->overmem_event); if (cleaner->resched_event != NULL) isc_event_free(&cleaner->resched_event); if (cleaner->cleaning_timer != NULL) isc_timer_detach(&cleaner->cleaning_timer); cleaner->acache->live_cleaners--; DESTROYLOCK(&cleaner->lock); fail: return (result); } static void begin_cleaning(acache_cleaner_t *cleaner) { dns_acacheentry_t *head; dns_acache_t *acache = cleaner->acache; /* * This function does not have to lock the cleaner, since critical * parameters (except current_entry, which is locked by acache lock,) * are only used in a single task context. */ REQUIRE(CLEANER_IDLE(cleaner)); INSIST(DNS_ACACHE_VALID(acache)); INSIST(cleaner->current_entry == NULL); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE, ISC_LOG_DEBUG(1), "begin acache cleaning, mem inuse %lu", (unsigned long)isc_mem_inuse(cleaner->acache->mctx)); LOCK(&acache->lock); head = ISC_LIST_HEAD(acache->entries); if (head != NULL) dns_acache_attachentry(head, &cleaner->current_entry); UNLOCK(&acache->lock); if (cleaner->current_entry != NULL) { cleaner->ncleaned = 0; cleaner->state = cleaner_s_busy; isc_task_send(acache->task, &cleaner->resched_event); } return; } static void end_cleaning(acache_cleaner_t *cleaner, isc_event_t *event) { dns_acache_t *acache = cleaner->acache; REQUIRE(CLEANER_BUSY(cleaner)); REQUIRE(event != NULL); REQUIRE(DNS_ACACHEENTRY_VALID(cleaner->current_entry)); /* No need to lock the cleaner (see begin_cleaning()). */ LOCK(&acache->lock); /* * Even if the cleaner has the last reference to the entry, which means * the entry has been unused, it may still be linked if unlinking the * entry has been delayed due to the reference. */ if (isc_refcount_current(&cleaner->current_entry->references) == 1) { INSIST(cleaner->current_entry->callback == NULL); if (ISC_LINK_LINKED(cleaner->current_entry, link)) { ISC_LIST_UNLINK(acache->entries, cleaner->current_entry, link); } } dns_acache_detachentry(&cleaner->current_entry); if (cleaner->overmem) acache->stats.overmem++; acache->stats.cleaned += cleaner->ncleaned; acache->stats.cleaner_runs++; isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE, ISC_LOG_NOTICE, "acache %p stats: hits=%d misses=%d queries=%d " "adds=%d deleted=%d " "cleaned=%d cleaner_runs=%d overmem=%d " "overmem_nocreates=%d nomem=%d", acache, acache->stats.hits, acache->stats.misses, acache->stats.queries, acache->stats.adds, acache->stats.deleted, acache->stats.cleaned, acache->stats.cleaner_runs, acache->stats.overmem, acache->stats.overmem_nocreates, acache->stats.nomem); reset_stats(acache); isc_stdtime_get(&cleaner->last_cleanup_time); UNLOCK(&acache->lock); dns_acache_setcleaninginterval(cleaner->acache, cleaner->cleaning_interval); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE, ISC_LOG_DEBUG(1), "end acache cleaning, " "%lu entries cleaned, mem inuse %lu", cleaner->ncleaned, (unsigned long)isc_mem_inuse(cleaner->acache->mctx)); if (cleaner->overmem) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE, ISC_LOG_NOTICE, "acache is still in overmem state " "after cleaning"); } cleaner->ncleaned = 0; cleaner->state = cleaner_s_idle; cleaner->resched_event = event; } /* * This is run once for every acache-cleaning-interval as defined * in named.conf. */ static void acache_cleaning_timer_action(isc_task_t *task, isc_event_t *event) { acache_cleaner_t *cleaner = event->ev_arg; UNUSED(task); INSIST(event->ev_type == ISC_TIMEREVENT_TICK); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE, ISC_LOG_DEBUG(1), "acache cleaning timer fired, " "cleaner state = %d", cleaner->state); if (cleaner->state == cleaner_s_idle) begin_cleaning(cleaner); isc_event_free(&event); } /* The caller must hold entry lock. */ static inline isc_boolean_t entry_stale(acache_cleaner_t *cleaner, dns_acacheentry_t *entry, isc_stdtime32_t now32, unsigned int interval) { /* * If the callback has been canceled, we definitely do not need the * entry. */ if (entry->callback == NULL) return (ISC_TRUE); if (interval > cleaner->cleaning_interval) interval = cleaner->cleaning_interval; if (entry->lastused + interval < now32) return (ISC_TRUE); /* * If the acache is in the overmem state, probabilistically decide if * the entry should be purged, based on the time passed from its last * use and the cleaning interval. */ if (cleaner->overmem) { unsigned int passed; isc_uint32_t val; if (isc_serial_ge(now32, entry->lastused)) passed = now32 - entry->lastused; /* <= interval */ else passed = 0; if (passed > interval / 2) return (ISC_TRUE); isc_random_get(&val); if (passed > interval / 4) return (ISC_TF(val % 4 == 0)); return (ISC_TF(val % 8 == 0)); } return (ISC_FALSE); } /* * Do incremental cleaning. */ static void acache_incremental_cleaning_action(isc_task_t *task, isc_event_t *event) { acache_cleaner_t *cleaner = event->ev_arg; dns_acache_t *acache = cleaner->acache; dns_acacheentry_t *entry, *next = NULL; int n_entries; isc_stdtime32_t now32, last32; isc_stdtime_t now; unsigned int interval; INSIST(DNS_ACACHE_VALID(acache)); INSIST(task == acache->task); INSIST(event->ev_type == DNS_EVENT_ACACHECLEAN); if (cleaner->state == cleaner_s_done) { cleaner->state = cleaner_s_busy; end_cleaning(cleaner, event); return; } INSIST(CLEANER_BUSY(cleaner)); n_entries = cleaner->increment; isc_stdtime_get(&now); isc_stdtime_convert32(now, &now32); LOCK(&acache->lock); entry = cleaner->current_entry; isc_stdtime_convert32(cleaner->last_cleanup_time, &last32); if (isc_serial_ge(now32, last32)) interval = now32 - last32; else interval = 0; while (n_entries-- > 0) { isc_boolean_t is_stale = ISC_FALSE; INSIST(entry != NULL); next = ISC_LIST_NEXT(entry, link); ACACHE_LOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write); is_stale = entry_stale(cleaner, entry, now32, interval); if (is_stale) { ISC_LIST_UNLINK(acache->entries, entry, link); unlink_dbentries(acache, entry); if (entry->callback != NULL) (entry->callback)(entry, &entry->cbarg); entry->callback = NULL; cleaner->ncleaned++; } ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write); if (is_stale) dns_acache_detachentry(&entry); if (next == NULL) { if (cleaner->overmem) { entry = ISC_LIST_HEAD(acache->entries); if (entry != NULL) { /* * If we are still in the overmem * state, keep cleaning. In case we * exit from the loop immediately after * this, reset next to the head entry * as we'll expect it will be never * NULL. */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE, ISC_LOG_DEBUG(1), "acache cleaner: " "still overmem, " "reset and try again"); next = entry; continue; } } UNLOCK(&acache->lock); end_cleaning(cleaner, event); return; } entry = next; } /* * We have successfully performed a cleaning increment but have * not gone through the entire cache. Remember the entry that will * be the starting point in the next clean-up, and reschedule another * batch. If it fails, just try to continue anyway. */ INSIST(next != NULL); dns_acache_detachentry(&cleaner->current_entry); dns_acache_attachentry(next, &cleaner->current_entry); UNLOCK(&acache->lock); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE, ISC_LOG_DEBUG(1), "acache cleaner: checked %d entries, " "mem inuse %lu, sleeping", cleaner->increment, (unsigned long)isc_mem_inuse(cleaner->acache->mctx)); isc_task_send(task, &event); INSIST(CLEANER_BUSY(cleaner)); return; } /* * This is called when the acache either surpasses its upper limit * or shrinks beyond its lower limit. */ static void acache_overmem_cleaning_action(isc_task_t *task, isc_event_t *event) { acache_cleaner_t *cleaner = event->ev_arg; isc_boolean_t want_cleaning = ISC_FALSE; UNUSED(task); INSIST(event->ev_type == DNS_EVENT_ACACHEOVERMEM); INSIST(cleaner->overmem_event == NULL); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE, ISC_LOG_DEBUG(1), "overmem_cleaning_action called, " "overmem = %d, state = %d", cleaner->overmem, cleaner->state); LOCK(&cleaner->lock); if (cleaner->overmem) { if (cleaner->state == cleaner_s_idle) want_cleaning = ISC_TRUE; } else { if (cleaner->state == cleaner_s_busy) /* * end_cleaning() can't be called here because * then both cleaner->overmem_event and * cleaner->resched_event will point to this * event. Set the state to done, and then * when the acache_incremental_cleaning_action() event * is posted, it will handle the end_cleaning. */ cleaner->state = cleaner_s_done; } cleaner->overmem_event = event; UNLOCK(&cleaner->lock); if (want_cleaning) begin_cleaning(cleaner); } static void water(void *arg, int mark) { dns_acache_t *acache = arg; isc_boolean_t overmem = ISC_TF(mark == ISC_MEM_HIWATER); REQUIRE(DNS_ACACHE_VALID(acache)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE, ISC_LOG_DEBUG(1), "acache memory reaches %s watermark, mem inuse %lu", overmem ? "high" : "low", (unsigned long)isc_mem_inuse(acache->mctx)); LOCK(&acache->cleaner.lock); if (acache->cleaner.overmem != overmem) { acache->cleaner.overmem = overmem; if (acache->cleaner.overmem_event != NULL) isc_task_send(acache->task, &acache->cleaner.overmem_event); isc_mem_waterack(acache->mctx, mark); } UNLOCK(&acache->cleaner.lock); } /* * The cleaner task is shutting down; do the necessary cleanup. */ static void acache_cleaner_shutdown_action(isc_task_t *task, isc_event_t *event) { dns_acache_t *acache = event->ev_arg; isc_boolean_t should_free = ISC_FALSE; INSIST(task == acache->task); INSIST(event->ev_type == ISC_TASKEVENT_SHUTDOWN); INSIST(DNS_ACACHE_VALID(acache)); ATRACE("acache cleaner shutdown"); if (CLEANER_BUSY(&acache->cleaner)) end_cleaning(&acache->cleaner, event); else isc_event_free(&event); LOCK(&acache->lock); acache->live_cleaners--; INSIST(acache->live_cleaners == 0); if (isc_refcount_current(&acache->refs) == 0) { INSIST(check_noentry(acache) == ISC_TRUE); should_free = ISC_TRUE; } /* * By detaching the timer in the context of its task, * we are guaranteed that there will be no further timer * events. */ if (acache->cleaner.cleaning_timer != NULL) isc_timer_detach(&acache->cleaner.cleaning_timer); /* Make sure we don't reschedule anymore. */ (void)isc_task_purge(task, NULL, DNS_EVENT_ACACHECLEAN, NULL); UNLOCK(&acache->lock); if (should_free) destroy(acache); } /* * Public functions. */ isc_result_t dns_acache_create(dns_acache_t **acachep, isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr) { int i; isc_result_t result; dns_acache_t *acache; REQUIRE(acachep != NULL && *acachep == NULL); REQUIRE(mctx != NULL); REQUIRE(taskmgr != NULL); acache = isc_mem_get(mctx, sizeof(*acache)); if (acache == NULL) return (ISC_R_NOMEMORY); ATRACE("create"); result = isc_refcount_init(&acache->refs, 1); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, acache, sizeof(*acache)); return (result); } result = isc_mutex_init(&acache->lock); if (result != ISC_R_SUCCESS) { isc_refcount_decrement(&acache->refs, NULL); isc_refcount_destroy(&acache->refs); isc_mem_put(mctx, acache, sizeof(*acache)); return (result); } acache->mctx = NULL; isc_mem_attach(mctx, &acache->mctx); ISC_LIST_INIT(acache->entries); acache->shutting_down = ISC_FALSE; acache->task = NULL; acache->entrylocks = NULL; result = isc_task_create(taskmgr, 1, &acache->task); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_task_create() failed(): %s", dns_result_totext(result)); result = ISC_R_UNEXPECTED; goto cleanup; } isc_task_setname(acache->task, "acachetask", acache); ISC_EVENT_INIT(&acache->cevent, sizeof(acache->cevent), 0, NULL, DNS_EVENT_ACACHECONTROL, shutdown_task, NULL, NULL, NULL, NULL); acache->cevent_sent = ISC_FALSE; acache->dbentries = 0; for (i = 0; i < DBBUCKETS; i++) ISC_LIST_INIT(acache->dbbucket[i]); acache->entrylocks = isc_mem_get(mctx, sizeof(*acache->entrylocks) * DEFAULT_ACACHE_ENTRY_LOCK_COUNT); if (acache->entrylocks == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } for (i = 0; i < DEFAULT_ACACHE_ENTRY_LOCK_COUNT; i++) { result = ACACHE_INITLOCK(&acache->entrylocks[i]); if (result != ISC_R_SUCCESS) { while (i-- > 0) ACACHE_DESTROYLOCK(&acache->entrylocks[i]); isc_mem_put(mctx, acache->entrylocks, sizeof(*acache->entrylocks) * DEFAULT_ACACHE_ENTRY_LOCK_COUNT); acache->entrylocks = NULL; goto cleanup; } } acache->live_cleaners = 0; result = acache_cleaner_init(acache, timermgr, &acache->cleaner); if (result != ISC_R_SUCCESS) goto cleanup; acache->stats.cleaner_runs = 0; reset_stats(acache); acache->magic = ACACHE_MAGIC; *acachep = acache; return (ISC_R_SUCCESS); cleanup: if (acache->task != NULL) isc_task_detach(&acache->task); DESTROYLOCK(&acache->lock); isc_refcount_decrement(&acache->refs, NULL); isc_refcount_destroy(&acache->refs); if (acache->entrylocks != NULL) { for (i = 0; i < DEFAULT_ACACHE_ENTRY_LOCK_COUNT; i++) ACACHE_DESTROYLOCK(&acache->entrylocks[i]); isc_mem_put(mctx, acache->entrylocks, sizeof(*acache->entrylocks) * DEFAULT_ACACHE_ENTRY_LOCK_COUNT); } isc_mem_put(mctx, acache, sizeof(*acache)); isc_mem_detach(&mctx); return (result); } void dns_acache_attach(dns_acache_t *source, dns_acache_t **targetp) { REQUIRE(DNS_ACACHE_VALID(source)); REQUIRE(targetp != NULL && *targetp == NULL); AATRACE(source, "attach"); isc_refcount_increment(&source->refs, NULL); *targetp = source; } void dns_acache_countquerymiss(dns_acache_t *acache) { acache->stats.misses++; /* XXXSK danger: unlocked! */ acache->stats.queries++; /* XXXSK danger: unlocked! */ } void dns_acache_detach(dns_acache_t **acachep) { dns_acache_t *acache; unsigned int refs; isc_boolean_t should_free = ISC_FALSE; REQUIRE(acachep != NULL && DNS_ACACHE_VALID(*acachep)); acache = *acachep; ATRACE("detach"); isc_refcount_decrement(&acache->refs, &refs); if (refs == 0) { INSIST(check_noentry(acache) == ISC_TRUE); should_free = ISC_TRUE; } *acachep = NULL; /* * If we're exiting and the cleaner task exists, let it free the cache. */ if (should_free && acache->live_cleaners > 0) { isc_task_shutdown(acache->task); should_free = ISC_FALSE; } if (should_free) destroy(acache); } void dns_acache_shutdown(dns_acache_t *acache) { REQUIRE(DNS_ACACHE_VALID(acache)); LOCK(&acache->lock); ATRACE("shutdown"); if (!acache->shutting_down) { isc_event_t *event; dns_acache_t *acache_evarg = NULL; INSIST(!acache->cevent_sent); acache->shutting_down = ISC_TRUE; isc_mem_setwater(acache->mctx, NULL, NULL, 0, 0); /* * Self attach the object in order to prevent it from being * destroyed while waiting for the event. */ dns_acache_attach(acache, &acache_evarg); event = &acache->cevent; event->ev_arg = acache_evarg; isc_task_send(acache->task, &event); acache->cevent_sent = ISC_TRUE; } UNLOCK(&acache->lock); } isc_result_t dns_acache_setdb(dns_acache_t *acache, dns_db_t *db) { int bucket; dbentry_t *dbentry; isc_result_t result = ISC_R_SUCCESS; REQUIRE(DNS_ACACHE_VALID(acache)); REQUIRE(db != NULL); ATRACE("setdb"); LOCK(&acache->lock); dbentry = NULL; result = finddbent(acache, db, &dbentry); if (result == ISC_R_SUCCESS) { result = ISC_R_EXISTS; goto end; } result = ISC_R_SUCCESS; dbentry = isc_mem_get(acache->mctx, sizeof(*dbentry)); if (dbentry == NULL) { result = ISC_R_NOMEMORY; goto end; } ISC_LINK_INIT(dbentry, link); ISC_LIST_INIT(dbentry->originlist); ISC_LIST_INIT(dbentry->referlist); dbentry->db = NULL; dns_db_attach(db, &dbentry->db); bucket = isc_hash_calc((const unsigned char *)&db, sizeof(db), ISC_TRUE) % DBBUCKETS; ISC_LIST_APPEND(acache->dbbucket[bucket], dbentry, link); acache->dbentries++; end: UNLOCK(&acache->lock); return (result); } isc_result_t dns_acache_putdb(dns_acache_t *acache, dns_db_t *db) { int bucket; isc_result_t result; dbentry_t *dbentry; dns_acacheentry_t *entry; REQUIRE(DNS_ACACHE_VALID(acache)); REQUIRE(db != NULL); ATRACE("putdb"); LOCK(&acache->lock); dbentry = NULL; result = finddbent(acache, db, &dbentry); if (result != ISC_R_SUCCESS) { /* * The entry may have not been created due to memory shortage. */ UNLOCK(&acache->lock); return (ISC_R_NOTFOUND); } /* * Release corresponding cache entries: for each entry, release all * links the entry has, and then callback to the entry holder (if any). * If no other external references exist (this can happen if the * original holder has canceled callback,) destroy it here. */ while ((entry = ISC_LIST_HEAD(dbentry->originlist)) != NULL) { ACACHE_LOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write); /* * Releasing olink first would avoid finddbent() in * unlink_dbentries(). */ ISC_LIST_UNLINK(dbentry->originlist, entry, olink); if (acache->cleaner.current_entry != entry) ISC_LIST_UNLINK(acache->entries, entry, link); unlink_dbentries(acache, entry); if (entry->callback != NULL) (entry->callback)(entry, &entry->cbarg); entry->callback = NULL; ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write); if (acache->cleaner.current_entry != entry) dns_acache_detachentry(&entry); } while ((entry = ISC_LIST_HEAD(dbentry->referlist)) != NULL) { ACACHE_LOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write); ISC_LIST_UNLINK(dbentry->referlist, entry, rlink); if (acache->cleaner.current_entry != entry) ISC_LIST_UNLINK(acache->entries, entry, link); unlink_dbentries(acache, entry); if (entry->callback != NULL) (entry->callback)(entry, &entry->cbarg); entry->callback = NULL; ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write); if (acache->cleaner.current_entry != entry) dns_acache_detachentry(&entry); } INSIST(ISC_LIST_EMPTY(dbentry->originlist) && ISC_LIST_EMPTY(dbentry->referlist)); bucket = isc_hash_calc((const unsigned char *)&db, sizeof(db), ISC_TRUE) % DBBUCKETS; ISC_LIST_UNLINK(acache->dbbucket[bucket], dbentry, link); dns_db_detach(&dbentry->db); isc_mem_put(acache->mctx, dbentry, sizeof(*dbentry)); acache->dbentries--; acache->stats.deleted++; UNLOCK(&acache->lock); return (ISC_R_SUCCESS); } isc_result_t dns_acache_createentry(dns_acache_t *acache, dns_db_t *origdb, void (*callback)(dns_acacheentry_t *, void **), void *cbarg, dns_acacheentry_t **entryp) { dns_acacheentry_t *newentry; isc_result_t result; isc_uint32_t r; REQUIRE(DNS_ACACHE_VALID(acache)); REQUIRE(entryp != NULL && *entryp == NULL); REQUIRE(origdb != NULL); /* * Should we exceed our memory limit for some reason (for * example, if the cleaner does not run aggressively enough), * then we will not create additional entries. * * XXXSK: It might be better to lock the acache->cleaner->lock, * but locking may be an expensive bottleneck. If we misread * the value, we will occasionally refuse to create a few * cache entries, or create a few that we should not. I do not * expect this to happen often, and it will not have very bad * effects when it does. So no lock for now. */ if (acache->cleaner.overmem) { acache->stats.overmem_nocreates++; /* XXXSK danger: unlocked! */ return (ISC_R_NORESOURCES); } newentry = isc_mem_get(acache->mctx, sizeof(*newentry)); if (newentry == NULL) { acache->stats.nomem++; /* XXXMLG danger: unlocked! */ return (ISC_R_NOMEMORY); } isc_random_get(&r); newentry->locknum = r % DEFAULT_ACACHE_ENTRY_LOCK_COUNT; result = isc_refcount_init(&newentry->references, 1); if (result != ISC_R_SUCCESS) { isc_mem_put(acache->mctx, newentry, sizeof(*newentry)); return (result); }; ISC_LINK_INIT(newentry, link); ISC_LINK_INIT(newentry, olink); ISC_LINK_INIT(newentry, rlink); newentry->acache = NULL; dns_acache_attach(acache, &newentry->acache); newentry->zone = NULL; newentry->db = NULL; newentry->version = NULL; newentry->node = NULL; newentry->foundname = NULL; newentry->callback = callback; newentry->cbarg = cbarg; newentry->origdb = NULL; dns_db_attach(origdb, &newentry->origdb); isc_stdtime_get(&newentry->lastused); newentry->magic = ACACHEENTRY_MAGIC; *entryp = newentry; return (ISC_R_SUCCESS); } isc_result_t dns_acache_getentry(dns_acacheentry_t *entry, dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp, dns_dbnode_t **nodep, dns_name_t *fname, dns_message_t *msg, isc_stdtime_t now) { isc_result_t result = ISC_R_SUCCESS; dns_rdataset_t *erdataset; isc_stdtime32_t now32; dns_acache_t *acache; int locknum; REQUIRE(DNS_ACACHEENTRY_VALID(entry)); REQUIRE(zonep == NULL || *zonep == NULL); REQUIRE(dbp != NULL && *dbp == NULL); REQUIRE(versionp != NULL && *versionp == NULL); REQUIRE(nodep != NULL && *nodep == NULL); REQUIRE(fname != NULL); REQUIRE(msg != NULL); acache = entry->acache; REQUIRE(DNS_ACACHE_VALID(acache)); locknum = entry->locknum; ACACHE_LOCK(&acache->entrylocks[locknum], isc_rwlocktype_read); isc_stdtime_convert32(now, &now32); acache_storetime(entry, now32); if (entry->zone != NULL && zonep != NULL) dns_zone_attach(entry->zone, zonep); if (entry->db == NULL) { *dbp = NULL; *versionp = NULL; } else { dns_db_attach(entry->db, dbp); dns_db_attachversion(entry->db, entry->version, versionp); } if (entry->node == NULL) *nodep = NULL; else { dns_db_attachnode(entry->db, entry->node, nodep); INSIST(entry->foundname != NULL); dns_name_copy(entry->foundname, fname, NULL); for (erdataset = ISC_LIST_HEAD(entry->foundname->list); erdataset != NULL; erdataset = ISC_LIST_NEXT(erdataset, link)) { dns_rdataset_t *ardataset; ardataset = NULL; result = dns_message_gettemprdataset(msg, &ardataset); if (result != ISC_R_SUCCESS) { ACACHE_UNLOCK(&acache->entrylocks[locknum], isc_rwlocktype_read); goto fail; } /* * XXXJT: if we simply clone the rdataset, we'll get * lost wrt cyclic ordering. We'll need an additional * trick to get the latest counter from the original * header. */ dns_rdataset_clone(erdataset, ardataset); ISC_LIST_APPEND(fname->list, ardataset, link); } } entry->acache->stats.hits++; /* XXXMLG danger: unlocked! */ entry->acache->stats.queries++; ACACHE_UNLOCK(&acache->entrylocks[locknum], isc_rwlocktype_read); return (result); fail: while ((erdataset = ISC_LIST_HEAD(fname->list)) != NULL) { ISC_LIST_UNLINK(fname->list, erdataset, link); dns_rdataset_disassociate(erdataset); dns_message_puttemprdataset(msg, &erdataset); } if (*nodep != NULL) dns_db_detachnode(*dbp, nodep); if (*versionp != NULL) dns_db_closeversion(*dbp, versionp, ISC_FALSE); if (*dbp != NULL) dns_db_detach(dbp); if (zonep != NULL && *zonep != NULL) dns_zone_detach(zonep); return (result); } isc_result_t dns_acache_setentry(dns_acache_t *acache, dns_acacheentry_t *entry, dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, dns_name_t *fname) { isc_result_t result; dbentry_t *odbent; dbentry_t *rdbent = NULL; isc_boolean_t close_version = ISC_FALSE; dns_acacheentry_t *dummy_entry = NULL; REQUIRE(DNS_ACACHE_VALID(acache)); REQUIRE(DNS_ACACHEENTRY_VALID(entry)); LOCK(&acache->lock); /* XXX: need to lock it here for ordering */ ACACHE_LOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write); /* Set zone */ if (zone != NULL) dns_zone_attach(zone, &entry->zone); /* Set DB */ if (db != NULL) dns_db_attach(db, &entry->db); /* * Set DB version. If the version is not given by the caller, * which is the case for glue or cache DBs, use the current version. */ if (version == NULL) { if (db != NULL) { dns_db_currentversion(db, &version); close_version = ISC_TRUE; } } if (version != NULL) { INSIST(db != NULL); dns_db_attachversion(db, version, &entry->version); } if (close_version) dns_db_closeversion(db, &version, ISC_FALSE); /* Set DB node. */ if (node != NULL) { INSIST(db != NULL); dns_db_attachnode(db, node, &entry->node); } /* * Set list of the corresponding rdatasets, if given. * To minimize the overhead and memory consumption, we'll do this for * positive cache only, in which case the DB node is non NULL. * We do not want to cache incomplete information, so give up the * entire entry when a memory shortage happen during the process. */ if (node != NULL) { dns_rdataset_t *ardataset, *crdataset; entry->foundname = isc_mem_get(acache->mctx, sizeof(*entry->foundname)); if (entry->foundname == NULL) { result = ISC_R_NOMEMORY; goto fail; } dns_name_init(entry->foundname, NULL); result = dns_name_dup(fname, acache->mctx, entry->foundname); if (result != ISC_R_SUCCESS) goto fail; for (ardataset = ISC_LIST_HEAD(fname->list); ardataset != NULL; ardataset = ISC_LIST_NEXT(ardataset, link)) { crdataset = isc_mem_get(acache->mctx, sizeof(*crdataset)); if (crdataset == NULL) { result = ISC_R_NOMEMORY; goto fail; } dns_rdataset_init(crdataset); dns_rdataset_clone(ardataset, crdataset); ISC_LIST_APPEND(entry->foundname->list, crdataset, link); } } odbent = NULL; result = finddbent(acache, entry->origdb, &odbent); if (result != ISC_R_SUCCESS) goto fail; if (db != NULL) { rdbent = NULL; result = finddbent(acache, db, &rdbent); if (result != ISC_R_SUCCESS) goto fail; } ISC_LIST_APPEND(acache->entries, entry, link); ISC_LIST_APPEND(odbent->originlist, entry, olink); if (rdbent != NULL) ISC_LIST_APPEND(rdbent->referlist, entry, rlink); /* * The additional cache needs an implicit reference to entries in its * link. */ dns_acache_attachentry(entry, &dummy_entry); ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write); acache->stats.adds++; UNLOCK(&acache->lock); return (ISC_R_SUCCESS); fail: clear_entry(acache, entry); ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write); UNLOCK(&acache->lock); return (result); } isc_boolean_t dns_acache_cancelentry(dns_acacheentry_t *entry) { dns_acache_t *acache; isc_boolean_t callback_active; REQUIRE(DNS_ACACHEENTRY_VALID(entry)); acache = entry->acache; INSIST(DNS_ACACHE_VALID(entry->acache)); LOCK(&acache->lock); ACACHE_LOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write); callback_active = ISC_TF(entry->cbarg != NULL); /* * Release dependencies stored in this entry as much as possible. * The main link cannot be released, since the acache object has * a reference to this entry; the empty entry will be released in * the next cleaning action. */ unlink_dbentries(acache, entry); clear_entry(entry->acache, entry); entry->callback = NULL; entry->cbarg = NULL; ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write); UNLOCK(&acache->lock); return (callback_active); } void dns_acache_attachentry(dns_acacheentry_t *source, dns_acacheentry_t **targetp) { REQUIRE(DNS_ACACHEENTRY_VALID(source)); REQUIRE(targetp != NULL && *targetp == NULL); isc_refcount_increment(&source->references, NULL); *targetp = source; } void dns_acache_detachentry(dns_acacheentry_t **entryp) { dns_acacheentry_t *entry; unsigned int refs; REQUIRE(entryp != NULL && DNS_ACACHEENTRY_VALID(*entryp)); entry = *entryp; isc_refcount_decrement(&entry->references, &refs); /* * If there are no references to the entry, the entry must have been * unlinked and can be destroyed safely. */ if (refs == 0) { INSIST(!ISC_LINK_LINKED(entry, link)); (*entryp)->acache->stats.deleted++; destroy_entry(entry); } *entryp = NULL; } void dns_acache_setcleaninginterval(dns_acache_t *acache, unsigned int t) { isc_interval_t interval; isc_result_t result; REQUIRE(DNS_ACACHE_VALID(acache)); ATRACE("dns_acache_setcleaninginterval"); LOCK(&acache->lock); /* * It may be the case that the acache has already shut down. * If so, it has no timer. (Not sure if this can really happen.) */ if (acache->cleaner.cleaning_timer == NULL) goto unlock; acache->cleaner.cleaning_interval = t; if (t == 0) { result = isc_timer_reset(acache->cleaner.cleaning_timer, isc_timertype_inactive, NULL, NULL, ISC_TRUE); } else { isc_interval_set(&interval, acache->cleaner.cleaning_interval, 0); result = isc_timer_reset(acache->cleaner.cleaning_timer, isc_timertype_ticker, NULL, &interval, ISC_FALSE); } if (result != ISC_R_SUCCESS) isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE, ISC_LOG_WARNING, "could not set acache cleaning interval: %s", isc_result_totext(result)); else isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE, ISC_LOG_NOTICE, "acache %p cleaning interval set to %d.", acache, t); unlock: UNLOCK(&acache->lock); } /* * This function was derived from cache.c:dns_cache_setcachesize(). See the * function for more details about the logic. */ void dns_acache_setcachesize(dns_acache_t *acache, size_t size) { size_t hiwater, lowater; REQUIRE(DNS_ACACHE_VALID(acache)); if (size != 0U && size < DNS_ACACHE_MINSIZE) size = DNS_ACACHE_MINSIZE; hiwater = size - (size >> 3); lowater = size - (size >> 2); if (size == 0U || hiwater == 0U || lowater == 0U) isc_mem_setwater(acache->mctx, water, acache, 0, 0); else isc_mem_setwater(acache->mctx, water, acache, hiwater, lowater); } bind9-9.10.3.dfsg.P4/lib/dns/pkcs11rsa_link.c0000644000470500017500000012372512664710322017726 0ustar lamontlamont/* * Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifdef PKCS11CRYPTO #include #include #include #include #include #include #include #include #include #include "dst_internal.h" #include "dst_parse.h" #include "dst_pkcs11.h" #include /* * Limit the size of public exponents. */ #ifndef RSA_MAX_PUBEXP_BITS #define RSA_MAX_PUBEXP_BITS 35 #endif #define DST_RET(a) {ret = a; goto err;} static CK_BBOOL truevalue = TRUE; static CK_BBOOL falsevalue = FALSE; static isc_result_t pkcs11rsa_todns(const dst_key_t *key, isc_buffer_t *data); static void pkcs11rsa_destroy(dst_key_t *key); static isc_result_t pkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label, dst_key_t *pub); static isc_result_t pkcs11rsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) { CK_RV rv; CK_MECHANISM mech = { 0, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; CK_KEY_TYPE keyType = CKK_RSA; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_MODULUS, NULL, 0 }, { CKA_PUBLIC_EXPONENT, NULL, 0 }, { CKA_PRIVATE_EXPONENT, NULL, 0 }, { CKA_PRIME_1, NULL, 0 }, { CKA_PRIME_2, NULL, 0 }, { CKA_EXPONENT_1, NULL, 0 }, { CKA_EXPONENT_2, NULL, 0 }, { CKA_COEFFICIENT, NULL, 0 } }; CK_ATTRIBUTE *attr; CK_SLOT_ID slotid; pk11_object_t *rsa; pk11_context_t *pk11_ctx; isc_result_t ret; unsigned int i; REQUIRE(key->key_alg == DST_ALG_RSAMD5 || key->key_alg == DST_ALG_RSASHA1 || key->key_alg == DST_ALG_NSEC3RSASHA1 || key->key_alg == DST_ALG_RSASHA256 || key->key_alg == DST_ALG_RSASHA512); rsa = key->keydata.pkey; pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); if (rsa->ontoken) slotid = rsa->slot; else slotid = pk11_get_best_token(OP_RSA); ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE, rsa->reqlogon, NULL, slotid); if (ret != ISC_R_SUCCESS) goto err; if (rsa->ontoken && (rsa->object != CK_INVALID_HANDLE)) { pk11_ctx->ontoken = rsa->ontoken; pk11_ctx->object = rsa->object; goto token_key; } for (attr = pk11_attribute_first(rsa); attr != NULL; attr = pk11_attribute_next(rsa, attr)) switch (attr->type) { case CKA_MODULUS: INSIST(keyTemplate[6].type == attr->type); keyTemplate[6].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[6].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[6].pValue, attr->pValue, attr->ulValueLen); keyTemplate[6].ulValueLen = attr->ulValueLen; break; case CKA_PUBLIC_EXPONENT: INSIST(keyTemplate[7].type == attr->type); keyTemplate[7].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[7].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[7].pValue, attr->pValue, attr->ulValueLen); keyTemplate[7].ulValueLen = attr->ulValueLen; break; case CKA_PRIVATE_EXPONENT: INSIST(keyTemplate[8].type == attr->type); keyTemplate[8].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[8].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[8].pValue, attr->pValue, attr->ulValueLen); keyTemplate[8].ulValueLen = attr->ulValueLen; break; case CKA_PRIME_1: INSIST(keyTemplate[9].type == attr->type); keyTemplate[9].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[9].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[9].pValue, attr->pValue, attr->ulValueLen); keyTemplate[9].ulValueLen = attr->ulValueLen; break; case CKA_PRIME_2: INSIST(keyTemplate[10].type == attr->type); keyTemplate[10].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[10].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[10].pValue, attr->pValue, attr->ulValueLen); keyTemplate[10].ulValueLen = attr->ulValueLen; break; case CKA_EXPONENT_1: INSIST(keyTemplate[11].type == attr->type); keyTemplate[11].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[11].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[11].pValue, attr->pValue, attr->ulValueLen); keyTemplate[11].ulValueLen = attr->ulValueLen; break; case CKA_EXPONENT_2: INSIST(keyTemplate[12].type == attr->type); keyTemplate[12].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[12].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[12].pValue, attr->pValue, attr->ulValueLen); keyTemplate[12].ulValueLen = attr->ulValueLen; break; case CKA_COEFFICIENT: INSIST(keyTemplate[13].type == attr->type); keyTemplate[13].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[13].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[13].pValue, attr->pValue, attr->ulValueLen); keyTemplate[13].ulValueLen = attr->ulValueLen; break; } pk11_ctx->object = CK_INVALID_HANDLE; pk11_ctx->ontoken = ISC_FALSE; PK11_RET(pkcs_C_CreateObject, (pk11_ctx->session, keyTemplate, (CK_ULONG) 14, &pk11_ctx->object), ISC_R_FAILURE); token_key: switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: mech.mechanism = CKM_MD5_RSA_PKCS; break; case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: mech.mechanism = CKM_SHA1_RSA_PKCS; break; case DST_ALG_RSASHA256: mech.mechanism = CKM_SHA256_RSA_PKCS; break; case DST_ALG_RSASHA512: mech.mechanism = CKM_SHA512_RSA_PKCS; break; default: INSIST(0); } PK11_RET(pkcs_C_SignInit, (pk11_ctx->session, &mech, pk11_ctx->object), ISC_R_FAILURE); dctx->ctxdata.pk11_ctx = pk11_ctx; for (i = 6; i <= 13; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } return (ISC_R_SUCCESS); err: if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); for (i = 6; i <= 13; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); } static isc_result_t pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits, dst_context_t *dctx) { CK_RV rv; CK_MECHANISM mech = { 0, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; CK_KEY_TYPE keyType = CKK_RSA; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_MODULUS, NULL, 0 }, { CKA_PUBLIC_EXPONENT, NULL, 0 }, }; CK_ATTRIBUTE *attr; pk11_object_t *rsa; pk11_context_t *pk11_ctx; isc_result_t ret; unsigned int i; REQUIRE(key->key_alg == DST_ALG_RSAMD5 || key->key_alg == DST_ALG_RSASHA1 || key->key_alg == DST_ALG_NSEC3RSASHA1 || key->key_alg == DST_ALG_RSASHA256 || key->key_alg == DST_ALG_RSASHA512); rsa = key->keydata.pkey; pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE, rsa->reqlogon, NULL, pk11_get_best_token(OP_RSA)); if (ret != ISC_R_SUCCESS) goto err; for (attr = pk11_attribute_first(rsa); attr != NULL; attr = pk11_attribute_next(rsa, attr)) switch (attr->type) { case CKA_MODULUS: INSIST(keyTemplate[5].type == attr->type); keyTemplate[5].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[5].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[5].pValue, attr->pValue, attr->ulValueLen); keyTemplate[5].ulValueLen = attr->ulValueLen; break; case CKA_PUBLIC_EXPONENT: INSIST(keyTemplate[6].type == attr->type); keyTemplate[6].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[6].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[6].pValue, attr->pValue, attr->ulValueLen); keyTemplate[6].ulValueLen = attr->ulValueLen; if (pk11_numbits(attr->pValue, attr->ulValueLen) > maxbits && maxbits != 0) DST_RET(DST_R_VERIFYFAILURE); break; } pk11_ctx->object = CK_INVALID_HANDLE; pk11_ctx->ontoken = ISC_FALSE; PK11_RET(pkcs_C_CreateObject, (pk11_ctx->session, keyTemplate, (CK_ULONG) 7, &pk11_ctx->object), ISC_R_FAILURE); switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: mech.mechanism = CKM_MD5_RSA_PKCS; break; case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: mech.mechanism = CKM_SHA1_RSA_PKCS; break; case DST_ALG_RSASHA256: mech.mechanism = CKM_SHA256_RSA_PKCS; break; case DST_ALG_RSASHA512: mech.mechanism = CKM_SHA512_RSA_PKCS; break; default: INSIST(0); } PK11_RET(pkcs_C_VerifyInit, (pk11_ctx->session, &mech, pk11_ctx->object), ISC_R_FAILURE); dctx->ctxdata.pk11_ctx = pk11_ctx; for (i = 5; i <= 6; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } return (ISC_R_SUCCESS); err: if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); for (i = 5; i <= 6; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); } static isc_result_t pkcs11rsa_createctx(dst_key_t *key, dst_context_t *dctx) { if (dctx->use == DO_SIGN) return (pkcs11rsa_createctx_sign(key, dctx)); else return (pkcs11rsa_createctx_verify(key, 0U, dctx)); } static isc_result_t pkcs11rsa_createctx2(dst_key_t *key, int maxbits, dst_context_t *dctx) { if (dctx->use == DO_SIGN) return (pkcs11rsa_createctx_sign(key, dctx)); else return (pkcs11rsa_createctx_verify(key, (unsigned) maxbits, dctx)); } static void pkcs11rsa_destroyctx(dst_context_t *dctx) { pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; if (pk11_ctx != NULL) { if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); dctx->ctxdata.pk11_ctx = NULL; } } static isc_result_t pkcs11rsa_adddata(dst_context_t *dctx, const isc_region_t *data) { CK_RV rv; pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; isc_result_t ret = ISC_R_SUCCESS; if (dctx->use == DO_SIGN) PK11_CALL(pkcs_C_SignUpdate, (pk11_ctx->session, (CK_BYTE_PTR) data->base, (CK_ULONG) data->length), ISC_R_FAILURE); else PK11_CALL(pkcs_C_VerifyUpdate, (pk11_ctx->session, (CK_BYTE_PTR) data->base, (CK_ULONG) data->length), ISC_R_FAILURE); return (ret); } static isc_result_t pkcs11rsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { CK_RV rv; CK_ULONG siglen = 0; isc_region_t r; pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; isc_result_t ret = ISC_R_SUCCESS; PK11_RET(pkcs_C_SignFinal, (pk11_ctx->session, NULL, &siglen), DST_R_SIGNFAILURE); isc_buffer_availableregion(sig, &r); if (r.length < (unsigned int) siglen) return (ISC_R_NOSPACE); PK11_RET(pkcs_C_SignFinal, (pk11_ctx->session, (CK_BYTE_PTR) r.base, &siglen), DST_R_SIGNFAILURE); isc_buffer_add(sig, (unsigned int) siglen); err: return (ret); } static isc_result_t pkcs11rsa_verify(dst_context_t *dctx, const isc_region_t *sig) { CK_RV rv; pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; isc_result_t ret = ISC_R_SUCCESS; PK11_CALL(pkcs_C_VerifyFinal, (pk11_ctx->session, (CK_BYTE_PTR) sig->base, (CK_ULONG) sig->length), DST_R_VERIFYFAILURE); return (ret); } static isc_boolean_t pkcs11rsa_compare(const dst_key_t *key1, const dst_key_t *key2) { pk11_object_t *rsa1, *rsa2; CK_ATTRIBUTE *attr1, *attr2; rsa1 = key1->keydata.pkey; rsa2 = key2->keydata.pkey; if ((rsa1 == NULL) && (rsa2 == NULL)) return (ISC_TRUE); else if ((rsa1 == NULL) || (rsa2 == NULL)) return (ISC_FALSE); attr1 = pk11_attribute_bytype(rsa1, CKA_MODULUS); attr2 = pk11_attribute_bytype(rsa2, CKA_MODULUS); if ((attr1 == NULL) && (attr2 == NULL)) return (ISC_TRUE); else if ((attr1 == NULL) || (attr2 == NULL) || (attr1->ulValueLen != attr2->ulValueLen) || !isc_safe_memequal(attr1->pValue, attr2->pValue, attr1->ulValueLen)) return (ISC_FALSE); attr1 = pk11_attribute_bytype(rsa1, CKA_PUBLIC_EXPONENT); attr2 = pk11_attribute_bytype(rsa2, CKA_PUBLIC_EXPONENT); if ((attr1 == NULL) && (attr2 == NULL)) return (ISC_TRUE); else if ((attr1 == NULL) || (attr2 == NULL) || (attr1->ulValueLen != attr2->ulValueLen) || !isc_safe_memequal(attr1->pValue, attr2->pValue, attr1->ulValueLen)) return (ISC_FALSE); attr1 = pk11_attribute_bytype(rsa1, CKA_PRIVATE_EXPONENT); attr2 = pk11_attribute_bytype(rsa2, CKA_PRIVATE_EXPONENT); if (((attr1 != NULL) || (attr2 != NULL)) && ((attr1 == NULL) || (attr2 == NULL) || (attr1->ulValueLen != attr2->ulValueLen) || !isc_safe_memequal(attr1->pValue, attr2->pValue, attr1->ulValueLen))) return (ISC_FALSE); if (!rsa1->ontoken && !rsa2->ontoken) return (ISC_TRUE); else if (rsa1->ontoken || rsa2->ontoken || (rsa1->object != rsa2->object)) return (ISC_FALSE); return (ISC_TRUE); } static isc_result_t pkcs11rsa_generate(dst_key_t *key, int exp, void (*callback)(int)) { CK_RV rv; CK_MECHANISM mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0 }; CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; CK_ULONG bits = 0; CK_BYTE pubexp[5]; CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; CK_KEY_TYPE keyType = CKK_RSA; CK_ATTRIBUTE pubTemplate[] = { { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_MODULUS_BITS, &bits, (CK_ULONG) sizeof(bits) }, { CKA_PUBLIC_EXPONENT, &pubexp, (CK_ULONG) sizeof(pubexp) } }; CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY; CK_ATTRIBUTE privTemplate[] = { { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, }; CK_ATTRIBUTE *attr; pk11_object_t *rsa; pk11_context_t *pk11_ctx; isc_result_t ret; unsigned int i; UNUSED(callback); pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_RSA)); if (ret != ISC_R_SUCCESS) goto err; bits = key->key_size; if (exp == 0) { /* RSA_F4 0x10001 */ pubexp[0] = 1; pubexp[1] = 0; pubexp[2] = 1; pubTemplate[6].ulValueLen = 3; } else { /* F5 0x100000001 */ pubexp[0] = 1; pubexp[1] = 0; pubexp[2] = 0; pubexp[3] = 0; pubexp[4] = 1; pubTemplate[6].ulValueLen = 5; } PK11_RET(pkcs_C_GenerateKeyPair, (pk11_ctx->session, &mech, pubTemplate, (CK_ULONG) 7, privTemplate, (CK_ULONG) 7, &pub, &priv), DST_R_CRYPTOFAILURE); rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa)); if (rsa == NULL) DST_RET(ISC_R_NOMEMORY); memset(rsa, 0, sizeof(*rsa)); key->keydata.pkey = rsa; rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 8); if (rsa->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(rsa->repr, 0, sizeof(*attr) * 8); rsa->attrcnt = 8; attr = rsa->repr; attr[0].type = CKA_MODULUS; attr[1].type = CKA_PUBLIC_EXPONENT; attr[2].type = CKA_PRIVATE_EXPONENT; attr[3].type = CKA_PRIME_1; attr[4].type = CKA_PRIME_2; attr[5].type = CKA_EXPONENT_1; attr[6].type = CKA_EXPONENT_2; attr[7].type = CKA_COEFFICIENT; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 2), DST_R_CRYPTOFAILURE); for (i = 0; i <= 1; i++) { attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); if (attr[i].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr[i].pValue, 0, attr[i].ulValueLen); } PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 2), DST_R_CRYPTOFAILURE); attr += 2; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 6), DST_R_CRYPTOFAILURE); for (i = 0; i <= 5; i++) { attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); if (attr[i].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr[i].pValue, 0, attr[i].ulValueLen); } PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 6), DST_R_CRYPTOFAILURE); (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ISC_R_SUCCESS); err: pkcs11rsa_destroy(key); if (priv != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); if (pub != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); } static isc_boolean_t pkcs11rsa_isprivate(const dst_key_t *key) { pk11_object_t *rsa = key->keydata.pkey; CK_ATTRIBUTE *attr; if (rsa == NULL) return (ISC_FALSE); attr = pk11_attribute_bytype(rsa, CKA_PRIVATE_EXPONENT); return (ISC_TF((attr != NULL) || rsa->ontoken)); } static void pkcs11rsa_destroy(dst_key_t *key) { pk11_object_t *rsa = key->keydata.pkey; CK_ATTRIBUTE *attr; if (rsa == NULL) return; INSIST((rsa->object == CK_INVALID_HANDLE) || rsa->ontoken); for (attr = pk11_attribute_first(rsa); attr != NULL; attr = pk11_attribute_next(rsa, attr)) switch (attr->type) { case CKA_LABEL: case CKA_ID: case CKA_MODULUS: case CKA_PUBLIC_EXPONENT: case CKA_PRIVATE_EXPONENT: case CKA_PRIME_1: case CKA_PRIME_2: case CKA_EXPONENT_1: case CKA_EXPONENT_2: case CKA_COEFFICIENT: if (attr->pValue != NULL) { memset(attr->pValue, 0, attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); } break; } if (rsa->repr != NULL) { memset(rsa->repr, 0, rsa->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, rsa->repr, rsa->attrcnt * sizeof(*attr)); } memset(rsa, 0, sizeof(*rsa)); isc_mem_put(key->mctx, rsa, sizeof(*rsa)); key->keydata.pkey = NULL; } static isc_result_t pkcs11rsa_todns(const dst_key_t *key, isc_buffer_t *data) { pk11_object_t *rsa; CK_ATTRIBUTE *attr; isc_region_t r; unsigned int e_bytes = 0, mod_bytes = 0; CK_BYTE *exponent = NULL, *modulus = NULL; REQUIRE(key->keydata.pkey != NULL); rsa = key->keydata.pkey; for (attr = pk11_attribute_first(rsa); attr != NULL; attr = pk11_attribute_next(rsa, attr)) switch (attr->type) { case CKA_PUBLIC_EXPONENT: exponent = (CK_BYTE *) attr->pValue; e_bytes = (unsigned int) attr->ulValueLen; break; case CKA_MODULUS: modulus = (CK_BYTE *) attr->pValue; mod_bytes = (unsigned int) attr->ulValueLen; break; } REQUIRE((exponent != NULL) && (modulus != NULL)); isc_buffer_availableregion(data, &r); if (e_bytes < 256) { /*%< key exponent is <= 2040 bits */ if (r.length < 1) return (ISC_R_NOSPACE); isc_buffer_putuint8(data, (isc_uint8_t) e_bytes); isc_region_consume(&r, 1); } else { if (r.length < 3) return (ISC_R_NOSPACE); isc_buffer_putuint8(data, 0); isc_buffer_putuint16(data, (isc_uint16_t) e_bytes); isc_region_consume(&r, 3); } if (r.length < e_bytes + mod_bytes) return (ISC_R_NOSPACE); memmove(r.base, exponent, e_bytes); isc_region_consume(&r, e_bytes); memmove(r.base, modulus, mod_bytes); isc_buffer_add(data, e_bytes + mod_bytes); return (ISC_R_SUCCESS); } static isc_result_t pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { pk11_object_t *rsa; isc_region_t r; unsigned int e_bytes, mod_bytes; CK_BYTE *exponent = NULL, *modulus = NULL; CK_ATTRIBUTE *attr; unsigned int length; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); length = r.length; rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa)); if (rsa == NULL) return (ISC_R_NOMEMORY); memset(rsa, 0, sizeof(*rsa)); e_bytes = *r.base; isc_region_consume(&r, 1); if (e_bytes == 0) { if (r.length < 2) { memset(rsa, 0, sizeof(*rsa)); isc_mem_put(key->mctx, rsa, sizeof(*rsa)); return (DST_R_INVALIDPUBLICKEY); } e_bytes = (*r.base) << 8; isc_region_consume(&r, 1); e_bytes += *r.base; isc_region_consume(&r, 1); } if (r.length < e_bytes) { memset(rsa, 0, sizeof(*rsa)); isc_mem_put(key->mctx, rsa, sizeof(*rsa)); return (DST_R_INVALIDPUBLICKEY); } exponent = r.base; isc_region_consume(&r, e_bytes); modulus = r.base; mod_bytes = r.length; key->key_size = pk11_numbits(modulus, mod_bytes); isc_buffer_forward(data, length); rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); if (rsa->repr == NULL) goto nomemory; memset(rsa->repr, 0, sizeof(*attr) * 2); rsa->attrcnt = 2; attr = rsa->repr; attr[0].type = CKA_MODULUS; attr[0].pValue = isc_mem_get(key->mctx, mod_bytes); if (attr[0].pValue == NULL) goto nomemory; memmove(attr[0].pValue, modulus, mod_bytes); attr[0].ulValueLen = (CK_ULONG) mod_bytes; attr[1].type = CKA_PUBLIC_EXPONENT; attr[1].pValue = isc_mem_get(key->mctx, e_bytes); if (attr[1].pValue == NULL) goto nomemory; memmove(attr[1].pValue, exponent, e_bytes); attr[1].ulValueLen = (CK_ULONG) e_bytes; key->keydata.pkey = rsa; return (ISC_R_SUCCESS); nomemory: for (attr = pk11_attribute_first(rsa); attr != NULL; attr = pk11_attribute_next(rsa, attr)) switch (attr->type) { case CKA_MODULUS: case CKA_PUBLIC_EXPONENT: if (attr->pValue != NULL) { memset(attr->pValue, 0, attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); } break; } if (rsa->repr != NULL) { memset(rsa->repr, 0, rsa->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, rsa->repr, rsa->attrcnt * sizeof(*attr)); } memset(rsa, 0, sizeof(*rsa)); isc_mem_put(key->mctx, rsa, sizeof(*rsa)); return (ISC_R_NOMEMORY); } static isc_result_t pkcs11rsa_tofile(const dst_key_t *key, const char *directory) { int i; pk11_object_t *rsa; CK_ATTRIBUTE *attr; CK_ATTRIBUTE *modulus = NULL, *exponent = NULL; CK_ATTRIBUTE *d = NULL, *p = NULL, *q = NULL; CK_ATTRIBUTE *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; dst_private_t priv; unsigned char *bufs[10]; isc_result_t result; if (key->keydata.pkey == NULL) return (DST_R_NULLKEY); if (key->external) { priv.nelements = 0; return (dst__privstruct_writefile(key, &priv, directory)); } rsa = key->keydata.pkey; for (attr = pk11_attribute_first(rsa); attr != NULL; attr = pk11_attribute_next(rsa, attr)) switch (attr->type) { case CKA_MODULUS: modulus = attr; break; case CKA_PUBLIC_EXPONENT: exponent = attr; break; case CKA_PRIVATE_EXPONENT: d = attr; break; case CKA_PRIME_1: p = attr; break; case CKA_PRIME_2: q = attr; break; case CKA_EXPONENT_1: dmp1 = attr; break; case CKA_EXPONENT_2: dmq1 = attr; break; case CKA_COEFFICIENT: iqmp = attr; break; } if ((modulus == NULL) || (exponent == NULL)) return (DST_R_NULLKEY); memset(bufs, 0, sizeof(bufs)); for (i = 0; i < 10; i++) { bufs[i] = isc_mem_get(key->mctx, modulus->ulValueLen); if (bufs[i] == NULL) { result = ISC_R_NOMEMORY; goto fail; } memset(bufs[i], 0, modulus->ulValueLen); } i = 0; priv.elements[i].tag = TAG_RSA_MODULUS; priv.elements[i].length = (unsigned short) modulus->ulValueLen; memmove(bufs[i], modulus->pValue, modulus->ulValueLen); priv.elements[i].data = bufs[i]; i++; priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT; priv.elements[i].length = (unsigned short) exponent->ulValueLen; memmove(bufs[i], exponent->pValue, exponent->ulValueLen); priv.elements[i].data = bufs[i]; i++; if (d != NULL) { priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT; priv.elements[i].length = (unsigned short) d->ulValueLen; memmove(bufs[i], d->pValue, d->ulValueLen); priv.elements[i].data = bufs[i]; i++; } if (p != NULL) { priv.elements[i].tag = TAG_RSA_PRIME1; priv.elements[i].length = (unsigned short) p->ulValueLen; memmove(bufs[i], p->pValue, p->ulValueLen); priv.elements[i].data = bufs[i]; i++; } if (q != NULL) { priv.elements[i].tag = TAG_RSA_PRIME2; priv.elements[i].length = (unsigned short) q->ulValueLen; memmove(bufs[i], q->pValue, q->ulValueLen); priv.elements[i].data = bufs[i]; i++; } if (dmp1 != NULL) { priv.elements[i].tag = TAG_RSA_EXPONENT1; priv.elements[i].length = (unsigned short) dmp1->ulValueLen; memmove(bufs[i], dmp1->pValue, dmp1->ulValueLen); priv.elements[i].data = bufs[i]; i++; } if (dmq1 != NULL) { priv.elements[i].tag = TAG_RSA_EXPONENT2; priv.elements[i].length = (unsigned short) dmq1->ulValueLen; memmove(bufs[i], dmq1->pValue, dmq1->ulValueLen); priv.elements[i].data = bufs[i]; i++; } if (iqmp != NULL) { priv.elements[i].tag = TAG_RSA_COEFFICIENT; priv.elements[i].length = (unsigned short) iqmp->ulValueLen; memmove(bufs[i], iqmp->pValue, iqmp->ulValueLen); priv.elements[i].data = bufs[i]; i++; } if (key->engine != NULL) { priv.elements[i].tag = TAG_RSA_ENGINE; priv.elements[i].length = strlen(key->engine) + 1; priv.elements[i].data = (unsigned char *)key->engine; i++; } if (key->label != NULL) { priv.elements[i].tag = TAG_RSA_LABEL; priv.elements[i].length = strlen(key->label) + 1; priv.elements[i].data = (unsigned char *)key->label; i++; } priv.nelements = i; result = dst__privstruct_writefile(key, &priv, directory); fail: for (i = 0; i < 10; i++) { if (bufs[i] == NULL) break; memset(bufs[i], 0, modulus->ulValueLen); isc_mem_put(key->mctx, bufs[i], modulus->ulValueLen); } return (result); } static isc_result_t pkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label, dst_key_t *pub) { CK_RV rv; CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; CK_KEY_TYPE keyType = CKK_RSA; CK_ATTRIBUTE searchTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_LABEL, NULL, 0 } }; CK_ULONG cnt; CK_ATTRIBUTE *attr; CK_ATTRIBUTE *pubattr; pk11_object_t *rsa; pk11_object_t *pubrsa; pk11_context_t *pk11_ctx = NULL; isc_result_t ret; if (label == NULL) return (DST_R_NOENGINE); rsa = key->keydata.pkey; pubrsa = pub->keydata.pkey; rsa->object = CK_INVALID_HANDLE; rsa->ontoken = ISC_TRUE; rsa->reqlogon = ISC_TRUE; rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); if (rsa->repr == NULL) return (ISC_R_NOMEMORY); memset(rsa->repr, 0, sizeof(*attr) * 2); rsa->attrcnt = 2; attr = rsa->repr; attr->type = CKA_MODULUS; pubattr = pk11_attribute_bytype(pubrsa, CKA_MODULUS); attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen); attr->ulValueLen = pubattr->ulValueLen; attr++; attr->type = CKA_PUBLIC_EXPONENT; pubattr = pk11_attribute_bytype(pubrsa, CKA_PUBLIC_EXPONENT); attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen); attr->ulValueLen = pubattr->ulValueLen; ret = pk11_parse_uri(rsa, label, key->mctx, OP_RSA); if (ret != ISC_R_SUCCESS) goto err; pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) DST_RET(ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE, rsa->reqlogon, NULL, rsa->slot); if (ret != ISC_R_SUCCESS) goto err; attr = pk11_attribute_bytype(rsa, CKA_LABEL); if (attr == NULL) { attr = pk11_attribute_bytype(rsa, CKA_ID); INSIST(attr != NULL); searchTemplate[3].type = CKA_ID; } searchTemplate[3].pValue = attr->pValue; searchTemplate[3].ulValueLen = attr->ulValueLen; PK11_RET(pkcs_C_FindObjectsInit, (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), DST_R_CRYPTOFAILURE); PK11_RET(pkcs_C_FindObjects, (pk11_ctx->session, &rsa->object, (CK_ULONG) 1, &cnt), DST_R_CRYPTOFAILURE); (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); if (cnt == 0) DST_RET(ISC_R_NOTFOUND); if (cnt > 1) DST_RET(ISC_R_EXISTS); if (engine != NULL) { key->engine = isc_mem_strdup(key->mctx, engine); if (key->engine == NULL) DST_RET(ISC_R_NOMEMORY); } key->label = isc_mem_strdup(key->mctx, label); if (key->label == NULL) DST_RET(ISC_R_NOMEMORY); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); attr = pk11_attribute_bytype(rsa, CKA_MODULUS); INSIST(attr != NULL); key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); return (ISC_R_SUCCESS); err: if (pk11_ctx != NULL) { pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); } return (ret); } static isc_result_t rsa_check(pk11_object_t *rsa, pk11_object_t *pubrsa) { CK_ATTRIBUTE *pubattr, *privattr; CK_BYTE *priv_exp = NULL, *priv_mod = NULL; CK_BYTE *pub_exp = NULL, *pub_mod = NULL; unsigned int priv_explen = 0, priv_modlen = 0; unsigned int pub_explen = 0, pub_modlen = 0; REQUIRE(rsa != NULL && pubrsa != NULL); privattr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT); INSIST(privattr != NULL); priv_exp = privattr->pValue; priv_explen = privattr->ulValueLen; pubattr = pk11_attribute_bytype(pubrsa, CKA_PUBLIC_EXPONENT); INSIST(pubattr != NULL); pub_exp = pubattr->pValue; pub_explen = pubattr->ulValueLen; if (priv_exp != NULL) { if (priv_explen != pub_explen) return (DST_R_INVALIDPRIVATEKEY); if (!isc_safe_memequal(priv_exp, pub_exp, pub_explen)) return (DST_R_INVALIDPRIVATEKEY); } else { privattr->pValue = pub_exp; privattr->ulValueLen = pub_explen; pubattr->pValue = NULL; pubattr->ulValueLen = 0; } if (privattr->pValue == NULL) return (DST_R_INVALIDPRIVATEKEY); privattr = pk11_attribute_bytype(rsa, CKA_MODULUS); INSIST(privattr != NULL); priv_mod = privattr->pValue; priv_modlen = privattr->ulValueLen; pubattr = pk11_attribute_bytype(pubrsa, CKA_MODULUS); INSIST(pubattr != NULL); pub_mod = pubattr->pValue; pub_modlen = pubattr->ulValueLen; if (priv_mod != NULL) { if (priv_modlen != pub_modlen) return (DST_R_INVALIDPRIVATEKEY); if (!isc_safe_memequal(priv_mod, pub_mod, pub_modlen)) return (DST_R_INVALIDPRIVATEKEY); } else { privattr->pValue = pub_mod; privattr->ulValueLen = pub_modlen; pubattr->pValue = NULL; pubattr->ulValueLen = 0; } if (privattr->pValue == NULL) return (DST_R_INVALIDPRIVATEKEY); return (ISC_R_SUCCESS); } static isc_result_t pkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t ret; int i; pk11_object_t *rsa; CK_ATTRIBUTE *attr; isc_mem_t *mctx = key->mctx; const char *engine = NULL, *label = NULL; /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) return (ret); if (key->external) { if (priv.nelements != 0) DST_RET(DST_R_INVALIDPRIVATEKEY); if (pub == NULL) DST_RET(DST_R_INVALIDPRIVATEKEY); key->keydata.pkey = pub->keydata.pkey; pub->keydata.pkey = NULL; key->key_size = pub->key_size; dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ISC_R_SUCCESS); } for (i = 0; i < priv.nelements; i++) { switch (priv.elements[i].tag) { case TAG_RSA_ENGINE: engine = (char *)priv.elements[i].data; break; case TAG_RSA_LABEL: label = (char *)priv.elements[i].data; break; default: break; } } rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa)); if (rsa == NULL) DST_RET(ISC_R_NOMEMORY); memset(rsa, 0, sizeof(*rsa)); key->keydata.pkey = rsa; /* Is this key is stored in a HSM? See if we can fetch it. */ if ((label != NULL) || (engine != NULL)) { ret = pkcs11rsa_fetch(key, engine, label, pub); if (ret != ISC_R_SUCCESS) goto err; dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ret); } rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 8); if (rsa->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(rsa->repr, 0, sizeof(*attr) * 8); rsa->attrcnt = 8; attr = rsa->repr; attr[0].type = CKA_MODULUS; attr[1].type = CKA_PUBLIC_EXPONENT; attr[2].type = CKA_PRIVATE_EXPONENT; attr[3].type = CKA_PRIME_1; attr[4].type = CKA_PRIME_2; attr[5].type = CKA_EXPONENT_1; attr[6].type = CKA_EXPONENT_2; attr[7].type = CKA_COEFFICIENT; for (i = 0; i < priv.nelements; i++) { CK_BYTE *bn; switch (priv.elements[i].tag) { case TAG_RSA_ENGINE: continue; case TAG_RSA_LABEL: continue; default: bn = isc_mem_get(key->mctx, priv.elements[i].length); if (bn == NULL) DST_RET(ISC_R_NOMEMORY); memmove(bn, priv.elements[i].data, priv.elements[i].length); } switch (priv.elements[i].tag) { case TAG_RSA_MODULUS: attr = pk11_attribute_bytype(rsa, CKA_MODULUS); INSIST(attr != NULL); attr->pValue = bn; attr->ulValueLen = priv.elements[i].length; break; case TAG_RSA_PUBLICEXPONENT: attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT); INSIST(attr != NULL); attr->pValue = bn; attr->ulValueLen = priv.elements[i].length; break; case TAG_RSA_PRIVATEEXPONENT: attr = pk11_attribute_bytype(rsa, CKA_PRIVATE_EXPONENT); INSIST(attr != NULL); attr->pValue = bn; attr->ulValueLen = priv.elements[i].length; break; case TAG_RSA_PRIME1: attr = pk11_attribute_bytype(rsa, CKA_PRIME_1); INSIST(attr != NULL); attr->pValue = bn; attr->ulValueLen = priv.elements[i].length; break; case TAG_RSA_PRIME2: attr = pk11_attribute_bytype(rsa, CKA_PRIME_2); INSIST(attr != NULL); attr->pValue = bn; attr->ulValueLen = priv.elements[i].length; break; case TAG_RSA_EXPONENT1: attr = pk11_attribute_bytype(rsa, CKA_EXPONENT_1); INSIST(attr != NULL); attr->pValue = bn; attr->ulValueLen = priv.elements[i].length; break; case TAG_RSA_EXPONENT2: attr = pk11_attribute_bytype(rsa, CKA_EXPONENT_2); INSIST(attr != NULL); attr->pValue = bn; attr->ulValueLen = priv.elements[i].length; break; case TAG_RSA_COEFFICIENT: attr = pk11_attribute_bytype(rsa, CKA_COEFFICIENT); INSIST(attr != NULL); attr->pValue = bn; attr->ulValueLen = priv.elements[i].length; break; } } if (rsa_check(rsa, pub->keydata.pkey) != ISC_R_SUCCESS) DST_RET(DST_R_INVALIDPRIVATEKEY); attr = pk11_attribute_bytype(rsa, CKA_MODULUS); INSIST(attr != NULL); key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT); INSIST(attr != NULL); if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS) DST_RET(ISC_R_RANGE); dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ISC_R_SUCCESS); err: pkcs11rsa_destroy(key); dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ret); } static isc_result_t pkcs11rsa_fromlabel(dst_key_t *key, const char *engine, const char *label, const char *pin) { CK_RV rv; CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; CK_KEY_TYPE keyType = CKK_RSA; CK_ATTRIBUTE searchTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_LABEL, NULL, 0 } }; CK_ULONG cnt; CK_ATTRIBUTE *attr; pk11_object_t *rsa; pk11_context_t *pk11_ctx = NULL; isc_result_t ret; unsigned int i; UNUSED(pin); rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa)); if (rsa == NULL) return (ISC_R_NOMEMORY); memset(rsa, 0, sizeof(*rsa)); rsa->object = CK_INVALID_HANDLE; rsa->ontoken = ISC_TRUE; rsa->reqlogon = ISC_TRUE; key->keydata.pkey = rsa; rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); if (rsa->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(rsa->repr, 0, sizeof(*attr) * 2); rsa->attrcnt = 2; attr = rsa->repr; attr[0].type = CKA_MODULUS; attr[1].type = CKA_PUBLIC_EXPONENT; ret = pk11_parse_uri(rsa, label, key->mctx, OP_RSA); if (ret != ISC_R_SUCCESS) goto err; pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) DST_RET(ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE, rsa->reqlogon, NULL, rsa->slot); if (ret != ISC_R_SUCCESS) goto err; attr = pk11_attribute_bytype(rsa, CKA_LABEL); if (attr == NULL) { attr = pk11_attribute_bytype(rsa, CKA_ID); INSIST(attr != NULL); searchTemplate[3].type = CKA_ID; } searchTemplate[3].pValue = attr->pValue; searchTemplate[3].ulValueLen = attr->ulValueLen; PK11_RET(pkcs_C_FindObjectsInit, (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), DST_R_CRYPTOFAILURE); PK11_RET(pkcs_C_FindObjects, (pk11_ctx->session, &hKey, (CK_ULONG) 1, &cnt), DST_R_CRYPTOFAILURE); (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); if (cnt == 0) DST_RET(ISC_R_NOTFOUND); if (cnt > 1) DST_RET(ISC_R_EXISTS); attr = rsa->repr; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, hKey, attr, 2), DST_R_CRYPTOFAILURE); for (i = 0; i <= 1; i++) { attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); if (attr[i].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr[i].pValue, 0, attr[i].ulValueLen); } PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, hKey, attr, 2), DST_R_CRYPTOFAILURE); keyClass = CKO_PRIVATE_KEY; PK11_RET(pkcs_C_FindObjectsInit, (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), DST_R_CRYPTOFAILURE); PK11_RET(pkcs_C_FindObjects, (pk11_ctx->session, &rsa->object, (CK_ULONG) 1, &cnt), DST_R_CRYPTOFAILURE); (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); if (cnt == 0) DST_RET(ISC_R_NOTFOUND); if (cnt > 1) DST_RET(ISC_R_EXISTS); if (engine != NULL) { key->engine = isc_mem_strdup(key->mctx, engine); if (key->engine == NULL) DST_RET(ISC_R_NOMEMORY); } key->label = isc_mem_strdup(key->mctx, label); if (key->label == NULL) DST_RET(ISC_R_NOMEMORY); attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT); INSIST(attr != NULL); if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS) DST_RET(ISC_R_RANGE); attr = pk11_attribute_bytype(rsa, CKA_MODULUS); INSIST(attr != NULL); key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ISC_R_SUCCESS); err: pkcs11rsa_destroy(key); if (pk11_ctx != NULL) { pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); } return (ret); } static dst_func_t pkcs11rsa_functions = { pkcs11rsa_createctx, pkcs11rsa_createctx2, pkcs11rsa_destroyctx, pkcs11rsa_adddata, pkcs11rsa_sign, pkcs11rsa_verify, NULL, /*%< verify2 */ NULL, /*%< computesecret */ pkcs11rsa_compare, NULL, /*%< paramcompare */ pkcs11rsa_generate, pkcs11rsa_isprivate, pkcs11rsa_destroy, pkcs11rsa_todns, pkcs11rsa_fromdns, pkcs11rsa_tofile, pkcs11rsa_parse, NULL, /*%< cleanup */ pkcs11rsa_fromlabel, NULL, /*%< dump */ NULL, /*%< restore */ }; isc_result_t dst__pkcs11rsa_init(dst_func_t **funcp) { REQUIRE(funcp != NULL); if (*funcp == NULL) *funcp = &pkcs11rsa_functions; return (ISC_R_SUCCESS); } #else /* PKCS11CRYPTO */ #include EMPTY_TRANSLATION_UNIT #endif /* PKCS11CRYPTO */ /*! \file */ bind9-9.10.3.dfsg.P4/lib/dns/name.c0000644000470500017500000016615712664710322016027 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define VALID_NAME(n) ISC_MAGIC_VALID(n, DNS_NAME_MAGIC) typedef enum { ft_init = 0, ft_start, ft_ordinary, ft_initialescape, ft_escape, ft_escdecimal, ft_at } ft_state; typedef enum { fw_start = 0, fw_ordinary, fw_newcurrent } fw_state; static char digitvalue[256] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/ }; static unsigned char maptolower[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; #define CONVERTTOASCII(c) #define CONVERTFROMASCII(c) #define INIT_OFFSETS(name, var, default) \ if (name->offsets != NULL) \ var = name->offsets; \ else \ var = default; #define SETUP_OFFSETS(name, var, default) \ if (name->offsets != NULL) \ var = name->offsets; \ else { \ var = default; \ set_offsets(name, var, NULL); \ } /*% * Note: If additional attributes are added that should not be set for * empty names, MAKE_EMPTY() must be changed so it clears them. */ #define MAKE_EMPTY(name) \ do { \ name->ndata = NULL; \ name->length = 0; \ name->labels = 0; \ name->attributes &= ~DNS_NAMEATTR_ABSOLUTE; \ } while (0); /*% * A name is "bindable" if it can be set to point to a new value, i.e. * name->ndata and name->length may be changed. */ #define BINDABLE(name) \ ((name->attributes & (DNS_NAMEATTR_READONLY|DNS_NAMEATTR_DYNAMIC)) \ == 0) /*% * Note that the name data must be a char array, not a string * literal, to avoid compiler warnings about discarding * the const attribute of a string. */ static unsigned char root_ndata[] = { '\0' }; static unsigned char root_offsets[] = { 0 }; static dns_name_t root = { DNS_NAME_MAGIC, root_ndata, 1, 1, DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, root_offsets, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} }; /* XXXDCL make const? */ LIBDNS_EXTERNAL_DATA dns_name_t *dns_rootname = &root; static unsigned char wild_ndata[] = { '\001', '*' }; static unsigned char wild_offsets[] = { 0 }; static dns_name_t wild = { DNS_NAME_MAGIC, wild_ndata, 2, 1, DNS_NAMEATTR_READONLY, wild_offsets, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} }; /* XXXDCL make const? */ LIBDNS_EXTERNAL_DATA dns_name_t *dns_wildcardname = &wild; unsigned int dns_fullname_hash(dns_name_t *name, isc_boolean_t case_sensitive); /* * dns_name_t to text post-conversion procedure. */ #ifdef ISC_PLATFORM_USETHREADS static int thread_key_initialized = 0; static isc_mutex_t thread_key_mutex; static isc_mem_t *thread_key_mctx = NULL; static isc_thread_key_t totext_filter_proc_key; static isc_once_t once = ISC_ONCE_INIT; #else static dns_name_totextfilter_t totext_filter_proc = NULL; #endif static void set_offsets(const dns_name_t *name, unsigned char *offsets, dns_name_t *set_name); void dns_name_init(dns_name_t *name, unsigned char *offsets) { /* * Initialize 'name'. */ DNS_NAME_INIT(name, offsets); } void dns_name_reset(dns_name_t *name) { REQUIRE(VALID_NAME(name)); REQUIRE(BINDABLE(name)); DNS_NAME_RESET(name); } void dns_name_invalidate(dns_name_t *name) { /* * Make 'name' invalid. */ REQUIRE(VALID_NAME(name)); name->magic = 0; name->ndata = NULL; name->length = 0; name->labels = 0; name->attributes = 0; name->offsets = NULL; name->buffer = NULL; ISC_LINK_INIT(name, link); } isc_boolean_t dns_name_isvalid(const dns_name_t *name) { unsigned char *ndata, *offsets; unsigned int offset, count, length, nlabels; if (!VALID_NAME(name)) return (ISC_FALSE); if (name->length > 255U || name->labels > 127U) return (ISC_FALSE); ndata = name->ndata; length = name->length; offsets = name->offsets; offset = 0; nlabels = 0; while (offset != length) { count = *ndata; if (count > 63U) return (ISC_FALSE); if (offsets != NULL && offsets[nlabels] != offset) return (ISC_FALSE); nlabels++; offset += count + 1; ndata += count + 1; if (offset > length) return (ISC_FALSE); if (count == 0) break; } if (nlabels != name->labels || offset != name->length) return (ISC_FALSE); return (ISC_TRUE); } void dns_name_setbuffer(dns_name_t *name, isc_buffer_t *buffer) { /* * Dedicate a buffer for use with 'name'. */ REQUIRE(VALID_NAME(name)); REQUIRE((buffer != NULL && name->buffer == NULL) || (buffer == NULL)); name->buffer = buffer; } isc_boolean_t dns_name_hasbuffer(const dns_name_t *name) { /* * Does 'name' have a dedicated buffer? */ REQUIRE(VALID_NAME(name)); if (name->buffer != NULL) return (ISC_TRUE); return (ISC_FALSE); } isc_boolean_t dns_name_isabsolute(const dns_name_t *name) { /* * Does 'name' end in the root label? */ REQUIRE(VALID_NAME(name)); if ((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) return (ISC_TRUE); return (ISC_FALSE); } #define hyphenchar(c) ((c) == 0x2d) #define asterchar(c) ((c) == 0x2a) #define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \ || ((c) >= 0x61 && (c) <= 0x7a)) #define digitchar(c) ((c) >= 0x30 && (c) <= 0x39) #define borderchar(c) (alphachar(c) || digitchar(c)) #define middlechar(c) (borderchar(c) || hyphenchar(c)) #define domainchar(c) ((c) > 0x20 && (c) < 0x7f) isc_boolean_t dns_name_ismailbox(const dns_name_t *name) { unsigned char *ndata, ch; unsigned int n; isc_boolean_t first; REQUIRE(VALID_NAME(name)); REQUIRE(name->labels > 0); REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE); /* * Root label. */ if (name->length == 1) return (ISC_TRUE); ndata = name->ndata; n = *ndata++; INSIST(n <= 63); while (n--) { ch = *ndata++; if (!domainchar(ch)) return (ISC_FALSE); } if (ndata == name->ndata + name->length) return (ISC_FALSE); /* * RFC292/RFC1123 hostname. */ while (ndata < (name->ndata + name->length)) { n = *ndata++; INSIST(n <= 63); first = ISC_TRUE; while (n--) { ch = *ndata++; if (first || n == 0) { if (!borderchar(ch)) return (ISC_FALSE); } else { if (!middlechar(ch)) return (ISC_FALSE); } first = ISC_FALSE; } } return (ISC_TRUE); } isc_boolean_t dns_name_ishostname(const dns_name_t *name, isc_boolean_t wildcard) { unsigned char *ndata, ch; unsigned int n; isc_boolean_t first; REQUIRE(VALID_NAME(name)); REQUIRE(name->labels > 0); REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE); /* * Root label. */ if (name->length == 1) return (ISC_TRUE); /* * Skip wildcard if this is a ownername. */ ndata = name->ndata; if (wildcard && ndata[0] == 1 && ndata[1] == '*') ndata += 2; /* * RFC292/RFC1123 hostname. */ while (ndata < (name->ndata + name->length)) { n = *ndata++; INSIST(n <= 63); first = ISC_TRUE; while (n--) { ch = *ndata++; if (first || n == 0) { if (!borderchar(ch)) return (ISC_FALSE); } else { if (!middlechar(ch)) return (ISC_FALSE); } first = ISC_FALSE; } } return (ISC_TRUE); } isc_boolean_t dns_name_iswildcard(const dns_name_t *name) { unsigned char *ndata; /* * Is 'name' a wildcard name? */ REQUIRE(VALID_NAME(name)); REQUIRE(name->labels > 0); if (name->length >= 2) { ndata = name->ndata; if (ndata[0] == 1 && ndata[1] == '*') return (ISC_TRUE); } return (ISC_FALSE); } isc_boolean_t dns_name_internalwildcard(const dns_name_t *name) { unsigned char *ndata; unsigned int count; unsigned int label; /* * Does 'name' contain a internal wildcard? */ REQUIRE(VALID_NAME(name)); REQUIRE(name->labels > 0); /* * Skip first label. */ ndata = name->ndata; count = *ndata++; INSIST(count <= 63); ndata += count; label = 1; /* * Check all but the last of the remaining labels. */ while (label + 1 < name->labels) { count = *ndata++; INSIST(count <= 63); if (count == 1 && *ndata == '*') return (ISC_TRUE); ndata += count; label++; } return (ISC_FALSE); } static inline unsigned int name_hash(dns_name_t *name, isc_boolean_t case_sensitive) { unsigned int length; const unsigned char *s; unsigned int h = 0; unsigned char c; length = name->length; if (length > 16) length = 16; /* * This hash function is similar to the one Ousterhout * uses in Tcl. */ s = name->ndata; if (case_sensitive) { while (length > 0) { h += ( h << 3 ) + *s; s++; length--; } } else { while (length > 0) { c = maptolower[*s]; h += ( h << 3 ) + c; s++; length--; } } return (h); } unsigned int dns_name_hash(dns_name_t *name, isc_boolean_t case_sensitive) { /* * Provide a hash value for 'name'. */ REQUIRE(VALID_NAME(name)); if (name->labels == 0) return (0); return (name_hash(name, case_sensitive)); } unsigned int dns_name_fullhash(dns_name_t *name, isc_boolean_t case_sensitive) { /* * Provide a hash value for 'name'. */ REQUIRE(VALID_NAME(name)); if (name->labels == 0) return (0); return (isc_hash_calc((const unsigned char *)name->ndata, name->length, case_sensitive)); } unsigned int dns_fullname_hash(dns_name_t *name, isc_boolean_t case_sensitive) { /* * This function was deprecated due to the breakage of the name space * convention. We only keep this internally to provide binary backward * compatibility. */ REQUIRE(VALID_NAME(name)); return (dns_name_fullhash(name, case_sensitive)); } unsigned int dns_name_hashbylabel(dns_name_t *name, isc_boolean_t case_sensitive) { unsigned char *offsets; dns_offsets_t odata; dns_name_t tname; unsigned int h = 0; unsigned int i; /* * Provide a hash value for 'name'. */ REQUIRE(VALID_NAME(name)); if (name->labels == 0) return (0); else if (name->labels == 1) return (name_hash(name, case_sensitive)); SETUP_OFFSETS(name, offsets, odata); DNS_NAME_INIT(&tname, NULL); tname.labels = 1; h = 0; for (i = 0; i < name->labels; i++) { tname.ndata = name->ndata + offsets[i]; if (i == name->labels - 1) tname.length = name->length - offsets[i]; else tname.length = offsets[i + 1] - offsets[i]; h += name_hash(&tname, case_sensitive); } return (h); } dns_namereln_t dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2, int *orderp, unsigned int *nlabelsp) { unsigned int l1, l2, l, count1, count2, count, nlabels; int cdiff, ldiff, chdiff; unsigned char *label1, *label2; unsigned char *offsets1, *offsets2; dns_offsets_t odata1, odata2; dns_namereln_t namereln = dns_namereln_none; /* * Determine the relative ordering under the DNSSEC order relation of * 'name1' and 'name2', and also determine the hierarchical * relationship of the names. * * Note: It makes no sense for one of the names to be relative and the * other absolute. If both names are relative, then to be meaningfully * compared the caller must ensure that they are both relative to the * same domain. */ REQUIRE(VALID_NAME(name1)); REQUIRE(VALID_NAME(name2)); REQUIRE(orderp != NULL); REQUIRE(nlabelsp != NULL); /* * Either name1 is absolute and name2 is absolute, or neither is. */ REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) == (name2->attributes & DNS_NAMEATTR_ABSOLUTE)); if (name1 == name2) { *orderp = 0; *nlabelsp = name1->labels; return (dns_namereln_equal); } SETUP_OFFSETS(name1, offsets1, odata1); SETUP_OFFSETS(name2, offsets2, odata2); nlabels = 0; l1 = name1->labels; l2 = name2->labels; if (l2 > l1) { l = l1; ldiff = 0 - (l2 - l1); } else { l = l2; ldiff = l1 - l2; } while (l > 0) { l--; l1--; l2--; label1 = &name1->ndata[offsets1[l1]]; label2 = &name2->ndata[offsets2[l2]]; count1 = *label1++; count2 = *label2++; /* * We dropped bitstring labels, and we don't support any * other extended label types. */ INSIST(count1 <= 63 && count2 <= 63); cdiff = (int)count1 - (int)count2; if (cdiff < 0) count = count1; else count = count2; while (count > 0) { chdiff = (int)maptolower[*label1] - (int)maptolower[*label2]; if (chdiff != 0) { *orderp = chdiff; goto done; } count--; label1++; label2++; } if (cdiff != 0) { *orderp = cdiff; goto done; } nlabels++; } *orderp = ldiff; if (ldiff < 0) namereln = dns_namereln_contains; else if (ldiff > 0) namereln = dns_namereln_subdomain; else namereln = dns_namereln_equal; done: *nlabelsp = nlabels; if (nlabels > 0 && namereln == dns_namereln_none) namereln = dns_namereln_commonancestor; return (namereln); } int dns_name_compare(const dns_name_t *name1, const dns_name_t *name2) { int order; unsigned int nlabels; /* * Determine the relative ordering under the DNSSEC order relation of * 'name1' and 'name2'. * * Note: It makes no sense for one of the names to be relative and the * other absolute. If both names are relative, then to be meaningfully * compared the caller must ensure that they are both relative to the * same domain. */ (void)dns_name_fullcompare(name1, name2, &order, &nlabels); return (order); } isc_boolean_t dns_name_equal(const dns_name_t *name1, const dns_name_t *name2) { unsigned int l, count; unsigned char c; unsigned char *label1, *label2; /* * Are 'name1' and 'name2' equal? * * Note: It makes no sense for one of the names to be relative and the * other absolute. If both names are relative, then to be meaningfully * compared the caller must ensure that they are both relative to the * same domain. */ REQUIRE(VALID_NAME(name1)); REQUIRE(VALID_NAME(name2)); /* * Either name1 is absolute and name2 is absolute, or neither is. */ REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) == (name2->attributes & DNS_NAMEATTR_ABSOLUTE)); if (name1 == name2) return (ISC_TRUE); if (name1->length != name2->length) return (ISC_FALSE); l = name1->labels; if (l != name2->labels) return (ISC_FALSE); label1 = name1->ndata; label2 = name2->ndata; while (l > 0) { l--; count = *label1++; if (count != *label2++) return (ISC_FALSE); INSIST(count <= 63); /* no bitstring support */ while (count > 0) { count--; c = maptolower[*label1++]; if (c != maptolower[*label2++]) return (ISC_FALSE); } } return (ISC_TRUE); } isc_boolean_t dns_name_caseequal(const dns_name_t *name1, const dns_name_t *name2) { /* * Are 'name1' and 'name2' equal? * * Note: It makes no sense for one of the names to be relative and the * other absolute. If both names are relative, then to be meaningfully * compared the caller must ensure that they are both relative to the * same domain. */ REQUIRE(VALID_NAME(name1)); REQUIRE(VALID_NAME(name2)); /* * Either name1 is absolute and name2 is absolute, or neither is. */ REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) == (name2->attributes & DNS_NAMEATTR_ABSOLUTE)); if (name1->length != name2->length) return (ISC_FALSE); if (memcmp(name1->ndata, name2->ndata, name1->length) != 0) return (ISC_FALSE); return (ISC_TRUE); } int dns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2) { unsigned int l1, l2, l, count1, count2, count; unsigned char c1, c2; unsigned char *label1, *label2; /* * Compare two absolute names as rdata. */ REQUIRE(VALID_NAME(name1)); REQUIRE(name1->labels > 0); REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) != 0); REQUIRE(VALID_NAME(name2)); REQUIRE(name2->labels > 0); REQUIRE((name2->attributes & DNS_NAMEATTR_ABSOLUTE) != 0); l1 = name1->labels; l2 = name2->labels; l = (l1 < l2) ? l1 : l2; label1 = name1->ndata; label2 = name2->ndata; while (l > 0) { l--; count1 = *label1++; count2 = *label2++; /* no bitstring support */ INSIST(count1 <= 63 && count2 <= 63); if (count1 != count2) return ((count1 < count2) ? -1 : 1); count = count1; while (count > 0) { count--; c1 = maptolower[*label1++]; c2 = maptolower[*label2++]; if (c1 < c2) return (-1); else if (c1 > c2) return (1); } } /* * If one name had more labels than the other, their common * prefix must have been different because the shorter name * ended with the root label and the longer one can't have * a root label in the middle of it. Therefore, if we get * to this point, the lengths must be equal. */ INSIST(l1 == l2); return (0); } isc_boolean_t dns_name_issubdomain(const dns_name_t *name1, const dns_name_t *name2) { int order; unsigned int nlabels; dns_namereln_t namereln; /* * Is 'name1' a subdomain of 'name2'? * * Note: It makes no sense for one of the names to be relative and the * other absolute. If both names are relative, then to be meaningfully * compared the caller must ensure that they are both relative to the * same domain. */ namereln = dns_name_fullcompare(name1, name2, &order, &nlabels); if (namereln == dns_namereln_subdomain || namereln == dns_namereln_equal) return (ISC_TRUE); return (ISC_FALSE); } isc_boolean_t dns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname) { int order; unsigned int nlabels, labels; dns_name_t tname; REQUIRE(VALID_NAME(name)); REQUIRE(name->labels > 0); REQUIRE(VALID_NAME(wname)); labels = wname->labels; REQUIRE(labels > 0); REQUIRE(dns_name_iswildcard(wname)); #if defined(__clang__) && \ ( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2)) memset(&tname, 0, sizeof(tname)); #endif DNS_NAME_INIT(&tname, NULL); dns_name_getlabelsequence(wname, 1, labels - 1, &tname); if (dns_name_fullcompare(name, &tname, &order, &nlabels) == dns_namereln_subdomain) return (ISC_TRUE); return (ISC_FALSE); } unsigned int dns_name_countlabels(const dns_name_t *name) { /* * How many labels does 'name' have? */ REQUIRE(VALID_NAME(name)); ENSURE(name->labels <= 128); return (name->labels); } void dns_name_getlabel(const dns_name_t *name, unsigned int n, dns_label_t *label) { unsigned char *offsets; dns_offsets_t odata; /* * Make 'label' refer to the 'n'th least significant label of 'name'. */ REQUIRE(VALID_NAME(name)); REQUIRE(name->labels > 0); REQUIRE(n < name->labels); REQUIRE(label != NULL); SETUP_OFFSETS(name, offsets, odata); label->base = &name->ndata[offsets[n]]; if (n == name->labels - 1) label->length = name->length - offsets[n]; else label->length = offsets[n + 1] - offsets[n]; } void dns_name_getlabelsequence(const dns_name_t *source, unsigned int first, unsigned int n, dns_name_t *target) { unsigned char *offsets; dns_offsets_t odata; unsigned int firstoffset, endoffset; /* * Make 'target' refer to the 'n' labels including and following * 'first' in 'source'. */ REQUIRE(VALID_NAME(source)); REQUIRE(VALID_NAME(target)); REQUIRE(first <= source->labels); REQUIRE(n <= source->labels - first); /* note first+n could overflow */ REQUIRE(BINDABLE(target)); SETUP_OFFSETS(source, offsets, odata); if (first == source->labels) firstoffset = source->length; else firstoffset = offsets[first]; if (first + n == source->labels) endoffset = source->length; else endoffset = offsets[first + n]; target->ndata = &source->ndata[firstoffset]; target->length = endoffset - firstoffset; if (first + n == source->labels && n > 0 && (source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) target->attributes |= DNS_NAMEATTR_ABSOLUTE; else target->attributes &= ~DNS_NAMEATTR_ABSOLUTE; target->labels = n; /* * If source and target are the same, and we're making target * a prefix of source, the offsets table is correct already * so we don't need to call set_offsets(). */ if (target->offsets != NULL && (target != source || first != 0)) set_offsets(target, target->offsets, NULL); } void dns_name_clone(const dns_name_t *source, dns_name_t *target) { /* * Make 'target' refer to the same name as 'source'. */ REQUIRE(VALID_NAME(source)); REQUIRE(VALID_NAME(target)); REQUIRE(BINDABLE(target)); target->ndata = source->ndata; target->length = source->length; target->labels = source->labels; target->attributes = source->attributes & (unsigned int)~(DNS_NAMEATTR_READONLY | DNS_NAMEATTR_DYNAMIC | DNS_NAMEATTR_DYNOFFSETS); if (target->offsets != NULL && source->labels > 0) { if (source->offsets != NULL) memmove(target->offsets, source->offsets, source->labels); else set_offsets(target, target->offsets, NULL); } } void dns_name_fromregion(dns_name_t *name, const isc_region_t *r) { unsigned char *offsets; dns_offsets_t odata; unsigned int len; isc_region_t r2; /* * Make 'name' refer to region 'r'. */ REQUIRE(VALID_NAME(name)); REQUIRE(r != NULL); REQUIRE(BINDABLE(name)); INIT_OFFSETS(name, offsets, odata); if (name->buffer != NULL) { isc_buffer_clear(name->buffer); isc_buffer_availableregion(name->buffer, &r2); len = (r->length < r2.length) ? r->length : r2.length; if (len > DNS_NAME_MAXWIRE) len = DNS_NAME_MAXWIRE; memmove(r2.base, r->base, len); name->ndata = r2.base; name->length = len; } else { name->ndata = r->base; name->length = (r->length <= DNS_NAME_MAXWIRE) ? r->length : DNS_NAME_MAXWIRE; } if (r->length > 0) set_offsets(name, offsets, name); else { name->labels = 0; name->attributes &= ~DNS_NAMEATTR_ABSOLUTE; } if (name->buffer != NULL) isc_buffer_add(name->buffer, name->length); } void dns_name_toregion(dns_name_t *name, isc_region_t *r) { /* * Make 'r' refer to 'name'. */ REQUIRE(VALID_NAME(name)); REQUIRE(r != NULL); DNS_NAME_TOREGION(name, r); } isc_result_t dns_name_fromtext(dns_name_t *name, isc_buffer_t *source, const dns_name_t *origin, unsigned int options, isc_buffer_t *target) { unsigned char *ndata, *label = NULL; char *tdata; char c; ft_state state; unsigned int value = 0, count = 0; unsigned int n1 = 0, n2 = 0; unsigned int tlen, nrem, nused, digits = 0, labels, tused; isc_boolean_t done; unsigned char *offsets; dns_offsets_t odata; isc_boolean_t downcase; /* * Convert the textual representation of a DNS name at source * into uncompressed wire form stored in target. * * Notes: * Relative domain names will have 'origin' appended to them * unless 'origin' is NULL, in which case relative domain names * will remain relative. */ REQUIRE(VALID_NAME(name)); REQUIRE(ISC_BUFFER_VALID(source)); REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) || (target == NULL && ISC_BUFFER_VALID(name->buffer))); downcase = ISC_TF((options & DNS_NAME_DOWNCASE) != 0); if (target == NULL && name->buffer != NULL) { target = name->buffer; isc_buffer_clear(target); } REQUIRE(BINDABLE(name)); INIT_OFFSETS(name, offsets, odata); offsets[0] = 0; /* * Make 'name' empty in case of failure. */ MAKE_EMPTY(name); /* * Set up the state machine. */ tdata = (char *)source->base + source->current; tlen = isc_buffer_remaininglength(source); tused = 0; ndata = isc_buffer_used(target); nrem = isc_buffer_availablelength(target); if (nrem > 255) nrem = 255; nused = 0; labels = 0; done = ISC_FALSE; state = ft_init; while (nrem > 0 && tlen > 0 && !done) { c = *tdata++; tlen--; tused++; switch (state) { case ft_init: /* * Is this the root name? */ if (c == '.') { if (tlen != 0) return (DNS_R_EMPTYLABEL); labels++; *ndata++ = 0; nrem--; nused++; done = ISC_TRUE; break; } if (c == '@' && tlen == 0) { state = ft_at; break; } /* FALLTHROUGH */ case ft_start: label = ndata; ndata++; nrem--; nused++; count = 0; if (c == '\\') { state = ft_initialescape; break; } state = ft_ordinary; if (nrem == 0) return (ISC_R_NOSPACE); /* FALLTHROUGH */ case ft_ordinary: if (c == '.') { if (count == 0) return (DNS_R_EMPTYLABEL); *label = count; labels++; INSIST(labels <= 127); offsets[labels] = nused; if (tlen == 0) { labels++; *ndata++ = 0; nrem--; nused++; done = ISC_TRUE; } state = ft_start; } else if (c == '\\') { state = ft_escape; } else { if (count >= 63) return (DNS_R_LABELTOOLONG); count++; CONVERTTOASCII(c); if (downcase) c = maptolower[c & 0xff]; *ndata++ = c; nrem--; nused++; } break; case ft_initialescape: if (c == '[') { /* * This looks like a bitstring label, which * was deprecated. Intentionally drop it. */ return (DNS_R_BADLABELTYPE); } state = ft_escape; POST(state); /* FALLTHROUGH */ case ft_escape: if (!isdigit(c & 0xff)) { if (count >= 63) return (DNS_R_LABELTOOLONG); count++; CONVERTTOASCII(c); if (downcase) c = maptolower[c & 0xff]; *ndata++ = c; nrem--; nused++; state = ft_ordinary; break; } digits = 0; value = 0; state = ft_escdecimal; /* FALLTHROUGH */ case ft_escdecimal: if (!isdigit(c & 0xff)) return (DNS_R_BADESCAPE); value *= 10; value += digitvalue[c & 0xff]; digits++; if (digits == 3) { if (value > 255) return (DNS_R_BADESCAPE); if (count >= 63) return (DNS_R_LABELTOOLONG); count++; if (downcase) value = maptolower[value]; *ndata++ = value; nrem--; nused++; state = ft_ordinary; } break; default: FATAL_ERROR(__FILE__, __LINE__, "Unexpected state %d", state); /* Does not return. */ } } if (!done) { if (nrem == 0) return (ISC_R_NOSPACE); INSIST(tlen == 0); if (state != ft_ordinary && state != ft_at) return (ISC_R_UNEXPECTEDEND); if (state == ft_ordinary) { INSIST(count != 0); *label = count; labels++; INSIST(labels <= 127); offsets[labels] = nused; } if (origin != NULL) { if (nrem < origin->length) return (ISC_R_NOSPACE); label = origin->ndata; n1 = origin->length; nrem -= n1; POST(nrem); while (n1 > 0) { n2 = *label++; INSIST(n2 <= 63); /* no bitstring support */ *ndata++ = n2; n1 -= n2 + 1; nused += n2 + 1; while (n2 > 0) { c = *label++; if (downcase) c = maptolower[c & 0xff]; *ndata++ = c; n2--; } labels++; if (n1 > 0) { INSIST(labels <= 127); offsets[labels] = nused; } } if ((origin->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) name->attributes |= DNS_NAMEATTR_ABSOLUTE; } } else name->attributes |= DNS_NAMEATTR_ABSOLUTE; name->ndata = (unsigned char *)target->base + target->used; name->labels = labels; name->length = nused; isc_buffer_forward(source, tused); isc_buffer_add(target, name->length); return (ISC_R_SUCCESS); } #ifdef ISC_PLATFORM_USETHREADS static void free_specific(void *arg) { dns_name_totextfilter_t *mem = arg; isc_mem_put(thread_key_mctx, mem, sizeof(*mem)); /* Stop use being called again. */ (void)isc_thread_key_setspecific(totext_filter_proc_key, NULL); } static void thread_key_mutex_init(void) { RUNTIME_CHECK(isc_mutex_init(&thread_key_mutex) == ISC_R_SUCCESS); } static isc_result_t totext_filter_proc_key_init(void) { isc_result_t result; /* * We need the call to isc_once_do() to support profiled mutex * otherwise thread_key_mutex could be initialized at compile time. */ result = isc_once_do(&once, thread_key_mutex_init); if (result != ISC_R_SUCCESS) return (result); if (!thread_key_initialized) { LOCK(&thread_key_mutex); if (thread_key_mctx == NULL) result = isc_mem_create2(0, 0, &thread_key_mctx, 0); if (result != ISC_R_SUCCESS) goto unlock; isc_mem_setname(thread_key_mctx, "threadkey", NULL); isc_mem_setdestroycheck(thread_key_mctx, ISC_FALSE); if (!thread_key_initialized && isc_thread_key_create(&totext_filter_proc_key, free_specific) != 0) { result = ISC_R_FAILURE; isc_mem_detach(&thread_key_mctx); } else thread_key_initialized = 1; unlock: UNLOCK(&thread_key_mutex); } return (result); } #endif isc_result_t dns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot, isc_buffer_t *target) { unsigned int options = DNS_NAME_MASTERFILE; if (omit_final_dot) options |= DNS_NAME_OMITFINALDOT; return (dns_name_totext2(name, options, target)); } isc_result_t dns_name_toprincipal(dns_name_t *name, isc_buffer_t *target) { return (dns_name_totext2(name, DNS_NAME_OMITFINALDOT, target)); } isc_result_t dns_name_totext2(dns_name_t *name, unsigned int options, isc_buffer_t *target) { unsigned char *ndata; char *tdata; unsigned int nlen, tlen; unsigned char c; unsigned int trem, count; unsigned int labels; isc_boolean_t saw_root = ISC_FALSE; unsigned int oused = target->used; #ifdef ISC_PLATFORM_USETHREADS dns_name_totextfilter_t *mem; dns_name_totextfilter_t totext_filter_proc = NULL; isc_result_t result; #endif isc_boolean_t omit_final_dot = ISC_TF(options & DNS_NAME_OMITFINALDOT); /* * This function assumes the name is in proper uncompressed * wire format. */ REQUIRE(VALID_NAME(name)); REQUIRE(ISC_BUFFER_VALID(target)); #ifdef ISC_PLATFORM_USETHREADS result = totext_filter_proc_key_init(); if (result != ISC_R_SUCCESS) return (result); #endif ndata = name->ndata; nlen = name->length; labels = name->labels; tdata = isc_buffer_used(target); tlen = isc_buffer_availablelength(target); trem = tlen; if (labels == 0 && nlen == 0) { /* * Special handling for an empty name. */ if (trem == 0) return (ISC_R_NOSPACE); /* * The names of these booleans are misleading in this case. * This empty name is not necessarily from the root node of * the DNS root zone, nor is a final dot going to be included. * They need to be set this way, though, to keep the "@" * from being trounced. */ saw_root = ISC_TRUE; omit_final_dot = ISC_FALSE; *tdata++ = '@'; trem--; /* * Skip the while() loop. */ nlen = 0; } else if (nlen == 1 && labels == 1 && *ndata == '\0') { /* * Special handling for the root label. */ if (trem == 0) return (ISC_R_NOSPACE); saw_root = ISC_TRUE; omit_final_dot = ISC_FALSE; *tdata++ = '.'; trem--; /* * Skip the while() loop. */ nlen = 0; } while (labels > 0 && nlen > 0 && trem > 0) { labels--; count = *ndata++; nlen--; if (count == 0) { saw_root = ISC_TRUE; break; } if (count < 64) { INSIST(nlen >= count); while (count > 0) { c = *ndata; switch (c) { /* Special modifiers in zone files. */ case 0x40: /* '@' */ case 0x24: /* '$' */ if ((options & DNS_NAME_MASTERFILE) == 0) goto no_escape; /* FALLTHROUGH */ case 0x22: /* '"' */ case 0x28: /* '(' */ case 0x29: /* ')' */ case 0x2E: /* '.' */ case 0x3B: /* ';' */ case 0x5C: /* '\\' */ if (trem < 2) return (ISC_R_NOSPACE); *tdata++ = '\\'; CONVERTFROMASCII(c); *tdata++ = c; ndata++; trem -= 2; nlen--; break; no_escape: default: if (c > 0x20 && c < 0x7f) { if (trem == 0) return (ISC_R_NOSPACE); CONVERTFROMASCII(c); *tdata++ = c; ndata++; trem--; nlen--; } else { if (trem < 4) return (ISC_R_NOSPACE); *tdata++ = 0x5c; *tdata++ = 0x30 + ((c / 100) % 10); *tdata++ = 0x30 + ((c / 10) % 10); *tdata++ = 0x30 + (c % 10); trem -= 4; ndata++; nlen--; } } count--; } } else { FATAL_ERROR(__FILE__, __LINE__, "Unexpected label type %02x", count); /* NOTREACHED */ } /* * The following assumes names are absolute. If not, we * fix things up later. Note that this means that in some * cases one more byte of text buffer is required than is * needed in the final output. */ if (trem == 0) return (ISC_R_NOSPACE); *tdata++ = '.'; trem--; } if (nlen != 0 && trem == 0) return (ISC_R_NOSPACE); if (!saw_root || omit_final_dot) trem++; isc_buffer_add(target, tlen - trem); #ifdef ISC_PLATFORM_USETHREADS mem = isc_thread_key_getspecific(totext_filter_proc_key); if (mem != NULL) totext_filter_proc = *mem; #endif if (totext_filter_proc != NULL) return ((*totext_filter_proc)(target, oused, saw_root)); return (ISC_R_SUCCESS); } isc_result_t dns_name_tofilenametext(dns_name_t *name, isc_boolean_t omit_final_dot, isc_buffer_t *target) { unsigned char *ndata; char *tdata; unsigned int nlen, tlen; unsigned char c; unsigned int trem, count; unsigned int labels; /* * This function assumes the name is in proper uncompressed * wire format. */ REQUIRE(VALID_NAME(name)); REQUIRE((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0); REQUIRE(ISC_BUFFER_VALID(target)); ndata = name->ndata; nlen = name->length; labels = name->labels; tdata = isc_buffer_used(target); tlen = isc_buffer_availablelength(target); trem = tlen; if (nlen == 1 && labels == 1 && *ndata == '\0') { /* * Special handling for the root label. */ if (trem == 0) return (ISC_R_NOSPACE); omit_final_dot = ISC_FALSE; *tdata++ = '.'; trem--; /* * Skip the while() loop. */ nlen = 0; } while (labels > 0 && nlen > 0 && trem > 0) { labels--; count = *ndata++; nlen--; if (count == 0) break; if (count < 64) { INSIST(nlen >= count); while (count > 0) { c = *ndata; if ((c >= 0x30 && c <= 0x39) || /* digit */ (c >= 0x41 && c <= 0x5A) || /* uppercase */ (c >= 0x61 && c <= 0x7A) || /* lowercase */ c == 0x2D || /* hyphen */ c == 0x5F) /* underscore */ { if (trem == 0) return (ISC_R_NOSPACE); /* downcase */ if (c >= 0x41 && c <= 0x5A) c += 0x20; CONVERTFROMASCII(c); *tdata++ = c; ndata++; trem--; nlen--; } else { if (trem < 3) return (ISC_R_NOSPACE); sprintf(tdata, "%%%02X", c); tdata += 3; trem -= 3; ndata++; nlen--; } count--; } } else { FATAL_ERROR(__FILE__, __LINE__, "Unexpected label type %02x", count); /* NOTREACHED */ } /* * The following assumes names are absolute. If not, we * fix things up later. Note that this means that in some * cases one more byte of text buffer is required than is * needed in the final output. */ if (trem == 0) return (ISC_R_NOSPACE); *tdata++ = '.'; trem--; } if (nlen != 0 && trem == 0) return (ISC_R_NOSPACE); if (omit_final_dot) trem++; isc_buffer_add(target, tlen - trem); return (ISC_R_SUCCESS); } isc_result_t dns_name_downcase(dns_name_t *source, dns_name_t *name, isc_buffer_t *target) { unsigned char *sndata, *ndata; unsigned int nlen, count, labels; isc_buffer_t buffer; /* * Downcase 'source'. */ REQUIRE(VALID_NAME(source)); REQUIRE(VALID_NAME(name)); if (source == name) { REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0); isc_buffer_init(&buffer, source->ndata, source->length); target = &buffer; ndata = source->ndata; } else { REQUIRE(BINDABLE(name)); REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) || (target == NULL && ISC_BUFFER_VALID(name->buffer))); if (target == NULL) { target = name->buffer; isc_buffer_clear(name->buffer); } ndata = (unsigned char *)target->base + target->used; name->ndata = ndata; } sndata = source->ndata; nlen = source->length; labels = source->labels; if (nlen > (target->length - target->used)) { MAKE_EMPTY(name); return (ISC_R_NOSPACE); } while (labels > 0 && nlen > 0) { labels--; count = *sndata++; *ndata++ = count; nlen--; if (count < 64) { INSIST(nlen >= count); while (count > 0) { *ndata++ = maptolower[(*sndata++)]; nlen--; count--; } } else { FATAL_ERROR(__FILE__, __LINE__, "Unexpected label type %02x", count); /* Does not return. */ } } if (source != name) { name->labels = source->labels; name->length = source->length; if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) name->attributes = DNS_NAMEATTR_ABSOLUTE; else name->attributes = 0; if (name->labels > 0 && name->offsets != NULL) set_offsets(name, name->offsets, NULL); } isc_buffer_add(target, name->length); return (ISC_R_SUCCESS); } static void set_offsets(const dns_name_t *name, unsigned char *offsets, dns_name_t *set_name) { unsigned int offset, count, length, nlabels; unsigned char *ndata; isc_boolean_t absolute; ndata = name->ndata; length = name->length; offset = 0; nlabels = 0; absolute = ISC_FALSE; while (offset != length) { INSIST(nlabels < 128); offsets[nlabels++] = offset; count = *ndata++; offset++; INSIST(count <= 63); offset += count; ndata += count; INSIST(offset <= length); if (count == 0) { absolute = ISC_TRUE; break; } } if (set_name != NULL) { INSIST(set_name == name); set_name->labels = nlabels; set_name->length = offset; if (absolute) set_name->attributes |= DNS_NAMEATTR_ABSOLUTE; else set_name->attributes &= ~DNS_NAMEATTR_ABSOLUTE; } INSIST(nlabels == name->labels); INSIST(offset == name->length); } isc_result_t dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, dns_decompress_t *dctx, unsigned int options, isc_buffer_t *target) { unsigned char *cdata, *ndata; unsigned int cused; /* Bytes of compressed name data used */ unsigned int nused, labels, n, nmax; unsigned int current, new_current, biggest_pointer; isc_boolean_t done; fw_state state = fw_start; unsigned int c; unsigned char *offsets; dns_offsets_t odata; isc_boolean_t downcase; isc_boolean_t seen_pointer; /* * Copy the possibly-compressed name at source into target, * decompressing it. Loop prevention is performed by checking * the new pointer against biggest_pointer. */ REQUIRE(VALID_NAME(name)); REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) || (target == NULL && ISC_BUFFER_VALID(name->buffer))); downcase = ISC_TF((options & DNS_NAME_DOWNCASE) != 0); if (target == NULL && name->buffer != NULL) { target = name->buffer; isc_buffer_clear(target); } REQUIRE(dctx != NULL); REQUIRE(BINDABLE(name)); INIT_OFFSETS(name, offsets, odata); /* * Make 'name' empty in case of failure. */ MAKE_EMPTY(name); /* * Initialize things to make the compiler happy; they're not required. */ n = 0; new_current = 0; /* * Set up. */ labels = 0; done = ISC_FALSE; ndata = isc_buffer_used(target); nused = 0; seen_pointer = ISC_FALSE; /* * Find the maximum number of uncompressed target name * bytes we are willing to generate. This is the smaller * of the available target buffer length and the * maximum legal domain name length (255). */ nmax = isc_buffer_availablelength(target); if (nmax > DNS_NAME_MAXWIRE) nmax = DNS_NAME_MAXWIRE; cdata = isc_buffer_current(source); cused = 0; current = source->current; biggest_pointer = current; /* * Note: The following code is not optimized for speed, but * rather for correctness. Speed will be addressed in the future. */ while (current < source->active && !done) { c = *cdata++; current++; if (!seen_pointer) cused++; switch (state) { case fw_start: if (c < 64) { offsets[labels] = nused; labels++; if (nused + c + 1 > nmax) goto full; nused += c + 1; *ndata++ = c; if (c == 0) done = ISC_TRUE; n = c; state = fw_ordinary; } else if (c >= 128 && c < 192) { /* * 14 bit local compression pointer. * Local compression is no longer an * IETF draft. */ return (DNS_R_BADLABELTYPE); } else if (c >= 192) { /* * Ordinary 14-bit pointer. */ if ((dctx->allowed & DNS_COMPRESS_GLOBAL14) == 0) return (DNS_R_DISALLOWED); new_current = c & 0x3F; state = fw_newcurrent; } else return (DNS_R_BADLABELTYPE); break; case fw_ordinary: if (downcase) c = maptolower[c]; *ndata++ = c; n--; if (n == 0) state = fw_start; break; case fw_newcurrent: new_current *= 256; new_current += c; if (new_current >= biggest_pointer) return (DNS_R_BADPOINTER); biggest_pointer = new_current; current = new_current; cdata = (unsigned char *)source->base + current; seen_pointer = ISC_TRUE; state = fw_start; break; default: FATAL_ERROR(__FILE__, __LINE__, "Unknown state %d", state); /* Does not return. */ } } if (!done) return (ISC_R_UNEXPECTEDEND); name->ndata = (unsigned char *)target->base + target->used; name->labels = labels; name->length = nused; name->attributes |= DNS_NAMEATTR_ABSOLUTE; isc_buffer_forward(source, cused); isc_buffer_add(target, name->length); return (ISC_R_SUCCESS); full: if (nmax == DNS_NAME_MAXWIRE) /* * The name did not fit even though we had a buffer * big enough to fit a maximum-length name. */ return (DNS_R_NAMETOOLONG); else /* * The name might fit if only the caller could give us a * big enough buffer. */ return (ISC_R_NOSPACE); } isc_result_t dns_name_towire(const dns_name_t *name, dns_compress_t *cctx, isc_buffer_t *target) { unsigned int methods; isc_uint16_t offset; dns_name_t gp; /* Global compression prefix */ isc_boolean_t gf; /* Global compression target found */ isc_uint16_t go; /* Global compression offset */ dns_offsets_t clo; dns_name_t clname; /* * Convert 'name' into wire format, compressing it as specified by the * compression context 'cctx', and storing the result in 'target'. */ REQUIRE(VALID_NAME(name)); REQUIRE(cctx != NULL); REQUIRE(ISC_BUFFER_VALID(target)); /* * If 'name' doesn't have an offsets table, make a clone which * has one. */ if (name->offsets == NULL) { #if defined(__clang__) && \ ( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2)) memset(&clname, 0, sizeof(clname)); #endif DNS_NAME_INIT(&clname, clo); dns_name_clone(name, &clname); name = &clname; } DNS_NAME_INIT(&gp, NULL); offset = target->used; /*XXX*/ methods = dns_compress_getmethods(cctx); if ((name->attributes & DNS_NAMEATTR_NOCOMPRESS) == 0 && (methods & DNS_COMPRESS_GLOBAL14) != 0) gf = dns_compress_findglobal(cctx, name, &gp, &go); else gf = ISC_FALSE; /* * If the offset is too high for 14 bit global compression, we're * out of luck. */ if (gf && go >= 0x4000) gf = ISC_FALSE; /* * Will the compression pointer reduce the message size? */ if (gf && (gp.length + 2) >= name->length) gf = ISC_FALSE; if (gf) { if (target->length - target->used < gp.length) return (ISC_R_NOSPACE); (void)memmove((unsigned char *)target->base + target->used, gp.ndata, (size_t)gp.length); isc_buffer_add(target, gp.length); go |= 0xc000; if (target->length - target->used < 2) return (ISC_R_NOSPACE); isc_buffer_putuint16(target, go); if (gp.length != 0) dns_compress_add(cctx, name, &gp, offset); } else { if (target->length - target->used < name->length) return (ISC_R_NOSPACE); (void)memmove((unsigned char *)target->base + target->used, name->ndata, (size_t)name->length); isc_buffer_add(target, name->length); dns_compress_add(cctx, name, name, offset); } return (ISC_R_SUCCESS); } isc_result_t dns_name_concatenate(dns_name_t *prefix, dns_name_t *suffix, dns_name_t *name, isc_buffer_t *target) { unsigned char *ndata, *offsets; unsigned int nrem, labels, prefix_length, length; isc_boolean_t copy_prefix = ISC_TRUE; isc_boolean_t copy_suffix = ISC_TRUE; isc_boolean_t absolute = ISC_FALSE; dns_name_t tmp_name; dns_offsets_t odata; /* * Concatenate 'prefix' and 'suffix'. */ REQUIRE(prefix == NULL || VALID_NAME(prefix)); REQUIRE(suffix == NULL || VALID_NAME(suffix)); REQUIRE(name == NULL || VALID_NAME(name)); REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) || (target == NULL && name != NULL && ISC_BUFFER_VALID(name->buffer))); if (prefix == NULL || prefix->labels == 0) copy_prefix = ISC_FALSE; if (suffix == NULL || suffix->labels == 0) copy_suffix = ISC_FALSE; if (copy_prefix && (prefix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) { absolute = ISC_TRUE; REQUIRE(!copy_suffix); } if (name == NULL) { DNS_NAME_INIT(&tmp_name, odata); name = &tmp_name; } if (target == NULL) { INSIST(name->buffer != NULL); target = name->buffer; isc_buffer_clear(name->buffer); } REQUIRE(BINDABLE(name)); /* * Set up. */ nrem = target->length - target->used; ndata = (unsigned char *)target->base + target->used; if (nrem > DNS_NAME_MAXWIRE) nrem = DNS_NAME_MAXWIRE; length = 0; prefix_length = 0; labels = 0; if (copy_prefix) { prefix_length = prefix->length; length += prefix_length; labels += prefix->labels; } if (copy_suffix) { length += suffix->length; labels += suffix->labels; } if (length > DNS_NAME_MAXWIRE) { MAKE_EMPTY(name); return (DNS_R_NAMETOOLONG); } if (length > nrem) { MAKE_EMPTY(name); return (ISC_R_NOSPACE); } if (copy_suffix) { if ((suffix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) absolute = ISC_TRUE; memmove(ndata + prefix_length, suffix->ndata, suffix->length); } /* * If 'prefix' and 'name' are the same object, and the object has * a dedicated buffer, and we're using it, then we don't have to * copy anything. */ if (copy_prefix && (prefix != name || prefix->buffer != target)) memmove(ndata, prefix->ndata, prefix_length); name->ndata = ndata; name->labels = labels; name->length = length; if (absolute) name->attributes = DNS_NAMEATTR_ABSOLUTE; else name->attributes = 0; if (name->labels > 0 && name->offsets != NULL) { INIT_OFFSETS(name, offsets, odata); set_offsets(name, offsets, NULL); } isc_buffer_add(target, name->length); return (ISC_R_SUCCESS); } void dns_name_split(dns_name_t *name, unsigned int suffixlabels, dns_name_t *prefix, dns_name_t *suffix) { unsigned int splitlabel; REQUIRE(VALID_NAME(name)); REQUIRE(suffixlabels > 0); REQUIRE(suffixlabels < name->labels); REQUIRE(prefix != NULL || suffix != NULL); REQUIRE(prefix == NULL || (VALID_NAME(prefix) && BINDABLE(prefix))); REQUIRE(suffix == NULL || (VALID_NAME(suffix) && BINDABLE(suffix))); splitlabel = name->labels - suffixlabels; if (prefix != NULL) dns_name_getlabelsequence(name, 0, splitlabel, prefix); if (suffix != NULL) dns_name_getlabelsequence(name, splitlabel, suffixlabels, suffix); return; } isc_result_t dns_name_dup(const dns_name_t *source, isc_mem_t *mctx, dns_name_t *target) { /* * Make 'target' a dynamically allocated copy of 'source'. */ REQUIRE(VALID_NAME(source)); REQUIRE(source->length > 0); REQUIRE(VALID_NAME(target)); REQUIRE(BINDABLE(target)); /* * Make 'target' empty in case of failure. */ MAKE_EMPTY(target); target->ndata = isc_mem_get(mctx, source->length); if (target->ndata == NULL) return (ISC_R_NOMEMORY); memmove(target->ndata, source->ndata, source->length); target->length = source->length; target->labels = source->labels; target->attributes = DNS_NAMEATTR_DYNAMIC; if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) target->attributes |= DNS_NAMEATTR_ABSOLUTE; if (target->offsets != NULL) { if (source->offsets != NULL) memmove(target->offsets, source->offsets, source->labels); else set_offsets(target, target->offsets, NULL); } return (ISC_R_SUCCESS); } isc_result_t dns_name_dupwithoffsets(dns_name_t *source, isc_mem_t *mctx, dns_name_t *target) { /* * Make 'target' a read-only dynamically allocated copy of 'source'. * 'target' will also have a dynamically allocated offsets table. */ REQUIRE(VALID_NAME(source)); REQUIRE(source->length > 0); REQUIRE(VALID_NAME(target)); REQUIRE(BINDABLE(target)); REQUIRE(target->offsets == NULL); /* * Make 'target' empty in case of failure. */ MAKE_EMPTY(target); target->ndata = isc_mem_get(mctx, source->length + source->labels); if (target->ndata == NULL) return (ISC_R_NOMEMORY); memmove(target->ndata, source->ndata, source->length); target->length = source->length; target->labels = source->labels; target->attributes = DNS_NAMEATTR_DYNAMIC | DNS_NAMEATTR_DYNOFFSETS | DNS_NAMEATTR_READONLY; if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) target->attributes |= DNS_NAMEATTR_ABSOLUTE; target->offsets = target->ndata + source->length; if (source->offsets != NULL) memmove(target->offsets, source->offsets, source->labels); else set_offsets(target, target->offsets, NULL); return (ISC_R_SUCCESS); } void dns_name_free(dns_name_t *name, isc_mem_t *mctx) { size_t size; /* * Free 'name'. */ REQUIRE(VALID_NAME(name)); REQUIRE((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0); size = name->length; if ((name->attributes & DNS_NAMEATTR_DYNOFFSETS) != 0) size += name->labels; isc_mem_put(mctx, name->ndata, size); dns_name_invalidate(name); } isc_result_t dns_name_digest(dns_name_t *name, dns_digestfunc_t digest, void *arg) { dns_name_t downname; unsigned char data[256]; isc_buffer_t buffer; isc_result_t result; isc_region_t r; /* * Send 'name' in DNSSEC canonical form to 'digest'. */ REQUIRE(VALID_NAME(name)); REQUIRE(digest != NULL); #if defined(__clang__) && \ ( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2)) memset(&downname, 0, sizeof(downname)); #endif DNS_NAME_INIT(&downname, NULL); isc_buffer_init(&buffer, data, sizeof(data)); result = dns_name_downcase(name, &downname, &buffer); if (result != ISC_R_SUCCESS) return (result); isc_buffer_usedregion(&buffer, &r); return ((digest)(arg, &r)); } isc_boolean_t dns_name_dynamic(dns_name_t *name) { REQUIRE(VALID_NAME(name)); /* * Returns whether there is dynamic memory associated with this name. */ return ((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0 ? ISC_TRUE : ISC_FALSE); } isc_result_t dns_name_print(dns_name_t *name, FILE *stream) { isc_result_t result; isc_buffer_t b; isc_region_t r; char t[1024]; /* * Print 'name' on 'stream'. */ REQUIRE(VALID_NAME(name)); isc_buffer_init(&b, t, sizeof(t)); result = dns_name_totext(name, ISC_FALSE, &b); if (result != ISC_R_SUCCESS) return (result); isc_buffer_usedregion(&b, &r); fprintf(stream, "%.*s", (int)r.length, (char *)r.base); return (ISC_R_SUCCESS); } isc_result_t dns_name_settotextfilter(dns_name_totextfilter_t proc) { #ifdef ISC_PLATFORM_USETHREADS isc_result_t result; dns_name_totextfilter_t *mem; int res; result = totext_filter_proc_key_init(); if (result != ISC_R_SUCCESS) return (result); /* * If we already have been here set / clear as appropriate. * Otherwise allocate memory. */ mem = isc_thread_key_getspecific(totext_filter_proc_key); if (mem != NULL && proc != NULL) { *mem = proc; return (ISC_R_SUCCESS); } if (proc == NULL) { isc_mem_put(thread_key_mctx, mem, sizeof(*mem)); res = isc_thread_key_setspecific(totext_filter_proc_key, NULL); if (res != 0) result = ISC_R_UNEXPECTED; return (result); } mem = isc_mem_get(thread_key_mctx, sizeof(*mem)); if (mem == NULL) return (ISC_R_NOMEMORY); *mem = proc; if (isc_thread_key_setspecific(totext_filter_proc_key, mem) != 0) { isc_mem_put(thread_key_mctx, mem, sizeof(*mem)); result = ISC_R_UNEXPECTED; } return (result); #else totext_filter_proc = proc; return (ISC_R_SUCCESS); #endif } void dns_name_format(dns_name_t *name, char *cp, unsigned int size) { isc_result_t result; isc_buffer_t buf; REQUIRE(size > 0); /* * Leave room for null termination after buffer. */ isc_buffer_init(&buf, cp, size - 1); result = dns_name_totext(name, ISC_TRUE, &buf); if (result == ISC_R_SUCCESS) { /* * Null terminate. */ isc_region_t r; isc_buffer_usedregion(&buf, &r); ((char *) r.base)[r.length] = '\0'; } else snprintf(cp, size, ""); } /* * dns_name_tostring() -- similar to dns_name_format() but allocates its own * memory. */ isc_result_t dns_name_tostring(dns_name_t *name, char **target, isc_mem_t *mctx) { isc_result_t result; isc_buffer_t buf; isc_region_t reg; char *p, txt[DNS_NAME_FORMATSIZE]; REQUIRE(VALID_NAME(name)); REQUIRE(target != NULL && *target == NULL); isc_buffer_init(&buf, txt, sizeof(txt)); result = dns_name_totext(name, ISC_FALSE, &buf); if (result != ISC_R_SUCCESS) return (result); isc_buffer_usedregion(&buf, ®); p = isc_mem_allocate(mctx, reg.length + 1); if (p == NULL) return (ISC_R_NOMEMORY); memmove(p, (char *) reg.base, (int) reg.length); p[reg.length] = '\0'; *target = p; return (ISC_R_SUCCESS); } /* * dns_name_fromstring() -- convert directly from a string to a name, * allocating memory as needed */ isc_result_t dns_name_fromstring(dns_name_t *target, const char *src, unsigned int options, isc_mem_t *mctx) { return (dns_name_fromstring2(target, src, dns_rootname, options, mctx)); } isc_result_t dns_name_fromstring2(dns_name_t *target, const char *src, const dns_name_t *origin, unsigned int options, isc_mem_t *mctx) { isc_result_t result; isc_buffer_t buf; dns_fixedname_t fn; dns_name_t *name; REQUIRE(src != NULL); isc_buffer_constinit(&buf, src, strlen(src)); isc_buffer_add(&buf, strlen(src)); if (BINDABLE(target) && target->buffer != NULL) name = target; else { dns_fixedname_init(&fn); name = dns_fixedname_name(&fn); } result = dns_name_fromtext(name, &buf, origin, options, NULL); if (result != ISC_R_SUCCESS) return (result); if (name != target) result = dns_name_dupwithoffsets(name, mctx, target); return (result); } isc_result_t dns_name_copy(dns_name_t *source, dns_name_t *dest, isc_buffer_t *target) { unsigned char *ndata; /* * Make dest a copy of source. */ REQUIRE(VALID_NAME(source)); REQUIRE(VALID_NAME(dest)); REQUIRE(target != NULL || dest->buffer != NULL); if (target == NULL) { target = dest->buffer; isc_buffer_clear(dest->buffer); } REQUIRE(BINDABLE(dest)); /* * Set up. */ if (target->length - target->used < source->length) return (ISC_R_NOSPACE); ndata = (unsigned char *)target->base + target->used; dest->ndata = target->base; memmove(ndata, source->ndata, source->length); dest->ndata = ndata; dest->labels = source->labels; dest->length = source->length; if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) dest->attributes = DNS_NAMEATTR_ABSOLUTE; else dest->attributes = 0; if (dest->labels > 0 && dest->offsets != NULL) { if (source->offsets != NULL) memmove(dest->offsets, source->offsets, source->labels); else set_offsets(dest, dest->offsets, NULL); } isc_buffer_add(target, dest->length); return (ISC_R_SUCCESS); } void dns_name_destroy(void) { #ifdef ISC_PLATFORM_USETHREADS RUNTIME_CHECK(isc_once_do(&once, thread_key_mutex_init) == ISC_R_SUCCESS); LOCK(&thread_key_mutex); if (thread_key_initialized) { isc_mem_detach(&thread_key_mctx); isc_thread_key_delete(totext_filter_proc_key); thread_key_initialized = 0; } UNLOCK(&thread_key_mutex); #endif } /* * Service Discovery Prefixes RFC 6763. */ static unsigned char b_dns_sd_udp_data[] = "\001b\007_dns-sd\004_udp"; static unsigned char b_dns_sd_udp_offsets[] = { 0, 2, 10 }; static unsigned char db_dns_sd_udp_data[] = "\002db\007_dns-sd\004_udp"; static unsigned char db_dns_sd_udp_offsets[] = { 0, 3, 11 }; static unsigned char r_dns_sd_udp_data[] = "\001r\007_dns-sd\004_udp"; static unsigned char r_dns_sd_udp_offsets[] = { 0, 2, 10 }; static unsigned char dr_dns_sd_udp_data[] = "\002dr\007_dns-sd\004_udp"; static unsigned char dr_dns_sd_udp_offsets[] = { 0, 3, 11 }; static unsigned char lb_dns_sd_udp_data[] = "\002lb\007_dns-sd\004_udp"; static unsigned char lb_dns_sd_udp_offsets[] = { 0, 3, 11 }; static const dns_name_t dns_sd[] = { { DNS_NAME_MAGIC, b_dns_sd_udp_data, 15, 3, DNS_NAMEATTR_READONLY, b_dns_sd_udp_offsets, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} }, { DNS_NAME_MAGIC, db_dns_sd_udp_data, 16, 3, DNS_NAMEATTR_READONLY, db_dns_sd_udp_offsets, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} }, { DNS_NAME_MAGIC, r_dns_sd_udp_data, 15, 3, DNS_NAMEATTR_READONLY, r_dns_sd_udp_offsets, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} }, { DNS_NAME_MAGIC, dr_dns_sd_udp_data, 16, 3, DNS_NAMEATTR_READONLY, dr_dns_sd_udp_offsets, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} }, { DNS_NAME_MAGIC, lb_dns_sd_udp_data, 16, 3, DNS_NAMEATTR_READONLY, lb_dns_sd_udp_offsets, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} } }; isc_boolean_t dns_name_isdnssd(const dns_name_t *name) { size_t i; dns_name_t prefix; if (dns_name_countlabels(name) > 3U) { dns_name_init(&prefix, NULL); dns_name_getlabelsequence(name, 0, 3, &prefix); for (i = 0; i < (sizeof(dns_sd)/sizeof(dns_sd[0])); i++) if (dns_name_equal(&prefix, &dns_sd[i])) return (ISC_TRUE); } return (ISC_FALSE); } bind9-9.10.3.dfsg.P4/lib/dns/log.c0000644000470500017500000000506112664710322015652 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ /* Principal Authors: DCL */ #include #include #include /*% * When adding a new category, be sure to add the appropriate * \#define to . */ LIBDNS_EXTERNAL_DATA isc_logcategory_t dns_categories[] = { { "notify", 0 }, { "database", 0 }, { "security", 0 }, { "_placeholder", 0 }, { "dnssec", 0 }, { "resolver", 0 }, { "xfer-in", 0 }, { "xfer-out", 0 }, { "dispatch", 0 }, { "lame-servers", 0 }, { "delegation-only", 0 }, { "edns-disabled", 0 }, { "rpz", 0 }, { "rate-limit", 0 }, { "cname", 0 }, { "spill", 0 }, { NULL, 0 } }; /*% * When adding a new module, be sure to add the appropriate * \#define to . */ LIBDNS_EXTERNAL_DATA isc_logmodule_t dns_modules[] = { { "dns/db", 0 }, { "dns/rbtdb", 0 }, { "dns/rbtdb64", 0 }, { "dns/rbt", 0 }, { "dns/rdata", 0 }, { "dns/master", 0 }, { "dns/message", 0 }, { "dns/cache", 0 }, { "dns/config", 0 }, { "dns/resolver", 0 }, { "dns/zone", 0 }, { "dns/journal", 0 }, { "dns/adb", 0 }, { "dns/xfrin", 0 }, { "dns/xfrout", 0 }, { "dns/acl", 0 }, { "dns/validator", 0 }, { "dns/dispatch", 0 }, { "dns/request", 0 }, { "dns/masterdump", 0 }, { "dns/tsig", 0 }, { "dns/tkey", 0 }, { "dns/sdb", 0 }, { "dns/diff", 0 }, { "dns/hints", 0 }, { "dns/acache", 0 }, { "dns/dlz", 0 }, { "dns/dnssec", 0 }, { "dns/crypto", 0 }, { "dns/packets", 0 }, { NULL, 0 } }; LIBDNS_EXTERNAL_DATA isc_log_t *dns_lctx = NULL; void dns_log_init(isc_log_t *lctx) { REQUIRE(lctx != NULL); isc_log_registercategories(lctx, dns_categories); isc_log_registermodules(lctx, dns_modules); } void dns_log_setcontext(isc_log_t *lctx) { dns_lctx = lctx; } bind9-9.10.3.dfsg.P4/lib/dns/message.c0000644000470500017500000027330112664710322016521 0ustar lamontlamont/* * Copyright (C) 2004-2016 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ /*** *** Imports ***/ #include #include #include #include #include #include /* Required for HP/UX (and others?) */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef SKAN_MSG_DEBUG static void hexdump(const char *msg, const char *msg2, void *base, size_t len) { unsigned char *p; unsigned int cnt; p = base; cnt = 0; printf("*** %s [%s] (%u bytes @ %p)\n", msg, msg2, len, base); while (cnt < len) { if (cnt % 16 == 0) printf("%p: ", p); else if (cnt % 8 == 0) printf(" |"); printf(" %02x %c", *p, (isprint(*p) ? *p : ' ')); p++; cnt++; if (cnt % 16 == 0) printf("\n"); } if (cnt % 16 != 0) printf("\n"); } #endif #define DNS_MESSAGE_OPCODE_MASK 0x7800U #define DNS_MESSAGE_OPCODE_SHIFT 11 #define DNS_MESSAGE_RCODE_MASK 0x000fU #define DNS_MESSAGE_FLAG_MASK 0x8ff0U #define DNS_MESSAGE_EDNSRCODE_MASK 0xff000000U #define DNS_MESSAGE_EDNSRCODE_SHIFT 24 #define DNS_MESSAGE_EDNSVERSION_MASK 0x00ff0000U #define DNS_MESSAGE_EDNSVERSION_SHIFT 16 #define VALID_NAMED_SECTION(s) (((s) > DNS_SECTION_ANY) \ && ((s) < DNS_SECTION_MAX)) #define VALID_SECTION(s) (((s) >= DNS_SECTION_ANY) \ && ((s) < DNS_SECTION_MAX)) #define ADD_STRING(b, s) {if (strlen(s) >= \ isc_buffer_availablelength(b)) \ return(ISC_R_NOSPACE); else \ isc_buffer_putstr(b, s);} #define VALID_PSEUDOSECTION(s) (((s) >= DNS_PSEUDOSECTION_ANY) \ && ((s) < DNS_PSEUDOSECTION_MAX)) #define OPTOUT(x) (((x)->attributes & DNS_RDATASETATTR_OPTOUT) != 0) /*% * This is the size of each individual scratchpad buffer, and the numbers * of various block allocations used within the server. * XXXMLG These should come from a config setting. */ #define SCRATCHPAD_SIZE 512 #define NAME_COUNT 8 #define OFFSET_COUNT 4 #define RDATA_COUNT 8 #define RDATALIST_COUNT 8 #define RDATASET_COUNT RDATALIST_COUNT /*% * Text representation of the different items, for message_totext * functions. */ static const char *sectiontext[] = { "QUESTION", "ANSWER", "AUTHORITY", "ADDITIONAL" }; static const char *updsectiontext[] = { "ZONE", "PREREQUISITE", "UPDATE", "ADDITIONAL" }; static const char *opcodetext[] = { "QUERY", "IQUERY", "STATUS", "RESERVED3", "NOTIFY", "UPDATE", "RESERVED6", "RESERVED7", "RESERVED8", "RESERVED9", "RESERVED10", "RESERVED11", "RESERVED12", "RESERVED13", "RESERVED14", "RESERVED15" }; static const char *rcodetext[] = { "NOERROR", "FORMERR", "SERVFAIL", "NXDOMAIN", "NOTIMP", "REFUSED", "YXDOMAIN", "YXRRSET", "NXRRSET", "NOTAUTH", "NOTZONE", "RESERVED11", "RESERVED12", "RESERVED13", "RESERVED14", "RESERVED15", "BADVERS" }; /*% * "helper" type, which consists of a block of some type, and is linkable. * For it to work, sizeof(dns_msgblock_t) must be a multiple of the pointer * size, or the allocated elements will not be aligned correctly. */ struct dns_msgblock { unsigned int count; unsigned int remaining; ISC_LINK(dns_msgblock_t) link; }; /* dynamically sized */ static inline dns_msgblock_t * msgblock_allocate(isc_mem_t *, unsigned int, unsigned int); #define msgblock_get(block, type) \ ((type *)msgblock_internalget(block, sizeof(type))) static inline void * msgblock_internalget(dns_msgblock_t *, unsigned int); static inline void msgblock_reset(dns_msgblock_t *); static inline void msgblock_free(isc_mem_t *, dns_msgblock_t *, unsigned int); /* * Allocate a new dns_msgblock_t, and return a pointer to it. If no memory * is free, return NULL. */ static inline dns_msgblock_t * msgblock_allocate(isc_mem_t *mctx, unsigned int sizeof_type, unsigned int count) { dns_msgblock_t *block; unsigned int length; length = sizeof(dns_msgblock_t) + (sizeof_type * count); block = isc_mem_get(mctx, length); if (block == NULL) return (NULL); block->count = count; block->remaining = count; ISC_LINK_INIT(block, link); return (block); } /* * Return an element from the msgblock. If no more are available, return * NULL. */ static inline void * msgblock_internalget(dns_msgblock_t *block, unsigned int sizeof_type) { void *ptr; if (block == NULL || block->remaining == 0) return (NULL); block->remaining--; ptr = (((unsigned char *)block) + sizeof(dns_msgblock_t) + (sizeof_type * block->remaining)); return (ptr); } static inline void msgblock_reset(dns_msgblock_t *block) { block->remaining = block->count; } /* * Release memory associated with a message block. */ static inline void msgblock_free(isc_mem_t *mctx, dns_msgblock_t *block, unsigned int sizeof_type) { unsigned int length; length = sizeof(dns_msgblock_t) + (sizeof_type * block->count); isc_mem_put(mctx, block, length); } /* * Allocate a new dynamic buffer, and attach it to this message as the * "current" buffer. (which is always the last on the list, for our * uses) */ static inline isc_result_t newbuffer(dns_message_t *msg, unsigned int size) { isc_result_t result; isc_buffer_t *dynbuf; dynbuf = NULL; result = isc_buffer_allocate(msg->mctx, &dynbuf, size); if (result != ISC_R_SUCCESS) return (ISC_R_NOMEMORY); ISC_LIST_APPEND(msg->scratchpad, dynbuf, link); return (ISC_R_SUCCESS); } static inline isc_buffer_t * currentbuffer(dns_message_t *msg) { isc_buffer_t *dynbuf; dynbuf = ISC_LIST_TAIL(msg->scratchpad); INSIST(dynbuf != NULL); return (dynbuf); } static inline void releaserdata(dns_message_t *msg, dns_rdata_t *rdata) { ISC_LIST_PREPEND(msg->freerdata, rdata, link); } static inline dns_rdata_t * newrdata(dns_message_t *msg) { dns_msgblock_t *msgblock; dns_rdata_t *rdata; rdata = ISC_LIST_HEAD(msg->freerdata); if (rdata != NULL) { ISC_LIST_UNLINK(msg->freerdata, rdata, link); return (rdata); } msgblock = ISC_LIST_TAIL(msg->rdatas); rdata = msgblock_get(msgblock, dns_rdata_t); if (rdata == NULL) { msgblock = msgblock_allocate(msg->mctx, sizeof(dns_rdata_t), RDATA_COUNT); if (msgblock == NULL) return (NULL); ISC_LIST_APPEND(msg->rdatas, msgblock, link); rdata = msgblock_get(msgblock, dns_rdata_t); } dns_rdata_init(rdata); return (rdata); } static inline void releaserdatalist(dns_message_t *msg, dns_rdatalist_t *rdatalist) { ISC_LIST_PREPEND(msg->freerdatalist, rdatalist, link); } static inline dns_rdatalist_t * newrdatalist(dns_message_t *msg) { dns_msgblock_t *msgblock; dns_rdatalist_t *rdatalist; rdatalist = ISC_LIST_HEAD(msg->freerdatalist); if (rdatalist != NULL) { ISC_LIST_UNLINK(msg->freerdatalist, rdatalist, link); goto out; } msgblock = ISC_LIST_TAIL(msg->rdatalists); rdatalist = msgblock_get(msgblock, dns_rdatalist_t); if (rdatalist == NULL) { msgblock = msgblock_allocate(msg->mctx, sizeof(dns_rdatalist_t), RDATALIST_COUNT); if (msgblock == NULL) return (NULL); ISC_LIST_APPEND(msg->rdatalists, msgblock, link); rdatalist = msgblock_get(msgblock, dns_rdatalist_t); } out: if (rdatalist != NULL) dns_rdatalist_init(rdatalist); return (rdatalist); } static inline dns_offsets_t * newoffsets(dns_message_t *msg) { dns_msgblock_t *msgblock; dns_offsets_t *offsets; msgblock = ISC_LIST_TAIL(msg->offsets); offsets = msgblock_get(msgblock, dns_offsets_t); if (offsets == NULL) { msgblock = msgblock_allocate(msg->mctx, sizeof(dns_offsets_t), OFFSET_COUNT); if (msgblock == NULL) return (NULL); ISC_LIST_APPEND(msg->offsets, msgblock, link); offsets = msgblock_get(msgblock, dns_offsets_t); } return (offsets); } static inline void msginitheader(dns_message_t *m) { m->id = 0; m->flags = 0; m->rcode = 0; m->opcode = 0; m->rdclass = 0; } static inline void msginitprivate(dns_message_t *m) { unsigned int i; for (i = 0; i < DNS_SECTION_MAX; i++) { m->cursors[i] = NULL; m->counts[i] = 0; } m->opt = NULL; m->sig0 = NULL; m->sig0name = NULL; m->tsig = NULL; m->tsigname = NULL; m->state = DNS_SECTION_ANY; /* indicate nothing parsed or rendered */ m->opt_reserved = 0; m->sig_reserved = 0; m->reserved = 0; m->buffer = NULL; } static inline void msginittsig(dns_message_t *m) { m->tsigstatus = dns_rcode_noerror; m->querytsigstatus = dns_rcode_noerror; m->tsigkey = NULL; m->tsigctx = NULL; m->sigstart = -1; m->sig0key = NULL; m->sig0status = dns_rcode_noerror; m->timeadjust = 0; } /* * Init elements to default state. Used both when allocating a new element * and when resetting one. */ static inline void msginit(dns_message_t *m) { msginitheader(m); msginitprivate(m); msginittsig(m); m->header_ok = 0; m->question_ok = 0; m->tcp_continuation = 0; m->verified_sig = 0; m->verify_attempted = 0; m->order = NULL; m->order_arg = NULL; m->query.base = NULL; m->query.length = 0; m->free_query = 0; m->saved.base = NULL; m->saved.length = 0; m->free_saved = 0; m->sitok = 0; m->sitbad = 0; m->tkey = 0; m->rdclass_set = 0; m->querytsig = NULL; } static inline void msgresetnames(dns_message_t *msg, unsigned int first_section) { unsigned int i; dns_name_t *name, *next_name; dns_rdataset_t *rds, *next_rds; /* * Clean up name lists by calling the rdataset disassociate function. */ for (i = first_section; i < DNS_SECTION_MAX; i++) { name = ISC_LIST_HEAD(msg->sections[i]); while (name != NULL) { next_name = ISC_LIST_NEXT(name, link); ISC_LIST_UNLINK(msg->sections[i], name, link); rds = ISC_LIST_HEAD(name->list); while (rds != NULL) { next_rds = ISC_LIST_NEXT(rds, link); ISC_LIST_UNLINK(name->list, rds, link); INSIST(dns_rdataset_isassociated(rds)); dns_rdataset_disassociate(rds); isc_mempool_put(msg->rdspool, rds); rds = next_rds; } if (dns_name_dynamic(name)) dns_name_free(name, msg->mctx); isc_mempool_put(msg->namepool, name); name = next_name; } } } static void msgresetopt(dns_message_t *msg) { if (msg->opt != NULL) { if (msg->opt_reserved > 0) { dns_message_renderrelease(msg, msg->opt_reserved); msg->opt_reserved = 0; } INSIST(dns_rdataset_isassociated(msg->opt)); dns_rdataset_disassociate(msg->opt); isc_mempool_put(msg->rdspool, msg->opt); msg->opt = NULL; msg->sitok = 0; msg->sitbad = 0; } } static void msgresetsigs(dns_message_t *msg, isc_boolean_t replying) { if (msg->sig_reserved > 0) { dns_message_renderrelease(msg, msg->sig_reserved); msg->sig_reserved = 0; } if (msg->tsig != NULL) { INSIST(dns_rdataset_isassociated(msg->tsig)); INSIST(msg->namepool != NULL); if (replying) { INSIST(msg->querytsig == NULL); msg->querytsig = msg->tsig; } else { dns_rdataset_disassociate(msg->tsig); isc_mempool_put(msg->rdspool, msg->tsig); if (msg->querytsig != NULL) { dns_rdataset_disassociate(msg->querytsig); isc_mempool_put(msg->rdspool, msg->querytsig); } } if (dns_name_dynamic(msg->tsigname)) dns_name_free(msg->tsigname, msg->mctx); isc_mempool_put(msg->namepool, msg->tsigname); msg->tsig = NULL; msg->tsigname = NULL; } else if (msg->querytsig != NULL && !replying) { dns_rdataset_disassociate(msg->querytsig); isc_mempool_put(msg->rdspool, msg->querytsig); msg->querytsig = NULL; } if (msg->sig0 != NULL) { INSIST(dns_rdataset_isassociated(msg->sig0)); dns_rdataset_disassociate(msg->sig0); isc_mempool_put(msg->rdspool, msg->sig0); if (msg->sig0name != NULL) { if (dns_name_dynamic(msg->sig0name)) dns_name_free(msg->sig0name, msg->mctx); isc_mempool_put(msg->namepool, msg->sig0name); } msg->sig0 = NULL; msg->sig0name = NULL; } } /* * Free all but one (or everything) for this message. This is used by * both dns_message_reset() and dns_message_destroy(). */ static void msgreset(dns_message_t *msg, isc_boolean_t everything) { dns_msgblock_t *msgblock, *next_msgblock; isc_buffer_t *dynbuf, *next_dynbuf; dns_rdata_t *rdata; dns_rdatalist_t *rdatalist; msgresetnames(msg, 0); msgresetopt(msg); msgresetsigs(msg, ISC_FALSE); /* * Clean up linked lists. */ /* * Run through the free lists, and just unlink anything found there. * The memory isn't lost since these are part of message blocks we * have allocated. */ rdata = ISC_LIST_HEAD(msg->freerdata); while (rdata != NULL) { ISC_LIST_UNLINK(msg->freerdata, rdata, link); rdata = ISC_LIST_HEAD(msg->freerdata); } rdatalist = ISC_LIST_HEAD(msg->freerdatalist); while (rdatalist != NULL) { ISC_LIST_UNLINK(msg->freerdatalist, rdatalist, link); rdatalist = ISC_LIST_HEAD(msg->freerdatalist); } dynbuf = ISC_LIST_HEAD(msg->scratchpad); INSIST(dynbuf != NULL); if (!everything) { isc_buffer_clear(dynbuf); dynbuf = ISC_LIST_NEXT(dynbuf, link); } while (dynbuf != NULL) { next_dynbuf = ISC_LIST_NEXT(dynbuf, link); ISC_LIST_UNLINK(msg->scratchpad, dynbuf, link); isc_buffer_free(&dynbuf); dynbuf = next_dynbuf; } msgblock = ISC_LIST_HEAD(msg->rdatas); if (!everything && msgblock != NULL) { msgblock_reset(msgblock); msgblock = ISC_LIST_NEXT(msgblock, link); } while (msgblock != NULL) { next_msgblock = ISC_LIST_NEXT(msgblock, link); ISC_LIST_UNLINK(msg->rdatas, msgblock, link); msgblock_free(msg->mctx, msgblock, sizeof(dns_rdata_t)); msgblock = next_msgblock; } /* * rdatalists could be empty. */ msgblock = ISC_LIST_HEAD(msg->rdatalists); if (!everything && msgblock != NULL) { msgblock_reset(msgblock); msgblock = ISC_LIST_NEXT(msgblock, link); } while (msgblock != NULL) { next_msgblock = ISC_LIST_NEXT(msgblock, link); ISC_LIST_UNLINK(msg->rdatalists, msgblock, link); msgblock_free(msg->mctx, msgblock, sizeof(dns_rdatalist_t)); msgblock = next_msgblock; } msgblock = ISC_LIST_HEAD(msg->offsets); if (!everything && msgblock != NULL) { msgblock_reset(msgblock); msgblock = ISC_LIST_NEXT(msgblock, link); } while (msgblock != NULL) { next_msgblock = ISC_LIST_NEXT(msgblock, link); ISC_LIST_UNLINK(msg->offsets, msgblock, link); msgblock_free(msg->mctx, msgblock, sizeof(dns_offsets_t)); msgblock = next_msgblock; } if (msg->tsigkey != NULL) { dns_tsigkey_detach(&msg->tsigkey); msg->tsigkey = NULL; } if (msg->tsigctx != NULL) dst_context_destroy(&msg->tsigctx); if (msg->query.base != NULL) { if (msg->free_query != 0) isc_mem_put(msg->mctx, msg->query.base, msg->query.length); msg->query.base = NULL; msg->query.length = 0; } if (msg->saved.base != NULL) { if (msg->free_saved != 0) isc_mem_put(msg->mctx, msg->saved.base, msg->saved.length); msg->saved.base = NULL; msg->saved.length = 0; } /* * cleanup the buffer cleanup list */ dynbuf = ISC_LIST_HEAD(msg->cleanup); while (dynbuf != NULL) { next_dynbuf = ISC_LIST_NEXT(dynbuf, link); ISC_LIST_UNLINK(msg->cleanup, dynbuf, link); isc_buffer_free(&dynbuf); dynbuf = next_dynbuf; } /* * Set other bits to normal default values. */ if (!everything) msginit(msg); ENSURE(isc_mempool_getallocated(msg->namepool) == 0); ENSURE(isc_mempool_getallocated(msg->rdspool) == 0); } static unsigned int spacefortsig(dns_tsigkey_t *key, int otherlen) { isc_region_t r1, r2; unsigned int x; isc_result_t result; /* * The space required for an TSIG record is: * * n1 bytes for the name * 2 bytes for the type * 2 bytes for the class * 4 bytes for the ttl * 2 bytes for the rdlength * n2 bytes for the algorithm name * 6 bytes for the time signed * 2 bytes for the fudge * 2 bytes for the MAC size * x bytes for the MAC * 2 bytes for the original id * 2 bytes for the error * 2 bytes for the other data length * y bytes for the other data (at most) * --------------------------------- * 26 + n1 + n2 + x + y bytes */ dns_name_toregion(&key->name, &r1); dns_name_toregion(key->algorithm, &r2); if (key->key == NULL) x = 0; else { result = dst_key_sigsize(key->key, &x); if (result != ISC_R_SUCCESS) x = 0; } return (26 + r1.length + r2.length + x + otherlen); } isc_result_t dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp) { dns_message_t *m; isc_result_t result; isc_buffer_t *dynbuf; unsigned int i; REQUIRE(mctx != NULL); REQUIRE(msgp != NULL); REQUIRE(*msgp == NULL); REQUIRE(intent == DNS_MESSAGE_INTENTPARSE || intent == DNS_MESSAGE_INTENTRENDER); m = isc_mem_get(mctx, sizeof(dns_message_t)); if (m == NULL) return (ISC_R_NOMEMORY); /* * No allocations until further notice. Just initialize all lists * and other members that are freed in the cleanup phase here. */ m->magic = DNS_MESSAGE_MAGIC; m->from_to_wire = intent; msginit(m); for (i = 0; i < DNS_SECTION_MAX; i++) ISC_LIST_INIT(m->sections[i]); m->mctx = NULL; isc_mem_attach(mctx, &m->mctx); ISC_LIST_INIT(m->scratchpad); ISC_LIST_INIT(m->cleanup); m->namepool = NULL; m->rdspool = NULL; ISC_LIST_INIT(m->rdatas); ISC_LIST_INIT(m->rdatalists); ISC_LIST_INIT(m->offsets); ISC_LIST_INIT(m->freerdata); ISC_LIST_INIT(m->freerdatalist); /* * Ok, it is safe to allocate (and then "goto cleanup" if failure) */ result = isc_mempool_create(m->mctx, sizeof(dns_name_t), &m->namepool); if (result != ISC_R_SUCCESS) goto cleanup; isc_mempool_setfreemax(m->namepool, NAME_COUNT); isc_mempool_setname(m->namepool, "msg:names"); result = isc_mempool_create(m->mctx, sizeof(dns_rdataset_t), &m->rdspool); if (result != ISC_R_SUCCESS) goto cleanup; isc_mempool_setfreemax(m->rdspool, NAME_COUNT); isc_mempool_setname(m->rdspool, "msg:rdataset"); dynbuf = NULL; result = isc_buffer_allocate(mctx, &dynbuf, SCRATCHPAD_SIZE); if (result != ISC_R_SUCCESS) goto cleanup; ISC_LIST_APPEND(m->scratchpad, dynbuf, link); m->cctx = NULL; *msgp = m; return (ISC_R_SUCCESS); /* * Cleanup for error returns. */ cleanup: dynbuf = ISC_LIST_HEAD(m->scratchpad); if (dynbuf != NULL) { ISC_LIST_UNLINK(m->scratchpad, dynbuf, link); isc_buffer_free(&dynbuf); } if (m->namepool != NULL) isc_mempool_destroy(&m->namepool); if (m->rdspool != NULL) isc_mempool_destroy(&m->rdspool); m->magic = 0; isc_mem_putanddetach(&mctx, m, sizeof(dns_message_t)); return (ISC_R_NOMEMORY); } void dns_message_reset(dns_message_t *msg, unsigned int intent) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(intent == DNS_MESSAGE_INTENTPARSE || intent == DNS_MESSAGE_INTENTRENDER); msgreset(msg, ISC_FALSE); msg->from_to_wire = intent; } void dns_message_destroy(dns_message_t **msgp) { dns_message_t *msg; REQUIRE(msgp != NULL); REQUIRE(DNS_MESSAGE_VALID(*msgp)); msg = *msgp; *msgp = NULL; msgreset(msg, ISC_TRUE); isc_mempool_destroy(&msg->namepool); isc_mempool_destroy(&msg->rdspool); msg->magic = 0; isc_mem_putanddetach(&msg->mctx, msg, sizeof(dns_message_t)); } static isc_result_t findname(dns_name_t **foundname, dns_name_t *target, dns_namelist_t *section) { dns_name_t *curr; for (curr = ISC_LIST_TAIL(*section); curr != NULL; curr = ISC_LIST_PREV(curr, link)) { if (dns_name_equal(curr, target)) { if (foundname != NULL) *foundname = curr; return (ISC_R_SUCCESS); } } return (ISC_R_NOTFOUND); } isc_result_t dns_message_find(dns_name_t *name, dns_rdataclass_t rdclass, dns_rdatatype_t type, dns_rdatatype_t covers, dns_rdataset_t **rdataset) { dns_rdataset_t *curr; if (rdataset != NULL) { REQUIRE(*rdataset == NULL); } for (curr = ISC_LIST_TAIL(name->list); curr != NULL; curr = ISC_LIST_PREV(curr, link)) { if (curr->rdclass == rdclass && curr->type == type && curr->covers == covers) { if (rdataset != NULL) *rdataset = curr; return (ISC_R_SUCCESS); } } return (ISC_R_NOTFOUND); } isc_result_t dns_message_findtype(dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers, dns_rdataset_t **rdataset) { dns_rdataset_t *curr; REQUIRE(name != NULL); if (rdataset != NULL) { REQUIRE(*rdataset == NULL); } for (curr = ISC_LIST_TAIL(name->list); curr != NULL; curr = ISC_LIST_PREV(curr, link)) { if (curr->type == type && curr->covers == covers) { if (rdataset != NULL) *rdataset = curr; return (ISC_R_SUCCESS); } } return (ISC_R_NOTFOUND); } /* * Read a name from buffer "source". */ static isc_result_t getname(dns_name_t *name, isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx) { isc_buffer_t *scratch; isc_result_t result; unsigned int tries; scratch = currentbuffer(msg); /* * First try: use current buffer. * Second try: allocate a new buffer and use that. */ tries = 0; while (tries < 2) { result = dns_name_fromwire(name, source, dctx, ISC_FALSE, scratch); if (result == ISC_R_NOSPACE) { tries++; result = newbuffer(msg, SCRATCHPAD_SIZE); if (result != ISC_R_SUCCESS) return (result); scratch = currentbuffer(msg); dns_name_reset(name); } else { return (result); } } INSIST(0); /* Cannot get here... */ return (ISC_R_UNEXPECTED); } static isc_result_t getrdata(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, dns_rdataclass_t rdclass, dns_rdatatype_t rdtype, unsigned int rdatalen, dns_rdata_t *rdata) { isc_buffer_t *scratch; isc_result_t result; unsigned int tries; unsigned int trysize; scratch = currentbuffer(msg); isc_buffer_setactive(source, rdatalen); /* * First try: use current buffer. * Second try: allocate a new buffer of size * max(SCRATCHPAD_SIZE, 2 * compressed_rdatalen) * (the data will fit if it was not more than 50% compressed) * Subsequent tries: double buffer size on each try. */ tries = 0; trysize = 0; /* XXX possibly change this to a while (tries < 2) loop */ for (;;) { result = dns_rdata_fromwire(rdata, rdclass, rdtype, source, dctx, 0, scratch); if (result == ISC_R_NOSPACE) { if (tries == 0) { trysize = 2 * rdatalen; if (trysize < SCRATCHPAD_SIZE) trysize = SCRATCHPAD_SIZE; } else { INSIST(trysize != 0); if (trysize >= 65535) return (ISC_R_NOSPACE); /* XXX DNS_R_RRTOOLONG? */ trysize *= 2; } tries++; result = newbuffer(msg, trysize); if (result != ISC_R_SUCCESS) return (result); scratch = currentbuffer(msg); } else { return (result); } } } #define DO_FORMERR \ do { \ if (best_effort) \ seen_problem = ISC_TRUE; \ else { \ result = DNS_R_FORMERR; \ goto cleanup; \ } \ } while (0) static isc_result_t getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, unsigned int options) { isc_region_t r; unsigned int count; dns_name_t *name; dns_name_t *name2; dns_offsets_t *offsets; dns_rdataset_t *rdataset; dns_rdatalist_t *rdatalist; isc_result_t result; dns_rdatatype_t rdtype; dns_rdataclass_t rdclass; dns_namelist_t *section; isc_boolean_t free_name; isc_boolean_t best_effort; isc_boolean_t seen_problem; section = &msg->sections[DNS_SECTION_QUESTION]; best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT); seen_problem = ISC_FALSE; name = NULL; rdataset = NULL; rdatalist = NULL; for (count = 0; count < msg->counts[DNS_SECTION_QUESTION]; count++) { name = isc_mempool_get(msg->namepool); if (name == NULL) return (ISC_R_NOMEMORY); free_name = ISC_TRUE; offsets = newoffsets(msg); if (offsets == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } dns_name_init(name, *offsets); /* * Parse the name out of this packet. */ isc_buffer_remainingregion(source, &r); isc_buffer_setactive(source, r.length); result = getname(name, source, msg, dctx); if (result != ISC_R_SUCCESS) goto cleanup; /* * Run through the section, looking to see if this name * is already there. If it is found, put back the allocated * name since we no longer need it, and set our name pointer * to point to the name we found. */ result = findname(&name2, name, section); /* * If it is the first name in the section, accept it. * * If it is not, but is not the same as the name already * in the question section, append to the section. Note that * here in the question section this is illegal, so return * FORMERR. In the future, check the opcode to see if * this should be legal or not. In either case we no longer * need this name pointer. */ if (result != ISC_R_SUCCESS) { if (!ISC_LIST_EMPTY(*section)) DO_FORMERR; ISC_LIST_APPEND(*section, name, link); free_name = ISC_FALSE; } else { isc_mempool_put(msg->namepool, name); name = name2; name2 = NULL; free_name = ISC_FALSE; } /* * Get type and class. */ isc_buffer_remainingregion(source, &r); if (r.length < 4) { result = ISC_R_UNEXPECTEDEND; goto cleanup; } rdtype = isc_buffer_getuint16(source); rdclass = isc_buffer_getuint16(source); /* * If this class is different than the one we already read, * this is an error. */ if (msg->rdclass_set == 0) { msg->rdclass = rdclass; msg->rdclass_set = 1; } else if (msg->rdclass != rdclass) DO_FORMERR; /* * Is this a TKEY query? */ if (rdtype == dns_rdatatype_tkey) msg->tkey = 1; /* * Can't ask the same question twice. */ result = dns_message_find(name, rdclass, rdtype, 0, NULL); if (result == ISC_R_SUCCESS) DO_FORMERR; /* * Allocate a new rdatalist. */ rdatalist = newrdatalist(msg); if (rdatalist == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } rdataset = isc_mempool_get(msg->rdspool); if (rdataset == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } /* * Convert rdatalist to rdataset, and attach the latter to * the name. */ rdatalist->type = rdtype; rdatalist->covers = 0; rdatalist->rdclass = rdclass; rdatalist->ttl = 0; ISC_LIST_INIT(rdatalist->rdata); dns_rdataset_init(rdataset); result = dns_rdatalist_tordataset(rdatalist, rdataset); if (result != ISC_R_SUCCESS) goto cleanup; rdataset->attributes |= DNS_RDATASETATTR_QUESTION; ISC_LIST_APPEND(name->list, rdataset, link); rdataset = NULL; } if (seen_problem) return (DNS_R_RECOVERABLE); return (ISC_R_SUCCESS); cleanup: if (rdataset != NULL) { INSIST(!dns_rdataset_isassociated(rdataset)); isc_mempool_put(msg->rdspool, rdataset); } #if 0 if (rdatalist != NULL) isc_mempool_put(msg->rdlpool, rdatalist); #endif if (free_name) isc_mempool_put(msg->namepool, name); return (result); } static isc_boolean_t update(dns_section_t section, dns_rdataclass_t rdclass) { if (section == DNS_SECTION_PREREQUISITE) return (ISC_TF(rdclass == dns_rdataclass_any || rdclass == dns_rdataclass_none)); if (section == DNS_SECTION_UPDATE) return (ISC_TF(rdclass == dns_rdataclass_any)); return (ISC_FALSE); } static isc_result_t getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, dns_section_t sectionid, unsigned int options) { isc_region_t r; unsigned int count, rdatalen; dns_name_t *name; dns_name_t *name2; dns_offsets_t *offsets; dns_rdataset_t *rdataset; dns_rdatalist_t *rdatalist; isc_result_t result; dns_rdatatype_t rdtype, covers; dns_rdataclass_t rdclass; dns_rdata_t *rdata; dns_ttl_t ttl; dns_namelist_t *section; isc_boolean_t free_name, free_rdataset; isc_boolean_t preserve_order, best_effort, seen_problem; isc_boolean_t issigzero; preserve_order = ISC_TF(options & DNS_MESSAGEPARSE_PRESERVEORDER); best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT); seen_problem = ISC_FALSE; for (count = 0; count < msg->counts[sectionid]; count++) { int recstart = source->current; isc_boolean_t skip_name_search, skip_type_search; section = &msg->sections[sectionid]; skip_name_search = ISC_FALSE; skip_type_search = ISC_FALSE; free_rdataset = ISC_FALSE; name = isc_mempool_get(msg->namepool); if (name == NULL) return (ISC_R_NOMEMORY); free_name = ISC_TRUE; offsets = newoffsets(msg); if (offsets == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } dns_name_init(name, *offsets); /* * Parse the name out of this packet. */ isc_buffer_remainingregion(source, &r); isc_buffer_setactive(source, r.length); result = getname(name, source, msg, dctx); if (result != ISC_R_SUCCESS) goto cleanup; /* * Get type, class, ttl, and rdatalen. Verify that at least * rdatalen bytes remain. (Some of this is deferred to * later.) */ isc_buffer_remainingregion(source, &r); if (r.length < 2 + 2 + 4 + 2) { result = ISC_R_UNEXPECTEDEND; goto cleanup; } rdtype = isc_buffer_getuint16(source); rdclass = isc_buffer_getuint16(source); /* * If there was no question section, we may not yet have * established a class. Do so now. */ if (msg->rdclass_set == 0 && rdtype != dns_rdatatype_opt && /* class is UDP SIZE */ rdtype != dns_rdatatype_tsig && /* class is ANY */ rdtype != dns_rdatatype_tkey) { /* class is undefined */ msg->rdclass = rdclass; msg->rdclass_set = 1; } /* * If this class is different than the one in the question * section, bail. */ if (msg->opcode != dns_opcode_update && rdtype != dns_rdatatype_tsig && rdtype != dns_rdatatype_opt && rdtype != dns_rdatatype_key /* in a TKEY query */ && rdtype != dns_rdatatype_sig /* SIG(0) */ && rdtype != dns_rdatatype_tkey /* Win2000 TKEY */ && msg->rdclass != dns_rdataclass_any && msg->rdclass != rdclass) DO_FORMERR; /* * If this is not a TKEY query/response then the KEY * record's class needs to match. */ if (msg->opcode != dns_opcode_update && !msg->tkey && rdtype == dns_rdatatype_key && msg->rdclass != dns_rdataclass_any && msg->rdclass != rdclass) DO_FORMERR; /* * Special type handling for TSIG, OPT, and TKEY. */ if (rdtype == dns_rdatatype_tsig) { /* * If it is a tsig, verify that it is in the * additional data section. */ if (sectionid != DNS_SECTION_ADDITIONAL || rdclass != dns_rdataclass_any || count != msg->counts[sectionid] - 1) DO_FORMERR; msg->sigstart = recstart; skip_name_search = ISC_TRUE; skip_type_search = ISC_TRUE; } else if (rdtype == dns_rdatatype_opt) { /* * The name of an OPT record must be ".", it * must be in the additional data section, and * it must be the first OPT we've seen. */ if (!dns_name_equal(dns_rootname, name) || msg->opt != NULL) DO_FORMERR; skip_name_search = ISC_TRUE; skip_type_search = ISC_TRUE; } else if (rdtype == dns_rdatatype_tkey) { /* * A TKEY must be in the additional section if this * is a query, and the answer section if this is a * response. Unless it's a Win2000 client. * * Its class is ignored. */ dns_section_t tkeysection; if ((msg->flags & DNS_MESSAGEFLAG_QR) == 0) tkeysection = DNS_SECTION_ADDITIONAL; else tkeysection = DNS_SECTION_ANSWER; if (sectionid != tkeysection && sectionid != DNS_SECTION_ANSWER) DO_FORMERR; } /* * ... now get ttl and rdatalen, and check buffer. */ ttl = isc_buffer_getuint32(source); rdatalen = isc_buffer_getuint16(source); r.length -= (2 + 2 + 4 + 2); if (r.length < rdatalen) { result = ISC_R_UNEXPECTEDEND; goto cleanup; } /* * Read the rdata from the wire format. Interpret the * rdata according to its actual class, even if it had a * DynDNS meta-class in the packet (unless this is a TSIG). * Then put the meta-class back into the finished rdata. */ rdata = newrdata(msg); if (rdata == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } if (msg->opcode == dns_opcode_update && update(sectionid, rdclass)) { if (rdatalen != 0) { result = DNS_R_FORMERR; goto cleanup; } /* * When the rdata is empty, the data pointer is * never dereferenced, but it must still be non-NULL. * Casting 1 rather than "" avoids warnings about * discarding the const attribute of a string, * for compilers that would warn about such things. */ rdata->data = (unsigned char *)1; rdata->length = 0; rdata->rdclass = rdclass; rdata->type = rdtype; rdata->flags = DNS_RDATA_UPDATE; result = ISC_R_SUCCESS; } else if (rdclass == dns_rdataclass_none && msg->opcode == dns_opcode_update && sectionid == DNS_SECTION_UPDATE) { result = getrdata(source, msg, dctx, msg->rdclass, rdtype, rdatalen, rdata); } else result = getrdata(source, msg, dctx, rdclass, rdtype, rdatalen, rdata); if (result != ISC_R_SUCCESS) goto cleanup; rdata->rdclass = rdclass; issigzero = ISC_FALSE; if (rdtype == dns_rdatatype_rrsig && rdata->flags == 0) { covers = dns_rdata_covers(rdata); if (covers == 0) DO_FORMERR; } else if (rdtype == dns_rdatatype_sig /* SIG(0) */ && rdata->flags == 0) { covers = dns_rdata_covers(rdata); if (covers == 0) { if (sectionid != DNS_SECTION_ADDITIONAL || count != msg->counts[sectionid] - 1) DO_FORMERR; msg->sigstart = recstart; skip_name_search = ISC_TRUE; skip_type_search = ISC_TRUE; issigzero = ISC_TRUE; } else { if (msg->rdclass != dns_rdataclass_any && msg->rdclass != rdclass) DO_FORMERR; } } else covers = 0; /* * Check the ownername of NSEC3 records */ if (rdtype == dns_rdatatype_nsec3 && !dns_rdata_checkowner(name, msg->rdclass, rdtype, ISC_FALSE)) { result = DNS_R_BADOWNERNAME; goto cleanup; } /* * If we are doing a dynamic update or this is a meta-type, * don't bother searching for a name, just append this one * to the end of the message. */ if (preserve_order || msg->opcode == dns_opcode_update || skip_name_search) { if (rdtype != dns_rdatatype_opt && rdtype != dns_rdatatype_tsig && !issigzero) { ISC_LIST_APPEND(*section, name, link); free_name = ISC_FALSE; } } else { /* * Run through the section, looking to see if this name * is already there. If it is found, put back the * allocated name since we no longer need it, and set * our name pointer to point to the name we found. */ result = findname(&name2, name, section); /* * If it is a new name, append to the section. */ if (result == ISC_R_SUCCESS) { isc_mempool_put(msg->namepool, name); name = name2; } else { ISC_LIST_APPEND(*section, name, link); } free_name = ISC_FALSE; } /* * Search name for the particular type and class. * Skip this stage if in update mode or this is a meta-type. */ if (preserve_order || msg->opcode == dns_opcode_update || skip_type_search) result = ISC_R_NOTFOUND; else { /* * If this is a type that can only occur in * the question section, fail. */ if (dns_rdatatype_questiononly(rdtype)) DO_FORMERR; rdataset = NULL; result = dns_message_find(name, rdclass, rdtype, covers, &rdataset); } /* * If we found an rdataset that matches, we need to * append this rdata to that set. If we did not, we need * to create a new rdatalist, store the important bits there, * convert it to an rdataset, and link the latter to the name. * Yuck. When appending, make certain that the type isn't * a singleton type, such as SOA or CNAME. * * Note that this check will be bypassed when preserving order, * the opcode is an update, or the type search is skipped. */ if (result == ISC_R_SUCCESS) { if (dns_rdatatype_issingleton(rdtype)) { dns_rdata_t *first; dns_rdatalist_fromrdataset(rdataset, &rdatalist); first = ISC_LIST_HEAD(rdatalist->rdata); INSIST(first != NULL); if (dns_rdata_compare(rdata, first) != 0) DO_FORMERR; } } if (result == ISC_R_NOTFOUND) { rdataset = isc_mempool_get(msg->rdspool); if (rdataset == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } free_rdataset = ISC_TRUE; rdatalist = newrdatalist(msg); if (rdatalist == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } rdatalist->type = rdtype; rdatalist->covers = covers; rdatalist->rdclass = rdclass; rdatalist->ttl = ttl; ISC_LIST_INIT(rdatalist->rdata); dns_rdataset_init(rdataset); RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) == ISC_R_SUCCESS); if (rdtype != dns_rdatatype_opt && rdtype != dns_rdatatype_tsig && !issigzero) { ISC_LIST_APPEND(name->list, rdataset, link); free_rdataset = ISC_FALSE; } } /* * Minimize TTLs. * * Section 5.2 of RFC2181 says we should drop * nonauthoritative rrsets where the TTLs differ, but we * currently treat them the as if they were authoritative and * minimize them. */ if (ttl != rdataset->ttl) { rdataset->attributes |= DNS_RDATASETATTR_TTLADJUSTED; if (ttl < rdataset->ttl) rdataset->ttl = ttl; } /* Append this rdata to the rdataset. */ dns_rdatalist_fromrdataset(rdataset, &rdatalist); ISC_LIST_APPEND(rdatalist->rdata, rdata, link); /* * If this is an OPT record, remember it. Also, set * the extended rcode. Note that msg->opt will only be set * if best-effort parsing is enabled. */ if (rdtype == dns_rdatatype_opt && msg->opt == NULL) { dns_rcode_t ercode; msg->opt = rdataset; rdataset = NULL; free_rdataset = ISC_FALSE; ercode = (dns_rcode_t) ((msg->opt->ttl & DNS_MESSAGE_EDNSRCODE_MASK) >> 20); msg->rcode |= ercode; isc_mempool_put(msg->namepool, name); free_name = ISC_FALSE; } /* * If this is an SIG(0) or TSIG record, remember it. Note * that msg->sig0 or msg->tsig will only be set if best-effort * parsing is enabled. */ if (issigzero && msg->sig0 == NULL) { msg->sig0 = rdataset; msg->sig0name = name; rdataset = NULL; free_rdataset = ISC_FALSE; free_name = ISC_FALSE; } else if (rdtype == dns_rdatatype_tsig && msg->tsig == NULL) { msg->tsig = rdataset; msg->tsigname = name; /* Windows doesn't like TSIG names to be compressed. */ msg->tsigname->attributes |= DNS_NAMEATTR_NOCOMPRESS; rdataset = NULL; free_rdataset = ISC_FALSE; free_name = ISC_FALSE; } if (seen_problem) { if (free_name) isc_mempool_put(msg->namepool, name); if (free_rdataset) isc_mempool_put(msg->rdspool, rdataset); free_name = free_rdataset = ISC_FALSE; } INSIST(free_name == ISC_FALSE); INSIST(free_rdataset == ISC_FALSE); } if (seen_problem) return (DNS_R_RECOVERABLE); return (ISC_R_SUCCESS); cleanup: if (free_name) isc_mempool_put(msg->namepool, name); if (free_rdataset) isc_mempool_put(msg->rdspool, rdataset); return (result); } isc_result_t dns_message_parse(dns_message_t *msg, isc_buffer_t *source, unsigned int options) { isc_region_t r; dns_decompress_t dctx; isc_result_t ret; isc_uint16_t tmpflags; isc_buffer_t origsource; isc_boolean_t seen_problem; isc_boolean_t ignore_tc; REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(source != NULL); REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE); seen_problem = ISC_FALSE; ignore_tc = ISC_TF(options & DNS_MESSAGEPARSE_IGNORETRUNCATION); origsource = *source; msg->header_ok = 0; msg->question_ok = 0; isc_buffer_remainingregion(source, &r); if (r.length < DNS_MESSAGE_HEADERLEN) return (ISC_R_UNEXPECTEDEND); msg->id = isc_buffer_getuint16(source); tmpflags = isc_buffer_getuint16(source); msg->opcode = ((tmpflags & DNS_MESSAGE_OPCODE_MASK) >> DNS_MESSAGE_OPCODE_SHIFT); msg->rcode = (dns_rcode_t)(tmpflags & DNS_MESSAGE_RCODE_MASK); msg->flags = (tmpflags & DNS_MESSAGE_FLAG_MASK); msg->counts[DNS_SECTION_QUESTION] = isc_buffer_getuint16(source); msg->counts[DNS_SECTION_ANSWER] = isc_buffer_getuint16(source); msg->counts[DNS_SECTION_AUTHORITY] = isc_buffer_getuint16(source); msg->counts[DNS_SECTION_ADDITIONAL] = isc_buffer_getuint16(source); msg->header_ok = 1; msg->state = DNS_SECTION_QUESTION; /* * -1 means no EDNS. */ dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY); dns_decompress_setmethods(&dctx, DNS_COMPRESS_GLOBAL14); ret = getquestions(source, msg, &dctx, options); if (ret == ISC_R_UNEXPECTEDEND && ignore_tc) goto truncated; if (ret == DNS_R_RECOVERABLE) { seen_problem = ISC_TRUE; ret = ISC_R_SUCCESS; } if (ret != ISC_R_SUCCESS) return (ret); msg->question_ok = 1; ret = getsection(source, msg, &dctx, DNS_SECTION_ANSWER, options); if (ret == ISC_R_UNEXPECTEDEND && ignore_tc) goto truncated; if (ret == DNS_R_RECOVERABLE) { seen_problem = ISC_TRUE; ret = ISC_R_SUCCESS; } if (ret != ISC_R_SUCCESS) return (ret); ret = getsection(source, msg, &dctx, DNS_SECTION_AUTHORITY, options); if (ret == ISC_R_UNEXPECTEDEND && ignore_tc) goto truncated; if (ret == DNS_R_RECOVERABLE) { seen_problem = ISC_TRUE; ret = ISC_R_SUCCESS; } if (ret != ISC_R_SUCCESS) return (ret); ret = getsection(source, msg, &dctx, DNS_SECTION_ADDITIONAL, options); if (ret == ISC_R_UNEXPECTEDEND && ignore_tc) goto truncated; if (ret == DNS_R_RECOVERABLE) { seen_problem = ISC_TRUE; ret = ISC_R_SUCCESS; } if (ret != ISC_R_SUCCESS) return (ret); isc_buffer_remainingregion(source, &r); if (r.length != 0) { isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MESSAGE, ISC_LOG_DEBUG(3), "message has %u byte(s) of trailing garbage", r.length); } truncated: if ((options & DNS_MESSAGEPARSE_CLONEBUFFER) == 0) isc_buffer_usedregion(&origsource, &msg->saved); else { msg->saved.length = isc_buffer_usedlength(&origsource); msg->saved.base = isc_mem_get(msg->mctx, msg->saved.length); if (msg->saved.base == NULL) return (ISC_R_NOMEMORY); memmove(msg->saved.base, isc_buffer_base(&origsource), msg->saved.length); msg->free_saved = 1; } if (ret == ISC_R_UNEXPECTEDEND && ignore_tc) return (DNS_R_RECOVERABLE); if (seen_problem == ISC_TRUE) return (DNS_R_RECOVERABLE); return (ISC_R_SUCCESS); } isc_result_t dns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx, isc_buffer_t *buffer) { isc_region_t r; REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(buffer != NULL); REQUIRE(msg->buffer == NULL); REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER); msg->cctx = cctx; /* * Erase the contents of this buffer. */ isc_buffer_clear(buffer); /* * Make certain there is enough for at least the header in this * buffer. */ isc_buffer_availableregion(buffer, &r); if (r.length < DNS_MESSAGE_HEADERLEN) return (ISC_R_NOSPACE); if (r.length < msg->reserved) return (ISC_R_NOSPACE); /* * Reserve enough space for the header in this buffer. */ isc_buffer_add(buffer, DNS_MESSAGE_HEADERLEN); msg->buffer = buffer; return (ISC_R_SUCCESS); } isc_result_t dns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer) { isc_region_t r, rn; REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(buffer != NULL); REQUIRE(msg->buffer != NULL); /* * Ensure that the new buffer is empty, and has enough space to * hold the current contents. */ isc_buffer_clear(buffer); isc_buffer_availableregion(buffer, &rn); isc_buffer_usedregion(msg->buffer, &r); REQUIRE(rn.length > r.length); /* * Copy the contents from the old to the new buffer. */ isc_buffer_add(buffer, r.length); memmove(rn.base, r.base, r.length); msg->buffer = buffer; return (ISC_R_SUCCESS); } void dns_message_renderrelease(dns_message_t *msg, unsigned int space) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(space <= msg->reserved); msg->reserved -= space; } isc_result_t dns_message_renderreserve(dns_message_t *msg, unsigned int space) { isc_region_t r; REQUIRE(DNS_MESSAGE_VALID(msg)); if (msg->buffer != NULL) { isc_buffer_availableregion(msg->buffer, &r); if (r.length < (space + msg->reserved)) return (ISC_R_NOSPACE); } msg->reserved += space; return (ISC_R_SUCCESS); } static inline isc_boolean_t wrong_priority(dns_rdataset_t *rds, int pass, dns_rdatatype_t preferred_glue) { int pass_needed; /* * If we are not rendering class IN, this ordering is bogus. */ if (rds->rdclass != dns_rdataclass_in) return (ISC_FALSE); switch (rds->type) { case dns_rdatatype_a: case dns_rdatatype_aaaa: if (preferred_glue == rds->type) pass_needed = 4; else pass_needed = 3; break; case dns_rdatatype_rrsig: case dns_rdatatype_dnskey: pass_needed = 2; break; default: pass_needed = 1; } if (pass_needed >= pass) return (ISC_FALSE); return (ISC_TRUE); } #ifdef ALLOW_FILTER_AAAA /* * Decide whether to not answer with an AAAA record and its RRSIG */ static inline isc_boolean_t norender_rdataset(const dns_rdataset_t *rdataset, unsigned int options, dns_section_t sectionid) { if (sectionid == DNS_SECTION_QUESTION) return (ISC_FALSE); switch (rdataset->type) { case dns_rdatatype_ns: if ((options & DNS_MESSAGERENDER_FILTER_AAAA) == 0 || sectionid != DNS_SECTION_AUTHORITY) return (ISC_FALSE); break; case dns_rdatatype_aaaa: if ((options & DNS_MESSAGERENDER_FILTER_AAAA) == 0) return (ISC_FALSE); break; case dns_rdatatype_rrsig: if ((options & DNS_MESSAGERENDER_FILTER_AAAA) == 0 || (rdataset->covers != dns_rdatatype_ns && rdataset->covers != dns_rdatatype_aaaa)) return (ISC_FALSE); if ((rdataset->covers == dns_rdatatype_ns) && (sectionid != DNS_SECTION_AUTHORITY)) return (ISC_FALSE); break; default: return (ISC_FALSE); } if (rdataset->rdclass != dns_rdataclass_in) return (ISC_FALSE); return (ISC_TRUE); } #endif isc_result_t dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid, unsigned int options) { dns_namelist_t *section; dns_name_t *name, *next_name; dns_rdataset_t *rdataset, *next_rdataset; unsigned int count, total; isc_result_t result; isc_buffer_t st; /* for rollbacks */ int pass; isc_boolean_t partial = ISC_FALSE; unsigned int rd_options; dns_rdatatype_t preferred_glue = 0; REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(msg->buffer != NULL); REQUIRE(VALID_NAMED_SECTION(sectionid)); section = &msg->sections[sectionid]; if ((sectionid == DNS_SECTION_ADDITIONAL) && (options & DNS_MESSAGERENDER_ORDERED) == 0) { if ((options & DNS_MESSAGERENDER_PREFER_A) != 0) { preferred_glue = dns_rdatatype_a; pass = 4; } else if ((options & DNS_MESSAGERENDER_PREFER_AAAA) != 0) { preferred_glue = dns_rdatatype_aaaa; pass = 4; } else pass = 3; } else pass = 1; if ((options & DNS_MESSAGERENDER_OMITDNSSEC) == 0) rd_options = 0; else rd_options = DNS_RDATASETTOWIRE_OMITDNSSEC; /* * Shrink the space in the buffer by the reserved amount. */ msg->buffer->length -= msg->reserved; total = 0; if (msg->reserved == 0 && (options & DNS_MESSAGERENDER_PARTIAL) != 0) partial = ISC_TRUE; /* * Render required glue first. Set TC if it won't fit. */ name = ISC_LIST_HEAD(*section); if (name != NULL) { rdataset = ISC_LIST_HEAD(name->list); if (rdataset != NULL && (rdataset->attributes & DNS_RDATASETATTR_REQUIREDGLUE) != 0 && (rdataset->attributes & DNS_RDATASETATTR_RENDERED) == 0) { const void *order_arg = msg->order_arg; st = *(msg->buffer); count = 0; if (partial) result = dns_rdataset_towirepartial(rdataset, name, msg->cctx, msg->buffer, msg->order, order_arg, rd_options, &count, NULL); else result = dns_rdataset_towiresorted(rdataset, name, msg->cctx, msg->buffer, msg->order, order_arg, rd_options, &count); total += count; if (partial && result == ISC_R_NOSPACE) { msg->flags |= DNS_MESSAGEFLAG_TC; msg->buffer->length += msg->reserved; msg->counts[sectionid] += total; return (result); } if (result == ISC_R_NOSPACE) msg->flags |= DNS_MESSAGEFLAG_TC; if (result != ISC_R_SUCCESS) { INSIST(st.used < 65536); dns_compress_rollback(msg->cctx, (isc_uint16_t)st.used); *(msg->buffer) = st; /* rollback */ msg->buffer->length += msg->reserved; msg->counts[sectionid] += total; return (result); } rdataset->attributes |= DNS_RDATASETATTR_RENDERED; } } do { name = ISC_LIST_HEAD(*section); if (name == NULL) { msg->buffer->length += msg->reserved; msg->counts[sectionid] += total; return (ISC_R_SUCCESS); } while (name != NULL) { next_name = ISC_LIST_NEXT(name, link); rdataset = ISC_LIST_HEAD(name->list); while (rdataset != NULL) { next_rdataset = ISC_LIST_NEXT(rdataset, link); if ((rdataset->attributes & DNS_RDATASETATTR_RENDERED) != 0) goto next; if (((options & DNS_MESSAGERENDER_ORDERED) == 0) && (sectionid == DNS_SECTION_ADDITIONAL) && wrong_priority(rdataset, pass, preferred_glue)) goto next; #ifdef ALLOW_FILTER_AAAA /* * Suppress AAAAs if asked and we are * not doing DNSSEC or are breaking DNSSEC. * Say so in the AD bit if we break DNSSEC. */ if (norender_rdataset(rdataset, options, sectionid)) { if (sectionid == DNS_SECTION_ANSWER || sectionid == DNS_SECTION_AUTHORITY) msg->flags &= ~DNS_MESSAGEFLAG_AD; if (OPTOUT(rdataset)) msg->flags &= ~DNS_MESSAGEFLAG_AD; goto next; } #endif st = *(msg->buffer); count = 0; if (partial) result = dns_rdataset_towirepartial( rdataset, name, msg->cctx, msg->buffer, msg->order, msg->order_arg, rd_options, &count, NULL); else result = dns_rdataset_towiresorted( rdataset, name, msg->cctx, msg->buffer, msg->order, msg->order_arg, rd_options, &count); total += count; /* * If out of space, record stats on what we * rendered so far, and return that status. * * XXXMLG Need to change this when * dns_rdataset_towire() can render partial * sets starting at some arbitrary point in the * set. This will include setting a bit in the * rdataset to indicate that a partial * rendering was done, and some state saved * somewhere (probably in the message struct) * to indicate where to continue from. */ if (partial && result == ISC_R_NOSPACE) { msg->buffer->length += msg->reserved; msg->counts[sectionid] += total; return (result); } if (result != ISC_R_SUCCESS) { INSIST(st.used < 65536); dns_compress_rollback(msg->cctx, (isc_uint16_t)st.used); *(msg->buffer) = st; /* rollback */ msg->buffer->length += msg->reserved; msg->counts[sectionid] += total; return (result); } /* * If we have rendered non-validated data, * ensure that the AD bit is not set. */ if (rdataset->trust != dns_trust_secure && (sectionid == DNS_SECTION_ANSWER || sectionid == DNS_SECTION_AUTHORITY)) msg->flags &= ~DNS_MESSAGEFLAG_AD; if (OPTOUT(rdataset)) msg->flags &= ~DNS_MESSAGEFLAG_AD; rdataset->attributes |= DNS_RDATASETATTR_RENDERED; next: rdataset = next_rdataset; } name = next_name; } } while (--pass != 0); msg->buffer->length += msg->reserved; msg->counts[sectionid] += total; return (ISC_R_SUCCESS); } void dns_message_renderheader(dns_message_t *msg, isc_buffer_t *target) { isc_uint16_t tmp; isc_region_t r; REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(target != NULL); isc_buffer_availableregion(target, &r); REQUIRE(r.length >= DNS_MESSAGE_HEADERLEN); isc_buffer_putuint16(target, msg->id); tmp = ((msg->opcode << DNS_MESSAGE_OPCODE_SHIFT) & DNS_MESSAGE_OPCODE_MASK); tmp |= (msg->rcode & DNS_MESSAGE_RCODE_MASK); tmp |= (msg->flags & DNS_MESSAGE_FLAG_MASK); INSIST(msg->counts[DNS_SECTION_QUESTION] < 65536 && msg->counts[DNS_SECTION_ANSWER] < 65536 && msg->counts[DNS_SECTION_AUTHORITY] < 65536 && msg->counts[DNS_SECTION_ADDITIONAL] < 65536); isc_buffer_putuint16(target, tmp); isc_buffer_putuint16(target, (isc_uint16_t)msg->counts[DNS_SECTION_QUESTION]); isc_buffer_putuint16(target, (isc_uint16_t)msg->counts[DNS_SECTION_ANSWER]); isc_buffer_putuint16(target, (isc_uint16_t)msg->counts[DNS_SECTION_AUTHORITY]); isc_buffer_putuint16(target, (isc_uint16_t)msg->counts[DNS_SECTION_ADDITIONAL]); } isc_result_t dns_message_renderend(dns_message_t *msg) { isc_buffer_t tmpbuf; isc_region_t r; int result; unsigned int count; REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(msg->buffer != NULL); if ((msg->rcode & ~DNS_MESSAGE_RCODE_MASK) != 0 && msg->opt == NULL) { /* * We have an extended rcode but are not using EDNS. */ return (DNS_R_FORMERR); } /* * If we're adding a OPT, TSIG or SIG(0) to a truncated message, * clear all rdatasets from the message except for the question * before adding the OPT, TSIG or SIG(0). If the question doesn't * fit, don't include it. */ if ((msg->tsigkey != NULL || msg->sig0key != NULL || msg->opt) && (msg->flags & DNS_MESSAGEFLAG_TC) != 0) { isc_buffer_t *buf; msgresetnames(msg, DNS_SECTION_ANSWER); buf = msg->buffer; dns_message_renderreset(msg); msg->buffer = buf; isc_buffer_clear(msg->buffer); isc_buffer_add(msg->buffer, DNS_MESSAGE_HEADERLEN); dns_compress_rollback(msg->cctx, 0); result = dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0); if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE) return (result); } /* * If we've got an OPT record, render it. */ if (msg->opt != NULL) { dns_message_renderrelease(msg, msg->opt_reserved); msg->opt_reserved = 0; /* * Set the extended rcode. */ msg->opt->ttl &= ~DNS_MESSAGE_EDNSRCODE_MASK; msg->opt->ttl |= ((msg->rcode << 20) & DNS_MESSAGE_EDNSRCODE_MASK); /* * Render. */ count = 0; result = dns_rdataset_towire(msg->opt, dns_rootname, msg->cctx, msg->buffer, 0, &count); msg->counts[DNS_SECTION_ADDITIONAL] += count; if (result != ISC_R_SUCCESS) return (result); } /* * If we're adding a TSIG record, generate and render it. */ if (msg->tsigkey != NULL) { dns_message_renderrelease(msg, msg->sig_reserved); msg->sig_reserved = 0; result = dns_tsig_sign(msg); if (result != ISC_R_SUCCESS) return (result); count = 0; result = dns_rdataset_towire(msg->tsig, msg->tsigname, msg->cctx, msg->buffer, 0, &count); msg->counts[DNS_SECTION_ADDITIONAL] += count; if (result != ISC_R_SUCCESS) return (result); } /* * If we're adding a SIG(0) record, generate and render it. */ if (msg->sig0key != NULL) { dns_message_renderrelease(msg, msg->sig_reserved); msg->sig_reserved = 0; result = dns_dnssec_signmessage(msg, msg->sig0key); if (result != ISC_R_SUCCESS) return (result); count = 0; /* * Note: dns_rootname is used here, not msg->sig0name, since * the owner name of a SIG(0) is irrelevant, and will not * be set in a message being rendered. */ result = dns_rdataset_towire(msg->sig0, dns_rootname, msg->cctx, msg->buffer, 0, &count); msg->counts[DNS_SECTION_ADDITIONAL] += count; if (result != ISC_R_SUCCESS) return (result); } isc_buffer_usedregion(msg->buffer, &r); isc_buffer_init(&tmpbuf, r.base, r.length); dns_message_renderheader(msg, &tmpbuf); msg->buffer = NULL; /* forget about this buffer only on success XXX */ return (ISC_R_SUCCESS); } void dns_message_renderreset(dns_message_t *msg) { unsigned int i; dns_name_t *name; dns_rdataset_t *rds; /* * Reset the message so that it may be rendered again. */ REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER); msg->buffer = NULL; for (i = 0; i < DNS_SECTION_MAX; i++) { msg->cursors[i] = NULL; msg->counts[i] = 0; for (name = ISC_LIST_HEAD(msg->sections[i]); name != NULL; name = ISC_LIST_NEXT(name, link)) { for (rds = ISC_LIST_HEAD(name->list); rds != NULL; rds = ISC_LIST_NEXT(rds, link)) { rds->attributes &= ~DNS_RDATASETATTR_RENDERED; } } } if (msg->tsigname != NULL) dns_message_puttempname(msg, &msg->tsigname); if (msg->tsig != NULL) { dns_rdataset_disassociate(msg->tsig); dns_message_puttemprdataset(msg, &msg->tsig); } if (msg->sig0 != NULL) { dns_rdataset_disassociate(msg->sig0); dns_message_puttemprdataset(msg, &msg->sig0); } } isc_result_t dns_message_firstname(dns_message_t *msg, dns_section_t section) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(VALID_NAMED_SECTION(section)); msg->cursors[section] = ISC_LIST_HEAD(msg->sections[section]); if (msg->cursors[section] == NULL) return (ISC_R_NOMORE); return (ISC_R_SUCCESS); } isc_result_t dns_message_nextname(dns_message_t *msg, dns_section_t section) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(VALID_NAMED_SECTION(section)); REQUIRE(msg->cursors[section] != NULL); msg->cursors[section] = ISC_LIST_NEXT(msg->cursors[section], link); if (msg->cursors[section] == NULL) return (ISC_R_NOMORE); return (ISC_R_SUCCESS); } void dns_message_currentname(dns_message_t *msg, dns_section_t section, dns_name_t **name) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(VALID_NAMED_SECTION(section)); REQUIRE(name != NULL && *name == NULL); REQUIRE(msg->cursors[section] != NULL); *name = msg->cursors[section]; } isc_result_t dns_message_findname(dns_message_t *msg, dns_section_t section, dns_name_t *target, dns_rdatatype_t type, dns_rdatatype_t covers, dns_name_t **name, dns_rdataset_t **rdataset) { dns_name_t *foundname; isc_result_t result; /* * XXX These requirements are probably too intensive, especially * where things can be NULL, but as they are they ensure that if * something is NON-NULL, indicating that the caller expects it * to be filled in, that we can in fact fill it in. */ REQUIRE(msg != NULL); REQUIRE(VALID_SECTION(section)); REQUIRE(target != NULL); if (name != NULL) REQUIRE(*name == NULL); if (type == dns_rdatatype_any) { REQUIRE(rdataset == NULL); } else { if (rdataset != NULL) REQUIRE(*rdataset == NULL); } result = findname(&foundname, target, &msg->sections[section]); if (result == ISC_R_NOTFOUND) return (DNS_R_NXDOMAIN); else if (result != ISC_R_SUCCESS) return (result); if (name != NULL) *name = foundname; /* * And now look for the type. */ if (type == dns_rdatatype_any) return (ISC_R_SUCCESS); result = dns_message_findtype(foundname, type, covers, rdataset); if (result == ISC_R_NOTFOUND) return (DNS_R_NXRRSET); return (result); } void dns_message_movename(dns_message_t *msg, dns_name_t *name, dns_section_t fromsection, dns_section_t tosection) { REQUIRE(msg != NULL); REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER); REQUIRE(name != NULL); REQUIRE(VALID_NAMED_SECTION(fromsection)); REQUIRE(VALID_NAMED_SECTION(tosection)); /* * Unlink the name from the old section */ ISC_LIST_UNLINK(msg->sections[fromsection], name, link); ISC_LIST_APPEND(msg->sections[tosection], name, link); } void dns_message_addname(dns_message_t *msg, dns_name_t *name, dns_section_t section) { REQUIRE(msg != NULL); REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER); REQUIRE(name != NULL); REQUIRE(VALID_NAMED_SECTION(section)); ISC_LIST_APPEND(msg->sections[section], name, link); } void dns_message_removename(dns_message_t *msg, dns_name_t *name, dns_section_t section) { REQUIRE(msg != NULL); REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER); REQUIRE(name != NULL); REQUIRE(VALID_NAMED_SECTION(section)); ISC_LIST_UNLINK(msg->sections[section], name, link); } isc_result_t dns_message_gettempname(dns_message_t *msg, dns_name_t **item) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(item != NULL && *item == NULL); *item = isc_mempool_get(msg->namepool); if (*item == NULL) return (ISC_R_NOMEMORY); dns_name_init(*item, NULL); return (ISC_R_SUCCESS); } isc_result_t dns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(item != NULL && *item == NULL); *item = newoffsets(msg); if (*item == NULL) return (ISC_R_NOMEMORY); return (ISC_R_SUCCESS); } isc_result_t dns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(item != NULL && *item == NULL); *item = newrdata(msg); if (*item == NULL) return (ISC_R_NOMEMORY); return (ISC_R_SUCCESS); } isc_result_t dns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(item != NULL && *item == NULL); *item = isc_mempool_get(msg->rdspool); if (*item == NULL) return (ISC_R_NOMEMORY); dns_rdataset_init(*item); return (ISC_R_SUCCESS); } isc_result_t dns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(item != NULL && *item == NULL); *item = newrdatalist(msg); if (*item == NULL) return (ISC_R_NOMEMORY); return (ISC_R_SUCCESS); } void dns_message_puttempname(dns_message_t *msg, dns_name_t **item) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(item != NULL && *item != NULL); if (dns_name_dynamic(*item)) dns_name_free(*item, msg->mctx); isc_mempool_put(msg->namepool, *item); *item = NULL; } void dns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(item != NULL && *item != NULL); releaserdata(msg, *item); *item = NULL; } void dns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(item != NULL && *item != NULL); REQUIRE(!dns_rdataset_isassociated(*item)); isc_mempool_put(msg->rdspool, *item); *item = NULL; } void dns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(item != NULL && *item != NULL); releaserdatalist(msg, *item); *item = NULL; } isc_result_t dns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp, unsigned int *flagsp) { isc_region_t r; isc_buffer_t buffer; dns_messageid_t id; unsigned int flags; REQUIRE(source != NULL); buffer = *source; isc_buffer_remainingregion(&buffer, &r); if (r.length < DNS_MESSAGE_HEADERLEN) return (ISC_R_UNEXPECTEDEND); id = isc_buffer_getuint16(&buffer); flags = isc_buffer_getuint16(&buffer); flags &= DNS_MESSAGE_FLAG_MASK; if (flagsp != NULL) *flagsp = flags; if (idp != NULL) *idp = id; return (ISC_R_SUCCESS); } isc_result_t dns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section) { unsigned int clear_from; isc_result_t result; REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE((msg->flags & DNS_MESSAGEFLAG_QR) == 0); if (!msg->header_ok) return (DNS_R_FORMERR); if (msg->opcode != dns_opcode_query && msg->opcode != dns_opcode_notify) want_question_section = ISC_FALSE; if (msg->opcode == dns_opcode_update) clear_from = DNS_SECTION_PREREQUISITE; else if (want_question_section) { if (!msg->question_ok) return (DNS_R_FORMERR); clear_from = DNS_SECTION_ANSWER; } else clear_from = DNS_SECTION_QUESTION; msg->from_to_wire = DNS_MESSAGE_INTENTRENDER; msgresetnames(msg, clear_from); msgresetopt(msg); msgresetsigs(msg, ISC_TRUE); msginitprivate(msg); /* * We now clear most flags and then set QR, ensuring that the * reply's flags will be in a reasonable state. */ msg->flags &= DNS_MESSAGE_REPLYPRESERVE; msg->flags |= DNS_MESSAGEFLAG_QR; /* * This saves the query TSIG status, if the query was signed, and * reserves space in the reply for the TSIG. */ if (msg->tsigkey != NULL) { unsigned int otherlen = 0; msg->querytsigstatus = msg->tsigstatus; msg->tsigstatus = dns_rcode_noerror; if (msg->querytsigstatus == dns_tsigerror_badtime) otherlen = 6; msg->sig_reserved = spacefortsig(msg->tsigkey, otherlen); result = dns_message_renderreserve(msg, msg->sig_reserved); if (result != ISC_R_SUCCESS) { msg->sig_reserved = 0; return (result); } } if (msg->saved.base != NULL) { msg->query.base = msg->saved.base; msg->query.length = msg->saved.length; msg->free_query = msg->free_saved; msg->saved.base = NULL; msg->saved.length = 0; msg->free_saved = 0; } return (ISC_R_SUCCESS); } dns_rdataset_t * dns_message_getopt(dns_message_t *msg) { /* * Get the OPT record for 'msg'. */ REQUIRE(DNS_MESSAGE_VALID(msg)); return (msg->opt); } isc_result_t dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt) { isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; /* * Set the OPT record for 'msg'. */ /* * The space required for an OPT record is: * * 1 byte for the name * 2 bytes for the type * 2 bytes for the class * 4 bytes for the ttl * 2 bytes for the rdata length * --------------------------------- * 11 bytes * * plus the length of the rdata. */ REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(opt->type == dns_rdatatype_opt); REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER); REQUIRE(msg->state == DNS_SECTION_ANY); msgresetopt(msg); result = dns_rdataset_first(opt); if (result != ISC_R_SUCCESS) goto cleanup; dns_rdataset_current(opt, &rdata); msg->opt_reserved = 11 + rdata.length; result = dns_message_renderreserve(msg, msg->opt_reserved); if (result != ISC_R_SUCCESS) { msg->opt_reserved = 0; goto cleanup; } msg->opt = opt; return (ISC_R_SUCCESS); cleanup: dns_rdataset_disassociate(opt); dns_message_puttemprdataset(msg, &opt); return (result); } dns_rdataset_t * dns_message_gettsig(dns_message_t *msg, dns_name_t **owner) { /* * Get the TSIG record and owner for 'msg'. */ REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(owner == NULL || *owner == NULL); if (owner != NULL) *owner = msg->tsigname; return (msg->tsig); } isc_result_t dns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key) { isc_result_t result; /* * Set the TSIG key for 'msg' */ REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(msg->state == DNS_SECTION_ANY); if (key == NULL && msg->tsigkey != NULL) { if (msg->sig_reserved != 0) { dns_message_renderrelease(msg, msg->sig_reserved); msg->sig_reserved = 0; } dns_tsigkey_detach(&msg->tsigkey); } if (key != NULL) { REQUIRE(msg->tsigkey == NULL && msg->sig0key == NULL); dns_tsigkey_attach(key, &msg->tsigkey); if (msg->from_to_wire == DNS_MESSAGE_INTENTRENDER) { msg->sig_reserved = spacefortsig(msg->tsigkey, 0); result = dns_message_renderreserve(msg, msg->sig_reserved); if (result != ISC_R_SUCCESS) { dns_tsigkey_detach(&msg->tsigkey); msg->sig_reserved = 0; return (result); } } } return (ISC_R_SUCCESS); } dns_tsigkey_t * dns_message_gettsigkey(dns_message_t *msg) { /* * Get the TSIG key for 'msg' */ REQUIRE(DNS_MESSAGE_VALID(msg)); return (msg->tsigkey); } isc_result_t dns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig) { dns_rdata_t *rdata = NULL; dns_rdatalist_t *list = NULL; dns_rdataset_t *set = NULL; isc_buffer_t *buf = NULL; isc_region_t r; isc_result_t result; REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(msg->querytsig == NULL); if (querytsig == NULL) return (ISC_R_SUCCESS); result = dns_message_gettemprdata(msg, &rdata); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_message_gettemprdatalist(msg, &list); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_message_gettemprdataset(msg, &set); if (result != ISC_R_SUCCESS) goto cleanup; isc_buffer_usedregion(querytsig, &r); result = isc_buffer_allocate(msg->mctx, &buf, r.length); if (result != ISC_R_SUCCESS) goto cleanup; isc_buffer_putmem(buf, r.base, r.length); isc_buffer_usedregion(buf, &r); dns_rdata_init(rdata); dns_rdata_fromregion(rdata, dns_rdataclass_any, dns_rdatatype_tsig, &r); dns_message_takebuffer(msg, &buf); ISC_LIST_APPEND(list->rdata, rdata, link); result = dns_rdatalist_tordataset(list, set); if (result != ISC_R_SUCCESS) goto cleanup; msg->querytsig = set; return (result); cleanup: if (rdata != NULL) dns_message_puttemprdata(msg, &rdata); if (list != NULL) dns_message_puttemprdatalist(msg, &list); if (set != NULL) dns_message_puttemprdataset(msg, &set); return (ISC_R_NOMEMORY); } isc_result_t dns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t **querytsig) { isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; isc_region_t r; REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(mctx != NULL); REQUIRE(querytsig != NULL && *querytsig == NULL); if (msg->tsig == NULL) return (ISC_R_SUCCESS); result = dns_rdataset_first(msg->tsig); if (result != ISC_R_SUCCESS) return (result); dns_rdataset_current(msg->tsig, &rdata); dns_rdata_toregion(&rdata, &r); result = isc_buffer_allocate(mctx, querytsig, r.length); if (result != ISC_R_SUCCESS) return (result); isc_buffer_putmem(*querytsig, r.base, r.length); return (ISC_R_SUCCESS); } dns_rdataset_t * dns_message_getsig0(dns_message_t *msg, dns_name_t **owner) { /* * Get the SIG(0) record for 'msg'. */ REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(owner == NULL || *owner == NULL); if (msg->sig0 != NULL && owner != NULL) { /* If dns_message_getsig0 is called on a rendered message * after the SIG(0) has been applied, we need to return the * root name, not NULL. */ if (msg->sig0name == NULL) *owner = dns_rootname; else *owner = msg->sig0name; } return (msg->sig0); } isc_result_t dns_message_setsig0key(dns_message_t *msg, dst_key_t *key) { isc_region_t r; unsigned int x; isc_result_t result; /* * Set the SIG(0) key for 'msg' */ /* * The space required for an SIG(0) record is: * * 1 byte for the name * 2 bytes for the type * 2 bytes for the class * 4 bytes for the ttl * 2 bytes for the type covered * 1 byte for the algorithm * 1 bytes for the labels * 4 bytes for the original ttl * 4 bytes for the signature expiration * 4 bytes for the signature inception * 2 bytes for the key tag * n bytes for the signer's name * x bytes for the signature * --------------------------------- * 27 + n + x bytes */ REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER); REQUIRE(msg->state == DNS_SECTION_ANY); if (key != NULL) { REQUIRE(msg->sig0key == NULL && msg->tsigkey == NULL); dns_name_toregion(dst_key_name(key), &r); result = dst_key_sigsize(key, &x); if (result != ISC_R_SUCCESS) { msg->sig_reserved = 0; return (result); } msg->sig_reserved = 27 + r.length + x; result = dns_message_renderreserve(msg, msg->sig_reserved); if (result != ISC_R_SUCCESS) { msg->sig_reserved = 0; return (result); } msg->sig0key = key; } return (ISC_R_SUCCESS); } dst_key_t * dns_message_getsig0key(dns_message_t *msg) { /* * Get the SIG(0) key for 'msg' */ REQUIRE(DNS_MESSAGE_VALID(msg)); return (msg->sig0key); } void dns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(buffer != NULL); REQUIRE(ISC_BUFFER_VALID(*buffer)); ISC_LIST_APPEND(msg->cleanup, *buffer, link); *buffer = NULL; } isc_result_t dns_message_signer(dns_message_t *msg, dns_name_t *signer) { isc_result_t result = ISC_R_SUCCESS; dns_rdata_t rdata = DNS_RDATA_INIT; REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(signer != NULL); REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE); if (msg->tsig == NULL && msg->sig0 == NULL) return (ISC_R_NOTFOUND); if (msg->verify_attempted == 0) return (DNS_R_NOTVERIFIEDYET); if (!dns_name_hasbuffer(signer)) { isc_buffer_t *dynbuf = NULL; result = isc_buffer_allocate(msg->mctx, &dynbuf, 512); if (result != ISC_R_SUCCESS) return (result); dns_name_setbuffer(signer, dynbuf); dns_message_takebuffer(msg, &dynbuf); } if (msg->sig0 != NULL) { dns_rdata_sig_t sig; result = dns_rdataset_first(msg->sig0); INSIST(result == ISC_R_SUCCESS); dns_rdataset_current(msg->sig0, &rdata); result = dns_rdata_tostruct(&rdata, &sig, NULL); if (result != ISC_R_SUCCESS) return (result); if (msg->verified_sig && msg->sig0status == dns_rcode_noerror) result = ISC_R_SUCCESS; else result = DNS_R_SIGINVALID; dns_name_clone(&sig.signer, signer); dns_rdata_freestruct(&sig); } else { dns_name_t *identity; dns_rdata_any_tsig_t tsig; result = dns_rdataset_first(msg->tsig); INSIST(result == ISC_R_SUCCESS); dns_rdataset_current(msg->tsig, &rdata); result = dns_rdata_tostruct(&rdata, &tsig, NULL); INSIST(result == ISC_R_SUCCESS); if (msg->tsigstatus != dns_rcode_noerror) result = DNS_R_TSIGVERIFYFAILURE; else if (tsig.error != dns_rcode_noerror) result = DNS_R_TSIGERRORSET; else result = ISC_R_SUCCESS; dns_rdata_freestruct(&tsig); if (msg->tsigkey == NULL) { /* * If msg->tsigstatus & tsig.error are both * dns_rcode_noerror, the message must have been * verified, which means msg->tsigkey will be * non-NULL. */ INSIST(result != ISC_R_SUCCESS); } else { identity = dns_tsigkey_identity(msg->tsigkey); if (identity == NULL) { if (result == ISC_R_SUCCESS) result = DNS_R_NOIDENTITY; identity = &msg->tsigkey->name; } dns_name_clone(identity, signer); } } return (result); } void dns_message_resetsig(dns_message_t *msg) { REQUIRE(DNS_MESSAGE_VALID(msg)); msg->verified_sig = 0; msg->verify_attempted = 0; msg->tsigstatus = dns_rcode_noerror; msg->sig0status = dns_rcode_noerror; msg->timeadjust = 0; if (msg->tsigkey != NULL) { dns_tsigkey_detach(&msg->tsigkey); msg->tsigkey = NULL; } } isc_result_t dns_message_rechecksig(dns_message_t *msg, dns_view_t *view) { dns_message_resetsig(msg); return (dns_message_checksig(msg, view)); } #ifdef SKAN_MSG_DEBUG void dns_message_dumpsig(dns_message_t *msg, char *txt1) { dns_rdata_t querytsigrdata = DNS_RDATA_INIT; dns_rdata_any_tsig_t querytsig; isc_result_t result; if (msg->tsig != NULL) { result = dns_rdataset_first(msg->tsig); RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_rdataset_current(msg->tsig, &querytsigrdata); result = dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); hexdump(txt1, "TSIG", querytsig.signature, querytsig.siglen); } if (msg->querytsig != NULL) { result = dns_rdataset_first(msg->querytsig); RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_rdataset_current(msg->querytsig, &querytsigrdata); result = dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); hexdump(txt1, "QUERYTSIG", querytsig.signature, querytsig.siglen); } } #endif isc_result_t dns_message_checksig(dns_message_t *msg, dns_view_t *view) { isc_buffer_t b, msgb; REQUIRE(DNS_MESSAGE_VALID(msg)); if (msg->tsigkey == NULL && msg->tsig == NULL && msg->sig0 == NULL) return (ISC_R_SUCCESS); INSIST(msg->saved.base != NULL); isc_buffer_init(&msgb, msg->saved.base, msg->saved.length); isc_buffer_add(&msgb, msg->saved.length); if (msg->tsigkey != NULL || msg->tsig != NULL) { #ifdef SKAN_MSG_DEBUG dns_message_dumpsig(msg, "dns_message_checksig#1"); #endif if (view != NULL) return (dns_view_checksig(view, &msgb, msg)); else return (dns_tsig_verify(&msgb, msg, NULL, NULL)); } else { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_sig_t sig; dns_rdataset_t keyset; isc_result_t result; result = dns_rdataset_first(msg->sig0); INSIST(result == ISC_R_SUCCESS); dns_rdataset_current(msg->sig0, &rdata); /* * This can occur when the message is a dynamic update, since * the rdata length checking is relaxed. This should not * happen in a well-formed message, since the SIG(0) is only * looked for in the additional section, and the dynamic update * meta-records are in the prerequisite and update sections. */ if (rdata.length == 0) return (ISC_R_UNEXPECTEDEND); result = dns_rdata_tostruct(&rdata, &sig, msg->mctx); if (result != ISC_R_SUCCESS) return (result); dns_rdataset_init(&keyset); if (view == NULL) return (DNS_R_KEYUNAUTHORIZED); result = dns_view_simplefind(view, &sig.signer, dns_rdatatype_key /* SIG(0) */, 0, 0, ISC_FALSE, &keyset, NULL); if (result != ISC_R_SUCCESS) { /* XXXBEW Should possibly create a fetch here */ result = DNS_R_KEYUNAUTHORIZED; goto freesig; } else if (keyset.trust < dns_trust_secure) { /* XXXBEW Should call a validator here */ result = DNS_R_KEYUNAUTHORIZED; goto freesig; } result = dns_rdataset_first(&keyset); INSIST(result == ISC_R_SUCCESS); for (; result == ISC_R_SUCCESS; result = dns_rdataset_next(&keyset)) { dst_key_t *key = NULL; dns_rdata_reset(&rdata); dns_rdataset_current(&keyset, &rdata); isc_buffer_init(&b, rdata.data, rdata.length); isc_buffer_add(&b, rdata.length); result = dst_key_fromdns(&sig.signer, rdata.rdclass, &b, view->mctx, &key); if (result != ISC_R_SUCCESS) continue; if (dst_key_alg(key) != sig.algorithm || dst_key_id(key) != sig.keyid || !(dst_key_proto(key) == DNS_KEYPROTO_DNSSEC || dst_key_proto(key) == DNS_KEYPROTO_ANY)) { dst_key_free(&key); continue; } result = dns_dnssec_verifymessage(&msgb, msg, key); dst_key_free(&key); if (result == ISC_R_SUCCESS) break; } if (result == ISC_R_NOMORE) result = DNS_R_KEYUNAUTHORIZED; freesig: if (dns_rdataset_isassociated(&keyset)) dns_rdataset_disassociate(&keyset); dns_rdata_freestruct(&sig); return (result); } } isc_result_t dns_message_sectiontotext(dns_message_t *msg, dns_section_t section, const dns_master_style_t *style, dns_messagetextflag_t flags, isc_buffer_t *target) { dns_name_t *name, empty_name; dns_rdataset_t *rdataset; isc_result_t result; isc_boolean_t seensoa = ISC_FALSE; REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(target != NULL); REQUIRE(VALID_SECTION(section)); if (ISC_LIST_EMPTY(msg->sections[section])) return (ISC_R_SUCCESS); if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) { ADD_STRING(target, ";; "); if (msg->opcode != dns_opcode_update) { ADD_STRING(target, sectiontext[section]); } else { ADD_STRING(target, updsectiontext[section]); } ADD_STRING(target, " SECTION:\n"); } dns_name_init(&empty_name, NULL); result = dns_message_firstname(msg, section); if (result != ISC_R_SUCCESS) { return (result); } do { name = NULL; dns_message_currentname(msg, section, &name); for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (section == DNS_SECTION_ANSWER && rdataset->type == dns_rdatatype_soa) { if ((flags & DNS_MESSAGETEXTFLAG_OMITSOA) != 0) continue; if (seensoa && (flags & DNS_MESSAGETEXTFLAG_ONESOA) != 0) continue; seensoa = ISC_TRUE; } if (section == DNS_SECTION_QUESTION) { ADD_STRING(target, ";"); result = dns_master_questiontotext(name, rdataset, style, target); } else { result = dns_master_rdatasettotext(name, rdataset, style, target); } if (result != ISC_R_SUCCESS) return (result); } result = dns_message_nextname(msg, section); } while (result == ISC_R_SUCCESS); if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 && (flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) ADD_STRING(target, "\n"); if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; return (result); } static isc_result_t render_ecs(isc_buffer_t *ecsbuf, isc_buffer_t *target) { int i; char addr[16], addr_text[64]; isc_uint16_t family; isc_uint8_t addrlen, addrbytes, scopelen; /* * Note: This routine needs to handle malformed ECS options. */ if (isc_buffer_remaininglength(ecsbuf) < 4) return (DNS_R_OPTERR); family = isc_buffer_getuint16(ecsbuf); addrlen = isc_buffer_getuint8(ecsbuf); scopelen = isc_buffer_getuint8(ecsbuf); addrbytes = (addrlen + 7) / 8; if (isc_buffer_remaininglength(ecsbuf) < addrbytes) return (DNS_R_OPTERR); if (addrbytes > sizeof(addr)) return (DNS_R_OPTERR); ADD_STRING(target, ": "); memset(addr, 0, sizeof(addr)); for (i = 0; i < addrbytes; i ++) addr[i] = isc_buffer_getuint8(ecsbuf); if (family == 1) { if (addrlen > 32 || scopelen > 32) return (DNS_R_OPTERR); inet_ntop(AF_INET, addr, addr_text, sizeof(addr_text)); } else if (family == 2) { if (addrlen > 128 || scopelen > 128) return (DNS_R_OPTERR); inet_ntop(AF_INET6, addr, addr_text, sizeof(addr_text)); } else { snprintf(addr_text, sizeof(addr_text), "Unsupported family %u", family); ADD_STRING(target, addr_text); return (ISC_R_SUCCESS); } ADD_STRING(target, addr_text); snprintf(addr_text, sizeof(addr_text), "/%d/%d", addrlen, scopelen); ADD_STRING(target, addr_text); return (ISC_R_SUCCESS); } isc_result_t dns_message_pseudosectiontotext(dns_message_t *msg, dns_pseudosection_t section, const dns_master_style_t *style, dns_messagetextflag_t flags, isc_buffer_t *target) { dns_rdataset_t *ps = NULL; dns_name_t *name = NULL; isc_result_t result; char buf[sizeof("1234567890")]; isc_uint32_t mbz; dns_rdata_t rdata; isc_buffer_t optbuf; isc_uint16_t optcode, optlen; unsigned char *optdata; REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(target != NULL); REQUIRE(VALID_PSEUDOSECTION(section)); switch (section) { case DNS_PSEUDOSECTION_OPT: ps = dns_message_getopt(msg); if (ps == NULL) return (ISC_R_SUCCESS); if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) ADD_STRING(target, ";; OPT PSEUDOSECTION:\n"); ADD_STRING(target, "; EDNS: version: "); snprintf(buf, sizeof(buf), "%u", (unsigned int)((ps->ttl & 0x00ff0000) >> 16)); ADD_STRING(target, buf); ADD_STRING(target, ", flags:"); if ((ps->ttl & DNS_MESSAGEEXTFLAG_DO) != 0) ADD_STRING(target, " do"); mbz = ps->ttl & 0xffff; mbz &= ~DNS_MESSAGEEXTFLAG_DO; /* Known Flags. */ if (mbz != 0) { ADD_STRING(target, "; MBZ: "); snprintf(buf, sizeof(buf), "%.4x ", mbz); ADD_STRING(target, buf); ADD_STRING(target, ", udp: "); } else ADD_STRING(target, "; udp: "); snprintf(buf, sizeof(buf), "%u\n", (unsigned int)ps->rdclass); ADD_STRING(target, buf); result = dns_rdataset_first(ps); if (result != ISC_R_SUCCESS) return (ISC_R_SUCCESS); /* * Print EDNS info, if any. * * WARNING: The option contents may be malformed as * dig +ednsopt=value: does not validity * checking. */ dns_rdata_init(&rdata); dns_rdataset_current(ps, &rdata); isc_buffer_init(&optbuf, rdata.data, rdata.length); isc_buffer_add(&optbuf, rdata.length); while (isc_buffer_remaininglength(&optbuf) != 0) { INSIST(isc_buffer_remaininglength(&optbuf) >= 4U); optcode = isc_buffer_getuint16(&optbuf); optlen = isc_buffer_getuint16(&optbuf); INSIST(isc_buffer_remaininglength(&optbuf) >= optlen); if (optcode == DNS_OPT_NSID) { ADD_STRING(target, "; NSID"); } else if (optcode == DNS_OPT_COOKIE) { ADD_STRING(target, "; COOKIE"); } else if (optcode == DNS_OPT_CLIENT_SUBNET) { isc_buffer_t ecsbuf; ADD_STRING(target, "; CLIENT-SUBNET"); isc_buffer_init(&ecsbuf, isc_buffer_current(&optbuf), optlen); isc_buffer_add(&ecsbuf, optlen); result = render_ecs(&ecsbuf, target); if (result == ISC_R_NOSPACE) return (result); if (result == ISC_R_SUCCESS) { isc_buffer_forward(&optbuf, optlen); ADD_STRING(target, "\n"); continue; } } else if (optcode == DNS_OPT_EXPIRE) { if (optlen == 4) { isc_uint32_t secs; secs = isc_buffer_getuint32(&optbuf); ADD_STRING(target, "; EXPIRE: "); snprintf(buf, sizeof(buf), "%u", secs); ADD_STRING(target, buf); ADD_STRING(target, " ("); dns_ttl_totext(secs, ISC_TRUE, target); ADD_STRING(target, ")\n"); continue; } ADD_STRING(target, "; EXPIRE"); } else { ADD_STRING(target, "; OPT="); snprintf(buf, sizeof(buf), "%u", optcode); ADD_STRING(target, buf); } if (optlen != 0) { int i; ADD_STRING(target, ": "); optdata = isc_buffer_current(&optbuf); for (i = 0; i < optlen; i++) { const char *sep; switch (optcode) { case DNS_OPT_COOKIE: sep = ""; break; default: sep = " "; break; } snprintf(buf, sizeof(buf), "%02x%s", optdata[i], sep); ADD_STRING(target, buf); } isc_buffer_forward(&optbuf, optlen); if (optcode == DNS_OPT_COOKIE) { if (msg->sitok) ADD_STRING(target, " (good)"); if (msg->sitbad) ADD_STRING(target, " (bad)"); ADD_STRING(target, "\n"); continue; } if (optcode == DNS_OPT_CLIENT_SUBNET) { ADD_STRING(target, "\n"); continue; } /* * For non-SIT options, add a printable * version */ ADD_STRING(target, "(\""); if (isc_buffer_availablelength(target) < optlen) return (ISC_R_NOSPACE); for (i = 0; i < optlen; i++) { if (isprint(optdata[i])) isc_buffer_putmem(target, &optdata[i], 1); else isc_buffer_putstr(target, "."); } ADD_STRING(target, "\")"); } ADD_STRING(target, "\n"); } return (ISC_R_SUCCESS); case DNS_PSEUDOSECTION_TSIG: ps = dns_message_gettsig(msg, &name); if (ps == NULL) return (ISC_R_SUCCESS); if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) ADD_STRING(target, ";; TSIG PSEUDOSECTION:\n"); result = dns_master_rdatasettotext(name, ps, style, target); if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 && (flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) ADD_STRING(target, "\n"); return (result); case DNS_PSEUDOSECTION_SIG0: ps = dns_message_getsig0(msg, &name); if (ps == NULL) return (ISC_R_SUCCESS); if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) ADD_STRING(target, ";; SIG0 PSEUDOSECTION:\n"); result = dns_master_rdatasettotext(name, ps, style, target); if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 && (flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) ADD_STRING(target, "\n"); return (result); } return (ISC_R_UNEXPECTED); } isc_result_t dns_message_totext(dns_message_t *msg, const dns_master_style_t *style, dns_messagetextflag_t flags, isc_buffer_t *target) { char buf[sizeof("1234567890")]; isc_result_t result; REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(target != NULL); if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0) { ADD_STRING(target, ";; ->>HEADER<<- opcode: "); ADD_STRING(target, opcodetext[msg->opcode]); ADD_STRING(target, ", status: "); if (msg->rcode < (sizeof(rcodetext)/sizeof(rcodetext[0]))) { ADD_STRING(target, rcodetext[msg->rcode]); } else { snprintf(buf, sizeof(buf), "%4u", msg->rcode); ADD_STRING(target, buf); } ADD_STRING(target, ", id: "); snprintf(buf, sizeof(buf), "%6u", msg->id); ADD_STRING(target, buf); ADD_STRING(target, "\n;; flags:"); if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) ADD_STRING(target, " qr"); if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0) ADD_STRING(target, " aa"); if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) ADD_STRING(target, " tc"); if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0) ADD_STRING(target, " rd"); if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0) ADD_STRING(target, " ra"); if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0) ADD_STRING(target, " ad"); if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0) ADD_STRING(target, " cd"); /* * The final unnamed flag must be zero. */ if ((msg->flags & 0x0040U) != 0) ADD_STRING(target, "; MBZ: 0x4"); if (msg->opcode != dns_opcode_update) { ADD_STRING(target, "; QUESTION: "); } else { ADD_STRING(target, "; ZONE: "); } snprintf(buf, sizeof(buf), "%1u", msg->counts[DNS_SECTION_QUESTION]); ADD_STRING(target, buf); if (msg->opcode != dns_opcode_update) { ADD_STRING(target, ", ANSWER: "); } else { ADD_STRING(target, ", PREREQ: "); } snprintf(buf, sizeof(buf), "%1u", msg->counts[DNS_SECTION_ANSWER]); ADD_STRING(target, buf); if (msg->opcode != dns_opcode_update) { ADD_STRING(target, ", AUTHORITY: "); } else { ADD_STRING(target, ", UPDATE: "); } snprintf(buf, sizeof(buf), "%1u", msg->counts[DNS_SECTION_AUTHORITY]); ADD_STRING(target, buf); ADD_STRING(target, ", ADDITIONAL: "); snprintf(buf, sizeof(buf), "%1u", msg->counts[DNS_SECTION_ADDITIONAL]); ADD_STRING(target, buf); ADD_STRING(target, "\n"); } result = dns_message_pseudosectiontotext(msg, DNS_PSEUDOSECTION_OPT, style, flags, target); if (result != ISC_R_SUCCESS) return (result); result = dns_message_sectiontotext(msg, DNS_SECTION_QUESTION, style, flags, target); if (result != ISC_R_SUCCESS) return (result); result = dns_message_sectiontotext(msg, DNS_SECTION_ANSWER, style, flags, target); if (result != ISC_R_SUCCESS) return (result); result = dns_message_sectiontotext(msg, DNS_SECTION_AUTHORITY, style, flags, target); if (result != ISC_R_SUCCESS) return (result); result = dns_message_sectiontotext(msg, DNS_SECTION_ADDITIONAL, style, flags, target); if (result != ISC_R_SUCCESS) return (result); result = dns_message_pseudosectiontotext(msg, DNS_PSEUDOSECTION_TSIG, style, flags, target); if (result != ISC_R_SUCCESS) return (result); result = dns_message_pseudosectiontotext(msg, DNS_PSEUDOSECTION_SIG0, style, flags, target); if (result != ISC_R_SUCCESS) return (result); return (ISC_R_SUCCESS); } isc_region_t * dns_message_getrawmessage(dns_message_t *msg) { REQUIRE(DNS_MESSAGE_VALID(msg)); return (&msg->saved); } void dns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order, const void *order_arg) { REQUIRE(DNS_MESSAGE_VALID(msg)); msg->order = order; msg->order_arg = order_arg; } void dns_message_settimeadjust(dns_message_t *msg, int timeadjust) { REQUIRE(DNS_MESSAGE_VALID(msg)); msg->timeadjust = timeadjust; } int dns_message_gettimeadjust(dns_message_t *msg) { REQUIRE(DNS_MESSAGE_VALID(msg)); return (msg->timeadjust); } isc_result_t dns_opcode_totext(dns_opcode_t opcode, isc_buffer_t *target) { REQUIRE(opcode < 16); if (isc_buffer_availablelength(target) < strlen(opcodetext[opcode])) return (ISC_R_NOSPACE); isc_buffer_putstr(target, opcodetext[opcode]); return (ISC_R_SUCCESS); } void dns_message_logpacket(dns_message_t *message, const char *description, isc_logcategory_t *category, isc_logmodule_t *module, int level, isc_mem_t *mctx) { dns_message_logfmtpacket(message, description, category, module, &dns_master_style_debug, level, mctx); } void dns_message_logfmtpacket(dns_message_t *message, const char *description, isc_logcategory_t *category, isc_logmodule_t *module, const dns_master_style_t *style, int level, isc_mem_t *mctx) { isc_buffer_t buffer; char *buf = NULL; int len = 1024; isc_result_t result; if (! isc_log_wouldlog(dns_lctx, level)) return; /* * Note that these are multiline debug messages. We want a newline * to appear in the log after each message. */ do { buf = isc_mem_get(mctx, len); if (buf == NULL) break; isc_buffer_init(&buffer, buf, len); result = dns_message_totext(message, style, 0, &buffer); if (result == ISC_R_NOSPACE) { isc_mem_put(mctx, buf, len); len += 1024; } else if (result == ISC_R_SUCCESS) isc_log_write(dns_lctx, category, module, level, "%s%.*s", description, (int)isc_buffer_usedlength(&buffer), buf); } while (result == ISC_R_NOSPACE); if (buf != NULL) isc_mem_put(mctx, buf, len); } isc_result_t dns_message_buildopt(dns_message_t *message, dns_rdataset_t **rdatasetp, unsigned int version, isc_uint16_t udpsize, unsigned int flags, dns_ednsopt_t *ednsopts, size_t count) { dns_rdataset_t *rdataset = NULL; dns_rdatalist_t *rdatalist = NULL; dns_rdata_t *rdata = NULL; isc_result_t result; unsigned int len = 0, i; REQUIRE(DNS_MESSAGE_VALID(message)); REQUIRE(rdatasetp != NULL && *rdatasetp == NULL); result = dns_message_gettemprdatalist(message, &rdatalist); if (result != ISC_R_SUCCESS) return (result); result = dns_message_gettemprdata(message, &rdata); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_message_gettemprdataset(message, &rdataset); if (result != ISC_R_SUCCESS) goto cleanup; rdatalist->type = dns_rdatatype_opt; /* * Set Maximum UDP buffer size. */ rdatalist->rdclass = udpsize; /* * Set EXTENDED-RCODE and Z to 0. */ rdatalist->ttl = (version << 16); rdatalist->ttl |= (flags & 0xffff); /* * Set EDNS options if applicable */ if (count != 0U) { isc_buffer_t *buf = NULL; for (i = 0; i < count; i++) len += ednsopts[i].length + 4; if (len > 0xffffU) { result = ISC_R_NOSPACE; goto cleanup; } result = isc_buffer_allocate(message->mctx, &buf, len); if (result != ISC_R_SUCCESS) goto cleanup; for (i = 0; i < count; i++) { isc_buffer_putuint16(buf, ednsopts[i].code); isc_buffer_putuint16(buf, ednsopts[i].length); isc_buffer_putmem(buf, ednsopts[i].value, ednsopts[i].length); } rdata->data = isc_buffer_base(buf); rdata->length = len; dns_message_takebuffer(message, &buf); } else { rdata->data = NULL; rdata->length = 0; } rdata->rdclass = rdatalist->rdclass; rdata->type = rdatalist->type; rdata->flags = 0; ISC_LIST_APPEND(rdatalist->rdata, rdata, link); result = dns_rdatalist_tordataset(rdatalist, rdataset); RUNTIME_CHECK(result == ISC_R_SUCCESS); *rdatasetp = rdataset; return (ISC_R_SUCCESS); cleanup: if (rdata != NULL) dns_message_puttemprdata(message, &rdata); if (rdataset != NULL) dns_message_puttemprdataset(message, &rdataset); if (rdatalist != NULL) dns_message_puttemprdatalist(message, &rdatalist); return (result); } void dns_message_setclass(dns_message_t *msg, dns_rdataclass_t rdclass) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE); REQUIRE(msg->state == DNS_SECTION_ANY); REQUIRE(msg->rdclass_set == 0); msg->rdclass = rdclass; msg->rdclass_set = 1; } bind9-9.10.3.dfsg.P4/lib/dns/rbtdb64.h0000644000470500017500000000256612664710322016354 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rbtdb64.h,v 1.17 2007/06/19 23:47:16 tbox Exp $ */ #ifndef DNS_RBTDB64_H #define DNS_RBTDB64_H 1 #include /***** ***** Module Info *****/ /*! \file * \brief * DNS Red-Black Tree DB Implementation with 64-bit version numbers */ #include ISC_LANG_BEGINDECLS isc_result_t dns_rbtdb64_create(isc_mem_t *mctx, dns_name_t *base, dns_dbtype_t type, dns_rdataclass_t rdclass, unsigned int argc, char *argv[], void *driverarg, dns_db_t **dbp); ISC_LANG_ENDDECLS #endif /* DNS_RBTDB64_H */ bind9-9.10.3.dfsg.P4/lib/dns/view.c0000644000470500017500000014360512664710322016052 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #include #include #include #include /* Required for HP/UX (and others?) */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define RESSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_RESSHUTDOWN) != 0) #define ADBSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_ADBSHUTDOWN) != 0) #define REQSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_REQSHUTDOWN) != 0) #define DNS_VIEW_DELONLYHASH 111 static void resolver_shutdown(isc_task_t *task, isc_event_t *event); static void adb_shutdown(isc_task_t *task, isc_event_t *event); static void req_shutdown(isc_task_t *task, isc_event_t *event); isc_result_t dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, const char *name, dns_view_t **viewp) { dns_view_t *view; isc_result_t result; /* * Create a view. */ REQUIRE(name != NULL); REQUIRE(viewp != NULL && *viewp == NULL); view = isc_mem_get(mctx, sizeof(*view)); if (view == NULL) return (ISC_R_NOMEMORY); view->mctx = NULL; isc_mem_attach(mctx, &view->mctx); view->name = isc_mem_strdup(mctx, name); if (view->name == NULL) { result = ISC_R_NOMEMORY; goto cleanup_view; } result = isc_mutex_init(&view->lock); if (result != ISC_R_SUCCESS) goto cleanup_name; view->zonetable = NULL; if (isc_bind9) { result = dns_zt_create(mctx, rdclass, &view->zonetable); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "dns_zt_create() failed: %s", isc_result_totext(result)); result = ISC_R_UNEXPECTED; goto cleanup_mutex; } } view->secroots_priv = NULL; view->fwdtable = NULL; result = dns_fwdtable_create(mctx, &view->fwdtable); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "dns_fwdtable_create() failed: %s", isc_result_totext(result)); result = ISC_R_UNEXPECTED; goto cleanup_zt; } view->acache = NULL; view->cache = NULL; view->cachedb = NULL; ISC_LIST_INIT(view->dlz_searched); ISC_LIST_INIT(view->dlz_unsearched); view->hints = NULL; view->resolver = NULL; view->adb = NULL; view->requestmgr = NULL; view->rdclass = rdclass; view->frozen = ISC_FALSE; view->task = NULL; result = isc_refcount_init(&view->references, 1); if (result != ISC_R_SUCCESS) goto cleanup_fwdtable; view->weakrefs = 0; view->attributes = (DNS_VIEWATTR_RESSHUTDOWN|DNS_VIEWATTR_ADBSHUTDOWN| DNS_VIEWATTR_REQSHUTDOWN); view->statickeys = NULL; view->dynamickeys = NULL; view->matchclients = NULL; view->matchdestinations = NULL; view->matchrecursiveonly = ISC_FALSE; result = dns_tsigkeyring_create(view->mctx, &view->dynamickeys); if (result != ISC_R_SUCCESS) goto cleanup_references; view->peers = NULL; view->order = NULL; view->delonly = NULL; view->rootdelonly = ISC_FALSE; view->rootexclude = NULL; view->adbstats = NULL; view->resstats = NULL; view->resquerystats = NULL; view->cacheshared = ISC_FALSE; ISC_LIST_INIT(view->dns64); view->dns64cnt = 0; /* * Initialize configuration data with default values. */ view->recursion = ISC_TRUE; view->auth_nxdomain = ISC_FALSE; /* Was true in BIND 8 */ view->additionalfromcache = ISC_TRUE; view->additionalfromauth = ISC_TRUE; view->enablednssec = ISC_TRUE; view->enablevalidation = ISC_TRUE; view->acceptexpired = ISC_FALSE; view->minimalresponses = ISC_FALSE; view->transfer_format = dns_one_answer; view->cacheacl = NULL; view->cacheonacl = NULL; view->queryacl = NULL; view->queryonacl = NULL; view->recursionacl = NULL; view->recursiononacl = NULL; view->sortlist = NULL; view->transferacl = NULL; view->notifyacl = NULL; view->updateacl = NULL; view->upfwdacl = NULL; view->denyansweracl = NULL; view->nocasecompress = NULL; view->answeracl_exclude = NULL; view->denyanswernames = NULL; view->answernames_exclude = NULL; view->rrl = NULL; view->provideixfr = ISC_TRUE; view->maxcachettl = 7 * 24 * 3600; view->maxncachettl = 3 * 3600; view->prefetch_eligible = 0; view->prefetch_trigger = 0; view->dstport = 53; view->preferred_glue = 0; view->flush = ISC_FALSE; view->dlv = NULL; view->maxudp = 0; view->situdp = 0; view->maxbits = 0; view->v4_aaaa = dns_aaaa_ok; view->v6_aaaa = dns_aaaa_ok; view->aaaa_acl = NULL; view->rpzs = NULL; dns_fixedname_init(&view->dlv_fixed); view->managed_keys = NULL; view->redirect = NULL; view->requestnsid = ISC_FALSE; view->requestsit = ISC_TRUE; view->new_zone_file = NULL; view->new_zone_config = NULL; view->cfg_destroy = NULL; if (isc_bind9) { result = dns_order_create(view->mctx, &view->order); if (result != ISC_R_SUCCESS) goto cleanup_dynkeys; } result = dns_peerlist_new(view->mctx, &view->peers); if (result != ISC_R_SUCCESS) goto cleanup_order; result = dns_aclenv_init(view->mctx, &view->aclenv); if (result != ISC_R_SUCCESS) goto cleanup_peerlist; ISC_LINK_INIT(view, link); ISC_EVENT_INIT(&view->resevent, sizeof(view->resevent), 0, NULL, DNS_EVENT_VIEWRESSHUTDOWN, resolver_shutdown, view, NULL, NULL, NULL); ISC_EVENT_INIT(&view->adbevent, sizeof(view->adbevent), 0, NULL, DNS_EVENT_VIEWADBSHUTDOWN, adb_shutdown, view, NULL, NULL, NULL); ISC_EVENT_INIT(&view->reqevent, sizeof(view->reqevent), 0, NULL, DNS_EVENT_VIEWREQSHUTDOWN, req_shutdown, view, NULL, NULL, NULL); view->viewlist = NULL; view->magic = DNS_VIEW_MAGIC; *viewp = view; return (ISC_R_SUCCESS); cleanup_peerlist: if (view->peers != NULL) dns_peerlist_detach(&view->peers); cleanup_order: if (view->order != NULL) dns_order_detach(&view->order); cleanup_dynkeys: if (view->dynamickeys != NULL) dns_tsigkeyring_detach(&view->dynamickeys); cleanup_references: isc_refcount_destroy(&view->references); cleanup_fwdtable: if (view->fwdtable != NULL) dns_fwdtable_destroy(&view->fwdtable); cleanup_zt: if (view->zonetable != NULL) dns_zt_detach(&view->zonetable); cleanup_mutex: DESTROYLOCK(&view->lock); cleanup_name: isc_mem_free(mctx, view->name); cleanup_view: isc_mem_putanddetach(&view->mctx, view, sizeof(*view)); return (result); } static inline void destroy(dns_view_t *view) { dns_dns64_t *dns64; dns_dlzdb_t *dlzdb; REQUIRE(!ISC_LINK_LINKED(view, link)); REQUIRE(isc_refcount_current(&view->references) == 0); REQUIRE(view->weakrefs == 0); REQUIRE(RESSHUTDOWN(view)); REQUIRE(ADBSHUTDOWN(view)); REQUIRE(REQSHUTDOWN(view)); if (view->order != NULL) dns_order_detach(&view->order); if (view->peers != NULL) dns_peerlist_detach(&view->peers); if (view->dynamickeys != NULL) { isc_result_t result; char template[20]; char keyfile[20]; FILE *fp = NULL; int n; n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys", view->name); if (n > 0 && (size_t)n < sizeof(keyfile)) { result = isc_file_mktemplate(keyfile, template, sizeof(template)); if (result == ISC_R_SUCCESS) (void)isc_file_openuniqueprivate(template, &fp); } if (fp == NULL) dns_tsigkeyring_detach(&view->dynamickeys); else { result = dns_tsigkeyring_dumpanddetach( &view->dynamickeys, fp); if (result == ISC_R_SUCCESS) { if (fclose(fp) == 0) result = isc_file_rename(template, keyfile); if (result != ISC_R_SUCCESS) (void)remove(template); } else { (void)fclose(fp); (void)remove(template); } } } if (view->statickeys != NULL) dns_tsigkeyring_detach(&view->statickeys); if (view->adb != NULL) dns_adb_detach(&view->adb); if (view->resolver != NULL) dns_resolver_detach(&view->resolver); if (view->acache != NULL) { if (view->cachedb != NULL) dns_acache_putdb(view->acache, view->cachedb); dns_acache_detach(&view->acache); } dns_rrl_view_destroy(view); if (view->rpzs != NULL) dns_rpz_detach_rpzs(&view->rpzs); for (dlzdb = ISC_LIST_HEAD(view->dlz_searched); dlzdb != NULL; dlzdb = ISC_LIST_HEAD(view->dlz_searched)) { ISC_LIST_UNLINK(view->dlz_searched, dlzdb, link); dns_dlzdestroy(&dlzdb); } for (dlzdb = ISC_LIST_HEAD(view->dlz_unsearched); dlzdb != NULL; dlzdb = ISC_LIST_HEAD(view->dlz_unsearched)) { ISC_LIST_UNLINK(view->dlz_unsearched, dlzdb, link); dns_dlzdestroy(&dlzdb); } if (view->requestmgr != NULL) dns_requestmgr_detach(&view->requestmgr); if (view->task != NULL) isc_task_detach(&view->task); if (view->hints != NULL) dns_db_detach(&view->hints); if (view->cachedb != NULL) dns_db_detach(&view->cachedb); if (view->cache != NULL) dns_cache_detach(&view->cache); if (view->nocasecompress != NULL) dns_acl_detach(&view->nocasecompress); if (view->matchclients != NULL) dns_acl_detach(&view->matchclients); if (view->matchdestinations != NULL) dns_acl_detach(&view->matchdestinations); if (view->cacheacl != NULL) dns_acl_detach(&view->cacheacl); if (view->cacheonacl != NULL) dns_acl_detach(&view->cacheonacl); if (view->queryacl != NULL) dns_acl_detach(&view->queryacl); if (view->queryonacl != NULL) dns_acl_detach(&view->queryonacl); if (view->recursionacl != NULL) dns_acl_detach(&view->recursionacl); if (view->recursiononacl != NULL) dns_acl_detach(&view->recursiononacl); if (view->sortlist != NULL) dns_acl_detach(&view->sortlist); if (view->transferacl != NULL) dns_acl_detach(&view->transferacl); if (view->notifyacl != NULL) dns_acl_detach(&view->notifyacl); if (view->updateacl != NULL) dns_acl_detach(&view->updateacl); if (view->upfwdacl != NULL) dns_acl_detach(&view->upfwdacl); if (view->denyansweracl != NULL) dns_acl_detach(&view->denyansweracl); if (view->aaaa_acl != NULL) dns_acl_detach(&view->aaaa_acl); if (view->answeracl_exclude != NULL) dns_rbt_destroy(&view->answeracl_exclude); if (view->denyanswernames != NULL) dns_rbt_destroy(&view->denyanswernames); if (view->answernames_exclude != NULL) dns_rbt_destroy(&view->answernames_exclude); if (view->delonly != NULL) { dns_name_t *name; int i; for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) { name = ISC_LIST_HEAD(view->delonly[i]); while (name != NULL) { ISC_LIST_UNLINK(view->delonly[i], name, link); dns_name_free(name, view->mctx); isc_mem_put(view->mctx, name, sizeof(*name)); name = ISC_LIST_HEAD(view->delonly[i]); } } isc_mem_put(view->mctx, view->delonly, sizeof(dns_namelist_t) * DNS_VIEW_DELONLYHASH); view->delonly = NULL; } if (view->rootexclude != NULL) { dns_name_t *name; int i; for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) { name = ISC_LIST_HEAD(view->rootexclude[i]); while (name != NULL) { ISC_LIST_UNLINK(view->rootexclude[i], name, link); dns_name_free(name, view->mctx); isc_mem_put(view->mctx, name, sizeof(*name)); name = ISC_LIST_HEAD(view->rootexclude[i]); } } isc_mem_put(view->mctx, view->rootexclude, sizeof(dns_namelist_t) * DNS_VIEW_DELONLYHASH); view->rootexclude = NULL; } if (view->adbstats != NULL) isc_stats_detach(&view->adbstats); if (view->resstats != NULL) isc_stats_detach(&view->resstats); if (view->resquerystats != NULL) dns_stats_detach(&view->resquerystats); if (view->secroots_priv != NULL) dns_keytable_detach(&view->secroots_priv); for (dns64 = ISC_LIST_HEAD(view->dns64); dns64 != NULL; dns64 = ISC_LIST_HEAD(view->dns64)) { dns_dns64_unlink(&view->dns64, dns64); dns_dns64_destroy(&dns64); } if (view->managed_keys != NULL) dns_zone_detach(&view->managed_keys); if (view->redirect != NULL) dns_zone_detach(&view->redirect); dns_view_setnewzones(view, ISC_FALSE, NULL, NULL); dns_fwdtable_destroy(&view->fwdtable); dns_aclenv_destroy(&view->aclenv); DESTROYLOCK(&view->lock); isc_refcount_destroy(&view->references); isc_mem_free(view->mctx, view->name); isc_mem_putanddetach(&view->mctx, view, sizeof(*view)); } /* * Return true iff 'view' may be freed. * The caller must be holding the view lock. */ static isc_boolean_t all_done(dns_view_t *view) { if (isc_refcount_current(&view->references) == 0 && view->weakrefs == 0 && RESSHUTDOWN(view) && ADBSHUTDOWN(view) && REQSHUTDOWN(view)) return (ISC_TRUE); return (ISC_FALSE); } void dns_view_attach(dns_view_t *source, dns_view_t **targetp) { REQUIRE(DNS_VIEW_VALID(source)); REQUIRE(targetp != NULL && *targetp == NULL); isc_refcount_increment(&source->references, NULL); *targetp = source; } static void view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) { dns_view_t *view; unsigned int refs; isc_boolean_t done = ISC_FALSE; REQUIRE(viewp != NULL); view = *viewp; REQUIRE(DNS_VIEW_VALID(view)); if (flush) view->flush = ISC_TRUE; isc_refcount_decrement(&view->references, &refs); if (refs == 0) { dns_zone_t *mkzone = NULL, *rdzone = NULL; LOCK(&view->lock); if (!RESSHUTDOWN(view)) dns_resolver_shutdown(view->resolver); if (!ADBSHUTDOWN(view)) dns_adb_shutdown(view->adb); if (!REQSHUTDOWN(view)) dns_requestmgr_shutdown(view->requestmgr); if (view->acache != NULL) dns_acache_shutdown(view->acache); if (view->zonetable != NULL) { if (view->flush) dns_zt_flushanddetach(&view->zonetable); else dns_zt_detach(&view->zonetable); } if (view->managed_keys != NULL) { mkzone = view->managed_keys; view->managed_keys = NULL; if (view->flush) dns_zone_flush(mkzone); } if (view->redirect != NULL) { rdzone = view->redirect; view->redirect = NULL; if (view->flush) dns_zone_flush(rdzone); } done = all_done(view); UNLOCK(&view->lock); /* Need to detach zones outside view lock */ if (mkzone != NULL) dns_zone_detach(&mkzone); if (rdzone != NULL) dns_zone_detach(&rdzone); } *viewp = NULL; if (done) destroy(view); } void dns_view_flushanddetach(dns_view_t **viewp) { view_flushanddetach(viewp, ISC_TRUE); } void dns_view_detach(dns_view_t **viewp) { view_flushanddetach(viewp, ISC_FALSE); } static isc_result_t dialup(dns_zone_t *zone, void *dummy) { UNUSED(dummy); dns_zone_dialup(zone); return (ISC_R_SUCCESS); } void dns_view_dialup(dns_view_t *view) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(view->zonetable != NULL); (void)dns_zt_apply(view->zonetable, ISC_FALSE, dialup, NULL); } void dns_view_weakattach(dns_view_t *source, dns_view_t **targetp) { REQUIRE(DNS_VIEW_VALID(source)); REQUIRE(targetp != NULL && *targetp == NULL); LOCK(&source->lock); source->weakrefs++; UNLOCK(&source->lock); *targetp = source; } void dns_view_weakdetach(dns_view_t **viewp) { dns_view_t *view; isc_boolean_t done = ISC_FALSE; REQUIRE(viewp != NULL); view = *viewp; REQUIRE(DNS_VIEW_VALID(view)); LOCK(&view->lock); INSIST(view->weakrefs > 0); view->weakrefs--; done = all_done(view); UNLOCK(&view->lock); *viewp = NULL; if (done) destroy(view); } static void resolver_shutdown(isc_task_t *task, isc_event_t *event) { dns_view_t *view = event->ev_arg; isc_boolean_t done; REQUIRE(event->ev_type == DNS_EVENT_VIEWRESSHUTDOWN); REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(view->task == task); UNUSED(task); isc_event_free(&event); LOCK(&view->lock); view->attributes |= DNS_VIEWATTR_RESSHUTDOWN; done = all_done(view); UNLOCK(&view->lock); if (done) destroy(view); } static void adb_shutdown(isc_task_t *task, isc_event_t *event) { dns_view_t *view = event->ev_arg; isc_boolean_t done; REQUIRE(event->ev_type == DNS_EVENT_VIEWADBSHUTDOWN); REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(view->task == task); UNUSED(task); isc_event_free(&event); LOCK(&view->lock); view->attributes |= DNS_VIEWATTR_ADBSHUTDOWN; done = all_done(view); UNLOCK(&view->lock); if (done) destroy(view); } static void req_shutdown(isc_task_t *task, isc_event_t *event) { dns_view_t *view = event->ev_arg; isc_boolean_t done; REQUIRE(event->ev_type == DNS_EVENT_VIEWREQSHUTDOWN); REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(view->task == task); UNUSED(task); isc_event_free(&event); LOCK(&view->lock); view->attributes |= DNS_VIEWATTR_REQSHUTDOWN; done = all_done(view); UNLOCK(&view->lock); if (done) destroy(view); } isc_result_t dns_view_createzonetable(dns_view_t *view) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(!view->frozen); REQUIRE(view->zonetable == NULL); return (dns_zt_create(view->mctx, view->rdclass, &view->zonetable)); } isc_result_t dns_view_createresolver(dns_view_t *view, isc_taskmgr_t *taskmgr, unsigned int ntasks, unsigned int ndisp, isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr, unsigned int options, dns_dispatchmgr_t *dispatchmgr, dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6) { isc_result_t result; isc_event_t *event; isc_mem_t *mctx = NULL; REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(!view->frozen); REQUIRE(view->resolver == NULL); result = isc_task_create(taskmgr, 0, &view->task); if (result != ISC_R_SUCCESS) return (result); isc_task_setname(view->task, "view", view); result = dns_resolver_create(view, taskmgr, ntasks, ndisp, socketmgr, timermgr, options, dispatchmgr, dispatchv4, dispatchv6, &view->resolver); if (result != ISC_R_SUCCESS) { isc_task_detach(&view->task); return (result); } event = &view->resevent; dns_resolver_whenshutdown(view->resolver, view->task, &event); view->attributes &= ~DNS_VIEWATTR_RESSHUTDOWN; result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) { dns_resolver_shutdown(view->resolver); return (result); } result = dns_adb_create(mctx, view, timermgr, taskmgr, &view->adb); isc_mem_setname(mctx, "ADB", NULL); isc_mem_detach(&mctx); if (result != ISC_R_SUCCESS) { dns_resolver_shutdown(view->resolver); return (result); } event = &view->adbevent; dns_adb_whenshutdown(view->adb, view->task, &event); view->attributes &= ~DNS_VIEWATTR_ADBSHUTDOWN; result = dns_requestmgr_create(view->mctx, timermgr, socketmgr, dns_resolver_taskmgr(view->resolver), dns_resolver_dispatchmgr(view->resolver), dispatchv4, dispatchv6, &view->requestmgr); if (result != ISC_R_SUCCESS) { dns_adb_shutdown(view->adb); dns_resolver_shutdown(view->resolver); return (result); } event = &view->reqevent; dns_requestmgr_whenshutdown(view->requestmgr, view->task, &event); view->attributes &= ~DNS_VIEWATTR_REQSHUTDOWN; return (ISC_R_SUCCESS); } void dns_view_setcache(dns_view_t *view, dns_cache_t *cache) { dns_view_setcache2(view, cache, ISC_FALSE); } void dns_view_setcache2(dns_view_t *view, dns_cache_t *cache, isc_boolean_t shared) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(!view->frozen); view->cacheshared = shared; if (view->cache != NULL) { if (view->acache != NULL) dns_acache_putdb(view->acache, view->cachedb); dns_db_detach(&view->cachedb); dns_cache_detach(&view->cache); } dns_cache_attach(cache, &view->cache); dns_cache_attachdb(cache, &view->cachedb); INSIST(DNS_DB_VALID(view->cachedb)); if (view->acache != NULL) dns_acache_setdb(view->acache, view->cachedb); } isc_boolean_t dns_view_iscacheshared(dns_view_t *view) { REQUIRE(DNS_VIEW_VALID(view)); return (view->cacheshared); } void dns_view_sethints(dns_view_t *view, dns_db_t *hints) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(!view->frozen); REQUIRE(view->hints == NULL); REQUIRE(dns_db_iszone(hints)); dns_db_attach(hints, &view->hints); } void dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(ring != NULL); if (view->statickeys != NULL) dns_tsigkeyring_detach(&view->statickeys); dns_tsigkeyring_attach(ring, &view->statickeys); } void dns_view_setdynamickeyring(dns_view_t *view, dns_tsig_keyring_t *ring) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(ring != NULL); if (view->dynamickeys != NULL) dns_tsigkeyring_detach(&view->dynamickeys); dns_tsigkeyring_attach(ring, &view->dynamickeys); } void dns_view_getdynamickeyring(dns_view_t *view, dns_tsig_keyring_t **ringp) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(ringp != NULL && *ringp == NULL); if (view->dynamickeys != NULL) dns_tsigkeyring_attach(view->dynamickeys, ringp); } void dns_view_restorekeyring(dns_view_t *view) { FILE *fp; char keyfile[20]; int n; REQUIRE(DNS_VIEW_VALID(view)); if (view->dynamickeys != NULL) { n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys", view->name); if (n > 0 && (size_t)n < sizeof(keyfile)) { fp = fopen(keyfile, "r"); if (fp != NULL) { dns_keyring_restore(view->dynamickeys, fp); (void)fclose(fp); } } } } void dns_view_setdstport(dns_view_t *view, in_port_t dstport) { REQUIRE(DNS_VIEW_VALID(view)); view->dstport = dstport; } void dns_view_freeze(dns_view_t *view) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(!view->frozen); if (view->resolver != NULL) { INSIST(view->cachedb != NULL); dns_resolver_freeze(view->resolver); } view->frozen = ISC_TRUE; } void dns_view_thaw(dns_view_t *view) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(view->frozen); view->frozen = ISC_FALSE; } isc_result_t dns_view_addzone(dns_view_t *view, dns_zone_t *zone) { isc_result_t result; REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(!view->frozen); REQUIRE(view->zonetable != NULL); result = dns_zt_mount(view->zonetable, zone); return (result); } isc_result_t dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep) { isc_result_t result; REQUIRE(DNS_VIEW_VALID(view)); LOCK(&view->lock); if (view->zonetable != NULL) { result = dns_zt_find(view->zonetable, name, 0, NULL, zonep); if (result == DNS_R_PARTIALMATCH) { dns_zone_detach(zonep); result = ISC_R_NOTFOUND; } } else result = ISC_R_NOTFOUND; UNLOCK(&view->lock); return (result); } isc_result_t dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints, dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { return (dns_view_find2(view, name, type, now, options, use_hints, ISC_FALSE, dbp, nodep, foundname, rdataset, sigrdataset)); } isc_result_t dns_view_find2(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints, isc_boolean_t use_static_stub, dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { isc_result_t result; dns_db_t *db, *zdb; dns_dbnode_t *node, *znode; isc_boolean_t is_cache, is_staticstub_zone; dns_rdataset_t zrdataset, zsigrdataset; dns_zone_t *zone; /* * Find an rdataset whose owner name is 'name', and whose type is * 'type'. */ REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(view->frozen); REQUIRE(type != dns_rdatatype_rrsig); REQUIRE(rdataset != NULL); /* XXXBEW - remove this */ REQUIRE(nodep == NULL || *nodep == NULL); /* * Initialize. */ dns_rdataset_init(&zrdataset); dns_rdataset_init(&zsigrdataset); zdb = NULL; znode = NULL; /* * Find a database to answer the query. */ db = NULL; node = NULL; is_staticstub_zone = ISC_FALSE; zone = NULL; LOCK(&view->lock); if (view->zonetable != NULL) result = dns_zt_find(view->zonetable, name, 0, NULL, &zone); else result = ISC_R_NOTFOUND; UNLOCK(&view->lock); if (zone != NULL && dns_zone_gettype(zone) == dns_zone_staticstub && !use_static_stub) result = ISC_R_NOTFOUND; if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { result = dns_zone_getdb(zone, &db); if (result != ISC_R_SUCCESS && view->cachedb != NULL) dns_db_attach(view->cachedb, &db); else if (result != ISC_R_SUCCESS) goto cleanup; if (dns_zone_gettype(zone) == dns_zone_staticstub && dns_name_equal(name, dns_zone_getorigin(zone))) { is_staticstub_zone = ISC_TRUE; } } else if (result == ISC_R_NOTFOUND && view->cachedb != NULL) dns_db_attach(view->cachedb, &db); else goto cleanup; is_cache = dns_db_iscache(db); db_find: /* * Now look for an answer in the database. */ result = dns_db_find(db, name, NULL, type, options, now, &node, foundname, rdataset, sigrdataset); if (result == DNS_R_DELEGATION || result == ISC_R_NOTFOUND) { if (dns_rdataset_isassociated(rdataset)) dns_rdataset_disassociate(rdataset); if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) dns_rdataset_disassociate(sigrdataset); if (node != NULL) dns_db_detachnode(db, &node); if (!is_cache) { dns_db_detach(&db); if (view->cachedb != NULL && !is_staticstub_zone) { /* * Either the answer is in the cache, or we * don't know it. * Note that if the result comes from a * static-stub zone we stop the search here * (see the function description in view.h). */ is_cache = ISC_TRUE; dns_db_attach(view->cachedb, &db); goto db_find; } } else { /* * We don't have the data in the cache. If we've got * glue from the zone, use it. */ if (dns_rdataset_isassociated(&zrdataset)) { dns_rdataset_clone(&zrdataset, rdataset); if (sigrdataset != NULL && dns_rdataset_isassociated(&zsigrdataset)) dns_rdataset_clone(&zsigrdataset, sigrdataset); result = DNS_R_GLUE; if (db != NULL) dns_db_detach(&db); dns_db_attach(zdb, &db); dns_db_attachnode(db, znode, &node); goto cleanup; } } /* * We don't know the answer. */ result = ISC_R_NOTFOUND; } else if (result == DNS_R_GLUE) { if (view->cachedb != NULL && !is_staticstub_zone) { /* * We found an answer, but the cache may be better. * Remember what we've got and go look in the cache. */ is_cache = ISC_TRUE; dns_rdataset_clone(rdataset, &zrdataset); dns_rdataset_disassociate(rdataset); if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) { dns_rdataset_clone(sigrdataset, &zsigrdataset); dns_rdataset_disassociate(sigrdataset); } dns_db_attach(db, &zdb); dns_db_attachnode(zdb, node, &znode); dns_db_detachnode(db, &node); dns_db_detach(&db); dns_db_attach(view->cachedb, &db); goto db_find; } /* * Otherwise, the glue is the best answer. */ result = ISC_R_SUCCESS; } if (result == ISC_R_NOTFOUND && use_hints && view->hints != NULL) { if (dns_rdataset_isassociated(rdataset)) dns_rdataset_disassociate(rdataset); if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) dns_rdataset_disassociate(sigrdataset); if (db != NULL) { if (node != NULL) dns_db_detachnode(db, &node); dns_db_detach(&db); } result = dns_db_find(view->hints, name, NULL, type, options, now, &node, foundname, rdataset, sigrdataset); if (result == ISC_R_SUCCESS || result == DNS_R_GLUE) { /* * We just used a hint. Let the resolver know it * should consider priming. */ dns_resolver_prime(view->resolver); dns_db_attach(view->hints, &db); result = DNS_R_HINT; } else if (result == DNS_R_NXRRSET) { dns_db_attach(view->hints, &db); result = DNS_R_HINTNXRRSET; } else if (result == DNS_R_NXDOMAIN) result = ISC_R_NOTFOUND; /* * Cleanup if non-standard hints are used. */ if (db == NULL && node != NULL) dns_db_detachnode(view->hints, &node); } cleanup: if (dns_rdataset_isassociated(&zrdataset)) { dns_rdataset_disassociate(&zrdataset); if (dns_rdataset_isassociated(&zsigrdataset)) dns_rdataset_disassociate(&zsigrdataset); } if (zdb != NULL) { if (znode != NULL) dns_db_detachnode(zdb, &znode); dns_db_detach(&zdb); } if (db != NULL) { if (node != NULL) { if (nodep != NULL) *nodep = node; else dns_db_detachnode(db, &node); } if (dbp != NULL) *dbp = db; else dns_db_detach(&db); } else INSIST(node == NULL); if (zone != NULL) dns_zone_detach(&zone); return (result); } isc_result_t dns_view_simplefind(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { isc_result_t result; dns_fixedname_t foundname; dns_fixedname_init(&foundname); result = dns_view_find(view, name, type, now, options, use_hints, NULL, NULL, dns_fixedname_name(&foundname), rdataset, sigrdataset); if (result == DNS_R_NXDOMAIN) { /* * The rdataset and sigrdataset of the relevant NSEC record * may be returned, but the caller cannot use them because * foundname is not returned by this simplified API. We * disassociate them here to prevent any misuse by the caller. */ if (dns_rdataset_isassociated(rdataset)) dns_rdataset_disassociate(rdataset); if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) dns_rdataset_disassociate(sigrdataset); } else if (result != ISC_R_SUCCESS && result != DNS_R_GLUE && result != DNS_R_HINT && result != DNS_R_NCACHENXDOMAIN && result != DNS_R_NCACHENXRRSET && result != DNS_R_NXRRSET && result != DNS_R_HINTNXRRSET && result != ISC_R_NOTFOUND) { if (dns_rdataset_isassociated(rdataset)) dns_rdataset_disassociate(rdataset); if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) dns_rdataset_disassociate(sigrdataset); result = ISC_R_NOTFOUND; } return (result); } isc_result_t dns_view_findzonecut(dns_view_t *view, dns_name_t *name, dns_name_t *fname, isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { return(dns_view_findzonecut2(view, name, fname, now, options, use_hints, ISC_TRUE, rdataset, sigrdataset)); } isc_result_t dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname, isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints, isc_boolean_t use_cache, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { isc_result_t result; dns_db_t *db; isc_boolean_t is_cache, use_zone, try_hints; dns_zone_t *zone; dns_name_t *zfname; dns_rdataset_t zrdataset, zsigrdataset; dns_fixedname_t zfixedname; unsigned int ztoptions = 0; REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(view->frozen); db = NULL; use_zone = ISC_FALSE; try_hints = ISC_FALSE; zfname = NULL; /* * Initialize. */ dns_fixedname_init(&zfixedname); dns_rdataset_init(&zrdataset); dns_rdataset_init(&zsigrdataset); /* * Find the right database. */ zone = NULL; LOCK(&view->lock); if (view->zonetable != NULL) { if ((options & DNS_DBFIND_NOEXACT) != 0) ztoptions |= DNS_ZTFIND_NOEXACT; result = dns_zt_find(view->zonetable, name, ztoptions, NULL, &zone); } else result = ISC_R_NOTFOUND; UNLOCK(&view->lock); if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) result = dns_zone_getdb(zone, &db); if (result == ISC_R_NOTFOUND) { /* * We're not directly authoritative for this query name, nor * is it a subdomain of any zone for which we're * authoritative. */ if (use_cache && view->cachedb != NULL) { /* * We have a cache; try it. */ dns_db_attach(view->cachedb, &db); } else { /* * Maybe we have hints... */ try_hints = ISC_TRUE; goto finish; } } else if (result != ISC_R_SUCCESS) { /* * Something is broken. */ goto cleanup; } is_cache = dns_db_iscache(db); db_find: /* * Look for the zonecut. */ if (!is_cache) { result = dns_db_find(db, name, NULL, dns_rdatatype_ns, options, now, NULL, fname, rdataset, sigrdataset); if (result == DNS_R_DELEGATION) result = ISC_R_SUCCESS; else if (result != ISC_R_SUCCESS) goto cleanup; if (use_cache && view->cachedb != NULL && db != view->hints) { /* * We found an answer, but the cache may be better. */ zfname = dns_fixedname_name(&zfixedname); result = dns_name_copy(fname, zfname, NULL); if (result != ISC_R_SUCCESS) goto cleanup; dns_rdataset_clone(rdataset, &zrdataset); dns_rdataset_disassociate(rdataset); if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) { dns_rdataset_clone(sigrdataset, &zsigrdataset); dns_rdataset_disassociate(sigrdataset); } dns_db_detach(&db); dns_db_attach(view->cachedb, &db); is_cache = ISC_TRUE; goto db_find; } } else { result = dns_db_findzonecut(db, name, options, now, NULL, fname, rdataset, sigrdataset); if (result == ISC_R_SUCCESS) { if (zfname != NULL && (!dns_name_issubdomain(fname, zfname) || (dns_zone_gettype(zone) == dns_zone_staticstub && dns_name_equal(fname, zfname)))) { /* * We found a zonecut in the cache, but our * zone delegation is better. */ use_zone = ISC_TRUE; } } else if (result == ISC_R_NOTFOUND) { if (zfname != NULL) { /* * We didn't find anything in the cache, but we * have a zone delegation, so use it. */ use_zone = ISC_TRUE; } else { /* * Maybe we have hints... */ try_hints = ISC_TRUE; } } else { /* * Something bad happened. */ goto cleanup; } } finish: if (use_zone) { if (dns_rdataset_isassociated(rdataset)) { dns_rdataset_disassociate(rdataset); if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) dns_rdataset_disassociate(sigrdataset); } result = dns_name_copy(zfname, fname, NULL); if (result != ISC_R_SUCCESS) goto cleanup; dns_rdataset_clone(&zrdataset, rdataset); if (sigrdataset != NULL && dns_rdataset_isassociated(&zrdataset)) dns_rdataset_clone(&zsigrdataset, sigrdataset); } else if (try_hints && use_hints && view->hints != NULL) { /* * We've found nothing so far, but we have hints. */ result = dns_db_find(view->hints, dns_rootname, NULL, dns_rdatatype_ns, 0, now, NULL, fname, rdataset, NULL); if (result != ISC_R_SUCCESS) { /* * We can't even find the hints for the root * nameservers! */ if (dns_rdataset_isassociated(rdataset)) dns_rdataset_disassociate(rdataset); result = ISC_R_NOTFOUND; } } cleanup: if (dns_rdataset_isassociated(&zrdataset)) { dns_rdataset_disassociate(&zrdataset); if (dns_rdataset_isassociated(&zsigrdataset)) dns_rdataset_disassociate(&zsigrdataset); } if (db != NULL) dns_db_detach(&db); if (zone != NULL) dns_zone_detach(&zone); return (result); } isc_result_t dns_viewlist_find(dns_viewlist_t *list, const char *name, dns_rdataclass_t rdclass, dns_view_t **viewp) { dns_view_t *view; REQUIRE(list != NULL); for (view = ISC_LIST_HEAD(*list); view != NULL; view = ISC_LIST_NEXT(view, link)) { if (strcmp(view->name, name) == 0 && view->rdclass == rdclass) break; } if (view == NULL) return (ISC_R_NOTFOUND); dns_view_attach(view, viewp); return (ISC_R_SUCCESS); } isc_result_t dns_viewlist_findzone(dns_viewlist_t *list, dns_name_t *name, isc_boolean_t allclasses, dns_rdataclass_t rdclass, dns_zone_t **zonep) { dns_view_t *view; isc_result_t result; dns_zone_t *zone1 = NULL, *zone2 = NULL; dns_zone_t **zp = NULL;; REQUIRE(list != NULL); REQUIRE(zonep != NULL && *zonep == NULL); for (view = ISC_LIST_HEAD(*list); view != NULL; view = ISC_LIST_NEXT(view, link)) { if (allclasses == ISC_FALSE && view->rdclass != rdclass) continue; /* * If the zone is defined in more than one view, * treat it as not found. */ zp = (zone1 == NULL) ? &zone1 : &zone2; LOCK(&view->lock); if (view->zonetable != NULL) result = dns_zt_find(view->zonetable, name, 0, NULL, zp); else result = ISC_R_NOTFOUND; UNLOCK(&view->lock); INSIST(result == ISC_R_SUCCESS || result == ISC_R_NOTFOUND || result == DNS_R_PARTIALMATCH); /* Treat a partial match as no match */ if (result == DNS_R_PARTIALMATCH) { dns_zone_detach(zp); result = ISC_R_NOTFOUND; POST(result); } if (zone2 != NULL) { dns_zone_detach(&zone1); dns_zone_detach(&zone2); return (ISC_R_MULTIPLE); } } if (zone1 != NULL) { dns_zone_attach(zone1, zonep); dns_zone_detach(&zone1); return (ISC_R_SUCCESS); } return (ISC_R_NOTFOUND); } isc_result_t dns_view_load(dns_view_t *view, isc_boolean_t stop) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(view->zonetable != NULL); return (dns_zt_load(view->zonetable, stop)); } isc_result_t dns_view_loadnew(dns_view_t *view, isc_boolean_t stop) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(view->zonetable != NULL); return (dns_zt_loadnew(view->zonetable, stop)); } isc_result_t dns_view_asyncload(dns_view_t *view, dns_zt_allloaded_t callback, void *arg) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(view->zonetable != NULL); return (dns_zt_asyncload(view->zonetable, callback, arg)); } isc_result_t dns_view_gettsig(dns_view_t *view, dns_name_t *keyname, dns_tsigkey_t **keyp) { isc_result_t result; REQUIRE(keyp != NULL && *keyp == NULL); result = dns_tsigkey_find(keyp, keyname, NULL, view->statickeys); if (result == ISC_R_NOTFOUND) result = dns_tsigkey_find(keyp, keyname, NULL, view->dynamickeys); return (result); } isc_result_t dns_view_getpeertsig(dns_view_t *view, isc_netaddr_t *peeraddr, dns_tsigkey_t **keyp) { isc_result_t result; dns_name_t *keyname = NULL; dns_peer_t *peer = NULL; result = dns_peerlist_peerbyaddr(view->peers, peeraddr, &peer); if (result != ISC_R_SUCCESS) return (result); result = dns_peer_getkey(peer, &keyname); if (result != ISC_R_SUCCESS) return (result); result = dns_view_gettsig(view, keyname, keyp); return ((result == ISC_R_NOTFOUND) ? ISC_R_FAILURE : result); } isc_result_t dns_view_checksig(dns_view_t *view, isc_buffer_t *source, dns_message_t *msg) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(source != NULL); return (dns_tsig_verify(source, msg, view->statickeys, view->dynamickeys)); } isc_result_t dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) { isc_result_t result; REQUIRE(DNS_VIEW_VALID(view)); (void)fprintf(fp, ";\n; Cache dump of view '%s'\n;\n", view->name); result = dns_master_dumptostream(view->mctx, view->cachedb, NULL, &dns_master_style_cache, fp); if (result != ISC_R_SUCCESS) return (result); dns_adb_dump(view->adb, fp); dns_resolver_printbadcache(view->resolver, fp); return (ISC_R_SUCCESS); } isc_result_t dns_view_flushcache(dns_view_t *view) { return (dns_view_flushcache2(view, ISC_FALSE)); } isc_result_t dns_view_flushcache2(dns_view_t *view, isc_boolean_t fixuponly) { isc_result_t result; REQUIRE(DNS_VIEW_VALID(view)); if (view->cachedb == NULL) return (ISC_R_SUCCESS); if (!fixuponly) { result = dns_cache_flush(view->cache); if (result != ISC_R_SUCCESS) return (result); } if (view->acache != NULL) dns_acache_putdb(view->acache, view->cachedb); dns_db_detach(&view->cachedb); dns_cache_attachdb(view->cache, &view->cachedb); if (view->acache != NULL) dns_acache_setdb(view->acache, view->cachedb); if (view->resolver != NULL) dns_resolver_flushbadcache(view->resolver, NULL); dns_adb_flush(view->adb); return (ISC_R_SUCCESS); } isc_result_t dns_view_flushname(dns_view_t *view, dns_name_t *name) { return (dns_view_flushnode(view, name, ISC_FALSE)); } isc_result_t dns_view_flushnode(dns_view_t *view, dns_name_t *name, isc_boolean_t tree) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(DNS_VIEW_VALID(view)); if (tree) { if (view->adb != NULL) dns_adb_flushnames(view->adb, name); if (view->resolver != NULL) dns_resolver_flushbadnames(view->resolver, name); } else { if (view->adb != NULL) dns_adb_flushname(view->adb, name); if (view->resolver != NULL) dns_resolver_flushbadcache(view->resolver, name); } if (view->cache != NULL) result = dns_cache_flushnode(view->cache, name, tree); return (result); } isc_result_t dns_view_adddelegationonly(dns_view_t *view, dns_name_t *name) { isc_result_t result; dns_name_t *new; isc_uint32_t hash; REQUIRE(DNS_VIEW_VALID(view)); if (view->delonly == NULL) { view->delonly = isc_mem_get(view->mctx, sizeof(dns_namelist_t) * DNS_VIEW_DELONLYHASH); if (view->delonly == NULL) return (ISC_R_NOMEMORY); for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++) ISC_LIST_INIT(view->delonly[hash]); } hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH; new = ISC_LIST_HEAD(view->delonly[hash]); while (new != NULL && !dns_name_equal(new, name)) new = ISC_LIST_NEXT(new, link); if (new != NULL) return (ISC_R_SUCCESS); new = isc_mem_get(view->mctx, sizeof(*new)); if (new == NULL) return (ISC_R_NOMEMORY); dns_name_init(new, NULL); result = dns_name_dup(name, view->mctx, new); if (result == ISC_R_SUCCESS) ISC_LIST_APPEND(view->delonly[hash], new, link); else isc_mem_put(view->mctx, new, sizeof(*new)); return (result); } isc_result_t dns_view_excludedelegationonly(dns_view_t *view, dns_name_t *name) { isc_result_t result; dns_name_t *new; isc_uint32_t hash; REQUIRE(DNS_VIEW_VALID(view)); if (view->rootexclude == NULL) { view->rootexclude = isc_mem_get(view->mctx, sizeof(dns_namelist_t) * DNS_VIEW_DELONLYHASH); if (view->rootexclude == NULL) return (ISC_R_NOMEMORY); for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++) ISC_LIST_INIT(view->rootexclude[hash]); } hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH; new = ISC_LIST_HEAD(view->rootexclude[hash]); while (new != NULL && !dns_name_equal(new, name)) new = ISC_LIST_NEXT(new, link); if (new != NULL) return (ISC_R_SUCCESS); new = isc_mem_get(view->mctx, sizeof(*new)); if (new == NULL) return (ISC_R_NOMEMORY); dns_name_init(new, NULL); result = dns_name_dup(name, view->mctx, new); if (result == ISC_R_SUCCESS) ISC_LIST_APPEND(view->rootexclude[hash], new, link); else isc_mem_put(view->mctx, new, sizeof(*new)); return (result); } isc_boolean_t dns_view_isdelegationonly(dns_view_t *view, dns_name_t *name) { dns_name_t *new; isc_uint32_t hash; REQUIRE(DNS_VIEW_VALID(view)); if (!view->rootdelonly && view->delonly == NULL) return (ISC_FALSE); hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH; if (view->rootdelonly && dns_name_countlabels(name) <= 2) { if (view->rootexclude == NULL) return (ISC_TRUE); new = ISC_LIST_HEAD(view->rootexclude[hash]); while (new != NULL && !dns_name_equal(new, name)) new = ISC_LIST_NEXT(new, link); if (new == NULL) return (ISC_TRUE); } if (view->delonly == NULL) return (ISC_FALSE); new = ISC_LIST_HEAD(view->delonly[hash]); while (new != NULL && !dns_name_equal(new, name)) new = ISC_LIST_NEXT(new, link); if (new == NULL) return (ISC_FALSE); return (ISC_TRUE); } void dns_view_setrootdelonly(dns_view_t *view, isc_boolean_t value) { REQUIRE(DNS_VIEW_VALID(view)); view->rootdelonly = value; } isc_boolean_t dns_view_getrootdelonly(dns_view_t *view) { REQUIRE(DNS_VIEW_VALID(view)); return (view->rootdelonly); } isc_result_t dns_view_freezezones(dns_view_t *view, isc_boolean_t value) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(view->zonetable != NULL); return (dns_zt_freezezones(view->zonetable, value)); } void dns_view_setadbstats(dns_view_t *view, isc_stats_t *stats) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(!view->frozen); REQUIRE(view->adbstats == NULL); isc_stats_attach(stats, &view->adbstats); } void dns_view_getadbstats(dns_view_t *view, isc_stats_t **statsp) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(statsp != NULL && *statsp == NULL); if (view->adbstats != NULL) isc_stats_attach(view->adbstats, statsp); } void dns_view_setresstats(dns_view_t *view, isc_stats_t *stats) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(!view->frozen); REQUIRE(view->resstats == NULL); isc_stats_attach(stats, &view->resstats); } void dns_view_getresstats(dns_view_t *view, isc_stats_t **statsp) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(statsp != NULL && *statsp == NULL); if (view->resstats != NULL) isc_stats_attach(view->resstats, statsp); } void dns_view_setresquerystats(dns_view_t *view, dns_stats_t *stats) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(!view->frozen); REQUIRE(view->resquerystats == NULL); dns_stats_attach(stats, &view->resquerystats); } void dns_view_getresquerystats(dns_view_t *view, dns_stats_t **statsp) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(statsp != NULL && *statsp == NULL); if (view->resquerystats != NULL) dns_stats_attach(view->resquerystats, statsp); } isc_result_t dns_view_initsecroots(dns_view_t *view, isc_mem_t *mctx) { REQUIRE(DNS_VIEW_VALID(view)); if (view->secroots_priv != NULL) dns_keytable_detach(&view->secroots_priv); return (dns_keytable_create(mctx, &view->secroots_priv)); } isc_result_t dns_view_getsecroots(dns_view_t *view, dns_keytable_t **ktp) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(ktp != NULL && *ktp == NULL); if (view->secroots_priv == NULL) return (ISC_R_NOTFOUND); dns_keytable_attach(view->secroots_priv, ktp); return (ISC_R_SUCCESS); } isc_result_t dns_view_issecuredomain(dns_view_t *view, dns_name_t *name, isc_boolean_t *secure_domain) { REQUIRE(DNS_VIEW_VALID(view)); if (view->secroots_priv == NULL) return (ISC_R_NOTFOUND); return (dns_keytable_issecuredomain(view->secroots_priv, name, secure_domain)); } void dns_view_untrust(dns_view_t *view, dns_name_t *keyname, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) { isc_result_t result; unsigned char data[4096]; dns_rdata_t rdata = DNS_RDATA_INIT; isc_buffer_t buffer; dst_key_t *key = NULL; dns_keytable_t *sr = NULL; /* * Clear the revoke bit, if set, so that the key will match what's * in secroots now. */ dnskey->flags &= ~DNS_KEYFLAG_REVOKE; /* Convert dnskey to DST key. */ isc_buffer_init(&buffer, data, sizeof(data)); dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, dns_rdatatype_dnskey, dnskey, &buffer); result = dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &key); if (result != ISC_R_SUCCESS) return; result = dns_view_getsecroots(view, &sr); if (result == ISC_R_SUCCESS) { dns_keytable_deletekeynode(sr, key); dns_keytable_detach(&sr); } dst_key_free(&key); } #define NZF ".nzf" void dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx, void (*cfg_destroy)(void **)) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE((cfgctx != NULL && cfg_destroy != NULL) || !allow); if (view->new_zone_file != NULL) { isc_mem_free(view->mctx, view->new_zone_file); view->new_zone_file = NULL; } if (view->new_zone_config != NULL) { view->cfg_destroy(&view->new_zone_config); view->cfg_destroy = NULL; } if (allow) { char buffer[ISC_SHA256_DIGESTSTRINGLENGTH + sizeof(NZF)]; isc_sha256_data((void *)view->name, strlen(view->name), buffer); /* Truncate the hash at 16 chars; full length is overkill */ isc_string_printf(buffer + 16, sizeof(NZF), "%s", NZF); view->new_zone_file = isc_mem_strdup(view->mctx, buffer); view->new_zone_config = cfgctx; view->cfg_destroy = cfg_destroy; } } isc_result_t dns_view_searchdlz(dns_view_t *view, dns_name_t *name, unsigned int minlabels, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, dns_db_t **dbp) { dns_fixedname_t fname; dns_name_t *zonename; unsigned int namelabels; unsigned int i; isc_result_t result; dns_dlzfindzone_t findzone; dns_dlzdb_t *dlzdb; dns_db_t *db, *best = NULL; /* * Performs checks to make sure data is as we expect it to be. */ REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(name != NULL); REQUIRE(dbp != NULL && *dbp == NULL); /* setup a "fixed" dns name */ dns_fixedname_init(&fname); zonename = dns_fixedname_name(&fname); /* count the number of labels in the name */ namelabels = dns_name_countlabels(name); for (dlzdb = ISC_LIST_HEAD(view->dlz_searched); dlzdb != NULL; dlzdb = ISC_LIST_NEXT(dlzdb, link)) { REQUIRE(DNS_DLZ_VALID(dlzdb)); /* * loop through starting with the longest domain name and * trying shorter names portions of the name until we find a * match, have an error, or are below the 'minlabels' * threshold. minlabels is 0, if neither the standard * database nor any previous DLZ database had a zone name * match. Otherwise minlabels is the number of labels * in that name. We need to beat that for a "better" * match for this DLZ database to be authoritative. */ for (i = namelabels; i > minlabels && i > 1; i--) { if (i == namelabels) { result = dns_name_copy(name, zonename, NULL); if (result != ISC_R_SUCCESS) return (result); } else dns_name_split(name, i, NULL, zonename); /* ask SDLZ driver if the zone is supported */ db = NULL; findzone = dlzdb->implementation->methods->findzone; result = (*findzone)(dlzdb->implementation->driverarg, dlzdb->dbdata, dlzdb->mctx, view->rdclass, zonename, methods, clientinfo, &db); if (result != ISC_R_NOTFOUND) { if (best != NULL) dns_db_detach(&best); if (result == ISC_R_SUCCESS) { INSIST(db != NULL); dns_db_attach(db, &best); dns_db_detach(&db); minlabels = i; } else { if (db != NULL) dns_db_detach(&db); break; } } else if (db != NULL) dns_db_detach(&db); } } if (best != NULL) { dns_db_attach(best, dbp); dns_db_detach(&best); return (ISC_R_SUCCESS); } return (ISC_R_NOTFOUND); } bind9-9.10.3.dfsg.P4/lib/dns/rriterator.c0000644000470500017500000001343212664710322017267 0ustar lamontlamont/* * Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ /*** *** Imports ***/ #include #include #include #include #include #include #include #include #include #include /*** *** RRiterator methods ***/ isc_result_t dns_rriterator_init(dns_rriterator_t *it, dns_db_t *db, dns_dbversion_t *ver, isc_stdtime_t now) { isc_result_t result; it->magic = RRITERATOR_MAGIC; it->db = db; it->dbit = NULL; it->ver = ver; it->now = now; it->node = NULL; result = dns_db_createiterator(it->db, 0, &it->dbit); if (result != ISC_R_SUCCESS) return (result); it->rdatasetit = NULL; dns_rdata_init(&it->rdata); dns_rdataset_init(&it->rdataset); dns_fixedname_init(&it->fixedname); INSIST(! dns_rdataset_isassociated(&it->rdataset)); it->result = ISC_R_SUCCESS; return (it->result); } isc_result_t dns_rriterator_first(dns_rriterator_t *it) { REQUIRE(VALID_RRITERATOR(it)); /* Reset state */ if (dns_rdataset_isassociated(&it->rdataset)) dns_rdataset_disassociate(&it->rdataset); if (it->rdatasetit != NULL) dns_rdatasetiter_destroy(&it->rdatasetit); if (it->node != NULL) dns_db_detachnode(it->db, &it->node); it->result = dns_dbiterator_first(it->dbit); /* * The top node may be empty when out of zone glue exists. * Walk the tree to find the first node with data. */ while (it->result == ISC_R_SUCCESS) { it->result = dns_dbiterator_current(it->dbit, &it->node, dns_fixedname_name(&it->fixedname)); if (it->result != ISC_R_SUCCESS) return (it->result); it->result = dns_db_allrdatasets(it->db, it->node, it->ver, it->now, &it->rdatasetit); if (it->result != ISC_R_SUCCESS) return (it->result); it->result = dns_rdatasetiter_first(it->rdatasetit); if (it->result != ISC_R_SUCCESS) { /* * This node is empty. Try next node. */ dns_rdatasetiter_destroy(&it->rdatasetit); dns_db_detachnode(it->db, &it->node); it->result = dns_dbiterator_next(it->dbit); continue; } dns_rdatasetiter_current(it->rdatasetit, &it->rdataset); it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER; it->result = dns_rdataset_first(&it->rdataset); return (it->result); } return (it->result); } isc_result_t dns_rriterator_nextrrset(dns_rriterator_t *it) { REQUIRE(VALID_RRITERATOR(it)); if (dns_rdataset_isassociated(&it->rdataset)) dns_rdataset_disassociate(&it->rdataset); it->result = dns_rdatasetiter_next(it->rdatasetit); /* * The while loop body is executed more than once * only when an empty dbnode needs to be skipped. */ while (it->result == ISC_R_NOMORE) { dns_rdatasetiter_destroy(&it->rdatasetit); dns_db_detachnode(it->db, &it->node); it->result = dns_dbiterator_next(it->dbit); if (it->result == ISC_R_NOMORE) { /* We are at the end of the entire database. */ return (it->result); } if (it->result != ISC_R_SUCCESS) return (it->result); it->result = dns_dbiterator_current(it->dbit, &it->node, dns_fixedname_name(&it->fixedname)); if (it->result != ISC_R_SUCCESS) return (it->result); it->result = dns_db_allrdatasets(it->db, it->node, it->ver, it->now, &it->rdatasetit); if (it->result != ISC_R_SUCCESS) return (it->result); it->result = dns_rdatasetiter_first(it->rdatasetit); } if (it->result != ISC_R_SUCCESS) return (it->result); dns_rdatasetiter_current(it->rdatasetit, &it->rdataset); it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER; it->result = dns_rdataset_first(&it->rdataset); return (it->result); } isc_result_t dns_rriterator_next(dns_rriterator_t *it) { REQUIRE(VALID_RRITERATOR(it)); if (it->result != ISC_R_SUCCESS) return (it->result); INSIST(it->dbit != NULL); INSIST(it->node != NULL); INSIST(it->rdatasetit != NULL); it->result = dns_rdataset_next(&it->rdataset); if (it->result == ISC_R_NOMORE) return (dns_rriterator_nextrrset(it)); return (it->result); } void dns_rriterator_pause(dns_rriterator_t *it) { REQUIRE(VALID_RRITERATOR(it)); RUNTIME_CHECK(dns_dbiterator_pause(it->dbit) == ISC_R_SUCCESS); } void dns_rriterator_destroy(dns_rriterator_t *it) { REQUIRE(VALID_RRITERATOR(it)); if (dns_rdataset_isassociated(&it->rdataset)) dns_rdataset_disassociate(&it->rdataset); if (it->rdatasetit != NULL) dns_rdatasetiter_destroy(&it->rdatasetit); if (it->node != NULL) dns_db_detachnode(it->db, &it->node); dns_dbiterator_destroy(&it->dbit); } void dns_rriterator_current(dns_rriterator_t *it, dns_name_t **name, isc_uint32_t *ttl, dns_rdataset_t **rdataset, dns_rdata_t **rdata) { REQUIRE(name != NULL && *name == NULL); REQUIRE(VALID_RRITERATOR(it)); REQUIRE(it->result == ISC_R_SUCCESS); REQUIRE(rdataset == NULL || *rdataset == NULL); REQUIRE(rdata == NULL || *rdata == NULL); *name = dns_fixedname_name(&it->fixedname); *ttl = it->rdataset.ttl; dns_rdata_reset(&it->rdata); dns_rdataset_current(&it->rdataset, &it->rdata); if (rdataset != NULL) *rdataset = &it->rdataset; if (rdata != NULL) *rdata = &it->rdata; } bind9-9.10.3.dfsg.P4/lib/dns/dnssec.c0000644000470500017500000014200012664710322016343 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* for DNS_TSIG_FUDGE */ #include LIBDNS_EXTERNAL_DATA isc_stats_t *dns_dnssec_stats; #define is_response(msg) (msg->flags & DNS_MESSAGEFLAG_QR) #define RETERR(x) do { \ result = (x); \ if (result != ISC_R_SUCCESS) \ goto failure; \ } while (0) #define TYPE_SIGN 0 #define TYPE_VERIFY 1 static isc_result_t digest_callback(void *arg, isc_region_t *data); static int rdata_compare_wrapper(const void *rdata1, const void *rdata2); static isc_result_t rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx, dns_rdata_t **rdata, int *nrdata); static isc_result_t digest_callback(void *arg, isc_region_t *data) { dst_context_t *ctx = arg; return (dst_context_adddata(ctx, data)); } static inline void inc_stat(isc_statscounter_t counter) { if (dns_dnssec_stats != NULL) isc_stats_increment(dns_dnssec_stats, counter); } /* * Make qsort happy. */ static int rdata_compare_wrapper(const void *rdata1, const void *rdata2) { return (dns_rdata_compare((const dns_rdata_t *)rdata1, (const dns_rdata_t *)rdata2)); } /* * Sort the rdataset into an array. */ static isc_result_t rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx, dns_rdata_t **rdata, int *nrdata) { isc_result_t ret; int i = 0, n; dns_rdata_t *data; dns_rdataset_t rdataset; n = dns_rdataset_count(set); data = isc_mem_get(mctx, n * sizeof(dns_rdata_t)); if (data == NULL) return (ISC_R_NOMEMORY); dns_rdataset_init(&rdataset); dns_rdataset_clone(set, &rdataset); ret = dns_rdataset_first(&rdataset); if (ret != ISC_R_SUCCESS) { dns_rdataset_disassociate(&rdataset); isc_mem_put(mctx, data, n * sizeof(dns_rdata_t)); return (ret); } /* * Put them in the array. */ do { dns_rdata_init(&data[i]); dns_rdataset_current(&rdataset, &data[i++]); } while (dns_rdataset_next(&rdataset) == ISC_R_SUCCESS); /* * Sort the array. */ qsort(data, n, sizeof(dns_rdata_t), rdata_compare_wrapper); *rdata = data; *nrdata = n; dns_rdataset_disassociate(&rdataset); return (ISC_R_SUCCESS); } isc_result_t dns_dnssec_keyfromrdata(dns_name_t *name, dns_rdata_t *rdata, isc_mem_t *mctx, dst_key_t **key) { isc_buffer_t b; isc_region_t r; INSIST(name != NULL); INSIST(rdata != NULL); INSIST(mctx != NULL); INSIST(key != NULL); INSIST(*key == NULL); REQUIRE(rdata->type == dns_rdatatype_key || rdata->type == dns_rdatatype_dnskey); dns_rdata_toregion(rdata, &r); isc_buffer_init(&b, r.base, r.length); isc_buffer_add(&b, r.length); return (dst_key_fromdns(name, rdata->rdclass, &b, mctx, key)); } static isc_result_t digest_sig(dst_context_t *ctx, isc_boolean_t downcase, dns_rdata_t *sigrdata, dns_rdata_rrsig_t *rrsig) { isc_region_t r; isc_result_t ret; dns_fixedname_t fname; dns_rdata_toregion(sigrdata, &r); INSIST(r.length >= 19); r.length = 18; ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) return (ret); if (downcase) { dns_fixedname_init(&fname); RUNTIME_CHECK(dns_name_downcase(&rrsig->signer, dns_fixedname_name(&fname), NULL) == ISC_R_SUCCESS); dns_name_toregion(dns_fixedname_name(&fname), &r); } else dns_name_toregion(&rrsig->signer, &r); return (dst_context_adddata(ctx, &r)); } isc_result_t dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, isc_stdtime_t *inception, isc_stdtime_t *expire, isc_mem_t *mctx, isc_buffer_t *buffer, dns_rdata_t *sigrdata) { dns_rdata_rrsig_t sig; dns_rdata_t tmpsigrdata; dns_rdata_t *rdatas; int nrdatas, i; isc_buffer_t sigbuf, envbuf; isc_region_t r; dst_context_t *ctx = NULL; isc_result_t ret; isc_buffer_t *databuf = NULL; char data[256 + 8]; isc_uint32_t flags; unsigned int sigsize; dns_fixedname_t fnewname; dns_fixedname_t fsigner; REQUIRE(name != NULL); REQUIRE(dns_name_countlabels(name) <= 255); REQUIRE(set != NULL); REQUIRE(key != NULL); REQUIRE(inception != NULL); REQUIRE(expire != NULL); REQUIRE(mctx != NULL); REQUIRE(sigrdata != NULL); if (*inception >= *expire) return (DNS_R_INVALIDTIME); /* * Is the key allowed to sign data? */ flags = dst_key_flags(key); if (flags & DNS_KEYTYPE_NOAUTH) return (DNS_R_KEYUNAUTHORIZED); if ((flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE) return (DNS_R_KEYUNAUTHORIZED); sig.mctx = mctx; sig.common.rdclass = set->rdclass; sig.common.rdtype = dns_rdatatype_rrsig; ISC_LINK_INIT(&sig.common, link); /* * Downcase signer. */ dns_name_init(&sig.signer, NULL); dns_fixedname_init(&fsigner); RUNTIME_CHECK(dns_name_downcase(dst_key_name(key), dns_fixedname_name(&fsigner), NULL) == ISC_R_SUCCESS); dns_name_clone(dns_fixedname_name(&fsigner), &sig.signer); sig.covered = set->type; sig.algorithm = dst_key_alg(key); sig.labels = dns_name_countlabels(name) - 1; if (dns_name_iswildcard(name)) sig.labels--; sig.originalttl = set->ttl; sig.timesigned = *inception; sig.timeexpire = *expire; sig.keyid = dst_key_id(key); ret = dst_key_sigsize(key, &sigsize); if (ret != ISC_R_SUCCESS) return (ret); sig.siglen = sigsize; /* * The actual contents of sig.signature are not important yet, since * they're not used in digest_sig(). */ sig.signature = isc_mem_get(mctx, sig.siglen); if (sig.signature == NULL) return (ISC_R_NOMEMORY); ret = isc_buffer_allocate(mctx, &databuf, sigsize + 256 + 18); if (ret != ISC_R_SUCCESS) goto cleanup_signature; dns_rdata_init(&tmpsigrdata); ret = dns_rdata_fromstruct(&tmpsigrdata, sig.common.rdclass, sig.common.rdtype, &sig, databuf); if (ret != ISC_R_SUCCESS) goto cleanup_databuf; ret = dst_context_create3(key, mctx, DNS_LOGCATEGORY_DNSSEC, ISC_TRUE, &ctx); if (ret != ISC_R_SUCCESS) goto cleanup_databuf; /* * Digest the SIG rdata. */ ret = digest_sig(ctx, ISC_FALSE, &tmpsigrdata, &sig); if (ret != ISC_R_SUCCESS) goto cleanup_context; dns_fixedname_init(&fnewname); RUNTIME_CHECK(dns_name_downcase(name, dns_fixedname_name(&fnewname), NULL) == ISC_R_SUCCESS); dns_name_toregion(dns_fixedname_name(&fnewname), &r); /* * Create an envelope for each rdata: . */ isc_buffer_init(&envbuf, data, sizeof(data)); memmove(data, r.base, r.length); isc_buffer_add(&envbuf, r.length); isc_buffer_putuint16(&envbuf, set->type); isc_buffer_putuint16(&envbuf, set->rdclass); isc_buffer_putuint32(&envbuf, set->ttl); ret = rdataset_to_sortedarray(set, mctx, &rdatas, &nrdatas); if (ret != ISC_R_SUCCESS) goto cleanup_context; isc_buffer_usedregion(&envbuf, &r); for (i = 0; i < nrdatas; i++) { isc_uint16_t len; isc_buffer_t lenbuf; isc_region_t lenr; /* * Skip duplicates. */ if (i > 0 && dns_rdata_compare(&rdatas[i], &rdatas[i-1]) == 0) continue; /* * Digest the envelope. */ ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_array; /* * Digest the length of the rdata. */ isc_buffer_init(&lenbuf, &len, sizeof(len)); INSIST(rdatas[i].length < 65536); isc_buffer_putuint16(&lenbuf, (isc_uint16_t)rdatas[i].length); isc_buffer_usedregion(&lenbuf, &lenr); ret = dst_context_adddata(ctx, &lenr); if (ret != ISC_R_SUCCESS) goto cleanup_array; /* * Digest the rdata. */ ret = dns_rdata_digest(&rdatas[i], digest_callback, ctx); if (ret != ISC_R_SUCCESS) goto cleanup_array; } isc_buffer_init(&sigbuf, sig.signature, sig.siglen); ret = dst_context_sign(ctx, &sigbuf); if (ret != ISC_R_SUCCESS) goto cleanup_array; isc_buffer_usedregion(&sigbuf, &r); if (r.length != sig.siglen) { ret = ISC_R_NOSPACE; goto cleanup_array; } ret = dns_rdata_fromstruct(sigrdata, sig.common.rdclass, sig.common.rdtype, &sig, buffer); cleanup_array: isc_mem_put(mctx, rdatas, nrdatas * sizeof(dns_rdata_t)); cleanup_context: dst_context_destroy(&ctx); cleanup_databuf: isc_buffer_free(&databuf); cleanup_signature: isc_mem_put(mctx, sig.signature, sig.siglen); return (ret); } isc_result_t dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, isc_boolean_t ignoretime, isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild) { return (dns_dnssec_verify3(name, set, key, ignoretime, 0, mctx, sigrdata, wild)); } isc_result_t dns_dnssec_verify3(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, isc_boolean_t ignoretime, unsigned int maxbits, isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild) { dns_rdata_rrsig_t sig; dns_fixedname_t fnewname; isc_region_t r; isc_buffer_t envbuf; dns_rdata_t *rdatas; int nrdatas, i; isc_stdtime_t now; isc_result_t ret; unsigned char data[300]; dst_context_t *ctx = NULL; int labels = 0; isc_uint32_t flags; isc_boolean_t downcase = ISC_FALSE; REQUIRE(name != NULL); REQUIRE(set != NULL); REQUIRE(key != NULL); REQUIRE(mctx != NULL); REQUIRE(sigrdata != NULL && sigrdata->type == dns_rdatatype_rrsig); ret = dns_rdata_tostruct(sigrdata, &sig, NULL); if (ret != ISC_R_SUCCESS) return (ret); if (set->type != sig.covered) return (DNS_R_SIGINVALID); if (isc_serial_lt(sig.timeexpire, sig.timesigned)) { inc_stat(dns_dnssecstats_fail); return (DNS_R_SIGINVALID); } if (!ignoretime) { isc_stdtime_get(&now); /* * Is SIG temporally valid? */ if (isc_serial_lt((isc_uint32_t)now, sig.timesigned)) { inc_stat(dns_dnssecstats_fail); return (DNS_R_SIGFUTURE); } else if (isc_serial_lt(sig.timeexpire, (isc_uint32_t)now)) { inc_stat(dns_dnssecstats_fail); return (DNS_R_SIGEXPIRED); } } /* * NS, SOA and DNSSKEY records are signed by their owner. * DS records are signed by the parent. */ switch (set->type) { case dns_rdatatype_ns: case dns_rdatatype_soa: case dns_rdatatype_dnskey: if (!dns_name_equal(name, &sig.signer)) { inc_stat(dns_dnssecstats_fail); return (DNS_R_SIGINVALID); } break; case dns_rdatatype_ds: if (dns_name_equal(name, &sig.signer)) { inc_stat(dns_dnssecstats_fail); return (DNS_R_SIGINVALID); } /* FALLTHROUGH */ default: if (!dns_name_issubdomain(name, &sig.signer)) { inc_stat(dns_dnssecstats_fail); return (DNS_R_SIGINVALID); } break; } /* * Is the key allowed to sign data? */ flags = dst_key_flags(key); if (flags & DNS_KEYTYPE_NOAUTH) { inc_stat(dns_dnssecstats_fail); return (DNS_R_KEYUNAUTHORIZED); } if ((flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE) { inc_stat(dns_dnssecstats_fail); return (DNS_R_KEYUNAUTHORIZED); } again: ret = dst_context_create4(key, mctx, DNS_LOGCATEGORY_DNSSEC, ISC_FALSE, maxbits, &ctx); if (ret != ISC_R_SUCCESS) goto cleanup_struct; /* * Digest the SIG rdata (not including the signature). */ ret = digest_sig(ctx, downcase, sigrdata, &sig); if (ret != ISC_R_SUCCESS) goto cleanup_context; /* * If the name is an expanded wildcard, use the wildcard name. */ dns_fixedname_init(&fnewname); labels = dns_name_countlabels(name) - 1; RUNTIME_CHECK(dns_name_downcase(name, dns_fixedname_name(&fnewname), NULL) == ISC_R_SUCCESS); if (labels - sig.labels > 0) dns_name_split(dns_fixedname_name(&fnewname), sig.labels + 1, NULL, dns_fixedname_name(&fnewname)); dns_name_toregion(dns_fixedname_name(&fnewname), &r); /* * Create an envelope for each rdata: . */ isc_buffer_init(&envbuf, data, sizeof(data)); if (labels - sig.labels > 0) { isc_buffer_putuint8(&envbuf, 1); isc_buffer_putuint8(&envbuf, '*'); memmove(data + 2, r.base, r.length); } else memmove(data, r.base, r.length); isc_buffer_add(&envbuf, r.length); isc_buffer_putuint16(&envbuf, set->type); isc_buffer_putuint16(&envbuf, set->rdclass); isc_buffer_putuint32(&envbuf, sig.originalttl); ret = rdataset_to_sortedarray(set, mctx, &rdatas, &nrdatas); if (ret != ISC_R_SUCCESS) goto cleanup_context; isc_buffer_usedregion(&envbuf, &r); for (i = 0; i < nrdatas; i++) { isc_uint16_t len; isc_buffer_t lenbuf; isc_region_t lenr; /* * Skip duplicates. */ if (i > 0 && dns_rdata_compare(&rdatas[i], &rdatas[i-1]) == 0) continue; /* * Digest the envelope. */ ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_array; /* * Digest the rdata length. */ isc_buffer_init(&lenbuf, &len, sizeof(len)); INSIST(rdatas[i].length < 65536); isc_buffer_putuint16(&lenbuf, (isc_uint16_t)rdatas[i].length); isc_buffer_usedregion(&lenbuf, &lenr); /* * Digest the rdata. */ ret = dst_context_adddata(ctx, &lenr); if (ret != ISC_R_SUCCESS) goto cleanup_array; ret = dns_rdata_digest(&rdatas[i], digest_callback, ctx); if (ret != ISC_R_SUCCESS) goto cleanup_array; } r.base = sig.signature; r.length = sig.siglen; ret = dst_context_verify2(ctx, maxbits, &r); if (ret == ISC_R_SUCCESS && downcase) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(&sig.signer, namebuf, sizeof(namebuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1), "successfully validated after lower casing " "signer '%s'", namebuf); inc_stat(dns_dnssecstats_downcase); } else if (ret == ISC_R_SUCCESS) inc_stat(dns_dnssecstats_asis); cleanup_array: isc_mem_put(mctx, rdatas, nrdatas * sizeof(dns_rdata_t)); cleanup_context: dst_context_destroy(&ctx); if (ret == DST_R_VERIFYFAILURE && !downcase) { downcase = ISC_TRUE; goto again; } cleanup_struct: dns_rdata_freestruct(&sig); if (ret == DST_R_VERIFYFAILURE) ret = DNS_R_SIGINVALID; if (ret != ISC_R_SUCCESS) inc_stat(dns_dnssecstats_fail); if (ret == ISC_R_SUCCESS && labels - sig.labels > 0) { if (wild != NULL) RUNTIME_CHECK(dns_name_concatenate(dns_wildcardname, dns_fixedname_name(&fnewname), wild, NULL) == ISC_R_SUCCESS); inc_stat(dns_dnssecstats_wildcard); ret = DNS_R_FROMWILDCARD; } return (ret); } isc_result_t dns_dnssec_verify(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, isc_boolean_t ignoretime, isc_mem_t *mctx, dns_rdata_t *sigrdata) { isc_result_t result; result = dns_dnssec_verify2(name, set, key, ignoretime, mctx, sigrdata, NULL); if (result == DNS_R_FROMWILDCARD) result = ISC_R_SUCCESS; return (result); } isc_boolean_t dns_dnssec_keyactive(dst_key_t *key, isc_stdtime_t now) { isc_result_t result; isc_stdtime_t publish, active, revoke, inactive, delete; isc_boolean_t pubset = ISC_FALSE, actset = ISC_FALSE; isc_boolean_t revset = ISC_FALSE, inactset = ISC_FALSE; isc_boolean_t delset = ISC_FALSE; int major, minor; /* Is this an old-style key? */ result = dst_key_getprivateformat(key, &major, &minor); RUNTIME_CHECK(result == ISC_R_SUCCESS); /* * Smart signing started with key format 1.3; prior to that, all * keys are assumed active */ if (major == 1 && minor <= 2) return (ISC_TRUE); result = dst_key_gettime(key, DST_TIME_PUBLISH, &publish); if (result == ISC_R_SUCCESS) pubset = ISC_TRUE; result = dst_key_gettime(key, DST_TIME_ACTIVATE, &active); if (result == ISC_R_SUCCESS) actset = ISC_TRUE; result = dst_key_gettime(key, DST_TIME_REVOKE, &revoke); if (result == ISC_R_SUCCESS) revset = ISC_TRUE; result = dst_key_gettime(key, DST_TIME_INACTIVE, &inactive); if (result == ISC_R_SUCCESS) inactset = ISC_TRUE; result = dst_key_gettime(key, DST_TIME_DELETE, &delete); if (result == ISC_R_SUCCESS) delset = ISC_TRUE; if ((inactset && inactive <= now) || (delset && delete <= now)) return (ISC_FALSE); if (revset && revoke <= now && pubset && publish <= now) return (ISC_TRUE); if (actset && active <= now) return (ISC_TRUE); return (ISC_FALSE); } #define is_zone_key(key) ((dst_key_flags(key) & DNS_KEYFLAG_OWNERMASK) \ == DNS_KEYOWNER_ZONE) isc_result_t dns_dnssec_findzonekeys2(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, dns_name_t *name, const char *directory, isc_mem_t *mctx, unsigned int maxkeys, dst_key_t **keys, unsigned int *nkeys) { dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; dst_key_t *pubkey = NULL; unsigned int count = 0; isc_stdtime_t now; REQUIRE(nkeys != NULL); REQUIRE(keys != NULL); isc_stdtime_get(&now); *nkeys = 0; memset(keys, 0, sizeof(*keys) * maxkeys); dns_rdataset_init(&rdataset); RETERR(dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 0, 0, &rdataset, NULL)); RETERR(dns_rdataset_first(&rdataset)); while (result == ISC_R_SUCCESS && count < maxkeys) { pubkey = NULL; dns_rdataset_current(&rdataset, &rdata); RETERR(dns_dnssec_keyfromrdata(name, &rdata, mctx, &pubkey)); dst_key_setttl(pubkey, rdataset.ttl); if (!is_zone_key(pubkey) || (dst_key_flags(pubkey) & DNS_KEYTYPE_NOAUTH) != 0) goto next; /* Corrupted .key file? */ if (!dns_name_equal(name, dst_key_name(pubkey))) goto next; keys[count] = NULL; result = dst_key_fromfile(dst_key_name(pubkey), dst_key_id(pubkey), dst_key_alg(pubkey), DST_TYPE_PUBLIC|DST_TYPE_PRIVATE, directory, mctx, &keys[count]); /* * If the key was revoked and the private file * doesn't exist, maybe it was revoked internally * by named. Try loading the unrevoked version. */ if (result == ISC_R_FILENOTFOUND) { isc_uint32_t flags; flags = dst_key_flags(pubkey); if ((flags & DNS_KEYFLAG_REVOKE) != 0) { dst_key_setflags(pubkey, flags & ~DNS_KEYFLAG_REVOKE); result = dst_key_fromfile(dst_key_name(pubkey), dst_key_id(pubkey), dst_key_alg(pubkey), DST_TYPE_PUBLIC| DST_TYPE_PRIVATE, directory, mctx, &keys[count]); if (result == ISC_R_SUCCESS && dst_key_pubcompare(pubkey, keys[count], ISC_FALSE)) { dst_key_setflags(keys[count], flags); } dst_key_setflags(pubkey, flags); } } if (result != ISC_R_SUCCESS) { char keybuf[DNS_NAME_FORMATSIZE]; char algbuf[DNS_SECALG_FORMATSIZE]; dns_name_format(dst_key_name(pubkey), keybuf, sizeof(keybuf)); dns_secalg_format(dst_key_alg(pubkey), algbuf, sizeof(algbuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_DNSSEC, ISC_LOG_WARNING, "dns_dnssec_findzonekeys2: error " "reading private key file %s/%s/%d: %s", keybuf, algbuf, dst_key_id(pubkey), isc_result_totext(result)); } if (result == ISC_R_FILENOTFOUND || result == ISC_R_NOPERM) { keys[count] = pubkey; pubkey = NULL; count++; goto next; } if (result != ISC_R_SUCCESS) goto failure; /* * If a key is marked inactive, skip it */ if (!dns_dnssec_keyactive(keys[count], now)) { dst_key_setinactive(pubkey, ISC_TRUE); dst_key_free(&keys[count]); keys[count] = pubkey; pubkey = NULL; count++; goto next; } /* * Whatever the key's default TTL may have * been, the rdataset TTL takes priority. */ dst_key_setttl(keys[count], rdataset.ttl); if ((dst_key_flags(keys[count]) & DNS_KEYTYPE_NOAUTH) != 0) { /* We should never get here. */ dst_key_free(&keys[count]); goto next; } count++; next: if (pubkey != NULL) dst_key_free(&pubkey); dns_rdata_reset(&rdata); result = dns_rdataset_next(&rdataset); } if (result != ISC_R_NOMORE) goto failure; if (count == 0) result = ISC_R_NOTFOUND; else result = ISC_R_SUCCESS; failure: if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (pubkey != NULL) dst_key_free(&pubkey); if (result != ISC_R_SUCCESS) while (count > 0) dst_key_free(&keys[--count]); *nkeys = count; return (result); } isc_result_t dns_dnssec_findzonekeys(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, dns_name_t *name, isc_mem_t *mctx, unsigned int maxkeys, dst_key_t **keys, unsigned int *nkeys) { return (dns_dnssec_findzonekeys2(db, ver, node, name, NULL, mctx, maxkeys, keys, nkeys)); } isc_result_t dns_dnssec_signmessage(dns_message_t *msg, dst_key_t *key) { dns_rdata_sig_t sig; /* SIG(0) */ unsigned char data[512]; unsigned char header[DNS_MESSAGE_HEADERLEN]; isc_buffer_t headerbuf, databuf, sigbuf; unsigned int sigsize; isc_buffer_t *dynbuf = NULL; dns_rdata_t *rdata; dns_rdatalist_t *datalist; dns_rdataset_t *dataset; isc_region_t r; isc_stdtime_t now; dst_context_t *ctx = NULL; isc_mem_t *mctx; isc_result_t result; isc_boolean_t signeedsfree = ISC_TRUE; REQUIRE(msg != NULL); REQUIRE(key != NULL); if (is_response(msg)) REQUIRE(msg->query.base != NULL); mctx = msg->mctx; memset(&sig, 0, sizeof(sig)); sig.mctx = mctx; sig.common.rdclass = dns_rdataclass_any; sig.common.rdtype = dns_rdatatype_sig; /* SIG(0) */ ISC_LINK_INIT(&sig.common, link); sig.covered = 0; sig.algorithm = dst_key_alg(key); sig.labels = 0; /* the root name */ sig.originalttl = 0; isc_stdtime_get(&now); sig.timesigned = now - DNS_TSIG_FUDGE; sig.timeexpire = now + DNS_TSIG_FUDGE; sig.keyid = dst_key_id(key); dns_name_init(&sig.signer, NULL); dns_name_clone(dst_key_name(key), &sig.signer); sig.siglen = 0; sig.signature = NULL; isc_buffer_init(&databuf, data, sizeof(data)); RETERR(dst_context_create3(key, mctx, DNS_LOGCATEGORY_DNSSEC, ISC_TRUE, &ctx)); /* * Digest the fields of the SIG - we can cheat and use * dns_rdata_fromstruct. Since siglen is 0, the digested data * is identical to dns format. */ RETERR(dns_rdata_fromstruct(NULL, dns_rdataclass_any, dns_rdatatype_sig /* SIG(0) */, &sig, &databuf)); isc_buffer_usedregion(&databuf, &r); RETERR(dst_context_adddata(ctx, &r)); /* * If this is a response, digest the query. */ if (is_response(msg)) RETERR(dst_context_adddata(ctx, &msg->query)); /* * Digest the header. */ isc_buffer_init(&headerbuf, header, sizeof(header)); dns_message_renderheader(msg, &headerbuf); isc_buffer_usedregion(&headerbuf, &r); RETERR(dst_context_adddata(ctx, &r)); /* * Digest the remainder of the message. */ isc_buffer_usedregion(msg->buffer, &r); isc_region_consume(&r, DNS_MESSAGE_HEADERLEN); RETERR(dst_context_adddata(ctx, &r)); RETERR(dst_key_sigsize(key, &sigsize)); sig.siglen = sigsize; sig.signature = (unsigned char *) isc_mem_get(mctx, sig.siglen); if (sig.signature == NULL) { result = ISC_R_NOMEMORY; goto failure; } isc_buffer_init(&sigbuf, sig.signature, sig.siglen); RETERR(dst_context_sign(ctx, &sigbuf)); dst_context_destroy(&ctx); rdata = NULL; RETERR(dns_message_gettemprdata(msg, &rdata)); RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, 1024)); RETERR(dns_rdata_fromstruct(rdata, dns_rdataclass_any, dns_rdatatype_sig /* SIG(0) */, &sig, dynbuf)); isc_mem_put(mctx, sig.signature, sig.siglen); signeedsfree = ISC_FALSE; dns_message_takebuffer(msg, &dynbuf); datalist = NULL; RETERR(dns_message_gettemprdatalist(msg, &datalist)); datalist->rdclass = dns_rdataclass_any; datalist->type = dns_rdatatype_sig; /* SIG(0) */ ISC_LIST_APPEND(datalist->rdata, rdata, link); dataset = NULL; RETERR(dns_message_gettemprdataset(msg, &dataset)); RUNTIME_CHECK(dns_rdatalist_tordataset(datalist, dataset) == ISC_R_SUCCESS); msg->sig0 = dataset; return (ISC_R_SUCCESS); failure: if (dynbuf != NULL) isc_buffer_free(&dynbuf); if (signeedsfree) isc_mem_put(mctx, sig.signature, sig.siglen); if (ctx != NULL) dst_context_destroy(&ctx); return (result); } isc_result_t dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg, dst_key_t *key) { dns_rdata_sig_t sig; /* SIG(0) */ unsigned char header[DNS_MESSAGE_HEADERLEN]; dns_rdata_t rdata = DNS_RDATA_INIT; isc_region_t r, source_r, sig_r, header_r; isc_stdtime_t now; dst_context_t *ctx = NULL; isc_mem_t *mctx; isc_result_t result; isc_uint16_t addcount, addcount_n; isc_boolean_t signeedsfree = ISC_FALSE; REQUIRE(source != NULL); REQUIRE(msg != NULL); REQUIRE(key != NULL); mctx = msg->mctx; msg->verify_attempted = 1; if (is_response(msg)) { if (msg->query.base == NULL) return (DNS_R_UNEXPECTEDTSIG); } isc_buffer_usedregion(source, &source_r); RETERR(dns_rdataset_first(msg->sig0)); dns_rdataset_current(msg->sig0, &rdata); RETERR(dns_rdata_tostruct(&rdata, &sig, NULL)); signeedsfree = ISC_TRUE; if (sig.labels != 0) { result = DNS_R_SIGINVALID; goto failure; } if (isc_serial_lt(sig.timeexpire, sig.timesigned)) { result = DNS_R_SIGINVALID; msg->sig0status = dns_tsigerror_badtime; goto failure; } isc_stdtime_get(&now); if (isc_serial_lt((isc_uint32_t)now, sig.timesigned)) { result = DNS_R_SIGFUTURE; msg->sig0status = dns_tsigerror_badtime; goto failure; } else if (isc_serial_lt(sig.timeexpire, (isc_uint32_t)now)) { result = DNS_R_SIGEXPIRED; msg->sig0status = dns_tsigerror_badtime; goto failure; } if (!dns_name_equal(dst_key_name(key), &sig.signer)) { result = DNS_R_SIGINVALID; msg->sig0status = dns_tsigerror_badkey; goto failure; } RETERR(dst_context_create3(key, mctx, DNS_LOGCATEGORY_DNSSEC, ISC_FALSE, &ctx)); /* * Digest the SIG(0) record, except for the signature. */ dns_rdata_toregion(&rdata, &r); r.length -= sig.siglen; RETERR(dst_context_adddata(ctx, &r)); /* * If this is a response, digest the query. */ if (is_response(msg)) RETERR(dst_context_adddata(ctx, &msg->query)); /* * Extract the header. */ memmove(header, source_r.base, DNS_MESSAGE_HEADERLEN); /* * Decrement the additional field counter. */ memmove(&addcount, &header[DNS_MESSAGE_HEADERLEN - 2], 2); addcount_n = ntohs(addcount); addcount = htons((isc_uint16_t)(addcount_n - 1)); memmove(&header[DNS_MESSAGE_HEADERLEN - 2], &addcount, 2); /* * Digest the modified header. */ header_r.base = (unsigned char *) header; header_r.length = DNS_MESSAGE_HEADERLEN; RETERR(dst_context_adddata(ctx, &header_r)); /* * Digest all non-SIG(0) records. */ r.base = source_r.base + DNS_MESSAGE_HEADERLEN; r.length = msg->sigstart - DNS_MESSAGE_HEADERLEN; RETERR(dst_context_adddata(ctx, &r)); sig_r.base = sig.signature; sig_r.length = sig.siglen; result = dst_context_verify(ctx, &sig_r); if (result != ISC_R_SUCCESS) { msg->sig0status = dns_tsigerror_badsig; goto failure; } msg->verified_sig = 1; dst_context_destroy(&ctx); dns_rdata_freestruct(&sig); return (ISC_R_SUCCESS); failure: if (signeedsfree) dns_rdata_freestruct(&sig); if (ctx != NULL) dst_context_destroy(&ctx); return (result); } /*% * Does this key ('rdata') self sign the rrset ('rdataset')? */ isc_boolean_t dns_dnssec_selfsigns(dns_rdata_t *rdata, dns_name_t *name, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, isc_boolean_t ignoretime, isc_mem_t *mctx) { INSIST(rdataset->type == dns_rdatatype_key || rdataset->type == dns_rdatatype_dnskey); if (rdataset->type == dns_rdatatype_key) { INSIST(sigrdataset->type == dns_rdatatype_sig); INSIST(sigrdataset->covers == dns_rdatatype_key); } else { INSIST(sigrdataset->type == dns_rdatatype_rrsig); INSIST(sigrdataset->covers == dns_rdatatype_dnskey); } return (dns_dnssec_signs(rdata, name, rdataset, sigrdataset, ignoretime, mctx)); } isc_boolean_t dns_dnssec_signs(dns_rdata_t *rdata, dns_name_t *name, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, isc_boolean_t ignoretime, isc_mem_t *mctx) { dst_key_t *dstkey = NULL; dns_keytag_t keytag; dns_rdata_dnskey_t key; dns_rdata_rrsig_t sig; dns_rdata_t sigrdata = DNS_RDATA_INIT; isc_result_t result; INSIST(sigrdataset->type == dns_rdatatype_rrsig); if (sigrdataset->covers != rdataset->type) return (ISC_FALSE); result = dns_dnssec_keyfromrdata(name, rdata, mctx, &dstkey); if (result != ISC_R_SUCCESS) return (ISC_FALSE); result = dns_rdata_tostruct(rdata, &key, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); keytag = dst_key_id(dstkey); for (result = dns_rdataset_first(sigrdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(sigrdataset)) { dns_rdata_reset(&sigrdata); dns_rdataset_current(sigrdataset, &sigrdata); result = dns_rdata_tostruct(&sigrdata, &sig, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (sig.algorithm == key.algorithm && sig.keyid == keytag) { result = dns_dnssec_verify2(name, rdataset, dstkey, ignoretime, mctx, &sigrdata, NULL); if (result == ISC_R_SUCCESS) { dst_key_free(&dstkey); return (ISC_TRUE); } } } dst_key_free(&dstkey); return (ISC_FALSE); } isc_result_t dns_dnsseckey_create(isc_mem_t *mctx, dst_key_t **dstkey, dns_dnsseckey_t **dkp) { isc_result_t result; dns_dnsseckey_t *dk; int major, minor; REQUIRE(dkp != NULL && *dkp == NULL); dk = isc_mem_get(mctx, sizeof(dns_dnsseckey_t)); if (dk == NULL) return (ISC_R_NOMEMORY); dk->key = *dstkey; *dstkey = NULL; dk->force_publish = ISC_FALSE; dk->force_sign = ISC_FALSE; dk->hint_publish = ISC_FALSE; dk->hint_sign = ISC_FALSE; dk->hint_remove = ISC_FALSE; dk->first_sign = ISC_FALSE; dk->is_active = ISC_FALSE; dk->prepublish = 0; dk->source = dns_keysource_unknown; dk->index = 0; /* KSK or ZSK? */ dk->ksk = ISC_TF((dst_key_flags(dk->key) & DNS_KEYFLAG_KSK) != 0); /* Is this an old-style key? */ result = dst_key_getprivateformat(dk->key, &major, &minor); INSIST(result == ISC_R_SUCCESS); /* Smart signing started with key format 1.3 */ dk->legacy = ISC_TF(major == 1 && minor <= 2); ISC_LINK_INIT(dk, link); *dkp = dk; return (ISC_R_SUCCESS); } void dns_dnsseckey_destroy(isc_mem_t *mctx, dns_dnsseckey_t **dkp) { dns_dnsseckey_t *dk; REQUIRE(dkp != NULL && *dkp != NULL); dk = *dkp; if (dk->key != NULL) dst_key_free(&dk->key); isc_mem_put(mctx, dk, sizeof(dns_dnsseckey_t)); *dkp = NULL; } static void get_hints(dns_dnsseckey_t *key, isc_stdtime_t now) { isc_result_t result; isc_stdtime_t publish, active, revoke, inactive, delete; isc_boolean_t pubset = ISC_FALSE, actset = ISC_FALSE; isc_boolean_t revset = ISC_FALSE, inactset = ISC_FALSE; isc_boolean_t delset = ISC_FALSE; REQUIRE(key != NULL && key->key != NULL); result = dst_key_gettime(key->key, DST_TIME_PUBLISH, &publish); if (result == ISC_R_SUCCESS) pubset = ISC_TRUE; result = dst_key_gettime(key->key, DST_TIME_ACTIVATE, &active); if (result == ISC_R_SUCCESS) actset = ISC_TRUE; result = dst_key_gettime(key->key, DST_TIME_REVOKE, &revoke); if (result == ISC_R_SUCCESS) revset = ISC_TRUE; result = dst_key_gettime(key->key, DST_TIME_INACTIVE, &inactive); if (result == ISC_R_SUCCESS) inactset = ISC_TRUE; result = dst_key_gettime(key->key, DST_TIME_DELETE, &delete); if (result == ISC_R_SUCCESS) delset = ISC_TRUE; /* Metadata says publish (but possibly not activate) */ if (pubset && publish <= now) key->hint_publish = ISC_TRUE; /* Metadata says activate (so we must also publish) */ if (actset && active <= now) { key->hint_sign = ISC_TRUE; /* Only publish if publish time has already passed. */ if (pubset && publish <= now) key->hint_publish = ISC_TRUE; } /* * Activation date is set (maybe in the future), but * publication date isn't. Most likely the user wants to * publish now and activate later. */ if (actset && !pubset) key->hint_publish = ISC_TRUE; /* * If activation date is in the future, make note of how far off */ if (key->hint_publish && actset && active > now) { key->prepublish = active - now; } /* * Key has been marked inactive: we can continue publishing, * but don't sign. */ if (key->hint_publish && inactset && inactive <= now) { key->hint_sign = ISC_FALSE; } /* * Metadata says revoke. If the key is published, * we *have to* sign with it per RFC5011--even if it was * not active before. * * If it hasn't already been done, we should also revoke it now. */ if (key->hint_publish && (revset && revoke <= now)) { isc_uint32_t flags; key->hint_sign = ISC_TRUE; flags = dst_key_flags(key->key); if ((flags & DNS_KEYFLAG_REVOKE) == 0) { flags |= DNS_KEYFLAG_REVOKE; dst_key_setflags(key->key, flags); } } /* * Metadata says delete, so don't publish this key or sign with it. */ if (delset && delete <= now) { key->hint_publish = ISC_FALSE; key->hint_sign = ISC_FALSE; key->hint_remove = ISC_TRUE; } } /*% * Get a list of DNSSEC keys from the key repository */ isc_result_t dns_dnssec_findmatchingkeys(dns_name_t *origin, const char *directory, isc_mem_t *mctx, dns_dnsseckeylist_t *keylist) { isc_result_t result = ISC_R_SUCCESS; isc_boolean_t dir_open = ISC_FALSE; dns_dnsseckeylist_t list; isc_dir_t dir; dns_dnsseckey_t *key = NULL; dst_key_t *dstkey = NULL; char namebuf[DNS_NAME_FORMATSIZE]; isc_buffer_t b; unsigned int len, i; isc_stdtime_t now; REQUIRE(keylist != NULL); ISC_LIST_INIT(list); isc_dir_init(&dir); isc_buffer_init(&b, namebuf, sizeof(namebuf) - 1); RETERR(dns_name_tofilenametext(origin, ISC_FALSE, &b)); len = isc_buffer_usedlength(&b); namebuf[len] = '\0'; if (directory == NULL) directory = "."; RETERR(isc_dir_open(&dir, directory)); dir_open = ISC_TRUE; isc_stdtime_get(&now); while (isc_dir_read(&dir) == ISC_R_SUCCESS) { if (dir.entry.name[0] != 'K' || dir.entry.length < len + 1 || dir.entry.name[len + 1] != '+' || strncasecmp(dir.entry.name + 1, namebuf, len) != 0) continue; for (i = len + 1 + 1; i < dir.entry.length ; i++) if (dir.entry.name[i] < '0' || dir.entry.name[i] > '9') break; if (i == len + 1 + 1 || i >= dir.entry.length || dir.entry.name[i] != '+') continue; for (i++ ; i < dir.entry.length ; i++) if (dir.entry.name[i] < '0' || dir.entry.name[i] > '9') break; if (strcmp(dir.entry.name + i, ".private") != 0) continue; dstkey = NULL; result = dst_key_fromnamedfile(dir.entry.name, directory, DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, mctx, &dstkey); if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_DNSSEC, ISC_LOG_WARNING, "dns_dnssec_findmatchingkeys: " "error reading key file %s: %s", dir.entry.name, isc_result_totext(result)); continue; } RETERR(dns_dnsseckey_create(mctx, &dstkey, &key)); key->source = dns_keysource_repository; get_hints(key, now); if (key->legacy) { dns_dnsseckey_destroy(mctx, &key); } else { ISC_LIST_APPEND(list, key, link); key = NULL; } } if (!ISC_LIST_EMPTY(list)) { result = ISC_R_SUCCESS; ISC_LIST_APPENDLIST(*keylist, list, link); } else result = ISC_R_NOTFOUND; failure: if (dir_open) isc_dir_close(&dir); INSIST(key == NULL); while ((key = ISC_LIST_HEAD(list)) != NULL) { ISC_LIST_UNLINK(list, key, link); INSIST(key->key != NULL); dst_key_free(&key->key); dns_dnsseckey_destroy(mctx, &key); } if (dstkey != NULL) dst_key_free(&dstkey); return (result); } /*% * Add 'newkey' to 'keylist' if it's not already there. * * If 'savekeys' is ISC_TRUE, then we need to preserve all * the keys in the keyset, regardless of whether they have * metadata indicating they should be deactivated or removed. */ static isc_result_t addkey(dns_dnsseckeylist_t *keylist, dst_key_t **newkey, isc_boolean_t savekeys, isc_mem_t *mctx) { dns_dnsseckey_t *key; isc_result_t result; /* Skip duplicates */ for (key = ISC_LIST_HEAD(*keylist); key != NULL; key = ISC_LIST_NEXT(key, link)) { if (dst_key_id(key->key) == dst_key_id(*newkey) && dst_key_alg(key->key) == dst_key_alg(*newkey) && dns_name_equal(dst_key_name(key->key), dst_key_name(*newkey))) break; } if (key != NULL) { /* * Found a match. If the old key was only public and the * new key is private, replace the old one; otherwise * leave it. But either way, mark the key as having * been found in the zone. */ if (dst_key_isprivate(key->key)) { dst_key_free(newkey); } else if (dst_key_isprivate(*newkey)) { dst_key_free(&key->key); key->key = *newkey; } key->source = dns_keysource_zoneapex; return (ISC_R_SUCCESS); } result = dns_dnsseckey_create(mctx, newkey, &key); if (result != ISC_R_SUCCESS) return (result); if (key->legacy || savekeys) { key->force_publish = ISC_TRUE; key->force_sign = dst_key_isprivate(key->key); } key->source = dns_keysource_zoneapex; ISC_LIST_APPEND(*keylist, key, link); *newkey = NULL; return (ISC_R_SUCCESS); } /*% * Mark all keys which signed the DNSKEY/SOA RRsets as "active", * for future reference. */ static isc_result_t mark_active_keys(dns_dnsseckeylist_t *keylist, dns_rdataset_t *rrsigs) { isc_result_t result = ISC_R_SUCCESS; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_t sigs; dns_dnsseckey_t *key; REQUIRE(rrsigs != NULL && dns_rdataset_isassociated(rrsigs)); dns_rdataset_init(&sigs); dns_rdataset_clone(rrsigs, &sigs); for (key = ISC_LIST_HEAD(*keylist); key != NULL; key = ISC_LIST_NEXT(key, link)) { isc_uint16_t keyid, sigid; dns_secalg_t keyalg, sigalg; keyid = dst_key_id(key->key); keyalg = dst_key_alg(key->key); for (result = dns_rdataset_first(&sigs); result == ISC_R_SUCCESS; result = dns_rdataset_next(&sigs)) { dns_rdata_rrsig_t sig; dns_rdata_reset(&rdata); dns_rdataset_current(&sigs, &rdata); result = dns_rdata_tostruct(&rdata, &sig, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); sigalg = sig.algorithm; sigid = sig.keyid; if (keyid == sigid && keyalg == sigalg) { key->is_active = ISC_TRUE; break; } } } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; if (dns_rdataset_isassociated(&sigs)) dns_rdataset_disassociate(&sigs); return (result); } /*% * Add the contents of a DNSKEY rdataset 'keyset' to 'keylist'. */ isc_result_t dns_dnssec_keylistfromrdataset(dns_name_t *origin, const char *directory, isc_mem_t *mctx, dns_rdataset_t *keyset, dns_rdataset_t *keysigs, dns_rdataset_t *soasigs, isc_boolean_t savekeys, isc_boolean_t publickey, dns_dnsseckeylist_t *keylist) { dns_rdataset_t keys; dns_rdata_t rdata = DNS_RDATA_INIT; dst_key_t *pubkey = NULL, *privkey = NULL; isc_result_t result; REQUIRE(keyset != NULL && dns_rdataset_isassociated(keyset)); dns_rdataset_init(&keys); dns_rdataset_clone(keyset, &keys); for (result = dns_rdataset_first(&keys); result == ISC_R_SUCCESS; result = dns_rdataset_next(&keys)) { dns_rdata_reset(&rdata); dns_rdataset_current(&keys, &rdata); RETERR(dns_dnssec_keyfromrdata(origin, &rdata, mctx, &pubkey)); dst_key_setttl(pubkey, keys.ttl); if (!is_zone_key(pubkey) || (dst_key_flags(pubkey) & DNS_KEYTYPE_NOAUTH) != 0) goto skip; /* Corrupted .key file? */ if (!dns_name_equal(origin, dst_key_name(pubkey))) goto skip; if (publickey) { RETERR(addkey(keylist, &pubkey, savekeys, mctx)); goto skip; } result = dst_key_fromfile(dst_key_name(pubkey), dst_key_id(pubkey), dst_key_alg(pubkey), DST_TYPE_PUBLIC|DST_TYPE_PRIVATE, directory, mctx, &privkey); /* * If the key was revoked and the private file * doesn't exist, maybe it was revoked internally * by named. Try loading the unrevoked version. */ if (result == ISC_R_FILENOTFOUND) { isc_uint32_t flags; flags = dst_key_flags(pubkey); if ((flags & DNS_KEYFLAG_REVOKE) != 0) { dst_key_setflags(pubkey, flags & ~DNS_KEYFLAG_REVOKE); result = dst_key_fromfile(dst_key_name(pubkey), dst_key_id(pubkey), dst_key_alg(pubkey), DST_TYPE_PUBLIC| DST_TYPE_PRIVATE, directory, mctx, &privkey); if (result == ISC_R_SUCCESS && dst_key_pubcompare(pubkey, privkey, ISC_FALSE)) { dst_key_setflags(privkey, flags); } dst_key_setflags(pubkey, flags); } } if (result != ISC_R_SUCCESS) { char keybuf[DNS_NAME_FORMATSIZE]; char algbuf[DNS_SECALG_FORMATSIZE]; dns_name_format(dst_key_name(pubkey), keybuf, sizeof(keybuf)); dns_secalg_format(dst_key_alg(pubkey), algbuf, sizeof(algbuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_DNSSEC, ISC_LOG_WARNING, "dns_dnssec_keylistfromrdataset: error " "reading private key file %s/%s/%d: %s", keybuf, algbuf, dst_key_id(pubkey), isc_result_totext(result)); } if (result == ISC_R_FILENOTFOUND || result == ISC_R_NOPERM) { RETERR(addkey(keylist, &pubkey, savekeys, mctx)); goto skip; } RETERR(result); /* This should never happen. */ if ((dst_key_flags(privkey) & DNS_KEYTYPE_NOAUTH) != 0) goto skip; /* * Whatever the key's default TTL may have * been, the rdataset TTL takes priority. */ dst_key_setttl(privkey, dst_key_getttl(pubkey)); RETERR(addkey(keylist, &privkey, savekeys, mctx)); skip: if (pubkey != NULL) dst_key_free(&pubkey); if (privkey != NULL) dst_key_free(&privkey); } if (result != ISC_R_NOMORE) RETERR(result); if (keysigs != NULL && dns_rdataset_isassociated(keysigs)) RETERR(mark_active_keys(keylist, keysigs)); if (soasigs != NULL && dns_rdataset_isassociated(soasigs)) RETERR(mark_active_keys(keylist, soasigs)); result = ISC_R_SUCCESS; failure: if (dns_rdataset_isassociated(&keys)) dns_rdataset_disassociate(&keys); if (pubkey != NULL) dst_key_free(&pubkey); if (privkey != NULL) dst_key_free(&privkey); return (result); } static isc_result_t make_dnskey(dst_key_t *key, unsigned char *buf, int bufsize, dns_rdata_t *target) { isc_result_t result; isc_buffer_t b; isc_region_t r; isc_buffer_init(&b, buf, bufsize); result = dst_key_todns(key, &b); if (result != ISC_R_SUCCESS) return (result); dns_rdata_reset(target); isc_buffer_usedregion(&b, &r); dns_rdata_fromregion(target, dst_key_class(key), dns_rdatatype_dnskey, &r); return (ISC_R_SUCCESS); } static isc_result_t publish_key(dns_diff_t *diff, dns_dnsseckey_t *key, dns_name_t *origin, dns_ttl_t ttl, isc_mem_t *mctx, isc_boolean_t allzsk, void (*report)(const char *, ...)) { isc_result_t result; dns_difftuple_t *tuple = NULL; unsigned char buf[DST_KEY_MAXSIZE]; dns_rdata_t dnskey = DNS_RDATA_INIT; char alg[80]; dns_rdata_reset(&dnskey); RETERR(make_dnskey(key->key, buf, sizeof(buf), &dnskey)); dns_secalg_format(dst_key_alg(key->key), alg, sizeof(alg)); report("Fetching %s %d/%s from key %s.", key->ksk ? (allzsk ? "KSK/ZSK" : "KSK") : "ZSK", dst_key_id(key->key), alg, key->source == dns_keysource_user ? "file" : "repository"); if (key->prepublish && ttl > key->prepublish) { char keystr[DST_KEY_FORMATSIZE]; isc_stdtime_t now; dst_key_format(key->key, keystr, sizeof(keystr)); report("Key %s: Delaying activation to match the DNSKEY TTL.\n", keystr, ttl); isc_stdtime_get(&now); dst_key_settime(key->key, DST_TIME_ACTIVATE, now + ttl); } /* publish key */ RETERR(dns_difftuple_create(mctx, DNS_DIFFOP_ADD, origin, ttl, &dnskey, &tuple)); dns_diff_appendminimal(diff, &tuple); result = ISC_R_SUCCESS; failure: return (result); } static isc_result_t remove_key(dns_diff_t *diff, dns_dnsseckey_t *key, dns_name_t *origin, dns_ttl_t ttl, isc_mem_t *mctx, const char *reason, void (*report)(const char *, ...)) { isc_result_t result; dns_difftuple_t *tuple = NULL; unsigned char buf[DST_KEY_MAXSIZE]; dns_rdata_t dnskey = DNS_RDATA_INIT; char alg[80]; dns_secalg_format(dst_key_alg(key->key), alg, sizeof(alg)); report("Removing %s key %d/%s from DNSKEY RRset.", reason, dst_key_id(key->key), alg); RETERR(make_dnskey(key->key, buf, sizeof(buf), &dnskey)); RETERR(dns_difftuple_create(mctx, DNS_DIFFOP_DEL, origin, ttl, &dnskey, &tuple)); dns_diff_appendminimal(diff, &tuple); result = ISC_R_SUCCESS; failure: return (result); } /* * Update 'keys' with information from 'newkeys'. * * If 'removed' is not NULL, any keys that are being removed from * the zone will be added to the list for post-removal processing. */ isc_result_t dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys, dns_dnsseckeylist_t *removed, dns_name_t *origin, dns_ttl_t hint_ttl, dns_diff_t *diff, isc_boolean_t allzsk, isc_mem_t *mctx, void (*report)(const char *, ...)) { isc_result_t result; dns_dnsseckey_t *key, *key1, *key2, *next; isc_boolean_t found_ttl = ISC_FALSE; dns_ttl_t ttl = hint_ttl; /* * First, look through the existing key list to find keys * supplied from the command line which are not in the zone. * Update the zone to include them. * * Also, if there are keys published in the zone already, * use their TTL for all subsequent published keys. */ for (key = ISC_LIST_HEAD(*keys); key != NULL; key = ISC_LIST_NEXT(key, link)) { if (key->source == dns_keysource_user && (key->hint_publish || key->force_publish)) { RETERR(publish_key(diff, key, origin, ttl, mctx, allzsk, report)); } if (key->source == dns_keysource_zoneapex) { ttl = dst_key_getttl(key->key); found_ttl = ISC_TRUE; } } /* * If there were no existing keys, use the smallest nonzero * TTL of the keys found in the repository. */ if (!found_ttl && !ISC_LIST_EMPTY(*newkeys)) { dns_ttl_t shortest = 0; for (key = ISC_LIST_HEAD(*newkeys); key != NULL; key = ISC_LIST_NEXT(key, link)) { dns_ttl_t thisttl = dst_key_getttl(key->key); if (thisttl != 0 && (shortest == 0 || thisttl < shortest)) shortest = thisttl; } if (shortest != 0) ttl = shortest; } /* * Second, scan the list of newly found keys looking for matches * with known keys, and update accordingly. */ for (key1 = ISC_LIST_HEAD(*newkeys); key1 != NULL; key1 = next) { isc_boolean_t key_revoked = ISC_FALSE; next = ISC_LIST_NEXT(key1, link); for (key2 = ISC_LIST_HEAD(*keys); key2 != NULL; key2 = ISC_LIST_NEXT(key2, link)) { int f1 = dst_key_flags(key1->key); int f2 = dst_key_flags(key2->key); int nr1 = f1 & ~DNS_KEYFLAG_REVOKE; int nr2 = f2 & ~DNS_KEYFLAG_REVOKE; if (nr1 == nr2 && dst_key_alg(key1->key) == dst_key_alg(key2->key) && dst_key_pubcompare(key1->key, key2->key, ISC_TRUE)) { int r1, r2; r1 = dst_key_flags(key1->key) & DNS_KEYFLAG_REVOKE; r2 = dst_key_flags(key2->key) & DNS_KEYFLAG_REVOKE; key_revoked = ISC_TF(r1 != r2); break; } } /* No match found in keys; add the new key. */ if (key2 == NULL) { ISC_LIST_UNLINK(*newkeys, key1, link); ISC_LIST_APPEND(*keys, key1, link); if (key1->source != dns_keysource_zoneapex && (key1->hint_publish || key1->force_publish)) { RETERR(publish_key(diff, key1, origin, ttl, mctx, allzsk, report)); if (key1->hint_sign || key1->force_sign) key1->first_sign = ISC_TRUE; } continue; } /* Match found: remove or update it as needed */ if (key1->hint_remove) { RETERR(remove_key(diff, key2, origin, ttl, mctx, "expired", report)); ISC_LIST_UNLINK(*keys, key2, link); if (removed != NULL) ISC_LIST_APPEND(*removed, key2, link); else dns_dnsseckey_destroy(mctx, &key2); } else if (key_revoked && (dst_key_flags(key1->key) & DNS_KEYFLAG_REVOKE) != 0) { /* * A previously valid key has been revoked. * We need to remove the old version and pull * in the new one. */ RETERR(remove_key(diff, key2, origin, ttl, mctx, "revoked", report)); ISC_LIST_UNLINK(*keys, key2, link); if (removed != NULL) ISC_LIST_APPEND(*removed, key2, link); else dns_dnsseckey_destroy(mctx, &key2); RETERR(publish_key(diff, key1, origin, ttl, mctx, allzsk, report)); ISC_LIST_UNLINK(*newkeys, key1, link); ISC_LIST_APPEND(*keys, key1, link); /* * XXX: The revoke flag is only defined for trust * anchors. Setting the flag on a non-KSK is legal, * but not defined in any RFC. It seems reasonable * to treat it the same as a KSK: keep it in the * zone, sign the DNSKEY set with it, but not * sign other records with it. */ key1->ksk = ISC_TRUE; continue; } else { if (!key2->is_active && (key1->hint_sign || key1->force_sign)) key2->first_sign = ISC_TRUE; key2->hint_sign = key1->hint_sign; key2->hint_publish = key1->hint_publish; } } /* Free any leftover keys in newkeys */ while (!ISC_LIST_EMPTY(*newkeys)) { key1 = ISC_LIST_HEAD(*newkeys); ISC_LIST_UNLINK(*newkeys, key1, link); dns_dnsseckey_destroy(mctx, &key1); } result = ISC_R_SUCCESS; failure: return (result); } bind9-9.10.3.dfsg.P4/lib/dns/sdlz.c0000644000470500017500000015061412664710322016052 0ustar lamontlamont/* * Portions Copyright (C) 2005-2015 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all * copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE * USE OR PERFORMANCE OF THIS SOFTWARE. * * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was * conceived and contributed by Rob Butler. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all * copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * ROB BUTLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE * USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "rdatalist_p.h" /* * Private Types */ struct dns_sdlzimplementation { const dns_sdlzmethods_t *methods; isc_mem_t *mctx; void *driverarg; unsigned int flags; isc_mutex_t driverlock; dns_dlzimplementation_t *dlz_imp; }; struct dns_sdlz_db { /* Unlocked */ dns_db_t common; void *dbdata; dns_sdlzimplementation_t *dlzimp; isc_mutex_t refcnt_lock; /* Locked */ unsigned int references; dns_dbversion_t *future_version; int dummy_version; }; struct dns_sdlzlookup { /* Unlocked */ unsigned int magic; dns_sdlz_db_t *sdlz; ISC_LIST(dns_rdatalist_t) lists; ISC_LIST(isc_buffer_t) buffers; dns_name_t *name; ISC_LINK(dns_sdlzlookup_t) link; isc_mutex_t lock; dns_rdatacallbacks_t callbacks; /* Locked */ unsigned int references; }; typedef struct dns_sdlzlookup dns_sdlznode_t; struct dns_sdlzallnodes { dns_dbiterator_t common; ISC_LIST(dns_sdlznode_t) nodelist; dns_sdlznode_t *current; dns_sdlznode_t *origin; }; typedef dns_sdlzallnodes_t sdlz_dbiterator_t; typedef struct sdlz_rdatasetiter { dns_rdatasetiter_t common; dns_rdatalist_t *current; } sdlz_rdatasetiter_t; #define SDLZDB_MAGIC ISC_MAGIC('D', 'L', 'Z', 'S') /* * Note that "impmagic" is not the first four bytes of the struct, so * ISC_MAGIC_VALID cannot be used. */ #define VALID_SDLZDB(sdlzdb) ((sdlzdb) != NULL && \ (sdlzdb)->common.impmagic == SDLZDB_MAGIC) #define SDLZLOOKUP_MAGIC ISC_MAGIC('D','L','Z','L') #define VALID_SDLZLOOKUP(sdlzl) ISC_MAGIC_VALID(sdlzl, SDLZLOOKUP_MAGIC) #define VALID_SDLZNODE(sdlzn) VALID_SDLZLOOKUP(sdlzn) /* These values are taken from RFC 1537 */ #define SDLZ_DEFAULT_REFRESH (60 * 60 * 8) #define SDLZ_DEFAULT_RETRY (60 * 60 * 2) #define SDLZ_DEFAULT_EXPIRE (60 * 60 * 24 * 7) #define SDLZ_DEFAULT_MINIMUM (60 * 60 * 24) /* This is a reasonable value */ #define SDLZ_DEFAULT_TTL (60 * 60 * 24) #ifdef __COVERITY__ #define MAYBE_LOCK(imp) LOCK(&imp->driverlock) #define MAYBE_UNLOCK(imp) UNLOCK(&imp->driverlock) #else #define MAYBE_LOCK(imp) \ do { \ unsigned int flags = imp->flags; \ if ((flags & DNS_SDLZFLAG_THREADSAFE) == 0) \ LOCK(&imp->driverlock); \ } while (0) #define MAYBE_UNLOCK(imp) \ do { \ unsigned int flags = imp->flags; \ if ((flags & DNS_SDLZFLAG_THREADSAFE) == 0) \ UNLOCK(&imp->driverlock); \ } while (0) #endif /* * Forward references. Try to keep these to a minimum. */ static void list_tordataset(dns_rdatalist_t *rdatalist, dns_db_t *db, dns_dbnode_t *node, dns_rdataset_t *rdataset); static void detachnode(dns_db_t *db, dns_dbnode_t **targetp); static void dbiterator_destroy(dns_dbiterator_t **iteratorp); static isc_result_t dbiterator_first(dns_dbiterator_t *iterator); static isc_result_t dbiterator_last(dns_dbiterator_t *iterator); static isc_result_t dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name); static isc_result_t dbiterator_prev(dns_dbiterator_t *iterator); static isc_result_t dbiterator_next(dns_dbiterator_t *iterator); static isc_result_t dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep, dns_name_t *name); static isc_result_t dbiterator_pause(dns_dbiterator_t *iterator); static isc_result_t dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name); static dns_dbiteratormethods_t dbiterator_methods = { dbiterator_destroy, dbiterator_first, dbiterator_last, dbiterator_seek, dbiterator_prev, dbiterator_next, dbiterator_current, dbiterator_pause, dbiterator_origin }; /* * Utility functions */ /* * Log a message at the given level */ static void sdlz_log(int level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(level), fmt, ap); va_end(ap); } /*% Converts the input string to lowercase, in place. */ static void dns_sdlz_tolower(char *str) { unsigned int len = strlen(str); unsigned int i; for (i = 0; i < len; i++) { if (str[i] >= 'A' && str[i] <= 'Z') str[i] += 32; } } static inline unsigned int initial_size(const char *data) { unsigned int len = (strlen(data) / 64) + 1; return (len * 64 + 64); } /* * Rdataset Iterator Methods. These methods were "borrowed" from the SDB * driver interface. See the SDB driver interface documentation for more info. */ static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) { sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)(*iteratorp); detachnode(sdlziterator->common.db, &sdlziterator->common.node); isc_mem_put(sdlziterator->common.db->mctx, sdlziterator, sizeof(sdlz_rdatasetiter_t)); *iteratorp = NULL; } static isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator) { sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator; dns_sdlznode_t *sdlznode = (dns_sdlznode_t *)iterator->node; if (ISC_LIST_EMPTY(sdlznode->lists)) return (ISC_R_NOMORE); sdlziterator->current = ISC_LIST_HEAD(sdlznode->lists); return (ISC_R_SUCCESS); } static isc_result_t rdatasetiter_next(dns_rdatasetiter_t *iterator) { sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator; sdlziterator->current = ISC_LIST_NEXT(sdlziterator->current, link); if (sdlziterator->current == NULL) return (ISC_R_NOMORE); else return (ISC_R_SUCCESS); } static void rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) { sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator; list_tordataset(sdlziterator->current, iterator->db, iterator->node, rdataset); } static dns_rdatasetitermethods_t rdatasetiter_methods = { rdatasetiter_destroy, rdatasetiter_first, rdatasetiter_next, rdatasetiter_current }; /* * DB routines. These methods were "borrowed" from the SDB driver interface. * See the SDB driver interface documentation for more info. */ static void attach(dns_db_t *source, dns_db_t **targetp) { dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *) source; REQUIRE(VALID_SDLZDB(sdlz)); LOCK(&sdlz->refcnt_lock); REQUIRE(sdlz->references > 0); sdlz->references++; UNLOCK(&sdlz->refcnt_lock); *targetp = source; } static void destroy(dns_sdlz_db_t *sdlz) { isc_mem_t *mctx; mctx = sdlz->common.mctx; sdlz->common.magic = 0; sdlz->common.impmagic = 0; (void)isc_mutex_destroy(&sdlz->refcnt_lock); dns_name_free(&sdlz->common.origin, mctx); isc_mem_put(mctx, sdlz, sizeof(dns_sdlz_db_t)); isc_mem_detach(&mctx); } static void detach(dns_db_t **dbp) { dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)(*dbp); isc_boolean_t need_destroy = ISC_FALSE; REQUIRE(VALID_SDLZDB(sdlz)); LOCK(&sdlz->refcnt_lock); REQUIRE(sdlz->references > 0); sdlz->references--; if (sdlz->references == 0) need_destroy = ISC_TRUE; UNLOCK(&sdlz->refcnt_lock); if (need_destroy) destroy(sdlz); *dbp = NULL; } static isc_result_t beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) { UNUSED(db); UNUSED(callbacks); return (ISC_R_NOTIMPLEMENTED); } static isc_result_t endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) { UNUSED(db); UNUSED(callbacks); return (ISC_R_NOTIMPLEMENTED); } static isc_result_t dump(dns_db_t *db, dns_dbversion_t *version, const char *filename, dns_masterformat_t masterformat) { UNUSED(db); UNUSED(version); UNUSED(filename); UNUSED(masterformat); return (ISC_R_NOTIMPLEMENTED); } static void currentversion(dns_db_t *db, dns_dbversion_t **versionp) { dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; REQUIRE(VALID_SDLZDB(sdlz)); REQUIRE(versionp != NULL && *versionp == NULL); *versionp = (void *) &sdlz->dummy_version; return; } static isc_result_t newversion(dns_db_t *db, dns_dbversion_t **versionp) { dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; char origin[DNS_NAME_MAXTEXT + 1]; isc_result_t result; REQUIRE(VALID_SDLZDB(sdlz)); if (sdlz->dlzimp->methods->newversion == NULL) return (ISC_R_NOTIMPLEMENTED); dns_name_format(&sdlz->common.origin, origin, sizeof(origin)); result = sdlz->dlzimp->methods->newversion(origin, sdlz->dlzimp->driverarg, sdlz->dbdata, versionp); if (result != ISC_R_SUCCESS) { sdlz_log(ISC_LOG_ERROR, "sdlz newversion on origin %s failed : %s", origin, isc_result_totext(result)); return (result); } sdlz->future_version = *versionp; return (ISC_R_SUCCESS); } static void attachversion(dns_db_t *db, dns_dbversion_t *source, dns_dbversion_t **targetp) { dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; REQUIRE(VALID_SDLZDB(sdlz)); REQUIRE(source != NULL && source == (void *)&sdlz->dummy_version); *targetp = source; } static void closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) { dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; char origin[DNS_NAME_MAXTEXT + 1]; REQUIRE(VALID_SDLZDB(sdlz)); REQUIRE(versionp != NULL); if (*versionp == (void *)&sdlz->dummy_version) { *versionp = NULL; return; } REQUIRE(*versionp == sdlz->future_version); REQUIRE(sdlz->dlzimp->methods->closeversion != NULL); dns_name_format(&sdlz->common.origin, origin, sizeof(origin)); sdlz->dlzimp->methods->closeversion(origin, commit, sdlz->dlzimp->driverarg, sdlz->dbdata, versionp); if (*versionp != NULL) sdlz_log(ISC_LOG_ERROR, "sdlz closeversion on origin %s failed", origin); sdlz->future_version = NULL; } static isc_result_t createnode(dns_sdlz_db_t *sdlz, dns_sdlznode_t **nodep) { dns_sdlznode_t *node; isc_result_t result; node = isc_mem_get(sdlz->common.mctx, sizeof(dns_sdlznode_t)); if (node == NULL) return (ISC_R_NOMEMORY); node->sdlz = NULL; attach((dns_db_t *)sdlz, (dns_db_t **)&node->sdlz); ISC_LIST_INIT(node->lists); ISC_LIST_INIT(node->buffers); ISC_LINK_INIT(node, link); node->name = NULL; result = isc_mutex_init(&node->lock); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_mutex_init() failed: %s", isc_result_totext(result)); isc_mem_put(sdlz->common.mctx, node, sizeof(dns_sdlznode_t)); return (ISC_R_UNEXPECTED); } dns_rdatacallbacks_init(&node->callbacks); node->references = 1; node->magic = SDLZLOOKUP_MAGIC; *nodep = node; return (ISC_R_SUCCESS); } static void destroynode(dns_sdlznode_t *node) { dns_rdatalist_t *list; dns_rdata_t *rdata; isc_buffer_t *b; dns_sdlz_db_t *sdlz; dns_db_t *db; isc_mem_t *mctx; sdlz = node->sdlz; mctx = sdlz->common.mctx; while (!ISC_LIST_EMPTY(node->lists)) { list = ISC_LIST_HEAD(node->lists); while (!ISC_LIST_EMPTY(list->rdata)) { rdata = ISC_LIST_HEAD(list->rdata); ISC_LIST_UNLINK(list->rdata, rdata, link); isc_mem_put(mctx, rdata, sizeof(dns_rdata_t)); } ISC_LIST_UNLINK(node->lists, list, link); isc_mem_put(mctx, list, sizeof(dns_rdatalist_t)); } while (!ISC_LIST_EMPTY(node->buffers)) { b = ISC_LIST_HEAD(node->buffers); ISC_LIST_UNLINK(node->buffers, b, link); isc_buffer_free(&b); } if (node->name != NULL) { dns_name_free(node->name, mctx); isc_mem_put(mctx, node->name, sizeof(dns_name_t)); } DESTROYLOCK(&node->lock); node->magic = 0; isc_mem_put(mctx, node, sizeof(dns_sdlznode_t)); db = &sdlz->common; detach(&db); } static isc_result_t findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep) { dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; dns_sdlznode_t *node = NULL; isc_result_t result; isc_buffer_t b; char namestr[DNS_NAME_MAXTEXT + 1]; isc_buffer_t b2; char zonestr[DNS_NAME_MAXTEXT + 1]; isc_boolean_t isorigin; dns_sdlzauthorityfunc_t authority; REQUIRE(VALID_SDLZDB(sdlz)); REQUIRE(nodep != NULL && *nodep == NULL); if (sdlz->dlzimp->methods->newversion == NULL) { REQUIRE(create == ISC_FALSE); } isc_buffer_init(&b, namestr, sizeof(namestr)); if ((sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVEOWNER) != 0) { dns_name_t relname; unsigned int labels; labels = dns_name_countlabels(name) - dns_name_countlabels(&db->origin); dns_name_init(&relname, NULL); dns_name_getlabelsequence(name, 0, labels, &relname); result = dns_name_totext(&relname, ISC_TRUE, &b); if (result != ISC_R_SUCCESS) return (result); } else { result = dns_name_totext(name, ISC_TRUE, &b); if (result != ISC_R_SUCCESS) return (result); } isc_buffer_putuint8(&b, 0); isc_buffer_init(&b2, zonestr, sizeof(zonestr)); result = dns_name_totext(&sdlz->common.origin, ISC_TRUE, &b2); if (result != ISC_R_SUCCESS) return (result); isc_buffer_putuint8(&b2, 0); result = createnode(sdlz, &node); if (result != ISC_R_SUCCESS) return (result); isorigin = dns_name_equal(name, &sdlz->common.origin); /* make sure strings are always lowercase */ dns_sdlz_tolower(zonestr); dns_sdlz_tolower(namestr); MAYBE_LOCK(sdlz->dlzimp); /* try to lookup the host (namestr) */ result = sdlz->dlzimp->methods->lookup(zonestr, namestr, sdlz->dlzimp->driverarg, sdlz->dbdata, node, methods, clientinfo); /* * if the host (namestr) was not found, try to lookup a * "wildcard" host. */ if (result == ISC_R_NOTFOUND && !create) result = sdlz->dlzimp->methods->lookup(zonestr, "*", sdlz->dlzimp->driverarg, sdlz->dbdata, node, methods, clientinfo); MAYBE_UNLOCK(sdlz->dlzimp); if (result == ISC_R_NOTFOUND && (isorigin || create)) result = ISC_R_SUCCESS; if (result != ISC_R_SUCCESS) { destroynode(node); return (result); } if (isorigin && sdlz->dlzimp->methods->authority != NULL) { MAYBE_LOCK(sdlz->dlzimp); authority = sdlz->dlzimp->methods->authority; result = (*authority)(zonestr, sdlz->dlzimp->driverarg, sdlz->dbdata, node); MAYBE_UNLOCK(sdlz->dlzimp); if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) { destroynode(node); return (result); } } if (node->name == NULL) { node->name = isc_mem_get(sdlz->common.mctx, sizeof(dns_name_t)); if (node->name == NULL) { destroynode(node); return (ISC_R_NOMEMORY); } dns_name_init(node->name, NULL); result = dns_name_dup(name, sdlz->common.mctx, node->name); if (result != ISC_R_SUCCESS) { isc_mem_put(sdlz->common.mctx, node->name, sizeof(dns_name_t)); destroynode(node); return (result); } } *nodep = node; return (ISC_R_SUCCESS); } static isc_result_t findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, dns_dbnode_t **nodep) { return (findnodeext(db, name, create, NULL, NULL, nodep)); } static isc_result_t findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { UNUSED(db); UNUSED(name); UNUSED(options); UNUSED(now); UNUSED(nodep); UNUSED(foundname); UNUSED(rdataset); UNUSED(sigrdataset); return (ISC_R_NOTIMPLEMENTED); } static void attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) { dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; dns_sdlznode_t *node = (dns_sdlznode_t *)source; REQUIRE(VALID_SDLZDB(sdlz)); UNUSED(sdlz); LOCK(&node->lock); INSIST(node->references > 0); node->references++; INSIST(node->references != 0); /* Catch overflow. */ UNLOCK(&node->lock); *targetp = source; } static void detachnode(dns_db_t *db, dns_dbnode_t **targetp) { dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; dns_sdlznode_t *node; isc_boolean_t need_destroy = ISC_FALSE; REQUIRE(VALID_SDLZDB(sdlz)); REQUIRE(targetp != NULL && *targetp != NULL); UNUSED(sdlz); node = (dns_sdlznode_t *)(*targetp); LOCK(&node->lock); INSIST(node->references > 0); node->references--; if (node->references == 0) need_destroy = ISC_TRUE; UNLOCK(&node->lock); if (need_destroy) destroynode(node); *targetp = NULL; } static isc_result_t expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { UNUSED(db); UNUSED(node); UNUSED(now); INSIST(0); return (ISC_R_UNEXPECTED); } static void printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) { UNUSED(db); UNUSED(node); UNUSED(out); return; } static isc_result_t createiterator(dns_db_t *db, unsigned int options, dns_dbiterator_t **iteratorp) { dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; sdlz_dbiterator_t *sdlziter; isc_result_t result; isc_buffer_t b; char zonestr[DNS_NAME_MAXTEXT + 1]; REQUIRE(VALID_SDLZDB(sdlz)); if (sdlz->dlzimp->methods->allnodes == NULL) return (ISC_R_NOTIMPLEMENTED); if ((options & DNS_DB_NSEC3ONLY) != 0 || (options & DNS_DB_NONSEC3) != 0) return (ISC_R_NOTIMPLEMENTED); isc_buffer_init(&b, zonestr, sizeof(zonestr)); result = dns_name_totext(&sdlz->common.origin, ISC_TRUE, &b); if (result != ISC_R_SUCCESS) return (result); isc_buffer_putuint8(&b, 0); sdlziter = isc_mem_get(sdlz->common.mctx, sizeof(sdlz_dbiterator_t)); if (sdlziter == NULL) return (ISC_R_NOMEMORY); sdlziter->common.methods = &dbiterator_methods; sdlziter->common.db = NULL; dns_db_attach(db, &sdlziter->common.db); sdlziter->common.relative_names = ISC_TF(options & DNS_DB_RELATIVENAMES); sdlziter->common.magic = DNS_DBITERATOR_MAGIC; ISC_LIST_INIT(sdlziter->nodelist); sdlziter->current = NULL; sdlziter->origin = NULL; /* make sure strings are always lowercase */ dns_sdlz_tolower(zonestr); MAYBE_LOCK(sdlz->dlzimp); result = sdlz->dlzimp->methods->allnodes(zonestr, sdlz->dlzimp->driverarg, sdlz->dbdata, sdlziter); MAYBE_UNLOCK(sdlz->dlzimp); if (result != ISC_R_SUCCESS) { dns_dbiterator_t *iter = &sdlziter->common; dbiterator_destroy(&iter); return (result); } if (sdlziter->origin != NULL) { ISC_LIST_UNLINK(sdlziter->nodelist, sdlziter->origin, link); ISC_LIST_PREPEND(sdlziter->nodelist, sdlziter->origin, link); } *iteratorp = (dns_dbiterator_t *)sdlziter; return (ISC_R_SUCCESS); } static isc_result_t findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdatatype_t type, dns_rdatatype_t covers, isc_stdtime_t now, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { dns_rdatalist_t *list; dns_sdlznode_t *sdlznode = (dns_sdlznode_t *)node; REQUIRE(VALID_SDLZNODE(node)); UNUSED(db); UNUSED(version); UNUSED(covers); UNUSED(now); UNUSED(sigrdataset); if (type == dns_rdatatype_sig || type == dns_rdatatype_rrsig) return (ISC_R_NOTIMPLEMENTED); list = ISC_LIST_HEAD(sdlznode->lists); while (list != NULL) { if (list->type == type) break; list = ISC_LIST_NEXT(list, link); } if (list == NULL) return (ISC_R_NOTFOUND); list_tordataset(list, db, node, rdataset); return (ISC_R_SUCCESS); } static isc_result_t findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; dns_dbnode_t *node = NULL; dns_fixedname_t fname; dns_rdataset_t xrdataset; dns_name_t *xname; unsigned int nlabels, olabels; isc_result_t result; unsigned int i; REQUIRE(VALID_SDLZDB(sdlz)); REQUIRE(nodep == NULL || *nodep == NULL); REQUIRE(version == NULL || version == (void*)&sdlz->dummy_version); UNUSED(options); UNUSED(sdlz); if (!dns_name_issubdomain(name, &db->origin)) return (DNS_R_NXDOMAIN); olabels = dns_name_countlabels(&db->origin); nlabels = dns_name_countlabels(name); dns_fixedname_init(&fname); xname = dns_fixedname_name(&fname); if (rdataset == NULL) { dns_rdataset_init(&xrdataset); rdataset = &xrdataset; } result = DNS_R_NXDOMAIN; for (i = olabels; i <= nlabels; i++) { /* * Look up the next label. */ dns_name_getlabelsequence(name, nlabels - i, i, xname); result = findnodeext(db, xname, ISC_FALSE, methods, clientinfo, &node); if (result == ISC_R_NOTFOUND) { result = DNS_R_NXDOMAIN; continue; } else if (result != ISC_R_SUCCESS) break; /* * Look for a DNAME at the current label, unless this is * the qname. */ if (i < nlabels) { result = findrdataset(db, node, version, dns_rdatatype_dname, 0, now, rdataset, sigrdataset); if (result == ISC_R_SUCCESS) { result = DNS_R_DNAME; break; } } /* * Look for an NS at the current label, unless this is the * origin or glue is ok. */ if (i != olabels && (options & DNS_DBFIND_GLUEOK) == 0) { result = findrdataset(db, node, version, dns_rdatatype_ns, 0, now, rdataset, sigrdataset); if (result == ISC_R_SUCCESS) { if (i == nlabels && type == dns_rdatatype_any) { result = DNS_R_ZONECUT; dns_rdataset_disassociate(rdataset); if (sigrdataset != NULL && dns_rdataset_isassociated (sigrdataset)) { dns_rdataset_disassociate (sigrdataset); } } else result = DNS_R_DELEGATION; break; } } /* * If the current name is not the qname, add another label * and try again. */ if (i < nlabels) { destroynode(node); node = NULL; continue; } /* * If we're looking for ANY, we're done. */ if (type == dns_rdatatype_any) { result = ISC_R_SUCCESS; break; } /* * Look for the qtype. */ result = findrdataset(db, node, version, type, 0, now, rdataset, sigrdataset); if (result == ISC_R_SUCCESS) break; /* * Look for a CNAME */ if (type != dns_rdatatype_cname) { result = findrdataset(db, node, version, dns_rdatatype_cname, 0, now, rdataset, sigrdataset); if (result == ISC_R_SUCCESS) { result = DNS_R_CNAME; break; } } result = DNS_R_NXRRSET; break; } if (rdataset == &xrdataset && dns_rdataset_isassociated(rdataset)) dns_rdataset_disassociate(rdataset); if (foundname != NULL) { isc_result_t xresult; xresult = dns_name_copy(xname, foundname, NULL); if (xresult != ISC_R_SUCCESS) { if (node != NULL) destroynode(node); if (dns_rdataset_isassociated(rdataset)) dns_rdataset_disassociate(rdataset); return (DNS_R_BADDB); } } if (nodep != NULL) *nodep = node; else if (node != NULL) detachnode(db, &node); return (result); } static isc_result_t find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { return (findext(db, name, version, type, options, now, nodep, foundname, NULL, NULL, rdataset, sigrdataset)); } static isc_result_t allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_stdtime_t now, dns_rdatasetiter_t **iteratorp) { dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *) db; sdlz_rdatasetiter_t *iterator; REQUIRE(VALID_SDLZDB(sdlz)); REQUIRE(version == NULL || version == (void*)&sdlz->dummy_version || version == sdlz->future_version); UNUSED(version); UNUSED(now); iterator = isc_mem_get(db->mctx, sizeof(sdlz_rdatasetiter_t)); if (iterator == NULL) return (ISC_R_NOMEMORY); iterator->common.magic = DNS_RDATASETITER_MAGIC; iterator->common.methods = &rdatasetiter_methods; iterator->common.db = db; iterator->common.node = NULL; attachnode(db, node, &iterator->common.node); iterator->common.version = version; iterator->common.now = now; *iteratorp = (dns_rdatasetiter_t *)iterator; return (ISC_R_SUCCESS); } static isc_result_t modrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdataset_t *rdataset, unsigned int options, dns_sdlzmodrdataset_t mod_function) { dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; dns_master_style_t *style = NULL; isc_result_t result; isc_buffer_t *buffer = NULL; isc_mem_t *mctx; dns_sdlznode_t *sdlznode; char *rdatastr = NULL; char name[DNS_NAME_MAXTEXT + 1]; REQUIRE(VALID_SDLZDB(sdlz)); if (mod_function == NULL) return (ISC_R_NOTIMPLEMENTED); sdlznode = (dns_sdlznode_t *)node; UNUSED(options); dns_name_format(sdlznode->name, name, sizeof(name)); mctx = sdlz->common.mctx; result = isc_buffer_allocate(mctx, &buffer, 1024); if (result != ISC_R_SUCCESS) return (result); result = dns_master_stylecreate(&style, 0, 0, 0, 0, 0, 0, 1, mctx); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_master_rdatasettotext(sdlznode->name, rdataset, style, buffer); if (result != ISC_R_SUCCESS) goto cleanup; if (isc_buffer_usedlength(buffer) < 1) { result = ISC_R_BADADDRESSFORM; goto cleanup; } rdatastr = isc_buffer_base(buffer); if (rdatastr == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } rdatastr[isc_buffer_usedlength(buffer) - 1] = 0; MAYBE_LOCK(sdlz->dlzimp); result = mod_function(name, rdatastr, sdlz->dlzimp->driverarg, sdlz->dbdata, version); MAYBE_UNLOCK(sdlz->dlzimp); cleanup: isc_buffer_free(&buffer); if (style != NULL) dns_master_styledestroy(&style, mctx); return (result); } static isc_result_t addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options, dns_rdataset_t *addedrdataset) { dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; isc_result_t result; UNUSED(now); UNUSED(addedrdataset); REQUIRE(VALID_SDLZDB(sdlz)); if (sdlz->dlzimp->methods->addrdataset == NULL) return (ISC_R_NOTIMPLEMENTED); result = modrdataset(db, node, version, rdataset, options, sdlz->dlzimp->methods->addrdataset); return (result); } static isc_result_t subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdataset_t *rdataset, unsigned int options, dns_rdataset_t *newrdataset) { dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; isc_result_t result; UNUSED(newrdataset); REQUIRE(VALID_SDLZDB(sdlz)); if (sdlz->dlzimp->methods->subtractrdataset == NULL) { return (ISC_R_NOTIMPLEMENTED); } result = modrdataset(db, node, version, rdataset, options, sdlz->dlzimp->methods->subtractrdataset); return (result); } static isc_result_t deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdatatype_t type, dns_rdatatype_t covers) { dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; char name[DNS_NAME_MAXTEXT + 1]; char b_type[DNS_RDATATYPE_FORMATSIZE]; dns_sdlznode_t *sdlznode; isc_result_t result; UNUSED(covers); REQUIRE(VALID_SDLZDB(sdlz)); if (sdlz->dlzimp->methods->delrdataset == NULL) return (ISC_R_NOTIMPLEMENTED); sdlznode = (dns_sdlznode_t *)node; dns_name_format(sdlznode->name, name, sizeof(name)); dns_rdatatype_format(type, b_type, sizeof(b_type)); MAYBE_LOCK(sdlz->dlzimp); result = sdlz->dlzimp->methods->delrdataset(name, b_type, sdlz->dlzimp->driverarg, sdlz->dbdata, version); MAYBE_UNLOCK(sdlz->dlzimp); return (result); } static isc_boolean_t issecure(dns_db_t *db) { UNUSED(db); return (ISC_FALSE); } static unsigned int nodecount(dns_db_t *db) { UNUSED(db); return (0); } static isc_boolean_t ispersistent(dns_db_t *db) { UNUSED(db); return (ISC_TRUE); } static void overmem(dns_db_t *db, isc_boolean_t over) { UNUSED(db); UNUSED(over); } static void settask(dns_db_t *db, isc_task_t *task) { UNUSED(db); UNUSED(task); } /* * getoriginnode() is used by the update code to find the * dns_rdatatype_dnskey record for a zone */ static isc_result_t getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) { dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; isc_result_t result; REQUIRE(VALID_SDLZDB(sdlz)); if (sdlz->dlzimp->methods->newversion == NULL) return (ISC_R_NOTIMPLEMENTED); result = findnodeext(db, &sdlz->common.origin, ISC_FALSE, NULL, NULL, nodep); if (result != ISC_R_SUCCESS) sdlz_log(ISC_LOG_ERROR, "sdlz getoriginnode failed: %s", isc_result_totext(result)); return (result); } static dns_dbmethods_t sdlzdb_methods = { attach, detach, beginload, endload, NULL, dump, currentversion, newversion, attachversion, closeversion, findnode, find, findzonecut, attachnode, detachnode, expirenode, printnode, createiterator, findrdataset, allrdatasets, addrdataset, subtractrdataset, deleterdataset, issecure, nodecount, ispersistent, overmem, settask, getoriginnode, NULL, /* transfernode */ NULL, /* getnsec3parameters */ NULL, /* findnsec3node */ NULL, /* setsigningtime */ NULL, /* getsigningtime */ NULL, /* resigned */ NULL, /* isdnssec */ NULL, /* getrrsetstats */ NULL, /* rpz_attach */ NULL, /* rpz_ready */ findnodeext, findext, NULL, /* setcachestats */ NULL /* hashsize */ }; /* * Database Iterator Methods. These methods were "borrowed" from the SDB * driver interface. See the SDB driver interface documentation for more info. */ static void dbiterator_destroy(dns_dbiterator_t **iteratorp) { sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)(*iteratorp); dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)sdlziter->common.db; while (!ISC_LIST_EMPTY(sdlziter->nodelist)) { dns_sdlznode_t *node; node = ISC_LIST_HEAD(sdlziter->nodelist); ISC_LIST_UNLINK(sdlziter->nodelist, node, link); destroynode(node); } dns_db_detach(&sdlziter->common.db); isc_mem_put(sdlz->common.mctx, sdlziter, sizeof(sdlz_dbiterator_t)); *iteratorp = NULL; } static isc_result_t dbiterator_first(dns_dbiterator_t *iterator) { sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator; sdlziter->current = ISC_LIST_HEAD(sdlziter->nodelist); if (sdlziter->current == NULL) return (ISC_R_NOMORE); else return (ISC_R_SUCCESS); } static isc_result_t dbiterator_last(dns_dbiterator_t *iterator) { sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator; sdlziter->current = ISC_LIST_TAIL(sdlziter->nodelist); if (sdlziter->current == NULL) return (ISC_R_NOMORE); else return (ISC_R_SUCCESS); } static isc_result_t dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) { sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator; sdlziter->current = ISC_LIST_HEAD(sdlziter->nodelist); while (sdlziter->current != NULL) { if (dns_name_equal(sdlziter->current->name, name)) return (ISC_R_SUCCESS); sdlziter->current = ISC_LIST_NEXT(sdlziter->current, link); } return (ISC_R_NOTFOUND); } static isc_result_t dbiterator_prev(dns_dbiterator_t *iterator) { sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator; sdlziter->current = ISC_LIST_PREV(sdlziter->current, link); if (sdlziter->current == NULL) return (ISC_R_NOMORE); else return (ISC_R_SUCCESS); } static isc_result_t dbiterator_next(dns_dbiterator_t *iterator) { sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator; sdlziter->current = ISC_LIST_NEXT(sdlziter->current, link); if (sdlziter->current == NULL) return (ISC_R_NOMORE); else return (ISC_R_SUCCESS); } static isc_result_t dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep, dns_name_t *name) { sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator; attachnode(iterator->db, sdlziter->current, nodep); if (name != NULL) return (dns_name_copy(sdlziter->current->name, name, NULL)); return (ISC_R_SUCCESS); } static isc_result_t dbiterator_pause(dns_dbiterator_t *iterator) { UNUSED(iterator); return (ISC_R_SUCCESS); } static isc_result_t dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) { UNUSED(iterator); return (dns_name_copy(dns_rootname, name, NULL)); } /* * Rdataset Methods. These methods were "borrowed" from the SDB driver * interface. See the SDB driver interface documentation for more info. */ static void disassociate(dns_rdataset_t *rdataset) { dns_dbnode_t *node = rdataset->private5; dns_sdlznode_t *sdlznode = (dns_sdlznode_t *) node; dns_db_t *db = (dns_db_t *) sdlznode->sdlz; detachnode(db, &node); isc__rdatalist_disassociate(rdataset); } static void rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { dns_dbnode_t *node = source->private5; dns_sdlznode_t *sdlznode = (dns_sdlznode_t *) node; dns_db_t *db = (dns_db_t *) sdlznode->sdlz; dns_dbnode_t *tempdb = NULL; isc__rdatalist_clone(source, target); attachnode(db, node, &tempdb); source->private5 = tempdb; } static dns_rdatasetmethods_t rdataset_methods = { disassociate, isc__rdatalist_first, isc__rdatalist_next, isc__rdatalist_current, rdataset_clone, isc__rdatalist_count, isc__rdatalist_addnoqname, isc__rdatalist_getnoqname, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static void list_tordataset(dns_rdatalist_t *rdatalist, dns_db_t *db, dns_dbnode_t *node, dns_rdataset_t *rdataset) { /* * The sdlz rdataset is an rdatalist with some additions. * - private1 & private2 are used by the rdatalist. * - private3 & private 4 are unused. * - private5 is the node. */ /* This should never fail. */ RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) == ISC_R_SUCCESS); rdataset->methods = &rdataset_methods; dns_db_attachnode(db, node, &rdataset->private5); } /* * SDLZ core methods. This is the core of the new DLZ functionality. */ /*% * Build a 'bind' database driver structure to be returned by * either the find zone or the allow zone transfer method. * This method is only available in this source file, it is * not made available anywhere else. */ static isc_result_t dns_sdlzcreateDBP(isc_mem_t *mctx, void *driverarg, void *dbdata, dns_name_t *name, dns_rdataclass_t rdclass, dns_db_t **dbp) { isc_result_t result; dns_sdlz_db_t *sdlzdb; dns_sdlzimplementation_t *imp; /* check that things are as we expect */ REQUIRE(dbp != NULL && *dbp == NULL); REQUIRE(name != NULL); imp = (dns_sdlzimplementation_t *) driverarg; /* allocate and zero memory for driver structure */ sdlzdb = isc_mem_get(mctx, sizeof(dns_sdlz_db_t)); if (sdlzdb == NULL) return (ISC_R_NOMEMORY); memset(sdlzdb, 0, sizeof(dns_sdlz_db_t)); /* initialize and set origin */ dns_name_init(&sdlzdb->common.origin, NULL); result = dns_name_dupwithoffsets(name, mctx, &sdlzdb->common.origin); if (result != ISC_R_SUCCESS) goto mem_cleanup; /* initialize the reference count mutex */ result = isc_mutex_init(&sdlzdb->refcnt_lock); if (result != ISC_R_SUCCESS) goto name_cleanup; /* set the rest of the database structure attributes */ sdlzdb->dlzimp = imp; sdlzdb->common.methods = &sdlzdb_methods; sdlzdb->common.attributes = 0; sdlzdb->common.rdclass = rdclass; sdlzdb->common.mctx = NULL; sdlzdb->dbdata = dbdata; sdlzdb->references = 1; /* attach to the memory context */ isc_mem_attach(mctx, &sdlzdb->common.mctx); /* mark structure as valid */ sdlzdb->common.magic = DNS_DB_MAGIC; sdlzdb->common.impmagic = SDLZDB_MAGIC; *dbp = (dns_db_t *) sdlzdb; return (result); /* * reference count mutex could not be initialized, clean up * name memory */ name_cleanup: dns_name_free(&sdlzdb->common.origin, mctx); mem_cleanup: isc_mem_put(mctx, sdlzdb, sizeof(dns_sdlz_db_t)); return (result); } static isc_result_t dns_sdlzallowzonexfr(void *driverarg, void *dbdata, isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_name_t *name, isc_sockaddr_t *clientaddr, dns_db_t **dbp) { isc_buffer_t b; isc_buffer_t b2; char namestr[DNS_NAME_MAXTEXT + 1]; char clientstr[(sizeof "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255") + 1]; isc_netaddr_t netaddr; isc_result_t result; dns_sdlzimplementation_t *imp; /* * Perform checks to make sure data is as we expect it to be. */ REQUIRE(driverarg != NULL); REQUIRE(name != NULL); REQUIRE(clientaddr != NULL); REQUIRE(dbp != NULL && *dbp == NULL); imp = (dns_sdlzimplementation_t *) driverarg; /* Convert DNS name to ascii text */ isc_buffer_init(&b, namestr, sizeof(namestr)); result = dns_name_totext(name, ISC_TRUE, &b); if (result != ISC_R_SUCCESS) return (result); isc_buffer_putuint8(&b, 0); /* convert client address to ascii text */ isc_buffer_init(&b2, clientstr, sizeof(clientstr)); isc_netaddr_fromsockaddr(&netaddr, clientaddr); result = isc_netaddr_totext(&netaddr, &b2); if (result != ISC_R_SUCCESS) return (result); isc_buffer_putuint8(&b2, 0); /* make sure strings are always lowercase */ dns_sdlz_tolower(namestr); dns_sdlz_tolower(clientstr); /* Call SDLZ driver's find zone method */ if (imp->methods->allowzonexfr != NULL) { MAYBE_LOCK(imp); result = imp->methods->allowzonexfr(imp->driverarg, dbdata, namestr, clientstr); MAYBE_UNLOCK(imp); /* * if zone is supported and transfers allowed build a 'bind' * database driver */ if (result == ISC_R_SUCCESS) result = dns_sdlzcreateDBP(mctx, driverarg, dbdata, name, rdclass, dbp); return (result); } return (ISC_R_NOTIMPLEMENTED); } static isc_result_t dns_sdlzcreate(isc_mem_t *mctx, const char *dlzname, unsigned int argc, char *argv[], void *driverarg, void **dbdata) { dns_sdlzimplementation_t *imp; isc_result_t result = ISC_R_NOTFOUND; /* Write debugging message to log */ sdlz_log(ISC_LOG_DEBUG(2), "Loading SDLZ driver."); /* * Performs checks to make sure data is as we expect it to be. */ REQUIRE(driverarg != NULL); REQUIRE(dlzname != NULL); REQUIRE(dbdata != NULL); UNUSED(mctx); imp = driverarg; /* If the create method exists, call it. */ if (imp->methods->create != NULL) { MAYBE_LOCK(imp); result = imp->methods->create(dlzname, argc, argv, imp->driverarg, dbdata); MAYBE_UNLOCK(imp); } /* Write debugging message to log */ if (result == ISC_R_SUCCESS) { sdlz_log(ISC_LOG_DEBUG(2), "SDLZ driver loaded successfully."); } else { sdlz_log(ISC_LOG_ERROR, "SDLZ driver failed to load."); } return (result); } static void dns_sdlzdestroy(void *driverdata, void **dbdata) { dns_sdlzimplementation_t *imp; /* Write debugging message to log */ sdlz_log(ISC_LOG_DEBUG(2), "Unloading SDLZ driver."); imp = driverdata; /* If the destroy method exists, call it. */ if (imp->methods->destroy != NULL) { MAYBE_LOCK(imp); imp->methods->destroy(imp->driverarg, dbdata); MAYBE_UNLOCK(imp); } } static isc_result_t dns_sdlzfindzone(void *driverarg, void *dbdata, isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_name_t *name, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, dns_db_t **dbp) { isc_buffer_t b; char namestr[DNS_NAME_MAXTEXT + 1]; isc_result_t result; dns_sdlzimplementation_t *imp; /* * Perform checks to make sure data is as we expect it to be. */ REQUIRE(driverarg != NULL); REQUIRE(name != NULL); REQUIRE(dbp != NULL && *dbp == NULL); imp = (dns_sdlzimplementation_t *) driverarg; /* Convert DNS name to ascii text */ isc_buffer_init(&b, namestr, sizeof(namestr)); result = dns_name_totext(name, ISC_TRUE, &b); if (result != ISC_R_SUCCESS) return (result); isc_buffer_putuint8(&b, 0); /* make sure strings are always lowercase */ dns_sdlz_tolower(namestr); /* Call SDLZ driver's find zone method */ MAYBE_LOCK(imp); result = imp->methods->findzone(imp->driverarg, dbdata, namestr, methods, clientinfo); MAYBE_UNLOCK(imp); /* * if zone is supported build a 'bind' database driver * structure to return */ if (result == ISC_R_SUCCESS) result = dns_sdlzcreateDBP(mctx, driverarg, dbdata, name, rdclass, dbp); return (result); } static isc_result_t dns_sdlzconfigure(void *driverarg, void *dbdata, dns_view_t *view, dns_dlzdb_t *dlzdb) { isc_result_t result; dns_sdlzimplementation_t *imp; REQUIRE(driverarg != NULL); imp = (dns_sdlzimplementation_t *) driverarg; /* Call SDLZ driver's configure method */ if (imp->methods->configure != NULL) { MAYBE_LOCK(imp); result = imp->methods->configure(view, dlzdb, imp->driverarg, dbdata); MAYBE_UNLOCK(imp); } else { result = ISC_R_SUCCESS; } return (result); } static isc_boolean_t dns_sdlzssumatch(dns_name_t *signer, dns_name_t *name, isc_netaddr_t *tcpaddr, dns_rdatatype_t type, const dst_key_t *key, void *driverarg, void *dbdata) { dns_sdlzimplementation_t *imp; char b_signer[DNS_NAME_FORMATSIZE]; char b_name[DNS_NAME_FORMATSIZE]; char b_addr[ISC_NETADDR_FORMATSIZE]; char b_type[DNS_RDATATYPE_FORMATSIZE]; char b_key[DST_KEY_FORMATSIZE]; isc_buffer_t *tkey_token = NULL; isc_region_t token_region; isc_uint32_t token_len = 0; isc_boolean_t ret; REQUIRE(driverarg != NULL); imp = (dns_sdlzimplementation_t *) driverarg; if (imp->methods->ssumatch == NULL) return (ISC_FALSE); /* * Format the request elements. sdlz operates on strings, not * structures */ if (signer != NULL) dns_name_format(signer, b_signer, sizeof(b_signer)); else b_signer[0] = 0; dns_name_format(name, b_name, sizeof(b_name)); if (tcpaddr != NULL) isc_netaddr_format(tcpaddr, b_addr, sizeof(b_addr)); else b_addr[0] = 0; dns_rdatatype_format(type, b_type, sizeof(b_type)); if (key != NULL) { dst_key_format(key, b_key, sizeof(b_key)); tkey_token = dst_key_tkeytoken(key); } else b_key[0] = 0; if (tkey_token != NULL) { isc_buffer_region(tkey_token, &token_region); token_len = token_region.length; } MAYBE_LOCK(imp); ret = imp->methods->ssumatch(b_signer, b_name, b_addr, b_type, b_key, token_len, token_len != 0 ? token_region.base : NULL, imp->driverarg, dbdata); MAYBE_UNLOCK(imp); return (ret); } static dns_dlzmethods_t sdlzmethods = { dns_sdlzcreate, dns_sdlzdestroy, dns_sdlzfindzone, dns_sdlzallowzonexfr, dns_sdlzconfigure, dns_sdlzssumatch }; /* * Public functions. */ isc_result_t dns_sdlz_putrr(dns_sdlzlookup_t *lookup, const char *type, dns_ttl_t ttl, const char *data) { dns_rdatalist_t *rdatalist; dns_rdata_t *rdata; dns_rdatatype_t typeval; isc_consttextregion_t r; isc_buffer_t b; isc_buffer_t *rdatabuf = NULL; isc_lex_t *lex; isc_result_t result; unsigned int size; isc_mem_t *mctx; dns_name_t *origin; REQUIRE(VALID_SDLZLOOKUP(lookup)); REQUIRE(type != NULL); REQUIRE(data != NULL); mctx = lookup->sdlz->common.mctx; r.base = type; r.length = strlen(type); result = dns_rdatatype_fromtext(&typeval, (void *) &r); if (result != ISC_R_SUCCESS) return (result); rdatalist = ISC_LIST_HEAD(lookup->lists); while (rdatalist != NULL) { if (rdatalist->type == typeval) break; rdatalist = ISC_LIST_NEXT(rdatalist, link); } if (rdatalist == NULL) { rdatalist = isc_mem_get(mctx, sizeof(dns_rdatalist_t)); if (rdatalist == NULL) return (ISC_R_NOMEMORY); dns_rdatalist_init(rdatalist); rdatalist->rdclass = lookup->sdlz->common.rdclass; rdatalist->type = typeval; rdatalist->ttl = ttl; ISC_LIST_APPEND(lookup->lists, rdatalist, link); } else if (rdatalist->ttl > ttl) { /* * BIND9 doesn't enforce all RRs in an RRset * having the same TTL, as per RFC 2136, * section 7.12. If a DLZ backend has * different TTLs, then the best * we can do is return the lowest. */ rdatalist->ttl = ttl; } rdata = isc_mem_get(mctx, sizeof(dns_rdata_t)); if (rdata == NULL) return (ISC_R_NOMEMORY); dns_rdata_init(rdata); if ((lookup->sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVERDATA) != 0) origin = &lookup->sdlz->common.origin; else origin = dns_rootname; lex = NULL; result = isc_lex_create(mctx, 64, &lex); if (result != ISC_R_SUCCESS) goto failure; size = initial_size(data); do { isc_buffer_constinit(&b, data, strlen(data)); isc_buffer_add(&b, strlen(data)); result = isc_lex_openbuffer(lex, &b); if (result != ISC_R_SUCCESS) goto failure; rdatabuf = NULL; result = isc_buffer_allocate(mctx, &rdatabuf, size); if (result != ISC_R_SUCCESS) goto failure; result = dns_rdata_fromtext(rdata, rdatalist->rdclass, rdatalist->type, lex, origin, ISC_FALSE, mctx, rdatabuf, &lookup->callbacks); if (result != ISC_R_SUCCESS) isc_buffer_free(&rdatabuf); if (size >= 65535) break; size *= 2; if (size >= 65535) size = 65535; } while (result == ISC_R_NOSPACE); if (result != ISC_R_SUCCESS) goto failure; ISC_LIST_APPEND(rdatalist->rdata, rdata, link); ISC_LIST_APPEND(lookup->buffers, rdatabuf, link); if (lex != NULL) isc_lex_destroy(&lex); return (ISC_R_SUCCESS); failure: if (rdatabuf != NULL) isc_buffer_free(&rdatabuf); if (lex != NULL) isc_lex_destroy(&lex); isc_mem_put(mctx, rdata, sizeof(dns_rdata_t)); return (result); } isc_result_t dns_sdlz_putnamedrr(dns_sdlzallnodes_t *allnodes, const char *name, const char *type, dns_ttl_t ttl, const char *data) { dns_name_t *newname, *origin; dns_fixedname_t fnewname; dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)allnodes->common.db; dns_sdlznode_t *sdlznode; isc_mem_t *mctx = sdlz->common.mctx; isc_buffer_t b; isc_result_t result; dns_fixedname_init(&fnewname); newname = dns_fixedname_name(&fnewname); if ((sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVERDATA) != 0) origin = &sdlz->common.origin; else origin = dns_rootname; isc_buffer_constinit(&b, name, strlen(name)); isc_buffer_add(&b, strlen(name)); result = dns_name_fromtext(newname, &b, origin, 0, NULL); if (result != ISC_R_SUCCESS) return (result); if (allnodes->common.relative_names) { /* All names are relative to the root */ unsigned int nlabels = dns_name_countlabels(newname); dns_name_getlabelsequence(newname, 0, nlabels - 1, newname); } sdlznode = ISC_LIST_HEAD(allnodes->nodelist); if (sdlznode == NULL || !dns_name_equal(sdlznode->name, newname)) { sdlznode = NULL; result = createnode(sdlz, &sdlznode); if (result != ISC_R_SUCCESS) return (result); sdlznode->name = isc_mem_get(mctx, sizeof(dns_name_t)); if (sdlznode->name == NULL) { destroynode(sdlznode); return (ISC_R_NOMEMORY); } dns_name_init(sdlznode->name, NULL); result = dns_name_dup(newname, mctx, sdlznode->name); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, sdlznode->name, sizeof(dns_name_t)); destroynode(sdlznode); return (result); } ISC_LIST_PREPEND(allnodes->nodelist, sdlznode, link); if (allnodes->origin == NULL && dns_name_equal(newname, &sdlz->common.origin)) allnodes->origin = sdlznode; } return (dns_sdlz_putrr(sdlznode, type, ttl, data)); } isc_result_t dns_sdlz_putsoa(dns_sdlzlookup_t *lookup, const char *mname, const char *rname, isc_uint32_t serial) { char str[2 * DNS_NAME_MAXTEXT + 5 * (sizeof("2147483647")) + 7]; int n; REQUIRE(mname != NULL); REQUIRE(rname != NULL); n = snprintf(str, sizeof str, "%s %s %u %u %u %u %u", mname, rname, serial, SDLZ_DEFAULT_REFRESH, SDLZ_DEFAULT_RETRY, SDLZ_DEFAULT_EXPIRE, SDLZ_DEFAULT_MINIMUM); if (n >= (int)sizeof(str) || n < 0) return (ISC_R_NOSPACE); return (dns_sdlz_putrr(lookup, "SOA", SDLZ_DEFAULT_TTL, str)); } isc_result_t dns_sdlzregister(const char *drivername, const dns_sdlzmethods_t *methods, void *driverarg, unsigned int flags, isc_mem_t *mctx, dns_sdlzimplementation_t **sdlzimp) { dns_sdlzimplementation_t *imp; isc_result_t result; /* * Performs checks to make sure data is as we expect it to be. */ REQUIRE(drivername != NULL); REQUIRE(methods != NULL); REQUIRE(methods->findzone != NULL); REQUIRE(methods->lookup != NULL); REQUIRE(mctx != NULL); REQUIRE(sdlzimp != NULL && *sdlzimp == NULL); REQUIRE((flags & ~(DNS_SDLZFLAG_RELATIVEOWNER | DNS_SDLZFLAG_RELATIVERDATA | DNS_SDLZFLAG_THREADSAFE)) == 0); /* Write debugging message to log */ sdlz_log(ISC_LOG_DEBUG(2), "Registering SDLZ driver '%s'", drivername); /* * Allocate memory for a sdlz_implementation object. Error if * we cannot. */ imp = isc_mem_get(mctx, sizeof(dns_sdlzimplementation_t)); if (imp == NULL) return (ISC_R_NOMEMORY); /* Make sure memory region is set to all 0's */ memset(imp, 0, sizeof(dns_sdlzimplementation_t)); /* Store the data passed into this method */ imp->methods = methods; imp->driverarg = driverarg; imp->flags = flags; imp->mctx = NULL; /* attach the new sdlz_implementation object to a memory context */ isc_mem_attach(mctx, &imp->mctx); /* * initialize the driver lock, error if we cannot * (used if a driver does not support multiple threads) */ result = isc_mutex_init(&imp->driverlock); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_mutex_init() failed: %s", isc_result_totext(result)); goto cleanup_mctx; } imp->dlz_imp = NULL; /* * register the DLZ driver. Pass in our "extra" sdlz information as * a driverarg. (that's why we stored the passed in driver arg in our * sdlz_implementation structure) Also, store the dlz_implementation * structure in our sdlz_implementation. */ result = dns_dlzregister(drivername, &sdlzmethods, imp, mctx, &imp->dlz_imp); /* if registration fails, cleanup and get outta here. */ if (result != ISC_R_SUCCESS) goto cleanup_mutex; *sdlzimp = imp; return (ISC_R_SUCCESS); cleanup_mutex: /* destroy the driver lock, we don't need it anymore */ DESTROYLOCK(&imp->driverlock); cleanup_mctx: /* * return the memory back to the available memory pool and * remove it from the memory context. */ isc_mem_put(mctx, imp, sizeof(dns_sdlzimplementation_t)); isc_mem_detach(&mctx); return (result); } void dns_sdlzunregister(dns_sdlzimplementation_t **sdlzimp) { dns_sdlzimplementation_t *imp; isc_mem_t *mctx; /* Write debugging message to log */ sdlz_log(ISC_LOG_DEBUG(2), "Unregistering SDLZ driver."); /* * Performs checks to make sure data is as we expect it to be. */ REQUIRE(sdlzimp != NULL && *sdlzimp != NULL); imp = *sdlzimp; /* Unregister the DLZ driver implementation */ dns_dlzunregister(&imp->dlz_imp); /* destroy the driver lock, we don't need it anymore */ DESTROYLOCK(&imp->driverlock); mctx = imp->mctx; /* * return the memory back to the available memory pool and * remove it from the memory context. */ isc_mem_put(mctx, imp, sizeof(dns_sdlzimplementation_t)); isc_mem_detach(&mctx); *sdlzimp = NULL; } isc_result_t dns_sdlz_setdb(dns_dlzdb_t *dlzdatabase, dns_rdataclass_t rdclass, dns_name_t *name, dns_db_t **dbp) { isc_result_t result; result = dns_sdlzcreateDBP(dlzdatabase->mctx, dlzdatabase->implementation->driverarg, dlzdatabase->dbdata, name, rdclass, dbp); return (result); } bind9-9.10.3.dfsg.P4/lib/dns/client.c0000644000470500017500000023326112664710322016354 0ustar lamontlamont/* * Copyright (C) 2009-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define DNS_CLIENT_MAGIC ISC_MAGIC('D', 'N', 'S', 'c') #define DNS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, DNS_CLIENT_MAGIC) #define RCTX_MAGIC ISC_MAGIC('R', 'c', 't', 'x') #define RCTX_VALID(c) ISC_MAGIC_VALID(c, RCTX_MAGIC) #define REQCTX_MAGIC ISC_MAGIC('R', 'q', 'c', 'x') #define REQCTX_VALID(c) ISC_MAGIC_VALID(c, REQCTX_MAGIC) #define UCTX_MAGIC ISC_MAGIC('U', 'c', 't', 'x') #define UCTX_VALID(c) ISC_MAGIC_VALID(c, UCTX_MAGIC) #define MAX_RESTARTS 16 #ifdef TUNE_LARGE #define RESOLVER_NTASKS 523 #else #define RESOLVER_NTASKS 31 #endif /* TUNE_LARGE */ /*% * DNS client object */ struct dns_client { /* Unlocked */ unsigned int magic; unsigned int attributes; isc_mutex_t lock; isc_mem_t *mctx; isc_appctx_t *actx; isc_taskmgr_t *taskmgr; isc_task_t *task; isc_socketmgr_t *socketmgr; isc_timermgr_t *timermgr; dns_dispatchmgr_t *dispatchmgr; dns_dispatch_t *dispatchv4; dns_dispatch_t *dispatchv6; unsigned int update_timeout; unsigned int update_udptimeout; unsigned int update_udpretries; unsigned int find_timeout; unsigned int find_udpretries; /* Locked */ unsigned int references; dns_viewlist_t viewlist; ISC_LIST(struct resctx) resctxs; ISC_LIST(struct reqctx) reqctxs; ISC_LIST(struct updatectx) updatectxs; }; /*% * Timeout/retry constants for dynamic update borrowed from nsupdate */ #define DEF_UPDATE_TIMEOUT 300 #define MIN_UPDATE_TIMEOUT 30 #define DEF_UPDATE_UDPTIMEOUT 3 #define DEF_UPDATE_UDPRETRIES 3 #define DEF_FIND_TIMEOUT 5 #define DEF_FIND_UDPRETRIES 3 #define DNS_CLIENTATTR_OWNCTX 0x01 #define DNS_CLIENTVIEW_NAME "dnsclient" /*% * Internal state for a single name resolution procedure */ typedef struct resctx { /* Unlocked */ unsigned int magic; isc_mutex_t lock; dns_client_t *client; isc_boolean_t want_dnssec; isc_boolean_t want_validation; isc_boolean_t want_cdflag; /* Locked */ ISC_LINK(struct resctx) link; isc_task_t *task; dns_view_t *view; unsigned int restarts; dns_fixedname_t name; dns_rdatatype_t type; dns_fetch_t *fetch; dns_namelist_t namelist; isc_result_t result; dns_clientresevent_t *event; isc_boolean_t canceled; dns_rdataset_t *rdataset; dns_rdataset_t *sigrdataset; } resctx_t; /*% * Argument of an internal event for synchronous name resolution. */ typedef struct resarg { /* Unlocked */ isc_appctx_t *actx; dns_client_t *client; isc_mutex_t lock; /* Locked */ isc_result_t result; isc_result_t vresult; dns_namelist_t *namelist; dns_clientrestrans_t *trans; isc_boolean_t canceled; } resarg_t; /*% * Internal state for a single DNS request */ typedef struct reqctx { /* Unlocked */ unsigned int magic; isc_mutex_t lock; dns_client_t *client; unsigned int parseoptions; /* Locked */ ISC_LINK(struct reqctx) link; isc_boolean_t canceled; dns_tsigkey_t *tsigkey; dns_request_t *request; dns_clientreqevent_t *event; } reqctx_t; /*% * Argument of an internal event for synchronous DNS request. */ typedef struct reqarg { /* Unlocked */ isc_appctx_t *actx; dns_client_t *client; isc_mutex_t lock; /* Locked */ isc_result_t result; dns_clientreqtrans_t *trans; isc_boolean_t canceled; } reqarg_t; /*% * Argument of an internal event for synchronous name resolution. */ typedef struct updatearg { /* Unlocked */ isc_appctx_t *actx; dns_client_t *client; isc_mutex_t lock; /* Locked */ isc_result_t result; dns_clientupdatetrans_t *trans; isc_boolean_t canceled; } updatearg_t; /*% * Internal state for a single dynamic update procedure */ typedef struct updatectx { /* Unlocked */ unsigned int magic; isc_mutex_t lock; dns_client_t *client; /* Locked */ dns_request_t *updatereq; dns_request_t *soareq; dns_clientrestrans_t *restrans; dns_clientrestrans_t *restrans2; isc_boolean_t canceled; /* Task Locked */ ISC_LINK(struct updatectx) link; dns_clientupdatestate_t state; dns_rdataclass_t rdclass; dns_view_t *view; dns_message_t *updatemsg; dns_message_t *soaquery; dns_clientupdateevent_t *event; dns_tsigkey_t *tsigkey; dst_key_t *sig0key; dns_name_t *firstname; dns_name_t soaqname; dns_fixedname_t zonefname; dns_name_t *zonename; isc_sockaddrlist_t servers; unsigned int nservers; isc_sockaddr_t *currentserver; struct updatectx *bp4; struct updatectx *bp6; } updatectx_t; static isc_result_t request_soa(updatectx_t *uctx); static void client_resfind(resctx_t *rctx, dns_fetchevent_t *event); static isc_result_t send_update(updatectx_t *uctx); static isc_result_t getudpdispatch(int family, dns_dispatchmgr_t *dispatchmgr, isc_socketmgr_t *socketmgr, isc_taskmgr_t *taskmgr, isc_boolean_t is_shared, dns_dispatch_t **dispp, isc_sockaddr_t *localaddr) { unsigned int attrs, attrmask; dns_dispatch_t *disp; unsigned buffersize, maxbuffers, maxrequests, buckets, increment; isc_result_t result; isc_sockaddr_t anyaddr; attrs = 0; attrs |= DNS_DISPATCHATTR_UDP; switch (family) { case AF_INET: attrs |= DNS_DISPATCHATTR_IPV4; break; case AF_INET6: attrs |= DNS_DISPATCHATTR_IPV6; break; default: INSIST(0); } attrmask = 0; attrmask |= DNS_DISPATCHATTR_UDP; attrmask |= DNS_DISPATCHATTR_TCP; attrmask |= DNS_DISPATCHATTR_IPV4; attrmask |= DNS_DISPATCHATTR_IPV6; if (localaddr == NULL) { localaddr = &anyaddr; isc_sockaddr_anyofpf(localaddr, family); } buffersize = 4096; maxbuffers = is_shared ? 1000 : 8; maxrequests = 32768; buckets = is_shared ? 16411 : 3; increment = is_shared ? 16433 : 5; disp = NULL; result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, localaddr, buffersize, maxbuffers, maxrequests, buckets, increment, attrs, attrmask, &disp); if (result == ISC_R_SUCCESS) *dispp = disp; return (result); } static isc_result_t createview(isc_mem_t *mctx, dns_rdataclass_t rdclass, unsigned int options, isc_taskmgr_t *taskmgr, unsigned int ntasks, isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr, dns_dispatchmgr_t *dispatchmgr, dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6, dns_view_t **viewp) { isc_result_t result; dns_view_t *view = NULL; const char *dbtype; result = dns_view_create(mctx, rdclass, DNS_CLIENTVIEW_NAME, &view); if (result != ISC_R_SUCCESS) return (result); /* Initialize view security roots */ result = dns_view_initsecroots(view, mctx); if (result != ISC_R_SUCCESS) { dns_view_detach(&view); return (result); } result = dns_view_createresolver(view, taskmgr, ntasks, 1, socketmgr, timermgr, 0, dispatchmgr, dispatchv4, dispatchv6); if (result != ISC_R_SUCCESS) { dns_view_detach(&view); return (result); } /* * Set cache DB. * XXX: it may be better if specific DB implementations can be * specified via some configuration knob. */ if ((options & DNS_CLIENTCREATEOPT_USECACHE) != 0) dbtype = "rbt"; else dbtype = "ecdb"; result = dns_db_create(mctx, dbtype, dns_rootname, dns_dbtype_cache, rdclass, 0, NULL, &view->cachedb); if (result != ISC_R_SUCCESS) { dns_view_detach(&view); return (result); } *viewp = view; return (ISC_R_SUCCESS); } isc_result_t dns_client_create(dns_client_t **clientp, unsigned int options) { isc_result_t result; isc_mem_t *mctx = NULL; isc_appctx_t *actx = NULL; isc_taskmgr_t *taskmgr = NULL; isc_socketmgr_t *socketmgr = NULL; isc_timermgr_t *timermgr = NULL; #if 0 /* XXXMPA add debug logging support */ isc_log_t *lctx = NULL; isc_logconfig_t *logconfig = NULL; unsigned int logdebuglevel = 0; #endif result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) return (result); result = isc_appctx_create(mctx, &actx); if (result != ISC_R_SUCCESS) goto cleanup; result = isc_app_ctxstart(actx); if (result != ISC_R_SUCCESS) goto cleanup; result = isc_taskmgr_createinctx(mctx, actx, 1, 0, &taskmgr); if (result != ISC_R_SUCCESS) goto cleanup; result = isc_socketmgr_createinctx(mctx, actx, &socketmgr); if (result != ISC_R_SUCCESS) goto cleanup; result = isc_timermgr_createinctx(mctx, actx, &timermgr); if (result != ISC_R_SUCCESS) goto cleanup; #if 0 result = isc_log_create(mctx, &lctx, &logconfig); if (result != ISC_R_SUCCESS) goto cleanup; isc_log_setcontext(lctx); dns_log_init(lctx); dns_log_setcontext(lctx); result = isc_log_usechannel(logconfig, "default_debug", NULL, NULL); if (result != ISC_R_SUCCESS) goto cleanup; isc_log_setdebuglevel(lctx, logdebuglevel); #endif result = dns_client_createx(mctx, actx, taskmgr, socketmgr, timermgr, options, clientp); if (result != ISC_R_SUCCESS) goto cleanup; (*clientp)->attributes |= DNS_CLIENTATTR_OWNCTX; /* client has its own reference to mctx, so we can detach it here */ isc_mem_detach(&mctx); return (ISC_R_SUCCESS); cleanup: if (taskmgr != NULL) isc_taskmgr_destroy(&taskmgr); if (timermgr != NULL) isc_timermgr_destroy(&timermgr); if (socketmgr != NULL) isc_socketmgr_destroy(&socketmgr); if (actx != NULL) isc_appctx_destroy(&actx); isc_mem_detach(&mctx); return (result); } isc_result_t dns_client_createx(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr, isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr, unsigned int options, dns_client_t **clientp) { isc_result_t result; result = dns_client_createx2(mctx, actx, taskmgr, socketmgr, timermgr, options, clientp, NULL, NULL); return (result); } isc_result_t dns_client_createx2(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr, isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr, unsigned int options, dns_client_t **clientp, isc_sockaddr_t *localaddr4, isc_sockaddr_t *localaddr6) { dns_client_t *client; isc_result_t result; dns_dispatchmgr_t *dispatchmgr = NULL; dns_dispatch_t *dispatchv4 = NULL; dns_dispatch_t *dispatchv6 = NULL; dns_view_t *view = NULL; REQUIRE(mctx != NULL); REQUIRE(taskmgr != NULL); REQUIRE(timermgr != NULL); REQUIRE(socketmgr != NULL); REQUIRE(clientp != NULL && *clientp == NULL); client = isc_mem_get(mctx, sizeof(*client)); if (client == NULL) return (ISC_R_NOMEMORY); result = isc_mutex_init(&client->lock); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, client, sizeof(*client)); return (result); } client->actx = actx; client->taskmgr = taskmgr; client->socketmgr = socketmgr; client->timermgr = timermgr; client->task = NULL; result = isc_task_create(client->taskmgr, 0, &client->task); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_dispatchmgr_create(mctx, NULL, &dispatchmgr); if (result != ISC_R_SUCCESS) goto cleanup; client->dispatchmgr = dispatchmgr; /* * If only one address family is specified, use it. * If neither family is specified, or if both are, use both. */ client->dispatchv4 = NULL; if (localaddr4 != NULL || localaddr6 == NULL) { result = getudpdispatch(AF_INET, dispatchmgr, socketmgr, taskmgr, ISC_TRUE, &dispatchv4, localaddr4); if (result == ISC_R_SUCCESS) client->dispatchv4 = dispatchv4; } client->dispatchv6 = NULL; if (localaddr6 != NULL || localaddr4 == NULL) { result = getudpdispatch(AF_INET6, dispatchmgr, socketmgr, taskmgr, ISC_TRUE, &dispatchv6, localaddr6); if (result == ISC_R_SUCCESS) client->dispatchv6 = dispatchv6; } /* We need at least one of the dispatchers */ if (dispatchv4 == NULL && dispatchv6 == NULL) { INSIST(result != ISC_R_SUCCESS); goto cleanup; } /* Create the default view for class IN */ result = createview(mctx, dns_rdataclass_in, options, taskmgr, RESOLVER_NTASKS, socketmgr, timermgr, dispatchmgr, dispatchv4, dispatchv6, &view); if (result != ISC_R_SUCCESS) goto cleanup; ISC_LIST_INIT(client->viewlist); ISC_LIST_APPEND(client->viewlist, view, link); dns_view_freeze(view); /* too early? */ ISC_LIST_INIT(client->resctxs); ISC_LIST_INIT(client->reqctxs); ISC_LIST_INIT(client->updatectxs); client->mctx = NULL; isc_mem_attach(mctx, &client->mctx); client->update_timeout = DEF_UPDATE_TIMEOUT; client->update_udptimeout = DEF_UPDATE_UDPTIMEOUT; client->update_udpretries = DEF_UPDATE_UDPRETRIES; client->find_timeout = DEF_FIND_TIMEOUT; client->find_udpretries = DEF_FIND_UDPRETRIES; client->attributes = 0; client->references = 1; client->magic = DNS_CLIENT_MAGIC; *clientp = client; return (ISC_R_SUCCESS); cleanup: if (dispatchv4 != NULL) dns_dispatch_detach(&dispatchv4); if (dispatchv6 != NULL) dns_dispatch_detach(&dispatchv6); if (dispatchmgr != NULL) dns_dispatchmgr_destroy(&dispatchmgr); if (client->task != NULL) isc_task_detach(&client->task); isc_mem_put(mctx, client, sizeof(*client)); return (result); } static void destroyclient(dns_client_t **clientp) { dns_client_t *client = *clientp; dns_view_t *view; while ((view = ISC_LIST_HEAD(client->viewlist)) != NULL) { ISC_LIST_UNLINK(client->viewlist, view, link); dns_view_detach(&view); } if (client->dispatchv4 != NULL) dns_dispatch_detach(&client->dispatchv4); if (client->dispatchv6 != NULL) dns_dispatch_detach(&client->dispatchv6); dns_dispatchmgr_destroy(&client->dispatchmgr); isc_task_detach(&client->task); /* * If the client has created its own running environments, * destroy them. */ if ((client->attributes & DNS_CLIENTATTR_OWNCTX) != 0) { isc_taskmgr_destroy(&client->taskmgr); isc_timermgr_destroy(&client->timermgr); isc_socketmgr_destroy(&client->socketmgr); isc_app_ctxfinish(client->actx); isc_appctx_destroy(&client->actx); } DESTROYLOCK(&client->lock); client->magic = 0; isc_mem_putanddetach(&client->mctx, client, sizeof(*client)); *clientp = NULL; } void dns_client_destroy(dns_client_t **clientp) { dns_client_t *client; isc_boolean_t destroyok = ISC_FALSE; REQUIRE(clientp != NULL); client = *clientp; REQUIRE(DNS_CLIENT_VALID(client)); LOCK(&client->lock); client->references--; if (client->references == 0 && ISC_LIST_EMPTY(client->resctxs) && ISC_LIST_EMPTY(client->reqctxs) && ISC_LIST_EMPTY(client->updatectxs)) { destroyok = ISC_TRUE; } UNLOCK(&client->lock); if (destroyok) destroyclient(&client); *clientp = NULL; } isc_result_t dns_client_setservers(dns_client_t *client, dns_rdataclass_t rdclass, dns_name_t *namespace, isc_sockaddrlist_t *addrs) { isc_result_t result; dns_view_t *view = NULL; REQUIRE(DNS_CLIENT_VALID(client)); REQUIRE(addrs != NULL); if (namespace == NULL) namespace = dns_rootname; LOCK(&client->lock); result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME, rdclass, &view); if (result != ISC_R_SUCCESS) { UNLOCK(&client->lock); return (result); } UNLOCK(&client->lock); result = dns_fwdtable_add(view->fwdtable, namespace, addrs, dns_fwdpolicy_only); dns_view_detach(&view); return (result); } isc_result_t dns_client_clearservers(dns_client_t *client, dns_rdataclass_t rdclass, dns_name_t *namespace) { isc_result_t result; dns_view_t *view = NULL; REQUIRE(DNS_CLIENT_VALID(client)); if (namespace == NULL) namespace = dns_rootname; LOCK(&client->lock); result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME, rdclass, &view); if (result != ISC_R_SUCCESS) { UNLOCK(&client->lock); return (result); } UNLOCK(&client->lock); result = dns_fwdtable_delete(view->fwdtable, namespace); dns_view_detach(&view); return (result); } isc_result_t dns_client_setdlv(dns_client_t *client, dns_rdataclass_t rdclass, const char *dlvname) { isc_result_t result; isc_buffer_t b; dns_view_t *view = NULL; REQUIRE(DNS_CLIENT_VALID(client)); LOCK(&client->lock); result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME, rdclass, &view); UNLOCK(&client->lock); if (result != ISC_R_SUCCESS) goto cleanup; if (dlvname == NULL) view->dlv = NULL; else { dns_name_t *newdlv; isc_buffer_constinit(&b, dlvname, strlen(dlvname)); isc_buffer_add(&b, strlen(dlvname)); newdlv = dns_fixedname_name(&view->dlv_fixed); result = dns_name_fromtext(newdlv, &b, dns_rootname, DNS_NAME_DOWNCASE, NULL); if (result != ISC_R_SUCCESS) goto cleanup; view->dlv = dns_fixedname_name(&view->dlv_fixed); } cleanup: if (view != NULL) dns_view_detach(&view); return (result); } static isc_result_t getrdataset(isc_mem_t *mctx, dns_rdataset_t **rdatasetp) { dns_rdataset_t *rdataset; REQUIRE(mctx != NULL); REQUIRE(rdatasetp != NULL && *rdatasetp == NULL); rdataset = isc_mem_get(mctx, sizeof(*rdataset)); if (rdataset == NULL) return (ISC_R_NOMEMORY); dns_rdataset_init(rdataset); *rdatasetp = rdataset; return (ISC_R_SUCCESS); } static void putrdataset(isc_mem_t *mctx, dns_rdataset_t **rdatasetp) { dns_rdataset_t *rdataset; REQUIRE(rdatasetp != NULL); rdataset = *rdatasetp; REQUIRE(rdataset != NULL); if (dns_rdataset_isassociated(rdataset)) dns_rdataset_disassociate(rdataset); isc_mem_put(mctx, rdataset, sizeof(*rdataset)); *rdatasetp = NULL; } static void fetch_done(isc_task_t *task, isc_event_t *event) { resctx_t *rctx = event->ev_arg; dns_fetchevent_t *fevent; REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); REQUIRE(RCTX_VALID(rctx)); REQUIRE(rctx->task == task); fevent = (dns_fetchevent_t *)event; client_resfind(rctx, fevent); } static inline isc_result_t start_fetch(resctx_t *rctx) { isc_result_t result; int fopts = 0; /* * The caller must be holding the rctx's lock. */ REQUIRE(rctx->fetch == NULL); if (!rctx->want_cdflag) fopts |= DNS_FETCHOPT_NOCDFLAG; if (!rctx->want_validation) fopts |= DNS_FETCHOPT_NOVALIDATE; result = dns_resolver_createfetch(rctx->view->resolver, dns_fixedname_name(&rctx->name), rctx->type, NULL, NULL, NULL, fopts, rctx->task, fetch_done, rctx, rctx->rdataset, rctx->sigrdataset, &rctx->fetch); return (result); } static isc_result_t view_find(resctx_t *rctx, dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname) { isc_result_t result; dns_name_t *name = dns_fixedname_name(&rctx->name); dns_rdatatype_t type; if (rctx->type == dns_rdatatype_rrsig) type = dns_rdatatype_any; else type = rctx->type; result = dns_view_find(rctx->view, name, type, 0, 0, ISC_FALSE, dbp, nodep, foundname, rctx->rdataset, rctx->sigrdataset); return (result); } static void client_resfind(resctx_t *rctx, dns_fetchevent_t *event) { isc_mem_t *mctx; isc_result_t tresult, result = ISC_R_SUCCESS; isc_result_t vresult = ISC_R_SUCCESS; isc_boolean_t want_restart; isc_boolean_t send_event = ISC_FALSE; dns_name_t *name, *prefix; dns_fixedname_t foundname, fixed; dns_rdataset_t *trdataset; dns_rdata_t rdata = DNS_RDATA_INIT; unsigned int nlabels; int order; dns_namereln_t namereln; dns_rdata_cname_t cname; dns_rdata_dname_t dname; REQUIRE(RCTX_VALID(rctx)); LOCK(&rctx->lock); mctx = rctx->view->mctx; name = dns_fixedname_name(&rctx->name); do { dns_name_t *fname = NULL; dns_name_t *ansname = NULL; dns_db_t *db = NULL; dns_dbnode_t *node = NULL; rctx->restarts++; want_restart = ISC_FALSE; if (event == NULL && !rctx->canceled) { dns_fixedname_init(&foundname); fname = dns_fixedname_name(&foundname); INSIST(!dns_rdataset_isassociated(rctx->rdataset)); INSIST(rctx->sigrdataset == NULL || !dns_rdataset_isassociated(rctx->sigrdataset)); result = view_find(rctx, &db, &node, fname); if (result == ISC_R_NOTFOUND) { /* * We don't know anything about the name. * Launch a fetch. */ if (node != NULL) { INSIST(db != NULL); dns_db_detachnode(db, &node); } if (db != NULL) dns_db_detach(&db); result = start_fetch(rctx); if (result != ISC_R_SUCCESS) { putrdataset(mctx, &rctx->rdataset); if (rctx->sigrdataset != NULL) putrdataset(mctx, &rctx->sigrdataset); send_event = ISC_TRUE; } goto done; } } else { INSIST(event != NULL); INSIST(event->fetch == rctx->fetch); dns_resolver_destroyfetch(&rctx->fetch); db = event->db; node = event->node; result = event->result; vresult = event->vresult; fname = dns_fixedname_name(&event->foundname); INSIST(event->rdataset == rctx->rdataset); INSIST(event->sigrdataset == rctx->sigrdataset); } /* * If we've been canceled, forget about the result. */ if (rctx->canceled) result = ISC_R_CANCELED; else { /* * Otherwise, get some resource for copying the * result. */ ansname = isc_mem_get(mctx, sizeof(*ansname)); if (ansname == NULL) tresult = ISC_R_NOMEMORY; else { dns_name_t *aname; aname = dns_fixedname_name(&rctx->name); dns_name_init(ansname, NULL); tresult = dns_name_dup(aname, mctx, ansname); if (tresult != ISC_R_SUCCESS) isc_mem_put(mctx, ansname, sizeof(*ansname)); } if (tresult != ISC_R_SUCCESS) result = tresult; } switch (result) { case ISC_R_SUCCESS: send_event = ISC_TRUE; /* * This case is handled in the main line below. */ break; case DNS_R_CNAME: /* * Add the CNAME to the answer list. */ trdataset = rctx->rdataset; ISC_LIST_APPEND(ansname->list, rctx->rdataset, link); rctx->rdataset = NULL; if (rctx->sigrdataset != NULL) { ISC_LIST_APPEND(ansname->list, rctx->sigrdataset, link); rctx->sigrdataset = NULL; } ISC_LIST_APPEND(rctx->namelist, ansname, link); ansname = NULL; /* * Copy the CNAME's target into the lookup's * query name and start over. */ tresult = dns_rdataset_first(trdataset); if (tresult != ISC_R_SUCCESS) goto done; dns_rdataset_current(trdataset, &rdata); tresult = dns_rdata_tostruct(&rdata, &cname, NULL); dns_rdata_reset(&rdata); if (tresult != ISC_R_SUCCESS) goto done; tresult = dns_name_copy(&cname.cname, name, NULL); dns_rdata_freestruct(&cname); if (tresult == ISC_R_SUCCESS) want_restart = ISC_TRUE; else result = tresult; goto done; case DNS_R_DNAME: /* * Add the DNAME to the answer list. */ trdataset = rctx->rdataset; ISC_LIST_APPEND(ansname->list, rctx->rdataset, link); rctx->rdataset = NULL; if (rctx->sigrdataset != NULL) { ISC_LIST_APPEND(ansname->list, rctx->sigrdataset, link); rctx->sigrdataset = NULL; } ISC_LIST_APPEND(rctx->namelist, ansname, link); ansname = NULL; namereln = dns_name_fullcompare(name, fname, &order, &nlabels); INSIST(namereln == dns_namereln_subdomain); /* * Get the target name of the DNAME. */ tresult = dns_rdataset_first(trdataset); if (tresult != ISC_R_SUCCESS) { result = tresult; goto done; } dns_rdataset_current(trdataset, &rdata); tresult = dns_rdata_tostruct(&rdata, &dname, NULL); dns_rdata_reset(&rdata); if (tresult != ISC_R_SUCCESS) { result = tresult; goto done; } /* * Construct the new query name and start over. */ dns_fixedname_init(&fixed); prefix = dns_fixedname_name(&fixed); dns_name_split(name, nlabels, prefix, NULL); tresult = dns_name_concatenate(prefix, &dname.dname, name, NULL); dns_rdata_freestruct(&dname); if (tresult == ISC_R_SUCCESS) want_restart = ISC_TRUE; else result = tresult; goto done; case DNS_R_NCACHENXDOMAIN: case DNS_R_NCACHENXRRSET: ISC_LIST_APPEND(ansname->list, rctx->rdataset, link); ISC_LIST_APPEND(rctx->namelist, ansname, link); ansname = NULL; rctx->rdataset = NULL; /* What about sigrdataset? */ if (rctx->sigrdataset != NULL) putrdataset(mctx, &rctx->sigrdataset); send_event = ISC_TRUE; goto done; default: if (rctx->rdataset != NULL) putrdataset(mctx, &rctx->rdataset); if (rctx->sigrdataset != NULL) putrdataset(mctx, &rctx->sigrdataset); send_event = ISC_TRUE; goto done; } if (rctx->type == dns_rdatatype_any) { int n = 0; dns_rdatasetiter_t *rdsiter = NULL; tresult = dns_db_allrdatasets(db, node, NULL, 0, &rdsiter); if (tresult != ISC_R_SUCCESS) { result = tresult; goto done; } tresult = dns_rdatasetiter_first(rdsiter); while (tresult == ISC_R_SUCCESS) { dns_rdatasetiter_current(rdsiter, rctx->rdataset); if (rctx->rdataset->type != 0) { ISC_LIST_APPEND(ansname->list, rctx->rdataset, link); n++; rctx->rdataset = NULL; } else { /* * We're not interested in this * rdataset. */ dns_rdataset_disassociate( rctx->rdataset); } tresult = dns_rdatasetiter_next(rdsiter); if (tresult == ISC_R_SUCCESS && rctx->rdataset == NULL) { tresult = getrdataset(mctx, &rctx->rdataset); if (tresult != ISC_R_SUCCESS) { result = tresult; POST(result); break; } } } if (n == 0) { /* * We didn't match any rdatasets (which means * something went wrong in this * implementation). */ result = DNS_R_SERVFAIL; /* better code? */ POST(result); } else { ISC_LIST_APPEND(rctx->namelist, ansname, link); ansname = NULL; } dns_rdatasetiter_destroy(&rdsiter); if (tresult != ISC_R_NOMORE) result = DNS_R_SERVFAIL; /* ditto */ else result = ISC_R_SUCCESS; goto done; } else { /* * This is the "normal" case -- an ordinary question * to which we've got the answer. */ ISC_LIST_APPEND(ansname->list, rctx->rdataset, link); rctx->rdataset = NULL; if (rctx->sigrdataset != NULL) { ISC_LIST_APPEND(ansname->list, rctx->sigrdataset, link); rctx->sigrdataset = NULL; } ISC_LIST_APPEND(rctx->namelist, ansname, link); ansname = NULL; } done: /* * Free temporary resources */ if (ansname != NULL) { dns_rdataset_t *rdataset; while ((rdataset = ISC_LIST_HEAD(ansname->list)) != NULL) { ISC_LIST_UNLINK(ansname->list, rdataset, link); putrdataset(mctx, &rdataset); } dns_name_free(ansname, mctx); isc_mem_put(mctx, ansname, sizeof(*ansname)); } if (node != NULL) dns_db_detachnode(db, &node); if (db != NULL) dns_db_detach(&db); if (event != NULL) isc_event_free(ISC_EVENT_PTR(&event)); /* * Limit the number of restarts. */ if (want_restart && rctx->restarts == MAX_RESTARTS) { want_restart = ISC_FALSE; result = ISC_R_QUOTA; send_event = ISC_TRUE; } /* * Prepare further find with new resources */ if (want_restart) { INSIST(rctx->rdataset == NULL && rctx->sigrdataset == NULL); result = getrdataset(mctx, &rctx->rdataset); if (result == ISC_R_SUCCESS && rctx->want_dnssec) { result = getrdataset(mctx, &rctx->sigrdataset); if (result != ISC_R_SUCCESS) { putrdataset(mctx, &rctx->rdataset); } } if (result != ISC_R_SUCCESS) { want_restart = ISC_FALSE; send_event = ISC_TRUE; } } } while (want_restart); if (send_event) { isc_task_t *task; while ((name = ISC_LIST_HEAD(rctx->namelist)) != NULL) { ISC_LIST_UNLINK(rctx->namelist, name, link); ISC_LIST_APPEND(rctx->event->answerlist, name, link); } rctx->event->result = result; rctx->event->vresult = vresult; task = rctx->event->ev_sender; rctx->event->ev_sender = rctx; isc_task_sendanddetach(&task, ISC_EVENT_PTR(&rctx->event)); } UNLOCK(&rctx->lock); } static void suspend(isc_task_t *task, isc_event_t *event) { isc_appctx_t *actx = event->ev_arg; UNUSED(task); isc_app_ctxsuspend(actx); isc_event_free(&event); } static void resolve_done(isc_task_t *task, isc_event_t *event) { resarg_t *resarg = event->ev_arg; dns_clientresevent_t *rev = (dns_clientresevent_t *)event; dns_name_t *name; isc_result_t result; UNUSED(task); LOCK(&resarg->lock); resarg->result = rev->result; resarg->vresult = rev->vresult; while ((name = ISC_LIST_HEAD(rev->answerlist)) != NULL) { ISC_LIST_UNLINK(rev->answerlist, name, link); ISC_LIST_APPEND(*resarg->namelist, name, link); } dns_client_destroyrestrans(&resarg->trans); isc_event_free(&event); if (!resarg->canceled) { UNLOCK(&resarg->lock); /* * We may or may not be running. isc__appctx_onrun will * fail if we are currently running otherwise we post a * action to call isc_app_ctxsuspend when we do start * running. */ result = isc_app_ctxonrun(resarg->actx, resarg->client->mctx, task, suspend, resarg->actx); if (result == ISC_R_ALREADYRUNNING) isc_app_ctxsuspend(resarg->actx); } else { /* * We have already exited from the loop (due to some * unexpected event). Just clean the arg up. */ UNLOCK(&resarg->lock); DESTROYLOCK(&resarg->lock); isc_mem_put(resarg->client->mctx, resarg, sizeof(*resarg)); } } isc_result_t dns_client_resolve(dns_client_t *client, dns_name_t *name, dns_rdataclass_t rdclass, dns_rdatatype_t type, unsigned int options, dns_namelist_t *namelist) { isc_result_t result; isc_appctx_t *actx; resarg_t *resarg; REQUIRE(DNS_CLIENT_VALID(client)); REQUIRE(namelist != NULL && ISC_LIST_EMPTY(*namelist)); if ((client->attributes & DNS_CLIENTATTR_OWNCTX) == 0 && (options & DNS_CLIENTRESOPT_ALLOWRUN) == 0) { /* * If the client is run under application's control, we need * to create a new running (sub)environment for this * particular resolution. */ return (ISC_R_NOTIMPLEMENTED); /* XXXTBD */ } else actx = client->actx; resarg = isc_mem_get(client->mctx, sizeof(*resarg)); if (resarg == NULL) return (ISC_R_NOMEMORY); result = isc_mutex_init(&resarg->lock); if (result != ISC_R_SUCCESS) { isc_mem_put(client->mctx, resarg, sizeof(*resarg)); return (result); } resarg->actx = actx; resarg->client = client; resarg->result = DNS_R_SERVFAIL; resarg->namelist = namelist; resarg->trans = NULL; resarg->canceled = ISC_FALSE; result = dns_client_startresolve(client, name, rdclass, type, options, client->task, resolve_done, resarg, &resarg->trans); if (result != ISC_R_SUCCESS) { DESTROYLOCK(&resarg->lock); isc_mem_put(client->mctx, resarg, sizeof(*resarg)); return (result); } /* * Start internal event loop. It blocks until the entire process * is completed. */ result = isc_app_ctxrun(actx); LOCK(&resarg->lock); if (result == ISC_R_SUCCESS || result == ISC_R_SUSPEND) result = resarg->result; if (result != ISC_R_SUCCESS && resarg->vresult != ISC_R_SUCCESS) { /* * If this lookup failed due to some error in DNSSEC * validation, return the validation error code. * XXX: or should we pass the validation result separately? */ result = resarg->vresult; } if (resarg->trans != NULL) { /* * Unusual termination (perhaps due to signal). We need some * tricky cleanup process. */ resarg->canceled = ISC_TRUE; dns_client_cancelresolve(resarg->trans); UNLOCK(&resarg->lock); /* resarg will be freed in the event handler. */ } else { UNLOCK(&resarg->lock); DESTROYLOCK(&resarg->lock); isc_mem_put(client->mctx, resarg, sizeof(*resarg)); } return (result); } isc_result_t dns_client_startresolve(dns_client_t *client, dns_name_t *name, dns_rdataclass_t rdclass, dns_rdatatype_t type, unsigned int options, isc_task_t *task, isc_taskaction_t action, void *arg, dns_clientrestrans_t **transp) { dns_view_t *view = NULL; dns_clientresevent_t *event = NULL; resctx_t *rctx = NULL; isc_task_t *clone = NULL; isc_mem_t *mctx; isc_result_t result; dns_rdataset_t *rdataset, *sigrdataset; isc_boolean_t want_dnssec, want_validation, want_cdflag; REQUIRE(DNS_CLIENT_VALID(client)); REQUIRE(transp != NULL && *transp == NULL); LOCK(&client->lock); result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME, rdclass, &view); UNLOCK(&client->lock); if (result != ISC_R_SUCCESS) return (result); mctx = client->mctx; rdataset = NULL; sigrdataset = NULL; want_dnssec = ISC_TF((options & DNS_CLIENTRESOPT_NODNSSEC) == 0); want_validation = ISC_TF((options & DNS_CLIENTRESOPT_NOVALIDATE) == 0); want_cdflag = ISC_TF((options & DNS_CLIENTRESOPT_NOCDFLAG) == 0); /* * Prepare some intermediate resources */ clone = NULL; isc_task_attach(task, &clone); event = (dns_clientresevent_t *) isc_event_allocate(mctx, clone, DNS_EVENT_CLIENTRESDONE, action, arg, sizeof(*event)); if (event == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } event->result = DNS_R_SERVFAIL; ISC_LIST_INIT(event->answerlist); rctx = isc_mem_get(mctx, sizeof(*rctx)); if (rctx == NULL) result = ISC_R_NOMEMORY; else { result = isc_mutex_init(&rctx->lock); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, rctx, sizeof(*rctx)); rctx = NULL; } } if (result != ISC_R_SUCCESS) goto cleanup; result = getrdataset(mctx, &rdataset); if (result != ISC_R_SUCCESS) goto cleanup; rctx->rdataset = rdataset; if (want_dnssec) { result = getrdataset(mctx, &sigrdataset); if (result != ISC_R_SUCCESS) goto cleanup; } rctx->sigrdataset = sigrdataset; dns_fixedname_init(&rctx->name); result = dns_name_copy(name, dns_fixedname_name(&rctx->name), NULL); if (result != ISC_R_SUCCESS) goto cleanup; rctx->client = client; ISC_LINK_INIT(rctx, link); rctx->canceled = ISC_FALSE; rctx->task = client->task; rctx->type = type; rctx->view = view; rctx->restarts = 0; rctx->fetch = NULL; rctx->want_dnssec = want_dnssec; rctx->want_validation = want_validation; rctx->want_cdflag = want_cdflag; ISC_LIST_INIT(rctx->namelist); rctx->event = event; rctx->magic = RCTX_MAGIC; LOCK(&client->lock); ISC_LIST_APPEND(client->resctxs, rctx, link); UNLOCK(&client->lock); *transp = (dns_clientrestrans_t *)rctx; client_resfind(rctx, NULL); return (ISC_R_SUCCESS); cleanup: if (rdataset != NULL) putrdataset(client->mctx, &rdataset); if (sigrdataset != NULL) putrdataset(client->mctx, &sigrdataset); if (rctx != NULL) { DESTROYLOCK(&rctx->lock); isc_mem_put(mctx, rctx, sizeof(*rctx)); } if (event != NULL) isc_event_free(ISC_EVENT_PTR(&event)); isc_task_detach(&clone); dns_view_detach(&view); return (result); } void dns_client_cancelresolve(dns_clientrestrans_t *trans) { resctx_t *rctx; REQUIRE(trans != NULL); rctx = (resctx_t *)trans; REQUIRE(RCTX_VALID(rctx)); LOCK(&rctx->lock); if (!rctx->canceled) { rctx->canceled = ISC_TRUE; if (rctx->fetch != NULL) dns_resolver_cancelfetch(rctx->fetch); } UNLOCK(&rctx->lock); } void dns_client_freeresanswer(dns_client_t *client, dns_namelist_t *namelist) { dns_name_t *name; dns_rdataset_t *rdataset; REQUIRE(DNS_CLIENT_VALID(client)); REQUIRE(namelist != NULL); while ((name = ISC_LIST_HEAD(*namelist)) != NULL) { ISC_LIST_UNLINK(*namelist, name, link); while ((rdataset = ISC_LIST_HEAD(name->list)) != NULL) { ISC_LIST_UNLINK(name->list, rdataset, link); putrdataset(client->mctx, &rdataset); } dns_name_free(name, client->mctx); isc_mem_put(client->mctx, name, sizeof(*name)); } } void dns_client_destroyrestrans(dns_clientrestrans_t **transp) { resctx_t *rctx; isc_mem_t *mctx; dns_client_t *client; isc_boolean_t need_destroyclient = ISC_FALSE; REQUIRE(transp != NULL); rctx = (resctx_t *)*transp; REQUIRE(RCTX_VALID(rctx)); REQUIRE(rctx->fetch == NULL); REQUIRE(rctx->event == NULL); client = rctx->client; REQUIRE(DNS_CLIENT_VALID(client)); mctx = client->mctx; dns_view_detach(&rctx->view); LOCK(&client->lock); INSIST(ISC_LINK_LINKED(rctx, link)); ISC_LIST_UNLINK(client->resctxs, rctx, link); if (client->references == 0 && ISC_LIST_EMPTY(client->resctxs) && ISC_LIST_EMPTY(client->reqctxs) && ISC_LIST_EMPTY(client->updatectxs)) need_destroyclient = ISC_TRUE; UNLOCK(&client->lock); INSIST(ISC_LIST_EMPTY(rctx->namelist)); DESTROYLOCK(&rctx->lock); rctx->magic = 0; isc_mem_put(mctx, rctx, sizeof(*rctx)); if (need_destroyclient) destroyclient(&client); *transp = NULL; } isc_result_t dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass, dns_name_t *keyname, isc_buffer_t *keydatabuf) { isc_result_t result; dns_view_t *view = NULL; dst_key_t *dstkey = NULL; dns_keytable_t *secroots = NULL; REQUIRE(DNS_CLIENT_VALID(client)); LOCK(&client->lock); result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME, rdclass, &view); UNLOCK(&client->lock); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_view_getsecroots(view, &secroots); if (result != ISC_R_SUCCESS) goto cleanup; result = dst_key_fromdns(keyname, rdclass, keydatabuf, client->mctx, &dstkey); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_keytable_add(secroots, ISC_FALSE, &dstkey); cleanup: if (dstkey != NULL) dst_key_free(&dstkey); if (view != NULL) dns_view_detach(&view); if (secroots != NULL) dns_keytable_detach(&secroots); return (result); } /*% * Simple request routines */ static void request_done(isc_task_t *task, isc_event_t *event) { dns_requestevent_t *reqev = NULL; dns_request_t *request; isc_result_t result, eresult; reqctx_t *ctx; UNUSED(task); REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE); reqev = (dns_requestevent_t *)event; request = reqev->request; result = eresult = reqev->result; ctx = reqev->ev_arg; REQUIRE(REQCTX_VALID(ctx)); isc_event_free(&event); LOCK(&ctx->lock); if (eresult == ISC_R_SUCCESS) { result = dns_request_getresponse(request, ctx->event->rmessage, ctx->parseoptions); } if (ctx->tsigkey != NULL) dns_tsigkey_detach(&ctx->tsigkey); if (ctx->canceled) ctx->event->result = ISC_R_CANCELED; else ctx->event->result = result; task = ctx->event->ev_sender; ctx->event->ev_sender = ctx; isc_task_sendanddetach(&task, ISC_EVENT_PTR(&ctx->event)); UNLOCK(&ctx->lock); } static void localrequest_done(isc_task_t *task, isc_event_t *event) { reqarg_t *reqarg = event->ev_arg; dns_clientreqevent_t *rev =(dns_clientreqevent_t *)event; UNUSED(task); REQUIRE(event->ev_type == DNS_EVENT_CLIENTREQDONE); LOCK(&reqarg->lock); reqarg->result = rev->result; dns_client_destroyreqtrans(&reqarg->trans); isc_event_free(&event); if (!reqarg->canceled) { UNLOCK(&reqarg->lock); /* Exit from the internal event loop */ isc_app_ctxsuspend(reqarg->actx); } else { /* * We have already exited from the loop (due to some * unexpected event). Just clean the arg up. */ UNLOCK(&reqarg->lock); DESTROYLOCK(&reqarg->lock); isc_mem_put(reqarg->client->mctx, reqarg, sizeof(*reqarg)); } } isc_result_t dns_client_request(dns_client_t *client, dns_message_t *qmessage, dns_message_t *rmessage, isc_sockaddr_t *server, unsigned int options, unsigned int parseoptions, dns_tsec_t *tsec, unsigned int timeout, unsigned int udptimeout, unsigned int udpretries) { isc_appctx_t *actx; reqarg_t *reqarg; isc_result_t result; REQUIRE(DNS_CLIENT_VALID(client)); REQUIRE(qmessage != NULL); REQUIRE(rmessage != NULL); if ((client->attributes & DNS_CLIENTATTR_OWNCTX) == 0 && (options & DNS_CLIENTREQOPT_ALLOWRUN) == 0) { /* * If the client is run under application's control, we need * to create a new running (sub)environment for this * particular resolution. */ return (ISC_R_NOTIMPLEMENTED); /* XXXTBD */ } else actx = client->actx; reqarg = isc_mem_get(client->mctx, sizeof(*reqarg)); if (reqarg == NULL) return (ISC_R_NOMEMORY); result = isc_mutex_init(&reqarg->lock); if (result != ISC_R_SUCCESS) { isc_mem_put(client->mctx, reqarg, sizeof(*reqarg)); return (result); } reqarg->actx = actx; reqarg->client = client; reqarg->trans = NULL; reqarg->canceled = ISC_FALSE; result = dns_client_startrequest(client, qmessage, rmessage, server, options, parseoptions, tsec, timeout, udptimeout, udpretries, client->task, localrequest_done, reqarg, &reqarg->trans); if (result != ISC_R_SUCCESS) { DESTROYLOCK(&reqarg->lock); isc_mem_put(client->mctx, reqarg, sizeof(*reqarg)); return (result); } /* * Start internal event loop. It blocks until the entire process * is completed. */ result = isc_app_ctxrun(actx); LOCK(&reqarg->lock); if (result == ISC_R_SUCCESS || result == ISC_R_SUSPEND) result = reqarg->result; if (reqarg->trans != NULL) { /* * Unusual termination (perhaps due to signal). We need some * tricky cleanup process. */ reqarg->canceled = ISC_TRUE; dns_client_cancelresolve(reqarg->trans); UNLOCK(&reqarg->lock); /* reqarg will be freed in the event handler. */ } else { UNLOCK(&reqarg->lock); DESTROYLOCK(&reqarg->lock); isc_mem_put(client->mctx, reqarg, sizeof(*reqarg)); } return (result); } isc_result_t dns_client_startrequest(dns_client_t *client, dns_message_t *qmessage, dns_message_t *rmessage, isc_sockaddr_t *server, unsigned int options, unsigned int parseoptions, dns_tsec_t *tsec, unsigned int timeout, unsigned int udptimeout, unsigned int udpretries, isc_task_t *task, isc_taskaction_t action, void *arg, dns_clientreqtrans_t **transp) { isc_result_t result; dns_view_t *view = NULL; isc_task_t *clone = NULL; dns_clientreqevent_t *event = NULL; reqctx_t *ctx = NULL; dns_tsectype_t tsectype = dns_tsectype_none; UNUSED(options); REQUIRE(DNS_CLIENT_VALID(client)); REQUIRE(qmessage != NULL); REQUIRE(rmessage != NULL); REQUIRE(transp != NULL && *transp == NULL); if (tsec != NULL) { tsectype = dns_tsec_gettype(tsec); if (tsectype != dns_tsectype_tsig) return (ISC_R_NOTIMPLEMENTED); /* XXX */ } LOCK(&client->lock); result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME, qmessage->rdclass, &view); UNLOCK(&client->lock); if (result != ISC_R_SUCCESS) return (result); clone = NULL; isc_task_attach(task, &clone); event = (dns_clientreqevent_t *) isc_event_allocate(client->mctx, clone, DNS_EVENT_CLIENTREQDONE, action, arg, sizeof(*event)); if (event == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } ctx = isc_mem_get(client->mctx, sizeof(*ctx)); if (ctx == NULL) result = ISC_R_NOMEMORY; else { result = isc_mutex_init(&ctx->lock); if (result != ISC_R_SUCCESS) { isc_mem_put(client->mctx, ctx, sizeof(*ctx)); ctx = NULL; } } if (result != ISC_R_SUCCESS) goto cleanup; ctx->client = client; ISC_LINK_INIT(ctx, link); ctx->parseoptions = parseoptions; ctx->canceled = ISC_FALSE; ctx->event = event; ctx->event->rmessage = rmessage; ctx->tsigkey = NULL; if (tsec != NULL) dns_tsec_getkey(tsec, &ctx->tsigkey); ctx->magic = REQCTX_MAGIC; LOCK(&client->lock); ISC_LIST_APPEND(client->reqctxs, ctx, link); UNLOCK(&client->lock); ctx->request = NULL; result = dns_request_createvia3(view->requestmgr, qmessage, NULL, server, options, ctx->tsigkey, timeout, udptimeout, udpretries, client->task, request_done, ctx, &ctx->request); if (result == ISC_R_SUCCESS) { dns_view_detach(&view); *transp = (dns_clientreqtrans_t *)ctx; return (ISC_R_SUCCESS); } cleanup: if (ctx != NULL) { LOCK(&client->lock); ISC_LIST_UNLINK(client->reqctxs, ctx, link); UNLOCK(&client->lock); DESTROYLOCK(&ctx->lock); isc_mem_put(client->mctx, ctx, sizeof(*ctx)); } if (event != NULL) isc_event_free(ISC_EVENT_PTR(&event)); isc_task_detach(&clone); dns_view_detach(&view); return (result); } void dns_client_cancelrequest(dns_clientreqtrans_t *trans) { reqctx_t *ctx; REQUIRE(trans != NULL); ctx = (reqctx_t *)trans; REQUIRE(REQCTX_VALID(ctx)); LOCK(&ctx->lock); if (!ctx->canceled) { ctx->canceled = ISC_TRUE; if (ctx->request != NULL) dns_request_cancel(ctx->request); } UNLOCK(&ctx->lock); } void dns_client_destroyreqtrans(dns_clientreqtrans_t **transp) { reqctx_t *ctx; isc_mem_t *mctx; dns_client_t *client; isc_boolean_t need_destroyclient = ISC_FALSE; REQUIRE(transp != NULL); ctx = (reqctx_t *)*transp; REQUIRE(REQCTX_VALID(ctx)); client = ctx->client; REQUIRE(DNS_CLIENT_VALID(client)); REQUIRE(ctx->event == NULL); REQUIRE(ctx->request != NULL); dns_request_destroy(&ctx->request); mctx = client->mctx; LOCK(&client->lock); INSIST(ISC_LINK_LINKED(ctx, link)); ISC_LIST_UNLINK(client->reqctxs, ctx, link); if (client->references == 0 && ISC_LIST_EMPTY(client->resctxs) && ISC_LIST_EMPTY(client->reqctxs) && ISC_LIST_EMPTY(client->updatectxs)) { need_destroyclient = ISC_TRUE; } UNLOCK(&client->lock); DESTROYLOCK(&ctx->lock); ctx->magic = 0; isc_mem_put(mctx, ctx, sizeof(*ctx)); if (need_destroyclient) destroyclient(&client); *transp = NULL; } /*% * Dynamic update routines */ static isc_result_t rcode2result(dns_rcode_t rcode) { /* XXX: isn't there a similar function? */ switch (rcode) { case dns_rcode_formerr: return (DNS_R_FORMERR); case dns_rcode_servfail: return (DNS_R_SERVFAIL); case dns_rcode_nxdomain: return (DNS_R_NXDOMAIN); case dns_rcode_notimp: return (DNS_R_NOTIMP); case dns_rcode_refused: return (DNS_R_REFUSED); case dns_rcode_yxdomain: return (DNS_R_YXDOMAIN); case dns_rcode_yxrrset: return (DNS_R_YXRRSET); case dns_rcode_nxrrset: return (DNS_R_NXRRSET); case dns_rcode_notauth: return (DNS_R_NOTAUTH); case dns_rcode_notzone: return (DNS_R_NOTZONE); case dns_rcode_badvers: return (DNS_R_BADVERS); } return (ISC_R_FAILURE); } static void update_sendevent(updatectx_t *uctx, isc_result_t result) { isc_task_t *task; dns_message_destroy(&uctx->updatemsg); if (uctx->tsigkey != NULL) dns_tsigkey_detach(&uctx->tsigkey); if (uctx->sig0key != NULL) dst_key_free(&uctx->sig0key); if (uctx->canceled) uctx->event->result = ISC_R_CANCELED; else uctx->event->result = result; uctx->event->state = uctx->state; task = uctx->event->ev_sender; uctx->event->ev_sender = uctx; isc_task_sendanddetach(&task, ISC_EVENT_PTR(&uctx->event)); } static void update_done(isc_task_t *task, isc_event_t *event) { isc_result_t result; dns_requestevent_t *reqev = NULL; dns_request_t *request; dns_message_t *answer = NULL; updatectx_t *uctx = event->ev_arg; dns_client_t *client; unsigned int timeout; UNUSED(task); REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE); reqev = (dns_requestevent_t *)event; request = reqev->request; REQUIRE(UCTX_VALID(uctx)); client = uctx->client; REQUIRE(DNS_CLIENT_VALID(client)); result = reqev->result; if (result != ISC_R_SUCCESS) goto out; result = dns_message_create(client->mctx, DNS_MESSAGE_INTENTPARSE, &answer); if (result != ISC_R_SUCCESS) goto out; uctx->state = dns_clientupdatestate_done; result = dns_request_getresponse(request, answer, DNS_MESSAGEPARSE_PRESERVEORDER); if (result == ISC_R_SUCCESS && answer->rcode != dns_rcode_noerror) result = rcode2result(answer->rcode); out: if (answer != NULL) dns_message_destroy(&answer); isc_event_free(&event); LOCK(&uctx->lock); uctx->currentserver = ISC_LIST_NEXT(uctx->currentserver, link); dns_request_destroy(&uctx->updatereq); if (result != ISC_R_SUCCESS && !uctx->canceled && uctx->currentserver != NULL) { dns_message_renderreset(uctx->updatemsg); dns_message_settsigkey(uctx->updatemsg, NULL); timeout = client->update_timeout / uctx->nservers; if (timeout < MIN_UPDATE_TIMEOUT) timeout = MIN_UPDATE_TIMEOUT; result = dns_request_createvia3(uctx->view->requestmgr, uctx->updatemsg, NULL, uctx->currentserver, 0, uctx->tsigkey, timeout, client->update_udptimeout, client->update_udpretries, client->task, update_done, uctx, &uctx->updatereq); UNLOCK(&uctx->lock); if (result == ISC_R_SUCCESS) { /* XXX: should we keep the 'done' state here? */ uctx->state = dns_clientupdatestate_sent; return; } } else UNLOCK(&uctx->lock); update_sendevent(uctx, result); } static isc_result_t send_update(updatectx_t *uctx) { isc_result_t result; dns_name_t *name = NULL; dns_rdataset_t *rdataset = NULL; dns_client_t *client = uctx->client; unsigned int timeout; REQUIRE(uctx->zonename != NULL && uctx->currentserver != NULL); result = dns_message_gettempname(uctx->updatemsg, &name); if (result != ISC_R_SUCCESS) return (result); dns_name_init(name, NULL); dns_name_clone(uctx->zonename, name); result = dns_message_gettemprdataset(uctx->updatemsg, &rdataset); if (result != ISC_R_SUCCESS) { dns_message_puttempname(uctx->updatemsg, &name); return (result); } dns_rdataset_makequestion(rdataset, uctx->rdclass, dns_rdatatype_soa); ISC_LIST_INIT(name->list); ISC_LIST_APPEND(name->list, rdataset, link); dns_message_addname(uctx->updatemsg, name, DNS_SECTION_ZONE); if (uctx->tsigkey == NULL && uctx->sig0key != NULL) { result = dns_message_setsig0key(uctx->updatemsg, uctx->sig0key); if (result != ISC_R_SUCCESS) return (result); } timeout = client->update_timeout / uctx->nservers; if (timeout < MIN_UPDATE_TIMEOUT) timeout = MIN_UPDATE_TIMEOUT; result = dns_request_createvia3(uctx->view->requestmgr, uctx->updatemsg, NULL, uctx->currentserver, 0, uctx->tsigkey, timeout, client->update_udptimeout, client->update_udpretries, client->task, update_done, uctx, &uctx->updatereq); if (result == ISC_R_SUCCESS && uctx->state == dns_clientupdatestate_prepare) { uctx->state = dns_clientupdatestate_sent; } return (result); } static void resolveaddr_done(isc_task_t *task, isc_event_t *event) { isc_result_t result; int family; dns_rdatatype_t qtype; dns_clientresevent_t *rev = (dns_clientresevent_t *)event; dns_name_t *name; dns_rdataset_t *rdataset; updatectx_t *uctx; isc_boolean_t completed = ISC_FALSE; UNUSED(task); REQUIRE(event->ev_arg != NULL); uctx = *(updatectx_t **)event->ev_arg; REQUIRE(UCTX_VALID(uctx)); if (event->ev_arg == &uctx->bp4) { family = AF_INET; qtype = dns_rdatatype_a; LOCK(&uctx->lock); dns_client_destroyrestrans(&uctx->restrans); UNLOCK(&uctx->lock); } else { INSIST(event->ev_arg == &uctx->bp6); family = AF_INET6; qtype = dns_rdatatype_aaaa; LOCK(&uctx->lock); dns_client_destroyrestrans(&uctx->restrans2); UNLOCK(&uctx->lock); } result = rev->result; if (result != ISC_R_SUCCESS) goto done; for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL; name = ISC_LIST_NEXT(name, link)) { for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (!dns_rdataset_isassociated(rdataset)) continue; if (rdataset->type != qtype) continue; for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdata_t rdata; dns_rdata_in_a_t rdata_a; dns_rdata_in_aaaa_t rdata_aaaa; isc_sockaddr_t *sa; sa = isc_mem_get(uctx->client->mctx, sizeof(*sa)); if (sa == NULL) { /* * If we fail to get a sockaddr, we simply move forward with the * addresses we've got so far. */ goto done; } dns_rdata_init(&rdata); switch (family) { case AF_INET: dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &rdata_a, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); isc_sockaddr_fromin(sa, &rdata_a.in_addr, 53); dns_rdata_freestruct(&rdata_a); break; case AF_INET6: dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &rdata_aaaa, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); isc_sockaddr_fromin6(sa, &rdata_aaaa.in6_addr, 53); dns_rdata_freestruct(&rdata_aaaa); break; } ISC_LINK_INIT(sa, link); ISC_LIST_APPEND(uctx->servers, sa, link); uctx->nservers++; } } } done: dns_client_freeresanswer(uctx->client, &rev->answerlist); isc_event_free(&event); LOCK(&uctx->lock); if (uctx->restrans == NULL && uctx->restrans2 == NULL) completed = ISC_TRUE; UNLOCK(&uctx->lock); if (completed) { INSIST(uctx->currentserver == NULL); uctx->currentserver = ISC_LIST_HEAD(uctx->servers); if (uctx->currentserver != NULL && !uctx->canceled) send_update(uctx); else { if (result == ISC_R_SUCCESS) result = ISC_R_NOTFOUND; update_sendevent(uctx, result); } } } static isc_result_t process_soa(updatectx_t *uctx, dns_rdataset_t *soaset, dns_name_t *soaname) { isc_result_t result; dns_rdata_t soarr = DNS_RDATA_INIT; dns_rdata_soa_t soa; dns_name_t primary; result = dns_rdataset_first(soaset); if (result != ISC_R_SUCCESS) return (result); dns_rdata_init(&soarr); dns_rdataset_current(soaset, &soarr); result = dns_rdata_tostruct(&soarr, &soa, NULL); if (result != ISC_R_SUCCESS) return (result); dns_name_init(&primary, NULL); dns_name_clone(&soa.origin, &primary); if (uctx->zonename == NULL) { uctx->zonename = dns_fixedname_name(&uctx->zonefname); result = dns_name_copy(soaname, uctx->zonename, NULL); if (result != ISC_R_SUCCESS) goto out; } if (uctx->currentserver != NULL) result = send_update(uctx); else { /* * Get addresses of the primary server. We don't use the ADB * feature so that we could avoid caching data. */ LOCK(&uctx->lock); uctx->bp4 = uctx; result = dns_client_startresolve(uctx->client, &primary, uctx->rdclass, dns_rdatatype_a, 0, uctx->client->task, resolveaddr_done, &uctx->bp4, &uctx->restrans); if (result == ISC_R_SUCCESS) { uctx->bp6 = uctx; result = dns_client_startresolve(uctx->client, &primary, uctx->rdclass, dns_rdatatype_aaaa, 0, uctx->client->task, resolveaddr_done, &uctx->bp6, &uctx->restrans2); } UNLOCK(&uctx->lock); } out: dns_rdata_freestruct(&soa); return (result); } static void receive_soa(isc_task_t *task, isc_event_t *event) { dns_requestevent_t *reqev = NULL; updatectx_t *uctx; dns_client_t *client; isc_result_t result, eresult; dns_request_t *request; dns_message_t *rcvmsg = NULL; dns_section_t section; dns_rdataset_t *soaset = NULL; int pass = 0; dns_name_t *name; dns_message_t *soaquery = NULL; isc_sockaddr_t *addr; isc_boolean_t seencname = ISC_FALSE; isc_boolean_t droplabel = ISC_FALSE; dns_name_t tname; unsigned int nlabels; UNUSED(task); REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE); reqev = (dns_requestevent_t *)event; request = reqev->request; result = eresult = reqev->result; POST(result); uctx = reqev->ev_arg; client = uctx->client; soaquery = uctx->soaquery; addr = uctx->currentserver; INSIST(addr != NULL); isc_event_free(&event); if (eresult != ISC_R_SUCCESS) { result = eresult; goto out; } result = dns_message_create(uctx->client->mctx, DNS_MESSAGE_INTENTPARSE, &rcvmsg); if (result != ISC_R_SUCCESS) goto out; result = dns_request_getresponse(request, rcvmsg, DNS_MESSAGEPARSE_PRESERVEORDER); if (result == DNS_R_TSIGERRORSET) { dns_request_t *newrequest = NULL; /* Retry SOA request without TSIG */ dns_message_destroy(&rcvmsg); dns_message_renderreset(uctx->soaquery); result = dns_request_createvia3(uctx->view->requestmgr, uctx->soaquery, NULL, addr, 0, NULL, client->find_timeout * 20, client->find_timeout, 3, uctx->client->task, receive_soa, uctx, &newrequest); if (result == ISC_R_SUCCESS) { LOCK(&uctx->lock); dns_request_destroy(&uctx->soareq); uctx->soareq = newrequest; UNLOCK(&uctx->lock); return; } goto out; } section = DNS_SECTION_ANSWER; POST(section); if (rcvmsg->rcode != dns_rcode_noerror && rcvmsg->rcode != dns_rcode_nxdomain) { result = rcode2result(rcvmsg->rcode); goto out; } lookforsoa: if (pass == 0) section = DNS_SECTION_ANSWER; else if (pass == 1) section = DNS_SECTION_AUTHORITY; else { droplabel = ISC_TRUE; goto out; } result = dns_message_firstname(rcvmsg, section); if (result != ISC_R_SUCCESS) { pass++; goto lookforsoa; } while (result == ISC_R_SUCCESS) { name = NULL; dns_message_currentname(rcvmsg, section, &name); soaset = NULL; result = dns_message_findtype(name, dns_rdatatype_soa, 0, &soaset); if (result == ISC_R_SUCCESS) break; if (section == DNS_SECTION_ANSWER) { dns_rdataset_t *tset = NULL; if (dns_message_findtype(name, dns_rdatatype_cname, 0, &tset) == ISC_R_SUCCESS || dns_message_findtype(name, dns_rdatatype_dname, 0, &tset) == ISC_R_SUCCESS ) { seencname = ISC_TRUE; break; } } result = dns_message_nextname(rcvmsg, section); } if (soaset == NULL && !seencname) { pass++; goto lookforsoa; } if (seencname) { droplabel = ISC_TRUE; goto out; } result = process_soa(uctx, soaset, name); out: if (droplabel) { result = dns_message_firstname(soaquery, DNS_SECTION_QUESTION); INSIST(result == ISC_R_SUCCESS); name = NULL; dns_message_currentname(soaquery, DNS_SECTION_QUESTION, &name); nlabels = dns_name_countlabels(name); if (nlabels == 1) result = DNS_R_SERVFAIL; /* is there a better error? */ else { dns_name_init(&tname, NULL); dns_name_getlabelsequence(name, 1, nlabels - 1, &tname); dns_name_clone(&tname, name); dns_request_destroy(&request); LOCK(&uctx->lock); uctx->soareq = NULL; UNLOCK(&uctx->lock); dns_message_renderreset(soaquery); dns_message_settsigkey(soaquery, NULL); result = dns_request_createvia3(uctx->view->requestmgr, soaquery, NULL, uctx->currentserver, 0, uctx->tsigkey, client->find_timeout * 20, client->find_timeout, 3, client->task, receive_soa, uctx, &uctx->soareq); } } if (!droplabel || result != ISC_R_SUCCESS) { dns_message_destroy(&uctx->soaquery); LOCK(&uctx->lock); dns_request_destroy(&uctx->soareq); UNLOCK(&uctx->lock); } if (rcvmsg != NULL) dns_message_destroy(&rcvmsg); if (result != ISC_R_SUCCESS) update_sendevent(uctx, result); } static isc_result_t request_soa(updatectx_t *uctx) { isc_result_t result; dns_message_t *soaquery = uctx->soaquery; dns_name_t *name = NULL; dns_rdataset_t *rdataset = NULL; if (soaquery == NULL) { result = dns_message_create(uctx->client->mctx, DNS_MESSAGE_INTENTRENDER, &soaquery); if (result != ISC_R_SUCCESS) return (result); } soaquery->flags |= DNS_MESSAGEFLAG_RD; result = dns_message_gettempname(soaquery, &name); if (result != ISC_R_SUCCESS) goto fail; result = dns_message_gettemprdataset(soaquery, &rdataset); if (result != ISC_R_SUCCESS) goto fail; dns_rdataset_makequestion(rdataset, uctx->rdclass, dns_rdatatype_soa); dns_name_clone(uctx->firstname, name); ISC_LIST_APPEND(name->list, rdataset, link); dns_message_addname(soaquery, name, DNS_SECTION_QUESTION); rdataset = NULL; name = NULL; result = dns_request_createvia3(uctx->view->requestmgr, soaquery, NULL, uctx->currentserver, 0, uctx->tsigkey, uctx->client->find_timeout * 20, uctx->client->find_timeout, 3, uctx->client->task, receive_soa, uctx, &uctx->soareq); if (result == ISC_R_SUCCESS) { uctx->soaquery = soaquery; return (ISC_R_SUCCESS); } fail: if (rdataset != NULL) { ISC_LIST_UNLINK(name->list, rdataset, link); /* for safety */ dns_message_puttemprdataset(soaquery, &rdataset); } if (name != NULL) dns_message_puttempname(soaquery, &name); dns_message_destroy(&soaquery); return (result); } static void resolvesoa_done(isc_task_t *task, isc_event_t *event) { dns_clientresevent_t *rev = (dns_clientresevent_t *)event; updatectx_t *uctx; dns_name_t *name, tname; dns_rdataset_t *rdataset = NULL; isc_result_t result = rev->result; unsigned int nlabels; UNUSED(task); uctx = event->ev_arg; REQUIRE(UCTX_VALID(uctx)); LOCK(&uctx->lock); dns_client_destroyrestrans(&uctx->restrans); UNLOCK(&uctx->lock); uctx = event->ev_arg; if (result != ISC_R_SUCCESS && result != DNS_R_NCACHENXDOMAIN && result != DNS_R_NCACHENXRRSET) { /* XXX: what about DNSSEC failure? */ goto out; } for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL; name = ISC_LIST_NEXT(name, link)) { for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (dns_rdataset_isassociated(rdataset) && rdataset->type == dns_rdatatype_soa) break; } } if (rdataset == NULL) { /* Drop one label and retry resolution. */ nlabels = dns_name_countlabels(&uctx->soaqname); if (nlabels == 1) { result = DNS_R_SERVFAIL; /* is there a better error? */ goto out; } dns_name_init(&tname, NULL); dns_name_getlabelsequence(&uctx->soaqname, 1, nlabels - 1, &tname); dns_name_clone(&tname, &uctx->soaqname); result = dns_client_startresolve(uctx->client, &uctx->soaqname, uctx->rdclass, dns_rdatatype_soa, 0, uctx->client->task, resolvesoa_done, uctx, &uctx->restrans); } else result = process_soa(uctx, rdataset, &uctx->soaqname); out: dns_client_freeresanswer(uctx->client, &rev->answerlist); isc_event_free(&event); if (result != ISC_R_SUCCESS) update_sendevent(uctx, result); } static isc_result_t copy_name(isc_mem_t *mctx, dns_message_t *msg, dns_name_t *name, dns_name_t **newnamep) { isc_result_t result; dns_name_t *newname = NULL; isc_region_t r; isc_buffer_t *namebuf = NULL, *rdatabuf = NULL; dns_rdatalist_t *rdatalist; dns_rdataset_t *rdataset, *newrdataset; dns_rdata_t rdata = DNS_RDATA_INIT, *newrdata; result = dns_message_gettempname(msg, &newname); if (result != ISC_R_SUCCESS) return (result); result = isc_buffer_allocate(mctx, &namebuf, DNS_NAME_MAXWIRE); if (result != ISC_R_SUCCESS) goto fail; dns_name_init(newname, NULL); dns_name_setbuffer(newname, namebuf); dns_message_takebuffer(msg, &namebuf); result = dns_name_copy(name, newname, NULL); if (result != ISC_R_SUCCESS) goto fail; for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { rdatalist = NULL; result = dns_message_gettemprdatalist(msg, &rdatalist); if (result != ISC_R_SUCCESS) goto fail; dns_rdatalist_init(rdatalist); rdatalist->type = rdataset->type; rdatalist->rdclass = rdataset->rdclass; rdatalist->covers = rdataset->covers; rdatalist->ttl = rdataset->ttl; result = dns_rdataset_first(rdataset); while (result == ISC_R_SUCCESS) { dns_rdata_reset(&rdata); dns_rdataset_current(rdataset, &rdata); newrdata = NULL; result = dns_message_gettemprdata(msg, &newrdata); if (result != ISC_R_SUCCESS) goto fail; dns_rdata_toregion(&rdata, &r); rdatabuf = NULL; result = isc_buffer_allocate(mctx, &rdatabuf, r.length); if (result != ISC_R_SUCCESS) goto fail; isc_buffer_putmem(rdatabuf, r.base, r.length); isc_buffer_usedregion(rdatabuf, &r); dns_rdata_init(newrdata); dns_rdata_fromregion(newrdata, rdata.rdclass, rdata.type, &r); newrdata->flags = rdata.flags; ISC_LIST_APPEND(rdatalist->rdata, newrdata, link); dns_message_takebuffer(msg, &rdatabuf); result = dns_rdataset_next(rdataset); } newrdataset = NULL; result = dns_message_gettemprdataset(msg, &newrdataset); if (result != ISC_R_SUCCESS) goto fail; dns_rdatalist_tordataset(rdatalist, newrdataset); ISC_LIST_APPEND(newname->list, newrdataset, link); } *newnamep = newname; return (ISC_R_SUCCESS); fail: dns_message_puttempname(msg, &newname); return (result); } static void internal_update_callback(isc_task_t *task, isc_event_t *event) { updatearg_t *uarg = event->ev_arg; dns_clientupdateevent_t *uev = (dns_clientupdateevent_t *)event; UNUSED(task); LOCK(&uarg->lock); uarg->result = uev->result; dns_client_destroyupdatetrans(&uarg->trans); isc_event_free(&event); if (!uarg->canceled) { UNLOCK(&uarg->lock); /* Exit from the internal event loop */ isc_app_ctxsuspend(uarg->actx); } else { /* * We have already exited from the loop (due to some * unexpected event). Just clean the arg up. */ UNLOCK(&uarg->lock); DESTROYLOCK(&uarg->lock); isc_mem_put(uarg->client->mctx, uarg, sizeof(*uarg)); } } isc_result_t dns_client_update(dns_client_t *client, dns_rdataclass_t rdclass, dns_name_t *zonename, dns_namelist_t *prerequisites, dns_namelist_t *updates, isc_sockaddrlist_t *servers, dns_tsec_t *tsec, unsigned int options) { isc_result_t result; isc_appctx_t *actx; updatearg_t *uarg; REQUIRE(DNS_CLIENT_VALID(client)); if ((client->attributes & DNS_CLIENTATTR_OWNCTX) == 0 && (options & DNS_CLIENTRESOPT_ALLOWRUN) == 0) { /* * If the client is run under application's control, we need * to create a new running (sub)environment for this * particular resolution. */ return (ISC_R_NOTIMPLEMENTED); /* XXXTBD */ } else actx = client->actx; uarg = isc_mem_get(client->mctx, sizeof(*uarg)); if (uarg == NULL) return (ISC_R_NOMEMORY); result = isc_mutex_init(&uarg->lock); if (result != ISC_R_SUCCESS) { isc_mem_put(client->mctx, uarg, sizeof(*uarg)); return (result); } uarg->actx = actx; uarg->client = client; uarg->result = ISC_R_FAILURE; uarg->trans = NULL; uarg->canceled = ISC_FALSE; result = dns_client_startupdate(client, rdclass, zonename, prerequisites, updates, servers, tsec, options, client->task, internal_update_callback, uarg, &uarg->trans); if (result != ISC_R_SUCCESS) { DESTROYLOCK(&uarg->lock); isc_mem_put(client->mctx, uarg, sizeof(*uarg)); return (result); } /* * Start internal event loop. It blocks until the entire process * is completed. */ result = isc_app_ctxrun(actx); LOCK(&uarg->lock); if (result == ISC_R_SUCCESS || result == ISC_R_SUSPEND) result = uarg->result; if (uarg->trans != NULL) { /* * Unusual termination (perhaps due to signal). We need some * tricky cleanup process. */ uarg->canceled = ISC_TRUE; dns_client_cancelupdate(uarg->trans); UNLOCK(&uarg->lock); /* uarg will be freed in the event handler. */ } else { UNLOCK(&uarg->lock); DESTROYLOCK(&uarg->lock); isc_mem_put(client->mctx, uarg, sizeof(*uarg)); } return (result); } isc_result_t dns_client_startupdate(dns_client_t *client, dns_rdataclass_t rdclass, dns_name_t *zonename, dns_namelist_t *prerequisites, dns_namelist_t *updates, isc_sockaddrlist_t *servers, dns_tsec_t *tsec, unsigned int options, isc_task_t *task, isc_taskaction_t action, void *arg, dns_clientupdatetrans_t **transp) { dns_view_t *view = NULL; isc_result_t result; dns_name_t *name, *newname; updatectx_t *uctx; isc_task_t *clone = NULL; dns_section_t section = DNS_SECTION_UPDATE; isc_sockaddr_t *server, *sa = NULL; dns_tsectype_t tsectype = dns_tsectype_none; UNUSED(options); REQUIRE(DNS_CLIENT_VALID(client)); REQUIRE(transp != NULL && *transp == NULL); REQUIRE(updates != NULL); REQUIRE(task != NULL); if (tsec != NULL) { tsectype = dns_tsec_gettype(tsec); if (tsectype != dns_tsectype_tsig) return (ISC_R_NOTIMPLEMENTED); /* XXX */ } LOCK(&client->lock); result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME, rdclass, &view); UNLOCK(&client->lock); if (result != ISC_R_SUCCESS) return (result); /* Create a context and prepare some resources */ uctx = isc_mem_get(client->mctx, sizeof(*uctx)); if (uctx == NULL) { dns_view_detach(&view); return (ISC_R_NOMEMORY); } result = isc_mutex_init(&uctx->lock); if (result != ISC_R_SUCCESS) { dns_view_detach(&view); isc_mem_put(client->mctx, uctx, sizeof(*uctx)); return (ISC_R_NOMEMORY); } clone = NULL; isc_task_attach(task, &clone); uctx->client = client; ISC_LINK_INIT(uctx, link); uctx->state = dns_clientupdatestate_prepare; uctx->view = view; uctx->rdclass = rdclass; uctx->canceled = ISC_FALSE; uctx->updatemsg = NULL; uctx->soaquery = NULL; uctx->updatereq = NULL; uctx->restrans = NULL; uctx->restrans2 = NULL; uctx->bp4 = NULL; uctx->bp6 = NULL; uctx->soareq = NULL; uctx->event = NULL; uctx->tsigkey = NULL; uctx->sig0key = NULL; uctx->zonename = NULL; dns_name_init(&uctx->soaqname, NULL); ISC_LIST_INIT(uctx->servers); uctx->nservers = 0; uctx->currentserver = NULL; dns_fixedname_init(&uctx->zonefname); if (tsec != NULL) dns_tsec_getkey(tsec, &uctx->tsigkey); uctx->event = (dns_clientupdateevent_t *) isc_event_allocate(client->mctx, clone, DNS_EVENT_UPDATEDONE, action, arg, sizeof(*uctx->event)); if (uctx->event == NULL) goto fail; if (zonename != NULL) { uctx->zonename = dns_fixedname_name(&uctx->zonefname); result = dns_name_copy(zonename, uctx->zonename, NULL); } if (servers != NULL) { for (server = ISC_LIST_HEAD(*servers); server != NULL; server = ISC_LIST_NEXT(server, link)) { sa = isc_mem_get(client->mctx, sizeof(*sa)); if (sa == NULL) goto fail; sa->type = server->type; sa->length = server->length; ISC_LINK_INIT(sa, link); ISC_LIST_APPEND(uctx->servers, sa, link); if (uctx->currentserver == NULL) uctx->currentserver = sa; uctx->nservers++; } } /* Make update message */ result = dns_message_create(client->mctx, DNS_MESSAGE_INTENTRENDER, &uctx->updatemsg); if (result != ISC_R_SUCCESS) goto fail; uctx->updatemsg->opcode = dns_opcode_update; if (prerequisites != NULL) { for (name = ISC_LIST_HEAD(*prerequisites); name != NULL; name = ISC_LIST_NEXT(name, link)) { newname = NULL; result = copy_name(client->mctx, uctx->updatemsg, name, &newname); if (result != ISC_R_SUCCESS) goto fail; dns_message_addname(uctx->updatemsg, newname, DNS_SECTION_PREREQUISITE); } } for (name = ISC_LIST_HEAD(*updates); name != NULL; name = ISC_LIST_NEXT(name, link)) { newname = NULL; result = copy_name(client->mctx, uctx->updatemsg, name, &newname); if (result != ISC_R_SUCCESS) goto fail; dns_message_addname(uctx->updatemsg, newname, DNS_SECTION_UPDATE); } uctx->firstname = NULL; result = dns_message_firstname(uctx->updatemsg, section); if (result == ISC_R_NOMORE) { section = DNS_SECTION_PREREQUISITE; result = dns_message_firstname(uctx->updatemsg, section); } if (result != ISC_R_SUCCESS) goto fail; dns_message_currentname(uctx->updatemsg, section, &uctx->firstname); uctx->magic = UCTX_MAGIC; LOCK(&client->lock); ISC_LIST_APPEND(client->updatectxs, uctx, link); UNLOCK(&client->lock); if (uctx->zonename != NULL && uctx->currentserver != NULL) { result = send_update(uctx); if (result != ISC_R_SUCCESS) goto fail; } else if (uctx->currentserver != NULL) { result = request_soa(uctx); if (result != ISC_R_SUCCESS) goto fail; } else { dns_name_clone(uctx->firstname, &uctx->soaqname); result = dns_client_startresolve(uctx->client, &uctx->soaqname, uctx->rdclass, dns_rdatatype_soa, 0, client->task, resolvesoa_done, uctx, &uctx->restrans); if (result != ISC_R_SUCCESS) goto fail; } *transp = (dns_clientupdatetrans_t *)uctx; return (ISC_R_SUCCESS); fail: if (ISC_LINK_LINKED(uctx, link)) { LOCK(&client->lock); ISC_LIST_UNLINK(client->updatectxs, uctx, link); UNLOCK(&client->lock); } if (uctx->updatemsg != NULL) dns_message_destroy(&uctx->updatemsg); while ((sa = ISC_LIST_HEAD(uctx->servers)) != NULL) { ISC_LIST_UNLINK(uctx->servers, sa, link); isc_mem_put(client->mctx, sa, sizeof(*sa)); } if (uctx->event != NULL) isc_event_free(ISC_EVENT_PTR(&uctx->event)); if (uctx->tsigkey != NULL) dns_tsigkey_detach(&uctx->tsigkey); isc_task_detach(&clone); DESTROYLOCK(&uctx->lock); uctx->magic = 0; isc_mem_put(client->mctx, uctx, sizeof(*uctx)); dns_view_detach(&view); return (result); } void dns_client_cancelupdate(dns_clientupdatetrans_t *trans) { updatectx_t *uctx; REQUIRE(trans != NULL); uctx = (updatectx_t *)trans; REQUIRE(UCTX_VALID(uctx)); LOCK(&uctx->lock); if (!uctx->canceled) { uctx->canceled = ISC_TRUE; if (uctx->updatereq != NULL) dns_request_cancel(uctx->updatereq); if (uctx->soareq != NULL) dns_request_cancel(uctx->soareq); if (uctx->restrans != NULL) dns_client_cancelresolve(uctx->restrans); if (uctx->restrans2 != NULL) dns_client_cancelresolve(uctx->restrans2); } UNLOCK(&uctx->lock); } void dns_client_destroyupdatetrans(dns_clientupdatetrans_t **transp) { updatectx_t *uctx; isc_mem_t *mctx; dns_client_t *client; isc_boolean_t need_destroyclient = ISC_FALSE; isc_sockaddr_t *sa; REQUIRE(transp != NULL); uctx = (updatectx_t *)*transp; REQUIRE(UCTX_VALID(uctx)); client = uctx->client; REQUIRE(DNS_CLIENT_VALID(client)); REQUIRE(uctx->updatereq == NULL && uctx->updatemsg == NULL && uctx->soareq == NULL && uctx->soaquery == NULL && uctx->event == NULL && uctx->tsigkey == NULL && uctx->sig0key == NULL); mctx = client->mctx; dns_view_detach(&uctx->view); while ((sa = ISC_LIST_HEAD(uctx->servers)) != NULL) { ISC_LIST_UNLINK(uctx->servers, sa, link); isc_mem_put(mctx, sa, sizeof(*sa)); } LOCK(&client->lock); INSIST(ISC_LINK_LINKED(uctx, link)); ISC_LIST_UNLINK(client->updatectxs, uctx, link); if (client->references == 0 && ISC_LIST_EMPTY(client->resctxs) && ISC_LIST_EMPTY(client->reqctxs) && ISC_LIST_EMPTY(client->updatectxs)) need_destroyclient = ISC_TRUE; UNLOCK(&client->lock); DESTROYLOCK(&uctx->lock); uctx->magic = 0; isc_mem_put(mctx, uctx, sizeof(*uctx)); if (need_destroyclient) destroyclient(&client); *transp = NULL; } isc_mem_t * dns_client_mctx(dns_client_t *client) { REQUIRE(DNS_CLIENT_VALID(client)); return (client->mctx); } typedef struct { isc_buffer_t buffer; dns_rdataset_t rdataset; dns_rdatalist_t rdatalist; dns_rdata_t rdata; size_t size; isc_mem_t * mctx; unsigned char data[FLEXIBLE_ARRAY_MEMBER]; } dns_client_updaterec_t; isc_result_t dns_client_updaterec(dns_client_updateop_t op, dns_name_t *owner, dns_rdatatype_t type, dns_rdata_t *source, dns_ttl_t ttl, dns_name_t *target, dns_rdataset_t *rdataset, dns_rdatalist_t *rdatalist, dns_rdata_t *rdata, isc_mem_t *mctx) { dns_client_updaterec_t *updaterec = NULL; size_t size = offsetof(dns_client_updaterec_t, data); REQUIRE(op < updateop_max); REQUIRE(owner != NULL); REQUIRE((rdataset != NULL && rdatalist != NULL && rdata != NULL) || (rdataset == NULL && rdatalist == NULL && rdata == NULL && mctx != NULL)); if (op == updateop_add) REQUIRE(source != NULL); if (source != NULL) { REQUIRE(source->type == type); REQUIRE(op == updateop_add || op == updateop_delete || op == updateop_exist); } size += owner->length; if (source != NULL) size += source->length; if (rdataset == NULL) { updaterec = isc_mem_get(mctx, size); if (updaterec == NULL) return (ISC_R_NOMEMORY); rdataset = &updaterec->rdataset; rdatalist = &updaterec->rdatalist; rdata = &updaterec->rdata; dns_rdataset_init(rdataset); dns_rdatalist_init(&updaterec->rdatalist); dns_rdata_init(&updaterec->rdata); isc_buffer_init(&updaterec->buffer, updaterec->data, (unsigned int) (size - offsetof(dns_client_updaterec_t, data))); dns_name_copy(owner, target, &updaterec->buffer); if (source != NULL) { isc_region_t r; dns_rdata_clone(source, rdata); dns_rdata_toregion(rdata, &r); rdata->data = isc_buffer_used(&updaterec->buffer); isc_buffer_copyregion(&updaterec->buffer, &r); } updaterec->mctx = NULL; isc_mem_attach(mctx, &updaterec->mctx); } else if (source != NULL) dns_rdata_clone(source, rdata); switch (op) { case updateop_add: break; case updateop_delete: if (source != NULL) { ttl = 0; dns_rdata_makedelete(rdata); } else dns_rdata_deleterrset(rdata, type); break; case updateop_notexist: dns_rdata_notexist(rdata, type); break; case updateop_exist: if (source == NULL) { ttl = 0; dns_rdata_exists(rdata, type); } case updateop_none: break; default: INSIST(0); } rdatalist->type = rdata->type; rdatalist->rdclass = rdata->rdclass; if (source != NULL) { rdatalist->covers = dns_rdata_covers(rdata); rdatalist->ttl = ttl; } ISC_LIST_APPEND(rdatalist->rdata, rdata, link); dns_rdatalist_tordataset(rdatalist, rdataset); ISC_LIST_APPEND(target->list, rdataset, link); if (updaterec != NULL) { target->attributes |= DNS_NAMEATTR_HASUPDATEREC; dns_name_setbuffer(target, &updaterec->buffer); } if (op == updateop_add || op == updateop_delete) target->attributes |= DNS_NAMEATTR_UPDATE; else target->attributes |= DNS_NAMEATTR_PREREQUISITE; return (ISC_R_SUCCESS); } void dns_client_freeupdate(dns_name_t **namep) { dns_client_updaterec_t *updaterec; dns_rdatalist_t *rdatalist; dns_rdataset_t *rdataset; dns_rdata_t *rdata; dns_name_t *name; REQUIRE(namep != NULL && *namep != NULL); name = *namep; for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_HEAD(name->list)) { ISC_LIST_UNLINK(name->list, rdataset, link); rdatalist = NULL; dns_rdatalist_fromrdataset(rdataset, &rdatalist); if (rdatalist == NULL) { dns_rdataset_disassociate(rdataset); continue; } for (rdata = ISC_LIST_HEAD(rdatalist->rdata); rdata != NULL; rdata = ISC_LIST_HEAD(rdatalist->rdata)) ISC_LIST_UNLINK(rdatalist->rdata, rdata, link); dns_rdataset_disassociate(rdataset); } if ((name->attributes & DNS_NAMEATTR_HASUPDATEREC) != 0) { updaterec = (dns_client_updaterec_t *)name->buffer; INSIST(updaterec != NULL); isc_mem_putanddetach(&updaterec->mctx, updaterec, updaterec->size); *namep = NULL; } } bind9-9.10.3.dfsg.P4/lib/dns/rbtdb.h0000644000470500017500000000325212664710322016173 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef DNS_RBTDB_H #define DNS_RBTDB_H 1 #include #include /***** ***** Module Info *****/ /*! \file * \brief * DNS Red-Black Tree DB Implementation */ ISC_LANG_BEGINDECLS isc_result_t dns_rbtdb_create(isc_mem_t *mctx, dns_name_t *base, dns_dbtype_t type, dns_rdataclass_t rdclass, unsigned int argc, char *argv[], void *driverarg, dns_db_t **dbp); /*%< * Create a new database of type "rbt" (or "rbt64"). Called via * dns_db_create(); see documentation for that function for more details. * * If argv[0] is set, it points to a valid memory context to be used for * allocation of heap memory. Generally this is used for cache databases * only. * * Requires: * * \li argc == 0 or argv[0] is a valid memory context. */ ISC_LANG_ENDDECLS #endif /* DNS_RBTDB_H */ bind9-9.10.3.dfsg.P4/lib/dns/ds.c0000644000470500017500000001025412664710322015477 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2010, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ds.c,v 1.13 2010/12/23 23:47:08 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) #include "dst_gost.h" #endif isc_result_t dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, unsigned int digest_type, unsigned char *buffer, dns_rdata_t *rdata) { dns_fixedname_t fname; dns_name_t *name; unsigned char digest[ISC_SHA384_DIGESTLENGTH]; isc_region_t r; isc_buffer_t b; dns_rdata_ds_t ds; isc_sha1_t sha1; isc_sha256_t sha256; isc_sha384_t sha384; #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) isc_gost_t gost; #endif REQUIRE(key != NULL); REQUIRE(key->type == dns_rdatatype_dnskey); if (!dst_ds_digest_supported(digest_type)) return (ISC_R_NOTIMPLEMENTED); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); (void)dns_name_downcase(owner, name, NULL); memset(buffer, 0, DNS_DS_BUFFERSIZE); isc_buffer_init(&b, buffer, DNS_DS_BUFFERSIZE); switch (digest_type) { case DNS_DSDIGEST_SHA1: isc_sha1_init(&sha1); dns_name_toregion(name, &r); isc_sha1_update(&sha1, r.base, r.length); dns_rdata_toregion(key, &r); INSIST(r.length >= 4); isc_sha1_update(&sha1, r.base, r.length); isc_sha1_final(&sha1, digest); break; #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) #define RETERR(x) do { \ isc_result_t ret = (x); \ if (ret != ISC_R_SUCCESS) { \ isc_gost_invalidate(&gost); \ return (ret); \ } \ } while (0) case DNS_DSDIGEST_GOST: RETERR(isc_gost_init(&gost)); dns_name_toregion(name, &r); RETERR(isc_gost_update(&gost, r.base, r.length)); dns_rdata_toregion(key, &r); INSIST(r.length >= 4); RETERR(isc_gost_update(&gost, r.base, r.length)); RETERR(isc_gost_final(&gost, digest)); break; #endif case DNS_DSDIGEST_SHA384: isc_sha384_init(&sha384); dns_name_toregion(name, &r); isc_sha384_update(&sha384, r.base, r.length); dns_rdata_toregion(key, &r); INSIST(r.length >= 4); isc_sha384_update(&sha384, r.base, r.length); isc_sha384_final(digest, &sha384); break; case DNS_DSDIGEST_SHA256: default: isc_sha256_init(&sha256); dns_name_toregion(name, &r); isc_sha256_update(&sha256, r.base, r.length); dns_rdata_toregion(key, &r); INSIST(r.length >= 4); isc_sha256_update(&sha256, r.base, r.length); isc_sha256_final(digest, &sha256); break; } ds.mctx = NULL; ds.common.rdclass = key->rdclass; ds.common.rdtype = dns_rdatatype_ds; ds.algorithm = r.base[3]; ds.key_tag = dst_region_computeid(&r, ds.algorithm); ds.digest_type = digest_type; switch (digest_type) { case DNS_DSDIGEST_SHA1: ds.length = ISC_SHA1_DIGESTLENGTH; break; #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) case DNS_DSDIGEST_GOST: ds.length = ISC_GOST_DIGESTLENGTH; break; #endif case DNS_DSDIGEST_SHA384: ds.length = ISC_SHA384_DIGESTLENGTH; break; case DNS_DSDIGEST_SHA256: default: ds.length = ISC_SHA256_DIGESTLENGTH; break; } ds.digest = digest; return (dns_rdata_fromstruct(rdata, key->rdclass, dns_rdatatype_ds, &ds, &b)); } bind9-9.10.3.dfsg.P4/lib/dns/dst_parse.c0000644000470500017500000004453112664710322017062 0ustar lamontlamont/* * Portions Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /*% * Principal Author: Brian Wellington * $Id: dst_parse.c,v 1.29 2011/08/18 23:46:35 tbox Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dst_internal.h" #include "dst_parse.h" #include "dst/result.h" #define DST_AS_STR(t) ((t).value.as_textregion.base) #define PRIVATE_KEY_STR "Private-key-format:" #define ALGORITHM_STR "Algorithm:" #define TIMING_NTAGS (DST_MAX_TIMES + 1) static const char *timetags[TIMING_NTAGS] = { "Created:", "Publish:", "Activate:", "Revoke:", "Inactive:", "Delete:", "DSPublish:" }; #define NUMERIC_NTAGS (DST_MAX_NUMERIC + 1) static const char *numerictags[NUMERIC_NTAGS] = { "Predecessor:", "Successor:", "MaxTTL:", "RollPeriod:" }; struct parse_map { const int value; const char *tag; }; static struct parse_map map[] = { {TAG_RSA_MODULUS, "Modulus:"}, {TAG_RSA_PUBLICEXPONENT, "PublicExponent:"}, {TAG_RSA_PRIVATEEXPONENT, "PrivateExponent:"}, {TAG_RSA_PRIME1, "Prime1:"}, {TAG_RSA_PRIME2, "Prime2:"}, {TAG_RSA_EXPONENT1, "Exponent1:"}, {TAG_RSA_EXPONENT2, "Exponent2:"}, {TAG_RSA_COEFFICIENT, "Coefficient:"}, {TAG_RSA_ENGINE, "Engine:" }, {TAG_RSA_LABEL, "Label:" }, {TAG_DH_PRIME, "Prime(p):"}, {TAG_DH_GENERATOR, "Generator(g):"}, {TAG_DH_PRIVATE, "Private_value(x):"}, {TAG_DH_PUBLIC, "Public_value(y):"}, {TAG_DSA_PRIME, "Prime(p):"}, {TAG_DSA_SUBPRIME, "Subprime(q):"}, {TAG_DSA_BASE, "Base(g):"}, {TAG_DSA_PRIVATE, "Private_value(x):"}, {TAG_DSA_PUBLIC, "Public_value(y):"}, {TAG_GOST_PRIVASN1, "GostAsn1:"}, {TAG_GOST_PRIVRAW, "PrivateKey:"}, {TAG_ECDSA_PRIVATEKEY, "PrivateKey:"}, {TAG_ECDSA_ENGINE, "Engine:" }, {TAG_ECDSA_LABEL, "Label:" }, {TAG_HMACMD5_KEY, "Key:"}, {TAG_HMACMD5_BITS, "Bits:"}, {TAG_HMACSHA1_KEY, "Key:"}, {TAG_HMACSHA1_BITS, "Bits:"}, {TAG_HMACSHA224_KEY, "Key:"}, {TAG_HMACSHA224_BITS, "Bits:"}, {TAG_HMACSHA256_KEY, "Key:"}, {TAG_HMACSHA256_BITS, "Bits:"}, {TAG_HMACSHA384_KEY, "Key:"}, {TAG_HMACSHA384_BITS, "Bits:"}, {TAG_HMACSHA512_KEY, "Key:"}, {TAG_HMACSHA512_BITS, "Bits:"}, {0, NULL} }; static int find_value(const char *s, const unsigned int alg) { int i; for (i = 0; map[i].tag != NULL; i++) { if (strcasecmp(s, map[i].tag) == 0 && (TAG_ALG(map[i].value) == alg)) return (map[i].value); } return (-1); } static const char * find_tag(const int value) { int i; for (i = 0; ; i++) { if (map[i].tag == NULL) return (NULL); else if (value == map[i].value) return (map[i].tag); } } static int find_metadata(const char *s, const char *tags[], int ntags) { int i; for (i = 0; i < ntags; i++) { if (strcasecmp(s, tags[i]) == 0) return (i); } return (-1); } static int find_timedata(const char *s) { return (find_metadata(s, timetags, TIMING_NTAGS)); } static int find_numericdata(const char *s) { return (find_metadata(s, numerictags, NUMERIC_NTAGS)); } static int check_rsa(const dst_private_t *priv, isc_boolean_t external) { int i, j; isc_boolean_t have[RSA_NTAGS]; isc_boolean_t ok; unsigned int mask; if (external) return ((priv->nelements == 0) ? 0 : -1); for (i = 0; i < RSA_NTAGS; i++) have[i] = ISC_FALSE; for (j = 0; j < priv->nelements; j++) { for (i = 0; i < RSA_NTAGS; i++) if (priv->elements[j].tag == TAG(DST_ALG_RSAMD5, i)) break; if (i == RSA_NTAGS) return (-1); have[i] = ISC_TRUE; } mask = ~0; mask <<= sizeof(mask) * 8 - TAG_SHIFT; mask >>= sizeof(mask) * 8 - TAG_SHIFT; if (have[TAG_RSA_ENGINE & mask]) ok = have[TAG_RSA_MODULUS & mask] && have[TAG_RSA_PUBLICEXPONENT & mask] && have[TAG_RSA_LABEL & mask]; else ok = have[TAG_RSA_MODULUS & mask] && have[TAG_RSA_PUBLICEXPONENT & mask] && have[TAG_RSA_PRIVATEEXPONENT & mask] && have[TAG_RSA_PRIME1 & mask] && have[TAG_RSA_PRIME2 & mask] && have[TAG_RSA_EXPONENT1 & mask] && have[TAG_RSA_EXPONENT2 & mask] && have[TAG_RSA_COEFFICIENT & mask]; return (ok ? 0 : -1 ); } static int check_dh(const dst_private_t *priv) { int i, j; if (priv->nelements != DH_NTAGS) return (-1); for (i = 0; i < DH_NTAGS; i++) { for (j = 0; j < priv->nelements; j++) if (priv->elements[j].tag == TAG(DST_ALG_DH, i)) break; if (j == priv->nelements) return (-1); } return (0); } static int check_dsa(const dst_private_t *priv, isc_boolean_t external) { int i, j; if (external) return ((priv->nelements == 0)? 0 : -1); if (priv->nelements != DSA_NTAGS) return (-1); for (i = 0; i < DSA_NTAGS; i++) { for (j = 0; j < priv->nelements; j++) if (priv->elements[j].tag == TAG(DST_ALG_DSA, i)) break; if (j == priv->nelements) return (-1); } return (0); } static int check_gost(const dst_private_t *priv, isc_boolean_t external) { if (external) return ((priv->nelements == 0)? 0 : -1); if (priv->nelements != GOST_NTAGS) return (-1); if ((priv->elements[0].tag != TAG(DST_ALG_ECCGOST, 0)) && (priv->elements[0].tag != TAG(DST_ALG_ECCGOST, 1))) return (-1); return (0); } static int check_ecdsa(const dst_private_t *priv, isc_boolean_t external) { int i, j; isc_boolean_t have[ECDSA_NTAGS]; isc_boolean_t ok; unsigned int mask; if (external) return ((priv->nelements == 0) ? 0 : -1); for (i = 0; i < ECDSA_NTAGS; i++) have[i] = ISC_FALSE; for (j = 0; j < priv->nelements; j++) { for (i = 0; i < ECDSA_NTAGS; i++) if (priv->elements[j].tag == TAG(DST_ALG_ECDSA256, i)) break; if (i == ECDSA_NTAGS) return (-1); have[i] = ISC_TRUE; } mask = ~0; mask <<= sizeof(mask) * 8 - TAG_SHIFT; mask >>= sizeof(mask) * 8 - TAG_SHIFT; if (have[TAG_ECDSA_ENGINE & mask]) ok = have[TAG_ECDSA_LABEL & mask]; else ok = have[TAG_ECDSA_PRIVATEKEY & mask]; return (ok ? 0 : -1 ); } static int check_hmac_md5(const dst_private_t *priv, isc_boolean_t old) { int i, j; if (priv->nelements != HMACMD5_NTAGS) { /* * If this is a good old format and we are accepting * the old format return success. */ if (old && priv->nelements == OLD_HMACMD5_NTAGS && priv->elements[0].tag == TAG_HMACMD5_KEY) return (0); return (-1); } /* * We must be new format at this point. */ for (i = 0; i < HMACMD5_NTAGS; i++) { for (j = 0; j < priv->nelements; j++) if (priv->elements[j].tag == TAG(DST_ALG_HMACMD5, i)) break; if (j == priv->nelements) return (-1); } return (0); } static int check_hmac_sha(const dst_private_t *priv, unsigned int ntags, unsigned int alg) { unsigned int i, j; if (priv->nelements != ntags) return (-1); for (i = 0; i < ntags; i++) { for (j = 0; j < priv->nelements; j++) if (priv->elements[j].tag == TAG(alg, i)) break; if (j == priv->nelements) return (-1); } return (0); } static int check_data(const dst_private_t *priv, const unsigned int alg, isc_boolean_t old, isc_boolean_t external) { /* XXXVIX this switch statement is too sparse to gen a jump table. */ switch (alg) { case DST_ALG_RSAMD5: case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: case DST_ALG_RSASHA256: case DST_ALG_RSASHA512: return (check_rsa(priv, external)); case DST_ALG_DH: return (check_dh(priv)); case DST_ALG_DSA: case DST_ALG_NSEC3DSA: return (check_dsa(priv, external)); case DST_ALG_ECCGOST: return (check_gost(priv, external)); case DST_ALG_ECDSA256: case DST_ALG_ECDSA384: return (check_ecdsa(priv, external)); case DST_ALG_HMACMD5: return (check_hmac_md5(priv, old)); case DST_ALG_HMACSHA1: return (check_hmac_sha(priv, HMACSHA1_NTAGS, alg)); case DST_ALG_HMACSHA224: return (check_hmac_sha(priv, HMACSHA224_NTAGS, alg)); case DST_ALG_HMACSHA256: return (check_hmac_sha(priv, HMACSHA256_NTAGS, alg)); case DST_ALG_HMACSHA384: return (check_hmac_sha(priv, HMACSHA384_NTAGS, alg)); case DST_ALG_HMACSHA512: return (check_hmac_sha(priv, HMACSHA512_NTAGS, alg)); default: return (DST_R_UNSUPPORTEDALG); } } void dst__privstruct_free(dst_private_t *priv, isc_mem_t *mctx) { int i; if (priv == NULL) return; for (i = 0; i < priv->nelements; i++) { if (priv->elements[i].data == NULL) continue; memset(priv->elements[i].data, 0, MAXFIELDSIZE); isc_mem_put(mctx, priv->elements[i].data, MAXFIELDSIZE); } priv->nelements = 0; } isc_result_t dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex, isc_mem_t *mctx, dst_private_t *priv) { int n = 0, major, minor, check; isc_buffer_t b; isc_token_t token; unsigned char *data = NULL; unsigned int opt = ISC_LEXOPT_EOL; isc_stdtime_t when; isc_result_t ret; isc_boolean_t external = ISC_FALSE; REQUIRE(priv != NULL); priv->nelements = 0; memset(priv->elements, 0, sizeof(priv->elements)); #define NEXTTOKEN(lex, opt, token) \ do { \ ret = isc_lex_gettoken(lex, opt, token); \ if (ret != ISC_R_SUCCESS) \ goto fail; \ } while (0) #define READLINE(lex, opt, token) \ do { \ ret = isc_lex_gettoken(lex, opt, token); \ if (ret == ISC_R_EOF) \ break; \ else if (ret != ISC_R_SUCCESS) \ goto fail; \ } while ((*token).type != isc_tokentype_eol) /* * Read the description line. */ NEXTTOKEN(lex, opt, &token); if (token.type != isc_tokentype_string || strcmp(DST_AS_STR(token), PRIVATE_KEY_STR) != 0) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } NEXTTOKEN(lex, opt, &token); if (token.type != isc_tokentype_string || (DST_AS_STR(token))[0] != 'v') { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } if (sscanf(DST_AS_STR(token), "v%d.%d", &major, &minor) != 2) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } if (major > DST_MAJOR_VERSION) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } /* * Store the private key format version number */ dst_key_setprivateformat(key, major, minor); READLINE(lex, opt, &token); /* * Read the algorithm line. */ NEXTTOKEN(lex, opt, &token); if (token.type != isc_tokentype_string || strcmp(DST_AS_STR(token), ALGORITHM_STR) != 0) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } NEXTTOKEN(lex, opt | ISC_LEXOPT_NUMBER, &token); if (token.type != isc_tokentype_number || token.value.as_ulong != (unsigned long) dst_key_alg(key)) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } READLINE(lex, opt, &token); /* * Read the key data. */ for (n = 0; n < MAXFIELDS; n++) { int tag; isc_region_t r; do { ret = isc_lex_gettoken(lex, opt, &token); if (ret == ISC_R_EOF) goto done; if (ret != ISC_R_SUCCESS) goto fail; } while (token.type == isc_tokentype_eol); if (token.type != isc_tokentype_string) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } if (strcmp(DST_AS_STR(token), "External:") == 0) { external = ISC_TRUE; goto next; } /* Numeric metadata */ tag = find_numericdata(DST_AS_STR(token)); if (tag >= 0) { INSIST(tag < NUMERIC_NTAGS); NEXTTOKEN(lex, opt | ISC_LEXOPT_NUMBER, &token); if (token.type != isc_tokentype_number) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } dst_key_setnum(key, tag, token.value.as_ulong); goto next; } /* Timing metadata */ tag = find_timedata(DST_AS_STR(token)); if (tag >= 0) { INSIST(tag < TIMING_NTAGS); NEXTTOKEN(lex, opt, &token); if (token.type != isc_tokentype_string) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } ret = dns_time32_fromtext(DST_AS_STR(token), &when); if (ret != ISC_R_SUCCESS) goto fail; dst_key_settime(key, tag, when); goto next; } /* Key data */ tag = find_value(DST_AS_STR(token), alg); if (tag < 0 && minor > DST_MINOR_VERSION) goto next; else if (tag < 0) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } priv->elements[n].tag = tag; data = (unsigned char *) isc_mem_get(mctx, MAXFIELDSIZE); if (data == NULL) goto fail; isc_buffer_init(&b, data, MAXFIELDSIZE); ret = isc_base64_tobuffer(lex, &b, -1); if (ret != ISC_R_SUCCESS) goto fail; isc_buffer_usedregion(&b, &r); priv->elements[n].length = r.length; priv->elements[n].data = r.base; priv->nelements++; next: READLINE(lex, opt, &token); data = NULL; } done: if (external && priv->nelements != 0) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } check = check_data(priv, alg, ISC_TRUE, external); if (check < 0) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } else if (check != ISC_R_SUCCESS) { ret = check; goto fail; } key->external = external; return (ISC_R_SUCCESS); fail: dst__privstruct_free(priv, mctx); if (data != NULL) isc_mem_put(mctx, data, MAXFIELDSIZE); return (ret); } isc_result_t dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv, const char *directory) { FILE *fp; isc_result_t result; char filename[ISC_DIR_NAMEMAX]; char buffer[MAXFIELDSIZE * 2]; isc_fsaccess_t access; isc_stdtime_t when; isc_uint32_t value; isc_buffer_t b; isc_region_t r; int major, minor; mode_t mode; int i, ret; REQUIRE(priv != NULL); ret = check_data(priv, dst_key_alg(key), ISC_FALSE, key->external); if (ret < 0) return (DST_R_INVALIDPRIVATEKEY); else if (ret != ISC_R_SUCCESS) return (ret); isc_buffer_init(&b, filename, sizeof(filename)); result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory, &b); if (result != ISC_R_SUCCESS) return (result); result = isc_file_mode(filename, &mode); if (result == ISC_R_SUCCESS && mode != 0600) { /* File exists; warn that we are changing its permissions */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_DNSSEC, ISC_LOG_WARNING, "Permissions on the file %s " "have changed from 0%o to 0600 as " "a result of this operation.", filename, (unsigned int)mode); } if ((fp = fopen(filename, "w")) == NULL) return (DST_R_WRITEERROR); access = 0; isc_fsaccess_add(ISC_FSACCESS_OWNER, ISC_FSACCESS_READ | ISC_FSACCESS_WRITE, &access); (void)isc_fsaccess_set(filename, access); dst_key_getprivateformat(key, &major, &minor); if (major == 0 && minor == 0) { major = DST_MAJOR_VERSION; minor = DST_MINOR_VERSION; } /* XXXDCL return value should be checked for full filesystem */ fprintf(fp, "%s v%d.%d\n", PRIVATE_KEY_STR, major, minor); fprintf(fp, "%s %d ", ALGORITHM_STR, dst_key_alg(key)); /* XXXVIX this switch statement is too sparse to gen a jump table. */ switch (dst_key_alg(key)) { case DST_ALG_RSAMD5: fprintf(fp, "(RSA)\n"); break; case DST_ALG_DH: fprintf(fp, "(DH)\n"); break; case DST_ALG_DSA: fprintf(fp, "(DSA)\n"); break; case DST_ALG_RSASHA1: fprintf(fp, "(RSASHA1)\n"); break; case DST_ALG_NSEC3RSASHA1: fprintf(fp, "(NSEC3RSASHA1)\n"); break; case DST_ALG_NSEC3DSA: fprintf(fp, "(NSEC3DSA)\n"); break; case DST_ALG_RSASHA256: fprintf(fp, "(RSASHA256)\n"); break; case DST_ALG_RSASHA512: fprintf(fp, "(RSASHA512)\n"); break; case DST_ALG_ECCGOST: fprintf(fp, "(ECC-GOST)\n"); break; case DST_ALG_ECDSA256: fprintf(fp, "(ECDSAP256SHA256)\n"); break; case DST_ALG_ECDSA384: fprintf(fp, "(ECDSAP384SHA384)\n"); break; case DST_ALG_HMACMD5: fprintf(fp, "(HMAC_MD5)\n"); break; case DST_ALG_HMACSHA1: fprintf(fp, "(HMAC_SHA1)\n"); break; case DST_ALG_HMACSHA224: fprintf(fp, "(HMAC_SHA224)\n"); break; case DST_ALG_HMACSHA256: fprintf(fp, "(HMAC_SHA256)\n"); break; case DST_ALG_HMACSHA384: fprintf(fp, "(HMAC_SHA384)\n"); break; case DST_ALG_HMACSHA512: fprintf(fp, "(HMAC_SHA512)\n"); break; default: fprintf(fp, "(?)\n"); break; } for (i = 0; i < priv->nelements; i++) { const char *s; s = find_tag(priv->elements[i].tag); r.base = priv->elements[i].data; r.length = priv->elements[i].length; isc_buffer_init(&b, buffer, sizeof(buffer)); result = isc_base64_totext(&r, sizeof(buffer), "", &b); if (result != ISC_R_SUCCESS) { fclose(fp); return (DST_R_INVALIDPRIVATEKEY); } isc_buffer_usedregion(&b, &r); fprintf(fp, "%s %.*s\n", s, (int)r.length, r.base); } if (key->external) fprintf(fp, "External:\n"); /* Add the metadata tags */ if (major > 1 || (major == 1 && minor >= 3)) { for (i = 0; i < NUMERIC_NTAGS; i++) { result = dst_key_getnum(key, i, &value); if (result != ISC_R_SUCCESS) continue; fprintf(fp, "%s %u\n", numerictags[i], value); } for (i = 0; i < TIMING_NTAGS; i++) { result = dst_key_gettime(key, i, &when); if (result != ISC_R_SUCCESS) continue; isc_buffer_init(&b, buffer, sizeof(buffer)); result = dns_time32_totext(when, &b); if (result != ISC_R_SUCCESS) { fclose(fp); return (DST_R_INVALIDPRIVATEKEY); } isc_buffer_usedregion(&b, &r); fprintf(fp, "%s %.*s\n", timetags[i], (int)r.length, r.base); } } fflush(fp); result = ferror(fp) ? DST_R_WRITEERROR : ISC_R_SUCCESS; fclose(fp); return (result); } /*! \file */ bind9-9.10.3.dfsg.P4/lib/dns/timer.c0000644000470500017500000000355112664710322016213 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: timer.c,v 1.7 2007/06/19 23:47:16 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #define CHECK(op) \ do { result = (op); \ if (result != ISC_R_SUCCESS) goto failure; \ } while (0) isc_result_t dns_timer_setidle(isc_timer_t *timer, unsigned int maxtime, unsigned int idletime, isc_boolean_t purge) { isc_result_t result; isc_interval_t maxinterval, idleinterval; isc_time_t expires; /* Compute the time of expiry. */ isc_interval_set(&maxinterval, maxtime, 0); CHECK(isc_time_nowplusinterval(&expires, &maxinterval)); /* * Compute the idle interval, and add a spare nanosecond to * work around the silly limitation of the ISC timer interface * that you cannot specify an idle interval of zero. */ isc_interval_set(&idleinterval, idletime, 1); CHECK(isc_timer_reset(timer, isc_timertype_once, &expires, &idleinterval, purge)); failure: return (result); } bind9-9.10.3.dfsg.P4/lib/dns/openssldsa_link.c0000644000470500017500000004077712664710322020276 0ustar lamontlamont/* * Portions Copyright (C) 2004-2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef OPENSSL #ifndef USE_EVP #define USE_EVP 1 #endif #include #include #include #include #include #include #include #include "dst_internal.h" #include "dst_openssl.h" #include "dst_parse.h" #include static isc_result_t openssldsa_todns(const dst_key_t *key, isc_buffer_t *data); static isc_result_t openssldsa_createctx(dst_key_t *key, dst_context_t *dctx) { #if USE_EVP EVP_MD_CTX *evp_md_ctx; UNUSED(key); evp_md_ctx = EVP_MD_CTX_create(); if (evp_md_ctx == NULL) return (ISC_R_NOMEMORY); if (!EVP_DigestInit_ex(evp_md_ctx, EVP_dss1(), NULL)) { EVP_MD_CTX_destroy(evp_md_ctx); return (ISC_R_FAILURE); } dctx->ctxdata.evp_md_ctx = evp_md_ctx; return (ISC_R_SUCCESS); #else isc_sha1_t *sha1ctx; UNUSED(key); sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t)); isc_sha1_init(sha1ctx); dctx->ctxdata.sha1ctx = sha1ctx; return (ISC_R_SUCCESS); #endif } static void openssldsa_destroyctx(dst_context_t *dctx) { #if USE_EVP EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; if (evp_md_ctx != NULL) { EVP_MD_CTX_destroy(evp_md_ctx); dctx->ctxdata.evp_md_ctx = NULL; } #else isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; if (sha1ctx != NULL) { isc_sha1_invalidate(sha1ctx); isc_mem_put(dctx->mctx, sha1ctx, sizeof(isc_sha1_t)); dctx->ctxdata.sha1ctx = NULL; } #endif } static isc_result_t openssldsa_adddata(dst_context_t *dctx, const isc_region_t *data) { #if USE_EVP EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) { return (ISC_R_FAILURE); } #else isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; isc_sha1_update(sha1ctx, data->base, data->length); #endif return (ISC_R_SUCCESS); } static int BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf, int size) { int bytes = size - BN_num_bytes(bn); while (bytes-- > 0) *buf++ = 0; BN_bn2bin(bn, buf); return (size); } static isc_result_t openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { dst_key_t *key = dctx->key; DSA *dsa = key->keydata.dsa; isc_region_t r; DSA_SIG *dsasig; unsigned int klen; #if USE_EVP EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; EVP_PKEY *pkey; unsigned char *sigbuf; const unsigned char *sb; unsigned int siglen; #else isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; unsigned char digest[ISC_SHA1_DIGESTLENGTH]; #endif isc_buffer_availableregion(sig, &r); if (r.length < ISC_SHA1_DIGESTLENGTH * 2 + 1) return (ISC_R_NOSPACE); #if USE_EVP pkey = EVP_PKEY_new(); if (pkey == NULL) return (ISC_R_NOMEMORY); if (!EVP_PKEY_set1_DSA(pkey, dsa)) { EVP_PKEY_free(pkey); return (ISC_R_FAILURE); } sigbuf = malloc(EVP_PKEY_size(pkey)); if (sigbuf == NULL) { EVP_PKEY_free(pkey); return (ISC_R_NOMEMORY); } if (!EVP_SignFinal(evp_md_ctx, sigbuf, &siglen, pkey)) { EVP_PKEY_free(pkey); free(sigbuf); return (dst__openssl_toresult3(dctx->category, "EVP_SignFinal", ISC_R_FAILURE)); } INSIST(EVP_PKEY_size(pkey) >= (int) siglen); EVP_PKEY_free(pkey); /* Convert from Dss-Sig-Value (RFC2459). */ dsasig = DSA_SIG_new(); if (dsasig == NULL) { free(sigbuf); return (ISC_R_NOMEMORY); } sb = sigbuf; if (d2i_DSA_SIG(&dsasig, &sb, (long) siglen) == NULL) { free(sigbuf); return (dst__openssl_toresult3(dctx->category, "d2i_DSA_SIG", ISC_R_FAILURE)); } free(sigbuf); #elif 0 /* Only use EVP for the Digest */ if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) { return (dst__openssl_toresult3(dctx->category, "EVP_DigestFinal_ex", ISC_R_FAILURE)); } dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa); if (dsasig == NULL) return (dst__openssl_toresult3(dctx->category, "DSA_do_sign", DST_R_SIGNFAILURE)); #else isc_sha1_final(sha1ctx, digest); dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa); if (dsasig == NULL) return (dst__openssl_toresult3(dctx->category, "DSA_do_sign", DST_R_SIGNFAILURE)); #endif klen = (key->key_size - 512)/64; if (klen > 255) return (ISC_R_FAILURE); *r.base = klen; isc_region_consume(&r, 1); BN_bn2bin_fixed(dsasig->r, r.base, ISC_SHA1_DIGESTLENGTH); isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); BN_bn2bin_fixed(dsasig->s, r.base, ISC_SHA1_DIGESTLENGTH); isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); DSA_SIG_free(dsasig); isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH * 2 + 1); return (ISC_R_SUCCESS); } static isc_result_t openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) { dst_key_t *key = dctx->key; DSA *dsa = key->keydata.dsa; int status = 0; unsigned char *cp = sig->base; DSA_SIG *dsasig; #if USE_EVP EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; #if 0 EVP_PKEY *pkey; unsigned char *sigbuf; #endif unsigned int siglen; #else isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; #endif unsigned char digest[ISC_SHA1_DIGESTLENGTH]; #if USE_EVP #if 1 /* Only use EVP for the digest */ if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) { return (ISC_R_FAILURE); } #endif #else isc_sha1_final(sha1ctx, digest); #endif if (sig->length != 2 * ISC_SHA1_DIGESTLENGTH + 1) { return (DST_R_VERIFYFAILURE); } cp++; /*%< Skip T */ dsasig = DSA_SIG_new(); if (dsasig == NULL) return (ISC_R_NOMEMORY); dsasig->r = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL); cp += ISC_SHA1_DIGESTLENGTH; dsasig->s = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL); #if 0 pkey = EVP_PKEY_new(); if (pkey == NULL) return (ISC_R_NOMEMORY); if (!EVP_PKEY_set1_DSA(pkey, dsa)) { EVP_PKEY_free(pkey); return (ISC_R_FAILURE); } /* Convert to Dss-Sig-Value (RFC2459). */ sigbuf = malloc(EVP_PKEY_size(pkey) + 50); if (sigbuf == NULL) { EVP_PKEY_free(pkey); return (ISC_R_NOMEMORY); } siglen = (unsigned) i2d_DSA_SIG(dsasig, &sigbuf); INSIST(EVP_PKEY_size(pkey) >= (int) siglen); status = EVP_VerifyFinal(evp_md_ctx, sigbuf, siglen, pkey); EVP_PKEY_free(pkey); free(sigbuf); #else status = DSA_do_verify(digest, ISC_SHA1_DIGESTLENGTH, dsasig, dsa); #endif DSA_SIG_free(dsasig); switch (status) { case 1: return (ISC_R_SUCCESS); case 0: return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); default: return (dst__openssl_toresult3(dctx->category, "DSA_do_verify", DST_R_VERIFYFAILURE)); } } static isc_boolean_t openssldsa_compare(const dst_key_t *key1, const dst_key_t *key2) { int status; DSA *dsa1, *dsa2; dsa1 = key1->keydata.dsa; dsa2 = key2->keydata.dsa; if (dsa1 == NULL && dsa2 == NULL) return (ISC_TRUE); else if (dsa1 == NULL || dsa2 == NULL) return (ISC_FALSE); status = BN_cmp(dsa1->p, dsa2->p) || BN_cmp(dsa1->q, dsa2->q) || BN_cmp(dsa1->g, dsa2->g) || BN_cmp(dsa1->pub_key, dsa2->pub_key); if (status != 0) return (ISC_FALSE); if (dsa1->priv_key != NULL || dsa2->priv_key != NULL) { if (dsa1->priv_key == NULL || dsa2->priv_key == NULL) return (ISC_FALSE); if (BN_cmp(dsa1->priv_key, dsa2->priv_key)) return (ISC_FALSE); } return (ISC_TRUE); } #if OPENSSL_VERSION_NUMBER > 0x00908000L static int progress_cb(int p, int n, BN_GENCB *cb) { union { void *dptr; void (*fptr)(int); } u; UNUSED(n); u.dptr = BN_GENCB_get_arg(cb); if (u.fptr != NULL) u.fptr(p); return (1); } #endif static isc_result_t openssldsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { DSA *dsa; unsigned char rand_array[ISC_SHA1_DIGESTLENGTH]; isc_result_t result; #if OPENSSL_VERSION_NUMBER > 0x00908000L BN_GENCB *cb; #if OPENSSL_VERSION_NUMBER < 0x10100000L BN_GENCB _cb; #endif union { void *dptr; void (*fptr)(int); } u; #else UNUSED(callback); #endif UNUSED(unused); result = dst__entropy_getdata(rand_array, sizeof(rand_array), ISC_FALSE); if (result != ISC_R_SUCCESS) return (result); #if OPENSSL_VERSION_NUMBER > 0x00908000L dsa = DSA_new(); if (dsa == NULL) return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); cb = BN_GENCB_new(); #if OPENSSL_VERSION_NUMBER >= 0x10100000L if (cb == NULL) { DSA_free(dsa); return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); } #endif if (callback == NULL) { BN_GENCB_set_old(cb, NULL, NULL); } else { u.fptr = callback; BN_GENCB_set(cb, &progress_cb, u.dptr); } if (!DSA_generate_parameters_ex(dsa, key->key_size, rand_array, ISC_SHA1_DIGESTLENGTH, NULL, NULL, cb)) { DSA_free(dsa); BN_GENCB_free(cb); return (dst__openssl_toresult2("DSA_generate_parameters_ex", DST_R_OPENSSLFAILURE)); } BN_GENCB_free(cb); #else dsa = DSA_generate_parameters(key->key_size, rand_array, ISC_SHA1_DIGESTLENGTH, NULL, NULL, NULL, NULL); if (dsa == NULL) return (dst__openssl_toresult2("DSA_generate_parameters", DST_R_OPENSSLFAILURE)); #endif if (DSA_generate_key(dsa) == 0) { DSA_free(dsa); return (dst__openssl_toresult2("DSA_generate_key", DST_R_OPENSSLFAILURE)); } dsa->flags &= ~DSA_FLAG_CACHE_MONT_P; key->keydata.dsa = dsa; return (ISC_R_SUCCESS); } static isc_boolean_t openssldsa_isprivate(const dst_key_t *key) { DSA *dsa = key->keydata.dsa; return (ISC_TF(dsa != NULL && dsa->priv_key != NULL)); } static void openssldsa_destroy(dst_key_t *key) { DSA *dsa = key->keydata.dsa; DSA_free(dsa); key->keydata.dsa = NULL; } static isc_result_t openssldsa_todns(const dst_key_t *key, isc_buffer_t *data) { DSA *dsa; isc_region_t r; int dnslen; unsigned int t, p_bytes; REQUIRE(key->keydata.dsa != NULL); dsa = key->keydata.dsa; isc_buffer_availableregion(data, &r); t = (BN_num_bytes(dsa->p) - 64) / 8; if (t > 8) return (DST_R_INVALIDPUBLICKEY); p_bytes = 64 + 8 * t; dnslen = 1 + (key->key_size * 3)/8 + ISC_SHA1_DIGESTLENGTH; if (r.length < (unsigned int) dnslen) return (ISC_R_NOSPACE); *r.base = t; isc_region_consume(&r, 1); BN_bn2bin_fixed(dsa->q, r.base, ISC_SHA1_DIGESTLENGTH); isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); BN_bn2bin_fixed(dsa->p, r.base, key->key_size/8); isc_region_consume(&r, p_bytes); BN_bn2bin_fixed(dsa->g, r.base, key->key_size/8); isc_region_consume(&r, p_bytes); BN_bn2bin_fixed(dsa->pub_key, r.base, key->key_size/8); isc_region_consume(&r, p_bytes); isc_buffer_add(data, dnslen); return (ISC_R_SUCCESS); } static isc_result_t openssldsa_fromdns(dst_key_t *key, isc_buffer_t *data) { DSA *dsa; isc_region_t r; unsigned int t, p_bytes; isc_mem_t *mctx = key->mctx; UNUSED(mctx); isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); dsa = DSA_new(); if (dsa == NULL) return (ISC_R_NOMEMORY); dsa->flags &= ~DSA_FLAG_CACHE_MONT_P; t = (unsigned int) *r.base; isc_region_consume(&r, 1); if (t > 8) { DSA_free(dsa); return (DST_R_INVALIDPUBLICKEY); } p_bytes = 64 + 8 * t; if (r.length < ISC_SHA1_DIGESTLENGTH + 3 * p_bytes) { DSA_free(dsa); return (DST_R_INVALIDPUBLICKEY); } dsa->q = BN_bin2bn(r.base, ISC_SHA1_DIGESTLENGTH, NULL); isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); dsa->p = BN_bin2bn(r.base, p_bytes, NULL); isc_region_consume(&r, p_bytes); dsa->g = BN_bin2bn(r.base, p_bytes, NULL); isc_region_consume(&r, p_bytes); dsa->pub_key = BN_bin2bn(r.base, p_bytes, NULL); isc_region_consume(&r, p_bytes); key->key_size = p_bytes * 8; isc_buffer_forward(data, 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes); key->keydata.dsa = dsa; return (ISC_R_SUCCESS); } static isc_result_t openssldsa_tofile(const dst_key_t *key, const char *directory) { int cnt = 0; DSA *dsa; dst_private_t priv; unsigned char bufs[5][128]; if (key->keydata.dsa == NULL) return (DST_R_NULLKEY); if (key->external) { priv.nelements = 0; return (dst__privstruct_writefile(key, &priv, directory)); } dsa = key->keydata.dsa; priv.elements[cnt].tag = TAG_DSA_PRIME; priv.elements[cnt].length = BN_num_bytes(dsa->p); BN_bn2bin(dsa->p, bufs[cnt]); priv.elements[cnt].data = bufs[cnt]; cnt++; priv.elements[cnt].tag = TAG_DSA_SUBPRIME; priv.elements[cnt].length = BN_num_bytes(dsa->q); BN_bn2bin(dsa->q, bufs[cnt]); priv.elements[cnt].data = bufs[cnt]; cnt++; priv.elements[cnt].tag = TAG_DSA_BASE; priv.elements[cnt].length = BN_num_bytes(dsa->g); BN_bn2bin(dsa->g, bufs[cnt]); priv.elements[cnt].data = bufs[cnt]; cnt++; priv.elements[cnt].tag = TAG_DSA_PRIVATE; priv.elements[cnt].length = BN_num_bytes(dsa->priv_key); BN_bn2bin(dsa->priv_key, bufs[cnt]); priv.elements[cnt].data = bufs[cnt]; cnt++; priv.elements[cnt].tag = TAG_DSA_PUBLIC; priv.elements[cnt].length = BN_num_bytes(dsa->pub_key); BN_bn2bin(dsa->pub_key, bufs[cnt]); priv.elements[cnt].data = bufs[cnt]; cnt++; priv.nelements = cnt; return (dst__privstruct_writefile(key, &priv, directory)); } static isc_result_t openssldsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t ret; int i; DSA *dsa = NULL; isc_mem_t *mctx = key->mctx; #define DST_RET(a) {ret = a; goto err;} /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_DSA, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) return (ret); if (key->external) { if (priv.nelements != 0) DST_RET(DST_R_INVALIDPRIVATEKEY); if (pub == NULL) DST_RET(DST_R_INVALIDPRIVATEKEY); key->keydata.pkey = pub->keydata.pkey; pub->keydata.pkey = NULL; key->key_size = pub->key_size; dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ISC_R_SUCCESS); } dsa = DSA_new(); if (dsa == NULL) DST_RET(ISC_R_NOMEMORY); dsa->flags &= ~DSA_FLAG_CACHE_MONT_P; key->keydata.dsa = dsa; for (i = 0; i < priv.nelements; i++) { BIGNUM *bn; bn = BN_bin2bn(priv.elements[i].data, priv.elements[i].length, NULL); if (bn == NULL) DST_RET(ISC_R_NOMEMORY); switch (priv.elements[i].tag) { case TAG_DSA_PRIME: dsa->p = bn; break; case TAG_DSA_SUBPRIME: dsa->q = bn; break; case TAG_DSA_BASE: dsa->g = bn; break; case TAG_DSA_PRIVATE: dsa->priv_key = bn; break; case TAG_DSA_PUBLIC: dsa->pub_key = bn; break; } } dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); key->key_size = BN_num_bits(dsa->p); return (ISC_R_SUCCESS); err: openssldsa_destroy(key); dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ret); } static dst_func_t openssldsa_functions = { openssldsa_createctx, NULL, /*%< createctx2 */ openssldsa_destroyctx, openssldsa_adddata, openssldsa_sign, openssldsa_verify, NULL, /*%< verify2 */ NULL, /*%< computesecret */ openssldsa_compare, NULL, /*%< paramcompare */ openssldsa_generate, openssldsa_isprivate, openssldsa_destroy, openssldsa_todns, openssldsa_fromdns, openssldsa_tofile, openssldsa_parse, NULL, /*%< cleanup */ NULL, /*%< fromlabel */ NULL, /*%< dump */ NULL, /*%< restore */ }; isc_result_t dst__openssldsa_init(dst_func_t **funcp) { REQUIRE(funcp != NULL); if (*funcp == NULL) *funcp = &openssldsa_functions; return (ISC_R_SUCCESS); } #else /* OPENSSL */ #include EMPTY_TRANSLATION_UNIT #endif /* OPENSSL */ /*! \file */ bind9-9.10.3.dfsg.P4/lib/dns/diff.c0000644000470500017500000004007512664710322016005 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007-2009, 2011, 2013-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: diff.c,v 1.26 2011/03/25 23:53:02 each Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define CHECK(op) \ do { result = (op); \ if (result != ISC_R_SUCCESS) goto failure; \ } while (0) #define DIFF_COMMON_LOGARGS \ dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_DIFF static dns_rdatatype_t rdata_covers(dns_rdata_t *rdata) { return (rdata->type == dns_rdatatype_rrsig ? dns_rdata_covers(rdata) : 0); } isc_result_t dns_difftuple_create(isc_mem_t *mctx, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata, dns_difftuple_t **tp) { dns_difftuple_t *t; unsigned int size; unsigned char *datap; REQUIRE(tp != NULL && *tp == NULL); /* * Create a new tuple. The variable-size wire-format name data and * rdata immediately follow the dns_difftuple_t structure * in memory. */ size = sizeof(*t) + name->length + rdata->length; t = isc_mem_allocate(mctx, size); if (t == NULL) return (ISC_R_NOMEMORY); t->mctx = NULL; isc_mem_attach(mctx, &t->mctx); t->op = op; datap = (unsigned char *)(t + 1); memmove(datap, name->ndata, name->length); dns_name_init(&t->name, NULL); dns_name_clone(name, &t->name); t->name.ndata = datap; datap += name->length; t->ttl = ttl; memmove(datap, rdata->data, rdata->length); dns_rdata_init(&t->rdata); dns_rdata_clone(rdata, &t->rdata); t->rdata.data = datap; datap += rdata->length; ISC_LINK_INIT(&t->rdata, link); ISC_LINK_INIT(t, link); t->magic = DNS_DIFFTUPLE_MAGIC; INSIST(datap == (unsigned char *)t + size); *tp = t; return (ISC_R_SUCCESS); } void dns_difftuple_free(dns_difftuple_t **tp) { dns_difftuple_t *t = *tp; isc_mem_t *mctx; REQUIRE(DNS_DIFFTUPLE_VALID(t)); dns_name_invalidate(&t->name); t->magic = 0; mctx = t->mctx; isc_mem_free(mctx, t); isc_mem_detach(&mctx); *tp = NULL; } isc_result_t dns_difftuple_copy(dns_difftuple_t *orig, dns_difftuple_t **copyp) { return (dns_difftuple_create(orig->mctx, orig->op, &orig->name, orig->ttl, &orig->rdata, copyp)); } void dns_diff_init(isc_mem_t *mctx, dns_diff_t *diff) { diff->mctx = mctx; ISC_LIST_INIT(diff->tuples); diff->magic = DNS_DIFF_MAGIC; } void dns_diff_clear(dns_diff_t *diff) { dns_difftuple_t *t; REQUIRE(DNS_DIFF_VALID(diff)); while ((t = ISC_LIST_HEAD(diff->tuples)) != NULL) { ISC_LIST_UNLINK(diff->tuples, t, link); dns_difftuple_free(&t); } ENSURE(ISC_LIST_EMPTY(diff->tuples)); } void dns_diff_append(dns_diff_t *diff, dns_difftuple_t **tuplep) { ISC_LIST_APPEND(diff->tuples, *tuplep, link); *tuplep = NULL; } /* XXX this is O(N) */ void dns_diff_appendminimal(dns_diff_t *diff, dns_difftuple_t **tuplep) { dns_difftuple_t *ot, *next_ot; REQUIRE(DNS_DIFF_VALID(diff)); REQUIRE(DNS_DIFFTUPLE_VALID(*tuplep)); /* * Look for an existing tuple with the same owner name, * rdata, and TTL. If we are doing an addition and find a * deletion or vice versa, remove both the old and the * new tuple since they cancel each other out (assuming * that we never delete nonexistent data or add existing * data). * * If we find an old update of the same kind as * the one we are doing, there must be a programming * error. We report it but try to continue anyway. */ for (ot = ISC_LIST_HEAD(diff->tuples); ot != NULL; ot = next_ot) { next_ot = ISC_LIST_NEXT(ot, link); if (dns_name_equal(&ot->name, &(*tuplep)->name) && dns_rdata_compare(&ot->rdata, &(*tuplep)->rdata) == 0 && ot->ttl == (*tuplep)->ttl) { ISC_LIST_UNLINK(diff->tuples, ot, link); if ((*tuplep)->op == ot->op) { UNEXPECTED_ERROR(__FILE__, __LINE__, "unexpected non-minimal diff"); } else { dns_difftuple_free(tuplep); } dns_difftuple_free(&ot); break; } } if (*tuplep != NULL) { ISC_LIST_APPEND(diff->tuples, *tuplep, link); *tuplep = NULL; } ENSURE(*tuplep == NULL); } static isc_stdtime_t setresign(dns_rdataset_t *modified) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_rrsig_t sig; isc_stdtime_t when; isc_result_t result; result = dns_rdataset_first(modified); INSIST(result == ISC_R_SUCCESS); dns_rdataset_current(modified, &rdata); (void)dns_rdata_tostruct(&rdata, &sig, NULL); if ((rdata.flags & DNS_RDATA_OFFLINE) != 0) when = 0; else when = sig.timeexpire; dns_rdata_reset(&rdata); result = dns_rdataset_next(modified); while (result == ISC_R_SUCCESS) { dns_rdataset_current(modified, &rdata); (void)dns_rdata_tostruct(&rdata, &sig, NULL); if ((rdata.flags & DNS_RDATA_OFFLINE) != 0) { goto next_rr; } if (when == 0 || sig.timeexpire < when) when = sig.timeexpire; next_rr: dns_rdata_reset(&rdata); result = dns_rdataset_next(modified); } INSIST(result == ISC_R_NOMORE); return (when); } static isc_result_t diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver, isc_boolean_t warn) { dns_difftuple_t *t; dns_dbnode_t *node = NULL; isc_result_t result; char namebuf[DNS_NAME_FORMATSIZE]; char typebuf[DNS_RDATATYPE_FORMATSIZE]; char classbuf[DNS_RDATACLASS_FORMATSIZE]; REQUIRE(DNS_DIFF_VALID(diff)); REQUIRE(DNS_DB_VALID(db)); t = ISC_LIST_HEAD(diff->tuples); while (t != NULL) { dns_name_t *name; INSIST(node == NULL); name = &t->name; /* * Find the node. * We create the node if it does not exist. * This will cause an empty node to be created if the diff * contains a deletion of an RR at a nonexistent name, * but such diffs should never be created in the first * place. */ while (t != NULL && dns_name_equal(&t->name, name)) { dns_rdatatype_t type, covers; dns_diffop_t op; dns_rdatalist_t rdl; dns_rdataset_t rds; dns_rdataset_t ardataset; dns_rdataset_t *modified = NULL; op = t->op; type = t->rdata.type; covers = rdata_covers(&t->rdata); /* * Collect a contiguous set of updates with * the same operation (add/delete) and RR type * into a single rdatalist so that the * database rrset merging/subtraction code * can work more efficiently than if each * RR were merged into / subtracted from * the database separately. * * This is done by linking rdata structures from the * diff into "rdatalist". This uses the rdata link * field, not the diff link field, so the structure * of the diff itself is not affected. */ dns_rdatalist_init(&rdl); rdl.type = type; rdl.covers = covers; rdl.rdclass = t->rdata.rdclass; rdl.ttl = t->ttl; node = NULL; if (type != dns_rdatatype_nsec3 && covers != dns_rdatatype_nsec3) CHECK(dns_db_findnode(db, name, ISC_TRUE, &node)); else CHECK(dns_db_findnsec3node(db, name, ISC_TRUE, &node)); while (t != NULL && dns_name_equal(&t->name, name) && t->op == op && t->rdata.type == type && rdata_covers(&t->rdata) == covers) { dns_name_format(name, namebuf, sizeof(namebuf)); dns_rdatatype_format(t->rdata.type, typebuf, sizeof(typebuf)); dns_rdataclass_format(t->rdata.rdclass, classbuf, sizeof(classbuf)); if (t->ttl != rdl.ttl && warn) isc_log_write(DIFF_COMMON_LOGARGS, ISC_LOG_WARNING, "'%s/%s/%s': TTL differs in " "rdataset, adjusting " "%lu -> %lu", namebuf, typebuf, classbuf, (unsigned long) t->ttl, (unsigned long) rdl.ttl); ISC_LIST_APPEND(rdl.rdata, &t->rdata, link); t = ISC_LIST_NEXT(t, link); } /* * Convert the rdatalist into a rdataset. */ dns_rdataset_init(&rds); CHECK(dns_rdatalist_tordataset(&rdl, &rds)); if (rds.type == dns_rdatatype_rrsig) switch (op) { case DNS_DIFFOP_ADDRESIGN: case DNS_DIFFOP_DELRESIGN: modified = &ardataset; dns_rdataset_init(modified); break; default: break; } rds.trust = dns_trust_ultimate; /* * Merge the rdataset into the database. */ switch (op) { case DNS_DIFFOP_ADD: case DNS_DIFFOP_ADDRESIGN: result = dns_db_addrdataset(db, node, ver, 0, &rds, DNS_DBADD_MERGE| DNS_DBADD_EXACT| DNS_DBADD_EXACTTTL, modified); break; case DNS_DIFFOP_DEL: case DNS_DIFFOP_DELRESIGN: result = dns_db_subtractrdataset(db, node, ver, &rds, DNS_DBSUB_EXACT, modified); break; default: INSIST(0); } if (result == ISC_R_SUCCESS) { if (modified != NULL) { isc_stdtime_t resign; resign = setresign(modified); dns_db_setsigningtime(db, modified, resign); } } else if (result == DNS_R_UNCHANGED) { /* * This will not happen when executing a * dynamic update, because that code will * generate strictly minimal diffs. * It may happen when receiving an IXFR * from a server that is not as careful. * Issue a warning and continue. */ if (warn) { dns_name_format(dns_db_origin(db), namebuf, sizeof(namebuf)); dns_rdataclass_format(dns_db_class(db), classbuf, sizeof(classbuf)); isc_log_write(DIFF_COMMON_LOGARGS, ISC_LOG_WARNING, "%s/%s: dns_diff_apply: " "update with no effect", namebuf, classbuf); } } else if (result == DNS_R_NXRRSET) { /* * OK. */ } else { if (modified != NULL && dns_rdataset_isassociated(modified)) dns_rdataset_disassociate(modified); CHECK(result); } dns_db_detachnode(db, &node); if (modified != NULL && dns_rdataset_isassociated(modified)) dns_rdataset_disassociate(modified); } } return (ISC_R_SUCCESS); failure: if (node != NULL) dns_db_detachnode(db, &node); return (result); } isc_result_t dns_diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver) { return (diff_apply(diff, db, ver, ISC_TRUE)); } isc_result_t dns_diff_applysilently(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver) { return (diff_apply(diff, db, ver, ISC_FALSE)); } /* XXX this duplicates lots of code in diff_apply(). */ isc_result_t dns_diff_load(dns_diff_t *diff, dns_addrdatasetfunc_t addfunc, void *add_private) { dns_difftuple_t *t; isc_result_t result; REQUIRE(DNS_DIFF_VALID(diff)); t = ISC_LIST_HEAD(diff->tuples); while (t != NULL) { dns_name_t *name; name = &t->name; while (t != NULL && dns_name_equal(&t->name, name)) { dns_rdatatype_t type, covers; dns_diffop_t op; dns_rdatalist_t rdl; dns_rdataset_t rds; op = t->op; type = t->rdata.type; covers = rdata_covers(&t->rdata); dns_rdatalist_init(&rdl); rdl.type = type; rdl.covers = covers; rdl.rdclass = t->rdata.rdclass; rdl.ttl = t->ttl; while (t != NULL && dns_name_equal(&t->name, name) && t->op == op && t->rdata.type == type && rdata_covers(&t->rdata) == covers) { ISC_LIST_APPEND(rdl.rdata, &t->rdata, link); t = ISC_LIST_NEXT(t, link); } /* * Convert the rdatalist into a rdataset. */ dns_rdataset_init(&rds); CHECK(dns_rdatalist_tordataset(&rdl, &rds)); rds.trust = dns_trust_ultimate; INSIST(op == DNS_DIFFOP_ADD); result = (*addfunc)(add_private, name, &rds); if (result == DNS_R_UNCHANGED) { isc_log_write(DIFF_COMMON_LOGARGS, ISC_LOG_WARNING, "dns_diff_load: " "update with no effect"); } else if (result == ISC_R_SUCCESS || result == DNS_R_NXRRSET) { /* * OK. */ } else { CHECK(result); } } } result = ISC_R_SUCCESS; failure: return (result); } /* * XXX uses qsort(); a merge sort would be more natural for lists, * and perhaps safer wrt thread stack overflow. */ isc_result_t dns_diff_sort(dns_diff_t *diff, dns_diff_compare_func *compare) { unsigned int length = 0; unsigned int i; dns_difftuple_t **v; dns_difftuple_t *p; REQUIRE(DNS_DIFF_VALID(diff)); for (p = ISC_LIST_HEAD(diff->tuples); p != NULL; p = ISC_LIST_NEXT(p, link)) length++; if (length == 0) return (ISC_R_SUCCESS); v = isc_mem_get(diff->mctx, length * sizeof(dns_difftuple_t *)); if (v == NULL) return (ISC_R_NOMEMORY); for (i = 0; i < length; i++) { p = ISC_LIST_HEAD(diff->tuples); v[i] = p; ISC_LIST_UNLINK(diff->tuples, p, link); } INSIST(ISC_LIST_HEAD(diff->tuples) == NULL); qsort(v, length, sizeof(v[0]), compare); for (i = 0; i < length; i++) { ISC_LIST_APPEND(diff->tuples, v[i], link); } isc_mem_put(diff->mctx, v, length * sizeof(dns_difftuple_t *)); return (ISC_R_SUCCESS); } /* * Create an rdataset containing the single RR of the given * tuple. The caller must allocate the rdata, rdataset and * an rdatalist structure for it to refer to. */ static isc_result_t diff_tuple_tordataset(dns_difftuple_t *t, dns_rdata_t *rdata, dns_rdatalist_t *rdl, dns_rdataset_t *rds) { REQUIRE(DNS_DIFFTUPLE_VALID(t)); REQUIRE(rdl != NULL); REQUIRE(rds != NULL); dns_rdatalist_init(rdl); rdl->type = t->rdata.type; rdl->rdclass = t->rdata.rdclass; rdl->ttl = t->ttl; dns_rdataset_init(rds); ISC_LINK_INIT(rdata, link); dns_rdata_clone(&t->rdata, rdata); ISC_LIST_APPEND(rdl->rdata, rdata, link); return (dns_rdatalist_tordataset(rdl, rds)); } isc_result_t dns_diff_print(dns_diff_t *diff, FILE *file) { isc_result_t result; dns_difftuple_t *t; char *mem = NULL; unsigned int size = 2048; const char *op = NULL; REQUIRE(DNS_DIFF_VALID(diff)); mem = isc_mem_get(diff->mctx, size); if (mem == NULL) return (ISC_R_NOMEMORY); for (t = ISC_LIST_HEAD(diff->tuples); t != NULL; t = ISC_LIST_NEXT(t, link)) { isc_buffer_t buf; isc_region_t r; dns_rdatalist_t rdl; dns_rdataset_t rds; dns_rdata_t rd = DNS_RDATA_INIT; result = diff_tuple_tordataset(t, &rd, &rdl, &rds); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "diff_tuple_tordataset failed: %s", dns_result_totext(result)); result = ISC_R_UNEXPECTED; goto cleanup; } again: isc_buffer_init(&buf, mem, size); result = dns_rdataset_totext(&rds, &t->name, ISC_FALSE, ISC_FALSE, &buf); if (result == ISC_R_NOSPACE) { isc_mem_put(diff->mctx, mem, size); size += 1024; mem = isc_mem_get(diff->mctx, size); if (mem == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } goto again; } if (result != ISC_R_SUCCESS) goto cleanup; /* * Get rid of final newline. */ INSIST(buf.used >= 1 && ((char *) buf.base)[buf.used-1] == '\n'); buf.used--; isc_buffer_usedregion(&buf, &r); switch (t->op) { case DNS_DIFFOP_EXISTS: op = "exists"; break; case DNS_DIFFOP_ADD: op = "add"; break; case DNS_DIFFOP_DEL: op = "del"; break; case DNS_DIFFOP_ADDRESIGN: op = "add re-sign"; break; case DNS_DIFFOP_DELRESIGN: op = "del re-sign"; break; } if (file != NULL) fprintf(file, "%s %.*s\n", op, (int) r.length, (char *) r.base); else isc_log_write(DIFF_COMMON_LOGARGS, ISC_LOG_DEBUG(7), "%s %.*s", op, (int) r.length, (char *) r.base); } result = ISC_R_SUCCESS; cleanup: if (mem != NULL) isc_mem_put(diff->mctx, mem, size); return (result); } bind9-9.10.3.dfsg.P4/lib/dns/order.c0000644000470500017500000001071712664710322016210 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: order.c,v 1.10 2007/06/19 23:47:16 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include typedef struct dns_order_ent dns_order_ent_t; struct dns_order_ent { dns_fixedname_t name; dns_rdataclass_t rdclass; dns_rdatatype_t rdtype; unsigned int mode; ISC_LINK(dns_order_ent_t) link; }; struct dns_order { unsigned int magic; isc_refcount_t references; ISC_LIST(dns_order_ent_t) ents; isc_mem_t *mctx; }; #define DNS_ORDER_MAGIC ISC_MAGIC('O','r','d','r') #define DNS_ORDER_VALID(order) ISC_MAGIC_VALID(order, DNS_ORDER_MAGIC) isc_result_t dns_order_create(isc_mem_t *mctx, dns_order_t **orderp) { dns_order_t *order; isc_result_t result; REQUIRE(orderp != NULL && *orderp == NULL); order = isc_mem_get(mctx, sizeof(*order)); if (order == NULL) return (ISC_R_NOMEMORY); ISC_LIST_INIT(order->ents); /* Implicit attach. */ result = isc_refcount_init(&order->references, 1); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, order, sizeof(*order)); return (result); } order->mctx = NULL; isc_mem_attach(mctx, &order->mctx); order->magic = DNS_ORDER_MAGIC; *orderp = order; return (ISC_R_SUCCESS); } isc_result_t dns_order_add(dns_order_t *order, dns_name_t *name, dns_rdatatype_t rdtype, dns_rdataclass_t rdclass, unsigned int mode) { dns_order_ent_t *ent; REQUIRE(DNS_ORDER_VALID(order)); REQUIRE(mode == DNS_RDATASETATTR_RANDOMIZE || mode == DNS_RDATASETATTR_FIXEDORDER || mode == 0 /* DNS_RDATASETATTR_CYCLIC */ ); ent = isc_mem_get(order->mctx, sizeof(*ent)); if (ent == NULL) return (ISC_R_NOMEMORY); dns_fixedname_init(&ent->name); RUNTIME_CHECK(dns_name_copy(name, dns_fixedname_name(&ent->name), NULL) == ISC_R_SUCCESS); ent->rdtype = rdtype; ent->rdclass = rdclass; ent->mode = mode; ISC_LINK_INIT(ent, link); ISC_LIST_INITANDAPPEND(order->ents, ent, link); return (ISC_R_SUCCESS); } static inline isc_boolean_t match(dns_name_t *name1, dns_name_t *name2) { if (dns_name_iswildcard(name2)) return(dns_name_matcheswildcard(name1, name2)); return (dns_name_equal(name1, name2)); } unsigned int dns_order_find(dns_order_t *order, dns_name_t *name, dns_rdatatype_t rdtype, dns_rdataclass_t rdclass) { dns_order_ent_t *ent; REQUIRE(DNS_ORDER_VALID(order)); for (ent = ISC_LIST_HEAD(order->ents); ent != NULL; ent = ISC_LIST_NEXT(ent, link)) { if (ent->rdtype != rdtype && ent->rdtype != dns_rdatatype_any) continue; if (ent->rdclass != rdclass && ent->rdclass != dns_rdataclass_any) continue; if (match(name, dns_fixedname_name(&ent->name))) return (ent->mode); } return (DNS_RDATASETATTR_RANDOMIZE); } void dns_order_attach(dns_order_t *source, dns_order_t **target) { REQUIRE(DNS_ORDER_VALID(source)); REQUIRE(target != NULL && *target == NULL); isc_refcount_increment(&source->references, NULL); *target = source; } void dns_order_detach(dns_order_t **orderp) { dns_order_t *order; dns_order_ent_t *ent; unsigned int references; REQUIRE(orderp != NULL); order = *orderp; REQUIRE(DNS_ORDER_VALID(order)); isc_refcount_decrement(&order->references, &references); *orderp = NULL; if (references != 0) return; order->magic = 0; while ((ent = ISC_LIST_HEAD(order->ents)) != NULL) { ISC_LIST_UNLINK(order->ents, ent, link); isc_mem_put(order->mctx, ent, sizeof(*ent)); } isc_refcount_destroy(&order->references); isc_mem_putanddetach(&order->mctx, order, sizeof(*order)); } bind9-9.10.3.dfsg.P4/lib/dns/dst_gost.h0000644000470500017500000000301212664710322016716 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef DST_GOST_H #define DST_GOST_H 1 #include #include #include #define ISC_GOST_DIGESTLENGTH 32U #ifdef HAVE_OPENSSL_GOST #include typedef EVP_MD_CTX isc_gost_t; #endif #ifdef HAVE_PKCS11_GOST #include typedef pk11_context_t isc_gost_t; #endif ISC_LANG_BEGINDECLS #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) isc_result_t isc_gost_init(isc_gost_t *ctx); void isc_gost_invalidate(isc_gost_t *ctx); isc_result_t isc_gost_update(isc_gost_t *ctx, const unsigned char *data, unsigned int len); isc_result_t isc_gost_final(isc_gost_t *ctx, unsigned char *digest); ISC_LANG_ENDDECLS #endif /* HAVE_OPENSSL_GOST || HAVE_PKCS11_GOST */ #endif /* DST_GOST_H */ bind9-9.10.3.dfsg.P4/lib/dns/keydata.c0000644000470500017500000000511412664710322016512 0ustar lamontlamont/* * Copyright (C) 2009, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: keydata.c,v 1.3 2009/07/01 23:47:36 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include isc_result_t dns_keydata_todnskey(dns_rdata_keydata_t *keydata, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) { REQUIRE(keydata != NULL && dnskey != NULL); dnskey->common.rdtype = dns_rdatatype_dnskey; dnskey->common.rdclass = keydata->common.rdclass; dnskey->mctx = mctx; dnskey->flags = keydata->flags; dnskey->protocol = keydata->protocol; dnskey->algorithm = keydata->algorithm; dnskey->datalen = keydata->datalen; if (mctx == NULL) dnskey->data = keydata->data; else { dnskey->data = isc_mem_allocate(mctx, dnskey->datalen); if (dnskey->data == NULL) return (ISC_R_NOMEMORY); memmove(dnskey->data, keydata->data, dnskey->datalen); } return (ISC_R_SUCCESS); } isc_result_t dns_keydata_fromdnskey(dns_rdata_keydata_t *keydata, dns_rdata_dnskey_t *dnskey, isc_uint32_t refresh, isc_uint32_t addhd, isc_uint32_t removehd, isc_mem_t *mctx) { REQUIRE(keydata != NULL && dnskey != NULL); keydata->common.rdtype = dns_rdatatype_keydata; keydata->common.rdclass = dnskey->common.rdclass; keydata->mctx = mctx; keydata->refresh = refresh; keydata->addhd = addhd; keydata->removehd = removehd; keydata->flags = dnskey->flags; keydata->protocol = dnskey->protocol; keydata->algorithm = dnskey->algorithm; keydata->datalen = dnskey->datalen; if (mctx == NULL) keydata->data = dnskey->data; else { keydata->data = isc_mem_allocate(mctx, keydata->datalen); if (keydata->data == NULL) return (ISC_R_NOMEMORY); memmove(keydata->data, dnskey->data, keydata->datalen); } return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/dns/zonekey.c0000644000470500017500000000327112664710322016556 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: zonekey.c,v 1.9 2007/06/19 23:47:16 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include isc_boolean_t dns_zonekey_iszonekey(dns_rdata_t *keyrdata) { isc_result_t result; dns_rdata_dnskey_t key; isc_boolean_t iszonekey = ISC_TRUE; REQUIRE(keyrdata != NULL); result = dns_rdata_tostruct(keyrdata, &key, NULL); if (result != ISC_R_SUCCESS) return (ISC_FALSE); if ((key.flags & DNS_KEYTYPE_NOAUTH) != 0) iszonekey = ISC_FALSE; if ((key.flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE) iszonekey = ISC_FALSE; if (key.protocol != DNS_KEYPROTO_DNSSEC && key.protocol != DNS_KEYPROTO_ANY) iszonekey = ISC_FALSE; return (iszonekey); } bind9-9.10.3.dfsg.P4/lib/dns/rdata/0002755000470500017500000000000012672612753016030 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/dns/rdata/ch_3/0002755000470500017500000000000012672612753016644 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/dns/rdata/ch_3/a_1.c0000644000470500017500000001760612664710322017450 0ustar lamontlamont/* * Copyright (C) 2005, 2007, 2009, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: a_1.c,v 1.8 2009/12/04 22:06:37 tbox Exp $ */ /* by Bjorn.Victor@it.uu.se, 2005-05-07 */ /* Based on generic/soa_6.c and generic/mx_15.c */ #ifndef RDATA_CH_3_A_1_C #define RDATA_CH_3_A_1_C #include #define RRTYPE_A_ATTRIBUTES (0) static inline isc_result_t fromtext_ch_a(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; REQUIRE(type == dns_rdatatype_a); REQUIRE(rdclass == dns_rdataclass_ch); /* 3 */ UNUSED(type); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); /* get domain name */ dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); if ((options & DNS_RDATA_CHECKNAMES) != 0 && (options & DNS_RDATA_CHECKREVERSE) != 0) { isc_boolean_t ok; ok = dns_name_ishostname(&name, ISC_FALSE); if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) RETTOK(DNS_R_BADNAME); if (!ok && callbacks != NULL) warn_badname(&name, lexer, callbacks); } /* 16-bit octal address */ RETERR(isc_lex_getoctaltoken(lexer, &token, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); return (uint16_tobuffer(token.value.as_ulong, target)); } static inline isc_result_t totext_ch_a(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; char buf[sizeof("0177777")]; isc_uint16_t addr; REQUIRE(rdata->type == dns_rdatatype_a); REQUIRE(rdata->rdclass == dns_rdataclass_ch); /* 3 */ REQUIRE(rdata->length != 0); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); isc_region_consume(®ion, name_length(&name)); addr = uint16_fromregion(®ion); sub = name_prefix(&name, tctx->origin, &prefix); RETERR(dns_name_totext(&prefix, sub, target)); sprintf(buf, "%o", addr); /* note octal */ RETERR(str_totext(" ", target)); return (str_totext(buf, target)); } static inline isc_result_t fromwire_ch_a(ARGS_FROMWIRE) { isc_region_t sregion; isc_region_t tregion; dns_name_t name; REQUIRE(type == dns_rdatatype_a); REQUIRE(rdclass == dns_rdataclass_ch); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, NULL); RETERR(dns_name_fromwire(&name, source, dctx, options, target)); isc_buffer_activeregion(source, &sregion); isc_buffer_availableregion(target, &tregion); if (sregion.length < 2) return (ISC_R_UNEXPECTEDEND); if (tregion.length < 2) return (ISC_R_NOSPACE); memmove(tregion.base, sregion.base, 2); isc_buffer_forward(source, 2); isc_buffer_add(target, 2); return (ISC_R_SUCCESS); } static inline isc_result_t towire_ch_a(ARGS_TOWIRE) { dns_name_t name; dns_offsets_t offsets; isc_region_t sregion; isc_region_t tregion; REQUIRE(rdata->type == dns_rdatatype_a); REQUIRE(rdata->rdclass == dns_rdataclass_ch); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, &sregion); dns_name_fromregion(&name, &sregion); isc_region_consume(&sregion, name_length(&name)); RETERR(dns_name_towire(&name, cctx, target)); isc_buffer_availableregion(target, &tregion); if (tregion.length < 2) return (ISC_R_NOSPACE); memmove(tregion.base, sregion.base, 2); isc_buffer_add(target, 2); return (ISC_R_SUCCESS); } static inline int compare_ch_a(ARGS_COMPARE) { dns_name_t name1; dns_name_t name2; isc_region_t region1; isc_region_t region2; int order; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_a); REQUIRE(rdata1->rdclass == dns_rdataclass_ch); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); isc_region_consume(®ion1, name_length(&name1)); isc_region_consume(®ion2, name_length(&name2)); order = dns_name_rdatacompare(&name1, &name2); if (order != 0) return (order); order = memcmp(rdata1->data, rdata2->data, 2); if (order != 0) order = (order < 0) ? -1 : 1; return (order); } static inline isc_result_t fromstruct_ch_a(ARGS_FROMSTRUCT) { dns_rdata_ch_a_t *a = source; isc_region_t region; REQUIRE(type == dns_rdatatype_a); REQUIRE(source != NULL); REQUIRE(a->common.rdtype == type); REQUIRE(a->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); dns_name_toregion(&a->ch_addr_dom, ®ion); RETERR(isc_buffer_copyregion(target, ®ion)); return (uint16_tobuffer(ntohs(a->ch_addr), target)); } static inline isc_result_t tostruct_ch_a(ARGS_TOSTRUCT) { dns_rdata_ch_a_t *a = target; isc_region_t region; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_a); REQUIRE(rdata->rdclass == dns_rdataclass_ch); REQUIRE(rdata->length != 0); a->common.rdclass = rdata->rdclass; a->common.rdtype = rdata->type; ISC_LINK_INIT(&a->common, link); dns_rdata_toregion(rdata, ®ion); dns_name_init(&name, NULL); dns_name_fromregion(&name, ®ion); isc_region_consume(®ion, name_length(&name)); dns_name_init(&a->ch_addr_dom, NULL); RETERR(name_duporclone(&name, mctx, &a->ch_addr_dom)); a->ch_addr = htons(uint16_fromregion(®ion)); a->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_ch_a(ARGS_FREESTRUCT) { dns_rdata_ch_a_t *a = source; REQUIRE(source != NULL); REQUIRE(a->common.rdtype == dns_rdatatype_a); if (a->mctx == NULL) return; dns_name_free(&a->ch_addr_dom, a->mctx); a->mctx = NULL; } static inline isc_result_t additionaldata_ch_a(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_a); REQUIRE(rdata->rdclass == dns_rdataclass_ch); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_ch_a(ARGS_DIGEST) { isc_region_t r; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_a); REQUIRE(rdata->rdclass == dns_rdataclass_ch); dns_rdata_toregion(rdata, &r); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); isc_region_consume(&r, name_length(&name)); RETERR(dns_name_digest(&name, digest, arg)); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_ch_a(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_a); REQUIRE(rdclass == dns_rdataclass_ch); UNUSED(type); return (dns_name_ishostname(name, wildcard)); } static inline isc_boolean_t checknames_ch_a(ARGS_CHECKNAMES) { isc_region_t region; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_a); REQUIRE(rdata->rdclass == dns_rdataclass_ch); UNUSED(owner); dns_rdata_toregion(rdata, ®ion); dns_name_init(&name, NULL); dns_name_fromregion(&name, ®ion); if (!dns_name_ishostname(&name, ISC_FALSE)) { if (bad != NULL) dns_name_clone(&name, bad); return (ISC_FALSE); } return (ISC_TRUE); } static inline int casecompare_ch_a(ARGS_COMPARE) { return (compare_ch_a(rdata1, rdata2)); } #endif /* RDATA_CH_3_A_1_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/ch_3/a_1.h0000644000470500017500000000234712664710322017451 0ustar lamontlamont/* * Copyright (C) 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: a_1.h,v 1.5 2007/06/19 23:47:17 tbox Exp $ */ /* by Bjorn.Victor@it.uu.se, 2005-05-07 */ /* Based on generic/mx_15.h */ #ifndef CH_3_A_1_H #define CH_3_A_1_H 1 typedef isc_uint16_t ch_addr_t; typedef struct dns_rdata_ch_a { dns_rdatacommon_t common; isc_mem_t *mctx; dns_name_t ch_addr_dom; /* ch-addr domain for back mapping */ ch_addr_t ch_addr; /* chaos address (16 bit) network order */ } dns_rdata_ch_a_t; #endif /* CH_3_A_1_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/any_255/0002755000470500017500000000000012672612753017212 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/dns/rdata/any_255/tsig_250.h0000644000470500017500000000251712664710322020712 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: tsig_250.h,v 1.25 2007/06/19 23:47:17 tbox Exp $ */ #ifndef ANY_255_TSIG_250_H #define ANY_255_TSIG_250_H 1 /*% RFC2845 */ typedef struct dns_rdata_any_tsig { dns_rdatacommon_t common; isc_mem_t * mctx; dns_name_t algorithm; isc_uint64_t timesigned; isc_uint16_t fudge; isc_uint16_t siglen; unsigned char * signature; isc_uint16_t originalid; isc_uint16_t error; isc_uint16_t otherlen; unsigned char * other; } dns_rdata_any_tsig_t; #endif /* ANY_255_TSIG_250_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/any_255/tsig_250.c0000644000470500017500000003343612664710322020711 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* Reviewed: Thu Mar 16 13:39:43 PST 2000 by gson */ #ifndef RDATA_ANY_255_TSIG_250_C #define RDATA_ANY_255_TSIG_250_C #define RRTYPE_TSIG_ATTRIBUTES \ (DNS_RDATATYPEATTR_META | DNS_RDATATYPEATTR_NOTQUESTION) static inline isc_result_t fromtext_any_tsig(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_uint64_t sigtime; isc_buffer_t buffer; dns_rcode_t rcode; long i; char *e; REQUIRE(type == dns_rdatatype_tsig); REQUIRE(rdclass == dns_rdataclass_any); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); /* * Algorithm Name. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); /* * Time Signed: 48 bits. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); sigtime = isc_string_touint64(DNS_AS_STR(token), &e, 10); if (*e != 0) RETTOK(DNS_R_SYNTAX); if ((sigtime >> 48) != 0) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer((isc_uint16_t)(sigtime >> 32), target)); RETERR(uint32_tobuffer((isc_uint32_t)(sigtime & 0xffffffffU), target)); /* * Fudge. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Signature Size. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Signature. */ RETERR(isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong)); /* * Original ID. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Error. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (dns_tsigrcode_fromtext(&rcode, &token.value.as_textregion) != ISC_R_SUCCESS) { i = strtol(DNS_AS_STR(token), &e, 10); if (*e != 0) RETTOK(DNS_R_UNKNOWN); if (i < 0 || i > 0xffff) RETTOK(ISC_R_RANGE); rcode = (dns_rcode_t)i; } RETERR(uint16_tobuffer(rcode, target)); /* * Other Len. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Other Data. */ return (isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong)); } static inline isc_result_t totext_any_tsig(ARGS_TOTEXT) { isc_region_t sr; isc_region_t sigr; char buf[sizeof(" 281474976710655 ")]; char *bufp; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; isc_uint64_t sigtime; unsigned short n; REQUIRE(rdata->type == dns_rdatatype_tsig); REQUIRE(rdata->rdclass == dns_rdataclass_any); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); /* * Algorithm Name. */ dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_name_fromregion(&name, &sr); sub = name_prefix(&name, tctx->origin, &prefix); RETERR(dns_name_totext(&prefix, sub, target)); RETERR(str_totext(" ", target)); isc_region_consume(&sr, name_length(&name)); /* * Time Signed. */ sigtime = ((isc_uint64_t)sr.base[0] << 40) | ((isc_uint64_t)sr.base[1] << 32) | ((isc_uint64_t)sr.base[2] << 24) | ((isc_uint64_t)sr.base[3] << 16) | ((isc_uint64_t)sr.base[4] << 8) | (isc_uint64_t)sr.base[5]; isc_region_consume(&sr, 6); bufp = &buf[sizeof(buf) - 1]; *bufp-- = 0; *bufp-- = ' '; do { *bufp-- = decdigits[sigtime % 10]; sigtime /= 10; } while (sigtime != 0); bufp++; RETERR(str_totext(bufp, target)); /* * Fudge. */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%u ", n); RETERR(str_totext(buf, target)); /* * Signature Size. */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%u", n); RETERR(str_totext(buf, target)); /* * Signature. */ REQUIRE(n <= sr.length); sigr = sr; sigr.length = n; if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(&sigr, 60, "", target)); else RETERR(isc_base64_totext(&sigr, tctx->width - 2, tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" ) ", target)); else RETERR(str_totext(" ", target)); isc_region_consume(&sr, n); /* * Original ID. */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%u ", n); RETERR(str_totext(buf, target)); /* * Error. */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); RETERR(dns_tsigrcode_totext((dns_rcode_t)n, target)); /* * Other Size. */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, " %u ", n); RETERR(str_totext(buf, target)); /* * Other. */ if (tctx->width == 0) /* No splitting */ return (isc_base64_totext(&sr, 60, "", target)); else return (isc_base64_totext(&sr, 60, " ", target)); } static inline isc_result_t fromwire_any_tsig(ARGS_FROMWIRE) { isc_region_t sr; dns_name_t name; unsigned long n; REQUIRE(type == dns_rdatatype_tsig); REQUIRE(rdclass == dns_rdataclass_any); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); /* * Algorithm Name. */ dns_name_init(&name, NULL); RETERR(dns_name_fromwire(&name, source, dctx, options, target)); isc_buffer_activeregion(source, &sr); /* * Time Signed + Fudge. */ if (sr.length < 8) return (ISC_R_UNEXPECTEDEND); RETERR(mem_tobuffer(target, sr.base, 8)); isc_region_consume(&sr, 8); isc_buffer_forward(source, 8); /* * Signature Length + Signature. */ if (sr.length < 2) return (ISC_R_UNEXPECTEDEND); n = uint16_fromregion(&sr); if (sr.length < n + 2) return (ISC_R_UNEXPECTEDEND); RETERR(mem_tobuffer(target, sr.base, n + 2)); isc_region_consume(&sr, n + 2); isc_buffer_forward(source, n + 2); /* * Original ID + Error. */ if (sr.length < 4) return (ISC_R_UNEXPECTEDEND); RETERR(mem_tobuffer(target, sr.base, 4)); isc_region_consume(&sr, 4); isc_buffer_forward(source, 4); /* * Other Length + Other. */ if (sr.length < 2) return (ISC_R_UNEXPECTEDEND); n = uint16_fromregion(&sr); if (sr.length < n + 2) return (ISC_R_UNEXPECTEDEND); isc_buffer_forward(source, n + 2); return (mem_tobuffer(target, sr.base, n + 2)); } static inline isc_result_t towire_any_tsig(ARGS_TOWIRE) { isc_region_t sr; dns_name_t name; dns_offsets_t offsets; REQUIRE(rdata->type == dns_rdatatype_tsig); REQUIRE(rdata->rdclass == dns_rdataclass_any); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); dns_rdata_toregion(rdata, &sr); dns_name_init(&name, offsets); dns_name_fromregion(&name, &sr); RETERR(dns_name_towire(&name, cctx, target)); isc_region_consume(&sr, name_length(&name)); return (mem_tobuffer(target, sr.base, sr.length)); } static inline int compare_any_tsig(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; dns_name_t name1; dns_name_t name2; int order; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_tsig); REQUIRE(rdata1->rdclass == dns_rdataclass_any); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_name_fromregion(&name1, &r1); dns_name_fromregion(&name2, &r2); order = dns_name_rdatacompare(&name1, &name2); if (order != 0) return (order); isc_region_consume(&r1, name_length(&name1)); isc_region_consume(&r2, name_length(&name2)); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_any_tsig(ARGS_FROMSTRUCT) { dns_rdata_any_tsig_t *tsig = source; isc_region_t tr; REQUIRE(type == dns_rdatatype_tsig); REQUIRE(rdclass == dns_rdataclass_any); REQUIRE(source != NULL); REQUIRE(tsig->common.rdclass == rdclass); REQUIRE(tsig->common.rdtype == type); UNUSED(type); UNUSED(rdclass); /* * Algorithm Name. */ RETERR(name_tobuffer(&tsig->algorithm, target)); isc_buffer_availableregion(target, &tr); if (tr.length < 6 + 2 + 2) return (ISC_R_NOSPACE); /* * Time Signed: 48 bits. */ RETERR(uint16_tobuffer((isc_uint16_t)(tsig->timesigned >> 32), target)); RETERR(uint32_tobuffer((isc_uint32_t)(tsig->timesigned & 0xffffffffU), target)); /* * Fudge. */ RETERR(uint16_tobuffer(tsig->fudge, target)); /* * Signature Size. */ RETERR(uint16_tobuffer(tsig->siglen, target)); /* * Signature. */ RETERR(mem_tobuffer(target, tsig->signature, tsig->siglen)); isc_buffer_availableregion(target, &tr); if (tr.length < 2 + 2 + 2) return (ISC_R_NOSPACE); /* * Original ID. */ RETERR(uint16_tobuffer(tsig->originalid, target)); /* * Error. */ RETERR(uint16_tobuffer(tsig->error, target)); /* * Other Len. */ RETERR(uint16_tobuffer(tsig->otherlen, target)); /* * Other Data. */ return (mem_tobuffer(target, tsig->other, tsig->otherlen)); } static inline isc_result_t tostruct_any_tsig(ARGS_TOSTRUCT) { dns_rdata_any_tsig_t *tsig; dns_name_t alg; isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_tsig); REQUIRE(rdata->rdclass == dns_rdataclass_any); REQUIRE(rdata->length != 0); tsig = (dns_rdata_any_tsig_t *) target; tsig->common.rdclass = rdata->rdclass; tsig->common.rdtype = rdata->type; ISC_LINK_INIT(&tsig->common, link); dns_rdata_toregion(rdata, &sr); /* * Algorithm Name. */ dns_name_init(&alg, NULL); dns_name_fromregion(&alg, &sr); dns_name_init(&tsig->algorithm, NULL); RETERR(name_duporclone(&alg, mctx, &tsig->algorithm)); isc_region_consume(&sr, name_length(&tsig->algorithm)); /* * Time Signed. */ INSIST(sr.length >= 6); tsig->timesigned = ((isc_uint64_t)sr.base[0] << 40) | ((isc_uint64_t)sr.base[1] << 32) | ((isc_uint64_t)sr.base[2] << 24) | ((isc_uint64_t)sr.base[3] << 16) | ((isc_uint64_t)sr.base[4] << 8) | (isc_uint64_t)sr.base[5]; isc_region_consume(&sr, 6); /* * Fudge. */ tsig->fudge = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * Signature Size. */ tsig->siglen = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * Signature. */ INSIST(sr.length >= tsig->siglen); tsig->signature = mem_maybedup(mctx, sr.base, tsig->siglen); if (tsig->signature == NULL) goto cleanup; isc_region_consume(&sr, tsig->siglen); /* * Original ID. */ tsig->originalid = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * Error. */ tsig->error = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * Other Size. */ tsig->otherlen = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * Other. */ INSIST(sr.length == tsig->otherlen); tsig->other = mem_maybedup(mctx, sr.base, tsig->otherlen); if (tsig->other == NULL) goto cleanup; tsig->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (mctx != NULL) dns_name_free(&tsig->algorithm, tsig->mctx); if (mctx != NULL && tsig->signature != NULL) isc_mem_free(mctx, tsig->signature); return (ISC_R_NOMEMORY); } static inline void freestruct_any_tsig(ARGS_FREESTRUCT) { dns_rdata_any_tsig_t *tsig = (dns_rdata_any_tsig_t *) source; REQUIRE(source != NULL); REQUIRE(tsig->common.rdtype == dns_rdatatype_tsig); REQUIRE(tsig->common.rdclass == dns_rdataclass_any); if (tsig->mctx == NULL) return; dns_name_free(&tsig->algorithm, tsig->mctx); if (tsig->signature != NULL) isc_mem_free(tsig->mctx, tsig->signature); if (tsig->other != NULL) isc_mem_free(tsig->mctx, tsig->other); tsig->mctx = NULL; } static inline isc_result_t additionaldata_any_tsig(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_tsig); REQUIRE(rdata->rdclass == dns_rdataclass_any); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_any_tsig(ARGS_DIGEST) { REQUIRE(rdata->type == dns_rdatatype_tsig); REQUIRE(rdata->rdclass == dns_rdataclass_any); UNUSED(rdata); UNUSED(digest); UNUSED(arg); return (ISC_R_NOTIMPLEMENTED); } static inline isc_boolean_t checkowner_any_tsig(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_tsig); REQUIRE(rdclass == dns_rdataclass_any); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_any_tsig(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_tsig); REQUIRE(rdata->rdclass == dns_rdataclass_any); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_any_tsig(ARGS_COMPARE) { return (compare_any_tsig(rdata1, rdata2)); } #endif /* RDATA_ANY_255_TSIG_250_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/0002755000470500017500000000000012672612753016656 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/a_1.c0000644000470500017500000001362612664710322017460 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: a_1.c,v 1.55 2009/12/04 22:06:37 tbox Exp $ */ /* Reviewed: Thu Mar 16 16:52:50 PST 2000 by bwelling */ #ifndef RDATA_IN_1_A_1_C #define RDATA_IN_1_A_1_C #include #include #define RRTYPE_A_ATTRIBUTES (0) static inline isc_result_t fromtext_in_a(ARGS_FROMTEXT) { isc_token_t token; struct in_addr addr; isc_region_t region; REQUIRE(type == dns_rdatatype_a); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(origin); UNUSED(options); UNUSED(rdclass); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1) RETTOK(DNS_R_BADDOTTEDQUAD); isc_buffer_availableregion(target, ®ion); if (region.length < 4) return (ISC_R_NOSPACE); memmove(region.base, &addr, 4); isc_buffer_add(target, 4); return (ISC_R_SUCCESS); } static inline isc_result_t totext_in_a(ARGS_TOTEXT) { isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_a); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length == 4); UNUSED(tctx); dns_rdata_toregion(rdata, ®ion); return (inet_totext(AF_INET, ®ion, target)); } static inline isc_result_t fromwire_in_a(ARGS_FROMWIRE) { isc_region_t sregion; isc_region_t tregion; REQUIRE(type == dns_rdatatype_a); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(dctx); UNUSED(options); UNUSED(rdclass); isc_buffer_activeregion(source, &sregion); isc_buffer_availableregion(target, &tregion); if (sregion.length < 4) return (ISC_R_UNEXPECTEDEND); if (tregion.length < 4) return (ISC_R_NOSPACE); memmove(tregion.base, sregion.base, 4); isc_buffer_forward(source, 4); isc_buffer_add(target, 4); return (ISC_R_SUCCESS); } static inline isc_result_t towire_in_a(ARGS_TOWIRE) { isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_a); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length == 4); UNUSED(cctx); isc_buffer_availableregion(target, ®ion); if (region.length < rdata->length) return (ISC_R_NOSPACE); memmove(region.base, rdata->data, rdata->length); isc_buffer_add(target, 4); return (ISC_R_SUCCESS); } static inline int compare_in_a(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_a); REQUIRE(rdata1->rdclass == dns_rdataclass_in); REQUIRE(rdata1->length == 4); REQUIRE(rdata2->length == 4); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_in_a(ARGS_FROMSTRUCT) { dns_rdata_in_a_t *a = source; isc_uint32_t n; REQUIRE(type == dns_rdatatype_a); REQUIRE(rdclass == dns_rdataclass_in); REQUIRE(source != NULL); REQUIRE(a->common.rdtype == type); REQUIRE(a->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); n = ntohl(a->in_addr.s_addr); return (uint32_tobuffer(n, target)); } static inline isc_result_t tostruct_in_a(ARGS_TOSTRUCT) { dns_rdata_in_a_t *a = target; isc_uint32_t n; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_a); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length == 4); UNUSED(mctx); a->common.rdclass = rdata->rdclass; a->common.rdtype = rdata->type; ISC_LINK_INIT(&a->common, link); dns_rdata_toregion(rdata, ®ion); n = uint32_fromregion(®ion); a->in_addr.s_addr = htonl(n); return (ISC_R_SUCCESS); } static inline void freestruct_in_a(ARGS_FREESTRUCT) { dns_rdata_in_a_t *a = source; REQUIRE(source != NULL); REQUIRE(a->common.rdtype == dns_rdatatype_a); REQUIRE(a->common.rdclass == dns_rdataclass_in); UNUSED(a); } static inline isc_result_t additionaldata_in_a(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_a); REQUIRE(rdata->rdclass == dns_rdataclass_in); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_in_a(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_a); REQUIRE(rdata->rdclass == dns_rdataclass_in); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_in_a(ARGS_CHECKOWNER) { dns_name_t prefix, suffix; REQUIRE(type == dns_rdatatype_a); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(rdclass); /* * Handle Active Diretory gc._msdcs. name. */ if (dns_name_countlabels(name) > 2U) { dns_name_init(&prefix, NULL); dns_name_init(&suffix, NULL); dns_name_split(name, dns_name_countlabels(name) - 2, &prefix, &suffix); if (dns_name_equal(&gc_msdcs, &prefix) && dns_name_ishostname(&suffix, ISC_FALSE)) return (ISC_TRUE); } return (dns_name_ishostname(name, wildcard)); } static inline isc_boolean_t checknames_in_a(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_a); REQUIRE(rdata->rdclass == dns_rdataclass_in); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_in_a(ARGS_COMPARE) { return (compare_in_a(rdata1, rdata2)); } #endif /* RDATA_IN_1_A_1_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/wks_11.c0000644000470500017500000002166212664710322020124 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* Reviewed: Fri Mar 17 15:01:49 PST 2000 by explorer */ #ifndef RDATA_IN_1_WKS_11_C #define RDATA_IN_1_WKS_11_C #include #include #include #include #include #define RRTYPE_WKS_ATTRIBUTES (0) static isc_mutex_t wks_lock; static void init_lock(void) { RUNTIME_CHECK(isc_mutex_init(&wks_lock) == ISC_R_SUCCESS); } static isc_boolean_t mygetprotobyname(const char *name, long *proto) { struct protoent *pe; LOCK(&wks_lock); pe = getprotobyname(name); if (pe != NULL) *proto = pe->p_proto; UNLOCK(&wks_lock); return (ISC_TF(pe != NULL)); } static isc_boolean_t mygetservbyname(const char *name, const char *proto, long *port) { struct servent *se; LOCK(&wks_lock); se = getservbyname(name, proto); if (se != NULL) *port = ntohs(se->s_port); UNLOCK(&wks_lock); return (ISC_TF(se != NULL)); } static inline isc_result_t fromtext_in_wks(ARGS_FROMTEXT) { static isc_once_t once = ISC_ONCE_INIT; isc_token_t token; isc_region_t region; struct in_addr addr; char *e; long proto; unsigned char bm[8*1024]; /* 64k bits */ long port; long maxport = -1; const char *ps = NULL; unsigned int n; char service[32]; int i; REQUIRE(type == dns_rdatatype_wks); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(origin); UNUSED(options); UNUSED(rdclass); RUNTIME_CHECK(isc_once_do(&once, init_lock) == ISC_R_SUCCESS); /* * IPv4 dotted quad. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); isc_buffer_availableregion(target, ®ion); if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1) RETTOK(DNS_R_BADDOTTEDQUAD); if (region.length < 4) return (ISC_R_NOSPACE); memmove(region.base, &addr, 4); isc_buffer_add(target, 4); /* * Protocol. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); proto = strtol(DNS_AS_STR(token), &e, 10); if (*e == 0) ; else if (!mygetprotobyname(DNS_AS_STR(token), &proto)) RETTOK(DNS_R_UNKNOWNPROTO); if (proto < 0 || proto > 0xff) RETTOK(ISC_R_RANGE); if (proto == IPPROTO_TCP) ps = "tcp"; else if (proto == IPPROTO_UDP) ps = "udp"; RETERR(uint8_tobuffer(proto, target)); memset(bm, 0, sizeof(bm)); do { RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_TRUE)); if (token.type != isc_tokentype_string) break; /* * Lowercase the service string as some getservbyname() are * case sensitive and the database is usually in lowercase. */ strncpy(service, DNS_AS_STR(token), sizeof(service)); service[sizeof(service)-1] = '\0'; for (i = strlen(service) - 1; i >= 0; i--) if (isupper(service[i]&0xff)) service[i] = tolower(service[i]&0xff); port = strtol(DNS_AS_STR(token), &e, 10); if (*e == 0) ; else if (!mygetservbyname(service, ps, &port) && !mygetservbyname(DNS_AS_STR(token), ps, &port)) RETTOK(DNS_R_UNKNOWNSERVICE); if (port < 0 || port > 0xffff) RETTOK(ISC_R_RANGE); if (port > maxport) maxport = port; bm[port / 8] |= (0x80 >> (port % 8)); } while (1); /* * Let upper layer handle eol/eof. */ isc_lex_ungettoken(lexer, &token); n = (maxport + 8) / 8; return (mem_tobuffer(target, bm, n)); } static inline isc_result_t totext_in_wks(ARGS_TOTEXT) { isc_region_t sr; unsigned short proto; char buf[sizeof("65535")]; unsigned int i, j; UNUSED(tctx); REQUIRE(rdata->type == dns_rdatatype_wks); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length >= 5); dns_rdata_toregion(rdata, &sr); RETERR(inet_totext(AF_INET, &sr, target)); isc_region_consume(&sr, 4); proto = uint8_fromregion(&sr); sprintf(buf, "%u", proto); RETERR(str_totext(" ", target)); RETERR(str_totext(buf, target)); isc_region_consume(&sr, 1); INSIST(sr.length <= 8*1024); for (i = 0; i < sr.length; i++) { if (sr.base[i] != 0) for (j = 0; j < 8; j++) if ((sr.base[i] & (0x80 >> j)) != 0) { sprintf(buf, "%u", i * 8 + j); RETERR(str_totext(" ", target)); RETERR(str_totext(buf, target)); } } return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_in_wks(ARGS_FROMWIRE) { isc_region_t sr; isc_region_t tr; REQUIRE(type == dns_rdatatype_wks); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(dctx); UNUSED(options); UNUSED(rdclass); isc_buffer_activeregion(source, &sr); isc_buffer_availableregion(target, &tr); if (sr.length < 5) return (ISC_R_UNEXPECTEDEND); if (sr.length > 8 * 1024 + 5) return (DNS_R_EXTRADATA); if (tr.length < sr.length) return (ISC_R_NOSPACE); memmove(tr.base, sr.base, sr.length); isc_buffer_add(target, sr.length); isc_buffer_forward(source, sr.length); return (ISC_R_SUCCESS); } static inline isc_result_t towire_in_wks(ARGS_TOWIRE) { isc_region_t sr; UNUSED(cctx); REQUIRE(rdata->type == dns_rdatatype_wks); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); return (mem_tobuffer(target, sr.base, sr.length)); } static inline int compare_in_wks(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_wks); REQUIRE(rdata1->rdclass == dns_rdataclass_in); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_in_wks(ARGS_FROMSTRUCT) { dns_rdata_in_wks_t *wks = source; isc_uint32_t a; REQUIRE(type == dns_rdatatype_wks); REQUIRE(rdclass == dns_rdataclass_in); REQUIRE(source != NULL); REQUIRE(wks->common.rdtype == type); REQUIRE(wks->common.rdclass == rdclass); REQUIRE((wks->map != NULL && wks->map_len <= 8*1024) || wks->map_len == 0); UNUSED(type); UNUSED(rdclass); a = ntohl(wks->in_addr.s_addr); RETERR(uint32_tobuffer(a, target)); RETERR(uint8_tobuffer(wks->protocol, target)); return (mem_tobuffer(target, wks->map, wks->map_len)); } static inline isc_result_t tostruct_in_wks(ARGS_TOSTRUCT) { dns_rdata_in_wks_t *wks = target; isc_uint32_t n; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_wks); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length != 0); wks->common.rdclass = rdata->rdclass; wks->common.rdtype = rdata->type; ISC_LINK_INIT(&wks->common, link); dns_rdata_toregion(rdata, ®ion); n = uint32_fromregion(®ion); wks->in_addr.s_addr = htonl(n); isc_region_consume(®ion, 4); wks->protocol = uint8_fromregion(®ion); isc_region_consume(®ion, 1); wks->map_len = region.length; wks->map = mem_maybedup(mctx, region.base, region.length); if (wks->map == NULL) return (ISC_R_NOMEMORY); wks->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_in_wks(ARGS_FREESTRUCT) { dns_rdata_in_wks_t *wks = source; REQUIRE(source != NULL); REQUIRE(wks->common.rdtype == dns_rdatatype_wks); REQUIRE(wks->common.rdclass == dns_rdataclass_in); if (wks->mctx == NULL) return; if (wks->map != NULL) isc_mem_free(wks->mctx, wks->map); wks->mctx = NULL; } static inline isc_result_t additionaldata_in_wks(ARGS_ADDLDATA) { UNUSED(rdata); UNUSED(add); UNUSED(arg); REQUIRE(rdata->type == dns_rdatatype_wks); REQUIRE(rdata->rdclass == dns_rdataclass_in); return (ISC_R_SUCCESS); } static inline isc_result_t digest_in_wks(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_wks); REQUIRE(rdata->rdclass == dns_rdataclass_in); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_in_wks(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_wks); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(rdclass); return (dns_name_ishostname(name, wildcard)); } static inline isc_boolean_t checknames_in_wks(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_wks); REQUIRE(rdata->rdclass == dns_rdataclass_in); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_in_wks(ARGS_COMPARE) { return (compare_in_wks(rdata1, rdata2)); } #endif /* RDATA_IN_1_WKS_11_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/kx_36.h0000644000470500017500000000222612664710322017751 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef IN_1_KX_36_H #define IN_1_KX_36_H 1 /* $Id: kx_36.h,v 1.20 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief Per RFC2230 */ typedef struct dns_rdata_in_kx { dns_rdatacommon_t common; isc_mem_t *mctx; isc_uint16_t preference; dns_name_t exchange; } dns_rdata_in_kx_t; #endif /* IN_1_KX_36_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/a6_38.c0000644000470500017500000002611612664710322017636 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: a6_38.c,v 1.56 2009/12/04 22:06:37 tbox Exp $ */ /* RFC2874 */ #ifndef RDATA_IN_1_A6_28_C #define RDATA_IN_1_A6_28_C #include #define RRTYPE_A6_ATTRIBUTES (0) static inline isc_result_t fromtext_in_a6(ARGS_FROMTEXT) { isc_token_t token; unsigned char addr[16]; unsigned char prefixlen; unsigned char octets; unsigned char mask; dns_name_t name; isc_buffer_t buffer; isc_boolean_t ok; REQUIRE(type == dns_rdatatype_a6); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); /* * Prefix length. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 128U) RETTOK(ISC_R_RANGE); prefixlen = (unsigned char)token.value.as_ulong; RETERR(mem_tobuffer(target, &prefixlen, 1)); /* * Suffix. */ if (prefixlen != 128) { /* * Prefix 0..127. */ octets = prefixlen/8; /* * Octets 0..15. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (inet_pton(AF_INET6, DNS_AS_STR(token), addr) != 1) RETTOK(DNS_R_BADAAAA); mask = 0xff >> (prefixlen % 8); addr[octets] &= mask; RETERR(mem_tobuffer(target, &addr[octets], 16 - octets)); } if (prefixlen == 0) return (ISC_R_SUCCESS); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); ok = ISC_TRUE; if ((options & DNS_RDATA_CHECKNAMES) != 0) ok = dns_name_ishostname(&name, ISC_FALSE); if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) RETTOK(DNS_R_BADNAME); if (!ok && callbacks != NULL) warn_badname(&name, lexer, callbacks); return (ISC_R_SUCCESS); } static inline isc_result_t totext_in_a6(ARGS_TOTEXT) { isc_region_t sr, ar; unsigned char addr[16]; unsigned char prefixlen; unsigned char octets; unsigned char mask; char buf[sizeof("128")]; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; REQUIRE(rdata->type == dns_rdatatype_a6); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); prefixlen = sr.base[0]; INSIST(prefixlen <= 128); isc_region_consume(&sr, 1); sprintf(buf, "%u", prefixlen); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); if (prefixlen != 128) { octets = prefixlen/8; memset(addr, 0, sizeof(addr)); memmove(&addr[octets], sr.base, 16 - octets); mask = 0xff >> (prefixlen % 8); addr[octets] &= mask; ar.base = addr; ar.length = sizeof(addr); RETERR(inet_totext(AF_INET6, &ar, target)); isc_region_consume(&sr, 16 - octets); } if (prefixlen == 0) return (ISC_R_SUCCESS); RETERR(str_totext(" ", target)); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_name_fromregion(&name, &sr); sub = name_prefix(&name, tctx->origin, &prefix); return (dns_name_totext(&prefix, sub, target)); } static inline isc_result_t fromwire_in_a6(ARGS_FROMWIRE) { isc_region_t sr; unsigned char prefixlen; unsigned char octets; unsigned char mask; dns_name_t name; REQUIRE(type == dns_rdatatype_a6); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); isc_buffer_activeregion(source, &sr); /* * Prefix length. */ if (sr.length < 1) return (ISC_R_UNEXPECTEDEND); prefixlen = sr.base[0]; if (prefixlen > 128) return (ISC_R_RANGE); isc_region_consume(&sr, 1); RETERR(mem_tobuffer(target, &prefixlen, 1)); isc_buffer_forward(source, 1); /* * Suffix. */ if (prefixlen != 128) { octets = 16 - prefixlen / 8; if (sr.length < octets) return (ISC_R_UNEXPECTEDEND); mask = 0xff >> (prefixlen % 8); sr.base[0] &= mask; /* Ensure pad bits are zero. */ RETERR(mem_tobuffer(target, sr.base, octets)); isc_buffer_forward(source, octets); } if (prefixlen == 0) return (ISC_R_SUCCESS); dns_name_init(&name, NULL); return (dns_name_fromwire(&name, source, dctx, options, target)); } static inline isc_result_t towire_in_a6(ARGS_TOWIRE) { isc_region_t sr; dns_name_t name; dns_offsets_t offsets; unsigned char prefixlen; unsigned char octets; REQUIRE(rdata->type == dns_rdatatype_a6); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); dns_rdata_toregion(rdata, &sr); prefixlen = sr.base[0]; INSIST(prefixlen <= 128); octets = 1 + 16 - prefixlen / 8; RETERR(mem_tobuffer(target, sr.base, octets)); isc_region_consume(&sr, octets); if (prefixlen == 0) return (ISC_R_SUCCESS); dns_name_init(&name, offsets); dns_name_fromregion(&name, &sr); return (dns_name_towire(&name, cctx, target)); } static inline int compare_in_a6(ARGS_COMPARE) { int order; unsigned char prefixlen1, prefixlen2; unsigned char octets; dns_name_t name1; dns_name_t name2; isc_region_t region1; isc_region_t region2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_a6); REQUIRE(rdata1->rdclass == dns_rdataclass_in); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); prefixlen1 = region1.base[0]; prefixlen2 = region2.base[0]; isc_region_consume(®ion1, 1); isc_region_consume(®ion2, 1); if (prefixlen1 < prefixlen2) return (-1); else if (prefixlen1 > prefixlen2) return (1); /* * Prefix lengths are equal. */ octets = 16 - prefixlen1 / 8; if (octets > 0) { order = memcmp(region1.base, region2.base, octets); if (order < 0) return (-1); else if (order > 0) return (1); /* * Address suffixes are equal. */ if (prefixlen1 == 0) return (order); isc_region_consume(®ion1, octets); isc_region_consume(®ion2, octets); } dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); return (dns_name_rdatacompare(&name1, &name2)); } static inline isc_result_t fromstruct_in_a6(ARGS_FROMSTRUCT) { dns_rdata_in_a6_t *a6 = source; isc_region_t region; int octets; isc_uint8_t bits; isc_uint8_t first; isc_uint8_t mask; REQUIRE(type == dns_rdatatype_a6); REQUIRE(rdclass == dns_rdataclass_in); REQUIRE(source != NULL); REQUIRE(a6->common.rdtype == type); REQUIRE(a6->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); if (a6->prefixlen > 128) return (ISC_R_RANGE); RETERR(uint8_tobuffer(a6->prefixlen, target)); /* Suffix */ if (a6->prefixlen != 128) { octets = 16 - a6->prefixlen / 8; bits = a6->prefixlen % 8; if (bits != 0) { mask = 0xffU >> bits; first = a6->in6_addr.s6_addr[16 - octets] & mask; RETERR(uint8_tobuffer(first, target)); octets--; } if (octets > 0) RETERR(mem_tobuffer(target, a6->in6_addr.s6_addr + 16 - octets, octets)); } if (a6->prefixlen == 0) return (ISC_R_SUCCESS); dns_name_toregion(&a6->prefix, ®ion); return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_in_a6(ARGS_TOSTRUCT) { dns_rdata_in_a6_t *a6 = target; unsigned char octets; dns_name_t name; isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_a6); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); a6->common.rdclass = rdata->rdclass; a6->common.rdtype = rdata->type; ISC_LINK_INIT(&a6->common, link); dns_rdata_toregion(rdata, &r); a6->prefixlen = uint8_fromregion(&r); isc_region_consume(&r, 1); memset(a6->in6_addr.s6_addr, 0, sizeof(a6->in6_addr.s6_addr)); /* * Suffix. */ if (a6->prefixlen != 128) { octets = 16 - a6->prefixlen / 8; INSIST(r.length >= octets); memmove(a6->in6_addr.s6_addr + 16 - octets, r.base, octets); isc_region_consume(&r, octets); } /* * Prefix. */ dns_name_init(&a6->prefix, NULL); if (a6->prefixlen != 0) { dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); RETERR(name_duporclone(&name, mctx, &a6->prefix)); } a6->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_in_a6(ARGS_FREESTRUCT) { dns_rdata_in_a6_t *a6 = source; REQUIRE(source != NULL); REQUIRE(a6->common.rdclass == dns_rdataclass_in); REQUIRE(a6->common.rdtype == dns_rdatatype_a6); if (a6->mctx == NULL) return; if (dns_name_dynamic(&a6->prefix)) dns_name_free(&a6->prefix, a6->mctx); a6->mctx = NULL; } static inline isc_result_t additionaldata_in_a6(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_a6); REQUIRE(rdata->rdclass == dns_rdataclass_in); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_in_a6(ARGS_DIGEST) { isc_region_t r1, r2; unsigned char prefixlen, octets; isc_result_t result; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_a6); REQUIRE(rdata->rdclass == dns_rdataclass_in); dns_rdata_toregion(rdata, &r1); r2 = r1; prefixlen = r1.base[0]; octets = 1 + 16 - prefixlen / 8; r1.length = octets; result = (digest)(arg, &r1); if (result != ISC_R_SUCCESS) return (result); if (prefixlen == 0) return (ISC_R_SUCCESS); isc_region_consume(&r2, octets); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r2); return (dns_name_digest(&name, digest, arg)); } static inline isc_boolean_t checkowner_in_a6(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_a6); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(rdclass); return (dns_name_ishostname(name, wildcard)); } static inline isc_boolean_t checknames_in_a6(ARGS_CHECKNAMES) { isc_region_t region; dns_name_t name; unsigned int prefixlen; REQUIRE(rdata->type == dns_rdatatype_a6); REQUIRE(rdata->rdclass == dns_rdataclass_in); UNUSED(owner); dns_rdata_toregion(rdata, ®ion); prefixlen = uint8_fromregion(®ion); if (prefixlen == 0) return (ISC_TRUE); isc_region_consume(®ion, 1 + 16 - prefixlen / 8); dns_name_init(&name, NULL); dns_name_fromregion(&name, ®ion); if (!dns_name_ishostname(&name, ISC_FALSE)) { if (bad != NULL) dns_name_clone(&name, bad); return (ISC_FALSE); } return (ISC_TRUE); } static inline int casecompare_in_a6(ARGS_COMPARE) { return (compare_in_a6(rdata1, rdata2)); } #endif /* RDATA_IN_1_A6_38_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/dhcid_49.h0000644000470500017500000000211212664710322020400 0ustar lamontlamont/* * Copyright (C) 2006, 2007 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef IN_1_DHCID_49_H #define IN_1_DHCID_49_H 1 /* $Id: dhcid_49.h,v 1.5 2007/06/19 23:47:17 tbox Exp $ */ typedef struct dns_rdata_in_dhcid { dns_rdatacommon_t common; isc_mem_t *mctx; unsigned char *dhcid; unsigned int length; } dns_rdata_in_dhcid_t; #endif /* IN_1_DHCID_49_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/nsap-ptr_23.h0000644000470500017500000000230712664710322021067 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef IN_1_NSAP_PTR_23_H #define IN_1_NSAP_PTR_23_H 1 /* $Id: nsap-ptr_23.h,v 1.19 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief Per RFC1348. Obsoleted in RFC 1706 - use PTR instead. */ typedef struct dns_rdata_in_nsap_ptr { dns_rdatacommon_t common; isc_mem_t *mctx; dns_name_t owner; } dns_rdata_in_nsap_ptr_t; #endif /* IN_1_NSAP_PTR_23_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/px_26.c0000644000470500017500000002175012664710322017753 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: px_26.c,v 1.45 2009/12/04 22:06:37 tbox Exp $ */ /* Reviewed: Mon Mar 20 10:44:27 PST 2000 */ /* RFC2163 */ #ifndef RDATA_IN_1_PX_26_C #define RDATA_IN_1_PX_26_C #define RRTYPE_PX_ATTRIBUTES (0) static inline isc_result_t fromtext_in_px(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; REQUIRE(type == dns_rdatatype_px); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); /* * Preference. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * MAP822. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); /* * MAPX400. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); return (ISC_R_SUCCESS); } static inline isc_result_t totext_in_px(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; char buf[sizeof("64000")]; unsigned short num; REQUIRE(rdata->type == dns_rdatatype_px); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length != 0); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); /* * Preference. */ dns_rdata_toregion(rdata, ®ion); num = uint16_fromregion(®ion); isc_region_consume(®ion, 2); sprintf(buf, "%u", num); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * MAP822. */ dns_name_fromregion(&name, ®ion); sub = name_prefix(&name, tctx->origin, &prefix); isc_region_consume(®ion, name_length(&name)); RETERR(dns_name_totext(&prefix, sub, target)); RETERR(str_totext(" ", target)); /* * MAPX400. */ dns_name_fromregion(&name, ®ion); sub = name_prefix(&name, tctx->origin, &prefix); return(dns_name_totext(&prefix, sub, target)); } static inline isc_result_t fromwire_in_px(ARGS_FROMWIRE) { dns_name_t name; isc_region_t sregion; REQUIRE(type == dns_rdatatype_px); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); dns_name_init(&name, NULL); /* * Preference. */ isc_buffer_activeregion(source, &sregion); if (sregion.length < 2) return (ISC_R_UNEXPECTEDEND); RETERR(mem_tobuffer(target, sregion.base, 2)); isc_buffer_forward(source, 2); /* * MAP822. */ RETERR(dns_name_fromwire(&name, source, dctx, options, target)); /* * MAPX400. */ return (dns_name_fromwire(&name, source, dctx, options, target)); } static inline isc_result_t towire_in_px(ARGS_TOWIRE) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_px); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); /* * Preference. */ dns_rdata_toregion(rdata, ®ion); RETERR(mem_tobuffer(target, region.base, 2)); isc_region_consume(®ion, 2); /* * MAP822. */ dns_name_init(&name, offsets); dns_name_fromregion(&name, ®ion); RETERR(dns_name_towire(&name, cctx, target)); isc_region_consume(®ion, name_length(&name)); /* * MAPX400. */ dns_name_init(&name, offsets); dns_name_fromregion(&name, ®ion); return (dns_name_towire(&name, cctx, target)); } static inline int compare_in_px(ARGS_COMPARE) { dns_name_t name1; dns_name_t name2; isc_region_t region1; isc_region_t region2; int order; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_px); REQUIRE(rdata1->rdclass == dns_rdataclass_in); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); order = memcmp(rdata1->data, rdata2->data, 2); if (order != 0) return (order < 0 ? -1 : 1); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); isc_region_consume(®ion1, 2); isc_region_consume(®ion2, 2); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); order = dns_name_rdatacompare(&name1, &name2); if (order != 0) return (order); isc_region_consume(®ion1, name_length(&name1)); isc_region_consume(®ion2, name_length(&name2)); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); return (dns_name_rdatacompare(&name1, &name2)); } static inline isc_result_t fromstruct_in_px(ARGS_FROMSTRUCT) { dns_rdata_in_px_t *px = source; isc_region_t region; REQUIRE(type == dns_rdatatype_px); REQUIRE(rdclass == dns_rdataclass_in); REQUIRE(source != NULL); REQUIRE(px->common.rdtype == type); REQUIRE(px->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); RETERR(uint16_tobuffer(px->preference, target)); dns_name_toregion(&px->map822, ®ion); RETERR(isc_buffer_copyregion(target, ®ion)); dns_name_toregion(&px->mapx400, ®ion); return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_in_px(ARGS_TOSTRUCT) { dns_rdata_in_px_t *px = target; dns_name_t name; isc_region_t region; isc_result_t result; REQUIRE(rdata->type == dns_rdatatype_px); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); px->common.rdclass = rdata->rdclass; px->common.rdtype = rdata->type; ISC_LINK_INIT(&px->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); px->preference = uint16_fromregion(®ion); isc_region_consume(®ion, 2); dns_name_fromregion(&name, ®ion); dns_name_init(&px->map822, NULL); RETERR(name_duporclone(&name, mctx, &px->map822)); isc_region_consume(®ion, name_length(&px->map822)); dns_name_init(&px->mapx400, NULL); result = name_duporclone(&name, mctx, &px->mapx400); if (result != ISC_R_SUCCESS) goto cleanup; px->mctx = mctx; return (result); cleanup: dns_name_free(&px->map822, mctx); return (ISC_R_NOMEMORY); } static inline void freestruct_in_px(ARGS_FREESTRUCT) { dns_rdata_in_px_t *px = source; REQUIRE(source != NULL); REQUIRE(px->common.rdclass == dns_rdataclass_in); REQUIRE(px->common.rdtype == dns_rdatatype_px); if (px->mctx == NULL) return; dns_name_free(&px->map822, px->mctx); dns_name_free(&px->mapx400, px->mctx); px->mctx = NULL; } static inline isc_result_t additionaldata_in_px(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_px); REQUIRE(rdata->rdclass == dns_rdataclass_in); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_in_px(ARGS_DIGEST) { isc_region_t r1, r2; dns_name_t name; isc_result_t result; REQUIRE(rdata->type == dns_rdatatype_px); REQUIRE(rdata->rdclass == dns_rdataclass_in); dns_rdata_toregion(rdata, &r1); r2 = r1; isc_region_consume(&r2, 2); r1.length = 2; result = (digest)(arg, &r1); if (result != ISC_R_SUCCESS) return (result); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r2); result = dns_name_digest(&name, digest, arg); if (result != ISC_R_SUCCESS) return (result); isc_region_consume(&r2, name_length(&name)); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r2); return (dns_name_digest(&name, digest, arg)); } static inline isc_boolean_t checkowner_in_px(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_px); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_in_px(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_px); REQUIRE(rdata->rdclass == dns_rdataclass_in); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_in_px(ARGS_COMPARE) { return (compare_in_px(rdata1, rdata2)); } #endif /* RDATA_IN_1_PX_26_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/a6_38.h0000644000470500017500000000226512664710322017642 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef IN_1_A6_38_H #define IN_1_A6_38_H 1 /* $Id: a6_38.h,v 1.24 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief Per RFC2874 */ typedef struct dns_rdata_in_a6 { dns_rdatacommon_t common; isc_mem_t *mctx; dns_name_t prefix; isc_uint8_t prefixlen; struct in6_addr in6_addr; } dns_rdata_in_a6_t; #endif /* IN_1_A6_38_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/srv_33.h0000644000470500017500000000237612664710322020144 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef IN_1_SRV_33_H #define IN_1_SRV_33_H 1 /* $Id: srv_33.h,v 1.19 2007/06/19 23:47:17 tbox Exp $ */ /* Reviewed: Fri Mar 17 13:01:00 PST 2000 by bwelling */ /*! * \brief Per RFC2782 */ typedef struct dns_rdata_in_srv { dns_rdatacommon_t common; isc_mem_t *mctx; isc_uint16_t priority; isc_uint16_t weight; isc_uint16_t port; dns_name_t target; } dns_rdata_in_srv_t; #endif /* IN_1_SRV_33_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/px_26.h0000644000470500017500000000225212664710322017754 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef IN_1_PX_26_H #define IN_1_PX_26_H 1 /* $Id: px_26.h,v 1.19 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief Per RFC2163 */ typedef struct dns_rdata_in_px { dns_rdatacommon_t common; isc_mem_t *mctx; isc_uint16_t preference; dns_name_t map822; dns_name_t mapx400; } dns_rdata_in_px_t; #endif /* IN_1_PX_26_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/apl_42.c0000644000470500017500000002532612664710322020101 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007-2009, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: apl_42.c,v 1.16 2009/12/04 22:06:37 tbox Exp $ */ /* RFC3123 */ #ifndef RDATA_IN_1_APL_42_C #define RDATA_IN_1_APL_42_C #define RRTYPE_APL_ATTRIBUTES (0) static inline isc_result_t fromtext_in_apl(ARGS_FROMTEXT) { isc_token_t token; unsigned char addr[16]; unsigned long afi; isc_uint8_t prefix; isc_uint8_t len; isc_boolean_t neg; char *cp, *ap, *slash; int n; REQUIRE(type == dns_rdatatype_apl); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); do { RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_TRUE)); if (token.type != isc_tokentype_string) break; cp = DNS_AS_STR(token); neg = ISC_TF(*cp == '!'); if (neg) cp++; afi = strtoul(cp, &ap, 10); if (*ap++ != ':' || cp == ap) RETTOK(DNS_R_SYNTAX); if (afi > 0xffffU) RETTOK(ISC_R_RANGE); slash = strchr(ap, '/'); if (slash == NULL || slash == ap) RETTOK(DNS_R_SYNTAX); RETTOK(isc_parse_uint8(&prefix, slash + 1, 10)); switch (afi) { case 1: *slash = '\0'; n = inet_pton(AF_INET, ap, addr); *slash = '/'; if (n != 1) RETTOK(DNS_R_BADDOTTEDQUAD); if (prefix > 32) RETTOK(ISC_R_RANGE); for (len = 4; len > 0; len--) if (addr[len - 1] != 0) break; break; case 2: *slash = '\0'; n = inet_pton(AF_INET6, ap, addr); *slash = '/'; if (n != 1) RETTOK(DNS_R_BADAAAA); if (prefix > 128) RETTOK(ISC_R_RANGE); for (len = 16; len > 0; len--) if (addr[len - 1] != 0) break; break; default: RETTOK(ISC_R_NOTIMPLEMENTED); } RETERR(uint16_tobuffer(afi, target)); RETERR(uint8_tobuffer(prefix, target)); RETERR(uint8_tobuffer(len | ((neg) ? 0x80 : 0), target)); RETERR(mem_tobuffer(target, addr, len)); } while (1); /* * Let upper layer handle eol/eof. */ isc_lex_ungettoken(lexer, &token); return (ISC_R_SUCCESS); } static inline isc_result_t totext_in_apl(ARGS_TOTEXT) { isc_region_t sr; isc_region_t ir; isc_uint16_t afi; isc_uint8_t prefix; isc_uint8_t len; isc_boolean_t neg; unsigned char buf[16]; char txt[sizeof(" !64000:")]; const char *sep = ""; int n; REQUIRE(rdata->type == dns_rdatatype_apl); REQUIRE(rdata->rdclass == dns_rdataclass_in); UNUSED(tctx); dns_rdata_toregion(rdata, &sr); ir.base = buf; ir.length = sizeof(buf); while (sr.length > 0) { INSIST(sr.length >= 4); afi = uint16_fromregion(&sr); isc_region_consume(&sr, 2); prefix = *sr.base; isc_region_consume(&sr, 1); len = (*sr.base & 0x7f); neg = ISC_TF((*sr.base & 0x80) != 0); isc_region_consume(&sr, 1); INSIST(len <= sr.length); n = snprintf(txt, sizeof(txt), "%s%s%u:", sep, neg ? "!" : "", afi); INSIST(n < (int)sizeof(txt)); RETERR(str_totext(txt, target)); switch (afi) { case 1: INSIST(len <= 4); INSIST(prefix <= 32); memset(buf, 0, sizeof(buf)); memmove(buf, sr.base, len); RETERR(inet_totext(AF_INET, &ir, target)); break; case 2: INSIST(len <= 16); INSIST(prefix <= 128); memset(buf, 0, sizeof(buf)); memmove(buf, sr.base, len); RETERR(inet_totext(AF_INET6, &ir, target)); break; default: return (ISC_R_NOTIMPLEMENTED); } n = snprintf(txt, sizeof(txt), "/%u", prefix); INSIST(n < (int)sizeof(txt)); RETERR(str_totext(txt, target)); isc_region_consume(&sr, len); sep = " "; } return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_in_apl(ARGS_FROMWIRE) { isc_region_t sr, sr2; isc_region_t tr; isc_uint16_t afi; isc_uint8_t prefix; isc_uint8_t len; REQUIRE(type == dns_rdatatype_apl); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(dctx); UNUSED(rdclass); UNUSED(options); isc_buffer_activeregion(source, &sr); isc_buffer_availableregion(target, &tr); if (sr.length > tr.length) return (ISC_R_NOSPACE); sr2 = sr; /* Zero or more items */ while (sr.length > 0) { if (sr.length < 4) return (ISC_R_UNEXPECTEDEND); afi = uint16_fromregion(&sr); isc_region_consume(&sr, 2); prefix = *sr.base; isc_region_consume(&sr, 1); len = (*sr.base & 0x7f); isc_region_consume(&sr, 1); if (len > sr.length) return (ISC_R_UNEXPECTEDEND); switch (afi) { case 1: if (prefix > 32 || len > 4) return (ISC_R_RANGE); break; case 2: if (prefix > 128 || len > 16) return (ISC_R_RANGE); } if (len > 0 && sr.base[len - 1] == 0) return (DNS_R_FORMERR); isc_region_consume(&sr, len); } isc_buffer_forward(source, sr2.length); return (mem_tobuffer(target, sr2.base, sr2.length)); } static inline isc_result_t towire_in_apl(ARGS_TOWIRE) { UNUSED(cctx); REQUIRE(rdata->type == dns_rdatatype_apl); REQUIRE(rdata->rdclass == dns_rdataclass_in); return (mem_tobuffer(target, rdata->data, rdata->length)); } static inline int compare_in_apl(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_apl); REQUIRE(rdata1->rdclass == dns_rdataclass_in); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_in_apl(ARGS_FROMSTRUCT) { dns_rdata_in_apl_t *apl = source; isc_buffer_t b; REQUIRE(type == dns_rdatatype_apl); REQUIRE(rdclass == dns_rdataclass_in); REQUIRE(source != NULL); REQUIRE(apl->common.rdtype == type); REQUIRE(apl->common.rdclass == rdclass); REQUIRE(apl->apl != NULL || apl->apl_len == 0); isc_buffer_init(&b, apl->apl, apl->apl_len); isc_buffer_add(&b, apl->apl_len); isc_buffer_setactive(&b, apl->apl_len); return(fromwire_in_apl(rdclass, type, &b, NULL, ISC_FALSE, target)); } static inline isc_result_t tostruct_in_apl(ARGS_TOSTRUCT) { dns_rdata_in_apl_t *apl = target; isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_apl); REQUIRE(rdata->rdclass == dns_rdataclass_in); apl->common.rdclass = rdata->rdclass; apl->common.rdtype = rdata->type; ISC_LINK_INIT(&apl->common, link); dns_rdata_toregion(rdata, &r); apl->apl_len = r.length; apl->apl = mem_maybedup(mctx, r.base, r.length); if (apl->apl == NULL) return (ISC_R_NOMEMORY); apl->offset = 0; apl->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_in_apl(ARGS_FREESTRUCT) { dns_rdata_in_apl_t *apl = source; REQUIRE(source != NULL); REQUIRE(apl->common.rdtype == dns_rdatatype_apl); REQUIRE(apl->common.rdclass == dns_rdataclass_in); if (apl->mctx == NULL) return; if (apl->apl != NULL) isc_mem_free(apl->mctx, apl->apl); apl->mctx = NULL; } isc_result_t dns_rdata_apl_first(dns_rdata_in_apl_t *apl) { isc_uint32_t length; REQUIRE(apl != NULL); REQUIRE(apl->common.rdtype == dns_rdatatype_apl); REQUIRE(apl->common.rdclass == dns_rdataclass_in); REQUIRE(apl->apl != NULL || apl->apl_len == 0); /* * If no APL return ISC_R_NOMORE. */ if (apl->apl == NULL) return (ISC_R_NOMORE); /* * Sanity check data. */ INSIST(apl->apl_len > 3U); length = apl->apl[apl->offset + 3] & 0x7f; INSIST(length <= apl->apl_len); apl->offset = 0; return (ISC_R_SUCCESS); } isc_result_t dns_rdata_apl_next(dns_rdata_in_apl_t *apl) { isc_uint32_t length; REQUIRE(apl != NULL); REQUIRE(apl->common.rdtype == dns_rdatatype_apl); REQUIRE(apl->common.rdclass == dns_rdataclass_in); REQUIRE(apl->apl != NULL || apl->apl_len == 0); /* * No APL or have already reached the end return ISC_R_NOMORE. */ if (apl->apl == NULL || apl->offset == apl->apl_len) return (ISC_R_NOMORE); /* * Sanity check data. */ INSIST(apl->offset < apl->apl_len); INSIST(apl->apl_len > 3U); INSIST(apl->offset <= apl->apl_len - 4U); length = apl->apl[apl->offset + 3] & 0x7f; /* * 16 to 32 bits promotion as 'length' is 32 bits so there is * no overflow problems. */ INSIST(length + apl->offset <= apl->apl_len); apl->offset += apl->apl[apl->offset + 3] & 0x7f; return ((apl->offset >= apl->apl_len) ? ISC_R_SUCCESS : ISC_R_NOMORE); } isc_result_t dns_rdata_apl_current(dns_rdata_in_apl_t *apl, dns_rdata_apl_ent_t *ent) { isc_uint32_t length; REQUIRE(apl != NULL); REQUIRE(apl->common.rdtype == dns_rdatatype_apl); REQUIRE(apl->common.rdclass == dns_rdataclass_in); REQUIRE(ent != NULL); REQUIRE(apl->apl != NULL || apl->apl_len == 0); REQUIRE(apl->offset <= apl->apl_len); if (apl->offset == apl->apl_len) return (ISC_R_NOMORE); /* * Sanity check data. */ INSIST(apl->apl_len > 3U); INSIST(apl->offset <= apl->apl_len - 4U); length = apl->apl[apl->offset + 3] & 0x7f; /* * 16 to 32 bits promotion as 'length' is 32 bits so there is * no overflow problems. */ INSIST(length + apl->offset <= apl->apl_len); ent->family = (apl->apl[apl->offset] << 8) + apl->apl[apl->offset + 1]; ent->prefix = apl->apl[apl->offset + 2]; ent->length = apl->apl[apl->offset + 3] & 0x7f; ent->negative = ISC_TF((apl->apl[apl->offset + 3] & 0x80) != 0); if (ent->length != 0) ent->data = &apl->apl[apl->offset + 4]; else ent->data = NULL; return (ISC_R_SUCCESS); } static inline isc_result_t additionaldata_in_apl(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_apl); REQUIRE(rdata->rdclass == dns_rdataclass_in); (void)add; (void)arg; return (ISC_R_SUCCESS); } static inline isc_result_t digest_in_apl(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_apl); REQUIRE(rdata->rdclass == dns_rdataclass_in); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_in_apl(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_apl); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_in_apl(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_apl); REQUIRE(rdata->rdclass == dns_rdataclass_in); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_in_apl(ARGS_COMPARE) { return (compare_in_apl(rdata1, rdata2)); } #endif /* RDATA_IN_1_APL_42_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/srv_33.c0000644000470500017500000002202312664710322020126 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: srv_33.c,v 1.47 2009/12/04 22:06:37 tbox Exp $ */ /* Reviewed: Fri Mar 17 13:01:00 PST 2000 by bwelling */ /* RFC2782 */ #ifndef RDATA_IN_1_SRV_33_C #define RDATA_IN_1_SRV_33_C #define RRTYPE_SRV_ATTRIBUTES (0) static inline isc_result_t fromtext_in_srv(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; isc_boolean_t ok; REQUIRE(type == dns_rdatatype_srv); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); /* * Priority. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Weight. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Port. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Target. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); ok = ISC_TRUE; if ((options & DNS_RDATA_CHECKNAMES) != 0) ok = dns_name_ishostname(&name, ISC_FALSE); if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) RETTOK(DNS_R_BADNAME); if (!ok && callbacks != NULL) warn_badname(&name, lexer, callbacks); return (ISC_R_SUCCESS); } static inline isc_result_t totext_in_srv(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; char buf[sizeof("64000")]; unsigned short num; REQUIRE(rdata->type == dns_rdatatype_srv); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length != 0); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); /* * Priority. */ dns_rdata_toregion(rdata, ®ion); num = uint16_fromregion(®ion); isc_region_consume(®ion, 2); sprintf(buf, "%u", num); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Weight. */ num = uint16_fromregion(®ion); isc_region_consume(®ion, 2); sprintf(buf, "%u", num); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Port. */ num = uint16_fromregion(®ion); isc_region_consume(®ion, 2); sprintf(buf, "%u", num); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Target. */ dns_name_fromregion(&name, ®ion); sub = name_prefix(&name, tctx->origin, &prefix); return (dns_name_totext(&prefix, sub, target)); } static inline isc_result_t fromwire_in_srv(ARGS_FROMWIRE) { dns_name_t name; isc_region_t sr; REQUIRE(type == dns_rdatatype_srv); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); dns_name_init(&name, NULL); /* * Priority, weight, port. */ isc_buffer_activeregion(source, &sr); if (sr.length < 6) return (ISC_R_UNEXPECTEDEND); RETERR(mem_tobuffer(target, sr.base, 6)); isc_buffer_forward(source, 6); /* * Target. */ return (dns_name_fromwire(&name, source, dctx, options, target)); } static inline isc_result_t towire_in_srv(ARGS_TOWIRE) { dns_name_t name; dns_offsets_t offsets; isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_srv); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); /* * Priority, weight, port. */ dns_rdata_toregion(rdata, &sr); RETERR(mem_tobuffer(target, sr.base, 6)); isc_region_consume(&sr, 6); /* * Target. */ dns_name_init(&name, offsets); dns_name_fromregion(&name, &sr); return (dns_name_towire(&name, cctx, target)); } static inline int compare_in_srv(ARGS_COMPARE) { dns_name_t name1; dns_name_t name2; isc_region_t region1; isc_region_t region2; int order; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_srv); REQUIRE(rdata1->rdclass == dns_rdataclass_in); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); /* * Priority, weight, port. */ order = memcmp(rdata1->data, rdata2->data, 6); if (order != 0) return (order < 0 ? -1 : 1); /* * Target. */ dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); isc_region_consume(®ion1, 6); isc_region_consume(®ion2, 6); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); return (dns_name_rdatacompare(&name1, &name2)); } static inline isc_result_t fromstruct_in_srv(ARGS_FROMSTRUCT) { dns_rdata_in_srv_t *srv = source; isc_region_t region; REQUIRE(type == dns_rdatatype_srv); REQUIRE(rdclass == dns_rdataclass_in); REQUIRE(source != NULL); REQUIRE(srv->common.rdtype == type); REQUIRE(srv->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); RETERR(uint16_tobuffer(srv->priority, target)); RETERR(uint16_tobuffer(srv->weight, target)); RETERR(uint16_tobuffer(srv->port, target)); dns_name_toregion(&srv->target, ®ion); return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_in_srv(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_in_srv_t *srv = target; dns_name_t name; REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->type == dns_rdatatype_srv); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); srv->common.rdclass = rdata->rdclass; srv->common.rdtype = rdata->type; ISC_LINK_INIT(&srv->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); srv->priority = uint16_fromregion(®ion); isc_region_consume(®ion, 2); srv->weight = uint16_fromregion(®ion); isc_region_consume(®ion, 2); srv->port = uint16_fromregion(®ion); isc_region_consume(®ion, 2); dns_name_fromregion(&name, ®ion); dns_name_init(&srv->target, NULL); RETERR(name_duporclone(&name, mctx, &srv->target)); srv->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_in_srv(ARGS_FREESTRUCT) { dns_rdata_in_srv_t *srv = source; REQUIRE(source != NULL); REQUIRE(srv->common.rdclass == dns_rdataclass_in); REQUIRE(srv->common.rdtype == dns_rdatatype_srv); if (srv->mctx == NULL) return; dns_name_free(&srv->target, srv->mctx); srv->mctx = NULL; } static inline isc_result_t additionaldata_in_srv(ARGS_ADDLDATA) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_srv); REQUIRE(rdata->rdclass == dns_rdataclass_in); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, ®ion); isc_region_consume(®ion, 6); dns_name_fromregion(&name, ®ion); return ((add)(arg, &name, dns_rdatatype_a)); } static inline isc_result_t digest_in_srv(ARGS_DIGEST) { isc_region_t r1, r2; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_srv); REQUIRE(rdata->rdclass == dns_rdataclass_in); dns_rdata_toregion(rdata, &r1); r2 = r1; isc_region_consume(&r2, 6); r1.length = 6; RETERR((digest)(arg, &r1)); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r2); return (dns_name_digest(&name, digest, arg)); } static inline isc_boolean_t checkowner_in_srv(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_srv); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_in_srv(ARGS_CHECKNAMES) { isc_region_t region; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_srv); REQUIRE(rdata->rdclass == dns_rdataclass_in); UNUSED(owner); dns_rdata_toregion(rdata, ®ion); isc_region_consume(®ion, 6); dns_name_init(&name, NULL); dns_name_fromregion(&name, ®ion); if (!dns_name_ishostname(&name, ISC_FALSE)) { if (bad != NULL) dns_name_clone(&name, bad); return (ISC_FALSE); } return (ISC_TRUE); } static inline int casecompare_in_srv(ARGS_COMPARE) { return (compare_in_srv(rdata1, rdata2)); } #endif /* RDATA_IN_1_SRV_33_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/nsap_22.c0000644000470500017500000001426312664710322020262 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2013, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: nsap_22.c,v 1.44 2009/12/04 22:06:37 tbox Exp $ */ /* Reviewed: Fri Mar 17 10:41:07 PST 2000 by gson */ /* RFC1706 */ #ifndef RDATA_IN_1_NSAP_22_C #define RDATA_IN_1_NSAP_22_C #define RRTYPE_NSAP_ATTRIBUTES (0) static inline isc_result_t fromtext_in_nsap(ARGS_FROMTEXT) { isc_token_t token; isc_textregion_t *sr; int n; isc_boolean_t valid = ISC_FALSE; int digits = 0; unsigned char c = 0; REQUIRE(type == dns_rdatatype_nsap); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(origin); UNUSED(options); UNUSED(rdclass); UNUSED(callbacks); /* 0x */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); sr = &token.value.as_textregion; if (sr->length < 2) RETTOK(ISC_R_UNEXPECTEDEND); if (sr->base[0] != '0' || (sr->base[1] != 'x' && sr->base[1] != 'X')) RETTOK(DNS_R_SYNTAX); isc_textregion_consume(sr, 2); while (sr->length > 0) { if (sr->base[0] == '.') { isc_textregion_consume(sr, 1); continue; } if ((n = hexvalue(sr->base[0])) == -1) RETTOK(DNS_R_SYNTAX); c <<= 4; c += n; if (++digits == 2) { RETERR(mem_tobuffer(target, &c, 1)); valid = ISC_TRUE; digits = 0; c = 0; } isc_textregion_consume(sr, 1); } if (digits != 0 || !valid) RETTOK(ISC_R_UNEXPECTEDEND); return (ISC_R_SUCCESS); } static inline isc_result_t totext_in_nsap(ARGS_TOTEXT) { isc_region_t region; char buf[sizeof("xx")]; REQUIRE(rdata->type == dns_rdatatype_nsap); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length != 0); UNUSED(tctx); dns_rdata_toregion(rdata, ®ion); RETERR(str_totext("0x", target)); while (region.length != 0) { sprintf(buf, "%02x", region.base[0]); isc_region_consume(®ion, 1); RETERR(str_totext(buf, target)); } return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_in_nsap(ARGS_FROMWIRE) { isc_region_t region; REQUIRE(type == dns_rdatatype_nsap); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(dctx); UNUSED(options); UNUSED(rdclass); isc_buffer_activeregion(source, ®ion); if (region.length < 1) return (ISC_R_UNEXPECTEDEND); RETERR(mem_tobuffer(target, region.base, region.length)); isc_buffer_forward(source, region.length); return (ISC_R_SUCCESS); } static inline isc_result_t towire_in_nsap(ARGS_TOWIRE) { REQUIRE(rdata->type == dns_rdatatype_nsap); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length != 0); UNUSED(cctx); return (mem_tobuffer(target, rdata->data, rdata->length)); } static inline int compare_in_nsap(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_nsap); REQUIRE(rdata1->rdclass == dns_rdataclass_in); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_in_nsap(ARGS_FROMSTRUCT) { dns_rdata_in_nsap_t *nsap = source; REQUIRE(type == dns_rdatatype_nsap); REQUIRE(rdclass == dns_rdataclass_in); REQUIRE(source != NULL); REQUIRE(nsap->common.rdtype == type); REQUIRE(nsap->common.rdclass == rdclass); REQUIRE(nsap->nsap != NULL || nsap->nsap_len == 0); UNUSED(type); UNUSED(rdclass); return (mem_tobuffer(target, nsap->nsap, nsap->nsap_len)); } static inline isc_result_t tostruct_in_nsap(ARGS_TOSTRUCT) { dns_rdata_in_nsap_t *nsap = target; isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_nsap); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); nsap->common.rdclass = rdata->rdclass; nsap->common.rdtype = rdata->type; ISC_LINK_INIT(&nsap->common, link); dns_rdata_toregion(rdata, &r); nsap->nsap_len = r.length; nsap->nsap = mem_maybedup(mctx, r.base, r.length); if (nsap->nsap == NULL) return (ISC_R_NOMEMORY); nsap->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_in_nsap(ARGS_FREESTRUCT) { dns_rdata_in_nsap_t *nsap = source; REQUIRE(source != NULL); REQUIRE(nsap->common.rdclass == dns_rdataclass_in); REQUIRE(nsap->common.rdtype == dns_rdatatype_nsap); if (nsap->mctx == NULL) return; if (nsap->nsap != NULL) isc_mem_free(nsap->mctx, nsap->nsap); nsap->mctx = NULL; } static inline isc_result_t additionaldata_in_nsap(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_nsap); REQUIRE(rdata->rdclass == dns_rdataclass_in); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_in_nsap(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_nsap); REQUIRE(rdata->rdclass == dns_rdataclass_in); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_in_nsap(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_nsap); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_in_nsap(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_nsap); REQUIRE(rdata->rdclass == dns_rdataclass_in); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_in_nsap(ARGS_COMPARE) { return (compare_in_nsap(rdata1, rdata2)); } #endif /* RDATA_IN_1_NSAP_22_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/dhcid_49.c0000644000470500017500000001321712664710322020403 0ustar lamontlamont/* * Copyright (C) 2006, 2007, 2009, 2011, 2012, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* RFC 4701 */ #ifndef RDATA_IN_1_DHCID_49_C #define RDATA_IN_1_DHCID_49_C 1 #define RRTYPE_DHCID_ATTRIBUTES 0 static inline isc_result_t fromtext_in_dhcid(ARGS_FROMTEXT) { REQUIRE(type == dns_rdatatype_dhcid); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); return (isc_base64_tobuffer(lexer, target, -1)); } static inline isc_result_t totext_in_dhcid(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof(" ; 64000 255 64000")]; size_t n; REQUIRE(rdata->type == dns_rdatatype_dhcid); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext("( " /*)*/, target)); if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(&sr, 60, "", target)); else RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { RETERR(str_totext(/* ( */ " )", target)); if (rdata->length > 2) { n = snprintf(buf, sizeof(buf), " ; %u %u %u", sr.base[0] * 256 + sr.base[1], sr.base[2], rdata->length - 3); INSIST(n < sizeof(buf)); RETERR(str_totext(buf, target)); } } return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_in_dhcid(ARGS_FROMWIRE) { isc_region_t sr; REQUIRE(type == dns_rdatatype_dhcid); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); isc_buffer_activeregion(source, &sr); if (sr.length == 0) return (ISC_R_UNEXPECTEDEND); isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); } static inline isc_result_t towire_in_dhcid(ARGS_TOWIRE) { isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_dhcid); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length != 0); UNUSED(cctx); dns_rdata_toregion(rdata, &sr); return (mem_tobuffer(target, sr.base, sr.length)); } static inline int compare_in_dhcid(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_dhcid); REQUIRE(rdata1->rdclass == dns_rdataclass_in); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_in_dhcid(ARGS_FROMSTRUCT) { dns_rdata_in_dhcid_t *dhcid = source; REQUIRE(type == dns_rdatatype_dhcid); REQUIRE(rdclass == dns_rdataclass_in); REQUIRE(source != NULL); REQUIRE(dhcid->common.rdtype == type); REQUIRE(dhcid->common.rdclass == rdclass); REQUIRE(dhcid->length != 0); UNUSED(type); UNUSED(rdclass); return (mem_tobuffer(target, dhcid->dhcid, dhcid->length)); } static inline isc_result_t tostruct_in_dhcid(ARGS_TOSTRUCT) { dns_rdata_in_dhcid_t *dhcid = target; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_dhcid); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); dhcid->common.rdclass = rdata->rdclass; dhcid->common.rdtype = rdata->type; ISC_LINK_INIT(&dhcid->common, link); dns_rdata_toregion(rdata, ®ion); dhcid->dhcid = mem_maybedup(mctx, region.base, region.length); if (dhcid->dhcid == NULL) return (ISC_R_NOMEMORY); dhcid->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_in_dhcid(ARGS_FREESTRUCT) { dns_rdata_in_dhcid_t *dhcid = source; REQUIRE(dhcid != NULL); REQUIRE(dhcid->common.rdtype == dns_rdatatype_dhcid); REQUIRE(dhcid->common.rdclass == dns_rdataclass_in); if (dhcid->mctx == NULL) return; if (dhcid->dhcid != NULL) isc_mem_free(dhcid->mctx, dhcid->dhcid); dhcid->mctx = NULL; } static inline isc_result_t additionaldata_in_dhcid(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_dhcid); REQUIRE(rdata->rdclass == dns_rdataclass_in); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_in_dhcid(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_dhcid); REQUIRE(rdata->rdclass == dns_rdataclass_in); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_in_dhcid(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_dhcid); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_in_dhcid(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_dhcid); REQUIRE(rdata->rdclass == dns_rdataclass_in); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_in_dhcid(ARGS_COMPARE) { return (compare_in_dhcid(rdata1, rdata2)); } #endif /* RDATA_IN_1_DHCID_49_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/wks_11.h0000644000470500017500000000224512664710322020125 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef IN_1_WKS_11_H #define IN_1_WKS_11_H 1 /* $Id: wks_11.h,v 1.22 2007/06/19 23:47:17 tbox Exp $ */ typedef struct dns_rdata_in_wks { dns_rdatacommon_t common; isc_mem_t *mctx; struct in_addr in_addr; isc_uint16_t protocol; unsigned char *map; isc_uint16_t map_len; } dns_rdata_in_wks_t; #endif /* IN_1_WKS_11_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/nsap_22.h0000644000470500017500000000224012664710322020257 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef IN_1_NSAP_22_H #define IN_1_NSAP_22_H 1 /* $Id: nsap_22.h,v 1.18 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief Per RFC1706 */ typedef struct dns_rdata_in_nsap { dns_rdatacommon_t common; isc_mem_t *mctx; unsigned char *nsap; isc_uint16_t nsap_len; } dns_rdata_in_nsap_t; #endif /* IN_1_NSAP_22_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/apl_42.h0000644000470500017500000000332712664710322020103 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef IN_1_APL_42_H #define IN_1_APL_42_H 1 /* $Id: apl_42.h,v 1.6 2007/06/19 23:47:17 tbox Exp $ */ typedef struct dns_rdata_apl_ent { isc_boolean_t negative; isc_uint16_t family; isc_uint8_t prefix; isc_uint8_t length; unsigned char *data; } dns_rdata_apl_ent_t; typedef struct dns_rdata_in_apl { dns_rdatacommon_t common; isc_mem_t *mctx; /* type & class specific elements */ unsigned char *apl; isc_uint16_t apl_len; /* private */ isc_uint16_t offset; } dns_rdata_in_apl_t; /* * ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS are already done * via rdatastructpre.h and rdatastructsuf.h. */ isc_result_t dns_rdata_apl_first(dns_rdata_in_apl_t *); isc_result_t dns_rdata_apl_next(dns_rdata_in_apl_t *); isc_result_t dns_rdata_apl_current(dns_rdata_in_apl_t *, dns_rdata_apl_ent_t *); #endif /* IN_1_APL_42_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/aaaa_28.c0000644000470500017500000001404212664710322020205 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: aaaa_28.c,v 1.47 2009/12/04 22:06:37 tbox Exp $ */ /* Reviewed: Thu Mar 16 16:52:50 PST 2000 by bwelling */ /* RFC1886 */ #ifndef RDATA_IN_1_AAAA_28_C #define RDATA_IN_1_AAAA_28_C #include #define RRTYPE_AAAA_ATTRIBUTES (0) static inline isc_result_t fromtext_in_aaaa(ARGS_FROMTEXT) { isc_token_t token; unsigned char addr[16]; isc_region_t region; REQUIRE(type == dns_rdatatype_aaaa); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(origin); UNUSED(options); UNUSED(rdclass); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (inet_pton(AF_INET6, DNS_AS_STR(token), addr) != 1) RETTOK(DNS_R_BADAAAA); isc_buffer_availableregion(target, ®ion); if (region.length < 16) return (ISC_R_NOSPACE); memmove(region.base, addr, 16); isc_buffer_add(target, 16); return (ISC_R_SUCCESS); } static inline isc_result_t totext_in_aaaa(ARGS_TOTEXT) { isc_region_t region; UNUSED(tctx); REQUIRE(rdata->type == dns_rdatatype_aaaa); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length == 16); dns_rdata_toregion(rdata, ®ion); return (inet_totext(AF_INET6, ®ion, target)); } static inline isc_result_t fromwire_in_aaaa(ARGS_FROMWIRE) { isc_region_t sregion; isc_region_t tregion; REQUIRE(type == dns_rdatatype_aaaa); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(dctx); UNUSED(options); UNUSED(rdclass); isc_buffer_activeregion(source, &sregion); isc_buffer_availableregion(target, &tregion); if (sregion.length < 16) return (ISC_R_UNEXPECTEDEND); if (tregion.length < 16) return (ISC_R_NOSPACE); memmove(tregion.base, sregion.base, 16); isc_buffer_forward(source, 16); isc_buffer_add(target, 16); return (ISC_R_SUCCESS); } static inline isc_result_t towire_in_aaaa(ARGS_TOWIRE) { isc_region_t region; UNUSED(cctx); REQUIRE(rdata->type == dns_rdatatype_aaaa); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length == 16); isc_buffer_availableregion(target, ®ion); if (region.length < rdata->length) return (ISC_R_NOSPACE); memmove(region.base, rdata->data, rdata->length); isc_buffer_add(target, 16); return (ISC_R_SUCCESS); } static inline int compare_in_aaaa(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_aaaa); REQUIRE(rdata1->rdclass == dns_rdataclass_in); REQUIRE(rdata1->length == 16); REQUIRE(rdata2->length == 16); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_in_aaaa(ARGS_FROMSTRUCT) { dns_rdata_in_aaaa_t *aaaa = source; REQUIRE(type == dns_rdatatype_aaaa); REQUIRE(rdclass == dns_rdataclass_in); REQUIRE(source != NULL); REQUIRE(aaaa->common.rdtype == type); REQUIRE(aaaa->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); return (mem_tobuffer(target, aaaa->in6_addr.s6_addr, 16)); } static inline isc_result_t tostruct_in_aaaa(ARGS_TOSTRUCT) { dns_rdata_in_aaaa_t *aaaa = target; isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_aaaa); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(target != NULL); REQUIRE(rdata->length == 16); UNUSED(mctx); aaaa->common.rdclass = rdata->rdclass; aaaa->common.rdtype = rdata->type; ISC_LINK_INIT(&aaaa->common, link); dns_rdata_toregion(rdata, &r); INSIST(r.length == 16); memmove(aaaa->in6_addr.s6_addr, r.base, 16); return (ISC_R_SUCCESS); } static inline void freestruct_in_aaaa(ARGS_FREESTRUCT) { dns_rdata_in_aaaa_t *aaaa = source; REQUIRE(source != NULL); REQUIRE(aaaa->common.rdclass == dns_rdataclass_in); REQUIRE(aaaa->common.rdtype == dns_rdatatype_aaaa); UNUSED(aaaa); } static inline isc_result_t additionaldata_in_aaaa(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_aaaa); REQUIRE(rdata->rdclass == dns_rdataclass_in); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_in_aaaa(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_aaaa); REQUIRE(rdata->rdclass == dns_rdataclass_in); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_in_aaaa(ARGS_CHECKOWNER) { dns_name_t prefix, suffix; REQUIRE(type == dns_rdatatype_aaaa); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(rdclass); /* * Handle Active Diretory gc._msdcs. name. */ if (dns_name_countlabels(name) > 2U) { dns_name_init(&prefix, NULL); dns_name_init(&suffix, NULL); dns_name_split(name, dns_name_countlabels(name) - 2, &prefix, &suffix); if (dns_name_equal(&gc_msdcs, &prefix) && dns_name_ishostname(&suffix, ISC_FALSE)) return (ISC_TRUE); } return (dns_name_ishostname(name, wildcard)); } static inline isc_boolean_t checknames_in_aaaa(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_aaaa); REQUIRE(rdata->rdclass == dns_rdataclass_in); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_in_aaaa(ARGS_COMPARE) { return (compare_in_aaaa(rdata1, rdata2)); } #endif /* RDATA_IN_1_AAAA_28_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/aaaa_28.h0000644000470500017500000000217112664710322020212 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef IN_1_AAAA_28_H #define IN_1_AAAA_28_H 1 /* $Id: aaaa_28.h,v 1.21 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief Per RFC1886 */ typedef struct dns_rdata_in_aaaa { dns_rdatacommon_t common; struct in6_addr in6_addr; } dns_rdata_in_aaaa_t; #endif /* IN_1_AAAA_28_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/kx_36.c0000644000470500017500000001636312664710322017753 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: kx_36.c,v 1.47 2009/12/04 22:06:37 tbox Exp $ */ /* Reviewed: Thu Mar 16 17:24:54 PST 2000 by explorer */ /* RFC2230 */ #ifndef RDATA_IN_1_KX_36_C #define RDATA_IN_1_KX_36_C #define RRTYPE_KX_ATTRIBUTES (0) static inline isc_result_t fromtext_in_kx(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; REQUIRE(type == dns_rdatatype_kx); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); return (ISC_R_SUCCESS); } static inline isc_result_t totext_in_kx(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; char buf[sizeof("64000")]; unsigned short num; REQUIRE(rdata->type == dns_rdatatype_kx); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length != 0); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, ®ion); num = uint16_fromregion(®ion); isc_region_consume(®ion, 2); sprintf(buf, "%u", num); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); dns_name_fromregion(&name, ®ion); sub = name_prefix(&name, tctx->origin, &prefix); return (dns_name_totext(&prefix, sub, target)); } static inline isc_result_t fromwire_in_kx(ARGS_FROMWIRE) { dns_name_t name; isc_region_t sregion; REQUIRE(type == dns_rdatatype_kx); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); dns_name_init(&name, NULL); isc_buffer_activeregion(source, &sregion); if (sregion.length < 2) return (ISC_R_UNEXPECTEDEND); RETERR(mem_tobuffer(target, sregion.base, 2)); isc_buffer_forward(source, 2); return (dns_name_fromwire(&name, source, dctx, options, target)); } static inline isc_result_t towire_in_kx(ARGS_TOWIRE) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_kx); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); dns_rdata_toregion(rdata, ®ion); RETERR(mem_tobuffer(target, region.base, 2)); isc_region_consume(®ion, 2); dns_name_init(&name, offsets); dns_name_fromregion(&name, ®ion); return (dns_name_towire(&name, cctx, target)); } static inline int compare_in_kx(ARGS_COMPARE) { dns_name_t name1; dns_name_t name2; isc_region_t region1; isc_region_t region2; int order; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_kx); REQUIRE(rdata1->rdclass == dns_rdataclass_in); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); order = memcmp(rdata1->data, rdata2->data, 2); if (order != 0) return (order < 0 ? -1 : 1); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); isc_region_consume(®ion1, 2); isc_region_consume(®ion2, 2); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); return (dns_name_rdatacompare(&name1, &name2)); } static inline isc_result_t fromstruct_in_kx(ARGS_FROMSTRUCT) { dns_rdata_in_kx_t *kx = source; isc_region_t region; REQUIRE(type == dns_rdatatype_kx); REQUIRE(rdclass == dns_rdataclass_in); REQUIRE(source != NULL); REQUIRE(kx->common.rdtype == type); REQUIRE(kx->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); RETERR(uint16_tobuffer(kx->preference, target)); dns_name_toregion(&kx->exchange, ®ion); return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_in_kx(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_in_kx_t *kx = target; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_kx); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); kx->common.rdclass = rdata->rdclass; kx->common.rdtype = rdata->type; ISC_LINK_INIT(&kx->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); kx->preference = uint16_fromregion(®ion); isc_region_consume(®ion, 2); dns_name_fromregion(&name, ®ion); dns_name_init(&kx->exchange, NULL); RETERR(name_duporclone(&name, mctx, &kx->exchange)); kx->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_in_kx(ARGS_FREESTRUCT) { dns_rdata_in_kx_t *kx = source; REQUIRE(source != NULL); REQUIRE(kx->common.rdclass == dns_rdataclass_in); REQUIRE(kx->common.rdtype == dns_rdatatype_kx); if (kx->mctx == NULL) return; dns_name_free(&kx->exchange, kx->mctx); kx->mctx = NULL; } static inline isc_result_t additionaldata_in_kx(ARGS_ADDLDATA) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_kx); REQUIRE(rdata->rdclass == dns_rdataclass_in); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, ®ion); isc_region_consume(®ion, 2); dns_name_fromregion(&name, ®ion); return ((add)(arg, &name, dns_rdatatype_a)); } static inline isc_result_t digest_in_kx(ARGS_DIGEST) { isc_region_t r1, r2; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_kx); REQUIRE(rdata->rdclass == dns_rdataclass_in); dns_rdata_toregion(rdata, &r1); r2 = r1; isc_region_consume(&r2, 2); r1.length = 2; RETERR((digest)(arg, &r1)); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r2); return (dns_name_digest(&name, digest, arg)); } static inline isc_boolean_t checkowner_in_kx(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_kx); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_in_kx(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_kx); REQUIRE(rdata->rdclass == dns_rdataclass_in); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_in_kx(ARGS_COMPARE) { return (compare_in_kx(rdata1, rdata2)); } #endif /* RDATA_IN_1_KX_36_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/a_1.h0000644000470500017500000000211712664710322017456 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef IN_1_A_1_H #define IN_1_A_1_H 1 /* $Id: a_1.h,v 1.28 2007/06/19 23:47:17 tbox Exp $ */ typedef struct dns_rdata_in_a { dns_rdatacommon_t common; struct in_addr in_addr; } dns_rdata_in_a_t; #endif /* IN_1_A_1_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/in_1/nsap-ptr_23.c0000644000470500017500000001447312664710322021071 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: nsap-ptr_23.c,v 1.40 2009/12/04 22:06:37 tbox Exp $ */ /* Reviewed: Fri Mar 17 10:16:02 PST 2000 by gson */ /* RFC1348. Obsoleted in RFC 1706 - use PTR instead. */ #ifndef RDATA_IN_1_NSAP_PTR_23_C #define RDATA_IN_1_NSAP_PTR_23_C #define RRTYPE_NSAP_PTR_ATTRIBUTES (0) static inline isc_result_t fromtext_in_nsap_ptr(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; REQUIRE(type == dns_rdatatype_nsap_ptr); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); return (ISC_R_SUCCESS); } static inline isc_result_t totext_in_nsap_ptr(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; REQUIRE(rdata->type == dns_rdatatype_nsap_ptr); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length != 0); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); sub = name_prefix(&name, tctx->origin, &prefix); return (dns_name_totext(&prefix, sub, target)); } static inline isc_result_t fromwire_in_nsap_ptr(ARGS_FROMWIRE) { dns_name_t name; REQUIRE(type == dns_rdatatype_nsap_ptr); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); dns_name_init(&name, NULL); return (dns_name_fromwire(&name, source, dctx, options, target)); } static inline isc_result_t towire_in_nsap_ptr(ARGS_TOWIRE) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_nsap_ptr); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); return (dns_name_towire(&name, cctx, target)); } static inline int compare_in_nsap_ptr(ARGS_COMPARE) { dns_name_t name1; dns_name_t name2; isc_region_t region1; isc_region_t region2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_nsap_ptr); REQUIRE(rdata1->rdclass == dns_rdataclass_in); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); return (dns_name_rdatacompare(&name1, &name2)); } static inline isc_result_t fromstruct_in_nsap_ptr(ARGS_FROMSTRUCT) { dns_rdata_in_nsap_ptr_t *nsap_ptr = source; isc_region_t region; REQUIRE(type == dns_rdatatype_nsap_ptr); REQUIRE(rdclass == dns_rdataclass_in); REQUIRE(source != NULL); REQUIRE(nsap_ptr->common.rdtype == type); REQUIRE(nsap_ptr->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); dns_name_toregion(&nsap_ptr->owner, ®ion); return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_in_nsap_ptr(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_in_nsap_ptr_t *nsap_ptr = target; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_nsap_ptr); REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); nsap_ptr->common.rdclass = rdata->rdclass; nsap_ptr->common.rdtype = rdata->type; ISC_LINK_INIT(&nsap_ptr->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); dns_name_init(&nsap_ptr->owner, NULL); RETERR(name_duporclone(&name, mctx, &nsap_ptr->owner)); nsap_ptr->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_in_nsap_ptr(ARGS_FREESTRUCT) { dns_rdata_in_nsap_ptr_t *nsap_ptr = source; REQUIRE(source != NULL); REQUIRE(nsap_ptr->common.rdclass == dns_rdataclass_in); REQUIRE(nsap_ptr->common.rdtype == dns_rdatatype_nsap_ptr); if (nsap_ptr->mctx == NULL) return; dns_name_free(&nsap_ptr->owner, nsap_ptr->mctx); nsap_ptr->mctx = NULL; } static inline isc_result_t additionaldata_in_nsap_ptr(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_nsap_ptr); REQUIRE(rdata->rdclass == dns_rdataclass_in); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_in_nsap_ptr(ARGS_DIGEST) { isc_region_t r; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_nsap_ptr); REQUIRE(rdata->rdclass == dns_rdataclass_in); dns_rdata_toregion(rdata, &r); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); return (dns_name_digest(&name, digest, arg)); } static inline isc_boolean_t checkowner_in_nsap_ptr(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_nsap_ptr); REQUIRE(rdclass == dns_rdataclass_in); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_in_nsap_ptr(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_nsap_ptr); REQUIRE(rdata->rdclass == dns_rdataclass_in); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_in_nsap_ptr(ARGS_COMPARE) { return (compare_in_nsap_ptr(rdata1, rdata2)); } #endif /* RDATA_IN_1_NSAP_PTR_23_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/hs_4/0002755000470500017500000000000012672612753016665 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/dns/rdata/hs_4/a_1.c0000644000470500017500000001255712664710322017471 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: a_1.c,v 1.33 2009/12/04 22:06:37 tbox Exp $ */ /* reviewed: Thu Mar 16 15:58:36 PST 2000 by brister */ #ifndef RDATA_HS_4_A_1_C #define RDATA_HS_4_A_1_C #include #define RRTYPE_A_ATTRIBUTES (0) static inline isc_result_t fromtext_hs_a(ARGS_FROMTEXT) { isc_token_t token; struct in_addr addr; isc_region_t region; REQUIRE(type == dns_rdatatype_a); REQUIRE(rdclass == dns_rdataclass_hs); UNUSED(type); UNUSED(origin); UNUSED(options); UNUSED(rdclass); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1) RETTOK(DNS_R_BADDOTTEDQUAD); isc_buffer_availableregion(target, ®ion); if (region.length < 4) return (ISC_R_NOSPACE); memmove(region.base, &addr, 4); isc_buffer_add(target, 4); return (ISC_R_SUCCESS); } static inline isc_result_t totext_hs_a(ARGS_TOTEXT) { isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_a); REQUIRE(rdata->rdclass == dns_rdataclass_hs); REQUIRE(rdata->length == 4); UNUSED(tctx); dns_rdata_toregion(rdata, ®ion); return (inet_totext(AF_INET, ®ion, target)); } static inline isc_result_t fromwire_hs_a(ARGS_FROMWIRE) { isc_region_t sregion; isc_region_t tregion; REQUIRE(type == dns_rdatatype_a); REQUIRE(rdclass == dns_rdataclass_hs); UNUSED(type); UNUSED(dctx); UNUSED(options); UNUSED(rdclass); isc_buffer_activeregion(source, &sregion); isc_buffer_availableregion(target, &tregion); if (sregion.length < 4) return (ISC_R_UNEXPECTEDEND); if (tregion.length < 4) return (ISC_R_NOSPACE); memmove(tregion.base, sregion.base, 4); isc_buffer_forward(source, 4); isc_buffer_add(target, 4); return (ISC_R_SUCCESS); } static inline isc_result_t towire_hs_a(ARGS_TOWIRE) { isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_a); REQUIRE(rdata->rdclass == dns_rdataclass_hs); REQUIRE(rdata->length == 4); UNUSED(cctx); isc_buffer_availableregion(target, ®ion); if (region.length < rdata->length) return (ISC_R_NOSPACE); memmove(region.base, rdata->data, rdata->length); isc_buffer_add(target, 4); return (ISC_R_SUCCESS); } static inline int compare_hs_a(ARGS_COMPARE) { int order; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_a); REQUIRE(rdata1->rdclass == dns_rdataclass_hs); REQUIRE(rdata1->length == 4); REQUIRE(rdata2->length == 4); order = memcmp(rdata1->data, rdata2->data, 4); if (order != 0) order = (order < 0) ? -1 : 1; return (order); } static inline isc_result_t fromstruct_hs_a(ARGS_FROMSTRUCT) { dns_rdata_hs_a_t *a = source; isc_uint32_t n; REQUIRE(type == dns_rdatatype_a); REQUIRE(rdclass == dns_rdataclass_hs); REQUIRE(source != NULL); REQUIRE(a->common.rdtype == type); REQUIRE(a->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); n = ntohl(a->in_addr.s_addr); return (uint32_tobuffer(n, target)); } static inline isc_result_t tostruct_hs_a(ARGS_TOSTRUCT) { dns_rdata_hs_a_t *a = target; isc_uint32_t n; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_a); REQUIRE(rdata->rdclass == dns_rdataclass_hs); REQUIRE(rdata->length == 4); UNUSED(mctx); a->common.rdclass = rdata->rdclass; a->common.rdtype = rdata->type; ISC_LINK_INIT(&a->common, link); dns_rdata_toregion(rdata, ®ion); n = uint32_fromregion(®ion); a->in_addr.s_addr = htonl(n); return (ISC_R_SUCCESS); } static inline void freestruct_hs_a(ARGS_FREESTRUCT) { UNUSED(source); REQUIRE(source != NULL); } static inline isc_result_t additionaldata_hs_a(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_a); REQUIRE(rdata->rdclass == dns_rdataclass_hs); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_hs_a(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_a); REQUIRE(rdata->rdclass == dns_rdataclass_hs); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_hs_a(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_a); REQUIRE(rdclass == dns_rdataclass_hs); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_hs_a(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_a); REQUIRE(rdata->rdclass == dns_rdataclass_hs); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_hs_a(ARGS_COMPARE) { return (compare_hs_a(rdata1, rdata2)); } #endif /* RDATA_HS_4_A_1_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/hs_4/a_1.h0000644000470500017500000000211712664710322017465 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef HS_4_A_1_H #define HS_4_A_1_H 1 /* $Id: a_1.h,v 1.12 2007/06/19 23:47:17 tbox Exp $ */ typedef struct dns_rdata_hs_a { dns_rdatacommon_t common; struct in_addr in_addr; } dns_rdata_hs_a_t; #endif /* HS_4_A_1_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/rdatastructpre.h0000644000470500017500000000265112664710322021242 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rdatastructpre.h,v 1.16 2007/06/19 23:47:17 tbox Exp $ */ #ifndef DNS_RDATASTRUCT_H #define DNS_RDATASTRUCT_H 1 #include #include #include #include ISC_LANG_BEGINDECLS typedef struct dns_rdatacommon { dns_rdataclass_t rdclass; dns_rdatatype_t rdtype; ISC_LINK(struct dns_rdatacommon) link; } dns_rdatacommon_t; #define DNS_RDATACOMMON_INIT(_data, _rdtype, _rdclass) \ do { \ (_data)->common.rdtype = (_rdtype); \ (_data)->common.rdclass = (_rdclass); \ ISC_LINK_INIT(&(_data)->common, link); \ } while (0) bind9-9.10.3.dfsg.P4/lib/dns/rdata/rdatastructsuf.h0000644000470500017500000000171512664710322021251 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rdatastructsuf.h,v 1.10 2007/06/19 23:47:17 tbox Exp $ */ ISC_LANG_ENDDECLS #endif /* DNS_RDATASTRUCT_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/0002755000470500017500000000000012672612753017444 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/dname_39.h0000644000470500017500000000221512664710322021202 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_DNAME_39_H #define GENERIC_DNAME_39_H 1 /* $Id: dname_39.h,v 1.21 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief per RFC2672 */ typedef struct dns_rdata_dname { dns_rdatacommon_t common; isc_mem_t *mctx; dns_name_t dname; } dns_rdata_dname_t; #endif /* GENERIC_DNAME_39_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/rrsig_46.h0000644000470500017500000000257112664710322021247 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_DNSSIG_46_H #define GENERIC_DNSSIG_46_H 1 /* $Id: rrsig_46.h,v 1.7 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief Per RFC2535 */ typedef struct dns_rdata_rrsig { dns_rdatacommon_t common; isc_mem_t * mctx; dns_rdatatype_t covered; dns_secalg_t algorithm; isc_uint8_t labels; isc_uint32_t originalttl; isc_uint32_t timeexpire; isc_uint32_t timesigned; isc_uint16_t keyid; dns_name_t signer; isc_uint16_t siglen; unsigned char * signature; } dns_rdata_rrsig_t; #endif /* GENERIC_DNSSIG_46_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/sig_24.h0000644000470500017500000000256312664710322020700 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_SIG_24_H #define GENERIC_SIG_24_H 1 /* $Id: sig_24.h,v 1.26 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief Per RFC2535 */ typedef struct dns_rdata_sig_t { dns_rdatacommon_t common; isc_mem_t * mctx; dns_rdatatype_t covered; dns_secalg_t algorithm; isc_uint8_t labels; isc_uint32_t originalttl; isc_uint32_t timeexpire; isc_uint32_t timesigned; isc_uint16_t keyid; dns_name_t signer; isc_uint16_t siglen; unsigned char * signature; } dns_rdata_sig_t; #endif /* GENERIC_SIG_24_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/cds_59.h0000644000470500017500000000220412664710322020667 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_CDS_59_H #define GENERIC_CDS_59_H 1 /* CDS records have the same RDATA fields as DS records. */ typedef struct dns_rdata_cds { dns_rdatacommon_t common; isc_mem_t *mctx; isc_uint16_t key_tag; isc_uint8_t algorithm; isc_uint8_t digest_type; isc_uint16_t length; unsigned char *digest; } dns_rdata_cds_t; #endif /* GENERIC_CDS_59_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/ns_2.c0000644000470500017500000001400112664710322020433 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ns_2.c,v 1.48 2009/12/04 22:06:37 tbox Exp $ */ /* Reviewed: Wed Mar 15 18:15:00 PST 2000 by bwelling */ #ifndef RDATA_GENERIC_NS_2_C #define RDATA_GENERIC_NS_2_C #define RRTYPE_NS_ATTRIBUTES (DNS_RDATATYPEATTR_ZONECUTAUTH) static inline isc_result_t fromtext_ns(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; isc_boolean_t ok; REQUIRE(type == dns_rdatatype_ns); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token,isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); ok = ISC_TRUE; if ((options & DNS_RDATA_CHECKNAMES) != 0) ok = dns_name_ishostname(&name, ISC_FALSE); if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) RETTOK(DNS_R_BADNAME); if (!ok && callbacks != NULL) warn_badname(&name, lexer, callbacks); return (ISC_R_SUCCESS); } static inline isc_result_t totext_ns(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; REQUIRE(rdata->type == dns_rdatatype_ns); REQUIRE(rdata->length != 0); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); sub = name_prefix(&name, tctx->origin, &prefix); return (dns_name_totext(&prefix, sub, target)); } static inline isc_result_t fromwire_ns(ARGS_FROMWIRE) { dns_name_t name; REQUIRE(type == dns_rdatatype_ns); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, NULL); return (dns_name_fromwire(&name, source, dctx, options, target)); } static inline isc_result_t towire_ns(ARGS_TOWIRE) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_ns); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); return (dns_name_towire(&name, cctx, target)); } static inline int compare_ns(ARGS_COMPARE) { dns_name_t name1; dns_name_t name2; isc_region_t region1; isc_region_t region2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_ns); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); return (dns_name_rdatacompare(&name1, &name2)); } static inline isc_result_t fromstruct_ns(ARGS_FROMSTRUCT) { dns_rdata_ns_t *ns = source; isc_region_t region; REQUIRE(type == dns_rdatatype_ns); REQUIRE(source != NULL); REQUIRE(ns->common.rdtype == type); REQUIRE(ns->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); dns_name_toregion(&ns->name, ®ion); return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_ns(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_ns_t *ns = target; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_ns); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); ns->common.rdclass = rdata->rdclass; ns->common.rdtype = rdata->type; ISC_LINK_INIT(&ns->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); dns_name_init(&ns->name, NULL); RETERR(name_duporclone(&name, mctx, &ns->name)); ns->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_ns(ARGS_FREESTRUCT) { dns_rdata_ns_t *ns = source; REQUIRE(source != NULL); if (ns->mctx == NULL) return; dns_name_free(&ns->name, ns->mctx); ns->mctx = NULL; } static inline isc_result_t additionaldata_ns(ARGS_ADDLDATA) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_ns); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); return ((add)(arg, &name, dns_rdatatype_a)); } static inline isc_result_t digest_ns(ARGS_DIGEST) { isc_region_t r; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_ns); dns_rdata_toregion(rdata, &r); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); return (dns_name_digest(&name, digest, arg)); } static inline isc_boolean_t checkowner_ns(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_ns); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_ns(ARGS_CHECKNAMES) { isc_region_t region; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_ns); UNUSED(owner); dns_rdata_toregion(rdata, ®ion); dns_name_init(&name, NULL); dns_name_fromregion(&name, ®ion); if (!dns_name_ishostname(&name, ISC_FALSE)) { if (bad != NULL) dns_name_clone(&name, bad); return (ISC_FALSE); } return (ISC_TRUE); } static inline int casecompare_ns(ARGS_COMPARE) { return (compare_ns(rdata1, rdata2)); } #endif /* RDATA_GENERIC_NS_2_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/dlv_32769.c0000644000470500017500000002040512664710322021136 0ustar lamontlamont/* * Copyright (C) 2004, 2006, 2007, 2009-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* RFC3658 */ #ifndef RDATA_GENERIC_DLV_32769_C #define RDATA_GENERIC_DLV_32769_C #define RRTYPE_DLV_ATTRIBUTES 0 #include #include #include #include "dst_gost.h" static inline isc_result_t fromtext_dlv(ARGS_FROMTEXT) { isc_token_t token; unsigned char c; int length; REQUIRE(type == dns_rdatatype_dlv); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); /* * Key tag. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Algorithm. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffU) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer(token.value.as_ulong, target)); /* * Digest type. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffU) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer(token.value.as_ulong, target)); c = (unsigned char) token.value.as_ulong; /* * Digest. */ switch (c) { case DNS_DSDIGEST_SHA1: length = ISC_SHA1_DIGESTLENGTH; break; case DNS_DSDIGEST_SHA256: length = ISC_SHA256_DIGESTLENGTH; break; #ifdef ISC_GOST_DIGESTLENGTH case DNS_DSDIGEST_GOST: length = ISC_GOST_DIGESTLENGTH; break; #endif case DNS_DSDIGEST_SHA384: length = ISC_SHA384_DIGESTLENGTH; break; default: length = -1; break; } return (isc_hex_tobuffer(lexer, target, length)); } static inline isc_result_t totext_dlv(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("64000 ")]; unsigned int n; REQUIRE(rdata->type == dns_rdatatype_dlv); REQUIRE(rdata->length != 0); UNUSED(tctx); dns_rdata_toregion(rdata, &sr); /* * Key tag. */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%u ", n); RETERR(str_totext(buf, target)); /* * Algorithm. */ n = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u ", n); RETERR(str_totext(buf, target)); /* * Digest type. */ n = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u", n); RETERR(str_totext(buf, target)); /* * Digest. */ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) { if (tctx->width == 0) /* No splitting */ RETERR(isc_hex_totext(&sr, 0, "", target)); else RETERR(isc_hex_totext(&sr, tctx->width - 2, tctx->linebreak, target)); } else RETERR(str_totext("[omitted]", target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_dlv(ARGS_FROMWIRE) { isc_region_t sr; REQUIRE(type == dns_rdatatype_dlv); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); isc_buffer_activeregion(source, &sr); /* * Check digest lengths if we know them. */ if (sr.length < 4 || (sr.base[3] == DNS_DSDIGEST_SHA1 && sr.length < 4 + ISC_SHA1_DIGESTLENGTH) || (sr.base[3] == DNS_DSDIGEST_SHA256 && sr.length < 4 + ISC_SHA256_DIGESTLENGTH) || #ifdef ISC_GOST_DIGESTLENGTH (sr.base[3] == DNS_DSDIGEST_GOST && sr.length < 4 + ISC_GOST_DIGESTLENGTH) || #endif (sr.base[3] == DNS_DSDIGEST_SHA384 && sr.length < 4 + ISC_SHA384_DIGESTLENGTH)) return (ISC_R_UNEXPECTEDEND); /* * Only copy digest lengths if we know them. * If there is extra data dns_rdata_fromwire() will * detect that. */ if (sr.base[3] == DNS_DSDIGEST_SHA1) sr.length = 4 + ISC_SHA1_DIGESTLENGTH; else if (sr.base[3] == DNS_DSDIGEST_SHA256) sr.length = 4 + ISC_SHA256_DIGESTLENGTH; #ifdef ISC_GOST_DIGESTLENGTH else if (sr.base[3] == DNS_DSDIGEST_GOST) sr.length = 4 + ISC_GOST_DIGESTLENGTH; #endif else if (sr.base[3] == DNS_DSDIGEST_SHA384) sr.length = 4 + ISC_SHA384_DIGESTLENGTH; isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); } static inline isc_result_t towire_dlv(ARGS_TOWIRE) { isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_dlv); REQUIRE(rdata->length != 0); UNUSED(cctx); dns_rdata_toregion(rdata, &sr); return (mem_tobuffer(target, sr.base, sr.length)); } static inline int compare_dlv(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_dlv); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_dlv(ARGS_FROMSTRUCT) { dns_rdata_dlv_t *dlv = source; REQUIRE(type == dns_rdatatype_dlv); REQUIRE(source != NULL); REQUIRE(dlv->common.rdtype == type); REQUIRE(dlv->common.rdclass == rdclass); switch (dlv->digest_type) { case DNS_DSDIGEST_SHA1: REQUIRE(dlv->length == ISC_SHA1_DIGESTLENGTH); break; case DNS_DSDIGEST_SHA256: REQUIRE(dlv->length == ISC_SHA256_DIGESTLENGTH); break; #ifdef ISC_GOST_DIGESTLENGTH case DNS_DSDIGEST_GOST: REQUIRE(dlv->length == ISC_GOST_DIGESTLENGTH); break; #endif case DNS_DSDIGEST_SHA384: REQUIRE(dlv->length == ISC_SHA384_DIGESTLENGTH); break; } UNUSED(type); UNUSED(rdclass); RETERR(uint16_tobuffer(dlv->key_tag, target)); RETERR(uint8_tobuffer(dlv->algorithm, target)); RETERR(uint8_tobuffer(dlv->digest_type, target)); return (mem_tobuffer(target, dlv->digest, dlv->length)); } static inline isc_result_t tostruct_dlv(ARGS_TOSTRUCT) { dns_rdata_dlv_t *dlv = target; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_dlv); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); dlv->common.rdclass = rdata->rdclass; dlv->common.rdtype = rdata->type; ISC_LINK_INIT(&dlv->common, link); dns_rdata_toregion(rdata, ®ion); dlv->key_tag = uint16_fromregion(®ion); isc_region_consume(®ion, 2); dlv->algorithm = uint8_fromregion(®ion); isc_region_consume(®ion, 1); dlv->digest_type = uint8_fromregion(®ion); isc_region_consume(®ion, 1); dlv->length = region.length; dlv->digest = mem_maybedup(mctx, region.base, region.length); if (dlv->digest == NULL) return (ISC_R_NOMEMORY); dlv->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_dlv(ARGS_FREESTRUCT) { dns_rdata_dlv_t *dlv = source; REQUIRE(dlv != NULL); REQUIRE(dlv->common.rdtype == dns_rdatatype_dlv); if (dlv->mctx == NULL) return; if (dlv->digest != NULL) isc_mem_free(dlv->mctx, dlv->digest); dlv->mctx = NULL; } static inline isc_result_t additionaldata_dlv(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_dlv); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_dlv(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_dlv); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_dlv(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_dlv); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_dlv(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_dlv); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_dlv(ARGS_COMPARE) { return (compare_dlv(rdata1, rdata2)); } #endif /* RDATA_GENERIC_DLV_32769_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/ds_43.c0000644000470500017500000002034412664710322020515 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* RFC3658 */ #ifndef RDATA_GENERIC_DS_43_C #define RDATA_GENERIC_DS_43_C #define RRTYPE_DS_ATTRIBUTES \ (DNS_RDATATYPEATTR_DNSSEC|DNS_RDATATYPEATTR_ATPARENT) #include #include #include #include "dst_gost.h" static inline isc_result_t fromtext_ds(ARGS_FROMTEXT) { isc_token_t token; unsigned char c; int length; REQUIRE(type == dns_rdatatype_ds); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); /* * Key tag. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Algorithm. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion)); RETERR(mem_tobuffer(target, &c, 1)); /* * Digest type. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_dsdigest_fromtext(&c, &token.value.as_textregion)); RETERR(mem_tobuffer(target, &c, 1)); /* * Digest. */ switch (c) { case DNS_DSDIGEST_SHA1: length = ISC_SHA1_DIGESTLENGTH; break; case DNS_DSDIGEST_SHA256: length = ISC_SHA256_DIGESTLENGTH; break; #ifdef ISC_GOST_DIGESTLENGTH case DNS_DSDIGEST_GOST: length = ISC_GOST_DIGESTLENGTH; break; #endif case DNS_DSDIGEST_SHA384: length = ISC_SHA384_DIGESTLENGTH; break; default: length = -1; break; } return (isc_hex_tobuffer(lexer, target, length)); } static inline isc_result_t totext_ds(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("64000 ")]; unsigned int n; REQUIRE(rdata->type == dns_rdatatype_ds); REQUIRE(rdata->length != 0); UNUSED(tctx); dns_rdata_toregion(rdata, &sr); /* * Key tag. */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%u ", n); RETERR(str_totext(buf, target)); /* * Algorithm. */ n = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u ", n); RETERR(str_totext(buf, target)); /* * Digest type. */ n = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u", n); RETERR(str_totext(buf, target)); /* * Digest. */ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) { if (tctx->width == 0) /* No splitting */ RETERR(isc_hex_totext(&sr, 0, "", target)); else RETERR(isc_hex_totext(&sr, tctx->width - 2, tctx->linebreak, target)); } else RETERR(str_totext("[omitted]", target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_ds(ARGS_FROMWIRE) { isc_region_t sr; REQUIRE(type == dns_rdatatype_ds); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); isc_buffer_activeregion(source, &sr); /* * Check digest lengths if we know them. */ if (sr.length < 4 || (sr.base[3] == DNS_DSDIGEST_SHA1 && sr.length < 4 + ISC_SHA1_DIGESTLENGTH) || (sr.base[3] == DNS_DSDIGEST_SHA256 && sr.length < 4 + ISC_SHA256_DIGESTLENGTH) || #ifdef ISC_GOST_DIGESTLENGTH (sr.base[3] == DNS_DSDIGEST_GOST && sr.length < 4 + ISC_GOST_DIGESTLENGTH) || #endif (sr.base[3] == DNS_DSDIGEST_SHA384 && sr.length < 4 + ISC_SHA384_DIGESTLENGTH)) return (ISC_R_UNEXPECTEDEND); /* * Only copy digest lengths if we know them. * If there is extra data dns_rdata_fromwire() will * detect that. */ if (sr.base[3] == DNS_DSDIGEST_SHA1) sr.length = 4 + ISC_SHA1_DIGESTLENGTH; else if (sr.base[3] == DNS_DSDIGEST_SHA256) sr.length = 4 + ISC_SHA256_DIGESTLENGTH; #ifdef ISC_GOST_DIGESTLENGTH else if (sr.base[3] == DNS_DSDIGEST_GOST) sr.length = 4 + ISC_GOST_DIGESTLENGTH; #endif else if (sr.base[3] == DNS_DSDIGEST_SHA384) sr.length = 4 + ISC_SHA384_DIGESTLENGTH; isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); } static inline isc_result_t towire_ds(ARGS_TOWIRE) { isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_ds); REQUIRE(rdata->length != 0); UNUSED(cctx); dns_rdata_toregion(rdata, &sr); return (mem_tobuffer(target, sr.base, sr.length)); } static inline int compare_ds(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_ds); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_ds(ARGS_FROMSTRUCT) { dns_rdata_ds_t *ds = source; REQUIRE(type == dns_rdatatype_ds); REQUIRE(source != NULL); REQUIRE(ds->common.rdtype == type); REQUIRE(ds->common.rdclass == rdclass); switch (ds->digest_type) { case DNS_DSDIGEST_SHA1: REQUIRE(ds->length == ISC_SHA1_DIGESTLENGTH); break; case DNS_DSDIGEST_SHA256: REQUIRE(ds->length == ISC_SHA256_DIGESTLENGTH); break; #ifdef ISC_GOST_DIGESTLENGTH case DNS_DSDIGEST_GOST: REQUIRE(ds->length == ISC_GOST_DIGESTLENGTH); break; #endif case DNS_DSDIGEST_SHA384: REQUIRE(ds->length == ISC_SHA384_DIGESTLENGTH); break; } UNUSED(type); UNUSED(rdclass); RETERR(uint16_tobuffer(ds->key_tag, target)); RETERR(uint8_tobuffer(ds->algorithm, target)); RETERR(uint8_tobuffer(ds->digest_type, target)); return (mem_tobuffer(target, ds->digest, ds->length)); } static inline isc_result_t tostruct_ds(ARGS_TOSTRUCT) { dns_rdata_ds_t *ds = target; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_ds); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); ds->common.rdclass = rdata->rdclass; ds->common.rdtype = rdata->type; ISC_LINK_INIT(&ds->common, link); dns_rdata_toregion(rdata, ®ion); ds->key_tag = uint16_fromregion(®ion); isc_region_consume(®ion, 2); ds->algorithm = uint8_fromregion(®ion); isc_region_consume(®ion, 1); ds->digest_type = uint8_fromregion(®ion); isc_region_consume(®ion, 1); ds->length = region.length; ds->digest = mem_maybedup(mctx, region.base, region.length); if (ds->digest == NULL) return (ISC_R_NOMEMORY); ds->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_ds(ARGS_FREESTRUCT) { dns_rdata_ds_t *ds = source; REQUIRE(ds != NULL); REQUIRE(ds->common.rdtype == dns_rdatatype_ds); if (ds->mctx == NULL) return; if (ds->digest != NULL) isc_mem_free(ds->mctx, ds->digest); ds->mctx = NULL; } static inline isc_result_t additionaldata_ds(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_ds); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_ds(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_ds); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_ds(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_ds); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_ds(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_ds); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_ds(ARGS_COMPARE) { return (compare_ds(rdata1, rdata2)); } #endif /* RDATA_GENERIC_DS_43_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/afsdb_18.c0000644000470500017500000001710012664710322021164 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: afsdb_18.c,v 1.49 2009/12/04 22:06:37 tbox Exp $ */ /* Reviewed: Wed Mar 15 14:59:00 PST 2000 by explorer */ /* RFC1183 */ #ifndef RDATA_GENERIC_AFSDB_18_C #define RDATA_GENERIC_AFSDB_18_C #define RRTYPE_AFSDB_ATTRIBUTES (0) static inline isc_result_t fromtext_afsdb(ARGS_FROMTEXT) { isc_token_t token; isc_buffer_t buffer; dns_name_t name; isc_boolean_t ok; REQUIRE(type == dns_rdatatype_afsdb); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); /* * Subtype. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Hostname. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); ok = ISC_TRUE; if ((options & DNS_RDATA_CHECKNAMES) != 0) ok = dns_name_ishostname(&name, ISC_FALSE); if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) RETTOK(DNS_R_BADNAME); if (!ok && callbacks != NULL) warn_badname(&name, lexer, callbacks); return (ISC_R_SUCCESS); } static inline isc_result_t totext_afsdb(ARGS_TOTEXT) { dns_name_t name; dns_name_t prefix; isc_region_t region; char buf[sizeof("64000 ")]; isc_boolean_t sub; unsigned int num; REQUIRE(rdata->type == dns_rdatatype_afsdb); REQUIRE(rdata->length != 0); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, ®ion); num = uint16_fromregion(®ion); isc_region_consume(®ion, 2); sprintf(buf, "%u ", num); RETERR(str_totext(buf, target)); dns_name_fromregion(&name, ®ion); sub = name_prefix(&name, tctx->origin, &prefix); return (dns_name_totext(&prefix, sub, target)); } static inline isc_result_t fromwire_afsdb(ARGS_FROMWIRE) { dns_name_t name; isc_region_t sr; isc_region_t tr; REQUIRE(type == dns_rdatatype_afsdb); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); dns_name_init(&name, NULL); isc_buffer_activeregion(source, &sr); isc_buffer_availableregion(target, &tr); if (tr.length < 2) return (ISC_R_NOSPACE); if (sr.length < 2) return (ISC_R_UNEXPECTEDEND); memmove(tr.base, sr.base, 2); isc_buffer_forward(source, 2); isc_buffer_add(target, 2); return (dns_name_fromwire(&name, source, dctx, options, target)); } static inline isc_result_t towire_afsdb(ARGS_TOWIRE) { isc_region_t tr; isc_region_t sr; dns_name_t name; dns_offsets_t offsets; REQUIRE(rdata->type == dns_rdatatype_afsdb); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); isc_buffer_availableregion(target, &tr); dns_rdata_toregion(rdata, &sr); if (tr.length < 2) return (ISC_R_NOSPACE); memmove(tr.base, sr.base, 2); isc_region_consume(&sr, 2); isc_buffer_add(target, 2); dns_name_init(&name, offsets); dns_name_fromregion(&name, &sr); return (dns_name_towire(&name, cctx, target)); } static inline int compare_afsdb(ARGS_COMPARE) { int result; dns_name_t name1; dns_name_t name2; isc_region_t region1; isc_region_t region2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_afsdb); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); result = memcmp(rdata1->data, rdata2->data, 2); if (result != 0) return (result < 0 ? -1 : 1); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); isc_region_consume(®ion1, 2); isc_region_consume(®ion2, 2); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); return (dns_name_rdatacompare(&name1, &name2)); } static inline isc_result_t fromstruct_afsdb(ARGS_FROMSTRUCT) { dns_rdata_afsdb_t *afsdb = source; isc_region_t region; REQUIRE(type == dns_rdatatype_afsdb); REQUIRE(source != NULL); REQUIRE(afsdb->common.rdclass == rdclass); REQUIRE(afsdb->common.rdtype == type); UNUSED(type); UNUSED(rdclass); RETERR(uint16_tobuffer(afsdb->subtype, target)); dns_name_toregion(&afsdb->server, ®ion); return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_afsdb(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_afsdb_t *afsdb = target; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_afsdb); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); afsdb->common.rdclass = rdata->rdclass; afsdb->common.rdtype = rdata->type; ISC_LINK_INIT(&afsdb->common, link); dns_name_init(&afsdb->server, NULL); dns_rdata_toregion(rdata, ®ion); afsdb->subtype = uint16_fromregion(®ion); isc_region_consume(®ion, 2); dns_name_init(&name, NULL); dns_name_fromregion(&name, ®ion); RETERR(name_duporclone(&name, mctx, &afsdb->server)); afsdb->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_afsdb(ARGS_FREESTRUCT) { dns_rdata_afsdb_t *afsdb = source; REQUIRE(source != NULL); REQUIRE(afsdb->common.rdtype == dns_rdatatype_afsdb); if (afsdb->mctx == NULL) return; dns_name_free(&afsdb->server, afsdb->mctx); afsdb->mctx = NULL; } static inline isc_result_t additionaldata_afsdb(ARGS_ADDLDATA) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_afsdb); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, ®ion); isc_region_consume(®ion, 2); dns_name_fromregion(&name, ®ion); return ((add)(arg, &name, dns_rdatatype_a)); } static inline isc_result_t digest_afsdb(ARGS_DIGEST) { isc_region_t r1, r2; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_afsdb); dns_rdata_toregion(rdata, &r1); r2 = r1; isc_region_consume(&r2, 2); r1.length = 2; RETERR((digest)(arg, &r1)); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r2); return (dns_name_digest(&name, digest, arg)); } static inline isc_boolean_t checkowner_afsdb(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_afsdb); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_afsdb(ARGS_CHECKNAMES) { isc_region_t region; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_afsdb); UNUSED(owner); dns_rdata_toregion(rdata, ®ion); isc_region_consume(®ion, 2); dns_name_init(&name, NULL); dns_name_fromregion(&name, ®ion); if (!dns_name_ishostname(&name, ISC_FALSE)) { if (bad != NULL) dns_name_clone(&name, bad); return (ISC_FALSE); } return (ISC_TRUE); } static inline int casecompare_afsdb(ARGS_COMPARE) { return (compare_afsdb(rdata1, rdata2)); } #endif /* RDATA_GENERIC_AFSDB_18_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/caa_257.c0000644000470500017500000002074612664710322020730 0ustar lamontlamont/* * Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_CAA_257_C #define GENERIC_CAA_257_C 1 #define RRTYPE_CAA_ATTRIBUTES (0) static unsigned char const alphanumeric[256] = { /* 0x00-0x0f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x2f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30-0x3f */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x40-0x4f */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x50-0x5f */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x60-0x6f */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x70-0x7f */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x80-0x8f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0-0xaf */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0-0xbf */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0-0xcf */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0-0xdf */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0-0xef */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xf0-0xff */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static inline isc_result_t fromtext_caa(ARGS_FROMTEXT) { isc_token_t token; isc_textregion_t tr; isc_uint8_t flags; unsigned int i; REQUIRE(type == dns_rdatatype_caa); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); /* Flags. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 255U) RETTOK(ISC_R_RANGE); flags = token.value.as_ulong; RETERR(uint8_tobuffer(flags, target)); /* * Tag */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); tr = token.value.as_textregion; for (i = 0; i < tr.length; i++) if (!alphanumeric[(unsigned char) tr.base[i]]) RETTOK(DNS_R_SYNTAX); RETERR(uint8_tobuffer(tr.length, target)); RETERR(mem_tobuffer(target, tr.base, tr.length)); /* * Value */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, ISC_FALSE)); if (token.type != isc_tokentype_qstring && token.type != isc_tokentype_string) RETERR(DNS_R_SYNTAX); RETERR(multitxt_fromtext(&token.value.as_textregion, target)); return (ISC_R_SUCCESS); } static inline isc_result_t totext_caa(ARGS_TOTEXT) { isc_region_t region; isc_uint8_t flags; char buf[256]; UNUSED(tctx); REQUIRE(rdata->type == dns_rdatatype_caa); REQUIRE(rdata->length >= 3U); REQUIRE(rdata->data != NULL); dns_rdata_toregion(rdata, ®ion); /* * Flags */ flags = uint8_consume_fromregion(®ion); sprintf(buf, "%u ", flags); RETERR(str_totext(buf, target)); /* * Tag */ RETERR(txt_totext(®ion, ISC_FALSE, target)); RETERR(str_totext(" ", target)); /* * Value */ RETERR(multitxt_totext(®ion, target)); return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_caa(ARGS_FROMWIRE) { isc_region_t sr; unsigned int len, i; REQUIRE(type == dns_rdatatype_caa); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); /* * Flags */ isc_buffer_activeregion(source, &sr); if (sr.length < 2) return (ISC_R_UNEXPECTEDEND); /* * Flags, tag length */ RETERR(mem_tobuffer(target, sr.base, 2)); len = sr.base[1]; isc_region_consume(&sr, 2); isc_buffer_forward(source, 2); /* * Zero length tag fields are illegal. */ if (sr.length < len || len == 0) RETERR(DNS_R_FORMERR); /* Check the Tag's value */ for (i = 0; i < len; i++) if (!alphanumeric[sr.base[i]]) RETERR(DNS_R_FORMERR); /* * Tag + Value */ isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); } static inline isc_result_t towire_caa(ARGS_TOWIRE) { isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_caa); REQUIRE(rdata->length >= 3U); REQUIRE(rdata->data != NULL); UNUSED(cctx); dns_rdata_toregion(rdata, ®ion); return (mem_tobuffer(target, region.base, region.length)); } static inline int compare_caa(ARGS_COMPARE) { isc_region_t r1, r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_caa); REQUIRE(rdata1->length >= 3U); REQUIRE(rdata2->length >= 3U); REQUIRE(rdata1->data != NULL); REQUIRE(rdata2->data != NULL); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_caa(ARGS_FROMSTRUCT) { dns_rdata_caa_t *caa = source; isc_region_t region; unsigned int i; REQUIRE(type == dns_rdatatype_caa); REQUIRE(source != NULL); REQUIRE(caa->common.rdtype == type); REQUIRE(caa->common.rdclass == rdclass); REQUIRE(caa->tag != NULL && caa->tag_len != 0); REQUIRE(caa->value != NULL); UNUSED(type); UNUSED(rdclass); /* * Flags */ RETERR(uint8_tobuffer(caa->flags, target)); /* * Tag length */ RETERR(uint8_tobuffer(caa->tag_len, target)); /* * Tag */ region.base = caa->tag; region.length = caa->tag_len; for (i = 0; i < region.length; i++) if (!alphanumeric[region.base[i]]) RETERR(DNS_R_SYNTAX); RETERR(isc_buffer_copyregion(target, ®ion)); /* * Value */ region.base = caa->value; region.length = caa->value_len; return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_caa(ARGS_TOSTRUCT) { dns_rdata_caa_t *caa = target; isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_caa); REQUIRE(target != NULL); REQUIRE(rdata->length >= 3U); REQUIRE(rdata->data != NULL); caa->common.rdclass = rdata->rdclass; caa->common.rdtype = rdata->type; ISC_LINK_INIT(&caa->common, link); dns_rdata_toregion(rdata, &sr); /* * Flags */ if (sr.length < 1) return (ISC_R_UNEXPECTEDEND); caa->flags = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* * Tag length */ if (sr.length < 1) return (ISC_R_UNEXPECTEDEND); caa->tag_len = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* * Tag */ if (sr.length < caa->tag_len) return (ISC_R_UNEXPECTEDEND); caa->tag = mem_maybedup(mctx, sr.base, caa->tag_len); if (caa->tag == NULL) return (ISC_R_NOMEMORY); isc_region_consume(&sr, caa->tag_len); /* * Value */ caa->value_len = sr.length; caa->value = mem_maybedup(mctx, sr.base, sr.length); if (caa->value == NULL) return (ISC_R_NOMEMORY); caa->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_caa(ARGS_FREESTRUCT) { dns_rdata_caa_t *caa = (dns_rdata_caa_t *) source; REQUIRE(source != NULL); REQUIRE(caa->common.rdtype == dns_rdatatype_caa); if (caa->mctx == NULL) return; if (caa->tag != NULL) isc_mem_free(caa->mctx, caa->tag); if (caa->value != NULL) isc_mem_free(caa->mctx, caa->value); caa->mctx = NULL; } static inline isc_result_t additionaldata_caa(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_caa); REQUIRE(rdata->data != NULL); REQUIRE(rdata->length >= 3U); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_caa(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_caa); REQUIRE(rdata->data != NULL); REQUIRE(rdata->length >= 3U); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_caa(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_caa); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_caa(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_caa); REQUIRE(rdata->data != NULL); REQUIRE(rdata->length >= 3U); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_caa(ARGS_COMPARE) { return (compare_caa(rdata1, rdata2)); } #endif /* GENERIC_CAA_257_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/x25_19.h0000644000470500017500000000223112664710322020530 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_X25_19_H #define GENERIC_X25_19_H 1 /* $Id: x25_19.h,v 1.18 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief Per RFC1183 */ typedef struct dns_rdata_x25 { dns_rdatacommon_t common; isc_mem_t *mctx; unsigned char *x25; isc_uint8_t x25_len; } dns_rdata_x25_t; #endif /* GENERIC_X25_19_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/cert_37.c0000644000470500017500000001474712664710322021061 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* Reviewed: Wed Mar 15 21:14:32 EST 2000 by tale */ /* RFC2538 */ #ifndef RDATA_GENERIC_CERT_37_C #define RDATA_GENERIC_CERT_37_C #define RRTYPE_CERT_ATTRIBUTES (0) static inline isc_result_t fromtext_cert(ARGS_FROMTEXT) { isc_token_t token; dns_secalg_t secalg; dns_cert_t cert; REQUIRE(type == dns_rdatatype_cert); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); /* * Cert type. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_cert_fromtext(&cert, &token.value.as_textregion)); RETERR(uint16_tobuffer(cert, target)); /* * Key tag. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Algorithm. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_secalg_fromtext(&secalg, &token.value.as_textregion)); RETERR(mem_tobuffer(target, &secalg, 1)); return (isc_base64_tobuffer(lexer, target, -1)); } static inline isc_result_t totext_cert(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("64000 ")]; unsigned int n; REQUIRE(rdata->type == dns_rdatatype_cert); REQUIRE(rdata->length != 0); UNUSED(tctx); dns_rdata_toregion(rdata, &sr); /* * Type. */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); RETERR(dns_cert_totext((dns_cert_t)n, target)); RETERR(str_totext(" ", target)); /* * Key tag. */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%u ", n); RETERR(str_totext(buf, target)); /* * Algorithm. */ RETERR(dns_secalg_totext(sr.base[0], target)); isc_region_consume(&sr, 1); /* * Cert. */ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(&sr, 60, "", target)); else RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_cert(ARGS_FROMWIRE) { isc_region_t sr; REQUIRE(type == dns_rdatatype_cert); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); isc_buffer_activeregion(source, &sr); if (sr.length < 5) return (ISC_R_UNEXPECTEDEND); isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); } static inline isc_result_t towire_cert(ARGS_TOWIRE) { isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_cert); REQUIRE(rdata->length != 0); UNUSED(cctx); dns_rdata_toregion(rdata, &sr); return (mem_tobuffer(target, sr.base, sr.length)); } static inline int compare_cert(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_cert); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_cert(ARGS_FROMSTRUCT) { dns_rdata_cert_t *cert = source; REQUIRE(type == dns_rdatatype_cert); REQUIRE(source != NULL); REQUIRE(cert->common.rdtype == type); REQUIRE(cert->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); RETERR(uint16_tobuffer(cert->type, target)); RETERR(uint16_tobuffer(cert->key_tag, target)); RETERR(uint8_tobuffer(cert->algorithm, target)); return (mem_tobuffer(target, cert->certificate, cert->length)); } static inline isc_result_t tostruct_cert(ARGS_TOSTRUCT) { dns_rdata_cert_t *cert = target; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_cert); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); cert->common.rdclass = rdata->rdclass; cert->common.rdtype = rdata->type; ISC_LINK_INIT(&cert->common, link); dns_rdata_toregion(rdata, ®ion); cert->type = uint16_fromregion(®ion); isc_region_consume(®ion, 2); cert->key_tag = uint16_fromregion(®ion); isc_region_consume(®ion, 2); cert->algorithm = uint8_fromregion(®ion); isc_region_consume(®ion, 1); cert->length = region.length; cert->certificate = mem_maybedup(mctx, region.base, region.length); if (cert->certificate == NULL) return (ISC_R_NOMEMORY); cert->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_cert(ARGS_FREESTRUCT) { dns_rdata_cert_t *cert = source; REQUIRE(cert != NULL); REQUIRE(cert->common.rdtype == dns_rdatatype_cert); if (cert->mctx == NULL) return; if (cert->certificate != NULL) isc_mem_free(cert->mctx, cert->certificate); cert->mctx = NULL; } static inline isc_result_t additionaldata_cert(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_cert); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_cert(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_cert); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_cert(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_cert); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_cert(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_cert); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_cert(ARGS_COMPARE) { return (compare_cert(rdata1, rdata2)); } #endif /* RDATA_GENERIC_CERT_37_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/rt_21.h0000644000470500017500000000222412664710322020532 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_RT_21_H #define GENERIC_RT_21_H 1 /* $Id: rt_21.h,v 1.21 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief Per RFC1183 */ typedef struct dns_rdata_rt { dns_rdatacommon_t common; isc_mem_t *mctx; isc_uint16_t preference; dns_name_t host; } dns_rdata_rt_t; #endif /* GENERIC_RT_21_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/isdn_20.c0000644000470500017500000001344512664710322021043 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2013-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: isdn_20.c,v 1.40 2009/12/04 22:06:37 tbox Exp $ */ /* Reviewed: Wed Mar 15 16:53:11 PST 2000 by bwelling */ /* RFC1183 */ #ifndef RDATA_GENERIC_ISDN_20_C #define RDATA_GENERIC_ISDN_20_C #define RRTYPE_ISDN_ATTRIBUTES (0) static inline isc_result_t fromtext_isdn(ARGS_FROMTEXT) { isc_token_t token; REQUIRE(type == dns_rdatatype_isdn); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); /* ISDN-address */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, ISC_FALSE)); RETTOK(txt_fromtext(&token.value.as_textregion, target)); /* sa: optional */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, ISC_TRUE)); if (token.type != isc_tokentype_string && token.type != isc_tokentype_qstring) { isc_lex_ungettoken(lexer, &token); return (ISC_R_SUCCESS); } RETTOK(txt_fromtext(&token.value.as_textregion, target)); return (ISC_R_SUCCESS); } static inline isc_result_t totext_isdn(ARGS_TOTEXT) { isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_isdn); REQUIRE(rdata->length != 0); UNUSED(tctx); dns_rdata_toregion(rdata, ®ion); RETERR(txt_totext(®ion, ISC_TRUE, target)); if (region.length == 0) return (ISC_R_SUCCESS); RETERR(str_totext(" ", target)); return (txt_totext(®ion, ISC_TRUE, target)); } static inline isc_result_t fromwire_isdn(ARGS_FROMWIRE) { REQUIRE(type == dns_rdatatype_isdn); UNUSED(type); UNUSED(dctx); UNUSED(rdclass); UNUSED(options); RETERR(txt_fromwire(source, target)); if (buffer_empty(source)) return (ISC_R_SUCCESS); return (txt_fromwire(source, target)); } static inline isc_result_t towire_isdn(ARGS_TOWIRE) { UNUSED(cctx); REQUIRE(rdata->type == dns_rdatatype_isdn); REQUIRE(rdata->length != 0); return (mem_tobuffer(target, rdata->data, rdata->length)); } static inline int compare_isdn(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_isdn); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_isdn(ARGS_FROMSTRUCT) { dns_rdata_isdn_t *isdn = source; REQUIRE(type == dns_rdatatype_isdn); REQUIRE(source != NULL); REQUIRE(isdn->common.rdtype == type); REQUIRE(isdn->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); RETERR(uint8_tobuffer(isdn->isdn_len, target)); RETERR(mem_tobuffer(target, isdn->isdn, isdn->isdn_len)); if (isdn->subaddress == NULL) return (ISC_R_SUCCESS); RETERR(uint8_tobuffer(isdn->subaddress_len, target)); return (mem_tobuffer(target, isdn->subaddress, isdn->subaddress_len)); } static inline isc_result_t tostruct_isdn(ARGS_TOSTRUCT) { dns_rdata_isdn_t *isdn = target; isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_isdn); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); isdn->common.rdclass = rdata->rdclass; isdn->common.rdtype = rdata->type; ISC_LINK_INIT(&isdn->common, link); dns_rdata_toregion(rdata, &r); isdn->isdn_len = uint8_fromregion(&r); isc_region_consume(&r, 1); isdn->isdn = mem_maybedup(mctx, r.base, isdn->isdn_len); if (isdn->isdn == NULL) return (ISC_R_NOMEMORY); isc_region_consume(&r, isdn->isdn_len); if (r.length == 0) { isdn->subaddress_len = 0; isdn->subaddress = NULL; } else { isdn->subaddress_len = uint8_fromregion(&r); isc_region_consume(&r, 1); isdn->subaddress = mem_maybedup(mctx, r.base, isdn->subaddress_len); if (isdn->subaddress == NULL) goto cleanup; } isdn->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (mctx != NULL && isdn->isdn != NULL) isc_mem_free(mctx, isdn->isdn); return (ISC_R_NOMEMORY); } static inline void freestruct_isdn(ARGS_FREESTRUCT) { dns_rdata_isdn_t *isdn = source; REQUIRE(source != NULL); if (isdn->mctx == NULL) return; if (isdn->isdn != NULL) isc_mem_free(isdn->mctx, isdn->isdn); if (isdn->subaddress != NULL) isc_mem_free(isdn->mctx, isdn->subaddress); isdn->mctx = NULL; } static inline isc_result_t additionaldata_isdn(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_isdn); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_isdn(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_isdn); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_isdn(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_isdn); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_isdn(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_isdn); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_isdn(ARGS_COMPARE) { return (compare_isdn(rdata1, rdata2)); } #endif /* RDATA_GENERIC_ISDN_20_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/mg_8.h0000644000470500017500000000213212664710322020433 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef GENERIC_MG_8_H #define GENERIC_MG_8_H 1 /* $Id: mg_8.h,v 1.26 2007/06/19 23:47:17 tbox Exp $ */ typedef struct dns_rdata_mg { dns_rdatacommon_t common; isc_mem_t *mctx; dns_name_t mg; } dns_rdata_mg_t; #endif /* GENERIC_MG_8_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/rt_21.c0000644000470500017500000001735212664710322020535 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rt_21.c,v 1.48 2009/12/04 22:06:37 tbox Exp $ */ /* reviewed: Thu Mar 16 15:02:31 PST 2000 by brister */ /* RFC1183 */ #ifndef RDATA_GENERIC_RT_21_C #define RDATA_GENERIC_RT_21_C #define RRTYPE_RT_ATTRIBUTES (0) static inline isc_result_t fromtext_rt(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; isc_boolean_t ok; REQUIRE(type == dns_rdatatype_rt); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); ok = ISC_TRUE; if ((options & DNS_RDATA_CHECKNAMES) != 0) ok = dns_name_ishostname(&name, ISC_FALSE); if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) RETTOK(DNS_R_BADNAME); if (!ok && callbacks != NULL) warn_badname(&name, lexer, callbacks); return (ISC_R_SUCCESS); } static inline isc_result_t totext_rt(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; char buf[sizeof("64000")]; unsigned short num; REQUIRE(rdata->type == dns_rdatatype_rt); REQUIRE(rdata->length != 0); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, ®ion); num = uint16_fromregion(®ion); isc_region_consume(®ion, 2); sprintf(buf, "%u", num); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); dns_name_fromregion(&name, ®ion); sub = name_prefix(&name, tctx->origin, &prefix); return (dns_name_totext(&prefix, sub, target)); } static inline isc_result_t fromwire_rt(ARGS_FROMWIRE) { dns_name_t name; isc_region_t sregion; isc_region_t tregion; REQUIRE(type == dns_rdatatype_rt); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); dns_name_init(&name, NULL); isc_buffer_activeregion(source, &sregion); isc_buffer_availableregion(target, &tregion); if (tregion.length < 2) return (ISC_R_NOSPACE); if (sregion.length < 2) return (ISC_R_UNEXPECTEDEND); memmove(tregion.base, sregion.base, 2); isc_buffer_forward(source, 2); isc_buffer_add(target, 2); return (dns_name_fromwire(&name, source, dctx, options, target)); } static inline isc_result_t towire_rt(ARGS_TOWIRE) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; isc_region_t tr; REQUIRE(rdata->type == dns_rdatatype_rt); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); isc_buffer_availableregion(target, &tr); dns_rdata_toregion(rdata, ®ion); if (tr.length < 2) return (ISC_R_NOSPACE); memmove(tr.base, region.base, 2); isc_region_consume(®ion, 2); isc_buffer_add(target, 2); dns_name_init(&name, offsets); dns_name_fromregion(&name, ®ion); return (dns_name_towire(&name, cctx, target)); } static inline int compare_rt(ARGS_COMPARE) { dns_name_t name1; dns_name_t name2; isc_region_t region1; isc_region_t region2; int order; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_rt); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); order = memcmp(rdata1->data, rdata2->data, 2); if (order != 0) return (order < 0 ? -1 : 1); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); isc_region_consume(®ion1, 2); isc_region_consume(®ion2, 2); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); return (dns_name_rdatacompare(&name1, &name2)); } static inline isc_result_t fromstruct_rt(ARGS_FROMSTRUCT) { dns_rdata_rt_t *rt = source; isc_region_t region; REQUIRE(type == dns_rdatatype_rt); REQUIRE(source != NULL); REQUIRE(rt->common.rdtype == type); REQUIRE(rt->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); RETERR(uint16_tobuffer(rt->preference, target)); dns_name_toregion(&rt->host, ®ion); return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_rt(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_rt_t *rt = target; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_rt); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); rt->common.rdclass = rdata->rdclass; rt->common.rdtype = rdata->type; ISC_LINK_INIT(&rt->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); rt->preference = uint16_fromregion(®ion); isc_region_consume(®ion, 2); dns_name_fromregion(&name, ®ion); dns_name_init(&rt->host, NULL); RETERR(name_duporclone(&name, mctx, &rt->host)); rt->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_rt(ARGS_FREESTRUCT) { dns_rdata_rt_t *rt = source; REQUIRE(source != NULL); REQUIRE(rt->common.rdtype == dns_rdatatype_rt); if (rt->mctx == NULL) return; dns_name_free(&rt->host, rt->mctx); rt->mctx = NULL; } static inline isc_result_t additionaldata_rt(ARGS_ADDLDATA) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; isc_result_t result; REQUIRE(rdata->type == dns_rdatatype_rt); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, ®ion); isc_region_consume(®ion, 2); dns_name_fromregion(&name, ®ion); result = (add)(arg, &name, dns_rdatatype_x25); if (result != ISC_R_SUCCESS) return (result); result = (add)(arg, &name, dns_rdatatype_isdn); if (result != ISC_R_SUCCESS) return (result); return ((add)(arg, &name, dns_rdatatype_a)); } static inline isc_result_t digest_rt(ARGS_DIGEST) { isc_region_t r1, r2; isc_result_t result; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_rt); dns_rdata_toregion(rdata, &r1); r2 = r1; isc_region_consume(&r2, 2); r1.length = 2; result = (digest)(arg, &r1); if (result != ISC_R_SUCCESS) return (result); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r2); return (dns_name_digest(&name, digest, arg)); } static inline isc_boolean_t checkowner_rt(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_rt); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_rt(ARGS_CHECKNAMES) { isc_region_t region; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_rt); UNUSED(owner); dns_rdata_toregion(rdata, ®ion); isc_region_consume(®ion, 2); dns_name_init(&name, NULL); dns_name_fromregion(&name, ®ion); if (!dns_name_ishostname(&name, ISC_FALSE)) { if (bad != NULL) dns_name_clone(&name, bad); return (ISC_FALSE); } return (ISC_TRUE); } static inline int casecompare_rt(ARGS_COMPARE) { return (compare_rt(rdata1, rdata2)); } #endif /* RDATA_GENERIC_RT_21_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/l32_105.c0000644000470500017500000001230012664710322020557 0ustar lamontlamont/* * Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef RDATA_GENERIC_L32_105_C #define RDATA_GENERIC_L32_105_C #include #include #define RRTYPE_L32_ATTRIBUTES (0) static inline isc_result_t fromtext_l32(ARGS_FROMTEXT) { isc_token_t token; struct in_addr addr; isc_region_t region; REQUIRE(type == dns_rdatatype_l32); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1) RETTOK(DNS_R_BADDOTTEDQUAD); isc_buffer_availableregion(target, ®ion); if (region.length < 4) return (ISC_R_NOSPACE); memmove(region.base, &addr, 4); isc_buffer_add(target, 4); return (ISC_R_SUCCESS); } static inline isc_result_t totext_l32(ARGS_TOTEXT) { isc_region_t region; char buf[sizeof("65000")]; unsigned short num; REQUIRE(rdata->type == dns_rdatatype_l32); REQUIRE(rdata->length == 6); UNUSED(tctx); dns_rdata_toregion(rdata, ®ion); num = uint16_fromregion(®ion); isc_region_consume(®ion, 2); sprintf(buf, "%u", num); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); return (inet_totext(AF_INET, ®ion, target)); } static inline isc_result_t fromwire_l32(ARGS_FROMWIRE) { isc_region_t sregion; REQUIRE(type == dns_rdatatype_l32); UNUSED(type); UNUSED(options); UNUSED(rdclass); UNUSED(dctx); isc_buffer_activeregion(source, &sregion); if (sregion.length != 6) return (DNS_R_FORMERR); isc_buffer_forward(source, sregion.length); return (mem_tobuffer(target, sregion.base, sregion.length)); } static inline isc_result_t towire_l32(ARGS_TOWIRE) { REQUIRE(rdata->type == dns_rdatatype_l32); REQUIRE(rdata->length == 6); UNUSED(cctx); return (mem_tobuffer(target, rdata->data, rdata->length)); } static inline int compare_l32(ARGS_COMPARE) { isc_region_t region1; isc_region_t region2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_l32); REQUIRE(rdata1->length == 6); REQUIRE(rdata2->length == 6); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); return (isc_region_compare(®ion1, ®ion2)); } static inline isc_result_t fromstruct_l32(ARGS_FROMSTRUCT) { dns_rdata_l32_t *l32 = source; isc_uint32_t n; REQUIRE(type == dns_rdatatype_l32); REQUIRE(source != NULL); REQUIRE(l32->common.rdtype == type); REQUIRE(l32->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); RETERR(uint16_tobuffer(l32->pref, target)); n = ntohl(l32->l32.s_addr); return (uint32_tobuffer(n, target)); } static inline isc_result_t tostruct_l32(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_l32_t *l32 = target; isc_uint32_t n; REQUIRE(rdata->type == dns_rdatatype_l32); REQUIRE(target != NULL); REQUIRE(rdata->length == 6); UNUSED(mctx); l32->common.rdclass = rdata->rdclass; l32->common.rdtype = rdata->type; ISC_LINK_INIT(&l32->common, link); dns_rdata_toregion(rdata, ®ion); l32->pref = uint16_fromregion(®ion); n = uint32_fromregion(®ion); l32->l32.s_addr = htonl(n); return (ISC_R_SUCCESS); } static inline void freestruct_l32(ARGS_FREESTRUCT) { dns_rdata_l32_t *l32 = source; REQUIRE(source != NULL); REQUIRE(l32->common.rdtype == dns_rdatatype_l32); return; } static inline isc_result_t additionaldata_l32(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_l32); REQUIRE(rdata->length == 6); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_l32(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_l32); REQUIRE(rdata->length == 6); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_l32(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_l32); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_l32(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_l32); REQUIRE(rdata->length == 6); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_l32(ARGS_COMPARE) { return (compare_l32(rdata1, rdata2)); } #endif /* RDATA_GENERIC_L32_105_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/tlsa_52.c0000644000470500017500000001457712664710322021065 0ustar lamontlamont/* * Copyright (C) 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* rfc6698.txt */ #ifndef RDATA_GENERIC_TLSA_52_C #define RDATA_GENERIC_TLSA_52_C #define RRTYPE_TLSA_ATTRIBUTES 0 static inline isc_result_t fromtext_tlsa(ARGS_FROMTEXT) { isc_token_t token; REQUIRE(type == dns_rdatatype_tlsa); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); /* * Certificate Usage. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffU) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer(token.value.as_ulong, target)); /* * Selector. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffU) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer(token.value.as_ulong, target)); /* * Matching type. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffU) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer(token.value.as_ulong, target)); /* * Certificate Association Data. */ return (isc_hex_tobuffer(lexer, target, -1)); } static inline isc_result_t totext_tlsa(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("64000 ")]; unsigned int n; REQUIRE(rdata->type == dns_rdatatype_tlsa); REQUIRE(rdata->length != 0); UNUSED(tctx); dns_rdata_toregion(rdata, &sr); /* * Certificate Usage. */ n = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u ", n); RETERR(str_totext(buf, target)); /* * Selector. */ n = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u ", n); RETERR(str_totext(buf, target)); /* * Matching type. */ n = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u", n); RETERR(str_totext(buf, target)); /* * Certificate Association Data. */ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); if (tctx->width == 0) /* No splitting */ RETERR(isc_hex_totext(&sr, 0, "", target)); else RETERR(isc_hex_totext(&sr, tctx->width - 2, tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_tlsa(ARGS_FROMWIRE) { isc_region_t sr; REQUIRE(type == dns_rdatatype_tlsa); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); isc_buffer_activeregion(source, &sr); if (sr.length < 3) return (ISC_R_UNEXPECTEDEND); isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); } static inline isc_result_t towire_tlsa(ARGS_TOWIRE) { isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_tlsa); REQUIRE(rdata->length != 0); UNUSED(cctx); dns_rdata_toregion(rdata, &sr); return (mem_tobuffer(target, sr.base, sr.length)); } static inline int compare_tlsa(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_tlsa); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_tlsa(ARGS_FROMSTRUCT) { dns_rdata_tlsa_t *tlsa = source; REQUIRE(type == dns_rdatatype_tlsa); REQUIRE(source != NULL); REQUIRE(tlsa->common.rdtype == type); REQUIRE(tlsa->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); RETERR(uint8_tobuffer(tlsa->usage, target)); RETERR(uint8_tobuffer(tlsa->selector, target)); RETERR(uint8_tobuffer(tlsa->match, target)); return (mem_tobuffer(target, tlsa->data, tlsa->length)); } static inline isc_result_t tostruct_tlsa(ARGS_TOSTRUCT) { dns_rdata_tlsa_t *tlsa = target; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_tlsa); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); tlsa->common.rdclass = rdata->rdclass; tlsa->common.rdtype = rdata->type; ISC_LINK_INIT(&tlsa->common, link); dns_rdata_toregion(rdata, ®ion); tlsa->usage = uint8_fromregion(®ion); isc_region_consume(®ion, 1); tlsa->selector = uint8_fromregion(®ion); isc_region_consume(®ion, 1); tlsa->match = uint8_fromregion(®ion); isc_region_consume(®ion, 1); tlsa->length = region.length; tlsa->data = mem_maybedup(mctx, region.base, region.length); if (tlsa->data == NULL) return (ISC_R_NOMEMORY); tlsa->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_tlsa(ARGS_FREESTRUCT) { dns_rdata_tlsa_t *tlsa = source; REQUIRE(tlsa != NULL); REQUIRE(tlsa->common.rdtype == dns_rdatatype_tlsa); if (tlsa->mctx == NULL) return; if (tlsa->data != NULL) isc_mem_free(tlsa->mctx, tlsa->data); tlsa->mctx = NULL; } static inline isc_result_t additionaldata_tlsa(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_tlsa); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_tlsa(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_tlsa); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_tlsa(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_tlsa); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_tlsa(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_tlsa); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_tlsa(ARGS_COMPARE) { return (compare_tlsa(rdata1, rdata2)); } #endif /* RDATA_GENERIC_TLSA_52_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/mr_9.c0000644000470500017500000001256412664710322020454 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: mr_9.c,v 1.44 2009/12/04 22:06:37 tbox Exp $ */ /* Reviewed: Wed Mar 15 21:30:35 EST 2000 by tale */ #ifndef RDATA_GENERIC_MR_9_C #define RDATA_GENERIC_MR_9_C #define RRTYPE_MR_ATTRIBUTES (0) static inline isc_result_t fromtext_mr(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; REQUIRE(type == dns_rdatatype_mr); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); return (ISC_R_SUCCESS); } static inline isc_result_t totext_mr(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; REQUIRE(rdata->type == dns_rdatatype_mr); REQUIRE(rdata->length != 0); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); sub = name_prefix(&name, tctx->origin, &prefix); return (dns_name_totext(&prefix, sub, target)); } static inline isc_result_t fromwire_mr(ARGS_FROMWIRE) { dns_name_t name; REQUIRE(type == dns_rdatatype_mr); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, NULL); return (dns_name_fromwire(&name, source, dctx, options, target)); } static inline isc_result_t towire_mr(ARGS_TOWIRE) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_mr); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); return (dns_name_towire(&name, cctx, target)); } static inline int compare_mr(ARGS_COMPARE) { dns_name_t name1; dns_name_t name2; isc_region_t region1; isc_region_t region2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_mr); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); return (dns_name_rdatacompare(&name1, &name2)); } static inline isc_result_t fromstruct_mr(ARGS_FROMSTRUCT) { dns_rdata_mr_t *mr = source; isc_region_t region; REQUIRE(type == dns_rdatatype_mr); REQUIRE(source != NULL); REQUIRE(mr->common.rdtype == type); REQUIRE(mr->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); dns_name_toregion(&mr->mr, ®ion); return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_mr(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_mr_t *mr = target; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_mr); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); mr->common.rdclass = rdata->rdclass; mr->common.rdtype = rdata->type; ISC_LINK_INIT(&mr->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); dns_name_init(&mr->mr, NULL); RETERR(name_duporclone(&name, mctx, &mr->mr)); mr->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_mr(ARGS_FREESTRUCT) { dns_rdata_mr_t *mr = source; REQUIRE(source != NULL); REQUIRE(mr->common.rdtype == dns_rdatatype_mr); if (mr->mctx == NULL) return; dns_name_free(&mr->mr, mr->mctx); mr->mctx = NULL; } static inline isc_result_t additionaldata_mr(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_mr); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_mr(ARGS_DIGEST) { isc_region_t r; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_mr); dns_rdata_toregion(rdata, &r); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); return (dns_name_digest(&name, digest, arg)); } static inline isc_boolean_t checkowner_mr(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_mr); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_mr(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_mr); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_mr(ARGS_COMPARE) { return (compare_mr(rdata1, rdata2)); } #endif /* RDATA_GENERIC_MR_9_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/afsdb_18.h0000644000470500017500000000224612664710322021176 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_AFSDB_18_H #define GENERIC_AFSDB_18_H 1 /* $Id: afsdb_18.h,v 1.20 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief Per RFC1183 */ typedef struct dns_rdata_afsdb { dns_rdatacommon_t common; isc_mem_t *mctx; isc_uint16_t subtype; dns_name_t server; } dns_rdata_afsdb_t; #endif /* GENERIC_AFSDB_18_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/hinfo_13.c0000644000470500017500000001240612664710322021207 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: hinfo_13.c,v 1.46 2009/12/04 22:06:37 tbox Exp $ */ /* * Reviewed: Wed Mar 15 16:47:10 PST 2000 by halley. */ #ifndef RDATA_GENERIC_HINFO_13_C #define RDATA_GENERIC_HINFO_13_C #define RRTYPE_HINFO_ATTRIBUTES (0) static inline isc_result_t fromtext_hinfo(ARGS_FROMTEXT) { isc_token_t token; int i; UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); REQUIRE(type == dns_rdatatype_hinfo); for (i = 0; i < 2; i++) { RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, ISC_FALSE)); RETTOK(txt_fromtext(&token.value.as_textregion, target)); } return (ISC_R_SUCCESS); } static inline isc_result_t totext_hinfo(ARGS_TOTEXT) { isc_region_t region; UNUSED(tctx); REQUIRE(rdata->type == dns_rdatatype_hinfo); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, ®ion); RETERR(txt_totext(®ion, ISC_TRUE, target)); RETERR(str_totext(" ", target)); return (txt_totext(®ion, ISC_TRUE, target)); } static inline isc_result_t fromwire_hinfo(ARGS_FROMWIRE) { REQUIRE(type == dns_rdatatype_hinfo); UNUSED(type); UNUSED(dctx); UNUSED(rdclass); UNUSED(options); RETERR(txt_fromwire(source, target)); return (txt_fromwire(source, target)); } static inline isc_result_t towire_hinfo(ARGS_TOWIRE) { UNUSED(cctx); REQUIRE(rdata->type == dns_rdatatype_hinfo); REQUIRE(rdata->length != 0); return (mem_tobuffer(target, rdata->data, rdata->length)); } static inline int compare_hinfo(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_hinfo); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_hinfo(ARGS_FROMSTRUCT) { dns_rdata_hinfo_t *hinfo = source; REQUIRE(type == dns_rdatatype_hinfo); REQUIRE(source != NULL); REQUIRE(hinfo->common.rdtype == type); REQUIRE(hinfo->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); RETERR(uint8_tobuffer(hinfo->cpu_len, target)); RETERR(mem_tobuffer(target, hinfo->cpu, hinfo->cpu_len)); RETERR(uint8_tobuffer(hinfo->os_len, target)); return (mem_tobuffer(target, hinfo->os, hinfo->os_len)); } static inline isc_result_t tostruct_hinfo(ARGS_TOSTRUCT) { dns_rdata_hinfo_t *hinfo = target; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_hinfo); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); hinfo->common.rdclass = rdata->rdclass; hinfo->common.rdtype = rdata->type; ISC_LINK_INIT(&hinfo->common, link); dns_rdata_toregion(rdata, ®ion); hinfo->cpu_len = uint8_fromregion(®ion); isc_region_consume(®ion, 1); hinfo->cpu = mem_maybedup(mctx, region.base, hinfo->cpu_len); if (hinfo->cpu == NULL) return (ISC_R_NOMEMORY); isc_region_consume(®ion, hinfo->cpu_len); hinfo->os_len = uint8_fromregion(®ion); isc_region_consume(®ion, 1); hinfo->os = mem_maybedup(mctx, region.base, hinfo->os_len); if (hinfo->os == NULL) goto cleanup; hinfo->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (mctx != NULL && hinfo->cpu != NULL) isc_mem_free(mctx, hinfo->cpu); return (ISC_R_NOMEMORY); } static inline void freestruct_hinfo(ARGS_FREESTRUCT) { dns_rdata_hinfo_t *hinfo = source; REQUIRE(source != NULL); if (hinfo->mctx == NULL) return; if (hinfo->cpu != NULL) isc_mem_free(hinfo->mctx, hinfo->cpu); if (hinfo->os != NULL) isc_mem_free(hinfo->mctx, hinfo->os); hinfo->mctx = NULL; } static inline isc_result_t additionaldata_hinfo(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_hinfo); UNUSED(add); UNUSED(arg); UNUSED(rdata); return (ISC_R_SUCCESS); } static inline isc_result_t digest_hinfo(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_hinfo); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_hinfo(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_hinfo); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_hinfo(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_hinfo); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_hinfo(ARGS_COMPARE) { return (compare_hinfo(rdata1, rdata2)); } #endif /* RDATA_GENERIC_HINFO_13_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/tkey_249.h0000644000470500017500000000266512664710322021166 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_TKEY_249_H #define GENERIC_TKEY_249_H 1 /* $Id: tkey_249.h,v 1.24 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief Per draft-ietf-dnsind-tkey-00.txt */ typedef struct dns_rdata_tkey { dns_rdatacommon_t common; isc_mem_t * mctx; dns_name_t algorithm; isc_uint32_t inception; isc_uint32_t expire; isc_uint16_t mode; isc_uint16_t error; isc_uint16_t keylen; unsigned char * key; isc_uint16_t otherlen; unsigned char * other; } dns_rdata_tkey_t; #endif /* GENERIC_TKEY_249_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/mf_4.h0000644000470500017500000000213212664710322020426 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef GENERIC_MF_4_H #define GENERIC_MF_4_H 1 /* $Id: mf_4.h,v 1.26 2007/06/19 23:47:17 tbox Exp $ */ typedef struct dns_rdata_mf { dns_rdatacommon_t common; isc_mem_t *mctx; dns_name_t mf; } dns_rdata_mf_t; #endif /* GENERIC_MF_4_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/nsec3_50.h0000644000470500017500000000765112664710322021133 0ustar lamontlamont/* * Copyright (C) 2008, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_NSEC3_50_H #define GENERIC_NSEC3_50_H 1 /* $Id$ */ /*! * \brief Per RFC 5155 */ #include typedef struct dns_rdata_nsec3 { dns_rdatacommon_t common; isc_mem_t *mctx; dns_hash_t hash; unsigned char flags; dns_iterations_t iterations; unsigned char salt_length; unsigned char next_length; isc_uint16_t len; unsigned char *salt; unsigned char *next; unsigned char *typebits; } dns_rdata_nsec3_t; /* * The corresponding NSEC3 interval is OPTOUT indicating possible * insecure delegations. */ #define DNS_NSEC3FLAG_OPTOUT 0x01U /*% * The following flags are used in the private-type record (implemented in * lib/dns/private.c) which is used to store NSEC3PARAM data during the * time when it is not legal to have an actual NSEC3PARAM record in the * zone. They are defined here because the private-type record uses the * same flags field for the OPTOUT flag above and for the private flags * below. XXX: This should be considered for refactoring. */ /*% * Non-standard, private type only. * * Create a corresponding NSEC3 chain. * Once the NSEC3 chain is complete this flag will be removed to signal * that there is a complete chain. * * This flag is automatically set when a NSEC3PARAM record is added to * the zone via UPDATE. * * NSEC3PARAM records containing this flag should never be published, * but if they are, they should be ignored by RFC 5155 compliant * nameservers. */ #define DNS_NSEC3FLAG_CREATE 0x80U /*% * Non-standard, private type only. * * The corresponding NSEC3 set is to be removed once the NSEC chain * has been generated. * * This flag is automatically set when the last active NSEC3PARAM record * is removed from the zone via UPDATE. * * NSEC3PARAM records containing this flag should never be published, * but if they are, they should be ignored by RFC 5155 compliant * nameservers. */ #define DNS_NSEC3FLAG_REMOVE 0x40U /*% * Non-standard, private type only. * * When set with the CREATE flag, a corresponding NSEC3 chain will be * created when the zone becomes capable of supporting one (i.e., when it * has a DNSKEY RRset containing at least one NSEC3-capable algorithm). * Without this flag, NSEC3 chain creation would be attempted immediately, * fail, and the private type record would be removed. With it, the NSEC3 * parameters are stored until they can be used. When the zone has the * necessary prerequisites for NSEC3, then the INITIAL flag can be cleared, * and the record will be cleaned up normally. * * NSEC3PARAM records containing this flag should never be published, but * if they are, they should be ignored by RFC 5155 compliant nameservers. */ #define DNS_NSEC3FLAG_INITIAL 0x20U /*% * Non-standard, private type only. * * Prevent the creation of a NSEC chain before the last NSEC3 chain * is removed. This will normally only be set when the zone is * transitioning from secure with NSEC3 chains to insecure. * * NSEC3PARAM records containing this flag should never be published, * but if they are, they should be ignored by RFC 5155 compliant * nameservers. */ #define DNS_NSEC3FLAG_NONSEC 0x10U #endif /* GENERIC_NSEC3_50_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/cdnskey_60.h0000644000470500017500000000223512664710322021552 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_CDNSKEY_60_H #define GENERIC_CDNSKEY_60_H 1 /* CDNSKEY records have the same RDATA fields as DNSKEY records. */ typedef struct dns_rdata_cdnskey { dns_rdatacommon_t common; isc_mem_t * mctx; isc_uint16_t flags; isc_uint8_t protocol; isc_uint8_t algorithm; isc_uint16_t datalen; unsigned char * data; } dns_rdata_cdnskey_t; #endif /* GENERIC_CDNSKEY_60_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/tkey_249.c0000644000470500017500000003025712664710322021157 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2011, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* * Reviewed: Thu Mar 16 17:35:30 PST 2000 by halley. */ /* draft-ietf-dnsext-tkey-01.txt */ #ifndef RDATA_GENERIC_TKEY_249_C #define RDATA_GENERIC_TKEY_249_C #define RRTYPE_TKEY_ATTRIBUTES (DNS_RDATATYPEATTR_META) static inline isc_result_t fromtext_tkey(ARGS_FROMTEXT) { isc_token_t token; dns_rcode_t rcode; dns_name_t name; isc_buffer_t buffer; long i; char *e; REQUIRE(type == dns_rdatatype_tkey); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); /* * Algorithm. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); /* * Inception. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); RETERR(uint32_tobuffer(token.value.as_ulong, target)); /* * Expiration. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); RETERR(uint32_tobuffer(token.value.as_ulong, target)); /* * Mode. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Error. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (dns_tsigrcode_fromtext(&rcode, &token.value.as_textregion) != ISC_R_SUCCESS) { i = strtol(DNS_AS_STR(token), &e, 10); if (*e != 0) RETTOK(DNS_R_UNKNOWN); if (i < 0 || i > 0xffff) RETTOK(ISC_R_RANGE); rcode = (dns_rcode_t)i; } RETERR(uint16_tobuffer(rcode, target)); /* * Key Size. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Key Data. */ RETERR(isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong)); /* * Other Size. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Other Data. */ return (isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong)); } static inline isc_result_t totext_tkey(ARGS_TOTEXT) { isc_region_t sr, dr; char buf[sizeof("4294967295 ")]; unsigned long n; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; REQUIRE(rdata->type == dns_rdatatype_tkey); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); /* * Algorithm. */ dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_name_fromregion(&name, &sr); sub = name_prefix(&name, tctx->origin, &prefix); RETERR(dns_name_totext(&prefix, sub, target)); RETERR(str_totext(" ", target)); isc_region_consume(&sr, name_length(&name)); /* * Inception. */ n = uint32_fromregion(&sr); isc_region_consume(&sr, 4); sprintf(buf, "%lu ", n); RETERR(str_totext(buf, target)); /* * Expiration. */ n = uint32_fromregion(&sr); isc_region_consume(&sr, 4); sprintf(buf, "%lu ", n); RETERR(str_totext(buf, target)); /* * Mode. */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%lu ", n); RETERR(str_totext(buf, target)); /* * Error. */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); if (dns_tsigrcode_totext((dns_rcode_t)n, target) == ISC_R_SUCCESS) RETERR(str_totext(" ", target)); else { sprintf(buf, "%lu ", n); RETERR(str_totext(buf, target)); } /* * Key Size. */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%lu", n); RETERR(str_totext(buf, target)); /* * Key Data. */ REQUIRE(n <= sr.length); dr = sr; dr.length = n; if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(&dr, 60, "", target)); else RETERR(isc_base64_totext(&dr, tctx->width - 2, tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" ) ", target)); else RETERR(str_totext(" ", target)); isc_region_consume(&sr, n); /* * Other Size. */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%lu", n); RETERR(str_totext(buf, target)); /* * Other Data. */ REQUIRE(n <= sr.length); if (n != 0U) { dr = sr; dr.length = n; if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(&dr, 60, "", target)); else RETERR(isc_base64_totext(&dr, tctx->width - 2, tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); } return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_tkey(ARGS_FROMWIRE) { isc_region_t sr; unsigned long n; dns_name_t name; REQUIRE(type == dns_rdatatype_tkey); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); /* * Algorithm. */ dns_name_init(&name, NULL); RETERR(dns_name_fromwire(&name, source, dctx, options, target)); /* * Inception: 4 * Expiration: 4 * Mode: 2 * Error: 2 */ isc_buffer_activeregion(source, &sr); if (sr.length < 12) return (ISC_R_UNEXPECTEDEND); RETERR(mem_tobuffer(target, sr.base, 12)); isc_region_consume(&sr, 12); isc_buffer_forward(source, 12); /* * Key Length + Key Data. */ if (sr.length < 2) return (ISC_R_UNEXPECTEDEND); n = uint16_fromregion(&sr); if (sr.length < n + 2) return (ISC_R_UNEXPECTEDEND); RETERR(mem_tobuffer(target, sr.base, n + 2)); isc_region_consume(&sr, n + 2); isc_buffer_forward(source, n + 2); /* * Other Length + Other Data. */ if (sr.length < 2) return (ISC_R_UNEXPECTEDEND); n = uint16_fromregion(&sr); if (sr.length < n + 2) return (ISC_R_UNEXPECTEDEND); isc_buffer_forward(source, n + 2); return (mem_tobuffer(target, sr.base, n + 2)); } static inline isc_result_t towire_tkey(ARGS_TOWIRE) { isc_region_t sr; dns_name_t name; dns_offsets_t offsets; REQUIRE(rdata->type == dns_rdatatype_tkey); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); /* * Algorithm. */ dns_rdata_toregion(rdata, &sr); dns_name_init(&name, offsets); dns_name_fromregion(&name, &sr); RETERR(dns_name_towire(&name, cctx, target)); isc_region_consume(&sr, name_length(&name)); return (mem_tobuffer(target, sr.base, sr.length)); } static inline int compare_tkey(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; dns_name_t name1; dns_name_t name2; int order; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_tkey); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); /* * Algorithm. */ dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_name_fromregion(&name1, &r1); dns_name_fromregion(&name2, &r2); if ((order = dns_name_rdatacompare(&name1, &name2)) != 0) return (order); isc_region_consume(&r1, name_length(&name1)); isc_region_consume(&r2, name_length(&name2)); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_tkey(ARGS_FROMSTRUCT) { dns_rdata_tkey_t *tkey = source; REQUIRE(type == dns_rdatatype_tkey); REQUIRE(source != NULL); REQUIRE(tkey->common.rdtype == type); REQUIRE(tkey->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); /* * Algorithm Name. */ RETERR(name_tobuffer(&tkey->algorithm, target)); /* * Inception: 32 bits. */ RETERR(uint32_tobuffer(tkey->inception, target)); /* * Expire: 32 bits. */ RETERR(uint32_tobuffer(tkey->expire, target)); /* * Mode: 16 bits. */ RETERR(uint16_tobuffer(tkey->mode, target)); /* * Error: 16 bits. */ RETERR(uint16_tobuffer(tkey->error, target)); /* * Key size: 16 bits. */ RETERR(uint16_tobuffer(tkey->keylen, target)); /* * Key. */ RETERR(mem_tobuffer(target, tkey->key, tkey->keylen)); /* * Other size: 16 bits. */ RETERR(uint16_tobuffer(tkey->otherlen, target)); /* * Other data. */ return (mem_tobuffer(target, tkey->other, tkey->otherlen)); } static inline isc_result_t tostruct_tkey(ARGS_TOSTRUCT) { dns_rdata_tkey_t *tkey = target; dns_name_t alg; isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_tkey); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); tkey->common.rdclass = rdata->rdclass; tkey->common.rdtype = rdata->type; ISC_LINK_INIT(&tkey->common, link); dns_rdata_toregion(rdata, &sr); /* * Algorithm Name. */ dns_name_init(&alg, NULL); dns_name_fromregion(&alg, &sr); dns_name_init(&tkey->algorithm, NULL); RETERR(name_duporclone(&alg, mctx, &tkey->algorithm)); isc_region_consume(&sr, name_length(&tkey->algorithm)); /* * Inception. */ tkey->inception = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* * Expire. */ tkey->expire = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* * Mode. */ tkey->mode = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * Error. */ tkey->error = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * Key size. */ tkey->keylen = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * Key. */ INSIST(tkey->keylen + 2U <= sr.length); tkey->key = mem_maybedup(mctx, sr.base, tkey->keylen); if (tkey->key == NULL) goto cleanup; isc_region_consume(&sr, tkey->keylen); /* * Other size. */ tkey->otherlen = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * Other. */ INSIST(tkey->otherlen <= sr.length); tkey->other = mem_maybedup(mctx, sr.base, tkey->otherlen); if (tkey->other == NULL) goto cleanup; tkey->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (mctx != NULL) dns_name_free(&tkey->algorithm, mctx); if (mctx != NULL && tkey->key != NULL) isc_mem_free(mctx, tkey->key); return (ISC_R_NOMEMORY); } static inline void freestruct_tkey(ARGS_FREESTRUCT) { dns_rdata_tkey_t *tkey = (dns_rdata_tkey_t *) source; REQUIRE(source != NULL); if (tkey->mctx == NULL) return; dns_name_free(&tkey->algorithm, tkey->mctx); if (tkey->key != NULL) isc_mem_free(tkey->mctx, tkey->key); if (tkey->other != NULL) isc_mem_free(tkey->mctx, tkey->other); tkey->mctx = NULL; } static inline isc_result_t additionaldata_tkey(ARGS_ADDLDATA) { UNUSED(rdata); UNUSED(add); UNUSED(arg); REQUIRE(rdata->type == dns_rdatatype_tkey); return (ISC_R_SUCCESS); } static inline isc_result_t digest_tkey(ARGS_DIGEST) { UNUSED(rdata); UNUSED(digest); UNUSED(arg); REQUIRE(rdata->type == dns_rdatatype_tkey); return (ISC_R_NOTIMPLEMENTED); } static inline isc_boolean_t checkowner_tkey(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_tkey); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_tkey(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_tkey); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline isc_result_t casecompare_tkey(ARGS_COMPARE) { return (compare_tkey(rdata1, rdata2)); } #endif /* RDATA_GENERIC_TKEY_249_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/mb_7.c0000644000470500017500000001273612664710322020433 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: mb_7.c,v 1.47 2009/12/04 22:06:37 tbox Exp $ */ /* Reviewed: Wed Mar 15 17:31:26 PST 2000 by bwelling */ #ifndef RDATA_GENERIC_MB_7_C #define RDATA_GENERIC_MB_7_C #define RRTYPE_MB_ATTRIBUTES (0) static inline isc_result_t fromtext_mb(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; REQUIRE(type == dns_rdatatype_mb); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); return (ISC_R_SUCCESS); } static inline isc_result_t totext_mb(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; REQUIRE(rdata->type == dns_rdatatype_mb); REQUIRE(rdata->length != 0); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); sub = name_prefix(&name, tctx->origin, &prefix); return (dns_name_totext(&prefix, sub, target)); } static inline isc_result_t fromwire_mb(ARGS_FROMWIRE) { dns_name_t name; REQUIRE(type == dns_rdatatype_mb); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, NULL); return (dns_name_fromwire(&name, source, dctx, options, target)); } static inline isc_result_t towire_mb(ARGS_TOWIRE) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_mb); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); return (dns_name_towire(&name, cctx, target)); } static inline int compare_mb(ARGS_COMPARE) { dns_name_t name1; dns_name_t name2; isc_region_t region1; isc_region_t region2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_mb); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); return (dns_name_rdatacompare(&name1, &name2)); } static inline isc_result_t fromstruct_mb(ARGS_FROMSTRUCT) { dns_rdata_mb_t *mb = source; isc_region_t region; REQUIRE(type == dns_rdatatype_mb); REQUIRE(source != NULL); REQUIRE(mb->common.rdtype == type); REQUIRE(mb->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); dns_name_toregion(&mb->mb, ®ion); return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_mb(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_mb_t *mb = target; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_mb); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); mb->common.rdclass = rdata->rdclass; mb->common.rdtype = rdata->type; ISC_LINK_INIT(&mb->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); dns_name_init(&mb->mb, NULL); RETERR(name_duporclone(&name, mctx, &mb->mb)); mb->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_mb(ARGS_FREESTRUCT) { dns_rdata_mb_t *mb = source; REQUIRE(source != NULL); if (mb->mctx == NULL) return; dns_name_free(&mb->mb, mb->mctx); mb->mctx = NULL; } static inline isc_result_t additionaldata_mb(ARGS_ADDLDATA) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_mb); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); return ((add)(arg, &name, dns_rdatatype_a)); } static inline isc_result_t digest_mb(ARGS_DIGEST) { isc_region_t r; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_mb); dns_rdata_toregion(rdata, &r); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); return (dns_name_digest(&name, digest, arg)); } static inline isc_boolean_t checkowner_mb(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_mb); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (dns_name_ismailbox(name)); } static inline isc_boolean_t checknames_mb(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_mb); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_mb(ARGS_COMPARE) { return (compare_mb(rdata1, rdata2)); } #endif /* RDATA_GENERIC_MB_7_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/rp_17.h0000644000470500017500000000232412664710322020534 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_RP_17_H #define GENERIC_RP_17_H 1 /* $Id: rp_17.h,v 1.21 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief Per RFC1183 */ typedef struct dns_rdata_rp { dns_rdatacommon_t common; isc_mem_t *mctx; dns_name_t mail; dns_name_t text; } dns_rdata_rp_t; #endif /* GENERIC_RP_17_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/l64_106.h0000644000470500017500000000175712664710322020610 0ustar lamontlamont/* * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef GENERIC_L64_106_H #define GENERIC_L64_106_H 1 typedef struct dns_rdata_l64 { dns_rdatacommon_t common; isc_uint16_t pref; unsigned char l64[8]; } dns_rdata_l64_t; #endif /* GENERIC_L64_106_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/eui48_108.c0000644000470500017500000001164612664710322021134 0ustar lamontlamont/* * Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef RDATA_GENERIC_EUI48_108_C #define RDATA_GENERIC_EUI48_108_C #include #define RRTYPE_EUI48_ATTRIBUTES (0) static inline isc_result_t fromtext_eui48(ARGS_FROMTEXT) { isc_token_t token; unsigned char eui48[6]; unsigned int l0, l1, l2, l3, l4, l5; int n; REQUIRE(type == dns_rdatatype_eui48); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); n = sscanf(DNS_AS_STR(token), "%2x-%2x-%2x-%2x-%2x-%2x", &l0, &l1, &l2, &l3, &l4, &l5); if (n != 6 || l0 > 255U || l1 > 255U || l2 > 255U || l3 > 255U || l4 > 255U || l5 > 255U) return (DNS_R_BADEUI); eui48[0] = l0; eui48[1] = l1; eui48[2] = l2; eui48[3] = l3; eui48[4] = l4; eui48[5] = l5; return (mem_tobuffer(target, eui48, sizeof(eui48))); } static inline isc_result_t totext_eui48(ARGS_TOTEXT) { char buf[sizeof("xx-xx-xx-xx-xx-xx")]; REQUIRE(rdata->type == dns_rdatatype_eui48); REQUIRE(rdata->length == 6); UNUSED(tctx); (void)snprintf(buf, sizeof(buf), "%02x-%02x-%02x-%02x-%02x-%02x", rdata->data[0], rdata->data[1], rdata->data[2], rdata->data[3], rdata->data[4], rdata->data[5]); return (str_totext(buf, target)); } static inline isc_result_t fromwire_eui48(ARGS_FROMWIRE) { isc_region_t sregion; REQUIRE(type == dns_rdatatype_eui48); UNUSED(type); UNUSED(options); UNUSED(rdclass); UNUSED(dctx); isc_buffer_activeregion(source, &sregion); if (sregion.length != 6) return (DNS_R_FORMERR); isc_buffer_forward(source, sregion.length); return (mem_tobuffer(target, sregion.base, sregion.length)); } static inline isc_result_t towire_eui48(ARGS_TOWIRE) { REQUIRE(rdata->type == dns_rdatatype_eui48); REQUIRE(rdata->length == 6); UNUSED(cctx); return (mem_tobuffer(target, rdata->data, rdata->length)); } static inline int compare_eui48(ARGS_COMPARE) { isc_region_t region1; isc_region_t region2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_eui48); REQUIRE(rdata1->length == 6); REQUIRE(rdata2->length == 6); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); return (isc_region_compare(®ion1, ®ion2)); } static inline isc_result_t fromstruct_eui48(ARGS_FROMSTRUCT) { dns_rdata_eui48_t *eui48 = source; REQUIRE(type == dns_rdatatype_eui48); REQUIRE(source != NULL); REQUIRE(eui48->common.rdtype == type); REQUIRE(eui48->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); return (mem_tobuffer(target, eui48->eui48, sizeof(eui48->eui48))); } static inline isc_result_t tostruct_eui48(ARGS_TOSTRUCT) { dns_rdata_eui48_t *eui48 = target; REQUIRE(rdata->type == dns_rdatatype_eui48); REQUIRE(target != NULL); REQUIRE(rdata->length == 6); UNUSED(mctx); eui48->common.rdclass = rdata->rdclass; eui48->common.rdtype = rdata->type; ISC_LINK_INIT(&eui48->common, link); memmove(eui48->eui48, rdata->data, rdata->length); return (ISC_R_SUCCESS); } static inline void freestruct_eui48(ARGS_FREESTRUCT) { dns_rdata_eui48_t *eui48 = source; REQUIRE(source != NULL); REQUIRE(eui48->common.rdtype == dns_rdatatype_eui48); return; } static inline isc_result_t additionaldata_eui48(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_eui48); REQUIRE(rdata->length == 6); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_eui48(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_eui48); REQUIRE(rdata->length == 6); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_eui48(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_eui48); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_eui48(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_eui48); REQUIRE(rdata->length == 6); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_eui48(ARGS_COMPARE) { return (compare_eui48(rdata1, rdata2)); } #endif /* RDATA_GENERIC_EUI48_108_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/dname_39.c0000644000470500017500000001310012664710322021170 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: dname_39.c,v 1.40 2009/12/04 22:06:37 tbox Exp $ */ /* Reviewed: Wed Mar 15 16:52:38 PST 2000 by explorer */ /* RFC2672 */ #ifndef RDATA_GENERIC_DNAME_39_C #define RDATA_GENERIC_DNAME_39_C #define RRTYPE_DNAME_ATTRIBUTES (DNS_RDATATYPEATTR_SINGLETON) static inline isc_result_t fromtext_dname(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; REQUIRE(type == dns_rdatatype_dname); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); return (ISC_R_SUCCESS); } static inline isc_result_t totext_dname(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; REQUIRE(rdata->type == dns_rdatatype_dname); REQUIRE(rdata->length != 0); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); sub = name_prefix(&name, tctx->origin, &prefix); return (dns_name_totext(&prefix, sub, target)); } static inline isc_result_t fromwire_dname(ARGS_FROMWIRE) { dns_name_t name; REQUIRE(type == dns_rdatatype_dname); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); dns_name_init(&name, NULL); return(dns_name_fromwire(&name, source, dctx, options, target)); } static inline isc_result_t towire_dname(ARGS_TOWIRE) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_dname); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); return (dns_name_towire(&name, cctx, target)); } static inline int compare_dname(ARGS_COMPARE) { dns_name_t name1; dns_name_t name2; isc_region_t region1; isc_region_t region2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_dname); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); return (dns_name_rdatacompare(&name1, &name2)); } static inline isc_result_t fromstruct_dname(ARGS_FROMSTRUCT) { dns_rdata_dname_t *dname = source; isc_region_t region; REQUIRE(type == dns_rdatatype_dname); REQUIRE(source != NULL); REQUIRE(dname->common.rdtype == type); REQUIRE(dname->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); dns_name_toregion(&dname->dname, ®ion); return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_dname(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_dname_t *dname = target; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_dname); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); dname->common.rdclass = rdata->rdclass; dname->common.rdtype = rdata->type; ISC_LINK_INIT(&dname->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); dns_name_init(&dname->dname, NULL); RETERR(name_duporclone(&name, mctx, &dname->dname)); dname->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_dname(ARGS_FREESTRUCT) { dns_rdata_dname_t *dname = source; REQUIRE(source != NULL); REQUIRE(dname->common.rdtype == dns_rdatatype_dname); if (dname->mctx == NULL) return; dns_name_free(&dname->dname, dname->mctx); dname->mctx = NULL; } static inline isc_result_t additionaldata_dname(ARGS_ADDLDATA) { UNUSED(rdata); UNUSED(add); UNUSED(arg); REQUIRE(rdata->type == dns_rdatatype_dname); return (ISC_R_SUCCESS); } static inline isc_result_t digest_dname(ARGS_DIGEST) { isc_region_t r; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_dname); dns_rdata_toregion(rdata, &r); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); return (dns_name_digest(&name, digest, arg)); } static inline isc_boolean_t checkowner_dname(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_dname); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_dname(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_dname); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_dname(ARGS_COMPARE) { return (compare_dname(rdata1, rdata2)); } #endif /* RDATA_GENERIC_DNAME_39_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/loc_29.c0000644000470500017500000004432712664710322020677 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: loc_29.c,v 1.50 2009/12/04 21:09:33 marka Exp $ */ /* Reviewed: Wed Mar 15 18:13:09 PST 2000 by explorer */ /* RFC1876 */ #ifndef RDATA_GENERIC_LOC_29_C #define RDATA_GENERIC_LOC_29_C #define RRTYPE_LOC_ATTRIBUTES (0) static inline isc_result_t fromtext_loc(ARGS_FROMTEXT) { isc_token_t token; int d1, m1, s1; int d2, m2, s2; unsigned char size; unsigned char hp; unsigned char vp; unsigned char version; isc_boolean_t east = ISC_FALSE; isc_boolean_t north = ISC_FALSE; long tmp; long m; long cm; long poweroften[8] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000 }; int man; int exp; char *e; int i; unsigned long latitude; unsigned long longitude; unsigned long altitude; REQUIRE(type == dns_rdatatype_loc); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); /* * Defaults. */ m1 = s1 = 0; m2 = s2 = 0; size = 0x12; /* 1.00m */ hp = 0x16; /* 10000.00 m */ vp = 0x13; /* 10.00 m */ version = 0; /* * Degrees. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 90U) RETTOK(ISC_R_RANGE); d1 = (int)token.value.as_ulong; /* * Minutes. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (strcasecmp(DNS_AS_STR(token), "N") == 0) north = ISC_TRUE; if (north || strcasecmp(DNS_AS_STR(token), "S") == 0) goto getlong; m1 = strtol(DNS_AS_STR(token), &e, 10); if (*e != 0) RETTOK(DNS_R_SYNTAX); if (m1 < 0 || m1 > 59) RETTOK(ISC_R_RANGE); if (d1 == 90 && m1 != 0) RETTOK(ISC_R_RANGE); /* * Seconds. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (strcasecmp(DNS_AS_STR(token), "N") == 0) north = ISC_TRUE; if (north || strcasecmp(DNS_AS_STR(token), "S") == 0) goto getlong; s1 = strtol(DNS_AS_STR(token), &e, 10); if (*e != 0 && *e != '.') RETTOK(DNS_R_SYNTAX); if (s1 < 0 || s1 > 59) RETTOK(ISC_R_RANGE); if (*e == '.') { const char *l; e++; for (i = 0; i < 3; i++) { if (*e == 0) break; if ((tmp = decvalue(*e++)) < 0) RETTOK(DNS_R_SYNTAX); s1 *= 10; s1 += tmp; } for (; i < 3; i++) s1 *= 10; l = e; while (*e != 0) { if (decvalue(*e++) < 0) RETTOK(DNS_R_SYNTAX); } if (*l != '\0' && callbacks != NULL) { const char *file = isc_lex_getsourcename(lexer); unsigned long line = isc_lex_getsourceline(lexer); if (file == NULL) file = "UNKNOWN"; (*callbacks->warn)(callbacks, "%s: %s:%u: '%s' extra " "precision digits ignored", "dns_rdata_fromtext", file, line, DNS_AS_STR(token)); } } else s1 *= 1000; if (d1 == 90 && s1 != 0) RETTOK(ISC_R_RANGE); /* * Direction. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (strcasecmp(DNS_AS_STR(token), "N") == 0) north = ISC_TRUE; if (!north && strcasecmp(DNS_AS_STR(token), "S") != 0) RETTOK(DNS_R_SYNTAX); getlong: /* * Degrees. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 180U) RETTOK(ISC_R_RANGE); d2 = (int)token.value.as_ulong; /* * Minutes. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (strcasecmp(DNS_AS_STR(token), "E") == 0) east = ISC_TRUE; if (east || strcasecmp(DNS_AS_STR(token), "W") == 0) goto getalt; m2 = strtol(DNS_AS_STR(token), &e, 10); if (*e != 0) RETTOK(DNS_R_SYNTAX); if (m2 < 0 || m2 > 59) RETTOK(ISC_R_RANGE); if (d2 == 180 && m2 != 0) RETTOK(ISC_R_RANGE); /* * Seconds. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (strcasecmp(DNS_AS_STR(token), "E") == 0) east = ISC_TRUE; if (east || strcasecmp(DNS_AS_STR(token), "W") == 0) goto getalt; s2 = strtol(DNS_AS_STR(token), &e, 10); if (*e != 0 && *e != '.') RETTOK(DNS_R_SYNTAX); if (s2 < 0 || s2 > 59) RETTOK(ISC_R_RANGE); if (*e == '.') { const char *l; e++; for (i = 0; i < 3; i++) { if (*e == 0) break; if ((tmp = decvalue(*e++)) < 0) RETTOK(DNS_R_SYNTAX); s2 *= 10; s2 += tmp; } for (; i < 3; i++) s2 *= 10; l = e; while (*e != 0) { if (decvalue(*e++) < 0) RETTOK(DNS_R_SYNTAX); } if (*l != '\0' && callbacks != NULL) { const char *file = isc_lex_getsourcename(lexer); unsigned long line = isc_lex_getsourceline(lexer); if (file == NULL) file = "UNKNOWN"; (*callbacks->warn)(callbacks, "%s: %s:%u: '%s' extra " "precision digits ignored", "dns_rdata_fromtext", file, line, DNS_AS_STR(token)); } } else s2 *= 1000; if (d2 == 180 && s2 != 0) RETTOK(ISC_R_RANGE); /* * Direction. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (strcasecmp(DNS_AS_STR(token), "E") == 0) east = ISC_TRUE; if (!east && strcasecmp(DNS_AS_STR(token), "W") != 0) RETTOK(DNS_R_SYNTAX); getalt: /* * Altitude. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); m = strtol(DNS_AS_STR(token), &e, 10); if (*e != 0 && *e != '.' && *e != 'm') RETTOK(DNS_R_SYNTAX); if (m < -100000 || m > 42849672) RETTOK(ISC_R_RANGE); cm = 0; if (*e == '.') { e++; for (i = 0; i < 2; i++) { if (*e == 0 || *e == 'm') break; if ((tmp = decvalue(*e++)) < 0) return (DNS_R_SYNTAX); cm *= 10; if (m < 0) cm -= tmp; else cm += tmp; } for (; i < 2; i++) cm *= 10; } if (*e == 'm') e++; if (*e != 0) RETTOK(DNS_R_SYNTAX); if (m == -100000 && cm != 0) RETTOK(ISC_R_RANGE); if (m == 42849672 && cm > 95) RETTOK(ISC_R_RANGE); /* * Adjust base. */ altitude = m + 100000; altitude *= 100; altitude += cm; /* * Size: optional. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_TRUE)); if (token.type == isc_tokentype_eol || token.type == isc_tokentype_eof) { isc_lex_ungettoken(lexer, &token); goto encode; } m = strtol(DNS_AS_STR(token), &e, 10); if (*e != 0 && *e != '.' && *e != 'm') RETTOK(DNS_R_SYNTAX); if (m < 0 || m > 90000000) RETTOK(ISC_R_RANGE); cm = 0; if (*e == '.') { e++; for (i = 0; i < 2; i++) { if (*e == 0 || *e == 'm') break; if ((tmp = decvalue(*e++)) < 0) RETTOK(DNS_R_SYNTAX); cm *= 10; cm += tmp; } for (; i < 2; i++) cm *= 10; } if (*e == 'm') e++; if (*e != 0) RETTOK(DNS_R_SYNTAX); /* * We don't just multiply out as we will overflow. */ if (m > 0) { for (exp = 0; exp < 7; exp++) if (m < poweroften[exp+1]) break; man = m / poweroften[exp]; exp += 2; } else { if (cm >= 10) { man = cm / 10; exp = 1; } else { man = cm; exp = 0; } } size = (man << 4) + exp; /* * Horizontal precision: optional. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_TRUE)); if (token.type == isc_tokentype_eol || token.type == isc_tokentype_eof) { isc_lex_ungettoken(lexer, &token); goto encode; } m = strtol(DNS_AS_STR(token), &e, 10); if (*e != 0 && *e != '.' && *e != 'm') RETTOK(DNS_R_SYNTAX); if (m < 0 || m > 90000000) RETTOK(ISC_R_RANGE); cm = 0; if (*e == '.') { e++; for (i = 0; i < 2; i++) { if (*e == 0 || *e == 'm') break; if ((tmp = decvalue(*e++)) < 0) RETTOK(DNS_R_SYNTAX); cm *= 10; cm += tmp; } for (; i < 2; i++) cm *= 10; } if (*e == 'm') e++; if (*e != 0) RETTOK(DNS_R_SYNTAX); /* * We don't just multiply out as we will overflow. */ if (m > 0) { for (exp = 0; exp < 7; exp++) if (m < poweroften[exp+1]) break; man = m / poweroften[exp]; exp += 2; } else if (cm >= 10) { man = cm / 10; exp = 1; } else { man = cm; exp = 0; } hp = (man << 4) + exp; /* * Vertical precision: optional. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_TRUE)); if (token.type == isc_tokentype_eol || token.type == isc_tokentype_eof) { isc_lex_ungettoken(lexer, &token); goto encode; } m = strtol(DNS_AS_STR(token), &e, 10); if (*e != 0 && *e != '.' && *e != 'm') RETTOK(DNS_R_SYNTAX); if (m < 0 || m > 90000000) RETTOK(ISC_R_RANGE); cm = 0; if (*e == '.') { e++; for (i = 0; i < 2; i++) { if (*e == 0 || *e == 'm') break; if ((tmp = decvalue(*e++)) < 0) RETTOK(DNS_R_SYNTAX); cm *= 10; cm += tmp; } for (; i < 2; i++) cm *= 10; } if (*e == 'm') e++; if (*e != 0) RETTOK(DNS_R_SYNTAX); /* * We don't just multiply out as we will overflow. */ if (m > 0) { for (exp = 0; exp < 7; exp++) if (m < poweroften[exp+1]) break; man = m / poweroften[exp]; exp += 2; } else if (cm >= 10) { man = cm / 10; exp = 1; } else { man = cm; exp = 0; } vp = (man << 4) + exp; encode: RETERR(mem_tobuffer(target, &version, 1)); RETERR(mem_tobuffer(target, &size, 1)); RETERR(mem_tobuffer(target, &hp, 1)); RETERR(mem_tobuffer(target, &vp, 1)); if (north) latitude = 0x80000000 + ( d1 * 3600 + m1 * 60 ) * 1000 + s1; else latitude = 0x80000000 - ( d1 * 3600 + m1 * 60 ) * 1000 - s1; RETERR(uint32_tobuffer(latitude, target)); if (east) longitude = 0x80000000 + ( d2 * 3600 + m2 * 60 ) * 1000 + s2; else longitude = 0x80000000 - ( d2 * 3600 + m2 * 60 ) * 1000 - s2; RETERR(uint32_tobuffer(longitude, target)); return (uint32_tobuffer(altitude, target)); } static inline isc_result_t totext_loc(ARGS_TOTEXT) { int d1, m1, s1, fs1; int d2, m2, s2, fs2; unsigned long latitude; unsigned long longitude; unsigned long altitude; isc_boolean_t north; isc_boolean_t east; isc_boolean_t below; isc_region_t sr; char buf[sizeof("89 59 59.999 N 179 59 59.999 E " "42849672.95m 90000000m 90000000m 90000000m")]; char sbuf[sizeof("90000000m")]; char hbuf[sizeof("90000000m")]; char vbuf[sizeof("90000000m")]; unsigned char size, hp, vp; unsigned long poweroften[8] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000 }; UNUSED(tctx); REQUIRE(rdata->type == dns_rdatatype_loc); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); if (sr.base[0] != 0) return (ISC_R_NOTIMPLEMENTED); REQUIRE(rdata->length == 16); size = sr.base[1]; INSIST((size&0x0f) < 10 && (size>>4) < 10); if ((size&0x0f)> 1) sprintf(sbuf, "%lum", (size>>4) * poweroften[(size&0x0f)-2]); else sprintf(sbuf, "0.%02lum", (size>>4) * poweroften[(size&0x0f)]); hp = sr.base[2]; INSIST((hp&0x0f) < 10 && (hp>>4) < 10); if ((hp&0x0f)> 1) sprintf(hbuf, "%lum", (hp>>4) * poweroften[(hp&0x0f)-2]); else sprintf(hbuf, "0.%02lum", (hp>>4) * poweroften[(hp&0x0f)]); vp = sr.base[3]; INSIST((vp&0x0f) < 10 && (vp>>4) < 10); if ((vp&0x0f)> 1) sprintf(vbuf, "%lum", (vp>>4) * poweroften[(vp&0x0f)-2]); else sprintf(vbuf, "0.%02lum", (vp>>4) * poweroften[(vp&0x0f)]); isc_region_consume(&sr, 4); latitude = uint32_fromregion(&sr); isc_region_consume(&sr, 4); if (latitude >= 0x80000000) { north = ISC_TRUE; latitude -= 0x80000000; } else { north = ISC_FALSE; latitude = 0x80000000 - latitude; } fs1 = (int)(latitude % 1000); latitude /= 1000; s1 = (int)(latitude % 60); latitude /= 60; m1 = (int)(latitude % 60); latitude /= 60; d1 = (int)latitude; INSIST(latitude <= 90U); longitude = uint32_fromregion(&sr); isc_region_consume(&sr, 4); if (longitude >= 0x80000000) { east = ISC_TRUE; longitude -= 0x80000000; } else { east = ISC_FALSE; longitude = 0x80000000 - longitude; } fs2 = (int)(longitude % 1000); longitude /= 1000; s2 = (int)(longitude % 60); longitude /= 60; m2 = (int)(longitude % 60); longitude /= 60; d2 = (int)longitude; INSIST(longitude <= 180U); altitude = uint32_fromregion(&sr); isc_region_consume(&sr, 4); if (altitude < 10000000U) { below = ISC_TRUE; altitude = 10000000 - altitude; } else { below =ISC_FALSE; altitude -= 10000000; } sprintf(buf, "%d %d %d.%03d %s %d %d %d.%03d %s %s%ld.%02ldm %s %s %s", d1, m1, s1, fs1, north ? "N" : "S", d2, m2, s2, fs2, east ? "E" : "W", below ? "-" : "", altitude/100, altitude % 100, sbuf, hbuf, vbuf); return (str_totext(buf, target)); } static inline isc_result_t fromwire_loc(ARGS_FROMWIRE) { isc_region_t sr; unsigned char c; unsigned long latitude; unsigned long longitude; REQUIRE(type == dns_rdatatype_loc); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); isc_buffer_activeregion(source, &sr); if (sr.length < 1) return (ISC_R_UNEXPECTEDEND); if (sr.base[0] != 0) { /* Treat as unknown. */ isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); } if (sr.length < 16) return (ISC_R_UNEXPECTEDEND); /* * Size. */ c = sr.base[1]; if (c != 0) if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0) return (ISC_R_RANGE); /* * Horizontal precision. */ c = sr.base[2]; if (c != 0) if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0) return (ISC_R_RANGE); /* * Vertical precision. */ c = sr.base[3]; if (c != 0) if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0) return (ISC_R_RANGE); isc_region_consume(&sr, 4); /* * Latitude. */ latitude = uint32_fromregion(&sr); if (latitude < (0x80000000UL - 90 * 3600000) || latitude > (0x80000000UL + 90 * 3600000)) return (ISC_R_RANGE); isc_region_consume(&sr, 4); /* * Longitude. */ longitude = uint32_fromregion(&sr); if (longitude < (0x80000000UL - 180 * 3600000) || longitude > (0x80000000UL + 180 * 3600000)) return (ISC_R_RANGE); /* * Altitude. * All values possible. */ isc_buffer_activeregion(source, &sr); isc_buffer_forward(source, 16); return (mem_tobuffer(target, sr.base, 16)); } static inline isc_result_t towire_loc(ARGS_TOWIRE) { UNUSED(cctx); REQUIRE(rdata->type == dns_rdatatype_loc); REQUIRE(rdata->length != 0); return (mem_tobuffer(target, rdata->data, rdata->length)); } static inline int compare_loc(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_loc); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_loc(ARGS_FROMSTRUCT) { dns_rdata_loc_t *loc = source; isc_uint8_t c; REQUIRE(type == dns_rdatatype_loc); REQUIRE(source != NULL); REQUIRE(loc->common.rdtype == type); REQUIRE(loc->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); if (loc->v.v0.version != 0) return (ISC_R_NOTIMPLEMENTED); RETERR(uint8_tobuffer(loc->v.v0.version, target)); c = loc->v.v0.size; if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0) return (ISC_R_RANGE); RETERR(uint8_tobuffer(loc->v.v0.size, target)); c = loc->v.v0.horizontal; if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0) return (ISC_R_RANGE); RETERR(uint8_tobuffer(loc->v.v0.horizontal, target)); c = loc->v.v0.vertical; if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0) return (ISC_R_RANGE); RETERR(uint8_tobuffer(loc->v.v0.vertical, target)); if (loc->v.v0.latitude < (0x80000000UL - 90 * 3600000) || loc->v.v0.latitude > (0x80000000UL + 90 * 3600000)) return (ISC_R_RANGE); RETERR(uint32_tobuffer(loc->v.v0.latitude, target)); if (loc->v.v0.longitude < (0x80000000UL - 180 * 3600000) || loc->v.v0.longitude > (0x80000000UL + 180 * 3600000)) return (ISC_R_RANGE); RETERR(uint32_tobuffer(loc->v.v0.longitude, target)); return (uint32_tobuffer(loc->v.v0.altitude, target)); } static inline isc_result_t tostruct_loc(ARGS_TOSTRUCT) { dns_rdata_loc_t *loc = target; isc_region_t r; isc_uint8_t version; REQUIRE(rdata->type == dns_rdatatype_loc); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); UNUSED(mctx); dns_rdata_toregion(rdata, &r); version = uint8_fromregion(&r); if (version != 0) return (ISC_R_NOTIMPLEMENTED); loc->common.rdclass = rdata->rdclass; loc->common.rdtype = rdata->type; ISC_LINK_INIT(&loc->common, link); loc->v.v0.version = version; isc_region_consume(&r, 1); loc->v.v0.size = uint8_fromregion(&r); isc_region_consume(&r, 1); loc->v.v0.horizontal = uint8_fromregion(&r); isc_region_consume(&r, 1); loc->v.v0.vertical = uint8_fromregion(&r); isc_region_consume(&r, 1); loc->v.v0.latitude = uint32_fromregion(&r); isc_region_consume(&r, 4); loc->v.v0.longitude = uint32_fromregion(&r); isc_region_consume(&r, 4); loc->v.v0.altitude = uint32_fromregion(&r); isc_region_consume(&r, 4); return (ISC_R_SUCCESS); } static inline void freestruct_loc(ARGS_FREESTRUCT) { dns_rdata_loc_t *loc = source; REQUIRE(source != NULL); REQUIRE(loc->common.rdtype == dns_rdatatype_loc); UNUSED(source); UNUSED(loc); } static inline isc_result_t additionaldata_loc(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_loc); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_loc(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_loc); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_loc(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_loc); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_loc(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_loc); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_loc(ARGS_COMPARE) { return (compare_loc(rdata1, rdata2)); } #endif /* RDATA_GENERIC_LOC_29_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/ipseckey_45.h0000644000470500017500000000246412664710322021735 0ustar lamontlamont/* * Copyright (C) 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ipseckey_45.h,v 1.4 2007/06/19 23:47:17 tbox Exp $ */ #ifndef GENERIC_IPSECKEY_45_H #define GENERIC_IPSECKEY_45_H 1 typedef struct dns_rdata_ipseckey { dns_rdatacommon_t common; isc_mem_t *mctx; isc_uint8_t precedence; isc_uint8_t gateway_type; isc_uint8_t algorithm; struct in_addr in_addr; /* gateway type 1 */ struct in6_addr in6_addr; /* gateway type 2 */ dns_name_t gateway; /* gateway type 3 */ unsigned char *key; isc_uint16_t keylength; } dns_rdata_ipseckey_t; #endif /* GENERIC_IPSECKEY_45_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/txt_16.c0000644000470500017500000001560712664710322020734 0ustar lamontlamont/* * Copyright (C) 2004, 2007-2009, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: txt_16.c,v 1.47 2009/12/04 22:06:37 tbox Exp $ */ /* Reviewed: Thu Mar 16 15:40:00 PST 2000 by bwelling */ #ifndef RDATA_GENERIC_TXT_16_C #define RDATA_GENERIC_TXT_16_C #define RRTYPE_TXT_ATTRIBUTES (0) static inline isc_result_t fromtext_txt(ARGS_FROMTEXT) { isc_token_t token; int strings; REQUIRE(type == dns_rdatatype_txt); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); strings = 0; if ((options & DNS_RDATA_UNKNOWNESCAPE) != 0) { isc_textregion_t r; DE_CONST("#", r.base); r.length = 1; RETERR(txt_fromtext(&r, target)); strings++; } for (;;) { RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, ISC_TRUE)); if (token.type != isc_tokentype_qstring && token.type != isc_tokentype_string) break; RETTOK(txt_fromtext(&token.value.as_textregion, target)); strings++; } /* Let upper layer handle eol/eof. */ isc_lex_ungettoken(lexer, &token); return (strings == 0 ? ISC_R_UNEXPECTEDEND : ISC_R_SUCCESS); } static inline isc_result_t totext_txt(ARGS_TOTEXT) { isc_region_t region; UNUSED(tctx); REQUIRE(rdata->type == dns_rdatatype_txt); dns_rdata_toregion(rdata, ®ion); while (region.length > 0) { RETERR(txt_totext(®ion, ISC_TRUE, target)); if (region.length > 0) RETERR(str_totext(" ", target)); } return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_txt(ARGS_FROMWIRE) { isc_result_t result; REQUIRE(type == dns_rdatatype_txt); UNUSED(type); UNUSED(dctx); UNUSED(rdclass); UNUSED(options); do { result = txt_fromwire(source, target); if (result != ISC_R_SUCCESS) return (result); } while (!buffer_empty(source)); return (ISC_R_SUCCESS); } static inline isc_result_t towire_txt(ARGS_TOWIRE) { isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_txt); UNUSED(cctx); isc_buffer_availableregion(target, ®ion); if (region.length < rdata->length) return (ISC_R_NOSPACE); memmove(region.base, rdata->data, rdata->length); isc_buffer_add(target, rdata->length); return (ISC_R_SUCCESS); } static inline int compare_txt(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_txt); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_txt(ARGS_FROMSTRUCT) { dns_rdata_txt_t *txt = source; isc_region_t region; isc_uint8_t length; REQUIRE(type == dns_rdatatype_txt); REQUIRE(source != NULL); REQUIRE(txt->common.rdtype == type); REQUIRE(txt->common.rdclass == rdclass); REQUIRE(txt->txt != NULL && txt->txt_len != 0); UNUSED(type); UNUSED(rdclass); region.base = txt->txt; region.length = txt->txt_len; while (region.length > 0) { length = uint8_fromregion(®ion); isc_region_consume(®ion, 1); if (region.length < length) return (ISC_R_UNEXPECTEDEND); isc_region_consume(®ion, length); } return (mem_tobuffer(target, txt->txt, txt->txt_len)); } static inline isc_result_t tostruct_txt(ARGS_TOSTRUCT) { dns_rdata_txt_t *txt = target; isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_txt); REQUIRE(target != NULL); txt->common.rdclass = rdata->rdclass; txt->common.rdtype = rdata->type; ISC_LINK_INIT(&txt->common, link); dns_rdata_toregion(rdata, &r); txt->txt_len = r.length; txt->txt = mem_maybedup(mctx, r.base, r.length); if (txt->txt == NULL) return (ISC_R_NOMEMORY); txt->offset = 0; txt->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_txt(ARGS_FREESTRUCT) { dns_rdata_txt_t *txt = source; REQUIRE(source != NULL); REQUIRE(txt->common.rdtype == dns_rdatatype_txt); if (txt->mctx == NULL) return; if (txt->txt != NULL) isc_mem_free(txt->mctx, txt->txt); txt->mctx = NULL; } static inline isc_result_t additionaldata_txt(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_txt); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_txt(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_txt); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_txt(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_txt); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_txt(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_txt); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline isc_result_t casecompare_txt(ARGS_COMPARE) { return (compare_txt(rdata1, rdata2)); } isc_result_t dns_rdata_txt_first(dns_rdata_txt_t *txt) { REQUIRE(txt != NULL); REQUIRE(txt->common.rdtype == dns_rdatatype_txt); REQUIRE(txt->txt != NULL || txt->txt_len == 0); if (txt->txt_len == 0) return (ISC_R_NOMORE); txt->offset = 0; return (ISC_R_SUCCESS); } isc_result_t dns_rdata_txt_next(dns_rdata_txt_t *txt) { isc_region_t r; isc_uint8_t length; REQUIRE(txt != NULL); REQUIRE(txt->common.rdtype == dns_rdatatype_txt); REQUIRE(txt->txt != NULL && txt->txt_len != 0); INSIST(txt->offset + 1 <= txt->txt_len); r.base = txt->txt + txt->offset; r.length = txt->txt_len - txt->offset; length = uint8_fromregion(&r); INSIST(txt->offset + 1 + length <= txt->txt_len); txt->offset = txt->offset + 1 + length; if (txt->offset == txt->txt_len) return (ISC_R_NOMORE); return (ISC_R_SUCCESS); } isc_result_t dns_rdata_txt_current(dns_rdata_txt_t *txt, dns_rdata_txt_string_t *string) { isc_region_t r; REQUIRE(txt != NULL); REQUIRE(string != NULL); REQUIRE(txt->common.rdtype == dns_rdatatype_txt); REQUIRE(txt->txt != NULL); REQUIRE(txt->offset < txt->txt_len); INSIST(txt->offset + 1 <= txt->txt_len); r.base = txt->txt + txt->offset; r.length = txt->txt_len - txt->offset; string->length = uint8_fromregion(&r); isc_region_consume(&r, 1); string->data = r.base; INSIST(txt->offset + 1 + string->length <= txt->txt_len); return (ISC_R_SUCCESS); } #endif /* RDATA_GENERIC_TXT_16_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/uri_256.h0000644000470500017500000000210412664710322020773 0ustar lamontlamont/* * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_URI_256_H #define GENERIC_URI_256_H 1 /* $Id$ */ typedef struct dns_rdata_uri { dns_rdatacommon_t common; isc_mem_t * mctx; isc_uint16_t priority; isc_uint16_t weight; unsigned char * target; isc_uint16_t tgt_len; } dns_rdata_uri_t; #endif /* GENERIC_URI_256_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/spf_99.c0000644000470500017500000001254612664710322020717 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: spf_99.c,v 1.6 2009/12/04 22:06:37 tbox Exp $ */ /* Reviewed: Thu Mar 16 15:40:00 PST 2000 by bwelling */ #ifndef RDATA_GENERIC_SPF_99_C #define RDATA_GENERIC_SPF_99_C #define RRTYPE_SPF_ATTRIBUTES (0) static inline isc_result_t fromtext_spf(ARGS_FROMTEXT) { isc_token_t token; int strings; REQUIRE(type == dns_rdatatype_spf); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); strings = 0; for (;;) { RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, ISC_TRUE)); if (token.type != isc_tokentype_qstring && token.type != isc_tokentype_string) break; RETTOK(txt_fromtext(&token.value.as_textregion, target)); strings++; } /* Let upper layer handle eol/eof. */ isc_lex_ungettoken(lexer, &token); return (strings == 0 ? ISC_R_UNEXPECTEDEND : ISC_R_SUCCESS); } static inline isc_result_t totext_spf(ARGS_TOTEXT) { isc_region_t region; UNUSED(tctx); REQUIRE(rdata->type == dns_rdatatype_spf); dns_rdata_toregion(rdata, ®ion); while (region.length > 0) { RETERR(txt_totext(®ion, ISC_TRUE, target)); if (region.length > 0) RETERR(str_totext(" ", target)); } return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_spf(ARGS_FROMWIRE) { isc_result_t result; REQUIRE(type == dns_rdatatype_spf); UNUSED(type); UNUSED(dctx); UNUSED(rdclass); UNUSED(options); do { result = txt_fromwire(source, target); if (result != ISC_R_SUCCESS) return (result); } while (!buffer_empty(source)); return (ISC_R_SUCCESS); } static inline isc_result_t towire_spf(ARGS_TOWIRE) { isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_spf); UNUSED(cctx); isc_buffer_availableregion(target, ®ion); if (region.length < rdata->length) return (ISC_R_NOSPACE); memmove(region.base, rdata->data, rdata->length); isc_buffer_add(target, rdata->length); return (ISC_R_SUCCESS); } static inline int compare_spf(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_spf); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_spf(ARGS_FROMSTRUCT) { dns_rdata_spf_t *txt = source; isc_region_t region; isc_uint8_t length; REQUIRE(type == dns_rdatatype_spf); REQUIRE(source != NULL); REQUIRE(txt->common.rdtype == type); REQUIRE(txt->common.rdclass == rdclass); REQUIRE(txt->txt != NULL && txt->txt_len != 0); UNUSED(type); UNUSED(rdclass); region.base = txt->txt; region.length = txt->txt_len; while (region.length > 0) { length = uint8_fromregion(®ion); isc_region_consume(®ion, 1); if (region.length <= length) return (ISC_R_UNEXPECTEDEND); isc_region_consume(®ion, length); } return (mem_tobuffer(target, txt->txt, txt->txt_len)); } static inline isc_result_t tostruct_spf(ARGS_TOSTRUCT) { dns_rdata_spf_t *txt = target; isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_spf); REQUIRE(target != NULL); txt->common.rdclass = rdata->rdclass; txt->common.rdtype = rdata->type; ISC_LINK_INIT(&txt->common, link); dns_rdata_toregion(rdata, &r); txt->txt_len = r.length; txt->txt = mem_maybedup(mctx, r.base, r.length); if (txt->txt == NULL) return (ISC_R_NOMEMORY); txt->offset = 0; txt->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_spf(ARGS_FREESTRUCT) { dns_rdata_spf_t *txt = source; REQUIRE(source != NULL); REQUIRE(txt->common.rdtype == dns_rdatatype_spf); if (txt->mctx == NULL) return; if (txt->txt != NULL) isc_mem_free(txt->mctx, txt->txt); txt->mctx = NULL; } static inline isc_result_t additionaldata_spf(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_spf); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_spf(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_spf); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_spf(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_spf); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_spf(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_spf); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_spf(ARGS_COMPARE) { return (compare_spf(rdata1, rdata2)); } #endif /* RDATA_GENERIC_SPF_99_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/l64_106.c0000644000470500017500000001226112664710322020573 0ustar lamontlamont/* * Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef RDATA_GENERIC_L64_106_C #define RDATA_GENERIC_L64_106_C #include #include #define RRTYPE_L64_ATTRIBUTES (0) static inline isc_result_t fromtext_l64(ARGS_FROMTEXT) { isc_token_t token; unsigned char locator[NS_LOCATORSZ]; REQUIRE(type == dns_rdatatype_l64); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (locator_pton(DNS_AS_STR(token), locator) != 1) RETTOK(DNS_R_SYNTAX); return (mem_tobuffer(target, locator, NS_LOCATORSZ)); } static inline isc_result_t totext_l64(ARGS_TOTEXT) { isc_region_t region; char buf[sizeof("xxxx:xxxx:xxxx:xxxx")]; unsigned short num; REQUIRE(rdata->type == dns_rdatatype_l64); REQUIRE(rdata->length == 10); UNUSED(tctx); dns_rdata_toregion(rdata, ®ion); num = uint16_fromregion(®ion); isc_region_consume(®ion, 2); sprintf(buf, "%u", num); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); sprintf(buf, "%x:%x:%x:%x", region.base[0]<<8 | region.base[1], region.base[2]<<8 | region.base[3], region.base[4]<<8 | region.base[5], region.base[6]<<8 | region.base[7]); return (str_totext(buf, target)); } static inline isc_result_t fromwire_l64(ARGS_FROMWIRE) { isc_region_t sregion; REQUIRE(type == dns_rdatatype_l64); UNUSED(type); UNUSED(options); UNUSED(rdclass); UNUSED(dctx); isc_buffer_activeregion(source, &sregion); if (sregion.length != 10) return (DNS_R_FORMERR); isc_buffer_forward(source, sregion.length); return (mem_tobuffer(target, sregion.base, sregion.length)); } static inline isc_result_t towire_l64(ARGS_TOWIRE) { REQUIRE(rdata->type == dns_rdatatype_l64); REQUIRE(rdata->length == 10); UNUSED(cctx); return (mem_tobuffer(target, rdata->data, rdata->length)); } static inline int compare_l64(ARGS_COMPARE) { isc_region_t region1; isc_region_t region2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_l64); REQUIRE(rdata1->length == 10); REQUIRE(rdata2->length == 10); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); return (isc_region_compare(®ion1, ®ion2)); } static inline isc_result_t fromstruct_l64(ARGS_FROMSTRUCT) { dns_rdata_l64_t *l64 = source; REQUIRE(type == dns_rdatatype_l64); REQUIRE(source != NULL); REQUIRE(l64->common.rdtype == type); REQUIRE(l64->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); RETERR(uint16_tobuffer(l64->pref, target)); return (mem_tobuffer(target, l64->l64, sizeof(l64->l64))); } static inline isc_result_t tostruct_l64(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_l64_t *l64 = target; REQUIRE(rdata->type == dns_rdatatype_l64); REQUIRE(target != NULL); REQUIRE(rdata->length == 10); UNUSED(mctx); l64->common.rdclass = rdata->rdclass; l64->common.rdtype = rdata->type; ISC_LINK_INIT(&l64->common, link); dns_rdata_toregion(rdata, ®ion); l64->pref = uint16_fromregion(®ion); memmove(l64->l64, region.base, region.length); return (ISC_R_SUCCESS); } static inline void freestruct_l64(ARGS_FREESTRUCT) { dns_rdata_l64_t *l64 = source; REQUIRE(source != NULL); REQUIRE(l64->common.rdtype == dns_rdatatype_l64); return; } static inline isc_result_t additionaldata_l64(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_l64); REQUIRE(rdata->length == 10); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_l64(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_l64); REQUIRE(rdata->length == 10); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_l64(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_l64); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_l64(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_l64); REQUIRE(rdata->length == 10); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_l64(ARGS_COMPARE) { return (compare_l64(rdata1, rdata2)); } #endif /* RDATA_GENERIC_L64_106_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/openpgpkey_61.c0000644000470500017500000001271712664710322022275 0ustar lamontlamont/* * Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef RDATA_GENERIC_OPENPGPKEY_61_C #define RDATA_GENERIC_OPENPGPKEY_61_C #define RRTYPE_OPENPGPKEY_ATTRIBUTES 0 static inline isc_result_t fromtext_openpgpkey(ARGS_FROMTEXT) { REQUIRE(type == dns_rdatatype_openpgpkey); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); UNUSED(options); UNUSED(origin); /* * Keyring. */ return (isc_base64_tobuffer(lexer, target, -1)); } static inline isc_result_t totext_openpgpkey(ARGS_TOTEXT) { isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_openpgpkey); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); /* * Keyring */ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext("( ", target)); if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) { if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(&sr, 60, "", target)); else RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, target)); } else RETERR(str_totext("[omitted]", target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_openpgpkey(ARGS_FROMWIRE) { isc_region_t sr; REQUIRE(type == dns_rdatatype_openpgpkey); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); /* * Keyring. */ isc_buffer_activeregion(source, &sr); if (sr.length < 1) return (ISC_R_UNEXPECTEDEND); isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); } static inline isc_result_t towire_openpgpkey(ARGS_TOWIRE) { isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_openpgpkey); REQUIRE(rdata->length != 0); UNUSED(cctx); dns_rdata_toregion(rdata, &sr); return (mem_tobuffer(target, sr.base, sr.length)); } static inline int compare_openpgpkey(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_openpgpkey); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_openpgpkey(ARGS_FROMSTRUCT) { dns_rdata_openpgpkey_t *sig = source; REQUIRE(type == dns_rdatatype_openpgpkey); REQUIRE(source != NULL); REQUIRE(sig->common.rdtype == type); REQUIRE(sig->common.rdclass == rdclass); REQUIRE(sig->keyring != NULL && sig->length != 0); UNUSED(type); UNUSED(rdclass); /* * Keyring. */ return (mem_tobuffer(target, sig->keyring, sig->length)); } static inline isc_result_t tostruct_openpgpkey(ARGS_TOSTRUCT) { isc_region_t sr; dns_rdata_openpgpkey_t *sig = target; REQUIRE(rdata->type == dns_rdatatype_openpgpkey); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); sig->common.rdclass = rdata->rdclass; sig->common.rdtype = rdata->type; ISC_LINK_INIT(&sig->common, link); dns_rdata_toregion(rdata, &sr); /* * Keyring. */ sig->length = sr.length; sig->keyring = mem_maybedup(mctx, sr.base, sig->length); if (sig->keyring == NULL) goto cleanup; sig->mctx = mctx; return (ISC_R_SUCCESS); cleanup: return (ISC_R_NOMEMORY); } static inline void freestruct_openpgpkey(ARGS_FREESTRUCT) { dns_rdata_openpgpkey_t *sig = (dns_rdata_openpgpkey_t *) source; REQUIRE(source != NULL); REQUIRE(sig->common.rdtype == dns_rdatatype_openpgpkey); if (sig->mctx == NULL) return; if (sig->keyring != NULL) isc_mem_free(sig->mctx, sig->keyring); sig->mctx = NULL; } static inline isc_result_t additionaldata_openpgpkey(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_openpgpkey); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_openpgpkey(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_openpgpkey); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_openpgpkey(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_openpgpkey); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_openpgpkey(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_openpgpkey); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_openpgpkey(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_openpgpkey); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } #endif /* RDATA_GENERIC_OPENPGPKEY_61_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/soa_6.c0000644000470500017500000002570012664710322020611 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2011, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* Reviewed: Thu Mar 16 15:18:32 PST 2000 by explorer */ #ifndef RDATA_GENERIC_SOA_6_C #define RDATA_GENERIC_SOA_6_C #define RRTYPE_SOA_ATTRIBUTES (DNS_RDATATYPEATTR_SINGLETON) static inline isc_result_t fromtext_soa(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; int i; isc_uint32_t n; isc_boolean_t ok; REQUIRE(type == dns_rdatatype_soa); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); origin = (origin != NULL) ? origin : dns_rootname; for (i = 0; i < 2; i++) { RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); ok = ISC_TRUE; if ((options & DNS_RDATA_CHECKNAMES) != 0) switch (i) { case 0: ok = dns_name_ishostname(&name, ISC_FALSE); break; case 1: ok = dns_name_ismailbox(&name); break; } if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) RETTOK(DNS_R_BADNAME); if (!ok && callbacks != NULL) warn_badname(&name, lexer, callbacks); } RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); RETERR(uint32_tobuffer(token.value.as_ulong, target)); for (i = 0; i < 4; i++) { RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_counter_fromtext(&token.value.as_textregion, &n)); RETERR(uint32_tobuffer(n, target)); } return (ISC_R_SUCCESS); } static const char *soa_fieldnames[5] = { "serial", "refresh", "retry", "expire", "minimum" }; static inline isc_result_t totext_soa(ARGS_TOTEXT) { isc_region_t dregion; dns_name_t mname; dns_name_t rname; dns_name_t prefix; isc_boolean_t sub; int i; isc_boolean_t multiline; isc_boolean_t comm; REQUIRE(rdata->type == dns_rdatatype_soa); REQUIRE(rdata->length != 0); multiline = ISC_TF((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0); if (multiline) comm = ISC_TF((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0); else comm = ISC_FALSE; dns_name_init(&mname, NULL); dns_name_init(&rname, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, &dregion); dns_name_fromregion(&mname, &dregion); isc_region_consume(&dregion, name_length(&mname)); dns_name_fromregion(&rname, &dregion); isc_region_consume(&dregion, name_length(&rname)); sub = name_prefix(&mname, tctx->origin, &prefix); RETERR(dns_name_totext(&prefix, sub, target)); RETERR(str_totext(" ", target)); sub = name_prefix(&rname, tctx->origin, &prefix); RETERR(dns_name_totext(&prefix, sub, target)); if (multiline) RETERR(str_totext(" (" , target)); RETERR(str_totext(tctx->linebreak, target)); for (i = 0; i < 5; i++) { char buf[sizeof("0123456789 ; ")]; unsigned long num; num = uint32_fromregion(&dregion); isc_region_consume(&dregion, 4); sprintf(buf, comm ? "%-10lu ; " : "%lu", num); RETERR(str_totext(buf, target)); if (comm) { RETERR(str_totext(soa_fieldnames[i], target)); /* Print times in week/day/hour/minute/second form */ if (i >= 1) { RETERR(str_totext(" (", target)); RETERR(dns_ttl_totext(num, ISC_TRUE, target)); RETERR(str_totext(")", target)); } RETERR(str_totext(tctx->linebreak, target)); } else if (i < 4) { RETERR(str_totext(tctx->linebreak, target)); } } if (multiline) RETERR(str_totext(")", target)); return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_soa(ARGS_FROMWIRE) { dns_name_t mname; dns_name_t rname; isc_region_t sregion; isc_region_t tregion; REQUIRE(type == dns_rdatatype_soa); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&mname, NULL); dns_name_init(&rname, NULL); RETERR(dns_name_fromwire(&mname, source, dctx, options, target)); RETERR(dns_name_fromwire(&rname, source, dctx, options, target)); isc_buffer_activeregion(source, &sregion); isc_buffer_availableregion(target, &tregion); if (sregion.length < 20) return (ISC_R_UNEXPECTEDEND); if (tregion.length < 20) return (ISC_R_NOSPACE); memmove(tregion.base, sregion.base, 20); isc_buffer_forward(source, 20); isc_buffer_add(target, 20); return (ISC_R_SUCCESS); } static inline isc_result_t towire_soa(ARGS_TOWIRE) { isc_region_t sregion; isc_region_t tregion; dns_name_t mname; dns_name_t rname; dns_offsets_t moffsets; dns_offsets_t roffsets; REQUIRE(rdata->type == dns_rdatatype_soa); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&mname, moffsets); dns_name_init(&rname, roffsets); dns_rdata_toregion(rdata, &sregion); dns_name_fromregion(&mname, &sregion); isc_region_consume(&sregion, name_length(&mname)); RETERR(dns_name_towire(&mname, cctx, target)); dns_name_fromregion(&rname, &sregion); isc_region_consume(&sregion, name_length(&rname)); RETERR(dns_name_towire(&rname, cctx, target)); isc_buffer_availableregion(target, &tregion); if (tregion.length < 20) return (ISC_R_NOSPACE); memmove(tregion.base, sregion.base, 20); isc_buffer_add(target, 20); return (ISC_R_SUCCESS); } static inline int compare_soa(ARGS_COMPARE) { isc_region_t region1; isc_region_t region2; dns_name_t name1; dns_name_t name2; int order; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_soa); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); order = dns_name_rdatacompare(&name1, &name2); if (order != 0) return (order); isc_region_consume(®ion1, name_length(&name1)); isc_region_consume(®ion2, name_length(&name2)); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); order = dns_name_rdatacompare(&name1, &name2); if (order != 0) return (order); isc_region_consume(®ion1, name_length(&name1)); isc_region_consume(®ion2, name_length(&name2)); return (isc_region_compare(®ion1, ®ion2)); } static inline isc_result_t fromstruct_soa(ARGS_FROMSTRUCT) { dns_rdata_soa_t *soa = source; isc_region_t region; REQUIRE(type == dns_rdatatype_soa); REQUIRE(source != NULL); REQUIRE(soa->common.rdtype == type); REQUIRE(soa->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); dns_name_toregion(&soa->origin, ®ion); RETERR(isc_buffer_copyregion(target, ®ion)); dns_name_toregion(&soa->contact, ®ion); RETERR(isc_buffer_copyregion(target, ®ion)); RETERR(uint32_tobuffer(soa->serial, target)); RETERR(uint32_tobuffer(soa->refresh, target)); RETERR(uint32_tobuffer(soa->retry, target)); RETERR(uint32_tobuffer(soa->expire, target)); return (uint32_tobuffer(soa->minimum, target)); } static inline isc_result_t tostruct_soa(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_soa_t *soa = target; dns_name_t name; isc_result_t result; REQUIRE(rdata->type == dns_rdatatype_soa); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); soa->common.rdclass = rdata->rdclass; soa->common.rdtype = rdata->type; ISC_LINK_INIT(&soa->common, link); dns_rdata_toregion(rdata, ®ion); dns_name_init(&name, NULL); dns_name_fromregion(&name, ®ion); isc_region_consume(®ion, name_length(&name)); dns_name_init(&soa->origin, NULL); RETERR(name_duporclone(&name, mctx, &soa->origin)); dns_name_fromregion(&name, ®ion); isc_region_consume(®ion, name_length(&name)); dns_name_init(&soa->contact, NULL); result = name_duporclone(&name, mctx, &soa->contact); if (result != ISC_R_SUCCESS) goto cleanup; soa->serial = uint32_fromregion(®ion); isc_region_consume(®ion, 4); soa->refresh = uint32_fromregion(®ion); isc_region_consume(®ion, 4); soa->retry = uint32_fromregion(®ion); isc_region_consume(®ion, 4); soa->expire = uint32_fromregion(®ion); isc_region_consume(®ion, 4); soa->minimum = uint32_fromregion(®ion); soa->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (mctx != NULL) dns_name_free(&soa->origin, mctx); return (ISC_R_NOMEMORY); } static inline void freestruct_soa(ARGS_FREESTRUCT) { dns_rdata_soa_t *soa = source; REQUIRE(source != NULL); REQUIRE(soa->common.rdtype == dns_rdatatype_soa); if (soa->mctx == NULL) return; dns_name_free(&soa->origin, soa->mctx); dns_name_free(&soa->contact, soa->mctx); soa->mctx = NULL; } static inline isc_result_t additionaldata_soa(ARGS_ADDLDATA) { UNUSED(rdata); UNUSED(add); UNUSED(arg); REQUIRE(rdata->type == dns_rdatatype_soa); return (ISC_R_SUCCESS); } static inline isc_result_t digest_soa(ARGS_DIGEST) { isc_region_t r; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_soa); dns_rdata_toregion(rdata, &r); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); RETERR(dns_name_digest(&name, digest, arg)); isc_region_consume(&r, name_length(&name)); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); RETERR(dns_name_digest(&name, digest, arg)); isc_region_consume(&r, name_length(&name)); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_soa(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_soa); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_soa(ARGS_CHECKNAMES) { isc_region_t region; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_soa); UNUSED(owner); dns_rdata_toregion(rdata, ®ion); dns_name_init(&name, NULL); dns_name_fromregion(&name, ®ion); if (!dns_name_ishostname(&name, ISC_FALSE)) { if (bad != NULL) dns_name_clone(&name, bad); return (ISC_FALSE); } isc_region_consume(®ion, name_length(&name)); dns_name_fromregion(&name, ®ion); if (!dns_name_ismailbox(&name)) { if (bad != NULL) dns_name_clone(&name, bad); return (ISC_FALSE); } return (ISC_TRUE); } static inline int casecompare_soa(ARGS_COMPARE) { return (compare_soa(rdata1, rdata2)); } #endif /* RDATA_GENERIC_SOA_6_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/keydata_65533.h0000644000470500017500000000257212664710322022000 0ustar lamontlamont/* * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_KEYDATA_65533_H #define GENERIC_KEYDATA_65533_H 1 /* $Id: keydata_65533.h,v 1.2 2009/06/30 02:52:32 each Exp $ */ typedef struct dns_rdata_keydata { dns_rdatacommon_t common; isc_mem_t * mctx; isc_uint32_t refresh; /* Timer for refreshing data */ isc_uint32_t addhd; /* Hold-down timer for adding */ isc_uint32_t removehd; /* Hold-down timer for removing */ isc_uint16_t flags; /* Copy of DNSKEY_48 */ isc_uint8_t protocol; isc_uint8_t algorithm; isc_uint16_t datalen; unsigned char * data; } dns_rdata_keydata_t; #endif /* GENERIC_KEYDATA_65533_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/opt_41.c0000644000470500017500000002227012664710322020707 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* Reviewed: Thu Mar 16 14:06:44 PST 2000 by gson */ /* RFC2671 */ #ifndef RDATA_GENERIC_OPT_41_C #define RDATA_GENERIC_OPT_41_C #define RRTYPE_OPT_ATTRIBUTES (DNS_RDATATYPEATTR_SINGLETON | \ DNS_RDATATYPEATTR_META | \ DNS_RDATATYPEATTR_NOTQUESTION) static inline isc_result_t fromtext_opt(ARGS_FROMTEXT) { /* * OPT records do not have a text format. */ REQUIRE(type == dns_rdatatype_opt); UNUSED(type); UNUSED(rdclass); UNUSED(lexer); UNUSED(origin); UNUSED(options); UNUSED(target); UNUSED(callbacks); return (ISC_R_NOTIMPLEMENTED); } static inline isc_result_t totext_opt(ARGS_TOTEXT) { isc_region_t r; isc_region_t or; isc_uint16_t option; isc_uint16_t length; char buf[sizeof("64000 64000")]; /* * OPT records do not have a text format. */ REQUIRE(rdata->type == dns_rdatatype_opt); dns_rdata_toregion(rdata, &r); while (r.length > 0) { option = uint16_fromregion(&r); isc_region_consume(&r, 2); length = uint16_fromregion(&r); isc_region_consume(&r, 2); sprintf(buf, "%u %u", option, length); RETERR(str_totext(buf, target)); INSIST(r.length >= length); if (length > 0) { if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); or = r; or.length = length; if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(&or, 60, "", target)); else RETERR(isc_base64_totext(&or, tctx->width - 2, tctx->linebreak, target)); isc_region_consume(&r, length); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); } if (r.length > 0) RETERR(str_totext(" ", target)); } return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_opt(ARGS_FROMWIRE) { isc_region_t sregion; isc_region_t tregion; isc_uint16_t opt; isc_uint16_t length; unsigned int total; REQUIRE(type == dns_rdatatype_opt); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); isc_buffer_activeregion(source, &sregion); total = 0; while (sregion.length != 0) { if (sregion.length < 4) return (ISC_R_UNEXPECTEDEND); opt = uint16_fromregion(&sregion); isc_region_consume(&sregion, 2); length = uint16_fromregion(&sregion); isc_region_consume(&sregion, 2); total += 4; if (sregion.length < length) return (ISC_R_UNEXPECTEDEND); switch (opt) { case DNS_OPT_CLIENT_SUBNET: { isc_uint16_t family; isc_uint8_t addrlen; isc_uint8_t scope; isc_uint8_t addrbytes; if (length < 4) return (DNS_R_OPTERR); family = uint16_fromregion(&sregion); isc_region_consume(&sregion, 2); addrlen = uint8_fromregion(&sregion); isc_region_consume(&sregion, 1); scope = uint8_fromregion(&sregion); isc_region_consume(&sregion, 1); switch (family) { case 1: if (addrlen > 32U || scope > 32U) return (DNS_R_OPTERR); break; case 2: if (addrlen > 128U || scope > 128U) return (DNS_R_OPTERR); break; } addrbytes = (addrlen + 7) / 8; if (addrbytes + 4 != length) return (DNS_R_OPTERR); if (addrbytes != 0U && (addrlen % 8) != 0) { isc_uint8_t bits = ~0 << (8 - (addrlen % 8)); bits &= sregion.base[addrbytes - 1]; if (bits != sregion.base[addrbytes - 1]) return (DNS_R_OPTERR); } isc_region_consume(&sregion, addrbytes); break; } case DNS_OPT_EXPIRE: /* * Request has zero length. Response is 32 bits. */ if (length != 0 && length != 4) return (DNS_R_OPTERR); isc_region_consume(&sregion, length); break; default: isc_region_consume(&sregion, length); break; } total += length; } isc_buffer_activeregion(source, &sregion); isc_buffer_availableregion(target, &tregion); if (tregion.length < total) return (ISC_R_NOSPACE); memmove(tregion.base, sregion.base, total); isc_buffer_forward(source, total); isc_buffer_add(target, total); return (ISC_R_SUCCESS); } static inline isc_result_t towire_opt(ARGS_TOWIRE) { REQUIRE(rdata->type == dns_rdatatype_opt); UNUSED(cctx); return (mem_tobuffer(target, rdata->data, rdata->length)); } static inline int compare_opt(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_opt); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_opt(ARGS_FROMSTRUCT) { dns_rdata_opt_t *opt = source; isc_region_t region; isc_uint16_t length; REQUIRE(type == dns_rdatatype_opt); REQUIRE(source != NULL); REQUIRE(opt->common.rdtype == type); REQUIRE(opt->common.rdclass == rdclass); REQUIRE(opt->options != NULL || opt->length == 0); UNUSED(type); UNUSED(rdclass); region.base = opt->options; region.length = opt->length; while (region.length >= 4) { isc_region_consume(®ion, 2); /* opt */ length = uint16_fromregion(®ion); isc_region_consume(®ion, 2); if (region.length < length) return (ISC_R_UNEXPECTEDEND); isc_region_consume(®ion, length); } if (region.length != 0) return (ISC_R_UNEXPECTEDEND); return (mem_tobuffer(target, opt->options, opt->length)); } static inline isc_result_t tostruct_opt(ARGS_TOSTRUCT) { dns_rdata_opt_t *opt = target; isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_opt); REQUIRE(target != NULL); opt->common.rdclass = rdata->rdclass; opt->common.rdtype = rdata->type; ISC_LINK_INIT(&opt->common, link); dns_rdata_toregion(rdata, &r); opt->length = r.length; opt->options = mem_maybedup(mctx, r.base, r.length); if (opt->options == NULL) return (ISC_R_NOMEMORY); opt->offset = 0; opt->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_opt(ARGS_FREESTRUCT) { dns_rdata_opt_t *opt = source; REQUIRE(source != NULL); REQUIRE(opt->common.rdtype == dns_rdatatype_opt); if (opt->mctx == NULL) return; if (opt->options != NULL) isc_mem_free(opt->mctx, opt->options); opt->mctx = NULL; } static inline isc_result_t additionaldata_opt(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_opt); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_opt(ARGS_DIGEST) { /* * OPT records are not digested. */ REQUIRE(rdata->type == dns_rdatatype_opt); UNUSED(rdata); UNUSED(digest); UNUSED(arg); return (ISC_R_NOTIMPLEMENTED); } static inline isc_boolean_t checkowner_opt(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_opt); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (dns_name_equal(name, dns_rootname)); } static inline isc_boolean_t checknames_opt(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_opt); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_opt(ARGS_COMPARE) { return (compare_opt(rdata1, rdata2)); } isc_result_t dns_rdata_opt_first(dns_rdata_opt_t *opt) { REQUIRE(opt != NULL); REQUIRE(opt->common.rdtype == dns_rdatatype_opt); REQUIRE(opt->options != NULL || opt->length == 0); if (opt->length == 0) return (ISC_R_NOMORE); opt->offset = 0; return (ISC_R_SUCCESS); } isc_result_t dns_rdata_opt_next(dns_rdata_opt_t *opt) { isc_region_t r; isc_uint16_t length; REQUIRE(opt != NULL); REQUIRE(opt->common.rdtype == dns_rdatatype_opt); REQUIRE(opt->options != NULL && opt->length != 0); REQUIRE(opt->offset < opt->length); INSIST(opt->offset + 4 <= opt->length); r.base = opt->options + opt->offset + 2; r.length = opt->length - opt->offset - 2; length = uint16_fromregion(&r); INSIST(opt->offset + 4 + length <= opt->length); opt->offset = opt->offset + 4 + length; if (opt->offset == opt->length) return (ISC_R_NOMORE); return (ISC_R_SUCCESS); } isc_result_t dns_rdata_opt_current(dns_rdata_opt_t *opt, dns_rdata_opt_opcode_t *opcode) { isc_region_t r; REQUIRE(opt != NULL); REQUIRE(opcode != NULL); REQUIRE(opt->common.rdtype == dns_rdatatype_opt); REQUIRE(opt->options != NULL); REQUIRE(opt->offset < opt->length); INSIST(opt->offset + 4 <= opt->length); r.base = opt->options + opt->offset; r.length = opt->length - opt->offset; opcode->opcode = uint16_fromregion(&r); isc_region_consume(&r, 2); opcode->length = uint16_fromregion(&r); isc_region_consume(&r, 2); opcode->data = r.base; INSIST(opt->offset + 4 + opcode->length <= opt->length); return (ISC_R_SUCCESS); } #endif /* RDATA_GENERIC_OPT_41_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/mb_7.h0000644000470500017500000000213212664710322020425 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef GENERIC_MB_7_H #define GENERIC_MB_7_H 1 /* $Id: mb_7.h,v 1.27 2007/06/19 23:47:17 tbox Exp $ */ typedef struct dns_rdata_mb { dns_rdatacommon_t common; isc_mem_t *mctx; dns_name_t mb; } dns_rdata_mb_t; #endif /* GENERIC_MB_7_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/proforma.h0000644000470500017500000000221712664710322021432 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef GENERIC_PROFORMA_H #define GENERIC_PROFORMA_H 1 /* $Id: proforma.h,v 1.23 2007/06/19 23:47:17 tbox Exp $ */ typedef struct dns_rdata_# { dns_rdatacommon_t common; isc_mem_t *mctx; /* if required */ /* type & class specific elements */ } dns_rdata_#_t; #endif /* GENERIC_PROFORMA_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/minfo_14.c0000644000470500017500000002003112664710322021206 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: minfo_14.c,v 1.47 2009/12/04 22:06:37 tbox Exp $ */ /* reviewed: Wed Mar 15 17:45:32 PST 2000 by brister */ #ifndef RDATA_GENERIC_MINFO_14_C #define RDATA_GENERIC_MINFO_14_C #define RRTYPE_MINFO_ATTRIBUTES (0) static inline isc_result_t fromtext_minfo(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; int i; isc_boolean_t ok; REQUIRE(type == dns_rdatatype_minfo); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); for (i = 0; i < 2; i++) { RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); ok = ISC_TRUE; if ((options & DNS_RDATA_CHECKNAMES) != 0) ok = dns_name_ismailbox(&name); if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) RETTOK(DNS_R_BADNAME); if (!ok && callbacks != NULL) warn_badname(&name, lexer, callbacks); } return (ISC_R_SUCCESS); } static inline isc_result_t totext_minfo(ARGS_TOTEXT) { isc_region_t region; dns_name_t rmail; dns_name_t email; dns_name_t prefix; isc_boolean_t sub; REQUIRE(rdata->type == dns_rdatatype_minfo); REQUIRE(rdata->length != 0); dns_name_init(&rmail, NULL); dns_name_init(&email, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&rmail, ®ion); isc_region_consume(®ion, rmail.length); dns_name_fromregion(&email, ®ion); isc_region_consume(®ion, email.length); sub = name_prefix(&rmail, tctx->origin, &prefix); RETERR(dns_name_totext(&prefix, sub, target)); RETERR(str_totext(" ", target)); sub = name_prefix(&email, tctx->origin, &prefix); return (dns_name_totext(&prefix, sub, target)); } static inline isc_result_t fromwire_minfo(ARGS_FROMWIRE) { dns_name_t rmail; dns_name_t email; REQUIRE(type == dns_rdatatype_minfo); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&rmail, NULL); dns_name_init(&email, NULL); RETERR(dns_name_fromwire(&rmail, source, dctx, options, target)); return (dns_name_fromwire(&email, source, dctx, options, target)); } static inline isc_result_t towire_minfo(ARGS_TOWIRE) { isc_region_t region; dns_name_t rmail; dns_name_t email; dns_offsets_t roffsets; dns_offsets_t eoffsets; REQUIRE(rdata->type == dns_rdatatype_minfo); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&rmail, roffsets); dns_name_init(&email, eoffsets); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&rmail, ®ion); isc_region_consume(®ion, name_length(&rmail)); RETERR(dns_name_towire(&rmail, cctx, target)); dns_name_fromregion(&rmail, ®ion); isc_region_consume(®ion, rmail.length); return (dns_name_towire(&rmail, cctx, target)); } static inline int compare_minfo(ARGS_COMPARE) { isc_region_t region1; isc_region_t region2; dns_name_t name1; dns_name_t name2; int order; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_minfo); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); order = dns_name_rdatacompare(&name1, &name2); if (order != 0) return (order); isc_region_consume(®ion1, name_length(&name1)); isc_region_consume(®ion2, name_length(&name2)); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); order = dns_name_rdatacompare(&name1, &name2); return (order); } static inline isc_result_t fromstruct_minfo(ARGS_FROMSTRUCT) { dns_rdata_minfo_t *minfo = source; isc_region_t region; REQUIRE(type == dns_rdatatype_minfo); REQUIRE(source != NULL); REQUIRE(minfo->common.rdtype == type); REQUIRE(minfo->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); dns_name_toregion(&minfo->rmailbox, ®ion); RETERR(isc_buffer_copyregion(target, ®ion)); dns_name_toregion(&minfo->emailbox, ®ion); return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_minfo(ARGS_TOSTRUCT) { dns_rdata_minfo_t *minfo = target; isc_region_t region; dns_name_t name; isc_result_t result; REQUIRE(rdata->type == dns_rdatatype_minfo); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); minfo->common.rdclass = rdata->rdclass; minfo->common.rdtype = rdata->type; ISC_LINK_INIT(&minfo->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); dns_name_init(&minfo->rmailbox, NULL); RETERR(name_duporclone(&name, mctx, &minfo->rmailbox)); isc_region_consume(®ion, name_length(&name)); dns_name_fromregion(&name, ®ion); dns_name_init(&minfo->emailbox, NULL); result = name_duporclone(&name, mctx, &minfo->emailbox); if (result != ISC_R_SUCCESS) goto cleanup; minfo->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (mctx != NULL) dns_name_free(&minfo->rmailbox, mctx); return (ISC_R_NOMEMORY); } static inline void freestruct_minfo(ARGS_FREESTRUCT) { dns_rdata_minfo_t *minfo = source; REQUIRE(source != NULL); REQUIRE(minfo->common.rdtype == dns_rdatatype_minfo); if (minfo->mctx == NULL) return; dns_name_free(&minfo->rmailbox, minfo->mctx); dns_name_free(&minfo->emailbox, minfo->mctx); minfo->mctx = NULL; } static inline isc_result_t additionaldata_minfo(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_minfo); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_minfo(ARGS_DIGEST) { isc_region_t r; dns_name_t name; isc_result_t result; REQUIRE(rdata->type == dns_rdatatype_minfo); dns_rdata_toregion(rdata, &r); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); result = dns_name_digest(&name, digest, arg); if (result != ISC_R_SUCCESS) return (result); isc_region_consume(&r, name_length(&name)); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); return (dns_name_digest(&name, digest, arg)); } static inline isc_boolean_t checkowner_minfo(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_minfo); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_minfo(ARGS_CHECKNAMES) { isc_region_t region; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_minfo); UNUSED(owner); dns_rdata_toregion(rdata, ®ion); dns_name_init(&name, NULL); dns_name_fromregion(&name, ®ion); if (!dns_name_ismailbox(&name)) { if (bad != NULL) dns_name_clone(&name, bad); return (ISC_FALSE); } isc_region_consume(®ion, name_length(&name)); dns_name_fromregion(&name, ®ion); if (!dns_name_ismailbox(&name)) { if (bad != NULL) dns_name_clone(&name, bad); return (ISC_FALSE); } return (ISC_TRUE); } static inline int casecompare_minfo(ARGS_COMPARE) { return (compare_minfo(rdata1, rdata2)); } #endif /* RDATA_GENERIC_MINFO_14_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/unspec_103.h0000644000470500017500000000223212664710322021462 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef GENERIC_UNSPEC_103_H #define GENERIC_UNSPEC_103_H 1 /* $Id: unspec_103.h,v 1.17 2007/06/19 23:47:17 tbox Exp $ */ typedef struct dns_rdata_unspec_t { dns_rdatacommon_t common; isc_mem_t *mctx; unsigned char *data; isc_uint16_t datalen; } dns_rdata_unspec_t; #endif /* GENERIC_UNSPEC_103_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/nid_104.h0000644000470500017500000000175712664710322020753 0ustar lamontlamont/* * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef GENERIC_NID_104_H #define GENERIC_NID_104_H 1 typedef struct dns_rdata_nid { dns_rdatacommon_t common; isc_uint16_t pref; unsigned char nid[8]; } dns_rdata_nid_t; #endif /* GENERIC_NID_104_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/naptr_35.h0000644000470500017500000000243712664710322021244 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_NAPTR_35_H #define GENERIC_NAPTR_35_H 1 /* $Id$ */ /*! * \brief Per RFC2915 */ typedef struct dns_rdata_naptr { dns_rdatacommon_t common; isc_mem_t *mctx; isc_uint16_t order; isc_uint16_t preference; char *flags; isc_uint8_t flags_len; char *service; isc_uint8_t service_len; char *regexp; isc_uint8_t regexp_len; dns_name_t replacement; } dns_rdata_naptr_t; #endif /* GENERIC_NAPTR_35_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/cname_5.h0000644000470500017500000000214312664710322021112 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: cname_5.h,v 1.26 2007/06/19 23:47:17 tbox Exp $ */ #ifndef GENERIC_CNAME_5_H #define GENERIC_CNAME_5_H 1 typedef struct dns_rdata_cname { dns_rdatacommon_t common; isc_mem_t *mctx; dns_name_t cname; } dns_rdata_cname_t; #endif /* GENERIC_CNAME_5_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/eui48_108.h0000644000470500017500000000174612664710322021141 0ustar lamontlamont/* * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef GENERIC_EUI48_108_H #define GENERIC_EUI48_108_H 1 typedef struct dns_rdata_eui48 { dns_rdatacommon_t common; unsigned char eui48[6]; } dns_rdata_eui48_t; #endif /* GENERIC_EUI48_10k_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/sshfp_44.h0000644000470500017500000000232012664710322021232 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: sshfp_44.h,v 1.8 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief Per RFC 4255 */ #ifndef GENERIC_SSHFP_44_H #define GENERIC_SSHFP_44_H 1 typedef struct dns_rdata_sshfp { dns_rdatacommon_t common; isc_mem_t *mctx; isc_uint8_t algorithm; isc_uint8_t digest_type; isc_uint16_t length; unsigned char *digest; } dns_rdata_sshfp_t; #endif /* GENERIC_SSHFP_44_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/md_3.h0000644000470500017500000000213312664710322020424 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef GENERIC_MD_3_H #define GENERIC_MD_3_H 1 /* $Id: md_3.h,v 1.28 2007/06/19 23:47:17 tbox Exp $ */ typedef struct dns_rdata_md { dns_rdatacommon_t common; isc_mem_t *mctx; dns_name_t md; } dns_rdata_md_t; #endif /* GENERIC_MD_3_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/txt_16.h0000644000470500017500000000330112664710322020725 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef GENERIC_TXT_16_H #define GENERIC_TXT_16_H 1 /* $Id: txt_16.h,v 1.28 2007/06/19 23:47:17 tbox Exp $ */ typedef struct dns_rdata_txt_string { isc_uint8_t length; unsigned char *data; } dns_rdata_txt_string_t; typedef struct dns_rdata_txt { dns_rdatacommon_t common; isc_mem_t *mctx; unsigned char *txt; isc_uint16_t txt_len; /* private */ isc_uint16_t offset; } dns_rdata_txt_t; /* * ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS are already done * via rdatastructpre.h and rdatastructsuf.h. */ isc_result_t dns_rdata_txt_first(dns_rdata_txt_t *); isc_result_t dns_rdata_txt_next(dns_rdata_txt_t *); isc_result_t dns_rdata_txt_current(dns_rdata_txt_t *, dns_rdata_txt_string_t *); #endif /* GENERIC_TXT_16_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/x25_19.c0000644000470500017500000001206612664710322020532 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: x25_19.c,v 1.41 2009/12/04 22:06:37 tbox Exp $ */ /* Reviewed: Thu Mar 16 16:15:57 PST 2000 by bwelling */ /* RFC1183 */ #ifndef RDATA_GENERIC_X25_19_C #define RDATA_GENERIC_X25_19_C #define RRTYPE_X25_ATTRIBUTES (0) static inline isc_result_t fromtext_x25(ARGS_FROMTEXT) { isc_token_t token; unsigned int i; REQUIRE(type == dns_rdatatype_x25); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, ISC_FALSE)); if (token.value.as_textregion.length < 4) RETTOK(DNS_R_SYNTAX); for (i = 0; i < token.value.as_textregion.length; i++) if (!isdigit(token.value.as_textregion.base[i] & 0xff)) RETTOK(ISC_R_RANGE); RETTOK(txt_fromtext(&token.value.as_textregion, target)); return (ISC_R_SUCCESS); } static inline isc_result_t totext_x25(ARGS_TOTEXT) { isc_region_t region; UNUSED(tctx); REQUIRE(rdata->type == dns_rdatatype_x25); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, ®ion); return (txt_totext(®ion, ISC_TRUE, target)); } static inline isc_result_t fromwire_x25(ARGS_FROMWIRE) { isc_region_t sr; REQUIRE(type == dns_rdatatype_x25); UNUSED(type); UNUSED(dctx); UNUSED(rdclass); UNUSED(options); isc_buffer_activeregion(source, &sr); if (sr.length < 5) return (DNS_R_FORMERR); return (txt_fromwire(source, target)); } static inline isc_result_t towire_x25(ARGS_TOWIRE) { UNUSED(cctx); REQUIRE(rdata->type == dns_rdatatype_x25); REQUIRE(rdata->length != 0); return (mem_tobuffer(target, rdata->data, rdata->length)); } static inline int compare_x25(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_x25); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_x25(ARGS_FROMSTRUCT) { dns_rdata_x25_t *x25 = source; isc_uint8_t i; REQUIRE(type == dns_rdatatype_x25); REQUIRE(source != NULL); REQUIRE(x25->common.rdtype == type); REQUIRE(x25->common.rdclass == rdclass); REQUIRE(x25->x25 != NULL && x25->x25_len != 0); UNUSED(type); UNUSED(rdclass); if (x25->x25_len < 4) return (ISC_R_RANGE); for (i = 0; i < x25->x25_len; i++) if (!isdigit(x25->x25[i] & 0xff)) return (ISC_R_RANGE); RETERR(uint8_tobuffer(x25->x25_len, target)); return (mem_tobuffer(target, x25->x25, x25->x25_len)); } static inline isc_result_t tostruct_x25(ARGS_TOSTRUCT) { dns_rdata_x25_t *x25 = target; isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_x25); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); x25->common.rdclass = rdata->rdclass; x25->common.rdtype = rdata->type; ISC_LINK_INIT(&x25->common, link); dns_rdata_toregion(rdata, &r); x25->x25_len = uint8_fromregion(&r); isc_region_consume(&r, 1); x25->x25 = mem_maybedup(mctx, r.base, x25->x25_len); if (x25->x25 == NULL) return (ISC_R_NOMEMORY); x25->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_x25(ARGS_FREESTRUCT) { dns_rdata_x25_t *x25 = source; REQUIRE(source != NULL); REQUIRE(x25->common.rdtype == dns_rdatatype_x25); if (x25->mctx == NULL) return; if (x25->x25 != NULL) isc_mem_free(x25->mctx, x25->x25); x25->mctx = NULL; } static inline isc_result_t additionaldata_x25(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_x25); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_x25(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_x25); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_x25(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_x25); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_x25(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_x25); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_x25(ARGS_COMPARE) { return (compare_x25(rdata1, rdata2)); } #endif /* RDATA_GENERIC_X25_19_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/ipseckey_45.c0000644000470500017500000002701112664710322021723 0ustar lamontlamont/* * Copyright (C) 2005, 2007, 2009, 2011, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef RDATA_GENERIC_IPSECKEY_45_C #define RDATA_GENERIC_IPSECKEY_45_C #include #include #define RRTYPE_IPSECKEY_ATTRIBUTES (0) static inline isc_result_t fromtext_ipseckey(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; unsigned int gateway; struct in_addr addr; unsigned char addr6[16]; isc_region_t region; REQUIRE(type == dns_rdatatype_ipseckey); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); /* * Precedence. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffU) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer(token.value.as_ulong, target)); /* * Gateway type. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0x3U) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer(token.value.as_ulong, target)); gateway = token.value.as_ulong; /* * Algorithm. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffU) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer(token.value.as_ulong, target)); /* * Gateway. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); switch (gateway) { case 0: if (strcmp(DNS_AS_STR(token), ".") != 0) RETTOK(DNS_R_SYNTAX); break; case 1: if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1) RETTOK(DNS_R_BADDOTTEDQUAD); isc_buffer_availableregion(target, ®ion); if (region.length < 4) return (ISC_R_NOSPACE); memmove(region.base, &addr, 4); isc_buffer_add(target, 4); break; case 2: if (inet_pton(AF_INET6, DNS_AS_STR(token), addr6) != 1) RETTOK(DNS_R_BADAAAA); isc_buffer_availableregion(target, ®ion); if (region.length < 16) return (ISC_R_NOSPACE); memmove(region.base, addr6, 16); isc_buffer_add(target, 16); break; case 3: dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); break; } /* * Public key. */ return (isc_base64_tobuffer(lexer, target, -1)); } static inline isc_result_t totext_ipseckey(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; char buf[sizeof("255 ")]; unsigned short num; unsigned short gateway; REQUIRE(rdata->type == dns_rdatatype_ipseckey); REQUIRE(rdata->length >= 3); dns_name_init(&name, NULL); if (rdata->data[1] > 3U) return (ISC_R_NOTIMPLEMENTED); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext("( ", target)); /* * Precedence. */ dns_rdata_toregion(rdata, ®ion); num = uint8_fromregion(®ion); isc_region_consume(®ion, 1); sprintf(buf, "%u ", num); RETERR(str_totext(buf, target)); /* * Gateway type. */ gateway = uint8_fromregion(®ion); isc_region_consume(®ion, 1); sprintf(buf, "%u ", gateway); RETERR(str_totext(buf, target)); /* * Algorithm. */ num = uint8_fromregion(®ion); isc_region_consume(®ion, 1); sprintf(buf, "%u ", num); RETERR(str_totext(buf, target)); /* * Gateway. */ switch (gateway) { case 0: RETERR(str_totext(".", target)); break; case 1: RETERR(inet_totext(AF_INET, ®ion, target)); isc_region_consume(®ion, 4); break; case 2: RETERR(inet_totext(AF_INET6, ®ion, target)); isc_region_consume(®ion, 16); break; case 3: dns_name_fromregion(&name, ®ion); RETERR(dns_name_totext(&name, ISC_FALSE, target)); isc_region_consume(®ion, name_length(&name)); break; } /* * Key. */ if (region.length > 0U) { RETERR(str_totext(tctx->linebreak, target)); if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(®ion, 60, "", target)); else RETERR(isc_base64_totext(®ion, tctx->width - 2, tctx->linebreak, target)); } if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_ipseckey(ARGS_FROMWIRE) { dns_name_t name; isc_region_t region; REQUIRE(type == dns_rdatatype_ipseckey); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); dns_name_init(&name, NULL); isc_buffer_activeregion(source, ®ion); if (region.length < 3) return (ISC_R_UNEXPECTEDEND); switch (region.base[1]) { case 0: isc_buffer_forward(source, region.length); return (mem_tobuffer(target, region.base, region.length)); case 1: if (region.length < 7) return (ISC_R_UNEXPECTEDEND); isc_buffer_forward(source, region.length); return (mem_tobuffer(target, region.base, region.length)); case 2: if (region.length < 19) return (ISC_R_UNEXPECTEDEND); isc_buffer_forward(source, region.length); return (mem_tobuffer(target, region.base, region.length)); case 3: RETERR(mem_tobuffer(target, region.base, 3)); isc_buffer_forward(source, 3); RETERR(dns_name_fromwire(&name, source, dctx, options, target)); isc_buffer_activeregion(source, ®ion); isc_buffer_forward(source, region.length); return(mem_tobuffer(target, region.base, region.length)); default: return (ISC_R_NOTIMPLEMENTED); } } static inline isc_result_t towire_ipseckey(ARGS_TOWIRE) { isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_ipseckey); REQUIRE(rdata->length != 0); UNUSED(cctx); dns_rdata_toregion(rdata, ®ion); return (mem_tobuffer(target, region.base, region.length)); } static inline int compare_ipseckey(ARGS_COMPARE) { isc_region_t region1; isc_region_t region2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_ipseckey); REQUIRE(rdata1->length >= 3); REQUIRE(rdata2->length >= 3); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); return (isc_region_compare(®ion1, ®ion2)); } static inline isc_result_t fromstruct_ipseckey(ARGS_FROMSTRUCT) { dns_rdata_ipseckey_t *ipseckey = source; isc_region_t region; isc_uint32_t n; REQUIRE(type == dns_rdatatype_ipseckey); REQUIRE(source != NULL); REQUIRE(ipseckey->common.rdtype == type); REQUIRE(ipseckey->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); if (ipseckey->gateway_type > 3U) return (ISC_R_NOTIMPLEMENTED); RETERR(uint8_tobuffer(ipseckey->precedence, target)); RETERR(uint8_tobuffer(ipseckey->gateway_type, target)); RETERR(uint8_tobuffer(ipseckey->algorithm, target)); switch (ipseckey->gateway_type) { case 0: break; case 1: n = ntohl(ipseckey->in_addr.s_addr); RETERR(uint32_tobuffer(n, target)); break; case 2: RETERR(mem_tobuffer(target, ipseckey->in6_addr.s6_addr, 16)); break; case 3: dns_name_toregion(&ipseckey->gateway, ®ion); RETERR(isc_buffer_copyregion(target, ®ion)); break; } return (mem_tobuffer(target, ipseckey->key, ipseckey->keylength)); } static inline isc_result_t tostruct_ipseckey(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_ipseckey_t *ipseckey = target; dns_name_t name; isc_uint32_t n; REQUIRE(rdata->type == dns_rdatatype_ipseckey); REQUIRE(target != NULL); REQUIRE(rdata->length >= 3); if (rdata->data[1] > 3U) return (ISC_R_NOTIMPLEMENTED); ipseckey->common.rdclass = rdata->rdclass; ipseckey->common.rdtype = rdata->type; ISC_LINK_INIT(&ipseckey->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); ipseckey->precedence = uint8_fromregion(®ion); isc_region_consume(®ion, 1); ipseckey->gateway_type = uint8_fromregion(®ion); isc_region_consume(®ion, 1); ipseckey->algorithm = uint8_fromregion(®ion); isc_region_consume(®ion, 1); switch (ipseckey->gateway_type) { case 0: break; case 1: n = uint32_fromregion(®ion); ipseckey->in_addr.s_addr = htonl(n); isc_region_consume(®ion, 4); break; case 2: memmove(ipseckey->in6_addr.s6_addr, region.base, 16); isc_region_consume(®ion, 16); break; case 3: dns_name_init(&ipseckey->gateway, NULL); dns_name_fromregion(&name, ®ion); RETERR(name_duporclone(&name, mctx, &ipseckey->gateway)); isc_region_consume(®ion, name_length(&name)); break; } ipseckey->keylength = region.length; if (ipseckey->keylength != 0U) { ipseckey->key = mem_maybedup(mctx, region.base, ipseckey->keylength); if (ipseckey->key == NULL) { if (ipseckey->gateway_type == 3) dns_name_free(&ipseckey->gateway, ipseckey->mctx); return (ISC_R_NOMEMORY); } } else ipseckey->key = NULL; ipseckey->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_ipseckey(ARGS_FREESTRUCT) { dns_rdata_ipseckey_t *ipseckey = source; REQUIRE(source != NULL); REQUIRE(ipseckey->common.rdtype == dns_rdatatype_ipseckey); if (ipseckey->mctx == NULL) return; if (ipseckey->gateway_type == 3) dns_name_free(&ipseckey->gateway, ipseckey->mctx); if (ipseckey->key != NULL) isc_mem_free(ipseckey->mctx, ipseckey->key); ipseckey->mctx = NULL; } static inline isc_result_t additionaldata_ipseckey(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_ipseckey); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_ipseckey(ARGS_DIGEST) { isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_ipseckey); dns_rdata_toregion(rdata, ®ion); return ((digest)(arg, ®ion)); } static inline isc_boolean_t checkowner_ipseckey(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_ipseckey); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_ipseckey(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_ipseckey); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_ipseckey(ARGS_COMPARE) { isc_region_t region1; isc_region_t region2; dns_name_t name1; dns_name_t name2; int order; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_ipseckey); REQUIRE(rdata1->length >= 3); REQUIRE(rdata2->length >= 3); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); if (memcmp(region1.base, region2.base, 3) != 0 || region1.base[1] != 3) return (isc_region_compare(®ion1, ®ion2)); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); isc_region_consume(®ion1, 3); isc_region_consume(®ion2, 3); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); order = dns_name_rdatacompare(&name1, &name2); if (order != 0) return (order); isc_region_consume(®ion1, name_length(&name1)); isc_region_consume(®ion2, name_length(&name2)); return (isc_region_compare(®ion1, ®ion2)); } #endif /* RDATA_GENERIC_IPSECKEY_45_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/unspec_103.c0000644000470500017500000001053312664710322021460 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: unspec_103.c,v 1.37 2009/12/04 22:06:37 tbox Exp $ */ #ifndef RDATA_GENERIC_UNSPEC_103_C #define RDATA_GENERIC_UNSPEC_103_C #define RRTYPE_UNSPEC_ATTRIBUTES (0) static inline isc_result_t fromtext_unspec(ARGS_FROMTEXT) { REQUIRE(type == dns_rdatatype_unspec); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); return (atob_tobuffer(lexer, target)); } static inline isc_result_t totext_unspec(ARGS_TOTEXT) { REQUIRE(rdata->type == dns_rdatatype_unspec); UNUSED(tctx); return (btoa_totext(rdata->data, rdata->length, target)); } static inline isc_result_t fromwire_unspec(ARGS_FROMWIRE) { isc_region_t sr; REQUIRE(type == dns_rdatatype_unspec); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); isc_buffer_activeregion(source, &sr); isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); } static inline isc_result_t towire_unspec(ARGS_TOWIRE) { REQUIRE(rdata->type == dns_rdatatype_unspec); UNUSED(cctx); return (mem_tobuffer(target, rdata->data, rdata->length)); } static inline int compare_unspec(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_unspec); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_unspec(ARGS_FROMSTRUCT) { dns_rdata_unspec_t *unspec = source; REQUIRE(type == dns_rdatatype_unspec); REQUIRE(source != NULL); REQUIRE(unspec->common.rdtype == type); REQUIRE(unspec->common.rdclass == rdclass); REQUIRE(unspec->data != NULL || unspec->datalen == 0); UNUSED(type); UNUSED(rdclass); return (mem_tobuffer(target, unspec->data, unspec->datalen)); } static inline isc_result_t tostruct_unspec(ARGS_TOSTRUCT) { dns_rdata_unspec_t *unspec = target; isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_unspec); REQUIRE(target != NULL); unspec->common.rdclass = rdata->rdclass; unspec->common.rdtype = rdata->type; ISC_LINK_INIT(&unspec->common, link); dns_rdata_toregion(rdata, &r); unspec->datalen = r.length; unspec->data = mem_maybedup(mctx, r.base, r.length); if (unspec->data == NULL) return (ISC_R_NOMEMORY); unspec->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_unspec(ARGS_FREESTRUCT) { dns_rdata_unspec_t *unspec = source; REQUIRE(source != NULL); REQUIRE(unspec->common.rdtype == dns_rdatatype_unspec); if (unspec->mctx == NULL) return; if (unspec->data != NULL) isc_mem_free(unspec->mctx, unspec->data); unspec->mctx = NULL; } static inline isc_result_t additionaldata_unspec(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_unspec); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_unspec(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_unspec); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_unspec(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_unspec); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_unspec(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_unspec); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_unspec(ARGS_COMPARE) { return (compare_unspec(rdata1, rdata2)); } #endif /* RDATA_GENERIC_UNSPEC_103_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/mf_4.c0000644000470500017500000001277512664710322020437 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: mf_4.c,v 1.47 2009/12/04 22:06:37 tbox Exp $ */ /* reviewed: Wed Mar 15 17:47:33 PST 2000 by brister */ #ifndef RDATA_GENERIC_MF_4_C #define RDATA_GENERIC_MF_4_C #define RRTYPE_MF_ATTRIBUTES (0) static inline isc_result_t fromtext_mf(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; REQUIRE(type == dns_rdatatype_mf); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); return (ISC_R_SUCCESS); } static inline isc_result_t totext_mf(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; REQUIRE(rdata->type == dns_rdatatype_mf); REQUIRE(rdata->length != 0); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); sub = name_prefix(&name, tctx->origin, &prefix); return (dns_name_totext(&prefix, sub, target)); } static inline isc_result_t fromwire_mf(ARGS_FROMWIRE) { dns_name_t name; REQUIRE(type == dns_rdatatype_mf); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, NULL); return (dns_name_fromwire(&name, source, dctx, options, target)); } static inline isc_result_t towire_mf(ARGS_TOWIRE) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_mf); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); return (dns_name_towire(&name, cctx, target)); } static inline int compare_mf(ARGS_COMPARE) { dns_name_t name1; dns_name_t name2; isc_region_t region1; isc_region_t region2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_mf); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); return (dns_name_rdatacompare(&name1, &name2)); } static inline isc_result_t fromstruct_mf(ARGS_FROMSTRUCT) { dns_rdata_mf_t *mf = source; isc_region_t region; REQUIRE(type == dns_rdatatype_mf); REQUIRE(source != NULL); REQUIRE(mf->common.rdtype == type); REQUIRE(mf->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); dns_name_toregion(&mf->mf, ®ion); return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_mf(ARGS_TOSTRUCT) { dns_rdata_mf_t *mf = target; isc_region_t r; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_mf); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); mf->common.rdclass = rdata->rdclass; mf->common.rdtype = rdata->type; ISC_LINK_INIT(&mf->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, &r); dns_name_fromregion(&name, &r); dns_name_init(&mf->mf, NULL); RETERR(name_duporclone(&name, mctx, &mf->mf)); mf->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_mf(ARGS_FREESTRUCT) { dns_rdata_mf_t *mf = source; REQUIRE(source != NULL); REQUIRE(mf->common.rdtype == dns_rdatatype_mf); if (mf->mctx == NULL) return; dns_name_free(&mf->mf, mf->mctx); mf->mctx = NULL; } static inline isc_result_t additionaldata_mf(ARGS_ADDLDATA) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_mf); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); return ((add)(arg, &name, dns_rdatatype_a)); } static inline isc_result_t digest_mf(ARGS_DIGEST) { isc_region_t r; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_mf); dns_rdata_toregion(rdata, &r); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); return (dns_name_digest(&name, digest, arg)); } static inline isc_boolean_t checkowner_mf(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_mf); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_mf(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_mf); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_mf(ARGS_COMPARE) { return (compare_mf(rdata1, rdata2)); } #endif /* RDATA_GENERIC_MF_4_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/null_10.h0000644000470500017500000000221012664710322021050 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef GENERIC_NULL_10_H #define GENERIC_NULL_10_H 1 /* $Id: null_10.h,v 1.25 2007/06/19 23:47:17 tbox Exp $ */ typedef struct dns_rdata_null { dns_rdatacommon_t common; isc_mem_t *mctx; isc_uint16_t length; unsigned char *data; } dns_rdata_null_t; #endif /* GENERIC_NULL_10_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/lp_107.h0000644000470500017500000000176612664710322020617 0ustar lamontlamont/* * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef GENERIC_LP_107_H #define GENERIC_LP_107_H 1 typedef struct dns_rdata_lp { dns_rdatacommon_t common; isc_mem_t *mctx; isc_uint16_t pref; dns_name_t lp; } dns_rdata_lp_t; #endif /* GENERIC_LP_107_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/proforma.c0000644000470500017500000001076212664710322021431 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: proforma.c,v 1.38 2009/12/04 22:06:37 tbox Exp $ */ #ifndef RDATA_GENERIC_#_#_C #define RDATA_GENERIC_#_#_C #define RRTYPE_#_ATTRIBUTES (0) static inline isc_result_t fromtext_#(ARGS_FROMTEXT) { isc_token_t token; REQUIRE(type == dns_rdatatype_proforma.c#); REQUIRE(rdclass == #); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); return (ISC_R_NOTIMPLEMENTED); } static inline isc_result_t totext_#(ARGS_TOTEXT) { REQUIRE(rdata->type == dns_rdatatype_proforma.c#); REQUIRE(rdata->rdclass == #); REQUIRE(rdata->length != 0); /* XXX */ return (ISC_R_NOTIMPLEMENTED); } static inline isc_result_t fromwire_#(ARGS_FROMWIRE) { REQUIRE(type == dns_rdatatype_proforma.c#); REQUIRE(rdclass == #); /* NONE or GLOBAL14 */ dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); return (ISC_R_NOTIMPLEMENTED); } static inline isc_result_t towire_#(ARGS_TOWIRE) { REQUIRE(rdata->type == dns_rdatatype_proforma.c#); REQUIRE(rdata->rdclass == #); REQUIRE(rdata->length != 0); /* XXX */ /* NONE or GLOBAL14 */ dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); return (ISC_R_NOTIMPLEMENTED); } static inline int compare_#(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == dns_rdatatype_proforma.crdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_proforma.c#); REQUIRE(rdata1->rdclass == #); REQUIRE(rdata1->length != 0); /* XXX */ REQUIRE(rdata2->length != 0); /* XXX */ dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_#(ARGS_FROMSTRUCT) { dns_rdata_#_t *# = source; REQUIRE(type == dns_rdatatype_proforma.c#); REQUIRE(rdclass == #); REQUIRE(source != NULL); REQUIRE(#->common.rdtype == dns_rdatatype_proforma.ctype); REQUIRE(#->common.rdclass == rdclass); return (ISC_R_NOTIMPLEMENTED); } static inline isc_result_t tostruct_#(ARGS_TOSTRUCT) { REQUIRE(rdata->type == dns_rdatatype_proforma.c#); REQUIRE(rdata->rdclass == #); REQUIRE(rdata->length != 0); /* XXX */ return (ISC_R_NOTIMPLEMENTED); } static inline void freestruct_#(ARGS_FREESTRUCT) { dns_rdata_#_t *# = source; REQUIRE(source != NULL); REQUIRE(#->common.rdtype == dns_rdatatype_proforma.c#); REQUIRE(#->common.rdclass == #); } static inline isc_result_t additionaldata_#(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_proforma.c#); REQUIRE(rdata->rdclass == #); (void)add; (void)arg; return (ISC_R_SUCCESS); } static inline isc_result_t digest_#(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_proforma.c#); REQUIRE(rdata->rdclass == #); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_#(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_proforma.c#); REQUIRE(rdclass == #); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_#(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_proforma.c#); REQUIRE(rdata->rdclass == #); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_#(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == dns_rdatatype_proforma.crdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_proforma.c#); REQUIRE(rdata1->rdclass == #); REQUIRE(rdata1->length != 0); /* XXX */ REQUIRE(rdata2->length != 0); /* XXX */ dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } #endif /* RDATA_GENERIC_#_#_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/nsec3_50.c0000644000470500017500000003210412664710322021115 0ustar lamontlamont/* * Copyright (C) 2008, 2009, 2011, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* * Copyright (C) 2004 Nominet, Ltd. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINET DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* RFC 5155 */ #ifndef RDATA_GENERIC_NSEC3_50_C #define RDATA_GENERIC_NSEC3_50_C #include #include #define RRTYPE_NSEC3_ATTRIBUTES DNS_RDATATYPEATTR_DNSSEC static inline isc_result_t fromtext_nsec3(ARGS_FROMTEXT) { isc_token_t token; unsigned char bm[8*1024]; /* 64k bits */ dns_rdatatype_t covered; int octet; int window; unsigned int flags; unsigned char hashalg; isc_buffer_t b; REQUIRE(type == dns_rdatatype_nsec3); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); UNUSED(origin); UNUSED(options); /* Hash. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_hashalg_fromtext(&hashalg, &token.value.as_textregion)); RETERR(uint8_tobuffer(hashalg, target)); /* Flags. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); flags = token.value.as_ulong; if (flags > 255U) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer(flags, target)); /* Iterations. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* salt */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (token.value.as_textregion.length > (255*2)) RETTOK(DNS_R_TEXTTOOLONG); if (strcmp(DNS_AS_STR(token), "-") == 0) { RETERR(uint8_tobuffer(0, target)); } else { RETERR(uint8_tobuffer(strlen(DNS_AS_STR(token)) / 2, target)); RETERR(isc_hex_decodestring(DNS_AS_STR(token), target)); } /* * Next hash a single base32hex word. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); isc_buffer_init(&b, bm, sizeof(bm)); RETTOK(isc_base32hexnp_decodestring(DNS_AS_STR(token), &b)); if (isc_buffer_usedlength(&b) > 0xffU) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer(isc_buffer_usedlength(&b), target)); RETERR(mem_tobuffer(target, &bm, isc_buffer_usedlength(&b))); memset(bm, 0, sizeof(bm)); do { RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_TRUE)); if (token.type != isc_tokentype_string) break; RETTOK(dns_rdatatype_fromtext(&covered, &token.value.as_textregion)); bm[covered/8] |= (0x80>>(covered%8)); } while (1); isc_lex_ungettoken(lexer, &token); for (window = 0; window < 256 ; window++) { /* * Find if we have a type in this window. */ for (octet = 31; octet >= 0; octet--) if (bm[window * 32 + octet] != 0) break; if (octet < 0) continue; RETERR(uint8_tobuffer(window, target)); RETERR(uint8_tobuffer(octet + 1, target)); RETERR(mem_tobuffer(target, &bm[window * 32], octet + 1)); } return (ISC_R_SUCCESS); } static inline isc_result_t totext_nsec3(ARGS_TOTEXT) { isc_region_t sr; unsigned int i, j, k; unsigned int window, len; unsigned char hash; unsigned char flags; char buf[sizeof("TYPE65535")]; isc_uint32_t iterations; isc_boolean_t first; REQUIRE(rdata->type == dns_rdatatype_nsec3); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); /* Hash */ hash = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u ", hash); RETERR(str_totext(buf, target)); /* Flags */ flags = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u ", flags); RETERR(str_totext(buf, target)); /* Iterations */ iterations = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%u ", iterations); RETERR(str_totext(buf, target)); /* Salt */ j = uint8_fromregion(&sr); isc_region_consume(&sr, 1); INSIST(j <= sr.length); if (j != 0) { i = sr.length; sr.length = j; RETERR(isc_hex_totext(&sr, 1, "", target)); sr.length = i - j; } else RETERR(str_totext("-", target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); /* Next hash */ j = uint8_fromregion(&sr); isc_region_consume(&sr, 1); INSIST(j <= sr.length); i = sr.length; sr.length = j; RETERR(isc_base32hexnp_totext(&sr, 1, "", target)); sr.length = i - j; if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) == 0) RETERR(str_totext(" ", target)); /* Types covered */ first = ISC_TRUE; for (i = 0; i < sr.length; i += len) { if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { RETERR(str_totext(tctx->linebreak, target)); first = ISC_TRUE; } INSIST(i + 2 <= sr.length); window = sr.base[i]; len = sr.base[i + 1]; INSIST(len > 0 && len <= 32); i += 2; INSIST(i + len <= sr.length); for (j = 0; j < len; j++) { dns_rdatatype_t t; if (sr.base[i + j] == 0) continue; for (k = 0; k < 8; k++) { if ((sr.base[i + j] & (0x80 >> k)) == 0) continue; t = window * 256 + j * 8 + k; if (!first) RETERR(str_totext(" ", target)); first = ISC_FALSE; if (dns_rdatatype_isknown(t)) { RETERR(dns_rdatatype_totext(t, target)); } else { sprintf(buf, "TYPE%u", t); RETERR(str_totext(buf, target)); } } } } if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_nsec3(ARGS_FROMWIRE) { isc_region_t sr, rr; unsigned int window, lastwindow = 0; unsigned int len; unsigned int saltlen, hashlen; isc_boolean_t first = ISC_TRUE; unsigned int i; REQUIRE(type == dns_rdatatype_nsec3); UNUSED(type); UNUSED(rdclass); UNUSED(options); UNUSED(dctx); isc_buffer_activeregion(source, &sr); rr = sr; /* hash(1), flags(1), iteration(2), saltlen(1) */ if (sr.length < 5U) RETERR(DNS_R_FORMERR); saltlen = sr.base[4]; isc_region_consume(&sr, 5); if (sr.length < saltlen) RETERR(DNS_R_FORMERR); isc_region_consume(&sr, saltlen); if (sr.length < 1U) RETERR(DNS_R_FORMERR); hashlen = sr.base[0]; isc_region_consume(&sr, 1); if (sr.length < hashlen) RETERR(DNS_R_FORMERR); isc_region_consume(&sr, hashlen); for (i = 0; i < sr.length; i += len) { /* * Check for overflow. */ if (i + 2 > sr.length) RETERR(DNS_R_FORMERR); window = sr.base[i]; len = sr.base[i + 1]; i += 2; /* * Check that bitmap windows are in the correct order. */ if (!first && window <= lastwindow) RETERR(DNS_R_FORMERR); /* * Check for legal lengths. */ if (len < 1 || len > 32) RETERR(DNS_R_FORMERR); /* * Check for overflow. */ if (i + len > sr.length) RETERR(DNS_R_FORMERR); /* * The last octet of the bitmap must be non zero. */ if (sr.base[i + len - 1] == 0) RETERR(DNS_R_FORMERR); lastwindow = window; first = ISC_FALSE; } if (i != sr.length) return (DNS_R_EXTRADATA); RETERR(mem_tobuffer(target, rr.base, rr.length)); isc_buffer_forward(source, rr.length); return (ISC_R_SUCCESS); } static inline isc_result_t towire_nsec3(ARGS_TOWIRE) { isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_nsec3); REQUIRE(rdata->length != 0); UNUSED(cctx); dns_rdata_toregion(rdata, &sr); return (mem_tobuffer(target, sr.base, sr.length)); } static inline int compare_nsec3(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_nsec3); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_nsec3(ARGS_FROMSTRUCT) { dns_rdata_nsec3_t *nsec3 = source; unsigned int i, len, window, lastwindow = 0; isc_boolean_t first = ISC_TRUE; REQUIRE(type == dns_rdatatype_nsec3); REQUIRE(source != NULL); REQUIRE(nsec3->common.rdtype == type); REQUIRE(nsec3->common.rdclass == rdclass); REQUIRE(nsec3->typebits != NULL || nsec3->len == 0); REQUIRE(nsec3->hash == dns_hash_sha1); UNUSED(type); UNUSED(rdclass); RETERR(uint8_tobuffer(nsec3->hash, target)); RETERR(uint8_tobuffer(nsec3->flags, target)); RETERR(uint16_tobuffer(nsec3->iterations, target)); RETERR(uint8_tobuffer(nsec3->salt_length, target)); RETERR(mem_tobuffer(target, nsec3->salt, nsec3->salt_length)); RETERR(uint8_tobuffer(nsec3->next_length, target)); RETERR(mem_tobuffer(target, nsec3->next, nsec3->next_length)); /* * Perform sanity check. */ for (i = 0; i < nsec3->len ; i += len) { INSIST(i + 2 <= nsec3->len); window = nsec3->typebits[i]; len = nsec3->typebits[i+1]; i += 2; INSIST(first || window > lastwindow); INSIST(len > 0 && len <= 32); INSIST(i + len <= nsec3->len); INSIST(nsec3->typebits[i + len - 1] != 0); lastwindow = window; first = ISC_FALSE; } return (mem_tobuffer(target, nsec3->typebits, nsec3->len)); } static inline isc_result_t tostruct_nsec3(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_nsec3_t *nsec3 = target; REQUIRE(rdata->type == dns_rdatatype_nsec3); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); nsec3->common.rdclass = rdata->rdclass; nsec3->common.rdtype = rdata->type; ISC_LINK_INIT(&nsec3->common, link); region.base = rdata->data; region.length = rdata->length; nsec3->hash = uint8_consume_fromregion(®ion); nsec3->flags = uint8_consume_fromregion(®ion); nsec3->iterations = uint16_consume_fromregion(®ion); nsec3->salt_length = uint8_consume_fromregion(®ion); nsec3->salt = mem_maybedup(mctx, region.base, nsec3->salt_length); if (nsec3->salt == NULL) return (ISC_R_NOMEMORY); isc_region_consume(®ion, nsec3->salt_length); nsec3->next_length = uint8_consume_fromregion(®ion); nsec3->next = mem_maybedup(mctx, region.base, nsec3->next_length); if (nsec3->next == NULL) goto cleanup; isc_region_consume(®ion, nsec3->next_length); nsec3->len = region.length; nsec3->typebits = mem_maybedup(mctx, region.base, region.length); if (nsec3->typebits == NULL) goto cleanup; nsec3->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (nsec3->next != NULL) isc_mem_free(mctx, nsec3->next); isc_mem_free(mctx, nsec3->salt); return (ISC_R_NOMEMORY); } static inline void freestruct_nsec3(ARGS_FREESTRUCT) { dns_rdata_nsec3_t *nsec3 = source; REQUIRE(source != NULL); REQUIRE(nsec3->common.rdtype == dns_rdatatype_nsec3); if (nsec3->mctx == NULL) return; if (nsec3->salt != NULL) isc_mem_free(nsec3->mctx, nsec3->salt); if (nsec3->next != NULL) isc_mem_free(nsec3->mctx, nsec3->next); if (nsec3->typebits != NULL) isc_mem_free(nsec3->mctx, nsec3->typebits); nsec3->mctx = NULL; } static inline isc_result_t additionaldata_nsec3(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_nsec3); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_nsec3(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_nsec3); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_nsec3(ARGS_CHECKOWNER) { unsigned char owner[NSEC3_MAX_HASH_LENGTH]; isc_buffer_t buffer; dns_label_t label; REQUIRE(type == dns_rdatatype_nsec3); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); /* * First label is a base32hex string without padding. */ dns_name_getlabel(name, 0, &label); isc_region_consume(&label, 1); isc_buffer_init(&buffer, owner, sizeof(owner)); if (isc_base32hexnp_decoderegion(&label, &buffer) == ISC_R_SUCCESS) return (ISC_TRUE); return (ISC_FALSE); } static inline isc_boolean_t checknames_nsec3(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_nsec3); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_nsec3(ARGS_COMPARE) { return (compare_nsec3(rdata1, rdata2)); } #endif /* RDATA_GENERIC_NSEC3_50_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/lp_107.c0000644000470500017500000001467612664710322020616 0ustar lamontlamont/* * Copyright (C) 2013, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef RDATA_GENERIC_LP_107_C #define RDATA_GENERIC_LP_107_C #include #include #define RRTYPE_LP_ATTRIBUTES (0) static inline isc_result_t fromtext_lp(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; REQUIRE(type == dns_rdatatype_lp); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; return (dns_name_fromtext(&name, &buffer, origin, options, target)); } static inline isc_result_t totext_lp(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; char buf[sizeof("64000")]; unsigned short num; REQUIRE(rdata->type == dns_rdatatype_lp); REQUIRE(rdata->length != 0); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, ®ion); num = uint16_fromregion(®ion); isc_region_consume(®ion, 2); sprintf(buf, "%u", num); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); dns_name_fromregion(&name, ®ion); sub = name_prefix(&name, tctx->origin, &prefix); return (dns_name_totext(&prefix, sub, target)); } static inline isc_result_t fromwire_lp(ARGS_FROMWIRE) { dns_name_t name; isc_region_t sregion; REQUIRE(type == dns_rdatatype_lp); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, NULL); isc_buffer_activeregion(source, &sregion); if (sregion.length < 2) return (ISC_R_UNEXPECTEDEND); RETERR(mem_tobuffer(target, sregion.base, 2)); isc_buffer_forward(source, 2); return (dns_name_fromwire(&name, source, dctx, options, target)); } static inline isc_result_t towire_lp(ARGS_TOWIRE) { REQUIRE(rdata->type == dns_rdatatype_lp); REQUIRE(rdata->length != 0); UNUSED(cctx); return (mem_tobuffer(target, rdata->data, rdata->length)); } static inline int compare_lp(ARGS_COMPARE) { isc_region_t region1; isc_region_t region2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_lp); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); return (isc_region_compare(®ion1, ®ion2)); } static inline isc_result_t fromstruct_lp(ARGS_FROMSTRUCT) { dns_rdata_lp_t *lp = source; isc_region_t region; REQUIRE(type == dns_rdatatype_lp); REQUIRE(source != NULL); REQUIRE(lp->common.rdtype == type); REQUIRE(lp->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); RETERR(uint16_tobuffer(lp->pref, target)); dns_name_toregion(&lp->lp, ®ion); return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_lp(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_lp_t *lp = target; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_lp); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); lp->common.rdclass = rdata->rdclass; lp->common.rdtype = rdata->type; ISC_LINK_INIT(&lp->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); lp->pref = uint16_fromregion(®ion); isc_region_consume(®ion, 2); dns_name_fromregion(&name, ®ion); dns_name_init(&lp->lp, NULL); RETERR(name_duporclone(&name, mctx, &lp->lp)); lp->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_lp(ARGS_FREESTRUCT) { dns_rdata_lp_t *lp = source; REQUIRE(source != NULL); REQUIRE(lp->common.rdtype == dns_rdatatype_lp); if (lp->mctx == NULL) return; dns_name_free(&lp->lp, lp->mctx); lp->mctx = NULL; } static inline isc_result_t additionaldata_lp(ARGS_ADDLDATA) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; isc_result_t result; REQUIRE(rdata->type == dns_rdatatype_lp); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, ®ion); isc_region_consume(®ion, 2); dns_name_fromregion(&name, ®ion); result = (add)(arg, &name, dns_rdatatype_l32); if (result != ISC_R_SUCCESS) return (result); return ((add)(arg, &name, dns_rdatatype_l64)); } static inline isc_result_t digest_lp(ARGS_DIGEST) { isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_lp); dns_rdata_toregion(rdata, ®ion); return ((digest)(arg, ®ion)); } static inline isc_boolean_t checkowner_lp(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_lp); UNUSED(type); UNUSED(rdclass); UNUSED(name); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_lp(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_lp); UNUSED(bad); UNUSED(owner); return (ISC_TRUE); } static inline int casecompare_lp(ARGS_COMPARE) { dns_name_t name1; dns_name_t name2; isc_region_t region1; isc_region_t region2; int order; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_lp); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); order = memcmp(rdata1->data, rdata2->data, 2); if (order != 0) return (order < 0 ? -1 : 1); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); isc_region_consume(®ion1, 2); isc_region_consume(®ion2, 2); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); return (dns_name_rdatacompare(&name1, &name2)); } #endif /* RDATA_GENERIC_LP_107_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/minfo_14.h0000644000470500017500000000221512664710322021217 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef GENERIC_MINFO_14_H #define GENERIC_MINFO_14_H 1 /* $Id: minfo_14.h,v 1.27 2007/06/19 23:47:17 tbox Exp $ */ typedef struct dns_rdata_minfo { dns_rdatacommon_t common; isc_mem_t *mctx; dns_name_t rmailbox; dns_name_t emailbox; } dns_rdata_minfo_t; #endif /* GENERIC_MINFO_14_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/key_25.c0000644000470500017500000002123412664710322020676 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2011-2013, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* * Reviewed: Wed Mar 15 16:47:10 PST 2000 by halley. */ /* RFC2535 */ #ifndef RDATA_GENERIC_KEY_25_C #define RDATA_GENERIC_KEY_25_C #include #define RRTYPE_KEY_ATTRIBUTES (0) static inline isc_result_t fromtext_key(ARGS_FROMTEXT) { isc_result_t result; isc_token_t token; dns_secalg_t alg; dns_secproto_t proto; dns_keyflags_t flags; REQUIRE(type == dns_rdatatype_key); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); /* flags */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion)); RETERR(uint16_tobuffer(flags, target)); /* protocol */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion)); RETERR(mem_tobuffer(target, &proto, 1)); /* algorithm */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion)); RETERR(mem_tobuffer(target, &alg, 1)); /* No Key? */ if ((flags & 0xc000) == 0xc000) return (ISC_R_SUCCESS); result = isc_base64_tobuffer(lexer, target, -1); if (result != ISC_R_SUCCESS) return (result); /* Ensure there's at least enough data to compute a key ID for MD5 */ if (alg == DST_ALG_RSAMD5 && isc_buffer_usedlength(target) < 7) return (ISC_R_UNEXPECTEDEND); return (ISC_R_SUCCESS); } static inline isc_result_t totext_key(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("64000")]; unsigned int flags; unsigned char algorithm; char namebuf[DNS_NAME_FORMATSIZE]; REQUIRE(rdata->type == dns_rdatatype_key); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); /* flags */ flags = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%u", flags); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* protocol */ sprintf(buf, "%u", sr.base[0]); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* algorithm */ algorithm = sr.base[0]; sprintf(buf, "%u", algorithm); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); /* No Key? */ if ((flags & 0xc000) == 0xc000) return (ISC_R_SUCCESS); if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0 && algorithm == DNS_KEYALG_PRIVATEDNS) { dns_name_t name; dns_name_init(&name, NULL); dns_name_fromregion(&name, &sr); dns_name_format(&name, namebuf, sizeof(namebuf)); } else namebuf[0] = 0; /* key */ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(&sr, 60, "", target)); else RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) RETERR(str_totext(tctx->linebreak, target)); else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" ", target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(")", target)); if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) { isc_region_t tmpr; RETERR(str_totext(" ; key id = ", target)); dns_rdata_toregion(rdata, &tmpr); sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm)); RETERR(str_totext(buf, target)); if (algorithm == DNS_KEYALG_PRIVATEDNS) { RETERR(str_totext(tctx->linebreak, target)); RETERR(str_totext("; alg = ", target)); RETERR(str_totext(namebuf, target)); } } return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_key(ARGS_FROMWIRE) { unsigned char algorithm; isc_region_t sr; REQUIRE(type == dns_rdatatype_key); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); isc_buffer_activeregion(source, &sr); if (sr.length < 4) return (ISC_R_UNEXPECTEDEND); algorithm = sr.base[3]; RETERR(mem_tobuffer(target, sr.base, 4)); isc_region_consume(&sr, 4); isc_buffer_forward(source, 4); if (algorithm == DNS_KEYALG_PRIVATEDNS) { dns_name_t name; dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); dns_name_init(&name, NULL); RETERR(dns_name_fromwire(&name, source, dctx, options, target)); } /* * RSAMD5 computes key ID differently from other * algorithms: we need to ensure there's enough data * present for the computation */ if (algorithm == DST_ALG_RSAMD5 && sr.length < 3) return (ISC_R_UNEXPECTEDEND); isc_buffer_activeregion(source, &sr); isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); } static inline isc_result_t towire_key(ARGS_TOWIRE) { isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_key); REQUIRE(rdata->length != 0); UNUSED(cctx); dns_rdata_toregion(rdata, &sr); return (mem_tobuffer(target, sr.base, sr.length)); } static inline int compare_key(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_key); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_key(ARGS_FROMSTRUCT) { dns_rdata_key_t *key = source; REQUIRE(type == dns_rdatatype_key); REQUIRE(source != NULL); REQUIRE(key->common.rdtype == type); REQUIRE(key->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); /* Flags */ RETERR(uint16_tobuffer(key->flags, target)); /* Protocol */ RETERR(uint8_tobuffer(key->protocol, target)); /* Algorithm */ RETERR(uint8_tobuffer(key->algorithm, target)); /* Data */ return (mem_tobuffer(target, key->data, key->datalen)); } static inline isc_result_t tostruct_key(ARGS_TOSTRUCT) { dns_rdata_key_t *key = target; isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_key); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); key->common.rdclass = rdata->rdclass; key->common.rdtype = rdata->type; ISC_LINK_INIT(&key->common, link); dns_rdata_toregion(rdata, &sr); /* Flags */ if (sr.length < 2) return (ISC_R_UNEXPECTEDEND); key->flags = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* Protocol */ if (sr.length < 1) return (ISC_R_UNEXPECTEDEND); key->protocol = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* Algorithm */ if (sr.length < 1) return (ISC_R_UNEXPECTEDEND); key->algorithm = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* Data */ key->datalen = sr.length; key->data = mem_maybedup(mctx, sr.base, key->datalen); if (key->data == NULL) return (ISC_R_NOMEMORY); key->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_key(ARGS_FREESTRUCT) { dns_rdata_key_t *key = (dns_rdata_key_t *) source; REQUIRE(source != NULL); REQUIRE(key->common.rdtype == dns_rdatatype_key); if (key->mctx == NULL) return; if (key->data != NULL) isc_mem_free(key->mctx, key->data); key->mctx = NULL; } static inline isc_result_t additionaldata_key(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_key); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_key(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_key); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_key(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_key); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_key(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_key); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_key(ARGS_COMPARE) { return (compare_key(rdata1, rdata2)); } #endif /* RDATA_GENERIC_KEY_25_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/hinfo_13.h0000644000470500017500000000223312664710322021211 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_HINFO_13_H #define GENERIC_HINFO_13_H 1 /* $Id: hinfo_13.h,v 1.25 2007/06/19 23:47:17 tbox Exp $ */ typedef struct dns_rdata_hinfo { dns_rdatacommon_t common; isc_mem_t *mctx; char *cpu; char *os; isc_uint8_t cpu_len; isc_uint8_t os_len; } dns_rdata_hinfo_t; #endif /* GENERIC_HINFO_13_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/nsec3param_51.h0000644000470500017500000000240312664710322022143 0ustar lamontlamont/* * Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_NSEC3PARAM_51_H #define GENERIC_NSEC3PARAM_51_H 1 /* $Id: nsec3param_51.h,v 1.4 2008/09/25 04:02:39 tbox Exp $ */ /*! * \brief Per RFC 5155 */ #include typedef struct dns_rdata_nsec3param { dns_rdatacommon_t common; isc_mem_t *mctx; dns_hash_t hash; unsigned char flags; /* DNS_NSEC3FLAG_* */ dns_iterations_t iterations; unsigned char salt_length; unsigned char *salt; } dns_rdata_nsec3param_t; #endif /* GENERIC_NSEC3PARAM_51_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/cert_37.h0000644000470500017500000000233512664710322021054 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: cert_37.h,v 1.20 2007/06/19 23:47:17 tbox Exp $ */ #ifndef GENERIC_CERT_37_H #define GENERIC_CERT_37_H 1 /*% RFC2538 */ typedef struct dns_rdata_cert { dns_rdatacommon_t common; isc_mem_t *mctx; isc_uint16_t type; isc_uint16_t key_tag; isc_uint8_t algorithm; isc_uint16_t length; unsigned char *certificate; } dns_rdata_cert_t; #endif /* GENERIC_CERT_37_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/soa_6.h0000644000470500017500000000252112664710322020612 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef GENERIC_SOA_6_H #define GENERIC_SOA_6_H 1 /* $Id: soa_6.h,v 1.32 2007/06/19 23:47:17 tbox Exp $ */ typedef struct dns_rdata_soa { dns_rdatacommon_t common; isc_mem_t *mctx; dns_name_t origin; dns_name_t contact; isc_uint32_t serial; /*%< host order */ isc_uint32_t refresh; /*%< host order */ isc_uint32_t retry; /*%< host order */ isc_uint32_t expire; /*%< host order */ isc_uint32_t minimum; /*%< host order */ } dns_rdata_soa_t; #endif /* GENERIC_SOA_6_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/dnskey_48.c0000644000470500017500000002256712664710322021422 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2011-2013, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* * Reviewed: Wed Mar 15 16:47:10 PST 2000 by halley. */ /* RFC2535 */ #ifndef RDATA_GENERIC_DNSKEY_48_C #define RDATA_GENERIC_DNSKEY_48_C #include #define RRTYPE_DNSKEY_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC) static inline isc_result_t fromtext_dnskey(ARGS_FROMTEXT) { isc_result_t result; isc_token_t token; dns_secalg_t alg; dns_secproto_t proto; dns_keyflags_t flags; REQUIRE(type == dns_rdatatype_dnskey); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); /* flags */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion)); RETERR(uint16_tobuffer(flags, target)); /* protocol */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion)); RETERR(mem_tobuffer(target, &proto, 1)); /* algorithm */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion)); RETERR(mem_tobuffer(target, &alg, 1)); /* No Key? */ if ((flags & 0xc000) == 0xc000) return (ISC_R_SUCCESS); result = isc_base64_tobuffer(lexer, target, -1); if (result != ISC_R_SUCCESS) return (result); /* Ensure there's at least enough data to compute a key ID for MD5 */ if (alg == DST_ALG_RSAMD5 && isc_buffer_usedlength(target) < 7) return (ISC_R_UNEXPECTEDEND); return (ISC_R_SUCCESS); } static inline isc_result_t totext_dnskey(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("[key id = 64000]")]; unsigned int flags; unsigned char algorithm; char algbuf[DNS_NAME_FORMATSIZE]; const char *keyinfo; isc_region_t tmpr; REQUIRE(rdata->type == dns_rdatatype_dnskey); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); /* flags */ flags = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%u", flags); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); if ((flags & DNS_KEYFLAG_KSK) != 0) { if (flags & DNS_KEYFLAG_REVOKE) keyinfo = "revoked KSK"; else keyinfo = "KSK"; } else keyinfo = "ZSK"; /* protocol */ sprintf(buf, "%u", sr.base[0]); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* algorithm */ algorithm = sr.base[0]; sprintf(buf, "%u", algorithm); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); /* No Key? */ if ((flags & 0xc000) == 0xc000) return (ISC_R_SUCCESS); if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0 && algorithm == DNS_KEYALG_PRIVATEDNS) { dns_name_t name; dns_name_init(&name, NULL); dns_name_fromregion(&name, &sr); dns_name_format(&name, algbuf, sizeof(algbuf)); } else { dns_secalg_format((dns_secalg_t) algorithm, algbuf, sizeof(algbuf)); } /* key */ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) { if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(&sr, 0, "", target)); else RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, target)); } else { dns_rdata_toregion(rdata, &tmpr); snprintf(buf, sizeof(buf), "[key id = %u]", dst_region_computeid(&tmpr, algorithm)); RETERR(str_totext(buf, target)); } if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) RETERR(str_totext(tctx->linebreak, target)); else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" ", target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(")", target)); if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) { RETERR(str_totext(" ; ", target)); RETERR(str_totext(keyinfo, target)); RETERR(str_totext("; alg = ", target)); RETERR(str_totext(algbuf, target)); RETERR(str_totext("; key id = ", target)); dns_rdata_toregion(rdata, &tmpr); sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm)); RETERR(str_totext(buf, target)); } return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_dnskey(ARGS_FROMWIRE) { unsigned char algorithm; isc_region_t sr; REQUIRE(type == dns_rdatatype_dnskey); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); isc_buffer_activeregion(source, &sr); if (sr.length < 4) return (ISC_R_UNEXPECTEDEND); algorithm = sr.base[3]; RETERR(mem_tobuffer(target, sr.base, 4)); isc_region_consume(&sr, 4); isc_buffer_forward(source, 4); if (algorithm == DNS_KEYALG_PRIVATEDNS) { dns_name_t name; dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); dns_name_init(&name, NULL); RETERR(dns_name_fromwire(&name, source, dctx, options, target)); } /* * RSAMD5 computes key ID differently from other * algorithms: we need to ensure there's enough data * present for the computation */ if (algorithm == DST_ALG_RSAMD5 && sr.length < 3) return (ISC_R_UNEXPECTEDEND); isc_buffer_activeregion(source, &sr); isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); } static inline isc_result_t towire_dnskey(ARGS_TOWIRE) { isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_dnskey); REQUIRE(rdata->length != 0); UNUSED(cctx); dns_rdata_toregion(rdata, &sr); return (mem_tobuffer(target, sr.base, sr.length)); } static inline int compare_dnskey(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_dnskey); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_dnskey(ARGS_FROMSTRUCT) { dns_rdata_dnskey_t *dnskey = source; REQUIRE(type == dns_rdatatype_dnskey); REQUIRE(source != NULL); REQUIRE(dnskey->common.rdtype == type); REQUIRE(dnskey->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); /* Flags */ RETERR(uint16_tobuffer(dnskey->flags, target)); /* Protocol */ RETERR(uint8_tobuffer(dnskey->protocol, target)); /* Algorithm */ RETERR(uint8_tobuffer(dnskey->algorithm, target)); /* Data */ return (mem_tobuffer(target, dnskey->data, dnskey->datalen)); } static inline isc_result_t tostruct_dnskey(ARGS_TOSTRUCT) { dns_rdata_dnskey_t *dnskey = target; isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_dnskey); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); dnskey->common.rdclass = rdata->rdclass; dnskey->common.rdtype = rdata->type; ISC_LINK_INIT(&dnskey->common, link); dns_rdata_toregion(rdata, &sr); /* Flags */ if (sr.length < 2) return (ISC_R_UNEXPECTEDEND); dnskey->flags = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* Protocol */ if (sr.length < 1) return (ISC_R_UNEXPECTEDEND); dnskey->protocol = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* Algorithm */ if (sr.length < 1) return (ISC_R_UNEXPECTEDEND); dnskey->algorithm = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* Data */ dnskey->datalen = sr.length; dnskey->data = mem_maybedup(mctx, sr.base, dnskey->datalen); if (dnskey->data == NULL) return (ISC_R_NOMEMORY); dnskey->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_dnskey(ARGS_FREESTRUCT) { dns_rdata_dnskey_t *dnskey = (dns_rdata_dnskey_t *) source; REQUIRE(source != NULL); REQUIRE(dnskey->common.rdtype == dns_rdatatype_dnskey); if (dnskey->mctx == NULL) return; if (dnskey->data != NULL) isc_mem_free(dnskey->mctx, dnskey->data); dnskey->mctx = NULL; } static inline isc_result_t additionaldata_dnskey(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_dnskey); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_dnskey(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_dnskey); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_dnskey(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_dnskey); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_dnskey(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_dnskey); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_dnskey(ARGS_COMPARE) { /* * Treat ALG 253 (private DNS) subtype name case sensistively. */ return (compare_dnskey(rdata1, rdata2)); } #endif /* RDATA_GENERIC_DNSKEY_48_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/dlv_32769.h0000644000470500017500000000231312664710322021141 0ustar lamontlamont/* * Copyright (C) 2004, 2006, 2007 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: dlv_32769.h,v 1.5 2007/06/19 23:47:17 tbox Exp $ */ /* draft-ietf-dnsext-delegation-signer-05.txt */ #ifndef GENERIC_DLV_32769_H #define GENERIC_DLV_32769_H 1 typedef struct dns_rdata_dlv { dns_rdatacommon_t common; isc_mem_t *mctx; isc_uint16_t key_tag; isc_uint8_t algorithm; isc_uint8_t digest_type; isc_uint16_t length; unsigned char *digest; } dns_rdata_dlv_t; #endif /* GENERIC_DLV_32769_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/gpos_27.c0000644000470500017500000001376512664710322021072 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: gpos_27.c,v 1.43 2009/12/04 22:06:37 tbox Exp $ */ /* reviewed: Wed Mar 15 16:48:45 PST 2000 by brister */ /* RFC1712 */ #ifndef RDATA_GENERIC_GPOS_27_C #define RDATA_GENERIC_GPOS_27_C #define RRTYPE_GPOS_ATTRIBUTES (0) static inline isc_result_t fromtext_gpos(ARGS_FROMTEXT) { isc_token_t token; int i; REQUIRE(type == dns_rdatatype_gpos); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); for (i = 0; i < 3; i++) { RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, ISC_FALSE)); RETTOK(txt_fromtext(&token.value.as_textregion, target)); } return (ISC_R_SUCCESS); } static inline isc_result_t totext_gpos(ARGS_TOTEXT) { isc_region_t region; int i; REQUIRE(rdata->type == dns_rdatatype_gpos); REQUIRE(rdata->length != 0); UNUSED(tctx); dns_rdata_toregion(rdata, ®ion); for (i = 0; i < 3; i++) { RETERR(txt_totext(®ion, ISC_TRUE, target)); if (i != 2) RETERR(str_totext(" ", target)); } return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_gpos(ARGS_FROMWIRE) { int i; REQUIRE(type == dns_rdatatype_gpos); UNUSED(type); UNUSED(dctx); UNUSED(rdclass); UNUSED(options); for (i = 0; i < 3; i++) RETERR(txt_fromwire(source, target)); return (ISC_R_SUCCESS); } static inline isc_result_t towire_gpos(ARGS_TOWIRE) { REQUIRE(rdata->type == dns_rdatatype_gpos); REQUIRE(rdata->length != 0); UNUSED(cctx); return (mem_tobuffer(target, rdata->data, rdata->length)); } static inline int compare_gpos(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_gpos); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_gpos(ARGS_FROMSTRUCT) { dns_rdata_gpos_t *gpos = source; REQUIRE(type == dns_rdatatype_gpos); REQUIRE(source != NULL); REQUIRE(gpos->common.rdtype == type); REQUIRE(gpos->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); RETERR(uint8_tobuffer(gpos->long_len, target)); RETERR(mem_tobuffer(target, gpos->longitude, gpos->long_len)); RETERR(uint8_tobuffer(gpos->lat_len, target)); RETERR(mem_tobuffer(target, gpos->latitude, gpos->lat_len)); RETERR(uint8_tobuffer(gpos->alt_len, target)); return (mem_tobuffer(target, gpos->altitude, gpos->alt_len)); } static inline isc_result_t tostruct_gpos(ARGS_TOSTRUCT) { dns_rdata_gpos_t *gpos = target; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_gpos); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); gpos->common.rdclass = rdata->rdclass; gpos->common.rdtype = rdata->type; ISC_LINK_INIT(&gpos->common, link); dns_rdata_toregion(rdata, ®ion); gpos->long_len = uint8_fromregion(®ion); isc_region_consume(®ion, 1); gpos->longitude = mem_maybedup(mctx, region.base, gpos->long_len); if (gpos->longitude == NULL) return (ISC_R_NOMEMORY); isc_region_consume(®ion, gpos->long_len); gpos->lat_len = uint8_fromregion(®ion); isc_region_consume(®ion, 1); gpos->latitude = mem_maybedup(mctx, region.base, gpos->lat_len); if (gpos->latitude == NULL) goto cleanup_longitude; isc_region_consume(®ion, gpos->lat_len); gpos->alt_len = uint8_fromregion(®ion); isc_region_consume(®ion, 1); if (gpos->lat_len > 0) { gpos->altitude = mem_maybedup(mctx, region.base, gpos->alt_len); if (gpos->altitude == NULL) goto cleanup_latitude; } else gpos->altitude = NULL; gpos->mctx = mctx; return (ISC_R_SUCCESS); cleanup_latitude: if (mctx != NULL && gpos->longitude != NULL) isc_mem_free(mctx, gpos->longitude); cleanup_longitude: if (mctx != NULL && gpos->latitude != NULL) isc_mem_free(mctx, gpos->latitude); return (ISC_R_NOMEMORY); } static inline void freestruct_gpos(ARGS_FREESTRUCT) { dns_rdata_gpos_t *gpos = source; REQUIRE(source != NULL); REQUIRE(gpos->common.rdtype == dns_rdatatype_gpos); if (gpos->mctx == NULL) return; if (gpos->longitude != NULL) isc_mem_free(gpos->mctx, gpos->longitude); if (gpos->latitude != NULL) isc_mem_free(gpos->mctx, gpos->latitude); if (gpos->altitude != NULL) isc_mem_free(gpos->mctx, gpos->altitude); gpos->mctx = NULL; } static inline isc_result_t additionaldata_gpos(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_gpos); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_gpos(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_gpos); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_gpos(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_gpos); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_gpos(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_gpos); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_gpos(ARGS_COMPARE) { return (compare_gpos(rdata1, rdata2)); } #endif /* RDATA_GENERIC_GPOS_27_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/naptr_35.c0000644000470500017500000003540012664710322021233 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007-2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* Reviewed: Thu Mar 16 16:52:50 PST 2000 by bwelling */ /* RFC2915 */ #ifndef RDATA_GENERIC_NAPTR_35_C #define RDATA_GENERIC_NAPTR_35_C #define RRTYPE_NAPTR_ATTRIBUTES (0) #include /* * Check the wire format of the Regexp field. * Don't allow embeded NUL's. */ static inline isc_result_t txt_valid_regex(const unsigned char *txt) { unsigned int nsub = 0; char regex[256]; char *cp; isc_boolean_t flags = ISC_FALSE; isc_boolean_t replace = ISC_FALSE; unsigned char c; unsigned char delim; unsigned int len; int n; len = *txt++; if (len == 0U) return (ISC_R_SUCCESS); delim = *txt++; len--; /* * Digits, backslash and flags can't be delimiters. */ switch (delim) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '\\': case 'i': case 0: return (DNS_R_SYNTAX); } cp = regex; while (len-- > 0) { c = *txt++; if (c == 0) return (DNS_R_SYNTAX); if (c == delim && !replace) { replace = ISC_TRUE; continue; } else if (c == delim && !flags) { flags = ISC_TRUE; continue; } else if (c == delim) return (DNS_R_SYNTAX); /* * Flags are not escaped. */ if (flags) { switch (c) { case 'i': continue; default: return (DNS_R_SYNTAX); } } if (!replace) *cp++ = c; if (c == '\\') { if (len == 0) return (DNS_R_SYNTAX); c = *txt++; if (c == 0) return (DNS_R_SYNTAX); len--; if (replace) switch (c) { case '0': return (DNS_R_SYNTAX); case '1': if (nsub < 1) nsub = 1; break; case '2': if (nsub < 2) nsub = 2; break; case '3': if (nsub < 3) nsub = 3; break; case '4': if (nsub < 4) nsub = 4; break; case '5': if (nsub < 5) nsub = 5; break; case '6': if (nsub < 6) nsub = 6; break; case '7': if (nsub < 7) nsub = 7; break; case '8': if (nsub < 8) nsub = 8; break; case '9': if (nsub < 9) nsub = 9; break; } if (!replace) *cp++ = c; } } if (!flags) return (DNS_R_SYNTAX); *cp = '\0'; n = isc_regex_validate(regex); if (n < 0 || nsub > (unsigned int)n) return (DNS_R_SYNTAX); return (ISC_R_SUCCESS); } static inline isc_result_t fromtext_naptr(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; unsigned char *regex; REQUIRE(type == dns_rdatatype_naptr); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); /* * Order. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Preference. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Flags. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, ISC_FALSE)); RETTOK(txt_fromtext(&token.value.as_textregion, target)); /* * Service. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, ISC_FALSE)); RETTOK(txt_fromtext(&token.value.as_textregion, target)); /* * Regexp. */ regex = isc_buffer_used(target); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, ISC_FALSE)); RETTOK(txt_fromtext(&token.value.as_textregion, target)); RETTOK(txt_valid_regex(regex)); /* * Replacement. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); return (ISC_R_SUCCESS); } static inline isc_result_t totext_naptr(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; char buf[sizeof("64000")]; unsigned short num; REQUIRE(rdata->type == dns_rdatatype_naptr); REQUIRE(rdata->length != 0); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, ®ion); /* * Order. */ num = uint16_fromregion(®ion); isc_region_consume(®ion, 2); sprintf(buf, "%u", num); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Preference. */ num = uint16_fromregion(®ion); isc_region_consume(®ion, 2); sprintf(buf, "%u", num); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Flags. */ RETERR(txt_totext(®ion, ISC_TRUE, target)); RETERR(str_totext(" ", target)); /* * Service. */ RETERR(txt_totext(®ion, ISC_TRUE, target)); RETERR(str_totext(" ", target)); /* * Regexp. */ RETERR(txt_totext(®ion, ISC_TRUE, target)); RETERR(str_totext(" ", target)); /* * Replacement. */ dns_name_fromregion(&name, ®ion); sub = name_prefix(&name, tctx->origin, &prefix); return (dns_name_totext(&prefix, sub, target)); } static inline isc_result_t fromwire_naptr(ARGS_FROMWIRE) { dns_name_t name; isc_region_t sr; unsigned char *regex; REQUIRE(type == dns_rdatatype_naptr); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); dns_name_init(&name, NULL); /* * Order, preference. */ isc_buffer_activeregion(source, &sr); if (sr.length < 4) return (ISC_R_UNEXPECTEDEND); RETERR(mem_tobuffer(target, sr.base, 4)); isc_buffer_forward(source, 4); /* * Flags. */ RETERR(txt_fromwire(source, target)); /* * Service. */ RETERR(txt_fromwire(source, target)); /* * Regexp. */ regex = isc_buffer_used(target); RETERR(txt_fromwire(source, target)); RETERR(txt_valid_regex(regex)); /* * Replacement. */ return (dns_name_fromwire(&name, source, dctx, options, target)); } static inline isc_result_t towire_naptr(ARGS_TOWIRE) { dns_name_t name; dns_offsets_t offsets; isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_naptr); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); /* * Order, preference. */ dns_rdata_toregion(rdata, &sr); RETERR(mem_tobuffer(target, sr.base, 4)); isc_region_consume(&sr, 4); /* * Flags. */ RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1)); isc_region_consume(&sr, sr.base[0] + 1); /* * Service. */ RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1)); isc_region_consume(&sr, sr.base[0] + 1); /* * Regexp. */ RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1)); isc_region_consume(&sr, sr.base[0] + 1); /* * Replacement. */ dns_name_init(&name, offsets); dns_name_fromregion(&name, &sr); return (dns_name_towire(&name, cctx, target)); } static inline int compare_naptr(ARGS_COMPARE) { dns_name_t name1; dns_name_t name2; isc_region_t region1; isc_region_t region2; int order, len; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_naptr); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); /* * Order, preference. */ order = memcmp(region1.base, region2.base, 4); if (order != 0) return (order < 0 ? -1 : 1); isc_region_consume(®ion1, 4); isc_region_consume(®ion2, 4); /* * Flags. */ len = ISC_MIN(region1.base[0], region2.base[0]); order = memcmp(region1.base, region2.base, len + 1); if (order != 0) return (order < 0 ? -1 : 1); isc_region_consume(®ion1, region1.base[0] + 1); isc_region_consume(®ion2, region2.base[0] + 1); /* * Service. */ len = ISC_MIN(region1.base[0], region2.base[0]); order = memcmp(region1.base, region2.base, len + 1); if (order != 0) return (order < 0 ? -1 : 1); isc_region_consume(®ion1, region1.base[0] + 1); isc_region_consume(®ion2, region2.base[0] + 1); /* * Regexp. */ len = ISC_MIN(region1.base[0], region2.base[0]); order = memcmp(region1.base, region2.base, len + 1); if (order != 0) return (order < 0 ? -1 : 1); isc_region_consume(®ion1, region1.base[0] + 1); isc_region_consume(®ion2, region2.base[0] + 1); /* * Replacement. */ dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); return (dns_name_rdatacompare(&name1, &name2)); } static inline isc_result_t fromstruct_naptr(ARGS_FROMSTRUCT) { dns_rdata_naptr_t *naptr = source; isc_region_t region; REQUIRE(type == dns_rdatatype_naptr); REQUIRE(source != NULL); REQUIRE(naptr->common.rdtype == type); REQUIRE(naptr->common.rdclass == rdclass); REQUIRE(naptr->flags != NULL || naptr->flags_len == 0); REQUIRE(naptr->service != NULL || naptr->service_len == 0); REQUIRE(naptr->regexp != NULL || naptr->regexp_len == 0); UNUSED(type); UNUSED(rdclass); RETERR(uint16_tobuffer(naptr->order, target)); RETERR(uint16_tobuffer(naptr->preference, target)); RETERR(uint8_tobuffer(naptr->flags_len, target)); RETERR(mem_tobuffer(target, naptr->flags, naptr->flags_len)); RETERR(uint8_tobuffer(naptr->service_len, target)); RETERR(mem_tobuffer(target, naptr->service, naptr->service_len)); RETERR(uint8_tobuffer(naptr->regexp_len, target)); RETERR(mem_tobuffer(target, naptr->regexp, naptr->regexp_len)); dns_name_toregion(&naptr->replacement, ®ion); return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_naptr(ARGS_TOSTRUCT) { dns_rdata_naptr_t *naptr = target; isc_region_t r; isc_result_t result; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_naptr); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); naptr->common.rdclass = rdata->rdclass; naptr->common.rdtype = rdata->type; ISC_LINK_INIT(&naptr->common, link); naptr->flags = NULL; naptr->service = NULL; naptr->regexp = NULL; dns_rdata_toregion(rdata, &r); naptr->order = uint16_fromregion(&r); isc_region_consume(&r, 2); naptr->preference = uint16_fromregion(&r); isc_region_consume(&r, 2); naptr->flags_len = uint8_fromregion(&r); isc_region_consume(&r, 1); INSIST(naptr->flags_len <= r.length); naptr->flags = mem_maybedup(mctx, r.base, naptr->flags_len); if (naptr->flags == NULL) goto cleanup; isc_region_consume(&r, naptr->flags_len); naptr->service_len = uint8_fromregion(&r); isc_region_consume(&r, 1); INSIST(naptr->service_len <= r.length); naptr->service = mem_maybedup(mctx, r.base, naptr->service_len); if (naptr->service == NULL) goto cleanup; isc_region_consume(&r, naptr->service_len); naptr->regexp_len = uint8_fromregion(&r); isc_region_consume(&r, 1); INSIST(naptr->regexp_len <= r.length); naptr->regexp = mem_maybedup(mctx, r.base, naptr->regexp_len); if (naptr->regexp == NULL) goto cleanup; isc_region_consume(&r, naptr->regexp_len); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); dns_name_init(&naptr->replacement, NULL); result = name_duporclone(&name, mctx, &naptr->replacement); if (result != ISC_R_SUCCESS) goto cleanup; naptr->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (mctx != NULL && naptr->flags != NULL) isc_mem_free(mctx, naptr->flags); if (mctx != NULL && naptr->service != NULL) isc_mem_free(mctx, naptr->service); if (mctx != NULL && naptr->regexp != NULL) isc_mem_free(mctx, naptr->regexp); return (ISC_R_NOMEMORY); } static inline void freestruct_naptr(ARGS_FREESTRUCT) { dns_rdata_naptr_t *naptr = source; REQUIRE(source != NULL); REQUIRE(naptr->common.rdtype == dns_rdatatype_naptr); if (naptr->mctx == NULL) return; if (naptr->flags != NULL) isc_mem_free(naptr->mctx, naptr->flags); if (naptr->service != NULL) isc_mem_free(naptr->mctx, naptr->service); if (naptr->regexp != NULL) isc_mem_free(naptr->mctx, naptr->regexp); dns_name_free(&naptr->replacement, naptr->mctx); naptr->mctx = NULL; } static inline isc_result_t additionaldata_naptr(ARGS_ADDLDATA) { dns_name_t name; dns_offsets_t offsets; isc_region_t sr; dns_rdatatype_t atype; unsigned int i, flagslen; char *cp; REQUIRE(rdata->type == dns_rdatatype_naptr); /* * Order, preference. */ dns_rdata_toregion(rdata, &sr); isc_region_consume(&sr, 4); /* * Flags. */ atype = 0; flagslen = sr.base[0]; cp = (char *)&sr.base[1]; for (i = 0; i < flagslen; i++, cp++) { if (*cp == 'S' || *cp == 's') { atype = dns_rdatatype_srv; break; } if (*cp == 'A' || *cp == 'a') { atype = dns_rdatatype_a; break; } } isc_region_consume(&sr, flagslen + 1); /* * Service. */ isc_region_consume(&sr, sr.base[0] + 1); /* * Regexp. */ isc_region_consume(&sr, sr.base[0] + 1); /* * Replacement. */ dns_name_init(&name, offsets); dns_name_fromregion(&name, &sr); if (atype != 0) return ((add)(arg, &name, atype)); return (ISC_R_SUCCESS); } static inline isc_result_t digest_naptr(ARGS_DIGEST) { isc_region_t r1, r2; unsigned int length, n; isc_result_t result; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_naptr); dns_rdata_toregion(rdata, &r1); r2 = r1; length = 0; /* * Order, preference. */ length += 4; isc_region_consume(&r2, 4); /* * Flags. */ n = r2.base[0] + 1; length += n; isc_region_consume(&r2, n); /* * Service. */ n = r2.base[0] + 1; length += n; isc_region_consume(&r2, n); /* * Regexp. */ n = r2.base[0] + 1; length += n; isc_region_consume(&r2, n); /* * Digest the RR up to the replacement name. */ r1.length = length; result = (digest)(arg, &r1); if (result != ISC_R_SUCCESS) return (result); /* * Replacement. */ dns_name_init(&name, NULL); dns_name_fromregion(&name, &r2); return (dns_name_digest(&name, digest, arg)); } static inline isc_boolean_t checkowner_naptr(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_naptr); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_naptr(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_naptr); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_naptr(ARGS_COMPARE) { return (compare_naptr(rdata1, rdata2)); } #endif /* RDATA_GENERIC_NAPTR_35_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/key_25.h0000644000470500017500000000242712664710322020706 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_KEY_25_H #define GENERIC_KEY_25_H 1 /* $Id: key_25.h,v 1.19 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief Per RFC2535 */ typedef struct dns_rdata_key_t { dns_rdatacommon_t common; isc_mem_t * mctx; isc_uint16_t flags; isc_uint8_t protocol; isc_uint8_t algorithm; isc_uint16_t datalen; unsigned char * data; } dns_rdata_key_t; #endif /* GENERIC_KEY_25_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/eui64_109.c0000644000470500017500000001210512664710322021122 0ustar lamontlamont/* * Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef RDATA_GENERIC_EUI64_109_C #define RDATA_GENERIC_EUI64_109_C #include #define RRTYPE_EUI64_ATTRIBUTES (0) static inline isc_result_t fromtext_eui64(ARGS_FROMTEXT) { isc_token_t token; unsigned char eui64[8]; unsigned int l0, l1, l2, l3, l4, l5, l6, l7; int n; REQUIRE(type == dns_rdatatype_eui64); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); n = sscanf(DNS_AS_STR(token), "%2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x", &l0, &l1, &l2, &l3, &l4, &l5, &l6, &l7); if (n != 8 || l0 > 255U || l1 > 255U || l2 > 255U || l3 > 255U || l4 > 255U || l5 > 255U || l6 > 255U || l7 > 255U) return (DNS_R_BADEUI); eui64[0] = l0; eui64[1] = l1; eui64[2] = l2; eui64[3] = l3; eui64[4] = l4; eui64[5] = l5; eui64[6] = l6; eui64[7] = l7; return (mem_tobuffer(target, eui64, sizeof(eui64))); } static inline isc_result_t totext_eui64(ARGS_TOTEXT) { char buf[sizeof("xx-xx-xx-xx-xx-xx-xx-xx")]; REQUIRE(rdata->type == dns_rdatatype_eui64); REQUIRE(rdata->length == 8); UNUSED(tctx); (void)snprintf(buf, sizeof(buf), "%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x", rdata->data[0], rdata->data[1], rdata->data[2], rdata->data[3], rdata->data[4], rdata->data[5], rdata->data[6], rdata->data[7]); return (str_totext(buf, target)); } static inline isc_result_t fromwire_eui64(ARGS_FROMWIRE) { isc_region_t sregion; REQUIRE(type == dns_rdatatype_eui64); UNUSED(type); UNUSED(options); UNUSED(rdclass); UNUSED(dctx); isc_buffer_activeregion(source, &sregion); if (sregion.length != 8) return (DNS_R_FORMERR); isc_buffer_forward(source, sregion.length); return (mem_tobuffer(target, sregion.base, sregion.length)); } static inline isc_result_t towire_eui64(ARGS_TOWIRE) { REQUIRE(rdata->type == dns_rdatatype_eui64); REQUIRE(rdata->length == 8); UNUSED(cctx); return (mem_tobuffer(target, rdata->data, rdata->length)); } static inline int compare_eui64(ARGS_COMPARE) { isc_region_t region1; isc_region_t region2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_eui64); REQUIRE(rdata1->length == 8); REQUIRE(rdata2->length == 8); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); return (isc_region_compare(®ion1, ®ion2)); } static inline isc_result_t fromstruct_eui64(ARGS_FROMSTRUCT) { dns_rdata_eui64_t *eui64 = source; REQUIRE(type == dns_rdatatype_eui64); REQUIRE(source != NULL); REQUIRE(eui64->common.rdtype == type); REQUIRE(eui64->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); return (mem_tobuffer(target, eui64->eui64, sizeof(eui64->eui64))); } static inline isc_result_t tostruct_eui64(ARGS_TOSTRUCT) { dns_rdata_eui64_t *eui64 = target; REQUIRE(rdata->type == dns_rdatatype_eui64); REQUIRE(target != NULL); REQUIRE(rdata->length == 8); UNUSED(mctx); eui64->common.rdclass = rdata->rdclass; eui64->common.rdtype = rdata->type; ISC_LINK_INIT(&eui64->common, link); memmove(eui64->eui64, rdata->data, rdata->length); return (ISC_R_SUCCESS); } static inline void freestruct_eui64(ARGS_FREESTRUCT) { dns_rdata_eui64_t *eui64 = source; REQUIRE(source != NULL); REQUIRE(eui64->common.rdtype == dns_rdatatype_eui64); return; } static inline isc_result_t additionaldata_eui64(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_eui64); REQUIRE(rdata->length == 8); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_eui64(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_eui64); REQUIRE(rdata->length == 8); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_eui64(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_eui64); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_eui64(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_eui64); REQUIRE(rdata->length == 8); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_eui64(ARGS_COMPARE) { return (compare_eui64(rdata1, rdata2)); } #endif /* RDATA_GENERIC_EUI64_109_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/nxt_30.c0000644000470500017500000002026312664710322020714 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: nxt_30.c,v 1.65 2009/12/04 22:06:37 tbox Exp $ */ /* reviewed: Wed Mar 15 18:21:15 PST 2000 by brister */ /* RFC2535 */ #ifndef RDATA_GENERIC_NXT_30_C #define RDATA_GENERIC_NXT_30_C /* * The attributes do not include DNS_RDATATYPEATTR_SINGLETON * because we must be able to handle a parent/child NXT pair. */ #define RRTYPE_NXT_ATTRIBUTES (0) static inline isc_result_t fromtext_nxt(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; char *e; unsigned char bm[8*1024]; /* 64k bits */ dns_rdatatype_t covered; dns_rdatatype_t maxcovered = 0; isc_boolean_t first = ISC_TRUE; long n; REQUIRE(type == dns_rdatatype_nxt); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); /* * Next domain. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); memset(bm, 0, sizeof(bm)); do { RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_TRUE)); if (token.type != isc_tokentype_string) break; n = strtol(DNS_AS_STR(token), &e, 10); if (e != DNS_AS_STR(token) && *e == '\0') { covered = (dns_rdatatype_t)n; } else if (dns_rdatatype_fromtext(&covered, &token.value.as_textregion) == DNS_R_UNKNOWN) RETTOK(DNS_R_UNKNOWN); /* * NXT is only specified for types 1..127. */ if (covered < 1 || covered > 127) return (ISC_R_RANGE); if (first || covered > maxcovered) maxcovered = covered; first = ISC_FALSE; bm[covered/8] |= (0x80>>(covered%8)); } while (1); isc_lex_ungettoken(lexer, &token); if (first) return (ISC_R_SUCCESS); n = (maxcovered + 8) / 8; return (mem_tobuffer(target, bm, n)); } static inline isc_result_t totext_nxt(ARGS_TOTEXT) { isc_region_t sr; unsigned int i, j; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; REQUIRE(rdata->type == dns_rdatatype_nxt); REQUIRE(rdata->length != 0); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, &sr); dns_name_fromregion(&name, &sr); isc_region_consume(&sr, name_length(&name)); sub = name_prefix(&name, tctx->origin, &prefix); RETERR(dns_name_totext(&prefix, sub, target)); for (i = 0; i < sr.length; i++) { if (sr.base[i] != 0) for (j = 0; j < 8; j++) if ((sr.base[i] & (0x80 >> j)) != 0) { dns_rdatatype_t t = i * 8 + j; RETERR(str_totext(" ", target)); if (dns_rdatatype_isknown(t)) { RETERR(dns_rdatatype_totext(t, target)); } else { char buf[sizeof("65535")]; sprintf(buf, "%u", t); RETERR(str_totext(buf, target)); } } } return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_nxt(ARGS_FROMWIRE) { isc_region_t sr; dns_name_t name; REQUIRE(type == dns_rdatatype_nxt); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); dns_name_init(&name, NULL); RETERR(dns_name_fromwire(&name, source, dctx, options, target)); isc_buffer_activeregion(source, &sr); if (sr.length > 0 && (sr.base[0] & 0x80) == 0 && ((sr.length > 16) || sr.base[sr.length - 1] == 0)) return (DNS_R_BADBITMAP); RETERR(mem_tobuffer(target, sr.base, sr.length)); isc_buffer_forward(source, sr.length); return (ISC_R_SUCCESS); } static inline isc_result_t towire_nxt(ARGS_TOWIRE) { isc_region_t sr; dns_name_t name; dns_offsets_t offsets; REQUIRE(rdata->type == dns_rdatatype_nxt); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, &sr); dns_name_fromregion(&name, &sr); isc_region_consume(&sr, name_length(&name)); RETERR(dns_name_towire(&name, cctx, target)); return (mem_tobuffer(target, sr.base, sr.length)); } static inline int compare_nxt(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; dns_name_t name1; dns_name_t name2; int order; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_nxt); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); dns_name_fromregion(&name1, &r1); dns_name_fromregion(&name2, &r2); order = dns_name_rdatacompare(&name1, &name2); if (order != 0) return (order); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_nxt(ARGS_FROMSTRUCT) { dns_rdata_nxt_t *nxt = source; isc_region_t region; REQUIRE(type == dns_rdatatype_nxt); REQUIRE(source != NULL); REQUIRE(nxt->common.rdtype == type); REQUIRE(nxt->common.rdclass == rdclass); REQUIRE(nxt->typebits != NULL || nxt->len == 0); if (nxt->typebits != NULL && (nxt->typebits[0] & 0x80) == 0) { REQUIRE(nxt->len <= 16); REQUIRE(nxt->typebits[nxt->len - 1] != 0); } UNUSED(type); UNUSED(rdclass); dns_name_toregion(&nxt->next, ®ion); RETERR(isc_buffer_copyregion(target, ®ion)); return (mem_tobuffer(target, nxt->typebits, nxt->len)); } static inline isc_result_t tostruct_nxt(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_nxt_t *nxt = target; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_nxt); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); nxt->common.rdclass = rdata->rdclass; nxt->common.rdtype = rdata->type; ISC_LINK_INIT(&nxt->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); isc_region_consume(®ion, name_length(&name)); dns_name_init(&nxt->next, NULL); RETERR(name_duporclone(&name, mctx, &nxt->next)); nxt->len = region.length; nxt->typebits = mem_maybedup(mctx, region.base, region.length); if (nxt->typebits == NULL) goto cleanup; nxt->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (mctx != NULL) dns_name_free(&nxt->next, mctx); return (ISC_R_NOMEMORY); } static inline void freestruct_nxt(ARGS_FREESTRUCT) { dns_rdata_nxt_t *nxt = source; REQUIRE(source != NULL); REQUIRE(nxt->common.rdtype == dns_rdatatype_nxt); if (nxt->mctx == NULL) return; dns_name_free(&nxt->next, nxt->mctx); if (nxt->typebits != NULL) isc_mem_free(nxt->mctx, nxt->typebits); nxt->mctx = NULL; } static inline isc_result_t additionaldata_nxt(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_nxt); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_nxt(ARGS_DIGEST) { isc_region_t r; dns_name_t name; isc_result_t result; REQUIRE(rdata->type == dns_rdatatype_nxt); dns_rdata_toregion(rdata, &r); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); result = dns_name_digest(&name, digest, arg); if (result != ISC_R_SUCCESS) return (result); isc_region_consume(&r, name_length(&name)); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_nxt(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_nxt); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_nxt(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_nxt); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_nxt(ARGS_COMPARE) { return (compare_nxt(rdata1, rdata2)); } #endif /* RDATA_GENERIC_NXT_30_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/nsec_47.h0000644000470500017500000000226512664710322021052 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_NSEC_47_H #define GENERIC_NSEC_47_H 1 /* $Id: nsec_47.h,v 1.10 2008/07/15 23:47:21 tbox Exp $ */ /*! * \brief Per RFC 3845 */ typedef struct dns_rdata_nsec { dns_rdatacommon_t common; isc_mem_t *mctx; dns_name_t next; unsigned char *typebits; isc_uint16_t len; } dns_rdata_nsec_t; #endif /* GENERIC_NSEC_47_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/sshfp_44.c0000644000470500017500000001376212664710322021241 0ustar lamontlamont/* * Copyright (C) 2004, 2006, 2007, 2009, 2011-2013, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* RFC 4255 */ #ifndef RDATA_GENERIC_SSHFP_44_C #define RDATA_GENERIC_SSHFP_44_C #define RRTYPE_SSHFP_ATTRIBUTES (0) static inline isc_result_t fromtext_sshfp(ARGS_FROMTEXT) { isc_token_t token; REQUIRE(type == dns_rdatatype_sshfp); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); /* * Algorithm. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffU) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer(token.value.as_ulong, target)); /* * Digest type. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffU) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer(token.value.as_ulong, target)); /* * Digest. */ return (isc_hex_tobuffer(lexer, target, -1)); } static inline isc_result_t totext_sshfp(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("64000 ")]; unsigned int n; REQUIRE(rdata->type == dns_rdatatype_sshfp); REQUIRE(rdata->length != 0); UNUSED(tctx); dns_rdata_toregion(rdata, &sr); /* * Algorithm. */ n = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u ", n); RETERR(str_totext(buf, target)); /* * Digest type. */ n = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u", n); RETERR(str_totext(buf, target)); /* * Digest. */ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); if (tctx->width == 0) /* No splitting */ RETERR(isc_hex_totext(&sr, 0, "", target)); else RETERR(isc_hex_totext(&sr, tctx->width - 2, tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_sshfp(ARGS_FROMWIRE) { isc_region_t sr; REQUIRE(type == dns_rdatatype_sshfp); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); isc_buffer_activeregion(source, &sr); if (sr.length < 4) return (ISC_R_UNEXPECTEDEND); isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); } static inline isc_result_t towire_sshfp(ARGS_TOWIRE) { isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_sshfp); REQUIRE(rdata->length != 0); UNUSED(cctx); dns_rdata_toregion(rdata, &sr); return (mem_tobuffer(target, sr.base, sr.length)); } static inline int compare_sshfp(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_sshfp); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_sshfp(ARGS_FROMSTRUCT) { dns_rdata_sshfp_t *sshfp = source; REQUIRE(type == dns_rdatatype_sshfp); REQUIRE(source != NULL); REQUIRE(sshfp->common.rdtype == type); REQUIRE(sshfp->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); RETERR(uint8_tobuffer(sshfp->algorithm, target)); RETERR(uint8_tobuffer(sshfp->digest_type, target)); return (mem_tobuffer(target, sshfp->digest, sshfp->length)); } static inline isc_result_t tostruct_sshfp(ARGS_TOSTRUCT) { dns_rdata_sshfp_t *sshfp = target; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_sshfp); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); sshfp->common.rdclass = rdata->rdclass; sshfp->common.rdtype = rdata->type; ISC_LINK_INIT(&sshfp->common, link); dns_rdata_toregion(rdata, ®ion); sshfp->algorithm = uint8_fromregion(®ion); isc_region_consume(®ion, 1); sshfp->digest_type = uint8_fromregion(®ion); isc_region_consume(®ion, 1); sshfp->length = region.length; sshfp->digest = mem_maybedup(mctx, region.base, region.length); if (sshfp->digest == NULL) return (ISC_R_NOMEMORY); sshfp->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_sshfp(ARGS_FREESTRUCT) { dns_rdata_sshfp_t *sshfp = source; REQUIRE(sshfp != NULL); REQUIRE(sshfp->common.rdtype == dns_rdatatype_sshfp); if (sshfp->mctx == NULL) return; if (sshfp->digest != NULL) isc_mem_free(sshfp->mctx, sshfp->digest); sshfp->mctx = NULL; } static inline isc_result_t additionaldata_sshfp(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_sshfp); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_sshfp(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_sshfp); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_sshfp(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_sshfp); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_sshfp(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_sshfp); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_sshfp(ARGS_COMPARE) { return (compare_sshfp(rdata1, rdata2)); } #endif /* RDATA_GENERIC_SSHFP_44_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/tlsa_52.h0000644000470500017500000000216612664710322021061 0ustar lamontlamont/* * Copyright (C) 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef GENERIC_TLSA_52_H #define GENERIC_TLSA_52_H 1 /*! * \brief per rfc6698.txt */ typedef struct dns_rdata_tlsa { dns_rdatacommon_t common; isc_mem_t *mctx; isc_uint8_t usage; isc_uint8_t selector; isc_uint8_t match; isc_uint16_t length; unsigned char *data; } dns_rdata_tlsa_t; #endif /* GENERIC_TLSA_52_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/isdn_20.h0000644000470500017500000000231312664710322021040 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_ISDN_20_H #define GENERIC_ISDN_20_H 1 /* $Id: isdn_20.h,v 1.18 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief Per RFC1183 */ typedef struct dns_rdata_isdn { dns_rdatacommon_t common; isc_mem_t *mctx; char *isdn; char *subaddress; isc_uint8_t isdn_len; isc_uint8_t subaddress_len; } dns_rdata_isdn_t; #endif /* GENERIC_ISDN_20_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/hip_55.h0000644000470500017500000000262112664710322020675 0ustar lamontlamont/* * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: hip_55.h,v 1.2 2009/02/26 06:09:19 marka Exp $ */ #ifndef GENERIC_HIP_5_H #define GENERIC_HIP_5_H 1 /* RFC 5205 */ typedef struct dns_rdata_hip { dns_rdatacommon_t common; isc_mem_t * mctx; unsigned char * hit; unsigned char * key; unsigned char * servers; isc_uint8_t algorithm; isc_uint8_t hit_len; isc_uint16_t key_len; isc_uint16_t servers_len; /* Private */ isc_uint16_t offset; } dns_rdata_hip_t; isc_result_t dns_rdata_hip_first(dns_rdata_hip_t *); isc_result_t dns_rdata_hip_next(dns_rdata_hip_t *); void dns_rdata_hip_current(dns_rdata_hip_t *, dns_name_t *); #endif /* GENERIC_HIP_5_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/mr_9.h0000644000470500017500000000213212664710322020447 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef GENERIC_MR_9_H #define GENERIC_MR_9_H 1 /* $Id: mr_9.h,v 1.26 2007/06/19 23:47:17 tbox Exp $ */ typedef struct dns_rdata_mr { dns_rdatacommon_t common; isc_mem_t *mctx; dns_name_t mr; } dns_rdata_mr_t; #endif /* GENERIC_MR_9_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/sig_24.c0000644000470500017500000003055012664710322020670 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* Reviewed: Fri Mar 17 09:05:02 PST 2000 by gson */ /* RFC2535 */ #ifndef RDATA_GENERIC_SIG_24_C #define RDATA_GENERIC_SIG_24_C #define RRTYPE_SIG_ATTRIBUTES (0) static inline isc_result_t fromtext_sig(ARGS_FROMTEXT) { isc_token_t token; unsigned char c; long i; dns_rdatatype_t covered; char *e; isc_result_t result; dns_name_t name; isc_buffer_t buffer; isc_uint32_t time_signed, time_expire; REQUIRE(type == dns_rdatatype_sig); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); /* * Type covered. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); result = dns_rdatatype_fromtext(&covered, &token.value.as_textregion); if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) { i = strtol(DNS_AS_STR(token), &e, 10); if (i < 0 || i > 65535) RETTOK(ISC_R_RANGE); if (*e != 0) RETTOK(result); covered = (dns_rdatatype_t)i; } RETERR(uint16_tobuffer(covered, target)); /* * Algorithm. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion)); RETERR(mem_tobuffer(target, &c, 1)); /* * Labels. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffU) RETTOK(ISC_R_RANGE); c = (unsigned char)token.value.as_ulong; RETERR(mem_tobuffer(target, &c, 1)); /* * Original ttl. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); RETERR(uint32_tobuffer(token.value.as_ulong, target)); /* * Signature expiration. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_expire)); RETERR(uint32_tobuffer(time_expire, target)); /* * Time signed. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_signed)); RETERR(uint32_tobuffer(time_signed, target)); /* * Key footprint. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Signer. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); /* * Sig. */ return (isc_base64_tobuffer(lexer, target, -1)); } static inline isc_result_t totext_sig(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("4294967295")]; dns_rdatatype_t covered; unsigned long ttl; unsigned long when; unsigned long exp; unsigned long foot; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; REQUIRE(rdata->type == dns_rdatatype_sig); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); /* * Type covered. */ covered = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * XXXAG We should have something like dns_rdatatype_isknown() * that does the right thing with type 0. */ if (dns_rdatatype_isknown(covered) && covered != 0) { RETERR(dns_rdatatype_totext(covered, target)); } else { sprintf(buf, "%u", covered); RETERR(str_totext(buf, target)); } RETERR(str_totext(" ", target)); /* * Algorithm. */ sprintf(buf, "%u", sr.base[0]); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Labels. */ sprintf(buf, "%u", sr.base[0]); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Ttl. */ ttl = uint32_fromregion(&sr); isc_region_consume(&sr, 4); sprintf(buf, "%lu", ttl); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Sig exp. */ exp = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(exp, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); /* * Time signed. */ when = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(when, target)); RETERR(str_totext(" ", target)); /* * Footprint. */ foot = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%lu", foot); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Signer. */ dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_name_fromregion(&name, &sr); isc_region_consume(&sr, name_length(&name)); sub = name_prefix(&name, tctx->origin, &prefix); RETERR(dns_name_totext(&prefix, sub, target)); /* * Sig. */ RETERR(str_totext(tctx->linebreak, target)); if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(&sr, 60, "", target)); else RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_sig(ARGS_FROMWIRE) { isc_region_t sr; dns_name_t name; REQUIRE(type == dns_rdatatype_sig); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); isc_buffer_activeregion(source, &sr); /* * type covered: 2 * algorithm: 1 * labels: 1 * original ttl: 4 * signature expiration: 4 * time signed: 4 * key footprint: 2 */ if (sr.length < 18) return (ISC_R_UNEXPECTEDEND); isc_buffer_forward(source, 18); RETERR(mem_tobuffer(target, sr.base, 18)); /* * Signer. */ dns_name_init(&name, NULL); RETERR(dns_name_fromwire(&name, source, dctx, options, target)); /* * Sig. */ isc_buffer_activeregion(source, &sr); isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); } static inline isc_result_t towire_sig(ARGS_TOWIRE) { isc_region_t sr; dns_name_t name; dns_offsets_t offsets; REQUIRE(rdata->type == dns_rdatatype_sig); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); dns_rdata_toregion(rdata, &sr); /* * type covered: 2 * algorithm: 1 * labels: 1 * original ttl: 4 * signature expiration: 4 * time signed: 4 * key footprint: 2 */ RETERR(mem_tobuffer(target, sr.base, 18)); isc_region_consume(&sr, 18); /* * Signer. */ dns_name_init(&name, offsets); dns_name_fromregion(&name, &sr); isc_region_consume(&sr, name_length(&name)); RETERR(dns_name_towire(&name, cctx, target)); /* * Signature. */ return (mem_tobuffer(target, sr.base, sr.length)); } static inline int compare_sig(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; dns_name_t name1; dns_name_t name2; int order; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_sig); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); INSIST(r1.length > 18); INSIST(r2.length > 18); r1.length = 18; r2.length = 18; order = isc_region_compare(&r1, &r2); if (order != 0) return (order); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); isc_region_consume(&r1, 18); isc_region_consume(&r2, 18); dns_name_fromregion(&name1, &r1); dns_name_fromregion(&name2, &r2); order = dns_name_rdatacompare(&name1, &name2); if (order != 0) return (order); isc_region_consume(&r1, name_length(&name1)); isc_region_consume(&r2, name_length(&name2)); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_sig(ARGS_FROMSTRUCT) { dns_rdata_sig_t *sig = source; REQUIRE(type == dns_rdatatype_sig); REQUIRE(source != NULL); REQUIRE(sig->common.rdtype == type); REQUIRE(sig->common.rdclass == rdclass); REQUIRE(sig->signature != NULL || sig->siglen == 0); UNUSED(type); UNUSED(rdclass); /* * Type covered. */ RETERR(uint16_tobuffer(sig->covered, target)); /* * Algorithm. */ RETERR(uint8_tobuffer(sig->algorithm, target)); /* * Labels. */ RETERR(uint8_tobuffer(sig->labels, target)); /* * Original TTL. */ RETERR(uint32_tobuffer(sig->originalttl, target)); /* * Expire time. */ RETERR(uint32_tobuffer(sig->timeexpire, target)); /* * Time signed. */ RETERR(uint32_tobuffer(sig->timesigned, target)); /* * Key ID. */ RETERR(uint16_tobuffer(sig->keyid, target)); /* * Signer name. */ RETERR(name_tobuffer(&sig->signer, target)); /* * Signature. */ return (mem_tobuffer(target, sig->signature, sig->siglen)); } static inline isc_result_t tostruct_sig(ARGS_TOSTRUCT) { isc_region_t sr; dns_rdata_sig_t *sig = target; dns_name_t signer; REQUIRE(rdata->type == dns_rdatatype_sig); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); sig->common.rdclass = rdata->rdclass; sig->common.rdtype = rdata->type; ISC_LINK_INIT(&sig->common, link); dns_rdata_toregion(rdata, &sr); /* * Type covered. */ sig->covered = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * Algorithm. */ sig->algorithm = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* * Labels. */ sig->labels = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* * Original TTL. */ sig->originalttl = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* * Expire time. */ sig->timeexpire = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* * Time signed. */ sig->timesigned = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* * Key ID. */ sig->keyid = uint16_fromregion(&sr); isc_region_consume(&sr, 2); dns_name_init(&signer, NULL); dns_name_fromregion(&signer, &sr); dns_name_init(&sig->signer, NULL); RETERR(name_duporclone(&signer, mctx, &sig->signer)); isc_region_consume(&sr, name_length(&sig->signer)); /* * Signature. */ sig->siglen = sr.length; sig->signature = mem_maybedup(mctx, sr.base, sig->siglen); if (sig->signature == NULL) goto cleanup; sig->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (mctx != NULL) dns_name_free(&sig->signer, mctx); return (ISC_R_NOMEMORY); } static inline void freestruct_sig(ARGS_FREESTRUCT) { dns_rdata_sig_t *sig = (dns_rdata_sig_t *) source; REQUIRE(source != NULL); REQUIRE(sig->common.rdtype == dns_rdatatype_sig); if (sig->mctx == NULL) return; dns_name_free(&sig->signer, sig->mctx); if (sig->signature != NULL) isc_mem_free(sig->mctx, sig->signature); sig->mctx = NULL; } static inline isc_result_t additionaldata_sig(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_sig); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_sig(ARGS_DIGEST) { REQUIRE(rdata->type == dns_rdatatype_sig); UNUSED(rdata); UNUSED(digest); UNUSED(arg); return (ISC_R_NOTIMPLEMENTED); } static inline dns_rdatatype_t covers_sig(dns_rdata_t *rdata) { dns_rdatatype_t type; isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_sig); dns_rdata_toregion(rdata, &r); type = uint16_fromregion(&r); return (type); } static inline isc_boolean_t checkowner_sig(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_sig); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_sig(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_sig); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_sig(ARGS_COMPARE) { return (compare_sig(rdata1, rdata2)); } #endif /* RDATA_GENERIC_SIG_24_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/mx_15.c0000644000470500017500000001754212664710322020540 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2012, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: mx_15.c,v 1.58 2009/12/04 22:06:37 tbox Exp $ */ /* reviewed: Wed Mar 15 18:05:46 PST 2000 by brister */ #ifndef RDATA_GENERIC_MX_15_C #define RDATA_GENERIC_MX_15_C #include #include #define RRTYPE_MX_ATTRIBUTES (0) static isc_boolean_t check_mx(isc_token_t *token) { char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123.")]; struct in_addr addr; struct in6_addr addr6; if (strlcpy(tmp, DNS_AS_STR(*token), sizeof(tmp)) >= sizeof(tmp)) return (ISC_TRUE); if (tmp[strlen(tmp) - 1] == '.') tmp[strlen(tmp) - 1] = '\0'; if (inet_aton(tmp, &addr) == 1 || inet_pton(AF_INET6, tmp, &addr6) == 1) return (ISC_FALSE); return (ISC_TRUE); } static inline isc_result_t fromtext_mx(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; isc_boolean_t ok; REQUIRE(type == dns_rdatatype_mx); UNUSED(type); UNUSED(rdclass); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); ok = ISC_TRUE; if ((options & DNS_RDATA_CHECKMX) != 0) ok = check_mx(&token); if (!ok && (options & DNS_RDATA_CHECKMXFAIL) != 0) RETTOK(DNS_R_MXISADDRESS); if (!ok && callbacks != NULL) warn_badmx(&token, lexer, callbacks); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); ok = ISC_TRUE; if ((options & DNS_RDATA_CHECKNAMES) != 0) ok = dns_name_ishostname(&name, ISC_FALSE); if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) RETTOK(DNS_R_BADNAME); if (!ok && callbacks != NULL) warn_badname(&name, lexer, callbacks); return (ISC_R_SUCCESS); } static inline isc_result_t totext_mx(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; char buf[sizeof("64000")]; unsigned short num; REQUIRE(rdata->type == dns_rdatatype_mx); REQUIRE(rdata->length != 0); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, ®ion); num = uint16_fromregion(®ion); isc_region_consume(®ion, 2); sprintf(buf, "%u", num); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); dns_name_fromregion(&name, ®ion); sub = name_prefix(&name, tctx->origin, &prefix); return (dns_name_totext(&prefix, sub, target)); } static inline isc_result_t fromwire_mx(ARGS_FROMWIRE) { dns_name_t name; isc_region_t sregion; REQUIRE(type == dns_rdatatype_mx); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, NULL); isc_buffer_activeregion(source, &sregion); if (sregion.length < 2) return (ISC_R_UNEXPECTEDEND); RETERR(mem_tobuffer(target, sregion.base, 2)); isc_buffer_forward(source, 2); return (dns_name_fromwire(&name, source, dctx, options, target)); } static inline isc_result_t towire_mx(ARGS_TOWIRE) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_mx); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); dns_rdata_toregion(rdata, ®ion); RETERR(mem_tobuffer(target, region.base, 2)); isc_region_consume(®ion, 2); dns_name_init(&name, offsets); dns_name_fromregion(&name, ®ion); return (dns_name_towire(&name, cctx, target)); } static inline int compare_mx(ARGS_COMPARE) { dns_name_t name1; dns_name_t name2; isc_region_t region1; isc_region_t region2; int order; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_mx); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); order = memcmp(rdata1->data, rdata2->data, 2); if (order != 0) return (order < 0 ? -1 : 1); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); isc_region_consume(®ion1, 2); isc_region_consume(®ion2, 2); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); return (dns_name_rdatacompare(&name1, &name2)); } static inline isc_result_t fromstruct_mx(ARGS_FROMSTRUCT) { dns_rdata_mx_t *mx = source; isc_region_t region; REQUIRE(type == dns_rdatatype_mx); REQUIRE(source != NULL); REQUIRE(mx->common.rdtype == type); REQUIRE(mx->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); RETERR(uint16_tobuffer(mx->pref, target)); dns_name_toregion(&mx->mx, ®ion); return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_mx(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_mx_t *mx = target; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_mx); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); mx->common.rdclass = rdata->rdclass; mx->common.rdtype = rdata->type; ISC_LINK_INIT(&mx->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); mx->pref = uint16_fromregion(®ion); isc_region_consume(®ion, 2); dns_name_fromregion(&name, ®ion); dns_name_init(&mx->mx, NULL); RETERR(name_duporclone(&name, mctx, &mx->mx)); mx->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_mx(ARGS_FREESTRUCT) { dns_rdata_mx_t *mx = source; REQUIRE(source != NULL); REQUIRE(mx->common.rdtype == dns_rdatatype_mx); if (mx->mctx == NULL) return; dns_name_free(&mx->mx, mx->mctx); mx->mctx = NULL; } static inline isc_result_t additionaldata_mx(ARGS_ADDLDATA) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_mx); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, ®ion); isc_region_consume(®ion, 2); dns_name_fromregion(&name, ®ion); return ((add)(arg, &name, dns_rdatatype_a)); } static inline isc_result_t digest_mx(ARGS_DIGEST) { isc_region_t r1, r2; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_mx); dns_rdata_toregion(rdata, &r1); r2 = r1; isc_region_consume(&r2, 2); r1.length = 2; RETERR((digest)(arg, &r1)); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r2); return (dns_name_digest(&name, digest, arg)); } static inline isc_boolean_t checkowner_mx(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_mx); UNUSED(type); UNUSED(rdclass); return (dns_name_ishostname(name, wildcard)); } static inline isc_boolean_t checknames_mx(ARGS_CHECKNAMES) { isc_region_t region; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_mx); UNUSED(owner); dns_rdata_toregion(rdata, ®ion); isc_region_consume(®ion, 2); dns_name_init(&name, NULL); dns_name_fromregion(&name, ®ion); if (!dns_name_ishostname(&name, ISC_FALSE)) { if (bad != NULL) dns_name_clone(&name, bad); return (ISC_FALSE); } return (ISC_TRUE); } static inline int casecompare_mx(ARGS_COMPARE) { return (compare_mx(rdata1, rdata2)); } #endif /* RDATA_GENERIC_MX_15_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/hip_55.c0000644000470500017500000002765712664710322020710 0ustar lamontlamont/* * Copyright (C) 2009, 2011, 2013-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: hip_55.c,v 1.8 2011/01/13 04:59:26 tbox Exp $ */ /* reviewed: TBC */ /* RFC 5205 */ #ifndef RDATA_GENERIC_HIP_5_C #define RDATA_GENERIC_HIP_5_C #define RRTYPE_HIP_ATTRIBUTES (0) static inline isc_result_t fromtext_hip(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; isc_buffer_t hit_len; isc_buffer_t key_len; unsigned char *start; size_t len; REQUIRE(type == dns_rdatatype_hip); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); /* * Dummy HIT len. */ hit_len = *target; RETERR(uint8_tobuffer(0, target)); /* * Algorithm. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffU) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer(token.value.as_ulong, target)); /* * Dummy KEY len. */ key_len = *target; RETERR(uint16_tobuffer(0, target)); /* * HIT (base16). */ start = isc_buffer_used(target); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(isc_hex_decodestring(DNS_AS_STR(token), target)); /* * Fill in HIT len. */ len = (unsigned char *)isc_buffer_used(target) - start; if (len > 0xffU) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer((isc_uint32_t)len, &hit_len)); /* * Public key (base64). */ start = isc_buffer_used(target); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(isc_base64_decodestring(DNS_AS_STR(token), target)); /* * Fill in KEY len. */ len = (unsigned char *)isc_buffer_used(target) - start; if (len > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer((isc_uint32_t)len, &key_len)); /* * Rendezvous Servers. */ dns_name_init(&name, NULL); do { RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_TRUE)); if (token.type != isc_tokentype_string) break; buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); } while (1); /* * Let upper layer handle eol/eof. */ isc_lex_ungettoken(lexer, &token); return (ISC_R_SUCCESS); } static inline isc_result_t totext_hip(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; unsigned int length, key_len, hit_len; unsigned char algorithm; char buf[sizeof("225 ")]; REQUIRE(rdata->type == dns_rdatatype_hip); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, ®ion); hit_len = uint8_fromregion(®ion); isc_region_consume(®ion, 1); algorithm = uint8_fromregion(®ion); isc_region_consume(®ion, 1); key_len = uint16_fromregion(®ion); isc_region_consume(®ion, 2); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext("( ", target)); /* * Algorithm */ sprintf(buf, "%u ", algorithm); RETERR(str_totext(buf, target)); /* * HIT. */ INSIST(hit_len < region.length); length = region.length; region.length = hit_len; RETERR(isc_hex_totext(®ion, 1, "", target)); region.length = length - hit_len; RETERR(str_totext(tctx->linebreak, target)); /* * Public KEY. */ INSIST(key_len <= region.length); length = region.length; region.length = key_len; RETERR(isc_base64_totext(®ion, 1, "", target)); region.length = length - key_len; RETERR(str_totext(tctx->linebreak, target)); /* * Rendezvous Servers. */ dns_name_init(&name, NULL); while (region.length > 0) { dns_name_fromregion(&name, ®ion); RETERR(dns_name_totext(&name, ISC_FALSE, target)); isc_region_consume(®ion, name.length); if (region.length > 0) RETERR(str_totext(tctx->linebreak, target)); } if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_hip(ARGS_FROMWIRE) { isc_region_t region, rr; dns_name_t name; isc_uint8_t hit_len; isc_uint16_t key_len; REQUIRE(type == dns_rdatatype_hip); UNUSED(type); UNUSED(rdclass); isc_buffer_activeregion(source, ®ion); if (region.length < 4U) RETERR(DNS_R_FORMERR); rr = region; hit_len = uint8_fromregion(®ion); if (hit_len == 0) RETERR(DNS_R_FORMERR); isc_region_consume(®ion, 2); /* hit length + algorithm */ key_len = uint16_fromregion(®ion); if (key_len == 0) RETERR(DNS_R_FORMERR); isc_region_consume(®ion, 2); if (region.length < (unsigned) (hit_len + key_len)) RETERR(DNS_R_FORMERR); RETERR(mem_tobuffer(target, rr.base, 4 + hit_len + key_len)); isc_buffer_forward(source, 4 + hit_len + key_len); dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); while (isc_buffer_activelength(source) > 0) { dns_name_init(&name, NULL); RETERR(dns_name_fromwire(&name, source, dctx, options, target)); } return (ISC_R_SUCCESS); } static inline isc_result_t towire_hip(ARGS_TOWIRE) { isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_hip); REQUIRE(rdata->length != 0); UNUSED(cctx); dns_rdata_toregion(rdata, ®ion); return (mem_tobuffer(target, region.base, region.length)); } static inline int compare_hip(ARGS_COMPARE) { isc_region_t region1; isc_region_t region2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_hip); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); return (isc_region_compare(®ion1, ®ion2)); } static inline isc_result_t fromstruct_hip(ARGS_FROMSTRUCT) { dns_rdata_hip_t *hip = source; dns_rdata_hip_t myhip; isc_result_t result; REQUIRE(type == dns_rdatatype_hip); REQUIRE(source != NULL); REQUIRE(hip->common.rdtype == type); REQUIRE(hip->common.rdclass == rdclass); REQUIRE(hip->hit_len > 0 && hip->hit != NULL); REQUIRE(hip->key_len > 0 && hip->key != NULL); REQUIRE((hip->servers == NULL && hip->servers_len == 0) || (hip->servers != NULL && hip->servers_len != 0)); UNUSED(type); UNUSED(rdclass); RETERR(uint8_tobuffer(hip->hit_len, target)); RETERR(uint8_tobuffer(hip->algorithm, target)); RETERR(uint16_tobuffer(hip->key_len, target)); RETERR(mem_tobuffer(target, hip->hit, hip->hit_len)); RETERR(mem_tobuffer(target, hip->key, hip->key_len)); myhip = *hip; for (result = dns_rdata_hip_first(&myhip); result == ISC_R_SUCCESS; result = dns_rdata_hip_next(&myhip)) /* empty */; return(mem_tobuffer(target, hip->servers, hip->servers_len)); } static inline isc_result_t tostruct_hip(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_hip_t *hip = target; REQUIRE(rdata->type == dns_rdatatype_hip); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); hip->common.rdclass = rdata->rdclass; hip->common.rdtype = rdata->type; ISC_LINK_INIT(&hip->common, link); dns_rdata_toregion(rdata, ®ion); hip->hit_len = uint8_fromregion(®ion); isc_region_consume(®ion, 1); hip->algorithm = uint8_fromregion(®ion); isc_region_consume(®ion, 1); hip->key_len = uint16_fromregion(®ion); isc_region_consume(®ion, 2); hip->hit = hip->key = hip->servers = NULL; hip->hit = mem_maybedup(mctx, region.base, hip->hit_len); if (hip->hit == NULL) goto cleanup; isc_region_consume(®ion, hip->hit_len); INSIST(hip->key_len <= region.length); hip->key = mem_maybedup(mctx, region.base, hip->key_len); if (hip->key == NULL) goto cleanup; isc_region_consume(®ion, hip->key_len); hip->servers_len = region.length; if (hip->servers_len != 0) { hip->servers = mem_maybedup(mctx, region.base, region.length); if (hip->servers == NULL) goto cleanup; } hip->offset = hip->servers_len; hip->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (hip->hit != NULL) isc_mem_free(mctx, hip->hit); if (hip->key != NULL) isc_mem_free(mctx, hip->key); if (hip->servers != NULL) isc_mem_free(mctx, hip->servers); return (ISC_R_NOMEMORY); } static inline void freestruct_hip(ARGS_FREESTRUCT) { dns_rdata_hip_t *hip = source; REQUIRE(source != NULL); if (hip->mctx == NULL) return; isc_mem_free(hip->mctx, hip->hit); isc_mem_free(hip->mctx, hip->key); if (hip->servers != NULL) isc_mem_free(hip->mctx, hip->servers); hip->mctx = NULL; } static inline isc_result_t additionaldata_hip(ARGS_ADDLDATA) { UNUSED(rdata); UNUSED(add); UNUSED(arg); REQUIRE(rdata->type == dns_rdatatype_hip); return (ISC_R_SUCCESS); } static inline isc_result_t digest_hip(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_hip); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_hip(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_hip); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_hip(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_hip); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } isc_result_t dns_rdata_hip_first(dns_rdata_hip_t *hip) { if (hip->servers_len == 0) return (ISC_R_NOMORE); hip->offset = 0; return (ISC_R_SUCCESS); } isc_result_t dns_rdata_hip_next(dns_rdata_hip_t *hip) { isc_region_t region; dns_name_t name; if (hip->offset >= hip->servers_len) return (ISC_R_NOMORE); region.base = hip->servers + hip->offset; region.length = hip->servers_len - hip->offset; dns_name_init(&name, NULL); dns_name_fromregion(&name, ®ion); hip->offset += name.length; INSIST(hip->offset <= hip->servers_len); return (ISC_R_SUCCESS); } void dns_rdata_hip_current(dns_rdata_hip_t *hip, dns_name_t *name) { isc_region_t region; REQUIRE(hip->offset < hip->servers_len); region.base = hip->servers + hip->offset; region.length = hip->servers_len - hip->offset; dns_name_fromregion(name, ®ion); INSIST(name->length + hip->offset <= hip->servers_len); } static inline int casecompare_hip(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; dns_name_t name1; dns_name_t name2; int order; isc_uint8_t hit_len; isc_uint16_t key_len; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_hip); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); INSIST(r1.length > 4); INSIST(r2.length > 4); order = memcmp(r1.base, r2.base, 4); if (order != 0) return (order); hit_len = uint8_fromregion(&r1); isc_region_consume(&r1, 2); /* hit length + algorithm */ key_len = uint16_fromregion(&r1); isc_region_consume(&r1, 2); /* key length */ isc_region_consume(&r2, 4); INSIST(r1.length >= (unsigned) (hit_len + key_len)); INSIST(r2.length >= (unsigned) (hit_len + key_len)); order = memcmp(r1.base, r2.base, hit_len + key_len); if (order != 0) return (order); isc_region_consume(&r1, hit_len + key_len); isc_region_consume(&r2, hit_len + key_len); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); while (r1.length != 0 && r2.length != 0) { dns_name_fromregion(&name1, &r1); dns_name_fromregion(&name2, &r2); order = dns_name_rdatacompare(&name1, &name2); if (order != 0) return (order); isc_region_consume(&r1, name_length(&name1)); isc_region_consume(&r2, name_length(&name2)); } return (isc_region_compare(&r1, &r2)); } #endif /* RDATA_GENERIC_HIP_5_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/mg_8.c0000644000470500017500000001257012664710322020435 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: mg_8.c,v 1.45 2009/12/04 22:06:37 tbox Exp $ */ /* reviewed: Wed Mar 15 17:49:21 PST 2000 by brister */ #ifndef RDATA_GENERIC_MG_8_C #define RDATA_GENERIC_MG_8_C #define RRTYPE_MG_ATTRIBUTES (0) static inline isc_result_t fromtext_mg(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; REQUIRE(type == dns_rdatatype_mg); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); return (ISC_R_SUCCESS); } static inline isc_result_t totext_mg(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; REQUIRE(rdata->type == dns_rdatatype_mg); REQUIRE(rdata->length != 0); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); sub = name_prefix(&name, tctx->origin, &prefix); return (dns_name_totext(&prefix, sub, target)); } static inline isc_result_t fromwire_mg(ARGS_FROMWIRE) { dns_name_t name; REQUIRE(type == dns_rdatatype_mg); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, NULL); return (dns_name_fromwire(&name, source, dctx, options, target)); } static inline isc_result_t towire_mg(ARGS_TOWIRE) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_mg); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); return (dns_name_towire(&name, cctx, target)); } static inline int compare_mg(ARGS_COMPARE) { dns_name_t name1; dns_name_t name2; isc_region_t region1; isc_region_t region2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_mg); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); return (dns_name_rdatacompare(&name1, &name2)); } static inline isc_result_t fromstruct_mg(ARGS_FROMSTRUCT) { dns_rdata_mg_t *mg = source; isc_region_t region; REQUIRE(type == dns_rdatatype_mg); REQUIRE(source != NULL); REQUIRE(mg->common.rdtype == type); REQUIRE(mg->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); dns_name_toregion(&mg->mg, ®ion); return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_mg(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_mg_t *mg = target; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_mg); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); mg->common.rdclass = rdata->rdclass; mg->common.rdtype = rdata->type; ISC_LINK_INIT(&mg->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); dns_name_init(&mg->mg, NULL); RETERR(name_duporclone(&name, mctx, &mg->mg)); mg->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_mg(ARGS_FREESTRUCT) { dns_rdata_mg_t *mg = source; REQUIRE(source != NULL); REQUIRE(mg->common.rdtype == dns_rdatatype_mg); if (mg->mctx == NULL) return; dns_name_free(&mg->mg, mg->mctx); mg->mctx = NULL; } static inline isc_result_t additionaldata_mg(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_mg); UNUSED(add); UNUSED(arg); UNUSED(rdata); return (ISC_R_SUCCESS); } static inline isc_result_t digest_mg(ARGS_DIGEST) { isc_region_t r; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_mg); dns_rdata_toregion(rdata, &r); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); return (dns_name_digest(&name, digest, arg)); } static inline isc_boolean_t checkowner_mg(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_mg); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (dns_name_ismailbox(name)); } static inline isc_boolean_t checknames_mg(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_mg); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_mg(ARGS_COMPARE) { return (compare_mg(rdata1, rdata2)); } #endif /* RDATA_GENERIC_MG_8_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/nsec_47.c0000644000470500017500000002305712664710322021047 0ustar lamontlamont/* * Copyright (C) 2004, 2007-2009, 2011, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: nsec_47.c,v 1.15 2011/01/13 04:59:26 tbox Exp $ */ /* reviewed: Wed Mar 15 18:21:15 PST 2000 by brister */ /* RFC 3845 */ #ifndef RDATA_GENERIC_NSEC_47_C #define RDATA_GENERIC_NSEC_47_C /* * The attributes do not include DNS_RDATATYPEATTR_SINGLETON * because we must be able to handle a parent/child NSEC pair. */ #define RRTYPE_NSEC_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC) static inline isc_result_t fromtext_nsec(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; unsigned char bm[8*1024]; /* 64k bits */ dns_rdatatype_t covered; int octet; int window; REQUIRE(type == dns_rdatatype_nsec); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); /* * Next domain. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); memset(bm, 0, sizeof(bm)); do { RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_TRUE)); if (token.type != isc_tokentype_string) break; RETTOK(dns_rdatatype_fromtext(&covered, &token.value.as_textregion)); bm[covered/8] |= (0x80>>(covered%8)); } while (1); isc_lex_ungettoken(lexer, &token); for (window = 0; window < 256 ; window++) { /* * Find if we have a type in this window. */ for (octet = 31; octet >= 0; octet--) if (bm[window * 32 + octet] != 0) break; if (octet < 0) continue; RETERR(uint8_tobuffer(window, target)); RETERR(uint8_tobuffer(octet + 1, target)); RETERR(mem_tobuffer(target, &bm[window * 32], octet + 1)); } return (ISC_R_SUCCESS); } static inline isc_result_t totext_nsec(ARGS_TOTEXT) { isc_region_t sr; unsigned int i, j, k; dns_name_t name; unsigned int window, len; REQUIRE(rdata->type == dns_rdatatype_nsec); REQUIRE(rdata->length != 0); UNUSED(tctx); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, &sr); dns_name_fromregion(&name, &sr); isc_region_consume(&sr, name_length(&name)); RETERR(dns_name_totext(&name, ISC_FALSE, target)); for (i = 0; i < sr.length; i += len) { INSIST(i + 2 <= sr.length); window = sr.base[i]; len = sr.base[i + 1]; INSIST(len > 0 && len <= 32); i += 2; INSIST(i + len <= sr.length); for (j = 0; j < len; j++) { dns_rdatatype_t t; if (sr.base[i + j] == 0) continue; for (k = 0; k < 8; k++) { if ((sr.base[i + j] & (0x80 >> k)) == 0) continue; t = window * 256 + j * 8 + k; RETERR(str_totext(" ", target)); if (dns_rdatatype_isknown(t)) { RETERR(dns_rdatatype_totext(t, target)); } else { char buf[sizeof("TYPE65535")]; sprintf(buf, "TYPE%u", t); RETERR(str_totext(buf, target)); } } } } return (ISC_R_SUCCESS); } static /* inline */ isc_result_t fromwire_nsec(ARGS_FROMWIRE) { isc_region_t sr; dns_name_t name; unsigned int window, lastwindow = 0; unsigned int len; isc_boolean_t first = ISC_TRUE; unsigned int i; REQUIRE(type == dns_rdatatype_nsec); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); dns_name_init(&name, NULL); RETERR(dns_name_fromwire(&name, source, dctx, options, target)); isc_buffer_activeregion(source, &sr); for (i = 0; i < sr.length; i += len) { /* * Check for overflow. */ if (i + 2 > sr.length) RETERR(DNS_R_FORMERR); window = sr.base[i]; len = sr.base[i + 1]; i += 2; /* * Check that bitmap windows are in the correct order. */ if (!first && window <= lastwindow) RETERR(DNS_R_FORMERR); /* * Check for legal lengths. */ if (len < 1 || len > 32) RETERR(DNS_R_FORMERR); /* * Check for overflow. */ if (i + len > sr.length) RETERR(DNS_R_FORMERR); /* * The last octet of the bitmap must be non zero. */ if (sr.base[i + len - 1] == 0) RETERR(DNS_R_FORMERR); lastwindow = window; first = ISC_FALSE; } if (i != sr.length) return (DNS_R_EXTRADATA); if (first) RETERR(DNS_R_FORMERR); RETERR(mem_tobuffer(target, sr.base, sr.length)); isc_buffer_forward(source, sr.length); return (ISC_R_SUCCESS); } static inline isc_result_t towire_nsec(ARGS_TOWIRE) { isc_region_t sr; dns_name_t name; dns_offsets_t offsets; REQUIRE(rdata->type == dns_rdatatype_nsec); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, &sr); dns_name_fromregion(&name, &sr); isc_region_consume(&sr, name_length(&name)); RETERR(dns_name_towire(&name, cctx, target)); return (mem_tobuffer(target, sr.base, sr.length)); } static inline int compare_nsec(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_nsec); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_nsec(ARGS_FROMSTRUCT) { dns_rdata_nsec_t *nsec = source; isc_region_t region; unsigned int i, len, window, lastwindow = 0; isc_boolean_t first = ISC_TRUE; REQUIRE(type == dns_rdatatype_nsec); REQUIRE(source != NULL); REQUIRE(nsec->common.rdtype == type); REQUIRE(nsec->common.rdclass == rdclass); REQUIRE(nsec->typebits != NULL || nsec->len == 0); UNUSED(type); UNUSED(rdclass); dns_name_toregion(&nsec->next, ®ion); RETERR(isc_buffer_copyregion(target, ®ion)); /* * Perform sanity check. */ for (i = 0; i < nsec->len ; i += len) { INSIST(i + 2 <= nsec->len); window = nsec->typebits[i]; len = nsec->typebits[i+1]; i += 2; INSIST(first || window > lastwindow); INSIST(len > 0 && len <= 32); INSIST(i + len <= nsec->len); INSIST(nsec->typebits[i + len - 1] != 0); lastwindow = window; first = ISC_FALSE; } INSIST(!first); return (mem_tobuffer(target, nsec->typebits, nsec->len)); } static inline isc_result_t tostruct_nsec(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_nsec_t *nsec = target; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_nsec); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); nsec->common.rdclass = rdata->rdclass; nsec->common.rdtype = rdata->type; ISC_LINK_INIT(&nsec->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); isc_region_consume(®ion, name_length(&name)); dns_name_init(&nsec->next, NULL); RETERR(name_duporclone(&name, mctx, &nsec->next)); nsec->len = region.length; nsec->typebits = mem_maybedup(mctx, region.base, region.length); if (nsec->typebits == NULL) goto cleanup; nsec->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (mctx != NULL) dns_name_free(&nsec->next, mctx); return (ISC_R_NOMEMORY); } static inline void freestruct_nsec(ARGS_FREESTRUCT) { dns_rdata_nsec_t *nsec = source; REQUIRE(source != NULL); REQUIRE(nsec->common.rdtype == dns_rdatatype_nsec); if (nsec->mctx == NULL) return; dns_name_free(&nsec->next, nsec->mctx); if (nsec->typebits != NULL) isc_mem_free(nsec->mctx, nsec->typebits); nsec->mctx = NULL; } static inline isc_result_t additionaldata_nsec(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_nsec); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_nsec(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_nsec); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_nsec(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_nsec); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_nsec(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_nsec); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_nsec(ARGS_COMPARE) { isc_region_t region1; isc_region_t region2; dns_name_t name1; dns_name_t name2; int order; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_nsec); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); order = dns_name_rdatacompare(&name1, &name2); if (order != 0) return (order); isc_region_consume(®ion1, name_length(&name1)); isc_region_consume(®ion2, name_length(&name2)); return (isc_region_compare(®ion1, ®ion2)); } #endif /* RDATA_GENERIC_NSEC_47_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/openpgpkey_61.h0000644000470500017500000000204212664710322022270 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_OPENPGPKEY_61_H #define GENERIC_OPENPGPKEY_61_H 1 typedef struct dns_rdata_openpgpkey { dns_rdatacommon_t common; isc_mem_t * mctx; isc_uint16_t length; unsigned char * keyring; } dns_rdata_openpgpkey_t; #endif /* GENERIC_OPENPGPKEY_61_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/uri_256.c0000644000470500017500000001463412664710322021001 0ustar lamontlamont/* * Copyright (C) 2011, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef GENERIC_URI_256_C #define GENERIC_URI_256_C 1 #define RRTYPE_URI_ATTRIBUTES (0) static inline isc_result_t fromtext_uri(ARGS_FROMTEXT) { isc_token_t token; REQUIRE(type == dns_rdatatype_uri); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); /* * Priority */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Weight */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Target URI */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, ISC_FALSE)); if (token.type != isc_tokentype_qstring) RETTOK(DNS_R_SYNTAX); RETTOK(multitxt_fromtext(&token.value.as_textregion, target)); return (ISC_R_SUCCESS); } static inline isc_result_t totext_uri(ARGS_TOTEXT) { isc_region_t region; unsigned short priority, weight; char buf[sizeof("65000 ")]; UNUSED(tctx); REQUIRE(rdata->type == dns_rdatatype_uri); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, ®ion); /* * Priority */ priority = uint16_fromregion(®ion); isc_region_consume(®ion, 2); sprintf(buf, "%u ", priority); RETERR(str_totext(buf, target)); /* * Weight */ weight = uint16_fromregion(®ion); isc_region_consume(®ion, 2); sprintf(buf, "%u ", weight); RETERR(str_totext(buf, target)); /* * Target URI */ RETERR(multitxt_totext(®ion, target)); return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_uri(ARGS_FROMWIRE) { isc_region_t region; REQUIRE(type == dns_rdatatype_uri); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); /* * Priority, weight */ isc_buffer_activeregion(source, ®ion); if (region.length < 4) return (ISC_R_UNEXPECTEDEND); /* * Priority, weight and target URI */ isc_buffer_forward(source, region.length); return (mem_tobuffer(target, region.base, region.length)); } static inline isc_result_t towire_uri(ARGS_TOWIRE) { isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_uri); REQUIRE(rdata->length != 0); UNUSED(cctx); dns_rdata_toregion(rdata, ®ion); return (mem_tobuffer(target, region.base, region.length)); } static inline int compare_uri(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; int order; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_uri); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); /* * Priority */ order = memcmp(r1.base, r2.base, 2); if (order != 0) return (order < 0 ? -1 : 1); isc_region_consume(&r1, 2); isc_region_consume(&r2, 2); /* * Weight */ order = memcmp(r1.base, r2.base, 2); if (order != 0) return (order < 0 ? -1 : 1); isc_region_consume(&r1, 2); isc_region_consume(&r2, 2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_uri(ARGS_FROMSTRUCT) { dns_rdata_uri_t *uri = source; REQUIRE(type == dns_rdatatype_uri); REQUIRE(source != NULL); REQUIRE(uri->common.rdtype == type); REQUIRE(uri->common.rdclass == rdclass); REQUIRE(uri->target != NULL && uri->tgt_len != 0); UNUSED(type); UNUSED(rdclass); /* * Priority */ RETERR(uint16_tobuffer(uri->priority, target)); /* * Weight */ RETERR(uint16_tobuffer(uri->weight, target)); /* * Target URI */ return (mem_tobuffer(target, uri->target, uri->tgt_len)); } static inline isc_result_t tostruct_uri(ARGS_TOSTRUCT) { dns_rdata_uri_t *uri = target; isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_uri); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); uri->common.rdclass = rdata->rdclass; uri->common.rdtype = rdata->type; ISC_LINK_INIT(&uri->common, link); dns_rdata_toregion(rdata, &sr); /* * Priority */ if (sr.length < 2) return (ISC_R_UNEXPECTEDEND); uri->priority = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * Weight */ if (sr.length < 2) return (ISC_R_UNEXPECTEDEND); uri->weight = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * Target URI */ uri->tgt_len = sr.length; uri->target = mem_maybedup(mctx, sr.base, sr.length); if (uri->target == NULL) return (ISC_R_NOMEMORY); uri->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_uri(ARGS_FREESTRUCT) { dns_rdata_uri_t *uri = (dns_rdata_uri_t *) source; REQUIRE(source != NULL); REQUIRE(uri->common.rdtype == dns_rdatatype_uri); if (uri->mctx == NULL) return; if (uri->target != NULL) isc_mem_free(uri->mctx, uri->target); uri->mctx = NULL; } static inline isc_result_t additionaldata_uri(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_uri); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_uri(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_uri); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_uri(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_uri); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_uri(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_uri); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_uri(ARGS_COMPARE) { return (compare_uri(rdata1, rdata2)); } #endif /* GENERIC_URI_256_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/ns_2.h0000644000470500017500000000213512664710322020445 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef GENERIC_NS_2_H #define GENERIC_NS_2_H 1 /* $Id: ns_2.h,v 1.27 2007/06/19 23:47:17 tbox Exp $ */ typedef struct dns_rdata_ns { dns_rdatacommon_t common; isc_mem_t *mctx; dns_name_t name; } dns_rdata_ns_t; #endif /* GENERIC_NS_2_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/nsec3param_51.c0000644000470500017500000002027112664710322022141 0ustar lamontlamont/* * Copyright (C) 2008, 2009, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: nsec3param_51.c,v 1.7 2009/12/04 21:09:34 marka Exp $ */ /* * Copyright (C) 2004 Nominet, Ltd. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND NOMINET DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* RFC 5155 */ #ifndef RDATA_GENERIC_NSEC3PARAM_51_C #define RDATA_GENERIC_NSEC3PARAM_51_C #include #include #define RRTYPE_NSEC3PARAM_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC) static inline isc_result_t fromtext_nsec3param(ARGS_FROMTEXT) { isc_token_t token; unsigned int flags = 0; unsigned char hashalg; REQUIRE(type == dns_rdatatype_nsec3param); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); UNUSED(origin); UNUSED(options); /* Hash. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_hashalg_fromtext(&hashalg, &token.value.as_textregion)); RETERR(uint8_tobuffer(hashalg, target)); /* Flags. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); flags = token.value.as_ulong; if (flags > 255U) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer(flags, target)); /* Iterations. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* Salt. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (token.value.as_textregion.length > (255*2)) RETTOK(DNS_R_TEXTTOOLONG); if (strcmp(DNS_AS_STR(token), "-") == 0) { RETERR(uint8_tobuffer(0, target)); } else { RETERR(uint8_tobuffer(strlen(DNS_AS_STR(token)) / 2, target)); RETERR(isc_hex_decodestring(DNS_AS_STR(token), target)); } return (ISC_R_SUCCESS); } static inline isc_result_t totext_nsec3param(ARGS_TOTEXT) { isc_region_t sr; unsigned int i, j; unsigned char hash; unsigned char flags; char buf[sizeof("65535 ")]; isc_uint32_t iterations; REQUIRE(rdata->type == dns_rdatatype_nsec3param); REQUIRE(rdata->length != 0); UNUSED(tctx); dns_rdata_toregion(rdata, &sr); hash = uint8_fromregion(&sr); isc_region_consume(&sr, 1); flags = uint8_fromregion(&sr); isc_region_consume(&sr, 1); iterations = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%u ", hash); RETERR(str_totext(buf, target)); sprintf(buf, "%u ", flags); RETERR(str_totext(buf, target)); sprintf(buf, "%u ", iterations); RETERR(str_totext(buf, target)); j = uint8_fromregion(&sr); isc_region_consume(&sr, 1); INSIST(j <= sr.length); if (j != 0) { i = sr.length; sr.length = j; RETERR(isc_hex_totext(&sr, 1, "", target)); sr.length = i - j; } else RETERR(str_totext("-", target)); return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_nsec3param(ARGS_FROMWIRE) { isc_region_t sr, rr; unsigned int saltlen; REQUIRE(type == dns_rdatatype_nsec3param); UNUSED(type); UNUSED(rdclass); UNUSED(options); UNUSED(dctx); isc_buffer_activeregion(source, &sr); rr = sr; /* hash(1), flags(1), iterations(2), saltlen(1) */ if (sr.length < 5U) RETERR(DNS_R_FORMERR); saltlen = sr.base[4]; isc_region_consume(&sr, 5); if (sr.length < saltlen) RETERR(DNS_R_FORMERR); isc_region_consume(&sr, saltlen); RETERR(mem_tobuffer(target, rr.base, rr.length)); isc_buffer_forward(source, rr.length); return (ISC_R_SUCCESS); } static inline isc_result_t towire_nsec3param(ARGS_TOWIRE) { isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_nsec3param); REQUIRE(rdata->length != 0); UNUSED(cctx); dns_rdata_toregion(rdata, &sr); return (mem_tobuffer(target, sr.base, sr.length)); } static inline int compare_nsec3param(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_nsec3param); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_nsec3param(ARGS_FROMSTRUCT) { dns_rdata_nsec3param_t *nsec3param = source; REQUIRE(type == dns_rdatatype_nsec3param); REQUIRE(source != NULL); REQUIRE(nsec3param->common.rdtype == type); REQUIRE(nsec3param->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); RETERR(uint8_tobuffer(nsec3param->hash, target)); RETERR(uint8_tobuffer(nsec3param->flags, target)); RETERR(uint16_tobuffer(nsec3param->iterations, target)); RETERR(uint8_tobuffer(nsec3param->salt_length, target)); RETERR(mem_tobuffer(target, nsec3param->salt, nsec3param->salt_length)); return (ISC_R_SUCCESS); } static inline isc_result_t tostruct_nsec3param(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_nsec3param_t *nsec3param = target; REQUIRE(rdata->type == dns_rdatatype_nsec3param); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); nsec3param->common.rdclass = rdata->rdclass; nsec3param->common.rdtype = rdata->type; ISC_LINK_INIT(&nsec3param->common, link); region.base = rdata->data; region.length = rdata->length; nsec3param->hash = uint8_consume_fromregion(®ion); nsec3param->flags = uint8_consume_fromregion(®ion); nsec3param->iterations = uint16_consume_fromregion(®ion); nsec3param->salt_length = uint8_consume_fromregion(®ion); nsec3param->salt = mem_maybedup(mctx, region.base, nsec3param->salt_length); if (nsec3param->salt == NULL) return (ISC_R_NOMEMORY); isc_region_consume(®ion, nsec3param->salt_length); nsec3param->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_nsec3param(ARGS_FREESTRUCT) { dns_rdata_nsec3param_t *nsec3param = source; REQUIRE(source != NULL); REQUIRE(nsec3param->common.rdtype == dns_rdatatype_nsec3param); if (nsec3param->mctx == NULL) return; if (nsec3param->salt != NULL) isc_mem_free(nsec3param->mctx, nsec3param->salt); nsec3param->mctx = NULL; } static inline isc_result_t additionaldata_nsec3param(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_nsec3param); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_nsec3param(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_nsec3param); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_nsec3param(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_nsec3param); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_nsec3param(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_nsec3param); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_nsec3param(ARGS_COMPARE) { return (compare_nsec3param(rdata1, rdata2)); } #endif /* RDATA_GENERIC_NSEC3PARAM_51_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/keydata_65533.c0000644000470500017500000002625012664710322021772 0ustar lamontlamont/* * Copyright (C) 2009, 2011-2013, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_KEYDATA_65533_C #define GENERIC_KEYDATA_65533_C 1 #include #include #include #define RRTYPE_KEYDATA_ATTRIBUTES (0) static inline isc_result_t fromtext_keydata(ARGS_FROMTEXT) { isc_result_t result; isc_token_t token; dns_secalg_t alg; dns_secproto_t proto; dns_keyflags_t flags; isc_uint32_t refresh, addhd, removehd; REQUIRE(type == dns_rdatatype_keydata); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); /* refresh timer */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &refresh)); RETERR(uint32_tobuffer(refresh, target)); /* add hold-down */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &addhd)); RETERR(uint32_tobuffer(addhd, target)); /* remove hold-down */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &removehd)); RETERR(uint32_tobuffer(removehd, target)); /* flags */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion)); RETERR(uint16_tobuffer(flags, target)); /* protocol */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion)); RETERR(mem_tobuffer(target, &proto, 1)); /* algorithm */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion)); RETERR(mem_tobuffer(target, &alg, 1)); /* No Key? */ if ((flags & 0xc000) == 0xc000) return (ISC_R_SUCCESS); result = isc_base64_tobuffer(lexer, target, -1); if (result != ISC_R_SUCCESS) return (result); /* Ensure there's at least enough data to compute a key ID for MD5 */ if (alg == DST_ALG_RSAMD5 && isc_buffer_usedlength(target) < 19) return (ISC_R_UNEXPECTEDEND); return (ISC_R_SUCCESS); } static inline isc_result_t totext_keydata(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("64000")]; unsigned int flags; unsigned char algorithm; unsigned long refresh, add, delete; char algbuf[DNS_NAME_FORMATSIZE]; const char *keyinfo; REQUIRE(rdata->type == dns_rdatatype_keydata); if ((tctx->flags & DNS_STYLEFLAG_KEYDATA) == 0 || rdata->length < 16) return (unknown_totext(rdata, tctx, target)); dns_rdata_toregion(rdata, &sr); /* refresh timer */ refresh = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(refresh, target)); RETERR(str_totext(" ", target)); /* add hold-down */ add = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(add, target)); RETERR(str_totext(" ", target)); /* remove hold-down */ delete = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(delete, target)); RETERR(str_totext(" ", target)); /* flags */ flags = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%u", flags); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); if ((flags & DNS_KEYFLAG_KSK) != 0) { if (flags & DNS_KEYFLAG_REVOKE) keyinfo = "revoked KSK"; else keyinfo = "KSK"; } else keyinfo = "ZSK"; /* protocol */ sprintf(buf, "%u", sr.base[0]); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* algorithm */ algorithm = sr.base[0]; sprintf(buf, "%u", algorithm); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); /* No Key? */ if ((flags & 0xc000) == 0xc000) return (ISC_R_SUCCESS); /* key */ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(&sr, 60, "", target)); else RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) RETERR(str_totext(tctx->linebreak, target)); else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" ", target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(")", target)); if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) { isc_region_t tmpr; char rbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; char abuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; char dbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; isc_time_t t; RETERR(str_totext(" ; ", target)); RETERR(str_totext(keyinfo, target)); dns_secalg_format((dns_secalg_t) algorithm, algbuf, sizeof(algbuf)); RETERR(str_totext("; alg = ", target)); RETERR(str_totext(algbuf, target)); RETERR(str_totext("; key id = ", target)); dns_rdata_toregion(rdata, &tmpr); /* Skip over refresh, addhd, and removehd */ isc_region_consume(&tmpr, 12); sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm)); RETERR(str_totext(buf, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { isc_stdtime_t now; isc_stdtime_get(&now); RETERR(str_totext(tctx->linebreak, target)); RETERR(str_totext("; next refresh: ", target)); isc_time_set(&t, refresh, 0); isc_time_formathttptimestamp(&t, rbuf, sizeof(rbuf)); RETERR(str_totext(rbuf, target)); if (add == 0U) { RETERR(str_totext(tctx->linebreak, target)); RETERR(str_totext("; no trust", target)); } else { RETERR(str_totext(tctx->linebreak, target)); if (add < now) { RETERR(str_totext("; trusted since: ", target)); } else { RETERR(str_totext("; trust pending: ", target)); } isc_time_set(&t, add, 0); isc_time_formathttptimestamp(&t, abuf, sizeof(abuf)); RETERR(str_totext(abuf, target)); } if (delete != 0U) { RETERR(str_totext(tctx->linebreak, target)); RETERR(str_totext("; removal pending: ", target)); isc_time_set(&t, delete, 0); isc_time_formathttptimestamp(&t, dbuf, sizeof(dbuf)); RETERR(str_totext(dbuf, target)); } } } return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_keydata(ARGS_FROMWIRE) { isc_region_t sr; REQUIRE(type == dns_rdatatype_keydata); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); isc_buffer_activeregion(source, &sr); isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); } static inline isc_result_t towire_keydata(ARGS_TOWIRE) { isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_keydata); UNUSED(cctx); dns_rdata_toregion(rdata, &sr); return (mem_tobuffer(target, sr.base, sr.length)); } static inline int compare_keydata(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_keydata); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_keydata(ARGS_FROMSTRUCT) { dns_rdata_keydata_t *keydata = source; REQUIRE(type == dns_rdatatype_keydata); REQUIRE(source != NULL); REQUIRE(keydata->common.rdtype == type); REQUIRE(keydata->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); /* Refresh timer */ RETERR(uint32_tobuffer(keydata->refresh, target)); /* Add hold-down */ RETERR(uint32_tobuffer(keydata->addhd, target)); /* Remove hold-down */ RETERR(uint32_tobuffer(keydata->removehd, target)); /* Flags */ RETERR(uint16_tobuffer(keydata->flags, target)); /* Protocol */ RETERR(uint8_tobuffer(keydata->protocol, target)); /* Algorithm */ RETERR(uint8_tobuffer(keydata->algorithm, target)); /* Data */ return (mem_tobuffer(target, keydata->data, keydata->datalen)); } static inline isc_result_t tostruct_keydata(ARGS_TOSTRUCT) { dns_rdata_keydata_t *keydata = target; isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_keydata); REQUIRE(target != NULL); keydata->common.rdclass = rdata->rdclass; keydata->common.rdtype = rdata->type; ISC_LINK_INIT(&keydata->common, link); dns_rdata_toregion(rdata, &sr); /* Refresh timer */ if (sr.length < 4) return (ISC_R_UNEXPECTEDEND); keydata->refresh = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* Add hold-down */ if (sr.length < 4) return (ISC_R_UNEXPECTEDEND); keydata->addhd = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* Remove hold-down */ if (sr.length < 4) return (ISC_R_UNEXPECTEDEND); keydata->removehd = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* Flags */ if (sr.length < 2) return (ISC_R_UNEXPECTEDEND); keydata->flags = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* Protocol */ if (sr.length < 1) return (ISC_R_UNEXPECTEDEND); keydata->protocol = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* Algorithm */ if (sr.length < 1) return (ISC_R_UNEXPECTEDEND); keydata->algorithm = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* Data */ keydata->datalen = sr.length; keydata->data = mem_maybedup(mctx, sr.base, keydata->datalen); if (keydata->data == NULL) return (ISC_R_NOMEMORY); keydata->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_keydata(ARGS_FREESTRUCT) { dns_rdata_keydata_t *keydata = (dns_rdata_keydata_t *) source; REQUIRE(source != NULL); REQUIRE(keydata->common.rdtype == dns_rdatatype_keydata); if (keydata->mctx == NULL) return; if (keydata->data != NULL) isc_mem_free(keydata->mctx, keydata->data); keydata->mctx = NULL; } static inline isc_result_t additionaldata_keydata(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_keydata); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_keydata(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_keydata); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_keydata(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_keydata); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_keydata(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_keydata); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_keydata(ARGS_COMPARE) { return (compare_keydata(rdata1, rdata2)); } #endif /* GENERIC_KEYDATA_65533_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/ptr_12.c0000644000470500017500000001626512664710322020717 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ptr_12.c,v 1.45 2009/12/04 22:06:37 tbox Exp $ */ /* Reviewed: Thu Mar 16 14:05:12 PST 2000 by explorer */ #ifndef RDATA_GENERIC_PTR_12_C #define RDATA_GENERIC_PTR_12_C #define RRTYPE_PTR_ATTRIBUTES (0) static inline isc_result_t fromtext_ptr(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; REQUIRE(type == dns_rdatatype_ptr); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); if (rdclass == dns_rdataclass_in && (options & DNS_RDATA_CHECKNAMES) != 0 && (options & DNS_RDATA_CHECKREVERSE) != 0) { isc_boolean_t ok; ok = dns_name_ishostname(&name, ISC_FALSE); if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) RETTOK(DNS_R_BADNAME); if (!ok && callbacks != NULL) warn_badname(&name, lexer, callbacks); } return (ISC_R_SUCCESS); } static inline isc_result_t totext_ptr(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; REQUIRE(rdata->type == dns_rdatatype_ptr); REQUIRE(rdata->length != 0); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); sub = name_prefix(&name, tctx->origin, &prefix); return (dns_name_totext(&prefix, sub, target)); } static inline isc_result_t fromwire_ptr(ARGS_FROMWIRE) { dns_name_t name; REQUIRE(type == dns_rdatatype_ptr); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, NULL); return (dns_name_fromwire(&name, source, dctx, options, target)); } static inline isc_result_t towire_ptr(ARGS_TOWIRE) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_ptr); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); return (dns_name_towire(&name, cctx, target)); } static inline int compare_ptr(ARGS_COMPARE) { dns_name_t name1; dns_name_t name2; isc_region_t region1; isc_region_t region2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_ptr); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); return (dns_name_rdatacompare(&name1, &name2)); } static inline isc_result_t fromstruct_ptr(ARGS_FROMSTRUCT) { dns_rdata_ptr_t *ptr = source; isc_region_t region; REQUIRE(type == dns_rdatatype_ptr); REQUIRE(source != NULL); REQUIRE(ptr->common.rdtype == type); REQUIRE(ptr->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); dns_name_toregion(&ptr->ptr, ®ion); return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_ptr(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_ptr_t *ptr = target; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_ptr); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); ptr->common.rdclass = rdata->rdclass; ptr->common.rdtype = rdata->type; ISC_LINK_INIT(&ptr->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); dns_name_init(&ptr->ptr, NULL); RETERR(name_duporclone(&name, mctx, &ptr->ptr)); ptr->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_ptr(ARGS_FREESTRUCT) { dns_rdata_ptr_t *ptr = source; REQUIRE(source != NULL); REQUIRE(ptr->common.rdtype == dns_rdatatype_ptr); if (ptr->mctx == NULL) return; dns_name_free(&ptr->ptr, ptr->mctx); ptr->mctx = NULL; } static inline isc_result_t additionaldata_ptr(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_ptr); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_ptr(ARGS_DIGEST) { isc_region_t r; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_ptr); dns_rdata_toregion(rdata, &r); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); return (dns_name_digest(&name, digest, arg)); } static inline isc_boolean_t checkowner_ptr(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_ptr); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static unsigned char ip6_arpa_data[] = "\003IP6\004ARPA"; static unsigned char ip6_arpa_offsets[] = { 0, 4, 9 }; static const dns_name_t ip6_arpa = { DNS_NAME_MAGIC, ip6_arpa_data, 10, 3, DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, ip6_arpa_offsets, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} }; static unsigned char ip6_int_data[] = "\003IP6\003INT"; static unsigned char ip6_int_offsets[] = { 0, 4, 8 }; static const dns_name_t ip6_int = { DNS_NAME_MAGIC, ip6_int_data, 9, 3, DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, ip6_int_offsets, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} }; static unsigned char in_addr_arpa_data[] = "\007IN-ADDR\004ARPA"; static unsigned char in_addr_arpa_offsets[] = { 0, 8, 13 }; static const dns_name_t in_addr_arpa = { DNS_NAME_MAGIC, in_addr_arpa_data, 14, 3, DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, in_addr_arpa_offsets, NULL, {(void *)-1, (void *)-1}, {NULL, NULL} }; static inline isc_boolean_t checknames_ptr(ARGS_CHECKNAMES) { isc_region_t region; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_ptr); if (rdata->rdclass != dns_rdataclass_in) return (ISC_TRUE); if (dns_name_isdnssd(owner)) return (ISC_TRUE); if (dns_name_issubdomain(owner, &in_addr_arpa) || dns_name_issubdomain(owner, &ip6_arpa) || dns_name_issubdomain(owner, &ip6_int)) { dns_rdata_toregion(rdata, ®ion); dns_name_init(&name, NULL); dns_name_fromregion(&name, ®ion); if (!dns_name_ishostname(&name, ISC_FALSE)) { if (bad != NULL) dns_name_clone(&name, bad); return (ISC_FALSE); } } return (ISC_TRUE); } static inline int casecompare_ptr(ARGS_COMPARE) { return (compare_ptr(rdata1, rdata2)); } #endif /* RDATA_GENERIC_PTR_12_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/l32_105.h0000644000470500017500000000175512664710322020600 0ustar lamontlamont/* * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef GENERIC_L32_105_H #define GENERIC_L32_105_H 1 typedef struct dns_rdata_l32 { dns_rdatacommon_t common; isc_uint16_t pref; struct in_addr l32; } dns_rdata_l32_t; #endif /* GENERIC_L32_105_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/rrsig_46.c0000644000470500017500000003262612664710322021246 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* Reviewed: Fri Mar 17 09:05:02 PST 2000 by gson */ /* RFC2535 */ #ifndef RDATA_GENERIC_RRSIG_46_C #define RDATA_GENERIC_RRSIG_46_C #define RRTYPE_RRSIG_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC) static inline isc_result_t fromtext_rrsig(ARGS_FROMTEXT) { isc_token_t token; unsigned char c; long i; dns_rdatatype_t covered; char *e; isc_result_t result; dns_name_t name; isc_buffer_t buffer; isc_uint32_t time_signed, time_expire; REQUIRE(type == dns_rdatatype_rrsig); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); /* * Type covered. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); result = dns_rdatatype_fromtext(&covered, &token.value.as_textregion); if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) { i = strtol(DNS_AS_STR(token), &e, 10); if (i < 0 || i > 65535) RETTOK(ISC_R_RANGE); if (*e != 0) RETTOK(result); covered = (dns_rdatatype_t)i; } RETERR(uint16_tobuffer(covered, target)); /* * Algorithm. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion)); RETERR(mem_tobuffer(target, &c, 1)); /* * Labels. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffU) RETTOK(ISC_R_RANGE); c = (unsigned char)token.value.as_ulong; RETERR(mem_tobuffer(target, &c, 1)); /* * Original ttl. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); RETERR(uint32_tobuffer(token.value.as_ulong, target)); /* * Signature expiration. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (strlen(DNS_AS_STR(token)) <= 10U && *DNS_AS_STR(token) != '-' && *DNS_AS_STR(token) != '+') { char *end; unsigned long u; isc_uint64_t u64; u64 = u = strtoul(DNS_AS_STR(token), &end, 10); if (u == ULONG_MAX || *end != 0) RETTOK(DNS_R_SYNTAX); if (u64 > 0xffffffffUL) RETTOK(ISC_R_RANGE); time_expire = u; } else RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_expire)); RETERR(uint32_tobuffer(time_expire, target)); /* * Time signed. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (strlen(DNS_AS_STR(token)) <= 10U && *DNS_AS_STR(token) != '-' && *DNS_AS_STR(token) != '+') { char *end; unsigned long u; isc_uint64_t u64; u64 = u = strtoul(DNS_AS_STR(token), &end, 10); if (u == ULONG_MAX || *end != 0) RETTOK(DNS_R_SYNTAX); if (u64 > 0xffffffffUL) RETTOK(ISC_R_RANGE); time_signed = u; } else RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_signed)); RETERR(uint32_tobuffer(time_signed, target)); /* * Key footprint. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Signer. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); /* * Sig. */ return (isc_base64_tobuffer(lexer, target, -1)); } static inline isc_result_t totext_rrsig(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("4294967295")]; dns_rdatatype_t covered; unsigned long ttl; unsigned long when; unsigned long exp; unsigned long foot; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_rrsig); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); /* * Type covered. */ covered = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * XXXAG We should have something like dns_rdatatype_isknown() * that does the right thing with type 0. */ if (dns_rdatatype_isknown(covered) && covered != 0) { RETERR(dns_rdatatype_totext(covered, target)); } else { sprintf(buf, "TYPE%u", covered); RETERR(str_totext(buf, target)); } RETERR(str_totext(" ", target)); /* * Algorithm. */ sprintf(buf, "%u", sr.base[0]); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Labels. */ sprintf(buf, "%u", sr.base[0]); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Ttl. */ ttl = uint32_fromregion(&sr); isc_region_consume(&sr, 4); sprintf(buf, "%lu", ttl); RETERR(str_totext(buf, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); /* * Sig exp. */ exp = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(exp, target)); RETERR(str_totext(" ", target)); /* * Time signed. */ when = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(when, target)); RETERR(str_totext(" ", target)); /* * Footprint. */ foot = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%lu", foot); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Signer. */ dns_name_init(&name, NULL); dns_name_fromregion(&name, &sr); isc_region_consume(&sr, name_length(&name)); RETERR(dns_name_totext(&name, ISC_FALSE, target)); /* * Sig. */ RETERR(str_totext(tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) { if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(&sr, 60, "", target)); else RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, target)); } else RETERR(str_totext("[omitted]", target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_rrsig(ARGS_FROMWIRE) { isc_region_t sr; dns_name_t name; REQUIRE(type == dns_rdatatype_rrsig); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); isc_buffer_activeregion(source, &sr); /* * type covered: 2 * algorithm: 1 * labels: 1 * original ttl: 4 * signature expiration: 4 * time signed: 4 * key footprint: 2 */ if (sr.length < 18) return (ISC_R_UNEXPECTEDEND); isc_buffer_forward(source, 18); RETERR(mem_tobuffer(target, sr.base, 18)); /* * Signer. */ dns_name_init(&name, NULL); RETERR(dns_name_fromwire(&name, source, dctx, options, target)); /* * Sig. */ isc_buffer_activeregion(source, &sr); isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); } static inline isc_result_t towire_rrsig(ARGS_TOWIRE) { isc_region_t sr; dns_name_t name; dns_offsets_t offsets; REQUIRE(rdata->type == dns_rdatatype_rrsig); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); dns_rdata_toregion(rdata, &sr); /* * type covered: 2 * algorithm: 1 * labels: 1 * original ttl: 4 * signature expiration: 4 * time signed: 4 * key footprint: 2 */ RETERR(mem_tobuffer(target, sr.base, 18)); isc_region_consume(&sr, 18); /* * Signer. */ dns_name_init(&name, offsets); dns_name_fromregion(&name, &sr); isc_region_consume(&sr, name_length(&name)); RETERR(dns_name_towire(&name, cctx, target)); /* * Signature. */ return (mem_tobuffer(target, sr.base, sr.length)); } static inline int compare_rrsig(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_rrsig); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_rrsig(ARGS_FROMSTRUCT) { dns_rdata_rrsig_t *sig = source; REQUIRE(type == dns_rdatatype_rrsig); REQUIRE(source != NULL); REQUIRE(sig->common.rdtype == type); REQUIRE(sig->common.rdclass == rdclass); REQUIRE(sig->signature != NULL || sig->siglen == 0); UNUSED(type); UNUSED(rdclass); /* * Type covered. */ RETERR(uint16_tobuffer(sig->covered, target)); /* * Algorithm. */ RETERR(uint8_tobuffer(sig->algorithm, target)); /* * Labels. */ RETERR(uint8_tobuffer(sig->labels, target)); /* * Original TTL. */ RETERR(uint32_tobuffer(sig->originalttl, target)); /* * Expire time. */ RETERR(uint32_tobuffer(sig->timeexpire, target)); /* * Time signed. */ RETERR(uint32_tobuffer(sig->timesigned, target)); /* * Key ID. */ RETERR(uint16_tobuffer(sig->keyid, target)); /* * Signer name. */ RETERR(name_tobuffer(&sig->signer, target)); /* * Signature. */ return (mem_tobuffer(target, sig->signature, sig->siglen)); } static inline isc_result_t tostruct_rrsig(ARGS_TOSTRUCT) { isc_region_t sr; dns_rdata_rrsig_t *sig = target; dns_name_t signer; REQUIRE(rdata->type == dns_rdatatype_rrsig); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); sig->common.rdclass = rdata->rdclass; sig->common.rdtype = rdata->type; ISC_LINK_INIT(&sig->common, link); dns_rdata_toregion(rdata, &sr); /* * Type covered. */ sig->covered = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * Algorithm. */ sig->algorithm = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* * Labels. */ sig->labels = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* * Original TTL. */ sig->originalttl = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* * Expire time. */ sig->timeexpire = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* * Time signed. */ sig->timesigned = uint32_fromregion(&sr); isc_region_consume(&sr, 4); /* * Key ID. */ sig->keyid = uint16_fromregion(&sr); isc_region_consume(&sr, 2); dns_name_init(&signer, NULL); dns_name_fromregion(&signer, &sr); dns_name_init(&sig->signer, NULL); RETERR(name_duporclone(&signer, mctx, &sig->signer)); isc_region_consume(&sr, name_length(&sig->signer)); /* * Signature. */ sig->siglen = sr.length; sig->signature = mem_maybedup(mctx, sr.base, sig->siglen); if (sig->signature == NULL) goto cleanup; sig->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (mctx != NULL) dns_name_free(&sig->signer, mctx); return (ISC_R_NOMEMORY); } static inline void freestruct_rrsig(ARGS_FREESTRUCT) { dns_rdata_rrsig_t *sig = (dns_rdata_rrsig_t *) source; REQUIRE(source != NULL); REQUIRE(sig->common.rdtype == dns_rdatatype_rrsig); if (sig->mctx == NULL) return; dns_name_free(&sig->signer, sig->mctx); if (sig->signature != NULL) isc_mem_free(sig->mctx, sig->signature); sig->mctx = NULL; } static inline isc_result_t additionaldata_rrsig(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_rrsig); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_rrsig(ARGS_DIGEST) { REQUIRE(rdata->type == dns_rdatatype_rrsig); UNUSED(rdata); UNUSED(digest); UNUSED(arg); return (ISC_R_NOTIMPLEMENTED); } static inline dns_rdatatype_t covers_rrsig(dns_rdata_t *rdata) { dns_rdatatype_t type; isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_rrsig); dns_rdata_toregion(rdata, &r); type = uint16_fromregion(&r); return (type); } static inline isc_boolean_t checkowner_rrsig(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_rrsig); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_rrsig(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_rrsig); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_rrsig(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; dns_name_t name1; dns_name_t name2; int order; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_rrsig); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); INSIST(r1.length > 18); INSIST(r2.length > 18); r1.length = 18; r2.length = 18; order = isc_region_compare(&r1, &r2); if (order != 0) return (order); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); isc_region_consume(&r1, 18); isc_region_consume(&r2, 18); dns_name_fromregion(&name1, &r1); dns_name_fromregion(&name2, &r2); order = dns_name_rdatacompare(&name1, &name2); if (order != 0) return (order); isc_region_consume(&r1, name_length(&name1)); isc_region_consume(&r2, name_length(&name2)); return (isc_region_compare(&r1, &r2)); } #endif /* RDATA_GENERIC_RRSIG_46_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/mx_15.h0000644000470500017500000000216312664710322020536 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef GENERIC_MX_15_H #define GENERIC_MX_15_H 1 /* $Id: mx_15.h,v 1.29 2007/06/19 23:47:17 tbox Exp $ */ typedef struct dns_rdata_mx { dns_rdatacommon_t common; isc_mem_t *mctx; isc_uint16_t pref; dns_name_t mx; } dns_rdata_mx_t; #endif /* GENERIC_MX_15_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/opt_41.h0000644000470500017500000000317212664710322020714 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_OPT_41_H #define GENERIC_OPT_41_H 1 /* $Id: opt_41.h,v 1.18 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief Per RFC2671 */ typedef struct dns_rdata_opt_opcode { isc_uint16_t opcode; isc_uint16_t length; unsigned char *data; } dns_rdata_opt_opcode_t; typedef struct dns_rdata_opt { dns_rdatacommon_t common; isc_mem_t *mctx; unsigned char *options; isc_uint16_t length; /* private */ isc_uint16_t offset; } dns_rdata_opt_t; /* * ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS are already done * via rdatastructpre.h and rdatastructsuf.h. */ isc_result_t dns_rdata_opt_first(dns_rdata_opt_t *); isc_result_t dns_rdata_opt_next(dns_rdata_opt_t *); isc_result_t dns_rdata_opt_current(dns_rdata_opt_t *, dns_rdata_opt_opcode_t *); #endif /* GENERIC_OPT_41_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/loc_29.h0000644000470500017500000000256512664710322020702 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_LOC_29_H #define GENERIC_LOC_29_H 1 /* $Id: loc_29.h,v 1.19 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief Per RFC1876 */ typedef struct dns_rdata_loc_0 { isc_uint8_t version; /* must be first and zero */ isc_uint8_t size; isc_uint8_t horizontal; isc_uint8_t vertical; isc_uint32_t latitude; isc_uint32_t longitude; isc_uint32_t altitude; } dns_rdata_loc_0_t; typedef struct dns_rdata_loc { dns_rdatacommon_t common; union { dns_rdata_loc_0_t v0; } v; } dns_rdata_loc_t; #endif /* GENERIC_LOC_29_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/ptr_12.h0000644000470500017500000000223112664710322020710 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef GENERIC_PTR_12_H #define GENERIC_PTR_12_H 1 /* $Id: ptr_12.h,v 1.27 2007/06/19 23:47:17 tbox Exp $ */ typedef struct dns_rdata_ptr { dns_rdatacommon_t common; isc_mem_t *mctx; dns_name_t ptr; } dns_rdata_ptr_t; #endif /* GENERIC_PTR_12_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/caa_257.h0000644000470500017500000000212012664710322020717 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_CAA_257_H #define GENERIC_CAA_257_H 1 /* $Id$ */ typedef struct dns_rdata_caa { dns_rdatacommon_t common; isc_mem_t * mctx; isc_uint8_t flags; unsigned char * tag; isc_uint8_t tag_len; unsigned char *value; isc_uint8_t value_len; } dns_rdata_caa_t; #endif /* GENERIC_CAA_257_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/nid_104.c0000644000470500017500000001226012664710322020735 0ustar lamontlamont/* * Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef RDATA_GENERIC_NID_104_C #define RDATA_GENERIC_NID_104_C #include #include #define RRTYPE_NID_ATTRIBUTES (0) static inline isc_result_t fromtext_nid(ARGS_FROMTEXT) { isc_token_t token; unsigned char locator[NS_LOCATORSZ]; REQUIRE(type == dns_rdatatype_nid); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (locator_pton(DNS_AS_STR(token), locator) != 1) RETTOK(DNS_R_SYNTAX); return (mem_tobuffer(target, locator, NS_LOCATORSZ)); } static inline isc_result_t totext_nid(ARGS_TOTEXT) { isc_region_t region; char buf[sizeof("xxxx:xxxx:xxxx:xxxx")]; unsigned short num; REQUIRE(rdata->type == dns_rdatatype_nid); REQUIRE(rdata->length != 0); UNUSED(tctx); dns_rdata_toregion(rdata, ®ion); num = uint16_fromregion(®ion); isc_region_consume(®ion, 2); sprintf(buf, "%u", num); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); sprintf(buf, "%x:%x:%x:%x", region.base[0]<<8 | region.base[1], region.base[2]<<8 | region.base[3], region.base[4]<<8 | region.base[5], region.base[6]<<8 | region.base[7]); return (str_totext(buf, target)); } static inline isc_result_t fromwire_nid(ARGS_FROMWIRE) { isc_region_t sregion; REQUIRE(type == dns_rdatatype_nid); UNUSED(type); UNUSED(options); UNUSED(rdclass); UNUSED(dctx); isc_buffer_activeregion(source, &sregion); if (sregion.length != 10) return (DNS_R_FORMERR); isc_buffer_forward(source, sregion.length); return (mem_tobuffer(target, sregion.base, sregion.length)); } static inline isc_result_t towire_nid(ARGS_TOWIRE) { REQUIRE(rdata->type == dns_rdatatype_nid); REQUIRE(rdata->length == 10); UNUSED(cctx); return (mem_tobuffer(target, rdata->data, rdata->length)); } static inline int compare_nid(ARGS_COMPARE) { isc_region_t region1; isc_region_t region2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_nid); REQUIRE(rdata1->length == 10); REQUIRE(rdata2->length == 10); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); return (isc_region_compare(®ion1, ®ion2)); } static inline isc_result_t fromstruct_nid(ARGS_FROMSTRUCT) { dns_rdata_nid_t *nid = source; REQUIRE(type == dns_rdatatype_nid); REQUIRE(source != NULL); REQUIRE(nid->common.rdtype == type); REQUIRE(nid->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); RETERR(uint16_tobuffer(nid->pref, target)); return (mem_tobuffer(target, nid->nid, sizeof(nid->nid))); } static inline isc_result_t tostruct_nid(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_nid_t *nid = target; REQUIRE(rdata->type == dns_rdatatype_nid); REQUIRE(target != NULL); REQUIRE(rdata->length == 10); UNUSED(mctx); nid->common.rdclass = rdata->rdclass; nid->common.rdtype = rdata->type; ISC_LINK_INIT(&nid->common, link); dns_rdata_toregion(rdata, ®ion); nid->pref = uint16_fromregion(®ion); memmove(nid->nid, region.base, region.length); return (ISC_R_SUCCESS); } static inline void freestruct_nid(ARGS_FREESTRUCT) { dns_rdata_nid_t *nid = source; REQUIRE(source != NULL); REQUIRE(nid->common.rdtype == dns_rdatatype_nid); return; } static inline isc_result_t additionaldata_nid(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_nid); REQUIRE(rdata->length == 10); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_nid(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_nid); REQUIRE(rdata->length == 10); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_nid(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_nid); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_nid(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_nid); REQUIRE(rdata->length == 10); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_nid(ARGS_COMPARE) { return (compare_nid(rdata1, rdata2)); } #endif /* RDATA_GENERIC_NID_104_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/nxt_30.h0000644000470500017500000000225212664710322020717 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_NXT_30_H #define GENERIC_NXT_30_H 1 /* $Id: nxt_30.h,v 1.25 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief RFC2535 */ typedef struct dns_rdata_nxt { dns_rdatacommon_t common; isc_mem_t *mctx; dns_name_t next; unsigned char *typebits; isc_uint16_t len; } dns_rdata_nxt_t; #endif /* GENERIC_NXT_30_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/md_3.c0000644000470500017500000001277712664710322020436 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: md_3.c,v 1.49 2009/12/04 22:06:37 tbox Exp $ */ /* Reviewed: Wed Mar 15 17:48:20 PST 2000 by bwelling */ #ifndef RDATA_GENERIC_MD_3_C #define RDATA_GENERIC_MD_3_C #define RRTYPE_MD_ATTRIBUTES (0) static inline isc_result_t fromtext_md(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; REQUIRE(type == dns_rdatatype_md); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); return (ISC_R_SUCCESS); } static inline isc_result_t totext_md(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; REQUIRE(rdata->type == dns_rdatatype_md); REQUIRE(rdata->length != 0); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); sub = name_prefix(&name, tctx->origin, &prefix); return (dns_name_totext(&prefix, sub, target)); } static inline isc_result_t fromwire_md(ARGS_FROMWIRE) { dns_name_t name; REQUIRE(type == dns_rdatatype_md); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, NULL); return (dns_name_fromwire(&name, source, dctx, options, target)); } static inline isc_result_t towire_md(ARGS_TOWIRE) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_md); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); return (dns_name_towire(&name, cctx, target)); } static inline int compare_md(ARGS_COMPARE) { dns_name_t name1; dns_name_t name2; isc_region_t region1; isc_region_t region2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_md); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); return (dns_name_rdatacompare(&name1, &name2)); } static inline isc_result_t fromstruct_md(ARGS_FROMSTRUCT) { dns_rdata_md_t *md = source; isc_region_t region; REQUIRE(type == dns_rdatatype_md); REQUIRE(source != NULL); REQUIRE(md->common.rdtype == type); REQUIRE(md->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); dns_name_toregion(&md->md, ®ion); return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_md(ARGS_TOSTRUCT) { dns_rdata_md_t *md = target; isc_region_t r; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_md); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); md->common.rdclass = rdata->rdclass; md->common.rdtype = rdata->type; ISC_LINK_INIT(&md->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, &r); dns_name_fromregion(&name, &r); dns_name_init(&md->md, NULL); RETERR(name_duporclone(&name, mctx, &md->md)); md->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_md(ARGS_FREESTRUCT) { dns_rdata_md_t *md = source; REQUIRE(source != NULL); REQUIRE(md->common.rdtype == dns_rdatatype_md); if (md->mctx == NULL) return; dns_name_free(&md->md, md->mctx); md->mctx = NULL; } static inline isc_result_t additionaldata_md(ARGS_ADDLDATA) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_md); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); return ((add)(arg, &name, dns_rdatatype_a)); } static inline isc_result_t digest_md(ARGS_DIGEST) { isc_region_t r; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_md); dns_rdata_toregion(rdata, &r); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); return (dns_name_digest(&name, digest, arg)); } static inline isc_boolean_t checkowner_md(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_md); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_md(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_md); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_md(ARGS_COMPARE) { return (compare_md(rdata1, rdata2)); } #endif /* RDATA_GENERIC_MD_3_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/gpos_27.h0000644000470500017500000000236212664710322021066 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_GPOS_27_H #define GENERIC_GPOS_27_H 1 /* $Id: gpos_27.h,v 1.17 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief per RFC1712 */ typedef struct dns_rdata_gpos { dns_rdatacommon_t common; isc_mem_t *mctx; char *longitude; char *latitude; char *altitude; isc_uint8_t long_len; isc_uint8_t lat_len; isc_uint8_t alt_len; } dns_rdata_gpos_t; #endif /* GENERIC_GPOS_27_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/ds_43.h0000644000470500017500000000237612664710322020527 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ds_43.h,v 1.7 2007/06/19 23:47:17 tbox Exp $ */ #ifndef GENERIC_DS_43_H #define GENERIC_DS_43_H 1 /*! * \brief per draft-ietf-dnsext-delegation-signer-05.txt */ typedef struct dns_rdata_ds { dns_rdatacommon_t common; isc_mem_t *mctx; isc_uint16_t key_tag; isc_uint8_t algorithm; isc_uint8_t digest_type; isc_uint16_t length; unsigned char *digest; } dns_rdata_ds_t; #endif /* GENERIC_DS_43_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/rp_17.c0000644000470500017500000001700312664710322020527 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rp_17.c,v 1.44 2009/12/04 22:06:37 tbox Exp $ */ /* RFC1183 */ #ifndef RDATA_GENERIC_RP_17_C #define RDATA_GENERIC_RP_17_C #define RRTYPE_RP_ATTRIBUTES (0) static inline isc_result_t fromtext_rp(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; int i; isc_boolean_t ok; REQUIRE(type == dns_rdatatype_rp); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); origin = (origin != NULL) ? origin : dns_rootname; for (i = 0; i < 2; i++) { RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); ok = ISC_TRUE; if ((options & DNS_RDATA_CHECKNAMES) != 0 && i == 0) ok = dns_name_ismailbox(&name); if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) RETTOK(DNS_R_BADNAME); if (!ok && callbacks != NULL) warn_badname(&name, lexer, callbacks); } return (ISC_R_SUCCESS); } static inline isc_result_t totext_rp(ARGS_TOTEXT) { isc_region_t region; dns_name_t rmail; dns_name_t email; dns_name_t prefix; isc_boolean_t sub; REQUIRE(rdata->type == dns_rdatatype_rp); REQUIRE(rdata->length != 0); dns_name_init(&rmail, NULL); dns_name_init(&email, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&rmail, ®ion); isc_region_consume(®ion, rmail.length); dns_name_fromregion(&email, ®ion); isc_region_consume(®ion, email.length); sub = name_prefix(&rmail, tctx->origin, &prefix); RETERR(dns_name_totext(&prefix, sub, target)); RETERR(str_totext(" ", target)); sub = name_prefix(&email, tctx->origin, &prefix); return (dns_name_totext(&prefix, sub, target)); } static inline isc_result_t fromwire_rp(ARGS_FROMWIRE) { dns_name_t rmail; dns_name_t email; REQUIRE(type == dns_rdatatype_rp); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); dns_name_init(&rmail, NULL); dns_name_init(&email, NULL); RETERR(dns_name_fromwire(&rmail, source, dctx, options, target)); return (dns_name_fromwire(&email, source, dctx, options, target)); } static inline isc_result_t towire_rp(ARGS_TOWIRE) { isc_region_t region; dns_name_t rmail; dns_name_t email; dns_offsets_t roffsets; dns_offsets_t eoffsets; REQUIRE(rdata->type == dns_rdatatype_rp); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); dns_name_init(&rmail, roffsets); dns_name_init(&email, eoffsets); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&rmail, ®ion); isc_region_consume(®ion, rmail.length); RETERR(dns_name_towire(&rmail, cctx, target)); dns_name_fromregion(&rmail, ®ion); isc_region_consume(®ion, rmail.length); return (dns_name_towire(&rmail, cctx, target)); } static inline int compare_rp(ARGS_COMPARE) { isc_region_t region1; isc_region_t region2; dns_name_t name1; dns_name_t name2; int order; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_rp); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); order = dns_name_rdatacompare(&name1, &name2); if (order != 0) return (order); isc_region_consume(®ion1, name_length(&name1)); isc_region_consume(®ion2, name_length(&name2)); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); return (dns_name_rdatacompare(&name1, &name2)); } static inline isc_result_t fromstruct_rp(ARGS_FROMSTRUCT) { dns_rdata_rp_t *rp = source; isc_region_t region; REQUIRE(type == dns_rdatatype_rp); REQUIRE(source != NULL); REQUIRE(rp->common.rdtype == type); REQUIRE(rp->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); dns_name_toregion(&rp->mail, ®ion); RETERR(isc_buffer_copyregion(target, ®ion)); dns_name_toregion(&rp->text, ®ion); return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_rp(ARGS_TOSTRUCT) { isc_result_t result; isc_region_t region; dns_rdata_rp_t *rp = target; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_rp); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); rp->common.rdclass = rdata->rdclass; rp->common.rdtype = rdata->type; ISC_LINK_INIT(&rp->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); dns_name_init(&rp->mail, NULL); RETERR(name_duporclone(&name, mctx, &rp->mail)); isc_region_consume(®ion, name_length(&name)); dns_name_fromregion(&name, ®ion); dns_name_init(&rp->text, NULL); result = name_duporclone(&name, mctx, &rp->text); if (result != ISC_R_SUCCESS) goto cleanup; rp->mctx = mctx; return (ISC_R_SUCCESS); cleanup: if (mctx != NULL) dns_name_free(&rp->mail, mctx); return (ISC_R_NOMEMORY); } static inline void freestruct_rp(ARGS_FREESTRUCT) { dns_rdata_rp_t *rp = source; REQUIRE(source != NULL); REQUIRE(rp->common.rdtype == dns_rdatatype_rp); if (rp->mctx == NULL) return; dns_name_free(&rp->mail, rp->mctx); dns_name_free(&rp->text, rp->mctx); rp->mctx = NULL; } static inline isc_result_t additionaldata_rp(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_rp); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_rp(ARGS_DIGEST) { isc_region_t r; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_rp); dns_rdata_toregion(rdata, &r); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); RETERR(dns_name_digest(&name, digest, arg)); isc_region_consume(&r, name_length(&name)); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); return (dns_name_digest(&name, digest, arg)); } static inline isc_boolean_t checkowner_rp(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_rp); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_rp(ARGS_CHECKNAMES) { isc_region_t region; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_rp); UNUSED(owner); dns_rdata_toregion(rdata, ®ion); dns_name_init(&name, NULL); dns_name_fromregion(&name, ®ion); if (!dns_name_ismailbox(&name)) { if (bad != NULL) dns_name_clone(&name, bad); return (ISC_FALSE); } return (ISC_TRUE); } static inline int casecompare_rp(ARGS_COMPARE) { return (compare_rp(rdata1, rdata2)); } #endif /* RDATA_GENERIC_RP_17_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/null_10.c0000644000470500017500000001035412664710322021053 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2011, 2012, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* Reviewed: Thu Mar 16 13:57:50 PST 2000 by explorer */ #ifndef RDATA_GENERIC_NULL_10_C #define RDATA_GENERIC_NULL_10_C #define RRTYPE_NULL_ATTRIBUTES (0) static inline isc_result_t fromtext_null(ARGS_FROMTEXT) { REQUIRE(type == dns_rdatatype_null); UNUSED(rdclass); UNUSED(type); UNUSED(lexer); UNUSED(origin); UNUSED(options); UNUSED(target); UNUSED(callbacks); return (DNS_R_SYNTAX); } static inline isc_result_t totext_null(ARGS_TOTEXT) { REQUIRE(rdata->type == dns_rdatatype_null); return (unknown_totext(rdata, tctx, target)); } static inline isc_result_t fromwire_null(ARGS_FROMWIRE) { isc_region_t sr; REQUIRE(type == dns_rdatatype_null); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); isc_buffer_activeregion(source, &sr); isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); } static inline isc_result_t towire_null(ARGS_TOWIRE) { REQUIRE(rdata->type == dns_rdatatype_null); UNUSED(cctx); return (mem_tobuffer(target, rdata->data, rdata->length)); } static inline int compare_null(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_null); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_null(ARGS_FROMSTRUCT) { dns_rdata_null_t *null = source; REQUIRE(type == dns_rdatatype_null); REQUIRE(source != NULL); REQUIRE(null->common.rdtype == type); REQUIRE(null->common.rdclass == rdclass); REQUIRE(null->data != NULL || null->length == 0); UNUSED(type); UNUSED(rdclass); return (mem_tobuffer(target, null->data, null->length)); } static inline isc_result_t tostruct_null(ARGS_TOSTRUCT) { dns_rdata_null_t *null = target; isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_null); REQUIRE(target != NULL); null->common.rdclass = rdata->rdclass; null->common.rdtype = rdata->type; ISC_LINK_INIT(&null->common, link); dns_rdata_toregion(rdata, &r); null->length = r.length; null->data = mem_maybedup(mctx, r.base, r.length); if (null->data == NULL) return (ISC_R_NOMEMORY); null->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_null(ARGS_FREESTRUCT) { dns_rdata_null_t *null = source; REQUIRE(source != NULL); REQUIRE(null->common.rdtype == dns_rdatatype_null); if (null->mctx == NULL) return; if (null->data != NULL) isc_mem_free(null->mctx, null->data); null->mctx = NULL; } static inline isc_result_t additionaldata_null(ARGS_ADDLDATA) { UNUSED(rdata); UNUSED(add); UNUSED(arg); REQUIRE(rdata->type == dns_rdatatype_null); return (ISC_R_SUCCESS); } static inline isc_result_t digest_null(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_null); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_null(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_null); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_null(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_null); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_null(ARGS_COMPARE) { return (compare_null(rdata1, rdata2)); } #endif /* RDATA_GENERIC_NULL_10_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/cname_5.c0000644000470500017500000001304112664710322021104 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: cname_5.c,v 1.49 2009/12/04 22:06:37 tbox Exp $ */ /* reviewed: Wed Mar 15 16:48:45 PST 2000 by brister */ #ifndef RDATA_GENERIC_CNAME_5_C #define RDATA_GENERIC_CNAME_5_C #define RRTYPE_CNAME_ATTRIBUTES \ (DNS_RDATATYPEATTR_EXCLUSIVE | DNS_RDATATYPEATTR_SINGLETON) static inline isc_result_t fromtext_cname(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; REQUIRE(type == dns_rdatatype_cname); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); return (ISC_R_SUCCESS); } static inline isc_result_t totext_cname(ARGS_TOTEXT) { isc_region_t region; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; REQUIRE(rdata->type == dns_rdatatype_cname); REQUIRE(rdata->length != 0); dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); sub = name_prefix(&name, tctx->origin, &prefix); return (dns_name_totext(&prefix, sub, target)); } static inline isc_result_t fromwire_cname(ARGS_FROMWIRE) { dns_name_t name; REQUIRE(type == dns_rdatatype_cname); UNUSED(type); UNUSED(rdclass); dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, NULL); return (dns_name_fromwire(&name, source, dctx, options, target)); } static inline isc_result_t towire_cname(ARGS_TOWIRE) { dns_name_t name; dns_offsets_t offsets; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_cname); REQUIRE(rdata->length != 0); dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); dns_name_init(&name, offsets); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); return (dns_name_towire(&name, cctx, target)); } static inline int compare_cname(ARGS_COMPARE) { dns_name_t name1; dns_name_t name2; isc_region_t region1; isc_region_t region2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_cname); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_name_init(&name1, NULL); dns_name_init(&name2, NULL); dns_rdata_toregion(rdata1, ®ion1); dns_rdata_toregion(rdata2, ®ion2); dns_name_fromregion(&name1, ®ion1); dns_name_fromregion(&name2, ®ion2); return (dns_name_rdatacompare(&name1, &name2)); } static inline isc_result_t fromstruct_cname(ARGS_FROMSTRUCT) { dns_rdata_cname_t *cname = source; isc_region_t region; REQUIRE(type == dns_rdatatype_cname); REQUIRE(source != NULL); REQUIRE(cname->common.rdtype == type); REQUIRE(cname->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); dns_name_toregion(&cname->cname, ®ion); return (isc_buffer_copyregion(target, ®ion)); } static inline isc_result_t tostruct_cname(ARGS_TOSTRUCT) { isc_region_t region; dns_rdata_cname_t *cname = target; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_cname); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); cname->common.rdclass = rdata->rdclass; cname->common.rdtype = rdata->type; ISC_LINK_INIT(&cname->common, link); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); dns_name_fromregion(&name, ®ion); dns_name_init(&cname->cname, NULL); RETERR(name_duporclone(&name, mctx, &cname->cname)); cname->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_cname(ARGS_FREESTRUCT) { dns_rdata_cname_t *cname = source; REQUIRE(source != NULL); if (cname->mctx == NULL) return; dns_name_free(&cname->cname, cname->mctx); cname->mctx = NULL; } static inline isc_result_t additionaldata_cname(ARGS_ADDLDATA) { UNUSED(rdata); UNUSED(add); UNUSED(arg); REQUIRE(rdata->type == dns_rdatatype_cname); return (ISC_R_SUCCESS); } static inline isc_result_t digest_cname(ARGS_DIGEST) { isc_region_t r; dns_name_t name; REQUIRE(rdata->type == dns_rdatatype_cname); dns_rdata_toregion(rdata, &r); dns_name_init(&name, NULL); dns_name_fromregion(&name, &r); return (dns_name_digest(&name, digest, arg)); } static inline isc_boolean_t checkowner_cname(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_cname); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_cname(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_cname); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_cname(ARGS_COMPARE) { return (compare_cname(rdata1, rdata2)); } #endif /* RDATA_GENERIC_CNAME_5_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/eui64_109.h0000644000470500017500000000174612664710322021140 0ustar lamontlamont/* * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* */ #ifndef GENERIC_EUI64_109_H #define GENERIC_EUI64_109_H 1 typedef struct dns_rdata_eui64 { dns_rdatacommon_t common; unsigned char eui64[8]; } dns_rdata_eui64_t; #endif /* GENERIC_EUI64_10k_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/cds_59.c0000644000470500017500000002024612664710322020670 0ustar lamontlamont/* * Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* draft-ietf-dnsop-delegation-trust-maintainance-14 */ #ifndef RDATA_GENERIC_CDS_59_C #define RDATA_GENERIC_CDS_59_C #define RRTYPE_CDS_ATTRIBUTES 0 #include #include #include #include "dst_gost.h" static inline isc_result_t fromtext_cds(ARGS_FROMTEXT) { isc_token_t token; unsigned char c; int length; REQUIRE(type == dns_rdatatype_cds); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); /* * Key tag. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Algorithm. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion)); RETERR(mem_tobuffer(target, &c, 1)); /* * Digest type. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_dsdigest_fromtext(&c, &token.value.as_textregion)); RETERR(mem_tobuffer(target, &c, 1)); /* * Digest. */ switch (c) { case DNS_DSDIGEST_SHA1: length = ISC_SHA1_DIGESTLENGTH; break; case DNS_DSDIGEST_SHA256: length = ISC_SHA256_DIGESTLENGTH; break; #ifdef ISC_GOST_DIGESTLENGTH case DNS_DSDIGEST_GOST: length = ISC_GOST_DIGESTLENGTH; break; #endif case DNS_DSDIGEST_SHA384: length = ISC_SHA384_DIGESTLENGTH; break; default: length = -1; break; } return (isc_hex_tobuffer(lexer, target, length)); } static inline isc_result_t totext_cds(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("64000 ")]; unsigned int n; REQUIRE(rdata->type == dns_rdatatype_cds); REQUIRE(rdata->length != 0); UNUSED(tctx); dns_rdata_toregion(rdata, &sr); /* * Key tag. */ n = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%u ", n); RETERR(str_totext(buf, target)); /* * Algorithm. */ n = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u ", n); RETERR(str_totext(buf, target)); /* * Digest type. */ n = uint8_fromregion(&sr); isc_region_consume(&sr, 1); sprintf(buf, "%u", n); RETERR(str_totext(buf, target)); /* * Digest. */ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) { if (tctx->width == 0) /* No splitting */ RETERR(isc_hex_totext(&sr, 0, "", target)); else RETERR(isc_hex_totext(&sr, tctx->width - 2, tctx->linebreak, target)); } else RETERR(str_totext("[omitted]", target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_cds(ARGS_FROMWIRE) { isc_region_t sr; REQUIRE(type == dns_rdatatype_cds); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); isc_buffer_activeregion(source, &sr); /* * Check digest lengths if we know them. */ if (sr.length < 4 || (sr.base[3] == DNS_DSDIGEST_SHA1 && sr.length < 4 + ISC_SHA1_DIGESTLENGTH) || (sr.base[3] == DNS_DSDIGEST_SHA256 && sr.length < 4 + ISC_SHA256_DIGESTLENGTH) || #ifdef ISC_GOST_DIGESTLENGTH (sr.base[3] == DNS_DSDIGEST_GOST && sr.length < 4 + ISC_GOST_DIGESTLENGTH) || #endif (sr.base[3] == DNS_DSDIGEST_SHA384 && sr.length < 4 + ISC_SHA384_DIGESTLENGTH)) return (ISC_R_UNEXPECTEDEND); /* * Only copy digest lengths if we know them. * If there is extra data dns_rdata_fromwire() will * detect that. */ if (sr.base[3] == DNS_DSDIGEST_SHA1) sr.length = 4 + ISC_SHA1_DIGESTLENGTH; else if (sr.base[3] == DNS_DSDIGEST_SHA256) sr.length = 4 + ISC_SHA256_DIGESTLENGTH; #ifdef ISC_GOST_DIGESTLENGTH else if (sr.base[3] == DNS_DSDIGEST_GOST) sr.length = 4 + ISC_GOST_DIGESTLENGTH; #endif else if (sr.base[3] == DNS_DSDIGEST_SHA384) sr.length = 4 + ISC_SHA384_DIGESTLENGTH; isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); } static inline isc_result_t towire_cds(ARGS_TOWIRE) { isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_cds); REQUIRE(rdata->length != 0); UNUSED(cctx); dns_rdata_toregion(rdata, &sr); return (mem_tobuffer(target, sr.base, sr.length)); } static inline int compare_cds(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_cds); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_cds(ARGS_FROMSTRUCT) { dns_rdata_cds_t *ds = source; REQUIRE(type == dns_rdatatype_cds); REQUIRE(source != NULL); REQUIRE(ds->common.rdtype == type); REQUIRE(ds->common.rdclass == rdclass); switch (ds->digest_type) { case DNS_DSDIGEST_SHA1: REQUIRE(ds->length == ISC_SHA1_DIGESTLENGTH); break; case DNS_DSDIGEST_SHA256: REQUIRE(ds->length == ISC_SHA256_DIGESTLENGTH); break; #ifdef ISC_GOST_DIGESTLENGTH case DNS_DSDIGEST_GOST: REQUIRE(ds->length == ISC_GOST_DIGESTLENGTH); break; #endif case DNS_DSDIGEST_SHA384: REQUIRE(ds->length == ISC_SHA384_DIGESTLENGTH); break; } UNUSED(type); UNUSED(rdclass); RETERR(uint16_tobuffer(ds->key_tag, target)); RETERR(uint8_tobuffer(ds->algorithm, target)); RETERR(uint8_tobuffer(ds->digest_type, target)); return (mem_tobuffer(target, ds->digest, ds->length)); } static inline isc_result_t tostruct_cds(ARGS_TOSTRUCT) { dns_rdata_cds_t *ds = target; isc_region_t region; REQUIRE(rdata->type == dns_rdatatype_cds); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); ds->common.rdclass = rdata->rdclass; ds->common.rdtype = rdata->type; ISC_LINK_INIT(&ds->common, link); dns_rdata_toregion(rdata, ®ion); ds->key_tag = uint16_fromregion(®ion); isc_region_consume(®ion, 2); ds->algorithm = uint8_fromregion(®ion); isc_region_consume(®ion, 1); ds->digest_type = uint8_fromregion(®ion); isc_region_consume(®ion, 1); ds->length = region.length; ds->digest = mem_maybedup(mctx, region.base, region.length); if (ds->digest == NULL) return (ISC_R_NOMEMORY); ds->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_cds(ARGS_FREESTRUCT) { dns_rdata_cds_t *ds = source; REQUIRE(ds != NULL); REQUIRE(ds->common.rdtype == dns_rdatatype_cds); if (ds->mctx == NULL) return; if (ds->digest != NULL) isc_mem_free(ds->mctx, ds->digest); ds->mctx = NULL; } static inline isc_result_t additionaldata_cds(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_cds); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_cds(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_cds); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_cds(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_cds); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_cds(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_cds); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_cds(ARGS_COMPARE) { return (compare_cds(rdata1, rdata2)); } #endif /* RDATA_GENERIC_CDS_59_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/spf_99.h0000644000470500017500000000267412664710322020725 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_SPF_99_H #define GENERIC_SPF_99_H 1 /* $Id: spf_99.h,v 1.4 2007/06/19 23:47:17 tbox Exp $ */ typedef struct dns_rdata_spf_string { isc_uint8_t length; unsigned char *data; } dns_rdata_spf_string_t; typedef struct dns_rdata_spf { dns_rdatacommon_t common; isc_mem_t *mctx; unsigned char *txt; isc_uint16_t txt_len; /* private */ isc_uint16_t offset; } dns_rdata_spf_t; /* * ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS are already done * via rdatastructpre.h and rdatastructsuf.h. */ #endif /* GENERIC_SPF_99_H */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/cdnskey_60.c0000644000470500017500000002241712664710322021551 0ustar lamontlamont/* * Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* draft-ietf-dnsop-delegation-trust-maintainance-14 */ #ifndef RDATA_GENERIC_CDNSKEY_60_C #define RDATA_GENERIC_CDNSKEY_60_C #include #define RRTYPE_CDNSKEY_ATTRIBUTES 0 static inline isc_result_t fromtext_cdnskey(ARGS_FROMTEXT) { isc_result_t result; isc_token_t token; dns_secalg_t alg; dns_secproto_t proto; dns_keyflags_t flags; REQUIRE(type == dns_rdatatype_cdnskey); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); /* flags */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion)); RETERR(uint16_tobuffer(flags, target)); /* protocol */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion)); RETERR(mem_tobuffer(target, &proto, 1)); /* algorithm */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion)); RETERR(mem_tobuffer(target, &alg, 1)); /* No Key? */ if ((flags & 0xc000) == 0xc000) return (ISC_R_SUCCESS); result = isc_base64_tobuffer(lexer, target, -1); if (result != ISC_R_SUCCESS) return (result); /* Ensure there's at least enough data to compute a key ID for MD5 */ if (alg == DST_ALG_RSAMD5 && isc_buffer_usedlength(target) < 7) return (ISC_R_UNEXPECTEDEND); return (ISC_R_SUCCESS); } static inline isc_result_t totext_cdnskey(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("[key id = 64000]")]; unsigned int flags; unsigned char algorithm; char algbuf[DNS_NAME_FORMATSIZE]; const char *keyinfo; isc_region_t tmpr; REQUIRE(rdata->type == dns_rdatatype_cdnskey); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); /* flags */ flags = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%u", flags); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); if ((flags & DNS_KEYFLAG_KSK) != 0) { if (flags & DNS_KEYFLAG_REVOKE) keyinfo = "revoked KSK"; else keyinfo = "KSK"; } else keyinfo = "ZSK"; /* protocol */ sprintf(buf, "%u", sr.base[0]); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* algorithm */ algorithm = sr.base[0]; sprintf(buf, "%u", algorithm); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); /* No Key? */ if ((flags & 0xc000) == 0xc000) return (ISC_R_SUCCESS); if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0 && algorithm == DNS_KEYALG_PRIVATEDNS) { dns_name_t name; dns_name_init(&name, NULL); dns_name_fromregion(&name, &sr); dns_name_format(&name, algbuf, sizeof(algbuf)); } else { dns_secalg_format((dns_secalg_t) algorithm, algbuf, sizeof(algbuf)); } /* key */ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) { if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(&sr, 0, "", target)); else RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, target)); } else { dns_rdata_toregion(rdata, &tmpr); snprintf(buf, sizeof(buf), "[key id = %u]", dst_region_computeid(&tmpr, algorithm)); RETERR(str_totext(buf, target)); } if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) RETERR(str_totext(tctx->linebreak, target)); else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" ", target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(")", target)); if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) { RETERR(str_totext(" ; ", target)); RETERR(str_totext(keyinfo, target)); RETERR(str_totext("; alg = ", target)); RETERR(str_totext(algbuf, target)); RETERR(str_totext("; key id = ", target)); dns_rdata_toregion(rdata, &tmpr); sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm)); RETERR(str_totext(buf, target)); } return (ISC_R_SUCCESS); } static inline isc_result_t fromwire_cdnskey(ARGS_FROMWIRE) { unsigned char algorithm; isc_region_t sr; REQUIRE(type == dns_rdatatype_cdnskey); UNUSED(type); UNUSED(rdclass); UNUSED(dctx); UNUSED(options); isc_buffer_activeregion(source, &sr); if (sr.length < 4) return (ISC_R_UNEXPECTEDEND); algorithm = sr.base[3]; RETERR(mem_tobuffer(target, sr.base, 4)); isc_region_consume(&sr, 4); isc_buffer_forward(source, 4); if (algorithm == DNS_KEYALG_PRIVATEDNS) { dns_name_t name; dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); dns_name_init(&name, NULL); RETERR(dns_name_fromwire(&name, source, dctx, options, target)); } /* * RSAMD5 computes key ID differently from other * algorithms: we need to ensure there's enough data * present for the computation */ if (algorithm == DST_ALG_RSAMD5 && sr.length < 3) return (ISC_R_UNEXPECTEDEND); isc_buffer_activeregion(source, &sr); isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); } static inline isc_result_t towire_cdnskey(ARGS_TOWIRE) { isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_cdnskey); REQUIRE(rdata->length != 0); UNUSED(cctx); dns_rdata_toregion(rdata, &sr); return (mem_tobuffer(target, sr.base, sr.length)); } static inline int compare_cdnskey(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_cdnskey); REQUIRE(rdata1->length != 0); REQUIRE(rdata2->length != 0); dns_rdata_toregion(rdata1, &r1); dns_rdata_toregion(rdata2, &r2); return (isc_region_compare(&r1, &r2)); } static inline isc_result_t fromstruct_cdnskey(ARGS_FROMSTRUCT) { dns_rdata_cdnskey_t *dnskey = source; REQUIRE(type == dns_rdatatype_cdnskey); REQUIRE(source != NULL); REQUIRE(dnskey->common.rdtype == type); REQUIRE(dnskey->common.rdclass == rdclass); UNUSED(type); UNUSED(rdclass); /* Flags */ RETERR(uint16_tobuffer(dnskey->flags, target)); /* Protocol */ RETERR(uint8_tobuffer(dnskey->protocol, target)); /* Algorithm */ RETERR(uint8_tobuffer(dnskey->algorithm, target)); /* Data */ return (mem_tobuffer(target, dnskey->data, dnskey->datalen)); } static inline isc_result_t tostruct_cdnskey(ARGS_TOSTRUCT) { dns_rdata_cdnskey_t *dnskey = target; isc_region_t sr; REQUIRE(rdata->type == dns_rdatatype_cdnskey); REQUIRE(target != NULL); REQUIRE(rdata->length != 0); dnskey->common.rdclass = rdata->rdclass; dnskey->common.rdtype = rdata->type; ISC_LINK_INIT(&dnskey->common, link); dns_rdata_toregion(rdata, &sr); /* Flags */ if (sr.length < 2) return (ISC_R_UNEXPECTEDEND); dnskey->flags = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* Protocol */ if (sr.length < 1) return (ISC_R_UNEXPECTEDEND); dnskey->protocol = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* Algorithm */ if (sr.length < 1) return (ISC_R_UNEXPECTEDEND); dnskey->algorithm = uint8_fromregion(&sr); isc_region_consume(&sr, 1); /* Data */ dnskey->datalen = sr.length; dnskey->data = mem_maybedup(mctx, sr.base, dnskey->datalen); if (dnskey->data == NULL) return (ISC_R_NOMEMORY); dnskey->mctx = mctx; return (ISC_R_SUCCESS); } static inline void freestruct_cdnskey(ARGS_FREESTRUCT) { dns_rdata_cdnskey_t *dnskey = (dns_rdata_cdnskey_t *) source; REQUIRE(source != NULL); REQUIRE(dnskey->common.rdtype == dns_rdatatype_cdnskey); if (dnskey->mctx == NULL) return; if (dnskey->data != NULL) isc_mem_free(dnskey->mctx, dnskey->data); dnskey->mctx = NULL; } static inline isc_result_t additionaldata_cdnskey(ARGS_ADDLDATA) { REQUIRE(rdata->type == dns_rdatatype_cdnskey); UNUSED(rdata); UNUSED(add); UNUSED(arg); return (ISC_R_SUCCESS); } static inline isc_result_t digest_cdnskey(ARGS_DIGEST) { isc_region_t r; REQUIRE(rdata->type == dns_rdatatype_cdnskey); dns_rdata_toregion(rdata, &r); return ((digest)(arg, &r)); } static inline isc_boolean_t checkowner_cdnskey(ARGS_CHECKOWNER) { REQUIRE(type == dns_rdatatype_cdnskey); UNUSED(name); UNUSED(type); UNUSED(rdclass); UNUSED(wildcard); return (ISC_TRUE); } static inline isc_boolean_t checknames_cdnskey(ARGS_CHECKNAMES) { REQUIRE(rdata->type == dns_rdatatype_cdnskey); UNUSED(rdata); UNUSED(owner); UNUSED(bad); return (ISC_TRUE); } static inline int casecompare_cdnskey(ARGS_COMPARE) { /* * Treat ALG 253 (private DNS) subtype name case sensistively. */ return (compare_cdnskey(rdata1, rdata2)); } #endif /* RDATA_GENERIC_CDNSKEY_60_C */ bind9-9.10.3.dfsg.P4/lib/dns/rdata/generic/dnskey_48.h0000644000470500017500000000244212664710322021415 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef GENERIC_DNSKEY_48_H #define GENERIC_DNSKEY_48_H 1 /* $Id: dnskey_48.h,v 1.7 2007/06/19 23:47:17 tbox Exp $ */ /*! * \brief per RFC2535 */ typedef struct dns_rdata_dnskey { dns_rdatacommon_t common; isc_mem_t * mctx; isc_uint16_t flags; isc_uint8_t protocol; isc_uint8_t algorithm; isc_uint16_t datalen; unsigned char * data; } dns_rdata_dnskey_t; #endif /* GENERIC_DNSKEY_48_H */ bind9-9.10.3.dfsg.P4/lib/dns/journal.c0000644000470500017500000017161612664710322016555 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007-2011, 2013-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: journal.c,v 1.120 2011/12/22 07:32:41 each Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /*! \file * \brief Journaling. * * A journal file consists of * * \li A fixed-size header of type journal_rawheader_t. * * \li The index. This is an unordered array of index entries * of type journal_rawpos_t giving the locations * of some arbitrary subset of the journal's addressable * transactions. The index entries are used as hints to * speed up the process of locating a transaction with a given * serial number. Unused index entries have an "offset" * field of zero. The size of the index can vary between * journal files, but does not change during the lifetime * of a file. The size can be zero. * * \li The journal data. This consists of one or more transactions. * Each transaction begins with a transaction header of type * journal_rawxhdr_t. The transaction header is followed by a * sequence of RRs, similar in structure to an IXFR difference * sequence (RFC1995). That is, the pre-transaction SOA, * zero or more other deleted RRs, the post-transaction SOA, * and zero or more other added RRs. Unlike in IXFR, each RR * is prefixed with a 32-bit length. * * The journal data part grows as new transactions are * appended to the file. Only those transactions * whose serial number is current-(2^31-1) to current * are considered "addressable" and may be pointed * to from the header or index. They may be preceded * by old transactions that are no longer addressable, * and they may be followed by transactions that were * appended to the journal but never committed by updating * the "end" position in the header. The latter will * be overwritten when new transactions are added. */ /*% * When true, accept IXFR difference sequences where the * SOA serial number does not change (BIND 8 sends such * sequences). */ static isc_boolean_t bind8_compat = ISC_TRUE; /* XXX config */ /**************************************************************************/ /* * Miscellaneous utilities. */ #define JOURNAL_COMMON_LOGARGS \ dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_JOURNAL #define JOURNAL_DEBUG_LOGARGS(n) \ JOURNAL_COMMON_LOGARGS, ISC_LOG_DEBUG(n) /*% * It would be non-sensical (or at least obtuse) to use FAIL() with an * ISC_R_SUCCESS code, but the test is there to keep the Solaris compiler * from complaining about "end-of-loop code not reached". */ #define FAIL(code) \ do { result = (code); \ if (result != ISC_R_SUCCESS) goto failure; \ } while (0) #define CHECK(op) \ do { result = (op); \ if (result != ISC_R_SUCCESS) goto failure; \ } while (0) #define JOURNAL_SERIALSET 0x01U static isc_result_t index_to_disk(dns_journal_t *); static inline isc_uint32_t decode_uint32(unsigned char *p) { return ((p[0] << 24) + (p[1] << 16) + (p[2] << 8) + (p[3] << 0)); } static inline void encode_uint32(isc_uint32_t val, unsigned char *p) { p[0] = (isc_uint8_t)(val >> 24); p[1] = (isc_uint8_t)(val >> 16); p[2] = (isc_uint8_t)(val >> 8); p[3] = (isc_uint8_t)(val >> 0); } isc_result_t dns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx, dns_diffop_t op, dns_difftuple_t **tp) { isc_result_t result; dns_dbnode_t *node; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; dns_name_t *zonename; zonename = dns_db_origin(db); node = NULL; result = dns_db_findnode(db, zonename, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) goto nonode; dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0, (isc_stdtime_t)0, &rdataset, NULL); if (result != ISC_R_SUCCESS) goto freenode; result = dns_rdataset_first(&rdataset); if (result != ISC_R_SUCCESS) goto freenode; dns_rdataset_current(&rdataset, &rdata); result = dns_difftuple_create(mctx, op, zonename, rdataset.ttl, &rdata, tp); dns_rdataset_disassociate(&rdataset); dns_db_detachnode(db, &node); return (result); freenode: dns_db_detachnode(db, &node); nonode: UNEXPECTED_ERROR(__FILE__, __LINE__, "missing SOA"); return (result); } /* Journaling */ /*% * On-disk representation of a "pointer" to a journal entry. * These are used in the journal header to locate the beginning * and end of the journal, and in the journal index to locate * other transactions. */ typedef struct { unsigned char serial[4]; /*%< SOA serial before update. */ /* * XXXRTH Should offset be 8 bytes? * XXXDCL ... probably, since isc_offset_t is 8 bytes on many OSs. * XXXAG ... but we will not be able to seek >2G anyway on many * platforms as long as we are using fseek() rather * than lseek(). */ unsigned char offset[4]; /*%< Offset from beginning of file. */ } journal_rawpos_t; /*% * The header is of a fixed size, with some spare room for future * extensions. */ #define JOURNAL_HEADER_SIZE 64 /* Bytes. */ /*% * The on-disk representation of the journal header. * All numbers are stored in big-endian order. */ typedef union { struct { /*% File format version ID. */ unsigned char format[16]; /*% Position of the first addressable transaction */ journal_rawpos_t begin; /*% Position of the next (yet nonexistent) transaction. */ journal_rawpos_t end; /*% Number of index entries following the header. */ unsigned char index_size[4]; /*% Source serial number. */ unsigned char sourceserial[4]; unsigned char flags; } h; /* Pad the header to a fixed size. */ unsigned char pad[JOURNAL_HEADER_SIZE]; } journal_rawheader_t; /*% * The on-disk representation of the transaction header. * There is one of these at the beginning of each transaction. */ typedef struct { unsigned char size[4]; /*%< In bytes, excluding header. */ unsigned char serial0[4]; /*%< SOA serial before update. */ unsigned char serial1[4]; /*%< SOA serial after update. */ } journal_rawxhdr_t; /*% * The on-disk representation of the RR header. * There is one of these at the beginning of each RR. */ typedef struct { unsigned char size[4]; /*%< In bytes, excluding header. */ } journal_rawrrhdr_t; /*% * The in-core representation of the journal header. */ typedef struct { isc_uint32_t serial; isc_offset_t offset; } journal_pos_t; #define POS_VALID(pos) ((pos).offset != 0) #define POS_INVALIDATE(pos) ((pos).offset = 0, (pos).serial = 0) typedef struct { unsigned char format[16]; journal_pos_t begin; journal_pos_t end; isc_uint32_t index_size; isc_uint32_t sourceserial; isc_boolean_t serialset; } journal_header_t; /*% * The in-core representation of the transaction header. */ typedef struct { isc_uint32_t size; isc_uint32_t serial0; isc_uint32_t serial1; } journal_xhdr_t; /*% * The in-core representation of the RR header. */ typedef struct { isc_uint32_t size; } journal_rrhdr_t; /*% * Initial contents to store in the header of a newly created * journal file. * * The header starts with the magic string ";BIND LOG V9\n" * to identify the file as a BIND 9 journal file. An ASCII * identification string is used rather than a binary magic * number to be consistent with BIND 8 (BIND 8 journal files * are ASCII text files). */ static journal_header_t initial_journal_header = { ";BIND LOG V9\n", { 0, 0 }, { 0, 0 }, 0, 0, 0 }; #define JOURNAL_EMPTY(h) ((h)->begin.offset == (h)->end.offset) typedef enum { JOURNAL_STATE_INVALID, JOURNAL_STATE_READ, JOURNAL_STATE_WRITE, JOURNAL_STATE_TRANSACTION, JOURNAL_STATE_INLINE } journal_state_t; struct dns_journal { unsigned int magic; /*%< JOUR */ isc_mem_t *mctx; /*%< Memory context */ journal_state_t state; char *filename; /*%< Journal file name */ FILE * fp; /*%< File handle */ isc_offset_t offset; /*%< Current file offset */ journal_header_t header; /*%< In-core journal header */ unsigned char *rawindex; /*%< In-core buffer for journal index in on-disk format */ journal_pos_t *index; /*%< In-core journal index */ /*% Current transaction state (when writing). */ struct { unsigned int n_soa; /*%< Number of SOAs seen */ journal_pos_t pos[2]; /*%< Begin/end position */ } x; /*% Iteration state (when reading). */ struct { /* These define the part of the journal we iterate over. */ journal_pos_t bpos; /*%< Position before first, */ journal_pos_t epos; /*%< and after last transaction */ /* The rest is iterator state. */ isc_uint32_t current_serial; /*%< Current SOA serial */ isc_buffer_t source; /*%< Data from disk */ isc_buffer_t target; /*%< Data from _fromwire check */ dns_decompress_t dctx; /*%< Dummy decompression ctx */ dns_name_t name; /*%< Current domain name */ dns_rdata_t rdata; /*%< Current rdata */ isc_uint32_t ttl; /*%< Current TTL */ unsigned int xsize; /*%< Size of transaction data */ unsigned int xpos; /*%< Current position in it */ isc_result_t result; /*%< Result of last call */ } it; }; #define DNS_JOURNAL_MAGIC ISC_MAGIC('J', 'O', 'U', 'R') #define DNS_JOURNAL_VALID(t) ISC_MAGIC_VALID(t, DNS_JOURNAL_MAGIC) static void journal_pos_decode(journal_rawpos_t *raw, journal_pos_t *cooked) { cooked->serial = decode_uint32(raw->serial); cooked->offset = decode_uint32(raw->offset); } static void journal_pos_encode(journal_rawpos_t *raw, journal_pos_t *cooked) { encode_uint32(cooked->serial, raw->serial); encode_uint32(cooked->offset, raw->offset); } static void journal_header_decode(journal_rawheader_t *raw, journal_header_t *cooked) { INSIST(sizeof(cooked->format) == sizeof(raw->h.format)); memmove(cooked->format, raw->h.format, sizeof(cooked->format)); journal_pos_decode(&raw->h.begin, &cooked->begin); journal_pos_decode(&raw->h.end, &cooked->end); cooked->index_size = decode_uint32(raw->h.index_size); cooked->sourceserial = decode_uint32(raw->h.sourceserial); cooked->serialset = ISC_TF(raw->h.flags & JOURNAL_SERIALSET); } static void journal_header_encode(journal_header_t *cooked, journal_rawheader_t *raw) { unsigned char flags = 0; INSIST(sizeof(cooked->format) == sizeof(raw->h.format)); memset(raw->pad, 0, sizeof(raw->pad)); memmove(raw->h.format, cooked->format, sizeof(raw->h.format)); journal_pos_encode(&raw->h.begin, &cooked->begin); journal_pos_encode(&raw->h.end, &cooked->end); encode_uint32(cooked->index_size, raw->h.index_size); encode_uint32(cooked->sourceserial, raw->h.sourceserial); if (cooked->serialset) flags |= JOURNAL_SERIALSET; raw->h.flags = flags; } /* * Journal file I/O subroutines, with error checking and reporting. */ static isc_result_t journal_seek(dns_journal_t *j, isc_uint32_t offset) { isc_result_t result; result = isc_stdio_seek(j->fp, (off_t)offset, SEEK_SET); if (result != ISC_R_SUCCESS) { isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "%s: seek: %s", j->filename, isc_result_totext(result)); return (ISC_R_UNEXPECTED); } j->offset = offset; return (ISC_R_SUCCESS); } static isc_result_t journal_read(dns_journal_t *j, void *mem, size_t nbytes) { isc_result_t result; result = isc_stdio_read(mem, 1, nbytes, j->fp, NULL); if (result != ISC_R_SUCCESS) { if (result == ISC_R_EOF) return (ISC_R_NOMORE); isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "%s: read: %s", j->filename, isc_result_totext(result)); return (ISC_R_UNEXPECTED); } j->offset += (isc_offset_t)nbytes; return (ISC_R_SUCCESS); } static isc_result_t journal_write(dns_journal_t *j, void *mem, size_t nbytes) { isc_result_t result; result = isc_stdio_write(mem, 1, nbytes, j->fp, NULL); if (result != ISC_R_SUCCESS) { isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "%s: write: %s", j->filename, isc_result_totext(result)); return (ISC_R_UNEXPECTED); } j->offset += (isc_offset_t)nbytes; return (ISC_R_SUCCESS); } static isc_result_t journal_fsync(dns_journal_t *j) { isc_result_t result; result = isc_stdio_flush(j->fp); if (result != ISC_R_SUCCESS) { isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "%s: flush: %s", j->filename, isc_result_totext(result)); return (ISC_R_UNEXPECTED); } result = isc_stdio_sync(j->fp); if (result != ISC_R_SUCCESS) { isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "%s: fsync: %s", j->filename, isc_result_totext(result)); return (ISC_R_UNEXPECTED); } return (ISC_R_SUCCESS); } /* * Read/write a transaction header at the current file position. */ static isc_result_t journal_read_xhdr(dns_journal_t *j, journal_xhdr_t *xhdr) { journal_rawxhdr_t raw; isc_result_t result; result = journal_read(j, &raw, sizeof(raw)); if (result != ISC_R_SUCCESS) return (result); xhdr->size = decode_uint32(raw.size); xhdr->serial0 = decode_uint32(raw.serial0); xhdr->serial1 = decode_uint32(raw.serial1); return (ISC_R_SUCCESS); } static isc_result_t journal_write_xhdr(dns_journal_t *j, isc_uint32_t size, isc_uint32_t serial0, isc_uint32_t serial1) { journal_rawxhdr_t raw; encode_uint32(size, raw.size); encode_uint32(serial0, raw.serial0); encode_uint32(serial1, raw.serial1); return (journal_write(j, &raw, sizeof(raw))); } /* * Read an RR header at the current file position. */ static isc_result_t journal_read_rrhdr(dns_journal_t *j, journal_rrhdr_t *rrhdr) { journal_rawrrhdr_t raw; isc_result_t result; result = journal_read(j, &raw, sizeof(raw)); if (result != ISC_R_SUCCESS) return (result); rrhdr->size = decode_uint32(raw.size); return (ISC_R_SUCCESS); } static isc_result_t journal_file_create(isc_mem_t *mctx, const char *filename) { FILE *fp = NULL; isc_result_t result; journal_header_t header; journal_rawheader_t rawheader; int index_size = 56; /* XXX configurable */ int size; void *mem; /* Memory for temporary index image. */ INSIST(sizeof(journal_rawheader_t) == JOURNAL_HEADER_SIZE); result = isc_stdio_open(filename, "wb", &fp); if (result != ISC_R_SUCCESS) { isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "%s: create: %s", filename, isc_result_totext(result)); return (ISC_R_UNEXPECTED); } header = initial_journal_header; header.index_size = index_size; journal_header_encode(&header, &rawheader); size = sizeof(journal_rawheader_t) + index_size * sizeof(journal_rawpos_t); mem = isc_mem_get(mctx, size); if (mem == NULL) { (void)isc_stdio_close(fp); (void)isc_file_remove(filename); return (ISC_R_NOMEMORY); } memset(mem, 0, size); memmove(mem, &rawheader, sizeof(rawheader)); result = isc_stdio_write(mem, 1, (size_t) size, fp, NULL); if (result != ISC_R_SUCCESS) { isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "%s: write: %s", filename, isc_result_totext(result)); (void)isc_stdio_close(fp); (void)isc_file_remove(filename); isc_mem_put(mctx, mem, size); return (ISC_R_UNEXPECTED); } isc_mem_put(mctx, mem, size); result = isc_stdio_close(fp); if (result != ISC_R_SUCCESS) { isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "%s: close: %s", filename, isc_result_totext(result)); (void)isc_file_remove(filename); return (ISC_R_UNEXPECTED); } return (ISC_R_SUCCESS); } static isc_result_t journal_open(isc_mem_t *mctx, const char *filename, isc_boolean_t writable, isc_boolean_t create, dns_journal_t **journalp) { FILE *fp = NULL; isc_result_t result; journal_rawheader_t rawheader; dns_journal_t *j; INSIST(journalp != NULL && *journalp == NULL); j = isc_mem_get(mctx, sizeof(*j)); if (j == NULL) return (ISC_R_NOMEMORY); j->mctx = NULL; isc_mem_attach(mctx, &j->mctx); j->state = JOURNAL_STATE_INVALID; j->fp = NULL; j->filename = isc_mem_strdup(mctx, filename); j->index = NULL; j->rawindex = NULL; if (j->filename == NULL) FAIL(ISC_R_NOMEMORY); result = isc_stdio_open(j->filename, writable ? "rb+" : "rb", &fp); if (result == ISC_R_FILENOTFOUND) { if (create) { isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_DEBUG(1), "journal file %s does not exist, " "creating it", j->filename); CHECK(journal_file_create(mctx, filename)); /* * Retry. */ result = isc_stdio_open(j->filename, "rb+", &fp); } else { FAIL(ISC_R_NOTFOUND); } } if (result != ISC_R_SUCCESS) { isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "%s: open: %s", j->filename, isc_result_totext(result)); FAIL(ISC_R_UNEXPECTED); } j->fp = fp; /* * Set magic early so that seek/read can succeed. */ j->magic = DNS_JOURNAL_MAGIC; CHECK(journal_seek(j, 0)); CHECK(journal_read(j, &rawheader, sizeof(rawheader))); if (memcmp(rawheader.h.format, initial_journal_header.format, sizeof(initial_journal_header.format)) != 0) { isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "%s: journal format not recognized", j->filename); FAIL(ISC_R_UNEXPECTED); } journal_header_decode(&rawheader, &j->header); /* * If there is an index, read the raw index into a dynamically * allocated buffer and then convert it into a cooked index. */ if (j->header.index_size != 0) { unsigned int i; unsigned int rawbytes; unsigned char *p; rawbytes = j->header.index_size * sizeof(journal_rawpos_t); j->rawindex = isc_mem_get(mctx, rawbytes); if (j->rawindex == NULL) FAIL(ISC_R_NOMEMORY); CHECK(journal_read(j, j->rawindex, rawbytes)); j->index = isc_mem_get(mctx, j->header.index_size * sizeof(journal_pos_t)); if (j->index == NULL) FAIL(ISC_R_NOMEMORY); p = j->rawindex; for (i = 0; i < j->header.index_size; i++) { j->index[i].serial = decode_uint32(p); p += 4; j->index[i].offset = decode_uint32(p); p += 4; } INSIST(p == j->rawindex + rawbytes); } j->offset = -1; /* Invalid, must seek explicitly. */ /* * Initialize the iterator. */ dns_name_init(&j->it.name, NULL); dns_rdata_init(&j->it.rdata); /* * Set up empty initial buffers for unchecked and checked * wire format RR data. They will be reallocated * later. */ isc_buffer_init(&j->it.source, NULL, 0); isc_buffer_init(&j->it.target, NULL, 0); dns_decompress_init(&j->it.dctx, -1, DNS_DECOMPRESS_NONE); j->state = writable ? JOURNAL_STATE_WRITE : JOURNAL_STATE_READ; *journalp = j; return (ISC_R_SUCCESS); failure: j->magic = 0; if (j->index != NULL) { isc_mem_put(j->mctx, j->index, j->header.index_size * sizeof(journal_rawpos_t)); j->index = NULL; } if (j->filename != NULL) isc_mem_free(j->mctx, j->filename); if (j->fp != NULL) (void)isc_stdio_close(j->fp); isc_mem_putanddetach(&j->mctx, j, sizeof(*j)); return (result); } isc_result_t dns_journal_open(isc_mem_t *mctx, const char *filename, unsigned int mode, dns_journal_t **journalp) { isc_result_t result; size_t namelen; char backup[1024]; isc_boolean_t writable, create; create = ISC_TF(mode & DNS_JOURNAL_CREATE); writable = ISC_TF(mode & (DNS_JOURNAL_WRITE|DNS_JOURNAL_CREATE)); result = journal_open(mctx, filename, writable, create, journalp); if (result == ISC_R_NOTFOUND) { namelen = strlen(filename); if (namelen > 4U && strcmp(filename + namelen - 4, ".jnl") == 0) namelen -= 4; result = isc_string_printf(backup, sizeof(backup), "%.*s.jbk", (int)namelen, filename); if (result != ISC_R_SUCCESS) return (result); result = journal_open(mctx, backup, writable, writable, journalp); } return (result); } /* * A comparison function defining the sorting order for * entries in the IXFR-style journal file. * * The IXFR format requires that deletions are sorted before * additions, and within either one, SOA records are sorted * before others. * * Also sort the non-SOA records by type as a courtesy to the * server receiving the IXFR - it may help reduce the amount of * rdataset merging it has to do. */ static int ixfr_order(const void *av, const void *bv) { dns_difftuple_t const * const *ap = av; dns_difftuple_t const * const *bp = bv; dns_difftuple_t const *a = *ap; dns_difftuple_t const *b = *bp; int r; int bop = 0, aop = 0; switch (a->op) { case DNS_DIFFOP_DEL: case DNS_DIFFOP_DELRESIGN: aop = 1; break; case DNS_DIFFOP_ADD: case DNS_DIFFOP_ADDRESIGN: aop = 0; break; default: INSIST(0); } switch (b->op) { case DNS_DIFFOP_DEL: case DNS_DIFFOP_DELRESIGN: bop = 1; break; case DNS_DIFFOP_ADD: case DNS_DIFFOP_ADDRESIGN: bop = 0; break; default: INSIST(0); } r = bop - aop; if (r != 0) return (r); r = (b->rdata.type == dns_rdatatype_soa) - (a->rdata.type == dns_rdatatype_soa); if (r != 0) return (r); r = (a->rdata.type - b->rdata.type); return (r); } /* * Advance '*pos' to the next journal transaction. * * Requires: * *pos refers to a valid journal transaction. * * Ensures: * When ISC_R_SUCCESS is returned, * *pos refers to the next journal transaction. * * Returns one of: * * ISC_R_SUCCESS * ISC_R_NOMORE *pos pointed at the last transaction * Other results due to file errors are possible. */ static isc_result_t journal_next(dns_journal_t *j, journal_pos_t *pos) { isc_result_t result; journal_xhdr_t xhdr; REQUIRE(DNS_JOURNAL_VALID(j)); result = journal_seek(j, pos->offset); if (result != ISC_R_SUCCESS) return (result); if (pos->serial == j->header.end.serial) return (ISC_R_NOMORE); /* * Read the header of the current transaction. * This will return ISC_R_NOMORE if we are at EOF. */ result = journal_read_xhdr(j, &xhdr); if (result != ISC_R_SUCCESS) return (result); /* * Check serial number consistency. */ if (xhdr.serial0 != pos->serial) { isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "%s: journal file corrupt: " "expected serial %u, got %u", j->filename, pos->serial, xhdr.serial0); return (ISC_R_UNEXPECTED); } /* * Check for offset wraparound. */ if ((isc_offset_t)(pos->offset + sizeof(journal_rawxhdr_t) + xhdr.size) < pos->offset) { isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "%s: offset too large", j->filename); return (ISC_R_UNEXPECTED); } pos->offset += sizeof(journal_rawxhdr_t) + xhdr.size; pos->serial = xhdr.serial1; return (ISC_R_SUCCESS); } /* * If the index of the journal 'j' contains an entry "better" * than '*best_guess', replace '*best_guess' with it. * * "Better" means having a serial number closer to 'serial' * but not greater than 'serial'. */ static void index_find(dns_journal_t *j, isc_uint32_t serial, journal_pos_t *best_guess) { unsigned int i; if (j->index == NULL) return; for (i = 0; i < j->header.index_size; i++) { if (POS_VALID(j->index[i]) && DNS_SERIAL_GE(serial, j->index[i].serial) && DNS_SERIAL_GT(j->index[i].serial, best_guess->serial)) *best_guess = j->index[i]; } } /* * Add a new index entry. If there is no room, make room by removing * the odd-numbered entries and compacting the others into the first * half of the index. This decimates old index entries exponentially * over time, so that the index always contains a much larger fraction * of recent serial numbers than of old ones. This is deliberate - * most index searches are for outgoing IXFR, and IXFR tends to request * recent versions more often than old ones. */ static void index_add(dns_journal_t *j, journal_pos_t *pos) { unsigned int i; if (j->index == NULL) return; /* * Search for a vacant position. */ for (i = 0; i < j->header.index_size; i++) { if (! POS_VALID(j->index[i])) break; } if (i == j->header.index_size) { unsigned int k = 0; /* * Found no vacant position. Make some room. */ for (i = 0; i < j->header.index_size; i += 2) { j->index[k++] = j->index[i]; } i = k; /* 'i' identifies the first vacant position. */ while (k < j->header.index_size) { POS_INVALIDATE(j->index[k]); k++; } } INSIST(i < j->header.index_size); INSIST(! POS_VALID(j->index[i])); /* * Store the new index entry. */ j->index[i] = *pos; } /* * Invalidate any existing index entries that could become * ambiguous when a new transaction with number 'serial' is added. */ static void index_invalidate(dns_journal_t *j, isc_uint32_t serial) { unsigned int i; if (j->index == NULL) return; for (i = 0; i < j->header.index_size; i++) { if (! DNS_SERIAL_GT(serial, j->index[i].serial)) POS_INVALIDATE(j->index[i]); } } /* * Try to find a transaction with initial serial number 'serial' * in the journal 'j'. * * If found, store its position at '*pos' and return ISC_R_SUCCESS. * * If 'serial' is current (= the ending serial number of the * last transaction in the journal), set '*pos' to * the position immediately following the last transaction and * return ISC_R_SUCCESS. * * If 'serial' is within the range of addressable serial numbers * covered by the journal but that particular serial number is missing * (from the journal, not just from the index), return ISC_R_NOTFOUND. * * If 'serial' is outside the range of addressable serial numbers * covered by the journal, return ISC_R_RANGE. * */ static isc_result_t journal_find(dns_journal_t *j, isc_uint32_t serial, journal_pos_t *pos) { isc_result_t result; journal_pos_t current_pos; REQUIRE(DNS_JOURNAL_VALID(j)); if (DNS_SERIAL_GT(j->header.begin.serial, serial)) return (ISC_R_RANGE); if (DNS_SERIAL_GT(serial, j->header.end.serial)) return (ISC_R_RANGE); if (serial == j->header.end.serial) { *pos = j->header.end; return (ISC_R_SUCCESS); } current_pos = j->header.begin; index_find(j, serial, ¤t_pos); while (current_pos.serial != serial) { if (DNS_SERIAL_GT(current_pos.serial, serial)) return (ISC_R_NOTFOUND); result = journal_next(j, ¤t_pos); if (result != ISC_R_SUCCESS) return (result); } *pos = current_pos; return (ISC_R_SUCCESS); } isc_result_t dns_journal_begin_transaction(dns_journal_t *j) { isc_uint32_t offset; isc_result_t result; journal_rawxhdr_t hdr; REQUIRE(DNS_JOURNAL_VALID(j)); REQUIRE(j->state == JOURNAL_STATE_WRITE || j->state == JOURNAL_STATE_INLINE); /* * Find the file offset where the new transaction should * be written, and seek there. */ if (JOURNAL_EMPTY(&j->header)) { offset = sizeof(journal_rawheader_t) + j->header.index_size * sizeof(journal_rawpos_t); } else { offset = j->header.end.offset; } j->x.pos[0].offset = offset; j->x.pos[1].offset = offset; /* Initial value, will be incremented. */ j->x.n_soa = 0; CHECK(journal_seek(j, offset)); /* * Write a dummy transaction header of all zeroes to reserve * space. It will be filled in when the transaction is * finished. */ memset(&hdr, 0, sizeof(hdr)); CHECK(journal_write(j, &hdr, sizeof(hdr))); j->x.pos[1].offset = j->offset; j->state = JOURNAL_STATE_TRANSACTION; result = ISC_R_SUCCESS; failure: return (result); } isc_result_t dns_journal_writediff(dns_journal_t *j, dns_diff_t *diff) { dns_difftuple_t *t; isc_buffer_t buffer; void *mem = NULL; unsigned int size; isc_result_t result; isc_region_t used; REQUIRE(DNS_DIFF_VALID(diff)); REQUIRE(j->state == JOURNAL_STATE_TRANSACTION); isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "writing to journal"); (void)dns_diff_print(diff, NULL); /* * Pass 1: determine the buffer size needed, and * keep track of SOA serial numbers. */ size = 0; for (t = ISC_LIST_HEAD(diff->tuples); t != NULL; t = ISC_LIST_NEXT(t, link)) { if (t->rdata.type == dns_rdatatype_soa) { if (j->x.n_soa < 2) j->x.pos[j->x.n_soa].serial = dns_soa_getserial(&t->rdata); j->x.n_soa++; } size += sizeof(journal_rawrrhdr_t); size += t->name.length; /* XXX should have access macro? */ size += 10; size += t->rdata.length; } mem = isc_mem_get(j->mctx, size); if (mem == NULL) return (ISC_R_NOMEMORY); isc_buffer_init(&buffer, mem, size); /* * Pass 2. Write RRs to buffer. */ for (t = ISC_LIST_HEAD(diff->tuples); t != NULL; t = ISC_LIST_NEXT(t, link)) { /* * Write the RR header. */ isc_buffer_putuint32(&buffer, t->name.length + 10 + t->rdata.length); /* * Write the owner name, RR header, and RR data. */ isc_buffer_putmem(&buffer, t->name.ndata, t->name.length); isc_buffer_putuint16(&buffer, t->rdata.type); isc_buffer_putuint16(&buffer, t->rdata.rdclass); isc_buffer_putuint32(&buffer, t->ttl); INSIST(t->rdata.length < 65536); isc_buffer_putuint16(&buffer, (isc_uint16_t)t->rdata.length); INSIST(isc_buffer_availablelength(&buffer) >= t->rdata.length); isc_buffer_putmem(&buffer, t->rdata.data, t->rdata.length); } isc_buffer_usedregion(&buffer, &used); INSIST(used.length == size); j->x.pos[1].offset += used.length; /* * Write the buffer contents to the journal file. */ CHECK(journal_write(j, used.base, used.length)); result = ISC_R_SUCCESS; failure: if (mem != NULL) isc_mem_put(j->mctx, mem, size); return (result); } isc_result_t dns_journal_commit(dns_journal_t *j) { isc_result_t result; journal_rawheader_t rawheader; REQUIRE(DNS_JOURNAL_VALID(j)); REQUIRE(j->state == JOURNAL_STATE_TRANSACTION || j->state == JOURNAL_STATE_INLINE); /* * Just write out a updated header. */ if (j->state == JOURNAL_STATE_INLINE) { CHECK(journal_fsync(j)); journal_header_encode(&j->header, &rawheader); CHECK(journal_seek(j, 0)); CHECK(journal_write(j, &rawheader, sizeof(rawheader))); CHECK(journal_fsync(j)); j->state = JOURNAL_STATE_WRITE; return (ISC_R_SUCCESS); } /* * Perform some basic consistency checks. */ if (j->x.n_soa != 2) { isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "%s: malformed transaction: %d SOAs", j->filename, j->x.n_soa); return (ISC_R_UNEXPECTED); } if (! (DNS_SERIAL_GT(j->x.pos[1].serial, j->x.pos[0].serial) || (bind8_compat && j->x.pos[1].serial == j->x.pos[0].serial))) { isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "%s: malformed transaction: serial number " "would decrease", j->filename); return (ISC_R_UNEXPECTED); } if (! JOURNAL_EMPTY(&j->header)) { if (j->x.pos[0].serial != j->header.end.serial) { isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "malformed transaction: " "%s last serial %u != " "transaction first serial %u", j->filename, j->header.end.serial, j->x.pos[0].serial); return (ISC_R_UNEXPECTED); } } /* * Some old journal entries may become non-addressable * when we increment the current serial number. Purge them * by stepping header.begin forward to the first addressable * transaction. Also purge them from the index. */ if (! JOURNAL_EMPTY(&j->header)) { while (! DNS_SERIAL_GT(j->x.pos[1].serial, j->header.begin.serial)) { CHECK(journal_next(j, &j->header.begin)); } index_invalidate(j, j->x.pos[1].serial); } #ifdef notyet if (DNS_SERIAL_GT(last_dumped_serial, j->x.pos[1].serial)) { force_dump(...); } #endif /* * Commit the transaction data to stable storage. */ CHECK(journal_fsync(j)); if (j->state == JOURNAL_STATE_TRANSACTION) { isc_offset_t offset; offset = (j->x.pos[1].offset - j->x.pos[0].offset) - sizeof(journal_rawxhdr_t); /* * Update the transaction header. */ CHECK(journal_seek(j, j->x.pos[0].offset)); CHECK(journal_write_xhdr(j, offset, j->x.pos[0].serial, j->x.pos[1].serial)); } /* * Update the journal header. */ if (JOURNAL_EMPTY(&j->header)) j->header.begin = j->x.pos[0]; j->header.end = j->x.pos[1]; journal_header_encode(&j->header, &rawheader); CHECK(journal_seek(j, 0)); CHECK(journal_write(j, &rawheader, sizeof(rawheader))); /* * Update the index. */ index_add(j, &j->x.pos[0]); /* * Convert the index into on-disk format and write * it to disk. */ CHECK(index_to_disk(j)); /* * Commit the header to stable storage. */ CHECK(journal_fsync(j)); /* * We no longer have a transaction open. */ j->state = JOURNAL_STATE_WRITE; result = ISC_R_SUCCESS; failure: return (result); } isc_result_t dns_journal_write_transaction(dns_journal_t *j, dns_diff_t *diff) { isc_result_t result; CHECK(dns_diff_sort(diff, ixfr_order)); CHECK(dns_journal_begin_transaction(j)); CHECK(dns_journal_writediff(j, diff)); CHECK(dns_journal_commit(j)); result = ISC_R_SUCCESS; failure: return (result); } void dns_journal_destroy(dns_journal_t **journalp) { dns_journal_t *j = *journalp; REQUIRE(DNS_JOURNAL_VALID(j)); j->it.result = ISC_R_FAILURE; dns_name_invalidate(&j->it.name); dns_decompress_invalidate(&j->it.dctx); if (j->rawindex != NULL) isc_mem_put(j->mctx, j->rawindex, j->header.index_size * sizeof(journal_rawpos_t)); if (j->index != NULL) isc_mem_put(j->mctx, j->index, j->header.index_size * sizeof(journal_pos_t)); if (j->it.target.base != NULL) isc_mem_put(j->mctx, j->it.target.base, j->it.target.length); if (j->it.source.base != NULL) isc_mem_put(j->mctx, j->it.source.base, j->it.source.length); if (j->filename != NULL) isc_mem_free(j->mctx, j->filename); if (j->fp != NULL) (void)isc_stdio_close(j->fp); j->magic = 0; isc_mem_putanddetach(&j->mctx, j, sizeof(*j)); *journalp = NULL; } /* * Roll the open journal 'j' into the database 'db'. * A new database version will be created. */ /* XXX Share code with incoming IXFR? */ static isc_result_t roll_forward(dns_journal_t *j, dns_db_t *db, unsigned int options) { isc_buffer_t source; /* Transaction data from disk */ isc_buffer_t target; /* Ditto after _fromwire check */ isc_uint32_t db_serial; /* Database SOA serial */ isc_uint32_t end_serial; /* Last journal SOA serial */ isc_result_t result; dns_dbversion_t *ver = NULL; journal_pos_t pos; dns_diff_t diff; unsigned int n_soa = 0; unsigned int n_put = 0; dns_diffop_t op; REQUIRE(DNS_JOURNAL_VALID(j)); REQUIRE(DNS_DB_VALID(db)); dns_diff_init(j->mctx, &diff); /* * Set up empty initial buffers for unchecked and checked * wire format transaction data. They will be reallocated * later. */ isc_buffer_init(&source, NULL, 0); isc_buffer_init(&target, NULL, 0); /* * Create the new database version. */ CHECK(dns_db_newversion(db, &ver)); /* * Get the current database SOA serial number. */ CHECK(dns_db_getsoaserial(db, ver, &db_serial)); /* * Locate a journal entry for the current database serial. */ CHECK(journal_find(j, db_serial, &pos)); /* * XXX do more drastic things, like marking zone stale, * if this fails? */ /* * XXXRTH The zone code should probably mark the zone as bad and * scream loudly into the log if this is a dynamic update * log reply that failed. */ end_serial = dns_journal_last_serial(j); if (db_serial == end_serial) CHECK(DNS_R_UPTODATE); CHECK(dns_journal_iter_init(j, db_serial, end_serial)); for (result = dns_journal_first_rr(j); result == ISC_R_SUCCESS; result = dns_journal_next_rr(j)) { dns_name_t *name; isc_uint32_t ttl; dns_rdata_t *rdata; dns_difftuple_t *tuple = NULL; name = NULL; rdata = NULL; dns_journal_current_rr(j, &name, &ttl, &rdata); if (rdata->type == dns_rdatatype_soa) { n_soa++; if (n_soa == 2) db_serial = j->it.current_serial; } if (n_soa == 3) n_soa = 1; if (n_soa == 0) { isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "%s: journal file corrupt: missing " "initial SOA", j->filename); FAIL(ISC_R_UNEXPECTED); } if ((options & DNS_JOURNALOPT_RESIGN) != 0) op = (n_soa == 1) ? DNS_DIFFOP_DELRESIGN : DNS_DIFFOP_ADDRESIGN; else op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD; CHECK(dns_difftuple_create(diff.mctx, op, name, ttl, rdata, &tuple)); dns_diff_append(&diff, &tuple); if (++n_put > 100) { isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "%s: applying diff to database (%u)", j->filename, db_serial); (void)dns_diff_print(&diff, NULL); CHECK(dns_diff_apply(&diff, db, ver)); dns_diff_clear(&diff); n_put = 0; } } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; CHECK(result); if (n_put != 0) { isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "%s: applying final diff to database (%u)", j->filename, db_serial); (void)dns_diff_print(&diff, NULL); CHECK(dns_diff_apply(&diff, db, ver)); dns_diff_clear(&diff); } failure: if (ver != NULL) dns_db_closeversion(db, &ver, result == ISC_R_SUCCESS ? ISC_TRUE : ISC_FALSE); if (source.base != NULL) isc_mem_put(j->mctx, source.base, source.length); if (target.base != NULL) isc_mem_put(j->mctx, target.base, target.length); dns_diff_clear(&diff); INSIST(ver == NULL); return (result); } isc_result_t dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db, unsigned int options, const char *filename) { dns_journal_t *j; isc_result_t result; REQUIRE(DNS_DB_VALID(db)); REQUIRE(filename != NULL); j = NULL; result = dns_journal_open(mctx, filename, DNS_JOURNAL_READ, &j); if (result == ISC_R_NOTFOUND) { isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "no journal file, but that's OK"); return (DNS_R_NOJOURNAL); } if (result != ISC_R_SUCCESS) return (result); if (JOURNAL_EMPTY(&j->header)) result = DNS_R_UPTODATE; else result = roll_forward(j, db, options); dns_journal_destroy(&j); return (result); } isc_result_t dns_journal_print(isc_mem_t *mctx, const char *filename, FILE *file) { dns_journal_t *j; isc_buffer_t source; /* Transaction data from disk */ isc_buffer_t target; /* Ditto after _fromwire check */ isc_uint32_t start_serial; /* Database SOA serial */ isc_uint32_t end_serial; /* Last journal SOA serial */ isc_result_t result; dns_diff_t diff; unsigned int n_soa = 0; unsigned int n_put = 0; REQUIRE(filename != NULL); j = NULL; result = dns_journal_open(mctx, filename, DNS_JOURNAL_READ, &j); if (result == ISC_R_NOTFOUND) { isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "no journal file"); return (DNS_R_NOJOURNAL); } if (result != ISC_R_SUCCESS) { isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "journal open failure: %s: %s", isc_result_totext(result), filename); return (result); } if (j->header.serialset) fprintf(file, "Source serial = %u\n", j->header.sourceserial); dns_diff_init(j->mctx, &diff); /* * Set up empty initial buffers for unchecked and checked * wire format transaction data. They will be reallocated * later. */ isc_buffer_init(&source, NULL, 0); isc_buffer_init(&target, NULL, 0); start_serial = dns_journal_first_serial(j); end_serial = dns_journal_last_serial(j); CHECK(dns_journal_iter_init(j, start_serial, end_serial)); for (result = dns_journal_first_rr(j); result == ISC_R_SUCCESS; result = dns_journal_next_rr(j)) { dns_name_t *name; isc_uint32_t ttl; dns_rdata_t *rdata; dns_difftuple_t *tuple = NULL; name = NULL; rdata = NULL; dns_journal_current_rr(j, &name, &ttl, &rdata); if (rdata->type == dns_rdatatype_soa) n_soa++; if (n_soa == 3) n_soa = 1; if (n_soa == 0) { isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "%s: journal file corrupt: missing " "initial SOA", j->filename); FAIL(ISC_R_UNEXPECTED); } CHECK(dns_difftuple_create(diff.mctx, n_soa == 1 ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD, name, ttl, rdata, &tuple)); dns_diff_append(&diff, &tuple); if (++n_put > 100) { result = dns_diff_print(&diff, file); dns_diff_clear(&diff); n_put = 0; if (result != ISC_R_SUCCESS) break; } } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; CHECK(result); if (n_put != 0) { result = dns_diff_print(&diff, file); dns_diff_clear(&diff); } goto cleanup; failure: isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "%s: cannot print: journal file corrupt", j->filename); cleanup: if (source.base != NULL) isc_mem_put(j->mctx, source.base, source.length); if (target.base != NULL) isc_mem_put(j->mctx, target.base, target.length); dns_diff_clear(&diff); dns_journal_destroy(&j); return (result); } /**************************************************************************/ /* * Miscellaneous accessors. */ isc_uint32_t dns_journal_first_serial(dns_journal_t *j) { return (j->header.begin.serial); } isc_uint32_t dns_journal_last_serial(dns_journal_t *j) { return (j->header.end.serial); } void dns_journal_set_sourceserial(dns_journal_t *j, isc_uint32_t sourceserial) { REQUIRE(j->state == JOURNAL_STATE_WRITE || j->state == JOURNAL_STATE_INLINE || j->state == JOURNAL_STATE_TRANSACTION); j->header.sourceserial = sourceserial; j->header.serialset = ISC_TRUE; if (j->state == JOURNAL_STATE_WRITE) j->state = JOURNAL_STATE_INLINE; } isc_boolean_t dns_journal_get_sourceserial(dns_journal_t *j, isc_uint32_t *sourceserial) { REQUIRE(sourceserial != NULL); if (!j->header.serialset) return (ISC_FALSE); *sourceserial = j->header.sourceserial; return (ISC_TRUE); } /**************************************************************************/ /* * Iteration support. * * When serving an outgoing IXFR, we transmit a part the journal starting * at the serial number in the IXFR request and ending at the serial * number that is current when the IXFR request arrives. The ending * serial number is not necessarily at the end of the journal: * the journal may grow while the IXFR is in progress, but we stop * when we reach the serial number that was current when the IXFR started. */ static isc_result_t read_one_rr(dns_journal_t *j); /* * Make sure the buffer 'b' is has at least 'size' bytes * allocated, and clear it. * * Requires: * Either b->base is NULL, or it points to b->length bytes of memory * previously allocated by isc_mem_get(). */ static isc_result_t size_buffer(isc_mem_t *mctx, isc_buffer_t *b, unsigned size) { if (b->length < size) { void *mem = isc_mem_get(mctx, size); if (mem == NULL) return (ISC_R_NOMEMORY); if (b->base != NULL) isc_mem_put(mctx, b->base, b->length); b->base = mem; b->length = size; } isc_buffer_clear(b); return (ISC_R_SUCCESS); } isc_result_t dns_journal_iter_init(dns_journal_t *j, isc_uint32_t begin_serial, isc_uint32_t end_serial) { isc_result_t result; CHECK(journal_find(j, begin_serial, &j->it.bpos)); INSIST(j->it.bpos.serial == begin_serial); CHECK(journal_find(j, end_serial, &j->it.epos)); INSIST(j->it.epos.serial == end_serial); result = ISC_R_SUCCESS; failure: j->it.result = result; return (j->it.result); } isc_result_t dns_journal_first_rr(dns_journal_t *j) { isc_result_t result; /* * Seek to the beginning of the first transaction we are * interested in. */ CHECK(journal_seek(j, j->it.bpos.offset)); j->it.current_serial = j->it.bpos.serial; j->it.xsize = 0; /* We have no transaction data yet... */ j->it.xpos = 0; /* ...and haven't used any of it. */ return (read_one_rr(j)); failure: return (result); } static isc_result_t read_one_rr(dns_journal_t *j) { isc_result_t result; dns_rdatatype_t rdtype; dns_rdataclass_t rdclass; unsigned int rdlen; isc_uint32_t ttl; journal_xhdr_t xhdr; journal_rrhdr_t rrhdr; INSIST(j->offset <= j->it.epos.offset); if (j->offset == j->it.epos.offset) return (ISC_R_NOMORE); if (j->it.xpos == j->it.xsize) { /* * We are at a transaction boundary. * Read another transaction header. */ CHECK(journal_read_xhdr(j, &xhdr)); if (xhdr.size == 0) { isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "%s: journal corrupt: empty transaction", j->filename); FAIL(ISC_R_UNEXPECTED); } if (xhdr.serial0 != j->it.current_serial) { isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "%s: journal file corrupt: " "expected serial %u, got %u", j->filename, j->it.current_serial, xhdr.serial0); FAIL(ISC_R_UNEXPECTED); } j->it.xsize = xhdr.size; j->it.xpos = 0; } /* * Read an RR. */ CHECK(journal_read_rrhdr(j, &rrhdr)); /* * Perform a sanity check on the journal RR size. * The smallest possible RR has a 1-byte owner name * and a 10-byte header. The largest possible * RR has 65535 bytes of data, a header, and a maximum- * size owner name, well below 70 k total. */ if (rrhdr.size < 1+10 || rrhdr.size > 70000) { isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, "%s: journal corrupt: impossible RR size " "(%d bytes)", j->filename, rrhdr.size); FAIL(ISC_R_UNEXPECTED); } CHECK(size_buffer(j->mctx, &j->it.source, rrhdr.size)); CHECK(journal_read(j, j->it.source.base, rrhdr.size)); isc_buffer_add(&j->it.source, rrhdr.size); /* * The target buffer is made the same size * as the source buffer, with the assumption that when * no compression in present, the output of dns_*_fromwire() * is no larger than the input. */ CHECK(size_buffer(j->mctx, &j->it.target, rrhdr.size)); /* * Parse the owner name. We don't know where it * ends yet, so we make the entire "remaining" * part of the buffer "active". */ isc_buffer_setactive(&j->it.source, j->it.source.used - j->it.source.current); CHECK(dns_name_fromwire(&j->it.name, &j->it.source, &j->it.dctx, 0, &j->it.target)); /* * Check that the RR header is there, and parse it. */ if (isc_buffer_remaininglength(&j->it.source) < 10) FAIL(DNS_R_FORMERR); rdtype = isc_buffer_getuint16(&j->it.source); rdclass = isc_buffer_getuint16(&j->it.source); ttl = isc_buffer_getuint32(&j->it.source); rdlen = isc_buffer_getuint16(&j->it.source); /* * Parse the rdata. */ if (isc_buffer_remaininglength(&j->it.source) != rdlen) FAIL(DNS_R_FORMERR); isc_buffer_setactive(&j->it.source, rdlen); dns_rdata_reset(&j->it.rdata); CHECK(dns_rdata_fromwire(&j->it.rdata, rdclass, rdtype, &j->it.source, &j->it.dctx, 0, &j->it.target)); j->it.ttl = ttl; j->it.xpos += sizeof(journal_rawrrhdr_t) + rrhdr.size; if (rdtype == dns_rdatatype_soa) { /* XXX could do additional consistency checks here */ j->it.current_serial = dns_soa_getserial(&j->it.rdata); } result = ISC_R_SUCCESS; failure: j->it.result = result; return (result); } isc_result_t dns_journal_next_rr(dns_journal_t *j) { j->it.result = read_one_rr(j); return (j->it.result); } void dns_journal_current_rr(dns_journal_t *j, dns_name_t **name, isc_uint32_t *ttl, dns_rdata_t **rdata) { REQUIRE(j->it.result == ISC_R_SUCCESS); *name = &j->it.name; *ttl = j->it.ttl; *rdata = &j->it.rdata; } /**************************************************************************/ /* * Generating diffs from databases */ /* * Construct a diff containing all the RRs at the current name of the * database iterator 'dbit' in database 'db', version 'ver'. * Set '*name' to the current name, and append the diff to 'diff'. * All new tuples will have the operation 'op'. * * Requires: 'name' must have buffer large enough to hold the name. * Typically, a dns_fixedname_t would be used. */ static isc_result_t get_name_diff(dns_db_t *db, dns_dbversion_t *ver, isc_stdtime_t now, dns_dbiterator_t *dbit, dns_name_t *name, dns_diffop_t op, dns_diff_t *diff) { isc_result_t result; dns_dbnode_t *node = NULL; dns_rdatasetiter_t *rdsiter = NULL; dns_difftuple_t *tuple = NULL; result = dns_dbiterator_current(dbit, &node, name); if (result != ISC_R_SUCCESS) return (result); result = dns_db_allrdatasets(db, node, ver, now, &rdsiter); if (result != ISC_R_SUCCESS) goto cleanup_node; for (result = dns_rdatasetiter_first(rdsiter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsiter)) { dns_rdataset_t rdataset; dns_rdataset_init(&rdataset); dns_rdatasetiter_current(rdsiter, &rdataset); for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); result = dns_difftuple_create(diff->mctx, op, name, rdataset.ttl, &rdata, &tuple); if (result != ISC_R_SUCCESS) { dns_rdataset_disassociate(&rdataset); goto cleanup_iterator; } dns_diff_append(diff, &tuple); } dns_rdataset_disassociate(&rdataset); if (result != ISC_R_NOMORE) goto cleanup_iterator; } if (result != ISC_R_NOMORE) goto cleanup_iterator; result = ISC_R_SUCCESS; cleanup_iterator: dns_rdatasetiter_destroy(&rdsiter); cleanup_node: dns_db_detachnode(db, &node); return (result); } /* * Comparison function for use by dns_diff_subtract when sorting * the diffs to be subtracted. The sort keys are the rdata type * and the rdata itself. The owner name is ignored, because * it is known to be the same for all tuples. */ static int rdata_order(const void *av, const void *bv) { dns_difftuple_t const * const *ap = av; dns_difftuple_t const * const *bp = bv; dns_difftuple_t const *a = *ap; dns_difftuple_t const *b = *bp; int r; r = (b->rdata.type - a->rdata.type); if (r != 0) return (r); r = dns_rdata_compare(&a->rdata, &b->rdata); return (r); } static isc_result_t dns_diff_subtract(dns_diff_t diff[2], dns_diff_t *r) { isc_result_t result; dns_difftuple_t *p[2]; int i, t; isc_boolean_t append; CHECK(dns_diff_sort(&diff[0], rdata_order)); CHECK(dns_diff_sort(&diff[1], rdata_order)); for (;;) { p[0] = ISC_LIST_HEAD(diff[0].tuples); p[1] = ISC_LIST_HEAD(diff[1].tuples); if (p[0] == NULL && p[1] == NULL) break; for (i = 0; i < 2; i++) if (p[!i] == NULL) { ISC_LIST_UNLINK(diff[i].tuples, p[i], link); ISC_LIST_APPEND(r->tuples, p[i], link); goto next; } t = rdata_order(&p[0], &p[1]); if (t < 0) { ISC_LIST_UNLINK(diff[0].tuples, p[0], link); ISC_LIST_APPEND(r->tuples, p[0], link); goto next; } if (t > 0) { ISC_LIST_UNLINK(diff[1].tuples, p[1], link); ISC_LIST_APPEND(r->tuples, p[1], link); goto next; } INSIST(t == 0); /* * Identical RRs in both databases; skip them both * if the ttl differs. */ append = ISC_TF(p[0]->ttl != p[1]->ttl); for (i = 0; i < 2; i++) { ISC_LIST_UNLINK(diff[i].tuples, p[i], link); if (append) { ISC_LIST_APPEND(r->tuples, p[i], link); } else { dns_difftuple_free(&p[i]); } } next: ; } result = ISC_R_SUCCESS; failure: return (result); } static isc_result_t diff_namespace(dns_db_t *dba, dns_dbversion_t *dbvera, dns_db_t *dbb, dns_dbversion_t *dbverb, unsigned int options, dns_diff_t *resultdiff) { dns_db_t *db[2]; dns_dbversion_t *ver[2]; dns_dbiterator_t *dbit[2] = { NULL, NULL }; isc_boolean_t have[2] = { ISC_FALSE, ISC_FALSE }; dns_fixedname_t fixname[2]; isc_result_t result, itresult[2]; dns_diff_t diff[2]; int i, t; db[0] = dba, db[1] = dbb; ver[0] = dbvera, ver[1] = dbverb; dns_diff_init(resultdiff->mctx, &diff[0]); dns_diff_init(resultdiff->mctx, &diff[1]); dns_fixedname_init(&fixname[0]); dns_fixedname_init(&fixname[1]); result = dns_db_createiterator(db[0], options, &dbit[0]); if (result != ISC_R_SUCCESS) return (result); result = dns_db_createiterator(db[1], options, &dbit[1]); if (result != ISC_R_SUCCESS) goto cleanup_iterator; itresult[0] = dns_dbiterator_first(dbit[0]); itresult[1] = dns_dbiterator_first(dbit[1]); for (;;) { for (i = 0; i < 2; i++) { if (! have[i] && itresult[i] == ISC_R_SUCCESS) { CHECK(get_name_diff(db[i], ver[i], 0, dbit[i], dns_fixedname_name(&fixname[i]), i == 0 ? DNS_DIFFOP_ADD : DNS_DIFFOP_DEL, &diff[i])); itresult[i] = dns_dbiterator_next(dbit[i]); have[i] = ISC_TRUE; } } if (! have[0] && ! have[1]) { INSIST(ISC_LIST_EMPTY(diff[0].tuples)); INSIST(ISC_LIST_EMPTY(diff[1].tuples)); break; } for (i = 0; i < 2; i++) { if (! have[!i]) { ISC_LIST_APPENDLIST(resultdiff->tuples, diff[i].tuples, link); INSIST(ISC_LIST_EMPTY(diff[i].tuples)); have[i] = ISC_FALSE; goto next; } } t = dns_name_compare(dns_fixedname_name(&fixname[0]), dns_fixedname_name(&fixname[1])); if (t < 0) { ISC_LIST_APPENDLIST(resultdiff->tuples, diff[0].tuples, link); INSIST(ISC_LIST_EMPTY(diff[0].tuples)); have[0] = ISC_FALSE; continue; } if (t > 0) { ISC_LIST_APPENDLIST(resultdiff->tuples, diff[1].tuples, link); INSIST(ISC_LIST_EMPTY(diff[1].tuples)); have[1] = ISC_FALSE; continue; } INSIST(t == 0); CHECK(dns_diff_subtract(diff, resultdiff)); INSIST(ISC_LIST_EMPTY(diff[0].tuples)); INSIST(ISC_LIST_EMPTY(diff[1].tuples)); have[0] = have[1] = ISC_FALSE; next: ; } if (itresult[0] != ISC_R_NOMORE) FAIL(itresult[0]); if (itresult[1] != ISC_R_NOMORE) FAIL(itresult[1]); INSIST(ISC_LIST_EMPTY(diff[0].tuples)); INSIST(ISC_LIST_EMPTY(diff[1].tuples)); failure: dns_dbiterator_destroy(&dbit[1]); cleanup_iterator: dns_dbiterator_destroy(&dbit[0]); dns_diff_clear(&diff[0]); dns_diff_clear(&diff[1]); return (result); } /* * Compare the databases 'dba' and 'dbb' and generate a journal * entry containing the changes to make 'dba' from 'dbb' (note * the order). This journal entry will consist of a single, * possibly very large transaction. */ isc_result_t dns_db_diff(isc_mem_t *mctx, dns_db_t *dba, dns_dbversion_t *dbvera, dns_db_t *dbb, dns_dbversion_t *dbverb, const char *filename) { isc_result_t result; dns_diff_t diff; dns_diff_init(mctx, &diff); result = dns_db_diffx(&diff, dba, dbvera, dbb, dbverb, filename); dns_diff_clear(&diff); return (result); } isc_result_t dns_db_diffx(dns_diff_t *diff, dns_db_t *dba, dns_dbversion_t *dbvera, dns_db_t *dbb, dns_dbversion_t *dbverb, const char *filename) { isc_result_t result; dns_journal_t *journal = NULL; if (filename != NULL) { result = dns_journal_open(diff->mctx, filename, DNS_JOURNAL_CREATE, &journal); if (result != ISC_R_SUCCESS) return (result); } CHECK(diff_namespace(dba, dbvera, dbb, dbverb, DNS_DB_NONSEC3, diff)); CHECK(diff_namespace(dba, dbvera, dbb, dbverb, DNS_DB_NSEC3ONLY, diff)); if (journal != NULL) { if (ISC_LIST_EMPTY(diff->tuples)) isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "no changes"); else CHECK(dns_journal_write_transaction(journal, diff)); } failure: if (journal != NULL) dns_journal_destroy(&journal); return (result); } isc_result_t dns_journal_compact(isc_mem_t *mctx, char *filename, isc_uint32_t serial, isc_uint32_t target_size) { unsigned int i; journal_pos_t best_guess; journal_pos_t current_pos; dns_journal_t *j = NULL; dns_journal_t *new = NULL; journal_rawheader_t rawheader; unsigned int copy_length; size_t namelen; char *buf = NULL; unsigned int size = 0; isc_result_t result; unsigned int indexend; char newname[1024]; char backup[1024]; isc_boolean_t is_backup = ISC_FALSE; REQUIRE(filename != NULL); namelen = strlen(filename); if (namelen > 4U && strcmp(filename + namelen - 4, ".jnl") == 0) namelen -= 4; result = isc_string_printf(newname, sizeof(newname), "%.*s.jnw", (int)namelen, filename); if (result != ISC_R_SUCCESS) return (result); result = isc_string_printf(backup, sizeof(backup), "%.*s.jbk", (int)namelen, filename); if (result != ISC_R_SUCCESS) return (result); result = journal_open(mctx, filename, ISC_FALSE, ISC_FALSE, &j); if (result == ISC_R_NOTFOUND) { is_backup = ISC_TRUE; result = journal_open(mctx, backup, ISC_FALSE, ISC_FALSE, &j); } if (result != ISC_R_SUCCESS) return (result); if (JOURNAL_EMPTY(&j->header)) { dns_journal_destroy(&j); return (ISC_R_SUCCESS); } if (DNS_SERIAL_GT(j->header.begin.serial, serial) || DNS_SERIAL_GT(serial, j->header.end.serial)) { dns_journal_destroy(&j); return (ISC_R_RANGE); } /* * Cope with very small target sizes. */ indexend = sizeof(journal_rawheader_t) + j->header.index_size * sizeof(journal_rawpos_t); if (target_size < indexend * 2) target_size = target_size/2 + indexend; /* * See if there is any work to do. */ if ((isc_uint32_t) j->header.end.offset < target_size) { dns_journal_destroy(&j); return (ISC_R_SUCCESS); } CHECK(journal_open(mctx, newname, ISC_TRUE, ISC_TRUE, &new)); /* * Remove overhead so space test below can succeed. */ if (target_size >= indexend) target_size -= indexend; /* * Find if we can create enough free space. */ best_guess = j->header.begin; for (i = 0; i < j->header.index_size; i++) { if (POS_VALID(j->index[i]) && DNS_SERIAL_GE(serial, j->index[i].serial) && ((isc_uint32_t)(j->header.end.offset - j->index[i].offset) >= target_size / 2) && j->index[i].offset > best_guess.offset) best_guess = j->index[i]; } current_pos = best_guess; while (current_pos.serial != serial) { CHECK(journal_next(j, ¤t_pos)); if (current_pos.serial == j->header.end.serial) break; if (DNS_SERIAL_GE(serial, current_pos.serial) && ((isc_uint32_t)(j->header.end.offset - current_pos.offset) >= (target_size / 2)) && current_pos.offset > best_guess.offset) best_guess = current_pos; else break; } INSIST(best_guess.serial != j->header.end.serial); if (best_guess.serial != serial) CHECK(journal_next(j, &best_guess)); /* * We should now be roughly half target_size provided * we did not reach 'serial'. If not we will just copy * all uncommitted deltas regardless of the size. */ copy_length = j->header.end.offset - best_guess.offset; if (copy_length != 0) { /* * Copy best_guess to end into space just freed. */ size = 64*1024; if (copy_length < size) size = copy_length; buf = isc_mem_get(mctx, size); if (buf == NULL) { result = ISC_R_NOMEMORY; goto failure; } CHECK(journal_seek(j, best_guess.offset)); CHECK(journal_seek(new, indexend)); for (i = 0; i < copy_length; i += size) { unsigned int len = (copy_length - i) > size ? size : (copy_length - i); CHECK(journal_read(j, buf, len)); CHECK(journal_write(new, buf, len)); } CHECK(journal_fsync(new)); /* * Compute new header. */ new->header.begin.serial = best_guess.serial; new->header.begin.offset = indexend; new->header.end.serial = j->header.end.serial; new->header.end.offset = indexend + copy_length; new->header.sourceserial = j->header.sourceserial; new->header.serialset = j->header.serialset; /* * Update the journal header. */ journal_header_encode(&new->header, &rawheader); CHECK(journal_seek(new, 0)); CHECK(journal_write(new, &rawheader, sizeof(rawheader))); CHECK(journal_fsync(new)); /* * Build new index. */ current_pos = new->header.begin; while (current_pos.serial != new->header.end.serial) { index_add(new, ¤t_pos); CHECK(journal_next(new, ¤t_pos)); } /* * Write index. */ CHECK(index_to_disk(new)); CHECK(journal_fsync(new)); indexend = new->header.end.offset; POST(indexend); } /* * Close both journals before trying to rename files (this is * necessary on WIN32). */ dns_journal_destroy(&j); dns_journal_destroy(&new); /* * With a UFS file system this should just succeed and be atomic. * Any IXFR outs will just continue and the old journal will be * removed on final close. * * With MSDOS / NTFS we need to do a two stage rename, triggered * by EEXIST. (If any IXFR's are running in other threads, however, * this will fail, and the journal will not be compacted. But * if so, hopefully they'll be finished by the next time we * compact.) */ if (rename(newname, filename) == -1) { if (errno == EEXIST && !is_backup) { result = isc_file_remove(backup); if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) goto failure; if (rename(filename, backup) == -1) goto maperrno; if (rename(newname, filename) == -1) goto maperrno; (void)isc_file_remove(backup); } else { maperrno: result = ISC_R_FAILURE; goto failure; } } result = ISC_R_SUCCESS; failure: (void)isc_file_remove(newname); if (buf != NULL) isc_mem_put(mctx, buf, size); if (j != NULL) dns_journal_destroy(&j); if (new != NULL) dns_journal_destroy(&new); return (result); } static isc_result_t index_to_disk(dns_journal_t *j) { isc_result_t result = ISC_R_SUCCESS; if (j->header.index_size != 0) { unsigned int i; unsigned char *p; unsigned int rawbytes; rawbytes = j->header.index_size * sizeof(journal_rawpos_t); p = j->rawindex; for (i = 0; i < j->header.index_size; i++) { encode_uint32(j->index[i].serial, p); p += 4; encode_uint32(j->index[i].offset, p); p += 4; } INSIST(p == j->rawindex + rawbytes); CHECK(journal_seek(j, sizeof(journal_rawheader_t))); CHECK(journal_write(j, j->rawindex, rawbytes)); } failure: return (result); } bind9-9.10.3.dfsg.P4/lib/dns/mapapi0000644000470500017500000000147612664710322016125 0ustar lamontlamont# This value should be increased whenever changing the structure of # any object that will appear in a type 'map' master file (which # contains a working memory image of an RBT database), as loading # an incorrect memory image produces an inconsistent and probably # nonfunctional database. These structures include but are not # necessarily limited to dns_masterrawheader, rbtdb_file_header, # rbt_file_header, dns_rbtdb, dns_rbt, dns_rbtnode, rdatasetheader. # # Err on the side of caution: if anything in the RBTDB is changed, # bump the value. Making map files unreadable protects the system # from instability; it's a feature not a bug. # # Whenever releasing a new major release of BIND9, set this value # back to 1.0 when releasing the first alpha. Fast files are *never* # compatible across major releases. MAPAPI=1.1 bind9-9.10.3.dfsg.P4/lib/dns/soa.c0000644000470500017500000001006612664710322015654 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: soa.c,v 1.12 2009/09/10 02:18:40 each Exp $ */ /*! \file */ #include #include #include #include #include #include #include static inline isc_uint32_t decode_uint32(unsigned char *p) { return ((p[0] << 24) + (p[1] << 16) + (p[2] << 8) + (p[3] << 0)); } static inline void encode_uint32(isc_uint32_t val, unsigned char *p) { p[0] = (isc_uint8_t)(val >> 24); p[1] = (isc_uint8_t)(val >> 16); p[2] = (isc_uint8_t)(val >> 8); p[3] = (isc_uint8_t)(val >> 0); } static isc_uint32_t soa_get(dns_rdata_t *rdata, int offset) { INSIST(rdata->type == dns_rdatatype_soa); /* * Locate the field within the SOA RDATA based * on its position relative to the end of the data. * * This is a bit of a kludge, but the alternative approach of * using dns_rdata_tostruct() and dns_rdata_fromstruct() would * involve a lot of unnecessary work (like building domain * names and allocating temporary memory) when all we really * want to do is to get 32 bits of fixed-sized data. */ INSIST(rdata->length >= 20); INSIST(offset >= 0 && offset <= 16); return (decode_uint32(rdata->data + rdata->length - 20 + offset)); } isc_result_t dns_soa_buildrdata(dns_name_t *origin, dns_name_t *contact, dns_rdataclass_t rdclass, isc_uint32_t serial, isc_uint32_t refresh, isc_uint32_t retry, isc_uint32_t expire, isc_uint32_t minimum, unsigned char *buffer, dns_rdata_t *rdata) { dns_rdata_soa_t soa; isc_buffer_t rdatabuf; REQUIRE(origin != NULL); REQUIRE(contact != NULL); memset(buffer, 0, DNS_SOA_BUFFERSIZE); isc_buffer_init(&rdatabuf, buffer, DNS_SOA_BUFFERSIZE); soa.common.rdtype = dns_rdatatype_soa; soa.common.rdclass = rdclass; soa.mctx = NULL; soa.serial = serial; soa.refresh = refresh; soa.retry = retry; soa.expire = expire; soa.minimum = minimum; dns_name_init(&soa.origin, NULL); dns_name_clone(origin, &soa.origin); dns_name_init(&soa.contact, NULL); dns_name_clone(contact, &soa.contact); return (dns_rdata_fromstruct(rdata, rdclass, dns_rdatatype_soa, &soa, &rdatabuf)); } isc_uint32_t dns_soa_getserial(dns_rdata_t *rdata) { return soa_get(rdata, 0); } isc_uint32_t dns_soa_getrefresh(dns_rdata_t *rdata) { return soa_get(rdata, 4); } isc_uint32_t dns_soa_getretry(dns_rdata_t *rdata) { return soa_get(rdata, 8); } isc_uint32_t dns_soa_getexpire(dns_rdata_t *rdata) { return soa_get(rdata, 12); } isc_uint32_t dns_soa_getminimum(dns_rdata_t *rdata) { return soa_get(rdata, 16); } static void soa_set(dns_rdata_t *rdata, isc_uint32_t val, int offset) { INSIST(rdata->type == dns_rdatatype_soa); INSIST(rdata->length >= 20); INSIST(offset >= 0 && offset <= 16); encode_uint32(val, rdata->data + rdata->length - 20 + offset); } void dns_soa_setserial(isc_uint32_t val, dns_rdata_t *rdata) { soa_set(rdata, val, 0); } void dns_soa_setrefresh(isc_uint32_t val, dns_rdata_t *rdata) { soa_set(rdata, val, 4); } void dns_soa_setretry(isc_uint32_t val, dns_rdata_t *rdata) { soa_set(rdata, val, 8); } void dns_soa_setexpire(isc_uint32_t val, dns_rdata_t *rdata) { soa_set(rdata, val, 12); } void dns_soa_setminimum(isc_uint32_t val, dns_rdata_t *rdata) { soa_set(rdata, val, 16); } bind9-9.10.3.dfsg.P4/lib/dns/zone.c0000644000470500017500000166770012664710322016063 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E') #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC) #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y') #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC) #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b') #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC) #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r') #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC) #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd') #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC) #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w') #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC) #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O') #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC) /*% * Ensure 'a' is at least 'min' but not more than 'max'. */ #define RANGE(a, min, max) \ (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max))) #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0) /*% * Key flags */ #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0) #define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0) #define ALG(x) dst_key_alg(x) /* * Default values. */ #define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */ #define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */ #define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */ #define RESIGN_DELAY 3600 /*%< 1 hour */ #ifndef DNS_MAX_EXPIRE #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */ #endif #ifndef DNS_DUMP_DELAY #define DNS_DUMP_DELAY 900 /*%< 15 minutes */ #endif typedef struct dns_notify dns_notify_t; typedef struct dns_stub dns_stub_t; typedef struct dns_load dns_load_t; typedef struct dns_forward dns_forward_t; typedef ISC_LIST(dns_forward_t) dns_forwardlist_t; typedef struct dns_io dns_io_t; typedef ISC_LIST(dns_io_t) dns_iolist_t; typedef struct dns_signing dns_signing_t; typedef ISC_LIST(dns_signing_t) dns_signinglist_t; typedef struct dns_nsec3chain dns_nsec3chain_t; typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t; typedef struct dns_keyfetch dns_keyfetch_t; typedef struct dns_asyncload dns_asyncload_t; typedef struct dns_include dns_include_t; #define DNS_ZONE_CHECKLOCK #ifdef DNS_ZONE_CHECKLOCK #define LOCK_ZONE(z) \ do { LOCK(&(z)->lock); \ INSIST((z)->locked == ISC_FALSE); \ (z)->locked = ISC_TRUE; \ } while (0) #define UNLOCK_ZONE(z) \ do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0) #define LOCKED_ZONE(z) ((z)->locked) #define TRYLOCK_ZONE(result, z) \ do { \ result = isc_mutex_trylock(&(z)->lock); \ if (result == ISC_R_SUCCESS) { \ INSIST((z)->locked == ISC_FALSE); \ (z)->locked = ISC_TRUE; \ } \ } while (0) #else #define LOCK_ZONE(z) LOCK(&(z)->lock) #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock) #define LOCKED_ZONE(z) ISC_TRUE #define TRYLOCK_ZONE(result, z) \ do { result = isc_mutex_trylock(&(z)->lock); } while (0) #endif #ifdef ISC_RWLOCK_USEATOMIC #define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0) #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l) #define ZONEDB_LOCK(l, t) RWLOCK((l), (t)) #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t)) #else #define ZONEDB_INITLOCK(l) isc_mutex_init(l) #define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l) #define ZONEDB_LOCK(l, t) LOCK(l) #define ZONEDB_UNLOCK(l, t) UNLOCK(l) #endif struct dns_zone { /* Unlocked */ unsigned int magic; isc_mutex_t lock; #ifdef DNS_ZONE_CHECKLOCK isc_boolean_t locked; #endif isc_mem_t *mctx; isc_refcount_t erefs; #ifdef ISC_RWLOCK_USEATOMIC isc_rwlock_t dblock; #else isc_mutex_t dblock; #endif dns_db_t *db; /* Locked by dblock */ /* Locked */ dns_zonemgr_t *zmgr; ISC_LINK(dns_zone_t) link; /* Used by zmgr. */ isc_timer_t *timer; unsigned int irefs; dns_name_t origin; char *masterfile; ISC_LIST(dns_include_t) includes; /* Include files */ ISC_LIST(dns_include_t) newincludes; /* Loading */ unsigned int nincludes; dns_masterformat_t masterformat; char *journal; isc_int32_t journalsize; dns_rdataclass_t rdclass; dns_zonetype_t type; unsigned int flags; unsigned int options; unsigned int options2; unsigned int db_argc; char **db_argv; isc_time_t expiretime; isc_time_t refreshtime; isc_time_t dumptime; isc_time_t loadtime; isc_time_t notifytime; isc_time_t resigntime; isc_time_t keywarntime; isc_time_t signingtime; isc_time_t nsec3chaintime; isc_time_t refreshkeytime; isc_uint32_t refreshkeyinterval; isc_uint32_t refreshkeycount; isc_uint32_t refresh; isc_uint32_t retry; isc_uint32_t expire; isc_uint32_t minimum; isc_stdtime_t key_expiry; isc_stdtime_t log_key_expired_timer; char *keydirectory; isc_uint32_t maxrefresh; isc_uint32_t minrefresh; isc_uint32_t maxretry; isc_uint32_t minretry; isc_sockaddr_t *masters; isc_dscp_t *masterdscps; dns_name_t **masterkeynames; isc_boolean_t *mastersok; unsigned int masterscnt; unsigned int curmaster; isc_sockaddr_t masteraddr; dns_notifytype_t notifytype; isc_sockaddr_t *notify; dns_name_t **notifykeynames; isc_dscp_t *notifydscp; unsigned int notifycnt; isc_sockaddr_t notifyfrom; isc_task_t *task; isc_task_t *loadtask; isc_sockaddr_t notifysrc4; isc_sockaddr_t notifysrc6; isc_sockaddr_t xfrsource4; isc_sockaddr_t xfrsource6; isc_sockaddr_t altxfrsource4; isc_sockaddr_t altxfrsource6; isc_sockaddr_t sourceaddr; isc_dscp_t notifysrc4dscp; isc_dscp_t notifysrc6dscp; isc_dscp_t xfrsource4dscp; isc_dscp_t xfrsource6dscp; isc_dscp_t altxfrsource4dscp; isc_dscp_t altxfrsource6dscp; dns_xfrin_ctx_t *xfr; /* task locked */ dns_tsigkey_t *tsigkey; /* key used for xfr */ /* Access Control Lists */ dns_acl_t *update_acl; dns_acl_t *forward_acl; dns_acl_t *notify_acl; dns_acl_t *query_acl; dns_acl_t *queryon_acl; dns_acl_t *xfr_acl; isc_boolean_t update_disabled; isc_boolean_t zero_no_soa_ttl; dns_severity_t check_names; ISC_LIST(dns_notify_t) notifies; dns_request_t *request; dns_loadctx_t *lctx; dns_io_t *readio; dns_dumpctx_t *dctx; dns_io_t *writeio; isc_uint32_t maxxfrin; isc_uint32_t maxxfrout; isc_uint32_t idlein; isc_uint32_t idleout; isc_event_t ctlevent; dns_ssutable_t *ssutable; isc_uint32_t sigvalidityinterval; isc_uint32_t sigresigninginterval; dns_view_t *view; dns_acache_t *acache; dns_checkmxfunc_t checkmx; dns_checksrvfunc_t checksrv; dns_checknsfunc_t checkns; /*% * Zones in certain states such as "waiting for zone transfer" * or "zone transfer in progress" are kept on per-state linked lists * in the zone manager using the 'statelink' field. The 'statelist' * field points at the list the zone is currently on. It the zone * is not on any such list, statelist is NULL. */ ISC_LINK(dns_zone_t) statelink; dns_zonelist_t *statelist; /*% * Statistics counters about zone management. */ isc_stats_t *stats; /*% * Optional per-zone statistics counters. Counted outside of this * module. */ dns_zonestat_level_t statlevel; isc_boolean_t requeststats_on; isc_stats_t *requeststats; dns_stats_t *rcvquerystats; isc_uint32_t notifydelay; dns_isselffunc_t isself; void *isselfarg; char * strnamerd; char * strname; char * strrdclass; char * strviewname; /*% * Serial number for deferred journal compaction. */ isc_uint32_t compact_serial; /*% * Keys that are signing the zone for the first time. */ dns_signinglist_t signing; dns_nsec3chainlist_t nsec3chain; /*% * Signing / re-signing quantum stopping parameters. */ isc_uint32_t signatures; isc_uint32_t nodes; dns_rdatatype_t privatetype; /*% * Autosigning/key-maintenance options */ isc_uint32_t keyopts; /*% * True if added by "rndc addzone" */ isc_boolean_t added; /*% * response policy data to be relayed to the database */ dns_rpz_zones_t *rpzs; dns_rpz_num_t rpz_num; /*% * Serial number update method. */ dns_updatemethod_t updatemethod; /*% * whether ixfr is requested */ isc_boolean_t requestixfr; /*% * Outstanding forwarded UPDATE requests. */ dns_forwardlist_t forwards; dns_zone_t *raw; dns_zone_t *secure; isc_boolean_t sourceserialset; isc_uint32_t sourceserial; /*% * maximum zone ttl */ dns_ttl_t maxttl; /* * Inline zone signing state. */ dns_diff_t rss_diff; isc_eventlist_t rss_events; dns_dbversion_t *rss_newver; dns_dbversion_t *rss_oldver; dns_db_t *rss_db; dns_zone_t *rss_raw; isc_event_t *rss_event; dns_update_state_t *rss_state; }; typedef struct { dns_diff_t *diff; isc_boolean_t offline; } zonediff_t; #define zonediff_init(z, d) \ do { \ zonediff_t *_z = (z); \ (_z)->diff = (d); \ (_z)->offline = ISC_FALSE; \ } while (0) #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0)) #define DNS_ZONE_SETFLAG(z,f) do { \ INSIST(LOCKED_ZONE(z)); \ (z)->flags |= (f); \ } while (0) #define DNS_ZONE_CLRFLAG(z,f) do { \ INSIST(LOCKED_ZONE(z)); \ (z)->flags &= ~(f); \ } while (0) /* XXX MPA these may need to go back into zone.h */ #define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */ #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */ #define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */ #define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */ #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */ #define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */ #define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */ #define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */ #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */ #define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are * uptodate */ #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify * messages */ #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on * reload */ #define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a * zone with no masters * occurred */ #define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/ #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set * from SOA (if not set, we * are still using * default timer values) */ #define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */ #define DNS_ZONEFLG_NOREFRESH 0x00010000U #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U #define DNS_ZONEFLG_DIALREFRESH 0x00040000U #define DNS_ZONEFLG_SHUTDOWN 0x00080000U #define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */ #define DNS_ZONEFLG_FLUSH 0x00200000U #define DNS_ZONEFLG_NOEDNS 0x00400000U #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U #define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */ #define DNS_ZONEFLG_THAW 0x08000000U #define DNS_ZONEFLG_LOADPENDING 0x10000000U /*%< Loading scheduled */ #define DNS_ZONEFLG_NODELAY 0x20000000U #define DNS_ZONEFLG_SENDSECURE 0x40000000U #define DNS_ZONEFLG_NEEDSTARTUPNOTIFY 0x80000000U /*%< need to send out notify * due to the zone just * being loaded for the * first time. */ #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0) #define DNS_ZONE_OPTION2(z,o) (((z)->options2 & (o)) != 0) #define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0) /* Flags for zone_load() */ #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */ #define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful load. */ #define UNREACH_CHACHE_SIZE 10U #define UNREACH_HOLD_TIME 600 /* 10 minutes */ #define CHECK(op) \ do { result = (op); \ if (result != ISC_R_SUCCESS) goto failure; \ } while (0) struct dns_unreachable { isc_sockaddr_t remote; isc_sockaddr_t local; isc_uint32_t expire; isc_uint32_t last; isc_uint32_t count; }; struct dns_zonemgr { unsigned int magic; isc_mem_t * mctx; int refs; /* Locked by rwlock */ isc_taskmgr_t * taskmgr; isc_timermgr_t * timermgr; isc_socketmgr_t * socketmgr; isc_taskpool_t * zonetasks; isc_taskpool_t * loadtasks; isc_task_t * task; isc_pool_t * mctxpool; isc_ratelimiter_t * notifyrl; isc_ratelimiter_t * refreshrl; isc_ratelimiter_t * startupnotifyrl; isc_ratelimiter_t * startuprefreshrl; isc_rwlock_t rwlock; isc_mutex_t iolock; isc_rwlock_t urlock; /* Locked by rwlock. */ dns_zonelist_t zones; dns_zonelist_t waiting_for_xfrin; dns_zonelist_t xfrin_in_progress; /* Configuration data. */ isc_uint32_t transfersin; isc_uint32_t transfersperns; unsigned int notifyrate; unsigned int startupnotifyrate; unsigned int serialqueryrate; unsigned int startupserialqueryrate; /* Locked by iolock */ isc_uint32_t iolimit; isc_uint32_t ioactive; dns_iolist_t high; dns_iolist_t low; /* Locked by urlock. */ /* LRU cache */ struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE]; }; /*% * Hold notify state. */ struct dns_notify { unsigned int magic; unsigned int flags; isc_mem_t *mctx; dns_zone_t *zone; dns_adbfind_t *find; dns_request_t *request; dns_name_t ns; isc_sockaddr_t dst; dns_tsigkey_t *key; isc_dscp_t dscp; ISC_LINK(dns_notify_t) link; isc_event_t *event; }; #define DNS_NOTIFY_NOSOA 0x0001U #define DNS_NOTIFY_STARTUP 0x0002U /*% * dns_stub holds state while performing a 'stub' transfer. * 'db' is the zone's 'db' or a new one if this is the initial * transfer. */ struct dns_stub { unsigned int magic; isc_mem_t *mctx; dns_zone_t *zone; dns_db_t *db; dns_dbversion_t *version; }; /*% * Hold load state. */ struct dns_load { unsigned int magic; isc_mem_t *mctx; dns_zone_t *zone; dns_db_t *db; isc_time_t loadtime; dns_rdatacallbacks_t callbacks; }; /*% * Hold forward state. */ struct dns_forward { unsigned int magic; isc_mem_t *mctx; dns_zone_t *zone; isc_buffer_t *msgbuf; dns_request_t *request; isc_uint32_t which; isc_sockaddr_t addr; dns_updatecallback_t callback; void *callback_arg; unsigned int options; ISC_LINK(dns_forward_t) link; }; /*% * Hold IO request state. */ struct dns_io { unsigned int magic; dns_zonemgr_t *zmgr; isc_boolean_t high; isc_task_t *task; ISC_LINK(dns_io_t) link; isc_event_t *event; }; /*% * Hold state for when we are signing a zone with a new * DNSKEY as result of an update. */ struct dns_signing { unsigned int magic; dns_db_t *db; dns_dbiterator_t *dbiterator; dns_secalg_t algorithm; isc_uint16_t keyid; isc_boolean_t delete; isc_boolean_t done; ISC_LINK(dns_signing_t) link; }; struct dns_nsec3chain { unsigned int magic; dns_db_t *db; dns_dbiterator_t *dbiterator; dns_rdata_nsec3param_t nsec3param; unsigned char salt[255]; isc_boolean_t done; isc_boolean_t seen_nsec; isc_boolean_t delete_nsec; isc_boolean_t save_delete_nsec; ISC_LINK(dns_nsec3chain_t) link; }; /*%< * 'dbiterator' contains a iterator for the database. If we are creating * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be * iterated. * * 'nsec3param' contains the parameters of the NSEC3 chain being created * or removed. * * 'salt' is buffer space and is referenced via 'nsec3param.salt'. * * 'seen_nsec' will be set to true if, while iterating the zone to create a * NSEC3 chain, a NSEC record is seen. * * 'delete_nsec' will be set to true if, at the completion of the creation * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we * are in the process of deleting the NSEC chain. * * 'save_delete_nsec' is used to store the initial state of 'delete_nsec' * so it can be recovered in the event of a error. */ struct dns_keyfetch { dns_fixedname_t name; dns_rdataset_t keydataset; dns_rdataset_t dnskeyset; dns_rdataset_t dnskeysigset; dns_zone_t *zone; dns_db_t *db; dns_fetch_t *fetch; }; /*% * Hold state for an asynchronous load */ struct dns_asyncload { dns_zone_t *zone; dns_zt_zoneloaded_t loaded; void *loaded_arg; }; /*% * Reference to an include file encountered during loading */ struct dns_include { char *name; isc_time_t filetime; ISC_LINK(dns_include_t) link; }; #define HOUR 3600 #define DAY (24*HOUR) #define MONTH (30*DAY) /* * These can be overridden by the -T mkeytimers option on the command * line, so that we can test with shorter periods than specified in * RFC 5011. */ unsigned int dns_zone_mkey_hour = HOUR; unsigned int dns_zone_mkey_day = DAY; unsigned int dns_zone_mkey_month = MONTH; #define SEND_BUFFER_SIZE 2048 static void zone_settimer(dns_zone_t *, isc_time_t *); static void cancel_refresh(dns_zone_t *); static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel, const char *msg, ...) ISC_FORMAT_PRINTF(4, 5); static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4); static void queue_xfrin(dns_zone_t *zone); static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata); static void zone_unload(dns_zone_t *zone); static void zone_expire(dns_zone_t *zone); static void zone_iattach(dns_zone_t *source, dns_zone_t **target); static void zone_idetach(dns_zone_t **zonep); static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump); static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db); static inline void zone_detachdb(dns_zone_t *zone); static isc_result_t default_journal(dns_zone_t *zone); static void zone_xfrdone(dns_zone_t *zone, isc_result_t result); static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, isc_result_t result); static void zone_needdump(dns_zone_t *zone, unsigned int delay); static void zone_shutdown(isc_task_t *, isc_event_t *); static void zone_loaddone(void *arg, isc_result_t result); static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime); static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length); static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length); static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length); static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length); static isc_result_t zone_send_secureserial(dns_zone_t *zone, isc_uint32_t serial); #if 0 /* ondestroy example */ static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event); #endif static void refresh_callback(isc_task_t *, isc_event_t *); static void stub_callback(isc_task_t *, isc_event_t *); static void queue_soa_query(dns_zone_t *zone); static void soa_query(isc_task_t *, isc_event_t *); static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub); static int message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type); static void notify_cancel(dns_zone_t *zone); static void notify_find_address(dns_notify_t *notify); static void notify_send(dns_notify_t *notify); static isc_result_t notify_createmessage(dns_zone_t *zone, unsigned int flags, dns_message_t **messagep); static void notify_done(isc_task_t *task, isc_event_t *event); static void notify_send_toaddr(isc_task_t *task, isc_event_t *event); static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t); static void got_transfer_quota(isc_task_t *task, isc_event_t *event); static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone); static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi); static void zonemgr_free(dns_zonemgr_t *zmgr); static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high, isc_task_t *task, isc_taskaction_t action, void *arg, dns_io_t **iop); static void zonemgr_putio(dns_io_t **iop); static void zonemgr_cancelio(dns_io_t *io); static isc_result_t zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, unsigned int *soacount, isc_uint32_t *serial, isc_uint32_t *refresh, isc_uint32_t *retry, isc_uint32_t *expire, isc_uint32_t *minimum, unsigned int *errors); static void zone_freedbargs(dns_zone_t *zone); static void forward_callback(isc_task_t *task, isc_event_t *event); static void zone_saveunique(dns_zone_t *zone, const char *path, const char *templat); static void zone_maintenance(dns_zone_t *zone); static void zone_notify(dns_zone_t *zone, isc_time_t *now); static void dump_done(void *arg, isc_result_t result); static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid, isc_boolean_t delete); static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, dns_name_t *name, dns_diff_t *diff); static void zone_rekey(dns_zone_t *zone); static isc_result_t zone_send_securedb(dns_zone_t *zone, dns_db_t *db); static void setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value); #define ENTER zone_debuglog(zone, me, 1, "enter") static const unsigned int dbargc_default = 1; static const char *dbargv_default[] = { "rbt" }; #define DNS_ZONE_JITTER_ADD(a, b, c) \ do { \ isc_interval_t _i; \ isc_uint32_t _j; \ _j = isc_random_jitter((b), (b)/4); \ isc_interval_set(&_i, _j, 0); \ if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \ dns_zone_log(zone, ISC_LOG_WARNING, \ "epoch approaching: upgrade required: " \ "now + %s failed", #b); \ isc_interval_set(&_i, _j/2, 0); \ (void)isc_time_add((a), &_i, (c)); \ } \ } while (0) #define DNS_ZONE_TIME_ADD(a, b, c) \ do { \ isc_interval_t _i; \ isc_interval_set(&_i, (b), 0); \ if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \ dns_zone_log(zone, ISC_LOG_WARNING, \ "epoch approaching: upgrade required: " \ "now + %s failed", #b); \ isc_interval_set(&_i, (b)/2, 0); \ (void)isc_time_add((a), &_i, (c)); \ } \ } while (0) typedef struct nsec3param nsec3param_t; struct nsec3param { unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1]; unsigned int length; isc_boolean_t nsec; isc_boolean_t replace; ISC_LINK(nsec3param_t) link; }; typedef ISC_LIST(nsec3param_t) nsec3paramlist_t; struct np3event { isc_event_t event; nsec3param_t params; }; /*% * Increment resolver-related statistics counters. Zone must be locked. */ static inline void inc_stats(dns_zone_t *zone, isc_statscounter_t counter) { if (zone->stats != NULL) isc_stats_increment(zone->stats, counter); } /*** *** Public functions. ***/ isc_result_t dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { isc_result_t result; dns_zone_t *zone; isc_time_t now; REQUIRE(zonep != NULL && *zonep == NULL); REQUIRE(mctx != NULL); TIME_NOW(&now); zone = isc_mem_get(mctx, sizeof(*zone)); if (zone == NULL) return (ISC_R_NOMEMORY); zone->mctx = NULL; isc_mem_attach(mctx, &zone->mctx); result = isc_mutex_init(&zone->lock); if (result != ISC_R_SUCCESS) goto free_zone; result = ZONEDB_INITLOCK(&zone->dblock); if (result != ISC_R_SUCCESS) goto free_mutex; /* XXX MPA check that all elements are initialised */ #ifdef DNS_ZONE_CHECKLOCK zone->locked = ISC_FALSE; #endif zone->db = NULL; zone->zmgr = NULL; ISC_LINK_INIT(zone, link); result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */ if (result != ISC_R_SUCCESS) goto free_dblock; zone->irefs = 0; dns_name_init(&zone->origin, NULL); zone->strnamerd = NULL; zone->strname = NULL; zone->strrdclass = NULL; zone->strviewname = NULL; zone->masterfile = NULL; ISC_LIST_INIT(zone->includes); ISC_LIST_INIT(zone->newincludes); zone->nincludes = 0; zone->masterformat = dns_masterformat_none; zone->keydirectory = NULL; zone->journalsize = -1; zone->journal = NULL; zone->rdclass = dns_rdataclass_none; zone->type = dns_zone_none; zone->flags = 0; zone->options = 0; zone->options2 = 0; zone->keyopts = 0; zone->db_argc = 0; zone->db_argv = NULL; isc_time_settoepoch(&zone->expiretime); isc_time_settoepoch(&zone->refreshtime); isc_time_settoepoch(&zone->dumptime); isc_time_settoepoch(&zone->loadtime); zone->notifytime = now; isc_time_settoepoch(&zone->resigntime); isc_time_settoepoch(&zone->keywarntime); isc_time_settoepoch(&zone->signingtime); isc_time_settoepoch(&zone->nsec3chaintime); isc_time_settoepoch(&zone->refreshkeytime); zone->refreshkeyinterval = 0; zone->refreshkeycount = 0; zone->refresh = DNS_ZONE_DEFAULTREFRESH; zone->retry = DNS_ZONE_DEFAULTRETRY; zone->expire = 0; zone->minimum = 0; zone->maxrefresh = DNS_ZONE_MAXREFRESH; zone->minrefresh = DNS_ZONE_MINREFRESH; zone->maxretry = DNS_ZONE_MAXRETRY; zone->minretry = DNS_ZONE_MINRETRY; zone->masters = NULL; zone->masterdscps = NULL; zone->masterkeynames = NULL; zone->mastersok = NULL; zone->masterscnt = 0; zone->curmaster = 0; zone->maxttl = 0; zone->notify = NULL; zone->notifykeynames = NULL; zone->notifydscp = NULL; zone->notifytype = dns_notifytype_yes; zone->notifycnt = 0; zone->task = NULL; zone->loadtask = NULL; zone->update_acl = NULL; zone->forward_acl = NULL; zone->notify_acl = NULL; zone->query_acl = NULL; zone->queryon_acl = NULL; zone->xfr_acl = NULL; zone->update_disabled = ISC_FALSE; zone->zero_no_soa_ttl = ISC_TRUE; zone->check_names = dns_severity_ignore; zone->request = NULL; zone->lctx = NULL; zone->readio = NULL; zone->dctx = NULL; zone->writeio = NULL; zone->timer = NULL; zone->idlein = DNS_DEFAULT_IDLEIN; zone->idleout = DNS_DEFAULT_IDLEOUT; zone->log_key_expired_timer = 0; ISC_LIST_INIT(zone->notifies); isc_sockaddr_any(&zone->notifysrc4); isc_sockaddr_any6(&zone->notifysrc6); isc_sockaddr_any(&zone->xfrsource4); isc_sockaddr_any6(&zone->xfrsource6); isc_sockaddr_any(&zone->altxfrsource4); isc_sockaddr_any6(&zone->altxfrsource6); zone->notifysrc4dscp = -1; zone->notifysrc6dscp = -1; zone->xfrsource4dscp = -1; zone->xfrsource6dscp = -1; zone->altxfrsource4dscp = -1; zone->altxfrsource6dscp = -1; zone->xfr = NULL; zone->tsigkey = NULL; zone->maxxfrin = MAX_XFER_TIME; zone->maxxfrout = MAX_XFER_TIME; zone->ssutable = NULL; zone->sigvalidityinterval = 30 * 24 * 3600; zone->sigresigninginterval = 7 * 24 * 3600; zone->view = NULL; zone->acache = NULL; zone->checkmx = NULL; zone->checksrv = NULL; zone->checkns = NULL; ISC_LINK_INIT(zone, statelink); zone->statelist = NULL; zone->stats = NULL; zone->requeststats_on = ISC_FALSE; zone->statlevel = dns_zonestat_none; zone->requeststats = NULL; zone->rcvquerystats = NULL; zone->notifydelay = 5; zone->isself = NULL; zone->isselfarg = NULL; ISC_LIST_INIT(zone->signing); ISC_LIST_INIT(zone->nsec3chain); zone->signatures = 10; zone->nodes = 100; zone->privatetype = (dns_rdatatype_t)0xffffU; zone->added = ISC_FALSE; zone->rpzs = NULL; zone->rpz_num = DNS_RPZ_INVALID_NUM; ISC_LIST_INIT(zone->forwards); zone->raw = NULL; zone->secure = NULL; zone->sourceserial = 0; zone->sourceserialset = ISC_FALSE; ISC_LIST_INIT(zone->rss_events); zone->rss_db = NULL; zone->rss_raw = NULL; zone->rss_newver = NULL; zone->rss_oldver = NULL; zone->rss_event = NULL; zone->rss_state = NULL; zone->updatemethod = dns_updatemethod_increment; zone->magic = ZONE_MAGIC; /* Must be after magic is set. */ result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default); if (result != ISC_R_SUCCESS) goto free_erefs; ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL, DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone, NULL, NULL); *zonep = zone; return (ISC_R_SUCCESS); free_erefs: isc_refcount_decrement(&zone->erefs, NULL); isc_refcount_destroy(&zone->erefs); free_dblock: ZONEDB_DESTROYLOCK(&zone->dblock); free_mutex: DESTROYLOCK(&zone->lock); free_zone: isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone)); return (result); } /* * Free a zone. Because we require that there be no more * outstanding events or references, no locking is necessary. */ static void zone_free(dns_zone_t *zone) { isc_mem_t *mctx = NULL; dns_signing_t *signing; dns_nsec3chain_t *nsec3chain; dns_include_t *include; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(isc_refcount_current(&zone->erefs) == 0); REQUIRE(zone->irefs == 0); REQUIRE(!LOCKED_ZONE(zone)); REQUIRE(zone->timer == NULL); REQUIRE(zone->zmgr == NULL); /* * Managed objects. Order is important. */ if (zone->request != NULL) dns_request_destroy(&zone->request); /* XXXMPA */ INSIST(zone->readio == NULL); INSIST(zone->statelist == NULL); INSIST(zone->writeio == NULL); if (zone->task != NULL) isc_task_detach(&zone->task); if (zone->loadtask != NULL) isc_task_detach(&zone->loadtask); /* Unmanaged objects */ for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL; signing = ISC_LIST_HEAD(zone->signing)) { ISC_LIST_UNLINK(zone->signing, signing, link); dns_db_detach(&signing->db); dns_dbiterator_destroy(&signing->dbiterator); isc_mem_put(zone->mctx, signing, sizeof *signing); } for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL; nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) { ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link); dns_db_detach(&nsec3chain->db); dns_dbiterator_destroy(&nsec3chain->dbiterator); isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); } for (include = ISC_LIST_HEAD(zone->includes); include != NULL; include = ISC_LIST_HEAD(zone->includes)) { ISC_LIST_UNLINK(zone->includes, include, link); isc_mem_free(zone->mctx, include->name); isc_mem_put(zone->mctx, include, sizeof *include); } for (include = ISC_LIST_HEAD(zone->newincludes); include != NULL; include = ISC_LIST_HEAD(zone->newincludes)) { ISC_LIST_UNLINK(zone->newincludes, include, link); isc_mem_free(zone->mctx, include->name); isc_mem_put(zone->mctx, include, sizeof *include); } if (zone->masterfile != NULL) isc_mem_free(zone->mctx, zone->masterfile); zone->masterfile = NULL; if (zone->keydirectory != NULL) isc_mem_free(zone->mctx, zone->keydirectory); zone->keydirectory = NULL; zone->journalsize = -1; if (zone->journal != NULL) isc_mem_free(zone->mctx, zone->journal); zone->journal = NULL; if (zone->stats != NULL) isc_stats_detach(&zone->stats); if (zone->requeststats != NULL) isc_stats_detach(&zone->requeststats); if (zone->rcvquerystats != NULL) dns_stats_detach(&zone->rcvquerystats); if (zone->db != NULL) zone_detachdb(zone); if (zone->acache != NULL) dns_acache_detach(&zone->acache); if (zone->rpzs != NULL) { REQUIRE(zone->rpz_num < zone->rpzs->p.num_zones); dns_rpz_detach_rpzs(&zone->rpzs); zone->rpz_num = DNS_RPZ_INVALID_NUM; } zone_freedbargs(zone); RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0) == ISC_R_SUCCESS); RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0) == ISC_R_SUCCESS); zone->check_names = dns_severity_ignore; if (zone->update_acl != NULL) dns_acl_detach(&zone->update_acl); if (zone->forward_acl != NULL) dns_acl_detach(&zone->forward_acl); if (zone->notify_acl != NULL) dns_acl_detach(&zone->notify_acl); if (zone->query_acl != NULL) dns_acl_detach(&zone->query_acl); if (zone->queryon_acl != NULL) dns_acl_detach(&zone->queryon_acl); if (zone->xfr_acl != NULL) dns_acl_detach(&zone->xfr_acl); if (dns_name_dynamic(&zone->origin)) dns_name_free(&zone->origin, zone->mctx); if (zone->strnamerd != NULL) isc_mem_free(zone->mctx, zone->strnamerd); if (zone->strname != NULL) isc_mem_free(zone->mctx, zone->strname); if (zone->strrdclass != NULL) isc_mem_free(zone->mctx, zone->strrdclass); if (zone->strviewname != NULL) isc_mem_free(zone->mctx, zone->strviewname); if (zone->ssutable != NULL) dns_ssutable_detach(&zone->ssutable); /* last stuff */ ZONEDB_DESTROYLOCK(&zone->dblock); DESTROYLOCK(&zone->lock); isc_refcount_destroy(&zone->erefs); zone->magic = 0; mctx = zone->mctx; isc_mem_put(mctx, zone, sizeof(*zone)); isc_mem_detach(&mctx); } /* * Returns ISC_TRUE iff this the signed side of an inline-signing zone. * Caller should hold zone lock. */ static inline isc_boolean_t inline_secure(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); if (zone->raw != NULL) return (ISC_TRUE); return (ISC_FALSE); } /* * Returns ISC_TRUE iff this the unsigned side of an inline-signing zone * Caller should hold zone lock. */ static inline isc_boolean_t inline_raw(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); if (zone->secure != NULL) return (ISC_TRUE); return (ISC_FALSE); } /* * Single shot. */ void dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) { char namebuf[1024]; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(rdclass != dns_rdataclass_none); /* * Test and set. */ LOCK_ZONE(zone); INSIST(zone != zone->raw); REQUIRE(zone->rdclass == dns_rdataclass_none || zone->rdclass == rdclass); zone->rdclass = rdclass; if (zone->strnamerd != NULL) isc_mem_free(zone->mctx, zone->strnamerd); if (zone->strrdclass != NULL) isc_mem_free(zone->mctx, zone->strrdclass); zone_namerd_tostr(zone, namebuf, sizeof namebuf); zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); zone_rdclass_tostr(zone, namebuf, sizeof namebuf); zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf); if (inline_secure(zone)) dns_zone_setclass(zone->raw, rdclass); UNLOCK_ZONE(zone); } dns_rdataclass_t dns_zone_getclass(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->rdclass); } void dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->notifytype = notifytype; UNLOCK_ZONE(zone); } isc_result_t dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) { isc_result_t result; unsigned int soacount; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(serialp != NULL); LOCK_ZONE(zone); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) { result = zone_get_from_db(zone, zone->db, NULL, &soacount, serialp, NULL, NULL, NULL, NULL, NULL); if (result == ISC_R_SUCCESS && soacount == 0) result = ISC_R_FAILURE; } else result = DNS_R_NOTLOADED; ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); UNLOCK_ZONE(zone); return (result); } isc_uint32_t dns_zone_getserial(dns_zone_t *zone) { isc_result_t result; isc_uint32_t serial; result = dns_zone_getserial2(zone, &serial); if (result != ISC_R_SUCCESS) serial = 0; /* XXX: not really correct, but no other choice */ return (serial); } /* * Single shot. */ void dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) { char namebuf[1024]; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(type != dns_zone_none); /* * Test and set. */ LOCK_ZONE(zone); REQUIRE(zone->type == dns_zone_none || zone->type == type); zone->type = type; if (zone->strnamerd != NULL) isc_mem_free(zone->mctx, zone->strnamerd); zone_namerd_tostr(zone, namebuf, sizeof namebuf); zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); UNLOCK_ZONE(zone); } static void zone_freedbargs(dns_zone_t *zone) { unsigned int i; /* Free the old database argument list. */ if (zone->db_argv != NULL) { for (i = 0; i < zone->db_argc; i++) isc_mem_free(zone->mctx, zone->db_argv[i]); isc_mem_put(zone->mctx, zone->db_argv, zone->db_argc * sizeof(*zone->db_argv)); } zone->db_argc = 0; zone->db_argv = NULL; } isc_result_t dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) { size_t size = 0; unsigned int i; isc_result_t result = ISC_R_SUCCESS; void *mem; char **tmp, *tmp2; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(argv != NULL && *argv == NULL); LOCK_ZONE(zone); size = (zone->db_argc + 1) * sizeof(char *); for (i = 0; i < zone->db_argc; i++) size += strlen(zone->db_argv[i]) + 1; mem = isc_mem_allocate(mctx, size); if (mem != NULL) { tmp = mem; tmp2 = mem; tmp2 += (zone->db_argc + 1) * sizeof(char *); for (i = 0; i < zone->db_argc; i++) { *tmp++ = tmp2; strcpy(tmp2, zone->db_argv[i]); tmp2 += strlen(tmp2) + 1; } *tmp = NULL; } else result = ISC_R_NOMEMORY; UNLOCK_ZONE(zone); *argv = mem; return (result); } isc_result_t dns_zone_setdbtype(dns_zone_t *zone, unsigned int dbargc, const char * const *dbargv) { isc_result_t result = ISC_R_SUCCESS; char **new = NULL; unsigned int i; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(dbargc >= 1); REQUIRE(dbargv != NULL); LOCK_ZONE(zone); /* Set up a new database argument list. */ new = isc_mem_get(zone->mctx, dbargc * sizeof(*new)); if (new == NULL) goto nomem; for (i = 0; i < dbargc; i++) new[i] = NULL; for (i = 0; i < dbargc; i++) { new[i] = isc_mem_strdup(zone->mctx, dbargv[i]); if (new[i] == NULL) goto nomem; } /* Free the old list. */ zone_freedbargs(zone); zone->db_argc = dbargc; zone->db_argv = new; result = ISC_R_SUCCESS; goto unlock; nomem: if (new != NULL) { for (i = 0; i < dbargc; i++) if (new[i] != NULL) isc_mem_free(zone->mctx, new[i]); isc_mem_put(zone->mctx, new, dbargc * sizeof(*new)); } result = ISC_R_NOMEMORY; unlock: UNLOCK_ZONE(zone); return (result); } void dns_zone_setview(dns_zone_t *zone, dns_view_t *view) { char namebuf[1024]; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); INSIST(zone != zone->raw); if (zone->view != NULL) dns_view_weakdetach(&zone->view); dns_view_weakattach(view, &zone->view); if (zone->strviewname != NULL) isc_mem_free(zone->mctx, zone->strviewname); if (zone->strnamerd != NULL) isc_mem_free(zone->mctx, zone->strnamerd); zone_namerd_tostr(zone, namebuf, sizeof namebuf); zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); zone_viewname_tostr(zone, namebuf, sizeof namebuf); zone->strviewname = isc_mem_strdup(zone->mctx, namebuf); if (inline_secure(zone)) dns_zone_setview(zone->raw, view); UNLOCK_ZONE(zone); } dns_view_t * dns_zone_getview(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->view); } isc_result_t dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) { isc_result_t result; char namebuf[1024]; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(origin != NULL); LOCK_ZONE(zone); INSIST(zone != zone->raw); if (dns_name_dynamic(&zone->origin)) { dns_name_free(&zone->origin, zone->mctx); dns_name_init(&zone->origin, NULL); } result = dns_name_dup(origin, zone->mctx, &zone->origin); if (zone->strnamerd != NULL) isc_mem_free(zone->mctx, zone->strnamerd); if (zone->strname != NULL) isc_mem_free(zone->mctx, zone->strname); zone_namerd_tostr(zone, namebuf, sizeof namebuf); zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); zone_name_tostr(zone, namebuf, sizeof namebuf); zone->strname = isc_mem_strdup(zone->mctx, namebuf); if (result == ISC_R_SUCCESS && inline_secure(zone)) result = dns_zone_setorigin(zone->raw, origin); UNLOCK_ZONE(zone); return (result); } void dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(acache != NULL); LOCK_ZONE(zone); if (zone->acache != NULL) dns_acache_detach(&zone->acache); dns_acache_attach(acache, &zone->acache); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) { isc_result_t result; /* * If the zone reuses an existing DB, the DB needs to be * set in the acache explicitly. We can safely ignore the * case where the DB is already set. If other error happens, * the acache will not work effectively. */ result = dns_acache_setdb(acache, zone->db); if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "dns_acache_setdb() failed: %s", isc_result_totext(result)); } } ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); UNLOCK_ZONE(zone); } static isc_result_t dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) { char *copy; if (value != NULL) { copy = isc_mem_strdup(zone->mctx, value); if (copy == NULL) return (ISC_R_NOMEMORY); } else { copy = NULL; } if (*field != NULL) isc_mem_free(zone->mctx, *field); *field = copy; return (ISC_R_SUCCESS); } isc_result_t dns_zone_setfile(dns_zone_t *zone, const char *file) { return (dns_zone_setfile2(zone, file, dns_masterformat_text)); } isc_result_t dns_zone_setfile2(dns_zone_t *zone, const char *file, dns_masterformat_t format) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); result = dns_zone_setstring(zone, &zone->masterfile, file); if (result == ISC_R_SUCCESS) { zone->masterformat = format; result = default_journal(zone); } UNLOCK_ZONE(zone); return (result); } const char * dns_zone_getfile(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->masterfile); } dns_ttl_t dns_zone_getmaxttl(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->maxttl); } void dns_zone_setmaxttl(dns_zone_t *zone, dns_ttl_t maxttl) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (maxttl != 0) zone->options2 |= DNS_ZONEOPT2_CHECKTTL; else zone->options2 &= ~DNS_ZONEOPT2_CHECKTTL; zone->maxttl = maxttl; UNLOCK_ZONE(zone); return; } static isc_result_t default_journal(dns_zone_t *zone) { isc_result_t result; char *journal; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(LOCKED_ZONE(zone)); if (zone->masterfile != NULL) { /* Calculate string length including '\0'. */ int len = strlen(zone->masterfile) + sizeof(".jnl"); journal = isc_mem_allocate(zone->mctx, len); if (journal == NULL) return (ISC_R_NOMEMORY); strcpy(journal, zone->masterfile); strcat(journal, ".jnl"); } else { journal = NULL; } result = dns_zone_setstring(zone, &zone->journal, journal); if (journal != NULL) isc_mem_free(zone->mctx, journal); return (result); } isc_result_t dns_zone_setjournal(dns_zone_t *zone, const char *journal) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); result = dns_zone_setstring(zone, &zone->journal, journal); UNLOCK_ZONE(zone); return (result); } char * dns_zone_getjournal(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->journal); } /* * Return true iff the zone is "dynamic", in the sense that the zone's * master file (if any) is written by the server, rather than being * updated manually and read by the server. * * This is true for slave zones, stub zones, key zones, and zones that * allow dynamic updates either by having an update policy ("ssutable") * or an "allow-update" ACL with a value other than exactly "{ none; }". */ isc_boolean_t dns_zone_isdynamic(dns_zone_t *zone, isc_boolean_t ignore_freeze) { REQUIRE(DNS_ZONE_VALID(zone)); if (zone->type == dns_zone_slave || zone->type == dns_zone_stub || zone->type == dns_zone_key || (zone->type == dns_zone_redirect && zone->masters != NULL)) return (ISC_TRUE); /* If !ignore_freeze, we need check whether updates are disabled. */ if (zone->type == dns_zone_master && (!zone->update_disabled || ignore_freeze) && ((zone->ssutable != NULL) || (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)))) return (ISC_TRUE); return (ISC_FALSE); } /* * Set the response policy index and information for a zone. */ isc_result_t dns_zone_rpz_enable(dns_zone_t *zone, dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num) { /* * Only RBTDB zones can be used for response policy zones, * because only they have the code to load the create the summary data. * Only zones that are loaded instead of mmap()ed create the * summary data and so can be policy zones. */ if (strcmp(zone->db_argv[0], "rbt") != 0 && strcmp(zone->db_argv[0], "rbt64") != 0) return (ISC_R_NOTIMPLEMENTED); /* * This must happen only once or be redundant. */ LOCK_ZONE(zone); if (zone->rpzs != NULL) { REQUIRE(zone->rpzs == rpzs && zone->rpz_num == rpz_num); } else { REQUIRE(zone->rpz_num == DNS_RPZ_INVALID_NUM); dns_rpz_attach_rpzs(rpzs, &zone->rpzs); zone->rpz_num = rpz_num; } rpzs->defined |= DNS_RPZ_ZBIT(rpz_num); UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); } dns_rpz_num_t dns_zone_get_rpz_num(dns_zone_t *zone) { return (zone->rpz_num); } /* * If a zone is a response policy zone, mark its new database. */ void dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) { if (zone->rpz_num != DNS_RPZ_INVALID_NUM) { REQUIRE(zone->rpzs != NULL); dns_db_rpz_attach(db, zone->rpzs, zone->rpz_num); } } static isc_boolean_t zone_touched(dns_zone_t *zone) { isc_result_t result; isc_time_t modtime; dns_include_t *include; REQUIRE(DNS_ZONE_VALID(zone)); result = isc_file_getmodtime(zone->masterfile, &modtime); if (result != ISC_R_SUCCESS || isc_time_compare(&modtime, &zone->loadtime) > 0) { zone->loadtime = modtime; return (ISC_TRUE); } for (include = ISC_LIST_HEAD(zone->includes); include != NULL; include = ISC_LIST_NEXT(include, link)) { result = isc_file_getmodtime(include->name, &modtime); if (result != ISC_R_SUCCESS || isc_time_compare(&modtime, &include->filetime) > 0) return (ISC_TRUE); } return (ISC_FALSE); } static isc_result_t zone_load(dns_zone_t *zone, unsigned int flags, isc_boolean_t locked) { isc_result_t result; isc_time_t now; isc_time_t loadtime; dns_db_t *db = NULL; isc_boolean_t rbt, hasraw; REQUIRE(DNS_ZONE_VALID(zone)); if (!locked) LOCK_ZONE(zone); INSIST(zone != zone->raw); hasraw = inline_secure(zone); if (hasraw) { result = zone_load(zone->raw, flags, ISC_FALSE); if (result != ISC_R_SUCCESS) { if (!locked) UNLOCK_ZONE(zone); return(result); } LOCK_ZONE(zone->raw); } TIME_NOW(&now); INSIST(zone->type != dns_zone_none); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) { if ((flags & DNS_ZONELOADFLAG_THAW) != 0) DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW); result = DNS_R_CONTINUE; goto cleanup; } INSIST(zone->db_argc >= 1); rbt = strcmp(zone->db_argv[0], "rbt") == 0 || strcmp(zone->db_argv[0], "rbt64") == 0; if (zone->db != NULL && zone->masterfile == NULL && rbt) { /* * The zone has no master file configured. */ result = ISC_R_SUCCESS; goto cleanup; } if (zone->db != NULL && dns_zone_isdynamic(zone, ISC_FALSE)) { /* * This is a slave, stub, or dynamically updated * zone being reloaded. Do nothing - the database * we already have is guaranteed to be up-to-date. */ if (zone->type == dns_zone_master) result = DNS_R_DYNAMIC; else result = ISC_R_SUCCESS; goto cleanup; } /* * Store the current time before the zone is loaded, so that if the * file changes between the time of the load and the time that * zone->loadtime is set, then the file will still be reloaded * the next time dns_zone_load is called. */ TIME_NOW(&loadtime); /* * Don't do the load if the file that stores the zone is older * than the last time the zone was loaded. If the zone has not * been loaded yet, zone->loadtime will be the epoch. */ if (zone->masterfile != NULL) { /* * The file is already loaded. If we are just doing a * "rndc reconfig", we are done. */ if (!isc_time_isepoch(&zone->loadtime) && (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) { result = ISC_R_SUCCESS; goto cleanup; } if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && !zone_touched(zone)) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "skipping load: master file " "older than last load"); result = DNS_R_UPTODATE; goto cleanup; } } /* * Built in zones (with the exception of empty zones) don't need * to be reloaded. */ if (zone->type == dns_zone_master && strcmp(zone->db_argv[0], "_builtin") == 0 && (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { result = ISC_R_SUCCESS; goto cleanup; } /* * Zones associated with a DLZ don't need to be loaded either, * but we need to associate the database with the zone object. */ if (strcmp(zone->db_argv[0], "dlz") == 0) { dns_dlzdb_t *dlzdb; dns_dlzfindzone_t findzone; for (dlzdb = ISC_LIST_HEAD(zone->view->dlz_unsearched); dlzdb != NULL; dlzdb = ISC_LIST_NEXT(dlzdb, link)) { INSIST(DNS_DLZ_VALID(dlzdb)); if (strcmp(zone->db_argv[1], dlzdb->dlzname) == 0) break; } if (dlzdb == NULL) { dns_zone_log(zone, ISC_LOG_ERROR, "DLZ %s does not exist or is set " "to 'search yes;'", zone->db_argv[1]); result = ISC_R_NOTFOUND; goto cleanup; } ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); /* ask SDLZ driver if the zone is supported */ findzone = dlzdb->implementation->methods->findzone; result = (*findzone)(dlzdb->implementation->driverarg, dlzdb->dbdata, dlzdb->mctx, zone->view->rdclass, &zone->origin, NULL, NULL, &db); if (result != ISC_R_NOTFOUND) { if (zone->db != NULL) zone_detachdb(zone); zone_attachdb(zone, db); dns_db_detach(&db); result = ISC_R_SUCCESS; } ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); if (result == ISC_R_SUCCESS) { if (dlzdb->configure_callback == NULL) goto cleanup; result = (*dlzdb->configure_callback)(zone->view, dlzdb, zone); if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_ERROR, "DLZ configuration callback: %s", isc_result_totext(result)); } goto cleanup; } if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub || (zone->type == dns_zone_redirect && zone->masters != NULL)) && rbt) { if (zone->masterfile == NULL || !isc_file_exists(zone->masterfile)) { if (zone->masterfile != NULL) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "no master file"); } zone->refreshtime = now; if (zone->task != NULL) zone_settimer(zone, &now); result = ISC_R_SUCCESS; goto cleanup; } } dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load"); result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin, (zone->type == dns_zone_stub) ? dns_dbtype_stub : dns_dbtype_zone, zone->rdclass, zone->db_argc - 1, zone->db_argv + 1, &db); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "loading zone: creating database: %s", isc_result_totext(result)); goto cleanup; } dns_db_settask(db, zone->task); if (! dns_db_ispersistent(db)) { if (zone->masterfile != NULL) { result = zone_startload(db, zone, loadtime); } else { result = DNS_R_NOMASTERFILE; if (zone->type == dns_zone_master || (zone->type == dns_zone_redirect && zone->masters == NULL)) { dns_zone_log(zone, ISC_LOG_ERROR, "loading zone: " "no master file configured"); goto cleanup; } dns_zone_log(zone, ISC_LOG_INFO, "loading zone: " "no master file configured: continuing"); } } if (result == DNS_R_CONTINUE) { DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING); if ((flags & DNS_ZONELOADFLAG_THAW) != 0) DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW); goto cleanup; } result = zone_postload(zone, db, loadtime, result); cleanup: if (hasraw) UNLOCK_ZONE(zone->raw); if (!locked) UNLOCK_ZONE(zone); if (db != NULL) dns_db_detach(&db); return (result); } isc_result_t dns_zone_load(dns_zone_t *zone) { return (zone_load(zone, 0, ISC_FALSE)); } isc_result_t dns_zone_loadnew(dns_zone_t *zone) { return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT, ISC_FALSE)); } static void zone_asyncload(isc_task_t *task, isc_event_t *event) { dns_asyncload_t *asl = event->ev_arg; dns_zone_t *zone = asl->zone; isc_result_t result = ISC_R_SUCCESS; isc_boolean_t load_pending; UNUSED(task); REQUIRE(DNS_ZONE_VALID(zone)); if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) result = ISC_R_CANCELED; isc_event_free(&event); if (result == ISC_R_CANCELED) goto cleanup; /* Make sure load is still pending */ LOCK_ZONE(zone); load_pending = ISC_TF(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)); if (!load_pending) { UNLOCK_ZONE(zone); goto cleanup; } zone_load(zone, 0, ISC_TRUE); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING); UNLOCK_ZONE(zone); /* Inform the zone table we've finished loading */ if (asl->loaded != NULL) (asl->loaded)(asl->loaded_arg, zone, task); cleanup: isc_mem_put(zone->mctx, asl, sizeof (*asl)); dns_zone_idetach(&zone); } isc_result_t dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg) { isc_event_t *e; dns_asyncload_t *asl = NULL; isc_result_t result = ISC_R_SUCCESS; REQUIRE(DNS_ZONE_VALID(zone)); if (zone->zmgr == NULL) return (ISC_R_FAILURE); /* If we already have a load pending, stop now */ if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) return (ISC_R_ALREADYRUNNING); asl = isc_mem_get(zone->mctx, sizeof (*asl)); if (asl == NULL) CHECK(ISC_R_NOMEMORY); asl->zone = NULL; asl->loaded = done; asl->loaded_arg = arg; e = isc_event_allocate(zone->zmgr->mctx, zone->zmgr, DNS_EVENT_ZONELOAD, zone_asyncload, asl, sizeof(isc_event_t)); if (e == NULL) CHECK(ISC_R_NOMEMORY); LOCK_ZONE(zone); zone_iattach(zone, &asl->zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING); isc_task_send(zone->loadtask, &e); UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); failure: if (asl != NULL) isc_mem_put(zone->mctx, asl, sizeof (*asl)); return (result); } isc_boolean_t dns__zone_loadpending(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (ISC_TF(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))); } isc_result_t dns_zone_loadandthaw(dns_zone_t *zone) { isc_result_t result; if (inline_raw(zone)) result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW, ISC_FALSE); else result = zone_load(zone, DNS_ZONELOADFLAG_THAW, ISC_FALSE); switch (result) { case DNS_R_CONTINUE: /* Deferred thaw. */ break; case DNS_R_UPTODATE: case ISC_R_SUCCESS: case DNS_R_SEENINCLUDE: zone->update_disabled = ISC_FALSE; break; case DNS_R_NOMASTERFILE: zone->update_disabled = ISC_FALSE; break; default: /* Error, remain in disabled state. */ break; } return (result); } static unsigned int get_master_options(dns_zone_t *zone) { unsigned int options; options = DNS_MASTER_ZONE | DNS_MASTER_RESIGN; if (zone->type == dns_zone_slave || (zone->type == dns_zone_redirect && zone->masters == NULL)) options |= DNS_MASTER_SLAVE; if (zone->type == dns_zone_key) options |= DNS_MASTER_KEY; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS)) options |= DNS_MASTER_CHECKNS; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS)) options |= DNS_MASTER_FATALNS; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) options |= DNS_MASTER_CHECKNAMES; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) options |= DNS_MASTER_CHECKNAMESFAIL; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX)) options |= DNS_MASTER_CHECKMX; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) options |= DNS_MASTER_CHECKMXFAIL; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) options |= DNS_MASTER_CHECKWILDCARD; if (DNS_ZONE_OPTION2(zone, DNS_ZONEOPT2_CHECKTTL)) options |= DNS_MASTER_CHECKTTL; return (options); } static void zone_registerinclude(const char *filename, void *arg) { isc_result_t result; dns_zone_t *zone = (dns_zone_t *) arg; dns_include_t *inc = NULL; REQUIRE(DNS_ZONE_VALID(zone)); if (filename == NULL) return; /* * Suppress duplicates. */ for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL; inc = ISC_LIST_NEXT(inc, link)) if (strcmp(filename, inc->name) == 0) return; inc = isc_mem_get(zone->mctx, sizeof(dns_include_t)); if (inc == NULL) return; inc->name = isc_mem_strdup(zone->mctx, filename); if (inc->name == NULL) { isc_mem_put(zone->mctx, inc, sizeof(dns_include_t)); return; } ISC_LINK_INIT(inc, link); result = isc_file_getmodtime(filename, &inc->filetime); if (result != ISC_R_SUCCESS) isc_time_settoepoch(&inc->filetime); ISC_LIST_APPEND(zone->newincludes, inc, link); } static void zone_gotreadhandle(isc_task_t *task, isc_event_t *event) { dns_load_t *load = event->ev_arg; isc_result_t result = ISC_R_SUCCESS; unsigned int options; REQUIRE(DNS_LOAD_VALID(load)); if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) result = ISC_R_CANCELED; isc_event_free(&event); if (result == ISC_R_CANCELED) goto fail; options = get_master_options(load->zone); result = dns_master_loadfileinc5(load->zone->masterfile, dns_db_origin(load->db), dns_db_origin(load->db), load->zone->rdclass, options, 0, &load->callbacks, task, zone_loaddone, load, &load->zone->lctx, zone_registerinclude, load->zone, load->zone->mctx, load->zone->masterformat, load->zone->maxttl); if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE && result != DNS_R_SEENINCLUDE) goto fail; return; fail: zone_loaddone(load, result); } static void get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) { isc_result_t result; unsigned int soacount; LOCK(&raw->lock); if (raw->db != NULL) { result = zone_get_from_db(raw, raw->db, NULL, &soacount, &rawdata->sourceserial, NULL, NULL, NULL, NULL, NULL); if (result == ISC_R_SUCCESS && soacount > 0U) rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET; } UNLOCK(&raw->lock); } static void zone_gotwritehandle(isc_task_t *task, isc_event_t *event) { const char me[] = "zone_gotwritehandle"; dns_zone_t *zone = event->ev_arg; isc_result_t result = ISC_R_SUCCESS; dns_dbversion_t *version = NULL; dns_masterrawheader_t rawdata; REQUIRE(DNS_ZONE_VALID(zone)); INSIST(task == zone->task); ENTER; if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) result = ISC_R_CANCELED; isc_event_free(&event); if (result == ISC_R_CANCELED) goto fail; LOCK_ZONE(zone); INSIST(zone != zone->raw); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) { const dns_master_style_t *output_style; dns_db_currentversion(zone->db, &version); dns_master_initrawheader(&rawdata); if (inline_secure(zone)) get_raw_serial(zone->raw, &rawdata); if (zone->type == dns_zone_key) output_style = &dns_master_style_keyzone; else output_style = &dns_master_style_default; result = dns_master_dumpinc3(zone->mctx, zone->db, version, output_style, zone->masterfile, zone->task, dump_done, zone, &zone->dctx, zone->masterformat, &rawdata); dns_db_closeversion(zone->db, &version, ISC_FALSE); } else result = ISC_R_CANCELED; ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); UNLOCK_ZONE(zone); if (result != DNS_R_CONTINUE) goto fail; return; fail: dump_done(zone, result); } /* * Save the raw serial number for inline-signing zones. * (XXX: Other information from the header will be used * for other purposes in the future, but for now this is * all we're interested in.) */ static void zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) { if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0) return; zone->sourceserial = header->sourceserial; zone->sourceserialset = ISC_TRUE; } void dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) { if (zone == NULL) return; LOCK_ZONE(zone); zone_setrawdata(zone, header); UNLOCK_ZONE(zone); } static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { dns_load_t *load; isc_result_t result; isc_result_t tresult; unsigned int options; dns_zone_rpz_enable_db(zone, db); options = get_master_options(zone); if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) options |= DNS_MASTER_MANYERRORS; if (zone->zmgr != NULL && zone->db != NULL && zone->loadtask != NULL) { load = isc_mem_get(zone->mctx, sizeof(*load)); if (load == NULL) return (ISC_R_NOMEMORY); load->mctx = NULL; load->zone = NULL; load->db = NULL; load->loadtime = loadtime; load->magic = LOAD_MAGIC; isc_mem_attach(zone->mctx, &load->mctx); zone_iattach(zone, &load->zone); dns_db_attach(db, &load->db); dns_rdatacallbacks_init(&load->callbacks); load->callbacks.rawdata = zone_setrawdata; zone_iattach(zone, &load->callbacks.zone); result = dns_db_beginload(db, &load->callbacks); if (result != ISC_R_SUCCESS) goto cleanup; result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->loadtask, zone_gotreadhandle, load, &zone->readio); if (result != ISC_R_SUCCESS) { /* * We can't report multiple errors so ignore * the result of dns_db_endload(). */ (void)dns_db_endload(load->db, &load->callbacks); goto cleanup; } else result = DNS_R_CONTINUE; } else { dns_rdatacallbacks_t callbacks; dns_rdatacallbacks_init(&callbacks); callbacks.rawdata = zone_setrawdata; zone_iattach(zone, &callbacks.zone); result = dns_db_beginload(db, &callbacks); if (result != ISC_R_SUCCESS) { zone_idetach(&callbacks.zone); return (result); } result = dns_master_loadfile5(zone->masterfile, &zone->origin, &zone->origin, zone->rdclass, options, 0, &callbacks, zone_registerinclude, zone, zone->mctx, zone->masterformat, zone->maxttl); tresult = dns_db_endload(db, &callbacks); if (result == ISC_R_SUCCESS) result = tresult; zone_idetach(&callbacks.zone); } return (result); cleanup: load->magic = 0; dns_db_detach(&load->db); zone_idetach(&load->zone); zone_idetach(&load->callbacks.zone); isc_mem_detach(&load->mctx); isc_mem_put(zone->mctx, load, sizeof(*load)); return (result); } static isc_boolean_t zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, dns_name_t *owner) { isc_result_t result; char ownerbuf[DNS_NAME_FORMATSIZE]; char namebuf[DNS_NAME_FORMATSIZE]; char altbuf[DNS_NAME_FORMATSIZE]; dns_fixedname_t fixed; dns_name_t *foundname; int level; /* * "." means the services does not exist. */ if (dns_name_equal(name, dns_rootname)) return (ISC_TRUE); /* * Outside of zone. */ if (!dns_name_issubdomain(name, &zone->origin)) { if (zone->checkmx != NULL) return ((zone->checkmx)(zone, name, owner)); return (ISC_TRUE); } if (zone->type == dns_zone_master) level = ISC_LOG_ERROR; else level = ISC_LOG_WARNING; dns_fixedname_init(&fixed); foundname = dns_fixedname_name(&fixed); result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL, foundname, NULL, NULL); if (result == ISC_R_SUCCESS) return (ISC_TRUE); if (result == DNS_R_NXRRSET) { result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 0, 0, NULL, foundname, NULL, NULL); if (result == ISC_R_SUCCESS) return (ISC_TRUE); } dns_name_format(owner, ownerbuf, sizeof ownerbuf); dns_name_format(name, namebuf, sizeof namebuf); if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || result == DNS_R_EMPTYNAME) { if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) level = ISC_LOG_WARNING; dns_zone_log(zone, level, "%s/MX '%s' has no address records (A or AAAA)", ownerbuf, namebuf); return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); } if (result == DNS_R_CNAME) { if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) level = ISC_LOG_WARNING; if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) dns_zone_log(zone, level, "%s/MX '%s' is a CNAME (illegal)", ownerbuf, namebuf); return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); } if (result == DNS_R_DNAME) { if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) level = ISC_LOG_WARNING; if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) { dns_name_format(foundname, altbuf, sizeof altbuf); dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME" " '%s' (illegal)", ownerbuf, namebuf, altbuf); } return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); } if (zone->checkmx != NULL && result == DNS_R_DELEGATION) return ((zone->checkmx)(zone, name, owner)); return (ISC_TRUE); } static isc_boolean_t zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, dns_name_t *owner) { isc_result_t result; char ownerbuf[DNS_NAME_FORMATSIZE]; char namebuf[DNS_NAME_FORMATSIZE]; char altbuf[DNS_NAME_FORMATSIZE]; dns_fixedname_t fixed; dns_name_t *foundname; int level; /* * "." means the services does not exist. */ if (dns_name_equal(name, dns_rootname)) return (ISC_TRUE); /* * Outside of zone. */ if (!dns_name_issubdomain(name, &zone->origin)) { if (zone->checksrv != NULL) return ((zone->checksrv)(zone, name, owner)); return (ISC_TRUE); } if (zone->type == dns_zone_master) level = ISC_LOG_ERROR; else level = ISC_LOG_WARNING; dns_fixedname_init(&fixed); foundname = dns_fixedname_name(&fixed); result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL, foundname, NULL, NULL); if (result == ISC_R_SUCCESS) return (ISC_TRUE); if (result == DNS_R_NXRRSET) { result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 0, 0, NULL, foundname, NULL, NULL); if (result == ISC_R_SUCCESS) return (ISC_TRUE); } dns_name_format(owner, ownerbuf, sizeof ownerbuf); dns_name_format(name, namebuf, sizeof namebuf); if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || result == DNS_R_EMPTYNAME) { dns_zone_log(zone, level, "%s/SRV '%s' has no address records (A or AAAA)", ownerbuf, namebuf); /* XXX950 make fatal for 9.5.0. */ return (ISC_TRUE); } if (result == DNS_R_CNAME) { if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) level = ISC_LOG_WARNING; if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) dns_zone_log(zone, level, "%s/SRV '%s' is a CNAME (illegal)", ownerbuf, namebuf); return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); } if (result == DNS_R_DNAME) { if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) level = ISC_LOG_WARNING; if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) { dns_name_format(foundname, altbuf, sizeof altbuf); dns_zone_log(zone, level, "%s/SRV '%s' is below a " "DNAME '%s' (illegal)", ownerbuf, namebuf, altbuf); } return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); } if (zone->checksrv != NULL && result == DNS_R_DELEGATION) return ((zone->checksrv)(zone, name, owner)); return (ISC_TRUE); } static isc_boolean_t zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, dns_name_t *owner) { isc_boolean_t answer = ISC_TRUE; isc_result_t result, tresult; char ownerbuf[DNS_NAME_FORMATSIZE]; char namebuf[DNS_NAME_FORMATSIZE]; char altbuf[DNS_NAME_FORMATSIZE]; dns_fixedname_t fixed; dns_name_t *foundname; dns_rdataset_t a; dns_rdataset_t aaaa; int level; /* * Outside of zone. */ if (!dns_name_issubdomain(name, &zone->origin)) { if (zone->checkns != NULL) return ((zone->checkns)(zone, name, owner, NULL, NULL)); return (ISC_TRUE); } if (zone->type == dns_zone_master) level = ISC_LOG_ERROR; else level = ISC_LOG_WARNING; dns_fixedname_init(&fixed); foundname = dns_fixedname_name(&fixed); dns_rdataset_init(&a); dns_rdataset_init(&aaaa); result = dns_db_find(db, name, NULL, dns_rdatatype_a, DNS_DBFIND_GLUEOK, 0, NULL, foundname, &a, NULL); if (result == ISC_R_SUCCESS) { dns_rdataset_disassociate(&a); return (ISC_TRUE); } else if (result == DNS_R_DELEGATION) dns_rdataset_disassociate(&a); if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION || result == DNS_R_GLUE) { tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, DNS_DBFIND_GLUEOK, 0, NULL, foundname, &aaaa, NULL); if (tresult == ISC_R_SUCCESS) { if (dns_rdataset_isassociated(&a)) dns_rdataset_disassociate(&a); dns_rdataset_disassociate(&aaaa); return (ISC_TRUE); } if (tresult == DNS_R_DELEGATION) dns_rdataset_disassociate(&aaaa); if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) { /* * Check glue against child zone. */ if (zone->checkns != NULL) answer = (zone->checkns)(zone, name, owner, &a, &aaaa); if (dns_rdataset_isassociated(&a)) dns_rdataset_disassociate(&a); if (dns_rdataset_isassociated(&aaaa)) dns_rdataset_disassociate(&aaaa); return (answer); } } dns_name_format(owner, ownerbuf, sizeof ownerbuf); dns_name_format(name, namebuf, sizeof namebuf); if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) { const char *what; isc_boolean_t required = ISC_FALSE; if (dns_name_issubdomain(name, owner)) { what = "REQUIRED GLUE "; required = ISC_TRUE; } else if (result == DNS_R_DELEGATION) what = "SIBLING GLUE "; else what = ""; if (result != DNS_R_DELEGATION || required || DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) { dns_zone_log(zone, level, "%s/NS '%s' has no %s" "address records (A or AAAA)", ownerbuf, namebuf, what); /* * Log missing address record. */ if (result == DNS_R_DELEGATION && zone->checkns != NULL) (void)(zone->checkns)(zone, name, owner, &a, &aaaa); /* XXX950 make fatal for 9.5.0. */ /* answer = ISC_FALSE; */ } } else if (result == DNS_R_CNAME) { dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)", ownerbuf, namebuf); /* XXX950 make fatal for 9.5.0. */ /* answer = ISC_FALSE; */ } else if (result == DNS_R_DNAME) { dns_name_format(foundname, altbuf, sizeof altbuf); dns_zone_log(zone, level, "%s/NS '%s' is below a DNAME '%s' (illegal)", ownerbuf, namebuf, altbuf); /* XXX950 make fatal for 9.5.0. */ /* answer = ISC_FALSE; */ } if (dns_rdataset_isassociated(&a)) dns_rdataset_disassociate(&a); if (dns_rdataset_isassociated(&aaaa)) dns_rdataset_disassociate(&aaaa); return (answer); } static isc_boolean_t zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner, dns_rdataset_t *rdataset) { dns_rdataset_t tmprdataset; isc_result_t result; isc_boolean_t answer = ISC_TRUE; isc_boolean_t format = ISC_TRUE; int level = ISC_LOG_WARNING; char ownerbuf[DNS_NAME_FORMATSIZE]; char typebuf[DNS_RDATATYPE_FORMATSIZE]; unsigned int count1 = 0; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL)) level = ISC_LOG_ERROR; dns_rdataset_init(&tmprdataset); for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdata_t rdata1 = DNS_RDATA_INIT; unsigned int count2 = 0; count1++; dns_rdataset_current(rdataset, &rdata1); dns_rdataset_clone(rdataset, &tmprdataset); for (result = dns_rdataset_first(&tmprdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&tmprdataset)) { dns_rdata_t rdata2 = DNS_RDATA_INIT; count2++; if (count1 >= count2) continue; dns_rdataset_current(&tmprdataset, &rdata2); if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) { if (format) { dns_name_format(owner, ownerbuf, sizeof ownerbuf); dns_rdatatype_format(rdata1.type, typebuf, sizeof(typebuf)); format = ISC_FALSE; } dns_zone_log(zone, level, "%s/%s has " "semantically identical records", ownerbuf, typebuf); if (level == ISC_LOG_ERROR) answer = ISC_FALSE; break; } } dns_rdataset_disassociate(&tmprdataset); if (!format) break; } return (answer); } static isc_boolean_t zone_check_dup(dns_zone_t *zone, dns_db_t *db) { dns_dbiterator_t *dbiterator = NULL; dns_dbnode_t *node = NULL; dns_fixedname_t fixed; dns_name_t *name; dns_rdataset_t rdataset; dns_rdatasetiter_t *rdsit = NULL; isc_boolean_t ok = ISC_TRUE; isc_result_t result; dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); dns_rdataset_init(&rdataset); result = dns_db_createiterator(db, 0, &dbiterator); if (result != ISC_R_SUCCESS) return (ISC_TRUE); for (result = dns_dbiterator_first(dbiterator); result == ISC_R_SUCCESS; result = dns_dbiterator_next(dbiterator)) { result = dns_dbiterator_current(dbiterator, &node, name); if (result != ISC_R_SUCCESS) continue; result = dns_db_allrdatasets(db, node, NULL, 0, &rdsit); if (result != ISC_R_SUCCESS) continue; for (result = dns_rdatasetiter_first(rdsit); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsit)) { dns_rdatasetiter_current(rdsit, &rdataset); if (!zone_rrset_check_dup(zone, name, &rdataset)) ok = ISC_FALSE; dns_rdataset_disassociate(&rdataset); } dns_rdatasetiter_destroy(&rdsit); dns_db_detachnode(db, &node); } if (node != NULL) dns_db_detachnode(db, &node); dns_dbiterator_destroy(&dbiterator); return (ok); } static isc_boolean_t isspf(const dns_rdata_t *rdata) { char buf[1024]; const unsigned char *data = rdata->data; unsigned int rdl = rdata->length, i = 0, tl, len; while (rdl > 0U) { len = tl = *data; ++data; --rdl; INSIST(tl <= rdl); if (len > sizeof(buf) - i - 1) len = sizeof(buf) - i - 1; memmove(buf + i, data, len); i += len; data += tl; rdl -= tl; } if (i < 6U) return(ISC_FALSE); buf[i] = 0; if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' ')) return (ISC_TRUE); return (ISC_FALSE); } static isc_boolean_t integrity_checks(dns_zone_t *zone, dns_db_t *db) { dns_dbiterator_t *dbiterator = NULL; dns_dbnode_t *node = NULL; dns_rdataset_t rdataset; dns_fixedname_t fixed; dns_fixedname_t fixedbottom; dns_rdata_mx_t mx; dns_rdata_ns_t ns; dns_rdata_in_srv_t srv; dns_rdata_t rdata; dns_name_t *name; dns_name_t *bottom; isc_result_t result; isc_boolean_t ok = ISC_TRUE, have_spf, have_txt; dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); dns_fixedname_init(&fixedbottom); bottom = dns_fixedname_name(&fixedbottom); dns_rdataset_init(&rdataset); dns_rdata_init(&rdata); result = dns_db_createiterator(db, 0, &dbiterator); if (result != ISC_R_SUCCESS) return (ISC_TRUE); result = dns_dbiterator_first(dbiterator); while (result == ISC_R_SUCCESS) { result = dns_dbiterator_current(dbiterator, &node, name); if (result != ISC_R_SUCCESS) goto cleanup; /* * Is this name visible in the zone? */ if (!dns_name_issubdomain(name, &zone->origin) || (dns_name_countlabels(bottom) > 0 && dns_name_issubdomain(name, bottom))) goto next; /* * Don't check the NS records at the origin. */ if (dns_name_equal(name, &zone->origin)) goto checkmx; result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns, 0, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) goto checkmx; /* * Remember bottom of zone. */ dns_name_copy(name, bottom, NULL); result = dns_rdataset_first(&rdataset); while (result == ISC_R_SUCCESS) { dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &ns, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (!zone_check_glue(zone, db, &ns.name, name)) ok = ISC_FALSE; dns_rdata_reset(&rdata); result = dns_rdataset_next(&rdataset); } dns_rdataset_disassociate(&rdataset); goto next; checkmx: result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx, 0, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) goto checksrv; result = dns_rdataset_first(&rdataset); while (result == ISC_R_SUCCESS) { dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &mx, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (!zone_check_mx(zone, db, &mx.mx, name)) ok = ISC_FALSE; dns_rdata_reset(&rdata); result = dns_rdataset_next(&rdataset); } dns_rdataset_disassociate(&rdataset); checksrv: if (zone->rdclass != dns_rdataclass_in) goto next; result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv, 0, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) goto checkspf; result = dns_rdataset_first(&rdataset); while (result == ISC_R_SUCCESS) { dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &srv, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (!zone_check_srv(zone, db, &srv.target, name)) ok = ISC_FALSE; dns_rdata_reset(&rdata); result = dns_rdataset_next(&rdataset); } dns_rdataset_disassociate(&rdataset); checkspf: /* * Check if there is a type SPF record without an * SPF-formatted type TXT record also being present. */ if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF)) goto next; if (zone->rdclass != dns_rdataclass_in) goto next; have_spf = have_txt = ISC_FALSE; result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf, 0, 0, &rdataset, NULL); if (result == ISC_R_SUCCESS) { dns_rdataset_disassociate(&rdataset); have_spf = ISC_TRUE; } result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt, 0, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) goto notxt; result = dns_rdataset_first(&rdataset); while (result == ISC_R_SUCCESS) { dns_rdataset_current(&rdataset, &rdata); have_txt = isspf(&rdata); dns_rdata_reset(&rdata); if (have_txt) break; result = dns_rdataset_next(&rdataset); } dns_rdataset_disassociate(&rdataset); notxt: if (have_spf && !have_txt) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(name, namebuf, sizeof(namebuf)); dns_zone_log(zone, ISC_LOG_WARNING, "'%s' found type " "SPF record but no SPF TXT record found, " "add matching type TXT record", namebuf); } next: dns_db_detachnode(db, &node); result = dns_dbiterator_next(dbiterator); } cleanup: if (node != NULL) dns_db_detachnode(db, &node); dns_dbiterator_destroy(&dbiterator); return (ok); } /* * OpenSSL verification of RSA keys with exponent 3 is known to be * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn * if they are in use. */ static void zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) { dns_dbnode_t *node = NULL; dns_dbversion_t *version = NULL; dns_rdata_dnskey_t dnskey; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_t rdataset; isc_result_t result; isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE; const char *algorithm; result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) goto cleanup; dns_db_currentversion(db, &version); dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, dns_rdatatype_none, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) goto cleanup; for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &dnskey, NULL); INSIST(result == ISC_R_SUCCESS); if ((dnskey.algorithm == DST_ALG_RSASHA1 || dnskey.algorithm == DST_ALG_RSAMD5) && dnskey.datalen > 1 && dnskey.data[0] == 1 && dnskey.data[1] == 3) { if (dnskey.algorithm == DST_ALG_RSASHA1) { logit = !foundrsa; foundrsa = ISC_TRUE; algorithm = "RSASHA1"; } else { logit = !foundmd5; foundmd5 = ISC_TRUE; algorithm = "RSAMD5"; } if (logit) dns_zone_log(zone, ISC_LOG_WARNING, "weak %s (%u) key found " "(exponent=3)", algorithm, dnskey.algorithm); if (foundrsa && foundmd5) break; } dns_rdata_reset(&rdata); } dns_rdataset_disassociate(&rdataset); cleanup: if (node != NULL) dns_db_detachnode(db, &node); if (version != NULL) dns_db_closeversion(db, &version, ISC_FALSE); } static void resume_signingwithkey(dns_zone_t *zone) { dns_dbnode_t *node = NULL; dns_dbversion_t *version = NULL; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_t rdataset; isc_result_t result; dns_db_t *db = NULL; ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) dns_db_attach(zone->db, &db); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); if (db == NULL) goto cleanup; result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) goto cleanup; dns_db_currentversion(db, &version); dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, version, zone->privatetype, dns_rdatatype_none, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) { INSIST(!dns_rdataset_isassociated(&rdataset)); goto cleanup; } for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdataset_current(&rdataset, &rdata); if (rdata.length != 5 || rdata.data[0] == 0 || rdata.data[4] != 0) { dns_rdata_reset(&rdata); continue; } result = zone_signwithkey(zone, rdata.data[0], (rdata.data[1] << 8) | rdata.data[2], ISC_TF(rdata.data[3])); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_signwithkey failed: %s", dns_result_totext(result)); } dns_rdata_reset(&rdata); } dns_rdataset_disassociate(&rdataset); cleanup: if (db != NULL) { if (node != NULL) dns_db_detachnode(db, &node); if (version != NULL) dns_db_closeversion(db, &version, ISC_FALSE); dns_db_detach(&db); } } static isc_result_t zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { dns_nsec3chain_t *nsec3chain, *current; dns_dbversion_t *version = NULL; isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE; isc_result_t result; isc_time_t now; unsigned int options = 0; char saltbuf[255*2+1]; char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")]; dns_db_t *db = NULL; int i; ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) dns_db_attach(zone->db, &db); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); if (db == NULL) { result = ISC_R_SUCCESS; goto cleanup; } dns_db_currentversion(db, &version); result = dns_nsec_nseconly(db, version, &nseconly); nsec3ok = (result == ISC_R_SUCCESS && !nseconly); dns_db_closeversion(db, &version, ISC_FALSE); if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) { result = ISC_R_SUCCESS; goto cleanup; } nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain); if (nsec3chain == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } nsec3chain->magic = 0; nsec3chain->done = ISC_FALSE; nsec3chain->db = NULL; nsec3chain->dbiterator = NULL; nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass; nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype; nsec3chain->nsec3param.hash = nsec3param->hash; nsec3chain->nsec3param.iterations = nsec3param->iterations; nsec3chain->nsec3param.flags = nsec3param->flags; nsec3chain->nsec3param.salt_length = nsec3param->salt_length; memmove(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length); nsec3chain->nsec3param.salt = nsec3chain->salt; nsec3chain->seen_nsec = ISC_FALSE; nsec3chain->delete_nsec = ISC_FALSE; nsec3chain->save_delete_nsec = ISC_FALSE; if (nsec3param->flags == 0) strlcpy(flags, "NONE", sizeof(flags)); else { flags[0] = '\0'; if (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) strlcat(flags, "REMOVE", sizeof(flags)); if (nsec3param->flags & DNS_NSEC3FLAG_INITIAL) { if (flags[0] == '\0') strlcpy(flags, "INITIAL", sizeof(flags)); else strlcat(flags, "|INITIAL", sizeof(flags)); } if (nsec3param->flags & DNS_NSEC3FLAG_CREATE) { if (flags[0] == '\0') strlcpy(flags, "CREATE", sizeof(flags)); else strlcat(flags, "|CREATE", sizeof(flags)); } if (nsec3param->flags & DNS_NSEC3FLAG_NONSEC) { if (flags[0] == '\0') strlcpy(flags, "NONSEC", sizeof(flags)); else strlcat(flags, "|NONSEC", sizeof(flags)); } if (nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) { if (flags[0] == '\0') strlcpy(flags, "OPTOUT", sizeof(flags)); else strlcat(flags, "|OPTOUT", sizeof(flags)); } } if (nsec3param->salt_length == 0) strlcpy(saltbuf, "-", sizeof(saltbuf)); else for (i = 0; i < nsec3param->salt_length; i++) sprintf(&saltbuf[i*2], "%02X", nsec3chain->salt[i]); dns_zone_log(zone, ISC_LOG_INFO, "zone_addnsec3chain(%u,%s,%u,%s)", nsec3param->hash, flags, nsec3param->iterations, saltbuf); for (current = ISC_LIST_HEAD(zone->nsec3chain); current != NULL; current = ISC_LIST_NEXT(current, link)) { if (current->db == db && current->nsec3param.hash == nsec3param->hash && current->nsec3param.iterations == nsec3param->iterations && current->nsec3param.salt_length == nsec3param->salt_length && !memcmp(current->nsec3param.salt, nsec3param->salt, nsec3param->salt_length)) current->done = ISC_TRUE; } dns_db_attach(db, &nsec3chain->db); if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0) options = DNS_DB_NONSEC3; result = dns_db_createiterator(nsec3chain->db, options, &nsec3chain->dbiterator); if (result == ISC_R_SUCCESS) dns_dbiterator_first(nsec3chain->dbiterator); if (result == ISC_R_SUCCESS) { dns_dbiterator_pause(nsec3chain->dbiterator); ISC_LIST_INITANDAPPEND(zone->nsec3chain, nsec3chain, link); nsec3chain = NULL; if (isc_time_isepoch(&zone->nsec3chaintime)) { TIME_NOW(&now); zone->nsec3chaintime = now; if (zone->task != NULL) zone_settimer(zone, &now); } } if (nsec3chain != NULL) { if (nsec3chain->db != NULL) dns_db_detach(&nsec3chain->db); if (nsec3chain->dbiterator != NULL) dns_dbiterator_destroy(&nsec3chain->dbiterator); isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); } cleanup: if (db != NULL) dns_db_detach(&db); return (result); } static void resume_addnsec3chain(dns_zone_t *zone) { dns_dbnode_t *node = NULL; dns_dbversion_t *version = NULL; dns_rdataset_t rdataset; isc_result_t result; dns_rdata_nsec3param_t nsec3param; isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE; dns_db_t *db = NULL; if (zone->privatetype == 0) return; ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) dns_db_attach(zone->db, &db); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); if (db == NULL) goto cleanup; result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) goto cleanup; dns_db_currentversion(db, &version); result = dns_nsec_nseconly(db, version, &nseconly); nsec3ok = (result == ISC_R_SUCCESS && !nseconly); dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, version, zone->privatetype, dns_rdatatype_none, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) { INSIST(!dns_rdataset_isassociated(&rdataset)); goto cleanup; } for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_t private = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &private); if (!dns_nsec3param_fromprivate(&private, &rdata, buf, sizeof(buf))) continue; result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) || ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok)) { result = zone_addnsec3chain(zone, &nsec3param); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_addnsec3chain failed: %s", dns_result_totext(result)); } } } dns_rdataset_disassociate(&rdataset); cleanup: if (db != NULL) { if (node != NULL) dns_db_detachnode(db, &node); if (version != NULL) dns_db_closeversion(db, &version, ISC_FALSE); dns_db_detach(&db); } } static void set_resigntime(dns_zone_t *zone) { dns_rdataset_t rdataset; dns_fixedname_t fixed; unsigned int resign; isc_result_t result; isc_uint32_t nanosecs; dns_db_t *db = NULL; /* We only re-sign zones that can be dynamically updated */ if (zone->update_disabled) return; if (!inline_secure(zone) && (zone->type != dns_zone_master || (zone->ssutable == NULL && (zone->update_acl == NULL || dns_acl_isnone(zone->update_acl))))) return; dns_rdataset_init(&rdataset); dns_fixedname_init(&fixed); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) dns_db_attach(zone->db, &db); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); if (db == NULL) { isc_time_settoepoch(&zone->resigntime); return; } result = dns_db_getsigningtime(db, &rdataset, dns_fixedname_name(&fixed)); if (result != ISC_R_SUCCESS) { isc_time_settoepoch(&zone->resigntime); goto cleanup; } resign = rdataset.resign - zone->sigresigninginterval; dns_rdataset_disassociate(&rdataset); isc_random_get(&nanosecs); nanosecs %= 1000000000; isc_time_set(&zone->resigntime, resign, nanosecs); cleanup: dns_db_detach(&db); return; } static isc_result_t check_nsec3param(dns_zone_t *zone, dns_db_t *db) { dns_dbnode_t *node = NULL; dns_rdataset_t rdataset; dns_dbversion_t *version = NULL; dns_rdata_nsec3param_t nsec3param; isc_boolean_t ok = ISC_FALSE; isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; isc_boolean_t dynamic = (zone->type == dns_zone_master) ? dns_zone_isdynamic(zone, ISC_FALSE) : ISC_FALSE; dns_rdataset_init(&rdataset); result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "nsec3param lookup failure: %s", dns_result_totext(result)); return (result); } dns_db_currentversion(db, &version); result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3param, dns_rdatatype_none, 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) { INSIST(!dns_rdataset_isassociated(&rdataset)); result = ISC_R_SUCCESS; goto cleanup; } if (result != ISC_R_SUCCESS) { INSIST(!dns_rdataset_isassociated(&rdataset)); dns_zone_log(zone, ISC_LOG_ERROR, "nsec3param lookup failure: %s", dns_result_totext(result)); goto cleanup; } /* * For dynamic zones we must support every algorithm so we can * regenerate all the NSEC3 chains. * For non-dynamic zones we only need to find a supported algorithm. */ for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); dns_rdata_reset(&rdata); INSIST(result == ISC_R_SUCCESS); if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) && nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic) { dns_zone_log(zone, ISC_LOG_WARNING, "nsec3 test \"unknown\" hash algorithm found: %u", nsec3param.hash); ok = ISC_TRUE; } else if (!dns_nsec3_supportedhash(nsec3param.hash)) { if (dynamic) { dns_zone_log(zone, ISC_LOG_ERROR, "unsupported nsec3 hash algorithm" " in dynamic zone: %u", nsec3param.hash); result = DNS_R_BADZONE; /* Stop second error message. */ ok = ISC_TRUE; break; } else dns_zone_log(zone, ISC_LOG_WARNING, "unsupported nsec3 hash algorithm: %u", nsec3param.hash); } else ok = ISC_TRUE; } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; if (!ok) { result = DNS_R_BADZONE; dns_zone_log(zone, ISC_LOG_ERROR, "no supported nsec3 hash algorithm"); } cleanup: if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); dns_db_closeversion(db, &version, ISC_FALSE); dns_db_detachnode(db, &node); return (result); } /* * Set the timer for refreshing the key zone to the soonest future time * of the set (current timer, keydata->refresh, keydata->addhd, * keydata->removehd). */ static void set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key, isc_stdtime_t now, isc_boolean_t force) { const char me[] = "set_refreshkeytimer"; isc_stdtime_t then; isc_time_t timenow, timethen; char timebuf[80]; ENTER; then = key->refresh; if (force) then = now; if (key->addhd > now && key->addhd < then) then = key->addhd; if (key->removehd > now && key->removehd < then) then = key->removehd; TIME_NOW(&timenow); if (then > now) DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen); else timethen = timenow; if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 || isc_time_compare(&timethen, &zone->refreshkeytime) < 0) zone->refreshkeytime = timethen; isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf); zone_settimer(zone, &timenow); } /* * Convert key(s) linked from 'keynode' to KEYDATA and add to the key zone. * If the key zone is changed, set '*changed' to ISC_TRUE. */ static isc_result_t create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, dns_keytable_t *keytable, dns_keynode_t **keynodep, isc_boolean_t *changed) { const char me[] = "create_keydata"; isc_result_t result = ISC_R_SUCCESS; isc_buffer_t keyb, dstb; unsigned char key_buf[4096], dst_buf[DST_KEY_MAXSIZE]; dns_rdata_keydata_t keydata; dns_rdata_dnskey_t dnskey; dns_rdata_t rdata = DNS_RDATA_INIT; dns_keynode_t *keynode; isc_stdtime_t now; isc_region_t r; dst_key_t *key; REQUIRE(keynodep != NULL); keynode = *keynodep; ENTER; isc_stdtime_get(&now); /* Loop in case there's more than one key. */ while (result == ISC_R_SUCCESS) { dns_keynode_t *nextnode = NULL; key = dns_keynode_key(keynode); if (key == NULL) goto skip; isc_buffer_init(&dstb, dst_buf, sizeof(dst_buf)); CHECK(dst_key_todns(key, &dstb)); /* Convert DST key to DNSKEY. */ dns_rdata_reset(&rdata); isc_buffer_usedregion(&dstb, &r); dns_rdata_fromregion(&rdata, dst_key_class(key), dns_rdatatype_dnskey, &r); /* DSTKEY to KEYDATA. */ CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL)); CHECK(dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0, NULL)); /* KEYDATA to rdata. */ dns_rdata_reset(&rdata); isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); CHECK(dns_rdata_fromstruct(&rdata, zone->rdclass, dns_rdatatype_keydata, &keydata, &keyb)); /* Add rdata to zone. */ CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, dst_key_name(key), 0, &rdata)); *changed = ISC_TRUE; /* Refresh new keys from the zone apex as soon as possible. */ set_refreshkeytimer(zone, &keydata, now, ISC_TRUE); skip: result = dns_keytable_nextkeynode(keytable, keynode, &nextnode); if (result != ISC_R_NOTFOUND) { dns_keytable_detachkeynode(keytable, &keynode); keynode = nextnode; } } if (keynode != NULL) dns_keytable_detachkeynode(keytable, &keynode); *keynodep = NULL; return (ISC_R_SUCCESS); failure: return (result); } /* * Remove from the key zone all the KEYDATA records found in rdataset. */ static isc_result_t delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, dns_name_t *name, dns_rdataset_t *rdataset) { dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result, uresult; for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdata_reset(&rdata); dns_rdataset_current(rdataset, &rdata); uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 0, &rdata); if (uresult != ISC_R_SUCCESS) return (uresult); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; return (result); } /* * Compute the DNSSEC key ID for a DNSKEY record. */ static isc_result_t compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx, dns_keytag_t *tag) { isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; unsigned char data[4096]; isc_buffer_t buffer; dst_key_t *dstkey = NULL; isc_buffer_init(&buffer, data, sizeof(data)); dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, dns_rdatatype_dnskey, dnskey, &buffer); result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey); if (result == ISC_R_SUCCESS) *tag = dst_key_id(dstkey); dst_key_free(&dstkey); return (result); } /* * Add key to the security roots. */ static void trust_key(dns_zone_t *zone, dns_name_t *keyname, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) { isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; unsigned char data[4096]; isc_buffer_t buffer; dns_keytable_t *sr = NULL; dst_key_t *dstkey = NULL; /* Convert dnskey to DST key. */ isc_buffer_init(&buffer, data, sizeof(data)); dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, dns_rdatatype_dnskey, dnskey, &buffer); result = dns_view_getsecroots(zone->view, &sr); if (result != ISC_R_SUCCESS) goto failure; CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey)); CHECK(dns_keytable_add(sr, ISC_TRUE, &dstkey)); dns_keytable_detach(&sr); failure: if (dstkey != NULL) dst_key_free(&dstkey); if (sr != NULL) dns_keytable_detach(&sr); return; } /* * Add a null key to the security roots for so that all queries * to the zone will fail. */ static void fail_secure(dns_zone_t *zone, dns_name_t *keyname) { isc_result_t result; dns_keytable_t *sr = NULL; result = dns_view_getsecroots(zone->view, &sr); if (result == ISC_R_SUCCESS) { dns_keytable_marksecure(sr, keyname); dns_keytable_detach(&sr); } } /* * Scan a set of KEYDATA records from the key zone. The ones that are * valid (i.e., the add holddown timer has expired) become trusted keys. */ static void load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) { isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_keydata_t keydata; dns_rdata_dnskey_t dnskey; isc_mem_t *mctx = zone->mctx; int trusted = 0, revoked = 0, pending = 0; isc_stdtime_t now; dns_keytable_t *sr = NULL; isc_stdtime_get(&now); result = dns_view_getsecroots(zone->view, &sr); if (result == ISC_R_SUCCESS) { dns_keytable_delete(sr, name); dns_keytable_detach(&sr); } /* Now insert all the accepted trust anchors from this keydata set. */ for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdata_reset(&rdata); dns_rdataset_current(rdataset, &rdata); /* Convert rdata to keydata. */ result = dns_rdata_tostruct(&rdata, &keydata, NULL); if (result == ISC_R_UNEXPECTEDEND) continue; RUNTIME_CHECK(result == ISC_R_SUCCESS); /* Set the key refresh timer to force a fast refresh. */ set_refreshkeytimer(zone, &keydata, now, ISC_TRUE); /* If the removal timer is nonzero, this key was revoked. */ if (keydata.removehd != 0) { revoked++; continue; } /* * If the add timer is still pending, this key is not * trusted yet. */ if (now < keydata.addhd) { pending++; continue; } /* Convert keydata to dnskey. */ dns_keydata_todnskey(&keydata, &dnskey, NULL); /* Add to keytables. */ trusted++; trust_key(zone, name, &dnskey, mctx); } if (trusted == 0 && pending != 0) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(name, namebuf, sizeof namebuf); dns_zone_log(zone, ISC_LOG_ERROR, "No valid trust anchors for '%s'!", namebuf); dns_zone_log(zone, ISC_LOG_ERROR, "%d key(s) revoked, %d still pending", revoked, pending); dns_zone_log(zone, ISC_LOG_ERROR, "All queries to '%s' will fail", namebuf); fail_secure(zone, name); } } static isc_result_t do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff) { dns_diff_t temp_diff; isc_result_t result; /* * Create a singleton diff. */ dns_diff_init(diff->mctx, &temp_diff); ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); /* * Apply it to the database. */ result = dns_diff_apply(&temp_diff, db, ver); ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); if (result != ISC_R_SUCCESS) { dns_difftuple_free(tuple); return (result); } /* * Merge it into the current pending journal entry. */ dns_diff_appendminimal(diff, tuple); /* * Do not clear temp_diff. */ return (ISC_R_SUCCESS); } static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) { dns_difftuple_t *tuple = NULL; isc_result_t result; result = dns_difftuple_create(diff->mctx, op, name, ttl, rdata, &tuple); if (result != ISC_R_SUCCESS) return (result); return (do_one_tuple(&tuple, db, ver, diff)); } static isc_result_t update_soa_serial(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, isc_mem_t *mctx, dns_updatemethod_t method) { dns_difftuple_t *deltuple = NULL; dns_difftuple_t *addtuple = NULL; isc_uint32_t serial; isc_result_t result; CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple)); CHECK(dns_difftuple_copy(deltuple, &addtuple)); addtuple->op = DNS_DIFFOP_ADD; serial = dns_soa_getserial(&addtuple->rdata); serial = dns_update_soaserial(serial, method); dns_soa_setserial(serial, &addtuple->rdata); CHECK(do_one_tuple(&deltuple, db, ver, diff)); CHECK(do_one_tuple(&addtuple, db, ver, diff)); result = ISC_R_SUCCESS; failure: if (addtuple != NULL) dns_difftuple_free(&addtuple); if (deltuple != NULL) dns_difftuple_free(&deltuple); return (result); } /* * Write all transactions in 'diff' to the zone journal file. */ static isc_result_t zone_journal(dns_zone_t *zone, dns_diff_t *diff, isc_uint32_t *sourceserial, const char *caller) { const char me[] = "zone_journal"; const char *journalfile; isc_result_t result = ISC_R_SUCCESS; dns_journal_t *journal = NULL; unsigned int mode = DNS_JOURNAL_CREATE|DNS_JOURNAL_WRITE; ENTER; journalfile = dns_zone_getjournal(zone); if (journalfile != NULL) { result = dns_journal_open(zone->mctx, journalfile, mode, &journal); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "%s:dns_journal_open -> %s", caller, dns_result_totext(result)); return (result); } if (sourceserial != NULL) dns_journal_set_sourceserial(journal, *sourceserial); result = dns_journal_write_transaction(journal, diff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "%s:dns_journal_write_transaction -> %s", caller, dns_result_totext(result)); } dns_journal_destroy(&journal); } return (result); } /* * Create an SOA record for a newly-created zone */ static isc_result_t add_soa(dns_zone_t *zone, dns_db_t *db) { isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; unsigned char buf[DNS_SOA_BUFFERSIZE]; dns_dbversion_t *ver = NULL; dns_diff_t diff; dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA"); dns_diff_init(zone->mctx, &diff); result = dns_db_newversion(db, &ver); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "add_soa:dns_db_newversion -> %s", dns_result_totext(result)); goto failure; } /* Build SOA record */ result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass, 0, 0, 0, 0, 0, buf, &rdata); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "add_soa:dns_soa_buildrdata -> %s", dns_result_totext(result)); goto failure; } result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD, &zone->origin, 0, &rdata); failure: dns_diff_clear(&diff); if (ver != NULL) dns_db_closeversion(db, &ver, ISC_TF(result == ISC_R_SUCCESS)); INSIST(ver == NULL); return (result); } /* * Synchronize the set of initializing keys found in managed-keys {} * statements with the set of trust anchors found in the managed-keys.bind * zone. If a domain is no longer named in managed-keys, delete all keys * from that domain from the key zone. If a domain is mentioned in in * managed-keys but there are no references to it in the key zone, load * the key zone with the initializing key(s) for that domain. */ static isc_result_t sync_keyzone(dns_zone_t *zone, dns_db_t *db) { isc_result_t result = ISC_R_SUCCESS; isc_boolean_t changed = ISC_FALSE; isc_boolean_t commit = ISC_FALSE; dns_rbtnodechain_t chain; dns_fixedname_t fn; dns_name_t foundname, *origin; dns_keynode_t *keynode = NULL; dns_view_t *view = zone->view; dns_keytable_t *sr = NULL; dns_dbversion_t *ver = NULL; dns_diff_t diff; dns_rriterator_t rrit; dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys"); dns_name_init(&foundname, NULL); dns_fixedname_init(&fn); origin = dns_fixedname_name(&fn); dns_diff_init(zone->mctx, &diff); CHECK(dns_view_getsecroots(view, &sr)); result = dns_db_newversion(db, &ver); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "sync_keyzone:dns_db_newversion -> %s", dns_result_totext(result)); goto failure; } /* * Walk the zone DB. If we find any keys whose names are no longer * in managed-keys (or *are* in trusted-keys, meaning they are * permanent and not RFC5011-maintained), delete them from the * zone. Otherwise call load_secroots(), which loads keys into * secroots as appropriate. */ dns_rriterator_init(&rrit, db, ver, 0); for (result = dns_rriterator_first(&rrit); result == ISC_R_SUCCESS; result = dns_rriterator_nextrrset(&rrit)) { dns_rdataset_t *rdataset = NULL; dns_name_t *rrname = NULL; isc_uint32_t ttl; dns_rriterator_current(&rrit, &rrname, &ttl, &rdataset, NULL); if (!dns_rdataset_isassociated(rdataset)) { dns_rriterator_destroy(&rrit); goto failure; } if (rdataset->type != dns_rdatatype_keydata) continue; result = dns_keytable_find(sr, rrname, &keynode); if ((result != ISC_R_SUCCESS && result != DNS_R_PARTIALMATCH) || dns_keynode_managed(keynode) == ISC_FALSE) { CHECK(delete_keydata(db, ver, &diff, rrname, rdataset)); changed = ISC_TRUE; } else { load_secroots(zone, rrname, rdataset); } if (keynode != NULL) dns_keytable_detachkeynode(sr, &keynode); } dns_rriterator_destroy(&rrit); /* * Now walk secroots to find any managed keys that aren't * in the zone. If we find any, we add them to the zone. */ RWLOCK(&sr->rwlock, isc_rwlocktype_write); dns_rbtnodechain_init(&chain, zone->mctx); result = dns_rbtnodechain_first(&chain, sr->table, &foundname, origin); if (result == ISC_R_NOTFOUND) result = ISC_R_NOMORE; while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) { dns_rbtnode_t *rbtnode = NULL; dns_rbtnodechain_current(&chain, &foundname, origin, &rbtnode); if (rbtnode->data == NULL) goto skip; dns_keytable_attachkeynode(sr, rbtnode->data, &keynode); if (dns_keynode_managed(keynode)) { dns_fixedname_t fname; dns_name_t *keyname; dst_key_t *key; key = dns_keynode_key(keynode); dns_fixedname_init(&fname); if (key == NULL) /* fail_secure() was called. */ goto skip; keyname = dst_key_name(key); result = dns_db_find(db, keyname, ver, dns_rdatatype_keydata, DNS_DBFIND_NOWILD, 0, NULL, dns_fixedname_name(&fname), NULL, NULL); if (result != ISC_R_SUCCESS) result = create_keydata(zone, db, ver, &diff, sr, &keynode, &changed); if (result != ISC_R_SUCCESS) break; } skip: result = dns_rbtnodechain_next(&chain, &foundname, origin); if (keynode != NULL) dns_keytable_detachkeynode(sr, &keynode); } RWUNLOCK(&sr->rwlock, isc_rwlocktype_write); if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; if (changed) { /* Write changes to journal file. */ CHECK(update_soa_serial(db, ver, &diff, zone->mctx, zone->updatemethod)); CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone")); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); zone_needdump(zone, 30); commit = ISC_TRUE; } failure: if (result != ISC_R_SUCCESS && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { dns_zone_log(zone, ISC_LOG_ERROR, "unable to synchronize managed keys: %s", dns_result_totext(result)); isc_time_settoepoch(&zone->refreshkeytime); } if (keynode != NULL) dns_keytable_detachkeynode(sr, &keynode); if (sr != NULL) dns_keytable_detach(&sr); if (ver != NULL) dns_db_closeversion(db, &ver, commit); dns_diff_clear(&diff); INSIST(ver == NULL); return (result); } isc_result_t dns_zone_synckeyzone(dns_zone_t *zone) { isc_result_t result; dns_db_t *db = NULL; if (zone->type != dns_zone_key) return (DNS_R_BADZONE); CHECK(dns_zone_getdb(zone, &db)); LOCK_ZONE(zone); result = sync_keyzone(zone, db); UNLOCK_ZONE(zone); failure: if (db != NULL) dns_db_detach(&db); return (result); } static void maybe_send_secure(dns_zone_t *zone) { isc_result_t result; /* * We've finished loading, or else failed to load, an inline-signing * 'secure' zone. We now need information about the status of the * 'raw' zone. If we failed to load, then we need it to send a * copy of its database; if we succeeded, we need it to send its * serial number so that we can sync with it. If it has not yet * loaded, we set a flag so that it will send the necessary * information when it has finished loading. */ if (zone->raw->db != NULL) { if (zone->db != NULL) { isc_uint32_t serial; unsigned int soacount; result = zone_get_from_db(zone->raw, zone->raw->db, NULL, &soacount, &serial, NULL, NULL, NULL, NULL, NULL); if (result == ISC_R_SUCCESS && soacount > 0U) zone_send_secureserial(zone->raw, serial); } else zone_send_securedb(zone->raw, zone->raw->db); } else DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE); } static isc_boolean_t zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) { isc_result_t result; isc_boolean_t answer = ISC_FALSE; dns_diff_t diff; dns_diff_init(mctx, &diff); result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL); if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples)) answer = ISC_TRUE; dns_diff_clear(&diff); return (answer); } /* * The zone is presumed to be locked. * If this is a inline_raw zone the secure version is also locked. */ static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, isc_result_t result) { unsigned int soacount = 0; unsigned int nscount = 0; unsigned int errors = 0; isc_uint32_t serial, oldserial, refresh, retry, expire, minimum; isc_time_t now; isc_boolean_t needdump = ISC_FALSE; isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE); isc_boolean_t nomaster = ISC_FALSE; unsigned int options; dns_include_t *inc; INSIST(LOCKED_ZONE(zone)); if (inline_raw(zone)) INSIST(LOCKED_ZONE(zone->secure)); TIME_NOW(&now); /* * Initiate zone transfer? We may need a error code that * indicates that the "permanent" form does not exist. * XXX better error feedback to log. */ if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) { if (zone->type == dns_zone_slave || zone->type == dns_zone_stub || (zone->type == dns_zone_redirect && zone->masters == NULL)) { if (result == ISC_R_FILENOTFOUND) dns_zone_log(zone, ISC_LOG_DEBUG(1), "no master file"); else if (result != DNS_R_NOMASTERFILE) dns_zone_log(zone, ISC_LOG_ERROR, "loading from master file %s " "failed: %s", zone->masterfile, dns_result_totext(result)); } else if (zone->type == dns_zone_master && inline_secure(zone) && result == ISC_R_FILENOTFOUND) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "no master file, requesting db"); maybe_send_secure(zone); } else { int level = ISC_LOG_ERROR; if (zone->type == dns_zone_key && result == ISC_R_FILENOTFOUND) level = ISC_LOG_DEBUG(1); dns_zone_log(zone, level, "loading from master file %s failed: %s", zone->masterfile, dns_result_totext(result)); nomaster = ISC_TRUE; } if (zone->type != dns_zone_key) goto cleanup; } dns_zone_log(zone, ISC_LOG_DEBUG(2), "number of nodes in database: %u", dns_db_nodecount(db)); if (result == DNS_R_SEENINCLUDE) DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE); else DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE); /* * If there's no master file for a key zone, then the zone is new: * create an SOA record. (We do this now, instead of later, so that * if there happens to be a journal file, we can roll forward from * a sane starting point.) */ if (nomaster && zone->type == dns_zone_key) { result = add_soa(zone, db); if (result != ISC_R_SUCCESS) goto cleanup; } /* * Apply update log, if any, on initial load. */ if (zone->journal != NULL && ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) && ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { if (zone->type == dns_zone_master && (zone->update_acl != NULL || zone->ssutable != NULL)) options = DNS_JOURNALOPT_RESIGN; else options = 0; result = dns_journal_rollforward(zone->mctx, db, options, zone->journal); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND && result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL && result != ISC_R_RANGE) { dns_zone_log(zone, ISC_LOG_ERROR, "journal rollforward failed: %s", dns_result_totext(result)); goto cleanup; } if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) { dns_zone_log(zone, ISC_LOG_ERROR, "journal rollforward failed: " "journal out of sync with zone"); goto cleanup; } dns_zone_log(zone, ISC_LOG_DEBUG(1), "journal rollforward completed " "successfully: %s", dns_result_totext(result)); if (result == ISC_R_SUCCESS) needdump = ISC_TRUE; } /* * Obtain ns, soa and cname counts for top of zone. */ INSIST(db != NULL); result = zone_get_from_db(zone, db, &nscount, &soacount, &serial, &refresh, &retry, &expire, &minimum, &errors); if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) { dns_zone_log(zone, ISC_LOG_ERROR, "could not find NS and/or SOA records"); } /* * Check to make sure the journal is up to date, and remove the * journal file if it isn't, as we wouldn't be able to apply * updates otherwise. */ if (zone->journal != NULL && dns_zone_isdynamic(zone, ISC_TRUE) && ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) { isc_uint32_t jserial; dns_journal_t *journal = NULL; result = dns_journal_open(zone->mctx, zone->journal, DNS_JOURNAL_READ, &journal); if (result == ISC_R_SUCCESS) { jserial = dns_journal_last_serial(journal); dns_journal_destroy(&journal); } else { jserial = serial; result = ISC_R_SUCCESS; } if (jserial != serial) { dns_zone_log(zone, ISC_LOG_INFO, "journal file is out of date: " "removing journal file"); if (remove(zone->journal) < 0 && errno != ENOENT) { char strbuf[ISC_STRERRORSIZE]; isc__strerror(errno, strbuf, sizeof(strbuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, ISC_LOG_WARNING, "unable to remove journal " "'%s': '%s'", zone->journal, strbuf); } } } dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded; checking validity"); /* * Master / Slave / Stub zones require both NS and SOA records at * the top of the zone. */ switch (zone->type) { case dns_zone_dlz: case dns_zone_master: case dns_zone_slave: case dns_zone_stub: case dns_zone_redirect: if (soacount != 1) { dns_zone_log(zone, ISC_LOG_ERROR, "has %d SOA records", soacount); result = DNS_R_BADZONE; } if (nscount == 0) { dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records"); result = DNS_R_BADZONE; } if (result != ISC_R_SUCCESS) goto cleanup; if (zone->type == dns_zone_master && errors != 0) { result = DNS_R_BADZONE; goto cleanup; } if (zone->type != dns_zone_stub && zone->type != dns_zone_redirect) { result = check_nsec3param(zone, db); if (result != ISC_R_SUCCESS) goto cleanup; } if (zone->type == dns_zone_master && DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) && !integrity_checks(zone, db)) { result = DNS_R_BADZONE; goto cleanup; } if (zone->type == dns_zone_master && DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) && !zone_check_dup(zone, db)) { result = DNS_R_BADZONE; goto cleanup; } if (zone->db != NULL) { unsigned int oldsoacount; /* * This is checked in zone_replacedb() for slave zones * as they don't reload from disk. */ result = zone_get_from_db(zone, zone->db, NULL, &oldsoacount, &oldserial, NULL, NULL, NULL, NULL, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); RUNTIME_CHECK(soacount > 0U); if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && !isc_serial_gt(serial, oldserial)) { isc_uint32_t serialmin, serialmax; INSIST(zone->type == dns_zone_master); if (serial == oldserial && zone_unchanged(zone->db, db, zone->mctx)) { dns_zone_log(zone, ISC_LOG_INFO, "ixfr-from-differences: " "unchanged"); return(ISC_R_SUCCESS); } serialmin = (oldserial + 1) & 0xffffffffU; serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU; dns_zone_log(zone, ISC_LOG_ERROR, "ixfr-from-differences: " "new serial (%u) out of range " "[%u - %u]", serial, serialmin, serialmax); result = DNS_R_BADZONE; goto cleanup; } else if (!isc_serial_ge(serial, oldserial)) dns_zone_log(zone, ISC_LOG_ERROR, "zone serial (%u/%u) has gone " "backwards", serial, oldserial); else if (serial == oldserial && !hasinclude && strcmp(zone->db_argv[0], "_builtin") != 0) dns_zone_log(zone, ISC_LOG_ERROR, "zone serial (%u) unchanged. " "zone may fail to transfer " "to slaves.", serial); } if (zone->type == dns_zone_master && (zone->update_acl != NULL || zone->ssutable != NULL) && zone->sigresigninginterval < (3 * refresh) && dns_db_issecure(db)) { dns_zone_log(zone, ISC_LOG_WARNING, "sig-re-signing-interval less than " "3 * refresh."); } zone->refresh = RANGE(refresh, zone->minrefresh, zone->maxrefresh); zone->retry = RANGE(retry, zone->minretry, zone->maxretry); zone->expire = RANGE(expire, zone->refresh + zone->retry, DNS_MAX_EXPIRE); zone->minimum = minimum; DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); if (zone->type == dns_zone_slave || zone->type == dns_zone_stub || (zone->type == dns_zone_redirect && zone->masters != NULL)) { isc_time_t t; isc_uint32_t delay; result = isc_file_getmodtime(zone->journal, &t); if (result != ISC_R_SUCCESS) result = isc_file_getmodtime(zone->masterfile, &t); if (result == ISC_R_SUCCESS) DNS_ZONE_TIME_ADD(&t, zone->expire, &zone->expiretime); else DNS_ZONE_TIME_ADD(&now, zone->retry, &zone->expiretime); delay = isc_random_jitter(zone->retry, (zone->retry * 3) / 4); DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime); if (isc_time_compare(&zone->refreshtime, &zone->expiretime) >= 0) zone->refreshtime = now; } break; case dns_zone_key: result = sync_keyzone(zone, db); if (result != ISC_R_SUCCESS) goto cleanup; break; default: UNEXPECTED_ERROR(__FILE__, __LINE__, "unexpected zone type %d", zone->type); result = ISC_R_UNEXPECTED; goto cleanup; } /* * Check for weak DNSKEY's. */ if (zone->type == dns_zone_master) zone_check_dnskeys(zone, db); /* * Schedule DNSSEC key refresh. */ if (zone->type == dns_zone_master && DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) zone->refreshkeytime = now; #if 0 /* destroy notification example. */ { isc_event_t *e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_DBDESTROYED, dns_zonemgr_dbdestroyed, zone, sizeof(isc_event_t)); dns_db_ondestroy(db, zone->task, &e); } #endif ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); if (zone->db != NULL) { result = zone_replacedb(zone, db, ISC_FALSE); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); if (result != ISC_R_SUCCESS) goto cleanup; } else { result = dns_db_rpz_ready(db); if (result != ISC_R_SUCCESS) goto cleanup; zone_attachdb(zone, db); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED| DNS_ZONEFLG_NEEDSTARTUPNOTIFY); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) && inline_raw(zone)) { if (zone->secure->db == NULL) zone_send_securedb(zone, db); else zone_send_secureserial(zone, serial); } } /* * Finished loading inline-signing zone; need to get status * from the raw side now. */ if (zone->type == dns_zone_master && inline_secure(zone)) maybe_send_secure(zone); result = ISC_R_SUCCESS; if (needdump) { if (zone->type == dns_zone_key) zone_needdump(zone, 30); else zone_needdump(zone, DNS_DUMP_DELAY); } if (zone->task != NULL) { if (zone->type == dns_zone_master) { set_resigntime(zone); resume_signingwithkey(zone); resume_addnsec3chain(zone); } if (zone->type == dns_zone_master && !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) && dns_zone_isdynamic(zone, ISC_FALSE) && dns_db_issecure(db)) { dns_name_t *name; dns_fixedname_t fixed; dns_rdataset_t next; dns_rdataset_init(&next); dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); result = dns_db_getsigningtime(db, &next, name); if (result == ISC_R_SUCCESS) { isc_stdtime_t timenow; char namebuf[DNS_NAME_FORMATSIZE]; char typebuf[DNS_RDATATYPE_FORMATSIZE]; isc_stdtime_get(&timenow); dns_name_format(name, namebuf, sizeof(namebuf)); dns_rdatatype_format(next.covers, typebuf, sizeof(typebuf)); dns_zone_log(zone, ISC_LOG_DEBUG(3), "next resign: %s/%s in %d seconds", namebuf, typebuf, next.resign - timenow - zone->sigresigninginterval); dns_rdataset_disassociate(&next); } else dns_zone_log(zone, ISC_LOG_WARNING, "signed dynamic zone has no " "resign event scheduled"); } zone_settimer(zone, &now); } /* * Clear old include list. */ for (inc = ISC_LIST_HEAD(zone->includes); inc != NULL; inc = ISC_LIST_HEAD(zone->includes)) { ISC_LIST_UNLINK(zone->includes, inc, link); isc_mem_free(zone->mctx, inc->name); isc_mem_put(zone->mctx, inc, sizeof(*inc)); } zone->nincludes = 0; /* * Transfer new include list. */ for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL; inc = ISC_LIST_HEAD(zone->newincludes)) { ISC_LIST_UNLINK(zone->newincludes, inc, link); ISC_LIST_APPEND(zone->includes, inc, link); zone->nincludes++; } if (! dns_db_ispersistent(db)) dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial, dns_db_issecure(db) ? " (DNSSEC signed)" : ""); zone->loadtime = loadtime; DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING); return (result); cleanup: for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL; inc = ISC_LIST_HEAD(zone->newincludes)) { ISC_LIST_UNLINK(zone->newincludes, inc, link); isc_mem_free(zone->mctx, inc->name); isc_mem_put(zone->mctx, inc, sizeof(*inc)); } if (zone->type == dns_zone_slave || zone->type == dns_zone_stub || zone->type == dns_zone_key || (zone->type == dns_zone_redirect && zone->masters != NULL)) { if (result != ISC_R_NOMEMORY) { if (zone->journal != NULL) zone_saveunique(zone, zone->journal, "jn-XXXXXXXX"); if (zone->masterfile != NULL) zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX"); } /* Mark the zone for immediate refresh. */ zone->refreshtime = now; if (zone->task != NULL) zone_settimer(zone, &now); result = ISC_R_SUCCESS; } else if (zone->type == dns_zone_master || zone->type == dns_zone_redirect) { if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND)) dns_zone_log(zone, ISC_LOG_ERROR, "not loaded due to errors."); else if (zone->type == dns_zone_master) result = ISC_R_SUCCESS; } return (result); } static isc_boolean_t exit_check(dns_zone_t *zone) { REQUIRE(LOCKED_ZONE(zone)); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) && zone->irefs == 0) { /* * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0. */ INSIST(isc_refcount_current(&zone->erefs) == 0); return (ISC_TRUE); } return (ISC_FALSE); } static isc_boolean_t zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, isc_boolean_t logit) { isc_result_t result; char namebuf[DNS_NAME_FORMATSIZE]; char altbuf[DNS_NAME_FORMATSIZE]; dns_fixedname_t fixed; dns_name_t *foundname; int level; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS)) return (ISC_TRUE); if (zone->type == dns_zone_master) level = ISC_LOG_ERROR; else level = ISC_LOG_WARNING; dns_fixedname_init(&fixed); foundname = dns_fixedname_name(&fixed); result = dns_db_find(db, name, version, dns_rdatatype_a, 0, 0, NULL, foundname, NULL, NULL); if (result == ISC_R_SUCCESS) return (ISC_TRUE); if (result == DNS_R_NXRRSET) { result = dns_db_find(db, name, version, dns_rdatatype_aaaa, 0, 0, NULL, foundname, NULL, NULL); if (result == ISC_R_SUCCESS) return (ISC_TRUE); } if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || result == DNS_R_EMPTYNAME) { if (logit) { dns_name_format(name, namebuf, sizeof namebuf); dns_zone_log(zone, level, "NS '%s' has no address " "records (A or AAAA)", namebuf); } return (ISC_FALSE); } if (result == DNS_R_CNAME) { if (logit) { dns_name_format(name, namebuf, sizeof namebuf); dns_zone_log(zone, level, "NS '%s' is a CNAME " "(illegal)", namebuf); } return (ISC_FALSE); } if (result == DNS_R_DNAME) { if (logit) { dns_name_format(name, namebuf, sizeof namebuf); dns_name_format(foundname, altbuf, sizeof altbuf); dns_zone_log(zone, level, "NS '%s' is below a DNAME " "'%s' (illegal)", namebuf, altbuf); } return (ISC_FALSE); } return (ISC_TRUE); } static isc_result_t zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, unsigned int *nscount, unsigned int *errors, isc_boolean_t logit) { isc_result_t result; unsigned int count = 0; unsigned int ecount = 0; dns_rdataset_t rdataset; dns_rdata_t rdata; dns_rdata_ns_t ns; dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns, dns_rdatatype_none, 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) { INSIST(!dns_rdataset_isassociated(&rdataset)); goto success; } if (result != ISC_R_SUCCESS) { INSIST(!dns_rdataset_isassociated(&rdataset)); goto invalidate_rdataset; } result = dns_rdataset_first(&rdataset); while (result == ISC_R_SUCCESS) { if (errors != NULL && zone->rdclass == dns_rdataclass_in && (zone->type == dns_zone_master || zone->type == dns_zone_slave)) { dns_rdata_init(&rdata); dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &ns, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (dns_name_issubdomain(&ns.name, &zone->origin) && !zone_check_ns(zone, db, version, &ns.name, logit)) ecount++; } count++; result = dns_rdataset_next(&rdataset); } dns_rdataset_disassociate(&rdataset); success: if (nscount != NULL) *nscount = count; if (errors != NULL) *errors = ecount; result = ISC_R_SUCCESS; invalidate_rdataset: dns_rdataset_invalidate(&rdataset); return (result); } static isc_result_t zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, unsigned int *soacount, isc_uint32_t *serial, isc_uint32_t *refresh, isc_uint32_t *retry, isc_uint32_t *expire, isc_uint32_t *minimum) { isc_result_t result; unsigned int count; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_soa_t soa; dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa, dns_rdatatype_none, 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) { INSIST(!dns_rdataset_isassociated(&rdataset)); if (soacount != NULL) *soacount = 0; if (serial != NULL) *serial = 0; if (refresh != NULL) *refresh = 0; if (retry != NULL) *retry = 0; if (expire != NULL) *expire = 0; if (minimum != NULL) *minimum = 0; result = ISC_R_SUCCESS; goto invalidate_rdataset; } if (result != ISC_R_SUCCESS) { INSIST(!dns_rdataset_isassociated(&rdataset)); goto invalidate_rdataset; } count = 0; result = dns_rdataset_first(&rdataset); while (result == ISC_R_SUCCESS) { dns_rdata_init(&rdata); dns_rdataset_current(&rdataset, &rdata); count++; if (count == 1) { result = dns_rdata_tostruct(&rdata, &soa, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); } result = dns_rdataset_next(&rdataset); dns_rdata_reset(&rdata); } dns_rdataset_disassociate(&rdataset); if (soacount != NULL) *soacount = count; if (count > 0) { if (serial != NULL) *serial = soa.serial; if (refresh != NULL) *refresh = soa.refresh; if (retry != NULL) *retry = soa.retry; if (expire != NULL) *expire = soa.expire; if (minimum != NULL) *minimum = soa.minimum; } else { if (soacount != NULL) *soacount = 0; if (serial != NULL) *serial = 0; if (refresh != NULL) *refresh = 0; if (retry != NULL) *retry = 0; if (expire != NULL) *expire = 0; if (minimum != NULL) *minimum = 0; } result = ISC_R_SUCCESS; invalidate_rdataset: dns_rdataset_invalidate(&rdataset); return (result); } /* * zone must be locked. */ static isc_result_t zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, unsigned int *soacount, isc_uint32_t *serial, isc_uint32_t *refresh, isc_uint32_t *retry, isc_uint32_t *expire, isc_uint32_t *minimum, unsigned int *errors) { isc_result_t result; isc_result_t answer = ISC_R_SUCCESS; dns_dbversion_t *version = NULL; dns_dbnode_t *node; REQUIRE(db != NULL); REQUIRE(zone != NULL); dns_db_currentversion(db, &version); if (nscount != NULL) *nscount = 0; if (soacount != NULL) *soacount = 0; if (serial != NULL) *serial = 0; if (refresh != NULL) *refresh = 0; if (retry != NULL) *retry = 0; if (expire != NULL) *expire = 0; if (errors != NULL) *errors = 0; node = NULL; result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) { answer = result; goto closeversion; } if (nscount != NULL || errors != NULL) { result = zone_count_ns_rr(zone, db, node, version, nscount, errors, ISC_TRUE); if (result != ISC_R_SUCCESS) answer = result; } if (soacount != NULL || serial != NULL || refresh != NULL || retry != NULL || expire != NULL || minimum != NULL) { result = zone_load_soa_rr(db, node, version, soacount, serial, refresh, retry, expire, minimum); if (result != ISC_R_SUCCESS) answer = result; } dns_db_detachnode(db, &node); closeversion: dns_db_closeversion(db, &version, ISC_FALSE); return (answer); } void dns_zone_attach(dns_zone_t *source, dns_zone_t **target) { REQUIRE(DNS_ZONE_VALID(source)); REQUIRE(target != NULL && *target == NULL); isc_refcount_increment(&source->erefs, NULL); *target = source; } void dns_zone_detach(dns_zone_t **zonep) { dns_zone_t *zone; dns_zone_t *raw = NULL; dns_zone_t *secure = NULL; unsigned int refs; isc_boolean_t free_now = ISC_FALSE; REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); zone = *zonep; isc_refcount_decrement(&zone->erefs, &refs); if (refs == 0) { LOCK_ZONE(zone); INSIST(zone != zone->raw); /* * We just detached the last external reference. */ if (zone->task != NULL) { /* * This zone is being managed. Post * its control event and let it clean * up synchronously in the context of * its task. */ isc_event_t *ev = &zone->ctlevent; isc_task_send(zone->task, &ev); } else { /* * This zone is not being managed; it has * no task and can have no outstanding * events. Free it immediately. */ /* * Unmanaged zones should not have non-null views; * we have no way of detaching from the view here * without causing deadlock because this code is called * with the view already locked. */ INSIST(zone->view == NULL); free_now = ISC_TRUE; raw = zone->raw; zone->raw = NULL; secure = zone->secure; zone->secure = NULL; } UNLOCK_ZONE(zone); } *zonep = NULL; if (free_now) { if (raw != NULL) dns_zone_detach(&raw); if (secure != NULL) dns_zone_idetach(&secure); zone_free(zone); } } void dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) { REQUIRE(DNS_ZONE_VALID(source)); REQUIRE(target != NULL && *target == NULL); LOCK_ZONE(source); zone_iattach(source, target); UNLOCK_ZONE(source); } static void zone_iattach(dns_zone_t *source, dns_zone_t **target) { /* * 'source' locked by caller. */ REQUIRE(LOCKED_ZONE(source)); REQUIRE(DNS_ZONE_VALID(source)); REQUIRE(target != NULL && *target == NULL); INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0); source->irefs++; INSIST(source->irefs != 0); *target = source; } static void zone_idetach(dns_zone_t **zonep) { dns_zone_t *zone; /* * 'zone' locked by caller. */ REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); zone = *zonep; REQUIRE(LOCKED_ZONE(*zonep)); *zonep = NULL; INSIST(zone->irefs > 0); zone->irefs--; INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0); } void dns_zone_idetach(dns_zone_t **zonep) { dns_zone_t *zone; isc_boolean_t free_needed; REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); zone = *zonep; *zonep = NULL; LOCK_ZONE(zone); INSIST(zone->irefs > 0); zone->irefs--; free_needed = exit_check(zone); UNLOCK_ZONE(zone); if (free_needed) zone_free(zone); } isc_mem_t * dns_zone_getmctx(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->mctx); } dns_zonemgr_t * dns_zone_getmgr(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->zmgr); } void dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (value) DNS_ZONE_SETFLAG(zone, flags); else DNS_ZONE_CLRFLAG(zone, flags); UNLOCK_ZONE(zone); } void dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (value) zone->options |= option; else zone->options &= ~option; UNLOCK_ZONE(zone); } void dns_zone_setoption2(dns_zone_t *zone, unsigned int option, isc_boolean_t value) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (value) zone->options2 |= option; else zone->options2 &= ~option; UNLOCK_ZONE(zone); } unsigned int dns_zone_getoptions(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->options); } unsigned int dns_zone_getoptions2(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->options2); } void dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, isc_boolean_t value) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (value) zone->keyopts |= keyopt; else zone->keyopts &= ~keyopt; UNLOCK_ZONE(zone); } unsigned int dns_zone_getkeyopts(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->keyopts); } isc_result_t dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->xfrsource4 = *xfrsource; UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); } isc_sockaddr_t * dns_zone_getxfrsource4(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (&zone->xfrsource4); } isc_result_t dns_zone_setxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->xfrsource4dscp = dscp; UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); } isc_dscp_t dns_zone_getxfrsource4dscp(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->xfrsource4dscp); } isc_result_t dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->xfrsource6 = *xfrsource; UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); } isc_sockaddr_t * dns_zone_getxfrsource6(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (&zone->xfrsource6); } isc_dscp_t dns_zone_getxfrsource6dscp(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->xfrsource6dscp); } isc_result_t dns_zone_setxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->xfrsource6dscp = dscp; UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); } isc_result_t dns_zone_setaltxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *altxfrsource) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->altxfrsource4 = *altxfrsource; UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); } isc_sockaddr_t * dns_zone_getaltxfrsource4(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (&zone->altxfrsource4); } isc_result_t dns_zone_setaltxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->altxfrsource4dscp = dscp; UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); } isc_dscp_t dns_zone_getaltxfrsource4dscp(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->altxfrsource4dscp); } isc_result_t dns_zone_setaltxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *altxfrsource) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->altxfrsource6 = *altxfrsource; UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); } isc_sockaddr_t * dns_zone_getaltxfrsource6(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (&zone->altxfrsource6); } isc_result_t dns_zone_setaltxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->altxfrsource6dscp = dscp; UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); } isc_dscp_t dns_zone_getaltxfrsource6dscp(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->altxfrsource6dscp); } isc_result_t dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->notifysrc4 = *notifysrc; UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); } isc_sockaddr_t * dns_zone_getnotifysrc4(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (&zone->notifysrc4); } isc_result_t dns_zone_setnotifysrc4dscp(dns_zone_t *zone, isc_dscp_t dscp) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->notifysrc4dscp = dscp; UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); } isc_dscp_t dns_zone_getnotifysrc4dscp(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->notifysrc4dscp); } isc_result_t dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->notifysrc6 = *notifysrc; UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); } isc_sockaddr_t * dns_zone_getnotifysrc6(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (&zone->notifysrc6); } static isc_boolean_t same_addrs(const isc_sockaddr_t *old, const isc_sockaddr_t *new, isc_uint32_t count) { unsigned int i; for (i = 0; i < count; i++) if (!isc_sockaddr_equal(&old[i], &new[i])) return (ISC_FALSE); return (ISC_TRUE); } static isc_boolean_t same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) { unsigned int i; if (old == NULL && new == NULL) return (ISC_TRUE); if (old == NULL || new == NULL) return (ISC_FALSE); for (i = 0; i < count; i++) { if (old[i] == NULL && new[i] == NULL) continue; if (old[i] == NULL || new[i] == NULL || !dns_name_equal(old[i], new[i])) return (ISC_FALSE); } return (ISC_TRUE); } static void clear_addresskeylist(isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp, dns_name_t ***keynamesp, unsigned int *countp, isc_mem_t *mctx) { unsigned int count; isc_sockaddr_t *addrs; isc_dscp_t *dscps; dns_name_t **keynames; REQUIRE(countp != NULL && addrsp != NULL && dscpsp != NULL && keynamesp != NULL); count = *countp; *countp = 0; addrs = *addrsp; *addrsp = NULL; dscps = *dscpsp; *dscpsp = NULL; keynames = *keynamesp; *keynamesp = NULL; if (addrs != NULL) isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t)); if (dscps != NULL) isc_mem_put(mctx, dscps, count * sizeof(isc_dscp_t)); if (keynames != NULL) { unsigned int i; for (i = 0; i < count; i++) { if (keynames[i] != NULL) { dns_name_free(keynames[i], mctx); isc_mem_put(mctx, keynames[i], sizeof(dns_name_t)); keynames[i] = NULL; } } isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *)); } } static isc_result_t set_addrkeylist(unsigned int count, const isc_sockaddr_t *addrs, isc_sockaddr_t **newaddrsp, const isc_dscp_t *dscp, isc_dscp_t **newdscpp, dns_name_t **names, dns_name_t ***newnamesp, isc_mem_t *mctx) { isc_result_t result; isc_sockaddr_t *newaddrs = NULL; isc_dscp_t *newdscp = NULL; dns_name_t **newnames = NULL; unsigned int i; REQUIRE(newaddrsp != NULL && *newaddrsp == NULL); REQUIRE(newdscpp != NULL && *newdscpp == NULL); REQUIRE(newnamesp != NULL && *newnamesp == NULL); newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs)); if (newaddrs == NULL) return (ISC_R_NOMEMORY); memmove(newaddrs, addrs, count * sizeof(*newaddrs)); if (dscp != NULL) { newdscp = isc_mem_get(mctx, count * sizeof(*newdscp)); if (newdscp == NULL) { isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs)); return (ISC_R_NOMEMORY); } memmove(newdscp, dscp, count * sizeof(*newdscp)); } else newdscp = NULL; if (names != NULL) { newnames = isc_mem_get(mctx, count * sizeof(*newnames)); if (newnames == NULL) { if (newdscp != NULL) isc_mem_put(mctx, newdscp, count * sizeof(*newdscp)); isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs)); return (ISC_R_NOMEMORY); } for (i = 0; i < count; i++) newnames[i] = NULL; for (i = 0; i < count; i++) { if (names[i] != NULL) { newnames[i] = isc_mem_get(mctx, sizeof(dns_name_t)); if (newnames[i] == NULL) goto allocfail; dns_name_init(newnames[i], NULL); result = dns_name_dup(names[i], mctx, newnames[i]); if (result != ISC_R_SUCCESS) { allocfail: for (i = 0; i < count; i++) if (newnames[i] != NULL) dns_name_free( newnames[i], mctx); isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs)); isc_mem_put(mctx, newdscp, count * sizeof(*newdscp)); isc_mem_put(mctx, newnames, count * sizeof(*newnames)); return (ISC_R_NOMEMORY); } } } } else newnames = NULL; *newdscpp = newdscp; *newaddrsp = newaddrs; *newnamesp = newnames; return (ISC_R_SUCCESS); } isc_result_t dns_zone_setnotifysrc6dscp(dns_zone_t *zone, isc_dscp_t dscp) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->notifysrc6dscp = dscp; UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); } isc_dscp_t dns_zone_getnotifysrc6dscp(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->notifysrc6dscp); } isc_result_t dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify, isc_uint32_t count) { return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, NULL, count)); } isc_result_t dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify, dns_name_t **keynames, isc_uint32_t count) { return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, keynames, count)); } isc_result_t dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify, const isc_dscp_t *dscps, dns_name_t **keynames, isc_uint32_t count) { isc_result_t result; isc_sockaddr_t *newaddrs = NULL; isc_dscp_t *newdscps = NULL; dns_name_t **newnames = NULL; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(count == 0 || notify != NULL); if (keynames != NULL) REQUIRE(count != 0); LOCK_ZONE(zone); if (count == zone->notifycnt && same_addrs(zone->notify, notify, count) && same_keynames(zone->notifykeynames, keynames, count)) goto unlock; clear_addresskeylist(&zone->notify, &zone->notifydscp, &zone->notifykeynames, &zone->notifycnt, zone->mctx); if (count == 0) goto unlock; /* * Set up the notify and notifykey lists */ result = set_addrkeylist(count, notify, &newaddrs, dscps, &newdscps, keynames, &newnames, zone->mctx); if (result != ISC_R_SUCCESS) goto unlock; /* * Everything is ok so attach to the zone. */ zone->notify = newaddrs; zone->notifydscp = newdscps; zone->notifykeynames = newnames; zone->notifycnt = count; unlock: UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); } isc_result_t dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters, isc_uint32_t count) { isc_result_t result; result = dns_zone_setmasterswithkeys(zone, masters, NULL, count); return (result); } isc_result_t dns_zone_setmasterswithkeys(dns_zone_t *zone, const isc_sockaddr_t *masters, dns_name_t **keynames, isc_uint32_t count) { isc_result_t result = ISC_R_SUCCESS; isc_sockaddr_t *newaddrs = NULL; isc_dscp_t *newdscps = NULL; dns_name_t **newnames = NULL; isc_boolean_t *newok; unsigned int i; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(count == 0 || masters != NULL); if (keynames != NULL) { REQUIRE(count != 0); } LOCK_ZONE(zone); /* * The refresh code assumes that 'masters' wouldn't change under it. * If it will change then kill off any current refresh in progress * and update the masters info. If it won't change then we can just * unlock and exit. */ if (count != zone->masterscnt || !same_addrs(zone->masters, masters, count) || !same_keynames(zone->masterkeynames, keynames, count)) { if (zone->request != NULL) dns_request_cancel(zone->request); } else goto unlock; /* * This needs to happen before clear_addresskeylist() sets * zone->masterscnt to 0: */ if (zone->mastersok != NULL) { isc_mem_put(zone->mctx, zone->mastersok, zone->masterscnt * sizeof(isc_boolean_t)); zone->mastersok = NULL; } clear_addresskeylist(&zone->masters, &zone->masterdscps, &zone->masterkeynames, &zone->masterscnt, zone->mctx); /* * If count == 0, don't allocate any space for masters, mastersok or * keynames so internally, those pointers are NULL if count == 0 */ if (count == 0) goto unlock; /* * mastersok must contain count elements */ newok = isc_mem_get(zone->mctx, count * sizeof(*newok)); if (newok == NULL) { result = ISC_R_NOMEMORY; isc_mem_put(zone->mctx, newaddrs, count * sizeof(*newaddrs)); goto unlock; }; for (i = 0; i < count; i++) newok[i] = ISC_FALSE; /* * Now set up the masters and masterkey lists */ result = set_addrkeylist(count, masters, &newaddrs, NULL, &newdscps, keynames, &newnames, zone->mctx); INSIST(newdscps == NULL); if (result != ISC_R_SUCCESS) { isc_mem_put(zone->mctx, newok, count * sizeof(*newok)); goto unlock; } /* * Everything is ok so attach to the zone. */ zone->curmaster = 0; zone->mastersok = newok; zone->masters = newaddrs; zone->masterdscps = newdscps; zone->masterkeynames = newnames; zone->masterscnt = count; DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS); unlock: UNLOCK_ZONE(zone); return (result); } isc_result_t dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(DNS_ZONE_VALID(zone)); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db == NULL) result = DNS_R_NOTLOADED; else dns_db_attach(zone->db, dpb); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); return (result); } void dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(zone->type == dns_zone_staticstub); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); REQUIRE(zone->db == NULL); dns_db_attach(db, &zone->db); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); } /* * Co-ordinates the starting of routine jobs. */ void dns_zone_maintenance(dns_zone_t *zone) { const char me[] = "dns_zone_maintenance"; isc_time_t now; REQUIRE(DNS_ZONE_VALID(zone)); ENTER; LOCK_ZONE(zone); TIME_NOW(&now); zone_settimer(zone, &now); UNLOCK_ZONE(zone); } static inline isc_boolean_t was_dumping(dns_zone_t *zone) { isc_boolean_t dumping; REQUIRE(LOCKED_ZONE(zone)); dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); if (!dumping) { DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); isc_time_settoepoch(&zone->dumptime); } return (dumping); } static isc_result_t find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx, unsigned int maxkeys, dst_key_t **keys, unsigned int *nkeys) { isc_result_t result; dns_dbnode_t *node = NULL; const char *directory = dns_zone_getkeydirectory(zone); CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node)); memset(keys, 0, sizeof(*keys) * maxkeys); result = dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db), directory, mctx, maxkeys, keys, nkeys); if (result == ISC_R_NOTFOUND) result = ISC_R_SUCCESS; failure: if (node != NULL) dns_db_detachnode(db, &node); return (result); } static isc_result_t offline(dns_db_t *db, dns_dbversion_t *ver, zonediff_t *zonediff, dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) { isc_result_t result; if ((rdata->flags & DNS_RDATA_OFFLINE) != 0) return (ISC_R_SUCCESS); result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, name, ttl, rdata); if (result != ISC_R_SUCCESS) return (result); rdata->flags |= DNS_RDATA_OFFLINE; result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN, name, ttl, rdata); zonediff->offline = ISC_TRUE; return (result); } static void set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now) { unsigned int delta; char timebuf[80]; zone->key_expiry = when; if (when <= now) { dns_zone_log(zone, ISC_LOG_ERROR, "DNSKEY RRSIG(s) have expired"); isc_time_settoepoch(&zone->keywarntime); } else if (when < now + 7 * 24 * 3600) { isc_time_t t; isc_time_set(&t, when, 0); isc_time_formattimestamp(&t, timebuf, 80); dns_zone_log(zone, ISC_LOG_WARNING, "DNSKEY RRSIG(s) will expire within 7 days: %s", timebuf); delta = when - now; delta--; /* loop prevention */ delta /= 24 * 3600; /* to whole days */ delta *= 24 * 3600; /* to seconds */ isc_time_set(&zone->keywarntime, when - delta, 0); } else { isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0); isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); dns_zone_log(zone, ISC_LOG_NOTICE, "setting keywarntime to %s", timebuf); } } /* * Helper function to del_sigs(). We don't want to delete RRSIGs that * have no new key. */ static isc_boolean_t delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys, isc_boolean_t *warn) { unsigned int i = 0; isc_boolean_t have_ksk = ISC_FALSE, have_zsk = ISC_FALSE; isc_boolean_t have_pksk = ISC_FALSE, have_pzsk = ISC_FALSE; for (i = 0; i < nkeys; i++) { if (rrsig_ptr->algorithm != dst_key_alg(keys[i])) continue; if (dst_key_isprivate(keys[i])) { if (KSK(keys[i])) have_ksk = have_pksk = ISC_TRUE; else have_zsk = have_pzsk = ISC_TRUE; } else { if (KSK(keys[i])) have_ksk = ISC_TRUE; else have_zsk = ISC_TRUE; } } if (have_zsk && have_ksk && !have_pzsk) *warn = ISC_TRUE; /* * It's okay to delete a signature if there is an active key * with the same algorithm to replace it. */ if (have_pksk || have_pzsk) return (ISC_TRUE); /* * Failing that, it is *not* okay to delete a signature * if the associated public key is still in the DNSKEY RRset */ for (i = 0; i < nkeys; i++) { if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) && (rrsig_ptr->keyid == dst_key_id(keys[i]))) return (ISC_FALSE); } /* * But if the key is gone, then go ahead. */ return (ISC_TRUE); } /* * Delete expired RRsigs and any RRsigs we are about to re-sign. * See also update.c:del_keysigs(). */ static isc_result_t del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_rdatatype_t type, zonediff_t *zonediff, dst_key_t **keys, unsigned int nkeys, isc_stdtime_t now, isc_boolean_t incremental) { isc_result_t result; dns_dbnode_t *node = NULL; dns_rdataset_t rdataset; unsigned int i; dns_rdata_rrsig_t rrsig; isc_boolean_t found; isc_int64_t timewarn = 0, timemaybe = 0; dns_rdataset_init(&rdataset); if (type == dns_rdatatype_nsec3) result = dns_db_findnsec3node(db, name, ISC_FALSE, &node); else result = dns_db_findnode(db, name, ISC_FALSE, &node); if (result == ISC_R_NOTFOUND) return (ISC_R_SUCCESS); if (result != ISC_R_SUCCESS) goto failure; result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type, (isc_stdtime_t) 0, &rdataset, NULL); dns_db_detachnode(db, &node); if (result == ISC_R_NOTFOUND) { INSIST(!dns_rdataset_isassociated(&rdataset)); return (ISC_R_SUCCESS); } if (result != ISC_R_SUCCESS) { INSIST(!dns_rdataset_isassociated(&rdataset)); goto failure; } for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &rrsig, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (type != dns_rdatatype_dnskey) { isc_boolean_t warn = ISC_FALSE, deleted = ISC_FALSE; if (delsig_ok(&rrsig, keys, nkeys, &warn)) { result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, name, rdataset.ttl, &rdata); if (result != ISC_R_SUCCESS) break; deleted = ISC_TRUE; } if (warn) { /* * At this point, we've got an RRSIG, * which is signed by an inactive key. * An administrator needs to provide a new * key/alg, but until that time, we want to * keep the old RRSIG. Marking the key as * offline will prevent us spinning waiting * for the private part. */ if (incremental && !deleted) { result = offline(db, ver, zonediff, name, rdataset.ttl, &rdata); if (result != ISC_R_SUCCESS) break; } /* * Log the key id and algorithm of * the inactive key with no replacement */ if (zone->log_key_expired_timer <= now) { char origin[DNS_NAME_FORMATSIZE]; char algbuf[DNS_NAME_FORMATSIZE]; dns_name_format(&zone->origin, origin, sizeof(origin)); dns_secalg_format(rrsig.algorithm, algbuf, sizeof(algbuf)); dns_zone_log(zone, ISC_LOG_WARNING, "Key %s/%s/%d " "missing or inactive " "and has no replacement: " "retaining signatures.", origin, algbuf, rrsig.keyid); zone->log_key_expired_timer = now + 3600; } } continue; } /* * RRSIG(DNSKEY) requires special processing. */ found = ISC_FALSE; for (i = 0; i < nkeys; i++) { if (rrsig.algorithm == dst_key_alg(keys[i]) && rrsig.keyid == dst_key_id(keys[i])) { found = ISC_TRUE; /* * Mark offline RRSIG(DNSKEY). * We want the earliest offline expire time * iff there is a new offline signature. */ if (!dst_key_inactive(keys[i]) && !dst_key_isprivate(keys[i])) { isc_int64_t timeexpire = dns_time64_from32(rrsig.timeexpire); if (timewarn != 0 && timewarn > timeexpire) timewarn = timeexpire; if (rdata.flags & DNS_RDATA_OFFLINE) { if (timemaybe == 0 || timemaybe > timeexpire) timemaybe = timeexpire; break; } if (timewarn == 0) timewarn = timemaybe; if (timewarn == 0 || timewarn > timeexpire) timewarn = timeexpire; result = offline(db, ver, zonediff, name, rdataset.ttl, &rdata); break; } result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, name, rdataset.ttl, &rdata); break; } } /* * If there is not a matching DNSKEY then * delete the RRSIG. */ if (!found) result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, name, rdataset.ttl, &rdata); if (result != ISC_R_SUCCESS) break; } dns_rdataset_disassociate(&rdataset); if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; if (timewarn > 0) { #if defined(STDTIME_ON_32BITS) isc_stdtime_t stdwarn = (isc_stdtime_t)timewarn; if (timewarn == stdwarn) #endif set_key_expiry_warning(zone, (isc_stdtime_t)timewarn, now); #if defined(STDTIME_ON_32BITS) else dns_zone_log(zone, ISC_LOG_ERROR, "key expiry warning time out of range"); #endif } failure: if (node != NULL) dns_db_detachnode(db, &node); return (result); } static isc_result_t add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys, unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception, isc_stdtime_t expire, isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly) { isc_result_t result; dns_dbnode_t *node = NULL; dns_rdataset_t rdataset; dns_rdata_t sig_rdata = DNS_RDATA_INIT; unsigned char data[1024]; /* XXX */ isc_buffer_t buffer; unsigned int i, j; dns_rdataset_init(&rdataset); isc_buffer_init(&buffer, data, sizeof(data)); if (type == dns_rdatatype_nsec3) result = dns_db_findnsec3node(db, name, ISC_FALSE, &node); else result = dns_db_findnode(db, name, ISC_FALSE, &node); if (result == ISC_R_NOTFOUND) return (ISC_R_SUCCESS); if (result != ISC_R_SUCCESS) goto failure; result = dns_db_findrdataset(db, node, ver, type, 0, (isc_stdtime_t) 0, &rdataset, NULL); dns_db_detachnode(db, &node); if (result == ISC_R_NOTFOUND) { INSIST(!dns_rdataset_isassociated(&rdataset)); return (ISC_R_SUCCESS); } if (result != ISC_R_SUCCESS) { INSIST(!dns_rdataset_isassociated(&rdataset)); goto failure; } for (i = 0; i < nkeys; i++) { isc_boolean_t both = ISC_FALSE; if (!dst_key_isprivate(keys[i])) continue; if (check_ksk && !REVOKE(keys[i])) { isc_boolean_t have_ksk, have_nonksk; if (KSK(keys[i])) { have_ksk = ISC_TRUE; have_nonksk = ISC_FALSE; } else { have_ksk = ISC_FALSE; have_nonksk = ISC_TRUE; } for (j = 0; j < nkeys; j++) { if (j == i || ALG(keys[i]) != ALG(keys[j])) continue; if (REVOKE(keys[j])) continue; if (KSK(keys[j])) have_ksk = ISC_TRUE; else have_nonksk = ISC_TRUE; both = have_ksk && have_nonksk; if (both) break; } } if (both) { if (type == dns_rdatatype_dnskey) { if (!KSK(keys[i]) && keyset_kskonly) continue; } else if (KSK(keys[i])) continue; } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) continue; /* Calculate the signature, creating a RRSIG RDATA. */ isc_buffer_clear(&buffer); CHECK(dns_dnssec_sign(name, &rdataset, keys[i], &inception, &expire, mctx, &buffer, &sig_rdata)); /* Update the database and journal with the RRSIG. */ /* XXX inefficient - will cause dataset merging */ CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, name, rdataset.ttl, &sig_rdata)); dns_rdata_reset(&sig_rdata); isc_buffer_init(&buffer, data, sizeof(data)); } failure: if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (node != NULL) dns_db_detachnode(db, &node); return (result); } static void zone_resigninc(dns_zone_t *zone) { const char *me = "zone_resigninc"; dns_db_t *db = NULL; dns_dbversion_t *version = NULL; dns_diff_t _sig_diff; zonediff_t zonediff; dns_fixedname_t fixed; dns_name_t *name; dns_rdataset_t rdataset; dns_rdatatype_t covers; dst_key_t *zone_keys[DNS_MAXZONEKEYS]; isc_boolean_t check_ksk, keyset_kskonly = ISC_FALSE; isc_result_t result; isc_stdtime_t now, inception, soaexpire, expire, stop; isc_uint32_t jitter; unsigned int i; unsigned int nkeys = 0; unsigned int resign; ENTER; dns_rdataset_init(&rdataset); dns_fixedname_init(&fixed); dns_diff_init(zone->mctx, &_sig_diff); zonediff_init(&zonediff, &_sig_diff); /* * Zone is frozen or automatic resigning is disabled. * Pause for 5 minutes. */ if (zone->update_disabled || DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN)) { result = ISC_R_FAILURE; goto failure; } ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); dns_db_attach(zone->db, &db); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); result = dns_db_newversion(db, &version); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_resigninc:dns_db_newversion -> %s", dns_result_totext(result)); goto failure; } result = find_zone_keys(zone, db, version, zone->mctx, DNS_MAXZONEKEYS, zone_keys, &nkeys); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_resigninc:find_zone_keys -> %s", dns_result_totext(result)); goto failure; } isc_stdtime_get(&now); inception = now - 3600; /* Allow for clock skew. */ soaexpire = now + dns_zone_getsigvalidityinterval(zone); /* * Spread out signatures over time if they happen to be * clumped. We don't do this for each add_sigs() call as * we still want some clustering to occur. */ isc_random_get(&jitter); expire = soaexpire - jitter % 3600; stop = now + 5; check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); name = dns_fixedname_name(&fixed); result = dns_db_getsigningtime(db, &rdataset, name); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_resigninc:dns_db_getsigningtime -> %s", dns_result_totext(result)); } i = 0; while (result == ISC_R_SUCCESS) { resign = rdataset.resign - zone->sigresigninginterval; covers = rdataset.covers; dns_rdataset_disassociate(&rdataset); /* * Stop if we hit the SOA as that means we have walked the * entire zone. The SOA record should always be the most * recent signature. */ /* XXXMPA increase number of RRsets signed pre call */ if (covers == dns_rdatatype_soa || i++ > zone->signatures || resign > stop) break; result = del_sigs(zone, db, version, name, covers, &zonediff, zone_keys, nkeys, now, ISC_TRUE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_resigninc:del_sigs -> %s", dns_result_totext(result)); break; } result = add_sigs(db, version, name, covers, zonediff.diff, zone_keys, nkeys, zone->mctx, inception, expire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_resigninc:add_sigs -> %s", dns_result_totext(result)); break; } result = dns_db_getsigningtime(db, &rdataset, name); if (nkeys == 0 && result == ISC_R_NOTFOUND) { result = ISC_R_SUCCESS; break; } if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_ERROR, "zone_resigninc:dns_db_getsigningtime -> %s", dns_result_totext(result)); } if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS) goto failure; result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, &zonediff, zone_keys, nkeys, now, ISC_TRUE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_resigninc:del_sigs -> %s", dns_result_totext(result)); goto failure; } /* * Did we change anything in the zone? */ if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { /* * Commit the changes if any key has been marked as offline. */ if (zonediff.offline) dns_db_closeversion(db, &version, ISC_TRUE); goto failure; } /* Increment SOA serial if we have made changes */ result = update_soa_serial(db, version, zonediff.diff, zone->mctx, zone->updatemethod); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_resigninc:update_soa_serial -> %s", dns_result_totext(result)); goto failure; } /* * Generate maximum life time signatures so that the above loop * termination is sensible. */ result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, zonediff.diff, zone_keys, nkeys, zone->mctx, inception, soaexpire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_resigninc:add_sigs -> %s", dns_result_totext(result)); goto failure; } /* Write changes to journal file. */ CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc")); /* Everything has succeeded. Commit the changes. */ dns_db_closeversion(db, &version, ISC_TRUE); failure: dns_diff_clear(&_sig_diff); for (i = 0; i < nkeys; i++) dst_key_free(&zone_keys[i]); if (version != NULL) { dns_db_closeversion(zone->db, &version, ISC_FALSE); dns_db_detach(&db); } else if (db != NULL) dns_db_detach(&db); if (result == ISC_R_SUCCESS) { set_resigntime(zone); LOCK_ZONE(zone); zone_needdump(zone, DNS_DUMP_DELAY); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); UNLOCK_ZONE(zone); } else { /* * Something failed. Retry in 5 minutes. */ isc_interval_t ival; isc_interval_set(&ival, 300, 0); isc_time_nowplusinterval(&zone->resigntime, &ival); } INSIST(version == NULL); } static isc_result_t next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname, dns_name_t *newname, isc_boolean_t bottom) { isc_result_t result; dns_dbiterator_t *dbit = NULL; dns_rdatasetiter_t *rdsit = NULL; dns_dbnode_t *node = NULL; CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit)); CHECK(dns_dbiterator_seek(dbit, oldname)); do { result = dns_dbiterator_next(dbit); if (result == ISC_R_NOMORE) CHECK(dns_dbiterator_first(dbit)); CHECK(dns_dbiterator_current(dbit, &node, newname)); if (bottom && dns_name_issubdomain(newname, oldname) && !dns_name_equal(newname, oldname)) { dns_db_detachnode(db, &node); continue; } /* * Is this node empty? */ CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit)); result = dns_rdatasetiter_first(rdsit); dns_db_detachnode(db, &node); dns_rdatasetiter_destroy(&rdsit); if (result != ISC_R_NOMORE) break; } while (1); failure: if (node != NULL) dns_db_detachnode(db, &node); if (dbit != NULL) dns_dbiterator_destroy(&dbit); return (result); } static isc_boolean_t signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdatatype_t type, dst_key_t *key) { isc_result_t result; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_rrsig_t rrsig; dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig, type, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) { INSIST(!dns_rdataset_isassociated(&rdataset)); return (ISC_FALSE); } for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &rrsig, NULL); INSIST(result == ISC_R_SUCCESS); if (rrsig.algorithm == dst_key_alg(key) && rrsig.keyid == dst_key_id(key)) { dns_rdataset_disassociate(&rdataset); return (ISC_TRUE); } dns_rdata_reset(&rdata); } dns_rdataset_disassociate(&rdataset); return (ISC_FALSE); } static isc_result_t add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, dns_dbnode_t *node, dns_ttl_t ttl, isc_boolean_t bottom, dns_diff_t *diff) { dns_fixedname_t fixed; dns_name_t *next; dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE]; dns_fixedname_init(&fixed); next = dns_fixedname_name(&fixed); CHECK(next_active(db, version, name, next, bottom)); CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer, &rdata)); CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl, &rdata)); failure: return (result); } static isc_result_t sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node, dns_dbversion_t *version, isc_boolean_t build_nsec3, isc_boolean_t build_nsec, dst_key_t *key, isc_stdtime_t inception, isc_stdtime_t expire, unsigned int minimum, isc_boolean_t is_ksk, isc_boolean_t keyset_kskonly, isc_boolean_t *delegation, dns_diff_t *diff, isc_int32_t *signatures, isc_mem_t *mctx) { isc_result_t result; dns_rdatasetiter_t *iterator = NULL; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; isc_buffer_t buffer; unsigned char data[1024]; isc_boolean_t seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec, seen_nsec3, seen_ds; isc_boolean_t bottom; result = dns_db_allrdatasets(db, node, version, 0, &iterator); if (result != ISC_R_SUCCESS) { if (result == ISC_R_NOTFOUND) result = ISC_R_SUCCESS; return (result); } dns_rdataset_init(&rdataset); isc_buffer_init(&buffer, data, sizeof(data)); seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec = seen_nsec3 = seen_ds = ISC_FALSE; for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(iterator)) { dns_rdatasetiter_current(iterator, &rdataset); if (rdataset.type == dns_rdatatype_soa) seen_soa = ISC_TRUE; else if (rdataset.type == dns_rdatatype_ns) seen_ns = ISC_TRUE; else if (rdataset.type == dns_rdatatype_ds) seen_ds = ISC_TRUE; else if (rdataset.type == dns_rdatatype_dname) seen_dname = ISC_TRUE; else if (rdataset.type == dns_rdatatype_nsec) seen_nsec = ISC_TRUE; else if (rdataset.type == dns_rdatatype_nsec3) seen_nsec3 = ISC_TRUE; if (rdataset.type != dns_rdatatype_rrsig) seen_rr = ISC_TRUE; dns_rdataset_disassociate(&rdataset); } if (result != ISC_R_NOMORE) goto failure; if (seen_ns && !seen_soa) *delegation = ISC_TRUE; /* * Going from insecure to NSEC3. * Don't generate NSEC3 records for NSEC3 records. */ if (build_nsec3 && !seen_nsec3 && seen_rr) { isc_boolean_t unsecure = !seen_ds && seen_ns && !seen_soa; CHECK(dns_nsec3_addnsec3s(db, version, name, minimum, unsecure, diff)); (*signatures)--; } /* * Going from insecure to NSEC. * Don't generate NSEC records for NSEC3 records. */ if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) { /* Build and add NSEC. */ bottom = (seen_ns && !seen_soa) || seen_dname; /* * Build a NSEC record except at the origin. */ if (!dns_name_equal(name, dns_db_origin(db))) { CHECK(add_nsec(db, version, name, node, minimum, bottom, diff)); /* Count a NSEC generation as a signature generation. */ (*signatures)--; } } result = dns_rdatasetiter_first(iterator); while (result == ISC_R_SUCCESS) { dns_rdatasetiter_current(iterator, &rdataset); if (rdataset.type == dns_rdatatype_soa || rdataset.type == dns_rdatatype_rrsig) goto next_rdataset; if (rdataset.type == dns_rdatatype_dnskey) { if (!is_ksk && keyset_kskonly) goto next_rdataset; } else if (is_ksk) { /* * CDS and CDNSKEY are signed with KSK (RFC 7344, 4.1). */ if (rdataset.type != dns_rdatatype_cds && rdataset.type != dns_rdatatype_cdnskey) goto next_rdataset; } if (*delegation && rdataset.type != dns_rdatatype_ds && rdataset.type != dns_rdatatype_nsec) goto next_rdataset; if (signed_with_key(db, node, version, rdataset.type, key)) goto next_rdataset; /* Calculate the signature, creating a RRSIG RDATA. */ isc_buffer_clear(&buffer); CHECK(dns_dnssec_sign(name, &rdataset, key, &inception, &expire, mctx, &buffer, &rdata)); /* Update the database and journal with the RRSIG. */ /* XXX inefficient - will cause dataset merging */ CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN, name, rdataset.ttl, &rdata)); dns_rdata_reset(&rdata); (*signatures)--; next_rdataset: dns_rdataset_disassociate(&rdataset); result = dns_rdatasetiter_next(iterator); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; if (seen_dname) *delegation = ISC_TRUE; failure: if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (iterator != NULL) dns_rdatasetiter_destroy(&iterator); return (result); } /* * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist. */ static isc_result_t updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, dns_ttl_t minimum, isc_boolean_t update_only, dns_diff_t *diff) { isc_result_t result; dns_rdataset_t rdataset; dns_dbnode_t *node = NULL; CHECK(dns_db_getoriginnode(db, &node)); if (update_only) { dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec, dns_rdatatype_none, 0, &rdataset, NULL); if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (result == ISC_R_NOTFOUND) goto success; if (result != ISC_R_SUCCESS) goto failure; } CHECK(delete_nsec(db, version, node, name, diff)); CHECK(add_nsec(db, version, name, node, minimum, ISC_FALSE, diff)); success: result = ISC_R_SUCCESS; failure: if (node != NULL) dns_db_detachnode(db, &node); return (result); } static isc_result_t updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing, dns_dbversion_t *version, isc_boolean_t build_nsec3, dns_ttl_t minimum, dns_diff_t *diff) { isc_result_t result; dns_dbnode_t *node = NULL; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; unsigned char data[5]; isc_boolean_t seen_done = ISC_FALSE; isc_boolean_t have_rr = ISC_FALSE; dns_rdataset_init(&rdataset); result = dns_db_getoriginnode(signing->db, &node); if (result != ISC_R_SUCCESS) goto failure; result = dns_db_findrdataset(signing->db, node, version, zone->privatetype, dns_rdatatype_none, 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) { INSIST(!dns_rdataset_isassociated(&rdataset)); result = ISC_R_SUCCESS; goto failure; } if (result != ISC_R_SUCCESS) { INSIST(!dns_rdataset_isassociated(&rdataset)); goto failure; } for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdataset_current(&rdataset, &rdata); /* * If we don't match the algorithm or keyid skip the record. */ if (rdata.length != 5 || rdata.data[0] != signing->algorithm || rdata.data[1] != ((signing->keyid >> 8) & 0xff) || rdata.data[2] != (signing->keyid & 0xff)) { have_rr = ISC_TRUE; dns_rdata_reset(&rdata); continue; } /* * We have a match. If we were signing (!signing->delete) * and we already have a record indicating that we have * finished signing (rdata.data[4] != 0) then keep it. * Otherwise it needs to be deleted as we have removed all * the signatures (signing->delete), so any record indicating * completion is now out of date, or we have finished signing * with the new record so we no longer need to remember that * we need to sign the zone with the matching key across a * nameserver re-start. */ if (!signing->delete && rdata.data[4] != 0) { seen_done = ISC_TRUE; have_rr = ISC_TRUE; } else CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_DEL, &zone->origin, rdataset.ttl, &rdata)); dns_rdata_reset(&rdata); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; if (!signing->delete && !seen_done) { /* * If we were signing then we need to indicate that we have * finished signing the zone with this key. If it is already * there we don't need to add it a second time. */ data[0] = signing->algorithm; data[1] = (signing->keyid >> 8) & 0xff; data[2] = signing->keyid & 0xff; data[3] = 0; data[4] = 1; rdata.length = sizeof(data); rdata.data = data; rdata.type = zone->privatetype; rdata.rdclass = dns_db_class(signing->db); CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD, &zone->origin, rdataset.ttl, &rdata)); } else if (!have_rr) { dns_name_t *origin = dns_db_origin(signing->db); /* * Rebuild the NSEC/NSEC3 record for the origin as we no * longer have any private records. */ if (build_nsec3) CHECK(dns_nsec3_addnsec3s(signing->db, version, origin, minimum, ISC_FALSE, diff)); CHECK(updatesecure(signing->db, version, origin, minimum, ISC_TRUE, diff)); } failure: if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (node != NULL) dns_db_detachnode(signing->db, &node); return (result); } /* * If 'active' is set then we are not done with the chain yet so only * delete the nsec3param record which indicates a full chain exists * (flags == 0). */ static isc_result_t fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain, isc_boolean_t active, dns_rdatatype_t privatetype, dns_diff_t *diff) { dns_dbnode_t *node = NULL; dns_name_t *name = dns_db_origin(db); dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_t rdataset; dns_rdata_nsec3param_t nsec3param; isc_result_t result; isc_buffer_t buffer; unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE]; dns_ttl_t ttl = 0; isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE; dns_rdataset_init(&rdataset); result = dns_db_getoriginnode(db, &node); RUNTIME_CHECK(result == ISC_R_SUCCESS); result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0, 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) goto try_private; if (result != ISC_R_SUCCESS) goto failure; /* * Preserve the existing ttl. */ ttl = rdataset.ttl; /* * Delete all NSEC3PARAM records which match that in nsec3chain. */ for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdataset_current(&rdataset, &rdata); CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); if (nsec3param.hash != chain->nsec3param.hash || (active && nsec3param.flags != 0) || nsec3param.iterations != chain->nsec3param.iterations || nsec3param.salt_length != chain->nsec3param.salt_length || memcmp(nsec3param.salt, chain->nsec3param.salt, nsec3param.salt_length)) { dns_rdata_reset(&rdata); continue; } CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, rdataset.ttl, &rdata)); dns_rdata_reset(&rdata); } if (result != ISC_R_NOMORE) goto failure; dns_rdataset_disassociate(&rdataset); try_private: if (active) goto add; result = dns_nsec_nseconly(db, ver, &nseconly); nsec3ok = (result == ISC_R_SUCCESS && !nseconly); /* * Delete all private records which match that in nsec3chain. */ result = dns_db_findrdataset(db, node, ver, privatetype, 0, 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) goto add; if (result != ISC_R_SUCCESS) goto failure; for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t private = DNS_RDATA_INIT; unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; dns_rdataset_current(&rdataset, &private); if (!dns_nsec3param_fromprivate(&private, &rdata, buf, sizeof(buf))) continue; CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); if ((!nsec3ok && (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) || nsec3param.hash != chain->nsec3param.hash || nsec3param.iterations != chain->nsec3param.iterations || nsec3param.salt_length != chain->nsec3param.salt_length || memcmp(nsec3param.salt, chain->nsec3param.salt, nsec3param.salt_length)) { dns_rdata_reset(&rdata); continue; } CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, rdataset.ttl, &private)); dns_rdata_reset(&rdata); } if (result != ISC_R_NOMORE) goto failure; add: if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) { result = ISC_R_SUCCESS; goto failure; } /* * Add a NSEC3PARAM record which matches that in nsec3chain but * with all flags bits cleared. * * Note: we do not clear chain->nsec3param.flags as this change * may be reversed. */ isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf)); CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db), dns_rdatatype_nsec3param, &chain->nsec3param, &buffer)); rdata.data[1] = 0; /* Clear flag bits. */ CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata)); failure: dns_db_detachnode(db, &node); if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); return (result); } static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, dns_name_t *name, dns_diff_t *diff) { dns_rdataset_t rdataset; isc_result_t result; dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) return (ISC_R_SUCCESS); if (result != ISC_R_SUCCESS) return (result); for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, rdataset.ttl, &rdata)); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; failure: dns_rdataset_disassociate(&rdataset); return (result); } static isc_result_t deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, dns_name_t *name, const dns_rdata_nsec3param_t *param, dns_diff_t *diff) { dns_rdataset_t rdataset; dns_rdata_nsec3_t nsec3; isc_result_t result; dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, 0, 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) return (ISC_R_SUCCESS); if (result != ISC_R_SUCCESS) return (result); for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL)); if (nsec3.hash != param->hash || nsec3.iterations != param->iterations || nsec3.salt_length != param->salt_length || memcmp(nsec3.salt, param->salt, nsec3.salt_length)) continue; CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, rdataset.ttl, &rdata)); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; failure: dns_rdataset_disassociate(&rdataset); return (result); } static isc_result_t need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver, const dns_rdata_nsec3param_t *param, isc_boolean_t *answer) { dns_dbnode_t *node = NULL; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_nsec3param_t myparam; dns_rdataset_t rdataset; isc_result_t result; *answer = ISC_FALSE; result = dns_db_getoriginnode(db, &node); RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, 0, &rdataset, NULL); if (result == ISC_R_SUCCESS) { dns_rdataset_disassociate(&rdataset); dns_db_detachnode(db, &node); return (result); } if (result != ISC_R_NOTFOUND) { dns_db_detachnode(db, &node); return (result); } result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0, 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) { *answer = ISC_TRUE; dns_db_detachnode(db, &node); return (ISC_R_SUCCESS); } if (result != ISC_R_SUCCESS) { dns_db_detachnode(db, &node); return (result); } for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdataset_current(&rdataset, &rdata); CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL)); dns_rdata_reset(&rdata); /* * Ignore any NSEC3PARAM removals. */ if (NSEC3REMOVE(myparam.flags)) continue; /* * Ignore the chain that we are in the process of deleting. */ if (myparam.hash == param->hash && myparam.iterations == param->iterations && myparam.salt_length == param->salt_length && !memcmp(myparam.salt, param->salt, myparam.salt_length)) continue; /* * Found an active NSEC3 chain. */ break; } if (result == ISC_R_NOMORE) { *answer = ISC_TRUE; result = ISC_R_SUCCESS; } failure: if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); dns_db_detachnode(db, &node); return (result); } static isc_result_t update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, dst_key_t *zone_keys[], unsigned int nkeys, dns_zone_t *zone, isc_stdtime_t inception, isc_stdtime_t expire, isc_stdtime_t now, isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly, zonediff_t *zonediff) { dns_difftuple_t *tuple; isc_result_t result; for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; tuple = ISC_LIST_HEAD(diff->tuples)) { result = del_sigs(zone, db, version, &tuple->name, tuple->rdata.type, zonediff, zone_keys, nkeys, now, ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "update_sigs:del_sigs -> %s", dns_result_totext(result)); return (result); } result = add_sigs(db, version, &tuple->name, tuple->rdata.type, zonediff->diff, zone_keys, nkeys, zone->mctx, inception, expire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "update_sigs:add_sigs -> %s", dns_result_totext(result)); return (result); } do { dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link); while (next != NULL && (tuple->rdata.type != next->rdata.type || !dns_name_equal(&tuple->name, &next->name))) next = ISC_LIST_NEXT(next, link); ISC_LIST_UNLINK(diff->tuples, tuple, link); dns_diff_appendminimal(zonediff->diff, &tuple); INSIST(tuple == NULL); tuple = next; } while (tuple != NULL); } return (ISC_R_SUCCESS); } /* * Incrementally build and sign a new NSEC3 chain using the parameters * requested. */ static void zone_nsec3chain(dns_zone_t *zone) { const char *me = "zone_nsec3chain"; dns_db_t *db = NULL; dns_dbnode_t *node = NULL; dns_dbversion_t *version = NULL; dns_diff_t _sig_diff; dns_diff_t nsec_diff; dns_diff_t nsec3_diff; dns_diff_t param_diff; zonediff_t zonediff; dns_fixedname_t fixed; dns_fixedname_t nextfixed; dns_name_t *name, *nextname; dns_rdataset_t rdataset; dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain; dns_nsec3chainlist_t cleanup; dst_key_t *zone_keys[DNS_MAXZONEKEYS]; isc_int32_t signatures; isc_boolean_t check_ksk, keyset_kskonly; isc_boolean_t delegation; isc_boolean_t first; isc_result_t result; isc_stdtime_t now, inception, soaexpire, expire; isc_uint32_t jitter; unsigned int i; unsigned int nkeys = 0; isc_uint32_t nodes; isc_boolean_t unsecure = ISC_FALSE; isc_boolean_t seen_soa, seen_ns, seen_dname, seen_ds; isc_boolean_t seen_nsec, seen_nsec3, seen_rr; dns_rdatasetiter_t *iterator = NULL; isc_boolean_t buildnsecchain; isc_boolean_t updatensec = ISC_FALSE; dns_rdatatype_t privatetype = zone->privatetype; ENTER; dns_rdataset_init(&rdataset); dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); dns_fixedname_init(&nextfixed); nextname = dns_fixedname_name(&nextfixed); dns_diff_init(zone->mctx, ¶m_diff); dns_diff_init(zone->mctx, &nsec3_diff); dns_diff_init(zone->mctx, &nsec_diff); dns_diff_init(zone->mctx, &_sig_diff); zonediff_init(&zonediff, &_sig_diff); ISC_LIST_INIT(cleanup); /* * Updates are disabled. Pause for 5 minutes. */ if (zone->update_disabled) { result = ISC_R_FAILURE; goto failure; } ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); dns_db_attach(zone->db, &db); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); result = dns_db_newversion(db, &version); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:dns_db_newversion -> %s", dns_result_totext(result)); goto failure; } result = find_zone_keys(zone, db, version, zone->mctx, DNS_MAXZONEKEYS, zone_keys, &nkeys); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:find_zone_keys -> %s", dns_result_totext(result)); goto failure; } isc_stdtime_get(&now); inception = now - 3600; /* Allow for clock skew. */ soaexpire = now + dns_zone_getsigvalidityinterval(zone); /* * Spread out signatures over time if they happen to be * clumped. We don't do this for each add_sigs() call as * we still want some clustering to occur. */ isc_random_get(&jitter); expire = soaexpire - jitter % 3600; check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); /* * We keep pulling nodes off each iterator in turn until * we have no more nodes to pull off or we reach the limits * for this quantum. */ nodes = zone->nodes; signatures = zone->signatures; LOCK_ZONE(zone); nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); UNLOCK_ZONE(zone); first = ISC_TRUE; if (nsec3chain != NULL) nsec3chain->save_delete_nsec = nsec3chain->delete_nsec; /* * Generate new NSEC3 chains first. */ while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) { LOCK_ZONE(zone); nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (nsec3chain->done || nsec3chain->db != zone->db) { ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link); ISC_LIST_APPEND(cleanup, nsec3chain, link); } ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); UNLOCK_ZONE(zone); if (ISC_LIST_TAIL(cleanup) == nsec3chain) goto next_addchain; /* * Possible future db. */ if (nsec3chain->db != db) { goto next_addchain; } if (NSEC3REMOVE(nsec3chain->nsec3param.flags)) goto next_addchain; dns_dbiterator_current(nsec3chain->dbiterator, &node, name); if (nsec3chain->delete_nsec) { delegation = ISC_FALSE; dns_dbiterator_pause(nsec3chain->dbiterator); CHECK(delete_nsec(db, version, node, name, &nsec_diff)); goto next_addnode; } /* * On the first pass we need to check if the current node * has not been obscured. */ delegation = ISC_FALSE; unsecure = ISC_FALSE; if (first) { dns_fixedname_t ffound; dns_name_t *found; dns_fixedname_init(&ffound); found = dns_fixedname_name(&ffound); result = dns_db_find(db, name, version, dns_rdatatype_soa, DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL); if ((result == DNS_R_DELEGATION || result == DNS_R_DNAME) && !dns_name_equal(name, found)) { /* * Remember the obscuring name so that * we skip all obscured names. */ dns_name_copy(found, name, NULL); delegation = ISC_TRUE; goto next_addnode; } } /* * Check to see if this is a bottom of zone node. */ result = dns_db_allrdatasets(db, node, version, 0, &iterator); if (result == ISC_R_NOTFOUND) /* Empty node? */ goto next_addnode; if (result != ISC_R_SUCCESS) goto failure; seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec = ISC_FALSE; for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(iterator)) { dns_rdatasetiter_current(iterator, &rdataset); INSIST(rdataset.type != dns_rdatatype_nsec3); if (rdataset.type == dns_rdatatype_soa) seen_soa = ISC_TRUE; else if (rdataset.type == dns_rdatatype_ns) seen_ns = ISC_TRUE; else if (rdataset.type == dns_rdatatype_dname) seen_dname = ISC_TRUE; else if (rdataset.type == dns_rdatatype_ds) seen_ds = ISC_TRUE; else if (rdataset.type == dns_rdatatype_nsec) seen_nsec = ISC_TRUE; dns_rdataset_disassociate(&rdataset); } dns_rdatasetiter_destroy(&iterator); /* * Is there a NSEC chain than needs to be cleaned up? */ if (seen_nsec) nsec3chain->seen_nsec = ISC_TRUE; if (seen_ns && !seen_soa && !seen_ds) unsecure = ISC_TRUE; if ((seen_ns && !seen_soa) || seen_dname) delegation = ISC_TRUE; /* * Process one node. */ dns_dbiterator_pause(nsec3chain->dbiterator); result = dns_nsec3_addnsec3(db, version, name, &nsec3chain->nsec3param, zone->minimum, unsecure, &nsec3_diff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "dns_nsec3_addnsec3 -> %s", dns_result_totext(result)); goto failure; } /* * Treat each call to dns_nsec3_addnsec3() as if it's cost is * two signatures. Additionally there will, in general, be * two signature generated below. * * If we are only changing the optout flag the cost is half * that of the cost of generating a completely new chain. */ signatures -= 4; /* * Go onto next node. */ next_addnode: first = ISC_FALSE; dns_db_detachnode(db, &node); do { result = dns_dbiterator_next(nsec3chain->dbiterator); if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) { dns_dbiterator_pause(nsec3chain->dbiterator); CHECK(fixup_nsec3param(db, version, nsec3chain, ISC_FALSE, privatetype, ¶m_diff)); LOCK_ZONE(zone); ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link); UNLOCK_ZONE(zone); ISC_LIST_APPEND(cleanup, nsec3chain, link); goto next_addchain; } if (result == ISC_R_NOMORE) { dns_dbiterator_pause(nsec3chain->dbiterator); if (nsec3chain->seen_nsec) { CHECK(fixup_nsec3param(db, version, nsec3chain, ISC_TRUE, privatetype, ¶m_diff)); nsec3chain->delete_nsec = ISC_TRUE; goto same_addchain; } CHECK(fixup_nsec3param(db, version, nsec3chain, ISC_FALSE, privatetype, ¶m_diff)); LOCK_ZONE(zone); ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link); UNLOCK_ZONE(zone); ISC_LIST_APPEND(cleanup, nsec3chain, link); goto next_addchain; } else if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "dns_dbiterator_next -> %s", dns_result_totext(result)); goto failure; } else if (delegation) { dns_dbiterator_current(nsec3chain->dbiterator, &node, nextname); dns_db_detachnode(db, &node); if (!dns_name_issubdomain(nextname, name)) break; } else break; } while (1); continue; same_addchain: CHECK(dns_dbiterator_first(nsec3chain->dbiterator)); first = ISC_TRUE; continue; next_addchain: dns_dbiterator_pause(nsec3chain->dbiterator); nsec3chain = nextnsec3chain; first = ISC_TRUE; if (nsec3chain != NULL) nsec3chain->save_delete_nsec = nsec3chain->delete_nsec; } /* * Process removals. */ LOCK_ZONE(zone); nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); UNLOCK_ZONE(zone); first = ISC_TRUE; buildnsecchain = ISC_FALSE; while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) { LOCK_ZONE(zone); nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link); UNLOCK_ZONE(zone); if (nsec3chain->db != db) goto next_removechain; if (!NSEC3REMOVE(nsec3chain->nsec3param.flags)) goto next_removechain; /* * Work out if we need to build a NSEC chain as a consequence * of removing this NSEC3 chain. */ if (first && !updatensec && (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0) { result = need_nsec_chain(db, version, &nsec3chain->nsec3param, &buildnsecchain); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "need_nsec_chain -> %s", dns_result_totext(result)); goto failure; } } if (first) dns_zone_log(zone, ISC_LOG_DEBUG(3), "zone_nsec3chain:" "buildnsecchain = %u\n", buildnsecchain); dns_dbiterator_current(nsec3chain->dbiterator, &node, name); delegation = ISC_FALSE; if (!buildnsecchain) { /* * Delete the NSECPARAM record that matches this chain. */ if (first) { result = fixup_nsec3param(db, version, nsec3chain, ISC_TRUE, privatetype, ¶m_diff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "fixup_nsec3param -> %s", dns_result_totext(result)); goto failure; } } /* * Delete the NSEC3 records. */ result = deletematchingnsec3(db, version, node, name, &nsec3chain->nsec3param, &nsec3_diff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "deletematchingnsec3 -> %s", dns_result_totext(result)); goto failure; } goto next_removenode; } if (first) { dns_fixedname_t ffound; dns_name_t *found; dns_fixedname_init(&ffound); found = dns_fixedname_name(&ffound); result = dns_db_find(db, name, version, dns_rdatatype_soa, DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL); if ((result == DNS_R_DELEGATION || result == DNS_R_DNAME) && !dns_name_equal(name, found)) { /* * Remember the obscuring name so that * we skip all obscured names. */ dns_name_copy(found, name, NULL); delegation = ISC_TRUE; goto next_removenode; } } /* * Check to see if this is a bottom of zone node. */ result = dns_db_allrdatasets(db, node, version, 0, &iterator); if (result == ISC_R_NOTFOUND) /* Empty node? */ goto next_removenode; if (result != ISC_R_SUCCESS) goto failure; seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec = seen_rr = ISC_FALSE; for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(iterator)) { dns_rdatasetiter_current(iterator, &rdataset); if (rdataset.type == dns_rdatatype_soa) seen_soa = ISC_TRUE; else if (rdataset.type == dns_rdatatype_ns) seen_ns = ISC_TRUE; else if (rdataset.type == dns_rdatatype_dname) seen_dname = ISC_TRUE; else if (rdataset.type == dns_rdatatype_nsec) seen_nsec = ISC_TRUE; else if (rdataset.type == dns_rdatatype_nsec3) seen_nsec3 = ISC_TRUE; if (rdataset.type != dns_rdatatype_rrsig) seen_rr = ISC_TRUE; dns_rdataset_disassociate(&rdataset); } dns_rdatasetiter_destroy(&iterator); if (!seen_rr || seen_nsec3 || seen_nsec) goto next_removenode; if ((seen_ns && !seen_soa) || seen_dname) delegation = ISC_TRUE; /* * Add a NSEC record except at the origin. */ if (!dns_name_equal(name, dns_db_origin(db))) { dns_dbiterator_pause(nsec3chain->dbiterator); CHECK(add_nsec(db, version, name, node, zone->minimum, delegation, &nsec_diff)); } next_removenode: first = ISC_FALSE; dns_db_detachnode(db, &node); do { result = dns_dbiterator_next(nsec3chain->dbiterator); if (result == ISC_R_NOMORE && buildnsecchain) { /* * The NSEC chain should now be built. * We can now remove the NSEC3 chain. */ updatensec = ISC_TRUE; goto same_removechain; } if (result == ISC_R_NOMORE) { LOCK_ZONE(zone); ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link); UNLOCK_ZONE(zone); ISC_LIST_APPEND(cleanup, nsec3chain, link); dns_dbiterator_pause(nsec3chain->dbiterator); result = fixup_nsec3param(db, version, nsec3chain, ISC_FALSE, privatetype, ¶m_diff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "fixup_nsec3param -> %s", dns_result_totext(result)); goto failure; } goto next_removechain; } else if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "dns_dbiterator_next -> %s", dns_result_totext(result)); goto failure; } else if (delegation) { dns_dbiterator_current(nsec3chain->dbiterator, &node, nextname); dns_db_detachnode(db, &node); if (!dns_name_issubdomain(nextname, name)) break; } else break; } while (1); continue; same_removechain: CHECK(dns_dbiterator_first(nsec3chain->dbiterator)); buildnsecchain = ISC_FALSE; first = ISC_TRUE; continue; next_removechain: dns_dbiterator_pause(nsec3chain->dbiterator); nsec3chain = nextnsec3chain; first = ISC_TRUE; } /* * We may need to update the NSEC/NSEC3 records for the zone apex. */ if (!ISC_LIST_EMPTY(param_diff.tuples)) { isc_boolean_t rebuild_nsec = ISC_FALSE, rebuild_nsec3 = ISC_FALSE; result = dns_db_getoriginnode(db, &node); RUNTIME_CHECK(result == ISC_R_SUCCESS); result = dns_db_allrdatasets(db, node, version, 0, &iterator); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "dns_db_allrdatasets -> %s", dns_result_totext(result)); goto failure; } for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(iterator)) { dns_rdatasetiter_current(iterator, &rdataset); if (rdataset.type == dns_rdatatype_nsec) rebuild_nsec = ISC_TRUE; if (rdataset.type == dns_rdatatype_nsec3param) rebuild_nsec3 = ISC_TRUE; dns_rdataset_disassociate(&rdataset); } dns_rdatasetiter_destroy(&iterator); dns_db_detachnode(db, &node); if (rebuild_nsec) { if (nsec3chain != NULL) dns_dbiterator_pause(nsec3chain->dbiterator); result = updatesecure(db, version, &zone->origin, zone->minimum, ISC_TRUE, &nsec_diff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "updatesecure -> %s", dns_result_totext(result)); goto failure; } } if (rebuild_nsec3) { if (nsec3chain != NULL) dns_dbiterator_pause(nsec3chain->dbiterator); result = dns_nsec3_addnsec3s(db, version, dns_db_origin(db), zone->minimum, ISC_FALSE, &nsec3_diff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "dns_nsec3_addnsec3s -> %s", dns_result_totext(result)); goto failure; } } } if (nsec3chain != NULL) dns_dbiterator_pause(nsec3chain->dbiterator); /* * Add / update signatures for the NSEC3 records. */ if (nsec3chain != NULL) dns_dbiterator_pause(nsec3chain->dbiterator); result = update_sigs(&nsec3_diff, db, version, zone_keys, nkeys, zone, inception, expire, now, check_ksk, keyset_kskonly, &zonediff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "update_sigs -> %s", dns_result_totext(result)); goto failure; } /* * We have changed the NSEC3PARAM or private RRsets * above so we need to update the signatures. */ result = update_sigs(¶m_diff, db, version, zone_keys, nkeys, zone, inception, expire, now, check_ksk, keyset_kskonly, &zonediff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "update_sigs -> %s", dns_result_totext(result)); goto failure; } if (updatensec) { result = updatesecure(db, version, &zone->origin, zone->minimum, ISC_FALSE, &nsec_diff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "updatesecure -> %s", dns_result_totext(result)); goto failure; } } result = update_sigs(&nsec_diff, db, version, zone_keys, nkeys, zone, inception, expire, now, check_ksk, keyset_kskonly, &zonediff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "update_sigs -> %s", dns_result_totext(result)); goto failure; } /* * If we made no effective changes to the zone then we can just * cleanup otherwise we need to increment the serial. */ if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { /* * No need to call dns_db_closeversion() here as it is * called with commit = ISC_TRUE below. */ goto done; } result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, &zonediff, zone_keys, nkeys, now, ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "del_sigs -> %s", dns_result_totext(result)); goto failure; } result = update_soa_serial(db, version, zonediff.diff, zone->mctx, zone->updatemethod); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "update_soa_serial -> %s", dns_result_totext(result)); goto failure; } result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, zonediff.diff, zone_keys, nkeys, zone->mctx, inception, soaexpire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "add_sigs -> %s", dns_result_totext(result)); goto failure; } /* Write changes to journal file. */ CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain")); LOCK_ZONE(zone); zone_needdump(zone, DNS_DUMP_DELAY); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); UNLOCK_ZONE(zone); done: /* * Pause all iterators so that dns_db_closeversion() can succeed. */ LOCK_ZONE(zone); for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL; nsec3chain = ISC_LIST_NEXT(nsec3chain, link)) dns_dbiterator_pause(nsec3chain->dbiterator); UNLOCK_ZONE(zone); /* * Everything has succeeded. Commit the changes. * Unconditionally commit as zonediff.offline not checked above. */ dns_db_closeversion(db, &version, ISC_TRUE); /* * Everything succeeded so we can clean these up now. */ nsec3chain = ISC_LIST_HEAD(cleanup); while (nsec3chain != NULL) { ISC_LIST_UNLINK(cleanup, nsec3chain, link); dns_db_detach(&nsec3chain->db); dns_dbiterator_destroy(&nsec3chain->dbiterator); isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); nsec3chain = ISC_LIST_HEAD(cleanup); } set_resigntime(zone); failure: if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s", dns_result_totext(result)); /* * On error roll back the current nsec3chain. */ if (result != ISC_R_SUCCESS && nsec3chain != NULL) { if (nsec3chain->done) { dns_db_detach(&nsec3chain->db); dns_dbiterator_destroy(&nsec3chain->dbiterator); isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); } else { result = dns_dbiterator_first(nsec3chain->dbiterator); RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_dbiterator_pause(nsec3chain->dbiterator); nsec3chain->delete_nsec = nsec3chain->save_delete_nsec; } } /* * Rollback the cleanup list. */ nsec3chain = ISC_LIST_TAIL(cleanup); while (nsec3chain != NULL) { ISC_LIST_UNLINK(cleanup, nsec3chain, link); if (nsec3chain->done) { dns_db_detach(&nsec3chain->db); dns_dbiterator_destroy(&nsec3chain->dbiterator); isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); } else { LOCK_ZONE(zone); ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link); UNLOCK_ZONE(zone); result = dns_dbiterator_first(nsec3chain->dbiterator); RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_dbiterator_pause(nsec3chain->dbiterator); nsec3chain->delete_nsec = nsec3chain->save_delete_nsec; } nsec3chain = ISC_LIST_TAIL(cleanup); } LOCK_ZONE(zone); for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL; nsec3chain = ISC_LIST_NEXT(nsec3chain, link)) dns_dbiterator_pause(nsec3chain->dbiterator); UNLOCK_ZONE(zone); dns_diff_clear(¶m_diff); dns_diff_clear(&nsec3_diff); dns_diff_clear(&nsec_diff); dns_diff_clear(&_sig_diff); if (iterator != NULL) dns_rdatasetiter_destroy(&iterator); for (i = 0; i < nkeys; i++) dst_key_free(&zone_keys[i]); if (node != NULL) dns_db_detachnode(db, &node); if (version != NULL) { dns_db_closeversion(db, &version, ISC_FALSE); dns_db_detach(&db); } else if (db != NULL) dns_db_detach(&db); LOCK_ZONE(zone); if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) { isc_interval_t interval; if (zone->update_disabled || result != ISC_R_SUCCESS) isc_interval_set(&interval, 60, 0); /* 1 minute */ else isc_interval_set(&interval, 0, 10000000); /* 10 ms */ isc_time_nowplusinterval(&zone->nsec3chaintime, &interval); } else isc_time_settoepoch(&zone->nsec3chaintime); UNLOCK_ZONE(zone); INSIST(version == NULL); } static isc_result_t del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm, isc_uint16_t keyid, dns_diff_t *diff) { dns_rdata_rrsig_t rrsig; dns_rdataset_t rdataset; dns_rdatasetiter_t *iterator = NULL; isc_result_t result; result = dns_db_allrdatasets(db, node, version, 0, &iterator); if (result != ISC_R_SUCCESS) { if (result == ISC_R_NOTFOUND) result = ISC_R_SUCCESS; return (result); } dns_rdataset_init(&rdataset); for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(iterator)) { dns_rdatasetiter_current(iterator, &rdataset); if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) { for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_DEL, name, rdataset.ttl, &rdata)); } if (result != ISC_R_NOMORE) goto failure; dns_rdataset_disassociate(&rdataset); continue; } if (rdataset.type != dns_rdatatype_rrsig) { dns_rdataset_disassociate(&rdataset); continue; } for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL)); if (rrsig.algorithm != algorithm || rrsig.keyid != keyid) continue; CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_DELRESIGN, name, rdataset.ttl, &rdata)); } dns_rdataset_disassociate(&rdataset); if (result != ISC_R_NOMORE) break; } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; failure: if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); dns_rdatasetiter_destroy(&iterator); return (result); } /* * Incrementally sign the zone using the keys requested. * Builds the NSEC chain if required. */ static void zone_sign(dns_zone_t *zone) { const char *me = "zone_sign"; dns_db_t *db = NULL; dns_dbnode_t *node = NULL; dns_dbversion_t *version = NULL; dns_diff_t _sig_diff; dns_diff_t post_diff; zonediff_t zonediff; dns_fixedname_t fixed; dns_fixedname_t nextfixed; dns_name_t *name, *nextname; dns_rdataset_t rdataset; dns_signing_t *signing, *nextsigning; dns_signinglist_t cleanup; dst_key_t *zone_keys[DNS_MAXZONEKEYS]; isc_int32_t signatures; isc_boolean_t check_ksk, keyset_kskonly, is_ksk; isc_boolean_t commit = ISC_FALSE; isc_boolean_t delegation; isc_boolean_t build_nsec = ISC_FALSE; isc_boolean_t build_nsec3 = ISC_FALSE; isc_boolean_t first; isc_result_t result; isc_stdtime_t now, inception, soaexpire, expire; isc_uint32_t jitter; unsigned int i, j; unsigned int nkeys = 0; isc_uint32_t nodes; ENTER; dns_rdataset_init(&rdataset); dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); dns_fixedname_init(&nextfixed); nextname = dns_fixedname_name(&nextfixed); dns_diff_init(zone->mctx, &_sig_diff); dns_diff_init(zone->mctx, &post_diff); zonediff_init(&zonediff, &_sig_diff); ISC_LIST_INIT(cleanup); /* * Updates are disabled. Pause for 5 minutes. */ if (zone->update_disabled) { result = ISC_R_FAILURE; goto failure; } ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) dns_db_attach(zone->db, &db); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); if (db == NULL) { result = ISC_R_FAILURE; goto failure; } result = dns_db_newversion(db, &version); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:dns_db_newversion -> %s", dns_result_totext(result)); goto failure; } result = find_zone_keys(zone, db, version, zone->mctx, DNS_MAXZONEKEYS, zone_keys, &nkeys); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:find_zone_keys -> %s", dns_result_totext(result)); goto failure; } isc_stdtime_get(&now); inception = now - 3600; /* Allow for clock skew. */ soaexpire = now + dns_zone_getsigvalidityinterval(zone); /* * Spread out signatures over time if they happen to be * clumped. We don't do this for each add_sigs() call as * we still want some clustering to occur. */ isc_random_get(&jitter); expire = soaexpire - jitter % 3600; /* * We keep pulling nodes off each iterator in turn until * we have no more nodes to pull off or we reach the limits * for this quantum. */ nodes = zone->nodes; signatures = zone->signatures; signing = ISC_LIST_HEAD(zone->signing); first = ISC_TRUE; check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); /* Determine which type of chain to build */ CHECK(dns_private_chains(db, version, zone->privatetype, &build_nsec, &build_nsec3)); /* If neither chain is found, default to NSEC */ if (!build_nsec && !build_nsec3) build_nsec = ISC_TRUE; while (signing != NULL && nodes-- > 0 && signatures > 0) { nextsigning = ISC_LIST_NEXT(signing, link); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (signing->done || signing->db != zone->db) { /* * The zone has been reloaded. We will have * created new signings as part of the reload * process so we can destroy this one. */ ISC_LIST_UNLINK(zone->signing, signing, link); ISC_LIST_APPEND(cleanup, signing, link); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); goto next_signing; } ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); if (signing->db != db) goto next_signing; delegation = ISC_FALSE; if (first && signing->delete) { /* * Remove the key we are deleting from consideration. */ for (i = 0, j = 0; i < nkeys; i++) { /* * Find the key we want to remove. */ if (ALG(zone_keys[i]) == signing->algorithm && dst_key_id(zone_keys[i]) == signing->keyid) { if (KSK(zone_keys[i])) dst_key_free(&zone_keys[i]); continue; } zone_keys[j] = zone_keys[i]; j++; } nkeys = j; } dns_dbiterator_current(signing->dbiterator, &node, name); if (signing->delete) { dns_dbiterator_pause(signing->dbiterator); CHECK(del_sig(db, version, name, node, nkeys, signing->algorithm, signing->keyid, zonediff.diff)); } /* * On the first pass we need to check if the current node * has not been obscured. */ if (first) { dns_fixedname_t ffound; dns_name_t *found; dns_fixedname_init(&ffound); found = dns_fixedname_name(&ffound); result = dns_db_find(db, name, version, dns_rdatatype_soa, DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL); if ((result == DNS_R_DELEGATION || result == DNS_R_DNAME) && !dns_name_equal(name, found)) { /* * Remember the obscuring name so that * we skip all obscured names. */ dns_name_copy(found, name, NULL); delegation = ISC_TRUE; goto next_node; } } /* * Process one node. */ dns_dbiterator_pause(signing->dbiterator); for (i = 0; i < nkeys; i++) { isc_boolean_t both = ISC_FALSE; /* * Find the keys we want to sign with. */ if (!dst_key_isprivate(zone_keys[i])) continue; /* * When adding look for the specific key. */ if (!signing->delete && (dst_key_alg(zone_keys[i]) != signing->algorithm || dst_key_id(zone_keys[i]) != signing->keyid)) continue; /* * When deleting make sure we are properly signed * with the algorithm that was being removed. */ if (signing->delete && ALG(zone_keys[i]) != signing->algorithm) continue; /* * Do we do KSK processing? */ if (check_ksk && !REVOKE(zone_keys[i])) { isc_boolean_t have_ksk, have_nonksk; if (KSK(zone_keys[i])) { have_ksk = ISC_TRUE; have_nonksk = ISC_FALSE; } else { have_ksk = ISC_FALSE; have_nonksk = ISC_TRUE; } for (j = 0; j < nkeys; j++) { if (j == i || ALG(zone_keys[i]) != ALG(zone_keys[j])) continue; if (REVOKE(zone_keys[j])) continue; if (KSK(zone_keys[j])) have_ksk = ISC_TRUE; else have_nonksk = ISC_TRUE; both = have_ksk && have_nonksk; if (both) break; } } if (both || REVOKE(zone_keys[i])) is_ksk = KSK(zone_keys[i]); else is_ksk = ISC_FALSE; CHECK(sign_a_node(db, name, node, version, build_nsec3, build_nsec, zone_keys[i], inception, expire, zone->minimum, is_ksk, ISC_TF(both && keyset_kskonly), &delegation, zonediff.diff, &signatures, zone->mctx)); /* * If we are adding we are done. Look for other keys * of the same algorithm if deleting. */ if (!signing->delete) break; } /* * Go onto next node. */ next_node: first = ISC_FALSE; dns_db_detachnode(db, &node); do { result = dns_dbiterator_next(signing->dbiterator); if (result == ISC_R_NOMORE) { ISC_LIST_UNLINK(zone->signing, signing, link); ISC_LIST_APPEND(cleanup, signing, link); dns_dbiterator_pause(signing->dbiterator); if (nkeys != 0 && build_nsec) { /* * We have finished regenerating the * zone with a zone signing key. * The NSEC chain is now complete and * there is a full set of signatures * for the zone. We can now clear the * OPT bit from the NSEC record. */ result = updatesecure(db, version, &zone->origin, zone->minimum, ISC_FALSE, &post_diff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "updatesecure -> %s", dns_result_totext(result)); goto failure; } } result = updatesignwithkey(zone, signing, version, build_nsec3, zone->minimum, &post_diff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "updatesignwithkey -> %s", dns_result_totext(result)); goto failure; } build_nsec = ISC_FALSE; goto next_signing; } else if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:dns_dbiterator_next -> %s", dns_result_totext(result)); goto failure; } else if (delegation) { dns_dbiterator_current(signing->dbiterator, &node, nextname); dns_db_detachnode(db, &node); if (!dns_name_issubdomain(nextname, name)) break; } else break; } while (1); continue; next_signing: dns_dbiterator_pause(signing->dbiterator); signing = nextsigning; first = ISC_TRUE; } if (ISC_LIST_HEAD(post_diff.tuples) != NULL) { result = update_sigs(&post_diff, db, version, zone_keys, nkeys, zone, inception, expire, now, check_ksk, keyset_kskonly, &zonediff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:" "update_sigs -> %s", dns_result_totext(result)); goto failure; } } /* * Have we changed anything? */ if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { if (zonediff.offline) commit = ISC_TRUE; result = ISC_R_SUCCESS; goto pauseall; } commit = ISC_TRUE; result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, &zonediff, zone_keys, nkeys, now, ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:del_sigs -> %s", dns_result_totext(result)); goto failure; } result = update_soa_serial(db, version, zonediff.diff, zone->mctx, zone->updatemethod); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:update_soa_serial -> %s", dns_result_totext(result)); goto failure; } /* * Generate maximum life time signatures so that the above loop * termination is sensible. */ result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, zonediff.diff, zone_keys, nkeys, zone->mctx, inception, soaexpire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:add_sigs -> %s", dns_result_totext(result)); goto failure; } /* * Write changes to journal file. */ CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign")); pauseall: /* * Pause all iterators so that dns_db_closeversion() can succeed. */ for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL; signing = ISC_LIST_NEXT(signing, link)) dns_dbiterator_pause(signing->dbiterator); for (signing = ISC_LIST_HEAD(cleanup); signing != NULL; signing = ISC_LIST_NEXT(signing, link)) dns_dbiterator_pause(signing->dbiterator); /* * Everything has succeeded. Commit the changes. */ dns_db_closeversion(db, &version, commit); /* * Everything succeeded so we can clean these up now. */ signing = ISC_LIST_HEAD(cleanup); while (signing != NULL) { ISC_LIST_UNLINK(cleanup, signing, link); dns_db_detach(&signing->db); dns_dbiterator_destroy(&signing->dbiterator); isc_mem_put(zone->mctx, signing, sizeof *signing); signing = ISC_LIST_HEAD(cleanup); } set_resigntime(zone); if (commit) { LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); zone_needdump(zone, DNS_DUMP_DELAY); UNLOCK_ZONE(zone); } failure: /* * Rollback the cleanup list. */ signing = ISC_LIST_HEAD(cleanup); while (signing != NULL) { ISC_LIST_UNLINK(cleanup, signing, link); ISC_LIST_PREPEND(zone->signing, signing, link); dns_dbiterator_first(signing->dbiterator); dns_dbiterator_pause(signing->dbiterator); signing = ISC_LIST_HEAD(cleanup); } for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL; signing = ISC_LIST_NEXT(signing, link)) dns_dbiterator_pause(signing->dbiterator); dns_diff_clear(&_sig_diff); for (i = 0; i < nkeys; i++) dst_key_free(&zone_keys[i]); if (node != NULL) dns_db_detachnode(db, &node); if (version != NULL) { dns_db_closeversion(db, &version, ISC_FALSE); dns_db_detach(&db); } else if (db != NULL) dns_db_detach(&db); if (ISC_LIST_HEAD(zone->signing) != NULL) { isc_interval_t interval; if (zone->update_disabled || result != ISC_R_SUCCESS) isc_interval_set(&interval, 60, 0); /* 1 minute */ else isc_interval_set(&interval, 0, 10000000); /* 10 ms */ isc_time_nowplusinterval(&zone->signingtime, &interval); } else isc_time_settoepoch(&zone->signingtime); INSIST(version == NULL); } static isc_result_t normalize_key(dns_rdata_t *rr, dns_rdata_t *target, unsigned char *data, int size) { dns_rdata_dnskey_t dnskey; dns_rdata_keydata_t keydata; isc_buffer_t buf; isc_result_t result; dns_rdata_reset(target); isc_buffer_init(&buf, data, size); switch (rr->type) { case dns_rdatatype_dnskey: result = dns_rdata_tostruct(rr, &dnskey, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); dnskey.flags &= ~DNS_KEYFLAG_REVOKE; dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, &dnskey, &buf); break; case dns_rdatatype_keydata: result = dns_rdata_tostruct(rr, &keydata, NULL); if (result == ISC_R_UNEXPECTEDEND) return (result); RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_keydata_todnskey(&keydata, &dnskey, NULL); dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, &dnskey, &buf); break; default: INSIST(0); } return (ISC_R_SUCCESS); } /* * 'rdset' contains either a DNSKEY rdataset from the zone apex, or * a KEYDATA rdataset from the key zone. * * 'rr' contains either a DNSKEY record, or a KEYDATA record * * After normalizing keys to the same format (DNSKEY, with revoke bit * cleared), return ISC_TRUE if a key that matches 'rr' is found in * 'rdset', or ISC_FALSE if not. */ static isc_boolean_t matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) { unsigned char data1[4096], data2[4096]; dns_rdata_t rdata, rdata1, rdata2; isc_result_t result; dns_rdata_init(&rdata); dns_rdata_init(&rdata1); dns_rdata_init(&rdata2); result = normalize_key(rr, &rdata1, data1, sizeof(data1)); if (result != ISC_R_SUCCESS) return (ISC_FALSE); for (result = dns_rdataset_first(rdset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdset)) { dns_rdata_reset(&rdata); dns_rdataset_current(rdset, &rdata); result = normalize_key(&rdata, &rdata2, data2, sizeof(data2)); if (result != ISC_R_SUCCESS) continue; if (dns_rdata_compare(&rdata1, &rdata2) == 0) return (ISC_TRUE); } return (ISC_FALSE); } /* * Calculate the refresh interval for a keydata zone, per * RFC5011: MAX(1 hr, * MIN(15 days, * 1/2 * OrigTTL, * 1/2 * RRSigExpirationInterval)) * or for retries: MAX(1 hr, * MIN(1 day, * 1/10 * OrigTTL, * 1/10 * RRSigExpirationInterval)) */ static inline isc_stdtime_t refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) { isc_result_t result; isc_uint32_t t; dns_rdataset_t *rdset; dns_rdata_t sigrr = DNS_RDATA_INIT; dns_rdata_sig_t sig; isc_stdtime_t now; isc_stdtime_get(&now); if (dns_rdataset_isassociated(&kfetch->dnskeysigset)) rdset = &kfetch->dnskeysigset; else return (now + dns_zone_mkey_hour); result = dns_rdataset_first(rdset); if (result != ISC_R_SUCCESS) return (now + dns_zone_mkey_hour); dns_rdataset_current(rdset, &sigrr); result = dns_rdata_tostruct(&sigrr, &sig, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (!retry) { t = sig.originalttl / 2; if (isc_serial_gt(sig.timeexpire, now)) { isc_uint32_t exp = (sig.timeexpire - now) / 2; if (t > exp) t = exp; } if (t > (15 * dns_zone_mkey_day)) t = (15 * dns_zone_mkey_day); if (t < dns_zone_mkey_hour) t = dns_zone_mkey_hour; } else { t = sig.originalttl / 10; if (isc_serial_gt(sig.timeexpire, now)) { isc_uint32_t exp = (sig.timeexpire - now) / 10; if (t > exp) t = exp; } if (t > dns_zone_mkey_day) t = dns_zone_mkey_day; if (t < dns_zone_mkey_hour) t = dns_zone_mkey_hour; } return (now + t); } /* * This routine is called when no changes are needed in a KEYDATA * record except to simply update the refresh timer. Caller should * hold zone lock. */ static isc_result_t minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff) { isc_result_t result; isc_buffer_t keyb; unsigned char key_buf[4096]; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_keydata_t keydata; dns_name_t *name; dns_zone_t *zone = kfetch->zone; isc_stdtime_t now; name = dns_fixedname_name(&kfetch->name); isc_stdtime_get(&now); for (result = dns_rdataset_first(&kfetch->keydataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&kfetch->keydataset)) { dns_rdata_reset(&rdata); dns_rdataset_current(&kfetch->keydataset, &rdata); /* Delete old version */ CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL, name, 0, &rdata)); /* Update refresh timer */ result = dns_rdata_tostruct(&rdata, &keydata, NULL); if (result == ISC_R_UNEXPECTEDEND) continue; if (result != ISC_R_SUCCESS) goto failure; keydata.refresh = refresh_time(kfetch, ISC_TRUE); set_refreshkeytimer(zone, &keydata, now, ISC_FALSE); dns_rdata_reset(&rdata); isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); CHECK(dns_rdata_fromstruct(&rdata, zone->rdclass, dns_rdatatype_keydata, &keydata, &keyb)); /* Insert updated version */ CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD, name, 0, &rdata)); } result = ISC_R_SUCCESS; failure: return (result); } /* * Verify that DNSKEY set is signed by the key specified in 'keydata'. */ static isc_boolean_t revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) { isc_result_t result; dns_name_t *keyname; isc_mem_t *mctx; dns_rdata_t sigrr = DNS_RDATA_INIT; dns_rdata_t rr = DNS_RDATA_INIT; dns_rdata_rrsig_t sig; dns_rdata_dnskey_t dnskey; dst_key_t *dstkey = NULL; unsigned char key_buf[4096]; isc_buffer_t keyb; isc_boolean_t answer = ISC_FALSE; REQUIRE(kfetch != NULL && keydata != NULL); REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset)); keyname = dns_fixedname_name(&kfetch->name); mctx = kfetch->zone->view->mctx; /* Generate a key from keydata */ isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); dns_keydata_todnskey(keydata, &dnskey, NULL); dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey, &dnskey, &keyb); result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey); if (result != ISC_R_SUCCESS) return (ISC_FALSE); /* See if that key generated any of the signatures */ for (result = dns_rdataset_first(&kfetch->dnskeysigset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&kfetch->dnskeysigset)) { dns_fixedname_t fixed; dns_fixedname_init(&fixed); dns_rdata_reset(&sigrr); dns_rdataset_current(&kfetch->dnskeysigset, &sigrr); result = dns_rdata_tostruct(&sigrr, &sig, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (dst_key_alg(dstkey) == sig.algorithm && dst_key_rid(dstkey) == sig.keyid) { result = dns_dnssec_verify2(keyname, &kfetch->dnskeyset, dstkey, ISC_FALSE, mctx, &sigrr, dns_fixedname_name(&fixed)); dns_zone_log(kfetch->zone, ISC_LOG_DEBUG(3), "Confirm revoked DNSKEY is self-signed: " "%s", dns_result_totext(result)); if (result == ISC_R_SUCCESS) { answer = ISC_TRUE; break; } } } dst_key_free(&dstkey); return (answer); } /* * A DNSKEY set has been fetched from the zone apex of a zone whose trust * anchors are being managed; scan the keyset, and update the key zone and the * local trust anchors according to RFC5011. */ static void keyfetch_done(isc_task_t *task, isc_event_t *event) { isc_result_t result, eresult; dns_fetchevent_t *devent; dns_keyfetch_t *kfetch; dns_zone_t *zone; isc_mem_t *mctx = NULL; dns_keytable_t *secroots = NULL; dns_dbversion_t *ver = NULL; dns_diff_t diff; isc_boolean_t alldone = ISC_FALSE; isc_boolean_t commit = ISC_FALSE; dns_name_t *keyname; dns_rdata_t sigrr = DNS_RDATA_INIT; dns_rdata_t dnskeyrr = DNS_RDATA_INIT; dns_rdata_t keydatarr = DNS_RDATA_INIT; dns_rdata_rrsig_t sig; dns_rdata_dnskey_t dnskey; dns_rdata_keydata_t keydata; isc_boolean_t initializing; char namebuf[DNS_NAME_FORMATSIZE]; unsigned char key_buf[4096]; isc_buffer_t keyb; dst_key_t *dstkey; isc_stdtime_t now; int pending = 0; isc_boolean_t secure; isc_boolean_t free_needed; UNUSED(task); INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE); INSIST(event->ev_arg != NULL); kfetch = event->ev_arg; zone = kfetch->zone; isc_mem_attach(zone->mctx, &mctx); keyname = dns_fixedname_name(&kfetch->name); devent = (dns_fetchevent_t *) event; eresult = devent->result; /* Free resources which are not of interest */ if (devent->node != NULL) dns_db_detachnode(devent->db, &devent->node); if (devent->db != NULL) dns_db_detach(&devent->db); isc_event_free(&event); dns_resolver_destroyfetch(&kfetch->fetch); LOCK_ZONE(zone); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL) goto cleanup; isc_stdtime_get(&now); dns_name_format(keyname, namebuf, sizeof(namebuf)); result = dns_view_getsecroots(zone->view, &secroots); INSIST(result == ISC_R_SUCCESS); dns_diff_init(mctx, &diff); CHECK(dns_db_newversion(kfetch->db, &ver)); zone->refreshkeycount--; alldone = ISC_TF(zone->refreshkeycount == 0); if (alldone) DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING); /* Fetch failed */ if (eresult != ISC_R_SUCCESS || !dns_rdataset_isassociated(&kfetch->dnskeyset)) { dns_zone_log(zone, ISC_LOG_WARNING, "Unable to fetch DNSKEY set " "'%s': %s", namebuf, dns_result_totext(eresult)); CHECK(minimal_update(kfetch, ver, &diff)); goto done; } /* No RRSIGs found */ if (!dns_rdataset_isassociated(&kfetch->dnskeysigset)) { dns_zone_log(zone, ISC_LOG_WARNING, "No DNSKEY RRSIGs found for " "'%s': %s", namebuf, dns_result_totext(eresult)); CHECK(minimal_update(kfetch, ver, &diff)); goto done; } /* * Clear any cached trust level, as we need to run validation * over again; trusted keys might have changed. */ kfetch->dnskeyset.trust = kfetch->dnskeysigset.trust = dns_trust_none; /* * Validate the dnskeyset against the current trusted keys. */ for (result = dns_rdataset_first(&kfetch->dnskeysigset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&kfetch->dnskeysigset)) { dns_keynode_t *keynode = NULL; dns_rdata_reset(&sigrr); dns_rdataset_current(&kfetch->dnskeysigset, &sigrr); result = dns_rdata_tostruct(&sigrr, &sig, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); result = dns_keytable_find(secroots, keyname, &keynode); while (result == ISC_R_SUCCESS) { dns_keynode_t *nextnode = NULL; dns_fixedname_t fixed; dns_fixedname_init(&fixed); dstkey = dns_keynode_key(keynode); if (dstkey == NULL) /* fail_secure() was called */ break; if (dst_key_alg(dstkey) == sig.algorithm && dst_key_id(dstkey) == sig.keyid) { result = dns_dnssec_verify2(keyname, &kfetch->dnskeyset, dstkey, ISC_FALSE, zone->view->mctx, &sigrr, dns_fixedname_name(&fixed)); dns_zone_log(zone, ISC_LOG_DEBUG(3), "Verifying DNSKEY set for zone " "'%s' using key %d/%d: %s", namebuf, sig.keyid, sig.algorithm, dns_result_totext(result)); if (result == ISC_R_SUCCESS) { kfetch->dnskeyset.trust = dns_trust_secure; kfetch->dnskeysigset.trust = dns_trust_secure; break; } } result = dns_keytable_nextkeynode(secroots, keynode, &nextnode); dns_keytable_detachkeynode(secroots, &keynode); keynode = nextnode; } if (keynode != NULL) dns_keytable_detachkeynode(secroots, &keynode); if (kfetch->dnskeyset.trust == dns_trust_secure) break; } /* * If we were not able to verify the answer using the current * trusted keys then all we can do is look at any revoked keys. */ secure = ISC_TF(kfetch->dnskeyset.trust == dns_trust_secure); /* * First scan keydataset to find keys that are not in dnskeyset * - Missing keys which are not scheduled for removal, * log a warning * - Missing keys which are scheduled for removal and * the remove hold-down timer has completed should * be removed from the key zone * - Missing keys whose acceptance timers have not yet * completed, log a warning and reset the acceptance * timer to 30 days in the future * - All keys not being removed have their refresh timers * updated */ initializing = ISC_TRUE; for (result = dns_rdataset_first(&kfetch->keydataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&kfetch->keydataset)) { dns_rdata_reset(&keydatarr); dns_rdataset_current(&kfetch->keydataset, &keydatarr); result = dns_rdata_tostruct(&keydatarr, &keydata, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); /* * If any keydata record has a nonzero add holddown, then * there was a pre-existing trust anchor for this domain; * that means we are *not* initializing it and shouldn't * automatically trust all the keys we find at the zone apex. */ initializing = initializing && ISC_TF(keydata.addhd == 0); if (! matchkey(&kfetch->dnskeyset, &keydatarr)) { isc_boolean_t deletekey = ISC_FALSE; if (!secure) { if (keydata.removehd != 0 && keydata.removehd <= now) deletekey = ISC_TRUE; } else if (keydata.addhd == 0) { deletekey = ISC_TRUE; } else if (keydata.addhd > now) { dns_zone_log(zone, ISC_LOG_WARNING, "Pending key unexpectedly missing " "from %s; restarting acceptance " "timer", namebuf); if (keydata.addhd < now + dns_zone_mkey_month) keydata.addhd = now + dns_zone_mkey_month; keydata.refresh = refresh_time(kfetch, ISC_FALSE); } else if (keydata.removehd == 0) { dns_zone_log(zone, ISC_LOG_WARNING, "Active key unexpectedly missing " "from %s", namebuf); keydata.refresh = now + dns_zone_mkey_hour; } else if (keydata.removehd <= now) { deletekey = ISC_TRUE; } else { keydata.refresh = refresh_time(kfetch, ISC_FALSE); } if (secure || deletekey) { /* Delete old version */ CHECK(update_one_rr(kfetch->db, ver, &diff, DNS_DIFFOP_DEL, keyname, 0, &keydatarr)); } if (!secure || deletekey) continue; dns_rdata_reset(&keydatarr); isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); dns_rdata_fromstruct(&keydatarr, zone->rdclass, dns_rdatatype_keydata, &keydata, &keyb); /* Insert updated version */ CHECK(update_one_rr(kfetch->db, ver, &diff, DNS_DIFFOP_ADD, keyname, 0, &keydatarr)); set_refreshkeytimer(zone, &keydata, now, ISC_FALSE); } } /* * Next scan dnskeyset: * - If new keys are found (i.e., lacking a match in keydataset) * add them to the key zone and set the acceptance timer * to 30 days in the future (or to immediately if we've * determined that we're initializing the zone for the * first time) * - Previously-known keys that have been revoked * must be scheduled for removal from the key zone (or, * if they hadn't been accepted as trust anchors yet * anyway, removed at once) * - Previously-known unrevoked keys whose acceptance timers * have completed are promoted to trust anchors * - All keys not being removed have their refresh * timers updated */ for (result = dns_rdataset_first(&kfetch->dnskeyset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&kfetch->dnskeyset)) { isc_boolean_t revoked = ISC_FALSE; isc_boolean_t newkey = ISC_FALSE; isc_boolean_t updatekey = ISC_FALSE; isc_boolean_t deletekey = ISC_FALSE; isc_boolean_t trustkey = ISC_FALSE; dns_rdata_reset(&dnskeyrr); dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr); result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); /* Skip ZSK's */ if (!ISC_TF(dnskey.flags & DNS_KEYFLAG_KSK)) continue; revoked = ISC_TF(dnskey.flags & DNS_KEYFLAG_REVOKE); if (matchkey(&kfetch->keydataset, &dnskeyrr)) { dns_rdata_reset(&keydatarr); dns_rdataset_current(&kfetch->keydataset, &keydatarr); result = dns_rdata_tostruct(&keydatarr, &keydata, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (revoked && revocable(kfetch, &keydata)) { if (keydata.addhd > now) { /* * Key wasn't trusted yet, and now * it's been revoked? Just remove it */ deletekey = ISC_TRUE; } else if (keydata.removehd == 0) { /* Remove from secroots */ dns_view_untrust(zone->view, keyname, &dnskey, mctx); /* But ensure there's a null key */ fail_secure(zone, keyname); /* If initializing, delete now */ if (keydata.addhd == 0) deletekey = ISC_TRUE; else { keydata.removehd = now + dns_zone_mkey_month; keydata.flags |= DNS_KEYFLAG_REVOKE; } } else if (keydata.removehd < now) { /* Scheduled for removal */ deletekey = ISC_TRUE; } } else if (revoked && keydata.removehd == 0) { dns_zone_log(zone, ISC_LOG_WARNING, "Active key for zone " "'%s' is revoked but " "did not self-sign; " "ignoring.", namebuf); continue; } else if (secure) { if (keydata.removehd != 0) { /* * Key isn't revoked--but it * seems it used to be. * Remove it now and add it * back as if it were a fresh key, * with a 30 day acceptance timer. */ deletekey = ISC_TRUE; newkey = ISC_TRUE; keydata.removehd = 0; keydata.addhd = now + dns_zone_mkey_month; } else if (keydata.addhd > now) pending++; else if (keydata.addhd == 0) keydata.addhd = now; if (keydata.addhd <= now) trustkey = ISC_TRUE; } else if (keydata.addhd > now) { /* * Not secure, and key is pending: * reset the acceptance timer */ pending++; keydata.addhd = now + dns_zone_mkey_month; } if (!deletekey && !newkey) updatekey = ISC_TRUE; } else if (secure) { /* * Key wasn't in the key zone but it's * revoked now anyway, so just skip it */ if (revoked) continue; /* Key wasn't in the key zone: add it */ newkey = ISC_TRUE; if (initializing) { dns_keytag_t tag = 0; CHECK(compute_tag(keyname, &dnskey, mctx, &tag)); dns_zone_log(zone, ISC_LOG_WARNING, "Initializing automatic trust " "anchor management for zone '%s'; " "DNSKEY ID %d is now trusted, " "waiving the normal 30-day " "waiting period.", namebuf, tag); trustkey = ISC_TRUE; } } else { /* * No previously known key, and the key is not * secure, so skip it. */ continue; } /* Delete old version */ if (deletekey || !newkey) CHECK(update_one_rr(kfetch->db, ver, &diff, DNS_DIFFOP_DEL, keyname, 0, &keydatarr)); if (updatekey) { /* Set refresh timer */ keydata.refresh = refresh_time(kfetch, ISC_FALSE); dns_rdata_reset(&keydatarr); isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); dns_rdata_fromstruct(&keydatarr, zone->rdclass, dns_rdatatype_keydata, &keydata, &keyb); /* Insert updated version */ CHECK(update_one_rr(kfetch->db, ver, &diff, DNS_DIFFOP_ADD, keyname, 0, &keydatarr)); } else if (newkey) { /* Convert DNSKEY to KEYDATA */ result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0, NULL); keydata.addhd = initializing ? now : now + dns_zone_mkey_month; keydata.refresh = refresh_time(kfetch, ISC_FALSE); dns_rdata_reset(&keydatarr); isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); dns_rdata_fromstruct(&keydatarr, zone->rdclass, dns_rdatatype_keydata, &keydata, &keyb); /* Insert into key zone */ CHECK(update_one_rr(kfetch->db, ver, &diff, DNS_DIFFOP_ADD, keyname, 0, &keydatarr)); } if (trustkey) { /* Trust this key. */ result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); trust_key(zone, keyname, &dnskey, mctx); } if (secure && !deletekey) { INSIST(newkey || updatekey); set_refreshkeytimer(zone, &keydata, now, ISC_FALSE); } } /* * RFC5011 says, "A trust point that has all of its trust anchors * revoked is considered deleted and is treated as if the trust * point was never configured." But if someone revoked their * active key before the standby was trusted, that would mean the * zone would suddenly be nonsecured. We avoid this by checking to * see if there's pending keydata. If so, we put a null key in * the security roots; then all queries to the zone will fail. */ if (pending != 0) fail_secure(zone, keyname); done: if (!ISC_LIST_EMPTY(diff.tuples)) { /* Write changes to journal file. */ CHECK(update_soa_serial(kfetch->db, ver, &diff, mctx, zone->updatemethod)); CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done")); commit = ISC_TRUE; DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); zone_needdump(zone, 30); } failure: dns_diff_clear(&diff); if (ver != NULL) dns_db_closeversion(kfetch->db, &ver, commit); cleanup: dns_db_detach(&kfetch->db); INSIST(zone->irefs > 0); zone->irefs--; kfetch->zone = NULL; if (dns_rdataset_isassociated(&kfetch->keydataset)) dns_rdataset_disassociate(&kfetch->keydataset); if (dns_rdataset_isassociated(&kfetch->dnskeyset)) dns_rdataset_disassociate(&kfetch->dnskeyset); if (dns_rdataset_isassociated(&kfetch->dnskeysigset)) dns_rdataset_disassociate(&kfetch->dnskeysigset); dns_name_free(keyname, mctx); isc_mem_put(mctx, kfetch, sizeof(dns_keyfetch_t)); isc_mem_detach(&mctx); if (secroots != NULL) dns_keytable_detach(&secroots); free_needed = exit_check(zone); UNLOCK_ZONE(zone); if (free_needed) zone_free(zone); INSIST(ver == NULL); } /* * Refresh the data in the key zone. Initiate a fetch to get new DNSKEY * records from the zone apex. */ static void zone_refreshkeys(dns_zone_t *zone) { const char me[] = "zone_refreshkeys"; isc_result_t result; dns_rriterator_t rrit; dns_db_t *db = NULL; dns_dbversion_t *ver = NULL; dns_diff_t diff; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_keydata_t kd; isc_stdtime_t now; isc_boolean_t commit = ISC_FALSE; isc_boolean_t fetching = ISC_FALSE, fetch_err = ISC_FALSE; ENTER; REQUIRE(zone->db != NULL); isc_stdtime_get(&now); LOCK_ZONE(zone); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { isc_time_settoepoch(&zone->refreshkeytime); UNLOCK_ZONE(zone); return; } ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); dns_db_attach(zone->db, &db); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); dns_diff_init(zone->mctx, &diff); CHECK(dns_db_newversion(db, &ver)); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING); dns_rriterator_init(&rrit, db, ver, 0); for (result = dns_rriterator_first(&rrit); result == ISC_R_SUCCESS; result = dns_rriterator_nextrrset(&rrit)) { isc_stdtime_t timer = 0xffffffff; dns_name_t *name = NULL, *kname = NULL; dns_rdataset_t *kdset = NULL; dns_keyfetch_t *kfetch; isc_uint32_t ttl; dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL); if (kdset == NULL || kdset->type != dns_rdatatype_keydata || !dns_rdataset_isassociated(kdset)) continue; /* * Scan the stored keys looking for ones that need * removal or refreshing */ for (result = dns_rdataset_first(kdset); result == ISC_R_SUCCESS; result = dns_rdataset_next(kdset)) { dns_rdata_reset(&rdata); dns_rdataset_current(kdset, &rdata); result = dns_rdata_tostruct(&rdata, &kd, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); /* Removal timer expired? */ if (kd.removehd != 0 && kd.removehd < now) { CHECK(update_one_rr(db, ver, &diff, DNS_DIFFOP_DEL, name, ttl, &rdata)); continue; } /* Acceptance timer expired? */ if (kd.addhd != 0 && kd.addhd < now) timer = kd.addhd; /* Or do we just need to refresh the keyset? */ if (timer > kd.refresh) timer = kd.refresh; } if (timer > now) continue; kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t)); if (kfetch == NULL) { fetch_err = ISC_TRUE; goto failure; } zone->refreshkeycount++; kfetch->zone = zone; zone->irefs++; INSIST(zone->irefs != 0); dns_fixedname_init(&kfetch->name); kname = dns_fixedname_name(&kfetch->name); dns_name_dup(name, zone->mctx, kname); dns_rdataset_init(&kfetch->dnskeyset); dns_rdataset_init(&kfetch->dnskeysigset); dns_rdataset_init(&kfetch->keydataset); dns_rdataset_clone(kdset, &kfetch->keydataset); kfetch->db = NULL; dns_db_attach(db, &kfetch->db); kfetch->fetch = NULL; result = dns_resolver_createfetch(zone->view->resolver, kname, dns_rdatatype_dnskey, NULL, NULL, NULL, DNS_FETCHOPT_NOVALIDATE, zone->task, keyfetch_done, kfetch, &kfetch->dnskeyset, &kfetch->dnskeysigset, &kfetch->fetch); if (result == ISC_R_SUCCESS) fetching = ISC_TRUE; else { zone->refreshkeycount--; zone->irefs--; dns_db_detach(&kfetch->db); dns_rdataset_disassociate(&kfetch->keydataset); dns_name_free(kname, zone->mctx); isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t)); dns_zone_log(zone, ISC_LOG_WARNING, "Failed to create fetch for " "DNSKEY update"); fetch_err = ISC_TRUE; } } if (!ISC_LIST_EMPTY(diff.tuples)) { CHECK(update_soa_serial(db, ver, &diff, zone->mctx, zone->updatemethod)); CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys")); commit = ISC_TRUE; DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); zone_needdump(zone, 30); } failure: if (fetch_err) { /* * Error during a key fetch; retry in an hour. */ isc_time_t timenow, timethen; char timebuf[80]; TIME_NOW(&timenow); DNS_ZONE_TIME_ADD(&timenow, dns_zone_mkey_hour, &timethen); zone->refreshkeytime = timethen; zone_settimer(zone, &timenow); isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); dns_zone_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s", timebuf); if (!fetching) DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING); } UNLOCK_ZONE(zone); dns_diff_clear(&diff); if (ver != NULL) { dns_rriterator_destroy(&rrit); dns_db_closeversion(db, &ver, commit); } dns_db_detach(&db); INSIST(ver == NULL); } static void zone_maintenance(dns_zone_t *zone) { const char me[] = "zone_maintenance"; isc_time_t now; isc_result_t result; isc_boolean_t dumping; REQUIRE(DNS_ZONE_VALID(zone)); ENTER; /* * Are we pending load/reload? */ if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) return; /* * Configuring the view of this zone may have * failed, for example because the config file * had a syntax error. In that case, the view * adb or resolver will be NULL, and we had better not try * to do further maintenance on it. */ if (zone->view == NULL || zone->view->adb == NULL) return; TIME_NOW(&now); /* * Expire check. */ switch (zone->type) { case dns_zone_redirect: if (zone->masters == NULL) break; case dns_zone_slave: case dns_zone_stub: LOCK_ZONE(zone); if (isc_time_compare(&now, &zone->expiretime) >= 0 && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { zone_expire(zone); zone->refreshtime = now; } UNLOCK_ZONE(zone); break; default: break; } /* * Up to date check. */ switch (zone->type) { case dns_zone_redirect: if (zone->masters == NULL) break; case dns_zone_slave: case dns_zone_stub: if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) && isc_time_compare(&now, &zone->refreshtime) >= 0) dns_zone_refresh(zone); break; default: break; } /* * Slaves send notifies before backing up to disk, masters after. */ if (zone->type == dns_zone_slave && (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) && isc_time_compare(&now, &zone->notifytime) >= 0) zone_notify(zone, &now); /* * Do we need to consolidate the backing store? */ switch (zone->type) { case dns_zone_master: case dns_zone_slave: case dns_zone_key: case dns_zone_redirect: case dns_zone_stub: LOCK_ZONE(zone); if (zone->masterfile != NULL && isc_time_compare(&now, &zone->dumptime) >= 0 && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) { dumping = was_dumping(zone); } else dumping = ISC_TRUE; UNLOCK_ZONE(zone); if (!dumping) { result = zone_dump(zone, ISC_TRUE); /* task locked */ if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_WARNING, "dump failed: %s", dns_result_totext(result)); } break; default: break; } /* * Master/redirect zones send notifies now, if needed */ switch (zone->type) { case dns_zone_master: case dns_zone_redirect: if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))&& isc_time_compare(&now, &zone->notifytime) >= 0) zone_notify(zone, &now); default: break; } /* * Do we need to refresh keys? */ switch (zone->type) { case dns_zone_key: if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) { if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) { zone_refreshkeys(zone); } } break; case dns_zone_master: if (!isc_time_isepoch(&zone->refreshkeytime) && isc_time_compare(&now, &zone->refreshkeytime) >= 0 && zone->rss_event == NULL) zone_rekey(zone); default: break; } switch (zone->type) { case dns_zone_master: case dns_zone_redirect: case dns_zone_slave: /* * Do we need to sign/resign some RRsets? */ if (zone->rss_event != NULL) break; if (!isc_time_isepoch(&zone->signingtime) && isc_time_compare(&now, &zone->signingtime) >= 0) zone_sign(zone); else if (!isc_time_isepoch(&zone->resigntime) && isc_time_compare(&now, &zone->resigntime) >= 0) zone_resigninc(zone); else if (!isc_time_isepoch(&zone->nsec3chaintime) && isc_time_compare(&now, &zone->nsec3chaintime) >= 0) zone_nsec3chain(zone); /* * Do we need to issue a key expiry warning? */ if (!isc_time_isepoch(&zone->keywarntime) && isc_time_compare(&now, &zone->keywarntime) >= 0) set_key_expiry_warning(zone, zone->key_expiry, isc_time_seconds(&now)); break; default: break; } zone_settimer(zone, &now); } void dns_zone_markdirty(dns_zone_t *zone) { isc_uint32_t serial; isc_result_t result = ISC_R_SUCCESS; dns_zone_t *secure = NULL; /* * Obtaining a lock on the zone->secure (see zone_send_secureserial) * could result in a deadlock due to a LOR so we will spin if we * can't obtain the both locks. */ again: LOCK_ZONE(zone); if (zone->type == dns_zone_master) { if (inline_raw(zone)) { unsigned int soacount; secure = zone->secure; INSIST(secure != zone); TRYLOCK_ZONE(result, secure); if (result != ISC_R_SUCCESS) { UNLOCK_ZONE(zone); secure = NULL; #ifdef ISC_PLATFORM_USETHREADS isc_thread_yield(); #endif goto again; } ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) { result = zone_get_from_db(zone, zone->db, NULL, &soacount, &serial, NULL, NULL, NULL, NULL, NULL); } else result = DNS_R_NOTLOADED; ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); if (result == ISC_R_SUCCESS && soacount > 0U) zone_send_secureserial(zone, serial); } /* XXXMPA make separate call back */ if (result == ISC_R_SUCCESS) set_resigntime(zone); } if (secure != NULL) UNLOCK_ZONE(secure); zone_needdump(zone, DNS_DUMP_DELAY); UNLOCK_ZONE(zone); } void dns_zone_expire(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone_expire(zone); UNLOCK_ZONE(zone); } static void zone_expire(dns_zone_t *zone) { /* * 'zone' locked by caller. */ REQUIRE(LOCKED_ZONE(zone)); dns_zone_log(zone, ISC_LOG_WARNING, "expired"); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED); zone->refresh = DNS_ZONE_DEFAULTREFRESH; zone->retry = DNS_ZONE_DEFAULTRETRY; DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); zone_unload(zone); } void dns_zone_refresh(dns_zone_t *zone) { isc_interval_t i; isc_uint32_t oldflags; unsigned int j; isc_result_t result; REQUIRE(DNS_ZONE_VALID(zone)); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) return; /* * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation * in progress at a time. */ LOCK_ZONE(zone); oldflags = zone->flags; if (zone->masterscnt == 0) { DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS); if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0) dns_zone_log(zone, ISC_LOG_ERROR, "cannot refresh: no masters"); goto unlock; } DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0) goto unlock; /* * Set the next refresh time as if refresh check has failed. * Setting this to the retry time will do that. XXXMLG * If we are successful it will be reset using zone->refresh. */ isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4), 0); result = isc_time_nowplusinterval(&zone->refreshtime, &i); if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_WARNING, "isc_time_nowplusinterval() failed: %s", dns_result_totext(result)); /* * When lacking user-specified timer values from the SOA, * do exponential backoff of the retry time up to a * maximum of six hours. */ if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600); zone->curmaster = 0; for (j = 0; j < zone->masterscnt; j++) zone->mastersok[j] = ISC_FALSE; /* initiate soa query */ queue_soa_query(zone); unlock: UNLOCK_ZONE(zone); } isc_result_t dns_zone_flush(dns_zone_t *zone) { isc_result_t result = ISC_R_SUCCESS; isc_boolean_t dumping; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && zone->masterfile != NULL) { result = ISC_R_ALREADYRUNNING; dumping = was_dumping(zone); } else dumping = ISC_TRUE; UNLOCK_ZONE(zone); if (!dumping) result = zone_dump(zone, ISC_FALSE); /* Unknown task. */ return (result); } isc_result_t dns_zone_dump(dns_zone_t *zone) { isc_result_t result = ISC_R_ALREADYRUNNING; isc_boolean_t dumping; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); dumping = was_dumping(zone); UNLOCK_ZONE(zone); if (!dumping) result = zone_dump(zone, ISC_FALSE); /* Unknown task. */ return (result); } static void zone_needdump(dns_zone_t *zone, unsigned int delay) { const char me[] = "zone_needdump"; isc_time_t dumptime; isc_time_t now; /* * 'zone' locked by caller */ REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(LOCKED_ZONE(zone)); ENTER; /* * Do we have a place to dump to and are we loaded? */ if (zone->masterfile == NULL || DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) return; TIME_NOW(&now); /* add some noise */ DNS_ZONE_JITTER_ADD(&now, delay, &dumptime); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP); if (isc_time_isepoch(&zone->dumptime) || isc_time_compare(&zone->dumptime, &dumptime) > 0) zone->dumptime = dumptime; if (zone->task != NULL) zone_settimer(zone, &now); } static void dump_done(void *arg, isc_result_t result) { const char me[] = "dump_done"; dns_zone_t *zone = arg; dns_db_t *db; dns_dbversion_t *version; isc_boolean_t again = ISC_FALSE; isc_boolean_t compact = ISC_FALSE; isc_uint32_t serial; isc_result_t tresult; REQUIRE(DNS_ZONE_VALID(zone)); ENTER; if (result == ISC_R_SUCCESS && zone->journal != NULL && zone->journalsize != -1) { /* * We don't own these, zone->dctx must stay valid. */ db = dns_dumpctx_db(zone->dctx); version = dns_dumpctx_version(zone->dctx); tresult = dns_db_getsoaserial(db, version, &serial); /* * If there is a secure version of this zone * use its serial if it is less than ours. */ if (tresult == ISC_R_SUCCESS && inline_raw(zone) && zone->secure->db != NULL) { isc_uint32_t sserial; isc_result_t mresult; mresult = dns_db_getsoaserial(zone->secure->db, NULL, &sserial); if (mresult == ISC_R_SUCCESS && isc_serial_lt(sserial, serial)) serial = sserial; } /* * Note: we are task locked here so we can test * zone->xfr safely. */ if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) { tresult = dns_journal_compact(zone->mctx, zone->journal, serial, zone->journalsize); switch (tresult) { case ISC_R_SUCCESS: case ISC_R_NOSPACE: case ISC_R_NOTFOUND: dns_zone_log(zone, ISC_LOG_DEBUG(3), "dns_journal_compact: %s", dns_result_totext(tresult)); break; default: dns_zone_log(zone, ISC_LOG_ERROR, "dns_journal_compact failed: %s", dns_result_totext(tresult)); break; } } else if (tresult == ISC_R_SUCCESS) { compact = ISC_TRUE; zone->compact_serial = serial; } } LOCK_ZONE(zone); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING); if (compact) DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) { /* * Try again in a short while. */ zone_needdump(zone, DNS_DUMP_DELAY); } else if (result == ISC_R_SUCCESS && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); isc_time_settoepoch(&zone->dumptime); again = ISC_TRUE; } else if (result == ISC_R_SUCCESS) DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); if (zone->dctx != NULL) dns_dumpctx_detach(&zone->dctx); zonemgr_putio(&zone->writeio); UNLOCK_ZONE(zone); if (again) (void)zone_dump(zone, ISC_FALSE); dns_zone_idetach(&zone); } static isc_result_t zone_dump(dns_zone_t *zone, isc_boolean_t compact) { const char me[] = "zone_dump"; isc_result_t result; dns_dbversion_t *version = NULL; isc_boolean_t again; dns_db_t *db = NULL; char *masterfile = NULL; dns_masterformat_t masterformat = dns_masterformat_none; /* * 'compact' MUST only be set if we are task locked. */ REQUIRE(DNS_ZONE_VALID(zone)); ENTER; redo: ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) dns_db_attach(zone->db, &db); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); LOCK_ZONE(zone); if (zone->masterfile != NULL) { masterfile = isc_mem_strdup(zone->mctx, zone->masterfile); masterformat = zone->masterformat; } UNLOCK_ZONE(zone); if (db == NULL) { result = DNS_R_NOTLOADED; goto fail; } if (masterfile == NULL) { result = DNS_R_NOMASTERFILE; goto fail; } if (compact && zone->type != dns_zone_stub) { dns_zone_t *dummy = NULL; LOCK_ZONE(zone); zone_iattach(zone, &dummy); result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task, zone_gotwritehandle, zone, &zone->writeio); if (result != ISC_R_SUCCESS) zone_idetach(&dummy); else result = DNS_R_CONTINUE; UNLOCK_ZONE(zone); } else { const dns_master_style_t *output_style; dns_masterrawheader_t rawdata; dns_db_currentversion(db, &version); dns_master_initrawheader(&rawdata); if (inline_secure(zone)) get_raw_serial(zone->raw, &rawdata); if (zone->type == dns_zone_key) output_style = &dns_master_style_keyzone; else output_style = &dns_master_style_default; result = dns_master_dump3(zone->mctx, db, version, output_style, masterfile, masterformat, &rawdata); dns_db_closeversion(db, &version, ISC_FALSE); } fail: if (db != NULL) dns_db_detach(&db); if (masterfile != NULL) isc_mem_free(zone->mctx, masterfile); masterfile = NULL; if (result == DNS_R_CONTINUE) return (ISC_R_SUCCESS); /* XXXMPA */ again = ISC_FALSE; LOCK_ZONE(zone); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING); if (result != ISC_R_SUCCESS) { /* * Try again in a short while. */ zone_needdump(zone, DNS_DUMP_DELAY); } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); isc_time_settoepoch(&zone->dumptime); again = ISC_TRUE; } else DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); UNLOCK_ZONE(zone); if (again) goto redo; return (result); } static isc_result_t dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style, dns_masterformat_t format, const isc_uint32_t rawversion) { isc_result_t result; dns_dbversion_t *version = NULL; dns_db_t *db = NULL; dns_masterrawheader_t rawdata; REQUIRE(DNS_ZONE_VALID(zone)); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) dns_db_attach(zone->db, &db); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); if (db == NULL) return (DNS_R_NOTLOADED); dns_db_currentversion(db, &version); dns_master_initrawheader(&rawdata); if (rawversion == 0) rawdata.flags |= DNS_MASTERRAW_COMPAT; else if (inline_secure(zone)) get_raw_serial(zone->raw, &rawdata); else if (zone->sourceserialset) { rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET; rawdata.sourceserial = zone->sourceserial; } result = dns_master_dumptostream3(zone->mctx, db, version, style, format, &rawdata, fd); dns_db_closeversion(db, &version, ISC_FALSE); dns_db_detach(&db); return (result); } isc_result_t dns_zone_dumptostream3(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, const dns_master_style_t *style, const isc_uint32_t rawversion) { return (dumptostream(zone, fd, style, format, rawversion)); } isc_result_t dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, const dns_master_style_t *style) { return (dumptostream(zone, fd, style, format, DNS_RAWFORMAT_VERSION)); } isc_result_t dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) { return (dumptostream(zone, fd, &dns_master_style_default, dns_masterformat_text, 0)); } isc_result_t dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) { return (dumptostream(zone, fd, &dns_master_style_full, dns_masterformat_text, 0)); } void dns_zone_unload(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone_unload(zone); UNLOCK_ZONE(zone); } static void notify_cancel(dns_zone_t *zone) { dns_notify_t *notify; /* * 'zone' locked by caller. */ REQUIRE(LOCKED_ZONE(zone)); for (notify = ISC_LIST_HEAD(zone->notifies); notify != NULL; notify = ISC_LIST_NEXT(notify, link)) { if (notify->find != NULL) dns_adb_cancelfind(notify->find); if (notify->request != NULL) dns_request_cancel(notify->request); } } static void forward_cancel(dns_zone_t *zone) { dns_forward_t *forward; /* * 'zone' locked by caller. */ REQUIRE(LOCKED_ZONE(zone)); for (forward = ISC_LIST_HEAD(zone->forwards); forward != NULL; forward = ISC_LIST_NEXT(forward, link)) { if (forward->request != NULL) dns_request_cancel(forward->request); } } static void zone_unload(dns_zone_t *zone) { /* * 'zone' locked by caller. */ REQUIRE(LOCKED_ZONE(zone)); if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) || !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { if (zone->writeio != NULL) zonemgr_cancelio(zone->writeio); if (zone->dctx != NULL) dns_dumpctx_cancel(zone->dctx); } ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); zone_detachdb(zone); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); } void dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(val > 0); zone->minrefresh = val; } void dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(val > 0); zone->maxrefresh = val; } void dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(val > 0); zone->minretry = val; } void dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(val > 0); zone->maxretry = val; } static isc_boolean_t notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name, isc_sockaddr_t *addr, dns_tsigkey_t *key) { dns_notify_t *notify; dns_zonemgr_t *zmgr; isc_result_t result; for (notify = ISC_LIST_HEAD(zone->notifies); notify != NULL; notify = ISC_LIST_NEXT(notify, link)) { if (notify->request != NULL) continue; if (name != NULL && dns_name_dynamic(¬ify->ns) && dns_name_equal(name, ¬ify->ns)) goto requeue; if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst) && notify->key == key) goto requeue; } return (ISC_FALSE); requeue: /* * If we are enqueued on the startup ratelimiter and this is * not a startup notify, re-enqueue on the normal notify * ratelimiter. */ if (notify->event != NULL && (flags & DNS_NOTIFY_STARTUP) == 0 && (notify->flags & DNS_NOTIFY_STARTUP) != 0) { zmgr = notify->zone->zmgr; result = isc_ratelimiter_dequeue(zmgr->startupnotifyrl, notify->event); if (result != ISC_R_SUCCESS) return (ISC_TRUE); notify->flags &= ~DNS_NOTIFY_STARTUP; result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl, notify->zone->task, ¬ify->event); if (result != ISC_R_SUCCESS) { isc_event_free(¬ify->event); return (ISC_FALSE); } } return (ISC_TRUE); } static isc_boolean_t notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) { dns_tsigkey_t *key = NULL; isc_sockaddr_t src; isc_sockaddr_t any; isc_boolean_t isself; isc_netaddr_t dstaddr; isc_result_t result; if (zone->view == NULL || zone->isself == NULL) return (ISC_FALSE); switch (isc_sockaddr_pf(dst)) { case PF_INET: src = zone->notifysrc4; isc_sockaddr_any(&any); break; case PF_INET6: src = zone->notifysrc6; isc_sockaddr_any6(&any); break; default: return (ISC_FALSE); } /* * When sending from any the kernel will assign a source address * that matches the destination address. */ if (isc_sockaddr_eqaddr(&any, &src)) src = *dst; isc_netaddr_fromsockaddr(&dstaddr, dst); result = dns_view_getpeertsig(zone->view, &dstaddr, &key); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) return (ISC_FALSE); isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass, zone->isselfarg); if (key != NULL) dns_tsigkey_detach(&key); return (isself); } static void notify_destroy(dns_notify_t *notify, isc_boolean_t locked) { isc_mem_t *mctx; REQUIRE(DNS_NOTIFY_VALID(notify)); if (notify->zone != NULL) { if (!locked) LOCK_ZONE(notify->zone); REQUIRE(LOCKED_ZONE(notify->zone)); if (ISC_LINK_LINKED(notify, link)) ISC_LIST_UNLINK(notify->zone->notifies, notify, link); if (!locked) UNLOCK_ZONE(notify->zone); if (locked) zone_idetach(¬ify->zone); else dns_zone_idetach(¬ify->zone); } if (notify->find != NULL) dns_adb_destroyfind(¬ify->find); if (notify->request != NULL) dns_request_destroy(¬ify->request); if (dns_name_dynamic(¬ify->ns)) dns_name_free(¬ify->ns, notify->mctx); if (notify->key != NULL) dns_tsigkey_detach(¬ify->key); mctx = notify->mctx; isc_mem_put(notify->mctx, notify, sizeof(*notify)); isc_mem_detach(&mctx); } static isc_result_t notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) { dns_notify_t *notify; REQUIRE(notifyp != NULL && *notifyp == NULL); notify = isc_mem_get(mctx, sizeof(*notify)); if (notify == NULL) return (ISC_R_NOMEMORY); notify->mctx = NULL; isc_mem_attach(mctx, ¬ify->mctx); notify->flags = flags; notify->zone = NULL; notify->find = NULL; notify->request = NULL; notify->key = NULL; notify->event = NULL; isc_sockaddr_any(¬ify->dst); dns_name_init(¬ify->ns, NULL); ISC_LINK_INIT(notify, link); notify->magic = NOTIFY_MAGIC; *notifyp = notify; return (ISC_R_SUCCESS); } /* * XXXAG should check for DNS_ZONEFLG_EXITING */ static void process_adb_event(isc_task_t *task, isc_event_t *ev) { dns_notify_t *notify; isc_eventtype_t result; UNUSED(task); notify = ev->ev_arg; REQUIRE(DNS_NOTIFY_VALID(notify)); INSIST(task == notify->zone->task); result = ev->ev_type; isc_event_free(&ev); if (result == DNS_EVENT_ADBMOREADDRESSES) { dns_adb_destroyfind(¬ify->find); notify_find_address(notify); return; } if (result == DNS_EVENT_ADBNOMOREADDRESSES) { LOCK_ZONE(notify->zone); notify_send(notify); UNLOCK_ZONE(notify->zone); } notify_destroy(notify, ISC_FALSE); } static void notify_find_address(dns_notify_t *notify) { isc_result_t result; unsigned int options; REQUIRE(DNS_NOTIFY_VALID(notify)); options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET | DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME; if (notify->zone->view->adb == NULL) goto destroy; result = dns_adb_createfind(notify->zone->view->adb, notify->zone->task, process_adb_event, notify, ¬ify->ns, dns_rootname, 0, options, 0, NULL, notify->zone->view->dstport, ¬ify->find); /* Something failed? */ if (result != ISC_R_SUCCESS) goto destroy; /* More addresses pending? */ if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0) return; /* We have as many addresses as we can get. */ LOCK_ZONE(notify->zone); notify_send(notify); UNLOCK_ZONE(notify->zone); destroy: notify_destroy(notify, ISC_FALSE); } static isc_result_t notify_send_queue(dns_notify_t *notify, isc_boolean_t startup) { isc_event_t *e; isc_result_t result; INSIST(notify->event == NULL); e = isc_event_allocate(notify->mctx, NULL, DNS_EVENT_NOTIFYSENDTOADDR, notify_send_toaddr, notify, sizeof(isc_event_t)); if (e == NULL) return (ISC_R_NOMEMORY); if (startup) notify->event = e; e->ev_arg = notify; e->ev_sender = NULL; result = isc_ratelimiter_enqueue(startup ? notify->zone->zmgr->startupnotifyrl : notify->zone->zmgr->notifyrl, notify->zone->task, &e); if (result != ISC_R_SUCCESS) { isc_event_free(&e); notify->event = NULL; } return (result); } static void notify_send_toaddr(isc_task_t *task, isc_event_t *event) { dns_notify_t *notify; isc_result_t result; dns_message_t *message = NULL; isc_netaddr_t dstip; dns_tsigkey_t *key = NULL; char addrbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_t src; int timeout; isc_boolean_t have_notifysource = ISC_FALSE; isc_boolean_t have_notifydscp = ISC_FALSE; isc_dscp_t dscp = -1; notify = event->ev_arg; REQUIRE(DNS_NOTIFY_VALID(notify)); UNUSED(task); LOCK_ZONE(notify->zone); notify->event = NULL; if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) { result = ISC_R_CANCELED; goto cleanup; } if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 || DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) || notify->zone->view->requestmgr == NULL || notify->zone->db == NULL) { result = ISC_R_CANCELED; goto cleanup; } /* * The raw IPv4 address should also exist. Don't send to the * mapped form. */ if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 && IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) { isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); notify_log(notify->zone, ISC_LOG_DEBUG(3), "notify: ignoring IPv6 mapped IPV4 address: %s", addrbuf); result = ISC_R_CANCELED; goto cleanup; } result = notify_createmessage(notify->zone, notify->flags, &message); if (result != ISC_R_SUCCESS) goto cleanup; if (notify->key != NULL) { /* Transfer ownership of key */ key = notify->key; notify->key = NULL; } else { isc_netaddr_fromsockaddr(&dstip, ¬ify->dst); isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); result = dns_view_getpeertsig(notify->zone->view, &dstip, &key); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { notify_log(notify->zone, ISC_LOG_ERROR, "NOTIFY to %s not sent. " "Peer TSIG key lookup failure.", addrbuf); goto cleanup_message; } } /* XXX: should we log the tsig key too? */ notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s", addrbuf); if (notify->zone->view->peers != NULL) { dns_peer_t *peer = NULL; result = dns_peerlist_peerbyaddr(notify->zone->view->peers, &dstip, &peer); if (result == ISC_R_SUCCESS) { result = dns_peer_getnotifysource(peer, &src); if (result == ISC_R_SUCCESS) have_notifysource = ISC_TRUE; dns_peer_getnotifydscp(peer, &dscp); if (dscp != -1) have_notifydscp = ISC_TRUE; } } switch (isc_sockaddr_pf(¬ify->dst)) { case PF_INET: if (!have_notifysource) src = notify->zone->notifysrc4; if (!have_notifydscp) dscp = notify->zone->notifysrc4dscp; break; case PF_INET6: if (!have_notifysource) src = notify->zone->notifysrc6; if (!have_notifydscp) dscp = notify->zone->notifysrc6dscp; break; default: result = ISC_R_NOTIMPLEMENTED; goto cleanup_key; } timeout = 15; if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY)) timeout = 30; result = dns_request_createvia4(notify->zone->view->requestmgr, message, &src, ¬ify->dst, dscp, 0, key, timeout * 3, timeout, 0, notify->zone->task, notify_done, notify, ¬ify->request); if (result == ISC_R_SUCCESS) { if (isc_sockaddr_pf(¬ify->dst) == AF_INET) { inc_stats(notify->zone, dns_zonestatscounter_notifyoutv4); } else { inc_stats(notify->zone, dns_zonestatscounter_notifyoutv6); } } cleanup_key: if (key != NULL) dns_tsigkey_detach(&key); cleanup_message: dns_message_destroy(&message); cleanup: UNLOCK_ZONE(notify->zone); isc_event_free(&event); if (result != ISC_R_SUCCESS) notify_destroy(notify, ISC_FALSE); } static void notify_send(dns_notify_t *notify) { dns_adbaddrinfo_t *ai; isc_sockaddr_t dst; isc_result_t result; dns_notify_t *new = NULL; unsigned int flags; isc_boolean_t startup; /* * Zone lock held by caller. */ REQUIRE(DNS_NOTIFY_VALID(notify)); REQUIRE(LOCKED_ZONE(notify->zone)); for (ai = ISC_LIST_HEAD(notify->find->list); ai != NULL; ai = ISC_LIST_NEXT(ai, publink)) { dst = ai->sockaddr; if (notify_isqueued(notify->zone, notify->flags, NULL, &dst, NULL)) continue; if (notify_isself(notify->zone, &dst)) continue; new = NULL; flags = notify->flags & DNS_NOTIFY_NOSOA; result = notify_create(notify->mctx, flags, &new); if (result != ISC_R_SUCCESS) goto cleanup; zone_iattach(notify->zone, &new->zone); ISC_LIST_APPEND(new->zone->notifies, new, link); new->dst = dst; startup = ISC_TF((notify->flags & DNS_NOTIFY_STARTUP) != 0); result = notify_send_queue(new, startup); if (result != ISC_R_SUCCESS) goto cleanup; new = NULL; } cleanup: if (new != NULL) notify_destroy(new, ISC_TRUE); } void dns_zone_notify(dns_zone_t *zone) { isc_time_t now; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); TIME_NOW(&now); zone_settimer(zone, &now); UNLOCK_ZONE(zone); } static void zone_notify(dns_zone_t *zone, isc_time_t *now) { dns_dbnode_t *node = NULL; dns_db_t *zonedb = NULL; dns_dbversion_t *version = NULL; dns_name_t *origin = NULL; dns_name_t master; dns_rdata_ns_t ns; dns_rdata_soa_t soa; isc_uint32_t serial; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_t nsrdset; dns_rdataset_t soardset; isc_result_t result; unsigned int i; isc_sockaddr_t dst; isc_boolean_t isqueued; dns_notifytype_t notifytype; unsigned int flags = 0; isc_boolean_t loggednotify = ISC_FALSE; isc_boolean_t startup; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); startup = !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY); notifytype = zone->notifytype; DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime); UNLOCK_ZONE(zone); if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) return; if (notifytype == dns_notifytype_no) return; if (notifytype == dns_notifytype_masteronly && zone->type != dns_zone_master) return; origin = &zone->origin; /* * If the zone is dialup we are done as we don't want to send * the current soa so as to force a refresh query. */ if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) flags |= DNS_NOTIFY_NOSOA; /* * Record that this was a notify due to starting up. */ if (startup) flags |= DNS_NOTIFY_STARTUP; /* * Get SOA RRset. */ ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) dns_db_attach(zone->db, &zonedb); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); if (zonedb == NULL) return; dns_db_currentversion(zonedb, &version); result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) goto cleanup1; dns_rdataset_init(&soardset); result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa, dns_rdatatype_none, 0, &soardset, NULL); if (result != ISC_R_SUCCESS) goto cleanup2; /* * Find serial and master server's name. */ dns_name_init(&master, NULL); result = dns_rdataset_first(&soardset); if (result != ISC_R_SUCCESS) goto cleanup3; dns_rdataset_current(&soardset, &rdata); result = dns_rdata_tostruct(&rdata, &soa, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_rdata_reset(&rdata); result = dns_name_dup(&soa.origin, zone->mctx, &master); serial = soa.serial; dns_rdataset_disassociate(&soardset); if (result != ISC_R_SUCCESS) goto cleanup3; /* * Enqueue notify requests for 'also-notify' servers. */ LOCK_ZONE(zone); for (i = 0; i < zone->notifycnt; i++) { dns_tsigkey_t *key = NULL; dns_notify_t *notify = NULL; if ((zone->notifykeynames != NULL) && (zone->notifykeynames[i] != NULL)) { dns_view_t *view = dns_zone_getview(zone); dns_name_t *keyname = zone->notifykeynames[i]; (void)dns_view_gettsig(view, keyname, &key); } dst = zone->notify[i]; if (notify_isqueued(zone, flags, NULL, &dst, key)) { if (key != NULL) dns_tsigkey_detach(&key); continue; } result = notify_create(zone->mctx, flags, ¬ify); if (result != ISC_R_SUCCESS) { if (key != NULL) dns_tsigkey_detach(&key); continue; } zone_iattach(zone, ¬ify->zone); notify->dst = dst; INSIST(notify->key == NULL); if (key != NULL) { notify->key = key; key = NULL; } ISC_LIST_APPEND(zone->notifies, notify, link); result = notify_send_queue(notify, startup); if (result != ISC_R_SUCCESS) notify_destroy(notify, ISC_TRUE); if (!loggednotify) { notify_log(zone, ISC_LOG_INFO, "sending notifies (serial %u)", serial); loggednotify = ISC_TRUE; } } UNLOCK_ZONE(zone); if (notifytype == dns_notifytype_explicit) goto cleanup3; /* * Process NS RRset to generate notifies. */ dns_rdataset_init(&nsrdset); result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns, dns_rdatatype_none, 0, &nsrdset, NULL); if (result != ISC_R_SUCCESS) goto cleanup3; result = dns_rdataset_first(&nsrdset); while (result == ISC_R_SUCCESS) { dns_notify_t *notify = NULL; dns_rdataset_current(&nsrdset, &rdata); result = dns_rdata_tostruct(&rdata, &ns, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_rdata_reset(&rdata); /* * Don't notify the master server unless explicitly * configured to do so. */ if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) && dns_name_compare(&master, &ns.name) == 0) { result = dns_rdataset_next(&nsrdset); continue; } if (!loggednotify) { notify_log(zone, ISC_LOG_INFO, "sending notifies (serial %u)", serial); loggednotify = ISC_TRUE; } LOCK_ZONE(zone); isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL); UNLOCK_ZONE(zone); if (isqueued) { result = dns_rdataset_next(&nsrdset); continue; } result = notify_create(zone->mctx, flags, ¬ify); if (result != ISC_R_SUCCESS) continue; dns_zone_iattach(zone, ¬ify->zone); result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns); if (result != ISC_R_SUCCESS) { LOCK_ZONE(zone); notify_destroy(notify, ISC_TRUE); UNLOCK_ZONE(zone); continue; } LOCK_ZONE(zone); ISC_LIST_APPEND(zone->notifies, notify, link); UNLOCK_ZONE(zone); notify_find_address(notify); result = dns_rdataset_next(&nsrdset); } dns_rdataset_disassociate(&nsrdset); cleanup3: if (dns_name_dynamic(&master)) dns_name_free(&master, zone->mctx); cleanup2: dns_db_detachnode(zonedb, &node); cleanup1: dns_db_closeversion(zonedb, &version, ISC_FALSE); dns_db_detach(&zonedb); } /*** *** Private ***/ static inline isc_result_t save_nsrrset(dns_message_t *message, dns_name_t *name, dns_db_t *db, dns_dbversion_t *version) { dns_rdataset_t *nsrdataset = NULL; dns_rdataset_t *rdataset = NULL; dns_dbnode_t *node = NULL; dns_rdata_ns_t ns; isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; /* * Extract NS RRset from message. */ result = dns_message_findname(message, DNS_SECTION_ANSWER, name, dns_rdatatype_ns, dns_rdatatype_none, NULL, &nsrdataset); if (result != ISC_R_SUCCESS) goto fail; /* * Add NS rdataset. */ result = dns_db_findnode(db, name, ISC_TRUE, &node); if (result != ISC_R_SUCCESS) goto fail; result = dns_db_addrdataset(db, node, version, 0, nsrdataset, 0, NULL); dns_db_detachnode(db, &node); if (result != ISC_R_SUCCESS) goto fail; /* * Add glue rdatasets. */ for (result = dns_rdataset_first(nsrdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(nsrdataset)) { dns_rdataset_current(nsrdataset, &rdata); result = dns_rdata_tostruct(&rdata, &ns, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_rdata_reset(&rdata); if (!dns_name_issubdomain(&ns.name, name)) continue; rdataset = NULL; result = dns_message_findname(message, DNS_SECTION_ADDITIONAL, &ns.name, dns_rdatatype_aaaa, dns_rdatatype_none, NULL, &rdataset); if (result == ISC_R_SUCCESS) { result = dns_db_findnode(db, &ns.name, ISC_TRUE, &node); if (result != ISC_R_SUCCESS) goto fail; result = dns_db_addrdataset(db, node, version, 0, rdataset, 0, NULL); dns_db_detachnode(db, &node); if (result != ISC_R_SUCCESS) goto fail; } rdataset = NULL; result = dns_message_findname(message, DNS_SECTION_ADDITIONAL, &ns.name, dns_rdatatype_a, dns_rdatatype_none, NULL, &rdataset); if (result == ISC_R_SUCCESS) { result = dns_db_findnode(db, &ns.name, ISC_TRUE, &node); if (result != ISC_R_SUCCESS) goto fail; result = dns_db_addrdataset(db, node, version, 0, rdataset, 0, NULL); dns_db_detachnode(db, &node); if (result != ISC_R_SUCCESS) goto fail; } } if (result != ISC_R_NOMORE) goto fail; return (ISC_R_SUCCESS); fail: return (result); } static void stub_callback(isc_task_t *task, isc_event_t *event) { const char me[] = "stub_callback"; dns_requestevent_t *revent = (dns_requestevent_t *)event; dns_stub_t *stub = NULL; dns_message_t *msg = NULL; dns_zone_t *zone = NULL; char master[ISC_SOCKADDR_FORMATSIZE]; char source[ISC_SOCKADDR_FORMATSIZE]; isc_uint32_t nscnt, cnamecnt, refresh, retry, expire; isc_result_t result; isc_time_t now; isc_boolean_t exiting = ISC_FALSE; isc_interval_t i; unsigned int j, soacount; stub = revent->ev_arg; INSIST(DNS_STUB_VALID(stub)); UNUSED(task); zone = stub->zone; ENTER; TIME_NOW(&now); LOCK_ZONE(zone); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { zone_debuglog(zone, me, 1, "exiting"); exiting = ISC_TRUE; goto next_master; } isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); if (revent->result != ISC_R_SUCCESS) { if (revent->result == ISC_R_TIMEDOUT && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); dns_zone_log(zone, ISC_LOG_DEBUG(1), "refreshing stub: timeout retrying " " without EDNS master %s (source %s)", master, source); goto same_master; } dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr, &zone->sourceaddr, &now); dns_zone_log(zone, ISC_LOG_INFO, "could not refresh stub from master %s" " (source %s): %s", master, source, dns_result_totext(revent->result)); goto next_master; } result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); if (result != ISC_R_SUCCESS) goto next_master; result = dns_request_getresponse(revent->request, msg, 0); if (result != ISC_R_SUCCESS) goto next_master; /* * Unexpected rcode. */ if (msg->rcode != dns_rcode_noerror) { char rcode[128]; isc_buffer_t rb; isc_buffer_init(&rb, rcode, sizeof(rcode)); (void)dns_rcode_totext(msg->rcode, &rb); if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && (msg->rcode == dns_rcode_servfail || msg->rcode == dns_rcode_notimp || msg->rcode == dns_rcode_formerr)) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "refreshing stub: rcode (%.*s) retrying " "without EDNS master %s (source %s)", (int)rb.used, rcode, master, source); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); goto same_master; } dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: " "unexpected rcode (%.*s) from %s (source %s)", (int)rb.used, rcode, master, source); goto next_master; } /* * We need complete messages. */ if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { if (dns_request_usedtcp(revent->request)) { dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: truncated TCP " "response from master %s (source %s)", master, source); goto next_master; } DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC); goto same_master; } /* * If non-auth log and next master. */ if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: " "non-authoritative answer from " "master %s (source %s)", master, source); goto next_master; } /* * Sanity checks. */ cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns); if (cnamecnt != 0) { dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: unexpected CNAME response " "from master %s (source %s)", master, source); goto next_master; } if (nscnt == 0) { dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: no NS records in response " "from master %s (source %s)", master, source); goto next_master; } /* * Save answer. */ result = save_nsrrset(msg, &zone->origin, stub->db, stub->version); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: unable to save NS records " "from master %s (source %s)", master, source); goto next_master; } /* * Tidy up. */ dns_db_closeversion(stub->db, &stub->version, ISC_TRUE); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); if (zone->db == NULL) zone_attachdb(zone, stub->db); result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL, &refresh, &retry, &expire, NULL, NULL); if (result == ISC_R_SUCCESS && soacount > 0U) { zone->refresh = RANGE(refresh, zone->minrefresh, zone->maxrefresh); zone->retry = RANGE(retry, zone->minretry, zone->maxretry); zone->expire = RANGE(expire, zone->refresh + zone->retry, DNS_MAX_EXPIRE); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); } ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); dns_db_detach(&stub->db); dns_message_destroy(&msg); isc_event_free(&event); dns_request_destroy(&zone->request); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); isc_interval_set(&i, zone->expire, 0); DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime); if (zone->masterfile != NULL) zone_needdump(zone, 0); zone_settimer(zone, &now); goto free_stub; next_master: if (stub->version != NULL) dns_db_closeversion(stub->db, &stub->version, ISC_FALSE); if (stub->db != NULL) dns_db_detach(&stub->db); if (msg != NULL) dns_message_destroy(&msg); isc_event_free(&event); dns_request_destroy(&zone->request); /* * Skip to next failed / untried master. */ do { zone->curmaster++; } while (zone->curmaster < zone->masterscnt && zone->mastersok[zone->curmaster]); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); if (exiting || zone->curmaster >= zone->masterscnt) { isc_boolean_t done = ISC_TRUE; if (!exiting && DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { /* * Did we get a good answer from all the masters? */ for (j = 0; j < zone->masterscnt; j++) if (zone->mastersok[j] == ISC_FALSE) { done = ISC_FALSE; break; } } else done = ISC_TRUE; if (!done) { zone->curmaster = 0; /* * Find the next failed master. */ while (zone->curmaster < zone->masterscnt && zone->mastersok[zone->curmaster]) zone->curmaster++; DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); } else { DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); zone_settimer(zone, &now); goto free_stub; } } queue_soa_query(zone); goto free_stub; same_master: if (msg != NULL) dns_message_destroy(&msg); isc_event_free(&event); dns_request_destroy(&zone->request); ns_query(zone, NULL, stub); UNLOCK_ZONE(zone); goto done; free_stub: UNLOCK_ZONE(zone); stub->magic = 0; dns_zone_idetach(&stub->zone); INSIST(stub->db == NULL); INSIST(stub->version == NULL); isc_mem_put(stub->mctx, stub, sizeof(*stub)); done: INSIST(event == NULL); return; } /* * An SOA query has finished (successfully or not). */ static void refresh_callback(isc_task_t *task, isc_event_t *event) { const char me[] = "refresh_callback"; dns_requestevent_t *revent = (dns_requestevent_t *)event; dns_zone_t *zone; dns_message_t *msg = NULL; isc_uint32_t soacnt, cnamecnt, soacount, nscount; isc_time_t now; char master[ISC_SOCKADDR_FORMATSIZE]; char source[ISC_SOCKADDR_FORMATSIZE]; dns_rdataset_t *rdataset = NULL; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_soa_t soa; isc_result_t result; isc_uint32_t serial, oldserial = 0; unsigned int j; isc_boolean_t do_queue_xfrin = ISC_FALSE; zone = revent->ev_arg; INSIST(DNS_ZONE_VALID(zone)); UNUSED(task); ENTER; TIME_NOW(&now); LOCK_ZONE(zone); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { isc_event_free(&event); dns_request_destroy(&zone->request); goto detach; } /* * if timeout log and next master; */ isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); if (revent->result != ISC_R_SUCCESS) { if (revent->result == ISC_R_TIMEDOUT && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); dns_zone_log(zone, ISC_LOG_DEBUG(1), "refresh: timeout retrying without EDNS " "master %s (source %s)", master, source); goto same_master; } if (revent->result == ISC_R_TIMEDOUT && !dns_request_usedtcp(revent->request)) { dns_zone_log(zone, ISC_LOG_INFO, "refresh: retry limit for " "master %s exceeded (source %s)", master, source); /* Try with slave with TCP. */ if ((zone->type == dns_zone_slave || zone->type == dns_zone_redirect) && DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) { if (!dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr, &zone->sourceaddr, &now)) { DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); goto tcp_transfer; } dns_zone_log(zone, ISC_LOG_DEBUG(1), "refresh: skipped tcp fallback " "as master %s (source %s) is " "unreachable (cached)", master, source); } } else dns_zone_log(zone, ISC_LOG_INFO, "refresh: failure trying master " "%s (source %s): %s", master, source, dns_result_totext(revent->result)); goto next_master; } result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); if (result != ISC_R_SUCCESS) goto next_master; result = dns_request_getresponse(revent->request, msg, 0); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_INFO, "refresh: failure trying master " "%s (source %s): %s", master, source, dns_result_totext(result)); goto next_master; } /* * Unexpected rcode. */ if (msg->rcode != dns_rcode_noerror) { char rcode[128]; isc_buffer_t rb; isc_buffer_init(&rb, rcode, sizeof(rcode)); (void)dns_rcode_totext(msg->rcode, &rb); if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && (msg->rcode == dns_rcode_servfail || msg->rcode == dns_rcode_notimp || msg->rcode == dns_rcode_formerr)) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "refresh: rcode (%.*s) retrying without " "EDNS master %s (source %s)", (int)rb.used, rcode, master, source); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); goto same_master; } dns_zone_log(zone, ISC_LOG_INFO, "refresh: unexpected rcode (%.*s) from " "master %s (source %s)", (int)rb.used, rcode, master, source); /* * Perhaps AXFR/IXFR is allowed even if SOA queries aren't. */ if (msg->rcode == dns_rcode_refused && (zone->type == dns_zone_slave || zone->type == dns_zone_redirect)) goto tcp_transfer; goto next_master; } /* * If truncated punt to zone transfer which will query again. */ if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { if (zone->type == dns_zone_slave || zone->type == dns_zone_redirect) { dns_zone_log(zone, ISC_LOG_INFO, "refresh: truncated UDP answer, " "initiating TCP zone xfer " "for master %s (source %s)", master, source); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); goto tcp_transfer; } else { INSIST(zone->type == dns_zone_stub); if (dns_request_usedtcp(revent->request)) { dns_zone_log(zone, ISC_LOG_INFO, "refresh: truncated TCP response " "from master %s (source %s)", master, source); goto next_master; } DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC); goto same_master; } } /* * if non-auth log and next master; */ if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { dns_zone_log(zone, ISC_LOG_INFO, "refresh: non-authoritative answer from " "master %s (source %s)", master, source); goto next_master; } cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa); nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns); soacount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_soa); /* * There should not be a CNAME record at top of zone. */ if (cnamecnt != 0) { dns_zone_log(zone, ISC_LOG_INFO, "refresh: CNAME at top of zone " "in master %s (source %s)", master, source); goto next_master; } /* * if referral log and next master; */ if (soacnt == 0 && soacount == 0 && nscount != 0) { dns_zone_log(zone, ISC_LOG_INFO, "refresh: referral response " "from master %s (source %s)", master, source); goto next_master; } /* * if nodata log and next master; */ if (soacnt == 0 && (nscount == 0 || soacount != 0)) { dns_zone_log(zone, ISC_LOG_INFO, "refresh: NODATA response " "from master %s (source %s)", master, source); goto next_master; } /* * Only one soa at top of zone. */ if (soacnt != 1) { dns_zone_log(zone, ISC_LOG_INFO, "refresh: answer SOA count (%d) != 1 " "from master %s (source %s)", soacnt, master, source); goto next_master; } /* * Extract serial */ rdataset = NULL; result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin, dns_rdatatype_soa, dns_rdatatype_none, NULL, &rdataset); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_INFO, "refresh: unable to get SOA record " "from master %s (source %s)", master, source); goto next_master; } result = dns_rdataset_first(rdataset); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_INFO, "refresh: dns_rdataset_first() failed"); goto next_master; } dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &soa, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); serial = soa.serial; if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { unsigned int dbsoacount; result = zone_get_from_db(zone, zone->db, NULL, &dbsoacount, &oldserial, NULL, NULL, NULL, NULL, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); RUNTIME_CHECK(dbsoacount > 0U); zone_debuglog(zone, me, 1, "serial: new %u, old %u", serial, oldserial); } else zone_debuglog(zone, me, 1, "serial: new %u, old not loaded", serial); if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) || DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) || isc_serial_gt(serial, oldserial)) { if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr, &zone->sourceaddr, &now)) { dns_zone_log(zone, ISC_LOG_INFO, "refresh: skipping %s as master %s " "(source %s) is unreachable (cached)", (zone->type == dns_zone_slave || zone->type == dns_zone_redirect) ? "zone transfer" : "NS query", master, source); goto next_master; } tcp_transfer: isc_event_free(&event); dns_request_destroy(&zone->request); if (zone->type == dns_zone_slave || zone->type == dns_zone_redirect) { do_queue_xfrin = ISC_TRUE; } else { INSIST(zone->type == dns_zone_stub); ns_query(zone, rdataset, NULL); } if (msg != NULL) dns_message_destroy(&msg); } else if (isc_serial_eq(soa.serial, oldserial)) { if (zone->masterfile != NULL) { result = ISC_R_FAILURE; if (zone->journal != NULL) result = isc_file_settime(zone->journal, &now); if (result == ISC_R_SUCCESS && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { result = isc_file_settime(zone->masterfile, &now); } else if (result != ISC_R_SUCCESS) result = isc_file_settime(zone->masterfile, &now); /* Someone removed the file from underneath us! */ if (result == ISC_R_FILENOTFOUND) { zone_needdump(zone, DNS_DUMP_DELAY); } else if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_ERROR, "refresh: could not set file " "modification time of '%s': %s", zone->masterfile, dns_result_totext(result)); } DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime); zone->mastersok[zone->curmaster] = ISC_TRUE; goto next_master; } else { if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER)) dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) " "received from master %s < ours (%u)", soa.serial, master, oldserial); else zone_debuglog(zone, me, 1, "ahead"); zone->mastersok[zone->curmaster] = ISC_TRUE; goto next_master; } if (msg != NULL) dns_message_destroy(&msg); goto detach; next_master: if (msg != NULL) dns_message_destroy(&msg); isc_event_free(&event); dns_request_destroy(&zone->request); /* * Skip to next failed / untried master. */ do { zone->curmaster++; } while (zone->curmaster < zone->masterscnt && zone->mastersok[zone->curmaster]); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); if (zone->curmaster >= zone->masterscnt) { isc_boolean_t done = ISC_TRUE; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { /* * Did we get a good answer from all the masters? */ for (j = 0; j < zone->masterscnt; j++) if (zone->mastersok[j] == ISC_FALSE) { done = ISC_FALSE; break; } } else done = ISC_TRUE; if (!done) { DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); zone->curmaster = 0; /* * Find the next failed master. */ while (zone->curmaster < zone->masterscnt && zone->mastersok[zone->curmaster]) zone->curmaster++; goto requeue; } DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) { DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); zone->refreshtime = now; } DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); zone_settimer(zone, &now); goto detach; } requeue: queue_soa_query(zone); goto detach; same_master: if (msg != NULL) dns_message_destroy(&msg); isc_event_free(&event); dns_request_destroy(&zone->request); queue_soa_query(zone); detach: UNLOCK_ZONE(zone); if (do_queue_xfrin) queue_xfrin(zone); dns_zone_idetach(&zone); return; } static void queue_soa_query(dns_zone_t *zone) { const char me[] = "queue_soa_query"; isc_event_t *e; dns_zone_t *dummy = NULL; isc_result_t result; ENTER; /* * Locked by caller */ REQUIRE(LOCKED_ZONE(zone)); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { cancel_refresh(zone); return; } e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE, soa_query, zone, sizeof(isc_event_t)); if (e == NULL) { cancel_refresh(zone); return; } /* * Attach so that we won't clean up * until the event is delivered. */ zone_iattach(zone, &dummy); e->ev_arg = zone; e->ev_sender = NULL; result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->task, &e); if (result != ISC_R_SUCCESS) { zone_idetach(&dummy); isc_event_free(&e); cancel_refresh(zone); } } static inline isc_result_t create_query(dns_zone_t *zone, dns_rdatatype_t rdtype, dns_message_t **messagep) { dns_message_t *message = NULL; dns_name_t *qname = NULL; dns_rdataset_t *qrdataset = NULL; isc_result_t result; result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, &message); if (result != ISC_R_SUCCESS) goto cleanup; message->opcode = dns_opcode_query; message->rdclass = zone->rdclass; result = dns_message_gettempname(message, &qname); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_message_gettemprdataset(message, &qrdataset); if (result != ISC_R_SUCCESS) goto cleanup; /* * Make question. */ dns_name_init(qname, NULL); dns_name_clone(&zone->origin, qname); dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype); ISC_LIST_APPEND(qname->list, qrdataset, link); dns_message_addname(message, qname, DNS_SECTION_QUESTION); *messagep = message; return (ISC_R_SUCCESS); cleanup: if (qname != NULL) dns_message_puttempname(message, &qname); if (qrdataset != NULL) dns_message_puttemprdataset(message, &qrdataset); if (message != NULL) dns_message_destroy(&message); return (result); } static isc_result_t add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) { isc_result_t result; dns_rdataset_t *rdataset = NULL; dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS]; int count = 0; /* Set EDNS options if applicable */ if (reqnsid) { INSIST(count < DNS_EDNSOPTIONS); ednsopts[count].code = DNS_OPT_NSID; ednsopts[count].length = 0; ednsopts[count].value = NULL; count++; } result = dns_message_buildopt(message, &rdataset, 0, udpsize, 0, ednsopts, count); if (result != ISC_R_SUCCESS) return (result); return (dns_message_setopt(message, rdataset)); } static void soa_query(isc_task_t *task, isc_event_t *event) { const char me[] = "soa_query"; isc_result_t result = ISC_R_FAILURE; dns_message_t *message = NULL; dns_zone_t *zone = event->ev_arg; dns_zone_t *dummy = NULL; isc_netaddr_t masterip; dns_tsigkey_t *key = NULL; isc_uint32_t options; isc_boolean_t cancel = ISC_TRUE; int timeout; isc_boolean_t have_xfrsource, have_xfrdscp, reqnsid; isc_uint16_t udpsize = SEND_BUFFER_SIZE; isc_dscp_t dscp = -1; REQUIRE(DNS_ZONE_VALID(zone)); UNUSED(task); ENTER; LOCK_ZONE(zone); if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) || DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view->requestmgr == NULL) { if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) cancel = ISC_FALSE; goto cleanup; } again: result = create_query(zone, dns_rdatatype_soa, &message); if (result != ISC_R_SUCCESS) goto cleanup; INSIST(zone->masterscnt > 0); INSIST(zone->curmaster < zone->masterscnt); zone->masteraddr = zone->masters[zone->curmaster]; isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); /* * First, look for a tsig key in the master statement, then * try for a server key. */ if ((zone->masterkeynames != NULL) && (zone->masterkeynames[zone->curmaster] != NULL)) { dns_view_t *view = dns_zone_getview(zone); dns_name_t *keyname = zone->masterkeynames[zone->curmaster]; result = dns_view_gettsig(view, keyname, &key); if (result != ISC_R_SUCCESS) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(keyname, namebuf, sizeof(namebuf)); dns_zone_log(zone, ISC_LOG_ERROR, "unable to find key: %s", namebuf); goto skip_master; } } if (key == NULL) { result = dns_view_getpeertsig(zone->view, &masterip, &key); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { char addrbuf[ISC_NETADDR_FORMATSIZE]; isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf)); dns_zone_log(zone, ISC_LOG_ERROR, "unable to find TSIG key for %s", addrbuf); goto skip_master; } } have_xfrsource = have_xfrdscp = ISC_FALSE; reqnsid = zone->view->requestnsid; if (zone->view->peers != NULL) { dns_peer_t *peer = NULL; isc_boolean_t edns; result = dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer); if (result == ISC_R_SUCCESS) { result = dns_peer_getsupportedns(peer, &edns); if (result == ISC_R_SUCCESS && !edns) DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); result = dns_peer_gettransfersource(peer, &zone->sourceaddr); if (result == ISC_R_SUCCESS) have_xfrsource = ISC_TRUE; (void)dns_peer_gettransferdscp(peer, &dscp); if (dscp != -1) have_xfrdscp = ISC_TRUE; if (zone->view->resolver != NULL) udpsize = dns_resolver_getudpsize(zone->view->resolver); (void)dns_peer_getudpsize(peer, &udpsize); (void)dns_peer_getrequestnsid(peer, &reqnsid); } } switch (isc_sockaddr_pf(&zone->masteraddr)) { case PF_INET: if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { if (isc_sockaddr_equal(&zone->altxfrsource4, &zone->xfrsource4)) goto skip_master; zone->sourceaddr = zone->altxfrsource4; if (!have_xfrdscp) dscp = zone->altxfrsource4dscp; } else if (!have_xfrsource) { zone->sourceaddr = zone->xfrsource4; if (!have_xfrdscp) dscp = zone->xfrsource4dscp; } break; case PF_INET6: if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { if (isc_sockaddr_equal(&zone->altxfrsource6, &zone->xfrsource6)) goto skip_master; zone->sourceaddr = zone->altxfrsource6; if (!have_xfrdscp) dscp = zone->altxfrsource6dscp; } else if (!have_xfrsource) { zone->sourceaddr = zone->xfrsource6; if (!have_xfrdscp) dscp = zone->xfrsource6dscp; } break; default: result = ISC_R_NOTIMPLEMENTED; goto cleanup; } options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ? DNS_REQUESTOPT_TCP : 0; if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { result = add_opt(message, udpsize, reqnsid); if (result != ISC_R_SUCCESS) zone_debuglog(zone, me, 1, "unable to add opt record: %s", dns_result_totext(result)); } zone_iattach(zone, &dummy); timeout = 15; if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) timeout = 30; result = dns_request_createvia4(zone->view->requestmgr, message, &zone->sourceaddr, &zone->masteraddr, dscp, options, key, timeout * 3, timeout, 0, zone->task, refresh_callback, zone, &zone->request); if (result != ISC_R_SUCCESS) { zone_idetach(&dummy); zone_debuglog(zone, me, 1, "dns_request_createvia4() failed: %s", dns_result_totext(result)); goto skip_master; } else { if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET) inc_stats(zone, dns_zonestatscounter_soaoutv4); else inc_stats(zone, dns_zonestatscounter_soaoutv6); } cancel = ISC_FALSE; cleanup: if (key != NULL) dns_tsigkey_detach(&key); if (result != ISC_R_SUCCESS) DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); if (message != NULL) dns_message_destroy(&message); if (cancel) cancel_refresh(zone); isc_event_free(&event); UNLOCK_ZONE(zone); dns_zone_idetach(&zone); return; skip_master: if (key != NULL) dns_tsigkey_detach(&key); dns_message_destroy(&message); /* * Skip to next failed / untried master. */ do { zone->curmaster++; } while (zone->curmaster < zone->masterscnt && zone->mastersok[zone->curmaster]); if (zone->curmaster < zone->masterscnt) goto again; zone->curmaster = 0; goto cleanup; } static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { const char me[] = "ns_query"; isc_result_t result; dns_message_t *message = NULL; isc_netaddr_t masterip; dns_tsigkey_t *key = NULL; dns_dbnode_t *node = NULL; int timeout; isc_boolean_t have_xfrsource = ISC_FALSE, have_xfrdscp = ISC_FALSE; isc_boolean_t reqnsid; isc_uint16_t udpsize = SEND_BUFFER_SIZE; isc_dscp_t dscp = -1; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(LOCKED_ZONE(zone)); REQUIRE((soardataset != NULL && stub == NULL) || (soardataset == NULL && stub != NULL)); REQUIRE(stub == NULL || DNS_STUB_VALID(stub)); ENTER; if (stub == NULL) { stub = isc_mem_get(zone->mctx, sizeof(*stub)); if (stub == NULL) goto cleanup; stub->magic = STUB_MAGIC; stub->mctx = zone->mctx; stub->zone = NULL; stub->db = NULL; stub->version = NULL; /* * Attach so that the zone won't disappear from under us. */ zone_iattach(zone, &stub->zone); /* * If a db exists we will update it, otherwise we create a * new one and attach it to the zone once we have the NS * RRset and glue. */ ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) { dns_db_attach(zone->db, &stub->db); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); } else { ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); INSIST(zone->db_argc >= 1); result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin, dns_dbtype_stub, zone->rdclass, zone->db_argc - 1, zone->db_argv + 1, &stub->db); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "refreshing stub: " "could not create " "database: %s", dns_result_totext(result)); goto cleanup; } dns_db_settask(stub->db, zone->task); } result = dns_db_newversion(stub->db, &stub->version); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: " "dns_db_newversion() failed: %s", dns_result_totext(result)); goto cleanup; } /* * Update SOA record. */ result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE, &node); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: " "dns_db_findnode() failed: %s", dns_result_totext(result)); goto cleanup; } result = dns_db_addrdataset(stub->db, node, stub->version, 0, soardataset, 0, NULL); dns_db_detachnode(stub->db, &node); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: " "dns_db_addrdataset() failed: %s", dns_result_totext(result)); goto cleanup; } } /* * XXX Optimisation: Create message when zone is setup and reuse. */ result = create_query(zone, dns_rdatatype_ns, &message); INSIST(result == ISC_R_SUCCESS); INSIST(zone->masterscnt > 0); INSIST(zone->curmaster < zone->masterscnt); zone->masteraddr = zone->masters[zone->curmaster]; isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); /* * First, look for a tsig key in the master statement, then * try for a server key. */ if ((zone->masterkeynames != NULL) && (zone->masterkeynames[zone->curmaster] != NULL)) { dns_view_t *view = dns_zone_getview(zone); dns_name_t *keyname = zone->masterkeynames[zone->curmaster]; result = dns_view_gettsig(view, keyname, &key); if (result != ISC_R_SUCCESS) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(keyname, namebuf, sizeof(namebuf)); dns_zone_log(zone, ISC_LOG_ERROR, "unable to find key: %s", namebuf); } } if (key == NULL) (void)dns_view_getpeertsig(zone->view, &masterip, &key); reqnsid = zone->view->requestnsid; if (zone->view->peers != NULL) { dns_peer_t *peer = NULL; isc_boolean_t edns; result = dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer); if (result == ISC_R_SUCCESS) { result = dns_peer_getsupportedns(peer, &edns); if (result == ISC_R_SUCCESS && !edns) DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); result = dns_peer_gettransfersource(peer, &zone->sourceaddr); if (result == ISC_R_SUCCESS) have_xfrsource = ISC_TRUE; result = dns_peer_gettransferdscp(peer, &dscp); if (result == ISC_R_SUCCESS && dscp != -1) have_xfrdscp = ISC_TRUE; if (zone->view->resolver != NULL) udpsize = dns_resolver_getudpsize(zone->view->resolver); (void)dns_peer_getudpsize(peer, &udpsize); (void)dns_peer_getrequestnsid(peer, &reqnsid); } } if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { result = add_opt(message, udpsize, reqnsid); if (result != ISC_R_SUCCESS) zone_debuglog(zone, me, 1, "unable to add opt record: %s", dns_result_totext(result)); } /* * Always use TCP so that we shouldn't truncate in additional section. */ switch (isc_sockaddr_pf(&zone->masteraddr)) { case PF_INET: if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { zone->sourceaddr = zone->altxfrsource4; if (!have_xfrdscp) dscp = zone->altxfrsource4dscp; } else if (!have_xfrsource) { zone->sourceaddr = zone->xfrsource4; if (!have_xfrdscp) dscp = zone->xfrsource4dscp; } break; case PF_INET6: if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { zone->sourceaddr = zone->altxfrsource6; if (!have_xfrdscp) dscp = zone->altxfrsource6dscp; } else if (!have_xfrsource) { zone->sourceaddr = zone->xfrsource6; if (!have_xfrdscp) dscp = zone->xfrsource6dscp; } break; default: result = ISC_R_NOTIMPLEMENTED; POST(result); goto cleanup; } timeout = 15; if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) timeout = 30; result = dns_request_createvia4(zone->view->requestmgr, message, &zone->sourceaddr, &zone->masteraddr, dscp, DNS_REQUESTOPT_TCP, key, timeout * 3, timeout, 0, zone->task, stub_callback, stub, &zone->request); if (result != ISC_R_SUCCESS) { zone_debuglog(zone, me, 1, "dns_request_createvia() failed: %s", dns_result_totext(result)); goto cleanup; } dns_message_destroy(&message); goto unlock; cleanup: cancel_refresh(zone); if (stub != NULL) { stub->magic = 0; if (stub->version != NULL) dns_db_closeversion(stub->db, &stub->version, ISC_FALSE); if (stub->db != NULL) dns_db_detach(&stub->db); if (stub->zone != NULL) zone_idetach(&stub->zone); isc_mem_put(stub->mctx, stub, sizeof(*stub)); } if (message != NULL) dns_message_destroy(&message); unlock: if (key != NULL) dns_tsigkey_detach(&key); return; } /* * Handle the control event. Note that although this event causes the zone * to shut down, it is not a shutdown event in the sense of the task library. */ static void zone_shutdown(isc_task_t *task, isc_event_t *event) { dns_zone_t *zone = (dns_zone_t *) event->ev_arg; isc_boolean_t free_needed, linked = ISC_FALSE; dns_zone_t *raw = NULL, *secure = NULL; UNUSED(task); REQUIRE(DNS_ZONE_VALID(zone)); INSIST(event->ev_type == DNS_EVENT_ZONECONTROL); INSIST(isc_refcount_current(&zone->erefs) == 0); zone_debuglog(zone, "zone_shutdown", 3, "shutting down"); /* * Stop things being restarted after we cancel them below. */ LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING); UNLOCK_ZONE(zone); /* * If we were waiting for xfrin quota, step out of * the queue. * If there's no zone manager, we can't be waiting for the * xfrin quota */ if (zone->zmgr != NULL) { RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); if (zone->statelist == &zone->zmgr->waiting_for_xfrin) { ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone, statelink); linked = ISC_TRUE; zone->statelist = NULL; } if (zone->statelist == &zone->zmgr->xfrin_in_progress) { ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink); zone->statelist = NULL; zmgr_resume_xfrs(zone->zmgr, ISC_FALSE); } RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); } /* * In task context, no locking required. See zone_xfrdone(). */ if (zone->xfr != NULL) dns_xfrin_shutdown(zone->xfr); /* Safe to release the zone now */ if (zone->zmgr != NULL) dns_zonemgr_releasezone(zone->zmgr, zone); LOCK_ZONE(zone); INSIST(zone != zone->raw); if (linked) { INSIST(zone->irefs > 0); zone->irefs--; } if (zone->request != NULL) { dns_request_cancel(zone->request); } if (zone->readio != NULL) zonemgr_cancelio(zone->readio); if (zone->lctx != NULL) dns_loadctx_cancel(zone->lctx); if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) || !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { if (zone->writeio != NULL) zonemgr_cancelio(zone->writeio); if (zone->dctx != NULL) dns_dumpctx_cancel(zone->dctx); } notify_cancel(zone); forward_cancel(zone); if (zone->timer != NULL) { isc_timer_detach(&zone->timer); INSIST(zone->irefs > 0); zone->irefs--; } if (zone->view != NULL) dns_view_weakdetach(&zone->view); /* * We have now canceled everything set the flag to allow exit_check() * to succeed. We must not unlock between setting this flag and * calling exit_check(). */ DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN); free_needed = exit_check(zone); if (inline_secure(zone)) { raw = zone->raw; zone->raw = NULL; } if (inline_raw(zone)) { secure = zone->secure; zone->secure = NULL; } UNLOCK_ZONE(zone); if (raw != NULL) dns_zone_detach(&raw); if (secure != NULL) dns_zone_idetach(&secure); if (free_needed) zone_free(zone); } static void zone_timer(isc_task_t *task, isc_event_t *event) { const char me[] = "zone_timer"; dns_zone_t *zone = (dns_zone_t *)event->ev_arg; UNUSED(task); REQUIRE(DNS_ZONE_VALID(zone)); ENTER; zone_maintenance(zone); isc_event_free(&event); } static void zone_settimer(dns_zone_t *zone, isc_time_t *now) { const char me[] = "zone_settimer"; isc_time_t next; isc_result_t result; REQUIRE(DNS_ZONE_VALID(zone)); ENTER; if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) return; isc_time_settoepoch(&next); switch (zone->type) { case dns_zone_redirect: if (zone->masters != NULL) goto treat_as_slave; /* FALLTHROUGH */ case dns_zone_master: if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) next = zone->notifytime; if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { INSIST(!isc_time_isepoch(&zone->dumptime)); if (isc_time_isepoch(&next) || isc_time_compare(&zone->dumptime, &next) < 0) next = zone->dumptime; } if (zone->type == dns_zone_redirect) break; if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) && !isc_time_isepoch(&zone->refreshkeytime)) { if (isc_time_isepoch(&next) || isc_time_compare(&zone->refreshkeytime, &next) < 0) next = zone->refreshkeytime; } if (!isc_time_isepoch(&zone->resigntime)) { if (isc_time_isepoch(&next) || isc_time_compare(&zone->resigntime, &next) < 0) next = zone->resigntime; } if (!isc_time_isepoch(&zone->keywarntime)) { if (isc_time_isepoch(&next) || isc_time_compare(&zone->keywarntime, &next) < 0) next = zone->keywarntime; } if (!isc_time_isepoch(&zone->signingtime)) { if (isc_time_isepoch(&next) || isc_time_compare(&zone->signingtime, &next) < 0) next = zone->signingtime; } if (!isc_time_isepoch(&zone->nsec3chaintime)) { if (isc_time_isepoch(&next) || isc_time_compare(&zone->nsec3chaintime, &next) < 0) next = zone->nsec3chaintime; } break; case dns_zone_slave: treat_as_slave: if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) next = zone->notifytime; /* FALLTHROUGH */ case dns_zone_stub: if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING) && !isc_time_isepoch(&zone->refreshtime) && (isc_time_isepoch(&next) || isc_time_compare(&zone->refreshtime, &next) < 0)) next = zone->refreshtime; if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && !isc_time_isepoch(&zone->expiretime)) { if (isc_time_isepoch(&next) || isc_time_compare(&zone->expiretime, &next) < 0) next = zone->expiretime; } if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { INSIST(!isc_time_isepoch(&zone->dumptime)); if (isc_time_isepoch(&next) || isc_time_compare(&zone->dumptime, &next) < 0) next = zone->dumptime; } break; case dns_zone_key: if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { INSIST(!isc_time_isepoch(&zone->dumptime)); if (isc_time_isepoch(&next) || isc_time_compare(&zone->dumptime, &next) < 0) next = zone->dumptime; } if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) { if (isc_time_isepoch(&next) || (!isc_time_isepoch(&zone->refreshkeytime) && isc_time_compare(&zone->refreshkeytime, &next) < 0)) next = zone->refreshkeytime; } break; default: break; } if (isc_time_isepoch(&next)) { zone_debuglog(zone, me, 10, "settimer inactive"); result = isc_timer_reset(zone->timer, isc_timertype_inactive, NULL, NULL, ISC_TRUE); if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_ERROR, "could not deactivate zone timer: %s", isc_result_totext(result)); } else { if (isc_time_compare(&next, now) <= 0) next = *now; result = isc_timer_reset(zone->timer, isc_timertype_once, &next, NULL, ISC_TRUE); if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_ERROR, "could not reset zone timer: %s", isc_result_totext(result)); } } static void cancel_refresh(dns_zone_t *zone) { const char me[] = "cancel_refresh"; isc_time_t now; /* * 'zone' locked by caller. */ REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(LOCKED_ZONE(zone)); ENTER; DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); TIME_NOW(&now); zone_settimer(zone, &now); } static isc_result_t notify_createmessage(dns_zone_t *zone, unsigned int flags, dns_message_t **messagep) { dns_db_t *zonedb = NULL; dns_dbnode_t *node = NULL; dns_dbversion_t *version = NULL; dns_message_t *message = NULL; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; dns_name_t *tempname = NULL; dns_rdata_t *temprdata = NULL; dns_rdatalist_t *temprdatalist = NULL; dns_rdataset_t *temprdataset = NULL; isc_result_t result; isc_region_t r; isc_buffer_t *b = NULL; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(messagep != NULL && *messagep == NULL); result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, &message); if (result != ISC_R_SUCCESS) return (result); message->opcode = dns_opcode_notify; message->flags |= DNS_MESSAGEFLAG_AA; message->rdclass = zone->rdclass; result = dns_message_gettempname(message, &tempname); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_message_gettemprdataset(message, &temprdataset); if (result != ISC_R_SUCCESS) goto cleanup; /* * Make question. */ dns_name_init(tempname, NULL); dns_name_clone(&zone->origin, tempname); dns_rdataset_makequestion(temprdataset, zone->rdclass, dns_rdatatype_soa); ISC_LIST_APPEND(tempname->list, temprdataset, link); dns_message_addname(message, tempname, DNS_SECTION_QUESTION); tempname = NULL; temprdataset = NULL; if ((flags & DNS_NOTIFY_NOSOA) != 0) goto done; result = dns_message_gettempname(message, &tempname); if (result != ISC_R_SUCCESS) goto soa_cleanup; result = dns_message_gettemprdata(message, &temprdata); if (result != ISC_R_SUCCESS) goto soa_cleanup; result = dns_message_gettemprdataset(message, &temprdataset); if (result != ISC_R_SUCCESS) goto soa_cleanup; result = dns_message_gettemprdatalist(message, &temprdatalist); if (result != ISC_R_SUCCESS) goto soa_cleanup; ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */ dns_db_attach(zone->db, &zonedb); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); dns_name_init(tempname, NULL); dns_name_clone(&zone->origin, tempname); dns_db_currentversion(zonedb, &version); result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) goto soa_cleanup; dns_rdataset_init(&rdataset); result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa, dns_rdatatype_none, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) goto soa_cleanup; result = dns_rdataset_first(&rdataset); if (result != ISC_R_SUCCESS) goto soa_cleanup; dns_rdataset_current(&rdataset, &rdata); dns_rdata_toregion(&rdata, &r); result = isc_buffer_allocate(zone->mctx, &b, r.length); if (result != ISC_R_SUCCESS) goto soa_cleanup; isc_buffer_putmem(b, r.base, r.length); isc_buffer_usedregion(b, &r); dns_rdata_init(temprdata); dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r); dns_message_takebuffer(message, &b); result = dns_rdataset_next(&rdataset); dns_rdataset_disassociate(&rdataset); if (result != ISC_R_NOMORE) goto soa_cleanup; temprdatalist->rdclass = rdata.rdclass; temprdatalist->type = rdata.type; temprdatalist->ttl = rdataset.ttl; ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link); result = dns_rdatalist_tordataset(temprdatalist, temprdataset); if (result != ISC_R_SUCCESS) goto soa_cleanup; ISC_LIST_APPEND(tempname->list, temprdataset, link); dns_message_addname(message, tempname, DNS_SECTION_ANSWER); temprdatalist = NULL; temprdataset = NULL; temprdata = NULL; tempname = NULL; soa_cleanup: if (node != NULL) dns_db_detachnode(zonedb, &node); if (version != NULL) dns_db_closeversion(zonedb, &version, ISC_FALSE); if (zonedb != NULL) dns_db_detach(&zonedb); if (tempname != NULL) dns_message_puttempname(message, &tempname); if (temprdata != NULL) dns_message_puttemprdata(message, &temprdata); if (temprdataset != NULL) dns_message_puttemprdataset(message, &temprdataset); if (temprdatalist != NULL) dns_message_puttemprdatalist(message, &temprdatalist); done: *messagep = message; return (ISC_R_SUCCESS); cleanup: if (tempname != NULL) dns_message_puttempname(message, &tempname); if (temprdataset != NULL) dns_message_puttemprdataset(message, &temprdataset); dns_message_destroy(&message); return (result); } isc_result_t dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, dns_message_t *msg) { unsigned int i; dns_rdata_soa_t soa; dns_rdataset_t *rdataset = NULL; dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; char fromtext[ISC_SOCKADDR_FORMATSIZE]; int match = 0; isc_netaddr_t netaddr; isc_sockaddr_t local, remote; isc_uint32_t serial = 0; isc_boolean_t have_serial = ISC_FALSE; dns_tsigkey_t *tsigkey; dns_name_t *tsig; REQUIRE(DNS_ZONE_VALID(zone)); /* * If type != T_SOA return DNS_R_NOTIMP. We don't yet support * ROLLOVER. * * SOA: RFC1996 * Check that 'from' is a valid notify source, (zone->masters). * Return DNS_R_REFUSED if not. * * If the notify message contains a serial number check it * against the zones serial and return if <= current serial * * If a refresh check is progress, if so just record the * fact we received a NOTIFY and from where and return. * We will perform a new refresh check when the current one * completes. Return ISC_R_SUCCESS. * * Otherwise initiate a refresh check using 'from' as the * first address to check. Return ISC_R_SUCCESS. */ isc_sockaddr_format(from, fromtext, sizeof(fromtext)); /* * Notify messages are processed by the raw zone. */ LOCK_ZONE(zone); INSIST(zone != zone->raw); if (inline_secure(zone)) { result = dns_zone_notifyreceive(zone->raw, from, msg); UNLOCK_ZONE(zone); return (result); } /* * We only handle NOTIFY (SOA) at the present. */ if (isc_sockaddr_pf(from) == PF_INET) inc_stats(zone, dns_zonestatscounter_notifyinv4); else inc_stats(zone, dns_zonestatscounter_notifyinv6); if (msg->counts[DNS_SECTION_QUESTION] == 0 || dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin, dns_rdatatype_soa, dns_rdatatype_none, NULL, NULL) != ISC_R_SUCCESS) { UNLOCK_ZONE(zone); if (msg->counts[DNS_SECTION_QUESTION] == 0) { dns_zone_log(zone, ISC_LOG_NOTICE, "NOTIFY with no " "question section from: %s", fromtext); return (DNS_R_FORMERR); } dns_zone_log(zone, ISC_LOG_NOTICE, "NOTIFY zone does not match"); return (DNS_R_NOTIMP); } /* * If we are a master zone just succeed. */ if (zone->type == dns_zone_master) { UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); } isc_netaddr_fromsockaddr(&netaddr, from); for (i = 0; i < zone->masterscnt; i++) { if (isc_sockaddr_eqaddr(from, &zone->masters[i])) break; if (zone->view->aclenv.match_mapped && IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) && isc_sockaddr_pf(&zone->masters[i]) == AF_INET) { isc_netaddr_t na1, na2; isc_netaddr_fromv4mapped(&na1, &netaddr); isc_netaddr_fromsockaddr(&na2, &zone->masters[i]); if (isc_netaddr_equal(&na1, &na2)) break; } } /* * Accept notify requests from non masters if they are on * 'zone->notify_acl'. */ tsigkey = dns_message_gettsigkey(msg); tsig = dns_tsigkey_identity(tsigkey); if (i >= zone->masterscnt && zone->notify_acl != NULL && dns_acl_match(&netaddr, tsig, zone->notify_acl, &zone->view->aclenv, &match, NULL) == ISC_R_SUCCESS && match > 0) { /* Accept notify. */ } else if (i >= zone->masterscnt) { UNLOCK_ZONE(zone); dns_zone_log(zone, ISC_LOG_INFO, "refused notify from non-master: %s", fromtext); inc_stats(zone, dns_zonestatscounter_notifyrej); return (DNS_R_REFUSED); } /* * If the zone is loaded and there are answers check the serial * to see if we need to do a refresh. Do not worry about this * check if we are a dialup zone as we use the notify request * to trigger a refresh check. */ if (msg->counts[DNS_SECTION_ANSWER] > 0 && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) { result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin, dns_rdatatype_soa, dns_rdatatype_none, NULL, &rdataset); if (result == ISC_R_SUCCESS) result = dns_rdataset_first(rdataset); if (result == ISC_R_SUCCESS) { isc_uint32_t oldserial; unsigned int soacount; dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &soa, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); serial = soa.serial; have_serial = ISC_TRUE; /* * The following should safely be performed without DB * lock and succeed in this context. */ result = zone_get_from_db(zone, zone->db, NULL, &soacount, &oldserial, NULL, NULL, NULL, NULL, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); RUNTIME_CHECK(soacount > 0U); if (isc_serial_le(serial, oldserial)) { dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: " "zone is up to date", fromtext); UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); } } } /* * If we got this far and there was a refresh in progress just * let it complete. Record where we got the notify from so we * can perform a refresh check when the current one completes */ if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) { DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); zone->notifyfrom = *from; UNLOCK_ZONE(zone); if (have_serial) dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: serial %u: refresh in " "progress, refresh check queued", fromtext, serial); else dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: refresh in progress, " "refresh check queued", fromtext); return (ISC_R_SUCCESS); } if (have_serial) dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: serial %u", fromtext, serial); else dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: no serial", fromtext); zone->notifyfrom = *from; remote = zone->masteraddr; local = zone->sourceaddr; UNLOCK_ZONE(zone); dns_zonemgr_unreachabledel(zone->zmgr, &remote, &local); dns_zone_refresh(zone); return (ISC_R_SUCCESS); } void dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (zone->notify_acl != NULL) dns_acl_detach(&zone->notify_acl); dns_acl_attach(acl, &zone->notify_acl); UNLOCK_ZONE(zone); } void dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (zone->query_acl != NULL) dns_acl_detach(&zone->query_acl); dns_acl_attach(acl, &zone->query_acl); UNLOCK_ZONE(zone); } void dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (zone->queryon_acl != NULL) dns_acl_detach(&zone->queryon_acl); dns_acl_attach(acl, &zone->queryon_acl); UNLOCK_ZONE(zone); } void dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (zone->update_acl != NULL) dns_acl_detach(&zone->update_acl); dns_acl_attach(acl, &zone->update_acl); UNLOCK_ZONE(zone); } void dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (zone->forward_acl != NULL) dns_acl_detach(&zone->forward_acl); dns_acl_attach(acl, &zone->forward_acl); UNLOCK_ZONE(zone); } void dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (zone->xfr_acl != NULL) dns_acl_detach(&zone->xfr_acl); dns_acl_attach(acl, &zone->xfr_acl); UNLOCK_ZONE(zone); } dns_acl_t * dns_zone_getnotifyacl(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->notify_acl); } dns_acl_t * dns_zone_getqueryacl(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->query_acl); } dns_acl_t * dns_zone_getqueryonacl(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->queryon_acl); } dns_acl_t * dns_zone_getupdateacl(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->update_acl); } dns_acl_t * dns_zone_getforwardacl(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->forward_acl); } dns_acl_t * dns_zone_getxfracl(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->xfr_acl); } void dns_zone_clearupdateacl(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (zone->update_acl != NULL) dns_acl_detach(&zone->update_acl); UNLOCK_ZONE(zone); } void dns_zone_clearforwardacl(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (zone->forward_acl != NULL) dns_acl_detach(&zone->forward_acl); UNLOCK_ZONE(zone); } void dns_zone_clearnotifyacl(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (zone->notify_acl != NULL) dns_acl_detach(&zone->notify_acl); UNLOCK_ZONE(zone); } void dns_zone_clearqueryacl(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (zone->query_acl != NULL) dns_acl_detach(&zone->query_acl); UNLOCK_ZONE(zone); } void dns_zone_clearqueryonacl(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (zone->queryon_acl != NULL) dns_acl_detach(&zone->queryon_acl); UNLOCK_ZONE(zone); } void dns_zone_clearxfracl(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (zone->xfr_acl != NULL) dns_acl_detach(&zone->xfr_acl); UNLOCK_ZONE(zone); } isc_boolean_t dns_zone_getupdatedisabled(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->update_disabled); } void dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) { REQUIRE(DNS_ZONE_VALID(zone)); zone->update_disabled = state; } isc_boolean_t dns_zone_getzeronosoattl(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->zero_no_soa_ttl); } void dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) { REQUIRE(DNS_ZONE_VALID(zone)); zone->zero_no_soa_ttl = state; } void dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) { REQUIRE(DNS_ZONE_VALID(zone)); zone->check_names = severity; } dns_severity_t dns_zone_getchecknames(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->check_names); } void dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) { REQUIRE(DNS_ZONE_VALID(zone)); zone->journalsize = size; } isc_int32_t dns_zone_getjournalsize(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->journalsize); } static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) { isc_result_t result = ISC_R_FAILURE; isc_buffer_t buffer; REQUIRE(buf != NULL); REQUIRE(length > 1U); /* * Leave space for terminating '\0'. */ isc_buffer_init(&buffer, buf, (unsigned int)length - 1); if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) { if (dns_name_dynamic(&zone->origin)) result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer); if (result != ISC_R_SUCCESS && isc_buffer_availablelength(&buffer) >= (sizeof("") - 1)) isc_buffer_putstr(&buffer, ""); if (isc_buffer_availablelength(&buffer) > 0) isc_buffer_putstr(&buffer, "/"); (void)dns_rdataclass_totext(zone->rdclass, &buffer); } if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 && strcmp(zone->view->name, "_default") != 0 && strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) { isc_buffer_putstr(&buffer, "/"); isc_buffer_putstr(&buffer, zone->view->name); } if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer)) isc_buffer_putstr(&buffer, " (signed)"); if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer)) isc_buffer_putstr(&buffer, " (unsigned)"); buf[isc_buffer_usedlength(&buffer)] = '\0'; } static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) { isc_result_t result = ISC_R_FAILURE; isc_buffer_t buffer; REQUIRE(buf != NULL); REQUIRE(length > 1U); /* * Leave space for terminating '\0'. */ isc_buffer_init(&buffer, buf, (unsigned int)length - 1); if (dns_name_dynamic(&zone->origin)) result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer); if (result != ISC_R_SUCCESS && isc_buffer_availablelength(&buffer) >= (sizeof("") - 1)) isc_buffer_putstr(&buffer, ""); buf[isc_buffer_usedlength(&buffer)] = '\0'; } static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) { isc_buffer_t buffer; REQUIRE(buf != NULL); REQUIRE(length > 1U); /* * Leave space for terminating '\0'. */ isc_buffer_init(&buffer, buf, (unsigned int)length - 1); (void)dns_rdataclass_totext(zone->rdclass, &buffer); buf[isc_buffer_usedlength(&buffer)] = '\0'; } static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) { isc_buffer_t buffer; REQUIRE(buf != NULL); REQUIRE(length > 1U); /* * Leave space for terminating '\0'. */ isc_buffer_init(&buffer, buf, (unsigned int)length - 1); if (zone->view == NULL) { isc_buffer_putstr(&buffer, "_none"); } else if (strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) { isc_buffer_putstr(&buffer, zone->view->name); } else { isc_buffer_putstr(&buffer, "_toolong"); } buf[isc_buffer_usedlength(&buffer)] = '\0'; } void dns_zone_name(dns_zone_t *zone, char *buf, size_t length) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(buf != NULL); zone_namerd_tostr(zone, buf, length); } void dns_zone_nameonly(dns_zone_t *zone, char *buf, size_t length) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(buf != NULL); zone_name_tostr(zone, buf, length); } static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...) { va_list ap; char message[4096]; if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) return; va_start(ap, fmt); vsnprintf(message, sizeof(message), fmt, ap); va_end(ap); isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE, level, "zone %s: %s", zone->strnamerd, message); } void dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category, int level, const char *fmt, ...) { va_list ap; char message[4096]; if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) return; va_start(ap, fmt); vsnprintf(message, sizeof(message), fmt, ap); va_end(ap); isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE, level, "%s%s: %s", (zone->type == dns_zone_key) ? "managed-keys-zone" : (zone->type == dns_zone_redirect) ? "redirect-zone" : "zone ", zone->strnamerd, message); } void dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) { va_list ap; char message[4096]; if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) return; va_start(ap, fmt); vsnprintf(message, sizeof(message), fmt, ap); va_end(ap); isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, level, "%s%s: %s", (zone->type == dns_zone_key) ? "managed-keys-zone" : (zone->type == dns_zone_redirect) ? "redirect-zone" : "zone ", zone->strnamerd, message); } static void zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel, const char *fmt, ...) { va_list ap; char message[4096]; int level = ISC_LOG_DEBUG(debuglevel); const char *zstr; if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) return; va_start(ap, fmt); vsnprintf(message, sizeof(message), fmt, ap); va_end(ap); switch (zone->type) { case dns_zone_key: zstr = "managed-keys-zone"; break; case dns_zone_redirect: zstr = "redirect-zone"; break; default: zstr = "zone"; } isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, level, "%s: %s %s: %s", me, zstr, zone->strnamerd, message); } static int message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type) { isc_result_t result; dns_name_t *name; dns_rdataset_t *curr; int count = 0; result = dns_message_firstname(msg, section); while (result == ISC_R_SUCCESS) { name = NULL; dns_message_currentname(msg, section, &name); for (curr = ISC_LIST_TAIL(name->list); curr != NULL; curr = ISC_LIST_PREV(curr, link)) { if (curr->type == type) count++; } result = dns_message_nextname(msg, section); } return (count); } void dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) { REQUIRE(DNS_ZONE_VALID(zone)); zone->maxxfrin = maxxfrin; } isc_uint32_t dns_zone_getmaxxfrin(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->maxxfrin); } void dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) { REQUIRE(DNS_ZONE_VALID(zone)); zone->maxxfrout = maxxfrout; } isc_uint32_t dns_zone_getmaxxfrout(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->maxxfrout); } dns_zonetype_t dns_zone_gettype(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->type); } dns_name_t * dns_zone_getorigin(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (&zone->origin); } void dns_zone_settask(dns_zone_t *zone, isc_task_t *task) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (zone->task != NULL) isc_task_detach(&zone->task); isc_task_attach(task, &zone->task); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) dns_db_settask(zone->db, zone->task); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); UNLOCK_ZONE(zone); } void dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) { REQUIRE(DNS_ZONE_VALID(zone)); isc_task_attach(zone->task, target); } void dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) { REQUIRE(DNS_ZONE_VALID(zone)); if (idlein == 0) idlein = DNS_DEFAULT_IDLEIN; zone->idlein = idlein; } isc_uint32_t dns_zone_getidlein(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->idlein); } void dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) { REQUIRE(DNS_ZONE_VALID(zone)); zone->idleout = idleout; } isc_uint32_t dns_zone_getidleout(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->idleout); } static void notify_done(isc_task_t *task, isc_event_t *event) { dns_requestevent_t *revent = (dns_requestevent_t *)event; dns_notify_t *notify; isc_result_t result; dns_message_t *message = NULL; isc_buffer_t buf; char rcode[128]; char addrbuf[ISC_SOCKADDR_FORMATSIZE]; UNUSED(task); notify = event->ev_arg; REQUIRE(DNS_NOTIFY_VALID(notify)); INSIST(task == notify->zone->task); isc_buffer_init(&buf, rcode, sizeof(rcode)); isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); result = revent->result; if (result == ISC_R_SUCCESS) result = dns_message_create(notify->zone->mctx, DNS_MESSAGE_INTENTPARSE, &message); if (result == ISC_R_SUCCESS) result = dns_request_getresponse(revent->request, message, DNS_MESSAGEPARSE_PRESERVEORDER); if (result == ISC_R_SUCCESS) result = dns_rcode_totext(message->rcode, &buf); if (result == ISC_R_SUCCESS) notify_log(notify->zone, ISC_LOG_DEBUG(3), "notify response from %s: %.*s", addrbuf, (int)buf.used, rcode); else notify_log(notify->zone, ISC_LOG_DEBUG(2), "notify to %s failed: %s", addrbuf, dns_result_totext(result)); /* * Old bind's return formerr if they see a soa record. Retry w/o * the soa if we see a formerr and had sent a SOA. */ isc_event_free(&event); if (message != NULL && message->rcode == dns_rcode_formerr && (notify->flags & DNS_NOTIFY_NOSOA) == 0) { isc_boolean_t startup; notify->flags |= DNS_NOTIFY_NOSOA; dns_request_destroy(¬ify->request); startup = ISC_TF((notify->flags & DNS_NOTIFY_STARTUP) != 0); result = notify_send_queue(notify, startup); if (result != ISC_R_SUCCESS) notify_destroy(notify, ISC_FALSE); } else { if (result == ISC_R_TIMEDOUT) notify_log(notify->zone, ISC_LOG_DEBUG(1), "notify to %s: retries exceeded", addrbuf); notify_destroy(notify, ISC_FALSE); } if (message != NULL) dns_message_destroy(&message); } struct secure_event { isc_event_t e; dns_db_t *db; isc_uint32_t serial; }; static void update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) { UNUSED(arg); dns_zone_log(zone, level, "%s", message); } static isc_result_t sync_secure_journal(dns_zone_t *zone, dns_zone_t *raw, dns_journal_t *journal, isc_uint32_t start, isc_uint32_t end, dns_difftuple_t **soatuplep, dns_diff_t *diff) { isc_result_t result; dns_difftuple_t *tuple = NULL; dns_diffop_t op = DNS_DIFFOP_ADD; int n_soa = 0; REQUIRE(soatuplep != NULL); if (start == end) return (DNS_R_UNCHANGED); CHECK(dns_journal_iter_init(journal, start, end)); for (result = dns_journal_first_rr(journal); result == ISC_R_SUCCESS; result = dns_journal_next_rr(journal)) { dns_name_t *name = NULL; isc_uint32_t ttl; dns_rdata_t *rdata = NULL; dns_journal_current_rr(journal, &name, &ttl, &rdata); if (rdata->type == dns_rdatatype_soa) { n_soa++; if (n_soa == 2) { /* * Save the latest raw SOA record. */ if (*soatuplep != NULL) dns_difftuple_free(soatuplep); CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name, ttl, rdata, soatuplep)); } if (n_soa == 3) n_soa = 1; continue; } /* Sanity. */ if (n_soa == 0) { dns_zone_log(raw, ISC_LOG_ERROR, "corrupt journal file: '%s'\n", raw->journal); return (ISC_R_FAILURE); } if (zone->privatetype != 0 && rdata->type == zone->privatetype) continue; if (rdata->type == dns_rdatatype_nsec || rdata->type == dns_rdatatype_rrsig || rdata->type == dns_rdatatype_nsec3 || rdata->type == dns_rdatatype_dnskey || rdata->type == dns_rdatatype_nsec3param) continue; op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD; CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata, &tuple)); dns_diff_appendminimal(diff, &tuple); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; failure: return(result); } static isc_result_t sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb, dns_dbversion_t *secver, dns_difftuple_t **soatuple, dns_diff_t *diff) { isc_result_t result; dns_db_t *rawdb = NULL; dns_dbversion_t *rawver = NULL; dns_difftuple_t *tuple = NULL, *next; dns_difftuple_t *oldtuple = NULL, *newtuple = NULL; dns_rdata_soa_t oldsoa, newsoa; REQUIRE(DNS_ZONE_VALID(seczone)); REQUIRE(soatuple != NULL && *soatuple == NULL); if (!seczone->sourceserialset) return (DNS_R_UNCHANGED); dns_db_attach(raw->db, &rawdb); dns_db_currentversion(rawdb, &rawver); result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL); dns_db_closeversion(rawdb, &rawver, ISC_FALSE); dns_db_detach(&rawdb); if (result != ISC_R_SUCCESS) return (result); for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; tuple = next) { next = ISC_LIST_NEXT(tuple, link); if (tuple->rdata.type == dns_rdatatype_nsec || tuple->rdata.type == dns_rdatatype_rrsig || tuple->rdata.type == dns_rdatatype_dnskey || tuple->rdata.type == dns_rdatatype_nsec3 || tuple->rdata.type == dns_rdatatype_nsec3param) { ISC_LIST_UNLINK(diff->tuples, tuple, link); dns_difftuple_free(&tuple); continue; } if (tuple->rdata.type == dns_rdatatype_soa) { if (tuple->op == DNS_DIFFOP_DEL) { INSIST(oldtuple == NULL); oldtuple = tuple; } if (tuple->op == DNS_DIFFOP_ADD) { INSIST(newtuple == NULL); newtuple = tuple; } } } if (oldtuple != NULL && newtuple != NULL) { result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); /* * If the SOA records are the same except for the serial * remove them from the diff. */ if (oldsoa.refresh == newsoa.refresh && oldsoa.retry == newsoa.retry && oldsoa.minimum == newsoa.minimum && oldsoa.expire == newsoa.expire && dns_name_equal(&oldsoa.origin, &newsoa.origin) && dns_name_equal(&oldsoa.contact, &newsoa.contact)) { ISC_LIST_UNLINK(diff->tuples, oldtuple, link); dns_difftuple_free(&oldtuple); ISC_LIST_UNLINK(diff->tuples, newtuple, link); dns_difftuple_free(&newtuple); } } if (ISC_LIST_EMPTY(diff->tuples)) return (DNS_R_UNCHANGED); /* * If there are still SOA records in the diff they can now be removed * saving the new SOA record. */ if (oldtuple != NULL) { ISC_LIST_UNLINK(diff->tuples, oldtuple, link); dns_difftuple_free(&oldtuple); } if (newtuple != NULL) { ISC_LIST_UNLINK(diff->tuples, newtuple, link); *soatuple = newtuple; } return (ISC_R_SUCCESS); } static void receive_secure_serial(isc_task_t *task, isc_event_t *event) { static char me[] = "receive_secure_serial"; isc_result_t result = ISC_R_SUCCESS; dns_journal_t *rjournal = NULL; dns_journal_t *sjournal = NULL; isc_uint32_t start, end; dns_zone_t *zone; dns_difftuple_t *tuple = NULL, *soatuple = NULL; dns_update_log_t log = { update_log_cb, NULL }; isc_time_t timenow; UNUSED(task); zone = event->ev_arg; end = ((struct secure_event *)event)->serial; ENTER; LOCK_ZONE(zone); /* * If we are already processing a receive secure serial event * for the zone, just queue the new one and exit. */ if (zone->rss_event != NULL && zone->rss_event != event) { ISC_LIST_APPEND(zone->rss_events, event, ev_link); UNLOCK_ZONE(zone); return; } nextevent: if (zone->rss_event != NULL) { INSIST(zone->rss_event == event); UNLOCK_ZONE(zone); } else { zone->rss_event = event; dns_diff_init(zone->mctx, &zone->rss_diff); /* * zone->db may be NULL, if the load from disk failed. */ result = ISC_R_SUCCESS; ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) dns_db_attach(zone->db, &zone->rss_db); else result = ISC_R_FAILURE; ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); if (result == ISC_R_SUCCESS && zone->raw != NULL) dns_zone_attach(zone->raw, &zone->rss_raw); else result = ISC_R_FAILURE; UNLOCK_ZONE(zone); CHECK(result); /* * We first attempt to sync the raw zone to the secure zone * by using the raw zone's journal, applying all the deltas * from the latest source-serial of the secure zone up to * the current serial number of the raw zone. * * If that fails, then we'll fall back to a direct comparison * between raw and secure zones. */ CHECK(dns_journal_open(zone->rss_raw->mctx, zone->rss_raw->journal, DNS_JOURNAL_WRITE, &rjournal)); result = dns_journal_open(zone->mctx, zone->journal, DNS_JOURNAL_READ, &sjournal); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) goto failure; if (!dns_journal_get_sourceserial(rjournal, &start)) { start = dns_journal_first_serial(rjournal); dns_journal_set_sourceserial(rjournal, start); } if (sjournal != NULL) { isc_uint32_t serial; /* * We read the secure journal first, if that * exists use its value provided it is greater * that from the raw journal. */ if (dns_journal_get_sourceserial(sjournal, &serial)) { if (isc_serial_gt(serial, start)) start = serial; } dns_journal_destroy(&sjournal); } dns_db_currentversion(zone->rss_db, &zone->rss_oldver); CHECK(dns_db_newversion(zone->rss_db, &zone->rss_newver)); /* * Try to apply diffs from the raw zone's journal to the secure * zone. If that fails, we recover by syncing up the databases * directly. */ result = sync_secure_journal(zone, zone->rss_raw, rjournal, start, end, &soatuple, &zone->rss_diff); if (result == DNS_R_UNCHANGED) goto failure; else if (result != ISC_R_SUCCESS) CHECK(sync_secure_db(zone, zone->rss_raw, zone->rss_db, zone->rss_oldver, &soatuple, &zone->rss_diff)); CHECK(dns_diff_apply(&zone->rss_diff, zone->rss_db, zone->rss_newver)); if (soatuple != NULL) { isc_uint32_t oldserial, newserial, desired; CHECK(dns_db_createsoatuple(zone->rss_db, zone->rss_oldver, zone->rss_diff.mctx, DNS_DIFFOP_DEL, &tuple)); oldserial = dns_soa_getserial(&tuple->rdata); newserial = desired = dns_soa_getserial(&soatuple->rdata); if (!isc_serial_gt(newserial, oldserial)) { newserial = oldserial + 1; if (newserial == 0) newserial++; dns_soa_setserial(newserial, &soatuple->rdata); } CHECK(do_one_tuple(&tuple, zone->rss_db, zone->rss_newver, &zone->rss_diff)); CHECK(do_one_tuple(&soatuple, zone->rss_db, zone->rss_newver, &zone->rss_diff)); dns_zone_log(zone, ISC_LOG_INFO, "serial %u (unsigned %u)", newserial, desired); } else CHECK(update_soa_serial(zone->rss_db, zone->rss_newver, &zone->rss_diff, zone->mctx, zone->updatemethod)); } result = dns_update_signaturesinc(&log, zone, zone->rss_db, zone->rss_oldver, zone->rss_newver, &zone->rss_diff, zone->sigvalidityinterval, &zone->rss_state); if (result == DNS_R_CONTINUE) { if (rjournal != NULL) dns_journal_destroy(&rjournal); isc_task_send(task, &event); fprintf(stderr, "looping on dns_update_signaturesinc\n"); return; } if (result != ISC_R_SUCCESS) goto failure; if (rjournal == NULL) CHECK(dns_journal_open(zone->rss_raw->mctx, zone->rss_raw->journal, DNS_JOURNAL_WRITE, &rjournal)); CHECK(zone_journal(zone, &zone->rss_diff, &end, "receive_secure_serial")); dns_journal_set_sourceserial(rjournal, end); dns_journal_commit(rjournal); LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); zone->sourceserial = end; zone->sourceserialset = ISC_TRUE; zone_needdump(zone, DNS_DUMP_DELAY); TIME_NOW(&timenow); zone_settimer(zone, &timenow); UNLOCK_ZONE(zone); dns_db_closeversion(zone->rss_db, &zone->rss_oldver, ISC_FALSE); dns_db_closeversion(zone->rss_db, &zone->rss_newver, ISC_TRUE); failure: isc_event_free(&zone->rss_event); event = ISC_LIST_HEAD(zone->rss_events); if (zone->rss_raw != NULL) dns_zone_detach(&zone->rss_raw); if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_serial: %s", dns_result_totext(result)); if (tuple != NULL) dns_difftuple_free(&tuple); if (soatuple != NULL) dns_difftuple_free(&soatuple); if (zone->rss_db != NULL) { if (zone->rss_oldver != NULL) dns_db_closeversion(zone->rss_db, &zone->rss_oldver, ISC_FALSE); if (zone->rss_newver != NULL) dns_db_closeversion(zone->rss_db, &zone->rss_newver, ISC_FALSE); dns_db_detach(&zone->rss_db); } INSIST(zone->rss_oldver == NULL); INSIST(zone->rss_newver == NULL); if (rjournal != NULL) dns_journal_destroy(&rjournal); dns_diff_clear(&zone->rss_diff); if (event != NULL) { LOCK_ZONE(zone); INSIST(zone->irefs > 1); zone->irefs--; goto nextevent; } dns_zone_idetach(&zone); } static isc_result_t zone_send_secureserial(dns_zone_t *zone, isc_uint32_t serial) { isc_event_t *e; dns_zone_t *dummy = NULL; e = isc_event_allocate(zone->secure->mctx, zone, DNS_EVENT_ZONESECURESERIAL, receive_secure_serial, zone->secure, sizeof(struct secure_event)); if (e == NULL) return (ISC_R_NOMEMORY); ((struct secure_event *)e)->serial = serial; INSIST(LOCKED_ZONE(zone->secure)); zone_iattach(zone->secure, &dummy); isc_task_send(zone->secure->task, &e); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE); return (ISC_R_SUCCESS); } static isc_result_t checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdataset_t *rdataset, isc_uint32_t oldserial) { dns_rdata_soa_t soa; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdatalist_t temprdatalist; dns_rdataset_t temprdataset; isc_buffer_t b; isc_result_t result; unsigned char buf[DNS_SOA_BUFFERSIZE]; result = dns_rdataset_first(rdataset); RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &soa, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (isc_serial_gt(soa.serial, oldserial)) return (dns_db_addrdataset(db, node, version, 0, rdataset, 0, NULL)); /* * Always bump the serial. */ oldserial++; if (oldserial == 0) oldserial++; soa.serial = oldserial; /* * Construct a replacement rdataset. */ dns_rdata_reset(&rdata); isc_buffer_init(&b, buf, sizeof(buf)); result = dns_rdata_fromstruct(&rdata, rdataset->rdclass, dns_rdatatype_soa, &soa, &b); RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_rdatalist_init(&temprdatalist); temprdatalist.rdclass = rdata.rdclass; temprdatalist.type = rdata.type; temprdatalist.ttl = rdataset->ttl; ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link); dns_rdataset_init(&temprdataset); result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset); RUNTIME_CHECK(result == ISC_R_SUCCESS); return (dns_db_addrdataset(db, node, version, 0, &temprdataset, 0, NULL)); } /* * This function should populate an nsec3paramlist_t with the * nsecparam_t data from a zone. */ static isc_result_t save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) { isc_result_t result; dns_dbnode_t *node = NULL; dns_rdataset_t rdataset, prdataset; dns_dbversion_t *version = NULL; nsec3param_t *nsec3param = NULL; nsec3param_t *nsec3p = NULL; nsec3param_t *next; dns_db_t *db = NULL; unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(nsec3list != NULL); REQUIRE(ISC_LIST_EMPTY(*nsec3list)); dns_rdataset_init(&rdataset); dns_rdataset_init(&prdataset); dns_db_attach(zone->db, &db); CHECK(dns_db_getoriginnode(db, &node)); dns_db_currentversion(db, &version); result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3param, dns_rdatatype_none, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) goto getprivate; /* * walk nsec3param rdataset making a list of parameters (note that * multiple simultaneous nsec3 chains are annoyingly legal -- this * is why we use an nsec3list, even tho we will usually only have * one) */ for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_t private = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), "looping through nsec3param data"); nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t)); if (nsec3param == NULL) CHECK(ISC_R_NOMEMORY); ISC_LINK_INIT(nsec3param, link); /* * now transfer the data from the rdata to * the nsec3param */ dns_nsec3param_toprivate(&rdata, &private, zone->privatetype, nsec3param->data, sizeof(nsec3param->data)); nsec3param->length = private.length; ISC_LIST_APPEND(*nsec3list, nsec3param, link); } getprivate: result = dns_db_findrdataset(db, node, version, zone->privatetype, dns_rdatatype_none, 0, &prdataset, NULL); if (result != ISC_R_SUCCESS) goto done; /* * walk private type records, converting them to nsec3 parameters * using dns_nsec3param_fromprivate(), do the right thing based on * CREATE and REMOVE flags */ for (result = dns_rdataset_first(&prdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&prdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_t private = DNS_RDATA_INIT; dns_rdataset_current(&prdataset, &private); isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), "looping through nsec3param private data"); /* * Do we have a valid private record? */ if (!dns_nsec3param_fromprivate(&private, &rdata, buf, sizeof(buf))) continue; /* * Remove any NSEC3PARAM records scheduled to be removed. */ if (NSEC3REMOVE(rdata.data[1])) { /* * Zero out the flags. */ rdata.data[1] = 0; for (nsec3p = ISC_LIST_HEAD(*nsec3list); nsec3p != NULL; nsec3p = next) { next = ISC_LIST_NEXT(nsec3p, link); if (nsec3p->length == rdata.length + 1 && memcmp(rdata.data, nsec3p->data + 1, nsec3p->length - 1) == 0) { ISC_LIST_UNLINK(*nsec3list, nsec3p, link); isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t)); } } continue; } nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t)); if (nsec3param == NULL) CHECK(ISC_R_NOMEMORY); ISC_LINK_INIT(nsec3param, link); /* * Copy the remaining private records so the nsec/nsec3 * chain gets created. */ INSIST(private.length <= sizeof(nsec3param->data)); memmove(nsec3param->data, private.data, private.length); nsec3param->length = private.length; ISC_LIST_APPEND(*nsec3list, nsec3param, link); } done: if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND) result = ISC_R_SUCCESS; failure: if (node != NULL) dns_db_detachnode(db, &node); if (version != NULL) dns_db_closeversion(db, &version, ISC_FALSE); if (db != NULL) dns_db_detach(&db); if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (dns_rdataset_isassociated(&prdataset)) dns_rdataset_disassociate(&prdataset); return (result); } /* * Walk the list of the nsec3 chains desired for the zone, converting * parameters to private type records using dns_nsec3param_toprivate(), * and insert them into the new zone db. */ static isc_result_t restore_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, nsec3paramlist_t *nsec3list) { isc_result_t result; dns_diff_t diff; dns_rdata_t rdata; nsec3param_t *nsec3p = NULL; nsec3param_t *next; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(!ISC_LIST_EMPTY(*nsec3list)); dns_diff_init(zone->mctx, &diff); /* * Loop through the list of private-type records, set the INITIAL * and CREATE flags, and the add the record to the apex of the tree * in db. */ for (nsec3p = ISC_LIST_HEAD(*nsec3list); nsec3p != NULL; nsec3p = next) { next = ISC_LIST_NEXT(nsec3p, link); dns_rdata_init(&rdata); nsec3p->data[2] = DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL; rdata.length = nsec3p->length; rdata.data = nsec3p->data; rdata.type = zone->privatetype; rdata.rdclass = zone->rdclass; CHECK(update_one_rr(db, version, &diff, DNS_DIFFOP_ADD, &zone->origin, 0, &rdata)); } result = ISC_R_SUCCESS; failure: for (nsec3p = ISC_LIST_HEAD(*nsec3list); nsec3p != NULL; nsec3p = next) { next = ISC_LIST_NEXT(nsec3p, link); ISC_LIST_UNLINK(*nsec3list, nsec3p, link); isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t)); } dns_diff_clear(&diff); return (result); } static void receive_secure_db(isc_task_t *task, isc_event_t *event) { isc_result_t result; dns_zone_t *zone; dns_db_t *rawdb, *db = NULL; dns_dbnode_t *rawnode = NULL, *node = NULL; dns_fixedname_t fname; dns_name_t *name; dns_dbiterator_t *dbiterator = NULL; dns_rdatasetiter_t *rdsit = NULL; dns_rdataset_t rdataset; dns_dbversion_t *version = NULL; isc_time_t loadtime; unsigned int oldserial = 0; isc_boolean_t have_oldserial = ISC_FALSE; nsec3paramlist_t nsec3list; UNUSED(task); ISC_LIST_INIT(nsec3list); zone = event->ev_arg; rawdb = ((struct secure_event *)event)->db; isc_event_free(&event); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_rdataset_init(&rdataset); LOCK_ZONE(zone); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) { result = ISC_R_SHUTTINGDOWN; goto failure; } TIME_NOW(&loadtime); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) { result = dns_db_getsoaserial(zone->db, NULL, &oldserial); if (result == ISC_R_SUCCESS) have_oldserial = ISC_TRUE; /* * assemble nsec3parameters from the old zone, and set a flag * if any are found */ result = save_nsec3param(zone, &nsec3list); if (result != ISC_R_SUCCESS) { ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); goto failure; } } ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin, dns_dbtype_zone, zone->rdclass, zone->db_argc - 1, zone->db_argv + 1, &db); if (result != ISC_R_SUCCESS) goto failure; result = dns_db_newversion(db, &version); if (result != ISC_R_SUCCESS) goto failure; result = dns_db_createiterator(rawdb, 0, &dbiterator); if (result != ISC_R_SUCCESS) goto failure; for (result = dns_dbiterator_first(dbiterator); result == ISC_R_SUCCESS; result = dns_dbiterator_next(dbiterator)) { result = dns_dbiterator_current(dbiterator, &rawnode, name); if (result != ISC_R_SUCCESS) continue; result = dns_db_findnode(db, name, ISC_TRUE, &node); if (result != ISC_R_SUCCESS) goto failure; result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, &rdsit); if (result != ISC_R_SUCCESS) goto failure; for (result = dns_rdatasetiter_first(rdsit); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsit)) { dns_rdatasetiter_current(rdsit, &rdataset); if (rdataset.type == dns_rdatatype_nsec || rdataset.type == dns_rdatatype_rrsig || rdataset.type == dns_rdatatype_nsec3 || rdataset.type == dns_rdatatype_dnskey || rdataset.type == dns_rdatatype_nsec3param) { dns_rdataset_disassociate(&rdataset); continue; } if (rdataset.type == dns_rdatatype_soa && have_oldserial) { result = checkandaddsoa(db, node, version, &rdataset, oldserial); } else result = dns_db_addrdataset(db, node, version, 0, &rdataset, 0, NULL); if (result != ISC_R_SUCCESS) goto failure; dns_rdataset_disassociate(&rdataset); } dns_rdatasetiter_destroy(&rdsit); dns_db_detachnode(rawdb, &rawnode); dns_db_detachnode(db, &node); } /* * Call restore_nsec3param() to create private-type records from * the old nsec3 parameters and insert them into db */ if (!ISC_LIST_EMPTY(nsec3list)) restore_nsec3param(zone, db, version, &nsec3list); dns_db_closeversion(db, &version, ISC_TRUE); /* * Lock hierarchy: zmgr, zone, raw. */ INSIST(zone != zone->raw); LOCK_ZONE(zone->raw); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS); zone_needdump(zone, 0); /* XXXMPA */ UNLOCK_ZONE(zone->raw); failure: UNLOCK_ZONE(zone); if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s", dns_result_totext(result)); while (!ISC_LIST_EMPTY(nsec3list)) { nsec3param_t *nsec3p; nsec3p = ISC_LIST_HEAD(nsec3list); ISC_LIST_UNLINK(nsec3list, nsec3p, link); isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t)); } if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (db != NULL) { if (node != NULL) dns_db_detachnode(db, &node); if (version != NULL) dns_db_closeversion(db, &version, ISC_FALSE); dns_db_detach(&db); } if (rawnode != NULL) dns_db_detachnode(rawdb, &rawnode); dns_db_detach(&rawdb); if (dbiterator != NULL) dns_dbiterator_destroy(&dbiterator); dns_zone_idetach(&zone); INSIST(version == NULL); } static isc_result_t zone_send_securedb(dns_zone_t *zone, dns_db_t *db) { isc_event_t *e; dns_db_t *dummy = NULL; dns_zone_t *secure = NULL; e = isc_event_allocate(zone->secure->mctx, zone, DNS_EVENT_ZONESECUREDB, receive_secure_db, zone->secure, sizeof(struct secure_event)); if (e == NULL) return (ISC_R_NOMEMORY); dns_db_attach(db, &dummy); ((struct secure_event *)e)->db = dummy; INSIST(LOCKED_ZONE(zone->secure)); zone_iattach(zone->secure, &secure); isc_task_send(zone->secure->task, &e); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE); return (ISC_R_SUCCESS); } isc_result_t dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { isc_result_t result; dns_zone_t *secure = NULL; REQUIRE(DNS_ZONE_VALID(zone)); again: LOCK_ZONE(zone); if (inline_raw(zone)) { secure = zone->secure; INSIST(secure != zone); TRYLOCK_ZONE(result, secure); if (result != ISC_R_SUCCESS) { UNLOCK_ZONE(zone); secure = NULL; #if ISC_PLATFORM_USETHREADS isc_thread_yield(); #endif goto again; } } ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); result = zone_replacedb(zone, db, dump); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); if (secure != NULL) UNLOCK_ZONE(secure); UNLOCK_ZONE(zone); return (result); } static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { dns_dbversion_t *ver; isc_result_t result; unsigned int soacount = 0; unsigned int nscount = 0; /* * 'zone' and 'zonedb' locked by caller. */ REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(LOCKED_ZONE(zone)); if (inline_raw(zone)) REQUIRE(LOCKED_ZONE(zone->secure)); result = dns_db_rpz_ready(db); if (result != ISC_R_SUCCESS) return (result); result = zone_get_from_db(zone, db, &nscount, &soacount, NULL, NULL, NULL, NULL, NULL, NULL); if (result == ISC_R_SUCCESS) { if (soacount != 1) { dns_zone_log(zone, ISC_LOG_ERROR, "has %d SOA records", soacount); result = DNS_R_BADZONE; } if (nscount == 0 && zone->type != dns_zone_key) { dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records"); result = DNS_R_BADZONE; } if (result != ISC_R_SUCCESS) return (result); } else { dns_zone_log(zone, ISC_LOG_ERROR, "retrieving SOA and NS records failed: %s", dns_result_totext(result)); return (result); } result = check_nsec3param(zone, db); if (result != ISC_R_SUCCESS) return (result); ver = NULL; dns_db_currentversion(db, &ver); /* * The initial version of a slave zone is always dumped; * subsequent versions may be journaled instead if this * is enabled in the configuration. */ if (zone->db != NULL && zone->journal != NULL && DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) { isc_uint32_t serial, oldserial; dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs"); result = dns_db_getsoaserial(db, ver, &serial); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "ixfr-from-differences: unable to get " "new serial"); goto fail; } /* * This is checked in zone_postload() for master zones. */ result = zone_get_from_db(zone, zone->db, NULL, &soacount, &oldserial, NULL, NULL, NULL, NULL, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); RUNTIME_CHECK(soacount > 0U); if ((zone->type == dns_zone_slave || (zone->type == dns_zone_redirect && zone->masters != NULL)) && !isc_serial_gt(serial, oldserial)) { isc_uint32_t serialmin, serialmax; serialmin = (oldserial + 1) & 0xffffffffU; serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU; dns_zone_log(zone, ISC_LOG_ERROR, "ixfr-from-differences: failed: " "new serial (%u) out of range [%u - %u]", serial, serialmin, serialmax); result = ISC_R_RANGE; goto fail; } result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL, zone->journal); if (result != ISC_R_SUCCESS) goto fail; if (dump) zone_needdump(zone, DNS_DUMP_DELAY); else if (zone->journalsize != -1) { result = dns_journal_compact(zone->mctx, zone->journal, serial, zone->journalsize); switch (result) { case ISC_R_SUCCESS: case ISC_R_NOSPACE: case ISC_R_NOTFOUND: dns_zone_log(zone, ISC_LOG_DEBUG(3), "dns_journal_compact: %s", dns_result_totext(result)); break; default: dns_zone_log(zone, ISC_LOG_ERROR, "dns_journal_compact failed: %s", dns_result_totext(result)); break; } } if (zone->type == dns_zone_master && inline_raw(zone)) zone_send_secureserial(zone, serial); } else { if (dump && zone->masterfile != NULL) { /* * If DNS_ZONEFLG_FORCEXFER was set we don't want * to keep the old masterfile. */ if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) && remove(zone->masterfile) < 0 && errno != ENOENT) { char strbuf[ISC_STRERRORSIZE]; isc__strerror(errno, strbuf, sizeof(strbuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, ISC_LOG_WARNING, "unable to remove masterfile " "'%s': '%s'", zone->masterfile, strbuf); } if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY); else zone_needdump(zone, 0); } if (dump && zone->journal != NULL) { /* * The in-memory database just changed, and * because 'dump' is set, it didn't change by * being loaded from disk. Also, we have not * journaled diffs for this change. * Therefore, the on-disk journal is missing * the deltas for this change. Since it can * no longer be used to bring the zone * up-to-date, it is useless and should be * removed. */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), "removing journal file"); if (remove(zone->journal) < 0 && errno != ENOENT) { char strbuf[ISC_STRERRORSIZE]; isc__strerror(errno, strbuf, sizeof(strbuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, ISC_LOG_WARNING, "unable to remove journal " "'%s': '%s'", zone->journal, strbuf); } } if (inline_raw(zone)) zone_send_securedb(zone, db); } dns_db_closeversion(db, &ver, ISC_FALSE); dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database"); if (zone->db != NULL) zone_detachdb(zone); zone_attachdb(zone, db); dns_db_settask(zone->db, zone->task); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY); return (ISC_R_SUCCESS); fail: dns_db_closeversion(db, &ver, ISC_FALSE); return (result); } /* The caller must hold the dblock as a writer. */ static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db) { REQUIRE(zone->db == NULL && db != NULL); dns_db_attach(db, &zone->db); if (zone->acache != NULL) { isc_result_t result; result = dns_acache_setdb(zone->acache, db); if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "dns_acache_setdb() failed: %s", isc_result_totext(result)); } } } /* The caller must hold the dblock as a writer. */ static inline void zone_detachdb(dns_zone_t *zone) { REQUIRE(zone->db != NULL); if (zone->acache != NULL) (void)dns_acache_putdb(zone->acache, zone->db); dns_db_detach(&zone->db); } static void zone_xfrdone(dns_zone_t *zone, isc_result_t result) { isc_time_t now; isc_boolean_t again = ISC_FALSE; unsigned int soacount; unsigned int nscount; isc_uint32_t serial, refresh, retry, expire, minimum; isc_result_t xfrresult = result; isc_boolean_t free_needed; dns_zone_t *secure = NULL; REQUIRE(DNS_ZONE_VALID(zone)); dns_zone_log(zone, ISC_LOG_DEBUG(1), "zone transfer finished: %s", dns_result_totext(result)); /* * Obtaining a lock on the zone->secure (see zone_send_secureserial) * could result in a deadlock due to a LOR so we will spin if we * can't obtain the both locks. */ again: LOCK_ZONE(zone); if (inline_raw(zone)) { secure = zone->secure; INSIST(secure != zone); TRYLOCK_ZONE(result, secure); if (result != ISC_R_SUCCESS) { UNLOCK_ZONE(zone); secure = NULL; #if ISC_PLATFORM_USETHREADS isc_thread_yield(); #endif goto again; } } INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); TIME_NOW(&now); switch (result) { case ISC_R_SUCCESS: DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); /*FALLTHROUGH*/ case DNS_R_UPTODATE: DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER); /* * Has the zone expired underneath us? */ ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db == NULL) { ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); goto same_master; } /* * Update the zone structure's data from the actual * SOA received. */ nscount = 0; soacount = 0; INSIST(zone->db != NULL); result = zone_get_from_db(zone, zone->db, &nscount, &soacount, &serial, &refresh, &retry, &expire, &minimum, NULL); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); if (result == ISC_R_SUCCESS) { if (soacount != 1) dns_zone_log(zone, ISC_LOG_ERROR, "transferred zone " "has %d SOA record%s", soacount, (soacount != 0) ? "s" : ""); if (nscount == 0) { dns_zone_log(zone, ISC_LOG_ERROR, "transferred zone " "has no NS records"); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) { zone->refresh = DNS_ZONE_DEFAULTREFRESH; zone->retry = DNS_ZONE_DEFAULTRETRY; } DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); zone_unload(zone); goto next_master; } zone->refresh = RANGE(refresh, zone->minrefresh, zone->maxrefresh); zone->retry = RANGE(retry, zone->minretry, zone->maxretry); zone->expire = RANGE(expire, zone->refresh + zone->retry, DNS_MAX_EXPIRE); zone->minimum = minimum; DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); } /* * Set our next update/expire times. */ if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) { DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); zone->refreshtime = now; DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime); } else { DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime); } if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) { char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")]; if (zone->tsigkey != NULL) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(&zone->tsigkey->name, namebuf, sizeof(namebuf)); snprintf(buf, sizeof(buf), ": TSIG '%s'", namebuf); } else buf[0] = '\0'; dns_zone_log(zone, ISC_LOG_INFO, "transferred serial %u%s", serial, buf); if (inline_raw(zone)) zone_send_secureserial(zone, serial); } /* * This is not necessary if we just performed a AXFR * however it is necessary for an IXFR / UPTODATE and * won't hurt with an AXFR. */ if (zone->masterfile != NULL || zone->journal != NULL) { unsigned int delay = DNS_DUMP_DELAY; result = ISC_R_FAILURE; if (zone->journal != NULL) result = isc_file_settime(zone->journal, &now); if (result != ISC_R_SUCCESS && zone->masterfile != NULL) result = isc_file_settime(zone->masterfile, &now); if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) || result == ISC_R_FILENOTFOUND) delay = 0; if ((result == ISC_R_SUCCESS || result == ISC_R_FILENOTFOUND) && zone->masterfile != NULL) zone_needdump(zone, delay); else if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_ERROR, "transfer: could not set file " "modification time of '%s': %s", zone->masterfile, dns_result_totext(result)); } DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY); inc_stats(zone, dns_zonestatscounter_xfrsuccess); break; case DNS_R_BADIXFR: /* Force retry with AXFR. */ DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR); goto same_master; default: next_master: /* * Skip to next failed / untried master. */ do { zone->curmaster++; } while (zone->curmaster < zone->masterscnt && zone->mastersok[zone->curmaster]); /* FALLTHROUGH */ same_master: if (zone->curmaster >= zone->masterscnt) { zone->curmaster = 0; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); while (zone->curmaster < zone->masterscnt && zone->mastersok[zone->curmaster]) zone->curmaster++; again = ISC_TRUE; } else DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); } else { DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); again = ISC_TRUE; } inc_stats(zone, dns_zonestatscounter_xfrfail); break; } zone_settimer(zone, &now); /* * If creating the transfer object failed, zone->xfr is NULL. * Otherwise, we are called as the done callback of a zone * transfer object that just entered its shutting-down * state. Since we are no longer responsible for shutting * it down, we can detach our reference. */ if (zone->xfr != NULL) dns_xfrin_detach(&zone->xfr); if (zone->tsigkey != NULL) dns_tsigkey_detach(&zone->tsigkey); /* * Handle any deferred journal compaction. */ if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) { result = dns_journal_compact(zone->mctx, zone->journal, zone->compact_serial, zone->journalsize); switch (result) { case ISC_R_SUCCESS: case ISC_R_NOSPACE: case ISC_R_NOTFOUND: dns_zone_log(zone, ISC_LOG_DEBUG(3), "dns_journal_compact: %s", dns_result_totext(result)); break; default: dns_zone_log(zone, ISC_LOG_ERROR, "dns_journal_compact failed: %s", dns_result_totext(result)); break; } DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); } if (secure != NULL) UNLOCK_ZONE(secure); /* * This transfer finishing freed up a transfer quota slot. * Let any other zones waiting for quota have it. */ if (zone->zmgr != NULL && zone->statelist == &zone->zmgr->xfrin_in_progress) { UNLOCK_ZONE(zone); RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink); zone->statelist = NULL; zmgr_resume_xfrs(zone->zmgr, ISC_FALSE); RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); LOCK_ZONE(zone); } /* * Retry with a different server if necessary. */ if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) queue_soa_query(zone); INSIST(zone->irefs > 0); zone->irefs--; free_needed = exit_check(zone); UNLOCK_ZONE(zone); if (free_needed) zone_free(zone); } static void zone_loaddone(void *arg, isc_result_t result) { static char me[] = "zone_loaddone"; dns_load_t *load = arg; dns_zone_t *zone; isc_result_t tresult; dns_zone_t *secure = NULL; REQUIRE(DNS_LOAD_VALID(load)); zone = load->zone; ENTER; tresult = dns_db_endload(load->db, &load->callbacks); if (tresult != ISC_R_SUCCESS && (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE)) result = tresult; /* * Lock hierarchy: zmgr, zone, raw. */ again: LOCK_ZONE(zone); INSIST(zone != zone->raw); if (inline_secure(zone)) LOCK_ZONE(zone->raw); else if (inline_raw(zone)) { secure = zone->secure; TRYLOCK_ZONE(result, secure); if (result != ISC_R_SUCCESS) { UNLOCK_ZONE(zone); secure = NULL; #if ISC_PLATFORM_USETHREADS isc_thread_yield(); #endif goto again; } } (void)zone_postload(zone, load->db, load->loadtime, result); zonemgr_putio(&zone->readio); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING); zone_idetach(&load->callbacks.zone); /* * Leave the zone frozen if the reload fails. */ if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW)) zone->update_disabled = ISC_FALSE; DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW); if (inline_secure(zone)) UNLOCK_ZONE(zone->raw); else if (secure != NULL) UNLOCK_ZONE(secure); UNLOCK_ZONE(zone); load->magic = 0; dns_db_detach(&load->db); if (load->zone->lctx != NULL) dns_loadctx_detach(&load->zone->lctx); dns_zone_idetach(&load->zone); isc_mem_putanddetach(&load->mctx, load, sizeof(*load)); } void dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(table != NULL); REQUIRE(*table == NULL); LOCK_ZONE(zone); if (zone->ssutable != NULL) dns_ssutable_attach(zone->ssutable, table); UNLOCK_ZONE(zone); } void dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (zone->ssutable != NULL) dns_ssutable_detach(&zone->ssutable); if (table != NULL) dns_ssutable_attach(table, &zone->ssutable); UNLOCK_ZONE(zone); } void dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) { REQUIRE(DNS_ZONE_VALID(zone)); zone->sigvalidityinterval = interval; } isc_uint32_t dns_zone_getsigvalidityinterval(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->sigvalidityinterval); } void dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) { isc_time_t now; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->sigresigninginterval = interval; set_resigntime(zone); if (zone->task != NULL) { TIME_NOW(&now); zone_settimer(zone, &now); } UNLOCK_ZONE(zone); } isc_uint32_t dns_zone_getsigresigninginterval(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->sigresigninginterval); } static void queue_xfrin(dns_zone_t *zone) { const char me[] = "queue_xfrin"; isc_result_t result; dns_zonemgr_t *zmgr = zone->zmgr; ENTER; INSIST(zone->statelist == NULL); RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink); LOCK_ZONE(zone); zone->irefs++; UNLOCK_ZONE(zone); zone->statelist = &zmgr->waiting_for_xfrin; result = zmgr_start_xfrin_ifquota(zmgr, zone); RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); if (result == ISC_R_QUOTA) { dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, "zone transfer deferred due to quota"); } else if (result != ISC_R_SUCCESS) { dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR, "starting zone transfer: %s", isc_result_totext(result)); } } /* * This event callback is called when a zone has received * any necessary zone transfer quota. This is the time * to go ahead and start the transfer. */ static void got_transfer_quota(isc_task_t *task, isc_event_t *event) { isc_result_t result = ISC_R_SUCCESS; dns_peer_t *peer = NULL; char master[ISC_SOCKADDR_FORMATSIZE]; char source[ISC_SOCKADDR_FORMATSIZE]; dns_rdatatype_t xfrtype; dns_zone_t *zone = event->ev_arg; isc_netaddr_t masterip; isc_sockaddr_t sourceaddr; isc_sockaddr_t masteraddr; isc_time_t now; const char *soa_before = ""; isc_dscp_t dscp = -1; isc_boolean_t loaded; UNUSED(task); INSIST(task == zone->task); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { result = ISC_R_CANCELED; goto cleanup; } TIME_NOW(&now); isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr, &zone->sourceaddr, &now)) { isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); dns_zone_log(zone, ISC_LOG_INFO, "got_transfer_quota: skipping zone transfer as " "master %s (source %s) is unreachable (cached)", master, source); result = ISC_R_CANCELED; goto cleanup; } isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) soa_before = "SOA before "; /* * Decide whether we should request IXFR or AXFR. */ ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); loaded = ISC_TF(zone->db != NULL); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); if (!loaded) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "no database exists yet, requesting AXFR of " "initial version from %s", master); xfrtype = dns_rdatatype_axfr; } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "forced reload, requesting AXFR of " "initial version from %s", master); xfrtype = dns_rdatatype_axfr; } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "retrying with AXFR from %s due to " "previous IXFR failure", master); xfrtype = dns_rdatatype_axfr; LOCK_ZONE(zone); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR); UNLOCK_ZONE(zone); } else { isc_boolean_t use_ixfr = ISC_TRUE; if (peer != NULL) result = dns_peer_getrequestixfr(peer, &use_ixfr); if (peer == NULL || result != ISC_R_SUCCESS) use_ixfr = zone->requestixfr; if (use_ixfr == ISC_FALSE) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "IXFR disabled, requesting %sAXFR from %s", soa_before, master); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) xfrtype = dns_rdatatype_soa; else xfrtype = dns_rdatatype_axfr; } else { dns_zone_log(zone, ISC_LOG_DEBUG(1), "requesting IXFR from %s", master); xfrtype = dns_rdatatype_ixfr; } } /* * Determine if we should attempt to sign the request with TSIG. */ result = ISC_R_NOTFOUND; /* * First, look for a tsig key in the master statement, then * try for a server key. */ if ((zone->masterkeynames != NULL) && (zone->masterkeynames[zone->curmaster] != NULL)) { dns_view_t *view = dns_zone_getview(zone); dns_name_t *keyname = zone->masterkeynames[zone->curmaster]; result = dns_view_gettsig(view, keyname, &zone->tsigkey); } if (zone->tsigkey == NULL) result = dns_view_getpeertsig(zone->view, &masterip, &zone->tsigkey); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { dns_zone_log(zone, ISC_LOG_ERROR, "could not get TSIG key for zone transfer: %s", isc_result_totext(result)); } if (zone->masterdscps != NULL) dscp = zone->masterdscps[zone->curmaster]; LOCK_ZONE(zone); masteraddr = zone->masteraddr; sourceaddr = zone->sourceaddr; switch (isc_sockaddr_pf(&masteraddr)) { case PF_INET: if (dscp == -1) dscp = zone->xfrsource4dscp; break; case PF_INET6: if (dscp == -1) dscp = zone->xfrsource6dscp; break; default: INSIST(0); }; UNLOCK_ZONE(zone); INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr)); result = dns_xfrin_create3(zone, xfrtype, &masteraddr, &sourceaddr, dscp, zone->tsigkey, zone->mctx, zone->zmgr->timermgr, zone->zmgr->socketmgr, zone->task, zone_xfrdone, &zone->xfr); if (result == ISC_R_SUCCESS) { LOCK_ZONE(zone); if (xfrtype == dns_rdatatype_axfr) { if (isc_sockaddr_pf(&masteraddr) == PF_INET) inc_stats(zone, dns_zonestatscounter_axfrreqv4); else inc_stats(zone, dns_zonestatscounter_axfrreqv6); } else if (xfrtype == dns_rdatatype_ixfr) { if (isc_sockaddr_pf(&masteraddr) == PF_INET) inc_stats(zone, dns_zonestatscounter_ixfrreqv4); else inc_stats(zone, dns_zonestatscounter_ixfrreqv6); } UNLOCK_ZONE(zone); } cleanup: /* * Any failure in this function is handled like a failed * zone transfer. This ensures that we get removed from * zmgr->xfrin_in_progress. */ if (result != ISC_R_SUCCESS) zone_xfrdone(zone, result); isc_event_free(&event); } /* * Update forwarding support. */ static void forward_destroy(dns_forward_t *forward) { forward->magic = 0; if (forward->request != NULL) dns_request_destroy(&forward->request); if (forward->msgbuf != NULL) isc_buffer_free(&forward->msgbuf); if (forward->zone != NULL) { LOCK(&forward->zone->lock); if (ISC_LINK_LINKED(forward, link)) ISC_LIST_UNLINK(forward->zone->forwards, forward, link); UNLOCK(&forward->zone->lock); dns_zone_idetach(&forward->zone); } isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward)); } static isc_result_t sendtomaster(dns_forward_t *forward) { isc_result_t result; isc_sockaddr_t src; isc_dscp_t dscp = -1; LOCK_ZONE(forward->zone); if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) { UNLOCK_ZONE(forward->zone); return (ISC_R_CANCELED); } if (forward->which >= forward->zone->masterscnt) { UNLOCK_ZONE(forward->zone); return (ISC_R_NOMORE); } forward->addr = forward->zone->masters[forward->which]; /* * Always use TCP regardless of whether the original update * used TCP. * XXX The timeout may but a bit small if we are far down a * transfer graph and the master has to try several masters. */ switch (isc_sockaddr_pf(&forward->addr)) { case PF_INET: src = forward->zone->xfrsource4; dscp = forward->zone->xfrsource4dscp; break; case PF_INET6: src = forward->zone->xfrsource6; dscp = forward->zone->xfrsource6dscp; break; default: result = ISC_R_NOTIMPLEMENTED; goto unlock; } result = dns_request_createraw4(forward->zone->view->requestmgr, forward->msgbuf, &src, &forward->addr, dscp, forward->options, 15 /* XXX */, 0, 0, forward->zone->task, forward_callback, forward, &forward->request); if (result == ISC_R_SUCCESS) { if (!ISC_LINK_LINKED(forward, link)) ISC_LIST_APPEND(forward->zone->forwards, forward, link); } unlock: UNLOCK_ZONE(forward->zone); return (result); } static void forward_callback(isc_task_t *task, isc_event_t *event) { const char me[] = "forward_callback"; dns_requestevent_t *revent = (dns_requestevent_t *)event; dns_message_t *msg = NULL; char master[ISC_SOCKADDR_FORMATSIZE]; isc_result_t result; dns_forward_t *forward; dns_zone_t *zone; UNUSED(task); forward = revent->ev_arg; INSIST(DNS_FORWARD_VALID(forward)); zone = forward->zone; INSIST(DNS_ZONE_VALID(zone)); ENTER; isc_sockaddr_format(&forward->addr, master, sizeof(master)); if (revent->result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_INFO, "could not forward dynamic update to %s: %s", master, dns_result_totext(revent->result)); goto next_master; } result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); if (result != ISC_R_SUCCESS) goto next_master; result = dns_request_getresponse(revent->request, msg, DNS_MESSAGEPARSE_PRESERVEORDER | DNS_MESSAGEPARSE_CLONEBUFFER); if (result != ISC_R_SUCCESS) goto next_master; switch (msg->rcode) { /* * Pass these rcodes back to client. */ case dns_rcode_noerror: case dns_rcode_yxdomain: case dns_rcode_yxrrset: case dns_rcode_nxrrset: case dns_rcode_refused: case dns_rcode_nxdomain: { char rcode[128]; isc_buffer_t rb; isc_buffer_init(&rb, rcode, sizeof(rcode)); (void)dns_rcode_totext(msg->rcode, &rb); dns_zone_log(zone, ISC_LOG_INFO, "forwarded dynamic update: " "master %s returned: %.*s", master, (int)rb.used, rcode); break; } /* These should not occur if the masters/zone are valid. */ case dns_rcode_notzone: case dns_rcode_notauth: { char rcode[128]; isc_buffer_t rb; isc_buffer_init(&rb, rcode, sizeof(rcode)); (void)dns_rcode_totext(msg->rcode, &rb); dns_zone_log(zone, ISC_LOG_WARNING, "forwarding dynamic update: " "unexpected response: master %s returned: %.*s", master, (int)rb.used, rcode); goto next_master; } /* Try another server for these rcodes. */ case dns_rcode_formerr: case dns_rcode_servfail: case dns_rcode_notimp: case dns_rcode_badvers: default: goto next_master; } /* call callback */ (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg); msg = NULL; dns_request_destroy(&forward->request); forward_destroy(forward); isc_event_free(&event); return; next_master: if (msg != NULL) dns_message_destroy(&msg); isc_event_free(&event); forward->which++; dns_request_destroy(&forward->request); result = sendtomaster(forward); if (result != ISC_R_SUCCESS) { /* call callback */ dns_zone_log(zone, ISC_LOG_DEBUG(3), "exhausted dynamic update forwarder list"); (forward->callback)(forward->callback_arg, result, NULL); forward_destroy(forward); } } isc_result_t dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg, dns_updatecallback_t callback, void *callback_arg) { dns_forward_t *forward; isc_result_t result; isc_region_t *mr; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(msg != NULL); REQUIRE(callback != NULL); forward = isc_mem_get(zone->mctx, sizeof(*forward)); if (forward == NULL) return (ISC_R_NOMEMORY); forward->request = NULL; forward->zone = NULL; forward->msgbuf = NULL; forward->which = 0; forward->mctx = 0; forward->callback = callback; forward->callback_arg = callback_arg; ISC_LINK_INIT(forward, link); forward->magic = FORWARD_MAGIC; forward->options = DNS_REQUESTOPT_TCP; /* * If we have a SIG(0) signed message we need to preserve the * query id as that is included in the SIG(0) computation. */ if (msg->sig0 != NULL) forward->options |= DNS_REQUESTOPT_FIXEDID; mr = dns_message_getrawmessage(msg); if (mr == NULL) { result = ISC_R_UNEXPECTEDEND; goto cleanup; } result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length); if (result != ISC_R_SUCCESS) goto cleanup; result = isc_buffer_copyregion(forward->msgbuf, mr); if (result != ISC_R_SUCCESS) goto cleanup; isc_mem_attach(zone->mctx, &forward->mctx); dns_zone_iattach(zone, &forward->zone); result = sendtomaster(forward); cleanup: if (result != ISC_R_SUCCESS) { forward_destroy(forward); } return (result); } isc_result_t dns_zone_next(dns_zone_t *zone, dns_zone_t **next) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(next != NULL && *next == NULL); *next = ISC_LIST_NEXT(zone, link); if (*next == NULL) return (ISC_R_NOMORE); else return (ISC_R_SUCCESS); } isc_result_t dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) { REQUIRE(DNS_ZONEMGR_VALID(zmgr)); REQUIRE(first != NULL && *first == NULL); *first = ISC_LIST_HEAD(zmgr->zones); if (*first == NULL) return (ISC_R_NOMORE); else return (ISC_R_SUCCESS); } /*** *** Zone manager. ***/ isc_result_t dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, dns_zonemgr_t **zmgrp) { dns_zonemgr_t *zmgr; isc_result_t result; zmgr = isc_mem_get(mctx, sizeof(*zmgr)); if (zmgr == NULL) return (ISC_R_NOMEMORY); zmgr->mctx = NULL; zmgr->refs = 1; isc_mem_attach(mctx, &zmgr->mctx); zmgr->taskmgr = taskmgr; zmgr->timermgr = timermgr; zmgr->socketmgr = socketmgr; zmgr->zonetasks = NULL; zmgr->loadtasks = NULL; zmgr->mctxpool = NULL; zmgr->task = NULL; zmgr->notifyrl = NULL; zmgr->refreshrl = NULL; zmgr->startupnotifyrl = NULL; zmgr->startuprefreshrl = NULL; ISC_LIST_INIT(zmgr->zones); ISC_LIST_INIT(zmgr->waiting_for_xfrin); ISC_LIST_INIT(zmgr->xfrin_in_progress); memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable)); result = isc_rwlock_init(&zmgr->rwlock, 0, 0); if (result != ISC_R_SUCCESS) goto free_mem; zmgr->transfersin = 10; zmgr->transfersperns = 2; /* Unreachable lock. */ result = isc_rwlock_init(&zmgr->urlock, 0, 0); if (result != ISC_R_SUCCESS) goto free_rwlock; /* Create a single task for queueing of SOA queries. */ result = isc_task_create(taskmgr, 1, &zmgr->task); if (result != ISC_R_SUCCESS) goto free_urlock; isc_task_setname(zmgr->task, "zmgr", zmgr); result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, &zmgr->notifyrl); if (result != ISC_R_SUCCESS) goto free_task; result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, &zmgr->refreshrl); if (result != ISC_R_SUCCESS) goto free_notifyrl; result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, &zmgr->startupnotifyrl); if (result != ISC_R_SUCCESS) goto free_refreshrl; result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, &zmgr->startuprefreshrl); if (result != ISC_R_SUCCESS) goto free_startupnotifyrl; /* default to 20 refresh queries / notifies per second. */ setrl(zmgr->notifyrl, &zmgr->notifyrate, 20); setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20); setrl(zmgr->refreshrl, &zmgr->serialqueryrate, 20); setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, 20); zmgr->iolimit = 1; zmgr->ioactive = 0; ISC_LIST_INIT(zmgr->high); ISC_LIST_INIT(zmgr->low); result = isc_mutex_init(&zmgr->iolock); if (result != ISC_R_SUCCESS) goto free_startuprefreshrl; zmgr->magic = ZONEMGR_MAGIC; *zmgrp = zmgr; return (ISC_R_SUCCESS); #if 0 free_iolock: DESTROYLOCK(&zmgr->iolock); #endif free_startuprefreshrl: isc_ratelimiter_detach(&zmgr->startuprefreshrl); free_startupnotifyrl: isc_ratelimiter_detach(&zmgr->startupnotifyrl); free_refreshrl: isc_ratelimiter_detach(&zmgr->refreshrl); free_notifyrl: isc_ratelimiter_detach(&zmgr->notifyrl); free_task: isc_task_detach(&zmgr->task); free_urlock: isc_rwlock_destroy(&zmgr->urlock); free_rwlock: isc_rwlock_destroy(&zmgr->rwlock); free_mem: isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr)); isc_mem_detach(&mctx); return (result); } isc_result_t dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) { isc_result_t result; isc_mem_t *mctx = NULL; dns_zone_t *zone = NULL; void *item; REQUIRE(DNS_ZONEMGR_VALID(zmgr)); REQUIRE(zonep != NULL && *zonep == NULL); if (zmgr->mctxpool == NULL) return (ISC_R_FAILURE); item = isc_pool_get(zmgr->mctxpool); if (item == NULL) return (ISC_R_FAILURE); isc_mem_attach((isc_mem_t *) item, &mctx); result = dns_zone_create(&zone, mctx); isc_mem_detach(&mctx); if (result == ISC_R_SUCCESS) *zonep = zone; return (result); } isc_result_t dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) { isc_result_t result; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(DNS_ZONEMGR_VALID(zmgr)); if (zmgr->zonetasks == NULL) return (ISC_R_FAILURE); RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); LOCK_ZONE(zone); REQUIRE(zone->task == NULL); REQUIRE(zone->timer == NULL); REQUIRE(zone->zmgr == NULL); isc_taskpool_gettask(zmgr->zonetasks, &zone->task); isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask); /* * Set the task name. The tag will arbitrarily point to one * of the zones sharing the task (in practice, the one * to be managed last). */ isc_task_setname(zone->task, "zone", zone); isc_task_setname(zone->loadtask, "loadzone", zone); result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, NULL, NULL, zone->task, zone_timer, zone, &zone->timer); if (result != ISC_R_SUCCESS) goto cleanup_tasks; /* * The timer "holds" a iref. */ zone->irefs++; INSIST(zone->irefs != 0); ISC_LIST_APPEND(zmgr->zones, zone, link); zone->zmgr = zmgr; zmgr->refs++; goto unlock; cleanup_tasks: isc_task_detach(&zone->loadtask); isc_task_detach(&zone->task); unlock: UNLOCK_ZONE(zone); RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); return (result); } void dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) { isc_boolean_t free_now = ISC_FALSE; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(DNS_ZONEMGR_VALID(zmgr)); REQUIRE(zone->zmgr == zmgr); RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); LOCK_ZONE(zone); ISC_LIST_UNLINK(zmgr->zones, zone, link); zone->zmgr = NULL; zmgr->refs--; if (zmgr->refs == 0) free_now = ISC_TRUE; UNLOCK_ZONE(zone); RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); if (free_now) zonemgr_free(zmgr); ENSURE(zone->zmgr == NULL); } void dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) { REQUIRE(DNS_ZONEMGR_VALID(source)); REQUIRE(target != NULL && *target == NULL); RWLOCK(&source->rwlock, isc_rwlocktype_write); REQUIRE(source->refs > 0); source->refs++; INSIST(source->refs > 0); RWUNLOCK(&source->rwlock, isc_rwlocktype_write); *target = source; } void dns_zonemgr_detach(dns_zonemgr_t **zmgrp) { dns_zonemgr_t *zmgr; isc_boolean_t free_now = ISC_FALSE; REQUIRE(zmgrp != NULL); zmgr = *zmgrp; REQUIRE(DNS_ZONEMGR_VALID(zmgr)); RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); zmgr->refs--; if (zmgr->refs == 0) free_now = ISC_TRUE; RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); if (free_now) zonemgr_free(zmgr); *zmgrp = NULL; } isc_result_t dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) { dns_zone_t *p; REQUIRE(DNS_ZONEMGR_VALID(zmgr)); RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); for (p = ISC_LIST_HEAD(zmgr->zones); p != NULL; p = ISC_LIST_NEXT(p, link)) { dns_zone_maintenance(p); } RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); /* * Recent configuration changes may have increased the * amount of available transfers quota. Make sure any * transfers currently blocked on quota get started if * possible. */ RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); zmgr_resume_xfrs(zmgr, ISC_TRUE); RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); return (ISC_R_SUCCESS); } void dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) { REQUIRE(DNS_ZONEMGR_VALID(zmgr)); RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); zmgr_resume_xfrs(zmgr, ISC_TRUE); RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); } void dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) { dns_zone_t *zone; REQUIRE(DNS_ZONEMGR_VALID(zmgr)); isc_ratelimiter_shutdown(zmgr->notifyrl); isc_ratelimiter_shutdown(zmgr->refreshrl); isc_ratelimiter_shutdown(zmgr->startupnotifyrl); isc_ratelimiter_shutdown(zmgr->startuprefreshrl); if (zmgr->task != NULL) isc_task_destroy(&zmgr->task); if (zmgr->zonetasks != NULL) isc_taskpool_destroy(&zmgr->zonetasks); if (zmgr->loadtasks != NULL) isc_taskpool_destroy(&zmgr->loadtasks); if (zmgr->mctxpool != NULL) isc_pool_destroy(&zmgr->mctxpool); RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; zone = ISC_LIST_NEXT(zone, link)) { LOCK_ZONE(zone); forward_cancel(zone); UNLOCK_ZONE(zone); } RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); } static isc_result_t mctxinit(void **target, void *arg) { isc_result_t result; isc_mem_t *mctx = NULL; UNUSED(arg); REQUIRE(target != NULL && *target == NULL); result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) return (result); isc_mem_setname(mctx, "zonemgr-pool", NULL); *target = mctx; return (ISC_R_SUCCESS); } static void mctxfree(void **target) { isc_mem_t *mctx = *(isc_mem_t **) target; isc_mem_detach(&mctx); *target = NULL; } #define ZONES_PER_TASK 100 #define ZONES_PER_MCTX 1000 isc_result_t dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) { isc_result_t result; int ntasks = num_zones / ZONES_PER_TASK; int nmctx = num_zones / ZONES_PER_MCTX; isc_taskpool_t *pool = NULL; isc_pool_t *mctxpool = NULL; REQUIRE(DNS_ZONEMGR_VALID(zmgr)); /* * For anything fewer than 1000 zones we use 10 tasks in * the task pools. More than that, and we'll scale at one * task per 100 zones. Similarly, for anything smaller than * 2000 zones we use 2 memory contexts, then scale at 1:1000. */ if (ntasks < 10) ntasks = 10; if (nmctx < 2) nmctx = 2; /* Create or resize the zone task pools. */ if (zmgr->zonetasks == NULL) result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, ntasks, 2, &pool); else result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool); if (result == ISC_R_SUCCESS) zmgr->zonetasks = pool; pool = NULL; if (zmgr->loadtasks == NULL) result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, ntasks, 2, &pool); else result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, &pool); if (result == ISC_R_SUCCESS) zmgr->loadtasks = pool; /* * We always set all tasks in the zone-load task pool to * privileged. This prevents other tasks in the system from * running while the server task manager is in privileged * mode. * * NOTE: If we start using task privileges for any other * part of the system than zone tasks, then this will need to be * revisted. In that case we'd want to turn on privileges for * zone tasks only when we were loading, and turn them off the * rest of the time. For now, however, it's okay to just * set it and forget it. */ isc_taskpool_setprivilege(zmgr->loadtasks, ISC_TRUE); /* Create or resize the zone memory context pool. */ if (zmgr->mctxpool == NULL) result = isc_pool_create(zmgr->mctx, nmctx, mctxfree, mctxinit, NULL, &mctxpool); else result = isc_pool_expand(&zmgr->mctxpool, nmctx, &mctxpool); if (result == ISC_R_SUCCESS) zmgr->mctxpool = mctxpool; return (result); } static void zonemgr_free(dns_zonemgr_t *zmgr) { isc_mem_t *mctx; INSIST(zmgr->refs == 0); INSIST(ISC_LIST_EMPTY(zmgr->zones)); zmgr->magic = 0; DESTROYLOCK(&zmgr->iolock); isc_ratelimiter_detach(&zmgr->notifyrl); isc_ratelimiter_detach(&zmgr->refreshrl); isc_ratelimiter_detach(&zmgr->startupnotifyrl); isc_ratelimiter_detach(&zmgr->startuprefreshrl); isc_rwlock_destroy(&zmgr->urlock); isc_rwlock_destroy(&zmgr->rwlock); mctx = zmgr->mctx; isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr)); isc_mem_detach(&mctx); } void dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) { REQUIRE(DNS_ZONEMGR_VALID(zmgr)); zmgr->transfersin = value; } isc_uint32_t dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) { REQUIRE(DNS_ZONEMGR_VALID(zmgr)); return (zmgr->transfersin); } void dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) { REQUIRE(DNS_ZONEMGR_VALID(zmgr)); zmgr->transfersperns = value; } isc_uint32_t dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) { REQUIRE(DNS_ZONEMGR_VALID(zmgr)); return (zmgr->transfersperns); } /* * Try to start a new incoming zone transfer to fill a quota * slot that was just vacated. * * Requires: * The zone manager is locked by the caller. */ static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) { dns_zone_t *zone; dns_zone_t *next; for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); zone != NULL; zone = next) { isc_result_t result; next = ISC_LIST_NEXT(zone, statelink); result = zmgr_start_xfrin_ifquota(zmgr, zone); if (result == ISC_R_SUCCESS) { if (multi) continue; /* * We successfully filled the slot. We're done. */ break; } else if (result == ISC_R_QUOTA) { /* * Not enough quota. This is probably the per-server * quota, because we usually get called when a unit of * global quota has just been freed. Try the next * zone, it may succeed if it uses another master. */ continue; } else { dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting zone transfer: %s", isc_result_totext(result)); break; } } } /* * Try to start an incoming zone transfer for 'zone', quota permitting. * * Requires: * The zone manager is locked by the caller. * * Returns: * ISC_R_SUCCESS There was enough quota and we attempted to * start a transfer. zone_xfrdone() has been or will * be called. * ISC_R_QUOTA Not enough quota. * Others Failure. */ static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) { dns_peer_t *peer = NULL; isc_netaddr_t masterip; isc_uint32_t nxfrsin, nxfrsperns; dns_zone_t *x; isc_uint32_t maxtransfersin, maxtransfersperns; isc_event_t *e; /* * If we are exiting just pretend we got quota so the zone will * be cleaned up in the zone's task context. */ LOCK_ZONE(zone); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { UNLOCK_ZONE(zone); goto gotquota; } /* * Find any configured information about the server we'd * like to transfer this zone from. */ isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer); UNLOCK_ZONE(zone); /* * Determine the total maximum number of simultaneous * transfers allowed, and the maximum for this specific * master. */ maxtransfersin = zmgr->transfersin; maxtransfersperns = zmgr->transfersperns; if (peer != NULL) (void)dns_peer_gettransfers(peer, &maxtransfersperns); /* * Count the total number of transfers that are in progress, * and the number of transfers in progress from this master. * We linearly scan a list of all transfers; if this turns * out to be too slow, we could hash on the master address. */ nxfrsin = nxfrsperns = 0; for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress); x != NULL; x = ISC_LIST_NEXT(x, statelink)) { isc_netaddr_t xip; LOCK_ZONE(x); isc_netaddr_fromsockaddr(&xip, &x->masteraddr); UNLOCK_ZONE(x); nxfrsin++; if (isc_netaddr_equal(&xip, &masterip)) nxfrsperns++; } /* Enforce quota. */ if (nxfrsin >= maxtransfersin) return (ISC_R_QUOTA); if (nxfrsperns >= maxtransfersperns) return (ISC_R_QUOTA); gotquota: /* * We have sufficient quota. Move the zone to the "xfrin_in_progress" * list and send it an event to let it start the actual transfer in the * context of its own task. */ e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN, got_transfer_quota, zone, sizeof(isc_event_t)); if (e == NULL) return (ISC_R_NOMEMORY); LOCK_ZONE(zone); INSIST(zone->statelist == &zmgr->waiting_for_xfrin); ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink); ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink); zone->statelist = &zmgr->xfrin_in_progress; isc_task_send(zone->task, &e); dns_zone_log(zone, ISC_LOG_INFO, "Transfer started."); UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); } void dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) { REQUIRE(DNS_ZONEMGR_VALID(zmgr)); REQUIRE(iolimit > 0); zmgr->iolimit = iolimit; } isc_uint32_t dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) { REQUIRE(DNS_ZONEMGR_VALID(zmgr)); return (zmgr->iolimit); } /* * Get permission to request a file handle from the OS. * An event will be sent to action when one is available. * There are two queues available (high and low), the high * queue will be serviced before the low one. * * zonemgr_putio() must be called after the event is delivered to * 'action'. */ static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high, isc_task_t *task, isc_taskaction_t action, void *arg, dns_io_t **iop) { dns_io_t *io; isc_boolean_t queue; REQUIRE(DNS_ZONEMGR_VALID(zmgr)); REQUIRE(iop != NULL && *iop == NULL); io = isc_mem_get(zmgr->mctx, sizeof(*io)); if (io == NULL) return (ISC_R_NOMEMORY); io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY, action, arg, sizeof(*io->event)); if (io->event == NULL) { isc_mem_put(zmgr->mctx, io, sizeof(*io)); return (ISC_R_NOMEMORY); } io->zmgr = zmgr; io->high = high; io->task = NULL; isc_task_attach(task, &io->task); ISC_LINK_INIT(io, link); io->magic = IO_MAGIC; LOCK(&zmgr->iolock); zmgr->ioactive++; queue = ISC_TF(zmgr->ioactive > zmgr->iolimit); if (queue) { if (io->high) ISC_LIST_APPEND(zmgr->high, io, link); else ISC_LIST_APPEND(zmgr->low, io, link); } UNLOCK(&zmgr->iolock); *iop = io; if (!queue) isc_task_send(io->task, &io->event); return (ISC_R_SUCCESS); } static void zonemgr_putio(dns_io_t **iop) { dns_io_t *io; dns_io_t *next; dns_zonemgr_t *zmgr; REQUIRE(iop != NULL); io = *iop; REQUIRE(DNS_IO_VALID(io)); *iop = NULL; INSIST(!ISC_LINK_LINKED(io, link)); INSIST(io->event == NULL); zmgr = io->zmgr; isc_task_detach(&io->task); io->magic = 0; isc_mem_put(zmgr->mctx, io, sizeof(*io)); LOCK(&zmgr->iolock); INSIST(zmgr->ioactive > 0); zmgr->ioactive--; next = HEAD(zmgr->high); if (next == NULL) next = HEAD(zmgr->low); if (next != NULL) { if (next->high) ISC_LIST_UNLINK(zmgr->high, next, link); else ISC_LIST_UNLINK(zmgr->low, next, link); INSIST(next->event != NULL); } UNLOCK(&zmgr->iolock); if (next != NULL) isc_task_send(next->task, &next->event); } static void zonemgr_cancelio(dns_io_t *io) { isc_boolean_t send_event = ISC_FALSE; REQUIRE(DNS_IO_VALID(io)); /* * If we are queued to be run then dequeue. */ LOCK(&io->zmgr->iolock); if (ISC_LINK_LINKED(io, link)) { if (io->high) ISC_LIST_UNLINK(io->zmgr->high, io, link); else ISC_LIST_UNLINK(io->zmgr->low, io, link); send_event = ISC_TRUE; INSIST(io->event != NULL); } UNLOCK(&io->zmgr->iolock); if (send_event) { io->event->ev_attributes |= ISC_EVENTATTR_CANCELED; isc_task_send(io->task, &io->event); } } static void zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) { char *buf; int buflen; isc_result_t result; buflen = strlen(path) + strlen(templat) + 2; buf = isc_mem_get(zone->mctx, buflen); if (buf == NULL) return; result = isc_file_template(path, templat, buf, buflen); if (result != ISC_R_SUCCESS) goto cleanup; result = isc_file_renameunique(path, buf); if (result != ISC_R_SUCCESS) goto cleanup; dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; " "renaming file to '%s' for failure analysis and " "retransferring.", path, buf); cleanup: isc_mem_put(zone->mctx, buf, buflen); } #if 0 /* Hook for ondestroy notification from a database. */ static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) { dns_db_t *db = event->sender; UNUSED(task); isc_event_free(&event); isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), "database (%p) destroyed", (void*) db); } #endif static void setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value) { isc_interval_t interval; isc_uint32_t s, ns; isc_uint32_t pertic; isc_result_t result; if (value == 0) value = 1; if (value == 1) { s = 1; ns = 0; pertic = 1; } else if (value <= 10) { s = 0; ns = 1000000000 / value; pertic = 1; } else { s = 0; ns = (1000000000 / value) * 10; pertic = 10; } isc_interval_set(&interval, s, ns); result = isc_ratelimiter_setinterval(rl, &interval); RUNTIME_CHECK(result == ISC_R_SUCCESS); isc_ratelimiter_setpertic(rl, pertic); *rate = value; } void dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) { REQUIRE(DNS_ZONEMGR_VALID(zmgr)); setrl(zmgr->refreshrl, &zmgr->serialqueryrate, value); /* Seperately controlled in BIND 9.11.x */ setrl(zmgr->notifyrl, &zmgr->notifyrate, value); setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, value); /* XXXMPA seperate out once we have the code to support this. */ setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, value); } unsigned int dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) { REQUIRE(DNS_ZONEMGR_VALID(zmgr)); return (zmgr->serialqueryrate); } isc_boolean_t dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, isc_sockaddr_t *local, isc_time_t *now) { unsigned int i; isc_rwlocktype_t locktype; isc_result_t result; isc_uint32_t seconds = isc_time_seconds(now); isc_uint32_t count = 0; REQUIRE(DNS_ZONEMGR_VALID(zmgr)); locktype = isc_rwlocktype_read; RWLOCK(&zmgr->urlock, locktype); for (i = 0; i < UNREACH_CHACHE_SIZE; i++) { if (zmgr->unreachable[i].expire >= seconds && isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) { result = isc_rwlock_tryupgrade(&zmgr->urlock); if (result == ISC_R_SUCCESS) { locktype = isc_rwlocktype_write; zmgr->unreachable[i].last = seconds; count = zmgr->unreachable[i].count; } break; } } RWUNLOCK(&zmgr->urlock, locktype); return (ISC_TF(i < UNREACH_CHACHE_SIZE && count > 1U)); } void dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, isc_sockaddr_t *local) { unsigned int i; isc_rwlocktype_t locktype; isc_result_t result; char master[ISC_SOCKADDR_FORMATSIZE]; char source[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(remote, master, sizeof(master)); isc_sockaddr_format(local, source, sizeof(source)); REQUIRE(DNS_ZONEMGR_VALID(zmgr)); locktype = isc_rwlocktype_read; RWLOCK(&zmgr->urlock, locktype); for (i = 0; i < UNREACH_CHACHE_SIZE; i++) { if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) { if (zmgr->unreachable[i].expire == 0) break; result = isc_rwlock_tryupgrade(&zmgr->urlock); if (result == ISC_R_SUCCESS) { locktype = isc_rwlocktype_write; zmgr->unreachable[i].expire = 0; isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, ISC_LOG_INFO, "master %s (source %s) deleted " "from unreachable cache", master, source); } break; } } RWUNLOCK(&zmgr->urlock, locktype); } void dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, isc_sockaddr_t *local, isc_time_t *now) { isc_uint32_t seconds = isc_time_seconds(now); isc_uint32_t last = seconds; unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0; REQUIRE(DNS_ZONEMGR_VALID(zmgr)); RWLOCK(&zmgr->urlock, isc_rwlocktype_write); for (i = 0; i < UNREACH_CHACHE_SIZE; i++) { /* Existing entry? */ if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) break; /* Empty slot? */ if (zmgr->unreachable[i].expire < seconds) slot = i; /* Least recently used slot? */ if (zmgr->unreachable[i].last < last) { last = zmgr->unreachable[i].last; oldest = i; } } if (i < UNREACH_CHACHE_SIZE) { /* * Found a existing entry. Update the expire timer and * last usage timestamps. */ zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME; zmgr->unreachable[i].last = seconds; if (zmgr->unreachable[i].expire < seconds) zmgr->unreachable[i].count = 1; else zmgr->unreachable[i].count++; } else if (slot != UNREACH_CHACHE_SIZE) { /* * Found a empty slot. Add a new entry to the cache. */ zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME; zmgr->unreachable[slot].last = seconds; zmgr->unreachable[slot].remote = *remote; zmgr->unreachable[slot].local = *local; zmgr->unreachable[slot].count = 1; } else { /* * Replace the least recently used entry in the cache. */ zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME; zmgr->unreachable[oldest].last = seconds; zmgr->unreachable[oldest].remote = *remote; zmgr->unreachable[oldest].local = *local; zmgr->unreachable[oldest].count = 1; } RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write); } void dns_zone_forcereload(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); if (zone->type == dns_zone_master || (zone->type == dns_zone_redirect && zone->masters == NULL)) return; LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER); UNLOCK_ZONE(zone); dns_zone_refresh(zone); } isc_boolean_t dns_zone_isforced(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)); } isc_result_t dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) { /* * This function is obsoleted. */ UNUSED(zone); UNUSED(on); return (ISC_R_NOTIMPLEMENTED); } isc_uint64_t * dns_zone_getstatscounters(dns_zone_t *zone) { /* * This function is obsoleted. */ UNUSED(zone); return (NULL); } void dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(zone->stats == NULL); LOCK_ZONE(zone); zone->stats = NULL; isc_stats_attach(stats, &zone->stats); UNLOCK_ZONE(zone); } void dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (zone->requeststats_on && stats == NULL) zone->requeststats_on = ISC_FALSE; else if (!zone->requeststats_on && stats != NULL) { if (zone->requeststats == NULL) { isc_stats_attach(stats, &zone->requeststats); zone->requeststats_on = ISC_TRUE; } } UNLOCK_ZONE(zone); } void dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); if (zone->requeststats_on && stats != NULL) { if (zone->rcvquerystats == NULL) { dns_stats_attach(stats, &zone->rcvquerystats); zone->requeststats_on = ISC_TRUE; } } UNLOCK_ZONE(zone); } isc_stats_t * dns_zone_getrequeststats(dns_zone_t *zone) { /* * We don't lock zone for efficiency reason. This is not catastrophic * because requeststats must always be valid when requeststats_on is * true. * Some counters may be incremented while requeststats_on is becoming * false, or some cannot be incremented just after the statistics are * installed, but it shouldn't matter much in practice. */ if (zone->requeststats_on) return (zone->requeststats); else return (NULL); } /* * Return the received query stats bucket * see note from dns_zone_getrequeststats() */ dns_stats_t * dns_zone_getrcvquerystats(dns_zone_t *zone) { if (zone->requeststats_on) return (zone->rcvquerystats); else return (NULL); } void dns_zone_dialup(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); zone_debuglog(zone, "dns_zone_dialup", 3, "notify = %d, refresh = %d", DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY), DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) dns_zone_notify(zone); if (zone->type != dns_zone_master && zone->masters != NULL && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) dns_zone_refresh(zone); } void dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY | DNS_ZONEFLG_DIALREFRESH | DNS_ZONEFLG_NOREFRESH); switch (dialup) { case dns_dialuptype_no: break; case dns_dialuptype_yes: DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY | DNS_ZONEFLG_DIALREFRESH | DNS_ZONEFLG_NOREFRESH)); break; case dns_dialuptype_notify: DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY); break; case dns_dialuptype_notifypassive: DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); break; case dns_dialuptype_refresh: DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); break; case dns_dialuptype_passive: DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); break; default: INSIST(0); } UNLOCK_ZONE(zone); } isc_result_t dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); result = dns_zone_setstring(zone, &zone->keydirectory, directory); UNLOCK_ZONE(zone); return (result); } const char * dns_zone_getkeydirectory(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->keydirectory); } unsigned int dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) { dns_zone_t *zone; unsigned int count = 0; REQUIRE(DNS_ZONEMGR_VALID(zmgr)); RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); switch (state) { case DNS_ZONESTATE_XFERRUNNING: for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress); zone != NULL; zone = ISC_LIST_NEXT(zone, statelink)) count++; break; case DNS_ZONESTATE_XFERDEFERRED: for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); zone != NULL; zone = ISC_LIST_NEXT(zone, statelink)) count++; break; case DNS_ZONESTATE_SOAQUERY: for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; zone = ISC_LIST_NEXT(zone, link)) if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) count++; break; case DNS_ZONESTATE_ANY: for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; zone = ISC_LIST_NEXT(zone, link)) { dns_view_t *view = zone->view; if (view != NULL && strcmp(view->name, "_bind") == 0) continue; count++; } break; default: INSIST(0); } RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); return (count); } isc_result_t dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) { isc_boolean_t ok = ISC_TRUE; isc_boolean_t fail = ISC_FALSE; char namebuf[DNS_NAME_FORMATSIZE]; char namebuf2[DNS_NAME_FORMATSIZE]; char typebuf[DNS_RDATATYPE_FORMATSIZE]; int level = ISC_LOG_WARNING; dns_name_t bad; REQUIRE(DNS_ZONE_VALID(zone)); if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES) && rdata->type != dns_rdatatype_nsec3) return (ISC_R_SUCCESS); if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL) || rdata->type == dns_rdatatype_nsec3) { level = ISC_LOG_ERROR; fail = ISC_TRUE; } ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE); if (!ok) { dns_name_format(name, namebuf, sizeof(namebuf)); dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf)); dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf, dns_result_totext(DNS_R_BADOWNERNAME)); if (fail) return (DNS_R_BADOWNERNAME); } dns_name_init(&bad, NULL); ok = dns_rdata_checknames(rdata, name, &bad); if (!ok) { dns_name_format(name, namebuf, sizeof(namebuf)); dns_name_format(&bad, namebuf2, sizeof(namebuf2)); dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf)); dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf, namebuf2, dns_result_totext(DNS_R_BADNAME)); if (fail) return (DNS_R_BADNAME); } return (ISC_R_SUCCESS); } void dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) { REQUIRE(DNS_ZONE_VALID(zone)); zone->checkmx = checkmx; } void dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) { REQUIRE(DNS_ZONE_VALID(zone)); zone->checksrv = checksrv; } void dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) { REQUIRE(DNS_ZONE_VALID(zone)); zone->checkns = checkns; } void dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->isself = isself; zone->isselfarg = arg; UNLOCK_ZONE(zone); } void dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->notifydelay = delay; UNLOCK_ZONE(zone); } isc_uint32_t dns_zone_getnotifydelay(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->notifydelay); } isc_result_t dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid, isc_boolean_t delete) { isc_result_t result; REQUIRE(DNS_ZONE_VALID(zone)); dns_zone_log(zone, ISC_LOG_NOTICE, "dns_zone_signwithkey(algorithm=%u, keyid=%u)", algorithm, keyid); LOCK_ZONE(zone); result = zone_signwithkey(zone, algorithm, keyid, delete); UNLOCK_ZONE(zone); return (result); } static const char *hex = "0123456789ABCDEF"; isc_result_t dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { isc_result_t result; char salt[255*2+1]; unsigned int i, j; REQUIRE(DNS_ZONE_VALID(zone)); if (nsec3param->salt_length != 0) { INSIST((nsec3param->salt_length * 2U) < sizeof(salt)); for (i = 0, j = 0; i < nsec3param->salt_length; i++) { salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf]; salt[j++] = hex[nsec3param->salt[i] & 0xf]; } salt[j] = '\0'; } else strcpy(salt, "-"); dns_zone_log(zone, ISC_LOG_NOTICE, "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)", nsec3param->hash, nsec3param->iterations, salt); LOCK_ZONE(zone); result = zone_addnsec3chain(zone, nsec3param); UNLOCK_ZONE(zone); return (result); } void dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) { REQUIRE(DNS_ZONE_VALID(zone)); if (nodes == 0) nodes = 1; zone->nodes = nodes; } void dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) { REQUIRE(DNS_ZONE_VALID(zone)); /* * We treat signatures as a signed value so explicitly * limit its range here. */ if (signatures > ISC_INT32_MAX) signatures = ISC_INT32_MAX; else if (signatures == 0) signatures = 1; zone->signatures = signatures; } isc_uint32_t dns_zone_getsignatures(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->signatures); } void dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) { REQUIRE(DNS_ZONE_VALID(zone)); zone->privatetype = type; } dns_rdatatype_t dns_zone_getprivatetype(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->privatetype); } static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid, isc_boolean_t delete) { dns_signing_t *signing; dns_signing_t *current; isc_result_t result = ISC_R_SUCCESS; isc_time_t now; dns_db_t *db = NULL; signing = isc_mem_get(zone->mctx, sizeof *signing); if (signing == NULL) return (ISC_R_NOMEMORY); signing->magic = 0; signing->db = NULL; signing->dbiterator = NULL; signing->algorithm = algorithm; signing->keyid = keyid; signing->delete = delete; signing->done = ISC_FALSE; TIME_NOW(&now); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) dns_db_attach(zone->db, &db); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); if (db == NULL) { result = ISC_R_NOTFOUND; goto cleanup; } dns_db_attach(db, &signing->db); for (current = ISC_LIST_HEAD(zone->signing); current != NULL; current = ISC_LIST_NEXT(current, link)) { if (current->db == signing->db && current->algorithm == signing->algorithm && current->keyid == signing->keyid) { if (current->delete != signing->delete) current->done = ISC_TRUE; else goto cleanup; } } result = dns_db_createiterator(signing->db, 0, &signing->dbiterator); if (result == ISC_R_SUCCESS) result = dns_dbiterator_first(signing->dbiterator); if (result == ISC_R_SUCCESS) { dns_dbiterator_pause(signing->dbiterator); ISC_LIST_INITANDAPPEND(zone->signing, signing, link); signing = NULL; if (isc_time_isepoch(&zone->signingtime)) { zone->signingtime = now; if (zone->task != NULL) zone_settimer(zone, &now); } } cleanup: if (signing != NULL) { if (signing->db != NULL) dns_db_detach(&signing->db); if (signing->dbiterator != NULL) dns_dbiterator_destroy(&signing->dbiterator); isc_mem_put(zone->mctx, signing, sizeof *signing); } if (db != NULL) dns_db_detach(&db); return (result); } static void logmsg(const char *format, ...) { va_list args; va_start(args, format); isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(1), format, args); va_end(args); } static void clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) { dns_dnsseckey_t *key; while (!ISC_LIST_EMPTY(*list)) { key = ISC_LIST_HEAD(*list); ISC_LIST_UNLINK(*list, key, link); dns_dnsseckey_destroy(mctx, &key); } } /* Called once; *timep should be set to the current time. */ static isc_result_t next_keyevent(dst_key_t *key, isc_stdtime_t *timep) { isc_result_t result; isc_stdtime_t now, then = 0, event; int i; now = *timep; for (i = 0; i <= DST_MAX_TIMES; i++) { result = dst_key_gettime(key, i, &event); if (result == ISC_R_SUCCESS && event > now && (then == 0 || event < then)) then = event; } if (then != 0) { *timep = then; return (ISC_R_SUCCESS); } return (ISC_R_NOTFOUND); } static isc_result_t rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, const dns_rdata_t *rdata, isc_boolean_t *flag) { dns_rdataset_t rdataset; dns_dbnode_t *node = NULL; isc_result_t result; dns_rdataset_init(&rdataset); if (rdata->type == dns_rdatatype_nsec3) CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node)); else CHECK(dns_db_findnode(db, name, ISC_FALSE, &node)); result = dns_db_findrdataset(db, node, ver, rdata->type, 0, (isc_stdtime_t) 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) { *flag = ISC_FALSE; result = ISC_R_SUCCESS; goto failure; } for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t myrdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &myrdata); if (!dns_rdata_compare(&myrdata, rdata)) break; } dns_rdataset_disassociate(&rdataset); if (result == ISC_R_SUCCESS) { *flag = ISC_TRUE; } else if (result == ISC_R_NOMORE) { *flag = ISC_FALSE; result = ISC_R_SUCCESS; } failure: if (node != NULL) dns_db_detachnode(db, &node); return (result); } /* * Add records to signal the state of signing or of key removal. */ static isc_result_t add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype, dns_dbversion_t *ver, dns_diff_t *diff, isc_boolean_t sign_all) { dns_difftuple_t *tuple, *newtuple = NULL; dns_rdata_dnskey_t dnskey; dns_rdata_t rdata = DNS_RDATA_INIT; isc_boolean_t flag; isc_region_t r; isc_result_t result = ISC_R_SUCCESS; isc_uint16_t keyid; unsigned char buf[5]; dns_name_t *name = dns_db_origin(db); for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link)) { if (tuple->rdata.type != dns_rdatatype_dnskey) continue; result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if ((dnskey.flags & (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH)) != DNS_KEYOWNER_ZONE) continue; dns_rdata_toregion(&tuple->rdata, &r); keyid = dst_region_computeid(&r, dnskey.algorithm); buf[0] = dnskey.algorithm; buf[1] = (keyid & 0xff00) >> 8; buf[2] = (keyid & 0xff); buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1; buf[4] = 0; rdata.data = buf; rdata.length = sizeof(buf); rdata.type = privatetype; rdata.rdclass = tuple->rdata.rdclass; if (sign_all || tuple->op == DNS_DIFFOP_DEL) { CHECK(rr_exists(db, ver, name, &rdata, &flag)); if (flag) continue; CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name, 0, &rdata, &newtuple)); CHECK(do_one_tuple(&newtuple, db, ver, diff)); INSIST(newtuple == NULL); } /* * Remove any record which says this operation has already * completed. */ buf[4] = 1; CHECK(rr_exists(db, ver, name, &rdata, &flag)); if (flag) { CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, name, 0, &rdata, &newtuple)); CHECK(do_one_tuple(&newtuple, db, ver, diff)); INSIST(newtuple == NULL); } } failure: return (result); } static isc_result_t sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, zonediff_t *zonediff) { isc_result_t result; isc_stdtime_t now, inception, soaexpire; isc_boolean_t check_ksk, keyset_kskonly; dst_key_t *zone_keys[DNS_MAXZONEKEYS]; unsigned int nkeys = 0, i; dns_difftuple_t *tuple; result = find_zone_keys(zone, db, ver, zone->mctx, DNS_MAXZONEKEYS, zone_keys, &nkeys); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "sign_apex:find_zone_keys -> %s", dns_result_totext(result)); return (result); } isc_stdtime_get(&now); inception = now - 3600; /* Allow for clock skew. */ soaexpire = now + dns_zone_getsigvalidityinterval(zone); check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); /* * See if update_sigs will update DNSKEY signature and if not * cause them to sign so that so that newly activated keys * are used. */ for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link)) { if (tuple->rdata.type == dns_rdatatype_dnskey && dns_name_equal(&tuple->name, &zone->origin)) break; } if (tuple == NULL) { result = del_sigs(zone, db, ver, &zone->origin, dns_rdatatype_dnskey, zonediff, zone_keys, nkeys, now, ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "sign_apex:del_sigs -> %s", dns_result_totext(result)); goto failure; } result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey, zonediff->diff, zone_keys, nkeys, zone->mctx, inception, soaexpire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "sign_apex:add_sigs -> %s", dns_result_totext(result)); goto failure; } } result = update_sigs(diff, db, ver, zone_keys, nkeys, zone, inception, soaexpire, now, check_ksk, keyset_kskonly, zonediff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "sign_apex:update_sigs -> %s", dns_result_totext(result)); goto failure; } failure: for (i = 0; i < nkeys; i++) dst_key_free(&zone_keys[i]); return (result); } /* * Prevent the zone entering a inconsistent state where * NSEC only DNSKEYs are present with NSEC3 chains. * See update.c:check_dnssec() */ static isc_boolean_t dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff) { isc_result_t result; dns_difftuple_t *tuple; isc_boolean_t nseconly = ISC_FALSE, nsec3 = ISC_FALSE; dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone); /* Scan the tuples for an NSEC-only DNSKEY */ for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link)) { isc_uint8_t alg; if (tuple->rdata.type != dns_rdatatype_dnskey || tuple->op != DNS_DIFFOP_ADD) continue; alg = tuple->rdata.data[3]; if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 || alg == DST_ALG_DSA || alg == DST_ALG_ECC) { nseconly = ISC_TRUE; break; } } /* Check existing DB for NSEC-only DNSKEY */ if (!nseconly) { result = dns_nsec_nseconly(db, ver, &nseconly); if (result == ISC_R_NOTFOUND) result = ISC_R_SUCCESS; CHECK(result); } /* Check existing DB for NSEC3 */ if (!nsec3) CHECK(dns_nsec3_activex(db, ver, ISC_FALSE, privatetype, &nsec3)); /* Refuse to allow NSEC3 with NSEC-only keys */ if (nseconly && nsec3) { dns_zone_log(zone, ISC_LOG_ERROR, "NSEC only DNSKEYs and NSEC3 chains not allowed"); goto failure; } return (ISC_TRUE); failure: return (ISC_FALSE); } static isc_result_t clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff) { isc_result_t result; dns_dbnode_t *node = NULL; dns_rdataset_t rdataset; dns_rdataset_init(&rdataset); CHECK(dns_db_getoriginnode(db, &node)); result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, dns_rdatatype_none, 0, &rdataset, NULL); if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (result != ISC_R_NOTFOUND) goto failure; result = dns_nsec3param_deletechains(db, ver, zone, ISC_TRUE, diff); failure: if (node != NULL) dns_db_detachnode(db, &node); return (result); } /* * Given an RRSIG rdataset and an algorithm, determine whether there * are any signatures using that algorithm. */ static isc_boolean_t signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_rrsig_t rrsig; isc_result_t result; REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig); if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) { return (ISC_FALSE); } for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &rrsig, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_rdata_reset(&rdata); if (rrsig.algorithm == alg) return (ISC_TRUE); } return (ISC_FALSE); } static isc_result_t add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff) { dns_name_t *origin; isc_boolean_t build_nsec3; isc_result_t result; origin = dns_db_origin(db); CHECK(dns_private_chains(db, ver, zone->privatetype, NULL, &build_nsec3)); if (build_nsec3) CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum, ISC_FALSE, zone->privatetype, diff)); CHECK(updatesecure(db, ver, origin, zone->minimum, ISC_TRUE, diff)); failure: return (result); } static void zone_rekey(dns_zone_t *zone) { isc_result_t result; dns_db_t *db = NULL; dns_dbnode_t *node = NULL; dns_dbversion_t *ver = NULL; dns_rdataset_t soaset, soasigs, keyset, keysigs; dns_dnsseckeylist_t dnskeys, keys, rmkeys; dns_dnsseckey_t *key; dns_diff_t diff, _sig_diff; zonediff_t zonediff; isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE; isc_boolean_t newalg = ISC_FALSE; isc_boolean_t fullsign; dns_ttl_t ttl = 3600; const char *dir; isc_mem_t *mctx; isc_stdtime_t now; isc_time_t timenow; isc_interval_t ival; char timebuf[80]; REQUIRE(DNS_ZONE_VALID(zone)); ISC_LIST_INIT(dnskeys); ISC_LIST_INIT(keys); ISC_LIST_INIT(rmkeys); dns_rdataset_init(&soaset); dns_rdataset_init(&soasigs); dns_rdataset_init(&keyset); dns_rdataset_init(&keysigs); dir = dns_zone_getkeydirectory(zone); mctx = zone->mctx; dns_diff_init(mctx, &diff); dns_diff_init(mctx, &_sig_diff); zonediff_init(&zonediff, &_sig_diff); CHECK(dns_zone_getdb(zone, &db)); CHECK(dns_db_newversion(db, &ver)); CHECK(dns_db_getoriginnode(db, &node)); TIME_NOW(&timenow); now = isc_time_seconds(&timenow); dns_zone_log(zone, ISC_LOG_INFO, "reconfiguring zone keys"); /* Get the SOA record's TTL */ CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, dns_rdatatype_none, 0, &soaset, &soasigs)); ttl = soaset.ttl; dns_rdataset_disassociate(&soaset); /* Get the DNSKEY rdataset */ result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, dns_rdatatype_none, 0, &keyset, &keysigs); if (result == ISC_R_SUCCESS) { ttl = keyset.ttl; CHECK(dns_dnssec_keylistfromrdataset(&zone->origin, dir, mctx, &keyset, &keysigs, &soasigs, ISC_FALSE, ISC_FALSE, &dnskeys)); } else if (result != ISC_R_NOTFOUND) goto failure; /* * True when called from "rndc sign". Indicates the zone should be * fully signed now. */ fullsign = ISC_TF(DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN) != 0); result = dns_dnssec_findmatchingkeys(&zone->origin, dir, mctx, &keys); if (result == ISC_R_SUCCESS) { isc_boolean_t check_ksk; check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys, &zone->origin, ttl, &diff, ISC_TF(!check_ksk), mctx, logmsg); /* Keys couldn't be updated for some reason; * try again later. */ if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_rekey:" "couldn't update zone keys: %s", isc_result_totext(result)); goto failure; } /* * See if any pre-existing keys have newly become active; * also, see if any new key is for a new algorithm, as in that * event, we need to sign the zone fully. (If there's a new * key, but it's for an already-existing algorithm, then * the zone signing can be handled incrementally.) */ for (key = ISC_LIST_HEAD(dnskeys); key != NULL; key = ISC_LIST_NEXT(key, link)) { if (!key->first_sign) continue; newactive = ISC_TRUE; if (!dns_rdataset_isassociated(&keysigs)) { newalg = ISC_TRUE; break; } if (signed_with_alg(&keysigs, dst_key_alg(key->key))) { /* * This isn't a new algorithm; clear * first_sign so we won't sign the * whole zone with this key later */ key->first_sign = ISC_FALSE; } else { newalg = ISC_TRUE; break; } } if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) && dnskey_sane(zone, db, ver, &diff)) { CHECK(dns_diff_apply(&diff, db, ver)); CHECK(clean_nsec3param(zone, db, ver, &diff)); CHECK(add_signing_records(db, zone->privatetype, ver, &diff, ISC_TF(newalg || fullsign))); CHECK(update_soa_serial(db, ver, &diff, mctx, zone->updatemethod)); CHECK(add_chains(zone, db, ver, &diff)); CHECK(sign_apex(zone, db, ver, &diff, &zonediff)); CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_rekey")); commit = ISC_TRUE; } } dns_db_closeversion(db, &ver, ISC_TRUE); if (commit) { dns_difftuple_t *tuple; LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); zone_needdump(zone, DNS_DUMP_DELAY); zone_settimer(zone, &timenow); /* Remove any signatures from removed keys. */ if (!ISC_LIST_EMPTY(rmkeys)) { for (key = ISC_LIST_HEAD(rmkeys); key != NULL; key = ISC_LIST_NEXT(key, link)) { result = zone_signwithkey(zone, dst_key_alg(key->key), dst_key_id(key->key), ISC_TRUE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_signwithkey failed: %s", dns_result_totext(result)); } } } if (fullsign) { /* * "rndc sign" was called, so we now sign the zone * with all active keys, whether they're new or not. */ for (key = ISC_LIST_HEAD(dnskeys); key != NULL; key = ISC_LIST_NEXT(key, link)) { if (!key->force_sign && !key->hint_sign) continue; result = zone_signwithkey(zone, dst_key_alg(key->key), dst_key_id(key->key), ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_signwithkey failed: %s", dns_result_totext(result)); } } } else if (newalg) { /* * We haven't been told to sign fully, but a new * algorithm was added to the DNSKEY. We sign * the full zone, but only with newly active * keys. */ for (key = ISC_LIST_HEAD(dnskeys); key != NULL; key = ISC_LIST_NEXT(key, link)) { if (!key->first_sign) continue; result = zone_signwithkey(zone, dst_key_alg(key->key), dst_key_id(key->key), ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_signwithkey failed: %s", dns_result_totext(result)); } } } /* * Clear fullsign flag, if it was set, so we don't do * another full signing next time */ zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN; /* * Cause the zone to add/delete NSEC3 chains for the * deferred NSEC3PARAM changes. */ for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples); tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link)) { unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_nsec3param_t nsec3param; if (tuple->rdata.type != zone->privatetype || tuple->op != DNS_DIFFOP_ADD) continue; if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata, buf, sizeof(buf))) continue; result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (nsec3param.flags == 0) continue; result = zone_addnsec3chain(zone, &nsec3param); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_addnsec3chain failed: %s", dns_result_totext(result)); } } /* * Activate any NSEC3 chain updates that may have * been scheduled before this rekey. */ if (fullsign || newalg) resume_addnsec3chain(zone); /* * Schedule the next resigning event */ set_resigntime(zone); UNLOCK_ZONE(zone); } isc_time_settoepoch(&zone->refreshkeytime); /* * If we're doing key maintenance, set the key refresh timer to * the next scheduled key event or to 'dnssec-loadkeys-interval' * seconds in the future, whichever is sooner. */ if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) { isc_time_t timethen; isc_stdtime_t then; LOCK_ZONE(zone); DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval, &timethen); zone->refreshkeytime = timethen; UNLOCK_ZONE(zone); for (key = ISC_LIST_HEAD(dnskeys); key != NULL; key = ISC_LIST_NEXT(key, link)) { then = now; result = next_keyevent(key->key, &then); if (result != ISC_R_SUCCESS) continue; DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen); LOCK_ZONE(zone); if (isc_time_compare(&timethen, &zone->refreshkeytime) < 0) { zone->refreshkeytime = timethen; } UNLOCK_ZONE(zone); } zone_settimer(zone, &timenow); isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf); } done: dns_diff_clear(&diff); dns_diff_clear(&_sig_diff); clear_keylist(&dnskeys, mctx); clear_keylist(&keys, mctx); clear_keylist(&rmkeys, mctx); if (ver != NULL) dns_db_closeversion(db, &ver, ISC_FALSE); if (dns_rdataset_isassociated(&keyset)) dns_rdataset_disassociate(&keyset); if (dns_rdataset_isassociated(&keysigs)) dns_rdataset_disassociate(&keysigs); if (dns_rdataset_isassociated(&soasigs)) dns_rdataset_disassociate(&soasigs); if (node != NULL) dns_db_detachnode(db, &node); if (db != NULL) dns_db_detach(&db); INSIST(ver == NULL); return; failure: /* * Something went wrong; try again in ten minutes or * after a key refresh interval, whichever is shorter. */ isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600), 0); isc_time_nowplusinterval(&zone->refreshkeytime, &ival); goto done; } void dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign) { isc_time_t now; if (zone->type == dns_zone_master && zone->task != NULL) { LOCK_ZONE(zone); if (fullsign) zone->keyopts |= DNS_ZONEKEY_FULLSIGN; TIME_NOW(&now); zone->refreshkeytime = now; zone_settimer(zone, &now); UNLOCK_ZONE(zone); } } isc_result_t dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, unsigned int *errors) { isc_result_t result; dns_dbnode_t *node = NULL; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(errors != NULL); result = dns_db_getoriginnode(db, &node); if (result != ISC_R_SUCCESS) return (result); result = zone_count_ns_rr(zone, db, node, version, NULL, errors, ISC_FALSE); dns_db_detachnode(db, &node); return (result); } isc_result_t dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { isc_result_t result; dns_dbnode_t *node = NULL; dns_rdataset_t dnskey, cds, cdnskey; unsigned char buffer[DNS_DS_BUFFERSIZE]; unsigned char algorithms[256]; unsigned int i; REQUIRE(DNS_ZONE_VALID(zone)); result = dns_db_getoriginnode(db, &node); if (result != ISC_R_SUCCESS) return (result); dns_rdataset_init(&cds); dns_rdataset_init(&dnskey); dns_rdataset_init(&cdnskey); result = dns_db_findrdataset(db, node, version, dns_rdatatype_cds, dns_rdatatype_none, 0, &cds, NULL); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) goto failure; result = dns_db_findrdataset(db, node, version, dns_rdatatype_cdnskey, dns_rdatatype_none, 0, &cdnskey, NULL); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) goto failure; if (!dns_rdataset_isassociated(&cds) && !dns_rdataset_isassociated(&cdnskey)) { result = ISC_R_SUCCESS; goto failure; } result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, dns_rdatatype_none, 0, &dnskey, NULL); if (result == ISC_R_NOTFOUND) { if (dns_rdataset_isassociated(&cds)) result = DNS_R_BADCDS; else result = DNS_R_BADCDNSKEY; goto failure; } if (result != ISC_R_SUCCESS) goto failure; /* * For each DNSSEC algorithm in the CDS RRset there must be * a matching DNSKEY record. */ if (dns_rdataset_isassociated(&cds)) { memset(algorithms, 0, sizeof(algorithms)); for (result = dns_rdataset_first(&cds); result == ISC_R_SUCCESS; result = dns_rdataset_next(&cds)) { dns_rdata_t crdata = DNS_RDATA_INIT; dns_rdata_cds_t structcds; dns_rdataset_current(&cds, &crdata); CHECK(dns_rdata_tostruct(&crdata, &structcds, NULL)); if (algorithms[structcds.algorithm] == 0) algorithms[structcds.algorithm] = 1; for (result = dns_rdataset_first(&dnskey); result == ISC_R_SUCCESS; result = dns_rdataset_next(&dnskey)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_t dsrdata = DNS_RDATA_INIT; dns_rdataset_current(&dnskey, &rdata); CHECK(dns_ds_buildrdata(&zone->origin, &rdata, structcds.digest_type, buffer, &dsrdata)); if (crdata.length == dsrdata.length && memcmp(crdata.data, dsrdata.data, dsrdata.length) == 0) { algorithms[structcds.algorithm] = 2; } } if (result != ISC_R_NOMORE) goto failure; } for (i = 0; i < sizeof(algorithms); i++) { if (algorithms[i] == 1) { result = DNS_R_BADCDNSKEY; goto failure; } } } /* * For each DNSSEC algorithm in the CDNSKEY RRset there must be * a matching DNSKEY record. */ if (dns_rdataset_isassociated(&cdnskey)) { memset(algorithms, 0, sizeof(algorithms)); for (result = dns_rdataset_first(&cdnskey); result == ISC_R_SUCCESS; result = dns_rdataset_next(&cdnskey)) { dns_rdata_t crdata = DNS_RDATA_INIT; dns_rdata_cdnskey_t structcdnskey; dns_rdataset_current(&cdnskey, &crdata); CHECK(dns_rdata_tostruct(&crdata, &structcdnskey, NULL)); if (algorithms[structcdnskey.algorithm] == 0) algorithms[structcdnskey.algorithm] = 1; for (result = dns_rdataset_first(&dnskey); result == ISC_R_SUCCESS; result = dns_rdataset_next(&dnskey)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&dnskey, &rdata); if (crdata.length == rdata.length && memcmp(crdata.data, rdata.data, rdata.length) == 0) { algorithms[structcdnskey.algorithm] = 2; } } if (result != ISC_R_NOMORE) goto failure; } for (i = 0; i < sizeof(algorithms); i++) { if (algorithms[i] == 1) { result = DNS_R_BADCDS; goto failure; } } } result = ISC_R_SUCCESS; failure: if (dns_rdataset_isassociated(&cds)) dns_rdataset_disassociate(&cds); if (dns_rdataset_isassociated(&dnskey)) dns_rdataset_disassociate(&dnskey); if (dns_rdataset_isassociated(&cdnskey)) dns_rdataset_disassociate(&cdnskey); dns_db_detachnode(db, &node); return (result); } void dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); zone->added = added; UNLOCK_ZONE(zone); } isc_boolean_t dns_zone_getadded(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->added); } isc_result_t dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db) { isc_time_t loadtime; isc_result_t result; dns_zone_t *secure = NULL; TIME_NOW(&loadtime); /* * Lock hierarchy: zmgr, zone, raw. */ again: LOCK_ZONE(zone); INSIST(zone != zone->raw); if (inline_secure(zone)) LOCK_ZONE(zone->raw); else if (inline_raw(zone)) { secure = zone->secure; TRYLOCK_ZONE(result, secure); if (result != ISC_R_SUCCESS) { UNLOCK_ZONE(zone); secure = NULL; #if ISC_PLATFORM_USETHREADS isc_thread_yield(); #endif goto again; } } result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS); if (inline_secure(zone)) UNLOCK_ZONE(zone->raw); else if (secure != NULL) UNLOCK_ZONE(secure); UNLOCK_ZONE(zone); return result; } isc_result_t dns_zone_setrefreshkeyinterval(dns_zone_t *zone, isc_uint32_t interval) { REQUIRE(DNS_ZONE_VALID(zone)); if (interval == 0) return (ISC_R_RANGE); /* Maximum value: 24 hours (3600 minutes) */ if (interval > (24 * 60)) interval = (24 * 60); /* Multiply by 60 for seconds */ zone->refreshkeyinterval = interval * 60; return (ISC_R_SUCCESS); } void dns_zone_setrequestixfr(dns_zone_t *zone, isc_boolean_t flag) { REQUIRE(DNS_ZONE_VALID(zone)); zone->requestixfr = flag; } isc_boolean_t dns_zone_getrequestixfr(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->requestixfr); } void dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) { REQUIRE(DNS_ZONE_VALID(zone)); zone->updatemethod = method; } dns_updatemethod_t dns_zone_getserialupdatemethod(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return(zone->updatemethod); } /* * Lock hierarchy: zmgr, zone, raw. */ isc_result_t dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) { isc_result_t result; dns_zonemgr_t *zmgr; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(zone->zmgr != NULL); REQUIRE(zone->task != NULL); REQUIRE(zone->loadtask != NULL); REQUIRE(zone->raw == NULL); REQUIRE(DNS_ZONE_VALID(raw)); REQUIRE(raw->zmgr == NULL); REQUIRE(raw->task == NULL); REQUIRE(raw->loadtask == NULL); REQUIRE(raw->secure == NULL); REQUIRE(zone != raw); /* * Lock hierarchy: zmgr, zone, raw. */ zmgr = zone->zmgr; RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); LOCK_ZONE(zone); LOCK_ZONE(raw); result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, NULL, NULL, zone->task, zone_timer, raw, &raw->timer); if (result != ISC_R_SUCCESS) goto unlock; /* * The timer "holds" a iref. */ raw->irefs++; INSIST(raw->irefs != 0); /* dns_zone_attach(raw, &zone->raw); */ isc_refcount_increment(&raw->erefs, NULL); zone->raw = raw; /* dns_zone_iattach(zone, &raw->secure); */ zone_iattach(zone, &raw->secure); isc_task_attach(zone->task, &raw->task); isc_task_attach(zone->loadtask, &raw->loadtask); ISC_LIST_APPEND(zmgr->zones, raw, link); raw->zmgr = zmgr; zmgr->refs++; unlock: UNLOCK_ZONE(raw); UNLOCK_ZONE(zone); RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); return (result); } void dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(raw != NULL && *raw == NULL); LOCK(&zone->lock); INSIST(zone != zone->raw); if (zone->raw != NULL) dns_zone_attach(zone->raw, raw); UNLOCK(&zone->lock); } struct keydone { isc_event_t event; isc_boolean_t all; unsigned char data[5]; }; #define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE|DNS_NSEC3FLAG_INITIAL) static void keydone(isc_task_t *task, isc_event_t *event) { const char *me = "keydone"; isc_boolean_t commit = ISC_FALSE; isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; dns_dbversion_t *oldver = NULL, *newver = NULL; dns_zone_t *zone; dns_db_t *db = NULL; dns_dbnode_t *node = NULL; dns_rdataset_t rdataset; dns_diff_t diff; struct keydone *kd = (struct keydone *)event; dns_update_log_t log = { update_log_cb, NULL }; isc_boolean_t clear_pending = ISC_FALSE; UNUSED(task); zone = event->ev_arg; INSIST(DNS_ZONE_VALID(zone)); ENTER; dns_rdataset_init(&rdataset); dns_diff_init(zone->mctx, &diff); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) { dns_db_attach(zone->db, &db); dns_db_currentversion(db, &oldver); result = dns_db_newversion(db, &newver); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "keydone:dns_db_newversion -> %s", dns_result_totext(result)); goto failure; } } ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); if (db == NULL) goto failure; result = dns_db_getoriginnode(db, &node); if (result != ISC_R_SUCCESS) goto failure; result = dns_db_findrdataset(db, node, newver, zone->privatetype, dns_rdatatype_none, 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) { INSIST(!dns_rdataset_isassociated(&rdataset)); goto failure; } if (result != ISC_R_SUCCESS) { INSIST(!dns_rdataset_isassociated(&rdataset)); goto failure; } for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { isc_boolean_t found = ISC_FALSE; dns_rdataset_current(&rdataset, &rdata); if (kd->all) { if (rdata.length == 5 && rdata.data[0] != 0 && rdata.data[3] == 0 && rdata.data[4] == 1) found = ISC_TRUE; else if (rdata.data[0] == 0 && (rdata.data[2] & PENDINGFLAGS) != 0) { found = ISC_TRUE; clear_pending = ISC_TRUE; } } else if (rdata.length == 5 && memcmp(rdata.data, kd->data, 5) == 0) found = ISC_TRUE; if (found) CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL, &zone->origin, rdataset.ttl, &rdata)); dns_rdata_reset(&rdata); } if (!ISC_LIST_EMPTY(diff.tuples)) { /* Write changes to journal file. */ CHECK(update_soa_serial(db, newver, &diff, zone->mctx, zone->updatemethod)); result = dns_update_signatures(&log, zone, db, oldver, newver, &diff, zone->sigvalidityinterval); if (!clear_pending) CHECK(result); CHECK(zone_journal(zone, &diff, NULL, "keydone")); commit = ISC_TRUE; LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); zone_needdump(zone, 30); UNLOCK_ZONE(zone); } failure: if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (db != NULL) { if (node != NULL) dns_db_detachnode(db, &node); if (oldver != NULL) dns_db_closeversion(db, &oldver, ISC_FALSE); if (newver != NULL) dns_db_closeversion(db, &newver, commit); dns_db_detach(&db); } dns_diff_clear(&diff); isc_event_free(&event); dns_zone_idetach(&zone); INSIST(oldver == NULL); INSIST(newver == NULL); } isc_result_t dns_zone_keydone(dns_zone_t *zone, const char *keystr) { isc_result_t result = ISC_R_SUCCESS; isc_event_t *e; isc_buffer_t b; dns_zone_t *dummy = NULL; struct keydone *kd; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_KEYDONE, keydone, zone, sizeof(struct keydone)); if (e == NULL) { result = ISC_R_NOMEMORY; goto failure; } kd = (struct keydone *) e; if (strcasecmp(keystr, "all") == 0) kd->all = ISC_TRUE; else { isc_textregion_t r; char *algstr; dns_keytag_t keyid; dns_secalg_t alg; size_t n; kd->all = ISC_FALSE; n = sscanf(keystr, "%hd/", &keyid); if (n == 0U) CHECK(ISC_R_FAILURE); algstr = strchr(keystr, '/'); if (algstr != NULL) algstr++; else CHECK(ISC_R_FAILURE); n = sscanf(algstr, "%hhd", &alg); if (n == 0U) { DE_CONST(algstr, r.base); r.length = strlen(algstr); CHECK(dns_secalg_fromtext(&alg, &r)); } /* construct a private-type rdata */ isc_buffer_init(&b, kd->data, sizeof(kd->data)); isc_buffer_putuint8(&b, alg); isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8); isc_buffer_putuint8(&b, (keyid & 0xff)); isc_buffer_putuint8(&b, 0); isc_buffer_putuint8(&b, 1); } zone_iattach(zone, &dummy); isc_task_send(zone->task, &e); failure: if (e != NULL) isc_event_free(&e); UNLOCK_ZONE(zone); return (result); } static void setnsec3param(isc_task_t *task, isc_event_t *event) { const char *me = "setnsec3param"; isc_boolean_t commit = ISC_FALSE; isc_result_t result; dns_dbversion_t *oldver = NULL, *newver = NULL; dns_zone_t *zone; dns_db_t *db = NULL; dns_dbnode_t *node = NULL; dns_rdataset_t prdataset, nrdataset; dns_diff_t diff; struct np3event *npe = (struct np3event *)event; nsec3param_t *np; dns_update_log_t log = { update_log_cb, NULL }; dns_rdata_t rdata; isc_boolean_t nseconly; isc_boolean_t exists = ISC_FALSE; UNUSED(task); zone = event->ev_arg; INSIST(DNS_ZONE_VALID(zone)); ENTER; np = &npe->params; dns_rdataset_init(&prdataset); dns_rdataset_init(&nrdataset); dns_diff_init(zone->mctx, &diff); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) { dns_db_attach(zone->db, &db); dns_db_currentversion(db, &oldver); result = dns_db_newversion(db, &newver); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "setnsec3param:dns_db_newversion -> %s", dns_result_totext(result)); goto failure; } } ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); if (db == NULL) goto failure; CHECK(dns_db_getoriginnode(db, &node)); /* * Does a private-type record already exist for this chain? */ result = dns_db_findrdataset(db, node, newver, zone->privatetype, dns_rdatatype_none, 0, &prdataset, NULL); if (result == ISC_R_SUCCESS) { for (result = dns_rdataset_first(&prdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&prdataset)) { dns_rdata_init(&rdata); dns_rdataset_current(&prdataset, &rdata); if (np->length == rdata.length && memcmp(rdata.data, np->data, np->length) == 0) { exists = ISC_TRUE; break; } } } else if (result != ISC_R_NOTFOUND) { INSIST(!dns_rdataset_isassociated(&prdataset)); goto failure; } /* * Does the chain already exist? */ result = dns_db_findrdataset(db, node, newver, dns_rdatatype_nsec3param, dns_rdatatype_none, 0, &nrdataset, NULL); if (result == ISC_R_SUCCESS) { for (result = dns_rdataset_first(&nrdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&nrdataset)) { dns_rdata_init(&rdata); dns_rdataset_current(&nrdataset, &rdata); if (np->length == (rdata.length + 1) && memcmp(rdata.data, np->data + 1, np->length - 1) == 0) { exists = ISC_TRUE; break; } } } else if (result != ISC_R_NOTFOUND) { INSIST(!dns_rdataset_isassociated(&nrdataset)); goto failure; } /* * We need to remove any existing NSEC3 chains. */ if (!exists && np->replace && (np->length != 0 || np->nsec)) CHECK(dns_nsec3param_deletechains(db, newver, zone, !np->nsec, &diff)); if (!exists && np->length != 0) { /* * We're creating an NSEC3 chain. * * If the zone is not currently capable of supporting * an NSEC3 chain, add the INITIAL flag, so these * parameters can be used later when NSEC3 becomes * available. */ dns_rdata_init(&rdata); np->data[2] |= DNS_NSEC3FLAG_CREATE; result = dns_nsec_nseconly(db, newver, &nseconly); if (result == ISC_R_NOTFOUND || nseconly) np->data[2] |= DNS_NSEC3FLAG_INITIAL; rdata.length = np->length; rdata.data = np->data; rdata.type = zone->privatetype; rdata.rdclass = zone->rdclass; CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD, &zone->origin, 0, &rdata)); } if (!ISC_LIST_EMPTY(diff.tuples)) { /* Write changes to journal file. */ CHECK(update_soa_serial(db, newver, &diff, zone->mctx, zone->updatemethod)); result = dns_update_signatures(&log, zone, db, oldver, newver, &diff, zone->sigvalidityinterval); if (result != ISC_R_NOTFOUND) CHECK(result); CHECK(zone_journal(zone, &diff, NULL, "setnsec3param")); commit = ISC_TRUE; LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); zone_needdump(zone, 30); UNLOCK_ZONE(zone); } failure: if (dns_rdataset_isassociated(&prdataset)) dns_rdataset_disassociate(&prdataset); if (dns_rdataset_isassociated(&nrdataset)) dns_rdataset_disassociate(&nrdataset); if (node != NULL) dns_db_detachnode(db, &node); if (oldver != NULL) dns_db_closeversion(db, &oldver, ISC_FALSE); if (newver != NULL) dns_db_closeversion(db, &newver, commit); if (db != NULL) dns_db_detach(&db); if (commit) resume_addnsec3chain(zone); dns_diff_clear(&diff); isc_event_free(&event); dns_zone_idetach(&zone); INSIST(oldver == NULL); INSIST(newver == NULL); } isc_result_t dns_zone_setnsec3param(dns_zone_t *zone, isc_uint8_t hash, isc_uint8_t flags, isc_uint16_t iter, isc_uint8_t saltlen, unsigned char *salt, isc_boolean_t replace) { isc_result_t result = ISC_R_SUCCESS; dns_rdata_nsec3param_t param; dns_rdata_t nrdata = DNS_RDATA_INIT; dns_rdata_t prdata = DNS_RDATA_INIT; unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE]; struct np3event *npe; nsec3param_t *np; dns_zone_t *dummy = NULL; isc_buffer_t b; isc_event_t *e; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(salt != NULL); LOCK_ZONE(zone); e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETNSEC3PARAM, setnsec3param, zone, sizeof(struct np3event)); if (e == NULL) { result = ISC_R_NOMEMORY; goto failure; } npe = (struct np3event *) e; np = &npe->params; np->replace = replace; if (hash == 0) { np->length = 0; np->nsec = ISC_TRUE; } else { param.common.rdclass = zone->rdclass; param.common.rdtype = dns_rdatatype_nsec3param; ISC_LINK_INIT(¶m.common, link); param.mctx = NULL; param.hash = hash; param.flags = flags; param.iterations = iter; param.salt_length = saltlen; param.salt = salt; isc_buffer_init(&b, nbuf, sizeof(nbuf)); CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass, dns_rdatatype_nsec3param, ¶m, &b)); dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype, np->data, sizeof(np->data)); np->length = prdata.length; } zone_iattach(zone, &dummy); isc_task_send(zone->task, &e); failure: if (e != NULL) isc_event_free(&e); UNLOCK_ZONE(zone); return (result); } isc_result_t dns_zone_getloadtime(dns_zone_t *zone, isc_time_t *loadtime) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(loadtime != NULL); LOCK_ZONE(zone); *loadtime = zone->loadtime; UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); } isc_result_t dns_zone_getexpiretime(dns_zone_t *zone, isc_time_t *expiretime) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(expiretime != NULL); LOCK_ZONE(zone); *expiretime = zone->expiretime; UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); } isc_result_t dns_zone_getrefreshtime(dns_zone_t *zone, isc_time_t *refreshtime) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(refreshtime != NULL); LOCK_ZONE(zone); *refreshtime = zone->refreshtime; UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); } isc_result_t dns_zone_getrefreshkeytime(dns_zone_t *zone, isc_time_t *refreshkeytime) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(refreshkeytime != NULL); LOCK_ZONE(zone); *refreshkeytime = zone->refreshkeytime; UNLOCK_ZONE(zone); return (ISC_R_SUCCESS); } unsigned int dns_zone_getincludes(dns_zone_t *zone, char ***includesp) { dns_include_t *include; char **array = NULL; unsigned int n = 0; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(includesp != NULL && *includesp == NULL); LOCK_ZONE(zone); if (zone->nincludes == 0) goto done; array = isc_mem_allocate(zone->mctx, sizeof(char *) * zone->nincludes); if (array == NULL) goto done; for (include = ISC_LIST_HEAD(zone->includes); include != NULL; include = ISC_LIST_NEXT(include, link)) { INSIST(n < zone->nincludes); array[n++] = isc_mem_strdup(zone->mctx, include->name); } INSIST(n == zone->nincludes); *includesp = array; done: UNLOCK_ZONE(zone); return (n); } void dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) { REQUIRE(DNS_ZONE_VALID(zone)); zone->statlevel = level; } dns_zonestat_level_t dns_zone_getstatlevel(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->statlevel); } bind9-9.10.3.dfsg.P4/lib/dns/time.c0000644000470500017500000001224412664710322016030 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009-2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include /* Required for HP/UX (and others?) */ #include #include #include #include #include #include #include #include #include static const int days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; isc_result_t dns_time64_totext(isc_int64_t t, isc_buffer_t *target) { struct tm tm; char buf[sizeof("YYYYMMDDHHMMSS")]; int secs; unsigned int l; isc_region_t region; /* * Warning. Do NOT use arguments with side effects with these macros. */ #define is_leap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) #define year_secs(y) ((is_leap(y) ? 366 : 365 ) * 86400) #define month_secs(m,y) ((days[m] + ((m == 1 && is_leap(y)) ? 1 : 0 )) * 86400) tm.tm_year = 70; while (t < 0) { if (tm.tm_year == 0) return (ISC_R_RANGE); tm.tm_year--; secs = year_secs(tm.tm_year + 1900); t += secs; } while ((secs = year_secs(tm.tm_year + 1900)) <= t) { t -= secs; tm.tm_year++; if (tm.tm_year + 1900 > 9999) return (ISC_R_RANGE); } tm.tm_mon = 0; while ((secs = month_secs(tm.tm_mon, tm.tm_year + 1900)) <= t) { t -= secs; tm.tm_mon++; } tm.tm_mday = 1; while (86400 <= t) { t -= 86400; tm.tm_mday++; } tm.tm_hour = 0; while (3600 <= t) { t -= 3600; tm.tm_hour++; } tm.tm_min = 0; while (60 <= t) { t -= 60; tm.tm_min++; } tm.tm_sec = (int)t; /* yyyy mm dd HH MM SS */ snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); isc_buffer_availableregion(target, ®ion); l = strlen(buf); if (l > region.length) return (ISC_R_NOSPACE); memmove(region.base, buf, l); isc_buffer_add(target, l); return (ISC_R_SUCCESS); } isc_int64_t dns_time64_from32(isc_uint32_t value) { isc_stdtime_t now; isc_int64_t start; isc_int64_t t; /* * Adjust the time to the closest epoch. This should be changed * to use a 64-bit counterpart to isc_stdtime_get() if one ever * is defined, but even the current code is good until the year * 2106. */ isc_stdtime_get(&now); start = (isc_int64_t) now; if (isc_serial_gt(value, now)) t = start + (value - now); else t = start - (now - value); return (t); } isc_result_t dns_time32_totext(isc_uint32_t value, isc_buffer_t *target) { return (dns_time64_totext(dns_time64_from32(value), target)); } isc_result_t dns_time64_fromtext(const char *source, isc_int64_t *target) { int year, month, day, hour, minute, second; isc_int64_t value; int secs; int i; #define RANGE(min, max, value) \ do { \ if (value < (min) || value > (max)) \ return (ISC_R_RANGE); \ } while (0) if (strlen(source) != 14U) return (DNS_R_SYNTAX); /* * Confirm the source only consists digits. sscanf() allows some * minor exceptions. */ for (i = 0; i < 14; i++) { if (!isdigit((unsigned char)source[i])) return (DNS_R_SYNTAX); } if (sscanf(source, "%4d%2d%2d%2d%2d%2d", &year, &month, &day, &hour, &minute, &second) != 6) return (DNS_R_SYNTAX); RANGE(0, 9999, year); RANGE(1, 12, month); RANGE(1, days[month - 1] + ((month == 2 && is_leap(year)) ? 1 : 0), day); #ifdef __COVERITY__ /* * Use a simplified range to silence Coverity warning (in * arithmetic with day below). */ RANGE(1, 31, day); #endif /* __COVERITY__ */ RANGE(0, 23, hour); RANGE(0, 59, minute); RANGE(0, 60, second); /* 60 == leap second. */ /* * Calculate seconds from epoch. * Note: this uses a idealized calendar. */ value = second + (60 * minute) + (3600 * hour) + ((day - 1) * 86400); for (i = 0; i < (month - 1); i++) value += days[i] * 86400; if (is_leap(year) && month > 2) value += 86400; if (year < 1970) { for (i = 1969; i >= year; i--) { secs = (is_leap(i) ? 366 : 365) * 86400; value -= secs; } } else { for (i = 1970; i < year; i++) { secs = (is_leap(i) ? 366 : 365) * 86400; value += secs; } } *target = value; return (ISC_R_SUCCESS); } isc_result_t dns_time32_fromtext(const char *source, isc_uint32_t *target) { isc_int64_t value64; isc_result_t result; result = dns_time64_fromtext(source, &value64); if (result != ISC_R_SUCCESS) return (result); *target = (isc_uint32_t)value64; return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/dns/update.c0000644000470500017500000015575712664710322016375 0ustar lamontlamont/* * Copyright (C) 2011-2013, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /**************************************************************************/ #define STATE_MAGIC ISC_MAGIC('S', 'T', 'T', 'E') #define DNS_STATE_VALID(state) ISC_MAGIC_VALID(state, STATE_MAGIC) /*% * Log level for tracing dynamic update protocol requests. */ #define LOGLEVEL_PROTOCOL ISC_LOG_INFO /*% * Log level for low-level debug tracing. */ #define LOGLEVEL_DEBUG ISC_LOG_DEBUG(8) /*% * Check an operation for failure. These macros all assume that * the function using them has a 'result' variable and a 'failure' * label. */ #define CHECK(op) \ do { result = (op); \ if (result != ISC_R_SUCCESS) goto failure; \ } while (0) /*% * Fail unconditionally with result 'code', which must not * be ISC_R_SUCCESS. The reason for failure presumably has * been logged already. * * The test against ISC_R_SUCCESS is there to keep the Solaris compiler * from complaining about "end-of-loop code not reached". */ #define FAIL(code) \ do { \ result = (code); \ if (result != ISC_R_SUCCESS) goto failure; \ } while (0) /*% * Fail unconditionally and log as a client error. * The test against ISC_R_SUCCESS is there to keep the Solaris compiler * from complaining about "end-of-loop code not reached". */ #define FAILC(code, msg) \ do { \ const char *_what = "failed"; \ result = (code); \ switch (result) { \ case DNS_R_NXDOMAIN: \ case DNS_R_YXDOMAIN: \ case DNS_R_YXRRSET: \ case DNS_R_NXRRSET: \ _what = "unsuccessful"; \ } \ update_log(log, zone, LOGLEVEL_PROTOCOL, \ "update %s: %s (%s)", _what, \ msg, isc_result_totext(result)); \ if (result != ISC_R_SUCCESS) goto failure; \ } while (0) #define FAILN(code, name, msg) \ do { \ const char *_what = "failed"; \ result = (code); \ switch (result) { \ case DNS_R_NXDOMAIN: \ case DNS_R_YXDOMAIN: \ case DNS_R_YXRRSET: \ case DNS_R_NXRRSET: \ _what = "unsuccessful"; \ } \ if (isc_log_wouldlog(dns_lctx, LOGLEVEL_PROTOCOL)) { \ char _nbuf[DNS_NAME_FORMATSIZE]; \ dns_name_format(name, _nbuf, sizeof(_nbuf)); \ update_log(log, zone, LOGLEVEL_PROTOCOL, \ "update %s: %s: %s (%s)", _what, _nbuf, \ msg, isc_result_totext(result)); \ } \ if (result != ISC_R_SUCCESS) goto failure; \ } while (0) #define FAILNT(code, name, type, msg) \ do { \ const char *_what = "failed"; \ result = (code); \ switch (result) { \ case DNS_R_NXDOMAIN: \ case DNS_R_YXDOMAIN: \ case DNS_R_YXRRSET: \ case DNS_R_NXRRSET: \ _what = "unsuccessful"; \ } \ if (isc_log_wouldlog(dns_lctx, LOGLEVEL_PROTOCOL)) { \ char _nbuf[DNS_NAME_FORMATSIZE]; \ char _tbuf[DNS_RDATATYPE_FORMATSIZE]; \ dns_name_format(name, _nbuf, sizeof(_nbuf)); \ dns_rdatatype_format(type, _tbuf, sizeof(_tbuf)); \ update_log(log, zone, LOGLEVEL_PROTOCOL, \ "update %s: %s/%s: %s (%s)", \ _what, _nbuf, _tbuf, msg, \ isc_result_totext(result)); \ } \ if (result != ISC_R_SUCCESS) goto failure; \ } while (0) /*% * Fail unconditionally and log as a server error. * The test against ISC_R_SUCCESS is there to keep the Solaris compiler * from complaining about "end-of-loop code not reached". */ #define FAILS(code, msg) \ do { \ result = (code); \ update_log(log, zone, LOGLEVEL_PROTOCOL, \ "error: %s: %s", \ msg, isc_result_totext(result)); \ if (result != ISC_R_SUCCESS) goto failure; \ } while (0) /**************************************************************************/ typedef struct rr rr_t; struct rr { /* dns_name_t name; */ isc_uint32_t ttl; dns_rdata_t rdata; }; typedef struct update_event update_event_t; /**************************************************************************/ static void update_log(dns_update_log_t *callback, dns_zone_t *zone, int level, const char *fmt, ...) ISC_FORMAT_PRINTF(4, 5); static void update_log(dns_update_log_t *callback, dns_zone_t *zone, int level, const char *fmt, ...) { va_list ap; char message[4096]; if (callback == NULL) return; if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) return; va_start(ap, fmt); vsnprintf(message, sizeof(message), fmt, ap); va_end(ap); (callback->func)(callback->arg, zone, level, message); } /*% * Update a single RR in version 'ver' of 'db' and log the * update in 'diff'. * * Ensures: * \li '*tuple' == NULL. Either the tuple is freed, or its * ownership has been transferred to the diff. */ static isc_result_t do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff) { dns_diff_t temp_diff; isc_result_t result; /* * Create a singleton diff. */ dns_diff_init(diff->mctx, &temp_diff); ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); /* * Apply it to the database. */ result = dns_diff_apply(&temp_diff, db, ver); ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); if (result != ISC_R_SUCCESS) { dns_difftuple_free(tuple); return (result); } /* * Merge it into the current pending journal entry. */ dns_diff_appendminimal(diff, tuple); /* * Do not clear temp_diff. */ return (ISC_R_SUCCESS); } static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) { dns_difftuple_t *tuple = NULL; isc_result_t result; result = dns_difftuple_create(diff->mctx, op, name, ttl, rdata, &tuple); if (result != ISC_R_SUCCESS) return (result); return (do_one_tuple(&tuple, db, ver, diff)); } /**************************************************************************/ /* * Callback-style iteration over rdatasets and rdatas. * * foreach_rrset() can be used to iterate over the RRsets * of a name and call a callback function with each * one. Similarly, foreach_rr() can be used to iterate * over the individual RRs at name, optionally restricted * to RRs of a given type. * * The callback functions are called "actions" and take * two arguments: a void pointer for passing arbitrary * context information, and a pointer to the current RRset * or RR. By convention, their names end in "_action". */ /* * XXXRTH We might want to make this public somewhere in libdns. */ /*% * Function type for foreach_rrset() iterator actions. */ typedef isc_result_t rrset_func(void *data, dns_rdataset_t *rrset); /*% * Function type for foreach_rr() iterator actions. */ typedef isc_result_t rr_func(void *data, rr_t *rr); /*% * Internal context struct for foreach_node_rr(). */ typedef struct { rr_func * rr_action; void * rr_action_data; } foreach_node_rr_ctx_t; /*% * Internal helper function for foreach_node_rr(). */ static isc_result_t foreach_node_rr_action(void *data, dns_rdataset_t *rdataset) { isc_result_t result; foreach_node_rr_ctx_t *ctx = data; for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { rr_t rr = { 0, DNS_RDATA_INIT }; dns_rdataset_current(rdataset, &rr.rdata); rr.ttl = rdataset->ttl; result = (*ctx->rr_action)(ctx->rr_action_data, &rr); if (result != ISC_R_SUCCESS) return (result); } if (result != ISC_R_NOMORE) return (result); return (ISC_R_SUCCESS); } /*% * For each rdataset of 'name' in 'ver' of 'db', call 'action' * with the rdataset and 'action_data' as arguments. If the name * does not exist, do nothing. * * If 'action' returns an error, abort iteration and return the error. */ static isc_result_t foreach_rrset(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, rrset_func *action, void *action_data) { isc_result_t result; dns_dbnode_t *node; dns_rdatasetiter_t *iter; node = NULL; result = dns_db_findnode(db, name, ISC_FALSE, &node); if (result == ISC_R_NOTFOUND) return (ISC_R_SUCCESS); if (result != ISC_R_SUCCESS) return (result); iter = NULL; result = dns_db_allrdatasets(db, node, ver, (isc_stdtime_t) 0, &iter); if (result != ISC_R_SUCCESS) goto cleanup_node; for (result = dns_rdatasetiter_first(iter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(iter)) { dns_rdataset_t rdataset; dns_rdataset_init(&rdataset); dns_rdatasetiter_current(iter, &rdataset); result = (*action)(action_data, &rdataset); dns_rdataset_disassociate(&rdataset); if (result != ISC_R_SUCCESS) goto cleanup_iterator; } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; cleanup_iterator: dns_rdatasetiter_destroy(&iter); cleanup_node: dns_db_detachnode(db, &node); return (result); } /*% * For each RR of 'name' in 'ver' of 'db', call 'action' * with the RR and 'action_data' as arguments. If the name * does not exist, do nothing. * * If 'action' returns an error, abort iteration * and return the error. */ static isc_result_t foreach_node_rr(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, rr_func *rr_action, void *rr_action_data) { foreach_node_rr_ctx_t ctx; ctx.rr_action = rr_action; ctx.rr_action_data = rr_action_data; return (foreach_rrset(db, ver, name, foreach_node_rr_action, &ctx)); } /*% * For each of the RRs specified by 'db', 'ver', 'name', 'type', * (which can be dns_rdatatype_any to match any type), and 'covers', call * 'action' with the RR and 'action_data' as arguments. If the name * does not exist, or if no RRset of the given type exists at the name, * do nothing. * * If 'action' returns an error, abort iteration and return the error. */ static isc_result_t foreach_rr(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers, rr_func *rr_action, void *rr_action_data) { isc_result_t result; dns_dbnode_t *node; dns_rdataset_t rdataset; if (type == dns_rdatatype_any) return (foreach_node_rr(db, ver, name, rr_action, rr_action_data)); node = NULL; if (type == dns_rdatatype_nsec3 || (type == dns_rdatatype_rrsig && covers == dns_rdatatype_nsec3)) result = dns_db_findnsec3node(db, name, ISC_FALSE, &node); else result = dns_db_findnode(db, name, ISC_FALSE, &node); if (result == ISC_R_NOTFOUND) return (ISC_R_SUCCESS); if (result != ISC_R_SUCCESS) return (result); dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, ver, type, covers, (isc_stdtime_t) 0, &rdataset, NULL); if (result == ISC_R_NOTFOUND) { result = ISC_R_SUCCESS; goto cleanup_node; } if (result != ISC_R_SUCCESS) goto cleanup_node; for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { rr_t rr = { 0, DNS_RDATA_INIT }; dns_rdataset_current(&rdataset, &rr.rdata); rr.ttl = rdataset.ttl; result = (*rr_action)(rr_action_data, &rr); if (result != ISC_R_SUCCESS) goto cleanup_rdataset; } if (result != ISC_R_NOMORE) goto cleanup_rdataset; result = ISC_R_SUCCESS; cleanup_rdataset: dns_rdataset_disassociate(&rdataset); cleanup_node: dns_db_detachnode(db, &node); return (result); } /**************************************************************************/ /* * Various tests on the database contents (for prerequisites, etc). */ /*% * Function type for predicate functions that compare a database RR 'db_rr' * against an update RR 'update_rr'. */ typedef isc_boolean_t rr_predicate(dns_rdata_t *update_rr, dns_rdata_t *db_rr); /*% * Helper function for rrset_exists(). */ static isc_result_t rrset_exists_action(void *data, rr_t *rr) { UNUSED(data); UNUSED(rr); return (ISC_R_EXISTS); } /*% * Utility macro for RR existence checking functions. * * If the variable 'result' has the value ISC_R_EXISTS or * ISC_R_SUCCESS, set *exists to ISC_TRUE or ISC_FALSE, * respectively, and return success. * * If 'result' has any other value, there was a failure. * Return the failure result code and do not set *exists. * * This would be more readable as "do { if ... } while(0)", * but that form generates tons of warnings on Solaris 2.6. */ #define RETURN_EXISTENCE_FLAG \ return ((result == ISC_R_EXISTS) ? \ (*exists = ISC_TRUE, ISC_R_SUCCESS) : \ ((result == ISC_R_SUCCESS) ? \ (*exists = ISC_FALSE, ISC_R_SUCCESS) : \ result)) /*% * Set '*exists' to true iff an rrset of the given type exists, * to false otherwise. */ static isc_result_t rrset_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers, isc_boolean_t *exists) { isc_result_t result; result = foreach_rr(db, ver, name, type, covers, rrset_exists_action, NULL); RETURN_EXISTENCE_FLAG; } /*% * Set '*visible' to true if the RRset exists and is part of the * visible zone. Otherwise '*visible' is set to false unless a * error occurs. */ static isc_result_t rrset_visible(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_rdatatype_t type, isc_boolean_t *visible) { isc_result_t result; dns_fixedname_t fixed; dns_fixedname_init(&fixed); result = dns_db_find(db, name, ver, type, DNS_DBFIND_NOWILD, (isc_stdtime_t) 0, NULL, dns_fixedname_name(&fixed), NULL, NULL); switch (result) { case ISC_R_SUCCESS: *visible = ISC_TRUE; break; /* * Glue, obscured, deleted or replaced records. */ case DNS_R_DELEGATION: case DNS_R_DNAME: case DNS_R_CNAME: case DNS_R_NXDOMAIN: case DNS_R_NXRRSET: case DNS_R_EMPTYNAME: case DNS_R_COVERINGNSEC: *visible = ISC_FALSE; result = ISC_R_SUCCESS; break; default: *visible = ISC_FALSE; /* silence false compiler warning */ break; } return (result); } /*% * Context struct and helper function for name_exists(). */ static isc_result_t name_exists_action(void *data, dns_rdataset_t *rrset) { UNUSED(data); UNUSED(rrset); return (ISC_R_EXISTS); } /*% * Set '*exists' to true iff the given name exists, to false otherwise. */ static isc_result_t name_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, isc_boolean_t *exists) { isc_result_t result; result = foreach_rrset(db, ver, name, name_exists_action, NULL); RETURN_EXISTENCE_FLAG; } /**************************************************************************/ /* * Checking of "RRset exists (value dependent)" prerequisites. * * In the RFC2136 section 3.2.5, this is the pseudocode involving * a variable called "temp", a mapping of tuples to rrsets. * * Here, we represent the "temp" data structure as (non-minimal) "dns_diff_t" * where each tuple has op==DNS_DIFFOP_EXISTS. */ /*% * A comparison function defining the sorting order for the entries * in the "temp" data structure. The major sort key is the owner name, * followed by the type and rdata. */ static int temp_order(const void *av, const void *bv) { dns_difftuple_t const * const *ap = av; dns_difftuple_t const * const *bp = bv; dns_difftuple_t const *a = *ap; dns_difftuple_t const *b = *bp; int r; r = dns_name_compare(&a->name, &b->name); if (r != 0) return (r); r = (b->rdata.type - a->rdata.type); if (r != 0) return (r); r = dns_rdata_casecompare(&a->rdata, &b->rdata); return (r); } /**************************************************************************/ /* * Conditional deletion of RRs. */ /*% * Context structure for delete_if(). */ typedef struct { rr_predicate *predicate; dns_db_t *db; dns_dbversion_t *ver; dns_diff_t *diff; dns_name_t *name; dns_rdata_t *update_rr; } conditional_delete_ctx_t; /*% * Predicate functions for delete_if(). */ /*% * Return true always. */ static isc_boolean_t true_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { UNUSED(update_rr); UNUSED(db_rr); return (ISC_TRUE); } /*% * Return true if the record is a RRSIG. */ static isc_boolean_t rrsig_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { UNUSED(update_rr); return ((db_rr->type == dns_rdatatype_rrsig) ? ISC_TRUE : ISC_FALSE); } /*% * Internal helper function for delete_if(). */ static isc_result_t delete_if_action(void *data, rr_t *rr) { conditional_delete_ctx_t *ctx = data; if ((*ctx->predicate)(ctx->update_rr, &rr->rdata)) { isc_result_t result; result = update_one_rr(ctx->db, ctx->ver, ctx->diff, DNS_DIFFOP_DEL, ctx->name, rr->ttl, &rr->rdata); return (result); } else { return (ISC_R_SUCCESS); } } /*% * Conditionally delete RRs. Apply 'predicate' to the RRs * specified by 'db', 'ver', 'name', and 'type' (which can * be dns_rdatatype_any to match any type). Delete those * RRs for which the predicate returns true, and log the * deletions in 'diff'. */ static isc_result_t delete_if(rr_predicate *predicate, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers, dns_rdata_t *update_rr, dns_diff_t *diff) { conditional_delete_ctx_t ctx; ctx.predicate = predicate; ctx.db = db; ctx.ver = ver; ctx.diff = diff; ctx.name = name; ctx.update_rr = update_rr; return (foreach_rr(db, ver, name, type, covers, delete_if_action, &ctx)); } /**************************************************************************/ /* * Incremental updating of NSECs and RRSIGs. */ /*% * We abuse the dns_diff_t type to represent a set of domain names * affected by the update. */ static isc_result_t namelist_append_name(dns_diff_t *list, dns_name_t *name) { isc_result_t result; dns_difftuple_t *tuple = NULL; static dns_rdata_t dummy_rdata = DNS_RDATA_INIT; CHECK(dns_difftuple_create(list->mctx, DNS_DIFFOP_EXISTS, name, 0, &dummy_rdata, &tuple)); dns_diff_append(list, &tuple); failure: return (result); } static isc_result_t namelist_append_subdomain(dns_db_t *db, dns_name_t *name, dns_diff_t *affected) { isc_result_t result; dns_fixedname_t fixedname; dns_name_t *child; dns_dbiterator_t *dbit = NULL; dns_fixedname_init(&fixedname); child = dns_fixedname_name(&fixedname); CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit)); for (result = dns_dbiterator_seek(dbit, name); result == ISC_R_SUCCESS; result = dns_dbiterator_next(dbit)) { dns_dbnode_t *node = NULL; CHECK(dns_dbiterator_current(dbit, &node, child)); dns_db_detachnode(db, &node); if (! dns_name_issubdomain(child, name)) break; CHECK(namelist_append_name(affected, child)); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; failure: if (dbit != NULL) dns_dbiterator_destroy(&dbit); return (result); } /*% * Helper function for non_nsec_rrset_exists(). */ static isc_result_t is_non_nsec_action(void *data, dns_rdataset_t *rrset) { UNUSED(data); if (!(rrset->type == dns_rdatatype_nsec || rrset->type == dns_rdatatype_nsec3 || (rrset->type == dns_rdatatype_rrsig && (rrset->covers == dns_rdatatype_nsec || rrset->covers == dns_rdatatype_nsec3)))) return (ISC_R_EXISTS); return (ISC_R_SUCCESS); } /*% * Check whether there is an rrset other than a NSEC or RRSIG NSEC, * i.e., anything that justifies the continued existence of a name * after a secure update. * * If such an rrset exists, set '*exists' to ISC_TRUE. * Otherwise, set it to ISC_FALSE. */ static isc_result_t non_nsec_rrset_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, isc_boolean_t *exists) { isc_result_t result; result = foreach_rrset(db, ver, name, is_non_nsec_action, NULL); RETURN_EXISTENCE_FLAG; } /*% * A comparison function for sorting dns_diff_t:s by name. */ static int name_order(const void *av, const void *bv) { dns_difftuple_t const * const *ap = av; dns_difftuple_t const * const *bp = bv; dns_difftuple_t const *a = *ap; dns_difftuple_t const *b = *bp; return (dns_name_compare(&a->name, &b->name)); } static isc_result_t uniqify_name_list(dns_diff_t *list) { isc_result_t result; dns_difftuple_t *p, *q; CHECK(dns_diff_sort(list, name_order)); p = ISC_LIST_HEAD(list->tuples); while (p != NULL) { do { q = ISC_LIST_NEXT(p, link); if (q == NULL || ! dns_name_equal(&p->name, &q->name)) break; ISC_LIST_UNLINK(list->tuples, q, link); dns_difftuple_free(&q); } while (1); p = ISC_LIST_NEXT(p, link); } failure: return (result); } static isc_result_t is_active(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, isc_boolean_t *flag, isc_boolean_t *cut, isc_boolean_t *unsecure) { isc_result_t result; dns_fixedname_t foundname; dns_fixedname_init(&foundname); result = dns_db_find(db, name, ver, dns_rdatatype_any, DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD, (isc_stdtime_t) 0, NULL, dns_fixedname_name(&foundname), NULL, NULL); if (result == ISC_R_SUCCESS || result == DNS_R_EMPTYNAME) { *flag = ISC_TRUE; *cut = ISC_FALSE; if (unsecure != NULL) *unsecure = ISC_FALSE; return (ISC_R_SUCCESS); } else if (result == DNS_R_ZONECUT) { *flag = ISC_TRUE; *cut = ISC_TRUE; if (unsecure != NULL) { /* * We are at the zonecut. Check to see if there * is a DS RRset. */ if (dns_db_find(db, name, ver, dns_rdatatype_ds, 0, (isc_stdtime_t) 0, NULL, dns_fixedname_name(&foundname), NULL, NULL) == DNS_R_NXRRSET) *unsecure = ISC_TRUE; else *unsecure = ISC_FALSE; } return (ISC_R_SUCCESS); } else if (result == DNS_R_GLUE || result == DNS_R_DNAME || result == DNS_R_DELEGATION || result == DNS_R_NXDOMAIN) { *flag = ISC_FALSE; *cut = ISC_FALSE; if (unsecure != NULL) *unsecure = ISC_FALSE; return (ISC_R_SUCCESS); } else { /* * Silence compiler. */ *flag = ISC_FALSE; *cut = ISC_FALSE; if (unsecure != NULL) *unsecure = ISC_FALSE; return (result); } } /*% * Find the next/previous name that has a NSEC record. * In other words, skip empty database nodes and names that * have had their NSECs removed because they are obscured by * a zone cut. */ static isc_result_t next_active(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *oldname, dns_name_t *newname, isc_boolean_t forward) { isc_result_t result; dns_dbiterator_t *dbit = NULL; isc_boolean_t has_nsec = ISC_FALSE; unsigned int wraps = 0; isc_boolean_t secure = dns_db_issecure(db); CHECK(dns_db_createiterator(db, 0, &dbit)); CHECK(dns_dbiterator_seek(dbit, oldname)); do { dns_dbnode_t *node = NULL; if (forward) result = dns_dbiterator_next(dbit); else result = dns_dbiterator_prev(dbit); if (result == ISC_R_NOMORE) { /* * Wrap around. */ if (forward) CHECK(dns_dbiterator_first(dbit)); else CHECK(dns_dbiterator_last(dbit)); wraps++; if (wraps == 2) { update_log(log, zone, ISC_LOG_ERROR, "secure zone with no NSECs"); result = DNS_R_BADZONE; goto failure; } } CHECK(dns_dbiterator_current(dbit, &node, newname)); dns_db_detachnode(db, &node); /* * The iterator may hold the tree lock, and * rrset_exists() calls dns_db_findnode() which * may try to reacquire it. To avoid deadlock * we must pause the iterator first. */ CHECK(dns_dbiterator_pause(dbit)); if (secure) { CHECK(rrset_exists(db, ver, newname, dns_rdatatype_nsec, 0, &has_nsec)); } else { dns_fixedname_t ffound; dns_name_t *found; dns_fixedname_init(&ffound); found = dns_fixedname_name(&ffound); result = dns_db_find(db, newname, ver, dns_rdatatype_soa, DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL); if (result == ISC_R_SUCCESS || result == DNS_R_EMPTYNAME || result == DNS_R_NXRRSET || result == DNS_R_CNAME || (result == DNS_R_DELEGATION && dns_name_equal(newname, found))) { has_nsec = ISC_TRUE; result = ISC_R_SUCCESS; } else if (result != DNS_R_NXDOMAIN) break; } } while (! has_nsec); failure: if (dbit != NULL) dns_dbiterator_destroy(&dbit); return (result); } /*% * Add a NSEC record for "name", recording the change in "diff". * The existing NSEC is removed. */ static isc_result_t add_nsec(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_ttl_t nsecttl, dns_diff_t *diff) { isc_result_t result; dns_dbnode_t *node = NULL; unsigned char buffer[DNS_NSEC_BUFFERSIZE]; dns_rdata_t rdata = DNS_RDATA_INIT; dns_difftuple_t *tuple = NULL; dns_fixedname_t fixedname; dns_name_t *target; dns_fixedname_init(&fixedname); target = dns_fixedname_name(&fixedname); /* * Find the successor name, aka NSEC target. */ CHECK(next_active(log, zone, db, ver, name, target, ISC_TRUE)); /* * Create the NSEC RDATA. */ CHECK(dns_db_findnode(db, name, ISC_FALSE, &node)); dns_rdata_init(&rdata); CHECK(dns_nsec_buildrdata(db, ver, node, target, buffer, &rdata)); dns_db_detachnode(db, &node); /* * Delete the old NSEC and record the change. */ CHECK(delete_if(true_p, db, ver, name, dns_rdatatype_nsec, 0, NULL, diff)); /* * Add the new NSEC and record the change. */ CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name, nsecttl, &rdata, &tuple)); CHECK(do_one_tuple(&tuple, db, ver, diff)); INSIST(tuple == NULL); failure: if (node != NULL) dns_db_detachnode(db, &node); return (result); } /*% * Add a placeholder NSEC record for "name", recording the change in "diff". */ static isc_result_t add_placeholder_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_diff_t *diff) { isc_result_t result; dns_difftuple_t *tuple = NULL; isc_region_t r; unsigned char data[1] = { 0 }; /* The root domain, no bits. */ dns_rdata_t rdata = DNS_RDATA_INIT; r.base = data; r.length = sizeof(data); dns_rdata_fromregion(&rdata, dns_db_class(db), dns_rdatatype_nsec, &r); CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name, 0, &rdata, &tuple)); CHECK(do_one_tuple(&tuple, db, ver, diff)); failure: return (result); } static isc_result_t find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx, unsigned int maxkeys, dst_key_t **keys, unsigned int *nkeys) { isc_result_t result; dns_dbnode_t *node = NULL; const char *directory = dns_zone_getkeydirectory(zone); CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node)); CHECK(dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db), directory, mctx, maxkeys, keys, nkeys)); failure: if (node != NULL) dns_db_detachnode(db, &node); return (result); } /*% * Add RRSIG records for an RRset, recording the change in "diff". */ static isc_result_t add_sigs(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys, unsigned int nkeys, isc_stdtime_t inception, isc_stdtime_t expire, isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly) { isc_result_t result; dns_dbnode_t *node = NULL; dns_rdataset_t rdataset; dns_rdata_t sig_rdata = DNS_RDATA_INIT; isc_buffer_t buffer; unsigned char data[1024]; /* XXX */ unsigned int i, j; isc_boolean_t added_sig = ISC_FALSE; isc_mem_t *mctx = diff->mctx; dns_rdataset_init(&rdataset); isc_buffer_init(&buffer, data, sizeof(data)); /* Get the rdataset to sign. */ if (type == dns_rdatatype_nsec3) CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node)); else CHECK(dns_db_findnode(db, name, ISC_FALSE, &node)); CHECK(dns_db_findrdataset(db, node, ver, type, 0, (isc_stdtime_t) 0, &rdataset, NULL)); dns_db_detachnode(db, &node); #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0) #define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0) #define ALG(x) dst_key_alg(x) /* * If we are honoring KSK flags then we need to check that we * have both KSK and non-KSK keys that are not revoked per * algorithm. */ for (i = 0; i < nkeys; i++) { isc_boolean_t both = ISC_FALSE; if (!dst_key_isprivate(keys[i])) continue; if (check_ksk && !REVOKE(keys[i])) { isc_boolean_t have_ksk, have_nonksk; if (KSK(keys[i])) { have_ksk = ISC_TRUE; have_nonksk = ISC_FALSE; } else { have_ksk = ISC_FALSE; have_nonksk = ISC_TRUE; } for (j = 0; j < nkeys; j++) { if (j == i || ALG(keys[i]) != ALG(keys[j])) continue; if (REVOKE(keys[j])) continue; if (KSK(keys[j])) have_ksk = ISC_TRUE; else have_nonksk = ISC_TRUE; both = have_ksk && have_nonksk; if (both) break; } } if (both) { if (type == dns_rdatatype_dnskey) { if (!KSK(keys[i]) && keyset_kskonly) continue; } else if (KSK(keys[i])) { /* * CDS and CDNSKEY are signed with KSK * (RFC 7344, 4.1). */ if (type != dns_rdatatype_cds && type != dns_rdatatype_cdnskey) continue; } } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) continue; /* Calculate the signature, creating a RRSIG RDATA. */ CHECK(dns_dnssec_sign(name, &rdataset, keys[i], &inception, &expire, mctx, &buffer, &sig_rdata)); /* Update the database and journal with the RRSIG. */ /* XXX inefficient - will cause dataset merging */ CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, name, rdataset.ttl, &sig_rdata)); dns_rdata_reset(&sig_rdata); isc_buffer_init(&buffer, data, sizeof(data)); added_sig = ISC_TRUE; } if (!added_sig) { update_log(log, zone, ISC_LOG_ERROR, "found no active private keys, " "unable to generate any signatures"); result = ISC_R_NOTFOUND; } failure: if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (node != NULL) dns_db_detachnode(db, &node); return (result); } /* * Delete expired RRsigs and any RRsigs we are about to re-sign. * See also zone.c:del_sigs(). */ static isc_result_t del_keysigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_diff_t *diff, dst_key_t **keys, unsigned int nkeys) { isc_result_t result; dns_dbnode_t *node = NULL; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; unsigned int i; dns_rdata_rrsig_t rrsig; isc_boolean_t found; dns_rdataset_init(&rdataset); result = dns_db_findnode(db, name, ISC_FALSE, &node); if (result == ISC_R_NOTFOUND) return (ISC_R_SUCCESS); if (result != ISC_R_SUCCESS) goto failure; result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, dns_rdatatype_dnskey, (isc_stdtime_t) 0, &rdataset, NULL); dns_db_detachnode(db, &node); if (result == ISC_R_NOTFOUND) return (ISC_R_SUCCESS); if (result != ISC_R_SUCCESS) goto failure; for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &rrsig, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); found = ISC_FALSE; for (i = 0; i < nkeys; i++) { if (rrsig.keyid == dst_key_id(keys[i])) { found = ISC_TRUE; if (!dst_key_isprivate(keys[i]) && !dst_key_inactive(keys[i])) { /* * The re-signing code in zone.c * will mark this as offline. * Just skip the record for now. */ break; } result = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, rdataset.ttl, &rdata); break; } } /* * If there is not a matching DNSKEY then delete the RRSIG. */ if (!found) result = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, rdataset.ttl, &rdata); dns_rdata_reset(&rdata); if (result != ISC_R_SUCCESS) break; } dns_rdataset_disassociate(&rdataset); if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; failure: if (node != NULL) dns_db_detachnode(db, &node); return (result); } static isc_result_t add_exposed_sigs(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, isc_boolean_t cut, dns_diff_t *diff, dst_key_t **keys, unsigned int nkeys, isc_stdtime_t inception, isc_stdtime_t expire, isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly, unsigned int *sigs) { isc_result_t result; dns_dbnode_t *node; dns_rdatasetiter_t *iter; node = NULL; result = dns_db_findnode(db, name, ISC_FALSE, &node); if (result == ISC_R_NOTFOUND) return (ISC_R_SUCCESS); if (result != ISC_R_SUCCESS) return (result); iter = NULL; result = dns_db_allrdatasets(db, node, ver, (isc_stdtime_t) 0, &iter); if (result != ISC_R_SUCCESS) goto cleanup_node; for (result = dns_rdatasetiter_first(iter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(iter)) { dns_rdataset_t rdataset; dns_rdatatype_t type; isc_boolean_t flag; dns_rdataset_init(&rdataset); dns_rdatasetiter_current(iter, &rdataset); type = rdataset.type; dns_rdataset_disassociate(&rdataset); /* * We don't need to sign unsigned NSEC records at the cut * as they are handled elsewhere. */ if ((type == dns_rdatatype_rrsig) || (cut && type != dns_rdatatype_ds)) continue; result = rrset_exists(db, ver, name, dns_rdatatype_rrsig, type, &flag); if (result != ISC_R_SUCCESS) goto cleanup_iterator; if (flag) continue;; result = add_sigs(log, zone, db, ver, name, type, diff, keys, nkeys, inception, expire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) goto cleanup_iterator; (*sigs)++; } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; cleanup_iterator: dns_rdatasetiter_destroy(&iter); cleanup_node: dns_db_detachnode(db, &node); return (result); } /*% * Update RRSIG, NSEC and NSEC3 records affected by an update. The original * update, including the SOA serial update but excluding the RRSIG & NSEC * changes, is in "diff" and has already been applied to "newver" of "db". * The database version prior to the update is "oldver". * * The necessary RRSIG, NSEC and NSEC3 changes will be applied to "newver" * and added (as a minimal diff) to "diff". * * The RRSIGs generated will be valid for 'sigvalidityinterval' seconds. */ isc_result_t dns_update_signatures(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *oldver, dns_dbversion_t *newver, dns_diff_t *diff, isc_uint32_t sigvalidityinterval) { return (dns_update_signaturesinc(log, zone, db, oldver, newver, diff, sigvalidityinterval, NULL)); } struct dns_update_state { unsigned int magic; dns_diff_t diffnames; dns_diff_t affected; dns_diff_t sig_diff; dns_diff_t nsec_diff; dns_diff_t nsec_mindiff; dns_diff_t work; dst_key_t *zone_keys[DNS_MAXZONEKEYS]; unsigned int nkeys; isc_stdtime_t inception, expire; dns_ttl_t nsecttl; isc_boolean_t check_ksk, keyset_kskonly; enum { sign_updates, remove_orphaned, build_chain, process_nsec, sign_nsec, update_nsec3, process_nsec3, sign_nsec3 } state; }; isc_result_t dns_update_signaturesinc(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *oldver, dns_dbversion_t *newver, dns_diff_t *diff, isc_uint32_t sigvalidityinterval, dns_update_state_t **statep) { isc_result_t result = ISC_R_SUCCESS; dns_update_state_t mystate, *state; dns_difftuple_t *t, *next; isc_boolean_t flag, build_nsec, build_nsec3; unsigned int i; isc_stdtime_t now; dns_rdata_soa_t soa; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_t rdataset; dns_dbnode_t *node = NULL; isc_boolean_t unsecure; isc_boolean_t cut; dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone); unsigned int sigs = 0; unsigned int maxsigs = dns_zone_getsignatures(zone); if (statep == NULL || (statep != NULL && *statep == NULL)) { if (statep == NULL) { state = &mystate; } else { state = isc_mem_get(diff->mctx, sizeof(*state)); if (state == NULL) return (ISC_R_NOMEMORY); } dns_diff_init(diff->mctx, &state->diffnames); dns_diff_init(diff->mctx, &state->affected); dns_diff_init(diff->mctx, &state->sig_diff); dns_diff_init(diff->mctx, &state->nsec_diff); dns_diff_init(diff->mctx, &state->nsec_mindiff); dns_diff_init(diff->mctx, &state->work); state->nkeys = 0; result = find_zone_keys(zone, db, newver, diff->mctx, DNS_MAXZONEKEYS, state->zone_keys, &state->nkeys); if (result != ISC_R_SUCCESS) { update_log(log, zone, ISC_LOG_ERROR, "could not get zone keys for secure " "dynamic update"); goto failure; } isc_stdtime_get(&now); state->inception = now - 3600; /* Allow for some clock skew. */ state->expire = now + sigvalidityinterval; /* * Do we look at the KSK flag on the DNSKEY to determining which * keys sign which RRsets? First check the zone option then * check the keys flags to make sure at least one has a ksk set * and one doesn't. */ state->check_ksk = ISC_TF((dns_zone_getoptions(zone) & DNS_ZONEOPT_UPDATECHECKKSK) != 0); state->keyset_kskonly = ISC_TF((dns_zone_getoptions(zone) & DNS_ZONEOPT_DNSKEYKSKONLY) != 0); /* * Get the NSEC/NSEC3 TTL from the SOA MINIMUM field. */ CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node)); dns_rdataset_init(&rdataset); CHECK(dns_db_findrdataset(db, node, newver, dns_rdatatype_soa, 0, (isc_stdtime_t) 0, &rdataset, NULL)); CHECK(dns_rdataset_first(&rdataset)); dns_rdataset_current(&rdataset, &rdata); CHECK(dns_rdata_tostruct(&rdata, &soa, NULL)); state->nsecttl = soa.minimum; dns_rdataset_disassociate(&rdataset); dns_db_detachnode(db, &node); /* * Find all RRsets directly affected by the update, and * update their RRSIGs. Also build a list of names affected * by the update in "diffnames". */ CHECK(dns_diff_sort(diff, temp_order)); state->state = sign_updates; state->magic = STATE_MAGIC; if (statep != NULL) *statep = state; } else { REQUIRE(DNS_STATE_VALID(*statep)); state = *statep; } next_state: switch (state->state) { case sign_updates: t = ISC_LIST_HEAD(diff->tuples); while (t != NULL) { dns_name_t *name = &t->name; /* * Now "name" is a new, unique name affected by the * update. */ CHECK(namelist_append_name(&state->diffnames, name)); while (t != NULL && dns_name_equal(&t->name, name)) { dns_rdatatype_t type; type = t->rdata.type; /* * Now "name" and "type" denote a new unique * RRset affected by the update. */ /* Don't sign RRSIGs. */ if (type == dns_rdatatype_rrsig) goto skip; /* * Delete all old RRSIGs covering this type, * since they are all invalid when the signed * RRset has changed. We may not be able to * recreate all of them - tough. * Special case changes to the zone's DNSKEY * records to support offline KSKs. */ if (type == dns_rdatatype_dnskey) del_keysigs(db, newver, name, &state->sig_diff, state->zone_keys, state->nkeys); else CHECK(delete_if(true_p, db, newver, name, dns_rdatatype_rrsig, type, NULL, &state->sig_diff)); /* * If this RRset is still visible after the * update, add a new signature for it. */ CHECK(rrset_visible(db, newver, name, type, &flag)); if (flag) { CHECK(add_sigs(log, zone, db, newver, name, type, &state->sig_diff, state->zone_keys, state->nkeys, state->inception, state->expire, state->check_ksk, state->keyset_kskonly)); sigs++; } skip: /* Skip any other updates to the same RRset. */ while (t != NULL && dns_name_equal(&t->name, name) && t->rdata.type == type) { next = ISC_LIST_NEXT(t, link); ISC_LIST_UNLINK(diff->tuples, t, link); ISC_LIST_APPEND(state->work.tuples, t, link); t = next; } } if (state != &mystate && sigs > maxsigs) return (DNS_R_CONTINUE); } ISC_LIST_APPENDLIST(diff->tuples, state->work.tuples, link); update_log(log, zone, ISC_LOG_DEBUG(3), "updated data signatures"); /*FALLTHROUGH*/ case remove_orphaned: state->state = remove_orphaned; /* Remove orphaned NSECs and RRSIG NSECs. */ for (t = ISC_LIST_HEAD(state->diffnames.tuples); t != NULL; t = ISC_LIST_NEXT(t, link)) { CHECK(non_nsec_rrset_exists(db, newver, &t->name, &flag)); if (!flag) { CHECK(delete_if(true_p, db, newver, &t->name, dns_rdatatype_any, 0, NULL, &state->sig_diff)); } } update_log(log, zone, ISC_LOG_DEBUG(3), "removed any orphaned NSEC records"); /* * See if we need to build NSEC or NSEC3 chains. */ CHECK(dns_private_chains(db, newver, privatetype, &build_nsec, &build_nsec3)); if (!build_nsec) { state->state = update_nsec3; goto next_state; } update_log(log, zone, ISC_LOG_DEBUG(3), "rebuilding NSEC chain"); /*FALLTHROUGH*/ case build_chain: state->state = build_chain; /* * When a name is created or deleted, its predecessor needs to * have its NSEC updated. */ for (t = ISC_LIST_HEAD(state->diffnames.tuples); t != NULL; t = ISC_LIST_NEXT(t, link)) { isc_boolean_t existed, exists; dns_fixedname_t fixedname; dns_name_t *prevname; dns_fixedname_init(&fixedname); prevname = dns_fixedname_name(&fixedname); if (oldver != NULL) CHECK(name_exists(db, oldver, &t->name, &existed)); else existed = ISC_FALSE; CHECK(name_exists(db, newver, &t->name, &exists)); if (exists == existed) continue; /* * Find the predecessor. * When names become obscured or unobscured in this * update transaction, we may find the wrong * predecessor because the NSECs have not yet been * updated to reflect the delegation change. This * should not matter because in this case, the correct * predecessor is either the delegation node or a * newly unobscured node, and those nodes are on the * "affected" list in any case. */ CHECK(next_active(log, zone, db, newver, &t->name, prevname, ISC_FALSE)); CHECK(namelist_append_name(&state->affected, prevname)); } /* * Find names potentially affected by delegation changes * (obscured by adding an NS or DNAME, or unobscured by * removing one). */ for (t = ISC_LIST_HEAD(state->diffnames.tuples); t != NULL; t = ISC_LIST_NEXT(t, link)) { isc_boolean_t ns_existed, dname_existed; isc_boolean_t ns_exists, dname_exists; if (oldver != NULL) CHECK(rrset_exists(db, oldver, &t->name, dns_rdatatype_ns, 0, &ns_existed)); else ns_existed = ISC_FALSE; if (oldver != NULL) CHECK(rrset_exists(db, oldver, &t->name, dns_rdatatype_dname, 0, &dname_existed)); else dname_existed = ISC_FALSE; CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_ns, 0, &ns_exists)); CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_dname, 0, &dname_exists)); if ((ns_exists || dname_exists) == (ns_existed || dname_existed)) continue; /* * There was a delegation change. Mark all subdomains * of t->name as potentially needing a NSEC update. */ CHECK(namelist_append_subdomain(db, &t->name, &state->affected)); } ISC_LIST_APPENDLIST(state->affected.tuples, state->diffnames.tuples, link); INSIST(ISC_LIST_EMPTY(state->diffnames.tuples)); CHECK(uniqify_name_list(&state->affected)); /*FALLTHROUGH*/ case process_nsec: state->state = process_nsec; /* * Determine which names should have NSECs, and delete/create * NSECs to make it so. We don't know the final NSEC targets * yet, so we just create placeholder NSECs with arbitrary * contents to indicate that their respective owner names * should be part of the NSEC chain. */ while ((t = ISC_LIST_HEAD(state->affected.tuples)) != NULL) { isc_boolean_t exists; dns_name_t *name = &t->name; CHECK(name_exists(db, newver, name, &exists)); if (! exists) goto unlink; CHECK(is_active(db, newver, name, &flag, &cut, NULL)); if (!flag) { /* * This name is obscured. Delete any * existing NSEC record. */ CHECK(delete_if(true_p, db, newver, name, dns_rdatatype_nsec, 0, NULL, &state->nsec_diff)); CHECK(delete_if(rrsig_p, db, newver, name, dns_rdatatype_any, 0, NULL, diff)); } else { /* * This name is not obscured. It needs to have * a NSEC unless it is the at the origin, in * which case it should already exist if there * is a complete NSEC chain and if there isn't * a complete NSEC chain we don't want to add * one as that would signal that there is a * complete NSEC chain. */ if (!dns_name_equal(name, dns_db_origin(db))) { CHECK(rrset_exists(db, newver, name, dns_rdatatype_nsec, 0, &flag)); if (!flag) CHECK(add_placeholder_nsec(db, newver, name, diff)); } CHECK(add_exposed_sigs(log, zone, db, newver, name, cut, &state->sig_diff, state->zone_keys, state->nkeys, state->inception, state->expire, state->check_ksk, state->keyset_kskonly, &sigs)); } unlink: ISC_LIST_UNLINK(state->affected.tuples, t, link); ISC_LIST_APPEND(state->work.tuples, t, link); if (state != &mystate && sigs > maxsigs) return (DNS_R_CONTINUE); } ISC_LIST_APPENDLIST(state->affected.tuples, state->work.tuples, link); /* * Now we know which names are part of the NSEC chain. * Make them all point at their correct targets. */ for (t = ISC_LIST_HEAD(state->affected.tuples); t != NULL; t = ISC_LIST_NEXT(t, link)) { CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_nsec, 0, &flag)); if (flag) { /* * There is a NSEC, but we don't know if it * is correct. Delete it and create a correct * one to be sure. If the update was * unnecessary, the diff minimization * will take care of eliminating it from the * journal, IXFRs, etc. * * The RRSIG bit should always be set in the * NSECs we generate, because they will all * get RRSIG NSECs. * (XXX what if the zone keys are missing?). * Because the RRSIG NSECs have not necessarily * been created yet, the correctness of the * bit mask relies on the assumption that NSECs * are only created if there is other data, and * if there is other data, there are other * RRSIGs. */ CHECK(add_nsec(log, zone, db, newver, &t->name, state->nsecttl, &state->nsec_diff)); } } /* * Minimize the set of NSEC updates so that we don't * have to regenerate the RRSIG NSECs for NSECs that were * replaced with identical ones. */ while ((t = ISC_LIST_HEAD(state->nsec_diff.tuples)) != NULL) { ISC_LIST_UNLINK(state->nsec_diff.tuples, t, link); dns_diff_appendminimal(&state->nsec_mindiff, &t); } update_log(log, zone, ISC_LOG_DEBUG(3), "signing rebuilt NSEC chain"); /*FALLTHROUGH*/ case sign_nsec: state->state = sign_nsec; /* Update RRSIG NSECs. */ while ((t = ISC_LIST_HEAD(state->nsec_mindiff.tuples)) != NULL) { if (t->op == DNS_DIFFOP_DEL) { CHECK(delete_if(true_p, db, newver, &t->name, dns_rdatatype_rrsig, dns_rdatatype_nsec, NULL, &state->sig_diff)); } else if (t->op == DNS_DIFFOP_ADD) { CHECK(add_sigs(log, zone, db, newver, &t->name, dns_rdatatype_nsec, &state->sig_diff, state->zone_keys, state->nkeys, state->inception, state->expire, state->check_ksk, state->keyset_kskonly)); sigs++; } else { INSIST(0); } ISC_LIST_UNLINK(state->nsec_mindiff.tuples, t, link); ISC_LIST_APPEND(state->work.tuples, t, link); if (state != &mystate && sigs > maxsigs) return (DNS_R_CONTINUE); } ISC_LIST_APPENDLIST(state->nsec_mindiff.tuples, state->work.tuples, link); /*FALLTHROUGH*/ case update_nsec3: state->state = update_nsec3; /* Record our changes for the journal. */ while ((t = ISC_LIST_HEAD(state->sig_diff.tuples)) != NULL) { ISC_LIST_UNLINK(state->sig_diff.tuples, t, link); dns_diff_appendminimal(diff, &t); } while ((t = ISC_LIST_HEAD(state->nsec_mindiff.tuples)) != NULL) { ISC_LIST_UNLINK(state->nsec_mindiff.tuples, t, link); dns_diff_appendminimal(diff, &t); } INSIST(ISC_LIST_EMPTY(state->sig_diff.tuples)); INSIST(ISC_LIST_EMPTY(state->nsec_diff.tuples)); INSIST(ISC_LIST_EMPTY(state->nsec_mindiff.tuples)); if (!build_nsec3) { update_log(log, zone, ISC_LOG_DEBUG(3), "no NSEC3 chains to rebuild"); goto failure; } update_log(log, zone, ISC_LOG_DEBUG(3), "rebuilding NSEC3 chains"); dns_diff_clear(&state->diffnames); dns_diff_clear(&state->affected); CHECK(dns_diff_sort(diff, temp_order)); /* * Find names potentially affected by delegation changes * (obscured by adding an NS or DNAME, or unobscured by * removing one). */ t = ISC_LIST_HEAD(diff->tuples); while (t != NULL) { dns_name_t *name = &t->name; isc_boolean_t ns_existed, dname_existed; isc_boolean_t ns_exists, dname_exists; isc_boolean_t exists, existed; if (t->rdata.type == dns_rdatatype_nsec || t->rdata.type == dns_rdatatype_rrsig) { t = ISC_LIST_NEXT(t, link); continue; } CHECK(namelist_append_name(&state->affected, name)); if (oldver != NULL) CHECK(rrset_exists(db, oldver, name, dns_rdatatype_ns, 0, &ns_existed)); else ns_existed = ISC_FALSE; if (oldver != NULL) CHECK(rrset_exists(db, oldver, name, dns_rdatatype_dname, 0, &dname_existed)); else dname_existed = ISC_FALSE; CHECK(rrset_exists(db, newver, name, dns_rdatatype_ns, 0, &ns_exists)); CHECK(rrset_exists(db, newver, name, dns_rdatatype_dname, 0, &dname_exists)); exists = ns_exists || dname_exists; existed = ns_existed || dname_existed; if (exists == existed) goto nextname; /* * There was a delegation change. Mark all subdomains * of t->name as potentially needing a NSEC3 update. */ CHECK(namelist_append_subdomain(db, name, &state->affected)); nextname: while (t != NULL && dns_name_equal(&t->name, name)) t = ISC_LIST_NEXT(t, link); } /*FALLTHROUGH*/ case process_nsec3: state->state = process_nsec3; while ((t = ISC_LIST_HEAD(state->affected.tuples)) != NULL) { dns_name_t *name = &t->name; unsecure = ISC_FALSE; /* Silence compiler warning. */ CHECK(is_active(db, newver, name, &flag, &cut, &unsecure)); if (!flag) { CHECK(delete_if(rrsig_p, db, newver, name, dns_rdatatype_any, 0, NULL, diff)); CHECK(dns_nsec3_delnsec3sx(db, newver, name, privatetype, &state->nsec_diff)); } else { CHECK(add_exposed_sigs(log, zone, db, newver, name, cut, &state->sig_diff, state->zone_keys, state->nkeys, state->inception, state->expire, state->check_ksk, state->keyset_kskonly, &sigs)); CHECK(dns_nsec3_addnsec3sx(db, newver, name, state->nsecttl, unsecure, privatetype, &state->nsec_diff)); } ISC_LIST_UNLINK(state->affected.tuples, t, link); ISC_LIST_APPEND(state->work.tuples, t, link); if (state != &mystate && sigs > maxsigs) return (DNS_R_CONTINUE); } ISC_LIST_APPENDLIST(state->affected.tuples, state->work.tuples, link); /* * Minimize the set of NSEC3 updates so that we don't * have to regenerate the RRSIG NSEC3s for NSEC3s that were * replaced with identical ones. */ while ((t = ISC_LIST_HEAD(state->nsec_diff.tuples)) != NULL) { ISC_LIST_UNLINK(state->nsec_diff.tuples, t, link); dns_diff_appendminimal(&state->nsec_mindiff, &t); } update_log(log, zone, ISC_LOG_DEBUG(3), "signing rebuilt NSEC3 chain"); /*FALLTHROUGH*/ case sign_nsec3: state->state = sign_nsec3; /* Update RRSIG NSEC3s. */ while ((t = ISC_LIST_HEAD(state->nsec_mindiff.tuples)) != NULL) { if (t->op == DNS_DIFFOP_DEL) { CHECK(delete_if(true_p, db, newver, &t->name, dns_rdatatype_rrsig, dns_rdatatype_nsec3, NULL, &state->sig_diff)); } else if (t->op == DNS_DIFFOP_ADD) { CHECK(add_sigs(log, zone, db, newver, &t->name, dns_rdatatype_nsec3, &state->sig_diff, state->zone_keys, state->nkeys, state->inception, state->expire, state->check_ksk, state->keyset_kskonly)); sigs++; } else { INSIST(0); } ISC_LIST_UNLINK(state->nsec_mindiff.tuples, t, link); ISC_LIST_APPEND(state->work.tuples, t, link); if (state != &mystate && sigs > maxsigs) return (DNS_R_CONTINUE); } ISC_LIST_APPENDLIST(state->nsec_mindiff.tuples, state->work.tuples, link); /* Record our changes for the journal. */ while ((t = ISC_LIST_HEAD(state->sig_diff.tuples)) != NULL) { ISC_LIST_UNLINK(state->sig_diff.tuples, t, link); dns_diff_appendminimal(diff, &t); } while ((t = ISC_LIST_HEAD(state->nsec_mindiff.tuples)) != NULL) { ISC_LIST_UNLINK(state->nsec_mindiff.tuples, t, link); dns_diff_appendminimal(diff, &t); } INSIST(ISC_LIST_EMPTY(state->sig_diff.tuples)); INSIST(ISC_LIST_EMPTY(state->nsec_diff.tuples)); INSIST(ISC_LIST_EMPTY(state->nsec_mindiff.tuples)); break; default: INSIST(0); } failure: dns_diff_clear(&state->sig_diff); dns_diff_clear(&state->nsec_diff); dns_diff_clear(&state->nsec_mindiff); dns_diff_clear(&state->affected); dns_diff_clear(&state->diffnames); dns_diff_clear(&state->work); for (i = 0; i < state->nkeys; i++) dst_key_free(&state->zone_keys[i]); if (state != &mystate && state != NULL) { *statep = NULL; state->magic = 0; isc_mem_put(diff->mctx, state, sizeof(*state)); } return (result); } isc_uint32_t dns_update_soaserial(isc_uint32_t serial, dns_updatemethod_t method) { isc_stdtime_t now; if (method == dns_updatemethod_unixtime) { isc_stdtime_get(&now); if (now != 0 && isc_serial_gt(now, serial)) return (now); } /* RFC1982 */ serial = (serial + 1) & 0xFFFFFFFF; if (serial == 0) serial = 1; return (serial); } bind9-9.10.3.dfsg.P4/lib/dns/gssapi_link.c0000644000470500017500000002274312664710322017402 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * $Id: gssapi_link.c,v 1.17 2011/03/28 05:32:16 marka Exp $ */ #include #ifdef GSSAPI #include #include #include #include #include #include #include #include "dst_internal.h" #include "dst_parse.h" #include #define INITIAL_BUFFER_SIZE 1024 #define BUFFER_EXTRA 1024 #define REGION_TO_GBUFFER(r, gb) \ do { \ (gb).length = (r).length; \ (gb).value = (r).base; \ } while (0) #define GBUFFER_TO_REGION(gb, r) \ do { \ (r).length = (unsigned int)(gb).length; \ (r).base = (gb).value; \ } while (0) struct dst_gssapi_signverifyctx { isc_buffer_t *buffer; }; /*% * Allocate a temporary "context" for use in gathering data for signing * or verifying. */ static isc_result_t gssapi_create_signverify_ctx(dst_key_t *key, dst_context_t *dctx) { dst_gssapi_signverifyctx_t *ctx; isc_result_t result; UNUSED(key); ctx = isc_mem_get(dctx->mctx, sizeof(dst_gssapi_signverifyctx_t)); if (ctx == NULL) return (ISC_R_NOMEMORY); ctx->buffer = NULL; result = isc_buffer_allocate(dctx->mctx, &ctx->buffer, INITIAL_BUFFER_SIZE); if (result != ISC_R_SUCCESS) { isc_mem_put(dctx->mctx, ctx, sizeof(dst_gssapi_signverifyctx_t)); return (result); } dctx->ctxdata.gssctx = ctx; return (ISC_R_SUCCESS); } /*% * Destroy the temporary sign/verify context. */ static void gssapi_destroy_signverify_ctx(dst_context_t *dctx) { dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx; if (ctx != NULL) { if (ctx->buffer != NULL) isc_buffer_free(&ctx->buffer); isc_mem_put(dctx->mctx, ctx, sizeof(dst_gssapi_signverifyctx_t)); dctx->ctxdata.gssctx = NULL; } } /*% * Add data to our running buffer of data we will be signing or verifying. * This code will see if the new data will fit in our existing buffer, and * copy it in if it will. If not, it will attempt to allocate a larger * buffer and copy old+new into it, and free the old buffer. */ static isc_result_t gssapi_adddata(dst_context_t *dctx, const isc_region_t *data) { dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx; isc_buffer_t *newbuffer = NULL; isc_region_t r; unsigned int length; isc_result_t result; result = isc_buffer_copyregion(ctx->buffer, data); if (result == ISC_R_SUCCESS) return (ISC_R_SUCCESS); length = isc_buffer_length(ctx->buffer) + data->length + BUFFER_EXTRA; result = isc_buffer_allocate(dctx->mctx, &newbuffer, length); if (result != ISC_R_SUCCESS) return (result); isc_buffer_usedregion(ctx->buffer, &r); (void)isc_buffer_copyregion(newbuffer, &r); (void)isc_buffer_copyregion(newbuffer, data); isc_buffer_free(&ctx->buffer); ctx->buffer = newbuffer; return (ISC_R_SUCCESS); } /*% * Sign. */ static isc_result_t gssapi_sign(dst_context_t *dctx, isc_buffer_t *sig) { dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx; isc_region_t message; gss_buffer_desc gmessage, gsig; OM_uint32 minor, gret; gss_ctx_id_t gssctx = dctx->key->keydata.gssctx; char buf[1024]; /* * Convert the data we wish to sign into a structure gssapi can * understand. */ isc_buffer_usedregion(ctx->buffer, &message); REGION_TO_GBUFFER(message, gmessage); /* * Generate the signature. */ gret = gss_get_mic(&minor, gssctx, GSS_C_QOP_DEFAULT, &gmessage, &gsig); /* * If it did not complete, we log the result and return a generic * failure code. */ if (gret != GSS_S_COMPLETE) { gss_log(3, "GSS sign error: %s", gss_error_tostring(gret, minor, buf, sizeof(buf))); return (ISC_R_FAILURE); } /* * If it will not fit in our allocated buffer, return that we need * more space. */ if (gsig.length > isc_buffer_availablelength(sig)) { gss_release_buffer(&minor, &gsig); return (ISC_R_NOSPACE); } /* * Copy the output into our buffer space, and release the gssapi * allocated space. */ isc_buffer_putmem(sig, gsig.value, (unsigned int)gsig.length); if (gsig.length != 0U) gss_release_buffer(&minor, &gsig); return (ISC_R_SUCCESS); } /*% * Verify. */ static isc_result_t gssapi_verify(dst_context_t *dctx, const isc_region_t *sig) { dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx; isc_region_t message, r; gss_buffer_desc gmessage, gsig; OM_uint32 minor, gret; gss_ctx_id_t gssctx = dctx->key->keydata.gssctx; unsigned char *buf; char err[1024]; /* * Convert the data we wish to sign into a structure gssapi can * understand. */ isc_buffer_usedregion(ctx->buffer, &message); REGION_TO_GBUFFER(message, gmessage); /* * XXXMLG * It seem that gss_verify_mic() modifies the signature buffer, * at least on Heimdal's implementation. Copy it here to an allocated * buffer. */ buf = isc_mem_allocate(dst__memory_pool, sig->length); if (buf == NULL) return (ISC_R_FAILURE); memmove(buf, sig->base, sig->length); r.base = buf; r.length = sig->length; REGION_TO_GBUFFER(r, gsig); /* * Verify the data. */ gret = gss_verify_mic(&minor, gssctx, &gmessage, &gsig, NULL); isc_mem_free(dst__memory_pool, buf); /* * Convert return codes into something useful to us. */ if (gret != GSS_S_COMPLETE) { gss_log(3, "GSS verify error: %s", gss_error_tostring(gret, minor, err, sizeof(err))); if (gret == GSS_S_DEFECTIVE_TOKEN || gret == GSS_S_BAD_SIG || gret == GSS_S_DUPLICATE_TOKEN || gret == GSS_S_OLD_TOKEN || gret == GSS_S_UNSEQ_TOKEN || gret == GSS_S_GAP_TOKEN || gret == GSS_S_CONTEXT_EXPIRED || gret == GSS_S_NO_CONTEXT || gret == GSS_S_FAILURE) return(DST_R_VERIFYFAILURE); else return (ISC_R_FAILURE); } return (ISC_R_SUCCESS); } static isc_boolean_t gssapi_compare(const dst_key_t *key1, const dst_key_t *key2) { gss_ctx_id_t gsskey1 = key1->keydata.gssctx; gss_ctx_id_t gsskey2 = key2->keydata.gssctx; /* No idea */ return (ISC_TF(gsskey1 == gsskey2)); } static isc_result_t gssapi_generate(dst_key_t *key, int unused, void (*callback)(int)) { UNUSED(key); UNUSED(unused); UNUSED(callback); /* No idea */ return (ISC_R_FAILURE); } static isc_boolean_t gssapi_isprivate(const dst_key_t *key) { UNUSED(key); return (ISC_TRUE); } static void gssapi_destroy(dst_key_t *key) { REQUIRE(key != NULL); dst_gssapi_deletectx(key->mctx, &key->keydata.gssctx); key->keydata.gssctx = NULL; } static isc_result_t gssapi_restore(dst_key_t *key, const char *keystr) { OM_uint32 major, minor; unsigned int len; isc_buffer_t *b = NULL; isc_region_t r; gss_buffer_desc gssbuffer; isc_result_t result; len = strlen(keystr); if ((len % 4) != 0U) return (ISC_R_BADBASE64); len = (len / 4) * 3; result = isc_buffer_allocate(key->mctx, &b, len); if (result != ISC_R_SUCCESS) return (result); result = isc_base64_decodestring(keystr, b); if (result != ISC_R_SUCCESS) { isc_buffer_free(&b); return (result); } isc_buffer_remainingregion(b, &r); REGION_TO_GBUFFER(r, gssbuffer); major = gss_import_sec_context(&minor, &gssbuffer, &key->keydata.gssctx); if (major != GSS_S_COMPLETE) { isc_buffer_free(&b); return (ISC_R_FAILURE); } isc_buffer_free(&b); return (ISC_R_SUCCESS); } static isc_result_t gssapi_dump(dst_key_t *key, isc_mem_t *mctx, char **buffer, int *length) { OM_uint32 major, minor; gss_buffer_desc gssbuffer; size_t len; char *buf; isc_buffer_t b; isc_region_t r; isc_result_t result; major = gss_export_sec_context(&minor, &key->keydata.gssctx, &gssbuffer); if (major != GSS_S_COMPLETE) { fprintf(stderr, "gss_export_sec_context -> %d, %d\n", major, minor); return (ISC_R_FAILURE); } if (gssbuffer.length == 0U) return (ISC_R_FAILURE); len = ((gssbuffer.length + 2)/3) * 4; buf = isc_mem_get(mctx, len); if (buf == NULL) { gss_release_buffer(&minor, &gssbuffer); return (ISC_R_NOMEMORY); } isc_buffer_init(&b, buf, (unsigned int)len); GBUFFER_TO_REGION(gssbuffer, r); result = isc_base64_totext(&r, 0, "", &b); RUNTIME_CHECK(result == ISC_R_SUCCESS); gss_release_buffer(&minor, &gssbuffer); *buffer = buf; *length = (int)len; return (ISC_R_SUCCESS); } static dst_func_t gssapi_functions = { gssapi_create_signverify_ctx, NULL, /*%< createctx2 */ gssapi_destroy_signverify_ctx, gssapi_adddata, gssapi_sign, gssapi_verify, NULL, /*%< verify2 */ NULL, /*%< computesecret */ gssapi_compare, NULL, /*%< paramcompare */ gssapi_generate, gssapi_isprivate, gssapi_destroy, NULL, /*%< todns */ NULL, /*%< fromdns */ NULL, /*%< tofile */ NULL, /*%< parse */ NULL, /*%< cleanup */ NULL, /*%< fromlabel */ gssapi_dump, gssapi_restore, }; isc_result_t dst__gssapi_init(dst_func_t **funcp) { REQUIRE(funcp != NULL); if (*funcp == NULL) *funcp = &gssapi_functions; return (ISC_R_SUCCESS); } #else int gssapi_link_unneeded = 1; #endif /*! \file */ bind9-9.10.3.dfsg.P4/lib/dns/api0000644000470500017500000000030012664710322015410 0ustar lamontlamont# LIBINTERFACE ranges # 9.6: 50-59, 110-119 # 9.7: 60-79 # 9.8: 80-89, 120-129 # 9.9: 90-109 # 9.9-sub: 130-139, 150-159 # 9.10: 140-149, 160-169 LIBINTERFACE = 163 LIBREVISION = 3 LIBAGE = 1 bind9-9.10.3.dfsg.P4/lib/dns/dst_openssl.h0000644000470500017500000000421012664710322017426 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007-2009, 2011, 2012, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: dst_openssl.h,v 1.11 2011/03/12 04:59:48 tbox Exp $ */ #ifndef DST_OPENSSL_H #define DST_OPENSSL_H 1 #include #include #include #include #include #include #include #include #include #if !defined(OPENSSL_NO_ENGINE) && defined(CRYPTO_LOCK_ENGINE) && \ (OPENSSL_VERSION_NUMBER >= 0x0090707f) #define USE_ENGINE 1 #endif #if OPENSSL_VERSION_NUMBER < 0x10100000L /* * These are new in OpenSSL 1.1.0. BN_GENCB _cb needs to be declared in * the function like this before the BN_GENCB_new call: * * #if OPENSSL_VERSION_NUMBER < 0x10100000L * _cb; * #endif */ #define BN_GENCB_free(x) (x = NULL); #define BN_GENCB_new() (&_cb) #define BN_GENCB_get_arg(x) ((x)->arg) #endif ISC_LANG_BEGINDECLS isc_result_t dst__openssl_toresult(isc_result_t fallback); isc_result_t dst__openssl_toresult2(const char *funcname, isc_result_t fallback); isc_result_t dst__openssl_toresult3(isc_logcategory_t *category, const char *funcname, isc_result_t fallback); #ifdef USE_ENGINE ENGINE * dst__openssl_getengine(const char *engine); #else #define dst__openssl_getengine(x) NULL #endif ISC_LANG_ENDDECLS #endif /* DST_OPENSSL_H */ /*! \file */ bind9-9.10.3.dfsg.P4/lib/dns/dbtable.c0000644000470500017500000001546412664710322016476 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * $Id: dbtable.c,v 1.33 2007/06/19 23:47:16 tbox Exp $ */ /*! \file * \author * Principal Author: DCL */ #include #include #include #include #include #include #include #include struct dns_dbtable { /* Unlocked. */ unsigned int magic; isc_mem_t * mctx; dns_rdataclass_t rdclass; isc_mutex_t lock; isc_rwlock_t tree_lock; /* Locked by lock. */ unsigned int references; /* Locked by tree_lock. */ dns_rbt_t * rbt; dns_db_t * default_db; }; #define DBTABLE_MAGIC ISC_MAGIC('D', 'B', '-', '-') #define VALID_DBTABLE(dbtable) ISC_MAGIC_VALID(dbtable, DBTABLE_MAGIC) static void dbdetach(void *data, void *arg) { dns_db_t *db = data; UNUSED(arg); dns_db_detach(&db); } isc_result_t dns_dbtable_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_dbtable_t **dbtablep) { dns_dbtable_t *dbtable; isc_result_t result; REQUIRE(mctx != NULL); REQUIRE(dbtablep != NULL && *dbtablep == NULL); dbtable = (dns_dbtable_t *)isc_mem_get(mctx, sizeof(*dbtable)); if (dbtable == NULL) return (ISC_R_NOMEMORY); dbtable->rbt = NULL; result = dns_rbt_create(mctx, dbdetach, NULL, &dbtable->rbt); if (result != ISC_R_SUCCESS) goto clean1; result = isc_mutex_init(&dbtable->lock); if (result != ISC_R_SUCCESS) goto clean2; result = isc_rwlock_init(&dbtable->tree_lock, 0, 0); if (result != ISC_R_SUCCESS) goto clean3; dbtable->default_db = NULL; dbtable->mctx = NULL; isc_mem_attach(mctx, &dbtable->mctx); dbtable->rdclass = rdclass; dbtable->magic = DBTABLE_MAGIC; dbtable->references = 1; *dbtablep = dbtable; return (ISC_R_SUCCESS); clean3: DESTROYLOCK(&dbtable->lock); clean2: dns_rbt_destroy(&dbtable->rbt); clean1: isc_mem_putanddetach(&mctx, dbtable, sizeof(*dbtable)); return (result); } static inline void dbtable_free(dns_dbtable_t *dbtable) { /* * Caller must ensure that it is safe to call. */ RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write); if (dbtable->default_db != NULL) dns_db_detach(&dbtable->default_db); dns_rbt_destroy(&dbtable->rbt); RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write); isc_rwlock_destroy(&dbtable->tree_lock); dbtable->magic = 0; isc_mem_putanddetach(&dbtable->mctx, dbtable, sizeof(*dbtable)); } void dns_dbtable_attach(dns_dbtable_t *source, dns_dbtable_t **targetp) { REQUIRE(VALID_DBTABLE(source)); REQUIRE(targetp != NULL && *targetp == NULL); LOCK(&source->lock); INSIST(source->references > 0); source->references++; INSIST(source->references != 0); UNLOCK(&source->lock); *targetp = source; } void dns_dbtable_detach(dns_dbtable_t **dbtablep) { dns_dbtable_t *dbtable; isc_boolean_t free_dbtable = ISC_FALSE; REQUIRE(dbtablep != NULL); dbtable = *dbtablep; REQUIRE(VALID_DBTABLE(dbtable)); LOCK(&dbtable->lock); INSIST(dbtable->references > 0); dbtable->references--; if (dbtable->references == 0) free_dbtable = ISC_TRUE; UNLOCK(&dbtable->lock); if (free_dbtable) dbtable_free(dbtable); *dbtablep = NULL; } isc_result_t dns_dbtable_add(dns_dbtable_t *dbtable, dns_db_t *db) { isc_result_t result; dns_db_t *clone; REQUIRE(VALID_DBTABLE(dbtable)); REQUIRE(dns_db_class(db) == dbtable->rdclass); clone = NULL; dns_db_attach(db, &clone); RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write); result = dns_rbt_addname(dbtable->rbt, dns_db_origin(clone), clone); RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write); return (result); } void dns_dbtable_remove(dns_dbtable_t *dbtable, dns_db_t *db) { dns_db_t *stored_data = NULL; isc_result_t result; dns_name_t *name; REQUIRE(VALID_DBTABLE(dbtable)); name = dns_db_origin(db); /* * There is a requirement that the association of name with db * be verified. With the current rbt.c this is expensive to do, * because effectively two find operations are being done, but * deletion is relatively infrequent. * XXXDCL ... this could be cheaper now with dns_rbt_deletenode. */ RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write); result = dns_rbt_findname(dbtable->rbt, name, 0, NULL, (void **) (void *)&stored_data); if (result == ISC_R_SUCCESS) { INSIST(stored_data == db); (void)dns_rbt_deletename(dbtable->rbt, name, ISC_FALSE); } RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write); } void dns_dbtable_adddefault(dns_dbtable_t *dbtable, dns_db_t *db) { REQUIRE(VALID_DBTABLE(dbtable)); REQUIRE(dbtable->default_db == NULL); REQUIRE(dns_name_compare(dns_db_origin(db), dns_rootname) == 0); RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write); dbtable->default_db = NULL; dns_db_attach(db, &dbtable->default_db); RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write); } void dns_dbtable_getdefault(dns_dbtable_t *dbtable, dns_db_t **dbp) { REQUIRE(VALID_DBTABLE(dbtable)); REQUIRE(dbp != NULL && *dbp == NULL); RWLOCK(&dbtable->tree_lock, isc_rwlocktype_read); dns_db_attach(dbtable->default_db, dbp); RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_read); } void dns_dbtable_removedefault(dns_dbtable_t *dbtable) { REQUIRE(VALID_DBTABLE(dbtable)); RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write); dns_db_detach(&dbtable->default_db); RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write); } isc_result_t dns_dbtable_find(dns_dbtable_t *dbtable, dns_name_t *name, unsigned int options, dns_db_t **dbp) { dns_db_t *stored_data = NULL; isc_result_t result; unsigned int rbtoptions = 0; REQUIRE(dbp != NULL && *dbp == NULL); if ((options & DNS_DBTABLEFIND_NOEXACT) != 0) rbtoptions |= DNS_RBTFIND_NOEXACT; RWLOCK(&dbtable->tree_lock, isc_rwlocktype_read); result = dns_rbt_findname(dbtable->rbt, name, rbtoptions, NULL, (void **) (void *)&stored_data); if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) dns_db_attach(stored_data, dbp); else if (dbtable->default_db != NULL) { dns_db_attach(dbtable->default_db, dbp); result = DNS_R_PARTIALMATCH; } else result = ISC_R_NOTFOUND; RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_read); return (result); } bind9-9.10.3.dfsg.P4/lib/irs/0002755000470500017500000000000012672612753014746 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/irs/version.c0000644000470500017500000000205612664710322016570 0ustar lamontlamont/* * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: version.c,v 1.3 2009/09/02 23:48:02 tbox Exp $ */ /*! \file */ #include const char irs_version[] = VERSION; const unsigned int irs_libinterface = LIBINTERFACE; const unsigned int irs_librevision = LIBREVISION; const unsigned int irs_libage = LIBAGE; bind9-9.10.3.dfsg.P4/lib/irs/getaddrinfo.c0000644000470500017500000010455612664710322017401 0ustar lamontlamont/* * Copyright (C) 2009, 2012-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: getaddrinfo.c,v 1.3 2009/09/02 23:48:02 tbox Exp $ */ /*! \file */ /** * getaddrinfo() is used to get a list of IP addresses and port * numbers for host hostname and service servname as defined in RFC3493. * hostname and servname are pointers to null-terminated strings * or NULL. hostname is either a host name or a numeric host address * string: a dotted decimal IPv4 address or an IPv6 address. servname is * either a decimal port number or a service name as listed in * /etc/services. * * If the operating system does not provide a struct addrinfo, the * following structure is used: * * \code * struct addrinfo { * int ai_flags; // AI_PASSIVE, AI_CANONNAME * int ai_family; // PF_xxx * int ai_socktype; // SOCK_xxx * int ai_protocol; // 0 or IPPROTO_xxx for IPv4 and IPv6 * size_t ai_addrlen; // length of ai_addr * char *ai_canonname; // canonical name for hostname * struct sockaddr *ai_addr; // binary address * struct addrinfo *ai_next; // next structure in linked list * }; * \endcode * * * hints is an optional pointer to a struct addrinfo. This structure can * be used to provide hints concerning the type of socket that the caller * supports or wishes to use. The caller can supply the following * structure elements in *hints: * *
    *
  • ai_family: * The protocol family that should be used. When ai_family is set * to PF_UNSPEC, it means the caller will accept any protocol * family supported by the operating system.
  • * *
  • ai_socktype: * denotes the type of socket -- SOCK_STREAM, SOCK_DGRAM or * SOCK_RAW -- that is wanted. When ai_socktype is zero the caller * will accept any socket type.
  • * *
  • ai_protocol: * indicates which transport protocol is wanted: IPPROTO_UDP or * IPPROTO_TCP. If ai_protocol is zero the caller will accept any * protocol.
  • * *
  • ai_flags: * Flag bits. If the AI_CANONNAME bit is set, a successful call to * getaddrinfo() will return a null-terminated string * containing the canonical name of the specified hostname in * ai_canonname of the first addrinfo structure returned. Setting * the AI_PASSIVE bit indicates that the returned socket address * structure is intended for used in a call to bind(2). In this * case, if the hostname argument is a NULL pointer, then the IP * address portion of the socket address structure will be set to * INADDR_ANY for an IPv4 address or IN6ADDR_ANY_INIT for an IPv6 * address.

    * * When ai_flags does not set the AI_PASSIVE bit, the returned * socket address structure will be ready for use in a call to * connect(2) for a connection-oriented protocol or connect(2), * sendto(2), or sendmsg(2) if a connectionless protocol was * chosen. The IP address portion of the socket address structure * will be set to the loopback address if hostname is a NULL * pointer and AI_PASSIVE is not set in ai_flags.

    * * If ai_flags is set to AI_NUMERICHOST it indicates that hostname * should be treated as a numeric string defining an IPv4 or IPv6 * address and no name resolution should be attempted. *
* * All other elements of the struct addrinfo passed via hints must be * zero. * * A hints of NULL is treated as if the caller provided a struct addrinfo * initialized to zero with ai_familyset to PF_UNSPEC. * * After a successful call to getaddrinfo(), *res is a pointer to a * linked list of one or more addrinfo structures. Each struct addrinfo * in this list cn be processed by following the ai_next pointer, until a * NULL pointer is encountered. The three members ai_family, ai_socktype, * and ai_protocol in each returned addrinfo structure contain the * corresponding arguments for a call to socket(2). For each addrinfo * structure in the list, the ai_addr member points to a filled-in socket * address structure of length ai_addrlen. * * All of the information returned by getaddrinfo() is dynamically * allocated: the addrinfo structures, and the socket address structures * and canonical host name strings pointed to by the addrinfostructures. * Memory allocated for the dynamically allocated structures created by a * successful call to getaddrinfo() is released by freeaddrinfo(). * ai is a pointer to a struct addrinfo created by a call to getaddrinfo(). * * \section irsreturn RETURN VALUES * * getaddrinfo() returns zero on success or one of the error codes * listed in gai_strerror() if an error occurs. If both hostname and * servname are NULL getaddrinfo() returns #EAI_NONAME. * * \section irssee SEE ALSO * * getaddrinfo(), freeaddrinfo(), * gai_strerror(), RFC3493, getservbyname(3), connect(2), * sendto(2), sendmsg(2), socket(2). */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define SA(addr) ((struct sockaddr *)(addr)) #define SIN(addr) ((struct sockaddr_in *)(addr)) #define SIN6(addr) ((struct sockaddr_in6 *)(addr)) #define SLOCAL(addr) ((struct sockaddr_un *)(addr)) /*! \struct addrinfo */ static struct addrinfo *ai_concat(struct addrinfo *ai1, struct addrinfo *ai2), *ai_reverse(struct addrinfo *oai), *ai_clone(struct addrinfo *oai, int family), *ai_alloc(int family, int addrlen); #ifdef AF_LOCAL static int get_local(const char *name, int socktype, struct addrinfo **res); #endif static int resolve_name(int family, const char *hostname, int flags, struct addrinfo **aip, int socktype, int port); static int add_ipv4(const char *hostname, int flags, struct addrinfo **aip, int socktype, int port); static int add_ipv6(const char *hostname, int flags, struct addrinfo **aip, int socktype, int port); static void set_order(int, int (**)(const char *, int, struct addrinfo **, int, int)); static void _freeaddrinfo(struct addrinfo *ai); #define FOUND_IPV4 0x1 #define FOUND_IPV6 0x2 #define FOUND_MAX 2 #define ISC_AI_MASK (AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST) /*% * Get a list of IP addresses and port numbers for host hostname and * service servname. */ int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res) { struct servent *sp; const char *proto; int family, socktype, flags, protocol; struct addrinfo *ai, *ai_list; int err = 0; int port, i; int (*net_order[FOUND_MAX+1])(const char *, int, struct addrinfo **, int, int); if (hostname == NULL && servname == NULL) return (EAI_NONAME); proto = NULL; if (hints != NULL) { if ((hints->ai_flags & ~(ISC_AI_MASK)) != 0) return (EAI_BADFLAGS); if (hints->ai_addrlen || hints->ai_canonname || hints->ai_addr || hints->ai_next) { errno = EINVAL; return (EAI_SYSTEM); } family = hints->ai_family; socktype = hints->ai_socktype; protocol = hints->ai_protocol; flags = hints->ai_flags; switch (family) { case AF_UNSPEC: switch (hints->ai_socktype) { case SOCK_STREAM: proto = "tcp"; break; case SOCK_DGRAM: proto = "udp"; break; } break; case AF_INET: case AF_INET6: switch (hints->ai_socktype) { case 0: break; case SOCK_STREAM: proto = "tcp"; break; case SOCK_DGRAM: proto = "udp"; break; case SOCK_RAW: break; default: return (EAI_SOCKTYPE); } break; #ifdef AF_LOCAL case AF_LOCAL: switch (hints->ai_socktype) { case 0: break; case SOCK_STREAM: break; case SOCK_DGRAM: break; default: return (EAI_SOCKTYPE); } break; #endif default: return (EAI_FAMILY); } } else { protocol = 0; family = 0; socktype = 0; flags = 0; } #ifdef AF_LOCAL /*! * First, deal with AF_LOCAL. If the family was not set, * then assume AF_LOCAL if the first character of the * hostname/servname is '/'. */ if (hostname != NULL && (family == AF_LOCAL || (family == 0 && *hostname == '/'))) return (get_local(hostname, socktype, res)); if (servname != NULL && (family == AF_LOCAL || (family == 0 && *servname == '/'))) return (get_local(servname, socktype, res)); #endif /* * Ok, only AF_INET and AF_INET6 left. */ ai_list = NULL; /* * First, look up the service name (port) if it was * requested. If the socket type wasn't specified, then * try and figure it out. */ if (servname != NULL) { char *e; port = strtol(servname, &e, 10); if (*e == '\0') { if (socktype == 0) return (EAI_SOCKTYPE); if (port < 0 || port > 65535) return (EAI_SERVICE); port = htons((unsigned short) port); } else { sp = getservbyname(servname, proto); if (sp == NULL) return (EAI_SERVICE); port = sp->s_port; if (socktype == 0) { if (strcmp(sp->s_proto, "tcp") == 0) socktype = SOCK_STREAM; else if (strcmp(sp->s_proto, "udp") == 0) socktype = SOCK_DGRAM; } } } else port = 0; /* * Next, deal with just a service name, and no hostname. * (we verified that one of them was non-null up above). */ if (hostname == NULL && (flags & AI_PASSIVE) != 0) { if (family == AF_INET || family == 0) { ai = ai_alloc(AF_INET, sizeof(struct sockaddr_in)); if (ai == NULL) return (EAI_MEMORY); ai->ai_socktype = socktype; ai->ai_protocol = protocol; SIN(ai->ai_addr)->sin_port = port; ai->ai_next = ai_list; ai_list = ai; } if (family == AF_INET6 || family == 0) { ai = ai_alloc(AF_INET6, sizeof(struct sockaddr_in6)); if (ai == NULL) { _freeaddrinfo(ai_list); return (EAI_MEMORY); } ai->ai_socktype = socktype; ai->ai_protocol = protocol; SIN6(ai->ai_addr)->sin6_port = port; ai->ai_next = ai_list; ai_list = ai; } *res = ai_list; return (0); } /* * If the family isn't specified or AI_NUMERICHOST specified, check * first to see if it is a numeric address. * Though the gethostbyname2() routine will recognize numeric addresses, * it will only recognize the format that it is being called for. Thus, * a numeric AF_INET address will be treated by the AF_INET6 call as * a domain name, and vice versa. Checking for both numerics here * avoids that. */ if (hostname != NULL && (family == 0 || (flags & AI_NUMERICHOST) != 0)) { char abuf[sizeof(struct in6_addr)]; char nbuf[NI_MAXHOST]; int addrsize, addroff; #ifdef IRS_HAVE_SIN6_SCOPE_ID char *p, *ep; char ntmp[NI_MAXHOST]; isc_uint32_t scopeid; #endif #ifdef IRS_HAVE_SIN6_SCOPE_ID /* * Scope identifier portion. */ ntmp[0] = '\0'; if (strchr(hostname, '%') != NULL) { strncpy(ntmp, hostname, sizeof(ntmp) - 1); ntmp[sizeof(ntmp) - 1] = '\0'; p = strchr(ntmp, '%'); ep = NULL; /* * Vendors may want to support non-numeric * scopeid around here. */ if (p != NULL) scopeid = (isc_uint32_t)strtoul(p + 1, &ep, 10); if (p != NULL && ep != NULL && ep[0] == '\0') *p = '\0'; else { ntmp[0] = '\0'; scopeid = 0; } } else scopeid = 0; #endif if (inet_pton(AF_INET, hostname, (struct in_addr *)abuf) == 1) { if (family == AF_INET6) { /* * Convert to a V4 mapped address. */ struct in6_addr *a6 = (struct in6_addr *)abuf; memmove(&a6->s6_addr[12], &a6->s6_addr[0], 4); memset(&a6->s6_addr[10], 0xff, 2); memset(&a6->s6_addr[0], 0, 10); goto inet6_addr; } addrsize = sizeof(struct in_addr); addroff = (char *)(&SIN(0)->sin_addr) - (char *)0; family = AF_INET; goto common; #ifdef IRS_HAVE_SIN6_SCOPE_ID } else if (ntmp[0] != '\0' && inet_pton(AF_INET6, ntmp, abuf) == 1) { if (family && family != AF_INET6) return (EAI_NONAME); addrsize = sizeof(struct in6_addr); addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0; family = AF_INET6; goto common; #endif } else if (inet_pton(AF_INET6, hostname, abuf) == 1) { if (family != 0 && family != AF_INET6) return (EAI_NONAME); inet6_addr: addrsize = sizeof(struct in6_addr); addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0; family = AF_INET6; common: ai = ai_alloc(family, ((family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))); if (ai == NULL) return (EAI_MEMORY); ai_list = ai; ai->ai_socktype = socktype; SIN(ai->ai_addr)->sin_port = port; memmove((char *)ai->ai_addr + addroff, abuf, addrsize); if ((flags & AI_CANONNAME) != 0) { #ifdef IRS_HAVE_SIN6_SCOPE_ID if (ai->ai_family == AF_INET6) SIN6(ai->ai_addr)->sin6_scope_id = scopeid; #endif if (getnameinfo(ai->ai_addr, (socklen_t)ai->ai_addrlen, nbuf, sizeof(nbuf), NULL, 0, NI_NUMERICHOST) == 0) { ai->ai_canonname = strdup(nbuf); if (ai->ai_canonname == NULL) { _freeaddrinfo(ai); return (EAI_MEMORY); } } else { /* XXX raise error? */ ai->ai_canonname = NULL; } } goto done; } else if ((flags & AI_NUMERICHOST) != 0) { return (EAI_NONAME); } } if (hostname == NULL && (flags & AI_PASSIVE) == 0) { set_order(family, net_order); for (i = 0; i < FOUND_MAX; i++) { if (net_order[i] == NULL) break; err = (net_order[i])(hostname, flags, &ai_list, socktype, port); if (err != 0) { if (ai_list != NULL) { _freeaddrinfo(ai_list); ai_list = NULL; } break; } } } else err = resolve_name(family, hostname, flags, &ai_list, socktype, port); if (ai_list == NULL) { if (err == 0) err = EAI_NONAME; return (err); } done: ai_list = ai_reverse(ai_list); *res = ai_list; return (0); } typedef struct gai_restrans { dns_clientrestrans_t *xid; isc_boolean_t is_inprogress; int error; struct addrinfo ai_sentinel; struct gai_resstate *resstate; } gai_restrans_t; typedef struct gai_resstate { isc_mem_t *mctx; struct gai_statehead *head; dns_fixedname_t fixedname; dns_name_t *qname; gai_restrans_t *trans4; gai_restrans_t *trans6; ISC_LINK(struct gai_resstate) link; } gai_resstate_t; typedef struct gai_statehead { int ai_family; int ai_flags; int ai_socktype; int ai_port; isc_appctx_t *actx; dns_client_t *dnsclient; isc_mutex_t list_lock; ISC_LIST(struct gai_resstate) resstates; unsigned int activestates; } gai_statehead_t; static isc_result_t make_resstate(isc_mem_t *mctx, gai_statehead_t *head, const char *hostname, const char *domain, gai_resstate_t **statep) { isc_result_t result; gai_resstate_t *state; dns_fixedname_t fixeddomain; dns_name_t *qdomain; unsigned int namelen; isc_buffer_t b; isc_boolean_t need_v4 = ISC_FALSE; isc_boolean_t need_v6 = ISC_FALSE; state = isc_mem_get(mctx, sizeof(*state)); if (state == NULL) return (ISC_R_NOMEMORY); /* Construct base domain name */ namelen = strlen(domain); isc_buffer_constinit(&b, domain, namelen); isc_buffer_add(&b, namelen); dns_fixedname_init(&fixeddomain); qdomain = dns_fixedname_name(&fixeddomain); result = dns_name_fromtext(qdomain, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, state, sizeof(*state)); return (result); } /* Construct query name */ namelen = strlen(hostname); isc_buffer_constinit(&b, hostname, namelen); isc_buffer_add(&b, namelen); dns_fixedname_init(&state->fixedname); state->qname = dns_fixedname_name(&state->fixedname); result = dns_name_fromtext(state->qname, &b, qdomain, 0, NULL); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, state, sizeof(*state)); return (result); } if (head->ai_family == AF_UNSPEC || head->ai_family == AF_INET) need_v4 = ISC_TRUE; if (head->ai_family == AF_UNSPEC || head->ai_family == AF_INET6) need_v6 = ISC_TRUE; state->trans6 = NULL; state->trans4 = NULL; if (need_v4) { state->trans4 = isc_mem_get(mctx, sizeof(gai_restrans_t)); if (state->trans4 == NULL) { isc_mem_put(mctx, state, sizeof(*state)); return (ISC_R_NOMEMORY); } state->trans4->error = 0; state->trans4->xid = NULL; state->trans4->resstate = state; state->trans4->is_inprogress = ISC_TRUE; state->trans4->ai_sentinel.ai_next = NULL; } if (need_v6) { state->trans6 = isc_mem_get(mctx, sizeof(gai_restrans_t)); if (state->trans6 == NULL) { if (state->trans4 != NULL) isc_mem_put(mctx, state->trans4, sizeof(*state->trans4)); isc_mem_put(mctx, state, sizeof(*state)); return (ISC_R_NOMEMORY); } state->trans6->error = 0; state->trans6->xid = NULL; state->trans6->resstate = state; state->trans6->is_inprogress = ISC_TRUE; state->trans6->ai_sentinel.ai_next = NULL; } state->mctx = mctx; state->head = head; ISC_LINK_INIT(state, link); *statep = state; return (ISC_R_SUCCESS); } static isc_result_t make_resstates(isc_mem_t *mctx, const char *hostname, gai_statehead_t *head, irs_resconf_t *resconf) { isc_result_t result; irs_resconf_searchlist_t *searchlist; irs_resconf_search_t *searchent; gai_resstate_t *resstate, *resstate0; resstate0 = NULL; result = make_resstate(mctx, head, hostname, ".", &resstate0); if (result != ISC_R_SUCCESS) return (result); searchlist = irs_resconf_getsearchlist(resconf); for (searchent = ISC_LIST_HEAD(*searchlist); searchent != NULL; searchent = ISC_LIST_NEXT(searchent, link)) { resstate = NULL; result = make_resstate(mctx, head, hostname, (const char *)searchent->domain, &resstate); if (result != ISC_R_SUCCESS) break; ISC_LIST_APPEND(head->resstates, resstate, link); head->activestates++; } /* * Insert the original hostname either at the head or the tail of the * state list, depending on the number of labels contained in the * original name and the 'ndots' configuration parameter. */ if (dns_name_countlabels(resstate0->qname) > irs_resconf_getndots(resconf) + 1) { ISC_LIST_PREPEND(head->resstates, resstate0, link); } else ISC_LIST_APPEND(head->resstates, resstate0, link); head->activestates++; if (result != ISC_R_SUCCESS) { while ((resstate = ISC_LIST_HEAD(head->resstates)) != NULL) { ISC_LIST_UNLINK(head->resstates, resstate, link); if (resstate->trans4 != NULL) { isc_mem_put(mctx, resstate->trans4, sizeof(*resstate->trans4)); } if (resstate->trans6 != NULL) { isc_mem_put(mctx, resstate->trans6, sizeof(*resstate->trans6)); } isc_mem_put(mctx, resstate, sizeof(*resstate)); } } return (result); } static void process_answer(isc_task_t *task, isc_event_t *event) { int error = 0, family; gai_restrans_t *trans = event->ev_arg; gai_resstate_t *resstate; dns_clientresevent_t *rev = (dns_clientresevent_t *)event; dns_rdatatype_t qtype; dns_name_t *name; REQUIRE(trans != NULL); resstate = trans->resstate; REQUIRE(resstate != NULL); REQUIRE(task != NULL); if (trans == resstate->trans4) { family = AF_INET; qtype = dns_rdatatype_a; } else { INSIST(trans == resstate->trans6); family = AF_INET6; qtype = dns_rdatatype_aaaa; } INSIST(trans->is_inprogress); trans->is_inprogress = ISC_FALSE; switch (rev->result) { case ISC_R_SUCCESS: case DNS_R_NCACHENXDOMAIN: /* treat this as a fatal error? */ case DNS_R_NCACHENXRRSET: break; default: switch (rev->vresult) { case DNS_R_SIGINVALID: case DNS_R_SIGEXPIRED: case DNS_R_SIGFUTURE: case DNS_R_KEYUNAUTHORIZED: case DNS_R_MUSTBESECURE: case DNS_R_COVERINGNSEC: case DNS_R_NOTAUTHORITATIVE: case DNS_R_NOVALIDKEY: case DNS_R_NOVALIDDS: case DNS_R_NOVALIDSIG: error = EAI_INSECUREDATA; break; default: error = EAI_FAIL; } goto done; } /* Parse the response and construct the addrinfo chain */ for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL; name = ISC_LIST_NEXT(name, link)) { isc_result_t result; dns_rdataset_t *rdataset; isc_buffer_t b; isc_region_t r; char t[1024]; for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (!dns_rdataset_isassociated(rdataset)) continue; if (rdataset->type != qtype) continue; if ((resstate->head->ai_flags & AI_CANONNAME) != 0) { isc_buffer_init(&b, t, sizeof(t)); result = dns_name_totext(name, ISC_TRUE, &b); if (result != ISC_R_SUCCESS) { error = EAI_FAIL; goto done; } isc_buffer_putuint8(&b, '\0'); isc_buffer_usedregion(&b, &r); } for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { struct addrinfo *ai; dns_rdata_t rdata; dns_rdata_in_a_t rdata_a; dns_rdata_in_aaaa_t rdata_aaaa; ai = ai_alloc(family, ((family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))); if (ai == NULL) { error = EAI_MEMORY; goto done; } ai->ai_socktype = resstate->head->ai_socktype; ai->ai_next = trans->ai_sentinel.ai_next; trans->ai_sentinel.ai_next = ai; /* * Set AF-specific parameters * (IPv4/v6 address/port) */ dns_rdata_init(&rdata); switch (family) { case AF_INET: dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &rdata_a, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); SIN(ai->ai_addr)->sin_port = resstate->head->ai_port; memmove(&SIN(ai->ai_addr)->sin_addr, &rdata_a.in_addr, 4); dns_rdata_freestruct(&rdata_a); break; case AF_INET6: dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &rdata_aaaa, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); SIN6(ai->ai_addr)->sin6_port = resstate->head->ai_port; memmove(&SIN6(ai->ai_addr)->sin6_addr, &rdata_aaaa.in6_addr, 16); dns_rdata_freestruct(&rdata_aaaa); break; } if ((resstate->head->ai_flags & AI_CANONNAME) != 0) { ai->ai_canonname = strdup((const char *)r.base); if (ai->ai_canonname == NULL) { error = EAI_MEMORY; goto done; } } } } } done: dns_client_freeresanswer(resstate->head->dnsclient, &rev->answerlist); dns_client_destroyrestrans(&trans->xid); isc_event_free(&event); /* Make sure that error == 0 iff we have a non-empty list */ if (error == 0) { if (trans->ai_sentinel.ai_next == NULL) error = EAI_NONAME; } else { if (trans->ai_sentinel.ai_next != NULL) { _freeaddrinfo(trans->ai_sentinel.ai_next); trans->ai_sentinel.ai_next = NULL; } } trans->error = error; /* Check whether we are done */ if ((resstate->trans4 == NULL || !resstate->trans4->is_inprogress) && (resstate->trans6 == NULL || !resstate->trans6->is_inprogress)) { /* * We're done for this state. If there is no other outstanding * state, we can exit. */ resstate->head->activestates--; if (resstate->head->activestates == 0) { isc_app_ctxsuspend(resstate->head->actx); return; } /* * There are outstanding states, but if we are at the head * of the state list (i.e., at the highest search priority) * and have any answer, we can stop now by canceling the * others. */ LOCK(&resstate->head->list_lock); if (resstate == ISC_LIST_HEAD(resstate->head->resstates)) { if ((resstate->trans4 != NULL && resstate->trans4->ai_sentinel.ai_next != NULL) || (resstate->trans6 != NULL && resstate->trans6->ai_sentinel.ai_next != NULL)) { gai_resstate_t *rest; for (rest = ISC_LIST_NEXT(resstate, link); rest != NULL; rest = ISC_LIST_NEXT(rest, link)) { if (rest->trans4 != NULL && rest->trans4->xid != NULL) dns_client_cancelresolve( rest->trans4->xid); if (rest->trans6 != NULL && rest->trans6->xid != NULL) dns_client_cancelresolve( rest->trans6->xid); } } else { /* * This search fails, so we move to the tail * of the list so that the next entry will * have the highest priority. */ ISC_LIST_UNLINK(resstate->head->resstates, resstate, link); ISC_LIST_APPEND(resstate->head->resstates, resstate, link); } } UNLOCK(&resstate->head->list_lock); } } static int resolve_name(int family, const char *hostname, int flags, struct addrinfo **aip, int socktype, int port) { isc_result_t result; irs_context_t *irsctx; irs_resconf_t *conf; isc_mem_t *mctx; isc_appctx_t *actx; isc_task_t *task; int terror = 0; int error = 0; dns_client_t *client; gai_resstate_t *resstate; gai_statehead_t head; isc_boolean_t all_fail = ISC_TRUE; /* get IRS context and the associated parameters */ irsctx = NULL; result = irs_context_get(&irsctx); if (result != ISC_R_SUCCESS) return (EAI_FAIL); actx = irs_context_getappctx(irsctx); mctx = irs_context_getmctx(irsctx); task = irs_context_gettask(irsctx); conf = irs_context_getresconf(irsctx); client = irs_context_getdnsclient(irsctx); /* construct resolution states */ head.activestates = 0; head.ai_family = family; head.ai_socktype = socktype; head.ai_flags = flags; head.ai_port = port; head.actx = actx; head.dnsclient = client; result = isc_mutex_init(&head.list_lock); if (result != ISC_R_SUCCESS) { return (EAI_FAIL); } ISC_LIST_INIT(head.resstates); result = make_resstates(mctx, hostname, &head, conf); if (result != ISC_R_SUCCESS) { DESTROYLOCK(&head.list_lock); return (EAI_FAIL); } LOCK(&head.list_lock); for (resstate = ISC_LIST_HEAD(head.resstates); resstate != NULL; resstate = ISC_LIST_NEXT(resstate, link)) { if (resstate->trans4 != NULL) { result = dns_client_startresolve(client, resstate->qname, dns_rdataclass_in, dns_rdatatype_a, 0, task, process_answer, resstate->trans4, &resstate->trans4->xid); if (result == ISC_R_SUCCESS) { resstate->trans4->is_inprogress = ISC_TRUE; all_fail = ISC_FALSE; } else resstate->trans4->is_inprogress = ISC_FALSE; } if (resstate->trans6 != NULL) { result = dns_client_startresolve(client, resstate->qname, dns_rdataclass_in, dns_rdatatype_aaaa, 0, task, process_answer, resstate->trans6, &resstate->trans6->xid); if (result == ISC_R_SUCCESS) { resstate->trans6->is_inprogress = ISC_TRUE; all_fail = ISC_FALSE; } else resstate->trans6->is_inprogress= ISC_FALSE; } } UNLOCK(&head.list_lock); if (!all_fail) { /* Start all the events */ isc_app_ctxrun(actx); } else error = EAI_FAIL; /* Cleanup */ while ((resstate = ISC_LIST_HEAD(head.resstates)) != NULL) { int terror4 = 0, terror6 = 0; ISC_LIST_UNLINK(head.resstates, resstate, link); if (*aip == NULL) { struct addrinfo *sentinel4 = NULL; struct addrinfo *sentinel6 = NULL; if (resstate->trans4 != NULL) { sentinel4 = resstate->trans4->ai_sentinel.ai_next; resstate->trans4->ai_sentinel.ai_next = NULL; } if (resstate->trans6 != NULL) { sentinel6 = resstate->trans6->ai_sentinel.ai_next; resstate->trans6->ai_sentinel.ai_next = NULL; } *aip = ai_concat(sentinel4, sentinel6); } if (resstate->trans4 != NULL) { INSIST(resstate->trans4->xid == NULL); terror4 = resstate->trans4->error; isc_mem_put(mctx, resstate->trans4, sizeof(*resstate->trans4)); } if (resstate->trans6 != NULL) { INSIST(resstate->trans6->xid == NULL); terror6 = resstate->trans6->error; isc_mem_put(mctx, resstate->trans6, sizeof(*resstate->trans6)); } /* * If the entire lookup fails, we need to choose an appropriate * error code from individual codes. We'll try to provide as * specific a code as possible. In general, we are going to * find an error code other than EAI_NONAME (which is too * generic and may actually not be problematic in some cases). * EAI_NONAME will be set below if no better code is found. */ if (terror == 0 || terror == EAI_NONAME) { if (terror4 != 0 && terror4 != EAI_NONAME) terror = terror4; else if (terror6 != 0 && terror6 != EAI_NONAME) terror = terror6; } isc_mem_put(mctx, resstate, sizeof(*resstate)); } if (*aip == NULL) { error = terror; if (error == 0) error = EAI_NONAME; } #if 1 /* XXX: enabled for finding leaks. should be cleaned up later. */ isc_app_ctxfinish(actx); irs_context_destroy(&irsctx); #endif DESTROYLOCK(&head.list_lock); return (error); } static char * irs_strsep(char **stringp, const char *delim) { char *string = *stringp; char *s; const char *d; char sc, dc; if (string == NULL) return (NULL); for (s = string; *s != '\0'; s++) { sc = *s; for (d = delim; (dc = *d) != '\0'; d++) if (sc == dc) { *s++ = '\0'; *stringp = s; return (string); } } *stringp = NULL; return (string); } static void set_order(int family, int (**net_order)(const char *, int, struct addrinfo **, int, int)) { char *order, *tok; int found; if (family) { switch (family) { case AF_INET: *net_order++ = add_ipv4; break; case AF_INET6: *net_order++ = add_ipv6; break; } } else { order = getenv("NET_ORDER"); found = 0; while (order != NULL) { /* * We ignore any unknown names. */ tok = irs_strsep(&order, ":"); if (strcasecmp(tok, "inet6") == 0) { if ((found & FOUND_IPV6) == 0) *net_order++ = add_ipv6; found |= FOUND_IPV6; } else if (strcasecmp(tok, "inet") == 0 || strcasecmp(tok, "inet4") == 0) { if ((found & FOUND_IPV4) == 0) *net_order++ = add_ipv4; found |= FOUND_IPV4; } } /* * Add in anything that we didn't find. */ if ((found & FOUND_IPV4) == 0) *net_order++ = add_ipv4; if ((found & FOUND_IPV6) == 0) *net_order++ = add_ipv6; } *net_order = NULL; return; } static char v4_loop[4] = { 127, 0, 0, 1 }; static int add_ipv4(const char *hostname, int flags, struct addrinfo **aip, int socktype, int port) { struct addrinfo *ai; UNUSED(hostname); UNUSED(flags); ai = ai_clone(*aip, AF_INET); /* don't use ai_clone() */ if (ai == NULL) return (EAI_MEMORY); *aip = ai; ai->ai_socktype = socktype; SIN(ai->ai_addr)->sin_port = port; memmove(&SIN(ai->ai_addr)->sin_addr, v4_loop, 4); return (0); } static char v6_loop[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; static int add_ipv6(const char *hostname, int flags, struct addrinfo **aip, int socktype, int port) { struct addrinfo *ai; UNUSED(hostname); UNUSED(flags); ai = ai_clone(*aip, AF_INET6); /* don't use ai_clone() */ if (ai == NULL) return (EAI_MEMORY); *aip = ai; ai->ai_socktype = socktype; SIN6(ai->ai_addr)->sin6_port = port; memmove(&SIN6(ai->ai_addr)->sin6_addr, v6_loop, 16); return (0); } /*% Free address info. */ void freeaddrinfo(struct addrinfo *ai) { _freeaddrinfo(ai); } static void _freeaddrinfo(struct addrinfo *ai) { struct addrinfo *ai_next; while (ai != NULL) { ai_next = ai->ai_next; if (ai->ai_addr != NULL) free(ai->ai_addr); if (ai->ai_canonname) free(ai->ai_canonname); free(ai); ai = ai_next; } } #ifdef AF_LOCAL static int get_local(const char *name, int socktype, struct addrinfo **res) { struct addrinfo *ai; struct sockaddr_un *slocal; if (socktype == 0) return (EAI_SOCKTYPE); ai = ai_alloc(AF_LOCAL, sizeof(*slocal)); if (ai == NULL) return (EAI_MEMORY); slocal = SLOCAL(ai->ai_addr); strlcpy(slocal->sun_path, name, sizeof(slocal->sun_path)); ai->ai_socktype = socktype; /* * ai->ai_flags, ai->ai_protocol, ai->ai_canonname, * and ai->ai_next were initialized to zero. */ *res = ai; return (0); } #endif /*! * Allocate an addrinfo structure, and a sockaddr structure * of the specificed length. We initialize: * ai_addrlen * ai_family * ai_addr * ai_addr->sa_family * ai_addr->sa_len (IRS_PLATFORM_HAVESALEN) * and everything else is initialized to zero. */ static struct addrinfo * ai_alloc(int family, int addrlen) { struct addrinfo *ai; ai = (struct addrinfo *)calloc(1, sizeof(*ai)); if (ai == NULL) return (NULL); ai->ai_addr = SA(calloc(1, addrlen)); if (ai->ai_addr == NULL) { free(ai); return (NULL); } ai->ai_addrlen = addrlen; ai->ai_family = family; ai->ai_addr->sa_family = family; #ifdef IRS_PLATFORM_HAVESALEN ai->ai_addr->sa_len = addrlen; #endif return (ai); } static struct addrinfo * ai_clone(struct addrinfo *oai, int family) { struct addrinfo *ai; ai = ai_alloc(family, ((family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))); if (ai == NULL) return (NULL); if (oai == NULL) return (ai); ai->ai_flags = oai->ai_flags; ai->ai_socktype = oai->ai_socktype; ai->ai_protocol = oai->ai_protocol; ai->ai_canonname = NULL; ai->ai_next = oai; return (ai); } static struct addrinfo * ai_reverse(struct addrinfo *oai) { struct addrinfo *nai, *tai; nai = NULL; while (oai != NULL) { /* * Grab one off the old list. */ tai = oai; oai = oai->ai_next; /* * Put it on the front of the new list. */ tai->ai_next = nai; nai = tai; } return (nai); } static struct addrinfo * ai_concat(struct addrinfo *ai1, struct addrinfo *ai2) { struct addrinfo *ai_tmp; if (ai1 == NULL) return (ai2); else if (ai2 == NULL) return (ai1); for (ai_tmp = ai1; ai_tmp != NULL && ai_tmp->ai_next != NULL; ai_tmp = ai_tmp->ai_next) ; ai_tmp->ai_next = ai2; return (ai1); } bind9-9.10.3.dfsg.P4/lib/irs/Makefile.in0000644000470500017500000000421212664710322017000 0ustar lamontlamont# Copyright (C) 2009, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.3 2009/09/02 23:48:02 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ @LIBIRS_API@ @BIND9_MAKE_INCLUDES@ CINCLUDES = -I. -I./include -I${srcdir}/include \ ${DNS_INCLUDES} ${ISC_INCLUDES} ${ISCCFG_INCLUDES} CDEFINES = CWARNINGS = # Alphabetically OBJS = context.@O@ \ dnsconf.@O@ \ gai_strerror.@O@ getaddrinfo.@O@ getnameinfo.@O@ \ resconf.@O@ # Alphabetically SRCS = context.c \ dnsconf.c \ gai_strerror.c getaddrinfo.c getnameinfo.c \ resconf.c LIBS = @LIBS@ SUBDIRS = include TARGETS = timestamp @BIND9_MAKE_RULES@ version.@O@: version.c ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ -DVERSION=\"${VERSION}\" \ -DLIBINTERFACE=${LIBINTERFACE} \ -DLIBREVISION=${LIBREVISION} \ -DLIBAGE=${LIBAGE} \ -c ${srcdir}/version.c libirs.@SA@: ${OBJS} version.@O@ ${AR} ${ARFLAGS} $@ ${OBJS} version.@O@ ${RANLIB} $@ libirs.la: ${OBJS} version.@O@ ${LIBTOOL_MODE_LINK} \ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libirs.la -rpath ${libdir} \ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \ ${OBJS} version.@O@ ${LIBS} timestamp: libirs.@A@ touch timestamp installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${libdir} install:: timestamp installdirs ${LIBTOOL_MODE_INSTALL} ${INSTALL_LIBRARY} libirs.@A@ ${DESTDIR}${libdir} clean distclean:: rm -f libirs.@A@ libirs.la timestamp bind9-9.10.3.dfsg.P4/lib/irs/gai_strerror.c0000644000470500017500000000661412664710322017611 0ustar lamontlamont/* * Copyright (C) 2009, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: gai_strerror.c,v 1.5 2009/09/02 23:48:02 tbox Exp $ */ /*! \file gai_strerror.c * gai_strerror() returns an error message corresponding to an * error code returned by getaddrinfo() and getnameinfo(). The following error * codes and their meaning are defined in * \link netdb.h include/irs/netdb.h.\endlink * This implementation is almost an exact copy of lwres/gai_sterror.c except * that it catches up the latest API standard, RFC3493. * * \li #EAI_ADDRFAMILY address family for hostname not supported * \li #EAI_AGAIN temporary failure in name resolution * \li #EAI_BADFLAGS invalid value for ai_flags * \li #EAI_FAIL non-recoverable failure in name resolution * \li #EAI_FAMILY ai_family not supported * \li #EAI_MEMORY memory allocation failure * \li #EAI_NODATA no address associated with hostname (obsoleted in RFC3493) * \li #EAI_NONAME hostname nor servname provided, or not known * \li #EAI_SERVICE servname not supported for ai_socktype * \li #EAI_SOCKTYPE ai_socktype not supported * \li #EAI_SYSTEM system error returned in errno * \li #EAI_BADHINTS Invalid value for hints (non-standard) * \li #EAI_PROTOCOL Resolved protocol is unknown (non-standard) * \li #EAI_OVERFLOW Argument buffer overflow * \li #EAI_INSECUREDATA Insecure Data (experimental) * * The message invalid error code is returned if ecode is out of range. * * ai_flags, ai_family and ai_socktype are elements of the struct * addrinfo used by lwres_getaddrinfo(). * * \section gai_strerror_see See Also * * strerror(), getaddrinfo(), getnameinfo(), RFC3493. */ #include #include #include /*% Text of error messages. */ static const char *gai_messages[] = { "no error", "address family for hostname not supported", "temporary failure in name resolution", "invalid value for ai_flags", "non-recoverable failure in name resolution", "ai_family not supported", "memory allocation failure", "no address associated with hostname", "hostname nor servname provided, or not known", "servname not supported for ai_socktype", "ai_socktype not supported", "system error returned in errno", "bad hints", "bad protocol", "argument buffer overflow", "insecure data provided" }; /*% * Returns an error message corresponding to an error code returned by * getaddrinfo() and getnameinfo() */ IRS_GAISTRERROR_RETURN_T gai_strerror(int ecode) { union { const char *const_ptr; char *deconst_ptr; } ptr; if ((ecode < 0) || (ecode >= (int)(sizeof(gai_messages)/sizeof(*gai_messages)))) ptr.const_ptr = "invalid error code"; else ptr.const_ptr = gai_messages[ecode]; return (ptr.deconst_ptr); } bind9-9.10.3.dfsg.P4/lib/irs/dnsconf.c0000644000470500017500000001575212664710322016544 0ustar lamontlamont/* * Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: dnsconf.c,v 1.3 2009/09/02 23:48:02 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define IRS_DNSCONF_MAGIC ISC_MAGIC('D', 'c', 'f', 'g') #define IRS_DNSCONF_VALID(c) ISC_MAGIC_VALID(c, IRS_DNSCONF_MAGIC) /*! * configuration data structure */ struct irs_dnsconf { unsigned int magic; isc_mem_t *mctx; irs_dnsconf_dnskeylist_t trusted_keylist; }; static isc_result_t configure_dnsseckeys(irs_dnsconf_t *conf, cfg_obj_t *cfgobj, dns_rdataclass_t rdclass) { isc_mem_t *mctx = conf->mctx; const cfg_obj_t *keys = NULL; const cfg_obj_t *key, *keylist; dns_fixedname_t fkeyname; dns_name_t *keyname_base, *keyname; const cfg_listelt_t *element, *element2; isc_result_t result; isc_uint32_t flags, proto, alg; const char *keystr, *keynamestr; unsigned char keydata[4096]; isc_buffer_t keydatabuf_base, *keydatabuf; dns_rdata_dnskey_t keystruct; unsigned char rrdata[4096]; isc_buffer_t rrdatabuf; isc_region_t r; isc_buffer_t namebuf; irs_dnsconf_dnskey_t *keyent; cfg_map_get(cfgobj, "trusted-keys", &keys); if (keys == NULL) return (ISC_R_SUCCESS); for (element = cfg_list_first(keys); element != NULL; element = cfg_list_next(element)) { keylist = cfg_listelt_value(element); for (element2 = cfg_list_first(keylist); element2 != NULL; element2 = cfg_list_next(element2)) { keydatabuf = NULL; keyname = NULL; key = cfg_listelt_value(element2); flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags")); proto = cfg_obj_asuint32(cfg_tuple_get(key, "protocol")); alg = cfg_obj_asuint32(cfg_tuple_get(key, "algorithm")); keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name")); keystruct.common.rdclass = rdclass; keystruct.common.rdtype = dns_rdatatype_dnskey; keystruct.mctx = NULL; ISC_LINK_INIT(&keystruct.common, link); if (flags > 0xffff) return (ISC_R_RANGE); if (proto > 0xff) return (ISC_R_RANGE); if (alg > 0xff) return (ISC_R_RANGE); keystruct.flags = (isc_uint16_t)flags; keystruct.protocol = (isc_uint8_t)proto; keystruct.algorithm = (isc_uint8_t)alg; isc_buffer_init(&keydatabuf_base, keydata, sizeof(keydata)); isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata)); /* Configure key value */ keystr = cfg_obj_asstring(cfg_tuple_get(key, "key")); result = isc_base64_decodestring(keystr, &keydatabuf_base); if (result != ISC_R_SUCCESS) return (result); isc_buffer_usedregion(&keydatabuf_base, &r); keystruct.datalen = r.length; keystruct.data = r.base; result = dns_rdata_fromstruct(NULL, keystruct.common.rdclass, keystruct.common.rdtype, &keystruct, &rrdatabuf); if (result != ISC_R_SUCCESS) return (result); isc_buffer_usedregion(&rrdatabuf, &r); result = isc_buffer_allocate(mctx, &keydatabuf, r.length); if (result != ISC_R_SUCCESS) return (result); result = isc_buffer_copyregion(keydatabuf, &r); if (result != ISC_R_SUCCESS) goto cleanup; /* Configure key name */ dns_fixedname_init(&fkeyname); keyname_base = dns_fixedname_name(&fkeyname); isc_buffer_constinit(&namebuf, keynamestr, strlen(keynamestr)); isc_buffer_add(&namebuf, strlen(keynamestr)); result = dns_name_fromtext(keyname_base, &namebuf, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) return (result); keyname = isc_mem_get(mctx, sizeof(*keyname)); if (keyname == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } dns_name_init(keyname, NULL); result = dns_name_dup(keyname_base, mctx, keyname); if (result != ISC_R_SUCCESS) goto cleanup; /* Add the key data to the list */ keyent = isc_mem_get(mctx, sizeof(*keyent)); if (keyent == NULL) { dns_name_free(keyname, mctx); result = ISC_R_NOMEMORY; goto cleanup; } keyent->keyname = keyname; keyent->keydatabuf = keydatabuf; ISC_LIST_APPEND(conf->trusted_keylist, keyent, link); } } return (ISC_R_SUCCESS); cleanup: if (keydatabuf != NULL) isc_buffer_free(&keydatabuf); if (keyname != NULL) isc_mem_put(mctx, keyname, sizeof(*keyname)); return (result); } isc_result_t irs_dnsconf_load(isc_mem_t *mctx, const char *filename, irs_dnsconf_t **confp) { irs_dnsconf_t *conf; cfg_parser_t *parser = NULL; cfg_obj_t *cfgobj = NULL; isc_result_t result = ISC_R_SUCCESS; REQUIRE(confp != NULL && *confp == NULL); conf = isc_mem_get(mctx, sizeof(*conf)); if (conf == NULL) return (ISC_R_NOMEMORY); conf->mctx = mctx; ISC_LIST_INIT(conf->trusted_keylist); /* * If the specified file does not exist, we'll simply with an empty * configuration. */ if (!isc_file_exists(filename)) goto cleanup; result = cfg_parser_create(mctx, NULL, &parser); if (result != ISC_R_SUCCESS) goto cleanup; result = cfg_parse_file(parser, filename, &cfg_type_dnsconf, &cfgobj); if (result != ISC_R_SUCCESS) goto cleanup; result = configure_dnsseckeys(conf, cfgobj, dns_rdataclass_in); cleanup: if (parser != NULL) { if (cfgobj != NULL) cfg_obj_destroy(parser, &cfgobj); cfg_parser_destroy(&parser); } conf->magic = IRS_DNSCONF_MAGIC; if (result == ISC_R_SUCCESS) *confp = conf; else irs_dnsconf_destroy(&conf); return (result); } void irs_dnsconf_destroy(irs_dnsconf_t **confp) { irs_dnsconf_t *conf; irs_dnsconf_dnskey_t *keyent; REQUIRE(confp != NULL); conf = *confp; REQUIRE(IRS_DNSCONF_VALID(conf)); while ((keyent = ISC_LIST_HEAD(conf->trusted_keylist)) != NULL) { ISC_LIST_UNLINK(conf->trusted_keylist, keyent, link); isc_buffer_free(&keyent->keydatabuf); dns_name_free(keyent->keyname, conf->mctx); isc_mem_put(conf->mctx, keyent->keyname, sizeof(dns_name_t)); isc_mem_put(conf->mctx, keyent, sizeof(*keyent)); } isc_mem_put(conf->mctx, conf, sizeof(*conf)); *confp = NULL; } irs_dnsconf_dnskeylist_t * irs_dnsconf_gettrustedkeys(irs_dnsconf_t *conf) { REQUIRE(IRS_DNSCONF_VALID(conf)); return (&conf->trusted_keylist); } bind9-9.10.3.dfsg.P4/lib/irs/include/0002755000470500017500000000000012672612753016371 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/irs/include/Makefile.in0000644000470500017500000000165612664710322020434 0ustar lamontlamont# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.3 2009/09/02 23:48:02 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = irs TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/irs/include/irs/0002755000470500017500000000000012664710322017156 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/irs/include/irs/platform.h.in0000644000470500017500000000242312664710322021557 0ustar lamontlamont/* * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: platform.h.in,v 1.3 2009/09/02 23:48:02 tbox Exp $ */ /*! \file */ #ifndef IRS_PLATFORM_H #define IRS_PLATFORM_H 1 /***** ***** Platform-dependent defines. *****/ #ifndef IRS_PLATFORM_USEDECLSPEC #define LIBIRS_EXTERNAL_DATA #else #ifdef LIBIRS_EXPORTS #define LIBIRS_EXTERNAL_DATA __declspec(dllexport) #else #define LIBIRS_EXTERNAL_DATA __declspec(dllimport) #endif #endif /* * Tell Emacs to use C mode on this file. * Local Variables: * mode: c * End: */ #endif /* IRS_PLATFORM_H */ bind9-9.10.3.dfsg.P4/lib/irs/include/irs/Makefile.in0000644000470500017500000000273212664710322021225 0ustar lamontlamont# Copyright (C) 2009, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.3 2009/09/02 23:48:02 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ # # Only list headers that are to be installed and are not # machine generated. The latter are handled specially in the # install target below. # HEADERS = context.h dnsconf.h resconf.h types.h version.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/irs install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/irs ; \ done ${INSTALL_DATA} netdb.h ${DESTDIR}${includedir}/irs ${INSTALL_DATA} platform.h ${DESTDIR}${includedir}/irs distclean:: rm -f netdb.h platform.h bind9-9.10.3.dfsg.P4/lib/irs/include/irs/resconf.h0000644000470500017500000000614412664710322020771 0ustar lamontlamont/* * Copyright (C) 2009, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: resconf.h,v 1.3 2009/09/02 23:48:02 tbox Exp $ */ #ifndef IRS_RESCONF_H #define IRS_RESCONF_H 1 /*! \file * * \brief * The IRS resconf module parses the legacy "/etc/resolv.conf" file and * creates the corresponding configuration objects for the DNS library * modules. */ #include /*% * A DNS search list specified in the 'domain' or 'search' statements * in the "resolv.conf" file. */ typedef struct irs_resconf_search { char *domain; ISC_LINK(struct irs_resconf_search) link; } irs_resconf_search_t; typedef ISC_LIST(irs_resconf_search_t) irs_resconf_searchlist_t; ISC_LANG_BEGINDECLS isc_result_t irs_resconf_load(isc_mem_t *mctx, const char *filename, irs_resconf_t **confp); /*%< * Load the resolver configuration file 'filename' in the "resolv.conf" format, * and create a new irs_resconf_t object from the configuration. If the file * is not found ISC_R_FILENOTFOUND is returned with the structure initialized * as if file contained only: * * nameserver ::1 * nameserver 127.0.0.1 * * Notes: * *\li Currently, only the following options are supported: * nameserver, domain, search, sortlist, ndots, and options. * In addition, 'sortlist' is not actually effective; it's parsed, but * the application cannot use the configuration. * * Returns: * \li ISC_R_SUCCESS on success * \li ISC_R_FILENOTFOUND if the file was not found. *confp will be valid. * \li other on error. * * Requires: * *\li 'mctx' is a valid memory context. * *\li 'filename' != NULL * *\li 'confp' != NULL && '*confp' == NULL */ void irs_resconf_destroy(irs_resconf_t **confp); /*%< * Destroy the resconf object. * * Requires: * *\li '*confp' is a valid resconf object. * * Ensures: * *\li *confp == NULL */ isc_sockaddrlist_t * irs_resconf_getnameservers(irs_resconf_t *conf); /*%< * Return a list of name server addresses stored in 'conf'. * * Requires: * *\li 'conf' is a valid resconf object. */ irs_resconf_searchlist_t * irs_resconf_getsearchlist(irs_resconf_t *conf); /*%< * Return the search list stored in 'conf'. * * Requires: * *\li 'conf' is a valid resconf object. */ unsigned int irs_resconf_getndots(irs_resconf_t *conf); /*%< * Return the 'ndots' value stored in 'conf'. * * Requires: * *\li 'conf' is a valid resconf object. */ ISC_LANG_ENDDECLS #endif /* IRS_RESCONF_H */ bind9-9.10.3.dfsg.P4/lib/irs/include/irs/types.h0000644000470500017500000000231512664710322020472 0ustar lamontlamont/* * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: types.h,v 1.3 2009/09/02 23:48:02 tbox Exp $ */ #ifndef IRS_TYPES_H #define IRS_TYPES_H 1 /* Core Types. Alphabetized by defined type. */ /*%< per-thread IRS context */ typedef struct irs_context irs_context_t; /*%< resolv.conf configuration information */ typedef struct irs_resconf irs_resconf_t; /*%< advanced DNS-related configuration information */ typedef struct irs_dnsconf irs_dnsconf_t; #endif /* IRS_TYPES_H */ bind9-9.10.3.dfsg.P4/lib/irs/include/irs/context.h0000644000470500017500000000756612664710322021027 0ustar lamontlamont/* * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: context.h,v 1.3 2009/09/02 23:48:02 tbox Exp $ */ #ifndef IRS_CONTEXT_H #define IRS_CONTEXT_H 1 /*! \file * * \brief * The IRS context module provides an abstract interface to the DNS library * with an application. An IRS context object initializes and holds various * resources used in the DNS library. */ #include #include ISC_LANG_BEGINDECLS isc_result_t irs_context_create(irs_context_t **contextp); /*%< * Create an IRS context. It internally initializes the ISC and DNS libraries * (if not yet), creates a DNS client object and initializes the client using * the configuration files parsed via the 'resconf' and 'dnsconf' IRS modules. * Some of the internally initialized objects can be used by the application * via irs_context_getxxx() functions (see below). * * Requires: * *\li contextp != NULL && *contextp == NULL. */ isc_result_t irs_context_get(irs_context_t **contextp); /*%< * Return an IRS context for the calling thread. If no IRS context is * associated to the thread, this function creates a new one by calling * irs_context_create(), and associates it with the thread as a thread specific * data value. This function is provided for standard libraries that are * expected to be thread-safe but do not accept an appropriate IRS context * as a library parameter, e.g., getaddrinfo(). * * Requires: * *\li contextp != NULL && *contextp == NULL. */ void irs_context_destroy(irs_context_t **contextp); /*%< * Destroy an IRS context. * * Requires: * *\li '*contextp' is a valid IRS context. * * Ensures: *\li '*contextp' == NULL. */ isc_mem_t * irs_context_getmctx(irs_context_t *context); /*%< * Return the memory context held in the context. * * Requires: * *\li 'context' is a valid IRS context. */ isc_appctx_t * irs_context_getappctx(irs_context_t *context); /*%< * Return the application context held in the context. * * Requires: * *\li 'context' is a valid IRS context. */ isc_taskmgr_t * irs_context_gettaskmgr(irs_context_t *context); /*%< * Return the task manager held in the context. * * Requires: * *\li 'context' is a valid IRS context. */ isc_timermgr_t * irs_context_gettimermgr(irs_context_t *context); /*%< * Return the timer manager held in the context. * * Requires: * *\li 'context' is a valid IRS context. */ isc_task_t * irs_context_gettask(irs_context_t *context); /*%< * Return the task object held in the context. * * Requires: * *\li 'context' is a valid IRS context. */ dns_client_t * irs_context_getdnsclient(irs_context_t *context); /*%< * Return the DNS client object held in the context. * * Requires: * *\li 'context' is a valid IRS context. */ irs_resconf_t * irs_context_getresconf(irs_context_t *context); /*%< * Return the resolver configuration object held in the context. * * Requires: * *\li 'context' is a valid IRS context. */ irs_dnsconf_t * irs_context_getdnsconf(irs_context_t *context); /*%< * Return the advanced DNS configuration object held in the context. * * Requires: * *\li 'context' is a valid IRS context. */ ISC_LANG_ENDDECLS #endif /* IRS_CONTEXT_H */ bind9-9.10.3.dfsg.P4/lib/irs/include/irs/version.h0000644000470500017500000000215712664710322021017 0ustar lamontlamont/* * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: version.h,v 1.3 2009/09/02 23:48:02 tbox Exp $ */ /*! \file */ #include LIBIRS_EXTERNAL_DATA extern const char irs_version[]; LIBIRS_EXTERNAL_DATA extern const unsigned int irs_libinterface; LIBIRS_EXTERNAL_DATA extern const unsigned int irs_librevision; LIBIRS_EXTERNAL_DATA extern const unsigned int irs_libage; bind9-9.10.3.dfsg.P4/lib/irs/include/irs/dnsconf.h0000644000470500017500000000524412664710322020764 0ustar lamontlamont/* * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: dnsconf.h,v 1.3 2009/09/02 23:48:02 tbox Exp $ */ #ifndef IRS_DNSCONF_H #define IRS_DNSCONF_H 1 /*! \file * * \brief * The IRS dnsconf module parses an "advanced" configuration file related to * the DNS library, such as trusted keys for DNSSEC validation, and creates * the corresponding configuration objects for the DNS library modules. * * Notes: * This module is very experimental and the configuration syntax or library * interfaces may change in future versions. Currently, only the * 'trusted-keys' statement is supported, whose syntax is the same as the * same name of statement for named.conf. */ #include /*% * A compound structure storing DNS key information mainly for DNSSEC * validation. A dns_key_t object will be created using the 'keyname' and * 'keydatabuf' members with the dst_key_fromdns() function. */ typedef struct irs_dnsconf_dnskey { dns_name_t *keyname; isc_buffer_t *keydatabuf; ISC_LINK(struct irs_dnsconf_dnskey) link; } irs_dnsconf_dnskey_t; typedef ISC_LIST(irs_dnsconf_dnskey_t) irs_dnsconf_dnskeylist_t; ISC_LANG_BEGINDECLS isc_result_t irs_dnsconf_load(isc_mem_t *mctx, const char *filename, irs_dnsconf_t **confp); /*%< * Load the "advanced" DNS configuration file 'filename' in the "dns.conf" * format, and create a new irs_dnsconf_t object from the configuration. * * Requires: * *\li 'mctx' is a valid memory context. * *\li 'filename' != NULL * *\li 'confp' != NULL && '*confp' == NULL */ void irs_dnsconf_destroy(irs_dnsconf_t **confp); /*%< * Destroy the dnsconf object. * * Requires: * *\li '*confp' is a valid dnsconf object. * * Ensures: * *\li *confp == NULL */ irs_dnsconf_dnskeylist_t * irs_dnsconf_gettrustedkeys(irs_dnsconf_t *conf); /*%< * Return a list of key information stored in 'conf'. * * Requires: * *\li 'conf' is a valid dnsconf object. */ ISC_LANG_ENDDECLS #endif /* IRS_DNSCONF_H */ bind9-9.10.3.dfsg.P4/lib/irs/include/irs/netdb.h.in0000644000470500017500000001113212664710322021024 0ustar lamontlamont/* * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: netdb.h.in,v 1.3 2009/09/02 23:48:02 tbox Exp $ */ /*! \file */ #ifndef IRS_NETDB_H #define IRS_NETDB_H 1 #include /* Required on FreeBSD (and others?) for size_t. */ #include /* Contractual provision. */ /* * Define if does not declare struct addrinfo. */ @ISC_IRS_NEEDADDRINFO@ #ifdef ISC_IRS_NEEDADDRINFO struct addrinfo { int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ int ai_family; /* PF_xxx */ int ai_socktype; /* SOCK_xxx */ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ size_t ai_addrlen; /* Length of ai_addr */ char *ai_canonname; /* Canonical name for hostname */ struct sockaddr *ai_addr; /* Binary address */ struct addrinfo *ai_next; /* Next structure in linked list */ }; #endif /* * Undefine all #defines we are interested in as may or may not have * defined them. */ /* * Error return codes from gethostbyname() and gethostbyaddr() * (left in extern int h_errno). */ #undef NETDB_INTERNAL #undef NETDB_SUCCESS #undef HOST_NOT_FOUND #undef TRY_AGAIN #undef NO_RECOVERY #undef NO_DATA #undef NO_ADDRESS #define NETDB_INTERNAL -1 /* see errno */ #define NETDB_SUCCESS 0 /* no problem */ #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */ #define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */ #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ #define NO_DATA 4 /* Valid name, no data record of requested type */ #define NO_ADDRESS NO_DATA /* no address, look for MX record */ /* * Error return codes from getaddrinfo(). EAI_INSECUREDATA is our own extension * and it's very unlikely to be already defined, but undef it just in case; it * at least doesn't do any harm. */ #undef EAI_ADDRFAMILY #undef EAI_AGAIN #undef EAI_BADFLAGS #undef EAI_FAIL #undef EAI_FAMILY #undef EAI_MEMORY #undef EAI_NODATA #undef EAI_NONAME #undef EAI_SERVICE #undef EAI_SOCKTYPE #undef EAI_SYSTEM #undef EAI_BADHINTS #undef EAI_PROTOCOL #undef EAI_OVERFLOW #undef EAI_INSECUREDATA #undef EAI_MAX #define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ #define EAI_AGAIN 2 /* temporary failure in name resolution */ #define EAI_BADFLAGS 3 /* invalid value for ai_flags */ #define EAI_FAIL 4 /* non-recoverable failure in name resolution */ #define EAI_FAMILY 5 /* ai_family not supported */ #define EAI_MEMORY 6 /* memory allocation failure */ #define EAI_NODATA 7 /* no address associated with hostname */ #define EAI_NONAME 8 /* hostname nor servname provided, or not known */ #define EAI_SERVICE 9 /* servname not supported for ai_socktype */ #define EAI_SOCKTYPE 10 /* ai_socktype not supported */ #define EAI_SYSTEM 11 /* system error returned in errno */ #define EAI_BADHINTS 12 #define EAI_PROTOCOL 13 #define EAI_OVERFLOW 14 #define EAI_INSECUREDATA 15 #define EAI_MAX 16 /* * Flag values for getaddrinfo() */ #undef AI_PASSIVE #undef AI_CANONNAME #undef AI_NUMERICHOST #define AI_PASSIVE 0x00000001 #define AI_CANONNAME 0x00000002 #define AI_NUMERICHOST 0x00000004 /* * Flag values for getipnodebyname() */ #undef AI_V4MAPPED #undef AI_ALL #undef AI_ADDRCONFIG #undef AI_DEFAULT #define AI_V4MAPPED 0x00000008 #define AI_ALL 0x00000010 #define AI_ADDRCONFIG 0x00000020 #define AI_DEFAULT (AI_V4MAPPED|AI_ADDRCONFIG) /* * Constants for lwres_getnameinfo() */ #undef NI_MAXHOST #undef NI_MAXSERV #define NI_MAXHOST 1025 #define NI_MAXSERV 32 /* * Flag values for lwres_getnameinfo() */ #undef NI_NOFQDN #undef NI_NUMERICHOST #undef NI_NAMEREQD #undef NI_NUMERICSERV #undef NI_DGRAM #undef NI_NUMERICSCOPE #define NI_NOFQDN 0x00000001 #define NI_NUMERICHOST 0x00000002 #define NI_NAMEREQD 0x00000004 #define NI_NUMERICSERV 0x00000008 #define NI_DGRAM 0x00000010 /* * Tell Emacs to use C mode on this file. * Local variables: * mode: c * End: */ #endif /* IRS_NETDB_H */ bind9-9.10.3.dfsg.P4/lib/irs/resconf.c0000644000470500017500000003614312664710322016546 0ustar lamontlamont/* * Copyright (C) 2009, 2011, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file resconf.c */ /** * Module for parsing resolv.conf files (largely derived from lwconfig.c). * * irs_resconf_load() opens the file filename and parses it to initialize * the configuration structure. * * \section lwconfig_return Return Values * * irs_resconf_load() returns #IRS_R_SUCCESS if it successfully read and * parsed filename. It returns a non-0 error code if filename could not be * opened or contained incorrect resolver statements. * * \section lwconfig_see See Also * * stdio(3), \link resolver resolver \endlink * * \section files Files * * /etc/resolv.conf */ #include #ifndef WIN32 #include #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #define IRS_RESCONF_MAGIC ISC_MAGIC('R', 'E', 'S', 'c') #define IRS_RESCONF_VALID(c) ISC_MAGIC_VALID(c, IRS_RESCONF_MAGIC) /*! * protocol constants */ #if ! defined(NS_INADDRSZ) #define NS_INADDRSZ 4 #endif #if ! defined(NS_IN6ADDRSZ) #define NS_IN6ADDRSZ 16 #endif /*! * resolv.conf parameters */ #define RESCONFMAXNAMESERVERS 3 /*%< max 3 "nameserver" entries */ #define RESCONFMAXSEARCH 8 /*%< max 8 domains in "search" entry */ #define RESCONFMAXLINELEN 256 /*%< max size of a line */ #define RESCONFMAXSORTLIST 10 /*%< max 10 */ /*! * configuration data structure */ struct irs_resconf { /* * The configuration data is a thread-specific object, and does not * need to be locked. */ unsigned int magic; isc_mem_t *mctx; isc_sockaddrlist_t nameservers; unsigned int numns; /*%< number of configured servers */ char *domainname; char *search[RESCONFMAXSEARCH]; isc_uint8_t searchnxt; /*%< index for next free slot */ irs_resconf_searchlist_t searchlist; struct { isc_netaddr_t addr; /*% mask has a non-zero 'family' if set */ isc_netaddr_t mask; } sortlist[RESCONFMAXSORTLIST]; isc_uint8_t sortlistnxt; /*%< non-zero if 'options debug' set */ isc_uint8_t resdebug; /*%< set to n in 'options ndots:n' */ isc_uint8_t ndots; }; static isc_result_t resconf_parsenameserver(irs_resconf_t *conf, FILE *fp); static isc_result_t resconf_parsedomain(irs_resconf_t *conf, FILE *fp); static isc_result_t resconf_parsesearch(irs_resconf_t *conf, FILE *fp); static isc_result_t resconf_parsesortlist(irs_resconf_t *conf, FILE *fp); static isc_result_t resconf_parseoption(irs_resconf_t *ctx, FILE *fp); /*! * Eat characters from FP until EOL or EOF. Returns EOF or '\n' */ static int eatline(FILE *fp) { int ch; ch = fgetc(fp); while (ch != '\n' && ch != EOF) ch = fgetc(fp); return (ch); } /*! * Eats white space up to next newline or non-whitespace character (of * EOF). Returns the last character read. Comments are considered white * space. */ static int eatwhite(FILE *fp) { int ch; ch = fgetc(fp); while (ch != '\n' && ch != EOF && isspace((unsigned char)ch)) ch = fgetc(fp); if (ch == ';' || ch == '#') ch = eatline(fp); return (ch); } /*! * Skip over any leading whitespace and then read in the next sequence of * non-whitespace characters. In this context newline is not considered * whitespace. Returns EOF on end-of-file, or the character * that caused the reading to stop. */ static int getword(FILE *fp, char *buffer, size_t size) { int ch; char *p = buffer; REQUIRE(buffer != NULL); REQUIRE(size > 0U); *p = '\0'; ch = eatwhite(fp); if (ch == EOF) return (EOF); do { *p = '\0'; if (ch == EOF || isspace((unsigned char)ch)) break; else if ((size_t) (p - buffer) == size - 1) return (EOF); /* Not enough space. */ *p++ = (char)ch; ch = fgetc(fp); } while (1); return (ch); } static isc_result_t add_server(isc_mem_t *mctx, const char *address_str, isc_sockaddrlist_t *nameservers) { int error; isc_sockaddr_t *address = NULL; struct addrinfo hints, *res; isc_result_t result = ISC_R_SUCCESS; res = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; hints.ai_flags = AI_NUMERICHOST; error = getaddrinfo(address_str, "53", &hints, &res); if (error != 0) return (ISC_R_BADADDRESSFORM); /* XXX: special case: treat all-0 IPv4 address as loopback */ if (res->ai_family == AF_INET) { struct in_addr *v4; unsigned char zeroaddress[] = {0, 0, 0, 0}; unsigned char loopaddress[] = {127, 0, 0, 1}; v4 = &((struct sockaddr_in *)res->ai_addr)->sin_addr; if (memcmp(v4, zeroaddress, 4) == 0) memmove(v4, loopaddress, 4); } address = isc_mem_get(mctx, sizeof(*address)); if (address == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } if (res->ai_addrlen > sizeof(address->type)) { isc_mem_put(mctx, address, sizeof(*address)); result = ISC_R_RANGE; goto cleanup; } address->length = (unsigned int)res->ai_addrlen; memmove(&address->type.ss, res->ai_addr, res->ai_addrlen); ISC_LINK_INIT(address, link); ISC_LIST_APPEND(*nameservers, address, link); cleanup: freeaddrinfo(res); return (result); } static isc_result_t create_addr(const char *buffer, isc_netaddr_t *addr, int convert_zero) { struct in_addr v4; struct in6_addr v6; if (inet_aton(buffer, &v4) == 1) { if (convert_zero) { unsigned char zeroaddress[] = {0, 0, 0, 0}; unsigned char loopaddress[] = {127, 0, 0, 1}; if (memcmp(&v4, zeroaddress, 4) == 0) memmove(&v4, loopaddress, 4); } addr->family = AF_INET; memmove(&addr->type.in, &v4, NS_INADDRSZ); addr->zone = 0; } else if (inet_pton(AF_INET6, buffer, &v6) == 1) { addr->family = AF_INET6; memmove(&addr->type.in6, &v6, NS_IN6ADDRSZ); addr->zone = 0; } else return (ISC_R_BADADDRESSFORM); /* Unrecognised format. */ return (ISC_R_SUCCESS); } static isc_result_t resconf_parsenameserver(irs_resconf_t *conf, FILE *fp) { char word[RESCONFMAXLINELEN]; int cp; isc_result_t result; if (conf->numns == RESCONFMAXNAMESERVERS) return (ISC_R_SUCCESS); cp = getword(fp, word, sizeof(word)); if (strlen(word) == 0U) return (ISC_R_UNEXPECTEDEND); /* Nothing on line. */ else if (cp == ' ' || cp == '\t') cp = eatwhite(fp); if (cp != EOF && cp != '\n') return (ISC_R_UNEXPECTEDTOKEN); /* Extra junk on line. */ result = add_server(conf->mctx, word, &conf->nameservers); if (result != ISC_R_SUCCESS) return (result); conf->numns++; return (ISC_R_SUCCESS); } static isc_result_t resconf_parsedomain(irs_resconf_t *conf, FILE *fp) { char word[RESCONFMAXLINELEN]; int res, i; res = getword(fp, word, sizeof(word)); if (strlen(word) == 0U) return (ISC_R_UNEXPECTEDEND); /* Nothing else on line. */ else if (res == ' ' || res == '\t') res = eatwhite(fp); if (res != EOF && res != '\n') return (ISC_R_UNEXPECTEDTOKEN); /* Extra junk on line. */ if (conf->domainname != NULL) isc_mem_free(conf->mctx, conf->domainname); /* * Search and domain are mutually exclusive. */ for (i = 0; i < RESCONFMAXSEARCH; i++) { if (conf->search[i] != NULL) { isc_mem_free(conf->mctx, conf->search[i]); conf->search[i] = NULL; } } conf->searchnxt = 0; conf->domainname = isc_mem_strdup(conf->mctx, word); if (conf->domainname == NULL) return (ISC_R_NOMEMORY); return (ISC_R_SUCCESS); } static isc_result_t resconf_parsesearch(irs_resconf_t *conf, FILE *fp) { int idx, delim; char word[RESCONFMAXLINELEN]; if (conf->domainname != NULL) { /* * Search and domain are mutually exclusive. */ isc_mem_free(conf->mctx, conf->domainname); conf->domainname = NULL; } /* * Remove any previous search definitions. */ for (idx = 0; idx < RESCONFMAXSEARCH; idx++) { if (conf->search[idx] != NULL) { isc_mem_free(conf->mctx, conf->search[idx]); conf->search[idx] = NULL; } } conf->searchnxt = 0; delim = getword(fp, word, sizeof(word)); if (strlen(word) == 0U) return (ISC_R_UNEXPECTEDEND); /* Nothing else on line. */ idx = 0; while (strlen(word) > 0U) { if (conf->searchnxt == RESCONFMAXSEARCH) goto ignore; /* Too many domains. */ conf->search[idx] = isc_mem_strdup(conf->mctx, word); if (conf->search[idx] == NULL) return (ISC_R_NOMEMORY); idx++; conf->searchnxt++; ignore: if (delim == EOF || delim == '\n') break; else delim = getword(fp, word, sizeof(word)); } return (ISC_R_SUCCESS); } static isc_result_t resconf_parsesortlist(irs_resconf_t *conf, FILE *fp) { int delim, res, idx; char word[RESCONFMAXLINELEN]; char *p; delim = getword(fp, word, sizeof(word)); if (strlen(word) == 0U) return (ISC_R_UNEXPECTEDEND); /* Empty line after keyword. */ while (strlen(word) > 0U) { if (conf->sortlistnxt == RESCONFMAXSORTLIST) return (ISC_R_QUOTA); /* Too many values. */ p = strchr(word, '/'); if (p != NULL) *p++ = '\0'; idx = conf->sortlistnxt; res = create_addr(word, &conf->sortlist[idx].addr, 1); if (res != ISC_R_SUCCESS) return (res); if (p != NULL) { res = create_addr(p, &conf->sortlist[idx].mask, 0); if (res != ISC_R_SUCCESS) return (res); } else { /* * Make up a mask. (XXX: is this correct?) */ conf->sortlist[idx].mask = conf->sortlist[idx].addr; memset(&conf->sortlist[idx].mask.type, 0xff, sizeof(conf->sortlist[idx].mask.type)); } conf->sortlistnxt++; if (delim == EOF || delim == '\n') break; else delim = getword(fp, word, sizeof(word)); } return (ISC_R_SUCCESS); } static isc_result_t resconf_parseoption(irs_resconf_t *conf, FILE *fp) { int delim; long ndots; char *p; char word[RESCONFMAXLINELEN]; delim = getword(fp, word, sizeof(word)); if (strlen(word) == 0U) return (ISC_R_UNEXPECTEDEND); /* Empty line after keyword. */ while (strlen(word) > 0U) { if (strcmp("debug", word) == 0) { conf->resdebug = 1; } else if (strncmp("ndots:", word, 6) == 0) { ndots = strtol(word + 6, &p, 10); if (*p != '\0') /* Bad string. */ return (ISC_R_UNEXPECTEDTOKEN); if (ndots < 0 || ndots > 0xff) /* Out of range. */ return (ISC_R_RANGE); conf->ndots = (isc_uint8_t)ndots; } if (delim == EOF || delim == '\n') break; else delim = getword(fp, word, sizeof(word)); } return (ISC_R_SUCCESS); } static isc_result_t add_search(irs_resconf_t *conf, char *domain) { irs_resconf_search_t *entry; entry = isc_mem_get(conf->mctx, sizeof(*entry)); if (entry == NULL) return (ISC_R_NOMEMORY); entry->domain = domain; ISC_LINK_INIT(entry, link); ISC_LIST_APPEND(conf->searchlist, entry, link); return (ISC_R_SUCCESS); } /*% parses a file and fills in the data structure. */ isc_result_t irs_resconf_load(isc_mem_t *mctx, const char *filename, irs_resconf_t **confp) { FILE *fp = NULL; char word[256]; isc_result_t rval, ret = ISC_R_SUCCESS; irs_resconf_t *conf; int i, stopchar; REQUIRE(mctx != NULL); REQUIRE(filename != NULL); REQUIRE(strlen(filename) > 0U); REQUIRE(confp != NULL && *confp == NULL); conf = isc_mem_get(mctx, sizeof(*conf)); if (conf == NULL) return (ISC_R_NOMEMORY); conf->mctx = mctx; ISC_LIST_INIT(conf->nameservers); conf->numns = 0; conf->domainname = NULL; conf->searchnxt = 0; conf->resdebug = 0; conf->ndots = 1; for (i = 0; i < RESCONFMAXSEARCH; i++) conf->search[i] = NULL; errno = 0; if ((fp = fopen(filename, "r")) != NULL) { do { stopchar = getword(fp, word, sizeof(word)); if (stopchar == EOF) { rval = ISC_R_SUCCESS; POST(rval); break; } if (strlen(word) == 0U) rval = ISC_R_SUCCESS; else if (strcmp(word, "nameserver") == 0) rval = resconf_parsenameserver(conf, fp); else if (strcmp(word, "domain") == 0) rval = resconf_parsedomain(conf, fp); else if (strcmp(word, "search") == 0) rval = resconf_parsesearch(conf, fp); else if (strcmp(word, "sortlist") == 0) rval = resconf_parsesortlist(conf, fp); else if (strcmp(word, "options") == 0) rval = resconf_parseoption(conf, fp); else { /* unrecognised word. Ignore entire line */ rval = ISC_R_SUCCESS; stopchar = eatline(fp); if (stopchar == EOF) { break; } } if (ret == ISC_R_SUCCESS && rval != ISC_R_SUCCESS) ret = rval; } while (1); fclose(fp); } else { switch (errno) { case ENOENT: break; default: isc_mem_put(mctx, conf, sizeof(*conf)); return (ISC_R_INVALIDFILE); } } /* If we don't find a nameserver fall back to localhost */ if (conf->numns == 0) { INSIST(ISC_LIST_EMPTY(conf->nameservers)); /* XXX: should we catch errors? */ (void)add_server(conf->mctx, "127.0.0.1", &conf->nameservers); (void)add_server(conf->mctx, "::1", &conf->nameservers); } /* * Construct unified search list from domain or configured * search list */ ISC_LIST_INIT(conf->searchlist); if (conf->domainname != NULL) { ret = add_search(conf, conf->domainname); } else if (conf->searchnxt > 0) { for (i = 0; i < conf->searchnxt; i++) { ret = add_search(conf, conf->search[i]); if (ret != ISC_R_SUCCESS) break; } } conf->magic = IRS_RESCONF_MAGIC; if (ret != ISC_R_SUCCESS) irs_resconf_destroy(&conf); else { if (fp == NULL) ret = ISC_R_FILENOTFOUND; *confp = conf; } return (ret); } void irs_resconf_destroy(irs_resconf_t **confp) { irs_resconf_t *conf; isc_sockaddr_t *address; irs_resconf_search_t *searchentry; int i; REQUIRE(confp != NULL); conf = *confp; REQUIRE(IRS_RESCONF_VALID(conf)); while ((searchentry = ISC_LIST_HEAD(conf->searchlist)) != NULL) { ISC_LIST_UNLINK(conf->searchlist, searchentry, link); isc_mem_put(conf->mctx, searchentry, sizeof(*searchentry)); } while ((address = ISC_LIST_HEAD(conf->nameservers)) != NULL) { ISC_LIST_UNLINK(conf->nameservers, address, link); isc_mem_put(conf->mctx, address, sizeof(*address)); } if (conf->domainname != NULL) isc_mem_free(conf->mctx, conf->domainname); for (i = 0; i < RESCONFMAXSEARCH; i++) { if (conf->search[i] != NULL) isc_mem_free(conf->mctx, conf->search[i]); } isc_mem_put(conf->mctx, conf, sizeof(*conf)); *confp = NULL; } isc_sockaddrlist_t * irs_resconf_getnameservers(irs_resconf_t *conf) { REQUIRE(IRS_RESCONF_VALID(conf)); return (&conf->nameservers); } irs_resconf_searchlist_t * irs_resconf_getsearchlist(irs_resconf_t *conf) { REQUIRE(IRS_RESCONF_VALID(conf)); return (&conf->searchlist); } unsigned int irs_resconf_getndots(irs_resconf_t *conf) { REQUIRE(IRS_RESCONF_VALID(conf)); return ((unsigned int)conf->ndots); } bind9-9.10.3.dfsg.P4/lib/irs/win32/0002755000470500017500000000000012664730167015711 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/irs/win32/version.c0000644000470500017500000000213412664710322017527 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #include #include LIBIRS_EXTERNAL_DATA const char irs_version[] = VERSION; LIBIRS_EXTERNAL_DATA const unsigned int irs_libinterface = LIBINTERFACE; LIBIRS_EXTERNAL_DATA const unsigned int irs_librevision = LIBREVISION; LIBIRS_EXTERNAL_DATA const unsigned int irs_libage = LIBAGE; bind9-9.10.3.dfsg.P4/lib/irs/win32/libirs.dsp.in0000644000470500017500000001320712664710322020302 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="libirs" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Dynamic-Link Library" 0x0102 CFG=libirs - @PLATFORM@ Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "libirs.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "libirs.mak" CFG="libirs - @PLATFORM@ Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "libirs - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE "libirs - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "libirs - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "libirs_EXPORTS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 @LIBXML2_INC@ @OPENSSL_INC@ @GEOIP_INC@ /I "./" /I "../../../" /I "include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isccfg/include" /I "../../../lib/dns/include" /I "../../../lib/isc/include" /D "NDEBUG" /D "WIN32" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ /D "LIBIRS_EXPORTS" @COPTY@ /FD /c # SUBTRACT CPP /X # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll @MACHINE@ # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Release/libisc.lib ../../dns/win32/Release/libdns.lib ../../isccfg/win32/Release/libisccfg.lib /nologo /dll @MACHINE@ /out:"../../../Build/Release/libirs.dll" !ELSEIF "$(CFG)" == "libirs - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "libirs_EXPORTS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od @LIBXML2_INC@ @OPENSSL_INC@ @GEOIP_INC@ /I "./" /I "../../../" /I "include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isccfg/include" /I "../../../lib/dns/include" /I "../../../lib/isc/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ /D "LIBIRS_EXPORTS" /FR @COPTY@ /FD /GZ /c # SUBTRACT CPP /X # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../isc/win32/debug/libisc.lib ../../dns/win32/debug/libdns.lib ../../isccfg/win32/debug/libisccfg.lib /nologo /dll /debug @MACHINE@ /out:"../../../Build/Debug/libirs.dll" /pdbtype:sept !ENDIF # Begin Target # Name "libirs - @PLATFORM@ Release" # Name "libirs - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\context.c # End Source File # Begin Source File SOURCE=.\DLLMain.c # End Source File # Begin Source File SOURCE=..\dnsconf.c # End Source File # Begin Source File SOURCE=..\gai_strerror.c # End Source File # Begin Source File SOURCE=..\getaddrinfo.c # End Source File # Begin Source File SOURCE=..\getnameinfo.c # End Source File # Begin Source File SOURCE=..\resconf.c # End Source File # Begin Source File SOURCE=.\version.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=..\include\irs\context.h # End Source File # Begin Source File SOURCE=..\include\irs\dnsconf.h # End Source File # Begin Source File SOURCE=..\include\irs\netdb.h # End Source File # Begin Source File SOURCE=..\include\irs\platform.h # End Source File # Begin Source File SOURCE=..\include\irs\resconf.h # End Source File # Begin Source File SOURCE=..\include\irs\types.h # End Source File # Begin Source File SOURCE=..\include\irs\version.h # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # Begin Source File SOURCE=.\libirs.def # End Source File # End Target # End Project bind9-9.10.3.dfsg.P4/lib/irs/win32/Makefile.in0000644000470500017500000000157312664710322017751 0ustar lamontlamont# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id$ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = include TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/irs/win32/libirs.dsw0000644000470500017500000000102712664710322017701 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "libirs"=.\libirs.dsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/lib/irs/win32/DLLMain.c0000644000470500017500000000273512664710322017271 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #include #include /* * Called when we enter the DLL */ __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { /* * The DLL is loading due to process * initialization or a call to LoadLibrary. */ case DLL_PROCESS_ATTACH: break; /* The attached process creates a new thread. */ case DLL_THREAD_ATTACH: break; /* The thread of the attached process terminates. */ case DLL_THREAD_DETACH: break; /* * The DLL is unloading from a process due to * process termination or a call to FreeLibrary. */ case DLL_PROCESS_DETACH: break; default: break; } return (TRUE); } bind9-9.10.3.dfsg.P4/lib/irs/win32/libirs.vcxproj.in0000644000470500017500000001704212664710322021210 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {A4F29CEB-7644-4A7F-BE9E-02B6A90E4919} Win32Proj libirs DynamicLibrary true MultiByte DynamicLibrary false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ Level3 Disabled WIN32;USE_MD5;@CRYPTO@_DEBUG;_WINDOWS;_USRDLL;LIBIRS_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions) .\;..\..\..\;include;..\include;..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;..\..\isccfg\include;..\..\dns\include;@LIBXML2_INC@@OPENSSL_INC@@GEOIP_INC@%(AdditionalIncludeDirectories) false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true Console true ..\..\isc\win32\$(Configuration);..\..\dns\win32\$(Configuration);..\..\isccfg\win32\$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;libdns.lib;libisccfg.lib;ws2_32.lib;%(AdditionalDependencies) .\libirs.def .\$(Configuration)\$(ProjectName).lib ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Level3 MaxSpeed true @INTRINSIC@ WIN32;USE_MD5;@CRYPTO@NDEBUG;_WINDOWS;_USRDLL;LIBIRS_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions) .\;..\..\..\;include;..\include;..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;..\..\isccfg\include;..\..\dns\include;@LIBXML2_INC@@OPENSSL_INC@@GEOIP_INC@%(AdditionalIncludeDirectories) OnlyExplicitInline false true .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb Console false true true ..\..\isc\win32\$(Configuration);..\..\dns\win32\$(Configuration);..\..\isccfg\win32\$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;libdns.lib;libisccfg.lib;ws2_32.lib;%(AdditionalDependencies) .\libirs.def .\$(Configuration)\$(ProjectName).lib Default ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) bind9-9.10.3.dfsg.P4/lib/irs/win32/include/0002755000470500017500000000000012672612753017333 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/irs/win32/include/Makefile.in0000644000470500017500000000156712664710322021377 0ustar lamontlamont# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id$ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = irs TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/irs/win32/include/irs/0002755000470500017500000000000012664730166020130 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/irs/win32/include/irs/Makefile.in0000644000470500017500000000210512664710322022161 0ustar lamontlamont# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id$ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ HEADERS = SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/irs install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/irs ; \ done bind9-9.10.3.dfsg.P4/lib/irs/win32/include/irs/platform.h0000644000470500017500000000232412664710322022114 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #ifndef IRS_PLATFORM_H #define IRS_PLATFORM_H 1 /***** ***** Platform-dependent defines. *****/ #ifndef IRS_PLATFORM_USEDECLSPEC #define LIBIRS_EXTERNAL_DATA #else #ifdef LIBIRS_EXPORTS #define LIBIRS_EXTERNAL_DATA __declspec(dllexport) #else #define LIBIRS_EXTERNAL_DATA __declspec(dllimport) #endif #endif /* * Tell Emacs to use C mode on this file. * Local Variables: * mode: c * End: */ #endif /* IRS_PLATFORM_H */ bind9-9.10.3.dfsg.P4/lib/irs/win32/include/irs/netdb.h0000644000470500017500000001234512664710322021370 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #ifndef IRS_NETDB_H #define IRS_NETDB_H 1 #include /* Required on FreeBSD (and others?) for size_t. */ /* * Define if does not declare struct addrinfo. */ #undef ISC_IRS_NEEDADDRINFO #ifdef ISC_IRS_NEEDADDRINFO struct addrinfo { int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ int ai_family; /* PF_xxx */ int ai_socktype; /* SOCK_xxx */ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ size_t ai_addrlen; /* Length of ai_addr */ char *ai_canonname; /* Canonical name for hostname */ struct sockaddr *ai_addr; /* Binary address */ struct addrinfo *ai_next; /* Next structure in linked list */ }; #endif /* * Undefine all #defines we are interested in as may or may not have * defined them. */ /* * Error return codes from gethostbyname() and gethostbyaddr() * (left in extern int h_errno). */ #undef NETDB_INTERNAL #undef NETDB_SUCCESS #undef HOST_NOT_FOUND #undef TRY_AGAIN #undef NO_RECOVERY #undef NO_DATA #undef NO_ADDRESS #define NETDB_INTERNAL -1 /* see errno */ #define NETDB_SUCCESS 0 /* no problem */ #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */ #define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */ #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ #define NO_DATA 4 /* Valid name, no data record of requested type */ #define NO_ADDRESS NO_DATA /* no address, look for MX record */ /* * Error return codes from getaddrinfo(). EAI_INSECUREDATA is our own extension * and it's very unlikely to be already defined, but undef it just in case; it * at least doesn't do any harm. */ #undef EAI_ADDRFAMILY #undef EAI_AGAIN #undef EAI_BADFLAGS #undef EAI_FAIL #undef EAI_FAMILY #undef EAI_MEMORY #undef EAI_NODATA #undef EAI_NONAME #undef EAI_SERVICE #undef EAI_SOCKTYPE #undef EAI_SYSTEM #undef EAI_BADHINTS #undef EAI_PROTOCOL #undef EAI_OVERFLOW #undef EAI_INSECUREDATA #undef EAI_MAX #define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ #define EAI_AGAIN 2 /* temporary failure in name resolution */ #define EAI_BADFLAGS 3 /* invalid value for ai_flags */ #define EAI_FAIL 4 /* non-recoverable failure in name resolution */ #define EAI_FAMILY 5 /* ai_family not supported */ #define EAI_MEMORY 6 /* memory allocation failure */ #define EAI_NODATA 7 /* no address associated with hostname */ #define EAI_NONAME 8 /* hostname nor servname provided, or not known */ #define EAI_SERVICE 9 /* servname not supported for ai_socktype */ #define EAI_SOCKTYPE 10 /* ai_socktype not supported */ #define EAI_SYSTEM 11 /* system error returned in errno */ #define EAI_BADHINTS 12 #define EAI_PROTOCOL 13 #define EAI_OVERFLOW 14 #define EAI_INSECUREDATA 15 #define EAI_MAX 16 /* * Flag values for getaddrinfo() */ #undef AI_PASSIVE #undef AI_CANONNAME #undef AI_NUMERICHOST #define AI_PASSIVE 0x00000001 #define AI_CANONNAME 0x00000002 #define AI_NUMERICHOST 0x00000004 /* * Flag values for getipnodebyname() */ #undef AI_V4MAPPED #undef AI_ALL #undef AI_ADDRCONFIG #undef AI_DEFAULT #define AI_V4MAPPED 0x00000008 #define AI_ALL 0x00000010 #define AI_ADDRCONFIG 0x00000020 #define AI_DEFAULT (AI_V4MAPPED|AI_ADDRCONFIG) /* * Constants for lwres_getnameinfo() */ #undef NI_MAXHOST #undef NI_MAXSERV #define NI_MAXHOST 1025 #define NI_MAXSERV 32 /* * Flag values for lwres_getnameinfo() */ #undef NI_NOFQDN #undef NI_NUMERICHOST #undef NI_NAMEREQD #undef NI_NUMERICSERV #undef NI_DGRAM #undef NI_NUMERICSCOPE #define NI_NOFQDN 0x00000001 #define NI_NUMERICHOST 0x00000002 #define NI_NAMEREQD 0x00000004 #define NI_NUMERICSERV 0x00000008 #define NI_DGRAM 0x00000010 /* * Define to map into irs_ namespace. */ #define IRS_NAMESPACE #ifdef IRS_NAMESPACE /* * Use our versions not the ones from the C library. */ #ifdef getnameinfo #undef getnameinfo #endif #define getnameinfo irs_getnameinfo #ifdef getaddrinfo #undef getaddrinfo #endif #define getaddrinfo irs_getaddrinfo #ifdef freeaddrinfo #undef freeaddrinfo #endif #define freeaddrinfo irs_freeaddrinfo #ifdef gai_strerror #undef gai_strerror #endif #define gai_strerror irs_gai_strerror #endif int getaddrinfo(const char *, const char *, const struct addrinfo *, struct addrinfo **); int getnameinfo(const struct sockaddr *, socklen_t, char *, DWORD, char *, DWORD, int); void freeaddrinfo(struct addrinfo *); char *gai_strerror(int); /* * Tell Emacs to use C mode on this file. * Local variables: * mode: c * End: */ #endif /* IRS_NETDB_H */ bind9-9.10.3.dfsg.P4/lib/irs/win32/libirs.vcxproj.user0000644000470500017500000000021712664710322021554 0ustar lamontlamont bind9-9.10.3.dfsg.P4/lib/irs/win32/libirs.mak.in0000644000470500017500000003507212664710322020270 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on libirs.dsp !IF "$(CFG)" == "" CFG=libirs - @PLATFORM@ Release !MESSAGE No configuration specified. Defaulting to libirs - @PLATFORM@ Release. !ENDIF !IF "$(CFG)" != "libirs - @PLATFORM@ Release" && "$(CFG)" != "libirs - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "libirs.mak" CFG="libirs - @PLATFORM@ Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "libirs - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE "libirs - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "libirs - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "libirs - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release !IF "$(RECURSE)" == "0" ALL : "..\..\..\Build\Release\libirs.dll" !ELSE ALL : "libisccfg - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" "libdns - @PLATFORM@ Release" "..\..\..\Build\Release\libirs.dll" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libdns - @PLATFORM@ ReleaseCLEAN" "libisc - @PLATFORM@ ReleaseCLEAN" "libisccfg - @PLATFORM@ ReleaseCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\context.obj" -@erase "$(INTDIR)\DLLMain.obj" -@erase "$(INTDIR)\dnsconf.obj" -@erase "$(INTDIR)\gai_strerror.obj" -@erase "$(INTDIR)\getaddrinfo.obj" -@erase "$(INTDIR)\getnameinfo.obj" -@erase "$(INTDIR)\resconf.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\version.obj" -@erase "$(OUTDIR)\libirs.exp" -@erase "$(OUTDIR)\libirs.lib" -@erase "..\..\..\Build\Release\libirs.dll" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 @LIBXML2_INC@ @OPENSSL_INC@ @GEOIP_INC@ /I "./" /I "../../../" /I "include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isccfg/include" /I "../../../lib/dns/include" /I "../../../lib/isc/include" /D "NDEBUG" /D "WIN32" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ /D "LIBIRS_EXPORTS" /Fp"$(INTDIR)\libirs.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\libirs.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Release/libisc.lib ../../dns/win32/Release/libdns.lib ../../isccfg/win32/Release/libisccfg.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\libirs.pdb" @MACHINE@ /def:".\libirs.def" /out:"../../../Build/Release/libirs.dll" /implib:"$(OUTDIR)\libirs.lib" DEF_FILE= \ ".\libirs.def" LINK32_OBJS= \ "$(INTDIR)\context.obj" \ "$(INTDIR)\DLLMain.obj" \ "$(INTDIR)\dnsconf.obj" \ "$(INTDIR)\gai_strerror.obj" \ "$(INTDIR)\getaddrinfo.obj" \ "$(INTDIR)\getnameinfo.obj" \ "$(INTDIR)\resconf.obj" \ "$(INTDIR)\version.obj" \ "..\..\dns\win32\Release\libdns.lib" \ "..\..\isc\win32\Release\libisc.lib" \ "..\..\isccfg\win32\Release\libisccfg.lib" "..\..\..\Build\Release\libirs.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_DLL) !ELSEIF "$(CFG)" == "libirs - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros !IF "$(RECURSE)" == "0" ALL : "..\..\..\Build\Debug\libirs.dll" "$(OUTDIR)\libirs.bsc" !ELSE ALL : "libisccfg - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" "libdns - @PLATFORM@ Debug" "..\..\..\Build\Debug\libirs.dll" "$(OUTDIR)\libirs.bsc" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libdns - @PLATFORM@ DebugCLEAN" "libisc - @PLATFORM@ DebugCLEAN" "libisccfg - @PLATFORM@ DebugCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\context.obj" -@erase "$(INTDIR)\context.sbr" -@erase "$(INTDIR)\DLLMain.obj" -@erase "$(INTDIR)\DLLMain.sbr" -@erase "$(INTDIR)\dnsconf.obj" -@erase "$(INTDIR)\dnsconf.sbr" -@erase "$(INTDIR)\gai_strerror.obj" -@erase "$(INTDIR)\gai_strerror.sbr" -@erase "$(INTDIR)\getaddrinfo.obj" -@erase "$(INTDIR)\getaddrinfo.sbr" -@erase "$(INTDIR)\getnameinfo.obj" -@erase "$(INTDIR)\getnameinfo.sbr" -@erase "$(INTDIR)\resconf.obj" -@erase "$(INTDIR)\resconf.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(INTDIR)\version.obj" -@erase "$(INTDIR)\version.sbr" -@erase "$(OUTDIR)\libirs.bsc" -@erase "$(OUTDIR)\libirs.exp" -@erase "$(OUTDIR)\libirs.lib" -@erase "$(OUTDIR)\libirs.pdb" -@erase "..\..\..\Build\Debug\libirs.dll" -@erase "..\..\..\Build\Debug\libirs.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od @LIBXML2_INC@ @OPENSSL_INC@ @GEOIP_INC@ /I "./" /I "../../../" /I "include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isccfg/include" /I "../../../lib/dns/include" /I "../../../lib/isc/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ /D "LIBIRS_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\libirs.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\libirs.bsc" BSC32_SBRS= \ "$(INTDIR)\context.sbr" \ "$(INTDIR)\DLLMain.sbr" \ "$(INTDIR)\dnsconf.sbr" \ "$(INTDIR)\gai_strerror.sbr" \ "$(INTDIR)\getaddrinfo.sbr" \ "$(INTDIR)\getnameinfo.sbr" \ "$(INTDIR)\resconf.sbr" \ "$(INTDIR)\version.sbr" "$(OUTDIR)\libirs.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../isc/win32/debug/libisc.lib ../../dns/win32/debug/libdns.lib ../../isccfg/win32/debug/libisccfg.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\libirs.pdb" /debug @MACHINE@ /def:".\libirs.def" /out:"../../../Build/Debug/libirs.dll" /implib:"$(OUTDIR)\libirs.lib" /pdbtype:sept DEF_FILE= \ ".\libirs.def" LINK32_OBJS= \ "$(INTDIR)\context.obj" \ "$(INTDIR)\DLLMain.obj" \ "$(INTDIR)\dnsconf.obj" \ "$(INTDIR)\gai_strerror.obj" \ "$(INTDIR)\getaddrinfo.obj" \ "$(INTDIR)\getnameinfo.obj" \ "$(INTDIR)\resconf.obj" \ "$(INTDIR)\version.obj" \ "..\..\dns\win32\Debug\libdns.lib" \ "..\..\isc\win32\Debug\libisc.lib" \ "..\..\isccfg\win32\Debug\libisccfg.lib" "..\..\..\Build\Debug\libirs.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_DLL) !ENDIF .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("libirs.dep") !INCLUDE "libirs.dep" !ELSE !MESSAGE Warning: cannot find "libirs.dep" !ENDIF !ENDIF !IF "$(CFG)" == "libirs - @PLATFORM@ Release" || "$(CFG)" == "libirs - @PLATFORM@ Debug" SOURCE=..\context.c !IF "$(CFG)" == "libirs - @PLATFORM@ Release" "$(INTDIR)\context.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libirs - @PLATFORM@ Debug" "$(INTDIR)\context.obj" "$(INTDIR)\context.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=.\DLLMain.c !IF "$(CFG)" == "libirs - @PLATFORM@ Release" "$(INTDIR)\DLLMain.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libirs - @PLATFORM@ Debug" "$(INTDIR)\DLLMain.obj" "$(INTDIR)\DLLMain.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=..\dnsconf.c !IF "$(CFG)" == "libirs - @PLATFORM@ Release" "$(INTDIR)\dnsconf.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libirs - @PLATFORM@ Debug" "$(INTDIR)\dnsconf.obj" "$(INTDIR)\dnsconf.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\gai_strerror.c !IF "$(CFG)" == "libirs - @PLATFORM@ Release" "$(INTDIR)\gai_strerror.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libirs - @PLATFORM@ Debug" "$(INTDIR)\gai_strerror.obj" "$(INTDIR)\gai_strerror.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\getaddrinfo.c !IF "$(CFG)" == "libirs - @PLATFORM@ Release" "$(INTDIR)\getaddrinfo.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libirs - @PLATFORM@ Debug" "$(INTDIR)\getaddrinfo.obj" "$(INTDIR)\getaddrinfo.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\getnameinfo.c !IF "$(CFG)" == "libirs - @PLATFORM@ Release" "$(INTDIR)\getnameinfo.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libirs - @PLATFORM@ Debug" "$(INTDIR)\getnameinfo.obj" "$(INTDIR)\getnameinfo.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\resconf.c !IF "$(CFG)" == "libirs - @PLATFORM@ Release" "$(INTDIR)\resconf.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libirs - @PLATFORM@ Debug" "$(INTDIR)\resconf.obj" "$(INTDIR)\resconf.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=.\version.c !IF "$(CFG)" == "libirs - @PLATFORM@ Release" "$(INTDIR)\version.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libirs - @PLATFORM@ Debug" "$(INTDIR)\version.obj" "$(INTDIR)\version.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF !IF "$(CFG)" == "libirs - @PLATFORM@ Release" "libdns - @PLATFORM@ Release" : cd "..\..\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" cd "..\..\irs\win32" "libdns - @PLATFORM@ ReleaseCLEAN" : cd "..\..\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\irs\win32" !ELSEIF "$(CFG)" == "libirs - @PLATFORM@ Debug" "libdns - @PLATFORM@ Debug" : cd "..\..\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" cd "..\..\irs\win32" "libdns - @PLATFORM@ DebugCLEAN" : cd "..\..\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\irs\win32" !ENDIF !IF "$(CFG)" == "libirs - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" cd "..\..\irs\win32" "libisc - @PLATFORM@ ReleaseCLEAN" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\irs\win32" !ELSEIF "$(CFG)" == "libirs - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" cd "..\..\irs\win32" "libisc - @PLATFORM@ DebugCLEAN" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\irs\win32" !ENDIF !IF "$(CFG)" == "libirs - @PLATFORM@ Release" "libisccfg - @PLATFORM@ Release" : cd "..\..\isccfg\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Release" cd "..\..\irs\win32" "libisccfg - @PLATFORM@ ReleaseCLEAN" : cd "..\..\isccfg\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\irs\win32" !ELSEIF "$(CFG)" == "libirs - @PLATFORM@ Debug" "libisccfg - @PLATFORM@ Debug" : cd "..\..\isccfg\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Debug" cd "..\..\irs\win32" "libisccfg - @PLATFORM@ DebugCLEAN" : cd "..\..\isccfg\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\irs\win32" !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/lib/irs/win32/libirs.vcxproj.filters.in0000644000470500017500000000447712664710322022667 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Header Files Header Files Header Files Header Files Header Files Header Files bind9-9.10.3.dfsg.P4/lib/irs/win32/libirs.def0000644000470500017500000000101112664710322017633 0ustar lamontlamontLIBRARY libirs ; Exported Functions EXPORTS irs_context_create irs_context_destroy irs_context_get irs_context_getappctx irs_context_getdnsclient irs_context_getdnsconf irs_context_getmctx irs_context_getresconf irs_context_gettask irs_context_gettaskmgr irs_context_gettimermgr irs_dnsconf_destroy irs_dnsconf_gettrustedkeys irs_dnsconf_load irs_freeaddrinfo irs_gai_strerror irs_getaddrinfo irs_getnameinfo irs_resconf_destroy irs_resconf_getnameservers irs_resconf_getndots irs_resconf_getsearchlist irs_resconf_load bind9-9.10.3.dfsg.P4/lib/irs/context.c0000644000470500017500000002265412664710322016575 0ustar lamontlamont/* * Copyright (C) 2009, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: context.c,v 1.3 2009/09/02 23:48:02 tbox Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define IRS_CONTEXT_MAGIC ISC_MAGIC('I', 'R', 'S', 'c') #define IRS_CONTEXT_VALID(c) ISC_MAGIC_VALID(c, IRS_CONTEXT_MAGIC) #ifndef RESOLV_CONF /*% location of resolve.conf */ #define RESOLV_CONF "/etc/resolv.conf" #endif #ifndef DNS_CONF /*% location of dns.conf */ #define DNS_CONF "/etc/dns.conf" #endif #ifndef ISC_PLATFORM_USETHREADS irs_context_t *irs_g_context = NULL; #else static isc_boolean_t thread_key_initialized = ISC_FALSE; static isc_mutex_t thread_key_mutex; static isc_thread_key_t irs_context_key; static isc_once_t once = ISC_ONCE_INIT; #endif struct irs_context { /* * An IRS context is a thread-specific object, and does not need to * be locked. */ unsigned int magic; isc_mem_t *mctx; isc_appctx_t *actx; isc_taskmgr_t *taskmgr; isc_task_t *task; isc_socketmgr_t *socketmgr; isc_timermgr_t *timermgr; dns_client_t *dnsclient; irs_resconf_t *resconf; irs_dnsconf_t *dnsconf; }; static void ctxs_destroy(isc_mem_t **mctxp, isc_appctx_t **actxp, isc_taskmgr_t **taskmgrp, isc_socketmgr_t **socketmgrp, isc_timermgr_t **timermgrp) { if (taskmgrp != NULL) isc_taskmgr_destroy(taskmgrp); if (timermgrp != NULL) isc_timermgr_destroy(timermgrp); if (socketmgrp != NULL) isc_socketmgr_destroy(socketmgrp); if (actxp != NULL) isc_appctx_destroy(actxp); if (mctxp != NULL) isc_mem_destroy(mctxp); } static isc_result_t ctxs_init(isc_mem_t **mctxp, isc_appctx_t **actxp, isc_taskmgr_t **taskmgrp, isc_socketmgr_t **socketmgrp, isc_timermgr_t **timermgrp) { isc_result_t result; result = isc_mem_create(0, 0, mctxp); if (result != ISC_R_SUCCESS) goto fail; result = isc_appctx_create(*mctxp, actxp); if (result != ISC_R_SUCCESS) goto fail; result = isc_taskmgr_createinctx(*mctxp, *actxp, 1, 0, taskmgrp); if (result != ISC_R_SUCCESS) goto fail; result = isc_socketmgr_createinctx(*mctxp, *actxp, socketmgrp); if (result != ISC_R_SUCCESS) goto fail; result = isc_timermgr_createinctx(*mctxp, *actxp, timermgrp); if (result != ISC_R_SUCCESS) goto fail; return (ISC_R_SUCCESS); fail: ctxs_destroy(mctxp, actxp, taskmgrp, socketmgrp, timermgrp); return (result); } #ifdef ISC_PLATFORM_USETHREADS static void free_specific_context(void *arg) { irs_context_t *context = arg; irs_context_destroy(&context); isc_thread_key_setspecific(irs_context_key, NULL); } static void thread_key_mutex_init(void) { RUNTIME_CHECK(isc_mutex_init(&thread_key_mutex) == ISC_R_SUCCESS); } static isc_result_t thread_key_init(void) { isc_result_t result; result = isc_once_do(&once, thread_key_mutex_init); if (result != ISC_R_SUCCESS) return (result); if (!thread_key_initialized) { LOCK(&thread_key_mutex); if (!thread_key_initialized && isc_thread_key_create(&irs_context_key, free_specific_context) != 0) { result = ISC_R_FAILURE; } else thread_key_initialized = ISC_TRUE; UNLOCK(&thread_key_mutex); } return (result); } #endif /* ISC_PLATFORM_USETHREADS */ isc_result_t irs_context_get(irs_context_t **contextp) { irs_context_t *context; isc_result_t result; REQUIRE(contextp != NULL && *contextp == NULL); #ifndef ISC_PLATFORM_USETHREADS if (irs_g_context == NULL) { result = irs_context_create(&irs_g_context); if (result != ISC_R_SUCCESS) return (result); } context = irs_g_context; #else result = thread_key_init(); if (result != ISC_R_SUCCESS) return (result); context = isc_thread_key_getspecific(irs_context_key); if (context == NULL) { result = irs_context_create(&context); if (result != ISC_R_SUCCESS) return (result); result = isc_thread_key_setspecific(irs_context_key, context); if (result != ISC_R_SUCCESS) { irs_context_destroy(&context); return (result); } } #endif /* ISC_PLATFORM_USETHREADS */ *contextp = context; return (ISC_R_SUCCESS); } isc_result_t irs_context_create(irs_context_t **contextp) { isc_result_t result; irs_context_t *context; isc_appctx_t *actx = NULL; isc_mem_t *mctx = NULL; isc_taskmgr_t *taskmgr = NULL; isc_socketmgr_t *socketmgr = NULL; isc_timermgr_t *timermgr = NULL; dns_client_t *client = NULL; isc_sockaddrlist_t *nameservers; irs_dnsconf_dnskeylist_t *trustedkeys; irs_dnsconf_dnskey_t *trustedkey; isc_lib_register(); result = dns_lib_init(); if (result != ISC_R_SUCCESS) return (result); result = ctxs_init(&mctx, &actx, &taskmgr, &socketmgr, &timermgr); if (result != ISC_R_SUCCESS) return (result); result = isc_app_ctxstart(actx); if (result != ISC_R_SUCCESS) { ctxs_destroy(&mctx, &actx, &taskmgr, &socketmgr, &timermgr); return (result); } context = isc_mem_get(mctx, sizeof(*context)); if (context == NULL) { ctxs_destroy(&mctx, &actx, &taskmgr, &socketmgr, &timermgr); return (ISC_R_NOMEMORY); } context->mctx = mctx; context->actx = actx; context->taskmgr = taskmgr; context->socketmgr = socketmgr; context->timermgr = timermgr; context->resconf = NULL; context->dnsconf = NULL; context->task = NULL; result = isc_task_create(taskmgr, 0, &context->task); if (result != ISC_R_SUCCESS) goto fail; /* Create a DNS client object */ result = dns_client_createx(mctx, actx, taskmgr, socketmgr, timermgr, 0, &client); if (result != ISC_R_SUCCESS) goto fail; context->dnsclient = client; /* Read resolver configuration file */ result = irs_resconf_load(mctx, RESOLV_CONF, &context->resconf); if (result != ISC_R_SUCCESS) goto fail; /* Set nameservers */ nameservers = irs_resconf_getnameservers(context->resconf); result = dns_client_setservers(client, dns_rdataclass_in, NULL, nameservers); if (result != ISC_R_SUCCESS) goto fail; /* Read advanced DNS configuration (if any) */ result = irs_dnsconf_load(mctx, DNS_CONF, &context->dnsconf); if (result != ISC_R_SUCCESS) goto fail; trustedkeys = irs_dnsconf_gettrustedkeys(context->dnsconf); for (trustedkey = ISC_LIST_HEAD(*trustedkeys); trustedkey != NULL; trustedkey = ISC_LIST_NEXT(trustedkey, link)) { result = dns_client_addtrustedkey(client, dns_rdataclass_in, trustedkey->keyname, trustedkey->keydatabuf); if (result != ISC_R_SUCCESS) goto fail; } context->magic = IRS_CONTEXT_MAGIC; *contextp = context; return (ISC_R_SUCCESS); fail: if (context->task != NULL) isc_task_detach(&context->task); if (context->resconf != NULL) irs_resconf_destroy(&context->resconf); if (context->dnsconf != NULL) irs_dnsconf_destroy(&context->dnsconf); if (client != NULL) dns_client_destroy(&client); ctxs_destroy(NULL, &actx, &taskmgr, &socketmgr, &timermgr); isc_mem_putanddetach(&mctx, context, sizeof(*context)); return (result); } void irs_context_destroy(irs_context_t **contextp) { irs_context_t *context; REQUIRE(contextp != NULL); context = *contextp; REQUIRE(IRS_CONTEXT_VALID(context)); isc_task_detach(&context->task); irs_dnsconf_destroy(&context->dnsconf); irs_resconf_destroy(&context->resconf); dns_client_destroy(&context->dnsclient); ctxs_destroy(NULL, &context->actx, &context->taskmgr, &context->socketmgr, &context->timermgr); context->magic = 0; isc_mem_putanddetach(&context->mctx, context, sizeof(*context)); *contextp = NULL; #ifndef ISC_PLATFORM_USETHREADS irs_g_context = NULL; #else (void)isc_thread_key_setspecific(irs_context_key, NULL); #endif } isc_mem_t * irs_context_getmctx(irs_context_t *context) { REQUIRE(IRS_CONTEXT_VALID(context)); return (context->mctx); } isc_appctx_t * irs_context_getappctx(irs_context_t *context) { REQUIRE(IRS_CONTEXT_VALID(context)); return (context->actx); } isc_taskmgr_t * irs_context_gettaskmgr(irs_context_t *context) { REQUIRE(IRS_CONTEXT_VALID(context)); return (context->taskmgr); } isc_timermgr_t * irs_context_gettimermgr(irs_context_t *context) { REQUIRE(IRS_CONTEXT_VALID(context)); return (context->timermgr); } isc_task_t * irs_context_gettask(irs_context_t *context) { REQUIRE(IRS_CONTEXT_VALID(context)); return (context->task); } dns_client_t * irs_context_getdnsclient(irs_context_t *context) { REQUIRE(IRS_CONTEXT_VALID(context)); return (context->dnsclient); } irs_resconf_t * irs_context_getresconf(irs_context_t *context) { REQUIRE(IRS_CONTEXT_VALID(context)); return (context->resconf); } irs_dnsconf_t * irs_context_getdnsconf(irs_context_t *context) { REQUIRE(IRS_CONTEXT_VALID(context)); return (context->dnsconf); } bind9-9.10.3.dfsg.P4/lib/irs/getnameinfo.c0000644000470500017500000002723512664710322017405 0ustar lamontlamont/* * Copyright (C) 2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * 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. Neither the name of the project 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 PROJECT 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 PROJECT 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. */ /** * getnameinfo() returns the hostname for the struct sockaddr sa which is * salen bytes long. The hostname is of length hostlen and is returned via * *host. The maximum length of the hostname is 1025 bytes: #NI_MAXHOST. * * The name of the service associated with the port number in sa is * returned in *serv. It is servlen bytes long. The maximum length of the * service name is #NI_MAXSERV - 32 bytes. * * The flags argument sets the following bits: * * \li #NI_NOFQDN: * A fully qualified domain name is not required for local hosts. * The local part of the fully qualified domain name is returned * instead. * * \li #NI_NUMERICHOST * Return the address in numeric form, as if calling inet_ntop(), * instead of a host name. * * \li #NI_NAMEREQD * A name is required. If the hostname cannot be found in the DNS * and this flag is set, a non-zero error code is returned. If the * hostname is not found and the flag is not set, the address is * returned in numeric form. * * \li #NI_NUMERICSERV * The service name is returned as a digit string representing the * port number. * * \li #NI_DGRAM * Specifies that the service being looked up is a datagram * service, and causes getservbyport() to be called with a second * argument of "udp" instead of its default of "tcp". This is * required for the few ports (512-514) that have different * services for UDP and TCP. * * \section getnameinfo_return Return Values * * getnameinfo() returns 0 on success or a non-zero error code if * an error occurs. * * \section getname_see See Also * * RFC3493, getservbyport(), * getnamebyaddr(). inet_ntop(). */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define SUCCESS 0 /*% afd structure definition */ static struct afd { int a_af; size_t a_addrlen; size_t a_socklen; } afdl [] = { /*! * First entry is linked last... */ { AF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in) }, { AF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6) }, {0, 0, 0}, }; /*! * The test against 0 is there to keep the Solaris compiler * from complaining about "end-of-loop code not reached". */ #define ERR(code) \ do { result = (code); \ if (result != 0) goto cleanup; \ } while (0) int getnameinfo(const struct sockaddr *sa, IRS_GETNAMEINFO_SOCKLEN_T salen, char *host, IRS_GETNAMEINFO_BUFLEN_T hostlen, char *serv, IRS_GETNAMEINFO_BUFLEN_T servlen, IRS_GETNAMEINFO_FLAGS_T flags) { struct afd *afd = NULL; struct servent *sp; unsigned short port = 0; #ifdef IRS_PLATFORM_HAVESALEN size_t len; #endif int family, i; const void *addr = NULL; char *p; #if 0 unsigned long v4a; unsigned char pfx; #endif char numserv[sizeof("65000")]; char numaddr[sizeof("abcd:abcd:abcd:abcd:abcd:abcd:255.255.255.255") + 1 + sizeof("4294967295")]; const char *proto; int result = SUCCESS; if (sa == NULL) ERR(EAI_FAIL); #ifdef IRS_PLATFORM_HAVESALEN len = sa->sa_len; if (len != salen) ERR(EAI_FAIL); #endif family = sa->sa_family; for (i = 0; afdl[i].a_af; i++) if (afdl[i].a_af == family) { afd = &afdl[i]; goto found; } ERR(EAI_FAMILY); found: if (salen != afd->a_socklen) ERR(EAI_FAIL); switch (family) { case AF_INET: port = ((const struct sockaddr_in *)sa)->sin_port; addr = &((const struct sockaddr_in *)sa)->sin_addr.s_addr; break; case AF_INET6: port = ((const struct sockaddr_in6 *)sa)->sin6_port; addr = ((const struct sockaddr_in6 *)sa)->sin6_addr.s6_addr; break; default: INSIST(0); } proto = (flags & NI_DGRAM) ? "udp" : "tcp"; if (serv == NULL || servlen == 0U) { /* * Caller does not want service. */ } else if ((flags & NI_NUMERICSERV) != 0 || (sp = getservbyport(port, proto)) == NULL) { snprintf(numserv, sizeof(numserv), "%d", ntohs(port)); if ((strlen(numserv) + 1) > servlen) ERR(EAI_OVERFLOW); strcpy(serv, numserv); } else { if ((strlen(sp->s_name) + 1) > servlen) ERR(EAI_OVERFLOW); strcpy(serv, sp->s_name); } #if 0 switch (sa->sa_family) { case AF_INET: v4a = ((struct sockaddr_in *)sa)->sin_addr.s_addr; if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) flags |= NI_NUMERICHOST; v4a >>= IN_CLASSA_NSHIFT; if (v4a == 0 || v4a == IN_LOOPBACKNET) flags |= NI_NUMERICHOST; break; case AF_INET6: pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[0]; if (pfx == 0 || pfx == 0xfe || pfx == 0xff) flags |= NI_NUMERICHOST; break; } #endif if (host == NULL || hostlen == 0U) { /* * do nothing in this case. * in case you are wondering if "&&" is more correct than * "||" here: RFC3493 says that host == NULL or hostlen == 0 * means that the caller does not want the result. */ } else if ((flags & NI_NUMERICHOST) != 0) { if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) == NULL) ERR(EAI_SYSTEM); #if defined(IRS_HAVE_SIN6_SCOPE_ID) if (afd->a_af == AF_INET6 && ((const struct sockaddr_in6 *)sa)->sin6_scope_id) { char *p = numaddr + strlen(numaddr); const char *stringscope = NULL; #ifdef VENDOR_SPECIFIC /* * Vendors may want to add support for * non-numeric scope identifier. */ stringscope = foo; #endif if (stringscope == NULL) { snprintf(p, sizeof(numaddr) - (p - numaddr), "%%%u", ((const struct sockaddr_in6 *)sa)->sin6_scope_id); } else { snprintf(p, sizeof(numaddr) - (p - numaddr), "%%%s", stringscope); } } #endif if (strlen(numaddr) + 1 > hostlen) ERR(EAI_OVERFLOW); strcpy(host, numaddr); } else { isc_netaddr_t netaddr; dns_fixedname_t ptrfname; dns_name_t *ptrname; irs_context_t *irsctx = NULL; dns_client_t *client; isc_boolean_t found = ISC_FALSE; dns_namelist_t answerlist; dns_rdataset_t *rdataset; isc_region_t hostregion; char hoststr[1024]; /* is this enough? */ isc_result_t iresult; /* Get IRS context and the associated DNS client object */ iresult = irs_context_get(&irsctx); if (iresult != ISC_R_SUCCESS) ERR(EAI_FAIL); client = irs_context_getdnsclient(irsctx); /* Make query name */ isc_netaddr_fromsockaddr(&netaddr, (const isc_sockaddr_t *)sa); dns_fixedname_init(&ptrfname); ptrname = dns_fixedname_name(&ptrfname); iresult = dns_byaddr_createptrname2(&netaddr, 0, ptrname); if (iresult != ISC_R_SUCCESS) ERR(EAI_FAIL); /* Get the PTR RRset */ ISC_LIST_INIT(answerlist); iresult = dns_client_resolve(client, ptrname, dns_rdataclass_in, dns_rdatatype_ptr, DNS_CLIENTRESOPT_ALLOWRUN, &answerlist); switch (iresult) { case ISC_R_SUCCESS: /* * a 'non-existent' error is not necessarily fatal for * getnameinfo(). */ case DNS_R_NCACHENXDOMAIN: case DNS_R_NCACHENXRRSET: break; case DNS_R_SIGINVALID: case DNS_R_SIGEXPIRED: case DNS_R_SIGFUTURE: case DNS_R_KEYUNAUTHORIZED: case DNS_R_MUSTBESECURE: case DNS_R_COVERINGNSEC: case DNS_R_NOTAUTHORITATIVE: case DNS_R_NOVALIDKEY: case DNS_R_NOVALIDDS: case DNS_R_NOVALIDSIG: ERR(EAI_INSECUREDATA); break; default: ERR(EAI_FAIL); } /* Parse the answer for the hostname */ for (ptrname = ISC_LIST_HEAD(answerlist); ptrname != NULL; ptrname = ISC_LIST_NEXT(ptrname, link)) { for (rdataset = ISC_LIST_HEAD(ptrname->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (!dns_rdataset_isassociated(rdataset)) continue; if (rdataset->type != dns_rdatatype_ptr) continue; for (iresult = dns_rdataset_first(rdataset); iresult == ISC_R_SUCCESS; iresult = dns_rdataset_next(rdataset)) { dns_rdata_t rdata; dns_rdata_ptr_t rdata_ptr; isc_buffer_t b; dns_rdata_init(&rdata); dns_rdataset_current(rdataset, &rdata); dns_rdata_tostruct(&rdata, &rdata_ptr, NULL); isc_buffer_init(&b, hoststr, sizeof(hoststr)); iresult = dns_name_totext(&rdata_ptr.ptr, ISC_TRUE, &b); dns_rdata_freestruct(&rdata_ptr); if (iresult == ISC_R_SUCCESS) { /* * We ignore the rest of the * answer. After all, * getnameinfo() can return * at most one hostname. */ found = ISC_TRUE; isc_buffer_usedregion( &b, &hostregion); goto ptrfound; } } } } ptrfound: dns_client_freeresanswer(client, &answerlist); if (found) { if ((flags & NI_NOFQDN) != 0) { p = strchr(hoststr, '.'); if (p) *p = '\0'; } if (hostregion.length + 1 > hostlen) ERR(EAI_OVERFLOW); snprintf(host, hostlen, "%.*s", (int)hostregion.length, (char *)hostregion.base); } else { if ((flags & NI_NAMEREQD) != 0) ERR(EAI_NONAME); if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) == NULL) ERR(EAI_SYSTEM); if ((strlen(numaddr) + 1) > hostlen) ERR(EAI_OVERFLOW); strcpy(host, numaddr); } } result = SUCCESS; cleanup: return (result); } bind9-9.10.3.dfsg.P4/lib/irs/api0000644000470500017500000000025612664710322015433 0ustar lamontlamont# LIBINTERFACE ranges # 9.6: 50-59, 110-119 # 9.7: 60-79 # 9.8: 80-89, 120-129 # 9.9: 90-109 # 9.9-sub: 130-139 # 9.10: 140-149 LIBINTERFACE = 141 LIBREVISION = 4 LIBAGE = 0 bind9-9.10.3.dfsg.P4/lib/Atffile0000644000470500017500000000015212664710322015432 0ustar lamontlamontContent-Type: application/X-atf-atffile; version="1" prop: test-suite = bind9 tp: dns tp: isc tp: lwres bind9-9.10.3.dfsg.P4/lib/isccfg/0002755000470500017500000000000012672612753015407 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isccfg/version.c0000644000470500017500000000217012664710322017226 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: version.c,v 1.7 2007/06/19 23:47:22 tbox Exp $ */ /*! \file */ #include const char cfg_version[] = VERSION; const unsigned int cfg_libinterface = LIBINTERFACE; const unsigned int cfg_librevision = LIBREVISION; const unsigned int cfg_libage = LIBAGE; bind9-9.10.3.dfsg.P4/lib/isccfg/namedconf.c0000644000470500017500000027314612664710322017510 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #define TOKEN_STRING(pctx) (pctx->token.value.as_textregion.base) /*% Check a return value. */ #define CHECK(op) \ do { result = (op); \ if (result != ISC_R_SUCCESS) goto cleanup; \ } while (0) /*% Clean up a configuration object if non-NULL. */ #define CLEANUP_OBJ(obj) \ do { if ((obj) != NULL) cfg_obj_destroy(pctx, &(obj)); } while (0) /*% * Forward declarations of static functions. */ static isc_result_t parse_enum_or_other(cfg_parser_t *pctx, const cfg_type_t *enumtype, const cfg_type_t *othertype, cfg_obj_t **ret); static void doc_enum_or_other(cfg_printer_t *pctx, const cfg_type_t *type); static isc_result_t parse_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); static isc_result_t parse_optional_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); static isc_result_t parse_updatepolicy(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); static void print_updatepolicy(cfg_printer_t *pctx, const cfg_obj_t *obj); static void doc_updatepolicy(cfg_printer_t *pctx, const cfg_type_t *type); static void print_keyvalue(cfg_printer_t *pctx, const cfg_obj_t *obj); static void doc_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type); static void doc_optional_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type); #ifdef HAVE_GEOIP static isc_result_t parse_geoip(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); static void print_geoip(cfg_printer_t *pctx, const cfg_obj_t *obj); static void doc_geoip(cfg_printer_t *pctx, const cfg_type_t *type); #endif /* HAVE_GEOIP */ static cfg_type_t cfg_type_acl; static cfg_type_t cfg_type_addrmatchelt; static cfg_type_t cfg_type_bracketed_aml; static cfg_type_t cfg_type_bracketed_namesockaddrkeylist; static cfg_type_t cfg_type_bracketed_dscpsockaddrlist; static cfg_type_t cfg_type_bracketed_sockaddrlist; static cfg_type_t cfg_type_bracketed_sockaddrnameportlist; static cfg_type_t cfg_type_controls; static cfg_type_t cfg_type_controls_sockaddr; static cfg_type_t cfg_type_destinationlist; static cfg_type_t cfg_type_dialuptype; static cfg_type_t cfg_type_ixfrdifftype; static cfg_type_t cfg_type_key; static cfg_type_t cfg_type_logfile; static cfg_type_t cfg_type_logging; static cfg_type_t cfg_type_logseverity; static cfg_type_t cfg_type_lwres; static cfg_type_t cfg_type_masterselement; static cfg_type_t cfg_type_maxttl; static cfg_type_t cfg_type_nameportiplist; static cfg_type_t cfg_type_negated; static cfg_type_t cfg_type_notifytype; static cfg_type_t cfg_type_optional_allow; static cfg_type_t cfg_type_optional_class; static cfg_type_t cfg_type_optional_facility; static cfg_type_t cfg_type_optional_keyref; static cfg_type_t cfg_type_optional_port; static cfg_type_t cfg_type_optional_dscp; static cfg_type_t cfg_type_optional_uint32; static cfg_type_t cfg_type_options; static cfg_type_t cfg_type_portiplist; static cfg_type_t cfg_type_querysource4; static cfg_type_t cfg_type_querysource6; static cfg_type_t cfg_type_querysource; static cfg_type_t cfg_type_server; static cfg_type_t cfg_type_server_key_kludge; static cfg_type_t cfg_type_size; static cfg_type_t cfg_type_sizenodefault; static cfg_type_t cfg_type_sockaddr4wild; static cfg_type_t cfg_type_sockaddr6wild; static cfg_type_t cfg_type_statschannels; static cfg_type_t cfg_type_view; static cfg_type_t cfg_type_viewopts; static cfg_type_t cfg_type_zone; static cfg_type_t cfg_type_zoneopts; static cfg_type_t cfg_type_filter_aaaa; static cfg_type_t cfg_type_dlz; /*% tkey-dhkey */ static cfg_tuplefielddef_t tkey_dhkey_fields[] = { { "name", &cfg_type_qstring, 0 }, { "keyid", &cfg_type_uint32, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_tkey_dhkey = { "tkey-dhkey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, tkey_dhkey_fields }; /*% listen-on */ static cfg_tuplefielddef_t listenon_fields[] = { { "port", &cfg_type_optional_port, 0 }, { "dscp", &cfg_type_optional_dscp, 0 }, { "acl", &cfg_type_bracketed_aml, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_listenon = { "listenon", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, listenon_fields }; /*% acl */ static cfg_tuplefielddef_t acl_fields[] = { { "name", &cfg_type_astring, 0 }, { "value", &cfg_type_bracketed_aml, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_acl = { "acl", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, acl_fields }; /*% masters */ static cfg_tuplefielddef_t masters_fields[] = { { "name", &cfg_type_astring, 0 }, { "port", &cfg_type_optional_port, 0 }, { "dscp", &cfg_type_optional_dscp, 0 }, { "addresses", &cfg_type_bracketed_namesockaddrkeylist, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_masters = { "masters", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, masters_fields }; /*% * "sockaddrkeylist", a list of socket addresses with optional keys * and an optional default port, as used in the masters option. * E.g., * "port 1234 { mymasters; 10.0.0.1 key foo; 1::2 port 69; }" */ static cfg_tuplefielddef_t namesockaddrkey_fields[] = { { "masterselement", &cfg_type_masterselement, 0 }, { "key", &cfg_type_optional_keyref, 0 }, { NULL, NULL, 0 }, }; static cfg_type_t cfg_type_namesockaddrkey = { "namesockaddrkey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, namesockaddrkey_fields }; static cfg_type_t cfg_type_bracketed_namesockaddrkeylist = { "bracketed_namesockaddrkeylist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_namesockaddrkey }; static cfg_tuplefielddef_t namesockaddrkeylist_fields[] = { { "port", &cfg_type_optional_port, 0 }, { "dscp", &cfg_type_optional_dscp, 0 }, { "addresses", &cfg_type_bracketed_namesockaddrkeylist, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_namesockaddrkeylist = { "sockaddrkeylist", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, namesockaddrkeylist_fields }; /*% * A list of socket addresses with an optional default port, as used * in the lwresd 'listen-on' option. E.g., "{ 10.0.0.1; 1::2 port 69; }" */ static cfg_tuplefielddef_t portiplist_fields[] = { { "port", &cfg_type_optional_port, 0 }, { "dscp", &cfg_type_optional_dscp, 0 }, { "addresses", &cfg_type_bracketed_dscpsockaddrlist, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_portiplist = { "portiplist", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, portiplist_fields }; /*% * A public key, as in the "pubkey" statement. */ static cfg_tuplefielddef_t pubkey_fields[] = { { "flags", &cfg_type_uint32, 0 }, { "protocol", &cfg_type_uint32, 0 }, { "algorithm", &cfg_type_uint32, 0 }, { "key", &cfg_type_qstring, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_pubkey = { "pubkey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, pubkey_fields }; /*% * A list of RR types, used in grant statements. * Note that the old parser allows quotes around the RR type names. */ static cfg_type_t cfg_type_rrtypelist = { "rrtypelist", cfg_parse_spacelist, cfg_print_spacelist, cfg_doc_terminal, &cfg_rep_list, &cfg_type_astring }; static const char *mode_enums[] = { "grant", "deny", NULL }; static cfg_type_t cfg_type_mode = { "mode", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, &mode_enums }; static isc_result_t parse_matchtype(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_string && strcasecmp(TOKEN_STRING(pctx), "zonesub") == 0) { pctx->flags |= CFG_PCTX_SKIP; } return (cfg_parse_enum(pctx, type, ret)); cleanup: return (result); } static isc_result_t parse_matchname(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *obj = NULL; if ((pctx->flags & CFG_PCTX_SKIP) != 0) { pctx->flags &= ~CFG_PCTX_SKIP; CHECK(cfg_parse_void(pctx, NULL, &obj)); } else result = cfg_parse_astring(pctx, type, &obj); *ret = obj; cleanup: return (result); } static void doc_matchname(cfg_printer_t *pctx, const cfg_type_t *type) { cfg_print_chars(pctx, "[ ", 2); cfg_doc_obj(pctx, type->of); cfg_print_chars(pctx, " ]", 2); } static const char *matchtype_enums[] = { "name", "subdomain", "wildcard", "self", "selfsub", "selfwild", "krb5-self", "ms-self", "krb5-subdomain", "ms-subdomain", "tcp-self", "6to4-self", "zonesub", "external", NULL }; static cfg_type_t cfg_type_matchtype = { "matchtype", parse_matchtype, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, &matchtype_enums }; static cfg_type_t cfg_type_matchname = { "optional_matchname", parse_matchname, cfg_print_ustring, &doc_matchname, &cfg_rep_tuple, &cfg_type_ustring }; /*% * A grant statement, used in the update policy. */ static cfg_tuplefielddef_t grant_fields[] = { { "mode", &cfg_type_mode, 0 }, { "identity", &cfg_type_astring, 0 }, /* domain name */ { "matchtype", &cfg_type_matchtype, 0 }, { "name", &cfg_type_matchname, 0 }, /* domain name */ { "types", &cfg_type_rrtypelist, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_grant = { "grant", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, grant_fields }; static cfg_type_t cfg_type_updatepolicy = { "update_policy", parse_updatepolicy, print_updatepolicy, doc_updatepolicy, &cfg_rep_list, &cfg_type_grant }; static isc_result_t parse_updatepolicy(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; CHECK(cfg_gettoken(pctx, 0)); if (pctx->token.type == isc_tokentype_special && pctx->token.value.as_char == '{') { cfg_ungettoken(pctx); return (cfg_parse_bracketed_list(pctx, type, ret)); } if (pctx->token.type == isc_tokentype_string && strcasecmp(TOKEN_STRING(pctx), "local") == 0) { cfg_obj_t *obj = NULL; CHECK(cfg_create_obj(pctx, &cfg_type_ustring, &obj)); obj->value.string.length = strlen("local"); obj->value.string.base = isc_mem_get(pctx->mctx, obj->value.string.length + 1); if (obj->value.string.base == NULL) { isc_mem_put(pctx->mctx, obj, sizeof(*obj)); return (ISC_R_NOMEMORY); } memmove(obj->value.string.base, "local", 5); obj->value.string.base[5] = '\0'; *ret = obj; return (ISC_R_SUCCESS); } cfg_ungettoken(pctx); return (ISC_R_UNEXPECTEDTOKEN); cleanup: return (result); } static void print_updatepolicy(cfg_printer_t *pctx, const cfg_obj_t *obj) { if (cfg_obj_isstring(obj)) cfg_print_ustring(pctx, obj); else cfg_print_bracketed_list(pctx, obj); } static void doc_updatepolicy(cfg_printer_t *pctx, const cfg_type_t *type) { cfg_print_cstr(pctx, "( local | { "); cfg_doc_obj(pctx, type->of); cfg_print_cstr(pctx, "; ... }"); } /*% * A view statement. */ static cfg_tuplefielddef_t view_fields[] = { { "name", &cfg_type_astring, 0 }, { "class", &cfg_type_optional_class, 0 }, { "options", &cfg_type_viewopts, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_view = { "view", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, view_fields }; /*% * A zone statement. */ static cfg_tuplefielddef_t zone_fields[] = { { "name", &cfg_type_astring, 0 }, { "class", &cfg_type_optional_class, 0 }, { "options", &cfg_type_zoneopts, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_zone = { "zone", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, zone_fields }; /*% * A "category" clause in the "logging" statement. */ static cfg_tuplefielddef_t category_fields[] = { { "name", &cfg_type_astring, 0 }, { "destinations", &cfg_type_destinationlist,0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_category = { "category", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, category_fields }; /*% * A dnssec key, as used in the "trusted-keys" statement. */ static cfg_tuplefielddef_t dnsseckey_fields[] = { { "name", &cfg_type_astring, 0 }, { "flags", &cfg_type_uint32, 0 }, { "protocol", &cfg_type_uint32, 0 }, { "algorithm", &cfg_type_uint32, 0 }, { "key", &cfg_type_qstring, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_dnsseckey = { "dnsseckey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, dnsseckey_fields }; /*% * A managed key initialization specifier, as used in the * "managed-keys" statement. */ static cfg_tuplefielddef_t managedkey_fields[] = { { "name", &cfg_type_astring, 0 }, { "init", &cfg_type_ustring, 0 }, /* must be literal "initial-key" */ { "flags", &cfg_type_uint32, 0 }, { "protocol", &cfg_type_uint32, 0 }, { "algorithm", &cfg_type_uint32, 0 }, { "key", &cfg_type_qstring, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_managedkey = { "managedkey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, managedkey_fields }; static keyword_type_t wild_class_kw = { "class", &cfg_type_ustring }; static cfg_type_t cfg_type_optional_wild_class = { "optional_wild_class", parse_optional_keyvalue, print_keyvalue, doc_optional_keyvalue, &cfg_rep_string, &wild_class_kw }; static keyword_type_t wild_type_kw = { "type", &cfg_type_ustring }; static cfg_type_t cfg_type_optional_wild_type = { "optional_wild_type", parse_optional_keyvalue, print_keyvalue, doc_optional_keyvalue, &cfg_rep_string, &wild_type_kw }; static keyword_type_t wild_name_kw = { "name", &cfg_type_qstring }; static cfg_type_t cfg_type_optional_wild_name = { "optional_wild_name", parse_optional_keyvalue, print_keyvalue, doc_optional_keyvalue, &cfg_rep_string, &wild_name_kw }; /*% * An rrset ordering element. */ static cfg_tuplefielddef_t rrsetorderingelement_fields[] = { { "class", &cfg_type_optional_wild_class, 0 }, { "type", &cfg_type_optional_wild_type, 0 }, { "name", &cfg_type_optional_wild_name, 0 }, { "order", &cfg_type_ustring, 0 }, /* must be literal "order" */ { "ordering", &cfg_type_ustring, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_rrsetorderingelement = { "rrsetorderingelement", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, rrsetorderingelement_fields }; /*% * A global or view "check-names" option. Note that the zone * "check-names" option has a different syntax. */ static const char *checktype_enums[] = { "master", "slave", "response", NULL }; static cfg_type_t cfg_type_checktype = { "checktype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, &checktype_enums }; static const char *checkmode_enums[] = { "fail", "warn", "ignore", NULL }; static cfg_type_t cfg_type_checkmode = { "checkmode", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, &checkmode_enums }; static const char *warn_enums[] = { "warn", "ignore", NULL }; static cfg_type_t cfg_type_warn = { "warn", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, &warn_enums }; static cfg_tuplefielddef_t checknames_fields[] = { { "type", &cfg_type_checktype, 0 }, { "mode", &cfg_type_checkmode, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_checknames = { "checknames", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, checknames_fields }; static cfg_type_t cfg_type_bracketed_dscpsockaddrlist = { "bracketed_sockaddrlist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_sockaddrdscp }; static cfg_type_t cfg_type_bracketed_sockaddrlist = { "bracketed_sockaddrlist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_sockaddr }; static const char *autodnssec_enums[] = { "allow", "maintain", "off", NULL }; static cfg_type_t cfg_type_autodnssec = { "autodnssec", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, &autodnssec_enums }; static const char *dnssecupdatemode_enums[] = { "maintain", "no-resign", NULL }; static cfg_type_t cfg_type_dnssecupdatemode = { "dnssecupdatemode", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, &dnssecupdatemode_enums }; static const char *updatemethods_enums[] = { "increment", "unixtime", NULL }; static cfg_type_t cfg_type_updatemethod = { "updatemethod", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, &updatemethods_enums }; /* * zone-statistics: full, terse, or none. * * for backward compatibility, we also support boolean values. * yes represents "full", no represents "terse". in the future we * may change no to mean "none". */ static const char *zonestat_enums[] = { "full", "terse", "none", NULL }; static isc_result_t parse_zonestat(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret)); } static cfg_type_t cfg_type_zonestat = { "zonestat", parse_zonestat, cfg_print_ustring, doc_enum_or_other, &cfg_rep_string, zonestat_enums }; static cfg_type_t cfg_type_rrsetorder = { "rrsetorder", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_rrsetorderingelement }; static keyword_type_t dscp_kw = { "dscp", &cfg_type_uint32 }; static cfg_type_t cfg_type_optional_dscp = { "optional_dscp", parse_optional_keyvalue, print_keyvalue, doc_optional_keyvalue, &cfg_rep_uint32, &dscp_kw }; static keyword_type_t port_kw = { "port", &cfg_type_uint32 }; static cfg_type_t cfg_type_optional_port = { "optional_port", parse_optional_keyvalue, print_keyvalue, doc_optional_keyvalue, &cfg_rep_uint32, &port_kw }; /*% A list of keys, as in the "key" clause of the controls statement. */ static cfg_type_t cfg_type_keylist = { "keylist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_astring }; /*% A list of dnssec keys, as in "trusted-keys" */ static cfg_type_t cfg_type_dnsseckeys = { "dnsseckeys", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_dnsseckey }; /*% * A list of managed key entries, as in "trusted-keys". Currently * (9.7.0) this has a format similar to dnssec keys, except the keyname * is followed by the keyword "initial-key". In future releases, this * keyword may take other values indicating different methods for the * key to be initialized. */ static cfg_type_t cfg_type_managedkeys = { "managedkeys", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_managedkey }; static const char *forwardtype_enums[] = { "first", "only", NULL }; static cfg_type_t cfg_type_forwardtype = { "forwardtype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, &forwardtype_enums }; static const char *zonetype_enums[] = { "master", "slave", "stub", "static-stub", "hint", "forward", "delegation-only", "redirect", NULL }; static cfg_type_t cfg_type_zonetype = { "zonetype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, &zonetype_enums }; static const char *loglevel_enums[] = { "critical", "error", "warning", "notice", "info", "dynamic", NULL }; static cfg_type_t cfg_type_loglevel = { "loglevel", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, &loglevel_enums }; static const char *transferformat_enums[] = { "many-answers", "one-answer", NULL }; static cfg_type_t cfg_type_transferformat = { "transferformat", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, &transferformat_enums }; /*% * The special keyword "none", as used in the pid-file option. */ static void print_none(cfg_printer_t *pctx, const cfg_obj_t *obj) { UNUSED(obj); cfg_print_cstr(pctx, "none"); } static cfg_type_t cfg_type_none = { "none", NULL, print_none, NULL, &cfg_rep_void, NULL }; /*% * A quoted string or the special keyword "none". Used in the pid-file option. */ static isc_result_t parse_qstringornone(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING)); if (pctx->token.type == isc_tokentype_string && strcasecmp(TOKEN_STRING(pctx), "none") == 0) return (cfg_create_obj(pctx, &cfg_type_none, ret)); cfg_ungettoken(pctx); return (cfg_parse_qstring(pctx, type, ret)); cleanup: return (result); } static void doc_qstringornone(cfg_printer_t *pctx, const cfg_type_t *type) { UNUSED(type); cfg_print_cstr(pctx, "( | none )"); } static cfg_type_t cfg_type_qstringornone = { "qstringornone", parse_qstringornone, NULL, doc_qstringornone, NULL, NULL }; /*% * A boolean ("yes" or "no"), or the special keyword "auto". * Used in the dnssec-validation option. */ static void print_auto(cfg_printer_t *pctx, const cfg_obj_t *obj) { UNUSED(obj); cfg_print_cstr(pctx, "auto"); } static cfg_type_t cfg_type_auto = { "auto", NULL, print_auto, NULL, &cfg_rep_void, NULL }; static isc_result_t parse_boolorauto(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING)); if (pctx->token.type == isc_tokentype_string && strcasecmp(TOKEN_STRING(pctx), "auto") == 0) return (cfg_create_obj(pctx, &cfg_type_auto, ret)); cfg_ungettoken(pctx); return (cfg_parse_boolean(pctx, type, ret)); cleanup: return (result); } static void print_boolorauto(cfg_printer_t *pctx, const cfg_obj_t *obj) { if (obj->type->rep == &cfg_rep_void) cfg_print_chars(pctx, "auto", 4); else if (obj->value.boolean) cfg_print_chars(pctx, "yes", 3); else cfg_print_chars(pctx, "no", 2); } static void doc_boolorauto(cfg_printer_t *pctx, const cfg_type_t *type) { UNUSED(type); cfg_print_cstr(pctx, "( yes | no | auto )"); } static cfg_type_t cfg_type_boolorauto = { "boolorauto", parse_boolorauto, print_boolorauto, doc_boolorauto, NULL, NULL }; /*% * keyword hostname */ static void print_hostname(cfg_printer_t *pctx, const cfg_obj_t *obj) { UNUSED(obj); cfg_print_cstr(pctx, "hostname"); } static cfg_type_t cfg_type_hostname = { "hostname", NULL, print_hostname, NULL, &cfg_rep_boolean, NULL }; /*% * "server-id" argument. */ static isc_result_t parse_serverid(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING)); if (pctx->token.type == isc_tokentype_string && strcasecmp(TOKEN_STRING(pctx), "none") == 0) return (cfg_create_obj(pctx, &cfg_type_none, ret)); if (pctx->token.type == isc_tokentype_string && strcasecmp(TOKEN_STRING(pctx), "hostname") == 0) { result = cfg_create_obj(pctx, &cfg_type_hostname, ret); if (result == ISC_R_SUCCESS) (*ret)->value.boolean = ISC_TRUE; return (result); } cfg_ungettoken(pctx); return (cfg_parse_qstring(pctx, type, ret)); cleanup: return (result); } static void doc_serverid(cfg_printer_t *pctx, const cfg_type_t *type) { UNUSED(type); cfg_print_cstr(pctx, "( | none | hostname )"); } static cfg_type_t cfg_type_serverid = { "serverid", parse_serverid, NULL, doc_serverid, NULL, NULL }; /*% * Port list. */ static cfg_tuplefielddef_t porttuple_fields[] = { { "loport", &cfg_type_uint32, 0 }, { "hiport", &cfg_type_uint32, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_porttuple = { "porttuple", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, porttuple_fields }; static isc_result_t parse_port(cfg_parser_t *pctx, cfg_obj_t **ret) { isc_result_t result; CHECK(cfg_parse_uint32(pctx, NULL, ret)); if ((*ret)->value.uint32 > 0xffff) { cfg_parser_error(pctx, CFG_LOG_NEAR, "invalid port"); cfg_obj_destroy(pctx, ret); result = ISC_R_RANGE; } cleanup: return (result); } static isc_result_t parse_portrange(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *obj = NULL; UNUSED(type); CHECK(cfg_peektoken(pctx, ISC_LEXOPT_NUMBER | ISC_LEXOPT_CNUMBER)); if (pctx->token.type == isc_tokentype_number) CHECK(parse_port(pctx, ret)); else { CHECK(cfg_gettoken(pctx, 0)); if (pctx->token.type != isc_tokentype_string || strcasecmp(TOKEN_STRING(pctx), "range") != 0) { cfg_parser_error(pctx, CFG_LOG_NEAR, "expected integer or 'range'"); return (ISC_R_UNEXPECTEDTOKEN); } CHECK(cfg_create_tuple(pctx, &cfg_type_porttuple, &obj)); CHECK(parse_port(pctx, &obj->value.tuple[0])); CHECK(parse_port(pctx, &obj->value.tuple[1])); if (obj->value.tuple[0]->value.uint32 > obj->value.tuple[1]->value.uint32) { cfg_parser_error(pctx, CFG_LOG_NOPREP, "low port '%u' must not be larger " "than high port", obj->value.tuple[0]->value.uint32); result = ISC_R_RANGE; goto cleanup; } *ret = obj; obj = NULL; } cleanup: if (obj != NULL) cfg_obj_destroy(pctx, &obj); return (result); } static cfg_type_t cfg_type_portrange = { "portrange", parse_portrange, NULL, cfg_doc_terminal, NULL, NULL }; static cfg_type_t cfg_type_bracketed_portlist = { "bracketed_sockaddrlist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_portrange }; #ifdef ENABLE_FETCHLIMIT /*% * fetch-quota-params */ static cfg_tuplefielddef_t fetchquota_fields[] = { { "frequency", &cfg_type_uint32, 0 }, { "low", &cfg_type_fixedpoint, 0 }, { "high", &cfg_type_fixedpoint, 0 }, { "discount", &cfg_type_fixedpoint, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_fetchquota = { "fetchquota", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, fetchquota_fields }; /*% * fetches-per-server or fetches-per-zone */ static const char *response_enums[] = { "drop", "fail", NULL }; static isc_result_t parse_optional_response(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { return (parse_enum_or_other(pctx, type, &cfg_type_void, ret)); } static void doc_optional_response(cfg_printer_t *pctx, const cfg_type_t *type) { UNUSED(type); cfg_print_cstr(pctx, "[ ( drop | fail ) ]"); } static cfg_type_t cfg_type_responsetype = { "responsetype", parse_optional_response, cfg_print_ustring, doc_optional_response, &cfg_rep_string, response_enums }; static cfg_tuplefielddef_t fetchesper_fields[] = { { "fetches", &cfg_type_uint32, 0 }, { "response", &cfg_type_responsetype, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_fetchesper = { "fetchesper", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, fetchesper_fields }; #endif /* ENABLE_FETCHLIMIT */ /*% * Clauses that can be found within the top level of the named.conf * file only. */ static cfg_clausedef_t namedconf_clauses[] = { { "options", &cfg_type_options, 0 }, { "controls", &cfg_type_controls, CFG_CLAUSEFLAG_MULTI }, { "acl", &cfg_type_acl, CFG_CLAUSEFLAG_MULTI }, { "masters", &cfg_type_masters, CFG_CLAUSEFLAG_MULTI }, { "logging", &cfg_type_logging, 0 }, { "view", &cfg_type_view, CFG_CLAUSEFLAG_MULTI }, { "lwres", &cfg_type_lwres, CFG_CLAUSEFLAG_MULTI }, { "statistics-channels", &cfg_type_statschannels, CFG_CLAUSEFLAG_MULTI }, { NULL, NULL, 0 } }; /*% * Clauses that can occur at the top level or in the view * statement, but not in the options block. */ static cfg_clausedef_t namedconf_or_view_clauses[] = { { "key", &cfg_type_key, CFG_CLAUSEFLAG_MULTI }, { "zone", &cfg_type_zone, CFG_CLAUSEFLAG_MULTI }, { "dlz", &cfg_type_dlz, CFG_CLAUSEFLAG_MULTI }, { "server", &cfg_type_server, CFG_CLAUSEFLAG_MULTI }, { "trusted-keys", &cfg_type_dnsseckeys, CFG_CLAUSEFLAG_MULTI }, { "managed-keys", &cfg_type_managedkeys, CFG_CLAUSEFLAG_MULTI }, { NULL, NULL, 0 } }; /*% * Clauses that can occur in the bind.keys file. */ static cfg_clausedef_t bindkeys_clauses[] = { { "trusted-keys", &cfg_type_dnsseckeys, CFG_CLAUSEFLAG_MULTI }, { "managed-keys", &cfg_type_managedkeys, CFG_CLAUSEFLAG_MULTI }, { NULL, NULL, 0 } }; /*% * Clauses that can be found within the 'options' statement. */ static cfg_clausedef_t options_clauses[] = { { "automatic-interface-scan", &cfg_type_boolean, 0 }, { "avoid-v4-udp-ports", &cfg_type_bracketed_portlist, 0 }, { "avoid-v6-udp-ports", &cfg_type_bracketed_portlist, 0 }, { "bindkeys-file", &cfg_type_qstring, 0 }, { "blackhole", &cfg_type_bracketed_aml, 0 }, { "coresize", &cfg_type_size, 0 }, { "datasize", &cfg_type_size, 0 }, { "session-keyfile", &cfg_type_qstringornone, 0 }, { "session-keyname", &cfg_type_astring, 0 }, { "session-keyalg", &cfg_type_astring, 0 }, { "deallocate-on-exit", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, { "directory", &cfg_type_qstring, CFG_CLAUSEFLAG_CALLBACK }, { "dscp", &cfg_type_uint32, 0 }, { "dump-file", &cfg_type_qstring, 0 }, { "fake-iquery", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, { "files", &cfg_type_size, 0 }, { "flush-zones-on-shutdown", &cfg_type_boolean, 0 }, #ifdef HAVE_GEOIP { "geoip-directory", &cfg_type_qstringornone, 0 }, #else { "geoip-directory", &cfg_type_qstringornone, CFG_CLAUSEFLAG_NOTCONFIGURED }, #endif /* HAVE_GEOIP */ { "has-old-clients", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, { "heartbeat-interval", &cfg_type_uint32, 0 }, { "host-statistics", &cfg_type_boolean, CFG_CLAUSEFLAG_NOTIMP }, { "host-statistics-max", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTIMP }, { "hostname", &cfg_type_qstringornone, 0 }, { "interface-interval", &cfg_type_uint32, 0 }, { "listen-on", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI }, { "listen-on-v6", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI }, #ifdef ISC_PLATFORM_USESIT { "sit-secret", &cfg_type_sstring, 0 }, #else { "sit-secret", &cfg_type_sstring, CFG_CLAUSEFLAG_NOTCONFIGURED }, #endif { "managed-keys-directory", &cfg_type_qstring, 0 }, { "match-mapped-addresses", &cfg_type_boolean, 0 }, { "max-rsa-exponent-size", &cfg_type_uint32, 0 }, { "memstatistics-file", &cfg_type_qstring, 0 }, { "memstatistics", &cfg_type_boolean, 0 }, { "multiple-cnames", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, { "named-xfer", &cfg_type_qstring, CFG_CLAUSEFLAG_OBSOLETE }, { "pid-file", &cfg_type_qstringornone, 0 }, { "port", &cfg_type_uint32, 0 }, { "querylog", &cfg_type_boolean, 0 }, { "recursing-file", &cfg_type_qstring, 0 }, { "random-device", &cfg_type_qstring, 0 }, { "recursive-clients", &cfg_type_uint32, 0 }, { "reserved-sockets", &cfg_type_uint32, 0 }, { "secroots-file", &cfg_type_qstring, 0 }, { "serial-queries", &cfg_type_uint32, CFG_CLAUSEFLAG_OBSOLETE }, { "serial-query-rate", &cfg_type_uint32, 0 }, { "server-id", &cfg_type_serverid, 0 }, { "stacksize", &cfg_type_size, 0 }, { "statistics-file", &cfg_type_qstring, 0 }, { "statistics-interval", &cfg_type_uint32, CFG_CLAUSEFLAG_NYI }, { "tcp-clients", &cfg_type_uint32, 0 }, { "tcp-listen-queue", &cfg_type_uint32, 0 }, { "tkey-dhkey", &cfg_type_tkey_dhkey, 0 }, { "tkey-gssapi-credential", &cfg_type_qstring, 0 }, { "tkey-gssapi-keytab", &cfg_type_qstring, 0 }, { "tkey-domain", &cfg_type_qstring, 0 }, { "transfers-per-ns", &cfg_type_uint32, 0 }, { "transfers-in", &cfg_type_uint32, 0 }, { "transfers-out", &cfg_type_uint32, 0 }, { "treat-cr-as-space", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, { "use-id-pool", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, { "use-ixfr", &cfg_type_boolean, 0 }, { "use-v4-udp-ports", &cfg_type_bracketed_portlist, 0 }, { "use-v6-udp-ports", &cfg_type_bracketed_portlist, 0 }, { "version", &cfg_type_qstringornone, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_namelist = { "namelist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_qstring }; static keyword_type_t exclude_kw = { "exclude", &cfg_type_namelist }; static cfg_type_t cfg_type_optional_exclude = { "optional_exclude", parse_optional_keyvalue, print_keyvalue, doc_optional_keyvalue, &cfg_rep_list, &exclude_kw }; static keyword_type_t exceptionnames_kw = { "except-from", &cfg_type_namelist }; static cfg_type_t cfg_type_optional_exceptionnames = { "optional_allow", parse_optional_keyvalue, print_keyvalue, doc_optional_keyvalue, &cfg_rep_list, &exceptionnames_kw }; static cfg_tuplefielddef_t denyaddresses_fields[] = { { "acl", &cfg_type_bracketed_aml, 0 }, { "except-from", &cfg_type_optional_exceptionnames, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_denyaddresses = { "denyaddresses", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, denyaddresses_fields }; static cfg_tuplefielddef_t denyaliases_fields[] = { { "name", &cfg_type_namelist, 0 }, { "except-from", &cfg_type_optional_exceptionnames, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_denyaliases = { "denyaliases", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, denyaliases_fields }; static cfg_type_t cfg_type_algorithmlist = { "algorithmlist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_astring }; static cfg_tuplefielddef_t disablealgorithm_fields[] = { { "name", &cfg_type_astring, 0 }, { "algorithms", &cfg_type_algorithmlist, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_disablealgorithm = { "disablealgorithm", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, disablealgorithm_fields }; static cfg_type_t cfg_type_dsdigestlist = { "dsdigestlist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_astring }; static cfg_tuplefielddef_t disabledsdigest_fields[] = { { "name", &cfg_type_astring, 0 }, { "digests", &cfg_type_dsdigestlist, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_disabledsdigest = { "disabledsdigest", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, disabledsdigest_fields }; static cfg_tuplefielddef_t mustbesecure_fields[] = { { "name", &cfg_type_astring, 0 }, { "value", &cfg_type_boolean, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_mustbesecure = { "mustbesecure", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, mustbesecure_fields }; static const char *masterformat_enums[] = { "text", "raw", "map", NULL }; static cfg_type_t cfg_type_masterformat = { "masterformat", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, &masterformat_enums }; /*% * response-policy { * zone [ policy (given|disabled|passthru|drop|tcp-only| * nxdomain|nodata|cname ) ] * [ recursive-only yes|no ] [ max-policy-ttl number ] ; * } [ recursive-only yes|no ] [ max-policy-ttl number ] * [ break-dnssec yes|no ] [ min-ns-dots number ] * [ qname-wait-recurse yes|no ] ; */ static void doc_rpz_policy(cfg_printer_t *pctx, const cfg_type_t *type) { const char * const *p; /* * This is cfg_doc_enum() without the trailing " )". */ cfg_print_chars(pctx, "( ", 2); for (p = type->of; *p != NULL; p++) { cfg_print_cstr(pctx, *p); if (p[1] != NULL) cfg_print_chars(pctx, " | ", 3); } } static void doc_rpz_cname(cfg_printer_t *pctx, const cfg_type_t *type) { cfg_doc_terminal(pctx, type); cfg_print_chars(pctx, " )", 2); } /* * Parse * given|disabled|passthru|drop|tcp-only|nxdomain|nodata|cname */ static isc_result_t cfg_parse_rpz_policy(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *obj; const cfg_tuplefielddef_t *fields; CHECK(cfg_create_tuple(pctx, type, &obj)); fields = type->of; CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0])); /* * parse cname domain only after "policy cname" */ if (strcasecmp("cname", cfg_obj_asstring(obj->value.tuple[0])) != 0) { CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[1])); } else { CHECK(cfg_parse_obj(pctx, fields[1].type, &obj->value.tuple[1])); } *ret = obj; return (ISC_R_SUCCESS); cleanup: CLEANUP_OBJ(obj); return (result); } /* * Parse a tuple consisting of any kind of required field followed * by 2 or more optional keyvalues that can be in any order. */ static isc_result_t cfg_parse_kv_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { const cfg_tuplefielddef_t *fields, *f; cfg_obj_t *obj; int fn; isc_result_t result; obj = NULL; CHECK(cfg_create_tuple(pctx, type, &obj)); /* * The zone first field is required and always first. */ fields = type->of; CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0])); for (;;) { CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING)); if (pctx->token.type != isc_tokentype_string) break; for (fn = 1, f = &fields[1]; ; ++fn, ++f) { if (f->name == NULL) { cfg_parser_error(pctx, 0, "unexpected '%s'", TOKEN_STRING(pctx)); result = ISC_R_UNEXPECTEDTOKEN; goto cleanup; } if (obj->value.tuple[fn] == NULL && strcasecmp(f->name, TOKEN_STRING(pctx)) == 0) break; } CHECK(cfg_gettoken(pctx, 0)); CHECK(cfg_parse_obj(pctx, f->type, &obj->value.tuple[fn])); } for (fn = 1, f = &fields[1]; f->name != NULL; ++fn, ++f) { if (obj->value.tuple[fn] == NULL) CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[fn])); } *ret = obj; return (ISC_R_SUCCESS); cleanup: CLEANUP_OBJ(obj); return (result); } static void cfg_print_kv_tuple(cfg_printer_t *pctx, const cfg_obj_t *obj) { unsigned int i; const cfg_tuplefielddef_t *fields, *f; const cfg_obj_t *fieldobj; fields = obj->type->of; for (f = fields, i = 0; f->name != NULL; f++, i++) { fieldobj = obj->value.tuple[i]; if (fieldobj->type->print == cfg_print_void) continue; if (i != 0) { cfg_print_chars(pctx, " ", 1); cfg_print_cstr(pctx, f->name); cfg_print_chars(pctx, " ", 1); } cfg_print_obj(pctx, fieldobj); } } static void cfg_doc_kv_tuple(cfg_printer_t *pctx, const cfg_type_t *type) { const cfg_tuplefielddef_t *fields, *f; fields = type->of; for (f = fields; f->name != NULL; f++) { if (f != fields) { cfg_print_chars(pctx, " [ ", 3); cfg_print_cstr(pctx, f->name); if (f->type->doc != cfg_doc_void) cfg_print_chars(pctx, " ", 1); } cfg_doc_obj(pctx, f->type); if (f != fields) cfg_print_chars(pctx, " ]", 2); } } static keyword_type_t zone_kw = {"zone", &cfg_type_qstring}; static cfg_type_t cfg_type_rpz_zone = { "zone", parse_keyvalue, print_keyvalue, doc_keyvalue, &cfg_rep_string, &zone_kw }; /* * "no-op" is an obsolete equivalent of "passthru". */ static const char *rpz_policies[] = { "given", "disabled", "passthru", "no-op", "drop", "tcp-only", "nxdomain", "nodata", "cname", NULL }; static cfg_type_t cfg_type_rpz_policy_name = { "policy name", cfg_parse_enum, cfg_print_ustring, doc_rpz_policy, &cfg_rep_string, &rpz_policies }; static cfg_type_t cfg_type_rpz_cname = { "quoted_string", cfg_parse_astring, NULL, doc_rpz_cname, &cfg_rep_string, NULL }; static cfg_tuplefielddef_t rpz_policy_fields[] = { { "policy name", &cfg_type_rpz_policy_name, 0 }, { "cname", &cfg_type_rpz_cname, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_rpz_policy = { "policy tuple", cfg_parse_rpz_policy, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, rpz_policy_fields }; static cfg_tuplefielddef_t rpz_zone_fields[] = { { "zone name", &cfg_type_rpz_zone, 0 }, { "policy", &cfg_type_rpz_policy, 0 }, { "recursive-only", &cfg_type_boolean, 0 }, { "max-policy-ttl", &cfg_type_uint32, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_rpz_tuple = { "rpz tuple", cfg_parse_kv_tuple, cfg_print_kv_tuple, cfg_doc_kv_tuple, &cfg_rep_tuple, rpz_zone_fields }; static cfg_type_t cfg_type_rpz_list = { "zone list", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_rpz_tuple }; static cfg_tuplefielddef_t rpz_fields[] = { { "zone list", &cfg_type_rpz_list, 0 }, { "recursive-only", &cfg_type_boolean, 0 }, { "break-dnssec", &cfg_type_boolean, 0 }, { "max-policy-ttl", &cfg_type_uint32, 0 }, { "min-ns-dots", &cfg_type_uint32, 0 }, { "qname-wait-recurse", &cfg_type_boolean, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_rpz = { "rpz", cfg_parse_kv_tuple, cfg_print_kv_tuple, cfg_doc_kv_tuple, &cfg_rep_tuple, rpz_fields }; /* * rate-limit */ static cfg_clausedef_t rrl_clauses[] = { { "responses-per-second", &cfg_type_uint32, 0 }, { "referrals-per-second", &cfg_type_uint32, 0 }, { "nodata-per-second", &cfg_type_uint32, 0 }, { "nxdomains-per-second", &cfg_type_uint32, 0 }, { "errors-per-second", &cfg_type_uint32, 0 }, { "all-per-second", &cfg_type_uint32, 0 }, { "slip", &cfg_type_uint32, 0 }, { "window", &cfg_type_uint32, 0 }, { "log-only", &cfg_type_boolean, 0 }, { "qps-scale", &cfg_type_uint32, 0 }, { "ipv4-prefix-length", &cfg_type_uint32, 0 }, { "ipv6-prefix-length", &cfg_type_uint32, 0 }, { "exempt-clients", &cfg_type_bracketed_aml, 0 }, { "max-table-size", &cfg_type_uint32, 0 }, { "min-table-size", &cfg_type_uint32, 0 }, { NULL, NULL, 0 } }; static cfg_clausedef_t *rrl_clausesets[] = { rrl_clauses, NULL }; static cfg_type_t cfg_type_rrl = { "rate-limit", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, rrl_clausesets }; /*% * dnssec-lookaside */ static void print_lookaside(cfg_printer_t *pctx, const cfg_obj_t *obj) { const cfg_obj_t *domain = obj->value.tuple[0]; if (domain->value.string.length == 4 && strncmp(domain->value.string.base, "auto", 4) == 0) cfg_print_cstr(pctx, "auto"); else cfg_print_tuple(pctx, obj); } static void doc_lookaside(cfg_printer_t *pctx, const cfg_type_t *type) { UNUSED(type); cfg_print_cstr(pctx, "( trust-anchor | auto | no )"); } static keyword_type_t trustanchor_kw = { "trust-anchor", &cfg_type_astring }; static cfg_type_t cfg_type_optional_trustanchor = { "optional_trustanchor", parse_optional_keyvalue, print_keyvalue, doc_keyvalue, &cfg_rep_string, &trustanchor_kw }; static cfg_tuplefielddef_t lookaside_fields[] = { { "domain", &cfg_type_astring, 0 }, { "trust-anchor", &cfg_type_optional_trustanchor, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_lookaside = { "lookaside", cfg_parse_tuple, print_lookaside, doc_lookaside, &cfg_rep_tuple, lookaside_fields }; static isc_result_t parse_optional_uint32(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; UNUSED(type); CHECK(cfg_peektoken(pctx, ISC_LEXOPT_NUMBER | ISC_LEXOPT_CNUMBER)); if (pctx->token.type == isc_tokentype_number) { CHECK(cfg_parse_obj(pctx, &cfg_type_uint32, ret)); } else { CHECK(cfg_parse_obj(pctx, &cfg_type_void, ret)); } cleanup: return (result); } static void doc_optional_uint32(cfg_printer_t *pctx, const cfg_type_t *type) { UNUSED(type); cfg_print_cstr(pctx, "[ ]"); } static cfg_type_t cfg_type_optional_uint32 = { "optional_uint32", parse_optional_uint32, NULL, doc_optional_uint32, NULL, NULL }; static cfg_tuplefielddef_t prefetch_fields[] = { { "trigger", &cfg_type_uint32, 0 }, { "eligible", &cfg_type_optional_uint32, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_prefetch = { "prefetch", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, prefetch_fields }; /* * DNS64. */ static cfg_clausedef_t dns64_clauses[] = { { "clients", &cfg_type_bracketed_aml, 0 }, { "mapped", &cfg_type_bracketed_aml, 0 }, { "exclude", &cfg_type_bracketed_aml, 0 }, { "suffix", &cfg_type_netaddr6, 0 }, { "recursive-only", &cfg_type_boolean, 0 }, { "break-dnssec", &cfg_type_boolean, 0 }, { NULL, NULL, 0 }, }; static cfg_clausedef_t * dns64_clausesets[] = { dns64_clauses, NULL }; static cfg_type_t cfg_type_dns64 = { "dns64", cfg_parse_netprefix_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, dns64_clausesets }; /*% * Clauses that can be found within the 'view' statement, * with defaults in the 'options' statement. */ static cfg_clausedef_t view_clauses[] = { { "acache-cleaning-interval", &cfg_type_uint32, 0 }, { "acache-enable", &cfg_type_boolean, 0 }, { "additional-from-auth", &cfg_type_boolean, 0 }, { "additional-from-cache", &cfg_type_boolean, 0 }, { "allow-new-zones", &cfg_type_boolean, 0 }, { "allow-query-cache", &cfg_type_bracketed_aml, 0 }, { "allow-query-cache-on", &cfg_type_bracketed_aml, 0 }, { "allow-recursion", &cfg_type_bracketed_aml, 0 }, { "allow-recursion-on", &cfg_type_bracketed_aml, 0 }, { "allow-v6-synthesis", &cfg_type_bracketed_aml, CFG_CLAUSEFLAG_OBSOLETE }, { "attach-cache", &cfg_type_astring, 0 }, { "auth-nxdomain", &cfg_type_boolean, CFG_CLAUSEFLAG_NEWDEFAULT }, { "cache-file", &cfg_type_qstring, 0 }, { "check-names", &cfg_type_checknames, CFG_CLAUSEFLAG_MULTI }, { "cleaning-interval", &cfg_type_uint32, 0 }, { "clients-per-query", &cfg_type_uint32, 0 }, { "deny-answer-addresses", &cfg_type_denyaddresses, 0 }, { "deny-answer-aliases", &cfg_type_denyaliases, 0 }, { "disable-algorithms", &cfg_type_disablealgorithm, CFG_CLAUSEFLAG_MULTI }, { "disable-ds-digests", &cfg_type_disabledsdigest, CFG_CLAUSEFLAG_MULTI }, { "disable-empty-zone", &cfg_type_astring, CFG_CLAUSEFLAG_MULTI }, { "dns64", &cfg_type_dns64, CFG_CLAUSEFLAG_MULTI }, { "dns64-server", &cfg_type_astring, 0 }, { "dns64-contact", &cfg_type_astring, 0 }, { "dnssec-accept-expired", &cfg_type_boolean, 0 }, { "dnssec-enable", &cfg_type_boolean, 0 }, { "dnssec-lookaside", &cfg_type_lookaside, CFG_CLAUSEFLAG_MULTI }, { "dnssec-must-be-secure", &cfg_type_mustbesecure, CFG_CLAUSEFLAG_MULTI }, { "dnssec-validation", &cfg_type_boolorauto, 0 }, { "dual-stack-servers", &cfg_type_nameportiplist, 0 }, { "edns-udp-size", &cfg_type_uint32, 0 }, { "empty-contact", &cfg_type_astring, 0 }, { "empty-server", &cfg_type_astring, 0 }, { "empty-zones-enable", &cfg_type_boolean, 0 }, { "fetch-glue", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, #ifdef ENABLE_FETCHLIMIT { "fetch-quota-params", &cfg_type_fetchquota, 0 }, { "fetches-per-server", &cfg_type_fetchesper, 0 }, { "fetches-per-zone", &cfg_type_fetchesper, 0 }, #endif /* ENABLE_FETCHLIMIT */ { "ixfr-from-differences", &cfg_type_ixfrdifftype, 0 }, { "lame-ttl", &cfg_type_uint32, 0 }, #ifdef ISC_PLATFORM_USESIT { "nosit-udp-size", &cfg_type_uint32, 0 }, #else { "nosit-udp-size", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTCONFIGURED }, #endif { "max-acache-size", &cfg_type_sizenodefault, 0 }, { "max-cache-size", &cfg_type_sizenodefault, 0 }, { "max-cache-ttl", &cfg_type_uint32, 0 }, { "max-clients-per-query", &cfg_type_uint32, 0 }, { "max-ncache-ttl", &cfg_type_uint32, 0 }, { "max-recursion-depth", &cfg_type_uint32, 0 }, { "max-recursion-queries", &cfg_type_uint32, 0 }, { "max-udp-size", &cfg_type_uint32, 0 }, { "min-roots", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTIMP }, { "minimal-responses", &cfg_type_boolean, 0 }, { "prefetch", &cfg_type_prefetch, 0 }, { "preferred-glue", &cfg_type_astring, 0 }, { "no-case-compress", &cfg_type_bracketed_aml, 0 }, { "provide-ixfr", &cfg_type_boolean, 0 }, /* * Note that the query-source option syntax is different * from the other -source options. */ { "query-source", &cfg_type_querysource4, 0 }, { "query-source-v6", &cfg_type_querysource6, 0 }, { "queryport-pool-ports", &cfg_type_uint32, CFG_CLAUSEFLAG_OBSOLETE }, { "queryport-pool-updateinterval", &cfg_type_uint32, CFG_CLAUSEFLAG_OBSOLETE }, { "recursion", &cfg_type_boolean, 0 }, #ifdef ISC_PLATFORM_USESIT { "request-sit", &cfg_type_boolean, 0 }, #else { "request-sit", &cfg_type_boolean, CFG_CLAUSEFLAG_NOTCONFIGURED }, #endif { "request-nsid", &cfg_type_boolean, 0 }, { "resolver-query-timeout", &cfg_type_uint32, 0 }, { "rfc2308-type1", &cfg_type_boolean, CFG_CLAUSEFLAG_NYI }, { "root-delegation-only", &cfg_type_optional_exclude, 0 }, { "rrset-order", &cfg_type_rrsetorder, 0 }, { "sortlist", &cfg_type_bracketed_aml, 0 }, { "suppress-initial-notify", &cfg_type_boolean, CFG_CLAUSEFLAG_NYI }, { "topology", &cfg_type_bracketed_aml, CFG_CLAUSEFLAG_NOTIMP }, { "transfer-format", &cfg_type_transferformat, 0 }, { "use-queryport-pool", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, { "zero-no-soa-ttl-cache", &cfg_type_boolean, 0 }, #ifdef ALLOW_FILTER_AAAA { "filter-aaaa", &cfg_type_bracketed_aml, 0 }, { "filter-aaaa-on-v4", &cfg_type_filter_aaaa, 0 }, { "filter-aaaa-on-v6", &cfg_type_filter_aaaa, 0 }, #else { "filter-aaaa", &cfg_type_bracketed_aml, CFG_CLAUSEFLAG_NOTCONFIGURED }, { "filter-aaaa-on-v4", &cfg_type_filter_aaaa, CFG_CLAUSEFLAG_NOTCONFIGURED }, { "filter-aaaa-on-v6", &cfg_type_filter_aaaa, CFG_CLAUSEFLAG_NOTCONFIGURED }, #endif { "response-policy", &cfg_type_rpz, 0 }, { "rate-limit", &cfg_type_rrl, 0 }, { NULL, NULL, 0 } }; /*% * Clauses that can be found within the 'view' statement only. */ static cfg_clausedef_t view_only_clauses[] = { { "match-clients", &cfg_type_bracketed_aml, 0 }, { "match-destinations", &cfg_type_bracketed_aml, 0 }, { "match-recursive-only", &cfg_type_boolean, 0 }, { NULL, NULL, 0 } }; /*% * Sig-validity-interval. */ static cfg_tuplefielddef_t validityinterval_fields[] = { { "validity", &cfg_type_uint32, 0 }, { "re-sign", &cfg_type_optional_uint32, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_validityinterval = { "validityinterval", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, validityinterval_fields }; /*% * Clauses that can be found in a 'zone' statement, * with defaults in the 'view' or 'options' statement. */ static cfg_clausedef_t zone_clauses[] = { { "allow-notify", &cfg_type_bracketed_aml, 0 }, { "allow-query", &cfg_type_bracketed_aml, 0 }, { "allow-query-on", &cfg_type_bracketed_aml, 0 }, { "allow-transfer", &cfg_type_bracketed_aml, 0 }, { "allow-update", &cfg_type_bracketed_aml, 0 }, { "allow-update-forwarding", &cfg_type_bracketed_aml, 0 }, { "also-notify", &cfg_type_namesockaddrkeylist, 0 }, { "alt-transfer-source", &cfg_type_sockaddr4wild, 0 }, { "alt-transfer-source-v6", &cfg_type_sockaddr6wild, 0 }, { "auto-dnssec", &cfg_type_autodnssec, 0 }, { "check-dup-records", &cfg_type_checkmode, 0 }, { "check-integrity", &cfg_type_boolean, 0 }, { "check-mx", &cfg_type_checkmode, 0 }, { "check-mx-cname", &cfg_type_checkmode, 0 }, { "check-sibling", &cfg_type_boolean, 0 }, { "check-spf", &cfg_type_warn, 0 }, { "check-srv-cname", &cfg_type_checkmode, 0 }, { "check-wildcard", &cfg_type_boolean, 0 }, { "dialup", &cfg_type_dialuptype, 0 }, { "dnssec-dnskey-kskonly", &cfg_type_boolean, 0 }, { "dnssec-loadkeys-interval", &cfg_type_uint32, 0 }, { "dnssec-secure-to-insecure", &cfg_type_boolean, 0 }, { "dnssec-update-mode", &cfg_type_dnssecupdatemode, 0 }, { "forward", &cfg_type_forwardtype, 0 }, { "forwarders", &cfg_type_portiplist, 0 }, { "inline-signing", &cfg_type_boolean, 0 }, { "key-directory", &cfg_type_qstring, 0 }, { "maintain-ixfr-base", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, { "masterfile-format", &cfg_type_masterformat, 0 }, { "max-ixfr-log-size", &cfg_type_size, CFG_CLAUSEFLAG_OBSOLETE }, { "max-journal-size", &cfg_type_sizenodefault, 0 }, { "max-refresh-time", &cfg_type_uint32, 0 }, { "max-retry-time", &cfg_type_uint32, 0 }, { "max-transfer-idle-in", &cfg_type_uint32, 0 }, { "max-transfer-idle-out", &cfg_type_uint32, 0 }, { "max-transfer-time-in", &cfg_type_uint32, 0 }, { "max-transfer-time-out", &cfg_type_uint32, 0 }, { "max-zone-ttl", &cfg_type_maxttl, 0 }, { "min-refresh-time", &cfg_type_uint32, 0 }, { "min-retry-time", &cfg_type_uint32, 0 }, { "multi-master", &cfg_type_boolean, 0 }, { "notify", &cfg_type_notifytype, 0 }, { "notify-delay", &cfg_type_uint32, 0 }, { "notify-source", &cfg_type_sockaddr4wild, 0 }, { "notify-source-v6", &cfg_type_sockaddr6wild, 0 }, { "notify-to-soa", &cfg_type_boolean, 0 }, { "nsec3-test-zone", &cfg_type_boolean, CFG_CLAUSEFLAG_TESTONLY }, { "request-ixfr", &cfg_type_boolean, 0 }, { "serial-update-method", &cfg_type_updatemethod, 0 }, { "sig-signing-nodes", &cfg_type_uint32, 0 }, { "sig-signing-signatures", &cfg_type_uint32, 0 }, { "sig-signing-type", &cfg_type_uint32, 0 }, { "sig-validity-interval", &cfg_type_validityinterval, 0 }, { "transfer-source", &cfg_type_sockaddr4wild, 0 }, { "transfer-source-v6", &cfg_type_sockaddr6wild, 0 }, { "try-tcp-refresh", &cfg_type_boolean, 0 }, { "update-check-ksk", &cfg_type_boolean, 0 }, { "use-alt-transfer-source", &cfg_type_boolean, 0 }, { "zero-no-soa-ttl", &cfg_type_boolean, 0 }, { "zone-statistics", &cfg_type_zonestat, 0 }, { NULL, NULL, 0 } }; /*% * Clauses that can be found in a 'zone' statement * only. */ static cfg_clausedef_t zone_only_clauses[] = { { "type", &cfg_type_zonetype, 0 }, { "file", &cfg_type_qstring, 0 }, { "journal", &cfg_type_qstring, 0 }, { "ixfr-base", &cfg_type_qstring, CFG_CLAUSEFLAG_OBSOLETE }, { "ixfr-tmp-file", &cfg_type_qstring, CFG_CLAUSEFLAG_OBSOLETE }, { "masters", &cfg_type_namesockaddrkeylist, 0 }, { "pubkey", &cfg_type_pubkey, CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_OBSOLETE }, { "update-policy", &cfg_type_updatepolicy, 0 }, { "database", &cfg_type_astring, 0 }, { "dlz", &cfg_type_astring, 0 }, { "delegation-only", &cfg_type_boolean, 0 }, /* * Note that the format of the check-names option is different between * the zone options and the global/view options. Ugh. */ { "check-names", &cfg_type_checkmode, 0 }, { "in-view", &cfg_type_astring, 0 }, { "ixfr-from-differences", &cfg_type_boolean, 0 }, { "server-addresses", &cfg_type_bracketed_sockaddrlist, 0 }, { "server-names", &cfg_type_namelist, 0 }, { NULL, NULL, 0 } }; /*% The top-level named.conf syntax. */ static cfg_clausedef_t * namedconf_clausesets[] = { namedconf_clauses, namedconf_or_view_clauses, NULL }; LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_namedconf = { "namedconf", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody, &cfg_rep_map, namedconf_clausesets }; /*% The bind.keys syntax (trusted-keys/managed-keys only). */ static cfg_clausedef_t * bindkeys_clausesets[] = { bindkeys_clauses, NULL }; LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_bindkeys = { "bindkeys", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody, &cfg_rep_map, bindkeys_clausesets }; /*% The "options" statement syntax. */ static cfg_clausedef_t * options_clausesets[] = { options_clauses, view_clauses, zone_clauses, NULL }; static cfg_type_t cfg_type_options = { "options", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, options_clausesets }; /*% The "view" statement syntax. */ static cfg_clausedef_t * view_clausesets[] = { view_only_clauses, namedconf_or_view_clauses, view_clauses, zone_clauses, NULL }; static cfg_type_t cfg_type_viewopts = { "view", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, view_clausesets }; /*% The "zone" statement syntax. */ static cfg_clausedef_t * zone_clausesets[] = { zone_only_clauses, zone_clauses, NULL }; static cfg_type_t cfg_type_zoneopts = { "zoneopts", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, zone_clausesets }; /*% The "dynamically loadable zones" statement syntax. */ static cfg_clausedef_t dlz_clauses[] = { { "database", &cfg_type_astring, 0 }, { "search", &cfg_type_boolean, 0 }, { NULL, NULL, 0 } }; static cfg_clausedef_t * dlz_clausesets[] = { dlz_clauses, NULL }; static cfg_type_t cfg_type_dlz = { "dlz", cfg_parse_named_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, dlz_clausesets }; /*% * Clauses that can be found within the 'key' statement. */ static cfg_clausedef_t key_clauses[] = { { "algorithm", &cfg_type_astring, 0 }, { "secret", &cfg_type_sstring, 0 }, { NULL, NULL, 0 } }; static cfg_clausedef_t * key_clausesets[] = { key_clauses, NULL }; static cfg_type_t cfg_type_key = { "key", cfg_parse_named_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, key_clausesets }; /*% * Clauses that can be found in a 'server' statement. */ static cfg_clausedef_t server_clauses[] = { { "bogus", &cfg_type_boolean, 0 }, { "edns", &cfg_type_boolean, 0 }, { "edns-udp-size", &cfg_type_uint32, 0 }, { "keys", &cfg_type_server_key_kludge, 0 }, { "max-udp-size", &cfg_type_uint32, 0 }, { "notify-source", &cfg_type_sockaddr4wild, 0 }, { "notify-source-v6", &cfg_type_sockaddr6wild, 0 }, { "provide-ixfr", &cfg_type_boolean, 0 }, { "query-source", &cfg_type_querysource4, 0 }, { "query-source-v6", &cfg_type_querysource6, 0 }, { "request-ixfr", &cfg_type_boolean, 0 }, { "request-nsid", &cfg_type_boolean, 0 }, #ifdef ISC_PLATFORM_USESIT { "request-sit", &cfg_type_boolean, 0 }, #else { "request-sit", &cfg_type_boolean, CFG_CLAUSEFLAG_NOTCONFIGURED }, #endif { "support-ixfr", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, { "transfer-format", &cfg_type_transferformat, 0 }, { "transfer-source", &cfg_type_sockaddr4wild, 0 }, { "transfer-source-v6", &cfg_type_sockaddr6wild, 0 }, { "transfers", &cfg_type_uint32, 0 }, { NULL, NULL, 0 } }; static cfg_clausedef_t * server_clausesets[] = { server_clauses, NULL }; static cfg_type_t cfg_type_server = { "server", cfg_parse_netprefix_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, server_clausesets }; /*% * Clauses that can be found in a 'channel' clause in the * 'logging' statement. * * These have some additional constraints that need to be * checked after parsing: * - There must exactly one of file/syslog/null/stderr * */ static cfg_clausedef_t channel_clauses[] = { /* Destinations. We no longer require these to be first. */ { "file", &cfg_type_logfile, 0 }, { "syslog", &cfg_type_optional_facility, 0 }, { "null", &cfg_type_void, 0 }, { "stderr", &cfg_type_void, 0 }, /* Options. We now accept these for the null channel, too. */ { "severity", &cfg_type_logseverity, 0 }, { "print-time", &cfg_type_boolean, 0 }, { "print-severity", &cfg_type_boolean, 0 }, { "print-category", &cfg_type_boolean, 0 }, { NULL, NULL, 0 } }; static cfg_clausedef_t * channel_clausesets[] = { channel_clauses, NULL }; static cfg_type_t cfg_type_channel = { "channel", cfg_parse_named_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, channel_clausesets }; /*% A list of log destination, used in the "category" clause. */ static cfg_type_t cfg_type_destinationlist = { "destinationlist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_astring }; /*% * Clauses that can be found in a 'logging' statement. */ static cfg_clausedef_t logging_clauses[] = { { "channel", &cfg_type_channel, CFG_CLAUSEFLAG_MULTI }, { "category", &cfg_type_category, CFG_CLAUSEFLAG_MULTI }, { NULL, NULL, 0 } }; static cfg_clausedef_t * logging_clausesets[] = { logging_clauses, NULL }; static cfg_type_t cfg_type_logging = { "logging", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, logging_clausesets }; /*% * For parsing an 'addzone' statement */ static cfg_tuplefielddef_t addzone_fields[] = { { "name", &cfg_type_astring, 0 }, { "class", &cfg_type_optional_class, 0 }, { "view", &cfg_type_optional_class, 0 }, { "options", &cfg_type_zoneopts, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_addzone = { "addzone", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, addzone_fields }; static cfg_clausedef_t addzoneconf_clauses[] = { { "addzone", &cfg_type_addzone, 0 }, { NULL, NULL, 0 } }; static cfg_clausedef_t * addzoneconf_clausesets[] = { addzoneconf_clauses, NULL }; LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_addzoneconf = { "addzoneconf", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody, &cfg_rep_map, addzoneconf_clausesets }; /*% The new-zone-file syntax (for zones added by 'rndc addzone') */ static cfg_clausedef_t newzones_clauses[] = { { "zone", &cfg_type_addzone, CFG_CLAUSEFLAG_MULTI }, { NULL, NULL, 0 } }; static cfg_clausedef_t * newzones_clausesets[] = { newzones_clauses, NULL }; LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_newzones = { "newzones", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody, &cfg_rep_map, newzones_clausesets }; static isc_result_t parse_unitstring(char *str, isc_resourcevalue_t *valuep) { char *endp; unsigned int len; isc_uint64_t value; isc_uint64_t unit; value = isc_string_touint64(str, &endp, 10); if (*endp == 0) { *valuep = value; return (ISC_R_SUCCESS); } len = strlen(str); if (len < 2 || endp[1] != '\0') return (ISC_R_FAILURE); switch (str[len - 1]) { case 'k': case 'K': unit = 1024; break; case 'm': case 'M': unit = 1024 * 1024; break; case 'g': case 'G': unit = 1024 * 1024 * 1024; break; default: return (ISC_R_FAILURE); } if (value > ISC_UINT64_MAX / unit) return (ISC_R_FAILURE); *valuep = value * unit; return (ISC_R_SUCCESS); } static isc_result_t parse_sizeval(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *obj = NULL; isc_uint64_t val; UNUSED(type); CHECK(cfg_gettoken(pctx, 0)); if (pctx->token.type != isc_tokentype_string) { result = ISC_R_UNEXPECTEDTOKEN; goto cleanup; } CHECK(parse_unitstring(TOKEN_STRING(pctx), &val)); CHECK(cfg_create_obj(pctx, &cfg_type_uint64, &obj)); obj->value.uint64 = val; *ret = obj; return (ISC_R_SUCCESS); cleanup: cfg_parser_error(pctx, CFG_LOG_NEAR, "expected integer and optional unit"); return (result); } /*% * A size value (number + optional unit). */ static cfg_type_t cfg_type_sizeval = { "sizeval", parse_sizeval, cfg_print_uint64, cfg_doc_terminal, &cfg_rep_uint64, NULL }; /*% * A size, "unlimited", or "default". */ static isc_result_t parse_size(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { return (parse_enum_or_other(pctx, type, &cfg_type_sizeval, ret)); } static const char *size_enums[] = { "unlimited", "default", NULL }; static cfg_type_t cfg_type_size = { "size", parse_size, cfg_print_ustring, cfg_doc_terminal, &cfg_rep_string, size_enums }; /*% * A size or "unlimited", but not "default". */ static const char *sizenodefault_enums[] = { "unlimited", NULL }; static cfg_type_t cfg_type_sizenodefault = { "size_no_default", parse_size, cfg_print_ustring, cfg_doc_terminal, &cfg_rep_string, sizenodefault_enums }; /*% * optional_keyvalue */ static isc_result_t parse_maybe_optional_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, isc_boolean_t optional, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *obj = NULL; const keyword_type_t *kw = type->of; CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_string && strcasecmp(TOKEN_STRING(pctx), kw->name) == 0) { CHECK(cfg_gettoken(pctx, 0)); CHECK(kw->type->parse(pctx, kw->type, &obj)); obj->type = type; /* XXX kludge */ } else { if (optional) { CHECK(cfg_parse_void(pctx, NULL, &obj)); } else { cfg_parser_error(pctx, CFG_LOG_NEAR, "expected '%s'", kw->name); result = ISC_R_UNEXPECTEDTOKEN; goto cleanup; } } *ret = obj; cleanup: return (result); } static isc_result_t parse_enum_or_other(cfg_parser_t *pctx, const cfg_type_t *enumtype, const cfg_type_t *othertype, cfg_obj_t **ret) { isc_result_t result; CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_string && cfg_is_enum(TOKEN_STRING(pctx), enumtype->of)) { CHECK(cfg_parse_enum(pctx, enumtype, ret)); } else { CHECK(cfg_parse_obj(pctx, othertype, ret)); } cleanup: return (result); } static void doc_enum_or_other(cfg_printer_t *pctx, const cfg_type_t *type) { cfg_doc_terminal(pctx, type); #if 0 /* XXX */ cfg_print_chars(pctx, "( ", 2);... #endif } static isc_result_t parse_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { return (parse_maybe_optional_keyvalue(pctx, type, ISC_FALSE, ret)); } static isc_result_t parse_optional_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { return (parse_maybe_optional_keyvalue(pctx, type, ISC_TRUE, ret)); } static void print_keyvalue(cfg_printer_t *pctx, const cfg_obj_t *obj) { const keyword_type_t *kw = obj->type->of; cfg_print_cstr(pctx, kw->name); cfg_print_chars(pctx, " ", 1); kw->type->print(pctx, obj); } static void doc_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type) { const keyword_type_t *kw = type->of; cfg_print_cstr(pctx, kw->name); cfg_print_chars(pctx, " ", 1); cfg_doc_obj(pctx, kw->type); } static void doc_optional_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type) { const keyword_type_t *kw = type->of; cfg_print_chars(pctx, "[ ", 2); cfg_print_cstr(pctx, kw->name); cfg_print_chars(pctx, " ", 1); cfg_doc_obj(pctx, kw->type); cfg_print_chars(pctx, " ]", 2); } static const char *dialup_enums[] = { "notify", "notify-passive", "refresh", "passive", NULL }; static isc_result_t parse_dialup_type(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret)); } static cfg_type_t cfg_type_dialuptype = { "dialuptype", parse_dialup_type, cfg_print_ustring, doc_enum_or_other, &cfg_rep_string, dialup_enums }; static const char *notify_enums[] = { "explicit", "master-only", NULL }; static isc_result_t parse_notify_type(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret)); } static cfg_type_t cfg_type_notifytype = { "notifytype", parse_notify_type, cfg_print_ustring, doc_enum_or_other, &cfg_rep_string, notify_enums, }; static const char *ixfrdiff_enums[] = { "master", "slave", NULL }; static isc_result_t parse_ixfrdiff_type(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret)); } static cfg_type_t cfg_type_ixfrdifftype = { "ixfrdiff", parse_ixfrdiff_type, cfg_print_ustring, doc_enum_or_other, &cfg_rep_string, ixfrdiff_enums, }; static const char *filter_aaaa_enums[] = { "break-dnssec", NULL }; static isc_result_t parse_filter_aaaa(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret)); } static cfg_type_t cfg_type_filter_aaaa = { "filter_aaaa", parse_filter_aaaa, cfg_print_ustring, doc_enum_or_other, &cfg_rep_string, filter_aaaa_enums, }; static keyword_type_t key_kw = { "key", &cfg_type_astring }; LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_keyref = { "keyref", parse_keyvalue, print_keyvalue, doc_keyvalue, &cfg_rep_string, &key_kw }; static cfg_type_t cfg_type_optional_keyref = { "optional_keyref", parse_optional_keyvalue, print_keyvalue, doc_optional_keyvalue, &cfg_rep_string, &key_kw }; #ifdef HAVE_GEOIP /* * "geoip" ACL element: * geoip [ db ] search-type */ static const char *geoiptype_enums[] = { "country", "country3", "countryname", "region", "regionname", "city", "postal", "metrocode", "areacode", "timezone", "continent", "isp", "domain", "asnum", "org", "netspeed", NULL }; static cfg_type_t cfg_type_geoiptype = { "geoiptype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, &geoiptype_enums }; static const char *geoipdb_enums[] = { "country", "region", "city", "isp", "domain", "asnum", "org", "netspeed", NULL }; static cfg_type_t cfg_type_geoipdb = { "geoipdb", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, &geoipdb_enums }; static cfg_tuplefielddef_t geoip_fields[] = { { "negated", &cfg_type_void, 0 }, { "db", &cfg_type_geoipdb, 0 }, { "subtype", &cfg_type_geoiptype, 0 }, { "search", &cfg_type_astring, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_geoip = { "geoip", parse_geoip, print_geoip, doc_geoip, &cfg_rep_tuple, geoip_fields }; static isc_result_t parse_geoip(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *obj = NULL; const cfg_tuplefielddef_t *fields = type->of; CHECK(cfg_create_tuple(pctx, type, &obj)); CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[0])); /* Parse the optional "db" field. */ CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_string) { CHECK(cfg_gettoken(pctx, 0)); if (strcasecmp(TOKEN_STRING(pctx), "db") == 0 && obj->value.tuple[1] == NULL) { CHECK(cfg_parse_obj(pctx, fields[1].type, &obj->value.tuple[1])); } else { CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[1])); cfg_ungettoken(pctx); } } CHECK(cfg_parse_obj(pctx, fields[2].type, &obj->value.tuple[2])); CHECK(cfg_parse_obj(pctx, fields[3].type, &obj->value.tuple[3])); *ret = obj; return (ISC_R_SUCCESS); cleanup: CLEANUP_OBJ(obj); return (result); } static void print_geoip(cfg_printer_t *pctx, const cfg_obj_t *obj) { if (obj->value.tuple[1]->type->print != cfg_print_void) { cfg_print_cstr(pctx, " db "); cfg_print_obj(pctx, obj->value.tuple[1]); } cfg_print_obj(pctx, obj->value.tuple[2]); cfg_print_obj(pctx, obj->value.tuple[3]); } static void doc_geoip(cfg_printer_t *pctx, const cfg_type_t *type) { UNUSED(type); cfg_print_cstr(pctx, "[ db "); cfg_doc_enum(pctx, &cfg_type_geoipdb); cfg_print_cstr(pctx, " ]"); cfg_print_chars(pctx, " ", 1); cfg_doc_enum(pctx, &cfg_type_geoiptype); cfg_print_chars(pctx, " ", 1); cfg_print_cstr(pctx, ""); } #endif /* HAVE_GEOIP */ /*% * A "controls" statement is represented as a map with the multivalued * "inet" and "unix" clauses. */ static keyword_type_t controls_allow_kw = { "allow", &cfg_type_bracketed_aml }; static cfg_type_t cfg_type_controls_allow = { "controls_allow", parse_keyvalue, print_keyvalue, doc_keyvalue, &cfg_rep_list, &controls_allow_kw }; static keyword_type_t controls_keys_kw = { "keys", &cfg_type_keylist }; static cfg_type_t cfg_type_controls_keys = { "controls_keys", parse_optional_keyvalue, print_keyvalue, doc_optional_keyvalue, &cfg_rep_list, &controls_keys_kw }; static cfg_tuplefielddef_t inetcontrol_fields[] = { { "address", &cfg_type_controls_sockaddr, 0 }, { "allow", &cfg_type_controls_allow, 0 }, { "keys", &cfg_type_controls_keys, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_inetcontrol = { "inetcontrol", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, inetcontrol_fields }; static keyword_type_t controls_perm_kw = { "perm", &cfg_type_uint32 }; static cfg_type_t cfg_type_controls_perm = { "controls_perm", parse_keyvalue, print_keyvalue, doc_keyvalue, &cfg_rep_uint32, &controls_perm_kw }; static keyword_type_t controls_owner_kw = { "owner", &cfg_type_uint32 }; static cfg_type_t cfg_type_controls_owner = { "controls_owner", parse_keyvalue, print_keyvalue, doc_keyvalue, &cfg_rep_uint32, &controls_owner_kw }; static keyword_type_t controls_group_kw = { "group", &cfg_type_uint32 }; static cfg_type_t cfg_type_controls_group = { "controls_allow", parse_keyvalue, print_keyvalue, doc_keyvalue, &cfg_rep_uint32, &controls_group_kw }; static cfg_tuplefielddef_t unixcontrol_fields[] = { { "path", &cfg_type_qstring, 0 }, { "perm", &cfg_type_controls_perm, 0 }, { "owner", &cfg_type_controls_owner, 0 }, { "group", &cfg_type_controls_group, 0 }, { "keys", &cfg_type_controls_keys, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_unixcontrol = { "unixcontrol", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, unixcontrol_fields }; static cfg_clausedef_t controls_clauses[] = { { "inet", &cfg_type_inetcontrol, CFG_CLAUSEFLAG_MULTI }, { "unix", &cfg_type_unixcontrol, CFG_CLAUSEFLAG_MULTI }, { NULL, NULL, 0 } }; static cfg_clausedef_t * controls_clausesets[] = { controls_clauses, NULL }; static cfg_type_t cfg_type_controls = { "controls", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, &controls_clausesets }; /*% * A "statistics-channels" statement is represented as a map with the * multivalued "inet" clauses. */ static void doc_optional_bracketed_list(cfg_printer_t *pctx, const cfg_type_t *type) { const keyword_type_t *kw = type->of; cfg_print_chars(pctx, "[ ", 2); cfg_print_cstr(pctx, kw->name); cfg_print_chars(pctx, " ", 1); cfg_doc_obj(pctx, kw->type); cfg_print_chars(pctx, " ]", 2); } static cfg_type_t cfg_type_optional_allow = { "optional_allow", parse_optional_keyvalue, print_keyvalue, doc_optional_bracketed_list, &cfg_rep_list, &controls_allow_kw }; static cfg_tuplefielddef_t statserver_fields[] = { { "address", &cfg_type_controls_sockaddr, 0 }, /* reuse controls def */ { "allow", &cfg_type_optional_allow, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_statschannel = { "statschannel", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, statserver_fields }; static cfg_clausedef_t statservers_clauses[] = { { "inet", &cfg_type_statschannel, CFG_CLAUSEFLAG_MULTI }, { NULL, NULL, 0 } }; static cfg_clausedef_t * statservers_clausesets[] = { statservers_clauses, NULL }; static cfg_type_t cfg_type_statschannels = { "statistics-channels", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, &statservers_clausesets }; /*% * An optional class, as used in view and zone statements. */ static isc_result_t parse_optional_class(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; UNUSED(type); CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_string) CHECK(cfg_parse_obj(pctx, &cfg_type_ustring, ret)); else CHECK(cfg_parse_obj(pctx, &cfg_type_void, ret)); cleanup: return (result); } static cfg_type_t cfg_type_optional_class = { "optional_class", parse_optional_class, NULL, cfg_doc_terminal, NULL, NULL }; static isc_result_t parse_querysource(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *obj = NULL; isc_netaddr_t netaddr; in_port_t port = 0; isc_dscp_t dscp = -1; unsigned int have_address = 0; unsigned int have_port = 0; unsigned int have_dscp = 0; const unsigned int *flagp = type->of; if ((*flagp & CFG_ADDR_V4OK) != 0) isc_netaddr_any(&netaddr); else if ((*flagp & CFG_ADDR_V6OK) != 0) isc_netaddr_any6(&netaddr); else INSIST(0); for (;;) { CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_string) { if (strcasecmp(TOKEN_STRING(pctx), "address") == 0) { /* read "address" */ CHECK(cfg_gettoken(pctx, 0)); CHECK(cfg_parse_rawaddr(pctx, *flagp, &netaddr)); have_address++; } else if (strcasecmp(TOKEN_STRING(pctx), "port") == 0) { /* read "port" */ CHECK(cfg_gettoken(pctx, 0)); CHECK(cfg_parse_rawport(pctx, CFG_ADDR_WILDOK, &port)); have_port++; } else if (strcasecmp(TOKEN_STRING(pctx), "dscp") == 0) { /* read "dscp" */ CHECK(cfg_gettoken(pctx, 0)); CHECK(cfg_parse_dscp(pctx, &dscp)); have_dscp++; } else if (have_port == 0 && have_dscp == 0 && have_address == 0) { return (cfg_parse_sockaddr(pctx, type, ret)); } else { cfg_parser_error(pctx, CFG_LOG_NEAR, "expected 'address', 'port', " "or 'dscp'"); return (ISC_R_UNEXPECTEDTOKEN); } } else break; } if (have_address > 1 || have_port > 1 || have_address + have_port == 0) { cfg_parser_error(pctx, 0, "expected one address and/or port"); return (ISC_R_UNEXPECTEDTOKEN); } if (have_dscp > 1) { cfg_parser_error(pctx, 0, "expected at most one dscp"); return (ISC_R_UNEXPECTEDTOKEN); } CHECK(cfg_create_obj(pctx, &cfg_type_querysource, &obj)); isc_sockaddr_fromnetaddr(&obj->value.sockaddr, &netaddr, port); obj->value.sockaddrdscp.dscp = dscp; *ret = obj; return (ISC_R_SUCCESS); cleanup: cfg_parser_error(pctx, CFG_LOG_NEAR, "invalid query source"); CLEANUP_OBJ(obj); return (result); } static void print_querysource(cfg_printer_t *pctx, const cfg_obj_t *obj) { isc_netaddr_t na; isc_netaddr_fromsockaddr(&na, &obj->value.sockaddr); cfg_print_cstr(pctx, "address "); cfg_print_rawaddr(pctx, &na); cfg_print_cstr(pctx, " port "); cfg_print_rawuint(pctx, isc_sockaddr_getport(&obj->value.sockaddr)); if (obj->value.sockaddrdscp.dscp != -1) { cfg_print_cstr(pctx, " dscp "); cfg_print_rawuint(pctx, obj->value.sockaddrdscp.dscp); } } static unsigned int sockaddr4wild_flags = CFG_ADDR_WILDOK | CFG_ADDR_V4OK | CFG_ADDR_DSCPOK; static unsigned int sockaddr6wild_flags = CFG_ADDR_WILDOK | CFG_ADDR_V6OK | CFG_ADDR_DSCPOK; static cfg_type_t cfg_type_querysource4 = { "querysource4", parse_querysource, NULL, cfg_doc_terminal, NULL, &sockaddr4wild_flags }; static cfg_type_t cfg_type_querysource6 = { "querysource6", parse_querysource, NULL, cfg_doc_terminal, NULL, &sockaddr6wild_flags }; static cfg_type_t cfg_type_querysource = { "querysource", NULL, print_querysource, NULL, &cfg_rep_sockaddr, NULL }; /*% addrmatchelt */ static isc_result_t parse_addrmatchelt(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; UNUSED(type); CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING)); if (pctx->token.type == isc_tokentype_string || pctx->token.type == isc_tokentype_qstring) { if (pctx->token.type == isc_tokentype_string && (strcasecmp(TOKEN_STRING(pctx), "key") == 0)) { CHECK(cfg_parse_obj(pctx, &cfg_type_keyref, ret)); } else if (pctx->token.type == isc_tokentype_string && (strcasecmp(TOKEN_STRING(pctx), "geoip") == 0)) { #ifdef HAVE_GEOIP CHECK(cfg_gettoken(pctx, 0)); CHECK(cfg_parse_obj(pctx, &cfg_type_geoip, ret)); #else cfg_parser_error(pctx, CFG_LOG_NEAR, "'geoip' not supported in this build"); return (ISC_R_UNEXPECTEDTOKEN); #endif } else { if (cfg_lookingat_netaddr(pctx, CFG_ADDR_V4OK | CFG_ADDR_V4PREFIXOK | CFG_ADDR_V6OK)) { CHECK(cfg_parse_netprefix(pctx, NULL, ret)); } else { CHECK(cfg_parse_astring(pctx, NULL, ret)); } } } else if (pctx->token.type == isc_tokentype_special) { if (pctx->token.value.as_char == '{') { /* Nested match list. */ CHECK(cfg_parse_obj(pctx, &cfg_type_bracketed_aml, ret)); } else if (pctx->token.value.as_char == '!') { CHECK(cfg_gettoken(pctx, 0)); /* read "!" */ CHECK(cfg_parse_obj(pctx, &cfg_type_negated, ret)); } else { goto bad; } } else { bad: cfg_parser_error(pctx, CFG_LOG_NEAR, "expected IP match list element"); return (ISC_R_UNEXPECTEDTOKEN); } cleanup: return (result); } /*% * A negated address match list element (like "! 10.0.0.1"). * Somewhat sneakily, the caller is expected to parse the * "!", but not to print it. */ static cfg_tuplefielddef_t negated_fields[] = { { "negated", &cfg_type_addrmatchelt, 0 }, { NULL, NULL, 0 } }; static void print_negated(cfg_printer_t *pctx, const cfg_obj_t *obj) { cfg_print_chars(pctx, "!", 1); cfg_print_tuple(pctx, obj); } static cfg_type_t cfg_type_negated = { "negated", cfg_parse_tuple, print_negated, NULL, &cfg_rep_tuple, &negated_fields }; /*% An address match list element */ static cfg_type_t cfg_type_addrmatchelt = { "address_match_element", parse_addrmatchelt, NULL, cfg_doc_terminal, NULL, NULL }; /*% A bracketed address match list */ static cfg_type_t cfg_type_bracketed_aml = { "bracketed_aml", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_addrmatchelt }; /*% * The socket address syntax in the "controls" statement is silly. * It allows both socket address families, but also allows "*", * whis is gratuitously interpreted as the IPv4 wildcard address. */ static unsigned int controls_sockaddr_flags = CFG_ADDR_V4OK | CFG_ADDR_V6OK | CFG_ADDR_WILDOK; static cfg_type_t cfg_type_controls_sockaddr = { "controls_sockaddr", cfg_parse_sockaddr, cfg_print_sockaddr, cfg_doc_sockaddr, &cfg_rep_sockaddr, &controls_sockaddr_flags }; /*% * Handle the special kludge syntax of the "keys" clause in the "server" * statement, which takes a single key with or without braces and semicolon. */ static isc_result_t parse_server_key_kludge(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; isc_boolean_t braces = ISC_FALSE; UNUSED(type); /* Allow opening brace. */ CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_special && pctx->token.value.as_char == '{') { CHECK(cfg_gettoken(pctx, 0)); braces = ISC_TRUE; } CHECK(cfg_parse_obj(pctx, &cfg_type_astring, ret)); if (braces) { /* Skip semicolon if present. */ CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_special && pctx->token.value.as_char == ';') CHECK(cfg_gettoken(pctx, 0)); CHECK(cfg_parse_special(pctx, '}')); } cleanup: return (result); } static cfg_type_t cfg_type_server_key_kludge = { "server_key", parse_server_key_kludge, NULL, cfg_doc_terminal, NULL, NULL }; /*% * An optional logging facility. */ static isc_result_t parse_optional_facility(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; UNUSED(type); CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING)); if (pctx->token.type == isc_tokentype_string || pctx->token.type == isc_tokentype_qstring) { CHECK(cfg_parse_obj(pctx, &cfg_type_astring, ret)); } else { CHECK(cfg_parse_obj(pctx, &cfg_type_void, ret)); } cleanup: return (result); } static cfg_type_t cfg_type_optional_facility = { "optional_facility", parse_optional_facility, NULL, cfg_doc_terminal, NULL, NULL }; /*% * A log severity. Return as a string, except "debug N", * which is returned as a keyword object. */ static keyword_type_t debug_kw = { "debug", &cfg_type_uint32 }; static cfg_type_t cfg_type_debuglevel = { "debuglevel", parse_keyvalue, print_keyvalue, doc_keyvalue, &cfg_rep_uint32, &debug_kw }; static isc_result_t parse_logseverity(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; UNUSED(type); CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_string && strcasecmp(TOKEN_STRING(pctx), "debug") == 0) { CHECK(cfg_gettoken(pctx, 0)); /* read "debug" */ CHECK(cfg_peektoken(pctx, ISC_LEXOPT_NUMBER)); if (pctx->token.type == isc_tokentype_number) { CHECK(cfg_parse_uint32(pctx, NULL, ret)); } else { /* * The debug level is optional and defaults to 1. * This makes little sense, but we support it for * compatibility with BIND 8. */ CHECK(cfg_create_obj(pctx, &cfg_type_uint32, ret)); (*ret)->value.uint32 = 1; } (*ret)->type = &cfg_type_debuglevel; /* XXX kludge */ } else { CHECK(cfg_parse_obj(pctx, &cfg_type_loglevel, ret)); } cleanup: return (result); } static cfg_type_t cfg_type_logseverity = { "log_severity", parse_logseverity, NULL, cfg_doc_terminal, NULL, NULL }; /*% * The "file" clause of the "channel" statement. * This is yet another special case. */ static const char *logversions_enums[] = { "unlimited", NULL }; static isc_result_t parse_logversions(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { return (parse_enum_or_other(pctx, type, &cfg_type_uint32, ret)); } static cfg_type_t cfg_type_logversions = { "logversions", parse_logversions, cfg_print_ustring, cfg_doc_terminal, &cfg_rep_string, logversions_enums }; static cfg_tuplefielddef_t logfile_fields[] = { { "file", &cfg_type_qstring, 0 }, { "versions", &cfg_type_logversions, 0 }, { "size", &cfg_type_size, 0 }, { NULL, NULL, 0 } }; static isc_result_t parse_logfile(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *obj = NULL; const cfg_tuplefielddef_t *fields = type->of; CHECK(cfg_create_tuple(pctx, type, &obj)); /* Parse the mandatory "file" field */ CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0])); /* Parse "versions" and "size" fields in any order. */ for (;;) { CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_string) { CHECK(cfg_gettoken(pctx, 0)); if (strcasecmp(TOKEN_STRING(pctx), "versions") == 0 && obj->value.tuple[1] == NULL) { CHECK(cfg_parse_obj(pctx, fields[1].type, &obj->value.tuple[1])); } else if (strcasecmp(TOKEN_STRING(pctx), "size") == 0 && obj->value.tuple[2] == NULL) { CHECK(cfg_parse_obj(pctx, fields[2].type, &obj->value.tuple[2])); } else { break; } } else { break; } } /* Create void objects for missing optional values. */ if (obj->value.tuple[1] == NULL) CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[1])); if (obj->value.tuple[2] == NULL) CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[2])); *ret = obj; return (ISC_R_SUCCESS); cleanup: CLEANUP_OBJ(obj); return (result); } static void print_logfile(cfg_printer_t *pctx, const cfg_obj_t *obj) { cfg_print_obj(pctx, obj->value.tuple[0]); /* file */ if (obj->value.tuple[1]->type->print != cfg_print_void) { cfg_print_cstr(pctx, " versions "); cfg_print_obj(pctx, obj->value.tuple[1]); } if (obj->value.tuple[2]->type->print != cfg_print_void) { cfg_print_cstr(pctx, " size "); cfg_print_obj(pctx, obj->value.tuple[2]); } } static void doc_logfile(cfg_printer_t *pctx, const cfg_type_t *type) { UNUSED(type); cfg_print_cstr(pctx, ""); cfg_print_chars(pctx, " ", 1); cfg_print_cstr(pctx, "[ versions ( \"unlimited\" | ) ]"); cfg_print_chars(pctx, " ", 1); cfg_print_cstr(pctx, "[ size ]"); } static cfg_type_t cfg_type_logfile = { "log_file", parse_logfile, print_logfile, doc_logfile, &cfg_rep_tuple, logfile_fields }; /*% An IPv4 address with optional dscp and port, "*" accepted as wildcard. */ static cfg_type_t cfg_type_sockaddr4wild = { "sockaddr4wild", cfg_parse_sockaddr, cfg_print_sockaddr, cfg_doc_sockaddr, &cfg_rep_sockaddr, &sockaddr4wild_flags }; /*% An IPv6 address with optional port, "*" accepted as wildcard. */ static cfg_type_t cfg_type_sockaddr6wild = { "v6addrportwild", cfg_parse_sockaddr, cfg_print_sockaddr, cfg_doc_sockaddr, &cfg_rep_sockaddr, &sockaddr6wild_flags }; /*% * lwres */ static cfg_tuplefielddef_t lwres_view_fields[] = { { "name", &cfg_type_astring, 0 }, { "class", &cfg_type_optional_class, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_lwres_view = { "lwres_view", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, lwres_view_fields }; static cfg_type_t cfg_type_lwres_searchlist = { "lwres_searchlist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_astring }; static cfg_clausedef_t lwres_clauses[] = { { "listen-on", &cfg_type_portiplist, 0 }, { "view", &cfg_type_lwres_view, 0 }, { "search", &cfg_type_lwres_searchlist, 0 }, { "ndots", &cfg_type_uint32, 0 }, { NULL, NULL, 0 } }; static cfg_clausedef_t * lwres_clausesets[] = { lwres_clauses, NULL }; static cfg_type_t cfg_type_lwres = { "lwres", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, lwres_clausesets }; /*% * rndc */ static cfg_clausedef_t rndcconf_options_clauses[] = { { "default-key", &cfg_type_astring, 0 }, { "default-port", &cfg_type_uint32, 0 }, { "default-server", &cfg_type_astring, 0 }, { "default-source-address", &cfg_type_netaddr4wild, 0 }, { "default-source-address-v6", &cfg_type_netaddr6wild, 0 }, { NULL, NULL, 0 } }; static cfg_clausedef_t * rndcconf_options_clausesets[] = { rndcconf_options_clauses, NULL }; static cfg_type_t cfg_type_rndcconf_options = { "rndcconf_options", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, rndcconf_options_clausesets }; static cfg_clausedef_t rndcconf_server_clauses[] = { { "key", &cfg_type_astring, 0 }, { "port", &cfg_type_uint32, 0 }, { "source-address", &cfg_type_netaddr4wild, 0 }, { "source-address-v6", &cfg_type_netaddr6wild, 0 }, { "addresses", &cfg_type_bracketed_sockaddrnameportlist, 0 }, { NULL, NULL, 0 } }; static cfg_clausedef_t * rndcconf_server_clausesets[] = { rndcconf_server_clauses, NULL }; static cfg_type_t cfg_type_rndcconf_server = { "rndcconf_server", cfg_parse_named_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, rndcconf_server_clausesets }; static cfg_clausedef_t rndcconf_clauses[] = { { "key", &cfg_type_key, CFG_CLAUSEFLAG_MULTI }, { "server", &cfg_type_rndcconf_server, CFG_CLAUSEFLAG_MULTI }, { "options", &cfg_type_rndcconf_options, 0 }, { NULL, NULL, 0 } }; static cfg_clausedef_t * rndcconf_clausesets[] = { rndcconf_clauses, NULL }; LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_rndcconf = { "rndcconf", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody, &cfg_rep_map, rndcconf_clausesets }; static cfg_clausedef_t rndckey_clauses[] = { { "key", &cfg_type_key, 0 }, { NULL, NULL, 0 } }; static cfg_clausedef_t * rndckey_clausesets[] = { rndckey_clauses, NULL }; LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_rndckey = { "rndckey", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody, &cfg_rep_map, rndckey_clausesets }; /* * session.key has exactly the same syntax as rndc.key, but it's defined * separately for clarity (and so we can extend it someday, if needed). */ LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_sessionkey = { "sessionkey", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody, &cfg_rep_map, rndckey_clausesets }; static cfg_tuplefielddef_t nameport_fields[] = { { "name", &cfg_type_astring, 0 }, { "port", &cfg_type_optional_port, 0 }, { "dscp", &cfg_type_optional_dscp, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_nameport = { "nameport", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, nameport_fields }; static void doc_sockaddrnameport(cfg_printer_t *pctx, const cfg_type_t *type) { UNUSED(type); cfg_print_chars(pctx, "( ", 2); cfg_print_cstr(pctx, ""); cfg_print_chars(pctx, " ", 1); cfg_print_cstr(pctx, "[ port ]"); cfg_print_chars(pctx, " ", 1); cfg_print_cstr(pctx, "[ dscp ]"); cfg_print_chars(pctx, " | ", 3); cfg_print_cstr(pctx, ""); cfg_print_chars(pctx, " ", 1); cfg_print_cstr(pctx, "[ port ]"); cfg_print_chars(pctx, " ", 1); cfg_print_cstr(pctx, "[ dscp ]"); cfg_print_chars(pctx, " | ", 3); cfg_print_cstr(pctx, ""); cfg_print_chars(pctx, " ", 1); cfg_print_cstr(pctx, "[ port ]"); cfg_print_chars(pctx, " ", 1); cfg_print_cstr(pctx, "[ dscp ]"); cfg_print_chars(pctx, " )", 2); } static isc_result_t parse_sockaddrnameport(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *obj = NULL; UNUSED(type); CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING)); if (pctx->token.type == isc_tokentype_string || pctx->token.type == isc_tokentype_qstring) { if (cfg_lookingat_netaddr(pctx, CFG_ADDR_V4OK | CFG_ADDR_V6OK)) CHECK(cfg_parse_sockaddr(pctx, &cfg_type_sockaddr, ret)); else { const cfg_tuplefielddef_t *fields = cfg_type_nameport.of; CHECK(cfg_create_tuple(pctx, &cfg_type_nameport, &obj)); CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0])); CHECK(cfg_parse_obj(pctx, fields[1].type, &obj->value.tuple[1])); CHECK(cfg_parse_obj(pctx, fields[2].type, &obj->value.tuple[2])); *ret = obj; obj = NULL; } } else { cfg_parser_error(pctx, CFG_LOG_NEAR, "expected IP address or hostname"); return (ISC_R_UNEXPECTEDTOKEN); } cleanup: CLEANUP_OBJ(obj); return (result); } static cfg_type_t cfg_type_sockaddrnameport = { "sockaddrnameport_element", parse_sockaddrnameport, NULL, doc_sockaddrnameport, NULL, NULL }; static cfg_type_t cfg_type_bracketed_sockaddrnameportlist = { "bracketed_sockaddrnameportlist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_sockaddrnameport }; /*% * A list of socket addresses or name with an optional default port, * as used in the dual-stack-servers option. E.g., * "port 1234 { dual-stack-servers.net; 10.0.0.1; 1::2 port 69; }" */ static cfg_tuplefielddef_t nameportiplist_fields[] = { { "port", &cfg_type_optional_port, 0 }, { "addresses", &cfg_type_bracketed_sockaddrnameportlist, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_nameportiplist = { "nameportiplist", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, nameportiplist_fields }; /*% * masters element. */ static void doc_masterselement(cfg_printer_t *pctx, const cfg_type_t *type) { UNUSED(type); cfg_print_chars(pctx, "( ", 2); cfg_print_cstr(pctx, ""); cfg_print_chars(pctx, " | ", 3); cfg_print_cstr(pctx, ""); cfg_print_chars(pctx, " ", 1); cfg_print_cstr(pctx, "[ port ]"); cfg_print_chars(pctx, " | ", 3); cfg_print_cstr(pctx, ""); cfg_print_chars(pctx, " ", 1); cfg_print_cstr(pctx, "[ port ]"); cfg_print_chars(pctx, " )", 2); } static isc_result_t parse_masterselement(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *obj = NULL; UNUSED(type); CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING)); if (pctx->token.type == isc_tokentype_string || pctx->token.type == isc_tokentype_qstring) { if (cfg_lookingat_netaddr(pctx, CFG_ADDR_V4OK | CFG_ADDR_V6OK)) CHECK(cfg_parse_sockaddr(pctx, &cfg_type_sockaddr, ret)); else CHECK(cfg_parse_astring(pctx, &cfg_type_astring, ret)); } else { cfg_parser_error(pctx, CFG_LOG_NEAR, "expected IP address or masters name"); return (ISC_R_UNEXPECTEDTOKEN); } cleanup: CLEANUP_OBJ(obj); return (result); } static cfg_type_t cfg_type_masterselement = { "masters_element", parse_masterselement, NULL, doc_masterselement, NULL, NULL }; static isc_result_t parse_maxttlval(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *obj = NULL; isc_uint32_t ttl; UNUSED(type); CHECK(cfg_gettoken(pctx, 0)); if (pctx->token.type != isc_tokentype_string) { result = ISC_R_UNEXPECTEDTOKEN; goto cleanup; } result = dns_ttl_fromtext(&pctx->token.value.as_textregion, &ttl); if (result == ISC_R_RANGE ) { cfg_parser_error(pctx, CFG_LOG_NEAR, "TTL out of range "); return (result); } else if (result != ISC_R_SUCCESS) goto cleanup; CHECK(cfg_create_obj(pctx, &cfg_type_uint32, &obj)); obj->value.uint32 = ttl; *ret = obj; return (ISC_R_SUCCESS); cleanup: cfg_parser_error(pctx, CFG_LOG_NEAR, "expected integer and optional unit"); return (result); } /*% * A size value (number + optional unit). */ static cfg_type_t cfg_type_maxttlval = { "maxttlval", parse_maxttlval, cfg_print_uint64, cfg_doc_terminal, &cfg_rep_uint64, NULL }; static isc_result_t parse_maxttl(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { return (parse_enum_or_other(pctx, type, &cfg_type_maxttlval, ret)); } /*% * A size or "unlimited", but not "default". */ static const char *maxttl_enums[] = { "unlimited", NULL }; static cfg_type_t cfg_type_maxttl = { "maxttl_no_default", parse_maxttl, cfg_print_ustring, cfg_doc_terminal, &cfg_rep_string, maxttl_enums }; bind9-9.10.3.dfsg.P4/lib/isccfg/Makefile.in0000644000470500017500000000450412664710322017445 0ustar lamontlamont# Copyright (C) 2004, 2005, 2007, 2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001-2003 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id$ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ @LIBISCCFG_API@ @BIND9_MAKE_INCLUDES@ CINCLUDES = -I. ${DNS_INCLUDES} ${ISC_INCLUDES} ${ISCCFG_INCLUDES} CDEFINES = CWARNINGS = ISCLIBS = ../../lib/isc/libisc.@A@ ISCCCLIBS = ../../lib/isccc/libisccc.@A@ DNSLIBS = ../../lib/dns/libdns.@A@ ISCCFGLIBS = ../../lib/cfg/libisccfg.@A@ ISCDEPLIBS = ../../lib/isc/libisc.@A@ ISCCFGDEPLIBS = libisccfg.@A@ LIBS = @LIBS@ SUBDIRS = include # Alphabetically OBJS = aclconf.@O@ dnsconf.@O@ log.@O@ namedconf.@O@ \ parser.@O@ version.@O@ # Alphabetically SRCS = aclconf.c dnsconf.c log.c namedconf.c \ parser.c version.c TARGETS = timestamp @BIND9_MAKE_RULES@ version.@O@: version.c ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ -DVERSION=\"${VERSION}\" \ -DLIBINTERFACE=${LIBINTERFACE} \ -DLIBREVISION=${LIBREVISION} \ -DLIBAGE=${LIBAGE} \ -c ${srcdir}/version.c libisccfg.@SA@: ${OBJS} ${AR} ${ARFLAGS} $@ ${OBJS} ${RANLIB} $@ libisccfg.la: ${OBJS} ${LIBTOOL_MODE_LINK} \ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisccfg.la -rpath ${libdir} \ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \ ${OBJS} ${DNSLIBS} ${ISCCCLIBS} ${ISCLIBS} @DNS_CRYPTO_LIBS@ \ ${LIBS} timestamp: libisccfg.@A@ touch timestamp installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${libdir} install:: timestamp installdirs ${LIBTOOL_MODE_INSTALL} ${INSTALL_LIBRARY} libisccfg.@A@ ${DESTDIR}${libdir} clean distclean:: rm -f libisccfg.@A@ timestamp bind9-9.10.3.dfsg.P4/lib/isccfg/dnsconf.c0000644000470500017500000000404212664710322017173 0ustar lamontlamont/* * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: dnsconf.c,v 1.4 2009/09/02 23:48:03 tbox Exp $ */ /*! \file */ #include #include #include /*% * A trusted key, as used in the "trusted-keys" statement. */ static cfg_tuplefielddef_t trustedkey_fields[] = { { "name", &cfg_type_astring, 0 }, { "flags", &cfg_type_uint32, 0 }, { "protocol", &cfg_type_uint32, 0 }, { "algorithm", &cfg_type_uint32, 0 }, { "key", &cfg_type_qstring, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_trustedkey = { "trustedkey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, trustedkey_fields }; static cfg_type_t cfg_type_trustedkeys = { "trusted-keys", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_trustedkey }; /*% * Clauses that can be found within the top level of the dns.conf * file only. */ static cfg_clausedef_t dnsconf_clauses[] = { { "trusted-keys", &cfg_type_trustedkeys, CFG_CLAUSEFLAG_MULTI }, { NULL, NULL, 0 } }; /*% The top-level dns.conf syntax. */ static cfg_clausedef_t * dnsconf_clausesets[] = { dnsconf_clauses, NULL }; LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_dnsconf = { "dnsconf", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody, &cfg_rep_map, dnsconf_clausesets }; bind9-9.10.3.dfsg.P4/lib/isccfg/include/0002755000470500017500000000000012672612753017032 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isccfg/include/Makefile.in0000644000470500017500000000175312664710322021073 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.7 2007/06/19 23:47:22 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = isccfg TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isccfg/include/isccfg/0002755000470500017500000000000012664710322020260 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isccfg/include/isccfg/namedconf.h0000644000470500017500000000375512664710322022373 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: namedconf.h,v 1.18 2010/08/11 18:14:20 each Exp $ */ #ifndef ISCCFG_NAMEDCONF_H #define ISCCFG_NAMEDCONF_H 1 /*! \file isccfg/namedconf.h * \brief * This module defines the named.conf, rndc.conf, and rndc.key grammars. */ #include /* * Configuration object types. */ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_namedconf; /*%< A complete named.conf file. */ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_bindkeys; /*%< A bind.keys file. */ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_newzones; /*%< A new-zones file (for zones added by 'rndc addzone'). */ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_addzoneconf; /*%< A single zone passed via the addzone rndc command. */ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_rndcconf; /*%< A complete rndc.conf file. */ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_rndckey; /*%< A complete rndc.key file. */ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sessionkey; /*%< A complete session.key file. */ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_keyref; /*%< A key reference, used as an ACL element */ #endif /* ISCCFG_NAMEDCONF_H */ bind9-9.10.3.dfsg.P4/lib/isccfg/include/isccfg/Makefile.in0000644000470500017500000000267012664710322022330 0ustar lamontlamont# Copyright (C) 2004, 2005, 2007, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001, 2002 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.12 2007/06/19 23:47:22 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ # # Only list headers that are to be installed and are not # machine generated. The latter are handled specially in the # install target below. # HEADERS = aclconf.h cfg.h dnsconf.h grammar.h log.h namedconf.h \ version.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isccfg install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/isccfg ; \ done bind9-9.10.3.dfsg.P4/lib/isccfg/include/isccfg/log.h0000644000470500017500000000324612664710322021215 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: log.h,v 1.14 2009/01/18 23:48:14 tbox Exp $ */ #ifndef ISCCFG_LOG_H #define ISCCFG_LOG_H 1 /*! \file isccfg/log.h */ #include #include LIBISCCFG_EXTERNAL_DATA extern isc_logcategory_t cfg_categories[]; LIBISCCFG_EXTERNAL_DATA extern isc_logmodule_t cfg_modules[]; #define CFG_LOGCATEGORY_CONFIG (&cfg_categories[0]) #define CFG_LOGMODULE_PARSER (&cfg_modules[0]) ISC_LANG_BEGINDECLS void cfg_log_init(isc_log_t *lctx); /*%< * Make the libisccfg categories and modules available for use with the * ISC logging library. * * Requires: *\li lctx is a valid logging context. * *\li cfg_log_init() is called only once. * * Ensures: * \li The categories and modules defined above are available for * use by isc_log_usechannnel() and isc_log_write(). */ ISC_LANG_ENDDECLS #endif /* ISCCFG_LOG_H */ bind9-9.10.3.dfsg.P4/lib/isccfg/include/isccfg/aclconf.h0000644000470500017500000000571012664710322022037 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2010-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef ISCCFG_ACLCONF_H #define ISCCFG_ACLCONF_H 1 #include #include #ifdef HAVE_GEOIP #include #endif #include typedef struct cfg_aclconfctx { ISC_LIST(dns_acl_t) named_acl_cache; isc_mem_t *mctx; #ifdef HAVE_GEOIP dns_geoip_databases_t *geoip; #endif isc_refcount_t references; } cfg_aclconfctx_t; /*** *** Functions ***/ ISC_LANG_BEGINDECLS isc_result_t cfg_aclconfctx_create(isc_mem_t *mctx, cfg_aclconfctx_t **ret); /* * Creates and initializes an ACL configuration context. */ void cfg_aclconfctx_detach(cfg_aclconfctx_t **actxp); /* * Removes a reference to an ACL configuration context; when references * reaches zero, clears the contents and deallocate the structure. */ void cfg_aclconfctx_attach(cfg_aclconfctx_t *src, cfg_aclconfctx_t **dest); /* * Attaches a pointer to an existing ACL configuration context. */ isc_result_t cfg_acl_fromconfig(const cfg_obj_t *caml, const cfg_obj_t *cctx, isc_log_t *lctx, cfg_aclconfctx_t *ctx, isc_mem_t *mctx, unsigned int nest_level, dns_acl_t **target); isc_result_t cfg_acl_fromconfig2(const cfg_obj_t *caml, const cfg_obj_t *cctx, isc_log_t *lctx, cfg_aclconfctx_t *ctx, isc_mem_t *mctx, unsigned int nest_level, isc_uint16_t family, dns_acl_t **target); /* * Construct a new dns_acl_t from configuration data in 'caml' and * 'cctx'. Memory is allocated through 'mctx'. * * Any named ACLs referred to within 'caml' will be be converted * into nested dns_acl_t objects. Multiple references to the same * named ACLs will be converted into shared references to a single * nested dns_acl_t object when the referring objects were created * passing the same ACL configuration context 'ctx'. * * cfg_acl_fromconfig() is a backward-compatible version of * cfg_acl_fromconfig2(), which allows an address family to be * specified. If 'family' is not zero, then only addresses/prefixes * of a matching family (AF_INET or AF_INET6) may be configured. * * On success, attach '*target' to the new dns_acl_t object. */ ISC_LANG_ENDDECLS #endif /* ISCCFG_ACLCONF_H */ bind9-9.10.3.dfsg.P4/lib/isccfg/include/isccfg/grammar.h0000644000470500017500000003376612664710322022074 0ustar lamontlamont/* * Copyright (C) 2004-2011, 2013-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: grammar.h,v 1.24 2011/01/04 23:47:14 tbox Exp $ */ #ifndef ISCCFG_GRAMMAR_H #define ISCCFG_GRAMMAR_H 1 /*! \file isccfg/grammar.h */ #include #include #include #include #include #include /* * Definitions shared between the configuration parser * and the grammars; not visible to users of the parser. */ /*% Clause may occur multiple times (e.g., "zone") */ #define CFG_CLAUSEFLAG_MULTI 0x00000001 /*% Clause is obsolete */ #define CFG_CLAUSEFLAG_OBSOLETE 0x00000002 /*% Clause is not implemented, and may never be */ #define CFG_CLAUSEFLAG_NOTIMP 0x00000004 /*% Clause is not implemented yet */ #define CFG_CLAUSEFLAG_NYI 0x00000008 /*% Default value has changed since earlier release */ #define CFG_CLAUSEFLAG_NEWDEFAULT 0x00000010 /*% * Clause needs to be interpreted during parsing * by calling a callback function, like the * "directory" option. */ #define CFG_CLAUSEFLAG_CALLBACK 0x00000020 /*% A option that is only used in testing. */ #define CFG_CLAUSEFLAG_TESTONLY 0x00000040 /*% A configuration option that was not configured at compile time. */ #define CFG_CLAUSEFLAG_NOTCONFIGURED 0x00000080 typedef struct cfg_clausedef cfg_clausedef_t; typedef struct cfg_tuplefielddef cfg_tuplefielddef_t; typedef struct cfg_printer cfg_printer_t; typedef ISC_LIST(cfg_listelt_t) cfg_list_t; typedef struct cfg_map cfg_map_t; typedef struct cfg_rep cfg_rep_t; /* * Function types for configuration object methods */ typedef isc_result_t (*cfg_parsefunc_t)(cfg_parser_t *, const cfg_type_t *type, cfg_obj_t **); typedef void (*cfg_printfunc_t)(cfg_printer_t *, const cfg_obj_t *); typedef void (*cfg_docfunc_t)(cfg_printer_t *, const cfg_type_t *); typedef void (*cfg_freefunc_t)(cfg_parser_t *, cfg_obj_t *); /* * Structure definitions */ /*% * A configuration printer object. This is an abstract * interface to a destination to which text can be printed * by calling the function 'f'. */ struct cfg_printer { void (*f)(void *closure, const char *text, int textlen); void *closure; int indent; int flags; }; /*% A clause definition. */ struct cfg_clausedef { const char *name; cfg_type_t *type; unsigned int flags; }; /*% A tuple field definition. */ struct cfg_tuplefielddef { const char *name; cfg_type_t *type; unsigned int flags; }; /*% A configuration object type definition. */ struct cfg_type { const char *name; /*%< For debugging purposes only */ cfg_parsefunc_t parse; cfg_printfunc_t print; cfg_docfunc_t doc; /*%< Print grammar description */ cfg_rep_t * rep; /*%< Data representation */ const void * of; /*%< Additional data for meta-types */ }; /*% A keyword-type definition, for things like "port ". */ typedef struct { const char *name; const cfg_type_t *type; } keyword_type_t; struct cfg_map { cfg_obj_t *id; /*%< Used for 'named maps' like keys, zones, &c */ const cfg_clausedef_t * const *clausesets; /*%< The clauses that can occur in this map; used for printing */ isc_symtab_t *symtab; }; typedef struct cfg_netprefix cfg_netprefix_t; struct cfg_netprefix { isc_netaddr_t address; /* IP4/IP6 */ unsigned int prefixlen; }; /*% * A configuration data representation. */ struct cfg_rep { const char * name; /*%< For debugging only */ cfg_freefunc_t free; /*%< How to free this kind of data. */ }; /*% * A configuration object. This is the main building block * of the configuration parse tree. */ struct cfg_obj { const cfg_type_t *type; union { isc_uint32_t uint32; isc_uint64_t uint64; isc_textregion_t string; /*%< null terminated, too */ isc_boolean_t boolean; cfg_map_t map; cfg_list_t list; cfg_obj_t ** tuple; isc_sockaddr_t sockaddr; struct { isc_sockaddr_t sockaddr; isc_dscp_t dscp; } sockaddrdscp; cfg_netprefix_t netprefix; } value; isc_refcount_t references; /*%< reference counter */ const char * file; unsigned int line; }; /*% A list element. */ struct cfg_listelt { cfg_obj_t *obj; ISC_LINK(cfg_listelt_t) link; }; /*% The parser object. */ struct cfg_parser { isc_mem_t * mctx; isc_log_t * lctx; isc_lex_t * lexer; unsigned int errors; unsigned int warnings; isc_token_t token; /*% We are at the end of all input. */ isc_boolean_t seen_eof; /*% The current token has been pushed back. */ isc_boolean_t ungotten; /*% * The stack of currently active files, represented * as a configuration list of configuration strings. * The head is the top-level file, subsequent elements * (if any) are the nested include files, and the * last element is the file currently being parsed. */ cfg_obj_t * open_files; /*% * Names of files that we have parsed and closed * and were previously on the open_file list. * We keep these objects around after closing * the files because the file names may still be * referenced from other configuration objects * for use in reporting semantic errors after * parsing is complete. */ cfg_obj_t * closed_files; /*% * Current line number. We maintain our own * copy of this so that it is available even * when a file has just been closed. */ unsigned int line; /*% * Parser context flags, used for maintaining state * from one token to the next. */ unsigned int flags; /*%< Reference counter */ isc_refcount_t references; cfg_parsecallback_t callback; void *callbackarg; }; /* Parser context flags */ #define CFG_PCTX_SKIP 0x1 /*@{*/ /*% * Flags defining whether to accept certain types of network addresses. */ #define CFG_ADDR_V4OK 0x00000001 #define CFG_ADDR_V4PREFIXOK 0x00000002 #define CFG_ADDR_V6OK 0x00000004 #define CFG_ADDR_WILDOK 0x00000008 #define CFG_ADDR_DSCPOK 0x00000010 #define CFG_ADDR_MASK (CFG_ADDR_V6OK|CFG_ADDR_V4OK) /*@}*/ /*@{*/ /*% * Predefined data representation types. */ LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_uint32; LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_uint64; LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_string; LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_boolean; LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_map; LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_list; LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_tuple; LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_sockaddr; LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_netprefix; LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_void; LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_fixedpoint; /*@}*/ /*@{*/ /*% * Predefined configuration object types. */ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_boolean; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_uint32; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_uint64; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_qstring; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_astring; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_ustring; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sstring; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sockaddr; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sockaddrdscp; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4wild; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr6; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr6wild; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netprefix; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_void; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_token; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_unsupported; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_fixedpoint; /*@}*/ isc_result_t cfg_gettoken(cfg_parser_t *pctx, int options); isc_result_t cfg_peektoken(cfg_parser_t *pctx, int options); void cfg_ungettoken(cfg_parser_t *pctx); #define CFG_LEXOPT_QSTRING (ISC_LEXOPT_QSTRING | ISC_LEXOPT_QSTRINGMULTILINE) isc_result_t cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp); void cfg_print_rawuint(cfg_printer_t *pctx, unsigned int u); isc_result_t cfg_parse_uint32(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); void cfg_print_uint32(cfg_printer_t *pctx, const cfg_obj_t *obj); void cfg_print_uint64(cfg_printer_t *pctx, const cfg_obj_t *obj); isc_result_t cfg_parse_qstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); void cfg_print_ustring(cfg_printer_t *pctx, const cfg_obj_t *obj); isc_result_t cfg_parse_astring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); isc_result_t cfg_parse_sstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); isc_result_t cfg_parse_rawaddr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na); void cfg_print_rawaddr(cfg_printer_t *pctx, const isc_netaddr_t *na); isc_boolean_t cfg_lookingat_netaddr(cfg_parser_t *pctx, unsigned int flags); isc_result_t cfg_parse_rawport(cfg_parser_t *pctx, unsigned int flags, in_port_t *port); isc_result_t cfg_parse_dscp(cfg_parser_t *pctx, isc_dscp_t *dscp); isc_result_t cfg_parse_sockaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); isc_result_t cfg_parse_boolean(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); void cfg_print_sockaddr(cfg_printer_t *pctx, const cfg_obj_t *obj); void cfg_print_boolean(cfg_printer_t *pctx, const cfg_obj_t *obj); void cfg_doc_sockaddr(cfg_printer_t *pctx, const cfg_type_t *type); isc_result_t cfg_parse_netprefix(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); isc_result_t cfg_parse_special(cfg_parser_t *pctx, int special); /*%< Parse a required special character 'special'. */ isc_result_t cfg_create_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp); isc_result_t cfg_parse_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); void cfg_print_tuple(cfg_printer_t *pctx, const cfg_obj_t *obj); void cfg_doc_tuple(cfg_printer_t *pctx, const cfg_type_t *type); isc_result_t cfg_create_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp); isc_result_t cfg_parse_listelt(cfg_parser_t *pctx, const cfg_type_t *elttype, cfg_listelt_t **ret); isc_result_t cfg_parse_bracketed_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); void cfg_print_bracketed_list(cfg_printer_t *pctx, const cfg_obj_t *obj); void cfg_doc_bracketed_list(cfg_printer_t *pctx, const cfg_type_t *type); isc_result_t cfg_parse_spacelist(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); void cfg_print_spacelist(cfg_printer_t *pctx, const cfg_obj_t *obj); isc_result_t cfg_parse_enum(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); void cfg_doc_enum(cfg_printer_t *pctx, const cfg_type_t *type); void cfg_print_chars(cfg_printer_t *pctx, const char *text, int len); /*%< Print 'len' characters at 'text' */ void cfg_print_cstr(cfg_printer_t *pctx, const char *s); /*%< Print the null-terminated string 's' */ isc_result_t cfg_parse_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); isc_result_t cfg_parse_named_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); isc_result_t cfg_parse_addressed_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); isc_result_t cfg_parse_netprefix_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t ** ret); void cfg_print_map(cfg_printer_t *pctx, const cfg_obj_t *obj); void cfg_doc_map(cfg_printer_t *pctx, const cfg_type_t *type); isc_result_t cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); void cfg_print_mapbody(cfg_printer_t *pctx, const cfg_obj_t *obj); void cfg_doc_mapbody(cfg_printer_t *pctx, const cfg_type_t *type); isc_result_t cfg_parse_void(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); void cfg_print_void(cfg_printer_t *pctx, const cfg_obj_t *obj); void cfg_doc_void(cfg_printer_t *pctx, const cfg_type_t *type); isc_result_t cfg_parse_fixedpoint(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); void cfg_print_fixedpoint(cfg_printer_t *pctx, const cfg_obj_t *obj); isc_result_t cfg_parse_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); void cfg_print_obj(cfg_printer_t *pctx, const cfg_obj_t *obj); void cfg_doc_obj(cfg_printer_t *pctx, const cfg_type_t *type); /*%< * Print a description of the grammar of an arbitrary configuration * type 'type' */ void cfg_doc_terminal(cfg_printer_t *pctx, const cfg_type_t *type); /*%< * Document the type 'type' as a terminal by printing its * name in angle brackets, e.g., <uint32>. */ void cfg_parser_error(cfg_parser_t *pctx, unsigned int flags, const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4); /*! * Pass one of these flags to cfg_parser_error() to include the * token text in log message. */ #define CFG_LOG_NEAR 0x00000001 /*%< Say "near " */ #define CFG_LOG_BEFORE 0x00000002 /*%< Say "before " */ #define CFG_LOG_NOPREP 0x00000004 /*%< Say just "" */ void cfg_parser_warning(cfg_parser_t *pctx, unsigned int flags, const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4); isc_boolean_t cfg_is_enum(const char *s, const char *const *enums); /*%< Return true iff the string 's' is one of the strings in 'enums' */ #endif /* ISCCFG_GRAMMAR_H */ bind9-9.10.3.dfsg.P4/lib/isccfg/include/isccfg/version.h0000644000470500017500000000230612664710322022115 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: version.h,v 1.9 2007/06/19 23:47:22 tbox Exp $ */ /*! \file isccfg/version.h */ #include LIBISCCFG_EXTERNAL_DATA extern const char cfg_version[]; LIBISCCFG_EXTERNAL_DATA extern const unsigned int cfg_libinterface; LIBISCCFG_EXTERNAL_DATA extern const unsigned int cfg_librevision; LIBISCCFG_EXTERNAL_DATA extern const unsigned int cfg_libage; bind9-9.10.3.dfsg.P4/lib/isccfg/include/isccfg/dnsconf.h0000644000470500017500000000224612664710322022065 0ustar lamontlamont/* * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: dnsconf.h,v 1.3 2009/09/02 23:48:03 tbox Exp $ */ #ifndef ISCCFG_NAMEDCONF_H #define ISCCFG_NAMEDCONF_H 1 /*! \file * \brief * This module defines the named.conf, rndc.conf, and rndc.key grammars. */ #include /* * Configuration object types. */ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_dnsconf; /*%< A complete dns.conf file. */ #endif /* ISCCFG_CFG_H */ bind9-9.10.3.dfsg.P4/lib/isccfg/include/isccfg/cfg.h0000644000470500017500000003067312664710322021177 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2010, 2013-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: cfg.h,v 1.46 2010/08/13 23:47:04 tbox Exp $ */ #ifndef ISCCFG_CFG_H #define ISCCFG_CFG_H 1 /***** ***** Module Info *****/ /*! \file isccfg/cfg.h * \brief * This is the new, table-driven, YACC-free configuration file parser. */ /*** *** Imports ***/ #include #include #include #include #include /*** *** Types ***/ /*% * A configuration parser. */ typedef struct cfg_parser cfg_parser_t; /*% * A configuration type definition object. There is a single * static cfg_type_t object for each data type supported by * the configuration parser. */ typedef struct cfg_type cfg_type_t; /*% * A configuration object. This is the basic building block of the * configuration parse tree. It contains a value (which may be * of one of several types) and information identifying the file * and line number the value came from, for printing error * messages. */ typedef struct cfg_obj cfg_obj_t; /*% * A configuration object list element. */ typedef struct cfg_listelt cfg_listelt_t; /*% * A callback function to be called when parsing an option * that needs to be interpreted at parsing time, like * "directory". */ typedef isc_result_t (*cfg_parsecallback_t)(const char *clausename, const cfg_obj_t *obj, void *arg); /*** *** Functions ***/ ISC_LANG_BEGINDECLS void cfg_parser_attach(cfg_parser_t *src, cfg_parser_t **dest); /*%< * Reference a parser object. */ isc_result_t cfg_parser_create(isc_mem_t *mctx, isc_log_t *lctx, cfg_parser_t **ret); /*%< * Create a configuration file parser. Any warning and error * messages will be logged to 'lctx'. * * The parser object returned can be used for a single call * to cfg_parse_file() or cfg_parse_buffer(). It must not * be reused for parsing multiple files or buffers. */ void cfg_parser_setcallback(cfg_parser_t *pctx, cfg_parsecallback_t callback, void *arg); /*%< * Make the parser call 'callback' whenever it encounters * a configuration clause with the callback attribute, * passing it the clause name, the clause value, * and 'arg' as arguments. * * To restore the default of not invoking callbacks, pass * callback==NULL and arg==NULL. */ isc_result_t cfg_parse_file(cfg_parser_t *pctx, const char *filename, const cfg_type_t *type, cfg_obj_t **ret); isc_result_t cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, const cfg_type_t *type, cfg_obj_t **ret); /*%< * Read a configuration containing data of type 'type' * and make '*ret' point to its parse tree. * * The configuration is read from the file 'filename' * (isc_parse_file()) or the buffer 'buffer' * (isc_parse_buffer()). * * Returns an error if the file does not parse correctly. * * Requires: *\li "filename" is valid. *\li "mem" is valid. *\li "type" is valid. *\li "cfg" is non-NULL and "*cfg" is NULL. * * Returns: * \li #ISC_R_SUCCESS - success *\li #ISC_R_NOMEMORY - no memory available *\li #ISC_R_INVALIDFILE - file doesn't exist or is unreadable *\li others - file contains errors */ void cfg_parser_destroy(cfg_parser_t **pctxp); /*%< * Remove a reference to a configuration parser; destroy it if there are no * more references. */ isc_boolean_t cfg_obj_isvoid(const cfg_obj_t *obj); /*%< * Return true iff 'obj' is of void type (e.g., an optional * value not specified). */ isc_boolean_t cfg_obj_ismap(const cfg_obj_t *obj); /*%< * Return true iff 'obj' is of a map type. */ isc_result_t cfg_map_get(const cfg_obj_t *mapobj, const char* name, const cfg_obj_t **obj); /*%< * Extract an element from a configuration object, which * must be of a map type. * * Requires: * \li 'mapobj' points to a valid configuration object of a map type. * \li 'name' points to a null-terminated string. * \li 'obj' is non-NULL and '*obj' is NULL. * * Returns: * \li #ISC_R_SUCCESS - success * \li #ISC_R_NOTFOUND - name not found in map */ const cfg_obj_t * cfg_map_getname(const cfg_obj_t *mapobj); /*%< * Get the name of a named map object, like a server "key" clause. * * Requires: * \li 'mapobj' points to a valid configuration object of a map type. * * Returns: * \li A pointer to a configuration object naming the map object, * or NULL if the map object does not have a name. */ unsigned int cfg_map_count(const cfg_obj_t *mapobj); /*%< * Get the number of elements defined in the symbol table of a map object. * * Requires: * \li 'mapobj' points to a valid configuration object of a map type. * * Returns: * \li The number of elements in the map object. */ isc_boolean_t cfg_obj_istuple(const cfg_obj_t *obj); /*%< * Return true iff 'obj' is of a map type. */ const cfg_obj_t * cfg_tuple_get(const cfg_obj_t *tupleobj, const char *name); /*%< * Extract an element from a configuration object, which * must be of a tuple type. * * Requires: * \li 'tupleobj' points to a valid configuration object of a tuple type. * \li 'name' points to a null-terminated string naming one of the *\li fields of said tuple type. */ isc_boolean_t cfg_obj_isuint32(const cfg_obj_t *obj); /*%< * Return true iff 'obj' is of integer type. */ isc_uint32_t cfg_obj_asuint32(const cfg_obj_t *obj); /*%< * Returns the value of a configuration object of 32-bit integer type. * * Requires: * \li 'obj' points to a valid configuration object of 32-bit integer type. * * Returns: * \li A 32-bit unsigned integer. */ isc_boolean_t cfg_obj_isuint64(const cfg_obj_t *obj); /*%< * Return true iff 'obj' is of integer type. */ isc_uint64_t cfg_obj_asuint64(const cfg_obj_t *obj); /*%< * Returns the value of a configuration object of 64-bit integer type. * * Requires: * \li 'obj' points to a valid configuration object of 64-bit integer type. * * Returns: * \li A 64-bit unsigned integer. */ isc_uint32_t cfg_obj_asfixedpoint(const cfg_obj_t *obj); /*%< * Returns the value of a configuration object of fixed point number. * * Requires: * \li 'obj' points to a valid configuration object of fixed point type. * * Returns: * \li A 32-bit unsigned integer. */ isc_boolean_t cfg_obj_isstring(const cfg_obj_t *obj); /*%< * Return true iff 'obj' is of string type. */ const char * cfg_obj_asstring(const cfg_obj_t *obj); /*%< * Returns the value of a configuration object of a string type * as a null-terminated string. * * Requires: * \li 'obj' points to a valid configuration object of a string type. * * Returns: * \li A pointer to a null terminated string. */ isc_boolean_t cfg_obj_isboolean(const cfg_obj_t *obj); /*%< * Return true iff 'obj' is of a boolean type. */ isc_boolean_t cfg_obj_asboolean(const cfg_obj_t *obj); /*%< * Returns the value of a configuration object of a boolean type. * * Requires: * \li 'obj' points to a valid configuration object of a boolean type. * * Returns: * \li A boolean value. */ isc_boolean_t cfg_obj_issockaddr(const cfg_obj_t *obj); /*%< * Return true iff 'obj' is a socket address. */ const isc_sockaddr_t * cfg_obj_assockaddr(const cfg_obj_t *obj); /*%< * Returns the value of a configuration object representing a socket address. * * Requires: * \li 'obj' points to a valid configuration object of a socket address type. * * Returns: * \li A pointer to a sockaddr. The sockaddr must be copied by the caller * if necessary. */ isc_dscp_t cfg_obj_getdscp(const cfg_obj_t *obj); /*%< * Returns the DSCP value of a configuration object representing a * socket address. * * Requires: * \li 'obj' points to a valid configuration object of a * socket address type. * * Returns: * \li DSCP value associated with a sockaddr, or -1. */ isc_boolean_t cfg_obj_isnetprefix(const cfg_obj_t *obj); /*%< * Return true iff 'obj' is a network prefix. */ void cfg_obj_asnetprefix(const cfg_obj_t *obj, isc_netaddr_t *netaddr, unsigned int *prefixlen); /*%< * Gets the value of a configuration object representing a network * prefix. The network address is returned through 'netaddr' and the * prefix length in bits through 'prefixlen'. * * Requires: * \li 'obj' points to a valid configuration object of network prefix type. *\li 'netaddr' and 'prefixlen' are non-NULL. */ isc_boolean_t cfg_obj_islist(const cfg_obj_t *obj); /*%< * Return true iff 'obj' is of list type. */ const cfg_listelt_t * cfg_list_first(const cfg_obj_t *obj); /*%< * Returns the first list element in a configuration object of a list type. * * Requires: * \li 'obj' points to a valid configuration object of a list type or NULL. * * Returns: * \li A pointer to a cfg_listelt_t representing the first list element, * or NULL if the list is empty or nonexistent. */ const cfg_listelt_t * cfg_list_next(const cfg_listelt_t *elt); /*%< * Returns the next element of a list of configuration objects. * * Requires: * \li 'elt' points to cfg_listelt_t obtained from cfg_list_first() or * a previous call to cfg_list_next(). * * Returns: * \li A pointer to a cfg_listelt_t representing the next element, * or NULL if there are no more elements. */ unsigned int cfg_list_length(const cfg_obj_t *obj, isc_boolean_t recurse); /*%< * Returns the length of a list of configure objects. If obj is * not a list, returns 0. If recurse is true, add in the length of * all contained lists. */ cfg_obj_t * cfg_listelt_value(const cfg_listelt_t *elt); /*%< * Returns the configuration object associated with cfg_listelt_t. * * Requires: * \li 'elt' points to cfg_listelt_t obtained from cfg_list_first() or * cfg_list_next(). * * Returns: * \li A non-NULL pointer to a configuration object. */ void cfg_print(const cfg_obj_t *obj, void (*f)(void *closure, const char *text, int textlen), void *closure); void cfg_printx(const cfg_obj_t *obj, unsigned int flags, void (*f)(void *closure, const char *text, int textlen), void *closure); #define CFG_PRINTER_XKEY 0x1 /* '?' out shared keys. */ /*%< * Print the configuration object 'obj' by repeatedly calling the * function 'f', passing 'closure' and a region of text starting * at 'text' and comprising 'textlen' characters. * * If CFG_PRINTER_XKEY the contents of shared keys will be obscured * by replacing them with question marks ('?') */ void cfg_print_grammar(const cfg_type_t *type, void (*f)(void *closure, const char *text, int textlen), void *closure); /*%< * Print a summary of the grammar of the configuration type 'type'. */ isc_boolean_t cfg_obj_istype(const cfg_obj_t *obj, const cfg_type_t *type); /*%< * Return true iff 'obj' is of type 'type'. */ void cfg_obj_attach(cfg_obj_t *src, cfg_obj_t **dest); /*%< * Reference a configuration object. */ void cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **obj); /*%< * Delete a reference to a configuration object; destroy the object if * there are no more references. * * Require: * \li '*obj' is a valid cfg_obj_t. * \li 'pctx' is a valid cfg_parser_t. */ void cfg_obj_log(const cfg_obj_t *obj, isc_log_t *lctx, int level, const char *fmt, ...) ISC_FORMAT_PRINTF(4, 5); /*%< * Log a message concerning configuration object 'obj' to the logging * channel of 'pctx', at log level 'level'. The message will be prefixed * with the file name(s) and line number where 'obj' was defined. */ const char * cfg_obj_file(const cfg_obj_t *obj); /*%< * Return the file that defined this object. */ unsigned int cfg_obj_line(const cfg_obj_t *obj); /*%< * Return the line in file where this object was defined. */ ISC_LANG_ENDDECLS #endif /* ISCCFG_CFG_H */ bind9-9.10.3.dfsg.P4/lib/isccfg/win32/0002755000470500017500000000000012664730167016352 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isccfg/win32/libisccfg.dsw0000644000470500017500000000103712664710322021004 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "libisccfg"=".\libisccfg.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/lib/isccfg/win32/version.c0000644000470500017500000000233312664710322020171 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: version.c,v 1.6 2007/06/19 23:47:22 tbox Exp $ */ #include #include LIBISCCFG_EXTERNAL_DATA const char cfg_version[] = VERSION; LIBISCCFG_EXTERNAL_DATA const unsigned int cfg_libinterface = LIBINTERFACE; LIBISCCFG_EXTERNAL_DATA const unsigned int cfg_librevision = LIBREVISION; LIBISCCFG_EXTERNAL_DATA const unsigned int cfg_libage = LIBAGE; bind9-9.10.3.dfsg.P4/lib/isccfg/win32/libisccfg.vcxproj.user0000644000470500017500000000021712664710322022656 0ustar lamontlamont bind9-9.10.3.dfsg.P4/lib/isccfg/win32/DLLMain.c0000644000470500017500000000314212664710322017723 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: DLLMain.c,v 1.6 2007/06/18 23:47:51 tbox Exp $ */ #include #include /* * Called when we enter the DLL */ __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { /* * The DLL is loading due to process * initialization or a call to LoadLibrary. */ case DLL_PROCESS_ATTACH: break; /* * The attached process creates a new thread. */ case DLL_THREAD_ATTACH: break; /* The thread of the attached process terminates. */ case DLL_THREAD_DETACH: break; /* * The DLL is unloading from a process due to * process termination or a call to FreeLibrary. */ case DLL_PROCESS_DETACH: break; default: break; } return (TRUE); } bind9-9.10.3.dfsg.P4/lib/isccfg/win32/libisccfg.vcxproj.in0000644000470500017500000001654712664710322022323 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {B2DFA58C-6347-478E-81E8-01E06999D4F1} Win32Proj libisccfg DynamicLibrary true MultiByte DynamicLibrary false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ Level3 Disabled WIN32;USE_MD5;@CRYPTO@_DEBUG;_WINDOWS;_USRDLL;LIBISCCFG_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions) .\;..\..\..\;include;..\include;..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;..\..\dns\include;@LIBXML2_INC@@GEOIP_INC@%(AdditionalIncludeDirectories) false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true Console true ..\..\dns\win32\$(Configuration);..\..\isc\win32\$(Configuration);%(AdditionalLibraryDirectories) libdns.lib;libisc.lib;ws2_32.lib;%(AdditionalDependencies) ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) $(ProjectName).def .\$(Configuration)\$(ProjectName).lib Level3 MaxSpeed true @INTRINSIC@ WIN32;USE_MD5;@CRYPTO@NDEBUG;_WINDOWS;_USRDLL;LIBISCCFG_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions) .\;..\..\..\;include;..\include;..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;..\..\dns\include;@LIBXML2_INC@@GEOIP_INC@%(AdditionalIncludeDirectories) OnlyExplicitInline true .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb false Console false true true ..\..\dns\win32\$(Configuration);..\..\isc\win32\$(Configuration);%(AdditionalLibraryDirectories) libdns.lib;libisc.lib;ws2_32.lib;%(AdditionalDependencies) Default ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) $(ProjectName).def .\$(Configuration)\$(ProjectName).lib bind9-9.10.3.dfsg.P4/lib/isccfg/win32/libisccfg.vcxproj.filters.in0000644000470500017500000000434012664710322023756 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files Source Files Source Files Source Files Source Files Source Files Source Files Header Files Header Files Header Files Header Files Header Files Header Files bind9-9.10.3.dfsg.P4/lib/isccfg/win32/libisccfg.def0000644000470500017500000000356212664710322020752 0ustar lamontlamontLIBRARY libisccfg ; Exported Functions EXPORTS cfg_acl_fromconfig cfg_acl_fromconfig2 cfg_aclconfctx_attach cfg_aclconfctx_create cfg_aclconfctx_detach cfg_create_list cfg_create_obj cfg_create_tuple cfg_doc_bracketed_list cfg_doc_enum cfg_doc_map cfg_doc_mapbody cfg_doc_obj cfg_doc_sockaddr cfg_doc_terminal cfg_doc_tuple cfg_doc_void cfg_gettoken cfg_is_enum cfg_list_first cfg_list_length cfg_list_next cfg_listelt_value cfg_log_init cfg_lookingat_netaddr cfg_map_count cfg_map_get cfg_map_getname cfg_obj_asboolean cfg_obj_asfixedpoint cfg_obj_asnetprefix cfg_obj_assockaddr cfg_obj_asstring cfg_obj_asuint32 cfg_obj_asuint64 cfg_obj_attach cfg_obj_destroy cfg_obj_file cfg_obj_getdscp cfg_obj_isboolean cfg_obj_islist cfg_obj_ismap cfg_obj_isnetprefix cfg_obj_issockaddr cfg_obj_isstring cfg_obj_istuple cfg_obj_istype cfg_obj_isuint32 cfg_obj_isuint64 cfg_obj_isvoid cfg_obj_line cfg_obj_log cfg_parse_addressed_map cfg_parse_astring cfg_parse_boolean cfg_parse_bracketed_list cfg_parse_buffer cfg_parse_dscp cfg_parse_enum cfg_parse_file cfg_parse_fixedpoint cfg_parse_listelt cfg_parse_map cfg_parse_mapbody cfg_parse_named_map cfg_parse_netprefix cfg_parse_netprefix_map cfg_parse_obj cfg_parse_qstring cfg_parse_rawaddr cfg_parse_rawport cfg_parse_sockaddr cfg_parse_spacelist cfg_parse_special cfg_parse_sstring cfg_parse_tuple cfg_parse_uint32 cfg_parse_void cfg_parser_attach cfg_parser_create cfg_parser_destroy cfg_parser_error cfg_parser_setcallback cfg_parser_warning cfg_peektoken cfg_print cfg_print_boolean cfg_print_bracketed_list cfg_print_chars cfg_print_cstr cfg_print_fixedpoint cfg_print_grammar cfg_print_map cfg_print_mapbody cfg_print_obj cfg_print_rawaddr cfg_print_rawuint cfg_print_sockaddr cfg_print_spacelist cfg_print_tuple cfg_print_uint32 cfg_print_uint64 cfg_print_ustring cfg_print_void cfg_printx cfg_tuple_get cfg_ungettoken ; Exported Data ;cfg_type_rndcconf bind9-9.10.3.dfsg.P4/lib/isccfg/win32/libisccfg.mak.in0000644000470500017500000003146312664710322021372 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on libisccfg.dsp !IF "$(CFG)" == "" CFG=libisccfg - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to libisccfg - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "libisccfg - @PLATFORM@ Release" && "$(CFG)" != "libisccfg - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "libisccfg.mak" CFG="libisccfg - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "libisccfg - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE "libisccfg - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "libisccfg - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "libisccfg - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release !IF "$(RECURSE)" == "0" ALL : "..\..\..\Build\Release\libisccfg.dll" !ELSE ALL : "libdns - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" "..\..\..\Build\Release\libisccfg.dll" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libdns - @PLATFORM@ ReleaseCLEAN" "libisc - @PLATFORM@ ReleaseCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\DLLMain.obj" -@erase "$(INTDIR)\aclconf.obj" -@erase "$(INTDIR)\dnsconf.obj" -@erase "$(INTDIR)\log.obj" -@erase "$(INTDIR)\namedconf.obj" -@erase "$(INTDIR)\parser.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\version.obj" -@erase "$(OUTDIR)\libisccfg.exp" -@erase "$(OUTDIR)\libisccfg.lib" -@erase "..\..\..\Build\Release\libisccfg.dll" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" /I "include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" @LIBXML2_INC@ @GEOIP_INC@ /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ /D "LIBISCCFG_EXPORTS" /Fp"$(INTDIR)\libisccfg.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\libisccfg.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../dns/win32/Release/libdns.lib ../../isc/win32/Release/libisc.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\libisccfg.pdb" @MACHINE@ /def:".\libisccfg.def" /out:"../../../Build/Release/libisccfg.dll" /implib:"$(OUTDIR)\libisccfg.lib" DEF_FILE= \ ".\libisccfg.def" LINK32_OBJS= \ "$(INTDIR)\DLLMain.obj" \ "$(INTDIR)\aclconf.obj" \ "$(INTDIR)\dnsconf.obj" \ "$(INTDIR)\log.obj" \ "$(INTDIR)\parser.obj" \ "$(INTDIR)\version.obj" \ "$(INTDIR)\namedconf.obj" \ "..\..\dns\win32\Release\libdns.lib" \ "..\..\isc\win32\Release\libisc.lib" "..\..\..\Build\Release\libisccfg.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_DLL) !ELSEIF "$(CFG)" == "libisccfg - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros !IF "$(RECURSE)" == "0" ALL : "..\..\..\Build\Debug\libisccfg.dll" "$(OUTDIR)\libisccfg.bsc" !ELSE ALL : "libisc - @PLATFORM@ Debug" "..\..\..\Build\Debug\libisccfg.dll" "$(OUTDIR)\libisccfg.bsc" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libisc - @PLATFORM@ DebugCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\DLLMain.obj" -@erase "$(INTDIR)\DLLMain.sbr" -@erase "$(INTDIR)\aclconf.obj" -@erase "$(INTDIR)\aclconf.sbr" -@erase "$(INTDIR)\dnsconf.obj" -@erase "$(INTDIR)\dnsconf.sbr" -@erase "$(INTDIR)\log.obj" -@erase "$(INTDIR)\log.sbr" -@erase "$(INTDIR)\namedconf.obj" -@erase "$(INTDIR)\namedconf.sbr" -@erase "$(INTDIR)\parser.obj" -@erase "$(INTDIR)\parser.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(INTDIR)\version.obj" -@erase "$(INTDIR)\version.sbr" -@erase "$(OUTDIR)\libisccfg.bsc" -@erase "$(OUTDIR)\libisccfg.exp" -@erase "$(OUTDIR)\libisccfg.lib" -@erase "$(OUTDIR)\libisccfg.pdb" -@erase "..\..\..\Build\Debug\libisccfg.dll" -@erase "..\..\..\Build\Debug\libisccfg.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" /I "include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" @LIBXML2_INC@ @GEOIP_INC@ /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBISCCFG_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\libisccfg.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\libisccfg.bsc" BSC32_SBRS= \ "$(INTDIR)\DLLMain.sbr" \ "$(INTDIR)\aclconf.sbr" \ "$(INTDIR)\dnsconf.sbr" \ "$(INTDIR)\log.sbr" \ "$(INTDIR)\parser.sbr" \ "$(INTDIR)\version.sbr" \ "$(INTDIR)\namedconf.sbr" "$(OUTDIR)\libisccfg.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../dns/win32/debug/libdns.lib ../../isc/win32/debug/libisc.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\libisccfg.pdb" /debug @MACHINE@ /def:".\libisccfg.def" /out:"../../../Build/Debug/libisccfg.dll" /implib:"$(OUTDIR)\libisccfg.lib" /pdbtype:sept DEF_FILE= \ ".\libisccfg.def" LINK32_OBJS= \ "$(INTDIR)\DLLMain.obj" \ "$(INTDIR)\aclconf.obj" \ "$(INTDIR)\dnsconf.obj" \ "$(INTDIR)\log.obj" \ "$(INTDIR)\parser.obj" \ "$(INTDIR)\version.obj" \ "$(INTDIR)\namedconf.obj" \ "..\..\dns\win32\Debug\libdns.lib" \ "..\..\isc\win32\Debug\libisc.lib" "..\..\..\Build\Debug\libisccfg.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_DLL) !ENDIF .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("libisccfg.dep") !INCLUDE "libisccfg.dep" !ELSE !MESSAGE Warning: cannot find "libisccfg.dep" !ENDIF !ENDIF !IF "$(CFG)" == "libisccfg - @PLATFORM@ Release" || "$(CFG)" == "libisccfg - @PLATFORM@ Debug" SOURCE=.\DLLMain.c !IF "$(CFG)" == "libisccfg - @PLATFORM@ Release" "$(INTDIR)\DLLMain.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisccfg - @PLATFORM@ Debug" "$(INTDIR)\DLLMain.obj" "$(INTDIR)\DLLMain.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=..\aclconf.c !IF "$(CFG)" == "libisccfg - @PLATFORM@ Release" "$(INTDIR)\aclconf.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisccfg - @PLATFORM@ Debug" "$(INTDIR)\aclconf.obj" "$(INTDIR)\aclconf.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\dnsconf.c !IF "$(CFG)" == "libisccfg - @PLATFORM@ Release" "$(INTDIR)\dnsconf.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisccfg - @PLATFORM@ Debug" "$(INTDIR)\dnsconf.obj" "$(INTDIR)\dnsconf.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\log.c !IF "$(CFG)" == "libisccfg - @PLATFORM@ Release" "$(INTDIR)\log.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisccfg - @PLATFORM@ Debug" "$(INTDIR)\log.obj" "$(INTDIR)\log.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\namedconf.c !IF "$(CFG)" == "libisccfg - @PLATFORM@ Release" "$(INTDIR)\namedconf.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisccfg - @PLATFORM@ Debug" "$(INTDIR)\namedconf.obj" "$(INTDIR)\namedconf.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\parser.c !IF "$(CFG)" == "libisccfg - @PLATFORM@ Release" "$(INTDIR)\parser.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisccfg - @PLATFORM@ Debug" "$(INTDIR)\parser.obj" "$(INTDIR)\parser.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=.\version.c !IF "$(CFG)" == "libisccfg - @PLATFORM@ Release" "$(INTDIR)\version.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisccfg - @PLATFORM@ Debug" "$(INTDIR)\version.obj" "$(INTDIR)\version.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF !IF "$(CFG)" == "libisccfg - @PLATFORM@ Release" "libdns - @PLATFORM@ Release" : cd "..\..\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" cd "..\..\isccfg\win32" "libdns - @PLATFORM@ ReleaseCLEAN" : cd "..\..\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\isccfg\win32" "libisc - @PLATFORM@ Release" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" cd "..\..\isccfg\win32" "libisc - @PLATFORM@ ReleaseCLEAN" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\isccfg\win32" !ELSEIF "$(CFG)" == "libisccfg - @PLATFORM@ Debug" "libdns - @PLATFORM@ Debug" : cd "..\..\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" cd "..\..\isccfg\win32" "libdns - @PLATFORM@ DebugCLEAN" : cd "..\..\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\isccfg\win32" "libisc - @PLATFORM@ Debug" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" cd "..\..\isccfg\win32" "libisc - @PLATFORM@ DebugCLEAN" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\isccfg\win32" !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/lib/isccfg/win32/libisccfg.dsp.in0000644000470500017500000001276312664710322021412 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="libisccfg" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Dynamic-Link Library" 0x0102 CFG=libisccfg - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "libisccfg.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "libisccfg.mak" CFG="libisccfg - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "libisccfg - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE "libisccfg - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "libisccfg - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "libisccfg_EXPORTS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" /I "include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" @LIBXML2_INC@ @GEOIP_INC@ /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ /D "LIBISCCFG_EXPORTS" @COPTY@ /FD /c # SUBTRACT CPP /X # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll @MACHINE@ # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../dns/win32/Release/libdns.lib ../../isc/win32/Release/libisc.lib /nologo /dll @MACHINE@ /out:"../../../Build/Release/libisccfg.dll" !ELSEIF "$(CFG)" == "libisccfg - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "libisccfg_EXPORTS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" /I "include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" @LIBXML2_INC@ @GEOIP_INC@ /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBISCCFG_EXPORTS" /FR @COPTY@ /FD /GZ /c # SUBTRACT CPP /X # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../dns/win32/debug/libdns.lib ../../isc/win32/debug/libisc.lib /nologo /dll /debug @MACHINE@ /out:"../../../Build/Debug/libisccfg.dll" /pdbtype:sept !ENDIF # Begin Target # Name "libisccfg - @PLATFORM@ Release" # Name "libisccfg - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.\DLLMain.c # End Source File # Begin Source File SOURCE=..\aclconf.c # End Source File # Begin Source File SOURCE=..\dnsconf.c # End Source File # Begin Source File SOURCE=..\log.c # End Source File # Begin Source File SOURCE=..\namedconf.c # End Source File # Begin Source File SOURCE=..\parser.c # End Source File # Begin Source File SOURCE=.\version.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=..\include\isccfg\cfg.h # End Source File # Begin Source File SOURCE=..\include\isccfg\check.h # End Source File # Begin Source File SOURCE=..\include\isccfg\grammar.h # End Source File # Begin Source File SOURCE=..\include\isccfg\aclconf.h # End Source File # Begin Source File SOURCE=..\include\isccfg\dnsconf.h # End Source File # Begin Source File SOURCE=..\include\isccfg\log.h # End Source File # Begin Source File SOURCE=..\include\isccfg\namedconf.h # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # Begin Source File SOURCE=.\libisccfg.def # End Source File # End Target # End Project bind9-9.10.3.dfsg.P4/lib/isccfg/aclconf.c0000644000470500017500000006125712664710322017161 0ustar lamontlamont/* * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #include #include #include /* Required for HP/UX (and others?) */ #include #include #include #include #include #include #include #ifdef HAVE_GEOIP #include #include #endif /* HAVE_GEOIP */ #define LOOP_MAGIC ISC_MAGIC('L','O','O','P') isc_result_t cfg_aclconfctx_create(isc_mem_t *mctx, cfg_aclconfctx_t **ret) { isc_result_t result; cfg_aclconfctx_t *actx; REQUIRE(mctx != NULL); REQUIRE(ret != NULL && *ret == NULL); actx = isc_mem_get(mctx, sizeof(*actx)); if (actx == NULL) return (ISC_R_NOMEMORY); result = isc_refcount_init(&actx->references, 1); if (result != ISC_R_SUCCESS) goto cleanup; actx->mctx = NULL; isc_mem_attach(mctx, &actx->mctx); ISC_LIST_INIT(actx->named_acl_cache); #ifdef HAVE_GEOIP actx->geoip = NULL; #endif *ret = actx; return (ISC_R_SUCCESS); cleanup: isc_mem_put(mctx, actx, sizeof(*actx)); return (result); } void cfg_aclconfctx_attach(cfg_aclconfctx_t *src, cfg_aclconfctx_t **dest) { REQUIRE(src != NULL); REQUIRE(dest != NULL && *dest == NULL); isc_refcount_increment(&src->references, NULL); *dest = src; } void cfg_aclconfctx_detach(cfg_aclconfctx_t **actxp) { cfg_aclconfctx_t *actx; dns_acl_t *dacl, *next; unsigned int refs; REQUIRE(actxp != NULL && *actxp != NULL); actx = *actxp; isc_refcount_decrement(&actx->references, &refs); if (refs == 0) { for (dacl = ISC_LIST_HEAD(actx->named_acl_cache); dacl != NULL; dacl = next) { next = ISC_LIST_NEXT(dacl, nextincache); ISC_LIST_UNLINK(actx->named_acl_cache, dacl, nextincache); dns_acl_detach(&dacl); } isc_mem_putanddetach(&actx->mctx, actx, sizeof(*actx)); } *actxp = NULL; } /* * Find the definition of the named acl whose name is "name". */ static isc_result_t get_acl_def(const cfg_obj_t *cctx, const char *name, const cfg_obj_t **ret) { isc_result_t result; const cfg_obj_t *acls = NULL; const cfg_listelt_t *elt; result = cfg_map_get(cctx, "acl", &acls); if (result != ISC_R_SUCCESS) return (result); for (elt = cfg_list_first(acls); elt != NULL; elt = cfg_list_next(elt)) { const cfg_obj_t *acl = cfg_listelt_value(elt); const char *aclname = cfg_obj_asstring(cfg_tuple_get(acl, "name")); if (strcasecmp(aclname, name) == 0) { if (ret != NULL) { *ret = cfg_tuple_get(acl, "value"); } return (ISC_R_SUCCESS); } } return (ISC_R_NOTFOUND); } static isc_result_t convert_named_acl(const cfg_obj_t *nameobj, const cfg_obj_t *cctx, isc_log_t *lctx, cfg_aclconfctx_t *ctx, isc_mem_t *mctx, unsigned int nest_level, dns_acl_t **target) { isc_result_t result; const cfg_obj_t *cacl = NULL; dns_acl_t *dacl; dns_acl_t loop; const char *aclname = cfg_obj_asstring(nameobj); /* Look for an already-converted version. */ for (dacl = ISC_LIST_HEAD(ctx->named_acl_cache); dacl != NULL; dacl = ISC_LIST_NEXT(dacl, nextincache)) { if (strcasecmp(aclname, dacl->name) == 0) { if (ISC_MAGIC_VALID(dacl, LOOP_MAGIC)) { cfg_obj_log(nameobj, lctx, ISC_LOG_ERROR, "acl loop detected: %s", aclname); return (ISC_R_FAILURE); } dns_acl_attach(dacl, target); return (ISC_R_SUCCESS); } } /* Not yet converted. Convert now. */ result = get_acl_def(cctx, aclname, &cacl); if (result != ISC_R_SUCCESS) { cfg_obj_log(nameobj, lctx, ISC_LOG_WARNING, "undefined ACL '%s'", aclname); return (result); } /* * Add a loop detection element. */ memset(&loop, 0, sizeof(loop)); ISC_LINK_INIT(&loop, nextincache); DE_CONST(aclname, loop.name); loop.magic = LOOP_MAGIC; ISC_LIST_APPEND(ctx->named_acl_cache, &loop, nextincache); result = cfg_acl_fromconfig(cacl, cctx, lctx, ctx, mctx, nest_level, &dacl); ISC_LIST_UNLINK(ctx->named_acl_cache, &loop, nextincache); loop.magic = 0; loop.name = NULL; if (result != ISC_R_SUCCESS) return (result); dacl->name = isc_mem_strdup(dacl->mctx, aclname); if (dacl->name == NULL) return (ISC_R_NOMEMORY); ISC_LIST_APPEND(ctx->named_acl_cache, dacl, nextincache); dns_acl_attach(dacl, target); return (ISC_R_SUCCESS); } static isc_result_t convert_keyname(const cfg_obj_t *keyobj, isc_log_t *lctx, isc_mem_t *mctx, dns_name_t *dnsname) { isc_result_t result; isc_buffer_t buf; dns_fixedname_t fixname; unsigned int keylen; const char *txtname = cfg_obj_asstring(keyobj); keylen = strlen(txtname); isc_buffer_constinit(&buf, txtname, keylen); isc_buffer_add(&buf, keylen); dns_fixedname_init(&fixname); result = dns_name_fromtext(dns_fixedname_name(&fixname), &buf, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) { cfg_obj_log(keyobj, lctx, ISC_LOG_WARNING, "key name '%s' is not a valid domain name", txtname); return (result); } return (dns_name_dup(dns_fixedname_name(&fixname), mctx, dnsname)); } /* * Recursively pre-parse an ACL definition to find the total number * of non-IP-prefix elements (localhost, localnets, key) in all nested * ACLs, so that the parent will have enough space allocated for the * elements table after all the nested ACLs have been merged in to the * parent. */ static isc_result_t count_acl_elements(const cfg_obj_t *caml, const cfg_obj_t *cctx, isc_log_t *lctx, cfg_aclconfctx_t *ctx, isc_mem_t *mctx, isc_uint32_t *count, isc_boolean_t *has_negative) { const cfg_listelt_t *elt; isc_result_t result; isc_uint32_t n = 0; REQUIRE(count != NULL); if (has_negative != NULL) *has_negative = ISC_FALSE; for (elt = cfg_list_first(caml); elt != NULL; elt = cfg_list_next(elt)) { const cfg_obj_t *ce = cfg_listelt_value(elt); /* might be a negated element, in which case get the value. */ if (cfg_obj_istuple(ce)) { const cfg_obj_t *negated = cfg_tuple_get(ce, "negated"); if (! cfg_obj_isvoid(negated)) { ce = negated; if (has_negative != NULL) *has_negative = ISC_TRUE; } } if (cfg_obj_istype(ce, &cfg_type_keyref)) { n++; } else if (cfg_obj_islist(ce)) { isc_boolean_t negative; isc_uint32_t sub; result = count_acl_elements(ce, cctx, lctx, ctx, mctx, &sub, &negative); if (result != ISC_R_SUCCESS) return (result); n += sub; if (negative) n++; #ifdef HAVE_GEOIP } else if (cfg_obj_istuple(ce) && cfg_obj_isvoid(cfg_tuple_get(ce, "negated"))) { n++; #endif /* HAVE_GEOIP */ } else if (cfg_obj_isstring(ce)) { const char *name = cfg_obj_asstring(ce); if (strcasecmp(name, "localhost") == 0 || strcasecmp(name, "localnets") == 0) { n++; } else if (strcasecmp(name, "any") != 0 && strcasecmp(name, "none") != 0) { dns_acl_t *inneracl = NULL; /* * Convert any named acls we reference now if * they have not already been converted. */ result = convert_named_acl(ce, cctx, lctx, ctx, mctx, 0, &inneracl); if (result == ISC_R_SUCCESS) { if (inneracl->has_negatives) n++; else n += inneracl->length; dns_acl_detach(&inneracl); } else return (result); } } } *count = n; return (ISC_R_SUCCESS); } #ifdef HAVE_GEOIP static dns_geoip_subtype_t get_subtype(const cfg_obj_t *obj, isc_log_t *lctx, dns_geoip_subtype_t subtype, const char *dbname) { if (dbname == NULL) return (subtype); switch (subtype) { case dns_geoip_countrycode: if (strcasecmp(dbname, "city") == 0) return (dns_geoip_city_countrycode); else if (strcasecmp(dbname, "region") == 0) return (dns_geoip_region_countrycode); else if (strcasecmp(dbname, "country") == 0) return (dns_geoip_country_code); cfg_obj_log(obj, lctx, ISC_LOG_ERROR, "invalid GeoIP DB specified for " "country search: ignored"); return (subtype); case dns_geoip_countrycode3: if (strcasecmp(dbname, "city") == 0) return (dns_geoip_city_countrycode3); else if (strcasecmp(dbname, "country") == 0) return (dns_geoip_country_code3); cfg_obj_log(obj, lctx, ISC_LOG_ERROR, "invalid GeoIP DB specified for " "country search: ignored"); return (subtype); case dns_geoip_countryname: if (strcasecmp(dbname, "city") == 0) return (dns_geoip_city_countryname); else if (strcasecmp(dbname, "country") == 0) return (dns_geoip_country_name); cfg_obj_log(obj, lctx, ISC_LOG_ERROR, "invalid GeoIP DB specified for " "country search: ignored"); return (subtype); case dns_geoip_region: if (strcasecmp(dbname, "city") == 0) return (dns_geoip_city_region); else if (strcasecmp(dbname, "region") == 0) return (dns_geoip_region_code); cfg_obj_log(obj, lctx, ISC_LOG_ERROR, "invalid GeoIP DB specified for " "region search: ignored"); return (subtype); case dns_geoip_regionname: if (strcasecmp(dbname, "city") == 0) return (dns_geoip_city_region); else if (strcasecmp(dbname, "region") == 0) return (dns_geoip_region_name); cfg_obj_log(obj, lctx, ISC_LOG_ERROR, "invalid GeoIP DB specified for " "region search: ignored"); return (subtype); /* * Log a warning if the wrong database was specified * on an unambiguous query */ case dns_geoip_city_name: case dns_geoip_city_postalcode: case dns_geoip_city_metrocode: case dns_geoip_city_areacode: case dns_geoip_city_continentcode: case dns_geoip_city_timezonecode: if (strcasecmp(dbname, "city") != 0) cfg_obj_log(obj, lctx, ISC_LOG_WARNING, "invalid GeoIP DB specified for " "a 'city'-only search type: ignoring"); return (subtype); case dns_geoip_isp_name: if (strcasecmp(dbname, "isp") != 0) cfg_obj_log(obj, lctx, ISC_LOG_WARNING, "invalid GeoIP DB specified for " "an 'isp' search: ignoring"); return (subtype); case dns_geoip_org_name: if (strcasecmp(dbname, "org") != 0) cfg_obj_log(obj, lctx, ISC_LOG_WARNING, "invalid GeoIP DB specified for " "an 'org' search: ignoring"); return (subtype); case dns_geoip_as_asnum: if (strcasecmp(dbname, "asnum") != 0) cfg_obj_log(obj, lctx, ISC_LOG_WARNING, "invalid GeoIP DB specified for " "an 'asnum' search: ignoring"); return (subtype); case dns_geoip_domain_name: if (strcasecmp(dbname, "domain") != 0) cfg_obj_log(obj, lctx, ISC_LOG_WARNING, "invalid GeoIP DB specified for " "a 'domain' search: ignoring"); return (subtype); case dns_geoip_netspeed_id: if (strcasecmp(dbname, "netspeed") != 0) cfg_obj_log(obj, lctx, ISC_LOG_WARNING, "invalid GeoIP DB specified for " "a 'netspeed' search: ignoring"); return (subtype); default: INSIST(0); } } static isc_boolean_t geoip_can_answer(dns_aclelement_t *elt, cfg_aclconfctx_t *ctx) { if (ctx->geoip == NULL) return (ISC_TRUE); switch (elt->geoip_elem.subtype) { case dns_geoip_countrycode: case dns_geoip_countrycode3: case dns_geoip_countryname: if (ctx->geoip->city_v4 != NULL || ctx->geoip->city_v6 != NULL || ctx->geoip->country_v4 != NULL || ctx->geoip->country_v6 != NULL || ctx->geoip->region != NULL) return (ISC_TRUE); case dns_geoip_region: case dns_geoip_regionname: if (ctx->geoip->city_v4 != NULL || ctx->geoip->city_v6 != NULL || ctx->geoip->region != NULL) return (ISC_TRUE); case dns_geoip_country_code: case dns_geoip_country_code3: case dns_geoip_country_name: if (ctx->geoip->country_v4 != NULL || ctx->geoip->country_v6 != NULL) return (ISC_TRUE); case dns_geoip_region_countrycode: case dns_geoip_region_code: case dns_geoip_region_name: if (ctx->geoip->region != NULL) return (ISC_TRUE); case dns_geoip_city_countrycode: case dns_geoip_city_countrycode3: case dns_geoip_city_countryname: case dns_geoip_city_region: case dns_geoip_city_regionname: case dns_geoip_city_name: case dns_geoip_city_postalcode: case dns_geoip_city_metrocode: case dns_geoip_city_areacode: case dns_geoip_city_continentcode: case dns_geoip_city_timezonecode: if (ctx->geoip->city_v4 != NULL || ctx->geoip->city_v6 != NULL) return (ISC_TRUE); case dns_geoip_isp_name: if (ctx->geoip->isp != NULL) return (ISC_TRUE); case dns_geoip_org_name: if (ctx->geoip->org != NULL) return (ISC_TRUE); case dns_geoip_as_asnum: if (ctx->geoip->as != NULL) return (ISC_TRUE); case dns_geoip_domain_name: if (ctx->geoip->domain != NULL) return (ISC_TRUE); case dns_geoip_netspeed_id: if (ctx->geoip->netspeed != NULL) return (ISC_TRUE); } return (ISC_FALSE); } static isc_result_t parse_geoip_element(const cfg_obj_t *obj, isc_log_t *lctx, cfg_aclconfctx_t *ctx, dns_aclelement_t *dep) { const cfg_obj_t *ge; const char *dbname = NULL; const char *stype, *search; dns_geoip_subtype_t subtype; dns_aclelement_t de; size_t len; REQUIRE(dep != NULL); de = *dep; ge = cfg_tuple_get(obj, "db"); if (!cfg_obj_isvoid(ge)) dbname = cfg_obj_asstring(ge); stype = cfg_obj_asstring(cfg_tuple_get(obj, "subtype")); search = cfg_obj_asstring(cfg_tuple_get(obj, "search")); len = strlen(search); if (len == 0) { cfg_obj_log(obj, lctx, ISC_LOG_ERROR, "zero-length geoip search field"); return (ISC_R_FAILURE); } if (strcasecmp(stype, "country") == 0 && len == 2) { /* Two-letter country code */ subtype = dns_geoip_countrycode; strlcpy(de.geoip_elem.as_string, search, sizeof(de.geoip_elem.as_string)); } else if (strcasecmp(stype, "country") == 0 && len == 3) { /* Three-letter country code */ subtype = dns_geoip_countrycode3; strlcpy(de.geoip_elem.as_string, search, sizeof(de.geoip_elem.as_string)); } else if (strcasecmp(stype, "country") == 0) { /* Country name */ subtype = dns_geoip_countryname; strlcpy(de.geoip_elem.as_string, search, sizeof(de.geoip_elem.as_string)); } else if (strcasecmp(stype, "region") == 0 && len == 2) { /* Two-letter region code */ subtype = dns_geoip_region; strlcpy(de.geoip_elem.as_string, search, sizeof(de.geoip_elem.as_string)); } else if (strcasecmp(stype, "region") == 0) { /* Region name */ subtype = dns_geoip_regionname; strlcpy(de.geoip_elem.as_string, search, sizeof(de.geoip_elem.as_string)); } else if (strcasecmp(stype, "city") == 0) { /* City name */ subtype = dns_geoip_city_name; strlcpy(de.geoip_elem.as_string, search, sizeof(de.geoip_elem.as_string)); } else if (strcasecmp(stype, "postal") == 0 && len < 7) { subtype = dns_geoip_city_postalcode; strlcpy(de.geoip_elem.as_string, search, sizeof(de.geoip_elem.as_string)); } else if (strcasecmp(stype, "postal") == 0) { cfg_obj_log(obj, lctx, ISC_LOG_ERROR, "geoiop postal code (%s) too long", search); return (ISC_R_FAILURE); } else if (strcasecmp(stype, "metro") == 0) { subtype = dns_geoip_city_metrocode; de.geoip_elem.as_int = atoi(search); } else if (strcasecmp(stype, "area") == 0) { subtype = dns_geoip_city_areacode; de.geoip_elem.as_int = atoi(search); } else if (strcasecmp(stype, "tz") == 0) { subtype = dns_geoip_city_timezonecode; strlcpy(de.geoip_elem.as_string, search, sizeof(de.geoip_elem.as_string)); } else if (strcasecmp(stype, "continent") == 0 && len == 2) { /* Two-letter continent code */ subtype = dns_geoip_city_continentcode; strlcpy(de.geoip_elem.as_string, search, sizeof(de.geoip_elem.as_string)); } else if (strcasecmp(stype, "continent") == 0) { cfg_obj_log(obj, lctx, ISC_LOG_ERROR, "geoiop continent code (%s) too long", search); return (ISC_R_FAILURE); } else if (strcasecmp(stype, "isp") == 0) { subtype = dns_geoip_isp_name; strlcpy(de.geoip_elem.as_string, search, sizeof(de.geoip_elem.as_string)); } else if (strcasecmp(stype, "asnum") == 0) { subtype = dns_geoip_as_asnum; strlcpy(de.geoip_elem.as_string, search, sizeof(de.geoip_elem.as_string)); } else if (strcasecmp(stype, "org") == 0) { subtype = dns_geoip_org_name; strlcpy(de.geoip_elem.as_string, search, sizeof(de.geoip_elem.as_string)); } else if (strcasecmp(stype, "domain") == 0) { subtype = dns_geoip_domain_name; strlcpy(de.geoip_elem.as_string, search, sizeof(de.geoip_elem.as_string)); } else if (strcasecmp(stype, "netspeed") == 0) { subtype = dns_geoip_netspeed_id; de.geoip_elem.as_int = atoi(search); } else INSIST(0); de.geoip_elem.subtype = get_subtype(obj, lctx, subtype, dbname); if (! geoip_can_answer(&de, ctx)) { cfg_obj_log(obj, lctx, ISC_LOG_ERROR, "no GeoIP database installed which can answer " "queries of type '%s'", stype); return (ISC_R_FAILURE); } *dep = de; return (ISC_R_SUCCESS); } #endif isc_result_t cfg_acl_fromconfig(const cfg_obj_t *caml, const cfg_obj_t *cctx, isc_log_t *lctx, cfg_aclconfctx_t *ctx, isc_mem_t *mctx, unsigned int nest_level, dns_acl_t **target) { return (cfg_acl_fromconfig2(caml, cctx, lctx, ctx, mctx, nest_level, 0, target)); } isc_result_t cfg_acl_fromconfig2(const cfg_obj_t *caml, const cfg_obj_t *cctx, isc_log_t *lctx, cfg_aclconfctx_t *ctx, isc_mem_t *mctx, unsigned int nest_level, isc_uint16_t family, dns_acl_t **target) { isc_result_t result; dns_acl_t *dacl = NULL, *inneracl = NULL; dns_aclelement_t *de; const cfg_listelt_t *elt; dns_iptable_t *iptab; int new_nest_level = 0; if (nest_level != 0) new_nest_level = nest_level - 1; REQUIRE(target != NULL); REQUIRE(*target == NULL || DNS_ACL_VALID(*target)); if (*target != NULL) { /* * If target already points to an ACL, then we're being * called recursively to configure a nested ACL. The * nested ACL's contents should just be absorbed into its * parent ACL. */ dns_acl_attach(*target, &dacl); dns_acl_detach(target); } else { /* * Need to allocate a new ACL structure. Count the items * in the ACL definition that will require space in the * elements table. (Note that if nest_level is nonzero, * *everything* goes in the elements table.) */ isc_uint32_t nelem; if (nest_level == 0) { result = count_acl_elements(caml, cctx, lctx, ctx, mctx, &nelem, NULL); if (result != ISC_R_SUCCESS) return (result); } else nelem = cfg_list_length(caml, ISC_FALSE); result = dns_acl_create(mctx, nelem, &dacl); if (result != ISC_R_SUCCESS) return (result); } de = dacl->elements; for (elt = cfg_list_first(caml); elt != NULL; elt = cfg_list_next(elt)) { const cfg_obj_t *ce = cfg_listelt_value(elt); isc_boolean_t neg = ISC_FALSE; INSIST(dacl->length <= dacl->alloc); if (cfg_obj_istuple(ce)) { /* Might be a negated element */ const cfg_obj_t *negated = cfg_tuple_get(ce, "negated"); if (! cfg_obj_isvoid(negated)) { neg = ISC_TRUE; dacl->has_negatives = ISC_TRUE; ce = negated; } } /* * If nest_level is nonzero, then every element is * to be stored as a separate, nested ACL rather than * merged into the main iptable. */ iptab = dacl->iptable; if (nest_level != 0) { result = dns_acl_create(mctx, cfg_list_length(ce, ISC_FALSE), &de->nestedacl); if (result != ISC_R_SUCCESS) goto cleanup; iptab = de->nestedacl->iptable; } if (cfg_obj_isnetprefix(ce)) { /* Network prefix */ isc_netaddr_t addr; unsigned int bitlen; cfg_obj_asnetprefix(ce, &addr, &bitlen); if (family != 0 && family != addr.family) { char buf[ISC_NETADDR_FORMATSIZE + 1]; isc_netaddr_format(&addr, buf, sizeof(buf)); cfg_obj_log(ce, lctx, ISC_LOG_WARNING, "'%s': incorrect address family; " "ignoring", buf); if (nest_level != 0) dns_acl_detach(&de->nestedacl); continue; } /* * If nesting ACLs (nest_level != 0), we negate * the nestedacl element, not the iptable entry. */ result = dns_iptable_addprefix(iptab, &addr, bitlen, ISC_TF(nest_level != 0 || !neg)); if (result != ISC_R_SUCCESS) goto cleanup; if (nest_level > 0) { INSIST(dacl->length < dacl->alloc); de->type = dns_aclelementtype_nestedacl; de->negative = neg; } else continue; } else if (cfg_obj_islist(ce)) { /* * If we're nesting ACLs, put the nested * ACL onto the elements list; otherwise * merge it into *this* ACL. We nest ACLs * in two cases: 1) sortlist, 2) if the * nested ACL contains negated members. */ if (inneracl != NULL) dns_acl_detach(&inneracl); result = cfg_acl_fromconfig(ce, cctx, lctx, ctx, mctx, new_nest_level, &inneracl); if (result != ISC_R_SUCCESS) goto cleanup; nested_acl: if (nest_level > 0 || inneracl->has_negatives) { INSIST(dacl->length < dacl->alloc); de->type = dns_aclelementtype_nestedacl; de->negative = neg; if (de->nestedacl != NULL) dns_acl_detach(&de->nestedacl); dns_acl_attach(inneracl, &de->nestedacl); dns_acl_detach(&inneracl); /* Fall through. */ } else { INSIST(dacl->length + inneracl->length <= dacl->alloc); dns_acl_merge(dacl, inneracl, ISC_TF(!neg)); de += inneracl->length; /* elements added */ dns_acl_detach(&inneracl); INSIST(dacl->length <= dacl->alloc); continue; } } else if (cfg_obj_istype(ce, &cfg_type_keyref)) { /* Key name. */ INSIST(dacl->length < dacl->alloc); de->type = dns_aclelementtype_keyname; de->negative = neg; dns_name_init(&de->keyname, NULL); result = convert_keyname(ce, lctx, mctx, &de->keyname); if (result != ISC_R_SUCCESS) goto cleanup; #ifdef HAVE_GEOIP } else if (cfg_obj_istuple(ce) && cfg_obj_isvoid(cfg_tuple_get(ce, "negated"))) { INSIST(dacl->length < dacl->alloc); result = parse_geoip_element(ce, lctx, ctx, de); if (result != ISC_R_SUCCESS) goto cleanup; de->type = dns_aclelementtype_geoip; de->negative = neg; #endif /* HAVE_GEOIP */ } else if (cfg_obj_isstring(ce)) { /* ACL name. */ const char *name = cfg_obj_asstring(ce); if (strcasecmp(name, "any") == 0) { /* Iptable entry with zero bit length. */ result = dns_iptable_addprefix(iptab, NULL, 0, ISC_TF(nest_level != 0 || !neg)); if (result != ISC_R_SUCCESS) goto cleanup; if (nest_level != 0) { INSIST(dacl->length < dacl->alloc); de->type = dns_aclelementtype_nestedacl; de->negative = neg; } else continue; } else if (strcasecmp(name, "none") == 0) { /* none == !any */ /* * We don't unconditional set * dacl->has_negatives and * de->negative to true so we can handle * "!none;". */ result = dns_iptable_addprefix(iptab, NULL, 0, ISC_TF(nest_level != 0 || neg)); if (result != ISC_R_SUCCESS) goto cleanup; if (!neg) dacl->has_negatives = !neg; if (nest_level != 0) { INSIST(dacl->length < dacl->alloc); de->type = dns_aclelementtype_nestedacl; de->negative = !neg; } else continue; } else if (strcasecmp(name, "localhost") == 0) { INSIST(dacl->length < dacl->alloc); de->type = dns_aclelementtype_localhost; de->negative = neg; } else if (strcasecmp(name, "localnets") == 0) { INSIST(dacl->length < dacl->alloc); de->type = dns_aclelementtype_localnets; de->negative = neg; } else { if (inneracl != NULL) dns_acl_detach(&inneracl); /* * This call should just find the cached * of the named acl. */ result = convert_named_acl(ce, cctx, lctx, ctx, mctx, new_nest_level, &inneracl); if (result != ISC_R_SUCCESS) goto cleanup; goto nested_acl; } } else { cfg_obj_log(ce, lctx, ISC_LOG_WARNING, "address match list contains " "unsupported element type"); result = ISC_R_FAILURE; goto cleanup; } /* * This should only be reached for localhost, localnets * and keyname elements, and nested ACLs if nest_level is * nonzero (i.e., in sortlists). */ if (de->nestedacl != NULL && de->type != dns_aclelementtype_nestedacl) dns_acl_detach(&de->nestedacl); dacl->node_count++; de->node_num = dacl->node_count; dacl->length++; de++; INSIST(dacl->length <= dacl->alloc); } dns_acl_attach(dacl, target); result = ISC_R_SUCCESS; cleanup: if (inneracl != NULL) dns_acl_detach(&inneracl); dns_acl_detach(&dacl); return (result); } bind9-9.10.3.dfsg.P4/lib/isccfg/log.c0000644000470500017500000000301712664710322016323 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: log.c,v 1.11 2007/06/19 23:47:22 tbox Exp $ */ /*! \file */ #include #include #include /*% * When adding a new category, be sure to add the appropriate * \#define to . */ LIBISCCFG_EXTERNAL_DATA isc_logcategory_t cfg_categories[] = { { "config", 0 }, { NULL, 0 } }; /*% * When adding a new module, be sure to add the appropriate * \#define to . */ LIBISCCFG_EXTERNAL_DATA isc_logmodule_t cfg_modules[] = { { "isccfg/parser", 0 }, { NULL, 0 } }; void cfg_log_init(isc_log_t *lctx) { REQUIRE(lctx != NULL); isc_log_registercategories(lctx, cfg_categories); isc_log_registermodules(lctx, cfg_modules); } bind9-9.10.3.dfsg.P4/lib/isccfg/parser.c0000644000470500017500000020064612664710322017045 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Shorthand */ #define CAT CFG_LOGCATEGORY_CONFIG #define MOD CFG_LOGMODULE_PARSER #define MAP_SYM 1 /* Unique type for isc_symtab */ #define TOKEN_STRING(pctx) (pctx->token.value.as_textregion.base) /* Check a return value. */ #define CHECK(op) \ do { result = (op); \ if (result != ISC_R_SUCCESS) goto cleanup; \ } while (0) /* Clean up a configuration object if non-NULL. */ #define CLEANUP_OBJ(obj) \ do { if ((obj) != NULL) cfg_obj_destroy(pctx, &(obj)); } while (0) /* * Forward declarations of static functions. */ static void free_tuple(cfg_parser_t *pctx, cfg_obj_t *obj); static isc_result_t parse_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); static void print_list(cfg_printer_t *pctx, const cfg_obj_t *obj); static void free_list(cfg_parser_t *pctx, cfg_obj_t *obj); static isc_result_t create_listelt(cfg_parser_t *pctx, cfg_listelt_t **eltp); static isc_result_t create_string(cfg_parser_t *pctx, const char *contents, const cfg_type_t *type, cfg_obj_t **ret); static void free_string(cfg_parser_t *pctx, cfg_obj_t *obj); static isc_result_t create_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp); static void free_map(cfg_parser_t *pctx, cfg_obj_t *obj); static isc_result_t parse_symtab_elt(cfg_parser_t *pctx, const char *name, cfg_type_t *elttype, isc_symtab_t *symtab, isc_boolean_t callback); static void free_noop(cfg_parser_t *pctx, cfg_obj_t *obj); static isc_result_t cfg_getstringtoken(cfg_parser_t *pctx); static void parser_complain(cfg_parser_t *pctx, isc_boolean_t is_warning, unsigned int flags, const char *format, va_list args); /* * Data representations. These correspond to members of the * "value" union in struct cfg_obj (except "void", which does * not need a union member). */ cfg_rep_t cfg_rep_uint32 = { "uint32", free_noop }; cfg_rep_t cfg_rep_uint64 = { "uint64", free_noop }; cfg_rep_t cfg_rep_string = { "string", free_string }; cfg_rep_t cfg_rep_boolean = { "boolean", free_noop }; cfg_rep_t cfg_rep_map = { "map", free_map }; cfg_rep_t cfg_rep_list = { "list", free_list }; cfg_rep_t cfg_rep_tuple = { "tuple", free_tuple }; cfg_rep_t cfg_rep_sockaddr = { "sockaddr", free_noop }; cfg_rep_t cfg_rep_netprefix = { "netprefix", free_noop }; cfg_rep_t cfg_rep_void = { "void", free_noop }; cfg_rep_t cfg_rep_fixedpoint = { "fixedpoint", free_noop }; /* * Configuration type definitions. */ /*% * An implicit list. These are formed by clauses that occur multiple times. */ static cfg_type_t cfg_type_implicitlist = { "implicitlist", NULL, print_list, NULL, &cfg_rep_list, NULL }; /* Functions. */ void cfg_print_obj(cfg_printer_t *pctx, const cfg_obj_t *obj) { obj->type->print(pctx, obj); } void cfg_print_chars(cfg_printer_t *pctx, const char *text, int len) { pctx->f(pctx->closure, text, len); } static void print_open(cfg_printer_t *pctx) { cfg_print_chars(pctx, "{\n", 2); pctx->indent++; } static void print_indent(cfg_printer_t *pctx) { int indent = pctx->indent; while (indent > 0) { cfg_print_chars(pctx, "\t", 1); indent--; } } static void print_close(cfg_printer_t *pctx) { pctx->indent--; print_indent(pctx); cfg_print_chars(pctx, "}", 1); } isc_result_t cfg_parse_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; INSIST(ret != NULL && *ret == NULL); result = type->parse(pctx, type, ret); if (result != ISC_R_SUCCESS) return (result); INSIST(*ret != NULL); return (ISC_R_SUCCESS); } void cfg_print(const cfg_obj_t *obj, void (*f)(void *closure, const char *text, int textlen), void *closure) { cfg_printx(obj, 0, f, closure); } void cfg_printx(const cfg_obj_t *obj, unsigned int flags, void (*f)(void *closure, const char *text, int textlen), void *closure) { cfg_printer_t pctx; pctx.f = f; pctx.closure = closure; pctx.indent = 0; pctx.flags = flags; obj->type->print(&pctx, obj); } /* Tuples. */ isc_result_t cfg_create_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; const cfg_tuplefielddef_t *fields = type->of; const cfg_tuplefielddef_t *f; cfg_obj_t *obj = NULL; unsigned int nfields = 0; int i; for (f = fields; f->name != NULL; f++) nfields++; CHECK(cfg_create_obj(pctx, type, &obj)); obj->value.tuple = isc_mem_get(pctx->mctx, nfields * sizeof(cfg_obj_t *)); if (obj->value.tuple == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } for (f = fields, i = 0; f->name != NULL; f++, i++) obj->value.tuple[i] = NULL; *ret = obj; return (ISC_R_SUCCESS); cleanup: if (obj != NULL) isc_mem_put(pctx->mctx, obj, sizeof(*obj)); return (result); } isc_result_t cfg_parse_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; const cfg_tuplefielddef_t *fields = type->of; const cfg_tuplefielddef_t *f; cfg_obj_t *obj = NULL; unsigned int i; CHECK(cfg_create_tuple(pctx, type, &obj)); for (f = fields, i = 0; f->name != NULL; f++, i++) CHECK(cfg_parse_obj(pctx, f->type, &obj->value.tuple[i])); *ret = obj; return (ISC_R_SUCCESS); cleanup: CLEANUP_OBJ(obj); return (result); } void cfg_print_tuple(cfg_printer_t *pctx, const cfg_obj_t *obj) { unsigned int i; const cfg_tuplefielddef_t *fields = obj->type->of; const cfg_tuplefielddef_t *f; isc_boolean_t need_space = ISC_FALSE; for (f = fields, i = 0; f->name != NULL; f++, i++) { const cfg_obj_t *fieldobj = obj->value.tuple[i]; if (need_space) cfg_print_chars(pctx, " ", 1); cfg_print_obj(pctx, fieldobj); need_space = ISC_TF(fieldobj->type->print != cfg_print_void); } } void cfg_doc_tuple(cfg_printer_t *pctx, const cfg_type_t *type) { const cfg_tuplefielddef_t *fields = type->of; const cfg_tuplefielddef_t *f; isc_boolean_t need_space = ISC_FALSE; for (f = fields; f->name != NULL; f++) { if (need_space) cfg_print_chars(pctx, " ", 1); cfg_doc_obj(pctx, f->type); need_space = ISC_TF(f->type->print != cfg_print_void); } } static void free_tuple(cfg_parser_t *pctx, cfg_obj_t *obj) { unsigned int i; const cfg_tuplefielddef_t *fields = obj->type->of; const cfg_tuplefielddef_t *f; unsigned int nfields = 0; if (obj->value.tuple == NULL) return; for (f = fields, i = 0; f->name != NULL; f++, i++) { CLEANUP_OBJ(obj->value.tuple[i]); nfields++; } isc_mem_put(pctx->mctx, obj->value.tuple, nfields * sizeof(cfg_obj_t *)); } isc_boolean_t cfg_obj_istuple(const cfg_obj_t *obj) { REQUIRE(obj != NULL); return (ISC_TF(obj->type->rep == &cfg_rep_tuple)); } const cfg_obj_t * cfg_tuple_get(const cfg_obj_t *tupleobj, const char* name) { unsigned int i; const cfg_tuplefielddef_t *fields; const cfg_tuplefielddef_t *f; REQUIRE(tupleobj != NULL && tupleobj->type->rep == &cfg_rep_tuple); fields = tupleobj->type->of; for (f = fields, i = 0; f->name != NULL; f++, i++) { if (strcmp(f->name, name) == 0) return (tupleobj->value.tuple[i]); } INSIST(0); return (NULL); } isc_result_t cfg_parse_special(cfg_parser_t *pctx, int special) { isc_result_t result; CHECK(cfg_gettoken(pctx, 0)); if (pctx->token.type == isc_tokentype_special && pctx->token.value.as_char == special) return (ISC_R_SUCCESS); cfg_parser_error(pctx, CFG_LOG_NEAR, "'%c' expected", special); return (ISC_R_UNEXPECTEDTOKEN); cleanup: return (result); } /* * Parse a required semicolon. If it is not there, log * an error and increment the error count but continue * parsing. Since the next token is pushed back, * care must be taken to make sure it is eventually * consumed or an infinite loop may result. */ static isc_result_t parse_semicolon(cfg_parser_t *pctx) { isc_result_t result; CHECK(cfg_gettoken(pctx, 0)); if (pctx->token.type == isc_tokentype_special && pctx->token.value.as_char == ';') return (ISC_R_SUCCESS); cfg_parser_error(pctx, CFG_LOG_BEFORE, "missing ';'"); cfg_ungettoken(pctx); cleanup: return (result); } /* * Parse EOF, logging and returning an error if not there. */ static isc_result_t parse_eof(cfg_parser_t *pctx) { isc_result_t result; CHECK(cfg_gettoken(pctx, 0)); if (pctx->token.type == isc_tokentype_eof) return (ISC_R_SUCCESS); cfg_parser_error(pctx, CFG_LOG_NEAR, "syntax error"); return (ISC_R_UNEXPECTEDTOKEN); cleanup: return (result); } /* A list of files, used internally for pctx->files. */ static cfg_type_t cfg_type_filelist = { "filelist", NULL, print_list, NULL, &cfg_rep_list, &cfg_type_qstring }; isc_result_t cfg_parser_create(isc_mem_t *mctx, isc_log_t *lctx, cfg_parser_t **ret) { isc_result_t result; cfg_parser_t *pctx; isc_lexspecials_t specials; REQUIRE(mctx != NULL); REQUIRE(ret != NULL && *ret == NULL); pctx = isc_mem_get(mctx, sizeof(*pctx)); if (pctx == NULL) return (ISC_R_NOMEMORY); pctx->mctx = NULL; isc_mem_attach(mctx, &pctx->mctx); result = isc_refcount_init(&pctx->references, 1); if (result != ISC_R_SUCCESS) { isc_mem_putanddetach(&pctx->mctx, pctx, sizeof(*pctx)); return (result); } pctx->lctx = lctx; pctx->lexer = NULL; pctx->seen_eof = ISC_FALSE; pctx->ungotten = ISC_FALSE; pctx->errors = 0; pctx->warnings = 0; pctx->open_files = NULL; pctx->closed_files = NULL; pctx->line = 0; pctx->callback = NULL; pctx->callbackarg = NULL; pctx->token.type = isc_tokentype_unknown; pctx->flags = 0; memset(specials, 0, sizeof(specials)); specials['{'] = 1; specials['}'] = 1; specials[';'] = 1; specials['/'] = 1; specials['"'] = 1; specials['!'] = 1; CHECK(isc_lex_create(pctx->mctx, 1024, &pctx->lexer)); isc_lex_setspecials(pctx->lexer, specials); isc_lex_setcomments(pctx->lexer, (ISC_LEXCOMMENT_C | ISC_LEXCOMMENT_CPLUSPLUS | ISC_LEXCOMMENT_SHELL)); CHECK(cfg_create_list(pctx, &cfg_type_filelist, &pctx->open_files)); CHECK(cfg_create_list(pctx, &cfg_type_filelist, &pctx->closed_files)); *ret = pctx; return (ISC_R_SUCCESS); cleanup: if (pctx->lexer != NULL) isc_lex_destroy(&pctx->lexer); CLEANUP_OBJ(pctx->open_files); CLEANUP_OBJ(pctx->closed_files); isc_mem_putanddetach(&pctx->mctx, pctx, sizeof(*pctx)); return (result); } static isc_result_t parser_openfile(cfg_parser_t *pctx, const char *filename) { isc_result_t result; cfg_listelt_t *elt = NULL; cfg_obj_t *stringobj = NULL; result = isc_lex_openfile(pctx->lexer, filename); if (result != ISC_R_SUCCESS) { cfg_parser_error(pctx, 0, "open: %s: %s", filename, isc_result_totext(result)); goto cleanup; } CHECK(create_string(pctx, filename, &cfg_type_qstring, &stringobj)); CHECK(create_listelt(pctx, &elt)); elt->obj = stringobj; ISC_LIST_APPEND(pctx->open_files->value.list, elt, link); return (ISC_R_SUCCESS); cleanup: CLEANUP_OBJ(stringobj); return (result); } void cfg_parser_setcallback(cfg_parser_t *pctx, cfg_parsecallback_t callback, void *arg) { pctx->callback = callback; pctx->callbackarg = arg; } /* * Parse a configuration using a pctx where a lexer has already * been set up with a source. */ static isc_result_t parse2(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *obj = NULL; result = cfg_parse_obj(pctx, type, &obj); if (pctx->errors != 0) { /* Errors have been logged. */ if (result == ISC_R_SUCCESS) result = ISC_R_FAILURE; goto cleanup; } if (result != ISC_R_SUCCESS) { /* Parsing failed but no errors have been logged. */ cfg_parser_error(pctx, 0, "parsing failed"); goto cleanup; } CHECK(parse_eof(pctx)); *ret = obj; return (ISC_R_SUCCESS); cleanup: CLEANUP_OBJ(obj); return (result); } isc_result_t cfg_parse_file(cfg_parser_t *pctx, const char *filename, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; REQUIRE(filename != NULL); CHECK(parser_openfile(pctx, filename)); CHECK(parse2(pctx, type, ret)); cleanup: return (result); } isc_result_t cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; REQUIRE(buffer != NULL); CHECK(isc_lex_openbuffer(pctx->lexer, buffer)); CHECK(parse2(pctx, type, ret)); cleanup: return (result); } void cfg_parser_attach(cfg_parser_t *src, cfg_parser_t **dest) { REQUIRE(src != NULL); REQUIRE(dest != NULL && *dest == NULL); isc_refcount_increment(&src->references, NULL); *dest = src; } void cfg_parser_destroy(cfg_parser_t **pctxp) { cfg_parser_t *pctx = *pctxp; unsigned int refs; isc_refcount_decrement(&pctx->references, &refs); if (refs == 0) { isc_lex_destroy(&pctx->lexer); /* * Cleaning up open_files does not * close the files; that was already done * by closing the lexer. */ CLEANUP_OBJ(pctx->open_files); CLEANUP_OBJ(pctx->closed_files); isc_mem_putanddetach(&pctx->mctx, pctx, sizeof(*pctx)); } *pctxp = NULL; } /* * void */ isc_result_t cfg_parse_void(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { UNUSED(type); return (cfg_create_obj(pctx, &cfg_type_void, ret)); } void cfg_print_void(cfg_printer_t *pctx, const cfg_obj_t *obj) { UNUSED(pctx); UNUSED(obj); } void cfg_doc_void(cfg_printer_t *pctx, const cfg_type_t *type) { UNUSED(pctx); UNUSED(type); } isc_boolean_t cfg_obj_isvoid(const cfg_obj_t *obj) { REQUIRE(obj != NULL); return (ISC_TF(obj->type->rep == &cfg_rep_void)); } cfg_type_t cfg_type_void = { "void", cfg_parse_void, cfg_print_void, cfg_doc_void, &cfg_rep_void, NULL }; /* * Fixed point */ isc_result_t cfg_parse_fixedpoint(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *obj = NULL; size_t n1, n2, n3, l; const char *p; UNUSED(type); CHECK(cfg_gettoken(pctx, 0)); if (pctx->token.type != isc_tokentype_string) { cfg_parser_error(pctx, CFG_LOG_NEAR, "expected fixed point number"); return (ISC_R_UNEXPECTEDTOKEN); } p = TOKEN_STRING(pctx); l = strlen(p); n1 = strspn(p, "0123456789"); n2 = strspn(p + n1, "."); n3 = strspn(p + n1 + n2, "0123456789"); if ((n1 + n2 + n3 != l) || (n1 + n3 == 0) || n1 > 5 || n2 > 1 || n3 > 2) { cfg_parser_error(pctx, CFG_LOG_NEAR, "expected fixed point number"); return (ISC_R_UNEXPECTEDTOKEN); } CHECK(cfg_create_obj(pctx, &cfg_type_fixedpoint, &obj)); obj->value.uint32 = strtoul(p, NULL, 10) * 100; switch (n3) { case 2: obj->value.uint32 += strtoul(p + n1 + n2, NULL, 10); break; case 1: obj->value.uint32 += strtoul(p + n1 + n2, NULL, 10) * 10; break; } *ret = obj; cleanup: return (result); } void cfg_print_fixedpoint(cfg_printer_t *pctx, const cfg_obj_t *obj) { char buf[64]; int n; n = snprintf(buf, sizeof(buf), "%u.%02u", obj->value.uint32/100, obj->value.uint32%100); INSIST(n > 0 && (size_t)n < sizeof(buf)); cfg_print_chars(pctx, buf, strlen(buf)); } isc_uint32_t cfg_obj_asfixedpoint(const cfg_obj_t *obj) { REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_fixedpoint); return (obj->value.uint32); } cfg_type_t cfg_type_fixedpoint = { "fixedpoint", cfg_parse_fixedpoint, cfg_print_fixedpoint, cfg_doc_terminal, &cfg_rep_fixedpoint, NULL }; /* * uint32 */ isc_result_t cfg_parse_uint32(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *obj = NULL; UNUSED(type); CHECK(cfg_gettoken(pctx, ISC_LEXOPT_NUMBER | ISC_LEXOPT_CNUMBER)); if (pctx->token.type != isc_tokentype_number) { cfg_parser_error(pctx, CFG_LOG_NEAR, "expected number"); return (ISC_R_UNEXPECTEDTOKEN); } CHECK(cfg_create_obj(pctx, &cfg_type_uint32, &obj)); obj->value.uint32 = pctx->token.value.as_ulong; *ret = obj; cleanup: return (result); } void cfg_print_cstr(cfg_printer_t *pctx, const char *s) { cfg_print_chars(pctx, s, strlen(s)); } void cfg_print_rawuint(cfg_printer_t *pctx, unsigned int u) { char buf[32]; snprintf(buf, sizeof(buf), "%u", u); cfg_print_cstr(pctx, buf); } void cfg_print_uint32(cfg_printer_t *pctx, const cfg_obj_t *obj) { cfg_print_rawuint(pctx, obj->value.uint32); } isc_boolean_t cfg_obj_isuint32(const cfg_obj_t *obj) { REQUIRE(obj != NULL); return (ISC_TF(obj->type->rep == &cfg_rep_uint32)); } isc_uint32_t cfg_obj_asuint32(const cfg_obj_t *obj) { REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_uint32); return (obj->value.uint32); } cfg_type_t cfg_type_uint32 = { "integer", cfg_parse_uint32, cfg_print_uint32, cfg_doc_terminal, &cfg_rep_uint32, NULL }; /* * uint64 */ isc_boolean_t cfg_obj_isuint64(const cfg_obj_t *obj) { REQUIRE(obj != NULL); return (ISC_TF(obj->type->rep == &cfg_rep_uint64)); } isc_uint64_t cfg_obj_asuint64(const cfg_obj_t *obj) { REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_uint64); return (obj->value.uint64); } void cfg_print_uint64(cfg_printer_t *pctx, const cfg_obj_t *obj) { char buf[32]; snprintf(buf, sizeof(buf), "%" ISC_PRINT_QUADFORMAT "u", obj->value.uint64); cfg_print_cstr(pctx, buf); } cfg_type_t cfg_type_uint64 = { "64_bit_integer", NULL, cfg_print_uint64, cfg_doc_terminal, &cfg_rep_uint64, NULL }; /* * qstring (quoted string), ustring (unquoted string), astring * (any string) */ /* Create a string object from a null-terminated C string. */ static isc_result_t create_string(cfg_parser_t *pctx, const char *contents, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *obj = NULL; int len; CHECK(cfg_create_obj(pctx, type, &obj)); len = strlen(contents); obj->value.string.length = len; obj->value.string.base = isc_mem_get(pctx->mctx, len + 1); if (obj->value.string.base == 0) { isc_mem_put(pctx->mctx, obj, sizeof(*obj)); return (ISC_R_NOMEMORY); } memmove(obj->value.string.base, contents, len); obj->value.string.base[len] = '\0'; *ret = obj; cleanup: return (result); } isc_result_t cfg_parse_qstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; UNUSED(type); CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING)); if (pctx->token.type != isc_tokentype_qstring) { cfg_parser_error(pctx, CFG_LOG_NEAR, "expected quoted string"); return (ISC_R_UNEXPECTEDTOKEN); } return (create_string(pctx, TOKEN_STRING(pctx), &cfg_type_qstring, ret)); cleanup: return (result); } static isc_result_t parse_ustring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; UNUSED(type); CHECK(cfg_gettoken(pctx, 0)); if (pctx->token.type != isc_tokentype_string) { cfg_parser_error(pctx, CFG_LOG_NEAR, "expected unquoted string"); return (ISC_R_UNEXPECTEDTOKEN); } return (create_string(pctx, TOKEN_STRING(pctx), &cfg_type_ustring, ret)); cleanup: return (result); } isc_result_t cfg_parse_astring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; UNUSED(type); CHECK(cfg_getstringtoken(pctx)); return (create_string(pctx, TOKEN_STRING(pctx), &cfg_type_qstring, ret)); cleanup: return (result); } isc_result_t cfg_parse_sstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; UNUSED(type); CHECK(cfg_getstringtoken(pctx)); return (create_string(pctx, TOKEN_STRING(pctx), &cfg_type_sstring, ret)); cleanup: return (result); } isc_boolean_t cfg_is_enum(const char *s, const char *const *enums) { const char * const *p; for (p = enums; *p != NULL; p++) { if (strcasecmp(*p, s) == 0) return (ISC_TRUE); } return (ISC_FALSE); } static isc_result_t check_enum(cfg_parser_t *pctx, cfg_obj_t *obj, const char *const *enums) { const char *s = obj->value.string.base; if (cfg_is_enum(s, enums)) return (ISC_R_SUCCESS); cfg_parser_error(pctx, 0, "'%s' unexpected", s); return (ISC_R_UNEXPECTEDTOKEN); } isc_result_t cfg_parse_enum(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *obj = NULL; CHECK(parse_ustring(pctx, NULL, &obj)); CHECK(check_enum(pctx, obj, type->of)); *ret = obj; return (ISC_R_SUCCESS); cleanup: CLEANUP_OBJ(obj); return (result); } void cfg_doc_enum(cfg_printer_t *pctx, const cfg_type_t *type) { const char * const *p; cfg_print_chars(pctx, "( ", 2); for (p = type->of; *p != NULL; p++) { cfg_print_cstr(pctx, *p); if (p[1] != NULL) cfg_print_chars(pctx, " | ", 3); } cfg_print_chars(pctx, " )", 2); } void cfg_print_ustring(cfg_printer_t *pctx, const cfg_obj_t *obj) { cfg_print_chars(pctx, obj->value.string.base, obj->value.string.length); } static void print_qstring(cfg_printer_t *pctx, const cfg_obj_t *obj) { cfg_print_chars(pctx, "\"", 1); cfg_print_ustring(pctx, obj); cfg_print_chars(pctx, "\"", 1); } static void print_sstring(cfg_printer_t *pctx, const cfg_obj_t *obj) { cfg_print_chars(pctx, "\"", 1); if ((pctx->flags & CFG_PRINTER_XKEY) != 0) { unsigned int len = obj->value.string.length; while (len-- > 0) cfg_print_chars(pctx, "?", 1); } else cfg_print_ustring(pctx, obj); cfg_print_chars(pctx, "\"", 1); } static void free_string(cfg_parser_t *pctx, cfg_obj_t *obj) { isc_mem_put(pctx->mctx, obj->value.string.base, obj->value.string.length + 1); } isc_boolean_t cfg_obj_isstring(const cfg_obj_t *obj) { REQUIRE(obj != NULL); return (ISC_TF(obj->type->rep == &cfg_rep_string)); } const char * cfg_obj_asstring(const cfg_obj_t *obj) { REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_string); return (obj->value.string.base); } /* Quoted string only */ cfg_type_t cfg_type_qstring = { "quoted_string", cfg_parse_qstring, print_qstring, cfg_doc_terminal, &cfg_rep_string, NULL }; /* Unquoted string only */ cfg_type_t cfg_type_ustring = { "string", parse_ustring, cfg_print_ustring, cfg_doc_terminal, &cfg_rep_string, NULL }; /* Any string (quoted or unquoted); printed with quotes */ cfg_type_t cfg_type_astring = { "string", cfg_parse_astring, print_qstring, cfg_doc_terminal, &cfg_rep_string, NULL }; /* * Any string (quoted or unquoted); printed with quotes. * If CFG_PRINTER_XKEY is set when printing the string will be '?' out. */ cfg_type_t cfg_type_sstring = { "string", cfg_parse_sstring, print_sstring, cfg_doc_terminal, &cfg_rep_string, NULL }; /* * Booleans */ isc_boolean_t cfg_obj_isboolean(const cfg_obj_t *obj) { REQUIRE(obj != NULL); return (ISC_TF(obj->type->rep == &cfg_rep_boolean)); } isc_boolean_t cfg_obj_asboolean(const cfg_obj_t *obj) { REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_boolean); return (obj->value.boolean); } isc_result_t cfg_parse_boolean(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; isc_boolean_t value; cfg_obj_t *obj = NULL; UNUSED(type); result = cfg_gettoken(pctx, 0); if (result != ISC_R_SUCCESS) return (result); if (pctx->token.type != isc_tokentype_string) goto bad_boolean; if ((strcasecmp(TOKEN_STRING(pctx), "true") == 0) || (strcasecmp(TOKEN_STRING(pctx), "yes") == 0) || (strcmp(TOKEN_STRING(pctx), "1") == 0)) { value = ISC_TRUE; } else if ((strcasecmp(TOKEN_STRING(pctx), "false") == 0) || (strcasecmp(TOKEN_STRING(pctx), "no") == 0) || (strcmp(TOKEN_STRING(pctx), "0") == 0)) { value = ISC_FALSE; } else { goto bad_boolean; } CHECK(cfg_create_obj(pctx, &cfg_type_boolean, &obj)); obj->value.boolean = value; *ret = obj; return (result); bad_boolean: cfg_parser_error(pctx, CFG_LOG_NEAR, "boolean expected"); return (ISC_R_UNEXPECTEDTOKEN); cleanup: return (result); } void cfg_print_boolean(cfg_printer_t *pctx, const cfg_obj_t *obj) { if (obj->value.boolean) cfg_print_chars(pctx, "yes", 3); else cfg_print_chars(pctx, "no", 2); } cfg_type_t cfg_type_boolean = { "boolean", cfg_parse_boolean, cfg_print_boolean, cfg_doc_terminal, &cfg_rep_boolean, NULL }; /* * Lists. */ isc_result_t cfg_create_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **obj) { isc_result_t result; CHECK(cfg_create_obj(pctx, type, obj)); ISC_LIST_INIT((*obj)->value.list); cleanup: return (result); } static isc_result_t create_listelt(cfg_parser_t *pctx, cfg_listelt_t **eltp) { cfg_listelt_t *elt; elt = isc_mem_get(pctx->mctx, sizeof(*elt)); if (elt == NULL) return (ISC_R_NOMEMORY); elt->obj = NULL; ISC_LINK_INIT(elt, link); *eltp = elt; return (ISC_R_SUCCESS); } static void free_list_elt(cfg_parser_t *pctx, cfg_listelt_t *elt) { cfg_obj_destroy(pctx, &elt->obj); isc_mem_put(pctx->mctx, elt, sizeof(*elt)); } static void free_list(cfg_parser_t *pctx, cfg_obj_t *obj) { cfg_listelt_t *elt, *next; for (elt = ISC_LIST_HEAD(obj->value.list); elt != NULL; elt = next) { next = ISC_LIST_NEXT(elt, link); free_list_elt(pctx, elt); } } isc_result_t cfg_parse_listelt(cfg_parser_t *pctx, const cfg_type_t *elttype, cfg_listelt_t **ret) { isc_result_t result; cfg_listelt_t *elt = NULL; cfg_obj_t *value = NULL; CHECK(create_listelt(pctx, &elt)); result = cfg_parse_obj(pctx, elttype, &value); if (result != ISC_R_SUCCESS) goto cleanup; elt->obj = value; *ret = elt; return (ISC_R_SUCCESS); cleanup: isc_mem_put(pctx->mctx, elt, sizeof(*elt)); return (result); } /* * Parse a homogeneous list whose elements are of type 'elttype' * and where each element is terminated by a semicolon. */ static isc_result_t parse_list(cfg_parser_t *pctx, const cfg_type_t *listtype, cfg_obj_t **ret) { cfg_obj_t *listobj = NULL; const cfg_type_t *listof = listtype->of; isc_result_t result; cfg_listelt_t *elt = NULL; CHECK(cfg_create_list(pctx, listtype, &listobj)); for (;;) { CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_special && pctx->token.value.as_char == /*{*/ '}') break; CHECK(cfg_parse_listelt(pctx, listof, &elt)); CHECK(parse_semicolon(pctx)); ISC_LIST_APPEND(listobj->value.list, elt, link); elt = NULL; } *ret = listobj; return (ISC_R_SUCCESS); cleanup: if (elt != NULL) free_list_elt(pctx, elt); CLEANUP_OBJ(listobj); return (result); } static void print_list(cfg_printer_t *pctx, const cfg_obj_t *obj) { const cfg_list_t *list = &obj->value.list; const cfg_listelt_t *elt; for (elt = ISC_LIST_HEAD(*list); elt != NULL; elt = ISC_LIST_NEXT(elt, link)) { print_indent(pctx); cfg_print_obj(pctx, elt->obj); cfg_print_chars(pctx, ";\n", 2); } } isc_result_t cfg_parse_bracketed_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; CHECK(cfg_parse_special(pctx, '{')); CHECK(parse_list(pctx, type, ret)); CHECK(cfg_parse_special(pctx, '}')); cleanup: return (result); } void cfg_print_bracketed_list(cfg_printer_t *pctx, const cfg_obj_t *obj) { print_open(pctx); print_list(pctx, obj); print_close(pctx); } void cfg_doc_bracketed_list(cfg_printer_t *pctx, const cfg_type_t *type) { cfg_print_chars(pctx, "{ ", 2); cfg_doc_obj(pctx, type->of); cfg_print_chars(pctx, "; ... }", 7); } /* * Parse a homogeneous list whose elements are of type 'elttype' * and where elements are separated by space. The list ends * before the first semicolon. */ isc_result_t cfg_parse_spacelist(cfg_parser_t *pctx, const cfg_type_t *listtype, cfg_obj_t **ret) { cfg_obj_t *listobj = NULL; const cfg_type_t *listof = listtype->of; isc_result_t result; CHECK(cfg_create_list(pctx, listtype, &listobj)); for (;;) { cfg_listelt_t *elt = NULL; CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_special && pctx->token.value.as_char == ';') break; CHECK(cfg_parse_listelt(pctx, listof, &elt)); ISC_LIST_APPEND(listobj->value.list, elt, link); } *ret = listobj; return (ISC_R_SUCCESS); cleanup: CLEANUP_OBJ(listobj); return (result); } void cfg_print_spacelist(cfg_printer_t *pctx, const cfg_obj_t *obj) { const cfg_list_t *list = &obj->value.list; const cfg_listelt_t *elt; for (elt = ISC_LIST_HEAD(*list); elt != NULL; elt = ISC_LIST_NEXT(elt, link)) { cfg_print_obj(pctx, elt->obj); if (ISC_LIST_NEXT(elt, link) != NULL) cfg_print_chars(pctx, " ", 1); } } isc_boolean_t cfg_obj_islist(const cfg_obj_t *obj) { REQUIRE(obj != NULL); return (ISC_TF(obj->type->rep == &cfg_rep_list)); } const cfg_listelt_t * cfg_list_first(const cfg_obj_t *obj) { REQUIRE(obj == NULL || obj->type->rep == &cfg_rep_list); if (obj == NULL) return (NULL); return (ISC_LIST_HEAD(obj->value.list)); } const cfg_listelt_t * cfg_list_next(const cfg_listelt_t *elt) { REQUIRE(elt != NULL); return (ISC_LIST_NEXT(elt, link)); } /* * Return the length of a list object. If obj is NULL or is not * a list, return 0. */ unsigned int cfg_list_length(const cfg_obj_t *obj, isc_boolean_t recurse) { const cfg_listelt_t *elt; unsigned int count = 0; if (obj == NULL || !cfg_obj_islist(obj)) return (0U); for (elt = cfg_list_first(obj); elt != NULL; elt = cfg_list_next(elt)) { if (recurse && cfg_obj_islist(elt->obj)) { count += cfg_list_length(elt->obj, recurse); } else { count++; } } return (count); } cfg_obj_t * cfg_listelt_value(const cfg_listelt_t *elt) { REQUIRE(elt != NULL); return (elt->obj); } /* * Maps. */ /* * Parse a map body. That's something like * * "foo 1; bar { glub; }; zap true; zap false;" * * i.e., a sequence of option names followed by values and * terminated by semicolons. Used for the top level of * the named.conf syntax, as well as for the body of the * options, view, zone, and other statements. */ isc_result_t cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { const cfg_clausedef_t * const *clausesets = type->of; isc_result_t result; const cfg_clausedef_t * const *clauseset; const cfg_clausedef_t *clause; cfg_obj_t *value = NULL; cfg_obj_t *obj = NULL; cfg_obj_t *eltobj = NULL; cfg_obj_t *includename = NULL; isc_symvalue_t symval; cfg_list_t *list = NULL; CHECK(create_map(pctx, type, &obj)); obj->value.map.clausesets = clausesets; for (;;) { cfg_listelt_t *elt; redo: /* * Parse the option name and see if it is known. */ CHECK(cfg_gettoken(pctx, 0)); if (pctx->token.type != isc_tokentype_string) { cfg_ungettoken(pctx); break; } /* * We accept "include" statements wherever a map body * clause can occur. */ if (strcasecmp(TOKEN_STRING(pctx), "include") == 0) { /* * Turn the file name into a temporary configuration * object just so that it is not overwritten by the * semicolon token. */ CHECK(cfg_parse_obj(pctx, &cfg_type_qstring, &includename)); CHECK(parse_semicolon(pctx)); CHECK(parser_openfile(pctx, includename-> value.string.base)); cfg_obj_destroy(pctx, &includename); goto redo; } clause = NULL; for (clauseset = clausesets; *clauseset != NULL; clauseset++) { for (clause = *clauseset; clause->name != NULL; clause++) { if (strcasecmp(TOKEN_STRING(pctx), clause->name) == 0) goto done; } } done: if (clause == NULL || clause->name == NULL) { cfg_parser_error(pctx, CFG_LOG_NOPREP, "unknown option"); /* * Try to recover by parsing this option as an unknown * option and discarding it. */ CHECK(cfg_parse_obj(pctx, &cfg_type_unsupported, &eltobj)); cfg_obj_destroy(pctx, &eltobj); CHECK(parse_semicolon(pctx)); continue; } /* Clause is known. */ /* Issue warnings if appropriate */ if ((clause->flags & CFG_CLAUSEFLAG_OBSOLETE) != 0) cfg_parser_warning(pctx, 0, "option '%s' is obsolete", clause->name); if ((clause->flags & CFG_CLAUSEFLAG_NOTIMP) != 0) cfg_parser_warning(pctx, 0, "option '%s' is " "not implemented", clause->name); if ((clause->flags & CFG_CLAUSEFLAG_NYI) != 0) cfg_parser_warning(pctx, 0, "option '%s' is " "not implemented", clause->name); if ((clause->flags & CFG_CLAUSEFLAG_NOTCONFIGURED) != 0) { cfg_parser_warning(pctx, 0, "option '%s' was not " "enabled at compile time", clause->name); result = ISC_R_FAILURE; goto cleanup; } /* * Don't log options with CFG_CLAUSEFLAG_NEWDEFAULT * set here - we need to log the *lack* of such an option, * not its presence. */ /* See if the clause already has a value; if not create one. */ result = isc_symtab_lookup(obj->value.map.symtab, clause->name, 0, &symval); if ((clause->flags & CFG_CLAUSEFLAG_MULTI) != 0) { /* Multivalued clause */ cfg_obj_t *listobj = NULL; if (result == ISC_R_NOTFOUND) { CHECK(cfg_create_list(pctx, &cfg_type_implicitlist, &listobj)); symval.as_pointer = listobj; result = isc_symtab_define(obj->value. map.symtab, clause->name, 1, symval, isc_symexists_reject); if (result != ISC_R_SUCCESS) { cfg_parser_error(pctx, CFG_LOG_NEAR, "isc_symtab_define(%s) " "failed", clause->name); isc_mem_put(pctx->mctx, list, sizeof(cfg_list_t)); goto cleanup; } } else { INSIST(result == ISC_R_SUCCESS); listobj = symval.as_pointer; } elt = NULL; CHECK(cfg_parse_listelt(pctx, clause->type, &elt)); CHECK(parse_semicolon(pctx)); ISC_LIST_APPEND(listobj->value.list, elt, link); } else { /* Single-valued clause */ if (result == ISC_R_NOTFOUND) { isc_boolean_t callback = ISC_TF((clause->flags & CFG_CLAUSEFLAG_CALLBACK) != 0); CHECK(parse_symtab_elt(pctx, clause->name, clause->type, obj->value.map.symtab, callback)); CHECK(parse_semicolon(pctx)); } else if (result == ISC_R_SUCCESS) { cfg_parser_error(pctx, CFG_LOG_NEAR, "'%s' redefined", clause->name); result = ISC_R_EXISTS; goto cleanup; } else { cfg_parser_error(pctx, CFG_LOG_NEAR, "isc_symtab_define() failed"); goto cleanup; } } } *ret = obj; return (ISC_R_SUCCESS); cleanup: CLEANUP_OBJ(value); CLEANUP_OBJ(obj); CLEANUP_OBJ(eltobj); CLEANUP_OBJ(includename); return (result); } static isc_result_t parse_symtab_elt(cfg_parser_t *pctx, const char *name, cfg_type_t *elttype, isc_symtab_t *symtab, isc_boolean_t callback) { isc_result_t result; cfg_obj_t *obj = NULL; isc_symvalue_t symval; CHECK(cfg_parse_obj(pctx, elttype, &obj)); if (callback && pctx->callback != NULL) CHECK(pctx->callback(name, obj, pctx->callbackarg)); symval.as_pointer = obj; CHECK(isc_symtab_define(symtab, name, 1, symval, isc_symexists_reject)); return (ISC_R_SUCCESS); cleanup: CLEANUP_OBJ(obj); return (result); } /* * Parse a map; e.g., "{ foo 1; bar { glub; }; zap true; zap false; }" */ isc_result_t cfg_parse_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; CHECK(cfg_parse_special(pctx, '{')); CHECK(cfg_parse_mapbody(pctx, type, ret)); CHECK(cfg_parse_special(pctx, '}')); cleanup: return (result); } /* * Subroutine for cfg_parse_named_map() and cfg_parse_addressed_map(). */ static isc_result_t parse_any_named_map(cfg_parser_t *pctx, cfg_type_t *nametype, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *idobj = NULL; cfg_obj_t *mapobj = NULL; CHECK(cfg_parse_obj(pctx, nametype, &idobj)); CHECK(cfg_parse_map(pctx, type, &mapobj)); mapobj->value.map.id = idobj; *ret = mapobj; return (result); cleanup: CLEANUP_OBJ(idobj); CLEANUP_OBJ(mapobj); return (result); } /* * Parse a map identified by a string name. E.g., "name { foo 1; }". * Used for the "key" and "channel" statements. */ isc_result_t cfg_parse_named_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { return (parse_any_named_map(pctx, &cfg_type_astring, type, ret)); } /* * Parse a map identified by a network address. * Used to be used for the "server" statement. */ isc_result_t cfg_parse_addressed_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { return (parse_any_named_map(pctx, &cfg_type_netaddr, type, ret)); } /* * Parse a map identified by a network prefix. * Used for the "server" statement. */ isc_result_t cfg_parse_netprefix_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { return (parse_any_named_map(pctx, &cfg_type_netprefix, type, ret)); } void cfg_print_mapbody(cfg_printer_t *pctx, const cfg_obj_t *obj) { isc_result_t result = ISC_R_SUCCESS; const cfg_clausedef_t * const *clauseset; for (clauseset = obj->value.map.clausesets; *clauseset != NULL; clauseset++) { isc_symvalue_t symval; const cfg_clausedef_t *clause; for (clause = *clauseset; clause->name != NULL; clause++) { result = isc_symtab_lookup(obj->value.map.symtab, clause->name, 0, &symval); if (result == ISC_R_SUCCESS) { cfg_obj_t *symobj = symval.as_pointer; if (symobj->type == &cfg_type_implicitlist) { /* Multivalued. */ cfg_list_t *list = &symobj->value.list; cfg_listelt_t *elt; for (elt = ISC_LIST_HEAD(*list); elt != NULL; elt = ISC_LIST_NEXT(elt, link)) { print_indent(pctx); cfg_print_cstr(pctx, clause->name); cfg_print_chars(pctx, " ", 1); cfg_print_obj(pctx, elt->obj); cfg_print_chars(pctx, ";\n", 2); } } else { /* Single-valued. */ print_indent(pctx); cfg_print_cstr(pctx, clause->name); cfg_print_chars(pctx, " ", 1); cfg_print_obj(pctx, symobj); cfg_print_chars(pctx, ";\n", 2); } } else if (result == ISC_R_NOTFOUND) { ; /* do nothing */ } else { INSIST(0); } } } } void cfg_doc_mapbody(cfg_printer_t *pctx, const cfg_type_t *type) { const cfg_clausedef_t * const *clauseset; const cfg_clausedef_t *clause; for (clauseset = type->of; *clauseset != NULL; clauseset++) { for (clause = *clauseset; clause->name != NULL; clause++) { cfg_print_cstr(pctx, clause->name); cfg_print_chars(pctx, " ", 1); cfg_doc_obj(pctx, clause->type); cfg_print_chars(pctx, ";", 1); /* XXX print flags here? */ cfg_print_chars(pctx, "\n\n", 2); } } } static struct flagtext { unsigned int flag; const char *text; } flagtexts[] = { { CFG_CLAUSEFLAG_NOTIMP, "not implemented" }, { CFG_CLAUSEFLAG_NYI, "not yet implemented" }, { CFG_CLAUSEFLAG_OBSOLETE, "obsolete" }, { CFG_CLAUSEFLAG_NEWDEFAULT, "default changed" }, { CFG_CLAUSEFLAG_TESTONLY, "test only" }, { CFG_CLAUSEFLAG_NOTCONFIGURED, "not configured" }, { 0, NULL } }; void cfg_print_map(cfg_printer_t *pctx, const cfg_obj_t *obj) { if (obj->value.map.id != NULL) { cfg_print_obj(pctx, obj->value.map.id); cfg_print_chars(pctx, " ", 1); } print_open(pctx); cfg_print_mapbody(pctx, obj); print_close(pctx); } static void print_clause_flags(cfg_printer_t *pctx, unsigned int flags) { struct flagtext *p; isc_boolean_t first = ISC_TRUE; for (p = flagtexts; p->flag != 0; p++) { if ((flags & p->flag) != 0) { if (first) cfg_print_chars(pctx, " // ", 4); else cfg_print_chars(pctx, ", ", 2); cfg_print_cstr(pctx, p->text); first = ISC_FALSE; } } } void cfg_doc_map(cfg_printer_t *pctx, const cfg_type_t *type) { const cfg_clausedef_t * const *clauseset; const cfg_clausedef_t *clause; if (type->parse == cfg_parse_named_map) { cfg_doc_obj(pctx, &cfg_type_astring); cfg_print_chars(pctx, " ", 1); } else if (type->parse == cfg_parse_addressed_map) { cfg_doc_obj(pctx, &cfg_type_netaddr); cfg_print_chars(pctx, " ", 1); } else if (type->parse == cfg_parse_netprefix_map) { cfg_doc_obj(pctx, &cfg_type_netprefix); cfg_print_chars(pctx, " ", 1); } print_open(pctx); for (clauseset = type->of; *clauseset != NULL; clauseset++) { for (clause = *clauseset; clause->name != NULL; clause++) { print_indent(pctx); cfg_print_cstr(pctx, clause->name); if (clause->type->print != cfg_print_void) cfg_print_chars(pctx, " ", 1); cfg_doc_obj(pctx, clause->type); cfg_print_chars(pctx, ";", 1); print_clause_flags(pctx, clause->flags); cfg_print_chars(pctx, "\n", 1); } } print_close(pctx); } isc_boolean_t cfg_obj_ismap(const cfg_obj_t *obj) { REQUIRE(obj != NULL); return (ISC_TF(obj->type->rep == &cfg_rep_map)); } isc_result_t cfg_map_get(const cfg_obj_t *mapobj, const char* name, const cfg_obj_t **obj) { isc_result_t result; isc_symvalue_t val; const cfg_map_t *map; REQUIRE(mapobj != NULL && mapobj->type->rep == &cfg_rep_map); REQUIRE(name != NULL); REQUIRE(obj != NULL && *obj == NULL); map = &mapobj->value.map; result = isc_symtab_lookup(map->symtab, name, MAP_SYM, &val); if (result != ISC_R_SUCCESS) return (result); *obj = val.as_pointer; return (ISC_R_SUCCESS); } const cfg_obj_t * cfg_map_getname(const cfg_obj_t *mapobj) { REQUIRE(mapobj != NULL && mapobj->type->rep == &cfg_rep_map); return (mapobj->value.map.id); } unsigned int cfg_map_count(const cfg_obj_t *mapobj) { const cfg_map_t *map; REQUIRE(mapobj != NULL && mapobj->type->rep == &cfg_rep_map); map = &mapobj->value.map; return (isc_symtab_count(map->symtab)); } /* Parse an arbitrary token, storing its raw text representation. */ static isc_result_t parse_token(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { cfg_obj_t *obj = NULL; isc_result_t result; isc_region_t r; UNUSED(type); CHECK(cfg_create_obj(pctx, &cfg_type_token, &obj)); CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING)); if (pctx->token.type == isc_tokentype_eof) { cfg_ungettoken(pctx); result = ISC_R_EOF; goto cleanup; } isc_lex_getlasttokentext(pctx->lexer, &pctx->token, &r); obj->value.string.base = isc_mem_get(pctx->mctx, r.length + 1); if (obj->value.string.base == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } obj->value.string.length = r.length; memmove(obj->value.string.base, r.base, r.length); obj->value.string.base[r.length] = '\0'; *ret = obj; return (result); cleanup: if (obj != NULL) isc_mem_put(pctx->mctx, obj, sizeof(*obj)); return (result); } cfg_type_t cfg_type_token = { "token", parse_token, cfg_print_ustring, cfg_doc_terminal, &cfg_rep_string, NULL }; /* * An unsupported option. This is just a list of tokens with balanced braces * ending in a semicolon. */ static isc_result_t parse_unsupported(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { cfg_obj_t *listobj = NULL; isc_result_t result; int braces = 0; CHECK(cfg_create_list(pctx, type, &listobj)); for (;;) { cfg_listelt_t *elt = NULL; CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_special) { if (pctx->token.value.as_char == '{') braces++; else if (pctx->token.value.as_char == '}') braces--; else if (pctx->token.value.as_char == ';') if (braces == 0) break; } if (pctx->token.type == isc_tokentype_eof || braces < 0) { cfg_parser_error(pctx, CFG_LOG_NEAR, "unexpected token"); result = ISC_R_UNEXPECTEDTOKEN; goto cleanup; } CHECK(cfg_parse_listelt(pctx, &cfg_type_token, &elt)); ISC_LIST_APPEND(listobj->value.list, elt, link); } INSIST(braces == 0); *ret = listobj; return (ISC_R_SUCCESS); cleanup: CLEANUP_OBJ(listobj); return (result); } cfg_type_t cfg_type_unsupported = { "unsupported", parse_unsupported, cfg_print_spacelist, cfg_doc_terminal, &cfg_rep_list, NULL }; /* * Try interpreting the current token as a network address. * * If CFG_ADDR_WILDOK is set in flags, "*" can be used as a wildcard * and at least one of CFG_ADDR_V4OK and CFG_ADDR_V6OK must also be set. The * "*" is interpreted as the IPv4 wildcard address if CFG_ADDR_V4OK is * set (including the case where CFG_ADDR_V4OK and CFG_ADDR_V6OK are both set), * and the IPv6 wildcard address otherwise. */ static isc_result_t token_addr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na) { char *s; struct in_addr in4a; struct in6_addr in6a; if (pctx->token.type != isc_tokentype_string) return (ISC_R_UNEXPECTEDTOKEN); s = TOKEN_STRING(pctx); if ((flags & CFG_ADDR_WILDOK) != 0 && strcmp(s, "*") == 0) { if ((flags & CFG_ADDR_V4OK) != 0) { isc_netaddr_any(na); return (ISC_R_SUCCESS); } else if ((flags & CFG_ADDR_V6OK) != 0) { isc_netaddr_any6(na); return (ISC_R_SUCCESS); } else { INSIST(0); } } else { if ((flags & (CFG_ADDR_V4OK | CFG_ADDR_V4PREFIXOK)) != 0) { if (inet_pton(AF_INET, s, &in4a) == 1) { isc_netaddr_fromin(na, &in4a); return (ISC_R_SUCCESS); } } if ((flags & CFG_ADDR_V4PREFIXOK) != 0 && strlen(s) <= 15U) { char buf[64]; int i; strcpy(buf, s); for (i = 0; i < 3; i++) { strcat(buf, ".0"); if (inet_pton(AF_INET, buf, &in4a) == 1) { isc_netaddr_fromin(na, &in4a); return (ISC_R_SUCCESS); } } } if ((flags & CFG_ADDR_V6OK) != 0 && strlen(s) <= 127U) { char buf[128]; /* see lib/bind9/getaddresses.c */ char *d; /* zone delimiter */ isc_uint32_t zone = 0; /* scope zone ID */ strcpy(buf, s); d = strchr(buf, '%'); if (d != NULL) *d = '\0'; if (inet_pton(AF_INET6, buf, &in6a) == 1) { if (d != NULL) { #ifdef ISC_PLATFORM_HAVESCOPEID isc_result_t result; result = isc_netscope_pton(AF_INET6, d + 1, &in6a, &zone); if (result != ISC_R_SUCCESS) return (result); #else return (ISC_R_BADADDRESSFORM); #endif } isc_netaddr_fromin6(na, &in6a); isc_netaddr_setzone(na, zone); return (ISC_R_SUCCESS); } } } return (ISC_R_UNEXPECTEDTOKEN); } isc_result_t cfg_parse_rawaddr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na) { isc_result_t result; const char *wild = ""; const char *prefix = ""; CHECK(cfg_gettoken(pctx, 0)); result = token_addr(pctx, flags, na); if (result == ISC_R_UNEXPECTEDTOKEN) { if ((flags & CFG_ADDR_WILDOK) != 0) wild = " or '*'"; if ((flags & CFG_ADDR_V4PREFIXOK) != 0) wild = " or IPv4 prefix"; if ((flags & CFG_ADDR_MASK) == CFG_ADDR_V4OK) cfg_parser_error(pctx, CFG_LOG_NEAR, "expected IPv4 address%s%s", prefix, wild); else if ((flags & CFG_ADDR_MASK) == CFG_ADDR_V6OK) cfg_parser_error(pctx, CFG_LOG_NEAR, "expected IPv6 address%s%s", prefix, wild); else cfg_parser_error(pctx, CFG_LOG_NEAR, "expected IP address%s%s", prefix, wild); } cleanup: return (result); } isc_boolean_t cfg_lookingat_netaddr(cfg_parser_t *pctx, unsigned int flags) { isc_result_t result; isc_netaddr_t na_dummy; result = token_addr(pctx, flags, &na_dummy); return (ISC_TF(result == ISC_R_SUCCESS)); } isc_result_t cfg_parse_rawport(cfg_parser_t *pctx, unsigned int flags, in_port_t *port) { isc_result_t result; CHECK(cfg_gettoken(pctx, ISC_LEXOPT_NUMBER)); if ((flags & CFG_ADDR_WILDOK) != 0 && pctx->token.type == isc_tokentype_string && strcmp(TOKEN_STRING(pctx), "*") == 0) { *port = 0; return (ISC_R_SUCCESS); } if (pctx->token.type != isc_tokentype_number) { cfg_parser_error(pctx, CFG_LOG_NEAR, "expected port number or '*'"); return (ISC_R_UNEXPECTEDTOKEN); } if (pctx->token.value.as_ulong >= 65536U) { cfg_parser_error(pctx, CFG_LOG_NEAR, "port number out of range"); return (ISC_R_UNEXPECTEDTOKEN); } *port = (in_port_t)(pctx->token.value.as_ulong); return (ISC_R_SUCCESS); cleanup: return (result); } void cfg_print_rawaddr(cfg_printer_t *pctx, const isc_netaddr_t *na) { isc_result_t result; char text[128]; isc_buffer_t buf; isc_buffer_init(&buf, text, sizeof(text)); result = isc_netaddr_totext(na, &buf); RUNTIME_CHECK(result == ISC_R_SUCCESS); cfg_print_chars(pctx, isc_buffer_base(&buf), isc_buffer_usedlength(&buf)); } isc_result_t cfg_parse_dscp(cfg_parser_t *pctx, isc_dscp_t *dscp) { isc_result_t result; CHECK(cfg_gettoken(pctx, ISC_LEXOPT_NUMBER | ISC_LEXOPT_CNUMBER)); if (pctx->token.type != isc_tokentype_number) { cfg_parser_error(pctx, CFG_LOG_NEAR, "expected number"); return (ISC_R_UNEXPECTEDTOKEN); } if (pctx->token.value.as_ulong > 63U) { cfg_parser_error(pctx, CFG_LOG_NEAR, "dscp out of range"); return (ISC_R_RANGE); } *dscp = (isc_dscp_t)(pctx->token.value.as_ulong); return (ISC_R_SUCCESS); cleanup: return (result); } /* netaddr */ static unsigned int netaddr_flags = CFG_ADDR_V4OK | CFG_ADDR_V6OK; static unsigned int netaddr4_flags = CFG_ADDR_V4OK; static unsigned int netaddr4wild_flags = CFG_ADDR_V4OK | CFG_ADDR_WILDOK; static unsigned int netaddr6_flags = CFG_ADDR_V6OK; static unsigned int netaddr6wild_flags = CFG_ADDR_V6OK | CFG_ADDR_WILDOK; static isc_result_t parse_netaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *obj = NULL; isc_netaddr_t netaddr; unsigned int flags = *(const unsigned int *)type->of; CHECK(cfg_create_obj(pctx, type, &obj)); CHECK(cfg_parse_rawaddr(pctx, flags, &netaddr)); isc_sockaddr_fromnetaddr(&obj->value.sockaddr, &netaddr, 0); *ret = obj; return (ISC_R_SUCCESS); cleanup: CLEANUP_OBJ(obj); return (result); } static void cfg_doc_netaddr(cfg_printer_t *pctx, const cfg_type_t *type) { const unsigned int *flagp = type->of; int n = 0; if (*flagp != CFG_ADDR_V4OK && *flagp != CFG_ADDR_V6OK) cfg_print_chars(pctx, "( ", 2); if (*flagp & CFG_ADDR_V4OK) { cfg_print_cstr(pctx, ""); n++; } if (*flagp & CFG_ADDR_V6OK) { if (n != 0) cfg_print_chars(pctx, " | ", 3); cfg_print_cstr(pctx, ""); n++; } if (*flagp & CFG_ADDR_WILDOK) { if (n != 0) cfg_print_chars(pctx, " | ", 3); cfg_print_chars(pctx, "*", 1); n++; POST(n); } if (*flagp != CFG_ADDR_V4OK && *flagp != CFG_ADDR_V6OK) cfg_print_chars(pctx, " )", 2); } cfg_type_t cfg_type_netaddr = { "netaddr", parse_netaddr, cfg_print_sockaddr, cfg_doc_netaddr, &cfg_rep_sockaddr, &netaddr_flags }; cfg_type_t cfg_type_netaddr4 = { "netaddr4", parse_netaddr, cfg_print_sockaddr, cfg_doc_netaddr, &cfg_rep_sockaddr, &netaddr4_flags }; cfg_type_t cfg_type_netaddr4wild = { "netaddr4wild", parse_netaddr, cfg_print_sockaddr, cfg_doc_netaddr, &cfg_rep_sockaddr, &netaddr4wild_flags }; cfg_type_t cfg_type_netaddr6 = { "netaddr6", parse_netaddr, cfg_print_sockaddr, cfg_doc_netaddr, &cfg_rep_sockaddr, &netaddr6_flags }; cfg_type_t cfg_type_netaddr6wild = { "netaddr6wild", parse_netaddr, cfg_print_sockaddr, cfg_doc_netaddr, &cfg_rep_sockaddr, &netaddr6wild_flags }; /* netprefix */ isc_result_t cfg_parse_netprefix(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { cfg_obj_t *obj = NULL; isc_result_t result; isc_netaddr_t netaddr; unsigned int addrlen = 0, prefixlen; UNUSED(type); CHECK(cfg_parse_rawaddr(pctx, CFG_ADDR_V4OK | CFG_ADDR_V4PREFIXOK | CFG_ADDR_V6OK, &netaddr)); switch (netaddr.family) { case AF_INET: addrlen = 32; break; case AF_INET6: addrlen = 128; break; default: INSIST(0); break; } CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_special && pctx->token.value.as_char == '/') { CHECK(cfg_gettoken(pctx, 0)); /* read "/" */ CHECK(cfg_gettoken(pctx, ISC_LEXOPT_NUMBER)); if (pctx->token.type != isc_tokentype_number) { cfg_parser_error(pctx, CFG_LOG_NEAR, "expected prefix length"); return (ISC_R_UNEXPECTEDTOKEN); } prefixlen = pctx->token.value.as_ulong; if (prefixlen > addrlen) { cfg_parser_error(pctx, CFG_LOG_NOPREP, "invalid prefix length"); return (ISC_R_RANGE); } } else { prefixlen = addrlen; } CHECK(cfg_create_obj(pctx, &cfg_type_netprefix, &obj)); obj->value.netprefix.address = netaddr; obj->value.netprefix.prefixlen = prefixlen; *ret = obj; return (ISC_R_SUCCESS); cleanup: cfg_parser_error(pctx, CFG_LOG_NEAR, "expected network prefix"); return (result); } static void print_netprefix(cfg_printer_t *pctx, const cfg_obj_t *obj) { const cfg_netprefix_t *p = &obj->value.netprefix; cfg_print_rawaddr(pctx, &p->address); cfg_print_chars(pctx, "/", 1); cfg_print_rawuint(pctx, p->prefixlen); } isc_boolean_t cfg_obj_isnetprefix(const cfg_obj_t *obj) { REQUIRE(obj != NULL); return (ISC_TF(obj->type->rep == &cfg_rep_netprefix)); } void cfg_obj_asnetprefix(const cfg_obj_t *obj, isc_netaddr_t *netaddr, unsigned int *prefixlen) { REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_netprefix); REQUIRE(netaddr != NULL); REQUIRE(prefixlen != NULL); *netaddr = obj->value.netprefix.address; *prefixlen = obj->value.netprefix.prefixlen; } cfg_type_t cfg_type_netprefix = { "netprefix", cfg_parse_netprefix, print_netprefix, cfg_doc_terminal, &cfg_rep_netprefix, NULL }; static isc_result_t parse_sockaddrsub(cfg_parser_t *pctx, const cfg_type_t *type, int flags, cfg_obj_t **ret) { isc_result_t result; isc_netaddr_t netaddr; in_port_t port = 0; isc_dscp_t dscp = -1; cfg_obj_t *obj = NULL; int have_port = 0, have_dscp = 0; CHECK(cfg_create_obj(pctx, type, &obj)); CHECK(cfg_parse_rawaddr(pctx, flags, &netaddr)); for (;;) { CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_string) { if (strcasecmp(TOKEN_STRING(pctx), "port") == 0) { CHECK(cfg_gettoken(pctx, 0)); /* read "port" */ CHECK(cfg_parse_rawport(pctx, flags, &port)); ++have_port; } else if ((flags & CFG_ADDR_DSCPOK) != 0 && strcasecmp(TOKEN_STRING(pctx), "dscp") == 0) { CHECK(cfg_gettoken(pctx, 0)); /* read "dscp" */ CHECK(cfg_parse_dscp(pctx, &dscp)); ++have_dscp; } else break; } else break; } if (have_port > 1) { cfg_parser_error(pctx, 0, "expected at most one port"); result = ISC_R_UNEXPECTEDTOKEN; goto cleanup; } if (have_dscp > 1) { cfg_parser_error(pctx, 0, "expected at most one dscp"); result = ISC_R_UNEXPECTEDTOKEN; goto cleanup; } isc_sockaddr_fromnetaddr(&obj->value.sockaddr, &netaddr, port); obj->value.sockaddrdscp.dscp = dscp; *ret = obj; return (ISC_R_SUCCESS); cleanup: CLEANUP_OBJ(obj); return (result); } static unsigned int sockaddr_flags = CFG_ADDR_V4OK | CFG_ADDR_V6OK; cfg_type_t cfg_type_sockaddr = { "sockaddr", cfg_parse_sockaddr, cfg_print_sockaddr, cfg_doc_sockaddr, &cfg_rep_sockaddr, &sockaddr_flags }; static unsigned int sockaddrdscp_flags = CFG_ADDR_V4OK | CFG_ADDR_V6OK | CFG_ADDR_DSCPOK; cfg_type_t cfg_type_sockaddrdscp = { "sockaddr", cfg_parse_sockaddr, cfg_print_sockaddr, cfg_doc_sockaddr, &cfg_rep_sockaddr, &sockaddrdscp_flags }; isc_result_t cfg_parse_sockaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { const unsigned int *flagp = type->of; return (parse_sockaddrsub(pctx, &cfg_type_sockaddr, *flagp, ret)); } void cfg_print_sockaddr(cfg_printer_t *pctx, const cfg_obj_t *obj) { isc_netaddr_t netaddr; in_port_t port; char buf[ISC_NETADDR_FORMATSIZE]; isc_netaddr_fromsockaddr(&netaddr, &obj->value.sockaddr); isc_netaddr_format(&netaddr, buf, sizeof(buf)); cfg_print_cstr(pctx, buf); port = isc_sockaddr_getport(&obj->value.sockaddr); if (port != 0) { cfg_print_chars(pctx, " port ", 6); cfg_print_rawuint(pctx, port); } if (obj->value.sockaddrdscp.dscp != -1) { cfg_print_chars(pctx, " dscp ", 6); cfg_print_rawuint(pctx, obj->value.sockaddrdscp.dscp); } } void cfg_doc_sockaddr(cfg_printer_t *pctx, const cfg_type_t *type) { const unsigned int *flagp = type->of; int n = 0; cfg_print_chars(pctx, "( ", 2); if (*flagp & CFG_ADDR_V4OK) { cfg_print_cstr(pctx, ""); n++; } if (*flagp & CFG_ADDR_V6OK) { if (n != 0) cfg_print_chars(pctx, " | ", 3); cfg_print_cstr(pctx, ""); n++; } if (*flagp & CFG_ADDR_WILDOK) { if (n != 0) cfg_print_chars(pctx, " | ", 3); cfg_print_chars(pctx, "*", 1); n++; POST(n); } cfg_print_chars(pctx, " ) ", 3); if (*flagp & CFG_ADDR_WILDOK) { cfg_print_cstr(pctx, "[ port ( | * ) ]"); } else { cfg_print_cstr(pctx, "[ port ]"); } if ((*flagp & CFG_ADDR_DSCPOK) != 0) { cfg_print_cstr(pctx, " [ dscp ]"); } } isc_boolean_t cfg_obj_issockaddr(const cfg_obj_t *obj) { REQUIRE(obj != NULL); return (ISC_TF(obj->type->rep == &cfg_rep_sockaddr)); } const isc_sockaddr_t * cfg_obj_assockaddr(const cfg_obj_t *obj) { REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_sockaddr); return (&obj->value.sockaddr); } isc_dscp_t cfg_obj_getdscp(const cfg_obj_t *obj) { REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_sockaddr); return (obj->value.sockaddrdscp.dscp); } isc_result_t cfg_gettoken(cfg_parser_t *pctx, int options) { isc_result_t result; if (pctx->seen_eof) return (ISC_R_SUCCESS); options |= (ISC_LEXOPT_EOF | ISC_LEXOPT_NOMORE); redo: pctx->token.type = isc_tokentype_unknown; result = isc_lex_gettoken(pctx->lexer, options, &pctx->token); pctx->ungotten = ISC_FALSE; pctx->line = isc_lex_getsourceline(pctx->lexer); switch (result) { case ISC_R_SUCCESS: if (pctx->token.type == isc_tokentype_eof) { result = isc_lex_close(pctx->lexer); INSIST(result == ISC_R_NOMORE || result == ISC_R_SUCCESS); if (isc_lex_getsourcename(pctx->lexer) != NULL) { /* * Closed an included file, not the main file. */ cfg_listelt_t *elt; elt = ISC_LIST_TAIL(pctx->open_files-> value.list); INSIST(elt != NULL); ISC_LIST_UNLINK(pctx->open_files-> value.list, elt, link); ISC_LIST_APPEND(pctx->closed_files-> value.list, elt, link); goto redo; } pctx->seen_eof = ISC_TRUE; } break; case ISC_R_NOSPACE: /* More understandable than "ran out of space". */ cfg_parser_error(pctx, CFG_LOG_NEAR, "token too big"); break; case ISC_R_IOERROR: cfg_parser_error(pctx, 0, "%s", isc_result_totext(result)); break; default: cfg_parser_error(pctx, CFG_LOG_NEAR, "%s", isc_result_totext(result)); break; } return (result); } void cfg_ungettoken(cfg_parser_t *pctx) { if (pctx->seen_eof) return; isc_lex_ungettoken(pctx->lexer, &pctx->token); pctx->ungotten = ISC_TRUE; } isc_result_t cfg_peektoken(cfg_parser_t *pctx, int options) { isc_result_t result; CHECK(cfg_gettoken(pctx, options)); cfg_ungettoken(pctx); cleanup: return (result); } /* * Get a string token, accepting both the quoted and the unquoted form. * Log an error if the next token is not a string. */ static isc_result_t cfg_getstringtoken(cfg_parser_t *pctx) { isc_result_t result; result = cfg_gettoken(pctx, CFG_LEXOPT_QSTRING); if (result != ISC_R_SUCCESS) return (result); if (pctx->token.type != isc_tokentype_string && pctx->token.type != isc_tokentype_qstring) { cfg_parser_error(pctx, CFG_LOG_NEAR, "expected string"); return (ISC_R_UNEXPECTEDTOKEN); } return (ISC_R_SUCCESS); } void cfg_parser_error(cfg_parser_t *pctx, unsigned int flags, const char *fmt, ...) { va_list args; va_start(args, fmt); parser_complain(pctx, ISC_FALSE, flags, fmt, args); va_end(args); pctx->errors++; } void cfg_parser_warning(cfg_parser_t *pctx, unsigned int flags, const char *fmt, ...) { va_list args; va_start(args, fmt); parser_complain(pctx, ISC_TRUE, flags, fmt, args); va_end(args); pctx->warnings++; } #define MAX_LOG_TOKEN 30 /* How much of a token to quote in log messages. */ static isc_boolean_t have_current_file(cfg_parser_t *pctx) { cfg_listelt_t *elt; if (pctx->open_files == NULL) return (ISC_FALSE); elt = ISC_LIST_TAIL(pctx->open_files->value.list); if (elt == NULL) return (ISC_FALSE); return (ISC_TRUE); } static char * current_file(cfg_parser_t *pctx) { static char none[] = "none"; cfg_listelt_t *elt; cfg_obj_t *fileobj; if (!have_current_file(pctx)) return (none); elt = ISC_LIST_TAIL(pctx->open_files->value.list); if (elt == NULL) /* shouldn't be possible, but... */ return (none); fileobj = elt->obj; INSIST(fileobj->type == &cfg_type_qstring); return (fileobj->value.string.base); } static void parser_complain(cfg_parser_t *pctx, isc_boolean_t is_warning, unsigned int flags, const char *format, va_list args) { char tokenbuf[MAX_LOG_TOKEN + 10]; static char where[ISC_DIR_PATHMAX + 100]; static char message[2048]; int level = ISC_LOG_ERROR; const char *prep = ""; size_t len; if (is_warning) level = ISC_LOG_WARNING; where[0] = '\0'; if (have_current_file(pctx)) snprintf(where, sizeof(where), "%s:%u: ", current_file(pctx), pctx->line); len = vsnprintf(message, sizeof(message), format, args); #define ELIPSIS " ... " if (len >= sizeof(message)) strcpy(message + sizeof(message) - sizeof(ELIPSIS) - 1, ELIPSIS); if ((flags & (CFG_LOG_NEAR|CFG_LOG_BEFORE|CFG_LOG_NOPREP)) != 0) { isc_region_t r; if (pctx->ungotten) (void)cfg_gettoken(pctx, 0); if (pctx->token.type == isc_tokentype_eof) { snprintf(tokenbuf, sizeof(tokenbuf), "end of file"); } else if (pctx->token.type == isc_tokentype_unknown) { flags = 0; tokenbuf[0] = '\0'; } else { isc_lex_getlasttokentext(pctx->lexer, &pctx->token, &r); if (r.length > MAX_LOG_TOKEN) snprintf(tokenbuf, sizeof(tokenbuf), "'%.*s...'", MAX_LOG_TOKEN, r.base); else snprintf(tokenbuf, sizeof(tokenbuf), "'%.*s'", (int)r.length, r.base); } /* Choose a preposition. */ if (flags & CFG_LOG_NEAR) prep = " near "; else if (flags & CFG_LOG_BEFORE) prep = " before "; else prep = " "; } else { tokenbuf[0] = '\0'; } isc_log_write(pctx->lctx, CAT, MOD, level, "%s%s%s%s", where, message, prep, tokenbuf); } void cfg_obj_log(const cfg_obj_t *obj, isc_log_t *lctx, int level, const char *fmt, ...) { va_list ap; char msgbuf[2048]; if (! isc_log_wouldlog(lctx, level)) return; va_start(ap, fmt); vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); isc_log_write(lctx, CAT, MOD, level, "%s:%u: %s", obj->file == NULL ? "" : obj->file, obj->line, msgbuf); va_end(ap); } const char * cfg_obj_file(const cfg_obj_t *obj) { return (obj->file); } unsigned int cfg_obj_line(const cfg_obj_t *obj) { return (obj->line); } isc_result_t cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *obj; obj = isc_mem_get(pctx->mctx, sizeof(cfg_obj_t)); if (obj == NULL) return (ISC_R_NOMEMORY); obj->type = type; obj->file = current_file(pctx); obj->line = pctx->line; result = isc_refcount_init(&obj->references, 1); if (result != ISC_R_SUCCESS) { isc_mem_put(pctx->mctx, obj, sizeof(cfg_obj_t)); return (result); } *ret = obj; return (ISC_R_SUCCESS); } static void map_symtabitem_destroy(char *key, unsigned int type, isc_symvalue_t symval, void *userarg) { cfg_obj_t *obj = symval.as_pointer; cfg_parser_t *pctx = (cfg_parser_t *)userarg; UNUSED(key); UNUSED(type); cfg_obj_destroy(pctx, &obj); } static isc_result_t create_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; isc_symtab_t *symtab = NULL; cfg_obj_t *obj = NULL; CHECK(cfg_create_obj(pctx, type, &obj)); CHECK(isc_symtab_create(pctx->mctx, 5, /* XXX */ map_symtabitem_destroy, pctx, ISC_FALSE, &symtab)); obj->value.map.symtab = symtab; obj->value.map.id = NULL; *ret = obj; return (ISC_R_SUCCESS); cleanup: if (obj != NULL) isc_mem_put(pctx->mctx, obj, sizeof(*obj)); return (result); } static void free_map(cfg_parser_t *pctx, cfg_obj_t *obj) { CLEANUP_OBJ(obj->value.map.id); isc_symtab_destroy(&obj->value.map.symtab); } isc_boolean_t cfg_obj_istype(const cfg_obj_t *obj, const cfg_type_t *type) { return (ISC_TF(obj->type == type)); } /* * Destroy 'obj', a configuration object created in 'pctx'. */ void cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **objp) { cfg_obj_t *obj; unsigned int refs; REQUIRE(objp != NULL && *objp != NULL); REQUIRE(pctx != NULL); obj = *objp; isc_refcount_decrement(&obj->references, &refs); if (refs == 0) { obj->type->rep->free(pctx, obj); isc_refcount_destroy(&obj->references); isc_mem_put(pctx->mctx, obj, sizeof(cfg_obj_t)); } *objp = NULL; } void cfg_obj_attach(cfg_obj_t *src, cfg_obj_t **dest) { REQUIRE(src != NULL); REQUIRE(dest != NULL && *dest == NULL); isc_refcount_increment(&src->references, NULL); *dest = src; } static void free_noop(cfg_parser_t *pctx, cfg_obj_t *obj) { UNUSED(pctx); UNUSED(obj); } void cfg_doc_obj(cfg_printer_t *pctx, const cfg_type_t *type) { type->doc(pctx, type); } void cfg_doc_terminal(cfg_printer_t *pctx, const cfg_type_t *type) { cfg_print_chars(pctx, "<", 1); cfg_print_cstr(pctx, type->name); cfg_print_chars(pctx, ">", 1); } void cfg_print_grammar(const cfg_type_t *type, void (*f)(void *closure, const char *text, int textlen), void *closure) { cfg_printer_t pctx; pctx.f = f; pctx.closure = closure; pctx.indent = 0; pctx.flags = 0; cfg_doc_obj(&pctx, type); } bind9-9.10.3.dfsg.P4/lib/isccfg/api0000644000470500017500000000025612664710322016074 0ustar lamontlamont# LIBINTERFACE ranges # 9.6: 50-59, 110-119 # 9.7: 60-79 # 9.8: 80-89, 120-129 # 9.9: 90-109 # 9.9-sub: 130-139 # 9.10: 140-149 LIBINTERFACE = 143 LIBREVISION = 0 LIBAGE = 3 bind9-9.10.3.dfsg.P4/lib/win32/0002755000470500017500000000000012664710322015103 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/win32/bindevt/0002755000470500017500000000000012664730167016547 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/win32/bindevt/bindevt.mc0000644000470500017500000000237612664710322020520 0ustar lamontlamont; Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") ; Copyright (C) 2001 Internet Software Consortium. ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above ; copyright notice and this permission notice appear in all copies. ; ; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. ; $Id: bindevt.mc,v 1.4 2007/06/19 23:47:24 tbox Exp $ MessageIdTypedef=DWORD LanguageNames = (English=0x409:MSG00409) OutputBase = 16 MessageId=0x1 Severity=Error Facility=Application SymbolicName=BIND_ERR_MSG Language=English %1 . MessageId=0x2 Severity=Warning Facility=Application SymbolicName=BIND_WARN_MSG Language=English %1 . MessageId=0x3 Severity=Informational Facility=Application SymbolicName=BIND_INFO_MSG Language=English %1 . bind9-9.10.3.dfsg.P4/lib/win32/bindevt/bindevt.dsw0000644000470500017500000000103112664710322020701 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "bindevt"=.\bindevt.dsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/lib/win32/bindevt/bindevt.vcxproj.user0000644000470500017500000000021712664710322022561 0ustar lamontlamont bind9-9.10.3.dfsg.P4/lib/win32/bindevt/bindevt.c0000644000470500017500000000214412664710322020334 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: bindevt.c,v 1.5 2007/06/19 23:47:24 tbox Exp $ */ /* * bindevt.c : Defines the entry point for event log viewer DLL. */ #include BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { return (TRUE); } bind9-9.10.3.dfsg.P4/lib/win32/bindevt/bindevt.vcxproj.in0000644000470500017500000001506112664710322022214 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {0D745CD9-FC3B-49DC-99BE-1E6DF85593F0} Win32Proj bindevt DynamicLibrary true MultiByte DynamicLibrary false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ ResourceCompile true false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ ResourceCompile true Level3 Disabled WIN32;_DEBUG;_WINDOWS;_USRDLL;BINDEVT_EXPORTS;%(PreprocessorDefinitions) ..\include;..\..\..\include;%(AdditionalIncludeDirectories) MultiThreadedDebugDLL false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) .\$(Configuration)\$(ProjectName).lib mc bindevt.mc $(TargetName).rc Level3 MaxSpeed true false WIN32;NDEBUG;_WINDOWS;_USRDLL;BINDEVT_EXPORTS;%(PreprocessorDefinitions) ..\include;..\..\..\include;%(AdditionalIncludeDirectories) OnlyExplicitInline true MultiThreadedDLL .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb false Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Default .\$(Configuration)\$(ProjectName).lib mc bindevt.mc $(TargetName).rc bind9-9.10.3.dfsg.P4/lib/win32/bindevt/bindevt.mak.in0000644000470500017500000001751712664710322021301 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on bindevt.dsp !IF "$(CFG)" == "" CFG=bindevt - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to bindevt - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "bindevt - @PLATFORM@ Release" && "$(CFG)" != "bindevt - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "bindevt.mak" CFG="bindevt - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "bindevt - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE "bindevt - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "bindevt - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "bindevt - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release ALL : "..\..\..\Build\Release\bindevt.dll" CLEAN : -@erase "$(INTDIR)\bindevt.obj" -@erase "$(INTDIR)\bindevt.res" -@erase "$(INTDIR)\vc60.idb" -@erase "$(OUTDIR)\bindevt.exp" -@erase "..\..\..\Build\Release\bindevt.dll" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MT /W3 @COPTX@ @COPTI@ /O2 /I "..\include" /I "..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BINDEVT_EXPORTS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 RSC_PROJ=/l 0x409 /fo"$(INTDIR)\bindevt.res" /d "NDEBUG" BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\bindevt.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /pdb:none @MACHINE@ /out:"..\..\..\Build\Release\bindevt.dll" /implib:"$(OUTDIR)\bindevt.lib" LINK32_OBJS= \ "$(INTDIR)\bindevt.obj" \ "$(INTDIR)\bindevt.res" "..\..\..\Build\Release\bindevt.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_DLL) !ELSEIF "$(CFG)" == "bindevt - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros ALL : "..\..\..\Build\Debug\bindevt.dll" "$(OUTDIR)\bindevt.bsc" CLEAN : -@erase "$(INTDIR)\bindevt.obj" -@erase "$(INTDIR)\bindevt.res" -@erase "$(INTDIR)\bindevt.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\bindevt.bsc" -@erase "$(OUTDIR)\bindevt.exp" -@erase "..\..\..\Build\Debug\bindevt.dll" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MTd /W3 /Gm @COPTX@ @COPTI@ /Zi /Od /I "..\include" /I "..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BINDEVT_EXPORTS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 RSC_PROJ=/l 0x409 /fo"$(INTDIR)\bindevt.res" /d "_DEBUG" BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\bindevt.bsc" BSC32_SBRS= \ "$(INTDIR)\bindevt.sbr" "$(OUTDIR)\bindevt.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /pdb:none /debug @MACHINE@ /out:"..\..\..\Build\Debug\bindevt.dll" /implib:"$(OUTDIR)\bindevt.lib" LINK32_OBJS= \ "$(INTDIR)\bindevt.obj" \ "$(INTDIR)\bindevt.res" "..\..\..\Build\Debug\bindevt.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_DLL) !ENDIF .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("bindevt.dep") !INCLUDE "bindevt.dep" !ELSE !MESSAGE Warning: cannot find "bindevt.dep" !ENDIF !ENDIF !IF "$(CFG)" == "bindevt - @PLATFORM@ Release" || "$(CFG)" == "bindevt - @PLATFORM@ Debug" SOURCE=.\bindevt.c !IF "$(CFG)" == "bindevt - @PLATFORM@ Release" "$(INTDIR)\bindevt.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "bindevt - @PLATFORM@ Debug" "$(INTDIR)\bindevt.obj" "$(INTDIR)\bindevt.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\bindevt.mc !IF "$(CFG)" == "bindevt - @PLATFORM@ Release" TargetName=bindevt InputPath=.\bindevt.mc InputName=bindevt ".\bindevt.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" < 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/lib/win32/bindevt/bindevt.dsp.in0000644000470500017500000001100612664710322021302 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="bindevt" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Dynamic-Link Library" 0x0102 CFG=bindevt - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "bindevt.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "bindevt.mak" CFG="bindevt - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "bindevt - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE "bindevt - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "bindevt - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BINDEVT_EXPORTS" /Yu"stdafx.h" /FD /c # ADD CPP /nologo /MT /W3 @COPTX@ @COPTI@ /O2 /I "..\include" /I "..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BINDEVT_EXPORTS" /FD /c # SUBTRACT CPP @COPTY@ /Yc /Yu # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll @MACHINE@ # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /pdb:none @MACHINE@ /out:"..\..\..\Build\Release\bindevt.dll" !ELSEIF "$(CFG)" == "bindevt - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BINDEVT_EXPORTS" /Yu"stdafx.h" /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm @COPTX@ @COPTI@ /Zi /Od /I "..\include" /I "..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BINDEVT_EXPORTS" /FR /FD /GZ /c # SUBTRACT CPP @COPTY@ /Yc /Yu # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug @MACHINE@ /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /pdb:none /debug @MACHINE@ /out:"..\..\..\Build\Debug\bindevt.dll" !ENDIF # Begin Target # Name "bindevt - @PLATFORM@ Release" # Name "bindevt - @PLATFORM@ Debug" # Begin Source File SOURCE=.\bindevt.c # End Source File # Begin Source File SOURCE=.\bindevt.mc !IF "$(CFG)" == "bindevt - @PLATFORM@ Release" # Begin Custom Build TargetName=bindevt InputPath=.\bindevt.mc InputName=bindevt "$(TargetName).rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" mc $(InputName).mc # End Custom Build !ELSEIF "$(CFG)" == "bindevt - @PLATFORM@ Debug" # Begin Custom Build TargetName=bindevt InputPath=.\bindevt.mc InputName=bindevt "$(TargetName).rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" mc $(InputName).mc # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=.\bindevt.rc # End Source File # End Target # End Project bind9-9.10.3.dfsg.P4/lib/win32/bindevt/bindevt.vcxproj.filters.in0000644000470500017500000000054412664710322023663 0ustar lamontlamont bind9-9.10.3.dfsg.P4/lib/isc/0002755000470500017500000000000012672612753014727 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/ratelimiter.c0000644000470500017500000002131312664710322017402 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ratelimiter.c,v 1.25 2007/06/19 23:47:17 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include typedef enum { isc_ratelimiter_stalled = 0, isc_ratelimiter_ratelimited = 1, isc_ratelimiter_idle = 2, isc_ratelimiter_shuttingdown = 3 } isc_ratelimiter_state_t; struct isc_ratelimiter { isc_mem_t * mctx; isc_mutex_t lock; int refs; isc_task_t * task; isc_timer_t * timer; isc_interval_t interval; isc_uint32_t pertic; isc_ratelimiter_state_t state; isc_event_t shutdownevent; ISC_LIST(isc_event_t) pending; }; #define ISC_RATELIMITEREVENT_SHUTDOWN (ISC_EVENTCLASS_RATELIMITER + 1) static void ratelimiter_tick(isc_task_t *task, isc_event_t *event); static void ratelimiter_shutdowncomplete(isc_task_t *task, isc_event_t *event); isc_result_t isc_ratelimiter_create(isc_mem_t *mctx, isc_timermgr_t *timermgr, isc_task_t *task, isc_ratelimiter_t **ratelimiterp) { isc_result_t result; isc_ratelimiter_t *rl; INSIST(ratelimiterp != NULL && *ratelimiterp == NULL); rl = isc_mem_get(mctx, sizeof(*rl)); if (rl == NULL) return ISC_R_NOMEMORY; rl->mctx = mctx; rl->refs = 1; rl->task = task; isc_interval_set(&rl->interval, 0, 0); rl->timer = NULL; rl->pertic = 1; rl->state = isc_ratelimiter_idle; ISC_LIST_INIT(rl->pending); result = isc_mutex_init(&rl->lock); if (result != ISC_R_SUCCESS) goto free_mem; result = isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL, rl->task, ratelimiter_tick, rl, &rl->timer); if (result != ISC_R_SUCCESS) goto free_mutex; /* * Increment the reference count to indicate that we may * (soon) have events outstanding. */ rl->refs++; ISC_EVENT_INIT(&rl->shutdownevent, sizeof(isc_event_t), 0, NULL, ISC_RATELIMITEREVENT_SHUTDOWN, ratelimiter_shutdowncomplete, rl, rl, NULL, NULL); *ratelimiterp = rl; return (ISC_R_SUCCESS); free_mutex: DESTROYLOCK(&rl->lock); free_mem: isc_mem_put(mctx, rl, sizeof(*rl)); return (result); } isc_result_t isc_ratelimiter_setinterval(isc_ratelimiter_t *rl, isc_interval_t *interval) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(rl != NULL); REQUIRE(interval != NULL); LOCK(&rl->lock); rl->interval = *interval; /* * If the timer is currently running, change its rate. */ if (rl->state == isc_ratelimiter_ratelimited) { result = isc_timer_reset(rl->timer, isc_timertype_ticker, NULL, &rl->interval, ISC_FALSE); } UNLOCK(&rl->lock); return (result); } void isc_ratelimiter_setpertic(isc_ratelimiter_t *rl, isc_uint32_t pertic) { REQUIRE(rl != NULL); if (pertic == 0) pertic = 1; rl->pertic = pertic; } isc_result_t isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task, isc_event_t **eventp) { isc_result_t result = ISC_R_SUCCESS; isc_event_t *ev; REQUIRE(rl != NULL); REQUIRE(task != NULL); REQUIRE(eventp != NULL && *eventp != NULL); ev = *eventp; REQUIRE(ev->ev_sender == NULL); LOCK(&rl->lock); if (rl->state == isc_ratelimiter_ratelimited || rl->state == isc_ratelimiter_stalled) { ev->ev_sender = task; *eventp = NULL; ISC_LIST_APPEND(rl->pending, ev, ev_link); } else if (rl->state == isc_ratelimiter_idle) { result = isc_timer_reset(rl->timer, isc_timertype_ticker, NULL, &rl->interval, ISC_FALSE); if (result == ISC_R_SUCCESS) { ev->ev_sender = task; rl->state = isc_ratelimiter_ratelimited; } } else { INSIST(rl->state == isc_ratelimiter_shuttingdown); result = ISC_R_SHUTTINGDOWN; } UNLOCK(&rl->lock); if (*eventp != NULL && result == ISC_R_SUCCESS) isc_task_send(task, eventp); return (result); } isc_result_t isc_ratelimiter_dequeue(isc_ratelimiter_t *rl, isc_event_t *event) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(rl != NULL); REQUIRE(event != NULL); LOCK(&rl->lock); if (ISC_LINK_LINKED(event, ev_link)) { ISC_LIST_UNLINK(rl->pending, event, ev_link); event->ev_sender = NULL; } else result = ISC_R_NOTFOUND; UNLOCK(&rl->lock); return (result); } static void ratelimiter_tick(isc_task_t *task, isc_event_t *event) { isc_result_t result = ISC_R_SUCCESS; isc_ratelimiter_t *rl = (isc_ratelimiter_t *)event->ev_arg; isc_event_t *p; isc_uint32_t pertic; UNUSED(task); isc_event_free(&event); pertic = rl->pertic; while (pertic != 0) { pertic--; LOCK(&rl->lock); p = ISC_LIST_HEAD(rl->pending); if (p != NULL) { /* * There is work to do. Let's do it after unlocking. */ ISC_LIST_UNLINK(rl->pending, p, ev_link); } else { /* * No work left to do. Stop the timer so that we don't * waste resources by having it fire periodically. */ result = isc_timer_reset(rl->timer, isc_timertype_inactive, NULL, NULL, ISC_FALSE); RUNTIME_CHECK(result == ISC_R_SUCCESS); rl->state = isc_ratelimiter_idle; pertic = 0; /* Force the loop to exit. */ } UNLOCK(&rl->lock); if (p != NULL) { isc_task_t *evtask = p->ev_sender; isc_task_send(evtask, &p); } INSIST(p == NULL); } } void isc_ratelimiter_shutdown(isc_ratelimiter_t *rl) { isc_event_t *ev; isc_task_t *task; REQUIRE(rl != NULL); LOCK(&rl->lock); rl->state = isc_ratelimiter_shuttingdown; (void)isc_timer_reset(rl->timer, isc_timertype_inactive, NULL, NULL, ISC_FALSE); while ((ev = ISC_LIST_HEAD(rl->pending)) != NULL) { ISC_LIST_UNLINK(rl->pending, ev, ev_link); ev->ev_attributes |= ISC_EVENTATTR_CANCELED; task = ev->ev_sender; isc_task_send(task, &ev); } isc_timer_detach(&rl->timer); /* * Send an event to our task. The delivery of this event * indicates that no more timer events will be delivered. */ ev = &rl->shutdownevent; isc_task_send(rl->task, &ev); UNLOCK(&rl->lock); } static void ratelimiter_shutdowncomplete(isc_task_t *task, isc_event_t *event) { isc_ratelimiter_t *rl = (isc_ratelimiter_t *)event->ev_arg; UNUSED(task); isc_ratelimiter_detach(&rl); } static void ratelimiter_free(isc_ratelimiter_t *rl) { DESTROYLOCK(&rl->lock); isc_mem_put(rl->mctx, rl, sizeof(*rl)); } void isc_ratelimiter_attach(isc_ratelimiter_t *source, isc_ratelimiter_t **target) { REQUIRE(source != NULL); REQUIRE(target != NULL && *target == NULL); LOCK(&source->lock); REQUIRE(source->refs > 0); source->refs++; INSIST(source->refs > 0); UNLOCK(&source->lock); *target = source; } void isc_ratelimiter_detach(isc_ratelimiter_t **rlp) { isc_ratelimiter_t *rl; isc_boolean_t free_now = ISC_FALSE; REQUIRE(rlp != NULL && *rlp != NULL); rl = *rlp; LOCK(&rl->lock); REQUIRE(rl->refs > 0); rl->refs--; if (rl->refs == 0) free_now = ISC_TRUE; UNLOCK(&rl->lock); if (free_now) ratelimiter_free(rl); *rlp = NULL; } isc_result_t isc_ratelimiter_stall(isc_ratelimiter_t *rl) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(rl != NULL); LOCK(&rl->lock); switch (rl->state) { case isc_ratelimiter_shuttingdown: result = ISC_R_SHUTTINGDOWN; break; case isc_ratelimiter_ratelimited: result = isc_timer_reset(rl->timer, isc_timertype_inactive, NULL, NULL, ISC_FALSE); RUNTIME_CHECK(result == ISC_R_SUCCESS); /* FALLTHROUGH */ case isc_ratelimiter_idle: case isc_ratelimiter_stalled: rl->state = isc_ratelimiter_stalled; break; } UNLOCK(&rl->lock); return (result); } isc_result_t isc_ratelimiter_release(isc_ratelimiter_t *rl) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(rl != NULL); LOCK(&rl->lock); switch (rl->state) { case isc_ratelimiter_shuttingdown: result = ISC_R_SHUTTINGDOWN; break; case isc_ratelimiter_stalled: if (!ISC_LIST_EMPTY(rl->pending)) { result = isc_timer_reset(rl->timer, isc_timertype_ticker, NULL, &rl->interval, ISC_FALSE); if (result == ISC_R_SUCCESS) rl->state = isc_ratelimiter_ratelimited; } else rl->state = isc_ratelimiter_idle; break; case isc_ratelimiter_ratelimited: case isc_ratelimiter_idle: break; } UNLOCK(&rl->lock); return (result); } bind9-9.10.3.dfsg.P4/lib/isc/buffer.c0000644000470500017500000002411412664710322016334 0ustar lamontlamont/* * Copyright (C) 2004-2008, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: buffer.c,v 1.49 2008/09/25 04:02:39 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include void isc__buffer_init(isc_buffer_t *b, void *base, unsigned int length) { /* * Make 'b' refer to the 'length'-byte region starting at 'base'. * XXXDCL see the comment in buffer.h about base being const. */ REQUIRE(b != NULL); ISC__BUFFER_INIT(b, base, length); } void isc__buffer_initnull(isc_buffer_t *b) { /* * Initialize a new buffer which has no backing store. This can * later be grown as needed and swapped in place. */ ISC__BUFFER_INIT(b, NULL, 0); } void isc_buffer_reinit(isc_buffer_t *b, void *base, unsigned int length) { /* * Re-initialize the buffer enough to reconfigure the base of the * buffer. We will swap in the new buffer, after copying any * data we contain into the new buffer and adjusting all of our * internal pointers. * * The buffer must not be smaller than the length of the original * buffer. */ REQUIRE(b->length <= length); REQUIRE(base != NULL); (void)memmove(base, b->base, b->length); b->base = base; b->length = length; } void isc__buffer_invalidate(isc_buffer_t *b) { /* * Make 'b' an invalid buffer. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(!ISC_LINK_LINKED(b, link)); REQUIRE(b->mctx == NULL); ISC__BUFFER_INVALIDATE(b); } void isc__buffer_region(isc_buffer_t *b, isc_region_t *r) { /* * Make 'r' refer to the region of 'b'. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(r != NULL); ISC__BUFFER_REGION(b, r); } void isc__buffer_usedregion(isc_buffer_t *b, isc_region_t *r) { /* * Make 'r' refer to the used region of 'b'. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(r != NULL); ISC__BUFFER_USEDREGION(b, r); } void isc__buffer_availableregion(isc_buffer_t *b, isc_region_t *r) { /* * Make 'r' refer to the available region of 'b'. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(r != NULL); ISC__BUFFER_AVAILABLEREGION(b, r); } void isc__buffer_add(isc_buffer_t *b, unsigned int n) { /* * Increase the 'used' region of 'b' by 'n' bytes. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->used + n <= b->length); ISC__BUFFER_ADD(b, n); } void isc__buffer_subtract(isc_buffer_t *b, unsigned int n) { /* * Decrease the 'used' region of 'b' by 'n' bytes. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->used >= n); ISC__BUFFER_SUBTRACT(b, n); } void isc__buffer_clear(isc_buffer_t *b) { /* * Make the used region empty. */ REQUIRE(ISC_BUFFER_VALID(b)); ISC__BUFFER_CLEAR(b); } void isc__buffer_consumedregion(isc_buffer_t *b, isc_region_t *r) { /* * Make 'r' refer to the consumed region of 'b'. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(r != NULL); ISC__BUFFER_CONSUMEDREGION(b, r); } void isc__buffer_remainingregion(isc_buffer_t *b, isc_region_t *r) { /* * Make 'r' refer to the remaining region of 'b'. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(r != NULL); ISC__BUFFER_REMAININGREGION(b, r); } void isc__buffer_activeregion(isc_buffer_t *b, isc_region_t *r) { /* * Make 'r' refer to the active region of 'b'. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(r != NULL); ISC__BUFFER_ACTIVEREGION(b, r); } void isc__buffer_setactive(isc_buffer_t *b, unsigned int n) { /* * Sets the end of the active region 'n' bytes after current. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->current + n <= b->used); ISC__BUFFER_SETACTIVE(b, n); } void isc__buffer_first(isc_buffer_t *b) { /* * Make the consumed region empty. */ REQUIRE(ISC_BUFFER_VALID(b)); ISC__BUFFER_FIRST(b); } void isc__buffer_forward(isc_buffer_t *b, unsigned int n) { /* * Increase the 'consumed' region of 'b' by 'n' bytes. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->current + n <= b->used); ISC__BUFFER_FORWARD(b, n); } void isc__buffer_back(isc_buffer_t *b, unsigned int n) { /* * Decrease the 'consumed' region of 'b' by 'n' bytes. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(n <= b->current); ISC__BUFFER_BACK(b, n); } void isc_buffer_compact(isc_buffer_t *b) { unsigned int length; void *src; /* * Compact the used region by moving the remaining region so it occurs * at the start of the buffer. The used region is shrunk by the size * of the consumed region, and the consumed region is then made empty. */ REQUIRE(ISC_BUFFER_VALID(b)); src = isc_buffer_current(b); length = isc_buffer_remaininglength(b); (void)memmove(b->base, src, (size_t)length); if (b->active > b->current) b->active -= b->current; else b->active = 0; b->current = 0; b->used = length; } isc_uint8_t isc_buffer_getuint8(isc_buffer_t *b) { unsigned char *cp; isc_uint8_t result; /* * Read an unsigned 8-bit integer from 'b' and return it. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->used - b->current >= 1); cp = isc_buffer_current(b); b->current += 1; result = ((isc_uint8_t)(cp[0])); return (result); } void isc__buffer_putuint8(isc_buffer_t *b, isc_uint8_t val) { REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->used + 1 <= b->length); ISC__BUFFER_PUTUINT8(b, val); } isc_uint16_t isc_buffer_getuint16(isc_buffer_t *b) { unsigned char *cp; isc_uint16_t result; /* * Read an unsigned 16-bit integer in network byte order from 'b', * convert it to host byte order, and return it. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->used - b->current >= 2); cp = isc_buffer_current(b); b->current += 2; result = ((unsigned int)(cp[0])) << 8; result |= ((unsigned int)(cp[1])); return (result); } void isc__buffer_putuint16(isc_buffer_t *b, isc_uint16_t val) { REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->used + 2 <= b->length); ISC__BUFFER_PUTUINT16(b, val); } void isc__buffer_putuint24(isc_buffer_t *b, isc_uint32_t val) { REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->used + 3 <= b->length); ISC__BUFFER_PUTUINT24(b, val); } isc_uint32_t isc_buffer_getuint32(isc_buffer_t *b) { unsigned char *cp; isc_uint32_t result; /* * Read an unsigned 32-bit integer in network byte order from 'b', * convert it to host byte order, and return it. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->used - b->current >= 4); cp = isc_buffer_current(b); b->current += 4; result = ((unsigned int)(cp[0])) << 24; result |= ((unsigned int)(cp[1])) << 16; result |= ((unsigned int)(cp[2])) << 8; result |= ((unsigned int)(cp[3])); return (result); } void isc__buffer_putuint32(isc_buffer_t *b, isc_uint32_t val) { REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->used + 4 <= b->length); ISC__BUFFER_PUTUINT32(b, val); } isc_uint64_t isc_buffer_getuint48(isc_buffer_t *b) { unsigned char *cp; isc_uint64_t result; /* * Read an unsigned 48-bit integer in network byte order from 'b', * convert it to host byte order, and return it. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->used - b->current >= 6); cp = isc_buffer_current(b); b->current += 6; result = ((isc_int64_t)(cp[0])) << 40; result |= ((isc_int64_t)(cp[1])) << 32; result |= ((isc_int64_t)(cp[2])) << 24; result |= ((isc_int64_t)(cp[3])) << 16; result |= ((isc_int64_t)(cp[4])) << 8; result |= ((isc_int64_t)(cp[5])); return (result); } void isc__buffer_putuint48(isc_buffer_t *b, isc_uint64_t val) { isc_uint16_t valhi; isc_uint32_t vallo; REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->used + 6 <= b->length); valhi = (isc_uint16_t)(val >> 32); vallo = (isc_uint32_t)(val & 0xFFFFFFFF); ISC__BUFFER_PUTUINT16(b, valhi); ISC__BUFFER_PUTUINT32(b, vallo); } void isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base, unsigned int length) { REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->used + length <= b->length); ISC__BUFFER_PUTMEM(b, base, length); } void isc__buffer_putstr(isc_buffer_t *b, const char *source) { unsigned int l; unsigned char *cp; REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(source != NULL); /* * Do not use ISC__BUFFER_PUTSTR(), so strlen is only done once. */ l = strlen(source); REQUIRE(l <= isc_buffer_availablelength(b)); cp = isc_buffer_used(b); memmove(cp, source, l); b->used += l; } isc_result_t isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r) { unsigned char *base; unsigned int available; REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(r != NULL); /* * XXXDCL */ base = isc_buffer_used(b); available = isc_buffer_availablelength(b); if (r->length > available) return (ISC_R_NOSPACE); memmove(base, r->base, r->length); b->used += r->length; return (ISC_R_SUCCESS); } isc_result_t isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer, unsigned int length) { isc_buffer_t *dbuf; REQUIRE(dynbuffer != NULL); REQUIRE(*dynbuffer == NULL); dbuf = isc_mem_get(mctx, length + sizeof(isc_buffer_t)); if (dbuf == NULL) return (ISC_R_NOMEMORY); isc_buffer_init(dbuf, ((unsigned char *)dbuf) + sizeof(isc_buffer_t), length); dbuf->mctx = mctx; *dynbuffer = dbuf; return (ISC_R_SUCCESS); } void isc_buffer_free(isc_buffer_t **dynbuffer) { unsigned int real_length; isc_buffer_t *dbuf; isc_mem_t *mctx; REQUIRE(dynbuffer != NULL); REQUIRE(ISC_BUFFER_VALID(*dynbuffer)); REQUIRE((*dynbuffer)->mctx != NULL); dbuf = *dynbuffer; *dynbuffer = NULL; /* destroy external reference */ real_length = dbuf->length + sizeof(isc_buffer_t); mctx = dbuf->mctx; dbuf->mctx = NULL; isc_buffer_invalidate(dbuf); isc_mem_put(mctx, dbuf, real_length); } bind9-9.10.3.dfsg.P4/lib/isc/task.c0000644000470500017500000016000612664710322016026 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file * \author Principal Author: Bob Halley */ /* * XXXRTH Need to document the states a task can be in, and the rules * for changing states. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef OPENSSL_LEAKS #include #endif /*% * For BIND9 internal applications: * when built with threads we use multiple worker threads shared by the whole * application. * when built without threads we share a single global task manager and use * an integrated event loop for socket, timer, and other generic task events. * For generic library: * we don't use either of them: an application can have multiple task managers * whether or not it's threaded, and if the application is threaded each thread * is expected to have a separate manager; no "worker threads" are shared by * the application threads. */ #ifdef ISC_PLATFORM_USETHREADS #define USE_WORKER_THREADS #else #define USE_SHARED_MANAGER #endif /* ISC_PLATFORM_USETHREADS */ #include "task_p.h" #ifdef ISC_TASK_TRACE #define XTRACE(m) fprintf(stderr, "task %p thread %lu: %s\n", \ task, isc_thread_self(), (m)) #define XTTRACE(t, m) fprintf(stderr, "task %p thread %lu: %s\n", \ (t), isc_thread_self(), (m)) #define XTHREADTRACE(m) fprintf(stderr, "thread %lu: %s\n", \ isc_thread_self(), (m)) #else #define XTRACE(m) #define XTTRACE(t, m) #define XTHREADTRACE(m) #endif /*** *** Types. ***/ typedef enum { task_state_idle, task_state_ready, task_state_running, task_state_done } task_state_t; #if defined(HAVE_LIBXML2) || defined(HAVE_JSON) static const char *statenames[] = { "idle", "ready", "running", "done", }; #endif #define TASK_MAGIC ISC_MAGIC('T', 'A', 'S', 'K') #define VALID_TASK(t) ISC_MAGIC_VALID(t, TASK_MAGIC) typedef struct isc__task isc__task_t; typedef struct isc__taskmgr isc__taskmgr_t; struct isc__task { /* Not locked. */ isc_task_t common; isc__taskmgr_t * manager; isc_mutex_t lock; /* Locked by task lock. */ task_state_t state; unsigned int references; isc_eventlist_t events; isc_eventlist_t on_shutdown; unsigned int nevents; unsigned int quantum; unsigned int flags; isc_stdtime_t now; char name[16]; void * tag; /* Locked by task manager lock. */ LINK(isc__task_t) link; LINK(isc__task_t) ready_link; LINK(isc__task_t) ready_priority_link; }; #define TASK_F_SHUTTINGDOWN 0x01 #define TASK_F_PRIVILEGED 0x02 #define TASK_SHUTTINGDOWN(t) (((t)->flags & TASK_F_SHUTTINGDOWN) \ != 0) #define TASK_MANAGER_MAGIC ISC_MAGIC('T', 'S', 'K', 'M') #define VALID_MANAGER(m) ISC_MAGIC_VALID(m, TASK_MANAGER_MAGIC) typedef ISC_LIST(isc__task_t) isc__tasklist_t; struct isc__taskmgr { /* Not locked. */ isc_taskmgr_t common; isc_mem_t * mctx; isc_mutex_t lock; #ifdef ISC_PLATFORM_USETHREADS unsigned int workers; isc_thread_t * threads; #endif /* ISC_PLATFORM_USETHREADS */ /* Locked by task manager lock. */ unsigned int default_quantum; LIST(isc__task_t) tasks; isc__tasklist_t ready_tasks; isc__tasklist_t ready_priority_tasks; isc_taskmgrmode_t mode; #ifdef ISC_PLATFORM_USETHREADS isc_condition_t work_available; isc_condition_t exclusive_granted; isc_condition_t paused; #endif /* ISC_PLATFORM_USETHREADS */ unsigned int tasks_running; unsigned int tasks_ready; isc_boolean_t pause_requested; isc_boolean_t exclusive_requested; isc_boolean_t exiting; /* * Multiple threads can read/write 'excl' at the same time, so we need * to protect the access. We can't use 'lock' since isc_task_detach() * will try to acquire it. */ isc_mutex_t excl_lock; isc__task_t *excl; #ifdef USE_SHARED_MANAGER unsigned int refs; #endif /* ISC_PLATFORM_USETHREADS */ }; #define DEFAULT_TASKMGR_QUANTUM 10 #define DEFAULT_DEFAULT_QUANTUM 5 #define FINISHED(m) ((m)->exiting && EMPTY((m)->tasks)) #ifdef USE_SHARED_MANAGER static isc__taskmgr_t *taskmgr = NULL; #endif /* USE_SHARED_MANAGER */ /*% * The following are intended for internal use (indicated by "isc__" * prefix) but are not declared as static, allowing direct access from * unit tests etc. */ isc_result_t isc__task_create(isc_taskmgr_t *manager0, unsigned int quantum, isc_task_t **taskp); void isc__task_attach(isc_task_t *source0, isc_task_t **targetp); void isc__task_detach(isc_task_t **taskp); void isc__task_send(isc_task_t *task0, isc_event_t **eventp); void isc__task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp); unsigned int isc__task_purgerange(isc_task_t *task0, void *sender, isc_eventtype_t first, isc_eventtype_t last, void *tag); unsigned int isc__task_purge(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag); isc_boolean_t isc_task_purgeevent(isc_task_t *task0, isc_event_t *event); unsigned int isc__task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first, isc_eventtype_t last, void *tag, isc_eventlist_t *events); unsigned int isc__task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag, isc_eventlist_t *events); isc_result_t isc__task_onshutdown(isc_task_t *task0, isc_taskaction_t action, void *arg); void isc__task_shutdown(isc_task_t *task0); void isc__task_destroy(isc_task_t **taskp); void isc__task_setname(isc_task_t *task0, const char *name, void *tag); const char * isc__task_getname(isc_task_t *task0); void * isc__task_gettag(isc_task_t *task0); void isc__task_getcurrenttime(isc_task_t *task0, isc_stdtime_t *t); isc_result_t isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers, unsigned int default_quantum, isc_taskmgr_t **managerp); void isc__taskmgr_destroy(isc_taskmgr_t **managerp); void isc_taskmgr_setexcltask(isc_taskmgr_t *mgr0, isc_task_t *task0); isc_result_t isc_taskmgr_excltask(isc_taskmgr_t *mgr0, isc_task_t **taskp); isc_result_t isc__task_beginexclusive(isc_task_t *task); void isc__task_endexclusive(isc_task_t *task0); void isc__task_setprivilege(isc_task_t *task0, isc_boolean_t priv); isc_boolean_t isc__task_privilege(isc_task_t *task0); void isc__taskmgr_setmode(isc_taskmgr_t *manager0, isc_taskmgrmode_t mode); isc_taskmgrmode_t isc__taskmgr_mode(isc_taskmgr_t *manager0); static inline isc_boolean_t empty_readyq(isc__taskmgr_t *manager); static inline isc__task_t * pop_readyq(isc__taskmgr_t *manager); static inline void push_readyq(isc__taskmgr_t *manager, isc__task_t *task); static struct isc__taskmethods { isc_taskmethods_t methods; /*% * The following are defined just for avoiding unused static functions. */ void *purgeevent, *unsendrange, *getname, *gettag, *getcurrenttime; } taskmethods = { { isc__task_attach, isc__task_detach, isc__task_destroy, isc__task_send, isc__task_sendanddetach, isc__task_unsend, isc__task_onshutdown, isc__task_shutdown, isc__task_setname, isc__task_purge, isc__task_purgerange, isc__task_beginexclusive, isc__task_endexclusive, isc__task_setprivilege, isc__task_privilege }, (void *)isc_task_purgeevent, (void *)isc__task_unsendrange, (void *)isc__task_getname, (void *)isc__task_gettag, (void *)isc__task_getcurrenttime }; static isc_taskmgrmethods_t taskmgrmethods = { isc__taskmgr_destroy, isc__taskmgr_setmode, isc__taskmgr_mode, isc__task_create, isc_taskmgr_setexcltask, isc_taskmgr_excltask }; /*** *** Tasks. ***/ static void task_finished(isc__task_t *task) { isc__taskmgr_t *manager = task->manager; REQUIRE(EMPTY(task->events)); REQUIRE(task->nevents == 0); REQUIRE(EMPTY(task->on_shutdown)); REQUIRE(task->references == 0); REQUIRE(task->state == task_state_done); XTRACE("task_finished"); LOCK(&manager->lock); UNLINK(manager->tasks, task, link); #ifdef USE_WORKER_THREADS if (FINISHED(manager)) { /* * All tasks have completed and the * task manager is exiting. Wake up * any idle worker threads so they * can exit. */ BROADCAST(&manager->work_available); } #endif /* USE_WORKER_THREADS */ UNLOCK(&manager->lock); DESTROYLOCK(&task->lock); task->common.impmagic = 0; task->common.magic = 0; isc_mem_put(manager->mctx, task, sizeof(*task)); } isc_result_t isc__task_create(isc_taskmgr_t *manager0, unsigned int quantum, isc_task_t **taskp) { isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0; isc__task_t *task; isc_boolean_t exiting; isc_result_t result; REQUIRE(VALID_MANAGER(manager)); REQUIRE(taskp != NULL && *taskp == NULL); task = isc_mem_get(manager->mctx, sizeof(*task)); if (task == NULL) return (ISC_R_NOMEMORY); XTRACE("isc_task_create"); task->manager = manager; result = isc_mutex_init(&task->lock); if (result != ISC_R_SUCCESS) { isc_mem_put(manager->mctx, task, sizeof(*task)); return (result); } task->state = task_state_idle; task->references = 1; INIT_LIST(task->events); INIT_LIST(task->on_shutdown); task->nevents = 0; task->quantum = quantum; task->flags = 0; task->now = 0; memset(task->name, 0, sizeof(task->name)); task->tag = NULL; INIT_LINK(task, link); INIT_LINK(task, ready_link); INIT_LINK(task, ready_priority_link); exiting = ISC_FALSE; LOCK(&manager->lock); if (!manager->exiting) { if (task->quantum == 0) task->quantum = manager->default_quantum; APPEND(manager->tasks, task, link); } else exiting = ISC_TRUE; UNLOCK(&manager->lock); if (exiting) { DESTROYLOCK(&task->lock); isc_mem_put(manager->mctx, task, sizeof(*task)); return (ISC_R_SHUTTINGDOWN); } task->common.methods = (isc_taskmethods_t *)&taskmethods; task->common.magic = ISCAPI_TASK_MAGIC; task->common.impmagic = TASK_MAGIC; *taskp = (isc_task_t *)task; return (ISC_R_SUCCESS); } void isc__task_attach(isc_task_t *source0, isc_task_t **targetp) { isc__task_t *source = (isc__task_t *)source0; /* * Attach *targetp to source. */ REQUIRE(VALID_TASK(source)); REQUIRE(targetp != NULL && *targetp == NULL); XTTRACE(source, "isc_task_attach"); LOCK(&source->lock); source->references++; UNLOCK(&source->lock); *targetp = (isc_task_t *)source; } static inline isc_boolean_t task_shutdown(isc__task_t *task) { isc_boolean_t was_idle = ISC_FALSE; isc_event_t *event, *prev; /* * Caller must be holding the task's lock. */ XTRACE("task_shutdown"); if (! TASK_SHUTTINGDOWN(task)) { XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_SHUTTINGDOWN, "shutting down")); task->flags |= TASK_F_SHUTTINGDOWN; if (task->state == task_state_idle) { INSIST(EMPTY(task->events)); task->state = task_state_ready; was_idle = ISC_TRUE; } INSIST(task->state == task_state_ready || task->state == task_state_running); /* * Note that we post shutdown events LIFO. */ for (event = TAIL(task->on_shutdown); event != NULL; event = prev) { prev = PREV(event, ev_link); DEQUEUE(task->on_shutdown, event, ev_link); ENQUEUE(task->events, event, ev_link); task->nevents++; } } return (was_idle); } /* * Moves a task onto the appropriate run queue. * * Caller must NOT hold manager lock. */ static inline void task_ready(isc__task_t *task) { isc__taskmgr_t *manager = task->manager; #ifdef USE_WORKER_THREADS isc_boolean_t has_privilege = isc__task_privilege((isc_task_t *) task); #endif /* USE_WORKER_THREADS */ REQUIRE(VALID_MANAGER(manager)); REQUIRE(task->state == task_state_ready); XTRACE("task_ready"); LOCK(&manager->lock); push_readyq(manager, task); #ifdef USE_WORKER_THREADS if (manager->mode == isc_taskmgrmode_normal || has_privilege) SIGNAL(&manager->work_available); #endif /* USE_WORKER_THREADS */ UNLOCK(&manager->lock); } static inline isc_boolean_t task_detach(isc__task_t *task) { /* * Caller must be holding the task lock. */ REQUIRE(task->references > 0); XTRACE("detach"); task->references--; if (task->references == 0 && task->state == task_state_idle) { INSIST(EMPTY(task->events)); /* * There are no references to this task, and no * pending events. We could try to optimize and * either initiate shutdown or clean up the task, * depending on its state, but it's easier to just * make the task ready and allow run() or the event * loop to deal with shutting down and termination. */ task->state = task_state_ready; return (ISC_TRUE); } return (ISC_FALSE); } void isc__task_detach(isc_task_t **taskp) { isc__task_t *task; isc_boolean_t was_idle; /* * Detach *taskp from its task. */ REQUIRE(taskp != NULL); task = (isc__task_t *)*taskp; REQUIRE(VALID_TASK(task)); XTRACE("isc_task_detach"); LOCK(&task->lock); was_idle = task_detach(task); UNLOCK(&task->lock); if (was_idle) task_ready(task); *taskp = NULL; } static inline isc_boolean_t task_send(isc__task_t *task, isc_event_t **eventp) { isc_boolean_t was_idle = ISC_FALSE; isc_event_t *event; /* * Caller must be holding the task lock. */ REQUIRE(eventp != NULL); event = *eventp; REQUIRE(event != NULL); REQUIRE(event->ev_type > 0); REQUIRE(task->state != task_state_done); XTRACE("task_send"); if (task->state == task_state_idle) { was_idle = ISC_TRUE; INSIST(EMPTY(task->events)); task->state = task_state_ready; } INSIST(task->state == task_state_ready || task->state == task_state_running); ENQUEUE(task->events, event, ev_link); task->nevents++; *eventp = NULL; return (was_idle); } void isc__task_send(isc_task_t *task0, isc_event_t **eventp) { isc__task_t *task = (isc__task_t *)task0; isc_boolean_t was_idle; /* * Send '*event' to 'task'. */ REQUIRE(VALID_TASK(task)); XTRACE("isc_task_send"); /* * We're trying hard to hold locks for as short a time as possible. * We're also trying to hold as few locks as possible. This is why * some processing is deferred until after the lock is released. */ LOCK(&task->lock); was_idle = task_send(task, eventp); UNLOCK(&task->lock); if (was_idle) { /* * We need to add this task to the ready queue. * * We've waited until now to do it because making a task * ready requires locking the manager. If we tried to do * this while holding the task lock, we could deadlock. * * We've changed the state to ready, so no one else will * be trying to add this task to the ready queue. The * only way to leave the ready state is by executing the * task. It thus doesn't matter if events are added, * removed, or a shutdown is started in the interval * between the time we released the task lock, and the time * we add the task to the ready queue. */ task_ready(task); } } void isc__task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp) { isc_boolean_t idle1, idle2; isc__task_t *task; /* * Send '*event' to '*taskp' and then detach '*taskp' from its * task. */ REQUIRE(taskp != NULL); task = (isc__task_t *)*taskp; REQUIRE(VALID_TASK(task)); XTRACE("isc_task_sendanddetach"); LOCK(&task->lock); idle1 = task_send(task, eventp); idle2 = task_detach(task); UNLOCK(&task->lock); /* * If idle1, then idle2 shouldn't be true as well since we're holding * the task lock, and thus the task cannot switch from ready back to * idle. */ INSIST(!(idle1 && idle2)); if (idle1 || idle2) task_ready(task); *taskp = NULL; } #define PURGE_OK(event) (((event)->ev_attributes & ISC_EVENTATTR_NOPURGE) == 0) static unsigned int dequeue_events(isc__task_t *task, void *sender, isc_eventtype_t first, isc_eventtype_t last, void *tag, isc_eventlist_t *events, isc_boolean_t purging) { isc_event_t *event, *next_event; unsigned int count = 0; REQUIRE(VALID_TASK(task)); REQUIRE(last >= first); XTRACE("dequeue_events"); /* * Events matching 'sender', whose type is >= first and <= last, and * whose tag is 'tag' will be dequeued. If 'purging', matching events * which are marked as unpurgable will not be dequeued. * * sender == NULL means "any sender", and tag == NULL means "any tag". */ LOCK(&task->lock); for (event = HEAD(task->events); event != NULL; event = next_event) { next_event = NEXT(event, ev_link); if (event->ev_type >= first && event->ev_type <= last && (sender == NULL || event->ev_sender == sender) && (tag == NULL || event->ev_tag == tag) && (!purging || PURGE_OK(event))) { DEQUEUE(task->events, event, ev_link); task->nevents--; ENQUEUE(*events, event, ev_link); count++; } } UNLOCK(&task->lock); return (count); } unsigned int isc__task_purgerange(isc_task_t *task0, void *sender, isc_eventtype_t first, isc_eventtype_t last, void *tag) { isc__task_t *task = (isc__task_t *)task0; unsigned int count; isc_eventlist_t events; isc_event_t *event, *next_event; /* * Purge events from a task's event queue. */ XTRACE("isc_task_purgerange"); ISC_LIST_INIT(events); count = dequeue_events(task, sender, first, last, tag, &events, ISC_TRUE); for (event = HEAD(events); event != NULL; event = next_event) { next_event = NEXT(event, ev_link); isc_event_free(&event); } /* * Note that purging never changes the state of the task. */ return (count); } unsigned int isc__task_purge(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag) { /* * Purge events from a task's event queue. */ XTRACE("isc_task_purge"); return (isc__task_purgerange(task, sender, type, type, tag)); } isc_boolean_t isc_task_purgeevent(isc_task_t *task0, isc_event_t *event) { isc__task_t *task = (isc__task_t *)task0; isc_event_t *curr_event, *next_event; /* * Purge 'event' from a task's event queue. * * XXXRTH: WARNING: This method may be removed before beta. */ REQUIRE(VALID_TASK(task)); /* * If 'event' is on the task's event queue, it will be purged, * unless it is marked as unpurgeable. 'event' does not have to be * on the task's event queue; in fact, it can even be an invalid * pointer. Purging only occurs if the event is actually on the task's * event queue. * * Purging never changes the state of the task. */ LOCK(&task->lock); for (curr_event = HEAD(task->events); curr_event != NULL; curr_event = next_event) { next_event = NEXT(curr_event, ev_link); if (curr_event == event && PURGE_OK(event)) { DEQUEUE(task->events, curr_event, ev_link); task->nevents--; break; } } UNLOCK(&task->lock); if (curr_event == NULL) return (ISC_FALSE); isc_event_free(&curr_event); return (ISC_TRUE); } unsigned int isc__task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first, isc_eventtype_t last, void *tag, isc_eventlist_t *events) { /* * Remove events from a task's event queue. */ XTRACE("isc_task_unsendrange"); return (dequeue_events((isc__task_t *)task, sender, first, last, tag, events, ISC_FALSE)); } unsigned int isc__task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag, isc_eventlist_t *events) { /* * Remove events from a task's event queue. */ XTRACE("isc_task_unsend"); return (dequeue_events((isc__task_t *)task, sender, type, type, tag, events, ISC_FALSE)); } isc_result_t isc__task_onshutdown(isc_task_t *task0, isc_taskaction_t action, void *arg) { isc__task_t *task = (isc__task_t *)task0; isc_boolean_t disallowed = ISC_FALSE; isc_result_t result = ISC_R_SUCCESS; isc_event_t *event; /* * Send a shutdown event with action 'action' and argument 'arg' when * 'task' is shutdown. */ REQUIRE(VALID_TASK(task)); REQUIRE(action != NULL); event = isc_event_allocate(task->manager->mctx, NULL, ISC_TASKEVENT_SHUTDOWN, action, arg, sizeof(*event)); if (event == NULL) return (ISC_R_NOMEMORY); LOCK(&task->lock); if (TASK_SHUTTINGDOWN(task)) { disallowed = ISC_TRUE; result = ISC_R_SHUTTINGDOWN; } else ENQUEUE(task->on_shutdown, event, ev_link); UNLOCK(&task->lock); if (disallowed) isc_mem_put(task->manager->mctx, event, sizeof(*event)); return (result); } void isc__task_shutdown(isc_task_t *task0) { isc__task_t *task = (isc__task_t *)task0; isc_boolean_t was_idle; /* * Shutdown 'task'. */ REQUIRE(VALID_TASK(task)); LOCK(&task->lock); was_idle = task_shutdown(task); UNLOCK(&task->lock); if (was_idle) task_ready(task); } void isc__task_destroy(isc_task_t **taskp) { /* * Destroy '*taskp'. */ REQUIRE(taskp != NULL); isc_task_shutdown(*taskp); isc_task_detach(taskp); } void isc__task_setname(isc_task_t *task0, const char *name, void *tag) { isc__task_t *task = (isc__task_t *)task0; /* * Name 'task'. */ REQUIRE(VALID_TASK(task)); LOCK(&task->lock); memset(task->name, 0, sizeof(task->name)); strncpy(task->name, name, sizeof(task->name) - 1); task->tag = tag; UNLOCK(&task->lock); } const char * isc__task_getname(isc_task_t *task0) { isc__task_t *task = (isc__task_t *)task0; REQUIRE(VALID_TASK(task)); return (task->name); } void * isc__task_gettag(isc_task_t *task0) { isc__task_t *task = (isc__task_t *)task0; REQUIRE(VALID_TASK(task)); return (task->tag); } void isc__task_getcurrenttime(isc_task_t *task0, isc_stdtime_t *t) { isc__task_t *task = (isc__task_t *)task0; REQUIRE(VALID_TASK(task)); REQUIRE(t != NULL); LOCK(&task->lock); *t = task->now; UNLOCK(&task->lock); } /*** *** Task Manager. ***/ /* * Return ISC_TRUE if the current ready list for the manager, which is * either ready_tasks or the ready_priority_tasks, depending on whether * the manager is currently in normal or privileged execution mode. * * Caller must hold the task manager lock. */ static inline isc_boolean_t empty_readyq(isc__taskmgr_t *manager) { isc__tasklist_t queue; if (manager->mode == isc_taskmgrmode_normal) queue = manager->ready_tasks; else queue = manager->ready_priority_tasks; return (ISC_TF(EMPTY(queue))); } /* * Dequeue and return a pointer to the first task on the current ready * list for the manager. * If the task is privileged, dequeue it from the other ready list * as well. * * Caller must hold the task manager lock. */ static inline isc__task_t * pop_readyq(isc__taskmgr_t *manager) { isc__task_t *task; if (manager->mode == isc_taskmgrmode_normal) task = HEAD(manager->ready_tasks); else task = HEAD(manager->ready_priority_tasks); if (task != NULL) { DEQUEUE(manager->ready_tasks, task, ready_link); if (ISC_LINK_LINKED(task, ready_priority_link)) DEQUEUE(manager->ready_priority_tasks, task, ready_priority_link); } return (task); } /* * Push 'task' onto the ready_tasks queue. If 'task' has the privilege * flag set, then also push it onto the ready_priority_tasks queue. * * Caller must hold the task manager lock. */ static inline void push_readyq(isc__taskmgr_t *manager, isc__task_t *task) { ENQUEUE(manager->ready_tasks, task, ready_link); if ((task->flags & TASK_F_PRIVILEGED) != 0) ENQUEUE(manager->ready_priority_tasks, task, ready_priority_link); manager->tasks_ready++; } static void dispatch(isc__taskmgr_t *manager) { isc__task_t *task; #ifndef USE_WORKER_THREADS unsigned int total_dispatch_count = 0; isc__tasklist_t new_ready_tasks; isc__tasklist_t new_priority_tasks; unsigned int tasks_ready = 0; #endif /* USE_WORKER_THREADS */ REQUIRE(VALID_MANAGER(manager)); /* * Again we're trying to hold the lock for as short a time as possible * and to do as little locking and unlocking as possible. * * In both while loops, the appropriate lock must be held before the * while body starts. Code which acquired the lock at the top of * the loop would be more readable, but would result in a lot of * extra locking. Compare: * * Straightforward: * * LOCK(); * ... * UNLOCK(); * while (expression) { * LOCK(); * ... * UNLOCK(); * * Unlocked part here... * * LOCK(); * ... * UNLOCK(); * } * * Note how if the loop continues we unlock and then immediately lock. * For N iterations of the loop, this code does 2N+1 locks and 2N+1 * unlocks. Also note that the lock is not held when the while * condition is tested, which may or may not be important, depending * on the expression. * * As written: * * LOCK(); * while (expression) { * ... * UNLOCK(); * * Unlocked part here... * * LOCK(); * ... * } * UNLOCK(); * * For N iterations of the loop, this code does N+1 locks and N+1 * unlocks. The while expression is always protected by the lock. */ #ifndef USE_WORKER_THREADS ISC_LIST_INIT(new_ready_tasks); ISC_LIST_INIT(new_priority_tasks); #endif LOCK(&manager->lock); while (!FINISHED(manager)) { #ifdef USE_WORKER_THREADS /* * For reasons similar to those given in the comment in * isc_task_send() above, it is safe for us to dequeue * the task while only holding the manager lock, and then * change the task to running state while only holding the * task lock. * * If a pause has been requested, don't do any work * until it's been released. */ while ((empty_readyq(manager) || manager->pause_requested || manager->exclusive_requested) && !FINISHED(manager)) { XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_WAIT, "wait")); WAIT(&manager->work_available, &manager->lock); XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TASK, ISC_MSG_AWAKE, "awake")); } #else /* USE_WORKER_THREADS */ if (total_dispatch_count >= DEFAULT_TASKMGR_QUANTUM || empty_readyq(manager)) break; #endif /* USE_WORKER_THREADS */ XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TASK, ISC_MSG_WORKING, "working")); task = pop_readyq(manager); if (task != NULL) { unsigned int dispatch_count = 0; isc_boolean_t done = ISC_FALSE; isc_boolean_t requeue = ISC_FALSE; isc_boolean_t finished = ISC_FALSE; isc_event_t *event; INSIST(VALID_TASK(task)); /* * Note we only unlock the manager lock if we actually * have a task to do. We must reacquire the manager * lock before exiting the 'if (task != NULL)' block. */ manager->tasks_ready--; manager->tasks_running++; UNLOCK(&manager->lock); LOCK(&task->lock); INSIST(task->state == task_state_ready); task->state = task_state_running; XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_RUNNING, "running")); isc_stdtime_get(&task->now); do { if (!EMPTY(task->events)) { event = HEAD(task->events); DEQUEUE(task->events, event, ev_link); task->nevents--; /* * Execute the event action. */ XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TASK, ISC_MSG_EXECUTE, "execute action")); if (event->ev_action != NULL) { UNLOCK(&task->lock); (event->ev_action)( (isc_task_t *)task, event); LOCK(&task->lock); } dispatch_count++; #ifndef USE_WORKER_THREADS total_dispatch_count++; #endif /* USE_WORKER_THREADS */ } if (task->references == 0 && EMPTY(task->events) && !TASK_SHUTTINGDOWN(task)) { isc_boolean_t was_idle; /* * There are no references and no * pending events for this task, * which means it will not become * runnable again via an external * action (such as sending an event * or detaching). * * We initiate shutdown to prevent * it from becoming a zombie. * * We do this here instead of in * the "if EMPTY(task->events)" block * below because: * * If we post no shutdown events, * we want the task to finish. * * If we did post shutdown events, * will still want the task's * quantum to be applied. */ was_idle = task_shutdown(task); INSIST(!was_idle); } if (EMPTY(task->events)) { /* * Nothing else to do for this task * right now. */ XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TASK, ISC_MSG_EMPTY, "empty")); if (task->references == 0 && TASK_SHUTTINGDOWN(task)) { /* * The task is done. */ XTRACE(isc_msgcat_get( isc_msgcat, ISC_MSGSET_TASK, ISC_MSG_DONE, "done")); finished = ISC_TRUE; task->state = task_state_done; } else task->state = task_state_idle; done = ISC_TRUE; } else if (dispatch_count >= task->quantum) { /* * Our quantum has expired, but * there is more work to be done. * We'll requeue it to the ready * queue later. * * We don't check quantum until * dispatching at least one event, * so the minimum quantum is one. */ XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TASK, ISC_MSG_QUANTUM, "quantum")); task->state = task_state_ready; requeue = ISC_TRUE; done = ISC_TRUE; } } while (!done); UNLOCK(&task->lock); if (finished) task_finished(task); LOCK(&manager->lock); manager->tasks_running--; #ifdef USE_WORKER_THREADS if (manager->exclusive_requested && manager->tasks_running == 1) { SIGNAL(&manager->exclusive_granted); } else if (manager->pause_requested && manager->tasks_running == 0) { SIGNAL(&manager->paused); } #endif /* USE_WORKER_THREADS */ if (requeue) { /* * We know we're awake, so we don't have * to wakeup any sleeping threads if the * ready queue is empty before we requeue. * * A possible optimization if the queue is * empty is to 'goto' the 'if (task != NULL)' * block, avoiding the ENQUEUE of the task * and the subsequent immediate DEQUEUE * (since it is the only executable task). * We don't do this because then we'd be * skipping the exit_requested check. The * cost of ENQUEUE is low anyway, especially * when you consider that we'd have to do * an extra EMPTY check to see if we could * do the optimization. If the ready queue * were usually nonempty, the 'optimization' * might even hurt rather than help. */ #ifdef USE_WORKER_THREADS push_readyq(manager, task); #else ENQUEUE(new_ready_tasks, task, ready_link); if ((task->flags & TASK_F_PRIVILEGED) != 0) ENQUEUE(new_priority_tasks, task, ready_priority_link); tasks_ready++; #endif } } #ifdef USE_WORKER_THREADS /* * If we are in privileged execution mode and there are no * tasks remaining on the current ready queue, then * we're stuck. Automatically drop privileges at that * point and continue with the regular ready queue. */ if (manager->tasks_running == 0 && empty_readyq(manager)) { manager->mode = isc_taskmgrmode_normal; if (!empty_readyq(manager)) BROADCAST(&manager->work_available); } #endif } #ifndef USE_WORKER_THREADS ISC_LIST_APPENDLIST(manager->ready_tasks, new_ready_tasks, ready_link); ISC_LIST_APPENDLIST(manager->ready_priority_tasks, new_priority_tasks, ready_priority_link); manager->tasks_ready += tasks_ready; if (empty_readyq(manager)) manager->mode = isc_taskmgrmode_normal; #endif UNLOCK(&manager->lock); } #ifdef USE_WORKER_THREADS static isc_threadresult_t #ifdef _WIN32 WINAPI #endif run(void *uap) { isc__taskmgr_t *manager = uap; XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_STARTING, "starting")); dispatch(manager); XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_EXITING, "exiting")); #ifdef OPENSSL_LEAKS ERR_remove_state(0); #endif return ((isc_threadresult_t)0); } #endif /* USE_WORKER_THREADS */ static void manager_free(isc__taskmgr_t *manager) { isc_mem_t *mctx; #ifdef USE_WORKER_THREADS (void)isc_condition_destroy(&manager->exclusive_granted); (void)isc_condition_destroy(&manager->work_available); (void)isc_condition_destroy(&manager->paused); isc_mem_free(manager->mctx, manager->threads); #endif /* USE_WORKER_THREADS */ DESTROYLOCK(&manager->lock); DESTROYLOCK(&manager->excl_lock); manager->common.impmagic = 0; manager->common.magic = 0; mctx = manager->mctx; isc_mem_put(mctx, manager, sizeof(*manager)); isc_mem_detach(&mctx); #ifdef USE_SHARED_MANAGER taskmgr = NULL; #endif /* USE_SHARED_MANAGER */ } isc_result_t isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers, unsigned int default_quantum, isc_taskmgr_t **managerp) { isc_result_t result; unsigned int i, started = 0; isc__taskmgr_t *manager; /* * Create a new task manager. */ REQUIRE(workers > 0); REQUIRE(managerp != NULL && *managerp == NULL); #ifndef USE_WORKER_THREADS UNUSED(i); UNUSED(started); #endif #ifdef USE_SHARED_MANAGER if (taskmgr != NULL) { if (taskmgr->refs == 0) return (ISC_R_SHUTTINGDOWN); taskmgr->refs++; *managerp = (isc_taskmgr_t *)taskmgr; return (ISC_R_SUCCESS); } #endif /* USE_SHARED_MANAGER */ manager = isc_mem_get(mctx, sizeof(*manager)); if (manager == NULL) return (ISC_R_NOMEMORY); manager->common.methods = &taskmgrmethods; manager->common.impmagic = TASK_MANAGER_MAGIC; manager->common.magic = ISCAPI_TASKMGR_MAGIC; manager->mode = isc_taskmgrmode_normal; manager->mctx = NULL; result = isc_mutex_init(&manager->lock); if (result != ISC_R_SUCCESS) goto cleanup_mgr; result = isc_mutex_init(&manager->excl_lock); if (result != ISC_R_SUCCESS) { DESTROYLOCK(&manager->lock); goto cleanup_mgr; } #ifdef USE_WORKER_THREADS manager->workers = 0; manager->threads = isc_mem_allocate(mctx, workers * sizeof(isc_thread_t)); if (manager->threads == NULL) { result = ISC_R_NOMEMORY; goto cleanup_lock; } if (isc_condition_init(&manager->work_available) != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_condition_init() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); result = ISC_R_UNEXPECTED; goto cleanup_threads; } if (isc_condition_init(&manager->exclusive_granted) != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_condition_init() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); result = ISC_R_UNEXPECTED; goto cleanup_workavailable; } if (isc_condition_init(&manager->paused) != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_condition_init() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); result = ISC_R_UNEXPECTED; goto cleanup_exclusivegranted; } #endif /* USE_WORKER_THREADS */ if (default_quantum == 0) default_quantum = DEFAULT_DEFAULT_QUANTUM; manager->default_quantum = default_quantum; INIT_LIST(manager->tasks); INIT_LIST(manager->ready_tasks); INIT_LIST(manager->ready_priority_tasks); manager->tasks_running = 0; manager->tasks_ready = 0; manager->exclusive_requested = ISC_FALSE; manager->pause_requested = ISC_FALSE; manager->exiting = ISC_FALSE; manager->excl = NULL; isc_mem_attach(mctx, &manager->mctx); #ifdef USE_WORKER_THREADS LOCK(&manager->lock); /* * Start workers. */ for (i = 0; i < workers; i++) { if (isc_thread_create(run, manager, &manager->threads[manager->workers]) == ISC_R_SUCCESS) { manager->workers++; started++; } } UNLOCK(&manager->lock); if (started == 0) { manager_free(manager); return (ISC_R_NOTHREADS); } isc_thread_setconcurrency(workers); #endif /* USE_WORKER_THREADS */ #ifdef USE_SHARED_MANAGER manager->refs = 1; taskmgr = manager; #endif /* USE_SHARED_MANAGER */ *managerp = (isc_taskmgr_t *)manager; return (ISC_R_SUCCESS); #ifdef USE_WORKER_THREADS cleanup_exclusivegranted: (void)isc_condition_destroy(&manager->exclusive_granted); cleanup_workavailable: (void)isc_condition_destroy(&manager->work_available); cleanup_threads: isc_mem_free(mctx, manager->threads); cleanup_lock: DESTROYLOCK(&manager->lock); #endif cleanup_mgr: isc_mem_put(mctx, manager, sizeof(*manager)); return (result); } void isc__taskmgr_destroy(isc_taskmgr_t **managerp) { isc__taskmgr_t *manager; isc__task_t *task; unsigned int i; /* * Destroy '*managerp'. */ REQUIRE(managerp != NULL); manager = (isc__taskmgr_t *)*managerp; REQUIRE(VALID_MANAGER(manager)); #ifndef USE_WORKER_THREADS UNUSED(i); #endif /* USE_WORKER_THREADS */ #ifdef USE_SHARED_MANAGER manager->refs--; if (manager->refs > 0) { *managerp = NULL; return; } #endif XTHREADTRACE("isc_taskmgr_destroy"); /* * Only one non-worker thread may ever call this routine. * If a worker thread wants to initiate shutdown of the * task manager, it should ask some non-worker thread to call * isc_taskmgr_destroy(), e.g. by signalling a condition variable * that the startup thread is sleeping on. */ /* * Detach the exclusive task before acquiring the manager lock */ LOCK(&manager->excl_lock); if (manager->excl != NULL) isc__task_detach((isc_task_t **) &manager->excl); UNLOCK(&manager->excl_lock); /* * Unlike elsewhere, we're going to hold this lock a long time. * We need to do so, because otherwise the list of tasks could * change while we were traversing it. * * This is also the only function where we will hold both the * task manager lock and a task lock at the same time. */ LOCK(&manager->lock); /* * Make sure we only get called once. */ INSIST(!manager->exiting); manager->exiting = ISC_TRUE; /* * If privileged mode was on, turn it off. */ manager->mode = isc_taskmgrmode_normal; /* * Post shutdown event(s) to every task (if they haven't already been * posted). */ for (task = HEAD(manager->tasks); task != NULL; task = NEXT(task, link)) { LOCK(&task->lock); if (task_shutdown(task)) push_readyq(manager, task); UNLOCK(&task->lock); } #ifdef USE_WORKER_THREADS /* * Wake up any sleeping workers. This ensures we get work done if * there's work left to do, and if there are already no tasks left * it will cause the workers to see manager->exiting. */ BROADCAST(&manager->work_available); UNLOCK(&manager->lock); /* * Wait for all the worker threads to exit. */ for (i = 0; i < manager->workers; i++) (void)isc_thread_join(manager->threads[i], NULL); #else /* USE_WORKER_THREADS */ /* * Dispatch the shutdown events. */ UNLOCK(&manager->lock); while (isc__taskmgr_ready((isc_taskmgr_t *)manager)) (void)isc__taskmgr_dispatch((isc_taskmgr_t *)manager); if (!ISC_LIST_EMPTY(manager->tasks)) isc_mem_printallactive(stderr); INSIST(ISC_LIST_EMPTY(manager->tasks)); #ifdef USE_SHARED_MANAGER taskmgr = NULL; #endif #endif /* USE_WORKER_THREADS */ manager_free(manager); *managerp = NULL; } void isc__taskmgr_setmode(isc_taskmgr_t *manager0, isc_taskmgrmode_t mode) { isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0; LOCK(&manager->lock); manager->mode = mode; UNLOCK(&manager->lock); } isc_taskmgrmode_t isc__taskmgr_mode(isc_taskmgr_t *manager0) { isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0; isc_taskmgrmode_t mode; LOCK(&manager->lock); mode = manager->mode; UNLOCK(&manager->lock); return (mode); } #ifndef USE_WORKER_THREADS isc_boolean_t isc__taskmgr_ready(isc_taskmgr_t *manager0) { isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0; isc_boolean_t is_ready; #ifdef USE_SHARED_MANAGER if (manager == NULL) manager = taskmgr; #endif if (manager == NULL) return (ISC_FALSE); LOCK(&manager->lock); is_ready = !empty_readyq(manager); UNLOCK(&manager->lock); return (is_ready); } isc_result_t isc__taskmgr_dispatch(isc_taskmgr_t *manager0) { isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0; #ifdef USE_SHARED_MANAGER if (manager == NULL) manager = taskmgr; #endif if (manager == NULL) return (ISC_R_NOTFOUND); dispatch(manager); return (ISC_R_SUCCESS); } #else void isc__taskmgr_pause(isc_taskmgr_t *manager0) { isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0; LOCK(&manager->lock); while (manager->tasks_running > 0) { WAIT(&manager->paused, &manager->lock); } manager->pause_requested = ISC_TRUE; UNLOCK(&manager->lock); } void isc__taskmgr_resume(isc_taskmgr_t *manager0) { isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0; LOCK(&manager->lock); if (manager->pause_requested) { manager->pause_requested = ISC_FALSE; BROADCAST(&manager->work_available); } UNLOCK(&manager->lock); } #endif /* USE_WORKER_THREADS */ void isc_taskmgr_setexcltask(isc_taskmgr_t *mgr0, isc_task_t *task0) { isc__taskmgr_t *mgr = (isc__taskmgr_t *) mgr0; isc__task_t *task = (isc__task_t *) task0; REQUIRE(VALID_MANAGER(mgr)); REQUIRE(VALID_TASK(task)); LOCK(&mgr->excl_lock); if (mgr->excl != NULL) isc__task_detach((isc_task_t **) &mgr->excl); isc__task_attach(task0, (isc_task_t **) &mgr->excl); UNLOCK(&mgr->excl_lock); } isc_result_t isc_taskmgr_excltask(isc_taskmgr_t *mgr0, isc_task_t **taskp) { isc__taskmgr_t *mgr = (isc__taskmgr_t *) mgr0; isc_result_t result = ISC_R_SUCCESS; REQUIRE(VALID_MANAGER(mgr)); REQUIRE(taskp != NULL && *taskp == NULL); LOCK(&mgr->excl_lock); if (mgr->excl != NULL) isc__task_attach((isc_task_t *) mgr->excl, taskp); else result = ISC_R_NOTFOUND; UNLOCK(&mgr->excl_lock); return (result); } isc_result_t isc__task_beginexclusive(isc_task_t *task0) { #ifdef USE_WORKER_THREADS isc__task_t *task = (isc__task_t *)task0; isc__taskmgr_t *manager = task->manager; REQUIRE(task->state == task_state_running); /* XXX: Require task == manager->excl? */ LOCK(&manager->lock); if (manager->exclusive_requested) { UNLOCK(&manager->lock); return (ISC_R_LOCKBUSY); } manager->exclusive_requested = ISC_TRUE; while (manager->tasks_running > 1) { WAIT(&manager->exclusive_granted, &manager->lock); } UNLOCK(&manager->lock); #else UNUSED(task0); #endif return (ISC_R_SUCCESS); } void isc__task_endexclusive(isc_task_t *task0) { #ifdef USE_WORKER_THREADS isc__task_t *task = (isc__task_t *)task0; isc__taskmgr_t *manager = task->manager; REQUIRE(task->state == task_state_running); LOCK(&manager->lock); REQUIRE(manager->exclusive_requested); manager->exclusive_requested = ISC_FALSE; BROADCAST(&manager->work_available); UNLOCK(&manager->lock); #else UNUSED(task0); #endif } void isc__task_setprivilege(isc_task_t *task0, isc_boolean_t priv) { isc__task_t *task = (isc__task_t *)task0; isc__taskmgr_t *manager = task->manager; isc_boolean_t oldpriv; LOCK(&task->lock); oldpriv = ISC_TF((task->flags & TASK_F_PRIVILEGED) != 0); if (priv) task->flags |= TASK_F_PRIVILEGED; else task->flags &= ~TASK_F_PRIVILEGED; UNLOCK(&task->lock); if (priv == oldpriv) return; LOCK(&manager->lock); if (priv && ISC_LINK_LINKED(task, ready_link)) ENQUEUE(manager->ready_priority_tasks, task, ready_priority_link); else if (!priv && ISC_LINK_LINKED(task, ready_priority_link)) DEQUEUE(manager->ready_priority_tasks, task, ready_priority_link); UNLOCK(&manager->lock); } isc_boolean_t isc__task_privilege(isc_task_t *task0) { isc__task_t *task = (isc__task_t *)task0; isc_boolean_t priv; LOCK(&task->lock); priv = ISC_TF((task->flags & TASK_F_PRIVILEGED) != 0); UNLOCK(&task->lock); return (priv); } isc_result_t isc__task_register(void) { return (isc_task_register(isc__taskmgr_create)); } isc_boolean_t isc_task_exiting(isc_task_t *t) { isc__task_t *task = (isc__task_t *)t; REQUIRE(VALID_TASK(task)); return (TASK_SHUTTINGDOWN(task)); } #ifdef HAVE_LIBXML2 #define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0) int isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) { isc__taskmgr_t *mgr = (isc__taskmgr_t *)mgr0; isc__task_t *task = NULL; int xmlrc; LOCK(&mgr->lock); /* * Write out the thread-model, and some details about each depending * on which type is enabled. */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "thread-model")); #ifdef ISC_PLATFORM_USETHREADS TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "type")); TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "threaded")); TRY0(xmlTextWriterEndElement(writer)); /* type */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "worker-threads")); TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->workers)); TRY0(xmlTextWriterEndElement(writer)); /* worker-threads */ #else /* ISC_PLATFORM_USETHREADS */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "type")); TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "non-threaded")); TRY0(xmlTextWriterEndElement(writer)); /* type */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references")); TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->refs)); TRY0(xmlTextWriterEndElement(writer)); /* references */ #endif /* ISC_PLATFORM_USETHREADS */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "default-quantum")); TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->default_quantum)); TRY0(xmlTextWriterEndElement(writer)); /* default-quantum */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-running")); TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->tasks_running)); TRY0(xmlTextWriterEndElement(writer)); /* tasks-running */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-ready")); TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->tasks_ready)); TRY0(xmlTextWriterEndElement(writer)); /* tasks-ready */ TRY0(xmlTextWriterEndElement(writer)); /* thread-model */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks")); task = ISC_LIST_HEAD(mgr->tasks); while (task != NULL) { LOCK(&task->lock); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "task")); if (task->name[0] != 0) { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); TRY0(xmlTextWriterWriteFormatString(writer, "%s", task->name)); TRY0(xmlTextWriterEndElement(writer)); /* name */ } TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references")); TRY0(xmlTextWriterWriteFormatString(writer, "%d", task->references)); TRY0(xmlTextWriterEndElement(writer)); /* references */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "id")); TRY0(xmlTextWriterWriteFormatString(writer, "%p", task)); TRY0(xmlTextWriterEndElement(writer)); /* id */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "state")); TRY0(xmlTextWriterWriteFormatString(writer, "%s", statenames[task->state])); TRY0(xmlTextWriterEndElement(writer)); /* state */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "quantum")); TRY0(xmlTextWriterWriteFormatString(writer, "%d", task->quantum)); TRY0(xmlTextWriterEndElement(writer)); /* quantum */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "events")); TRY0(xmlTextWriterWriteFormatString(writer, "%d", task->nevents)); TRY0(xmlTextWriterEndElement(writer)); /* events */ TRY0(xmlTextWriterEndElement(writer)); UNLOCK(&task->lock); task = ISC_LIST_NEXT(task, link); } TRY0(xmlTextWriterEndElement(writer)); /* tasks */ error: if (task != NULL) UNLOCK(&task->lock); UNLOCK(&mgr->lock); return (xmlrc); } #endif /* HAVE_LIBXML2 */ #ifdef HAVE_JSON #define CHECKMEM(m) do { \ if (m == NULL) { \ result = ISC_R_NOMEMORY;\ goto error;\ } \ } while(0) isc_result_t isc_taskmgr_renderjson(isc_taskmgr_t *mgr0, json_object *tasks) { isc_result_t result = ISC_R_SUCCESS; isc__taskmgr_t *mgr = (isc__taskmgr_t *)mgr0; isc__task_t *task = NULL; json_object *obj = NULL, *array = NULL, *taskobj = NULL; LOCK(&mgr->lock); /* * Write out the thread-model, and some details about each depending * on which type is enabled. */ #ifdef ISC_PLATFORM_USETHREADS obj = json_object_new_string("threaded"); CHECKMEM(obj); json_object_object_add(tasks, "thread-model", obj); obj = json_object_new_int(mgr->workers); CHECKMEM(obj); json_object_object_add(tasks, "worker-threads", obj); #else /* ISC_PLATFORM_USETHREADS */ obj = json_object_new_string("non-threaded"); CHECKMEM(obj); json_object_object_add(tasks, "thread-model", obj); obj = json_object_new_int(mgr->refs); CHECKMEM(obj); json_object_object_add(tasks, "references", obj); #endif /* ISC_PLATFORM_USETHREADS */ obj = json_object_new_int(mgr->default_quantum); CHECKMEM(obj); json_object_object_add(tasks, "default-quantum", obj); obj = json_object_new_int(mgr->tasks_running); CHECKMEM(obj); json_object_object_add(tasks, "tasks-running", obj); obj = json_object_new_int(mgr->tasks_ready); CHECKMEM(obj); json_object_object_add(tasks, "tasks-ready", obj); array = json_object_new_array(); CHECKMEM(array); for (task = ISC_LIST_HEAD(mgr->tasks); task != NULL; task = ISC_LIST_NEXT(task, link)) { char buf[255]; LOCK(&task->lock); taskobj = json_object_new_object(); CHECKMEM(taskobj); json_object_array_add(array, taskobj); sprintf(buf, "%p", task); obj = json_object_new_string(buf); CHECKMEM(obj); json_object_object_add(taskobj, "id", obj); if (task->name[0] != 0) { obj = json_object_new_string(task->name); CHECKMEM(obj); json_object_object_add(taskobj, "name", obj); } obj = json_object_new_int(task->references); CHECKMEM(obj); json_object_object_add(taskobj, "references", obj); obj = json_object_new_string(statenames[task->state]); CHECKMEM(obj); json_object_object_add(taskobj, "state", obj); obj = json_object_new_int(task->quantum); CHECKMEM(obj); json_object_object_add(taskobj, "quantum", obj); obj = json_object_new_int(task->nevents); CHECKMEM(obj); json_object_object_add(taskobj, "events", obj); UNLOCK(&task->lock); } json_object_object_add(tasks, "tasks", array); array = NULL; result = ISC_R_SUCCESS; error: if (array != NULL) json_object_put(array); if (task != NULL) UNLOCK(&task->lock); UNLOCK(&mgr->lock); return (result); } #endif static isc_mutex_t createlock; static isc_once_t once = ISC_ONCE_INIT; static isc_taskmgrcreatefunc_t taskmgr_createfunc = NULL; static void initialize(void) { RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS); } isc_result_t isc_task_register(isc_taskmgrcreatefunc_t createfunc) { isc_result_t result = ISC_R_SUCCESS; RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); LOCK(&createlock); if (taskmgr_createfunc == NULL) taskmgr_createfunc = createfunc; else result = ISC_R_EXISTS; UNLOCK(&createlock); return (result); } isc_result_t isc_taskmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx, unsigned int workers, unsigned int default_quantum, isc_taskmgr_t **managerp) { isc_result_t result; LOCK(&createlock); REQUIRE(taskmgr_createfunc != NULL); result = (*taskmgr_createfunc)(mctx, workers, default_quantum, managerp); UNLOCK(&createlock); if (result == ISC_R_SUCCESS) isc_appctx_settaskmgr(actx, *managerp); return (result); } isc_result_t isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers, unsigned int default_quantum, isc_taskmgr_t **managerp) { isc_result_t result; if (isc_bind9) return (isc__taskmgr_create(mctx, workers, default_quantum, managerp)); LOCK(&createlock); REQUIRE(taskmgr_createfunc != NULL); result = (*taskmgr_createfunc)(mctx, workers, default_quantum, managerp); UNLOCK(&createlock); return (result); } void isc_taskmgr_destroy(isc_taskmgr_t **managerp) { REQUIRE(managerp != NULL && ISCAPI_TASKMGR_VALID(*managerp)); if (isc_bind9) isc__taskmgr_destroy(managerp); else (*managerp)->methods->destroy(managerp); ENSURE(*managerp == NULL); } void isc_taskmgr_setmode(isc_taskmgr_t *manager, isc_taskmgrmode_t mode) { REQUIRE(ISCAPI_TASKMGR_VALID(manager)); if (isc_bind9) isc__taskmgr_setmode(manager, mode); else manager->methods->setmode(manager, mode); } isc_taskmgrmode_t isc_taskmgr_mode(isc_taskmgr_t *manager) { REQUIRE(ISCAPI_TASKMGR_VALID(manager)); if (isc_bind9) return (isc__taskmgr_mode(manager)); return (manager->methods->mode(manager)); } isc_result_t isc_task_create(isc_taskmgr_t *manager, unsigned int quantum, isc_task_t **taskp) { REQUIRE(ISCAPI_TASKMGR_VALID(manager)); REQUIRE(taskp != NULL && *taskp == NULL); if (isc_bind9) return (isc__task_create(manager, quantum, taskp)); return (manager->methods->taskcreate(manager, quantum, taskp)); } void isc_task_attach(isc_task_t *source, isc_task_t **targetp) { REQUIRE(ISCAPI_TASK_VALID(source)); REQUIRE(targetp != NULL && *targetp == NULL); if (isc_bind9) isc__task_attach(source, targetp); else source->methods->attach(source, targetp); ENSURE(*targetp == source); } void isc_task_detach(isc_task_t **taskp) { REQUIRE(taskp != NULL && ISCAPI_TASK_VALID(*taskp)); if (isc_bind9) isc__task_detach(taskp); else (*taskp)->methods->detach(taskp); ENSURE(*taskp == NULL); } void isc_task_send(isc_task_t *task, isc_event_t **eventp) { REQUIRE(ISCAPI_TASK_VALID(task)); REQUIRE(eventp != NULL && *eventp != NULL); if (isc_bind9) isc__task_send(task, eventp); else { task->methods->send(task, eventp); ENSURE(*eventp == NULL); } } void isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp) { REQUIRE(taskp != NULL && ISCAPI_TASK_VALID(*taskp)); REQUIRE(eventp != NULL && *eventp != NULL); if (isc_bind9) isc__task_sendanddetach(taskp, eventp); else { (*taskp)->methods->sendanddetach(taskp, eventp); ENSURE(*eventp == NULL); } ENSURE(*taskp == NULL); } unsigned int isc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag, isc_eventlist_t *events) { REQUIRE(ISCAPI_TASK_VALID(task)); if (isc_bind9) return (isc__task_unsend(task, sender, type, tag, events)); return (task->methods->unsend(task, sender, type, tag, events)); } isc_result_t isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action, void *arg) { REQUIRE(ISCAPI_TASK_VALID(task)); if (isc_bind9) return (isc__task_onshutdown(task, action, arg)); return (task->methods->onshutdown(task, action, arg)); } void isc_task_shutdown(isc_task_t *task) { REQUIRE(ISCAPI_TASK_VALID(task)); if (isc_bind9) isc__task_shutdown(task); else task->methods->shutdown(task); } void isc_task_destroy(isc_task_t **taskp) { if (!isc_bind9) return; isc__task_destroy(taskp); } void isc_task_setname(isc_task_t *task, const char *name, void *tag) { REQUIRE(ISCAPI_TASK_VALID(task)); if (isc_bind9) isc__task_setname(task, name, tag); else task->methods->setname(task, name, tag); } unsigned int isc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag) { REQUIRE(ISCAPI_TASK_VALID(task)); if (isc_bind9) return (isc__task_purge(task, sender, type, tag)); return (task->methods->purgeevents(task, sender, type, tag)); } isc_result_t isc_task_beginexclusive(isc_task_t *task) { REQUIRE(ISCAPI_TASK_VALID(task)); if (isc_bind9) return (isc__task_beginexclusive(task)); return (task->methods->beginexclusive(task)); } void isc_task_endexclusive(isc_task_t *task) { REQUIRE(ISCAPI_TASK_VALID(task)); if (isc_bind9) isc__task_endexclusive(task); else task->methods->endexclusive(task); } void isc_task_setprivilege(isc_task_t *task, isc_boolean_t priv) { REQUIRE(ISCAPI_TASK_VALID(task)); if (isc_bind9) isc__task_setprivilege(task, priv); else task->methods->setprivilege(task, priv); } isc_boolean_t isc_task_privilege(isc_task_t *task) { REQUIRE(ISCAPI_TASK_VALID(task)); if (isc_bind9) return (isc__task_privilege(task)); return (task->methods->privilege(task)); } void isc_task_getcurrenttime(isc_task_t *task, isc_stdtime_t *t) { if (!isc_bind9) return; isc__task_getcurrenttime(task, t); } /*% * This is necessary for libisc's internal timer implementation. Other * implementation might skip implementing this. */ unsigned int isc_task_purgerange(isc_task_t *task, void *sender, isc_eventtype_t first, isc_eventtype_t last, void *tag) { REQUIRE(ISCAPI_TASK_VALID(task)); if (isc_bind9) return (isc__task_purgerange(task, sender, first, last, tag)); return (task->methods->purgerange(task, sender, first, last, tag)); } bind9-9.10.3.dfsg.P4/lib/isc/error.c0000644000470500017500000000570012664710322016214 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: error.c,v 1.21 2007/06/19 23:47:17 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include /*% Default unexpected callback. */ static void default_unexpected_callback(const char *, int, const char *, va_list) ISC_FORMAT_PRINTF(3, 0); /*% Default fatal callback. */ static void default_fatal_callback(const char *, int, const char *, va_list) ISC_FORMAT_PRINTF(3, 0); /*% unexpected_callback */ static isc_errorcallback_t unexpected_callback = default_unexpected_callback; static isc_errorcallback_t fatal_callback = default_fatal_callback; void isc_error_setunexpected(isc_errorcallback_t cb) { if (cb == NULL) unexpected_callback = default_unexpected_callback; else unexpected_callback = cb; } void isc_error_setfatal(isc_errorcallback_t cb) { if (cb == NULL) fatal_callback = default_fatal_callback; else fatal_callback = cb; } void isc_error_unexpected(const char *file, int line, const char *format, ...) { va_list args; va_start(args, format); (unexpected_callback)(file, line, format, args); va_end(args); } void isc_error_fatal(const char *file, int line, const char *format, ...) { va_list args; va_start(args, format); (fatal_callback)(file, line, format, args); va_end(args); abort(); } void isc_error_runtimecheck(const char *file, int line, const char *expression) { isc_error_fatal(file, line, "RUNTIME_CHECK(%s) %s", expression, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); } static void default_unexpected_callback(const char *file, int line, const char *format, va_list args) { fprintf(stderr, "%s:%d: ", file, line); vfprintf(stderr, format, args); fprintf(stderr, "\n"); fflush(stderr); } static void default_fatal_callback(const char *file, int line, const char *format, va_list args) { fprintf(stderr, "%s:%d: %s: ", file, line, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FATALERROR, "fatal error")); vfprintf(stderr, format, args); fprintf(stderr, "\n"); fflush(stderr); } bind9-9.10.3.dfsg.P4/lib/isc/version.c0000644000470500017500000000216512664710322016552 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: version.c,v 1.15 2007/06/19 23:47:17 tbox Exp $ */ /*! \file */ #include const char isc_version[] = VERSION; const unsigned int isc_libinterface = LIBINTERFACE; const unsigned int isc_librevision = LIBREVISION; const unsigned int isc_libage = LIBAGE; bind9-9.10.3.dfsg.P4/lib/isc/nls/0002755000470500017500000000000012672612753015523 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/nls/Makefile.in0000644000470500017500000000224112664710322017555 0ustar lamontlamont# Copyright (C) 2004, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1999-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.17 2009/12/05 23:31:41 each Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ CINCLUDES = -I../unix/include \ -I${srcdir}/../unix/include \ -I../include \ -I${srcdir}/../include CDEFINES = CWARNINGS = OBJS = msgcat.@O@ SRCS = msgcat.c SUBDIRS = TARGETS = ${OBJS} @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/nls/msgcat.c0000644000470500017500000000603312664710322017135 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: msgcat.c,v 1.18 2007/06/19 23:47:18 tbox Exp $ */ /*! \file msgcat.c * * \author Principal Author: Bob Halley */ #include #include #include #include #include #include #ifdef HAVE_CATGETS #include /* Required for nl_catd. */ #endif /* * Implementation Notes: * * We use malloc() and free() instead of isc_mem_get() and isc_mem_put() * because we don't want to require a memory context to be specified * in order to use a message catalog. */ struct isc_msgcat { unsigned int magic; #ifdef HAVE_CATGETS nl_catd catalog; #endif }; #define MSGCAT_MAGIC ISC_MAGIC('M', 'C', 'a', 't') #define VALID_MSGCAT(m) ISC_MAGIC_VALID(m, MSGCAT_MAGIC) void isc_msgcat_open(const char *name, isc_msgcat_t **msgcatp) { isc_msgcat_t *msgcat; /* * Open a message catalog. */ REQUIRE(name != NULL); REQUIRE(msgcatp != NULL && *msgcatp == NULL); msgcat = malloc(sizeof(*msgcat)); if (msgcat == NULL) { *msgcatp = NULL; return; } #ifdef HAVE_CATGETS /* * We don't check if catopen() fails because we don't care. * If it does fail, then when we call catgets(), it will use * the default string. */ msgcat->catalog = catopen(name, 0); #endif msgcat->magic = MSGCAT_MAGIC; *msgcatp = msgcat; } void isc_msgcat_close(isc_msgcat_t **msgcatp) { isc_msgcat_t *msgcat; /* * Close a message catalog. */ REQUIRE(msgcatp != NULL); msgcat = *msgcatp; REQUIRE(VALID_MSGCAT(msgcat) || msgcat == NULL); if (msgcat != NULL) { #ifdef HAVE_CATGETS if (msgcat->catalog != (nl_catd)(-1)) (void)catclose(msgcat->catalog); #endif msgcat->magic = 0; free(msgcat); } *msgcatp = NULL; } const char * isc_msgcat_get(isc_msgcat_t *msgcat, int set, int message, const char *default_text) { /* * Get message 'message' from message set 'set' in 'msgcat'. If it * is not available, use 'default'. */ REQUIRE(VALID_MSGCAT(msgcat) || msgcat == NULL); REQUIRE(set > 0); REQUIRE(message > 0); REQUIRE(default_text != NULL); #ifdef HAVE_CATGETS if (msgcat == NULL) return (default_text); return (catgets(msgcat->catalog, set, message, default_text)); #else return (default_text); #endif } bind9-9.10.3.dfsg.P4/lib/isc/hmacsha.c0000644000470500017500000007017312664710322016475 0ustar lamontlamont/* * Copyright (C) 2005-2007, 2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* * This code implements the HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384 * and HMAC-SHA512 keyed hash algorithm described in RFC 2104 and * draft-ietf-dnsext-tsig-sha-01.txt. */ #include "config.h" #include #include #include #include #include #include #include #include #include #if PKCS11CRYPTO #include #include #endif #ifdef ISC_PLATFORM_OPENSSLHASH void isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key, unsigned int len) { #ifdef HMAC_RETURN_INT RUNTIME_CHECK(HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha1()) == 1); #else HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha1()); #endif } void isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) { HMAC_CTX_cleanup(ctx); } void isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf, unsigned int len) { #ifdef HMAC_RETURN_INT RUNTIME_CHECK(HMAC_Update(ctx, buf, (int) len) == 1); #else HMAC_Update(ctx, buf, (int) len); #endif } void isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) { unsigned char newdigest[ISC_SHA1_DIGESTLENGTH]; REQUIRE(len <= ISC_SHA1_DIGESTLENGTH); #ifdef HMAC_RETURN_INT RUNTIME_CHECK(HMAC_Final(ctx, newdigest, NULL) == 1); #else HMAC_Final(ctx, newdigest, NULL); #endif HMAC_CTX_cleanup(ctx); memmove(digest, newdigest, len); memset(newdigest, 0, sizeof(newdigest)); } void isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key, unsigned int len) { #ifdef HMAC_RETURN_INT RUNTIME_CHECK(HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha224()) == 1); #else HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha224()); #endif } void isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) { HMAC_CTX_cleanup(ctx); } void isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf, unsigned int len) { #ifdef HMAC_RETURN_INT RUNTIME_CHECK(HMAC_Update(ctx, buf, (int) len) == 1); #else HMAC_Update(ctx, buf, (int) len); #endif } void isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) { unsigned char newdigest[ISC_SHA224_DIGESTLENGTH]; REQUIRE(len <= ISC_SHA224_DIGESTLENGTH); #ifdef HMAC_RETURN_INT RUNTIME_CHECK(HMAC_Final(ctx, newdigest, NULL) == 1); #else HMAC_Final(ctx, newdigest, NULL); #endif HMAC_CTX_cleanup(ctx); memmove(digest, newdigest, len); memset(newdigest, 0, sizeof(newdigest)); } void isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key, unsigned int len) { #ifdef HMAC_RETURN_INT RUNTIME_CHECK(HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha256()) == 1); #else HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha256()); #endif } void isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) { HMAC_CTX_cleanup(ctx); } void isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf, unsigned int len) { #ifdef HMAC_RETURN_INT RUNTIME_CHECK(HMAC_Update(ctx, buf, (int) len) == 1); #else HMAC_Update(ctx, buf, (int) len); #endif } void isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) { unsigned char newdigest[ISC_SHA256_DIGESTLENGTH]; REQUIRE(len <= ISC_SHA256_DIGESTLENGTH); #ifdef HMAC_RETURN_INT RUNTIME_CHECK(HMAC_Final(ctx, newdigest, NULL) == 1); #else HMAC_Final(ctx, newdigest, NULL); #endif HMAC_CTX_cleanup(ctx); memmove(digest, newdigest, len); memset(newdigest, 0, sizeof(newdigest)); } void isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key, unsigned int len) { #ifdef HMAC_RETURN_INT RUNTIME_CHECK(HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha384()) == 1); #else HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha384()); #endif } void isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) { HMAC_CTX_cleanup(ctx); } void isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf, unsigned int len) { #ifdef HMAC_RETURN_INT RUNTIME_CHECK(HMAC_Update(ctx, buf, (int) len) == 1); #else HMAC_Update(ctx, buf, (int) len); #endif } void isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) { unsigned char newdigest[ISC_SHA384_DIGESTLENGTH]; REQUIRE(len <= ISC_SHA384_DIGESTLENGTH); #ifdef HMAC_RETURN_INT RUNTIME_CHECK(HMAC_Final(ctx, newdigest, NULL) == 1); #else HMAC_Final(ctx, newdigest, NULL); #endif HMAC_CTX_cleanup(ctx); memmove(digest, newdigest, len); memset(newdigest, 0, sizeof(newdigest)); } void isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key, unsigned int len) { #ifdef HMAC_RETURN_INT RUNTIME_CHECK(HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha512()) == 1); #else HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha512()); #endif } void isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) { HMAC_CTX_cleanup(ctx); } void isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf, unsigned int len) { #ifdef HMAC_RETURN_INT RUNTIME_CHECK(HMAC_Update(ctx, buf, (int) len) == 1); #else HMAC_Update(ctx, buf, (int) len); #endif } void isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) { unsigned char newdigest[ISC_SHA512_DIGESTLENGTH]; REQUIRE(len <= ISC_SHA512_DIGESTLENGTH); #ifdef HMAC_RETURN_INT RUNTIME_CHECK(HMAC_Final(ctx, newdigest, NULL) == 1); #else HMAC_Final(ctx, newdigest, NULL); #endif HMAC_CTX_cleanup(ctx); memmove(digest, newdigest, len); memset(newdigest, 0, sizeof(newdigest)); } #elif PKCS11CRYPTO static CK_BBOOL truevalue = TRUE; static CK_BBOOL falsevalue = FALSE; void isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key, unsigned int len) { CK_RV rv; CK_MECHANISM mech = { CKM_SHA_1_HMAC, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; CK_KEY_TYPE keyType = CKK_SHA_1_HMAC; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_VALUE, NULL, (CK_ULONG) len } }; DE_CONST(key, keyTemplate[5].pValue); RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); ctx->object = CK_INVALID_HANDLE; PK11_FATALCHECK(pkcs_C_CreateObject, (ctx->session, keyTemplate, (CK_ULONG) 6, &ctx->object)); INSIST(ctx->object != CK_INVALID_HANDLE); PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object)); } void isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) { CK_BYTE garbage[ISC_SHA1_DIGESTLENGTH]; CK_ULONG len = ISC_SHA1_DIGESTLENGTH; if (ctx->handle == NULL) return; (void) pkcs_C_SignFinal(ctx->session, garbage, &len); memset(garbage, 0, sizeof(garbage)); if (ctx->object != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx->session, ctx->object); ctx->object = CK_INVALID_HANDLE; pk11_return_session(ctx); } void isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf, unsigned int len) { CK_RV rv; CK_BYTE_PTR pPart; DE_CONST(buf, pPart); PK11_FATALCHECK(pkcs_C_SignUpdate, (ctx->session, pPart, (CK_ULONG) len)); } void isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) { CK_RV rv; CK_BYTE newdigest[ISC_SHA1_DIGESTLENGTH]; CK_ULONG psl = ISC_SHA1_DIGESTLENGTH; REQUIRE(len <= ISC_SHA1_DIGESTLENGTH); PK11_FATALCHECK(pkcs_C_SignFinal, (ctx->session, newdigest, &psl)); if (ctx->object != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx->session, ctx->object); ctx->object = CK_INVALID_HANDLE; pk11_return_session(ctx); memmove(digest, newdigest, len); memset(newdigest, 0, sizeof(newdigest)); } void isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key, unsigned int len) { CK_RV rv; CK_MECHANISM mech = { CKM_SHA224_HMAC, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; CK_KEY_TYPE keyType = CKK_SHA224_HMAC; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_VALUE, NULL, (CK_ULONG) len } }; DE_CONST(key, keyTemplate[5].pValue); RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); ctx->object = CK_INVALID_HANDLE; PK11_FATALCHECK(pkcs_C_CreateObject, (ctx->session, keyTemplate, (CK_ULONG) 6, &ctx->object)); INSIST(ctx->object != CK_INVALID_HANDLE); PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object)); } void isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) { CK_BYTE garbage[ISC_SHA224_DIGESTLENGTH]; CK_ULONG len = ISC_SHA224_DIGESTLENGTH; if (ctx->handle == NULL) return; (void) pkcs_C_SignFinal(ctx->session, garbage, &len); memset(garbage, 0, sizeof(garbage)); if (ctx->object != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx->session, ctx->object); ctx->object = CK_INVALID_HANDLE; pk11_return_session(ctx); } void isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf, unsigned int len) { CK_RV rv; CK_BYTE_PTR pPart; DE_CONST(buf, pPart); PK11_FATALCHECK(pkcs_C_SignUpdate, (ctx->session, pPart, (CK_ULONG) len)); } void isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) { CK_RV rv; CK_BYTE newdigest[ISC_SHA224_DIGESTLENGTH]; CK_ULONG psl = ISC_SHA224_DIGESTLENGTH; REQUIRE(len <= ISC_SHA224_DIGESTLENGTH); PK11_FATALCHECK(pkcs_C_SignFinal, (ctx->session, newdigest, &psl)); if (ctx->object != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx->session, ctx->object); ctx->object = CK_INVALID_HANDLE; pk11_return_session(ctx); memmove(digest, newdigest, len); memset(newdigest, 0, sizeof(newdigest)); } void isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key, unsigned int len) { CK_RV rv; CK_MECHANISM mech = { CKM_SHA256_HMAC, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; CK_KEY_TYPE keyType = CKK_SHA256_HMAC; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_VALUE, NULL, (CK_ULONG) len } }; DE_CONST(key, keyTemplate[5].pValue); RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); ctx->object = CK_INVALID_HANDLE; PK11_FATALCHECK(pkcs_C_CreateObject, (ctx->session, keyTemplate, (CK_ULONG) 6, &ctx->object)); INSIST(ctx->object != CK_INVALID_HANDLE); PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object)); } void isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) { CK_BYTE garbage[ISC_SHA256_DIGESTLENGTH]; CK_ULONG len = ISC_SHA256_DIGESTLENGTH; if (ctx->handle == NULL) return; (void) pkcs_C_SignFinal(ctx->session, garbage, &len); memset(garbage, 0, sizeof(garbage)); if (ctx->object != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx->session, ctx->object); ctx->object = CK_INVALID_HANDLE; pk11_return_session(ctx); } void isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf, unsigned int len) { CK_RV rv; CK_BYTE_PTR pPart; DE_CONST(buf, pPart); PK11_FATALCHECK(pkcs_C_SignUpdate, (ctx->session, pPart, (CK_ULONG) len)); } void isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) { CK_RV rv; CK_BYTE newdigest[ISC_SHA256_DIGESTLENGTH]; CK_ULONG psl = ISC_SHA256_DIGESTLENGTH; REQUIRE(len <= ISC_SHA256_DIGESTLENGTH); PK11_FATALCHECK(pkcs_C_SignFinal, (ctx->session, newdigest, &psl)); if (ctx->object != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx->session, ctx->object); ctx->object = CK_INVALID_HANDLE; pk11_return_session(ctx); memmove(digest, newdigest, len); memset(newdigest, 0, sizeof(newdigest)); } void isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key, unsigned int len) { CK_RV rv; CK_MECHANISM mech = { CKM_SHA384_HMAC, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; CK_KEY_TYPE keyType = CKK_SHA384_HMAC; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_VALUE, NULL, (CK_ULONG) len } }; DE_CONST(key, keyTemplate[5].pValue); RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); ctx->object = CK_INVALID_HANDLE; PK11_FATALCHECK(pkcs_C_CreateObject, (ctx->session, keyTemplate, (CK_ULONG) 6, &ctx->object)); INSIST(ctx->object != CK_INVALID_HANDLE); PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object)); } void isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) { CK_BYTE garbage[ISC_SHA384_DIGESTLENGTH]; CK_ULONG len = ISC_SHA384_DIGESTLENGTH; if (ctx->handle == NULL) return; (void) pkcs_C_SignFinal(ctx->session, garbage, &len); memset(garbage, 0, sizeof(garbage)); if (ctx->object != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx->session, ctx->object); ctx->object = CK_INVALID_HANDLE; pk11_return_session(ctx); } void isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf, unsigned int len) { CK_RV rv; CK_BYTE_PTR pPart; DE_CONST(buf, pPart); PK11_FATALCHECK(pkcs_C_SignUpdate, (ctx->session, pPart, (CK_ULONG) len)); } void isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) { CK_RV rv; CK_BYTE newdigest[ISC_SHA384_DIGESTLENGTH]; CK_ULONG psl = ISC_SHA384_DIGESTLENGTH; REQUIRE(len <= ISC_SHA384_DIGESTLENGTH); PK11_FATALCHECK(pkcs_C_SignFinal, (ctx->session, newdigest, &psl)); if (ctx->object != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx->session, ctx->object); ctx->object = CK_INVALID_HANDLE; pk11_return_session(ctx); memmove(digest, newdigest, len); memset(newdigest, 0, sizeof(newdigest)); } void isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key, unsigned int len) { CK_RV rv; CK_MECHANISM mech = { CKM_SHA512_HMAC, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; CK_KEY_TYPE keyType = CKK_SHA512_HMAC; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_VALUE, NULL, (CK_ULONG) len } }; DE_CONST(key, keyTemplate[5].pValue); RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); ctx->object = CK_INVALID_HANDLE; PK11_FATALCHECK(pkcs_C_CreateObject, (ctx->session, keyTemplate, (CK_ULONG) 6, &ctx->object)); INSIST(ctx->object != CK_INVALID_HANDLE); PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object)); } void isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) { CK_BYTE garbage[ISC_SHA512_DIGESTLENGTH]; CK_ULONG len = ISC_SHA512_DIGESTLENGTH; if (ctx->handle == NULL) return; (void) pkcs_C_SignFinal(ctx->session, garbage, &len); memset(garbage, 0, sizeof(garbage)); if (ctx->object != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx->session, ctx->object); ctx->object = CK_INVALID_HANDLE; pk11_return_session(ctx); } void isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf, unsigned int len) { CK_RV rv; CK_BYTE_PTR pPart; DE_CONST(buf, pPart); PK11_FATALCHECK(pkcs_C_SignUpdate, (ctx->session, pPart, (CK_ULONG) len)); } void isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) { CK_RV rv; CK_BYTE newdigest[ISC_SHA512_DIGESTLENGTH]; CK_ULONG psl = ISC_SHA512_DIGESTLENGTH; REQUIRE(len <= ISC_SHA512_DIGESTLENGTH); PK11_FATALCHECK(pkcs_C_SignFinal, (ctx->session, newdigest, &psl)); if (ctx->object != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx->session, ctx->object); ctx->object = CK_INVALID_HANDLE; pk11_return_session(ctx); memmove(digest, newdigest, len); memset(newdigest, 0, sizeof(newdigest)); } #else #define IPAD 0x36 #define OPAD 0x5C /* * Start HMAC-SHA1 process. Initialize an sha1 context and digest the key. */ void isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key, unsigned int len) { unsigned char ipad[ISC_SHA1_BLOCK_LENGTH]; unsigned int i; memset(ctx->key, 0, sizeof(ctx->key)); if (len > sizeof(ctx->key)) { isc_sha1_t sha1ctx; isc_sha1_init(&sha1ctx); isc_sha1_update(&sha1ctx, key, len); isc_sha1_final(&sha1ctx, ctx->key); } else memmove(ctx->key, key, len); isc_sha1_init(&ctx->sha1ctx); memset(ipad, IPAD, sizeof(ipad)); for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++) ipad[i] ^= ctx->key[i]; isc_sha1_update(&ctx->sha1ctx, ipad, sizeof(ipad)); } void isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) { isc_sha1_invalidate(&ctx->sha1ctx); memset(ctx, 0, sizeof(*ctx)); } /* * Update context to reflect the concatenation of another buffer full * of bytes. */ void isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf, unsigned int len) { isc_sha1_update(&ctx->sha1ctx, buf, len); } /* * Compute signature - finalize SHA1 operation and reapply SHA1. */ void isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) { unsigned char opad[ISC_SHA1_BLOCK_LENGTH]; unsigned char newdigest[ISC_SHA1_DIGESTLENGTH]; unsigned int i; REQUIRE(len <= ISC_SHA1_DIGESTLENGTH); isc_sha1_final(&ctx->sha1ctx, newdigest); memset(opad, OPAD, sizeof(opad)); for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++) opad[i] ^= ctx->key[i]; isc_sha1_init(&ctx->sha1ctx); isc_sha1_update(&ctx->sha1ctx, opad, sizeof(opad)); isc_sha1_update(&ctx->sha1ctx, newdigest, ISC_SHA1_DIGESTLENGTH); isc_sha1_final(&ctx->sha1ctx, newdigest); isc_hmacsha1_invalidate(ctx); memmove(digest, newdigest, len); memset(newdigest, 0, sizeof(newdigest)); } /* * Start HMAC-SHA224 process. Initialize an sha224 context and digest the key. */ void isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key, unsigned int len) { unsigned char ipad[ISC_SHA224_BLOCK_LENGTH]; unsigned int i; memset(ctx->key, 0, sizeof(ctx->key)); if (len > sizeof(ctx->key)) { isc_sha224_t sha224ctx; isc_sha224_init(&sha224ctx); isc_sha224_update(&sha224ctx, key, len); isc_sha224_final(ctx->key, &sha224ctx); } else memmove(ctx->key, key, len); isc_sha224_init(&ctx->sha224ctx); memset(ipad, IPAD, sizeof(ipad)); for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++) ipad[i] ^= ctx->key[i]; isc_sha224_update(&ctx->sha224ctx, ipad, sizeof(ipad)); } void isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) { memset(ctx, 0, sizeof(*ctx)); } /* * Update context to reflect the concatenation of another buffer full * of bytes. */ void isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf, unsigned int len) { isc_sha224_update(&ctx->sha224ctx, buf, len); } /* * Compute signature - finalize SHA224 operation and reapply SHA224. */ void isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) { unsigned char opad[ISC_SHA224_BLOCK_LENGTH]; unsigned char newdigest[ISC_SHA224_DIGESTLENGTH]; unsigned int i; REQUIRE(len <= ISC_SHA224_DIGESTLENGTH); isc_sha224_final(newdigest, &ctx->sha224ctx); memset(opad, OPAD, sizeof(opad)); for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++) opad[i] ^= ctx->key[i]; isc_sha224_init(&ctx->sha224ctx); isc_sha224_update(&ctx->sha224ctx, opad, sizeof(opad)); isc_sha224_update(&ctx->sha224ctx, newdigest, ISC_SHA224_DIGESTLENGTH); isc_sha224_final(newdigest, &ctx->sha224ctx); memmove(digest, newdigest, len); memset(newdigest, 0, sizeof(newdigest)); } /* * Start HMAC-SHA256 process. Initialize an sha256 context and digest the key. */ void isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key, unsigned int len) { unsigned char ipad[ISC_SHA256_BLOCK_LENGTH]; unsigned int i; memset(ctx->key, 0, sizeof(ctx->key)); if (len > sizeof(ctx->key)) { isc_sha256_t sha256ctx; isc_sha256_init(&sha256ctx); isc_sha256_update(&sha256ctx, key, len); isc_sha256_final(ctx->key, &sha256ctx); } else memmove(ctx->key, key, len); isc_sha256_init(&ctx->sha256ctx); memset(ipad, IPAD, sizeof(ipad)); for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++) ipad[i] ^= ctx->key[i]; isc_sha256_update(&ctx->sha256ctx, ipad, sizeof(ipad)); } void isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) { memset(ctx, 0, sizeof(*ctx)); } /* * Update context to reflect the concatenation of another buffer full * of bytes. */ void isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf, unsigned int len) { isc_sha256_update(&ctx->sha256ctx, buf, len); } /* * Compute signature - finalize SHA256 operation and reapply SHA256. */ void isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) { unsigned char opad[ISC_SHA256_BLOCK_LENGTH]; unsigned char newdigest[ISC_SHA256_DIGESTLENGTH]; unsigned int i; REQUIRE(len <= ISC_SHA256_DIGESTLENGTH); isc_sha256_final(newdigest, &ctx->sha256ctx); memset(opad, OPAD, sizeof(opad)); for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++) opad[i] ^= ctx->key[i]; isc_sha256_init(&ctx->sha256ctx); isc_sha256_update(&ctx->sha256ctx, opad, sizeof(opad)); isc_sha256_update(&ctx->sha256ctx, newdigest, ISC_SHA256_DIGESTLENGTH); isc_sha256_final(newdigest, &ctx->sha256ctx); memmove(digest, newdigest, len); memset(newdigest, 0, sizeof(newdigest)); } /* * Start HMAC-SHA384 process. Initialize an sha384 context and digest the key. */ void isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key, unsigned int len) { unsigned char ipad[ISC_SHA384_BLOCK_LENGTH]; unsigned int i; memset(ctx->key, 0, sizeof(ctx->key)); if (len > sizeof(ctx->key)) { isc_sha384_t sha384ctx; isc_sha384_init(&sha384ctx); isc_sha384_update(&sha384ctx, key, len); isc_sha384_final(ctx->key, &sha384ctx); } else memmove(ctx->key, key, len); isc_sha384_init(&ctx->sha384ctx); memset(ipad, IPAD, sizeof(ipad)); for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++) ipad[i] ^= ctx->key[i]; isc_sha384_update(&ctx->sha384ctx, ipad, sizeof(ipad)); } void isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) { memset(ctx, 0, sizeof(*ctx)); } /* * Update context to reflect the concatenation of another buffer full * of bytes. */ void isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf, unsigned int len) { isc_sha384_update(&ctx->sha384ctx, buf, len); } /* * Compute signature - finalize SHA384 operation and reapply SHA384. */ void isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) { unsigned char opad[ISC_SHA384_BLOCK_LENGTH]; unsigned char newdigest[ISC_SHA384_DIGESTLENGTH]; unsigned int i; REQUIRE(len <= ISC_SHA384_DIGESTLENGTH); isc_sha384_final(newdigest, &ctx->sha384ctx); memset(opad, OPAD, sizeof(opad)); for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++) opad[i] ^= ctx->key[i]; isc_sha384_init(&ctx->sha384ctx); isc_sha384_update(&ctx->sha384ctx, opad, sizeof(opad)); isc_sha384_update(&ctx->sha384ctx, newdigest, ISC_SHA384_DIGESTLENGTH); isc_sha384_final(newdigest, &ctx->sha384ctx); memmove(digest, newdigest, len); memset(newdigest, 0, sizeof(newdigest)); } /* * Start HMAC-SHA512 process. Initialize an sha512 context and digest the key. */ void isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key, unsigned int len) { unsigned char ipad[ISC_SHA512_BLOCK_LENGTH]; unsigned int i; memset(ctx->key, 0, sizeof(ctx->key)); if (len > sizeof(ctx->key)) { isc_sha512_t sha512ctx; isc_sha512_init(&sha512ctx); isc_sha512_update(&sha512ctx, key, len); isc_sha512_final(ctx->key, &sha512ctx); } else memmove(ctx->key, key, len); isc_sha512_init(&ctx->sha512ctx); memset(ipad, IPAD, sizeof(ipad)); for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++) ipad[i] ^= ctx->key[i]; isc_sha512_update(&ctx->sha512ctx, ipad, sizeof(ipad)); } void isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) { memset(ctx, 0, sizeof(*ctx)); } /* * Update context to reflect the concatenation of another buffer full * of bytes. */ void isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf, unsigned int len) { isc_sha512_update(&ctx->sha512ctx, buf, len); } /* * Compute signature - finalize SHA512 operation and reapply SHA512. */ void isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) { unsigned char opad[ISC_SHA512_BLOCK_LENGTH]; unsigned char newdigest[ISC_SHA512_DIGESTLENGTH]; unsigned int i; REQUIRE(len <= ISC_SHA512_DIGESTLENGTH); isc_sha512_final(newdigest, &ctx->sha512ctx); memset(opad, OPAD, sizeof(opad)); for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++) opad[i] ^= ctx->key[i]; isc_sha512_init(&ctx->sha512ctx); isc_sha512_update(&ctx->sha512ctx, opad, sizeof(opad)); isc_sha512_update(&ctx->sha512ctx, newdigest, ISC_SHA512_DIGESTLENGTH); isc_sha512_final(newdigest, &ctx->sha512ctx); memmove(digest, newdigest, len); memset(newdigest, 0, sizeof(newdigest)); } #endif /* !ISC_PLATFORM_OPENSSLHASH */ /* * Verify signature - finalize SHA1 operation and reapply SHA1, then * compare to the supplied digest. */ isc_boolean_t isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) { unsigned char newdigest[ISC_SHA1_DIGESTLENGTH]; REQUIRE(len <= ISC_SHA1_DIGESTLENGTH); isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH); return (isc_safe_memequal(digest, newdigest, len)); } /* * Verify signature - finalize SHA224 operation and reapply SHA224, then * compare to the supplied digest. */ isc_boolean_t isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) { unsigned char newdigest[ISC_SHA224_DIGESTLENGTH]; REQUIRE(len <= ISC_SHA224_DIGESTLENGTH); isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH); return (isc_safe_memequal(digest, newdigest, len)); } /* * Verify signature - finalize SHA256 operation and reapply SHA256, then * compare to the supplied digest. */ isc_boolean_t isc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) { unsigned char newdigest[ISC_SHA256_DIGESTLENGTH]; REQUIRE(len <= ISC_SHA256_DIGESTLENGTH); isc_hmacsha256_sign(ctx, newdigest, ISC_SHA256_DIGESTLENGTH); return (isc_safe_memequal(digest, newdigest, len)); } /* * Verify signature - finalize SHA384 operation and reapply SHA384, then * compare to the supplied digest. */ isc_boolean_t isc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) { unsigned char newdigest[ISC_SHA384_DIGESTLENGTH]; REQUIRE(len <= ISC_SHA384_DIGESTLENGTH); isc_hmacsha384_sign(ctx, newdigest, ISC_SHA384_DIGESTLENGTH); return (isc_safe_memequal(digest, newdigest, len)); } /* * Verify signature - finalize SHA512 operation and reapply SHA512, then * compare to the supplied digest. */ isc_boolean_t isc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) { unsigned char newdigest[ISC_SHA512_DIGESTLENGTH]; REQUIRE(len <= ISC_SHA512_DIGESTLENGTH); isc_hmacsha512_sign(ctx, newdigest, ISC_SHA512_DIGESTLENGTH); return (isc_safe_memequal(digest, newdigest, len)); } bind9-9.10.3.dfsg.P4/lib/isc/regex.c0000644000470500017500000001717612664710322016207 0ustar lamontlamont/* * Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #if VALREGEX_REPORT_REASON #define FAIL(x) do { reason = (x); goto error; } while(0) #else #define FAIL(x) goto error #endif /* * Validate the regular expression 'C' locale. */ int isc_regex_validate(const char *c) { enum { none, parse_bracket, parse_bound, parse_ce, parse_ec, parse_cc } state = none; /* Well known character classes. */ const char *cc[] = { ":alnum:", ":digit:", ":punct:", ":alpha:", ":graph:", ":space:", ":blank:", ":lower:", ":upper:", ":cntrl:", ":print:", ":xdigit:" }; isc_boolean_t seen_comma = ISC_FALSE; isc_boolean_t seen_high = ISC_FALSE; isc_boolean_t seen_char = ISC_FALSE; isc_boolean_t seen_ec = ISC_FALSE; isc_boolean_t seen_ce = ISC_FALSE; isc_boolean_t have_atom = ISC_FALSE; int group = 0; int range = 0; int sub = 0; isc_boolean_t empty_ok = ISC_FALSE; isc_boolean_t neg = ISC_FALSE; isc_boolean_t was_multiple = ISC_FALSE; unsigned int low = 0; unsigned int high = 0; const char *ccname = NULL; int range_start = 0; #if VALREGEX_REPORT_REASON const char *reason = ""; #endif if (c == NULL || *c == 0) FAIL("empty string"); while (c != NULL && *c != 0) { switch (state) { case none: switch (*c) { case '\\': /* make literal */ ++c; switch (*c) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if ((*c - '0') > sub) FAIL("bad back reference"); have_atom = ISC_TRUE; was_multiple = ISC_FALSE; break; case 0: FAIL("escaped end-of-string"); default: goto literal; } ++c; break; case '[': /* bracket start */ ++c; neg = ISC_FALSE; was_multiple = ISC_FALSE; seen_char = ISC_FALSE; state = parse_bracket; break; case '{': /* bound start */ switch (c[1]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (!have_atom) FAIL("no atom"); if (was_multiple) FAIL("was multiple"); seen_comma = ISC_FALSE; seen_high = ISC_FALSE; low = high = 0; state = parse_bound; break; default: goto literal; } ++c; have_atom = ISC_TRUE; was_multiple = ISC_TRUE; break; case '}': goto literal; case '(': /* group start */ have_atom = ISC_FALSE; was_multiple = ISC_FALSE; empty_ok = ISC_TRUE; ++group; ++sub; ++c; break; case ')': /* group end */ if (group && !have_atom && !empty_ok) FAIL("empty alternative"); have_atom = ISC_TRUE; was_multiple = ISC_FALSE; if (group != 0) --group; ++c; break; case '|': /* alternative seperator */ if (!have_atom) FAIL("no atom"); have_atom = ISC_FALSE; empty_ok = ISC_FALSE; was_multiple = ISC_FALSE; ++c; break; case '^': case '$': have_atom = ISC_TRUE; was_multiple = ISC_TRUE; ++c; break; case '+': case '*': case '?': if (was_multiple) FAIL("was multiple"); if (!have_atom) FAIL("no atom"); have_atom = ISC_TRUE; was_multiple = ISC_TRUE; ++c; break; case '.': default: literal: have_atom = ISC_TRUE; was_multiple = ISC_FALSE; ++c; break; } break; case parse_bound: switch (*c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (!seen_comma) { low = low * 10 + *c - '0'; if (low > 255) FAIL("lower bound too big"); } else { seen_high = ISC_TRUE; high = high * 10 + *c - '0'; if (high > 255) FAIL("upper bound too big"); } ++c; break; case ',': if (seen_comma) FAIL("multiple commas"); seen_comma = ISC_TRUE; ++c; break; default: case '{': FAIL("non digit/comma"); case '}': if (seen_high && low > high) FAIL("bad parse bound"); seen_comma = ISC_FALSE; state = none; ++c; break; } break; case parse_bracket: switch (*c) { case '^': if (seen_char || neg) goto inside; neg = ISC_TRUE; ++c; break; case '-': if (range == 2) goto inside; if (!seen_char) goto inside; if (range == 1) FAIL("bad range"); range = 2; ++c; break; case '[': ++c; switch (*c) { case '.': /* collating element */ if (range != 0) --range; ++c; state = parse_ce; seen_ce = ISC_FALSE; break; case '=': /* equivalence class */ if (range == 2) FAIL("equivalence class in range"); ++c; state = parse_ec; seen_ec = ISC_FALSE; break; case ':': /* character class */ if (range == 2) FAIL("character class in range"); ccname = c; ++c; state = parse_cc; break; } seen_char = ISC_TRUE; break; case ']': if (!c[1] && !seen_char) FAIL("unfinished brace"); if (!seen_char) goto inside; ++c; range = 0; have_atom = ISC_TRUE; state = none; break; default: inside: seen_char = ISC_TRUE; if (range == 2 && (*c & 0xff) < range_start) FAIL("out of order range"); if (range != 0) --range; range_start = *c & 0xff; ++c; break; }; break; case parse_ce: switch (*c) { case '.': ++c; switch (*c) { case ']': if (!seen_ce) FAIL("empty ce"); ++c; state = parse_bracket; break; default: if (seen_ce) range_start = 256; else range_start = '.'; seen_ce = ISC_TRUE; break; } break; default: if (seen_ce) range_start = 256; else range_start = *c; seen_ce = ISC_TRUE; ++c; break; } break; case parse_ec: switch (*c) { case '=': ++c; switch (*c) { case ']': if (!seen_ec) FAIL("no ec"); ++c; state = parse_bracket; break; default: seen_ec = ISC_TRUE; break; } break; default: seen_ec = ISC_TRUE; ++c; break; } break; case parse_cc: switch (*c) { case ':': ++c; switch (*c) { case ']': { unsigned int i; isc_boolean_t found = ISC_FALSE; for (i = 0; i < sizeof(cc)/sizeof(*cc); i++) { unsigned int len; len = strlen(cc[i]); if (len != (unsigned int)(c - ccname)) continue; if (strncmp(cc[i], ccname, len)) continue; found = ISC_TRUE; } if (!found) FAIL("unknown cc"); ++c; state = parse_bracket; break; } default: break; } break; default: ++c; break; } break; } } if (group != 0) FAIL("group open"); if (state != none) FAIL("incomplete"); if (!have_atom) FAIL("no atom"); return (sub); error: #if VALREGEX_REPORT_REASON fprintf(stderr, "%s\n", reason); #endif return (-1); } bind9-9.10.3.dfsg.P4/lib/isc/mips/0002755000470500017500000000000012672612753015677 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/mips/Makefile.in0000644000470500017500000000166312664710322017740 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = include TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/mips/include/0002755000470500017500000000000012664710322017312 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/mips/include/Makefile.in0000644000470500017500000000165712664710322021366 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = isc TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/mips/include/isc/0002755000470500017500000000000012664710322020070 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/mips/include/isc/Makefile.in0000644000470500017500000000223012664710322022130 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ HEADERS = atomic.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \ done bind9-9.10.3.dfsg.P4/lib/isc/mips/include/isc/atomic.h0000644000470500017500000000464512664710322021524 0ustar lamontlamont/* * Copyright (C) 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: atomic.h,v 1.3 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_ATOMIC_H #define ISC_ATOMIC_H 1 #include #include #ifdef ISC_PLATFORM_USEGCCASM /* * This routine atomically increments the value stored in 'p' by 'val', and * returns the previous value. */ static inline isc_int32_t isc_atomic_xadd(isc_int32_t *p, int val) { isc_int32_t orig; /* add is a cheat, since MIPS has no mov instruction */ __asm__ volatile ( "1:" "ll $3, %1\n" "add %0, $0, $3\n" "add $3, $3, %2\n" "sc $3, %1\n" "beq $3, 0, 1b" : "=&r"(orig) : "m"(*p), "r"(val) : "memory", "$3" ); return (orig); } /* * This routine atomically stores the value 'val' in 'p'. */ static inline void isc_atomic_store(isc_int32_t *p, isc_int32_t val) { __asm__ volatile ( "1:" "ll $3, %0\n" "add $3, $0, %1\n" "sc $3, %0\n" "beq $3, 0, 1b" : : "m"(*p), "r"(val) : "memory", "$3" ); } /* * This routine atomically replaces the value in 'p' with 'val', if the * original value is equal to 'cmpval'. The original value is returned in any * case. */ static inline isc_int32_t isc_atomic_cmpxchg(isc_int32_t *p, int cmpval, int val) { isc_int32_t orig; __asm__ volatile( "1:" "ll $3, %1\n" "add %0, $0, $3\n" "bne $3, %2, 2f\n" "add $3, $0, %3\n" "sc $3, %1\n" "beq $3, 0, 1b\n" "2:" : "=&r"(orig) : "m"(*p), "r"(cmpval), "r"(val) : "memory", "$3" ); return (orig); } #else /* !ISC_PLATFORM_USEGCCASM */ #error "unsupported compiler. disable atomic ops by --disable-atomic" #endif #endif /* ISC_ATOMIC_H */ bind9-9.10.3.dfsg.P4/lib/isc/lib.c0000644000470500017500000000533212664710322015632 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2013-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lib.c,v 1.16 2009/09/02 23:48:02 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include /*** *** Globals ***/ LIBISC_EXTERNAL_DATA isc_msgcat_t * isc_msgcat = NULL; /*** *** Private ***/ static isc_once_t msgcat_once = ISC_ONCE_INIT; /*** *** Functions ***/ static void open_msgcat(void) { isc_msgcat_open("libisc.cat", &isc_msgcat); } void isc_lib_initmsgcat(void) { isc_result_t result; /*! * Initialize the ISC library's message catalog, isc_msgcat, if it * has not already been initialized. */ result = isc_once_do(&msgcat_once, open_msgcat); if (result != ISC_R_SUCCESS) { /* * Normally we'd use RUNTIME_CHECK() or FATAL_ERROR(), but * we can't do that here, since they might call us! * (Note that the catalog might be open anyway, so we might * as well try to provide an internationalized message.) */ fprintf(stderr, "%s:%d: %s: isc_once_do() %s.\n", __FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FATALERROR, "fatal error"), isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); abort(); } } static isc_once_t register_once = ISC_ONCE_INIT; static void do_register(void) { isc_bind9 = ISC_FALSE; RUNTIME_CHECK(isc__mem_register() == ISC_R_SUCCESS); RUNTIME_CHECK(isc__app_register() == ISC_R_SUCCESS); RUNTIME_CHECK(isc__task_register() == ISC_R_SUCCESS); RUNTIME_CHECK(isc__socket_register() == ISC_R_SUCCESS); RUNTIME_CHECK(isc__timer_register() == ISC_R_SUCCESS); } void isc_lib_register(void) { RUNTIME_CHECK(isc_once_do(®ister_once, do_register) == ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/isc/assertions.c0000644000470500017500000000667012664710322017264 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007-2009, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1997-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: assertions.c,v 1.26 2009/09/29 15:06:07 fdupont Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include /* * The maximum number of stack frames to dump on assertion failure. */ #ifndef BACKTRACE_MAXFRAME #define BACKTRACE_MAXFRAME 128 #endif /*% * Forward. */ static void default_callback(const char *, int, isc_assertiontype_t, const char *); static isc_assertioncallback_t isc_assertion_failed_cb = default_callback; /*% * Public. */ /*% assertion failed handler */ /* coverity[+kill] */ void isc_assertion_failed(const char *file, int line, isc_assertiontype_t type, const char *cond) { isc_assertion_failed_cb(file, line, type, cond); abort(); /* NOTREACHED */ } /*% Set callback. */ void isc_assertion_setcallback(isc_assertioncallback_t cb) { if (cb == NULL) isc_assertion_failed_cb = default_callback; else isc_assertion_failed_cb = cb; } /*% Type to Text */ const char * isc_assertion_typetotext(isc_assertiontype_t type) { const char *result; /* * These strings have purposefully not been internationalized * because they are considered to essentially be keywords of * the ISC development environment. */ switch (type) { case isc_assertiontype_require: result = "REQUIRE"; break; case isc_assertiontype_ensure: result = "ENSURE"; break; case isc_assertiontype_insist: result = "INSIST"; break; case isc_assertiontype_invariant: result = "INVARIANT"; break; default: result = NULL; } return (result); } /* * Private. */ static void default_callback(const char *file, int line, isc_assertiontype_t type, const char *cond) { void *tracebuf[BACKTRACE_MAXFRAME]; int i, nframes; const char *logsuffix = "."; const char *fname; isc_result_t result; result = isc_backtrace_gettrace(tracebuf, BACKTRACE_MAXFRAME, &nframes); if (result == ISC_R_SUCCESS && nframes > 0) logsuffix = ", back trace"; fprintf(stderr, "%s:%d: %s(%s) %s%s\n", file, line, isc_assertion_typetotext(type), cond, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), logsuffix); if (result == ISC_R_SUCCESS) { for (i = 0; i < nframes; i++) { unsigned long offset; fname = NULL; result = isc_backtrace_getsymbol(tracebuf[i], &fname, &offset); if (result == ISC_R_SUCCESS) { fprintf(stderr, "#%d %p in %s()+0x%lx\n", i, tracebuf[i], fname, offset); } else { fprintf(stderr, "#%d %p in ??\n", i, tracebuf[i]); } } } fflush(stderr); } bind9-9.10.3.dfsg.P4/lib/isc/base64.c0000644000470500017500000001507412664710322016154 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: base64.c,v 1.34 2009/10/21 23:48:05 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #define RETERR(x) do { \ isc_result_t _r = (x); \ if (_r != ISC_R_SUCCESS) \ return (_r); \ } while (0) /*@{*/ /*! * These static functions are also present in lib/dns/rdata.c. I'm not * sure where they should go. -- bwelling */ static isc_result_t str_totext(const char *source, isc_buffer_t *target); static isc_result_t mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length); static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; /*@}*/ isc_result_t isc_base64_totext(isc_region_t *source, int wordlength, const char *wordbreak, isc_buffer_t *target) { char buf[5]; unsigned int loops = 0; if (wordlength < 4) wordlength = 4; memset(buf, 0, sizeof(buf)); while (source->length > 2) { buf[0] = base64[(source->base[0]>>2)&0x3f]; buf[1] = base64[((source->base[0]<<4)&0x30)| ((source->base[1]>>4)&0x0f)]; buf[2] = base64[((source->base[1]<<2)&0x3c)| ((source->base[2]>>6)&0x03)]; buf[3] = base64[source->base[2]&0x3f]; RETERR(str_totext(buf, target)); isc_region_consume(source, 3); loops++; if (source->length != 0 && (int)((loops + 1) * 4) >= wordlength) { loops = 0; RETERR(str_totext(wordbreak, target)); } } if (source->length == 2) { buf[0] = base64[(source->base[0]>>2)&0x3f]; buf[1] = base64[((source->base[0]<<4)&0x30)| ((source->base[1]>>4)&0x0f)]; buf[2] = base64[((source->base[1]<<2)&0x3c)]; buf[3] = '='; RETERR(str_totext(buf, target)); isc_region_consume(source, 2); } else if (source->length == 1) { buf[0] = base64[(source->base[0]>>2)&0x3f]; buf[1] = base64[((source->base[0]<<4)&0x30)]; buf[2] = buf[3] = '='; RETERR(str_totext(buf, target)); isc_region_consume(source, 1); } return (ISC_R_SUCCESS); } /*% * State of a base64 decoding process in progress. */ typedef struct { int length; /*%< Desired length of binary data or -1 */ isc_buffer_t *target; /*%< Buffer for resulting binary data */ int digits; /*%< Number of buffered base64 digits */ isc_boolean_t seen_end; /*%< True if "=" end marker seen */ int val[4]; } base64_decode_ctx_t; static inline void base64_decode_init(base64_decode_ctx_t *ctx, int length, isc_buffer_t *target) { ctx->digits = 0; ctx->seen_end = ISC_FALSE; ctx->length = length; ctx->target = target; } static inline isc_result_t base64_decode_char(base64_decode_ctx_t *ctx, int c) { char *s; if (ctx->seen_end) return (ISC_R_BADBASE64); if ((s = strchr(base64, c)) == NULL) return (ISC_R_BADBASE64); ctx->val[ctx->digits++] = (int)(s - base64); if (ctx->digits == 4) { int n; unsigned char buf[3]; if (ctx->val[0] == 64 || ctx->val[1] == 64) return (ISC_R_BADBASE64); if (ctx->val[2] == 64 && ctx->val[3] != 64) return (ISC_R_BADBASE64); /* * Check that bits that should be zero are. */ if (ctx->val[2] == 64 && (ctx->val[1] & 0xf) != 0) return (ISC_R_BADBASE64); /* * We don't need to test for ctx->val[2] != 64 as * the bottom two bits of 64 are zero. */ if (ctx->val[3] == 64 && (ctx->val[2] & 0x3) != 0) return (ISC_R_BADBASE64); n = (ctx->val[2] == 64) ? 1 : (ctx->val[3] == 64) ? 2 : 3; if (n != 3) { ctx->seen_end = ISC_TRUE; if (ctx->val[2] == 64) ctx->val[2] = 0; if (ctx->val[3] == 64) ctx->val[3] = 0; } buf[0] = (ctx->val[0]<<2)|(ctx->val[1]>>4); buf[1] = (ctx->val[1]<<4)|(ctx->val[2]>>2); buf[2] = (ctx->val[2]<<6)|(ctx->val[3]); RETERR(mem_tobuffer(ctx->target, buf, n)); if (ctx->length >= 0) { if (n > ctx->length) return (ISC_R_BADBASE64); else ctx->length -= n; } ctx->digits = 0; } return (ISC_R_SUCCESS); } static inline isc_result_t base64_decode_finish(base64_decode_ctx_t *ctx) { if (ctx->length > 0) return (ISC_R_UNEXPECTEDEND); if (ctx->digits != 0) return (ISC_R_BADBASE64); return (ISC_R_SUCCESS); } isc_result_t isc_base64_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) { base64_decode_ctx_t ctx; isc_textregion_t *tr; isc_token_t token; isc_boolean_t eol; base64_decode_init(&ctx, length, target); while (!ctx.seen_end && (ctx.length != 0)) { unsigned int i; if (length > 0) eol = ISC_FALSE; else eol = ISC_TRUE; RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, eol)); if (token.type != isc_tokentype_string) break; tr = &token.value.as_textregion; for (i = 0; i < tr->length; i++) RETERR(base64_decode_char(&ctx, tr->base[i])); } if (ctx.length < 0 && !ctx.seen_end) isc_lex_ungettoken(lexer, &token); RETERR(base64_decode_finish(&ctx)); return (ISC_R_SUCCESS); } isc_result_t isc_base64_decodestring(const char *cstr, isc_buffer_t *target) { base64_decode_ctx_t ctx; base64_decode_init(&ctx, -1, target); for (;;) { int c = *cstr++; if (c == '\0') break; if (c == ' ' || c == '\t' || c == '\n' || c== '\r') continue; RETERR(base64_decode_char(&ctx, c)); } RETERR(base64_decode_finish(&ctx)); return (ISC_R_SUCCESS); } static isc_result_t str_totext(const char *source, isc_buffer_t *target) { unsigned int l; isc_region_t region; isc_buffer_availableregion(target, ®ion); l = strlen(source); if (l > region.length) return (ISC_R_NOSPACE); memmove(region.base, source, l); isc_buffer_add(target, l); return (ISC_R_SUCCESS); } static isc_result_t mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) { isc_region_t tr; isc_buffer_availableregion(target, &tr); if (length > tr.length) return (ISC_R_NOSPACE); memmove(tr.base, base, length); isc_buffer_add(target, length); return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/isc/pk11_result.c0000644000470500017500000000437512664710322017244 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #include LIBISC_EXTERNAL_DATA isc_msgcat_t * pk11_msgcat = NULL; static isc_once_t msgcat_once = ISC_ONCE_INIT; static const char *text[PK11_R_NRESULTS] = { "PKCS#11 initialization failed", /*%< 0 */ "no PKCS#11 provider", /*%< 1 */ "PKCS#11 provider has no random service", /*%< 2 */ "PKCS#11 provider has no digest service", /*%< 3 */ "PKCS#11 provider has no AES service", /*%< 4 */ }; #define PK11_RESULT_RESULTSET 2 static isc_once_t once = ISC_ONCE_INIT; static void open_msgcat(void) { isc_msgcat_open("libpk11.cat", &pk11_msgcat); } void pk11_initmsgcat(void) { /* * Initialize the PKCS#11 support's message catalog, * pk11_msgcat, if it has not already been initialized. */ RUNTIME_CHECK(isc_once_do(&msgcat_once, open_msgcat) == ISC_R_SUCCESS); } static void initialize_action(void) { isc_result_t result; result = isc_result_register(ISC_RESULTCLASS_PK11, PK11_R_NRESULTS, text, pk11_msgcat, PK11_RESULT_RESULTSET); if (result != ISC_R_SUCCESS) UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_result_register() failed: %u", result); } static void initialize(void) { pk11_initmsgcat(); RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); } const char * pk11_result_totext(isc_result_t result) { initialize(); return (isc_result_totext(result)); } void pk11_result_register(void) { initialize(); } bind9-9.10.3.dfsg.P4/lib/isc/backtrace.c0000644000470500017500000001754312664710322017012 0ustar lamontlamont/* * Copyright (C) 2009, 2013-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: backtrace.c,v 1.3 2009/09/02 23:48:02 tbox Exp $ */ /*! \file */ #include "config.h" #include #include #ifdef HAVE_LIBCTRACE #include #endif #include #include #include #ifdef ISC_PLATFORM_USEBACKTRACE /* * Getting a back trace of a running process is tricky and highly platform * dependent. Our current approach is as follows: * 1. If the system library supports the "backtrace()" function, use it. * 2. Otherwise, if the compiler is gcc and the architecture is x86_64 or IA64, * then use gcc's (hidden) Unwind_Backtrace() function. Note that this * function doesn't work for C programs on many other architectures. * 3. Otherwise, if the architecture x86 or x86_64, try to unwind the stack * frame following frame pointers. This assumes the executable binary * compiled with frame pointers; this is not always true for x86_64 (rather, * compiler optimizations often disable frame pointers). The validation * checks in getnextframeptr() hopefully rejects bogus values stored in * the RBP register in such a case. If the backtrace function itself crashes * due to this problem, the whole package should be rebuilt with * --disable-backtrace. */ #ifdef HAVE_LIBCTRACE #define BACKTRACE_LIBC #elif defined(__GNUC__) && (defined(__x86_64__) || defined(__ia64__)) #define BACKTRACE_GCC #elif defined(WIN32) #define BACKTRACE_WIN32 #elif defined(__x86_64__) || defined(__i386__) #define BACKTRACE_X86STACK #else #define BACKTRACE_DISABLED #endif /* HAVE_LIBCTRACE */ #else /* !ISC_PLATFORM_USEBACKTRACE */ #define BACKTRACE_DISABLED #endif /* ISC_PLATFORM_USEBACKTRACE */ #ifdef BACKTRACE_LIBC isc_result_t isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) { int n; /* * Validate the arguments: intentionally avoid using REQUIRE(). * See notes in backtrace.h. */ if (addrs == NULL || nframes == NULL) return (ISC_R_FAILURE); /* * backtrace(3) includes this function itself in the address array, * which should be eliminated from the returned sequence. */ n = backtrace(addrs, maxaddrs); if (n < 2) return (ISC_R_NOTFOUND); n--; memmove(addrs, &addrs[1], sizeof(void *) * n); *nframes = n; return (ISC_R_SUCCESS); } #elif defined(BACKTRACE_GCC) extern int _Unwind_Backtrace(void* fn, void* a); extern void* _Unwind_GetIP(void* ctx); typedef struct { void **result; int max_depth; int skip_count; int count; } trace_arg_t; static int btcallback(void *uc, void *opq) { trace_arg_t *arg = (trace_arg_t *)opq; if (arg->skip_count > 0) arg->skip_count--; else arg->result[arg->count++] = (void *)_Unwind_GetIP(uc); if (arg->count == arg->max_depth) return (5); /* _URC_END_OF_STACK */ return (0); /* _URC_NO_REASON */ } isc_result_t isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) { trace_arg_t arg; /* Argument validation: see above. */ if (addrs == NULL || nframes == NULL) return (ISC_R_FAILURE); arg.skip_count = 1; arg.result = addrs; arg.max_depth = maxaddrs; arg.count = 0; _Unwind_Backtrace(btcallback, &arg); *nframes = arg.count; return (ISC_R_SUCCESS); } #elif defined(BACKTRACE_WIN32) isc_result_t isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) { unsigned long ftc = (unsigned long)maxaddrs; *nframes = (int)CaptureStackBackTrace(1, ftc, addrs, NULL); return ISC_R_SUCCESS; } #elif defined(BACKTRACE_X86STACK) #ifdef __x86_64__ static unsigned long getrbp(void) { __asm("movq %rbp, %rax\n"); } #endif static void ** getnextframeptr(void **sp) { void **newsp = (void **)*sp; /* * Perform sanity check for the new frame pointer, derived from * google glog. This can actually be bogus depending on compiler. */ /* prohibit the stack frames from growing downwards */ if (newsp <= sp) return (NULL); /* A heuristics to reject "too large" frame: this actually happened. */ if ((char *)newsp - (char *)sp > 100000) return (NULL); /* * Not sure if other checks used in glog are needed at this moment. * For our purposes we don't have to consider non-contiguous frames, * for example. */ return (newsp); } isc_result_t isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) { int i = 0; void **sp; /* Argument validation: see above. */ if (addrs == NULL || nframes == NULL) return (ISC_R_FAILURE); #ifdef __x86_64__ sp = (void **)getrbp(); if (sp == NULL) return (ISC_R_NOTFOUND); /* * sp is the frame ptr of this function itself due to the call to * getrbp(), so need to unwind one frame for consistency. */ sp = getnextframeptr(sp); #else /* * i386: the frame pointer is stored 2 words below the address for the * first argument. Note that the body of this function cannot be * inlined since it depends on the address of the function argument. */ sp = (void **)&addrs - 2; #endif while (sp != NULL && i < maxaddrs) { addrs[i++] = *(sp + 1); sp = getnextframeptr(sp); } *nframes = i; return (ISC_R_SUCCESS); } #elif defined(BACKTRACE_DISABLED) isc_result_t isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) { /* Argument validation: see above. */ if (addrs == NULL || nframes == NULL) return (ISC_R_FAILURE); UNUSED(maxaddrs); return (ISC_R_NOTIMPLEMENTED); } #endif isc_result_t isc_backtrace_getsymbolfromindex(int idx, const void **addrp, const char **symbolp) { REQUIRE(addrp != NULL && *addrp == NULL); REQUIRE(symbolp != NULL && *symbolp == NULL); if (idx < 0 || idx >= isc__backtrace_nsymbols) return (ISC_R_RANGE); *addrp = isc__backtrace_symtable[idx].addr; *symbolp = isc__backtrace_symtable[idx].symbol; return (ISC_R_SUCCESS); } static int symtbl_compare(const void *addr, const void *entryarg) { const isc_backtrace_symmap_t *entry = entryarg; const isc_backtrace_symmap_t *end = &isc__backtrace_symtable[isc__backtrace_nsymbols - 1]; if (isc__backtrace_nsymbols == 1 || entry == end) { if (addr >= entry->addr) { /* * If addr is equal to or larger than that of the last * entry of the table, we cannot be sure if this is * within a valid range so we consider it valid. */ return (0); } return (-1); } /* entry + 1 is a valid entry from now on. */ if (addr < entry->addr) return (-1); else if (addr >= (entry + 1)->addr) return (1); return (0); } isc_result_t isc_backtrace_getsymbol(const void *addr, const char **symbolp, unsigned long *offsetp) { isc_result_t result = ISC_R_SUCCESS; isc_backtrace_symmap_t *found; /* * Validate the arguments: intentionally avoid using REQUIRE(). * See notes in backtrace.h. */ if (symbolp == NULL || *symbolp != NULL || offsetp == NULL) return (ISC_R_FAILURE); if (isc__backtrace_nsymbols < 1) return (ISC_R_NOTFOUND); /* * Search the table for the entry that meets: * entry.addr <= addr < next_entry.addr. */ found = bsearch(addr, isc__backtrace_symtable, isc__backtrace_nsymbols, sizeof(isc__backtrace_symtable[0]), symtbl_compare); if (found == NULL) result = ISC_R_NOTFOUND; else { *symbolp = found->symbol; *offsetp = (unsigned long) ((const char *)addr - (char *)found->addr); } return (result); } bind9-9.10.3.dfsg.P4/lib/isc/x86_64/0002755000470500017500000000000012664710322015655 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/x86_64/Makefile.in0000644000470500017500000000166312664710322017726 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = include TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/x86_64/include/0002755000470500017500000000000012664710322017300 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/x86_64/include/Makefile.in0000644000470500017500000000165712664710322021354 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = isc TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/x86_64/include/isc/0002755000470500017500000000000012664710322020056 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/x86_64/include/isc/Makefile.in0000644000470500017500000000223012664710322022116 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:10:00 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ HEADERS = atomic.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \ done bind9-9.10.3.dfsg.P4/lib/isc/x86_64/include/isc/atomic.h0000644000470500017500000000572512664710322021512 0ustar lamontlamont/* * Copyright (C) 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: atomic.h,v 1.6 2008/01/24 23:47:00 tbox Exp $ */ #ifndef ISC_ATOMIC_H #define ISC_ATOMIC_H 1 #include #include #ifdef ISC_PLATFORM_USEGCCASM /* We share the gcc-version with x86_32 */ #error "impossible case. check build configuration" #elif defined(ISC_PLATFORM_USESTDASM) /* * The followings are "generic" assembly code which implements the same * functionality in case the gcc extension cannot be used. It should be * better to avoid inlining below, since we directly refer to specific * registers for arguments, which would not actually correspond to the * intended address or value in the embedded mnemonic. */ #include /* for 'UNUSED' macro */ static isc_int32_t isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) { UNUSED(p); UNUSED(val); __asm ( "movq %rdi, %rdx\n" "movl %esi, %eax\n" #ifdef ISC_PLATFORM_USETHREADS "lock;" #endif "xadd %eax, (%rdx)\n" /* * XXX: assume %eax will be used as the return value. */ ); } #ifdef ISC_PLATFORM_HAVEXADDQ static isc_int64_t isc_atomic_xaddq(isc_int64_t *p, isc_int64_t val) { UNUSED(p); UNUSED(val); __asm ( "movq %rdi, %rdx\n" "movq %rsi, %rax\n" #ifdef ISC_PLATFORM_USETHREADS "lock;" #endif "xaddq %rax, (%rdx)\n" /* * XXX: assume %rax will be used as the return value. */ ); } #endif static void isc_atomic_store(isc_int32_t *p, isc_int32_t val) { UNUSED(p); UNUSED(val); __asm ( "movq %rdi, %rax\n" "movl %esi, %edx\n" #ifdef ISC_PLATFORM_USETHREADS "lock;" #endif "xchgl (%rax), %edx\n" /* * XXX: assume %rax will be used as the return value. */ ); } static isc_int32_t isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) { UNUSED(p); UNUSED(cmpval); UNUSED(val); __asm ( "movl %edx, %ecx\n" "movl %esi, %eax\n" "movq %rdi, %rdx\n" #ifdef ISC_PLATFORM_USETHREADS "lock;" #endif /* * If (%rdi) == %eax then (%rdi) := %edx. * %eax is set to old (%ecx), which will be the return value. */ "cmpxchgl %ecx, (%rdx)" ); } #else /* !ISC_PLATFORM_USEGCCASM && !ISC_PLATFORM_USESTDASM */ #error "unsupported compiler. disable atomic ops by --disable-atomic" #endif #endif /* ISC_ATOMIC_H */ bind9-9.10.3.dfsg.P4/lib/isc/result.c0000644000470500017500000001361412664710322016404 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2008, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include typedef struct resulttable { unsigned int base; unsigned int last; const char ** text; isc_msgcat_t * msgcat; int set; ISC_LINK(struct resulttable) link; } resulttable; static const char *description[ISC_R_NRESULTS] = { "success", /*%< 0 */ "out of memory", /*%< 1 */ "timed out", /*%< 2 */ "no available threads", /*%< 3 */ "address not available", /*%< 4 */ "address in use", /*%< 5 */ "permission denied", /*%< 6 */ "no pending connections", /*%< 7 */ "network unreachable", /*%< 8 */ "host unreachable", /*%< 9 */ "network down", /*%< 10 */ "host down", /*%< 11 */ "connection refused", /*%< 12 */ "not enough free resources", /*%< 13 */ "end of file", /*%< 14 */ "socket already bound", /*%< 15 */ "reload", /*%< 16 */ "lock busy", /*%< 17 */ "already exists", /*%< 18 */ "ran out of space", /*%< 19 */ "operation canceled", /*%< 20 */ "socket is not bound", /*%< 21 */ "shutting down", /*%< 22 */ "not found", /*%< 23 */ "unexpected end of input", /*%< 24 */ "failure", /*%< 25 */ "I/O error", /*%< 26 */ "not implemented", /*%< 27 */ "unbalanced parentheses", /*%< 28 */ "no more", /*%< 29 */ "invalid file", /*%< 30 */ "bad base64 encoding", /*%< 31 */ "unexpected token", /*%< 32 */ "quota reached", /*%< 33 */ "unexpected error", /*%< 34 */ "already running", /*%< 35 */ "ignore", /*%< 36 */ "address mask not contiguous", /*%< 37 */ "file not found", /*%< 38 */ "file already exists", /*%< 39 */ "socket is not connected", /*%< 40 */ "out of range", /*%< 41 */ "out of entropy", /*%< 42 */ "invalid use of multicast address", /*%< 43 */ "not a file", /*%< 44 */ "not a directory", /*%< 45 */ "queue is full", /*%< 46 */ "address family mismatch", /*%< 47 */ "address family not supported", /*%< 48 */ "bad hex encoding", /*%< 49 */ "too many open files", /*%< 50 */ "not blocking", /*%< 51 */ "unbalanced quotes", /*%< 52 */ "operation in progress", /*%< 53 */ "connection reset", /*%< 54 */ "soft quota reached", /*%< 55 */ "not a valid number", /*%< 56 */ "disabled", /*%< 57 */ "max size", /*%< 58 */ "invalid address format", /*%< 59 */ "bad base32 encoding", /*%< 60 */ "unset", /*%< 61 */ "multiple", /*%< 62 */ }; #define ISC_RESULT_RESULTSET 2 #define ISC_RESULT_UNAVAILABLESET 3 static isc_once_t once = ISC_ONCE_INIT; static ISC_LIST(resulttable) tables; static isc_mutex_t lock; static isc_result_t register_table(unsigned int base, unsigned int nresults, const char **text, isc_msgcat_t *msgcat, int set) { resulttable *table; REQUIRE(base % ISC_RESULTCLASS_SIZE == 0); REQUIRE(nresults <= ISC_RESULTCLASS_SIZE); REQUIRE(text != NULL); /* * We use malloc() here because we we want to be able to use * isc_result_totext() even if there is no memory context. */ table = malloc(sizeof(*table)); if (table == NULL) return (ISC_R_NOMEMORY); table->base = base; table->last = base + nresults - 1; table->text = text; table->msgcat = msgcat; table->set = set; ISC_LINK_INIT(table, link); LOCK(&lock); ISC_LIST_APPEND(tables, table, link); UNLOCK(&lock); return (ISC_R_SUCCESS); } static void initialize_action(void) { isc_result_t result; RUNTIME_CHECK(isc_mutex_init(&lock) == ISC_R_SUCCESS); ISC_LIST_INIT(tables); result = register_table(ISC_RESULTCLASS_ISC, ISC_R_NRESULTS, description, isc_msgcat, ISC_RESULT_RESULTSET); if (result != ISC_R_SUCCESS) UNEXPECTED_ERROR(__FILE__, __LINE__, "register_table() %s: %u", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), result); } static void initialize(void) { isc_lib_initmsgcat(); RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); } const char * isc_result_totext(isc_result_t result) { resulttable *table; const char *text, *default_text; int index; initialize(); LOCK(&lock); text = NULL; for (table = ISC_LIST_HEAD(tables); table != NULL; table = ISC_LIST_NEXT(table, link)) { if (result >= table->base && result <= table->last) { index = (int)(result - table->base); default_text = table->text[index]; /* * Note: we use 'index + 1' as the message number * instead of index because isc_msgcat_get() requires * the message number to be > 0. */ text = isc_msgcat_get(table->msgcat, table->set, index + 1, default_text); break; } } if (text == NULL) text = isc_msgcat_get(isc_msgcat, ISC_RESULT_UNAVAILABLESET, 1, "(result code text not available)"); UNLOCK(&lock); return (text); } isc_result_t isc_result_register(unsigned int base, unsigned int nresults, const char **text, isc_msgcat_t *msgcat, int set) { initialize(); return (register_table(base, nresults, text, msgcat, set)); } bind9-9.10.3.dfsg.P4/lib/isc/socket_api.c0000644000470500017500000002350612664710322017210 0ustar lamontlamont/* * Copyright (C) 2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #include #include #include #include #include #include #include static isc_mutex_t createlock; static isc_once_t once = ISC_ONCE_INIT; static isc_socketmgrcreatefunc_t socketmgr_createfunc = NULL; static void initialize(void) { RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS); } isc_result_t isc_socket_register(isc_socketmgrcreatefunc_t createfunc) { isc_result_t result = ISC_R_SUCCESS; RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); LOCK(&createlock); if (socketmgr_createfunc == NULL) socketmgr_createfunc = createfunc; else result = ISC_R_EXISTS; UNLOCK(&createlock); return (result); } isc_result_t isc_socketmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx, isc_socketmgr_t **managerp) { isc_result_t result; LOCK(&createlock); REQUIRE(socketmgr_createfunc != NULL); result = (*socketmgr_createfunc)(mctx, managerp); UNLOCK(&createlock); if (result == ISC_R_SUCCESS) isc_appctx_setsocketmgr(actx, *managerp); return (result); } isc_result_t isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) { isc_result_t result; if (isc_bind9) return (isc__socketmgr_create(mctx, managerp)); LOCK(&createlock); REQUIRE(socketmgr_createfunc != NULL); result = (*socketmgr_createfunc)(mctx, managerp); UNLOCK(&createlock); return (result); } void isc_socketmgr_destroy(isc_socketmgr_t **managerp) { REQUIRE(managerp != NULL && ISCAPI_SOCKETMGR_VALID(*managerp)); if (isc_bind9) isc__socketmgr_destroy(managerp); else (*managerp)->methods->destroy(managerp); ENSURE(*managerp == NULL); } isc_result_t isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, isc_socket_t **socketp) { REQUIRE(ISCAPI_SOCKETMGR_VALID(manager)); if (isc_bind9) return (isc__socket_create(manager, pf, type, socketp)); return (manager->methods->socketcreate(manager, pf, type, socketp)); } void isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp) { REQUIRE(ISCAPI_SOCKET_VALID(sock)); REQUIRE(socketp != NULL && *socketp == NULL); if (isc_bind9) isc__socket_attach(sock, socketp); else sock->methods->attach(sock, socketp); ENSURE(*socketp == sock); } void isc_socket_detach(isc_socket_t **socketp) { REQUIRE(socketp != NULL && ISCAPI_SOCKET_VALID(*socketp)); if (isc_bind9) isc__socket_detach(socketp); else (*socketp)->methods->detach(socketp); ENSURE(*socketp == NULL); } isc_result_t isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr, unsigned int options) { REQUIRE(ISCAPI_SOCKET_VALID(sock)); if (isc_bind9) return (isc__socket_bind(sock, sockaddr, options)); return (sock->methods->bind(sock, sockaddr, options)); } isc_result_t isc_socket_sendto(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo) { REQUIRE(ISCAPI_SOCKET_VALID(sock)); if (isc_bind9) return (isc__socket_sendto(sock, region, task, action, arg, address, pktinfo)); return (sock->methods->sendto(sock, region, task, action, arg, address, pktinfo)); } isc_result_t isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr, isc_task_t *task, isc_taskaction_t action, void *arg) { REQUIRE(ISCAPI_SOCKET_VALID(sock)); if (isc_bind9) return (isc__socket_connect(sock, addr, task, action, arg)); return (sock->methods->connect(sock, addr, task, action, arg)); } isc_result_t isc_socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, isc_task_t *task, isc_taskaction_t action, void *arg) { REQUIRE(ISCAPI_SOCKET_VALID(sock)); if (isc_bind9) return (isc__socket_recv(sock, region, minimum, task, action, arg)); return (sock->methods->recv(sock, region, minimum, task, action, arg)); } void isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) { REQUIRE(ISCAPI_SOCKET_VALID(sock)); if (isc_bind9) isc__socket_cancel(sock, task, how); else sock->methods->cancel(sock, task, how); } isc_result_t isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) { REQUIRE(ISCAPI_SOCKET_VALID(sock)); if (isc_bind9) return (isc__socket_getsockname(sock, addressp)); return (sock->methods->getsockname(sock, addressp)); } void isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) { REQUIRE(ISCAPI_SOCKET_VALID(sock)); if (isc_bind9) isc__socket_ipv6only(sock, yes); else sock->methods->ipv6only(sock, yes); } void isc_socket_dscp(isc_socket_t *sock, isc_dscp_t dscp) { REQUIRE(ISCAPI_SOCKET_VALID(sock)); sock->methods->dscp(sock, dscp); } isc_sockettype_t isc_socket_gettype(isc_socket_t *sock) { REQUIRE(ISCAPI_SOCKET_VALID(sock)); if (isc_bind9) return (isc__socket_gettype(sock)); return (sock->methods->gettype(sock)); } void isc_socket_setname(isc_socket_t *sock, const char *name, void *tag) { REQUIRE(ISCAPI_SOCKET_VALID(sock)); UNUSED(sock); /* in case REQUIRE() is empty */ UNUSED(name); UNUSED(tag); } isc_result_t isc_socket_fdwatchcreate(isc_socketmgr_t *manager, int fd, int flags, isc_sockfdwatch_t callback, void *cbarg, isc_task_t *task, isc_socket_t **socketp) { REQUIRE(ISCAPI_SOCKETMGR_VALID(manager)); if (isc_bind9) return (isc__socket_fdwatchcreate(manager, fd, flags, callback, cbarg, task, socketp)); return (manager->methods->fdwatchcreate(manager, fd, flags, callback, cbarg, task, socketp)); } isc_result_t isc_socket_fdwatchpoke(isc_socket_t *sock, int flags) { REQUIRE(ISCAPI_SOCKET_VALID(sock)); if (isc_bind9) return (isc__socket_fdwatchpoke(sock, flags)); return (sock->methods->fdwatchpoke(sock, flags)); } isc_result_t isc_socket_dup(isc_socket_t *sock, isc_socket_t **socketp) { REQUIRE(ISCAPI_SOCKET_VALID(sock)); REQUIRE(socketp != NULL && *socketp == NULL); if (isc_bind9) return (isc__socket_dup(sock, socketp)); return (sock->methods->dup(sock, socketp)); } int isc_socket_getfd(isc_socket_t *sock) { REQUIRE(ISCAPI_SOCKET_VALID(sock)); if (isc_bind9) return (isc__socket_getfd(sock)); return (sock->methods->getfd(sock)); } isc_result_t isc_socket_open(isc_socket_t *sock) { return (isc__socket_open(sock)); } isc_result_t isc_socket_close(isc_socket_t *sock) { return (isc__socket_close(sock)); } isc_result_t isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp, unsigned int maxsocks) { return (isc__socketmgr_create2(mctx, managerp, maxsocks)); } isc_result_t isc_socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist, unsigned int minimum, isc_task_t *task, isc_taskaction_t action, void *arg) { return (isc__socket_recvv(sock, buflist, minimum, task, action, arg)); } isc_result_t isc_socket_recv2(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, isc_task_t *task, isc_socketevent_t *event, unsigned int flags) { return (isc__socket_recv2(sock, region, minimum, task, event, flags)); } isc_result_t isc_socket_send(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, isc_taskaction_t action, void *arg) { return (isc__socket_send(sock, region, task, action, arg)); } isc_result_t isc_socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist, isc_task_t *task, isc_taskaction_t action, void *arg) { return (isc__socket_sendv(sock, buflist, task, action, arg)); } isc_result_t isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist, isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo) { return (isc__socket_sendtov(sock, buflist, task, action, arg, address, pktinfo)); } isc_result_t isc_socket_sendtov2(isc_socket_t *sock, isc_bufferlist_t *buflist, isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, unsigned int flags) { return (isc__socket_sendtov2(sock, buflist, task, action, arg, address, pktinfo, flags)); } isc_result_t isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, isc_socketevent_t *event, unsigned int flags) { return (isc__socket_sendto2(sock, region, task, address, pktinfo, event, flags)); } void isc_socket_cleanunix(isc_sockaddr_t *sockaddr, isc_boolean_t active) { isc__socket_cleanunix(sockaddr, active); } isc_result_t isc_socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm, isc_uint32_t owner, isc_uint32_t group) { return (isc__socket_permunix(sockaddr, perm, owner, group)); } isc_result_t isc_socket_filter(isc_socket_t *sock, const char *filter) { return (isc__socket_filter(sock, filter)); } isc_result_t isc_socket_listen(isc_socket_t *sock, unsigned int backlog) { return (isc__socket_listen(sock, backlog)); } isc_result_t isc_socket_accept(isc_socket_t *sock, isc_task_t *task, isc_taskaction_t action, void *arg) { return (isc__socket_accept(sock, task, action, arg)); } isc_result_t isc_socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp) { return (isc__socket_getpeername(sock, addressp)); } bind9-9.10.3.dfsg.P4/lib/isc/Makefile.in0000644000470500017500000001144212664710322016764 0ustar lamontlamont# Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2003 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ @LIBISC_API@ @BIND9_MAKE_INCLUDES@ PROVIDER = @PKCS11_PROVIDER@ CINCLUDES = -I${srcdir}/unix/include \ -I${srcdir}/@ISC_THREAD_DIR@/include \ -I${srcdir}/@ISC_ARCH_DIR@/include \ -I./include \ -I${srcdir}/include @ISC_OPENSSL_INC@ ${DNS_INCLUDES} CDEFINES = @CRYPTO@ -DPK11_LIB_LOCATION=\"${PROVIDER}\" CWARNINGS = # Alphabetically UNIXOBJS = @ISC_ISCIPV6_O@ @ISC_ISCPK11_API_O@ \ unix/app.@O@ unix/dir.@O@ unix/entropy.@O@ \ unix/errno2result.@O@ unix/file.@O@ unix/fsaccess.@O@ \ unix/interfaceiter.@O@ unix/keyboard.@O@ unix/net.@O@ \ unix/os.@O@ unix/resource.@O@ unix/socket.@O@ unix/stdio.@O@ \ unix/stdtime.@O@ unix/strerror.@O@ unix/syslog.@O@ unix/time.@O@ NLSOBJS = nls/msgcat.@O@ THREADOPTOBJS = @ISC_THREAD_DIR@/condition.@O@ @ISC_THREAD_DIR@/mutex.@O@ THREADOBJS = @THREADOPTOBJS@ @ISC_THREAD_DIR@/thread.@O@ WIN32OBJS = win32/condition.@O@ win32/dir.@O@ win32/file.@O@ \ win32/fsaccess.@O@ win32/once.@O@ win32/stdtime.@O@ \ win32/thread.@O@ win32/time.@O@ # Alphabetically OBJS = @ISC_EXTRA_OBJS@ @ISC_PK11_O@ @ISC_PK11_RESULT_O@ \ aes.@O@ assertions.@O@ backtrace.@O@ base32.@O@ base64.@O@ \ bind9.@O@ buffer.@O@ bufferlist.@O@ \ commandline.@O@ counter.@O@ crc64.@O@ error.@O@ event.@O@ \ hash.@O@ heap.@O@ hex.@O@ hmacmd5.@O@ hmacsha.@O@ \ httpd.@O@ inet_aton.@O@ iterated_hash.@O@ \ lex.@O@ lfsr.@O@ lib.@O@ log.@O@ \ md5.@O@ mem.@O@ mutexblock.@O@ \ netaddr.@O@ netscope.@O@ pool.@O@ ondestroy.@O@ \ parseint.@O@ portset.@O@ quota.@O@ radix.@O@ random.@O@ \ ratelimiter.@O@ refcount.@O@ region.@O@ regex.@O@ result.@O@ \ rwlock.@O@ \ safe.@O@ serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ stats.@O@ \ string.@O@ strtoul.@O@ symtab.@O@ task.@O@ taskpool.@O@ \ tm.@O@ timer.@O@ version.@O@ \ ${UNIXOBJS} ${NLSOBJS} ${THREADOBJS} SYMTBLOBJS = backtrace-emptytbl.@O@ # Alphabetically SRCS = @ISC_EXTRA_SRCS@ @ISC_PK11_C@ @ISC_PK11_RESULT_C@ \ aes.c assertions.c backtrace.c base32.c base64.c bind9.c \ buffer.c bufferlist.c commandline.c counter.c crc64.c \ error.c event.c heap.c hex.c hmacmd5.c hmacsha.c \ httpd.c inet_aton.c iterated_hash.c \ lex.c lfsr.c lib.c log.c \ md5.c mem.c mutexblock.c \ netaddr.c netscope.c pool.c ondestroy.c \ parseint.c portset.c quota.c radix.c random.c \ ratelimiter.c refcount.c region.c regex.c result.c rwlock.c \ safe.c serial.c sha1.c sha2.c sockaddr.c stats.c string.c \ strtoul.c symtab.c task.c taskpool.c timer.c \ tm.c version.c LIBS = @ISC_OPENSSL_LIBS@ @LIBS@ # Note: the order of SUBDIRS is important. # Attempt to disable parallel processing. .NOTPARALLEL: .NO_PARALLEL: SUBDIRS = include unix nls @ISC_THREAD_DIR@ @ISC_ARCH_DIR@ TARGETS = timestamp TESTDIRS = @UNITTESTS@ @BIND9_MAKE_RULES@ safe.@O@: safe.c ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} @CCNOOPT@ \ -c ${srcdir}/safe.c version.@O@: version.c ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ -DVERSION=\"${VERSION}\" \ -DLIBINTERFACE=${LIBINTERFACE} \ -DLIBREVISION=${LIBREVISION} \ -DLIBAGE=${LIBAGE} \ -c ${srcdir}/version.c libisc.@SA@: ${OBJS} ${SYMTBLOBJS} ${AR} ${ARFLAGS} $@ ${OBJS} ${SYMTBLOBJS} ${RANLIB} $@ libisc-nosymtbl.@SA@: ${OBJS} ${AR} ${ARFLAGS} $@ ${OBJS} ${RANLIB} $@ libisc.la: ${OBJS} ${SYMTBLOBJS} ${LIBTOOL_MODE_LINK} \ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisc.la -rpath ${libdir} \ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \ ${OBJS} ${SYMTBLOBJS} ${LIBS} libisc-nosymtbl.la: ${OBJS} ${LIBTOOL_MODE_LINK} \ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisc-nosymtbl.la -rpath ${libdir} \ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \ ${OBJS} ${LIBS} timestamp: libisc.@A@ libisc-nosymtbl.@A@ touch timestamp installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${libdir} install:: timestamp installdirs ${LIBTOOL_MODE_INSTALL} ${INSTALL_LIBRARY} libisc.@A@ ${DESTDIR}${libdir} clean distclean:: rm -f libisc.@A@ libisc-nosymtbl.@A@ libisc.la \ libisc-nosymtbl.la timestamp bind9-9.10.3.dfsg.P4/lib/isc/symtab.c0000644000470500017500000001661512664710322016371 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1996-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include typedef struct elt { char * key; unsigned int type; isc_symvalue_t value; LINK(struct elt) link; } elt_t; typedef LIST(elt_t) eltlist_t; #define SYMTAB_MAGIC ISC_MAGIC('S', 'y', 'm', 'T') #define VALID_SYMTAB(st) ISC_MAGIC_VALID(st, SYMTAB_MAGIC) struct isc_symtab { /* Unlocked. */ unsigned int magic; isc_mem_t * mctx; unsigned int size; unsigned int count; unsigned int maxload; eltlist_t * table; isc_symtabaction_t undefine_action; void * undefine_arg; isc_boolean_t case_sensitive; }; isc_result_t isc_symtab_create(isc_mem_t *mctx, unsigned int size, isc_symtabaction_t undefine_action, void *undefine_arg, isc_boolean_t case_sensitive, isc_symtab_t **symtabp) { isc_symtab_t *symtab; unsigned int i; REQUIRE(mctx != NULL); REQUIRE(symtabp != NULL && *symtabp == NULL); REQUIRE(size > 0); /* Should be prime. */ symtab = (isc_symtab_t *)isc_mem_get(mctx, sizeof(*symtab)); if (symtab == NULL) return (ISC_R_NOMEMORY); symtab->mctx = NULL; isc_mem_attach(mctx, &symtab->mctx); symtab->table = (eltlist_t *)isc_mem_get(mctx, size * sizeof(eltlist_t)); if (symtab->table == NULL) { isc_mem_putanddetach(&symtab->mctx, symtab, sizeof(*symtab)); return (ISC_R_NOMEMORY); } for (i = 0; i < size; i++) INIT_LIST(symtab->table[i]); symtab->size = size; symtab->count = 0; symtab->maxload = size * 3 / 4; symtab->undefine_action = undefine_action; symtab->undefine_arg = undefine_arg; symtab->case_sensitive = case_sensitive; symtab->magic = SYMTAB_MAGIC; *symtabp = symtab; return (ISC_R_SUCCESS); } void isc_symtab_destroy(isc_symtab_t **symtabp) { isc_symtab_t *symtab; unsigned int i; elt_t *elt, *nelt; REQUIRE(symtabp != NULL); symtab = *symtabp; REQUIRE(VALID_SYMTAB(symtab)); for (i = 0; i < symtab->size; i++) { for (elt = HEAD(symtab->table[i]); elt != NULL; elt = nelt) { nelt = NEXT(elt, link); if (symtab->undefine_action != NULL) (symtab->undefine_action)(elt->key, elt->type, elt->value, symtab->undefine_arg); isc_mem_put(symtab->mctx, elt, sizeof(*elt)); } } isc_mem_put(symtab->mctx, symtab->table, symtab->size * sizeof(eltlist_t)); symtab->magic = 0; isc_mem_putanddetach(&symtab->mctx, symtab, sizeof(*symtab)); *symtabp = NULL; } static inline unsigned int hash(const char *key, isc_boolean_t case_sensitive) { const char *s; unsigned int h = 0; int c; /* * This hash function is similar to the one Ousterhout * uses in Tcl. */ if (case_sensitive) { for (s = key; *s != '\0'; s++) { h += (h << 3) + *s; } } else { for (s = key; *s != '\0'; s++) { c = *s; c = tolower((unsigned char)c); h += (h << 3) + c; } } return (h); } #define FIND(s, k, t, b, e) \ b = hash((k), (s)->case_sensitive) % (s)->size; \ if ((s)->case_sensitive) { \ for (e = HEAD((s)->table[b]); e != NULL; e = NEXT(e, link)) { \ if (((t) == 0 || e->type == (t)) && \ strcmp(e->key, (k)) == 0) \ break; \ } \ } else { \ for (e = HEAD((s)->table[b]); e != NULL; e = NEXT(e, link)) { \ if (((t) == 0 || e->type == (t)) && \ strcasecmp(e->key, (k)) == 0) \ break; \ } \ } isc_result_t isc_symtab_lookup(isc_symtab_t *symtab, const char *key, unsigned int type, isc_symvalue_t *value) { unsigned int bucket; elt_t *elt; REQUIRE(VALID_SYMTAB(symtab)); REQUIRE(key != NULL); FIND(symtab, key, type, bucket, elt); if (elt == NULL) return (ISC_R_NOTFOUND); if (value != NULL) *value = elt->value; return (ISC_R_SUCCESS); } static void grow_table(isc_symtab_t *symtab) { eltlist_t *newtable; unsigned int i, newsize, newmax; REQUIRE(symtab != NULL); newsize = symtab->size * 2; newmax = newsize * 3 / 4; INSIST(newsize > 0U && newmax > 0U); newtable = isc_mem_get(symtab->mctx, newsize * sizeof(eltlist_t)); if (newtable == NULL) return; for (i = 0; i < newsize; i++) INIT_LIST(newtable[i]); for (i = 0; i < symtab->size; i++) { elt_t *elt, *nelt; for (elt = HEAD(symtab->table[i]); elt != NULL; elt = nelt) { unsigned int hv; nelt = NEXT(elt, link); UNLINK(symtab->table[i], elt, link); hv = hash(elt->key, symtab->case_sensitive); APPEND(newtable[hv % newsize], elt, link); } } isc_mem_put(symtab->mctx, symtab->table, symtab->size * sizeof(eltlist_t)); symtab->table = newtable; symtab->size = newsize; symtab->maxload = newmax; } isc_result_t isc_symtab_define(isc_symtab_t *symtab, const char *key, unsigned int type, isc_symvalue_t value, isc_symexists_t exists_policy) { unsigned int bucket; elt_t *elt; REQUIRE(VALID_SYMTAB(symtab)); REQUIRE(key != NULL); REQUIRE(type != 0); FIND(symtab, key, type, bucket, elt); if (exists_policy != isc_symexists_add && elt != NULL) { if (exists_policy == isc_symexists_reject) return (ISC_R_EXISTS); INSIST(exists_policy == isc_symexists_replace); UNLINK(symtab->table[bucket], elt, link); if (symtab->undefine_action != NULL) (symtab->undefine_action)(elt->key, elt->type, elt->value, symtab->undefine_arg); } else { elt = (elt_t *)isc_mem_get(symtab->mctx, sizeof(*elt)); if (elt == NULL) return (ISC_R_NOMEMORY); ISC_LINK_INIT(elt, link); symtab->count++; } /* * Though the "key" can be const coming in, it is not stored as const * so that the calling program can easily have writable access to * it in its undefine_action function. In the event that it *was* * truly const coming in and then the caller modified it anyway ... * well, don't do that! */ DE_CONST(key, elt->key); elt->type = type; elt->value = value; /* * We prepend so that the most recent definition will be found. */ PREPEND(symtab->table[bucket], elt, link); if (symtab->count > symtab->maxload) grow_table(symtab); return (ISC_R_SUCCESS); } isc_result_t isc_symtab_undefine(isc_symtab_t *symtab, const char *key, unsigned int type) { unsigned int bucket; elt_t *elt; REQUIRE(VALID_SYMTAB(symtab)); REQUIRE(key != NULL); FIND(symtab, key, type, bucket, elt); if (elt == NULL) return (ISC_R_NOTFOUND); if (symtab->undefine_action != NULL) (symtab->undefine_action)(elt->key, elt->type, elt->value, symtab->undefine_arg); UNLINK(symtab->table[bucket], elt, link); isc_mem_put(symtab->mctx, elt, sizeof(*elt)); symtab->count--; return (ISC_R_SUCCESS); } unsigned int isc_symtab_count(isc_symtab_t *symtab) { REQUIRE(VALID_SYMTAB(symtab)); return (symtab->count); } bind9-9.10.3.dfsg.P4/lib/isc/hash.c0000644000470500017500000002526712664710322016020 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2013-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: hash.c,v 1.16 2009/09/01 00:22:28 jinmei Exp $ */ /*! \file * Some portion of this code was derived from universal hash function * libraries of Rice University. \section license UH Universal Hashing Library Copyright ((c)) 2002, Rice University All rights reserved. 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 Rice University (RICE) 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 RICE and the contributors on an "as is" basis, without any representations or warranties of any kind, express or implied including, but not limited to, representations or warranties of non-infringement, merchantability or fitness for a particular purpose. In no event shall RICE 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. */ #include #include #include #include #include #include #include #include #include #include #include #define HASH_MAGIC ISC_MAGIC('H', 'a', 's', 'h') #define VALID_HASH(h) ISC_MAGIC_VALID((h), HASH_MAGIC) /*% * A large 32-bit prime number that specifies the range of the hash output. */ #define PRIME32 0xFFFFFFFB /* 2^32 - 5 */ /*@{*/ /*% * Types of random seed and hash accumulator. Perhaps they can be system * dependent. */ typedef isc_uint32_t hash_accum_t; typedef isc_uint16_t hash_random_t; /*@}*/ /*% isc hash structure */ struct isc_hash { unsigned int magic; isc_mem_t *mctx; isc_mutex_t lock; isc_boolean_t initialized; isc_refcount_t refcnt; isc_entropy_t *entropy; /*%< entropy source */ size_t limit; /*%< upper limit of key length */ size_t vectorlen; /*%< size of the vector below */ hash_random_t *rndvector; /*%< random vector for universal hashing */ }; static isc_mutex_t createlock; static isc_once_t once = ISC_ONCE_INIT; static isc_hash_t *hash = NULL; static unsigned char maptolower[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; isc_result_t isc_hash_ctxcreate(isc_mem_t *mctx, isc_entropy_t *entropy, size_t limit, isc_hash_t **hctxp) { isc_result_t result; isc_hash_t *hctx; size_t vlen; hash_random_t *rv; hash_accum_t overflow_limit; REQUIRE(mctx != NULL); REQUIRE(hctxp != NULL && *hctxp == NULL); /* * Overflow check. Since our implementation only does a modulo * operation at the last stage of hash calculation, the accumulator * must not overflow. */ overflow_limit = 1 << (((sizeof(hash_accum_t) - sizeof(hash_random_t))) * 8); if (overflow_limit < (limit + 1) * 0xff) return (ISC_R_RANGE); hctx = isc_mem_get(mctx, sizeof(isc_hash_t)); if (hctx == NULL) return (ISC_R_NOMEMORY); vlen = sizeof(hash_random_t) * (limit + 1); rv = isc_mem_get(mctx, vlen); if (rv == NULL) { result = ISC_R_NOMEMORY; goto errout; } /* * We need a lock. */ result = isc_mutex_init(&hctx->lock); if (result != ISC_R_SUCCESS) goto errout; /* * From here down, no failures will/can occur. */ hctx->magic = HASH_MAGIC; hctx->mctx = NULL; isc_mem_attach(mctx, &hctx->mctx); hctx->initialized = ISC_FALSE; result = isc_refcount_init(&hctx->refcnt, 1); if (result != ISC_R_SUCCESS) goto cleanup_lock; hctx->entropy = NULL; hctx->limit = limit; hctx->vectorlen = vlen; hctx->rndvector = rv; if (entropy != NULL) isc_entropy_attach(entropy, &hctx->entropy); *hctxp = hctx; return (ISC_R_SUCCESS); cleanup_lock: DESTROYLOCK(&hctx->lock); errout: isc_mem_put(mctx, hctx, sizeof(isc_hash_t)); if (rv != NULL) isc_mem_put(mctx, rv, vlen); return (result); } static void initialize_lock(void) { RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS); } isc_result_t isc_hash_create(isc_mem_t *mctx, isc_entropy_t *entropy, size_t limit) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(mctx != NULL); INSIST(hash == NULL); RUNTIME_CHECK(isc_once_do(&once, initialize_lock) == ISC_R_SUCCESS); LOCK(&createlock); if (hash == NULL) result = isc_hash_ctxcreate(mctx, entropy, limit, &hash); UNLOCK(&createlock); return (result); } void isc_hash_ctxinit(isc_hash_t *hctx) { LOCK(&hctx->lock); if (hctx->initialized == ISC_TRUE) goto out; if (hctx->entropy != NULL) { isc_result_t result; result = isc_entropy_getdata(hctx->entropy, hctx->rndvector, (unsigned int)hctx->vectorlen, NULL, 0); INSIST(result == ISC_R_SUCCESS); } else { isc_uint32_t pr; size_t i, copylen; unsigned char *p; p = (unsigned char *)hctx->rndvector; for (i = 0; i < hctx->vectorlen; i += copylen, p += copylen) { isc_random_get(&pr); if (i + sizeof(pr) <= hctx->vectorlen) copylen = sizeof(pr); else copylen = hctx->vectorlen - i; memmove(p, &pr, copylen); } INSIST(p == (unsigned char *)hctx->rndvector + hctx->vectorlen); } hctx->initialized = ISC_TRUE; out: UNLOCK(&hctx->lock); } void isc_hash_init(void) { INSIST(hash != NULL && VALID_HASH(hash)); isc_hash_ctxinit(hash); } void isc_hash_ctxattach(isc_hash_t *hctx, isc_hash_t **hctxp) { REQUIRE(VALID_HASH(hctx)); REQUIRE(hctxp != NULL && *hctxp == NULL); isc_refcount_increment(&hctx->refcnt, NULL); *hctxp = hctx; } static void destroy(isc_hash_t **hctxp) { isc_hash_t *hctx; isc_mem_t *mctx; REQUIRE(hctxp != NULL && *hctxp != NULL); hctx = *hctxp; *hctxp = NULL; LOCK(&hctx->lock); isc_refcount_destroy(&hctx->refcnt); mctx = hctx->mctx; if (hctx->entropy != NULL) isc_entropy_detach(&hctx->entropy); if (hctx->rndvector != NULL) isc_mem_put(mctx, hctx->rndvector, hctx->vectorlen); UNLOCK(&hctx->lock); DESTROYLOCK(&hctx->lock); memset(hctx, 0, sizeof(isc_hash_t)); isc_mem_put(mctx, hctx, sizeof(isc_hash_t)); isc_mem_detach(&mctx); } void isc_hash_ctxdetach(isc_hash_t **hctxp) { isc_hash_t *hctx; unsigned int refs; REQUIRE(hctxp != NULL && VALID_HASH(*hctxp)); hctx = *hctxp; isc_refcount_decrement(&hctx->refcnt, &refs); if (refs == 0) destroy(&hctx); *hctxp = NULL; } void isc_hash_destroy(void) { unsigned int refs; INSIST(hash != NULL && VALID_HASH(hash)); isc_refcount_decrement(&hash->refcnt, &refs); INSIST(refs == 0); destroy(&hash); } static inline unsigned int hash_calc(isc_hash_t *hctx, const unsigned char *key, unsigned int keylen, isc_boolean_t case_sensitive) { hash_accum_t partial_sum = 0; hash_random_t *p = hctx->rndvector; unsigned int i = 0; /* Make it sure that the hash context is initialized. */ if (hctx->initialized == ISC_FALSE) isc_hash_ctxinit(hctx); if (case_sensitive) { for (i = 0; i < keylen; i++) partial_sum += key[i] * (hash_accum_t)p[i]; } else { for (i = 0; i < keylen; i++) partial_sum += maptolower[key[i]] * (hash_accum_t)p[i]; } partial_sum += p[i]; return ((unsigned int)(partial_sum % PRIME32)); } unsigned int isc_hash_ctxcalc(isc_hash_t *hctx, const unsigned char *key, unsigned int keylen, isc_boolean_t case_sensitive) { REQUIRE(hctx != NULL && VALID_HASH(hctx)); REQUIRE(keylen <= hctx->limit); return (hash_calc(hctx, key, keylen, case_sensitive)); } unsigned int isc_hash_calc(const unsigned char *key, unsigned int keylen, isc_boolean_t case_sensitive) { INSIST(hash != NULL && VALID_HASH(hash)); REQUIRE(keylen <= hash->limit); return (hash_calc(hash, key, keylen, case_sensitive)); } void isc__hash_setvec(const isc_uint16_t *vec) { int i; hash_random_t *p; if (hash == NULL) return; p = hash->rndvector; for (i = 0; i < 256; i++) { p[i] = vec[i]; } } bind9-9.10.3.dfsg.P4/lib/isc/sparc64/0002755000470500017500000000000012672612753016211 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/sparc64/Makefile.in0000644000470500017500000000166312664710322020252 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = include TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/sparc64/include/0002755000470500017500000000000012664710322017624 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/sparc64/include/Makefile.in0000644000470500017500000000165712664710322021700 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = isc TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/sparc64/include/isc/0002755000470500017500000000000012664710322020402 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/sparc64/include/isc/Makefile.in0000644000470500017500000000223012664710322022442 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ HEADERS = atomic.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \ done bind9-9.10.3.dfsg.P4/lib/isc/sparc64/include/isc/atomic.h0000644000470500017500000001012012664710322022017 0ustar lamontlamont/* * Copyright (C) 2005, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: atomic.h,v 1.5 2007/06/19 23:47:18 tbox Exp $ */ /* * This code was written based on FreeBSD's kernel source whose copyright * follows: */ /*- * Copyright (c) 1998 Doug Rabson. * Copyright (c) 2001 Jake Burkholder. * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. * * from: FreeBSD: src/sys/i386/include/atomic.h,v 1.20 2001/02/11 * $FreeBSD: src/sys/sparc64/include/atomic.h,v 1.8 2004/05/22 00:52:16 marius Exp $ */ #ifndef ISC_ATOMIC_H #define ISC_ATOMIC_H 1 #include #include #define ASI_P 0x80 /* Primary Address Space Identifier */ #ifdef ISC_PLATFORM_USEGCCASM /* * This routine atomically increments the value stored in 'p' by 'val', and * returns the previous value. */ static inline isc_int32_t isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) { isc_int32_t prev, swapped; for (prev = *(volatile isc_int32_t *)p; ; prev = swapped) { swapped = prev + val; __asm__ volatile( "casa [%2] %3, %4, %0" : "+r"(swapped), "=m"(*p) : "r"(p), "n"(ASI_P), "r"(prev), "m"(*p)); if (swapped == prev) break; } return (prev); } /* * This routine atomically stores the value 'val' in 'p'. */ static inline void isc_atomic_store(isc_int32_t *p, isc_int32_t val) { isc_int32_t prev, swapped; for (prev = *(volatile isc_int32_t *)p; ; prev = swapped) { swapped = val; __asm__ volatile( "casa [%2] %3, %4, %0" : "+r"(swapped), "=m"(*p) : "r"(p), "n"(ASI_P), "r"(prev), "m"(*p)); if (swapped == prev) break; } } /* * This routine atomically replaces the value in 'p' with 'val', if the * original value is equal to 'cmpval'. The original value is returned in any * case. */ static inline isc_int32_t isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) { isc_int32_t temp = val; __asm__ volatile( "casa [%2] %3, %4, %0" : "+r"(temp), "=m"(*p) : "r"(p), "n"(ASI_P), "r"(cmpval), "m"(*p)); return (temp); } #else /* ISC_PLATFORM_USEGCCASM */ #error "unsupported compiler. disable atomic ops by --disable-atomic" #endif /* ISC_PLATFORM_USEGCCASM */ #endif /* ISC_ATOMIC_H */ bind9-9.10.3.dfsg.P4/lib/isc/task_p.h0000644000470500017500000000237412664710322016355 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef ISC_TASK_P_H #define ISC_TASK_P_H /*! \file */ #if defined(ISC_PLATFORM_USETHREADS) void isc__taskmgr_pause(isc_taskmgr_t *taskmgr); void isc__taskmgr_resume(isc_taskmgr_t *taskmgr); #else isc_boolean_t isc__taskmgr_ready(isc_taskmgr_t *taskmgr); isc_result_t isc__taskmgr_dispatch(isc_taskmgr_t *taskmgr); #endif /* !ISC_PLATFORM_USETHREADS */ #endif /* ISC_TASK_P_H */ bind9-9.10.3.dfsg.P4/lib/isc/netscope.c0000644000470500017500000000447712664710322016715 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #if defined(LIBC_SCCS) && !defined(lint) static char rcsid[] = "$Id: netscope.c,v 1.13 2007/06/19 23:47:17 tbox Exp $"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include isc_result_t isc_netscope_pton(int af, char *scopename, void *addr, isc_uint32_t *zoneid) { char *ep; #ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX unsigned int ifid; #endif struct in6_addr *in6; isc_uint32_t zone; isc_uint64_t llz; /* at this moment, we only support AF_INET6 */ if (af != AF_INET6) return (ISC_R_FAILURE); in6 = (struct in6_addr *)addr; /* * Basically, "names" are more stable than numeric IDs in terms of * renumbering, and are more preferred. However, since there is no * standard naming convention and APIs to deal with the names. Thus, * we only handle the case of link-local addresses, for which we use * interface names as link names, assuming one to one mapping between * interfaces and links. */ #ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX if (IN6_IS_ADDR_LINKLOCAL(in6) && (ifid = if_nametoindex((const char *)scopename)) != 0) zone = (isc_uint32_t)ifid; else { #endif llz = isc_string_touint64(scopename, &ep, 10); if (ep == scopename) return (ISC_R_FAILURE); /* check overflow */ zone = (isc_uint32_t)(llz & 0xffffffffUL); if (zone != llz) return (ISC_R_FAILURE); #ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX } #endif *zoneid = zone; return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/isc/hmacmd5.c0000644000470500017500000002072512664710322016405 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2013-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: hmacmd5.c,v 1.16 2009/02/06 23:47:42 tbox Exp $ */ /*! \file * This code implements the HMAC-MD5 keyed hash algorithm * described in RFC2104. */ #include "config.h" #include #include #include #include #include #include #include #include #if PKCS11CRYPTO || PKCS11CRYPTOWITHHMAC #include #include #endif #ifdef ISC_PLATFORM_OPENSSLHASH void isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key, unsigned int len) { #ifdef HMAC_RETURN_INT RUNTIME_CHECK(HMAC_Init(ctx, (const void *) key, (int) len, EVP_md5()) == 1); #else HMAC_Init(ctx, (const void *) key, (int) len, EVP_md5()); #endif } void isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx) { HMAC_CTX_cleanup(ctx); } void isc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf, unsigned int len) { #ifdef HMAC_RETURN_INT RUNTIME_CHECK(HMAC_Update(ctx, buf, (int) len) == 1); #else HMAC_Update(ctx, buf, (int) len); #endif } void isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) { #ifdef HMAC_RETURN_INT RUNTIME_CHECK(HMAC_Final(ctx, digest, NULL) == 1); #else HMAC_Final(ctx, digest, NULL); #endif HMAC_CTX_cleanup(ctx); } #elif PKCS11CRYPTOWITHHMAC static CK_BBOOL truevalue = TRUE; static CK_BBOOL falsevalue = FALSE; void isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key, unsigned int len) { CK_RV rv; CK_MECHANISM mech = { CKM_MD5_HMAC, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; CK_KEY_TYPE keyType = CKK_MD5_HMAC; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_VALUE, NULL, (CK_ULONG) len } }; DE_CONST(key, keyTemplate[5].pValue); RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); ctx->object = CK_INVALID_HANDLE; PK11_FATALCHECK(pkcs_C_CreateObject, (ctx->session, keyTemplate, (CK_ULONG) 6, &ctx->object)); INSIST(ctx->object != CK_INVALID_HANDLE); PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object)); } void isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx) { CK_BYTE garbage[ISC_MD5_DIGESTLENGTH]; CK_ULONG len = ISC_MD5_DIGESTLENGTH; if (ctx->handle == NULL) return; (void) pkcs_C_SignFinal(ctx->session, garbage, &len); memset(garbage, 0, sizeof(garbage)); if (ctx->object != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx->session, ctx->object); ctx->object = CK_INVALID_HANDLE; pk11_return_session(ctx); } void isc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf, unsigned int len) { CK_RV rv; CK_BYTE_PTR pPart; DE_CONST(buf, pPart); PK11_FATALCHECK(pkcs_C_SignUpdate, (ctx->session, pPart, (CK_ULONG) len)); } void isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) { CK_RV rv; CK_ULONG len = ISC_MD5_DIGESTLENGTH; PK11_FATALCHECK(pkcs_C_SignFinal, (ctx->session, (CK_BYTE_PTR) digest, &len)); if (ctx->object != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx->session, ctx->object); ctx->object = CK_INVALID_HANDLE; pk11_return_session(ctx); } #elif PKCS11CRYPTO #define PADLEN 64 #define IPAD 0x36 #define OPAD 0x5C void isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key, unsigned int len) { CK_RV rv; CK_MECHANISM mech = { CKM_MD5, NULL, 0 }; unsigned char ipad[PADLEN]; unsigned int i; RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); RUNTIME_CHECK((ctx->key = pk11_mem_get(PADLEN)) != NULL); if (len > PADLEN) { CK_BYTE_PTR kPart; CK_ULONG kl; PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech)); DE_CONST(key, kPart); PK11_FATALCHECK(pkcs_C_DigestUpdate, (ctx->session, kPart, (CK_ULONG) len)); kl = ISC_MD5_DIGESTLENGTH; PK11_FATALCHECK(pkcs_C_DigestFinal, (ctx->session, (CK_BYTE_PTR) ctx->key, &kl)); } else memmove(ctx->key, key, len); PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech)); memset(ipad, IPAD, PADLEN); for (i = 0; i < PADLEN; i++) ipad[i] ^= ctx->key[i]; PK11_FATALCHECK(pkcs_C_DigestUpdate, (ctx->session, ipad, (CK_ULONG) PADLEN)); } void isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx) { if (ctx->key != NULL) pk11_mem_put(ctx->key, PADLEN); ctx->key = NULL; isc_md5_invalidate(ctx); } void isc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf, unsigned int len) { CK_RV rv; CK_BYTE_PTR pPart; DE_CONST(buf, pPart); PK11_FATALCHECK(pkcs_C_DigestUpdate, (ctx->session, pPart, (CK_ULONG) len)); } void isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) { CK_RV rv; CK_MECHANISM mech = { CKM_MD5, NULL, 0 }; CK_ULONG len = ISC_MD5_DIGESTLENGTH; CK_BYTE opad[PADLEN]; unsigned int i; PK11_FATALCHECK(pkcs_C_DigestFinal, (ctx->session, (CK_BYTE_PTR) digest, (CK_ULONG_PTR) &len)); memset(opad, OPAD, PADLEN); for (i = 0; i < PADLEN; i++) opad[i] ^= ctx->key[i]; pk11_mem_put(ctx->key, PADLEN); ctx->key = NULL; PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech)); PK11_FATALCHECK(pkcs_C_DigestUpdate, (ctx->session, opad, (CK_ULONG) PADLEN)); PK11_FATALCHECK(pkcs_C_DigestUpdate, (ctx->session, (CK_BYTE_PTR) digest, len)); PK11_FATALCHECK(pkcs_C_DigestFinal, (ctx->session, (CK_BYTE_PTR) digest, (CK_ULONG_PTR) &len)); pk11_return_session(ctx); } #else #define PADLEN 64 #define IPAD 0x36 #define OPAD 0x5C /*! * Start HMAC-MD5 process. Initialize an md5 context and digest the key. */ void isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key, unsigned int len) { unsigned char ipad[PADLEN]; int i; memset(ctx->key, 0, sizeof(ctx->key)); if (len > sizeof(ctx->key)) { isc_md5_t md5ctx; isc_md5_init(&md5ctx); isc_md5_update(&md5ctx, key, len); isc_md5_final(&md5ctx, ctx->key); } else memmove(ctx->key, key, len); isc_md5_init(&ctx->md5ctx); memset(ipad, IPAD, sizeof(ipad)); for (i = 0; i < PADLEN; i++) ipad[i] ^= ctx->key[i]; isc_md5_update(&ctx->md5ctx, ipad, sizeof(ipad)); } void isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx) { isc_md5_invalidate(&ctx->md5ctx); memset(ctx->key, 0, sizeof(ctx->key)); } /*! * Update context to reflect the concatenation of another buffer full * of bytes. */ void isc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf, unsigned int len) { isc_md5_update(&ctx->md5ctx, buf, len); } /*! * Compute signature - finalize MD5 operation and reapply MD5. */ void isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) { unsigned char opad[PADLEN]; int i; isc_md5_final(&ctx->md5ctx, digest); memset(opad, OPAD, sizeof(opad)); for (i = 0; i < PADLEN; i++) opad[i] ^= ctx->key[i]; isc_md5_init(&ctx->md5ctx); isc_md5_update(&ctx->md5ctx, opad, sizeof(opad)); isc_md5_update(&ctx->md5ctx, digest, ISC_MD5_DIGESTLENGTH); isc_md5_final(&ctx->md5ctx, digest); isc_hmacmd5_invalidate(ctx); } #endif /* !ISC_PLATFORM_OPENSSLHASH */ /*! * Verify signature - finalize MD5 operation and reapply MD5, then * compare to the supplied digest. */ isc_boolean_t isc_hmacmd5_verify(isc_hmacmd5_t *ctx, unsigned char *digest) { return (isc_hmacmd5_verify2(ctx, digest, ISC_MD5_DIGESTLENGTH)); } isc_boolean_t isc_hmacmd5_verify2(isc_hmacmd5_t *ctx, unsigned char *digest, size_t len) { unsigned char newdigest[ISC_MD5_DIGESTLENGTH]; REQUIRE(len <= ISC_MD5_DIGESTLENGTH); isc_hmacmd5_sign(ctx, newdigest); return (isc_safe_memequal(digest, newdigest, len)); } bind9-9.10.3.dfsg.P4/lib/isc/iterated_hash.c0000644000470500017500000000270712664710322017673 0ustar lamontlamont/* * Copyright (C) 2006, 2008, 2009 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: iterated_hash.c,v 1.6 2009/02/18 23:47:48 tbox Exp $ */ #include "config.h" #include #include #include int isc_iterated_hash(unsigned char out[ISC_SHA1_DIGESTLENGTH], unsigned int hashalg, int iterations, const unsigned char *salt, int saltlength, const unsigned char *in, int inlength) { isc_sha1_t ctx; int n = 0; if (hashalg != 1) return (0); do { isc_sha1_init(&ctx); isc_sha1_update(&ctx, in, inlength); isc_sha1_update(&ctx, salt, saltlength); isc_sha1_final(&ctx, out); in = out; inlength = ISC_SHA1_DIGESTLENGTH; } while (n++ < iterations); return (ISC_SHA1_DIGESTLENGTH); } bind9-9.10.3.dfsg.P4/lib/isc/tests/0002755000470500017500000000000012672612753016071 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/tests/regex_test.c0000644000470500017500000024707712664710322020415 0ustar lamontlamont/* * Copyright (C) 2013, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #include #ifdef HAVE_REGEX_H #include #endif #include #include #include ATF_TC(regex_validate); ATF_TC_HEAD(regex_validate, tc) { atf_tc_set_md_var(tc, "descr", "check isc_regex_validate()"); } ATF_TC_BODY(regex_validate, tc) { /* * test regex were generated using http://code.google.com/p/regfuzz/ * modified to use only printable characters */ struct { const char * expression; int expect; int exception; /* regcomp accepts but is disallowed. */ } tests[] = { { "", -1, 0 }, { "*", -1, 0 }, { ".*", 0, 0 }, { ".**", -1, 0 }, { ".*\?", -1, 0 }, { ".*+", -1, 0 }, { "+", -1, 0 }, { ".+", 0, 0 }, { ".++", -1, 0 }, { ".+\?", -1, 0 }, { ".+*", -1, 0 }, { "\?", -1, 0 }, { ".\?", 0, 0 }, { ".\?\?", -1, 0 }, { ".\?*", -1, 0 }, { ".\?+", -1, 0 }, { "(", -1, 0 }, { "()", 1, 0 }, { "(|)", -1, 0 }, { "(a|)", -1, 0 }, { "(|b)", -1, 0 }, { ".{", 0, 0 }, { ".{1", -1, 0 }, { ".\\{1", 0, 0 }, { ".{1}", 0, 0 }, { ".\\{1}", 0, 0 }, { ".{,", 0, 0 }, { ".{,}", 0, 0 }, { ".{1,}", 0, 0 }, { ".\\{1,}", 0, 0 }, { ".{1,\\}", -1, 0 }, { ".{1,", -1, 0 }, { ".\\{1,", 0, 0 }, { ".{1,2}", 0, 0 }, { ".{1,2}*", -1, 0 }, { ".{1,2}+", -1, 0 }, { ".{1,2}\?", -1, 0 }, { ".{1,2", -1, 0 }, { ".{2,1}", -1, 0 }, { "[", -1, 0 }, { "[]", -1, 0 }, { "[]]", 0, 0 }, { "[[]", 0, 0 }, { "[^]", -1, 0 }, { "[1-2-3]", -1, 0 }, { "[1-22-3]", 0, 0 }, { "[+--23]", 0, 0 }, { "[+--]", 0, 0 }, { "[-1]", 0, 0 }, { "[1-]", 0, 0 }, { "[[.^.]]", 0, 0 }, { "[^]]", 0, 0 }, { "[^^]", 0, 0 }, { "[]]\?", 0, 0 }, { "[[]\?", 0, 0 }, { "[[..]]", -1, 0 }, { "[[...]]", 0, 0 }, { "[[..5.]--]", -1, 0 }, { "[[.+.]--]", 0, 0 }, { "[[..+.]--]", -1, 0 }, { "[[.5.]--]", -1, 0 }, { "[1-[=x=]]", -1, 0 }, { "[[:alpha:]]", 0, 0 }, { "[[:alpha:]", -1, 0 }, { "[[:alnum:]]", 0, 0 }, { "[[:alnum:]", -1, 0 }, { "[[:digit:]]", 0, 0 }, { "[[:digit:]", -1, 0 }, { "[[:punct:]]", 0, 0 }, { "[[:punct:]", -1, 0 }, { "[[:graph:]]", 0, 0 }, { "[[:graph:]", -1, 0 }, { "[[:space:]]", 0, 0 }, { "[[:space:]", -1, 0 }, { "[[:blank:]]", 0, 0 }, { "[[:blank:]", -1, 0 }, { "[[:upper:]]", 0, 0 }, { "[[:upper:]", -1, 0 }, { "[[:cntrl:]]", 0, 0 }, { "[[:cntrl:]", -1, 0 }, { "[[:print:]]", 0, 0 }, { "[[:print:]", -1, 0 }, { "[[:xdigit:]]", 0, 0 }, { "[[:xdigit:]", -1, 0 }, { "[[:unknown:]]", -1, 0 }, { "\\[", 0, 0 }, { "(a)\\1", 1, 0 }, { "(a)\\2", -1, 1 }, { "\\0", 0, 0 }, { "[[][:g(\?(raph:][:alnu)(\?{m:][:space:]h]/r(\?<(\?=!(\?(\?!Nn(\?#])))", 0, 0 }, { "[(\?!(\?<=[^{,37}AAAA(AAAAAAAAAAAAA])", 0, 0 }, { "[^((\?(\?:ms(\?\?=[])p.]}8X[:blankcntrl:],{-119,94})XmF1.{)-)[:upperword:])[:digit:]{zg-q", 2, 0 }, { "[^[({(\?#254}))Z[l][x50]=444444444444(4444444444u[:punct:]\?[:punct:(\?!])])", 1, 0 }, { "[^[^[^([^((*4[(^((\?<=])Ec)", 0, 0 }, { "(0)Y:8biiiiiiiiiiiiiiiiiii", 1, 0 }, { "[^w(\?!)P::::::::::::::(\?#::(\?<=:::::::::]\"\"{}[3333333333333333(\?<=33333(\?!)9Xja][:alph(\?<=a:])xB1)(PX8Cf\?4444)qq[:digit:])", 1, 0 }, { "([U[^[^].]^m]/306KS7JJJJJJJJ{})", 1, 0 }, { "[^[^([^[(\?!(\?>8j`Wg2(\?{,(\?>!#N++++(\?@+(\?>l.]}))*\\BCYX]^W{52,123}(lXislccccccccccccccccc)-*)", 1, 0 }, { "(x42+,)7=]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]", 1, 0 }, { "[^(*[:graph:]q/TH\?B(\?{P)]})uZn[:digit:]+2", 0, 0 }, { "([XXXXXXXXXXXXXXXXXXXXX[(:alnum:][:space:]i%[:upperw(\?=o(\?#rd:])) ", 1, 0 }, { "(@@@@)", 1, 0 }, { "{-18,}[:as[(\?>^[cii:]]{}>+{-46,}{,95}[:punct:]{}99999999999999])-{-134}'sK$wCKjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj", 0, 0 }, { "(l[:alpha:(\?!]))", 1, 0 }, { "[[^(\?{]|JJ[:alph(a:]X{})B^][:lowerprint:]n-219{-32}{19,105}k4P}){,-144}", 0, 0 }, { "[[^]P[:punct:][:alpha:][:xdigit:]syh]|W#JS*(m<2,P-RK)cA@", 1, 0 }, { "([^((\?({\?<=)}){[^}^]{}])^P4[:punct:[]$)]", 1, 0 }, { "([(\?#:(\?{space:]}):{}{-242,}n)F[:alpha:]3$)d4H3up6qS[:blankcntrl:]B:C{}[:upperword:]r", 1, 0 }, { "([(\?:]))[:digit:]mLV.{}", 1, 0 }, { "[^PPP-[]{[,50}{128,}]111111111111111]p", 0, 0 }, { "[^([^([^([[^[([^[^[[2[[[[[[[[[[[[[^[[[[(\?(\?{:[[[[[[(\?([-[:ascii:]--*)", -1, 0 }, { ")!F^DA/ZZZZZZZZZZZZZZZZZZ", 0, 0 }, { "[[[[[[[((\?=\?(\?>([[[[[[[^[[[[(\?()[[[K(\?#))])))]7Y[:space:]{,-96}pP)[:ascii:]u{-88}:N{-251}uo", 0, 0 }, { "t[:x(\?<=digit:])eYYYYYYYYYYYYYYYYYY{,-220}A", 0, 0 }, { "[[({10,}[:graph:]Pdddddd(\?#X)])[:alnum:(]]L-C){,50}[:blankcntrl:]p[:gra(ph:]){66,}", 0, 0 }, { "[^[^]*4br]w[:digit(\?::]n99999999999999999)P[:punct:]pP", 0, 0 }, { "[:digit:]{67,247}!N{122})VrXe", 0, 0 }, { "[:xdigit:]^[:xdigit:]Z[:alnum:]^^^^1[:upperword:(\?=])[:lowerprint:]*JJ-", 0, 0 }, { "[[(\?imsximsx:^*e(){,3[6}](V~\?^[:asc(\?!ii:]I.dZ))]$^AAAAAAAAAAAAAAAAAAAAAAAA[:space:]k)]", 1, 0 }, { "W{,112}[:lowerp(\?R7~t'\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"9,O).", 0, 0 }, { "[^{6((\?>\?:4}(\?<=G))f)KKKKKKKKKKKKKKKKKKKKKKKKKKKKKpppppppp(\?=ppppp]{,-101}|[:blankcntrl:]Z{-182})", 0, 0 }, { "([:punct:]@^,,,,,,,,,,,,,,,,,,,,,,,,,,0\?:-o8NPIIIIIIIII)pPKKKKKKKKKKKKKKKKKKKK", 1, 0 }, { "([^[[^[^]]]])", 1, 0 }, { "[([^[(333\"(\?#\\\\[)(\?isx-x:\"Tx]')", 0, 0 }, { "[[n>^>T%.zzzzzzzzzzzzzzzzz$&|Fk.1o7^o, ^8{202,-12}$[:alnum:]]G[:upperword:]V[:xdigit:]L|[:upperword:]KKKKKKKKKKKKYX\"\")xJ ~B@[{,-68}/][:upperword:]QI.", 0, 0 }, { "[^[]tN^hy3\"d@v T[GE\?^~{124,10(\?{2}]})\?[:upperword:]O", 0, 0 }, { "d.``````````````````````````[:up(\?=perword:]RRRRRRRRRRRRRRR)", 0, 0 }, { "[Z{{{{{{{{{{{{{(\?={(\?{{J6N:H[tA+mN3Zmf:p\?]\?){-181,82}S4n.b[:lowerpri(\?{nt:]|ggggggggggggggggggggggggggggggg}))4)", 0, 0 }, { "[^((/////[^////[^/////////[(^/////]fI{240}{-120}+]R]GA)", 0, 0 }, { "[-(\?#.)(\?())[:alpha:](\?={(\?#}r)[:space:]PPW]o)", 0, 0 }, { "[:lowerp(\?{rint:]})201{46,}[:a[^scii:]0Q{37,}][:blankcntrl:]1331", 0, 0 }, { "[^(\?!(\?#)\\GIwxKKKKKKKKKK'$KKKKKKKK]l)bbb^&\?", 0, 0 }, { "[:ascii:]*[:sp(\?<=ace:])", 0, 0 }, { "({-66,}Z{})0I{-111,}[:punct(\?():])", 1, 0 }, { "[[^(\?!()%%%%%%%%%%%%%(\?:%%%%%%%%%%%%%%%%)t(\?{VX>B#6sUU(\?BBBZvvvvvvvvvv(\?m(sximsx:vvv)iiiiiiii)))j>Rs:Sm]0MMMMMMMMMMM|@F)Y]*^#EEEEEEE)*", 0, 0 }, { "([^([(U(\?!)<<<<<<<<<<(\?#<<<<(\?(\?#){}]{}`){1,82}){-143[,}]^G", 0, 0 }, { "[:digit:]W|[:up(\?@]", 1, 0 }, { "[^[^[(\?imsximsx::p(\?{unct:][(\?>:ascii:]5w)]{159}\\Q\?@C]4(44444444}[^)|)[:graph:]]C:b)", 1, 0 }, { "[^[[(tYri[W<8%1(\?='yt][:lowerprint:[]))1r]][:alnum:][:digit:]{48}{-52,-183}+][:alpha:]r][:upperword:]\?{-105,155}{-55,-87}pPN#############################{63,232}]", 0, 0 }, { "[*(\?>L(\?<(\?>=))]&&&&&&&(&&&&&&&&&&&&&&&&&&))[|WIX]{-62,-114}S K=HW60XE<2+W", 1, 0 }, { "(00000000000)z\\\\*t{}R{88}[:alnum:]*", 1, 0 }, { "(([^(\?=\?gggggg[gLw)]{-250,}[:xdigit:]yZ[:g(raph:]8QNr[:space:][:blankcntrl:]A)][:digit:]D)[:xdigit:])", 2, 0 }, { "[^([^,(\?s8.>[^{}$(\?(]]XXXXXXX)XXXXXXXXXXXXXX[:alpha:]Whii\?p[:xdigit:])+", 0, 0 }, { "(7777[:blankcntrl:])", 1, 0 }, { "[^C[:digit:]]{}YYYY(YYYYYYYYYYYYYYYY)", 1, 0 }, { "on|,#tve%F(w-::::::::::::::::::::::::::::*=->)", 1, 0 }, { "([((\?=(\?!((\?=')))27(<{})S-vvvvvvvvvv(\?=vvvvvvvvvvvvvvvvv[:punct:][:alnum:]}}}}}}}}}}}}}}}}}}}}}}}PPPPPPPPPPPPPPPPPPPPPPPPPPPPPgggggggggggggggggggggggggg(\?#(\?#gggggg+))uQ)W>[:punct:][:xdigit:][:digit:][:punct:]{}[:digit:][:space:]){,-105}=xiAyf}o[:alpha:]akZSYK+sl{", 1, 0 }, { "[^[^]/S:Hq<[:upperword:(\?<=]W[:alnum:]X])1973", 0, 0 }, { "[[^[[^([^VVVV(\?!(VVVVVVVVVVVVVVVVVVVVV[VVVVX][^]2))98ppppppppppppppppppppppppppppppp/////////////////////b.]G{-101,}[:[ascii:]P].=~])AAAAAAAAAAAAA2{-153,}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]][:alnum:][:lowerprint:]WN/D!rD]|4444{180}]V_@3lW#lat]", 0, 0 }, { "[^[^([^TTTTT(\?:T(\?:T7777{,59}])[:graph:][:ascii(\?<=:]))f]AD{,-43}%%%%%%%%%%%%%%%%)S|[:digit:]FZm<[:blankcntrl:]QT&xj*{-114,}$[:xdigit:]042][:xdig[it:]{-180}027[:alpha:][:ascii:][:lowerprint:][:xdigit:]^|[:alnum:][^Mi]z!suQ{-44,-32}[:digit:]]", 0, 0 }, { ")", 0, 0 }, { "''''''''''[:a(\?imsxisx:lnum:])P", 0, 0 }, { "(([{20(\?<=8}[:alnum:]pP$`(\?#N)wRH[:graph:]aaaaaaaaaaaaaa(\?=aaaaaaaaaaaaaaaaP]a)))[:punct:]-\?)A^", 2, 0 }, { "[^(.//[:punct:]&-333333333333333333333333333(\?W90DDDDDDDDDDD[^DDDDDDDDDDDDDDDDDDDD]B[:punct:]c/", 1, 0 }, { "[^(\?]|)p1EmmmmmmmmmmmmmmmmmmmmmmmmmmmmL{-241}666666666666666666666)]^bLDDDDDDDDDDDDD]", 0, 0 }, { "[nn(\?1((\?>\?#45)Z{,108}{}11111111111111111111111111qqqq)\?][:lowerprint:]mbo#)@", 0, 0 }, { "[^iii8(888888(\?(\?=)]]T()[:bl(\?!ankcntrl:]=jjjjjjjjjjjjjjjj-)))t{}[:alpha:]-\":i! Gn[A4Ym7<<<<<<<<<<<<<<<<]", 2, 0 }, { "^{}{[^,241(\?#}(\?m(\?ixim:sximsx:]t))+oD)", 0, 0 }, { "5[(\?#:xdigit:])", 0, 0 }, { "[^f{(\?>,22(9}[^[^])6KKKKKKKKKKKKK)]RRRRRRRRfuK99999999C}osnNR]BgCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC[:blankcntrl:]", 0, 0 }, { "[^(\?=U){24,}W-{,17(\?:3[^}]q.nQ#PU_|i$$$$$$$$$$$$$$+)[:dig(\?4^4ta[:alpha:]", 0, 0 }, { "(((b0HN)q))p5X)uH]$})354b[:alnum:]]]EVVVVVVVVVVVVVVVVVVVVVVVVVVVVVz[:digi(\?(t:][:upperword:])", 1, 0 }, { "([:blankcntrl:]t-){121,}[:ascii:]444444{}[:graph:]E040", 1, 0 }, { "[^{134,}]DzQ\?{-30,191})z,\?1Vfq!z}cgv)ERK)1T/=f\?>'", 0, 0 }, { "@v)))])Y]|){,10}\?{}", 0, 0 }, { "([[[(\?!^]P-AA[AAAAAA[A[^A)r]+B]])", 1, 0 }, { "3}|[:ascii:][:punct:]()", 1, 0 }, { "()dw", 1, 0 }, { "[N]{})))))))))))))))))))))))", 0, 0 }, { "[[[^([[(\?()(\?#)++([^\?{+++[^+++++++++++(\?!+(\?=+++++++r9/n]N7{-219}{-91}pP[:punct:]T]mROm+~[:digit:][:digit:])Y:", 0, 0 }, { "[^'Pu[(\?~\?N|z#Ar--SO{,-141}076)G\?{,-110}M+-[:alpha:]", 0, 0 }, { "{,-214}{,10(9})", 1, 0 }, { "([^xxxxxxxxxxxxxxxxxMMMMMMMMMMMMMMXW])].[:punct:]Q`{-63,63}Uua[:alnum:]\?OQssb#L@@@@@@@@(@@@)[:graph:]", 2, 0 }, { "[[^(\?!```[^``````````````(\?<=``(\?>````````M/////(\?!////////////////////[^GD!|#li]~)*.$]))Tq!]C[:lowerprint:]Qk[{}]]JJJJJJJJJJJJJJJJJJJJJJJ{e])c", 0, 0 }, { "$[5(7ES])[:xdigit:]%{MRMtYD&aS&g6jp&ghJ@:!I~4%{P\?0vvvvvvvvvvvvvvvvvvvv\\\\\\\\\\\\\\\\\\\\\\\\x54[:lowerprint:][:upperword:]", 0, 0 }, { "[((([(\?((\?>[:alnum:][):as(\?{,-49})q${98,}J\?]){", 0, 0 }, { "([:pu(\?(nc)t:]F{-32,-102}+)\?cpP[:lowerprint:].^)", 1, 0 }, { "([{}{210,-238}]1:h)", 1, 0 }, { "([]QQQQ[QQQQQQQQQQQQQQQQQQ][:digit:]Z{-20,}Slllllll[:space:]C^(@{-174,-156}fx{cf2c}{-242,}rBBBBBBBBBBBBBBBBBBc[:alpha:]N\?))$[:graph:][:ascii:]P+nnnnnnnnnnnnnnnnnnnnnnn1N$r>>>>>>>>>>>>>>>>>>>>>>>>(>>{,88}{,-234}__________)[:upperword:]R.[:alnum:][:lowerprint:]^}\"", 3, 0 }, { "([^(\?=]-))$", 1, 0 }, { "([:ascii:]\?,D[:upperword:][:xdigit:]tttttttttttt[^tt(\?{,10}[(\?<=:xdigit:]))PL9{-89,-181}F'''''''''", 1, 0 }, { "[^.|(\?{af]})^$XE!$", 0, 0 }, { "(WWWWWWWWWWWWWWWWWWWWWWWWWWWW#J)", 1, 0 }, { "({}}M7we-216)L[:digit:][:upperword:]", 1, 0 }, { "([:aln[^u(\?=m:]))].z", 1, 0 }, { "([:alpha:]{(92})%6{41,136})Vij@[:alnum:][:lowerprint:]", 2, 0 }, { "[[[++(\?{+++{}})n{{137,}{51,-177}Z[]M*[:ascii:]{(-29,-47}2)$e^{,-195}{-156,}^]{}{-225,69}A]{-222,}{,20}m[:blankcntrl:]", 1, 0 }, { ")l)[:alnum:][:graph:]g8TTTTTTTTTTTTTTTTLLLLLLLLLLLLLLLLL", 0, 0 }, { "[([(\?<=.(\?{)/})mmmmmmmm(\?(mmmmm]{-154,-176}*S)I]", 0, 0 }, { "[(([{(\?(\?[:lowerprint:][:ascii:]e-]]]]]]]]]]]]]]]]]]]]]", 0, 0 }, { "[^({}(){(66(\?=,}[^]'''''QQQQQQQQQ).P#>^){86,168}Z[(\?Q{,147}_____________(\?!______uuuuuuuuuuuuuTr]){74,179}{}){,103}{-209,16}*RRRRRRRRRRRRRRRRw{,87}9{144}[:ascii:]'(\?raph:])^)Ny6RF_ndoU9@*rxW{4,41}4{}", 0, 0 }, { "[:punct:]{162,}j[:aln(um:].....................[^...]\?>z[:l[owerprint:]){55,222}]", 0, 0 }, { "(>vWa)OXcccccccccccccccccccccccc[:alpha:]C{,-10}81|m1D^T)[:lowerprint:]''''[:alpha:]l", 1, 0 }, { "(XZcgM/UI-/mZq-222){-85,-196}[:alpha:]{114}rrrrrrrrrrrrrrrrrrrrrrrr{,157}ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZLkD-&&&&&&&&&&&&&&&-][:alnum:]{}{,111}[:digit:]", 1, 0 }, { "[^(\?:]MMMMMMMMMMMMMMMMMMMMMMMMMMM)cK[KKKKKKKKKKKKKKKKKKKKKKKK]P{146}", 0, 0 }, { "([^[^wqesa)n\?L(\?<=FH+G[^rCGmfD]w)m1D\"%}]])", 1, 0 }, { "[((\?:[^.HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH|S)xd)*[:space:](])[:xdigit:]ngr'G#/B]-----------------------------", 0, 0 }, { ")[:lowerprint(\?<=(:]l))G p", 0, 0 }, { "[^[^(\?<(\?<(=(\?imsximx:![(((\?", -1, 0 }, { "Nvvv[vv.][:alnu[^m:]+|Crrrrrrrrrrrrrrrrrrrrr[:xdigit:]j1n)v#]", 0, 0 }, { "[^#}[(\?>:alnum:]).QQQQ[^QQQQQQ!!![!!!!!!!-s.n]se]{-238,}Tf]p4721", 0, 0 }, { "([((\?#\?<=)+)Hr:-H]z[:graph:].{}oooooo(ooooooooo][:punct:]k}}}}}}}(}}}}}\?310[|))xA5r][[^:ascii:]^{,-156}{])CCCCCCCCCCC-145]FzwOD_u\?", 1, 0 }, { "[^[^[]{-163}{(-203}[(\?!:upperword:]PPGjZ[:xdi(\?=git(\?#:]{-73}s)qqqq(qqqqqqqqqqqqqqqqqq{173,210}[:xdigit:(\?<(\?>=]WW[^WWWWWWW\?*O)))Q){}08)[(\?(\?<=#:blankcntrl:]{90,}]U)])L)ooooooooooooooooooooooooooox--^c[:ascii:]])s)", 2, 0 }, { "[(\?!:punc(\?imximx:t[^:]4F<}!)]'M-)tKKKa4904", 0, 0 }, { "[^^{}\\(\?)T000000000(\?(000)00000))+])", 0, 0 }, { "L[:p(\?#unct:])", 0, 0 }, { "[:upperw(\?<[^U/)]]{}X3333333333(3333333f*])", 1, 0 }, { "<<<<<<<<<<<<<<<[^<<<<<<<<<.][(\?#:ascii:])[:xdigit:]|^", 0, 0 }, { "([:punct:]{}){-167,}{-59,}Pd\"", 1, 0 }, { "[((\?#{,214})t$)VVV[:xdigit:]{104(\?<=}D][:graph:])|H){1,}{-176,}", 0, 0 }, { "[[([[^N,,,,,(\?=,,(\?#(\?:,,,,,,,,,,,[^,,,,,,,,,,]<,~4::_.A]){-52,}-[:alnum:]Pnnnnnnnnnnnnnnnnnn)d", 0, 0 }, { "{-18(3,})uT{4,}", 1, 0 }, { "[^[^[(p+c(\?:])[])][:s[^pace:]][:alnum:][:alpha:]]kw06E", 0, 0 }, { "[^^^^^^JJJJJJJJ(JJ(\?=JJ(.6[:space:]H]{231,}A^eqqq)[:ascii:(\?>(])[(\?>:spa(\?:ce:]xxxxxxxxx)@_t-))138GNNNNNNNNNNNNNNNNNNNNNNNNNN[:digit:]no!`#E\?&[:lowerprint:].)[:graph:]{86,}[:digit:][:alnum:]", 0, 0 }, { "[:g(\?<=raph:]a{114,146}(){}0Y[:bl(ankcntrl:])D)\?", 1, 0 }, { "[^[^]*H{-192,96}S|]G)6B-kLB", 0, 0 }, { "[[^[^][/NS8`um(\?{82&{((\?{\?DW>9tN%{113}{unE", 0, 0 }, { "[:(\?(alpha:]`))Y2sCqWQ104", 0, 0 }, { "(([^()Wcccccccc(\?{cccccccccccccccccc(\?)FZ{}{}`|||||||||||||*````````````````````````````'=dLQmx/Y.A7j'o}jn{}:})][:punct:]$|,-)!&Y:Ys#ykL7JJJJJJJJJJJJJJJJJJJJJJJJJ8yex>#mv[:punct:](x@)$[:uppe(\?9))i})]a!lBW3p{A=or)ShE%[:punct:]{}]5r", 0, 0 }, { "[:pu[nc[^t:]]]}}}}}}}[}}}}}}}(\?#}])@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDD\?]xA2\?", 0, 0 }, { "(.[:alpha:]xB7[:alnu(\?{m:]})RRRRRRRRRRRRRRRRRRRRRRRRRRRL)[:space:]G\?", 1, 0 }, { "[:blan(\?cii:])[:alnum:]$$$$$[:space:]3$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$1", 0, 0 }, { "[[$zQ================(\?=========(\?====D[^))|i{}\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?)][:s(pace:]]))]", 0, 0 }, { "[^{,-[15(\?#6}]Vwjjjjjjjj[jjjjjjjjjjjjjjjjjjS9999)]q]rWWWWWWWWWWWWWWWW[:punct:]@@@@@@@@@@@@@@@@@@@@@@@@gO[:blankcntrl:]>L[:ascii:]:::::::::::::::::::x11uuuuuuuuuuuuuuuuuuuuuuuuuuuuu{-124,114}[:graph:]C#{tcg[:xdigit:]gZZZZ[:lowerprint:]nA(_{{{{{{{{{{{{{{{{{{{{SS)\\D[:alpha:]", 1, 0 }, { "[^(\?())]!T\?[:asc[^ii:]E:4},,]I[^b(\?:n4(njj~+{\?'k{7}{189,-194}{ig.[[[[[[(\?#[[[_bs6,JD`1(\?>>>>>>>>>>>>>>>>>>>>>>>>>>>[^>>>(\?(>)){,-165}]", 0, 0 }, { "([^[][^n(\?{[[p]#})|][^]L|66666666666[:graph:]][:graph:]2[:xdigit:][:space:]9b})[:digit(\?imsximsx::]+PZ):{}|E)[:xdigit[^:]|>]^[:alpha:]::::::::[:ascii:]````[:ascii:]:", 1, 0 }, { "[:lowerprint(\?t|LQT(|)L[(:ascii:])", 0, 0 }, { "[^[^([:graph:](QpPdyDQ`[:alpha:](.X[:digit:]wwwwwwwwwwwwww(\?imxims:wwwwwwwe(\?)*d2K0DNX5)T(].)[:digit:].", 0, 0 }, { "([:punct:(\?#])})JJJJJJJJ[:xdigit:]PPUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU.......................0hSk{,89}[:xdigit:].[:xdigit:]Z", 1, 0 }, { "(LGTTTTTTTTTTTTTTTTTTTTTTTTTT[:alpha:]){-106,113}[:punct:]d|[:digit:]kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\?wP", 1, 0 }, { "([^[^Sow", 0, 0 }, { "{-179}^[:alpha:(\?!].a'5wacA3\\\\\\\\AAAAAAAA)~^]wC", 0, 0 }, { ">[:digit:]{,-212}+(`)LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL[:ascii:][:digit:][:space:]", 1, 0 }, { "[[^[[^RBW{,255(}(\?(\?>=(W)_]uu][:blankcntrl:])O)]]", 0, 0 }, { "(C_______________________________)2", 1, 0 }, { "([/ntf_a3].)", 1, 0 }, { "[:space:]+[(:upperword:],c7[:asci(\?<=i:]ggggggggggg)[:ascii:]/1$$$$$$$$$$$$$$$$$$$$$$$$$$)", 0, 0 }, { "Xq{109}~EEEEEEEE[:upper[^word:]lgB:X(h[:alpha:]B[:space:]].)IkaH@3}}H'yK~\?[:upperw(\?#ord:(\?:]){=================[:blankcntrl:])", 1, 0 }, { "(([[^]]$3Xr^$%%%%%%%%%%%%%%%%%%%%%================U[:ascii:])X).FFFFFFFFFFgO[:punct:]oooooooooooooooooooBC[:blankcntrl:]mmmmmmmmmmmmmmmmmmmm[:lowerprint:]rBM~rERRRRRRR[^RRRRR(\?>RRRRR])[(\?=^)X]{207,}U])))Z[:blankcntrl:]]yyyyyyyyyyyyyyyy\?", 1, 0 }, { "[Q(\?{*[^(\?(\?!!])[:graph:]]})[:alnum:]iE)dGGGGGGG[^GGGGGGGGGG[:xdigit:]w]", 0, 0 }, { "[^Z(\?!6(\?(\?><=)[:graph:])]BBBBBBBBBBBBBBBB^)", 0, 0 }, { "[[^([^[^][[[[[[[(\?({[[(\?(\?imsxmsx(\?imsi[ms:::[[[[[[[[[}))]$)){12,})|:::::::::::::::::::[:lowerprint:]{}{-96,-147}){13,}`[:digit:]]\"^Ca%%%%%%%%%%%%%%%%%%%%%%%%%%UUUUUUUUUUUUUUUUUU]]9", 0, 0 }, { "[^(\?(\?(\?#!<=))JLBS\"zi)'''''''''''['''''''''''''piiiiiiiiiiiii(\?<=iiii]])ZZZZZZZZZZZZZZZZZZ[:space:]", 0, 0 }, { "({})[:punct:]", 1, 0 }, { "E9[:blankc(\?{ntrl:]})N", 0, 0 }, { "[:alph(\?#a:]){198,}sq\?X0B7", 0, 0 }, { "[^\\\\\\\\(\\\\\\[\\\\\\\\\\\\[(\?<(\?isximsx:={11(\?(9,}\?0])]]))\?FN3M\?{-128,}Z444444)444fbLiVN8)", 0, 0 }, { "[[^[^([[[[[[[[[(\?>[[[[[[[[[[[[[[[[[[[[[{53(\?<=,-175(\?>}ggggggggggggggggg%))[:alnum:])[:punct:]kkkkkkkkkkkkkkkkkkkkkkkkk)+Soooooooooooooooooooooooooooooooo](WR+--)x36+llllllllllll{,35}]Fqb^=F]KKKKKKaaaaa{,131}", 1, 0 }, { "(g\"Ssqw<&{Cl{82,}Mdf|9cIlmCW{}[:digit:]4C{}[:alnum:]PP)", 1, 0 }, { "OOOOOOOU[*evVIIIIIIIIIIIIIIIII(\?#(\?#IIII)]PP[:xdigit:]2222222222222222[:xdigit:]Kx)p[:digit:]", 0, 0 }, { "([[{248,16(\?=5(\?#}][:alpha:])|[:p(\?!unct:(\?(]", 1, 0 }, { "[pP((\?=S)(\?#)]$[:aln(\?(um:)]2\?)$GGGGGGGGGGGGGGGGG({-U:c){-61,}[:ascii:]{-202}G", 1, 0 }, { "()$D[:alnum:]", 1, 0 }, { "[(\?#^]){}[:ascii:]", 0, 0 }, { "[uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu]FFFFFFFFFFFFFFFFFFFFFF&2e\?)%oP'mc@z2b}n{xisx:)UHpP*n{}]{}fx14<7OEpE>n2150)8888888888888888]^GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGS", 0, 0 }, { "(d)+", 1, 0 }, { "[^.(\?(>)(\?=e)])al[:space:]x", 0, 0 }, { "[^256c(\?!]){-19,}", 0, 0 }, { "Q)", 0, 0 }, { "[^s\?\?(\?{\?\?\?(\?#\?(\?cii:])){-107,-139}6/{^[:upperw(\?imsxmsx:ord:]{,-47} ]wuH#nAn)GGGGGGGGGGGGGGGGGr[)]T{91}lJ))[:lowerprint:][:xdigit:][:lowerprint:])]*", 1, 0 }, { "()[:space:]~!$[:alnum:]JJJJ[:ascii:]", 1, 0 }, { "[^(\?<=)-]()k", 1, 0 }, { "(()W){,8}ea", 2, 0 }, { "({,-56}5G&&&&rrrrrrrrrrrrrrrrrrrrrrrrrrk.8) hWJ,TM)0Yd-", 1, 0 }, { "(Z-fddddddddddddddddddddddd)-{9}", 1, 0 }, { "[^<[(\?!:asc(\?:i(\?2!+[:punct:(\?qQ[^]e[:ascii:]PP()[:digit:]NQ8%6d=&2I{-62,-142}w]].e{}*", 1, 0 }, { "{,-219}xxxtEEEEEEEEEEEEEEEE[:pun(\?(ct:])qqq)nnnnnnnnnnnnnnnnnnnnnnnnnnn", 0, 0 }, { "[:di(\?>git:])W4", 0, 0 }, { "([^y])Fkvto$", 1, 0 }, { "[^($$$$$$(\?!$$$$$(\?{$$$$$$(\?<=$$$$$$$$$$$+===)[:alnum:]MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM)Z]{}^[:blankcntrl:]--xxxxxxxxxxxxxxx[^xxxxxxx)\?tVG\?{232,81}{121,}xn{,-226}})tttttttttttttttttttttttmu(\?[:digit:]S[:space:]t", 0, 0 }, { "()n", 1, 0 }, { "[:upp(erword:]$)<}.vZM)rCD&{5(\?msxisx:7,}qqqqqqqqqqqqqqqqqq{31,}@w#W:(@(\?:zp$YYYYA[:alpha:]{1}A)*dZJ\"5OG|\?(\?#a])]|){-150}[:xdigit:]", 0, 0 }, { "[($)gwo{`\"]{-160,}\\\\\\\\\\\\\\\\\\\\\\\\\\66666666666666888888888888", -1, 1 }, { "((}DA+Rc000000000000000000)%vvvvvvvvvvvvvvvvvvvvv%C&emZ*[:alnum:]#m/D[:graph:][:blank[^cntrl:]E{,168})kkkkkkkkkk000000000000000]", 2, 0 }, { "[^[u*(\?#x01234)oxGGGGG(\?([GGGG)GGGGGGGGG]^U)!!CCCCBM`4QB^XEN]{,-60}[:upperword:]G]", 0, 0 }, { "(%)~t{S,K^MI3PMo)=b", 1, 0 }, { "[[[^]{}eU([:xdigit:]&&&&&&&&&&&&&&&&&)\"W|43[:alpha:][:graph:]J8b[:blankcntrl:]gggggQ{,183}{,-254}\?[:ascii(:]{,134}", 1, 0 }, { "[[([^[^([^(\?=)1RRRRRRRRRRRRRRRRRRRRRR(\?:(\?(\?(\?!=#RRRRR(\?=RRRR(\?<[^!Ru)])]o[:[graph:[^]{,7})[:digit(\?::]{-215,}e[:space:]]", 0, 0 }, { "({{{{{{{{{{{{{{{{{{KKKKKKKKKKKKKKKKKKKKKKKKKKKKBBBBBBBBBBBB)[:space:]0[:alnum:]HcctQA", 1, 0 }, { "[^(pP7(HsN[^g{186,-87}\?\?]EQ%u:-Y)+>>>>>>>>>>>>>>>>>>>>>pP][:alpha:]", 0, 0 }, { "[(.{141}h|)((\?:\?=@Q} ghcC{+*(R)D+][:lo(\?#werprint:]zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz))", 0, 0 }, { "[^({}S)PPFl(])-216", 0, 0 }, { "[([[^(((([(\?#^[^[^\?4[(:[dig[^it(\?(:]{122,})y\?", 0, 0 }, { "[[2${188}u{1(4(\?(1,1(\?{98}e{&tbaoI]q)[:punct:])d}))Nqffffffffffffffffffffffffffff[:ascii:]+]", 0, 0 }, { "()K-", 1, 0 }, { "[[{2(2((\?(\?!()2})])[:alpha:]fVVVVVVVVV{-47}):::::::::::)\?vwyyyyyyyyyyyyyyyyyyyyyyyyy-]{}", 0, 0 }, { "ivcs)g", 0, 0 }, { "(hhhh[^hhhh(\?{h\?]})%%%%%%%%%%%%%%%)\"+38mbY:s9{/d# zaNnbQb)b:*zpKI{-26,-189}", 1, 0 }, { "S*(#)[:graph:]lllllllll&G)t", 1, 0 }, { "([^[(([\?=\?\?%)$Lwq[:alpha:]{-115,}================================{127,}", 1, 0 }, { "e)", 0, 0 }, { "[{,2[5}Klen+D0'YX(\?<=|_H]I,Y\"*/<3sM[:digit:]])#.", 0, 0 }, { "[:(xdigit:]){[:digit(\?mxmsx::][:as(\?<=cii:]d!{135})#)pP[:space:]Syyyyyyyyyyyyyyyyyyyy\"Gg8", 0, 0 }, { "[(\?()])", 0, 0 }, { "[^([^[^[[^[:alpha:]SIus[^f][^((\?n*)P<3tttttttttttttttttttttttttt)n{}[:graph:]eeeeeeeeeeeeeeeeeeeeeeeeeeeeeee{,83}[:digit:])0BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB[:alpha:]{-155,}{151,}", 0, 0 }, { "Ue{,254}+f[:lowerp(\?<=rint:]U.fff)", 0, 0 }, { "QQQQQQQQQQQQQQQQQQQQQQQQAY===========[^=S|[^[:alpha:]G/]qqqqqqqqq{}[:xdigit:])..k", 0, 0 }, { "[([^[[:space:]ffffff(\?=ff]M]))[:xdigit:]UbCI,CzalLU*y5I[:digit:]r{-30,180}{-209,-45}Paf]", 0, 0 }, { "[^[h(\?{hhhhhhhhhhhhhhhhhhhhh})]{,143}[:lowerprint:][:ascii:((\?(\?=])[:asc)ii:])zp]", 0, 0 }, { "[[(\?{]})]", 0, 0 }, { "[[1\"3m^,(\?2m[M/2222222222222222222222222222(\?:22222222222(\?#22(\?:(\?=22222{,243}]x68+I/K)11111111111]\\pP[:graph:]$[:space:]^{}A)[:xdigit:]-={>", 0, 0 }, { "[(\?>[(^()Vty2vvvvvvvvvvvvvvvvz^])ZZZZZZZZZZZZZZZZZZZ----------------5\\dVLSp8UE2m+z3X/Sd", 0, 0 }, { "[}}}}}}}}}}}}}}}}}}}(\?#}}(\?<=)|*C ]*29JW7O9mEB]pE_OoxN)[:alpha:]", 0, 0 }, { "([^((\?<=\?)D{,200}.[(\?#:ascii:])[:space:].)[:alpha:]D|[:graph:]{,-41}*LLUUUUUUUUUUUUU{-189,-131}]qHR])]][:blankcntrl:]M[:alpha:]x9[:upperword:]|[:xdigit:]b", 1, 0 }, { "()[:digit:][^[U}-]]{,206}V*WJ@R]\?", 1, 0 }, { "[^](\?#{}(\?[<=)yv)]r", 0, 0 }, { "({,-192}//////////////////////7!eW_0eoL){}", 1, 0 }, { "^[:punct:(]+)IIIIIIIII[:punct:]P$pP", 0, 0 }, { "[(\?=|U)^-]{-52,-72}[:digit:]*6666666666\?{{{", 0, 0 }, { "([^f(\?:+{1((\?=34,}]))^)s0bux7\?5`Bwr[:upperword:])Dy+", 1, 0 }, { "AL{}:::::::::::::::::::::::::::::::{,(104}~@,Ysey@h).", 1, 0 }, { "[^((.)))(\?()))))))))))))))))))))(\?msxims:))))))))))[)][:upperword:][:alpha:])", 0, 0 }, { "[^(()f])G^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^T{}N*nK[G]{,61}^^^^^^^^]", 0, 0 }, { "[(N::(\?<=[:digit:][:graph:][:space:]xB5[(:xdigit:]|Yv{}HHHHHHHHHHHHHHHHHHHHHHHHd).[:g(\?<=raph:])[:digit:]<<)[:digit:])[:space:]Q[:punct:]x7C]", 0, 0 }, { "[^((\?(\?(())a)(\?!){})W)pP3333333333(33333333333333333333hhh]{})", 0, 0 }, { "[^ [ a*FFFFF[^FFFFFFFFFFF(\?<[^!FFFF(\?=FF])])L1]{,-52}{B-bxsPKg{,8}[:digit:][:punct:][:upperword:]DD${,-131}", 0, 0 }, { "($$$$$$$$$$$$$$$$$$$$$$$$$$$$$^pP),,,,,,,,,,,,,(,,,,,,,,,,,,)QQQQQQQQQQQQQQQQQQQQQQQQ", 2, 0 }, { "[:lowerprint:]|l{(,-54}C{}*-)IIIIIIIIIIIIIIIII", 1, 0 }, { "()+", 1, 0 }, { "[(([(\?{[:punct:]]|))[[[[[[[[[[})]WWWWWWWW&$$$$$$$[:graph:]", 0, 0 }, { "[^(\?{}){(107[(^,}][:space:[]))^w,&aPPPPPP[^PPPPP{117,-213}s\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?]]]222222[:d(\?(igit:]NNNNNN)NNNNNNNNNNNNN8)I", 0, 0 }, { "[^(\?9C^:\?X_KK]2sw@hHZT!],uuuuuuut|lFW()'''''''''''''''''''''[:graph:]<~v{-251}0[:digit:]C[{222,}]{,41}{}*g^UuS/{-114}", 1, 0 }, { "(D{,-79}[:gra(ph:(\?(]C[:ascii:]))I[tC.%tkllll[^llllllllllllllll]&&&&&&)&&&&&&&&&&&&&&&&&&&&&&)]10435", 1, 0 }, { "[:al(\?{[^num:]]})}x'[:(\?#xdigit:])xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxKKKKKKKKKKKKKKKKKKKKKKKKKKKKTTTr*%{~f", 0, 0 }, { "[ZQKEEEEEEEEEEEEEEEEE(\?[:alnum:]W[:space:]]D)|L", 0, 0 }, { "(M(MM)[:alnum:]|[:lowerprint:]4)", 2, 0 }, { "[[^(\?:{}{2[2(\?>0,})]]]Etu)-)", 0, 0 }, { "([^[^^z[:graph:]]#{-144,96}[:punct:]!4LY//////////////////SSSSSSSSSSSSSSSSSSSSSSSSS[[^:xdigit:]\?`-!L#p0{52}]%{-121,}[:graph:]]WqJ>$6UBg{,7}[:blankcntrl:])[:upperword:]y2wW!A[:blankcntrl:]0CN\?", 1, 0 }, { "[[^(\?:|+bII(IIIIIII(\?(\?>!)275SIIIIIIIIII(IIIIIII(\?=IIIIII[:graph:]|)`]S\?.}A)[:alnum:]Jgggggggggg{-150,}{-89,})[:alpha:]Q)|07be5:j)]", 0, 0 }, { "([(\?i(ms(\?=x-x(\?>:))C)]){})>eIqm~lFb[:upperword:][:blankcntrl:]w=[:digit:][:graph:]", 1, 0 }, { "([HHHHHHHHHHHHHHHHHHHHHHHHHH[^HHH(\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?!!!!!!!!!!!!!!!!!!!!{23}]~J=[:ascii:]tttttttttttttttt])-216", 1, 0 }, { "B{[^-32,246}{13(\?!0}q>GVQw*[:digit:][:punct:].77777777777777777777`T(-t01odD]\?${}{-247}+gV{131})+[:lowerprint:]m/z~d", 0, 0 }, { "[t[$FV+(\?=E=[^])]-$U{-22[5,}{253,}08g]$[{}][:xdigit:][:punct:]{-18}{-173,}]{,-191}V_|90", 0, 0 }, { "()$", 1, 0 }, { "[^[^((((((((((((((W[(\?::blankcntrl:]&-JH]J){93}LLLLLLL|r{,221}tY/172]-AS", 0, 0 }, { "[^()(\?{qqqq(\?msimsx:qqqqqqqqqq3999999999999GGGGG|S*W%{,128}][:xdigit:]AJt]}\"Zf!lRpr{>){,36}})", 0, 0 }, { "[([]^]^)", 0, 0 }, { "([.(\?#){}[:alpha:]\?S{2}P%Gw]nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnYiq5)>i*r<", 1, 0 }, { "[ggggggggggg$PPP:S (:]N{239,}|A[:lowerprint:]vvvvvvvvvv[:lower(print:]{-184}({-133,}+)[:punct:]P/Q.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", 1, 0 }, { "(RRRRRRR[^RRRRR[RRRRRRRRR])]", 1, 0 }, { "[(\?:^])D%", 0, 0 }, { "()[]#C[+[j]{,29}-]", 1, 0 }, { "(([(\?(((\?{\?!(\?=\?=#[Es*){02$r'}(\?:3pz)uPPPPPPPPPPPPPPPP(\?(\?>:PPPP][:graph:][:ascii:]`.)[:punct:][:a(\?mxi:lnum:])r)$)[:xdigit:]$[:(\?=digit:])aa[^]a)\?])sQQQQQQQQQQQQQQQQQQQQQQQQQQ^|$)-}))", 2, 0 }, { "z@@@@@@@y${}[:(\?:upperword:]l\?{,144}-)", 0, 0 }, { "[:aln(\?:(\?>um:(\?imximsx:]){})FGGGGGGGGGG|-p){,105}", 0, 0 }, { "[[{17}llllllllllllllll(\?:lllllllll{,(\?#-94}OUUUUUUU(\?#UUUUUUUUUUUUUAA]p[:digit:]{-1(57,}5yyyyyyyyyyyyyyyyyyyyy[:alnum:]v{-185}^^^^^^^^^^^^^)d[[[p)]))", 1, 0 }, { "()|[:digit:].E2o", 1, 0 }, { "()3[:lowerprint:]", 1, 0 }, { "[(\?{(\?#(\?>SN}[^)z+r^t[:digit:]seP[:alnum:]$b1ZY[U(\?{}000000000000000000000000000000$|)", 0, 0 }, { "[:(\?=digit:])v{164}", 0, 0 }, { "[:graph:]h[:upper(\?(wo(\?{rd:)])00000[^000000000000}).4OEVf{,-46}]A", 0, 0 }, { "[](((((((((((((((N{{{{{{{{{{{{{{{{,-1}e]a{-166,-44}", 0, 0 }, { "([[^[^[(^[]]YYYYYYYYYYY]D.cQ{}[:alpha:]ttttttt000000[^0000(\?raph:])[:punct:][:upperword:]LV\"t+t!)[:ascii:][:lowerprint:]q", 2, 0 }, { "[[[^([7(\?[R]]$PeFuufcBA`qr!!!!!!!!!!!!!!!!!!!!!!!!!", 0, 0 }, { "[[(\?#F^(\?wwwww)3z/57z){34}]/(/////////////[^//////////////////)]E%)L{-133}]*$]", 1, 0 }, { "(!)GS[:ascii:][:punct:]{235}T'&-_h\"", 1, 0 }, { "(){}", 1, 0 }, { "[[^((\?!(\?<=)*QF[:alpha:])([^[^\?qqqqqqqqqqqqqqqqqqqqqqqP6W0_'O)Bur*'6&*t)]{65})+", 0, 0 }, { "([(\?=)]wr$7f5ru){100,}[:xdigit:]y{}[:digit:]{}2n@P|9#mru~97{-189,73}$a", 1, 0 }, { "({-113,213}){-172,221}B[:ascii:]{,-48}", 1, 0 }, { "[^[[Xf`````((\?{(\?<=\?imsmsx:`````````(\?!`````````[```(\?mximsx:``(\?(&|o{xIaO][:)space:]3))\?])+)*<|@@@@@@@@@@@@@@@@@@@@@@){-251,}{}]*[:graph:]1!azE\?|-120u*][:lowerprint:]})", 0, 0 }, { "[[[^##(\?################(\?>(\?(##t)][:punct:])b))<<<<<<<<<<<<<<<<<<<<<<<<<<[:alnum:]y >u=l:rp8i3Ci#]46%NIO-W[:space:]IIIIIIIIIIIIIIIIII]W[:space:]f]l{-253}", 0, 0 }, { "[:graph:]L{-136,175}{[^}h(\?=t)Q]ooooooooo(ooooooooooooooooo_)[:space:]q\?", 1, 0 }, { "()$.", 1, 0 }, { "[(\?\"y8].]:::::::::::::::)pP5-]p)O{,199}xxxxxxxxxxxxxxxxxxxxxx[:ascii:]%", 1, 0 }, { "([:alpha:]Fs)Z", 1, 0 }, { "[()]{209}[:alpha:]hhhhhhhhh(hhhhhhhhhhhhhhhhhhhhh)pP<<<<<<<<<<<<<<<<<<<<<<<<<<<<<", 1, 0 }, { "-{-8,}.[:(\?imsxx:ascii(\?D9'", 0, 0 }, { "[#(\?msximsx:#########################-IIIIIIIIIIIIII(IIII(\?#IIIII((\?#[^III{})N.[(\?=:lowerprint:]))CwT,,,,,,,,,,,,,,,,,,,,Sq]$CCCCCCCCCCCCCCCCCCCCCCCuuuuuuuu])))", 0, 0 }, { "[:xdigit:][(\?#]){13}{,75}lllllllll", 0, 0 }, { "[c]QQQQQQQQ1+{-252[(\?#}33333])[:upperword:]", 0, 0 }, { "P@i #>>PF!@8G<[(\?:^P]-)D", 0, 0 }, { "uZZZZZZZZZZZZZZ[^ZZZZZl*-211{199}(\?!p])EEEEEEEEEEEEEEEEEEEEEEEEEEED[:lowerp(\?msximsx:rint:])", 0, 0 }, { "[(\?!^])021[:graph:]'", 0, 0 }, { "\\(\?>[(\?<=:ascii:]{}[:alpha:]d8}G))", 0, 0 }, { "[^[((\?!1)[^,a|]\?{,242}[:alnum:])X\"a", 0, 0 }, { "pP[((\?simx::a(\?!lnum:]vvvvvvvvvvvvvvvvvvvvvvvvv)|O0)[:digit:]ooooooooooooooooooooo)\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"", 0, 0 }, { "_ L:8J-~ Y$[:uppe(rword:]{,-184}]{}6.A)", 0, 0 }, { "{,105}.(9]]{-12})N@0nOOE", 1, 0 }, { "HHHHHHHHHH[:xdigit:]uuuuuuuuuuuu{}E^X\\\\\\12601", -1, 1 }, { "( o)=\"OU7h{V>", 1, 0 }, { "[[:xdigit:])))))$[:xdigit:]+{152}{,-50}(c),,,,,,!!!!!!!!!!!!!!(\?>!!!!!!!!!!!!!.[:digit:]i>\"O'i9])-175d_", 0, 0 }, { "[([^[^[^([[Eeee[^eeeeeee(\?(\?(\?!(\?>a:]a{,166})/////////////////////[:gr[^aph:])Gpu", 0, 0 }, { "(7)NNNNNNNNNNN132", 1, 0 }, { "[([\?#^[]{QKm$v])][:alp[^ha:]]", 0, 0 }, { "(:{86})7{K|[:alpha:]{O", 1, 0 }, { "([Y(\?{[[^:alnum:][:alnum:][:digit:][:a(\?(lpha(\?(:].})", 1, 0 }, { "[[({29,-30}([[^:digit:])Y]]J=~{,220}[:blankcntrl:])0ooooooooooooooooooooooooooooooo[:punct:]&]", 0, 0 }, { "[^1Dx32[:alnum:]]{[(\?::punct:]MMMMMMMMMM)12759", 0, 0 }, { "([[[]]*|(_])[:u(\?{pperword:]})", 2, 0 }, { "[:upper(\?(wo)rd:]){-16,250}", 0, 0 }, { "([^{194}i(\?({161)}PP\\S{}{,-14}]))z{208,225}BpPEt", 1, 0 }, { "[(\?m-ms:)}&!@29k0sUqzt9}<-x|A$!+G>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>CCCCCCCCCC-][[:space:]][:space:]El", 0, 0 }, { "()[:digit:(\?isx(\?>ix:]K^WQQQQQQQQQQQQQQs)[:lowerprint:])", 1, 0 }, { "[a|(\?imix:S(\?(SSSS)SS(\?>S)]W)8t[:ascii:]f$)[:alnum:]111111111111111111111[^[:space:]x{12729}+'''''''''''''''']", 0, 0 }, { "[^(\?!(\?(\?#=)a)[:punct:]=2)(){}$$$$$$$$$(\?ims(\?#-isx:$$$$$$$$$$$$$$$$(\?#$$s)x{294b}##############################slllll)]){,209}333333333333333333G:v2/K", 0, 0 }, { "[^]ub(\?<=)vQ6(\?#Z\"3.)[:space:]u[[:digit:]]7777777777777777U'{}sssssssssss", 0, 0 }, { "(([(])`[:ascii:]b)", 2, 0 }, { "[[[^[^([^[^(\?=(\?imxisx:[[^w])", 0, 0 }, { "pppp(pppppppppp-{-175}Nb>k&)sssss{-190,-54}", 1, 0 }, { "()OJ@`'%[:(as(\?!cii(\?#:]))+pffffffffffffffffffffffffffff{,162}[:ascii:]5)s-[:graph:]", 1, 0 }, { "[(M{}Ux5{jaW/{}[^u[:alpha:]s^{84,}PPb@Wt$(\?>nha:al[^pha:]])\"O\"vN", 0, 0 }, { "[(\?>d8E@b.{(\?<=,-250}(\?=mx48[:punct:]^&)]nAeYY)W)-13272", 0, 0 }, { "22222222222222222222222222///////////////////[:digi(\?#t:]eM)[:lowerprint:][:alpha:][:alpha:]EEEEEEEEEEE", 0, 0 }, { "[(\?={38,223})^\\\\\\\\\\\\\\\\L(\?:{,-50}3|)}r]aW\\x70U{-110,}8LUf)w]4+oav", 0, 0 }, { "G[:upperword:]v[:lowerprint:]-tu)j8CK", 0, 0 }, { "[([([^().(\?(\?><=c)'(\?<(='(\?L\?q!G))|)(\?=n(\?(^tk)T-z$q!D|2[^a:]W,[4DLR[^^8THMtVv~KKw(\?>)pPF)].{-245,}]))fffffffffd[:alpha:]zzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 1, 0 }, { "[^[[^]{-[1(\?imximx:83,}{,182}][:graph:]]^])-bTO X0P", 0, 0 }, { "[11111111111(\?#11111111]U[:asc([\?!ii:]{,37}+{-89}){-170,218}{-21,})f[:xdigit:]]P.[:xdig(\?:it:]145)YYYYYY$S@:@@@@@@@@@{-150,-109}", 0, 0 }, { "{-40} (\?( (\?{ (\?!]E{-29})pP)})ZpP", 0, 0 }, { "(t|{}c[^z^\?(@YLD]bSSSSSSSSSSSSSSS)+{{{{{{{{{{{{{{{[:xdigit:]n>1)WkF}7", 1, 0 }, { "W22[0Q[^d-d{}PPPPPPPPPPPPPPP<^FZ(\?<=\"[U]Yo}9H'cYy]S[:alnum:]^8wTDH)^u", 0, 0 }, { "([^[(\?:(\?>((\?#$)(\?{^(\?>))///////////(\?>/ggggggggggggggggg{1(\?!90,-13}\\D)Dyyyyyyyyyyyy(\?!y(\?ankcntrl:]))(^m+)zSiZ F4[!]VV$E{-9,-100}''''('''''''''\?DEOOOOOOOOOOOO###############[:space:])HHHH)[:digit:]'////////////", 2, 0 }, { "[^*}(\?>)(\?:7Q=#+]KKKKKKKKKKKKKKKKKKKKKKKKKKKG)]]]]]]]]]]]]]]]]]]]]]]]]]][:alpha:]-{}", 0, 0 }, { "[n(\?<(\?#!nnnnnn55555{205,}!)[:alnum:]^]!!!!!!!!!!!!!!!!!!!!!!![:punct:])[:x(\?(digit:]vr)|'n6W5 D&jk[:punct:]5)", 0, 0 }, { "[^P(P{(\?i(msxisx:235,}))***])[:alpha:]^", 0, 0 }, { "[([t(\?a:])x11{-144,45}.", 0, 0 }, { "[]{#y.^(\?{{}&&&&(\?:[^&&&&&&&&)[:punct:]n{190}OylBQ{(\?!-73})2u',x(\?#Ds(\?#{})j(\?{-})})u0(((((((\?{(((([:alnum:])MC})b=71TncyE>[:xdigit:]*\\f]{}]\"p#!8twZT\")[:punct:][:space:]", 0, 0 }, { "[^(Z6]8)|'@p8{}[:upperword:]MMMMMMMMMMMMMMMMMMMMMMMMMMMM{}7c", 0, 0 }, { "$0)@#vp,VcJ.Bdh", 0, 0 }, { "[[^(-])nnnn+s`[:alpha:][:blankcnt[^rl:][:upperword:]{-15,}][:g(raph:]c]){,-177}6[:upperword:]##################{,-14}", 0, 0 }, { "[[(5C{86(,}PPrrrrrrrrrrrrrrrrrrrrr{150,182})N{}LSC|)-[:alnum:]{}KKKKKKKKKKKKKKKK<4=~7K3PPPPPPPPPPPPPPPPPPPPPPP[:lowerprint:]]]", -1, 0 }, { "([^(x{145b[5}^hfc.0)+]z@_&lA{-34,}])X\?", 1, 0 }, { "([(\?<=)(\?!])l)L", 1, 0 }, { "({-104,}DrPPDF4444444444444[:space:])[:space:]", 1, 0 }, { "())))", 1, 0 }, { "[[^((\?>\?(\?[{})q5v}r7t(P)xtffffffffffff))]{,-66}kdExX&-SCeCzzzzzzzzzEc)E,\"^I]x{e629}|{}]", 0, 0 }, { "[h[:punct:]p\\[\\\\(\?:\\\\[^\\\\)Eo#:C$u[^T/ysA[*%nM:f]{,221}[:lowerprin[^t:]{]bx{f285}E]E[:alnum:]+]1oe3B][:alp(ha:]]fh7}M$l)D{17}", 0, 0 }, { "IIIIIIII[^IIIIIIX]-_S[:digit(\?#:])33333333333333333333333333[:punct:]iiiiiiiiiiiiiiiiii", 0, 0 }, { "[^[[:punct:](\?((\?:^ #Q_po(\?=[:alpha:]{}z()(\?!======'wq$Q2)LLLLLLLLLLLLLLLe(C9gggggggggggggggggg[(\?<=:alnum:]()\?(\?=a!Ib1P]])])~~~~~~~]xE9", 0, 0 }, { "X()", 1, 0 }, { "[^()(\?#G(\?777777])", 0, 0 }, { "(),e<^X~{[:alpha:]{}G{70}", 1, 0 }, { "({-211,}'){}", 1, 0 }, { "[^(\?imsxsx:{}[*])cccccccccccccccccccccccccccccccc[x))(\?:]r.]]]))[:graph(\?<=:])))", 0, 0 }, { "[^([(\?#)(\?(\?(<=)l|\?(\?!])kkkkkkkkkkkkkkkkkkkkkkkkkk", 0, 0 }, { "[:xdigit:]K(KKKKKKK)^3c.OOO{-240,-10}2{-97,-139}*{-34,}[:xdigit:]", 1, 0 }, { "[([^66666666F(\?>FFFFFFFFFFwpP)LLLLLDeDA&Am$l[:xdigit:]!T5#]n[:alpha:]U*)))))))))))))PP]", 0, 0 }, { "[[[:punct:]u^[:xdigit:]L(\?:[:xdigit:][[:graph:]PP{21}A[:alpha:]8%I(M%bSSSSSSSSSSSSSSSSSSSSSS]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]{,-1}])[:blankcntrl:]===============================[:punct:][:blankcntrl:]Z[:space:][:ascii:]$|$[:blankcntrl:] JR.{,133}[:alpha:]$\?)<]", -1, 0 }, { "(OL[:u[pperword(:][:s[^pace:].[:spac(e:],,,,]*])$)\?)", 1, 0 }, { "(VI[:digit:][:alpha:]6)EG", 1, 0 }, { "({}){-2,-40}rrrrrrrrrrrrrrrrrrrrrrr[:punct:]", 1, 0 }, { "()q", 1, 0 }, { "[^([^[([^C|])]{,-56}[:xdigit:]{-144,}V])fYv{-[40,-58}$@@@@@@@@@@@@@]|Y(-]-.]h-[:dig(it:])>>>dddddddddddddddddddddddddd{101,}", 1, 0 }, { "([P,{1(\?(\?(<=28,-218[^)}LoZX)])!!!!!!!!!!!!!!*[:blank(\?!cntrl:]ed)\\\\\\\\\\\\\\\\\\\\[\\L\?][:graph:]:*Y{-108,120}xCC)]", 1, 0 }, { "(A[:space:]PP{185}a^!!!!!!lllllll)*db\?$Pfr", 1, 0 }, { "{-21,-118}kG[(\?{:xdigit:]})[:punct:]{69}Qyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy5{}TTTTTTTTTTTTTTTTTTTTT", 0, 0 }, { "[[^[P(\?<=P$X>0^d.[:punct:](\?#ccccccccccccccccccccccccc{}3N000(\?>00000000000000000000000000000]f[:punct:]5)).R================{,222}^wwwwwwww$)]-{} ]{,-22}CjP{242,}", 0, 0 }, { "[(\?#^]{})", 0, 0 }, { "[^([[([([[([^[^(\?:(\?(\?(!)]\"))h>\"RRRRRRRRRRRRRRRR[^RRRRR{68,-65}7Q(\?{]", 0, 0 }, { "(P{}){175,}PP{}rttttttttttt", 1, 0 }, { "[:bla(\?{nkcntrl(\?#:]})))))))))))))))))))))))!!!!sR{})", 0, 0 }, { " [:digit:]dAAAAAAAAAAAAA^[:ascii(:]55)^", 0, 0 }, { "($*)dZY", -1, 0 }, { "[:graph:][:lowerprint:]S[:gr(\?=aph:]{-128,}666666666666666666666{}[:upperword:]|nnnnnnnnnnnnnnnnnnnnnnnnnnB)c[:xdigit:]{-225,}{-4,}{-192,}QQQQQQQQQQQQQQQ@@@@@@@@@@@@@@@@@@@@@@.", 0, 0 }, { "([:digit:]s{44,}{}{-31,}c{,-130}pP){-241,}UeN", 1, 0 }, { "([^)((\?>\?#{}hK\"V2\?d][KKK(\?imsxim:KKKKKKKKKKKKKKKKKKKK[^KKKKKKKKKWWWW[WWWWWWWWWWWWWWWWW)B])_l_3", 1, 0 }, { "[(^[(\?!*){[^,91}].j]*]L)*c|[:alpha:]&", 0, 0 }, { "[^[[[^[777GGG(\?:W_U(\?imsxms:[:punct:]A]-)[:digit:][:blankcntrl(\?(:]][:alnum:)])]WRRRRRRRRRRRRRRRRRRRRRRRRRRR]{31,}[:xdigit:]][:xdigit:]))))))))))))))))))))))$[:xdigit:]", 0, 0 }, { "[:ascii:]m*[:punct:]#[(\?>>>>>>>>>>>>{,-129}))\?{-226,}^P)R", 2, 0 }, { "[^[[nnnnnnnnnn(\?=nnnn(\?!nnnnnnnnnnnn(\?#nnnnnn{,-38}N){202,}]$[:alnum:])]t][:alnum:[]^=w){237}][:alpha:]-[:alpha:]+e", 0, 0 }, { "()[(\?(:digit):]+qc)O88888888{,151}aJ", 1, 0 }, { "([^([(\?!sv(\?=)d]{-200,})N))]Z{-73,15}", 1, 0 }, { "([\?\?\?\?|||||||||||(\?{||(\?=||||||||-}[))Ehhhhhhhhhhhhh{,202}&TcfL((\?:>)((\?!\?>$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$8[:alpha:]\\d])]C[:graph:]h*,\"\?u{|mU,a)[:blankcntrl:][:lowerp(\?>rint:])PPnP+9.[:xdigit:]*PPjjjjjjjjjj~y<#*scf_\"^e[:xdig(\?(i)t(:])~$y)^){-131,77}^L%", 1, 0 }, { "[^[(((\?>)$}h9$B5+yhU/Nqh$YYYYYYYYYYYYYYYYYYYYYShK)3WHw1vMMMMMMMMMMMMM(\?=MMMMMMMMMMMM[:alnum:]/)dddddddddddd(dddddd\"e5zLW)+![:space:]+BHGHfAS]\?IIIIIIIIIIIIIIII*&&&&&&&&&&&&&&&&&&)NNvwDteepjdm<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<${61,219}D][:digit:]0", -1, 0 }, { "[:punct:][{177,(\?=234}]ix9*)", 0, 0 }, { "([^K{,3(\?<=4}]I)\?U)", 1, 0 }, { "[([^[[[^([([^[^(\?=])X", 0, 0 }, { "[:blankcntrl:(])qd_R\?{\?r[=\"[^[^6]vX8)a+{C%H84CK6Uy#E]sE{208}", 0, 0 }, { "PPPPPPPPPPPPPPPPPPPPPPPPPPnnnnnnnnnn()[:upperword:]us", 1, 0 }, { "x{,46}[:graph:]LU{}CU)", 0, 0 }, { "()-t|[^W{}][:lo[^werprint:]{}]\?b5", 1, 0 }, { "()x5A", 1, 0 }, { "[([^]-217)]s{-47,135}0000000000000000000000000000000{,-108}", 0, 0 }, { "[^((\?{[^L\?u]})f", 0, 0 }, { "()[[^^(\?{y(\?=VF_(\?<=]D}))]-= {46,})^5bIEQ{,-96}Z", 1, 0 }, { "([^{}f[:punct:]\"X%%%%%%%%%%%%%%%%%%%%]5{-194}A[:punct:]mnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn+AAAAAAAAAA-)", 1, 0 }, { "(CCCCCCCCCCCCCCCCCCCC{-230}352{-182,-68}O4{})", 1, 0 }, { "([^[^\?[:space:]$TTTTTTTTTTTTLLLLL[^LLLLLLLLLL[^({}{4,-179}]]J] C]){}C{}{-224,})QQQQQQQQQQQQQQQQQ^", 1, 0 }, { "([[:alnum:]].){-155,-82}dzI{55,}^", 1, 0 }, { "([[:alnum:](\?#{88,-178})[:graph:]NC\"pI[:punct:]rmWd5y^p+gUP]YYYYYYYYYYYYYYYYYYYY~{,-62}{,200}{-109}{}+333333333333333333333333333333{}p)^.hhhhhhhhhhhhhhh", 1, 0 }, { "[000000(\?mmsx:00000000000000000000000)M]]]]2*`[^]QQQQQQQQ(\?<=QQQQQQQQQQQQQQQQQQQQQQQ])\"5j[bbbbbbb(\?{bb)o{}3(\?imxisx:E]g})YYYYY[:blankcntr(\?#l:].(()w264[:ascii:]^)[:ascii:]G)&(n {^PGn[:xdigit:])nv_e|]{-103,30}", 3, 0 }, { "[^(([(\?!{}@[^HCO[[^^D[|]{,-49}][:xdigit:]]c`4[:ascii(\?ggggggggggggggg\\\\\\\\\\\\\\\\\\\\\\\\\\Ef[:space:]\?][:ascii:]{21,}", 0, 0 }, { "([:xdigit:]W[:u(pperword(\?::]jS [:upperword:]*)[:alpha:]nnnnnnnnnnn))-148}SSu", 1, 0 }, { "([^(\?!\?)[(:upperword:])Bx^x$~lCr6*)6", 1, 0 }, { "[{,-78}Y[:xdigit:][^s(\?>]P[:space:])]YYYYYYYYY[:punct:][:alnum:][:blankcntrl:]", 0, 0 }, { "([MMMMMM(\?(MMM)M(\?<=MMMMMMMMMMMMMMM[^M)]en][:punct:]-[:alpha:]))Nr[:space:]", 1, 0 }, { "~=1([^(\?=(\?:l){}])j{-44}{-18}[^u[:graph:]]{-187,}[:xdigit:]w[:alpha:])", 1, 0 }, { "[ccccc(\?>c(\?{cccc[ccccwetoCei+)w&-+{,-142}[:alpha:]PP66io4(|zkA=],,,,,,,,,,,,,,,,,,,,,Lx5Cx{d2bb}]{188}U~~~~~~~~~~~~~~~~~~~~~~~})", 0, 0 }, { "Q|0\"[:d(\?:igit:]^{,-174})", 0, 0 }, { "[^[(\?>rh])]", 0, 0 }, { "[ees{{{{{{{{{{{{{{{{{bbbbbbb4`ml******(\?=****+])", 0, 0 }, { "((hdG[((\?<=:dig(it:])[^[:alpha:]$(\?sxi:)x{11390}[(\?{:upperword:]~)i 8[:blankcn[trl:(])]+{,-183}Zqp", 2, 0 }, { "Dd{D8`+DW={-[53,1(\?<=71}])", 0, 0 }, { "[:(\?(alpha:][:punct:])", 0, 0 }, { ".LLLLLLLLLLLLLLLLLLLLLLLLLLLL{}pP[:punct:]x0CZ{30,}!!!(!!!!!!!!!!!!!!!!!!!!!!!!!==@77.%[:graph:]D)", 1, 0 }, { "[^[^[[r(\?#]){-237,}RRRRRRRRRRRRRRRRRRRRRRRR[^Rll(\?!(\?{lllll]", 0, 0 }, { "()*ooooooooooooooooooooyyyyyyyyyyyyyyy", 1, 0 }, { "{,4(}D)JJJJJJJJJJJJJJJJJJJJJJJJJ", 1, 0 }, { "((b.D{}[:al[pha:]{64}]{})==========================[:alnum:]h>77b)!Ab", 2, 0 }, { "([^[^[^oooooooooooooooooooooo][:space:][:punct:]PeniKe*~$g\?${>[:lowerprint:]w))))))))))))))){}yyyyyyyyyyyyyyyyyy]pP.|QhZ]{,190})sssssssssssssr+=[:blankcntrl:]WWWWWWWWWWWWWWWWWWWWW", 1, 0 }, { "([*(\?{})hhhhhhhhhhhhhhhh]G{,-170}QdErrrrrrrc-jjjjjjjjjjjjjjjjjjjjn+{-130,-10})PpDS@Bee", 1, 0 }, { "([:b(\?=lankcntrl:]))T[:alnum:]{-224}ywt", 1, 0 }, { "([633(\?<=333(\?<=3333333333(333333)^\?]aGA)[:digi(\?>(\?{t:])$[[:space:][:xdigit:])|8T\?',_{171}{}{113}b\?5kAv0/7{})`huh>xM]C8pYRz]s$Eu08)", 1, 0 }, { "-(pP)[:alnum:]$^", 1, 0 }, { "[^x(\?{{17681}]P*)U(_t/8E_\"iN})3333333", 1, 0 }, { "(([^([[r(\?=[[^^*kx$][:alpha:]:::[:::::[^[^::::::::((\?{\?{::]).^p[:space:]}){52}{}]W{}fn", 2, 0 }, { "[:(\?>punct:]Ef[:xdigit:]x{c07b}{-50}Z{129,}YL1T`\\A)x[:punc(\?=t:]e[:xdigit:]2c6E46Y)+n ", 0, 0 }, { "[^(\?!{,-79}[:punct:]'|}>,)][:blankcntrl:]{-118,-231}{-119,-50}:XXXXXXXXXXXXXXXXX-~{}$txlB)3KFL", 0, 0 }, { "[^(([^fccccccccccccccccccc(\?)])qcU$Q7|82\?{})", 2, 0 }, { "[^yyyyyyyyyyyyyyyyyyyy(\?#yyyyyyyyyyya][:ascii:]\?)", 0, 0 }, { "(([((\?{)EEEE(\?QQQQQQ(\?!QQQQQ][:digit:]\?))99999999999999)[:digit:][:upperword:]b))PP{}{}", 2, 0 }, { "(K(c=B))", 2, 0 }, { "(G`*s\?b[:g(raph:]))", 1, 0 }, { "[^[([[[*QQQQQQQQQQQQQQQQ(\?=(\?=QQQQQQ(\?ddddddddddc{22,}iiiiiiiii(iiiiiiiiiiiiiii(\?#iiiiiii[^i))\?\?\?\?\?\?]WWW)[:lowerprint:])]{-60,202}+[:upperword:]f[:xdigit:][:alnum:]{,-214})1~~~~~~~MMMMMMMMMMMMMMMMMM.", 0, 0 }, { "({-102,})A.", 1, 0 }, { "[((((\?(\?#\?()))p\"JD.{}(\?>)))((\?{l(\?<=).'053][:xdigit:]N+)})]WWWW%[:asc(\?{ii:]}))B[:alnum:]X){}s[:digit:]", 0, 0 }, { "x7&{139}WWWWWWWWWWWWWW[:blankcntr[^(\?~[^n@f`````````````)````````P])Y,N{}{}]{}pXF@)", 0, 0 }, { "G[([(\?(^)$])P]^[:alnum:]){,-48}[:blankcntrl:]{}", 0, 0 }, { "[[^[^f(\?=f(\?<=fffffff[^fffffffff[^fffffffff(\?<=fff]){-194,150}fx{e5a4}V", 0, 0 }, { "9[:xdigit(\?{:]})", 0, 0 }, { "[^([[(\?>()$xxxxxxxxxxxxxx[xxxxxxxxxxxxxxxx((\?=aA)s13]])pp[(\?>pppppppppppppppp|{}){20,}]b)]{-179,183}{-204,}[:ascii:])]-11111111{}{,132}qooooooooooooooooooo{}${}|9t", 0, 0 }, { "([^[{}]\"[^6]*-{,-106}{}u]BR~8WG,U-)[:blankcntrl:]", 1, 0 }, { "[''''''''(''''''''''z])c", 0, 0 }, { "[^[(\?>])[:alnum:]r[:alnum:]+{,215}D]", 0, 0 }, { "([({,127}7Qr(\?:z)pPNev%}(\?msximsx:4(\?nn(\?:nnnnnnnn_U{}]E)):^oooooooooooooooooooooooooooo)", 1, 0 }, { "[^(\?#)(\?!(([:alnum:]{252}{}})ffffffffffffl){}A2r\?~ImE\"[:punct:]){}[:digit:]", 2, 0 }, { "([:blank[cntrl:]].t^P)", 1, 0 }, { "[^[(\?:X])|rrrrrrrrrrrrrrrrrrrrrrrrrr*P]Q", 0, 0 }, { "[[[^(\?{((\?15}]x{f779}ZZ,Wo)O[:alpha:][:lowerprint:]{81,228}Q[:upperword:]", 0, 0 }, { "[[^[^()n[[[[[[[[[[[[^[[[[[[[[[[(\?: G)(\?{K![^m) j(\?:C|((\?:n*Xlaa908:n$m,))[:xdigit:]x(\?{{1a5cd}pppppppppppppp(\?(pppp)p(pQ)))ddddddddddddddddddddddddddddddd]q[:alnum:(\?{]Ga})\?})@[:lowerprint:]{,169}[:blankcntrl:][:graph:]]n{-76,}|U\"{,-54}t]I{}{-64,-232}]\?].\?{-111,227}) @hFp\?j=H$Wbu<{,209}De{,145}{206}-})[:blankcntrl:]", 0, 0 }, { "[^[^(LLLLLLLLLLLLLL[^L[L[:alpha:]3{,189}(\?#(\?>n){}^EXXXXXXXXXXXXXXXXXXXXXXXXX]c*)^r=$WWWWWWWWWWWWW", 0, 0 }, { ")w###################", 0, 0 }, { "{,121}[:d(\?(i)git:])E\?[:punct:]LLLLLLLLL[:ascii:]+", 0, 0 }, { "([]]]]]]]]]]]]][:space:]Jrt3o.]b)pwwwwwwwwwwwQfm~", 1, 0 }, { "[+-{,-120}*(\?!()t*(\?(\?{>G)F)yd]V{}f<\?}){245}xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx[:upperword:]", 0, 0 }, { "(DDDDDDDDDDDDDDDDDDDDDDDDDDDDDc[:space:][:pu[^nct:]{-11,12}[:ascii:][:alpha:]{,155}P])", 1, 0 }, { "()ggggggg{-136,-21}", 1, 0 }, { "([^((\?<=U\?)(\?=^^^^^^^^^^^[^^^^^^^^^^^^^///(\?#//[////////////////////(\?()#######b+]$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$^[:digit:])\\U]Q8@}4d)\\U", 1, 0 }, { "A[:graph(\?::])-mo=U[:upperword:]ttttttttttttttttttttttttttt", 0, 0 }, { "[^(((\?=\?im-m(sx:)c~~[^~~~~~~~~~~~~~(\?>~~~~~~~~~~~~~SSSSSSSSSSSSSSSSSSSS]{51,}[:digit:]{,-179}N))kk[kkkkkkkkkkkkkkg$)[(\?::punct:]zWl)]|)*", 0, 0 }, { "[((\?=()+A)][:graph:]x0B)[:graph:]", 0, 0 }, { "(nR%B[:blankcntrl:]C=|en-[:digit:]n[:graph:]HHHH[HH]D\?%[:digit:]MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM.z(oF9zW8A7cfff(f))-[:blankcntrl:][:blankcntrl:]A[:digit:])D{,-243}", 3, 0 }, { "([[()]]{,-251(})\?L)uw@", 2, 0 }, { "\"|{(,-144})A.ooooooooo(ooooooFFFFFFFFFFFFF\?)n{,-18}", 2, 0 }, { "([^([(([[^([000000[0(0(\?!0(\?=0000000])45|E]", 1, 0 }, { "[B[[[[[[[[[[[|{}*oKqv%(\?<=wsQ{1pMeK1^6%nLNqi<@ge][:punct:]= M@* D|NwL\\-117\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"~Qnd]h.O\"01x:[:alpha:]^){}D}\"", 0, 0 }, { "([[RRRRRRRRRRRRRRRRRRRRRRRRRRRRxpSrx{7d79}*oJ2`Ft{n1,3g:1H@bT$D &[n/Cg)=ld@Ir{Fk>*4*`(\?>````````````````````(\?:`````.....................]]{,246})7 \"F4[^F|/g)]+e`rw@{,-69}H)", 1, 0 }, { "([(\?<=)X[:digit:]PP.[(\?#:((\?#\?#graph:])[:digit:][Q+)(N][:alpha:]]f)[:graph:])+Elllllllllllllllll[:digit:]=)pP{uU-20bzY|ZKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKt:])|l*KKKKKKKKKKKKKKKKK,,,,,,,[,,,s.{148,}P33333][:lo(\?Q){,57}%[:digit:]\?\?\?\?\?\?\?\?\?\?.[)]]d{)-49,}f)^O{,68})\?C", 0, 0 }, { "(}u])18621", 1, 0 }, { "[:as(\?=cii:][^(\?=)(S-{.F-[:punct:]3-105^[:lowerprint:]111111111111111111111111---)][:alnum:][:ascii:]JJJJJwHSk", -1, 0 }, { "[^3>>>>>>-sZ^^^^(\?>]Y[:di(\?(\?imxim:#git:]{-158,-102}[:punct:]{}{87,})))[:upperword:]", 0, 0 }, { "[(\?{AjBBBBBBBBBBBBBBBBBBBBBBB[:upperword:]`'W)", 0, 0 }, { "[^([[()DN1[^][|]\?]{-104,}])[:space:]][:lowerprint:]r[:alpha:].DU", 0, 0 }, { "[^((33333333333333333333333(\?<=3333333D))kkkkkkkkkkkkkkkkkkkkkkk[k[:alpha:]])]X+", 0, 0 }, { "[({,-17})[@e{220,(\?#41}])]]{-213,-225}", 0, 0 }, { "[[^(\?#[(\?:^[[(\?(^]))]])]vvvvvvvvvvvvvvvvvvvvv{,96}|m]{-79,248}[:alpha:])", 0, 0 }, { "([[(\?imsisx:^}$,-[:al(\?>num:]Xqqqqqqqqqqqq{-185,154}]b#+T){-241,})A{-27}[(\?([\?()(\?#))]--R1rk^UnP.[(\?!:digit:]])^)[:upperword:]{}0000000000000000000000000000000~U{-139,-19}z})RR(\?=R<]p'N~&.-})6]", 0, 0 }, { "[^\?[^(\?(lFt]).[^7Q-])kkkkkkkkkkkk]XTFy\"1Deiv!,'xVK", 0, 0 }, { "[^$[^[:xdigit:](\?{*{245,99}h8v(\?!)]]u)Z[:punct:]})[:alnum:]+|[:blankcntrl:]u{}[:lowerprint:]+bBJ4+k-v{-116}", 0, 0 }, { "S)f{,180}[:graph:]&{12,244}", 0, 0 }, { "(([[(.()[^^{80(\?>(\?<=,235})ddddddddd[^ddddddddd(\?<=d.__B{36}````````````````(\?:```(\?>```````,,,,,,,(\?:,,)P$U,[:xdigit:])zzzzzzzzzzzzz]UUUU[uB]n<&[(:ascii:].][:alnum:])\?S]{})d{138,}s9========[:lowerprint:]]OOOOOOOOOOOOOOO|yyyyyyyyyyyyyyy$LZ[:lowerprint:]EEEEEEE[:ascii:][:punct:]VpP^{-48}D){,46}x))2P))a[:lowerprint:]r", 2, 0 }, { "[^(((\?555(\?owerp(rint:]])]*", 0, 0 }, { "Au)khgzAfXIZoZ=g[:digit:]){,186}Upvf=x<]Tbd5Rq\?.", 0, 0 }, { "b{-176,}B^[:bla(\?(>>>>>>>>>>>>(>>>>>>>>D)Ix{(1(\?imxmsx:762)c}))A)[[[[[[[[[[[[[[5Rp]DDDDDDDDDDDDDDDDDDDD]Us+\\w[:digit:]{-47}[:xdigit:][:blankcntrl:])ddddddddddddddd[^ddddddddddddd[:digit:]|]]*{-165,-230}{-212}{53,}]\?", 0, 0 }, { "[^[^]]|[:(\?:alnum:])}}}}}}}}}}}}}}}}}}}}", 0, 0 }, { "VVVVVVVVVVVVVVVVVVVVVVVVVVVV[:d(i(\?#git:])){{{{{{[:digit:]ZfQ55555555{}Z", 0, 0 }, { "[L][:blankcnt(\?((\?=rl:(\?=]){-35,[^}){)eJb>>>>>>>>>>>>>>>>>>>>>>$ [:xdigit:]l0Tv2Tw2@C[:space:]Zc/{*)>]N3j~.dMBBBB", 0, 0 }, { "[[^(\?>(([]))])[:graph:]]{65,}as#Q:lQ", 0, 0 }, { "[^[fPPUUUUUUUUUUU(\?#UUU[^UUUUUU(\?<=UUUUUUUUUGGGGGGGGGGGGGGGGGGG((\?{\?=GGGGGG.MK))+]+)&UxFW)rwv\?@D.", 0, 0 }, { "{-(60,})m", 1, 0 }, { "b[(])^w", 0, 0 }, { "[][^qVs(\?:(p])X)\?'", 0, 0 }, { "()8", 1, 0 }, { "(t[:punc[^t:(\?{][:blankcntrl:])})[^8\?]z*]", 1, 0 }, { "[:lowerprint:])[:graph:]lppppppppppppppppppppppppppppf", 0, 0 }, { "[:alph(a:])[:ascii:]g +z-Bc-U{,%Gk", 0, 0 }, { "u[:graph:(\?=]*)W:::", 0, 0 }, { "([:alnum(:])l)", 1, 0 }, { "[[[}}}}}}}}(\?)(\?{,)At]%M9FSq5)EB", 1, 0 }, { "(}````````````````(``{210,})[:(\?#space:]P[:digit:])PP.{-227,}$pK~mm ImR|{,51}[:alnum:]<)[:alpha:]", 2, 0 }, { "[^(\?<=])[:digit:]", 0, 0 }, { "[^'''''''{(\?:178,}e{,16}$QQQQQQQQQQQQQQQQQQQQQQQ$])", 0, 0 }, { "[^(\?>@K*)(\?#d18]{78,}B)[:digit:]{-193,}=wg{,59}", 0, 0 }, { "[^.{156,}!(\?<=!!!!!!!!!!!!!!(\?{!(\?(!!!!!!!!!!!!!)})TTTTTTTTTTTTTTTTTTTTTTTTTTTTT[^}}}}}}}}}}}})}}}}}}}}}}}}}]]){}^L#%-{}FC", 0, 0 }, { "(eeeee{-169,-100}-fa[:upperword:]N)$Nellllllllllllll", 1, 0 }, { "[[(\?!())\?[(\?!:alnum:]e{,28}M])[:punct:]CCCCCCCCCCCCCCCCCCCC]{-150,}{-167}", 0, 0 }, { "[[@[@(\?#@[@]P]Z{')]{-186,117}]+)7f-", 0, 0 }, { "\\Q+kD}]AEM)u ", 0, 0 }, { "([(\?{(\?=:::::::::::::&){,210}]^})P{-31,}8[:space:]C[:alnum:][:a(scii:]z|[:upperword:])[:alnum:][:graph:])zr~Zk", 1, 0 }, { ".[:space:]e[:g(\?{(\?{raph:]})})@@@@@@@@@@@@@wb|~k", 0, 0 }, { "()ooooooooo\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"[:graph:]", 1, 0 }, { "[^64h(\?(@Eyw][:xdi[git:]pP%%%%%u(uuu[:up[perword:]`8Utdh{)}]]))lW[:punct:]W.hhhhhhhhhhhhhhhhhhhhhhhh'm<<}O8`ZXtG.$", 1, 0 }, { "BPP[:digit:]bbbbbbbbbbb(bb)S+[:alnum:]", 1, 0 }, { "um.[:ascii((\?#\?!:])*)+KKKKKKKKKKKKKKKKKKKKKKKKKS.=,eDl", -1, 0 }, { "(()[^])e{-241,}", -1, 0 }, { "()[:alpha:]rliiiiiiii[:alnum:]Mb*QW9N.>\?{115,}&u*j", -1, 0 }, { "()[]p", -1, 0 }, { "(I[^]pfL)$[:punct:]", -1, 0 }, { "([])>>>>>>>>>>[:alnum:]", -1, 0 }, { "([])O\\\\\\\\\\\\\\fffffffffffffffffffffff=s6jCZy/b+ir2'*{151,}", -1, 0 }, { "([])nnnnnnnnnnnnnnnnnnnnnnnnnn[:xdigit:]^N$f", -1, 0 }, { "([]M)[:lowerprint:]a(pg$Z[:punct:])77777777777.", -1, 0 }, { "([]XXXXXXXXXXXXXXXXXXXXXX-===========)", -1, 0 }, { "([]lkX{-224}[:blankcntrl:]$gPKIZlSC#F@XX I'^}{234}yZm)uuuuuuuuuuuuuuuuuuuuuurS", -1, 0 }, { "([^0kYkg9])IIIIIIIIIIIIIIIIIIIIII/{(192,-118}l+FoSD6\?A)c[:xdigit:]`````````````````e-{-4,-170}x{4620}Z[:upperword:]", -1, 0 }, { "([^[^[^()(\?>){}B]XYF+#[:alpha:]{-85((,-55[^}t]n).{,-33}]](bQJ!|O+{175,})RFh)Z+^.{137,}:VpP[:alpha:]-MceqVVkkkk(kkkkkkkkkkkkkkkkkk)\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?{-115,-67})``````````````````````````````", -1, 0 }, { "([^]EzU[:alnum:]+^^^^^^^^^^^^^^^^^^^)[:xdigit:]HHHHHHHH$66666666666666666666666666666666UUUUUUUUUUUUUUUUUUUUL{}iiii{-76}X", -1, 0 }, { "([^]~~~~~~~~~~{240,})]NOp", -1, 0 }, { "(sb)[:digit:]VVVVVVVVx{9569}52,|]", -1, 0 }, { "(x{19762}){}", -1, 0 }, { "-[:xdigit:][]", -1, 0 }, { "121|", -1, 0 }, { "141[:xdigit:][:lowerprint:]{24}{59,191}[:digit:]/", -1, 0 }, { "G[^],,,,,,,,,,,,,+\"DiX", -1, 0 }, { "Gm(ho9:\"8{-188,-200}Z[:blankcntrl:]{,171}\?\?\?\?\?\?\?\?\?\?\?[:blankcntrl:]LLLLLLLLLLLLLLLLLLLLLLL{}^[:graph:][:blankc(\?#ntrl:])w", -1, 0 }, { "N\"\"\"\"\"\"\"-------------------------|[:alnum:]AAAAAAAAAAAAAAAAAAAAf\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?", -1, 0 }, { "U{-30,}^\?\?\?", -1, 0 }, { "W^*04rAY(Ee*>[^o3[]]_)", -1, 0 }, { "X[^]}*C[:alnum:]", -1, 0 }, { "[${,-3}]+^\?[|x8A|][:space:]'''''['''''JJJJJJJJJJJJJJJJJJJJJJJJJJJJJyl}.Y7G]", -1, 0 }, { "[()&[&&&]\?\?[\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?pg%k8ug`Wqk4|NR{h[CK5Ez=]jHpQw&`{:]{,91}D", -1, 0 }, { "[(\?#(\?:)[)([\?>)(\?>(\?:[:alnum:])]G]{85}[^)w]N]gYrUs|", -1, 0 }, { "[(\?<=)[:digit:]\?]{152,}VR|", -1, 0 }, { "[****(\?>**********(\?))TTTTTTTTTTTTTTTTTTTTTTT)[:punct:][:digit:]]GGGGGGGGGGGGGGGGGGGGG,]|.{-224}{96}{239,}1", -1, 0 }, { "[[^^PP]{,-222}{182}{141}]zFD}-.", -1, 0 }, { "[] Hn&[:xdigit:][:upperword:]f", -1, 0 }, { "[]$.B", -1, 0 }, { "[]&&&&&&&&&&&&&&&&&&&&&&&", -1, 0 }, { "[]()[:xdigit:]er063{132,140}$", -1, 0 }, { "[]+1434", -1, 0 }, { "[]-", -1, 0 }, { "[]-#yyK", -1, 0 }, { "[]-(S$5)AxbdTKO[:alnum:]", -1, 0 }, { "[]2883", -1, 0 }, { "[]2dhd-[:alpha:]sssssssssssssssss55555555555555555555555555555555Z[:punct:]", -1, 0 }, { "[]4", -1, 0 }, { "[]44444444444444444G", -1, 0 }, { "[]\?", -1, 0 }, { "[]A", -1, 0 }, { "[]Gap8bc", -1, 0 }, { "[]OOOO", -1, 0 }, { "[]PP", -1, 0 }, { "[]QQ", -1, 0 }, { "[]WaFaGO,o", -1, 0 }, { "[]Z", -1, 0 }, { "[][:alpha:]|[:digit:]Ls$I-Ff~+xA3e", -1, 0 }, { "[][:ascii:]-218", -1, 0 }, { "[][:ascii:]N}}}}}}}}}}}}}}}-{137,}8682", -1, 0 }, { "[][:lowerprint:]Ur", -1, 0 }, { "[][:space:]15097", -1, 0 }, { "[][:xdigit:]", -1, 0 }, { "[]dpSSSSSSSS", -1, 0 }, { "[]e13768", -1, 0 }, { "[]gT", -1, 0 }, { "[]h", -1, 0 }, { "[]n", -1, 0 }, { "[]vvvvvvvvvvvvvvvvvvvvvvvvvv*[:xdigit:]", -1, 0 }, { "[]{,-212}1111111111111111111C3821", -1, 0 }, { "[]{-128,}hc", -1, 0 }, { "[]{-181,}&[:xdigit:].\?}}}}}}}}}}}}}}}}}}}}}}", -1, 0 }, { "[]{}F&}i`7|ZAH", -1, 0 }, { "[^(\?())u{196,}pP][r^ndddddddddddddddddddddd]{31,246}\?J", -1, 0 }, { "[^.ii.1-S]lwwwwwwwwwwwwwwwwww[^wwwwwwwwwwwwww[:alnum:]DOpP+%fffffffffff", -1, 0 }, { "aW|", -1, 0 }, { "cT{}[]C^r2``tm", -1, 0 }, { "kkkkkkkkkkkkkkkkkkkkkkk[:blankcntrl:]|{}3{26,}{151,}[:punct:]JJJlH$gP%(2WUE%%%%%%%%%%%%%%%%%%%%a){ibf{}\?", -1, 0 }, { "lZ\?\?\?\?\?\?\?\?\?\?\?-P2eZt[:punct:]", -1, 0 }, { "vF3qn[^]N.", -1, 0 }, { "wwwwwwwwwwwwww{-176,}275[^]>.UUUUUUUUUUUUUUUUUUUUeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee2$Yd", -1, 0 }, { "{-197,223}bf]]]]]]]]]]\?&}/s\?\?~c", -1, 0 }, { "{-37,}EpP|", -1, 0 }, { "{}@]a[][:xdigit:]z{a", -1, 0 }, { "}02|", -1, 0 }, { "}}}}}}}}}(}}){}[llll]^N|", -1, 0 }, }; unsigned int i; int r; UNUSED(tc); #ifdef HAVE_REGEX_H /* * Check if we get the expected response. */ for (i = 0; i < sizeof(tests)/sizeof(*tests); i++) { regex_t preg; memset(&preg, 0, sizeof(preg)); r = regcomp(&preg, tests[i].expression, REG_EXTENDED); if (((r != 0 && tests[i].expect != -1) || (r == 0 && tests[i].expect == -1)) && !tests[i].exception) fprintf(stderr, "regcomp(%s) -> %s expected %s\n", tests[i].expression, r != 0 ? "bad" : "good", tests[i].expect == -1 ? "bad" : "good"); else if (r == 0 && preg.re_nsub != (unsigned int)tests[i].expect && !tests[i].exception) { fprintf(stderr, "%s preg.re_nsub %lu expected %d\n", tests[i].expression, (unsigned long)preg.re_nsub, tests[i].expect); tests[i].expect = preg.re_nsub; } if (r == 0) regfree(&preg); } #endif /* * Check if we get the expected response. */ for (i = 0; i < sizeof(tests)/sizeof(*tests); i++) { r = isc_regex_validate(tests[i].expression); if (r != tests[i].expect) fprintf(stderr, "%s -> %d expected %d\n", tests[i].expression, r, tests[i].expect); ATF_CHECK_EQ(r, tests[i].expect); } } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, regex_validate); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/isc/tests/hash_test.c0000644000470500017500000015057412664710322020221 0ustar lamontlamont/* * Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* ! \file */ #include #include #include #include #include #include #include #include #include #include #include #include /* * Test data from RFC6234 */ unsigned char digest[ISC_SHA512_DIGESTLENGTH]; unsigned char buffer[1024]; const char *s; char str[2 * ISC_SHA512_DIGESTLENGTH + 3]; unsigned char key[20]; isc_result_t tohexstr(unsigned char *d, unsigned int len, char *out); /* * Precondition: a hexadecimal number in *d, the length of that number in len, * and a pointer to a character array to put the output (*out). * Postcondition: A String representation of the given hexadecimal number is * placed into the array *out * * 'out' MUST point to an array of at least len * 2 + 1 * * Return values: ISC_R_SUCCESS if the operation is sucessful */ isc_result_t tohexstr(unsigned char *d, unsigned int len, char *out) { out[0]='\0'; char c_ret[] = "AA"; unsigned int i; strcat(out, "0x"); for (i = 0; i < len; i++) { sprintf(c_ret, "%02X", d[i]); strcat(out, c_ret); } strcat(out, "\0"); return (ISC_R_SUCCESS); } #define TEST_INPUT(x) (x), sizeof(x)-1 typedef struct hash_testcase { const char *input; size_t input_len; const char *result; int repeats; } hash_testcase_t; typedef struct hash_test_key { const char *key; const int len; } hash_test_key_t; /* non-hmac tests */ ATF_TC(isc_sha1); ATF_TC_HEAD(isc_sha1, tc) { atf_tc_set_md_var(tc, "descr", "sha1 examples from RFC4634"); } ATF_TC_BODY(isc_sha1, tc) { isc_sha1_t sha1; int i; UNUSED(tc); /* * These are the various test vectors. All of these are passed * through the hash function and the results are compared to the * result specified here. */ hash_testcase_t testcases[] = { /* Test 1 */ { TEST_INPUT("abc"), "0xA9993E364706816ABA3E25717850C26C9CD0D89D", 1 }, /* Test 2 */ { TEST_INPUT("abcdbcdecdefdefgefghfghighijhijkijk" "ljklmklmnlmnomnopnopq"), "0x84983E441C3BD26EBAAE4AA1F95129E5E54670F1", 1 }, /* Test 3 */ { TEST_INPUT("a") /* times 1000000 */, "0x34AA973CD4C4DAA4F61EEB2BDBAD27316534016F", 1000000 }, /* Test 4 -- exact multiple of 512 bits */ { TEST_INPUT("01234567012345670123456701234567"), "0xDEA356A2CDDD90C7A7ECEDC5EBB563934F460452", 20 /* 20 times */ }, #if 0 /* Test 5 -- optional feature, not implemented */ { TEST_INPUT(""), /* "extrabits": 0x98 , "numberextrabits": 5 */ "0x29826B003B906E660EFF4027CE98AF3531AC75BA", 1 }, #endif /* Test 6 */ { TEST_INPUT("\x5e"), "0x5E6F80A34A9798CAFC6A5DB96CC57BA4C4DB59C2", 1 }, #if 0 /* Test 7 -- optional feature, not implemented */ { TEST_INPUT("\x49\xb2\xae\xc2\x59\x4b\xbe\x3a" "\x3b\x11\x75\x42\xd9\x4a\xc8"), /* "extrabits": 0x80, "numberextrabits": 3 */ "0x6239781E03729919C01955B3FFA8ACB60B988340", 1 }, #endif /* Test 8 */ { TEST_INPUT("\x9a\x7d\xfd\xf1\xec\xea\xd0\x6e\xd6\x46" "\xaa\x55\xfe\x75\x71\x46"), "0x82ABFF6605DBE1C17DEF12A394FA22A82B544A35", 1 }, #if 0 /* Test 9 -- optional feature, not implemented */ { TEST_INPUT("\x65\xf9\x32\x99\x5b\xa4\xce\x2c\xb1\xb4" "\xa2\xe7\x1a\xe7\x02\x20\xaa\xce\xc8\x96" "\x2d\xd4\x49\x9c\xbd\x7c\x88\x7a\x94\xea" "\xaa\x10\x1e\xa5\xaa\xbc\x52\x9b\x4e\x7e" "\x43\x66\x5a\x5a\xf2\xcd\x03\xfe\x67\x8e" "\xa6\xa5\x00\x5b\xba\x3b\x08\x22\x04\xc2" "\x8b\x91\x09\xf4\x69\xda\xc9\x2a\xaa\xb3" "\xaa\x7c\x11\xa1\xb3\x2a"), /* "extrabits": 0xE0 , "numberextrabits": 3 */ "0x8C5B2A5DDAE5A97FC7F9D85661C672ADBF7933D4", 1 }, #endif /* Test 10 */ { TEST_INPUT("\xf7\x8f\x92\x14\x1b\xcd\x17\x0a\xe8\x9b" "\x4f\xba\x15\xa1\xd5\x9f\x3f\xd8\x4d\x22" "\x3c\x92\x51\xbd\xac\xbb\xae\x61\xd0\x5e" "\xd1\x15\xa0\x6a\x7c\xe1\x17\xb7\xbe\xea" "\xd2\x44\x21\xde\xd9\xc3\x25\x92\xbd\x57" "\xed\xea\xe3\x9c\x39\xfa\x1f\xe8\x94\x6a" "\x84\xd0\xcf\x1f\x7b\xee\xad\x17\x13\xe2" "\xe0\x95\x98\x97\x34\x7f\x67\xc8\x0b\x04" "\x00\xc2\x09\x81\x5d\x6b\x10\xa6\x83\x83" "\x6f\xd5\x56\x2a\x56\xca\xb1\xa2\x8e\x81" "\xb6\x57\x66\x54\x63\x1c\xf1\x65\x66\xb8" "\x6e\x3b\x33\xa1\x08\xb0\x53\x07\xc0\x0a" "\xff\x14\xa7\x68\xed\x73\x50\x60\x6a\x0f" "\x85\xe6\xa9\x1d\x39\x6f\x5b\x5c\xbe\x57" "\x7f\x9b\x38\x80\x7c\x7d\x52\x3d\x6d\x79" "\x2f\x6e\xbc\x24\xa4\xec\xf2\xb3\xa4\x27" "\xcd\xbb\xfb"), "0xCB0082C8F197D260991BA6A460E76E202BAD27B3", 1 }, { NULL, 0, NULL, 1 } }; hash_testcase_t *testcase = testcases; while (testcase->input != NULL && testcase->result != NULL) { isc_sha1_init(&sha1); for(i = 0; i < testcase->repeats; i++) { isc_sha1_update(&sha1, (const isc_uint8_t *) testcase->input, testcase->input_len); } isc_sha1_final(&sha1, digest); tohexstr(digest, ISC_SHA1_DIGESTLENGTH, str); ATF_CHECK_STREQ(str, testcase->result); testcase++; } } ATF_TC(isc_sha224); ATF_TC_HEAD(isc_sha224, tc) { atf_tc_set_md_var(tc, "descr", "sha224 examples from RFC4634"); } ATF_TC_BODY(isc_sha224, tc) { isc_sha224_t sha224; int i; UNUSED(tc); /* * These are the various test vectors. All of these are passed * through the hash function and the results are compared to the * result specified here. */ hash_testcase_t testcases[] = { /* Test 1 */ { TEST_INPUT("abc"), "0x23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7" "E36C9DA7", 1 }, /* Test 2 */ { TEST_INPUT("abcdbcdecdefdefgefghfghighijhijkijklj" "klmklmnlmnomnopnopq"), "0x75388B16512776CC5DBA5DA1FD890150B0C6455CB4F58B" "1952522525", 1 }, /* Test 3 */ { TEST_INPUT("a"), "0x20794655980C91D8BBB4C1EA97618A4BF03F42581948B2" "EE4EE7AD67", 1000000 }, /* Test 4 */ { TEST_INPUT("01234567012345670123456701234567"), "0x567F69F168CD7844E65259CE658FE7AADFA25216E68ECA" "0EB7AB8262", 20 }, #if 0 /* Test 5 -- unimplemented optional functionality */ { TEST_INPUT(""), "0xXXX", 1 }, #endif /* Test 6 */ { TEST_INPUT("\x07"), "0x00ECD5F138422B8AD74C9799FD826C531BAD2FCABC7450" "BEE2AA8C2A", 1 }, #if 0 /* Test 7 -- unimplemented optional functionality */ { TEST_INPUT(""), "0xXXX", 1 }, #endif /* Test 8 */ { TEST_INPUT("\x18\x80\x40\x05\xdd\x4f\xbd\x15\x56\x29" "\x9d\x6f\x9d\x93\xdf\x62"), "0xDF90D78AA78821C99B40BA4C966921ACCD8FFB1E98AC38" "8E56191DB1", 1 }, #if 0 /* Test 9 */ { TEST_INPUT(""), "0xXXX", 1 }, #endif /* Test 10 */ { TEST_INPUT("\x55\xb2\x10\x07\x9c\x61\xb5\x3a\xdd\x52" "\x06\x22\xd1\xac\x97\xd5\xcd\xbe\x8c\xb3" "\x3a\xa0\xae\x34\x45\x17\xbe\xe4\xd7\xba" "\x09\xab\xc8\x53\x3c\x52\x50\x88\x7a\x43" "\xbe\xbb\xac\x90\x6c\x2e\x18\x37\xf2\x6b" "\x36\xa5\x9a\xe3\xbe\x78\x14\xd5\x06\x89" "\x6b\x71\x8b\x2a\x38\x3e\xcd\xac\x16\xb9" "\x61\x25\x55\x3f\x41\x6f\xf3\x2c\x66\x74" "\xc7\x45\x99\xa9\x00\x53\x86\xd9\xce\x11" "\x12\x24\x5f\x48\xee\x47\x0d\x39\x6c\x1e" "\xd6\x3b\x92\x67\x0c\xa5\x6e\xc8\x4d\xee" "\xa8\x14\xb6\x13\x5e\xca\x54\x39\x2b\xde" "\xdb\x94\x89\xbc\x9b\x87\x5a\x8b\xaf\x0d" "\xc1\xae\x78\x57\x36\x91\x4a\xb7\xda\xa2" "\x64\xbc\x07\x9d\x26\x9f\x2c\x0d\x7e\xdd" "\xd8\x10\xa4\x26\x14\x5a\x07\x76\xf6\x7c" "\x87\x82\x73"), "0x0B31894EC8937AD9B91BDFBCBA294D9ADEFAA18E09305E" "9F20D5C3A4", 1 }, { NULL, 0, NULL, 1 } }; hash_testcase_t *testcase = testcases; while (testcase->input != NULL && testcase->result != NULL) { isc_sha224_init(&sha224); for(i = 0; i < testcase->repeats; i++) { isc_sha224_update(&sha224, (const isc_uint8_t *) testcase->input, testcase->input_len); } isc_sha224_final(digest, &sha224); /* *API inconsistency BUG HERE * in order to be consistant with the other isc_hash_final * functions the call should be * isc_sha224_final(&sha224, digest); */ tohexstr(digest, ISC_SHA224_DIGESTLENGTH, str); ATF_CHECK_STREQ(str, testcase->result); testcase++; } } ATF_TC(isc_sha256); ATF_TC_HEAD(isc_sha256, tc) { atf_tc_set_md_var(tc, "descr", "sha224 examples from RFC4634"); } ATF_TC_BODY(isc_sha256, tc) { isc_sha256_t sha256; int i; UNUSED(tc); /* * These are the various test vectors. All of these are passed * through the hash function and the results are compared to the * result specified here. */ hash_testcase_t testcases[] = { /* Test 1 */ { TEST_INPUT("abc"), "0xBA7816BF8F01CFEA414140DE5DAE2223B00361A396177A" "9CB410FF61F20015AD", 1 }, /* Test 2 */ { TEST_INPUT("abcdbcdecdefdefgefghfghighijhijkijkljk" "lmklmnlmnomnopnopq"), "0x248D6A61D20638B8E5C026930C3E6039A33CE45964FF21" "67F6ECEDD419DB06C1", 1 }, /* Test 3 */ { TEST_INPUT("a"), "0xCDC76E5C9914FB9281A1C7E284D73E67F1809A48A49720" "0E046D39CCC7112CD0", 1000000 }, /* Test 4 */ { TEST_INPUT("01234567012345670123456701234567"), "0x594847328451BDFA85056225462CC1D867D877FB388DF0" "CE35F25AB5562BFBB5", 20 }, #if 0 /* Test 5 -- unimplemented optional functionality */ { TEST_INPUT(""), "0xXXX", 1 }, #endif /* Test 6 */ { TEST_INPUT("\x19"), "0x68AA2E2EE5DFF96E3355E6C7EE373E3D6A4E17F75F9518" "D843709C0C9BC3E3D4", 1 }, #if 0 /* Test 7 -- unimplemented optional functionality */ { TEST_INPUT(""), "0xXXX", 1 }, #endif /* Test 8 */ { TEST_INPUT("\xe3\xd7\x25\x70\xdc\xdd\x78\x7c\xe3" "\x88\x7a\xb2\xcd\x68\x46\x52"), "0x175EE69B02BA9B58E2B0A5FD13819CEA573F3940A94F82" "5128CF4209BEABB4E8", 1 }, #if 0 /* Test 9 -- unimplemented optional functionality */ { TEST_INPUT(""), "0xXXX", 1 }, #endif /* Test 10 */ { TEST_INPUT("\x83\x26\x75\x4e\x22\x77\x37\x2f\x4f\xc1" "\x2b\x20\x52\x7a\xfe\xf0\x4d\x8a\x05\x69" "\x71\xb1\x1a\xd5\x71\x23\xa7\xc1\x37\x76" "\x00\x00\xd7\xbe\xf6\xf3\xc1\xf7\xa9\x08" "\x3a\xa3\x9d\x81\x0d\xb3\x10\x77\x7d\xab" "\x8b\x1e\x7f\x02\xb8\x4a\x26\xc7\x73\x32" "\x5f\x8b\x23\x74\xde\x7a\x4b\x5a\x58\xcb" "\x5c\x5c\xf3\x5b\xce\xe6\xfb\x94\x6e\x5b" "\xd6\x94\xfa\x59\x3a\x8b\xeb\x3f\x9d\x65" "\x92\xec\xed\xaa\x66\xca\x82\xa2\x9d\x0c" "\x51\xbc\xf9\x33\x62\x30\xe5\xd7\x84\xe4" "\xc0\xa4\x3f\x8d\x79\xa3\x0a\x16\x5c\xba" "\xbe\x45\x2b\x77\x4b\x9c\x71\x09\xa9\x7d" "\x13\x8f\x12\x92\x28\x96\x6f\x6c\x0a\xdc" "\x10\x6a\xad\x5a\x9f\xdd\x30\x82\x57\x69" "\xb2\xc6\x71\xaf\x67\x59\xdf\x28\xeb\x39" "\x3d\x54\xd6"), "0x97DBCA7DF46D62C8A422C941DD7E835B8AD3361763F7E9" "B2D95F4F0DA6E1CCBC", 1 }, { NULL, 0, NULL, 1 } }; hash_testcase_t *testcase = testcases; while (testcase->input != NULL && testcase->result != NULL) { isc_sha256_init(&sha256); for(i = 0; i < testcase->repeats; i++) { isc_sha256_update(&sha256, (const isc_uint8_t *) testcase->input, testcase->input_len); } isc_sha256_final(digest, &sha256); /* *API inconsistency BUG HERE * in order to be consistant with the other isc_hash_final * functions the call should be * isc_sha224_final(&sha224, digest); */ tohexstr(digest, ISC_SHA256_DIGESTLENGTH, str); ATF_CHECK_STREQ(str, testcase->result); testcase++; } } ATF_TC(isc_sha384); ATF_TC_HEAD(isc_sha384, tc) { atf_tc_set_md_var(tc, "descr", "sha224 examples from RFC4634"); } ATF_TC_BODY(isc_sha384, tc) { isc_sha384_t sha384; int i; UNUSED(tc); /* * These are the various test vectors. All of these are passed * through the hash function and the results are compared to the * result specified here. */ hash_testcase_t testcases[] = { /* Test 1 */ { TEST_INPUT("abc"), "0xCB00753F45A35E8BB5A03D699AC65007272C32AB0EDED1" "631A8B605A43FF5BED8086072BA1E7CC2358BAEC" "A134C825A7", 1 }, /* Test 2 */ { TEST_INPUT("abcdefghbcdefghicdefghijdefghijkefghijkl" "fghijklmghijklmnhijklmnoijklmnopjklmnopq" "klmnopqrlmnopqrsmnopqrstnopqrstu"), "0x09330C33F71147E83D192FC782CD1B4753111B173B3B05" "D22FA08086E3B0F712FCC7C71A557E2DB966C3E9" "FA91746039", 1 }, /* Test 3 */ { TEST_INPUT("a"), "0x9D0E1809716474CB086E834E310A4A1CED149E9C00F248" "527972CEC5704C2A5B07B8B3DC38ECC4EBAE97DD" "D87F3D8985", 1000000 }, /* Test 4 */ { TEST_INPUT("01234567012345670123456701234567"), "0x2FC64A4F500DDB6828F6A3430B8DD72A368EB7F3A8322A" "70BC84275B9C0B3AB00D27A5CC3C2D224AA6B61A" "0D79FB4596", 20 }, #if 0 /* Test 5 -- unimplemented optional functionality */ { TEST_INPUT(""), "0xXXX", 1 }, #endif /* Test 6 */ { TEST_INPUT("\xb9"), "0xBC8089A19007C0B14195F4ECC74094FEC64F01F9092928" "2C2FB392881578208AD466828B1C6C283D2722CF" "0AD1AB6938", 1 }, #if 0 /* Test 7 -- unimplemented optional functionality */ { TEST_INPUT(""), "0xXXX", 1 }, #endif /* Test 8 */ { TEST_INPUT("\xa4\x1c\x49\x77\x79\xc0\x37\x5f\xf1" "\x0a\x7f\x4e\x08\x59\x17\x39"), "0xC9A68443A005812256B8EC76B00516F0DBB74FAB26D665" "913F194B6FFB0E91EA9967566B58109CBC675CC2" "08E4C823F7", 1 }, #if 0 /* Test 9 -- unimplemented optional functionality */ { TEST_INPUT(""), "0xXXX", 1 }, #endif /* Test 10 */ { TEST_INPUT("\x39\x96\x69\xe2\x8f\x6b\x9c\x6d\xbc\xbb" "\x69\x12\xec\x10\xff\xcf\x74\x79\x03\x49" "\xb7\xdc\x8f\xbe\x4a\x8e\x7b\x3b\x56\x21" "\xdb\x0f\x3e\x7d\xc8\x7f\x82\x32\x64\xbb" "\xe4\x0d\x18\x11\xc9\xea\x20\x61\xe1\xc8" "\x4a\xd1\x0a\x23\xfa\xc1\x72\x7e\x72\x02" "\xfc\x3f\x50\x42\xe6\xbf\x58\xcb\xa8\xa2" "\x74\x6e\x1f\x64\xf9\xb9\xea\x35\x2c\x71" "\x15\x07\x05\x3c\xf4\xe5\x33\x9d\x52\x86" "\x5f\x25\xcc\x22\xb5\xe8\x77\x84\xa1\x2f" "\xc9\x61\xd6\x6c\xb6\xe8\x95\x73\x19\x9a" "\x2c\xe6\x56\x5c\xbd\xf1\x3d\xca\x40\x38" "\x32\xcf\xcb\x0e\x8b\x72\x11\xe8\x3a\xf3" "\x2a\x11\xac\x17\x92\x9f\xf1\xc0\x73\xa5" "\x1c\xc0\x27\xaa\xed\xef\xf8\x5a\xad\x7c" "\x2b\x7c\x5a\x80\x3e\x24\x04\xd9\x6d\x2a" "\x77\x35\x7b\xda\x1a\x6d\xae\xed\x17\x15" "\x1c\xb9\xbc\x51\x25\xa4\x22\xe9\x41\xde" "\x0c\xa0\xfc\x50\x11\xc2\x3e\xcf\xfe\xfd" "\xd0\x96\x76\x71\x1c\xf3\xdb\x0a\x34\x40" "\x72\x0e\x16\x15\xc1\xf2\x2f\xbc\x3c\x72" "\x1d\xe5\x21\xe1\xb9\x9b\xa1\xbd\x55\x77" "\x40\x86\x42\x14\x7e\xd0\x96"), "0x4F440DB1E6EDD2899FA335F09515AA025EE177A79F4B4A" "AF38E42B5C4DE660F5DE8FB2A5B2FBD2A3CBFFD2" "0CFF1288C0", 1 }, { NULL, 0, NULL, 1 } }; hash_testcase_t *testcase = testcases; while (testcase->input != NULL && testcase->result != NULL) { isc_sha384_init(&sha384); for(i = 0; i < testcase->repeats; i++) { isc_sha384_update(&sha384, (const isc_uint8_t *) testcase->input, testcase->input_len); } isc_sha384_final(digest, &sha384); /* *API inconsistency BUG HERE * in order to be consistant with the other isc_hash_final * functions the call should be * isc_sha224_final(&sha224, digest); */ tohexstr(digest, ISC_SHA384_DIGESTLENGTH, str); ATF_CHECK_STREQ(str, testcase->result); testcase++; } } ATF_TC(isc_sha512); ATF_TC_HEAD(isc_sha512, tc) { atf_tc_set_md_var(tc, "descr", "sha224 examples from RFC4634"); } ATF_TC_BODY(isc_sha512, tc) { isc_sha512_t sha512; int i; UNUSED(tc); /* * These are the various test vectors. All of these are passed * through the hash function and the results are compared to the * result specified here. */ hash_testcase_t testcases[] = { /* Test 1 */ { TEST_INPUT("abc"), "0xDDAF35A193617ABACC417349AE20413112E6FA4E89A97E" "A20A9EEEE64B55D39A2192992A274FC1A836BA3C" "23A3FEEBBD454D4423643CE80E2A9AC94FA54CA49F", 1 }, /* Test 2 */ { TEST_INPUT("abcdefghbcdefghicdefghijdefghijkefghijkl" "fghijklmghijklmnhijklmnoijklmnopjklmnopq" "klmnopqrlmnopqrsmnopqrstnopqrstu"), "0x8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7F" "A17299AEADB6889018501D289E4900F7E4331B99" "DEC4B5433AC7D329EEB6DD26545E96E55B874BE909", 1 }, /* Test 3 */ { TEST_INPUT("a"), "0xE718483D0CE769644E2E42C7BC15B4638E1F98B13B2044" "285632A803AFA973EBDE0FF244877EA60A4CB043" "2CE577C31BEB009C5C2C49AA2E4EADB217AD8CC09B", 1000000 }, /* Test 4 */ { TEST_INPUT("01234567012345670123456701234567"), "0x89D05BA632C699C31231DED4FFC127D5A894DAD412C0E0" "24DB872D1ABD2BA8141A0F85072A9BE1E2AA04CF" "33C765CB510813A39CD5A84C4ACAA64D3F3FB7BAE9", 20 }, #if 0 /* Test 5 -- unimplemented optional functionality */ { TEST_INPUT(""), "0xXXX", 1 }, #endif /* Test 6 */ { TEST_INPUT("\xD0"), "0x9992202938E882E73E20F6B69E68A0A7149090423D93C8" "1BAB3F21678D4ACEEEE50E4E8CAFADA4C85A54EA" "8306826C4AD6E74CECE9631BFA8A549B4AB3FBBA15", 1 }, #if 0 /* Test 7 -- unimplemented optional functionality */ { TEST_INPUT(""), "0xXXX", 1 }, #endif /* Test 8 */ { TEST_INPUT("\x8d\x4e\x3c\x0e\x38\x89\x19\x14\x91\x81" "\x6e\x9d\x98\xbf\xf0\xa0"), "0xCB0B67A4B8712CD73C9AABC0B199E9269B20844AFB75AC" "BDD1C153C9828924C3DDEDAAFE669C5FDD0BC66F" "630F6773988213EB1B16F517AD0DE4B2F0C95C90F8", 1 }, #if 0 /* Test 9 -- unimplemented optional functionality */ { TEST_INPUT(""), "0xXXX", 1 }, #endif /* Test 10 */ { TEST_INPUT("\xa5\x5f\x20\xc4\x11\xaa\xd1\x32\x80\x7a" "\x50\x2d\x65\x82\x4e\x31\xa2\x30\x54\x32" "\xaa\x3d\x06\xd3\xe2\x82\xa8\xd8\x4e\x0d" "\xe1\xde\x69\x74\xbf\x49\x54\x69\xfc\x7f" "\x33\x8f\x80\x54\xd5\x8c\x26\xc4\x93\x60" "\xc3\xe8\x7a\xf5\x65\x23\xac\xf6\xd8\x9d" "\x03\xe5\x6f\xf2\xf8\x68\x00\x2b\xc3\xe4" "\x31\xed\xc4\x4d\xf2\xf0\x22\x3d\x4b\xb3" "\xb2\x43\x58\x6e\x1a\x7d\x92\x49\x36\x69" "\x4f\xcb\xba\xf8\x8d\x95\x19\xe4\xeb\x50" "\xa6\x44\xf8\xe4\xf9\x5e\xb0\xea\x95\xbc" "\x44\x65\xc8\x82\x1a\xac\xd2\xfe\x15\xab" "\x49\x81\x16\x4b\xbb\x6d\xc3\x2f\x96\x90" "\x87\xa1\x45\xb0\xd9\xcc\x9c\x67\xc2\x2b" "\x76\x32\x99\x41\x9c\xc4\x12\x8b\xe9\xa0" "\x77\xb3\xac\xe6\x34\x06\x4e\x6d\x99\x28" "\x35\x13\xdc\x06\xe7\x51\x5d\x0d\x73\x13" "\x2e\x9a\x0d\xc6\xd3\xb1\xf8\xb2\x46\xf1" "\xa9\x8a\x3f\xc7\x29\x41\xb1\xe3\xbb\x20" "\x98\xe8\xbf\x16\xf2\x68\xd6\x4f\x0b\x0f" "\x47\x07\xfe\x1e\xa1\xa1\x79\x1b\xa2\xf3" "\xc0\xc7\x58\xe5\xf5\x51\x86\x3a\x96\xc9" "\x49\xad\x47\xd7\xfb\x40\xd2"), "0xC665BEFB36DA189D78822D10528CBF3B12B3EEF7260399" "09C1A16A270D48719377966B957A878E72058477" "9A62825C18DA26415E49A7176A894E7510FD1451F5", 1 }, { NULL, 0, NULL, 1 } }; hash_testcase_t *testcase = testcases; while (testcase->input != NULL && testcase->result != NULL) { isc_sha512_init(&sha512); for(i = 0; i < testcase->repeats; i++) { isc_sha512_update(&sha512, (const isc_uint8_t *) testcase->input, testcase->input_len); } isc_sha512_final(digest, &sha512); /* *API inconsistency BUG HERE * in order to be consistant with the other isc_hash_final * functions the call should be * isc_sha224_final(&sha224, digest); */ tohexstr(digest, ISC_SHA512_DIGESTLENGTH, str); ATF_CHECK_STREQ(str, testcase->result); testcase++; } } ATF_TC(isc_md5); ATF_TC_HEAD(isc_md5, tc) { atf_tc_set_md_var(tc, "descr", "md5 example from RFC1321"); } ATF_TC_BODY(isc_md5, tc) { isc_md5_t md5; int i; UNUSED(tc); /* * These are the various test vectors. All of these are passed * through the hash function and the results are compared to the * result specified here. */ hash_testcase_t testcases[] = { { TEST_INPUT(""), "0xD41D8CD98F00B204E9800998ECF8427E", 1 }, { TEST_INPUT("a"), "0x0CC175B9C0F1B6A831C399E269772661", 1 }, { TEST_INPUT("abc"), "0x900150983CD24FB0D6963F7D28E17F72", 1 }, { TEST_INPUT("message digest"), "0xF96B697D7CB7938D525A2F31AAF161D0", 1 }, { TEST_INPUT("abcdefghijklmnopqrstuvwxyz"), "0xC3FCD3D76192E4007DFB496CCA67E13B", 1 }, { TEST_INPUT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm" "nopqrstuvwxyz0123456789"), "0xD174AB98D277D9F5A5611C2C9F419D9F", 1 }, { TEST_INPUT("123456789012345678901234567890123456789" "01234567890123456789012345678901234567890"), "0x57EDF4A22BE3C955AC49DA2E2107B67A", 1 }, { NULL, 0, NULL, 1 } }; hash_testcase_t *testcase = testcases; while (testcase->input != NULL && testcase->result != NULL) { isc_md5_init(&md5); for(i = 0; i < testcase->repeats; i++) { isc_md5_update(&md5, (const isc_uint8_t *) testcase->input, testcase->input_len); } isc_md5_final(&md5, digest); tohexstr(digest, ISC_MD5_DIGESTLENGTH, str); ATF_CHECK_STREQ(str, testcase->result); testcase++; } } /* HMAC-SHA1 test */ ATF_TC(isc_hmacsha1); ATF_TC_HEAD(isc_hmacsha1, tc) { atf_tc_set_md_var(tc, "descr", "HMAC-SHA1 examples from RFC2104"); } ATF_TC_BODY(isc_hmacsha1, tc) { isc_hmacsha1_t hmacsha1; UNUSED(tc); /* * These are the various test vectors. All of these are passed * through the hash function and the results are compared to the * result specified here. */ hash_testcase_t testcases[] = { /* Test 1 */ { TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"), "0xB617318655057264E28BC0B6FB378C8EF146BE00", 1 }, /* Test 2 */ { TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61" "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20" "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"), "0xEFFCDF6AE5EB2FA2D27416D5F184DF9C259A7C79", 1 }, /* Test 3 */ { TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"), "0x125D7342B9AC11CD91A39AF48AA17B4F63F175D3", 1 }, /* Test 4 */ { TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"), "0x4C9007F4026250C6BC8414F9BF50C86C2D7235DA", 1 }, #if 0 /* Test 5 -- unimplemented optional functionality */ { TEST_INPUT("Test With Truncation"), "0x4C1A03424B55E07FE7F27BE1", 1 }, #endif /* Test 6 */ { TEST_INPUT("Test Using Larger Than Block-Size Key - " "Hash Key First"), "0xAA4AE5E15272D00E95705637CE8A3B55ED402112", 1 }, /* Test 7 */ { TEST_INPUT("Test Using Larger Than Block-Size Key and " "Larger Than One Block-Size Data"), "0xE8E99D0F45237D786D6BBAA7965C7808BBFF1A91", 1 }, { NULL, 0, NULL, 1 } }; hash_testcase_t *testcase = testcases; hash_test_key_t test_keys[] = { /* Key 1 */ { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20 }, /* Key 2 */ { "Jefe", 4 }, /* Key 3 */ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 20 }, /* Key 4 */ { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a" "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14" "\x15\x16\x17\x18\x19", 25 }, #if 0 /* Key 5 */ { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c" "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 20 }, #endif /* Key 6 */ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 80 }, /* Key 7 */ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 80 }, { "", 0 } }; hash_test_key_t *test_key = test_keys; while (testcase->input != NULL && testcase->result != NULL) { memmove(buffer, test_key->key, test_key->len); isc_hmacsha1_init(&hmacsha1, buffer, test_key->len); isc_hmacsha1_update(&hmacsha1, (const isc_uint8_t *) testcase->input, testcase->input_len); isc_hmacsha1_sign(&hmacsha1, digest, ISC_SHA1_DIGESTLENGTH); tohexstr(digest, ISC_SHA1_DIGESTLENGTH, str); ATF_CHECK_STREQ(str, testcase->result); testcase++; test_key++; } } /* HMAC-SHA224 test */ ATF_TC(isc_hmacsha224); ATF_TC_HEAD(isc_hmacsha224, tc) { atf_tc_set_md_var(tc, "descr", "HMAC-SHA224 examples from RFC4634"); } ATF_TC_BODY(isc_hmacsha224, tc) { isc_hmacsha224_t hmacsha224; UNUSED(tc); /* * These are the various test vectors. All of these are passed * through the hash function and the results are compared to the * result specified here. */ hash_testcase_t testcases[] = { /* Test 1 */ { TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"), "0x896FB1128ABBDF196832107CD49DF33F47B4B1169912BA" "4F53684B22", 1 }, /* Test 2 */ { TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61" "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20" "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"), "0xA30E01098BC6DBBF45690F3A7E9E6D0F8BBEA2A39E61480" "08FD05E44", 1 }, /* Test 3 */ { TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"), "0x7FB3CB3588C6C1F6FFA9694D7D6AD2649365B0C1F65D69" "D1EC8333EA", 1 }, /* Test 4 */ { TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"), "0x6C11506874013CAC6A2ABC1BB382627CEC6A90D86EFC01" "2DE7AFEC5A", 1 }, #if 0 /* Test 5 -- unimplemented optional functionality */ { TEST_INPUT("Test With Truncation"), "0x4C1A03424B55E07FE7F27BE1", 1 }, #endif /* Test 6 */ { TEST_INPUT("Test Using Larger Than Block-Size Key - " "Hash Key First"), "0x95E9A0DB962095ADAEBE9B2D6F0DBCE2D499F112F2D2B7" "273FA6870E", 1 }, /* Test 7 */ { TEST_INPUT("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20" "\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67" "\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20" "\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b" "\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20" "\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67" "\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c" "\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64" "\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b" "\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74" "\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65" "\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62" "\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20" "\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41" "\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68" "\x6d\x2e"), "0x3A854166AC5D9F023F54D517D0B39DBD946770DB9C2B95" "C9F6F565D1", 1 }, { NULL, 0, NULL, 1 } }; hash_testcase_t *testcase = testcases; hash_test_key_t test_keys[] = { /* Key 1 */ { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20 }, /* Key 2 */ { "Jefe", 4 }, /* Key 3 */ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 20 }, /* Key 4 */ { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a" "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14" "\x15\x16\x17\x18\x19", 25 }, #if 0 /* Key 5 */ { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c" "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 20 }, #endif /* Key 6 */ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 }, /* Key 7 */ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 }, { "", 0 } }; hash_test_key_t *test_key = test_keys; while (testcase->input != NULL && testcase->result != NULL) { memmove(buffer, test_key->key, test_key->len); isc_hmacsha224_init(&hmacsha224, buffer, test_key->len); isc_hmacsha224_update(&hmacsha224, (const isc_uint8_t *) testcase->input, testcase->input_len); isc_hmacsha224_sign(&hmacsha224, digest, ISC_SHA224_DIGESTLENGTH); tohexstr(digest, ISC_SHA224_DIGESTLENGTH, str); ATF_CHECK_STREQ(str, testcase->result); testcase++; test_key++; } } /* HMAC-SHA256 test */ ATF_TC(isc_hmacsha256); ATF_TC_HEAD(isc_hmacsha256, tc) { atf_tc_set_md_var(tc, "descr", "HMAC-SHA256 examples from RFC4634"); } ATF_TC_BODY(isc_hmacsha256, tc) { isc_hmacsha256_t hmacsha256; UNUSED(tc); /* * These are the various test vectors. All of these are passed * through the hash function and the results are compared to the * result specified here. */ hash_testcase_t testcases[] = { /* Test 1 */ { TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"), "0xB0344C61D8DB38535CA8AFCEAF0BF12B881DC200C9833D" "A726E9376C2E32CFF7", 1 }, /* Test 2 */ { TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61" "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20" "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"), "0x5BDCC146BF60754E6A042426089575C75A003F089D2739" "839DEC58B964EC3843", 1 }, /* Test 3 */ { TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"), "0x773EA91E36800E46854DB8EBD09181A72959098B3EF8C1" "22D9635514CED565FE", 1 }, /* Test 4 */ { TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"), "0x82558A389A443C0EA4CC819899F2083A85F0FAA3E578F8" "077A2E3FF46729665B", 1 }, #if 0 /* Test 5 -- unimplemented optional functionality */ { TEST_INPUT("Test With Truncation"), "0x4C1A03424B55E07FE7F27BE1", 1 }, #endif /* Test 6 */ { TEST_INPUT("Test Using Larger Than Block-Size Key - " "Hash Key First"), "0x60E431591EE0B67F0D8A26AACBF5B77F8E0BC6213728C5" "140546040F0EE37F54", 1 }, /* Test 7 */ { TEST_INPUT("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20" "\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67" "\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20" "\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b" "\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20" "\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67" "\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c" "\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64" "\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b" "\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74" "\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65" "\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62" "\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20" "\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41" "\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68" "\x6d\x2e"), "0x9B09FFA71B942FCB27635FBCD5B0E944BFDC63644F0713" "938A7F51535C3A35E2", 1 }, { NULL, 0, NULL, 1 } }; hash_testcase_t *testcase = testcases; hash_test_key_t test_keys[] = { /* Key 1 */ { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20 }, /* Key 2 */ { "Jefe", 4 }, /* Key 3 */ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 20 }, /* Key 4 */ { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a" "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14" "\x15\x16\x17\x18\x19", 25 }, #if 0 /* Key 5 */ { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c" "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 20 }, #endif /* Key 6 */ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 }, /* Key 7 */ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 }, { "", 0 } }; hash_test_key_t *test_key = test_keys; while (testcase->input != NULL && testcase->result != NULL) { memmove(buffer, test_key->key, test_key->len); isc_hmacsha256_init(&hmacsha256, buffer, test_key->len); isc_hmacsha256_update(&hmacsha256, (const isc_uint8_t *) testcase->input, testcase->input_len); isc_hmacsha256_sign(&hmacsha256, digest, ISC_SHA256_DIGESTLENGTH); tohexstr(digest, ISC_SHA256_DIGESTLENGTH, str); ATF_CHECK_STREQ(str, testcase->result); testcase++; test_key++; } } /* HMAC-SHA384 test */ ATF_TC(isc_hmacsha384); ATF_TC_HEAD(isc_hmacsha384, tc) { atf_tc_set_md_var(tc, "descr", "HMAC-SHA384 examples from RFC4634"); } ATF_TC_BODY(isc_hmacsha384, tc) { isc_hmacsha384_t hmacsha384; UNUSED(tc); /* * These are the various test vectors. All of these are passed * through the hash function and the results are compared to the * result specified here. */ hash_testcase_t testcases[] = { /* Test 1 */ { TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"), "0xAFD03944D84895626B0825F4AB46907F15F9DADBE4101E" "C682AA034C7CEBC59CFAEA9EA9076EDE7F4AF152" "E8B2FA9CB6", 1 }, /* Test 2 */ { TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61" "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20" "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"), "0xAF45D2E376484031617F78D2B58A6B1B9C7EF464F5A01B" "47E42EC3736322445E8E2240CA5E69E2C78B3239" "ECFAB21649", 1 }, /* Test 3 */ { TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"), "0x88062608D3E6AD8A0AA2ACE014C8A86F0AA635D947AC9F" "EBE83EF4E55966144B2A5AB39DC13814B94E3AB6" "E101A34F27", 1 }, /* Test 4 */ { TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"), "0x3E8A69B7783C25851933AB6290AF6CA77A998148085000" "9CC5577C6E1F573B4E6801DD23C4A7D679CCF8A3" "86C674CFFB", 1 }, #if 0 /* Test 5 -- unimplemented optional functionality */ { TEST_INPUT("Test With Truncation"), "0x4C1A03424B55E07FE7F27BE1", 1 }, #endif /* Test 6 */ { TEST_INPUT("Test Using Larger Than Block-Size Key - " "Hash Key First"), "0x4ECE084485813E9088D2C63A041BC5B44F9EF1012A2B58" "8F3CD11F05033AC4C60C2EF6AB4030FE8296248D" "F163F44952", 1 }, /* Test 7 */ { TEST_INPUT("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20" "\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67" "\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20" "\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b" "\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20" "\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67" "\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c" "\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64" "\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b" "\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74" "\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65" "\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62" "\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20" "\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41" "\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68" "\x6d\x2e"), "0x6617178E941F020D351E2F254E8FD32C602420FEB0B8FB" "9ADCCEBB82461E99C5A678CC31E799176D3860E6" "110C46523E", 1 }, { NULL, 0, NULL, 1 } }; hash_testcase_t *testcase = testcases; hash_test_key_t test_keys[] = { /* Key 1 */ { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20 }, /* Key 2 */ { "Jefe", 4 }, /* Key 3 */ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 20 }, /* Key 4 */ { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a" "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14" "\x15\x16\x17\x18\x19", 25 }, #if 0 /* Key 5 */ { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c" "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 20 }, #endif /* Key 6 */ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 }, /* Key 7 */ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 }, { "", 0 } }; hash_test_key_t *test_key = test_keys; while (testcase->input != NULL && testcase->result != NULL) { memmove(buffer, test_key->key, test_key->len); isc_hmacsha384_init(&hmacsha384, buffer, test_key->len); isc_hmacsha384_update(&hmacsha384, (const isc_uint8_t *) testcase->input, testcase->input_len); isc_hmacsha384_sign(&hmacsha384, digest, ISC_SHA384_DIGESTLENGTH); tohexstr(digest, ISC_SHA384_DIGESTLENGTH, str); ATF_CHECK_STREQ(str, testcase->result); testcase++; test_key++; } } /* HMAC-SHA512 test */ ATF_TC(isc_hmacsha512); ATF_TC_HEAD(isc_hmacsha512, tc) { atf_tc_set_md_var(tc, "descr", "HMAC-SHA512 examples from RFC4634"); } ATF_TC_BODY(isc_hmacsha512, tc) { isc_hmacsha512_t hmacsha512; UNUSED(tc); /* * These are the various test vectors. All of these are passed * through the hash function and the results are compared to the * result specified here. */ hash_testcase_t testcases[] = { /* Test 1 */ { TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"), "0x87AA7CDEA5EF619D4FF0B4241A1D6CB02379F4E2CE4EC2" "787AD0B30545E17CDEDAA833B7D6B8A702038B27" "4EAEA3F4E4BE9D914EEB61F1702E696C203A126854", 1 }, /* Test 2 */ { TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61" "\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20" "\x6e\x6f\x74\x68\x69\x6e\x67\x3f"), "0x164B7A7BFCF819E2E395FBE73B56E0A387BD64222E831F" "D610270CD7EA2505549758BF75C05A994A6D034F" "65F8F0E6FDCAEAB1A34D4A6B4B636E070A38BCE737", 1 }, /* Test 3 */ { TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"), "0xFA73B0089D56A284EFB0F0756C890BE9B1B5DBDD8EE81A" "3655F83E33B2279D39BF3E848279A722C806B485" "A47E67C807B946A337BEE8942674278859E13292FB", 1 }, /* Test 4 */ { TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"), "0xB0BA465637458C6990E5A8C5F61D4AF7E576D97FF94B87" "2DE76F8050361EE3DBA91CA5C11AA25EB4D67927" "5CC5788063A5F19741120C4F2DE2ADEBEB10A298DD", 1 }, #if 0 /* Test 5 -- unimplemented optional functionality */ { TEST_INPUT("Test With Truncation"), "0x4C1A03424B55E07FE7F27BE1", 1 }, #endif /* Test 6 */ { TEST_INPUT("Test Using Larger Than Block-Size Key - " "Hash Key First"), "0x80B24263C7C1A3EBB71493C1DD7BE8B49B46D1F41B4AEE" "C1121B013783F8F3526B56D037E05F2598BD0FD2" "215D6A1E5295E64F73F63F0AEC8B915A985D786598", 1 }, /* Test 7 */ { TEST_INPUT("\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20" "\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67" "\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20" "\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b" "\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20" "\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67" "\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c" "\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64" "\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b" "\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74" "\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65" "\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62" "\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20" "\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41" "\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68" "\x6d\x2e"), "0xE37B6A775DC87DBAA4DFA9F96E5E3FFDDEBD71F8867289" "865DF5A32D20CDC944B6022CAC3C4982B10D5EEB" "55C3E4DE15134676FB6DE0446065C97440FA8C6A58", 1 }, { NULL, 0, NULL, 1 } }; hash_testcase_t *testcase = testcases; hash_test_key_t test_keys[] = { /* Key 1 */ { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20 }, /* Key 2 */ { "Jefe", 4 }, /* Key 3 */ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 20 }, /* Key 4 */ { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a" "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14" "\x15\x16\x17\x18\x19", 25 }, #if 0 /* Key 5 */ { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c" "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 20 }, #endif /* Key 6 */ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 }, /* Key 7 */ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 }, { "", 0 } }; hash_test_key_t *test_key = test_keys; while (testcase->input != NULL && testcase->result != NULL) { memmove(buffer, test_key->key, test_key->len); isc_hmacsha512_init(&hmacsha512, buffer, test_key->len); isc_hmacsha512_update(&hmacsha512, (const isc_uint8_t *) testcase->input, testcase->input_len); isc_hmacsha512_sign(&hmacsha512, digest, ISC_SHA512_DIGESTLENGTH); tohexstr(digest, ISC_SHA512_DIGESTLENGTH, str); ATF_CHECK_STREQ(str, testcase->result); testcase++; test_key++; } } /* HMAC-MD5 Test */ ATF_TC(isc_hmacmd5); ATF_TC_HEAD(isc_hmacmd5, tc) { atf_tc_set_md_var(tc, "descr", "HMAC-MD5 examples from RFC2104"); } ATF_TC_BODY(isc_hmacmd5, tc) { isc_hmacmd5_t hmacmd5; UNUSED(tc); /* * These are the various test vectors. All of these are passed * through the hash function and the results are compared to the * result specified here. */ hash_testcase_t testcases[] = { /* Test 1 */ { TEST_INPUT("\x48\x69\x20\x54\x68\x65\x72\x65"), "0x9294727A3638BB1C13F48EF8158BFC9D", 1 }, /* Test 2 */ { TEST_INPUT("\x77\x68\x61\x74\x20\x64\x6f\x20\x79" "\x61\x20\x77\x61\x6e\x74\x20\x66\x6f" "\x72\x20\x6e\x6f\x74\x68\x69\x6e\x67\x3f"), "0x750C783E6AB0B503EAA86E310A5DB738", 1 }, /* Test 3 */ { TEST_INPUT("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"), "0x56BE34521D144C88DBB8C733F0E8B3F6", 1 }, /* Test 4 */ { TEST_INPUT("\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"), "0x697EAF0ACA3A3AEA3A75164746FFAA79", 1 }, #if 0 /* Test 5 -- unimplemented optional functionality */ { TEST_INPUT("Test With Truncation"), "0x4C1A03424B55E07FE7F27BE1", 1 }, /* Test 6 -- unimplemented optional functionality */ { TEST_INPUT("Test Using Larger Than Block-Size Key - " "Hash Key First"), "0xAA4AE5E15272D00E95705637CE8A3B55ED402112", 1 }, /* Test 7 -- unimplemented optional functionality */ { TEST_INPUT("Test Using Larger Than Block-Size Key and " "Larger Than One Block-Size Data"), "0xE8E99D0F45237D786D6BBAA7965C7808BBFF1A91", 1 }, #endif { NULL, 0, NULL, 1 } }; hash_testcase_t *testcase = testcases; hash_test_key_t test_keys[] = { /* Key 1 */ { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b\x0b\x0b\x0b", 16 }, /* Key 2 */ { "Jefe", 4 }, /* Key 3 */ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa", 16 }, /* Key 4 */ { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a" "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14" "\x15\x16\x17\x18\x19", 25 }, #if 0 /* Key 5 */ { "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c" "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 20 }, /* Key 6 */ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 }, /* Key 7 */ { "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131 }, #endif { "", 0 } }; hash_test_key_t *test_key = test_keys; while (testcase->input != NULL && testcase->result != NULL) { memmove(buffer, test_key->key, test_key->len); isc_hmacmd5_init(&hmacmd5, buffer, test_key->len); isc_hmacmd5_update(&hmacmd5, (const isc_uint8_t *) testcase->input, testcase->input_len); isc_hmacmd5_sign(&hmacmd5, digest); tohexstr(digest, ISC_MD5_DIGESTLENGTH, str); ATF_CHECK_STREQ(str, testcase->result); testcase++; test_key++; } } /* CRC64 Test */ ATF_TC(isc_crc64); ATF_TC_HEAD(isc_crc64, tc) { atf_tc_set_md_var(tc, "descr", "64-bit cyclic redundancy check"); } ATF_TC_BODY(isc_crc64, tc) { isc_uint64_t crc; int i; UNUSED(tc); hash_testcase_t testcases[] = { { TEST_INPUT(""), "0x0000000000000000", 1 }, { TEST_INPUT("a"), "0x9AA9C0AC27F473CE", 1 }, { TEST_INPUT("abc"), "0x0297F4F93A818B04", 1 }, { TEST_INPUT("message digest"), "0xF47B357AEAF97352", 1 }, { TEST_INPUT("abcdefghijklmnopqrstuvwxyz"), "0xA1AA8B21F979F059", 1 }, { TEST_INPUT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm" "nopqrstuvwxyz0123456789"), "0xFBB6781EF7A86DA3", 1 }, { TEST_INPUT("123456789012345678901234567890123456789" "01234567890123456789012345678901234567890"), "0x4A87E7C873EBE581", 1 }, { NULL, 0, NULL, 1 } }; hash_testcase_t *testcase = testcases; while (testcase->input != NULL && testcase->result != NULL) { isc_crc64_init(&crc); for(i = 0; i < testcase->repeats; i++) { isc_crc64_update(&crc, (const isc_uint8_t *) testcase->input, testcase->input_len); } isc_crc64_final(&crc); tohexstr((unsigned char *) &crc, sizeof(crc), str); ATF_CHECK_STREQ(str, testcase->result); testcase++; } } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, isc_hmacmd5); ATF_TP_ADD_TC(tp, isc_hmacsha1); ATF_TP_ADD_TC(tp, isc_hmacsha224); ATF_TP_ADD_TC(tp, isc_hmacsha256); ATF_TP_ADD_TC(tp, isc_hmacsha384); ATF_TP_ADD_TC(tp, isc_hmacsha512); ATF_TP_ADD_TC(tp, isc_md5); ATF_TP_ADD_TC(tp, isc_sha1); ATF_TP_ADD_TC(tp, isc_sha224); ATF_TP_ADD_TC(tp, isc_sha256); ATF_TP_ADD_TC(tp, isc_sha384); ATF_TP_ADD_TC(tp, isc_sha512); ATF_TP_ADD_TC(tp, isc_crc64); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/isc/tests/pool_test.c0000644000470500017500000001063212664710322020235 0ustar lamontlamont/* * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include "isctest.h" static isc_result_t poolinit(void **target, void *arg) { isc_result_t result; isc_taskmgr_t *mgr = (isc_taskmgr_t *) arg; isc_task_t *task = NULL; result = isc_task_create(mgr, 0, &task); if (result != ISC_R_SUCCESS) return (result); *target = (void *) task; return (ISC_R_SUCCESS); } static void poolfree(void **target) { isc_task_t *task = *(isc_task_t **) target; isc_task_destroy(&task); *target = NULL; } /* * Individual unit tests */ /* Create a pool */ ATF_TC(create_pool); ATF_TC_HEAD(create_pool, tc) { atf_tc_set_md_var(tc, "descr", "create a pool"); } ATF_TC_BODY(create_pool, tc) { isc_result_t result; isc_pool_t *pool = NULL; UNUSED(tc); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_pool_create(mctx, 8, poolfree, poolinit, taskmgr, &pool); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(isc_pool_count(pool), 8); isc_pool_destroy(&pool); ATF_REQUIRE_EQ(pool, NULL); isc_test_end(); } /* Resize a pool */ ATF_TC(expand_pool); ATF_TC_HEAD(expand_pool, tc) { atf_tc_set_md_var(tc, "descr", "expand a pool"); } ATF_TC_BODY(expand_pool, tc) { isc_result_t result; isc_pool_t *pool1 = NULL, *pool2 = NULL, *hold = NULL; UNUSED(tc); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_pool_create(mctx, 10, poolfree, poolinit, taskmgr, &pool1); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(isc_pool_count(pool1), 10); /* resizing to a smaller size should have no effect */ hold = pool1; result = isc_pool_expand(&pool1, 5, &pool2); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(isc_pool_count(pool2), 10); ATF_REQUIRE_EQ(pool2, hold); ATF_REQUIRE_EQ(pool1, NULL); pool1 = pool2; pool2 = NULL; /* resizing to the same size should have no effect */ hold = pool1; result = isc_pool_expand(&pool1, 10, &pool2); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(isc_pool_count(pool2), 10); ATF_REQUIRE_EQ(pool2, hold); ATF_REQUIRE_EQ(pool1, NULL); pool1 = pool2; pool2 = NULL; /* resizing to larger size should make a new pool */ hold = pool1; result = isc_pool_expand(&pool1, 20, &pool2); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(isc_pool_count(pool2), 20); ATF_REQUIRE(pool2 != hold); ATF_REQUIRE_EQ(pool1, NULL); isc_pool_destroy(&pool2); ATF_REQUIRE_EQ(pool2, NULL); isc_test_end(); } /* Get objects */ ATF_TC(get_objects); ATF_TC_HEAD(get_objects, tc) { atf_tc_set_md_var(tc, "descr", "get objects"); } ATF_TC_BODY(get_objects, tc) { isc_result_t result; isc_pool_t *pool = NULL; void *item; isc_task_t *task1 = NULL, *task2 = NULL, *task3 = NULL; UNUSED(tc); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_pool_create(mctx, 2, poolfree, poolinit, taskmgr, &pool); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(isc_pool_count(pool), 2); item = isc_pool_get(pool); ATF_REQUIRE(item != NULL); isc_task_attach((isc_task_t *) item, &task1); item = isc_pool_get(pool); ATF_REQUIRE(item != NULL); isc_task_attach((isc_task_t *) item, &task2); item = isc_pool_get(pool); ATF_REQUIRE(item != NULL); isc_task_attach((isc_task_t *) item, &task3); isc_task_detach(&task1); isc_task_detach(&task2); isc_task_detach(&task3); isc_pool_destroy(&pool); ATF_REQUIRE_EQ(pool, NULL); isc_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, create_pool); ATF_TP_ADD_TC(tp, expand_pool); ATF_TP_ADD_TC(tp, get_objects); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/isc/tests/socket_test.c0000644000470500017500000005106612664710322020562 0ustar lamontlamont/* * Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include "../task_p.h" #include "../unix/socket_p.h" #include "isctest.h" static isc_boolean_t recv_dscp; static unsigned int recv_dscp_value; /* * Helper functions */ typedef struct { isc_boolean_t done; isc_result_t result; isc_socket_t *socket; } completion_t; static void completion_init(completion_t *completion) { completion->done = ISC_FALSE; completion->socket = NULL; } static void accept_done(isc_task_t *task, isc_event_t *event) { isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event; completion_t *completion = event->ev_arg; UNUSED(task); completion->result = nevent->result; completion->done = ISC_TRUE; if (completion->result == ISC_R_SUCCESS) completion->socket = nevent->newsocket; isc_event_free(&event); } static void event_done(isc_task_t *task, isc_event_t *event) { isc_socketevent_t *dev; completion_t *completion = event->ev_arg; UNUSED(task); dev = (isc_socketevent_t *) event; completion->result = dev->result; completion->done = ISC_TRUE; if ((dev->attributes & ISC_SOCKEVENTATTR_DSCP) != 0) { recv_dscp = ISC_TRUE; recv_dscp_value = dev->dscp;; } else recv_dscp = ISC_FALSE; isc_event_free(&event); } static isc_result_t waitfor(completion_t *completion) { int i = 0; while (!completion->done && i++ < 5000) { #ifndef ISC_PLATFORM_USETHREADS while (isc__taskmgr_ready(taskmgr)) isc__taskmgr_dispatch(taskmgr); #endif isc_test_nap(1000); } if (completion->done) return (ISC_R_SUCCESS); return (ISC_R_FAILURE); } #if 0 static isc_result_t waitfor(completion_t *completion) { int i = 0; while (!completion->done && i++ < 5000) { waitbody(); } if (completion->done) return (ISC_R_SUCCESS); return (ISC_R_FAILURE); } #endif static void waitbody(void) { #ifndef ISC_PLATFORM_USETHREADS struct timeval tv; isc_socketwait_t *swait = NULL; while (isc__taskmgr_ready(taskmgr)) isc__taskmgr_dispatch(taskmgr); if (socketmgr != NULL) { tv.tv_sec = 0; tv.tv_usec = 1000 ; if (isc__socketmgr_waitevents(socketmgr, &tv, &swait) > 0) isc__socketmgr_dispatch(socketmgr, swait); } else #endif isc_test_nap(1000); } static isc_result_t waitfor2(completion_t *c1, completion_t *c2) { int i = 0; while (!(c1->done && c2->done) && i++ < 5000) { waitbody(); } if (c1->done && c2->done) return (ISC_R_SUCCESS); return (ISC_R_FAILURE); } /* * Individual unit tests */ /* Test UDP sendto/recv (IPv4) */ ATF_TC(udp_sendto); ATF_TC_HEAD(udp_sendto, tc) { atf_tc_set_md_var(tc, "descr", "UDP sendto/recv"); } ATF_TC_BODY(udp_sendto, tc) { isc_result_t result; isc_sockaddr_t addr1, addr2; struct in_addr in; isc_socket_t *s1 = NULL, *s2 = NULL; isc_task_t *task = NULL; char sendbuf[BUFSIZ], recvbuf[BUFSIZ]; completion_t completion; isc_region_t r; UNUSED(tc); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* * Create two sockets: 127.0.0.1/5444 and 127.0.0.1/5445, talking to * each other. */ in.s_addr = inet_addr("127.0.0.1"); isc_sockaddr_fromin(&addr1, &in, 5444); isc_sockaddr_fromin(&addr2, &in, 5445); result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s1); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_socket_bind(s1, &addr1, ISC_SOCKET_REUSEADDRESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s2); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_socket_bind(s2, &addr2, ISC_SOCKET_REUSEADDRESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_task_create(taskmgr, 0, &task); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); strcpy(sendbuf, "Hello"); r.base = (void *) sendbuf; r.length = strlen(sendbuf) + 1; completion_init(&completion); result = isc_socket_sendto(s1, &r, task, event_done, &completion, &addr2, NULL); ATF_CHECK_EQ(result, ISC_R_SUCCESS); waitfor(&completion); ATF_CHECK(completion.done); ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS); r.base = (void *) recvbuf; r.length = BUFSIZ; completion_init(&completion); result = isc_socket_recv(s2, &r, 1, task, event_done, &completion); ATF_CHECK_EQ(result, ISC_R_SUCCESS); waitfor(&completion); ATF_CHECK(completion.done); ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS); ATF_CHECK_STREQ(recvbuf, "Hello"); isc_task_detach(&task); isc_socket_detach(&s1); isc_socket_detach(&s2); isc_test_end(); } /* Test UDP sendto/recv with duplicated socket */ ATF_TC(udp_dup); ATF_TC_HEAD(udp_dup, tc) { atf_tc_set_md_var(tc, "descr", "duplicated socket sendto/recv"); } ATF_TC_BODY(udp_dup, tc) { isc_result_t result; isc_sockaddr_t addr1, addr2; struct in_addr in; isc_socket_t *s1 = NULL, *s2 = NULL, *s3 = NULL; isc_task_t *task = NULL; char sendbuf[BUFSIZ], recvbuf[BUFSIZ]; completion_t completion; isc_region_t r; UNUSED(tc); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* * Create two sockets: 127.0.0.1/5444 and 127.0.0.1/5445, talking to * each other. */ in.s_addr = inet_addr("127.0.0.1"); isc_sockaddr_fromin(&addr1, &in, 5444); isc_sockaddr_fromin(&addr2, &in, 5445); result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s1); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_socket_bind(s1, &addr1, ISC_SOCKET_REUSEADDRESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s2); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_socket_bind(s2, &addr2, ISC_SOCKET_REUSEADDRESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_socket_dup(s2, &s3); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_task_create(taskmgr, 0, &task); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); strcpy(sendbuf, "Hello"); r.base = (void *) sendbuf; r.length = strlen(sendbuf) + 1; completion_init(&completion); result = isc_socket_sendto(s1, &r, task, event_done, &completion, &addr2, NULL); ATF_CHECK_EQ(result, ISC_R_SUCCESS); waitfor(&completion); ATF_CHECK(completion.done); ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS); strcpy(sendbuf, "World"); r.base = (void *) sendbuf; r.length = strlen(sendbuf) + 1; completion_init(&completion); result = isc_socket_sendto(s1, &r, task, event_done, &completion, &addr2, NULL); ATF_CHECK_EQ(result, ISC_R_SUCCESS); waitfor(&completion); ATF_CHECK(completion.done); ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS); r.base = (void *) recvbuf; r.length = BUFSIZ; completion_init(&completion); result = isc_socket_recv(s2, &r, 1, task, event_done, &completion); ATF_CHECK_EQ(result, ISC_R_SUCCESS); waitfor(&completion); ATF_CHECK(completion.done); ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS); ATF_CHECK_STREQ(recvbuf, "Hello"); r.base = (void *) recvbuf; r.length = BUFSIZ; completion_init(&completion); result = isc_socket_recv(s3, &r, 1, task, event_done, &completion); ATF_CHECK_EQ(result, ISC_R_SUCCESS); waitfor(&completion); ATF_CHECK(completion.done); ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS); ATF_CHECK_STREQ(recvbuf, "World"); isc_task_detach(&task); isc_socket_detach(&s1); isc_socket_detach(&s2); isc_socket_detach(&s3); isc_test_end(); } /* Test TCP sendto/recv (IPv4) */ ATF_TC(udp_dscp_v4); ATF_TC_HEAD(udp_dscp_v4, tc) { atf_tc_set_md_var(tc, "descr", "UDP DSCP IPV4"); } ATF_TC_BODY(udp_dscp_v4, tc) { isc_result_t result; isc_sockaddr_t addr1, addr2; struct in_addr in; isc_socket_t *s1 = NULL, *s2 = NULL; isc_task_t *task = NULL; char sendbuf[BUFSIZ], recvbuf[BUFSIZ]; completion_t completion; isc_region_t r; isc_socketevent_t *socketevent; UNUSED(tc); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* * Create two sockets: 127.0.0.1/5444 and 127.0.0.1/5445, talking to * each other. */ in.s_addr = inet_addr("127.0.0.1"); isc_sockaddr_fromin(&addr1, &in, 5444); isc_sockaddr_fromin(&addr2, &in, 5445); result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s1); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s", isc_result_totext(result)); result = isc_socket_bind(s1, &addr1, ISC_SOCKET_REUSEADDRESS); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s", isc_result_totext(result)); result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s2); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s", isc_result_totext(result)); result = isc_socket_bind(s2, &addr2, ISC_SOCKET_REUSEADDRESS); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s", isc_result_totext(result)); result = isc_task_create(taskmgr, 0, &task); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s", isc_result_totext(result)); strcpy(sendbuf, "Hello"); r.base = (void *) sendbuf; r.length = strlen(sendbuf) + 1; completion_init(&completion); socketevent = isc_socket_socketevent(mctx, s1, ISC_SOCKEVENT_SENDDONE, event_done, &completion); ATF_REQUIRE(socketevent != NULL); if ((isc_net_probedscp() & ISC_NET_DSCPPKTV4) != 0) { socketevent->dscp = 056; /* EF */ socketevent->attributes |= ISC_SOCKEVENTATTR_DSCP; } else if ((isc_net_probedscp() & ISC_NET_DSCPSETV4) != 0) { isc_socket_dscp(s1, 056); /* EF */ socketevent->dscp = 0; socketevent->attributes &= ~ISC_SOCKEVENTATTR_DSCP; } recv_dscp = ISC_FALSE; recv_dscp_value = 0; result = isc_socket_sendto2(s1, &r, task, &addr2, NULL, socketevent, 0); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s", isc_result_totext(result)); waitfor(&completion); ATF_CHECK(completion.done); ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS); r.base = (void *) recvbuf; r.length = BUFSIZ; completion_init(&completion); result = isc_socket_recv(s2, &r, 1, task, event_done, &completion); ATF_CHECK_EQ(result, ISC_R_SUCCESS); waitfor(&completion); ATF_CHECK(completion.done); ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS); ATF_CHECK_STREQ(recvbuf, "Hello"); if ((isc_net_probedscp() & ISC_NET_DSCPRECVV4) != 0) { ATF_CHECK(recv_dscp); ATF_CHECK_EQ(recv_dscp_value, 056); } else ATF_CHECK(!recv_dscp); isc_task_detach(&task); isc_socket_detach(&s1); isc_socket_detach(&s2); isc_test_end(); } /* Test TCP sendto/recv (IPv4) */ ATF_TC(udp_dscp_v6); ATF_TC_HEAD(udp_dscp_v6, tc) { atf_tc_set_md_var(tc, "descr", "udp dscp ipv6"); } ATF_TC_BODY(udp_dscp_v6, tc) { isc_result_t result; isc_sockaddr_t addr1, addr2; struct in6_addr in6; isc_socket_t *s1 = NULL, *s2 = NULL; isc_task_t *task = NULL; char sendbuf[BUFSIZ], recvbuf[BUFSIZ]; completion_t completion; isc_region_t r; isc_socketevent_t *socketevent; int n; UNUSED(tc); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* * Create two sockets: ::1/5444 and ::1/5445, talking to * each other. */ n = inet_pton(AF_INET6, "::1", &in6.s6_addr); ATF_REQUIRE(n == 1); isc_sockaddr_fromin6(&addr1, &in6, 5444); isc_sockaddr_fromin6(&addr2, &in6, 5445); result = isc_socket_create(socketmgr, PF_INET6, isc_sockettype_udp, &s1); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s", isc_result_totext(result)); result = isc_socket_bind(s1, &addr1, ISC_SOCKET_REUSEADDRESS); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s", isc_result_totext(result)); result = isc_socket_create(socketmgr, PF_INET6, isc_sockettype_udp, &s2); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s", isc_result_totext(result)); result = isc_socket_bind(s2, &addr2, ISC_SOCKET_REUSEADDRESS); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s", isc_result_totext(result)); result = isc_task_create(taskmgr, 0, &task); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s", isc_result_totext(result)); strcpy(sendbuf, "Hello"); r.base = (void *) sendbuf; r.length = strlen(sendbuf) + 1; completion_init(&completion); socketevent = isc_socket_socketevent(mctx, s1, ISC_SOCKEVENT_SENDDONE, event_done, &completion); ATF_REQUIRE(socketevent != NULL); if ((isc_net_probedscp() & ISC_NET_DSCPPKTV6) != 0) { socketevent->dscp = 056; /* EF */ socketevent->attributes = ISC_SOCKEVENTATTR_DSCP; } else if ((isc_net_probedscp() & ISC_NET_DSCPSETV6) != 0) isc_socket_dscp(s1, 056); /* EF */ recv_dscp = ISC_FALSE; recv_dscp_value = 0; result = isc_socket_sendto2(s1, &r, task, &addr2, NULL, socketevent, 0); ATF_CHECK_EQ(result, ISC_R_SUCCESS); waitfor(&completion); ATF_CHECK(completion.done); ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS); r.base = (void *) recvbuf; r.length = BUFSIZ; completion_init(&completion); result = isc_socket_recv(s2, &r, 1, task, event_done, &completion); ATF_CHECK_EQ(result, ISC_R_SUCCESS); waitfor(&completion); ATF_CHECK(completion.done); ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS); ATF_CHECK_STREQ(recvbuf, "Hello"); if ((isc_net_probedscp() & ISC_NET_DSCPRECVV6) != 0) { ATF_CHECK(recv_dscp); ATF_CHECK_EQ(recv_dscp_value, 056); } else ATF_CHECK(!recv_dscp); isc_task_detach(&task); isc_socket_detach(&s1); isc_socket_detach(&s2); isc_test_end(); } /* Test TCP sendto/recv (IPv4) */ ATF_TC(tcp_dscp_v4); ATF_TC_HEAD(tcp_dscp_v4, tc) { atf_tc_set_md_var(tc, "descr", "tcp dscp ipv4"); } ATF_TC_BODY(tcp_dscp_v4, tc) { isc_result_t result; isc_sockaddr_t addr1; struct in_addr in; isc_socket_t *s1 = NULL, *s2 = NULL, *s3 = NULL; isc_task_t *task = NULL; char sendbuf[BUFSIZ], recvbuf[BUFSIZ]; completion_t completion, completion2; isc_region_t r; UNUSED(tc); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* * Create two sockets: 127.0.0.1/5444, talking to each other. */ in.s_addr = inet_addr("127.0.0.1"); isc_sockaddr_fromin(&addr1, &in, 5444); result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_tcp, &s1); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_socket_bind(s1, &addr1, ISC_SOCKET_REUSEADDRESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_socket_listen(s1, 3); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_tcp, &s2); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_task_create(taskmgr, 0, &task); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); completion_init(&completion2); result = isc_socket_accept(s1, task, accept_done, &completion2); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); completion_init(&completion); result = isc_socket_connect(s2, &addr1, task, event_done, &completion); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); waitfor2(&completion, &completion2); ATF_CHECK(completion.done); ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS); ATF_CHECK(completion2.done); ATF_CHECK_EQ(completion2.result, ISC_R_SUCCESS); s3 = completion2.socket; isc_socket_dscp(s2, 056); /* EF */ strcpy(sendbuf, "Hello"); r.base = (void *) sendbuf; r.length = strlen(sendbuf) + 1; recv_dscp = ISC_FALSE; recv_dscp_value = 0; completion_init(&completion); result = isc_socket_sendto(s2, &r, task, event_done, &completion, NULL, NULL); ATF_CHECK_EQ(result, ISC_R_SUCCESS); waitfor(&completion); ATF_CHECK(completion.done); ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS); r.base = (void *) recvbuf; r.length = BUFSIZ; completion_init(&completion); result = isc_socket_recv(s3, &r, 1, task, event_done, &completion); ATF_CHECK_EQ(result, ISC_R_SUCCESS); waitfor(&completion); ATF_CHECK(completion.done); ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS); ATF_CHECK_STREQ(recvbuf, "Hello"); if ((isc_net_probedscp() & ISC_NET_DSCPRECVV4) != 0) { if (recv_dscp) ATF_CHECK_EQ(recv_dscp_value, 056); } else ATF_CHECK(!recv_dscp); isc_task_detach(&task); isc_socket_detach(&s1); isc_socket_detach(&s2); isc_socket_detach(&s3); isc_test_end(); } /* Test TCP sendto/recv (IPv6) */ ATF_TC(tcp_dscp_v6); ATF_TC_HEAD(tcp_dscp_v6, tc) { atf_tc_set_md_var(tc, "descr", "tcp dscp ipv6"); } ATF_TC_BODY(tcp_dscp_v6, tc) { isc_result_t result; isc_sockaddr_t addr1; struct in6_addr in6; isc_socket_t *s1 = NULL, *s2 = NULL, *s3 = NULL; isc_task_t *task = NULL; char sendbuf[BUFSIZ], recvbuf[BUFSIZ]; completion_t completion, completion2; isc_region_t r; int n; UNUSED(tc); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* * Create two sockets: ::1/5444, talking to each other. */ n = inet_pton(AF_INET6, "::1", &in6.s6_addr); ATF_REQUIRE(n == 1); isc_sockaddr_fromin6(&addr1, &in6, 5444); result = isc_socket_create(socketmgr, PF_INET6, isc_sockettype_tcp, &s1); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_socket_bind(s1, &addr1, ISC_SOCKET_REUSEADDRESS); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_socket_listen(s1, 3); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_socket_create(socketmgr, PF_INET6, isc_sockettype_tcp, &s2); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_task_create(taskmgr, 0, &task); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); completion_init(&completion2); result = isc_socket_accept(s1, task, accept_done, &completion2); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); completion_init(&completion); result = isc_socket_connect(s2, &addr1, task, event_done, &completion); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); waitfor2(&completion, &completion2); ATF_CHECK(completion.done); ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS); ATF_CHECK(completion2.done); ATF_CHECK_EQ(completion2.result, ISC_R_SUCCESS); s3 = completion2.socket; isc_socket_dscp(s2, 056); /* EF */ strcpy(sendbuf, "Hello"); r.base = (void *) sendbuf; r.length = strlen(sendbuf) + 1; recv_dscp = ISC_FALSE; recv_dscp_value = 0; completion_init(&completion); result = isc_socket_sendto(s2, &r, task, event_done, &completion, NULL, NULL); ATF_CHECK_EQ(result, ISC_R_SUCCESS); waitfor(&completion); ATF_CHECK(completion.done); ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS); r.base = (void *) recvbuf; r.length = BUFSIZ; completion_init(&completion); result = isc_socket_recv(s3, &r, 1, task, event_done, &completion); ATF_CHECK_EQ(result, ISC_R_SUCCESS); waitfor(&completion); ATF_CHECK(completion.done); ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS); ATF_CHECK_STREQ(recvbuf, "Hello"); if ((isc_net_probedscp() & ISC_NET_DSCPRECVV6) != 0) { /* * IPV6_RECVTCLASS is undefined for TCP however * if we do get it it should be the value we set. */ if (recv_dscp) ATF_CHECK_EQ(recv_dscp_value, 056); } else ATF_CHECK(!recv_dscp); isc_task_detach(&task); isc_socket_detach(&s1); isc_socket_detach(&s2); isc_socket_detach(&s3); isc_test_end(); } ATF_TC(net_probedscp); ATF_TC_HEAD(net_probedscp, tc) { atf_tc_set_md_var(tc, "descr", "probe dscp capabilities"); } ATF_TC_BODY(net_probedscp, tc) { unsigned int n; UNUSED(tc); n = isc_net_probedscp(); ATF_CHECK((n & ~ISC_NET_DSCPALL) == 0); /* ISC_NET_DSCPSETV4 MUST be set if any is set. */ if (n & (ISC_NET_DSCPSETV4|ISC_NET_DSCPPKTV4|ISC_NET_DSCPRECVV4)) ATF_CHECK_MSG((n & ISC_NET_DSCPSETV4) != 0, "IPv4:%s%s%s\n", (n & ISC_NET_DSCPSETV4) ? " set" : " none", (n & ISC_NET_DSCPPKTV4) ? " packet" : "", (n & ISC_NET_DSCPRECVV4) ? " receive" : ""); /* ISC_NET_DSCPSETV6 MUST be set if any is set. */ if (n & (ISC_NET_DSCPSETV6|ISC_NET_DSCPPKTV4|ISC_NET_DSCPRECVV4)) ATF_CHECK_MSG((n & ISC_NET_DSCPSETV6) != 0, "IPv6:%s%s%s\n", (n & ISC_NET_DSCPSETV6) ? " set" : " none", (n & ISC_NET_DSCPPKTV6) ? " packet" : "", (n & ISC_NET_DSCPRECVV6) ? " receive" : ""); #if 0 fprintf(stdout, "IPv4:%s%s%s\n", (n & ISC_NET_DSCPSETV4) ? " set" : "none", (n & ISC_NET_DSCPPKTV4) ? " packet" : "", (n & ISC_NET_DSCPRECVV4) ? " receive" : ""); fprintf(stdout, "IPv6:%s%s%s\n", (n & ISC_NET_DSCPSETV6) ? " set" : "none", (n & ISC_NET_DSCPPKTV6) ? " packet" : "", (n & ISC_NET_DSCPRECVV6) ? " receive" : ""); #endif } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, udp_sendto); ATF_TP_ADD_TC(tp, udp_dup); ATF_TP_ADD_TC(tp, tcp_dscp_v4); ATF_TP_ADD_TC(tp, tcp_dscp_v6); ATF_TP_ADD_TC(tp, udp_dscp_v4); ATF_TP_ADD_TC(tp, udp_dscp_v6); ATF_TP_ADD_TC(tp, net_probedscp); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/isc/tests/lex_test.c0000644000470500017500000000344012664710322020053 0ustar lamontlamont/* * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #include #include #include #include #include ATF_TC(lex); ATF_TC_HEAD(lex, tc) { atf_tc_set_md_var(tc, "descr", "check handling of 0xff"); } ATF_TC_BODY(lex, tc) { isc_mem_t *mctx = NULL; isc_result_t result; isc_lex_t *lex = NULL; isc_buffer_t death_buf; isc_token_t token; unsigned char death[] = { EOF, 'A' }; UNUSED(tc); result = isc_mem_create(0, 0, &mctx); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_lex_create(mctx, 1024, &lex); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); isc_buffer_init(&death_buf, &death[0], sizeof(death)); isc_buffer_add(&death_buf, sizeof(death)); result = isc_lex_openbuffer(lex, &death_buf); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_lex_gettoken(lex, 0, &token); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, lex); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/isc/tests/print_test.c0000644000470500017500000001013612664710322020417 0ustar lamontlamont/* * Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #include /* * Workout if we need to force the inclusion of print.c so we can test * it on all platforms even if we don't include it in libisc. */ #include #if !defined(ISC_PLATFORM_NEEDPRINTF) && \ !defined(ISC_PLATFORM_NEEDFPRINTF) && \ !defined(ISC_PLATFORM_NEEDSPRINTF) && \ !defined(ISC_PLATFORM_NEEDVSNPRINTF) #define ISC__PRINT_SOURCE #include "../print.c" #else #if !defined(ISC_PLATFORM_NEEDPRINTF) || \ !defined(ISC_PLATFORM_NEEDFPRINTF) || \ !defined(ISC_PLATFORM_NEEDSPRINTF) || \ !defined(ISC_PLATFORM_NEEDVSNPRINTF) #define ISC__PRINT_SOURCE #endif #include #include #include #endif ATF_TC(snprintf); ATF_TC_HEAD(snprintf, tc) { atf_tc_set_md_var(tc, "descr", "snprintf implementation"); } ATF_TC_BODY(snprintf, tc) { char buf[10000]; isc_uint64_t ll = 8589934592ULL; isc_uint64_t nn = 20000000000000ULL; isc_uint64_t zz = 10000000000000000000LLU; int n; size_t size; UNUSED(tc); /* * 4294967296 <= 8589934592 < 1000000000^2 to verify fix for * RT#36505. */ memset(buf, 0xff, sizeof(buf)); n = isc_print_snprintf(buf, sizeof(buf), "%qu", ll); ATF_CHECK_EQ(n, 10); ATF_CHECK_STREQ(buf, "8589934592"); memset(buf, 0xff, sizeof(buf)); n = isc_print_snprintf(buf, sizeof(buf), "%llu", ll); ATF_CHECK_EQ(n, 10); ATF_CHECK_STREQ(buf, "8589934592"); memset(buf, 0xff, sizeof(buf)); n = isc_print_snprintf(buf, sizeof(buf), "%qu", nn); ATF_CHECK_EQ(n, 14); ATF_CHECK_STREQ(buf, "20000000000000"); memset(buf, 0xff, sizeof(buf)); n = isc_print_snprintf(buf, sizeof(buf), "%llu", nn); ATF_CHECK_EQ(n, 14); ATF_CHECK_STREQ(buf, "20000000000000"); memset(buf, 0xff, sizeof(buf)); n = isc_print_snprintf(buf, sizeof(buf), "%qu", zz); ATF_CHECK_EQ(n, 20); ATF_CHECK_STREQ(buf, "10000000000000000000"); memset(buf, 0xff, sizeof(buf)); n = isc_print_snprintf(buf, sizeof(buf), "%llu", zz); ATF_CHECK_EQ(n, 20); ATF_CHECK_STREQ(buf, "10000000000000000000"); memset(buf, 0xff, sizeof(buf)); n = isc_print_snprintf(buf, sizeof(buf), "%lld", nn); ATF_CHECK_EQ(n, 14); ATF_CHECK_STREQ(buf, "20000000000000"); size = 1000; memset(buf, 0xff, sizeof(buf)); n = isc_print_snprintf(buf, sizeof(buf), "%zu", size); ATF_CHECK_EQ(n, 4); ATF_CHECK_STREQ(buf, "1000"); size = 1000; memset(buf, 0xff, sizeof(buf)); n = isc_print_snprintf(buf, sizeof(buf), "%zx", size); ATF_CHECK_EQ(n, 3); ATF_CHECK_STREQ(buf, "3e8"); size = 1000; memset(buf, 0xff, sizeof(buf)); n = isc_print_snprintf(buf, sizeof(buf), "%zo", size); ATF_CHECK_EQ(n, 4); ATF_CHECK_STREQ(buf, "1750"); } ATF_TC(fprintf); ATF_TC_HEAD(fprintf, tc) { atf_tc_set_md_var(tc, "descr", "fprintf implementation"); } ATF_TC_BODY(fprintf, tc) { FILE *f; int n; size_t size; char buf[10000]; UNUSED(tc); f = fopen("fprintf.test", "w+"); ATF_REQUIRE(f != NULL); size = 1000; n = isc_print_fprintf(f, "%zu", size); ATF_CHECK_EQ(n, 4); rewind(f); memset(buf, 0, sizeof(buf)); n = fread(buf, 1, sizeof(buf), f); ATF_CHECK_EQ(n, 4); fclose(f); ATF_CHECK_STREQ(buf, "1000"); if ((n > 0) && (!strcmp(buf, "1000"))) unlink("fprintf.test"); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, snprintf); ATF_TP_ADD_TC(tp, fprintf); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/isc/tests/symtab_test.c0000644000470500017500000000672612664710322020574 0ustar lamontlamont/* * Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include "isctest.h" static void undefine(char *key, unsigned int type, isc_symvalue_t value, void *arg) { UNUSED(arg); ATF_REQUIRE_EQ(type, 1); isc_mem_free(mctx, key); isc_mem_free(mctx, value.as_pointer); } /* * Individual unit tests */ ATF_TC(symtab_grow); ATF_TC_HEAD(symtab_grow, tc) { atf_tc_set_md_var(tc, "descr", "symbol table growth"); } ATF_TC_BODY(symtab_grow, tc) { isc_result_t result; isc_symtab_t *st = NULL; isc_symvalue_t value; isc_symexists_t policy = isc_symexists_reject; int i; UNUSED(tc); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_symtab_create(mctx, 3, undefine, NULL, ISC_FALSE, &st); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE(st != NULL); /* Nothing should be in the table yet */ /* * Put 1024 entries in the table (this should necessate * regrowing the hash table several times */ for (i = 0; i < 1024; i++) { char str[16], *key; snprintf(str, sizeof(str), "%04x", i); key = isc_mem_strdup(mctx, str); ATF_REQUIRE(key != NULL); value.as_pointer = isc_mem_strdup(mctx, str); ATF_REQUIRE(value.as_pointer != NULL); result = isc_symtab_define(st, key, 1, value, policy); ATF_CHECK_EQ(result, ISC_R_SUCCESS); if (result != ISC_R_SUCCESS) undefine(key, 1, value, NULL); } /* * Try to put them in again; this should fail */ for (i = 0; i < 1024; i++) { char str[16], *key; snprintf(str, sizeof(str), "%04x", i); key = isc_mem_strdup(mctx, str); ATF_REQUIRE(key != NULL); value.as_pointer = isc_mem_strdup(mctx, str); ATF_REQUIRE(value.as_pointer != NULL); result = isc_symtab_define(st, key, 1, value, policy); ATF_CHECK_EQ(result, ISC_R_EXISTS); undefine(key, 1, value, NULL); } /* * Retrieve them; this should succeed */ for (i = 0; i < 1024; i++) { char str[16]; snprintf(str, sizeof(str), "%04x", i); result = isc_symtab_lookup(st, str, 0, &value); ATF_CHECK_EQ(result, ISC_R_SUCCESS); ATF_CHECK_STREQ(str, (char *)value.as_pointer); } /* * Undefine them */ for (i = 0; i < 1024; i++) { char str[16]; snprintf(str, sizeof(str), "%04x", i); result = isc_symtab_undefine(st, str, 1); ATF_CHECK_EQ(result, ISC_R_SUCCESS); } /* * Retrieve them again; this should fail */ for (i = 0; i < 1024; i++) { char str[16]; snprintf(str, sizeof(str), "%04x", i); result = isc_symtab_lookup(st, str, 0, &value); ATF_CHECK_EQ(result, ISC_R_NOTFOUND); } isc_symtab_destroy(&st); isc_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, symtab_grow); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/isc/tests/mem_test.c0000644000470500017500000000722712664710322020050 0ustar lamontlamont/* * Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #include "isctest.h" #include #include #include static void * default_memalloc(void *arg, size_t size) { UNUSED(arg); if (size == 0U) size = 1; return (malloc(size)); } static void default_memfree(void *arg, void *ptr) { UNUSED(arg); free(ptr); } ATF_TC(isc_mem_total); ATF_TC_HEAD(isc_mem_total, tc) { atf_tc_set_md_var(tc, "descr", "test TotalUse calculation"); } ATF_TC_BODY(isc_mem_total, tc) { isc_result_t result; isc_mem_t *mctx2 = NULL; size_t before, after; ssize_t diff; int i; result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* Local alloc, free */ mctx2 = NULL; result = isc_mem_createx2(0, 0, default_memalloc, default_memfree, NULL, &mctx2, 0); if (result != ISC_R_SUCCESS) goto out; before = isc_mem_total(mctx2); for (i = 0; i < 100000; i++) { void *ptr; ptr = isc_mem_allocate(mctx2, 2048); isc_mem_free(mctx2, ptr); } after = isc_mem_total(mctx2); diff = after - before; printf("total_before=%lu, total_after=%lu, total_diff=%lu\n", (unsigned long)before, (unsigned long)after, (unsigned long)diff); /* 2048 +8 bytes extra for size_info */ ATF_CHECK_EQ(diff, (2048 + 8) * 100000); /* ISC_MEMFLAG_INTERNAL */ before = isc_mem_total(mctx); for (i = 0; i < 100000; i++) { void *ptr; ptr = isc_mem_allocate(mctx, 2048); isc_mem_free(mctx, ptr); } after = isc_mem_total(mctx); diff = after - before; printf("total_before=%lu, total_after=%lu, total_diff=%lu\n", (unsigned long)before, (unsigned long)after, (unsigned long)diff); /* 2048 +8 bytes extra for size_info */ ATF_CHECK_EQ(diff, (2048 + 8) * 100000); out: if (mctx2 != NULL) isc_mem_destroy(&mctx2); isc_test_end(); } ATF_TC(isc_mem_inuse); ATF_TC_HEAD(isc_mem_inuse, tc) { atf_tc_set_md_var(tc, "descr", "test InUse calculation"); } ATF_TC_BODY(isc_mem_inuse, tc) { isc_result_t result; isc_mem_t *mctx2 = NULL; size_t before, during, after; ssize_t diff; void *ptr; result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); mctx2 = NULL; result = isc_mem_createx2(0, 0, default_memalloc, default_memfree, NULL, &mctx2, 0); if (result != ISC_R_SUCCESS) goto out; before = isc_mem_inuse(mctx2); ptr = isc_mem_allocate(mctx2, 1024000); during = isc_mem_inuse(mctx2); isc_mem_free(mctx2, ptr); after = isc_mem_inuse(mctx2); diff = after - before; printf("inuse_before=%lu, inuse_during=%lu, inuse_after=%lu\n", (unsigned long)before, (unsigned long)during, (unsigned long)after); ATF_REQUIRE_EQ(diff, 0); out: if (mctx2 != NULL) isc_mem_destroy(&mctx2); isc_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, isc_mem_total); ATF_TP_ADD_TC(tp, isc_mem_inuse); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/isc/tests/Makefile.in0000644000470500017500000001166612664710322020136 0ustar lamontlamont# Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ # Attempt to disable parallel processing. .NOTPARALLEL: .NO_PARALLEL: @BIND9_VERSION@ @BIND9_MAKE_INCLUDES@ CINCLUDES = -I. -Iinclude ${ISC_INCLUDES} @ISC_OPENSSL_INC@ CDEFINES = -DTESTS="\"${top_builddir}/lib/isc/tests/\"" ISCLIBS = ../libisc.@A@ @ISC_OPENSSL_LIBS@ ISCDEPLIBS = ../libisc.@A@ LIBS = @LIBS@ @ATFLIBS@ OBJS = isctest.@O@ SRCS = isctest.c taskpool_test.c socket_test.c hash_test.c \ lex_test.c radix_test.c \ sockaddr_test.c symtab_test.c task_test.c queue_test.c \ parse_test.c pool_test.c print_test.c regex_test.c \ socket_test.c safe_test.c time_test.c aes_test.c \ counter_test.c mem_test.c SUBDIRS = TARGETS = taskpool_test@EXEEXT@ socket_test@EXEEXT@ hash_test@EXEEXT@ \ lex_test@EXEEXT@ radix_test@EXEEXT@ \ sockaddr_test@EXEEXT@ symtab_test@EXEEXT@ task_test@EXEEXT@ \ queue_test@EXEEXT@ parse_test@EXEEXT@ pool_test@EXEEXT@ \ print_test@EXEEXT@ regex_test@EXEEXT@ socket_test@EXEEXT@ \ safe_test@EXEEXT@ time_test@EXEEXT@ aes_test@EXEEXT@ \ counter_test@EXEEXT@ mem_test@EXEEXT@ @BIND9_MAKE_RULES@ taskpool_test@EXEEXT@: taskpool_test.@O@ isctest.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ taskpool_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS} task_test@EXEEXT@: task_test.@O@ isctest.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ task_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS} socket_test@EXEEXT@: socket_test.@O@ isctest.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ socket_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS} hash_test@EXEEXT@: hash_test.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ hash_test.@O@ ${ISCLIBS} ${LIBS} lex_test@EXEEXT@: lex_test.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ lex_test.@O@ ${ISCLIBS} ${LIBS} queue_test@EXEEXT@: queue_test.@O@ isctest.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ queue_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS} radix_test@EXEEXT@: radix_test.@O@ isctest.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ radix_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS} symtab_test@EXEEXT@: symtab_test.@O@ isctest.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ symtab_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS} parse_test@EXEEXT@: parse_test.@O@ isctest.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ parse_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS} sockaddr_test@EXEEXT@: sockaddr_test.@O@ isctest.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ sockaddr_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS} print_test.@O@: ${top_srcdir}/lib/isc/print.c print_test@EXEEXT@: print_test.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ print_test.@O@ ${ISCLIBS} ${LIBS} pool_test@EXEEXT@: pool_test.@O@ isctest.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ pool_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS} regex_test@EXEEXT@: regex_test.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ regex_test.@O@ ${ISCLIBS} ${LIBS} safe_test@EXEEXT@: safe_test.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ safe_test.@O@ ${ISCLIBS} ${LIBS} time_test@EXEEXT@: time_test.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ time_test.@O@ ${ISCLIBS} ${LIBS} aes_test@EXEEXT@: aes_test.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ aes_test.@O@ ${ISCLIBS} ${LIBS} counter_test@EXEEXT@: counter_test.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ counter_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS} mem_test@EXEEXT@: mem_test.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ mem_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS} unit:: sh ${top_srcdir}/unit/unittest.sh clean distclean:: rm -f ${TARGETS} rm -f atf.out bind9-9.10.3.dfsg.P4/lib/isc/tests/safe_test.c0000644000470500017500000000427612664710322020211 0ustar lamontlamont/* * Copyright (C) 2013, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* ! \file */ #include #include #include #include #include #include ATF_TC(isc_safe_memequal); ATF_TC_HEAD(isc_safe_memequal, tc) { atf_tc_set_md_var(tc, "descr", "safe memequal()"); } ATF_TC_BODY(isc_safe_memequal, tc) { UNUSED(tc); ATF_CHECK(isc_safe_memequal("test", "test", 4)); ATF_CHECK(!isc_safe_memequal("test", "tesc", 4)); ATF_CHECK(isc_safe_memequal("\x00\x00\x00\x00", "\x00\x00\x00\x00", 4)); ATF_CHECK(!isc_safe_memequal("\x00\x00\x00\x00", "\x00\x00\x00\x01", 4)); ATF_CHECK(!isc_safe_memequal("\x00\x00\x00\x02", "\x00\x00\x00\x00", 4)); } ATF_TC(isc_safe_memcompare); ATF_TC_HEAD(isc_safe_memcompare, tc) { atf_tc_set_md_var(tc, "descr", "safe memcompare()"); } ATF_TC_BODY(isc_safe_memcompare, tc) { UNUSED(tc); ATF_CHECK(isc_safe_memcompare("test", "test", 4) == 0); ATF_CHECK(isc_safe_memcompare("test", "tesc", 4) > 0); ATF_CHECK(isc_safe_memcompare("test", "tesy", 4) < 0); ATF_CHECK(isc_safe_memcompare("\x00\x00\x00\x00", "\x00\x00\x00\x00", 4) == 0); ATF_CHECK(isc_safe_memcompare("\x00\x00\x00\x00", "\x00\x00\x00\x01", 4) < 0); ATF_CHECK(isc_safe_memcompare("\x00\x00\x00\x02", "\x00\x00\x00\x00", 4) > 0); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, isc_safe_memequal); ATF_TP_ADD_TC(tp, isc_safe_memcompare); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/isc/tests/task_test.c0000644000470500017500000002446212664710322020234 0ustar lamontlamont/* * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include "../task_p.h" #include "isctest.h" /* * Helper functions */ /* task event handler, sets a boolean to true */ int counter = 0; isc_mutex_t set_lock; static void set(isc_task_t *task, isc_event_t *event) { int *value = (int *) event->ev_arg; UNUSED(task); isc_event_free(&event); LOCK(&set_lock); *value = counter++; UNLOCK(&set_lock); } static void set_and_drop(isc_task_t *task, isc_event_t *event) { int *value = (int *) event->ev_arg; UNUSED(task); isc_event_free(&event); LOCK(&set_lock); *value = (int) isc_taskmgr_mode(taskmgr); counter++; UNLOCK(&set_lock); isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_normal); } /* * Individual unit tests */ /* Create a task */ ATF_TC(create_task); ATF_TC_HEAD(create_task, tc) { atf_tc_set_md_var(tc, "descr", "create and destroy a task"); } ATF_TC_BODY(create_task, tc) { isc_result_t result; isc_task_t *task = NULL; UNUSED(tc); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_task_create(taskmgr, 0, &task); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); isc_task_destroy(&task); ATF_REQUIRE_EQ(task, NULL); isc_test_end(); } /* Process events */ ATF_TC(all_events); ATF_TC_HEAD(all_events, tc) { atf_tc_set_md_var(tc, "descr", "process task events"); } ATF_TC_BODY(all_events, tc) { isc_result_t result; isc_task_t *task = NULL; isc_event_t *event; int a = 0, b = 0; int i = 0; UNUSED(tc); counter = 1; result = isc_mutex_init(&set_lock); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_task_create(taskmgr, 0, &task); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); /* First event */ event = isc_event_allocate(mctx, task, ISC_TASKEVENT_TEST, set, &a, sizeof (isc_event_t)); ATF_REQUIRE(event != NULL); ATF_CHECK_EQ(a, 0); isc_task_send(task, &event); event = isc_event_allocate(mctx, task, ISC_TASKEVENT_TEST, set, &b, sizeof (isc_event_t)); ATF_REQUIRE(event != NULL); ATF_CHECK_EQ(b, 0); isc_task_send(task, &event); while ((a == 0 || b == 0) && i++ < 5000) { #ifndef ISC_PLATFORM_USETHREADS while (isc__taskmgr_ready(taskmgr)) isc__taskmgr_dispatch(taskmgr); #endif isc_test_nap(1000); } ATF_CHECK(a != 0); ATF_CHECK(b != 0); isc_task_destroy(&task); ATF_REQUIRE_EQ(task, NULL); isc_test_end(); } /* Privileged events */ ATF_TC(privileged_events); ATF_TC_HEAD(privileged_events, tc) { atf_tc_set_md_var(tc, "descr", "process privileged events"); } ATF_TC_BODY(privileged_events, tc) { isc_result_t result; isc_task_t *task1 = NULL, *task2 = NULL; isc_event_t *event; int a = 0, b = 0, c = 0, d = 0, e = 0; int i = 0; UNUSED(tc); counter = 1; result = isc_mutex_init(&set_lock); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); #ifdef ISC_PLATFORM_USETHREADS /* * Pause the task manager so we can fill up the work queue * without things happening while we do it. */ isc__taskmgr_pause(taskmgr); #endif result = isc_task_create(taskmgr, 0, &task1); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); isc_task_setname(task1, "privileged", NULL); ATF_CHECK(!isc_task_privilege(task1)); isc_task_setprivilege(task1, ISC_TRUE); ATF_CHECK(isc_task_privilege(task1)); result = isc_task_create(taskmgr, 0, &task2); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); isc_task_setname(task2, "normal", NULL); ATF_CHECK(!isc_task_privilege(task2)); /* First event: privileged */ event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST, set, &a, sizeof (isc_event_t)); ATF_REQUIRE(event != NULL); ATF_CHECK_EQ(a, 0); isc_task_send(task1, &event); /* Second event: not privileged */ event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST, set, &b, sizeof (isc_event_t)); ATF_REQUIRE(event != NULL); ATF_CHECK_EQ(b, 0); isc_task_send(task2, &event); /* Third event: privileged */ event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST, set, &c, sizeof (isc_event_t)); ATF_REQUIRE(event != NULL); ATF_CHECK_EQ(c, 0); isc_task_send(task1, &event); /* Fourth event: privileged */ event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST, set, &d, sizeof (isc_event_t)); ATF_REQUIRE(event != NULL); ATF_CHECK_EQ(d, 0); isc_task_send(task1, &event); /* Fifth event: not privileged */ event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST, set, &e, sizeof (isc_event_t)); ATF_REQUIRE(event != NULL); ATF_CHECK_EQ(e, 0); isc_task_send(task2, &event); ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal); isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_privileged); ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_privileged); #ifdef ISC_PLATFORM_USETHREADS isc__taskmgr_resume(taskmgr); #endif /* We're waiting for *all* variables to be set */ while ((a == 0 || b == 0 || c == 0 || d == 0 || e == 0) && i++ < 5000) { #ifndef ISC_PLATFORM_USETHREADS while (isc__taskmgr_ready(taskmgr)) isc__taskmgr_dispatch(taskmgr); #endif isc_test_nap(1000); } /* * We can't guarantee what order the events fire, but * we do know the privileged tasks that set a, c, and d * would have fired first. */ ATF_CHECK(a <= 3); ATF_CHECK(c <= 3); ATF_CHECK(d <= 3); /* ...and the non-privileged tasks that set b and e, last */ ATF_CHECK(b >= 4); ATF_CHECK(e >= 4); ATF_CHECK_EQ(counter, 6); isc_task_setprivilege(task1, ISC_FALSE); ATF_CHECK(!isc_task_privilege(task1)); ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal); isc_task_destroy(&task1); ATF_REQUIRE_EQ(task1, NULL); isc_task_destroy(&task2); ATF_REQUIRE_EQ(task2, NULL); isc_test_end(); } /* * Edge case: this tests that the task manager behaves as expected when * we explicitly set it into normal mode *while* running privileged. */ ATF_TC(privilege_drop); ATF_TC_HEAD(privilege_drop, tc) { atf_tc_set_md_var(tc, "descr", "process privileged events"); } ATF_TC_BODY(privilege_drop, tc) { isc_result_t result; isc_task_t *task1 = NULL, *task2 = NULL; isc_event_t *event; int a = -1, b = -1, c = -1, d = -1, e = -1; /* non valid states */ int i = 0; UNUSED(tc); counter = 1; result = isc_mutex_init(&set_lock); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); #ifdef ISC_PLATFORM_USETHREADS /* * Pause the task manager so we can fill up the work queue * without things happening while we do it. */ isc__taskmgr_pause(taskmgr); #endif result = isc_task_create(taskmgr, 0, &task1); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); isc_task_setname(task1, "privileged", NULL); ATF_CHECK(!isc_task_privilege(task1)); isc_task_setprivilege(task1, ISC_TRUE); ATF_CHECK(isc_task_privilege(task1)); result = isc_task_create(taskmgr, 0, &task2); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); isc_task_setname(task2, "normal", NULL); ATF_CHECK(!isc_task_privilege(task2)); /* First event: privileged */ event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST, set_and_drop, &a, sizeof (isc_event_t)); ATF_REQUIRE(event != NULL); ATF_CHECK_EQ(a, -1); isc_task_send(task1, &event); /* Second event: not privileged */ event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST, set_and_drop, &b, sizeof (isc_event_t)); ATF_REQUIRE(event != NULL); ATF_CHECK_EQ(b, -1); isc_task_send(task2, &event); /* Third event: privileged */ event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST, set_and_drop, &c, sizeof (isc_event_t)); ATF_REQUIRE(event != NULL); ATF_CHECK_EQ(c, -1); isc_task_send(task1, &event); /* Fourth event: privileged */ event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST, set_and_drop, &d, sizeof (isc_event_t)); ATF_REQUIRE(event != NULL); ATF_CHECK_EQ(d, -1); isc_task_send(task1, &event); /* Fifth event: not privileged */ event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST, set_and_drop, &e, sizeof (isc_event_t)); ATF_REQUIRE(event != NULL); ATF_CHECK_EQ(e, -1); isc_task_send(task2, &event); ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal); isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_privileged); ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_privileged); #ifdef ISC_PLATFORM_USETHREADS isc__taskmgr_resume(taskmgr); #endif /* We're waiting for all variables to be set. */ while ((a == -1 || b == -1 || c == -1 || d == -1 || e == -1) && i++ < 5000) { #ifndef ISC_PLATFORM_USETHREADS while (isc__taskmgr_ready(taskmgr)) isc__taskmgr_dispatch(taskmgr); #endif isc_test_nap(1000); } /* * We can't guarantee what order the events fire, but * we do know *exactly one* of the privileged tasks will * have run in privileged mode... */ ATF_CHECK(a == isc_taskmgrmode_privileged || c == isc_taskmgrmode_privileged || d == isc_taskmgrmode_privileged); ATF_CHECK(a + c + d == isc_taskmgrmode_privileged); /* ...and neither of the non-privileged tasks did... */ ATF_CHECK(b == isc_taskmgrmode_normal || e == isc_taskmgrmode_normal); /* ...but all five of them did run. */ ATF_CHECK_EQ(counter, 6); ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal); isc_task_destroy(&task1); ATF_REQUIRE_EQ(task1, NULL); isc_task_destroy(&task2); ATF_REQUIRE_EQ(task2, NULL); isc_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, create_task); ATF_TP_ADD_TC(tp, all_events); ATF_TP_ADD_TC(tp, privileged_events); ATF_TP_ADD_TC(tp, privilege_drop); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/isc/tests/isctest.h0000644000470500017500000000300512664710322017704 0ustar lamontlamont/* * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #define CHECK(r) \ do { \ result = (r); \ if (result != ISC_R_SUCCESS) \ goto cleanup; \ } while (0) extern isc_mem_t *mctx; extern isc_entropy_t *ectx; extern isc_log_t *lctx; extern isc_taskmgr_t *taskmgr; extern isc_timermgr_t *timermgr; extern isc_socketmgr_t *socketmgr; extern int ncpus; isc_result_t isc_test_begin(FILE *logfile, isc_boolean_t start_managers); void isc_test_end(void); void isc_test_nap(isc_uint32_t usec); bind9-9.10.3.dfsg.P4/lib/isc/tests/queue_test.c0000644000470500017500000000651512664710322020415 0ustar lamontlamont/* * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include "isctest.h" typedef struct item item_t; struct item { int value; ISC_QLINK(item_t) qlink; }; typedef ISC_QUEUE(item_t) item_queue_t; static void item_init(item_t *item, int value) { item->value = value; ISC_QLINK_INIT(item, qlink); } /* * Individual unit tests */ /* Test UDP sendto/recv (IPv4) */ ATF_TC(queue_valid); ATF_TC_HEAD(queue_valid, tc) { atf_tc_set_md_var(tc, "descr", "Check queue validity"); } ATF_TC_BODY(queue_valid, tc) { isc_result_t result; item_queue_t queue; item_t one, two, three, four, five; item_t *p; UNUSED(tc); ISC_QUEUE_INIT(queue, qlink); item_init(&one, 1); item_init(&two, 2); item_init(&three, 3); item_init(&four, 4); item_init(&five, 5); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_CHECK(ISC_QUEUE_EMPTY(queue)); ISC_QUEUE_POP(queue, qlink, p); ATF_CHECK(p == NULL); ATF_CHECK(! ISC_QLINK_LINKED(&one, qlink)); ISC_QUEUE_PUSH(queue, &one, qlink); ATF_CHECK(ISC_QLINK_LINKED(&one, qlink)); ATF_CHECK(! ISC_QUEUE_EMPTY(queue)); ISC_QUEUE_POP(queue, qlink, p); ATF_REQUIRE(p != NULL); ATF_CHECK_EQ(p->value, 1); ATF_CHECK(ISC_QUEUE_EMPTY(queue)); ATF_CHECK(! ISC_QLINK_LINKED(p, qlink)); ISC_QUEUE_PUSH(queue, p, qlink); ATF_CHECK(! ISC_QUEUE_EMPTY(queue)); ATF_CHECK(ISC_QLINK_LINKED(p, qlink)); ATF_CHECK(! ISC_QLINK_LINKED(&two, qlink)); ISC_QUEUE_PUSH(queue, &two, qlink); ATF_CHECK(ISC_QLINK_LINKED(&two, qlink)); ATF_CHECK(! ISC_QLINK_LINKED(&three, qlink)); ISC_QUEUE_PUSH(queue, &three, qlink); ATF_CHECK(ISC_QLINK_LINKED(&three, qlink)); ATF_CHECK(! ISC_QLINK_LINKED(&four, qlink)); ISC_QUEUE_PUSH(queue, &four, qlink); ATF_CHECK(ISC_QLINK_LINKED(&four, qlink)); ATF_CHECK(! ISC_QLINK_LINKED(&five, qlink)); ISC_QUEUE_PUSH(queue, &five, qlink); ATF_CHECK(ISC_QLINK_LINKED(&five, qlink)); /* Test unlink by removing one item from the middle */ ISC_QUEUE_UNLINK(queue, &three, qlink); ISC_QUEUE_POP(queue, qlink, p); ATF_REQUIRE(p != NULL); ATF_CHECK_EQ(p->value, 1); ISC_QUEUE_POP(queue, qlink, p); ATF_REQUIRE(p != NULL); ATF_CHECK_EQ(p->value, 2); ISC_QUEUE_POP(queue, qlink, p); ATF_REQUIRE(p != NULL); ATF_CHECK_EQ(p->value, 4); ISC_QUEUE_POP(queue, qlink, p); ATF_REQUIRE(p != NULL); ATF_CHECK_EQ(p->value, 5); ATF_CHECK(ISC_QUEUE_EMPTY(queue)); ISC_QUEUE_DESTROY(queue); isc_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, queue_valid); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/isc/tests/aes_test.c0000644000470500017500000001665412664710322020046 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* ! \file */ #include #include #include #include #include #include #include #include #include #include #include #ifdef ISC_PLATFORM_WANTAES /* * Test data from NIST KAT */ isc_result_t tohexstr(unsigned char *d, char *out); size_t fromhexstr(const char *in, unsigned char *d); unsigned char plaintext[3 * ISC_AES_BLOCK_LENGTH]; unsigned char ciphertext[ISC_AES_BLOCK_LENGTH]; char str[2 * ISC_AES_BLOCK_LENGTH + 1]; unsigned char key[ISC_AES256_KEYLENGTH + 1]; size_t len; isc_result_t tohexstr(unsigned char *d, char *out) { isc_buffer_t b; isc_region_t r; isc_buffer_init(&b, out, 2 * ISC_AES_BLOCK_LENGTH + 1); r.base = d; r.length = ISC_AES_BLOCK_LENGTH; return (isc_hex_totext(&r, 0, "", &b)); } size_t fromhexstr(const char *in, unsigned char *d) { isc_buffer_t b; isc_result_t ret; isc_buffer_init(&b, d, ISC_AES256_KEYLENGTH + 1); ret = isc_hex_decodestring(in, &b); if (ret != ISC_R_SUCCESS) return 0; return isc_buffer_usedlength(&b); } typedef struct aes_testcase { const char *key; const char *input; const char *result; } aes_testcase_t; ATF_TC(isc_aes128); ATF_TC_HEAD(isc_aes128, tc) { atf_tc_set_md_var(tc, "descr", "AES 128 test vectors"); } ATF_TC_BODY(isc_aes128, tc) { UNUSED(tc); aes_testcase_t testcases[] = { /* Test 1 (KAT ECBVarTxt128 #3) */ { "00000000000000000000000000000000", "F0000000000000000000000000000000", "96D9FD5CC4F07441727DF0F33E401A36" }, /* Test 2 (KAT ECBVarTxt128 #123) */ { "00000000000000000000000000000000", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", "F9B0FDA0C4A898F5B9E6F661C4CE4D07" }, /* Test 3 (KAT ECBVarKey128 #3) */ { "F0000000000000000000000000000000", "00000000000000000000000000000000", "970014D634E2B7650777E8E84D03CCD8" }, /* Test 4 (KAT ECBVarKey128 #123) */ { "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", "00000000000000000000000000000000", "41C78C135ED9E98C096640647265DA1E" }, /* Test 5 (KAT ECBGFSbox128 #3) */ { "00000000000000000000000000000000", "6A118A874519E64E9963798A503F1D35", "DC43BE40BE0E53712F7E2BF5CA707209" }, /* Test 6 (KAT ECBKeySbox128 #3) */ { "B6364AC4E1DE1E285EAF144A2415F7A0", "00000000000000000000000000000000", "5D9B05578FC944B3CF1CCF0E746CD581" }, { NULL, NULL, NULL } }; aes_testcase_t *testcase = testcases; while (testcase->key != NULL) { len = fromhexstr(testcase->key, key); ATF_CHECK_EQ(len, ISC_AES128_KEYLENGTH); len = fromhexstr(testcase->input, plaintext); ATF_CHECK_EQ(len, ISC_AES_BLOCK_LENGTH); isc_aes128_crypt(key, plaintext, ciphertext); ATF_CHECK(tohexstr(ciphertext, str) == ISC_R_SUCCESS); ATF_CHECK_STREQ(str, testcase->result); testcase++; } } ATF_TC(isc_aes192); ATF_TC_HEAD(isc_aes192, tc) { atf_tc_set_md_var(tc, "descr", "AES 192 test vectors"); } ATF_TC_BODY(isc_aes192, tc) { UNUSED(tc); aes_testcase_t testcases[] = { /* Test 1 (KAT ECBVarTxt192 #3) */ { "000000000000000000000000000000000000000000000000", "F0000000000000000000000000000000", "2A560364CE529EFC21788779568D5555" }, /* Test 2 (KAT ECBVarTxt192 #123) */ { "000000000000000000000000000000000000000000000000", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", "2AABB999F43693175AF65C6C612C46FB" }, /* Test 3 (KAT ECBVarKey192 #3) */ { "F00000000000000000000000000000000000000000000000", "00000000000000000000000000000000", "180B09F267C45145DB2F826C2582D35C" }, /* Test 4 (KAT ECBVarKey192 #187) */ { "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", "00000000000000000000000000000000", "EACF1E6C4224EFB38900B185AB1DFD42" }, /* Test 5 (KAT ECBGFSbox192 #3) */ { "000000000000000000000000000000000000000000000000", "51719783D3185A535BD75ADC65071CE1", "4F354592FF7C8847D2D0870CA9481B7C" }, /* Test 6 (KAT ECBKeySbox192 #3) */ { "CD62376D5EBB414917F0C78F05266433DC9192A1EC943300", "00000000000000000000000000000000", "7F6C25FF41858561BB62F36492E93C29" }, { NULL, NULL, NULL } }; aes_testcase_t *testcase = testcases; while (testcase->key != NULL) { len = fromhexstr(testcase->key, key); ATF_CHECK_EQ(len, ISC_AES192_KEYLENGTH); len = fromhexstr(testcase->input, plaintext); ATF_CHECK_EQ(len, ISC_AES_BLOCK_LENGTH); isc_aes192_crypt(key, plaintext, ciphertext); ATF_CHECK(tohexstr(ciphertext, str) == ISC_R_SUCCESS); ATF_CHECK_STREQ(str, testcase->result); testcase++; } } ATF_TC(isc_aes256); ATF_TC_HEAD(isc_aes256, tc) { atf_tc_set_md_var(tc, "descr", "AES 256 test vectors"); } ATF_TC_BODY(isc_aes256, tc) { UNUSED(tc); aes_testcase_t testcases[] = { /* Test 1 (KAT ECBVarTxt256 #3) */ { "00000000000000000000000000000000" "00000000000000000000000000000000", "F0000000000000000000000000000000", "7F2C5ECE07A98D8BEE13C51177395FF7" }, /* Test 2 (KAT ECBVarTxt256 #123) */ { "00000000000000000000000000000000" "00000000000000000000000000000000", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", "7240E524BC51D8C4D440B1BE55D1062C" }, /* Test 3 (KAT ECBVarKey256 #3) */ { "F0000000000000000000000000000000" "00000000000000000000000000000000", "00000000000000000000000000000000", "1C777679D50037C79491A94DA76A9A35" }, /* Test 4 (KAT ECBVarKey256 #251) */ { "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", "00000000000000000000000000000000", "03720371A04962EAEA0A852E69972858" }, /* Test 5 (KAT ECBGFSbox256 #3) */ { "00000000000000000000000000000000" "00000000000000000000000000000000", "8A560769D605868AD80D819BDBA03771", "38F2C7AE10612415D27CA190D27DA8B4" }, /* Test 6 (KAT ECBKeySbox256 #3) */ { "984CA75F4EE8D706F46C2D98C0BF4A45" "F5B00D791C2DFEB191B5ED8E420FD627", "00000000000000000000000000000000", "4307456A9E67813B452E15FA8FFFE398" }, { NULL, NULL, NULL } }; aes_testcase_t *testcase = testcases; while (testcase->key != NULL) { len = fromhexstr(testcase->key, key); ATF_CHECK_EQ(len, ISC_AES256_KEYLENGTH); len = fromhexstr(testcase->input, plaintext); ATF_CHECK_EQ(len, ISC_AES_BLOCK_LENGTH); isc_aes256_crypt(key, plaintext, ciphertext); ATF_CHECK(tohexstr(ciphertext, str) == ISC_R_SUCCESS); ATF_CHECK_STREQ(str, testcase->result); testcase++; } } #else ATF_TC(untested); ATF_TC_HEAD(untested, tc) { atf_tc_set_md_var(tc, "descr", "skipping aes test"); } ATF_TC_BODY(untested, tc) { UNUSED(tc); atf_tc_skip("AES not available"); } #endif /* * Main */ ATF_TP_ADD_TCS(tp) { #ifdef ISC_PLATFORM_WANTAES ATF_TP_ADD_TC(tp, isc_aes128); ATF_TP_ADD_TC(tp, isc_aes192); ATF_TP_ADD_TC(tp, isc_aes256); #else ATF_TP_ADD_TC(tp, untested); #endif return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/isc/tests/parse_test.c0000644000470500017500000000341312664710322020375 0ustar lamontlamont/* * Copyright (C) 2012, 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include "isctest.h" /* * Individual unit tests */ /* Test for 32 bit overflow on 64 bit machines in isc_parse_uint32 */ ATF_TC(parse_overflow); ATF_TC_HEAD(parse_overflow, tc) { atf_tc_set_md_var(tc, "descr", "Check for 32 bit overflow"); } ATF_TC_BODY(parse_overflow, tc) { isc_result_t result; isc_uint32_t output; UNUSED(tc); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_parse_uint32(&output, "1234567890", 10); ATF_CHECK_EQ(ISC_R_SUCCESS, result); ATF_CHECK_EQ(1234567890, output); result = isc_parse_uint32(&output, "123456789012345", 10); ATF_CHECK_EQ(ISC_R_RANGE, result); result = isc_parse_uint32(&output, "12345678901234567890", 10); ATF_CHECK_EQ(ISC_R_RANGE, result); isc_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, parse_overflow); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/isc/tests/time_test.c0000644000470500017500000000307412664710322020224 0ustar lamontlamont/* * Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include ATF_TC(isc_time_parsehttptimestamp); ATF_TC_HEAD(isc_time_parsehttptimestamp, tc) { atf_tc_set_md_var(tc, "descr", "parse http time stamp"); } ATF_TC_BODY(isc_time_parsehttptimestamp, tc) { isc_result_t result; isc_time_t t, x; char buf[ISC_FORMATHTTPTIMESTAMP_SIZE]; setenv("TZ", "PST8PDT", 1); result = isc_time_now(&t); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); isc_time_formathttptimestamp(&t, buf, sizeof(buf)); result = isc_time_parsehttptimestamp(buf, &x); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(isc_time_seconds(&t), isc_time_seconds(&x)); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, isc_time_parsehttptimestamp); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/isc/tests/Atffile0000644000470500017500000000014012664710322017347 0ustar lamontlamontContent-Type: application/X-atf-atffile; version="1" prop: test-suite = bind9 tp-glob: *_test bind9-9.10.3.dfsg.P4/lib/isc/tests/taskpool_test.c0000644000470500017500000001236712664710322021127 0ustar lamontlamont/* * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include "isctest.h" /* * Individual unit tests */ /* Create a taskpool */ ATF_TC(create_pool); ATF_TC_HEAD(create_pool, tc) { atf_tc_set_md_var(tc, "descr", "create a taskpool"); } ATF_TC_BODY(create_pool, tc) { isc_result_t result; isc_taskpool_t *pool = NULL; UNUSED(tc); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_taskpool_create(taskmgr, mctx, 8, 2, &pool); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(isc_taskpool_size(pool), 8); isc_taskpool_destroy(&pool); ATF_REQUIRE_EQ(pool, NULL); isc_test_end(); } /* Resize a taskpool */ ATF_TC(expand_pool); ATF_TC_HEAD(expand_pool, tc) { atf_tc_set_md_var(tc, "descr", "expand a taskpool"); } ATF_TC_BODY(expand_pool, tc) { isc_result_t result; isc_taskpool_t *pool1 = NULL, *pool2 = NULL, *hold = NULL; UNUSED(tc); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_taskpool_create(taskmgr, mctx, 10, 2, &pool1); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(isc_taskpool_size(pool1), 10); /* resizing to a smaller size should have no effect */ hold = pool1; result = isc_taskpool_expand(&pool1, 5, &pool2); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(isc_taskpool_size(pool2), 10); ATF_REQUIRE_EQ(pool2, hold); ATF_REQUIRE_EQ(pool1, NULL); pool1 = pool2; pool2 = NULL; /* resizing to the same size should have no effect */ hold = pool1; result = isc_taskpool_expand(&pool1, 10, &pool2); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(isc_taskpool_size(pool2), 10); ATF_REQUIRE_EQ(pool2, hold); ATF_REQUIRE_EQ(pool1, NULL); pool1 = pool2; pool2 = NULL; /* resizing to larger size should make a new pool */ hold = pool1; result = isc_taskpool_expand(&pool1, 20, &pool2); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(isc_taskpool_size(pool2), 20); ATF_REQUIRE(pool2 != hold); ATF_REQUIRE_EQ(pool1, NULL); isc_taskpool_destroy(&pool2); ATF_REQUIRE_EQ(pool2, NULL); isc_test_end(); } /* Get tasks */ ATF_TC(get_tasks); ATF_TC_HEAD(get_tasks, tc) { atf_tc_set_md_var(tc, "descr", "create a taskpool"); } ATF_TC_BODY(get_tasks, tc) { isc_result_t result; isc_taskpool_t *pool = NULL; isc_task_t *task1 = NULL, *task2 = NULL, *task3 = NULL; UNUSED(tc); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_taskpool_create(taskmgr, mctx, 2, 2, &pool); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(isc_taskpool_size(pool), 2); /* two tasks in pool; make sure we can access them more than twice */ isc_taskpool_gettask(pool, &task1); ATF_REQUIRE(ISCAPI_TASK_VALID(task1)); isc_taskpool_gettask(pool, &task2); ATF_REQUIRE(ISCAPI_TASK_VALID(task2)); isc_taskpool_gettask(pool, &task3); ATF_REQUIRE(ISCAPI_TASK_VALID(task3)); isc_task_destroy(&task1); isc_task_destroy(&task2); isc_task_destroy(&task3); isc_taskpool_destroy(&pool); ATF_REQUIRE_EQ(pool, NULL); isc_test_end(); } /* Get tasks */ ATF_TC(set_privilege); ATF_TC_HEAD(set_privilege, tc) { atf_tc_set_md_var(tc, "descr", "create a taskpool"); } ATF_TC_BODY(set_privilege, tc) { isc_result_t result; isc_taskpool_t *pool = NULL; isc_task_t *task1 = NULL, *task2 = NULL, *task3 = NULL; UNUSED(tc); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_taskpool_create(taskmgr, mctx, 2, 2, &pool); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(isc_taskpool_size(pool), 2); isc_taskpool_setprivilege(pool, ISC_TRUE); isc_taskpool_gettask(pool, &task1); isc_taskpool_gettask(pool, &task2); isc_taskpool_gettask(pool, &task3); ATF_CHECK(ISCAPI_TASK_VALID(task1)); ATF_CHECK(ISCAPI_TASK_VALID(task2)); ATF_CHECK(ISCAPI_TASK_VALID(task3)); ATF_CHECK(isc_task_privilege(task1)); ATF_CHECK(isc_task_privilege(task2)); ATF_CHECK(isc_task_privilege(task3)); isc_taskpool_setprivilege(pool, ISC_FALSE); ATF_CHECK(!isc_task_privilege(task1)); ATF_CHECK(!isc_task_privilege(task2)); ATF_CHECK(!isc_task_privilege(task3)); isc_task_destroy(&task1); isc_task_destroy(&task2); isc_task_destroy(&task3); isc_taskpool_destroy(&pool); ATF_REQUIRE_EQ(pool, NULL); isc_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, create_pool); ATF_TP_ADD_TC(tp, expand_pool); ATF_TP_ADD_TC(tp, get_tasks); ATF_TP_ADD_TC(tp, set_privilege); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/isc/tests/isctest.c0000644000470500017500000001042112664710322017677 0ustar lamontlamont/* * Copyright (C) 2011-2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "isctest.h" isc_mem_t *mctx = NULL; isc_entropy_t *ectx = NULL; isc_log_t *lctx = NULL; isc_taskmgr_t *taskmgr = NULL; isc_timermgr_t *timermgr = NULL; isc_socketmgr_t *socketmgr = NULL; isc_task_t *maintask = NULL; int ncpus; static isc_boolean_t hash_active = ISC_FALSE; /* * Logging categories: this needs to match the list in bin/named/log.c. */ static isc_logcategory_t categories[] = { { "", 0 }, { "client", 0 }, { "network", 0 }, { "update", 0 }, { "queries", 0 }, { "unmatched", 0 }, { "update-security", 0 }, { "query-errors", 0 }, { NULL, 0 } }; static void cleanup_managers(void) { if (maintask != NULL) isc_task_destroy(&maintask); if (socketmgr != NULL) isc_socketmgr_destroy(&socketmgr); if (taskmgr != NULL) isc_taskmgr_destroy(&taskmgr); if (timermgr != NULL) isc_timermgr_destroy(&timermgr); } static isc_result_t create_managers(void) { isc_result_t result; #ifdef ISC_PLATFORM_USETHREADS ncpus = isc_os_ncpus(); #else ncpus = 1; #endif CHECK(isc_taskmgr_create(mctx, ncpus, 0, &taskmgr)); CHECK(isc_task_create(taskmgr, 0, &maintask)); isc_taskmgr_setexcltask(taskmgr, maintask); CHECK(isc_timermgr_create(mctx, &timermgr)); CHECK(isc_socketmgr_create(mctx, &socketmgr)); return (ISC_R_SUCCESS); cleanup: cleanup_managers(); return (result); } isc_result_t isc_test_begin(FILE *logfile, isc_boolean_t start_managers) { isc_result_t result; isc_mem_debugging |= ISC_MEM_DEBUGRECORD; CHECK(isc_mem_create(0, 0, &mctx)); CHECK(isc_entropy_create(mctx, &ectx)); CHECK(isc_hash_create(mctx, ectx, 255)); hash_active = ISC_TRUE; if (logfile != NULL) { isc_logdestination_t destination; isc_logconfig_t *logconfig = NULL; CHECK(isc_log_create(mctx, &lctx, &logconfig)); isc_log_registercategories(lctx, categories); isc_log_setcontext(lctx); destination.file.stream = logfile; destination.file.name = NULL; destination.file.versions = ISC_LOG_ROLLNEVER; destination.file.maximum_size = 0; CHECK(isc_log_createchannel(logconfig, "stderr", ISC_LOG_TOFILEDESC, ISC_LOG_DYNAMIC, &destination, 0)); CHECK(isc_log_usechannel(logconfig, "stderr", NULL, NULL)); } #ifdef ISC_PLATFORM_USETHREADS ncpus = isc_os_ncpus(); #else ncpus = 1; #endif if (start_managers) CHECK(create_managers()); return (ISC_R_SUCCESS); cleanup: isc_test_end(); return (result); } void isc_test_end(void) { if (maintask != NULL) isc_task_detach(&maintask); if (taskmgr != NULL) isc_taskmgr_destroy(&taskmgr); if (lctx != NULL) isc_log_destroy(&lctx); if (hash_active) { isc_hash_destroy(); hash_active = ISC_FALSE; } if (ectx != NULL) isc_entropy_detach(&ectx); cleanup_managers(); if (mctx != NULL) isc_mem_destroy(&mctx); } /* * Sleep for 'usec' microseconds. */ void isc_test_nap(isc_uint32_t usec) { #ifdef HAVE_NANOSLEEP struct timespec ts; ts.tv_sec = usec / 1000000; ts.tv_nsec = (usec % 1000000) * 1000; nanosleep(&ts, NULL); #elif HAVE_USLEEP usleep(usec); #else /* * No fractional-second sleep function is available, so we * round up to the nearest second and sleep instead */ sleep((usec / 1000000) + 1); #endif } bind9-9.10.3.dfsg.P4/lib/isc/tests/radix_test.c0000644000470500017500000000504012664710322020370 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #include #include #include #include #include "isctest.h" ATF_TC(isc_radix_search); ATF_TC_HEAD(isc_radix_search, tc) { atf_tc_set_md_var(tc, "descr", "test radix seaching"); } ATF_TC_BODY(isc_radix_search, tc) { isc_radix_tree_t *radix = NULL; isc_radix_node_t *node; isc_prefix_t prefix; isc_result_t result; struct in_addr in_addr; isc_netaddr_t netaddr; UNUSED(tc); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_radix_create(mctx, &radix, 32); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); in_addr.s_addr = inet_addr("3.3.3.0"); isc_netaddr_fromin(&netaddr, &in_addr); NETADDR_TO_PREFIX_T(&netaddr, prefix, 24); node = NULL; result = isc_radix_insert(radix, &node, NULL, &prefix); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); node->data[0] = (void *)1; isc_refcount_destroy(&prefix.refcount); in_addr.s_addr = inet_addr("3.3.0.0"); isc_netaddr_fromin(&netaddr, &in_addr); NETADDR_TO_PREFIX_T(&netaddr, prefix, 16); node = NULL; result = isc_radix_insert(radix, &node, NULL, &prefix); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); node->data[0] = (void *)2; isc_refcount_destroy(&prefix.refcount); in_addr.s_addr = inet_addr("3.3.3.3"); isc_netaddr_fromin(&netaddr, &in_addr); NETADDR_TO_PREFIX_T(&netaddr, prefix, 22); node = NULL; result = isc_radix_search(radix, &node, &prefix); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(node->data[0], (void *)2); isc_refcount_destroy(&prefix.refcount); isc_radix_destroy(radix, NULL); isc_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, isc_radix_search); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/isc/tests/sockaddr_test.c0000644000470500017500000000355212664710322021061 0ustar lamontlamont/* * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include "isctest.h" /* * Individual unit tests */ ATF_TC(sockaddr_hash); ATF_TC_HEAD(sockaddr_hash, tc) { atf_tc_set_md_var(tc, "descr", "sockaddr hash"); } ATF_TC_BODY(sockaddr_hash, tc) { isc_result_t result; isc_sockaddr_t addr; struct in_addr in; struct in6_addr in6; unsigned int h1, h2, h3, h4; int ret; UNUSED(tc); result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); in.s_addr = inet_addr("127.0.0.1"); isc_sockaddr_fromin(&addr, &in, 1); h1 = isc_sockaddr_hash(&addr, ISC_TRUE); h2 = isc_sockaddr_hash(&addr, ISC_FALSE); ATF_CHECK(h1 != h2); ret = inet_pton(AF_INET6, "::ffff:127.0.0.1", &in6); ATF_CHECK(ret == 1); isc_sockaddr_fromin6(&addr, &in6, 1); h3 = isc_sockaddr_hash(&addr, ISC_TRUE); h4 = isc_sockaddr_hash(&addr, ISC_FALSE); ATF_CHECK(h1 == h3); ATF_CHECK(h2 == h4); isc_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, sockaddr_hash); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/isc/tests/counter_test.c0000644000470500017500000000342212664710322020742 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #include "isctest.h" ATF_TC(isc_counter); ATF_TC_HEAD(isc_counter, tc) { atf_tc_set_md_var(tc, "descr", "isc counter object"); } ATF_TC_BODY(isc_counter, tc) { isc_result_t result; isc_counter_t *counter = NULL; int i; result = isc_test_begin(NULL, ISC_TRUE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_counter_create(mctx, 0, &counter); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); for (i = 0; i < 10; i++) { result = isc_counter_increment(counter); ATF_CHECK_EQ(result, ISC_R_SUCCESS); } ATF_CHECK_EQ(isc_counter_used(counter), 10); isc_counter_setlimit(counter, 15); for (i = 0; i < 10; i++) { result = isc_counter_increment(counter); if (result != ISC_R_SUCCESS) break; } ATF_CHECK_EQ(isc_counter_used(counter), 15); isc_counter_detach(&counter); isc_test_end(); } /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, isc_counter); return (atf_no_error()); } bind9-9.10.3.dfsg.P4/lib/isc/backtrace-emptytbl.c0000644000470500017500000000252212664710322020637 0ustar lamontlamont/* * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: backtrace-emptytbl.c,v 1.3 2009/09/01 20:13:44 each Exp $ */ /*! \file */ /* * This file defines an empty (default) symbol table used in backtrace.c * If the application wants to have a complete symbol table, it should redefine * isc__backtrace_symtable with the complete table in some way, and link the * version of the library not including this definition * (e.g. libisc-nosymbol.a). */ #include #include const int isc__backtrace_nsymbols = 0; const isc_backtrace_symmap_t isc__backtrace_symtable[] = { { NULL, "" } }; bind9-9.10.3.dfsg.P4/lib/isc/httpd.c0000644000470500017500000006574512664710322016225 0ustar lamontlamont/* * Copyright (C) 2006-2008, 2010-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include /*% * TODO: * * o Put in better checks to make certain things are passed in correctly. * This includes a magic number for externally-visible structures, * checking for NULL-ness before dereferencing, etc. * o Make the URL processing external functions which will fill-in a buffer * structure we provide, or return an error and we will render a generic * page and close the client. */ #define MSHUTTINGDOWN(cm) ((cm->flags & ISC_HTTPDMGR_FLAGSHUTTINGDOWN) != 0) #define MSETSHUTTINGDOWN(cm) (cm->flags |= ISC_HTTPDMGR_FLAGSHUTTINGDOWN) #ifdef DEBUG_HTTPD #define ENTER(x) do { fprintf(stderr, "ENTER %s\n", (x)); } while (0) #define EXIT(x) do { fprintf(stderr, "EXIT %s\n", (x)); } while (0) #define NOTICE(x) do { fprintf(stderr, "NOTICE %s\n", (x)); } while (0) #else #define ENTER(x) do { } while(0) #define EXIT(x) do { } while(0) #define NOTICE(x) do { } while(0) #endif #define HTTP_RECVLEN 1024 #define HTTP_SENDGROW 1024 #define HTTP_SEND_MAXLEN 10240 #define HTTPD_CLOSE 0x0001 /* Got a Connection: close header */ #define HTTPD_FOUNDHOST 0x0002 /* Got a Host: header */ #define HTTPD_KEEPALIVE 0x0004 /* Got a Connection: Keep-Alive */ /*% http client */ struct isc_httpd { isc_httpdmgr_t *mgr; /*%< our parent */ ISC_LINK(isc_httpd_t) link; unsigned int state; isc_socket_t *sock; /*% * Received data state. */ char recvbuf[HTTP_RECVLEN]; /*%< receive buffer */ isc_uint32_t recvlen; /*%< length recv'd */ char *headers; /*%< set in process_request() */ unsigned int method; char *url; char *querystring; char *protocol; /* * Flags on the httpd client. */ int flags; /*% * Transmit data state. * * This is the data buffer we will transmit. * * This free function pointer is filled in by the rendering function * we call. The free function is called after the data is transmitted * to the client. * * The bufflist is the list of buffers we are currently transmitting. * The headerdata is where we render our headers to. If we run out of * space when rendering a header, we will change the size of our * buffer. We will not free it until we are finished, and will * allocate an additional HTTP_SENDGROW bytes per header space grow. * * We currently use two buffers total, one for the headers (which * we manage) and another for the client to fill in (which it manages, * it provides the space for it, etc) -- we will pass that buffer * structure back to the caller, who is responsible for managing the * space it may have allocated as backing store for it. This second * buffer is bodybuffer, and we only allocate the buffer itself, not * the backing store. */ isc_bufferlist_t bufflist; char *headerdata; /*%< send header buf */ unsigned int headerlen; /*%< current header buffer size */ isc_buffer_t headerbuffer; const char *mimetype; unsigned int retcode; const char *retmsg; isc_buffer_t bodybuffer; isc_httpdfree_t *freecb; void *freecb_arg; }; /*% lightweight socket manager for httpd output */ struct isc_httpdmgr { isc_mem_t *mctx; isc_socket_t *sock; /*%< listening socket */ isc_task_t *task; /*%< owning task */ isc_timermgr_t *timermgr; isc_httpdclientok_t *client_ok; /*%< client validator */ isc_httpdondestroy_t *ondestroy; /*%< cleanup callback */ void *cb_arg; /*%< argument for the above */ unsigned int flags; ISC_LIST(isc_httpd_t) running; /*%< running clients */ isc_mutex_t lock; ISC_LIST(isc_httpdurl_t) urls; /*%< urls we manage */ isc_httpdaction_t *render_404; isc_httpdaction_t *render_500; }; /*% * HTTP methods. */ #define ISC_HTTPD_METHODUNKNOWN 0 #define ISC_HTTPD_METHODGET 1 #define ISC_HTTPD_METHODPOST 2 /*% * Client states. * * _IDLE The client is not doing anything at all. This state should * only occur just after creation, and just before being * destroyed. * * _RECV The client is waiting for data after issuing a socket recv(). * * _RECVDONE Data has been received, and is being processed. * * _SEND All data for a response has completed, and a reply was * sent via a socket send() call. * * _SENDDONE Send is completed. * * Badly formatted state table: * * IDLE -> RECV when client has a recv() queued. * * RECV -> RECVDONE when recvdone event received. * * RECVDONE -> SEND if the data for a reply is at hand. * * SEND -> RECV when a senddone event was received. * * At any time -> RECV on error. If RECV fails, the client will * self-destroy, closing the socket and freeing memory. */ #define ISC_HTTPD_STATEIDLE 0 #define ISC_HTTPD_STATERECV 1 #define ISC_HTTPD_STATERECVDONE 2 #define ISC_HTTPD_STATESEND 3 #define ISC_HTTPD_STATESENDDONE 4 #define ISC_HTTPD_ISRECV(c) ((c)->state == ISC_HTTPD_STATERECV) #define ISC_HTTPD_ISRECVDONE(c) ((c)->state == ISC_HTTPD_STATERECVDONE) #define ISC_HTTPD_ISSEND(c) ((c)->state == ISC_HTTPD_STATESEND) #define ISC_HTTPD_ISSENDDONE(c) ((c)->state == ISC_HTTPD_STATESENDDONE) /*% * Overall magic test that means we're not idle. */ #define ISC_HTTPD_SETRECV(c) ((c)->state = ISC_HTTPD_STATERECV) #define ISC_HTTPD_SETRECVDONE(c) ((c)->state = ISC_HTTPD_STATERECVDONE) #define ISC_HTTPD_SETSEND(c) ((c)->state = ISC_HTTPD_STATESEND) #define ISC_HTTPD_SETSENDDONE(c) ((c)->state = ISC_HTTPD_STATESENDDONE) static void isc_httpd_accept(isc_task_t *, isc_event_t *); static void isc_httpd_recvdone(isc_task_t *, isc_event_t *); static void isc_httpd_senddone(isc_task_t *, isc_event_t *); static void destroy_client(isc_httpd_t **); static isc_result_t process_request(isc_httpd_t *, int); static void httpdmgr_destroy(isc_httpdmgr_t *); static isc_result_t grow_headerspace(isc_httpd_t *); static void reset_client(isc_httpd_t *httpd); static isc_httpdaction_t render_404; static isc_httpdaction_t render_500; static void destroy_client(isc_httpd_t **httpdp) { isc_httpd_t *httpd = *httpdp; isc_httpdmgr_t *httpdmgr = httpd->mgr; *httpdp = NULL; LOCK(&httpdmgr->lock); isc_socket_detach(&httpd->sock); ISC_LIST_UNLINK(httpdmgr->running, httpd, link); if (httpd->headerlen > 0) isc_mem_put(httpdmgr->mctx, httpd->headerdata, httpd->headerlen); isc_mem_put(httpdmgr->mctx, httpd, sizeof(isc_httpd_t)); UNLOCK(&httpdmgr->lock); httpdmgr_destroy(httpdmgr); } isc_result_t isc_httpdmgr_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task, isc_httpdclientok_t *client_ok, isc_httpdondestroy_t *ondestroy, void *cb_arg, isc_timermgr_t *tmgr, isc_httpdmgr_t **httpdmgrp) { isc_result_t result; isc_httpdmgr_t *httpdmgr; REQUIRE(mctx != NULL); REQUIRE(sock != NULL); REQUIRE(task != NULL); REQUIRE(tmgr != NULL); REQUIRE(httpdmgrp != NULL && *httpdmgrp == NULL); httpdmgr = isc_mem_get(mctx, sizeof(isc_httpdmgr_t)); if (httpdmgr == NULL) return (ISC_R_NOMEMORY); result = isc_mutex_init(&httpdmgr->lock); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, httpdmgr, sizeof(isc_httpdmgr_t)); return (result); } httpdmgr->mctx = NULL; isc_mem_attach(mctx, &httpdmgr->mctx); httpdmgr->sock = NULL; isc_socket_attach(sock, &httpdmgr->sock); httpdmgr->task = NULL; isc_task_attach(task, &httpdmgr->task); httpdmgr->timermgr = tmgr; /* XXXMLG no attach function? */ httpdmgr->client_ok = client_ok; httpdmgr->ondestroy = ondestroy; httpdmgr->cb_arg = cb_arg; httpdmgr->flags = 0; ISC_LIST_INIT(httpdmgr->running); ISC_LIST_INIT(httpdmgr->urls); /* XXXMLG ignore errors on isc_socket_listen() */ result = isc_socket_listen(sock, SOMAXCONN); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_socket_listen() failed: %s", isc_result_totext(result)); goto cleanup; } (void)isc_socket_filter(sock, "httpready"); result = isc_socket_accept(sock, task, isc_httpd_accept, httpdmgr); if (result != ISC_R_SUCCESS) goto cleanup; httpdmgr->render_404 = render_404; httpdmgr->render_500 = render_500; *httpdmgrp = httpdmgr; return (ISC_R_SUCCESS); cleanup: isc_task_detach(&httpdmgr->task); isc_socket_detach(&httpdmgr->sock); isc_mem_detach(&httpdmgr->mctx); (void)isc_mutex_destroy(&httpdmgr->lock); isc_mem_put(mctx, httpdmgr, sizeof(isc_httpdmgr_t)); return (result); } static void httpdmgr_destroy(isc_httpdmgr_t *httpdmgr) { isc_mem_t *mctx; isc_httpdurl_t *url; ENTER("httpdmgr_destroy"); LOCK(&httpdmgr->lock); if (!MSHUTTINGDOWN(httpdmgr)) { NOTICE("httpdmgr_destroy not shutting down yet"); UNLOCK(&httpdmgr->lock); return; } /* * If all clients are not shut down, don't do anything yet. */ if (!ISC_LIST_EMPTY(httpdmgr->running)) { NOTICE("httpdmgr_destroy clients still active"); UNLOCK(&httpdmgr->lock); return; } NOTICE("httpdmgr_destroy detaching socket, task, and timermgr"); isc_socket_detach(&httpdmgr->sock); isc_task_detach(&httpdmgr->task); httpdmgr->timermgr = NULL; /* * Clear out the list of all actions we know about. Just free the * memory. */ url = ISC_LIST_HEAD(httpdmgr->urls); while (url != NULL) { isc_mem_free(httpdmgr->mctx, url->url); ISC_LIST_UNLINK(httpdmgr->urls, url, link); isc_mem_put(httpdmgr->mctx, url, sizeof(isc_httpdurl_t)); url = ISC_LIST_HEAD(httpdmgr->urls); } UNLOCK(&httpdmgr->lock); (void)isc_mutex_destroy(&httpdmgr->lock); if (httpdmgr->ondestroy != NULL) (httpdmgr->ondestroy)(httpdmgr->cb_arg); mctx = httpdmgr->mctx; isc_mem_putanddetach(&mctx, httpdmgr, sizeof(isc_httpdmgr_t)); EXIT("httpdmgr_destroy"); } #define LENGTHOK(s) (httpd->recvbuf - (s) < (int)httpd->recvlen) #define BUFLENOK(s) (httpd->recvbuf - (s) < HTTP_RECVLEN) static isc_result_t process_request(isc_httpd_t *httpd, int length) { char *s; char *p; int delim; ENTER("request"); httpd->recvlen += length; httpd->recvbuf[httpd->recvlen] = 0; httpd->headers = NULL; /* * If we don't find a blank line in our buffer, return that we need * more data. */ s = strstr(httpd->recvbuf, "\r\n\r\n"); delim = 1; if (s == NULL) { s = strstr(httpd->recvbuf, "\n\n"); delim = 2; } if (s == NULL) return (ISC_R_NOTFOUND); /* * Determine if this is a POST or GET method. Any other values will * cause an error to be returned. */ if (strncmp(httpd->recvbuf, "GET ", 4) == 0) { httpd->method = ISC_HTTPD_METHODGET; p = httpd->recvbuf + 4; } else if (strncmp(httpd->recvbuf, "POST ", 5) == 0) { httpd->method = ISC_HTTPD_METHODPOST; p = httpd->recvbuf + 5; } else { return (ISC_R_RANGE); } /* * From now on, p is the start of our buffer. */ /* * Extract the URL. */ s = p; while (LENGTHOK(s) && BUFLENOK(s) && (*s != '\n' && *s != '\r' && *s != '\0' && *s != ' ')) s++; if (!LENGTHOK(s)) return (ISC_R_NOTFOUND); if (!BUFLENOK(s)) return (ISC_R_NOMEMORY); *s = 0; /* * Make the URL relative. */ if ((strncmp(p, "http:/", 6) == 0) || (strncmp(p, "https:/", 7) == 0)) { /* Skip first / */ while (*p != '/' && *p != 0) p++; if (*p == 0) return (ISC_R_RANGE); p++; /* Skip second / */ while (*p != '/' && *p != 0) p++; if (*p == 0) return (ISC_R_RANGE); p++; /* Find third / */ while (*p != '/' && *p != 0) p++; if (*p == 0) { p--; *p = '/'; } } httpd->url = p; p = s + delim; s = p; /* * Now, see if there is a ? mark in the URL. If so, this is * part of the query string, and we will split it from the URL. */ httpd->querystring = strchr(httpd->url, '?'); if (httpd->querystring != NULL) { *(httpd->querystring) = 0; httpd->querystring++; } /* * Extract the HTTP/1.X protocol. We will bounce on anything but * HTTP/1.1 for now. */ while (LENGTHOK(s) && BUFLENOK(s) && (*s != '\n' && *s != '\r' && *s != '\0')) s++; if (!LENGTHOK(s)) return (ISC_R_NOTFOUND); if (!BUFLENOK(s)) return (ISC_R_NOMEMORY); *s = 0; if ((strncmp(p, "HTTP/1.0", 8) != 0) && (strncmp(p, "HTTP/1.1", 8) != 0)) return (ISC_R_RANGE); httpd->protocol = p; p = s + 1; s = p; httpd->headers = s; if (strstr(s, "Connection: close") != NULL) httpd->flags |= HTTPD_CLOSE; if (strstr(s, "Host: ") != NULL) httpd->flags |= HTTPD_FOUNDHOST; if (strncmp(httpd->protocol, "HTTP/1.0", 8) == 0) { if (strcasestr(s, "Connection: Keep-Alive") != NULL) httpd->flags |= HTTPD_KEEPALIVE; else httpd->flags |= HTTPD_CLOSE; } /* * Standards compliance hooks here. */ if (strcmp(httpd->protocol, "HTTP/1.1") == 0 && ((httpd->flags & HTTPD_FOUNDHOST) == 0)) return (ISC_R_RANGE); EXIT("request"); return (ISC_R_SUCCESS); } static void isc_httpd_accept(isc_task_t *task, isc_event_t *ev) { isc_result_t result; isc_httpdmgr_t *httpdmgr = ev->ev_arg; isc_httpd_t *httpd; isc_region_t r; isc_socket_newconnev_t *nev = (isc_socket_newconnev_t *)ev; isc_sockaddr_t peeraddr; ENTER("accept"); LOCK(&httpdmgr->lock); if (MSHUTTINGDOWN(httpdmgr)) { NOTICE("accept shutting down, goto out"); goto out; } if (nev->result == ISC_R_CANCELED) { NOTICE("accept canceled, goto out"); goto out; } if (nev->result != ISC_R_SUCCESS) { /* XXXMLG log failure */ NOTICE("accept returned failure, goto requeue"); goto requeue; } (void)isc_socket_getpeername(nev->newsocket, &peeraddr); if (httpdmgr->client_ok != NULL && !(httpdmgr->client_ok)(&peeraddr, httpdmgr->cb_arg)) { isc_socket_detach(&nev->newsocket); goto requeue; } httpd = isc_mem_get(httpdmgr->mctx, sizeof(isc_httpd_t)); if (httpd == NULL) { /* XXXMLG log failure */ NOTICE("accept failed to allocate memory, goto requeue"); isc_socket_detach(&nev->newsocket); goto requeue; } httpd->mgr = httpdmgr; ISC_LINK_INIT(httpd, link); ISC_LIST_APPEND(httpdmgr->running, httpd, link); ISC_HTTPD_SETRECV(httpd); httpd->sock = nev->newsocket; isc_socket_setname(httpd->sock, "httpd", NULL); httpd->flags = 0; /* * Initialize the buffer for our headers. */ httpd->headerdata = isc_mem_get(httpdmgr->mctx, HTTP_SENDGROW); if (httpd->headerdata == NULL) { isc_mem_put(httpdmgr->mctx, httpd, sizeof(isc_httpd_t)); isc_socket_detach(&nev->newsocket); goto requeue; } httpd->headerlen = HTTP_SENDGROW; isc_buffer_init(&httpd->headerbuffer, httpd->headerdata, httpd->headerlen); ISC_LIST_INIT(httpd->bufflist); isc_buffer_initnull(&httpd->bodybuffer); reset_client(httpd); r.base = (unsigned char *)httpd->recvbuf; r.length = HTTP_RECVLEN - 1; result = isc_socket_recv(httpd->sock, &r, 1, task, isc_httpd_recvdone, httpd); /* FIXME!!! */ POST(result); NOTICE("accept queued recv on socket"); requeue: result = isc_socket_accept(httpdmgr->sock, task, isc_httpd_accept, httpdmgr); if (result != ISC_R_SUCCESS) { /* XXXMLG what to do? Log failure... */ NOTICE("accept could not reaccept due to failure"); } out: UNLOCK(&httpdmgr->lock); httpdmgr_destroy(httpdmgr); isc_event_free(&ev); EXIT("accept"); } static isc_result_t render_404(const char *url, isc_httpdurl_t *urlinfo, const char *querystring, const char *headers, void *arg, unsigned int *retcode, const char **retmsg, const char **mimetype, isc_buffer_t *b, isc_httpdfree_t **freecb, void **freecb_args) { static char msg[] = "No such URL.\r\n"; UNUSED(url); UNUSED(urlinfo); UNUSED(querystring); UNUSED(headers); UNUSED(arg); *retcode = 404; *retmsg = "No such URL"; *mimetype = "text/plain"; isc_buffer_reinit(b, msg, strlen(msg)); isc_buffer_add(b, strlen(msg)); *freecb = NULL; *freecb_args = NULL; return (ISC_R_SUCCESS); } static isc_result_t render_500(const char *url, isc_httpdurl_t *urlinfo, const char *querystring, const char *headers, void *arg, unsigned int *retcode, const char **retmsg, const char **mimetype, isc_buffer_t *b, isc_httpdfree_t **freecb, void **freecb_args) { static char msg[] = "Internal server failure.\r\n"; UNUSED(url); UNUSED(urlinfo); UNUSED(querystring); UNUSED(headers); UNUSED(arg); *retcode = 500; *retmsg = "Internal server failure"; *mimetype = "text/plain"; isc_buffer_reinit(b, msg, strlen(msg)); isc_buffer_add(b, strlen(msg)); *freecb = NULL; *freecb_args = NULL; return (ISC_R_SUCCESS); } static void isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) { isc_region_t r; isc_result_t result; isc_httpd_t *httpd = ev->ev_arg; isc_socketevent_t *sev = (isc_socketevent_t *)ev; isc_httpdurl_t *url; isc_time_t now; char datebuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; ENTER("recv"); INSIST(ISC_HTTPD_ISRECV(httpd)); if (sev->result != ISC_R_SUCCESS) { NOTICE("recv destroying client"); destroy_client(&httpd); goto out; } result = process_request(httpd, sev->n); if (result == ISC_R_NOTFOUND) { if (httpd->recvlen >= HTTP_RECVLEN - 1) { destroy_client(&httpd); goto out; } r.base = (unsigned char *)httpd->recvbuf + httpd->recvlen; r.length = HTTP_RECVLEN - httpd->recvlen - 1; /* check return code? */ (void)isc_socket_recv(httpd->sock, &r, 1, task, isc_httpd_recvdone, httpd); goto out; } else if (result != ISC_R_SUCCESS) { destroy_client(&httpd); goto out; } ISC_HTTPD_SETSEND(httpd); /* * XXXMLG Call function here. Provide an add-header function * which will append the common headers to a response we generate. */ isc_buffer_initnull(&httpd->bodybuffer); isc_time_now(&now); isc_time_formathttptimestamp(&now, datebuf, sizeof(datebuf)); url = ISC_LIST_HEAD(httpd->mgr->urls); while (url != NULL) { if (strcmp(httpd->url, url->url) == 0) break; url = ISC_LIST_NEXT(url, link); } if (url == NULL) result = httpd->mgr->render_404(httpd->url, NULL, httpd->querystring, NULL, NULL, &httpd->retcode, &httpd->retmsg, &httpd->mimetype, &httpd->bodybuffer, &httpd->freecb, &httpd->freecb_arg); else result = url->action(httpd->url, url, httpd->querystring, httpd->headers, url->action_arg, &httpd->retcode, &httpd->retmsg, &httpd->mimetype, &httpd->bodybuffer, &httpd->freecb, &httpd->freecb_arg); if (result != ISC_R_SUCCESS) { result = httpd->mgr->render_500(httpd->url, url, httpd->querystring, NULL, NULL, &httpd->retcode, &httpd->retmsg, &httpd->mimetype, &httpd->bodybuffer, &httpd->freecb, &httpd->freecb_arg); RUNTIME_CHECK(result == ISC_R_SUCCESS); } isc_httpd_response(httpd); if ((httpd->flags & HTTPD_KEEPALIVE) != 0) isc_httpd_addheader(httpd, "Connection", "Keep-Alive"); isc_httpd_addheader(httpd, "Content-Type", httpd->mimetype); isc_httpd_addheader(httpd, "Date", datebuf); isc_httpd_addheader(httpd, "Expires", datebuf); if (url != NULL && url->isstatic) { char loadbuf[ISC_FORMATHTTPTIMESTAMP_SIZE]; isc_time_formathttptimestamp(&url->loadtime, loadbuf, sizeof(loadbuf)); isc_httpd_addheader(httpd, "Last-Modified", loadbuf); isc_httpd_addheader(httpd, "Cache-Control: public", NULL); } else { isc_httpd_addheader(httpd, "Last-Modified", datebuf); isc_httpd_addheader(httpd, "Pragma: no-cache", NULL); isc_httpd_addheader(httpd, "Cache-Control: no-cache", NULL); } isc_httpd_addheader(httpd, "Server: libisc", NULL); isc_httpd_addheaderuint(httpd, "Content-Length", isc_buffer_usedlength(&httpd->bodybuffer)); isc_httpd_endheaders(httpd); /* done */ ISC_LIST_APPEND(httpd->bufflist, &httpd->headerbuffer, link); /* * Link the data buffer into our send queue, should we have any data * rendered into it. If no data is present, we won't do anything * with the buffer. */ if (isc_buffer_length(&httpd->bodybuffer) > 0) ISC_LIST_APPEND(httpd->bufflist, &httpd->bodybuffer, link); /* check return code? */ (void)isc_socket_sendv(httpd->sock, &httpd->bufflist, task, isc_httpd_senddone, httpd); out: isc_event_free(&ev); EXIT("recv"); } void isc_httpdmgr_shutdown(isc_httpdmgr_t **httpdmgrp) { isc_httpdmgr_t *httpdmgr; isc_httpd_t *httpd; httpdmgr = *httpdmgrp; *httpdmgrp = NULL; ENTER("isc_httpdmgr_shutdown"); LOCK(&httpdmgr->lock); MSETSHUTTINGDOWN(httpdmgr); isc_socket_cancel(httpdmgr->sock, httpdmgr->task, ISC_SOCKCANCEL_ALL); httpd = ISC_LIST_HEAD(httpdmgr->running); while (httpd != NULL) { isc_socket_cancel(httpd->sock, httpdmgr->task, ISC_SOCKCANCEL_ALL); httpd = ISC_LIST_NEXT(httpd, link); } UNLOCK(&httpdmgr->lock); EXIT("isc_httpdmgr_shutdown"); } static isc_result_t grow_headerspace(isc_httpd_t *httpd) { char *newspace; unsigned int newlen; isc_region_t r; newlen = httpd->headerlen + HTTP_SENDGROW; if (newlen > HTTP_SEND_MAXLEN) return (ISC_R_NOSPACE); newspace = isc_mem_get(httpd->mgr->mctx, newlen); if (newspace == NULL) return (ISC_R_NOMEMORY); isc_buffer_region(&httpd->headerbuffer, &r); isc_buffer_reinit(&httpd->headerbuffer, newspace, newlen); isc_mem_put(httpd->mgr->mctx, r.base, r.length); return (ISC_R_SUCCESS); } isc_result_t isc_httpd_response(isc_httpd_t *httpd) { isc_result_t result; unsigned int needlen; needlen = strlen(httpd->protocol) + 1; /* protocol + space */ needlen += 3 + 1; /* room for response code, always 3 bytes */ needlen += strlen(httpd->retmsg) + 2; /* return msg + CRLF */ while (isc_buffer_availablelength(&httpd->headerbuffer) < needlen) { result = grow_headerspace(httpd); if (result != ISC_R_SUCCESS) return (result); } sprintf(isc_buffer_used(&httpd->headerbuffer), "%s %03d %s\r\n", httpd->protocol, httpd->retcode, httpd->retmsg); isc_buffer_add(&httpd->headerbuffer, needlen); return (ISC_R_SUCCESS); } isc_result_t isc_httpd_addheader(isc_httpd_t *httpd, const char *name, const char *val) { isc_result_t result; unsigned int needlen; needlen = strlen(name); /* name itself */ if (val != NULL) needlen += 2 + strlen(val); /* : and val */ needlen += 2; /* CRLF */ while (isc_buffer_availablelength(&httpd->headerbuffer) < needlen) { result = grow_headerspace(httpd); if (result != ISC_R_SUCCESS) return (result); } if (val != NULL) sprintf(isc_buffer_used(&httpd->headerbuffer), "%s: %s\r\n", name, val); else sprintf(isc_buffer_used(&httpd->headerbuffer), "%s\r\n", name); isc_buffer_add(&httpd->headerbuffer, needlen); return (ISC_R_SUCCESS); } isc_result_t isc_httpd_endheaders(isc_httpd_t *httpd) { isc_result_t result; while (isc_buffer_availablelength(&httpd->headerbuffer) < 2) { result = grow_headerspace(httpd); if (result != ISC_R_SUCCESS) return (result); } sprintf(isc_buffer_used(&httpd->headerbuffer), "\r\n"); isc_buffer_add(&httpd->headerbuffer, 2); return (ISC_R_SUCCESS); } isc_result_t isc_httpd_addheaderuint(isc_httpd_t *httpd, const char *name, int val) { isc_result_t result; unsigned int needlen; char buf[sizeof "18446744073709551616"]; sprintf(buf, "%d", val); needlen = strlen(name); /* name itself */ needlen += 2 + strlen(buf); /* : and val */ needlen += 2; /* CRLF */ while (isc_buffer_availablelength(&httpd->headerbuffer) < needlen) { result = grow_headerspace(httpd); if (result != ISC_R_SUCCESS) return (result); } sprintf(isc_buffer_used(&httpd->headerbuffer), "%s: %s\r\n", name, buf); isc_buffer_add(&httpd->headerbuffer, needlen); return (ISC_R_SUCCESS); } static void isc_httpd_senddone(isc_task_t *task, isc_event_t *ev) { isc_httpd_t *httpd = ev->ev_arg; isc_region_t r; isc_socketevent_t *sev = (isc_socketevent_t *)ev; ENTER("senddone"); INSIST(ISC_HTTPD_ISSEND(httpd)); /* * First, unlink our header buffer from the socket's bufflist. This * is sort of an evil hack, since we know our buffer will be there, * and we know it's address, so we can just remove it directly. */ NOTICE("senddone unlinked header"); ISC_LIST_UNLINK(sev->bufferlist, &httpd->headerbuffer, link); /* * We will always want to clean up our receive buffer, even if we * got an error on send or we are shutting down. * * We will pass in the buffer only if there is data in it. If * there is no data, we will pass in a NULL. */ if (httpd->freecb != NULL) { isc_buffer_t *b = NULL; if (isc_buffer_length(&httpd->bodybuffer) > 0) { b = &httpd->bodybuffer; httpd->freecb(b, httpd->freecb_arg); } NOTICE("senddone free callback performed"); } if (ISC_LINK_LINKED(&httpd->bodybuffer, link)) { ISC_LIST_UNLINK(sev->bufferlist, &httpd->bodybuffer, link); NOTICE("senddone body buffer unlinked"); } if (sev->result != ISC_R_SUCCESS) { destroy_client(&httpd); goto out; } if ((httpd->flags & HTTPD_CLOSE) != 0) { destroy_client(&httpd); goto out; } ISC_HTTPD_SETRECV(httpd); NOTICE("senddone restarting recv on socket"); reset_client(httpd); r.base = (unsigned char *)httpd->recvbuf; r.length = HTTP_RECVLEN - 1; /* check return code? */ (void)isc_socket_recv(httpd->sock, &r, 1, task, isc_httpd_recvdone, httpd); out: isc_event_free(&ev); EXIT("senddone"); } static void reset_client(isc_httpd_t *httpd) { /* * Catch errors here. We MUST be in RECV mode, and we MUST NOT have * any outstanding buffers. If we have buffers, we have a leak. */ INSIST(ISC_HTTPD_ISRECV(httpd)); INSIST(!ISC_LINK_LINKED(&httpd->headerbuffer, link)); INSIST(!ISC_LINK_LINKED(&httpd->bodybuffer, link)); httpd->recvbuf[0] = 0; httpd->recvlen = 0; httpd->headers = NULL; httpd->method = ISC_HTTPD_METHODUNKNOWN; httpd->url = NULL; httpd->querystring = NULL; httpd->protocol = NULL; httpd->flags = 0; isc_buffer_clear(&httpd->headerbuffer); isc_buffer_invalidate(&httpd->bodybuffer); } isc_result_t isc_httpdmgr_addurl(isc_httpdmgr_t *httpdmgr, const char *url, isc_httpdaction_t *func, void *arg) { return (isc_httpdmgr_addurl2(httpdmgr, url, ISC_FALSE, func, arg)); } isc_result_t isc_httpdmgr_addurl2(isc_httpdmgr_t *httpdmgr, const char *url, isc_boolean_t isstatic, isc_httpdaction_t *func, void *arg) { isc_httpdurl_t *item; if (url == NULL) { httpdmgr->render_404 = func; return (ISC_R_SUCCESS); } item = isc_mem_get(httpdmgr->mctx, sizeof(isc_httpdurl_t)); if (item == NULL) return (ISC_R_NOMEMORY); item->url = isc_mem_strdup(httpdmgr->mctx, url); if (item->url == NULL) { isc_mem_put(httpdmgr->mctx, item, sizeof(isc_httpdurl_t)); return (ISC_R_NOMEMORY); } item->action = func; item->action_arg = arg; item->isstatic = isstatic; isc_time_now(&item->loadtime); ISC_LINK_INIT(item, link); ISC_LIST_APPEND(httpdmgr->urls, item, link); return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/isc/nothreads/0002755000470500017500000000000012672612753016716 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/nothreads/Makefile.in0000644000470500017500000000246712664710322020762 0ustar lamontlamont# Copyright (C) 2004, 2007, 2009, 2010, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000, 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.12 2010/06/09 23:50:58 tbox Exp $ top_srcdir = @top_srcdir@ srcdir = @srcdir@ VPATH = @srcdir@ CINCLUDES = -I${srcdir}/include \ -I${srcdir}/../unix/include \ -I../include \ -I${srcdir}/../include \ -I${srcdir}/.. CDEFINES = CWARNINGS = THREADOPTOBJS = condition.@O@ mutex.@O@ OBJS = @THREADOPTOBJS@ thread.@O@ THREADOPTSRCS = condition.c mutex.c SRCS = @THREADOPTSRCS@ thread.c SUBDIRS = include TARGETS = ${OBJS} @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/nothreads/thread.c0000644000470500017500000000203612664710322020320 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: thread.c,v 1.5 2007/06/19 23:47:18 tbox Exp $ */ #include #include #include void isc_thread_setconcurrency(unsigned int level) { UNUSED(level); } bind9-9.10.3.dfsg.P4/lib/isc/nothreads/condition.c0000644000470500017500000000174012664710322021040 0ustar lamontlamont/* * Copyright (C) 2004, 2006, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: condition.c,v 1.10 2007/06/19 23:47:18 tbox Exp $ */ #include #include EMPTY_TRANSLATION_UNIT bind9-9.10.3.dfsg.P4/lib/isc/nothreads/include/0002755000470500017500000000000012672612753020341 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/nothreads/include/Makefile.in0000644000470500017500000000175612664710322022405 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000, 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.5 2007/06/19 23:47:18 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = isc TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/nothreads/include/isc/0002755000470500017500000000000012664710322021107 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/nothreads/include/isc/once.h0000644000470500017500000000222012664710322022176 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: once.h,v 1.6 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_ONCE_H #define ISC_ONCE_H 1 #include typedef isc_boolean_t isc_once_t; #define ISC_ONCE_INIT ISC_FALSE #define isc_once_do(op, f) \ (!*(op) ? (f(), *(op) = ISC_TRUE, ISC_R_SUCCESS) : ISC_R_SUCCESS) #endif /* ISC_ONCE_H */ bind9-9.10.3.dfsg.P4/lib/isc/nothreads/include/isc/Makefile.in0000644000470500017500000000236212664710322023155 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000, 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.7 2007/06/19 23:47:18 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ HEADERS = condition.h mutex.h once.h thread.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \ done bind9-9.10.3.dfsg.P4/lib/isc/nothreads/include/isc/condition.h0000644000470500017500000000412612664710322023247 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: condition.h,v 1.6 2007/06/19 23:47:18 tbox Exp $ */ /* * This provides a limited subset of the isc_condition_t * functionality for use by single-threaded programs that * need to block waiting for events. Only a single * call to isc_condition_wait() may be blocked at any given * time, and the _waituntil and _broadcast functions are not * supported. This is intended primarily for use by the omapi * library, and may go away once omapi goes away. Use for * other purposes is strongly discouraged. */ #ifndef ISC_CONDITION_H #define ISC_CONDITION_H 1 #include typedef int isc_condition_t; isc_result_t isc__nothread_wait_hack(isc_condition_t *cp, isc_mutex_t *mp); isc_result_t isc__nothread_signal_hack(isc_condition_t *cp); #define isc_condition_init(cp) \ (*(cp) = 0, ISC_R_SUCCESS) #define isc_condition_wait(cp, mp) \ isc__nothread_wait_hack(cp, mp) #define isc_condition_waituntil(cp, mp, tp) \ ((void)(cp), (void)(mp), (void)(tp), ISC_R_NOTIMPLEMENTED) #define isc_condition_signal(cp) \ isc__nothread_signal_hack(cp) #define isc_condition_broadcast(cp) \ ((void)(cp), ISC_R_NOTIMPLEMENTED) #define isc_condition_destroy(cp) \ (*(cp) == 0 ? (*(cp) = -1, ISC_R_SUCCESS) : ISC_R_UNEXPECTED) #endif /* ISC_CONDITION_H */ bind9-9.10.3.dfsg.P4/lib/isc/nothreads/include/isc/mutex.h0000644000470500017500000000264512664710322022427 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef ISC_MUTEX_H #define ISC_MUTEX_H 1 #include /* for ISC_R_ codes */ typedef int isc_mutex_t; #define isc_mutex_init(mp) \ (*(mp) = 0, ISC_R_SUCCESS) #define isc_mutex_lock(mp) \ ((*(mp))++ == 0 ? ISC_R_SUCCESS : ISC_R_UNEXPECTED) #define isc_mutex_unlock(mp) \ (--(*(mp)) == 0 ? ISC_R_SUCCESS : ISC_R_UNEXPECTED) #define isc_mutex_trylock(mp) \ (*(mp) == 0 ? ((*(mp))++, ISC_R_SUCCESS) : ISC_R_LOCKBUSY) #define isc_mutex_destroy(mp) \ (*(mp) == 0 ? (*(mp) = -1, ISC_R_SUCCESS) : ISC_R_UNEXPECTED) #define isc_mutex_stats(fp) #endif /* ISC_MUTEX_H */ bind9-9.10.3.dfsg.P4/lib/isc/nothreads/include/isc/thread.h0000644000470500017500000000227712664710322022535 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: thread.h,v 1.6 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_THREAD_H #define ISC_THREAD_H 1 #include #include ISC_LANG_BEGINDECLS void isc_thread_setconcurrency(unsigned int level); #define isc_thread_self() ((unsigned long)0) #define isc_thread_yield() ((void)0) ISC_LANG_ENDDECLS #endif /* ISC_THREAD_H */ bind9-9.10.3.dfsg.P4/lib/isc/nothreads/mutex.c0000644000470500017500000000173512664710322020220 0ustar lamontlamont/* * Copyright (C) 2004, 2006, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: mutex.c,v 1.10 2007/06/19 23:47:18 tbox Exp $ */ #include #include EMPTY_TRANSLATION_UNIT bind9-9.10.3.dfsg.P4/lib/isc/crc64.c0000644000470500017500000001645412664710322016014 0ustar lamontlamont/* * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include "config.h" #include #include #include #include #include /*%< * ECMA-182 CRC64 polynomial. */ static const isc_uint64_t crc64_table[256] = { 0x0000000000000000ULL, 0x42F0E1EBA9EA3693ULL, 0x85E1C3D753D46D26ULL, 0xC711223CFA3E5BB5ULL, 0x493366450E42ECDFULL, 0x0BC387AEA7A8DA4CULL, 0xCCD2A5925D9681F9ULL, 0x8E224479F47CB76AULL, 0x9266CC8A1C85D9BEULL, 0xD0962D61B56FEF2DULL, 0x17870F5D4F51B498ULL, 0x5577EEB6E6BB820BULL, 0xDB55AACF12C73561ULL, 0x99A54B24BB2D03F2ULL, 0x5EB4691841135847ULL, 0x1C4488F3E8F96ED4ULL, 0x663D78FF90E185EFULL, 0x24CD9914390BB37CULL, 0xE3DCBB28C335E8C9ULL, 0xA12C5AC36ADFDE5AULL, 0x2F0E1EBA9EA36930ULL, 0x6DFEFF5137495FA3ULL, 0xAAEFDD6DCD770416ULL, 0xE81F3C86649D3285ULL, 0xF45BB4758C645C51ULL, 0xB6AB559E258E6AC2ULL, 0x71BA77A2DFB03177ULL, 0x334A9649765A07E4ULL, 0xBD68D2308226B08EULL, 0xFF9833DB2BCC861DULL, 0x388911E7D1F2DDA8ULL, 0x7A79F00C7818EB3BULL, 0xCC7AF1FF21C30BDEULL, 0x8E8A101488293D4DULL, 0x499B3228721766F8ULL, 0x0B6BD3C3DBFD506BULL, 0x854997BA2F81E701ULL, 0xC7B97651866BD192ULL, 0x00A8546D7C558A27ULL, 0x4258B586D5BFBCB4ULL, 0x5E1C3D753D46D260ULL, 0x1CECDC9E94ACE4F3ULL, 0xDBFDFEA26E92BF46ULL, 0x990D1F49C77889D5ULL, 0x172F5B3033043EBFULL, 0x55DFBADB9AEE082CULL, 0x92CE98E760D05399ULL, 0xD03E790CC93A650AULL, 0xAA478900B1228E31ULL, 0xE8B768EB18C8B8A2ULL, 0x2FA64AD7E2F6E317ULL, 0x6D56AB3C4B1CD584ULL, 0xE374EF45BF6062EEULL, 0xA1840EAE168A547DULL, 0x66952C92ECB40FC8ULL, 0x2465CD79455E395BULL, 0x3821458AADA7578FULL, 0x7AD1A461044D611CULL, 0xBDC0865DFE733AA9ULL, 0xFF3067B657990C3AULL, 0x711223CFA3E5BB50ULL, 0x33E2C2240A0F8DC3ULL, 0xF4F3E018F031D676ULL, 0xB60301F359DBE0E5ULL, 0xDA050215EA6C212FULL, 0x98F5E3FE438617BCULL, 0x5FE4C1C2B9B84C09ULL, 0x1D14202910527A9AULL, 0x93366450E42ECDF0ULL, 0xD1C685BB4DC4FB63ULL, 0x16D7A787B7FAA0D6ULL, 0x5427466C1E109645ULL, 0x4863CE9FF6E9F891ULL, 0x0A932F745F03CE02ULL, 0xCD820D48A53D95B7ULL, 0x8F72ECA30CD7A324ULL, 0x0150A8DAF8AB144EULL, 0x43A04931514122DDULL, 0x84B16B0DAB7F7968ULL, 0xC6418AE602954FFBULL, 0xBC387AEA7A8DA4C0ULL, 0xFEC89B01D3679253ULL, 0x39D9B93D2959C9E6ULL, 0x7B2958D680B3FF75ULL, 0xF50B1CAF74CF481FULL, 0xB7FBFD44DD257E8CULL, 0x70EADF78271B2539ULL, 0x321A3E938EF113AAULL, 0x2E5EB66066087D7EULL, 0x6CAE578BCFE24BEDULL, 0xABBF75B735DC1058ULL, 0xE94F945C9C3626CBULL, 0x676DD025684A91A1ULL, 0x259D31CEC1A0A732ULL, 0xE28C13F23B9EFC87ULL, 0xA07CF2199274CA14ULL, 0x167FF3EACBAF2AF1ULL, 0x548F120162451C62ULL, 0x939E303D987B47D7ULL, 0xD16ED1D631917144ULL, 0x5F4C95AFC5EDC62EULL, 0x1DBC74446C07F0BDULL, 0xDAAD56789639AB08ULL, 0x985DB7933FD39D9BULL, 0x84193F60D72AF34FULL, 0xC6E9DE8B7EC0C5DCULL, 0x01F8FCB784FE9E69ULL, 0x43081D5C2D14A8FAULL, 0xCD2A5925D9681F90ULL, 0x8FDAB8CE70822903ULL, 0x48CB9AF28ABC72B6ULL, 0x0A3B7B1923564425ULL, 0x70428B155B4EAF1EULL, 0x32B26AFEF2A4998DULL, 0xF5A348C2089AC238ULL, 0xB753A929A170F4ABULL, 0x3971ED50550C43C1ULL, 0x7B810CBBFCE67552ULL, 0xBC902E8706D82EE7ULL, 0xFE60CF6CAF321874ULL, 0xE224479F47CB76A0ULL, 0xA0D4A674EE214033ULL, 0x67C58448141F1B86ULL, 0x253565A3BDF52D15ULL, 0xAB1721DA49899A7FULL, 0xE9E7C031E063ACECULL, 0x2EF6E20D1A5DF759ULL, 0x6C0603E6B3B7C1CAULL, 0xF6FAE5C07D3274CDULL, 0xB40A042BD4D8425EULL, 0x731B26172EE619EBULL, 0x31EBC7FC870C2F78ULL, 0xBFC9838573709812ULL, 0xFD39626EDA9AAE81ULL, 0x3A28405220A4F534ULL, 0x78D8A1B9894EC3A7ULL, 0x649C294A61B7AD73ULL, 0x266CC8A1C85D9BE0ULL, 0xE17DEA9D3263C055ULL, 0xA38D0B769B89F6C6ULL, 0x2DAF4F0F6FF541ACULL, 0x6F5FAEE4C61F773FULL, 0xA84E8CD83C212C8AULL, 0xEABE6D3395CB1A19ULL, 0x90C79D3FEDD3F122ULL, 0xD2377CD44439C7B1ULL, 0x15265EE8BE079C04ULL, 0x57D6BF0317EDAA97ULL, 0xD9F4FB7AE3911DFDULL, 0x9B041A914A7B2B6EULL, 0x5C1538ADB04570DBULL, 0x1EE5D94619AF4648ULL, 0x02A151B5F156289CULL, 0x4051B05E58BC1E0FULL, 0x87409262A28245BAULL, 0xC5B073890B687329ULL, 0x4B9237F0FF14C443ULL, 0x0962D61B56FEF2D0ULL, 0xCE73F427ACC0A965ULL, 0x8C8315CC052A9FF6ULL, 0x3A80143F5CF17F13ULL, 0x7870F5D4F51B4980ULL, 0xBF61D7E80F251235ULL, 0xFD913603A6CF24A6ULL, 0x73B3727A52B393CCULL, 0x31439391FB59A55FULL, 0xF652B1AD0167FEEAULL, 0xB4A25046A88DC879ULL, 0xA8E6D8B54074A6ADULL, 0xEA16395EE99E903EULL, 0x2D071B6213A0CB8BULL, 0x6FF7FA89BA4AFD18ULL, 0xE1D5BEF04E364A72ULL, 0xA3255F1BE7DC7CE1ULL, 0x64347D271DE22754ULL, 0x26C49CCCB40811C7ULL, 0x5CBD6CC0CC10FAFCULL, 0x1E4D8D2B65FACC6FULL, 0xD95CAF179FC497DAULL, 0x9BAC4EFC362EA149ULL, 0x158E0A85C2521623ULL, 0x577EEB6E6BB820B0ULL, 0x906FC95291867B05ULL, 0xD29F28B9386C4D96ULL, 0xCEDBA04AD0952342ULL, 0x8C2B41A1797F15D1ULL, 0x4B3A639D83414E64ULL, 0x09CA82762AAB78F7ULL, 0x87E8C60FDED7CF9DULL, 0xC51827E4773DF90EULL, 0x020905D88D03A2BBULL, 0x40F9E43324E99428ULL, 0x2CFFE7D5975E55E2ULL, 0x6E0F063E3EB46371ULL, 0xA91E2402C48A38C4ULL, 0xEBEEC5E96D600E57ULL, 0x65CC8190991CB93DULL, 0x273C607B30F68FAEULL, 0xE02D4247CAC8D41BULL, 0xA2DDA3AC6322E288ULL, 0xBE992B5F8BDB8C5CULL, 0xFC69CAB42231BACFULL, 0x3B78E888D80FE17AULL, 0x7988096371E5D7E9ULL, 0xF7AA4D1A85996083ULL, 0xB55AACF12C735610ULL, 0x724B8ECDD64D0DA5ULL, 0x30BB6F267FA73B36ULL, 0x4AC29F2A07BFD00DULL, 0x08327EC1AE55E69EULL, 0xCF235CFD546BBD2BULL, 0x8DD3BD16FD818BB8ULL, 0x03F1F96F09FD3CD2ULL, 0x41011884A0170A41ULL, 0x86103AB85A2951F4ULL, 0xC4E0DB53F3C36767ULL, 0xD8A453A01B3A09B3ULL, 0x9A54B24BB2D03F20ULL, 0x5D45907748EE6495ULL, 0x1FB5719CE1045206ULL, 0x919735E51578E56CULL, 0xD367D40EBC92D3FFULL, 0x1476F63246AC884AULL, 0x568617D9EF46BED9ULL, 0xE085162AB69D5E3CULL, 0xA275F7C11F7768AFULL, 0x6564D5FDE549331AULL, 0x279434164CA30589ULL, 0xA9B6706FB8DFB2E3ULL, 0xEB46918411358470ULL, 0x2C57B3B8EB0BDFC5ULL, 0x6EA7525342E1E956ULL, 0x72E3DAA0AA188782ULL, 0x30133B4B03F2B111ULL, 0xF7021977F9CCEAA4ULL, 0xB5F2F89C5026DC37ULL, 0x3BD0BCE5A45A6B5DULL, 0x79205D0E0DB05DCEULL, 0xBE317F32F78E067BULL, 0xFCC19ED95E6430E8ULL, 0x86B86ED5267CDBD3ULL, 0xC4488F3E8F96ED40ULL, 0x0359AD0275A8B6F5ULL, 0x41A94CE9DC428066ULL, 0xCF8B0890283E370CULL, 0x8D7BE97B81D4019FULL, 0x4A6ACB477BEA5A2AULL, 0x089A2AACD2006CB9ULL, 0x14DEA25F3AF9026DULL, 0x562E43B4931334FEULL, 0x913F6188692D6F4BULL, 0xD3CF8063C0C759D8ULL, 0x5DEDC41A34BBEEB2ULL, 0x1F1D25F19D51D821ULL, 0xD80C07CD676F8394ULL, 0x9AFCE626CE85B507ULL }; void isc_crc64_init(isc_uint64_t *crc) { REQUIRE(crc != NULL); *crc = 0xffffffffffffffffULL; } void isc_crc64_update(isc_uint64_t *crc, const void *data, size_t len) { const unsigned char *p = data; int i; REQUIRE(crc != NULL); REQUIRE(data != NULL); while (len-- > 0U) { i = ((int) (*crc >> 56) ^ *p++) & 0xff; *crc = crc64_table[i] ^ (*crc << 8); } } void isc_crc64_final(isc_uint64_t *crc) { REQUIRE(crc != NULL); *crc ^= 0xffffffffffffffffULL; } bind9-9.10.3.dfsg.P4/lib/isc/string.c0000644000470500017500000001642512664710322016377 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2011, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (c) 1990, 1993 * The Regents of the University of California. 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. Neither the name of the University 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 REGENTS 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 */ #include #include #include #include #include #include #include static char digits[] = "0123456789abcdefghijklmnoprstuvwxyz"; isc_uint64_t isc_string_touint64(char *source, char **end, int base) { isc_uint64_t tmp; isc_uint64_t overflow; char *s = source; char *o; char c; if ((base < 0) || (base == 1) || (base > 36)) { *end = source; return (0); } while (*s != 0 && isascii(*s&0xff) && isspace(*s&0xff)) s++; if (*s == '+' /* || *s == '-' */) s++; if (base == 0) { if (*s == '0' && (*(s+1) == 'X' || *(s+1) == 'x')) { s += 2; base = 16; } else if (*s == '0') base = 8; else base = 10; } if (*s == 0) { *end = source; return (0); } overflow = ~0; overflow /= base; tmp = 0; while ((c = *s) != 0) { c = tolower(c&0xff); /* end ? */ if ((o = strchr(digits, c)) == NULL) { *end = s; return (tmp); } /* end ? */ if ((o - digits) >= base) { *end = s; return (tmp); } /* overflow ? */ if (tmp > overflow) { *end = source; return (0); } tmp *= base; /* overflow ? */ if ((tmp + (o - digits)) < tmp) { *end = source; return (0); } tmp += o - digits; s++; } *end = s; return (tmp); } isc_result_t isc_string_copy(char *target, size_t size, const char *source) { REQUIRE(size > 0U); if (strlcpy(target, source, size) >= size) { memset(target, ISC_STRING_MAGIC, size); return (ISC_R_NOSPACE); } ENSURE(strlen(target) < size); return (ISC_R_SUCCESS); } void isc_string_copy_truncate(char *target, size_t size, const char *source) { REQUIRE(size > 0U); strlcpy(target, source, size); ENSURE(strlen(target) < size); } isc_result_t isc_string_append(char *target, size_t size, const char *source) { REQUIRE(size > 0U); REQUIRE(strlen(target) < size); if (strlcat(target, source, size) >= size) { memset(target, ISC_STRING_MAGIC, size); return (ISC_R_NOSPACE); } ENSURE(strlen(target) < size); return (ISC_R_SUCCESS); } void isc_string_append_truncate(char *target, size_t size, const char *source) { REQUIRE(size > 0U); REQUIRE(strlen(target) < size); strlcat(target, source, size); ENSURE(strlen(target) < size); } isc_result_t isc_string_printf(char *target, size_t size, const char *format, ...) { va_list args; size_t n; REQUIRE(size > 0U); va_start(args, format); n = vsnprintf(target, size, format, args); va_end(args); if (n >= size) { memset(target, ISC_STRING_MAGIC, size); return (ISC_R_NOSPACE); } ENSURE(strlen(target) < size); return (ISC_R_SUCCESS); } void isc_string_printf_truncate(char *target, size_t size, const char *format, ...) { va_list args; REQUIRE(size > 0U); va_start(args, format); /* check return code? */ (void)vsnprintf(target, size, format, args); va_end(args); ENSURE(strlen(target) < size); } char * isc_string_regiondup(isc_mem_t *mctx, const isc_region_t *source) { char *target; REQUIRE(mctx != NULL); REQUIRE(source != NULL); target = (char *) isc_mem_allocate(mctx, source->length + 1); if (target != NULL) { memmove(source->base, target, source->length); target[source->length] = '\0'; } return (target); } char * isc_string_separate(char **stringp, const char *delim) { char *string = *stringp; char *s; const char *d; char sc, dc; if (string == NULL) return (NULL); for (s = string; (sc = *s) != '\0'; s++) for (d = delim; (dc = *d) != '\0'; d++) if (sc == dc) { *s++ = '\0'; *stringp = s; return (string); } *stringp = NULL; return (string); } size_t isc_string_strlcpy(char *dst, const char *src, size_t size) { char *d = dst; const char *s = src; size_t n = size; /* Copy as many bytes as will fit */ if (n != 0U && --n != 0U) { do { if ((*d++ = *s++) == 0) break; } while (--n != 0U); } /* Not enough room in dst, add NUL and traverse rest of src */ if (n == 0U) { if (size != 0U) *d = '\0'; /* NUL-terminate dst */ while (*s++) ; } return(s - src - 1); /* count does not include NUL */ } size_t isc_string_strlcat(char *dst, const char *src, size_t size) { char *d = dst; const char *s = src; size_t n = size; size_t dlen; /* Find the end of dst and adjust bytes left but don't go past end */ while (n-- != 0U && *d != '\0') d++; dlen = d - dst; n = size - dlen; if (n == 0U) return(dlen + strlen(s)); while (*s != '\0') { if (n != 1U) { *d++ = *s; n--; } s++; } *d = '\0'; return(dlen + (s - src)); /* count does not include NUL */ } char * isc_string_strcasestr(const char *str, const char *search) { char c, sc, *s; size_t len; if ((c = *search++) != 0) { c = tolower((unsigned char) c); len = strlen(search); do { do { if ((sc = *str++) == 0) return (NULL); } while ((char) tolower((unsigned char) sc) != c); } while (strncasecmp(str, search, len) != 0); str--; } DE_CONST(str, s); return (s); } bind9-9.10.3.dfsg.P4/lib/isc/pk11.c0000644000470500017500000010341612664710322015642 0ustar lamontlamont/* * Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Portions copyright (c) 2008 Nominet UK. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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. */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * This product includes software developed by the OpenSSL Project for * use in the OpenSSL Toolkit (http://www.openssl.org/). * * This project also referenced hw_pkcs11-0.9.7b.patch written by * Afchine Madjlessi. */ /* * ==================================================================== * Copyright (c) 2000-2001 The OpenSSL Project. 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. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * licensing@OpenSSL.org. * * 5. Products derived from this software may not be called "OpenSSL" * nor may "OpenSSL" appear in their names without prior written * permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED 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 OpenSSL PROJECT OR * ITS 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. * ==================================================================== * * This product includes cryptographic software written by Eric Young * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). * */ /* $Id$ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* was 32 octets, Petr Spacek suggested 1024, SoftHSMv2 uses 256... */ #ifndef PINLEN #define PINLEN 256 #endif #ifndef PK11_NO_LOGERR #define PK11_NO_LOGERR 1 #endif static isc_once_t once = ISC_ONCE_INIT; static isc_mem_t *pk11_mctx = NULL; static isc_int32_t allocsize = 0; static isc_boolean_t initialized = ISC_FALSE; typedef struct pk11_session pk11_session_t; typedef struct pk11_token pk11_token_t; typedef ISC_LIST(pk11_session_t) pk11_sessionlist_t; struct pk11_session { unsigned int magic; CK_SESSION_HANDLE session; ISC_LINK(pk11_session_t) link; pk11_token_t *token; }; struct pk11_token { unsigned int magic; unsigned int operations; ISC_LINK(pk11_token_t) link; CK_SLOT_ID slotid; pk11_sessionlist_t sessions; isc_boolean_t logged; char name[32]; char manuf[32]; char model[16]; char serial[16]; char pin[PINLEN + 1]; }; static ISC_LIST(pk11_token_t) tokens; static pk11_token_t *rand_token; static pk11_token_t *best_rsa_token; static pk11_token_t *best_dsa_token; static pk11_token_t *best_dh_token; static pk11_token_t *digest_token; static pk11_token_t *best_ec_token; static pk11_token_t *best_gost_token; static pk11_token_t *aes_token; static isc_result_t free_all_sessions(void); static isc_result_t free_session_list(pk11_sessionlist_t *slist); static isc_result_t setup_session(pk11_session_t *sp, pk11_token_t *token, isc_boolean_t rw); static void choose_slots(void); static isc_result_t token_login(pk11_session_t *sp); static char *percent_decode(char *x, size_t *len); static isc_boolean_t pk11strcmp(const char *x, size_t lenx, const char *y, size_t leny); static CK_ATTRIBUTE *push_attribute(pk11_object_t *obj, isc_mem_t *mctx, size_t len); static isc_mutex_t alloclock; static isc_mutex_t sessionlock; static pk11_sessionlist_t actives; static CK_C_INITIALIZE_ARGS pk11_init_args = { NULL_PTR, /* CreateMutex */ NULL_PTR, /* DestroyMutex */ NULL_PTR, /* LockMutex */ NULL_PTR, /* UnlockMutex */ CKF_OS_LOCKING_OK, /* flags */ NULL_PTR, /* pReserved */ }; #ifndef PK11_LIB_LOCATION #define PK11_LIB_LOCATION "unknown_provider" #endif #ifndef WIN32 static const char *lib_name = PK11_LIB_LOCATION; #else static const char *lib_name = PK11_LIB_LOCATION ".dll"; #endif void pk11_set_lib_name(const char *name) { lib_name = name; } const char * pk11_get_lib_name(void) { return (lib_name); } static void initialize(void) { char *pk11_provider; RUNTIME_CHECK(isc_mutex_init(&alloclock) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_mutex_init(&sessionlock) == ISC_R_SUCCESS); pk11_provider = getenv("PKCS11_PROVIDER"); if (pk11_provider != NULL) lib_name = pk11_provider; } void * pk11_mem_get(size_t size) { void *ptr; LOCK(&alloclock); if (pk11_mctx != NULL) ptr = isc_mem_get(pk11_mctx, size); else { ptr = malloc(size); if (ptr != NULL) allocsize += (int)size; } UNLOCK(&alloclock); if (ptr != NULL) memset(ptr, 0, size); return (ptr); } void pk11_mem_put(void *ptr, size_t size) { if (ptr != NULL) memset(ptr, 0, size); LOCK(&alloclock); if (pk11_mctx != NULL) isc_mem_put(pk11_mctx, ptr, size); else { if (ptr != NULL) allocsize -= (int)size; free(ptr); } UNLOCK(&alloclock); } isc_result_t pk11_initialize(isc_mem_t *mctx, const char *engine) { isc_result_t result; CK_RV rv; RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); LOCK(&alloclock); if ((mctx != NULL) && (pk11_mctx == NULL) && (allocsize == 0)) isc_mem_attach(mctx, &pk11_mctx); if (initialized) { UNLOCK(&alloclock); return (ISC_R_SUCCESS); } else { LOCK(&sessionlock); initialized = ISC_TRUE; UNLOCK(&alloclock); } ISC_LIST_INIT(tokens); ISC_LIST_INIT(actives); if (engine != NULL) lib_name = engine; /* Initialize the CRYPTOKI library */ rv = pkcs_C_Initialize((CK_VOID_PTR) &pk11_init_args); if (rv == 0xfe) { result = PK11_R_NOPROVIDER; goto unlock; } if (rv != CKR_OK) { result = PK11_R_INITFAILED; goto unlock; } choose_slots(); #ifdef PKCS11CRYPTO if (rand_token == NULL) { result = PK11_R_NORANDOMSERVICE; goto unlock; } if (digest_token == NULL) { result = PK11_R_NODIGESTSERVICE; goto unlock; } #if defined(ISC_PLATFORM_USESIT) && defined(AES_SIT) if (aes_token == NULL) { result = PK11_R_NOAESSERVICE; goto unlock; } #endif #endif /* PKCS11CRYPTO */ result = ISC_R_SUCCESS; unlock: UNLOCK(&sessionlock); return (result); } isc_result_t pk11_finalize(void) { pk11_token_t *token, *next; isc_result_t ret; ret = free_all_sessions(); (void) pkcs_C_Finalize(NULL_PTR); token = ISC_LIST_HEAD(tokens); while (token != NULL) { next = ISC_LIST_NEXT(token, link); ISC_LIST_UNLINK(tokens, token, link); if (token == rand_token) rand_token = NULL; if (token == best_rsa_token) best_rsa_token = NULL; if (token == best_dsa_token) best_dsa_token = NULL; if (token == best_dh_token) best_dh_token = NULL; if (token == digest_token) digest_token = NULL; if (token == best_ec_token) best_ec_token = NULL; if (token == best_gost_token) best_gost_token = NULL; if (token == aes_token) aes_token = NULL; pk11_mem_put(token, sizeof(*token)); token = next; } if (pk11_mctx != NULL) isc_mem_detach(&pk11_mctx); initialized = ISC_FALSE; return (ret); } isc_result_t pk11_rand_bytes(unsigned char *buf, int num) { isc_result_t ret; CK_RV rv; pk11_context_t ctx; ret = pk11_get_session(&ctx, OP_RAND, ISC_FALSE, ISC_FALSE, ISC_FALSE, NULL, 0); if ((ret != ISC_R_SUCCESS) && (ret != PK11_R_NODIGESTSERVICE) && (ret != PK11_R_NOAESSERVICE)) return (ret); RUNTIME_CHECK(ctx.session != CK_INVALID_HANDLE); rv = pkcs_C_GenerateRandom(ctx.session, (CK_BYTE_PTR) buf, (CK_ULONG) num); pk11_return_session(&ctx); if (rv == CKR_OK) return (ISC_R_SUCCESS); else return (DST_R_CRYPTOFAILURE); } #define SEEDSIZE 1024 static CK_BYTE seed[SEEDSIZE]; void pk11_rand_seed_fromfile(const char *randomfile) { pk11_context_t ctx; FILE *stream = NULL; size_t cc = 0; isc_result_t ret; ret = pk11_get_session(&ctx, OP_RAND, ISC_FALSE, ISC_FALSE, ISC_FALSE, NULL, 0); if ((ret != ISC_R_SUCCESS) && (ret != PK11_R_NODIGESTSERVICE) && (ret != PK11_R_NOAESSERVICE)) return; RUNTIME_CHECK(ctx.session != CK_INVALID_HANDLE); ret = isc_stdio_open(randomfile, "r", &stream); if (ret != ISC_R_SUCCESS) goto cleanup; ret = isc_stdio_read(seed, 1, SEEDSIZE, stream, &cc); if (ret!= ISC_R_SUCCESS) goto cleanup; ret = isc_stdio_close(stream); stream = NULL; if (ret!= ISC_R_SUCCESS) goto cleanup; (void) pkcs_C_SeedRandom(ctx.session, seed, (CK_ULONG) cc); cleanup: if (stream != NULL) (void) isc_stdio_close(stream); pk11_return_session(&ctx); } isc_result_t pk11_get_session(pk11_context_t *ctx, pk11_optype_t optype, isc_boolean_t need_services, isc_boolean_t rw, isc_boolean_t logon, const char *pin, CK_SLOT_ID slot) { pk11_token_t *token = NULL; pk11_sessionlist_t *freelist; pk11_session_t *sp; isc_result_t ret; #ifdef PKCS11CRYPTO isc_result_t service_ret = ISC_R_SUCCESS; #else UNUSED(need_services); #endif memset(ctx, 0, sizeof(pk11_context_t)); ctx->handle = NULL; ctx->session = CK_INVALID_HANDLE; ret = pk11_initialize(NULL, NULL); #ifdef PKCS11CRYPTO if (ret == PK11_R_NORANDOMSERVICE || ret == PK11_R_NODIGESTSERVICE || ret == PK11_R_NOAESSERVICE) { if (need_services) return (ret); service_ret = ret; } else #endif /* PKCS11CRYPTO */ if (ret != ISC_R_SUCCESS) return (ret); LOCK(&sessionlock); /* wait for initialization to finish */ UNLOCK(&sessionlock); switch(optype) { #ifdef PKCS11CRYPTO case OP_RAND: token = rand_token; break; case OP_DIGEST: token = digest_token; break; case OP_AES: token = aes_token; break; case OP_ANY: for (token = ISC_LIST_HEAD(tokens); token != NULL; token = ISC_LIST_NEXT(token, link)) if (token->slotid == slot) break; break; #endif default: for (token = ISC_LIST_HEAD(tokens); token != NULL; token = ISC_LIST_NEXT(token, link)) if (token->slotid == slot) break; #ifdef PKCS11CRYPTO if ((token == NULL) || ((token->operations & (1 << optype)) == 0)) return (ISC_R_NOTFOUND); #endif break; } if (token == NULL) return (ISC_R_NOTFOUND); /* Override the token's PIN */ if (logon && pin != NULL && *pin != '\0') { if (strlen(pin) > PINLEN) return ISC_R_RANGE; memset(token->pin, 0, PINLEN + 1); strncpy(token->pin, pin, PINLEN); } freelist = &token->sessions; LOCK(&sessionlock); sp = ISC_LIST_HEAD(*freelist); if (sp != NULL) { ISC_LIST_UNLINK(*freelist, sp, link); ISC_LIST_APPEND(actives, sp, link); UNLOCK(&sessionlock); if (logon) ret = token_login(sp); ctx->handle = sp; ctx->session = sp->session; return (ret); } UNLOCK(&sessionlock); sp = pk11_mem_get(sizeof(*sp)); if (sp == NULL) return (ISC_R_NOMEMORY); sp->magic = SES_MAGIC; sp->token = token; sp->session = CK_INVALID_HANDLE; ISC_LINK_INIT(sp, link); ret = setup_session(sp, token, rw); if ((ret == ISC_R_SUCCESS) && logon) ret = token_login(sp); LOCK(&sessionlock); ISC_LIST_APPEND(actives, sp, link); UNLOCK(&sessionlock); ctx->handle = sp; ctx->session = sp->session; #ifdef PKCS11CRYPTO if (ret == ISC_R_SUCCESS) ret = service_ret; #endif return (ret); } void pk11_return_session(pk11_context_t *ctx) { pk11_session_t *sp = (pk11_session_t *) ctx->handle; if (sp == NULL) return; ctx->handle = NULL; ctx->session = CK_INVALID_HANDLE; LOCK(&sessionlock); ISC_LIST_UNLINK(actives, sp, link); UNLOCK(&sessionlock); if (sp->session == CK_INVALID_HANDLE) { pk11_mem_put(sp, sizeof(*sp)); return; } LOCK(&sessionlock); ISC_LIST_APPEND(sp->token->sessions, sp, link); UNLOCK(&sessionlock); } static isc_result_t free_all_sessions(void) { pk11_token_t *token; isc_result_t ret = ISC_R_SUCCESS; isc_result_t oret; for (token = ISC_LIST_HEAD(tokens); token != NULL; token = ISC_LIST_NEXT(token, link)) { oret = free_session_list(&token->sessions); if (oret != ISC_R_SUCCESS) ret = oret; } if (!ISC_LIST_EMPTY(actives)) { ret = ISC_R_ADDRINUSE; oret = free_session_list(&actives); if (oret != ISC_R_SUCCESS) ret = oret; } return (ret); } static isc_result_t free_session_list(pk11_sessionlist_t *slist) { pk11_session_t *sp; CK_RV rv; isc_result_t ret; ret = ISC_R_SUCCESS; LOCK(&sessionlock); while (!ISC_LIST_EMPTY(*slist)) { sp = ISC_LIST_HEAD(*slist); UNLOCK(&sessionlock); if (sp->session != CK_INVALID_HANDLE) { rv = pkcs_C_CloseSession(sp->session); if (rv != CKR_OK) ret = DST_R_CRYPTOFAILURE; } LOCK(&sessionlock); ISC_LIST_UNLINK(*slist, sp, link); pk11_mem_put(sp, sizeof(*sp)); } UNLOCK(&sessionlock); return (ret); } static isc_result_t setup_session(pk11_session_t *sp, pk11_token_t *token, isc_boolean_t rw) { CK_RV rv; CK_FLAGS flags = CKF_SERIAL_SESSION; if (rw) flags += CKF_RW_SESSION; rv = pkcs_C_OpenSession(token->slotid, flags, NULL_PTR, NULL_PTR, &sp->session); if (rv != CKR_OK) return (DST_R_CRYPTOFAILURE); return (ISC_R_SUCCESS); } static isc_result_t token_login(pk11_session_t *sp) { CK_RV rv; pk11_token_t *token = sp->token; isc_result_t ret = ISC_R_SUCCESS; LOCK(&sessionlock); if (!token->logged) { rv = pkcs_C_Login(sp->session, CKU_USER, (CK_UTF8CHAR_PTR) token->pin, (CK_ULONG) strlen(token->pin)); if (rv != CKR_OK) { ret = ISC_R_NOPERM; #if PK11_NO_LOGERR pk11_error_fatalcheck(__FILE__, __LINE__, "pkcs_C_Login", rv); #endif } else token->logged = ISC_TRUE; } UNLOCK(&sessionlock); return (ret); } static void choose_slots(void) { CK_MECHANISM_INFO mechInfo; CK_TOKEN_INFO tokenInfo; CK_RV rv; CK_SLOT_ID slot; CK_SLOT_ID_PTR slotList; CK_ULONG slotCount; pk11_token_t *token; unsigned int i; slotCount = 0; PK11_FATALCHECK(pkcs_C_GetSlotList, (CK_FALSE, NULL_PTR, &slotCount)); /* it's not an error if we didn't find any providers */ if (slotCount == 0) return; slotList = pk11_mem_get(sizeof(CK_SLOT_ID_PTR) * slotCount); RUNTIME_CHECK(slotList != NULL); PK11_FATALCHECK(pkcs_C_GetSlotList, (CK_FALSE, slotList, &slotCount)); for (i = 0; i < slotCount; i++) { slot = slotList[i]; rv = pkcs_C_GetTokenInfo(slot, &tokenInfo); if (rv != CKR_OK) continue; token = pk11_mem_get(sizeof(*token)); RUNTIME_CHECK(token != NULL); token->magic = TOK_MAGIC; token->slotid = slot; ISC_LINK_INIT(token, link); ISC_LIST_INIT(token->sessions); memmove(token->name, tokenInfo.label, 32); memmove(token->manuf, tokenInfo.manufacturerID, 32); memmove(token->model, tokenInfo.model, 16); memmove(token->serial, tokenInfo.serialNumber, 16); ISC_LIST_APPEND(tokens, token, link); if ((tokenInfo.flags & CKF_RNG) == 0) goto try_rsa; token->operations |= 1 << OP_RAND; if (rand_token == NULL) rand_token = token; try_rsa: rv = pkcs_C_GetMechanismInfo(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_GENERATE_KEY_PAIR) == 0)) goto try_dsa; rv = pkcs_C_GetMechanismInfo(slot, CKM_MD5_RSA_PKCS, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0) || ((mechInfo.flags & CKF_VERIFY) == 0)) goto try_dsa; rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA1_RSA_PKCS, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0) || ((mechInfo.flags & CKF_VERIFY) == 0)) goto try_dsa; rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA256_RSA_PKCS, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0) || ((mechInfo.flags & CKF_VERIFY) == 0)) goto try_dsa; rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA512_RSA_PKCS, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0) || ((mechInfo.flags & CKF_VERIFY) == 0)) goto try_dsa; token->operations |= 1 << OP_RSA; if (best_rsa_token == NULL) best_rsa_token = token; try_dsa: rv = pkcs_C_GetMechanismInfo(slot, CKM_DSA_PARAMETER_GEN, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_GENERATE) == 0)) goto try_dh; rv = pkcs_C_GetMechanismInfo(slot, CKM_DSA_KEY_PAIR_GEN, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_GENERATE_KEY_PAIR) == 0)) goto try_dh; rv = pkcs_C_GetMechanismInfo(slot, CKM_DSA_SHA1, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0) || ((mechInfo.flags & CKF_VERIFY) == 0)) goto try_dh; token->operations |= 1 << OP_DSA; if (best_dsa_token == NULL) best_dsa_token = token; try_dh: #ifdef notdef rv = pkcs_C_GetMechanismInfo(slot, CKM_DH_PKCS_PARAMETER_GEN, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_GENERATE) == 0)) goto try_digest; #endif rv = pkcs_C_GetMechanismInfo(slot, CKM_DH_PKCS_KEY_PAIR_GEN, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_GENERATE_KEY_PAIR) == 0)) goto try_digest; rv = pkcs_C_GetMechanismInfo(slot, CKM_DH_PKCS_DERIVE, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DERIVE) == 0)) goto try_digest; token->operations |= 1 << OP_DH; if (best_dh_token == NULL) best_dh_token = token; try_digest: rv = pkcs_C_GetMechanismInfo(slot, CKM_MD5, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) continue; rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA_1, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) continue; rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA224, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) continue; rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA256, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) continue; rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA384, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) continue; rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA512, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) continue; #ifdef PKCS11CRYPTOWITHHMAC rv = pkcs_C_GetMechanismInfo(slot, CKM_MD5_HMAC, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) continue; #endif rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA_1_HMAC, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) continue; rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA224_HMAC, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) continue; rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA256_HMAC, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) continue; rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA384_HMAC, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) continue; rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA512_HMAC, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) continue; token->operations |= 1 << OP_DIGEST; if (digest_token == NULL) digest_token = token; /* ECDSA requires digest */ rv = pkcs_C_GetMechanismInfo(slot, CKM_EC_KEY_PAIR_GEN, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_GENERATE_KEY_PAIR) == 0)) goto try_gost; rv = pkcs_C_GetMechanismInfo(slot, CKM_ECDSA, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0) || ((mechInfo.flags & CKF_VERIFY) == 0)) goto try_gost; token->operations |= 1 << OP_EC; if (best_ec_token == NULL) best_ec_token = token; try_gost: /* does GOST require digest too? */ rv = pkcs_C_GetMechanismInfo(slot, CKM_GOSTR3411, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) goto try_aes; rv = pkcs_C_GetMechanismInfo(slot, CKM_GOSTR3410_KEY_PAIR_GEN, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_GENERATE_KEY_PAIR) == 0)) goto try_aes; rv = pkcs_C_GetMechanismInfo(slot, CKM_GOSTR3410_WITH_GOSTR3411, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0) || ((mechInfo.flags & CKF_VERIFY) == 0)) goto try_aes; token->operations |= 1 << OP_GOST; if (best_gost_token == NULL) best_gost_token = token; try_aes: rv = pkcs_C_GetMechanismInfo(slot, CKM_AES_ECB, &mechInfo); if ((rv != CKR_OK) || ((mechInfo.flags & CKF_ENCRYPT) == 0)) continue; token->operations |= 1 << OP_AES; if (aes_token == NULL) aes_token = token; } if (slotList != NULL) pk11_mem_put(slotList, sizeof(CK_SLOT_ID_PTR) * slotCount); } CK_SLOT_ID pk11_get_best_token(pk11_optype_t optype) { pk11_token_t *token = NULL; switch (optype) { case OP_RAND: token = rand_token; break; case OP_RSA: token = best_rsa_token; break; case OP_DSA: token = best_dsa_token; break; case OP_DH: token = best_dh_token; break; case OP_DIGEST: token = digest_token; break; case OP_EC: token = best_ec_token; break; case OP_GOST: token = best_gost_token; break; case OP_AES: token = aes_token; break; default: break; } if (token == NULL) return (0); return (token->slotid); } unsigned int pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt) { unsigned int bitcnt, i; CK_BYTE top; if (bytecnt == 0) return (0); bitcnt = bytecnt * 8; for (i = 0; i < bytecnt; i++) { top = data[i]; if (top == 0) { bitcnt -= 8; continue; } if (top & 0x80) return (bitcnt); if (top & 0x40) return (bitcnt - 1); if (top & 0x20) return (bitcnt - 2); if (top & 0x10) return (bitcnt - 3); if (top & 0x08) return (bitcnt - 4); if (top & 0x04) return (bitcnt - 5); if (top & 0x02) return (bitcnt - 6); if (top & 0x01) return (bitcnt - 7); break; } INSIST(0); } CK_ATTRIBUTE * pk11_attribute_first(const pk11_object_t *obj) { return (obj->repr); } CK_ATTRIBUTE * pk11_attribute_next(const pk11_object_t *obj, CK_ATTRIBUTE *attr) { CK_ATTRIBUTE *next; next = attr + 1; if ((next - obj->repr) >= obj->attrcnt) return (NULL); return (next); } CK_ATTRIBUTE * pk11_attribute_bytype(const pk11_object_t *obj, CK_ATTRIBUTE_TYPE type) { CK_ATTRIBUTE *attr; for(attr = pk11_attribute_first(obj); attr != NULL; attr = pk11_attribute_next(obj, attr)) if (attr->type == type) return (attr); return (NULL); } static char * percent_decode(char *x, size_t *len) { char *p, *c; unsigned char v; INSIST(len != NULL); for (p = c = x; p[0] != '\0'; p++, c++) { switch (p[0]) { case '%': v = 0; switch (p[1]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': v = (p[1] - '0') << 4; break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': v = (p[1] - 'A' + 10) << 4; break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': v = (p[1] - 'a' + 10) << 4; break; default: return (NULL); } switch (p[2]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': v |= (p[2] - '0') & 0x0f; break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': v = (p[2] - 'A' + 10) & 0x0f; break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': v = (p[2] - 'a' + 10) & 0x0f; break; default: return (NULL); } p += 2; *c = (char) v; (*len)++; break; default: *c = *p; (*len)++; } } return (x); } static isc_boolean_t pk11strcmp(const char *x, size_t lenx, const char *y, size_t leny) { char buf[32]; INSIST((leny == 32) || (leny == 16)); memset(buf, ' ', 32); if (lenx > leny) lenx = leny; memmove(buf, x, lenx); return (ISC_TF(memcmp(buf, y, leny) == 0)); } static CK_ATTRIBUTE * push_attribute(pk11_object_t *obj, isc_mem_t *mctx, size_t len) { CK_ATTRIBUTE *old = obj->repr; CK_ATTRIBUTE *attr; CK_BYTE cnt = obj->attrcnt; obj->repr = isc_mem_get(mctx, (cnt + 1) * sizeof(*attr)); if (obj->repr == NULL) { obj->repr = old; return (NULL); } memset(obj->repr, 0, (cnt + 1) * sizeof(*attr)); memmove(obj->repr, old, cnt * sizeof(*attr)); attr = obj->repr + cnt; attr->ulValueLen = (CK_ULONG) len; attr->pValue = isc_mem_get(mctx, len); if (attr->pValue == NULL) { memset(obj->repr, 0, (cnt + 1) * sizeof(*attr)); isc_mem_put(mctx, obj->repr, (cnt + 1) * sizeof(*attr)); obj->repr = old; return (NULL); } memset(attr->pValue, 0, len); if (old != NULL) { memset(old, 0, cnt * sizeof(*attr)); isc_mem_put(mctx, old, cnt * sizeof(*attr)); } obj->attrcnt++; return (attr); } #define DST_RET(a) { ret = a; goto err; } isc_result_t pk11_parse_uri(pk11_object_t *obj, const char *label, isc_mem_t *mctx, pk11_optype_t optype) { CK_ATTRIBUTE *attr; pk11_token_t *token = NULL; char *uri, *p, *a, *na, *v; size_t len, l; FILE *stream = NULL; char pin[PINLEN + 1]; isc_boolean_t gotpin = ISC_FALSE; isc_result_t ret; /* get values to work on */ len = strlen(label) + 1; uri = isc_mem_get(mctx, len); if (uri == NULL) return (ISC_R_NOMEMORY); memmove(uri, label, len); /* get the URI scheme */ p = strchr(uri, ':'); if (p == NULL) DST_RET(PK11_R_NOPROVIDER); *p++ = '\0'; if (strcmp(uri, "pkcs11") != 0) DST_RET(PK11_R_NOPROVIDER); /* get attributes */ for (na = p; na != NULL;) { a = na; p = strchr(a, ';'); if (p == NULL) { /* last attribute */ na = NULL; } else { *p++ = '\0'; na = p; } p = strchr(a, '='); if (p != NULL) { *p++ = '\0'; v = p; } else v = a; l = 0; v = percent_decode(v, &l); if (v == NULL) DST_RET(PK11_R_NOPROVIDER); if ((a == v) || (strcmp(a, "object") == 0)) { /* object: CKA_LABEL */ attr = pk11_attribute_bytype(obj, CKA_LABEL); if (attr != NULL) DST_RET(PK11_R_NOPROVIDER); attr = push_attribute(obj, mctx, l); if (attr == NULL) DST_RET(ISC_R_NOMEMORY); attr->type = CKA_LABEL; memmove(attr->pValue, v, l); } else if (strcmp(a, "token") == 0) { /* token: CK_TOKEN_INFO label */ if (token == NULL) for (token = ISC_LIST_HEAD(tokens); token != NULL; token = ISC_LIST_NEXT(token, link)) if (pk11strcmp(v, l, token->name, 32)) break; } else if (strcmp(a, "manufacturer") == 0) { /* manufacturer: CK_TOKEN_INFO manufacturerID */ if (token == NULL) for (token = ISC_LIST_HEAD(tokens); token != NULL; token = ISC_LIST_NEXT(token, link)) if (pk11strcmp(v, l, token->manuf, 32)) break; } else if (strcmp(a, "serial") == 0) { /* serial: CK_TOKEN_INFO serialNumber */ if (token == NULL) for (token = ISC_LIST_HEAD(tokens); token != NULL; token = ISC_LIST_NEXT(token, link)) if (pk11strcmp(v, l, token->serial, 16)) break; } else if (strcmp(a, "model") == 0) { /* model: CK_TOKEN_INFO model */ if (token == NULL) for (token = ISC_LIST_HEAD(tokens); token != NULL; token = ISC_LIST_NEXT(token, link)) if (pk11strcmp(v, l, token->model, 16)) break; } else if (strcmp(a, "library-manufacturer") == 0) { /* ignored */ } else if (strcmp(a, "library-description") == 0) { /* ignored */ } else if (strcmp(a, "library-version") == 0) { /* ignored */ } else if (strcmp(a, "object-type") == 0) { /* object-type: CKA_CLASS */ /* only private makes sense */ if (strcmp(v, "private") != 0) DST_RET(PK11_R_NOPROVIDER); } else if (strcmp(a, "id") == 0) { /* id: CKA_ID */ attr = pk11_attribute_bytype(obj, CKA_ID); if (attr != NULL) DST_RET(PK11_R_NOPROVIDER); attr = push_attribute(obj, mctx, l); if (attr == NULL) DST_RET(ISC_R_NOMEMORY); attr->type = CKA_ID; memmove(attr->pValue, v, l); } else if (strcmp(a, "pin-source") == 0) { /* pin-source: PIN */ ret = isc_stdio_open(v, "r", &stream); if (ret != ISC_R_SUCCESS) goto err; memset(pin, 0, PINLEN + 1); ret = isc_stdio_read(pin, 1, PINLEN + 1, stream, &l); if ((ret != ISC_R_SUCCESS) && (ret != ISC_R_EOF)) goto err; if (l > PINLEN) DST_RET(ISC_R_RANGE); ret = isc_stdio_close(stream); stream = NULL; if (ret != ISC_R_SUCCESS) goto err; gotpin = ISC_TRUE; } else DST_RET(PK11_R_NOPROVIDER); } if ((pk11_attribute_bytype(obj, CKA_LABEL) == NULL) && (pk11_attribute_bytype(obj, CKA_ID) == NULL)) DST_RET(ISC_R_NOTFOUND); if (token == NULL) { if (optype == OP_RSA) token = best_rsa_token; else if (optype == OP_DSA) token = best_dsa_token; else if (optype == OP_DH) token = best_dh_token; else if (optype == OP_EC) token = best_ec_token; } if (token == NULL) DST_RET(ISC_R_NOTFOUND); obj->slot = token->slotid; if (gotpin) { memmove(token->pin, pin, PINLEN + 1); obj->reqlogon = ISC_TRUE; } ret = ISC_R_SUCCESS; err: if (stream != NULL) (void) isc_stdio_close(stream); isc_mem_put(mctx, uri, len); return (ret); } void pk11_error_fatalcheck(const char *file, int line, const char *funcname, CK_RV rv) { isc_error_fatal(file, line, "%s: Error = 0x%.8lX\n", funcname, rv); } void pk11_dump_tokens(void) { pk11_token_t *token; isc_boolean_t first; printf("DEFAULTS\n"); printf("\trand_token=%p\n", rand_token); printf("\tbest_rsa_token=%p\n", best_rsa_token); printf("\tbest_dsa_token=%p\n", best_dsa_token); printf("\tbest_dh_token=%p\n", best_dh_token); printf("\tdigest_token=%p\n", digest_token); printf("\tbest_ec_token=%p\n", best_ec_token); printf("\tbest_gost_token=%p\n", best_gost_token); printf("\taes_token=%p\n", aes_token); for (token = ISC_LIST_HEAD(tokens); token != NULL; token = ISC_LIST_NEXT(token, link)) { printf("\nTOKEN\n"); printf("\taddress=%p\n", token); printf("\tslotID=%lu\n", token->slotid); printf("\tlabel=%.32s\n", token->name); printf("\tmanufacturerID=%.32s\n", token->manuf); printf("\tmodel=%.16s\n", token->model); printf("\tserialNumber=%.16s\n", token->serial); printf("\tsupported operations=0x%x (", token->operations); first = ISC_TRUE; if (token->operations & (1 << OP_RAND)) { if (!first) printf(","); first = ISC_FALSE; printf("RAND"); } if (token->operations & (1 << OP_RSA)) { if (!first) printf(","); first = ISC_FALSE; printf("RSA"); } if (token->operations & (1 << OP_DSA)) { if (!first) printf(","); first = ISC_FALSE; printf("DSA"); } if (token->operations & (1 << OP_DH)) { if (!first) printf(","); first = ISC_FALSE; printf("DH"); } if (token->operations & (1 << OP_DIGEST)) { if (!first) printf(","); first = ISC_FALSE; printf("DIGEST"); } if (token->operations & (1 << OP_EC)) { if (!first) printf(","); first = ISC_FALSE; printf("EC"); } printf(")\n"); } } bind9-9.10.3.dfsg.P4/lib/isc/tm.c0000644000470500017500000002511312664710322015503 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*- * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. * All rights reserved. * * This code was contributed to The NetBSD Foundation by Klaus Klein. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. */ #include #include #include #include #include #include #include #include /* * Portable conversion routines for struct tm, replacing * timegm() and strptime(), which are not available on all * platforms and don't always behave the same way when they * are. */ /* * We do not implement alternate representations. However, we always * check whether a given modifier is allowed for a certain conversion. */ #define ALT_E 0x01 #define ALT_O 0x02 #define LEGAL_ALT(x) { if (alt_format & ~(x)) return (0); } #ifndef TM_YEAR_BASE #define TM_YEAR_BASE 1900 #endif static const char *day[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; static const char *abday[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; static const char *mon[12] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; static const char *abmon[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; static const char *am_pm[2] = { "AM", "PM" }; static int conv_num(const char **buf, int *dest, int llim, int ulim) { int result = 0; /* The limit also determines the number of valid digits. */ int rulim = ulim; if (**buf < '0' || **buf > '9') return (0); do { result *= 10; result += *(*buf)++ - '0'; rulim /= 10; } while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9'); if (result < llim || result > ulim) return (0); *dest = result; return (1); } time_t isc_tm_timegm(struct tm *tm) { time_t ret; int i, yday = 0, leapday; int mdays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 }; leapday = ((((tm->tm_year + 1900 ) % 4) == 0 && ((tm->tm_year + 1900 ) % 100) != 0) || ((tm->tm_year + 1900 ) % 400) == 0) ? 1 : 0; mdays[1] += leapday; yday = tm->tm_mday - 1; for (i = 1; i <= tm->tm_mon; i++) yday += mdays[i - 1]; ret = tm->tm_sec + (60 * tm->tm_min) + (3600 * tm->tm_hour) + (86400 * (yday + ((tm->tm_year - 70) * 365) + ((tm->tm_year - 69) / 4) - ((tm->tm_year - 1) / 100) + ((tm->tm_year + 299) / 400))); return (ret); } char * isc_tm_strptime(const char *buf, const char *fmt, struct tm *tm) { char c, *ret; const char *bp; size_t len = 0; int alt_format, i, split_year = 0; REQUIRE(buf != NULL); REQUIRE(fmt != NULL); REQUIRE(tm != NULL); memset(tm, 0, sizeof(struct tm)); bp = buf; while ((c = *fmt) != '\0') { /* Clear `alternate' modifier prior to new conversion. */ alt_format = 0; /* Eat up white-space. */ if (isspace((unsigned char) c)) { while (isspace((unsigned char) *bp)) bp++; fmt++; continue; } if ((c = *fmt++) != '%') goto literal; again: switch (c = *fmt++) { case '%': /* "%%" is converted to "%". */ literal: if (c != *bp++) return (0); break; /* * "Alternative" modifiers. Just set the appropriate flag * and start over again. */ case 'E': /* "%E?" alternative conversion modifier. */ LEGAL_ALT(0); alt_format |= ALT_E; goto again; case 'O': /* "%O?" alternative conversion modifier. */ LEGAL_ALT(0); alt_format |= ALT_O; goto again; /* * "Complex" conversion rules, implemented through recursion. */ case 'c': /* Date and time, using the locale's format. */ LEGAL_ALT(ALT_E); if (!(bp = isc_tm_strptime(bp, "%x %X", tm))) return (0); break; case 'D': /* The date as "%m/%d/%y". */ LEGAL_ALT(0); if (!(bp = isc_tm_strptime(bp, "%m/%d/%y", tm))) return (0); break; case 'R': /* The time as "%H:%M". */ LEGAL_ALT(0); if (!(bp = isc_tm_strptime(bp, "%H:%M", tm))) return (0); break; case 'r': /* The time in 12-hour clock representation. */ LEGAL_ALT(0); if (!(bp = isc_tm_strptime(bp, "%I:%M:%S %p", tm))) return (0); break; case 'T': /* The time as "%H:%M:%S". */ LEGAL_ALT(0); if (!(bp = isc_tm_strptime(bp, "%H:%M:%S", tm))) return (0); break; case 'X': /* The time, using the locale's format. */ LEGAL_ALT(ALT_E); if (!(bp = isc_tm_strptime(bp, "%H:%M:%S", tm))) return (0); break; case 'x': /* The date, using the locale's format. */ LEGAL_ALT(ALT_E); if (!(bp = isc_tm_strptime(bp, "%m/%d/%y", tm))) return (0); break; /* * "Elementary" conversion rules. */ case 'A': /* The day of week, using the locale's form. */ case 'a': LEGAL_ALT(0); for (i = 0; i < 7; i++) { /* Full name. */ len = strlen(day[i]); if (strncasecmp(day[i], bp, len) == 0) break; /* Abbreviated name. */ len = strlen(abday[i]); if (strncasecmp(abday[i], bp, len) == 0) break; } /* Nothing matched. */ if (i == 7) return (0); tm->tm_wday = i; bp += len; break; case 'B': /* The month, using the locale's form. */ case 'b': case 'h': LEGAL_ALT(0); for (i = 0; i < 12; i++) { /* Full name. */ len = strlen(mon[i]); if (strncasecmp(mon[i], bp, len) == 0) break; /* Abbreviated name. */ len = strlen(abmon[i]); if (strncasecmp(abmon[i], bp, len) == 0) break; } /* Nothing matched. */ if (i == 12) return (0); tm->tm_mon = i; bp += len; break; case 'C': /* The century number. */ LEGAL_ALT(ALT_E); if (!(conv_num(&bp, &i, 0, 99))) return (0); if (split_year) { tm->tm_year = (tm->tm_year % 100) + (i * 100); } else { tm->tm_year = i * 100; split_year = 1; } break; case 'd': /* The day of month. */ case 'e': LEGAL_ALT(ALT_O); if (!(conv_num(&bp, &tm->tm_mday, 1, 31))) return (0); break; case 'k': /* The hour (24-hour clock representation). */ LEGAL_ALT(0); /* FALLTHROUGH */ case 'H': LEGAL_ALT(ALT_O); if (!(conv_num(&bp, &tm->tm_hour, 0, 23))) return (0); break; case 'l': /* The hour (12-hour clock representation). */ LEGAL_ALT(0); /* FALLTHROUGH */ case 'I': LEGAL_ALT(ALT_O); if (!(conv_num(&bp, &tm->tm_hour, 1, 12))) return (0); if (tm->tm_hour == 12) tm->tm_hour = 0; break; case 'j': /* The day of year. */ LEGAL_ALT(0); if (!(conv_num(&bp, &i, 1, 366))) return (0); tm->tm_yday = i - 1; break; case 'M': /* The minute. */ LEGAL_ALT(ALT_O); if (!(conv_num(&bp, &tm->tm_min, 0, 59))) return (0); break; case 'm': /* The month. */ LEGAL_ALT(ALT_O); if (!(conv_num(&bp, &i, 1, 12))) return (0); tm->tm_mon = i - 1; break; case 'p': /* The locale's equivalent of AM/PM. */ LEGAL_ALT(0); /* AM? */ if (strcasecmp(am_pm[0], bp) == 0) { if (tm->tm_hour > 11) return (0); bp += strlen(am_pm[0]); break; } /* PM? */ else if (strcasecmp(am_pm[1], bp) == 0) { if (tm->tm_hour > 11) return (0); tm->tm_hour += 12; bp += strlen(am_pm[1]); break; } /* Nothing matched. */ return (0); case 'S': /* The seconds. */ LEGAL_ALT(ALT_O); if (!(conv_num(&bp, &tm->tm_sec, 0, 61))) return (0); break; case 'U': /* The week of year, beginning on sunday. */ case 'W': /* The week of year, beginning on monday. */ LEGAL_ALT(ALT_O); /* * XXX This is bogus, as we can not assume any valid * information present in the tm structure at this * point to calculate a real value, so just check the * range for now. */ if (!(conv_num(&bp, &i, 0, 53))) return (0); break; case 'w': /* The day of week, beginning on sunday. */ LEGAL_ALT(ALT_O); if (!(conv_num(&bp, &tm->tm_wday, 0, 6))) return (0); break; case 'Y': /* The year. */ LEGAL_ALT(ALT_E); if (!(conv_num(&bp, &i, 0, 9999))) return (0); tm->tm_year = i - TM_YEAR_BASE; break; case 'y': /* The year within 100 years of the epoch. */ LEGAL_ALT(ALT_E | ALT_O); if (!(conv_num(&bp, &i, 0, 99))) return (0); if (split_year) { tm->tm_year = ((tm->tm_year / 100) * 100) + i; break; } split_year = 1; if (i <= 68) tm->tm_year = i + 2000 - TM_YEAR_BASE; else tm->tm_year = i + 1900 - TM_YEAR_BASE; break; /* * Miscellaneous conversions. */ case 'n': /* Any kind of white-space. */ case 't': LEGAL_ALT(0); while (isspace((unsigned char) *bp)) bp++; break; default: /* Unknown/unsupported conversion. */ return (0); } } /* LINTED functional specification */ DE_CONST(bp, ret); return (ret); } bind9-9.10.3.dfsg.P4/lib/isc/x86_32/0002755000470500017500000000000012672612753015660 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/x86_32/Makefile.in0000644000470500017500000000166312664710322017721 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = include TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/x86_32/include/0002755000470500017500000000000012664710322017273 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/x86_32/include/Makefile.in0000644000470500017500000000165712664710322021347 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = isc TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/x86_32/include/isc/0002755000470500017500000000000012664710322020051 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/x86_32/include/isc/Makefile.in0000644000470500017500000000223012664710322022111 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ HEADERS = atomic.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \ done bind9-9.10.3.dfsg.P4/lib/isc/x86_32/include/isc/atomic.h0000644000470500017500000001024212664710322021473 0ustar lamontlamont/* * Copyright (C) 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: atomic.h,v 1.10 2008/01/24 23:47:00 tbox Exp $ */ #ifndef ISC_ATOMIC_H #define ISC_ATOMIC_H 1 #include #include #ifdef ISC_PLATFORM_USEGCCASM /* * This routine atomically increments the value stored in 'p' by 'val', and * returns the previous value. */ static __inline__ isc_int32_t isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) { isc_int32_t prev = val; __asm__ volatile( #ifdef ISC_PLATFORM_USETHREADS "lock;" #endif "xadd %0, %1" :"=q"(prev) :"m"(*p), "0"(prev) :"memory", "cc"); return (prev); } #ifdef ISC_PLATFORM_HAVEXADDQ static __inline__ isc_int64_t isc_atomic_xaddq(isc_int64_t *p, isc_int64_t val) { isc_int64_t prev = val; __asm__ volatile( #ifdef ISC_PLATFORM_USETHREADS "lock;" #endif "xaddq %0, %1" :"=q"(prev) :"m"(*p), "0"(prev) :"memory", "cc"); return (prev); } #endif /* ISC_PLATFORM_HAVEXADDQ */ /* * This routine atomically stores the value 'val' in 'p'. */ static __inline__ void isc_atomic_store(isc_int32_t *p, isc_int32_t val) { __asm__ volatile( #ifdef ISC_PLATFORM_USETHREADS /* * xchg should automatically lock memory, but we add it * explicitly just in case (it at least doesn't harm) */ "lock;" #endif "xchgl %1, %0" : : "r"(val), "m"(*p) : "memory"); } /* * This routine atomically replaces the value in 'p' with 'val', if the * original value is equal to 'cmpval'. The original value is returned in any * case. */ static __inline__ isc_int32_t isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) { __asm__ volatile( #ifdef ISC_PLATFORM_USETHREADS "lock;" #endif "cmpxchgl %1, %2" : "=a"(cmpval) : "r"(val), "m"(*p), "a"(cmpval) : "memory"); return (cmpval); } #elif defined(ISC_PLATFORM_USESTDASM) /* * The followings are "generic" assembly code which implements the same * functionality in case the gcc extension cannot be used. It should be * better to avoid inlining below, since we directly refer to specific * positions of the stack frame, which would not actually point to the * intended address in the embedded mnemonic. */ #include /* for 'UNUSED' macro */ static isc_int32_t isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) { UNUSED(p); UNUSED(val); __asm ( "movl 8(%ebp), %ecx\n" "movl 12(%ebp), %edx\n" #ifdef ISC_PLATFORM_USETHREADS "lock;" #endif "xadd %edx, (%ecx)\n" /* * set the return value directly in the register so that we * can avoid guessing the correct position in the stack for a * local variable. */ "movl %edx, %eax" ); } static void isc_atomic_store(isc_int32_t *p, isc_int32_t val) { UNUSED(p); UNUSED(val); __asm ( "movl 8(%ebp), %ecx\n" "movl 12(%ebp), %edx\n" #ifdef ISC_PLATFORM_USETHREADS "lock;" #endif "xchgl (%ecx), %edx\n" ); } static isc_int32_t isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) { UNUSED(p); UNUSED(cmpval); UNUSED(val); __asm ( "movl 8(%ebp), %ecx\n" "movl 12(%ebp), %eax\n" /* must be %eax for cmpxchgl */ "movl 16(%ebp), %edx\n" #ifdef ISC_PLATFORM_USETHREADS "lock;" #endif /* * If (%ecx) == %eax then (%ecx) := %edx. % %eax is set to old (%ecx), which will be the return value. */ "cmpxchgl %edx, (%ecx)" ); } #else /* !ISC_PLATFORM_USEGCCASM && !ISC_PLATFORM_USESTDASM */ #error "unsupported compiler. disable atomic ops by --disable-atomic" #endif #endif /* ISC_ATOMIC_H */ bind9-9.10.3.dfsg.P4/lib/isc/region.c0000644000470500017500000000261312664710322016346 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: region.c,v 1.7 2007/06/19 23:47:17 tbox Exp $ */ /*! \file */ #include #include #include #include #include int isc_region_compare(isc_region_t *r1, isc_region_t *r2) { unsigned int l; int result; REQUIRE(r1 != NULL); REQUIRE(r2 != NULL); l = (r1->length < r2->length) ? r1->length : r2->length; if ((result = memcmp(r1->base, r2->base, l)) != 0) return ((result < 0) ? -1 : 1); else return ((r1->length == r2->length) ? 0 : (r1->length < r2->length) ? -1 : 1); } bind9-9.10.3.dfsg.P4/lib/isc/app_api.c0000644000470500017500000001215712664710322016500 0ustar lamontlamont/* * Copyright (C) 2009, 2013-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: app_api.c,v 1.5 2009/09/02 23:48:02 tbox Exp $ */ #include #include #include #include #include #include #include static isc_mutex_t createlock; static isc_once_t once = ISC_ONCE_INIT; static isc_appctxcreatefunc_t appctx_createfunc = NULL; static isc_boolean_t is_running = ISC_FALSE; #define ISCAPI_APPMETHODS_VALID(m) ISC_MAGIC_VALID(m, ISCAPI_APPMETHODS_MAGIC) static void initialize(void) { RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS); } isc_result_t isc_app_register(isc_appctxcreatefunc_t createfunc) { isc_result_t result = ISC_R_SUCCESS; RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); LOCK(&createlock); if (appctx_createfunc == NULL) appctx_createfunc = createfunc; else result = ISC_R_EXISTS; UNLOCK(&createlock); return (result); } isc_result_t isc_appctx_create(isc_mem_t *mctx, isc_appctx_t **ctxp) { isc_result_t result; if (isc_bind9) return (isc__appctx_create(mctx, ctxp)); LOCK(&createlock); REQUIRE(appctx_createfunc != NULL); result = (*appctx_createfunc)(mctx, ctxp); UNLOCK(&createlock); return (result); } void isc_appctx_destroy(isc_appctx_t **ctxp) { REQUIRE(ctxp != NULL && ISCAPI_APPCTX_VALID(*ctxp)); if (isc_bind9) isc__appctx_destroy(ctxp); else (*ctxp)->methods->ctxdestroy(ctxp); ENSURE(*ctxp == NULL); } isc_result_t isc_app_ctxstart(isc_appctx_t *ctx) { REQUIRE(ISCAPI_APPCTX_VALID(ctx)); if (isc_bind9) return (isc__app_ctxstart(ctx)); return (ctx->methods->ctxstart(ctx)); } isc_result_t isc_app_ctxrun(isc_appctx_t *ctx) { REQUIRE(ISCAPI_APPCTX_VALID(ctx)); if (isc_bind9) return (isc__app_ctxrun(ctx)); return (ctx->methods->ctxrun(ctx)); } isc_result_t isc_app_ctxonrun(isc_appctx_t *ctx, isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action, void *arg) { REQUIRE(ISCAPI_APPCTX_VALID(ctx)); if (isc_bind9) return (isc__app_ctxonrun(ctx, mctx, task, action, arg)); return (ctx->methods->ctxonrun(ctx, mctx, task, action, arg)); } isc_result_t isc_app_ctxsuspend(isc_appctx_t *ctx) { REQUIRE(ISCAPI_APPCTX_VALID(ctx)); if (isc_bind9) return (isc__app_ctxsuspend(ctx)); return (ctx->methods->ctxsuspend(ctx)); } isc_result_t isc_app_ctxshutdown(isc_appctx_t *ctx) { REQUIRE(ISCAPI_APPCTX_VALID(ctx)); if (isc_bind9) return (isc__app_ctxshutdown(ctx)); return (ctx->methods->ctxshutdown(ctx)); } void isc_app_ctxfinish(isc_appctx_t *ctx) { REQUIRE(ISCAPI_APPCTX_VALID(ctx)); if (isc_bind9) isc__app_ctxfinish(ctx); ctx->methods->ctxfinish(ctx); } void isc_appctx_settaskmgr(isc_appctx_t *ctx, isc_taskmgr_t *taskmgr) { REQUIRE(ISCAPI_APPCTX_VALID(ctx)); REQUIRE(taskmgr != NULL); if (isc_bind9) isc__appctx_settaskmgr(ctx, taskmgr); ctx->methods->settaskmgr(ctx, taskmgr); } void isc_appctx_setsocketmgr(isc_appctx_t *ctx, isc_socketmgr_t *socketmgr) { REQUIRE(ISCAPI_APPCTX_VALID(ctx)); REQUIRE(socketmgr != NULL); if (isc_bind9) isc__appctx_setsocketmgr(ctx, socketmgr); ctx->methods->setsocketmgr(ctx, socketmgr); } void isc_appctx_settimermgr(isc_appctx_t *ctx, isc_timermgr_t *timermgr) { REQUIRE(ISCAPI_APPCTX_VALID(ctx)); REQUIRE(timermgr != NULL); if (isc_bind9) isc__appctx_settimermgr(ctx, timermgr); ctx->methods->settimermgr(ctx, timermgr); } isc_result_t isc_app_start(void) { if (isc_bind9) return (isc__app_start()); return (ISC_R_NOTIMPLEMENTED); } isc_result_t isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action, void *arg) { if (isc_bind9) return (isc__app_onrun(mctx, task, action, arg)); return (ISC_R_NOTIMPLEMENTED); } isc_result_t isc_app_run() { if (isc_bind9) { isc_result_t result; is_running = ISC_TRUE; result = isc__app_run(); is_running = ISC_FALSE; return (result); } return (ISC_R_NOTIMPLEMENTED); } isc_boolean_t isc_app_isrunning() { return (is_running); } isc_result_t isc_app_shutdown(void) { if (isc_bind9) return (isc__app_shutdown()); return (ISC_R_NOTIMPLEMENTED); } isc_result_t isc_app_reload(void) { if (isc_bind9) return (isc__app_reload()); return (ISC_R_NOTIMPLEMENTED); } void isc_app_finish(void) { if (!isc_bind9) return; isc__app_finish(); } void isc_app_block(void) { if (!isc_bind9) return; isc__app_block(); } void isc_app_unblock(void) { if (!isc_bind9) return; isc__app_unblock(); } bind9-9.10.3.dfsg.P4/lib/isc/mutexblock.c0000644000470500017500000000305312664710322017237 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include isc_result_t isc_mutexblock_init(isc_mutex_t *block, unsigned int count) { isc_result_t result; unsigned int i; for (i = 0; i < count; i++) { result = isc_mutex_init(&block[i]); if (result != ISC_R_SUCCESS) { while (i > 0U) { i--; DESTROYLOCK(&block[i]); } return (result); } } return (ISC_R_SUCCESS); } isc_result_t isc_mutexblock_destroy(isc_mutex_t *block, unsigned int count) { isc_result_t result; unsigned int i; for (i = 0; i < count; i++) { result = isc_mutex_destroy(&block[i]); if (result != ISC_R_SUCCESS) return (result); } return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/isc/heap.c0000644000470500017500000001466312664710322016010 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2010-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1997-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file * Heap implementation of priority queues adapted from the following: * * \li "Introduction to Algorithms," Cormen, Leiserson, and Rivest, * MIT Press / McGraw Hill, 1990, ISBN 0-262-03141-8, chapter 7. * * \li "Algorithms," Second Edition, Sedgewick, Addison-Wesley, 1988, * ISBN 0-201-06673-4, chapter 11. */ #include #include #include #include #include /* Required for memmove. */ #include /*@{*/ /*% * Note: to make heap_parent and heap_left easy to compute, the first * element of the heap array is not used; i.e. heap subscripts are 1-based, * not 0-based. The parent is index/2, and the left-child is index*2. * The right child is index*2+1. */ #define heap_parent(i) ((i) >> 1) #define heap_left(i) ((i) << 1) /*@}*/ #define SIZE_INCREMENT 1024 #define HEAP_MAGIC ISC_MAGIC('H', 'E', 'A', 'P') #define VALID_HEAP(h) ISC_MAGIC_VALID(h, HEAP_MAGIC) /*% * When the heap is in a consistent state, the following invariant * holds true: for every element i > 1, heap_parent(i) has a priority * higher than or equal to that of i. */ #define HEAPCONDITION(i) ((i) == 1 || \ ! heap->compare(heap->array[(i)], \ heap->array[heap_parent(i)])) /*% ISC heap structure. */ struct isc_heap { unsigned int magic; isc_mem_t * mctx; unsigned int size; unsigned int size_increment; unsigned int last; void **array; isc_heapcompare_t compare; isc_heapindex_t index; }; isc_result_t isc_heap_create(isc_mem_t *mctx, isc_heapcompare_t compare, isc_heapindex_t idx, unsigned int size_increment, isc_heap_t **heapp) { isc_heap_t *heap; REQUIRE(heapp != NULL && *heapp == NULL); REQUIRE(compare != NULL); heap = isc_mem_get(mctx, sizeof(*heap)); if (heap == NULL) return (ISC_R_NOMEMORY); heap->magic = HEAP_MAGIC; heap->size = 0; heap->mctx = NULL; isc_mem_attach(mctx, &heap->mctx); if (size_increment == 0) heap->size_increment = SIZE_INCREMENT; else heap->size_increment = size_increment; heap->last = 0; heap->array = NULL; heap->compare = compare; heap->index = idx; *heapp = heap; return (ISC_R_SUCCESS); } void isc_heap_destroy(isc_heap_t **heapp) { isc_heap_t *heap; REQUIRE(heapp != NULL); heap = *heapp; REQUIRE(VALID_HEAP(heap)); if (heap->array != NULL) isc_mem_put(heap->mctx, heap->array, heap->size * sizeof(void *)); heap->magic = 0; isc_mem_putanddetach(&heap->mctx, heap, sizeof(*heap)); *heapp = NULL; } static isc_boolean_t resize(isc_heap_t *heap) { void **new_array; unsigned int new_size; REQUIRE(VALID_HEAP(heap)); new_size = heap->size + heap->size_increment; new_array = isc_mem_get(heap->mctx, new_size * sizeof(void *)); if (new_array == NULL) return (ISC_FALSE); if (heap->array != NULL) { memmove(new_array, heap->array, heap->size * sizeof(void *)); isc_mem_put(heap->mctx, heap->array, heap->size * sizeof(void *)); } heap->size = new_size; heap->array = new_array; return (ISC_TRUE); } static void float_up(isc_heap_t *heap, unsigned int i, void *elt) { unsigned int p; for (p = heap_parent(i) ; i > 1 && heap->compare(elt, heap->array[p]) ; i = p, p = heap_parent(i)) { heap->array[i] = heap->array[p]; if (heap->index != NULL) (heap->index)(heap->array[i], i); } heap->array[i] = elt; if (heap->index != NULL) (heap->index)(heap->array[i], i); INSIST(HEAPCONDITION(i)); } static void sink_down(isc_heap_t *heap, unsigned int i, void *elt) { unsigned int j, size, half_size; size = heap->last; half_size = size / 2; while (i <= half_size) { /* Find the smallest of the (at most) two children. */ j = heap_left(i); if (j < size && heap->compare(heap->array[j+1], heap->array[j])) j++; if (heap->compare(elt, heap->array[j])) break; heap->array[i] = heap->array[j]; if (heap->index != NULL) (heap->index)(heap->array[i], i); i = j; } heap->array[i] = elt; if (heap->index != NULL) (heap->index)(heap->array[i], i); INSIST(HEAPCONDITION(i)); } isc_result_t isc_heap_insert(isc_heap_t *heap, void *elt) { unsigned int new_last; REQUIRE(VALID_HEAP(heap)); new_last = heap->last + 1; RUNTIME_CHECK(new_last > 0); /* overflow check */ if (new_last >= heap->size && !resize(heap)) return (ISC_R_NOMEMORY); heap->last = new_last; float_up(heap, new_last, elt); return (ISC_R_SUCCESS); } void isc_heap_delete(isc_heap_t *heap, unsigned int idx) { void *elt; isc_boolean_t less; REQUIRE(VALID_HEAP(heap)); REQUIRE(idx >= 1 && idx <= heap->last); if (idx == heap->last) { heap->array[heap->last] = NULL; heap->last--; } else { elt = heap->array[heap->last]; heap->array[heap->last] = NULL; heap->last--; less = heap->compare(elt, heap->array[idx]); heap->array[idx] = elt; if (less) float_up(heap, idx, heap->array[idx]); else sink_down(heap, idx, heap->array[idx]); } } void isc_heap_increased(isc_heap_t *heap, unsigned int idx) { REQUIRE(VALID_HEAP(heap)); REQUIRE(idx >= 1 && idx <= heap->last); float_up(heap, idx, heap->array[idx]); } void isc_heap_decreased(isc_heap_t *heap, unsigned int idx) { REQUIRE(VALID_HEAP(heap)); REQUIRE(idx >= 1 && idx <= heap->last); sink_down(heap, idx, heap->array[idx]); } void * isc_heap_element(isc_heap_t *heap, unsigned int idx) { REQUIRE(VALID_HEAP(heap)); REQUIRE(idx >= 1); if (idx <= heap->last) return (heap->array[idx]); return (NULL); } void isc_heap_foreach(isc_heap_t *heap, isc_heapaction_t action, void *uap) { unsigned int i; REQUIRE(VALID_HEAP(heap)); REQUIRE(action != NULL); for (i = 1 ; i <= heap->last ; i++) (action)(heap->array[i], uap); } bind9-9.10.3.dfsg.P4/lib/isc/safe.c0000644000470500017500000000330712664710322016002 0ustar lamontlamont/* * Copyright (C) 2013, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #ifdef _MSC_VER #pragma optimize("", off) #endif isc_boolean_t isc_safe_memequal(const void *s1, const void *s2, size_t n) { isc_uint8_t acc = 0; if (n != 0U) { const isc_uint8_t *p1 = s1, *p2 = s2; do { acc |= *p1++ ^ *p2++; } while (--n != 0U); } return (ISC_TF(acc == 0)); } int isc_safe_memcompare(const void *b1, const void *b2, size_t len) { const unsigned char *p1 = b1, *p2 = b2; size_t i; int res = 0, done = 0; for (i = 0; i < len; i++) { /* lt is -1 if p1[i] < p2[i]; else 0. */ int lt = (p1[i] - p2[i]) >> CHAR_BIT; /* gt is -1 if p1[i] > p2[i]; else 0. */ int gt = (p2[i] - p1[i]) >> CHAR_BIT; /* cmp is 1 if p1[i] > p2[i]; -1 if p1[i] < p2[i]; else 0. */ int cmp = lt - gt; /* set res = cmp if !done. */ res |= cmp & ~done; /* set done if p1[i] != p2[i]. */ done |= lt | gt; } return (res); } bind9-9.10.3.dfsg.P4/lib/isc/Atffile0000644000470500017500000000013212664710322016206 0ustar lamontlamontContent-Type: application/X-atf-atffile; version="1" prop: test-suite = bind9 tp: tests bind9-9.10.3.dfsg.P4/lib/isc/include/0002755000470500017500000000000012672612753016352 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/include/Makefile.in0000644000470500017500000000200012664710322020375 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.13 2007/06/19 23:47:18 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = isc pk11 pkcs11 TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/include/pkcs11/0002755000470500017500000000000012664710322017444 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/include/pkcs11/Makefile.in0000644000470500017500000000247512664710322021517 0ustar lamontlamont# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.7 2007/06/19 23:47:22 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ # # Only list headers that are to be installed and are not # machine generated. The latter are handled specially in the # install target below. # HEADERS = pkcs11f.h pkcs11.h pkcs11t.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/pkcs11 install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/pkcs11 ; \ done bind9-9.10.3.dfsg.P4/lib/isc/include/pkcs11/pkcs11t.h0000644000470500017500000021600212664710322021102 0ustar lamontlamont/* pkcs11t.h include file for PKCS #11. */ /* $Revision: 1.2 $ */ /* License to copy and use this software is granted provided that it is * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface * (Cryptoki)" in all material mentioning or referencing this software. * License is also granted to make and use derivative works provided that * such works are identified as "derived from the RSA Security Inc. PKCS #11 * Cryptographic Token Interface (Cryptoki)" in all material mentioning or * referencing the derived work. * RSA Security Inc. makes no representations concerning either the * merchantability of this software or the suitability of this software for * any particular purpose. It is provided "as is" without express or implied * warranty of any kind. */ /* See top of pkcs11.h for information about the macros that * must be defined and the structure-packing conventions that * must be set before including this file. */ #ifndef _PKCS11T_H_ #define _PKCS11T_H_ 1 #define CRYPTOKI_VERSION_MAJOR 2 #define CRYPTOKI_VERSION_MINOR 30 #define CRYPTOKI_VERSION_REVISION 0 #define CRYPTOKI_VERSION_AMENDMENT 0 #define CK_TRUE 1 #define CK_FALSE 0 #ifndef CK_DISABLE_TRUE_FALSE #ifndef FALSE #define FALSE CK_FALSE #endif #ifndef TRUE #define TRUE CK_TRUE #endif #endif /* an unsigned 8-bit value */ typedef unsigned char CK_BYTE; /* an unsigned 8-bit character */ typedef CK_BYTE CK_CHAR; /* an 8-bit UTF-8 character */ typedef CK_BYTE CK_UTF8CHAR; /* a BYTE-sized Boolean flag */ typedef CK_BYTE CK_BBOOL; /* an unsigned value, at least 32 bits long */ typedef unsigned long int CK_ULONG; /* a signed value, the same size as a CK_ULONG */ /* CK_LONG is new for v2.0 */ typedef long int CK_LONG; /* at least 32 bits; each bit is a Boolean flag */ typedef CK_ULONG CK_FLAGS; /* some special values for certain CK_ULONG variables */ #define CK_UNAVAILABLE_INFORMATION (~0UL) #define CK_EFFECTIVELY_INFINITE 0 typedef CK_BYTE CK_PTR CK_BYTE_PTR; typedef CK_CHAR CK_PTR CK_CHAR_PTR; typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR; typedef CK_ULONG CK_PTR CK_ULONG_PTR; typedef void CK_PTR CK_VOID_PTR; /* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */ typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR; /* The following value is always invalid if used as a session */ /* handle or object handle */ #define CK_INVALID_HANDLE 0 typedef struct CK_VERSION { CK_BYTE major; /* integer portion of version number */ CK_BYTE minor; /* 1/100ths portion of version number */ } CK_VERSION; typedef CK_VERSION CK_PTR CK_VERSION_PTR; typedef struct CK_INFO { /* manufacturerID and libraryDecription have been changed from * CK_CHAR to CK_UTF8CHAR for v2.10 */ CK_VERSION cryptokiVersion; /* Cryptoki interface ver */ CK_UTF8CHAR manufacturerID[32]; /* blank padded */ CK_FLAGS flags; /* must be zero */ /* libraryDescription and libraryVersion are new for v2.0 */ CK_UTF8CHAR libraryDescription[32]; /* blank padded */ CK_VERSION libraryVersion; /* version of library */ } CK_INFO; typedef CK_INFO CK_PTR CK_INFO_PTR; /* CK_NOTIFICATION enumerates the types of notifications that * Cryptoki provides to an application */ /* CK_NOTIFICATION has been changed from an enum to a CK_ULONG * for v2.0 */ typedef CK_ULONG CK_NOTIFICATION; #define CKN_SURRENDER 0 /* The following notification is new for PKCS #11 v2.20 amendment 3 */ #define CKN_OTP_CHANGED 1 typedef CK_ULONG CK_SLOT_ID; typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR; /* CK_SLOT_INFO provides information about a slot */ typedef struct CK_SLOT_INFO { /* slotDescription and manufacturerID have been changed from * CK_CHAR to CK_UTF8CHAR for v2.10 */ CK_UTF8CHAR slotDescription[64]; /* blank padded */ CK_UTF8CHAR manufacturerID[32]; /* blank padded */ CK_FLAGS flags; /* hardwareVersion and firmwareVersion are new for v2.0 */ CK_VERSION hardwareVersion; /* version of hardware */ CK_VERSION firmwareVersion; /* version of firmware */ } CK_SLOT_INFO; /* flags: bit flags that provide capabilities of the slot * Bit Flag Mask Meaning */ #define CKF_TOKEN_PRESENT 0x00000001 /* a token is there */ #define CKF_REMOVABLE_DEVICE 0x00000002 /* removable devices*/ #define CKF_HW_SLOT 0x00000004 /* hardware slot */ typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR; /* CK_TOKEN_INFO provides information about a token */ typedef struct CK_TOKEN_INFO { /* label, manufacturerID, and model have been changed from * CK_CHAR to CK_UTF8CHAR for v2.10 */ CK_UTF8CHAR label[32]; /* blank padded */ CK_UTF8CHAR manufacturerID[32]; /* blank padded */ CK_UTF8CHAR model[16]; /* blank padded */ CK_CHAR serialNumber[16]; /* blank padded */ CK_FLAGS flags; /* see below */ /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount, * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been * changed from CK_USHORT to CK_ULONG for v2.0 */ CK_ULONG ulMaxSessionCount; /* max open sessions */ CK_ULONG ulSessionCount; /* sess. now open */ CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */ CK_ULONG ulRwSessionCount; /* R/W sess. now open */ CK_ULONG ulMaxPinLen; /* in bytes */ CK_ULONG ulMinPinLen; /* in bytes */ CK_ULONG ulTotalPublicMemory; /* in bytes */ CK_ULONG ulFreePublicMemory; /* in bytes */ CK_ULONG ulTotalPrivateMemory; /* in bytes */ CK_ULONG ulFreePrivateMemory; /* in bytes */ /* hardwareVersion, firmwareVersion, and time are new for * v2.0 */ CK_VERSION hardwareVersion; /* version of hardware */ CK_VERSION firmwareVersion; /* version of firmware */ CK_CHAR utcTime[16]; /* time */ } CK_TOKEN_INFO; /* The flags parameter is defined as follows: * Bit Flag Mask Meaning */ #define CKF_RNG 0x00000001 /* has random # * generator */ #define CKF_WRITE_PROTECTED 0x00000002 /* token is * write- * protected */ #define CKF_LOGIN_REQUIRED 0x00000004 /* user must * login */ #define CKF_USER_PIN_INITIALIZED 0x00000008 /* normal user's * PIN is set */ /* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0. If it is set, * that means that *every* time the state of cryptographic * operations of a session is successfully saved, all keys * needed to continue those operations are stored in the state */ #define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020 /* CKF_CLOCK_ON_TOKEN is new for v2.0. If it is set, that means * that the token has some sort of clock. The time on that * clock is returned in the token info structure */ #define CKF_CLOCK_ON_TOKEN 0x00000040 /* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0. If it is * set, that means that there is some way for the user to login * without sending a PIN through the Cryptoki library itself */ #define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100 /* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0. If it is true, * that means that a single session with the token can perform * dual simultaneous cryptographic operations (digest and * encrypt; decrypt and digest; sign and encrypt; and decrypt * and sign) */ #define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200 /* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the * token has been initialized using C_InitializeToken or an * equivalent mechanism outside the scope of PKCS #11. * Calling C_InitializeToken when this flag is set will cause * the token to be reinitialized. */ #define CKF_TOKEN_INITIALIZED 0x00000400 /* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is * true, the token supports secondary authentication for * private key objects. This flag is deprecated in v2.11 and onwards. */ #define CKF_SECONDARY_AUTHENTICATION 0x00000800 /* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an * incorrect user login PIN has been entered at least once * since the last successful authentication. */ #define CKF_USER_PIN_COUNT_LOW 0x00010000 /* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true, * supplying an incorrect user PIN will it to become locked. */ #define CKF_USER_PIN_FINAL_TRY 0x00020000 /* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the * user PIN has been locked. User login to the token is not * possible. */ #define CKF_USER_PIN_LOCKED 0x00040000 /* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true, * the user PIN value is the default value set by token * initialization or manufacturing, or the PIN has been * expired by the card. */ #define CKF_USER_PIN_TO_BE_CHANGED 0x00080000 /* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an * incorrect SO login PIN has been entered at least once since * the last successful authentication. */ #define CKF_SO_PIN_COUNT_LOW 0x00100000 /* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true, * supplying an incorrect SO PIN will it to become locked. */ #define CKF_SO_PIN_FINAL_TRY 0x00200000 /* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO * PIN has been locked. SO login to the token is not possible. */ #define CKF_SO_PIN_LOCKED 0x00400000 /* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true, * the SO PIN value is the default value set by token * initialization or manufacturing, or the PIN has been * expired by the card. */ #define CKF_SO_PIN_TO_BE_CHANGED 0x00800000 /* CKF_ERROR_STATE if new for v2.30. If it is true, * the token failed a FIPS 140-2 self-test and * entered an error state. */ #define CKF_ERROR_STATE 0x01000000 typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR; /* CK_SESSION_HANDLE is a Cryptoki-assigned value that * identifies a session */ typedef CK_ULONG CK_SESSION_HANDLE; typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR; /* CK_USER_TYPE enumerates the types of Cryptoki users */ /* CK_USER_TYPE has been changed from an enum to a CK_ULONG for * v2.0 */ typedef CK_ULONG CK_USER_TYPE; /* Security Officer */ #define CKU_SO 0 /* Normal user */ #define CKU_USER 1 /* Context specific (added in v2.20) */ #define CKU_CONTEXT_SPECIFIC 2 /* CK_STATE enumerates the session states */ /* CK_STATE has been changed from an enum to a CK_ULONG for * v2.0 */ typedef CK_ULONG CK_STATE; #define CKS_RO_PUBLIC_SESSION 0 #define CKS_RO_USER_FUNCTIONS 1 #define CKS_RW_PUBLIC_SESSION 2 #define CKS_RW_USER_FUNCTIONS 3 #define CKS_RW_SO_FUNCTIONS 4 /* CK_SESSION_INFO provides information about a session */ typedef struct CK_SESSION_INFO { CK_SLOT_ID slotID; CK_STATE state; CK_FLAGS flags; /* see below */ /* ulDeviceError was changed from CK_USHORT to CK_ULONG for * v2.0 */ CK_ULONG ulDeviceError; /* device-dependent error code */ } CK_SESSION_INFO; /* The flags are defined in the following table: * Bit Flag Mask Meaning */ #define CKF_RW_SESSION 0x00000002 /* session is r/w */ #define CKF_SERIAL_SESSION 0x00000004 /* no parallel */ typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR; /* CK_OBJECT_HANDLE is a token-specific identifier for an * object */ typedef CK_ULONG CK_OBJECT_HANDLE; typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR; /* CK_OBJECT_CLASS is a value that identifies the classes (or * types) of objects that Cryptoki recognizes. It is defined * as follows: */ /* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for * v2.0 */ typedef CK_ULONG CK_OBJECT_CLASS; /* The following classes of objects are defined: */ /* CKO_HW_FEATURE is new for v2.10 */ /* CKO_DOMAIN_PARAMETERS is new for v2.11 */ /* CKO_MECHANISM is new for v2.20 */ #define CKO_DATA 0x00000000 #define CKO_CERTIFICATE 0x00000001 #define CKO_PUBLIC_KEY 0x00000002 #define CKO_PRIVATE_KEY 0x00000003 #define CKO_SECRET_KEY 0x00000004 #define CKO_HW_FEATURE 0x00000005 #define CKO_DOMAIN_PARAMETERS 0x00000006 #define CKO_MECHANISM 0x00000007 /* CKO_OTP_KEY is new for PKCS #11 v2.20 amendment 1 */ #define CKO_OTP_KEY 0x00000008 #define CKO_VENDOR_DEFINED 0x80000000 typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR; /* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a * value that identifies the hardware feature type of an object * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */ typedef CK_ULONG CK_HW_FEATURE_TYPE; /* The following hardware feature types are defined */ /* CKH_USER_INTERFACE is new for v2.20 */ #define CKH_MONOTONIC_COUNTER 0x00000001 #define CKH_CLOCK 0x00000002 #define CKH_USER_INTERFACE 0x00000003 #define CKH_VENDOR_DEFINED 0x80000000 /* CK_KEY_TYPE is a value that identifies a key type */ /* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */ typedef CK_ULONG CK_KEY_TYPE; /* the following key types are defined: */ #define CKK_RSA 0x00000000 #define CKK_DSA 0x00000001 #define CKK_DH 0x00000002 /* CKK_ECDSA and CKK_KEA are new for v2.0 */ /* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */ #define CKK_ECDSA 0x00000003 #define CKK_EC 0x00000003 #define CKK_X9_42_DH 0x00000004 #define CKK_KEA 0x00000005 #define CKK_GENERIC_SECRET 0x00000010 #define CKK_RC2 0x00000011 #define CKK_RC4 0x00000012 #define CKK_DES 0x00000013 #define CKK_DES2 0x00000014 #define CKK_DES3 0x00000015 /* all these key types are new for v2.0 */ #define CKK_CAST 0x00000016 #define CKK_CAST3 0x00000017 /* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */ #define CKK_CAST5 0x00000018 #define CKK_CAST128 0x00000018 #define CKK_RC5 0x00000019 #define CKK_IDEA 0x0000001A #define CKK_SKIPJACK 0x0000001B #define CKK_BATON 0x0000001C #define CKK_JUNIPER 0x0000001D #define CKK_CDMF 0x0000001E #define CKK_AES 0x0000001F /* BlowFish and TwoFish are new for v2.20 */ #define CKK_BLOWFISH 0x00000020 #define CKK_TWOFISH 0x00000021 /* SecurID, HOTP, and ACTI are new for PKCS #11 v2.20 amendment 1 */ #define CKK_SECURID 0x00000022 #define CKK_HOTP 0x00000023 #define CKK_ACTI 0x00000024 /* Camellia is new for PKCS #11 v2.20 amendment 3 */ #define CKK_CAMELLIA 0x00000025 /* ARIA is new for PKCS #11 v2.20 amendment 3 */ #define CKK_ARIA 0x00000026 /* From PKCS #11 v2.20 amendment 4 draft 2 */ #define CKK_MD5_HMAC 0x00000027 #define CKK_SHA_1_HMAC 0x00000028 #define CKK_RIPEMD128_HMAC 0x00000029 #define CKK_RIPEMD160_HMAC 0x0000002A #define CKK_SHA256_HMAC 0x0000002B #define CKK_SHA384_HMAC 0x0000002C #define CKK_SHA512_HMAC 0x0000002D #define CKK_SHA224_HMAC 0x0000002E /* From PKCS #11 v2.30 */ #define CKK_SEED 0x0000002F #define CKK_GOSTR3410 0x00000030 #define CKK_GOSTR3411 0x00000031 #define CKK_GOST28147 0x00000032 #define CKK_VENDOR_DEFINED 0x80000000 /* CK_CERTIFICATE_TYPE is a value that identifies a certificate * type */ /* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG * for v2.0 */ typedef CK_ULONG CK_CERTIFICATE_TYPE; /* The following certificate types are defined: */ /* CKC_X_509_ATTR_CERT is new for v2.10 */ /* CKC_WTLS is new for v2.20 */ #define CKC_X_509 0x00000000 #define CKC_X_509_ATTR_CERT 0x00000001 #define CKC_WTLS 0x00000002 #define CKC_VENDOR_DEFINED 0x80000000 /* CK_ATTRIBUTE_TYPE is a value that identifies an attribute * type */ /* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for * v2.0 */ typedef CK_ULONG CK_ATTRIBUTE_TYPE; /* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which consists of an array of values. */ #define CKF_ARRAY_ATTRIBUTE 0x40000000 /* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 and relates to the CKA_OTP_FORMAT attribute */ #define CK_OTP_FORMAT_DECIMAL 0 #define CK_OTP_FORMAT_HEXADECIMAL 1 #define CK_OTP_FORMAT_ALPHANUMERIC 2 #define CK_OTP_FORMAT_BINARY 3 /* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 and relates to the CKA_OTP_..._REQUIREMENT attributes */ #define CK_OTP_PARAM_IGNORED 0 #define CK_OTP_PARAM_OPTIONAL 1 #define CK_OTP_PARAM_MANDATORY 2 /* The following attribute types are defined: */ #define CKA_CLASS 0x00000000 #define CKA_TOKEN 0x00000001 #define CKA_PRIVATE 0x00000002 #define CKA_LABEL 0x00000003 #define CKA_APPLICATION 0x00000010 #define CKA_VALUE 0x00000011 /* CKA_OBJECT_ID is new for v2.10 */ #define CKA_OBJECT_ID 0x00000012 #define CKA_CERTIFICATE_TYPE 0x00000080 #define CKA_ISSUER 0x00000081 #define CKA_SERIAL_NUMBER 0x00000082 /* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new * for v2.10 */ #define CKA_AC_ISSUER 0x00000083 #define CKA_OWNER 0x00000084 #define CKA_ATTR_TYPES 0x00000085 /* CKA_TRUSTED is new for v2.11 */ #define CKA_TRUSTED 0x00000086 /* CKA_CERTIFICATE_CATEGORY ... * CKA_CHECK_VALUE are new for v2.20 */ #define CKA_CERTIFICATE_CATEGORY 0x00000087 #define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088 #define CKA_URL 0x00000089 #define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008A #define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008B /* One from v2.30? */ #define CKA_NAME_HASH_ALGORITH 0x0000008C #define CKA_CHECK_VALUE 0x00000090 #define CKA_KEY_TYPE 0x00000100 #define CKA_SUBJECT 0x00000101 #define CKA_ID 0x00000102 #define CKA_SENSITIVE 0x00000103 #define CKA_ENCRYPT 0x00000104 #define CKA_DECRYPT 0x00000105 #define CKA_WRAP 0x00000106 #define CKA_UNWRAP 0x00000107 #define CKA_SIGN 0x00000108 #define CKA_SIGN_RECOVER 0x00000109 #define CKA_VERIFY 0x0000010A #define CKA_VERIFY_RECOVER 0x0000010B #define CKA_DERIVE 0x0000010C #define CKA_START_DATE 0x00000110 #define CKA_END_DATE 0x00000111 #define CKA_MODULUS 0x00000120 #define CKA_MODULUS_BITS 0x00000121 #define CKA_PUBLIC_EXPONENT 0x00000122 #define CKA_PRIVATE_EXPONENT 0x00000123 #define CKA_PRIME_1 0x00000124 #define CKA_PRIME_2 0x00000125 #define CKA_EXPONENT_1 0x00000126 #define CKA_EXPONENT_2 0x00000127 #define CKA_COEFFICIENT 0x00000128 #define CKA_PRIME 0x00000130 #define CKA_SUBPRIME 0x00000131 #define CKA_BASE 0x00000132 /* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */ #define CKA_PRIME_BITS 0x00000133 #define CKA_SUBPRIME_BITS 0x00000134 #define CKA_SUB_PRIME_BITS CKA_SUBPRIME_BITS /* (To retain backwards-compatibility) */ #define CKA_VALUE_BITS 0x00000160 #define CKA_VALUE_LEN 0x00000161 /* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE, * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS, * and CKA_EC_POINT are new for v2.0 */ #define CKA_EXTRACTABLE 0x00000162 #define CKA_LOCAL 0x00000163 #define CKA_NEVER_EXTRACTABLE 0x00000164 #define CKA_ALWAYS_SENSITIVE 0x00000165 /* CKA_KEY_GEN_MECHANISM is new for v2.11 */ #define CKA_KEY_GEN_MECHANISM 0x00000166 #define CKA_MODIFIABLE 0x00000170 /* From v2.30? */ #define CKA_COPYABLE 0x00000171 /* CKA_ECDSA_PARAMS is deprecated in v2.11, * CKA_EC_PARAMS is preferred. */ #define CKA_ECDSA_PARAMS 0x00000180 #define CKA_EC_PARAMS 0x00000180 #define CKA_EC_POINT 0x00000181 /* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS, * are new for v2.10. Deprecated in v2.11 and onwards. */ #define CKA_SECONDARY_AUTH 0x00000200 #define CKA_AUTH_PIN_FLAGS 0x00000201 /* CKA_ALWAYS_AUTHENTICATE ... * CKA_UNWRAP_TEMPLATE are new for v2.20 */ #define CKA_ALWAYS_AUTHENTICATE 0x00000202 #define CKA_WRAP_WITH_TRUSTED 0x00000210 #define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000211) #define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000212) /* CKA_OTP... atttributes are new for PKCS #11 v2.20 amendment 3. */ #define CKA_OTP_FORMAT 0x00000220 #define CKA_OTP_LENGTH 0x00000221 #define CKA_OTP_TIME_INTERVAL 0x00000222 #define CKA_OTP_USER_FRIENDLY_MODE 0x00000223 #define CKA_OTP_CHALLENGE_REQUIREMENT 0x00000224 #define CKA_OTP_TIME_REQUIREMENT 0x00000225 #define CKA_OTP_COUNTER_REQUIREMENT 0x00000226 #define CKA_OTP_PIN_REQUIREMENT 0x00000227 #define CKA_OTP_COUNTER 0x0000022E #define CKA_OTP_TIME 0x0000022F #define CKA_OTP_USER_IDENTIFIER 0x0000022A #define CKA_OTP_SERVICE_IDENTIFIER 0x0000022B #define CKA_OTP_SERVICE_LOGO 0x0000022C #define CKA_OTP_SERVICE_LOGO_TYPE 0x0000022D /* CKA_GOST... */ #define CKA_GOSTR3410_PARAMS 0x00000250 #define CKA_GOSTR3411_PARAMS 0x00000251 #define CKA_GOST28147_PARAMS 0x00000252 /* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET * are new for v2.10 */ #define CKA_HW_FEATURE_TYPE 0x00000300 #define CKA_RESET_ON_INIT 0x00000301 #define CKA_HAS_RESET 0x00000302 /* The following attributes are new for v2.20 */ #define CKA_PIXEL_X 0x00000400 #define CKA_PIXEL_Y 0x00000401 #define CKA_RESOLUTION 0x00000402 #define CKA_CHAR_ROWS 0x00000403 #define CKA_CHAR_COLUMNS 0x00000404 #define CKA_COLOR 0x00000405 #define CKA_BITS_PER_PIXEL 0x00000406 #define CKA_CHAR_SETS 0x00000480 #define CKA_ENCODING_METHODS 0x00000481 #define CKA_MIME_TYPES 0x00000482 #define CKA_MECHANISM_TYPE 0x00000500 #define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501 #define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502 #define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503 #define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE|0x00000600) /* From v2.30? */ #define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000211) #define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000212) #define CKA_DERIVE_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000213) #define CKA_VENDOR_DEFINED 0x80000000 /* CK_ATTRIBUTE is a structure that includes the type, length * and value of an attribute */ typedef struct CK_ATTRIBUTE { CK_ATTRIBUTE_TYPE type; CK_VOID_PTR pValue; /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */ CK_ULONG ulValueLen; /* in bytes */ } CK_ATTRIBUTE; typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR; /* CK_DATE is a structure that defines a date */ typedef struct CK_DATE{ CK_CHAR year[4]; /* the year ("1900" - "9999") */ CK_CHAR month[2]; /* the month ("01" - "12") */ CK_CHAR day[2]; /* the day ("01" - "31") */ } CK_DATE; /* CK_MECHANISM_TYPE is a value that identifies a mechanism * type */ /* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for * v2.0 */ typedef CK_ULONG CK_MECHANISM_TYPE; /* the following mechanism types are defined: */ #define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000 #define CKM_RSA_PKCS 0x00000001 #define CKM_RSA_9796 0x00000002 #define CKM_RSA_X_509 0x00000003 /* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS * are new for v2.0. They are mechanisms which hash and sign */ #define CKM_MD2_RSA_PKCS 0x00000004 #define CKM_MD5_RSA_PKCS 0x00000005 #define CKM_SHA1_RSA_PKCS 0x00000006 /* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and * CKM_RSA_PKCS_OAEP are new for v2.10 */ #define CKM_RIPEMD128_RSA_PKCS 0x00000007 #define CKM_RIPEMD160_RSA_PKCS 0x00000008 #define CKM_RSA_PKCS_OAEP 0x00000009 /* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31, * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */ #define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000A #define CKM_RSA_X9_31 0x0000000B #define CKM_SHA1_RSA_X9_31 0x0000000C #define CKM_RSA_PKCS_PSS 0x0000000D #define CKM_SHA1_RSA_PKCS_PSS 0x0000000E #define CKM_DSA_KEY_PAIR_GEN 0x00000010 #define CKM_DSA 0x00000011 #define CKM_DSA_SHA1 0x00000012 /* Other DSAs */ #define CKM_DSA_SHA224 0x00000013 #define CKM_DSA_SHA256 0x00000014 #define CKM_DSA_SHA384 0x00000015 #define CKM_DSA_SHA512 0x00000016 #define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020 #define CKM_DH_PKCS_DERIVE 0x00000021 /* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE, * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for * v2.11 */ #define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030 #define CKM_X9_42_DH_DERIVE 0x00000031 #define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032 #define CKM_X9_42_MQV_DERIVE 0x00000033 /* CKM_SHA256/384/512 are new for v2.20 */ #define CKM_SHA256_RSA_PKCS 0x00000040 #define CKM_SHA384_RSA_PKCS 0x00000041 #define CKM_SHA512_RSA_PKCS 0x00000042 #define CKM_SHA256_RSA_PKCS_PSS 0x00000043 #define CKM_SHA384_RSA_PKCS_PSS 0x00000044 #define CKM_SHA512_RSA_PKCS_PSS 0x00000045 /* SHA-224 RSA mechanisms are new for PKCS #11 v2.20 amendment 3 */ #define CKM_SHA224_RSA_PKCS 0x00000046 #define CKM_SHA224_RSA_PKCS_PSS 0x00000047 #define CKM_RC2_KEY_GEN 0x00000100 #define CKM_RC2_ECB 0x00000101 #define CKM_RC2_CBC 0x00000102 #define CKM_RC2_MAC 0x00000103 /* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */ #define CKM_RC2_MAC_GENERAL 0x00000104 #define CKM_RC2_CBC_PAD 0x00000105 #define CKM_RC4_KEY_GEN 0x00000110 #define CKM_RC4 0x00000111 #define CKM_DES_KEY_GEN 0x00000120 #define CKM_DES_ECB 0x00000121 #define CKM_DES_CBC 0x00000122 #define CKM_DES_MAC 0x00000123 /* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */ #define CKM_DES_MAC_GENERAL 0x00000124 #define CKM_DES_CBC_PAD 0x00000125 #define CKM_DES2_KEY_GEN 0x00000130 #define CKM_DES3_KEY_GEN 0x00000131 #define CKM_DES3_ECB 0x00000132 #define CKM_DES3_CBC 0x00000133 #define CKM_DES3_MAC 0x00000134 /* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN, * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC, * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0, * CKM_DES3_CMAC_GENERAL and CKM_DES3_CMAC are from v2.30? */ #define CKM_DES3_MAC_GENERAL 0x00000135 #define CKM_DES3_CBC_PAD 0x00000136 #define CKM_DES3_CMAC_GENERAL 0x00000137 #define CKM_DES3_CMAC 0x00000138 #define CKM_CDMF_KEY_GEN 0x00000140 #define CKM_CDMF_ECB 0x00000141 #define CKM_CDMF_CBC 0x00000142 #define CKM_CDMF_MAC 0x00000143 #define CKM_CDMF_MAC_GENERAL 0x00000144 #define CKM_CDMF_CBC_PAD 0x00000145 /* the following four DES mechanisms are new for v2.20 */ #define CKM_DES_OFB64 0x00000150 #define CKM_DES_OFB8 0x00000151 #define CKM_DES_CFB64 0x00000152 #define CKM_DES_CFB8 0x00000153 #define CKM_MD2 0x00000200 /* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */ #define CKM_MD2_HMAC 0x00000201 #define CKM_MD2_HMAC_GENERAL 0x00000202 #define CKM_MD5 0x00000210 /* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */ #define CKM_MD5_HMAC 0x00000211 #define CKM_MD5_HMAC_GENERAL 0x00000212 #define CKM_SHA_1 0x00000220 /* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */ #define CKM_SHA_1_HMAC 0x00000221 #define CKM_SHA_1_HMAC_GENERAL 0x00000222 /* CKM_RIPEMD128, CKM_RIPEMD128_HMAC, * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC, * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */ #define CKM_RIPEMD128 0x00000230 #define CKM_RIPEMD128_HMAC 0x00000231 #define CKM_RIPEMD128_HMAC_GENERAL 0x00000232 #define CKM_RIPEMD160 0x00000240 #define CKM_RIPEMD160_HMAC 0x00000241 #define CKM_RIPEMD160_HMAC_GENERAL 0x00000242 /* CKM_SHA256/384/512 are new for v2.20 */ #define CKM_SHA256 0x00000250 #define CKM_SHA256_HMAC 0x00000251 #define CKM_SHA256_HMAC_GENERAL 0x00000252 /* SHA-224 is new for PKCS #11 v2.20 amendment 3 */ #define CKM_SHA224 0x00000255 #define CKM_SHA224_HMAC 0x00000256 #define CKM_SHA224_HMAC_GENERAL 0x00000257 #define CKM_SHA384 0x00000260 #define CKM_SHA384_HMAC 0x00000261 #define CKM_SHA384_HMAC_GENERAL 0x00000262 #define CKM_SHA512 0x00000270 #define CKM_SHA512_HMAC 0x00000271 #define CKM_SHA512_HMAC_GENERAL 0x00000272 /* SecurID is new for PKCS #11 v2.20 amendment 1 */ #define CKM_SECURID_KEY_GEN 0x00000280 #define CKM_SECURID 0x00000282 /* HOTP is new for PKCS #11 v2.20 amendment 1 */ #define CKM_HOTP_KEY_GEN 0x00000290 #define CKM_HOTP 0x00000291 /* ACTI is new for PKCS #11 v2.20 amendment 1 */ #define CKM_ACTI 0x000002A0 #define CKM_ACTI_KEY_GEN 0x000002A1 /* All of the following mechanisms are new for v2.0 */ /* Note that CAST128 and CAST5 are the same algorithm */ #define CKM_CAST_KEY_GEN 0x00000300 #define CKM_CAST_ECB 0x00000301 #define CKM_CAST_CBC 0x00000302 #define CKM_CAST_MAC 0x00000303 #define CKM_CAST_MAC_GENERAL 0x00000304 #define CKM_CAST_CBC_PAD 0x00000305 #define CKM_CAST3_KEY_GEN 0x00000310 #define CKM_CAST3_ECB 0x00000311 #define CKM_CAST3_CBC 0x00000312 #define CKM_CAST3_MAC 0x00000313 #define CKM_CAST3_MAC_GENERAL 0x00000314 #define CKM_CAST3_CBC_PAD 0x00000315 #define CKM_CAST5_KEY_GEN 0x00000320 #define CKM_CAST128_KEY_GEN 0x00000320 #define CKM_CAST5_ECB 0x00000321 #define CKM_CAST128_ECB 0x00000321 #define CKM_CAST5_CBC 0x00000322 #define CKM_CAST128_CBC 0x00000322 #define CKM_CAST5_MAC 0x00000323 #define CKM_CAST128_MAC 0x00000323 #define CKM_CAST5_MAC_GENERAL 0x00000324 #define CKM_CAST128_MAC_GENERAL 0x00000324 #define CKM_CAST5_CBC_PAD 0x00000325 #define CKM_CAST128_CBC_PAD 0x00000325 #define CKM_RC5_KEY_GEN 0x00000330 #define CKM_RC5_ECB 0x00000331 #define CKM_RC5_CBC 0x00000332 #define CKM_RC5_MAC 0x00000333 #define CKM_RC5_MAC_GENERAL 0x00000334 #define CKM_RC5_CBC_PAD 0x00000335 #define CKM_IDEA_KEY_GEN 0x00000340 #define CKM_IDEA_ECB 0x00000341 #define CKM_IDEA_CBC 0x00000342 #define CKM_IDEA_MAC 0x00000343 #define CKM_IDEA_MAC_GENERAL 0x00000344 #define CKM_IDEA_CBC_PAD 0x00000345 #define CKM_GENERIC_SECRET_KEY_GEN 0x00000350 #define CKM_CONCATENATE_BASE_AND_KEY 0x00000360 #define CKM_CONCATENATE_BASE_AND_DATA 0x00000362 #define CKM_CONCATENATE_DATA_AND_BASE 0x00000363 #define CKM_XOR_BASE_AND_DATA 0x00000364 #define CKM_EXTRACT_KEY_FROM_KEY 0x00000365 #define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370 #define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371 #define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372 /* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN, * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */ #define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373 #define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374 #define CKM_TLS_MASTER_KEY_DERIVE 0x00000375 #define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376 #define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377 /* CKM_TLS_PRF is new for v2.20 */ #define CKM_TLS_PRF 0x00000378 #define CKM_SSL3_MD5_MAC 0x00000380 #define CKM_SSL3_SHA1_MAC 0x00000381 #define CKM_MD5_KEY_DERIVATION 0x00000390 #define CKM_MD2_KEY_DERIVATION 0x00000391 #define CKM_SHA1_KEY_DERIVATION 0x00000392 /* CKM_SHA256/384/512 are new for v2.20 */ #define CKM_SHA256_KEY_DERIVATION 0x00000393 #define CKM_SHA384_KEY_DERIVATION 0x00000394 #define CKM_SHA512_KEY_DERIVATION 0x00000395 /* SHA-224 key derivation is new for PKCS #11 v2.20 amendment 3 */ #define CKM_SHA224_KEY_DERIVATION 0x00000396 #define CKM_PBE_MD2_DES_CBC 0x000003A0 #define CKM_PBE_MD5_DES_CBC 0x000003A1 #define CKM_PBE_MD5_CAST_CBC 0x000003A2 #define CKM_PBE_MD5_CAST3_CBC 0x000003A3 #define CKM_PBE_MD5_CAST5_CBC 0x000003A4 #define CKM_PBE_MD5_CAST128_CBC 0x000003A4 #define CKM_PBE_SHA1_CAST5_CBC 0x000003A5 #define CKM_PBE_SHA1_CAST128_CBC 0x000003A5 #define CKM_PBE_SHA1_RC4_128 0x000003A6 #define CKM_PBE_SHA1_RC4_40 0x000003A7 #define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8 #define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9 #define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA #define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB /* CKM_PKCS5_PBKD2 is new for v2.10 */ #define CKM_PKCS5_PBKD2 0x000003B0 #define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0 /* WTLS mechanisms are new for v2.20 */ #define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0 #define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1 #define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2 #define CKM_WTLS_PRF 0x000003D3 #define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4 #define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5 #define CKM_KEY_WRAP_LYNKS 0x00000400 #define CKM_KEY_WRAP_SET_OAEP 0x00000401 /* CKM_CMS_SIG is new for v2.20 */ #define CKM_CMS_SIG 0x00000500 /* CKM_KIP mechanisms are new for PKCS #11 v2.20 amendment 2 */ #define CKM_KIP_DERIVE 0x00000510 #define CKM_KIP_WRAP 0x00000511 #define CKM_KIP_MAC 0x00000512 /* Camellia is new for PKCS #11 v2.20 amendment 3 */ #define CKM_CAMELLIA_KEY_GEN 0x00000550 #define CKM_CAMELLIA_ECB 0x00000551 #define CKM_CAMELLIA_CBC 0x00000552 #define CKM_CAMELLIA_MAC 0x00000553 #define CKM_CAMELLIA_MAC_GENERAL 0x00000554 #define CKM_CAMELLIA_CBC_PAD 0x00000555 #define CKM_CAMELLIA_ECB_ENCRYPT_DATA 0x00000556 #define CKM_CAMELLIA_CBC_ENCRYPT_DATA 0x00000557 #define CKM_CAMELLIA_CTR 0x00000558 /* ARIA is new for PKCS #11 v2.20 amendment 3 */ #define CKM_ARIA_KEY_GEN 0x00000560 #define CKM_ARIA_ECB 0x00000561 #define CKM_ARIA_CBC 0x00000562 #define CKM_ARIA_MAC 0x00000563 #define CKM_ARIA_MAC_GENERAL 0x00000564 #define CKM_ARIA_CBC_PAD 0x00000565 #define CKM_ARIA_ECB_ENCRYPT_DATA 0x00000566 #define CKM_ARIA_CBC_ENCRYPT_DATA 0x00000567 /* SEED is new from PKCS #11 v2.30? */ #define CKM_SEED_KEY_GEN 0x00000650 #define CKM_SEED_ECB 0x00000651 #define CKM_SEED_CBC 0x00000652 #define CKM_SEED_MAC 0x00000653 #define CKM_SEED_MAC_GENERAL 0x00000654 #define CKM_SEED_CBC_PAD 0x00000655 #define CKM_SEED_ECB_ENCRYPT_DATA 0x00000656 #define CKM_SEED_CBC_ENCRYPT_DATA 0x00000657 /* Fortezza mechanisms */ #define CKM_SKIPJACK_KEY_GEN 0x00001000 #define CKM_SKIPJACK_ECB64 0x00001001 #define CKM_SKIPJACK_CBC64 0x00001002 #define CKM_SKIPJACK_OFB64 0x00001003 #define CKM_SKIPJACK_CFB64 0x00001004 #define CKM_SKIPJACK_CFB32 0x00001005 #define CKM_SKIPJACK_CFB16 0x00001006 #define CKM_SKIPJACK_CFB8 0x00001007 #define CKM_SKIPJACK_WRAP 0x00001008 #define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009 #define CKM_SKIPJACK_RELAYX 0x0000100a #define CKM_KEA_KEY_PAIR_GEN 0x00001010 #define CKM_KEA_KEY_DERIVE 0x00001011 #define CKM_FORTEZZA_TIMESTAMP 0x00001020 #define CKM_BATON_KEY_GEN 0x00001030 #define CKM_BATON_ECB128 0x00001031 #define CKM_BATON_ECB96 0x00001032 #define CKM_BATON_CBC128 0x00001033 #define CKM_BATON_COUNTER 0x00001034 #define CKM_BATON_SHUFFLE 0x00001035 #define CKM_BATON_WRAP 0x00001036 /* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11, * CKM_EC_KEY_PAIR_GEN is preferred */ #define CKM_ECDSA_KEY_PAIR_GEN 0x00001040 #define CKM_EC_KEY_PAIR_GEN 0x00001040 #define CKM_ECDSA 0x00001041 #define CKM_ECDSA_SHA1 0x00001042 /* From v2.30? */ #define CKM_ECDSA_SHA224 0x00001043 #define CKM_ECDSA_SHA256 0x00001044 #define CKM_ECDSA_SHA384 0x00001045 #define CKM_ECDSA_SHA512 0x00001046 /* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE * are new for v2.11 */ #define CKM_ECDH1_DERIVE 0x00001050 #define CKM_ECDH1_COFACTOR_DERIVE 0x00001051 #define CKM_ECMQV_DERIVE 0x00001052 #define CKM_JUNIPER_KEY_GEN 0x00001060 #define CKM_JUNIPER_ECB128 0x00001061 #define CKM_JUNIPER_CBC128 0x00001062 #define CKM_JUNIPER_COUNTER 0x00001063 #define CKM_JUNIPER_SHUFFLE 0x00001064 #define CKM_JUNIPER_WRAP 0x00001065 #define CKM_FASTHASH 0x00001070 /* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC, * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN, * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are * new for v2.11 */ #define CKM_AES_KEY_GEN 0x00001080 #define CKM_AES_ECB 0x00001081 #define CKM_AES_CBC 0x00001082 #define CKM_AES_MAC 0x00001083 #define CKM_AES_MAC_GENERAL 0x00001084 #define CKM_AES_CBC_PAD 0x00001085 /* AES counter mode is new for PKCS #11 v2.20 amendment 3 */ #define CKM_AES_CTR 0x00001086 /* Missing CKM_AES_GCM and co! */ /* BlowFish and TwoFish are new for v2.20 */ #define CKM_BLOWFISH_KEY_GEN 0x00001090 #define CKM_BLOWFISH_CBC 0x00001091 #define CKM_TWOFISH_KEY_GEN 0x00001092 #define CKM_TWOFISH_CBC 0x00001093 /* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */ #define CKM_DES_ECB_ENCRYPT_DATA 0x00001100 #define CKM_DES_CBC_ENCRYPT_DATA 0x00001101 #define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102 #define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103 #define CKM_AES_ECB_ENCRYPT_DATA 0x00001104 #define CKM_AES_CBC_ENCRYPT_DATA 0x00001105 /* GOST mechanism from v2.30? */ #define CKM_GOSTR3410_KEY_PAIR_GEN 0x00001200 #define CKM_GOSTR3410 0x00001201 #define CKM_GOSTR3410_WITH_GOSTR3411 0x00001202 #define CKM_GOSTR3410_KEY_WRAP 0x00001203 #define CKM_GOSTR3410_DERIVE 0x00001204 #define CKM_GOSTR3411 0x00001210 #define CKM_GOSTR3411_HMAC 0x00001211 #define CKM_GOST28147_KEY_GEN 0x00001220 #define CKM_GOST28147_ECB 0x00001221 #define CKM_GOST28147 0x00001222 #define CKM_GOST28147_MAC 0x00001223 #define CKM_GOST28147_KEY_WRAP 0x00001224 #define CKM_DSA_PARAMETER_GEN 0x00002000 #define CKM_DH_PKCS_PARAMETER_GEN 0x00002001 #define CKM_X9_42_DH_PARAMETER_GEN 0x00002002 /* Missing AES_OFB and co, and RSA_PKCS 1_1 */ #define CKM_VENDOR_DEFINED 0x80000000 typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR; /* CK_MECHANISM is a structure that specifies a particular * mechanism */ typedef struct CK_MECHANISM { CK_MECHANISM_TYPE mechanism; CK_VOID_PTR pParameter; /* ulParameterLen was changed from CK_USHORT to CK_ULONG for * v2.0 */ CK_ULONG ulParameterLen; /* in bytes */ } CK_MECHANISM; typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR; /* CK_MECHANISM_INFO provides information about a particular * mechanism */ typedef struct CK_MECHANISM_INFO { CK_ULONG ulMinKeySize; CK_ULONG ulMaxKeySize; CK_FLAGS flags; } CK_MECHANISM_INFO; /* The flags are defined as follows: * Bit Flag Mask Meaning */ #define CKF_HW 0x00000001 /* performed by HW */ /* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN, * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER, * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP, * and CKF_DERIVE are new for v2.0. They specify whether or not * a mechanism can be used for a particular task */ #define CKF_ENCRYPT 0x00000100 #define CKF_DECRYPT 0x00000200 #define CKF_DIGEST 0x00000400 #define CKF_SIGN 0x00000800 #define CKF_SIGN_RECOVER 0x00001000 #define CKF_VERIFY 0x00002000 #define CKF_VERIFY_RECOVER 0x00004000 #define CKF_GENERATE 0x00008000 #define CKF_GENERATE_KEY_PAIR 0x00010000 #define CKF_WRAP 0x00020000 #define CKF_UNWRAP 0x00040000 #define CKF_DERIVE 0x00080000 /* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE, * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They * describe a token's EC capabilities not available in mechanism * information. */ #define CKF_EC_F_P 0x00100000 #define CKF_EC_F_2M 0x00200000 #define CKF_EC_ECPARAMETERS 0x00400000 #define CKF_EC_NAMEDCURVE 0x00800000 #define CKF_EC_UNCOMPRESS 0x01000000 #define CKF_EC_COMPRESS 0x02000000 #define CKF_EXTENSION 0x80000000 /* FALSE for this version */ typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR; /* CK_RV is a value that identifies the return value of a * Cryptoki function */ /* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */ typedef CK_ULONG CK_RV; #define CKR_OK 0x00000000 #define CKR_CANCEL 0x00000001 #define CKR_HOST_MEMORY 0x00000002 #define CKR_SLOT_ID_INVALID 0x00000003 /* CKR_FLAGS_INVALID was removed for v2.0 */ /* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */ #define CKR_GENERAL_ERROR 0x00000005 #define CKR_FUNCTION_FAILED 0x00000006 /* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS, * and CKR_CANT_LOCK are new for v2.01 */ #define CKR_ARGUMENTS_BAD 0x00000007 #define CKR_NO_EVENT 0x00000008 #define CKR_NEED_TO_CREATE_THREADS 0x00000009 #define CKR_CANT_LOCK 0x0000000A #define CKR_ATTRIBUTE_READ_ONLY 0x00000010 #define CKR_ATTRIBUTE_SENSITIVE 0x00000011 #define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012 #define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013 /* New CKR_COPY_PROHIBITED in v2.30? */ #define CKR_COPY_PROHIBITED 0x0000001A #define CKR_DATA_INVALID 0x00000020 #define CKR_DATA_LEN_RANGE 0x00000021 #define CKR_DEVICE_ERROR 0x00000030 #define CKR_DEVICE_MEMORY 0x00000031 #define CKR_DEVICE_REMOVED 0x00000032 #define CKR_ENCRYPTED_DATA_INVALID 0x00000040 #define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041 #define CKR_FUNCTION_CANCELED 0x00000050 #define CKR_FUNCTION_NOT_PARALLEL 0x00000051 /* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */ #define CKR_FUNCTION_NOT_SUPPORTED 0x00000054 #define CKR_KEY_HANDLE_INVALID 0x00000060 /* CKR_KEY_SENSITIVE was removed for v2.0 */ #define CKR_KEY_SIZE_RANGE 0x00000062 #define CKR_KEY_TYPE_INCONSISTENT 0x00000063 /* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED, * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED, * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for * v2.0 */ #define CKR_KEY_NOT_NEEDED 0x00000064 #define CKR_KEY_CHANGED 0x00000065 #define CKR_KEY_NEEDED 0x00000066 #define CKR_KEY_INDIGESTIBLE 0x00000067 #define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068 #define CKR_KEY_NOT_WRAPPABLE 0x00000069 #define CKR_KEY_UNEXTRACTABLE 0x0000006A #define CKR_MECHANISM_INVALID 0x00000070 #define CKR_MECHANISM_PARAM_INVALID 0x00000071 /* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID * were removed for v2.0 */ #define CKR_OBJECT_HANDLE_INVALID 0x00000082 #define CKR_OPERATION_ACTIVE 0x00000090 #define CKR_OPERATION_NOT_INITIALIZED 0x00000091 #define CKR_PIN_INCORRECT 0x000000A0 #define CKR_PIN_INVALID 0x000000A1 #define CKR_PIN_LEN_RANGE 0x000000A2 /* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */ #define CKR_PIN_EXPIRED 0x000000A3 #define CKR_PIN_LOCKED 0x000000A4 #define CKR_SESSION_CLOSED 0x000000B0 #define CKR_SESSION_COUNT 0x000000B1 #define CKR_SESSION_HANDLE_INVALID 0x000000B3 #define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4 #define CKR_SESSION_READ_ONLY 0x000000B5 #define CKR_SESSION_EXISTS 0x000000B6 /* CKR_SESSION_READ_ONLY_EXISTS and * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */ #define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7 #define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8 #define CKR_SIGNATURE_INVALID 0x000000C0 #define CKR_SIGNATURE_LEN_RANGE 0x000000C1 #define CKR_TEMPLATE_INCOMPLETE 0x000000D0 #define CKR_TEMPLATE_INCONSISTENT 0x000000D1 #define CKR_TOKEN_NOT_PRESENT 0x000000E0 #define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1 #define CKR_TOKEN_WRITE_PROTECTED 0x000000E2 #define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0 #define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1 #define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2 /* private extra values */ #define CKR_LIBRARY_ALREADY_INITIALIZED 0x000000FD #define CKR_LIBRARY_FAILED_TO_LOAD 0x000000FE #define CKR_SYMBOL_RESOLUTION_FAILED 0x000000FF #define CKR_USER_ALREADY_LOGGED_IN 0x00000100 #define CKR_USER_NOT_LOGGED_IN 0x00000101 #define CKR_USER_PIN_NOT_INITIALIZED 0x00000102 #define CKR_USER_TYPE_INVALID 0x00000103 /* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES * are new to v2.01 */ #define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104 #define CKR_USER_TOO_MANY_TYPES 0x00000105 #define CKR_WRAPPED_KEY_INVALID 0x00000110 #define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112 #define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113 #define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114 #define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115 #define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120 /* These are new to v2.0 */ #define CKR_RANDOM_NO_RNG 0x00000121 /* These are new to v2.11 */ #define CKR_DOMAIN_PARAMS_INVALID 0x00000130 /* These are new to v2.0 */ #define CKR_BUFFER_TOO_SMALL 0x00000150 #define CKR_SAVED_STATE_INVALID 0x00000160 #define CKR_INFORMATION_SENSITIVE 0x00000170 #define CKR_STATE_UNSAVEABLE 0x00000180 /* These are new to v2.01 */ #define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190 #define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191 #define CKR_MUTEX_BAD 0x000001A0 #define CKR_MUTEX_NOT_LOCKED 0x000001A1 /* The following return values are new for PKCS #11 v2.20 amendment 3 */ #define CKR_NEW_PIN_MODE 0x000001B0 #define CKR_NEXT_OTP 0x000001B1 /* New from v2.30? */ #define CKR_EXCEEDED_MAX_ITERATIONS 0x000001B5 #define CKR_FIPS_SELF_TEST_FAILED 0x000001B6 #define CKR_LIBRARY_LOAD_FAILED 0x000001B7 #define CKR_PIN_TOO_WEAK 0x000001B8 #define CKR_PUBLIC_KEY_INVALID 0x000001B9 /* This is new to v2.20 */ #define CKR_FUNCTION_REJECTED 0x00000200 #define CKR_VENDOR_DEFINED 0x80000000 /* CK_NOTIFY is an application callback that processes events */ typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_NOTIFICATION event, CK_VOID_PTR pApplication /* passed to C_OpenSession */ ); /* CK_FUNCTION_LIST is a structure holding a Cryptoki spec * version and pointers of appropriate types to all the * Cryptoki functions */ /* CK_FUNCTION_LIST is new for v2.0 */ typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST; typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR; typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR; /* CK_CREATEMUTEX is an application callback for creating a * mutex object */ typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)( CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */ ); /* CK_DESTROYMUTEX is an application callback for destroying a * mutex object */ typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)( CK_VOID_PTR pMutex /* pointer to mutex */ ); /* CK_LOCKMUTEX is an application callback for locking a mutex */ typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)( CK_VOID_PTR pMutex /* pointer to mutex */ ); /* CK_UNLOCKMUTEX is an application callback for unlocking a * mutex */ typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)( CK_VOID_PTR pMutex /* pointer to mutex */ ); /* CK_C_INITIALIZE_ARGS provides the optional arguments to * C_Initialize */ typedef struct CK_C_INITIALIZE_ARGS { CK_CREATEMUTEX CreateMutex; CK_DESTROYMUTEX DestroyMutex; CK_LOCKMUTEX LockMutex; CK_UNLOCKMUTEX UnlockMutex; CK_FLAGS flags; CK_VOID_PTR pReserved; } CK_C_INITIALIZE_ARGS; /* flags: bit flags that provide capabilities of the slot * Bit Flag Mask Meaning */ #define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001 #define CKF_OS_LOCKING_OK 0x00000002 typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR; /* additional flags for parameters to functions */ /* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */ #define CKF_DONT_BLOCK 1 /* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10. * CK_RSA_PKCS_OAEP_MGF_TYPE is used to indicate the Message * Generation Function (MGF) applied to a message block when * formatting a message block for the PKCS #1 OAEP encryption * scheme. */ typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE; typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR; /* The following MGFs are defined */ /* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512 * are new for v2.20 */ #define CKG_MGF1_SHA1 0x00000001 #define CKG_MGF1_SHA256 0x00000002 #define CKG_MGF1_SHA384 0x00000003 #define CKG_MGF1_SHA512 0x00000004 /* SHA-224 is new for PKCS #11 v2.20 amendment 3 */ #define CKG_MGF1_SHA224 0x00000005 /* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10. * CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source * of the encoding parameter when formatting a message block * for the PKCS #1 OAEP encryption scheme. */ typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE; typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR; /* The following encoding parameter sources are defined */ #define CKZ_DATA_SPECIFIED 0x00000001 /* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10. * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the * CKM_RSA_PKCS_OAEP mechanism. */ typedef struct CK_RSA_PKCS_OAEP_PARAMS { CK_MECHANISM_TYPE hashAlg; CK_RSA_PKCS_MGF_TYPE mgf; CK_RSA_PKCS_OAEP_SOURCE_TYPE source; CK_VOID_PTR pSourceData; CK_ULONG ulSourceDataLen; } CK_RSA_PKCS_OAEP_PARAMS; typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR; /* CK_RSA_PKCS_PSS_PARAMS is new for v2.11. * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the * CKM_RSA_PKCS_PSS mechanism(s). */ typedef struct CK_RSA_PKCS_PSS_PARAMS { CK_MECHANISM_TYPE hashAlg; CK_RSA_PKCS_MGF_TYPE mgf; CK_ULONG sLen; } CK_RSA_PKCS_PSS_PARAMS; typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR; /* CK_EC_KDF_TYPE is new for v2.11. */ typedef CK_ULONG CK_EC_KDF_TYPE; /* The following EC Key Derivation Functions are defined */ #define CKD_NULL 0x00000001 #define CKD_SHA1_KDF 0x00000002 /* CK_ECDH1_DERIVE_PARAMS is new for v2.11. * CK_ECDH1_DERIVE_PARAMS provides the parameters to the * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms, * where each party contributes one key pair. */ typedef struct CK_ECDH1_DERIVE_PARAMS { CK_EC_KDF_TYPE kdf; CK_ULONG ulSharedDataLen; CK_BYTE_PTR pSharedData; CK_ULONG ulPublicDataLen; CK_BYTE_PTR pPublicData; } CK_ECDH1_DERIVE_PARAMS; typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR; /* CK_ECDH2_DERIVE_PARAMS is new for v2.11. * CK_ECDH2_DERIVE_PARAMS provides the parameters to the * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */ typedef struct CK_ECDH2_DERIVE_PARAMS { CK_EC_KDF_TYPE kdf; CK_ULONG ulSharedDataLen; CK_BYTE_PTR pSharedData; CK_ULONG ulPublicDataLen; CK_BYTE_PTR pPublicData; CK_ULONG ulPrivateDataLen; CK_OBJECT_HANDLE hPrivateData; CK_ULONG ulPublicDataLen2; CK_BYTE_PTR pPublicData2; } CK_ECDH2_DERIVE_PARAMS; typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR; typedef struct CK_ECMQV_DERIVE_PARAMS { CK_EC_KDF_TYPE kdf; CK_ULONG ulSharedDataLen; CK_BYTE_PTR pSharedData; CK_ULONG ulPublicDataLen; CK_BYTE_PTR pPublicData; CK_ULONG ulPrivateDataLen; CK_OBJECT_HANDLE hPrivateData; CK_ULONG ulPublicDataLen2; CK_BYTE_PTR pPublicData2; CK_OBJECT_HANDLE publicKey; } CK_ECMQV_DERIVE_PARAMS; typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR; /* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */ typedef CK_ULONG CK_X9_42_DH_KDF_TYPE; typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR; /* The following X9.42 DH key derivation functions are defined (besides CKD_NULL already defined : */ #define CKD_SHA1_KDF_ASN1 0x00000003 #define CKD_SHA1_KDF_CONCATENATE 0x00000004 /* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11. * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party * contributes one key pair */ typedef struct CK_X9_42_DH1_DERIVE_PARAMS { CK_X9_42_DH_KDF_TYPE kdf; CK_ULONG ulOtherInfoLen; CK_BYTE_PTR pOtherInfo; CK_ULONG ulPublicDataLen; CK_BYTE_PTR pPublicData; } CK_X9_42_DH1_DERIVE_PARAMS; typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR; /* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11. * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation * mechanisms, where each party contributes two key pairs */ typedef struct CK_X9_42_DH2_DERIVE_PARAMS { CK_X9_42_DH_KDF_TYPE kdf; CK_ULONG ulOtherInfoLen; CK_BYTE_PTR pOtherInfo; CK_ULONG ulPublicDataLen; CK_BYTE_PTR pPublicData; CK_ULONG ulPrivateDataLen; CK_OBJECT_HANDLE hPrivateData; CK_ULONG ulPublicDataLen2; CK_BYTE_PTR pPublicData2; } CK_X9_42_DH2_DERIVE_PARAMS; typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR; typedef struct CK_X9_42_MQV_DERIVE_PARAMS { CK_X9_42_DH_KDF_TYPE kdf; CK_ULONG ulOtherInfoLen; CK_BYTE_PTR pOtherInfo; CK_ULONG ulPublicDataLen; CK_BYTE_PTR pPublicData; CK_ULONG ulPrivateDataLen; CK_OBJECT_HANDLE hPrivateData; CK_ULONG ulPublicDataLen2; CK_BYTE_PTR pPublicData2; CK_OBJECT_HANDLE publicKey; } CK_X9_42_MQV_DERIVE_PARAMS; typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR; /* CK_KEA_DERIVE_PARAMS provides the parameters to the * CKM_KEA_DERIVE mechanism */ /* CK_KEA_DERIVE_PARAMS is new for v2.0 */ typedef struct CK_KEA_DERIVE_PARAMS { CK_BBOOL isSender; CK_ULONG ulRandomLen; CK_BYTE_PTR pRandomA; CK_BYTE_PTR pRandomB; CK_ULONG ulPublicDataLen; CK_BYTE_PTR pPublicData; } CK_KEA_DERIVE_PARAMS; typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR; /* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just * holds the effective keysize */ typedef CK_ULONG CK_RC2_PARAMS; typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR; /* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC * mechanism */ typedef struct CK_RC2_CBC_PARAMS { /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for * v2.0 */ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ CK_BYTE iv[8]; /* IV for CBC mode */ } CK_RC2_CBC_PARAMS; typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR; /* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the * CKM_RC2_MAC_GENERAL mechanism */ /* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */ typedef struct CK_RC2_MAC_GENERAL_PARAMS { CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ CK_ULONG ulMacLength; /* Length of MAC in bytes */ } CK_RC2_MAC_GENERAL_PARAMS; typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \ CK_RC2_MAC_GENERAL_PARAMS_PTR; /* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and * CKM_RC5_MAC mechanisms */ /* CK_RC5_PARAMS is new for v2.0 */ typedef struct CK_RC5_PARAMS { CK_ULONG ulWordsize; /* wordsize in bits */ CK_ULONG ulRounds; /* number of rounds */ } CK_RC5_PARAMS; typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR; /* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC * mechanism */ /* CK_RC5_CBC_PARAMS is new for v2.0 */ typedef struct CK_RC5_CBC_PARAMS { CK_ULONG ulWordsize; /* wordsize in bits */ CK_ULONG ulRounds; /* number of rounds */ CK_BYTE_PTR pIv; /* pointer to IV */ CK_ULONG ulIvLen; /* length of IV in bytes */ } CK_RC5_CBC_PARAMS; typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR; /* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the * CKM_RC5_MAC_GENERAL mechanism */ /* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */ typedef struct CK_RC5_MAC_GENERAL_PARAMS { CK_ULONG ulWordsize; /* wordsize in bits */ CK_ULONG ulRounds; /* number of rounds */ CK_ULONG ulMacLength; /* Length of MAC in bytes */ } CK_RC5_MAC_GENERAL_PARAMS; typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \ CK_RC5_MAC_GENERAL_PARAMS_PTR; /* CK_MAC_GENERAL_PARAMS provides the parameters to most block * ciphers' MAC_GENERAL mechanisms. Its value is the length of * the MAC */ /* CK_MAC_GENERAL_PARAMS is new for v2.0 */ typedef CK_ULONG CK_MAC_GENERAL_PARAMS; typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR; /* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */ typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS { CK_BYTE iv[8]; CK_BYTE_PTR pData; CK_ULONG length; } CK_DES_CBC_ENCRYPT_DATA_PARAMS; typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR; typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS { CK_BYTE iv[16]; CK_BYTE_PTR pData; CK_ULONG length; } CK_AES_CBC_ENCRYPT_DATA_PARAMS; typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR; /* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the * CKM_SKIPJACK_PRIVATE_WRAP mechanism */ /* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */ typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS { CK_ULONG ulPasswordLen; CK_BYTE_PTR pPassword; CK_ULONG ulPublicDataLen; CK_BYTE_PTR pPublicData; CK_ULONG ulPAndGLen; CK_ULONG ulQLen; CK_ULONG ulRandomLen; CK_BYTE_PTR pRandomA; CK_BYTE_PTR pPrimeP; CK_BYTE_PTR pBaseG; CK_BYTE_PTR pSubprimeQ; } CK_SKIPJACK_PRIVATE_WRAP_PARAMS; typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \ CK_SKIPJACK_PRIVATE_WRAP_PTR; /* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the * CKM_SKIPJACK_RELAYX mechanism */ /* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */ typedef struct CK_SKIPJACK_RELAYX_PARAMS { CK_ULONG ulOldWrappedXLen; CK_BYTE_PTR pOldWrappedX; CK_ULONG ulOldPasswordLen; CK_BYTE_PTR pOldPassword; CK_ULONG ulOldPublicDataLen; CK_BYTE_PTR pOldPublicData; CK_ULONG ulOldRandomLen; CK_BYTE_PTR pOldRandomA; CK_ULONG ulNewPasswordLen; CK_BYTE_PTR pNewPassword; CK_ULONG ulNewPublicDataLen; CK_BYTE_PTR pNewPublicData; CK_ULONG ulNewRandomLen; CK_BYTE_PTR pNewRandomA; } CK_SKIPJACK_RELAYX_PARAMS; typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \ CK_SKIPJACK_RELAYX_PARAMS_PTR; typedef struct CK_PBE_PARAMS { CK_BYTE_PTR pInitVector; CK_UTF8CHAR_PTR pPassword; CK_ULONG ulPasswordLen; CK_BYTE_PTR pSalt; CK_ULONG ulSaltLen; CK_ULONG ulIteration; } CK_PBE_PARAMS; typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR; /* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the * CKM_KEY_WRAP_SET_OAEP mechanism */ /* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */ typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS { CK_BYTE bBC; /* block contents byte */ CK_BYTE_PTR pX; /* extra data */ CK_ULONG ulXLen; /* length of extra data in bytes */ } CK_KEY_WRAP_SET_OAEP_PARAMS; typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \ CK_KEY_WRAP_SET_OAEP_PARAMS_PTR; typedef struct CK_SSL3_RANDOM_DATA { CK_BYTE_PTR pClientRandom; CK_ULONG ulClientRandomLen; CK_BYTE_PTR pServerRandom; CK_ULONG ulServerRandomLen; } CK_SSL3_RANDOM_DATA; typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS { CK_SSL3_RANDOM_DATA RandomInfo; CK_VERSION_PTR pVersion; } CK_SSL3_MASTER_KEY_DERIVE_PARAMS; typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \ CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR; typedef struct CK_SSL3_KEY_MAT_OUT { CK_OBJECT_HANDLE hClientMacSecret; CK_OBJECT_HANDLE hServerMacSecret; CK_OBJECT_HANDLE hClientKey; CK_OBJECT_HANDLE hServerKey; CK_BYTE_PTR pIVClient; CK_BYTE_PTR pIVServer; } CK_SSL3_KEY_MAT_OUT; typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR; typedef struct CK_SSL3_KEY_MAT_PARAMS { CK_ULONG ulMacSizeInBits; CK_ULONG ulKeySizeInBits; CK_ULONG ulIVSizeInBits; CK_BBOOL bIsExport; CK_SSL3_RANDOM_DATA RandomInfo; CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial; } CK_SSL3_KEY_MAT_PARAMS; typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR; /* CK_TLS_PRF_PARAMS is new for version 2.20 */ typedef struct CK_TLS_PRF_PARAMS { CK_BYTE_PTR pSeed; CK_ULONG ulSeedLen; CK_BYTE_PTR pLabel; CK_ULONG ulLabelLen; CK_BYTE_PTR pOutput; CK_ULONG_PTR pulOutputLen; } CK_TLS_PRF_PARAMS; typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR; /* WTLS is new for version 2.20 */ typedef struct CK_WTLS_RANDOM_DATA { CK_BYTE_PTR pClientRandom; CK_ULONG ulClientRandomLen; CK_BYTE_PTR pServerRandom; CK_ULONG ulServerRandomLen; } CK_WTLS_RANDOM_DATA; typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR; typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS { CK_MECHANISM_TYPE DigestMechanism; CK_WTLS_RANDOM_DATA RandomInfo; CK_BYTE_PTR pVersion; } CK_WTLS_MASTER_KEY_DERIVE_PARAMS; typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \ CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR; typedef struct CK_WTLS_PRF_PARAMS { CK_MECHANISM_TYPE DigestMechanism; CK_BYTE_PTR pSeed; CK_ULONG ulSeedLen; CK_BYTE_PTR pLabel; CK_ULONG ulLabelLen; CK_BYTE_PTR pOutput; CK_ULONG_PTR pulOutputLen; } CK_WTLS_PRF_PARAMS; typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR; typedef struct CK_WTLS_KEY_MAT_OUT { CK_OBJECT_HANDLE hMacSecret; CK_OBJECT_HANDLE hKey; CK_BYTE_PTR pIV; } CK_WTLS_KEY_MAT_OUT; typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR; typedef struct CK_WTLS_KEY_MAT_PARAMS { CK_MECHANISM_TYPE DigestMechanism; CK_ULONG ulMacSizeInBits; CK_ULONG ulKeySizeInBits; CK_ULONG ulIVSizeInBits; CK_ULONG ulSequenceNumber; CK_BBOOL bIsExport; CK_WTLS_RANDOM_DATA RandomInfo; CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial; } CK_WTLS_KEY_MAT_PARAMS; typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR; /* CMS is new for version 2.20 */ typedef struct CK_CMS_SIG_PARAMS { CK_OBJECT_HANDLE certificateHandle; CK_MECHANISM_PTR pSigningMechanism; CK_MECHANISM_PTR pDigestMechanism; CK_UTF8CHAR_PTR pContentType; CK_BYTE_PTR pRequestedAttributes; CK_ULONG ulRequestedAttributesLen; CK_BYTE_PTR pRequiredAttributes; CK_ULONG ulRequiredAttributesLen; } CK_CMS_SIG_PARAMS; typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR; typedef struct CK_KEY_DERIVATION_STRING_DATA { CK_BYTE_PTR pData; CK_ULONG ulLen; } CK_KEY_DERIVATION_STRING_DATA; typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \ CK_KEY_DERIVATION_STRING_DATA_PTR; /* The CK_EXTRACT_PARAMS is used for the * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit * of the base key should be used as the first bit of the * derived key */ /* CK_EXTRACT_PARAMS is new for v2.0 */ typedef CK_ULONG CK_EXTRACT_PARAMS; typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR; /* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10. * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to * indicate the Pseudo-Random Function (PRF) used to generate * key bits using PKCS #5 PBKDF2. */ typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE; typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR; /* The following PRFs are defined in PKCS #5 v2.0. */ #define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001 /* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10. * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the * source of the salt value when deriving a key using PKCS #5 * PBKDF2. */ typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE; typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR; /* The following salt value sources are defined in PKCS #5 v2.0. */ #define CKZ_SALT_SPECIFIED 0x00000001 /* CK_PKCS5_PBKD2_PARAMS is new for v2.10. * CK_PKCS5_PBKD2_PARAMS is a structure that provides the * parameters to the CKM_PKCS5_PBKD2 mechanism. */ typedef struct CK_PKCS5_PBKD2_PARAMS { CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; CK_VOID_PTR pSaltSourceData; CK_ULONG ulSaltSourceDataLen; CK_ULONG iterations; CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf; CK_VOID_PTR pPrfData; CK_ULONG ulPrfDataLen; CK_UTF8CHAR_PTR pPassword; CK_ULONG_PTR ulPasswordLen; } CK_PKCS5_PBKD2_PARAMS; typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR; /* All CK_OTP structs are new for PKCS #11 v2.20 amendment 3 */ typedef CK_ULONG CK_OTP_PARAM_TYPE; typedef CK_OTP_PARAM_TYPE CK_PARAM_TYPE; /* B/w compatibility */ typedef struct CK_OTP_PARAM { CK_OTP_PARAM_TYPE type; CK_VOID_PTR pValue; CK_ULONG ulValueLen; } CK_OTP_PARAM; typedef CK_OTP_PARAM CK_PTR CK_OTP_PARAM_PTR; typedef struct CK_OTP_PARAMS { CK_OTP_PARAM_PTR pParams; CK_ULONG ulCount; } CK_OTP_PARAMS; typedef CK_OTP_PARAMS CK_PTR CK_OTP_PARAMS_PTR; typedef struct CK_OTP_SIGNATURE_INFO { CK_OTP_PARAM_PTR pParams; CK_ULONG ulCount; } CK_OTP_SIGNATURE_INFO; typedef CK_OTP_SIGNATURE_INFO CK_PTR CK_OTP_SIGNATURE_INFO_PTR; /* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */ #define CK_OTP_VALUE 0 #define CK_OTP_PIN 1 #define CK_OTP_CHALLENGE 2 #define CK_OTP_TIME 3 #define CK_OTP_COUNTER 4 #define CK_OTP_FLAGS 5 #define CK_OTP_OUTPUT_LENGTH 6 #define CK_OTP_OUTPUT_FORMAT 7 /* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */ #define CKF_NEXT_OTP 0x00000001 #define CKF_EXCLUDE_TIME 0x00000002 #define CKF_EXCLUDE_COUNTER 0x00000004 #define CKF_EXCLUDE_CHALLENGE 0x00000008 #define CKF_EXCLUDE_PIN 0x00000010 #define CKF_USER_FRIENDLY_OTP 0x00000020 /* CK_KIP_PARAMS is new for PKCS #11 v2.20 amendment 2 */ typedef struct CK_KIP_PARAMS { CK_MECHANISM_PTR pMechanism; CK_OBJECT_HANDLE hKey; CK_BYTE_PTR pSeed; CK_ULONG ulSeedLen; } CK_KIP_PARAMS; typedef CK_KIP_PARAMS CK_PTR CK_KIP_PARAMS_PTR; /* CK_AES_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */ typedef struct CK_AES_CTR_PARAMS { CK_ULONG ulCounterBits; CK_BYTE cb[16]; } CK_AES_CTR_PARAMS; typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR; /* CK_CAMELLIA_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */ typedef struct CK_CAMELLIA_CTR_PARAMS { CK_ULONG ulCounterBits; CK_BYTE cb[16]; } CK_CAMELLIA_CTR_PARAMS; typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR; /* CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */ typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS { CK_BYTE iv[16]; CK_BYTE_PTR pData; CK_ULONG length; } CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS; typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR; /* CK_ARIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */ typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS { CK_BYTE iv[16]; CK_BYTE_PTR pData; CK_ULONG length; } CK_ARIA_CBC_ENCRYPT_DATA_PARAMS; typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR; #endif bind9-9.10.3.dfsg.P4/lib/isc/include/pkcs11/pkcs11f.h0000644000470500017500000006727212664710322021101 0ustar lamontlamont/* pkcs11f.h include file for PKCS #11. */ /* $Revision: 1.2 $ */ /* License to copy and use this software is granted provided that it is * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface * (Cryptoki)" in all material mentioning or referencing this software. * License is also granted to make and use derivative works provided that * such works are identified as "derived from the RSA Security Inc. PKCS #11 * Cryptographic Token Interface (Cryptoki)" in all material mentioning or * referencing the derived work. * RSA Security Inc. makes no representations concerning either the * merchantability of this software or the suitability of this software for * any particular purpose. It is provided "as is" without express or implied * warranty of any kind. */ /* This header file contains pretty much everything about all the */ /* Cryptoki function prototypes. Because this information is */ /* used for more than just declaring function prototypes, the */ /* order of the functions appearing herein is important, and */ /* should not be altered. */ /* General-purpose */ /* C_Initialize initializes the Cryptoki library. */ CK_PKCS11_FUNCTION_INFO(C_Initialize) #ifdef CK_NEED_ARG_LIST ( CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets * cast to CK_C_INITIALIZE_ARGS_PTR * and dereferenced */ ); #endif /* C_Finalize indicates that an application is done with the * Cryptoki library. */ CK_PKCS11_FUNCTION_INFO(C_Finalize) #ifdef CK_NEED_ARG_LIST ( CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */ ); #endif /* C_GetInfo returns general information about Cryptoki. */ CK_PKCS11_FUNCTION_INFO(C_GetInfo) #ifdef CK_NEED_ARG_LIST ( CK_INFO_PTR pInfo /* location that receives information */ ); #endif /* C_GetFunctionList returns the function list. */ CK_PKCS11_FUNCTION_INFO(C_GetFunctionList) #ifdef CK_NEED_ARG_LIST ( CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to * function list */ ); #endif /* Slot and token management */ /* C_GetSlotList obtains a list of slots in the system. */ CK_PKCS11_FUNCTION_INFO(C_GetSlotList) #ifdef CK_NEED_ARG_LIST ( CK_BBOOL tokenPresent, /* only slots with tokens? */ CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */ CK_ULONG_PTR pulCount /* receives number of slots */ ); #endif /* C_GetSlotInfo obtains information about a particular slot in * the system. */ CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo) #ifdef CK_NEED_ARG_LIST ( CK_SLOT_ID slotID, /* the ID of the slot */ CK_SLOT_INFO_PTR pInfo /* receives the slot information */ ); #endif /* C_GetTokenInfo obtains information about a particular token * in the system. */ CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo) #ifdef CK_NEED_ARG_LIST ( CK_SLOT_ID slotID, /* ID of the token's slot */ CK_TOKEN_INFO_PTR pInfo /* receives the token information */ ); #endif /* C_GetMechanismList obtains a list of mechanism types * supported by a token. */ CK_PKCS11_FUNCTION_INFO(C_GetMechanismList) #ifdef CK_NEED_ARG_LIST ( CK_SLOT_ID slotID, /* ID of token's slot */ CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */ CK_ULONG_PTR pulCount /* gets # of mechs. */ ); #endif /* C_GetMechanismInfo obtains information about a particular * mechanism possibly supported by a token. */ CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo) #ifdef CK_NEED_ARG_LIST ( CK_SLOT_ID slotID, /* ID of the token's slot */ CK_MECHANISM_TYPE type, /* type of mechanism */ CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */ ); #endif /* C_InitToken initializes a token. */ CK_PKCS11_FUNCTION_INFO(C_InitToken) #ifdef CK_NEED_ARG_LIST /* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */ ( CK_SLOT_ID slotID, /* ID of the token's slot */ CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */ CK_ULONG ulPinLen, /* length in bytes of the PIN */ CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */ ); #endif /* C_InitPIN initializes the normal user's PIN. */ CK_PKCS11_FUNCTION_INFO(C_InitPIN) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */ CK_ULONG ulPinLen /* length in bytes of the PIN */ ); #endif /* C_SetPIN modifies the PIN of the user who is logged in. */ CK_PKCS11_FUNCTION_INFO(C_SetPIN) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_UTF8CHAR_PTR pOldPin, /* the old PIN */ CK_ULONG ulOldLen, /* length of the old PIN */ CK_UTF8CHAR_PTR pNewPin, /* the new PIN */ CK_ULONG ulNewLen /* length of the new PIN */ ); #endif /* Session management */ /* C_OpenSession opens a session between an application and a * token. */ CK_PKCS11_FUNCTION_INFO(C_OpenSession) #ifdef CK_NEED_ARG_LIST ( CK_SLOT_ID slotID, /* the slot's ID */ CK_FLAGS flags, /* from CK_SESSION_INFO */ CK_VOID_PTR pApplication, /* passed to callback */ CK_NOTIFY Notify, /* callback function */ CK_SESSION_HANDLE_PTR phSession /* gets session handle */ ); #endif /* C_CloseSession closes a session between an application and a * token. */ CK_PKCS11_FUNCTION_INFO(C_CloseSession) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession /* the session's handle */ ); #endif /* C_CloseAllSessions closes all sessions with a token. */ CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions) #ifdef CK_NEED_ARG_LIST ( CK_SLOT_ID slotID /* the token's slot */ ); #endif /* C_GetSessionInfo obtains information about the session. */ CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_SESSION_INFO_PTR pInfo /* receives session info */ ); #endif /* C_GetOperationState obtains the state of the cryptographic operation * in a session. */ CK_PKCS11_FUNCTION_INFO(C_GetOperationState) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* session's handle */ CK_BYTE_PTR pOperationState, /* gets state */ CK_ULONG_PTR pulOperationStateLen /* gets state length */ ); #endif /* C_SetOperationState restores the state of the cryptographic * operation in a session. */ CK_PKCS11_FUNCTION_INFO(C_SetOperationState) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* session's handle */ CK_BYTE_PTR pOperationState, /* holds state */ CK_ULONG ulOperationStateLen, /* holds state length */ CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */ CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */ ); #endif /* C_Login logs a user into a token. */ CK_PKCS11_FUNCTION_INFO(C_Login) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_USER_TYPE userType, /* the user type */ CK_UTF8CHAR_PTR pPin, /* the user's PIN */ CK_ULONG ulPinLen /* the length of the PIN */ ); #endif /* C_Logout logs a user out from a token. */ CK_PKCS11_FUNCTION_INFO(C_Logout) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession /* the session's handle */ ); #endif /* Object management */ /* C_CreateObject creates a new object. */ CK_PKCS11_FUNCTION_INFO(C_CreateObject) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_ATTRIBUTE_PTR pTemplate, /* the object's template */ CK_ULONG ulCount, /* attributes in template */ CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */ ); #endif /* C_CopyObject copies an object, creating a new object for the * copy. */ CK_PKCS11_FUNCTION_INFO(C_CopyObject) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_OBJECT_HANDLE hObject, /* the object's handle */ CK_ATTRIBUTE_PTR pTemplate, /* template for new object */ CK_ULONG ulCount, /* attributes in template */ CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */ ); #endif /* C_DestroyObject destroys an object. */ CK_PKCS11_FUNCTION_INFO(C_DestroyObject) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_OBJECT_HANDLE hObject /* the object's handle */ ); #endif /* C_GetObjectSize gets the size of an object in bytes. */ CK_PKCS11_FUNCTION_INFO(C_GetObjectSize) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_OBJECT_HANDLE hObject, /* the object's handle */ CK_ULONG_PTR pulSize /* receives size of object */ ); #endif /* C_GetAttributeValue obtains the value of one or more object * attributes. */ CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_OBJECT_HANDLE hObject, /* the object's handle */ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */ CK_ULONG ulCount /* attributes in template */ ); #endif /* C_SetAttributeValue modifies the value of one or more object * attributes */ CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_OBJECT_HANDLE hObject, /* the object's handle */ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */ CK_ULONG ulCount /* attributes in template */ ); #endif /* C_FindObjectsInit initializes a search for token and session * objects that match a template. */ CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */ CK_ULONG ulCount /* attrs in search template */ ); #endif /* C_FindObjects continues a search for token and session * objects that match a template, obtaining additional object * handles. */ CK_PKCS11_FUNCTION_INFO(C_FindObjects) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* session's handle */ CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */ CK_ULONG ulMaxObjectCount, /* max handles to get */ CK_ULONG_PTR pulObjectCount /* actual # returned */ ); #endif /* C_FindObjectsFinal finishes a search for token and session * objects. */ CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession /* the session's handle */ ); #endif /* Encryption and decryption */ /* C_EncryptInit initializes an encryption operation. */ CK_PKCS11_FUNCTION_INFO(C_EncryptInit) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */ CK_OBJECT_HANDLE hKey /* handle of encryption key */ ); #endif /* C_Encrypt encrypts single-part data. */ CK_PKCS11_FUNCTION_INFO(C_Encrypt) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* session's handle */ CK_BYTE_PTR pData, /* the plaintext data */ CK_ULONG ulDataLen, /* bytes of plaintext */ CK_BYTE_PTR pEncryptedData, /* gets ciphertext */ CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */ ); #endif /* C_EncryptUpdate continues a multiple-part encryption * operation. */ CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* session's handle */ CK_BYTE_PTR pPart, /* the plaintext data */ CK_ULONG ulPartLen, /* plaintext data len */ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */ ); #endif /* C_EncryptFinal finishes a multiple-part encryption * operation. */ CK_PKCS11_FUNCTION_INFO(C_EncryptFinal) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* session handle */ CK_BYTE_PTR pLastEncryptedPart, /* last c-text */ CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */ ); #endif /* C_DecryptInit initializes a decryption operation. */ CK_PKCS11_FUNCTION_INFO(C_DecryptInit) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */ CK_OBJECT_HANDLE hKey /* handle of decryption key */ ); #endif /* C_Decrypt decrypts encrypted data in a single part. */ CK_PKCS11_FUNCTION_INFO(C_Decrypt) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* session's handle */ CK_BYTE_PTR pEncryptedData, /* ciphertext */ CK_ULONG ulEncryptedDataLen, /* ciphertext length */ CK_BYTE_PTR pData, /* gets plaintext */ CK_ULONG_PTR pulDataLen /* gets p-text size */ ); #endif /* C_DecryptUpdate continues a multiple-part decryption * operation. */ CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* session's handle */ CK_BYTE_PTR pEncryptedPart, /* encrypted data */ CK_ULONG ulEncryptedPartLen, /* input length */ CK_BYTE_PTR pPart, /* gets plaintext */ CK_ULONG_PTR pulPartLen /* p-text size */ ); #endif /* C_DecryptFinal finishes a multiple-part decryption * operation. */ CK_PKCS11_FUNCTION_INFO(C_DecryptFinal) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pLastPart, /* gets plaintext */ CK_ULONG_PTR pulLastPartLen /* p-text size */ ); #endif /* Message digesting */ /* C_DigestInit initializes a message-digesting operation. */ CK_PKCS11_FUNCTION_INFO(C_DigestInit) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_MECHANISM_PTR pMechanism /* the digesting mechanism */ ); #endif /* C_Digest digests data in a single part. */ CK_PKCS11_FUNCTION_INFO(C_Digest) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pData, /* data to be digested */ CK_ULONG ulDataLen, /* bytes of data to digest */ CK_BYTE_PTR pDigest, /* gets the message digest */ CK_ULONG_PTR pulDigestLen /* gets digest length */ ); #endif /* C_DigestUpdate continues a multiple-part message-digesting * operation. */ CK_PKCS11_FUNCTION_INFO(C_DigestUpdate) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pPart, /* data to be digested */ CK_ULONG ulPartLen /* bytes of data to be digested */ ); #endif /* C_DigestKey continues a multi-part message-digesting * operation, by digesting the value of a secret key as part of * the data already digested. */ CK_PKCS11_FUNCTION_INFO(C_DigestKey) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_OBJECT_HANDLE hKey /* secret key to digest */ ); #endif /* C_DigestFinal finishes a multiple-part message-digesting * operation. */ CK_PKCS11_FUNCTION_INFO(C_DigestFinal) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pDigest, /* gets the message digest */ CK_ULONG_PTR pulDigestLen /* gets byte count of digest */ ); #endif /* Signing and MACing */ /* C_SignInit initializes a signature (private key encryption) * operation, where the signature is (will be) an appendix to * the data, and plaintext cannot be recovered from the *signature. */ CK_PKCS11_FUNCTION_INFO(C_SignInit) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ CK_OBJECT_HANDLE hKey /* handle of signature key */ ); #endif /* C_Sign signs (encrypts with private key) data in a single * part, where the signature is (will be) an appendix to the * data, and plaintext cannot be recovered from the signature. */ CK_PKCS11_FUNCTION_INFO(C_Sign) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pData, /* the data to sign */ CK_ULONG ulDataLen, /* count of bytes to sign */ CK_BYTE_PTR pSignature, /* gets the signature */ CK_ULONG_PTR pulSignatureLen /* gets signature length */ ); #endif /* C_SignUpdate continues a multiple-part signature operation, * where the signature is (will be) an appendix to the data, * and plaintext cannot be recovered from the signature. */ CK_PKCS11_FUNCTION_INFO(C_SignUpdate) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pPart, /* the data to sign */ CK_ULONG ulPartLen /* count of bytes to sign */ ); #endif /* C_SignFinal finishes a multiple-part signature operation, * returning the signature. */ CK_PKCS11_FUNCTION_INFO(C_SignFinal) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pSignature, /* gets the signature */ CK_ULONG_PTR pulSignatureLen /* gets signature length */ ); #endif /* C_SignRecoverInit initializes a signature operation, where * the data can be recovered from the signature. */ CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ CK_OBJECT_HANDLE hKey /* handle of the signature key */ ); #endif /* C_SignRecover signs data in a single operation, where the * data can be recovered from the signature. */ CK_PKCS11_FUNCTION_INFO(C_SignRecover) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pData, /* the data to sign */ CK_ULONG ulDataLen, /* count of bytes to sign */ CK_BYTE_PTR pSignature, /* gets the signature */ CK_ULONG_PTR pulSignatureLen /* gets signature length */ ); #endif /* Verifying signatures and MACs */ /* C_VerifyInit initializes a verification operation, where the * signature is an appendix to the data, and plaintext cannot * cannot be recovered from the signature (e.g. DSA). */ CK_PKCS11_FUNCTION_INFO(C_VerifyInit) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ CK_OBJECT_HANDLE hKey /* verification key */ ); #endif /* C_Verify verifies a signature in a single-part operation, * where the signature is an appendix to the data, and plaintext * cannot be recovered from the signature. */ CK_PKCS11_FUNCTION_INFO(C_Verify) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pData, /* signed data */ CK_ULONG ulDataLen, /* length of signed data */ CK_BYTE_PTR pSignature, /* signature */ CK_ULONG ulSignatureLen /* signature length*/ ); #endif /* C_VerifyUpdate continues a multiple-part verification * operation, where the signature is an appendix to the data, * and plaintext cannot be recovered from the signature. */ CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pPart, /* signed data */ CK_ULONG ulPartLen /* length of signed data */ ); #endif /* C_VerifyFinal finishes a multiple-part verification * operation, checking the signature. */ CK_PKCS11_FUNCTION_INFO(C_VerifyFinal) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pSignature, /* signature to verify */ CK_ULONG ulSignatureLen /* signature length */ ); #endif /* C_VerifyRecoverInit initializes a signature verification * operation, where the data is recovered from the signature. */ CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ CK_OBJECT_HANDLE hKey /* verification key */ ); #endif /* C_VerifyRecover verifies a signature in a single-part * operation, where the data is recovered from the signature. */ CK_PKCS11_FUNCTION_INFO(C_VerifyRecover) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pSignature, /* signature to verify */ CK_ULONG ulSignatureLen, /* signature length */ CK_BYTE_PTR pData, /* gets signed data */ CK_ULONG_PTR pulDataLen /* gets signed data len */ ); #endif /* Dual-function cryptographic operations */ /* C_DigestEncryptUpdate continues a multiple-part digesting * and encryption operation. */ CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* session's handle */ CK_BYTE_PTR pPart, /* the plaintext data */ CK_ULONG ulPartLen, /* plaintext length */ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */ ); #endif /* C_DecryptDigestUpdate continues a multiple-part decryption and * digesting operation. */ CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* session's handle */ CK_BYTE_PTR pEncryptedPart, /* ciphertext */ CK_ULONG ulEncryptedPartLen, /* ciphertext length */ CK_BYTE_PTR pPart, /* gets plaintext */ CK_ULONG_PTR pulPartLen /* gets plaintext len */ ); #endif /* C_SignEncryptUpdate continues a multiple-part signing and * encryption operation. */ CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* session's handle */ CK_BYTE_PTR pPart, /* the plaintext data */ CK_ULONG ulPartLen, /* plaintext length */ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */ ); #endif /* C_DecryptVerifyUpdate continues a multiple-part decryption and * verify operation. */ CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* session's handle */ CK_BYTE_PTR pEncryptedPart, /* ciphertext */ CK_ULONG ulEncryptedPartLen, /* ciphertext length */ CK_BYTE_PTR pPart, /* gets plaintext */ CK_ULONG_PTR pulPartLen /* gets p-text length */ ); #endif /* Key management */ /* C_GenerateKey generates a secret key, creating a new key * object. */ CK_PKCS11_FUNCTION_INFO(C_GenerateKey) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_MECHANISM_PTR pMechanism, /* key generation mech. */ CK_ATTRIBUTE_PTR pTemplate, /* template for new key */ CK_ULONG ulCount, /* # of attrs in template */ CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */ ); #endif /* C_GenerateKeyPair generates a public-key/private-key pair, * creating new key objects. */ CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* session * handle */ CK_MECHANISM_PTR pMechanism, /* key-gen * mech. */ CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template * for pub. * key */ CK_ULONG ulPublicKeyAttributeCount, /* # pub. * attrs. */ CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template * for priv. * key */ CK_ULONG ulPrivateKeyAttributeCount, /* # priv. * attrs. */ CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub. * key * handle */ CK_OBJECT_HANDLE_PTR phPrivateKey /* gets * priv. key * handle */ ); #endif /* C_WrapKey wraps (i.e., encrypts) a key. */ CK_PKCS11_FUNCTION_INFO(C_WrapKey) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */ CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */ CK_OBJECT_HANDLE hKey, /* key to be wrapped */ CK_BYTE_PTR pWrappedKey, /* gets wrapped key */ CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */ ); #endif /* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new * key object. */ CK_PKCS11_FUNCTION_INFO(C_UnwrapKey) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* session's handle */ CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */ CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */ CK_BYTE_PTR pWrappedKey, /* the wrapped key */ CK_ULONG ulWrappedKeyLen, /* wrapped key len */ CK_ATTRIBUTE_PTR pTemplate, /* new key template */ CK_ULONG ulAttributeCount, /* template length */ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */ ); #endif /* C_DeriveKey derives a key from a base key, creating a new key * object. */ CK_PKCS11_FUNCTION_INFO(C_DeriveKey) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* session's handle */ CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */ CK_OBJECT_HANDLE hBaseKey, /* base key */ CK_ATTRIBUTE_PTR pTemplate, /* new key template */ CK_ULONG ulAttributeCount, /* template length */ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */ ); #endif /* Random number generation */ /* C_SeedRandom mixes additional seed material into the token's * random number generator. */ CK_PKCS11_FUNCTION_INFO(C_SeedRandom) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pSeed, /* the seed material */ CK_ULONG ulSeedLen /* length of seed material */ ); #endif /* C_GenerateRandom generates random data. */ CK_PKCS11_FUNCTION_INFO(C_GenerateRandom) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR RandomData, /* receives the random data */ CK_ULONG ulRandomLen /* # of bytes to generate */ ); #endif /* Parallel function management */ /* C_GetFunctionStatus is a legacy function; it obtains an * updated status of a function running in parallel with an * application. */ CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession /* the session's handle */ ); #endif /* C_CancelFunction is a legacy function; it cancels a function * running in parallel. */ CK_PKCS11_FUNCTION_INFO(C_CancelFunction) #ifdef CK_NEED_ARG_LIST ( CK_SESSION_HANDLE hSession /* the session's handle */ ); #endif /* Functions added in for Cryptoki Version 2.01 or later */ /* C_WaitForSlotEvent waits for a slot event (token insertion, * removal, etc.) to occur. */ CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent) #ifdef CK_NEED_ARG_LIST ( CK_FLAGS flags, /* blocking/nonblocking flag */ CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */ CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */ ); #endif bind9-9.10.3.dfsg.P4/lib/isc/include/pkcs11/pkcs11.h0000644000470500017500000002207712664710322020725 0ustar lamontlamont/* pkcs11.h include file for PKCS #11. */ /* $Revision: 1.2 $ */ /* License to copy and use this software is granted provided that it is * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface * (Cryptoki)" in all material mentioning or referencing this software. * License is also granted to make and use derivative works provided that * such works are identified as "derived from the RSA Security Inc. PKCS #11 * Cryptographic Token Interface (Cryptoki)" in all material mentioning or * referencing the derived work. * RSA Security Inc. makes no representations concerning either the * merchantability of this software or the suitability of this software for * any particular purpose. It is provided "as is" without express or implied * warranty of any kind. */ #ifndef _PKCS11_H_ #define _PKCS11_H_ 1 #ifdef __cplusplus extern "C" { #endif /* Before including this file (pkcs11.h) (or pkcs11t.h by * itself), 6 platform-specific macros must be defined. These * macros are described below, and typical definitions for them * are also given. Be advised that these definitions can depend * on both the platform and the compiler used (and possibly also * on whether a Cryptoki library is linked statically or * dynamically). * * In addition to defining these 6 macros, the packing convention * for Cryptoki structures should be set. The Cryptoki * convention on packing is that structures should be 1-byte * aligned. * * If you're using Microsoft Developer Studio 5.0 to produce * Win32 stuff, this might be done by using the following * preprocessor directive before including pkcs11.h or pkcs11t.h: * * #pragma pack(push, cryptoki, 1) * * and using the following preprocessor directive after including * pkcs11.h or pkcs11t.h: * * #pragma pack(pop, cryptoki) * * If you're using an earlier version of Microsoft Developer * Studio to produce Win16 stuff, this might be done by using * the following preprocessor directive before including * pkcs11.h or pkcs11t.h: * * #pragma pack(1) * * In a UNIX environment, you're on your own for this. You might * not need to do (or be able to do!) anything. * * * Now for the macros: * * * 1. CK_PTR: The indirection string for making a pointer to an * object. It can be used like this: * * typedef CK_BYTE CK_PTR CK_BYTE_PTR; * * If you're using Microsoft Developer Studio 5.0 to produce * Win32 stuff, it might be defined by: * * #define CK_PTR * * * If you're using an earlier version of Microsoft Developer * Studio to produce Win16 stuff, it might be defined by: * * #define CK_PTR far * * * In a typical UNIX environment, it might be defined by: * * #define CK_PTR * * * * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes * an exportable Cryptoki library function definition out of a * return type and a function name. It should be used in the * following fashion to define the exposed Cryptoki functions in * a Cryptoki library: * * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)( * CK_VOID_PTR pReserved * ) * { * ... * } * * If you're using Microsoft Developer Studio 5.0 to define a * function in a Win32 Cryptoki .dll, it might be defined by: * * #define CK_DEFINE_FUNCTION(returnType, name) \ * returnType __declspec(dllexport) name * * If you're using an earlier version of Microsoft Developer * Studio to define a function in a Win16 Cryptoki .dll, it * might be defined by: * * #define CK_DEFINE_FUNCTION(returnType, name) \ * returnType __export _far _pascal name * * In a UNIX environment, it might be defined by: * * #define CK_DEFINE_FUNCTION(returnType, name) \ * returnType name * * * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes * an importable Cryptoki library function declaration out of a * return type and a function name. It should be used in the * following fashion: * * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)( * CK_VOID_PTR pReserved * ); * * If you're using Microsoft Developer Studio 5.0 to declare a * function in a Win32 Cryptoki .dll, it might be defined by: * * #define CK_DECLARE_FUNCTION(returnType, name) \ * returnType __declspec(dllimport) name * * If you're using an earlier version of Microsoft Developer * Studio to declare a function in a Win16 Cryptoki .dll, it * might be defined by: * * #define CK_DECLARE_FUNCTION(returnType, name) \ * returnType __export _far _pascal name * * In a UNIX environment, it might be defined by: * * #define CK_DECLARE_FUNCTION(returnType, name) \ * returnType name * * * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro * which makes a Cryptoki API function pointer declaration or * function pointer type declaration out of a return type and a * function name. It should be used in the following fashion: * * // Define funcPtr to be a pointer to a Cryptoki API function * // taking arguments args and returning CK_RV. * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args); * * or * * // Define funcPtrType to be the type of a pointer to a * // Cryptoki API function taking arguments args and returning * // CK_RV, and then define funcPtr to be a variable of type * // funcPtrType. * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args); * funcPtrType funcPtr; * * If you're using Microsoft Developer Studio 5.0 to access * functions in a Win32 Cryptoki .dll, in might be defined by: * * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ * returnType __declspec(dllimport) (* name) * * If you're using an earlier version of Microsoft Developer * Studio to access functions in a Win16 Cryptoki .dll, it might * be defined by: * * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ * returnType __export _far _pascal (* name) * * In a UNIX environment, it might be defined by: * * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ * returnType (* name) * * * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes * a function pointer type for an application callback out of * a return type for the callback and a name for the callback. * It should be used in the following fashion: * * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args); * * to declare a function pointer, myCallback, to a callback * which takes arguments args and returns a CK_RV. It can also * be used like this: * * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args); * myCallbackType myCallback; * * If you're using Microsoft Developer Studio 5.0 to do Win32 * Cryptoki development, it might be defined by: * * #define CK_CALLBACK_FUNCTION(returnType, name) \ * returnType (* name) * * If you're using an earlier version of Microsoft Developer * Studio to do Win16 development, it might be defined by: * * #define CK_CALLBACK_FUNCTION(returnType, name) \ * returnType _far _pascal (* name) * * In a UNIX environment, it might be defined by: * * #define CK_CALLBACK_FUNCTION(returnType, name) \ * returnType (* name) * * * 6. NULL_PTR: This macro is the value of a NULL pointer. * * In any ANSI/ISO C environment (and in many others as well), * this should best be defined by * * #ifndef NULL_PTR * #define NULL_PTR 0 * #endif */ /* All the various Cryptoki types and #define'd values are in the * file pkcs11t.h. */ #include "pkcs11t.h" #define __PASTE(x,y) x##y /* ============================================================== * Define the "extern" form of all the entry points. * ============================================================== */ #define CK_NEED_ARG_LIST 1 #define CK_PKCS11_FUNCTION_INFO(name) \ extern CK_DECLARE_FUNCTION(CK_RV, name) /* pkcs11f.h has all the information about the Cryptoki * function prototypes. */ #include "pkcs11f.h" #undef CK_NEED_ARG_LIST #undef CK_PKCS11_FUNCTION_INFO /* ============================================================== * Define the typedef form of all the entry points. That is, for * each Cryptoki function C_XXX, define a type CK_C_XXX which is * a pointer to that kind of function. * ============================================================== */ #define CK_NEED_ARG_LIST 1 #define CK_PKCS11_FUNCTION_INFO(name) \ typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name)) /* pkcs11f.h has all the information about the Cryptoki * function prototypes. */ #include "pkcs11f.h" #undef CK_NEED_ARG_LIST #undef CK_PKCS11_FUNCTION_INFO /* ============================================================== * Define structed vector of entry points. A CK_FUNCTION_LIST * contains a CK_VERSION indicating a library's Cryptoki version * and then a whole slew of function pointers to the routines in * the library. This type was declared, but not defined, in * pkcs11t.h. * ============================================================== */ #define CK_PKCS11_FUNCTION_INFO(name) \ __PASTE(CK_,name) name; struct CK_FUNCTION_LIST { CK_VERSION version; /* Cryptoki version */ /* Pile all the function pointers into the CK_FUNCTION_LIST. */ /* pkcs11f.h has all the information about the Cryptoki * function prototypes. */ #include "pkcs11f.h" }; #undef CK_PKCS11_FUNCTION_INFO #undef __PASTE #ifdef __cplusplus } #endif #endif bind9-9.10.3.dfsg.P4/lib/isc/include/isc/0002755000470500017500000000000012672612753017130 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/include/isc/event.h0000644000470500017500000000666412664710322020424 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: event.h,v 1.34 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_EVENT_H #define ISC_EVENT_H 1 /*! \file isc/event.h */ #include #include /***** ***** Events. *****/ typedef void (*isc_eventdestructor_t)(isc_event_t *); #define ISC_EVENT_COMMON(ltype) \ size_t ev_size; \ unsigned int ev_attributes; \ void * ev_tag; \ isc_eventtype_t ev_type; \ isc_taskaction_t ev_action; \ void * ev_arg; \ void * ev_sender; \ isc_eventdestructor_t ev_destroy; \ void * ev_destroy_arg; \ ISC_LINK(ltype) ev_link /*% * Attributes matching a mask of 0x000000ff are reserved for the task library's * definition. Attributes of 0xffffff00 may be used by the application * or non-ISC libraries. */ #define ISC_EVENTATTR_NOPURGE 0x00000001 /*% * The ISC_EVENTATTR_CANCELED attribute is intended to indicate * that an event is delivered as a result of a canceled operation * rather than successful completion, by mutual agreement * between the sender and receiver. It is not set or used by * the task system. */ #define ISC_EVENTATTR_CANCELED 0x00000002 #define ISC_EVENT_INIT(event, sz, at, ta, ty, ac, ar, sn, df, da) \ do { \ (event)->ev_size = (sz); \ (event)->ev_attributes = (at); \ (event)->ev_tag = (ta); \ (event)->ev_type = (ty); \ (event)->ev_action = (ac); \ (event)->ev_arg = (ar); \ (event)->ev_sender = (sn); \ (event)->ev_destroy = (df); \ (event)->ev_destroy_arg = (da); \ ISC_LINK_INIT((event), ev_link); \ } while (0) /*% * This structure is public because "subclassing" it may be useful when * defining new event types. */ struct isc_event { ISC_EVENT_COMMON(struct isc_event); }; #define ISC_EVENTTYPE_FIRSTEVENT 0x00000000 #define ISC_EVENTTYPE_LASTEVENT 0xffffffff #define ISC_EVENT_PTR(p) ((isc_event_t **)(void *)(p)) ISC_LANG_BEGINDECLS isc_event_t * isc_event_allocate(isc_mem_t *mctx, void *sender, isc_eventtype_t type, isc_taskaction_t action, void *arg, size_t size); isc_event_t * isc_event_constallocate(isc_mem_t *mctx, void *sender, isc_eventtype_t type, isc_taskaction_t action, const void *arg, size_t size); /*%< * Allocate an event structure. * * Allocate and initialize in a structure with initial elements * defined by: * * \code * struct { * ISC_EVENT_COMMON(struct isc_event); * ... * }; * \endcode * * Requires: *\li 'size' >= sizeof(struct isc_event) *\li 'action' to be non NULL * * Returns: *\li a pointer to a initialized structure of the requested size. *\li NULL if unable to allocate memory. */ void isc_event_free(isc_event_t **); ISC_LANG_ENDDECLS #endif /* ISC_EVENT_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/print.h0000644000470500017500000000573312664710322020433 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef ISC_PRINT_H #define ISC_PRINT_H 1 /*! \file isc/print.h */ /*** *** Imports ***/ #include /* Required for ISC_FORMAT_PRINTF() macro. */ #include #include /*! * This block allows lib/isc/print.c to be cleanly compiled even if * the platform does not need it. The standard Makefile will still * not compile print.c or archive print.o, so this is just to make test * compilation ("make print.o") easier. */ #if !defined(ISC_PLATFORM_NEEDVSNPRINTF) && defined(ISC__PRINT_SOURCE) #define ISC_PLATFORM_NEEDVSNPRINTF #undef snprintf #undef vsnprintf #endif #if !defined(ISC_PLATFORM_NEEDSPRINTF) && defined(ISC__PRINT_SOURCE) #define ISC_PLATFORM_NEEDSPRINTF #undef sprintf #endif #if !defined(ISC_PLATFORM_NEEDFPRINTF) && defined(ISC__PRINT_SOURCE) #define ISC_PLATFORM_NEEDFPRINTF #undef fprintf #endif #if !defined(ISC_PLATFORM_NEEDPRINTF) && defined(ISC__PRINT_SOURCE) #define ISC_PLATFORM_NEEDPRINTF #undef printf #endif /*** *** Macros ***/ #define ISC_PRINT_QUADFORMAT ISC_PLATFORM_QUADFORMAT /*** *** Functions ***/ #ifdef ISC_PLATFORM_NEEDVSNPRINTF #include #include #endif #include ISC_LANG_BEGINDECLS #ifdef ISC_PLATFORM_NEEDVSNPRINTF int isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) ISC_FORMAT_PRINTF(3, 0); #undef vsnprintf #define vsnprintf isc_print_vsnprintf int isc_print_snprintf(char *str, size_t size, const char *format, ...) ISC_FORMAT_PRINTF(3, 4); #undef snprintf #define snprintf isc_print_snprintf #endif /* ISC_PLATFORM_NEEDVSNPRINTF */ #ifdef ISC_PLATFORM_NEEDSPRINTF int isc_print_sprintf(char *str, const char *format, ...) ISC_FORMAT_PRINTF(2, 3); #undef sprintf #define sprintf isc_print_sprintf #endif #ifdef ISC_PLATFORM_NEEDPRINTF int isc_print_printf(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); #undef printf #define printf isc_print_printf #endif #ifdef ISC_PLATFORM_NEEDFPRINTF int isc_print_fprintf(FILE * fp, const char *format, ...) ISC_FORMAT_PRINTF(2, 3); #undef fprintf #define fprintf isc_print_fprintf #endif ISC_LANG_ENDDECLS #endif /* ISC_PRINT_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/md5.h0000644000470500017500000000506312664710322017760 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2010, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: md5.h,v 1.20 2010/01/07 23:48:54 tbox Exp $ */ /*! \file isc/md5.h * \brief This is the header file for the MD5 message-digest algorithm. * * The algorithm is due to Ron Rivest. This code was * written by Colin Plumb in 1993, no copyright is claimed. * This code is in the public domain; do with it what you wish. * * Equivalent code is available from RSA Data Security, Inc. * This code has been tested against that, and is equivalent, * except that you don't need to include two pages of legalese * with every copy. * * To compute the message digest of a chunk of bytes, declare an * MD5Context structure, pass it to MD5Init, call MD5Update as * needed on buffers full of bytes, and then call MD5Final, which * will fill a supplied 16-byte array with the digest. * * Changed so as no longer to depend on Colin Plumb's `usual.h' * header definitions; now uses stuff from dpkg's config.h * - Ian Jackson . * Still in the public domain. */ #ifndef ISC_MD5_H #define ISC_MD5_H 1 #include #include #include #define ISC_MD5_DIGESTLENGTH 16U #define ISC_MD5_BLOCK_LENGTH 64U #ifdef ISC_PLATFORM_OPENSSLHASH #include typedef EVP_MD_CTX isc_md5_t; #elif PKCS11CRYPTO #include typedef pk11_context_t isc_md5_t; #else typedef struct { isc_uint32_t buf[4]; isc_uint32_t bytes[2]; isc_uint32_t in[16]; } isc_md5_t; #endif ISC_LANG_BEGINDECLS void isc_md5_init(isc_md5_t *ctx); void isc_md5_invalidate(isc_md5_t *ctx); void isc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len); void isc_md5_final(isc_md5_t *ctx, unsigned char *digest); ISC_LANG_ENDDECLS #endif /* ISC_MD5_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/iterated_hash.h0000644000470500017500000000275612664710322022105 0ustar lamontlamont/* * Copyright (C) 2008, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: iterated_hash.h,v 1.3 2008/09/25 04:02:39 tbox Exp $ */ #ifndef ISC_ITERATED_HASH_H #define ISC_ITERATED_HASH_H 1 #include #include /* * The maximal hash length that can be encoded in a name * using base32hex. floor(255/8)*5 */ #define NSEC3_MAX_HASH_LENGTH 155 /* * The maximum has that can be encoded in a single label using * base32hex. floor(63/8)*5 */ #define NSEC3_MAX_LABEL_HASH 35 ISC_LANG_BEGINDECLS int isc_iterated_hash(unsigned char out[NSEC3_MAX_HASH_LENGTH], unsigned int hashalg, int iterations, const unsigned char *salt, int saltlength, const unsigned char *in, int inlength); ISC_LANG_ENDDECLS #endif /* ISC_ITERATED_HASH_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/lang.h0000644000470500017500000000220612664710322020210 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lang.h,v 1.13 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_LANG_H #define ISC_LANG_H 1 /*! \file isc/lang.h */ #ifdef __cplusplus #define ISC_LANG_BEGINDECLS extern "C" { #define ISC_LANG_ENDDECLS } #else #define ISC_LANG_BEGINDECLS #define ISC_LANG_ENDDECLS #endif #endif /* ISC_LANG_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/netscope.h0000644000470500017500000000270212664710322021110 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: netscope.h,v 1.13 2009/06/25 23:48:02 tbox Exp $ */ #ifndef ISC_NETSCOPE_H #define ISC_NETSCOPE_H 1 /*! \file isc/netscope.h */ ISC_LANG_BEGINDECLS /*% * Convert a string of an IPv6 scope zone to zone index. If the conversion * succeeds, 'zoneid' will store the index value. * * XXXJT: when a standard interface for this purpose is defined, * we should use it. * * Returns: * \li ISC_R_SUCCESS: conversion succeeds * \li ISC_R_FAILURE: conversion fails */ isc_result_t isc_netscope_pton(int af, char *scopename, void *addr, isc_uint32_t *zoneid); ISC_LANG_ENDDECLS #endif /* ISC_NETSCOPE_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/queue.h0000644000470500017500000001210312664710322020410 0ustar lamontlamont/* * Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* * This is a generic implementation of a two-lock concurrent queue. * There are built-in mutex locks for the head and tail of the queue, * allowing elements to be safely added and removed at the same time. * * NULL is "end of list" * -1 is "not linked" */ #ifndef ISC_QUEUE_H #define ISC_QUEUE_H 1 #include #include #include #ifdef ISC_QUEUE_CHECKINIT #define ISC_QLINK_INSIST(x) ISC_INSIST(x) #else #define ISC_QLINK_INSIST(x) (void)0 #endif #define ISC_QLINK(type) struct { type *prev, *next; } #define ISC_QLINK_INIT(elt, link) \ do { \ (elt)->link.next = (elt)->link.prev = (void *)(-1); \ } while(0) #define ISC_QLINK_LINKED(elt, link) ((void*)(elt)->link.next != (void*)(-1)) #define ISC_QUEUE(type) struct { \ type *head, *tail; \ isc_mutex_t headlock, taillock; \ } #define ISC_QUEUE_INIT(queue, link) \ do { \ (void) isc_mutex_init(&(queue).taillock); \ (void) isc_mutex_init(&(queue).headlock); \ (queue).tail = (queue).head = NULL; \ } while (0) #define ISC_QUEUE_EMPTY(queue) ISC_TF((queue).head == NULL) #define ISC_QUEUE_DESTROY(queue) \ do { \ ISC_QLINK_INSIST(ISC_QUEUE_EMPTY(queue)); \ (void) isc_mutex_destroy(&(queue).taillock); \ (void) isc_mutex_destroy(&(queue).headlock); \ } while (0) /* * queues are meant to separate the locks at either end. For best effect, that * means keeping the ends separate - i.e. non-empty queues work best. * * a push to an empty queue has to take the pop lock to update * the pop side of the queue. * Popping the last entry has to take the push lock to update * the push side of the queue. * * The order is (pop, push), because a pop is presumably in the * latency path and a push is when we're done. * * We do an MT hot test in push to see if we need both locks, so we can * acquire them in order. Hopefully that makes the case where we get * the push lock and find we need the pop lock (and have to release it) rare. * * > 1 entry - no collision, push works on one end, pop on the other * 0 entry - headlock race * pop wins - return(NULL), push adds new as both head/tail * push wins - updates head/tail, becomes 1 entry case. * 1 entry - taillock race * pop wins - return(pop) sets head/tail NULL, becomes 0 entry case * push wins - updates {head,tail}->link.next, pop updates head * with new ->link.next and doesn't update tail * */ #define ISC_QUEUE_PUSH(queue, elt, link) \ do { \ isc_boolean_t headlocked = ISC_FALSE; \ ISC_QLINK_INSIST(!ISC_QLINK_LINKED(elt, link)); \ if ((queue).head == NULL) { \ LOCK(&(queue).headlock); \ headlocked = ISC_TRUE; \ } \ LOCK(&(queue).taillock); \ if ((queue).tail == NULL && !headlocked) { \ UNLOCK(&(queue).taillock); \ LOCK(&(queue).headlock); \ LOCK(&(queue).taillock); \ headlocked = ISC_TRUE; \ } \ (elt)->link.prev = (queue).tail; \ (elt)->link.next = NULL; \ if ((queue).tail != NULL) \ (queue).tail->link.next = (elt); \ (queue).tail = (elt); \ UNLOCK(&(queue).taillock); \ if (headlocked) { \ if ((queue).head == NULL) \ (queue).head = (elt); \ UNLOCK(&(queue).headlock); \ } \ } while (0) #define ISC_QUEUE_POP(queue, link, ret) \ do { \ LOCK(&(queue).headlock); \ ret = (queue).head; \ while (ret != NULL) { \ if (ret->link.next == NULL) { \ LOCK(&(queue).taillock); \ if (ret->link.next == NULL) { \ (queue).head = (queue).tail = NULL; \ UNLOCK(&(queue).taillock); \ break; \ }\ UNLOCK(&(queue).taillock); \ } \ (queue).head = ret->link.next; \ (queue).head->link.prev = NULL; \ break; \ } \ UNLOCK(&(queue).headlock); \ if (ret != NULL) \ (ret)->link.next = (ret)->link.prev = (void *)(-1); \ } while(0) #define ISC_QUEUE_UNLINK(queue, elt, link) \ do { \ ISC_QLINK_INSIST(ISC_QLINK_LINKED(elt, link)); \ LOCK(&(queue).headlock); \ LOCK(&(queue).taillock); \ if ((elt)->link.prev == NULL) \ (queue).head = (elt)->link.next; \ else \ (elt)->link.prev->link.next = (elt)->link.next; \ if ((elt)->link.next == NULL) \ (queue).tail = (elt)->link.prev; \ else \ (elt)->link.next->link.prev = (elt)->link.prev; \ UNLOCK(&(queue).taillock); \ UNLOCK(&(queue).headlock); \ (elt)->link.next = (elt)->link.prev = (void *)(-1); \ } while(0) #endif /* ISC_QUEUE_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/quota.h0000644000470500017500000000520312664710322020420 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: quota.h,v 1.16 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_QUOTA_H #define ISC_QUOTA_H 1 /***** ***** Module Info *****/ /*! \file isc/quota.h * * \brief The isc_quota_t object is a simple helper object for implementing * quotas on things like the number of simultaneous connections to * a server. It keeps track of the amount of quota in use, and * encapsulates the locking necessary to allow multiple tasks to * share a quota. */ /*** *** Imports. ***/ #include #include #include /***** ***** Types. *****/ ISC_LANG_BEGINDECLS /*% isc_quota structure */ struct isc_quota { isc_mutex_t lock; /*%< Locked by lock. */ int max; int used; int soft; }; isc_result_t isc_quota_init(isc_quota_t *quota, int max); /*%< * Initialize a quota object. * * Returns: * ISC_R_SUCCESS * Other error Lock creation failed. */ void isc_quota_destroy(isc_quota_t *quota); /*%< * Destroy a quota object. */ void isc_quota_soft(isc_quota_t *quota, int soft); /*%< * Set a soft quota. */ void isc_quota_max(isc_quota_t *quota, int max); /*%< * Re-set a maximum quota. */ isc_result_t isc_quota_reserve(isc_quota_t *quota); /*%< * Attempt to reserve one unit of 'quota'. * * Returns: * \li #ISC_R_SUCCESS Success * \li #ISC_R_SOFTQUOTA Success soft quota reached * \li #ISC_R_QUOTA Quota is full */ void isc_quota_release(isc_quota_t *quota); /*%< * Release one unit of quota. */ isc_result_t isc_quota_attach(isc_quota_t *quota, isc_quota_t **p); /*%< * Like isc_quota_reserve, and also attaches '*p' to the * quota if successful (ISC_R_SUCCESS or ISC_R_SOFTQUOTA). */ void isc_quota_detach(isc_quota_t **p); /*%< * Like isc_quota_release, and also detaches '*p' from the * quota. */ ISC_LANG_ENDDECLS #endif /* ISC_QUOTA_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/heap.h0000644000470500017500000001325012664710322020205 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1997-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: heap.h,v 1.26 2009/01/17 23:47:43 tbox Exp $ */ #ifndef ISC_HEAP_H #define ISC_HEAP_H 1 /*! \file isc/heap.h */ #include #include ISC_LANG_BEGINDECLS /*% * The comparison function returns ISC_TRUE if the first argument has * higher priority than the second argument, and ISC_FALSE otherwise. */ typedef isc_boolean_t (*isc_heapcompare_t)(void *, void *); /*% * The index function allows the client of the heap to receive a callback * when an item's index number changes. This allows it to maintain * sync with its external state, but still delete itself, since deletions * from the heap require the index be provided. */ typedef void (*isc_heapindex_t)(void *, unsigned int); /*% * The heapaction function is used when iterating over the heap. * * NOTE: The heap structure CANNOT BE MODIFIED during the call to * isc_heap_foreach(). */ typedef void (*isc_heapaction_t)(void *, void *); typedef struct isc_heap isc_heap_t; isc_result_t isc_heap_create(isc_mem_t *mctx, isc_heapcompare_t compare, isc_heapindex_t index, unsigned int size_increment, isc_heap_t **heapp); /*!< * \brief Create a new heap. The heap is implemented using a space-efficient * storage method. When the heap elements are deleted space is not freed * but will be reused when new elements are inserted. * * Heap elements are indexed from 1. * * Requires: *\li "mctx" is valid. *\li "compare" is a function which takes two void * arguments and * returns ISC_TRUE if the first argument has a higher priority than * the second, and ISC_FALSE otherwise. *\li "index" is a function which takes a void *, and an unsigned int * argument. This function will be called whenever an element's * index value changes, so it may continue to delete itself from the * heap. This option may be NULL if this functionality is unneeded. *\li "size_increment" is a hint about how large the heap should grow * when resizing is needed. If this is 0, a default size will be * used, which is currently 1024, allowing space for an additional 1024 * heap elements to be inserted before adding more space. *\li "heapp" is not NULL, and "*heap" is NULL. * * Returns: *\li ISC_R_SUCCESS - success *\li ISC_R_NOMEMORY - insufficient memory */ void isc_heap_destroy(isc_heap_t **heapp); /*!< * \brief Destroys a heap. * * Requires: *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t. */ isc_result_t isc_heap_insert(isc_heap_t *heap, void *elt); /*!< * \brief Inserts a new element into a heap. * * Requires: *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t. */ void isc_heap_delete(isc_heap_t *heap, unsigned int index); /*!< * \brief Deletes an element from a heap, by element index. * * Requires: *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t. *\li "index" is a valid element index, as provided by the "index" callback * provided during heap creation. */ void isc_heap_increased(isc_heap_t *heap, unsigned int index); /*!< * \brief Indicates to the heap that an element's priority has increased. * This function MUST be called whenever an element has increased in priority. * * Requires: *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t. *\li "index" is a valid element index, as provided by the "index" callback * provided during heap creation. */ void isc_heap_decreased(isc_heap_t *heap, unsigned int index); /*!< * \brief Indicates to the heap that an element's priority has decreased. * This function MUST be called whenever an element has decreased in priority. * * Requires: *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t. *\li "index" is a valid element index, as provided by the "index" callback * provided during heap creation. */ void * isc_heap_element(isc_heap_t *heap, unsigned int index); /*!< * \brief Returns the element for a specific element index. * * Requires: *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t. *\li "index" is a valid element index, as provided by the "index" callback * provided during heap creation. * * Returns: *\li A pointer to the element for the element index. */ void isc_heap_foreach(isc_heap_t *heap, isc_heapaction_t action, void *uap); /*!< * \brief Iterate over the heap, calling an action for each element. The * order of iteration is not sorted. * * Requires: *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t. *\li "action" is not NULL, and is a function which takes two arguments. * The first is a void *, representing the element, and the second is * "uap" as provided to isc_heap_foreach. *\li "uap" is a caller-provided argument, and may be NULL. * * Note: *\li The heap structure CANNOT be modified during this iteration. The only * safe function to call while iterating the heap is isc_heap_element(). */ ISC_LANG_ENDDECLS #endif /* ISC_HEAP_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/counter.h0000644000470500017500000000443012664710322020747 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef ISC_COUNTER_H #define ISC_COUNTER_H 1 /***** ***** Module Info *****/ /*! \file isc/counter.h * * \brief The isc_counter_t object is a simplified version of the * isc_quota_t object; it tracks the consumption of limited * resources, returning an error condition when the quota is * exceeded. However, unlike isc_quota_t, attaching and detaching * from a counter object does not increment or decrement the counter. */ /*** *** Imports. ***/ #include #include #include /***** ***** Types. *****/ ISC_LANG_BEGINDECLS isc_result_t isc_counter_create(isc_mem_t *mctx, int limit, isc_counter_t **counterp); /*%< * Allocate and initialize a counter object. */ isc_result_t isc_counter_increment(isc_counter_t *counter); /*%< * Increment the counter. * * If the counter limit is nonzero and has been reached, then * return ISC_R_QUOTA, otherwise ISC_R_SUCCESS. (The counter is * incremented regardless of return value.) */ unsigned int isc_counter_used(isc_counter_t *counter); /*%< * Return the current counter value. */ void isc_counter_setlimit(isc_counter_t *counter, int limit); /*%< * Set the counter limit. */ void isc_counter_attach(isc_counter_t *source, isc_counter_t **targetp); /*%< * Attach to a counter object, increasing its reference counter. */ void isc_counter_detach(isc_counter_t **counterp); /*%< * Detach (and destroy if reference counter has dropped to zero) * a counter object. */ ISC_LANG_ENDDECLS #endif /* ISC_COUNTER_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/error.h0000644000470500017500000000351712664710322020426 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: error.h,v 1.22 2009/09/29 23:48:04 tbox Exp $ */ #ifndef ISC_ERROR_H #define ISC_ERROR_H 1 /*! \file isc/error.h */ #include #include #include #include ISC_LANG_BEGINDECLS typedef void (*isc_errorcallback_t)(const char *, int, const char *, va_list); /*% set unexpected error */ void isc_error_setunexpected(isc_errorcallback_t); /*% set fatal error */ void isc_error_setfatal(isc_errorcallback_t); /*% unexpected error */ void isc_error_unexpected(const char *, int, const char *, ...) ISC_FORMAT_PRINTF(3, 4); /*% fatal error */ ISC_PLATFORM_NORETURN_PRE void isc_error_fatal(const char *, int, const char *, ...) ISC_FORMAT_PRINTF(3, 4) ISC_PLATFORM_NORETURN_POST; /*% runtimecheck error */ void isc_error_runtimecheck(const char *, int, const char *); #define ISC_ERROR_RUNTIMECHECK(cond) \ ((void) ((cond) || \ ((isc_error_runtimecheck)(__FILE__, __LINE__, #cond), 0))) ISC_LANG_ENDDECLS #endif /* ISC_ERROR_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/msgs.h0000644000470500017500000002123612664710322020244 0ustar lamontlamont/* * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: msgs.h,v 1.19 2009/10/01 23:48:08 tbox Exp $ */ #ifndef ISC_MSGS_H #define ISC_MSGS_H 1 /*! \file isc/msgs.h */ #include /* Provide isc_msgcat global variable. */ #include /* Provide isc_msgcat_*() functions. */ /*@{*/ /*! * \brief Message sets, named per source file, excepting "GENERAL". * * IMPORTANT: The original list is alphabetical, but any new sets must * be added to the end. */ #define ISC_MSGSET_GENERAL 1 /* ISC_RESULT_RESULTSET 2 */ /* XXX */ /* ISC_RESULT_UNAVAILABLESET 3 */ /* XXX */ #define ISC_MSGSET_APP 4 #define ISC_MSGSET_COMMANDLINE 5 #define ISC_MSGSET_ENTROPY 6 #define ISC_MSGSET_IFITERIOCTL 7 #define ISC_MSGSET_IFITERSYSCTL 8 #define ISC_MSGSET_LEX 9 #define ISC_MSGSET_LOG 10 #define ISC_MSGSET_MEM 11 #define ISC_MSGSET_NETADDR 12 #define ISC_MSGSET_PRINT 13 #define ISC_MSGSET_RESULT 14 #define ISC_MSGSET_RWLOCK 15 #define ISC_MSGSET_SOCKADDR 16 #define ISC_MSGSET_SOCKET 17 #define ISC_MSGSET_TASK 18 #define ISC_MSGSET_TIMER 19 #define ISC_MSGSET_UTIL 20 #define ISC_MSGSET_IFITERGETIFADDRS 21 /*@}*/ /*@{*/ /*! * Message numbers * are only required to be unique per message set, * but are unique throughout the entire catalog to not be as confusing when * debugging. * * The initial numbering was done by multiply by 100 the set number the * message appears in then adding the incremental message number. */ #define ISC_MSG_FAILED 101 /*%< "failed" */ #define ISC_MSG_SUCCEEDED 102 /*%< Compatible with "failed" */ #define ISC_MSG_SUCCESS 103 /*%< More usual way to say "success" */ #define ISC_MSG_STARTING 104 /*%< As in "daemon: starting" */ #define ISC_MSG_STOPING 105 /*%< As in "daemon: stopping" */ #define ISC_MSG_ENTERING 106 /*%< As in "some_subr: entering" */ #define ISC_MSG_EXITING 107 /*%< As in "some_subr: exiting" */ #define ISC_MSG_CALLING 108 /*%< As in "calling some_subr()" */ #define ISC_MSG_RETURNED 109 /*%< As in "some_subr: returned " */ #define ISC_MSG_FATALERROR 110 /*%< "fatal error" */ #define ISC_MSG_SHUTTINGDOWN 111 /*%< "shutting down" */ #define ISC_MSG_RUNNING 112 /*%< "running" */ #define ISC_MSG_WAIT 113 /*%< "wait" */ #define ISC_MSG_WAITUNTIL 114 /*%< "waituntil" */ #define ISC_MSG_SIGNALSETUP 201 /*%< "handle_signal() %d setup: %s" */ #define ISC_MSG_ILLEGALOPT 301 /*%< "illegal option" */ #define ISC_MSG_OPTNEEDARG 302 /*%< "option requires an argument" */ #define ISC_MSG_ENTROPYSTATS 401 /*%< "Entropy pool %p: refcnt %u ..." */ #define ISC_MSG_MAKESCANSOCKET 501 /*%< "making interface scan socket: %s" */ #define ISC_MSG_GETIFCONFIG 502 /*%< "get interface configuration: %s" */ #define ISC_MSG_BUFFERMAX 503 /*%< "... maximum buffer size exceeded" */ #define ISC_MSG_GETDESTADDR 504 /*%< "%s: getting destination address: %s" */ #define ISC_MSG_GETNETMASK 505 /*%< "%s: getting netmask: %s" */ #define ISC_MSG_GETIFLISTSIZE 601 /*%< "getting interface list size: ..." */ #define ISC_MSG_GETIFLIST 602 /*%< "getting interface list: ..." */ #define ISC_MSG_UNEXPECTEDTYPE 603 /*%< "... unexpected ... message type" */ #define ISC_MSG_UNEXPECTEDSTATE 701 /*%< "Unexpected state %d" */ #define ISC_MSG_BADTIME 801 /*%< "Bad 00 99:99:99.999 " */ #define ISC_MSG_LEVEL 802 /*%< "level %d: " */ #define ISC_MSG_ADDTRACE 901 /*%< "add %p size %u " */ #define ISC_MSG_DELTRACE 902 /*%< "del %p size %u " */ #define ISC_MSG_POOLSTATS 903 /*%< "[Pool statistics]\n" */ #define ISC_MSG_POOLNAME 904 /*%< "name" */ #define ISC_MSG_POOLSIZE 905 /*%< "size" */ #define ISC_MSG_POOLMAXALLOC 906 /*%< "maxalloc" */ #define ISC_MSG_POOLALLOCATED 907 /*%< "allocated" */ #define ISC_MSG_POOLFREECOUNT 908 /*%< "freecount" */ #define ISC_MSG_POOLFREEMAX 909 /*%< "freemax" */ #define ISC_MSG_POOLFILLCOUNT 910 /*%< "fillcount" */ #define ISC_MSG_POOLGETS 911 /*%< "gets" */ #define ISC_MSG_DUMPALLOC 912 /*%< "DUMP OF ALL OUTSTANDING MEMORY ..." */ #define ISC_MSG_NONE 913 /*%< "\tNone.\n" */ #define ISC_MSG_PTRFILELINE 914 /*%< "\tptr %p file %s line %u\n" */ #define ISC_MSG_UNKNOWNADDR 1001 /*%< "" */ #define ISC_MSG_NOLONGDBL 1104 /*%< "long doubles are not supported" */ #define ISC_MSG_PRINTLOCK 1201 /*%< "rwlock %p thread %lu ..." */ #define ISC_MSG_READ 1202 /*%< "read" */ #define ISC_MSG_WRITE 1203 /*%< "write" */ #define ISC_MSG_READING 1204 /*%< "reading" */ #define ISC_MSG_WRITING 1205 /*%< "writing" */ #define ISC_MSG_PRELOCK 1206 /*%< "prelock" */ #define ISC_MSG_POSTLOCK 1207 /*%< "postlock" */ #define ISC_MSG_PREUNLOCK 1208 /*%< "preunlock" */ #define ISC_MSG_POSTUNLOCK 1209 /*%< "postunlock" */ #define ISC_MSG_UNKNOWNFAMILY 1301 /*%< "unknown address family: %d" */ #define ISC_MSG_WRITEFAILED 1401 /*%< "write() failed during watcher ..." */ #define ISC_MSG_READFAILED 1402 /*%< "read() failed during watcher ... " */ #define ISC_MSG_PROCESSCMSG 1403 /*%< "processing cmsg %p" */ #define ISC_MSG_IFRECEIVED 1404 /*%< "interface received on ifindex %u" */ #define ISC_MSG_SENDTODATA 1405 /*%< "sendto pktinfo data, ifindex %u" */ #define ISC_MSG_DOIORECV 1406 /*%< "doio_recv: recvmsg(%d) %d bytes ..." */ #define ISC_MSG_PKTRECV 1407 /*%< "packet received correctly" */ #define ISC_MSG_DESTROYING 1408 /*%< "destroying" */ #define ISC_MSG_CREATED 1409 /*%< "created" */ #define ISC_MSG_ACCEPTLOCK 1410 /*%< "internal_accept called, locked ..." */ #define ISC_MSG_ACCEPTEDCXN 1411 /*%< "accepted connection, new socket %p" */ #define ISC_MSG_INTERNALRECV 1412 /*%< "internal_recv: task %p got event %p" */ #define ISC_MSG_INTERNALSEND 1413 /*%< "internal_send: task %p got event %p" */ #define ISC_MSG_WATCHERMSG 1414 /*%< "watcher got message %d" */ #define ISC_MSG_SOCKETSREMAIN 1415 /*%< "sockets exist" */ #define ISC_MSG_PKTINFOPROVIDED 1416 /*%< "pktinfo structure provided, ..." */ #define ISC_MSG_BOUND 1417 /*%< "bound" */ #define ISC_MSG_ACCEPTRETURNED 1418 /*%< accept() returned %d/%s */ #define ISC_MSG_TOOMANYFDS 1419 /*%< %s: too many open file descriptors */ #define ISC_MSG_ZEROPORT 1420 /*%< dropping source port zero packet */ #define ISC_MSG_FILTER 1421 /*%< setsockopt(SO_ACCEPTFILTER): %s */ #define ISC_MSG_TOOMANYHANDLES 1422 /*%< %s: too many open WSA event handles: %s */ #define ISC_MSG_POKED 1423 /*%< "poked flags: %d" */ #define ISC_MSG_AWAKE 1502 /*%< "awake" */ #define ISC_MSG_WORKING 1503 /*%< "working" */ #define ISC_MSG_EXECUTE 1504 /*%< "execute action" */ #define ISC_MSG_EMPTY 1505 /*%< "empty" */ #define ISC_MSG_DONE 1506 /*%< "done" */ #define ISC_MSG_QUANTUM 1507 /*%< "quantum" */ #define ISC_MSG_SCHEDULE 1601 /*%< "schedule" */ #define ISC_MSG_SIGNALSCHED 1602 /*%< "signal (schedule)" */ #define ISC_MSG_SIGNALDESCHED 1603 /*%< "signal (deschedule)" */ #define ISC_MSG_SIGNALDESTROY 1604 /*%< "signal (destroy)" */ #define ISC_MSG_IDLERESCHED 1605 /*%< "idle reschedule" */ #define ISC_MSG_EVENTNOTALLOC 1606 /*%< "couldn't allocate event" */ #define ISC_MSG_SCHEDFAIL 1607 /*%< "couldn't schedule timer: %u" */ #define ISC_MSG_POSTING 1608 /*%< "posting" */ #define ISC_MSG_WAKEUP 1609 /*%< "wakeup" */ #define ISC_MSG_LOCK 1701 /*%< "LOCK" */ #define ISC_MSG_LOCKING 1702 /*%< "LOCKING" */ #define ISC_MSG_LOCKED 1703 /*%< "LOCKED" */ #define ISC_MSG_UNLOCKED 1704 /*%< "UNLOCKED" */ #define ISC_MSG_RWLOCK 1705 /*%< "RWLOCK" */ #define ISC_MSG_RWLOCKED 1706 /*%< "RWLOCKED" */ #define ISC_MSG_RWUNLOCK 1707 /*%< "RWUNLOCK" */ #define ISC_MSG_BROADCAST 1708 /*%< "BROADCAST" */ #define ISC_MSG_SIGNAL 1709 /*%< "SIGNAL" */ #define ISC_MSG_UTILWAIT 1710 /*%< "WAIT" */ #define ISC_MSG_WAITED 1711 /*%< "WAITED" */ #define ISC_MSG_GETIFADDRS 1801 /*%< "getting interface addresses: ..." */ /*@}*/ #endif /* ISC_MSGS_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/ondestroy.h0000644000470500017500000000637712664710322021332 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ondestroy.h,v 1.14 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_ONDESTROY_H #define ISC_ONDESTROY_H 1 #include #include ISC_LANG_BEGINDECLS /*! \file isc/ondestroy.h * ondestroy handling. * * Any class ``X'' of objects that wants to send out notifications * on its destruction should declare a field of type isc_ondestroy_t * (call it 'ondest'). * * \code * typedef struct { * ... * isc_ondestroy_t ondest; * ... * } X; * \endcode * * When an object ``A'' of type X is created * it must initialize the field ondest with a call to * * \code * isc_ondestroy_init(&A->ondest). * \endcode * * X should also provide a registration function for third-party * objects to call to register their interest in being told about * the destruction of a particular instance of X. * * \code * isc_result_t * X_ondestroy(X *instance, isc_task_t *task, * isc_event_t **eventp) { * return(isc_ondestroy_register(&instance->ondest, task,eventp)); * } * \endcode * * Note: locking of the ondestory structure embedded inside of X, is * X's responsibility. * * When an instance of X is destroyed, a call to isc_ondestroy_notify() * sends the notifications: * * \code * X *instance; * isc_ondestroy_t ondest = instance->ondest; * * ... completely cleanup 'instance' here... * * isc_ondestroy_notify(&ondest, instance); * \endcode * * * see lib/dns/zone.c for an ifdef'd-out example. */ struct isc_ondestroy { unsigned int magic; isc_eventlist_t events; }; void isc_ondestroy_init(isc_ondestroy_t *ondest); /*%< * Initialize the on ondest structure. *must* be called before first call * to isc_ondestroy_register(). */ isc_result_t isc_ondestroy_register(isc_ondestroy_t *ondest, isc_task_t *task, isc_event_t **eventp); /*%< * Stores task and *eventp away inside *ondest. Ownership of **event is * taken from the caller (and *eventp is set to NULL). The task is attached * to. */ void isc_ondestroy_notify(isc_ondestroy_t *ondest, void *sender); /*%< * Dispatches the event(s) to the task(s) that were given in * isc_ondestroy_register call(s) (done via calls to * isc_task_sendanddetach()). Before dispatch, the sender value of each * event structure is set to the value of the sender paramater. The * internal structures of the ondest parameter are cleaned out, so no other * cleanup is needed. */ ISC_LANG_ENDDECLS #endif /* ISC_ONDESTROY_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/commandline.h0000644000470500017500000000343712664710322021564 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: commandline.h,v 1.16 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_COMMANDLINE_H #define ISC_COMMANDLINE_H 1 /*! \file isc/commandline.h */ #include #include #include /*% Index into parent argv vector. */ LIBISC_EXTERNAL_DATA extern int isc_commandline_index; /*% Character checked for validity. */ LIBISC_EXTERNAL_DATA extern int isc_commandline_option; /*% Argument associated with option. */ LIBISC_EXTERNAL_DATA extern char *isc_commandline_argument; /*% For printing error messages. */ LIBISC_EXTERNAL_DATA extern char *isc_commandline_progname; /*% Print error message. */ LIBISC_EXTERNAL_DATA extern isc_boolean_t isc_commandline_errprint; /*% Reset getopt. */ LIBISC_EXTERNAL_DATA extern isc_boolean_t isc_commandline_reset; ISC_LANG_BEGINDECLS /*% parse command line */ int isc_commandline_parse(int argc, char * const *argv, const char *options); ISC_LANG_ENDDECLS #endif /* ISC_COMMANDLINE_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/httpd.h0000644000470500017500000000525612664710322020422 0ustar lamontlamont/* * Copyright (C) 2006-2008, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: httpd.h,v 1.9 2008/08/08 05:06:49 marka Exp $ */ #ifndef ISC_HTTPD_H #define ISC_HTTPD_H 1 /*! \file */ #include #include #include #include #include #include /*% * HTTP urls. These are the URLs we manage, and the function to call to * provide the data for it. We pass in the base url (so the same function * can handle multiple requests), and a structure to fill in to return a * result to the client. We also pass in a pointer to be filled in for * the data cleanup function. */ struct isc_httpdurl { char *url; isc_httpdaction_t *action; void *action_arg; isc_boolean_t isstatic; isc_time_t loadtime; ISC_LINK(isc_httpdurl_t) link; }; #define HTTPD_EVENTCLASS ISC_EVENTCLASS(4300) #define HTTPD_SHUTDOWN (HTTPD_EVENTCLASS + 0x0001) #define ISC_HTTPDMGR_FLAGSHUTTINGDOWN 0x00000001 /* * Create a new http daemon which will send, once every time period, * a http-like header followed by HTTP data. */ isc_result_t isc_httpdmgr_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task, isc_httpdclientok_t *client_ok, isc_httpdondestroy_t *ondestory, void *cb_arg, isc_timermgr_t *tmgr, isc_httpdmgr_t **httpdp); void isc_httpdmgr_shutdown(isc_httpdmgr_t **httpdp); isc_result_t isc_httpdmgr_addurl(isc_httpdmgr_t *httpdmgr, const char *url, isc_httpdaction_t *func, void *arg); isc_result_t isc_httpdmgr_addurl2(isc_httpdmgr_t *httpdmgr, const char *url, isc_boolean_t isstatic, isc_httpdaction_t *func, void *arg); isc_result_t isc_httpd_response(isc_httpd_t *httpd); isc_result_t isc_httpd_addheader(isc_httpd_t *httpd, const char *name, const char *val); isc_result_t isc_httpd_addheaderuint(isc_httpd_t *httpd, const char *name, int val); isc_result_t isc_httpd_endheaders(isc_httpd_t *httpd); #endif /* ISC_HTTPD_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/stats.h0000644000470500017500000000666412664710322020441 0ustar lamontlamont/* * Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef ISC_STATS_H #define ISC_STATS_H 1 /*! \file isc/stats.h */ #include ISC_LANG_BEGINDECLS /*%< * Flag(s) for isc_stats_dump(). */ #define ISC_STATSDUMP_VERBOSE 0x00000001 /*%< dump 0-value counters */ /*%< * Dump callback type. */ typedef void (*isc_stats_dumper_t)(isc_statscounter_t, isc_uint64_t, void *); isc_result_t isc_stats_create(isc_mem_t *mctx, isc_stats_t **statsp, int ncounters); /*%< * Create a statistics counter structure of general type. It counts a general * set of counters indexed by an ID between 0 and ncounters -1. * * Requires: *\li 'mctx' must be a valid memory context. * *\li 'statsp' != NULL && '*statsp' == NULL. * * Returns: *\li ISC_R_SUCCESS -- all ok * *\li anything else -- failure */ void isc_stats_attach(isc_stats_t *stats, isc_stats_t **statsp); /*%< * Attach to a statistics set. * * Requires: *\li 'stats' is a valid isc_stats_t. * *\li 'statsp' != NULL && '*statsp' == NULL */ void isc_stats_detach(isc_stats_t **statsp); /*%< * Detaches from the statistics set. * * Requires: *\li 'statsp' != NULL and '*statsp' is a valid isc_stats_t. */ int isc_stats_ncounters(isc_stats_t *stats); /*%< * Returns the number of counters contained in stats. * * Requires: *\li 'stats' is a valid isc_stats_t. * */ void isc_stats_increment(isc_stats_t *stats, isc_statscounter_t counter); /*%< * Increment the counter-th counter of stats. * * Requires: *\li 'stats' is a valid isc_stats_t. * *\li counter is less than the maximum available ID for the stats specified * on creation. */ void isc_stats_decrement(isc_stats_t *stats, isc_statscounter_t counter); /*%< * Decrement the counter-th counter of stats. * * Requires: *\li 'stats' is a valid isc_stats_t. */ void isc_stats_dump(isc_stats_t *stats, isc_stats_dumper_t dump_fn, void *arg, unsigned int options); /*%< * Dump the current statistics counters in a specified way. For each counter * in stats, dump_fn is called with its current value and the given argument * arg. By default counters that have a value of 0 is skipped; if options has * the ISC_STATSDUMP_VERBOSE flag, even such counters are dumped. * * Requires: *\li 'stats' is a valid isc_stats_t. */ void isc_stats_set(isc_stats_t *stats, isc_uint64_t val, isc_statscounter_t counter); /*%< * Set the given counter to the specfied value. * * Requires: *\li 'stats' is a valid isc_stats_t. */ void isc_stats_set(isc_stats_t *stats, isc_uint64_t val, isc_statscounter_t counter); /*%< * Set the given counter to the specfied value. * * Requires: *\li 'stats' is a valid isc_stats_t. */ ISC_LANG_ENDDECLS #endif /* ISC_STATS_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/platform.h.in0000644000470500017500000002130512664710322021521 0ustar lamontlamont/* * Copyright (C) 2004-2010, 2013-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef ISC_PLATFORM_H #define ISC_PLATFORM_H 1 /*! \file */ /***** ***** Platform-dependent defines. *****/ /*** *** Network. ***/ /*! \brief * Define if this system needs the header file included * for full IPv6 support (pretty much only UnixWare). */ @ISC_PLATFORM_NEEDNETINETIN6H@ /*! \brief * Define if this system needs the header file included * to support in6_pkinfo (pretty much only BSD/OS). */ @ISC_PLATFORM_NEEDNETINET6IN6H@ /*! \brief * If sockaddrs on this system have an sa_len field, ISC_PLATFORM_HAVESALEN * will be defined. */ @ISC_PLATFORM_HAVESALEN@ /*! \brief * If this system has the IPv6 structure definitions, ISC_PLATFORM_HAVEIPV6 * will be defined. */ @ISC_PLATFORM_HAVEIPV6@ /*! \brief * If this system is missing in6addr_any, ISC_PLATFORM_NEEDIN6ADDRANY will * be defined. */ @ISC_PLATFORM_NEEDIN6ADDRANY@ /*! \brief * If this system is missing in6addr_loopback, ISC_PLATFORM_NEEDIN6ADDRLOOPBACK * will be defined. */ @ISC_PLATFORM_NEEDIN6ADDRLOOPBACK@ /*! \brief * If this system has in6_pktinfo, ISC_PLATFORM_HAVEIN6PKTINFO will be * defined. */ @ISC_PLATFORM_HAVEIN6PKTINFO@ /*! \brief * If this system has in_addr6, rather than in6_addr, ISC_PLATFORM_HAVEINADDR6 * will be defined. */ @ISC_PLATFORM_HAVEINADDR6@ /*! \brief * If this system has sin6_scope_id, ISC_PLATFORM_HAVESCOPEID will be defined. */ @ISC_PLATFORM_HAVESCOPEID@ /*! \brief * If this system needs inet_ntop(), ISC_PLATFORM_NEEDNTOP will be defined. */ @ISC_PLATFORM_NEEDNTOP@ /*! \brief * If this system needs inet_pton(), ISC_PLATFORM_NEEDPTON will be defined. */ @ISC_PLATFORM_NEEDPTON@ /*! \brief * If this system needs in_port_t, ISC_PLATFORM_NEEDPORTT will be defined. */ @ISC_PLATFORM_NEEDPORTT@ /*! \brief * Define if the system has struct lifconf which is a extended struct ifconf * for IPv6. */ @ISC_PLATFORM_HAVELIFCONF@ /*! \brief * Define if the system has struct if_laddrconf which is a extended struct * ifconf for IPv6. */ @ISC_PLATFORM_HAVEIF_LADDRCONF@ /*! \brief * Define if the system has struct if_laddrreq. */ @ISC_PLATFORM_HAVEIF_LADDRREQ@ /*! \brief * Define either ISC_PLATFORM_BSD44MSGHDR or ISC_PLATFORM_BSD43MSGHDR. */ @ISC_PLATFORM_MSGHDRFLAVOR@ /*! \brief * Define if the system supports if_nametoindex. */ @ISC_PLATFORM_HAVEIFNAMETOINDEX@ /*! \brief * Define on some UnixWare systems to fix erroneous definitions of various * IN6_IS_ADDR_* macros. */ @ISC_PLATFORM_FIXIN6ISADDR@ /*! \brief * Define if the system has struct sockaddr_storage. */ @ISC_PLATFORM_HAVESOCKADDRSTORAGE@ /*! \brief * Define if the system supports kqueue multiplexing */ @ISC_PLATFORM_HAVEKQUEUE@ /*! \brief * Define if the system supports epoll multiplexing */ @ISC_PLATFORM_HAVEEPOLL@ /*! \brief * Define if the system supports /dev/poll multiplexing */ @ISC_PLATFORM_HAVEDEVPOLL@ /*! \brief * Define if we want to log backtrace */ @ISC_PLATFORM_USEBACKTRACE@ /* *** Printing. ***/ /*! \brief * If this system needs vsnprintf() and snprintf(), ISC_PLATFORM_NEEDVSNPRINTF * will be defined. */ @ISC_PLATFORM_NEEDVSNPRINTF@ /*! \brief * If this system need a modern sprintf() that returns (int) not (char*). */ @ISC_PLATFORM_NEEDSPRINTF@ /*! \brief * If this system need a modern printf() that format size %z (size_t). */ @ISC_PLATFORM_NEEDPRINTF@ /*! \brief * If this system need a modern fprintf() that format size %z (size_t). */ @ISC_PLATFORM_NEEDFPRINTF@ /*! \brief * The printf format string modifier to use with isc_uint64_t values. */ @ISC_PLATFORM_QUADFORMAT@ /*** *** String functions. ***/ /* * If the system needs strsep(), ISC_PLATFORM_NEEDSTRSEP will be defined. */ @ISC_PLATFORM_NEEDSTRSEP@ /* * If the system needs strlcpy(), ISC_PLATFORM_NEEDSTRLCPY will be defined. */ @ISC_PLATFORM_NEEDSTRLCPY@ /* * If the system needs strlcat(), ISC_PLATFORM_NEEDSTRLCAT will be defined. */ @ISC_PLATFORM_NEEDSTRLCAT@ /* * Define if this system needs strtoul. */ @ISC_PLATFORM_NEEDSTRTOUL@ /* * Define if this system needs memmove. */ @ISC_PLATFORM_NEEDMEMMOVE@ /* * Define if this system needs strcasestr. */ @ISC_PLATFORM_NEEDSTRCASESTR@ /*** *** Miscellaneous. ***/ /* * Defined if we are using threads. */ @ISC_PLATFORM_USETHREADS@ /* * Defined if unistd.h does not cause fd_set to be delared. */ @ISC_PLATFORM_NEEDSYSSELECTH@ /* * Defined to or for how to include * the GSSAPI header. */ @ISC_PLATFORM_GSSAPIHEADER@ /* * Defined to or for how to * include the GSSAPI KRB5 header. */ @ISC_PLATFORM_GSSAPI_KRB5_HEADER@ /* * Defined to or for how to include * the KRB5 header. */ @ISC_PLATFORM_KRB5HEADER@ /* * Type used for resource limits. */ @ISC_PLATFORM_RLIMITTYPE@ /* * Define if your compiler supports "long long int". */ @ISC_PLATFORM_HAVELONGLONG@ /* * Define if PTHREAD_ONCE_INIT should be surrounded by braces to * prevent compiler warnings (such as with gcc on Solaris 2.8). */ @ISC_PLATFORM_BRACEPTHREADONCEINIT@ /* * Used to control how extern data is linked; needed for Win32 platforms. */ @ISC_PLATFORM_USEDECLSPEC@ /* * Define if the platform has . */ @ISC_PLATFORM_HAVESYSUNH@ /* * If the "xadd" operation is available on this architecture, * ISC_PLATFORM_HAVEXADD will be defined. */ @ISC_PLATFORM_HAVEXADD@ /* * If the "xaddq" operation (64bit xadd) is available on this architecture, * ISC_PLATFORM_HAVEXADDQ will be defined. */ @ISC_PLATFORM_HAVEXADDQ@ /* * If the "atomic swap" operation is available on this architecture, * ISC_PLATFORM_HAVEATOMICSTORE" will be defined. */ @ISC_PLATFORM_HAVEATOMICSTORE@ /* * If the "compare-and-exchange" operation is available on this architecture, * ISC_PLATFORM_HAVECMPXCHG will be defined. */ @ISC_PLATFORM_HAVECMPXCHG@ /* * Define if gcc ASM extension is available */ @ISC_PLATFORM_USEGCCASM@ /* * Define if Tru64 style ASM syntax must be used. */ @ISC_PLATFORM_USEOSFASM@ /* * Define if the standard __asm function must be used. */ @ISC_PLATFORM_USESTDASM@ /* * Define if the platform has . */ @ISC_PLATFORM_HAVESTRINGSH@ /* * Define if the hash functions must be provided by OpenSSL. */ @ISC_PLATFORM_OPENSSLHASH@ /* * Define if AES support is wanted */ @ISC_PLATFORM_WANTAES@ /* * Defines for the noreturn attribute. */ @ISC_PLATFORM_NORETURN_PRE@ @ISC_PLATFORM_NORETURN_POST@ /* * Defined if we are enabling SIT (Source Identity Token). */ @ISC_PLATFORM_USESIT@ /*** *** Windows dll support. ***/ /* * Define if MacOS style of PPC assembly must be used. * e.g. "r6", not "6", for register six. */ @ISC_PLATFORM_USEMACASM@ #ifndef ISC_PLATFORM_USEDECLSPEC #define LIBISC_EXTERNAL_DATA #define LIBDNS_EXTERNAL_DATA #define LIBISCCC_EXTERNAL_DATA #define LIBISCCFG_EXTERNAL_DATA #define LIBBIND9_EXTERNAL_DATA #define LIBTESTS_EXTERNAL_DATA #else /*! \brief ISC_PLATFORM_USEDECLSPEC */ #ifdef LIBISC_EXPORTS #define LIBISC_EXTERNAL_DATA __declspec(dllexport) #else #define LIBISC_EXTERNAL_DATA __declspec(dllimport) #endif #ifdef LIBDNS_EXPORTS #define LIBDNS_EXTERNAL_DATA __declspec(dllexport) #else #define LIBDNS_EXTERNAL_DATA __declspec(dllimport) #endif #ifdef LIBISCCC_EXPORTS #define LIBISCCC_EXTERNAL_DATA __declspec(dllexport) #else #define LIBISCCC_EXTERNAL_DATA __declspec(dllimport) #endif #ifdef LIBISCCFG_EXPORTS #define LIBISCCFG_EXTERNAL_DATA __declspec(dllexport) #else #define LIBISCCFG_EXTERNAL_DATA __declspec(dllimport) #endif #ifdef LIBBIND9_EXPORTS #define LIBBIND9_EXTERNAL_DATA __declspec(dllexport) #else #define LIBBIND9_EXTERNAL_DATA __declspec(dllimport) #endif #ifdef LIBTESTS_EXPORTS #define LIBTESTS_EXTERNAL_DATA __declspec(dllexport) #else #define LIBTESTS_EXTERNAL_DATA __declspec(dllimport) #endif #endif /*! \brief ISC_PLATFORM_USEDECLSPEC */ /* * Tell emacs to use C mode for this file. * * Local Variables: * mode: c * End: */ #endif /* ISC_PLATFORM_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/Makefile.in0000644000470500017500000000425012664710322021164 0ustar lamontlamont# Copyright (C) 2004-2009, 2012-2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001, 2003 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ # # Only list headers that are to be installed and are not # machine generated. The latter are handled specially in the # install target below. # HEADERS = aes.h app.h assertions.h backtrace.h base32.h base64.h \ bind9.h boolean.h buffer.h bufferlist.h \ commandline.h counter.h crc64.h entropy.h error.h event.h \ eventclass.h file.h formatcheck.h fsaccess.h \ hash.h heap.h hex.h hmacmd5.h hmacsha.h httpd.h \ interfaceiter.h @ISC_IPV6_H@ iterated_hash.h json.h \ lang.h lex.h lfsr.h lib.h list.h log.h \ magic.h md5.h mem.h msgcat.h msgs.h mutexblock.h \ netaddr.h netscope.h ondestroy.h os.h parseint.h \ pool.h portset.h print.h queue.h quota.h \ radix.h random.h ratelimiter.h refcount.h regex.h \ region.h resource.h result.h resultclass.h rwlock.h \ safe.h serial.h sha1.h sha2.h sockaddr.h socket.h \ stats.h stdio.h stdlib.h string.h symtab.h \ task.h taskpool.h timer.h tm.h types.h util.h version.h \ xml.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/isc ; \ done ${INSTALL_DATA} platform.h ${DESTDIR}${includedir}/isc distclean:: rm -f platform.h bind9-9.10.3.dfsg.P4/lib/isc/include/isc/taskpool.h0000644000470500017500000001013012664710322021116 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef ISC_TASKPOOL_H #define ISC_TASKPOOL_H 1 /***** ***** Module Info *****/ /*! \file isc/taskpool.h * \brief A task pool is a mechanism for sharing a small number of tasks * among a large number of objects such that each object is * assigned a unique task, but each task may be shared by several * objects. * * Task pools are used to let objects that can exist in large * numbers (e.g., zones) use tasks for synchronization without * the memory overhead and unfair scheduling competition that * could result from creating a separate task for each object. */ /*** *** Imports. ***/ #include #include ISC_LANG_BEGINDECLS /***** ***** Types. *****/ typedef struct isc_taskpool isc_taskpool_t; /***** ***** Functions. *****/ isc_result_t isc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx, unsigned int ntasks, unsigned int quantum, isc_taskpool_t **poolp); /*%< * Create a task pool of "ntasks" tasks, each with quantum * "quantum". * * Requires: * *\li 'tmgr' is a valid task manager. * *\li 'mctx' is a valid memory context. * *\li poolp != NULL && *poolp == NULL * * Ensures: * *\li On success, '*taskp' points to the new task pool. * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li #ISC_R_UNEXPECTED */ void isc_taskpool_gettask(isc_taskpool_t *pool, isc_task_t **targetp); /*%< * Attach to a task from the pool. Currently the next task is chosen * from the pool at random. (This may be changed in the future to * something that guaratees balance.) */ int isc_taskpool_size(isc_taskpool_t *pool); /*%< * Returns the number of tasks in the task pool 'pool'. */ isc_result_t isc_taskpool_expand(isc_taskpool_t **sourcep, unsigned int size, isc_taskpool_t **targetp); /*%< * If 'size' is larger than the number of tasks in the pool pointed to by * 'sourcep', then a new taskpool of size 'size' is allocated, the existing * tasks from are moved into it, additional tasks are created to bring the * total number up to 'size', and the resulting pool is attached to * 'targetp'. * * If 'size' is less than or equal to the tasks in pool 'source', then * 'sourcep' is attached to 'targetp' without any other action being taken. * * In either case, 'sourcep' is detached. * * Requires: * * \li 'sourcep' is not NULL and '*source' is not NULL * \li 'targetp' is not NULL and '*source' is NULL * * Ensures: * * \li On success, '*targetp' points to a valid task pool. * \li On success, '*sourcep' points to NULL. * * Returns: * * \li #ISC_R_SUCCESS * \li #ISC_R_NOMEMORY */ void isc_taskpool_destroy(isc_taskpool_t **poolp); /*%< * Destroy a task pool. The tasks in the pool are detached but not * shut down. * * Requires: * \li '*poolp' is a valid task pool. */ void isc_taskpool_setprivilege(isc_taskpool_t *pool, isc_boolean_t priv); /*%< * Set the privilege flag on all tasks in 'pool' to 'priv'. If 'priv' is * true, then when the task manager is set into privileged mode, only * tasks wihin this pool will be able to execute. (Note: It is important * to turn the pool tasks' privilege back off before the last task finishes * executing.) * * Requires: * \li 'pool' is a valid task pool. */ ISC_LANG_ENDDECLS #endif /* ISC_TASKPOOL_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/json.h0000644000470500017500000000351312664710322020242 0ustar lamontlamont/* * Copyright (C) 2013, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef ISC_JSON_H #define ISC_JSON_H 1 #ifdef HAVE_JSON /* * This file is here mostly to make it easy to add additional libjson header * files as needed across all the users of this file. Rather than place * these libjson includes in each file, one include makes it easy to handle * the ifdef as well as adding the ability to add additional functions * which may be useful. */ #ifdef HAVE_JSON_C /* * We don't include as the subsequent includes do not * prefix the header file names with "json-c/" and using * -I /include/json-c results in too many filename collisions. */ #include #include #include #include #include #include #else #include #endif #endif #define ISC_JSON_RENDERCONFIG 0x00000001 /* render config data */ #define ISC_JSON_RENDERSTATS 0x00000002 /* render stats */ #define ISC_JSON_RENDERALL 0x000000ff /* render everything */ #endif /* ISC_JSON_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/task.h0000644000470500017500000005244212664710322020240 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef ISC_TASK_H #define ISC_TASK_H 1 /***** ***** Module Info *****/ /*! \file isc/task.h * \brief The task system provides a lightweight execution context, which is * basically an event queue. * When a task's event queue is non-empty, the * task is runnable. A small work crew of threads, typically one per CPU, * execute runnable tasks by dispatching the events on the tasks' event * queues. Context switching between tasks is fast. * * \li MP: * The module ensures appropriate synchronization of data structures it * creates and manipulates. * The caller must ensure that isc_taskmgr_destroy() is called only * once for a given manager. * * \li Reliability: * No anticipated impact. * * \li Resources: * TBS * * \li Security: * No anticipated impact. * * \li Standards: * None. * * \section purge Purging and Unsending * * Events which have been queued for a task but not delivered may be removed * from the task's event queue by purging or unsending. * * With both types, the caller specifies a matching pattern that selects * events based upon their sender, type, and tag. * * Purging calls isc_event_free() on the matching events. * * Unsending returns a list of events that matched the pattern. * The caller is then responsible for them. * * Consumers of events should purge, not unsend. * * Producers of events often want to remove events when the caller indicates * it is no longer interested in the object, e.g. by canceling a timer. * Sometimes this can be done by purging, but for some event types, the * calls to isc_event_free() cause deadlock because the event free routine * wants to acquire a lock the caller is already holding. Unsending instead * of purging solves this problem. As a general rule, producers should only * unsend events which they have sent. */ /*** *** Imports. ***/ #include #include #include #include #include #include #define ISC_TASKEVENT_FIRSTEVENT (ISC_EVENTCLASS_TASK + 0) #define ISC_TASKEVENT_SHUTDOWN (ISC_EVENTCLASS_TASK + 1) #define ISC_TASKEVENT_TEST (ISC_EVENTCLASS_TASK + 1) #define ISC_TASKEVENT_LASTEVENT (ISC_EVENTCLASS_TASK + 65535) /***** ***** Tasks. *****/ ISC_LANG_BEGINDECLS /*** *** Types ***/ typedef enum { isc_taskmgrmode_normal = 0, isc_taskmgrmode_privileged } isc_taskmgrmode_t; /*% Task and task manager methods */ typedef struct isc_taskmgrmethods { void (*destroy)(isc_taskmgr_t **managerp); void (*setmode)(isc_taskmgr_t *manager, isc_taskmgrmode_t mode); isc_taskmgrmode_t (*mode)(isc_taskmgr_t *manager); isc_result_t (*taskcreate)(isc_taskmgr_t *manager, unsigned int quantum, isc_task_t **taskp); void (*setexcltask)(isc_taskmgr_t *mgr, isc_task_t *task); isc_result_t (*excltask)(isc_taskmgr_t *mgr, isc_task_t **taskp); } isc_taskmgrmethods_t; typedef struct isc_taskmethods { void (*attach)(isc_task_t *source, isc_task_t **targetp); void (*detach)(isc_task_t **taskp); void (*destroy)(isc_task_t **taskp); void (*send)(isc_task_t *task, isc_event_t **eventp); void (*sendanddetach)(isc_task_t **taskp, isc_event_t **eventp); unsigned int (*unsend)(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag, isc_eventlist_t *events); isc_result_t (*onshutdown)(isc_task_t *task, isc_taskaction_t action, void *arg); void (*shutdown)(isc_task_t *task); void (*setname)(isc_task_t *task, const char *name, void *tag); unsigned int (*purgeevents)(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag); unsigned int (*purgerange)(isc_task_t *task, void *sender, isc_eventtype_t first, isc_eventtype_t last, void *tag); isc_result_t (*beginexclusive)(isc_task_t *task); void (*endexclusive)(isc_task_t *task); void (*setprivilege)(isc_task_t *task, isc_boolean_t priv); isc_boolean_t (*privilege)(isc_task_t *task); } isc_taskmethods_t; /*% * This structure is actually just the common prefix of a task manager * object implementation's version of an isc_taskmgr_t. * \brief * Direct use of this structure by clients is forbidden. task implementations * may change the structure. 'magic' must be ISCAPI_TASKMGR_MAGIC for any * of the isc_task_ routines to work. task implementations must maintain * all task invariants. */ struct isc_taskmgr { unsigned int impmagic; unsigned int magic; isc_taskmgrmethods_t *methods; }; #define ISCAPI_TASKMGR_MAGIC ISC_MAGIC('A','t','m','g') #define ISCAPI_TASKMGR_VALID(m) ((m) != NULL && \ (m)->magic == ISCAPI_TASKMGR_MAGIC) /*% * This is the common prefix of a task object. The same note as * that for the taskmgr structure applies. */ struct isc_task { unsigned int impmagic; unsigned int magic; isc_taskmethods_t *methods; }; #define ISCAPI_TASK_MAGIC ISC_MAGIC('A','t','s','t') #define ISCAPI_TASK_VALID(s) ((s) != NULL && \ (s)->magic == ISCAPI_TASK_MAGIC) isc_result_t isc_task_create(isc_taskmgr_t *manager, unsigned int quantum, isc_task_t **taskp); /*%< * Create a task. * * Notes: * *\li If 'quantum' is non-zero, then only that many events can be dispatched * before the task must yield to other tasks waiting to execute. If * quantum is zero, then the default quantum of the task manager will * be used. * *\li The 'quantum' option may be removed from isc_task_create() in the * future. If this happens, isc_task_getquantum() and * isc_task_setquantum() will be provided. * * Requires: * *\li 'manager' is a valid task manager. * *\li taskp != NULL && *taskp == NULL * * Ensures: * *\li On success, '*taskp' is bound to the new task. * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li #ISC_R_UNEXPECTED *\li #ISC_R_SHUTTINGDOWN */ void isc_task_attach(isc_task_t *source, isc_task_t **targetp); /*%< * Attach *targetp to source. * * Requires: * *\li 'source' is a valid task. * *\li 'targetp' points to a NULL isc_task_t *. * * Ensures: * *\li *targetp is attached to source. */ void isc_task_detach(isc_task_t **taskp); /*%< * Detach *taskp from its task. * * Requires: * *\li '*taskp' is a valid task. * * Ensures: * *\li *taskp is NULL. * *\li If '*taskp' is the last reference to the task, the task is idle (has * an empty event queue), and has not been shutdown, the task will be * shutdown. * *\li If '*taskp' is the last reference to the task and * the task has been shutdown, * all resources used by the task will be freed. */ void isc_task_send(isc_task_t *task, isc_event_t **eventp); /*%< * Send '*event' to 'task'. * * Requires: * *\li 'task' is a valid task. *\li eventp != NULL && *eventp != NULL. * * Ensures: * *\li *eventp == NULL. */ void isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp); /*%< * Send '*event' to '*taskp' and then detach '*taskp' from its * task. * * Requires: * *\li '*taskp' is a valid task. *\li eventp != NULL && *eventp != NULL. * * Ensures: * *\li *eventp == NULL. * *\li *taskp == NULL. * *\li If '*taskp' is the last reference to the task, the task is * idle (has an empty event queue), and has not been shutdown, * the task will be shutdown. * *\li If '*taskp' is the last reference to the task and * the task has been shutdown, * all resources used by the task will be freed. */ unsigned int isc_task_purgerange(isc_task_t *task, void *sender, isc_eventtype_t first, isc_eventtype_t last, void *tag); /*%< * Purge events from a task's event queue. * * Requires: * *\li 'task' is a valid task. * *\li last >= first * * Ensures: * *\li Events in the event queue of 'task' whose sender is 'sender', whose * type is >= first and <= last, and whose tag is 'tag' will be purged, * unless they are marked as unpurgable. * *\li A sender of NULL will match any sender. A NULL tag matches any * tag. * * Returns: * *\li The number of events purged. */ unsigned int isc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag); /*%< * Purge events from a task's event queue. * * Notes: * *\li This function is equivalent to * *\code * isc_task_purgerange(task, sender, type, type, tag); *\endcode * * Requires: * *\li 'task' is a valid task. * * Ensures: * *\li Events in the event queue of 'task' whose sender is 'sender', whose * type is 'type', and whose tag is 'tag' will be purged, unless they * are marked as unpurgable. * *\li A sender of NULL will match any sender. A NULL tag matches any * tag. * * Returns: * *\li The number of events purged. */ isc_boolean_t isc_task_purgeevent(isc_task_t *task, isc_event_t *event); /*%< * Purge 'event' from a task's event queue. * * XXXRTH: WARNING: This method may be removed before beta. * * Notes: * *\li If 'event' is on the task's event queue, it will be purged, * unless it is marked as unpurgeable. 'event' does not have to be * on the task's event queue; in fact, it can even be an invalid * pointer. Purging only occurs if the event is actually on the task's * event queue. * * \li Purging never changes the state of the task. * * Requires: * *\li 'task' is a valid task. * * Ensures: * *\li 'event' is not in the event queue for 'task'. * * Returns: * *\li #ISC_TRUE The event was purged. *\li #ISC_FALSE The event was not in the event queue, * or was marked unpurgeable. */ unsigned int isc_task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first, isc_eventtype_t last, void *tag, isc_eventlist_t *events); /*%< * Remove events from a task's event queue. * * Requires: * *\li 'task' is a valid task. * *\li last >= first. * *\li *events is a valid list. * * Ensures: * *\li Events in the event queue of 'task' whose sender is 'sender', whose * type is >= first and <= last, and whose tag is 'tag' will be dequeued * and appended to *events. * *\li A sender of NULL will match any sender. A NULL tag matches any * tag. * * Returns: * *\li The number of events unsent. */ unsigned int isc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag, isc_eventlist_t *events); /*%< * Remove events from a task's event queue. * * Notes: * *\li This function is equivalent to * *\code * isc_task_unsendrange(task, sender, type, type, tag, events); *\endcode * * Requires: * *\li 'task' is a valid task. * *\li *events is a valid list. * * Ensures: * *\li Events in the event queue of 'task' whose sender is 'sender', whose * type is 'type', and whose tag is 'tag' will be dequeued and appended * to *events. * * Returns: * *\li The number of events unsent. */ isc_result_t isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action, void *arg); /*%< * Send a shutdown event with action 'action' and argument 'arg' when * 'task' is shutdown. * * Notes: * *\li Shutdown events are posted in LIFO order. * * Requires: * *\li 'task' is a valid task. * *\li 'action' is a valid task action. * * Ensures: * *\li When the task is shutdown, shutdown events requested with * isc_task_onshutdown() will be appended to the task's event queue. * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li #ISC_R_TASKSHUTTINGDOWN Task is shutting down. */ void isc_task_shutdown(isc_task_t *task); /*%< * Shutdown 'task'. * * Notes: * *\li Shutting down a task causes any shutdown events requested with * isc_task_onshutdown() to be posted (in LIFO order). The task * moves into a "shutting down" mode which prevents further calls * to isc_task_onshutdown(). * *\li Trying to shutdown a task that has already been shutdown has no * effect. * * Requires: * *\li 'task' is a valid task. * * Ensures: * *\li Any shutdown events requested with isc_task_onshutdown() have been * posted (in LIFO order). */ void isc_task_destroy(isc_task_t **taskp); /*%< * Destroy '*taskp'. * * Notes: * *\li This call is equivalent to: * *\code * isc_task_shutdown(*taskp); * isc_task_detach(taskp); *\endcode * * Requires: * * '*taskp' is a valid task. * * Ensures: * *\li Any shutdown events requested with isc_task_onshutdown() have been * posted (in LIFO order). * *\li *taskp == NULL * *\li If '*taskp' is the last reference to the task, * all resources used by the task will be freed. */ void isc_task_setname(isc_task_t *task, const char *name, void *tag); /*%< * Name 'task'. * * Notes: * *\li Only the first 15 characters of 'name' will be copied. * *\li Naming a task is currently only useful for debugging purposes. * * Requires: * *\li 'task' is a valid task. */ const char * isc_task_getname(isc_task_t *task); /*%< * Get the name of 'task', as previously set using isc_task_setname(). * * Notes: *\li This function is for debugging purposes only. * * Requires: *\li 'task' is a valid task. * * Returns: *\li A non-NULL pointer to a null-terminated string. * If the task has not been named, the string is * empty. * */ void * isc_task_gettag(isc_task_t *task); /*%< * Get the tag value for 'task', as previously set using isc_task_settag(). * * Notes: *\li This function is for debugging purposes only. * * Requires: *\li 'task' is a valid task. */ isc_result_t isc_task_beginexclusive(isc_task_t *task); /*%< * Request exclusive access for 'task', which must be the calling * task. Waits for any other concurrently executing tasks to finish their * current event, and prevents any new events from executing in any of the * tasks sharing a task manager with 'task'. * * The exclusive access must be relinquished by calling * isc_task_endexclusive() before returning from the current event handler. * * Requires: *\li 'task' is the calling task. * * Returns: *\li #ISC_R_SUCCESS The current task now has exclusive access. *\li #ISC_R_LOCKBUSY Another task has already requested exclusive * access. */ void isc_task_endexclusive(isc_task_t *task); /*%< * Relinquish the exclusive access obtained by isc_task_beginexclusive(), * allowing other tasks to execute. * * Requires: *\li 'task' is the calling task, and has obtained * exclusive access by calling isc_task_spl(). */ void isc_task_getcurrenttime(isc_task_t *task, isc_stdtime_t *t); /*%< * Provide the most recent timestamp on the task. The timestamp is considered * as the "current time" in the second-order granularity. * * Requires: *\li 'task' is a valid task. *\li 't' is a valid non NULL pointer. * * Ensures: *\li '*t' has the "current time". */ isc_boolean_t isc_task_exiting(isc_task_t *t); /*%< * Returns ISC_TRUE if the task is in the process of shutting down, * ISC_FALSE otherwise. * * Requires: *\li 'task' is a valid task. */ void isc_task_setprivilege(isc_task_t *task, isc_boolean_t priv); /*%< * Set or unset the task's "privileged" flag depending on the value of * 'priv'. * * Under normal circumstances this flag has no effect on the task behavior, * but when the task manager has been set to privileged execution mode via * isc_taskmgr_setmode(), only tasks with the flag set will be executed, * and all other tasks will wait until they're done. Once all privileged * tasks have finished executing, the task manager will automatically * return to normal execution mode and nonprivileged task can resume. * * Requires: *\li 'task' is a valid task. */ isc_boolean_t isc_task_privilege(isc_task_t *task); /*%< * Returns the current value of the task's privilege flag. * * Requires: *\li 'task' is a valid task. */ /***** ***** Task Manager. *****/ isc_result_t isc_taskmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx, unsigned int workers, unsigned int default_quantum, isc_taskmgr_t **managerp); isc_result_t isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers, unsigned int default_quantum, isc_taskmgr_t **managerp); /*%< * Create a new task manager. isc_taskmgr_createinctx() also associates * the new manager with the specified application context. * * Notes: * *\li 'workers' in the number of worker threads to create. In general, * the value should be close to the number of processors in the system. * The 'workers' value is advisory only. An attempt will be made to * create 'workers' threads, but if at least one thread creation * succeeds, isc_taskmgr_create() may return ISC_R_SUCCESS. * *\li If 'default_quantum' is non-zero, then it will be used as the default * quantum value when tasks are created. If zero, then an implementation * defined default quantum will be used. * * Requires: * *\li 'mctx' is a valid memory context. * *\li workers > 0 * *\li managerp != NULL && *managerp == NULL * *\li 'actx' is a valid application context (for createinctx()). * * Ensures: * *\li On success, '*managerp' will be attached to the newly created task * manager. * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li #ISC_R_NOTHREADS No threads could be created. *\li #ISC_R_UNEXPECTED An unexpected error occurred. *\li #ISC_R_SHUTTINGDOWN The non-threaded, shared, task * manager shutting down. */ void isc_taskmgr_setmode(isc_taskmgr_t *manager, isc_taskmgrmode_t mode); isc_taskmgrmode_t isc_taskmgr_mode(isc_taskmgr_t *manager); /*%< * Set/get the current operating mode of the task manager. Valid modes are: * *\li isc_taskmgrmode_normal *\li isc_taskmgrmode_privileged * * In privileged execution mode, only tasks that have had the "privilege" * flag set via isc_task_setprivilege() can be executed. When all such * tasks are complete, the manager automatically returns to normal mode * and proceeds with running non-privileged ready tasks. This means it is * necessary to have at least one privileged task waiting on the ready * queue *before* setting the manager into privileged execution mode, * which in turn means the task which calls this function should be in * task-exclusive mode when it does so. * * Requires: * *\li 'manager' is a valid task manager. */ void isc_taskmgr_destroy(isc_taskmgr_t **managerp); /*%< * Destroy '*managerp'. * * Notes: * *\li Calling isc_taskmgr_destroy() will shutdown all tasks managed by * *managerp that haven't already been shutdown. The call will block * until all tasks have entered the done state. * *\li isc_taskmgr_destroy() must not be called by a task event action, * because it would block forever waiting for the event action to * complete. An event action that wants to cause task manager shutdown * should request some non-event action thread of execution to do the * shutdown, e.g. by signaling a condition variable or using * isc_app_shutdown(). * *\li Task manager references are not reference counted, so the caller * must ensure that no attempt will be made to use the manager after * isc_taskmgr_destroy() returns. * * Requires: * *\li '*managerp' is a valid task manager. * *\li isc_taskmgr_destroy() has not be called previously on '*managerp'. * * Ensures: * *\li All resources used by the task manager, and any tasks it managed, * have been freed. */ void isc_taskmgr_setexcltask(isc_taskmgr_t *mgr, isc_task_t *task); /*%< * Set a task which will be used for all task-exclusive operations. * * Requires: *\li 'manager' is a valid task manager. * *\li 'task' is a valid task. */ isc_result_t isc_taskmgr_excltask(isc_taskmgr_t *mgr, isc_task_t **taskp); /*%< * Attach '*taskp' to the task set by isc_taskmgr_getexcltask(). * This task should be used whenever running in task-exclusive mode, * so as to prevent deadlock between two exclusive tasks. * * Requires: *\li 'manager' is a valid task manager. *\li taskp != NULL && *taskp == NULL */ #ifdef HAVE_LIBXML2 int isc_taskmgr_renderxml(isc_taskmgr_t *mgr, xmlTextWriterPtr writer); #endif #ifdef HAVE_JSON isc_result_t isc_taskmgr_renderjson(isc_taskmgr_t *mgr, json_object *tasksobj); #endif /*%< * See isc_taskmgr_create() above. */ typedef isc_result_t (*isc_taskmgrcreatefunc_t)(isc_mem_t *mctx, unsigned int workers, unsigned int default_quantum, isc_taskmgr_t **managerp); isc_result_t isc_task_register(isc_taskmgrcreatefunc_t createfunc); /*%< * Register a new task management implementation and add it to the list of * supported implementations. This function must be called when a different * event library is used than the one contained in the ISC library. */ isc_result_t isc__task_register(void); /*%< * A short cut function that specifies the task management module in the ISC * library for isc_task_register(). An application that uses the ISC library * usually do not have to care about this function: it would call * isc_lib_register(), which internally calls this function. */ ISC_LANG_ENDDECLS #endif /* ISC_TASK_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/bufferlist.h0000644000470500017500000000367312664710322021445 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: bufferlist.h,v 1.17 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_BUFFERLIST_H #define ISC_BUFFERLIST_H 1 /***** ***** Module Info *****/ /*! \file isc/bufferlist.h * * *\brief Buffer lists have no synchronization. Clients must ensure exclusive * access. * * \li Reliability: * No anticipated impact. * \li Security: * No anticipated impact. * * \li Standards: * None. */ /*** *** Imports ***/ #include #include ISC_LANG_BEGINDECLS /*** *** Functions ***/ unsigned int isc_bufferlist_usedcount(isc_bufferlist_t *bl); /*!< * \brief Return the length of the sum of all used regions of all buffers in * the buffer list 'bl' * * Requires: * *\li 'bl' is not NULL. * * Returns: *\li sum of all used regions' lengths. */ unsigned int isc_bufferlist_availablecount(isc_bufferlist_t *bl); /*!< * \brief Return the length of the sum of all available regions of all buffers in * the buffer list 'bl' * * Requires: * *\li 'bl' is not NULL. * * Returns: *\li sum of all available regions' lengths. */ ISC_LANG_ENDDECLS #endif /* ISC_BUFFERLIST_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/magic.h0000644000470500017500000000267712664710322020363 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: magic.h,v 1.18 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_MAGIC_H #define ISC_MAGIC_H 1 /*! \file isc/magic.h */ typedef struct { unsigned int magic; } isc__magic_t; /*% * To use this macro the magic number MUST be the first thing in the * structure, and MUST be of type "unsigned int". * The intent of this is to allow magic numbers to be checked even though * the object is otherwise opaque. */ #define ISC_MAGIC_VALID(a,b) (((a) != NULL) && \ (((const isc__magic_t *)(a))->magic == (b))) #define ISC_MAGIC(a, b, c, d) ((a) << 24 | (b) << 16 | (c) << 8 | (d)) #endif /* ISC_MAGIC_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/pool.h0000644000470500017500000000750012664710322020242 0ustar lamontlamont/* * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef ISC_OBJPOOL_H #define ISC_OBJPOOL_H 1 /***** ***** Module Info *****/ /*! \file isc/pool.h * \brief An object pool is a mechanism for sharing a small pool of * fungible objects among a large number of objects that depend on them. * * This is useful, for example, when it causes performance problems for * large number of zones to share a single memory context or task object, * but it would create a different set of problems for them each to have an * independent task or memory context. */ /*** *** Imports. ***/ #include #include #include ISC_LANG_BEGINDECLS /***** ***** Types. *****/ typedef void (*isc_pooldeallocator_t)(void **object); typedef isc_result_t (*isc_poolinitializer_t)(void **target, void *arg); typedef struct isc_pool isc_pool_t; /***** ***** Functions. *****/ isc_result_t isc_pool_create(isc_mem_t *mctx, unsigned int count, isc_pooldeallocator_t free, isc_poolinitializer_t init, void *initarg, isc_pool_t **poolp); /*%< * Create a pool of "count" object pointers. If 'free' is not NULL, * it points to a function that will detach the objects. 'init' * points to a function that will initialize the arguments, and * 'arg' to an argument to be passed into that function (for example, * a relevant manager or context object). * * Requires: * *\li 'mctx' is a valid memory context. * *\li init != NULL * *\li poolp != NULL && *poolp == NULL * * Ensures: * *\li On success, '*poolp' points to the new object pool. * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li #ISC_R_UNEXPECTED */ void * isc_pool_get(isc_pool_t *pool); /*%< * Returns a pointer to an object from the pool. Currently the object * is chosen from the pool at random. (This may be changed in the future * to something that guaratees balance.) */ int isc_pool_count(isc_pool_t *pool); /*%< * Returns the number of objcts in the pool 'pool'. */ isc_result_t isc_pool_expand(isc_pool_t **sourcep, unsigned int count, isc_pool_t **targetp); /*%< * If 'size' is larger than the number of objects in the pool pointed to by * 'sourcep', then a new pool of size 'count' is allocated, the existing * objects are copied into it, additional ones created to bring the * total number up to 'count', and the resulting pool is attached to * 'targetp'. * * If 'count' is less than or equal to the number of objects in 'source', then * 'sourcep' is attached to 'targetp' without any other action being taken. * * In either case, 'sourcep' is detached. * * Requires: * * \li 'sourcep' is not NULL and '*source' is not NULL * \li 'targetp' is not NULL and '*source' is NULL * * Ensures: * * \li On success, '*targetp' points to a valid task pool. * \li On success, '*sourcep' points to NULL. * * Returns: * * \li #ISC_R_SUCCESS * \li #ISC_R_NOMEMORY */ void isc_pool_destroy(isc_pool_t **poolp); /*%< * Destroy a task pool. The tasks in the pool are detached but not * shut down. * * Requires: * \li '*poolp' is a valid task pool. */ ISC_LANG_ENDDECLS #endif /* ISC_OBJPOOL_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/portset.h0000644000470500017500000000725512664710322021000 0ustar lamontlamont/* * Copyright (C) 2008, 2009 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: portset.h,v 1.6 2009/06/25 05:28:34 marka Exp $ */ /*! \file isc/portset.h * \brief Transport Protocol Port Manipulation Module * * This module provides simple utilities to handle a set of transport protocol * (UDP or TCP) port numbers, e.g., for creating an ACL list. An isc_portset_t * object is an opaque instance of a port set, for which the user can add or * remove a specific port or a range of consecutive ports. This object is * expected to be used as a temporary work space only, and does not protect * simultaneous access from multiple threads. Therefore it must not be stored * in a place that can be accessed from multiple threads. */ #ifndef ISC_PORTSET_H #define ISC_PORTSET_H 1 /*** *** Imports ***/ #include /*** *** Functions ***/ ISC_LANG_BEGINDECLS isc_result_t isc_portset_create(isc_mem_t *mctx, isc_portset_t **portsetp); /*%< * Create a port set and initialize it as an empty set. * * Requires: *\li 'mctx' to be valid. *\li 'portsetp' to be non NULL and '*portsetp' to be NULL; * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY */ void isc_portset_destroy(isc_mem_t *mctx, isc_portset_t **portsetp); /*%< * Destroy a port set. * * Requires: *\li 'mctx' to be valid and must be the same context given when the port set * was created. *\li '*portsetp' to be a valid set. */ isc_boolean_t isc_portset_isset(isc_portset_t *portset, in_port_t port); /*%< * Test whether the given port is stored in the portset. * * Requires: *\li 'portset' to be a valid set. * * Returns * \li #ISC_TRUE if the port is found, ISC_FALSE otherwise. */ unsigned int isc_portset_nports(isc_portset_t *portset); /*%< * Provides the number of ports stored in the given portset. * * Requires: *\li 'portset' to be a valid set. * * Returns * \li the number of ports stored in portset. */ void isc_portset_add(isc_portset_t *portset, in_port_t port); /*%< * Add the given port to the portset. The port may or may not be stored in * the portset. * * Requires: *\li 'portlist' to be valid. */ void isc_portset_remove(isc_portset_t *portset, in_port_t port); /*%< * Remove the given port to the portset. The port may or may not be stored in * the portset. * * Requires: *\li 'portlist' to be valid. */ void isc_portset_addrange(isc_portset_t *portset, in_port_t port_lo, in_port_t port_hi); /*%< * Add a subset of [port_lo, port_hi] (inclusive) to the portset. Ports in the * subset may or may not be stored in portset. * * Requires: *\li 'portlist' to be valid. *\li port_lo <= port_hi */ void isc_portset_removerange(isc_portset_t *portset, in_port_t port_lo, in_port_t port_hi); /*%< * Subtract a subset of [port_lo, port_hi] (inclusive) from the portset. Ports * in the subset may or may not be stored in portset. * * Requires: *\li 'portlist' to be valid. *\li port_lo <= port_hi */ ISC_LANG_ENDDECLS #endif /* ISC_PORTSET_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/stdio.h0000644000470500017500000000433212664710322020413 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: stdio.h,v 1.13 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_STDIO_H #define ISC_STDIO_H 1 /*! \file isc/stdio.h */ /*% * These functions are wrappers around the corresponding stdio functions. * * They return a detailed error code in the form of an an isc_result_t. ANSI C * does not guarantee that stdio functions set errno, hence these functions * must use platform dependent methods (e.g., the POSIX errno) to construct the * error code. */ #include #include #include ISC_LANG_BEGINDECLS /*% Open */ isc_result_t isc_stdio_open(const char *filename, const char *mode, FILE **fp); /*% Close */ isc_result_t isc_stdio_close(FILE *f); /*% Seek */ isc_result_t isc_stdio_seek(FILE *f, off_t offset, int whence); /*% Tell */ isc_result_t isc_stdio_tell(FILE *f, off_t *offsetp); /*% Read */ isc_result_t isc_stdio_read(void *ptr, size_t size, size_t nmemb, FILE *f, size_t *nret); /*% Write */ isc_result_t isc_stdio_write(const void *ptr, size_t size, size_t nmemb, FILE *f, size_t *nret); /*% Flush */ isc_result_t isc_stdio_flush(FILE *f); isc_result_t isc_stdio_sync(FILE *f); /*%< * Invoke fsync() on the file descriptor underlying an stdio stream, or an * equivalent system-dependent operation. Note that this function has no * direct counterpart in the stdio library. */ ISC_LANG_ENDDECLS #endif /* ISC_STDIO_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/serial.h0000644000470500017500000000364712664710322020560 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: serial.h,v 1.18 2009/01/18 23:48:14 tbox Exp $ */ #ifndef ISC_SERIAL_H #define ISC_SERIAL_H 1 #include #include /*! \file isc/serial.h * \brief Implement 32 bit serial space arithmetic comparison functions. * Note: Undefined results are returned as ISC_FALSE. */ /*** *** Functions ***/ ISC_LANG_BEGINDECLS isc_boolean_t isc_serial_lt(isc_uint32_t a, isc_uint32_t b); /*%< * Return true if 'a' < 'b' otherwise false. */ isc_boolean_t isc_serial_gt(isc_uint32_t a, isc_uint32_t b); /*%< * Return true if 'a' > 'b' otherwise false. */ isc_boolean_t isc_serial_le(isc_uint32_t a, isc_uint32_t b); /*%< * Return true if 'a' <= 'b' otherwise false. */ isc_boolean_t isc_serial_ge(isc_uint32_t a, isc_uint32_t b); /*%< * Return true if 'a' >= 'b' otherwise false. */ isc_boolean_t isc_serial_eq(isc_uint32_t a, isc_uint32_t b); /*%< * Return true if 'a' == 'b' otherwise false. */ isc_boolean_t isc_serial_ne(isc_uint32_t a, isc_uint32_t b); /*%< * Return true if 'a' != 'b' otherwise false. */ ISC_LANG_ENDDECLS #endif /* ISC_SERIAL_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/parseint.h0000644000470500017500000000401212664710322021111 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001, 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: parseint.h,v 1.9 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_PARSEINT_H #define ISC_PARSEINT_H 1 #include #include /*! \file isc/parseint.h * \brief Parse integers, in a saner way than atoi() or strtoul() do. */ /*** *** Functions ***/ ISC_LANG_BEGINDECLS isc_result_t isc_parse_uint32(isc_uint32_t *uip, const char *string, int base); isc_result_t isc_parse_uint16(isc_uint16_t *uip, const char *string, int base); isc_result_t isc_parse_uint8(isc_uint8_t *uip, const char *string, int base); /*%< * Parse the null-terminated string 'string' containing a base 'base' * integer, storing the result in '*uip'. * The base is interpreted * as in strtoul(). Unlike strtoul(), leading whitespace, minus or * plus signs are not accepted, and all errors (including overflow) * are reported uniformly through the return value. * * Requires: *\li 'string' points to a null-terminated string *\li 0 <= 'base' <= 36 * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_BADNUMBER The string is not numeric (in the given base) *\li #ISC_R_RANGE The number is not representable as the requested type. */ ISC_LANG_ENDDECLS #endif /* ISC_PARSEINT_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/timer.h0000644000470500017500000002607412664710322020420 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2012-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: timer.h,v 1.43 2009/09/02 23:48:03 tbox Exp $ */ #ifndef ISC_TIMER_H #define ISC_TIMER_H 1 /***** ***** Module Info *****/ /*! \file isc/timer.h * \brief Provides timers which are event sources in the task system. * * Three types of timers are supported: * *\li 'ticker' timers generate a periodic tick event. * *\li 'once' timers generate an idle timeout event if they are idle for too * long, and generate a life timeout event if their lifetime expires. * They are used to implement both (possibly expiring) idle timers and * 'one-shot' timers. * *\li 'limited' timers generate a periodic tick event until they reach * their lifetime when they generate a life timeout event. * *\li 'inactive' timers generate no events. * * Timers can change type. It is typical to create a timer as * an 'inactive' timer and then change it into a 'ticker' or * 'once' timer. * *\li MP: * The module ensures appropriate synchronization of data structures it * creates and manipulates. * Clients of this module must not be holding a timer's task's lock when * making a call that affects that timer. Failure to follow this rule * can result in deadlock. * The caller must ensure that isc_timermgr_destroy() is called only * once for a given manager. * * \li Reliability: * No anticipated impact. * * \li Resources: * TBS * * \li Security: * No anticipated impact. * * \li Standards: * None. */ /*** *** Imports ***/ #include #include #include #include #include ISC_LANG_BEGINDECLS /*** *** Types ***/ /*% Timer Type */ typedef enum { isc_timertype_undefined = -1, /*%< Undefined */ isc_timertype_ticker = 0, /*%< Ticker */ isc_timertype_once = 1, /*%< Once */ isc_timertype_limited = 2, /*%< Limited */ isc_timertype_inactive = 3 /*%< Inactive */ } isc_timertype_t; typedef struct isc_timerevent { struct isc_event common; isc_time_t due; } isc_timerevent_t; #define ISC_TIMEREVENT_FIRSTEVENT (ISC_EVENTCLASS_TIMER + 0) #define ISC_TIMEREVENT_TICK (ISC_EVENTCLASS_TIMER + 1) #define ISC_TIMEREVENT_IDLE (ISC_EVENTCLASS_TIMER + 2) #define ISC_TIMEREVENT_LIFE (ISC_EVENTCLASS_TIMER + 3) #define ISC_TIMEREVENT_LASTEVENT (ISC_EVENTCLASS_TIMER + 65535) /*% Timer and timer manager methods */ typedef struct { void (*destroy)(isc_timermgr_t **managerp); isc_result_t (*timercreate)(isc_timermgr_t *manager, isc_timertype_t type, const isc_time_t *expires, const isc_interval_t *interval, isc_task_t *task, isc_taskaction_t action, void *arg, isc_timer_t **timerp); } isc_timermgrmethods_t; typedef struct { void (*attach)(isc_timer_t *timer, isc_timer_t **timerp); void (*detach)(isc_timer_t **timerp); isc_result_t (*reset)(isc_timer_t *timer, isc_timertype_t type, const isc_time_t *expires, const isc_interval_t *interval, isc_boolean_t purge); isc_result_t (*touch)(isc_timer_t *timer); } isc_timermethods_t; /*% * This structure is actually just the common prefix of a timer manager * object implementation's version of an isc_timermgr_t. * \brief * Direct use of this structure by clients is forbidden. timer implementations * may change the structure. 'magic' must be ISCAPI_TIMERMGR_MAGIC for any * of the isc_timer_ routines to work. timer implementations must maintain * all timer invariants. */ struct isc_timermgr { unsigned int impmagic; unsigned int magic; isc_timermgrmethods_t *methods; }; #define ISCAPI_TIMERMGR_MAGIC ISC_MAGIC('A','t','m','g') #define ISCAPI_TIMERMGR_VALID(m) ((m) != NULL && \ (m)->magic == ISCAPI_TIMERMGR_MAGIC) /*% * This is the common prefix of a timer object. The same note as * that for the timermgr structure applies. */ struct isc_timer { unsigned int impmagic; unsigned int magic; isc_timermethods_t *methods; }; #define ISCAPI_TIMER_MAGIC ISC_MAGIC('A','t','m','r') #define ISCAPI_TIMER_VALID(s) ((s) != NULL && \ (s)->magic == ISCAPI_TIMER_MAGIC) /*** *** Timer and Timer Manager Functions *** *** Note: all Ensures conditions apply only if the result is success for *** those functions which return an isc_result_t. ***/ isc_result_t isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type, const isc_time_t *expires, const isc_interval_t *interval, isc_task_t *task, isc_taskaction_t action, void *arg, isc_timer_t **timerp); /*%< * Create a new 'type' timer managed by 'manager'. The timers parameters * are specified by 'expires' and 'interval'. Events will be posted to * 'task' and when dispatched 'action' will be called with 'arg' as the * arg value. The new timer is returned in 'timerp'. * * Notes: * *\li For ticker timers, the timer will generate a 'tick' event every * 'interval' seconds. The value of 'expires' is ignored. * *\li For once timers, 'expires' specifies the time when a life timeout * event should be generated. If 'expires' is 0 (the epoch), then no life * timeout will be generated. 'interval' specifies how long the timer * can be idle before it generates an idle timeout. If 0, then no * idle timeout will be generated. * *\li If 'expires' is NULL, the epoch will be used. * * If 'interval' is NULL, the zero interval will be used. * * Requires: * *\li 'manager' is a valid manager * *\li 'task' is a valid task * *\li 'action' is a valid action * *\li 'expires' points to a valid time, or is NULL. * *\li 'interval' points to a valid interval, or is NULL. * *\li type == isc_timertype_inactive || * ('expires' and 'interval' are not both 0) * *\li 'timerp' is a valid pointer, and *timerp == NULL * * Ensures: * *\li '*timerp' is attached to the newly created timer * *\li The timer is attached to the task * *\li An idle timeout will not be generated until at least Now + the * timer's interval if 'timer' is a once timer with a non-zero * interval. * * Returns: * *\li Success *\li No memory *\li Unexpected error */ isc_result_t isc_timer_reset(isc_timer_t *timer, isc_timertype_t type, const isc_time_t *expires, const isc_interval_t *interval, isc_boolean_t purge); /*%< * Change the timer's type, expires, and interval values to the given * values. If 'purge' is TRUE, any pending events from this timer * are purged from its task's event queue. * * Notes: * *\li If 'expires' is NULL, the epoch will be used. * *\li If 'interval' is NULL, the zero interval will be used. * * Requires: * *\li 'timer' is a valid timer * *\li The same requirements that isc_timer_create() imposes on 'type', * 'expires' and 'interval' apply. * * Ensures: * *\li An idle timeout will not be generated until at least Now + the * timer's interval if 'timer' is a once timer with a non-zero * interval. * * Returns: * *\li Success *\li No memory *\li Unexpected error */ isc_result_t isc_timer_touch(isc_timer_t *timer); /*%< * Set the last-touched time of 'timer' to the current time. * * Requires: * *\li 'timer' is a valid once timer. * * Ensures: * *\li An idle timeout will not be generated until at least Now + the * timer's interval if 'timer' is a once timer with a non-zero * interval. * * Returns: * *\li Success *\li Unexpected error */ void isc_timer_attach(isc_timer_t *timer, isc_timer_t **timerp); /*%< * Attach *timerp to timer. * * Requires: * *\li 'timer' is a valid timer. * *\li 'timerp' points to a NULL timer. * * Ensures: * *\li *timerp is attached to timer. */ void isc_timer_detach(isc_timer_t **timerp); /*%< * Detach *timerp from its timer. * * Requires: * *\li 'timerp' points to a valid timer. * * Ensures: * *\li *timerp is NULL. * *\li If '*timerp' is the last reference to the timer, * then: * *\code * The timer will be shutdown * * The timer will detach from its task * * All resources used by the timer have been freed * * Any events already posted by the timer will be purged. * Therefore, if isc_timer_detach() is called in the context * of the timer's task, it is guaranteed that no more * timer event callbacks will run after the call. *\endcode */ isc_timertype_t isc_timer_gettype(isc_timer_t *timer); /*%< * Return the timer type. * * Requires: * *\li 'timer' to be a valid timer. */ isc_result_t isc_timermgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx, isc_timermgr_t **managerp); isc_result_t isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp); /*%< * Create a timer manager. isc_timermgr_createinctx() also associates * the new manager with the specified application context. * * Notes: * *\li All memory will be allocated in memory context 'mctx'. * * Requires: * *\li 'mctx' is a valid memory context. * *\li 'managerp' points to a NULL isc_timermgr_t. * *\li 'actx' is a valid application context (for createinctx()). * * Ensures: * *\li '*managerp' is a valid isc_timermgr_t. * * Returns: * *\li Success *\li No memory *\li Unexpected error */ void isc_timermgr_destroy(isc_timermgr_t **managerp); /*%< * Destroy a timer manager. * * Notes: * *\li This routine blocks until there are no timers left in the manager, * so if the caller holds any timer references using the manager, it * must detach them before calling isc_timermgr_destroy() or it will * block forever. * * Requires: * *\li '*managerp' is a valid isc_timermgr_t. * * Ensures: * *\li *managerp == NULL * *\li All resources used by the manager have been freed. */ void isc_timermgr_poke(isc_timermgr_t *m); /*%< * See isc_timermgr_create() above. */ typedef isc_result_t (*isc_timermgrcreatefunc_t)(isc_mem_t *mctx, isc_timermgr_t **managerp); isc_result_t isc__timer_register(void); /*%< * Register a new timer management implementation and add it to the list of * supported implementations. This function must be called when a different * event library is used than the one contained in the ISC library. */ isc_result_t isc_timer_register(isc_timermgrcreatefunc_t createfunc); /*%< * A short cut function that specifies the timer management module in the ISC * library for isc_timer_register(). An application that uses the ISC library * usually do not have to care about this function: it would call * isc_lib_register(), which internally calls this function. */ ISC_LANG_ENDDECLS #endif /* ISC_TIMER_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/mem.h0000644000470500017500000005214012664710322020047 0ustar lamontlamont/* * Copyright (C) 2004-2013, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1997-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef ISC_MEM_H #define ISC_MEM_H 1 /*! \file isc/mem.h */ #include #include #include #include #include #include #include ISC_LANG_BEGINDECLS #define ISC_MEM_LOWATER 0 #define ISC_MEM_HIWATER 1 typedef void (*isc_mem_water_t)(void *, int); typedef void * (*isc_memalloc_t)(void *, size_t); typedef void (*isc_memfree_t)(void *, void *); /*% * Define ISC_MEM_TRACKLINES=1 to turn on detailed tracing of memory * allocation and freeing by file and line number. */ #ifndef ISC_MEM_TRACKLINES #define ISC_MEM_TRACKLINES 1 #endif /*% * Define ISC_MEM_CHECKOVERRUN=1 to turn on checks for using memory outside * the requested space. This will increase the size of each allocation. * * If we are performing a Coverity static analysis then ISC_MEM_CHECKOVERRUN * can hide bugs that would otherwise discovered so force to zero. */ #ifdef __COVERITY__ #undef ISC_MEM_CHECKOVERRUN #define ISC_MEM_CHECKOVERRUN 0 #endif #ifndef ISC_MEM_CHECKOVERRUN #define ISC_MEM_CHECKOVERRUN 1 #endif /*% * Define ISC_MEM_FILL=1 to fill each block of memory returned to the system * with the byte string '0xbe'. This helps track down uninitialized pointers * and the like. On freeing memory, the space is filled with '0xde' for * the same reasons. * * If we are performing a Coverity static analysis then ISC_MEM_FILL * can hide bugs that would otherwise discovered so force to zero. */ #ifdef __COVERITY__ #undef ISC_MEM_FILL #define ISC_MEM_FILL 0 #endif #ifndef ISC_MEM_FILL #define ISC_MEM_FILL 1 #endif /*% * Define ISC_MEMPOOL_NAMES=1 to make memory pools store a symbolic * name so that the leaking pool can be more readily identified in * case of a memory leak. */ #ifndef ISC_MEMPOOL_NAMES #define ISC_MEMPOOL_NAMES 1 #endif LIBISC_EXTERNAL_DATA extern unsigned int isc_mem_debugging; LIBISC_EXTERNAL_DATA extern unsigned int isc_mem_defaultflags; /*@{*/ #define ISC_MEM_DEBUGTRACE 0x00000001U #define ISC_MEM_DEBUGRECORD 0x00000002U #define ISC_MEM_DEBUGUSAGE 0x00000004U #define ISC_MEM_DEBUGSIZE 0x00000008U #define ISC_MEM_DEBUGCTX 0x00000010U #define ISC_MEM_DEBUGALL 0x0000001FU /*!< * The variable isc_mem_debugging holds a set of flags for * turning certain memory debugging options on or off at * runtime. It is initialized to the value ISC_MEM_DEGBUGGING, * which is 0 by default but may be overridden at compile time. * The following flags can be specified: * * \li #ISC_MEM_DEBUGTRACE * Log each allocation and free to isc_lctx. * * \li #ISC_MEM_DEBUGRECORD * Remember each allocation, and match them up on free. * Crash if a free doesn't match an allocation. * * \li #ISC_MEM_DEBUGUSAGE * If a hi_water mark is set, print the maximum inuse memory * every time it is raised once it exceeds the hi_water mark. * * \li #ISC_MEM_DEBUGSIZE * Check the size argument being passed to isc_mem_put() matches * that passed to isc_mem_get(). * * \li #ISC_MEM_DEBUGCTX * Check the mctx argument being passed to isc_mem_put() matches * that passed to isc_mem_get(). */ /*@}*/ #if ISC_MEM_TRACKLINES #define _ISC_MEM_FILELINE , __FILE__, __LINE__ #define _ISC_MEM_FLARG , const char *, unsigned int #else #define _ISC_MEM_FILELINE #define _ISC_MEM_FLARG #endif /*! * Define ISC_MEM_USE_INTERNAL_MALLOC=1 to use the internal malloc() * implementation in preference to the system one. The internal malloc() * is very space-efficient, and quite fast on uniprocessor systems. It * performs poorly on multiprocessor machines. * JT: we can overcome the performance issue on multiprocessor machines * by carefully separating memory contexts. */ #ifndef ISC_MEM_USE_INTERNAL_MALLOC #define ISC_MEM_USE_INTERNAL_MALLOC 1 #endif /* * Flags for isc_mem_create2()calls. */ #define ISC_MEMFLAG_NOLOCK 0x00000001 /* no lock is necessary */ #define ISC_MEMFLAG_INTERNAL 0x00000002 /* use internal malloc */ #if ISC_MEM_USE_INTERNAL_MALLOC #define ISC_MEMFLAG_DEFAULT ISC_MEMFLAG_INTERNAL #else #define ISC_MEMFLAG_DEFAULT 0 #endif /*%< * We use either isc___mem (three underscores) or isc__mem (two) depending on * whether it's for BIND9's internal purpose (with -DBIND9) or generic export * library. */ #define ISCMEMFUNC(sfx) isc__mem_ ## sfx #define ISCMEMPOOLFUNC(sfx) isc__mempool_ ## sfx #define isc_mem_get(c, s) ISCMEMFUNC(get)((c), (s) _ISC_MEM_FILELINE) #define isc_mem_allocate(c, s) ISCMEMFUNC(allocate)((c), (s) _ISC_MEM_FILELINE) #define isc_mem_reallocate(c, p, s) ISCMEMFUNC(reallocate)((c), (p), (s) _ISC_MEM_FILELINE) #define isc_mem_strdup(c, p) ISCMEMFUNC(strdup)((c), (p) _ISC_MEM_FILELINE) #define isc_mempool_get(c) ISCMEMPOOLFUNC(get)((c) _ISC_MEM_FILELINE) /*% * isc_mem_putanddetach() is a convenience function for use where you * have a structure with an attached memory context. * * Given: * * \code * struct { * ... * isc_mem_t *mctx; * ... * } *ptr; * * isc_mem_t *mctx; * * isc_mem_putanddetach(&ptr->mctx, ptr, sizeof(*ptr)); * \endcode * * is the equivalent of: * * \code * mctx = NULL; * isc_mem_attach(ptr->mctx, &mctx); * isc_mem_detach(&ptr->mctx); * isc_mem_put(mctx, ptr, sizeof(*ptr)); * isc_mem_detach(&mctx); * \endcode */ /*% memory and memory pool methods */ typedef struct isc_memmethods { void (*attach)(isc_mem_t *source, isc_mem_t **targetp); void (*detach)(isc_mem_t **mctxp); void (*destroy)(isc_mem_t **mctxp); void *(*memget)(isc_mem_t *mctx, size_t size _ISC_MEM_FLARG); void (*memput)(isc_mem_t *mctx, void *ptr, size_t size _ISC_MEM_FLARG); void (*memputanddetach)(isc_mem_t **mctxp, void *ptr, size_t size _ISC_MEM_FLARG); void *(*memallocate)(isc_mem_t *mctx, size_t size _ISC_MEM_FLARG); void *(*memreallocate)(isc_mem_t *mctx, void *ptr, size_t size _ISC_MEM_FLARG); char *(*memstrdup)(isc_mem_t *mctx, const char *s _ISC_MEM_FLARG); void (*memfree)(isc_mem_t *mctx, void *ptr _ISC_MEM_FLARG); void (*setdestroycheck)(isc_mem_t *mctx, isc_boolean_t flag); void (*setwater)(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg, size_t hiwater, size_t lowater); void (*waterack)(isc_mem_t *ctx, int flag); size_t (*inuse)(isc_mem_t *mctx); size_t (*maxinuse)(isc_mem_t *mctx); size_t (*total)(isc_mem_t *mctx); isc_boolean_t (*isovermem)(isc_mem_t *mctx); isc_result_t (*mpcreate)(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp); } isc_memmethods_t; typedef struct isc_mempoolmethods { void (*destroy)(isc_mempool_t **mpctxp); void *(*get)(isc_mempool_t *mpctx _ISC_MEM_FLARG); void (*put)(isc_mempool_t *mpctx, void *mem _ISC_MEM_FLARG); unsigned int (*getallocated)(isc_mempool_t *mpctx); void (*setmaxalloc)(isc_mempool_t *mpctx, unsigned int limit); void (*setfreemax)(isc_mempool_t *mpctx, unsigned int limit); void (*setname)(isc_mempool_t *mpctx, const char *name); void (*associatelock)(isc_mempool_t *mpctx, isc_mutex_t *lock); void (*setfillcount)(isc_mempool_t *mpctx, unsigned int limit); } isc_mempoolmethods_t; /*% * This structure is actually just the common prefix of a memory context * implementation's version of an isc_mem_t. * \brief * Direct use of this structure by clients is forbidden. mctx implementations * may change the structure. 'magic' must be ISCAPI_MCTX_MAGIC for any of the * isc_mem_ routines to work. mctx implementations must maintain all mctx * invariants. */ struct isc_mem { unsigned int impmagic; unsigned int magic; isc_memmethods_t *methods; }; #define ISCAPI_MCTX_MAGIC ISC_MAGIC('A','m','c','x') #define ISCAPI_MCTX_VALID(m) ((m) != NULL && \ (m)->magic == ISCAPI_MCTX_MAGIC) /*% * This is the common prefix of a memory pool context. The same note as * that for the mem structure applies. */ struct isc_mempool { unsigned int impmagic; unsigned int magic; isc_mempoolmethods_t *methods; }; #define ISCAPI_MPOOL_MAGIC ISC_MAGIC('A','m','p','l') #define ISCAPI_MPOOL_VALID(mp) ((mp) != NULL && \ (mp)->magic == ISCAPI_MPOOL_MAGIC) #define isc_mem_put(c, p, s) \ do { \ ISCMEMFUNC(put)((c), (p), (s) _ISC_MEM_FILELINE); \ (p) = NULL; \ } while (0) #define isc_mem_putanddetach(c, p, s) \ do { \ ISCMEMFUNC(putanddetach)((c), (p), (s) _ISC_MEM_FILELINE); \ (p) = NULL; \ } while (0) #define isc_mem_free(c, p) \ do { \ ISCMEMFUNC(free)((c), (p) _ISC_MEM_FILELINE); \ (p) = NULL; \ } while (0) #define isc_mempool_put(c, p) \ do { \ ISCMEMPOOLFUNC(put)((c), (p) _ISC_MEM_FILELINE); \ (p) = NULL; \ } while (0) /*@{*/ isc_result_t isc_mem_create(size_t max_size, size_t target_size, isc_mem_t **mctxp); isc_result_t isc_mem_create2(size_t max_size, size_t target_size, isc_mem_t **mctxp, unsigned int flags); isc_result_t isc_mem_createx(size_t max_size, size_t target_size, isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg, isc_mem_t **mctxp); isc_result_t isc_mem_createx2(size_t max_size, size_t target_size, isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg, isc_mem_t **mctxp, unsigned int flags); /*!< * \brief Create a memory context. * * 'max_size' and 'target_size' are tuning parameters. When * ISC_MEMFLAG_INTERNAL is set, allocations smaller than 'max_size' * will be satisfied by getting blocks of size 'target_size' from the * system allocator and breaking them up into pieces; larger allocations * will use the system allocator directly. If 'max_size' and/or * 'target_size' are zero, default values will be * used. When * ISC_MEMFLAG_INTERNAL is not set, 'target_size' is ignored. * * 'max_size' is also used to size the statistics arrays and the array * used to record active memory when ISC_MEM_DEBUGRECORD is set. Setting * 'max_size' too low can have detrimental effects on performance. * * A memory context created using isc_mem_createx() will obtain * memory from the system by calling 'memalloc' and 'memfree', * passing them the argument 'arg'. A memory context created * using isc_mem_create() will use the standard library malloc() * and free(). * * If ISC_MEMFLAG_NOLOCK is set in 'flags', the corresponding memory context * will be accessed without locking. The user who creates the context must * ensure there be no race. Since this can be a source of bug, it is generally * inadvisable to use this flag unless the user is very sure about the race * condition and the access to the object is highly performance sensitive. * * Requires: * mctxp != NULL && *mctxp == NULL */ /*@}*/ /*@{*/ void isc_mem_attach(isc_mem_t *, isc_mem_t **); void isc_mem_detach(isc_mem_t **); /*!< * \brief Attach to / detach from a memory context. * * This is intended for applications that use multiple memory contexts * in such a way that it is not obvious when the last allocations from * a given context has been freed and destroying the context is safe. * * Most applications do not need to call these functions as they can * simply create a single memory context at the beginning of main() * and destroy it at the end of main(), thereby guaranteeing that it * is not destroyed while there are outstanding allocations. */ /*@}*/ void isc_mem_destroy(isc_mem_t **); /*%< * Destroy a memory context. */ isc_result_t isc_mem_ondestroy(isc_mem_t *ctx, isc_task_t *task, isc_event_t **event); /*%< * Request to be notified with an event when a memory context has * been successfully destroyed. */ void isc_mem_stats(isc_mem_t *mctx, FILE *out); /*%< * Print memory usage statistics for 'mctx' on the stream 'out'. */ void isc_mem_setdestroycheck(isc_mem_t *mctx, isc_boolean_t on); /*%< * If 'on' is ISC_TRUE, 'mctx' will check for memory leaks when * destroyed and abort the program if any are present. */ /*@{*/ void isc_mem_setquota(isc_mem_t *, size_t); size_t isc_mem_getquota(isc_mem_t *); /*%< * Set/get the memory quota of 'mctx'. This is a hard limit * on the amount of memory that may be allocated from mctx; * if it is exceeded, allocations will fail. */ /*@}*/ size_t isc_mem_inuse(isc_mem_t *mctx); /*%< * Get an estimate of the amount of memory in use in 'mctx', in bytes. * This includes quantization overhead, but does not include memory * allocated from the system but not yet used. */ size_t isc_mem_maxinuse(isc_mem_t *mctx); /*%< * Get an estimate of the largest amount of memory that has been in * use in 'mctx' at any time. */ size_t isc_mem_total(isc_mem_t *mctx); /*%< * Get the total amount of memory in 'mctx', in bytes, including memory * not yet used. */ isc_boolean_t isc_mem_isovermem(isc_mem_t *mctx); /*%< * Return true iff the memory context is in "over memory" state, i.e., * a hiwater mark has been set and the used amount of memory has exceeds * the mark. */ void isc_mem_setwater(isc_mem_t *mctx, isc_mem_water_t water, void *water_arg, size_t hiwater, size_t lowater); /*%< * Set high and low water marks for this memory context. * * When the memory usage of 'mctx' exceeds 'hiwater', * '(water)(water_arg, #ISC_MEM_HIWATER)' will be called. 'water' needs to * call isc_mem_waterack() with #ISC_MEM_HIWATER to acknowledge the state * change. 'water' may be called multiple times. * * When the usage drops below 'lowater', 'water' will again be called, this * time with #ISC_MEM_LOWATER. 'water' need to calls isc_mem_waterack() with * #ISC_MEM_LOWATER to acknowledge the change. * * static void * water(void *arg, int mark) { * struct foo *foo = arg; * * LOCK(&foo->marklock); * if (foo->mark != mark) { * foo->mark = mark; * .... * isc_mem_waterack(foo->mctx, mark); * } * UNLOCK(&foo->marklock); * } * * If 'water' is NULL then 'water_arg', 'hi_water' and 'lo_water' are * ignored and the state is reset. * * Requires: * * 'water' is not NULL. * hi_water >= lo_water */ void isc_mem_waterack(isc_mem_t *ctx, int mark); /*%< * Called to acknowledge changes in signaled by calls to 'water'. */ void isc_mem_printactive(isc_mem_t *mctx, FILE *file); /*%< * Print to 'file' all active memory in 'mctx'. * * Requires ISC_MEM_DEBUGRECORD to have been set. */ void isc_mem_printallactive(FILE *file); /*%< * Print to 'file' all active memory in all contexts. * * Requires ISC_MEM_DEBUGRECORD to have been set. */ void isc_mem_checkdestroyed(FILE *file); /*%< * Check that all memory contexts have been destroyed. * Prints out those that have not been. * Fatally fails if there are still active contexts. */ unsigned int isc_mem_references(isc_mem_t *ctx); /*%< * Return the current reference count. */ void isc_mem_setname(isc_mem_t *ctx, const char *name, void *tag); /*%< * Name 'ctx'. * * Notes: * *\li Only the first 15 characters of 'name' will be copied. * *\li 'tag' is for debugging purposes only. * * Requires: * *\li 'ctx' is a valid ctx. */ const char * isc_mem_getname(isc_mem_t *ctx); /*%< * Get the name of 'ctx', as previously set using isc_mem_setname(). * * Requires: *\li 'ctx' is a valid ctx. * * Returns: *\li A non-NULL pointer to a null-terminated string. * If the ctx has not been named, the string is * empty. */ void * isc_mem_gettag(isc_mem_t *ctx); /*%< * Get the tag value for 'task', as previously set using isc_mem_setname(). * * Requires: *\li 'ctx' is a valid ctx. * * Notes: *\li This function is for debugging purposes only. * * Requires: *\li 'ctx' is a valid task. */ #ifdef HAVE_LIBXML2 int isc_mem_renderxml(xmlTextWriterPtr writer); /*%< * Render all contexts' statistics and status in XML for writer. */ #endif /* HAVE_LIBXML2 */ #ifdef HAVE_JSON isc_result_t isc_mem_renderjson(json_object *memobj); /*%< * Render all contexts' statistics and status in JSON. */ #endif /* HAVE_JSON */ /* * Memory pools */ isc_result_t isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp); /*%< * Create a memory pool. * * Requires: *\li mctx is a valid memory context. *\li size > 0 *\li mpctxp != NULL and *mpctxp == NULL * * Defaults: *\li maxalloc = UINT_MAX *\li freemax = 1 *\li fillcount = 1 * * Returns: *\li #ISC_R_NOMEMORY -- not enough memory to create pool *\li #ISC_R_SUCCESS -- all is well. */ void isc_mempool_destroy(isc_mempool_t **mpctxp); /*%< * Destroy a memory pool. * * Requires: *\li mpctxp != NULL && *mpctxp is a valid pool. *\li The pool has no un"put" allocations outstanding */ void isc_mempool_setname(isc_mempool_t *mpctx, const char *name); /*%< * Associate a name with a memory pool. At most 15 characters may be used. * * Requires: *\li mpctx is a valid pool. *\li name != NULL; */ void isc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock); /*%< * Associate a lock with this memory pool. * * This lock is used when getting or putting items using this memory pool, * and it is also used to set or get internal state via the isc_mempool_get*() * and isc_mempool_set*() set of functions. * * Multiple pools can each share a single lock. For instance, if "manager" * type object contained pools for various sizes of events, and each of * these pools used a common lock. Note that this lock must NEVER be used * by other than mempool routines once it is given to a pool, since that can * easily cause double locking. * * Requires: * *\li mpctpx is a valid pool. * *\li lock != NULL. * *\li No previous lock is assigned to this pool. * *\li The lock is initialized before calling this function via the normal * means of doing that. */ /* * The following functions get/set various parameters. Note that due to * the unlocked nature of pools these are potentially random values unless * the imposed externally provided locking protocols are followed. * * Also note that the quota limits will not always take immediate effect. * For instance, setting "maxalloc" to a number smaller than the currently * allocated count is permitted. New allocations will be refused until * the count drops below this threshold. * * All functions require (in addition to other requirements): * mpctx is a valid memory pool */ unsigned int isc_mempool_getfreemax(isc_mempool_t *mpctx); /*%< * Returns the maximum allowed size of the free list. */ void isc_mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit); /*%< * Sets the maximum allowed size of the free list. */ unsigned int isc_mempool_getfreecount(isc_mempool_t *mpctx); /*%< * Returns current size of the free list. */ unsigned int isc_mempool_getmaxalloc(isc_mempool_t *mpctx); /*!< * Returns the maximum allowed number of allocations. */ void isc_mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit); /*%< * Sets the maximum allowed number of allocations. * * Additional requirements: *\li limit > 0 */ unsigned int isc_mempool_getallocated(isc_mempool_t *mpctx); /*%< * Returns the number of items allocated from this pool. */ unsigned int isc_mempool_getfillcount(isc_mempool_t *mpctx); /*%< * Returns the number of items allocated as a block from the parent memory * context when the free list is empty. */ void isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit); /*%< * Sets the fillcount. * * Additional requirements: *\li limit > 0 */ /* * Pseudo-private functions for use via macros. Do not call directly. */ void * ISCMEMFUNC(get)(isc_mem_t *, size_t _ISC_MEM_FLARG); void ISCMEMFUNC(putanddetach)(isc_mem_t **, void *, size_t _ISC_MEM_FLARG); void ISCMEMFUNC(put)(isc_mem_t *, void *, size_t _ISC_MEM_FLARG); void * ISCMEMFUNC(allocate)(isc_mem_t *, size_t _ISC_MEM_FLARG); void * ISCMEMFUNC(reallocate)(isc_mem_t *, void *, size_t _ISC_MEM_FLARG); void ISCMEMFUNC(free)(isc_mem_t *, void * _ISC_MEM_FLARG); char * ISCMEMFUNC(strdup)(isc_mem_t *, const char *_ISC_MEM_FLARG); void * ISCMEMPOOLFUNC(get)(isc_mempool_t * _ISC_MEM_FLARG); void ISCMEMPOOLFUNC(put)(isc_mempool_t *, void * _ISC_MEM_FLARG); /*%< * See isc_mem_create2() above. */ typedef isc_result_t (*isc_memcreatefunc_t)(size_t init_max_size, size_t target_size, isc_mem_t **ctxp, unsigned int flags); isc_result_t isc_mem_register(isc_memcreatefunc_t createfunc); /*%< * Register a new memory management implementation and add it to the list of * supported implementations. This function must be called when a different * memory management library is used than the one contained in the ISC library. */ isc_result_t isc__mem_register(void); /*%< * A short cut function that specifies the memory management module in the ISC * library for isc_mem_register(). An application that uses the ISC library * usually do not have to care about this function: it would call * isc_lib_register(), which internally calls this function. */ ISC_LANG_ENDDECLS #endif /* ISC_MEM_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/crc64.h0000644000470500017500000000255512664710322020217 0ustar lamontlamont/* * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef ISC_CRC64_H #define ISC_CRC64_H 1 /*! \file isc/crc64.h * \brief CRC64 in C */ #include #include ISC_LANG_BEGINDECLS void isc_crc64_init(isc_uint64_t *crc); /*% * Initialize a new CRC. * * Requires: * * 'crc' is not NULL. */ void isc_crc64_update(isc_uint64_t *crc, const void *data, size_t len); /*% * Add data to the CRC. * * Requires: * * 'crc' is not NULL. * * 'data' is not NULL. */ void isc_crc64_final(isc_uint64_t *crc); /*% * Finalize the CRC. * * Requires: * * 'crc' is not NULL. */ ISC_LANG_ENDDECLS #endif /* ISC_CRC64_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/radix.h0000644000470500017500000001565412664710322020411 0ustar lamontlamont/* * Copyright (C) 2007, 2008, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: radix.h,v 1.13 2008/12/01 23:47:45 tbox Exp $ */ /* * This source was adapted from MRT's RCS Ids: * Id: radix.h,v 1.6 1999/08/03 03:32:53 masaki Exp * Id: mrt.h,v 1.57.2.6 1999/12/28 23:41:27 labovit Exp * Id: defs.h,v 1.5.2.2 2000/01/15 14:19:16 masaki Exp */ #include #include #include #include #include #include #ifndef _RADIX_H #define _RADIX_H #define NETADDR_TO_PREFIX_T(na,pt,bits) \ do { \ const void *p = na; \ memset(&(pt), 0, sizeof(pt)); \ if (p != NULL) { \ (pt).family = (na)->family; \ (pt).bitlen = (bits); \ if ((pt).family == AF_INET6) { \ memmove(&(pt).add.sin6, &(na)->type.in6, \ ((bits)+7)/8); \ } else \ memmove(&(pt).add.sin, &(na)->type.in, \ ((bits)+7)/8); \ } else { \ (pt).family = AF_UNSPEC; \ (pt).bitlen = 0; \ } \ isc_refcount_init(&(pt).refcount, 0); \ } while(0) typedef struct isc_prefix { isc_mem_t *mctx; unsigned int family; /* AF_INET | AF_INET6, or AF_UNSPEC for "any" */ unsigned int bitlen; /* 0 for "any" */ isc_refcount_t refcount; union { struct in_addr sin; struct in6_addr sin6; } add; } isc_prefix_t; typedef void (*isc_radix_destroyfunc_t)(void *); typedef void (*isc_radix_processfunc_t)(isc_prefix_t *, void **); #define isc_prefix_tochar(prefix) ((char *)&(prefix)->add.sin) #define isc_prefix_touchar(prefix) ((u_char *)&(prefix)->add.sin) #define BIT_TEST(f, b) ((f) & (b)) /* * We need "first match" when we search the radix tree to preserve * compatibility with the existing ACL implementation. Radix trees * naturally lend themselves to "best match". In order to get "first match" * behavior, we keep track of the order in which entries are added to the * tree--and when a search is made, we find all matching entries, and * return the one that was added first. * * An IPv4 prefix and an IPv6 prefix may share a radix tree node if they * have the same length and bit pattern (e.g., 127/8 and 7f::/8). To * disambiguate between them, node_num and data are two-element arrays; * node_num[0] and data[0] are used for IPv4 addresses, node_num[1] * and data[1] for IPv6 addresses. The only exception is a prefix of * 0/0 (aka "any" or "none"), which is always stored as IPv4 but matches * IPv6 addresses too. */ #define ISC_IS6(family) ((family) == AF_INET6 ? 1 : 0) typedef struct isc_radix_node { isc_mem_t *mctx; isc_uint32_t bit; /* bit length of the prefix */ isc_prefix_t *prefix; /* who we are in radix tree */ struct isc_radix_node *l, *r; /* left and right children */ struct isc_radix_node *parent; /* may be used */ void *data[2]; /* pointers to IPv4 and IPV6 data */ int node_num[2]; /* which node this was in the tree, or -1 for glue nodes */ } isc_radix_node_t; #define RADIX_TREE_MAGIC ISC_MAGIC('R','d','x','T'); #define RADIX_TREE_VALID(a) ISC_MAGIC_VALID(a, RADIX_TREE_MAGIC); typedef struct isc_radix_tree { unsigned int magic; isc_mem_t *mctx; isc_radix_node_t *head; isc_uint32_t maxbits; /* for IP, 32 bit addresses */ int num_active_node; /* for debugging purposes */ int num_added_node; /* total number of nodes */ } isc_radix_tree_t; isc_result_t isc_radix_search(isc_radix_tree_t *radix, isc_radix_node_t **target, isc_prefix_t *prefix); /*%< * Search 'radix' for the best match to 'prefix'. * Return the node found in '*target'. * * Requires: * \li 'radix' to be valid. * \li 'target' is not NULL and "*target" is NULL. * \li 'prefix' to be valid. * * Returns: * \li ISC_R_NOTFOUND * \li ISC_R_SUCCESS */ isc_result_t isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, isc_radix_node_t *source, isc_prefix_t *prefix); /*%< * Insert 'source' or 'prefix' into the radix tree 'radix'. * Return the node added in 'target'. * * Requires: * \li 'radix' to be valid. * \li 'target' is not NULL and "*target" is NULL. * \li 'prefix' to be valid or 'source' to be non NULL and contain * a valid prefix. * * Returns: * \li ISC_R_NOMEMORY * \li ISC_R_SUCCESS */ void isc_radix_remove(isc_radix_tree_t *radix, isc_radix_node_t *node); /*%< * Remove the node 'node' from the radix tree 'radix'. * * Requires: * \li 'radix' to be valid. * \li 'node' to be valid. */ isc_result_t isc_radix_create(isc_mem_t *mctx, isc_radix_tree_t **target, int maxbits); /*%< * Create a radix tree with a maximum depth of 'maxbits'; * * Requires: * \li 'mctx' to be valid. * \li 'target' to be non NULL and '*target' to be NULL. * \li 'maxbits' to be less than or equal to RADIX_MAXBITS. * * Returns: * \li ISC_R_NOMEMORY * \li ISC_R_SUCCESS */ void isc_radix_destroy(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func); /*%< * Destroy a radix tree optionally calling 'func' to clean up node data. * * Requires: * \li 'radix' to be valid. */ void isc_radix_process(isc_radix_tree_t *radix, isc_radix_processfunc_t func); /*%< * Walk a radix tree calling 'func' to process node data. * * Requires: * \li 'radix' to be valid. * \li 'func' to point to a function. */ #define RADIX_MAXBITS 128 #define RADIX_NBIT(x) (0x80 >> ((x) & 0x7f)) #define RADIX_NBYTE(x) ((x) >> 3) #define RADIX_DATA_GET(node, type) (type *)((node)->data) #define RADIX_DATA_SET(node, value) ((node)->data = (void *)(value)) #define RADIX_WALK(Xhead, Xnode) \ do { \ isc_radix_node_t *Xstack[RADIX_MAXBITS+1]; \ isc_radix_node_t **Xsp = Xstack; \ isc_radix_node_t *Xrn = (Xhead); \ while ((Xnode = Xrn)) { \ if (Xnode->prefix) #define RADIX_WALK_ALL(Xhead, Xnode) \ do { \ isc_radix_node_t *Xstack[RADIX_MAXBITS+1]; \ isc_radix_node_t **Xsp = Xstack; \ isc_radix_node_t *Xrn = (Xhead); \ while ((Xnode = Xrn)) { \ if (1) #define RADIX_WALK_BREAK { \ if (Xsp != Xstack) { \ Xrn = *(--Xsp); \ } else { \ Xrn = (radix_node_t *) 0; \ } \ continue; } #define RADIX_WALK_END \ if (Xrn->l) { \ if (Xrn->r) { \ *Xsp++ = Xrn->r; \ } \ Xrn = Xrn->l; \ } else if (Xrn->r) { \ Xrn = Xrn->r; \ } else if (Xsp != Xstack) { \ Xrn = *(--Xsp); \ } else { \ Xrn = (isc_radix_node_t *) 0; \ } \ } \ } while (0) #endif /* _RADIX_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/log.h0000644000470500017500000007065012664710322020060 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: log.h,v 1.59 2009/02/16 02:01:16 marka Exp $ */ #ifndef ISC_LOG_H #define ISC_LOG_H 1 /*! \file isc/log.h */ #include #include #include /* XXXDCL NT */ #include #include #include #include /*@{*/ /*! * \brief Severity levels, patterned after Unix's syslog levels. * */ #define ISC_LOG_DEBUG(level) (level) /*! * #ISC_LOG_DYNAMIC can only be used for defining channels with * isc_log_createchannel(), not to specify a level in isc_log_write(). */ #define ISC_LOG_DYNAMIC 0 #define ISC_LOG_INFO (-1) #define ISC_LOG_NOTICE (-2) #define ISC_LOG_WARNING (-3) #define ISC_LOG_ERROR (-4) #define ISC_LOG_CRITICAL (-5) /*@}*/ /*@{*/ /*! * \brief Destinations. */ #define ISC_LOG_TONULL 1 #define ISC_LOG_TOSYSLOG 2 #define ISC_LOG_TOFILE 3 #define ISC_LOG_TOFILEDESC 4 /*@}*/ /*@{*/ /*% * Channel flags. */ #define ISC_LOG_PRINTTIME 0x0001 #define ISC_LOG_PRINTLEVEL 0x0002 #define ISC_LOG_PRINTCATEGORY 0x0004 #define ISC_LOG_PRINTMODULE 0x0008 #define ISC_LOG_PRINTTAG 0x0010 /* tag and ":" */ #define ISC_LOG_PRINTPREFIX 0x0020 /* tag only, no colon */ #define ISC_LOG_PRINTALL 0x003F #define ISC_LOG_DEBUGONLY 0x1000 #define ISC_LOG_OPENERR 0x8000 /* internal */ /*@}*/ /*@{*/ /*! * \brief Other options. * * XXXDCL INFINITE doesn't yet work. Arguably it isn't needed, but * since I am intend to make large number of versions work efficiently, * INFINITE is going to be trivial to add to that. */ #define ISC_LOG_ROLLINFINITE (-1) #define ISC_LOG_ROLLNEVER (-2) /*@}*/ /*! * \brief Used to name the categories used by a library. * * An array of isc_logcategory * structures names each category, and the id value is initialized by calling * isc_log_registercategories. */ struct isc_logcategory { const char *name; unsigned int id; }; /*% * Similar to isc_logcategory, but for all the modules a library defines. */ struct isc_logmodule { const char *name; unsigned int id; }; /*% * The isc_logfile structure is initialized as part of an isc_logdestination * before calling isc_log_createchannel(). * * When defining an #ISC_LOG_TOFILE * channel the name, versions and maximum_size should be set before calling * isc_log_createchannel(). To define an #ISC_LOG_TOFILEDESC channel set only * the stream before the call. * * Setting maximum_size to zero implies no maximum. */ typedef struct isc_logfile { FILE *stream; /*%< Initialized to NULL for #ISC_LOG_TOFILE. */ const char *name; /*%< NULL for #ISC_LOG_TOFILEDESC. */ int versions; /* >= 0, #ISC_LOG_ROLLNEVER, #ISC_LOG_ROLLINFINITE. */ /*% * stdio's ftell is standardized to return a long, which may well not * be big enough for the largest file supportable by the operating * system (though it is _probably_ big enough for the largest log * anyone would want). st_size returned by fstat should be typedef'd * to a size large enough for the largest possible file on a system. */ isc_offset_t maximum_size; isc_boolean_t maximum_reached; /*%< Private. */ } isc_logfile_t; /*% * Passed to isc_log_createchannel to define the attributes of either * a stdio or a syslog log. */ typedef union isc_logdestination { isc_logfile_t file; int facility; /* XXXDCL NT */ } isc_logdestination_t; /*@{*/ /*% * The built-in categories of libisc. * * Each library registering categories should provide library_LOGCATEGORY_name * definitions with indexes into its isc_logcategory structure corresponding to * the order of the names. */ LIBISC_EXTERNAL_DATA extern isc_logcategory_t isc_categories[]; LIBISC_EXTERNAL_DATA extern isc_log_t *isc_lctx; LIBISC_EXTERNAL_DATA extern isc_logmodule_t isc_modules[]; /*@}*/ /*@{*/ /*% * Do not log directly to DEFAULT. Use another category. When in doubt, * use GENERAL. */ #define ISC_LOGCATEGORY_DEFAULT (&isc_categories[0]) #define ISC_LOGCATEGORY_GENERAL (&isc_categories[1]) /*@}*/ #define ISC_LOGMODULE_SOCKET (&isc_modules[0]) #define ISC_LOGMODULE_TIME (&isc_modules[1]) #define ISC_LOGMODULE_INTERFACE (&isc_modules[2]) #define ISC_LOGMODULE_TIMER (&isc_modules[3]) #define ISC_LOGMODULE_FILE (&isc_modules[4]) #define ISC_LOGMODULE_OTHER (&isc_modules[5]) ISC_LANG_BEGINDECLS isc_result_t isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp, isc_logconfig_t **lcfgp); /*%< * Establish a new logging context, with default channels. * * Notes: *\li isc_log_create() calls isc_logconfig_create(), so see its comment * below for more information. * * Requires: *\li mctx is a valid memory context. *\li lctxp is not null and *lctxp is null. *\li lcfgp is null or lcfgp is not null and *lcfgp is null. * * Ensures: *\li *lctxp will point to a valid logging context if all of the necessary * memory was allocated, or NULL otherwise. *\li *lcfgp will point to a valid logging configuration if all of the * necessary memory was allocated, or NULL otherwise. *\li On failure, no additional memory is allocated. * * Returns: *\li #ISC_R_SUCCESS Success *\li #ISC_R_NOMEMORY Resource limit: Out of memory */ isc_result_t isc_logconfig_create(isc_log_t *lctx, isc_logconfig_t **lcfgp); /*%< * Create the data structure that holds all of the configurable information * about where messages are actually supposed to be sent -- the information * that could changed based on some configuration file, as opposed to the * the category/module specification of isc_log_[v]write[1] that is compiled * into a program, or the debug_level which is dynamic state information. * * Notes: *\li It is necessary to specify the logging context the configuration * will be used with because the number of categories and modules * needs to be known in order to set the configuration. However, * the configuration is not used by the logging context until the * isc_logconfig_use function is called. * *\li The memory context used for operations that allocate memory for * the configuration is that of the logging context, as specified * in the isc_log_create call. * *\li Four default channels are established: *\verbatim * default_syslog * - log to syslog's daemon facility #ISC_LOG_INFO or higher * default_stderr * - log to stderr #ISC_LOG_INFO or higher * default_debug * - log to stderr #ISC_LOG_DEBUG dynamically * null * - log nothing *\endverbatim * * Requires: *\li lctx is a valid logging context. *\li lcftp is not null and *lcfgp is null. * * Ensures: *\li *lcfgp will point to a valid logging context if all of the necessary * memory was allocated, or NULL otherwise. *\li On failure, no additional memory is allocated. * * Returns: *\li #ISC_R_SUCCESS Success *\li #ISC_R_NOMEMORY Resource limit: Out of memory */ isc_logconfig_t * isc_logconfig_get(isc_log_t *lctx); /*%< * Returns a pointer to the configuration currently in use by the log context. * * Requires: *\li lctx is a valid context. * * Ensures: *\li The configuration pointer is non-null. * * Returns: *\li The configuration pointer. */ isc_result_t isc_logconfig_use(isc_log_t *lctx, isc_logconfig_t *lcfg); /*%< * Associate a new configuration with a logging context. * * Notes: *\li This is thread safe. The logging context will lock a mutex * before attempting to swap in the new configuration, and isc_log_doit * (the internal function used by all of isc_log_[v]write[1]) locks * the same lock for the duration of its use of the configuration. * * Requires: *\li lctx is a valid logging context. *\li lcfg is a valid logging configuration. *\li lctx is the same configuration given to isc_logconfig_create * when the configuration was created. * * Ensures: *\li Future calls to isc_log_write will use the new configuration. * * Returns: *\li #ISC_R_SUCCESS Success *\li #ISC_R_NOMEMORY Resource limit: Out of memory */ void isc_log_destroy(isc_log_t **lctxp); /*%< * Deallocate the memory associated with a logging context. * * Requires: *\li *lctx is a valid logging context. * * Ensures: *\li All of the memory associated with the logging context is returned * to the free memory pool. * *\li Any open files are closed. * *\li The logging context is marked as invalid. */ void isc_logconfig_destroy(isc_logconfig_t **lcfgp); /*%< * Destroy a logging configuration. * * Notes: *\li This function cannot be used directly with the return value of * isc_logconfig_get, because a logging context must always have * a valid configuration associated with it. * * Requires: *\li lcfgp is not null and *lcfgp is a valid logging configuration. *\li The logging configuration is not in use by an existing logging context. * * Ensures: *\li All memory allocated for the configuration is freed. * *\li The configuration is marked as invalid. */ void isc_log_registercategories(isc_log_t *lctx, isc_logcategory_t categories[]); /*%< * Identify logging categories a library will use. * * Notes: *\li A category should only be registered once, but no mechanism enforces * this rule. * *\li The end of the categories array is identified by a NULL name. * *\li Because the name is used by #ISC_LOG_PRINTCATEGORY, it should not * be altered or destroyed after isc_log_registercategories(). * *\li Because each element of the categories array is used by * isc_log_categorybyname, it should not be altered or destroyed * after registration. * *\li The value of the id integer in each structure is overwritten * by this function, and so id need not be initialized to any particular * value prior to the function call. * *\li A subsequent call to isc_log_registercategories with the same * logging context (but new categories) will cause the last * element of the categories array from the prior call to have * its "name" member changed from NULL to point to the new * categories array, and its "id" member set to UINT_MAX. * * Requires: *\li lctx is a valid logging context. *\li categories != NULL. *\li categories[0].name != NULL. * * Ensures: * \li There are references to each category in the logging context, * so they can be used with isc_log_usechannel() and isc_log_write(). */ void isc_log_registermodules(isc_log_t *lctx, isc_logmodule_t modules[]); /*%< * Identify logging categories a library will use. * * Notes: *\li A module should only be registered once, but no mechanism enforces * this rule. * *\li The end of the modules array is identified by a NULL name. * *\li Because the name is used by #ISC_LOG_PRINTMODULE, it should not * be altered or destroyed after isc_log_registermodules(). * *\li Because each element of the modules array is used by * isc_log_modulebyname, it should not be altered or destroyed * after registration. * *\li The value of the id integer in each structure is overwritten * by this function, and so id need not be initialized to any particular * value prior to the function call. * *\li A subsequent call to isc_log_registermodules with the same * logging context (but new modules) will cause the last * element of the modules array from the prior call to have * its "name" member changed from NULL to point to the new * modules array, and its "id" member set to UINT_MAX. * * Requires: *\li lctx is a valid logging context. *\li modules != NULL. *\li modules[0].name != NULL; * * Ensures: *\li Each module has a reference in the logging context, so they can be * used with isc_log_usechannel() and isc_log_write(). */ isc_result_t isc_log_createchannel(isc_logconfig_t *lcfg, const char *name, unsigned int type, int level, const isc_logdestination_t *destination, unsigned int flags); /*%< * Specify the parameters of a logging channel. * * Notes: *\li The name argument is copied to memory in the logging context, so * it can be altered or destroyed after isc_log_createchannel(). * *\li Defining a very large number of channels will have a performance * impact on isc_log_usechannel(), since the names are searched * linearly until a match is made. This same issue does not affect * isc_log_write, however. * *\li Channel names can be redefined; this is primarily useful for programs * that want their own definition of default_syslog, default_debug * and default_stderr. * *\li Any channel that is redefined will not affect logging that was * already directed to its original definition, _except_ for the * default_stderr channel. This case is handled specially so that * the default logging category can be changed by redefining * default_stderr. (XXXDCL Though now that I think of it, the default * logging category can be changed with only one additional function * call by defining a new channel and then calling isc_log_usechannel() * for #ISC_LOGCATEGORY_DEFAULT.) * *\li Specifying #ISC_LOG_PRINTTIME or #ISC_LOG_PRINTTAG for syslog is allowed, * but probably not what you wanted to do. * * #ISC_LOG_DEBUGONLY will mark the channel as usable only when the * debug level of the logging context (see isc_log_setdebuglevel) * is non-zero. * * Requires: *\li lcfg is a valid logging configuration. * *\li name is not NULL. * *\li type is #ISC_LOG_TOSYSLOG, #ISC_LOG_TOFILE, #ISC_LOG_TOFILEDESC or * #ISC_LOG_TONULL. * *\li destination is not NULL unless type is #ISC_LOG_TONULL. * *\li level is >= #ISC_LOG_CRITICAL (the most negative logging level). * *\li flags does not include any bits aside from the ISC_LOG_PRINT* bits * or #ISC_LOG_DEBUGONLY. * * Ensures: *\li #ISC_R_SUCCESS * A channel with the given name is usable with * isc_log_usechannel(). * *\li #ISC_R_NOMEMORY or #ISC_R_UNEXPECTED * No additional memory is being used by the logging context. * Any channel that previously existed with the given name * is not redefined. * * Returns: *\li #ISC_R_SUCCESS Success *\li #ISC_R_NOMEMORY Resource limit: Out of memory *\li #ISC_R_UNEXPECTED type was out of range and REQUIRE() * was disabled. */ isc_result_t isc_log_usechannel(isc_logconfig_t *lcfg, const char *name, const isc_logcategory_t *category, const isc_logmodule_t *module); /*%< * Associate a named logging channel with a category and module that * will use it. * * Notes: *\li The name is searched for linearly in the set of known channel names * until a match is found. (Note the performance impact of a very large * number of named channels.) When multiple channels of the same * name are defined, the most recent definition is found. * *\li Specifying a very large number of channels for a category will have * a moderate impact on performance in isc_log_write(), as each * call looks up the category for the start of a linked list, which * it follows all the way to the end to find matching modules. The * test for matching modules is integral, though. * *\li If category is NULL, then the channel is associated with the indicated * module for all known categories (including the "default" category). * *\li If module is NULL, then the channel is associated with every module * that uses that category. * *\li Passing both category and module as NULL would make every log message * use the indicated channel. * * \li Specifying a channel that is #ISC_LOG_TONULL for a category/module pair * has no effect on any other channels associated with that pair, * regardless of ordering. Thus you cannot use it to "mask out" one * category/module pair when you have specified some other channel that * is also used by that category/module pair. * * Requires: *\li lcfg is a valid logging configuration. * *\li category is NULL or has an id that is in the range of known ids. * * module is NULL or has an id that is in the range of known ids. * * Ensures: *\li #ISC_R_SUCCESS * The channel will be used by the indicated category/module * arguments. * *\li #ISC_R_NOMEMORY * If assignment for a specific category has been requested, * the channel has not been associated with the indicated * category/module arguments and no additional memory is * used by the logging context. * If assignment for all categories has been requested * then _some_ may have succeeded (starting with category * "default" and progressing through the order of categories * passed to isc_log_registercategories()) and additional memory * is being used by whatever assignments succeeded. * * Returns: *\li #ISC_R_SUCCESS Success *\li #ISC_R_NOMEMORY Resource limit: Out of memory */ /* Attention: next four comments PRECEED code */ /*! * \brief * Write a message to the log channels. * * Notes: *\li Log messages containing natural language text should be logged with * isc_log_iwrite() to allow for localization. * *\li lctx can be NULL; this is allowed so that programs which use * libraries that use the ISC logging system are not required to * also use it. * *\li The format argument is a printf(3) string, with additional arguments * as necessary. * * Requires: *\li lctx is a valid logging context. * *\li The category and module arguments must have ids that are in the * range of known ids, as established by isc_log_registercategories() * and isc_log_registermodules(). * *\li level != #ISC_LOG_DYNAMIC. ISC_LOG_DYNAMIC is used only to define * channels, and explicit debugging level must be identified for * isc_log_write() via ISC_LOG_DEBUG(level). * *\li format != NULL. * * Ensures: *\li The log message is written to every channel associated with the * indicated category/module pair. * * Returns: *\li Nothing. Failure to log a message is not construed as a * meaningful error. */ void isc_log_write(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, const char *format, ...) ISC_FORMAT_PRINTF(5, 6); /*% * Write a message to the log channels. * * Notes: *\li lctx can be NULL; this is allowed so that programs which use * libraries that use the ISC logging system are not required to * also use it. * *\li The format argument is a printf(3) string, with additional arguments * as necessary. * * Requires: *\li lctx is a valid logging context. * *\li The category and module arguments must have ids that are in the * range of known ids, as established by isc_log_registercategories() * and isc_log_registermodules(). * *\li level != #ISC_LOG_DYNAMIC. ISC_LOG_DYNAMIC is used only to define * channels, and explicit debugging level must be identified for * isc_log_write() via ISC_LOG_DEBUG(level). * *\li format != NULL. * * Ensures: *\li The log message is written to every channel associated with the * indicated category/module pair. * * Returns: *\li Nothing. Failure to log a message is not construed as a * meaningful error. */ void isc_log_vwrite(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, const char *format, va_list args) ISC_FORMAT_PRINTF(5, 0); /*% * Write a message to the log channels, pruning duplicates that occur within * a configurable amount of seconds (see isc_log_[sg]etduplicateinterval). * This function is otherwise identical to isc_log_write(). */ void isc_log_write1(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, const char *format, ...) ISC_FORMAT_PRINTF(5, 6); /*% * Write a message to the log channels, pruning duplicates that occur within * a configurable amount of seconds (see isc_log_[sg]etduplicateinterval). * This function is otherwise identical to isc_log_vwrite(). */ void isc_log_vwrite1(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, const char *format, va_list args) ISC_FORMAT_PRINTF(5, 0); /*% * These are four internationalized versions of the isc_log_[v]write[1] * functions. * * The only difference is that they take arguments for a message * catalog, message set, and message number, all immediately preceding the * format argument. The format argument becomes the default text, a la * isc_msgcat_get. If the message catalog is NULL, no lookup is attempted * for a message -- which makes the message set and message number irrelevant, * and the non-internationalized call should have probably been used instead. * * Yes, that means there are now *eight* interfaces to logging a message. * Sheesh. Make the madness stop! */ /*@{*/ void isc_log_iwrite(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, isc_msgcat_t *msgcat, int msgset, int message, const char *format, ...) ISC_FORMAT_PRINTF(8, 9); void isc_log_ivwrite(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, isc_msgcat_t *msgcat, int msgset, int message, const char *format, va_list args) ISC_FORMAT_PRINTF(8, 0); void isc_log_iwrite1(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, isc_msgcat_t *msgcat, int msgset, int message, const char *format, ...) ISC_FORMAT_PRINTF(8, 9); void isc_log_ivwrite1(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, isc_msgcat_t *msgcat, int msgset, int message, const char *format, va_list args) ISC_FORMAT_PRINTF(8, 0); /*@}*/ void isc_log_setdebuglevel(isc_log_t *lctx, unsigned int level); /*%< * Set the debugging level used for logging. * * Notes: *\li Setting the debugging level to 0 disables debugging log messages. * * Requires: *\li lctx is a valid logging context. * * Ensures: *\li The debugging level is set to the requested value. */ unsigned int isc_log_getdebuglevel(isc_log_t *lctx); /*%< * Get the current debugging level. * * Notes: *\li This is provided so that a program can have a notion of * "increment debugging level" or "decrement debugging level" * without needing to keep track of what the current level is. * *\li A return value of 0 indicates that debugging messages are disabled. * * Requires: *\li lctx is a valid logging context. * * Ensures: *\li The current logging debugging level is returned. */ isc_boolean_t isc_log_wouldlog(isc_log_t *lctx, int level); /*%< * Determine whether logging something to 'lctx' at 'level' would * actually cause something to be logged somewhere. * * If #ISC_FALSE is returned, it is guaranteed that nothing would * be logged, allowing the caller to omit unnecessary * isc_log_write() calls and possible message preformatting. */ void isc_log_setduplicateinterval(isc_logconfig_t *lcfg, unsigned int interval); /*%< * Set the interval over which duplicate log messages will be ignored * by isc_log_[v]write1(), in seconds. * * Notes: *\li Increasing the duplicate interval from X to Y will not necessarily * filter out duplicates of messages logged in Y - X seconds since the * increase. (Example: Message1 is logged at midnight. Message2 * is logged at 00:01:00, when the interval is only 30 seconds, causing * Message1 to be expired from the log message history. Then the interval * is increased to 3000 (five minutes) and at 00:04:00 Message1 is logged * again. It will appear the second time even though less than five * passed since the first occurrence. * * Requires: *\li lctx is a valid logging context. */ unsigned int isc_log_getduplicateinterval(isc_logconfig_t *lcfg); /*%< * Get the current duplicate filtering interval. * * Requires: *\li lctx is a valid logging context. * * Returns: *\li The current duplicate filtering interval. */ isc_result_t isc_log_settag(isc_logconfig_t *lcfg, const char *tag); /*%< * Set the program name or other identifier for #ISC_LOG_PRINTTAG. * * Requires: *\li lcfg is a valid logging configuration. * * Notes: *\li If this function has not set the tag to a non-NULL, non-empty value, * then the #ISC_LOG_PRINTTAG channel flag will not print anything. * Unlike some implementations of syslog on Unix systems, you *must* set * the tag in order to get it logged. It is not implicitly derived from * the program name (which is pretty impossible to infer portably). * *\li Setting the tag to NULL or the empty string will also cause the * #ISC_LOG_PRINTTAG channel flag to not print anything. If tag equals the * empty string, calls to isc_log_gettag will return NULL. * * Returns: *\li #ISC_R_SUCCESS Success *\li #ISC_R_NOMEMORY Resource Limit: Out of memory * * XXXDCL when creating a new isc_logconfig_t, it might be nice if the tag * of the currently active isc_logconfig_t was inherited. this does not * currently happen. */ char * isc_log_gettag(isc_logconfig_t *lcfg); /*%< * Get the current identifier printed with #ISC_LOG_PRINTTAG. * * Requires: *\li lcfg is a valid logging configuration. * * Notes: *\li Since isc_log_settag() will not associate a zero-length string * with the logging configuration, attempts to do so will cause * this function to return NULL. However, a determined programmer * will observe that (currently) a tag of length greater than zero * could be set, and then modified to be zero length. * * Returns: *\li A pointer to the current identifier, or NULL if none has been set. */ void isc_log_opensyslog(const char *tag, int options, int facility); /*%< * Initialize syslog logging. * * Notes: *\li XXXDCL NT * This is currently equivalent to openlog(), but is not going to remain * that way. In the meantime, the arguments are all identical to * those used by openlog(3), as follows: * * \code * tag: The string to use in the position of the program * name in syslog messages. Most (all?) syslogs * will use basename(argv[0]) if tag is NULL. * * options: LOG_CONS, LOG_PID, LOG_NDELAY ... whatever your * syslog supports. * * facility: The default syslog facility. This is irrelevant * since isc_log_write will ALWAYS use the channel's * declared facility. * \endcode * *\li Zero effort has been made (yet) to accommodate systems with openlog() * that only takes two arguments, or to identify valid syslog * facilities or options for any given architecture. * *\li It is necessary to call isc_log_opensyslog() to initialize * syslogging on machines which do not support network connections to * syslogd because they require a Unix domain socket to be used. Since * this is a chore to determine at run-time, it is suggested that it * always be called by programs using the ISC logging system. * * Requires: *\li Nothing. * * Ensures: *\li openlog() is called to initialize the syslog system. */ void isc_log_closefilelogs(isc_log_t *lctx); /*%< * Close all open files used by #ISC_LOG_TOFILE channels. * * Notes: *\li This function is provided for programs that want to use their own * log rolling mechanism rather than the one provided internally. * For example, a program that wanted to keep daily logs would define * a channel which used #ISC_LOG_ROLLNEVER, then once a day would * rename the log file and call isc_log_closefilelogs(). * *\li #ISC_LOG_TOFILEDESC channels are unaffected. * * Requires: *\li lctx is a valid context. * * Ensures: *\li The open files are closed and will be reopened when they are * next needed. */ isc_logcategory_t * isc_log_categorybyname(isc_log_t *lctx, const char *name); /*%< * Find a category by its name. * * Notes: *\li The string name of a category is not required to be unique. * * Requires: *\li lctx is a valid context. *\li name is not NULL. * * Returns: *\li A pointer to the _first_ isc_logcategory_t structure used by "name". * *\li NULL if no category exists by that name. */ isc_logmodule_t * isc_log_modulebyname(isc_log_t *lctx, const char *name); /*%< * Find a module by its name. * * Notes: *\li The string name of a module is not required to be unique. * * Requires: *\li lctx is a valid context. *\li name is not NULL. * * Returns: *\li A pointer to the _first_ isc_logmodule_t structure used by "name". * *\li NULL if no module exists by that name. */ void isc_log_setcontext(isc_log_t *lctx); /*%< * Sets the context used by the libisc for logging. * * Requires: *\li lctx be a valid context. */ ISC_LANG_ENDDECLS #endif /* ISC_LOG_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/ipv6.h0000644000470500017500000000714512664710322020162 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ipv6.h,v 1.24 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_IPV6_H #define ISC_IPV6_H 1 /*! * Also define LWRES_IPV6_H to keep it from being included if liblwres is * being used, or redefinition errors will occur. */ #define LWRES_IPV6_H 1 /***** ***** Module Info *****/ /*! \file isc/ipv6.h * \brief IPv6 definitions for systems which do not support IPv6. * * \li MP: * No impact. * * \li Reliability: * No anticipated impact. * * \li Resources: * N/A. * * \li Security: * No anticipated impact. * * \li Standards: * RFC2553. */ /*** *** Imports. ***/ #include #include /*** *** Types. ***/ struct in6_addr { union { isc_uint8_t _S6_u8[16]; isc_uint16_t _S6_u16[8]; isc_uint32_t _S6_u32[4]; } _S6_un; }; #define s6_addr _S6_un._S6_u8 #define s6_addr8 _S6_un._S6_u8 #define s6_addr16 _S6_un._S6_u16 #define s6_addr32 _S6_un._S6_u32 #define IN6ADDR_ANY_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}} #define IN6ADDR_LOOPBACK_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}} LIBISC_EXTERNAL_DATA extern const struct in6_addr in6addr_any; LIBISC_EXTERNAL_DATA extern const struct in6_addr in6addr_loopback; struct sockaddr_in6 { #ifdef ISC_PLATFORM_HAVESALEN isc_uint8_t sin6_len; isc_uint8_t sin6_family; #else isc_uint16_t sin6_family; #endif isc_uint16_t sin6_port; isc_uint32_t sin6_flowinfo; struct in6_addr sin6_addr; isc_uint32_t sin6_scope_id; }; #ifdef ISC_PLATFORM_HAVESALEN #define SIN6_LEN 1 #endif /*% * Unspecified */ #define IN6_IS_ADDR_UNSPECIFIED(a) \ (((a)->s6_addr32[0] == 0) && \ ((a)->s6_addr32[1] == 0) && \ ((a)->s6_addr32[2] == 0) && \ ((a)->s6_addr32[3] == 0)) /*% * Loopback */ #define IN6_IS_ADDR_LOOPBACK(a) \ (((a)->s6_addr32[0] == 0) && \ ((a)->s6_addr32[1] == 0) && \ ((a)->s6_addr32[2] == 0) && \ ((a)->s6_addr32[3] == htonl(1))) /*% * IPv4 compatible */ #define IN6_IS_ADDR_V4COMPAT(a) \ (((a)->s6_addr32[0] == 0) && \ ((a)->s6_addr32[1] == 0) && \ ((a)->s6_addr32[2] == 0) && \ ((a)->s6_addr32[3] != 0) && \ ((a)->s6_addr32[3] != htonl(1))) /*% * Mapped */ #define IN6_IS_ADDR_V4MAPPED(a) \ (((a)->s6_addr32[0] == 0) && \ ((a)->s6_addr32[1] == 0) && \ ((a)->s6_addr32[2] == htonl(0x0000ffff))) /*% * Multicast */ #define IN6_IS_ADDR_MULTICAST(a) \ ((a)->s6_addr8[0] == 0xffU) /*% * Unicast link / site local. */ #define IN6_IS_ADDR_LINKLOCAL(a) \ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80)) #define IN6_IS_ADDR_SITELOCAL(a) \ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0)) #endif /* ISC_IPV6_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/string.h0000644000470500017500000001464212664710322020604 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: string.h,v 1.23 2007/09/13 04:48:16 each Exp $ */ #ifndef ISC_STRING_H #define ISC_STRING_H 1 /*! \file isc/string.h */ #include #include #include #include #include #include #ifdef ISC_PLATFORM_HAVESTRINGSH #include #endif #define ISC_STRING_MAGIC 0x5e ISC_LANG_BEGINDECLS isc_uint64_t isc_string_touint64(char *source, char **endp, int base); /*%< * Convert the string pointed to by 'source' to isc_uint64_t. * * On successful conversion 'endp' points to the first character * after conversion is complete. * * 'base': 0 or 2..36 * * If base is 0 the base is computed from the string type. * * On error 'endp' points to 'source'. */ isc_result_t isc_string_copy(char *target, size_t size, const char *source); /* * Copy the string pointed to by 'source' to 'target' which is a * pointer to a string of at least 'size' bytes. * * Requires: * 'target' is a pointer to a char[] of at least 'size' bytes. * 'size' an integer > 0. * 'source' == NULL or points to a NUL terminated string. * * Ensures: * If result == ISC_R_SUCCESS * 'target' will be a NUL terminated string of no more * than 'size' bytes (including NUL). * * If result == ISC_R_NOSPACE * 'target' is undefined. * * Returns: * ISC_R_SUCCESS -- 'source' was successfully copied to 'target'. * ISC_R_NOSPACE -- 'source' could not be copied since 'target' * is too small. */ void isc_string_copy_truncate(char *target, size_t size, const char *source); /* * Copy the string pointed to by 'source' to 'target' which is a * pointer to a string of at least 'size' bytes. * * Requires: * 'target' is a pointer to a char[] of at least 'size' bytes. * 'size' an integer > 0. * 'source' == NULL or points to a NUL terminated string. * * Ensures: * 'target' will be a NUL terminated string of no more * than 'size' bytes (including NUL). */ isc_result_t isc_string_append(char *target, size_t size, const char *source); /* * Append the string pointed to by 'source' to 'target' which is a * pointer to a NUL terminated string of at least 'size' bytes. * * Requires: * 'target' is a pointer to a NUL terminated char[] of at * least 'size' bytes. * 'size' an integer > 0. * 'source' == NULL or points to a NUL terminated string. * * Ensures: * If result == ISC_R_SUCCESS * 'target' will be a NUL terminated string of no more * than 'size' bytes (including NUL). * * If result == ISC_R_NOSPACE * 'target' is undefined. * * Returns: * ISC_R_SUCCESS -- 'source' was successfully appended to 'target'. * ISC_R_NOSPACE -- 'source' could not be appended since 'target' * is too small. */ void isc_string_append_truncate(char *target, size_t size, const char *source); /* * Append the string pointed to by 'source' to 'target' which is a * pointer to a NUL terminated string of at least 'size' bytes. * * Requires: * 'target' is a pointer to a NUL terminated char[] of at * least 'size' bytes. * 'size' an integer > 0. * 'source' == NULL or points to a NUL terminated string. * * Ensures: * 'target' will be a NUL terminated string of no more * than 'size' bytes (including NUL). */ isc_result_t isc_string_printf(char *target, size_t size, const char *format, ...) ISC_FORMAT_PRINTF(3, 4); /* * Print 'format' to 'target' which is a pointer to a string of at least * 'size' bytes. * * Requires: * 'target' is a pointer to a char[] of at least 'size' bytes. * 'size' an integer > 0. * 'format' == NULL or points to a NUL terminated string. * * Ensures: * If result == ISC_R_SUCCESS * 'target' will be a NUL terminated string of no more * than 'size' bytes (including NUL). * * If result == ISC_R_NOSPACE * 'target' is undefined. * * Returns: * ISC_R_SUCCESS -- 'format' was successfully printed to 'target'. * ISC_R_NOSPACE -- 'format' could not be printed to 'target' since it * is too small. */ void isc_string_printf_truncate(char *target, size_t size, const char *format, ...) ISC_FORMAT_PRINTF(3, 4); /* * Print 'format' to 'target' which is a pointer to a string of at least * 'size' bytes. * * Requires: * 'target' is a pointer to a char[] of at least 'size' bytes. * 'size' an integer > 0. * 'format' == NULL or points to a NUL terminated string. * * Ensures: * 'target' will be a NUL terminated string of no more * than 'size' bytes (including NUL). */ char * isc_string_regiondup(isc_mem_t *mctx, const isc_region_t *source); /* * Copy the region pointed to by r to a NUL terminated string * allocated from the memory context pointed to by mctx. * * The result should be deallocated using isc_mem_free() * * Requires: * 'mctx' is a point to a valid memory context. * 'source' is a pointer to a valid region. * * Returns: * a pointer to a NUL terminated string or * NULL if memory for the copy could not be allocated * */ char * isc_string_separate(char **stringp, const char *delim); #ifdef ISC_PLATFORM_NEEDSTRSEP #define strsep isc_string_separate #endif #ifdef ISC_PLATFORM_NEEDMEMMOVE #define memmove(a,b,c) bcopy(b,a,c) #endif size_t isc_string_strlcpy(char *dst, const char *src, size_t size); #ifdef ISC_PLATFORM_NEEDSTRLCPY #define strlcpy isc_string_strlcpy #endif size_t isc_string_strlcat(char *dst, const char *src, size_t size); #ifdef ISC_PLATFORM_NEEDSTRLCAT #define strlcat isc_string_strlcat #endif char * isc_string_strcasestr(const char *big, const char *little); #ifdef ISC_PLATFORM_NEEDSTRCASESTR #define strcasestr isc_string_strcasestr #endif ISC_LANG_ENDDECLS #endif /* ISC_STRING_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/hmacmd5.h0000644000470500017500000000400412664710322020603 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: hmacmd5.h,v 1.14 2009/02/06 23:47:42 tbox Exp $ */ /*! \file isc/hmacmd5.h * \brief This is the header file for the HMAC-MD5 keyed hash algorithm * described in RFC2104. */ #ifndef ISC_HMACMD5_H #define ISC_HMACMD5_H 1 #include #include #include #include #define ISC_HMACMD5_KEYLENGTH 64 #ifdef ISC_PLATFORM_OPENSSLHASH #include typedef HMAC_CTX isc_hmacmd5_t; #elif PKCS11CRYPTO #include typedef pk11_context_t isc_hmacmd5_t; #else typedef struct { isc_md5_t md5ctx; unsigned char key[ISC_HMACMD5_KEYLENGTH]; } isc_hmacmd5_t; #endif ISC_LANG_BEGINDECLS void isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key, unsigned int len); void isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx); void isc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf, unsigned int len); void isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest); isc_boolean_t isc_hmacmd5_verify(isc_hmacmd5_t *ctx, unsigned char *digest); isc_boolean_t isc_hmacmd5_verify2(isc_hmacmd5_t *ctx, unsigned char *digest, size_t len); ISC_LANG_ENDDECLS #endif /* ISC_HMACMD5_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/safe.h0000644000470500017500000000240412664710322020205 0ustar lamontlamont/* * Copyright (C) 2013, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef ISC_SAFE_H #define ISC_SAFE_H 1 /*! \file isc/safe.h */ #include ISC_LANG_BEGINDECLS isc_boolean_t isc_safe_memequal(const void *s1, const void *s2, size_t n); /*%< * Returns ISC_TRUE iff. two blocks of memory are equal, otherwise * ISC_FALSE. * */ int isc_safe_memcompare(const void *b1, const void *b2, size_t len); /*%< * Clone of libc memcmp() which is safe to differential timing attacks. */ ISC_LANG_ENDDECLS #endif /* ISC_SAFE_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/types.h0000644000470500017500000001366712664710322020450 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2012-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef ISC_TYPES_H #define ISC_TYPES_H 1 #include /*! \file isc/types.h * \brief * OS-specific types, from the OS-specific include directories. */ #include #include /* * XXXDCL should isc_boolean_t be moved here, requiring an explicit include * of when ISC_TRUE/ISC_FALSE/ISC_TF() are desired? */ #include /* * XXXDCL This is just for ISC_LIST and ISC_LINK, but gets all of the other * list macros too. */ #include /* Core Types. Alphabetized by defined type. */ typedef struct isc_appctx isc_appctx_t; /*%< Application context */ typedef struct isc_backtrace_symmap isc_backtrace_symmap_t; /*%< Symbol Table Entry */ typedef struct isc_buffer isc_buffer_t; /*%< Buffer */ typedef ISC_LIST(isc_buffer_t) isc_bufferlist_t; /*%< Buffer List */ typedef struct isc_constregion isc_constregion_t; /*%< Const region */ typedef struct isc_consttextregion isc_consttextregion_t; /*%< Const Text Region */ typedef struct isc_counter isc_counter_t; /*%< Counter */ typedef isc_int16_t isc_dscp_t; /*%< Diffserv code point */ typedef struct isc_entropy isc_entropy_t; /*%< Entropy */ typedef struct isc_entropysource isc_entropysource_t; /*%< Entropy Source */ typedef struct isc_event isc_event_t; /*%< Event */ typedef ISC_LIST(isc_event_t) isc_eventlist_t; /*%< Event List */ typedef unsigned int isc_eventtype_t; /*%< Event Type */ typedef isc_uint32_t isc_fsaccess_t; /*%< FS Access */ typedef struct isc_hash isc_hash_t; /*%< Hash */ typedef struct isc_httpd isc_httpd_t; /*%< HTTP client */ typedef void (isc_httpdfree_t)(isc_buffer_t *, void *); /*%< HTTP free function */ typedef struct isc_httpdmgr isc_httpdmgr_t; /*%< HTTP manager */ typedef struct isc_httpdurl isc_httpdurl_t; /*%< HTTP URL */ typedef void (isc_httpdondestroy_t)(void *); /*%< Callback on destroying httpd */ typedef struct isc_interface isc_interface_t; /*%< Interface */ typedef struct isc_interfaceiter isc_interfaceiter_t; /*%< Interface Iterator */ typedef struct isc_interval isc_interval_t; /*%< Interval */ typedef struct isc_lex isc_lex_t; /*%< Lex */ typedef struct isc_log isc_log_t; /*%< Log */ typedef struct isc_logcategory isc_logcategory_t; /*%< Log Category */ typedef struct isc_logconfig isc_logconfig_t; /*%< Log Configuration */ typedef struct isc_logmodule isc_logmodule_t; /*%< Log Module */ typedef struct isc_mem isc_mem_t; /*%< Memory */ typedef struct isc_mempool isc_mempool_t; /*%< Memory Pool */ typedef struct isc_msgcat isc_msgcat_t; /*%< Message Catalog */ typedef struct isc_ondestroy isc_ondestroy_t; /*%< On Destroy */ typedef struct isc_netaddr isc_netaddr_t; /*%< Net Address */ typedef struct isc_portset isc_portset_t; /*%< Port Set */ typedef struct isc_quota isc_quota_t; /*%< Quota */ typedef struct isc_random isc_random_t; /*%< Random */ typedef struct isc_ratelimiter isc_ratelimiter_t; /*%< Rate Limiter */ typedef struct isc_region isc_region_t; /*%< Region */ typedef isc_uint64_t isc_resourcevalue_t; /*%< Resource Value */ typedef unsigned int isc_result_t; /*%< Result */ typedef struct isc_rwlock isc_rwlock_t; /*%< Read Write Lock */ typedef struct isc_sockaddr isc_sockaddr_t; /*%< Socket Address */ typedef struct isc_socket isc_socket_t; /*%< Socket */ typedef struct isc_socketevent isc_socketevent_t; /*%< Socket Event */ typedef struct isc_socketmgr isc_socketmgr_t; /*%< Socket Manager */ typedef struct isc_stats isc_stats_t; /*%< Statistics */ typedef int isc_statscounter_t; /*%< Statistics Counter */ typedef struct isc_symtab isc_symtab_t; /*%< Symbol Table */ typedef struct isc_task isc_task_t; /*%< Task */ typedef ISC_LIST(isc_task_t) isc_tasklist_t; /*%< Task List */ typedef struct isc_taskmgr isc_taskmgr_t; /*%< Task Manager */ typedef struct isc_textregion isc_textregion_t; /*%< Text Region */ typedef struct isc_time isc_time_t; /*%< Time */ typedef struct isc_timer isc_timer_t; /*%< Timer */ typedef struct isc_timermgr isc_timermgr_t; /*%< Timer Manager */ typedef void (*isc_taskaction_t)(isc_task_t *, isc_event_t *); typedef int (*isc_sockfdwatch_t)(isc_task_t *, isc_socket_t *, void *, int); /* The following cannot be listed alphabetically due to forward reference */ typedef isc_result_t (isc_httpdaction_t)(const char *url, isc_httpdurl_t *urlinfo, const char *querystring, const char *headers, void *arg, unsigned int *retcode, const char **retmsg, const char **mimetype, isc_buffer_t *body, isc_httpdfree_t **freecb, void **freecb_args); typedef isc_boolean_t (isc_httpdclientok_t)(const isc_sockaddr_t *, void *); /*% Resource */ typedef enum { isc_resource_coresize = 1, isc_resource_cputime, isc_resource_datasize, isc_resource_filesize, isc_resource_lockedmemory, isc_resource_openfiles, isc_resource_processes, isc_resource_residentsize, isc_resource_stacksize } isc_resource_t; /*% Statistics formats (text file or XML) */ typedef enum { isc_statsformat_file, isc_statsformat_xml, isc_statsformat_json } isc_statsformat_t; #endif /* ISC_TYPES_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/tm.h0000644000470500017500000000242112664710322017706 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef ISC_TM_H #define ISC_TM_H 1 /*! \file isc/tm.h * Provides portable conversion routines for struct tm. */ #include #include #include ISC_LANG_BEGINDECLS time_t isc_tm_timegm(struct tm *tm); /* * Convert a tm structure to time_t, using UTC rather than the local * time zone. */ char * isc_tm_strptime(const char *buf, const char *fmt, struct tm *tm); /* * Parse a formatted date string into struct tm. */ ISC_LANG_ENDDECLS #endif /* ISC_TIMER_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/lfsr.h0000644000470500017500000000663012664710322020242 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lfsr.h,v 1.17 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_LFSR_H #define ISC_LFSR_H 1 /*! \file isc/lfsr.h */ #include #include typedef struct isc_lfsr isc_lfsr_t; /*% * This function is called when reseeding is needed. It is allowed to * modify any state in the LFSR in any way it sees fit OTHER THAN "bits". * * It MUST set "count" to a new value or the lfsr will never reseed again. * * Also, a reseed will never occur in the middle of an extraction. This * is purely an optimization, and is probably what one would want. */ typedef void (*isc_lfsrreseed_t)(isc_lfsr_t *, void *); /*% * The members of this structure can be used by the application, but care * needs to be taken to not change state once the lfsr is in operation. */ struct isc_lfsr { isc_uint32_t state; /*%< previous state */ unsigned int bits; /*%< length */ isc_uint32_t tap; /*%< bit taps */ unsigned int count; /*%< reseed count (in BITS!) */ isc_lfsrreseed_t reseed; /*%< reseed function */ void *arg; /*%< reseed function argument */ }; ISC_LANG_BEGINDECLS void isc_lfsr_init(isc_lfsr_t *lfsr, isc_uint32_t state, unsigned int bits, isc_uint32_t tap, unsigned int count, isc_lfsrreseed_t reseed, void *arg); /*%< * Initialize an LFSR. * * Note: * *\li Putting untrusted values into this function will cause the LFSR to * generate (perhaps) non-maximal length sequences. * * Requires: * *\li lfsr != NULL * *\li 8 <= bits <= 32 * *\li tap != 0 */ void isc_lfsr_generate(isc_lfsr_t *lfsr, void *data, unsigned int count); /*%< * Returns "count" bytes of data from the LFSR. * * Requires: * *\li lfsr be valid. * *\li data != NULL. * *\li count > 0. */ void isc_lfsr_skip(isc_lfsr_t *lfsr, unsigned int skip); /*%< * Skip "skip" states. * * Requires: * *\li lfsr be valid. */ isc_uint32_t isc_lfsr_generate32(isc_lfsr_t *lfsr1, isc_lfsr_t *lfsr2); /*%< * Given two LFSRs, use the current state from each to skip entries in the * other. The next states are then xor'd together and returned. * * WARNING: * *\li This function is used only for very, very low security data, such * as DNS message IDs where it is desired to have an unpredictable * stream of bytes that are harder to predict than a simple flooding * attack. * * Notes: * *\li Since the current state from each of the LFSRs is used to skip * state in the other, it is important that no state be leaked * from either LFSR. * * Requires: * *\li lfsr1 and lfsr2 be valid. * *\li 1 <= skipbits <= 31 */ ISC_LANG_ENDDECLS #endif /* ISC_LFSR_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/formatcheck.h0000644000470500017500000000261712664710322021563 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: formatcheck.h,v 1.13 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_FORMATCHECK_H #define ISC_FORMATCHECK_H 1 /*! \file isc/formatcheck.h */ /*% * ISC_FORMAT_PRINTF(). * * \li fmt is the location of the format string parameter. * \li args is the location of the first argument (or 0 for no argument checking). * * Note: * \li The first parameter is 1, not 0. */ #ifdef __GNUC__ #define ISC_FORMAT_PRINTF(fmt, args) __attribute__((__format__(__printf__, fmt, args))) #else #define ISC_FORMAT_PRINTF(fmt, args) #endif #endif /* ISC_FORMATCHECK_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/lib.h0000644000470500017500000000307212664710322020037 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lib.h,v 1.16 2009/09/02 23:48:03 tbox Exp $ */ #ifndef ISC_LIB_H #define ISC_LIB_H 1 /*! \file isc/lib.h */ #include #include ISC_LANG_BEGINDECLS LIBISC_EXTERNAL_DATA extern isc_msgcat_t *isc_msgcat; void isc_lib_initmsgcat(void); /*!< * \brief Initialize the ISC library's message catalog, isc_msgcat, if it * has not already been initialized. */ void isc_lib_register(void); /*!< * \brief Register the ISC library implementations for some base services * such as memory or event management and handling socket or timer events. * An external application that wants to use the ISC library must call this * function very early in main(). */ ISC_LANG_ENDDECLS #endif /* ISC_LIB_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/entropy.h0000644000470500017500000002234412664710322020774 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: entropy.h,v 1.35 2009/10/19 02:37:08 marka Exp $ */ #ifndef ISC_ENTROPY_H #define ISC_ENTROPY_H 1 /***** ***** Module Info *****/ /*! \file isc/entropy.h * \brief The entropy API * * \li MP: * The entropy object is locked internally. All callbacks into * application-provided functions (for setup, gathering, and * shutdown of sources) are guaranteed to be called with the * entropy API lock held. This means these functions are * not permitted to call back into the entropy API. * * \li Reliability: * No anticipated impact. * * \li Resources: * A buffer, used as an entropy pool. * * \li Security: * While this code is believed to implement good entropy gathering * and distribution, it has not been reviewed by a cryptographic * expert. * Since the added entropy is only as good as the sources used, * this module could hand out bad data and never know it. * * \li Standards: * None. */ /*** *** Imports ***/ #include #include #include /*@{*/ /*% Entropy callback function. */ typedef isc_result_t (*isc_entropystart_t)(isc_entropysource_t *source, void *arg, isc_boolean_t blocking); typedef isc_result_t (*isc_entropyget_t)(isc_entropysource_t *source, void *arg, isc_boolean_t blocking); typedef void (*isc_entropystop_t)(isc_entropysource_t *source, void *arg); /*@}*/ /*** *** Flags. ***/ /*! * \brief * Extract only "good" data; return failure if there is not enough * data available and there are no sources which we can poll to get * data, or those sources are empty. * * */ #define ISC_ENTROPY_GOODONLY 0x00000001U /*! * \brief * Extract as much good data as possible, but if there isn't enough * at hand, return what is available. This flag only makes sense * when used with _GOODONLY. */ #define ISC_ENTROPY_PARTIAL 0x00000002U /*! * \brief * Block the task until data is available. This is contrary to the * ISC task system, where tasks should never block. However, if * this is a special purpose application where blocking a task is * acceptable (say, an offline zone signer) this flag may be set. * This flag only makes sense when used with _GOODONLY, and will * block regardless of the setting for _PARTIAL. */ #define ISC_ENTROPY_BLOCKING 0x00000004U /*! * \brief * Estimate the amount of entropy contained in the sample pool. * If this is not set, the source will be gathered and periodically * mixed into the entropy pool, but no increment in contained entropy * will be assumed. This flag only makes sense on sample sources. */ #define ISC_ENTROPYSOURCE_ESTIMATE 0x00000001U /* * For use with isc_entropy_usebestsource(). */ /*! * \brief * Use the keyboard as the only entropy source. */ #define ISC_ENTROPY_KEYBOARDYES 1 /*! * \brief * Never use the keyboard as an entropy source. */ #define ISC_ENTROPY_KEYBOARDNO 2 /*! * \brief * Use the keyboard as an entropy source only if opening the * random device fails. */ #define ISC_ENTROPY_KEYBOARDMAYBE 3 ISC_LANG_BEGINDECLS /*** *** Functions ***/ isc_result_t isc_entropy_create(isc_mem_t *mctx, isc_entropy_t **entp); /*!< * \brief Create a new entropy object. */ void isc_entropy_attach(isc_entropy_t *ent, isc_entropy_t **entp); /*!< * Attaches to an entropy object. */ void isc_entropy_detach(isc_entropy_t **entp); /*!< * \brief Detaches from an entropy object. */ isc_result_t isc_entropy_createfilesource(isc_entropy_t *ent, const char *fname); /*!< * \brief Create a new entropy source from a file. * * The file is assumed to contain good randomness, and will be mixed directly * into the pool with every byte adding 8 bits of entropy. * * The file will be put into non-blocking mode, so it may be a device file, * such as /dev/random. /dev/urandom should not be used here if it can * be avoided, since it will always provide data even if it isn't good. * We will make as much pseudorandom data as we need internally if our * caller asks for it. * * If we hit end-of-file, we will stop reading from this source. Callers * who require strong random data will get failure when our pool drains. * The file will never be opened/read again once EOF is reached. */ void isc_entropy_destroysource(isc_entropysource_t **sourcep); /*!< * \brief Removes an entropy source from the entropy system. */ isc_result_t isc_entropy_createsamplesource(isc_entropy_t *ent, isc_entropysource_t **sourcep); /*!< * \brief Create an entropy source that consists of samples. Each sample is * added to the source via isc_entropy_addsamples(), below. */ isc_result_t isc_entropy_createcallbacksource(isc_entropy_t *ent, isc_entropystart_t start, isc_entropyget_t get, isc_entropystop_t stop, void *arg, isc_entropysource_t **sourcep); /*!< * \brief Create an entropy source that is polled via a callback. * * This would * be used when keyboard input is used, or a GUI input method. It can * also be used to hook in any external entropy source. * * Samples are added via isc_entropy_addcallbacksample(), below. * _addcallbacksample() is the only function which may be called from * within an entropy API callback function. */ void isc_entropy_stopcallbacksources(isc_entropy_t *ent); /*!< * \brief Call the stop functions for callback sources that have had their * start functions called. */ /*@{*/ isc_result_t isc_entropy_addcallbacksample(isc_entropysource_t *source, isc_uint32_t sample, isc_uint32_t extra); isc_result_t isc_entropy_addsample(isc_entropysource_t *source, isc_uint32_t sample, isc_uint32_t extra); /*!< * \brief Add a sample to the sample source. * * The sample MUST be a timestamp * that increases over time, with the exception of wrap-around for * extremely high resolution timers which will quickly wrap-around * a 32-bit integer. * * The "extra" parameter is used only to add a bit more unpredictable * data. It is not used other than included in the hash of samples. * * When in an entropy API callback function, _addcallbacksource() must be * used. At all other times, _addsample() must be used. */ /*@}*/ isc_result_t isc_entropy_getdata(isc_entropy_t *ent, void *data, unsigned int length, unsigned int *returned, unsigned int flags); /*!< * \brief Extract data from the entropy pool. This may load the pool from various * sources. * * Do this by stiring the pool and returning a part of hash as randomness. * Note that no secrets are given away here since parts of the hash are * xored together before returned. * * Honor the request from the caller to only return good data, any data, * etc. */ void isc_entropy_putdata(isc_entropy_t *ent, void *data, unsigned int length, isc_uint32_t entropy); /*!< * \brief Add "length" bytes in "data" to the entropy pool, incrementing the * pool's entropy count by "entropy." * * These bytes will prime the pseudorandom portion even if no entropy is * actually added. */ void isc_entropy_stats(isc_entropy_t *ent, FILE *out); /*!< * \brief Dump some (trivial) stats to the stdio stream "out". */ unsigned int isc_entropy_status(isc_entropy_t *end); /* * Returns the number of bits the pool currently contains. This is just * an estimate. */ isc_result_t isc_entropy_usebestsource(isc_entropy_t *ectx, isc_entropysource_t **source, const char *randomfile, int use_keyboard); /*!< * \brief Use whatever source of entropy is best. * * Notes: *\li If "randomfile" is not NULL, open it with * isc_entropy_createfilesource(). * *\li If "randomfile" is NULL and the system's random device was detected * when the program was configured and built, open that device with * isc_entropy_createfilesource(). * *\li If "use_keyboard" is #ISC_ENTROPY_KEYBOARDYES, then always open * the keyboard as an entropy source (possibly in addition to * "randomfile" or the random device). * *\li If "use_keyboard" is #ISC_ENTROPY_KEYBOARDMAYBE, open the keyboard only * if opening the random file/device fails. A message will be * printed describing the need for keyboard input. * *\li If "use_keyboard" is #ISC_ENTROPY_KEYBOARDNO, the keyboard will * never be opened. * * Returns: *\li #ISC_R_SUCCESS if at least one source of entropy could be started. * *\li #ISC_R_NOENTROPY if use_keyboard is #ISC_ENTROPY_KEYBOARDNO and * there is no random device pathname compiled into the program. * *\li A return code from isc_entropy_createfilesource() or * isc_entropy_createcallbacksource(). */ ISC_LANG_ENDDECLS #endif /* ISC_ENTROPY_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/assertions.h0000644000470500017500000000636212664710322021470 0ustar lamontlamont/* * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1997-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * $Id: assertions.h,v 1.28 2009/09/29 23:48:04 tbox Exp $ */ /*! \file isc/assertions.h */ #ifndef ISC_ASSERTIONS_H #define ISC_ASSERTIONS_H 1 #include #include ISC_LANG_BEGINDECLS /*% isc assertion type */ typedef enum { isc_assertiontype_require, isc_assertiontype_ensure, isc_assertiontype_insist, isc_assertiontype_invariant } isc_assertiontype_t; typedef void (*isc_assertioncallback_t)(const char *, int, isc_assertiontype_t, const char *); /* coverity[+kill] */ ISC_PLATFORM_NORETURN_PRE void isc_assertion_failed(const char *, int, isc_assertiontype_t, const char *) ISC_PLATFORM_NORETURN_POST; void isc_assertion_setcallback(isc_assertioncallback_t); const char * isc_assertion_typetotext(isc_assertiontype_t type); #if defined(ISC_CHECK_ALL) || defined(__COVERITY__) #define ISC_CHECK_REQUIRE 1 #define ISC_CHECK_ENSURE 1 #define ISC_CHECK_INSIST 1 #define ISC_CHECK_INVARIANT 1 #endif #if defined(ISC_CHECK_NONE) && !defined(__COVERITY__) #define ISC_CHECK_REQUIRE 0 #define ISC_CHECK_ENSURE 0 #define ISC_CHECK_INSIST 0 #define ISC_CHECK_INVARIANT 0 #endif #ifndef ISC_CHECK_REQUIRE #define ISC_CHECK_REQUIRE 1 #endif #ifndef ISC_CHECK_ENSURE #define ISC_CHECK_ENSURE 1 #endif #ifndef ISC_CHECK_INSIST #define ISC_CHECK_INSIST 1 #endif #ifndef ISC_CHECK_INVARIANT #define ISC_CHECK_INVARIANT 1 #endif #if ISC_CHECK_REQUIRE != 0 #define ISC_REQUIRE(cond) \ ((void) ((cond) || \ ((isc_assertion_failed)(__FILE__, __LINE__, \ isc_assertiontype_require, \ #cond), 0))) #else #define ISC_REQUIRE(cond) ((void) 0) #endif /* ISC_CHECK_REQUIRE */ #if ISC_CHECK_ENSURE != 0 #define ISC_ENSURE(cond) \ ((void) ((cond) || \ ((isc_assertion_failed)(__FILE__, __LINE__, \ isc_assertiontype_ensure, \ #cond), 0))) #else #define ISC_ENSURE(cond) ((void) 0) #endif /* ISC_CHECK_ENSURE */ #if ISC_CHECK_INSIST != 0 #define ISC_INSIST(cond) \ ((void) ((cond) || \ ((isc_assertion_failed)(__FILE__, __LINE__, \ isc_assertiontype_insist, \ #cond), 0))) #else #define ISC_INSIST(cond) ((void) 0) #endif /* ISC_CHECK_INSIST */ #if ISC_CHECK_INVARIANT != 0 #define ISC_INVARIANT(cond) \ ((void) ((cond) || \ ((isc_assertion_failed)(__FILE__, __LINE__, \ isc_assertiontype_invariant, \ #cond), 0))) #else #define ISC_INVARIANT(cond) ((void) 0) #endif /* ISC_CHECK_INVARIANT */ ISC_LANG_ENDDECLS #endif /* ISC_ASSERTIONS_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/base64.h0000644000470500017500000000562712664710322020365 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: base64.h,v 1.22 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_BASE64_H #define ISC_BASE64_H 1 /*! \file isc/base64.h */ #include #include ISC_LANG_BEGINDECLS /*** *** Functions ***/ isc_result_t isc_base64_totext(isc_region_t *source, int wordlength, const char *wordbreak, isc_buffer_t *target); /*!< * \brief Convert data into base64 encoded text. * * Notes: *\li The base64 encoded text in 'target' will be divided into * words of at most 'wordlength' characters, separated by * the 'wordbreak' string. No parentheses will surround * the text. * * Requires: *\li 'source' is a region containing binary data *\li 'target' is a text buffer containing available space *\li 'wordbreak' points to a null-terminated string of * zero or more whitespace characters * * Ensures: *\li target will contain the base64 encoded version of the data * in source. The 'used' pointer in target will be advanced as * necessary. */ isc_result_t isc_base64_decodestring(const char *cstr, isc_buffer_t *target); /*!< * \brief Decode a null-terminated base64 string. * * Requires: *\li 'cstr' is non-null. *\li 'target' is a valid buffer. * * Returns: *\li #ISC_R_SUCCESS -- the entire decoded representation of 'cstring' * fit in 'target'. *\li #ISC_R_BADBASE64 -- 'cstr' is not a valid base64 encoding. * * Other error returns are any possible error code from: *\li isc_lex_create(), *\li isc_lex_openbuffer(), *\li isc_base64_tobuffer(). */ isc_result_t isc_base64_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length); /*!< * \brief Convert base64 encoded text from a lexer context into data. * * Requires: *\li 'lex' is a valid lexer context *\li 'target' is a buffer containing binary data *\li 'length' is an integer * * Ensures: *\li target will contain the data represented by the base64 encoded * string parsed by the lexer. No more than length bytes will be read, * if length is positive. The 'used' pointer in target will be * advanced as necessary. */ ISC_LANG_ENDDECLS #endif /* ISC_BASE64_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/app.h0000644000470500017500000002540212664710322020052 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2013-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: app.h,v 1.11 2009/09/02 23:48:03 tbox Exp $ */ #ifndef ISC_APP_H #define ISC_APP_H 1 /***** ***** Module Info *****/ /*! \file isc/app.h * \brief ISC Application Support * * Dealing with program termination can be difficult, especially in a * multithreaded program. The routines in this module help coordinate * the shutdown process. They are used as follows by the initial (main) * thread of the application: * *\li isc_app_start(); Call very early in main(), before * any other threads have been created. * *\li isc_app_run(); This will post any on-run events, * and then block until application * shutdown is requested. A shutdown * request is made by calling * isc_app_shutdown(), or by sending * SIGINT or SIGTERM to the process. * After isc_app_run() returns, the * application should shutdown itself. * *\li isc_app_finish(); Call very late in main(). * * Applications that want to use SIGHUP/isc_app_reload() to trigger reloading * should check the result of isc_app_run() and call the reload routine if * the result is ISC_R_RELOAD. They should then call isc_app_run() again * to resume waiting for reload or termination. * * Use of this module is not required. In particular, isc_app_start() is * NOT an ISC library initialization routine. * * This module also supports per-thread 'application contexts'. With this * mode, a thread-based application will have a separate context, in which * it uses other ISC library services such as tasks or timers. Signals are * not caught in this mode, so that the application can handle the signals * in its preferred way. * * \li MP: * Clients must ensure that isc_app_start(), isc_app_run(), and * isc_app_finish() are called at most once. isc_app_shutdown() * is safe to use by any thread (provided isc_app_start() has been * called previously). * * The same note applies to isc_app_ctxXXX() functions, but in this case * it's a per-thread restriction. For example, a thread with an * application context must ensure that isc_app_ctxstart() with the * context is called at most once. * * \li Reliability: * No anticipated impact. * * \li Resources: * None. * * \li Security: * No anticipated impact. * * \li Standards: * None. */ #include #include #include #include /*** *** Types ***/ typedef isc_event_t isc_appevent_t; #define ISC_APPEVENT_FIRSTEVENT (ISC_EVENTCLASS_APP + 0) #define ISC_APPEVENT_SHUTDOWN (ISC_EVENTCLASS_APP + 1) #define ISC_APPEVENT_LASTEVENT (ISC_EVENTCLASS_APP + 65535) /*% * app module methods. Only app driver implementations use this structure. * Other clients should use the top-level interfaces (i.e., isc_app_xxx * functions). magic must be ISCAPI_APPMETHODS_MAGIC. */ typedef struct isc_appmethods { void (*ctxdestroy)(isc_appctx_t **ctxp); isc_result_t (*ctxstart)(isc_appctx_t *ctx); isc_result_t (*ctxrun)(isc_appctx_t *ctx); isc_result_t (*ctxsuspend)(isc_appctx_t *ctx); isc_result_t (*ctxshutdown)(isc_appctx_t *ctx); void (*ctxfinish)(isc_appctx_t *ctx); void (*settaskmgr)(isc_appctx_t *ctx, isc_taskmgr_t *timermgr); void (*setsocketmgr)(isc_appctx_t *ctx, isc_socketmgr_t *timermgr); void (*settimermgr)(isc_appctx_t *ctx, isc_timermgr_t *timermgr); isc_result_t (*ctxonrun)(isc_appctx_t *ctx, isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action, void *arg); } isc_appmethods_t; /*% * This structure is actually just the common prefix of an application context * implementation's version of an isc_appctx_t. * \brief * Direct use of this structure by clients is forbidden. app implementations * may change the structure. 'magic' must be ISCAPI_APPCTX_MAGIC for any * of the isc_app_ routines to work. app implementations must maintain * all app context invariants. */ struct isc_appctx { unsigned int impmagic; unsigned int magic; isc_appmethods_t *methods; }; #define ISCAPI_APPCTX_MAGIC ISC_MAGIC('A','a','p','c') #define ISCAPI_APPCTX_VALID(c) ((c) != NULL && \ (c)->magic == ISCAPI_APPCTX_MAGIC) ISC_LANG_BEGINDECLS isc_result_t isc_app_ctxstart(isc_appctx_t *ctx); isc_result_t isc_app_start(void); /*!< * \brief Start an ISC library application. * * Notes: * This call should be made before any other ISC library call, and as * close to the beginning of the application as possible. * * Requires: *\li 'ctx' is a valid application context (for app_ctxstart()). */ isc_result_t isc_app_ctxonrun(isc_appctx_t *ctx, isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action, void *arg); isc_result_t isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action, void *arg); /*!< * \brief Request delivery of an event when the application is run. * * Requires: *\li isc_app_start() has been called. *\li 'ctx' is a valid application context (for app_ctxonrun()). * * Returns: * ISC_R_SUCCESS * ISC_R_NOMEMORY */ isc_result_t isc_app_ctxrun(isc_appctx_t *ctx); isc_result_t isc_app_run(void); /*!< * \brief Run an ISC library application. * * Notes: *\li The caller (typically the initial thread of an application) will * block until shutdown is requested. When the call returns, the * caller should start shutting down the application. * * Requires: *\li isc_app_[ctx]start() has been called. * * Ensures: *\li Any events requested via isc_app_onrun() will have been posted (in * FIFO order) before isc_app_run() blocks. *\li 'ctx' is a valid application context (for app_ctxrun()). * * Returns: *\li ISC_R_SUCCESS Shutdown has been requested. *\li ISC_R_RELOAD Reload has been requested. */ isc_boolean_t isc_app_isrunning(void); /*!< * \brief Return if the ISC library application is running. * * Returns: *\li ISC_TRUE App is running. *\li ISC_FALSE App is not running. */ isc_result_t isc_app_ctxshutdown(isc_appctx_t *ctx); isc_result_t isc_app_shutdown(void); /*!< * \brief Request application shutdown. * * Notes: *\li It is safe to call isc_app_shutdown() multiple times. Shutdown will * only be triggered once. * * Requires: *\li isc_app_[ctx]run() has been called. *\li 'ctx' is a valid application context (for app_ctxshutdown()). * * Returns: *\li ISC_R_SUCCESS *\li ISC_R_UNEXPECTED */ isc_result_t isc_app_ctxsuspend(isc_appctx_t *ctx); /*!< * \brief This has the same behavior as isc_app_ctxsuspend(). */ isc_result_t isc_app_reload(void); /*!< * \brief Request application reload. * * Requires: *\li isc_app_run() has been called. * * Returns: *\li ISC_R_SUCCESS *\li ISC_R_UNEXPECTED */ void isc_app_ctxfinish(isc_appctx_t *ctx); void isc_app_finish(void); /*!< * \brief Finish an ISC library application. * * Notes: *\li This call should be made at or near the end of main(). * * Requires: *\li isc_app_start() has been called. *\li 'ctx' is a valid application context (for app_ctxfinish()). * * Ensures: *\li Any resources allocated by isc_app_start() have been released. */ void isc_app_block(void); /*!< * \brief Indicate that a blocking operation will be performed. * * Notes: *\li If a blocking operation is in process, a call to isc_app_shutdown() * or an external signal will abort the program, rather than allowing * clean shutdown. This is primarily useful for reading user input. * * Requires: * \li isc_app_start() has been called. * \li No other blocking operations are in progress. */ void isc_app_unblock(void); /*!< * \brief Indicate that a blocking operation is complete. * * Notes: * \li When a blocking operation has completed, return the program to a * state where a call to isc_app_shutdown() or an external signal will * shutdown normally. * * Requires: * \li isc_app_start() has been called. * \li isc_app_block() has been called by the same thread. */ isc_result_t isc_appctx_create(isc_mem_t *mctx, isc_appctx_t **ctxp); /*!< * \brief Create an application context. * * Requires: *\li 'mctx' is a valid memory context. *\li 'ctxp' != NULL && *ctxp == NULL. */ void isc_appctx_destroy(isc_appctx_t **ctxp); /*!< * \brief Destroy an application context. * * Requires: *\li '*ctxp' is a valid application context. * * Ensures: *\li *ctxp == NULL. */ void isc_appctx_settaskmgr(isc_appctx_t *ctx, isc_taskmgr_t *taskmgr); /*!< * \brief Associate a task manager with an application context. * * This must be done before running tasks within the application context. * * Requires: *\li 'ctx' is a valid application context. *\li 'taskmgr' is a valid task manager. */ void isc_appctx_setsocketmgr(isc_appctx_t *ctx, isc_socketmgr_t *socketmgr); /*!< * \brief Associate a socket manager with an application context. * * This must be done before handling socket events within the application * context. * * Requires: *\li 'ctx' is a valid application context. *\li 'socketmgr' is a valid socket manager. */ void isc_appctx_settimermgr(isc_appctx_t *ctx, isc_timermgr_t *timermgr); /*!< * \brief Associate a socket timer with an application context. * * This must be done before handling timer events within the application * context. * * Requires: *\li 'ctx' is a valid application context. *\li 'timermgr' is a valid timer manager. */ /*%< * See isc_appctx_create() above. */ typedef isc_result_t (*isc_appctxcreatefunc_t)(isc_mem_t *mctx, isc_appctx_t **ctxp); isc_result_t isc_app_register(isc_appctxcreatefunc_t createfunc); /*%< * Register a new application implementation and add it to the list of * supported implementations. This function must be called when a different * event library is used than the one contained in the ISC library. */ isc_result_t isc__app_register(void); /*%< * A short cut function that specifies the application module in the ISC * library for isc_app_register(). An application that uses the ISC library * usually do not have to care about this function: it would call * isc_lib_register(), which internally calls this function. */ ISC_LANG_ENDDECLS #endif /* ISC_APP_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/base32.h0000644000470500017500000001053012664710322020345 0ustar lamontlamont/* * Copyright (C) 2008, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef ISC_BASE32_H #define ISC_BASE32_H 1 /*! \file */ /* * Routines for manipulating base 32 and base 32 hex encoded data. * Based on RFC 4648. * * Base 32 hex preserves the sort order of data when it is encoded / * decoded. * * Base 32 hex "np" is base 32 hex but no padding is produced or accepted. */ #include #include ISC_LANG_BEGINDECLS /*** *** Functions ***/ isc_result_t isc_base32_totext(isc_region_t *source, int wordlength, const char *wordbreak, isc_buffer_t *target); isc_result_t isc_base32hex_totext(isc_region_t *source, int wordlength, const char *wordbreak, isc_buffer_t *target); isc_result_t isc_base32hexnp_totext(isc_region_t *source, int wordlength, const char *wordbreak, isc_buffer_t *target); /*!< * \brief Convert data into base32 encoded text. * * Notes: *\li The base32 encoded text in 'target' will be divided into * words of at most 'wordlength' characters, separated by * the 'wordbreak' string. No parentheses will surround * the text. * * Requires: *\li 'source' is a region containing binary data *\li 'target' is a text buffer containing available space *\li 'wordbreak' points to a null-terminated string of * zero or more whitespace characters * * Ensures: *\li target will contain the base32 encoded version of the data * in source. The 'used' pointer in target will be advanced as * necessary. */ isc_result_t isc_base32_decodestring(const char *cstr, isc_buffer_t *target); isc_result_t isc_base32hex_decodestring(const char *cstr, isc_buffer_t *target); isc_result_t isc_base32hexnp_decodestring(const char *cstr, isc_buffer_t *target); /*!< * \brief Decode a null-terminated string in base32, base32hex, or * base32hex non-padded. * * Requires: *\li 'cstr' is non-null. *\li 'target' is a valid buffer. * * Returns: *\li #ISC_R_SUCCESS -- the entire decoded representation of 'cstring' * fit in 'target'. *\li #ISC_R_BADBASE32 -- 'cstr' is not a valid base32 encoding. * * Other error returns are any possible error code from: *\li isc_lex_create(), *\li isc_lex_openbuffer(), *\li isc_base32_tobuffer(). */ isc_result_t isc_base32_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length); isc_result_t isc_base32hex_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length); isc_result_t isc_base32hexnp_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length); /*!< * \brief Convert text encoded in base32, base32hex, or base32hex * non-padded from a lexer context into data. * * Requires: *\li 'lex' is a valid lexer context *\li 'target' is a buffer containing binary data *\li 'length' is an integer * * Ensures: *\li target will contain the data represented by the base32 encoded * string parsed by the lexer. No more than length bytes will be read, * if length is positive. The 'used' pointer in target will be * advanced as necessary. */ isc_result_t isc_base32_decoderegion(isc_region_t *source, isc_buffer_t *target); isc_result_t isc_base32hex_decoderegion(isc_region_t *source, isc_buffer_t *target); isc_result_t isc_base32hexnp_decoderegion(isc_region_t *source, isc_buffer_t *target); /*!< * \brief Decode a packed (no white space permitted) region in * base32, base32hex or base32hex non-padded. * * Requires: *\li 'source' is a valid region. *\li 'target' is a valid buffer. * * Returns: *\li #ISC_R_SUCCESS -- the entire decoded representation of 'cstring' * fit in 'target'. *\li #ISC_R_BADBASE32 -- 'source' is not a valid base32 encoding. */ ISC_LANG_ENDDECLS #endif /* ISC_BASE32_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/result.h0000644000470500017500000001133512664710322020610 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef ISC_RESULT_H #define ISC_RESULT_H 1 /*! \file isc/result.h */ #include #include #define ISC_R_SUCCESS 0 /*%< success */ #define ISC_R_NOMEMORY 1 /*%< out of memory */ #define ISC_R_TIMEDOUT 2 /*%< timed out */ #define ISC_R_NOTHREADS 3 /*%< no available threads */ #define ISC_R_ADDRNOTAVAIL 4 /*%< address not available */ #define ISC_R_ADDRINUSE 5 /*%< address in use */ #define ISC_R_NOPERM 6 /*%< permission denied */ #define ISC_R_NOCONN 7 /*%< no pending connections */ #define ISC_R_NETUNREACH 8 /*%< network unreachable */ #define ISC_R_HOSTUNREACH 9 /*%< host unreachable */ #define ISC_R_NETDOWN 10 /*%< network down */ #define ISC_R_HOSTDOWN 11 /*%< host down */ #define ISC_R_CONNREFUSED 12 /*%< connection refused */ #define ISC_R_NORESOURCES 13 /*%< not enough free resources */ #define ISC_R_EOF 14 /*%< end of file */ #define ISC_R_BOUND 15 /*%< socket already bound */ #define ISC_R_RELOAD 16 /*%< reload */ #define ISC_R_SUSPEND ISC_R_RELOAD /*%< alias of 'reload' */ #define ISC_R_LOCKBUSY 17 /*%< lock busy */ #define ISC_R_EXISTS 18 /*%< already exists */ #define ISC_R_NOSPACE 19 /*%< ran out of space */ #define ISC_R_CANCELED 20 /*%< operation canceled */ #define ISC_R_NOTBOUND 21 /*%< socket is not bound */ #define ISC_R_SHUTTINGDOWN 22 /*%< shutting down */ #define ISC_R_NOTFOUND 23 /*%< not found */ #define ISC_R_UNEXPECTEDEND 24 /*%< unexpected end of input */ #define ISC_R_FAILURE 25 /*%< generic failure */ #define ISC_R_IOERROR 26 /*%< I/O error */ #define ISC_R_NOTIMPLEMENTED 27 /*%< not implemented */ #define ISC_R_UNBALANCED 28 /*%< unbalanced parentheses */ #define ISC_R_NOMORE 29 /*%< no more */ #define ISC_R_INVALIDFILE 30 /*%< invalid file */ #define ISC_R_BADBASE64 31 /*%< bad base64 encoding */ #define ISC_R_UNEXPECTEDTOKEN 32 /*%< unexpected token */ #define ISC_R_QUOTA 33 /*%< quota reached */ #define ISC_R_UNEXPECTED 34 /*%< unexpected error */ #define ISC_R_ALREADYRUNNING 35 /*%< already running */ #define ISC_R_IGNORE 36 /*%< ignore */ #define ISC_R_MASKNONCONTIG 37 /*%< addr mask not contiguous */ #define ISC_R_FILENOTFOUND 38 /*%< file not found */ #define ISC_R_FILEEXISTS 39 /*%< file already exists */ #define ISC_R_NOTCONNECTED 40 /*%< socket is not connected */ #define ISC_R_RANGE 41 /*%< out of range */ #define ISC_R_NOENTROPY 42 /*%< out of entropy */ #define ISC_R_MULTICAST 43 /*%< invalid use of multicast */ #define ISC_R_NOTFILE 44 /*%< not a file */ #define ISC_R_NOTDIRECTORY 45 /*%< not a directory */ #define ISC_R_QUEUEFULL 46 /*%< queue is full */ #define ISC_R_FAMILYMISMATCH 47 /*%< address family mismatch */ #define ISC_R_FAMILYNOSUPPORT 48 /*%< AF not supported */ #define ISC_R_BADHEX 49 /*%< bad hex encoding */ #define ISC_R_TOOMANYOPENFILES 50 /*%< too many open files */ #define ISC_R_NOTBLOCKING 51 /*%< not blocking */ #define ISC_R_UNBALANCEDQUOTES 52 /*%< unbalanced quotes */ #define ISC_R_INPROGRESS 53 /*%< operation in progress */ #define ISC_R_CONNECTIONRESET 54 /*%< connection reset */ #define ISC_R_SOFTQUOTA 55 /*%< soft quota reached */ #define ISC_R_BADNUMBER 56 /*%< not a valid number */ #define ISC_R_DISABLED 57 /*%< disabled */ #define ISC_R_MAXSIZE 58 /*%< max size */ #define ISC_R_BADADDRESSFORM 59 /*%< invalid address format */ #define ISC_R_BADBASE32 60 /*%< bad base32 encoding */ #define ISC_R_UNSET 61 /*%< unset */ #define ISC_R_MULTIPLE 62 /*%< multiple */ /*% Not a result code: the number of results. */ #define ISC_R_NRESULTS 63 ISC_LANG_BEGINDECLS const char * isc_result_totext(isc_result_t); /*%< * Convert an isc_result_t into a string message describing the result. */ isc_result_t isc_result_register(unsigned int base, unsigned int nresults, const char **text, isc_msgcat_t *msgcat, int set); ISC_LANG_ENDDECLS #endif /* ISC_RESULT_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/resource.h0000644000470500017500000000650412664710322021123 0ustar lamontlamont/* * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: resource.h,v 1.13 2008/07/11 23:47:09 tbox Exp $ */ #ifndef ISC_RESOURCE_H #define ISC_RESOURCE_H 1 /*! \file isc/resource.h */ #include #include #define ISC_RESOURCE_UNLIMITED ((isc_resourcevalue_t)ISC_UINT64_MAX) ISC_LANG_BEGINDECLS isc_result_t isc_resource_setlimit(isc_resource_t resource, isc_resourcevalue_t value); /*%< * Set the maximum limit for a system resource. * * Notes: *\li If 'value' exceeds the maximum possible on the operating system, * it is silently limited to that maximum -- or to "infinity", if * the operating system has that concept. #ISC_RESOURCE_UNLIMITED * can be used to explicitly ask for the maximum. * * Requires: *\li 'resource' is a valid member of the isc_resource_t enumeration. * * Returns: *\li #ISC_R_SUCCESS Success. *\li #ISC_R_NOTIMPLEMENTED 'resource' is not a type known by the OS. *\li #ISC_R_NOPERM The calling process did not have adequate permission * to change the resource limit. */ isc_result_t isc_resource_getlimit(isc_resource_t resource, isc_resourcevalue_t *value); /*%< * Get the maximum limit for a system resource. * * Notes: *\li 'value' is set to the maximum limit. * *\li #ISC_RESOURCE_UNLIMITED is the maximum value of isc_resourcevalue_t. * *\li On many (all?) Unix systems, RLIM_INFINITY is a valid value that is * significantly less than #ISC_RESOURCE_UNLIMITED, but which in practice * behaves the same. * *\li The current ISC libdns configuration file parser assigns a value * of ISC_UINT32_MAX for a size_spec of "unlimited" and ISC_UNIT32_MAX - 1 * for "default", the latter of which is supposed to represent "the * limit that was in force when the server started". Since these are * valid values in the middle of the range of isc_resourcevalue_t, * there is the possibility for confusion over what exactly those * particular values are supposed to represent in a particular context -- * discrete integral values or generalized concepts. * * Requires: *\li 'resource' is a valid member of the isc_resource_t enumeration. * * Returns: *\li #ISC_R_SUCCESS Success. *\li #ISC_R_NOTIMPLEMENTED 'resource' is not a type known by the OS. */ isc_result_t isc_resource_getcurlimit(isc_resource_t resource, isc_resourcevalue_t *value); /*%< * Same as isc_resource_getlimit(), but returns the current (soft) limit. * * Returns: *\li #ISC_R_SUCCESS Success. *\li #ISC_R_NOTIMPLEMENTED 'resource' is not a type known by the OS. */ ISC_LANG_ENDDECLS #endif /* ISC_RESOURCE_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/sha1.h0000644000470500017500000000354312664710322020130 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef ISC_SHA1_H #define ISC_SHA1_H 1 /* $Id: sha1.h,v 1.19 2009/02/06 23:47:42 tbox Exp $ */ /* $NetBSD: sha1.h,v 1.2 1998/05/29 22:55:44 thorpej Exp $ */ /*! \file isc/sha1.h * \brief SHA-1 in C * \author By Steve Reid * \note 100% Public Domain */ #include #include #include #define ISC_SHA1_DIGESTLENGTH 20U #define ISC_SHA1_BLOCK_LENGTH 64U #ifdef ISC_PLATFORM_OPENSSLHASH #include typedef EVP_MD_CTX isc_sha1_t; #elif PKCS11CRYPTO #include typedef pk11_context_t isc_sha1_t; #else typedef struct { isc_uint32_t state[5]; isc_uint32_t count[2]; unsigned char buffer[ISC_SHA1_BLOCK_LENGTH]; } isc_sha1_t; #endif ISC_LANG_BEGINDECLS void isc_sha1_init(isc_sha1_t *ctx); void isc_sha1_invalidate(isc_sha1_t *ctx); void isc_sha1_update(isc_sha1_t *ctx, const unsigned char *data, unsigned int len); void isc_sha1_final(isc_sha1_t *ctx, unsigned char *digest); ISC_LANG_ENDDECLS #endif /* ISC_SHA1_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/sha2.h0000644000470500017500000001354112664710322020130 0ustar lamontlamont/* * Copyright (C) 2005-2007, 2009, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: sha2.h,v 1.12 2009/10/22 02:21:31 each Exp $ */ /* $FreeBSD: src/sys/crypto/sha2/sha2.h,v 1.1.2.1 2001/07/03 11:01:36 ume Exp $ */ /* $KAME: sha2.h,v 1.3 2001/03/12 08:27:48 itojun Exp $ */ /* * sha2.h * * Version 1.0.0beta1 * * Written by Aaron D. Gifford * * Copyright 2000 Aaron D. Gifford. 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. Neither the name of the copyright holder nor the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``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(S) OR CONTRIBUTOR(S) 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. * */ #ifndef ISC_SHA2_H #define ISC_SHA2_H #include #include #include /*** SHA-224/256/384/512 Various Length Definitions ***********************/ #define ISC_SHA224_BLOCK_LENGTH 64U #define ISC_SHA224_DIGESTLENGTH 28U #define ISC_SHA224_DIGESTSTRINGLENGTH (ISC_SHA224_DIGESTLENGTH * 2 + 1) #define ISC_SHA256_BLOCK_LENGTH 64U #define ISC_SHA256_DIGESTLENGTH 32U #define ISC_SHA256_DIGESTSTRINGLENGTH (ISC_SHA256_DIGESTLENGTH * 2 + 1) #define ISC_SHA384_BLOCK_LENGTH 128 #define ISC_SHA384_DIGESTLENGTH 48U #define ISC_SHA384_DIGESTSTRINGLENGTH (ISC_SHA384_DIGESTLENGTH * 2 + 1) #define ISC_SHA512_BLOCK_LENGTH 128U #define ISC_SHA512_DIGESTLENGTH 64U #define ISC_SHA512_DIGESTSTRINGLENGTH (ISC_SHA512_DIGESTLENGTH * 2 + 1) /*** SHA-256/384/512 Context Structures *******************************/ #ifdef ISC_PLATFORM_OPENSSLHASH #include typedef EVP_MD_CTX isc_sha256_t; typedef EVP_MD_CTX isc_sha512_t; #elif PKCS11CRYPTO #include typedef pk11_context_t isc_sha256_t; typedef pk11_context_t isc_sha512_t; #else /* * Keep buffer immediately after bitcount to preserve alignment. */ typedef struct { isc_uint32_t state[8]; isc_uint64_t bitcount; isc_uint8_t buffer[ISC_SHA256_BLOCK_LENGTH]; } isc_sha256_t; /* * Keep buffer immediately after bitcount to preserve alignment. */ typedef struct { isc_uint64_t state[8]; isc_uint64_t bitcount[2]; isc_uint8_t buffer[ISC_SHA512_BLOCK_LENGTH]; } isc_sha512_t; #endif typedef isc_sha256_t isc_sha224_t; typedef isc_sha512_t isc_sha384_t; ISC_LANG_BEGINDECLS /*** SHA-224/256/384/512 Function Prototypes ******************************/ void isc_sha224_init (isc_sha224_t *); void isc_sha224_invalidate (isc_sha224_t *); void isc_sha224_update (isc_sha224_t *, const isc_uint8_t *, size_t); void isc_sha224_final (isc_uint8_t[ISC_SHA224_DIGESTLENGTH], isc_sha224_t *); char *isc_sha224_end (isc_sha224_t *, char[ISC_SHA224_DIGESTSTRINGLENGTH]); char *isc_sha224_data (const isc_uint8_t *, size_t, char[ISC_SHA224_DIGESTSTRINGLENGTH]); void isc_sha256_init (isc_sha256_t *); void isc_sha256_invalidate (isc_sha256_t *); void isc_sha256_update (isc_sha256_t *, const isc_uint8_t *, size_t); void isc_sha256_final (isc_uint8_t[ISC_SHA256_DIGESTLENGTH], isc_sha256_t *); char *isc_sha256_end (isc_sha256_t *, char[ISC_SHA256_DIGESTSTRINGLENGTH]); char *isc_sha256_data (const isc_uint8_t *, size_t, char[ISC_SHA256_DIGESTSTRINGLENGTH]); void isc_sha384_init (isc_sha384_t *); void isc_sha384_invalidate (isc_sha384_t *); void isc_sha384_update (isc_sha384_t *, const isc_uint8_t *, size_t); void isc_sha384_final (isc_uint8_t[ISC_SHA384_DIGESTLENGTH], isc_sha384_t *); char *isc_sha384_end (isc_sha384_t *, char[ISC_SHA384_DIGESTSTRINGLENGTH]); char *isc_sha384_data (const isc_uint8_t *, size_t, char[ISC_SHA384_DIGESTSTRINGLENGTH]); void isc_sha512_init (isc_sha512_t *); void isc_sha512_invalidate (isc_sha512_t *); void isc_sha512_update (isc_sha512_t *, const isc_uint8_t *, size_t); void isc_sha512_final (isc_uint8_t[ISC_SHA512_DIGESTLENGTH], isc_sha512_t *); char *isc_sha512_end (isc_sha512_t *, char[ISC_SHA512_DIGESTSTRINGLENGTH]); char *isc_sha512_data (const isc_uint8_t *, size_t, char[ISC_SHA512_DIGESTSTRINGLENGTH]); ISC_LANG_ENDDECLS #endif /* ISC_SHA2_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/ratelimiter.h0000644000470500017500000000735112664710322021616 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ratelimiter.h,v 1.23 2009/01/18 23:48:14 tbox Exp $ */ #ifndef ISC_RATELIMITER_H #define ISC_RATELIMITER_H 1 /***** ***** Module Info *****/ /*! \file isc/ratelimiter.h * \brief A rate limiter is a mechanism for dispatching events at a limited * rate. This is intended to be used when sending zone maintenance * SOA queries, NOTIFY messages, etc. */ /*** *** Imports. ***/ #include #include ISC_LANG_BEGINDECLS /***** ***** Functions. *****/ isc_result_t isc_ratelimiter_create(isc_mem_t *mctx, isc_timermgr_t *timermgr, isc_task_t *task, isc_ratelimiter_t **ratelimiterp); /*%< * Create a rate limiter. The execution interval is initially undefined. */ isc_result_t isc_ratelimiter_setinterval(isc_ratelimiter_t *rl, isc_interval_t *interval); /*!< * Set the minimum interval between event executions. * The interval value is copied, so the caller need not preserve it. * * Requires: * '*interval' is a nonzero interval. */ void isc_ratelimiter_setpertic(isc_ratelimiter_t *rl, isc_uint32_t perint); /*%< * Set the number of events processed per interval timer tick. * If 'perint' is zero it is treated as 1. */ isc_result_t isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task, isc_event_t **eventp); /*%< * Queue an event for rate-limited execution. * * This is similar * to doing an isc_task_send() to the 'task', except that the * execution may be delayed to achieve the desired rate of * execution. * * '(*eventp)->ev_sender' is used to hold the task. The caller * must ensure that the task exists until the event is delivered. * * Requires: *\li An interval has been set by calling * isc_ratelimiter_setinterval(). * *\li 'task' to be non NULL. *\li '(*eventp)->ev_sender' to be NULL. */ isc_result_t isc_ratelimiter_dequeue(isc_ratelimiter_t *rl, isc_event_t *event); /* * Dequeue a event off the ratelimiter queue. * * Returns: * \li ISC_R_NOTFOUND if the event is no longer linked to the rate limiter. * \li ISC_R_SUCCESS */ void isc_ratelimiter_shutdown(isc_ratelimiter_t *ratelimiter); /*%< * Shut down a rate limiter. * * Ensures: *\li All events that have not yet been * dispatched to the task are dispatched immediately with * the #ISC_EVENTATTR_CANCELED bit set in ev_attributes. * *\li Further attempts to enqueue events will fail with * #ISC_R_SHUTTINGDOWN. * *\li The rate limiter is no longer attached to its task. */ void isc_ratelimiter_attach(isc_ratelimiter_t *source, isc_ratelimiter_t **target); /*%< * Attach to a rate limiter. */ void isc_ratelimiter_detach(isc_ratelimiter_t **ratelimiterp); /*%< * Detach from a rate limiter. */ isc_result_t isc_ratelimiter_stall(isc_ratelimiter_t *rl); /*%< * Stall event processing. */ isc_result_t isc_ratelimiter_release(isc_ratelimiter_t *rl); /*%< * Release a stalled rate limiter. */ ISC_LANG_ENDDECLS #endif /* ISC_RATELIMITER_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/region.h0000644000470500017500000000500312664710322020550 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: region.h,v 1.25 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_REGION_H #define ISC_REGION_H 1 /*! \file isc/region.h */ #include #include struct isc_region { unsigned char * base; unsigned int length; }; struct isc_textregion { char * base; unsigned int length; }; /* XXXDCL questionable ... bears discussion. we have been putting off * discussing the region api. */ struct isc_constregion { const void * base; unsigned int length; }; struct isc_consttextregion { const char * base; unsigned int length; }; /*@{*/ /*! * The region structure is not opaque, and is usually directly manipulated. * Some macros are defined below for convenience. */ #define isc_region_consume(r,l) \ do { \ isc_region_t *_r = (r); \ unsigned int _l = (l); \ INSIST(_r->length >= _l); \ _r->base += _l; \ _r->length -= _l; \ } while (0) #define isc_textregion_consume(r,l) \ do { \ isc_textregion_t *_r = (r); \ unsigned int _l = (l); \ INSIST(_r->length >= _l); \ _r->base += _l; \ _r->length -= _l; \ } while (0) #define isc_constregion_consume(r,l) \ do { \ isc_constregion_t *_r = (r); \ unsigned int _l = (l); \ INSIST(_r->length >= _l); \ _r->base += _l; \ _r->length -= _l; \ } while (0) /*@}*/ ISC_LANG_BEGINDECLS int isc_region_compare(isc_region_t *r1, isc_region_t *r2); /*%< * Compares the contents of two regions * * Requires: *\li 'r1' is a valid region *\li 'r2' is a valid region * * Returns: *\li < 0 if r1 is lexicographically less than r2 *\li = 0 if r1 is lexicographically identical to r2 *\li > 0 if r1 is lexicographically greater than r2 */ ISC_LANG_ENDDECLS #endif /* ISC_REGION_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/netaddr.h0000644000470500017500000001146512664710322020717 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: netaddr.h,v 1.37 2009/01/17 23:47:43 tbox Exp $ */ #ifndef ISC_NETADDR_H #define ISC_NETADDR_H 1 /*! \file isc/netaddr.h */ #include #include #include #ifdef ISC_PLATFORM_HAVESYSUNH #include #include #endif ISC_LANG_BEGINDECLS struct isc_netaddr { unsigned int family; union { struct in_addr in; struct in6_addr in6; #ifdef ISC_PLATFORM_HAVESYSUNH char un[sizeof(((struct sockaddr_un *)0)->sun_path)]; #endif } type; isc_uint32_t zone; }; isc_boolean_t isc_netaddr_equal(const isc_netaddr_t *a, const isc_netaddr_t *b); /*%< * Compare network addresses 'a' and 'b'. Return #ISC_TRUE if * they are equal, #ISC_FALSE if not. */ isc_boolean_t isc_netaddr_eqprefix(const isc_netaddr_t *a, const isc_netaddr_t *b, unsigned int prefixlen); /*%< * Compare the 'prefixlen' most significant bits of the network * addresses 'a' and 'b'. If 'b''s scope is zero then 'a''s scope is * ignored. Return #ISC_TRUE if they are equal, #ISC_FALSE if not. */ isc_result_t isc_netaddr_masktoprefixlen(const isc_netaddr_t *s, unsigned int *lenp); /*%< * Convert a netmask in 's' into a prefix length in '*lenp'. * The mask should consist of zero or more '1' bits in the most * most significant part of the address, followed by '0' bits. * If this is not the case, #ISC_R_MASKNONCONTIG is returned. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_MASKNONCONTIG */ isc_result_t isc_netaddr_totext(const isc_netaddr_t *netaddr, isc_buffer_t *target); /*%< * Append a text representation of 'sockaddr' to the buffer 'target'. * The text is NOT null terminated. Handles IPv4 and IPv6 addresses. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOSPACE The text or the null termination did not fit. *\li #ISC_R_FAILURE Unspecified failure */ void isc_netaddr_format(const isc_netaddr_t *na, char *array, unsigned int size); /*%< * Format a human-readable representation of the network address '*na' * into the character array 'array', which is of size 'size'. * The resulting string is guaranteed to be null-terminated. */ #define ISC_NETADDR_FORMATSIZE \ sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:XXX.XXX.XXX.XXX%SSSSSSSSSS") /*%< * Minimum size of array to pass to isc_netaddr_format(). */ void isc_netaddr_fromsockaddr(isc_netaddr_t *netaddr, const isc_sockaddr_t *source); void isc_netaddr_fromin(isc_netaddr_t *netaddr, const struct in_addr *ina); void isc_netaddr_fromin6(isc_netaddr_t *netaddr, const struct in6_addr *ina6); isc_result_t isc_netaddr_frompath(isc_netaddr_t *netaddr, const char *path); void isc_netaddr_setzone(isc_netaddr_t *netaddr, isc_uint32_t zone); isc_uint32_t isc_netaddr_getzone(const isc_netaddr_t *netaddr); void isc_netaddr_any(isc_netaddr_t *netaddr); /*%< * Return the IPv4 wildcard address. */ void isc_netaddr_any6(isc_netaddr_t *netaddr); /*%< * Return the IPv6 wildcard address. */ isc_boolean_t isc_netaddr_ismulticast(isc_netaddr_t *na); /*%< * Returns ISC_TRUE if the address is a multicast address. */ isc_boolean_t isc_netaddr_isexperimental(isc_netaddr_t *na); /*%< * Returns ISC_TRUE if the address is a experimental (CLASS E) address. */ isc_boolean_t isc_netaddr_islinklocal(isc_netaddr_t *na); /*%< * Returns #ISC_TRUE if the address is a link local address. */ isc_boolean_t isc_netaddr_issitelocal(isc_netaddr_t *na); /*%< * Returns #ISC_TRUE if the address is a site local address. */ void isc_netaddr_fromv4mapped(isc_netaddr_t *t, const isc_netaddr_t *s); /*%< * Convert an IPv6 v4mapped address into an IPv4 address. */ isc_result_t isc_netaddr_prefixok(const isc_netaddr_t *na, unsigned int prefixlen); /* * Test whether the netaddr 'na' and 'prefixlen' are consistant. * e.g. prefixlen within range. * na does not have bits set which are not covered by the prefixlen. * * Returns: * ISC_R_SUCCESS * ISC_R_RANGE prefixlen out of range * ISC_R_NOTIMPLEMENTED unsupported family * ISC_R_FAILURE extra bits. */ ISC_LANG_ENDDECLS #endif /* ISC_NETADDR_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/hex.h0000644000470500017500000000553712664710322020065 0ustar lamontlamont/* * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: hex.h,v 1.13 2008/09/25 04:02:39 tbox Exp $ */ #ifndef ISC_HEX_H #define ISC_HEX_H 1 /*! \file isc/hex.h */ #include #include ISC_LANG_BEGINDECLS /*** *** Functions ***/ isc_result_t isc_hex_totext(isc_region_t *source, int wordlength, const char *wordbreak, isc_buffer_t *target); /*!< * \brief Convert data into hex encoded text. * * Notes: *\li The hex encoded text in 'target' will be divided into * words of at most 'wordlength' characters, separated by * the 'wordbreak' string. No parentheses will surround * the text. * * Requires: *\li 'source' is a region containing binary data *\li 'target' is a text buffer containing available space *\li 'wordbreak' points to a null-terminated string of * zero or more whitespace characters * * Ensures: *\li target will contain the hex encoded version of the data * in source. The 'used' pointer in target will be advanced as * necessary. */ isc_result_t isc_hex_decodestring(const char *cstr, isc_buffer_t *target); /*!< * \brief Decode a null-terminated hex string. * * Requires: *\li 'cstr' is non-null. *\li 'target' is a valid buffer. * * Returns: *\li #ISC_R_SUCCESS -- the entire decoded representation of 'cstring' * fit in 'target'. *\li #ISC_R_BADHEX -- 'cstr' is not a valid hex encoding. * * Other error returns are any possible error code from: * isc_lex_create(), * isc_lex_openbuffer(), * isc_hex_tobuffer(). */ isc_result_t isc_hex_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length); /*!< * \brief Convert hex encoded text from a lexer context into data. * * Requires: *\li 'lex' is a valid lexer context *\li 'target' is a buffer containing binary data *\li 'length' is an integer * * Ensures: *\li target will contain the data represented by the hex encoded * string parsed by the lexer. No more than length bytes will be read, * if length is positive. The 'used' pointer in target will be * advanced as necessary. */ ISC_LANG_ENDDECLS #endif /* ISC_HEX_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/version.h0000644000470500017500000000226712664710322020763 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: version.h,v 1.9 2007/06/19 23:47:18 tbox Exp $ */ /*! \file isc/version.h */ #include LIBISC_EXTERNAL_DATA extern const char isc_version[]; LIBISC_EXTERNAL_DATA extern const unsigned int isc_libinterface; LIBISC_EXTERNAL_DATA extern const unsigned int isc_librevision; LIBISC_EXTERNAL_DATA extern const unsigned int isc_libage; bind9-9.10.3.dfsg.P4/lib/isc/include/isc/hmacsha.h0000644000470500017500000001123612664710322020676 0ustar lamontlamont/* * Copyright (C) 2005-2007, 2009, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: hmacsha.h,v 1.9 2009/02/06 23:47:42 tbox Exp $ */ /*! \file isc/hmacsha.h * This is the header file for the HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, * HMAC-SHA334 and HMAC-SHA512 hash algorithm described in RFC 2104. */ #ifndef ISC_HMACSHA_H #define ISC_HMACSHA_H 1 #include #include #include #include #include #define ISC_HMACSHA1_KEYLENGTH ISC_SHA1_BLOCK_LENGTH #define ISC_HMACSHA224_KEYLENGTH ISC_SHA224_BLOCK_LENGTH #define ISC_HMACSHA256_KEYLENGTH ISC_SHA256_BLOCK_LENGTH #define ISC_HMACSHA384_KEYLENGTH ISC_SHA384_BLOCK_LENGTH #define ISC_HMACSHA512_KEYLENGTH ISC_SHA512_BLOCK_LENGTH #ifdef ISC_PLATFORM_OPENSSLHASH #include typedef HMAC_CTX isc_hmacsha1_t; typedef HMAC_CTX isc_hmacsha224_t; typedef HMAC_CTX isc_hmacsha256_t; typedef HMAC_CTX isc_hmacsha384_t; typedef HMAC_CTX isc_hmacsha512_t; #elif PKCS11CRYPTO #include typedef pk11_context_t isc_hmacsha1_t; typedef pk11_context_t isc_hmacsha224_t; typedef pk11_context_t isc_hmacsha256_t; typedef pk11_context_t isc_hmacsha384_t; typedef pk11_context_t isc_hmacsha512_t; #else typedef struct { isc_sha1_t sha1ctx; unsigned char key[ISC_HMACSHA1_KEYLENGTH]; } isc_hmacsha1_t; typedef struct { isc_sha224_t sha224ctx; unsigned char key[ISC_HMACSHA224_KEYLENGTH]; } isc_hmacsha224_t; typedef struct { isc_sha256_t sha256ctx; unsigned char key[ISC_HMACSHA256_KEYLENGTH]; } isc_hmacsha256_t; typedef struct { isc_sha384_t sha384ctx; unsigned char key[ISC_HMACSHA384_KEYLENGTH]; } isc_hmacsha384_t; typedef struct { isc_sha512_t sha512ctx; unsigned char key[ISC_HMACSHA512_KEYLENGTH]; } isc_hmacsha512_t; #endif ISC_LANG_BEGINDECLS void isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key, unsigned int len); void isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx); void isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf, unsigned int len); void isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len); isc_boolean_t isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len); void isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key, unsigned int len); void isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx); void isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf, unsigned int len); void isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len); isc_boolean_t isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len); void isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key, unsigned int len); void isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx); void isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf, unsigned int len); void isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len); isc_boolean_t isc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len); void isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key, unsigned int len); void isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx); void isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf, unsigned int len); void isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len); isc_boolean_t isc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len); void isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key, unsigned int len); void isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx); void isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf, unsigned int len); void isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len); isc_boolean_t isc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len); ISC_LANG_ENDDECLS #endif /* ISC_HMACSHA_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/util.h0000644000470500017500000001743012664710322020251 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2010-2012, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef ISC_UTIL_H #define ISC_UTIL_H 1 /*! \file isc/util.h * NOTE: * * This file is not to be included from any (or other) library * files. * * \brief * Including this file puts several macros in your name space that are * not protected (as all the other ISC functions/macros do) by prepending * ISC_ or isc_ to the name. */ /*** *** General Macros. ***/ /*% * Use this to hide unused function arguments. * \code * int * foo(char *bar) * { * UNUSED(bar); * } * \endcode */ #define UNUSED(x) (void)(x) /*% * The opposite: silent warnings about stored values which are never read. */ #define POST(x) (void)(x) #define ISC_MAX(a, b) ((a) > (b) ? (a) : (b)) #define ISC_MIN(a, b) ((a) < (b) ? (a) : (b)) #define ISC_CLAMP(v, x, y) ((v) < (x) ? (x) : ((v) > (y) ? (y) : (v))) /*% * Use this to remove the const qualifier of a variable to assign it to * a non-const variable or pass it as a non-const function argument ... * but only when you are sure it won't then be changed! * This is necessary to sometimes shut up some compilers * (as with gcc -Wcast-qual) when there is just no other good way to avoid the * situation. */ #define DE_CONST(konst, var) \ do { \ union { const void *k; void *v; } _u; \ _u.k = konst; \ var = _u.v; \ } while (0) /*% * Use this in translation units that would otherwise be empty, to * suppress compiler warnings. */ #define EMPTY_TRANSLATION_UNIT static void isc__empty(void) { isc__empty(); } /*% * We use macros instead of calling the routines directly because * the capital letters make the locking stand out. * We RUNTIME_CHECK for success since in general there's no way * for us to continue if they fail. */ #ifdef ISC_UTIL_TRACEON #define ISC_UTIL_TRACE(a) a #include /* Required for fprintf/stderr when tracing. */ #include /* Required for isc_msgcat when tracing. */ #else #define ISC_UTIL_TRACE(a) #endif #include /* Contractual promise. */ #define LOCK(lp) do { \ ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ ISC_MSG_LOCKING, "LOCKING"), \ (lp), __FILE__, __LINE__)); \ RUNTIME_CHECK(isc_mutex_lock((lp)) == ISC_R_SUCCESS); \ ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ ISC_MSG_LOCKED, "LOCKED"), \ (lp), __FILE__, __LINE__)); \ } while (0) #define UNLOCK(lp) do { \ RUNTIME_CHECK(isc_mutex_unlock((lp)) == ISC_R_SUCCESS); \ ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ ISC_MSG_UNLOCKED, "UNLOCKED"), \ (lp), __FILE__, __LINE__)); \ } while (0) #define ISLOCKED(lp) (1) #define DESTROYLOCK(lp) \ RUNTIME_CHECK(isc_mutex_destroy((lp)) == ISC_R_SUCCESS) #define BROADCAST(cvp) do { \ ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ ISC_MSG_BROADCAST, "BROADCAST"),\ (cvp), __FILE__, __LINE__)); \ RUNTIME_CHECK(isc_condition_broadcast((cvp)) == ISC_R_SUCCESS); \ } while (0) #define SIGNAL(cvp) do { \ ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ ISC_MSG_SIGNAL, "SIGNAL"), \ (cvp), __FILE__, __LINE__)); \ RUNTIME_CHECK(isc_condition_signal((cvp)) == ISC_R_SUCCESS); \ } while (0) #define WAIT(cvp, lp) do { \ ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %p %s %d\n", \ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ ISC_MSG_UTILWAIT, "WAIT"), \ (cvp), \ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ ISC_MSG_LOCK, "LOCK"), \ (lp), __FILE__, __LINE__)); \ RUNTIME_CHECK(isc_condition_wait((cvp), (lp)) == ISC_R_SUCCESS); \ ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %p %s %d\n", \ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ ISC_MSG_WAITED, "WAITED"), \ (cvp), \ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ ISC_MSG_LOCKED, "LOCKED"), \ (lp), __FILE__, __LINE__)); \ } while (0) /* * isc_condition_waituntil can return ISC_R_TIMEDOUT, so we * don't RUNTIME_CHECK the result. * * XXX Also, can't really debug this then... */ #define WAITUNTIL(cvp, lp, tp) \ isc_condition_waituntil((cvp), (lp), (tp)) #define RWLOCK(lp, t) do { \ ISC_UTIL_TRACE(fprintf(stderr, "%s %p, %d %s %d\n", \ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ ISC_MSG_RWLOCK, "RWLOCK"), \ (lp), (t), __FILE__, __LINE__)); \ RUNTIME_CHECK(isc_rwlock_lock((lp), (t)) == ISC_R_SUCCESS); \ ISC_UTIL_TRACE(fprintf(stderr, "%s %p, %d %s %d\n", \ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ ISC_MSG_RWLOCKED, "RWLOCKED"), \ (lp), (t), __FILE__, __LINE__)); \ } while (0) #define RWUNLOCK(lp, t) do { \ ISC_UTIL_TRACE(fprintf(stderr, "%s %p, %d %s %d\n", \ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \ ISC_MSG_RWUNLOCK, "RWUNLOCK"), \ (lp), (t), __FILE__, __LINE__)); \ RUNTIME_CHECK(isc_rwlock_unlock((lp), (t)) == ISC_R_SUCCESS); \ } while (0) #define DESTROYMUTEXBLOCK(bp, n) \ RUNTIME_CHECK(isc_mutexblock_destroy((bp), (n)) == ISC_R_SUCCESS) /* * List Macros. */ #include /* Contractual promise. */ #define LIST(type) ISC_LIST(type) #define INIT_LIST(type) ISC_LIST_INIT(type) #define LINK(type) ISC_LINK(type) #define INIT_LINK(elt, link) ISC_LINK_INIT(elt, link) #define HEAD(list) ISC_LIST_HEAD(list) #define TAIL(list) ISC_LIST_TAIL(list) #define EMPTY(list) ISC_LIST_EMPTY(list) #define PREV(elt, link) ISC_LIST_PREV(elt, link) #define NEXT(elt, link) ISC_LIST_NEXT(elt, link) #define APPEND(list, elt, link) ISC_LIST_APPEND(list, elt, link) #define PREPEND(list, elt, link) ISC_LIST_PREPEND(list, elt, link) #define UNLINK(list, elt, link) ISC_LIST_UNLINK(list, elt, link) #define ENQUEUE(list, elt, link) ISC_LIST_APPEND(list, elt, link) #define DEQUEUE(list, elt, link) ISC_LIST_UNLINK(list, elt, link) #define INSERTBEFORE(li, b, e, ln) ISC_LIST_INSERTBEFORE(li, b, e, ln) #define INSERTAFTER(li, a, e, ln) ISC_LIST_INSERTAFTER(li, a, e, ln) #define APPENDLIST(list1, list2, link) ISC_LIST_APPENDLIST(list1, list2, link) /* * Assertions */ #include /* Contractual promise. */ /*% Require Assertion */ #define REQUIRE(e) ISC_REQUIRE(e) /*% Ensure Assertion */ #define ENSURE(e) ISC_ENSURE(e) /*% Insist Assertion */ #define INSIST(e) ISC_INSIST(e) /*% Invariant Assertion */ #define INVARIANT(e) ISC_INVARIANT(e) /* * Errors */ #include /* Contractual promise. */ /*% Unexpected Error */ #define UNEXPECTED_ERROR isc_error_unexpected /*% Fatal Error */ #define FATAL_ERROR isc_error_fatal /*% Runtime Check */ #define RUNTIME_CHECK(cond) ISC_ERROR_RUNTIMECHECK(cond) /*% * Time */ #define TIME_NOW(tp) RUNTIME_CHECK(isc_time_now((tp)) == ISC_R_SUCCESS) #endif /* ISC_UTIL_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/backtrace.h0000644000470500017500000001033012664710322021203 0ustar lamontlamont/* * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: backtrace.h,v 1.2 2009/09/01 18:40:25 jinmei Exp $ */ /*! \file isc/backtrace.h * \brief provide a back trace of the running process to help debug problems. * * This module tries to get a back trace of the process using some platform * dependent way when available. It also manages an internal symbol table * that maps function addresses used in the process to their textual symbols. * This module is expected to be used to help debug when some fatal error * happens. * * IMPORTANT NOTE: since the (major) intended use case of this module is * dumping a back trace on a fatal error, normally followed by self termination, * functions defined in this module generally doesn't employ assertion checks * (if it did, a program bug could cause infinite recursive calls to a * backtrace function). These functions still perform minimal checks and return * ISC_R_FAILURE if they detect an error, but the caller should therefore be * very careful about the use of these functions, and generally discouraged to * use them except in an exit path. The exception is * isc_backtrace_getsymbolfromindex(), which is expected to be used in a * non-error-handling context and validates arguments with assertion checks. */ #ifndef ISC_BACKTRACE_H #define ISC_BACKTRACE_H 1 /*** *** Imports ***/ #include /*** *** Types ***/ struct isc_backtrace_symmap { void *addr; const char *symbol; }; extern const int isc__backtrace_nsymbols; extern const isc_backtrace_symmap_t isc__backtrace_symtable[]; /*** *** Functions ***/ ISC_LANG_BEGINDECLS isc_result_t isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes); /*%< * Get a back trace of the running process above this function itself. On * success, addrs[i] will store the address of the call point of the i-th * stack frame (addrs[0] is the caller of this function). *nframes will store * the total number of frames. * * Requires (note that these are not ensured by assertion checks, see above): * *\li 'addrs' is a valid array containing at least 'maxaddrs' void * entries. * *\li 'nframes' must be non NULL. * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_FAILURE *\li #ISC_R_NOTFOUND *\li #ISC_R_NOTIMPLEMENTED */ isc_result_t isc_backtrace_getsymbolfromindex(int index, const void **addrp, const char **symbolp); /*%< * Returns the content of the internal symbol table of the given index. * On success, *addrsp and *symbolp point to the address and the symbol of * the 'index'th entry of the table, respectively. If 'index' is not in the * range of the symbol table, ISC_R_RANGE will be returned. * * Requires * *\li 'addrp' must be non NULL && '*addrp' == NULL. * *\li 'symbolp' must be non NULL && '*symbolp' == NULL. * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_RANGE */ isc_result_t isc_backtrace_getsymbol(const void *addr, const char **symbolp, unsigned long *offsetp); /*%< * Searches the internal symbol table for the symbol that most matches the * given 'addr'. On success, '*symbolp' will point to the name of function * to which the address 'addr' belong, and '*offsetp' will store the offset * from the function's entry address to 'addr'. * * Requires (note that these are not ensured by assertion checks, see above): * *\li 'symbolp' must be non NULL && '*symbolp' == NULL. * *\li 'offsetp' must be non NULL. * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_FAILURE *\li #ISC_R_NOTFOUND */ ISC_LANG_ENDDECLS #endif /* ISC_BACKTRACE_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/os.h0000644000470500017500000000224712664710322017715 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: os.h,v 1.12 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_OS_H #define ISC_OS_H 1 /*! \file isc/os.h */ #include ISC_LANG_BEGINDECLS unsigned int isc_os_ncpus(void); /*%< * Return the number of CPUs available on the system, or 1 if this cannot * be determined. */ ISC_LANG_ENDDECLS #endif /* ISC_OS_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/hash.h0000644000470500017500000001450012664710322020212 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: hash.h,v 1.12 2009/01/17 23:47:43 tbox Exp $ */ #ifndef ISC_HASH_H #define ISC_HASH_H 1 #include /***** ***** Module Info *****/ /*! \file isc/hash.h * * \brief The hash API * provides an unpredictable hash value for variable length data. * A hash object contains a random vector (which is hidden from clients * of this API) to make the actual hash value unpredictable. * * The algorithm used in the API guarantees the probability of hash * collision; in the current implementation, as long as the values stored * in the random vector are unpredictable, the probability of hash * collision between arbitrary two different values is at most 1/2^16. * * Although the API is generic about the hash keys, it mainly expects * DNS names (and sometimes IPv4/v6 addresses) as inputs. It has an * upper limit of the input length, and may run slow to calculate the * hash values for large inputs. * * This API is designed to be general so that it can provide multiple * different hash contexts that have different random vectors. However, * it should be typical to have a single context for an entire system. * To support such cases, the API also provides a single-context mode. * * \li MP: * The hash object is almost read-only. Once the internal random vector * is initialized, no write operation will occur, and there will be no * need to lock the object to calculate actual hash values. * * \li Reliability: * In some cases this module uses low-level data copy to initialize the * random vector. Errors in this part are likely to crash the server or * corrupt memory. * * \li Resources: * A buffer, used as a random vector for calculating hash values. * * \li Security: * This module intends to provide unpredictable hash values in * adversarial environments in order to avoid denial of service attacks * to hash buckets. * Its unpredictability relies on the quality of entropy to build the * random vector. * * \li Standards: * None. */ /*** *** Imports ***/ #include /*** *** Functions ***/ ISC_LANG_BEGINDECLS isc_result_t isc_hash_ctxcreate(isc_mem_t *mctx, isc_entropy_t *entropy, size_t limit, isc_hash_t **hctx); isc_result_t isc_hash_create(isc_mem_t *mctx, isc_entropy_t *entropy, size_t limit); /*!< * \brief Create a new hash object. * * isc_hash_ctxcreate() creates a different object. * * isc_hash_create() creates a module-internal object to support the * single-context mode. It should be called only once. * * 'entropy' must be NULL or a valid entropy object. If 'entropy' is NULL, * pseudo random values will be used to build the random vector, which may * weaken security. * * 'limit' specifies the maximum number of hash keys. If it is too large, * these functions may fail. */ void isc_hash_ctxattach(isc_hash_t *hctx, isc_hash_t **hctxp); /*!< * \brief Attach to a hash object. * * This function is only necessary for the multiple-context mode. */ void isc_hash_ctxdetach(isc_hash_t **hctxp); /*!< * \brief Detach from a hash object. * * This function is for the multiple-context mode, and takes a valid * hash object as an argument. */ void isc_hash_destroy(void); /*!< * \brief This function is for the single-context mode, and is expected to be used * as a counterpart of isc_hash_create(). * * A valid module-internal hash object must have been created, and this * function should be called only once. */ /*@{*/ void isc_hash_ctxinit(isc_hash_t *hctx); void isc_hash_init(void); /*!< * \brief Initialize a hash object. * * It fills in the random vector with a proper * source of entropy, which is typically from the entropy object specified * at the creation. Thus, it is desirable to call these functions after * initializing the entropy object with some good entropy sources. * * These functions should be called before the first hash calculation. * * isc_hash_ctxinit() is for the multiple-context mode, and takes a valid hash * object as an argument. * * isc_hash_init() is for the single-context mode. A valid module-internal * hash object must have been created, and this function should be called only * once. */ /*@}*/ /*@{*/ unsigned int isc_hash_ctxcalc(isc_hash_t *hctx, const unsigned char *key, unsigned int keylen, isc_boolean_t case_sensitive); unsigned int isc_hash_calc(const unsigned char *key, unsigned int keylen, isc_boolean_t case_sensitive); /*!< * \brief Calculate a hash value. * * isc_hash_ctxinit() is for the multiple-context mode, and takes a valid hash * object as an argument. * * isc_hash_init() is for the single-context mode. A valid module-internal * hash object must have been created. * * 'key' is the hash key, which is a variable length buffer. * * 'keylen' specifies the key length, which must not be larger than the limit * specified for the corresponding hash object. * * 'case_sensitive' specifies whether the hash key should be treated as * case_sensitive values. It should typically be ISC_FALSE if the hash key * is a DNS name. */ /*@}*/ void isc__hash_setvec(const isc_uint16_t *vec); /*!< * \brief Set the contents of the random vector used in hashing. * * WARNING: This function is meant to be used only in testing code. It * must not be used anywhere in normally running code. * * The hash context must have been created beforehand, otherwise this * function is a nop. * * 'vec' is not documented here on purpose. You should know what you are * doing before using this function. */ ISC_LANG_ENDDECLS #endif /* ISC_HASH_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/sockaddr.h0000644000470500017500000001472612664710322021073 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: sockaddr.h,v 1.57 2009/01/18 23:48:14 tbox Exp $ */ #ifndef ISC_SOCKADDR_H #define ISC_SOCKADDR_H 1 /*! \file isc/sockaddr.h */ #include #include #include #ifdef ISC_PLATFORM_HAVESYSUNH #include #endif struct isc_sockaddr { union { struct sockaddr sa; struct sockaddr_in sin; struct sockaddr_in6 sin6; struct sockaddr_storage ss; #ifdef ISC_PLATFORM_HAVESYSUNH struct sockaddr_un sunix; #endif } type; unsigned int length; /* XXXRTH beginning? */ ISC_LINK(struct isc_sockaddr) link; }; typedef ISC_LIST(struct isc_sockaddr) isc_sockaddrlist_t; #define ISC_SOCKADDR_CMPADDR 0x0001 /*%< compare the address * sin_addr/sin6_addr */ #define ISC_SOCKADDR_CMPPORT 0x0002 /*%< compare the port * sin_port/sin6_port */ #define ISC_SOCKADDR_CMPSCOPE 0x0004 /*%< compare the scope * sin6_scope */ #define ISC_SOCKADDR_CMPSCOPEZERO 0x0008 /*%< when comparing scopes * zero scopes always match */ ISC_LANG_BEGINDECLS isc_boolean_t isc_sockaddr_compare(const isc_sockaddr_t *a, const isc_sockaddr_t *b, unsigned int flags); /*%< * Compare the elements of the two address ('a' and 'b') as specified * by 'flags' and report if they are equal or not. * * 'flags' is set from ISC_SOCKADDR_CMP*. */ isc_boolean_t isc_sockaddr_equal(const isc_sockaddr_t *a, const isc_sockaddr_t *b); /*%< * Return ISC_TRUE iff the socket addresses 'a' and 'b' are equal. */ isc_boolean_t isc_sockaddr_eqaddr(const isc_sockaddr_t *a, const isc_sockaddr_t *b); /*%< * Return ISC_TRUE iff the address parts of the socket addresses * 'a' and 'b' are equal, ignoring the ports. */ isc_boolean_t isc_sockaddr_eqaddrprefix(const isc_sockaddr_t *a, const isc_sockaddr_t *b, unsigned int prefixlen); /*%< * Return ISC_TRUE iff the most significant 'prefixlen' bits of the * socket addresses 'a' and 'b' are equal, ignoring the ports. * If 'b''s scope is zero then 'a''s scope will be ignored. */ unsigned int isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, isc_boolean_t address_only); /*%< * Return a hash value for the socket address 'sockaddr'. If 'address_only' * is ISC_TRUE, the hash value will not depend on the port. * * IPv6 addresses containing mapped IPv4 addresses generate the same hash * value as the equivalent IPv4 address. */ void isc_sockaddr_any(isc_sockaddr_t *sockaddr); /*%< * Return the IPv4 wildcard address. */ void isc_sockaddr_any6(isc_sockaddr_t *sockaddr); /*%< * Return the IPv6 wildcard address. */ void isc_sockaddr_anyofpf(isc_sockaddr_t *sockaddr, int family); /*%< * Set '*sockaddr' to the wildcard address of protocol family * 'family'. * * Requires: * \li 'family' is AF_INET or AF_INET6. */ void isc_sockaddr_fromin(isc_sockaddr_t *sockaddr, const struct in_addr *ina, in_port_t port); /*%< * Construct an isc_sockaddr_t from an IPv4 address and port. */ void isc_sockaddr_fromin6(isc_sockaddr_t *sockaddr, const struct in6_addr *ina6, in_port_t port); /*%< * Construct an isc_sockaddr_t from an IPv6 address and port. */ void isc_sockaddr_v6fromin(isc_sockaddr_t *sockaddr, const struct in_addr *ina, in_port_t port); /*%< * Construct an IPv6 isc_sockaddr_t representing a mapped IPv4 address. */ void isc_sockaddr_fromnetaddr(isc_sockaddr_t *sockaddr, const isc_netaddr_t *na, in_port_t port); /*%< * Construct an isc_sockaddr_t from an isc_netaddr_t and port. */ int isc_sockaddr_pf(const isc_sockaddr_t *sockaddr); /*%< * Get the protocol family of 'sockaddr'. * * Requires: * *\li 'sockaddr' is a valid sockaddr with an address family of AF_INET * or AF_INET6. * * Returns: * *\li The protocol family of 'sockaddr', e.g. PF_INET or PF_INET6. */ void isc_sockaddr_setport(isc_sockaddr_t *sockaddr, in_port_t port); /*%< * Set the port of 'sockaddr' to 'port'. */ in_port_t isc_sockaddr_getport(const isc_sockaddr_t *sockaddr); /*%< * Get the port stored in 'sockaddr'. */ isc_result_t isc_sockaddr_totext(const isc_sockaddr_t *sockaddr, isc_buffer_t *target); /*%< * Append a text representation of 'sockaddr' to the buffer 'target'. * The text will include both the IP address (v4 or v6) and the port. * The text is null terminated, but the terminating null is not * part of the buffer's used region. * * Returns: * \li ISC_R_SUCCESS * \li ISC_R_NOSPACE The text or the null termination did not fit. */ void isc_sockaddr_format(const isc_sockaddr_t *sa, char *array, unsigned int size); /*%< * Format a human-readable representation of the socket address '*sa' * into the character array 'array', which is of size 'size'. * The resulting string is guaranteed to be null-terminated. */ isc_boolean_t isc_sockaddr_ismulticast(const isc_sockaddr_t *sa); /*%< * Returns #ISC_TRUE if the address is a multicast address. */ isc_boolean_t isc_sockaddr_isexperimental(const isc_sockaddr_t *sa); /* * Returns ISC_TRUE if the address is a experimental (CLASS E) address. */ isc_boolean_t isc_sockaddr_islinklocal(const isc_sockaddr_t *sa); /*%< * Returns ISC_TRUE if the address is a link local address. */ isc_boolean_t isc_sockaddr_issitelocal(const isc_sockaddr_t *sa); /*%< * Returns ISC_TRUE if the address is a sitelocal address. */ isc_result_t isc_sockaddr_frompath(isc_sockaddr_t *sockaddr, const char *path); /* * Create a UNIX domain sockaddr that refers to path. * * Returns: * \li ISC_R_NOSPACE * \li ISC_R_NOTIMPLEMENTED * \li ISC_R_SUCCESS */ #define ISC_SOCKADDR_FORMATSIZE \ sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:XXX.XXX.XXX.XXX%SSSSSSSSSS#YYYYY") /*%< * Minimum size of array to pass to isc_sockaddr_format(). */ ISC_LANG_ENDDECLS #endif /* ISC_SOCKADDR_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/msgcat.h0000644000470500017500000000627012664710322020552 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: msgcat.h,v 1.13 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_MSGCAT_H #define ISC_MSGCAT_H 1 /***** ***** Module Info *****/ /*! \file isc/msgcat.h * \brief The ISC Message Catalog * aids internationalization of applications by allowing * messages to be retrieved from locale-specific files instead of * hardwiring them into the application. This allows translations of * messages appropriate to the locale to be supplied without recompiling * the application. * * Notes: *\li It's very important that message catalogs work, even if only the * default_text can be used. * * MP: *\li The caller must ensure appropriate synchronization of * isc_msgcat_open() and isc_msgcat_close(). isc_msgcat_get() * ensures appropriate synchronization. * * Reliability: *\li No anticipated impact. * * Resources: *\li TBS * * \li Security: * No anticipated impact. * * \li Standards: * None. */ /***** ***** Imports *****/ #include #include ISC_LANG_BEGINDECLS /***** ***** Methods *****/ void isc_msgcat_open(const char *name, isc_msgcat_t **msgcatp); /*%< * Open a message catalog. * * Notes: * *\li If memory cannot be allocated or other failures occur, *msgcatp * will be set to NULL. If a NULL msgcat is given to isc_msgcat_get(), * the default_text will be returned, ensuring that some message text * will be available, no matter what's going wrong. * * Requires: * *\li 'name' is a valid string. * *\li msgcatp != NULL && *msgcatp == NULL */ void isc_msgcat_close(isc_msgcat_t **msgcatp); /*%< * Close a message catalog. * * Notes: * *\li Any string pointers returned by prior calls to isc_msgcat_get() are * invalid after isc_msgcat_close() has been called and must not be * used. * * Requires: * *\li *msgcatp is a valid message catalog or is NULL. * * Ensures: * *\li All resources associated with the message catalog are released. * *\li *msgcatp == NULL */ const char * isc_msgcat_get(isc_msgcat_t *msgcat, int set, int message, const char *default_text); /*%< * Get message 'message' from message set 'set' in 'msgcat'. If it * is not available, use 'default_text'. * * Requires: * *\li 'msgcat' is a valid message catalog or is NULL. * *\li set > 0 * *\li message > 0 * *\li 'default_text' is a valid string. */ ISC_LANG_ENDDECLS #endif /* ISC_MSGCAT_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/xml.h0000644000470500017500000000302412664710322020066 0ustar lamontlamont/* * Copyright (C) 2006, 2007 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: xml.h,v 1.4 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_XML_H #define ISC_XML_H 1 /* * This file is here mostly to make it easy to add additional libxml header * files as needed across all the users of this file. Rather than place * these libxml includes in each file, one include makes it easy to handle * the ifdef as well as adding the ability to add additional functions * which may be useful. */ #ifdef HAVE_LIBXML2 #include #include #endif #define ISC_XMLCHAR (const xmlChar *) #define ISC_XML_RENDERCONFIG 0x00000001 /* render config data */ #define ISC_XML_RENDERSTATS 0x00000002 /* render stats */ #define ISC_XML_RENDERALL 0x000000ff /* render everything */ #endif /* ISC_XML_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/socket.h0000644000470500017500000011015412664710322020561 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef ISC_SOCKET_H #define ISC_SOCKET_H 1 /***** ***** Module Info *****/ /*! \file isc/socket.h * \brief Provides TCP and UDP sockets for network I/O. The sockets are event * sources in the task system. * * When I/O completes, a completion event for the socket is posted to the * event queue of the task which requested the I/O. * * \li MP: * The module ensures appropriate synchronization of data structures it * creates and manipulates. * Clients of this module must not be holding a socket's task's lock when * making a call that affects that socket. Failure to follow this rule * can result in deadlock. * The caller must ensure that isc_socketmgr_destroy() is called only * once for a given manager. * * \li Reliability: * No anticipated impact. * * \li Resources: * TBS * * \li Security: * No anticipated impact. * * \li Standards: * None. */ /*** *** Imports ***/ #include #include #include #include #include #include #include #include #include #ifdef WIN32 /* from the old namespace.h */ #define isc_socket_create isc__socket_create #define isc_socket_dup isc__socket_dup #define isc_socket_attach isc__socket_attach #define isc_socket_detach isc__socket_detach #define isc_socketmgr_create isc__socketmgr_create #define isc_socketmgr_create2 isc__socketmgr_create2 #define isc_socketmgr_destroy isc__socketmgr_destroy #define isc_socket_open isc__socket_open #define isc_socket_close isc__socket_close #define isc_socket_recvv isc__socket_recvv #define isc_socket_recv isc__socket_recv #define isc_socket_recv2 isc__socket_recv2 #define isc_socket_send isc__socket_send #define isc_socket_sendto isc__socket_sendto #define isc_socket_sendv isc__socket_sendv #define isc_socket_sendtov isc__socket_sendtov #define isc_socket_sendtov2 isc__socket_sendtov2 #define isc_socket_sendto2 isc__socket_sendto2 #define isc_socket_cleanunix isc__socket_cleanunix #define isc_socket_permunix isc__socket_permunix #define isc_socket_bind isc__socket_bind #define isc_socket_filter isc__socket_filter #define isc_socket_listen isc__socket_listen #define isc_socket_accept isc__socket_accept #define isc_socket_connect isc__socket_connect #define isc_socket_getfd isc__socket_getfd #define isc_socket_getname isc__socket_getname #define isc_socket_gettag isc__socket_gettag #define isc_socket_getpeername isc__socket_getpeername #define isc_socket_getsockname isc__socket_getsockname #define isc_socket_cancel isc__socket_cancel #define isc_socket_gettype isc__socket_gettype #define isc_socket_isbound isc__socket_isbound #define isc_socket_ipv6only isc__socket_ipv6only #define isc_socket_setname isc__socket_setname #define isc_socketmgr_getmaxsockets isc__socketmgr_getmaxsockets #define isc_socketmgr_setstats isc__socketmgr_setstats #define isc_socketmgr_setreserved isc__socketmgr_setreserved #define isc__socketmgr_maxudp isc___socketmgr_maxudp #define isc_socket_fdwatchcreate isc__socket_fdwatchcreate #define isc_socket_fdwatchpoke isc__socket_fdwatchpoke #define isc_socket_dscp isc__socket_dscp #endif ISC_LANG_BEGINDECLS /*** *** Constants ***/ /*% * Maximum number of buffers in a scatter/gather read/write. The operating * system in use must support at least this number (plus one on some.) */ #define ISC_SOCKET_MAXSCATTERGATHER 8 /*% * In isc_socket_bind() set socket option SO_REUSEADDR prior to calling * bind() if a non zero port is specified (AF_INET and AF_INET6). */ #define ISC_SOCKET_REUSEADDRESS 0x01U /*% * Statistics counters. Used as isc_statscounter_t values. */ enum { isc_sockstatscounter_udp4open = 0, isc_sockstatscounter_udp6open = 1, isc_sockstatscounter_tcp4open = 2, isc_sockstatscounter_tcp6open = 3, isc_sockstatscounter_unixopen = 4, isc_sockstatscounter_udp4openfail = 5, isc_sockstatscounter_udp6openfail = 6, isc_sockstatscounter_tcp4openfail = 7, isc_sockstatscounter_tcp6openfail = 8, isc_sockstatscounter_unixopenfail = 9, isc_sockstatscounter_udp4close = 10, isc_sockstatscounter_udp6close = 11, isc_sockstatscounter_tcp4close = 12, isc_sockstatscounter_tcp6close = 13, isc_sockstatscounter_unixclose = 14, isc_sockstatscounter_fdwatchclose = 15, isc_sockstatscounter_udp4bindfail = 16, isc_sockstatscounter_udp6bindfail = 17, isc_sockstatscounter_tcp4bindfail = 18, isc_sockstatscounter_tcp6bindfail = 19, isc_sockstatscounter_unixbindfail = 20, isc_sockstatscounter_fdwatchbindfail = 21, isc_sockstatscounter_udp4connect = 22, isc_sockstatscounter_udp6connect = 23, isc_sockstatscounter_tcp4connect = 24, isc_sockstatscounter_tcp6connect = 25, isc_sockstatscounter_unixconnect = 26, isc_sockstatscounter_fdwatchconnect = 27, isc_sockstatscounter_udp4connectfail = 28, isc_sockstatscounter_udp6connectfail = 29, isc_sockstatscounter_tcp4connectfail = 30, isc_sockstatscounter_tcp6connectfail = 31, isc_sockstatscounter_unixconnectfail = 32, isc_sockstatscounter_fdwatchconnectfail = 33, isc_sockstatscounter_tcp4accept = 34, isc_sockstatscounter_tcp6accept = 35, isc_sockstatscounter_unixaccept = 36, isc_sockstatscounter_tcp4acceptfail = 37, isc_sockstatscounter_tcp6acceptfail = 38, isc_sockstatscounter_unixacceptfail = 39, isc_sockstatscounter_udp4sendfail = 40, isc_sockstatscounter_udp6sendfail = 41, isc_sockstatscounter_tcp4sendfail = 42, isc_sockstatscounter_tcp6sendfail = 43, isc_sockstatscounter_unixsendfail = 44, isc_sockstatscounter_fdwatchsendfail = 45, isc_sockstatscounter_udp4recvfail = 46, isc_sockstatscounter_udp6recvfail = 47, isc_sockstatscounter_tcp4recvfail = 48, isc_sockstatscounter_tcp6recvfail = 49, isc_sockstatscounter_unixrecvfail = 50, isc_sockstatscounter_fdwatchrecvfail = 51, isc_sockstatscounter_udp4active = 52, isc_sockstatscounter_udp6active = 53, isc_sockstatscounter_tcp4active = 54, isc_sockstatscounter_tcp6active = 55, isc_sockstatscounter_unixactive = 56, isc_sockstatscounter_rawopen = 57, isc_sockstatscounter_rawopenfail = 58, isc_sockstatscounter_rawclose = 59, isc_sockstatscounter_rawrecvfail = 60, isc_sockstatscounter_rawactive = 61, isc_sockstatscounter_max = 62 }; /*** *** Types ***/ struct isc_socketevent { ISC_EVENT_COMMON(isc_socketevent_t); isc_result_t result; /*%< OK, EOF, whatever else */ unsigned int minimum; /*%< minimum i/o for event */ unsigned int n; /*%< bytes read or written */ unsigned int offset; /*%< offset into buffer list */ isc_region_t region; /*%< for single-buffer i/o */ isc_bufferlist_t bufferlist; /*%< list of buffers */ isc_sockaddr_t address; /*%< source address */ isc_time_t timestamp; /*%< timestamp of packet recv */ struct in6_pktinfo pktinfo; /*%< ipv6 pktinfo */ isc_uint32_t attributes; /*%< see below */ isc_eventdestructor_t destroy; /*%< original destructor */ unsigned int dscp; /*%< UDP dscp value */ }; typedef struct isc_socket_newconnev isc_socket_newconnev_t; struct isc_socket_newconnev { ISC_EVENT_COMMON(isc_socket_newconnev_t); isc_socket_t * newsocket; isc_result_t result; /*%< OK, EOF, whatever else */ isc_sockaddr_t address; /*%< source address */ }; typedef struct isc_socket_connev isc_socket_connev_t; struct isc_socket_connev { ISC_EVENT_COMMON(isc_socket_connev_t); isc_result_t result; /*%< OK, EOF, whatever else */ }; /*@{*/ /*! * _ATTACHED: Internal use only. * _TRUNC: Packet was truncated on receive. * _CTRUNC: Packet control information was truncated. This can * indicate that the packet is not complete, even though * all the data is valid. * _TIMESTAMP: The timestamp member is valid. * _PKTINFO: The pktinfo member is valid. * _MULTICAST: The UDP packet was received via a multicast transmission. * _DSCP: The UDP DSCP value is valid. */ #define ISC_SOCKEVENTATTR_ATTACHED 0x80000000U /* internal */ #define ISC_SOCKEVENTATTR_TRUNC 0x00800000U /* public */ #define ISC_SOCKEVENTATTR_CTRUNC 0x00400000U /* public */ #define ISC_SOCKEVENTATTR_TIMESTAMP 0x00200000U /* public */ #define ISC_SOCKEVENTATTR_PKTINFO 0x00100000U /* public */ #define ISC_SOCKEVENTATTR_MULTICAST 0x00080000U /* public */ #define ISC_SOCKEVENTATTR_DSCP 0x00040000U /* public */ /*@}*/ #define ISC_SOCKEVENT_ANYEVENT (0) #define ISC_SOCKEVENT_RECVDONE (ISC_EVENTCLASS_SOCKET + 1) #define ISC_SOCKEVENT_SENDDONE (ISC_EVENTCLASS_SOCKET + 2) #define ISC_SOCKEVENT_NEWCONN (ISC_EVENTCLASS_SOCKET + 3) #define ISC_SOCKEVENT_CONNECT (ISC_EVENTCLASS_SOCKET + 4) /* * Internal events. */ #define ISC_SOCKEVENT_INTR (ISC_EVENTCLASS_SOCKET + 256) #define ISC_SOCKEVENT_INTW (ISC_EVENTCLASS_SOCKET + 257) typedef enum { isc_sockettype_udp = 1, isc_sockettype_tcp = 2, isc_sockettype_unix = 3, isc_sockettype_fdwatch = 4, isc_sockettype_raw = 5 } isc_sockettype_t; /*@{*/ /*! * How a socket should be shutdown in isc_socket_shutdown() calls. */ #define ISC_SOCKSHUT_RECV 0x00000001 /*%< close read side */ #define ISC_SOCKSHUT_SEND 0x00000002 /*%< close write side */ #define ISC_SOCKSHUT_ALL 0x00000003 /*%< close them all */ /*@}*/ /*@{*/ /*! * What I/O events to cancel in isc_socket_cancel() calls. */ #define ISC_SOCKCANCEL_RECV 0x00000001 /*%< cancel recv */ #define ISC_SOCKCANCEL_SEND 0x00000002 /*%< cancel send */ #define ISC_SOCKCANCEL_ACCEPT 0x00000004 /*%< cancel accept */ #define ISC_SOCKCANCEL_CONNECT 0x00000008 /*%< cancel connect */ #define ISC_SOCKCANCEL_ALL 0x0000000f /*%< cancel everything */ /*@}*/ /*@{*/ /*! * Flags for isc_socket_send() and isc_socket_recv() calls. */ #define ISC_SOCKFLAG_IMMEDIATE 0x00000001 /*%< send event only if needed */ #define ISC_SOCKFLAG_NORETRY 0x00000002 /*%< drop failed UDP sends */ /*@}*/ /*@{*/ /*! * Flags for fdwatchcreate. */ #define ISC_SOCKFDWATCH_READ 0x00000001 /*%< watch for readable */ #define ISC_SOCKFDWATCH_WRITE 0x00000002 /*%< watch for writable */ /*@}*/ /*% Socket and socket manager methods */ typedef struct isc_socketmgrmethods { void (*destroy)(isc_socketmgr_t **managerp); isc_result_t (*socketcreate)(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, isc_socket_t **socketp); isc_result_t (*fdwatchcreate)(isc_socketmgr_t *manager, int fd, int flags, isc_sockfdwatch_t callback, void *cbarg, isc_task_t *task, isc_socket_t **socketp); } isc_socketmgrmethods_t; typedef struct isc_socketmethods { void (*attach)(isc_socket_t *socket, isc_socket_t **socketp); void (*detach)(isc_socket_t **socketp); isc_result_t (*bind)(isc_socket_t *sock, isc_sockaddr_t *sockaddr, unsigned int options); isc_result_t (*sendto)(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo); isc_result_t (*sendto2)(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, isc_socketevent_t *event, unsigned int flags); isc_result_t (*connect)(isc_socket_t *sock, isc_sockaddr_t *addr, isc_task_t *task, isc_taskaction_t action, void *arg); isc_result_t (*recv)(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, isc_task_t *task, isc_taskaction_t action, void *arg); isc_result_t (*recv2)(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, isc_task_t *task, isc_socketevent_t *event, unsigned int flags); void (*cancel)(isc_socket_t *sock, isc_task_t *task, unsigned int how); isc_result_t (*getsockname)(isc_socket_t *sock, isc_sockaddr_t *addressp); isc_sockettype_t (*gettype)(isc_socket_t *sock); void (*ipv6only)(isc_socket_t *sock, isc_boolean_t yes); isc_result_t (*fdwatchpoke)(isc_socket_t *sock, int flags); isc_result_t (*dup)(isc_socket_t *socket, isc_socket_t **socketp); int (*getfd)(isc_socket_t *socket); void (*dscp)(isc_socket_t *socket, isc_dscp_t dscp); } isc_socketmethods_t; /*% * This structure is actually just the common prefix of a socket manager * object implementation's version of an isc_socketmgr_t. * \brief * Direct use of this structure by clients is forbidden. socket implementations * may change the structure. 'magic' must be ISCAPI_SOCKETMGR_MAGIC for any * of the isc_socket_ routines to work. socket implementations must maintain * all socket invariants. * In effect, this definition is used only for non-BIND9 version ("export") * of the library, and the export version does not work for win32. So, to avoid * the definition conflict with win32/socket.c, we enable this definition only * for non-Win32 (i.e. Unix) platforms. */ #ifndef WIN32 struct isc_socketmgr { unsigned int impmagic; unsigned int magic; isc_socketmgrmethods_t *methods; }; #endif #define ISCAPI_SOCKETMGR_MAGIC ISC_MAGIC('A','s','m','g') #define ISCAPI_SOCKETMGR_VALID(m) ((m) != NULL && \ (m)->magic == ISCAPI_SOCKETMGR_MAGIC) /*% * This is the common prefix of a socket object. The same note as * that for the socketmgr structure applies. */ #ifndef WIN32 struct isc_socket { unsigned int impmagic; unsigned int magic; isc_socketmethods_t *methods; }; #endif #define ISCAPI_SOCKET_MAGIC ISC_MAGIC('A','s','c','t') #define ISCAPI_SOCKET_VALID(s) ((s) != NULL && \ (s)->magic == ISCAPI_SOCKET_MAGIC) /*** *** Socket and Socket Manager Functions *** *** Note: all Ensures conditions apply only if the result is success for *** those functions which return an isc_result. ***/ isc_result_t isc_socket_fdwatchcreate(isc_socketmgr_t *manager, int fd, int flags, isc_sockfdwatch_t callback, void *cbarg, isc_task_t *task, isc_socket_t **socketp); /*%< * Create a new file descriptor watch socket managed by 'manager'. * * Note: * *\li 'fd' is the already-opened file descriptor. *\li This function is not available on Windows. *\li The callback function is called "in-line" - this means the function * needs to return as fast as possible, as all other I/O will be suspended * until the callback completes. * * Requires: * *\li 'manager' is a valid manager * *\li 'socketp' is a valid pointer, and *socketp == NULL * *\li 'fd' be opened. * * Ensures: * * '*socketp' is attached to the newly created fdwatch socket * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li #ISC_R_NORESOURCES *\li #ISC_R_UNEXPECTED */ isc_result_t isc_socket_fdwatchpoke(isc_socket_t *sock, int flags); /*%< * Poke a file descriptor watch socket informing the manager that it * should restart watching the socket * * Note: * *\li 'sock' is the socket returned by isc_socket_fdwatchcreate * *\li 'flags' indicates what the manager should watch for on the socket * in addition to what it may already be watching. It can be one or * both of ISC_SOCKFDWATCH_READ and ISC_SOCKFDWATCH_WRITE. To * temporarily disable watching on a socket the value indicating * no more data should be returned from the call back routine. * *\li This function is not available on Windows. * * Requires: * *\li 'sock' is a valid isc socket * * * Returns: * *\li #ISC_R_SUCCESS */ isc_result_t isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, isc_socket_t **socketp); /*%< * Create a new 'type' socket managed by 'manager'. * * For isc_sockettype_fdwatch sockets you should use isc_socket_fdwatchcreate() * rather than isc_socket_create(). * * Note: * *\li 'pf' is the desired protocol family, e.g. PF_INET or PF_INET6. * * Requires: * *\li 'manager' is a valid manager * *\li 'socketp' is a valid pointer, and *socketp == NULL * *\li 'type' is not isc_sockettype_fdwatch * * Ensures: * * '*socketp' is attached to the newly created socket * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li #ISC_R_NORESOURCES *\li #ISC_R_UNEXPECTED */ isc_result_t isc_socket_dup(isc_socket_t *sock0, isc_socket_t **socketp); /*%< * Duplicate an existing socket, reusing its file descriptor. */ void isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how); /*%< * Cancel pending I/O of the type specified by "how". * * Note: if "task" is NULL, then the cancel applies to all tasks using the * socket. * * Requires: * * \li "socket" is a valid socket * * \li "task" is NULL or a valid task * * "how" is a bitmask describing the type of cancelation to perform. * The type ISC_SOCKCANCEL_ALL will cancel all pending I/O on this * socket. * * \li ISC_SOCKCANCEL_RECV: * Cancel pending isc_socket_recv() calls. * * \li ISC_SOCKCANCEL_SEND: * Cancel pending isc_socket_send() and isc_socket_sendto() calls. * * \li ISC_SOCKCANCEL_ACCEPT: * Cancel pending isc_socket_accept() calls. * * \li ISC_SOCKCANCEL_CONNECT: * Cancel pending isc_socket_connect() call. */ void isc_socket_shutdown(isc_socket_t *sock, unsigned int how); /*%< * Shutdown 'socket' according to 'how'. * * Requires: * * \li 'socket' is a valid socket. * * \li 'task' is NULL or is a valid task. * * \li If 'how' is 'ISC_SOCKSHUT_RECV' or 'ISC_SOCKSHUT_ALL' then * * The read queue must be empty. * * No further read requests may be made. * * \li If 'how' is 'ISC_SOCKSHUT_SEND' or 'ISC_SOCKSHUT_ALL' then * * The write queue must be empty. * * No further write requests may be made. */ void isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp); /*%< * Attach *socketp to socket. * * Requires: * * \li 'socket' is a valid socket. * * \li 'socketp' points to a NULL socket. * * Ensures: * * \li *socketp is attached to socket. */ void isc_socket_detach(isc_socket_t **socketp); /*%< * Detach *socketp from its socket. * * Requires: * * \li 'socketp' points to a valid socket. * * \li If '*socketp' is the last reference to the socket, * then: * * There must be no pending I/O requests. * * Ensures: * * \li *socketp is NULL. * * \li If '*socketp' is the last reference to the socket, * then: * * The socket will be shutdown (both reading and writing) * for all tasks. * * All resources used by the socket have been freed */ isc_result_t isc_socket_open(isc_socket_t *sock); /*%< * Open a new socket file descriptor of the given socket structure. It simply * opens a new descriptor; all of the other parameters including the socket * type are inherited from the existing socket. This function is provided to * avoid overhead of destroying and creating sockets when many short-lived * sockets are frequently opened and closed. When the efficiency is not an * issue, it should be safer to detach the unused socket and re-create a new * one. This optimization may not be available for some systems, in which * case this function will return ISC_R_NOTIMPLEMENTED and must not be used. * * isc_socket_open() should not be called on sockets created by * isc_socket_fdwatchcreate(). * * Requires: * * \li there must be no other reference to this socket. * * \li 'socket' is a valid and previously closed by isc_socket_close() * * \li 'sock->type' is not isc_sockettype_fdwatch * * Returns: * Same as isc_socket_create(). * \li ISC_R_NOTIMPLEMENTED */ isc_result_t isc_socket_close(isc_socket_t *sock); /*%< * Close a socket file descriptor of the given socket structure. This function * is provided as an alternative to destroying an unused socket when overhead * destroying/re-creating sockets can be significant, and is expected to be * used with isc_socket_open(). This optimization may not be available for some * systems, in which case this function will return ISC_R_NOTIMPLEMENTED and * must not be used. * * isc_socket_close() should not be called on sockets created by * isc_socket_fdwatchcreate(). * * Requires: * * \li The socket must have a valid descriptor. * * \li There must be no other reference to this socket. * * \li There must be no pending I/O requests. * * \li 'sock->type' is not isc_sockettype_fdwatch * * Returns: * \li #ISC_R_NOTIMPLEMENTED */ isc_result_t isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *addressp, unsigned int options); /*%< * Bind 'socket' to '*addressp'. * * Requires: * * \li 'socket' is a valid socket * * \li 'addressp' points to a valid isc_sockaddr. * * Returns: * * \li ISC_R_SUCCESS * \li ISC_R_NOPERM * \li ISC_R_ADDRNOTAVAIL * \li ISC_R_ADDRINUSE * \li ISC_R_BOUND * \li ISC_R_UNEXPECTED */ isc_result_t isc_socket_filter(isc_socket_t *sock, const char *filter); /*%< * Inform the kernel that it should perform accept filtering. * If filter is NULL the current filter will be removed.:w */ isc_result_t isc_socket_listen(isc_socket_t *sock, unsigned int backlog); /*%< * Set listen mode on the socket. After this call, the only function that * can be used (other than attach and detach) is isc_socket_accept(). * * Notes: * * \li 'backlog' is as in the UNIX system call listen() and may be * ignored by non-UNIX implementations. * * \li If 'backlog' is zero, a reasonable system default is used, usually * SOMAXCONN. * * Requires: * * \li 'socket' is a valid, bound TCP socket or a valid, bound UNIX socket. * * Returns: * * \li ISC_R_SUCCESS * \li ISC_R_UNEXPECTED */ isc_result_t isc_socket_accept(isc_socket_t *sock, isc_task_t *task, isc_taskaction_t action, void *arg); /*%< * Queue accept event. When a new connection is received, the task will * get an ISC_SOCKEVENT_NEWCONN event with the sender set to the listen * socket. The new socket structure is sent inside the isc_socket_newconnev_t * event type, and is attached to the task 'task'. * * REQUIRES: * \li 'socket' is a valid TCP socket that isc_socket_listen() was called * on. * * \li 'task' is a valid task * * \li 'action' is a valid action * * RETURNS: * \li ISC_R_SUCCESS * \li ISC_R_NOMEMORY * \li ISC_R_UNEXPECTED */ isc_result_t isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addressp, isc_task_t *task, isc_taskaction_t action, void *arg); /*%< * Connect 'socket' to peer with address *saddr. When the connection * succeeds, or when an error occurs, a CONNECT event with action 'action' * and arg 'arg' will be posted to the event queue for 'task'. * * Requires: * * \li 'socket' is a valid TCP socket * * \li 'addressp' points to a valid isc_sockaddr * * \li 'task' is a valid task * * \li 'action' is a valid action * * Returns: * * \li ISC_R_SUCCESS * \li ISC_R_NOMEMORY * \li ISC_R_UNEXPECTED * * Posted event's result code: * * \li ISC_R_SUCCESS * \li ISC_R_TIMEDOUT * \li ISC_R_CONNREFUSED * \li ISC_R_NETUNREACH * \li ISC_R_UNEXPECTED */ isc_result_t isc_socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp); /*%< * Get the name of the peer connected to 'socket'. * * Requires: * * \li 'socket' is a valid TCP socket. * * Returns: * * \li ISC_R_SUCCESS * \li ISC_R_TOOSMALL * \li ISC_R_UNEXPECTED */ isc_result_t isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp); /*%< * Get the name of 'socket'. * * Requires: * * \li 'socket' is a valid socket. * * Returns: * * \li ISC_R_SUCCESS * \li ISC_R_TOOSMALL * \li ISC_R_UNEXPECTED */ /*@{*/ isc_result_t isc_socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, isc_task_t *task, isc_taskaction_t action, void *arg); isc_result_t isc_socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist, unsigned int minimum, isc_task_t *task, isc_taskaction_t action, void *arg); isc_result_t isc_socket_recv2(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, isc_task_t *task, isc_socketevent_t *event, unsigned int flags); /*! * Receive from 'socket', storing the results in region. * * Notes: * *\li Let 'length' refer to the length of 'region' or to the sum of all * available regions in the list of buffers '*buflist'. * *\li If 'minimum' is non-zero and at least that many bytes are read, * the completion event will be posted to the task 'task.' If minimum * is zero, the exact number of bytes requested in the region must * be read for an event to be posted. This only makes sense for TCP * connections, and is always set to 1 byte for UDP. * *\li The read will complete when the desired number of bytes have been * read, if end-of-input occurs, or if an error occurs. A read done * event with the given 'action' and 'arg' will be posted to the * event queue of 'task'. * *\li The caller may not modify 'region', the buffers which are passed * into this function, or any data they refer to until the completion * event is received. * *\li For isc_socket_recvv(): * On successful completion, '*buflist' will be empty, and the list of * all buffers will be returned in the done event's 'bufferlist' * member. On error return, '*buflist' will be unchanged. * *\li For isc_socket_recv2(): * 'event' is not NULL, and the non-socket specific fields are * expected to be initialized. * *\li For isc_socket_recv2(): * The only defined value for 'flags' is ISC_SOCKFLAG_IMMEDIATE. If * set and the operation completes, the return value will be * ISC_R_SUCCESS and the event will be filled in and not sent. If the * operation does not complete, the return value will be * ISC_R_INPROGRESS and the event will be sent when the operation * completes. * * Requires: * *\li 'socket' is a valid, bound socket. * *\li For isc_socket_recv(): * 'region' is a valid region * *\li For isc_socket_recvv(): * 'buflist' is non-NULL, and '*buflist' contain at least one buffer. * *\li 'task' is a valid task * *\li For isc_socket_recv() and isc_socket_recvv(): * action != NULL and is a valid action * *\li For isc_socket_recv2(): * event != NULL * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_INPROGRESS *\li #ISC_R_NOMEMORY *\li #ISC_R_UNEXPECTED * * Event results: * *\li #ISC_R_SUCCESS *\li #ISC_R_UNEXPECTED *\li XXX needs other net-type errors */ /*@}*/ /*@{*/ isc_result_t isc_socket_send(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, isc_taskaction_t action, void *arg); isc_result_t isc_socket_sendto(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo); isc_result_t isc_socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist, isc_task_t *task, isc_taskaction_t action, void *arg); isc_result_t isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist, isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo); isc_result_t isc_socket_sendtov2(isc_socket_t *sock, isc_bufferlist_t *buflist, isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, unsigned int flags); isc_result_t isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, isc_socketevent_t *event, unsigned int flags); /*! * Send the contents of 'region' to the socket's peer. * * Notes: * *\li Shutting down the requestor's task *may* result in any * still pending writes being dropped or completed, depending on the * underlying OS implementation. * *\li If 'action' is NULL, then no completion event will be posted. * *\li The caller may not modify 'region', the buffers which are passed * into this function, or any data they refer to until the completion * event is received. * *\li For isc_socket_sendv() and isc_socket_sendtov(): * On successful completion, '*buflist' will be empty, and the list of * all buffers will be returned in the done event's 'bufferlist' * member. On error return, '*buflist' will be unchanged. * *\li For isc_socket_sendto2(): * 'event' is not NULL, and the non-socket specific fields are * expected to be initialized. * *\li For isc_socket_sendto2(): * The only defined values for 'flags' are ISC_SOCKFLAG_IMMEDIATE * and ISC_SOCKFLAG_NORETRY. * *\li If ISC_SOCKFLAG_IMMEDIATE is set and the operation completes, the * return value will be ISC_R_SUCCESS and the event will be filled * in and not sent. If the operation does not complete, the return * value will be ISC_R_INPROGRESS and the event will be sent when * the operation completes. * *\li ISC_SOCKFLAG_NORETRY can only be set for UDP sockets. If set * and the send operation fails due to a transient error, the send * will not be retried and the error will be indicated in the event. * Using this option along with ISC_SOCKFLAG_IMMEDIATE allows the caller * to specify a region that is allocated on the stack. * * Requires: * *\li 'socket' is a valid, bound socket. * *\li For isc_socket_send(): * 'region' is a valid region * *\li For isc_socket_sendv() and isc_socket_sendtov(): * 'buflist' is non-NULL, and '*buflist' contain at least one buffer. * *\li 'task' is a valid task * *\li For isc_socket_sendv(), isc_socket_sendtov(), isc_socket_send(), and * isc_socket_sendto(): * action == NULL or is a valid action * *\li For isc_socket_sendto2(): * event != NULL * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_INPROGRESS *\li #ISC_R_NOMEMORY *\li #ISC_R_UNEXPECTED * * Event results: * *\li #ISC_R_SUCCESS *\li #ISC_R_UNEXPECTED *\li XXX needs other net-type errors */ /*@}*/ isc_result_t isc_socketmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx, isc_socketmgr_t **managerp); isc_result_t isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp); isc_result_t isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp, unsigned int maxsocks); /*%< * Create a socket manager. If "maxsocks" is non-zero, it specifies the * maximum number of sockets that the created manager should handle. * isc_socketmgr_create() is equivalent of isc_socketmgr_create2() with * "maxsocks" being zero. * isc_socketmgr_createinctx() also associates the new manager with the * specified application context. * * Notes: * *\li All memory will be allocated in memory context 'mctx'. * * Requires: * *\li 'mctx' is a valid memory context. * *\li 'managerp' points to a NULL isc_socketmgr_t. * *\li 'actx' is a valid application context (for createinctx()). * * Ensures: * *\li '*managerp' is a valid isc_socketmgr_t. * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY *\li #ISC_R_UNEXPECTED *\li #ISC_R_NOTIMPLEMENTED */ isc_result_t isc_socketmgr_getmaxsockets(isc_socketmgr_t *manager, unsigned int *nsockp); /*%< * Returns in "*nsockp" the maximum number of sockets this manager may open. * * Requires: * *\li '*manager' is a valid isc_socketmgr_t. *\li 'nsockp' is not NULL. * * Returns: * *\li #ISC_R_SUCCESS *\li #ISC_R_NOTIMPLEMENTED */ void isc_socketmgr_setstats(isc_socketmgr_t *manager, isc_stats_t *stats); /*%< * Set a general socket statistics counter set 'stats' for 'manager'. * * Requires: * \li 'manager' is valid, hasn't opened any socket, and doesn't have * stats already set. * *\li stats is a valid statistics supporting socket statistics counters * (see above). */ void isc_socketmgr_destroy(isc_socketmgr_t **managerp); /*%< * Destroy a socket manager. * * Notes: * *\li This routine blocks until there are no sockets left in the manager, * so if the caller holds any socket references using the manager, it * must detach them before calling isc_socketmgr_destroy() or it will * block forever. * * Requires: * *\li '*managerp' is a valid isc_socketmgr_t. * *\li All sockets managed by this manager are fully detached. * * Ensures: * *\li *managerp == NULL * *\li All resources used by the manager have been freed. */ isc_sockettype_t isc_socket_gettype(isc_socket_t *sock); /*%< * Returns the socket type for "sock." * * Requires: * *\li "sock" is a valid socket. */ /*@{*/ isc_boolean_t isc__socket_isbound(isc_socket_t *sock); /*% * Intended for internal use in BIND9 only */ void isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes); /*%< * If the socket is an IPv6 socket set/clear the IPV6_IPV6ONLY socket * option if the host OS supports this option. * * Requires: *\li 'sock' is a valid socket. */ /*@}*/ void isc_socket_dscp(isc_socket_t *sock, isc_dscp_t dscp); /*%< * Sets the Differentiated Services Code Point (DSCP) field for packets * transmitted on this socket. If 'dscp' is -1, return immediately. * * Requires: *\li 'sock' is a valid socket. */ isc_socketevent_t * isc_socket_socketevent(isc_mem_t *mctx, void *sender, isc_eventtype_t eventtype, isc_taskaction_t action, void *arg); /*%< * Get a isc_socketevent_t to be used with isc_socket_sendto2(), etc. */ void isc_socket_cleanunix(isc_sockaddr_t *addr, isc_boolean_t active); /*%< * Cleanup UNIX domain sockets in the file-system. If 'active' is true * then just unlink the socket. If 'active' is false try to determine * if there is a listener of the socket or not. If no listener is found * then unlink socket. * * Prior to unlinking the path is tested to see if it a socket. * * Note: there are a number of race conditions which cannot be avoided * both in the filesystem and any application using UNIX domain * sockets (e.g. socket is tested between bind() and listen(), * the socket is deleted and replaced in the file-system between * stat() and unlink()). */ isc_result_t isc_socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm, isc_uint32_t owner, isc_uint32_t group); /*%< * Set ownership and file permissions on the UNIX domain socket. * * Note: On Solaris and SunOS this secures the directory containing * the socket as Solaris and SunOS do not honour the filesystem * permissions on the socket. * * Requires: * \li 'sockaddr' to be a valid UNIX domain sockaddr. * * Returns: * \li #ISC_R_SUCCESS * \li #ISC_R_FAILURE */ void isc_socket_setname(isc_socket_t *socket, const char *name, void *tag); /*%< * Set the name and optional tag for a socket. This allows tracking of the * owner or purpose for this socket, and is useful for tracing and statistics * reporting. */ const char *isc_socket_getname(isc_socket_t *socket); /*%< * Get the name associated with a socket, if any. */ void *isc_socket_gettag(isc_socket_t *socket); /*%< * Get the tag associated with a socket, if any. */ int isc_socket_getfd(isc_socket_t *socket); /*%< * Get the file descriptor associated with a socket */ void isc__socketmgr_setreserved(isc_socketmgr_t *mgr, isc_uint32_t); /*%< * Temporary. For use by named only. */ void isc__socketmgr_maxudp(isc_socketmgr_t *mgr, int maxudp); /*%< * Test interface. Drop UDP packet > 'maxudp'. */ #ifdef HAVE_LIBXML2 int isc_socketmgr_renderxml(isc_socketmgr_t *mgr, xmlTextWriterPtr writer); /*%< * Render internal statistics and other state into the XML document. */ #endif /* HAVE_LIBXML2 */ #ifdef HAVE_JSON isc_result_t isc_socketmgr_renderjson(isc_socketmgr_t *mgr, json_object *stats); /*%< * Render internal statistics and other state into JSON format. */ #endif /* HAVE_JSON */ /*%< * See isc_socketmgr_create() above. */ typedef isc_result_t (*isc_socketmgrcreatefunc_t)(isc_mem_t *mctx, isc_socketmgr_t **managerp); isc_result_t isc_socket_register(isc_socketmgrcreatefunc_t createfunc); /*%< * Register a new socket I/O implementation and add it to the list of * supported implementations. This function must be called when a different * event library is used than the one contained in the ISC library. */ isc_result_t isc__socket_register(void); /*%< * A short cut function that specifies the socket I/O module in the ISC * library for isc_socket_register(). An application that uses the ISC library * usually do not have to care about this function: it would call * isc_lib_register(), which internally calls this function. */ ISC_LANG_ENDDECLS #endif /* ISC_SOCKET_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/random.h0000644000470500017500000000344212664710322020552 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: random.h,v 1.20 2009/01/17 23:47:43 tbox Exp $ */ #ifndef ISC_RANDOM_H #define ISC_RANDOM_H 1 #include #include /*! \file isc/random.h * \brief Implements a random state pool which will let the caller return a * series of possibly non-reproducible random values. * * Note that the * strength of these numbers is not all that high, and should not be * used in cryptography functions. It is useful for jittering values * a bit here and there, such as timeouts, etc. */ ISC_LANG_BEGINDECLS void isc_random_seed(isc_uint32_t seed); /*%< * Set the initial seed of the random state. */ void isc_random_get(isc_uint32_t *val); /*%< * Get a random value. * * Requires: * val != NULL. */ isc_uint32_t isc_random_jitter(isc_uint32_t max, isc_uint32_t jitter); /*%< * Get a random value between (max - jitter) and (max). * This is useful for jittering timer values. */ ISC_LANG_ENDDECLS #endif /* ISC_RANDOM_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/list.h0000644000470500017500000001420412664710322020243 0ustar lamontlamont/* * Copyright (C) 2004, 2006, 2007, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1997-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef ISC_LIST_H #define ISC_LIST_H 1 #include #include #ifdef ISC_LIST_CHECKINIT #define ISC_LINK_INSIST(x) ISC_INSIST(x) #else #define ISC_LINK_INSIST(x) #endif #define ISC_LIST(type) struct { type *head, *tail; } #define ISC_LIST_INIT(list) \ do { (list).head = NULL; (list).tail = NULL; } while (0) #define ISC_LINK(type) struct { type *prev, *next; } #define ISC_LINK_INIT_TYPE(elt, link, type) \ do { \ (elt)->link.prev = (type *)(-1); \ (elt)->link.next = (type *)(-1); \ } while (0) #define ISC_LINK_INIT(elt, link) \ ISC_LINK_INIT_TYPE(elt, link, void) #define ISC_LINK_LINKED(elt, link) ((void *)((elt)->link.prev) != (void *)(-1)) #define ISC_LIST_HEAD(list) ((list).head) #define ISC_LIST_TAIL(list) ((list).tail) #define ISC_LIST_EMPTY(list) ISC_TF((list).head == NULL) #define __ISC_LIST_PREPENDUNSAFE(list, elt, link) \ do { \ if ((list).head != NULL) \ (list).head->link.prev = (elt); \ else \ (list).tail = (elt); \ (elt)->link.prev = NULL; \ (elt)->link.next = (list).head; \ (list).head = (elt); \ } while (0) #define ISC_LIST_PREPEND(list, elt, link) \ do { \ ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \ __ISC_LIST_PREPENDUNSAFE(list, elt, link); \ } while (0) #define ISC_LIST_INITANDPREPEND(list, elt, link) \ __ISC_LIST_PREPENDUNSAFE(list, elt, link) #define __ISC_LIST_APPENDUNSAFE(list, elt, link) \ do { \ if ((list).tail != NULL) \ (list).tail->link.next = (elt); \ else \ (list).head = (elt); \ (elt)->link.prev = (list).tail; \ (elt)->link.next = NULL; \ (list).tail = (elt); \ } while (0) #define ISC_LIST_APPEND(list, elt, link) \ do { \ ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \ __ISC_LIST_APPENDUNSAFE(list, elt, link); \ } while (0) #define ISC_LIST_INITANDAPPEND(list, elt, link) \ __ISC_LIST_APPENDUNSAFE(list, elt, link) #define __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, type) \ do { \ if ((elt)->link.next != NULL) \ (elt)->link.next->link.prev = (elt)->link.prev; \ else { \ ISC_INSIST((list).tail == (elt)); \ (list).tail = (elt)->link.prev; \ } \ if ((elt)->link.prev != NULL) \ (elt)->link.prev->link.next = (elt)->link.next; \ else { \ ISC_INSIST((list).head == (elt)); \ (list).head = (elt)->link.next; \ } \ (elt)->link.prev = (type *)(-1); \ (elt)->link.next = (type *)(-1); \ ISC_INSIST((list).head != (elt)); \ ISC_INSIST((list).tail != (elt)); \ } while (0) #define __ISC_LIST_UNLINKUNSAFE(list, elt, link) \ __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, void) #define ISC_LIST_UNLINK_TYPE(list, elt, link, type) \ do { \ ISC_LINK_INSIST(ISC_LINK_LINKED(elt, link)); \ __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, type); \ } while (0) #define ISC_LIST_UNLINK(list, elt, link) \ ISC_LIST_UNLINK_TYPE(list, elt, link, void) #define ISC_LIST_PREV(elt, link) ((elt)->link.prev) #define ISC_LIST_NEXT(elt, link) ((elt)->link.next) #define __ISC_LIST_INSERTBEFOREUNSAFE(list, before, elt, link) \ do { \ if ((before)->link.prev == NULL) \ ISC_LIST_PREPEND(list, elt, link); \ else { \ (elt)->link.prev = (before)->link.prev; \ (before)->link.prev = (elt); \ (elt)->link.prev->link.next = (elt); \ (elt)->link.next = (before); \ } \ } while (0) #define ISC_LIST_INSERTBEFORE(list, before, elt, link) \ do { \ ISC_LINK_INSIST(ISC_LINK_LINKED(before, link)); \ ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \ __ISC_LIST_INSERTBEFOREUNSAFE(list, before, elt, link); \ } while (0) #define __ISC_LIST_INSERTAFTERUNSAFE(list, after, elt, link) \ do { \ if ((after)->link.next == NULL) \ ISC_LIST_APPEND(list, elt, link); \ else { \ (elt)->link.next = (after)->link.next; \ (after)->link.next = (elt); \ (elt)->link.next->link.prev = (elt); \ (elt)->link.prev = (after); \ } \ } while (0) #define ISC_LIST_INSERTAFTER(list, after, elt, link) \ do { \ ISC_LINK_INSIST(ISC_LINK_LINKED(after, link)); \ ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \ __ISC_LIST_INSERTAFTERUNSAFE(list, after, elt, link); \ } while (0) #define ISC_LIST_APPENDLIST(list1, list2, link) \ do { \ if (ISC_LIST_EMPTY(list1)) \ (list1) = (list2); \ else if (!ISC_LIST_EMPTY(list2)) { \ (list1).tail->link.next = (list2).head; \ (list2).head->link.prev = (list1).tail; \ (list1).tail = (list2).tail; \ } \ (list2).head = NULL; \ (list2).tail = NULL; \ } while (0) #define ISC_LIST_PREPENDLIST(list1, list2, link) \ do { \ if (ISC_LIST_EMPTY(list1)) \ (list1) = (list2); \ else if (!ISC_LIST_EMPTY(list2)) { \ (list2).tail->link.next = (list1).head; \ (list1).head->link.prev = (list2).tail; \ (list1).head = (list2).head; \ } \ (list2).head = NULL; \ (list2).tail = NULL; \ } while (0) #define ISC_LIST_ENQUEUE(list, elt, link) ISC_LIST_APPEND(list, elt, link) #define __ISC_LIST_ENQUEUEUNSAFE(list, elt, link) \ __ISC_LIST_APPENDUNSAFE(list, elt, link) #define ISC_LIST_DEQUEUE(list, elt, link) \ ISC_LIST_UNLINK_TYPE(list, elt, link, void) #define ISC_LIST_DEQUEUE_TYPE(list, elt, link, type) \ ISC_LIST_UNLINK_TYPE(list, elt, link, type) #define __ISC_LIST_DEQUEUEUNSAFE(list, elt, link) \ __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, void) #define __ISC_LIST_DEQUEUEUNSAFE_TYPE(list, elt, link, type) \ __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, type) #endif /* ISC_LIST_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/rwlock.h0000644000470500017500000000740312664710322020574 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rwlock.h,v 1.28 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_RWLOCK_H #define ISC_RWLOCK_H 1 /*! \file isc/rwlock.h */ #include #include #include #include ISC_LANG_BEGINDECLS typedef enum { isc_rwlocktype_none = 0, isc_rwlocktype_read, isc_rwlocktype_write } isc_rwlocktype_t; #ifdef ISC_PLATFORM_USETHREADS #if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG) #define ISC_RWLOCK_USEATOMIC 1 #endif struct isc_rwlock { /* Unlocked. */ unsigned int magic; isc_mutex_t lock; #if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG) /* * When some atomic instructions with hardware assistance are * available, rwlock will use those so that concurrent readers do not * interfere with each other through mutex as long as no writers * appear, massively reducing the lock overhead in the typical case. * * The basic algorithm of this approach is the "simple * writer-preference lock" shown in the following URL: * http://www.cs.rochester.edu/u/scott/synchronization/pseudocode/rw.html * but our implementation does not rely on the spin lock unlike the * original algorithm to be more portable as a user space application. */ /* Read or modified atomically. */ isc_int32_t write_requests; isc_int32_t write_completions; isc_int32_t cnt_and_flag; /* Locked by lock. */ isc_condition_t readable; isc_condition_t writeable; unsigned int readers_waiting; /* Locked by rwlock itself. */ unsigned int write_granted; /* Unlocked. */ unsigned int write_quota; #else /* ISC_PLATFORM_HAVEXADD && ISC_PLATFORM_HAVECMPXCHG */ /*%< Locked by lock. */ isc_condition_t readable; isc_condition_t writeable; isc_rwlocktype_t type; /*% The number of threads that have the lock. */ unsigned int active; /*% * The number of lock grants made since the lock was last switched * from reading to writing or vice versa; used in determining * when the quota is reached and it is time to switch. */ unsigned int granted; unsigned int readers_waiting; unsigned int writers_waiting; unsigned int read_quota; unsigned int write_quota; isc_rwlocktype_t original; #endif /* ISC_PLATFORM_HAVEXADD && ISC_PLATFORM_HAVECMPXCHG */ }; #else /* ISC_PLATFORM_USETHREADS */ struct isc_rwlock { unsigned int magic; isc_rwlocktype_t type; unsigned int active; }; #endif /* ISC_PLATFORM_USETHREADS */ isc_result_t isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota, unsigned int write_quota); isc_result_t isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type); isc_result_t isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type); isc_result_t isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type); isc_result_t isc_rwlock_tryupgrade(isc_rwlock_t *rwl); void isc_rwlock_downgrade(isc_rwlock_t *rwl); void isc_rwlock_destroy(isc_rwlock_t *rwl); ISC_LANG_ENDDECLS #endif /* ISC_RWLOCK_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/symtab.h0000644000470500017500000001130612664710322020567 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1996-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef ISC_SYMTAB_H #define ISC_SYMTAB_H 1 /***** ***** Module Info *****/ /*! \file isc/symtab.h * \brief Provides a simple memory-based symbol table. * * Keys are C strings, and key comparisons are case-insensitive. A type may * be specified when looking up, defining, or undefining. A type value of * 0 means "match any type"; any other value will only match the given * type. * * It's possible that a client will attempt to define a * tuple when a tuple with the given key and type already exists in the table. * What to do in this case is specified by the client. Possible policies are: * *\li #isc_symexists_reject Disallow the define, returning #ISC_R_EXISTS *\li #isc_symexists_replace Replace the old value with the new. The * undefine action (if provided) will be called * with the old tuple. *\li #isc_symexists_add Add the new tuple, leaving the old tuple in * the table. Subsequent lookups will retrieve * the most-recently-defined tuple. * * A lookup of a key using type 0 will return the most-recently defined * symbol with that key. An undefine of a key using type 0 will undefine the * most-recently defined symbol with that key. Trying to define a key with * type 0 is illegal. * * The symbol table library does not make a copy the key field, so the * caller must ensure that any key it passes to isc_symtab_define() will not * change until it calls isc_symtab_undefine() or isc_symtab_destroy(). * * A user-specified action will be called (if provided) when a symbol is * undefined. It can be used to free memory associated with keys and/or * values. * * A symbol table is implemented as a hash table of lists; the size of the * hash table is set by the 'size' parameter to isc_symtbl_create(). When * the number of entries in the symbol table reaches three quarters of this * value, the hash table is reallocated with size doubled, in order to * optimize lookup performance. This has a negative effect on insertion * performance, which can be mitigated by sizing the table appropriately * when creating it. * * \li MP: * The callers of this module must ensure any required synchronization. * * \li Reliability: * No anticipated impact. * * \li Resources: * TBS * * \li Security: * No anticipated impact. * * \li Standards: * None. */ /*** *** Imports. ***/ #include #include /* *** Symbol Tables. ***/ /*% Symbol table value. */ typedef union isc_symvalue { void * as_pointer; const void * as_cpointer; int as_integer; unsigned int as_uinteger; } isc_symvalue_t; typedef void (*isc_symtabaction_t)(char *key, unsigned int type, isc_symvalue_t value, void *userarg); /*% Symbol table exists. */ typedef enum { isc_symexists_reject = 0, /*%< Disallow the define */ isc_symexists_replace = 1, /*%< Replace the old value with the new */ isc_symexists_add = 2 /*%< Add the new tuple */ } isc_symexists_t; ISC_LANG_BEGINDECLS /*% Create a symbol table. */ isc_result_t isc_symtab_create(isc_mem_t *mctx, unsigned int size, isc_symtabaction_t undefine_action, void *undefine_arg, isc_boolean_t case_sensitive, isc_symtab_t **symtabp); /*% Destroy a symbol table. */ void isc_symtab_destroy(isc_symtab_t **symtabp); /*% Lookup a symbol table. */ isc_result_t isc_symtab_lookup(isc_symtab_t *symtab, const char *key, unsigned int type, isc_symvalue_t *value); /*% Define a symbol table. */ isc_result_t isc_symtab_define(isc_symtab_t *symtab, const char *key, unsigned int type, isc_symvalue_t value, isc_symexists_t exists_policy); /*% Undefine a symbol table. */ isc_result_t isc_symtab_undefine(isc_symtab_t *symtab, const char *key, unsigned int type); /*% Return the number of items in a symbol table. */ unsigned int isc_symtab_count(isc_symtab_t *symtab); ISC_LANG_ENDDECLS #endif /* ISC_SYMTAB_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/file.h0000644000470500017500000002531612664710322020215 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2011, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef ISC_FILE_H #define ISC_FILE_H 1 /*! \file isc/file.h */ #include #include #include #include ISC_LANG_BEGINDECLS isc_result_t isc_file_settime(const char *file, isc_time_t *time); isc_result_t isc_file_mode(const char *file, mode_t *modep); isc_result_t isc_file_getmodtime(const char *file, isc_time_t *time); /*!< * \brief Get the time of last modification of a file. * * Notes: *\li The time that is set is relative to the (OS-specific) epoch, as are * all isc_time_t structures. * * Requires: *\li file != NULL. *\li time != NULL. * * Ensures: *\li If the file could not be accessed, 'time' is unchanged. * * Returns: *\li #ISC_R_SUCCESS * Success. *\li #ISC_R_NOTFOUND * No such file exists. *\li #ISC_R_INVALIDFILE * The path specified was not usable by the operating system. *\li #ISC_R_NOPERM * The file's metainformation could not be retrieved because * permission was denied to some part of the file's path. *\li #ISC_R_IOERROR * Hardware error interacting with the filesystem. *\li #ISC_R_UNEXPECTED * Something totally unexpected happened. * */ isc_result_t isc_file_mktemplate(const char *path, char *buf, size_t buflen); /*!< * \brief Generate a template string suitable for use with isc_file_openunique(). * * Notes: *\li This function is intended to make creating temporary files * portable between different operating systems. * *\li The path is prepended to an implementation-defined string and * placed into buf. The string has no path characters in it, * and its maximum length is 14 characters plus a NUL. Thus * buflen should be at least strlen(path) + 15 characters or * an error will be returned. * * Requires: *\li buf != NULL. * * Ensures: *\li If result == #ISC_R_SUCCESS: * buf contains a string suitable for use as the template argument * to isc_file_openunique(). * *\li If result != #ISC_R_SUCCESS: * buf is unchanged. * * Returns: *\li #ISC_R_SUCCESS Success. *\li #ISC_R_NOSPACE buflen indicates buf is too small for the catenation * of the path with the internal template string. */ isc_result_t isc_file_openunique(char *templet, FILE **fp); isc_result_t isc_file_openuniqueprivate(char *templet, FILE **fp); isc_result_t isc_file_openuniquemode(char *templet, int mode, FILE **fp); isc_result_t isc_file_bopenunique(char *templet, FILE **fp); isc_result_t isc_file_bopenuniqueprivate(char *templet, FILE **fp); isc_result_t isc_file_bopenuniquemode(char *templet, int mode, FILE **fp); /*!< * \brief Create and open a file with a unique name based on 'templet'. * isc_file_bopen*() open the file in binary mode in Windows. * isc_file_open*() open the file in text mode in Windows. * * Notes: *\li 'template' is a reserved work in C++. If you want to complain * about the spelling of 'templet', first look it up in the * Merriam-Webster English dictionary. (http://www.m-w.com/) * *\li This function works by using the template to generate file names. * The template must be a writable string, as it is modified in place. * Trailing X characters in the file name (full file name on Unix, * basename on Win32 -- eg, tmp-XXXXXX vs XXXXXX.tmp, respectively) * are replaced with ASCII characters until a non-existent filename * is found. If the template does not include pathname information, * the files in the working directory of the program are searched. * *\li isc_file_mktemplate is a good, portable way to get a template. * * Requires: *\li 'fp' is non-NULL and '*fp' is NULL. * *\li 'template' is non-NULL, and of a form suitable for use by * the system as described above. * * Ensures: *\li If result is #ISC_R_SUCCESS: * *fp points to an stream opening in stdio's "w+" mode. * *\li If result is not #ISC_R_SUCCESS: * *fp is NULL. * * No file is open. Even if one was created (but unable * to be reopened as a stdio FILE pointer) then it has been * removed. * *\li This function does *not* ensure that the template string has not been * modified, even if the operation was unsuccessful. * * Returns: *\li #ISC_R_SUCCESS * Success. *\li #ISC_R_EXISTS * No file with a unique name could be created based on the * template. *\li #ISC_R_INVALIDFILE * The path specified was not usable by the operating system. *\li #ISC_R_NOPERM * The file could not be created because permission was denied * to some part of the file's path. *\li #ISC_R_IOERROR * Hardware error interacting with the filesystem. *\li #ISC_R_UNEXPECTED * Something totally unexpected happened. */ isc_result_t isc_file_remove(const char *filename); /*!< * \brief Remove the file named by 'filename'. */ isc_result_t isc_file_rename(const char *oldname, const char *newname); /*!< * \brief Rename the file 'oldname' to 'newname'. */ isc_boolean_t isc_file_exists(const char *pathname); /*!< * \brief Return #ISC_TRUE if the calling process can tell that the given file exists. * Will not return true if the calling process has insufficient privileges * to search the entire path. */ isc_boolean_t isc_file_isabsolute(const char *filename); /*!< * \brief Return #ISC_TRUE if the given file name is absolute. */ isc_result_t isc_file_isplainfile(const char *name); isc_result_t isc_file_isplainfilefd(int fd); /*!< * \brief Check that the file is a plain file * * Returns: *\li #ISC_R_SUCCESS * Success. The file is a plain file. *\li #ISC_R_INVALIDFILE * The path specified was not usable by the operating system. *\li #ISC_R_FILENOTFOUND * The file does not exist. This return code comes from * errno=ENOENT when stat returns -1. This code is mentioned * here, because in logconf.c, it is the one rcode that is * permitted in addition to ISC_R_SUCCESS. This is done since * the next call in logconf.c is to isc_stdio_open(), which * will create the file if it can. *\li other ISC_R_* errors translated from errno * These occur when stat returns -1 and an errno. */ isc_result_t isc_file_isdirectory(const char *name); /*!< * \brief Check that 'name' exists and is a directory. * * Returns: *\li #ISC_R_SUCCESS * Success, file is a directory. *\li #ISC_R_INVALIDFILE * File is not a directory. *\li #ISC_R_FILENOTFOUND * File does not exist. *\li other ISC_R_* errors translated from errno * These occur when stat returns -1 and an errno. */ isc_boolean_t isc_file_iscurrentdir(const char *filename); /*!< * \brief Return #ISC_TRUE if the given file name is the current directory ("."). */ isc_boolean_t isc_file_ischdiridempotent(const char *filename); /*%< * Return #ISC_TRUE if calling chdir(filename) multiple times will give * the same result as calling it once. */ const char * isc_file_basename(const char *filename); /*%< * Return the final component of the path in the file name. */ isc_result_t isc_file_progname(const char *filename, char *buf, size_t buflen); /*!< * \brief Given an operating system specific file name "filename" * referring to a program, return the canonical program name. * * * Any directory prefix or executable file name extension (if * used on the OS in case) is stripped. On systems where program * names are case insensitive, the name is canonicalized to all * lower case. The name is written to 'buf', an array of 'buflen' * chars, and null terminated. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOSPACE The name did not fit in 'buf'. */ isc_result_t isc_file_template(const char *path, const char *templet, char *buf, size_t buflen); /*%< * Create an OS specific template using 'path' to define the directory * 'templet' to describe the filename and store the result in 'buf' * such that path can be renamed to buf atomically. */ isc_result_t isc_file_renameunique(const char *file, char *templet); /*%< * Rename 'file' using 'templet' as a template for the new file name. */ isc_result_t isc_file_absolutepath(const char *filename, char *path, size_t pathlen); /*%< * Given a file name, return the fully qualified path to the file. */ /* * XXX We should also have a isc_file_writeeopen() function * for safely open a file in a publicly writable directory * (see write_open() in BIND 8's ns_config.c). */ isc_result_t isc_file_truncate(const char *filename, isc_offset_t size); /*%< * Truncate/extend the file specified to 'size' bytes. */ isc_result_t isc_file_safecreate(const char *filename, FILE **fp); /*%< * Open 'filename' for writing, truncating if necessary. Ensure that * if it existed it was a normal file. If creating the file, ensure * that only the owner can read/write it. */ isc_result_t isc_file_splitpath(isc_mem_t *mctx, char *path, char **dirname, char **basename); /*%< * Split a path into dirname and basename. If 'path' contains no slash * (or, on windows, backslash), then '*dirname' is set to ".". * * Allocates memory for '*dirname', which can be freed with isc_mem_free(). * * Returns: * - ISC_R_SUCCESS on success * - ISC_R_INVALIDFILE if 'path' is empty or ends with '/' * - ISC_R_NOMEMORY if unable to allocate memory */ isc_result_t isc_file_getsize(const char *file, off_t *size); /*%< * Return the size of the file (stored in the parameter pointed * to by 'size') in bytes. * * Returns: * - ISC_R_SUCCESS on success */ isc_result_t isc_file_getsizefd(int fd, off_t *size); /*%< * Return the size of the file (stored in the parameter pointed * to by 'size') in bytes. * * Returns: * - ISC_R_SUCCESS on success */ void * isc_file_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset); /*%< * Portable front-end to mmap(). If mmap() is not defined on this * platform, then we simulate it by calling malloc() and read(). * (In this event, the addr, prot, and flags parameters are ignored). */ int isc_file_munmap(void *addr, size_t len); /*%< * Portable front-end to munmap(). If munmap() is not defined on * this platform, then we simply free the memory. */ ISC_LANG_ENDDECLS #endif /* ISC_FILE_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/fsaccess.h0000644000470500017500000001742212664710322021067 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: fsaccess.h,v 1.16 2009/01/17 23:47:43 tbox Exp $ */ #ifndef ISC_FSACCESS_H #define ISC_FSACCESS_H 1 /*! \file isc/fsaccess.h * \brief The ISC filesystem access module encapsulates the setting of file * and directory access permissions into one API that is meant to be * portable to multiple operating systems. * * The two primary operating system flavors that are initially accommodated * are POSIX and Windows NT 4.0 and later. The Windows NT access model is * considerable more flexible than POSIX's model (as much as I am loathe to * admit it), and so the ISC API has a higher degree of complexity than would * be needed to simply address POSIX's needs. * * The full breadth of NT's flexibility is not available either, for the * present time. Much of it is to provide compatibility with what Unix * programmers are expecting. This is also due to not yet really needing all * of the functionality of an NT system (or, for that matter, a POSIX system) * in BIND9, and so resolving how to handle the various incompatibilities has * been a purely theoretical exercise with no operational experience to * indicate how flawed the thinking may be. * * Some of the more notable dumbing down of NT for this API includes: * *\li Each of FILE_READ_DATA and FILE_READ_EA are set with #ISC_FSACCESS_READ. * * \li All of FILE_WRITE_DATA, FILE_WRITE_EA and FILE_APPEND_DATA are * set with #ISC_FSACCESS_WRITE. FILE_WRITE_ATTRIBUTES is not set * so as to be consistent with Unix, where only the owner of the file * or the superuser can change the attributes/mode of a file. * * \li Both of FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY are set with * #ISC_FSACCESS_CREATECHILD. This is similar to setting the WRITE * permission on a Unix directory. * * \li SYNCHRONIZE is always set for files and directories, unless someone * can give me a reason why this is a bad idea. * * \li READ_CONTROL and FILE_READ_ATTRIBUTES are always set; this is * consistent with Unix, where any file or directory can be stat()'d * unless the directory path disallows complete access somewhere along * the way. * * \li WRITE_DAC is only set for the owner. This too is consistent with * Unix, and is tighter security than allowing anyone else to be * able to set permissions. * * \li DELETE is only set for the owner. On Unix the ability to delete * a file is controlled by the directory permissions, but it isn't * currently clear to me what happens on NT if the directory has * FILE_DELETE_CHILD set but a file within it does not have DELETE * set. Always setting DELETE on the file/directory for the owner * gives maximum flexibility to the owner without exposing the * file to deletion by others. * * \li WRITE_OWNER is never set. This too is consistent with Unix, * and is also tighter security than allowing anyone to change the * ownership of the file apart from the superu..ahem, Administrator. * * \li Inheritance is set to NO_INHERITANCE. * * Unix's dumbing down includes: * * \li The sticky bit cannot be set. * * \li setuid and setgid cannot be set. * * \li Only regular files and directories can be set. * * The rest of this comment discusses a few of the incompatibilities * between the two systems that need more thought if this API is to * be extended to accommodate them. * * The Windows standard access right "DELETE" doesn't have a direct * equivalent in the Unix world, so it isn't clear what should be done * with it. * * The Unix sticky bit is not supported. While NT does have a concept * of allowing users to create files in a directory but not delete or * rename them, it does not have a concept of allowing them to be deleted * if they are owned by the user trying to delete/rename. While it is * probable that something could be cobbled together in NT 5 with inheritance, * it can't really be done in NT 4 as a single property that you could * set on a directory. You'd need to coordinate something with file creation * so that every file created had DELETE set for the owner but noone else. * * On Unix systems, setting #ISC_FSACCESS_LISTDIRECTORY sets READ. * ... setting either #ISC_FSACCESS_CREATECHILD or #ISC_FSACCESS_DELETECHILD * sets WRITE. * ... setting #ISC_FSACCESS_ACCESSCHILD sets EXECUTE. * * On NT systems, setting #ISC_FSACCESS_LISTDIRECTORY sets FILE_LIST_DIRECTORY. * ... setting #ISC_FSACCESS_CREATECHILD sets FILE_CREATE_CHILD independently. * ... setting #ISC_FSACCESS_DELETECHILD sets FILE_DELETE_CHILD independently. * ... setting #ISC_FSACCESS_ACCESSCHILD sets FILE_TRAVERSE. * * Unresolved: XXXDCL * \li What NT access right controls the ability to rename a file? * \li How does DELETE work? If a directory has FILE_DELETE_CHILD but a * file or directory within it does not have DELETE, is that file * or directory deletable? * \li To implement isc_fsaccess_get(), mapping an existing Unix permission * mode_t back to an isc_fsaccess_t is pretty trivial; however, mapping * an NT DACL could be impossible to do in a responsible way. * \li Similarly, trying to implement the functionality of being able to * say "add group writability to whatever permissions already exist" * could be tricky on NT because of the order-of-entry issue combined * with possibly having one or more matching ACEs already explicitly * granting or denying access. Because this functionality is * not yet needed by the ISC, no code has been written to try to * solve this problem. */ #include #include /* * Trustees. */ #define ISC_FSACCESS_OWNER 0x1 /*%< User account. */ #define ISC_FSACCESS_GROUP 0x2 /*%< Primary group owner. */ #define ISC_FSACCESS_OTHER 0x4 /*%< Not the owner or the group owner. */ #define ISC_FSACCESS_WORLD 0x7 /*%< User, Group, Other. */ /* * Types of permission. */ #define ISC_FSACCESS_READ 0x00000001 /*%< File only. */ #define ISC_FSACCESS_WRITE 0x00000002 /*%< File only. */ #define ISC_FSACCESS_EXECUTE 0x00000004 /*%< File only. */ #define ISC_FSACCESS_CREATECHILD 0x00000008 /*%< Dir only. */ #define ISC_FSACCESS_DELETECHILD 0x00000010 /*%< Dir only. */ #define ISC_FSACCESS_LISTDIRECTORY 0x00000020 /*%< Dir only. */ #define ISC_FSACCESS_ACCESSCHILD 0x00000040 /*%< Dir only. */ /*% * Adding any permission bits beyond 0x200 would mean typedef'ing * isc_fsaccess_t as isc_uint64_t, and redefining this value to * reflect the new range of permission types, Probably to 21 for * maximum flexibility. The number of bits has to accommodate all of * the permission types, and three full sets of them have to fit * within an isc_fsaccess_t. */ #define ISC__FSACCESS_PERMISSIONBITS 10 ISC_LANG_BEGINDECLS void isc_fsaccess_add(int trustee, int permission, isc_fsaccess_t *access); void isc_fsaccess_remove(int trustee, int permission, isc_fsaccess_t *access); isc_result_t isc_fsaccess_set(const char *path, isc_fsaccess_t access); ISC_LANG_ENDDECLS #endif /* ISC_FSACCESS_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/aes.h0000644000470500017500000000272512664710322020045 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file isc/aes.h */ #ifndef ISC_AES_H #define ISC_AES_H 1 #include #include #include #define ISC_AES128_KEYLENGTH 16U #define ISC_AES192_KEYLENGTH 24U #define ISC_AES256_KEYLENGTH 32U #define ISC_AES_BLOCK_LENGTH 16U #ifdef ISC_PLATFORM_WANTAES ISC_LANG_BEGINDECLS void isc_aes128_crypt(const unsigned char *key, const unsigned char *in, unsigned char *out); void isc_aes192_crypt(const unsigned char *key, const unsigned char *in, unsigned char *out); void isc_aes256_crypt(const unsigned char *key, const unsigned char *in, unsigned char *out); ISC_LANG_ENDDECLS #endif /* ISC_PLATFORM_WANTAES */ #endif /* ISC_AES_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/bind9.h0000644000470500017500000000244212664710322020276 0ustar lamontlamont/* * Copyright (C) 2009, 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: bind9.h,v 1.2 2009/12/05 23:31:41 each Exp $ */ #ifndef ISC_BIND9_H #define ISC_BIND9_H 1 #include #include /* * This determines whether we are using the libisc/libdns libraries * in BIND9 or in some other application. For BIND9 (named and related * tools) it must be set to ISC_TRUE at runtime. Export library clients * will call isc_lib_register(), which will set it to ISC_FALSE. */ LIBISC_EXTERNAL_DATA extern isc_boolean_t isc_bind9; #endif /* ISC_BIND9_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/refcount.h0000644000470500017500000001407312664710322021121 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: refcount.h,v 1.17 2009/09/29 23:48:04 tbox Exp $ */ #ifndef ISC_REFCOUNT_H #define ISC_REFCOUNT_H 1 #include #include #include #include #include #include /*! \file isc/refcount.h * \brief Implements a locked reference counter. * * These functions may actually be * implemented using macros, and implementations of these macros are below. * The isc_refcount_t type should not be accessed directly, as its contents * depend on the implementation. */ ISC_LANG_BEGINDECLS /* * Function prototypes */ /* * isc_result_t * isc_refcount_init(isc_refcount_t *ref, unsigned int n); * * Initialize the reference counter. There will be 'n' initial references. * * Requires: * ref != NULL */ /* * void * isc_refcount_destroy(isc_refcount_t *ref); * * Destroys a reference counter. * * Requires: * ref != NULL * The number of references is 0. */ /* * void * isc_refcount_increment(isc_refcount_t *ref, unsigned int *targetp); * isc_refcount_increment0(isc_refcount_t *ref, unsigned int *targetp); * * Increments the reference count, returning the new value in targetp if it's * not NULL. The reference counter typically begins with the initial counter * of 1, and will be destroyed once the counter reaches 0. Thus, * isc_refcount_increment() additionally requires the previous counter be * larger than 0 so that an error which violates the usage can be easily * caught. isc_refcount_increment0() does not have this restriction. * * Requires: * ref != NULL. */ /* * void * isc_refcount_decrement(isc_refcount_t *ref, unsigned int *targetp); * * Decrements the reference count, returning the new value in targetp if it's * not NULL. * * Requires: * ref != NULL. */ /* * Sample implementations */ #ifdef ISC_PLATFORM_USETHREADS #ifdef ISC_PLATFORM_HAVEXADD #define ISC_REFCOUNT_HAVEATOMIC 1 typedef struct isc_refcount { isc_int32_t refs; } isc_refcount_t; #define isc_refcount_destroy(rp) REQUIRE((rp)->refs == 0) #define isc_refcount_current(rp) ((unsigned int)((rp)->refs)) #define isc_refcount_increment0(rp, tp) \ do { \ unsigned int *_tmp = (unsigned int *)(tp); \ isc_int32_t prev; \ prev = isc_atomic_xadd(&(rp)->refs, 1); \ if (_tmp != NULL) \ *_tmp = prev + 1; \ } while (0) #define isc_refcount_increment(rp, tp) \ do { \ unsigned int *_tmp = (unsigned int *)(tp); \ isc_int32_t prev; \ prev = isc_atomic_xadd(&(rp)->refs, 1); \ REQUIRE(prev > 0); \ if (_tmp != NULL) \ *_tmp = prev + 1; \ } while (0) #define isc_refcount_decrement(rp, tp) \ do { \ unsigned int *_tmp = (unsigned int *)(tp); \ isc_int32_t prev; \ prev = isc_atomic_xadd(&(rp)->refs, -1); \ REQUIRE(prev > 0); \ if (_tmp != NULL) \ *_tmp = prev - 1; \ } while (0) #else /* ISC_PLATFORM_HAVEXADD */ typedef struct isc_refcount { int refs; isc_mutex_t lock; } isc_refcount_t; /*% Destroys a reference counter. */ #define isc_refcount_destroy(rp) \ do { \ REQUIRE((rp)->refs == 0); \ DESTROYLOCK(&(rp)->lock); \ } while (0) #define isc_refcount_current(rp) ((unsigned int)((rp)->refs)) /*% Increments the reference count, returning the new value in targetp if it's not NULL. */ #define isc_refcount_increment0(rp, tp) \ do { \ unsigned int *_tmp = (unsigned int *)(tp); \ LOCK(&(rp)->lock); \ ++((rp)->refs); \ if (_tmp != NULL) \ *_tmp = ((rp)->refs); \ UNLOCK(&(rp)->lock); \ } while (0) #define isc_refcount_increment(rp, tp) \ do { \ unsigned int *_tmp = (unsigned int *)(tp); \ LOCK(&(rp)->lock); \ REQUIRE((rp)->refs > 0); \ ++((rp)->refs); \ if (_tmp != NULL) \ *_tmp = ((rp)->refs); \ UNLOCK(&(rp)->lock); \ } while (0) /*% Decrements the reference count, returning the new value in targetp if it's not NULL. */ #define isc_refcount_decrement(rp, tp) \ do { \ unsigned int *_tmp = (unsigned int *)(tp); \ LOCK(&(rp)->lock); \ REQUIRE((rp)->refs > 0); \ --((rp)->refs); \ if (_tmp != NULL) \ *_tmp = ((rp)->refs); \ UNLOCK(&(rp)->lock); \ } while (0) #endif /* ISC_PLATFORM_HAVEXADD */ #else /* ISC_PLATFORM_USETHREADS */ typedef struct isc_refcount { int refs; } isc_refcount_t; #define isc_refcount_destroy(rp) REQUIRE((rp)->refs == 0) #define isc_refcount_current(rp) ((unsigned int)((rp)->refs)) #define isc_refcount_increment0(rp, tp) \ do { \ unsigned int *_tmp = (unsigned int *)(tp); \ int _n = ++(rp)->refs; \ if (_tmp != NULL) \ *_tmp = _n; \ } while (0) #define isc_refcount_increment(rp, tp) \ do { \ unsigned int *_tmp = (unsigned int *)(tp); \ int _n; \ REQUIRE((rp)->refs > 0); \ _n = ++(rp)->refs; \ if (_tmp != NULL) \ *_tmp = _n; \ } while (0) #define isc_refcount_decrement(rp, tp) \ do { \ unsigned int *_tmp = (unsigned int *)(tp); \ int _n; \ REQUIRE((rp)->refs > 0); \ _n = --(rp)->refs; \ if (_tmp != NULL) \ *_tmp = _n; \ } while (0) #endif /* ISC_PLATFORM_USETHREADS */ isc_result_t isc_refcount_init(isc_refcount_t *ref, unsigned int n); ISC_LANG_ENDDECLS #endif /* ISC_REFCOUNT_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/eventclass.h0000644000470500017500000000357312664710322021446 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: eventclass.h,v 1.18 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_EVENTCLASS_H #define ISC_EVENTCLASS_H 1 /*! \file isc/eventclass.h ***** Registry of Predefined Event Type Classes *****/ /*% * An event class is an unsigned 16 bit number. Each class may contain up * to 65536 events. An event type is formed by adding the event number * within the class to the class number. * */ #define ISC_EVENTCLASS(eclass) ((eclass) << 16) /*@{*/ /*! * Classes < 1024 are reserved for ISC use. * Event classes >= 1024 and <= 65535 are reserved for application use. */ #define ISC_EVENTCLASS_TASK ISC_EVENTCLASS(0) #define ISC_EVENTCLASS_TIMER ISC_EVENTCLASS(1) #define ISC_EVENTCLASS_SOCKET ISC_EVENTCLASS(2) #define ISC_EVENTCLASS_FILE ISC_EVENTCLASS(3) #define ISC_EVENTCLASS_DNS ISC_EVENTCLASS(4) #define ISC_EVENTCLASS_APP ISC_EVENTCLASS(5) #define ISC_EVENTCLASS_OMAPI ISC_EVENTCLASS(6) #define ISC_EVENTCLASS_RATELIMITER ISC_EVENTCLASS(7) #define ISC_EVENTCLASS_ISCCC ISC_EVENTCLASS(8) /*@}*/ #endif /* ISC_EVENTCLASS_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/boolean.h0000644000470500017500000000227412664710322020713 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: boolean.h,v 1.19 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_BOOLEAN_H #define ISC_BOOLEAN_H 1 /*! \file isc/boolean.h */ typedef enum { isc_boolean_false = 0, isc_boolean_true = 1 } isc_boolean_t; #define ISC_FALSE isc_boolean_false #define ISC_TRUE isc_boolean_true #define ISC_TF(x) ((x) ? ISC_TRUE : ISC_FALSE) #endif /* ISC_BOOLEAN_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/resultclass.h0000644000470500017500000000413312664710322021634 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: resultclass.h,v 1.20 2009/09/02 23:48:03 tbox Exp $ */ #ifndef ISC_RESULTCLASS_H #define ISC_RESULTCLASS_H 1 /*! \file isc/resultclass.h * \brief Registry of Predefined Result Type Classes * * A result class number is an unsigned 16 bit number. Each class may * contain up to 65536 results. A result code is formed by adding the * result number within the class to the class number multiplied by 65536. * * Classes < 1024 are reserved for ISC use. * Result classes >= 1024 and <= 65535 are reserved for application use. */ #define ISC_RESULTCLASS_FROMNUM(num) ((num) << 16) #define ISC_RESULTCLASS_TONUM(rclass) ((rclass) >> 16) #define ISC_RESULTCLASS_SIZE 65536 #define ISC_RESULTCLASS_INCLASS(rclass, result) \ ((rclass) == ((result) & 0xFFFF0000)) #define ISC_RESULTCLASS_ISC ISC_RESULTCLASS_FROMNUM(0) #define ISC_RESULTCLASS_DNS ISC_RESULTCLASS_FROMNUM(1) #define ISC_RESULTCLASS_DST ISC_RESULTCLASS_FROMNUM(2) #define ISC_RESULTCLASS_DNSRCODE ISC_RESULTCLASS_FROMNUM(3) #define ISC_RESULTCLASS_OMAPI ISC_RESULTCLASS_FROMNUM(4) #define ISC_RESULTCLASS_ISCCC ISC_RESULTCLASS_FROMNUM(5) #define ISC_RESULTCLASS_DHCP ISC_RESULTCLASS_FROMNUM(6) #define ISC_RESULTCLASS_PK11 ISC_RESULTCLASS_FROMNUM(7) #endif /* ISC_RESULTCLASS_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/mutexblock.h0000644000470500017500000000355612664710322021455 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: mutexblock.h,v 1.17 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_MUTEXBLOCK_H #define ISC_MUTEXBLOCK_H 1 /*! \file isc/mutexblock.h */ #include #include #include ISC_LANG_BEGINDECLS isc_result_t isc_mutexblock_init(isc_mutex_t *block, unsigned int count); /*%< * Initialize a block of locks. If an error occurs all initialized locks * will be destroyed, if possible. * * Requires: * *\li block != NULL * *\li count > 0 * * Returns: * *\li Any code isc_mutex_init() can return is a valid return for this * function. */ isc_result_t isc_mutexblock_destroy(isc_mutex_t *block, unsigned int count); /*%< * Destroy a block of locks. * * Requires: * *\li block != NULL * *\li count > 0 * *\li Each lock in the block be initialized via isc_mutex_init() or * the whole block was initialized via isc_mutex_initblock(). * * Returns: * *\li Any code isc_mutex_init() can return is a valid return for this * function. */ ISC_LANG_ENDDECLS #endif /* ISC_MUTEXBLOCK_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/buffer.h0000644000470500017500000005463312664710322020553 0ustar lamontlamont/* * Copyright (C) 2004-2008, 2010, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: buffer.h,v 1.55 2010/12/20 23:47:21 tbox Exp $ */ #ifndef ISC_BUFFER_H #define ISC_BUFFER_H 1 /***** ***** Module Info *****/ /*! \file isc/buffer.h * * \brief A buffer is a region of memory, together with a set of related subregions. * Buffers are used for parsing and I/O operations. * * The 'used region' and the 'available' region are disjoint, and their * union is the buffer's region. The used region extends from the beginning * of the buffer region to the last used byte. The available region * extends from one byte greater than the last used byte to the end of the * buffer's region. The size of the used region can be changed using various * buffer commands. Initially, the used region is empty. * * The used region is further subdivided into two disjoint regions: the * 'consumed region' and the 'remaining region'. The union of these two * regions is the used region. The consumed region extends from the beginning * of the used region to the byte before the 'current' offset (if any). The * 'remaining' region the current pointer to the end of the used * region. The size of the consumed region can be changed using various * buffer commands. Initially, the consumed region is empty. * * The 'active region' is an (optional) subregion of the remaining region. * It extends from the current offset to an offset in the remaining region * that is selected with isc_buffer_setactive(). Initially, the active region * is empty. If the current offset advances beyond the chosen offset, the * active region will also be empty. * * \verbatim * /------------entire length---------------\ * /----- used region -----\/-- available --\ * +----------------------------------------+ * | consumed | remaining | | * +----------------------------------------+ * a b c d e * * a == base of buffer. * b == current pointer. Can be anywhere between a and d. * c == active pointer. Meaningful between b and d. * d == used pointer. * e == length of buffer. * * a-e == entire length of buffer. * a-d == used region. * a-b == consumed region. * b-d == remaining region. * b-c == optional active region. *\endverbatim * * The following invariants are maintained by all routines: * *\code * length > 0 * * base is a valid pointer to length bytes of memory * * 0 <= used <= length * * 0 <= current <= used * * 0 <= active <= used * (although active < current implies empty active region) *\endcode * * \li MP: * Buffers have no synchronization. Clients must ensure exclusive * access. * * \li Reliability: * No anticipated impact. * * \li Resources: * Memory: 1 pointer + 6 unsigned integers per buffer. * * \li Security: * No anticipated impact. * * \li Standards: * None. */ /*** *** Imports ***/ #include #include #include /*! * To make many functions be inline macros (via \#define) define this. * If it is undefined, a function will be used. */ /* #define ISC_BUFFER_USEINLINE */ ISC_LANG_BEGINDECLS /*@{*/ /*! *** Magic numbers ***/ #define ISC_BUFFER_MAGIC 0x42756621U /* Buf!. */ #define ISC_BUFFER_VALID(b) ISC_MAGIC_VALID(b, ISC_BUFFER_MAGIC) /*@}*/ /* * The following macros MUST be used only on valid buffers. It is the * caller's responsibility to ensure this by using the ISC_BUFFER_VALID * check above, or by calling another isc_buffer_*() function (rather than * another macro.) */ /*@{*/ /*! * Fundamental buffer elements. (A through E in the introductory comment.) */ #define isc_buffer_base(b) ((void *)(b)->base) /*a*/ #define isc_buffer_current(b) \ ((void *)((unsigned char *)(b)->base + (b)->current)) /*b*/ #define isc_buffer_active(b) \ ((void *)((unsigned char *)(b)->base + (b)->active)) /*c*/ #define isc_buffer_used(b) \ ((void *)((unsigned char *)(b)->base + (b)->used)) /*d*/ #define isc_buffer_length(b) ((b)->length) /*e*/ /*@}*/ /*@{*/ /*! * Derived lengths. (Described in the introductory comment.) */ #define isc_buffer_usedlength(b) ((b)->used) /* d-a */ #define isc_buffer_consumedlength(b) ((b)->current) /* b-a */ #define isc_buffer_remaininglength(b) ((b)->used - (b)->current) /* d-b */ #define isc_buffer_activelength(b) ((b)->active - (b)->current) /* c-b */ #define isc_buffer_availablelength(b) ((b)->length - (b)->used) /* e-d */ /*@}*/ /*! * Note that the buffer structure is public. This is principally so buffer * operations can be implemented using macros. Applications are strongly * discouraged from directly manipulating the structure. */ struct isc_buffer { unsigned int magic; void *base; /*@{*/ /*! The following integers are byte offsets from 'base'. */ unsigned int length; unsigned int used; unsigned int current; unsigned int active; /*@}*/ /*! linkable */ ISC_LINK(isc_buffer_t) link; /*! private internal elements */ isc_mem_t *mctx; }; /*** *** Functions ***/ isc_result_t isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer, unsigned int length); /*!< * \brief Allocate a dynamic linkable buffer which has "length" bytes in the * data region. * * Requires: *\li "mctx" is valid. * *\li "dynbuffer" is non-NULL, and "*dynbuffer" is NULL. * * Returns: *\li ISC_R_SUCCESS - success *\li ISC_R_NOMEMORY - no memory available * * Note: *\li Changing the buffer's length field is not permitted. */ void isc_buffer_free(isc_buffer_t **dynbuffer); /*!< * \brief Release resources allocated for a dynamic buffer. * * Requires: *\li "dynbuffer" is not NULL. * *\li "*dynbuffer" is a valid dynamic buffer. * * Ensures: *\li "*dynbuffer" will be NULL on return, and all memory associated with * the dynamic buffer is returned to the memory context used in * isc_buffer_allocate(). */ void isc__buffer_init(isc_buffer_t *b, void *base, unsigned int length); /*!< * \brief Make 'b' refer to the 'length'-byte region starting at base. * * Requires: * *\li 'length' > 0 * *\li 'base' is a pointer to a sequence of 'length' bytes. * */ void isc__buffer_initnull(isc_buffer_t *b); /*!< *\brief Initialize a buffer 'b' with a null data and zero length/ */ void isc_buffer_reinit(isc_buffer_t *b, void *base, unsigned int length); /*!< * \brief Make 'b' refer to the 'length'-byte region starting at base. * Any existing data will be copied. * * Requires: * *\li 'length' > 0 AND length >= previous length * *\li 'base' is a pointer to a sequence of 'length' bytes. * */ void isc__buffer_invalidate(isc_buffer_t *b); /*!< * \brief Make 'b' an invalid buffer. * * Requires: *\li 'b' is a valid buffer. * * Ensures: *\li If assertion checking is enabled, future attempts to use 'b' without * calling isc_buffer_init() on it will cause an assertion failure. */ void isc__buffer_region(isc_buffer_t *b, isc_region_t *r); /*!< * \brief Make 'r' refer to the region of 'b'. * * Requires: * *\li 'b' is a valid buffer. * *\li 'r' points to a region structure. */ void isc__buffer_usedregion(isc_buffer_t *b, isc_region_t *r); /*!< * \brief Make 'r' refer to the used region of 'b'. * * Requires: * *\li 'b' is a valid buffer. * *\li 'r' points to a region structure. */ void isc__buffer_availableregion(isc_buffer_t *b, isc_region_t *r); /*!< * \brief Make 'r' refer to the available region of 'b'. * * Requires: * *\li 'b' is a valid buffer. * *\li 'r' points to a region structure. */ void isc__buffer_add(isc_buffer_t *b, unsigned int n); /*!< * \brief Increase the 'used' region of 'b' by 'n' bytes. * * Requires: * *\li 'b' is a valid buffer * *\li used + n <= length * */ void isc__buffer_subtract(isc_buffer_t *b, unsigned int n); /*!< * \brief Decrease the 'used' region of 'b' by 'n' bytes. * * Requires: * *\li 'b' is a valid buffer * *\li used >= n * */ void isc__buffer_clear(isc_buffer_t *b); /*!< * \brief Make the used region empty. * * Requires: * *\li 'b' is a valid buffer * * Ensures: * *\li used = 0 * */ void isc__buffer_consumedregion(isc_buffer_t *b, isc_region_t *r); /*!< * \brief Make 'r' refer to the consumed region of 'b'. * * Requires: * *\li 'b' is a valid buffer. * *\li 'r' points to a region structure. */ void isc__buffer_remainingregion(isc_buffer_t *b, isc_region_t *r); /*!< * \brief Make 'r' refer to the remaining region of 'b'. * * Requires: * *\li 'b' is a valid buffer. * *\li 'r' points to a region structure. */ void isc__buffer_activeregion(isc_buffer_t *b, isc_region_t *r); /*!< * \brief Make 'r' refer to the active region of 'b'. * * Requires: * *\li 'b' is a valid buffer. * *\li 'r' points to a region structure. */ void isc__buffer_setactive(isc_buffer_t *b, unsigned int n); /*!< * \brief Sets the end of the active region 'n' bytes after current. * * Requires: * *\li 'b' is a valid buffer. * *\li current + n <= used */ void isc__buffer_first(isc_buffer_t *b); /*!< * \brief Make the consumed region empty. * * Requires: * *\li 'b' is a valid buffer * * Ensures: * *\li current == 0 * */ void isc__buffer_forward(isc_buffer_t *b, unsigned int n); /*!< * \brief Increase the 'consumed' region of 'b' by 'n' bytes. * * Requires: * *\li 'b' is a valid buffer * *\li current + n <= used * */ void isc__buffer_back(isc_buffer_t *b, unsigned int n); /*!< * \brief Decrease the 'consumed' region of 'b' by 'n' bytes. * * Requires: * *\li 'b' is a valid buffer * *\li n <= current * */ void isc_buffer_compact(isc_buffer_t *b); /*!< * \brief Compact the used region by moving the remaining region so it occurs * at the start of the buffer. The used region is shrunk by the size of * the consumed region, and the consumed region is then made empty. * * Requires: * *\li 'b' is a valid buffer * * Ensures: * *\li current == 0 * *\li The size of the used region is now equal to the size of the remaining * region (as it was before the call). The contents of the used region * are those of the remaining region (as it was before the call). */ isc_uint8_t isc_buffer_getuint8(isc_buffer_t *b); /*!< * \brief Read an unsigned 8-bit integer from 'b' and return it. * * Requires: * *\li 'b' is a valid buffer. * *\li The length of the available region of 'b' is at least 1. * * Ensures: * *\li The current pointer in 'b' is advanced by 1. * * Returns: * *\li A 8-bit unsigned integer. */ void isc__buffer_putuint8(isc_buffer_t *b, isc_uint8_t val); /*!< * \brief Store an unsigned 8-bit integer from 'val' into 'b'. * * Requires: *\li 'b' is a valid buffer. * *\li The length of the unused region of 'b' is at least 1. * * Ensures: *\li The used pointer in 'b' is advanced by 1. */ isc_uint16_t isc_buffer_getuint16(isc_buffer_t *b); /*!< * \brief Read an unsigned 16-bit integer in network byte order from 'b', convert * it to host byte order, and return it. * * Requires: * *\li 'b' is a valid buffer. * *\li The length of the available region of 'b' is at least 2. * * Ensures: * *\li The current pointer in 'b' is advanced by 2. * * Returns: * *\li A 16-bit unsigned integer. */ void isc__buffer_putuint16(isc_buffer_t *b, isc_uint16_t val); /*!< * \brief Store an unsigned 16-bit integer in host byte order from 'val' * into 'b' in network byte order. * * Requires: *\li 'b' is a valid buffer. * *\li The length of the unused region of 'b' is at least 2. * * Ensures: *\li The used pointer in 'b' is advanced by 2. */ isc_uint32_t isc_buffer_getuint32(isc_buffer_t *b); /*!< * \brief Read an unsigned 32-bit integer in network byte order from 'b', convert * it to host byte order, and return it. * * Requires: * *\li 'b' is a valid buffer. * *\li The length of the available region of 'b' is at least 4. * * Ensures: * *\li The current pointer in 'b' is advanced by 4. * * Returns: * *\li A 32-bit unsigned integer. */ void isc__buffer_putuint32(isc_buffer_t *b, isc_uint32_t val); /*!< * \brief Store an unsigned 32-bit integer in host byte order from 'val' * into 'b' in network byte order. * * Requires: *\li 'b' is a valid buffer. * *\li The length of the unused region of 'b' is at least 4. * * Ensures: *\li The used pointer in 'b' is advanced by 4. */ isc_uint64_t isc_buffer_getuint48(isc_buffer_t *b); /*!< * \brief Read an unsigned 48-bit integer in network byte order from 'b', * convert it to host byte order, and return it. * * Requires: * *\li 'b' is a valid buffer. * *\li The length of the available region of 'b' is at least 6. * * Ensures: * *\li The current pointer in 'b' is advanced by 6. * * Returns: * *\li A 48-bit unsigned integer (stored in a 64-bit integer). */ void isc__buffer_putuint48(isc_buffer_t *b, isc_uint64_t val); /*!< * \brief Store an unsigned 48-bit integer in host byte order from 'val' * into 'b' in network byte order. * * Requires: *\li 'b' is a valid buffer. * *\li The length of the unused region of 'b' is at least 6. * * Ensures: *\li The used pointer in 'b' is advanced by 6. */ void isc__buffer_putuint24(isc_buffer_t *b, isc_uint32_t val); /*!< * Store an unsigned 24-bit integer in host byte order from 'val' * into 'b' in network byte order. * * Requires: *\li 'b' is a valid buffer. * * The length of the unused region of 'b' is at least 3. * * Ensures: *\li The used pointer in 'b' is advanced by 3. */ void isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base, unsigned int length); /*!< * \brief Copy 'length' bytes of memory at 'base' into 'b'. * * Requires: *\li 'b' is a valid buffer. * *\li 'base' points to 'length' bytes of valid memory. * */ void isc__buffer_putstr(isc_buffer_t *b, const char *source); /*!< * \brief Copy 'source' into 'b', not including terminating NUL. * * Requires: *\li 'b' is a valid buffer. * *\li 'source' to be a valid NULL terminated string. * *\li strlen(source) <= isc_buffer_available(b) */ isc_result_t isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r); /*!< * \brief Copy the contents of 'r' into 'b'. * * Requires: *\li 'b' is a valid buffer. * *\li 'r' is a valid region. * * Returns: * *\li ISC_R_SUCCESS *\li ISC_R_NOSPACE The available region of 'b' is not * big enough. */ ISC_LANG_ENDDECLS /* * Inline macro versions of the functions. These should never be called * directly by an application, but will be used by the functions within * buffer.c. The callers should always use "isc_buffer_*()" names, never * ones beginning with "isc__" */ /*! \note * XXXDCL Something more could be done with initializing buffers that * point to const data. For example, isc_buffer_constinit() could * set a new boolean flag in the buffer structure indicating whether * the buffer was initialized with that function. * Then if the * boolean were true, the isc_buffer_put* functions could assert a * contractual requirement for a non-const buffer. * * One drawback is that the isc_buffer_* functions (macros) that return * pointers would still need to return non-const pointers to avoid compiler * warnings, so it would be up to code that uses them to have to deal * with the possibility that the buffer was initialized as const -- * a problem that they *already* have to deal with but have absolutely * no ability to. With a new isc_buffer_isconst() function returning * true/false, they could at least assert a contractual requirement for * non-const buffers when needed. */ #define ISC__BUFFER_INIT(_b, _base, _length) \ do { \ (_b)->base = _base; \ (_b)->length = (_length); \ (_b)->used = 0; \ (_b)->current = 0; \ (_b)->active = 0; \ (_b)->mctx = NULL; \ ISC_LINK_INIT(_b, link); \ (_b)->magic = ISC_BUFFER_MAGIC; \ } while (0) #define ISC__BUFFER_INITNULL(_b) ISC__BUFFER_INIT(_b, NULL, 0) #define ISC__BUFFER_INVALIDATE(_b) \ do { \ (_b)->magic = 0; \ (_b)->base = NULL; \ (_b)->length = 0; \ (_b)->used = 0; \ (_b)->current = 0; \ (_b)->active = 0; \ } while (0) #define ISC__BUFFER_REGION(_b, _r) \ do { \ (_r)->base = (_b)->base; \ (_r)->length = (_b)->length; \ } while (0) #define ISC__BUFFER_USEDREGION(_b, _r) \ do { \ (_r)->base = (_b)->base; \ (_r)->length = (_b)->used; \ } while (0) #define ISC__BUFFER_AVAILABLEREGION(_b, _r) \ do { \ (_r)->base = isc_buffer_used(_b); \ (_r)->length = isc_buffer_availablelength(_b); \ } while (0) #define ISC__BUFFER_ADD(_b, _n) \ do { \ (_b)->used += (_n); \ } while (0) #define ISC__BUFFER_SUBTRACT(_b, _n) \ do { \ (_b)->used -= (_n); \ if ((_b)->current > (_b)->used) \ (_b)->current = (_b)->used; \ if ((_b)->active > (_b)->used) \ (_b)->active = (_b)->used; \ } while (0) #define ISC__BUFFER_CLEAR(_b) \ do { \ (_b)->used = 0; \ (_b)->current = 0; \ (_b)->active = 0; \ } while (0) #define ISC__BUFFER_CONSUMEDREGION(_b, _r) \ do { \ (_r)->base = (_b)->base; \ (_r)->length = (_b)->current; \ } while (0) #define ISC__BUFFER_REMAININGREGION(_b, _r) \ do { \ (_r)->base = isc_buffer_current(_b); \ (_r)->length = isc_buffer_remaininglength(_b); \ } while (0) #define ISC__BUFFER_ACTIVEREGION(_b, _r) \ do { \ if ((_b)->current < (_b)->active) { \ (_r)->base = isc_buffer_current(_b); \ (_r)->length = isc_buffer_activelength(_b); \ } else { \ (_r)->base = NULL; \ (_r)->length = 0; \ } \ } while (0) #define ISC__BUFFER_SETACTIVE(_b, _n) \ do { \ (_b)->active = (_b)->current + (_n); \ } while (0) #define ISC__BUFFER_FIRST(_b) \ do { \ (_b)->current = 0; \ } while (0) #define ISC__BUFFER_FORWARD(_b, _n) \ do { \ (_b)->current += (_n); \ } while (0) #define ISC__BUFFER_BACK(_b, _n) \ do { \ (_b)->current -= (_n); \ } while (0) #define ISC__BUFFER_PUTMEM(_b, _base, _length) \ do { \ memmove(isc_buffer_used(_b), (_base), (_length)); \ (_b)->used += (_length); \ } while (0) #define ISC__BUFFER_PUTSTR(_b, _source) \ do { \ unsigned int _length; \ unsigned char *_cp; \ _length = strlen(_source); \ _cp = isc_buffer_used(_b); \ memmove(_cp, (_source), _length); \ (_b)->used += (_length); \ } while (0) #define ISC__BUFFER_PUTUINT8(_b, _val) \ do { \ unsigned char *_cp; \ isc_uint8_t _val2 = (_val); \ _cp = isc_buffer_used(_b); \ (_b)->used++; \ _cp[0] = _val2 & 0x00ff; \ } while (0) #define ISC__BUFFER_PUTUINT16(_b, _val) \ do { \ unsigned char *_cp; \ isc_uint16_t _val2 = (_val); \ _cp = isc_buffer_used(_b); \ (_b)->used += 2; \ _cp[0] = (unsigned char)((_val2 & 0xff00U) >> 8); \ _cp[1] = (unsigned char)(_val2 & 0x00ffU); \ } while (0) #define ISC__BUFFER_PUTUINT24(_b, _val) \ do { \ unsigned char *_cp; \ isc_uint32_t _val2 = (_val); \ _cp = isc_buffer_used(_b); \ (_b)->used += 3; \ _cp[0] = (unsigned char)((_val2 & 0xff0000U) >> 16); \ _cp[1] = (unsigned char)((_val2 & 0xff00U) >> 8); \ _cp[2] = (unsigned char)(_val2 & 0x00ffU); \ } while (0) #define ISC__BUFFER_PUTUINT32(_b, _val) \ do { \ unsigned char *_cp; \ isc_uint32_t _val2 = (_val); \ _cp = isc_buffer_used(_b); \ (_b)->used += 4; \ _cp[0] = (unsigned char)((_val2 & 0xff000000) >> 24); \ _cp[1] = (unsigned char)((_val2 & 0x00ff0000) >> 16); \ _cp[2] = (unsigned char)((_val2 & 0x0000ff00) >> 8); \ _cp[3] = (unsigned char)((_val2 & 0x000000ff)); \ } while (0) #if defined(ISC_BUFFER_USEINLINE) #define isc_buffer_init ISC__BUFFER_INIT #define isc_buffer_initnull ISC__BUFFER_INITNULL #define isc_buffer_invalidate ISC__BUFFER_INVALIDATE #define isc_buffer_region ISC__BUFFER_REGION #define isc_buffer_usedregion ISC__BUFFER_USEDREGION #define isc_buffer_availableregion ISC__BUFFER_AVAILABLEREGION #define isc_buffer_add ISC__BUFFER_ADD #define isc_buffer_subtract ISC__BUFFER_SUBTRACT #define isc_buffer_clear ISC__BUFFER_CLEAR #define isc_buffer_consumedregion ISC__BUFFER_CONSUMEDREGION #define isc_buffer_remainingregion ISC__BUFFER_REMAININGREGION #define isc_buffer_activeregion ISC__BUFFER_ACTIVEREGION #define isc_buffer_setactive ISC__BUFFER_SETACTIVE #define isc_buffer_first ISC__BUFFER_FIRST #define isc_buffer_forward ISC__BUFFER_FORWARD #define isc_buffer_back ISC__BUFFER_BACK #define isc_buffer_putmem ISC__BUFFER_PUTMEM #define isc_buffer_putstr ISC__BUFFER_PUTSTR #define isc_buffer_putuint8 ISC__BUFFER_PUTUINT8 #define isc_buffer_putuint16 ISC__BUFFER_PUTUINT16 #define isc_buffer_putuint24 ISC__BUFFER_PUTUINT24 #define isc_buffer_putuint32 ISC__BUFFER_PUTUINT32 #else #define isc_buffer_init isc__buffer_init #define isc_buffer_initnull isc__buffer_initnull #define isc_buffer_invalidate isc__buffer_invalidate #define isc_buffer_region isc__buffer_region #define isc_buffer_usedregion isc__buffer_usedregion #define isc_buffer_availableregion isc__buffer_availableregion #define isc_buffer_add isc__buffer_add #define isc_buffer_subtract isc__buffer_subtract #define isc_buffer_clear isc__buffer_clear #define isc_buffer_consumedregion isc__buffer_consumedregion #define isc_buffer_remainingregion isc__buffer_remainingregion #define isc_buffer_activeregion isc__buffer_activeregion #define isc_buffer_setactive isc__buffer_setactive #define isc_buffer_first isc__buffer_first #define isc_buffer_forward isc__buffer_forward #define isc_buffer_back isc__buffer_back #define isc_buffer_putmem isc__buffer_putmem #define isc_buffer_putstr isc__buffer_putstr #define isc_buffer_putuint8 isc__buffer_putuint8 #define isc_buffer_putuint16 isc__buffer_putuint16 #define isc_buffer_putuint24 isc__buffer_putuint24 #define isc_buffer_putuint32 isc__buffer_putuint32 #endif #define isc_buffer_constinit(_b, _d, _l) \ do { \ union { void *_var; const void *_const; } _deconst; \ _deconst._const = (_d); \ isc_buffer_init((_b), _deconst._var, (_l)); \ } while (0) /* * No inline method for this one (yet). */ #define isc_buffer_putuint48 isc__buffer_putuint48 #endif /* ISC_BUFFER_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/lex.h0000644000470500017500000002266512664710322020072 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lex.h,v 1.37 2008/05/30 23:47:01 tbox Exp $ */ #ifndef ISC_LEX_H #define ISC_LEX_H 1 /***** ***** Module Info *****/ /*! \file isc/lex.h * \brief The "lex" module provides a lightweight tokenizer. It can operate * on files or buffers, and can handle "include". It is designed for * parsing of DNS master files and the BIND configuration file, but * should be general enough to tokenize other things, e.g. HTTP. * * \li MP: * No synchronization is provided. Clients must ensure exclusive * access. * * \li Reliability: * No anticipated impact. * * \li Resources: * TBS * * \li Security: * No anticipated impact. * * \li Standards: * None. */ /*** *** Imports ***/ #include #include #include #include ISC_LANG_BEGINDECLS /*** *** Options ***/ /*@{*/ /*! * Various options for isc_lex_gettoken(). */ #define ISC_LEXOPT_EOL 0x01 /*%< Want end-of-line token. */ #define ISC_LEXOPT_EOF 0x02 /*%< Want end-of-file token. */ #define ISC_LEXOPT_INITIALWS 0x04 /*%< Want initial whitespace. */ #define ISC_LEXOPT_NUMBER 0x08 /*%< Recognize numbers. */ #define ISC_LEXOPT_QSTRING 0x10 /*%< Recognize qstrings. */ /*@}*/ /*@{*/ /*! * The ISC_LEXOPT_DNSMULTILINE option handles the processing of '(' and ')' in * the DNS master file format. If this option is set, then the * ISC_LEXOPT_INITIALWS and ISC_LEXOPT_EOL options will be ignored when * the paren count is > 0. To use this option, '(' and ')' must be special * characters. */ #define ISC_LEXOPT_DNSMULTILINE 0x20 /*%< Handle '(' and ')'. */ #define ISC_LEXOPT_NOMORE 0x40 /*%< Want "no more" token. */ #define ISC_LEXOPT_CNUMBER 0x80 /*%< Recognize octal and hex. */ #define ISC_LEXOPT_ESCAPE 0x100 /*%< Recognize escapes. */ #define ISC_LEXOPT_QSTRINGMULTILINE 0x200 /*%< Allow multiline "" strings */ #define ISC_LEXOPT_OCTAL 0x400 /*%< Expect a octal number. */ /*@}*/ /*@{*/ /*! * Various commenting styles, which may be changed at any time with * isc_lex_setcomments(). */ #define ISC_LEXCOMMENT_C 0x01 #define ISC_LEXCOMMENT_CPLUSPLUS 0x02 #define ISC_LEXCOMMENT_SHELL 0x04 #define ISC_LEXCOMMENT_DNSMASTERFILE 0x08 /*@}*/ /*** *** Types ***/ /*! Lex */ typedef char isc_lexspecials_t[256]; /* Tokens */ typedef enum { isc_tokentype_unknown = 0, isc_tokentype_string = 1, isc_tokentype_number = 2, isc_tokentype_qstring = 3, isc_tokentype_eol = 4, isc_tokentype_eof = 5, isc_tokentype_initialws = 6, isc_tokentype_special = 7, isc_tokentype_nomore = 8 } isc_tokentype_t; typedef union { char as_char; unsigned long as_ulong; isc_region_t as_region; isc_textregion_t as_textregion; void * as_pointer; } isc_tokenvalue_t; typedef struct isc_token { isc_tokentype_t type; isc_tokenvalue_t value; } isc_token_t; /*** *** Functions ***/ isc_result_t isc_lex_create(isc_mem_t *mctx, size_t max_token, isc_lex_t **lexp); /*%< * Create a lexer. * * 'max_token' is a hint of the number of bytes in the largest token. * * Requires: *\li '*lexp' is a valid lexer. * *\li max_token > 0. * * Ensures: *\li On success, *lexp is attached to the newly created lexer. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY */ void isc_lex_destroy(isc_lex_t **lexp); /*%< * Destroy the lexer. * * Requires: *\li '*lexp' is a valid lexer. * * Ensures: *\li *lexp == NULL */ unsigned int isc_lex_getcomments(isc_lex_t *lex); /*%< * Return the current lexer commenting styles. * * Requires: *\li 'lex' is a valid lexer. * * Returns: *\li The commenting sytles which are currently allowed. */ void isc_lex_setcomments(isc_lex_t *lex, unsigned int comments); /*%< * Set allowed lexer commenting styles. * * Requires: *\li 'lex' is a valid lexer. * *\li 'comments' has meaningful values. */ void isc_lex_getspecials(isc_lex_t *lex, isc_lexspecials_t specials); /*%< * Put the current list of specials into 'specials'. * * Requires: *\li 'lex' is a valid lexer. */ void isc_lex_setspecials(isc_lex_t *lex, isc_lexspecials_t specials); /*!< * The characters in 'specials' are returned as tokens. Along with * whitespace, they delimit strings and numbers. * * Note: *\li Comment processing takes precedence over special character * recognition. * * Requires: *\li 'lex' is a valid lexer. */ isc_result_t isc_lex_openfile(isc_lex_t *lex, const char *filename); /*%< * Open 'filename' and make it the current input source for 'lex'. * * Requires: *\li 'lex' is a valid lexer. * *\li filename is a valid C string. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY Out of memory *\li #ISC_R_NOTFOUND File not found *\li #ISC_R_NOPERM No permission to open file *\li #ISC_R_FAILURE Couldn't open file, not sure why *\li #ISC_R_UNEXPECTED */ isc_result_t isc_lex_openstream(isc_lex_t *lex, FILE *stream); /*%< * Make 'stream' the current input source for 'lex'. * * Requires: *\li 'lex' is a valid lexer. * *\li 'stream' is a valid C stream. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY Out of memory */ isc_result_t isc_lex_openbuffer(isc_lex_t *lex, isc_buffer_t *buffer); /*%< * Make 'buffer' the current input source for 'lex'. * * Requires: *\li 'lex' is a valid lexer. * *\li 'buffer' is a valid buffer. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMEMORY Out of memory */ isc_result_t isc_lex_close(isc_lex_t *lex); /*%< * Close the most recently opened object (i.e. file or buffer). * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_NOMORE No more input sources */ isc_result_t isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp); /*%< * Get the next token. * * Requires: *\li 'lex' is a valid lexer. * *\li 'lex' has an input source. * *\li 'options' contains valid options. * *\li '*tokenp' is a valid pointer. * * Returns: *\li #ISC_R_SUCCESS *\li #ISC_R_UNEXPECTEDEND *\li #ISC_R_NOMEMORY * * These two results are returned only if their corresponding lexer * options are not set. * *\li #ISC_R_EOF End of input source *\li #ISC_R_NOMORE No more input sources */ isc_result_t isc_lex_getmastertoken(isc_lex_t *lex, isc_token_t *token, isc_tokentype_t expect, isc_boolean_t eol); /*%< * Get the next token from a DNS master file type stream. This is a * convenience function that sets appropriate options and handles quoted * strings and end of line correctly for master files. It also ungets * unexpected tokens. * * Requires: *\li 'lex' is a valid lexer. * *\li 'token' is a valid pointer * * Returns: * * \li any return code from isc_lex_gettoken(). */ isc_result_t isc_lex_getoctaltoken(isc_lex_t *lex, isc_token_t *token, isc_boolean_t eol); /*%< * Get the next token from a DNS master file type stream. This is a * convenience function that sets appropriate options and handles end * of line correctly for master files. It also ungets unexpected tokens. * * Requires: *\li 'lex' is a valid lexer. * *\li 'token' is a valid pointer * * Returns: * * \li any return code from isc_lex_gettoken(). */ void isc_lex_ungettoken(isc_lex_t *lex, isc_token_t *tokenp); /*%< * Unget the current token. * * Requires: *\li 'lex' is a valid lexer. * *\li 'lex' has an input source. * *\li 'tokenp' points to a valid token. * *\li There is no ungotten token already. */ void isc_lex_getlasttokentext(isc_lex_t *lex, isc_token_t *tokenp, isc_region_t *r); /*%< * Returns a region containing the text of the last token returned. * * Requires: *\li 'lex' is a valid lexer. * *\li 'lex' has an input source. * *\li 'tokenp' points to a valid token. * *\li A token has been gotten and not ungotten. */ char * isc_lex_getsourcename(isc_lex_t *lex); /*%< * Return the input source name. * * Requires: *\li 'lex' is a valid lexer. * * Returns: * \li source name or NULL if no current source. *\li result valid while current input source exists. */ unsigned long isc_lex_getsourceline(isc_lex_t *lex); /*%< * Return the input source line number. * * Requires: *\li 'lex' is a valid lexer. * * Returns: *\li Current line number or 0 if no current source. */ isc_result_t isc_lex_setsourcename(isc_lex_t *lex, const char *name); /*%< * Assigns a new name to the input source. * * Requires: * * \li 'lex' is a valid lexer. * * Returns: * \li #ISC_R_SUCCESS * \li #ISC_R_NOMEMORY * \li #ISC_R_NOTFOUND - there are no sources. */ isc_boolean_t isc_lex_isfile(isc_lex_t *lex); /*%< * Return whether the current input source is a file. * * Requires: *\li 'lex' is a valid lexer. * * Returns: * \li #ISC_TRUE if the current input is a file, *\li #ISC_FALSE otherwise. */ ISC_LANG_ENDDECLS #endif /* ISC_LEX_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/stdlib.h0000644000470500017500000000230512664710322020550 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: stdlib.h,v 1.8 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_STDLIB_H #define ISC_STDLIB_H 1 /*! \file isc/stdlib.h */ #include #include #include #ifdef ISC_PLATFORM_NEEDSTRTOUL #define strtoul isc_strtoul #endif ISC_LANG_BEGINDECLS unsigned long isc_strtoul(const char *, char **, int); ISC_LANG_ENDDECLS #endif bind9-9.10.3.dfsg.P4/lib/isc/include/isc/regex.h0000644000470500017500000000222112664710322020376 0ustar lamontlamont/* * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef ISC_REGEX_H #define ISC_REGEX_H 1 /*! \file isc/regex.h */ #include #include ISC_LANG_BEGINDECLS int isc_regex_validate(const char *expression); /*%< * Check a regular expression for syntactic correctness. * * Returns: *\li -1 on error. *\li the number of groups in the expression. */ ISC_LANG_ENDDECLS #endif /* ISC_REGEX_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/isc/interfaceiter.h0000644000470500017500000000705712664710322022124 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: interfaceiter.h,v 1.17 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_INTERFACEITER_H #define ISC_INTERFACEITER_H 1 /***** ***** Module Info *****/ /*! \file isc/interfaceiter.h * \brief Iterates over the list of network interfaces. * * Interfaces whose address family is not supported are ignored and never * returned by the iterator. Interfaces whose netmask, interface flags, * or similar cannot be obtained are also ignored, and the failure is logged. * * Standards: * The API for scanning varies greatly among operating systems. * This module attempts to hide the differences. */ /*** *** Imports ***/ #include #include #include /*! * \brief Public structure describing a network interface. */ struct isc_interface { char name[32]; /*%< Interface name, null-terminated. */ unsigned int af; /*%< Address family. */ isc_netaddr_t address; /*%< Local address. */ isc_netaddr_t netmask; /*%< Network mask. */ isc_netaddr_t dstaddress; /*%< Destination address (point-to-point only). */ isc_uint32_t flags; /*%< Flags; see INTERFACE flags. */ }; /*@{*/ /*! Interface flags. */ #define INTERFACE_F_UP 0x00000001U #define INTERFACE_F_POINTTOPOINT 0x00000002U #define INTERFACE_F_LOOPBACK 0x00000004U /*@}*/ /*** *** Functions ***/ ISC_LANG_BEGINDECLS isc_result_t isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp); /*!< * \brief Create an iterator for traversing the operating system's list * of network interfaces. * * Returns: *\li #ISC_R_SUCCESS * \li #ISC_R_NOMEMORY *\li Various network-related errors */ isc_result_t isc_interfaceiter_first(isc_interfaceiter_t *iter); /*!< * \brief Position the iterator on the first interface. * * Returns: *\li #ISC_R_SUCCESS Success. *\li #ISC_R_NOMORE There are no interfaces. */ isc_result_t isc_interfaceiter_current(isc_interfaceiter_t *iter, isc_interface_t *ifdata); /*!< * \brief Get information about the interface the iterator is currently * positioned at and store it at *ifdata. * * Requires: *\li The iterator has been successfully positioned using * isc_interface_iter_first() / isc_interface_iter_next(). * * Returns: *\li #ISC_R_SUCCESS Success. */ isc_result_t isc_interfaceiter_next(isc_interfaceiter_t *iter); /*!< * \brief Position the iterator on the next interface. * * Requires: * \li The iterator has been successfully positioned using * isc_interface_iter_first() / isc_interface_iter_next(). * * Returns: *\li #ISC_R_SUCCESS Success. *\li #ISC_R_NOMORE There are no more interfaces. */ void isc_interfaceiter_destroy(isc_interfaceiter_t **iterp); /*!< * \brief Destroy the iterator. */ ISC_LANG_ENDDECLS #endif /* ISC_INTERFACEITER_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/pk11/0002755000470500017500000000000012672612753017126 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/include/pk11/internal.h0000644000470500017500000000264012664710322021103 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef PK11_INTERNAL_H #define PK11_INTERNAL_H 1 /*! \file pk11/internal.h */ ISC_LANG_BEGINDECLS const char *pk11_get_lib_name(void); void *pk11_mem_get(size_t size); void pk11_mem_put(void *ptr, size_t size); CK_SLOT_ID pk11_get_best_token(pk11_optype_t optype); unsigned int pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt); CK_ATTRIBUTE *pk11_attribute_first(const pk11_object_t *obj); CK_ATTRIBUTE *pk11_attribute_next(const pk11_object_t *obj, CK_ATTRIBUTE *attr); CK_ATTRIBUTE *pk11_attribute_bytype(const pk11_object_t *obj, CK_ATTRIBUTE_TYPE type); ISC_LANG_ENDDECLS #endif /* PK11_INTERNAL_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/pk11/Makefile.in0000644000470500017500000000241212664710322021160 0ustar lamontlamont# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ # # Only list headers that are to be installed and are not # machine generated. The latter are handled specially in the # install target below. # HEADERS = constants.h internal.h pk11.h result.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/pk11 install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/pk11 ; \ done bind9-9.10.3.dfsg.P4/lib/isc/include/pk11/pk11.h0000644000470500017500000002020712664710322020042 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef PK11_PK11_H #define PK11_PK11_H 1 /*! \file pk11/pk11.h */ #include #include #include #define PK11_FATALCHECK(func, args) \ ((void) (((rv = (func) args) == CKR_OK) || \ ((pk11_error_fatalcheck)(__FILE__, __LINE__, #func, rv), 0))) #include ISC_LANG_BEGINDECLS #define SES_MAGIC ISC_MAGIC('P','K','S','S') #define TOK_MAGIC ISC_MAGIC('P','K','T','K') #define VALID_SES(x) ISC_MAGIC_VALID(x, SES_MAGIC) #define VALID_TOK(x) ISC_MAGIC_VALID(x, TOK_MAGIC) typedef struct pk11_context pk11_context_t; struct pk11_object { CK_OBJECT_HANDLE object; CK_SLOT_ID slot; CK_BBOOL ontoken; CK_BBOOL reqlogon; CK_BYTE attrcnt; CK_ATTRIBUTE *repr; }; struct pk11_context { void *handle; CK_SESSION_HANDLE session; CK_BBOOL ontoken; CK_OBJECT_HANDLE object; #ifndef PKCS11CRYPTOWITHHMAC unsigned char *key; #endif }; typedef struct pk11_object pk11_object_t; typedef enum { OP_ANY = 0, OP_RAND = 1, OP_RSA = 2, OP_DSA = 3, OP_DH = 4, OP_DIGEST = 5, OP_EC = 6, OP_GOST = 7, OP_AES = 8, OP_MAX = 9 } pk11_optype_t; /*% * Function prototypes */ void pk11_set_lib_name(const char *lib_name); /*%< * Set the PKCS#11 provider (aka library) path/name. */ isc_result_t pk11_initialize(isc_mem_t *mctx, const char *engine); /*%< * Initialize PKCS#11 device * * mctx: memory context to attach to pk11_mctx. * engine: PKCS#11 provider (aka library) path/name. * * returns: * ISC_R_SUCCESS * PK11_R_NOPROVIDER: can't load the provider * PK11_R_INITFAILED: C_Initialize() failed * PK11_R_NORANDOMSERVICE: can't find required random service * PK11_R_NODIGESTSERVICE: can't find required digest service * PK11_R_NOAESSERVICE: can't find required AES service */ isc_result_t pk11_get_session(pk11_context_t *ctx, pk11_optype_t optype, isc_boolean_t need_services, isc_boolean_t rw, isc_boolean_t logon, const char *pin, CK_SLOT_ID slot); /*%< * Initialize PKCS#11 device and acquire a session. * * need_services: * if ISC_TRUE, this session requires full PKCS#11 API * support including random and digest services, and * the lack of these services will cause the session not * to be initialized. If ISC_FALSE, the function will return * an error code indicating the missing service, but the * session will be usable for other purposes. * rw: if ISC_TRUE, session will be read/write (useful for * generating or destroying keys); otherwise read-only. * login: indicates whether to log in to the device * pin: optional PIN, overriding any PIN currently associated * with the * slot: device slot ID */ void pk11_return_session(pk11_context_t *ctx); /*%< * Release an active PKCS#11 session for reuse. */ isc_result_t pk11_finalize(void); /*%< * Shut down PKCS#11 device and free all sessions. */ isc_result_t pk11_rand_bytes(unsigned char *buf, int num); void pk11_rand_seed_fromfile(const char *randomfile); isc_result_t pk11_parse_uri(pk11_object_t *obj, const char *label, isc_mem_t *mctx, pk11_optype_t optype); ISC_PLATFORM_NORETURN_PRE void pk11_error_fatalcheck(const char *file, int line, const char *funcname, CK_RV rv) ISC_PLATFORM_NORETURN_POST; void pk11_dump_tokens(void); CK_RV pkcs_C_Initialize(CK_VOID_PTR pReserved); CK_RV pkcs_C_Finalize(CK_VOID_PTR pReserved); CK_RV pkcs_C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount); CK_RV pkcs_C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo); CK_RV pkcs_C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo); CK_RV pkcs_C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_RV (*Notify) (CK_SESSION_HANDLE hSession, CK_NOTIFICATION event, CK_VOID_PTR pApplication), CK_SESSION_HANDLE_PTR phSession); CK_RV pkcs_C_CloseSession(CK_SESSION_HANDLE hSession); CK_RV pkcs_C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG usPinLen); CK_RV pkcs_C_Logout(CK_SESSION_HANDLE hSession); CK_RV pkcs_C_CreateObject(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount, CK_OBJECT_HANDLE_PTR phObject); CK_RV pkcs_C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject); CK_RV pkcs_C_GetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount); CK_RV pkcs_C_SetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount); CK_RV pkcs_C_FindObjectsInit(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount); CK_RV pkcs_C_FindObjects(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG usMaxObjectCount, CK_ULONG_PTR pusObjectCount); CK_RV pkcs_C_FindObjectsFinal(CK_SESSION_HANDLE hSession); CK_RV pkcs_C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); CK_RV pkcs_C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen); CK_RV pkcs_C_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism); CK_RV pkcs_C_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen); CK_RV pkcs_C_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen); CK_RV pkcs_C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); CK_RV pkcs_C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen); CK_RV pkcs_C_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen); CK_RV pkcs_C_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen); CK_RV pkcs_C_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); CK_RV pkcs_C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen); CK_RV pkcs_C_VerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen); CK_RV pkcs_C_VerifyFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen); CK_RV pkcs_C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey); CK_RV pkcs_C_GenerateKeyPair(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG usPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG usPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPrivateKey, CK_OBJECT_HANDLE_PTR phPublicKey); CK_RV pkcs_C_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey); CK_RV pkcs_C_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen); CK_RV pkcs_C_GenerateRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR RandomData, CK_ULONG ulRandomLen); ISC_LANG_ENDDECLS #endif /* PK11_PK11_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/pk11/constants.h0000644000470500017500000001010412664710322021275 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef PK11_CONSTANTS_H #define PK11_CONSTANTS_H 1 /*! \file pk11/constants.h */ /*% * Static arrays of data used for key template initalization */ #ifdef WANT_ECC_CURVES static CK_BYTE pk11_ecc_prime256v1[] = { 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 }; static CK_BYTE pk11_ecc_secp384r1[] = { 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22 }; #endif #ifdef WANT_DH_PRIMES static CK_BYTE pk11_dh_bn2[] = { 2 }; static CK_BYTE pk11_dh_bn768[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34, 0xc4, 0xc6, 0x62, 0x8b, 0x80, 0xdc, 0x1c, 0xd1, 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74, 0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22, 0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd, 0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, 0x30, 0x2b, 0x0a, 0x6d, 0xf2, 0x5f, 0x14, 0x37, 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xc2, 0x45, 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6, 0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x3a, 0x36, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; static CK_BYTE pk11_dh_bn1024[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34, 0xc4, 0xc6, 0x62, 0x8b, 0x80, 0xdc, 0x1c, 0xd1, 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74, 0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22, 0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd, 0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, 0x30, 0x2b, 0x0a, 0x6d, 0xf2, 0x5f, 0x14, 0x37, 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xc2, 0x45, 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6, 0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x37, 0xed, 0x6b, 0x0b, 0xff, 0x5c, 0xb6, 0xf4, 0x06, 0xb7, 0xed, 0xee, 0x38, 0x6b, 0xfb, 0x5a, 0x89, 0x9f, 0xa5, 0xae, 0x9f, 0x24, 0x11, 0x7c, 0x4b, 0x1f, 0xe6, 0x49, 0x28, 0x66, 0x51, 0xec, 0xe6, 0x53, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; static CK_BYTE pk11_dh_bn1536[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34, 0xc4, 0xc6, 0x62, 0x8b, 0x80, 0xdc, 0x1c, 0xd1, 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74, 0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22, 0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd, 0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, 0x30, 0x2b, 0x0a, 0x6d, 0xf2, 0x5f, 0x14, 0x37, 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xc2, 0x45, 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6, 0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x37, 0xed, 0x6b, 0x0b, 0xff, 0x5c, 0xb6, 0xf4, 0x06, 0xb7, 0xed, 0xee, 0x38, 0x6b, 0xfb, 0x5a, 0x89, 0x9f, 0xa5, 0xae, 0x9f, 0x24, 0x11, 0x7c, 0x4b, 0x1f, 0xe6, 0x49, 0x28, 0x66, 0x51, 0xec, 0xe4, 0x5b, 0x3d, 0xc2, 0x00, 0x7c, 0xb8, 0xa1, 0x63, 0xbf, 0x05, 0x98, 0xda, 0x48, 0x36, 0x1c, 0x55, 0xd3, 0x9a, 0x69, 0x16, 0x3f, 0xa8, 0xfd, 0x24, 0xcf, 0x5f, 0x83, 0x65, 0x5d, 0x23, 0xdc, 0xa3, 0xad, 0x96, 0x1c, 0x62, 0xf3, 0x56, 0x20, 0x85, 0x52, 0xbb, 0x9e, 0xd5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6d, 0x67, 0x0c, 0x35, 0x4e, 0x4a, 0xbc, 0x98, 0x04, 0xf1, 0x74, 0x6c, 0x08, 0xca, 0x23, 0x73, 0x27, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; #endif #ifdef WANT_GOST_PARAMS static CK_BYTE pk11_gost_a_paramset[] = { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01 }; static CK_BYTE pk11_gost_paramset[] = { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01 }; #endif #endif /* PK11_CONSTANTS_H */ bind9-9.10.3.dfsg.P4/lib/isc/include/pk11/result.h0000644000470500017500000000334412664710322020607 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef PK11_RESULT_H #define PK11_RESULT_H 1 /*! \file pk11/result.h */ #include #include /* * Nothing in this file truly depends on , but the * PK11 result codes are considered to be publicly derived from * the ISC result codes, so including this file buys you the ISC_R_ * namespace too. */ #include /* Contractual promise. */ #define PK11_R_INITFAILED (ISC_RESULTCLASS_PK11 + 0) #define PK11_R_NOPROVIDER (ISC_RESULTCLASS_PK11 + 1) #define PK11_R_NORANDOMSERVICE (ISC_RESULTCLASS_PK11 + 2) #define PK11_R_NODIGESTSERVICE (ISC_RESULTCLASS_PK11 + 3) #define PK11_R_NOAESSERVICE (ISC_RESULTCLASS_PK11 + 4) #define PK11_R_NRESULTS 5 /* Number of results */ ISC_LANG_BEGINDECLS LIBISC_EXTERNAL_DATA extern isc_msgcat_t *pk11_msgcat; void pk11_initmsgcat(void); const char * pk11_result_totext(isc_result_t); void pk11_result_register(void); ISC_LANG_ENDDECLS #endif /* PK11_RESULT_H */ bind9-9.10.3.dfsg.P4/lib/isc/inet_pton.c0000644000470500017500000001247312664710322017067 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1996-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #if defined(LIBC_SCCS) && !defined(lint) static char rcsid[] = "$Id: inet_pton.c,v 1.19 2007/06/19 23:47:17 tbox Exp $"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include /*% INT16 Size */ #define NS_INT16SZ 2 /*% IPv4 Address Size */ #define NS_INADDRSZ 4 /*% IPv6 Address Size */ #define NS_IN6ADDRSZ 16 /* * WARNING: Don't even consider trying to compile this on a system where * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ static int inet_pton4(const char *src, unsigned char *dst); static int inet_pton6(const char *src, unsigned char *dst); /*% * convert from presentation format (which usually means ASCII printable) * to network format (which is usually some kind of binary format). * \return * 1 if the address was valid for the specified address family * 0 if the address wasn't valid (`dst' is untouched in this case) * -1 if some other error occurred (`dst' is untouched in this case, too) * \author * Paul Vixie, 1996. */ int isc_net_pton(int af, const char *src, void *dst) { switch (af) { case AF_INET: return (inet_pton4(src, dst)); case AF_INET6: return (inet_pton6(src, dst)); default: errno = EAFNOSUPPORT; return (-1); } /* NOTREACHED */ } /*!\fn static int inet_pton4(const char *src, unsigned char *dst) * \brief * like inet_aton() but without all the hexadecimal and shorthand. * \return * 1 if `src' is a valid dotted quad, else 0. * \note * does not touch `dst' unless it's returning 1. * \author * Paul Vixie, 1996. */ static int inet_pton4(const char *src, unsigned char *dst) { static const char digits[] = "0123456789"; int saw_digit, octets, ch; unsigned char tmp[NS_INADDRSZ], *tp; saw_digit = 0; octets = 0; *(tp = tmp) = 0; while ((ch = *src++) != '\0') { const char *pch; if ((pch = strchr(digits, ch)) != NULL) { unsigned int new = *tp * 10; new += (int)(pch - digits); if (saw_digit && *tp == 0) return (0); if (new > 255) return (0); *tp = new; if (!saw_digit) { if (++octets > 4) return (0); saw_digit = 1; } } else if (ch == '.' && saw_digit) { if (octets == 4) return (0); *++tp = 0; saw_digit = 0; } else return (0); } if (octets < 4) return (0); memmove(dst, tmp, NS_INADDRSZ); return (1); } /*% * convert presentation level address to network order binary form. * \return * 1 if `src' is a valid [RFC1884 2.2] address, else 0. * \note * (1) does not touch `dst' unless it's returning 1. * \note * (2) :: in a full address is silently ignored. * \author * inspired by Mark Andrews. * \author * Paul Vixie, 1996. */ static int inet_pton6(const char *src, unsigned char *dst) { static const char xdigits_l[] = "0123456789abcdef", xdigits_u[] = "0123456789ABCDEF"; unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; const char *xdigits, *curtok; int ch, seen_xdigits; unsigned int val; memset((tp = tmp), '\0', NS_IN6ADDRSZ); endp = tp + NS_IN6ADDRSZ; colonp = NULL; /* Leading :: requires some special handling. */ if (*src == ':') if (*++src != ':') return (0); curtok = src; seen_xdigits = 0; val = 0; while ((ch = *src++) != '\0') { const char *pch; if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) pch = strchr((xdigits = xdigits_u), ch); if (pch != NULL) { val <<= 4; val |= (pch - xdigits); if (++seen_xdigits > 4) return (0); continue; } if (ch == ':') { curtok = src; if (!seen_xdigits) { if (colonp) return (0); colonp = tp; continue; } if (tp + NS_INT16SZ > endp) return (0); *tp++ = (unsigned char) (val >> 8) & 0xff; *tp++ = (unsigned char) val & 0xff; seen_xdigits = 0; val = 0; continue; } if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && inet_pton4(curtok, tp) > 0) { tp += NS_INADDRSZ; seen_xdigits = 0; break; /* '\0' was seen by inet_pton4(). */ } return (0); } if (seen_xdigits) { if (tp + NS_INT16SZ > endp) return (0); *tp++ = (unsigned char) (val >> 8) & 0xff; *tp++ = (unsigned char) val & 0xff; } if (colonp != NULL) { /* * Since some memmove()'s erroneously fail to handle * overlapping regions, we'll do the shift by hand. */ const int n = (int)(tp - colonp); int i; if (tp == endp) return (0); for (i = 1; i <= n; i++) { endp[- i] = colonp[n - i]; colonp[n - i] = 0; } tp = endp; } if (tp != endp) return (0); memmove(dst, tmp, NS_IN6ADDRSZ); return (1); } bind9-9.10.3.dfsg.P4/lib/isc/bind9.c0000644000470500017500000000231712664710322016071 0ustar lamontlamont/* * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include /* * This determines whether we are using the libisc/libdns libraries * in BIND9 or in some other application. It is initialized to ISC_TRUE * and remains unchanged for BIND9 and related tools; export library * clients will run isc_lib_register(), which sets it to ISC_FALSE, * overriding certain BIND9 behaviors. */ LIBISC_EXTERNAL_DATA isc_boolean_t isc_bind9 = ISC_TRUE; bind9-9.10.3.dfsg.P4/lib/isc/sockaddr.c0000644000470500017500000003247612664710322016667 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2010-2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include isc_boolean_t isc_sockaddr_equal(const isc_sockaddr_t *a, const isc_sockaddr_t *b) { return (isc_sockaddr_compare(a, b, ISC_SOCKADDR_CMPADDR| ISC_SOCKADDR_CMPPORT| ISC_SOCKADDR_CMPSCOPE)); } isc_boolean_t isc_sockaddr_eqaddr(const isc_sockaddr_t *a, const isc_sockaddr_t *b) { return (isc_sockaddr_compare(a, b, ISC_SOCKADDR_CMPADDR| ISC_SOCKADDR_CMPSCOPE)); } isc_boolean_t isc_sockaddr_compare(const isc_sockaddr_t *a, const isc_sockaddr_t *b, unsigned int flags) { REQUIRE(a != NULL && b != NULL); if (a->length != b->length) return (ISC_FALSE); /* * We don't just memcmp because the sin_zero field isn't always * zero. */ if (a->type.sa.sa_family != b->type.sa.sa_family) return (ISC_FALSE); switch (a->type.sa.sa_family) { case AF_INET: if ((flags & ISC_SOCKADDR_CMPADDR) != 0 && memcmp(&a->type.sin.sin_addr, &b->type.sin.sin_addr, sizeof(a->type.sin.sin_addr)) != 0) return (ISC_FALSE); if ((flags & ISC_SOCKADDR_CMPPORT) != 0 && a->type.sin.sin_port != b->type.sin.sin_port) return (ISC_FALSE); break; case AF_INET6: if ((flags & ISC_SOCKADDR_CMPADDR) != 0 && memcmp(&a->type.sin6.sin6_addr, &b->type.sin6.sin6_addr, sizeof(a->type.sin6.sin6_addr)) != 0) return (ISC_FALSE); #ifdef ISC_PLATFORM_HAVESCOPEID /* * If ISC_SOCKADDR_CMPSCOPEZERO is set then don't return * ISC_FALSE if one of the scopes in zero. */ if ((flags & ISC_SOCKADDR_CMPSCOPE) != 0 && a->type.sin6.sin6_scope_id != b->type.sin6.sin6_scope_id && ((flags & ISC_SOCKADDR_CMPSCOPEZERO) == 0 || (a->type.sin6.sin6_scope_id != 0 && b->type.sin6.sin6_scope_id != 0))) return (ISC_FALSE); #endif if ((flags & ISC_SOCKADDR_CMPPORT) != 0 && a->type.sin6.sin6_port != b->type.sin6.sin6_port) return (ISC_FALSE); break; default: if (memcmp(&a->type, &b->type, a->length) != 0) return (ISC_FALSE); } return (ISC_TRUE); } isc_boolean_t isc_sockaddr_eqaddrprefix(const isc_sockaddr_t *a, const isc_sockaddr_t *b, unsigned int prefixlen) { isc_netaddr_t na, nb; isc_netaddr_fromsockaddr(&na, a); isc_netaddr_fromsockaddr(&nb, b); return (isc_netaddr_eqprefix(&na, &nb, prefixlen)); } isc_result_t isc_sockaddr_totext(const isc_sockaddr_t *sockaddr, isc_buffer_t *target) { isc_result_t result; isc_netaddr_t netaddr; char pbuf[sizeof("65000")]; unsigned int plen; isc_region_t avail; REQUIRE(sockaddr != NULL); /* * Do the port first, giving us the opportunity to check for * unsupported address families before calling * isc_netaddr_fromsockaddr(). */ switch (sockaddr->type.sa.sa_family) { case AF_INET: snprintf(pbuf, sizeof(pbuf), "%u", ntohs(sockaddr->type.sin.sin_port)); break; case AF_INET6: snprintf(pbuf, sizeof(pbuf), "%u", ntohs(sockaddr->type.sin6.sin6_port)); break; #ifdef ISC_PLAFORM_HAVESYSUNH case AF_UNIX: plen = strlen(sockaddr->type.sunix.sun_path); if (plen >= isc_buffer_availablelength(target)) return (ISC_R_NOSPACE); isc_buffer_putmem(target, sockaddr->type.sunix.sun_path, plen); /* * Null terminate after used region. */ isc_buffer_availableregion(target, &avail); INSIST(avail.length >= 1); avail.base[0] = '\0'; return (ISC_R_SUCCESS); #endif default: return (ISC_R_FAILURE); } plen = strlen(pbuf); INSIST(plen < sizeof(pbuf)); isc_netaddr_fromsockaddr(&netaddr, sockaddr); result = isc_netaddr_totext(&netaddr, target); if (result != ISC_R_SUCCESS) return (result); if (1 + plen + 1 > isc_buffer_availablelength(target)) return (ISC_R_NOSPACE); isc_buffer_putmem(target, (const unsigned char *)"#", 1); isc_buffer_putmem(target, (const unsigned char *)pbuf, plen); /* * Null terminate after used region. */ isc_buffer_availableregion(target, &avail); INSIST(avail.length >= 1); avail.base[0] = '\0'; return (ISC_R_SUCCESS); } void isc_sockaddr_format(const isc_sockaddr_t *sa, char *array, unsigned int size) { isc_result_t result; isc_buffer_t buf; if (size == 0U) return; isc_buffer_init(&buf, array, size); result = isc_sockaddr_totext(sa, &buf); if (result != ISC_R_SUCCESS) { /* * The message is the same as in netaddr.c. */ snprintf(array, size, isc_msgcat_get(isc_msgcat, ISC_MSGSET_NETADDR, ISC_MSG_UNKNOWNADDR, ""), sa->type.sa.sa_family); array[size - 1] = '\0'; } } unsigned int isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, isc_boolean_t address_only) { unsigned int length = 0; const unsigned char *s = NULL; unsigned int h = 0; unsigned int g; unsigned int p = 0; const struct in6_addr *in6; REQUIRE(sockaddr != NULL); switch (sockaddr->type.sa.sa_family) { case AF_INET: s = (const unsigned char *)&sockaddr->type.sin.sin_addr; p = ntohs(sockaddr->type.sin.sin_port); length = sizeof(sockaddr->type.sin.sin_addr.s_addr); break; case AF_INET6: in6 = &sockaddr->type.sin6.sin6_addr; s = (const unsigned char *)in6; if (IN6_IS_ADDR_V4MAPPED(in6)) { s += 12; length = sizeof(sockaddr->type.sin.sin_addr.s_addr); } else length = sizeof(sockaddr->type.sin6.sin6_addr); p = ntohs(sockaddr->type.sin6.sin6_port); break; default: UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKADDR, ISC_MSG_UNKNOWNFAMILY, "unknown address family: %d"), (int)sockaddr->type.sa.sa_family); s = (const unsigned char *)&sockaddr->type; length = sockaddr->length; p = 0; } h = isc_hash_calc(s, length, ISC_TRUE); if (!address_only) { g = isc_hash_calc((const unsigned char *)&p, sizeof(p), ISC_TRUE); h = h ^ g; /* XXX: we should concatenate h and p first */ } return (h); } void isc_sockaddr_any(isc_sockaddr_t *sockaddr) { memset(sockaddr, 0, sizeof(*sockaddr)); sockaddr->type.sin.sin_family = AF_INET; #ifdef ISC_PLATFORM_HAVESALEN sockaddr->type.sin.sin_len = sizeof(sockaddr->type.sin); #endif sockaddr->type.sin.sin_addr.s_addr = INADDR_ANY; sockaddr->type.sin.sin_port = 0; sockaddr->length = sizeof(sockaddr->type.sin); ISC_LINK_INIT(sockaddr, link); } void isc_sockaddr_any6(isc_sockaddr_t *sockaddr) { memset(sockaddr, 0, sizeof(*sockaddr)); sockaddr->type.sin6.sin6_family = AF_INET6; #ifdef ISC_PLATFORM_HAVESALEN sockaddr->type.sin6.sin6_len = sizeof(sockaddr->type.sin6); #endif sockaddr->type.sin6.sin6_addr = in6addr_any; sockaddr->type.sin6.sin6_port = 0; sockaddr->length = sizeof(sockaddr->type.sin6); ISC_LINK_INIT(sockaddr, link); } void isc_sockaddr_fromin(isc_sockaddr_t *sockaddr, const struct in_addr *ina, in_port_t port) { memset(sockaddr, 0, sizeof(*sockaddr)); sockaddr->type.sin.sin_family = AF_INET; #ifdef ISC_PLATFORM_HAVESALEN sockaddr->type.sin.sin_len = sizeof(sockaddr->type.sin); #endif sockaddr->type.sin.sin_addr = *ina; sockaddr->type.sin.sin_port = htons(port); sockaddr->length = sizeof(sockaddr->type.sin); ISC_LINK_INIT(sockaddr, link); } void isc_sockaddr_anyofpf(isc_sockaddr_t *sockaddr, int pf) { switch (pf) { case AF_INET: isc_sockaddr_any(sockaddr); break; case AF_INET6: isc_sockaddr_any6(sockaddr); break; default: INSIST(0); } } void isc_sockaddr_fromin6(isc_sockaddr_t *sockaddr, const struct in6_addr *ina6, in_port_t port) { memset(sockaddr, 0, sizeof(*sockaddr)); sockaddr->type.sin6.sin6_family = AF_INET6; #ifdef ISC_PLATFORM_HAVESALEN sockaddr->type.sin6.sin6_len = sizeof(sockaddr->type.sin6); #endif sockaddr->type.sin6.sin6_addr = *ina6; sockaddr->type.sin6.sin6_port = htons(port); sockaddr->length = sizeof(sockaddr->type.sin6); ISC_LINK_INIT(sockaddr, link); } void isc_sockaddr_v6fromin(isc_sockaddr_t *sockaddr, const struct in_addr *ina, in_port_t port) { memset(sockaddr, 0, sizeof(*sockaddr)); sockaddr->type.sin6.sin6_family = AF_INET6; #ifdef ISC_PLATFORM_HAVESALEN sockaddr->type.sin6.sin6_len = sizeof(sockaddr->type.sin6); #endif sockaddr->type.sin6.sin6_addr.s6_addr[10] = 0xff; sockaddr->type.sin6.sin6_addr.s6_addr[11] = 0xff; memmove(&sockaddr->type.sin6.sin6_addr.s6_addr[12], ina, 4); sockaddr->type.sin6.sin6_port = htons(port); sockaddr->length = sizeof(sockaddr->type.sin6); ISC_LINK_INIT(sockaddr, link); } int isc_sockaddr_pf(const isc_sockaddr_t *sockaddr) { /* * Get the protocol family of 'sockaddr'. */ #if (AF_INET == PF_INET && AF_INET6 == PF_INET6) /* * Assume that PF_xxx == AF_xxx for all AF and PF. */ return (sockaddr->type.sa.sa_family); #else switch (sockaddr->type.sa.sa_family) { case AF_INET: return (PF_INET); case AF_INET6: return (PF_INET6); default: FATAL_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKADDR, ISC_MSG_UNKNOWNFAMILY, "unknown address family: %d"), (int)sockaddr->type.sa.sa_family); } #endif } void isc_sockaddr_fromnetaddr(isc_sockaddr_t *sockaddr, const isc_netaddr_t *na, in_port_t port) { memset(sockaddr, 0, sizeof(*sockaddr)); sockaddr->type.sin.sin_family = na->family; switch (na->family) { case AF_INET: sockaddr->length = sizeof(sockaddr->type.sin); #ifdef ISC_PLATFORM_HAVESALEN sockaddr->type.sin.sin_len = sizeof(sockaddr->type.sin); #endif sockaddr->type.sin.sin_addr = na->type.in; sockaddr->type.sin.sin_port = htons(port); break; case AF_INET6: sockaddr->length = sizeof(sockaddr->type.sin6); #ifdef ISC_PLATFORM_HAVESALEN sockaddr->type.sin6.sin6_len = sizeof(sockaddr->type.sin6); #endif memmove(&sockaddr->type.sin6.sin6_addr, &na->type.in6, 16); #ifdef ISC_PLATFORM_HAVESCOPEID sockaddr->type.sin6.sin6_scope_id = isc_netaddr_getzone(na); #endif sockaddr->type.sin6.sin6_port = htons(port); break; default: INSIST(0); } ISC_LINK_INIT(sockaddr, link); } void isc_sockaddr_setport(isc_sockaddr_t *sockaddr, in_port_t port) { switch (sockaddr->type.sa.sa_family) { case AF_INET: sockaddr->type.sin.sin_port = htons(port); break; case AF_INET6: sockaddr->type.sin6.sin6_port = htons(port); break; default: FATAL_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKADDR, ISC_MSG_UNKNOWNFAMILY, "unknown address family: %d"), (int)sockaddr->type.sa.sa_family); } } in_port_t isc_sockaddr_getport(const isc_sockaddr_t *sockaddr) { in_port_t port = 0; switch (sockaddr->type.sa.sa_family) { case AF_INET: port = ntohs(sockaddr->type.sin.sin_port); break; case AF_INET6: port = ntohs(sockaddr->type.sin6.sin6_port); break; default: FATAL_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKADDR, ISC_MSG_UNKNOWNFAMILY, "unknown address family: %d"), (int)sockaddr->type.sa.sa_family); } return (port); } isc_boolean_t isc_sockaddr_ismulticast(const isc_sockaddr_t *sockaddr) { isc_netaddr_t netaddr; if (sockaddr->type.sa.sa_family == AF_INET || sockaddr->type.sa.sa_family == AF_INET6) { isc_netaddr_fromsockaddr(&netaddr, sockaddr); return (isc_netaddr_ismulticast(&netaddr)); } return (ISC_FALSE); } isc_boolean_t isc_sockaddr_isexperimental(const isc_sockaddr_t *sockaddr) { isc_netaddr_t netaddr; if (sockaddr->type.sa.sa_family == AF_INET) { isc_netaddr_fromsockaddr(&netaddr, sockaddr); return (isc_netaddr_isexperimental(&netaddr)); } return (ISC_FALSE); } isc_boolean_t isc_sockaddr_issitelocal(const isc_sockaddr_t *sockaddr) { isc_netaddr_t netaddr; if (sockaddr->type.sa.sa_family == AF_INET6) { isc_netaddr_fromsockaddr(&netaddr, sockaddr); return (isc_netaddr_issitelocal(&netaddr)); } return (ISC_FALSE); } isc_boolean_t isc_sockaddr_islinklocal(const isc_sockaddr_t *sockaddr) { isc_netaddr_t netaddr; if (sockaddr->type.sa.sa_family == AF_INET6) { isc_netaddr_fromsockaddr(&netaddr, sockaddr); return (isc_netaddr_islinklocal(&netaddr)); } return (ISC_FALSE); } isc_result_t isc_sockaddr_frompath(isc_sockaddr_t *sockaddr, const char *path) { #ifdef ISC_PLATFORM_HAVESYSUNH if (strlen(path) >= sizeof(sockaddr->type.sunix.sun_path)) return (ISC_R_NOSPACE); memset(sockaddr, 0, sizeof(*sockaddr)); sockaddr->length = sizeof(sockaddr->type.sunix); sockaddr->type.sunix.sun_family = AF_UNIX; #ifdef ISC_PLATFORM_HAVESALEN sockaddr->type.sunix.sun_len = (unsigned char)sizeof(sockaddr->type.sunix); #endif strcpy(sockaddr->type.sunix.sun_path, path); return (ISC_R_SUCCESS); #else UNUSED(sockaddr); UNUSED(path); return (ISC_R_NOTIMPLEMENTED); #endif } bind9-9.10.3.dfsg.P4/lib/isc/unix/0002755000470500017500000000000012672612753015712 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/unix/socket_p.h0000644000470500017500000000243412664710322017663 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: socket_p.h,v 1.15 2009/09/02 23:48:03 tbox Exp $ */ #ifndef ISC_SOCKET_P_H #define ISC_SOCKET_P_H /*! \file */ #ifdef ISC_PLATFORM_NEEDSYSSELECTH #include #endif typedef struct isc_socketwait isc_socketwait_t; int isc__socketmgr_waitevents(isc_socketmgr_t *, struct timeval *, isc_socketwait_t **); isc_result_t isc__socketmgr_dispatch(isc_socketmgr_t *, isc_socketwait_t *); #endif /* ISC_SOCKET_P_H */ bind9-9.10.3.dfsg.P4/lib/isc/unix/strerror.c0000644000470500017500000000403512664710322017730 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: strerror.c,v 1.10 2009/02/16 23:48:04 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #ifdef HAVE_STRERROR /*% * We need to do this this way for profiled locks. */ static isc_mutex_t isc_strerror_lock; static void init_lock(void) { RUNTIME_CHECK(isc_mutex_init(&isc_strerror_lock) == ISC_R_SUCCESS); } #else extern const char * const sys_errlist[]; extern const int sys_nerr; #endif void isc__strerror(int num, char *buf, size_t size) { #ifdef HAVE_STRERROR char *msg; unsigned int unum = (unsigned int)num; static isc_once_t once = ISC_ONCE_INIT; REQUIRE(buf != NULL); RUNTIME_CHECK(isc_once_do(&once, init_lock) == ISC_R_SUCCESS); LOCK(&isc_strerror_lock); msg = strerror(num); if (msg != NULL) snprintf(buf, size, "%s", msg); else snprintf(buf, size, "Unknown error: %u", unum); UNLOCK(&isc_strerror_lock); #else unsigned int unum = (unsigned int)num; REQUIRE(buf != NULL); if (num >= 0 && num < sys_nerr) snprintf(buf, size, "%s", sys_errlist[num]); else snprintf(buf, size, "Unknown error: %u", unum); #endif } bind9-9.10.3.dfsg.P4/lib/isc/unix/syslog.c0000644000470500017500000000420512664710322017365 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: syslog.c,v 1.8 2007/09/13 04:45:18 each Exp $ */ /*! \file */ #include #include #include #include #include #include #include static struct dsn_c_pvt_sfnt { int val; const char *strval; } facilities[] = { { LOG_KERN, "kern" }, { LOG_USER, "user" }, { LOG_MAIL, "mail" }, { LOG_DAEMON, "daemon" }, { LOG_AUTH, "auth" }, { LOG_SYSLOG, "syslog" }, { LOG_LPR, "lpr" }, #ifdef LOG_NEWS { LOG_NEWS, "news" }, #endif #ifdef LOG_UUCP { LOG_UUCP, "uucp" }, #endif #ifdef LOG_CRON { LOG_CRON, "cron" }, #endif #ifdef LOG_AUTHPRIV { LOG_AUTHPRIV, "authpriv" }, #endif #ifdef LOG_FTP { LOG_FTP, "ftp" }, #endif { LOG_LOCAL0, "local0"}, { LOG_LOCAL1, "local1"}, { LOG_LOCAL2, "local2"}, { LOG_LOCAL3, "local3"}, { LOG_LOCAL4, "local4"}, { LOG_LOCAL5, "local5"}, { LOG_LOCAL6, "local6"}, { LOG_LOCAL7, "local7"}, { 0, NULL } }; isc_result_t isc_syslog_facilityfromstring(const char *str, int *facilityp) { int i; REQUIRE(str != NULL); REQUIRE(facilityp != NULL); for (i = 0; facilities[i].strval != NULL; i++) { if (strcasecmp(facilities[i].strval, str) == 0) { *facilityp = facilities[i].val; return (ISC_R_SUCCESS); } } return (ISC_R_NOTFOUND); } bind9-9.10.3.dfsg.P4/lib/isc/unix/file.c0000644000470500017500000003745412664710322017000 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Portions Copyright (c) 1987, 1993 * The Regents of the University of California. 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. Neither the name of the University 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 REGENTS 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. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include /* Required for utimes on some platforms. */ #include /* Required for mkstemp on NetBSD. */ #include #include #ifdef HAVE_SYS_MMAN_H #include #endif #include #include #include #include #include #include #include #include #include "errno2result.h" /* * XXXDCL As the API for accessing file statistics undoubtedly gets expanded, * it might be good to provide a mechanism that allows for the results * of a previous stat() to be used again without having to do another stat, * such as perl's mechanism of using "_" in place of a file name to indicate * that the results of the last stat should be used. But then you get into * annoying MP issues. BTW, Win32 has stat(). */ static isc_result_t file_stats(const char *file, struct stat *stats) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(file != NULL); REQUIRE(stats != NULL); if (stat(file, stats) != 0) result = isc__errno2result(errno); return (result); } static isc_result_t fd_stats(int fd, struct stat *stats) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(stats != NULL); if (fstat(fd, stats) != 0) result = isc__errno2result(errno); return (result); } isc_result_t isc_file_getsizefd(int fd, off_t *size) { isc_result_t result; struct stat stats; REQUIRE(size != NULL); result = fd_stats(fd, &stats); if (result == ISC_R_SUCCESS) *size = stats.st_size; return (result); } isc_result_t isc_file_mode(const char *file, mode_t *modep) { isc_result_t result; struct stat stats; REQUIRE(modep != NULL); result = file_stats(file, &stats); if (result == ISC_R_SUCCESS) *modep = (stats.st_mode & 07777); return (result); } isc_result_t isc_file_getmodtime(const char *file, isc_time_t *modtime) { isc_result_t result; struct stat stats; REQUIRE(file != NULL); REQUIRE(modtime != NULL); result = file_stats(file, &stats); if (result == ISC_R_SUCCESS) /* * XXXDCL some operating systems provide nanoseconds, too, * such as BSD/OS via st_mtimespec. */ isc_time_set(modtime, stats.st_mtime, 0); return (result); } isc_result_t isc_file_getsize(const char *file, off_t *size) { isc_result_t result; struct stat stats; REQUIRE(file != NULL); REQUIRE(size != NULL); result = file_stats(file, &stats); if (result == ISC_R_SUCCESS) *size = stats.st_size; return (result); } isc_result_t isc_file_settime(const char *file, isc_time_t *when) { struct timeval times[2]; REQUIRE(file != NULL && when != NULL); /* * tv_sec is at least a 32 bit quantity on all platforms we're * dealing with, but it is signed on most (all?) of them, * so we need to make sure the high bit isn't set. This unfortunately * loses when either: * * tv_sec becomes a signed 64 bit integer but long is 32 bits * and isc_time_seconds > LONG_MAX, or * * isc_time_seconds is changed to be > 32 bits but long is 32 bits * and isc_time_seconds has at least 33 significant bits. */ times[0].tv_sec = times[1].tv_sec = (long)isc_time_seconds(when); /* * Here is the real check for the high bit being set. */ if ((times[0].tv_sec & (1ULL << (sizeof(times[0].tv_sec) * CHAR_BIT - 1))) != 0) return (ISC_R_RANGE); /* * isc_time_nanoseconds guarantees a value that divided by 1000 will * fit into the minimum possible size tv_usec field. Unfortunately, * we don't know what that type is so can't cast directly ... but * we can at least cast to signed so the IRIX compiler shuts up. */ times[0].tv_usec = times[1].tv_usec = (isc_int32_t)(isc_time_nanoseconds(when) / 1000); if (utimes(file, times) < 0) return (isc__errno2result(errno)); return (ISC_R_SUCCESS); } #undef TEMPLATE #define TEMPLATE "tmp-XXXXXXXXXX" /*%< 14 characters. */ isc_result_t isc_file_mktemplate(const char *path, char *buf, size_t buflen) { return (isc_file_template(path, TEMPLATE, buf, buflen)); } isc_result_t isc_file_template(const char *path, const char *templet, char *buf, size_t buflen) { char *s; REQUIRE(path != NULL); REQUIRE(templet != NULL); REQUIRE(buf != NULL); s = strrchr(templet, '/'); if (s != NULL) templet = s + 1; s = strrchr(path, '/'); if (s != NULL) { if ((s - path + 1 + strlen(templet) + 1) > buflen) return (ISC_R_NOSPACE); strncpy(buf, path, s - path + 1); buf[s - path + 1] = '\0'; strcat(buf, templet); } else { if ((strlen(templet) + 1) > buflen) return (ISC_R_NOSPACE); strcpy(buf, templet); } return (ISC_R_SUCCESS); } static char alphnum[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; isc_result_t isc_file_renameunique(const char *file, char *templet) { char *x; char *cp; isc_uint32_t which; REQUIRE(file != NULL); REQUIRE(templet != NULL); cp = templet; while (*cp != '\0') cp++; if (cp == templet) return (ISC_R_FAILURE); x = cp--; while (cp >= templet && *cp == 'X') { isc_random_get(&which); *cp = alphnum[which % (sizeof(alphnum) - 1)]; x = cp--; } while (link(file, templet) == -1) { if (errno != EEXIST) return (isc__errno2result(errno)); for (cp = x;;) { char *t; if (*cp == '\0') return (ISC_R_FAILURE); t = strchr(alphnum, *cp); if (t == NULL || *++t == '\0') *cp++ = alphnum[0]; else { *cp = *t; break; } } } if (unlink(file) < 0) if (errno != ENOENT) return (isc__errno2result(errno)); return (ISC_R_SUCCESS); } isc_result_t isc_file_openunique(char *templet, FILE **fp) { int mode = S_IWUSR|S_IRUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; return (isc_file_openuniquemode(templet, mode, fp)); } isc_result_t isc_file_openuniqueprivate(char *templet, FILE **fp) { int mode = S_IWUSR|S_IRUSR; return (isc_file_openuniquemode(templet, mode, fp)); } isc_result_t isc_file_openuniquemode(char *templet, int mode, FILE **fp) { int fd; FILE *f; isc_result_t result = ISC_R_SUCCESS; char *x; char *cp; isc_uint32_t which; REQUIRE(templet != NULL); REQUIRE(fp != NULL && *fp == NULL); cp = templet; while (*cp != '\0') cp++; if (cp == templet) return (ISC_R_FAILURE); x = cp--; while (cp >= templet && *cp == 'X') { isc_random_get(&which); *cp = alphnum[which % (sizeof(alphnum) - 1)]; x = cp--; } while ((fd = open(templet, O_RDWR|O_CREAT|O_EXCL, mode)) == -1) { if (errno != EEXIST) return (isc__errno2result(errno)); for (cp = x;;) { char *t; if (*cp == '\0') return (ISC_R_FAILURE); t = strchr(alphnum, *cp); if (t == NULL || *++t == '\0') *cp++ = alphnum[0]; else { *cp = *t; break; } } } f = fdopen(fd, "w+"); if (f == NULL) { result = isc__errno2result(errno); if (remove(templet) < 0) { isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_FILE, ISC_LOG_ERROR, "remove '%s': failed", templet); } (void)close(fd); } else *fp = f; return (result); } isc_result_t isc_file_bopenunique(char *templet, FILE **fp) { int mode = S_IWUSR|S_IRUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; return (isc_file_openuniquemode(templet, mode, fp)); } isc_result_t isc_file_bopenuniqueprivate(char *templet, FILE **fp) { int mode = S_IWUSR|S_IRUSR; return (isc_file_openuniquemode(templet, mode, fp)); } isc_result_t isc_file_bopenuniquemode(char *templet, int mode, FILE **fp) { return (isc_file_openuniquemode(templet, mode, fp)); } isc_result_t isc_file_remove(const char *filename) { int r; REQUIRE(filename != NULL); r = unlink(filename); if (r == 0) return (ISC_R_SUCCESS); else return (isc__errno2result(errno)); } isc_result_t isc_file_rename(const char *oldname, const char *newname) { int r; REQUIRE(oldname != NULL); REQUIRE(newname != NULL); r = rename(oldname, newname); if (r == 0) return (ISC_R_SUCCESS); else return (isc__errno2result(errno)); } isc_boolean_t isc_file_exists(const char *pathname) { struct stat stats; REQUIRE(pathname != NULL); return (ISC_TF(file_stats(pathname, &stats) == ISC_R_SUCCESS)); } isc_result_t isc_file_isplainfile(const char *filename) { /* * This function returns success if filename is a plain file. */ struct stat filestat; memset(&filestat,0,sizeof(struct stat)); if ((stat(filename, &filestat)) == -1) return(isc__errno2result(errno)); if(! S_ISREG(filestat.st_mode)) return(ISC_R_INVALIDFILE); return(ISC_R_SUCCESS); } isc_result_t isc_file_isplainfilefd(int fd) { /* * This function returns success if filename is a plain file. */ struct stat filestat; memset(&filestat,0,sizeof(struct stat)); if ((fstat(fd, &filestat)) == -1) return(isc__errno2result(errno)); if(! S_ISREG(filestat.st_mode)) return(ISC_R_INVALIDFILE); return(ISC_R_SUCCESS); } isc_result_t isc_file_isdirectory(const char *filename) { /* * This function returns success if filename exists and is a * directory. */ struct stat filestat; memset(&filestat,0,sizeof(struct stat)); if ((stat(filename, &filestat)) == -1) return(isc__errno2result(errno)); if(! S_ISDIR(filestat.st_mode)) return(ISC_R_INVALIDFILE); return(ISC_R_SUCCESS); } isc_boolean_t isc_file_isabsolute(const char *filename) { REQUIRE(filename != NULL); return (ISC_TF(filename[0] == '/')); } isc_boolean_t isc_file_iscurrentdir(const char *filename) { REQUIRE(filename != NULL); return (ISC_TF(filename[0] == '.' && filename[1] == '\0')); } isc_boolean_t isc_file_ischdiridempotent(const char *filename) { REQUIRE(filename != NULL); if (isc_file_isabsolute(filename)) return (ISC_TRUE); if (isc_file_iscurrentdir(filename)) return (ISC_TRUE); return (ISC_FALSE); } const char * isc_file_basename(const char *filename) { char *s; REQUIRE(filename != NULL); s = strrchr(filename, '/'); if (s == NULL) return (filename); return (s + 1); } isc_result_t isc_file_progname(const char *filename, char *buf, size_t buflen) { const char *base; size_t len; REQUIRE(filename != NULL); REQUIRE(buf != NULL); base = isc_file_basename(filename); len = strlen(base) + 1; if (len > buflen) return (ISC_R_NOSPACE); memmove(buf, base, len); return (ISC_R_SUCCESS); } /* * Put the absolute name of the current directory into 'dirname', which is * a buffer of at least 'length' characters. End the string with the * appropriate path separator, such that the final product could be * concatenated with a relative pathname to make a valid pathname string. */ static isc_result_t dir_current(char *dirname, size_t length) { char *cwd; isc_result_t result = ISC_R_SUCCESS; REQUIRE(dirname != NULL); REQUIRE(length > 0U); cwd = getcwd(dirname, length); if (cwd == NULL) { if (errno == ERANGE) result = ISC_R_NOSPACE; else result = isc__errno2result(errno); } else { if (strlen(dirname) + 1 == length) result = ISC_R_NOSPACE; else if (dirname[1] != '\0') strcat(dirname, "/"); } return (result); } isc_result_t isc_file_absolutepath(const char *filename, char *path, size_t pathlen) { isc_result_t result; result = dir_current(path, pathlen); if (result != ISC_R_SUCCESS) return (result); if (strlen(path) + strlen(filename) + 1 > pathlen) return (ISC_R_NOSPACE); strcat(path, filename); return (ISC_R_SUCCESS); } isc_result_t isc_file_truncate(const char *filename, isc_offset_t size) { isc_result_t result = ISC_R_SUCCESS; if (truncate(filename, size) < 0) result = isc__errno2result(errno); return (result); } isc_result_t isc_file_safecreate(const char *filename, FILE **fp) { isc_result_t result; int flags; struct stat sb; FILE *f; int fd; REQUIRE(filename != NULL); REQUIRE(fp != NULL && *fp == NULL); result = file_stats(filename, &sb); if (result == ISC_R_SUCCESS) { if ((sb.st_mode & S_IFREG) == 0) return (ISC_R_INVALIDFILE); flags = O_WRONLY | O_TRUNC; } else if (result == ISC_R_FILENOTFOUND) { flags = O_WRONLY | O_CREAT | O_EXCL; } else return (result); fd = open(filename, flags, S_IRUSR | S_IWUSR); if (fd == -1) return (isc__errno2result(errno)); f = fdopen(fd, "w"); if (f == NULL) { result = isc__errno2result(errno); close(fd); return (result); } *fp = f; return (ISC_R_SUCCESS); } isc_result_t isc_file_splitpath(isc_mem_t *mctx, char *path, char **dirname, char **basename) { char *dir, *file, *slash; if (path == NULL) return (ISC_R_INVALIDFILE); slash = strrchr(path, '/'); if (slash == path) { file = ++slash; dir = isc_mem_strdup(mctx, "/"); } else if (slash != NULL) { file = ++slash; dir = isc_mem_allocate(mctx, slash - path); if (dir != NULL) strlcpy(dir, path, slash - path); } else { file = path; dir = isc_mem_strdup(mctx, "."); } if (dir == NULL) return (ISC_R_NOMEMORY); if (*file == '\0') { isc_mem_free(mctx, dir); return (ISC_R_INVALIDFILE); } *dirname = dir; *basename = file; return (ISC_R_SUCCESS); } void * isc_file_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) { #ifdef HAVE_MMAP return (mmap(addr, len, prot, flags, fd, offset)); #else void *buf; ssize_t ret; off_t end; UNUSED(addr); UNUSED(prot); UNUSED(flags); end = lseek(fd, 0, SEEK_END); lseek(fd, offset, SEEK_SET); if (end - offset < (off_t) len) len = end - offset; buf = malloc(len); ret = read(fd, buf, len); if (ret != (ssize_t) len) { free(buf); buf = NULL; } return (buf); #endif } int isc_file_munmap(void *addr, size_t len) { #ifdef HAVE_MMAP return (munmap(addr, len)); #else UNUSED(len); free(addr); return (0); #endif } bind9-9.10.3.dfsg.P4/lib/isc/unix/ifiter_getifaddrs.c0000644000470500017500000001347412664710322021533 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007-2009, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ifiter_getifaddrs.c,v 1.13 2009/09/24 23:48:13 tbox Exp $ */ /*! \file * \brief * Obtain the list of network interfaces using the getifaddrs(3) library. */ #include /*% Iterator Magic */ #define IFITER_MAGIC ISC_MAGIC('I', 'F', 'I', 'G') /*% Valid Iterator */ #define VALID_IFITER(t) ISC_MAGIC_VALID(t, IFITER_MAGIC) #ifdef __linux static isc_boolean_t seenv6 = ISC_FALSE; #endif /*% Iterator structure */ struct isc_interfaceiter { unsigned int magic; /*%< Magic number. */ isc_mem_t *mctx; void *buf; /*%< (unused) */ unsigned int bufsize; /*%< (always 0) */ struct ifaddrs *ifaddrs; /*%< List of ifaddrs */ struct ifaddrs *pos; /*%< Ptr to current ifaddr */ isc_interface_t current; /*%< Current interface data. */ isc_result_t result; /*%< Last result code. */ #ifdef __linux FILE * proc; char entry[ISC_IF_INET6_SZ]; isc_result_t valid; #endif }; isc_result_t isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { isc_interfaceiter_t *iter; isc_result_t result; char strbuf[ISC_STRERRORSIZE]; REQUIRE(mctx != NULL); REQUIRE(iterp != NULL); REQUIRE(*iterp == NULL); iter = isc_mem_get(mctx, sizeof(*iter)); if (iter == NULL) return (ISC_R_NOMEMORY); iter->mctx = mctx; iter->buf = NULL; iter->bufsize = 0; iter->ifaddrs = NULL; #ifdef __linux /* * Only open "/proc/net/if_inet6" if we have never seen a IPv6 * address returned by getifaddrs(). */ if (!seenv6) iter->proc = fopen("/proc/net/if_inet6", "r"); else iter->proc = NULL; iter->valid = ISC_R_FAILURE; #endif if (getifaddrs(&iter->ifaddrs) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERGETIFADDRS, ISC_MSG_GETIFADDRS, "getting interface " "addresses: getifaddrs: %s"), strbuf); result = ISC_R_UNEXPECTED; goto failure; } /* * A newly created iterator has an undefined position * until isc_interfaceiter_first() is called. */ iter->pos = NULL; iter->result = ISC_R_FAILURE; iter->magic = IFITER_MAGIC; *iterp = iter; return (ISC_R_SUCCESS); failure: #ifdef __linux if (iter->proc != NULL) fclose(iter->proc); #endif if (iter->ifaddrs != NULL) /* just in case */ freeifaddrs(iter->ifaddrs); isc_mem_put(mctx, iter, sizeof(*iter)); return (result); } /* * Get information about the current interface to iter->current. * If successful, return ISC_R_SUCCESS. * If the interface has an unsupported address family, * return ISC_R_IGNORE. */ static isc_result_t internal_current(isc_interfaceiter_t *iter) { struct ifaddrs *ifa; int family; unsigned int namelen; REQUIRE(VALID_IFITER(iter)); ifa = iter->pos; #ifdef __linux if (iter->pos == NULL) return (linux_if_inet6_current(iter)); #endif INSIST(ifa != NULL); INSIST(ifa->ifa_name != NULL); if (ifa->ifa_addr == NULL) return (ISC_R_IGNORE); family = ifa->ifa_addr->sa_family; if (family != AF_INET && family != AF_INET6) return (ISC_R_IGNORE); #ifdef __linux if (family == AF_INET6) seenv6 = ISC_TRUE; #endif memset(&iter->current, 0, sizeof(iter->current)); namelen = strlen(ifa->ifa_name); if (namelen > sizeof(iter->current.name) - 1) namelen = sizeof(iter->current.name) - 1; memset(iter->current.name, 0, sizeof(iter->current.name)); memmove(iter->current.name, ifa->ifa_name, namelen); iter->current.flags = 0; if ((ifa->ifa_flags & IFF_UP) != 0) iter->current.flags |= INTERFACE_F_UP; if ((ifa->ifa_flags & IFF_POINTOPOINT) != 0) iter->current.flags |= INTERFACE_F_POINTTOPOINT; if ((ifa->ifa_flags & IFF_LOOPBACK) != 0) iter->current.flags |= INTERFACE_F_LOOPBACK; iter->current.af = family; get_addr(family, &iter->current.address, ifa->ifa_addr, ifa->ifa_name); if (ifa->ifa_netmask != NULL) get_addr(family, &iter->current.netmask, ifa->ifa_netmask, ifa->ifa_name); if (ifa->ifa_dstaddr != NULL && (iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) get_addr(family, &iter->current.dstaddress, ifa->ifa_dstaddr, ifa->ifa_name); return (ISC_R_SUCCESS); } /* * Step the iterator to the next interface. Unlike * isc_interfaceiter_next(), this may leave the iterator * positioned on an interface that will ultimately * be ignored. Return ISC_R_NOMORE if there are no more * interfaces, otherwise ISC_R_SUCCESS. */ static isc_result_t internal_next(isc_interfaceiter_t *iter) { if (iter->pos != NULL) iter->pos = iter->pos->ifa_next; if (iter->pos == NULL) { #ifdef __linux if (!seenv6) return (linux_if_inet6_next(iter)); #endif return (ISC_R_NOMORE); } return (ISC_R_SUCCESS); } static void internal_destroy(isc_interfaceiter_t *iter) { #ifdef __linux if (iter->proc != NULL) fclose(iter->proc); iter->proc = NULL; #endif if (iter->ifaddrs) freeifaddrs(iter->ifaddrs); iter->ifaddrs = NULL; } static void internal_first(isc_interfaceiter_t *iter) { #ifdef __linux linux_if_inet6_first(iter); #endif iter->pos = iter->ifaddrs; } bind9-9.10.3.dfsg.P4/lib/isc/unix/ifiter_ioctl.c0000644000470500017500000006042612664710322020530 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ifiter_ioctl.c,v 1.62 2009/01/18 23:48:14 tbox Exp $ */ #include /*! \file * \brief * Obtain the list of network interfaces using the SIOCGLIFCONF ioctl. * See netintro(4). */ #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) #ifdef ISC_PLATFORM_HAVEIF_LADDRCONF #define lifc_len iflc_len #define lifc_buf iflc_buf #define lifc_req iflc_req #define LIFCONF if_laddrconf #else #define ISC_HAVE_LIFC_FAMILY 1 #define ISC_HAVE_LIFC_FLAGS 1 #define LIFCONF lifconf #endif #ifdef ISC_PLATFORM_HAVEIF_LADDRREQ #define lifr_addr iflr_addr #define lifr_name iflr_name #define lifr_dstaddr iflr_dstaddr #define lifr_flags iflr_flags #define ss_family sa_family #define LIFREQ if_laddrreq #else #define LIFREQ lifreq #endif #endif #define IFITER_MAGIC ISC_MAGIC('I', 'F', 'I', 'T') #define VALID_IFITER(t) ISC_MAGIC_VALID(t, IFITER_MAGIC) struct isc_interfaceiter { unsigned int magic; /* Magic number. */ isc_mem_t *mctx; int mode; int socket; struct ifconf ifc; void *buf; /* Buffer for sysctl data. */ unsigned int bufsize; /* Bytes allocated. */ unsigned int pos; /* Current offset in SIOCGIFCONF data */ #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) int socket6; struct LIFCONF lifc; void *buf6; /* Buffer for sysctl data. */ unsigned int bufsize6; /* Bytes allocated. */ unsigned int pos6; /* Current offset in SIOCGLIFCONF data */ isc_result_t result6; /* Last result code. */ isc_boolean_t first6; #endif #ifdef HAVE_TRUCLUSTER int clua_context; /* Cluster alias context */ isc_boolean_t clua_done; struct sockaddr clua_sa; #endif #ifdef __linux FILE * proc; char entry[ISC_IF_INET6_SZ]; isc_result_t valid; #endif isc_interface_t current; /* Current interface data. */ isc_result_t result; /* Last result code. */ }; #ifdef HAVE_TRUCLUSTER #include #include #endif /*% * Size of buffer for SIOCGLIFCONF, in bytes. We assume no sane system * will have more than a megabyte of interface configuration data. */ #define IFCONF_BUFSIZE_INITIAL 4096 #define IFCONF_BUFSIZE_MAX 1048576 #ifdef __linux #ifndef IF_NAMESIZE # ifdef IFNAMSIZ # define IF_NAMESIZE IFNAMSIZ # else # define IF_NAMESIZE 16 # endif #endif #endif static isc_result_t getbuf4(isc_interfaceiter_t *iter) { char strbuf[ISC_STRERRORSIZE]; iter->bufsize = IFCONF_BUFSIZE_INITIAL; for (;;) { iter->buf = isc_mem_get(iter->mctx, iter->bufsize); if (iter->buf == NULL) return (ISC_R_NOMEMORY); memset(&iter->ifc.ifc_len, 0, sizeof(iter->ifc.ifc_len)); iter->ifc.ifc_len = iter->bufsize; iter->ifc.ifc_buf = iter->buf; /* * Ignore the HP/UX warning about "integer overflow during * conversion". It comes from its own macro definition, * and is really hard to shut up. */ if (ioctl(iter->socket, SIOCGIFCONF, (char *)&iter->ifc) == -1) { if (errno != EINVAL) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_GETIFCONFIG, "get interface " "configuration: %s"), strbuf); goto unexpected; } /* * EINVAL. Retry with a bigger buffer. */ } else { /* * The ioctl succeeded. * Some OS's just return what will fit rather * than set EINVAL if the buffer is too small * to fit all the interfaces in. If * ifc.lifc_len is too near to the end of the * buffer we will grow it just in case and * retry. */ if (iter->ifc.ifc_len + 2 * sizeof(struct ifreq) < iter->bufsize) break; } if (iter->bufsize >= IFCONF_BUFSIZE_MAX) { UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_BUFFERMAX, "get interface " "configuration: " "maximum buffer " "size exceeded")); goto unexpected; } isc_mem_put(iter->mctx, iter->buf, iter->bufsize); iter->bufsize *= 2; } return (ISC_R_SUCCESS); unexpected: isc_mem_put(iter->mctx, iter->buf, iter->bufsize); iter->buf = NULL; return (ISC_R_UNEXPECTED); } #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) static isc_result_t getbuf6(isc_interfaceiter_t *iter) { char strbuf[ISC_STRERRORSIZE]; isc_result_t result; iter->bufsize6 = IFCONF_BUFSIZE_INITIAL; for (;;) { iter->buf6 = isc_mem_get(iter->mctx, iter->bufsize6); if (iter->buf6 == NULL) return (ISC_R_NOMEMORY); memset(&iter->lifc, 0, sizeof(iter->lifc)); #ifdef ISC_HAVE_LIFC_FAMILY iter->lifc.lifc_family = AF_INET6; #endif #ifdef ISC_HAVE_LIFC_FLAGS iter->lifc.lifc_flags = 0; #endif iter->lifc.lifc_len = iter->bufsize6; iter->lifc.lifc_buf = iter->buf6; /* * Ignore the HP/UX warning about "integer overflow during * conversion". It comes from its own macro definition, * and is really hard to shut up. */ if (ioctl(iter->socket6, SIOCGLIFCONF, (char *)&iter->lifc) == -1) { #ifdef __hpux /* * IPv6 interface scanning is not available on all * kernels w/ IPv6 sockets. */ if (errno == ENOENT) { isc__strerror(errno, strbuf, sizeof(strbuf)); isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_INTERFACE, ISC_LOG_DEBUG(1), isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_GETIFCONFIG, "get interface " "configuration: %s"), strbuf); result = ISC_R_FAILURE; goto cleanup; } #endif if (errno != EINVAL) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_GETIFCONFIG, "get interface " "configuration: %s"), strbuf); result = ISC_R_UNEXPECTED; goto cleanup; } /* * EINVAL. Retry with a bigger buffer. */ } else { /* * The ioctl succeeded. * Some OS's just return what will fit rather * than set EINVAL if the buffer is too small * to fit all the interfaces in. If * ifc.ifc_len is too near to the end of the * buffer we will grow it just in case and * retry. */ if (iter->lifc.lifc_len + 2 * sizeof(struct LIFREQ) < iter->bufsize6) break; } if (iter->bufsize6 >= IFCONF_BUFSIZE_MAX) { UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_BUFFERMAX, "get interface " "configuration: " "maximum buffer " "size exceeded")); result = ISC_R_UNEXPECTED; goto cleanup; } isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6); iter->bufsize6 *= 2; } if (iter->lifc.lifc_len != 0) iter->mode = 6; return (ISC_R_SUCCESS); cleanup: isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6); iter->buf6 = NULL; return (result); } #endif isc_result_t isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { isc_interfaceiter_t *iter; isc_result_t result; char strbuf[ISC_STRERRORSIZE]; REQUIRE(mctx != NULL); REQUIRE(iterp != NULL); REQUIRE(*iterp == NULL); iter = isc_mem_get(mctx, sizeof(*iter)); if (iter == NULL) return (ISC_R_NOMEMORY); iter->mctx = mctx; iter->mode = 4; iter->buf = NULL; iter->pos = (unsigned int) -1; #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) iter->buf6 = NULL; iter->pos6 = (unsigned int) -1; iter->result6 = ISC_R_NOMORE; iter->socket6 = -1; iter->first6 = ISC_FALSE; #endif /* * Get the interface configuration, allocating more memory if * necessary. */ #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) result = isc_net_probeipv6(); if (result == ISC_R_SUCCESS) { /* * Create an unbound datagram socket to do the SIOCGLIFCONF * ioctl on. HP/UX requires an AF_INET6 socket for * SIOCGLIFCONF to get IPv6 addresses. */ if ((iter->socket6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_MAKESCANSOCKET, "making interface " "scan socket: %s"), strbuf); result = ISC_R_UNEXPECTED; goto socket6_failure; } result = iter->result6 = getbuf6(iter); if (result != ISC_R_NOTIMPLEMENTED && result != ISC_R_SUCCESS) goto ioctl6_failure; } #endif if ((iter->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_MAKESCANSOCKET, "making interface " "scan socket: %s"), strbuf); result = ISC_R_UNEXPECTED; goto socket_failure; } result = getbuf4(iter); if (result != ISC_R_SUCCESS) goto ioctl_failure; /* * A newly created iterator has an undefined position * until isc_interfaceiter_first() is called. */ #ifdef HAVE_TRUCLUSTER iter->clua_context = -1; iter->clua_done = ISC_TRUE; #endif #ifdef __linux iter->proc = fopen("/proc/net/if_inet6", "r"); iter->valid = ISC_R_FAILURE; #endif iter->result = ISC_R_FAILURE; iter->magic = IFITER_MAGIC; *iterp = iter; return (ISC_R_SUCCESS); ioctl_failure: if (iter->buf != NULL) isc_mem_put(mctx, iter->buf, iter->bufsize); (void) close(iter->socket); socket_failure: #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) if (iter->buf6 != NULL) isc_mem_put(mctx, iter->buf6, iter->bufsize6); ioctl6_failure: if (iter->socket6 != -1) (void) close(iter->socket6); socket6_failure: #endif isc_mem_put(mctx, iter, sizeof(*iter)); return (result); } #ifdef HAVE_TRUCLUSTER static void get_inaddr(isc_netaddr_t *dst, struct in_addr *src) { dst->family = AF_INET; memmove(&dst->type.in, src, sizeof(struct in_addr)); } static isc_result_t internal_current_clusteralias(isc_interfaceiter_t *iter) { struct clua_info ci; if (clua_getaliasinfo(&iter->clua_sa, &ci) != CLUA_SUCCESS) return (ISC_R_IGNORE); memset(&iter->current, 0, sizeof(iter->current)); iter->current.af = iter->clua_sa.sa_family; memset(iter->current.name, 0, sizeof(iter->current.name)); sprintf(iter->current.name, "clua%d", ci.aliasid); iter->current.flags = INTERFACE_F_UP; get_inaddr(&iter->current.address, &ci.addr); get_inaddr(&iter->current.netmask, &ci.netmask); return (ISC_R_SUCCESS); } #endif /* * Get information about the current interface to iter->current. * If successful, return ISC_R_SUCCESS. * If the interface has an unsupported address family, or if * some operation on it fails, return ISC_R_IGNORE to make * the higher-level iterator code ignore it. */ static isc_result_t internal_current4(isc_interfaceiter_t *iter) { struct ifreq *ifrp; struct ifreq ifreq; int family; char strbuf[ISC_STRERRORSIZE]; #if !defined(ISC_PLATFORM_HAVEIF_LADDRREQ) && defined(SIOCGLIFADDR) struct lifreq lifreq; #else char sabuf[256]; #endif int i, bits, prefixlen; REQUIRE(VALID_IFITER(iter)); if (iter->ifc.ifc_len == 0 || iter->pos == (unsigned int)iter->ifc.ifc_len) { #ifdef __linux return (linux_if_inet6_current(iter)); #else return (ISC_R_NOMORE); #endif } INSIST( iter->pos < (unsigned int) iter->ifc.ifc_len); ifrp = (struct ifreq *)((char *) iter->ifc.ifc_req + iter->pos); memset(&ifreq, 0, sizeof(ifreq)); memmove(&ifreq, ifrp, sizeof(ifreq)); family = ifreq.ifr_addr.sa_family; #if defined(ISC_PLATFORM_HAVEIPV6) if (family != AF_INET && family != AF_INET6) #else if (family != AF_INET) #endif return (ISC_R_IGNORE); memset(&iter->current, 0, sizeof(iter->current)); iter->current.af = family; INSIST(sizeof(ifreq.ifr_name) <= sizeof(iter->current.name)); memset(iter->current.name, 0, sizeof(iter->current.name)); memmove(iter->current.name, ifreq.ifr_name, sizeof(ifreq.ifr_name)); get_addr(family, &iter->current.address, (struct sockaddr *)&ifrp->ifr_addr, ifreq.ifr_name); /* * If the interface does not have a address ignore it. */ switch (family) { case AF_INET: if (iter->current.address.type.in.s_addr == htonl(INADDR_ANY)) return (ISC_R_IGNORE); break; case AF_INET6: if (memcmp(&iter->current.address.type.in6, &in6addr_any, sizeof(in6addr_any)) == 0) return (ISC_R_IGNORE); break; } /* * Get interface flags. */ iter->current.flags = 0; /* * Ignore the HP/UX warning about "integer overflow during * conversion. It comes from its own macro definition, * and is really hard to shut up. */ if (ioctl(iter->socket, SIOCGIFFLAGS, (char *) &ifreq) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "%s: getting interface flags: %s", ifreq.ifr_name, strbuf); return (ISC_R_IGNORE); } if ((ifreq.ifr_flags & IFF_UP) != 0) iter->current.flags |= INTERFACE_F_UP; #ifdef IFF_POINTOPOINT if ((ifreq.ifr_flags & IFF_POINTOPOINT) != 0) iter->current.flags |= INTERFACE_F_POINTTOPOINT; #endif if ((ifreq.ifr_flags & IFF_LOOPBACK) != 0) iter->current.flags |= INTERFACE_F_LOOPBACK; if (family == AF_INET) goto inet; #if !defined(ISC_PLATFORM_HAVEIF_LADDRREQ) && defined(SIOCGLIFADDR) memset(&lifreq, 0, sizeof(lifreq)); memmove(lifreq.lifr_name, iter->current.name, sizeof(lifreq.lifr_name)); memmove(&lifreq.lifr_addr, &iter->current.address.type.in6, sizeof(iter->current.address.type.in6)); if (ioctl(iter->socket, SIOCGLIFADDR, &lifreq) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "%s: getting interface address: %s", ifreq.ifr_name, strbuf); return (ISC_R_IGNORE); } prefixlen = lifreq.lifr_addrlen; #else isc_netaddr_format(&iter->current.address, sabuf, sizeof(sabuf)); isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_INTERFACE, ISC_LOG_INFO, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_GETIFCONFIG, "prefix length for %s is unknown " "(assume 128)"), sabuf); prefixlen = 128; #endif /* * Netmask already zeroed. */ iter->current.netmask.family = family; for (i = 0; i < 16; i++) { if (prefixlen > 8) { bits = 0; prefixlen -= 8; } else { bits = 8 - prefixlen; prefixlen = 0; } iter->current.netmask.type.in6.s6_addr[i] = (~0 << bits) & 0xff; } return (ISC_R_SUCCESS); inet: if (family != AF_INET) return (ISC_R_IGNORE); #ifdef IFF_POINTOPOINT /* * If the interface is point-to-point, get the destination address. */ if ((iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) { /* * Ignore the HP/UX warning about "integer overflow during * conversion. It comes from its own macro definition, * and is really hard to shut up. */ if (ioctl(iter->socket, SIOCGIFDSTADDR, (char *)&ifreq) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_GETDESTADDR, "%s: getting " "destination address: %s"), ifreq.ifr_name, strbuf); return (ISC_R_IGNORE); } get_addr(family, &iter->current.dstaddress, (struct sockaddr *)&ifreq.ifr_dstaddr, ifreq.ifr_name); } #endif /* * Get the network mask. */ memset(&ifreq, 0, sizeof(ifreq)); memmove(&ifreq, ifrp, sizeof(ifreq)); /* * Ignore the HP/UX warning about "integer overflow during * conversion. It comes from its own macro definition, * and is really hard to shut up. */ if (ioctl(iter->socket, SIOCGIFNETMASK, (char *)&ifreq) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_GETNETMASK, "%s: getting netmask: %s"), ifreq.ifr_name, strbuf); return (ISC_R_IGNORE); } get_addr(family, &iter->current.netmask, (struct sockaddr *)&ifreq.ifr_addr, ifreq.ifr_name); return (ISC_R_SUCCESS); } #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) static isc_result_t internal_current6(isc_interfaceiter_t *iter) { struct LIFREQ *ifrp; struct LIFREQ lifreq; int family; char strbuf[ISC_STRERRORSIZE]; int fd; REQUIRE(VALID_IFITER(iter)); if (iter->result6 != ISC_R_SUCCESS) return (iter->result6); REQUIRE(iter->pos6 < (unsigned int) iter->lifc.lifc_len); ifrp = (struct LIFREQ *)((char *) iter->lifc.lifc_req + iter->pos6); memset(&lifreq, 0, sizeof(lifreq)); memmove(&lifreq, ifrp, sizeof(lifreq)); family = lifreq.lifr_addr.ss_family; #ifdef ISC_PLATFORM_HAVEIPV6 if (family != AF_INET && family != AF_INET6) #else if (family != AF_INET) #endif return (ISC_R_IGNORE); memset(&iter->current, 0, sizeof(iter->current)); iter->current.af = family; INSIST(sizeof(lifreq.lifr_name) <= sizeof(iter->current.name)); memset(iter->current.name, 0, sizeof(iter->current.name)); memmove(iter->current.name, lifreq.lifr_name, sizeof(lifreq.lifr_name)); get_addr(family, &iter->current.address, (struct sockaddr *)&lifreq.lifr_addr, lifreq.lifr_name); /* * If the interface does not have a address ignore it. */ switch (family) { case AF_INET: if (iter->current.address.type.in.s_addr == htonl(INADDR_ANY)) return (ISC_R_IGNORE); break; case AF_INET6: if (memcmp(&iter->current.address.type.in6, &in6addr_any, sizeof(in6addr_any)) == 0) return (ISC_R_IGNORE); break; } /* * Get interface flags. */ iter->current.flags = 0; if (family == AF_INET6) fd = iter->socket6; else fd = iter->socket; /* * Ignore the HP/UX warning about "integer overflow during * conversion. It comes from its own macro definition, * and is really hard to shut up. */ if (ioctl(fd, SIOCGLIFFLAGS, (char *) &lifreq) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "%s: getting interface flags: %s", lifreq.lifr_name, strbuf); return (ISC_R_IGNORE); } if ((lifreq.lifr_flags & IFF_UP) != 0) iter->current.flags |= INTERFACE_F_UP; #ifdef IFF_POINTOPOINT if ((lifreq.lifr_flags & IFF_POINTOPOINT) != 0) iter->current.flags |= INTERFACE_F_POINTTOPOINT; #endif if ((lifreq.lifr_flags & IFF_LOOPBACK) != 0) iter->current.flags |= INTERFACE_F_LOOPBACK; #ifdef IFF_POINTOPOINT /* * If the interface is point-to-point, get the destination address. */ if ((iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) { /* * Ignore the HP/UX warning about "integer overflow during * conversion. It comes from its own macro definition, * and is really hard to shut up. */ if (ioctl(fd, SIOCGLIFDSTADDR, (char *)&lifreq) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_GETDESTADDR, "%s: getting " "destination address: %s"), lifreq.lifr_name, strbuf); return (ISC_R_IGNORE); } get_addr(family, &iter->current.dstaddress, (struct sockaddr *)&lifreq.lifr_dstaddr, lifreq.lifr_name); } #endif /* * Get the network mask. Netmask already zeroed. */ memset(&lifreq, 0, sizeof(lifreq)); memmove(&lifreq, ifrp, sizeof(lifreq)); #ifdef lifr_addrlen /* * Special case: if the system provides lifr_addrlen member, the * netmask of an IPv6 address can be derived from the length, since * an IPv6 address always has a contiguous mask. */ if (family == AF_INET6) { int i, bits; iter->current.netmask.family = family; for (i = 0; i < lifreq.lifr_addrlen; i += 8) { bits = lifreq.lifr_addrlen - i; bits = (bits < 8) ? (8 - bits) : 0; iter->current.netmask.type.in6.s6_addr[i / 8] = (~0 << bits) & 0xff; } return (ISC_R_SUCCESS); } #endif /* * Ignore the HP/UX warning about "integer overflow during * conversion. It comes from its own macro definition, * and is really hard to shut up. */ if (ioctl(fd, SIOCGLIFNETMASK, (char *)&lifreq) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_GETNETMASK, "%s: getting netmask: %s"), lifreq.lifr_name, strbuf); return (ISC_R_IGNORE); } get_addr(family, &iter->current.netmask, (struct sockaddr *)&lifreq.lifr_addr, lifreq.lifr_name); return (ISC_R_SUCCESS); } #endif static isc_result_t internal_current(isc_interfaceiter_t *iter) { #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) if (iter->mode == 6) { iter->result6 = internal_current6(iter); if (iter->result6 != ISC_R_NOMORE) return (iter->result6); } #endif #ifdef HAVE_TRUCLUSTER if (!iter->clua_done) return(internal_current_clusteralias(iter)); #endif return (internal_current4(iter)); } /* * Step the iterator to the next interface. Unlike * isc_interfaceiter_next(), this may leave the iterator * positioned on an interface that will ultimately * be ignored. Return ISC_R_NOMORE if there are no more * interfaces, otherwise ISC_R_SUCCESS. */ static isc_result_t internal_next4(isc_interfaceiter_t *iter) { #ifdef ISC_PLATFORM_HAVESALEN struct ifreq *ifrp; #endif if (iter->pos < (unsigned int) iter->ifc.ifc_len) { #ifdef ISC_PLATFORM_HAVESALEN ifrp = (struct ifreq *)((char *) iter->ifc.ifc_req + iter->pos); if (ifrp->ifr_addr.sa_len > sizeof(struct sockaddr)) iter->pos += sizeof(ifrp->ifr_name) + ifrp->ifr_addr.sa_len; else #endif iter->pos += sizeof(struct ifreq); } else { INSIST(iter->pos == (unsigned int) iter->ifc.ifc_len); #ifdef __linux return (linux_if_inet6_next(iter)); #else return (ISC_R_NOMORE); #endif } return (ISC_R_SUCCESS); } #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) static isc_result_t internal_next6(isc_interfaceiter_t *iter) { #ifdef ISC_PLATFORM_HAVESALEN struct LIFREQ *ifrp; #endif if (iter->result6 != ISC_R_SUCCESS && iter->result6 != ISC_R_IGNORE) return (iter->result6); REQUIRE(iter->pos6 < (unsigned int) iter->lifc.lifc_len); #ifdef ISC_PLATFORM_HAVESALEN ifrp = (struct LIFREQ *)((char *) iter->lifc.lifc_req + iter->pos6); if (ifrp->lifr_addr.sa_len > sizeof(struct sockaddr)) iter->pos6 += sizeof(ifrp->lifr_name) + ifrp->lifr_addr.sa_len; else #endif iter->pos6 += sizeof(struct LIFREQ); if (iter->pos6 >= (unsigned int) iter->lifc.lifc_len) return (ISC_R_NOMORE); return (ISC_R_SUCCESS); } #endif static isc_result_t internal_next(isc_interfaceiter_t *iter) { #ifdef HAVE_TRUCLUSTER int clua_result; #endif #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) if (iter->mode == 6) { iter->result6 = internal_next6(iter); if (iter->result6 != ISC_R_NOMORE) return (iter->result6); if (iter->first6) { iter->first6 = ISC_FALSE; return (ISC_R_SUCCESS); } } #endif #ifdef HAVE_TRUCLUSTER if (!iter->clua_done) { clua_result = clua_getaliasaddress(&iter->clua_sa, &iter->clua_context); if (clua_result != CLUA_SUCCESS) iter->clua_done = ISC_TRUE; return (ISC_R_SUCCESS); } #endif return (internal_next4(iter)); } static void internal_destroy(isc_interfaceiter_t *iter) { (void) close(iter->socket); #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) if (iter->socket6 != -1) (void) close(iter->socket6); if (iter->buf6 != NULL) { isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6); } #endif #ifdef __linux if (iter->proc != NULL) fclose(iter->proc); #endif } static void internal_first(isc_interfaceiter_t *iter) { #ifdef HAVE_TRUCLUSTER int clua_result; #endif iter->pos = 0; #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) iter->pos6 = 0; if (iter->result6 == ISC_R_NOMORE) iter->result6 = ISC_R_SUCCESS; iter->first6 = ISC_TRUE; #endif #ifdef HAVE_TRUCLUSTER iter->clua_context = 0; clua_result = clua_getaliasaddress(&iter->clua_sa, &iter->clua_context); iter->clua_done = ISC_TF(clua_result != CLUA_SUCCESS); #endif #ifdef __linux linux_if_inet6_first(iter); #endif } bind9-9.10.3.dfsg.P4/lib/isc/unix/socket.c0000644000470500017500000052464112664710322017350 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #if defined(HAVE_LINUX_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H) #include #include #endif #include #include #include #include #include #include #ifdef HAVE_INTTYPES_H #include /* uintptr_t */ #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef ISC_PLATFORM_HAVESYSUNH #include #endif #ifdef ISC_PLATFORM_HAVEKQUEUE #include #endif #ifdef ISC_PLATFORM_HAVEEPOLL #include #endif #ifdef ISC_PLATFORM_HAVEDEVPOLL #if defined(HAVE_SYS_DEVPOLL_H) #include #elif defined(HAVE_DEVPOLL_H) #include #endif #endif #include "errno2result.h" /* See task.c about the following definition: */ #ifdef ISC_PLATFORM_USETHREADS #define USE_WATCHER_THREAD #else #define USE_SHARED_MANAGER #endif /* ISC_PLATFORM_USETHREADS */ #ifndef USE_WATCHER_THREAD #include "socket_p.h" #include "../task_p.h" #endif /* USE_WATCHER_THREAD */ #if defined(SO_BSDCOMPAT) && defined(__linux__) #include #endif /*% * Choose the most preferable multiplex method. */ #ifdef ISC_PLATFORM_HAVEKQUEUE #define USE_KQUEUE #elif defined (ISC_PLATFORM_HAVEEPOLL) #define USE_EPOLL #elif defined (ISC_PLATFORM_HAVEDEVPOLL) #define USE_DEVPOLL typedef struct { unsigned int want_read : 1, want_write : 1; } pollinfo_t; #else #define USE_SELECT #endif /* ISC_PLATFORM_HAVEKQUEUE */ #ifndef USE_WATCHER_THREAD #if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL) struct isc_socketwait { int nevents; }; #elif defined (USE_SELECT) struct isc_socketwait { fd_set *readset; fd_set *writeset; int nfds; int maxfd; }; #endif /* USE_KQUEUE */ #endif /* !USE_WATCHER_THREAD */ /* * Set by the -T dscp option on the command line. If set to a value * other than -1, we check to make sure DSCP values match it, and * assert if not. */ int isc_dscp_check_value = -1; /*% * Maximum number of allowable open sockets. This is also the maximum * allowable socket file descriptor. * * Care should be taken before modifying this value for select(): * The API standard doesn't ensure select() accept more than (the system default * of) FD_SETSIZE descriptors, and the default size should in fact be fine in * the vast majority of cases. This constant should therefore be increased only * when absolutely necessary and possible, i.e., the server is exhausting all * available file descriptors (up to FD_SETSIZE) and the select() function * and FD_xxx macros support larger values than FD_SETSIZE (which may not * always by true, but we keep using some of them to ensure as much * portability as possible). Note also that overall server performance * may be rather worsened with a larger value of this constant due to * inherent scalability problems of select(). * * As a special note, this value shouldn't have to be touched if * this is a build for an authoritative only DNS server. */ #ifndef ISC_SOCKET_MAXSOCKETS #if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL) #ifdef TUNE_LARGE #define ISC_SOCKET_MAXSOCKETS 21000 #else #define ISC_SOCKET_MAXSOCKETS 4096 #endif /* TUNE_LARGE */ #elif defined(USE_SELECT) #define ISC_SOCKET_MAXSOCKETS FD_SETSIZE #endif /* USE_KQUEUE... */ #endif /* ISC_SOCKET_MAXSOCKETS */ #ifdef USE_SELECT /*% * Mac OS X needs a special definition to support larger values in select(). * We always define this because a larger value can be specified run-time. */ #ifdef __APPLE__ #define _DARWIN_UNLIMITED_SELECT #endif /* __APPLE__ */ #endif /* USE_SELECT */ #ifdef ISC_SOCKET_USE_POLLWATCH /*% * If this macro is defined, enable workaround for a Solaris /dev/poll kernel * bug: DP_POLL ioctl could keep sleeping even if socket I/O is possible for * some of the specified FD. The idea is based on the observation that it's * likely for a busy server to keep receiving packets. It specifically works * as follows: the socket watcher is first initialized with the state of * "poll_idle". While it's in the idle state it keeps sleeping until a socket * event occurs. When it wakes up for a socket I/O event, it moves to the * poll_active state, and sets the poll timeout to a short period * (ISC_SOCKET_POLLWATCH_TIMEOUT msec). If timeout occurs in this state, the * watcher goes to the poll_checking state with the same timeout period. * In this state, the watcher tries to detect whether this is a break * during intermittent events or the kernel bug is triggered. If the next * polling reports an event within the short period, the previous timeout is * likely to be a kernel bug, and so the watcher goes back to the active state. * Otherwise, it moves to the idle state again. * * It's not clear whether this is a thread-related bug, but since we've only * seen this with threads, this workaround is used only when enabling threads. */ typedef enum { poll_idle, poll_active, poll_checking } pollstate_t; #ifndef ISC_SOCKET_POLLWATCH_TIMEOUT #define ISC_SOCKET_POLLWATCH_TIMEOUT 10 #endif /* ISC_SOCKET_POLLWATCH_TIMEOUT */ #endif /* ISC_SOCKET_USE_POLLWATCH */ /*% * Size of per-FD lock buckets. */ #ifdef ISC_PLATFORM_USETHREADS #define FDLOCK_COUNT 1024 #define FDLOCK_ID(fd) ((fd) % FDLOCK_COUNT) #else #define FDLOCK_COUNT 1 #define FDLOCK_ID(fd) 0 #endif /* ISC_PLATFORM_USETHREADS */ /*% * Maximum number of events communicated with the kernel. There should normally * be no need for having a large number. */ #if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL) #ifndef ISC_SOCKET_MAXEVENTS #ifdef TUNE_LARGE #define ISC_SOCKET_MAXEVENTS 2048 #else #define ISC_SOCKET_MAXEVENTS 64 #endif /* TUNE_LARGE */ #endif #endif /*% * Some systems define the socket length argument as an int, some as size_t, * some as socklen_t. This is here so it can be easily changed if needed. */ #ifndef ISC_SOCKADDR_LEN_T #define ISC_SOCKADDR_LEN_T unsigned int #endif /*% * Define what the possible "soft" errors can be. These are non-fatal returns * of various network related functions, like recv() and so on. * * For some reason, BSDI (and perhaps others) will sometimes return <0 * from recv() but will have errno==0. This is broken, but we have to * work around it here. */ #define SOFT_ERROR(e) ((e) == EAGAIN || \ (e) == EWOULDBLOCK || \ (e) == EINTR || \ (e) == 0) #define DLVL(x) ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(x) /*!< * DLVL(90) -- Function entry/exit and other tracing. * DLVL(70) -- Socket "correctness" -- including returning of events, etc. * DLVL(60) -- Socket data send/receive * DLVL(50) -- Event tracing, including receiving/sending completion events. * DLVL(20) -- Socket creation/destruction. */ #define TRACE_LEVEL 90 #define CORRECTNESS_LEVEL 70 #define IOEVENT_LEVEL 60 #define EVENT_LEVEL 50 #define CREATION_LEVEL 20 #define TRACE DLVL(TRACE_LEVEL) #define CORRECTNESS DLVL(CORRECTNESS_LEVEL) #define IOEVENT DLVL(IOEVENT_LEVEL) #define EVENT DLVL(EVENT_LEVEL) #define CREATION DLVL(CREATION_LEVEL) typedef isc_event_t intev_t; #define SOCKET_MAGIC ISC_MAGIC('I', 'O', 'i', 'o') #define VALID_SOCKET(s) ISC_MAGIC_VALID(s, SOCKET_MAGIC) /*! * IPv6 control information. If the socket is an IPv6 socket we want * to collect the destination address and interface so the client can * set them on outgoing packets. */ #ifdef ISC_PLATFORM_HAVEIN6PKTINFO #ifndef USE_CMSG #define USE_CMSG 1 #endif #endif /*% * NetBSD and FreeBSD can timestamp packets. XXXMLG Should we have * a setsockopt() like interface to request timestamps, and if the OS * doesn't do it for us, call gettimeofday() on every UDP receive? */ #ifdef SO_TIMESTAMP #ifndef USE_CMSG #define USE_CMSG 1 #endif #endif /*% * The size to raise the receive buffer to (from BIND 8). */ #ifdef TUNE_LARGE #ifdef sun #define RCVBUFSIZE (1*1024*1024) #else #define RCVBUFSIZE (16*1024*1024) #endif #else #define RCVBUFSIZE (32*1024) #endif /* TUNE_LARGE */ /*% * The number of times a send operation is repeated if the result is EINTR. */ #define NRETRIES 10 typedef struct isc__socket isc__socket_t; typedef struct isc__socketmgr isc__socketmgr_t; #define NEWCONNSOCK(ev) ((isc__socket_t *)(ev)->newsocket) struct isc__socket { /* Not locked. */ isc_socket_t common; isc__socketmgr_t *manager; isc_mutex_t lock; isc_sockettype_t type; const isc_statscounter_t *statsindex; /* Locked by socket lock. */ ISC_LINK(isc__socket_t) link; unsigned int references; int fd; int pf; char name[16]; void * tag; ISC_LIST(isc_socketevent_t) send_list; ISC_LIST(isc_socketevent_t) recv_list; ISC_LIST(isc_socket_newconnev_t) accept_list; isc_socket_connev_t *connect_ev; /* * Internal events. Posted when a descriptor is readable or * writable. These are statically allocated and never freed. * They will be set to non-purgable before use. */ intev_t readable_ev; intev_t writable_ev; isc_sockaddr_t peer_address; /* remote address */ unsigned int pending_recv : 1, pending_send : 1, pending_accept : 1, listener : 1, /* listener socket */ connected : 1, connecting : 1, /* connect pending */ bound : 1, /* bound to local addr */ dupped : 1, active : 1, /* currently active */ pktdscp : 1; /* per packet dscp */ #ifdef ISC_NET_RECVOVERFLOW unsigned char overflow; /* used for MSG_TRUNC fake */ #endif char *recvcmsgbuf; ISC_SOCKADDR_LEN_T recvcmsgbuflen; char *sendcmsgbuf; ISC_SOCKADDR_LEN_T sendcmsgbuflen; void *fdwatcharg; isc_sockfdwatch_t fdwatchcb; int fdwatchflags; isc_task_t *fdwatchtask; unsigned int dscp; }; #define SOCKET_MANAGER_MAGIC ISC_MAGIC('I', 'O', 'm', 'g') #define VALID_MANAGER(m) ISC_MAGIC_VALID(m, SOCKET_MANAGER_MAGIC) struct isc__socketmgr { /* Not locked. */ isc_socketmgr_t common; isc_mem_t *mctx; isc_mutex_t lock; isc_mutex_t *fdlock; isc_stats_t *stats; #ifdef USE_KQUEUE int kqueue_fd; int nevents; struct kevent *events; #endif /* USE_KQUEUE */ #ifdef USE_EPOLL int epoll_fd; int nevents; struct epoll_event *events; #endif /* USE_EPOLL */ #ifdef USE_DEVPOLL int devpoll_fd; isc_resourcevalue_t open_max; unsigned int calls; int nevents; struct pollfd *events; #endif /* USE_DEVPOLL */ #ifdef USE_SELECT int fd_bufsize; #endif /* USE_SELECT */ unsigned int maxsocks; #ifdef ISC_PLATFORM_USETHREADS int pipe_fds[2]; #endif /* Locked by fdlock. */ isc__socket_t **fds; int *fdstate; #ifdef USE_DEVPOLL pollinfo_t *fdpollinfo; #endif /* Locked by manager lock. */ ISC_LIST(isc__socket_t) socklist; #ifdef USE_SELECT fd_set *read_fds; fd_set *read_fds_copy; fd_set *write_fds; fd_set *write_fds_copy; int maxfd; #endif /* USE_SELECT */ int reserved; /* unlocked */ #ifdef USE_WATCHER_THREAD isc_thread_t watcher; isc_condition_t shutdown_ok; #else /* USE_WATCHER_THREAD */ unsigned int refs; #endif /* USE_WATCHER_THREAD */ int maxudp; }; #ifdef USE_SHARED_MANAGER static isc__socketmgr_t *socketmgr = NULL; #endif /* USE_SHARED_MANAGER */ #define CLOSED 0 /* this one must be zero */ #define MANAGED 1 #define CLOSE_PENDING 2 /* * send() and recv() iovec counts */ #define MAXSCATTERGATHER_SEND (ISC_SOCKET_MAXSCATTERGATHER) #ifdef ISC_NET_RECVOVERFLOW # define MAXSCATTERGATHER_RECV (ISC_SOCKET_MAXSCATTERGATHER + 1) #else # define MAXSCATTERGATHER_RECV (ISC_SOCKET_MAXSCATTERGATHER) #endif static isc_result_t socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, isc_socket_t **socketp, isc_socket_t *dup_socket); static void send_recvdone_event(isc__socket_t *, isc_socketevent_t **); static void send_senddone_event(isc__socket_t *, isc_socketevent_t **); static void free_socket(isc__socket_t **); static isc_result_t allocate_socket(isc__socketmgr_t *, isc_sockettype_t, isc__socket_t **); static void destroy(isc__socket_t **); static void internal_accept(isc_task_t *, isc_event_t *); static void internal_connect(isc_task_t *, isc_event_t *); static void internal_recv(isc_task_t *, isc_event_t *); static void internal_send(isc_task_t *, isc_event_t *); static void internal_fdwatch_write(isc_task_t *, isc_event_t *); static void internal_fdwatch_read(isc_task_t *, isc_event_t *); static void process_cmsg(isc__socket_t *, struct msghdr *, isc_socketevent_t *); static void build_msghdr_send(isc__socket_t *, isc_socketevent_t *, struct msghdr *, struct iovec *, size_t *); static void build_msghdr_recv(isc__socket_t *, isc_socketevent_t *, struct msghdr *, struct iovec *, size_t *); #ifdef USE_WATCHER_THREAD static isc_boolean_t process_ctlfd(isc__socketmgr_t *manager); #endif static void setdscp(isc__socket_t *sock, isc_dscp_t dscp); /*% * The following are intended for internal use (indicated by "isc__" * prefix) but are not declared as static, allowing direct access from * unit tests etc. */ isc_result_t isc__socket_open(isc_socket_t *sock0); isc_result_t isc__socket_close(isc_socket_t *sock0); isc_result_t isc__socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, isc_socket_t **socketp); void isc__socket_attach(isc_socket_t *sock, isc_socket_t **socketp); void isc__socket_detach(isc_socket_t **socketp); isc_result_t isc__socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist, unsigned int minimum, isc_task_t *task, isc_taskaction_t action, void *arg); isc_result_t isc__socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, isc_task_t *task, isc_taskaction_t action, void *arg); isc_result_t isc__socket_recv2(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, isc_task_t *task, isc_socketevent_t *event, unsigned int flags); isc_result_t isc__socket_send(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, isc_taskaction_t action, void *arg); isc_result_t isc__socket_sendto(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo); isc_result_t isc__socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist, isc_task_t *task, isc_taskaction_t action, void *arg); isc_result_t isc__socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist, isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo); isc_result_t isc__socket_sendtov2(isc_socket_t *sock, isc_bufferlist_t *buflist, isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, unsigned int flags); isc_result_t isc__socket_sendto2(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, isc_socketevent_t *event, unsigned int flags); isc_socketevent_t * isc_socket_socketevent(isc_mem_t *mctx, void *sender, isc_eventtype_t eventtype, isc_taskaction_t action, void *arg); void isc__socket_cleanunix(isc_sockaddr_t *sockaddr, isc_boolean_t active); isc_result_t isc__socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm, isc_uint32_t owner, isc_uint32_t group); isc_result_t isc__socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr, unsigned int options); isc_result_t isc__socket_filter(isc_socket_t *sock, const char *filter); isc_result_t isc__socket_listen(isc_socket_t *sock, unsigned int backlog); isc_result_t isc__socket_accept(isc_socket_t *sock, isc_task_t *task, isc_taskaction_t action, void *arg); isc_result_t isc__socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr, isc_task_t *task, isc_taskaction_t action, void *arg); isc_result_t isc__socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp); isc_result_t isc__socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp); void isc__socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how); isc_sockettype_t isc__socket_gettype(isc_socket_t *sock); isc_boolean_t isc__socket_isbound(isc_socket_t *sock); void isc__socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes); void isc__socket_dscp(isc_socket_t *sock, isc_dscp_t dscp); isc_result_t isc__socket_fdwatchcreate(isc_socketmgr_t *manager, int fd, int flags, isc_sockfdwatch_t callback, void *cbarg, isc_task_t *task, isc_socket_t **socketp); isc_result_t isc__socket_fdwatchpoke(isc_socket_t *sock, int flags); isc_result_t isc__socket_dup(isc_socket_t *sock, isc_socket_t **socketp); int isc__socket_getfd(isc_socket_t *sock); isc_result_t isc__socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp); isc_result_t isc__socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp, unsigned int maxsocks); isc_result_t isc_socketmgr_getmaxsockets(isc_socketmgr_t *manager0, unsigned int *nsockp); void isc_socketmgr_setstats(isc_socketmgr_t *manager0, isc_stats_t *stats); void isc__socketmgr_destroy(isc_socketmgr_t **managerp); void isc__socket_setname(isc_socket_t *socket0, const char *name, void *tag); const char * isc__socket_getname(isc_socket_t *socket0); void * isc__socket_gettag(isc_socket_t *socket0); #ifdef HAVE_LIBXML2 void isc__socketmgr_renderxml(isc_socketmgr_t *mgr0, xmlTextWriterPtr writer); #endif #ifdef HAVE_JSON isc_result_t isc__socketmgr_renderjson(isc_socketmgr_t *mgr0, json_object *stats); #endif static struct { isc_socketmethods_t methods; /*% * The following are defined just for avoiding unused static functions. */ void *recvv, *send, *sendv, *sendto2, *cleanunix, *permunix, *filter, *listen, *accept, *getpeername, *isbound; } socketmethods = { { isc__socket_attach, isc__socket_detach, isc__socket_bind, isc__socket_sendto, isc__socket_sendto2, isc__socket_connect, isc__socket_recv, isc__socket_recv2, isc__socket_cancel, isc__socket_getsockname, isc__socket_gettype, isc__socket_ipv6only, isc__socket_fdwatchpoke, isc__socket_dup, isc__socket_getfd, isc__socket_dscp }, (void *)isc__socket_recvv, (void *)isc__socket_send, (void *)isc__socket_sendv, (void *)isc__socket_sendto2, (void *)isc__socket_cleanunix, (void *)isc__socket_permunix, (void *)isc__socket_filter, (void *)isc__socket_listen, (void *)isc__socket_accept, (void *)isc__socket_getpeername, (void *)isc__socket_isbound }; static isc_socketmgrmethods_t socketmgrmethods = { isc__socketmgr_destroy, isc__socket_create, isc__socket_fdwatchcreate }; #define SELECT_POKE_SHUTDOWN (-1) #define SELECT_POKE_NOTHING (-2) #define SELECT_POKE_READ (-3) #define SELECT_POKE_ACCEPT (-3) /*%< Same as _READ */ #define SELECT_POKE_WRITE (-4) #define SELECT_POKE_CONNECT (-4) /*%< Same as _WRITE */ #define SELECT_POKE_CLOSE (-5) #define SOCK_DEAD(s) ((s)->references == 0) /*% * Shortcut index arrays to get access to statistics counters. */ enum { STATID_OPEN = 0, STATID_OPENFAIL = 1, STATID_CLOSE = 2, STATID_BINDFAIL = 3, STATID_CONNECTFAIL = 4, STATID_CONNECT = 5, STATID_ACCEPTFAIL = 6, STATID_ACCEPT = 7, STATID_SENDFAIL = 8, STATID_RECVFAIL = 9, STATID_ACTIVE = 10 }; static const isc_statscounter_t udp4statsindex[] = { isc_sockstatscounter_udp4open, isc_sockstatscounter_udp4openfail, isc_sockstatscounter_udp4close, isc_sockstatscounter_udp4bindfail, isc_sockstatscounter_udp4connectfail, isc_sockstatscounter_udp4connect, -1, -1, isc_sockstatscounter_udp4sendfail, isc_sockstatscounter_udp4recvfail, isc_sockstatscounter_udp4active }; static const isc_statscounter_t udp6statsindex[] = { isc_sockstatscounter_udp6open, isc_sockstatscounter_udp6openfail, isc_sockstatscounter_udp6close, isc_sockstatscounter_udp6bindfail, isc_sockstatscounter_udp6connectfail, isc_sockstatscounter_udp6connect, -1, -1, isc_sockstatscounter_udp6sendfail, isc_sockstatscounter_udp6recvfail, isc_sockstatscounter_udp6active }; static const isc_statscounter_t tcp4statsindex[] = { isc_sockstatscounter_tcp4open, isc_sockstatscounter_tcp4openfail, isc_sockstatscounter_tcp4close, isc_sockstatscounter_tcp4bindfail, isc_sockstatscounter_tcp4connectfail, isc_sockstatscounter_tcp4connect, isc_sockstatscounter_tcp4acceptfail, isc_sockstatscounter_tcp4accept, isc_sockstatscounter_tcp4sendfail, isc_sockstatscounter_tcp4recvfail, isc_sockstatscounter_tcp4active }; static const isc_statscounter_t tcp6statsindex[] = { isc_sockstatscounter_tcp6open, isc_sockstatscounter_tcp6openfail, isc_sockstatscounter_tcp6close, isc_sockstatscounter_tcp6bindfail, isc_sockstatscounter_tcp6connectfail, isc_sockstatscounter_tcp6connect, isc_sockstatscounter_tcp6acceptfail, isc_sockstatscounter_tcp6accept, isc_sockstatscounter_tcp6sendfail, isc_sockstatscounter_tcp6recvfail, isc_sockstatscounter_tcp6active }; static const isc_statscounter_t unixstatsindex[] = { isc_sockstatscounter_unixopen, isc_sockstatscounter_unixopenfail, isc_sockstatscounter_unixclose, isc_sockstatscounter_unixbindfail, isc_sockstatscounter_unixconnectfail, isc_sockstatscounter_unixconnect, isc_sockstatscounter_unixacceptfail, isc_sockstatscounter_unixaccept, isc_sockstatscounter_unixsendfail, isc_sockstatscounter_unixrecvfail, isc_sockstatscounter_unixactive }; static const isc_statscounter_t fdwatchstatsindex[] = { -1, -1, isc_sockstatscounter_fdwatchclose, isc_sockstatscounter_fdwatchbindfail, isc_sockstatscounter_fdwatchconnectfail, isc_sockstatscounter_fdwatchconnect, -1, -1, isc_sockstatscounter_fdwatchsendfail, isc_sockstatscounter_fdwatchrecvfail, -1 }; static const isc_statscounter_t rawstatsindex[] = { isc_sockstatscounter_rawopen, isc_sockstatscounter_rawopenfail, isc_sockstatscounter_rawclose, -1, -1, -1, -1, -1, -1, isc_sockstatscounter_rawrecvfail, isc_sockstatscounter_rawactive }; #if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL) || \ defined(USE_WATCHER_THREAD) static void manager_log(isc__socketmgr_t *sockmgr, isc_logcategory_t *category, isc_logmodule_t *module, int level, const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6); static void manager_log(isc__socketmgr_t *sockmgr, isc_logcategory_t *category, isc_logmodule_t *module, int level, const char *fmt, ...) { char msgbuf[2048]; va_list ap; if (! isc_log_wouldlog(isc_lctx, level)) return; va_start(ap, fmt); vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); va_end(ap); isc_log_write(isc_lctx, category, module, level, "sockmgr %p: %s", sockmgr, msgbuf); } #endif static void socket_log(isc__socket_t *sock, isc_sockaddr_t *address, isc_logcategory_t *category, isc_logmodule_t *module, int level, isc_msgcat_t *msgcat, int msgset, int message, const char *fmt, ...) ISC_FORMAT_PRINTF(9, 10); static void socket_log(isc__socket_t *sock, isc_sockaddr_t *address, isc_logcategory_t *category, isc_logmodule_t *module, int level, isc_msgcat_t *msgcat, int msgset, int message, const char *fmt, ...) { char msgbuf[2048]; char peerbuf[ISC_SOCKADDR_FORMATSIZE]; va_list ap; if (! isc_log_wouldlog(isc_lctx, level)) return; va_start(ap, fmt); vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); va_end(ap); if (address == NULL) { isc_log_iwrite(isc_lctx, category, module, level, msgcat, msgset, message, "socket %p: %s", sock, msgbuf); } else { isc_sockaddr_format(address, peerbuf, sizeof(peerbuf)); isc_log_iwrite(isc_lctx, category, module, level, msgcat, msgset, message, "socket %p %s: %s", sock, peerbuf, msgbuf); } } #if defined(_AIX) && defined(ISC_NET_BSD44MSGHDR) && \ defined(USE_CMSG) && defined(IPV6_RECVPKTINFO) /* * AIX has a kernel bug where IPV6_RECVPKTINFO gets cleared by * setting IPV6_V6ONLY. */ static void FIX_IPV6_RECVPKTINFO(isc__socket_t *sock) { char strbuf[ISC_STRERRORSIZE]; int on = 1; if (sock->pf != AF_INET6 || sock->type != isc_sockettype_udp) return; if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, (void *)&on, sizeof(on)) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, IPV6_RECVPKTINFO) " "%s: %s", sock->fd, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); } } #else #define FIX_IPV6_RECVPKTINFO(sock) (void)0 #endif /*% * Increment socket-related statistics counters. */ static inline void inc_stats(isc_stats_t *stats, isc_statscounter_t counterid) { REQUIRE(counterid != -1); if (stats != NULL) isc_stats_increment(stats, counterid); } /*% * Decrement socket-related statistics counters. */ static inline void dec_stats(isc_stats_t *stats, isc_statscounter_t counterid) { REQUIRE(counterid != -1); if (stats != NULL) isc_stats_decrement(stats, counterid); } static inline isc_result_t watch_fd(isc__socketmgr_t *manager, int fd, int msg) { isc_result_t result = ISC_R_SUCCESS; #ifdef USE_KQUEUE struct kevent evchange; memset(&evchange, 0, sizeof(evchange)); if (msg == SELECT_POKE_READ) evchange.filter = EVFILT_READ; else evchange.filter = EVFILT_WRITE; evchange.flags = EV_ADD; evchange.ident = fd; if (kevent(manager->kqueue_fd, &evchange, 1, NULL, 0, NULL) != 0) result = isc__errno2result(errno); return (result); #elif defined(USE_EPOLL) struct epoll_event event; if (msg == SELECT_POKE_READ) event.events = EPOLLIN; else event.events = EPOLLOUT; memset(&event.data, 0, sizeof(event.data)); event.data.fd = fd; if (epoll_ctl(manager->epoll_fd, EPOLL_CTL_ADD, fd, &event) == -1 && errno != EEXIST) { result = isc__errno2result(errno); } return (result); #elif defined(USE_DEVPOLL) struct pollfd pfd; int lockid = FDLOCK_ID(fd); memset(&pfd, 0, sizeof(pfd)); if (msg == SELECT_POKE_READ) pfd.events = POLLIN; else pfd.events = POLLOUT; pfd.fd = fd; pfd.revents = 0; LOCK(&manager->fdlock[lockid]); if (write(manager->devpoll_fd, &pfd, sizeof(pfd)) == -1) result = isc__errno2result(errno); else { if (msg == SELECT_POKE_READ) manager->fdpollinfo[fd].want_read = 1; else manager->fdpollinfo[fd].want_write = 1; } UNLOCK(&manager->fdlock[lockid]); return (result); #elif defined(USE_SELECT) LOCK(&manager->lock); if (msg == SELECT_POKE_READ) FD_SET(fd, manager->read_fds); if (msg == SELECT_POKE_WRITE) FD_SET(fd, manager->write_fds); UNLOCK(&manager->lock); return (result); #endif } static inline isc_result_t unwatch_fd(isc__socketmgr_t *manager, int fd, int msg) { isc_result_t result = ISC_R_SUCCESS; #ifdef USE_KQUEUE struct kevent evchange; memset(&evchange, 0, sizeof(evchange)); if (msg == SELECT_POKE_READ) evchange.filter = EVFILT_READ; else evchange.filter = EVFILT_WRITE; evchange.flags = EV_DELETE; evchange.ident = fd; if (kevent(manager->kqueue_fd, &evchange, 1, NULL, 0, NULL) != 0) result = isc__errno2result(errno); return (result); #elif defined(USE_EPOLL) struct epoll_event event; if (msg == SELECT_POKE_READ) event.events = EPOLLIN; else event.events = EPOLLOUT; memset(&event.data, 0, sizeof(event.data)); event.data.fd = fd; if (epoll_ctl(manager->epoll_fd, EPOLL_CTL_DEL, fd, &event) == -1 && errno != ENOENT) { char strbuf[ISC_STRERRORSIZE]; isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "epoll_ctl(DEL), %d: %s", fd, strbuf); result = ISC_R_UNEXPECTED; } return (result); #elif defined(USE_DEVPOLL) struct pollfd pfds[2]; size_t writelen = sizeof(pfds[0]); int lockid = FDLOCK_ID(fd); memset(pfds, 0, sizeof(pfds)); pfds[0].events = POLLREMOVE; pfds[0].fd = fd; /* * Canceling read or write polling via /dev/poll is tricky. Since it * only provides a way of canceling per FD, we may need to re-poll the * socket for the other operation. */ LOCK(&manager->fdlock[lockid]); if (msg == SELECT_POKE_READ && manager->fdpollinfo[fd].want_write == 1) { pfds[1].events = POLLOUT; pfds[1].fd = fd; writelen += sizeof(pfds[1]); } if (msg == SELECT_POKE_WRITE && manager->fdpollinfo[fd].want_read == 1) { pfds[1].events = POLLIN; pfds[1].fd = fd; writelen += sizeof(pfds[1]); } if (write(manager->devpoll_fd, pfds, writelen) == -1) result = isc__errno2result(errno); else { if (msg == SELECT_POKE_READ) manager->fdpollinfo[fd].want_read = 0; else manager->fdpollinfo[fd].want_write = 0; } UNLOCK(&manager->fdlock[lockid]); return (result); #elif defined(USE_SELECT) LOCK(&manager->lock); if (msg == SELECT_POKE_READ) FD_CLR(fd, manager->read_fds); else if (msg == SELECT_POKE_WRITE) FD_CLR(fd, manager->write_fds); UNLOCK(&manager->lock); return (result); #endif } static void wakeup_socket(isc__socketmgr_t *manager, int fd, int msg) { isc_result_t result; int lockid = FDLOCK_ID(fd); /* * This is a wakeup on a socket. If the socket is not in the * process of being closed, start watching it for either reads * or writes. */ INSIST(fd >= 0 && fd < (int)manager->maxsocks); if (msg == SELECT_POKE_CLOSE) { /* No one should be updating fdstate, so no need to lock it */ INSIST(manager->fdstate[fd] == CLOSE_PENDING); manager->fdstate[fd] = CLOSED; (void)unwatch_fd(manager, fd, SELECT_POKE_READ); (void)unwatch_fd(manager, fd, SELECT_POKE_WRITE); (void)close(fd); return; } LOCK(&manager->fdlock[lockid]); if (manager->fdstate[fd] == CLOSE_PENDING) { UNLOCK(&manager->fdlock[lockid]); /* * We accept (and ignore) any error from unwatch_fd() as we are * closing the socket, hoping it doesn't leave dangling state in * the kernel. * Note that unwatch_fd() must be called after releasing the * fdlock; otherwise it could cause deadlock due to a lock order * reversal. */ (void)unwatch_fd(manager, fd, SELECT_POKE_READ); (void)unwatch_fd(manager, fd, SELECT_POKE_WRITE); return; } if (manager->fdstate[fd] != MANAGED) { UNLOCK(&manager->fdlock[lockid]); return; } UNLOCK(&manager->fdlock[lockid]); /* * Set requested bit. */ result = watch_fd(manager, fd, msg); if (result != ISC_R_SUCCESS) { /* * XXXJT: what should we do? Ignoring the failure of watching * a socket will make the application dysfunctional, but there * seems to be no reasonable recovery process. */ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, "failed to start watching FD (%d): %s", fd, isc_result_totext(result)); } } #ifdef USE_WATCHER_THREAD /* * Poke the select loop when there is something for us to do. * The write is required (by POSIX) to complete. That is, we * will not get partial writes. */ static void select_poke(isc__socketmgr_t *mgr, int fd, int msg) { int cc; int buf[2]; char strbuf[ISC_STRERRORSIZE]; buf[0] = fd; buf[1] = msg; do { cc = write(mgr->pipe_fds[1], buf, sizeof(buf)); #ifdef ENOSR /* * Treat ENOSR as EAGAIN but loop slowly as it is * unlikely to clear fast. */ if (cc < 0 && errno == ENOSR) { sleep(1); errno = EAGAIN; } #endif } while (cc < 0 && SOFT_ERROR(errno)); if (cc < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); FATAL_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_WRITEFAILED, "write() failed " "during watcher poke: %s"), strbuf); } INSIST(cc == sizeof(buf)); } /* * Read a message on the internal fd. */ static void select_readmsg(isc__socketmgr_t *mgr, int *fd, int *msg) { int buf[2]; int cc; char strbuf[ISC_STRERRORSIZE]; cc = read(mgr->pipe_fds[0], buf, sizeof(buf)); if (cc < 0) { *msg = SELECT_POKE_NOTHING; *fd = -1; /* Silence compiler. */ if (SOFT_ERROR(errno)) return; isc__strerror(errno, strbuf, sizeof(strbuf)); FATAL_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_READFAILED, "read() failed " "during watcher poke: %s"), strbuf); } INSIST(cc == sizeof(buf)); *fd = buf[0]; *msg = buf[1]; } #else /* USE_WATCHER_THREAD */ /* * Update the state of the socketmgr when something changes. */ static void select_poke(isc__socketmgr_t *manager, int fd, int msg) { if (msg == SELECT_POKE_SHUTDOWN) return; else if (fd >= 0) wakeup_socket(manager, fd, msg); return; } #endif /* USE_WATCHER_THREAD */ /* * Make a fd non-blocking. */ static isc_result_t make_nonblock(int fd) { int ret; int flags; char strbuf[ISC_STRERRORSIZE]; #ifdef USE_FIONBIO_IOCTL int on = 1; ret = ioctl(fd, FIONBIO, (char *)&on); #else flags = fcntl(fd, F_GETFL, 0); flags |= PORT_NONBLOCK; ret = fcntl(fd, F_SETFL, flags); #endif if (ret == -1) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, #ifdef USE_FIONBIO_IOCTL "ioctl(%d, FIONBIO, &on): %s", fd, #else "fcntl(%d, F_SETFL, %d): %s", fd, flags, #endif strbuf); return (ISC_R_UNEXPECTED); } return (ISC_R_SUCCESS); } #ifdef USE_CMSG /* * Not all OSes support advanced CMSG macros: CMSG_LEN and CMSG_SPACE. * In order to ensure as much portability as possible, we provide wrapper * functions of these macros. * Note that cmsg_space() could run slow on OSes that do not have * CMSG_SPACE. */ static inline ISC_SOCKADDR_LEN_T cmsg_len(ISC_SOCKADDR_LEN_T len) { #ifdef CMSG_LEN return (CMSG_LEN(len)); #else ISC_SOCKADDR_LEN_T hdrlen; /* * Cast NULL so that any pointer arithmetic performed by CMSG_DATA * is correct. */ hdrlen = (ISC_SOCKADDR_LEN_T)CMSG_DATA(((struct cmsghdr *)NULL)); return (hdrlen + len); #endif } static inline ISC_SOCKADDR_LEN_T cmsg_space(ISC_SOCKADDR_LEN_T len) { #ifdef CMSG_SPACE return (CMSG_SPACE(len)); #else struct msghdr msg; struct cmsghdr *cmsgp; /* * XXX: The buffer length is an ad-hoc value, but should be enough * in a practical sense. */ char dummybuf[sizeof(struct cmsghdr) + 1024]; memset(&msg, 0, sizeof(msg)); msg.msg_control = dummybuf; msg.msg_controllen = sizeof(dummybuf); cmsgp = (struct cmsghdr *)dummybuf; cmsgp->cmsg_len = cmsg_len(len); cmsgp = CMSG_NXTHDR(&msg, cmsgp); if (cmsgp != NULL) return ((char *)cmsgp - (char *)msg.msg_control); else return (0); #endif } #endif /* USE_CMSG */ /* * Process control messages received on a socket. */ static void process_cmsg(isc__socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) { #ifdef USE_CMSG struct cmsghdr *cmsgp; #ifdef ISC_PLATFORM_HAVEIN6PKTINFO struct in6_pktinfo *pktinfop; #endif #ifdef SO_TIMESTAMP void *timevalp; #endif #endif /* * sock is used only when ISC_NET_BSD44MSGHDR and USE_CMSG are defined. * msg and dev are used only when ISC_NET_BSD44MSGHDR is defined. * They are all here, outside of the CPP tests, because it is * more consistent with the usual ISC coding style. */ UNUSED(sock); UNUSED(msg); UNUSED(dev); #ifdef ISC_NET_BSD44MSGHDR #ifdef MSG_TRUNC if ((msg->msg_flags & MSG_TRUNC) == MSG_TRUNC) dev->attributes |= ISC_SOCKEVENTATTR_TRUNC; #endif #ifdef MSG_CTRUNC if ((msg->msg_flags & MSG_CTRUNC) == MSG_CTRUNC) dev->attributes |= ISC_SOCKEVENTATTR_CTRUNC; #endif #ifndef USE_CMSG return; #else if (msg->msg_controllen == 0U || msg->msg_control == NULL) return; #ifdef SO_TIMESTAMP timevalp = NULL; #endif #ifdef ISC_PLATFORM_HAVEIN6PKTINFO pktinfop = NULL; #endif cmsgp = CMSG_FIRSTHDR(msg); while (cmsgp != NULL) { socket_log(sock, NULL, TRACE, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_PROCESSCMSG, "processing cmsg %p", cmsgp); #ifdef ISC_PLATFORM_HAVEIN6PKTINFO if (cmsgp->cmsg_level == IPPROTO_IPV6 && cmsgp->cmsg_type == IPV6_PKTINFO) { pktinfop = (struct in6_pktinfo *)CMSG_DATA(cmsgp); memmove(&dev->pktinfo, pktinfop, sizeof(struct in6_pktinfo)); dev->attributes |= ISC_SOCKEVENTATTR_PKTINFO; socket_log(sock, NULL, TRACE, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_IFRECEIVED, "interface received on ifindex %u", dev->pktinfo.ipi6_ifindex); if (IN6_IS_ADDR_MULTICAST(&pktinfop->ipi6_addr)) dev->attributes |= ISC_SOCKEVENTATTR_MULTICAST; goto next; } #endif #ifdef SO_TIMESTAMP if (cmsgp->cmsg_level == SOL_SOCKET && cmsgp->cmsg_type == SCM_TIMESTAMP) { struct timeval tv; timevalp = CMSG_DATA(cmsgp); memmove(&tv, timevalp, sizeof(tv)); dev->timestamp.seconds = tv.tv_sec; dev->timestamp.nanoseconds = tv.tv_usec * 1000; dev->attributes |= ISC_SOCKEVENTATTR_TIMESTAMP; goto next; } #endif #ifdef IPV6_TCLASS if (cmsgp->cmsg_level == IPPROTO_IPV6 && cmsgp->cmsg_type == IPV6_TCLASS) { dev->dscp = *(int *)CMSG_DATA(cmsgp); dev->dscp >>= 2; dev->attributes |= ISC_SOCKEVENTATTR_DSCP; goto next; } #endif #ifdef IP_TOS if (cmsgp->cmsg_level == IPPROTO_IP && (cmsgp->cmsg_type == IP_TOS #ifdef IP_RECVTOS || cmsgp->cmsg_type == IP_RECVTOS #endif )) { dev->dscp = (int) *(unsigned char *)CMSG_DATA(cmsgp); dev->dscp >>= 2; dev->attributes |= ISC_SOCKEVENTATTR_DSCP; goto next; } #endif next: cmsgp = CMSG_NXTHDR(msg, cmsgp); } #endif /* USE_CMSG */ #endif /* ISC_NET_BSD44MSGHDR */ } /* * Construct an iov array and attach it to the msghdr passed in. This is * the SEND constructor, which will use the used region of the buffer * (if using a buffer list) or will use the internal region (if a single * buffer I/O is requested). * * Nothing can be NULL, and the done event must list at least one buffer * on the buffer linked list for this function to be meaningful. * * If write_countp != NULL, *write_countp will hold the number of bytes * this transaction can send. */ static void build_msghdr_send(isc__socket_t *sock, isc_socketevent_t *dev, struct msghdr *msg, struct iovec *iov, size_t *write_countp) { unsigned int iovcount; isc_buffer_t *buffer; isc_region_t used; size_t write_count; size_t skip_count; #ifdef ISC_NET_BSD44MSGHDR struct cmsghdr *cmsgp; #endif memset(msg, 0, sizeof(*msg)); if (!sock->connected) { msg->msg_name = (void *)&dev->address.type.sa; msg->msg_namelen = dev->address.length; } else { msg->msg_name = NULL; msg->msg_namelen = 0; } buffer = ISC_LIST_HEAD(dev->bufferlist); write_count = 0; iovcount = 0; /* * Single buffer I/O? Skip what we've done so far in this region. */ if (buffer == NULL) { write_count = dev->region.length - dev->n; iov[0].iov_base = (void *)(dev->region.base + dev->n); iov[0].iov_len = write_count; iovcount = 1; goto config; } /* * Multibuffer I/O. * Skip the data in the buffer list that we have already written. */ skip_count = dev->n; while (buffer != NULL) { REQUIRE(ISC_BUFFER_VALID(buffer)); if (skip_count < isc_buffer_usedlength(buffer)) break; skip_count -= isc_buffer_usedlength(buffer); buffer = ISC_LIST_NEXT(buffer, link); } while (buffer != NULL) { INSIST(iovcount < MAXSCATTERGATHER_SEND); isc_buffer_usedregion(buffer, &used); if (used.length > 0) { iov[iovcount].iov_base = (void *)(used.base + skip_count); iov[iovcount].iov_len = used.length - skip_count; write_count += (used.length - skip_count); skip_count = 0; iovcount++; } buffer = ISC_LIST_NEXT(buffer, link); } INSIST(skip_count == 0U); config: msg->msg_iov = iov; msg->msg_iovlen = iovcount; #ifdef ISC_NET_BSD44MSGHDR msg->msg_control = NULL; msg->msg_controllen = 0; msg->msg_flags = 0; #if defined(USE_CMSG) && defined(ISC_PLATFORM_HAVEIN6PKTINFO) if ((sock->type == isc_sockettype_udp) && ((dev->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0)) { #if defined(IPV6_USE_MIN_MTU) int use_min_mtu = 1; /* -1, 0, 1 */ #endif struct in6_pktinfo *pktinfop; socket_log(sock, NULL, TRACE, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_SENDTODATA, "sendto pktinfo data, ifindex %u", dev->pktinfo.ipi6_ifindex); msg->msg_controllen = cmsg_space(sizeof(struct in6_pktinfo)); INSIST(msg->msg_controllen <= sock->sendcmsgbuflen); msg->msg_control = (void *)sock->sendcmsgbuf; cmsgp = (struct cmsghdr *)sock->sendcmsgbuf; cmsgp->cmsg_level = IPPROTO_IPV6; cmsgp->cmsg_type = IPV6_PKTINFO; cmsgp->cmsg_len = cmsg_len(sizeof(struct in6_pktinfo)); pktinfop = (struct in6_pktinfo *)CMSG_DATA(cmsgp); memmove(pktinfop, &dev->pktinfo, sizeof(struct in6_pktinfo)); #if defined(IPV6_USE_MIN_MTU) /* * Set IPV6_USE_MIN_MTU as a per packet option as FreeBSD * ignores setsockopt(IPV6_USE_MIN_MTU) when IPV6_PKTINFO * is used. */ cmsgp = (struct cmsghdr *)(sock->sendcmsgbuf + msg->msg_controllen); msg->msg_controllen += cmsg_space(sizeof(use_min_mtu)); INSIST(msg->msg_controllen <= sock->sendcmsgbuflen); cmsgp->cmsg_level = IPPROTO_IPV6; cmsgp->cmsg_type = IPV6_USE_MIN_MTU; cmsgp->cmsg_len = cmsg_len(sizeof(use_min_mtu)); memmove(CMSG_DATA(cmsgp), &use_min_mtu, sizeof(use_min_mtu)); #endif } if (isc_dscp_check_value > -1) { if (sock->type == isc_sockettype_udp) INSIST((int)dev->dscp == isc_dscp_check_value); else if (sock->type == isc_sockettype_tcp) INSIST((int)sock->dscp == isc_dscp_check_value); } if ((sock->type == isc_sockettype_udp) && ((dev->attributes & ISC_SOCKEVENTATTR_DSCP) != 0)) { int dscp = (dev->dscp << 2) & 0xff; INSIST(dev->dscp < 0x40); #ifdef IP_TOS if (sock->pf == AF_INET && sock->pktdscp) { cmsgp = (struct cmsghdr *)(sock->sendcmsgbuf + msg->msg_controllen); msg->msg_control = (void *)sock->sendcmsgbuf; msg->msg_controllen += cmsg_space(sizeof(dscp)); INSIST(msg->msg_controllen <= sock->sendcmsgbuflen); cmsgp->cmsg_level = IPPROTO_IP; cmsgp->cmsg_type = IP_TOS; cmsgp->cmsg_len = cmsg_len(sizeof(char)); *(unsigned char*)CMSG_DATA(cmsgp) = dscp; } else if (sock->pf == AF_INET && sock->dscp != dev->dscp) { if (setsockopt(sock->fd, IPPROTO_IP, IP_TOS, (void *)&dscp, sizeof(int)) < 0) { char strbuf[ISC_STRERRORSIZE]; isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, IP_TOS, %.02x)" " %s: %s", sock->fd, dscp >> 2, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); } else sock->dscp = dscp; } #endif #if defined(IPPROTO_IPV6) && defined(IPV6_TCLASS) if (sock->pf == AF_INET6 && sock->pktdscp) { cmsgp = (struct cmsghdr *)(sock->sendcmsgbuf + msg->msg_controllen); msg->msg_control = (void *)sock->sendcmsgbuf; msg->msg_controllen += cmsg_space(sizeof(dscp)); INSIST(msg->msg_controllen <= sock->sendcmsgbuflen); cmsgp->cmsg_level = IPPROTO_IPV6; cmsgp->cmsg_type = IPV6_TCLASS; cmsgp->cmsg_len = cmsg_len(sizeof(dscp)); memmove(CMSG_DATA(cmsgp), &dscp, sizeof(dscp)); } else if (sock->pf == AF_INET6 && sock->dscp != dev->dscp) { if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_TCLASS, (void *)&dscp, sizeof(int)) < 0) { char strbuf[ISC_STRERRORSIZE]; isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, IPV6_TCLASS, " "%.02x) %s: %s", sock->fd, dscp >> 2, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); } else sock->dscp = dscp; } #endif } #endif /* USE_CMSG && ISC_PLATFORM_HAVEIPV6 */ #else /* ISC_NET_BSD44MSGHDR */ msg->msg_accrights = NULL; msg->msg_accrightslen = 0; #endif /* ISC_NET_BSD44MSGHDR */ if (write_countp != NULL) *write_countp = write_count; } /* * Construct an iov array and attach it to the msghdr passed in. This is * the RECV constructor, which will use the available region of the buffer * (if using a buffer list) or will use the internal region (if a single * buffer I/O is requested). * * Nothing can be NULL, and the done event must list at least one buffer * on the buffer linked list for this function to be meaningful. * * If read_countp != NULL, *read_countp will hold the number of bytes * this transaction can receive. */ static void build_msghdr_recv(isc__socket_t *sock, isc_socketevent_t *dev, struct msghdr *msg, struct iovec *iov, size_t *read_countp) { unsigned int iovcount; isc_buffer_t *buffer; isc_region_t available; size_t read_count; memset(msg, 0, sizeof(struct msghdr)); if (sock->type == isc_sockettype_udp) { memset(&dev->address, 0, sizeof(dev->address)); #ifdef BROKEN_RECVMSG if (sock->pf == AF_INET) { msg->msg_name = (void *)&dev->address.type.sin; msg->msg_namelen = sizeof(dev->address.type.sin6); } else if (sock->pf == AF_INET6) { msg->msg_name = (void *)&dev->address.type.sin6; msg->msg_namelen = sizeof(dev->address.type.sin6); #ifdef ISC_PLATFORM_HAVESYSUNH } else if (sock->pf == AF_UNIX) { msg->msg_name = (void *)&dev->address.type.sunix; msg->msg_namelen = sizeof(dev->address.type.sunix); #endif } else { msg->msg_name = (void *)&dev->address.type.sa; msg->msg_namelen = sizeof(dev->address.type); } #else msg->msg_name = (void *)&dev->address.type.sa; msg->msg_namelen = sizeof(dev->address.type); #endif #ifdef ISC_NET_RECVOVERFLOW /* If needed, steal one iovec for overflow detection. */ maxiov--; #endif } else { /* TCP */ msg->msg_name = NULL; msg->msg_namelen = 0; dev->address = sock->peer_address; } buffer = ISC_LIST_HEAD(dev->bufferlist); read_count = 0; /* * Single buffer I/O? Skip what we've done so far in this region. */ if (buffer == NULL) { read_count = dev->region.length - dev->n; iov[0].iov_base = (void *)(dev->region.base + dev->n); iov[0].iov_len = read_count; iovcount = 1; goto config; } /* * Multibuffer I/O. * Skip empty buffers. */ while (buffer != NULL) { REQUIRE(ISC_BUFFER_VALID(buffer)); if (isc_buffer_availablelength(buffer) != 0) break; buffer = ISC_LIST_NEXT(buffer, link); } iovcount = 0; while (buffer != NULL) { INSIST(iovcount < MAXSCATTERGATHER_RECV); isc_buffer_availableregion(buffer, &available); if (available.length > 0) { iov[iovcount].iov_base = (void *)(available.base); iov[iovcount].iov_len = available.length; read_count += available.length; iovcount++; } buffer = ISC_LIST_NEXT(buffer, link); } config: /* * If needed, set up to receive that one extra byte. Note that * we know there is at least one iov left, since we stole it * at the top of this function. */ #ifdef ISC_NET_RECVOVERFLOW if (sock->type == isc_sockettype_udp) { iov[iovcount].iov_base = (void *)(&sock->overflow); iov[iovcount].iov_len = 1; iovcount++; } #endif msg->msg_iov = iov; msg->msg_iovlen = iovcount; #ifdef ISC_NET_BSD44MSGHDR msg->msg_control = NULL; msg->msg_controllen = 0; msg->msg_flags = 0; #if defined(USE_CMSG) msg->msg_control = sock->recvcmsgbuf; msg->msg_controllen = sock->recvcmsgbuflen; #endif /* USE_CMSG */ #else /* ISC_NET_BSD44MSGHDR */ msg->msg_accrights = NULL; msg->msg_accrightslen = 0; #endif /* ISC_NET_BSD44MSGHDR */ if (read_countp != NULL) *read_countp = read_count; } static void set_dev_address(isc_sockaddr_t *address, isc__socket_t *sock, isc_socketevent_t *dev) { if (sock->type == isc_sockettype_udp) { if (address != NULL) dev->address = *address; else dev->address = sock->peer_address; } else if (sock->type == isc_sockettype_tcp) { INSIST(address == NULL); dev->address = sock->peer_address; } } static void destroy_socketevent(isc_event_t *event) { isc_socketevent_t *ev = (isc_socketevent_t *)event; INSIST(ISC_LIST_EMPTY(ev->bufferlist)); (ev->destroy)(event); } static isc_socketevent_t * allocate_socketevent(isc_mem_t *mctx, void *sender, isc_eventtype_t eventtype, isc_taskaction_t action, void *arg) { isc_socketevent_t *ev; ev = (isc_socketevent_t *)isc_event_allocate(mctx, sender, eventtype, action, arg, sizeof(*ev)); if (ev == NULL) return (NULL); ev->result = ISC_R_UNSET; ISC_LINK_INIT(ev, ev_link); ISC_LIST_INIT(ev->bufferlist); ev->region.base = NULL; ev->n = 0; ev->offset = 0; ev->attributes = 0; ev->destroy = ev->ev_destroy; ev->ev_destroy = destroy_socketevent; ev->dscp = 0; return (ev); } #if defined(ISC_SOCKET_DEBUG) static void dump_msg(struct msghdr *msg) { unsigned int i; printf("MSGHDR %p\n", msg); printf("\tname %p, namelen %ld\n", msg->msg_name, (long) msg->msg_namelen); printf("\tiov %p, iovlen %ld\n", msg->msg_iov, (long) msg->msg_iovlen); for (i = 0; i < (unsigned int)msg->msg_iovlen; i++) printf("\t\t%d\tbase %p, len %ld\n", i, msg->msg_iov[i].iov_base, (long) msg->msg_iov[i].iov_len); #ifdef ISC_NET_BSD44MSGHDR printf("\tcontrol %p, controllen %ld\n", msg->msg_control, (long) msg->msg_controllen); #endif } #endif #define DOIO_SUCCESS 0 /* i/o ok, event sent */ #define DOIO_SOFT 1 /* i/o ok, soft error, no event sent */ #define DOIO_HARD 2 /* i/o error, event sent */ #define DOIO_EOF 3 /* EOF, no event sent */ static int doio_recv(isc__socket_t *sock, isc_socketevent_t *dev) { int cc; struct iovec iov[MAXSCATTERGATHER_RECV]; size_t read_count; size_t actual_count; struct msghdr msghdr; isc_buffer_t *buffer; int recv_errno; char strbuf[ISC_STRERRORSIZE]; build_msghdr_recv(sock, dev, &msghdr, iov, &read_count); #if defined(ISC_SOCKET_DEBUG) dump_msg(&msghdr); #endif cc = recvmsg(sock->fd, &msghdr, 0); recv_errno = errno; #if defined(ISC_SOCKET_DEBUG) dump_msg(&msghdr); #endif if (cc < 0) { if (SOFT_ERROR(recv_errno)) return (DOIO_SOFT); if (isc_log_wouldlog(isc_lctx, IOEVENT_LEVEL)) { isc__strerror(recv_errno, strbuf, sizeof(strbuf)); socket_log(sock, NULL, IOEVENT, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_DOIORECV, "doio_recv: recvmsg(%d) %d bytes, err %d/%s", sock->fd, cc, recv_errno, strbuf); } #define SOFT_OR_HARD(_system, _isc) \ if (recv_errno == _system) { \ if (sock->connected) { \ dev->result = _isc; \ inc_stats(sock->manager->stats, \ sock->statsindex[STATID_RECVFAIL]); \ return (DOIO_HARD); \ } \ return (DOIO_SOFT); \ } #define ALWAYS_HARD(_system, _isc) \ if (recv_errno == _system) { \ dev->result = _isc; \ inc_stats(sock->manager->stats, \ sock->statsindex[STATID_RECVFAIL]); \ return (DOIO_HARD); \ } SOFT_OR_HARD(ECONNREFUSED, ISC_R_CONNREFUSED); SOFT_OR_HARD(ENETUNREACH, ISC_R_NETUNREACH); SOFT_OR_HARD(EHOSTUNREACH, ISC_R_HOSTUNREACH); SOFT_OR_HARD(EHOSTDOWN, ISC_R_HOSTDOWN); /* HPUX 11.11 can return EADDRNOTAVAIL. */ SOFT_OR_HARD(EADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL); ALWAYS_HARD(ENOBUFS, ISC_R_NORESOURCES); /* Should never get this one but it was seen. */ #ifdef ENOPROTOOPT SOFT_OR_HARD(ENOPROTOOPT, ISC_R_HOSTUNREACH); #endif /* * HPUX returns EPROTO and EINVAL on receiving some ICMP/ICMPv6 * errors. */ #ifdef EPROTO SOFT_OR_HARD(EPROTO, ISC_R_HOSTUNREACH); #endif SOFT_OR_HARD(EINVAL, ISC_R_HOSTUNREACH); #undef SOFT_OR_HARD #undef ALWAYS_HARD dev->result = isc__errno2result(recv_errno); inc_stats(sock->manager->stats, sock->statsindex[STATID_RECVFAIL]); return (DOIO_HARD); } /* * On TCP and UNIX sockets, zero length reads indicate EOF, * while on UDP sockets, zero length reads are perfectly valid, * although strange. */ switch (sock->type) { case isc_sockettype_tcp: case isc_sockettype_unix: if (cc == 0) return (DOIO_EOF); break; case isc_sockettype_udp: case isc_sockettype_raw: break; case isc_sockettype_fdwatch: default: INSIST(0); } if (sock->type == isc_sockettype_udp) { dev->address.length = msghdr.msg_namelen; if (isc_sockaddr_getport(&dev->address) == 0) { if (isc_log_wouldlog(isc_lctx, IOEVENT_LEVEL)) { socket_log(sock, &dev->address, IOEVENT, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ZEROPORT, "dropping source port zero packet"); } return (DOIO_SOFT); } /* * Simulate a firewall blocking UDP responses bigger than * 'maxudp' bytes. */ if (sock->manager->maxudp != 0 && cc > sock->manager->maxudp) return (DOIO_SOFT); } socket_log(sock, &dev->address, IOEVENT, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_PKTRECV, "packet received correctly"); /* * Overflow bit detection. If we received MORE bytes than we should, * this indicates an overflow situation. Set the flag in the * dev entry and adjust how much we read by one. */ #ifdef ISC_NET_RECVOVERFLOW if ((sock->type == isc_sockettype_udp) && ((size_t)cc > read_count)) { dev->attributes |= ISC_SOCKEVENTATTR_TRUNC; cc--; } #endif /* * If there are control messages attached, run through them and pull * out the interesting bits. */ process_cmsg(sock, &msghdr, dev); /* * update the buffers (if any) and the i/o count */ dev->n += cc; actual_count = cc; buffer = ISC_LIST_HEAD(dev->bufferlist); while (buffer != NULL && actual_count > 0U) { REQUIRE(ISC_BUFFER_VALID(buffer)); if (isc_buffer_availablelength(buffer) <= actual_count) { actual_count -= isc_buffer_availablelength(buffer); isc_buffer_add(buffer, isc_buffer_availablelength(buffer)); } else { isc_buffer_add(buffer, actual_count); actual_count = 0; POST(actual_count); break; } buffer = ISC_LIST_NEXT(buffer, link); if (buffer == NULL) { INSIST(actual_count == 0U); } } /* * If we read less than we expected, update counters, * and let the upper layer poke the descriptor. */ if (((size_t)cc != read_count) && (dev->n < dev->minimum)) return (DOIO_SOFT); /* * Full reads are posted, or partials if partials are ok. */ dev->result = ISC_R_SUCCESS; return (DOIO_SUCCESS); } /* * Returns: * DOIO_SUCCESS The operation succeeded. dev->result contains * ISC_R_SUCCESS. * * DOIO_HARD A hard or unexpected I/O error was encountered. * dev->result contains the appropriate error. * * DOIO_SOFT A soft I/O error was encountered. No senddone * event was sent. The operation should be retried. * * No other return values are possible. */ static int doio_send(isc__socket_t *sock, isc_socketevent_t *dev) { int cc; struct iovec iov[MAXSCATTERGATHER_SEND]; size_t write_count; struct msghdr msghdr; char addrbuf[ISC_SOCKADDR_FORMATSIZE]; int attempts = 0; int send_errno; char strbuf[ISC_STRERRORSIZE]; build_msghdr_send(sock, dev, &msghdr, iov, &write_count); resend: if (sock->type == isc_sockettype_udp && sock->manager->maxudp != 0 && write_count > (size_t)sock->manager->maxudp) cc = write_count; else cc = sendmsg(sock->fd, &msghdr, 0); send_errno = errno; /* * Check for error or block condition. */ if (cc < 0) { if (send_errno == EINTR && ++attempts < NRETRIES) goto resend; if (SOFT_ERROR(send_errno)) return (DOIO_SOFT); #define SOFT_OR_HARD(_system, _isc) \ if (send_errno == _system) { \ if (sock->connected) { \ dev->result = _isc; \ inc_stats(sock->manager->stats, \ sock->statsindex[STATID_SENDFAIL]); \ return (DOIO_HARD); \ } \ return (DOIO_SOFT); \ } #define ALWAYS_HARD(_system, _isc) \ if (send_errno == _system) { \ dev->result = _isc; \ inc_stats(sock->manager->stats, \ sock->statsindex[STATID_SENDFAIL]); \ return (DOIO_HARD); \ } SOFT_OR_HARD(ECONNREFUSED, ISC_R_CONNREFUSED); ALWAYS_HARD(EACCES, ISC_R_NOPERM); ALWAYS_HARD(EAFNOSUPPORT, ISC_R_ADDRNOTAVAIL); ALWAYS_HARD(EADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL); ALWAYS_HARD(EHOSTUNREACH, ISC_R_HOSTUNREACH); #ifdef EHOSTDOWN ALWAYS_HARD(EHOSTDOWN, ISC_R_HOSTUNREACH); #endif ALWAYS_HARD(ENETUNREACH, ISC_R_NETUNREACH); ALWAYS_HARD(ENOBUFS, ISC_R_NORESOURCES); ALWAYS_HARD(EPERM, ISC_R_HOSTUNREACH); ALWAYS_HARD(EPIPE, ISC_R_NOTCONNECTED); ALWAYS_HARD(ECONNRESET, ISC_R_CONNECTIONRESET); #undef SOFT_OR_HARD #undef ALWAYS_HARD /* * The other error types depend on whether or not the * socket is UDP or TCP. If it is UDP, some errors * that we expect to be fatal under TCP are merely * annoying, and are really soft errors. * * However, these soft errors are still returned as * a status. */ isc_sockaddr_format(&dev->address, addrbuf, sizeof(addrbuf)); isc__strerror(send_errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "internal_send: %s: %s", addrbuf, strbuf); dev->result = isc__errno2result(send_errno); inc_stats(sock->manager->stats, sock->statsindex[STATID_SENDFAIL]); return (DOIO_HARD); } if (cc == 0) { inc_stats(sock->manager->stats, sock->statsindex[STATID_SENDFAIL]); UNEXPECTED_ERROR(__FILE__, __LINE__, "doio_send: send() %s 0", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_RETURNED, "returned")); } /* * If we write less than we expected, update counters, poke. */ dev->n += cc; if ((size_t)cc != write_count) return (DOIO_SOFT); /* * Exactly what we wanted to write. We're done with this * entry. Post its completion event. */ dev->result = ISC_R_SUCCESS; return (DOIO_SUCCESS); } /* * Kill. * * Caller must ensure that the socket is not locked and no external * references exist. */ static void socketclose(isc__socketmgr_t *manager, isc__socket_t *sock, int fd) { isc_sockettype_t type = sock->type; int lockid = FDLOCK_ID(fd); /* * No one has this socket open, so the watcher doesn't have to be * poked, and the socket doesn't have to be locked. */ LOCK(&manager->fdlock[lockid]); manager->fds[fd] = NULL; if (type == isc_sockettype_fdwatch) manager->fdstate[fd] = CLOSED; else manager->fdstate[fd] = CLOSE_PENDING; UNLOCK(&manager->fdlock[lockid]); if (type == isc_sockettype_fdwatch) { /* * The caller may close the socket once this function returns, * and `fd' may be reassigned for a new socket. So we do * unwatch_fd() here, rather than defer it via select_poke(). * Note: this may complicate data protection among threads and * may reduce performance due to additional locks. One way to * solve this would be to dup() the watched descriptor, but we * take a simpler approach at this moment. */ (void)unwatch_fd(manager, fd, SELECT_POKE_READ); (void)unwatch_fd(manager, fd, SELECT_POKE_WRITE); } else select_poke(manager, fd, SELECT_POKE_CLOSE); inc_stats(manager->stats, sock->statsindex[STATID_CLOSE]); if (sock->active == 1) { dec_stats(manager->stats, sock->statsindex[STATID_ACTIVE]); sock->active = 0; } /* * update manager->maxfd here (XXX: this should be implemented more * efficiently) */ #ifdef USE_SELECT LOCK(&manager->lock); if (manager->maxfd == fd) { int i; manager->maxfd = 0; for (i = fd - 1; i >= 0; i--) { lockid = FDLOCK_ID(i); LOCK(&manager->fdlock[lockid]); if (manager->fdstate[i] == MANAGED) { manager->maxfd = i; UNLOCK(&manager->fdlock[lockid]); break; } UNLOCK(&manager->fdlock[lockid]); } #ifdef ISC_PLATFORM_USETHREADS if (manager->maxfd < manager->pipe_fds[0]) manager->maxfd = manager->pipe_fds[0]; #endif } UNLOCK(&manager->lock); #endif /* USE_SELECT */ } static void destroy(isc__socket_t **sockp) { int fd; isc__socket_t *sock = *sockp; isc__socketmgr_t *manager = sock->manager; socket_log(sock, NULL, CREATION, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_DESTROYING, "destroying"); INSIST(ISC_LIST_EMPTY(sock->accept_list)); INSIST(ISC_LIST_EMPTY(sock->recv_list)); INSIST(ISC_LIST_EMPTY(sock->send_list)); INSIST(sock->connect_ev == NULL); REQUIRE(sock->fd == -1 || sock->fd < (int)manager->maxsocks); if (sock->fd >= 0) { fd = sock->fd; sock->fd = -1; socketclose(manager, sock, fd); } LOCK(&manager->lock); ISC_LIST_UNLINK(manager->socklist, sock, link); #ifdef USE_WATCHER_THREAD if (ISC_LIST_EMPTY(manager->socklist)) SIGNAL(&manager->shutdown_ok); #endif /* USE_WATCHER_THREAD */ /* can't unlock manager as its memory context is still used */ free_socket(sockp); UNLOCK(&manager->lock); } static isc_result_t allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type, isc__socket_t **socketp) { isc__socket_t *sock; isc_result_t result; ISC_SOCKADDR_LEN_T cmsgbuflen; sock = isc_mem_get(manager->mctx, sizeof(*sock)); if (sock == NULL) return (ISC_R_NOMEMORY); sock->common.magic = 0; sock->common.impmagic = 0; sock->references = 0; sock->manager = manager; sock->type = type; sock->fd = -1; sock->dscp = 0; /* TOS/TCLASS is zero until set. */ sock->dupped = 0; sock->statsindex = NULL; sock->active = 0; ISC_LINK_INIT(sock, link); sock->recvcmsgbuf = NULL; sock->sendcmsgbuf = NULL; /* * Set up cmsg buffers. */ cmsgbuflen = 0; #if defined(USE_CMSG) && defined(ISC_PLATFORM_HAVEIN6PKTINFO) cmsgbuflen += cmsg_space(sizeof(struct in6_pktinfo)); #endif #if defined(USE_CMSG) && defined(SO_TIMESTAMP) cmsgbuflen += cmsg_space(sizeof(struct timeval)); #endif #if defined(USE_CMSG) && (defined(IPV6_TCLASS) || defined(IP_TOS)) cmsgbuflen += cmsg_space(sizeof(int)); #endif sock->recvcmsgbuflen = cmsgbuflen; if (sock->recvcmsgbuflen != 0U) { sock->recvcmsgbuf = isc_mem_get(manager->mctx, cmsgbuflen); if (sock->recvcmsgbuf == NULL) { result = ISC_R_NOMEMORY; goto error; } } cmsgbuflen = 0; #if defined(USE_CMSG) && defined(ISC_PLATFORM_HAVEIN6PKTINFO) cmsgbuflen += cmsg_space(sizeof(struct in6_pktinfo)); #if defined(IPV6_USE_MIN_MTU) /* * Provide space for working around FreeBSD's broken IPV6_USE_MIN_MTU * support. */ cmsgbuflen += cmsg_space(sizeof(int)); #endif #endif #if defined(USE_CMSG) && (defined(IP_TOS) || defined(IPV6_TCLASS)) cmsgbuflen += cmsg_space(sizeof(int)); #endif sock->sendcmsgbuflen = cmsgbuflen; if (sock->sendcmsgbuflen != 0U) { sock->sendcmsgbuf = isc_mem_get(manager->mctx, cmsgbuflen); if (sock->sendcmsgbuf == NULL) { result = ISC_R_NOMEMORY; goto error; } } memset(sock->name, 0, sizeof(sock->name)); sock->tag = NULL; /* * Set up list of readers and writers to be initially empty. */ ISC_LIST_INIT(sock->recv_list); ISC_LIST_INIT(sock->send_list); ISC_LIST_INIT(sock->accept_list); sock->connect_ev = NULL; sock->pending_recv = 0; sock->pending_send = 0; sock->pending_accept = 0; sock->listener = 0; sock->connected = 0; sock->connecting = 0; sock->bound = 0; sock->pktdscp = 0; /* * Initialize the lock. */ result = isc_mutex_init(&sock->lock); if (result != ISC_R_SUCCESS) { sock->common.magic = 0; sock->common.impmagic = 0; goto error; } /* * Initialize readable and writable events. */ ISC_EVENT_INIT(&sock->readable_ev, sizeof(intev_t), ISC_EVENTATTR_NOPURGE, NULL, ISC_SOCKEVENT_INTR, NULL, sock, sock, NULL, NULL); ISC_EVENT_INIT(&sock->writable_ev, sizeof(intev_t), ISC_EVENTATTR_NOPURGE, NULL, ISC_SOCKEVENT_INTW, NULL, sock, sock, NULL, NULL); sock->common.magic = ISCAPI_SOCKET_MAGIC; sock->common.impmagic = SOCKET_MAGIC; *socketp = sock; return (ISC_R_SUCCESS); error: if (sock->recvcmsgbuf != NULL) isc_mem_put(manager->mctx, sock->recvcmsgbuf, sock->recvcmsgbuflen); if (sock->sendcmsgbuf != NULL) isc_mem_put(manager->mctx, sock->sendcmsgbuf, sock->sendcmsgbuflen); isc_mem_put(manager->mctx, sock, sizeof(*sock)); return (result); } /* * This event requires that the various lists be empty, that the reference * count be 1, and that the magic number is valid. The other socket bits, * like the lock, must be initialized as well. The fd associated must be * marked as closed, by setting it to -1 on close, or this routine will * also close the socket. */ static void free_socket(isc__socket_t **socketp) { isc__socket_t *sock = *socketp; INSIST(sock->references == 0); INSIST(VALID_SOCKET(sock)); INSIST(!sock->connecting); INSIST(!sock->pending_recv); INSIST(!sock->pending_send); INSIST(!sock->pending_accept); INSIST(ISC_LIST_EMPTY(sock->recv_list)); INSIST(ISC_LIST_EMPTY(sock->send_list)); INSIST(ISC_LIST_EMPTY(sock->accept_list)); INSIST(!ISC_LINK_LINKED(sock, link)); if (sock->recvcmsgbuf != NULL) isc_mem_put(sock->manager->mctx, sock->recvcmsgbuf, sock->recvcmsgbuflen); if (sock->sendcmsgbuf != NULL) isc_mem_put(sock->manager->mctx, sock->sendcmsgbuf, sock->sendcmsgbuflen); sock->common.magic = 0; sock->common.impmagic = 0; DESTROYLOCK(&sock->lock); isc_mem_put(sock->manager->mctx, sock, sizeof(*sock)); *socketp = NULL; } #ifdef SO_RCVBUF static isc_once_t rcvbuf_once = ISC_ONCE_INIT; static int rcvbuf = RCVBUFSIZE; static void set_rcvbuf(void) { int fd; int max = rcvbuf, min; ISC_SOCKADDR_LEN_T len; fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); #if defined(ISC_PLATFORM_HAVEIPV6) if (fd == -1) { switch (errno) { case EPROTONOSUPPORT: case EPFNOSUPPORT: case EAFNOSUPPORT: /* * Linux 2.2 (and maybe others) return EINVAL instead of * EAFNOSUPPORT. */ case EINVAL: fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); break; } } #endif if (fd == -1) return; len = sizeof(min); if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void *)&min, &len) >= 0 && min < rcvbuf) { again: if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void *)&rcvbuf, sizeof(rcvbuf)) == -1) { if (errno == ENOBUFS && rcvbuf > min) { max = rcvbuf - 1; rcvbuf = (rcvbuf + min) / 2; goto again; } else { rcvbuf = min; goto cleanup; } } else min = rcvbuf; if (min != max) { rcvbuf = max; goto again; } } cleanup: close (fd); } #endif #ifdef SO_BSDCOMPAT /* * This really should not be necessary to do. Having to workout * which kernel version we are on at run time so that we don't cause * the kernel to issue a warning about us using a deprecated socket option. * Such warnings should *never* be on by default in production kernels. * * We can't do this a build time because executables are moved between * machines and hence kernels. * * We can't just not set SO_BSDCOMAT because some kernels require it. */ static isc_once_t bsdcompat_once = ISC_ONCE_INIT; isc_boolean_t bsdcompat = ISC_TRUE; static void clear_bsdcompat(void) { #ifdef __linux__ struct utsname buf; char *endp; long int major; long int minor; uname(&buf); /* Can only fail if buf is bad in Linux. */ /* Paranoia in parsing can be increased, but we trust uname(). */ major = strtol(buf.release, &endp, 10); if (*endp == '.') { minor = strtol(endp+1, &endp, 10); if ((major > 2) || ((major == 2) && (minor >= 4))) { bsdcompat = ISC_FALSE; } } #endif /* __linux __ */ } #endif static void use_min_mtu(isc__socket_t *sock) { #if !defined(IPV6_USE_MIN_MTU) && !defined(IPV6_MTU) UNUSED(sock); #endif #ifdef IPV6_USE_MIN_MTU /* use minimum MTU */ if (sock->pf == AF_INET6) { int on = 1; (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, (void *)&on, sizeof(on)); } #endif #if defined(IPV6_MTU) /* * Use minimum MTU on IPv6 sockets. */ if (sock->pf == AF_INET6) { int mtu = 1280; (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_MTU, &mtu, sizeof(mtu)); } #endif } static isc_result_t opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, isc__socket_t *dup_socket) { isc_result_t result; char strbuf[ISC_STRERRORSIZE]; const char *err = "socket"; int tries = 0; #if defined(USE_CMSG) || defined(SO_BSDCOMPAT) || defined(SO_NOSIGPIPE) int on = 1; #endif #if defined(SO_RCVBUF) ISC_SOCKADDR_LEN_T optlen; int size; #endif again: if (dup_socket == NULL) { switch (sock->type) { case isc_sockettype_udp: sock->fd = socket(sock->pf, SOCK_DGRAM, IPPROTO_UDP); break; case isc_sockettype_tcp: sock->fd = socket(sock->pf, SOCK_STREAM, IPPROTO_TCP); break; case isc_sockettype_unix: sock->fd = socket(sock->pf, SOCK_STREAM, 0); break; case isc_sockettype_raw: errno = EPFNOSUPPORT; /* * PF_ROUTE is a alias for PF_NETLINK on linux. */ #if defined(PF_ROUTE) if (sock->fd == -1 && sock->pf == PF_ROUTE) { #ifdef NETLINK_ROUTE sock->fd = socket(sock->pf, SOCK_RAW, NETLINK_ROUTE); #else sock->fd = socket(sock->pf, SOCK_RAW, 0); #endif if (sock->fd != -1) { #ifdef NETLINK_ROUTE struct sockaddr_nl sa; int n; /* * Do an implicit bind. */ memset(&sa, 0, sizeof(sa)); sa.nl_family = AF_NETLINK; sa.nl_groups = RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR; n = bind(sock->fd, (struct sockaddr *) &sa, sizeof(sa)); if (n < 0) { close(sock->fd); sock->fd = -1; } #endif sock->bound = 1; } } #endif break; case isc_sockettype_fdwatch: /* * We should not be called for isc_sockettype_fdwatch * sockets. */ INSIST(0); break; } } else { sock->fd = dup(dup_socket->fd); sock->dupped = 1; sock->bound = dup_socket->bound; } if (sock->fd == -1 && errno == EINTR && tries++ < 42) goto again; #ifdef F_DUPFD /* * Leave a space for stdio and TCP to work in. */ if (manager->reserved != 0 && sock->type == isc_sockettype_udp && sock->fd >= 0 && sock->fd < manager->reserved) { int new, tmp; new = fcntl(sock->fd, F_DUPFD, manager->reserved); tmp = errno; (void)close(sock->fd); errno = tmp; sock->fd = new; err = "isc_socket_create: fcntl/reserved"; } else if (sock->fd >= 0 && sock->fd < 20) { int new, tmp; new = fcntl(sock->fd, F_DUPFD, 20); tmp = errno; (void)close(sock->fd); errno = tmp; sock->fd = new; err = "isc_socket_create: fcntl"; } #endif if (sock->fd >= (int)manager->maxsocks) { (void)close(sock->fd); isc_log_iwrite(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_TOOMANYFDS, "socket: file descriptor exceeds limit (%d/%u)", sock->fd, manager->maxsocks); inc_stats(manager->stats, sock->statsindex[STATID_OPENFAIL]); return (ISC_R_NORESOURCES); } if (sock->fd < 0) { switch (errno) { case EMFILE: case ENFILE: isc__strerror(errno, strbuf, sizeof(strbuf)); isc_log_iwrite(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_TOOMANYFDS, "%s: %s", err, strbuf); /* fallthrough */ case ENOBUFS: inc_stats(manager->stats, sock->statsindex[STATID_OPENFAIL]); return (ISC_R_NORESOURCES); case EPROTONOSUPPORT: case EPFNOSUPPORT: case EAFNOSUPPORT: /* * Linux 2.2 (and maybe others) return EINVAL instead of * EAFNOSUPPORT. */ case EINVAL: inc_stats(manager->stats, sock->statsindex[STATID_OPENFAIL]); return (ISC_R_FAMILYNOSUPPORT); default: isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "%s() %s: %s", err, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); inc_stats(manager->stats, sock->statsindex[STATID_OPENFAIL]); return (ISC_R_UNEXPECTED); } } if (dup_socket != NULL) goto setup_done; result = make_nonblock(sock->fd); if (result != ISC_R_SUCCESS) { (void)close(sock->fd); inc_stats(manager->stats, sock->statsindex[STATID_OPENFAIL]); return (result); } #ifdef SO_BSDCOMPAT RUNTIME_CHECK(isc_once_do(&bsdcompat_once, clear_bsdcompat) == ISC_R_SUCCESS); if (sock->type != isc_sockettype_unix && bsdcompat && setsockopt(sock->fd, SOL_SOCKET, SO_BSDCOMPAT, (void *)&on, sizeof(on)) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, SO_BSDCOMPAT) %s: %s", sock->fd, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); /* Press on... */ } #endif #ifdef SO_NOSIGPIPE if (setsockopt(sock->fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&on, sizeof(on)) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, SO_NOSIGPIPE) %s: %s", sock->fd, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); /* Press on... */ } #endif /* * Use minimum mtu if possible. */ use_min_mtu(sock); #if defined(USE_CMSG) || defined(SO_RCVBUF) if (sock->type == isc_sockettype_udp) { #if defined(USE_CMSG) #if defined(SO_TIMESTAMP) if (setsockopt(sock->fd, SOL_SOCKET, SO_TIMESTAMP, (void *)&on, sizeof(on)) < 0 && errno != ENOPROTOOPT) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, SO_TIMESTAMP) %s: %s", sock->fd, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); /* Press on... */ } #endif /* SO_TIMESTAMP */ #if defined(ISC_PLATFORM_HAVEIPV6) if (sock->pf == AF_INET6 && sock->recvcmsgbuflen == 0U) { /* * Warn explicitly because this anomaly can be hidden * in usual operation (and unexpectedly appear later). */ UNEXPECTED_ERROR(__FILE__, __LINE__, "No buffer available to receive " "IPv6 destination"); } #ifdef ISC_PLATFORM_HAVEIN6PKTINFO #ifdef IPV6_RECVPKTINFO /* RFC 3542 */ if ((sock->pf == AF_INET6) && (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, (void *)&on, sizeof(on)) < 0)) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, IPV6_RECVPKTINFO) " "%s: %s", sock->fd, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); } #else /* RFC 2292 */ if ((sock->pf == AF_INET6) && (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_PKTINFO, (void *)&on, sizeof(on)) < 0)) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, IPV6_PKTINFO) %s: %s", sock->fd, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); } #endif /* IPV6_RECVPKTINFO */ #endif /* ISC_PLATFORM_HAVEIN6PKTINFO */ #if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DONT) /* * Turn off Path MTU discovery on IPv6/UDP sockets. */ if (sock->pf == AF_INET6) { int action = IPV6_PMTUDISC_DONT; (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &action, sizeof(action)); } #endif #endif /* ISC_PLATFORM_HAVEIPV6 */ #endif /* defined(USE_CMSG) */ #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) /* * Turn off Path MTU discovery on IPv4/UDP sockets. */ if (sock->pf == AF_INET) { int action = IP_PMTUDISC_DONT; (void)setsockopt(sock->fd, IPPROTO_IP, IP_MTU_DISCOVER, &action, sizeof(action)); } #endif #if defined(IP_DONTFRAG) /* * Turn off Path MTU discovery on IPv4/UDP sockets. */ if (sock->pf == AF_INET) { int off = 0; (void)setsockopt(sock->fd, IPPROTO_IP, IP_DONTFRAG, &off, sizeof(off)); } #endif #if defined(SO_RCVBUF) optlen = sizeof(size); if (getsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF, (void *)&size, &optlen) >= 0 && size < rcvbuf) { RUNTIME_CHECK(isc_once_do(&rcvbuf_once, set_rcvbuf) == ISC_R_SUCCESS); if (setsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF, (void *)&rcvbuf, sizeof(rcvbuf)) == -1) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, SO_RCVBUF, %d) %s: %s", sock->fd, rcvbuf, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); } } #endif } #ifdef IPV6_RECVTCLASS if ((sock->pf == AF_INET6) && (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVTCLASS, (void *)&on, sizeof(on)) < 0)) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, IPV6_RECVTCLASS) " "%s: %s", sock->fd, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); } #endif #ifdef IP_RECVTOS if ((sock->pf == AF_INET) && (setsockopt(sock->fd, IPPROTO_IP, IP_RECVTOS, (void *)&on, sizeof(on)) < 0)) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, IP_RECVTOS) " "%s: %s", sock->fd, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); } #endif #endif /* defined(USE_CMSG) || defined(SO_RCVBUF) */ setup_done: inc_stats(manager->stats, sock->statsindex[STATID_OPEN]); if (sock->active == 0) { inc_stats(manager->stats, sock->statsindex[STATID_ACTIVE]); sock->active = 1; } return (ISC_R_SUCCESS); } /* * Create a 'type' socket or duplicate an existing socket, managed * by 'manager'. Events will be posted to 'task' and when dispatched * 'action' will be called with 'arg' as the arg value. The new * socket is returned in 'socketp'. */ static isc_result_t socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, isc_socket_t **socketp, isc_socket_t *dup_socket) { isc__socket_t *sock = NULL; isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0; isc_result_t result; int lockid; REQUIRE(VALID_MANAGER(manager)); REQUIRE(socketp != NULL && *socketp == NULL); REQUIRE(type != isc_sockettype_fdwatch); result = allocate_socket(manager, type, &sock); if (result != ISC_R_SUCCESS) return (result); switch (sock->type) { case isc_sockettype_udp: sock->statsindex = (pf == AF_INET) ? udp4statsindex : udp6statsindex; #define DCSPPKT(pf) ((pf == AF_INET) ? ISC_NET_DSCPPKTV4 : ISC_NET_DSCPPKTV6) sock->pktdscp = (isc_net_probedscp() & DCSPPKT(pf)) != 0; break; case isc_sockettype_tcp: sock->statsindex = (pf == AF_INET) ? tcp4statsindex : tcp6statsindex; break; case isc_sockettype_unix: sock->statsindex = unixstatsindex; break; case isc_sockettype_raw: sock->statsindex = rawstatsindex; break; default: INSIST(0); } sock->pf = pf; result = opensocket(manager, sock, (isc__socket_t *)dup_socket); if (result != ISC_R_SUCCESS) { free_socket(&sock); return (result); } sock->common.methods = (isc_socketmethods_t *)&socketmethods; sock->references = 1; *socketp = (isc_socket_t *)sock; /* * Note we don't have to lock the socket like we normally would because * there are no external references to it yet. */ lockid = FDLOCK_ID(sock->fd); LOCK(&manager->fdlock[lockid]); manager->fds[sock->fd] = sock; manager->fdstate[sock->fd] = MANAGED; #ifdef USE_DEVPOLL INSIST(sock->manager->fdpollinfo[sock->fd].want_read == 0 && sock->manager->fdpollinfo[sock->fd].want_write == 0); #endif UNLOCK(&manager->fdlock[lockid]); LOCK(&manager->lock); ISC_LIST_APPEND(manager->socklist, sock, link); #ifdef USE_SELECT if (manager->maxfd < sock->fd) manager->maxfd = sock->fd; #endif UNLOCK(&manager->lock); socket_log(sock, NULL, CREATION, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_CREATED, dup_socket != NULL ? "dupped" : "created"); return (ISC_R_SUCCESS); } /*% * Create a new 'type' socket managed by 'manager'. Events * will be posted to 'task' and when dispatched 'action' will be * called with 'arg' as the arg value. The new socket is returned * in 'socketp'. */ isc_result_t isc__socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, isc_socket_t **socketp) { return (socket_create(manager0, pf, type, socketp, NULL)); } /*% * Duplicate an existing socket. The new socket is returned * in 'socketp'. */ isc_result_t isc__socket_dup(isc_socket_t *sock0, isc_socket_t **socketp) { isc__socket_t *sock = (isc__socket_t *)sock0; REQUIRE(VALID_SOCKET(sock)); REQUIRE(socketp != NULL && *socketp == NULL); return (socket_create((isc_socketmgr_t *) sock->manager, sock->pf, sock->type, socketp, sock0)); } isc_result_t isc__socket_open(isc_socket_t *sock0) { isc_result_t result; isc__socket_t *sock = (isc__socket_t *)sock0; REQUIRE(VALID_SOCKET(sock)); LOCK(&sock->lock); REQUIRE(sock->references == 1); REQUIRE(sock->type != isc_sockettype_fdwatch); UNLOCK(&sock->lock); /* * We don't need to retain the lock hereafter, since no one else has * this socket. */ REQUIRE(sock->fd == -1); result = opensocket(sock->manager, sock, NULL); if (result != ISC_R_SUCCESS) sock->fd = -1; if (result == ISC_R_SUCCESS) { int lockid = FDLOCK_ID(sock->fd); LOCK(&sock->manager->fdlock[lockid]); sock->manager->fds[sock->fd] = sock; sock->manager->fdstate[sock->fd] = MANAGED; #ifdef USE_DEVPOLL INSIST(sock->manager->fdpollinfo[sock->fd].want_read == 0 && sock->manager->fdpollinfo[sock->fd].want_write == 0); #endif UNLOCK(&sock->manager->fdlock[lockid]); #ifdef USE_SELECT LOCK(&sock->manager->lock); if (sock->manager->maxfd < sock->fd) sock->manager->maxfd = sock->fd; UNLOCK(&sock->manager->lock); #endif } return (result); } /* * Create a new 'type' socket managed by 'manager'. Events * will be posted to 'task' and when dispatched 'action' will be * called with 'arg' as the arg value. The new socket is returned * in 'socketp'. */ isc_result_t isc__socket_fdwatchcreate(isc_socketmgr_t *manager0, int fd, int flags, isc_sockfdwatch_t callback, void *cbarg, isc_task_t *task, isc_socket_t **socketp) { isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0; isc__socket_t *sock = NULL; isc_result_t result; int lockid; REQUIRE(VALID_MANAGER(manager)); REQUIRE(socketp != NULL && *socketp == NULL); result = allocate_socket(manager, isc_sockettype_fdwatch, &sock); if (result != ISC_R_SUCCESS) return (result); sock->fd = fd; sock->fdwatcharg = cbarg; sock->fdwatchcb = callback; sock->fdwatchflags = flags; sock->fdwatchtask = task; sock->statsindex = fdwatchstatsindex; sock->common.methods = (isc_socketmethods_t *)&socketmethods; sock->references = 1; *socketp = (isc_socket_t *)sock; /* * Note we don't have to lock the socket like we normally would because * there are no external references to it yet. */ lockid = FDLOCK_ID(sock->fd); LOCK(&manager->fdlock[lockid]); manager->fds[sock->fd] = sock; manager->fdstate[sock->fd] = MANAGED; UNLOCK(&manager->fdlock[lockid]); LOCK(&manager->lock); ISC_LIST_APPEND(manager->socklist, sock, link); #ifdef USE_SELECT if (manager->maxfd < sock->fd) manager->maxfd = sock->fd; #endif UNLOCK(&manager->lock); if (flags & ISC_SOCKFDWATCH_READ) select_poke(sock->manager, sock->fd, SELECT_POKE_READ); if (flags & ISC_SOCKFDWATCH_WRITE) select_poke(sock->manager, sock->fd, SELECT_POKE_WRITE); socket_log(sock, NULL, CREATION, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_CREATED, "fdwatch-created"); return (ISC_R_SUCCESS); } /* * Indicate to the manager that it should watch the socket again. * This can be used to restart watching if the previous event handler * didn't indicate there was more data to be processed. Primarily * it is for writing but could be used for reading if desired */ isc_result_t isc__socket_fdwatchpoke(isc_socket_t *sock0, int flags) { isc__socket_t *sock = (isc__socket_t *)sock0; REQUIRE(VALID_SOCKET(sock)); /* * We check both flags first to allow us to get the lock * once but only if we need it. */ if ((flags & (ISC_SOCKFDWATCH_READ | ISC_SOCKFDWATCH_WRITE)) != 0) { LOCK(&sock->lock); if (((flags & ISC_SOCKFDWATCH_READ) != 0) && !sock->pending_recv) select_poke(sock->manager, sock->fd, SELECT_POKE_READ); if (((flags & ISC_SOCKFDWATCH_WRITE) != 0) && !sock->pending_send) select_poke(sock->manager, sock->fd, SELECT_POKE_WRITE); UNLOCK(&sock->lock); } socket_log(sock, NULL, TRACE, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_POKED, "fdwatch-poked flags: %d", flags); return (ISC_R_SUCCESS); } /* * Attach to a socket. Caller must explicitly detach when it is done. */ void isc__socket_attach(isc_socket_t *sock0, isc_socket_t **socketp) { isc__socket_t *sock = (isc__socket_t *)sock0; REQUIRE(VALID_SOCKET(sock)); REQUIRE(socketp != NULL && *socketp == NULL); LOCK(&sock->lock); sock->references++; UNLOCK(&sock->lock); *socketp = (isc_socket_t *)sock; } /* * Dereference a socket. If this is the last reference to it, clean things * up by destroying the socket. */ void isc__socket_detach(isc_socket_t **socketp) { isc__socket_t *sock; isc_boolean_t kill_socket = ISC_FALSE; REQUIRE(socketp != NULL); sock = (isc__socket_t *)*socketp; REQUIRE(VALID_SOCKET(sock)); LOCK(&sock->lock); REQUIRE(sock->references > 0); sock->references--; if (sock->references == 0) kill_socket = ISC_TRUE; UNLOCK(&sock->lock); if (kill_socket) destroy(&sock); *socketp = NULL; } isc_result_t isc__socket_close(isc_socket_t *sock0) { isc__socket_t *sock = (isc__socket_t *)sock0; int fd; isc__socketmgr_t *manager; fflush(stdout); REQUIRE(VALID_SOCKET(sock)); LOCK(&sock->lock); REQUIRE(sock->references == 1); REQUIRE(sock->type != isc_sockettype_fdwatch); REQUIRE(sock->fd >= 0 && sock->fd < (int)sock->manager->maxsocks); INSIST(!sock->connecting); INSIST(!sock->pending_recv); INSIST(!sock->pending_send); INSIST(!sock->pending_accept); INSIST(ISC_LIST_EMPTY(sock->recv_list)); INSIST(ISC_LIST_EMPTY(sock->send_list)); INSIST(ISC_LIST_EMPTY(sock->accept_list)); INSIST(sock->connect_ev == NULL); manager = sock->manager; fd = sock->fd; sock->fd = -1; sock->dupped = 0; memset(sock->name, 0, sizeof(sock->name)); sock->tag = NULL; sock->listener = 0; sock->connected = 0; sock->connecting = 0; sock->bound = 0; isc_sockaddr_any(&sock->peer_address); UNLOCK(&sock->lock); socketclose(manager, sock, fd); return (ISC_R_SUCCESS); } /* * I/O is possible on a given socket. Schedule an event to this task that * will call an internal function to do the I/O. This will charge the * task with the I/O operation and let our select loop handler get back * to doing something real as fast as possible. * * The socket and manager must be locked before calling this function. */ static void dispatch_recv(isc__socket_t *sock) { intev_t *iev; isc_socketevent_t *ev; isc_task_t *sender; INSIST(!sock->pending_recv); if (sock->type != isc_sockettype_fdwatch) { ev = ISC_LIST_HEAD(sock->recv_list); if (ev == NULL) return; socket_log(sock, NULL, EVENT, NULL, 0, 0, "dispatch_recv: event %p -> task %p", ev, ev->ev_sender); sender = ev->ev_sender; } else { sender = sock->fdwatchtask; } sock->pending_recv = 1; iev = &sock->readable_ev; sock->references++; iev->ev_sender = sock; if (sock->type == isc_sockettype_fdwatch) iev->ev_action = internal_fdwatch_read; else iev->ev_action = internal_recv; iev->ev_arg = sock; isc_task_send(sender, (isc_event_t **)&iev); } static void dispatch_send(isc__socket_t *sock) { intev_t *iev; isc_socketevent_t *ev; isc_task_t *sender; INSIST(!sock->pending_send); if (sock->type != isc_sockettype_fdwatch) { ev = ISC_LIST_HEAD(sock->send_list); if (ev == NULL) return; socket_log(sock, NULL, EVENT, NULL, 0, 0, "dispatch_send: event %p -> task %p", ev, ev->ev_sender); sender = ev->ev_sender; } else { sender = sock->fdwatchtask; } sock->pending_send = 1; iev = &sock->writable_ev; sock->references++; iev->ev_sender = sock; if (sock->type == isc_sockettype_fdwatch) iev->ev_action = internal_fdwatch_write; else iev->ev_action = internal_send; iev->ev_arg = sock; isc_task_send(sender, (isc_event_t **)&iev); } /* * Dispatch an internal accept event. */ static void dispatch_accept(isc__socket_t *sock) { intev_t *iev; isc_socket_newconnev_t *ev; INSIST(!sock->pending_accept); /* * Are there any done events left, or were they all canceled * before the manager got the socket lock? */ ev = ISC_LIST_HEAD(sock->accept_list); if (ev == NULL) return; sock->pending_accept = 1; iev = &sock->readable_ev; sock->references++; /* keep socket around for this internal event */ iev->ev_sender = sock; iev->ev_action = internal_accept; iev->ev_arg = sock; isc_task_send(ev->ev_sender, (isc_event_t **)&iev); } static void dispatch_connect(isc__socket_t *sock) { intev_t *iev; isc_socket_connev_t *ev; iev = &sock->writable_ev; ev = sock->connect_ev; INSIST(ev != NULL); /* XXX */ INSIST(sock->connecting); sock->references++; /* keep socket around for this internal event */ iev->ev_sender = sock; iev->ev_action = internal_connect; iev->ev_arg = sock; isc_task_send(ev->ev_sender, (isc_event_t **)&iev); } /* * Dequeue an item off the given socket's read queue, set the result code * in the done event to the one provided, and send it to the task it was * destined for. * * If the event to be sent is on a list, remove it before sending. If * asked to, send and detach from the socket as well. * * Caller must have the socket locked if the event is attached to the socket. */ static void send_recvdone_event(isc__socket_t *sock, isc_socketevent_t **dev) { isc_task_t *task; task = (*dev)->ev_sender; (*dev)->ev_sender = sock; if (ISC_LINK_LINKED(*dev, ev_link)) ISC_LIST_DEQUEUE(sock->recv_list, *dev, ev_link); if (((*dev)->attributes & ISC_SOCKEVENTATTR_ATTACHED) == ISC_SOCKEVENTATTR_ATTACHED) isc_task_sendanddetach(&task, (isc_event_t **)dev); else isc_task_send(task, (isc_event_t **)dev); } /* * See comments for send_recvdone_event() above. * * Caller must have the socket locked if the event is attached to the socket. */ static void send_senddone_event(isc__socket_t *sock, isc_socketevent_t **dev) { isc_task_t *task; INSIST(dev != NULL && *dev != NULL); task = (*dev)->ev_sender; (*dev)->ev_sender = sock; if (ISC_LINK_LINKED(*dev, ev_link)) ISC_LIST_DEQUEUE(sock->send_list, *dev, ev_link); if (((*dev)->attributes & ISC_SOCKEVENTATTR_ATTACHED) == ISC_SOCKEVENTATTR_ATTACHED) isc_task_sendanddetach(&task, (isc_event_t **)dev); else isc_task_send(task, (isc_event_t **)dev); } /* * Call accept() on a socket, to get the new file descriptor. The listen * socket is used as a prototype to create a new isc_socket_t. The new * socket has one outstanding reference. The task receiving the event * will be detached from just after the event is delivered. * * On entry to this function, the event delivered is the internal * readable event, and the first item on the accept_list should be * the done event we want to send. If the list is empty, this is a no-op, * so just unlock and return. */ static void internal_accept(isc_task_t *me, isc_event_t *ev) { isc__socket_t *sock; isc__socketmgr_t *manager; isc_socket_newconnev_t *dev; isc_task_t *task; ISC_SOCKADDR_LEN_T addrlen; int fd; isc_result_t result = ISC_R_SUCCESS; char strbuf[ISC_STRERRORSIZE]; const char *err = "accept"; UNUSED(me); sock = ev->ev_sender; INSIST(VALID_SOCKET(sock)); LOCK(&sock->lock); socket_log(sock, NULL, TRACE, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTLOCK, "internal_accept called, locked socket"); manager = sock->manager; INSIST(VALID_MANAGER(manager)); INSIST(sock->listener); INSIST(sock->pending_accept == 1); sock->pending_accept = 0; INSIST(sock->references > 0); sock->references--; /* the internal event is done with this socket */ if (sock->references == 0) { UNLOCK(&sock->lock); destroy(&sock); return; } /* * Get the first item off the accept list. * If it is empty, unlock the socket and return. */ dev = ISC_LIST_HEAD(sock->accept_list); if (dev == NULL) { UNLOCK(&sock->lock); return; } /* * Try to accept the new connection. If the accept fails with * EAGAIN or EINTR, simply poke the watcher to watch this socket * again. Also ignore ECONNRESET, which has been reported to * be spuriously returned on Linux 2.2.19 although it is not * a documented error for accept(). ECONNABORTED has been * reported for Solaris 8. The rest are thrown in not because * we have seen them but because they are ignored by other * daemons such as BIND 8 and Apache. */ addrlen = sizeof(NEWCONNSOCK(dev)->peer_address.type); memset(&NEWCONNSOCK(dev)->peer_address.type, 0, addrlen); fd = accept(sock->fd, &NEWCONNSOCK(dev)->peer_address.type.sa, (void *)&addrlen); #ifdef F_DUPFD /* * Leave a space for stdio to work in. */ if (fd >= 0 && fd < 20) { int new, tmp; new = fcntl(fd, F_DUPFD, 20); tmp = errno; (void)close(fd); errno = tmp; fd = new; err = "accept/fcntl"; } #endif if (fd < 0) { if (SOFT_ERROR(errno)) goto soft_error; switch (errno) { case ENFILE: case EMFILE: isc_log_iwrite(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_TOOMANYFDS, "%s: too many open file descriptors", err); goto soft_error; case ENOBUFS: case ENOMEM: case ECONNRESET: case ECONNABORTED: case EHOSTUNREACH: case EHOSTDOWN: case ENETUNREACH: case ENETDOWN: case ECONNREFUSED: #ifdef EPROTO case EPROTO: #endif #ifdef ENONET case ENONET: #endif goto soft_error; default: break; } isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "internal_accept: %s() %s: %s", err, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); fd = -1; result = ISC_R_UNEXPECTED; } else { if (addrlen == 0U) { UNEXPECTED_ERROR(__FILE__, __LINE__, "internal_accept(): " "accept() failed to return " "remote address"); (void)close(fd); goto soft_error; } else if (NEWCONNSOCK(dev)->peer_address.type.sa.sa_family != sock->pf) { UNEXPECTED_ERROR(__FILE__, __LINE__, "internal_accept(): " "accept() returned peer address " "family %u (expected %u)", NEWCONNSOCK(dev)->peer_address. type.sa.sa_family, sock->pf); (void)close(fd); goto soft_error; } else if (fd >= (int)manager->maxsocks) { isc_log_iwrite(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_TOOMANYFDS, "accept: " "file descriptor exceeds limit (%d/%u)", fd, manager->maxsocks); (void)close(fd); goto soft_error; } } if (fd != -1) { NEWCONNSOCK(dev)->peer_address.length = addrlen; NEWCONNSOCK(dev)->pf = sock->pf; } /* * Pull off the done event. */ ISC_LIST_UNLINK(sock->accept_list, dev, ev_link); /* * Poke watcher if there are more pending accepts. */ if (!ISC_LIST_EMPTY(sock->accept_list)) select_poke(sock->manager, sock->fd, SELECT_POKE_ACCEPT); UNLOCK(&sock->lock); if (fd != -1) { result = make_nonblock(fd); if (result != ISC_R_SUCCESS) { (void)close(fd); fd = -1; } } /* * -1 means the new socket didn't happen. */ if (fd != -1) { int lockid = FDLOCK_ID(fd); NEWCONNSOCK(dev)->fd = fd; NEWCONNSOCK(dev)->bound = 1; NEWCONNSOCK(dev)->connected = 1; /* * Use minimum mtu if possible. */ use_min_mtu(NEWCONNSOCK(dev)); /* * Ensure DSCP settings are inherited across accept. */ setdscp(NEWCONNSOCK(dev), sock->dscp); /* * Save away the remote address */ dev->address = NEWCONNSOCK(dev)->peer_address; LOCK(&manager->fdlock[lockid]); manager->fds[fd] = NEWCONNSOCK(dev); manager->fdstate[fd] = MANAGED; UNLOCK(&manager->fdlock[lockid]); LOCK(&manager->lock); #ifdef USE_SELECT if (manager->maxfd < fd) manager->maxfd = fd; #endif socket_log(sock, &NEWCONNSOCK(dev)->peer_address, CREATION, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTEDCXN, "accepted connection, new socket %p", dev->newsocket); ISC_LIST_APPEND(manager->socklist, NEWCONNSOCK(dev), link); UNLOCK(&manager->lock); inc_stats(manager->stats, sock->statsindex[STATID_ACCEPT]); inc_stats(manager->stats, sock->statsindex[STATID_ACTIVE]); } else { inc_stats(manager->stats, sock->statsindex[STATID_ACCEPTFAIL]); NEWCONNSOCK(dev)->references--; free_socket((isc__socket_t **)&dev->newsocket); } /* * Fill in the done event details and send it off. */ dev->result = result; task = dev->ev_sender; dev->ev_sender = sock; isc_task_sendanddetach(&task, ISC_EVENT_PTR(&dev)); return; soft_error: select_poke(sock->manager, sock->fd, SELECT_POKE_ACCEPT); UNLOCK(&sock->lock); inc_stats(manager->stats, sock->statsindex[STATID_ACCEPTFAIL]); return; } static void internal_recv(isc_task_t *me, isc_event_t *ev) { isc_socketevent_t *dev; isc__socket_t *sock; INSIST(ev->ev_type == ISC_SOCKEVENT_INTR); sock = ev->ev_sender; INSIST(VALID_SOCKET(sock)); LOCK(&sock->lock); socket_log(sock, NULL, IOEVENT, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_INTERNALRECV, "internal_recv: task %p got event %p", me, ev); INSIST(sock->pending_recv == 1); sock->pending_recv = 0; INSIST(sock->references > 0); sock->references--; /* the internal event is done with this socket */ if (sock->references == 0) { UNLOCK(&sock->lock); destroy(&sock); return; } /* * Try to do as much I/O as possible on this socket. There are no * limits here, currently. */ dev = ISC_LIST_HEAD(sock->recv_list); while (dev != NULL) { switch (doio_recv(sock, dev)) { case DOIO_SOFT: goto poke; case DOIO_EOF: /* * read of 0 means the remote end was closed. * Run through the event queue and dispatch all * the events with an EOF result code. */ do { dev->result = ISC_R_EOF; send_recvdone_event(sock, &dev); dev = ISC_LIST_HEAD(sock->recv_list); } while (dev != NULL); goto poke; case DOIO_SUCCESS: case DOIO_HARD: send_recvdone_event(sock, &dev); break; } dev = ISC_LIST_HEAD(sock->recv_list); } poke: if (!ISC_LIST_EMPTY(sock->recv_list)) select_poke(sock->manager, sock->fd, SELECT_POKE_READ); UNLOCK(&sock->lock); } static void internal_send(isc_task_t *me, isc_event_t *ev) { isc_socketevent_t *dev; isc__socket_t *sock; INSIST(ev->ev_type == ISC_SOCKEVENT_INTW); /* * Find out what socket this is and lock it. */ sock = (isc__socket_t *)ev->ev_sender; INSIST(VALID_SOCKET(sock)); LOCK(&sock->lock); socket_log(sock, NULL, IOEVENT, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_INTERNALSEND, "internal_send: task %p got event %p", me, ev); INSIST(sock->pending_send == 1); sock->pending_send = 0; INSIST(sock->references > 0); sock->references--; /* the internal event is done with this socket */ if (sock->references == 0) { UNLOCK(&sock->lock); destroy(&sock); return; } /* * Try to do as much I/O as possible on this socket. There are no * limits here, currently. */ dev = ISC_LIST_HEAD(sock->send_list); while (dev != NULL) { switch (doio_send(sock, dev)) { case DOIO_SOFT: goto poke; case DOIO_HARD: case DOIO_SUCCESS: send_senddone_event(sock, &dev); break; } dev = ISC_LIST_HEAD(sock->send_list); } poke: if (!ISC_LIST_EMPTY(sock->send_list)) select_poke(sock->manager, sock->fd, SELECT_POKE_WRITE); UNLOCK(&sock->lock); } static void internal_fdwatch_write(isc_task_t *me, isc_event_t *ev) { isc__socket_t *sock; int more_data; INSIST(ev->ev_type == ISC_SOCKEVENT_INTW); /* * Find out what socket this is and lock it. */ sock = (isc__socket_t *)ev->ev_sender; INSIST(VALID_SOCKET(sock)); LOCK(&sock->lock); socket_log(sock, NULL, IOEVENT, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_INTERNALSEND, "internal_fdwatch_write: task %p got event %p", me, ev); INSIST(sock->pending_send == 1); UNLOCK(&sock->lock); more_data = (sock->fdwatchcb)(me, (isc_socket_t *)sock, sock->fdwatcharg, ISC_SOCKFDWATCH_WRITE); LOCK(&sock->lock); sock->pending_send = 0; INSIST(sock->references > 0); sock->references--; /* the internal event is done with this socket */ if (sock->references == 0) { UNLOCK(&sock->lock); destroy(&sock); return; } if (more_data) select_poke(sock->manager, sock->fd, SELECT_POKE_WRITE); UNLOCK(&sock->lock); } static void internal_fdwatch_read(isc_task_t *me, isc_event_t *ev) { isc__socket_t *sock; int more_data; INSIST(ev->ev_type == ISC_SOCKEVENT_INTR); /* * Find out what socket this is and lock it. */ sock = (isc__socket_t *)ev->ev_sender; INSIST(VALID_SOCKET(sock)); LOCK(&sock->lock); socket_log(sock, NULL, IOEVENT, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_INTERNALRECV, "internal_fdwatch_read: task %p got event %p", me, ev); INSIST(sock->pending_recv == 1); UNLOCK(&sock->lock); more_data = (sock->fdwatchcb)(me, (isc_socket_t *)sock, sock->fdwatcharg, ISC_SOCKFDWATCH_READ); LOCK(&sock->lock); sock->pending_recv = 0; INSIST(sock->references > 0); sock->references--; /* the internal event is done with this socket */ if (sock->references == 0) { UNLOCK(&sock->lock); destroy(&sock); return; } if (more_data) select_poke(sock->manager, sock->fd, SELECT_POKE_READ); UNLOCK(&sock->lock); } /* * Process read/writes on each fd here. Avoid locking * and unlocking twice if both reads and writes are possible. */ static void process_fd(isc__socketmgr_t *manager, int fd, isc_boolean_t readable, isc_boolean_t writeable) { isc__socket_t *sock; isc_boolean_t unlock_sock; isc_boolean_t unwatch_read = ISC_FALSE, unwatch_write = ISC_FALSE; int lockid = FDLOCK_ID(fd); /* * If the socket is going to be closed, don't do more I/O. */ LOCK(&manager->fdlock[lockid]); if (manager->fdstate[fd] == CLOSE_PENDING) { UNLOCK(&manager->fdlock[lockid]); (void)unwatch_fd(manager, fd, SELECT_POKE_READ); (void)unwatch_fd(manager, fd, SELECT_POKE_WRITE); return; } sock = manager->fds[fd]; unlock_sock = ISC_FALSE; if (readable) { if (sock == NULL) { unwatch_read = ISC_TRUE; goto check_write; } unlock_sock = ISC_TRUE; LOCK(&sock->lock); if (!SOCK_DEAD(sock)) { if (sock->listener) dispatch_accept(sock); else dispatch_recv(sock); } unwatch_read = ISC_TRUE; } check_write: if (writeable) { if (sock == NULL) { unwatch_write = ISC_TRUE; goto unlock_fd; } if (!unlock_sock) { unlock_sock = ISC_TRUE; LOCK(&sock->lock); } if (!SOCK_DEAD(sock)) { if (sock->connecting) dispatch_connect(sock); else dispatch_send(sock); } unwatch_write = ISC_TRUE; } if (unlock_sock) UNLOCK(&sock->lock); unlock_fd: UNLOCK(&manager->fdlock[lockid]); if (unwatch_read) (void)unwatch_fd(manager, fd, SELECT_POKE_READ); if (unwatch_write) (void)unwatch_fd(manager, fd, SELECT_POKE_WRITE); } #ifdef USE_KQUEUE static isc_boolean_t process_fds(isc__socketmgr_t *manager, struct kevent *events, int nevents) { int i; isc_boolean_t readable, writable; isc_boolean_t done = ISC_FALSE; #ifdef USE_WATCHER_THREAD isc_boolean_t have_ctlevent = ISC_FALSE; #endif if (nevents == manager->nevents) { /* * This is not an error, but something unexpected. If this * happens, it may indicate the need for increasing * ISC_SOCKET_MAXEVENTS. */ manager_log(manager, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_INFO, "maximum number of FD events (%d) received", nevents); } for (i = 0; i < nevents; i++) { REQUIRE(events[i].ident < manager->maxsocks); #ifdef USE_WATCHER_THREAD if (events[i].ident == (uintptr_t)manager->pipe_fds[0]) { have_ctlevent = ISC_TRUE; continue; } #endif readable = ISC_TF(events[i].filter == EVFILT_READ); writable = ISC_TF(events[i].filter == EVFILT_WRITE); process_fd(manager, events[i].ident, readable, writable); } #ifdef USE_WATCHER_THREAD if (have_ctlevent) done = process_ctlfd(manager); #endif return (done); } #elif defined(USE_EPOLL) static isc_boolean_t process_fds(isc__socketmgr_t *manager, struct epoll_event *events, int nevents) { int i; isc_boolean_t done = ISC_FALSE; #ifdef USE_WATCHER_THREAD isc_boolean_t have_ctlevent = ISC_FALSE; #endif if (nevents == manager->nevents) { manager_log(manager, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_INFO, "maximum number of FD events (%d) received", nevents); } for (i = 0; i < nevents; i++) { REQUIRE(events[i].data.fd < (int)manager->maxsocks); #ifdef USE_WATCHER_THREAD if (events[i].data.fd == manager->pipe_fds[0]) { have_ctlevent = ISC_TRUE; continue; } #endif if ((events[i].events & EPOLLERR) != 0 || (events[i].events & EPOLLHUP) != 0) { /* * epoll does not set IN/OUT bits on an erroneous * condition, so we need to try both anyway. This is a * bit inefficient, but should be okay for such rare * events. Note also that the read or write attempt * won't block because we use non-blocking sockets. */ events[i].events |= (EPOLLIN | EPOLLOUT); } process_fd(manager, events[i].data.fd, (events[i].events & EPOLLIN) != 0, (events[i].events & EPOLLOUT) != 0); } #ifdef USE_WATCHER_THREAD if (have_ctlevent) done = process_ctlfd(manager); #endif return (done); } #elif defined(USE_DEVPOLL) static isc_boolean_t process_fds(isc__socketmgr_t *manager, struct pollfd *events, int nevents) { int i; isc_boolean_t done = ISC_FALSE; #ifdef USE_WATCHER_THREAD isc_boolean_t have_ctlevent = ISC_FALSE; #endif if (nevents == manager->nevents) { manager_log(manager, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_INFO, "maximum number of FD events (%d) received", nevents); } for (i = 0; i < nevents; i++) { REQUIRE(events[i].fd < (int)manager->maxsocks); #ifdef USE_WATCHER_THREAD if (events[i].fd == manager->pipe_fds[0]) { have_ctlevent = ISC_TRUE; continue; } #endif process_fd(manager, events[i].fd, (events[i].events & POLLIN) != 0, (events[i].events & POLLOUT) != 0); } #ifdef USE_WATCHER_THREAD if (have_ctlevent) done = process_ctlfd(manager); #endif return (done); } #elif defined(USE_SELECT) static void process_fds(isc__socketmgr_t *manager, int maxfd, fd_set *readfds, fd_set *writefds) { int i; REQUIRE(maxfd <= (int)manager->maxsocks); for (i = 0; i < maxfd; i++) { #ifdef USE_WATCHER_THREAD if (i == manager->pipe_fds[0] || i == manager->pipe_fds[1]) continue; #endif /* USE_WATCHER_THREAD */ process_fd(manager, i, FD_ISSET(i, readfds), FD_ISSET(i, writefds)); } } #endif #ifdef USE_WATCHER_THREAD static isc_boolean_t process_ctlfd(isc__socketmgr_t *manager) { int msg, fd; for (;;) { select_readmsg(manager, &fd, &msg); manager_log(manager, IOEVENT, isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_WATCHERMSG, "watcher got message %d " "for socket %d"), msg, fd); /* * Nothing to read? */ if (msg == SELECT_POKE_NOTHING) break; /* * Handle shutdown message. We really should * jump out of this loop right away, but * it doesn't matter if we have to do a little * more work first. */ if (msg == SELECT_POKE_SHUTDOWN) return (ISC_TRUE); /* * This is a wakeup on a socket. Look * at the event queue for both read and write, * and decide if we need to watch on it now * or not. */ wakeup_socket(manager, fd, msg); } return (ISC_FALSE); } /* * This is the thread that will loop forever, always in a select or poll * call. * * When select returns something to do, track down what thread gets to do * this I/O and post the event to it. */ static isc_threadresult_t watcher(void *uap) { isc__socketmgr_t *manager = uap; isc_boolean_t done; int cc; #ifdef USE_KQUEUE const char *fnname = "kevent()"; #elif defined (USE_EPOLL) const char *fnname = "epoll_wait()"; #elif defined(USE_DEVPOLL) isc_result_t result; const char *fnname = "ioctl(DP_POLL)"; struct dvpoll dvp; int pass; #elif defined (USE_SELECT) const char *fnname = "select()"; int maxfd; int ctlfd; #endif char strbuf[ISC_STRERRORSIZE]; #ifdef ISC_SOCKET_USE_POLLWATCH pollstate_t pollstate = poll_idle; #endif #if defined (USE_SELECT) /* * Get the control fd here. This will never change. */ ctlfd = manager->pipe_fds[0]; #endif done = ISC_FALSE; while (!done) { do { #ifdef USE_KQUEUE cc = kevent(manager->kqueue_fd, NULL, 0, manager->events, manager->nevents, NULL); #elif defined(USE_EPOLL) cc = epoll_wait(manager->epoll_fd, manager->events, manager->nevents, -1); #elif defined(USE_DEVPOLL) /* * Re-probe every thousand calls. */ if (manager->calls++ > 1000U) { result = isc_resource_getcurlimit( isc_resource_openfiles, &manager->open_max); if (result != ISC_R_SUCCESS) manager->open_max = 64; manager->calls = 0; } for (pass = 0; pass < 2; pass++) { dvp.dp_fds = manager->events; dvp.dp_nfds = manager->nevents; if (dvp.dp_nfds >= manager->open_max) dvp.dp_nfds = manager->open_max - 1; #ifndef ISC_SOCKET_USE_POLLWATCH dvp.dp_timeout = -1; #else if (pollstate == poll_idle) dvp.dp_timeout = -1; else dvp.dp_timeout = ISC_SOCKET_POLLWATCH_TIMEOUT; #endif /* ISC_SOCKET_USE_POLLWATCH */ cc = ioctl(manager->devpoll_fd, DP_POLL, &dvp); if (cc == -1 && errno == EINVAL) { /* * {OPEN_MAX} may have dropped. Look * up the current value and try again. */ result = isc_resource_getcurlimit( isc_resource_openfiles, &manager->open_max); if (result != ISC_R_SUCCESS) manager->open_max = 64; } else break; } #elif defined(USE_SELECT) LOCK(&manager->lock); memmove(manager->read_fds_copy, manager->read_fds, manager->fd_bufsize); memmove(manager->write_fds_copy, manager->write_fds, manager->fd_bufsize); maxfd = manager->maxfd + 1; UNLOCK(&manager->lock); cc = select(maxfd, manager->read_fds_copy, manager->write_fds_copy, NULL, NULL); #endif /* USE_KQUEUE */ if (cc < 0 && !SOFT_ERROR(errno)) { isc__strerror(errno, strbuf, sizeof(strbuf)); FATAL_ERROR(__FILE__, __LINE__, "%s %s: %s", fnname, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); } #if defined(USE_DEVPOLL) && defined(ISC_SOCKET_USE_POLLWATCH) if (cc == 0) { if (pollstate == poll_active) pollstate = poll_checking; else if (pollstate == poll_checking) pollstate = poll_idle; } else if (cc > 0) { if (pollstate == poll_checking) { /* * XXX: We'd like to use a more * verbose log level as it's actually an * unexpected event, but the kernel bug * reportedly happens pretty frequently * (and it can also be a false positive) * so it would be just too noisy. */ manager_log(manager, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(1), "unexpected POLL timeout"); } pollstate = poll_active; } #endif } while (cc < 0); #if defined(USE_KQUEUE) || defined (USE_EPOLL) || defined (USE_DEVPOLL) done = process_fds(manager, manager->events, cc); #elif defined(USE_SELECT) process_fds(manager, maxfd, manager->read_fds_copy, manager->write_fds_copy); /* * Process reads on internal, control fd. */ if (FD_ISSET(ctlfd, manager->read_fds_copy)) done = process_ctlfd(manager); #endif } manager_log(manager, TRACE, "%s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_EXITING, "watcher exiting")); return ((isc_threadresult_t)0); } #endif /* USE_WATCHER_THREAD */ void isc__socketmgr_setreserved(isc_socketmgr_t *manager0, isc_uint32_t reserved) { isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0; REQUIRE(VALID_MANAGER(manager)); manager->reserved = reserved; } void isc__socketmgr_maxudp(isc_socketmgr_t *manager0, int maxudp) { isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0; REQUIRE(VALID_MANAGER(manager)); manager->maxudp = maxudp; } /* * Create a new socket manager. */ static isc_result_t setup_watcher(isc_mem_t *mctx, isc__socketmgr_t *manager) { isc_result_t result; #if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL) char strbuf[ISC_STRERRORSIZE]; #endif #ifdef USE_KQUEUE manager->nevents = ISC_SOCKET_MAXEVENTS; manager->events = isc_mem_get(mctx, sizeof(struct kevent) * manager->nevents); if (manager->events == NULL) return (ISC_R_NOMEMORY); manager->kqueue_fd = kqueue(); if (manager->kqueue_fd == -1) { result = isc__errno2result(errno); isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "kqueue %s: %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); isc_mem_put(mctx, manager->events, sizeof(struct kevent) * manager->nevents); return (result); } #ifdef USE_WATCHER_THREAD result = watch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ); if (result != ISC_R_SUCCESS) { close(manager->kqueue_fd); isc_mem_put(mctx, manager->events, sizeof(struct kevent) * manager->nevents); return (result); } #endif /* USE_WATCHER_THREAD */ #elif defined(USE_EPOLL) manager->nevents = ISC_SOCKET_MAXEVENTS; manager->events = isc_mem_get(mctx, sizeof(struct epoll_event) * manager->nevents); if (manager->events == NULL) return (ISC_R_NOMEMORY); manager->epoll_fd = epoll_create(manager->nevents); if (manager->epoll_fd == -1) { result = isc__errno2result(errno); isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "epoll_create %s: %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); isc_mem_put(mctx, manager->events, sizeof(struct epoll_event) * manager->nevents); return (result); } #ifdef USE_WATCHER_THREAD result = watch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ); if (result != ISC_R_SUCCESS) { close(manager->epoll_fd); isc_mem_put(mctx, manager->events, sizeof(struct epoll_event) * manager->nevents); return (result); } #endif /* USE_WATCHER_THREAD */ #elif defined(USE_DEVPOLL) manager->nevents = ISC_SOCKET_MAXEVENTS; result = isc_resource_getcurlimit(isc_resource_openfiles, &manager->open_max); if (result != ISC_R_SUCCESS) manager->open_max = 64; manager->calls = 0; manager->events = isc_mem_get(mctx, sizeof(struct pollfd) * manager->nevents); if (manager->events == NULL) return (ISC_R_NOMEMORY); /* * Note: fdpollinfo should be able to support all possible FDs, so * it must have maxsocks entries (not nevents). */ manager->fdpollinfo = isc_mem_get(mctx, sizeof(pollinfo_t) * manager->maxsocks); if (manager->fdpollinfo == NULL) { isc_mem_put(mctx, manager->events, sizeof(struct pollfd) * manager->nevents); return (ISC_R_NOMEMORY); } memset(manager->fdpollinfo, 0, sizeof(pollinfo_t) * manager->maxsocks); manager->devpoll_fd = open("/dev/poll", O_RDWR); if (manager->devpoll_fd == -1) { result = isc__errno2result(errno); isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "open(/dev/poll) %s: %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); isc_mem_put(mctx, manager->events, sizeof(struct pollfd) * manager->nevents); isc_mem_put(mctx, manager->fdpollinfo, sizeof(pollinfo_t) * manager->maxsocks); return (result); } #ifdef USE_WATCHER_THREAD result = watch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ); if (result != ISC_R_SUCCESS) { close(manager->devpoll_fd); isc_mem_put(mctx, manager->events, sizeof(struct pollfd) * manager->nevents); isc_mem_put(mctx, manager->fdpollinfo, sizeof(pollinfo_t) * manager->maxsocks); return (result); } #endif /* USE_WATCHER_THREAD */ #elif defined(USE_SELECT) UNUSED(result); #if ISC_SOCKET_MAXSOCKETS > FD_SETSIZE /* * Note: this code should also cover the case of MAXSOCKETS <= * FD_SETSIZE, but we separate the cases to avoid possible portability * issues regarding howmany() and the actual representation of fd_set. */ manager->fd_bufsize = howmany(manager->maxsocks, NFDBITS) * sizeof(fd_mask); #else manager->fd_bufsize = sizeof(fd_set); #endif manager->read_fds = NULL; manager->read_fds_copy = NULL; manager->write_fds = NULL; manager->write_fds_copy = NULL; manager->read_fds = isc_mem_get(mctx, manager->fd_bufsize); if (manager->read_fds != NULL) manager->read_fds_copy = isc_mem_get(mctx, manager->fd_bufsize); if (manager->read_fds_copy != NULL) manager->write_fds = isc_mem_get(mctx, manager->fd_bufsize); if (manager->write_fds != NULL) { manager->write_fds_copy = isc_mem_get(mctx, manager->fd_bufsize); } if (manager->write_fds_copy == NULL) { if (manager->write_fds != NULL) { isc_mem_put(mctx, manager->write_fds, manager->fd_bufsize); } if (manager->read_fds_copy != NULL) { isc_mem_put(mctx, manager->read_fds_copy, manager->fd_bufsize); } if (manager->read_fds != NULL) { isc_mem_put(mctx, manager->read_fds, manager->fd_bufsize); } return (ISC_R_NOMEMORY); } memset(manager->read_fds, 0, manager->fd_bufsize); memset(manager->write_fds, 0, manager->fd_bufsize); #ifdef USE_WATCHER_THREAD (void)watch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ); manager->maxfd = manager->pipe_fds[0]; #else /* USE_WATCHER_THREAD */ manager->maxfd = 0; #endif /* USE_WATCHER_THREAD */ #endif /* USE_KQUEUE */ return (ISC_R_SUCCESS); } static void cleanup_watcher(isc_mem_t *mctx, isc__socketmgr_t *manager) { #ifdef USE_WATCHER_THREAD isc_result_t result; result = unwatch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "epoll_ctl(DEL) %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); } #endif /* USE_WATCHER_THREAD */ #ifdef USE_KQUEUE close(manager->kqueue_fd); isc_mem_put(mctx, manager->events, sizeof(struct kevent) * manager->nevents); #elif defined(USE_EPOLL) close(manager->epoll_fd); isc_mem_put(mctx, manager->events, sizeof(struct epoll_event) * manager->nevents); #elif defined(USE_DEVPOLL) close(manager->devpoll_fd); isc_mem_put(mctx, manager->events, sizeof(struct pollfd) * manager->nevents); isc_mem_put(mctx, manager->fdpollinfo, sizeof(pollinfo_t) * manager->maxsocks); #elif defined(USE_SELECT) if (manager->read_fds != NULL) isc_mem_put(mctx, manager->read_fds, manager->fd_bufsize); if (manager->read_fds_copy != NULL) isc_mem_put(mctx, manager->read_fds_copy, manager->fd_bufsize); if (manager->write_fds != NULL) isc_mem_put(mctx, manager->write_fds, manager->fd_bufsize); if (manager->write_fds_copy != NULL) isc_mem_put(mctx, manager->write_fds_copy, manager->fd_bufsize); #endif /* USE_KQUEUE */ } isc_result_t isc__socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) { return (isc__socketmgr_create2(mctx, managerp, 0)); } isc_result_t isc__socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp, unsigned int maxsocks) { int i; isc__socketmgr_t *manager; #ifdef USE_WATCHER_THREAD char strbuf[ISC_STRERRORSIZE]; #endif isc_result_t result; REQUIRE(managerp != NULL && *managerp == NULL); #ifdef USE_SHARED_MANAGER if (socketmgr != NULL) { /* Don't allow maxsocks to be updated */ if (maxsocks > 0 && socketmgr->maxsocks != maxsocks) return (ISC_R_EXISTS); socketmgr->refs++; *managerp = (isc_socketmgr_t *)socketmgr; return (ISC_R_SUCCESS); } #endif /* USE_SHARED_MANAGER */ if (maxsocks == 0) maxsocks = ISC_SOCKET_MAXSOCKETS; manager = isc_mem_get(mctx, sizeof(*manager)); if (manager == NULL) return (ISC_R_NOMEMORY); /* zero-clear so that necessary cleanup on failure will be easy */ memset(manager, 0, sizeof(*manager)); manager->maxsocks = maxsocks; manager->reserved = 0; manager->maxudp = 0; manager->fds = isc_mem_get(mctx, manager->maxsocks * sizeof(isc__socket_t *)); if (manager->fds == NULL) { result = ISC_R_NOMEMORY; goto free_manager; } manager->fdstate = isc_mem_get(mctx, manager->maxsocks * sizeof(int)); if (manager->fdstate == NULL) { result = ISC_R_NOMEMORY; goto free_manager; } manager->stats = NULL; manager->common.methods = &socketmgrmethods; manager->common.magic = ISCAPI_SOCKETMGR_MAGIC; manager->common.impmagic = SOCKET_MANAGER_MAGIC; manager->mctx = NULL; memset(manager->fds, 0, manager->maxsocks * sizeof(isc_socket_t *)); ISC_LIST_INIT(manager->socklist); result = isc_mutex_init(&manager->lock); if (result != ISC_R_SUCCESS) goto free_manager; manager->fdlock = isc_mem_get(mctx, FDLOCK_COUNT * sizeof(isc_mutex_t)); if (manager->fdlock == NULL) { result = ISC_R_NOMEMORY; goto cleanup_lock; } for (i = 0; i < FDLOCK_COUNT; i++) { result = isc_mutex_init(&manager->fdlock[i]); if (result != ISC_R_SUCCESS) { while (--i >= 0) DESTROYLOCK(&manager->fdlock[i]); isc_mem_put(mctx, manager->fdlock, FDLOCK_COUNT * sizeof(isc_mutex_t)); manager->fdlock = NULL; goto cleanup_lock; } } #ifdef USE_WATCHER_THREAD if (isc_condition_init(&manager->shutdown_ok) != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_condition_init() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); result = ISC_R_UNEXPECTED; goto cleanup_lock; } /* * Create the special fds that will be used to wake up the * select/poll loop when something internal needs to be done. */ if (pipe(manager->pipe_fds) != 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "pipe() %s: %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); result = ISC_R_UNEXPECTED; goto cleanup_condition; } RUNTIME_CHECK(make_nonblock(manager->pipe_fds[0]) == ISC_R_SUCCESS); #if 0 RUNTIME_CHECK(make_nonblock(manager->pipe_fds[1]) == ISC_R_SUCCESS); #endif #endif /* USE_WATCHER_THREAD */ #ifdef USE_SHARED_MANAGER manager->refs = 1; #endif /* USE_SHARED_MANAGER */ /* * Set up initial state for the select loop */ result = setup_watcher(mctx, manager); if (result != ISC_R_SUCCESS) goto cleanup; memset(manager->fdstate, 0, manager->maxsocks * sizeof(int)); #ifdef USE_WATCHER_THREAD /* * Start up the select/poll thread. */ if (isc_thread_create(watcher, manager, &manager->watcher) != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_thread_create() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); cleanup_watcher(mctx, manager); result = ISC_R_UNEXPECTED; goto cleanup; } #endif /* USE_WATCHER_THREAD */ isc_mem_attach(mctx, &manager->mctx); #ifdef USE_SHARED_MANAGER socketmgr = manager; #endif /* USE_SHARED_MANAGER */ *managerp = (isc_socketmgr_t *)manager; return (ISC_R_SUCCESS); cleanup: #ifdef USE_WATCHER_THREAD (void)close(manager->pipe_fds[0]); (void)close(manager->pipe_fds[1]); #endif /* USE_WATCHER_THREAD */ #ifdef USE_WATCHER_THREAD cleanup_condition: (void)isc_condition_destroy(&manager->shutdown_ok); #endif /* USE_WATCHER_THREAD */ cleanup_lock: if (manager->fdlock != NULL) { for (i = 0; i < FDLOCK_COUNT; i++) DESTROYLOCK(&manager->fdlock[i]); } DESTROYLOCK(&manager->lock); free_manager: if (manager->fdlock != NULL) { isc_mem_put(mctx, manager->fdlock, FDLOCK_COUNT * sizeof(isc_mutex_t)); } if (manager->fdstate != NULL) { isc_mem_put(mctx, manager->fdstate, manager->maxsocks * sizeof(int)); } if (manager->fds != NULL) { isc_mem_put(mctx, manager->fds, manager->maxsocks * sizeof(isc_socket_t *)); } isc_mem_put(mctx, manager, sizeof(*manager)); return (result); } isc_result_t isc_socketmgr_getmaxsockets(isc_socketmgr_t *manager0, unsigned int *nsockp) { isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0; REQUIRE(VALID_MANAGER(manager)); REQUIRE(nsockp != NULL); *nsockp = manager->maxsocks; return (ISC_R_SUCCESS); } void isc_socketmgr_setstats(isc_socketmgr_t *manager0, isc_stats_t *stats) { isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0; REQUIRE(VALID_MANAGER(manager)); REQUIRE(ISC_LIST_EMPTY(manager->socklist)); REQUIRE(manager->stats == NULL); REQUIRE(isc_stats_ncounters(stats) == isc_sockstatscounter_max); isc_stats_attach(stats, &manager->stats); } void isc__socketmgr_destroy(isc_socketmgr_t **managerp) { isc__socketmgr_t *manager; int i; isc_mem_t *mctx; /* * Destroy a socket manager. */ REQUIRE(managerp != NULL); manager = (isc__socketmgr_t *)*managerp; REQUIRE(VALID_MANAGER(manager)); #ifdef USE_SHARED_MANAGER manager->refs--; if (manager->refs > 0) { *managerp = NULL; return; } socketmgr = NULL; #endif /* USE_SHARED_MANAGER */ LOCK(&manager->lock); /* * Wait for all sockets to be destroyed. */ while (!ISC_LIST_EMPTY(manager->socklist)) { #ifdef USE_WATCHER_THREAD manager_log(manager, CREATION, "%s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_SOCKETSREMAIN, "sockets exist")); WAIT(&manager->shutdown_ok, &manager->lock); #else /* USE_WATCHER_THREAD */ UNLOCK(&manager->lock); isc__taskmgr_dispatch(NULL); LOCK(&manager->lock); #endif /* USE_WATCHER_THREAD */ } UNLOCK(&manager->lock); /* * Here, poke our select/poll thread. Do this by closing the write * half of the pipe, which will send EOF to the read half. * This is currently a no-op in the non-threaded case. */ select_poke(manager, 0, SELECT_POKE_SHUTDOWN); #ifdef USE_WATCHER_THREAD /* * Wait for thread to exit. */ if (isc_thread_join(manager->watcher, NULL) != ISC_R_SUCCESS) UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_thread_join() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); #endif /* USE_WATCHER_THREAD */ /* * Clean up. */ cleanup_watcher(manager->mctx, manager); #ifdef USE_WATCHER_THREAD (void)close(manager->pipe_fds[0]); (void)close(manager->pipe_fds[1]); (void)isc_condition_destroy(&manager->shutdown_ok); #endif /* USE_WATCHER_THREAD */ for (i = 0; i < (int)manager->maxsocks; i++) if (manager->fdstate[i] == CLOSE_PENDING) /* no need to lock */ (void)close(i); isc_mem_put(manager->mctx, manager->fds, manager->maxsocks * sizeof(isc__socket_t *)); isc_mem_put(manager->mctx, manager->fdstate, manager->maxsocks * sizeof(int)); if (manager->stats != NULL) isc_stats_detach(&manager->stats); if (manager->fdlock != NULL) { for (i = 0; i < FDLOCK_COUNT; i++) DESTROYLOCK(&manager->fdlock[i]); isc_mem_put(manager->mctx, manager->fdlock, FDLOCK_COUNT * sizeof(isc_mutex_t)); } DESTROYLOCK(&manager->lock); manager->common.magic = 0; manager->common.impmagic = 0; mctx= manager->mctx; isc_mem_put(mctx, manager, sizeof(*manager)); isc_mem_detach(&mctx); *managerp = NULL; #ifdef USE_SHARED_MANAGER socketmgr = NULL; #endif } static isc_result_t socket_recv(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, unsigned int flags) { int io_state; isc_boolean_t have_lock = ISC_FALSE; isc_task_t *ntask = NULL; isc_result_t result = ISC_R_SUCCESS; dev->ev_sender = task; if (sock->type == isc_sockettype_udp) { io_state = doio_recv(sock, dev); } else { LOCK(&sock->lock); have_lock = ISC_TRUE; if (ISC_LIST_EMPTY(sock->recv_list)) io_state = doio_recv(sock, dev); else io_state = DOIO_SOFT; } switch (io_state) { case DOIO_SOFT: /* * We couldn't read all or part of the request right now, so * queue it. * * Attach to socket and to task */ isc_task_attach(task, &ntask); dev->attributes |= ISC_SOCKEVENTATTR_ATTACHED; if (!have_lock) { LOCK(&sock->lock); have_lock = ISC_TRUE; } /* * Enqueue the request. If the socket was previously not being * watched, poke the watcher to start paying attention to it. */ if (ISC_LIST_EMPTY(sock->recv_list) && !sock->pending_recv) select_poke(sock->manager, sock->fd, SELECT_POKE_READ); ISC_LIST_ENQUEUE(sock->recv_list, dev, ev_link); socket_log(sock, NULL, EVENT, NULL, 0, 0, "socket_recv: event %p -> task %p", dev, ntask); if ((flags & ISC_SOCKFLAG_IMMEDIATE) != 0) result = ISC_R_INPROGRESS; break; case DOIO_EOF: dev->result = ISC_R_EOF; /* fallthrough */ case DOIO_HARD: case DOIO_SUCCESS: if ((flags & ISC_SOCKFLAG_IMMEDIATE) == 0) send_recvdone_event(sock, &dev); break; } if (have_lock) UNLOCK(&sock->lock); return (result); } isc_result_t isc__socket_recvv(isc_socket_t *sock0, isc_bufferlist_t *buflist, unsigned int minimum, isc_task_t *task, isc_taskaction_t action, void *arg) { isc__socket_t *sock = (isc__socket_t *)sock0; isc_socketevent_t *dev; isc__socketmgr_t *manager; unsigned int iocount; isc_buffer_t *buffer; REQUIRE(VALID_SOCKET(sock)); REQUIRE(buflist != NULL); REQUIRE(!ISC_LIST_EMPTY(*buflist)); REQUIRE(task != NULL); REQUIRE(action != NULL); manager = sock->manager; REQUIRE(VALID_MANAGER(manager)); iocount = isc_bufferlist_availablecount(buflist); REQUIRE(iocount > 0); INSIST(sock->bound); dev = allocate_socketevent(manager->mctx, sock, ISC_SOCKEVENT_RECVDONE, action, arg); if (dev == NULL) return (ISC_R_NOMEMORY); /* * UDP sockets are always partial read */ if (sock->type == isc_sockettype_udp) dev->minimum = 1; else { if (minimum == 0) dev->minimum = iocount; else dev->minimum = minimum; } /* * Move each buffer from the passed in list to our internal one. */ buffer = ISC_LIST_HEAD(*buflist); while (buffer != NULL) { ISC_LIST_DEQUEUE(*buflist, buffer, link); ISC_LIST_ENQUEUE(dev->bufferlist, buffer, link); buffer = ISC_LIST_HEAD(*buflist); } return (socket_recv(sock, dev, task, 0)); } isc_result_t isc__socket_recv(isc_socket_t *sock0, isc_region_t *region, unsigned int minimum, isc_task_t *task, isc_taskaction_t action, void *arg) { isc__socket_t *sock = (isc__socket_t *)sock0; isc_socketevent_t *dev; isc__socketmgr_t *manager; REQUIRE(VALID_SOCKET(sock)); REQUIRE(action != NULL); manager = sock->manager; REQUIRE(VALID_MANAGER(manager)); INSIST(sock->bound); dev = allocate_socketevent(manager->mctx, sock, ISC_SOCKEVENT_RECVDONE, action, arg); if (dev == NULL) return (ISC_R_NOMEMORY); return (isc__socket_recv2(sock0, region, minimum, task, dev, 0)); } isc_result_t isc__socket_recv2(isc_socket_t *sock0, isc_region_t *region, unsigned int minimum, isc_task_t *task, isc_socketevent_t *event, unsigned int flags) { isc__socket_t *sock = (isc__socket_t *)sock0; event->ev_sender = sock; event->result = ISC_R_UNSET; ISC_LIST_INIT(event->bufferlist); event->region = *region; event->n = 0; event->offset = 0; event->attributes = 0; /* * UDP sockets are always partial read. */ if (sock->type == isc_sockettype_udp) event->minimum = 1; else { if (minimum == 0) event->minimum = region->length; else event->minimum = minimum; } return (socket_recv(sock, event, task, flags)); } static isc_result_t socket_send(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, unsigned int flags) { int io_state; isc_boolean_t have_lock = ISC_FALSE; isc_task_t *ntask = NULL; isc_result_t result = ISC_R_SUCCESS; dev->ev_sender = task; set_dev_address(address, sock, dev); if (pktinfo != NULL) { dev->attributes |= ISC_SOCKEVENTATTR_PKTINFO; dev->pktinfo = *pktinfo; if (!isc_sockaddr_issitelocal(&dev->address) && !isc_sockaddr_islinklocal(&dev->address)) { socket_log(sock, NULL, TRACE, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_PKTINFOPROVIDED, "pktinfo structure provided, ifindex %u " "(set to 0)", pktinfo->ipi6_ifindex); /* * Set the pktinfo index to 0 here, to let the * kernel decide what interface it should send on. */ dev->pktinfo.ipi6_ifindex = 0; } } if (sock->type == isc_sockettype_udp) io_state = doio_send(sock, dev); else { LOCK(&sock->lock); have_lock = ISC_TRUE; if (ISC_LIST_EMPTY(sock->send_list)) io_state = doio_send(sock, dev); else io_state = DOIO_SOFT; } switch (io_state) { case DOIO_SOFT: /* * We couldn't send all or part of the request right now, so * queue it unless ISC_SOCKFLAG_NORETRY is set. */ if ((flags & ISC_SOCKFLAG_NORETRY) == 0) { isc_task_attach(task, &ntask); dev->attributes |= ISC_SOCKEVENTATTR_ATTACHED; if (!have_lock) { LOCK(&sock->lock); have_lock = ISC_TRUE; } /* * Enqueue the request. If the socket was previously * not being watched, poke the watcher to start * paying attention to it. */ if (ISC_LIST_EMPTY(sock->send_list) && !sock->pending_send) select_poke(sock->manager, sock->fd, SELECT_POKE_WRITE); ISC_LIST_ENQUEUE(sock->send_list, dev, ev_link); socket_log(sock, NULL, EVENT, NULL, 0, 0, "socket_send: event %p -> task %p", dev, ntask); if ((flags & ISC_SOCKFLAG_IMMEDIATE) != 0) result = ISC_R_INPROGRESS; break; } case DOIO_HARD: case DOIO_SUCCESS: if ((flags & ISC_SOCKFLAG_IMMEDIATE) == 0) send_senddone_event(sock, &dev); break; } if (have_lock) UNLOCK(&sock->lock); return (result); } isc_result_t isc__socket_send(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, isc_taskaction_t action, void *arg) { /* * REQUIRE() checking is performed in isc_socket_sendto(). */ return (isc__socket_sendto(sock, region, task, action, arg, NULL, NULL)); } isc_result_t isc__socket_sendto(isc_socket_t *sock0, isc_region_t *region, isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo) { isc__socket_t *sock = (isc__socket_t *)sock0; isc_socketevent_t *dev; isc__socketmgr_t *manager; REQUIRE(VALID_SOCKET(sock)); REQUIRE(region != NULL); REQUIRE(task != NULL); REQUIRE(action != NULL); manager = sock->manager; REQUIRE(VALID_MANAGER(manager)); INSIST(sock->bound); dev = allocate_socketevent(manager->mctx, sock, ISC_SOCKEVENT_SENDDONE, action, arg); if (dev == NULL) return (ISC_R_NOMEMORY); dev->region = *region; return (socket_send(sock, dev, task, address, pktinfo, 0)); } isc_result_t isc__socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist, isc_task_t *task, isc_taskaction_t action, void *arg) { return (isc__socket_sendtov2(sock, buflist, task, action, arg, NULL, NULL, 0)); } isc_result_t isc__socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist, isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo) { return (isc__socket_sendtov2(sock, buflist, task, action, arg, address, pktinfo, 0)); } isc_result_t isc__socket_sendtov2(isc_socket_t *sock0, isc_bufferlist_t *buflist, isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, unsigned int flags) { isc__socket_t *sock = (isc__socket_t *)sock0; isc_socketevent_t *dev; isc__socketmgr_t *manager; unsigned int iocount; isc_buffer_t *buffer; REQUIRE(VALID_SOCKET(sock)); REQUIRE(buflist != NULL); REQUIRE(!ISC_LIST_EMPTY(*buflist)); REQUIRE(task != NULL); REQUIRE(action != NULL); manager = sock->manager; REQUIRE(VALID_MANAGER(manager)); iocount = isc_bufferlist_usedcount(buflist); REQUIRE(iocount > 0); dev = allocate_socketevent(manager->mctx, sock, ISC_SOCKEVENT_SENDDONE, action, arg); if (dev == NULL) return (ISC_R_NOMEMORY); /* * Move each buffer from the passed in list to our internal one. */ buffer = ISC_LIST_HEAD(*buflist); while (buffer != NULL) { ISC_LIST_DEQUEUE(*buflist, buffer, link); ISC_LIST_ENQUEUE(dev->bufferlist, buffer, link); buffer = ISC_LIST_HEAD(*buflist); } return (socket_send(sock, dev, task, address, pktinfo, flags)); } isc_result_t isc__socket_sendto2(isc_socket_t *sock0, isc_region_t *region, isc_task_t *task, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, isc_socketevent_t *event, unsigned int flags) { isc__socket_t *sock = (isc__socket_t *)sock0; REQUIRE(VALID_SOCKET(sock)); REQUIRE((flags & ~(ISC_SOCKFLAG_IMMEDIATE|ISC_SOCKFLAG_NORETRY)) == 0); if ((flags & ISC_SOCKFLAG_NORETRY) != 0) REQUIRE(sock->type == isc_sockettype_udp); event->ev_sender = sock; event->result = ISC_R_UNSET; ISC_LIST_INIT(event->bufferlist); event->region = *region; event->n = 0; event->offset = 0; event->attributes &= ~ISC_SOCKEVENTATTR_ATTACHED; return (socket_send(sock, event, task, address, pktinfo, flags)); } void isc__socket_cleanunix(isc_sockaddr_t *sockaddr, isc_boolean_t active) { #ifdef ISC_PLATFORM_HAVESYSUNH int s; struct stat sb; char strbuf[ISC_STRERRORSIZE]; if (sockaddr->type.sa.sa_family != AF_UNIX) return; #ifndef S_ISSOCK #if defined(S_IFMT) && defined(S_IFSOCK) #define S_ISSOCK(mode) ((mode & S_IFMT)==S_IFSOCK) #elif defined(_S_IFMT) && defined(S_IFSOCK) #define S_ISSOCK(mode) ((mode & _S_IFMT)==S_IFSOCK) #endif #endif #ifndef S_ISFIFO #if defined(S_IFMT) && defined(S_IFIFO) #define S_ISFIFO(mode) ((mode & S_IFMT)==S_IFIFO) #elif defined(_S_IFMT) && defined(S_IFIFO) #define S_ISFIFO(mode) ((mode & _S_IFMT)==S_IFIFO) #endif #endif #if !defined(S_ISFIFO) && !defined(S_ISSOCK) #error You need to define S_ISFIFO and S_ISSOCK as appropriate for your platform. See . #endif #ifndef S_ISFIFO #define S_ISFIFO(mode) 0 #endif #ifndef S_ISSOCK #define S_ISSOCK(mode) 0 #endif if (active) { if (stat(sockaddr->type.sunix.sun_path, &sb) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, "isc_socket_cleanunix: stat(%s): %s", sockaddr->type.sunix.sun_path, strbuf); return; } if (!(S_ISSOCK(sb.st_mode) || S_ISFIFO(sb.st_mode))) { isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, "isc_socket_cleanunix: %s: not a socket", sockaddr->type.sunix.sun_path); return; } if (unlink(sockaddr->type.sunix.sun_path) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, "isc_socket_cleanunix: unlink(%s): %s", sockaddr->type.sunix.sun_path, strbuf); } return; } s = socket(AF_UNIX, SOCK_STREAM, 0); if (s < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_WARNING, "isc_socket_cleanunix: socket(%s): %s", sockaddr->type.sunix.sun_path, strbuf); return; } if (stat(sockaddr->type.sunix.sun_path, &sb) < 0) { switch (errno) { case ENOENT: /* We exited cleanly last time */ break; default: isc__strerror(errno, strbuf, sizeof(strbuf)); isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_WARNING, "isc_socket_cleanunix: stat(%s): %s", sockaddr->type.sunix.sun_path, strbuf); break; } goto cleanup; } if (!(S_ISSOCK(sb.st_mode) || S_ISFIFO(sb.st_mode))) { isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_WARNING, "isc_socket_cleanunix: %s: not a socket", sockaddr->type.sunix.sun_path); goto cleanup; } if (connect(s, (struct sockaddr *)&sockaddr->type.sunix, sizeof(sockaddr->type.sunix)) < 0) { switch (errno) { case ECONNREFUSED: case ECONNRESET: if (unlink(sockaddr->type.sunix.sun_path) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_WARNING, "isc_socket_cleanunix: " "unlink(%s): %s", sockaddr->type.sunix.sun_path, strbuf); } break; default: isc__strerror(errno, strbuf, sizeof(strbuf)); isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_WARNING, "isc_socket_cleanunix: connect(%s): %s", sockaddr->type.sunix.sun_path, strbuf); break; } } cleanup: close(s); #else UNUSED(sockaddr); UNUSED(active); #endif } isc_result_t isc__socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm, isc_uint32_t owner, isc_uint32_t group) { #ifdef ISC_PLATFORM_HAVESYSUNH isc_result_t result = ISC_R_SUCCESS; char strbuf[ISC_STRERRORSIZE]; char path[sizeof(sockaddr->type.sunix.sun_path)]; #ifdef NEED_SECURE_DIRECTORY char *slash; #endif REQUIRE(sockaddr->type.sa.sa_family == AF_UNIX); INSIST(strlen(sockaddr->type.sunix.sun_path) < sizeof(path)); strcpy(path, sockaddr->type.sunix.sun_path); #ifdef NEED_SECURE_DIRECTORY slash = strrchr(path, '/'); if (slash != NULL) { if (slash != path) *slash = '\0'; else strcpy(path, "/"); } else strcpy(path, "."); #endif if (chmod(path, perm) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, "isc_socket_permunix: chmod(%s, %d): %s", path, perm, strbuf); result = ISC_R_FAILURE; } if (chown(path, owner, group) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, "isc_socket_permunix: chown(%s, %d, %d): %s", path, owner, group, strbuf); result = ISC_R_FAILURE; } return (result); #else UNUSED(sockaddr); UNUSED(perm); UNUSED(owner); UNUSED(group); return (ISC_R_NOTIMPLEMENTED); #endif } isc_result_t isc__socket_bind(isc_socket_t *sock0, isc_sockaddr_t *sockaddr, unsigned int options) { isc__socket_t *sock = (isc__socket_t *)sock0; char strbuf[ISC_STRERRORSIZE]; int on = 1; REQUIRE(VALID_SOCKET(sock)); LOCK(&sock->lock); INSIST(!sock->bound); INSIST(!sock->dupped); if (sock->pf != sockaddr->type.sa.sa_family) { UNLOCK(&sock->lock); return (ISC_R_FAMILYMISMATCH); } /* * Only set SO_REUSEADDR when we want a specific port. */ #ifdef AF_UNIX if (sock->pf == AF_UNIX) goto bind_socket; #endif if ((options & ISC_SOCKET_REUSEADDRESS) != 0 && isc_sockaddr_getport(sockaddr) != (in_port_t)0 && setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)) < 0) { UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d) %s", sock->fd, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); /* Press on... */ } #ifdef AF_UNIX bind_socket: #endif if (bind(sock->fd, &sockaddr->type.sa, sockaddr->length) < 0) { inc_stats(sock->manager->stats, sock->statsindex[STATID_BINDFAIL]); UNLOCK(&sock->lock); switch (errno) { case EACCES: return (ISC_R_NOPERM); case EADDRNOTAVAIL: return (ISC_R_ADDRNOTAVAIL); case EADDRINUSE: return (ISC_R_ADDRINUSE); case EINVAL: return (ISC_R_BOUND); default: isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "bind: %s", strbuf); return (ISC_R_UNEXPECTED); } } socket_log(sock, sockaddr, TRACE, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_BOUND, "bound"); sock->bound = 1; UNLOCK(&sock->lock); return (ISC_R_SUCCESS); } /* * Enable this only for specific OS versions, and only when they have repaired * their problems with it. Until then, this is is broken and needs to be * diabled by default. See RT22589 for details. */ #undef ENABLE_ACCEPTFILTER isc_result_t isc__socket_filter(isc_socket_t *sock0, const char *filter) { isc__socket_t *sock = (isc__socket_t *)sock0; #if defined(SO_ACCEPTFILTER) && defined(ENABLE_ACCEPTFILTER) char strbuf[ISC_STRERRORSIZE]; struct accept_filter_arg afa; #else UNUSED(sock); UNUSED(filter); #endif REQUIRE(VALID_SOCKET(sock)); #if defined(SO_ACCEPTFILTER) && defined(ENABLE_ACCEPTFILTER) bzero(&afa, sizeof(afa)); strncpy(afa.af_name, filter, sizeof(afa.af_name)); if (setsockopt(sock->fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa)) == -1) { isc__strerror(errno, strbuf, sizeof(strbuf)); socket_log(sock, NULL, CREATION, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_FILTER, "setsockopt(SO_ACCEPTFILTER): %s", strbuf); return (ISC_R_FAILURE); } return (ISC_R_SUCCESS); #else return (ISC_R_NOTIMPLEMENTED); #endif } /* * Set up to listen on a given socket. We do this by creating an internal * event that will be dispatched when the socket has read activity. The * watcher will send the internal event to the task when there is a new * connection. * * Unlike in read, we don't preallocate a done event here. Every time there * is a new connection we'll have to allocate a new one anyway, so we might * as well keep things simple rather than having to track them. */ isc_result_t isc__socket_listen(isc_socket_t *sock0, unsigned int backlog) { isc__socket_t *sock = (isc__socket_t *)sock0; char strbuf[ISC_STRERRORSIZE]; REQUIRE(VALID_SOCKET(sock)); LOCK(&sock->lock); REQUIRE(!sock->listener); REQUIRE(sock->bound); REQUIRE(sock->type == isc_sockettype_tcp || sock->type == isc_sockettype_unix); if (backlog == 0) backlog = SOMAXCONN; if (listen(sock->fd, (int)backlog) < 0) { UNLOCK(&sock->lock); isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "listen: %s", strbuf); return (ISC_R_UNEXPECTED); } sock->listener = 1; UNLOCK(&sock->lock); return (ISC_R_SUCCESS); } /* * This should try to do aggressive accept() XXXMLG */ isc_result_t isc__socket_accept(isc_socket_t *sock0, isc_task_t *task, isc_taskaction_t action, void *arg) { isc__socket_t *sock = (isc__socket_t *)sock0; isc_socket_newconnev_t *dev; isc__socketmgr_t *manager; isc_task_t *ntask = NULL; isc__socket_t *nsock; isc_result_t result; isc_boolean_t do_poke = ISC_FALSE; REQUIRE(VALID_SOCKET(sock)); manager = sock->manager; REQUIRE(VALID_MANAGER(manager)); LOCK(&sock->lock); REQUIRE(sock->listener); /* * Sender field is overloaded here with the task we will be sending * this event to. Just before the actual event is delivered the * actual ev_sender will be touched up to be the socket. */ dev = (isc_socket_newconnev_t *) isc_event_allocate(manager->mctx, task, ISC_SOCKEVENT_NEWCONN, action, arg, sizeof(*dev)); if (dev == NULL) { UNLOCK(&sock->lock); return (ISC_R_NOMEMORY); } ISC_LINK_INIT(dev, ev_link); result = allocate_socket(manager, sock->type, &nsock); if (result != ISC_R_SUCCESS) { isc_event_free(ISC_EVENT_PTR(&dev)); UNLOCK(&sock->lock); return (result); } /* * Attach to socket and to task. */ isc_task_attach(task, &ntask); if (isc_task_exiting(ntask)) { free_socket(&nsock); isc_task_detach(&ntask); isc_event_free(ISC_EVENT_PTR(&dev)); UNLOCK(&sock->lock); return (ISC_R_SHUTTINGDOWN); } nsock->references++; nsock->statsindex = sock->statsindex; dev->ev_sender = ntask; dev->newsocket = (isc_socket_t *)nsock; /* * Poke watcher here. We still have the socket locked, so there * is no race condition. We will keep the lock for such a short * bit of time waking it up now or later won't matter all that much. */ if (ISC_LIST_EMPTY(sock->accept_list)) do_poke = ISC_TRUE; ISC_LIST_ENQUEUE(sock->accept_list, dev, ev_link); if (do_poke) select_poke(manager, sock->fd, SELECT_POKE_ACCEPT); UNLOCK(&sock->lock); return (ISC_R_SUCCESS); } isc_result_t isc__socket_connect(isc_socket_t *sock0, isc_sockaddr_t *addr, isc_task_t *task, isc_taskaction_t action, void *arg) { isc__socket_t *sock = (isc__socket_t *)sock0; isc_socket_connev_t *dev; isc_task_t *ntask = NULL; isc__socketmgr_t *manager; int cc; char strbuf[ISC_STRERRORSIZE]; char addrbuf[ISC_SOCKADDR_FORMATSIZE]; REQUIRE(VALID_SOCKET(sock)); REQUIRE(addr != NULL); REQUIRE(task != NULL); REQUIRE(action != NULL); manager = sock->manager; REQUIRE(VALID_MANAGER(manager)); REQUIRE(addr != NULL); if (isc_sockaddr_ismulticast(addr)) return (ISC_R_MULTICAST); LOCK(&sock->lock); REQUIRE(!sock->connecting); dev = (isc_socket_connev_t *)isc_event_allocate(manager->mctx, sock, ISC_SOCKEVENT_CONNECT, action, arg, sizeof(*dev)); if (dev == NULL) { UNLOCK(&sock->lock); return (ISC_R_NOMEMORY); } ISC_LINK_INIT(dev, ev_link); /* * Try to do the connect right away, as there can be only one * outstanding, and it might happen to complete. */ sock->peer_address = *addr; cc = connect(sock->fd, &addr->type.sa, addr->length); if (cc < 0) { /* * HP-UX "fails" to connect a UDP socket and sets errno to * EINPROGRESS if it's non-blocking. We'd rather regard this as * a success and let the user detect it if it's really an error * at the time of sending a packet on the socket. */ if (sock->type == isc_sockettype_udp && errno == EINPROGRESS) { cc = 0; goto success; } if (SOFT_ERROR(errno) || errno == EINPROGRESS) goto queue; switch (errno) { #define ERROR_MATCH(a, b) case a: dev->result = b; goto err_exit; ERROR_MATCH(EACCES, ISC_R_NOPERM); ERROR_MATCH(EADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL); ERROR_MATCH(EAFNOSUPPORT, ISC_R_ADDRNOTAVAIL); ERROR_MATCH(ECONNREFUSED, ISC_R_CONNREFUSED); ERROR_MATCH(EHOSTUNREACH, ISC_R_HOSTUNREACH); #ifdef EHOSTDOWN ERROR_MATCH(EHOSTDOWN, ISC_R_HOSTUNREACH); #endif ERROR_MATCH(ENETUNREACH, ISC_R_NETUNREACH); ERROR_MATCH(ENOBUFS, ISC_R_NORESOURCES); ERROR_MATCH(EPERM, ISC_R_HOSTUNREACH); ERROR_MATCH(EPIPE, ISC_R_NOTCONNECTED); ERROR_MATCH(ECONNRESET, ISC_R_CONNECTIONRESET); #undef ERROR_MATCH } sock->connected = 0; isc__strerror(errno, strbuf, sizeof(strbuf)); isc_sockaddr_format(addr, addrbuf, sizeof(addrbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "connect(%s) %d/%s", addrbuf, errno, strbuf); UNLOCK(&sock->lock); inc_stats(sock->manager->stats, sock->statsindex[STATID_CONNECTFAIL]); isc_event_free(ISC_EVENT_PTR(&dev)); return (ISC_R_UNEXPECTED); err_exit: sock->connected = 0; isc_task_send(task, ISC_EVENT_PTR(&dev)); UNLOCK(&sock->lock); inc_stats(sock->manager->stats, sock->statsindex[STATID_CONNECTFAIL]); return (ISC_R_SUCCESS); } /* * If connect completed, fire off the done event. */ success: if (cc == 0) { sock->connected = 1; sock->bound = 1; dev->result = ISC_R_SUCCESS; isc_task_send(task, ISC_EVENT_PTR(&dev)); UNLOCK(&sock->lock); inc_stats(sock->manager->stats, sock->statsindex[STATID_CONNECT]); return (ISC_R_SUCCESS); } queue: /* * Attach to task. */ isc_task_attach(task, &ntask); sock->connecting = 1; dev->ev_sender = ntask; /* * Poke watcher here. We still have the socket locked, so there * is no race condition. We will keep the lock for such a short * bit of time waking it up now or later won't matter all that much. */ if (sock->connect_ev == NULL) select_poke(manager, sock->fd, SELECT_POKE_CONNECT); sock->connect_ev = dev; UNLOCK(&sock->lock); return (ISC_R_SUCCESS); } /* * Called when a socket with a pending connect() finishes. */ static void internal_connect(isc_task_t *me, isc_event_t *ev) { isc__socket_t *sock; isc_socket_connev_t *dev; isc_task_t *task; int cc; ISC_SOCKADDR_LEN_T optlen; char strbuf[ISC_STRERRORSIZE]; char peerbuf[ISC_SOCKADDR_FORMATSIZE]; UNUSED(me); INSIST(ev->ev_type == ISC_SOCKEVENT_INTW); sock = ev->ev_sender; INSIST(VALID_SOCKET(sock)); LOCK(&sock->lock); /* * When the internal event was sent the reference count was bumped * to keep the socket around for us. Decrement the count here. */ INSIST(sock->references > 0); sock->references--; if (sock->references == 0) { UNLOCK(&sock->lock); destroy(&sock); return; } /* * Has this event been canceled? */ dev = sock->connect_ev; if (dev == NULL) { INSIST(!sock->connecting); UNLOCK(&sock->lock); return; } INSIST(sock->connecting); sock->connecting = 0; /* * Get any possible error status here. */ optlen = sizeof(cc); if (getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, (void *)&cc, (void *)&optlen) < 0) cc = errno; else errno = cc; if (errno != 0) { /* * If the error is EAGAIN, just re-select on this * fd and pretend nothing strange happened. */ if (SOFT_ERROR(errno) || errno == EINPROGRESS) { sock->connecting = 1; select_poke(sock->manager, sock->fd, SELECT_POKE_CONNECT); UNLOCK(&sock->lock); return; } inc_stats(sock->manager->stats, sock->statsindex[STATID_CONNECTFAIL]); /* * Translate other errors into ISC_R_* flavors. */ switch (errno) { #define ERROR_MATCH(a, b) case a: dev->result = b; break; ERROR_MATCH(EACCES, ISC_R_NOPERM); ERROR_MATCH(EADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL); ERROR_MATCH(EAFNOSUPPORT, ISC_R_ADDRNOTAVAIL); ERROR_MATCH(ECONNREFUSED, ISC_R_CONNREFUSED); ERROR_MATCH(EHOSTUNREACH, ISC_R_HOSTUNREACH); #ifdef EHOSTDOWN ERROR_MATCH(EHOSTDOWN, ISC_R_HOSTUNREACH); #endif ERROR_MATCH(ENETUNREACH, ISC_R_NETUNREACH); ERROR_MATCH(ENOBUFS, ISC_R_NORESOURCES); ERROR_MATCH(EPERM, ISC_R_HOSTUNREACH); ERROR_MATCH(EPIPE, ISC_R_NOTCONNECTED); ERROR_MATCH(ETIMEDOUT, ISC_R_TIMEDOUT); ERROR_MATCH(ECONNRESET, ISC_R_CONNECTIONRESET); #undef ERROR_MATCH default: dev->result = ISC_R_UNEXPECTED; isc_sockaddr_format(&sock->peer_address, peerbuf, sizeof(peerbuf)); isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "internal_connect: connect(%s) %s", peerbuf, strbuf); } } else { inc_stats(sock->manager->stats, sock->statsindex[STATID_CONNECT]); dev->result = ISC_R_SUCCESS; sock->connected = 1; sock->bound = 1; } sock->connect_ev = NULL; UNLOCK(&sock->lock); task = dev->ev_sender; dev->ev_sender = sock; isc_task_sendanddetach(&task, ISC_EVENT_PTR(&dev)); } isc_result_t isc__socket_getpeername(isc_socket_t *sock0, isc_sockaddr_t *addressp) { isc__socket_t *sock = (isc__socket_t *)sock0; isc_result_t result; REQUIRE(VALID_SOCKET(sock)); REQUIRE(addressp != NULL); LOCK(&sock->lock); if (sock->connected) { *addressp = sock->peer_address; result = ISC_R_SUCCESS; } else { result = ISC_R_NOTCONNECTED; } UNLOCK(&sock->lock); return (result); } isc_result_t isc__socket_getsockname(isc_socket_t *sock0, isc_sockaddr_t *addressp) { isc__socket_t *sock = (isc__socket_t *)sock0; ISC_SOCKADDR_LEN_T len; isc_result_t result; char strbuf[ISC_STRERRORSIZE]; REQUIRE(VALID_SOCKET(sock)); REQUIRE(addressp != NULL); LOCK(&sock->lock); if (!sock->bound) { result = ISC_R_NOTBOUND; goto out; } result = ISC_R_SUCCESS; len = sizeof(addressp->type); if (getsockname(sock->fd, &addressp->type.sa, (void *)&len) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "getsockname: %s", strbuf); result = ISC_R_UNEXPECTED; goto out; } addressp->length = (unsigned int)len; out: UNLOCK(&sock->lock); return (result); } /* * Run through the list of events on this socket, and cancel the ones * queued for task "task" of type "how". "how" is a bitmask. */ void isc__socket_cancel(isc_socket_t *sock0, isc_task_t *task, unsigned int how) { isc__socket_t *sock = (isc__socket_t *)sock0; REQUIRE(VALID_SOCKET(sock)); /* * Quick exit if there is nothing to do. Don't even bother locking * in this case. */ if (how == 0) return; LOCK(&sock->lock); /* * All of these do the same thing, more or less. * Each will: * o If the internal event is marked as "posted" try to * remove it from the task's queue. If this fails, mark it * as canceled instead, and let the task clean it up later. * o For each I/O request for that task of that type, post * its done event with status of "ISC_R_CANCELED". * o Reset any state needed. */ if (((how & ISC_SOCKCANCEL_RECV) == ISC_SOCKCANCEL_RECV) && !ISC_LIST_EMPTY(sock->recv_list)) { isc_socketevent_t *dev; isc_socketevent_t *next; isc_task_t *current_task; dev = ISC_LIST_HEAD(sock->recv_list); while (dev != NULL) { current_task = dev->ev_sender; next = ISC_LIST_NEXT(dev, ev_link); if ((task == NULL) || (task == current_task)) { dev->result = ISC_R_CANCELED; send_recvdone_event(sock, &dev); } dev = next; } } if (((how & ISC_SOCKCANCEL_SEND) == ISC_SOCKCANCEL_SEND) && !ISC_LIST_EMPTY(sock->send_list)) { isc_socketevent_t *dev; isc_socketevent_t *next; isc_task_t *current_task; dev = ISC_LIST_HEAD(sock->send_list); while (dev != NULL) { current_task = dev->ev_sender; next = ISC_LIST_NEXT(dev, ev_link); if ((task == NULL) || (task == current_task)) { dev->result = ISC_R_CANCELED; send_senddone_event(sock, &dev); } dev = next; } } if (((how & ISC_SOCKCANCEL_ACCEPT) == ISC_SOCKCANCEL_ACCEPT) && !ISC_LIST_EMPTY(sock->accept_list)) { isc_socket_newconnev_t *dev; isc_socket_newconnev_t *next; isc_task_t *current_task; dev = ISC_LIST_HEAD(sock->accept_list); while (dev != NULL) { current_task = dev->ev_sender; next = ISC_LIST_NEXT(dev, ev_link); if ((task == NULL) || (task == current_task)) { ISC_LIST_UNLINK(sock->accept_list, dev, ev_link); NEWCONNSOCK(dev)->references--; free_socket((isc__socket_t **)&dev->newsocket); dev->result = ISC_R_CANCELED; dev->ev_sender = sock; isc_task_sendanddetach(¤t_task, ISC_EVENT_PTR(&dev)); } dev = next; } } /* * Connecting is not a list. */ if (((how & ISC_SOCKCANCEL_CONNECT) == ISC_SOCKCANCEL_CONNECT) && sock->connect_ev != NULL) { isc_socket_connev_t *dev; isc_task_t *current_task; INSIST(sock->connecting); sock->connecting = 0; dev = sock->connect_ev; current_task = dev->ev_sender; if ((task == NULL) || (task == current_task)) { sock->connect_ev = NULL; dev->result = ISC_R_CANCELED; dev->ev_sender = sock; isc_task_sendanddetach(¤t_task, ISC_EVENT_PTR(&dev)); } } UNLOCK(&sock->lock); } isc_sockettype_t isc__socket_gettype(isc_socket_t *sock0) { isc__socket_t *sock = (isc__socket_t *)sock0; REQUIRE(VALID_SOCKET(sock)); return (sock->type); } isc_boolean_t isc__socket_isbound(isc_socket_t *sock0) { isc__socket_t *sock = (isc__socket_t *)sock0; isc_boolean_t val; REQUIRE(VALID_SOCKET(sock)); LOCK(&sock->lock); val = ((sock->bound) ? ISC_TRUE : ISC_FALSE); UNLOCK(&sock->lock); return (val); } void isc__socket_ipv6only(isc_socket_t *sock0, isc_boolean_t yes) { isc__socket_t *sock = (isc__socket_t *)sock0; #if defined(IPV6_V6ONLY) int onoff = yes ? 1 : 0; #else UNUSED(yes); UNUSED(sock); #endif REQUIRE(VALID_SOCKET(sock)); INSIST(!sock->dupped); #ifdef IPV6_V6ONLY if (sock->pf == AF_INET6) { if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&onoff, sizeof(int)) < 0) { char strbuf[ISC_STRERRORSIZE]; isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, IPV6_V6ONLY) " "%s: %s", sock->fd, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); } } FIX_IPV6_RECVPKTINFO(sock); /* AIX */ #endif } static void setdscp(isc__socket_t *sock, isc_dscp_t dscp) { #if defined(IP_TOS) || defined(IPV6_TCLASS) int value = dscp << 2; #endif sock->dscp = dscp; #ifdef IP_TOS if (sock->pf == AF_INET) { if (setsockopt(sock->fd, IPPROTO_IP, IP_TOS, (void *)&value, sizeof(value)) < 0) { char strbuf[ISC_STRERRORSIZE]; isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, IP_TOS, %.02x) " "%s: %s", sock->fd, value >> 2, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); } } #endif #ifdef IPV6_TCLASS if (sock->pf == AF_INET6) { if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_TCLASS, (void *)&value, sizeof(value)) < 0) { char strbuf[ISC_STRERRORSIZE]; isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, IPV6_TCLASS, %.02x) " "%s: %s", sock->fd, dscp >> 2, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); } } #endif } void isc__socket_dscp(isc_socket_t *sock0, isc_dscp_t dscp) { isc__socket_t *sock = (isc__socket_t *)sock0; REQUIRE(VALID_SOCKET(sock)); REQUIRE(dscp < 0x40); #if !defined(IP_TOS) && !defined(IPV6_TCLASS) UNUSED(dscp); #else if (dscp < 0) return; /* The DSCP value must not be changed once it has been set. */ if (isc_dscp_check_value != -1) INSIST(dscp == isc_dscp_check_value); #endif #ifdef notyet REQUIRE(!sock->dupped); #endif setdscp(sock, dscp); } isc_socketevent_t * isc_socket_socketevent(isc_mem_t *mctx, void *sender, isc_eventtype_t eventtype, isc_taskaction_t action, void *arg) { return (allocate_socketevent(mctx, sender, eventtype, action, arg)); } #ifndef USE_WATCHER_THREAD /* * In our assumed scenario, we can simply use a single static object. * XXX: this is not true if the application uses multiple threads with * 'multi-context' mode. Fixing this is a future TODO item. */ static isc_socketwait_t swait_private; int isc__socketmgr_waitevents(isc_socketmgr_t *manager0, struct timeval *tvp, isc_socketwait_t **swaitp) { isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0; int n; #ifdef USE_KQUEUE struct timespec ts, *tsp; #endif #ifdef USE_EPOLL int timeout; #endif #ifdef USE_DEVPOLL isc_result_t result; int pass; struct dvpoll dvp; #endif REQUIRE(swaitp != NULL && *swaitp == NULL); #ifdef USE_SHARED_MANAGER if (manager == NULL) manager = socketmgr; #endif if (manager == NULL) return (0); #ifdef USE_KQUEUE if (tvp != NULL) { ts.tv_sec = tvp->tv_sec; ts.tv_nsec = tvp->tv_usec * 1000; tsp = &ts; } else tsp = NULL; swait_private.nevents = kevent(manager->kqueue_fd, NULL, 0, manager->events, manager->nevents, tsp); n = swait_private.nevents; #elif defined(USE_EPOLL) if (tvp != NULL) timeout = tvp->tv_sec * 1000 + (tvp->tv_usec + 999) / 1000; else timeout = -1; swait_private.nevents = epoll_wait(manager->epoll_fd, manager->events, manager->nevents, timeout); n = swait_private.nevents; #elif defined(USE_DEVPOLL) /* * Re-probe every thousand calls. */ if (manager->calls++ > 1000U) { result = isc_resource_getcurlimit(isc_resource_openfiles, &manager->open_max); if (result != ISC_R_SUCCESS) manager->open_max = 64; manager->calls = 0; } for (pass = 0; pass < 2; pass++) { dvp.dp_fds = manager->events; dvp.dp_nfds = manager->nevents; if (dvp.dp_nfds >= manager->open_max) dvp.dp_nfds = manager->open_max - 1; if (tvp != NULL) { dvp.dp_timeout = tvp->tv_sec * 1000 + (tvp->tv_usec + 999) / 1000; } else dvp.dp_timeout = -1; n = ioctl(manager->devpoll_fd, DP_POLL, &dvp); if (n == -1 && errno == EINVAL) { /* * {OPEN_MAX} may have dropped. Look * up the current value and try again. */ result = isc_resource_getcurlimit( isc_resource_openfiles, &manager->open_max); if (result != ISC_R_SUCCESS) manager->open_max = 64; } else break; } swait_private.nevents = n; #elif defined(USE_SELECT) memmove(manager->read_fds_copy, manager->read_fds, manager->fd_bufsize); memmove(manager->write_fds_copy, manager->write_fds, manager->fd_bufsize); swait_private.readset = manager->read_fds_copy; swait_private.writeset = manager->write_fds_copy; swait_private.maxfd = manager->maxfd + 1; n = select(swait_private.maxfd, swait_private.readset, swait_private.writeset, NULL, tvp); #endif *swaitp = &swait_private; return (n); } isc_result_t isc__socketmgr_dispatch(isc_socketmgr_t *manager0, isc_socketwait_t *swait) { isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0; REQUIRE(swait == &swait_private); #ifdef USE_SHARED_MANAGER if (manager == NULL) manager = socketmgr; #endif if (manager == NULL) return (ISC_R_NOTFOUND); #if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL) (void)process_fds(manager, manager->events, swait->nevents); return (ISC_R_SUCCESS); #elif defined(USE_SELECT) process_fds(manager, swait->maxfd, swait->readset, swait->writeset); return (ISC_R_SUCCESS); #endif } #endif /* USE_WATCHER_THREAD */ void isc__socket_setname(isc_socket_t *socket0, const char *name, void *tag) { isc__socket_t *sock = (isc__socket_t *)socket0; /* * Name 'sock'. */ REQUIRE(VALID_SOCKET(sock)); LOCK(&sock->lock); memset(sock->name, 0, sizeof(sock->name)); strncpy(sock->name, name, sizeof(sock->name) - 1); sock->tag = tag; UNLOCK(&sock->lock); } const char * isc__socket_getname(isc_socket_t *socket0) { isc__socket_t *sock = (isc__socket_t *)socket0; return (sock->name); } void * isc__socket_gettag(isc_socket_t *socket0) { isc__socket_t *sock = (isc__socket_t *)socket0; return (sock->tag); } isc_result_t isc__socket_register(void) { return (isc_socket_register(isc__socketmgr_create)); } int isc__socket_getfd(isc_socket_t *socket0) { isc__socket_t *sock = (isc__socket_t *)socket0; return ((short) sock->fd); } #if defined(HAVE_LIBXML2) || defined(HAVE_JSON) static const char * _socktype(isc_sockettype_t type) { if (type == isc_sockettype_udp) return ("udp"); else if (type == isc_sockettype_tcp) return ("tcp"); else if (type == isc_sockettype_unix) return ("unix"); else if (type == isc_sockettype_fdwatch) return ("fdwatch"); else return ("not-initialized"); } #endif #ifdef HAVE_LIBXML2 #define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0) int isc_socketmgr_renderxml(isc_socketmgr_t *mgr0, xmlTextWriterPtr writer) { isc__socketmgr_t *mgr = (isc__socketmgr_t *)mgr0; isc__socket_t *sock = NULL; char peerbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_t addr; ISC_SOCKADDR_LEN_T len; int xmlrc; LOCK(&mgr->lock); #ifdef USE_SHARED_MANAGER TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references")); TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->refs)); TRY0(xmlTextWriterEndElement(writer)); #endif /* USE_SHARED_MANAGER */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "sockets")); sock = ISC_LIST_HEAD(mgr->socklist); while (sock != NULL) { LOCK(&sock->lock); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "socket")); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "id")); TRY0(xmlTextWriterWriteFormatString(writer, "%p", sock)); TRY0(xmlTextWriterEndElement(writer)); if (sock->name[0] != 0) { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); TRY0(xmlTextWriterWriteFormatString(writer, "%s", sock->name)); TRY0(xmlTextWriterEndElement(writer)); /* name */ } TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references")); TRY0(xmlTextWriterWriteFormatString(writer, "%d", sock->references)); TRY0(xmlTextWriterEndElement(writer)); TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "type", ISC_XMLCHAR _socktype(sock->type))); if (sock->connected) { isc_sockaddr_format(&sock->peer_address, peerbuf, sizeof(peerbuf)); TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "peer-address", ISC_XMLCHAR peerbuf)); } len = sizeof(addr); if (getsockname(sock->fd, &addr.type.sa, (void *)&len) == 0) { isc_sockaddr_format(&addr, peerbuf, sizeof(peerbuf)); TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "local-address", ISC_XMLCHAR peerbuf)); } TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "states")); if (sock->pending_recv) TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", ISC_XMLCHAR "pending-receive")); if (sock->pending_send) TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", ISC_XMLCHAR "pending-send")); if (sock->pending_accept) TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", ISC_XMLCHAR "pending_accept")); if (sock->listener) TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", ISC_XMLCHAR "listener")); if (sock->connected) TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", ISC_XMLCHAR "connected")); if (sock->connecting) TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", ISC_XMLCHAR "connecting")); if (sock->bound) TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", ISC_XMLCHAR "bound")); TRY0(xmlTextWriterEndElement(writer)); /* states */ TRY0(xmlTextWriterEndElement(writer)); /* socket */ UNLOCK(&sock->lock); sock = ISC_LIST_NEXT(sock, link); } TRY0(xmlTextWriterEndElement(writer)); /* sockets */ error: if (sock != NULL) UNLOCK(&sock->lock); UNLOCK(&mgr->lock); return (xmlrc); } #endif /* HAVE_LIBXML2 */ #ifdef HAVE_JSON #define CHECKMEM(m) do { \ if (m == NULL) { \ result = ISC_R_NOMEMORY;\ goto error;\ } \ } while(0) isc_result_t isc_socketmgr_renderjson(isc_socketmgr_t *mgr0, json_object *stats) { isc_result_t result = ISC_R_SUCCESS; isc__socketmgr_t *mgr = (isc__socketmgr_t *)mgr0; isc__socket_t *sock = NULL; char peerbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_t addr; ISC_SOCKADDR_LEN_T len; json_object *obj, *array = json_object_new_array(); CHECKMEM(array); LOCK(&mgr->lock); #ifdef USE_SHARED_MANAGER obj = json_object_new_int(mgr->refs); CHECKMEM(obj); json_object_object_add(stats, "references", obj); #endif /* USE_SHARED_MANAGER */ sock = ISC_LIST_HEAD(mgr->socklist); while (sock != NULL) { json_object *states, *entry = json_object_new_object(); char buf[255]; CHECKMEM(entry); json_object_array_add(array, entry); LOCK(&sock->lock); sprintf(buf, "%p", sock); obj = json_object_new_string(buf); CHECKMEM(obj); json_object_object_add(entry, "id", obj); if (sock->name[0] != 0) { obj = json_object_new_string(sock->name); CHECKMEM(obj); json_object_object_add(entry, "name", obj); } obj = json_object_new_int(sock->references); CHECKMEM(obj); json_object_object_add(entry, "references", obj); obj = json_object_new_string(_socktype(sock->type)); CHECKMEM(obj); json_object_object_add(entry, "type", obj); if (sock->connected) { isc_sockaddr_format(&sock->peer_address, peerbuf, sizeof(peerbuf)); obj = json_object_new_string(peerbuf); CHECKMEM(obj); json_object_object_add(entry, "peer-address", obj); } len = sizeof(addr); if (getsockname(sock->fd, &addr.type.sa, (void *)&len) == 0) { isc_sockaddr_format(&addr, peerbuf, sizeof(peerbuf)); obj = json_object_new_string(peerbuf); CHECKMEM(obj); json_object_object_add(entry, "local-address", obj); } states = json_object_new_array(); CHECKMEM(states); json_object_object_add(entry, "states", states); if (sock->pending_recv) { obj = json_object_new_string("pending-receive"); CHECKMEM(obj); json_object_array_add(states, obj); } if (sock->pending_send) { obj = json_object_new_string("pending-send"); CHECKMEM(obj); json_object_array_add(states, obj); } if (sock->pending_accept) { obj = json_object_new_string("pending-accept"); CHECKMEM(obj); json_object_array_add(states, obj); } if (sock->listener) { obj = json_object_new_string("listener"); CHECKMEM(obj); json_object_array_add(states, obj); } if (sock->connected) { obj = json_object_new_string("connected"); CHECKMEM(obj); json_object_array_add(states, obj); } if (sock->connecting) { obj = json_object_new_string("connecting"); CHECKMEM(obj); json_object_array_add(states, obj); } if (sock->bound) { obj = json_object_new_string("bound"); CHECKMEM(obj); json_object_array_add(states, obj); } UNLOCK(&sock->lock); sock = ISC_LIST_NEXT(sock, link); } json_object_object_add(stats, "sockets", array); array = NULL; result = ISC_R_SUCCESS; error: if (array != NULL) json_object_put(array); if (sock != NULL) UNLOCK(&sock->lock); UNLOCK(&mgr->lock); return (result); } #endif /* HAVE_JSON */ #include "../socket_api.c" bind9-9.10.3.dfsg.P4/lib/isc/unix/Makefile.in0000644000470500017500000000336012664710322017747 0ustar lamontlamont# Copyright (C) 2004, 2007, 2009, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.44 2009/12/05 23:31:41 each Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ CINCLUDES = -I${srcdir}/include \ -I${srcdir}/../@ISC_THREAD_DIR@/include \ -I../include \ -I${srcdir}/../include \ -I${srcdir}/.. CDEFINES = CWARNINGS = # Alphabetically OBJS = @ISC_IPV6_O@ @ISC_PK11_API_O@ \ app.@O@ dir.@O@ entropy.@O@ errno2result.@O@ file.@O@ \ fsaccess.@O@ interfaceiter.@O@ keyboard.@O@ net.@O@ \ os.@O@ resource.@O@ socket.@O@ stdio.@O@ stdtime.@O@ \ strerror.@O@ syslog.@O@ time.@O@ # Alphabetically SRCS = @ISC_IPV6_C@ @ISC_PK11_API_C@ \ app.c dir.c entropy.c errno2result.c file.c \ fsaccess.c interfaceiter.c keyboard.c net.c \ os.c resource.c socket.c stdio.c stdtime.c \ strerror.c syslog.c time.c SUBDIRS = include TARGETS = ${OBJS} @BIND9_MAKE_RULES@ interfaceiter.@O@: interfaceiter.c ifiter_ioctl.c ifiter_sysctl.c ifiter_getifaddrs.c bind9-9.10.3.dfsg.P4/lib/isc/unix/interfaceiter.c0000644000470500017500000001767412664710322020707 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2008, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: interfaceiter.c,v 1.45 2008/12/01 03:51:47 marka Exp $ */ /*! \file */ #include #include #include #ifdef HAVE_SYS_SOCKIO_H #include /* Required for ifiter_ioctl.c. */ #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Must follow . */ #ifdef HAVE_NET_IF6_H #include #endif #include /* Common utility functions */ /*% * Extract the network address part from a "struct sockaddr". * \brief * The address family is given explicitly * instead of using src->sa_family, because the latter does not work * for copying a network mask obtained by SIOCGIFNETMASK (it does * not have a valid address family). */ static void get_addr(unsigned int family, isc_netaddr_t *dst, struct sockaddr *src, char *ifname) { struct sockaddr_in6 *sa6; #if !defined(ISC_PLATFORM_HAVEIFNAMETOINDEX) || \ !defined(ISC_PLATFORM_HAVESCOPEID) UNUSED(ifname); #endif /* clear any remaining value for safety */ memset(dst, 0, sizeof(*dst)); dst->family = family; switch (family) { case AF_INET: memmove(&dst->type.in, &((struct sockaddr_in *) src)->sin_addr, sizeof(struct in_addr)); break; case AF_INET6: sa6 = (struct sockaddr_in6 *)src; memmove(&dst->type.in6, &sa6->sin6_addr, sizeof(struct in6_addr)); #ifdef ISC_PLATFORM_HAVESCOPEID if (sa6->sin6_scope_id != 0) isc_netaddr_setzone(dst, sa6->sin6_scope_id); else { /* * BSD variants embed scope zone IDs in the 128bit * address as a kernel internal form. Unfortunately, * the embedded IDs are not hidden from applications * when getting access to them by sysctl or ioctl. * We convert the internal format to the pure address * part and the zone ID part. * Since multicast addresses should not appear here * and they cannot be distinguished from netmasks, * we only consider unicast link-local addresses. */ if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) { isc_uint16_t zone16; memmove(&zone16, &sa6->sin6_addr.s6_addr[2], sizeof(zone16)); zone16 = ntohs(zone16); if (zone16 != 0) { /* the zone ID is embedded */ isc_netaddr_setzone(dst, (isc_uint32_t)zone16); dst->type.in6.s6_addr[2] = 0; dst->type.in6.s6_addr[3] = 0; #ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX } else if (ifname != NULL) { unsigned int zone; /* * sin6_scope_id is still not provided, * but the corresponding interface name * is know. Use the interface ID as * the link ID. */ zone = if_nametoindex(ifname); if (zone != 0) { isc_netaddr_setzone(dst, (isc_uint32_t)zone); } #endif } } } #endif break; default: INSIST(0); break; } } /* * Include system-dependent code. */ #ifdef __linux #define ISC_IF_INET6_SZ \ sizeof("00000000000000000000000000000001 01 80 10 80 XXXXXXloXXXXXXXX\n") static isc_result_t linux_if_inet6_next(isc_interfaceiter_t *); static isc_result_t linux_if_inet6_current(isc_interfaceiter_t *); static void linux_if_inet6_first(isc_interfaceiter_t *iter); #endif #if HAVE_GETIFADDRS #include "ifiter_getifaddrs.c" #elif HAVE_IFLIST_SYSCTL #include "ifiter_sysctl.c" #else #include "ifiter_ioctl.c" #endif #ifdef __linux static void linux_if_inet6_first(isc_interfaceiter_t *iter) { if (iter->proc != NULL) { rewind(iter->proc); (void)linux_if_inet6_next(iter); } else iter->valid = ISC_R_NOMORE; } static isc_result_t linux_if_inet6_next(isc_interfaceiter_t *iter) { if (iter->proc != NULL && fgets(iter->entry, sizeof(iter->entry), iter->proc) != NULL) iter->valid = ISC_R_SUCCESS; else iter->valid = ISC_R_NOMORE; return (iter->valid); } static isc_result_t linux_if_inet6_current(isc_interfaceiter_t *iter) { char address[33]; char name[IF_NAMESIZE+1]; struct in6_addr addr6; int ifindex, prefix, flag3, flag4; int res; unsigned int i; if (iter->valid != ISC_R_SUCCESS) return (iter->valid); if (iter->proc == NULL) { isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR, "/proc/net/if_inet6:iter->proc == NULL"); return (ISC_R_FAILURE); } res = sscanf(iter->entry, "%32[a-f0-9] %x %x %x %x %16s\n", address, &ifindex, &prefix, &flag3, &flag4, name); if (res != 6) { isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR, "/proc/net/if_inet6:sscanf() -> %d (expected 6)", res); return (ISC_R_FAILURE); } if (strlen(address) != 32) { isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR, "/proc/net/if_inet6:strlen(%s) != 32", address); return (ISC_R_FAILURE); } for (i = 0; i < 16; i++) { unsigned char byte; static const char hex[] = "0123456789abcdef"; byte = ((strchr(hex, address[i * 2]) - hex) << 4) | (strchr(hex, address[i * 2 + 1]) - hex); addr6.s6_addr[i] = byte; } iter->current.af = AF_INET6; iter->current.flags = INTERFACE_F_UP; isc_netaddr_fromin6(&iter->current.address, &addr6); if (isc_netaddr_islinklocal(&iter->current.address)) { isc_netaddr_setzone(&iter->current.address, (isc_uint32_t)ifindex); } for (i = 0; i < 16; i++) { if (prefix > 8) { addr6.s6_addr[i] = 0xff; prefix -= 8; } else { addr6.s6_addr[i] = (0xff << (8 - prefix)) & 0xff; prefix = 0; } } isc_netaddr_fromin6(&iter->current.netmask, &addr6); strncpy(iter->current.name, name, sizeof(iter->current.name)); return (ISC_R_SUCCESS); } #endif /* * The remaining code is common to the sysctl and ioctl case. */ isc_result_t isc_interfaceiter_current(isc_interfaceiter_t *iter, isc_interface_t *ifdata) { REQUIRE(iter->result == ISC_R_SUCCESS); memmove(ifdata, &iter->current, sizeof(*ifdata)); return (ISC_R_SUCCESS); } isc_result_t isc_interfaceiter_first(isc_interfaceiter_t *iter) { isc_result_t result; REQUIRE(VALID_IFITER(iter)); internal_first(iter); for (;;) { result = internal_current(iter); if (result != ISC_R_IGNORE) break; result = internal_next(iter); if (result != ISC_R_SUCCESS) break; } iter->result = result; return (result); } isc_result_t isc_interfaceiter_next(isc_interfaceiter_t *iter) { isc_result_t result; REQUIRE(VALID_IFITER(iter)); REQUIRE(iter->result == ISC_R_SUCCESS); for (;;) { result = internal_next(iter); if (result != ISC_R_SUCCESS) break; result = internal_current(iter); if (result != ISC_R_IGNORE) break; } iter->result = result; return (result); } void isc_interfaceiter_destroy(isc_interfaceiter_t **iterp) { isc_interfaceiter_t *iter; REQUIRE(iterp != NULL); iter = *iterp; REQUIRE(VALID_IFITER(iter)); internal_destroy(iter); if (iter->buf != NULL) isc_mem_put(iter->mctx, iter->buf, iter->bufsize); iter->magic = 0; isc_mem_put(iter->mctx, iter, sizeof(*iter)); *iterp = NULL; } bind9-9.10.3.dfsg.P4/lib/isc/unix/stdtime.c0000644000470500017500000000413512664710322017520 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: stdtime.c,v 1.19 2007/06/19 23:47:18 tbox Exp $ */ /*! \file */ #include #include /* NULL */ #include /* NULL */ #include #include #include #include #ifndef ISC_FIX_TV_USEC #define ISC_FIX_TV_USEC 1 #endif #define US_PER_S 1000000 #if ISC_FIX_TV_USEC static inline void fix_tv_usec(struct timeval *tv) { isc_boolean_t fixed = ISC_FALSE; if (tv->tv_usec < 0) { fixed = ISC_TRUE; do { tv->tv_sec -= 1; tv->tv_usec += US_PER_S; } while (tv->tv_usec < 0); } else if (tv->tv_usec >= US_PER_S) { fixed = ISC_TRUE; do { tv->tv_sec += 1; tv->tv_usec -= US_PER_S; } while (tv->tv_usec >=US_PER_S); } /* * Call syslog directly as we are called from the logging functions. */ if (fixed) (void)syslog(LOG_ERR, "gettimeofday returned bad tv_usec: corrected"); } #endif void isc_stdtime_get(isc_stdtime_t *t) { struct timeval tv; /* * Set 't' to the number of seconds since 00:00:00 UTC, January 1, * 1970. */ REQUIRE(t != NULL); RUNTIME_CHECK(gettimeofday(&tv, NULL) != -1); #if ISC_FIX_TV_USEC fix_tv_usec(&tv); INSIST(tv.tv_usec >= 0); #else INSIST(tv.tv_usec >= 0 && tv.tv_usec < US_PER_S); #endif *t = (unsigned int)tv.tv_sec; } bind9-9.10.3.dfsg.P4/lib/isc/unix/errno2result.c0000644000470500017500000000613312664710322020515 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include "errno2result.h" /*% * Convert a POSIX errno value into an isc_result_t. The * list of supported errno values is not complete; new users * of this function should add any expected errors that are * not already there. */ isc_result_t isc___errno2result(int posixerrno, const char *file, unsigned int line) { char strbuf[ISC_STRERRORSIZE]; switch (posixerrno) { case ENOTDIR: case ELOOP: case EINVAL: /* XXX sometimes this is not for files */ case ENAMETOOLONG: case EBADF: return (ISC_R_INVALIDFILE); case ENOENT: return (ISC_R_FILENOTFOUND); case EACCES: case EPERM: return (ISC_R_NOPERM); case EEXIST: return (ISC_R_FILEEXISTS); case EIO: return (ISC_R_IOERROR); case ENOMEM: return (ISC_R_NOMEMORY); case ENFILE: case EMFILE: return (ISC_R_TOOMANYOPENFILES); #ifdef EOVERFLOW case EOVERFLOW: return (ISC_R_RANGE); #endif case EPIPE: #ifdef ECONNRESET case ECONNRESET: #endif #ifdef ECONNABORTED case ECONNABORTED: #endif return (ISC_R_CONNECTIONRESET); #ifdef ENOTCONN case ENOTCONN: return (ISC_R_NOTCONNECTED); #endif #ifdef ETIMEDOUT case ETIMEDOUT: return (ISC_R_TIMEDOUT); #endif #ifdef ENOBUFS case ENOBUFS: return (ISC_R_NORESOURCES); #endif #ifdef EAFNOSUPPORT case EAFNOSUPPORT: return (ISC_R_FAMILYNOSUPPORT); #endif #ifdef ENETDOWN case ENETDOWN: return (ISC_R_NETDOWN); #endif #ifdef EHOSTDOWN case EHOSTDOWN: return (ISC_R_HOSTDOWN); #endif #ifdef ENETUNREACH case ENETUNREACH: return (ISC_R_NETUNREACH); #endif #ifdef EHOSTUNREACH case EHOSTUNREACH: return (ISC_R_HOSTUNREACH); #endif #ifdef EADDRINUSE case EADDRINUSE: return (ISC_R_ADDRINUSE); #endif case EADDRNOTAVAIL: return (ISC_R_ADDRNOTAVAIL); case ECONNREFUSED: return (ISC_R_CONNREFUSED); default: isc__strerror(posixerrno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(file, line, "unable to convert errno " "to isc_result: %d: %s", posixerrno, strbuf); /* * XXXDCL would be nice if perhaps this function could * return the system's error string, so the caller * might have something more descriptive than "unexpected * error" to log with. */ return (ISC_R_UNEXPECTED); } } bind9-9.10.3.dfsg.P4/lib/isc/unix/pk11_api.c0000644000470500017500000004244712664710322017464 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #define KEEP_PKCS11_NAMES #include #include static void *hPK11 = NULL; CK_RV pkcs_C_Initialize(CK_VOID_PTR pReserved) { CK_C_Initialize sym; if (hPK11 != NULL) return (CKR_LIBRARY_ALREADY_INITIALIZED); hPK11 = dlopen(pk11_get_lib_name(), RTLD_NOW); if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); sym = (CK_C_Initialize)dlsym(hPK11, "C_Initialize"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(pReserved); } CK_RV pkcs_C_Finalize(CK_VOID_PTR pReserved) { CK_C_Finalize sym; CK_RV rv; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); sym = (CK_C_Finalize)dlsym(hPK11, "C_Finalize"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); rv = (*sym)(pReserved); if ((rv == CKR_OK) && (dlclose(hPK11) != 0)) return (CKR_LIBRARY_FAILED_TO_LOAD); hPK11 = NULL; return (rv); } CK_RV pkcs_C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) { static CK_C_GetSlotList sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_GetSlotList)dlsym(hPK11, "C_GetSlotList"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(tokenPresent, pSlotList, pulCount); } CK_RV pkcs_C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) { static CK_C_GetTokenInfo sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_GetTokenInfo)dlsym(hPK11, "C_GetTokenInfo"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(slotID, pInfo); } CK_RV pkcs_C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo) { static CK_C_GetMechanismInfo sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_GetMechanismInfo)dlsym(hPK11, "C_GetMechanismInfo"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(slotID, type, pInfo); } CK_RV pkcs_C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_RV (*Notify) (CK_SESSION_HANDLE hSession, CK_NOTIFICATION event, CK_VOID_PTR pApplication), CK_SESSION_HANDLE_PTR phSession) { static CK_C_OpenSession sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) hPK11 = dlopen(pk11_get_lib_name(), RTLD_NOW); if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_OpenSession)dlsym(hPK11, "C_OpenSession"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(slotID, flags, pApplication, Notify, phSession); } CK_RV pkcs_C_CloseSession(CK_SESSION_HANDLE hSession) { static CK_C_CloseSession sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_CloseSession)dlsym(hPK11, "C_CloseSession"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession); } CK_RV pkcs_C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG usPinLen) { static CK_C_Login sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_Login)dlsym(hPK11, "C_Login"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, userType, pPin, usPinLen); } CK_RV pkcs_C_Logout(CK_SESSION_HANDLE hSession) { static CK_C_Logout sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_Logout)dlsym(hPK11, "C_Logout"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession); } CK_RV pkcs_C_CreateObject(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount, CK_OBJECT_HANDLE_PTR phObject) { static CK_C_CreateObject sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_CreateObject)dlsym(hPK11, "C_CreateObject"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pTemplate, usCount, phObject); } CK_RV pkcs_C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) { static CK_C_DestroyObject sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_DestroyObject)dlsym(hPK11, "C_DestroyObject"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, hObject); } CK_RV pkcs_C_GetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount) { static CK_C_GetAttributeValue sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_GetAttributeValue)dlsym(hPK11, "C_GetAttributeValue"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, hObject, pTemplate, usCount); } CK_RV pkcs_C_SetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount) { static CK_C_SetAttributeValue sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_SetAttributeValue)dlsym(hPK11, "C_SetAttributeValue"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, hObject, pTemplate, usCount); } CK_RV pkcs_C_FindObjectsInit(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount) { static CK_C_FindObjectsInit sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_FindObjectsInit)dlsym(hPK11, "C_FindObjectsInit"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pTemplate, usCount); } CK_RV pkcs_C_FindObjects(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG usMaxObjectCount, CK_ULONG_PTR pusObjectCount) { static CK_C_FindObjects sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_FindObjects)dlsym(hPK11, "C_FindObjects"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, phObject, usMaxObjectCount, pusObjectCount); } CK_RV pkcs_C_FindObjectsFinal(CK_SESSION_HANDLE hSession) { static CK_C_FindObjectsFinal sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_FindObjectsFinal)dlsym(hPK11, "C_FindObjectsFinal"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession); } CK_RV pkcs_C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { static CK_C_EncryptInit sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_EncryptInit)dlsym(hPK11, "C_EncryptInit"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pMechanism, hKey); } CK_RV pkcs_C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen) { static CK_C_Encrypt sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_Encrypt)dlsym(hPK11, "C_Encrypt"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pData, ulDataLen, pEncryptedData, pulEncryptedDataLen); } CK_RV pkcs_C_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism) { static CK_C_DigestInit sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_DigestInit)dlsym(hPK11, "C_DigestInit"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pMechanism); } CK_RV pkcs_C_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) { static CK_C_DigestUpdate sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_DigestUpdate)dlsym(hPK11, "C_DigestUpdate"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pPart, ulPartLen); } CK_RV pkcs_C_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen) { static CK_C_DigestFinal sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_DigestFinal)dlsym(hPK11, "C_DigestFinal"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pDigest, pulDigestLen); } CK_RV pkcs_C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { static CK_C_SignInit sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_SignInit)dlsym(hPK11, "C_SignInit"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pMechanism, hKey); } CK_RV pkcs_C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) { static CK_C_Sign sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_Sign)dlsym(hPK11, "C_Sign"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pData, ulDataLen, pSignature, pulSignatureLen); } CK_RV pkcs_C_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) { static CK_C_SignUpdate sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_SignUpdate)dlsym(hPK11, "C_SignUpdate"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pPart, ulPartLen); } CK_RV pkcs_C_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) { static CK_C_SignFinal sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_SignFinal)dlsym(hPK11, "C_SignFinal"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pSignature, pulSignatureLen); } CK_RV pkcs_C_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { static CK_C_VerifyInit sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_VerifyInit)dlsym(hPK11, "C_VerifyInit"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pMechanism, hKey); } CK_RV pkcs_C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) { static CK_C_Verify sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_Verify)dlsym(hPK11, "C_Verify"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pData, ulDataLen, pSignature, ulSignatureLen); } CK_RV pkcs_C_VerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) { static CK_C_VerifyUpdate sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_VerifyUpdate)dlsym(hPK11, "C_VerifyUpdate"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pPart, ulPartLen); } CK_RV pkcs_C_VerifyFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) { static CK_C_VerifyFinal sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_VerifyFinal)dlsym(hPK11, "C_VerifyFinal"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pSignature, ulSignatureLen); } CK_RV pkcs_C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey) { static CK_C_GenerateKey sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_GenerateKey)dlsym(hPK11, "C_GenerateKey"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pMechanism, pTemplate, ulCount, phKey); } CK_RV pkcs_C_GenerateKeyPair(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG usPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG usPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPrivateKey, CK_OBJECT_HANDLE_PTR phPublicKey) { static CK_C_GenerateKeyPair sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_GenerateKeyPair)dlsym(hPK11, "C_GenerateKeyPair"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pMechanism, pPublicKeyTemplate, usPublicKeyAttributeCount, pPrivateKeyTemplate, usPrivateKeyAttributeCount, phPrivateKey, phPublicKey); } CK_RV pkcs_C_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) { static CK_C_DeriveKey sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_DeriveKey)dlsym(hPK11, "C_DeriveKey"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pMechanism, hBaseKey, pTemplate, ulAttributeCount, phKey); } CK_RV pkcs_C_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen) { static CK_C_SeedRandom sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_SeedRandom)dlsym(hPK11, "C_SeedRandom"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pSeed, ulSeedLen); } CK_RV pkcs_C_GenerateRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR RandomData, CK_ULONG ulRandomLen) { static CK_C_GenerateRandom sym = NULL; static void *pPK11 = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if ((sym == NULL) || (hPK11 != pPK11)) { pPK11 = hPK11; sym = (CK_C_GenerateRandom)dlsym(hPK11, "C_GenerateRandom"); } if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, RandomData, ulRandomLen); } bind9-9.10.3.dfsg.P4/lib/isc/unix/resource.c0000644000470500017500000001401712664710322017676 0ustar lamontlamont/* * Copyright (C) 2004, 2007-2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: resource.c,v 1.23 2009/02/13 23:48:14 tbox Exp $ */ #include #include #include /* Required on some systems for . */ #include #include #include #include #include #ifdef __linux__ #include /* To get the large NR_OPEN. */ #endif #if defined(__hpux) && defined(HAVE_SYS_DYNTUNE_H) #include #endif #include "errno2result.h" static isc_result_t resource2rlim(isc_resource_t resource, int *rlim_resource) { isc_result_t result = ISC_R_SUCCESS; switch (resource) { case isc_resource_coresize: *rlim_resource = RLIMIT_CORE; break; case isc_resource_cputime: *rlim_resource = RLIMIT_CPU; break; case isc_resource_datasize: *rlim_resource = RLIMIT_DATA; break; case isc_resource_filesize: *rlim_resource = RLIMIT_FSIZE; break; case isc_resource_lockedmemory: #ifdef RLIMIT_MEMLOCK *rlim_resource = RLIMIT_MEMLOCK; #else result = ISC_R_NOTIMPLEMENTED; #endif break; case isc_resource_openfiles: #ifdef RLIMIT_NOFILE *rlim_resource = RLIMIT_NOFILE; #else result = ISC_R_NOTIMPLEMENTED; #endif break; case isc_resource_processes: #ifdef RLIMIT_NPROC *rlim_resource = RLIMIT_NPROC; #else result = ISC_R_NOTIMPLEMENTED; #endif break; case isc_resource_residentsize: #ifdef RLIMIT_RSS *rlim_resource = RLIMIT_RSS; #else result = ISC_R_NOTIMPLEMENTED; #endif break; case isc_resource_stacksize: *rlim_resource = RLIMIT_STACK; break; default: /* * This test is not very robust if isc_resource_t * changes, but generates a clear assertion message. */ REQUIRE(resource >= isc_resource_coresize && resource <= isc_resource_stacksize); result = ISC_R_RANGE; break; } return (result); } isc_result_t isc_resource_setlimit(isc_resource_t resource, isc_resourcevalue_t value) { struct rlimit rl; ISC_PLATFORM_RLIMITTYPE rlim_value; int unixresult; int unixresource; isc_result_t result; result = resource2rlim(resource, &unixresource); if (result != ISC_R_SUCCESS) return (result); if (value == ISC_RESOURCE_UNLIMITED) rlim_value = RLIM_INFINITY; else { /* * isc_resourcevalue_t was chosen as an unsigned 64 bit * integer so that it could contain the maximum range of * reasonable values. Unfortunately, this exceeds the typical * range on Unix systems. Ensure the range of * ISC_PLATFORM_RLIMITTYPE is not overflowed. */ isc_resourcevalue_t rlim_max; isc_boolean_t rlim_t_is_signed = ISC_TF(((double)(ISC_PLATFORM_RLIMITTYPE)-1) < 0); if (rlim_t_is_signed) rlim_max = ~((ISC_PLATFORM_RLIMITTYPE)1 << (sizeof(ISC_PLATFORM_RLIMITTYPE) * 8 - 1)); else rlim_max = (ISC_PLATFORM_RLIMITTYPE)-1; if (value > rlim_max) value = rlim_max; rlim_value = value; } rl.rlim_cur = rl.rlim_max = rlim_value; unixresult = setrlimit(unixresource, &rl); if (unixresult == 0) return (ISC_R_SUCCESS); #if defined(OPEN_MAX) && defined(__APPLE__) /* * The Darwin kernel doesn't accept RLIM_INFINITY for rlim_cur; the * maximum possible value is OPEN_MAX. BIND8 used to use * sysconf(_SC_OPEN_MAX) for such a case, but this value is much * smaller than OPEN_MAX and is not really effective. */ if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) { rl.rlim_cur = OPEN_MAX; unixresult = setrlimit(unixresource, &rl); if (unixresult == 0) return (ISC_R_SUCCESS); } #elif defined(__linux__) #ifndef NR_OPEN #define NR_OPEN (1024*1024) #endif /* * Some Linux kernels don't accept RLIM_INFINIT; the maximum * possible value is the NR_OPEN defined in linux/fs.h. */ if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) { rl.rlim_cur = rl.rlim_max = NR_OPEN; unixresult = setrlimit(unixresource, &rl); if (unixresult == 0) return (ISC_R_SUCCESS); } #elif defined(__hpux) && defined(HAVE_SYS_DYNTUNE_H) if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) { uint64_t maxfiles; if (gettune("maxfiles_lim", &maxfiles) == 0) { rl.rlim_cur = rl.rlim_max = maxfiles; unixresult = setrlimit(unixresource, &rl); if (unixresult == 0) return (ISC_R_SUCCESS); } } #endif if (resource == isc_resource_openfiles && rlim_value == RLIM_INFINITY) { if (getrlimit(unixresource, &rl) == 0) { rl.rlim_cur = rl.rlim_max; unixresult = setrlimit(unixresource, &rl); if (unixresult == 0) return (ISC_R_SUCCESS); } } return (isc__errno2result(errno)); } isc_result_t isc_resource_getlimit(isc_resource_t resource, isc_resourcevalue_t *value) { int unixresult; int unixresource; struct rlimit rl; isc_result_t result; result = resource2rlim(resource, &unixresource); if (result == ISC_R_SUCCESS) { unixresult = getrlimit(unixresource, &rl); INSIST(unixresult == 0); *value = rl.rlim_max; } return (result); } isc_result_t isc_resource_getcurlimit(isc_resource_t resource, isc_resourcevalue_t *value) { int unixresult; int unixresource; struct rlimit rl; isc_result_t result; result = resource2rlim(resource, &unixresource); if (result == ISC_R_SUCCESS) { unixresult = getrlimit(unixresource, &rl); INSIST(unixresult == 0); *value = rl.rlim_cur; } return (result); } bind9-9.10.3.dfsg.P4/lib/isc/unix/keyboard.c0000644000470500017500000000576112664710322017655 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: keyboard.c,v 1.13 2007/06/19 23:47:18 tbox Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include isc_result_t isc_keyboard_open(isc_keyboard_t *keyboard) { int fd; isc_result_t ret; struct termios current_mode; REQUIRE(keyboard != NULL); fd = open("/dev/tty", O_RDONLY, 0); if (fd < 0) return (ISC_R_IOERROR); keyboard->fd = fd; if (tcgetattr(fd, &keyboard->saved_mode) < 0) { ret = ISC_R_IOERROR; goto errout; } current_mode = keyboard->saved_mode; current_mode.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); current_mode.c_oflag &= ~OPOST; current_mode.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); current_mode.c_cflag &= ~(CSIZE|PARENB); current_mode.c_cflag |= CS8; current_mode.c_cc[VMIN] = 1; current_mode.c_cc[VTIME] = 0; if (tcsetattr(fd, TCSAFLUSH, ¤t_mode) < 0) { ret = ISC_R_IOERROR; goto errout; } keyboard->result = ISC_R_SUCCESS; return (ISC_R_SUCCESS); errout: close (fd); return (ret); } isc_result_t isc_keyboard_close(isc_keyboard_t *keyboard, unsigned int sleeptime) { REQUIRE(keyboard != NULL); if (sleeptime > 0 && keyboard->result != ISC_R_CANCELED) (void)sleep(sleeptime); (void)tcsetattr(keyboard->fd, TCSAFLUSH, &keyboard->saved_mode); (void)close(keyboard->fd); keyboard->fd = -1; return (ISC_R_SUCCESS); } isc_result_t isc_keyboard_getchar(isc_keyboard_t *keyboard, unsigned char *cp) { ssize_t cc; unsigned char c; cc_t *controlchars; REQUIRE(keyboard != NULL); REQUIRE(cp != NULL); cc = read(keyboard->fd, &c, 1); if (cc < 0) { keyboard->result = ISC_R_IOERROR; return (keyboard->result); } controlchars = keyboard->saved_mode.c_cc; if (c == controlchars[VINTR] || c == controlchars[VQUIT]) { keyboard->result = ISC_R_CANCELED; return (keyboard->result); } *cp = c; return (ISC_R_SUCCESS); } isc_boolean_t isc_keyboard_canceled(isc_keyboard_t *keyboard) { return (ISC_TF(keyboard->result == ISC_R_CANCELED)); } bind9-9.10.3.dfsg.P4/lib/isc/unix/stdio.c0000644000470500017500000000612312664710322017170 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2011-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #include #include #include #include #include #include #include "errno2result.h" isc_result_t isc_stdio_open(const char *filename, const char *mode, FILE **fp) { FILE *f; f = fopen(filename, mode); if (f == NULL) return (isc__errno2result(errno)); *fp = f; return (ISC_R_SUCCESS); } isc_result_t isc_stdio_close(FILE *f) { int r; r = fclose(f); if (r == 0) return (ISC_R_SUCCESS); else return (isc__errno2result(errno)); } isc_result_t isc_stdio_seek(FILE *f, off_t offset, int whence) { int r; #ifdef HAVE_FSEEKO r = fseeko(f, offset, whence); #else r = fseek(f, offset, whence); #endif if (r == 0) return (ISC_R_SUCCESS); else return (isc__errno2result(errno)); } isc_result_t isc_stdio_tell(FILE *f, off_t *offsetp) { off_t r; REQUIRE(offsetp != NULL); #ifdef HAVE_FTELLO r = ftello(f); #else r = ftell(f); #endif if (r >= 0) { *offsetp = r; return (ISC_R_SUCCESS); } else return (isc__errno2result(errno)); } isc_result_t isc_stdio_read(void *ptr, size_t size, size_t nmemb, FILE *f, size_t *nret) { isc_result_t result = ISC_R_SUCCESS; size_t r; clearerr(f); r = fread(ptr, size, nmemb, f); if (r != nmemb) { if (feof(f)) result = ISC_R_EOF; else result = isc__errno2result(errno); } if (nret != NULL) *nret = r; return (result); } isc_result_t isc_stdio_write(const void *ptr, size_t size, size_t nmemb, FILE *f, size_t *nret) { isc_result_t result = ISC_R_SUCCESS; size_t r; clearerr(f); r = fwrite(ptr, size, nmemb, f); if (r != nmemb) result = isc__errno2result(errno); if (nret != NULL) *nret = r; return (result); } isc_result_t isc_stdio_flush(FILE *f) { int r; r = fflush(f); if (r == 0) return (ISC_R_SUCCESS); else return (isc__errno2result(errno)); } /* * OpenBSD has deprecated ENOTSUP in favor of EOPNOTSUPP. */ #if defined(EOPNOTSUPP) && !defined(ENOTSUP) #define ENOTSUP EOPNOTSUPP #endif isc_result_t isc_stdio_sync(FILE *f) { int r; r = fsync(fileno(f)); /* * fsync is not supported on sockets and pipes which * result in EINVAL / ENOTSUP. */ if (r == 0 || errno == EINVAL || errno == ENOTSUP) return (ISC_R_SUCCESS); else return (isc__errno2result(errno)); } bind9-9.10.3.dfsg.P4/lib/isc/unix/app.c0000644000470500017500000006317612664710322016641 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007-2009, 2013-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include /* Openserver 5.0.6A and FD_SETSIZE */ #include #include #include #include #include #include #include #ifdef HAVE_EPOLL #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef ISC_PLATFORM_USETHREADS #include #endif /*% * For BIND9 internal applications built with threads, we use a single app * context and let multiple worker, I/O, timer threads do actual jobs. * For other cases (including BIND9 built without threads) an app context acts * as an event loop dispatching various events. */ #ifndef ISC_PLATFORM_USETHREADS #include "../timer_p.h" #include "../task_p.h" #include "socket_p.h" #endif /* ISC_PLATFORM_USETHREADS */ #ifdef ISC_PLATFORM_USETHREADS static pthread_t blockedthread; #endif /* ISC_PLATFORM_USETHREADS */ /*% * The following are intended for internal use (indicated by "isc__" * prefix) but are not declared as static, allowing direct access from * unit tests etc. */ isc_result_t isc__app_start(void); isc_result_t isc__app_ctxstart(isc_appctx_t *ctx); isc_result_t isc__app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action, void *arg); isc_result_t isc__app_ctxrun(isc_appctx_t *ctx); isc_result_t isc__app_run(void); isc_result_t isc__app_ctxshutdown(isc_appctx_t *ctx); isc_result_t isc__app_shutdown(void); isc_result_t isc__app_reload(void); isc_result_t isc__app_ctxsuspend(isc_appctx_t *ctx); void isc__app_ctxfinish(isc_appctx_t *ctx); void isc__app_finish(void); void isc__app_block(void); void isc__app_unblock(void); isc_result_t isc__appctx_create(isc_mem_t *mctx, isc_appctx_t **ctxp); void isc__appctx_destroy(isc_appctx_t **ctxp); void isc__appctx_settaskmgr(isc_appctx_t *ctx, isc_taskmgr_t *taskmgr); void isc__appctx_setsocketmgr(isc_appctx_t *ctx, isc_socketmgr_t *socketmgr); void isc__appctx_settimermgr(isc_appctx_t *ctx, isc_timermgr_t *timermgr); isc_result_t isc__app_ctxonrun(isc_appctx_t *ctx, isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action, void *arg); /* * The application context of this module. This implementation actually * doesn't use it. (This may change in the future). */ #define APPCTX_MAGIC ISC_MAGIC('A', 'p', 'c', 'x') #define VALID_APPCTX(c) ISC_MAGIC_VALID(c, APPCTX_MAGIC) typedef struct isc__appctx { isc_appctx_t common; isc_mem_t *mctx; isc_mutex_t lock; isc_eventlist_t on_run; isc_boolean_t shutdown_requested; isc_boolean_t running; /*! * We assume that 'want_shutdown' can be read and written atomically. */ isc_boolean_t want_shutdown; /* * We assume that 'want_reload' can be read and written atomically. */ isc_boolean_t want_reload; isc_boolean_t blocked; isc_taskmgr_t *taskmgr; isc_socketmgr_t *socketmgr; isc_timermgr_t *timermgr; #ifdef ISC_PLATFORM_USETHREADS isc_mutex_t readylock; isc_condition_t ready; #endif /* ISC_PLATFORM_USETHREADS */ } isc__appctx_t; static isc__appctx_t isc_g_appctx; static struct { isc_appmethods_t methods; /*% * The following are defined just for avoiding unused static functions. */ void *run, *shutdown, *start, *reload, *finish, *block, *unblock; } appmethods = { { isc__appctx_destroy, isc__app_ctxstart, isc__app_ctxrun, isc__app_ctxsuspend, isc__app_ctxshutdown, isc__app_ctxfinish, isc__appctx_settaskmgr, isc__appctx_setsocketmgr, isc__appctx_settimermgr, isc__app_ctxonrun }, (void *)isc__app_run, (void *)isc__app_shutdown, (void *)isc__app_start, (void *)isc__app_reload, (void *)isc__app_finish, (void *)isc__app_block, (void *)isc__app_unblock }; #ifdef HAVE_LINUXTHREADS /*! * Linux has sigwait(), but it appears to prevent signal handlers from * running, even if they're not in the set being waited for. This makes * it impossible to get the default actions for SIGILL, SIGSEGV, etc. * Instead of messing with it, we just use sigsuspend() instead. */ #undef HAVE_SIGWAIT /*! * We need to remember which thread is the main thread... */ static pthread_t main_thread; #endif #ifndef HAVE_SIGWAIT static void exit_action(int arg) { UNUSED(arg); isc_g_appctx.want_shutdown = ISC_TRUE; } static void reload_action(int arg) { UNUSED(arg); isc_g_appctx.want_reload = ISC_TRUE; } #endif static isc_result_t handle_signal(int sig, void (*handler)(int)) { struct sigaction sa; char strbuf[ISC_STRERRORSIZE]; memset(&sa, 0, sizeof(sa)); sa.sa_handler = handler; if (sigfillset(&sa.sa_mask) != 0 || sigaction(sig, &sa, NULL) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_APP, ISC_MSG_SIGNALSETUP, "handle_signal() %d setup: %s"), sig, strbuf); return (ISC_R_UNEXPECTED); } return (ISC_R_SUCCESS); } isc_result_t isc__app_ctxstart(isc_appctx_t *ctx0) { isc__appctx_t *ctx = (isc__appctx_t *)ctx0; isc_result_t result; int presult; sigset_t sset; char strbuf[ISC_STRERRORSIZE]; REQUIRE(VALID_APPCTX(ctx)); /* * Start an ISC library application. */ #ifdef NEED_PTHREAD_INIT /* * BSDI 3.1 seg faults in pthread_sigmask() if we don't do this. */ presult = pthread_init(); if (presult != 0) { isc__strerror(presult, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_app_start() pthread_init: %s", strbuf); return (ISC_R_UNEXPECTED); } #endif #ifdef ISC_PLATFORM_USETHREADS #ifdef HAVE_LINUXTHREADS main_thread = pthread_self(); #endif /* HAVE_LINUXTHREADS */ result = isc_mutex_init(&ctx->readylock); if (result != ISC_R_SUCCESS) return (result); result = isc_condition_init(&ctx->ready); if (result != ISC_R_SUCCESS) goto cleanup_rlock; result = isc_mutex_init(&ctx->lock); if (result != ISC_R_SUCCESS) goto cleanup_rcond; #else /* ISC_PLATFORM_USETHREADS */ result = isc_mutex_init(&ctx->lock); if (result != ISC_R_SUCCESS) goto cleanup; #endif /* ISC_PLATFORM_USETHREADS */ ISC_LIST_INIT(ctx->on_run); ctx->shutdown_requested = ISC_FALSE; ctx->running = ISC_FALSE; ctx->want_shutdown = ISC_FALSE; ctx->want_reload = ISC_FALSE; ctx->blocked = ISC_FALSE; #ifndef HAVE_SIGWAIT /* * Install do-nothing handlers for SIGINT and SIGTERM. * * We install them now because BSDI 3.1 won't block * the default actions, regardless of what we do with * pthread_sigmask(). */ result = handle_signal(SIGINT, exit_action); if (result != ISC_R_SUCCESS) goto cleanup; result = handle_signal(SIGTERM, exit_action); if (result != ISC_R_SUCCESS) goto cleanup; #endif /* * Always ignore SIGPIPE. */ result = handle_signal(SIGPIPE, SIG_IGN); if (result != ISC_R_SUCCESS) goto cleanup; /* * On Solaris 2, delivery of a signal whose action is SIG_IGN * will not cause sigwait() to return. We may have inherited * unexpected actions for SIGHUP, SIGINT, and SIGTERM from our parent * process (e.g, Solaris cron). Set an action of SIG_DFL to make * sure sigwait() works as expected. Only do this for SIGTERM and * SIGINT if we don't have sigwait(), since a different handler is * installed above. */ result = handle_signal(SIGHUP, SIG_DFL); if (result != ISC_R_SUCCESS) goto cleanup; #ifdef HAVE_SIGWAIT result = handle_signal(SIGTERM, SIG_DFL); if (result != ISC_R_SUCCESS) goto cleanup; result = handle_signal(SIGINT, SIG_DFL); if (result != ISC_R_SUCCESS) goto cleanup; #endif #ifdef ISC_PLATFORM_USETHREADS /* * Block SIGHUP, SIGINT, SIGTERM. * * If isc_app_start() is called from the main thread before any other * threads have been created, then the pthread_sigmask() call below * will result in all threads having SIGHUP, SIGINT and SIGTERM * blocked by default, ensuring that only the thread that calls * sigwait() for them will get those signals. */ if (sigemptyset(&sset) != 0 || sigaddset(&sset, SIGHUP) != 0 || sigaddset(&sset, SIGINT) != 0 || sigaddset(&sset, SIGTERM) != 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_app_start() sigsetops: %s", strbuf); result = ISC_R_UNEXPECTED; goto cleanup; } presult = pthread_sigmask(SIG_BLOCK, &sset, NULL); if (presult != 0) { isc__strerror(presult, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_app_start() pthread_sigmask: %s", strbuf); result = ISC_R_UNEXPECTED; goto cleanup; } #else /* ISC_PLATFORM_USETHREADS */ /* * Unblock SIGHUP, SIGINT, SIGTERM. * * If we're not using threads, we need to make sure that SIGHUP, * SIGINT and SIGTERM are not inherited as blocked from the parent * process. */ if (sigemptyset(&sset) != 0 || sigaddset(&sset, SIGHUP) != 0 || sigaddset(&sset, SIGINT) != 0 || sigaddset(&sset, SIGTERM) != 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_app_start() sigsetops: %s", strbuf); result = ISC_R_UNEXPECTED; goto cleanup; } presult = sigprocmask(SIG_UNBLOCK, &sset, NULL); if (presult != 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_app_start() sigprocmask: %s", strbuf); result = ISC_R_UNEXPECTED; goto cleanup; } #endif /* ISC_PLATFORM_USETHREADS */ return (ISC_R_SUCCESS); cleanup: #ifdef ISC_PLATFORM_USETHREADS cleanup_rcond: (void)isc_condition_destroy(&ctx->ready); cleanup_rlock: (void)isc_mutex_destroy(&ctx->readylock); #endif /* ISC_PLATFORM_USETHREADS */ return (result); } isc_result_t isc__app_start(void) { isc_g_appctx.common.impmagic = APPCTX_MAGIC; isc_g_appctx.common.magic = ISCAPI_APPCTX_MAGIC; isc_g_appctx.common.methods = &appmethods.methods; isc_g_appctx.mctx = NULL; /* The remaining members will be initialized in ctxstart() */ return (isc__app_ctxstart((isc_appctx_t *)&isc_g_appctx)); } isc_result_t isc__app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action, void *arg) { return (isc__app_ctxonrun((isc_appctx_t *)&isc_g_appctx, mctx, task, action, arg)); } isc_result_t isc__app_ctxonrun(isc_appctx_t *ctx0, isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action, void *arg) { isc__appctx_t *ctx = (isc__appctx_t *)ctx0; isc_event_t *event; isc_task_t *cloned_task = NULL; isc_result_t result; LOCK(&ctx->lock); if (ctx->running) { result = ISC_R_ALREADYRUNNING; goto unlock; } /* * Note that we store the task to which we're going to send the event * in the event's "sender" field. */ isc_task_attach(task, &cloned_task); event = isc_event_allocate(mctx, cloned_task, ISC_APPEVENT_SHUTDOWN, action, arg, sizeof(*event)); if (event == NULL) { result = ISC_R_NOMEMORY; goto unlock; } ISC_LIST_APPEND(ctx->on_run, event, ev_link); result = ISC_R_SUCCESS; unlock: UNLOCK(&ctx->lock); return (result); } #ifndef ISC_PLATFORM_USETHREADS /*! * Event loop for nonthreaded programs. */ static isc_result_t evloop(isc__appctx_t *ctx) { isc_result_t result; while (!ctx->want_shutdown) { int n; isc_time_t when, now; struct timeval tv, *tvp; isc_socketwait_t *swait; isc_boolean_t readytasks; isc_boolean_t call_timer_dispatch = ISC_FALSE; /* * Check the reload (or suspend) case first for exiting the * loop as fast as possible in case: * - the direct call to isc__taskmgr_dispatch() in * isc__app_ctxrun() completes all the tasks so far, * - there is thus currently no active task, and * - there is a timer event */ if (ctx->want_reload) { ctx->want_reload = ISC_FALSE; return (ISC_R_RELOAD); } readytasks = isc__taskmgr_ready(ctx->taskmgr); if (readytasks) { tv.tv_sec = 0; tv.tv_usec = 0; tvp = &tv; call_timer_dispatch = ISC_TRUE; } else { result = isc__timermgr_nextevent(ctx->timermgr, &when); if (result != ISC_R_SUCCESS) tvp = NULL; else { isc_uint64_t us; TIME_NOW(&now); us = isc_time_microdiff(&when, &now); if (us == 0) call_timer_dispatch = ISC_TRUE; tv.tv_sec = us / 1000000; tv.tv_usec = us % 1000000; tvp = &tv; } } swait = NULL; n = isc__socketmgr_waitevents(ctx->socketmgr, tvp, &swait); if (n == 0 || call_timer_dispatch) { /* * We call isc__timermgr_dispatch() only when * necessary, in order to reduce overhead. If the * select() call indicates a timeout, we need the * dispatch. Even if not, if we set the 0-timeout * for the select() call, we need to check the timer * events. In the 'readytasks' case, there may be no * timeout event actually, but there is no other way * to reduce the overhead. * Note that we do not have to worry about the case * where a new timer is inserted during the select() * call, since this loop only runs in the non-thread * mode. */ isc__timermgr_dispatch(ctx->timermgr); } if (n > 0) (void)isc__socketmgr_dispatch(ctx->socketmgr, swait); (void)isc__taskmgr_dispatch(ctx->taskmgr); } return (ISC_R_SUCCESS); } /* * This is a gross hack to support waiting for condition * variables in nonthreaded programs in a limited way; * see lib/isc/nothreads/include/isc/condition.h. * We implement isc_condition_wait() by entering the * event loop recursively until the want_shutdown flag * is set by isc_condition_signal(). */ /*! * \brief True if we are currently executing in the recursive * event loop. */ static isc_boolean_t in_recursive_evloop = ISC_FALSE; /*! * \brief True if we are exiting the event loop as the result of * a call to isc_condition_signal() rather than a shutdown * or reload. */ static isc_boolean_t signalled = ISC_FALSE; isc_result_t isc__nothread_wait_hack(isc_condition_t *cp, isc_mutex_t *mp) { isc_result_t result; UNUSED(cp); UNUSED(mp); INSIST(!in_recursive_evloop); in_recursive_evloop = ISC_TRUE; INSIST(*mp == 1); /* Mutex must be locked on entry. */ --*mp; result = evloop(&isc_g_appctx); if (result == ISC_R_RELOAD) isc_g_appctx.want_reload = ISC_TRUE; if (signalled) { isc_g_appctx.want_shutdown = ISC_FALSE; signalled = ISC_FALSE; } ++*mp; in_recursive_evloop = ISC_FALSE; return (ISC_R_SUCCESS); } isc_result_t isc__nothread_signal_hack(isc_condition_t *cp) { UNUSED(cp); INSIST(in_recursive_evloop); isc_g_appctx.want_shutdown = ISC_TRUE; signalled = ISC_TRUE; return (ISC_R_SUCCESS); } #endif /* ISC_PLATFORM_USETHREADS */ isc_result_t isc__app_ctxrun(isc_appctx_t *ctx0) { isc__appctx_t *ctx = (isc__appctx_t *)ctx0; int result; isc_event_t *event, *next_event; isc_task_t *task; #ifdef ISC_PLATFORM_USETHREADS sigset_t sset; char strbuf[ISC_STRERRORSIZE]; #ifdef HAVE_SIGWAIT int sig; #endif /* HAVE_SIGWAIT */ #endif /* ISC_PLATFORM_USETHREADS */ REQUIRE(VALID_APPCTX(ctx)); #ifdef HAVE_LINUXTHREADS REQUIRE(main_thread == pthread_self()); #endif LOCK(&ctx->lock); if (!ctx->running) { ctx->running = ISC_TRUE; /* * Post any on-run events (in FIFO order). */ for (event = ISC_LIST_HEAD(ctx->on_run); event != NULL; event = next_event) { next_event = ISC_LIST_NEXT(event, ev_link); ISC_LIST_UNLINK(ctx->on_run, event, ev_link); task = event->ev_sender; event->ev_sender = NULL; isc_task_sendanddetach(&task, &event); } } UNLOCK(&ctx->lock); #ifndef ISC_PLATFORM_USETHREADS if (isc_bind9 && ctx == &isc_g_appctx) { result = handle_signal(SIGHUP, reload_action); if (result != ISC_R_SUCCESS) return (ISC_R_SUCCESS); } (void) isc__taskmgr_dispatch(ctx->taskmgr); result = evloop(ctx); return (result); #else /* ISC_PLATFORM_USETHREADS */ /* * BIND9 internal tools using multiple contexts do not * rely on signal. */ if (isc_bind9 && ctx != &isc_g_appctx) return (ISC_R_SUCCESS); /* * There is no danger if isc_app_shutdown() is called before we * wait for signals. Signals are blocked, so any such signal will * simply be made pending and we will get it when we call * sigwait(). */ while (!ctx->want_shutdown) { #ifdef HAVE_SIGWAIT if (isc_bind9) { /* * BIND9 internal; single context: * Wait for SIGHUP, SIGINT, or SIGTERM. */ if (sigemptyset(&sset) != 0 || sigaddset(&sset, SIGHUP) != 0 || sigaddset(&sset, SIGINT) != 0 || sigaddset(&sset, SIGTERM) != 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_app_run() sigsetops: %s", strbuf); return (ISC_R_UNEXPECTED); } #ifndef HAVE_UNIXWARE_SIGWAIT result = sigwait(&sset, &sig); if (result == 0) { if (sig == SIGINT || sig == SIGTERM) ctx->want_shutdown = ISC_TRUE; else if (sig == SIGHUP) ctx->want_reload = ISC_TRUE; } #else /* Using UnixWare sigwait semantics. */ sig = sigwait(&sset); if (sig >= 0) { if (sig == SIGINT || sig == SIGTERM) ctx->want_shutdown = ISC_TRUE; else if (sig == SIGHUP) ctx->want_reload = ISC_TRUE; } #endif /* HAVE_UNIXWARE_SIGWAIT */ } else { /* * External, or BIND9 using multiple contexts: * wait until woken up. */ LOCK(&ctx->readylock); if (ctx->want_shutdown) { /* shutdown() won the race. */ UNLOCK(&ctx->readylock); break; } if (!ctx->want_reload) WAIT(&ctx->ready, &ctx->readylock); UNLOCK(&ctx->readylock); } #else /* Don't have sigwait(). */ if (isc_bind9) { /* * BIND9 internal; single context: * Install a signal handler for SIGHUP, then wait for * all signals. */ result = handle_signal(SIGHUP, reload_action); if (result != ISC_R_SUCCESS) return (ISC_R_SUCCESS); if (sigemptyset(&sset) != 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_app_run() sigsetops: %s", strbuf); return (ISC_R_UNEXPECTED); } #ifdef HAVE_GPERFTOOLS_PROFILER if (sigaddset(&sset, SIGALRM) != 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_app_run() sigsetops: %s", strbuf); return (ISC_R_UNEXPECTED); } #endif (void)sigsuspend(&sset); } else { /* * External, or BIND9 using multiple contexts: * wait until woken up. */ LOCK(&ctx->readylock); if (ctx->want_shutdown) { /* shutdown() won the race. */ UNLOCK(&ctx->readylock); break; } if (!ctx->want_reload) WAIT(&ctx->ready, &ctx->readylock); UNLOCK(&ctx->readylock); } #endif /* HAVE_SIGWAIT */ if (ctx->want_reload) { ctx->want_reload = ISC_FALSE; return (ISC_R_RELOAD); } if (ctx->want_shutdown && ctx->blocked) exit(1); } return (ISC_R_SUCCESS); #endif /* ISC_PLATFORM_USETHREADS */ } isc_result_t isc__app_run(void) { return (isc__app_ctxrun((isc_appctx_t *)&isc_g_appctx)); } isc_result_t isc__app_ctxshutdown(isc_appctx_t *ctx0) { isc__appctx_t *ctx = (isc__appctx_t *)ctx0; isc_boolean_t want_kill = ISC_TRUE; #ifdef ISC_PLATFORM_USETHREADS char strbuf[ISC_STRERRORSIZE]; #endif /* ISC_PLATFORM_USETHREADS */ REQUIRE(VALID_APPCTX(ctx)); LOCK(&ctx->lock); REQUIRE(ctx->running); if (ctx->shutdown_requested) want_kill = ISC_FALSE; else ctx->shutdown_requested = ISC_TRUE; UNLOCK(&ctx->lock); if (want_kill) { if (isc_bind9 && ctx != &isc_g_appctx) /* BIND9 internal, but using multiple contexts */ ctx->want_shutdown = ISC_TRUE; else { #ifndef ISC_PLATFORM_USETHREADS ctx->want_shutdown = ISC_TRUE; #else /* ISC_PLATFORM_USETHREADS */ #ifdef HAVE_LINUXTHREADS if (isc_bind9) { /* BIND9 internal, single context */ int result; result = pthread_kill(main_thread, SIGTERM); if (result != 0) { isc__strerror(result, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_app_shutdown() " "pthread_kill: %s", strbuf); return (ISC_R_UNEXPECTED); } } #else if (isc_bind9) { /* BIND9 internal, single context */ if (kill(getpid(), SIGTERM) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_app_shutdown() " "kill: %s", strbuf); return (ISC_R_UNEXPECTED); } } #endif /* HAVE_LINUXTHREADS */ else { /* External, multiple contexts */ LOCK(&ctx->readylock); ctx->want_shutdown = ISC_TRUE; UNLOCK(&ctx->readylock); SIGNAL(&ctx->ready); } #endif /* ISC_PLATFORM_USETHREADS */ } } return (ISC_R_SUCCESS); } isc_result_t isc__app_shutdown(void) { return (isc__app_ctxshutdown((isc_appctx_t *)&isc_g_appctx)); } isc_result_t isc__app_ctxsuspend(isc_appctx_t *ctx0) { isc__appctx_t *ctx = (isc__appctx_t *)ctx0; isc_boolean_t want_kill = ISC_TRUE; #ifdef ISC_PLATFORM_USETHREADS char strbuf[ISC_STRERRORSIZE]; #endif REQUIRE(VALID_APPCTX(ctx)); LOCK(&ctx->lock); REQUIRE(ctx->running); /* * Don't send the reload signal if we're shutting down. */ if (ctx->shutdown_requested) want_kill = ISC_FALSE; UNLOCK(&ctx->lock); if (want_kill) { if (isc_bind9 && ctx != &isc_g_appctx) /* BIND9 internal, but using multiple contexts */ ctx->want_reload = ISC_TRUE; else { #ifndef ISC_PLATFORM_USETHREADS ctx->want_reload = ISC_TRUE; #else /* ISC_PLATFORM_USETHREADS */ #ifdef HAVE_LINUXTHREADS if (isc_bind9) { /* BIND9 internal, single context */ int result; result = pthread_kill(main_thread, SIGHUP); if (result != 0) { isc__strerror(result, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_app_reload() " "pthread_kill: %s", strbuf); return (ISC_R_UNEXPECTED); } } #else if (isc_bind9) { /* BIND9 internal, single context */ if (kill(getpid(), SIGHUP) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_app_reload() " "kill: %s", strbuf); return (ISC_R_UNEXPECTED); } } #endif /* HAVE_LINUXTHREADS */ else { /* External, multiple contexts */ LOCK(&ctx->readylock); ctx->want_reload = ISC_TRUE; UNLOCK(&ctx->readylock); SIGNAL(&ctx->ready); } #endif /* ISC_PLATFORM_USETHREADS */ } } return (ISC_R_SUCCESS); } isc_result_t isc__app_reload(void) { return (isc__app_ctxsuspend((isc_appctx_t *)&isc_g_appctx)); } void isc__app_ctxfinish(isc_appctx_t *ctx0) { isc__appctx_t *ctx = (isc__appctx_t *)ctx0; REQUIRE(VALID_APPCTX(ctx)); DESTROYLOCK(&ctx->lock); } void isc__app_finish(void) { isc__app_ctxfinish((isc_appctx_t *)&isc_g_appctx); } void isc__app_block(void) { #ifdef ISC_PLATFORM_USETHREADS sigset_t sset; #endif /* ISC_PLATFORM_USETHREADS */ REQUIRE(isc_g_appctx.running); REQUIRE(!isc_g_appctx.blocked); isc_g_appctx.blocked = ISC_TRUE; #ifdef ISC_PLATFORM_USETHREADS blockedthread = pthread_self(); RUNTIME_CHECK(sigemptyset(&sset) == 0 && sigaddset(&sset, SIGINT) == 0 && sigaddset(&sset, SIGTERM) == 0); RUNTIME_CHECK(pthread_sigmask(SIG_UNBLOCK, &sset, NULL) == 0); #endif /* ISC_PLATFORM_USETHREADS */ } void isc__app_unblock(void) { #ifdef ISC_PLATFORM_USETHREADS sigset_t sset; #endif /* ISC_PLATFORM_USETHREADS */ REQUIRE(isc_g_appctx.running); REQUIRE(isc_g_appctx.blocked); isc_g_appctx.blocked = ISC_FALSE; #ifdef ISC_PLATFORM_USETHREADS REQUIRE(blockedthread == pthread_self()); RUNTIME_CHECK(sigemptyset(&sset) == 0 && sigaddset(&sset, SIGINT) == 0 && sigaddset(&sset, SIGTERM) == 0); RUNTIME_CHECK(pthread_sigmask(SIG_BLOCK, &sset, NULL) == 0); #endif /* ISC_PLATFORM_USETHREADS */ } isc_result_t isc__appctx_create(isc_mem_t *mctx, isc_appctx_t **ctxp) { isc__appctx_t *ctx; REQUIRE(mctx != NULL); REQUIRE(ctxp != NULL && *ctxp == NULL); ctx = isc_mem_get(mctx, sizeof(*ctx)); if (ctx == NULL) return (ISC_R_NOMEMORY); ctx->common.impmagic = APPCTX_MAGIC; ctx->common.magic = ISCAPI_APPCTX_MAGIC; ctx->common.methods = &appmethods.methods; ctx->mctx = NULL; isc_mem_attach(mctx, &ctx->mctx); ctx->taskmgr = NULL; ctx->socketmgr = NULL; ctx->timermgr = NULL; *ctxp = (isc_appctx_t *)ctx; return (ISC_R_SUCCESS); } void isc__appctx_destroy(isc_appctx_t **ctxp) { isc__appctx_t *ctx; REQUIRE(ctxp != NULL); ctx = (isc__appctx_t *)*ctxp; REQUIRE(VALID_APPCTX(ctx)); isc_mem_putanddetach(&ctx->mctx, ctx, sizeof(*ctx)); *ctxp = NULL; } void isc__appctx_settaskmgr(isc_appctx_t *ctx0, isc_taskmgr_t *taskmgr) { isc__appctx_t *ctx = (isc__appctx_t *)ctx0; REQUIRE(VALID_APPCTX(ctx)); ctx->taskmgr = taskmgr; } void isc__appctx_setsocketmgr(isc_appctx_t *ctx0, isc_socketmgr_t *socketmgr) { isc__appctx_t *ctx = (isc__appctx_t *)ctx0; REQUIRE(VALID_APPCTX(ctx)); ctx->socketmgr = socketmgr; } void isc__appctx_settimermgr(isc_appctx_t *ctx0, isc_timermgr_t *timermgr) { isc__appctx_t *ctx = (isc__appctx_t *)ctx0; REQUIRE(VALID_APPCTX(ctx)); ctx->timermgr = timermgr; } isc_result_t isc__app_register(void) { return (isc_app_register(isc__appctx_create)); } #include "../app_api.c" bind9-9.10.3.dfsg.P4/lib/isc/unix/include/0002755000470500017500000000000012672612753017335 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/unix/include/Makefile.in0000644000470500017500000000177312664710322021400 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.14 2007/06/19 23:47:18 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = isc pkcs11 TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/unix/include/pkcs11/0002755000470500017500000000000012664710322020427 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/unix/include/pkcs11/cryptoki.h0000644000470500017500000000441512664710322022446 0ustar lamontlamont/* cryptoki.h include file for PKCS #11. */ /* * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Revision: 1.3 $ */ /* * Portions Copyright RSA Security Inc. * * License to copy and use this software is granted provided that it is * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface * (Cryptoki)" in all material mentioning or referencing this software. * License is also granted to make and use derivative works provided that * such works are identified as "derived from the RSA Security Inc. PKCS #11 * Cryptographic Token Interface (Cryptoki)" in all material mentioning or * referencing the derived work. * RSA Security Inc. makes no representations concerning either the * merchantability of this software or the suitability of this software for * any particular purpose. It is provided "as is" without express or implied * warranty of any kind. */ /* This is a sample file containing the top level include directives * for building Unix Cryptoki libraries and applications. */ #ifndef ___CRYPTOKI_H_INC___ #define ___CRYPTOKI_H_INC___ #define CK_PTR * #define CK_DEFINE_FUNCTION(returnType, name) \ returnType name #define CK_DECLARE_FUNCTION(returnType, name) \ returnType name #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ returnType (* name) #define CK_CALLBACK_FUNCTION(returnType, name) \ returnType (* name) /* NULL is in unistd.h */ #include #define NULL_PTR NULL #undef CK_PKCS11_FUNCTION_INFO #include #endif /* ___CRYPTOKI_H_INC___ */ bind9-9.10.3.dfsg.P4/lib/isc/unix/include/pkcs11/Makefile.in0000644000470500017500000000220712664710322022473 0ustar lamontlamont# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.4 2007/06/19 23:47:23 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ HEADERS = cryptoki.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/pkcs11 install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/pkcs11 ; \ done bind9-9.10.3.dfsg.P4/lib/isc/unix/include/isc/0002755000470500017500000000000012672612753020113 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/unix/include/isc/int.h0000644000470500017500000000352112664710322021045 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: int.h,v 1.16 2007/06/19 23:47:19 tbox Exp $ */ #ifndef ISC_INT_H #define ISC_INT_H 1 /*! \file */ typedef char isc_int8_t; typedef unsigned char isc_uint8_t; typedef short isc_int16_t; typedef unsigned short isc_uint16_t; typedef int isc_int32_t; typedef unsigned int isc_uint32_t; typedef long long isc_int64_t; typedef unsigned long long isc_uint64_t; #define ISC_INT8_MIN -128 #define ISC_INT8_MAX 127 #define ISC_UINT8_MAX 255 #define ISC_INT16_MIN -32768 #define ISC_INT16_MAX 32767 #define ISC_UINT16_MAX 65535 /*% * Note that "int" is 32 bits on all currently supported Unix-like operating * systems, but "long" can be either 32 bits or 64 bits, thus the 32 bit * constants are not qualified with "L". */ #define ISC_INT32_MIN -2147483648 #define ISC_INT32_MAX 2147483647 #define ISC_UINT32_MAX 4294967295U #define ISC_INT64_MIN -9223372036854775808LL #define ISC_INT64_MAX 9223372036854775807LL #define ISC_UINT64_MAX 18446744073709551615ULL #endif /* ISC_INT_H */ bind9-9.10.3.dfsg.P4/lib/isc/unix/include/isc/Makefile.in0000644000470500017500000000246112664710322022151 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012-2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.30 2007/06/19 23:47:19 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ HEADERS = dir.h int.h keyboard.h net.h netdb.h offset.h stat.h \ stdtime.h strerror.h syslog.h time.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \ done bind9-9.10.3.dfsg.P4/lib/isc/unix/include/isc/dir.h0000644000470500017500000000501112664710322021025 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: dir.h,v 1.21 2007/06/19 23:47:19 tbox Exp $ */ /* Principal Authors: DCL */ #ifndef ISC_DIR_H #define ISC_DIR_H 1 /*! \file */ #include /* Required on some systems. */ #include #include #include #define ISC_DIR_NAMEMAX 256 #define ISC_DIR_PATHMAX 1024 /*% Directory Entry */ typedef struct isc_direntry { /*! * Ideally, this should be NAME_MAX, but AIX does not define it by * default and dynamically allocating the space based on pathconf() * complicates things undesirably, as does adding special conditionals * just for AIX. So a comfortably sized buffer is chosen instead. */ char name[ISC_DIR_NAMEMAX]; unsigned int length; } isc_direntry_t; /*% Directory */ typedef struct isc_dir { unsigned int magic; /*! * As with isc_direntry_t->name, making this "right" for all systems * is slightly problematic because AIX does not define PATH_MAX. */ char dirname[ISC_DIR_PATHMAX]; isc_direntry_t entry; DIR * handle; } isc_dir_t; ISC_LANG_BEGINDECLS void isc_dir_init(isc_dir_t *dir); isc_result_t isc_dir_open(isc_dir_t *dir, const char *dirname); isc_result_t isc_dir_read(isc_dir_t *dir); isc_result_t isc_dir_reset(isc_dir_t *dir); void isc_dir_close(isc_dir_t *dir); isc_result_t isc_dir_chdir(const char *dirname); isc_result_t isc_dir_chroot(const char *dirname); isc_result_t isc_dir_createunique(char *templet); /*!< * Use a templet (such as from isc_file_mktemplate()) to create a uniquely * named, empty directory. The templet string is modified in place. * If result == ISC_R_SUCCESS, it is the name of the directory that was * created. */ ISC_LANG_ENDDECLS #endif /* ISC_DIR_H */ bind9-9.10.3.dfsg.P4/lib/isc/unix/include/isc/offset.h0000644000470500017500000000355212664710322021545 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: offset.h,v 1.17 2008/12/01 23:47:45 tbox Exp $ */ #ifndef ISC_OFFSET_H #define ISC_OFFSET_H 1 /*! \file * \brief * File offsets are operating-system dependent. */ #include /* Required for CHAR_BIT. */ #include #include /* For Linux Standard Base. */ typedef off_t isc_offset_t; /*% * POSIX says "Additionally, blkcnt_t and off_t are extended signed integral * types", so the maximum value is all 1s except for the high bit. * This definition is more complex than it really needs to be because it was * crafted to keep both the SunOS 5.6 and the HP/UX 11 compilers quiet about * integer overflow. For example, though this is equivalent to just left * shifting 1 to the high bit and then inverting the bits, the SunOS compiler * is unhappy about shifting a positive "1" to negative in a signed integer. */ #define ISC_OFFSET_MAXIMUM \ (~(((off_t)-1 >> (sizeof(off_t) * CHAR_BIT - 1)) \ << (sizeof(off_t) * CHAR_BIT - 1))) #endif /* ISC_OFFSET_H */ bind9-9.10.3.dfsg.P4/lib/isc/unix/include/isc/syslog.h0000644000470500017500000000253512664710322021577 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: syslog.h,v 1.7 2007/06/19 23:47:19 tbox Exp $ */ #ifndef ISC_SYSLOG_H #define ISC_SYSLOG_H 1 /*! \file */ #include #include ISC_LANG_BEGINDECLS isc_result_t isc_syslog_facilityfromstring(const char *str, int *facilityp); /*%< * Convert 'str' to the appropriate syslog facility constant. * * Requires: * *\li 'str' is not NULL *\li 'facilityp' is not NULL * * Returns: * \li #ISC_R_SUCCESS * \li #ISC_R_NOTFOUND */ ISC_LANG_ENDDECLS #endif /* ISC_SYSLOG_H */ bind9-9.10.3.dfsg.P4/lib/isc/unix/include/isc/net.h0000644000470500017500000002470712664710322021052 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2008, 2012-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef ISC_NET_H #define ISC_NET_H 1 /***** ***** Module Info *****/ /*! \file * \brief * Basic Networking Types * * This module is responsible for defining the following basic networking * types: * *\li struct in_addr *\li struct in6_addr *\li struct in6_pktinfo *\li struct sockaddr *\li struct sockaddr_in *\li struct sockaddr_in6 *\li struct sockaddr_storage *\li in_port_t * * It ensures that the AF_ and PF_ macros are defined. * * It declares ntoh[sl]() and hton[sl](). * * It declares inet_aton(), inet_ntop(), and inet_pton(). * * It ensures that #INADDR_LOOPBACK, #INADDR_ANY, #IN6ADDR_ANY_INIT, * in6addr_any, and in6addr_loopback are available. * * It ensures that IN_MULTICAST() is available to check for multicast * addresses. * * MP: *\li No impact. * * Reliability: *\li No anticipated impact. * * Resources: *\li N/A. * * Security: *\li No anticipated impact. * * Standards: *\li BSD Socket API *\li RFC2553 */ /*** *** Imports. ***/ #include #include #include /* Contractual promise. */ #include #include /* Contractual promise. */ #include /* Contractual promise. */ #ifdef ISC_PLATFORM_NEEDNETINETIN6H #include /* Required on UnixWare. */ #endif #ifdef ISC_PLATFORM_NEEDNETINET6IN6H #include /* Required on BSD/OS for in6_pktinfo. */ #endif #ifndef ISC_PLATFORM_HAVEIPV6 #include /* Contractual promise. */ #endif #include #include #ifdef ISC_PLATFORM_HAVEINADDR6 #define in6_addr in_addr6 /*%< Required for pre RFC2133 implementations. */ #endif #ifdef ISC_PLATFORM_HAVEIPV6 #ifndef IN6ADDR_ANY_INIT #ifdef s6_addr /*% * Required for some pre RFC2133 implementations. * IN6ADDR_ANY_INIT and IN6ADDR_LOOPBACK_INIT were added in * draft-ietf-ipngwg-bsd-api-04.txt or draft-ietf-ipngwg-bsd-api-05.txt. * If 's6_addr' is defined then assume that there is a union and three * levels otherwise assume two levels required. */ #define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } } #else #define IN6ADDR_ANY_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } #endif #endif #ifndef IN6ADDR_LOOPBACK_INIT #ifdef s6_addr /*% IPv6 address loopback init */ #define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } } #else #define IN6ADDR_LOOPBACK_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } #endif #endif #ifndef IN6_IS_ADDR_V4MAPPED /*% Is IPv6 address V4 mapped? */ #define IN6_IS_ADDR_V4MAPPED(x) \ (memcmp((x)->s6_addr, in6addr_any.s6_addr, 10) == 0 && \ (x)->s6_addr[10] == 0xff && (x)->s6_addr[11] == 0xff) #endif #ifndef IN6_IS_ADDR_V4COMPAT /*% Is IPv6 address V4 compatible? */ #define IN6_IS_ADDR_V4COMPAT(x) \ (memcmp((x)->s6_addr, in6addr_any.s6_addr, 12) == 0 && \ ((x)->s6_addr[12] != 0 || (x)->s6_addr[13] != 0 || \ (x)->s6_addr[14] != 0 || \ ((x)->s6_addr[15] != 0 && (x)->s6_addr[15] != 1))) #endif #ifndef IN6_IS_ADDR_MULTICAST /*% Is IPv6 address multicast? */ #define IN6_IS_ADDR_MULTICAST(a) ((a)->s6_addr[0] == 0xff) #endif #ifndef IN6_IS_ADDR_LINKLOCAL /*% Is IPv6 address linklocal? */ #define IN6_IS_ADDR_LINKLOCAL(a) \ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80)) #endif #ifndef IN6_IS_ADDR_SITELOCAL /*% is IPv6 address sitelocal? */ #define IN6_IS_ADDR_SITELOCAL(a) \ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0)) #endif #ifndef IN6_IS_ADDR_LOOPBACK /*% is IPv6 address loopback? */ #define IN6_IS_ADDR_LOOPBACK(x) \ (memcmp((x)->s6_addr, in6addr_loopback.s6_addr, 16) == 0) #endif #endif #ifndef AF_INET6 /*% IPv6 */ #define AF_INET6 99 #endif #ifndef PF_INET6 /*% IPv6 */ #define PF_INET6 AF_INET6 #endif #ifndef INADDR_LOOPBACK /*% inaddr loopback */ #define INADDR_LOOPBACK 0x7f000001UL #endif #ifndef ISC_PLATFORM_HAVEIN6PKTINFO /*% IPv6 packet info */ struct in6_pktinfo { struct in6_addr ipi6_addr; /*%< src/dst IPv6 address */ unsigned int ipi6_ifindex; /*%< send/recv interface index */ }; #endif #ifndef ISC_PLATFORM_HAVESOCKADDRSTORAGE #define _SS_MAXSIZE 128 #define _SS_ALIGNSIZE (sizeof (isc_uint64_t)) #ifdef ISC_PLATFORM_HAVESALEN #define _SS_PAD1SIZE (_SS_ALIGNSIZE - (2 * sizeof(isc_uint8_t))) #define _SS_PAD2SIZE (_SS_MAXSIZE - (_SS_ALIGNSIZE + _SS_PAD1SIZE \ + 2 * sizeof(isc_uint8_t))) #else #define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(isc_uint16_t)) #define _SS_PAD2SIZE (_SS_MAXSIZE - (_SS_ALIGNSIZE + _SS_PAD1SIZE \ + sizeof(isc_uint16_t))) #endif struct sockaddr_storage { #ifdef ISC_PLATFORM_HAVESALEN isc_uint8_t ss_len; isc_uint8_t ss_family; #else isc_uint16_t ss_family; #endif char __ss_pad1[_SS_PAD1SIZE]; isc_uint64_t __ss_align; /* field to force desired structure */ char __ss_pad2[_SS_PAD2SIZE]; }; #endif #if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRANY) extern const struct in6_addr isc_net_in6addrany; /*% * Cope with a missing in6addr_any and in6addr_loopback. */ #define in6addr_any isc_net_in6addrany #endif #if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK) extern const struct in6_addr isc_net_in6addrloop; #define in6addr_loopback isc_net_in6addrloop #endif #ifdef ISC_PLATFORM_FIXIN6ISADDR #undef IN6_IS_ADDR_GEOGRAPHIC /*! * \brief * Fix UnixWare 7.1.1's broken IN6_IS_ADDR_* definitions. */ #define IN6_IS_ADDR_GEOGRAPHIC(a) (((a)->S6_un.S6_l[0] & 0xE0) == 0x80) #undef IN6_IS_ADDR_IPX #define IN6_IS_ADDR_IPX(a) (((a)->S6_un.S6_l[0] & 0xFE) == 0x04) #undef IN6_IS_ADDR_LINKLOCAL #define IN6_IS_ADDR_LINKLOCAL(a) (((a)->S6_un.S6_l[0] & 0xC0FF) == 0x80FE) #undef IN6_IS_ADDR_MULTICAST #define IN6_IS_ADDR_MULTICAST(a) (((a)->S6_un.S6_l[0] & 0xFF) == 0xFF) #undef IN6_IS_ADDR_NSAP #define IN6_IS_ADDR_NSAP(a) (((a)->S6_un.S6_l[0] & 0xFE) == 0x02) #undef IN6_IS_ADDR_PROVIDER #define IN6_IS_ADDR_PROVIDER(a) (((a)->S6_un.S6_l[0] & 0xE0) == 0x40) #undef IN6_IS_ADDR_SITELOCAL #define IN6_IS_ADDR_SITELOCAL(a) (((a)->S6_un.S6_l[0] & 0xC0FF) == 0xC0FE) #endif /* ISC_PLATFORM_FIXIN6ISADDR */ #ifdef ISC_PLATFORM_NEEDPORTT /*% * Ensure type in_port_t is defined. */ typedef isc_uint16_t in_port_t; #endif #ifndef MSG_TRUNC /*% * If this system does not have MSG_TRUNC (as returned from recvmsg()) * ISC_PLATFORM_RECVOVERFLOW will be defined. This will enable the MSG_TRUNC * faking code in socket.c. */ #define ISC_PLATFORM_RECVOVERFLOW #endif /*% IP address. */ #define ISC__IPADDR(x) ((isc_uint32_t)htonl((isc_uint32_t)(x))) /*% Is IP address multicast? */ #define ISC_IPADDR_ISMULTICAST(i) \ (((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \ == ISC__IPADDR(0xe0000000)) #define ISC_IPADDR_ISEXPERIMENTAL(i) \ (((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \ == ISC__IPADDR(0xf0000000)) /*** *** Functions. ***/ ISC_LANG_BEGINDECLS isc_result_t isc_net_probeipv4(void); /*%< * Check if the system's kernel supports IPv4. * * Returns: * *\li #ISC_R_SUCCESS IPv4 is supported. *\li #ISC_R_NOTFOUND IPv4 is not supported. *\li #ISC_R_DISABLED IPv4 is disabled. *\li #ISC_R_UNEXPECTED */ isc_result_t isc_net_probeipv6(void); /*%< * Check if the system's kernel supports IPv6. * * Returns: * *\li #ISC_R_SUCCESS IPv6 is supported. *\li #ISC_R_NOTFOUND IPv6 is not supported. *\li #ISC_R_DISABLED IPv6 is disabled. *\li #ISC_R_UNEXPECTED */ isc_result_t isc_net_probe_ipv6only(void); /*%< * Check if the system's kernel supports the IPV6_V6ONLY socket option. * * Returns: * *\li #ISC_R_SUCCESS the option is supported for both TCP and UDP. *\li #ISC_R_NOTFOUND IPv6 itself or the option is not supported. *\li #ISC_R_UNEXPECTED */ isc_result_t isc_net_probe_ipv6pktinfo(void); /* * Check if the system's kernel supports the IPV6_(RECV)PKTINFO socket option * for UDP sockets. * * Returns: * * \li #ISC_R_SUCCESS the option is supported. * \li #ISC_R_NOTFOUND IPv6 itself or the option is not supported. * \li #ISC_R_UNEXPECTED */ void isc_net_disableipv4(void); void isc_net_disableipv6(void); void isc_net_enableipv4(void); void isc_net_enableipv6(void); isc_result_t isc_net_probeunix(void); /* * Returns whether UNIX domain sockets are supported. */ #define ISC_NET_DSCPRECVV4 0x01 /* Can receive sent DSCP value IPv4 */ #define ISC_NET_DSCPRECVV6 0x02 /* Can receive sent DSCP value IPv6 */ #define ISC_NET_DSCPSETV4 0x04 /* Can set DSCP on socket IPv4 */ #define ISC_NET_DSCPSETV6 0x08 /* Can set DSCP on socket IPv6 */ #define ISC_NET_DSCPPKTV4 0x10 /* Can set DSCP on per packet IPv4 */ #define ISC_NET_DSCPPKTV6 0x20 /* Can set DSCP on per packet IPv6 */ #define ISC_NET_DSCPALL 0x3f /* All valid flags */ unsigned int isc_net_probedscp(void); /*%< * Probe the level of DSCP support. */ isc_result_t isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high); /*%< * Returns system's default range of ephemeral UDP ports, if defined. * If the range is not available or unknown, ISC_NET_PORTRANGELOW and * ISC_NET_PORTRANGEHIGH will be returned. * * Requires: * *\li 'low' and 'high' must be non NULL. * * Returns: * *\li *low and *high will be the ports specifying the low and high ends of * the range. */ #ifdef ISC_PLATFORM_NEEDNTOP const char * isc_net_ntop(int af, const void *src, char *dst, size_t size); #define inet_ntop isc_net_ntop #endif #ifdef ISC_PLATFORM_NEEDPTON int isc_net_pton(int af, const char *src, void *dst); #undef inet_pton #define inet_pton isc_net_pton #endif int isc_net_aton(const char *cp, struct in_addr *addr); #undef inet_aton #define inet_aton isc_net_aton ISC_LANG_ENDDECLS #endif /* ISC_NET_H */ bind9-9.10.3.dfsg.P4/lib/isc/unix/include/isc/strerror.h0000644000470500017500000000243612664710322022141 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: strerror.h,v 1.10 2008/12/01 23:47:45 tbox Exp $ */ #ifndef ISC_STRERROR_H #define ISC_STRERROR_H /*! \file */ #include #include ISC_LANG_BEGINDECLS /*% String Error Size */ #define ISC_STRERRORSIZE 128 /*% * Provide a thread safe wrapper to strerror(). * * Requires: * 'buf' to be non NULL. */ void isc__strerror(int num, char *buf, size_t bufsize); ISC_LANG_ENDDECLS #endif /* ISC_STRERROR_H */ bind9-9.10.3.dfsg.P4/lib/isc/unix/include/isc/stdtime.h0000644000470500017500000000345012664710322021725 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef ISC_STDTIME_H #define ISC_STDTIME_H 1 /*! \file */ #include #include /*% * It's public information that 'isc_stdtime_t' is an unsigned integral type. * Applications that want maximum portability should not assume anything * about its size. */ typedef isc_uint32_t isc_stdtime_t; /* but this flag helps... */ #define STDTIME_ON_32BITS 1 /* * isc_stdtime32_t is a 32-bit version of isc_stdtime_t. A variable of this * type should only be used as an opaque integer (e.g.,) to compare two * time values. */ typedef isc_uint32_t isc_stdtime32_t; ISC_LANG_BEGINDECLS /* */ void isc_stdtime_get(isc_stdtime_t *t); /*%< * Set 't' to the number of seconds since 00:00:00 UTC, January 1, 1970. * * Requires: * *\li 't' is a valid pointer. */ #define isc_stdtime_convert32(t, t32p) (*(t32p) = t) /* * Convert the standard time to its 32-bit version. */ ISC_LANG_ENDDECLS #endif /* ISC_STDTIME_H */ bind9-9.10.3.dfsg.P4/lib/isc/unix/include/isc/time.h0000644000470500017500000002060512664710322021213 0ustar lamontlamont/* * Copyright (C) 2004-2009, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: time.h,v 1.40 2009/01/05 23:47:54 tbox Exp $ */ #ifndef ISC_TIME_H #define ISC_TIME_H 1 /*! \file */ #include #include /*** *** Intervals ***/ /*! * \brief * The contents of this structure are private, and MUST NOT be accessed * directly by callers. * * The contents are exposed only to allow callers to avoid dynamic allocation. */ struct isc_interval { unsigned int seconds; unsigned int nanoseconds; }; extern const isc_interval_t * const isc_interval_zero; /* * ISC_FORMATHTTPTIMESTAMP_SIZE needs to be 30 in C locale and potentially * more for other locales to handle longer national abbreviations when * expanding strftime's %a and %b. */ #define ISC_FORMATHTTPTIMESTAMP_SIZE 50 ISC_LANG_BEGINDECLS void isc_interval_set(isc_interval_t *i, unsigned int seconds, unsigned int nanoseconds); /*%< * Set 'i' to a value representing an interval of 'seconds' seconds and * 'nanoseconds' nanoseconds, suitable for use in isc_time_add() and * isc_time_subtract(). * * Requires: * *\li 't' is a valid pointer. *\li nanoseconds < 1000000000. */ isc_boolean_t isc_interval_iszero(const isc_interval_t *i); /*%< * Returns ISC_TRUE iff. 'i' is the zero interval. * * Requires: * *\li 'i' is a valid pointer. */ /*** *** Absolute Times ***/ /*% * The contents of this structure are private, and MUST NOT be accessed * directly by callers. * * The contents are exposed only to allow callers to avoid dynamic allocation. */ struct isc_time { unsigned int seconds; unsigned int nanoseconds; }; extern const isc_time_t * const isc_time_epoch; void isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds); /*%< * Set 't' to a value which represents the given number of seconds and * nanoseconds since 00:00:00 January 1, 1970, UTC. * * Notes: *\li The Unix version of this call is equivalent to: *\code * isc_time_settoepoch(t); * isc_interval_set(i, seconds, nanoseconds); * isc_time_add(t, i, t); *\endcode * * Requires: *\li 't' is a valid pointer. *\li nanoseconds < 1000000000. */ void isc_time_settoepoch(isc_time_t *t); /*%< * Set 't' to the time of the epoch. * * Notes: *\li The date of the epoch is platform-dependent. * * Requires: * *\li 't' is a valid pointer. */ isc_boolean_t isc_time_isepoch(const isc_time_t *t); /*%< * Returns ISC_TRUE iff. 't' is the epoch ("time zero"). * * Requires: * *\li 't' is a valid pointer. */ isc_result_t isc_time_now(isc_time_t *t); /*%< * Set 't' to the current absolute time. * * Requires: * *\li 't' is a valid pointer. * * Returns: * *\li Success *\li Unexpected error * Getting the time from the system failed. *\li Out of range * The time from the system is too large to be represented * in the current definition of isc_time_t. */ isc_result_t isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i); /*%< * Set *t to the current absolute time + i. * * Note: *\li This call is equivalent to: * *\code * isc_time_now(t); * isc_time_add(t, i, t); *\endcode * * Requires: * *\li 't' and 'i' are valid pointers. * * Returns: * *\li Success *\li Unexpected error * Getting the time from the system failed. *\li Out of range * The interval added to the time from the system is too large to * be represented in the current definition of isc_time_t. */ int isc_time_compare(const isc_time_t *t1, const isc_time_t *t2); /*%< * Compare the times referenced by 't1' and 't2' * * Requires: * *\li 't1' and 't2' are valid pointers. * * Returns: * *\li -1 t1 < t2 (comparing times, not pointers) *\li 0 t1 = t2 *\li 1 t1 > t2 */ isc_result_t isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result); /*%< * Add 'i' to 't', storing the result in 'result'. * * Requires: * *\li 't', 'i', and 'result' are valid pointers. * * Returns: *\li Success *\li Out of range * The interval added to the time is too large to * be represented in the current definition of isc_time_t. */ isc_result_t isc_time_subtract(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result); /*%< * Subtract 'i' from 't', storing the result in 'result'. * * Requires: * *\li 't', 'i', and 'result' are valid pointers. * * Returns: *\li Success *\li Out of range * The interval is larger than the time since the epoch. */ isc_uint64_t isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2); /*%< * Find the difference in microseconds between time t1 and time t2. * t2 is the subtrahend of t1; ie, difference = t1 - t2. * * Requires: * *\li 't1' and 't2' are valid pointers. * * Returns: *\li The difference of t1 - t2, or 0 if t1 <= t2. */ isc_uint32_t isc_time_seconds(const isc_time_t *t); /*%< * Return the number of seconds since the epoch stored in a time structure. * * Requires: * *\li 't' is a valid pointer. */ isc_result_t isc_time_secondsastimet(const isc_time_t *t, time_t *secondsp); /*%< * Ensure the number of seconds in an isc_time_t is representable by a time_t. * * Notes: *\li The number of seconds stored in an isc_time_t might be larger * than the number of seconds a time_t is able to handle. Since * time_t is mostly opaque according to the ANSI/ISO standard * (essentially, all you can be sure of is that it is an arithmetic type, * not even necessarily integral), it can be tricky to ensure that * the isc_time_t is in the range a time_t can handle. Use this * function in place of isc_time_seconds() any time you need to set a * time_t from an isc_time_t. * * Requires: *\li 't' is a valid pointer. * * Returns: *\li Success *\li Out of range */ isc_uint32_t isc_time_nanoseconds(const isc_time_t *t); /*%< * Return the number of nanoseconds stored in a time structure. * * Notes: *\li This is the number of nanoseconds in excess of the number * of seconds since the epoch; it will always be less than one * full second. * * Requires: *\li 't' is a valid pointer. * * Ensures: *\li The returned value is less than 1*10^9. */ void isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len); /*%< * Format the time 't' into the buffer 'buf' of length 'len', * using a format like "30-Aug-2000 04:06:47.997" and the local time zone. * If the text does not fit in the buffer, the result is indeterminate, * but is always guaranteed to be null terminated. * * Requires: *\li 'len' > 0 *\li 'buf' points to an array of at least len chars * */ void isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len); /*%< * Format the time 't' into the buffer 'buf' of length 'len', * using a format like "Mon, 30 Aug 2000 04:06:47 GMT" * If the text does not fit in the buffer, the result is indeterminate, * but is always guaranteed to be null terminated. * * Requires: *\li 'len' > 0 *\li 'buf' points to an array of at least len chars * */ isc_result_t isc_time_parsehttptimestamp(char *input, isc_time_t *t); /*%< * Parse the time in 'input' into the isc_time_t pointed to by 't', * expecting a format like "Mon, 30 Aug 2000 04:06:47 GMT" * * Requires: *\li 'buf' and 't' are not NULL. */ void isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len); /*%< * Format the time 't' into the buffer 'buf' of length 'len', * using the ISO8601 format: "yyyy-mm-ddThh:mm:ssZ" * If the text does not fit in the buffer, the result is indeterminate, * but is always guaranteed to be null terminated. * * Requires: *\li 'len' > 0 *\li 'buf' points to an array of at least len chars * */ ISC_LANG_ENDDECLS #endif /* ISC_TIME_H */ bind9-9.10.3.dfsg.P4/lib/isc/unix/include/isc/netdb.h0000644000470500017500000000256012664710322021351 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: netdb.h,v 1.11 2007/06/19 23:47:19 tbox Exp $ */ #ifndef ISC_NETDB_H #define ISC_NETDB_H 1 /***** ***** Module Info *****/ /*! \file * \brief * Portable netdb.h support. * * This module is responsible for defining the getby APIs. * * MP: *\li No impact. * * Reliability: *\li No anticipated impact. * * Resources: *\li N/A. * * Security: *\li No anticipated impact. * * Standards: *\li BSD API */ /*** *** Imports. ***/ #include #include #endif /* ISC_NETDB_H */ bind9-9.10.3.dfsg.P4/lib/isc/unix/include/isc/keyboard.h0000644000470500017500000000274612664710322022063 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: keyboard.h,v 1.11 2007/06/19 23:47:19 tbox Exp $ */ #ifndef ISC_KEYBOARD_H #define ISC_KEYBOARD_H 1 /*! \file */ #include #include #include ISC_LANG_BEGINDECLS typedef struct { int fd; struct termios saved_mode; isc_result_t result; } isc_keyboard_t; isc_result_t isc_keyboard_open(isc_keyboard_t *keyboard); isc_result_t isc_keyboard_close(isc_keyboard_t *keyboard, unsigned int sleepseconds); isc_result_t isc_keyboard_getchar(isc_keyboard_t *keyboard, unsigned char *cp); isc_boolean_t isc_keyboard_canceled(isc_keyboard_t *keyboard); ISC_LANG_ENDDECLS #endif /* ISC_KEYBOARD_H */ bind9-9.10.3.dfsg.P4/lib/isc/unix/include/isc/stat.h0000644000470500017500000000237312664710322021232 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: stat.h,v 1.5 2007/06/19 23:47:19 tbox Exp $ */ #ifndef ISC_STAT_H #define ISC_STAT_H 1 /***** ***** Module Info *****/ /* * Portable support. * * This module is responsible for defining S_IS??? macros. * * MP: * No impact. * * Reliability: * No anticipated impact. * * Resources: * N/A. * * Security: * No anticipated impact. * */ /*** *** Imports. ***/ #include #include #endif /* ISC_STAT_H */ bind9-9.10.3.dfsg.P4/lib/isc/unix/errno2result.h0000644000470500017500000000251312664710322020520 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef UNIX_ERRNO2RESULT_H #define UNIX_ERRNO2RESULT_H 1 /*! \file */ /* XXXDCL this should be moved to lib/isc/include/isc/errno2result.h. */ #include /* Provides errno. */ #include #include ISC_LANG_BEGINDECLS #define isc__errno2result(x) isc___errno2result(x, __FILE__, __LINE__) isc_result_t isc___errno2result(int posixerrno, const char *file, unsigned int line); ISC_LANG_ENDDECLS #endif /* UNIX_ERRNO2RESULT_H */ bind9-9.10.3.dfsg.P4/lib/isc/unix/net.c0000644000470500017500000005125512664710322016642 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2008, 2012-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #include #include #if defined(HAVE_SYS_SYSCTL_H) #if defined(HAVE_SYS_PARAM_H) #include #endif #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #ifndef ISC_SOCKADDR_LEN_T #define ISC_SOCKADDR_LEN_T unsigned int #endif /*% * Definitions about UDP port range specification. This is a total mess of * portability variants: some use sysctl (but the sysctl names vary), some use * system-specific interfaces, some have the same interface for IPv4 and IPv6, * some separate them, etc... */ /*% * The last resort defaults: use all non well known port space */ #ifndef ISC_NET_PORTRANGELOW #define ISC_NET_PORTRANGELOW 1024 #endif /* ISC_NET_PORTRANGELOW */ #ifndef ISC_NET_PORTRANGEHIGH #define ISC_NET_PORTRANGEHIGH 65535 #endif /* ISC_NET_PORTRANGEHIGH */ #ifdef HAVE_SYSCTLBYNAME /*% * sysctl variants */ #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__) #define USE_SYSCTL_PORTRANGE #define SYSCTL_V4PORTRANGE_LOW "net.inet.ip.portrange.hifirst" #define SYSCTL_V4PORTRANGE_HIGH "net.inet.ip.portrange.hilast" #define SYSCTL_V6PORTRANGE_LOW "net.inet.ip.portrange.hifirst" #define SYSCTL_V6PORTRANGE_HIGH "net.inet.ip.portrange.hilast" #endif #ifdef __NetBSD__ #define USE_SYSCTL_PORTRANGE #define SYSCTL_V4PORTRANGE_LOW "net.inet.ip.anonportmin" #define SYSCTL_V4PORTRANGE_HIGH "net.inet.ip.anonportmax" #define SYSCTL_V6PORTRANGE_LOW "net.inet6.ip6.anonportmin" #define SYSCTL_V6PORTRANGE_HIGH "net.inet6.ip6.anonportmax" #endif #else /* !HAVE_SYSCTLBYNAME */ #ifdef __OpenBSD__ #define USE_SYSCTL_PORTRANGE #define SYSCTL_V4PORTRANGE_LOW { CTL_NET, PF_INET, IPPROTO_IP, \ IPCTL_IPPORT_HIFIRSTAUTO } #define SYSCTL_V4PORTRANGE_HIGH { CTL_NET, PF_INET, IPPROTO_IP, \ IPCTL_IPPORT_HILASTAUTO } /* Same for IPv6 */ #define SYSCTL_V6PORTRANGE_LOW SYSCTL_V4PORTRANGE_LOW #define SYSCTL_V6PORTRANGE_HIGH SYSCTL_V4PORTRANGE_HIGH #endif #endif /* HAVE_SYSCTLBYNAME */ #if defined(ISC_PLATFORM_HAVEIPV6) # if defined(ISC_PLATFORM_NEEDIN6ADDRANY) const struct in6_addr isc_net_in6addrany = IN6ADDR_ANY_INIT; # endif # if defined(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK) const struct in6_addr isc_net_in6addrloop = IN6ADDR_LOOPBACK_INIT; # endif # if defined(WANT_IPV6) static isc_once_t once_ipv6only = ISC_ONCE_INIT; # endif # if defined(ISC_PLATFORM_HAVEIN6PKTINFO) static isc_once_t once_ipv6pktinfo = ISC_ONCE_INIT; # endif #endif /* ISC_PLATFORM_HAVEIPV6 */ static isc_once_t once = ISC_ONCE_INIT; static isc_once_t once_dscp = ISC_ONCE_INIT; static isc_result_t ipv4_result = ISC_R_NOTFOUND; static isc_result_t ipv6_result = ISC_R_NOTFOUND; static isc_result_t unix_result = ISC_R_NOTFOUND; static isc_result_t ipv6only_result = ISC_R_NOTFOUND; static isc_result_t ipv6pktinfo_result = ISC_R_NOTFOUND; static unsigned int dscp_result = 0; static isc_result_t try_proto(int domain) { int s; isc_result_t result = ISC_R_SUCCESS; char strbuf[ISC_STRERRORSIZE]; s = socket(domain, SOCK_STREAM, 0); if (s == -1) { switch (errno) { #ifdef EAFNOSUPPORT case EAFNOSUPPORT: #endif #ifdef EPROTONOSUPPORT case EPROTONOSUPPORT: #endif #ifdef EINVAL case EINVAL: #endif return (ISC_R_NOTFOUND); default: isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "socket() %s: %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); return (ISC_R_UNEXPECTED); } } #ifdef ISC_PLATFORM_HAVEIPV6 #ifdef WANT_IPV6 #ifdef ISC_PLATFORM_HAVEIN6PKTINFO if (domain == PF_INET6) { struct sockaddr_in6 sin6; unsigned int len; /* * Check to see if IPv6 is broken, as is common on Linux. */ len = sizeof(sin6); if (getsockname(s, (struct sockaddr *)&sin6, (void *)&len) < 0) { isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, "retrieving the address of an IPv6 " "socket from the kernel failed."); isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, "IPv6 is not supported."); result = ISC_R_NOTFOUND; } else { if (len == sizeof(struct sockaddr_in6)) result = ISC_R_SUCCESS; else { isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, "IPv6 structures in kernel and " "user space do not match."); isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, "IPv6 is not supported."); result = ISC_R_NOTFOUND; } } } #endif #endif #endif (void)close(s); return (result); } static void initialize_action(void) { ipv4_result = try_proto(PF_INET); #ifdef ISC_PLATFORM_HAVEIPV6 #ifdef WANT_IPV6 #ifdef ISC_PLATFORM_HAVEIN6PKTINFO ipv6_result = try_proto(PF_INET6); #endif #endif #endif #ifdef ISC_PLATFORM_HAVESYSUNH unix_result = try_proto(PF_UNIX); #endif } static void initialize(void) { RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); } isc_result_t isc_net_probeipv4(void) { initialize(); return (ipv4_result); } isc_result_t isc_net_probeipv6(void) { initialize(); return (ipv6_result); } isc_result_t isc_net_probeunix(void) { initialize(); return (unix_result); } #ifdef ISC_PLATFORM_HAVEIPV6 #ifdef WANT_IPV6 static void try_ipv6only(void) { #ifdef IPV6_V6ONLY int s, on; char strbuf[ISC_STRERRORSIZE]; #endif isc_result_t result; result = isc_net_probeipv6(); if (result != ISC_R_SUCCESS) { ipv6only_result = result; return; } #ifndef IPV6_V6ONLY ipv6only_result = ISC_R_NOTFOUND; return; #else /* check for TCP sockets */ s = socket(PF_INET6, SOCK_STREAM, 0); if (s == -1) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "socket() %s: %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); ipv6only_result = ISC_R_UNEXPECTED; return; } on = 1; if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) { ipv6only_result = ISC_R_NOTFOUND; goto close; } close(s); /* check for UDP sockets */ s = socket(PF_INET6, SOCK_DGRAM, 0); if (s == -1) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "socket() %s: %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); ipv6only_result = ISC_R_UNEXPECTED; return; } on = 1; if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) { ipv6only_result = ISC_R_NOTFOUND; goto close; } ipv6only_result = ISC_R_SUCCESS; close: close(s); return; #endif /* IPV6_V6ONLY */ } static void initialize_ipv6only(void) { RUNTIME_CHECK(isc_once_do(&once_ipv6only, try_ipv6only) == ISC_R_SUCCESS); } #endif /* WANT_IPV6 */ #ifdef ISC_PLATFORM_HAVEIN6PKTINFO #ifdef WANT_IPV6 static void try_ipv6pktinfo(void) { int s, on; char strbuf[ISC_STRERRORSIZE]; isc_result_t result; int optname; result = isc_net_probeipv6(); if (result != ISC_R_SUCCESS) { ipv6pktinfo_result = result; return; } /* we only use this for UDP sockets */ s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); if (s == -1) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "socket() %s: %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); ipv6pktinfo_result = ISC_R_UNEXPECTED; return; } #ifdef IPV6_RECVPKTINFO optname = IPV6_RECVPKTINFO; #else optname = IPV6_PKTINFO; #endif on = 1; if (setsockopt(s, IPPROTO_IPV6, optname, &on, sizeof(on)) < 0) { ipv6pktinfo_result = ISC_R_NOTFOUND; goto close; } ipv6pktinfo_result = ISC_R_SUCCESS; close: close(s); return; } static void initialize_ipv6pktinfo(void) { RUNTIME_CHECK(isc_once_do(&once_ipv6pktinfo, try_ipv6pktinfo) == ISC_R_SUCCESS); } #endif /* WANT_IPV6 */ #endif /* ISC_PLATFORM_HAVEIN6PKTINFO */ #endif /* ISC_PLATFORM_HAVEIPV6 */ isc_result_t isc_net_probe_ipv6only(void) { #ifdef ISC_PLATFORM_HAVEIPV6 #ifdef WANT_IPV6 initialize_ipv6only(); #else ipv6only_result = ISC_R_NOTFOUND; #endif #endif return (ipv6only_result); } isc_result_t isc_net_probe_ipv6pktinfo(void) { #ifdef ISC_PLATFORM_HAVEIPV6 #ifdef ISC_PLATFORM_HAVEIN6PKTINFO #ifdef WANT_IPV6 initialize_ipv6pktinfo(); #else ipv6pktinfo_result = ISC_R_NOTFOUND; #endif #endif #endif return (ipv6pktinfo_result); } static inline ISC_SOCKADDR_LEN_T cmsg_len(ISC_SOCKADDR_LEN_T len) { #ifdef CMSG_LEN return (CMSG_LEN(len)); #else ISC_SOCKADDR_LEN_T hdrlen; /* * Cast NULL so that any pointer arithmetic performed by CMSG_DATA * is correct. */ hdrlen = (ISC_SOCKADDR_LEN_T)CMSG_DATA(((struct cmsghdr *)NULL)); return (hdrlen + len); #endif } static inline ISC_SOCKADDR_LEN_T cmsg_space(ISC_SOCKADDR_LEN_T len) { #ifdef CMSG_SPACE return (CMSG_SPACE(len)); #else struct msghdr msg; struct cmsghdr *cmsgp; /* * XXX: The buffer length is an ad-hoc value, but should be enough * in a practical sense. */ char dummybuf[sizeof(struct cmsghdr) + 1024]; memset(&msg, 0, sizeof(msg)); msg.msg_control = dummybuf; msg.msg_controllen = sizeof(dummybuf); cmsgp = (struct cmsghdr *)dummybuf; cmsgp->cmsg_len = cmsg_len(len); cmsgp = CMSG_NXTHDR(&msg, cmsgp); if (cmsgp != NULL) return ((char *)cmsgp - (char *)msg.msg_control); else return (0); #endif } #ifdef ISC_NET_BSD44MSGHDR /* * Make a fd non-blocking. */ static isc_result_t make_nonblock(int fd) { int ret; int flags; char strbuf[ISC_STRERRORSIZE]; #ifdef USE_FIONBIO_IOCTL int on = 1; ret = ioctl(fd, FIONBIO, (char *)&on); #else flags = fcntl(fd, F_GETFL, 0); flags |= PORT_NONBLOCK; ret = fcntl(fd, F_SETFL, flags); #endif if (ret == -1) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, #ifdef USE_FIONBIO_IOCTL "ioctl(%d, FIONBIO, &on): %s", fd, #else "fcntl(%d, F_SETFL, %d): %s", fd, flags, #endif strbuf); return (ISC_R_UNEXPECTED); } return (ISC_R_SUCCESS); } static isc_boolean_t cmsgsend(int s, int level, int type, struct addrinfo *res) { char strbuf[ISC_STRERRORSIZE]; struct sockaddr_storage ss; ISC_SOCKADDR_LEN_T len = sizeof(ss); struct msghdr msg; union { struct cmsghdr h; unsigned char b[256]; } control; struct cmsghdr *cmsgp; int dscp = 46; struct iovec iovec; char buf[1] = { 0 }; isc_result_t result; if (bind(s, res->ai_addr, res->ai_addrlen) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(10), "bind: %s", strbuf); return (ISC_FALSE); } if (getsockname(s, (struct sockaddr *)&ss, &len) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(10), "getsockname: %s", strbuf); return (ISC_FALSE); } iovec.iov_base = buf; iovec.iov_len = sizeof(buf); memset(&msg, 0, sizeof(msg)); msg.msg_name = (struct sockaddr *)&ss; msg.msg_namelen = len; msg.msg_iov = &iovec; msg.msg_iovlen = 1; msg.msg_control = (void*)&control; msg.msg_controllen = 0; msg.msg_flags = 0; cmsgp = msg.msg_control; switch (type) { #ifdef IP_TOS case IP_TOS: memset(cmsgp, 0, cmsg_space(sizeof(char))); cmsgp->cmsg_level = level; cmsgp->cmsg_type = type; cmsgp->cmsg_len = cmsg_len(sizeof(char)); *(unsigned char*)CMSG_DATA(cmsgp) = dscp; msg.msg_controllen += cmsg_space(sizeof(char)); break; #endif #ifdef IPV6_TCLASS case IPV6_TCLASS: memset(cmsgp, 0, cmsg_space(sizeof(dscp))); cmsgp->cmsg_level = level; cmsgp->cmsg_type = type; cmsgp->cmsg_len = cmsg_len(sizeof(dscp)); memmove(CMSG_DATA(cmsgp), &dscp, sizeof(dscp)); msg.msg_controllen += cmsg_space(sizeof(dscp)); break; #endif default: INSIST(0); } if (sendmsg(s, &msg, 0) < 0) { int debug = ISC_LOG_DEBUG(10); switch (errno) { #ifdef ENOPROTOOPT case ENOPROTOOPT: #endif #ifdef EOPNOTSUPP case EOPNOTSUPP: #endif case EINVAL: break; default: debug = ISC_LOG_NOTICE; } isc__strerror(errno, strbuf, sizeof(strbuf)); if (debug != ISC_LOG_NOTICE) { isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(10), "sendmsg: %s", strbuf); } else { UNEXPECTED_ERROR(__FILE__, __LINE__, "sendmsg() %s: %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); } return (ISC_FALSE); } /* * Make sure the message actually got sent. */ result = make_nonblock(s); RUNTIME_CHECK(result == ISC_R_SUCCESS); iovec.iov_base = buf; iovec.iov_len = sizeof(buf); memset(&msg, 0, sizeof(msg)); msg.msg_name = (struct sockaddr *)&ss; msg.msg_namelen = sizeof(ss); msg.msg_iov = &iovec; msg.msg_iovlen = 1; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_flags = 0; if (recvmsg(s, &msg, 0) < 0) return (ISC_FALSE); return (ISC_TRUE); } #endif static void try_dscp_v4(void) { #ifdef IP_TOS char strbuf[ISC_STRERRORSIZE]; struct addrinfo hints, *res0; int s, dscp = 0, n; #ifdef IP_RECVTOS int on = 1; #endif /* IP_RECVTOS */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; #ifdef AI_NUMERICHOST hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; #else hints.ai_flags = AI_PASSIVE; #endif n = getaddrinfo("127.0.0.1", NULL, &hints, &res0); if (n != 0 || res0 == NULL) { isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(10), "getaddrinfo(127.0.0.1): %s", gai_strerror(n)); return; } s = socket(res0->ai_family, res0->ai_socktype, res0->ai_protocol); if (s == -1) { isc__strerror(errno, strbuf, sizeof(strbuf)); isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(10), "socket: %s", strbuf); freeaddrinfo(res0); return; } if (setsockopt(s, IPPROTO_IP, IP_TOS, &dscp, sizeof(dscp)) == 0) dscp_result |= ISC_NET_DSCPSETV4; #ifdef IP_RECVTOS on = 1; if (setsockopt(s, IPPROTO_IP, IP_RECVTOS, &on, sizeof(on)) == 0) dscp_result |= ISC_NET_DSCPRECVV4; #endif /* IP_RECVTOS */ #ifdef ISC_NET_BSD44MSGHDR #ifndef ISC_CMSG_IP_TOS #ifdef __APPLE__ #define ISC_CMSG_IP_TOS 0 /* As of 10.8.2. */ #else /* ! __APPLE__ */ #define ISC_CMSG_IP_TOS 1 #endif /* ! __APPLE__ */ #endif /* ! ISC_CMSG_IP_TOS */ #if ISC_CMSG_IP_TOS if (cmsgsend(s, IPPROTO_IP, IP_TOS, res0)) dscp_result |= ISC_NET_DSCPPKTV4; #endif /* ISC_CMSG_IP_TOS */ #endif /* ISC_NET_BSD44MSGHDR */ freeaddrinfo(res0); close(s); #endif /* IP_TOS */ } static void try_dscp_v6(void) { #ifdef ISC_PLATFORM_HAVEIPV6 #ifdef WANT_IPV6 #ifdef IPV6_TCLASS char strbuf[ISC_STRERRORSIZE]; struct addrinfo hints, *res0; int s, dscp = 0, n; #if defined(IPV6_RECVTCLASS) int on = 1; #endif /* IPV6_RECVTCLASS */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; #ifdef AI_NUMERICHOST hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; #else hints.ai_flags = AI_PASSIVE; #endif n = getaddrinfo("::1", NULL, &hints, &res0); if (n != 0 || res0 == NULL) { isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(10), "getaddrinfo(::1): %s", gai_strerror(n)); return; } s = socket(res0->ai_family, res0->ai_socktype, res0->ai_protocol); if (s == -1) { isc__strerror(errno, strbuf, sizeof(strbuf)); isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(10), "socket: %s", strbuf); freeaddrinfo(res0); return; } if (setsockopt(s, IPPROTO_IPV6, IPV6_TCLASS, &dscp, sizeof(dscp)) == 0) dscp_result |= ISC_NET_DSCPSETV6; #ifdef IPV6_RECVTCLASS on = 1; if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVTCLASS, &on, sizeof(on)) == 0) dscp_result |= ISC_NET_DSCPRECVV6; #endif /* IPV6_RECVTCLASS */ #ifdef ISC_NET_BSD44MSGHDR if (cmsgsend(s, IPPROTO_IPV6, IPV6_TCLASS, res0)) dscp_result |= ISC_NET_DSCPPKTV6; #endif /* ISC_NET_BSD44MSGHDR */ freeaddrinfo(res0); close(s); #endif /* IPV6_TCLASS */ #endif /* WANT_IPV6 */ #endif /* ISC_PLATFORM_HAVEIPV6 */ } static void try_dscp(void) { try_dscp_v4(); try_dscp_v6(); } static void initialize_dscp(void) { RUNTIME_CHECK(isc_once_do(&once_dscp, try_dscp) == ISC_R_SUCCESS); } unsigned int isc_net_probedscp(void) { initialize_dscp(); return (dscp_result); } #if defined(USE_SYSCTL_PORTRANGE) #if defined(HAVE_SYSCTLBYNAME) static isc_result_t getudpportrange_sysctl(int af, in_port_t *low, in_port_t *high) { int port_low, port_high; size_t portlen; const char *sysctlname_lowport, *sysctlname_hiport; if (af == AF_INET) { sysctlname_lowport = SYSCTL_V4PORTRANGE_LOW; sysctlname_hiport = SYSCTL_V4PORTRANGE_HIGH; } else { sysctlname_lowport = SYSCTL_V6PORTRANGE_LOW; sysctlname_hiport = SYSCTL_V6PORTRANGE_HIGH; } portlen = sizeof(port_low); if (sysctlbyname(sysctlname_lowport, &port_low, &portlen, NULL, 0) < 0) { return (ISC_R_FAILURE); } portlen = sizeof(port_high); if (sysctlbyname(sysctlname_hiport, &port_high, &portlen, NULL, 0) < 0) { return (ISC_R_FAILURE); } if ((port_low & ~0xffff) != 0 || (port_high & ~0xffff) != 0) return (ISC_R_RANGE); *low = (in_port_t)port_low; *high = (in_port_t)port_high; return (ISC_R_SUCCESS); } #else /* !HAVE_SYSCTLBYNAME */ static isc_result_t getudpportrange_sysctl(int af, in_port_t *low, in_port_t *high) { int mib_lo4[4] = SYSCTL_V4PORTRANGE_LOW; int mib_hi4[4] = SYSCTL_V4PORTRANGE_HIGH; int mib_lo6[4] = SYSCTL_V6PORTRANGE_LOW; int mib_hi6[4] = SYSCTL_V6PORTRANGE_HIGH; int *mib_lo, *mib_hi, miblen; int port_low, port_high; size_t portlen; if (af == AF_INET) { mib_lo = mib_lo4; mib_hi = mib_hi4; miblen = sizeof(mib_lo4) / sizeof(mib_lo4[0]); } else { mib_lo = mib_lo6; mib_hi = mib_hi6; miblen = sizeof(mib_lo6) / sizeof(mib_lo6[0]); } portlen = sizeof(port_low); if (sysctl(mib_lo, miblen, &port_low, &portlen, NULL, 0) < 0) { return (ISC_R_FAILURE); } portlen = sizeof(port_high); if (sysctl(mib_hi, miblen, &port_high, &portlen, NULL, 0) < 0) { return (ISC_R_FAILURE); } if ((port_low & ~0xffff) != 0 || (port_high & ~0xffff) != 0) return (ISC_R_RANGE); *low = (in_port_t) port_low; *high = (in_port_t) port_high; return (ISC_R_SUCCESS); } #endif /* HAVE_SYSCTLBYNAME */ #endif /* USE_SYSCTL_PORTRANGE */ isc_result_t isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high) { int result = ISC_R_FAILURE; #if !defined(USE_SYSCTL_PORTRANGE) && defined(__linux) FILE *fp; #endif REQUIRE(low != NULL && high != NULL); #if defined(USE_SYSCTL_PORTRANGE) result = getudpportrange_sysctl(af, low, high); #elif defined(__linux) UNUSED(af); /* * Linux local ports are address family agnostic. */ fp = fopen("/proc/sys/net/ipv4/ip_local_port_range", "r"); if (fp != NULL) { int n; unsigned int l, h; n = fscanf(fp, "%u %u", &l, &h); if (n == 2 && (l & ~0xffff) == 0 && (h & ~0xffff) == 0) { *low = l; *high = h; result = ISC_R_SUCCESS; } fclose(fp); } #else UNUSED(af); #endif if (result != ISC_R_SUCCESS) { *low = ISC_NET_PORTRANGELOW; *high = ISC_NET_PORTRANGEHIGH; } return (ISC_R_SUCCESS); /* we currently never fail in this function */ } void isc_net_disableipv4(void) { initialize(); if (ipv4_result == ISC_R_SUCCESS) ipv4_result = ISC_R_DISABLED; } void isc_net_disableipv6(void) { initialize(); if (ipv6_result == ISC_R_SUCCESS) ipv6_result = ISC_R_DISABLED; } void isc_net_enableipv4(void) { initialize(); if (ipv4_result == ISC_R_DISABLED) ipv4_result = ISC_R_SUCCESS; } void isc_net_enableipv6(void) { initialize(); if (ipv6_result == ISC_R_DISABLED) ipv6_result = ISC_R_SUCCESS; } bind9-9.10.3.dfsg.P4/lib/isc/unix/entropy.c0000644000470500017500000003355712664710322017561 0ustar lamontlamont/* * Copyright (C) 2004-2008, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: entropy.c,v 1.82 2008/12/01 23:47:45 tbox Exp $ */ /* \file unix/entropy.c * \brief * This is the system dependent part of the ISC entropy API. */ #include #include /* Openserver 5.0.6A and FD_SETSIZE */ #include #include #include #include #include #ifdef HAVE_NANOSLEEP #include #endif #include #include #include #ifdef ISC_PLATFORM_NEEDSYSSELECTH #include #endif #include "errno2result.h" /*% * There is only one variable in the entropy data structures that is not * system independent, but pulling the structure that uses it into this file * ultimately means pulling several other independent structures here also to * resolve their interdependencies. Thus only the problem variable's type * is defined here. */ #define FILESOURCE_HANDLE_TYPE int typedef struct { int handle; enum { isc_usocketsource_disconnected, isc_usocketsource_connecting, isc_usocketsource_connected, isc_usocketsource_ndesired, isc_usocketsource_wrote, isc_usocketsource_reading } status; size_t sz_to_recv; } isc_entropyusocketsource_t; #include "../entropy.c" static unsigned int get_from_filesource(isc_entropysource_t *source, isc_uint32_t desired) { isc_entropy_t *ent = source->ent; unsigned char buf[128]; int fd = source->sources.file.handle; ssize_t n, ndesired; unsigned int added; if (source->bad) return (0); desired = desired / 8 + (((desired & 0x07) > 0) ? 1 : 0); added = 0; while (desired > 0) { ndesired = ISC_MIN(desired, sizeof(buf)); n = read(fd, buf, ndesired); if (n < 0) { if (errno == EAGAIN || errno == EINTR) goto out; goto err; } if (n == 0) goto err; entropypool_adddata(ent, buf, n, n * 8); added += n * 8; desired -= n; } goto out; err: (void)close(fd); source->sources.file.handle = -1; source->bad = ISC_TRUE; out: return (added); } static unsigned int get_from_usocketsource(isc_entropysource_t *source, isc_uint32_t desired) { isc_entropy_t *ent = source->ent; unsigned char buf[128]; int fd = source->sources.usocket.handle; ssize_t n = 0, ndesired; unsigned int added; size_t sz_to_recv = source->sources.usocket.sz_to_recv; if (source->bad) return (0); desired = desired / 8 + (((desired & 0x07) > 0) ? 1 : 0); added = 0; while (desired > 0) { ndesired = ISC_MIN(desired, sizeof(buf)); eagain_loop: switch ( source->sources.usocket.status ) { case isc_usocketsource_ndesired: buf[0] = ndesired; if ((n = sendto(fd, buf, 1, 0, NULL, 0)) < 0) { if (errno == EWOULDBLOCK || errno == EINTR || errno == ECONNRESET) goto out; goto err; } INSIST(n == 1); source->sources.usocket.status = isc_usocketsource_wrote; goto eagain_loop; case isc_usocketsource_connecting: case isc_usocketsource_connected: buf[0] = 1; buf[1] = ndesired; if ((n = sendto(fd, buf, 2, 0, NULL, 0)) < 0) { if (errno == EWOULDBLOCK || errno == EINTR || errno == ECONNRESET) goto out; goto err; } if (n == 1) { source->sources.usocket.status = isc_usocketsource_ndesired; goto eagain_loop; } INSIST(n == 2); source->sources.usocket.status = isc_usocketsource_wrote; /*FALLTHROUGH*/ case isc_usocketsource_wrote: if (recvfrom(fd, buf, 1, 0, NULL, NULL) != 1) { if (errno == EAGAIN) { /* * The problem of EAGAIN (try again * later) is a major issue on HP-UX. * Solaris actually tries the recvfrom * call again, while HP-UX just dies. * This code is an attempt to let the * entropy pool fill back up (at least * that's what I think the problem is.) * We go to eagain_loop because if we * just "break", then the "desired" * amount gets borked. */ #ifdef HAVE_NANOSLEEP struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 1000000; nanosleep(&ts, NULL); #else usleep(1000); #endif goto eagain_loop; } if (errno == EWOULDBLOCK || errno == EINTR) goto out; goto err; } source->sources.usocket.status = isc_usocketsource_reading; sz_to_recv = buf[0]; source->sources.usocket.sz_to_recv = sz_to_recv; if (sz_to_recv > sizeof(buf)) goto err; /*FALLTHROUGH*/ case isc_usocketsource_reading: if (sz_to_recv != 0U) { n = recv(fd, buf, sz_to_recv, 0); if (n < 0) { if (errno == EWOULDBLOCK || errno == EINTR) goto out; goto err; } } else n = 0; break; default: goto err; } if ((size_t)n != sz_to_recv) source->sources.usocket.sz_to_recv -= n; else source->sources.usocket.status = isc_usocketsource_connected; if (n == 0) goto out; entropypool_adddata(ent, buf, n, n * 8); added += n * 8; desired -= n; } goto out; err: close(fd); source->bad = ISC_TRUE; source->sources.usocket.status = isc_usocketsource_disconnected; source->sources.usocket.handle = -1; out: return (added); } /* * Poll each source, trying to get data from it to stuff into the entropy * pool. */ static void fillpool(isc_entropy_t *ent, unsigned int desired, isc_boolean_t blocking) { unsigned int added; unsigned int remaining; unsigned int needed; unsigned int nsource; isc_entropysource_t *source; REQUIRE(VALID_ENTROPY(ent)); needed = desired; /* * This logic is a little strange, so an explanation is in order. * * If needed is 0, it means we are being asked to "fill to whatever * we think is best." This means that if we have at least a * partially full pool (say, > 1/4th of the pool) we probably don't * need to add anything. * * Also, we will check to see if the "pseudo" count is too high. * If it is, try to mix in better data. Too high is currently * defined as 1/4th of the pool. * * Next, if we are asked to add a specific bit of entropy, make * certain that we will do so. Clamp how much we try to add to * (DIGEST_SIZE * 8 < needed < POOLBITS - entropy). * * Note that if we are in a blocking mode, we will only try to * get as much data as we need, not as much as we might want * to build up. */ if (needed == 0) { REQUIRE(!blocking); if ((ent->pool.entropy >= RND_POOLBITS / 4) && (ent->pool.pseudo <= RND_POOLBITS / 4)) return; needed = THRESHOLD_BITS * 4; } else { needed = ISC_MAX(needed, THRESHOLD_BITS); needed = ISC_MIN(needed, RND_POOLBITS); } /* * In any case, clamp how much we need to how much we can add. */ needed = ISC_MIN(needed, RND_POOLBITS - ent->pool.entropy); /* * But wait! If we're not yet initialized, we need at least * THRESHOLD_BITS * of randomness. */ if (ent->initialized < THRESHOLD_BITS) needed = ISC_MAX(needed, THRESHOLD_BITS - ent->initialized); /* * Poll each file source to see if we can read anything useful from * it. XXXMLG When where are multiple sources, we should keep a * record of which one we last used so we can start from it (or the * next one) to avoid letting some sources build up entropy while * others are always drained. */ added = 0; remaining = needed; if (ent->nextsource == NULL) { ent->nextsource = ISC_LIST_HEAD(ent->sources); if (ent->nextsource == NULL) return; } source = ent->nextsource; again_file: for (nsource = 0; nsource < ent->nsources; nsource++) { unsigned int got; if (remaining == 0) break; got = 0; switch ( source->type ) { case ENTROPY_SOURCETYPE_FILE: got = get_from_filesource(source, remaining); break; case ENTROPY_SOURCETYPE_USOCKET: got = get_from_usocketsource(source, remaining); break; } added += got; remaining -= ISC_MIN(remaining, got); source = ISC_LIST_NEXT(source, link); if (source == NULL) source = ISC_LIST_HEAD(ent->sources); } ent->nextsource = source; if (blocking && remaining != 0) { int fds; fds = wait_for_sources(ent); if (fds > 0) goto again_file; } /* * Here, if there are bits remaining to be had and we can block, * check to see if we have a callback source. If so, call them. */ source = ISC_LIST_HEAD(ent->sources); while ((remaining != 0) && (source != NULL)) { unsigned int got; got = 0; if (source->type == ENTROPY_SOURCETYPE_CALLBACK) got = get_from_callback(source, remaining, blocking); added += got; remaining -= ISC_MIN(remaining, got); if (added >= needed) break; source = ISC_LIST_NEXT(source, link); } /* * Mark as initialized if we've added enough data. */ if (ent->initialized < THRESHOLD_BITS) ent->initialized += added; } static int wait_for_sources(isc_entropy_t *ent) { isc_entropysource_t *source; int maxfd, fd; int cc; fd_set reads; fd_set writes; maxfd = -1; FD_ZERO(&reads); FD_ZERO(&writes); source = ISC_LIST_HEAD(ent->sources); while (source != NULL) { if (source->type == ENTROPY_SOURCETYPE_FILE) { fd = source->sources.file.handle; if (fd >= 0) { maxfd = ISC_MAX(maxfd, fd); FD_SET(fd, &reads); } } if (source->type == ENTROPY_SOURCETYPE_USOCKET) { fd = source->sources.usocket.handle; if (fd >= 0) { switch (source->sources.usocket.status) { case isc_usocketsource_disconnected: break; case isc_usocketsource_connecting: case isc_usocketsource_connected: case isc_usocketsource_ndesired: maxfd = ISC_MAX(maxfd, fd); FD_SET(fd, &writes); break; case isc_usocketsource_wrote: case isc_usocketsource_reading: maxfd = ISC_MAX(maxfd, fd); FD_SET(fd, &reads); break; } } } source = ISC_LIST_NEXT(source, link); } if (maxfd < 0) return (-1); cc = select(maxfd + 1, &reads, &writes, NULL, NULL); if (cc < 0) return (-1); return (cc); } static void destroyfilesource(isc_entropyfilesource_t *source) { (void)close(source->handle); } static void destroyusocketsource(isc_entropyusocketsource_t *source) { close(source->handle); } /* * Make a fd non-blocking */ static isc_result_t make_nonblock(int fd) { int ret; int flags; char strbuf[ISC_STRERRORSIZE]; #ifdef USE_FIONBIO_IOCTL int on = 1; ret = ioctl(fd, FIONBIO, (char *)&on); #else flags = fcntl(fd, F_GETFL, 0); flags |= PORT_NONBLOCK; ret = fcntl(fd, F_SETFL, flags); #endif if (ret == -1) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, #ifdef USE_FIONBIO_IOCTL "ioctl(%d, FIONBIO, &on): %s", fd, #else "fcntl(%d, F_SETFL, %d): %s", fd, flags, #endif strbuf); return (ISC_R_UNEXPECTED); } return (ISC_R_SUCCESS); } isc_result_t isc_entropy_createfilesource(isc_entropy_t *ent, const char *fname) { int fd; struct stat _stat; isc_boolean_t is_usocket = ISC_FALSE; isc_boolean_t is_connected = ISC_FALSE; isc_result_t ret; isc_entropysource_t *source; REQUIRE(VALID_ENTROPY(ent)); REQUIRE(fname != NULL); LOCK(&ent->lock); if (stat(fname, &_stat) < 0) { ret = isc__errno2result(errno); goto errout; } /* * Solaris 2.5.1 does not have support for sockets (S_IFSOCK), * but it does return type S_IFIFO (the OS believes that * the socket is a fifo). This may be an issue if we tell * the program to look at an actual FIFO as its source of * entropy. */ #if defined(S_ISSOCK) if (S_ISSOCK(_stat.st_mode)) is_usocket = ISC_TRUE; #endif #if defined(S_ISFIFO) && defined(sun) if (S_ISFIFO(_stat.st_mode)) is_usocket = ISC_TRUE; #endif if (is_usocket) fd = socket(PF_UNIX, SOCK_STREAM, 0); else fd = open(fname, O_RDONLY | PORT_NONBLOCK, 0); if (fd < 0) { ret = isc__errno2result(errno); goto errout; } ret = make_nonblock(fd); if (ret != ISC_R_SUCCESS) goto closefd; if (is_usocket) { struct sockaddr_un sname; memset(&sname, 0, sizeof(sname)); sname.sun_family = AF_UNIX; strlcpy(sname.sun_path, fname, sizeof(sname.sun_path)); #ifdef ISC_PLATFORM_HAVESALEN #if !defined(SUN_LEN) #define SUN_LEN(su) \ (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) #endif sname.sun_len = SUN_LEN(&sname); #endif if (connect(fd, (struct sockaddr *) &sname, sizeof(struct sockaddr_un)) < 0) { if (errno != EINPROGRESS) { ret = isc__errno2result(errno); goto closefd; } } else is_connected = ISC_TRUE; } source = isc_mem_get(ent->mctx, sizeof(isc_entropysource_t)); if (source == NULL) { ret = ISC_R_NOMEMORY; goto closefd; } /* * From here down, no failures can occur. */ source->magic = SOURCE_MAGIC; source->ent = ent; source->total = 0; source->bad = ISC_FALSE; memset(source->name, 0, sizeof(source->name)); ISC_LINK_INIT(source, link); if (is_usocket) { source->sources.usocket.handle = fd; if (is_connected) source->sources.usocket.status = isc_usocketsource_connected; else source->sources.usocket.status = isc_usocketsource_connecting; source->sources.usocket.sz_to_recv = 0; source->type = ENTROPY_SOURCETYPE_USOCKET; } else { source->sources.file.handle = fd; source->type = ENTROPY_SOURCETYPE_FILE; } /* * Hook it into the entropy system. */ ISC_LIST_APPEND(ent->sources, source, link); ent->nsources++; UNLOCK(&ent->lock); return (ISC_R_SUCCESS); closefd: (void)close(fd); errout: UNLOCK(&ent->lock); return (ret); } bind9-9.10.3.dfsg.P4/lib/isc/unix/ipv6.c0000644000470500017500000000210012664710322016721 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ipv6.c,v 1.14 2007/06/19 23:47:18 tbox Exp $ */ /*! \file */ #include #include const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT; bind9-9.10.3.dfsg.P4/lib/isc/unix/os.c0000644000470500017500000000421012664710322016462 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: os.c,v 1.18 2007/06/19 23:47:18 tbox Exp $ */ #include #include #ifdef HAVE_SYSCONF #include #ifndef __hpux static inline long sysconf_ncpus(void) { #if defined(_SC_NPROCESSORS_ONLN) return sysconf((_SC_NPROCESSORS_ONLN)); #elif defined(_SC_NPROC_ONLN) return sysconf((_SC_NPROC_ONLN)); #else return (0); #endif } #endif #endif /* HAVE_SYSCONF */ #ifdef __hpux #include static inline int hpux_ncpus(void) { struct pst_dynamic psd; if (pstat_getdynamic(&psd, sizeof(psd), 1, 0) != -1) return (psd.psd_proc_cnt); else return (0); } #endif /* __hpux */ #if defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_SYSCTLBYNAME) #include /* for FreeBSD */ #include /* for NetBSD */ #include static int sysctl_ncpus(void) { int ncpu, result; size_t len; len = sizeof(ncpu); result = sysctlbyname("hw.ncpu", &ncpu, &len , 0, 0); if (result != -1) return (ncpu); return (0); } #endif unsigned int isc_os_ncpus(void) { long ncpus = 0; #ifdef __hpux ncpus = hpux_ncpus(); #elif defined(HAVE_SYSCONF) ncpus = sysconf_ncpus(); #endif #if defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_SYSCTLBYNAME) if (ncpus <= 0) ncpus = sysctl_ncpus(); #endif if (ncpus <= 0) ncpus = 1; return ((unsigned int)ncpus); } bind9-9.10.3.dfsg.P4/lib/isc/unix/dir.c0000644000470500017500000001177512664710322016635 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file * \author Principal Authors: DCL */ #include #include #include #include #include #include #include #include #include #include #include "errno2result.h" #define ISC_DIR_MAGIC ISC_MAGIC('D', 'I', 'R', '*') #define VALID_DIR(dir) ISC_MAGIC_VALID(dir, ISC_DIR_MAGIC) void isc_dir_init(isc_dir_t *dir) { REQUIRE(dir != NULL); dir->entry.name[0] = '\0'; dir->entry.length = 0; dir->handle = NULL; dir->magic = ISC_DIR_MAGIC; } /*! * \brief Allocate workspace and open directory stream. If either one fails, * NULL will be returned. */ isc_result_t isc_dir_open(isc_dir_t *dir, const char *dirname) { char *p; isc_result_t result = ISC_R_SUCCESS; REQUIRE(VALID_DIR(dir)); REQUIRE(dirname != NULL); /* * Copy directory name. Need to have enough space for the name, * a possible path separator, the wildcard, and the final NUL. */ if (strlen(dirname) + 3 > sizeof(dir->dirname)) /* XXXDCL ? */ return (ISC_R_NOSPACE); strcpy(dir->dirname, dirname); /* * Append path separator, if needed, and "*". */ p = dir->dirname + strlen(dir->dirname); if (dir->dirname < p && *(p - 1) != '/') *p++ = '/'; *p++ = '*'; *p = '\0'; /* * Open stream. */ dir->handle = opendir(dirname); if (dir->handle == NULL) return isc__errno2result(errno); return (result); } /*! * \brief Return previously retrieved file or get next one. * Unix's dirent has * separate open and read functions, but the Win32 and DOS interfaces open * the dir stream and reads the first file in one operation. */ isc_result_t isc_dir_read(isc_dir_t *dir) { struct dirent *entry; REQUIRE(VALID_DIR(dir) && dir->handle != NULL); /* * Fetch next file in directory. */ entry = readdir(dir->handle); if (entry == NULL) return (ISC_R_NOMORE); /* * Make sure that the space for the name is long enough. */ if (sizeof(dir->entry.name) <= strlen(entry->d_name)) return (ISC_R_UNEXPECTED); strcpy(dir->entry.name, entry->d_name); /* * Some dirents have d_namlen, but it is not portable. */ dir->entry.length = strlen(entry->d_name); return (ISC_R_SUCCESS); } /*! * \brief Close directory stream. */ void isc_dir_close(isc_dir_t *dir) { REQUIRE(VALID_DIR(dir) && dir->handle != NULL); (void)closedir(dir->handle); dir->handle = NULL; } /*! * \brief Reposition directory stream at start. */ isc_result_t isc_dir_reset(isc_dir_t *dir) { REQUIRE(VALID_DIR(dir) && dir->handle != NULL); rewinddir(dir->handle); return (ISC_R_SUCCESS); } isc_result_t isc_dir_chdir(const char *dirname) { /*! * \brief Change the current directory to 'dirname'. */ REQUIRE(dirname != NULL); if (chdir(dirname) < 0) return (isc__errno2result(errno)); return (ISC_R_SUCCESS); } isc_result_t isc_dir_chroot(const char *dirname) { REQUIRE(dirname != NULL); #ifdef HAVE_CHROOT if (chroot(dirname) < 0 || chdir("/") < 0) return (isc__errno2result(errno)); return (ISC_R_SUCCESS); #else return (ISC_R_NOTIMPLEMENTED); #endif } isc_result_t isc_dir_createunique(char *templet) { isc_result_t result; char *x; char *p; int i; int pid; REQUIRE(templet != NULL); /*! * \brief mkdtemp is not portable, so this emulates it. */ pid = getpid(); /* * Replace trailing Xs with the process-id, zero-filled. */ for (x = templet + strlen(templet) - 1; *x == 'X' && x >= templet; x--, pid /= 10) *x = pid % 10 + '0'; x++; /* Set x to start of ex-Xs. */ do { i = mkdir(templet, 0700); if (i == 0 || errno != EEXIST) break; /* * The BSD algorithm. */ p = x; while (*p != '\0') { if (isdigit(*p & 0xff)) *p = 'a'; else if (*p != 'z') ++*p; else { /* * Reset character and move to next. */ *p++ = 'a'; continue; } break; } if (*p == '\0') { /* * Tried all combinations. errno should already * be EEXIST, but ensure it is anyway for * isc__errno2result(). */ errno = EEXIST; break; } } while (1); if (i == -1) result = isc__errno2result(errno); else result = ISC_R_SUCCESS; return (result); } bind9-9.10.3.dfsg.P4/lib/isc/unix/fsaccess.c0000644000470500017500000000455712664710322017651 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: fsaccess.c,v 1.13 2007/06/19 23:47:18 tbox Exp $ */ #include #include #include #include #include "errno2result.h" /*! \file * \brief * The OS-independent part of the API is in lib/isc. */ #include "../fsaccess.c" isc_result_t isc_fsaccess_set(const char *path, isc_fsaccess_t access) { struct stat statb; mode_t mode; isc_boolean_t is_dir = ISC_FALSE; isc_fsaccess_t bits; isc_result_t result; if (stat(path, &statb) != 0) return (isc__errno2result(errno)); if ((statb.st_mode & S_IFDIR) != 0) is_dir = ISC_TRUE; else if ((statb.st_mode & S_IFREG) == 0) return (ISC_R_INVALIDFILE); result = check_bad_bits(access, is_dir); if (result != ISC_R_SUCCESS) return (result); /* * Done with checking bad bits. Set mode_t. */ mode = 0; #define SET_AND_CLEAR1(modebit) \ if ((access & bits) != 0) { \ mode |= modebit; \ access &= ~bits; \ } #define SET_AND_CLEAR(user, group, other) \ SET_AND_CLEAR1(user); \ bits <<= STEP; \ SET_AND_CLEAR1(group); \ bits <<= STEP; \ SET_AND_CLEAR1(other); bits = ISC_FSACCESS_READ | ISC_FSACCESS_LISTDIRECTORY; SET_AND_CLEAR(S_IRUSR, S_IRGRP, S_IROTH); bits = ISC_FSACCESS_WRITE | ISC_FSACCESS_CREATECHILD | ISC_FSACCESS_DELETECHILD; SET_AND_CLEAR(S_IWUSR, S_IWGRP, S_IWOTH); bits = ISC_FSACCESS_EXECUTE | ISC_FSACCESS_ACCESSCHILD; SET_AND_CLEAR(S_IXUSR, S_IXGRP, S_IXOTH); INSIST(access == 0); if (chmod(path, mode) < 0) return (isc__errno2result(errno)); return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/isc/unix/time.c0000644000470500017500000002610512664710322017006 0ustar lamontlamont/* * Copyright (C) 2004-2008, 2011, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include /* Required for struct timeval on some platforms. */ #include #include #include #include #include #include #include #define NS_PER_S 1000000000 /*%< Nanoseconds per second. */ #define NS_PER_US 1000 /*%< Nanoseconds per microsecond. */ #define US_PER_S 1000000 /*%< Microseconds per second. */ /* * All of the INSIST()s checks of nanoseconds < NS_PER_S are for * consistency checking of the type. In lieu of magic numbers, it * is the best we've got. The check is only performed on functions which * need an initialized type. */ #ifndef ISC_FIX_TV_USEC #define ISC_FIX_TV_USEC 1 #endif /*% *** Intervals ***/ static const isc_interval_t zero_interval = { 0, 0 }; const isc_interval_t * const isc_interval_zero = &zero_interval; #if ISC_FIX_TV_USEC static inline void fix_tv_usec(struct timeval *tv) { isc_boolean_t fixed = ISC_FALSE; if (tv->tv_usec < 0) { fixed = ISC_TRUE; do { tv->tv_sec -= 1; tv->tv_usec += US_PER_S; } while (tv->tv_usec < 0); } else if (tv->tv_usec >= US_PER_S) { fixed = ISC_TRUE; do { tv->tv_sec += 1; tv->tv_usec -= US_PER_S; } while (tv->tv_usec >=US_PER_S); } /* * Call syslog directly as was are called from the logging functions. */ if (fixed) (void)syslog(LOG_ERR, "gettimeofday returned bad tv_usec: corrected"); } #endif void isc_interval_set(isc_interval_t *i, unsigned int seconds, unsigned int nanoseconds) { REQUIRE(i != NULL); REQUIRE(nanoseconds < NS_PER_S); i->seconds = seconds; i->nanoseconds = nanoseconds; } isc_boolean_t isc_interval_iszero(const isc_interval_t *i) { REQUIRE(i != NULL); INSIST(i->nanoseconds < NS_PER_S); if (i->seconds == 0 && i->nanoseconds == 0) return (ISC_TRUE); return (ISC_FALSE); } /*** *** Absolute Times ***/ static const isc_time_t epoch = { 0, 0 }; const isc_time_t * const isc_time_epoch = &epoch; void isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) { REQUIRE(t != NULL); REQUIRE(nanoseconds < NS_PER_S); t->seconds = seconds; t->nanoseconds = nanoseconds; } void isc_time_settoepoch(isc_time_t *t) { REQUIRE(t != NULL); t->seconds = 0; t->nanoseconds = 0; } isc_boolean_t isc_time_isepoch(const isc_time_t *t) { REQUIRE(t != NULL); INSIST(t->nanoseconds < NS_PER_S); if (t->seconds == 0 && t->nanoseconds == 0) return (ISC_TRUE); return (ISC_FALSE); } isc_result_t isc_time_now(isc_time_t *t) { struct timeval tv; char strbuf[ISC_STRERRORSIZE]; REQUIRE(t != NULL); if (gettimeofday(&tv, NULL) == -1) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", strbuf); return (ISC_R_UNEXPECTED); } /* * Does POSIX guarantee the signedness of tv_sec and tv_usec? If not, * then this test will generate warnings for platforms on which it is * unsigned. In any event, the chances of any of these problems * happening are pretty much zero, but since the libisc library ensures * certain things to be true ... */ #if ISC_FIX_TV_USEC fix_tv_usec(&tv); if (tv.tv_sec < 0) return (ISC_R_UNEXPECTED); #else if (tv.tv_sec < 0 || tv.tv_usec < 0 || tv.tv_usec >= US_PER_S) return (ISC_R_UNEXPECTED); #endif /* * Ensure the tv_sec value fits in t->seconds. */ if (sizeof(tv.tv_sec) > sizeof(t->seconds) && ((tv.tv_sec | (unsigned int)-1) ^ (unsigned int)-1) != 0U) return (ISC_R_RANGE); t->seconds = tv.tv_sec; t->nanoseconds = tv.tv_usec * NS_PER_US; return (ISC_R_SUCCESS); } isc_result_t isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i) { struct timeval tv; char strbuf[ISC_STRERRORSIZE]; REQUIRE(t != NULL); REQUIRE(i != NULL); INSIST(i->nanoseconds < NS_PER_S); if (gettimeofday(&tv, NULL) == -1) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", strbuf); return (ISC_R_UNEXPECTED); } /* * Does POSIX guarantee the signedness of tv_sec and tv_usec? If not, * then this test will generate warnings for platforms on which it is * unsigned. In any event, the chances of any of these problems * happening are pretty much zero, but since the libisc library ensures * certain things to be true ... */ #if ISC_FIX_TV_USEC fix_tv_usec(&tv); if (tv.tv_sec < 0) return (ISC_R_UNEXPECTED); #else if (tv.tv_sec < 0 || tv.tv_usec < 0 || tv.tv_usec >= US_PER_S) return (ISC_R_UNEXPECTED); #endif /* * Ensure the resulting seconds value fits in the size of an * unsigned int. (It is written this way as a slight optimization; * note that even if both values == INT_MAX, then when added * and getting another 1 added below the result is UINT_MAX.) */ if ((tv.tv_sec > INT_MAX || i->seconds > INT_MAX) && ((long long)tv.tv_sec + i->seconds > UINT_MAX)) return (ISC_R_RANGE); t->seconds = tv.tv_sec + i->seconds; t->nanoseconds = tv.tv_usec * NS_PER_US + i->nanoseconds; if (t->nanoseconds >= NS_PER_S) { t->seconds++; t->nanoseconds -= NS_PER_S; } return (ISC_R_SUCCESS); } int isc_time_compare(const isc_time_t *t1, const isc_time_t *t2) { REQUIRE(t1 != NULL && t2 != NULL); INSIST(t1->nanoseconds < NS_PER_S && t2->nanoseconds < NS_PER_S); if (t1->seconds < t2->seconds) return (-1); if (t1->seconds > t2->seconds) return (1); if (t1->nanoseconds < t2->nanoseconds) return (-1); if (t1->nanoseconds > t2->nanoseconds) return (1); return (0); } isc_result_t isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result) { REQUIRE(t != NULL && i != NULL && result != NULL); INSIST(t->nanoseconds < NS_PER_S && i->nanoseconds < NS_PER_S); /* * Ensure the resulting seconds value fits in the size of an * unsigned int. (It is written this way as a slight optimization; * note that even if both values == INT_MAX, then when added * and getting another 1 added below the result is UINT_MAX.) */ if ((t->seconds > INT_MAX || i->seconds > INT_MAX) && ((long long)t->seconds + i->seconds > UINT_MAX)) return (ISC_R_RANGE); result->seconds = t->seconds + i->seconds; result->nanoseconds = t->nanoseconds + i->nanoseconds; if (result->nanoseconds >= NS_PER_S) { result->seconds++; result->nanoseconds -= NS_PER_S; } return (ISC_R_SUCCESS); } isc_result_t isc_time_subtract(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result) { REQUIRE(t != NULL && i != NULL && result != NULL); INSIST(t->nanoseconds < NS_PER_S && i->nanoseconds < NS_PER_S); if ((unsigned int)t->seconds < i->seconds || ((unsigned int)t->seconds == i->seconds && t->nanoseconds < i->nanoseconds)) return (ISC_R_RANGE); result->seconds = t->seconds - i->seconds; if (t->nanoseconds >= i->nanoseconds) result->nanoseconds = t->nanoseconds - i->nanoseconds; else { result->nanoseconds = NS_PER_S - i->nanoseconds + t->nanoseconds; result->seconds--; } return (ISC_R_SUCCESS); } isc_uint64_t isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2) { isc_uint64_t i1, i2, i3; REQUIRE(t1 != NULL && t2 != NULL); INSIST(t1->nanoseconds < NS_PER_S && t2->nanoseconds < NS_PER_S); i1 = (isc_uint64_t)t1->seconds * NS_PER_S + t1->nanoseconds; i2 = (isc_uint64_t)t2->seconds * NS_PER_S + t2->nanoseconds; if (i1 <= i2) return (0); i3 = i1 - i2; /* * Convert to microseconds. */ i3 /= NS_PER_US; return (i3); } isc_uint32_t isc_time_seconds(const isc_time_t *t) { REQUIRE(t != NULL); INSIST(t->nanoseconds < NS_PER_S); return ((isc_uint32_t)t->seconds); } isc_result_t isc_time_secondsastimet(const isc_time_t *t, time_t *secondsp) { time_t seconds; REQUIRE(t != NULL); INSIST(t->nanoseconds < NS_PER_S); /* * Ensure that the number of seconds represented by t->seconds * can be represented by a time_t. Since t->seconds is an unsigned * int and since time_t is mostly opaque, this is trickier than * it seems. (This standardized opaqueness of time_t is *very* * frustrating; time_t is not even limited to being an integral * type.) * * The mission, then, is to avoid generating any kind of warning * about "signed versus unsigned" while trying to determine if the * the unsigned int t->seconds is out range for tv_sec, which is * pretty much only true if time_t is a signed integer of the same * size as the return value of isc_time_seconds. * * If the paradox in the if clause below is true, t->seconds is out * of range for time_t. */ seconds = (time_t)t->seconds; INSIST(sizeof(unsigned int) == sizeof(isc_uint32_t)); INSIST(sizeof(time_t) >= sizeof(isc_uint32_t)); if (t->seconds > (~0U>>1) && seconds <= (time_t)(~0U>>1)) return (ISC_R_RANGE); *secondsp = seconds; return (ISC_R_SUCCESS); } isc_uint32_t isc_time_nanoseconds(const isc_time_t *t) { REQUIRE(t != NULL); ENSURE(t->nanoseconds < NS_PER_S); return ((isc_uint32_t)t->nanoseconds); } void isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len) { time_t now; unsigned int flen; REQUIRE(len > 0); now = (time_t) t->seconds; flen = strftime(buf, len, "%d-%b-%Y %X", localtime(&now)); INSIST(flen < len); if (flen != 0) snprintf(buf + flen, len - flen, ".%03u", t->nanoseconds / 1000000); else snprintf(buf, len, "99-Bad-9999 99:99:99.999"); } void isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len) { time_t now; unsigned int flen; REQUIRE(len > 0); /* * 5 spaces, 1 comma, 3 GMT, 2 %d, 4 %Y, 8 %H:%M:%S, 3+ %a, 3+ %b (29+) */ now = (time_t)t->seconds; flen = strftime(buf, len, "%a, %d %b %Y %H:%M:%S GMT", gmtime(&now)); INSIST(flen < len); } isc_result_t isc_time_parsehttptimestamp(char *buf, isc_time_t *t) { struct tm t_tm; time_t when; char *p; REQUIRE(buf != NULL); REQUIRE(t != NULL); p = isc_tm_strptime(buf, "%a, %d %b %Y %H:%M:%S", &t_tm); if (p == NULL) return (ISC_R_UNEXPECTED); when = isc_tm_timegm(&t_tm); if (when == -1) return (ISC_R_UNEXPECTED); isc_time_set(t, when, 0); return (ISC_R_SUCCESS); } void isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len) { time_t now; unsigned int flen; REQUIRE(len > 0); now = (time_t)t->seconds; flen = strftime(buf, len, "%Y-%m-%dT%H:%M:%SZ", gmtime(&now)); INSIST(flen < len); } bind9-9.10.3.dfsg.P4/lib/isc/unix/ifiter_sysctl.c0000644000470500017500000001740712664710322020740 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ifiter_sysctl.c,v 1.25 2007/06/19 23:47:18 tbox Exp $ */ /*! \file * \brief * Obtain the list of network interfaces using sysctl. * See TCP/IP Illustrated Volume 2, sections 19.8, 19.14, * and 19.16. */ #include #include #include #include #include /* XXX what about Alpha? */ #ifdef sgi #define ROUNDUP(a) ((a) > 0 ? \ (1 + (((a) - 1) | (sizeof(__uint64_t) - 1))) : \ sizeof(__uint64_t)) #else #define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) \ : sizeof(long)) #endif #define IFITER_MAGIC ISC_MAGIC('I', 'F', 'I', 'S') #define VALID_IFITER(t) ISC_MAGIC_VALID(t, IFITER_MAGIC) struct isc_interfaceiter { unsigned int magic; /* Magic number. */ isc_mem_t *mctx; void *buf; /* Buffer for sysctl data. */ unsigned int bufsize; /* Bytes allocated. */ unsigned int bufused; /* Bytes used. */ unsigned int pos; /* Current offset in sysctl data. */ isc_interface_t current; /* Current interface data. */ isc_result_t result; /* Last result code. */ }; static int mib[6] = { CTL_NET, PF_ROUTE, 0, 0, /* Any address family. */ NET_RT_IFLIST, 0 /* Flags. */ }; isc_result_t isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { isc_interfaceiter_t *iter; isc_result_t result; size_t bufsize; size_t bufused; char strbuf[ISC_STRERRORSIZE]; REQUIRE(mctx != NULL); REQUIRE(iterp != NULL); REQUIRE(*iterp == NULL); iter = isc_mem_get(mctx, sizeof(*iter)); if (iter == NULL) return (ISC_R_NOMEMORY); iter->mctx = mctx; iter->buf = 0; /* * Determine the amount of memory needed. */ bufsize = 0; if (sysctl(mib, 6, NULL, &bufsize, NULL, (size_t) 0) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERSYSCTL, ISC_MSG_GETIFLISTSIZE, "getting interface " "list size: sysctl: %s"), strbuf); result = ISC_R_UNEXPECTED; goto failure; } iter->bufsize = bufsize; iter->buf = isc_mem_get(iter->mctx, iter->bufsize); if (iter->buf == NULL) { result = ISC_R_NOMEMORY; goto failure; } bufused = bufsize; if (sysctl(mib, 6, iter->buf, &bufused, NULL, (size_t) 0) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERSYSCTL, ISC_MSG_GETIFLIST, "getting interface list: " "sysctl: %s"), strbuf); result = ISC_R_UNEXPECTED; goto failure; } iter->bufused = bufused; INSIST(iter->bufused <= iter->bufsize); /* * A newly created iterator has an undefined position * until isc_interfaceiter_first() is called. */ iter->pos = (unsigned int) -1; iter->result = ISC_R_FAILURE; iter->magic = IFITER_MAGIC; *iterp = iter; return (ISC_R_SUCCESS); failure: if (iter->buf != NULL) isc_mem_put(mctx, iter->buf, iter->bufsize); isc_mem_put(mctx, iter, sizeof(*iter)); return (result); } /* * Get information about the current interface to iter->current. * If successful, return ISC_R_SUCCESS. * If the interface has an unsupported address family, * return ISC_R_IGNORE. In case of other failure, * return ISC_R_UNEXPECTED. */ static isc_result_t internal_current(isc_interfaceiter_t *iter) { struct ifa_msghdr *ifam, *ifam_end; REQUIRE(VALID_IFITER(iter)); REQUIRE (iter->pos < (unsigned int) iter->bufused); ifam = (struct ifa_msghdr *) ((char *) iter->buf + iter->pos); ifam_end = (struct ifa_msghdr *) ((char *) iter->buf + iter->bufused); if (ifam->ifam_type == RTM_IFINFO) { struct if_msghdr *ifm = (struct if_msghdr *) ifam; struct sockaddr_dl *sdl = (struct sockaddr_dl *) (ifm + 1); unsigned int namelen; memset(&iter->current, 0, sizeof(iter->current)); namelen = sdl->sdl_nlen; if (namelen > sizeof(iter->current.name) - 1) namelen = sizeof(iter->current.name) - 1; memset(iter->current.name, 0, sizeof(iter->current.name)); memmove(iter->current.name, sdl->sdl_data, namelen); iter->current.flags = 0; if ((ifam->ifam_flags & IFF_UP) != 0) iter->current.flags |= INTERFACE_F_UP; if ((ifam->ifam_flags & IFF_POINTOPOINT) != 0) iter->current.flags |= INTERFACE_F_POINTTOPOINT; if ((ifam->ifam_flags & IFF_LOOPBACK) != 0) iter->current.flags |= INTERFACE_F_LOOPBACK; /* * This is not an interface address. * Force another iteration. */ return (ISC_R_IGNORE); } else if (ifam->ifam_type == RTM_NEWADDR) { int i; int family; struct sockaddr *mask_sa = NULL; struct sockaddr *addr_sa = NULL; struct sockaddr *dst_sa = NULL; struct sockaddr *sa = (struct sockaddr *)(ifam + 1); family = sa->sa_family; for (i = 0; i < RTAX_MAX; i++) { if ((ifam->ifam_addrs & (1 << i)) == 0) continue; INSIST(sa < (struct sockaddr *) ifam_end); switch (i) { case RTAX_NETMASK: /* Netmask */ mask_sa = sa; break; case RTAX_IFA: /* Interface address */ addr_sa = sa; break; case RTAX_BRD: /* Broadcast or destination address */ dst_sa = sa; break; } #ifdef ISC_PLATFORM_HAVESALEN sa = (struct sockaddr *)((char*)(sa) + ROUNDUP(sa->sa_len)); #else #ifdef sgi /* * Do as the contributed SGI code does. */ sa = (struct sockaddr *)((char*)(sa) + ROUNDUP(_FAKE_SA_LEN_DST(sa))); #else /* XXX untested. */ sa = (struct sockaddr *)((char*)(sa) + ROUNDUP(sizeof(struct sockaddr))); #endif #endif } if (addr_sa == NULL) return (ISC_R_IGNORE); family = addr_sa->sa_family; if (family != AF_INET && family != AF_INET6) return (ISC_R_IGNORE); iter->current.af = family; get_addr(family, &iter->current.address, addr_sa, iter->current.name); if (mask_sa != NULL) get_addr(family, &iter->current.netmask, mask_sa, iter->current.name); if (dst_sa != NULL && (iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) get_addr(family, &iter->current.dstaddress, dst_sa, iter->current.name); return (ISC_R_SUCCESS); } else { printf(isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERSYSCTL, ISC_MSG_UNEXPECTEDTYPE, "warning: unexpected interface list " "message type\n")); return (ISC_R_IGNORE); } } /* * Step the iterator to the next interface. Unlike * isc_interfaceiter_next(), this may leave the iterator * positioned on an interface that will ultimately * be ignored. Return ISC_R_NOMORE if there are no more * interfaces, otherwise ISC_R_SUCCESS. */ static isc_result_t internal_next(isc_interfaceiter_t *iter) { struct ifa_msghdr *ifam; REQUIRE (iter->pos < (unsigned int) iter->bufused); ifam = (struct ifa_msghdr *) ((char *) iter->buf + iter->pos); iter->pos += ifam->ifam_msglen; if (iter->pos >= iter->bufused) return (ISC_R_NOMORE); return (ISC_R_SUCCESS); } static void internal_destroy(isc_interfaceiter_t *iter) { UNUSED(iter); /* Unused. */ /* * Do nothing. */ } static void internal_first(isc_interfaceiter_t *iter) { iter->pos = 0; } bind9-9.10.3.dfsg.P4/lib/isc/refcount.c0000644000470500017500000000232212664710322016705 0ustar lamontlamont/* * Copyright (C) 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: refcount.c,v 1.5 2007/06/19 23:47:17 tbox Exp $ */ #include #include #include #include #include isc_result_t isc_refcount_init(isc_refcount_t *ref, unsigned int n) { REQUIRE(ref != NULL); ref->refs = n; #if defined(ISC_PLATFORM_USETHREADS) && !defined(ISC_PLATFORM_HAVEXADD) return (isc_mutex_init(&ref->lock)); #else return (ISC_R_SUCCESS); #endif } bind9-9.10.3.dfsg.P4/lib/isc/serial.c0000644000470500017500000000335312664710322016344 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: serial.c,v 1.12 2007/06/19 23:47:17 tbox Exp $ */ /*! \file */ #include #include isc_boolean_t isc_serial_lt(isc_uint32_t a, isc_uint32_t b) { /* * Undefined => ISC_FALSE */ if (a == (b ^ 0x80000000U)) return (ISC_FALSE); return (((isc_int32_t)(a - b) < 0) ? ISC_TRUE : ISC_FALSE); } isc_boolean_t isc_serial_gt(isc_uint32_t a, isc_uint32_t b) { return (((isc_int32_t)(a - b) > 0) ? ISC_TRUE : ISC_FALSE); } isc_boolean_t isc_serial_le(isc_uint32_t a, isc_uint32_t b) { return ((a == b) ? ISC_TRUE : isc_serial_lt(a, b)); } isc_boolean_t isc_serial_ge(isc_uint32_t a, isc_uint32_t b) { return ((a == b) ? ISC_TRUE : isc_serial_gt(a, b)); } isc_boolean_t isc_serial_eq(isc_uint32_t a, isc_uint32_t b) { return ((a == b) ? ISC_TRUE : ISC_FALSE); } isc_boolean_t isc_serial_ne(isc_uint32_t a, isc_uint32_t b) { return ((a != b) ? ISC_TRUE : ISC_FALSE); } bind9-9.10.3.dfsg.P4/lib/isc/timer_p.h0000644000470500017500000000220212664710322016521 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: timer_p.h,v 1.12 2009/09/02 23:48:02 tbox Exp $ */ #ifndef ISC_TIMER_P_H #define ISC_TIMER_P_H /*! \file */ isc_result_t isc__timermgr_nextevent(isc_timermgr_t *timermgr, isc_time_t *when); void isc__timermgr_dispatch(isc_timermgr_t *timermgr); #endif /* ISC_TIMER_P_H */ bind9-9.10.3.dfsg.P4/lib/isc/sha1.c0000644000470500017500000002712312664710322015722 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* $NetBSD: sha1.c,v 1.5 2000/01/22 22:19:14 mycroft Exp $ */ /* $OpenBSD: sha1.c,v 1.9 1997/07/23 21:12:32 kstailey Exp $ */ /*! \file * SHA-1 in C * \author By Steve Reid * 100% Public Domain * \verbatim * Test Vectors (from FIPS PUB 180-1) * "abc" * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 * A million repetitions of "a" * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F * \endverbatim */ #include "config.h" #include #include #include #include #include #include #if PKCS11CRYPTO #include #include #endif #ifdef ISC_PLATFORM_OPENSSLHASH void isc_sha1_init(isc_sha1_t *context) { INSIST(context != NULL); RUNTIME_CHECK(EVP_DigestInit(context, EVP_sha1()) == 1); } void isc_sha1_invalidate(isc_sha1_t *context) { EVP_MD_CTX_cleanup(context); } void isc_sha1_update(isc_sha1_t *context, const unsigned char *data, unsigned int len) { INSIST(context != 0); INSIST(data != 0); RUNTIME_CHECK(EVP_DigestUpdate(context, (const void *) data, (size_t) len) == 1); } void isc_sha1_final(isc_sha1_t *context, unsigned char *digest) { INSIST(digest != 0); INSIST(context != 0); RUNTIME_CHECK(EVP_DigestFinal(context, digest, NULL) == 1); } #elif PKCS11CRYPTO void isc_sha1_init(isc_sha1_t *ctx) { CK_RV rv; CK_MECHANISM mech = { CKM_SHA_1, NULL, 0 }; RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech)); } void isc_sha1_invalidate(isc_sha1_t *ctx) { CK_BYTE garbage[ISC_SHA1_DIGESTLENGTH]; CK_ULONG len = ISC_SHA1_DIGESTLENGTH; if (ctx->handle == NULL) return; (void) pkcs_C_DigestFinal(ctx->session, garbage, &len); memset(garbage, 0, sizeof(garbage)); pk11_return_session(ctx); } void isc_sha1_update(isc_sha1_t *ctx, const unsigned char *buf, unsigned int len) { CK_RV rv; CK_BYTE_PTR pPart; DE_CONST(buf, pPart); PK11_FATALCHECK(pkcs_C_DigestUpdate, (ctx->session, pPart, (CK_ULONG) len)); } void isc_sha1_final(isc_sha1_t *ctx, unsigned char *digest) { CK_RV rv; CK_ULONG len = ISC_SHA1_DIGESTLENGTH; PK11_FATALCHECK(pkcs_C_DigestFinal, (ctx->session, (CK_BYTE_PTR) digest, &len)); pk11_return_session(ctx); } #else #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) /*@{*/ /*! * blk0() and blk() perform the initial expand. * I got the idea of expanding during the round function from SSLeay */ #if !defined(WORDS_BIGENDIAN) # define blk0(i) \ (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) \ | (rol(block->l[i], 8) & 0x00FF00FF)) #else # define blk0(i) block->l[i] #endif #define blk(i) \ (block->l[i & 15] = rol(block->l[(i + 13) & 15] \ ^ block->l[(i + 8) & 15] \ ^ block->l[(i + 2) & 15] \ ^ block->l[i & 15], 1)) /*@}*/ /*@{*/ /*! * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 */ #define R0(v,w,x,y,z,i) \ z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \ w = rol(w, 30); #define R1(v,w,x,y,z,i) \ z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \ w = rol(w, 30); #define R2(v,w,x,y,z,i) \ z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); \ w = rol(w, 30); #define R3(v,w,x,y,z,i) \ z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \ w = rol(w, 30); #define R4(v,w,x,y,z,i) \ z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \ w = rol(w, 30); /*@}*/ typedef union { unsigned char c[64]; unsigned int l[16]; } CHAR64LONG16; #ifdef __sparc_v9__ static void do_R01(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, isc_uint32_t *d, isc_uint32_t *e, CHAR64LONG16 *); static void do_R2(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, isc_uint32_t *d, isc_uint32_t *e, CHAR64LONG16 *); static void do_R3(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, isc_uint32_t *d, isc_uint32_t *e, CHAR64LONG16 *); static void do_R4(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, isc_uint32_t *d, isc_uint32_t *e, CHAR64LONG16 *); #define nR0(v,w,x,y,z,i) R0(*v,*w,*x,*y,*z,i) #define nR1(v,w,x,y,z,i) R1(*v,*w,*x,*y,*z,i) #define nR2(v,w,x,y,z,i) R2(*v,*w,*x,*y,*z,i) #define nR3(v,w,x,y,z,i) R3(*v,*w,*x,*y,*z,i) #define nR4(v,w,x,y,z,i) R4(*v,*w,*x,*y,*z,i) static void do_R01(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, isc_uint32_t *d, isc_uint32_t *e, CHAR64LONG16 *block) { nR0(a,b,c,d,e, 0); nR0(e,a,b,c,d, 1); nR0(d,e,a,b,c, 2); nR0(c,d,e,a,b, 3); nR0(b,c,d,e,a, 4); nR0(a,b,c,d,e, 5); nR0(e,a,b,c,d, 6); nR0(d,e,a,b,c, 7); nR0(c,d,e,a,b, 8); nR0(b,c,d,e,a, 9); nR0(a,b,c,d,e,10); nR0(e,a,b,c,d,11); nR0(d,e,a,b,c,12); nR0(c,d,e,a,b,13); nR0(b,c,d,e,a,14); nR0(a,b,c,d,e,15); nR1(e,a,b,c,d,16); nR1(d,e,a,b,c,17); nR1(c,d,e,a,b,18); nR1(b,c,d,e,a,19); } static void do_R2(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, isc_uint32_t *d, isc_uint32_t *e, CHAR64LONG16 *block) { nR2(a,b,c,d,e,20); nR2(e,a,b,c,d,21); nR2(d,e,a,b,c,22); nR2(c,d,e,a,b,23); nR2(b,c,d,e,a,24); nR2(a,b,c,d,e,25); nR2(e,a,b,c,d,26); nR2(d,e,a,b,c,27); nR2(c,d,e,a,b,28); nR2(b,c,d,e,a,29); nR2(a,b,c,d,e,30); nR2(e,a,b,c,d,31); nR2(d,e,a,b,c,32); nR2(c,d,e,a,b,33); nR2(b,c,d,e,a,34); nR2(a,b,c,d,e,35); nR2(e,a,b,c,d,36); nR2(d,e,a,b,c,37); nR2(c,d,e,a,b,38); nR2(b,c,d,e,a,39); } static void do_R3(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, isc_uint32_t *d, isc_uint32_t *e, CHAR64LONG16 *block) { nR3(a,b,c,d,e,40); nR3(e,a,b,c,d,41); nR3(d,e,a,b,c,42); nR3(c,d,e,a,b,43); nR3(b,c,d,e,a,44); nR3(a,b,c,d,e,45); nR3(e,a,b,c,d,46); nR3(d,e,a,b,c,47); nR3(c,d,e,a,b,48); nR3(b,c,d,e,a,49); nR3(a,b,c,d,e,50); nR3(e,a,b,c,d,51); nR3(d,e,a,b,c,52); nR3(c,d,e,a,b,53); nR3(b,c,d,e,a,54); nR3(a,b,c,d,e,55); nR3(e,a,b,c,d,56); nR3(d,e,a,b,c,57); nR3(c,d,e,a,b,58); nR3(b,c,d,e,a,59); } static void do_R4(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, isc_uint32_t *d, isc_uint32_t *e, CHAR64LONG16 *block) { nR4(a,b,c,d,e,60); nR4(e,a,b,c,d,61); nR4(d,e,a,b,c,62); nR4(c,d,e,a,b,63); nR4(b,c,d,e,a,64); nR4(a,b,c,d,e,65); nR4(e,a,b,c,d,66); nR4(d,e,a,b,c,67); nR4(c,d,e,a,b,68); nR4(b,c,d,e,a,69); nR4(a,b,c,d,e,70); nR4(e,a,b,c,d,71); nR4(d,e,a,b,c,72); nR4(c,d,e,a,b,73); nR4(b,c,d,e,a,74); nR4(a,b,c,d,e,75); nR4(e,a,b,c,d,76); nR4(d,e,a,b,c,77); nR4(c,d,e,a,b,78); nR4(b,c,d,e,a,79); } #endif /*! * Hash a single 512-bit block. This is the core of the algorithm. */ static void transform(isc_uint32_t state[5], const unsigned char buffer[64]) { isc_uint32_t a, b, c, d, e; CHAR64LONG16 *block; CHAR64LONG16 workspace; INSIST(buffer != NULL); INSIST(state != NULL); block = &workspace; (void)memmove(block, buffer, 64); /* Copy context->state[] to working vars */ a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4]; #ifdef __sparc_v9__ do_R01(&a, &b, &c, &d, &e, block); do_R2(&a, &b, &c, &d, &e, block); do_R3(&a, &b, &c, &d, &e, block); do_R4(&a, &b, &c, &d, &e, block); #else /* 4 rounds of 20 operations each. Loop unrolled. */ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); #endif /* Add the working vars back into context.state[] */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e; /* Wipe variables */ a = b = c = d = e = 0; /* Avoid compiler warnings */ POST(a); POST(b); POST(c); POST(d); POST(e); } /*! * isc_sha1_init - Initialize new context */ void isc_sha1_init(isc_sha1_t *context) { INSIST(context != NULL); /* SHA1 initialization constants */ context->state[0] = 0x67452301; context->state[1] = 0xEFCDAB89; context->state[2] = 0x98BADCFE; context->state[3] = 0x10325476; context->state[4] = 0xC3D2E1F0; context->count[0] = 0; context->count[1] = 0; } void isc_sha1_invalidate(isc_sha1_t *context) { memset(context, 0, sizeof(isc_sha1_t)); } /*! * Run your data through this. */ void isc_sha1_update(isc_sha1_t *context, const unsigned char *data, unsigned int len) { unsigned int i, j; INSIST(context != 0); INSIST(data != 0); j = context->count[0]; if ((context->count[0] += len << 3) < j) context->count[1] += (len >> 29) + 1; j = (j >> 3) & 63; if ((j + len) > 63) { (void)memmove(&context->buffer[j], data, (i = 64 - j)); transform(context->state, context->buffer); for (; i + 63 < len; i += 64) transform(context->state, &data[i]); j = 0; } else { i = 0; } (void)memmove(&context->buffer[j], &data[i], len - i); } /*! * Add padding and return the message digest. */ static const unsigned char final_200 = 128; static const unsigned char final_0 = 0; void isc_sha1_final(isc_sha1_t *context, unsigned char *digest) { unsigned int i; unsigned char finalcount[8]; INSIST(digest != 0); INSIST(context != 0); for (i = 0; i < 8; i++) { /* Endian independent */ finalcount[i] = (unsigned char) ((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255); } isc_sha1_update(context, &final_200, 1); while ((context->count[0] & 504) != 448) isc_sha1_update(context, &final_0, 1); /* The next Update should cause a transform() */ isc_sha1_update(context, finalcount, 8); if (digest) { for (i = 0; i < 20; i++) digest[i] = (unsigned char) ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); } memset(context, 0, sizeof(isc_sha1_t)); } #endif bind9-9.10.3.dfsg.P4/lib/isc/aes.c0000644000470500017500000001223012664710322015627 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file isc/aes.c */ #include "config.h" #include #include #include #include #include #include #ifdef ISC_PLATFORM_WANTAES #if HAVE_OPENSSL_EVP_AES #include void isc_aes128_crypt(const unsigned char *key, const unsigned char *in, unsigned char *out) { EVP_CIPHER_CTX c; int len; EVP_CIPHER_CTX_init(&c); RUNTIME_CHECK(EVP_EncryptInit(&c, EVP_aes_128_ecb(), key, NULL) == 1); EVP_CIPHER_CTX_set_padding(&c, 0); RUNTIME_CHECK(EVP_EncryptUpdate(&c, out, &len, in, ISC_AES_BLOCK_LENGTH) == 1); RUNTIME_CHECK(len == ISC_AES_BLOCK_LENGTH); RUNTIME_CHECK(EVP_CIPHER_CTX_cleanup(&c) == 1); } void isc_aes192_crypt(const unsigned char *key, const unsigned char *in, unsigned char *out) { EVP_CIPHER_CTX c; int len; EVP_CIPHER_CTX_init(&c); RUNTIME_CHECK(EVP_EncryptInit(&c, EVP_aes_192_ecb(), key, NULL) == 1); EVP_CIPHER_CTX_set_padding(&c, 0); RUNTIME_CHECK(EVP_EncryptUpdate(&c, out, &len, in, ISC_AES_BLOCK_LENGTH) == 1); RUNTIME_CHECK(len == ISC_AES_BLOCK_LENGTH); RUNTIME_CHECK(EVP_CIPHER_CTX_cleanup(&c) == 1); } void isc_aes256_crypt(const unsigned char *key, const unsigned char *in, unsigned char *out) { EVP_CIPHER_CTX c; int len; EVP_CIPHER_CTX_init(&c); RUNTIME_CHECK(EVP_EncryptInit(&c, EVP_aes_256_ecb(), key, NULL) == 1); EVP_CIPHER_CTX_set_padding(&c, 0); RUNTIME_CHECK(EVP_EncryptUpdate(&c, out, &len, in, ISC_AES_BLOCK_LENGTH) == 1); RUNTIME_CHECK(len == ISC_AES_BLOCK_LENGTH); RUNTIME_CHECK(EVP_CIPHER_CTX_cleanup(&c) == 1); } #elif HAVE_OPENSSL_AES #include void isc_aes128_crypt(const unsigned char *key, const unsigned char *in, unsigned char *out) { AES_KEY k; RUNTIME_CHECK(AES_set_encrypt_key(key, 128, &k) == 0); AES_encrypt(in, out, &k); } void isc_aes192_crypt(const unsigned char *key, const unsigned char *in, unsigned char *out) { AES_KEY k; RUNTIME_CHECK(AES_set_encrypt_key(key, 192, &k) == 0); AES_encrypt(in, out, &k); } void isc_aes256_crypt(const unsigned char *key, const unsigned char *in, unsigned char *out) { AES_KEY k; RUNTIME_CHECK(AES_set_encrypt_key(key, 256, &k) == 0); AES_encrypt(in, out, &k); } #elif PKCS11CRYPTO #include #include static CK_BBOOL truevalue = TRUE; static CK_BBOOL falsevalue = FALSE; static void isc_aes_crypt(const unsigned char *key, CK_ULONG keylen, const unsigned char *in, unsigned char *out); void isc_aes128_crypt(const unsigned char *key, const unsigned char *in, unsigned char *out) { isc_aes_crypt(key, ISC_AES128_KEYLENGTH, in, out); } void isc_aes192_crypt(const unsigned char *key, const unsigned char *in, unsigned char *out) { isc_aes_crypt(key, ISC_AES192_KEYLENGTH, in, out); } void isc_aes256_crypt(const unsigned char *key, const unsigned char *in, unsigned char *out) { isc_aes_crypt(key, ISC_AES256_KEYLENGTH, in, out); } static void isc_aes_crypt(const unsigned char *key, CK_ULONG keylen, const unsigned char *in, unsigned char *out) { CK_RV rv; CK_MECHANISM mech = { CKM_AES_ECB, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; CK_KEY_TYPE keyType = CKK_AES; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_ENCRYPT, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_VALUE, NULL, keylen } }; CK_ULONG blocklen; CK_BYTE_PTR pData; pk11_context_t ctx; DE_CONST(key, keyTemplate[5].pValue); RUNTIME_CHECK(pk11_get_session(&ctx, OP_AES, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); ctx.object = CK_INVALID_HANDLE; PK11_FATALCHECK(pkcs_C_CreateObject, (ctx.session, keyTemplate, (CK_ULONG) 6, &ctx.object)); INSIST(ctx.object != CK_INVALID_HANDLE); PK11_FATALCHECK(pkcs_C_EncryptInit, (ctx.session, &mech, ctx.object)); DE_CONST(in, pData); blocklen = (CK_ULONG) ISC_AES_BLOCK_LENGTH; PK11_FATALCHECK(pkcs_C_Encrypt, (ctx.session, pData, (CK_ULONG) ISC_AES_BLOCK_LENGTH, out, &blocklen)); RUNTIME_CHECK(blocklen == (CK_ULONG) ISC_AES_BLOCK_LENGTH); (void) pkcs_C_DestroyObject(ctx.session, ctx.object); ctx.object = CK_INVALID_HANDLE; pk11_return_session(&ctx); } #endif #endif /* ISC_PLATFORM_WANTAES */ bind9-9.10.3.dfsg.P4/lib/isc/netaddr.c0000644000470500017500000002345712664710322016515 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2010-2012, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include isc_boolean_t isc_netaddr_equal(const isc_netaddr_t *a, const isc_netaddr_t *b) { REQUIRE(a != NULL && b != NULL); if (a->family != b->family) return (ISC_FALSE); if (a->zone != b->zone) return (ISC_FALSE); switch (a->family) { case AF_INET: if (a->type.in.s_addr != b->type.in.s_addr) return (ISC_FALSE); break; case AF_INET6: if (memcmp(&a->type.in6, &b->type.in6, sizeof(a->type.in6)) != 0 || a->zone != b->zone) return (ISC_FALSE); break; #ifdef ISC_PLATFORM_HAVESYSUNH case AF_UNIX: if (strcmp(a->type.un, b->type.un) != 0) return (ISC_FALSE); break; #endif default: return (ISC_FALSE); } return (ISC_TRUE); } isc_boolean_t isc_netaddr_eqprefix(const isc_netaddr_t *a, const isc_netaddr_t *b, unsigned int prefixlen) { const unsigned char *pa = NULL, *pb = NULL; unsigned int ipabytes = 0; /* Length of whole IP address in bytes */ unsigned int nbytes; /* Number of significant whole bytes */ unsigned int nbits; /* Number of significant leftover bits */ REQUIRE(a != NULL && b != NULL); if (a->family != b->family) return (ISC_FALSE); if (a->zone != b->zone && b->zone != 0) return (ISC_FALSE); switch (a->family) { case AF_INET: pa = (const unsigned char *) &a->type.in; pb = (const unsigned char *) &b->type.in; ipabytes = 4; break; case AF_INET6: pa = (const unsigned char *) &a->type.in6; pb = (const unsigned char *) &b->type.in6; ipabytes = 16; break; default: return (ISC_FALSE); } /* * Don't crash if we get a pattern like 10.0.0.1/9999999. */ if (prefixlen > ipabytes * 8) prefixlen = ipabytes * 8; nbytes = prefixlen / 8; nbits = prefixlen % 8; if (nbytes > 0) { if (memcmp(pa, pb, nbytes) != 0) return (ISC_FALSE); } if (nbits > 0) { unsigned int bytea, byteb, mask; INSIST(nbytes < ipabytes); INSIST(nbits < 8); bytea = pa[nbytes]; byteb = pb[nbytes]; mask = (0xFF << (8-nbits)) & 0xFF; if ((bytea & mask) != (byteb & mask)) return (ISC_FALSE); } return (ISC_TRUE); } isc_result_t isc_netaddr_totext(const isc_netaddr_t *netaddr, isc_buffer_t *target) { char abuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")]; char zbuf[sizeof("%4294967295")]; unsigned int alen; int zlen; const char *r; const void *type; REQUIRE(netaddr != NULL); switch (netaddr->family) { case AF_INET: type = &netaddr->type.in; break; case AF_INET6: type = &netaddr->type.in6; break; #ifdef ISC_PLATFORM_HAVESYSUNH case AF_UNIX: alen = strlen(netaddr->type.un); if (alen > isc_buffer_availablelength(target)) return (ISC_R_NOSPACE); isc_buffer_putmem(target, (const unsigned char *)(netaddr->type.un), alen); return (ISC_R_SUCCESS); #endif default: return (ISC_R_FAILURE); } r = inet_ntop(netaddr->family, type, abuf, sizeof(abuf)); if (r == NULL) return (ISC_R_FAILURE); alen = strlen(abuf); INSIST(alen < sizeof(abuf)); zlen = 0; if (netaddr->family == AF_INET6 && netaddr->zone != 0) { zlen = snprintf(zbuf, sizeof(zbuf), "%%%u", netaddr->zone); if (zlen < 0) return (ISC_R_FAILURE); INSIST((unsigned int)zlen < sizeof(zbuf)); } if (alen + zlen > isc_buffer_availablelength(target)) return (ISC_R_NOSPACE); isc_buffer_putmem(target, (unsigned char *)abuf, alen); isc_buffer_putmem(target, (unsigned char *)zbuf, zlen); return (ISC_R_SUCCESS); } void isc_netaddr_format(const isc_netaddr_t *na, char *array, unsigned int size) { isc_result_t result; isc_buffer_t buf; isc_buffer_init(&buf, array, size); result = isc_netaddr_totext(na, &buf); if (size == 0) return; /* * Null terminate. */ if (result == ISC_R_SUCCESS) { if (isc_buffer_availablelength(&buf) >= 1) isc_buffer_putuint8(&buf, 0); else result = ISC_R_NOSPACE; } if (result != ISC_R_SUCCESS) { snprintf(array, size, isc_msgcat_get(isc_msgcat, ISC_MSGSET_NETADDR, ISC_MSG_UNKNOWNADDR, ""), na->family); array[size - 1] = '\0'; } } isc_result_t isc_netaddr_prefixok(const isc_netaddr_t *na, unsigned int prefixlen) { static const unsigned char zeros[16]; unsigned int nbits, nbytes, ipbytes = 0; const unsigned char *p; switch (na->family) { case AF_INET: p = (const unsigned char *) &na->type.in; ipbytes = 4; if (prefixlen > 32) return (ISC_R_RANGE); break; case AF_INET6: p = (const unsigned char *) &na->type.in6; ipbytes = 16; if (prefixlen > 128) return (ISC_R_RANGE); break; default: return (ISC_R_NOTIMPLEMENTED); } nbytes = prefixlen / 8; nbits = prefixlen % 8; if (nbits != 0) { INSIST(nbytes < ipbytes); if ((p[nbytes] & (0xff>>nbits)) != 0U) return (ISC_R_FAILURE); nbytes++; } if (nbytes < ipbytes && memcmp(p + nbytes, zeros, ipbytes - nbytes) != 0) return (ISC_R_FAILURE); return (ISC_R_SUCCESS); } isc_result_t isc_netaddr_masktoprefixlen(const isc_netaddr_t *s, unsigned int *lenp) { unsigned int nbits = 0, nbytes = 0, ipbytes = 0, i; const unsigned char *p; switch (s->family) { case AF_INET: p = (const unsigned char *) &s->type.in; ipbytes = 4; break; case AF_INET6: p = (const unsigned char *) &s->type.in6; ipbytes = 16; break; default: return (ISC_R_NOTIMPLEMENTED); } for (i = 0; i < ipbytes; i++) { if (p[i] != 0xFF) break; } nbytes = i; if (i < ipbytes) { unsigned int c = p[nbytes]; while ((c & 0x80) != 0 && nbits < 8) { c <<= 1; nbits++; } if ((c & 0xFF) != 0) return (ISC_R_MASKNONCONTIG); i++; } for (; i < ipbytes; i++) { if (p[i] != 0) return (ISC_R_MASKNONCONTIG); i++; } *lenp = nbytes * 8 + nbits; return (ISC_R_SUCCESS); } void isc_netaddr_fromin(isc_netaddr_t *netaddr, const struct in_addr *ina) { memset(netaddr, 0, sizeof(*netaddr)); netaddr->family = AF_INET; netaddr->type.in = *ina; } void isc_netaddr_fromin6(isc_netaddr_t *netaddr, const struct in6_addr *ina6) { memset(netaddr, 0, sizeof(*netaddr)); netaddr->family = AF_INET6; netaddr->type.in6 = *ina6; } isc_result_t isc_netaddr_frompath(isc_netaddr_t *netaddr, const char *path) { #ifdef ISC_PLATFORM_HAVESYSUNH if (strlen(path) > sizeof(netaddr->type.un) - 1) return (ISC_R_NOSPACE); memset(netaddr, 0, sizeof(*netaddr)); netaddr->family = AF_UNIX; strcpy(netaddr->type.un, path); netaddr->zone = 0; return (ISC_R_SUCCESS); #else UNUSED(netaddr); UNUSED(path); return (ISC_R_NOTIMPLEMENTED); #endif } void isc_netaddr_setzone(isc_netaddr_t *netaddr, isc_uint32_t zone) { /* we currently only support AF_INET6. */ REQUIRE(netaddr->family == AF_INET6); netaddr->zone = zone; } isc_uint32_t isc_netaddr_getzone(const isc_netaddr_t *netaddr) { return (netaddr->zone); } void isc_netaddr_fromsockaddr(isc_netaddr_t *t, const isc_sockaddr_t *s) { int family = s->type.sa.sa_family; t->family = family; switch (family) { case AF_INET: t->type.in = s->type.sin.sin_addr; t->zone = 0; break; case AF_INET6: memmove(&t->type.in6, &s->type.sin6.sin6_addr, 16); #ifdef ISC_PLATFORM_HAVESCOPEID t->zone = s->type.sin6.sin6_scope_id; #else t->zone = 0; #endif break; #ifdef ISC_PLATFORM_HAVESYSUNH case AF_UNIX: memmove(t->type.un, s->type.sunix.sun_path, sizeof(t->type.un)); t->zone = 0; break; #endif default: INSIST(0); } } void isc_netaddr_any(isc_netaddr_t *netaddr) { memset(netaddr, 0, sizeof(*netaddr)); netaddr->family = AF_INET; netaddr->type.in.s_addr = INADDR_ANY; } void isc_netaddr_any6(isc_netaddr_t *netaddr) { memset(netaddr, 0, sizeof(*netaddr)); netaddr->family = AF_INET6; netaddr->type.in6 = in6addr_any; } isc_boolean_t isc_netaddr_ismulticast(isc_netaddr_t *na) { switch (na->family) { case AF_INET: return (ISC_TF(ISC_IPADDR_ISMULTICAST(na->type.in.s_addr))); case AF_INET6: return (ISC_TF(IN6_IS_ADDR_MULTICAST(&na->type.in6))); default: return (ISC_FALSE); /* XXXMLG ? */ } } isc_boolean_t isc_netaddr_isexperimental(isc_netaddr_t *na) { switch (na->family) { case AF_INET: return (ISC_TF(ISC_IPADDR_ISEXPERIMENTAL(na->type.in.s_addr))); default: return (ISC_FALSE); /* XXXMLG ? */ } } isc_boolean_t isc_netaddr_islinklocal(isc_netaddr_t *na) { switch (na->family) { case AF_INET: return (ISC_FALSE); case AF_INET6: return (ISC_TF(IN6_IS_ADDR_LINKLOCAL(&na->type.in6))); default: return (ISC_FALSE); } } isc_boolean_t isc_netaddr_issitelocal(isc_netaddr_t *na) { switch (na->family) { case AF_INET: return (ISC_FALSE); case AF_INET6: return (ISC_TF(IN6_IS_ADDR_SITELOCAL(&na->type.in6))); default: return (ISC_FALSE); } } void isc_netaddr_fromv4mapped(isc_netaddr_t *t, const isc_netaddr_t *s) { isc_netaddr_t *src; DE_CONST(s, src); /* Must come before IN6_IS_ADDR_V4MAPPED. */ REQUIRE(s->family == AF_INET6); REQUIRE(IN6_IS_ADDR_V4MAPPED(&src->type.in6)); memset(t, 0, sizeof(*t)); t->family = AF_INET; memmove(&t->type.in, (char *)&src->type.in6 + 12, 4); return; } bind9-9.10.3.dfsg.P4/lib/isc/win32/0002755000470500017500000000000012672612753015671 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/win32/libisc.def.exclude0000644000470500017500000000152212664710322021234 0ustar lamontlamont; These symbols are not needed by the WIN32 build, but build-tarballs ; will complain if they aren't present here. isc_socket_fdwatchcreate isc_socket_fdwatchpoke isc_socket_create isc_socket_dup isc_socket_cancel isc_socket_attach isc_socket_detach isc_socket_open isc_socket_close isc_socket_bind isc_socket_filter isc_socket_listen isc_socket_accept isc_socket_connect isc_socket_getpeername isc_socket_getsockname isc_socket_recv isc_socket_recvv isc_socket_recv2 isc_socket_send isc_socket_sendto isc_socket_sendv isc_socket_sendtov isc_socket_sendtov2 isc_socket_sendto2 isc_socketmgr_create isc_socketmgr_create2 isc_socketmgr_destroy isc_socket_gettype isc_socket_ipv6only isc_socket_dscp isc_socket_cleanunix isc_socket_permunix isc_socket_register isc_print_vsnprintf isc_print_snprintf isc_print_sprintf isc_print_fprintf isc_print_printf bind9-9.10.3.dfsg.P4/lib/isc/win32/strerror.c0000644000470500017500000002360712664710322017715 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001, 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: strerror.c,v 1.8 2007/06/19 23:47:19 tbox Exp $ */ #include #include #include #include #include #include #include #include #include /* * Forward declarations */ char * FormatError(int error); char * GetWSAErrorMessage(int errval); char * NTstrerror(int err, BOOL *bfreebuf); /* * We need to do this this way for profiled locks. */ static isc_mutex_t isc_strerror_lock; static void init_lock(void) { RUNTIME_CHECK(isc_mutex_init(&isc_strerror_lock) == ISC_R_SUCCESS); } /* * This routine needs to free up any buffer allocated by FormatMessage * if that routine gets used. */ void isc__strerror(int num, char *buf, size_t size) { char *msg; BOOL freebuf; unsigned int unum = num; static isc_once_t once = ISC_ONCE_INIT; REQUIRE(buf != NULL); RUNTIME_CHECK(isc_once_do(&once, init_lock) == ISC_R_SUCCESS); LOCK(&isc_strerror_lock); freebuf = FALSE; msg = NTstrerror(num, &freebuf); if (msg != NULL) snprintf(buf, size, "%s", msg); else snprintf(buf, size, "Unknown error: %u", unum); if(freebuf && msg != NULL) { LocalFree(msg); } UNLOCK(&isc_strerror_lock); } /* * Note this will cause a memory leak unless the memory allocated here * is freed by calling LocalFree. isc__strerror does this before unlocking. * This only gets called if there is a system type of error and will likely * be an unusual event. */ char * FormatError(int error) { LPVOID lpMsgBuf = NULL; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, /* Default language */ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); return (lpMsgBuf); } /* * This routine checks the error value and calls the WSA Windows Sockets * Error message function GetWSAErrorMessage below if it's within that range * since those messages are not available in the system error messages. */ char * NTstrerror(int err, BOOL *bfreebuf) { char *retmsg = NULL; /* Copy the error value first in case of other errors */ DWORD errval = err; *bfreebuf = FALSE; /* Get the Winsock2 error messages */ if (errval >= WSABASEERR && errval <= (WSABASEERR + 1015)) { retmsg = GetWSAErrorMessage(errval); if (retmsg != NULL) return (retmsg); } /* * If it's not one of the standard Unix error codes, * try a system error message */ if (errval > (DWORD) _sys_nerr) { *bfreebuf = TRUE; return (FormatError(errval)); } else { return (strerror(errval)); } } /* * This is a replacement for perror */ void __cdecl NTperror(char *errmsg) { /* Copy the error value first in case of other errors */ int errval = errno; BOOL bfreebuf = FALSE; char *msg; msg = NTstrerror(errval, &bfreebuf); fprintf(stderr, "%s: %s\n", errmsg, msg); if(bfreebuf == TRUE) { LocalFree(msg); } } /* * Return the error string related to Winsock2 errors. * This function is necessary since FormatMessage knows nothing about them * and there is no function to get them. */ char * GetWSAErrorMessage(int errval) { char *msg; switch (errval) { case WSAEINTR: msg = "Interrupted system call"; break; case WSAEBADF: msg = "Bad file number"; break; case WSAEACCES: msg = "Permission denied"; break; case WSAEFAULT: msg = "Bad address"; break; case WSAEINVAL: msg = "Invalid argument"; break; case WSAEMFILE: msg = "Too many open sockets"; break; case WSAEWOULDBLOCK: msg = "Operation would block"; break; case WSAEINPROGRESS: msg = "Operation now in progress"; break; case WSAEALREADY: msg = "Operation already in progress"; break; case WSAENOTSOCK: msg = "Socket operation on non-socket"; break; case WSAEDESTADDRREQ: msg = "Destination address required"; break; case WSAEMSGSIZE: msg = "Message too long"; break; case WSAEPROTOTYPE: msg = "Protocol wrong type for socket"; break; case WSAENOPROTOOPT: msg = "Bad protocol option"; break; case WSAEPROTONOSUPPORT: msg = "Protocol not supported"; break; case WSAESOCKTNOSUPPORT: msg = "Socket type not supported"; break; case WSAEOPNOTSUPP: msg = "Operation not supported on socket"; break; case WSAEPFNOSUPPORT: msg = "Protocol family not supported"; break; case WSAEAFNOSUPPORT: msg = "Address family not supported"; break; case WSAEADDRINUSE: msg = "Address already in use"; break; case WSAEADDRNOTAVAIL: msg = "Can't assign requested address"; break; case WSAENETDOWN: msg = "Network is down"; break; case WSAENETUNREACH: msg = "Network is unreachable"; break; case WSAENETRESET: msg = "Net connection reset"; break; case WSAECONNABORTED: msg = "Software caused connection abort"; break; case WSAECONNRESET: msg = "Connection reset by peer"; break; case WSAENOBUFS: msg = "No buffer space available"; break; case WSAEISCONN: msg = "Socket is already connected"; break; case WSAENOTCONN: msg = "Socket is not connected"; break; case WSAESHUTDOWN: msg = "Can't send after socket shutdown"; break; case WSAETOOMANYREFS: msg = "Too many references: can't splice"; break; case WSAETIMEDOUT: msg = "Connection timed out"; break; case WSAECONNREFUSED: msg = "Connection refused"; break; case WSAELOOP: msg = "Too many levels of symbolic links"; break; case WSAENAMETOOLONG: msg = "File name too long"; break; case WSAEHOSTDOWN: msg = "Host is down"; break; case WSAEHOSTUNREACH: msg = "No route to host"; break; case WSAENOTEMPTY: msg = "Directory not empty"; break; case WSAEPROCLIM: msg = "Too many processes"; break; case WSAEUSERS: msg = "Too many users"; break; case WSAEDQUOT: msg = "Disc quota exceeded"; break; case WSAESTALE: msg = "Stale NFS file handle"; break; case WSAEREMOTE: msg = "Too many levels of remote in path"; break; case WSASYSNOTREADY: msg = "Network system is unavailable"; break; case WSAVERNOTSUPPORTED: msg = "Winsock version out of range"; break; case WSANOTINITIALISED: msg = "WSAStartup not yet called"; break; case WSAEDISCON: msg = "Graceful shutdown in progress"; break; /* case WSAHOST_NOT_FOUND: msg = "Host not found"; break; case WSANO_DATA: msg = "No host data of that type was found"; break; */ default: msg = NULL; break; } return (msg); } /* * These error messages are more informative about CryptAPI Errors than the * standard error messages */ char * GetCryptErrorMessage(int errval) { char *msg; switch (errval) { case NTE_BAD_FLAGS: msg = "The dwFlags parameter has an illegal value."; break; case NTE_BAD_KEYSET: msg = "The Registry entry for the key container " "could not be opened and may not exist."; break; case NTE_BAD_KEYSET_PARAM: msg = "The pszContainer or pszProvider parameter " "is set to an illegal value."; break; case NTE_BAD_PROV_TYPE: msg = "The value of the dwProvType parameter is out " "of range. All provider types must be from " "1 to 999, inclusive."; break; case NTE_BAD_SIGNATURE: msg = "The provider DLL signature did not verify " "correctly. Either the DLL or the digital " "signature has been tampered with."; break; case NTE_EXISTS: msg = "The dwFlags parameter is CRYPT_NEWKEYSET, but the key" " container already exists."; break; case NTE_KEYSET_ENTRY_BAD: msg = "The Registry entry for the pszContainer key container " "was found (in the HKEY_CURRENT_USER window), but is " "corrupt. See the section System Administration for " " etails about CryptoAPI's Registry usage."; break; case NTE_KEYSET_NOT_DEF: msg = "No Registry entry exists in the HKEY_CURRENT_USER " "window for the key container specified by " "pszContainer."; break; case NTE_NO_MEMORY: msg = "The CSP ran out of memory during the operation."; break; case NTE_PROV_DLL_NOT_FOUND: msg = "The provider DLL file does not exist or is not on the " "current path."; break; case NTE_PROV_TYPE_ENTRY_BAD: msg = "The Registry entry for the provider type specified by " "dwProvType is corrupt. This error may relate to " "either the user default CSP list or the machine " "default CSP list. See the section System " "Administration for details about CryptoAPI's " "Registry usage."; break; case NTE_PROV_TYPE_NO_MATCH: msg = "The provider type specified by dwProvType does not " "match the provider type found in the Registry. Note " "that this error can only occur when pszProvider " "specifies an actual CSP name."; break; case NTE_PROV_TYPE_NOT_DEF: msg = "No Registry entry exists for the provider type " "specified by dwProvType."; break; case NTE_PROVIDER_DLL_FAIL: msg = "The provider DLL file could not be loaded, and " "may not exist. If it exists, then the file is " "not a valid DLL."; break; case NTE_SIGNATURE_FILE_BAD: msg = "An error occurred while loading the DLL file image, " "prior to verifying its signature."; break; default: msg = NULL; break; } return msg; } bind9-9.10.3.dfsg.P4/lib/isc/win32/ntpaths.c0000644000470500017500000000770212664710322017512 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ntpaths.c,v 1.15 2009/07/14 22:54:57 each Exp $ */ /* * This module fetches the required path information that is specific * to NT systems which can have its configuration and system files * almost anywhere. It can be used to override whatever the application * had previously assigned to the pointer. Basic information about the * file locations are stored in the registry. */ #include #include #include /* * Module Variables */ static char systemDir[MAX_PATH]; static char namedBase[MAX_PATH]; static char ns_confFile[MAX_PATH]; static char lwresd_confFile[MAX_PATH]; static char lwresd_resolvconfFile[MAX_PATH]; static char rndc_confFile[MAX_PATH]; static char ns_defaultpidfile[MAX_PATH]; static char lwresd_defaultpidfile[MAX_PATH]; static char local_state_dir[MAX_PATH]; static char sys_conf_dir[MAX_PATH]; static char rndc_keyFile[MAX_PATH]; static char session_keyFile[MAX_PATH]; static DWORD baseLen = MAX_PATH; static BOOL Initialized = FALSE; void isc_ntpaths_init(void) { HKEY hKey; BOOL keyFound = TRUE; memset(namedBase, 0, MAX_PATH); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, BIND_SUBKEY, 0, KEY_READ, &hKey) != ERROR_SUCCESS) keyFound = FALSE; if (keyFound == TRUE) { /* Get the named directory */ if (RegQueryValueEx(hKey, "InstallDir", NULL, NULL, (LPBYTE)namedBase, &baseLen) != ERROR_SUCCESS) keyFound = FALSE; RegCloseKey(hKey); } GetSystemDirectory(systemDir, MAX_PATH); if (keyFound == FALSE) /* Use the System Directory as a default */ strcpy(namedBase, systemDir); strcpy(ns_confFile, namedBase); strcat(ns_confFile, "\\etc\\named.conf"); strcpy(lwresd_confFile, namedBase); strcat(lwresd_confFile, "\\etc\\lwresd.conf"); strcpy(lwresd_resolvconfFile, systemDir); strcat(lwresd_resolvconfFile, "\\Drivers\\etc\\resolv.conf"); strcpy(rndc_keyFile, namedBase); strcat(rndc_keyFile, "\\etc\\rndc.key"); strcpy(session_keyFile, namedBase); strcat(session_keyFile, "\\etc\\session.key"); strcpy(rndc_confFile, namedBase); strcat(rndc_confFile, "\\etc\\rndc.conf"); strcpy(ns_defaultpidfile, namedBase); strcat(ns_defaultpidfile, "\\etc\\named.pid"); strcpy(lwresd_defaultpidfile, namedBase); strcat(lwresd_defaultpidfile, "\\etc\\lwresd.pid"); strcpy(local_state_dir, namedBase); strcat(local_state_dir, "\\bin"); strcpy(sys_conf_dir, namedBase); strcat(sys_conf_dir, "\\etc"); Initialized = TRUE; } char * isc_ntpaths_get(int ind) { if (!Initialized) isc_ntpaths_init(); switch (ind) { case NAMED_CONF_PATH: return (ns_confFile); break; case LWRES_CONF_PATH: return (lwresd_confFile); break; case RESOLV_CONF_PATH: return (lwresd_resolvconfFile); break; case RNDC_CONF_PATH: return (rndc_confFile); break; case NAMED_PID_PATH: return (ns_defaultpidfile); break; case LWRESD_PID_PATH: return (lwresd_defaultpidfile); break; case LOCAL_STATE_DIR: return (local_state_dir); break; case SYS_CONF_DIR: return (sys_conf_dir); break; case RNDC_KEY_PATH: return (rndc_keyFile); break; case SESSION_KEY_PATH: return (session_keyFile); break; default: return (NULL); } } bind9-9.10.3.dfsg.P4/lib/isc/win32/syslog.c0000644000470500017500000001025012664710322017341 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: syslog.c,v 1.10 2007/06/19 23:47:19 tbox Exp $ */ #include #include #include #include #include #include #include #include #include #include static HANDLE hAppLog = NULL; static FILE *log_stream; static int debug_level = 0; static struct dsn_c_pvt_sfnt { int val; const char *strval; } facilities[] = { { LOG_KERN, "kern" }, { LOG_USER, "user" }, { LOG_MAIL, "mail" }, { LOG_DAEMON, "daemon" }, { LOG_AUTH, "auth" }, { LOG_SYSLOG, "syslog" }, { LOG_LPR, "lpr" }, #ifdef LOG_NEWS { LOG_NEWS, "news" }, #endif #ifdef LOG_UUCP { LOG_UUCP, "uucp" }, #endif #ifdef LOG_CRON { LOG_CRON, "cron" }, #endif #ifdef LOG_AUTHPRIV { LOG_AUTHPRIV, "authpriv" }, #endif #ifdef LOG_FTP { LOG_FTP, "ftp" }, #endif { LOG_LOCAL0, "local0"}, { LOG_LOCAL1, "local1"}, { LOG_LOCAL2, "local2"}, { LOG_LOCAL3, "local3"}, { LOG_LOCAL4, "local4"}, { LOG_LOCAL5, "local5"}, { LOG_LOCAL6, "local6"}, { LOG_LOCAL7, "local7"}, { 0, NULL } }; isc_result_t isc_syslog_facilityfromstring(const char *str, int *facilityp) { int i; REQUIRE(str != NULL); REQUIRE(facilityp != NULL); for (i = 0; facilities[i].strval != NULL; i++) { if (strcasecmp(facilities[i].strval, str) == 0) { *facilityp = facilities[i].val; return (ISC_R_SUCCESS); } } return (ISC_R_NOTFOUND); } /* * Log to the NT Event Log */ void syslog(int level, const char *fmt, ...) { va_list ap; char buf[1024]; char *str[1]; str[0] = buf; va_start(ap, fmt); vsprintf(buf, fmt, ap); va_end(ap); /* Make sure that the channel is open to write the event */ if (hAppLog != NULL) { switch (level) { case LOG_INFO: case LOG_NOTICE: case LOG_DEBUG: ReportEvent(hAppLog, EVENTLOG_INFORMATION_TYPE, 0, BIND_INFO_MSG, NULL, 1, 0, str, NULL); break; case LOG_WARNING: ReportEvent(hAppLog, EVENTLOG_WARNING_TYPE, 0, BIND_WARN_MSG, NULL, 1, 0, str, NULL); break; default: ReportEvent(hAppLog, EVENTLOG_ERROR_TYPE, 0, BIND_ERR_MSG, NULL, 1, 0, str, NULL); break; } } } /* * Initialize event logging */ void openlog(const char *name, int flags, ...) { /* Get a handle to the Application event log */ hAppLog = RegisterEventSource(NULL, name); } /* * Close the Handle to the application Event Log * We don't care whether or not we succeeded so ignore return values * In fact if we failed then we would have nowhere to put the message */ void closelog(void) { DeregisterEventSource(hAppLog); } /* * Keep event logging synced with the current debug level */ void ModifyLogLevel(int level) { debug_level = level; } /* * Initialize logging for the port section of libbind. * Piggyback onto stream given. */ void InitNTLogging(FILE *stream, int debug) { log_stream = stream; ModifyLogLevel(debug); } /* * This function is for reporting errors to the application * event log in case the regular syslog is not available * mainly during startup. It should not be used under normal * circumstances. */ void NTReportError(const char *name, const char *str) { HANDLE hNTAppLog = NULL; const char *buf[1]; buf[0] = str; hNTAppLog = RegisterEventSource(NULL, name); ReportEvent(hNTAppLog, EVENTLOG_ERROR_TYPE, 0, BIND_ERR_MSG, NULL, 1, 0, buf, NULL); DeregisterEventSource(hNTAppLog); } bind9-9.10.3.dfsg.P4/lib/isc/win32/version.c0000644000470500017500000000231312664710322017507 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: version.c,v 1.7 2007/06/19 23:47:19 tbox Exp $ */ #include #include LIBISC_EXTERNAL_DATA const char isc_version[] = VERSION; LIBISC_EXTERNAL_DATA const unsigned int isc_libinterface = LIBINTERFACE; LIBISC_EXTERNAL_DATA const unsigned int isc_librevision = LIBREVISION; LIBISC_EXTERNAL_DATA const unsigned int isc_libage = LIBAGE; bind9-9.10.3.dfsg.P4/lib/isc/win32/libgen.h0000644000470500017500000000167212664710322017276 0ustar lamontlamont/* * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: libgen.h,v 1.3 2009/07/17 23:47:41 tbox Exp $ */ #ifndef LIBGEN_H #define LIBGEN_H 1 char *basename(const char *); char *dirname(const char *); #endif bind9-9.10.3.dfsg.P4/lib/isc/win32/file.c0000644000470500017500000003714312664710322016752 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #include #undef rename #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "errno2result.h" /* * Emulate UNIX mkstemp, which returns an open FD to the new file * */ static int gettemp(char *path, isc_boolean_t binary, int *doopen) { char *start, *trv; struct stat sbuf; int pid; int flags = O_CREAT|O_EXCL|O_RDWR; if (binary) flags |= _O_BINARY; trv = strrchr(path, 'X'); trv++; pid = getpid(); /* extra X's get set to 0's */ while (*--trv == 'X') { *trv = (pid % 10) + '0'; pid /= 10; } /* * check the target directory; if you have six X's and it * doesn't exist this runs for a *very* long time. */ for (start = trv + 1;; --trv) { if (trv <= path) break; if (*trv == '\\') { *trv = '\0'; if (stat(path, &sbuf)) return (0); if (!S_ISDIR(sbuf.st_mode)) { errno = ENOTDIR; return (0); } *trv = '\\'; break; } } for (;;) { if (doopen) { if ((*doopen = open(path, flags, _S_IREAD | _S_IWRITE)) >= 0) return (1); if (errno != EEXIST) return (0); } else if (stat(path, &sbuf)) return (errno == ENOENT ? 1 : 0); /* tricky little algorithm for backward compatibility */ for (trv = start;;) { if (!*trv) return (0); if (*trv == 'z') *trv++ = 'a'; else { if (isdigit(*trv)) *trv = 'a'; else ++*trv; break; } } } /*NOTREACHED*/ } static int mkstemp(char *path, isc_boolean_t binary) { int fd; return (gettemp(path, binary, &fd) ? fd : -1); } /* * XXXDCL As the API for accessing file statistics undoubtedly gets expanded, * it might be good to provide a mechanism that allows for the results * of a previous stat() to be used again without having to do another stat, * such as perl's mechanism of using "_" in place of a file name to indicate * that the results of the last stat should be used. But then you get into * annoying MP issues. BTW, Win32 has stat(). */ static isc_result_t file_stats(const char *file, struct stat *stats) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(file != NULL); REQUIRE(stats != NULL); if (stat(file, stats) != 0) result = isc__errno2result(errno); return (result); } static isc_result_t fd_stats(int fd, struct stat *stats) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(stats != NULL); if (fstat(fd, stats) != 0) result = isc__errno2result(errno); return (result); } isc_result_t isc_file_getsizefd(int fd, off_t *size) { isc_result_t result; struct stat stats; REQUIRE(size != NULL); result = fd_stats(fd, &stats); if (result == ISC_R_SUCCESS) *size = stats.st_size; return (result); } isc_result_t isc_file_mode(const char *file, mode_t *modep) { isc_result_t result; struct stat stats; REQUIRE(modep != NULL); result = file_stats(file, &stats); if (result == ISC_R_SUCCESS) *modep = (stats.st_mode & 07777); return (result); } /* * isc_file_safemovefile is needed to be defined here to ensure that * any file with the new name is renamed to a backup name and then the * rename is done. If all goes well then the backup can be deleted, * otherwise it gets renamed back. */ int isc_file_safemovefile(const char *oldname, const char *newname) { BOOL filestatus; char buf[512]; struct stat sbuf; BOOL exists = FALSE; int tmpfd; /* * Make sure we have something to do */ if (stat(oldname, &sbuf) != 0) { errno = ENOENT; return (-1); } /* * Rename to a backup the new file if it still exists */ if (stat(newname, &sbuf) == 0) { exists = TRUE; strcpy(buf, newname); strcat(buf, ".XXXXX"); tmpfd = mkstemp(buf, ISC_TRUE); if (tmpfd > 0) _close(tmpfd); (void)DeleteFile(buf); _chmod(newname, _S_IREAD | _S_IWRITE); filestatus = MoveFile(newname, buf); } /* Now rename the file to the new name */ _chmod(oldname, _S_IREAD | _S_IWRITE); filestatus = MoveFile(oldname, newname); if (filestatus == 0) { /* * Try to rename the backup back to the original name * if the backup got created */ if (exists == TRUE) { filestatus = MoveFile(buf, newname); if (filestatus == 0) errno = EACCES; } return (-1); } /* * Delete the backup file if it got created */ if (exists == TRUE) (void)DeleteFile(buf); return (0); } isc_result_t isc_file_getmodtime(const char *file, isc_time_t *time) { int fh; REQUIRE(file != NULL); REQUIRE(time != NULL); if ((fh = open(file, _O_RDONLY | _O_BINARY)) < 0) return (isc__errno2result(errno)); if (!GetFileTime((HANDLE) _get_osfhandle(fh), NULL, NULL, &time->absolute)) { close(fh); errno = EINVAL; return (isc__errno2result(errno)); } close(fh); return (ISC_R_SUCCESS); } isc_result_t isc_file_getsize(const char *file, off_t *size) { isc_result_t result; struct stat stats; REQUIRE(file != NULL); REQUIRE(size != NULL); result = file_stats(file, &stats); if (result == ISC_R_SUCCESS) *size = stats.st_size; return (result); } isc_result_t isc_file_settime(const char *file, isc_time_t *time) { int fh; REQUIRE(file != NULL && time != NULL); if ((fh = open(file, _O_RDWR | _O_BINARY)) < 0) return (isc__errno2result(errno)); /* * Set the date via the filedate system call and return. Failing * this call implies the new file times are not supported by the * underlying file system. */ if (!SetFileTime((HANDLE) _get_osfhandle(fh), NULL, &time->absolute, &time->absolute)) { close(fh); errno = EINVAL; return (isc__errno2result(errno)); } close(fh); return (ISC_R_SUCCESS); } #undef TEMPLATE #define TEMPLATE "XXXXXXXXXX.tmp" /* 14 characters. */ isc_result_t isc_file_mktemplate(const char *path, char *buf, size_t buflen) { return (isc_file_template(path, TEMPLATE, buf, buflen)); } isc_result_t isc_file_template(const char *path, const char *templet, char *buf, size_t buflen) { char *s; REQUIRE(path != NULL); REQUIRE(templet != NULL); REQUIRE(buf != NULL); s = strrchr(templet, '\\'); if (s != NULL) templet = s + 1; s = strrchr(path, '\\'); if (s != NULL) { if ((s - path + 1 + strlen(templet) + 1) > (ssize_t)buflen) return (ISC_R_NOSPACE); strncpy(buf, path, s - path + 1); buf[s - path + 1] = '\0'; strcat(buf, templet); } else { if ((strlen(templet) + 1) > buflen) return (ISC_R_NOSPACE); strcpy(buf, templet); } return (ISC_R_SUCCESS); } isc_result_t isc_file_renameunique(const char *file, char *templet) { int fd; int res = 0; isc_result_t result = ISC_R_SUCCESS; REQUIRE(file != NULL); REQUIRE(templet != NULL); fd = mkstemp(templet, ISC_TRUE); if (fd == -1) result = isc__errno2result(errno); else close(fd); if (result == ISC_R_SUCCESS) { res = isc_file_safemovefile(file, templet); if (res != 0) { result = isc__errno2result(errno); (void)unlink(templet); } } return (result); } static isc_result_t openuniquemode(char *templet, int mode, isc_boolean_t binary, FILE **fp) { int fd; FILE *f; isc_result_t result = ISC_R_SUCCESS; REQUIRE(templet != NULL); REQUIRE(fp != NULL && *fp == NULL); /* * Win32 does not have mkstemp. Using emulation above. */ fd = mkstemp(templet, binary); if (fd == -1) result = isc__errno2result(errno); if (result == ISC_R_SUCCESS) { #if 1 UNUSED(mode); #else (void)fchmod(fd, mode); #endif f = fdopen(fd, binary ? "wb+" : "w+"); if (f == NULL) { result = isc__errno2result(errno); (void)remove(templet); (void)close(fd); } else *fp = f; } return (result); } isc_result_t isc_file_openuniqueprivate(char *templet, FILE **fp) { int mode = _S_IREAD | _S_IWRITE; return (openuniquemode(templet, mode, ISC_FALSE, fp)); } isc_result_t isc_file_openunique(char *templet, FILE **fp) { int mode = _S_IREAD | _S_IWRITE; return (openuniquemode(templet, mode, ISC_FALSE, fp)); } isc_result_t isc_file_openuniquemode(char *templet, int mode, FILE **fp) { return (openuniquemode(templet, mode, ISC_FALSE, fp)); } isc_result_t isc_file_bopenuniqueprivate(char *templet, FILE **fp) { int mode = _S_IREAD | _S_IWRITE; return (openuniquemode(templet, mode, ISC_TRUE, fp)); } isc_result_t isc_file_bopenunique(char *templet, FILE **fp) { int mode = _S_IREAD | _S_IWRITE; return (openuniquemode(templet, mode, ISC_TRUE, fp)); } isc_result_t isc_file_bopenuniquemode(char *templet, int mode, FILE **fp) { return (openuniquemode(templet, mode, ISC_TRUE, fp)); } isc_result_t isc_file_remove(const char *filename) { int r; REQUIRE(filename != NULL); r = unlink(filename); if (r == 0) return (ISC_R_SUCCESS); else return (isc__errno2result(errno)); } isc_result_t isc_file_rename(const char *oldname, const char *newname) { int r; REQUIRE(oldname != NULL); REQUIRE(newname != NULL); r = isc_file_safemovefile(oldname, newname); if (r == 0) return (ISC_R_SUCCESS); else return (isc__errno2result(errno)); } isc_boolean_t isc_file_exists(const char *pathname) { struct stat stats; REQUIRE(pathname != NULL); return (ISC_TF(file_stats(pathname, &stats) == ISC_R_SUCCESS)); } isc_result_t isc_file_isplainfile(const char *filename) { /* * This function returns success if filename is a plain file. */ struct stat filestat; memset(&filestat,0,sizeof(struct stat)); if ((stat(filename, &filestat)) == -1) return(isc__errno2result(errno)); if(! S_ISREG(filestat.st_mode)) return(ISC_R_INVALIDFILE); return(ISC_R_SUCCESS); } isc_result_t isc_file_isplainfilefd(int fd) { /* * This function returns success if filename is a plain file. */ struct stat filestat; memset(&filestat,0,sizeof(struct stat)); if ((fstat(fd, &filestat)) == -1) return(isc__errno2result(errno)); if(! S_ISREG(filestat.st_mode)) return(ISC_R_INVALIDFILE); return(ISC_R_SUCCESS); } isc_result_t isc_file_isdirectory(const char *filename) { /* * This function returns success if filename is a directory. */ struct stat filestat; memset(&filestat,0,sizeof(struct stat)); if ((stat(filename, &filestat)) == -1) return(isc__errno2result(errno)); if(! S_ISDIR(filestat.st_mode)) return(ISC_R_INVALIDFILE); return(ISC_R_SUCCESS); } isc_boolean_t isc_file_isabsolute(const char *filename) { REQUIRE(filename != NULL); /* * Look for c:\path\... style, c:/path/... or \\computer\shar\path... * the UNC style file specs */ if ((filename[0] == '\\') && (filename[1] == '\\')) return (ISC_TRUE); if (isalpha(filename[0]) && filename[1] == ':' && filename[2] == '\\') return (ISC_TRUE); if (isalpha(filename[0]) && filename[1] == ':' && filename[2] == '/') return (ISC_TRUE); return (ISC_FALSE); } isc_boolean_t isc_file_iscurrentdir(const char *filename) { REQUIRE(filename != NULL); return (ISC_TF(filename[0] == '.' && filename[1] == '\0')); } isc_boolean_t isc_file_ischdiridempotent(const char *filename) { REQUIRE(filename != NULL); if (isc_file_isabsolute(filename)) return (ISC_TRUE); if (filename[0] == '\\') return (ISC_TRUE); if (filename[0] == '/') return (ISC_TRUE); if (isc_file_iscurrentdir(filename)) return (ISC_TRUE); return (ISC_FALSE); } const char * isc_file_basename(const char *filename) { char *s; REQUIRE(filename != NULL); s = strrchr(filename, '\\'); if (s == NULL) return (filename); return (s + 1); } isc_result_t isc_file_progname(const char *filename, char *progname, size_t namelen) { const char *s; char *p; size_t len; REQUIRE(filename != NULL); REQUIRE(progname != NULL); /* * Strip the path from the name */ s = isc_file_basename(filename); if (s == NULL) { return (ISC_R_NOSPACE); } /* * Strip any and all suffixes */ p = strchr(s, '.'); if (p == NULL) { if (namelen <= strlen(s)) return (ISC_R_NOSPACE); strcpy(progname, s); return (ISC_R_SUCCESS); } /* * Copy the result to the buffer */ len = p - s; if (len >= namelen) return (ISC_R_NOSPACE); strncpy(progname, s, len); progname[len] = '\0'; return (ISC_R_SUCCESS); } isc_result_t isc_file_absolutepath(const char *filename, char *path, size_t pathlen) { char *ptrname; DWORD retval; REQUIRE(filename != NULL); REQUIRE(path != NULL); retval = GetFullPathName(filename, (DWORD) pathlen, path, &ptrname); /* Something went wrong in getting the path */ if (retval == 0) return (ISC_R_NOTFOUND); /* Caller needs to provide a larger buffer to contain the string */ if (retval >= pathlen) return (ISC_R_NOSPACE); return (ISC_R_SUCCESS); } isc_result_t isc_file_truncate(const char *filename, isc_offset_t size) { int fh; REQUIRE(filename != NULL && size >= 0); if ((fh = open(filename, _O_RDWR | _O_BINARY)) < 0) return (isc__errno2result(errno)); if(_chsize(fh, size) != 0) { close(fh); return (isc__errno2result(errno)); } close(fh); return (ISC_R_SUCCESS); } isc_result_t isc_file_safecreate(const char *filename, FILE **fp) { isc_result_t result; int flags; struct stat sb; FILE *f; int fd; REQUIRE(filename != NULL); REQUIRE(fp != NULL && *fp == NULL); result = file_stats(filename, &sb); if (result == ISC_R_SUCCESS) { if ((sb.st_mode & S_IFREG) == 0) return (ISC_R_INVALIDFILE); flags = O_WRONLY | O_TRUNC; } else if (result == ISC_R_FILENOTFOUND) { flags = O_WRONLY | O_CREAT | O_EXCL; } else return (result); fd = open(filename, flags, S_IRUSR | S_IWUSR); if (fd == -1) return (isc__errno2result(errno)); f = fdopen(fd, "w"); if (f == NULL) { result = isc__errno2result(errno); close(fd); return (result); } *fp = f; return (ISC_R_SUCCESS); } isc_result_t isc_file_splitpath(isc_mem_t *mctx, char *path, char **dirname, char **basename) { char *dir, *file, *slash; char *backslash; slash = strrchr(path, '/'); backslash = strrchr(path, '\\'); if ((slash != NULL && backslash != NULL && backslash > slash) || (slash == NULL && backslash != NULL)) slash = backslash; if (slash == path) { file = ++slash; dir = isc_mem_strdup(mctx, "/"); } else if (slash != NULL) { file = ++slash; dir = isc_mem_allocate(mctx, slash - path); if (dir != NULL) strlcpy(dir, path, slash - path); } else { file = path; dir = isc_mem_strdup(mctx, "."); } if (dir == NULL) return (ISC_R_NOMEMORY); if (*file == '\0') { isc_mem_free(mctx, dir); return (ISC_R_INVALIDFILE); } *dirname = dir; *basename = file; return (ISC_R_SUCCESS); } void * isc_file_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) { void *buf; ssize_t ret; off_t end; UNUSED(addr); UNUSED(prot); UNUSED(flags); end = lseek(fd, 0, SEEK_END); lseek(fd, offset, SEEK_SET); if (end - offset < (off_t) len) len = end - offset; buf = malloc(len); ret = read(fd, buf, (unsigned int) len); if (ret != (ssize_t) len) { free(buf); buf = NULL; } return (buf); } int isc_file_munmap(void *addr, size_t len) { UNUSED(len); free(addr); return (0); } bind9-9.10.3.dfsg.P4/lib/isc/win32/libisc.dsp.in0000644000470500017500000004325112664710322020246 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="libisc" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Dynamic-Link Library" 0x0102 CFG=libisc - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "libisc.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "libisc.mak" CFG="libisc - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "libisc - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE "libisc - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "libisc - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 @COPTX@ @COPTI@ /O2 /D "BIND9" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" @COPTY@ /FD /c @IF PKCS11 # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "include" /I "../include" /I "win32" /I "../../isccfg/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" /D "BIND9" @CRYPTO@ @PK11_LIB_LOCATION@ /D "WIN32" /D "NDEBUG" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" @COPTY@ /FD /c @ELSE PKCS11 # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "include" /I "../include" /I "win32" /I "../../isccfg/include" /D "BIND9" /D "WIN32" /D "NDEBUG" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" @COPTY@ /FD /c @END PKCS11 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll @MACHINE@ # ADD LINK32 @LIBXML2_LIB@ @OPENSSL_LIB@ user32.lib advapi32.lib ws2_32.lib /nologo /dll @MACHINE@ /out:"../../../Build/Release/libisc.dll" # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "BIND9" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" @COPTY@ /FD /GZ /c @IF PKCS11 # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "include" /I "../include" /I "win32" /I "../../isccfg/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" /D "BIND9" @CRYPTO@ @PK11_LIB_LOCATION@ /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" /FR @COPTY@ /FD /GZ /c @ELSE PKCS11 # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "include" /I "../include" /I "win32" /I "../../isccfg/include" /D "BIND9" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" /FR @COPTY@ /FD /GZ /c @END PKCS11 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug @MACHINE@ /pdbtype:sept # ADD LINK32 @LIBXML2_LIB@ @OPENSSL_LIB@ user32.lib advapi32.lib ws2_32.lib /nologo /dll /map /debug @MACHINE@ /out:"../../../Build/Debug/libisc.dll" /pdbtype:sept !ENDIF # Begin Target # Name "libisc - @PLATFORM@ Release" # Name "libisc - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.\app.c # End Source File # Begin Source File SOURCE=.\condition.c # End Source File # Begin Source File SOURCE=.\dir.c # End Source File # Begin Source File SOURCE=.\DLLMain.c # End Source File # Begin Source File SOURCE=.\entropy.c # End Source File # Begin Source File SOURCE=.\errno2result.c # End Source File # Begin Source File SOURCE=.\file.c # End Source File # Begin Source File SOURCE=.\fsaccess.c # End Source File # Begin Source File SOURCE=.\interfaceiter.c # End Source File # Begin Source File SOURCE=.\ipv6.c # End Source File # Begin Source File SOURCE=.\keyboard.c # End Source File # Begin Source File SOURCE=.\net.c # End Source File # Begin Source File SOURCE=.\ntpaths.c # End Source File # Begin Source File SOURCE=.\once.c # End Source File # Begin Source File SOURCE=.\os.c # End Source File @IF PKCS11 # Begin Source File SOURCE=.\pk11_api.c # End Source File @END PKCS11 # Begin Source File SOURCE=.\resource.c # End Source File # Begin Source File SOURCE=.\socket.c # End Source File # Begin Source File SOURCE=.\stdio.c # End Source File # Begin Source File SOURCE=.\stdtime.c # End Source File # Begin Source File SOURCE=.\strerror.c # End Source File # Begin Source File SOURCE=.\syslog.c # End Source File # Begin Source File SOURCE=.\thread.c # End Source File # Begin Source File SOURCE=.\time.c # End Source File # Begin Source File SOURCE=.\version.c # End Source File # Begin Source File SOURCE=.\win32os.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" @IF AES # Begin Source File SOURCE=..\include\isc\aes.h # End Source File @END AES # Begin Source File SOURCE=..\include\isc\app.h # End Source File # Begin Source File SOURCE=..\include\isc\assertions.h # End Source File # Begin Source File SOURCE=..\include\isc\backtrace.h # End Source File # Begin Source File SOURCE=..\include\isc\base32.h # End Source File # Begin Source File SOURCE=..\include\isc\base64.h # End Source File # Begin Source File SOURCE=..\include\isc\bind9.h # End Source File # Begin Source File SOURCE=.\include\isc\bind_registry.h # End Source File # Begin Source File SOURCE=.\include\isc\bindevt.h # End Source File # Begin Source File SOURCE=..\include\isc\boolean.h # End Source File # Begin Source File SOURCE=..\include\isc\buffer.h # End Source File # Begin Source File SOURCE=..\include\isc\bufferlist.h # End Source File # Begin Source File SOURCE=..\include\isc\commandline.h # End Source File # Begin Source File SOURCE=..\include\isc\counter.h # End Source File # Begin Source File SOURCE=.\include\isc\condition.h # End Source File # Begin Source File SOURCE=..\..\..\config.h # End Source File # Begin Source File SOURCE=..\include\isc\crc64.h # End Source File # Begin Source File SOURCE=.\include\isc\dir.h # End Source File # Begin Source File SOURCE=..\include\isc\entropy.h # End Source File # Begin Source File SOURCE=.\errno2result.h # End Source File # Begin Source File SOURCE=..\include\isc\error.h # End Source File # Begin Source File SOURCE=..\include\isc\event.h # End Source File # Begin Source File SOURCE=..\include\isc\eventclass.h # End Source File # Begin Source File SOURCE=..\include\isc\file.h # End Source File # Begin Source File SOURCE=..\include\isc\formatcheck.h # End Source File # Begin Source File SOURCE=..\include\isc\fsaccess.h # End Source File # Begin Source File SOURCE=..\include\isc\hash.h # End Source File # Begin Source File SOURCE=..\include\isc\heap.h # End Source File # Begin Source File SOURCE=..\include\isc\hex.h # End Source File # Begin Source File SOURCE=..\include\isc\hmacmd5.h # End Source File # Begin Source File SOURCE=..\include\isc\hmacsha.h # End Source File # Begin Source File SOURCE=..\include\isc\httpd.h # End Source File # Begin Source File SOURCE=.\include\isc\int.h # End Source File # Begin Source File SOURCE=..\include\isc\interfaceiter.h # End Source File @IF PKCS11 # Begin Source File SOURCE=..\include\pk11\internal.h # End Source File @END PKCS11 # Begin Source File SOURCE=.\include\isc\ipv6.h # End Source File # Begin Source File SOURCE=..\include\isc\iterated_hash.h # End Source File # Begin Source File SOURCE=.\include\isc\keyboard.h # End Source File # Begin Source File SOURCE=..\include\isc\json.h # End Source File # Begin Source File SOURCE=..\include\isc\lang.h # End Source File # Begin Source File SOURCE=..\include\isc\lex.h # End Source File # Begin Source File SOURCE=..\include\isc\lfsr.h # End Source File # Begin Source File SOURCE=..\include\isc\lib.h # End Source File # Begin Source File SOURCE=..\include\isc\list.h # End Source File # Begin Source File SOURCE=..\include\isc\log.h # End Source File # Begin Source File SOURCE=..\include\isc\magic.h # End Source File # Begin Source File SOURCE=..\include\isc\md5.h # End Source File # Begin Source File SOURCE=..\include\isc\mem.h # End Source File # Begin Source File SOURCE=..\include\isc\msgcat.h # End Source File # Begin Source File SOURCE=.\include\isc\mutex.h # End Source File # Begin Source File SOURCE=..\include\isc\mutexblock.h # End Source File # Begin Source File SOURCE=.\include\isc\net.h # End Source File # Begin Source File SOURCE=..\include\isc\netaddr.h # End Source File # Begin Source File SOURCE=..\include\isc\netscope.h # End Source File # Begin Source File SOURCE=.\include\isc\netdb.h # End Source File # Begin Source File SOURCE=.\include\isc\ntgroups.h # End Source File # Begin Source File SOURCE=.\include\isc\ntpaths.h # End Source File # Begin Source File SOURCE=.\include\isc\offset.h # End Source File # Begin Source File SOURCE=.\include\isc\once.h # End Source File # Begin Source File SOURCE=..\include\isc\ondestroy.h # End Source File # Begin Source File SOURCE=..\include\isc\os.h # End Source File # Begin Source File SOURCE=..\include\isc\parseint.h # End Source File @IF PKCS11 # Begin Source File SOURCE=..\include\pk11\pk11.h # End Source File @END PKCS11 # Begin Source File SOURCE=..\include\isc\pool.h # End Source File # Begin Source File SOURCE=..\include\isc\portset.h # End Source File # Begin Source File SOURCE=.\include\isc\platform.h # End Source File # Begin Source File SOURCE=..\include\isc\print.h # End Source File # Begin Source File SOURCE=..\include\isc\queue.h # End Source File # Begin Source File SOURCE=..\include\isc\quota.h # End Source File # Begin Source File SOURCE=..\include\isc\radix.h # End Source File # Begin Source File SOURCE=..\include\isc\random.h # End Source File # Begin Source File SOURCE=..\include\isc\ratelimiter.h # End Source File # Begin Source File SOURCE=..\include\isc\refcount.h # End Source File # Begin Source File SOURCE=..\include\isc\regex.h # End Source File # Begin Source File SOURCE=..\include\isc\region.h # End Source File # Begin Source File SOURCE=..\include\isc\resource.h # End Source File # Begin Source File SOURCE=..\include\isc\result.h # End Source File @IF PKCS11 # Begin Source File SOURCE=..\include\pk11\result.h # End Source File @END PKCS11 # Begin Source File SOURCE=..\include\isc\resultclass.h # End Source File # Begin Source File SOURCE=..\include\isc\rwlock.h # End Source File # Begin Source File SOURCE=..\include\isc\safe.h # End Source File # Begin Source File SOURCE=..\include\isc\serial.h # End Source File # Begin Source File SOURCE=..\include\isc\sha1.h # End Source File # Begin Source File SOURCE=..\include\isc\sha2.h # End Source File # Begin Source File SOURCE=..\include\isc\sockaddr.h # End Source File # Begin Source File SOURCE=..\include\isc\socket.h # End Source File # Begin Source File SOURCE=.\include\isc\stats.h # End Source File # Begin Source File SOURCE=..\include\isc\stdio.h # End Source File # Begin Source File SOURCE=..\include\isc\stdlib.h # End Source File # Begin Source File SOURCE=.\include\isc\stdtime.h # End Source File # Begin Source File SOURCE=.\include\isc\strerror.h # End Source File # Begin Source File SOURCE=..\include\isc\string.h # End Source File # Begin Source File SOURCE=..\include\isc\symtab.h # End Source File # Begin Source File SOURCE=.\include\isc\syslog.h # End Source File # Begin Source File SOURCE=.\syslog.h # End Source File # Begin Source File SOURCE=..\include\isc\task.h # End Source File # Begin Source File SOURCE=..\include\isc\taskpool.h # End Source File # Begin Source File SOURCE=.\include\isc\thread.h # End Source File # Begin Source File SOURCE=.\include\isc\time.h # End Source File # Begin Source File SOURCE=..\include\isc\timer.h # End Source File # Begin Source File SOURCE=..\include\isc\tm.h # End Source File # Begin Source File SOURCE=.\include\isc\win32os.h # End Source File # Begin Source File SOURCE=..\include\isc\types.h # End Source File # Begin Source File SOURCE=.\unistd.h # End Source File # Begin Source File SOURCE=..\include\isc\util.h # End Source File # Begin Source File SOURCE=..\..\..\versions.h # End Source File # Begin Source File SOURCE=..\include\isc\xml.h # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # Begin Group "Main Isc Lib" # PROP Default_Filter "c" @IF AES # Begin Source File SOURCE=..\aes.c # End Source File @END AES # Begin Source File SOURCE=..\assertions.c # End Source File # Begin Source File SOURCE=..\backtrace.c # End Source File # Begin Source File SOURCE=..\backtrace-emptytbl.c # End Source File # Begin Source File SOURCE=..\base32.c # End Source File # Begin Source File SOURCE=..\base64.c # End Source File # Begin Source File SOURCE=..\bind9.c # End Source File # Begin Source File SOURCE=..\buffer.c # End Source File # Begin Source File SOURCE=..\bufferlist.c # End Source File # Begin Source File SOURCE=..\commandline.c # End Source File # Begin Source File SOURCE=..\counter.c # End Source File # Begin Source File SOURCE=..\crc64.c # End Source File # Begin Source File SOURCE=..\error.c # End Source File # Begin Source File SOURCE=..\event.c # End Source File # Begin Source File SOURCE=..\hash.c # End Source File # Begin Source File SOURCE=..\heap.c # End Source File # Begin Source File SOURCE=..\hex.c # End Source File # Begin Source File SOURCE=..\hmacmd5.c # End Source File # Begin Source File SOURCE=..\hmacsha.c # End Source File # Begin Source File SOURCE=..\httpd.c # End Source File # Begin Source File SOURCE=..\inet_aton.c # End Source File # Begin Source File SOURCE=..\inet_ntop.c # End Source File # Begin Source File SOURCE=..\inet_pton.c # End Source File # Begin Source File SOURCE=..\iterated_hash.c # End Source File # Begin Source File SOURCE=..\lex.c # End Source File # Begin Source File SOURCE=..\lfsr.c # End Source File # Begin Source File SOURCE=..\lib.c # End Source File # Begin Source File SOURCE=..\log.c # End Source File # Begin Source File SOURCE=..\md5.c # End Source File # Begin Source File SOURCE=..\mem.c # End Source File # Begin Source File SOURCE=..\nls\msgcat.c # End Source File # Begin Source File SOURCE=..\mutexblock.c # End Source File # Begin Source File SOURCE=..\netaddr.c # End Source File # Begin Source File SOURCE=..\netscope.c # End Source File # Begin Source File SOURCE=..\ondestroy.c # End Source File # Begin Source File SOURCE=..\parseint.c # End Source File @IF PKCS11 # Begin Source File SOURCE=..\pk11.c # End Source File # Begin Source File SOURCE=..\pk11_result.c # End Source File @END PKCS11 # Begin Source File SOURCE=..\pool.c # End Source File # Begin Source File SOURCE=..\portset.c # End Source File # Begin Source File SOURCE=..\quota.c # End Source File # Begin Source File SOURCE=..\radix.c # End Source File # Begin Source File SOURCE=..\random.c # End Source File # Begin Source File SOURCE=..\ratelimiter.c # End Source File # Begin Source File SOURCE=..\refcount.c # End Source File # Begin Source File SOURCE=..\regex.c # End Source File # Begin Source File SOURCE=..\region.c # End Source File # Begin Source File SOURCE=..\result.c # End Source File # Begin Source File SOURCE=..\rwlock.c # End Source File # Begin Source File SOURCE=..\safe.c # End Source File # Begin Source File SOURCE=..\serial.c # End Source File # Begin Source File SOURCE=..\sha1.c # End Source File # Begin Source File SOURCE=..\sha2.c # End Source File # Begin Source File SOURCE=..\sockaddr.c # End Source File # Begin Source File SOURCE=..\stats.c # End Source File # Begin Source File SOURCE=..\string.c # End Source File # Begin Source File SOURCE=..\symtab.c # End Source File # Begin Source File SOURCE=..\task.c # End Source File # Begin Source File SOURCE=..\taskpool.c # End Source File # Begin Source File SOURCE=..\timer.c # End Source File # Begin Source File SOURCE=..\tm.c # End Source File # End Group @IF ATOMIC # Begin Source File SOURCE=.\include\atomic.h # End Source File @ELSE ATOMIC # Begin Source File SOURCE=..\noatomic\include\atomic.h # End Source File @END ATOMIC # Begin Source File SOURCE=.\libisc.def # End Source File # End Target # End Project bind9-9.10.3.dfsg.P4/lib/isc/win32/libisc.vcxproj.filters.in0000644000470500017500000005550412664710322022626 0ustar lamontlamont {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {289562c2-1bdd-4582-b6bd-3f598ee23cbd} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {d03c3e6a-e78e-4a01-bd77-64c839b1adfe} h;hpp;hxx;hm;inl;inc;xsd {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms @IF AES Library Header Files @END AES Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files Library Header Files @IF PKCS11 Library Header Files Library Header Files Library Header Files Library Header Files Pkcs11 Header Files Pkcs11 Header Files Pkcs11 Header Files @END PKCS11 Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files Win32 Header Files @IF PKCS11 Win32 Header Files @END PKCS11 @IF ATOMIC @ELSE ATOMIC @END ATOMIC Library Header Files Library Header Files Library Header Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files Win32 Source Files @IF PKCS11 Win32 Source Files @END PKCS11 @IF AES Win32 Source Files @END AES Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files Library Source Files @IF PKCS11 Library Source Files Library Source Files @END PKCS11 bind9-9.10.3.dfsg.P4/lib/isc/win32/socket.c0000644000470500017500000031550612664710322017325 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* This code uses functions which are only available on Server 2003 and * higher, and Windows XP and higher. * * This code is by nature multithreaded and takes advantage of various * features to pass on information through the completion port for * when I/O is completed. All sends, receives, accepts, and connects are * completed through the completion port. * * The number of Completion Port Worker threads used is the total number * of CPU's + 1. This increases the likelihood that a Worker Thread is * available for processing a completed request. * * XXXPDM 5 August, 2002 */ #define MAKE_EXTERNAL 1 #include #include #ifndef _WINSOCKAPI_ #define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */ #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "errno2result.h" /* * Set by the -T dscp option on the command line. If set to a value * other than -1, we check to make sure DSCP values match it, and * assert if not. */ int isc_dscp_check_value = -1; /* * How in the world can Microsoft exist with APIs like this? * We can't actually call this directly, because it turns out * no library exports this function. Instead, we need to * issue a runtime call to get the address. */ LPFN_CONNECTEX ISCConnectEx; LPFN_ACCEPTEX ISCAcceptEx; LPFN_GETACCEPTEXSOCKADDRS ISCGetAcceptExSockaddrs; /* * Run expensive internal consistency checks. */ #ifdef ISC_SOCKET_CONSISTENCY_CHECKS #define CONSISTENT(sock) consistent(sock) #else #define CONSISTENT(sock) do {} while (0) #endif static void consistent(isc_socket_t *sock); /* * Define this macro to control the behavior of connection * resets on UDP sockets. See Microsoft KnowledgeBase Article Q263823 * for details. * NOTE: This requires that Windows 2000 systems install Service Pack 2 * or later. */ #ifndef SIO_UDP_CONNRESET #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12) #endif /* * Some systems define the socket length argument as an int, some as size_t, * some as socklen_t. This is here so it can be easily changed if needed. */ #ifndef ISC_SOCKADDR_LEN_T #define ISC_SOCKADDR_LEN_T unsigned int #endif /* * Define what the possible "soft" errors can be. These are non-fatal returns * of various network related functions, like recv() and so on. */ #define SOFT_ERROR(e) ((e) == WSAEINTR || \ (e) == WSAEWOULDBLOCK || \ (e) == EWOULDBLOCK || \ (e) == EINTR || \ (e) == EAGAIN || \ (e) == 0) /* * Pending errors are not really errors and should be * kept separate */ #define PENDING_ERROR(e) ((e) == WSA_IO_PENDING || (e) == 0) #define DOIO_SUCCESS 0 /* i/o ok, event sent */ #define DOIO_SOFT 1 /* i/o ok, soft error, no event sent */ #define DOIO_HARD 2 /* i/o error, event sent */ #define DOIO_EOF 3 /* EOF, no event sent */ #define DOIO_PENDING 4 /* status when i/o is in process */ #define DOIO_NEEDMORE 5 /* IO was processed, but we need more due to minimum */ #define DLVL(x) ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(x) /* * DLVL(90) -- Function entry/exit and other tracing. * DLVL(70) -- Socket "correctness" -- including returning of events, etc. * DLVL(60) -- Socket data send/receive * DLVL(50) -- Event tracing, including receiving/sending completion events. * DLVL(20) -- Socket creation/destruction. */ #define TRACE_LEVEL 90 #define CORRECTNESS_LEVEL 70 #define IOEVENT_LEVEL 60 #define EVENT_LEVEL 50 #define CREATION_LEVEL 20 #define TRACE DLVL(TRACE_LEVEL) #define CORRECTNESS DLVL(CORRECTNESS_LEVEL) #define IOEVENT DLVL(IOEVENT_LEVEL) #define EVENT DLVL(EVENT_LEVEL) #define CREATION DLVL(CREATION_LEVEL) typedef isc_event_t intev_t; /* * Socket State */ enum { SOCK_INITIALIZED, /* Socket Initialized */ SOCK_OPEN, /* Socket opened but nothing yet to do */ SOCK_DATA, /* Socket sending or receiving data */ SOCK_LISTEN, /* TCP Socket listening for connects */ SOCK_ACCEPT, /* TCP socket is waiting to accept */ SOCK_CONNECT, /* TCP Socket connecting */ SOCK_CLOSED, /* Socket has been closed */ }; #define SOCKET_MAGIC ISC_MAGIC('I', 'O', 'i', 'o') #define VALID_SOCKET(t) ISC_MAGIC_VALID(t, SOCKET_MAGIC) /* * IPv6 control information. If the socket is an IPv6 socket we want * to collect the destination address and interface so the client can * set them on outgoing packets. */ #ifdef ISC_PLATFORM_HAVEIPV6 #ifndef USE_CMSG #define USE_CMSG 1 #endif #endif /* * We really don't want to try and use these control messages. Win32 * doesn't have this mechanism before XP. */ #undef USE_CMSG /* * Message header for recvmsg and sendmsg calls. * Used value-result for recvmsg, value only for sendmsg. */ struct msghdr { SOCKADDR_STORAGE to_addr; /* UDP send/recv address */ int to_addr_len; /* length of the address */ WSABUF *msg_iov; /* scatter/gather array */ u_int msg_iovlen; /* # elements in msg_iov */ void *msg_control; /* ancillary data, see below */ u_int msg_controllen; /* ancillary data buffer len */ u_int msg_totallen; /* total length of this message */ } msghdr; /* * The size to raise the receive buffer to. */ #define RCVBUFSIZE (32*1024) /* * The number of times a send operation is repeated if the result * is WSAEINTR. */ #define NRETRIES 10 struct isc_socket { /* Not locked. */ unsigned int magic; isc_socketmgr_t *manager; isc_mutex_t lock; isc_sockettype_t type; /* Pointers to scatter/gather buffers */ WSABUF iov[ISC_SOCKET_MAXSCATTERGATHER]; /* Locked by socket lock. */ ISC_LINK(isc_socket_t) link; unsigned int references; /* EXTERNAL references */ SOCKET fd; /* file handle */ int pf; /* protocol family */ char name[16]; void * tag; /* * Each recv() call uses this buffer. It is a per-socket receive * buffer that allows us to decouple the system recv() from the * recv_list done events. This means the items on the recv_list * can be removed without having to cancel pending system recv() * calls. It also allows us to read-ahead in some cases. */ struct { SOCKADDR_STORAGE from_addr; // UDP send/recv address int from_addr_len; // length of the address char *base; // the base of the buffer char *consume_position; // where to start copying data from next unsigned int len; // the actual size of this buffer unsigned int remaining; // the number of bytes remaining } recvbuf; ISC_LIST(isc_socketevent_t) send_list; ISC_LIST(isc_socketevent_t) recv_list; ISC_LIST(isc_socket_newconnev_t) accept_list; isc_socket_connev_t *connect_ev; isc_sockaddr_t address; /* remote address */ unsigned int listener : 1, /* listener socket */ connected : 1, pending_connect : 1, /* connect pending */ bound : 1, /* bound to local addr */ dupped : 1; /* created by isc_socket_dup() */ unsigned int pending_iocp; /* Should equal the counters below. Debug. */ unsigned int pending_recv; /* Number of outstanding recv() calls. */ unsigned int pending_send; /* Number of outstanding send() calls. */ unsigned int pending_accept; /* Number of outstanding accept() calls. */ unsigned int state; /* Socket state. Debugging and consistency checking. */ int state_lineno; /* line which last touched state */ }; #define _set_state(sock, _state) do { (sock)->state = (_state); (sock)->state_lineno = __LINE__; } while (0) /* * Buffer structure */ typedef struct buflist buflist_t; struct buflist { void *buf; unsigned int buflen; ISC_LINK(buflist_t) link; }; /* * I/O Completion ports Info structures */ static HANDLE hHeapHandle = NULL; typedef struct IoCompletionInfo { OVERLAPPED overlapped; isc_socketevent_t *dev; /* send()/recv() done event */ isc_socket_connev_t *cdev; /* connect() done event */ isc_socket_newconnev_t *adev; /* accept() done event */ void *acceptbuffer; DWORD received_bytes; int request_type; struct msghdr messagehdr; ISC_LIST(buflist_t) bufferlist; /*%< list of buffers */ } IoCompletionInfo; /* * Define a maximum number of I/O Completion Port worker threads * to handle the load on the Completion Port. The actual number * used is the number of CPU's + 1. */ #define MAX_IOCPTHREADS 20 #define SOCKET_MANAGER_MAGIC ISC_MAGIC('I', 'O', 'm', 'g') #define VALID_MANAGER(m) ISC_MAGIC_VALID(m, SOCKET_MANAGER_MAGIC) struct isc_socketmgr { /* Not locked. */ unsigned int magic; isc_mem_t *mctx; isc_mutex_t lock; isc_stats_t *stats; /* Locked by manager lock. */ ISC_LIST(isc_socket_t) socklist; isc_boolean_t bShutdown; isc_condition_t shutdown_ok; HANDLE hIoCompletionPort; int maxIOCPThreads; HANDLE hIOCPThreads[MAX_IOCPTHREADS]; DWORD dwIOCPThreadIds[MAX_IOCPTHREADS]; /* * Debugging. * Modified by InterlockedIncrement() and InterlockedDecrement() */ LONG totalSockets; LONG iocp_total; }; enum { SOCKET_RECV, SOCKET_SEND, SOCKET_ACCEPT, SOCKET_CONNECT }; /* * send() and recv() iovec counts */ #define MAXSCATTERGATHER_SEND (ISC_SOCKET_MAXSCATTERGATHER) #define MAXSCATTERGATHER_RECV (ISC_SOCKET_MAXSCATTERGATHER) static isc_result_t socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, isc_socket_t **socketp, isc_socket_t *dup_socket); static isc_threadresult_t WINAPI SocketIoThread(LPVOID ThreadContext); static void maybe_free_socket(isc_socket_t **, int); static void free_socket(isc_socket_t **, int); static isc_boolean_t senddone_is_active(isc_socket_t *sock, isc_socketevent_t *dev); static isc_boolean_t acceptdone_is_active(isc_socket_t *sock, isc_socket_newconnev_t *dev); static isc_boolean_t connectdone_is_active(isc_socket_t *sock, isc_socket_connev_t *dev); static void send_recvdone_event(isc_socket_t *sock, isc_socketevent_t **dev); static void send_senddone_event(isc_socket_t *sock, isc_socketevent_t **dev); static void send_acceptdone_event(isc_socket_t *sock, isc_socket_newconnev_t **adev); static void send_connectdone_event(isc_socket_t *sock, isc_socket_connev_t **cdev); static void send_recvdone_abort(isc_socket_t *sock, isc_result_t result); static void queue_receive_event(isc_socket_t *sock, isc_task_t *task, isc_socketevent_t *dev); static void queue_receive_request(isc_socket_t *sock); /* * This is used to dump the contents of the sock structure * You should make sure that the sock is locked before * dumping it. Since the code uses simple printf() statements * it should only be used interactively. */ void sock_dump(isc_socket_t *sock) { isc_socketevent_t *ldev; isc_socket_newconnev_t *ndev; #if 0 isc_sockaddr_t addr; char socktext[ISC_SOCKADDR_FORMATSIZE]; isc_result_t result; result = isc_socket_getpeername(sock, &addr); if (result == ISC_R_SUCCESS) { isc_sockaddr_format(&addr, socktext, sizeof(socktext)); printf("Remote Socket: %s\n", socktext); } result = isc_socket_getsockname(sock, &addr); if (result == ISC_R_SUCCESS) { isc_sockaddr_format(&addr, socktext, sizeof(socktext)); printf("This Socket: %s\n", socktext); } #endif printf("\n\t\tSock Dump\n"); printf("\t\tfd: %u\n", sock->fd); printf("\t\treferences: %d\n", sock->references); printf("\t\tpending_accept: %d\n", sock->pending_accept); printf("\t\tconnecting: %d\n", sock->pending_connect); printf("\t\tconnected: %d\n", sock->connected); printf("\t\tbound: %d\n", sock->bound); printf("\t\tpending_iocp: %d\n", sock->pending_iocp); printf("\t\tsocket type: %d\n", sock->type); printf("\n\t\tSock Recv List\n"); ldev = ISC_LIST_HEAD(sock->recv_list); while (ldev != NULL) { printf("\t\tdev: %p\n", ldev); ldev = ISC_LIST_NEXT(ldev, ev_link); } printf("\n\t\tSock Send List\n"); ldev = ISC_LIST_HEAD(sock->send_list); while (ldev != NULL) { printf("\t\tdev: %p\n", ldev); ldev = ISC_LIST_NEXT(ldev, ev_link); } printf("\n\t\tSock Accept List\n"); ndev = ISC_LIST_HEAD(sock->accept_list); while (ndev != NULL) { printf("\t\tdev: %p\n", ldev); ndev = ISC_LIST_NEXT(ndev, ev_link); } } static void socket_log(int lineno, isc_socket_t *sock, isc_sockaddr_t *address, isc_logcategory_t *category, isc_logmodule_t *module, int level, isc_msgcat_t *msgcat, int msgset, int message, const char *fmt, ...) ISC_FORMAT_PRINTF(9, 10); /* This function will add an entry to the I/O completion port * that will signal the I/O thread to exit (gracefully) */ static void signal_iocompletionport_exit(isc_socketmgr_t *manager) { int i; int errval; char strbuf[ISC_STRERRORSIZE]; REQUIRE(VALID_MANAGER(manager)); for (i = 0; i < manager->maxIOCPThreads; i++) { if (!PostQueuedCompletionStatus(manager->hIoCompletionPort, 0, 0, 0)) { errval = GetLastError(); isc__strerror(errval, strbuf, sizeof(strbuf)); FATAL_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_FAILED, "Can't request service thread to exit: %s"), strbuf); } } } /* * Create the worker threads for the I/O Completion Port */ void iocompletionport_createthreads(int total_threads, isc_socketmgr_t *manager) { int errval; char strbuf[ISC_STRERRORSIZE]; int i; INSIST(total_threads > 0); REQUIRE(VALID_MANAGER(manager)); /* * We need at least one */ for (i = 0; i < total_threads; i++) { manager->hIOCPThreads[i] = CreateThread(NULL, 0, SocketIoThread, manager, 0, &manager->dwIOCPThreadIds[i]); if (manager->hIOCPThreads[i] == NULL) { errval = GetLastError(); isc__strerror(errval, strbuf, sizeof(strbuf)); FATAL_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_FAILED, "Can't create IOCP thread: %s"), strbuf); exit(1); } } } /* * Create/initialise the I/O completion port */ void iocompletionport_init(isc_socketmgr_t *manager) { int errval; char strbuf[ISC_STRERRORSIZE]; REQUIRE(VALID_MANAGER(manager)); /* * Create a private heap to handle the socket overlapped structure * The minimum number of structures is 10, there is no maximum */ hHeapHandle = HeapCreate(0, 10 * sizeof(IoCompletionInfo), 0); if (hHeapHandle == NULL) { errval = GetLastError(); isc__strerror(errval, strbuf, sizeof(strbuf)); FATAL_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_FAILED, "HeapCreate() failed during " "initialization: %s"), strbuf); exit(1); } manager->maxIOCPThreads = min(isc_os_ncpus() + 1, MAX_IOCPTHREADS); /* Now Create the Completion Port */ manager->hIoCompletionPort = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 0, manager->maxIOCPThreads); if (manager->hIoCompletionPort == NULL) { errval = GetLastError(); isc__strerror(errval, strbuf, sizeof(strbuf)); FATAL_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_FAILED, "CreateIoCompletionPort() failed " "during initialization: %s"), strbuf); exit(1); } /* * Worker threads for servicing the I/O */ iocompletionport_createthreads(manager->maxIOCPThreads, manager); } /* * Associate a socket with an IO Completion Port. This allows us to queue events for it * and have our worker pool of threads process them. */ void iocompletionport_update(isc_socket_t *sock) { HANDLE hiocp; char strbuf[ISC_STRERRORSIZE]; REQUIRE(VALID_SOCKET(sock)); hiocp = CreateIoCompletionPort((HANDLE)sock->fd, sock->manager->hIoCompletionPort, (ULONG_PTR)sock, 0); if (hiocp == NULL) { DWORD errval = GetLastError(); isc__strerror(errval, strbuf, sizeof(strbuf)); isc_log_iwrite(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_TOOMANYHANDLES, "iocompletionport_update: failed to open" " io completion port: %s", strbuf); /* XXXMLG temporary hack to make failures detected. * This function should return errors to the caller, not * exit here. */ FATAL_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_FAILED, "CreateIoCompletionPort() failed " "during initialization: %s"), strbuf); exit(1); } InterlockedIncrement(&sock->manager->iocp_total); } /* * Routine to cleanup and then close the socket. * Only close the socket here if it is NOT associated * with an event, otherwise the WSAWaitForMultipleEvents * may fail due to the fact that the Wait should not * be running while closing an event or a socket. * The socket is locked before calling this function */ void socket_close(isc_socket_t *sock) { REQUIRE(sock != NULL); if (sock->fd != INVALID_SOCKET) { closesocket(sock->fd); sock->fd = INVALID_SOCKET; _set_state(sock, SOCK_CLOSED); InterlockedDecrement(&sock->manager->totalSockets); } } static isc_once_t initialise_once = ISC_ONCE_INIT; static isc_boolean_t initialised = ISC_FALSE; static void initialise(void) { WORD wVersionRequested; WSADATA wsaData; int err; SOCKET sock; GUID GUIDConnectEx = WSAID_CONNECTEX; GUID GUIDAcceptEx = WSAID_ACCEPTEX; GUID GUIDGetAcceptExSockaddrs = WSAID_GETACCEPTEXSOCKADDRS; DWORD dwBytes; /* Need Winsock 2.2 or better */ wVersionRequested = MAKEWORD(2, 2); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { char strbuf[ISC_STRERRORSIZE]; isc__strerror(err, strbuf, sizeof(strbuf)); FATAL_ERROR(__FILE__, __LINE__, "WSAStartup() %s: %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); exit(1); } /* * The following APIs do not exist as functions in a library, but we must * ask winsock for them. They are "extensions" -- but why they cannot be * actual functions is beyond me. So, ask winsock for the pointers to the * functions we need. */ sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); INSIST(sock != INVALID_SOCKET); err = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &GUIDConnectEx, sizeof(GUIDConnectEx), &ISCConnectEx, sizeof(ISCConnectEx), &dwBytes, NULL, NULL); INSIST(err == 0); err = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &GUIDAcceptEx, sizeof(GUIDAcceptEx), &ISCAcceptEx, sizeof(ISCAcceptEx), &dwBytes, NULL, NULL); INSIST(err == 0); err = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &GUIDGetAcceptExSockaddrs, sizeof(GUIDGetAcceptExSockaddrs), &ISCGetAcceptExSockaddrs, sizeof(ISCGetAcceptExSockaddrs), &dwBytes, NULL, NULL); INSIST(err == 0); closesocket(sock); initialised = ISC_TRUE; } /* * Initialize socket services */ void InitSockets(void) { RUNTIME_CHECK(isc_once_do(&initialise_once, initialise) == ISC_R_SUCCESS); if (!initialised) exit(1); } int internal_sendmsg(isc_socket_t *sock, IoCompletionInfo *lpo, struct msghdr *messagehdr, int flags, int *Error) { int Result; DWORD BytesSent; DWORD Flags = flags; int total_sent; *Error = 0; Result = WSASendTo(sock->fd, messagehdr->msg_iov, messagehdr->msg_iovlen, &BytesSent, Flags, (SOCKADDR *)&messagehdr->to_addr, messagehdr->to_addr_len, (LPWSAOVERLAPPED)lpo, NULL); total_sent = (int)BytesSent; /* Check for errors.*/ if (Result == SOCKET_ERROR) { *Error = WSAGetLastError(); switch (*Error) { case WSA_IO_INCOMPLETE: case WSA_WAIT_IO_COMPLETION: case WSA_IO_PENDING: case NO_ERROR: /* Strange, but okay */ sock->pending_iocp++; sock->pending_send++; break; default: return (-1); break; } } else { sock->pending_iocp++; sock->pending_send++; } if (lpo != NULL) return (0); else return (total_sent); } static void queue_receive_request(isc_socket_t *sock) { DWORD Flags = 0; DWORD NumBytes = 0; int Result; int Error; int need_retry; WSABUF iov[1]; IoCompletionInfo *lpo = NULL; isc_result_t isc_result; retry: need_retry = ISC_FALSE; /* * If we already have a receive pending, do nothing. */ if (sock->pending_recv > 0) { if (lpo != NULL) HeapFree(hHeapHandle, 0, lpo); return; } /* * If no one is waiting, do nothing. */ if (ISC_LIST_EMPTY(sock->recv_list)) { if (lpo != NULL) HeapFree(hHeapHandle, 0, lpo); return; } INSIST(sock->recvbuf.remaining == 0); INSIST(sock->fd != INVALID_SOCKET); iov[0].len = sock->recvbuf.len; iov[0].buf = sock->recvbuf.base; if (lpo == NULL) { lpo = (IoCompletionInfo *)HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, sizeof(IoCompletionInfo)); RUNTIME_CHECK(lpo != NULL); } else ZeroMemory(lpo, sizeof(IoCompletionInfo)); lpo->request_type = SOCKET_RECV; sock->recvbuf.from_addr_len = sizeof(sock->recvbuf.from_addr); Error = 0; Result = WSARecvFrom((SOCKET)sock->fd, iov, 1, &NumBytes, &Flags, (SOCKADDR *)&sock->recvbuf.from_addr, &sock->recvbuf.from_addr_len, (LPWSAOVERLAPPED)lpo, NULL); /* Check for errors. */ if (Result == SOCKET_ERROR) { Error = WSAGetLastError(); switch (Error) { case WSA_IO_PENDING: sock->pending_iocp++; sock->pending_recv++; break; /* direct error: no completion event */ case ERROR_HOST_UNREACHABLE: case WSAENETRESET: case WSAECONNRESET: if (!sock->connected) { /* soft error */ need_retry = ISC_TRUE; break; } /* FALLTHROUGH */ default: isc_result = isc__errno2result(Error); if (isc_result == ISC_R_UNEXPECTED) UNEXPECTED_ERROR(__FILE__, __LINE__, "WSARecvFrom: Windows error code: %d, isc result %d", Error, isc_result); send_recvdone_abort(sock, isc_result); HeapFree(hHeapHandle, 0, lpo); lpo = NULL; break; } } else { /* * The recv() finished immediately, but we will still get * a completion event. Rather than duplicate code, let * that thread handle sending the data along its way. */ sock->pending_iocp++; sock->pending_recv++; } socket_log(__LINE__, sock, NULL, IOEVENT, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_DOIORECV, "queue_io_request: fd %d result %d error %d", sock->fd, Result, Error); CONSISTENT(sock); if (need_retry) goto retry; } static void manager_log(isc_socketmgr_t *sockmgr, isc_logcategory_t *category, isc_logmodule_t *module, int level, const char *fmt, ...) { char msgbuf[2048]; va_list ap; if (!isc_log_wouldlog(isc_lctx, level)) return; va_start(ap, fmt); vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); va_end(ap); isc_log_write(isc_lctx, category, module, level, "sockmgr %p: %s", sockmgr, msgbuf); } static void socket_log(int lineno, isc_socket_t *sock, isc_sockaddr_t *address, isc_logcategory_t *category, isc_logmodule_t *module, int level, isc_msgcat_t *msgcat, int msgset, int message, const char *fmt, ...) { char msgbuf[2048]; char peerbuf[256]; va_list ap; if (!isc_log_wouldlog(isc_lctx, level)) return; va_start(ap, fmt); vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); va_end(ap); if (address == NULL) { isc_log_iwrite(isc_lctx, category, module, level, msgcat, msgset, message, "socket %p line %d: %s", sock, lineno, msgbuf); } else { isc_sockaddr_format(address, peerbuf, sizeof(peerbuf)); isc_log_iwrite(isc_lctx, category, module, level, msgcat, msgset, message, "socket %p line %d peer %s: %s", sock, lineno, peerbuf, msgbuf); } } /* * Make an fd SOCKET non-blocking. */ static isc_result_t make_nonblock(SOCKET fd) { int ret; unsigned long flags = 1; char strbuf[ISC_STRERRORSIZE]; /* Set the socket to non-blocking */ ret = ioctlsocket(fd, FIONBIO, &flags); if (ret == -1) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "ioctlsocket(%d, FIOBIO, %d): %s", fd, flags, strbuf); return (ISC_R_UNEXPECTED); } return (ISC_R_SUCCESS); } /* * Windows 2000 systems incorrectly cause UDP sockets using WSARecvFrom * to not work correctly, returning a WSACONNRESET error when a WSASendTo * fails with an "ICMP port unreachable" response and preventing the * socket from using the WSARecvFrom in subsequent operations. * The function below fixes this, but requires that Windows 2000 * Service Pack 2 or later be installed on the system. NT 4.0 * systems are not affected by this and work correctly. * See Microsoft Knowledge Base Article Q263823 for details of this. */ isc_result_t connection_reset_fix(SOCKET fd) { DWORD dwBytesReturned = 0; BOOL bNewBehavior = FALSE; DWORD status; if (isc_win32os_versioncheck(5, 0, 0, 0) < 0) return (ISC_R_SUCCESS); /* NT 4.0 has no problem */ /* disable bad behavior using IOCTL: SIO_UDP_CONNRESET */ status = WSAIoctl(fd, SIO_UDP_CONNRESET, &bNewBehavior, sizeof(bNewBehavior), NULL, 0, &dwBytesReturned, NULL, NULL); if (status != SOCKET_ERROR) return (ISC_R_SUCCESS); else { UNEXPECTED_ERROR(__FILE__, __LINE__, "WSAIoctl(SIO_UDP_CONNRESET, oldBehaviour) %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); return (ISC_R_UNEXPECTED); } } /* * Construct an iov array and attach it to the msghdr passed in. This is * the SEND constructor, which will use the used region of the buffer * (if using a buffer list) or will use the internal region (if a single * buffer I/O is requested). * * Nothing can be NULL, and the done event must list at least one buffer * on the buffer linked list for this function to be meaningful. */ static void build_msghdr_send(isc_socket_t *sock, isc_socketevent_t *dev, struct msghdr *msg, char *cmsg, WSABUF *iov, IoCompletionInfo *lpo) { unsigned int iovcount; isc_buffer_t *buffer; buflist_t *cpbuffer; isc_region_t used; size_t write_count; size_t skip_count; memset(msg, 0, sizeof(*msg)); memmove(&msg->to_addr, &dev->address.type, dev->address.length); msg->to_addr_len = dev->address.length; buffer = ISC_LIST_HEAD(dev->bufferlist); write_count = 0; iovcount = 0; /* * Single buffer I/O? Skip what we've done so far in this region. */ if (buffer == NULL) { write_count = dev->region.length - dev->n; cpbuffer = HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, sizeof(buflist_t)); RUNTIME_CHECK(cpbuffer != NULL); cpbuffer->buf = HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, write_count); RUNTIME_CHECK(cpbuffer->buf != NULL); socket_log(__LINE__, sock, NULL, TRACE, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTLOCK, "alloc_buffer %p %d %p %d", cpbuffer, sizeof(buflist_t), cpbuffer->buf, write_count); memmove(cpbuffer->buf,(dev->region.base + dev->n), write_count); cpbuffer->buflen = (unsigned int)write_count; ISC_LIST_ENQUEUE(lpo->bufferlist, cpbuffer, link); iov[0].buf = cpbuffer->buf; iov[0].len = (u_long)write_count; iovcount = 1; goto config; } /* * Multibuffer I/O. * Skip the data in the buffer list that we have already written. */ skip_count = dev->n; while (buffer != NULL) { REQUIRE(ISC_BUFFER_VALID(buffer)); if (skip_count < isc_buffer_usedlength(buffer)) break; skip_count -= isc_buffer_usedlength(buffer); buffer = ISC_LIST_NEXT(buffer, link); } while (buffer != NULL) { INSIST(iovcount < MAXSCATTERGATHER_SEND); isc_buffer_usedregion(buffer, &used); if (used.length > 0) { int uselen = (int)(used.length - skip_count); cpbuffer = HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, sizeof(buflist_t)); RUNTIME_CHECK(cpbuffer != NULL); cpbuffer->buf = HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, uselen); RUNTIME_CHECK(cpbuffer->buf != NULL); socket_log(__LINE__, sock, NULL, TRACE, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTLOCK, "alloc_buffer %p %d %p %d", cpbuffer, sizeof(buflist_t), cpbuffer->buf, write_count); memmove(cpbuffer->buf,(used.base + skip_count), uselen); cpbuffer->buflen = uselen; iov[iovcount].buf = cpbuffer->buf; iov[iovcount].len = (u_long)(used.length - skip_count); write_count += uselen; skip_count = 0; iovcount++; } buffer = ISC_LIST_NEXT(buffer, link); } INSIST(skip_count == 0); config: msg->msg_iov = iov; msg->msg_iovlen = iovcount; msg->msg_totallen = (u_int)write_count; } static void set_dev_address(isc_sockaddr_t *address, isc_socket_t *sock, isc_socketevent_t *dev) { if (sock->type == isc_sockettype_udp) { if (address != NULL) dev->address = *address; else dev->address = sock->address; } else if (sock->type == isc_sockettype_tcp) { INSIST(address == NULL); dev->address = sock->address; } } static void destroy_socketevent(isc_event_t *event) { isc_socketevent_t *ev = (isc_socketevent_t *)event; INSIST(ISC_LIST_EMPTY(ev->bufferlist)); (ev->destroy)(event); } static isc_socketevent_t * allocate_socketevent(isc_mem_t *mctx, isc_socket_t *sock, isc_eventtype_t eventtype, isc_taskaction_t action, void *arg) { isc_socketevent_t *ev; ev = (isc_socketevent_t *)isc_event_allocate(mctx, sock, eventtype, action, arg, sizeof(*ev)); if (ev == NULL) return (NULL); ev->result = ISC_R_IOERROR; // XXXMLG temporary change to detect failure to set ISC_LINK_INIT(ev, ev_link); ISC_LIST_INIT(ev->bufferlist); ev->region.base = NULL; ev->n = 0; ev->offset = 0; ev->attributes = 0; ev->destroy = ev->ev_destroy; ev->ev_destroy = destroy_socketevent; ev->dscp = 0; return (ev); } #if defined(ISC_SOCKET_DEBUG) static void dump_msg(struct msghdr *msg, isc_socket_t *sock) { unsigned int i; printf("MSGHDR %p, Socket #: %u\n", msg, sock->fd); printf("\tname %p, namelen %d\n", msg->msg_name, msg->msg_namelen); printf("\tiov %p, iovlen %d\n", msg->msg_iov, msg->msg_iovlen); for (i = 0; i < (unsigned int)msg->msg_iovlen; i++) printf("\t\t%u\tbase %p, len %u\n", i, msg->msg_iov[i].buf, msg->msg_iov[i].len); } #endif /* * map the error code */ int map_socket_error(isc_socket_t *sock, int windows_errno, int *isc_errno, char *errorstring, size_t bufsize) { int doreturn; switch (windows_errno) { case WSAECONNREFUSED: *isc_errno = ISC_R_CONNREFUSED; if (sock->connected) doreturn = DOIO_HARD; else doreturn = DOIO_SOFT; break; case WSAENETUNREACH: case ERROR_NETWORK_UNREACHABLE: *isc_errno = ISC_R_NETUNREACH; if (sock->connected) doreturn = DOIO_HARD; else doreturn = DOIO_SOFT; break; case ERROR_PORT_UNREACHABLE: case ERROR_HOST_UNREACHABLE: case WSAEHOSTUNREACH: *isc_errno = ISC_R_HOSTUNREACH; if (sock->connected) doreturn = DOIO_HARD; else doreturn = DOIO_SOFT; break; case WSAENETDOWN: *isc_errno = ISC_R_NETDOWN; if (sock->connected) doreturn = DOIO_HARD; else doreturn = DOIO_SOFT; break; case WSAEHOSTDOWN: *isc_errno = ISC_R_HOSTDOWN; if (sock->connected) doreturn = DOIO_HARD; else doreturn = DOIO_SOFT; break; case WSAEACCES: *isc_errno = ISC_R_NOPERM; if (sock->connected) doreturn = DOIO_HARD; else doreturn = DOIO_SOFT; break; case WSAECONNRESET: case WSAENETRESET: case WSAECONNABORTED: case WSAEDISCON: *isc_errno = ISC_R_CONNECTIONRESET; if (sock->connected) doreturn = DOIO_HARD; else doreturn = DOIO_SOFT; break; case WSAENOTCONN: *isc_errno = ISC_R_NOTCONNECTED; if (sock->connected) doreturn = DOIO_HARD; else doreturn = DOIO_SOFT; break; case ERROR_OPERATION_ABORTED: case ERROR_CONNECTION_ABORTED: case ERROR_REQUEST_ABORTED: *isc_errno = ISC_R_CONNECTIONRESET; doreturn = DOIO_HARD; break; case WSAENOBUFS: *isc_errno = ISC_R_NORESOURCES; doreturn = DOIO_HARD; break; case WSAEAFNOSUPPORT: *isc_errno = ISC_R_FAMILYNOSUPPORT; doreturn = DOIO_HARD; break; case WSAEADDRNOTAVAIL: *isc_errno = ISC_R_ADDRNOTAVAIL; doreturn = DOIO_HARD; break; case WSAEDESTADDRREQ: *isc_errno = ISC_R_BADADDRESSFORM; doreturn = DOIO_HARD; break; case ERROR_NETNAME_DELETED: *isc_errno = ISC_R_NETDOWN; doreturn = DOIO_HARD; break; default: *isc_errno = ISC_R_IOERROR; doreturn = DOIO_HARD; break; } if (doreturn == DOIO_HARD) { isc__strerror(windows_errno, errorstring, bufsize); } return (doreturn); } static void fill_recv(isc_socket_t *sock, isc_socketevent_t *dev) { isc_region_t r; int copylen; isc_buffer_t *buffer; INSIST(dev->n < dev->minimum); INSIST(sock->recvbuf.remaining > 0); INSIST(sock->pending_recv == 0); if (sock->type == isc_sockettype_udp) { dev->address.length = sock->recvbuf.from_addr_len; memmove(&dev->address.type, &sock->recvbuf.from_addr, sock->recvbuf.from_addr_len); if (isc_sockaddr_getport(&dev->address) == 0) { if (isc_log_wouldlog(isc_lctx, IOEVENT_LEVEL)) { socket_log(__LINE__, sock, &dev->address, IOEVENT, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ZEROPORT, "dropping source port zero packet"); } sock->recvbuf.remaining = 0; return; } } else if (sock->type == isc_sockettype_tcp) { dev->address = sock->address; } /* * Run through the list of buffers we were given, and find the * first one with space. Once it is found, loop through, filling * the buffers as much as possible. */ buffer = ISC_LIST_HEAD(dev->bufferlist); if (buffer != NULL) { // Multi-buffer receive while (buffer != NULL && sock->recvbuf.remaining > 0) { REQUIRE(ISC_BUFFER_VALID(buffer)); if (isc_buffer_availablelength(buffer) > 0) { isc_buffer_availableregion(buffer, &r); copylen = min(r.length, sock->recvbuf.remaining); memmove(r.base, sock->recvbuf.consume_position, copylen); sock->recvbuf.consume_position += copylen; sock->recvbuf.remaining -= copylen; isc_buffer_add(buffer, copylen); dev->n += copylen; } buffer = ISC_LIST_NEXT(buffer, link); } } else { // Single-buffer receive copylen = min(dev->region.length - dev->n, sock->recvbuf.remaining); memmove(dev->region.base + dev->n, sock->recvbuf.consume_position, copylen); sock->recvbuf.consume_position += copylen; sock->recvbuf.remaining -= copylen; dev->n += copylen; } /* * UDP receives are all-consuming. That is, if we have 4k worth of * data in our receive buffer, and the caller only gave us * 1k of space, we will toss the remaining 3k of data. TCP * will keep the extra data around and use it for later requests. */ if (sock->type == isc_sockettype_udp) sock->recvbuf.remaining = 0; } /* * Copy out as much data from the internal buffer to done events. * As each done event is filled, send it along its way. */ static void completeio_recv(isc_socket_t *sock) { isc_socketevent_t *dev; /* * If we are in the process of filling our buffer, we cannot * touch it yet, so don't. */ if (sock->pending_recv > 0) return; while (sock->recvbuf.remaining > 0 && !ISC_LIST_EMPTY(sock->recv_list)) { dev = ISC_LIST_HEAD(sock->recv_list); /* * See if we have sufficient data in our receive buffer * to handle this. If we do, copy out the data. */ fill_recv(sock, dev); /* * Did we satisfy it? */ if (dev->n >= dev->minimum) { dev->result = ISC_R_SUCCESS; send_recvdone_event(sock, &dev); } } } /* * Returns: * DOIO_SUCCESS The operation succeeded. dev->result contains * ISC_R_SUCCESS. * * DOIO_HARD A hard or unexpected I/O error was encountered. * dev->result contains the appropriate error. * * DOIO_SOFT A soft I/O error was encountered. No senddone * event was sent. The operation should be retried. * * No other return values are possible. */ static int completeio_send(isc_socket_t *sock, isc_socketevent_t *dev, struct msghdr *messagehdr, int cc, int send_errno) { char addrbuf[ISC_SOCKADDR_FORMATSIZE]; char strbuf[ISC_STRERRORSIZE]; if (send_errno != 0) { if (SOFT_ERROR(send_errno)) return (DOIO_SOFT); return (map_socket_error(sock, send_errno, &dev->result, strbuf, sizeof(strbuf))); /* * The other error types depend on whether or not the * socket is UDP or TCP. If it is UDP, some errors * that we expect to be fatal under TCP are merely * annoying, and are really soft errors. * * However, these soft errors are still returned as * a status. */ isc_sockaddr_format(&dev->address, addrbuf, sizeof(addrbuf)); isc__strerror(send_errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "completeio_send: %s: %s", addrbuf, strbuf); dev->result = isc__errno2result(send_errno); return (DOIO_HARD); } /* * If we write less than we expected, update counters, poke. */ dev->n += cc; if (cc != messagehdr->msg_totallen) return (DOIO_SOFT); /* * Exactly what we wanted to write. We're done with this * entry. Post its completion event. */ dev->result = ISC_R_SUCCESS; return (DOIO_SUCCESS); } static int startio_send(isc_socket_t *sock, isc_socketevent_t *dev, int *nbytes, int *send_errno) { char *cmsg = NULL; char strbuf[ISC_STRERRORSIZE]; IoCompletionInfo *lpo; int status; struct msghdr *msghdr; lpo = (IoCompletionInfo *)HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, sizeof(IoCompletionInfo)); RUNTIME_CHECK(lpo != NULL); lpo->request_type = SOCKET_SEND; lpo->dev = dev; msghdr = &lpo->messagehdr; memset(msghdr, 0, sizeof(struct msghdr)); ISC_LIST_INIT(lpo->bufferlist); build_msghdr_send(sock, dev, msghdr, cmsg, sock->iov, lpo); *nbytes = internal_sendmsg(sock, lpo, msghdr, 0, send_errno); if (*nbytes <= 0) { /* * I/O has been initiated * completion will be through the completion port */ if (PENDING_ERROR(*send_errno)) { status = DOIO_PENDING; goto done; } if (SOFT_ERROR(*send_errno)) { status = DOIO_SOFT; goto done; } /* * If we got this far then something is wrong */ if (isc_log_wouldlog(isc_lctx, IOEVENT_LEVEL)) { isc__strerror(*send_errno, strbuf, sizeof(strbuf)); socket_log(__LINE__, sock, NULL, IOEVENT, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_INTERNALSEND, "startio_send: internal_sendmsg(%d) %d " "bytes, err %d/%s", sock->fd, *nbytes, *send_errno, strbuf); } status = DOIO_HARD; goto done; } dev->result = ISC_R_SUCCESS; status = DOIO_SOFT; done: _set_state(sock, SOCK_DATA); return (status); } static void use_min_mtu(isc_socket_t *sock) { #ifdef IPV6_USE_MIN_MTU /* use minimum MTU */ if (sock->pf == AF_INET6) { int on = 1; (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, (void *)&on, sizeof(on)); } #else UNUSED(sock); #endif } static isc_result_t allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type, isc_socket_t **socketp) { isc_socket_t *sock; isc_result_t result; sock = isc_mem_get(manager->mctx, sizeof(*sock)); if (sock == NULL) return (ISC_R_NOMEMORY); sock->magic = 0; sock->references = 0; sock->manager = manager; sock->type = type; sock->fd = INVALID_SOCKET; ISC_LINK_INIT(sock, link); /* * Set up list of readers and writers to be initially empty. */ ISC_LIST_INIT(sock->recv_list); ISC_LIST_INIT(sock->send_list); ISC_LIST_INIT(sock->accept_list); sock->connect_ev = NULL; sock->pending_accept = 0; sock->pending_recv = 0; sock->pending_send = 0; sock->pending_iocp = 0; sock->listener = 0; sock->connected = 0; sock->pending_connect = 0; sock->bound = 0; sock->dupped = 0; memset(sock->name, 0, sizeof(sock->name)); // zero the name field _set_state(sock, SOCK_INITIALIZED); sock->recvbuf.len = 65536; sock->recvbuf.consume_position = sock->recvbuf.base; sock->recvbuf.remaining = 0; sock->recvbuf.base = isc_mem_get(manager->mctx, sock->recvbuf.len); // max buffer size if (sock->recvbuf.base == NULL) { result = ISC_R_NOMEMORY; goto error; } /* * Initialize the lock. */ result = isc_mutex_init(&sock->lock); if (result != ISC_R_SUCCESS) goto error; socket_log(__LINE__, sock, NULL, EVENT, NULL, 0, 0, "allocated"); sock->magic = SOCKET_MAGIC; *socketp = sock; return (ISC_R_SUCCESS); error: if (sock->recvbuf.base != NULL) isc_mem_put(manager->mctx, sock->recvbuf.base, sock->recvbuf.len); isc_mem_put(manager->mctx, sock, sizeof(*sock)); return (result); } /* * Verify that the socket state is consistent. */ static void consistent(isc_socket_t *sock) { isc_socketevent_t *dev; isc_socket_newconnev_t *nev; unsigned int count; char *crash_reason; isc_boolean_t crash = ISC_FALSE; REQUIRE(sock->pending_iocp == sock->pending_recv + sock->pending_send + sock->pending_accept + sock->pending_connect); dev = ISC_LIST_HEAD(sock->send_list); count = 0; while (dev != NULL) { count++; dev = ISC_LIST_NEXT(dev, ev_link); } if (count > sock->pending_send) { crash = ISC_TRUE; crash_reason = "send_list > sock->pending_send"; } nev = ISC_LIST_HEAD(sock->accept_list); count = 0; while (nev != NULL) { count++; nev = ISC_LIST_NEXT(nev, ev_link); } if (count > sock->pending_accept) { crash = ISC_TRUE; crash_reason = "send_list > sock->pending_send"; } if (crash) { socket_log(__LINE__, sock, NULL, CREATION, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_DESTROYING, "SOCKET INCONSISTENT: %s", crash_reason); sock_dump(sock); INSIST(crash == ISC_FALSE); } } /* * Maybe free the socket. * * This function will verify tht the socket is no longer in use in any way, * either internally or externally. This is the only place where this * check is to be made; if some bit of code believes that IT is done with * the socket (e.g., some reference counter reaches zero), it should call * this function. * * When calling this function, the socket must be locked, and the manager * must be unlocked. * * When this function returns, *socketp will be NULL. No tricks to try * to hold on to this pointer are allowed. */ static void maybe_free_socket(isc_socket_t **socketp, int lineno) { isc_socket_t *sock = *socketp; *socketp = NULL; INSIST(VALID_SOCKET(sock)); CONSISTENT(sock); if (sock->pending_iocp > 0 || sock->pending_recv > 0 || sock->pending_send > 0 || sock->pending_accept > 0 || sock->references > 0 || sock->pending_connect == 1 || !ISC_LIST_EMPTY(sock->recv_list) || !ISC_LIST_EMPTY(sock->send_list) || !ISC_LIST_EMPTY(sock->accept_list) || sock->fd != INVALID_SOCKET) { UNLOCK(&sock->lock); return; } UNLOCK(&sock->lock); free_socket(&sock, lineno); } void free_socket(isc_socket_t **sockp, int lineno) { isc_socketmgr_t *manager; isc_socket_t *sock = *sockp; *sockp = NULL; /* * Seems we can free the socket after all. */ manager = sock->manager; socket_log(__LINE__, sock, NULL, CREATION, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_DESTROYING, "freeing socket line %d fd %d lock %p semaphore %p", lineno, sock->fd, &sock->lock, sock->lock.LockSemaphore); sock->magic = 0; DESTROYLOCK(&sock->lock); if (sock->recvbuf.base != NULL) isc_mem_put(manager->mctx, sock->recvbuf.base, sock->recvbuf.len); LOCK(&manager->lock); if (ISC_LINK_LINKED(sock, link)) ISC_LIST_UNLINK(manager->socklist, sock, link); isc_mem_put(manager->mctx, sock, sizeof(*sock)); if (ISC_LIST_EMPTY(manager->socklist)) SIGNAL(&manager->shutdown_ok); UNLOCK(&manager->lock); } /* * Create a new 'type' socket managed by 'manager'. Events * will be posted to 'task' and when dispatched 'action' will be * called with 'arg' as the arg value. The new socket is returned * in 'socketp'. */ static isc_result_t socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, isc_socket_t **socketp, isc_socket_t *dup_socket) { isc_socket_t *sock = NULL; isc_result_t result; #if defined(USE_CMSG) int on = 1; #endif #if defined(SO_RCVBUF) ISC_SOCKADDR_LEN_T optlen; int size; #endif int socket_errno; char strbuf[ISC_STRERRORSIZE]; REQUIRE(VALID_MANAGER(manager)); REQUIRE(socketp != NULL && *socketp == NULL); REQUIRE(type != isc_sockettype_fdwatch); #ifndef SOCK_RAW if (type == isc_sockettype_raw) return (ISC_R_NOTIMPLEMENTED); #endif result = allocate_socket(manager, type, &sock); if (result != ISC_R_SUCCESS) return (result); sock->pf = pf; switch (type) { case isc_sockettype_udp: sock->fd = socket(pf, SOCK_DGRAM, IPPROTO_UDP); if (sock->fd != INVALID_SOCKET) { result = connection_reset_fix(sock->fd); if (result != ISC_R_SUCCESS) { socket_log(__LINE__, sock, NULL, EVENT, NULL, 0, 0, "closed %d %d %d " "con_reset_fix_failed", sock->pending_recv, sock->pending_send, sock->references); closesocket(sock->fd); _set_state(sock, SOCK_CLOSED); sock->fd = INVALID_SOCKET; free_socket(&sock, __LINE__); return (result); } } break; case isc_sockettype_tcp: sock->fd = socket(pf, SOCK_STREAM, IPPROTO_TCP); break; #ifdef SOCK_RAW case isc_sockettype_raw: sock->fd = socket(pf, SOCK_RAW, 0); #ifdef PF_ROUTE if (pf == PF_ROUTE) sock->bound = 1; #endif break; #endif } if (sock->fd == INVALID_SOCKET) { socket_errno = WSAGetLastError(); free_socket(&sock, __LINE__); switch (socket_errno) { case WSAEMFILE: case WSAENOBUFS: return (ISC_R_NORESOURCES); case WSAEPROTONOSUPPORT: case WSAEPFNOSUPPORT: case WSAEAFNOSUPPORT: return (ISC_R_FAMILYNOSUPPORT); default: isc__strerror(socket_errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "socket() %s: %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); return (ISC_R_UNEXPECTED); } } result = make_nonblock(sock->fd); if (result != ISC_R_SUCCESS) { socket_log(__LINE__, sock, NULL, EVENT, NULL, 0, 0, "closed %d %d %d make_nonblock_failed", sock->pending_recv, sock->pending_send, sock->references); closesocket(sock->fd); sock->fd = INVALID_SOCKET; free_socket(&sock, __LINE__); return (result); } /* * Use minimum mtu if possible. */ use_min_mtu(sock); #if defined(USE_CMSG) || defined(SO_RCVBUF) if (type == isc_sockettype_udp) { #if defined(USE_CMSG) #if defined(ISC_PLATFORM_HAVEIPV6) #ifdef IPV6_RECVPKTINFO /* 2292bis */ if ((pf == AF_INET6) && (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, (char *)&on, sizeof(on)) < 0)) { isc__strerror(WSAGetLastError(), strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, IPV6_RECVPKTINFO) " "%s: %s", sock->fd, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); } #else /* 2292 */ if ((pf == AF_INET6) && (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_PKTINFO, (char *)&on, sizeof(on)) < 0)) { isc__strerror(WSAGetLastError(), strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d, IPV6_PKTINFO) %s: %s", sock->fd, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); } #endif /* IPV6_RECVPKTINFO */ #endif /* ISC_PLATFORM_HAVEIPV6 */ #endif /* defined(USE_CMSG) */ #if defined(SO_RCVBUF) optlen = sizeof(size); if (getsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF, (char *)&size, &optlen) >= 0 && size < RCVBUFSIZE) { size = RCVBUFSIZE; (void)setsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF, (char *)&size, sizeof(size)); } #endif } #endif /* defined(USE_CMSG) || defined(SO_RCVBUF) */ _set_state(sock, SOCK_OPEN); sock->references = 1; *socketp = sock; iocompletionport_update(sock); if (dup_socket) { #ifndef ISC_ALLOW_MAPPED isc__socket_ipv6only(sock, ISC_TRUE); #endif if (dup_socket->bound) { isc_sockaddr_t local; result = isc__socket_getsockname(dup_socket, &local); if (result != ISC_R_SUCCESS) { isc_socket_close(sock); return (result); } result = isc__socket_bind(sock, &local, ISC_SOCKET_REUSEADDRESS); if (result != ISC_R_SUCCESS) { isc_socket_close(sock); return (result); } } sock->dupped = 1; } /* * Note we don't have to lock the socket like we normally would because * there are no external references to it yet. */ LOCK(&manager->lock); ISC_LIST_APPEND(manager->socklist, sock, link); InterlockedIncrement(&manager->totalSockets); UNLOCK(&manager->lock); socket_log(__LINE__, sock, NULL, CREATION, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_CREATED, "created %u type %u", sock->fd, type); return (ISC_R_SUCCESS); } isc_result_t isc__socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, isc_socket_t **socketp) { return (socket_create(manager, pf, type, socketp, NULL)); } isc_result_t isc__socket_dup(isc_socket_t *sock, isc_socket_t **socketp) { REQUIRE(VALID_SOCKET(sock)); REQUIRE(socketp != NULL && *socketp == NULL); return (socket_create(sock->manager, sock->pf, sock->type, socketp, sock)); } isc_result_t isc_socket_open(isc_socket_t *sock) { REQUIRE(VALID_SOCKET(sock)); REQUIRE(sock->type != isc_sockettype_fdwatch); return (ISC_R_NOTIMPLEMENTED); } /* * Attach to a socket. Caller must explicitly detach when it is done. */ void isc__socket_attach(isc_socket_t *sock, isc_socket_t **socketp) { REQUIRE(VALID_SOCKET(sock)); REQUIRE(socketp != NULL && *socketp == NULL); LOCK(&sock->lock); CONSISTENT(sock); sock->references++; UNLOCK(&sock->lock); *socketp = sock; } /* * Dereference a socket. If this is the last reference to it, clean things * up by destroying the socket. */ void isc__socket_detach(isc_socket_t **socketp) { isc_socket_t *sock; REQUIRE(socketp != NULL); sock = *socketp; REQUIRE(VALID_SOCKET(sock)); REQUIRE(sock->type != isc_sockettype_fdwatch); LOCK(&sock->lock); CONSISTENT(sock); REQUIRE(sock->references > 0); sock->references--; socket_log(__LINE__, sock, NULL, EVENT, NULL, 0, 0, "detach_socket %d %d %d", sock->pending_recv, sock->pending_send, sock->references); if (sock->references == 0 && sock->fd != INVALID_SOCKET) { closesocket(sock->fd); sock->fd = INVALID_SOCKET; _set_state(sock, SOCK_CLOSED); } maybe_free_socket(&sock, __LINE__); *socketp = NULL; } isc_result_t isc_socket_close(isc_socket_t *sock) { REQUIRE(VALID_SOCKET(sock)); REQUIRE(sock->type != isc_sockettype_fdwatch); return (ISC_R_NOTIMPLEMENTED); } /* * Dequeue an item off the given socket's read queue, set the result code * in the done event to the one provided, and send it to the task it was * destined for. * * If the event to be sent is on a list, remove it before sending. If * asked to, send and detach from the task as well. * * Caller must have the socket locked if the event is attached to the socket. */ static void send_recvdone_event(isc_socket_t *sock, isc_socketevent_t **dev) { isc_task_t *task; task = (*dev)->ev_sender; (*dev)->ev_sender = sock; if (ISC_LINK_LINKED(*dev, ev_link)) ISC_LIST_DEQUEUE(sock->recv_list, *dev, ev_link); if (((*dev)->attributes & ISC_SOCKEVENTATTR_ATTACHED) == ISC_SOCKEVENTATTR_ATTACHED) isc_task_sendanddetach(&task, (isc_event_t **)dev); else isc_task_send(task, (isc_event_t **)dev); CONSISTENT(sock); } /* * See comments for send_recvdone_event() above. */ static void send_senddone_event(isc_socket_t *sock, isc_socketevent_t **dev) { isc_task_t *task; INSIST(dev != NULL && *dev != NULL); task = (*dev)->ev_sender; (*dev)->ev_sender = sock; if (ISC_LINK_LINKED(*dev, ev_link)) ISC_LIST_DEQUEUE(sock->send_list, *dev, ev_link); if (((*dev)->attributes & ISC_SOCKEVENTATTR_ATTACHED) == ISC_SOCKEVENTATTR_ATTACHED) isc_task_sendanddetach(&task, (isc_event_t **)dev); else isc_task_send(task, (isc_event_t **)dev); CONSISTENT(sock); } /* * See comments for send_recvdone_event() above. */ static void send_acceptdone_event(isc_socket_t *sock, isc_socket_newconnev_t **adev) { isc_task_t *task; INSIST(adev != NULL && *adev != NULL); task = (*adev)->ev_sender; (*adev)->ev_sender = sock; if (ISC_LINK_LINKED(*adev, ev_link)) ISC_LIST_DEQUEUE(sock->accept_list, *adev, ev_link); isc_task_sendanddetach(&task, (isc_event_t **)adev); CONSISTENT(sock); } /* * See comments for send_recvdone_event() above. */ static void send_connectdone_event(isc_socket_t *sock, isc_socket_connev_t **cdev) { isc_task_t *task; INSIST(cdev != NULL && *cdev != NULL); task = (*cdev)->ev_sender; (*cdev)->ev_sender = sock; sock->connect_ev = NULL; isc_task_sendanddetach(&task, (isc_event_t **)cdev); CONSISTENT(sock); } /* * On entry to this function, the event delivered is the internal * readable event, and the first item on the accept_list should be * the done event we want to send. If the list is empty, this is a no-op, * so just close the new connection, unlock, and return. * * Note the socket is locked before entering here */ static void internal_accept(isc_socket_t *sock, IoCompletionInfo *lpo, int accept_errno) { isc_socket_newconnev_t *adev; isc_result_t result = ISC_R_SUCCESS; isc_socket_t *nsock; struct sockaddr *localaddr; int localaddr_len = sizeof(*localaddr); struct sockaddr *remoteaddr; int remoteaddr_len = sizeof(*remoteaddr); INSIST(VALID_SOCKET(sock)); LOCK(&sock->lock); CONSISTENT(sock); socket_log(__LINE__, sock, NULL, TRACE, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTLOCK, "internal_accept called"); INSIST(sock->listener); INSIST(sock->pending_iocp > 0); sock->pending_iocp--; INSIST(sock->pending_accept > 0); sock->pending_accept--; adev = lpo->adev; /* * If the event is no longer in the list we can just return. */ if (!acceptdone_is_active(sock, adev)) goto done; nsock = adev->newsocket; /* * Pull off the done event. */ ISC_LIST_UNLINK(sock->accept_list, adev, ev_link); /* * Extract the addresses from the socket, copy them into the structure, * and return the new socket. */ ISCGetAcceptExSockaddrs(lpo->acceptbuffer, 0, sizeof(SOCKADDR_STORAGE) + 16, sizeof(SOCKADDR_STORAGE) + 16, (LPSOCKADDR *)&localaddr, &localaddr_len, (LPSOCKADDR *)&remoteaddr, &remoteaddr_len); memmove(&adev->address.type, remoteaddr, remoteaddr_len); adev->address.length = remoteaddr_len; nsock->address = adev->address; nsock->pf = adev->address.type.sa.sa_family; socket_log(__LINE__, nsock, &nsock->address, TRACE, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTLOCK, "internal_accept parent %p", sock); result = make_nonblock(adev->newsocket->fd); INSIST(result == ISC_R_SUCCESS); /* * Use minimum mtu if possible. */ use_min_mtu(adev->newsocket); INSIST(setsockopt(nsock->fd, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char *)&sock->fd, sizeof(sock->fd)) == 0); /* * Hook it up into the manager. */ nsock->bound = 1; nsock->connected = 1; _set_state(nsock, SOCK_OPEN); LOCK(&nsock->manager->lock); ISC_LIST_APPEND(nsock->manager->socklist, nsock, link); InterlockedIncrement(&nsock->manager->totalSockets); UNLOCK(&nsock->manager->lock); socket_log(__LINE__, sock, &nsock->address, CREATION, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTEDCXN, "accepted_connection new_socket %p fd %d", nsock, nsock->fd); adev->result = result; send_acceptdone_event(sock, &adev); done: CONSISTENT(sock); UNLOCK(&sock->lock); HeapFree(hHeapHandle, 0, lpo->acceptbuffer); lpo->acceptbuffer = NULL; } /* * Called when a socket with a pending connect() finishes. * Note that the socket is locked before entering. */ static void internal_connect(isc_socket_t *sock, IoCompletionInfo *lpo, int connect_errno) { isc_socket_connev_t *cdev; char strbuf[ISC_STRERRORSIZE]; INSIST(VALID_SOCKET(sock)); LOCK(&sock->lock); INSIST(sock->pending_iocp > 0); sock->pending_iocp--; INSIST(sock->pending_connect == 1); sock->pending_connect = 0; /* * Has this event been canceled? */ cdev = lpo->cdev; if (!connectdone_is_active(sock, cdev)) { sock->pending_connect = 0; if (sock->fd != INVALID_SOCKET) { closesocket(sock->fd); sock->fd = INVALID_SOCKET; _set_state(sock, SOCK_CLOSED); } CONSISTENT(sock); UNLOCK(&sock->lock); return; } /* * Check possible Windows network event error status here. */ if (connect_errno != 0) { /* * If the error is SOFT, just try again on this * fd and pretend nothing strange happened. */ if (SOFT_ERROR(connect_errno) || connect_errno == WSAEINPROGRESS) { sock->pending_connect = 1; CONSISTENT(sock); UNLOCK(&sock->lock); return; } /* * Translate other errors into ISC_R_* flavors. */ switch (connect_errno) { #define ERROR_MATCH(a, b) case a: cdev->result = b; break; ERROR_MATCH(WSAEACCES, ISC_R_NOPERM); ERROR_MATCH(WSAEADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL); ERROR_MATCH(WSAEAFNOSUPPORT, ISC_R_ADDRNOTAVAIL); ERROR_MATCH(WSAECONNREFUSED, ISC_R_CONNREFUSED); ERROR_MATCH(WSAEHOSTUNREACH, ISC_R_HOSTUNREACH); ERROR_MATCH(WSAEHOSTDOWN, ISC_R_HOSTDOWN); ERROR_MATCH(WSAENETUNREACH, ISC_R_NETUNREACH); ERROR_MATCH(WSAENETDOWN, ISC_R_NETDOWN); ERROR_MATCH(WSAENOBUFS, ISC_R_NORESOURCES); ERROR_MATCH(WSAECONNRESET, ISC_R_CONNECTIONRESET); ERROR_MATCH(WSAECONNABORTED, ISC_R_CONNECTIONRESET); ERROR_MATCH(WSAETIMEDOUT, ISC_R_TIMEDOUT); #undef ERROR_MATCH default: cdev->result = ISC_R_UNEXPECTED; isc__strerror(connect_errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "internal_connect: connect() %s", strbuf); } } else { INSIST(setsockopt(sock->fd, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0) == 0); cdev->result = ISC_R_SUCCESS; sock->connected = 1; socket_log(__LINE__, sock, &sock->address, IOEVENT, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTEDCXN, "internal_connect: success"); } send_connectdone_event(sock, &cdev); UNLOCK(&sock->lock); } /* * Loop through the socket, returning ISC_R_EOF for each done event pending. */ static void send_recvdone_abort(isc_socket_t *sock, isc_result_t result) { isc_socketevent_t *dev; while (!ISC_LIST_EMPTY(sock->recv_list)) { dev = ISC_LIST_HEAD(sock->recv_list); dev->result = result; send_recvdone_event(sock, &dev); } } /* * Take the data we received in our private buffer, and if any recv() calls on * our list are satisfied, send the corresponding done event. * * If we need more data (there are still items on the recv_list after we consume all * our data) then arrange for another system recv() call to fill our buffers. */ static void internal_recv(isc_socket_t *sock, int nbytes) { INSIST(VALID_SOCKET(sock)); LOCK(&sock->lock); CONSISTENT(sock); socket_log(__LINE__, sock, NULL, IOEVENT, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_INTERNALRECV, "internal_recv: %d bytes received", nbytes); /* * If we got here, the I/O operation succeeded. However, we might still have removed this * event from our notification list (or never placed it on it due to immediate completion.) * Handle the reference counting here, and handle the cancellation event just after. */ INSIST(sock->pending_iocp > 0); sock->pending_iocp--; INSIST(sock->pending_recv > 0); sock->pending_recv--; /* * The only way we could have gotten here is that our I/O has successfully completed. * Update our pointers, and move on. The only odd case here is that we might not * have received enough data on a TCP stream to satisfy the minimum requirements. If * this is the case, we will re-issue the recv() call for what we need. * * We do check for a recv() of 0 bytes on a TCP stream. This means the remote end * has closed. */ if (nbytes == 0 && sock->type == isc_sockettype_tcp) { send_recvdone_abort(sock, ISC_R_EOF); maybe_free_socket(&sock, __LINE__); return; } sock->recvbuf.remaining = nbytes; sock->recvbuf.consume_position = sock->recvbuf.base; completeio_recv(sock); /* * If there are more receivers waiting for data, queue another receive * here. */ queue_receive_request(sock); /* * Unlock and/or destroy if we are the last thing this socket has left to do. */ maybe_free_socket(&sock, __LINE__); } static void internal_send(isc_socket_t *sock, isc_socketevent_t *dev, struct msghdr *messagehdr, int nbytes, int send_errno, IoCompletionInfo *lpo) { buflist_t *buffer; /* * Find out what socket this is and lock it. */ INSIST(VALID_SOCKET(sock)); LOCK(&sock->lock); CONSISTENT(sock); socket_log(__LINE__, sock, NULL, IOEVENT, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_INTERNALSEND, "internal_send: task got socket event %p", dev); buffer = ISC_LIST_HEAD(lpo->bufferlist); while (buffer != NULL) { ISC_LIST_DEQUEUE(lpo->bufferlist, buffer, link); socket_log(__LINE__, sock, NULL, TRACE, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTLOCK, "free_buffer %p %p", buffer, buffer->buf); HeapFree(hHeapHandle, 0, buffer->buf); HeapFree(hHeapHandle, 0, buffer); buffer = ISC_LIST_HEAD(lpo->bufferlist); } INSIST(sock->pending_iocp > 0); sock->pending_iocp--; INSIST(sock->pending_send > 0); sock->pending_send--; /* If the event is no longer in the list we can just return */ if (!senddone_is_active(sock, dev)) goto done; /* * Set the error code and send things on its way. */ switch (completeio_send(sock, dev, messagehdr, nbytes, send_errno)) { case DOIO_SOFT: break; case DOIO_HARD: case DOIO_SUCCESS: send_senddone_event(sock, &dev); break; } done: maybe_free_socket(&sock, __LINE__); } /* * These return if the done event passed in is on the list (or for connect, is * the one we're waiting for. Using these ensures we will not double-send an * event. */ static isc_boolean_t senddone_is_active(isc_socket_t *sock, isc_socketevent_t *dev) { isc_socketevent_t *ldev; ldev = ISC_LIST_HEAD(sock->send_list); while (ldev != NULL && ldev != dev) ldev = ISC_LIST_NEXT(ldev, ev_link); return (ldev == NULL ? ISC_FALSE : ISC_TRUE); } static isc_boolean_t acceptdone_is_active(isc_socket_t *sock, isc_socket_newconnev_t *dev) { isc_socket_newconnev_t *ldev; ldev = ISC_LIST_HEAD(sock->accept_list); while (ldev != NULL && ldev != dev) ldev = ISC_LIST_NEXT(ldev, ev_link); return (ldev == NULL ? ISC_FALSE : ISC_TRUE); } static isc_boolean_t connectdone_is_active(isc_socket_t *sock, isc_socket_connev_t *dev) { return (sock->connect_ev == dev ? ISC_TRUE : ISC_FALSE); } // // The Windows network stack seems to have two very distinct paths depending // on what is installed. Specifically, if something is looking at network // connections (like an anti-virus or anti-malware application, such as // McAfee products) Windows may return additional error conditions which // were not previously returned. // // One specific one is when a TCP SYN scan is used. In this situation, // Windows responds with the SYN-ACK, but the scanner never responds with // the 3rd packet, the ACK. Windows consiers this a partially open connection. // Most Unix networking stacks, and Windows without McAfee installed, will // not return this to the caller. However, with this product installed, // Windows returns this as a failed status on the Accept() call. Here, we // will just re-issue the ISCAcceptEx() call as if nothing had happened. // // This code should only be called when the listening socket has received // such an error. Additionally, the "parent" socket must be locked. // Additionally, the lpo argument is re-used here, and must not be freed // by the caller. // static isc_result_t restart_accept(isc_socket_t *parent, IoCompletionInfo *lpo) { isc_socket_t *nsock = lpo->adev->newsocket; SOCKET new_fd; /* * AcceptEx() requires we pass in a socket. Note that we carefully * do not close the previous socket in case of an error message returned by * our new socket() call. If we return an error here, our caller will * clean up. */ new_fd = socket(parent->pf, SOCK_STREAM, IPPROTO_TCP); if (nsock->fd == INVALID_SOCKET) { return (ISC_R_FAILURE); // parent will ask windows for error message } closesocket(nsock->fd); nsock->fd = new_fd; memset(&lpo->overlapped, 0, sizeof(lpo->overlapped)); ISCAcceptEx(parent->fd, nsock->fd, /* Accepted Socket */ lpo->acceptbuffer, /* Buffer for initial Recv */ 0, /* Length of Buffer */ sizeof(SOCKADDR_STORAGE) + 16, /* Local address length + 16 */ sizeof(SOCKADDR_STORAGE) + 16, /* Remote address lengh + 16 */ (LPDWORD)&lpo->received_bytes, /* Bytes Recved */ (LPOVERLAPPED)lpo /* Overlapped structure */ ); InterlockedDecrement(&nsock->manager->iocp_total); iocompletionport_update(nsock); return (ISC_R_SUCCESS); } /* * This is the I/O Completion Port Worker Function. It loops forever * waiting for I/O to complete and then forwards them for further * processing. There are a number of these in separate threads. */ static isc_threadresult_t WINAPI SocketIoThread(LPVOID ThreadContext) { isc_socketmgr_t *manager = ThreadContext; BOOL bSuccess = FALSE; DWORD nbytes; IoCompletionInfo *lpo = NULL; isc_socket_t *sock = NULL; int request; struct msghdr *messagehdr = NULL; int errval; char strbuf[ISC_STRERRORSIZE]; int errstatus; REQUIRE(VALID_MANAGER(manager)); /* * Set the thread priority high enough so I/O will * preempt normal recv packet processing, but not * higher than the timer sync thread. */ if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL)) { errval = GetLastError(); isc__strerror(errval, strbuf, sizeof(strbuf)); FATAL_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_FAILED, "Can't set thread priority: %s"), strbuf); } /* * Loop forever waiting on I/O Completions and then processing them */ while (TRUE) { wait_again: bSuccess = GetQueuedCompletionStatus(manager->hIoCompletionPort, &nbytes, (PULONG_PTR)&sock, (LPWSAOVERLAPPED *)&lpo, INFINITE); if (lpo == NULL) /* Received request to exit */ break; REQUIRE(VALID_SOCKET(sock)); request = lpo->request_type; errstatus = 0; if (!bSuccess) { isc_result_t isc_result; /* * Did the I/O operation complete? */ errstatus = GetLastError(); isc_result = isc__errno2resultx(errstatus, __FILE__, __LINE__); LOCK(&sock->lock); CONSISTENT(sock); switch (request) { case SOCKET_RECV: INSIST(sock->pending_iocp > 0); sock->pending_iocp--; INSIST(sock->pending_recv > 0); sock->pending_recv--; if (!sock->connected && ((errstatus == ERROR_HOST_UNREACHABLE) || (errstatus == WSAENETRESET) || (errstatus == WSAECONNRESET))) { /* ignore soft errors */ queue_receive_request(sock); break; } send_recvdone_abort(sock, isc_result); if (isc_result == ISC_R_UNEXPECTED) { UNEXPECTED_ERROR(__FILE__, __LINE__, "SOCKET_RECV: Windows error code: %d, returning ISC error %d", errstatus, isc_result); } break; case SOCKET_SEND: INSIST(sock->pending_iocp > 0); sock->pending_iocp--; INSIST(sock->pending_send > 0); sock->pending_send--; if (senddone_is_active(sock, lpo->dev)) { lpo->dev->result = isc_result; socket_log(__LINE__, sock, NULL, EVENT, NULL, 0, 0, "canceled_send"); send_senddone_event(sock, &lpo->dev); } break; case SOCKET_ACCEPT: INSIST(sock->pending_iocp > 0); INSIST(sock->pending_accept > 0); socket_log(__LINE__, sock, NULL, EVENT, NULL, 0, 0, "Accept: errstatus=%d isc_result=%d", errstatus, isc_result); if (acceptdone_is_active(sock, lpo->adev)) { if (restart_accept(sock, lpo) == ISC_R_SUCCESS) { UNLOCK(&sock->lock); goto wait_again; } else { errstatus = GetLastError(); isc_result = isc__errno2resultx(errstatus, __FILE__, __LINE__); socket_log(__LINE__, sock, NULL, EVENT, NULL, 0, 0, "restart_accept() failed: errstatus=%d isc_result=%d", errstatus, isc_result); } } sock->pending_iocp--; sock->pending_accept--; if (acceptdone_is_active(sock, lpo->adev)) { closesocket(lpo->adev->newsocket->fd); lpo->adev->newsocket->fd = INVALID_SOCKET; lpo->adev->newsocket->references--; free_socket(&lpo->adev->newsocket, __LINE__); lpo->adev->result = isc_result; socket_log(__LINE__, sock, NULL, EVENT, NULL, 0, 0, "canceled_accept"); send_acceptdone_event(sock, &lpo->adev); } break; case SOCKET_CONNECT: INSIST(sock->pending_iocp > 0); sock->pending_iocp--; INSIST(sock->pending_connect == 1); sock->pending_connect = 0; if (connectdone_is_active(sock, lpo->cdev)) { lpo->cdev->result = isc_result; socket_log(__LINE__, sock, NULL, EVENT, NULL, 0, 0, "canceled_connect"); send_connectdone_event(sock, &lpo->cdev); } break; } maybe_free_socket(&sock, __LINE__); if (lpo != NULL) HeapFree(hHeapHandle, 0, lpo); continue; } messagehdr = &lpo->messagehdr; switch (request) { case SOCKET_RECV: internal_recv(sock, nbytes); break; case SOCKET_SEND: internal_send(sock, lpo->dev, messagehdr, nbytes, errstatus, lpo); break; case SOCKET_ACCEPT: internal_accept(sock, lpo, errstatus); break; case SOCKET_CONNECT: internal_connect(sock, lpo, errstatus); break; } if (lpo != NULL) HeapFree(hHeapHandle, 0, lpo); } /* * Exit Completion Port Thread */ manager_log(manager, TRACE, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_EXITING, "SocketIoThread exiting")); return ((isc_threadresult_t)0); } /* * Create a new socket manager. */ isc_result_t isc__socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) { return (isc_socketmgr_create2(mctx, managerp, 0)); } isc_result_t isc__socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp, unsigned int maxsocks) { isc_socketmgr_t *manager; isc_result_t result; REQUIRE(managerp != NULL && *managerp == NULL); if (maxsocks != 0) return (ISC_R_NOTIMPLEMENTED); manager = isc_mem_get(mctx, sizeof(*manager)); if (manager == NULL) return (ISC_R_NOMEMORY); InitSockets(); manager->magic = SOCKET_MANAGER_MAGIC; manager->mctx = NULL; manager->stats = NULL; ISC_LIST_INIT(manager->socklist); result = isc_mutex_init(&manager->lock); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, manager, sizeof(*manager)); return (result); } if (isc_condition_init(&manager->shutdown_ok) != ISC_R_SUCCESS) { DESTROYLOCK(&manager->lock); isc_mem_put(mctx, manager, sizeof(*manager)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_condition_init() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); return (ISC_R_UNEXPECTED); } isc_mem_attach(mctx, &manager->mctx); iocompletionport_init(manager); /* Create the Completion Ports */ manager->bShutdown = ISC_FALSE; manager->totalSockets = 0; manager->iocp_total = 0; *managerp = manager; return (ISC_R_SUCCESS); } isc_result_t isc_socketmgr_getmaxsockets(isc_socketmgr_t *manager, unsigned int *nsockp) { REQUIRE(VALID_MANAGER(manager)); REQUIRE(nsockp != NULL); return (ISC_R_NOTIMPLEMENTED); } void isc_socketmgr_setstats(isc_socketmgr_t *manager, isc_stats_t *stats) { REQUIRE(VALID_MANAGER(manager)); REQUIRE(ISC_LIST_EMPTY(manager->socklist)); REQUIRE(manager->stats == NULL); REQUIRE(isc_stats_ncounters(stats) == isc_sockstatscounter_max); isc_stats_attach(stats, &manager->stats); } void isc__socketmgr_destroy(isc_socketmgr_t **managerp) { isc_socketmgr_t *manager; int i; isc_mem_t *mctx; /* * Destroy a socket manager. */ REQUIRE(managerp != NULL); manager = *managerp; REQUIRE(VALID_MANAGER(manager)); LOCK(&manager->lock); /* * Wait for all sockets to be destroyed. */ while (!ISC_LIST_EMPTY(manager->socklist)) { manager_log(manager, CREATION, isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_SOCKETSREMAIN, "sockets exist")); WAIT(&manager->shutdown_ok, &manager->lock); } UNLOCK(&manager->lock); /* * Here, we need to had some wait code for the completion port * thread. */ signal_iocompletionport_exit(manager); manager->bShutdown = ISC_TRUE; /* * Wait for threads to exit. */ for (i = 0; i < manager->maxIOCPThreads; i++) { if (isc_thread_join((isc_thread_t) manager->hIOCPThreads[i], NULL) != ISC_R_SUCCESS) UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_thread_join() for Completion Port %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); } /* * Clean up. */ CloseHandle(manager->hIoCompletionPort); (void)isc_condition_destroy(&manager->shutdown_ok); DESTROYLOCK(&manager->lock); if (manager->stats != NULL) isc_stats_detach(&manager->stats); manager->magic = 0; mctx= manager->mctx; isc_mem_put(mctx, manager, sizeof(*manager)); isc_mem_detach(&mctx); *managerp = NULL; } static void queue_receive_event(isc_socket_t *sock, isc_task_t *task, isc_socketevent_t *dev) { isc_task_t *ntask = NULL; isc_task_attach(task, &ntask); dev->attributes |= ISC_SOCKEVENTATTR_ATTACHED; /* * Enqueue the request. */ INSIST(!ISC_LINK_LINKED(dev, ev_link)); ISC_LIST_ENQUEUE(sock->recv_list, dev, ev_link); socket_log(__LINE__, sock, NULL, EVENT, NULL, 0, 0, "queue_receive_event: event %p -> task %p", dev, ntask); } /* * Check the pending receive queue, and if we have data pending, give it to this * caller. If we have none, queue an I/O request. If this caller is not the first * on the list, then we will just queue this event and return. * * Caller must have the socket locked. */ static isc_result_t socket_recv(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, unsigned int flags) { isc_result_t result = ISC_R_SUCCESS; dev->ev_sender = task; if (sock->fd == INVALID_SOCKET) return (ISC_R_EOF); /* * Queue our event on the list of things to do. Call our function to * attempt to fill buffers as much as possible, and return done events. * We are going to lie about our handling of the ISC_SOCKFLAG_IMMEDIATE * here and tell our caller that we could not satisfy it immediately. */ queue_receive_event(sock, task, dev); if ((flags & ISC_SOCKFLAG_IMMEDIATE) != 0) result = ISC_R_INPROGRESS; completeio_recv(sock); /* * If there are more receivers waiting for data, queue another receive * here. If the */ queue_receive_request(sock); return (result); } isc_result_t isc__socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist, unsigned int minimum, isc_task_t *task, isc_taskaction_t action, void *arg) { isc_socketevent_t *dev; isc_socketmgr_t *manager; unsigned int iocount; isc_buffer_t *buffer; isc_result_t ret; REQUIRE(VALID_SOCKET(sock)); LOCK(&sock->lock); CONSISTENT(sock); /* * Make sure that the socket is not closed. XXXMLG change error here? */ if (sock->fd == INVALID_SOCKET) { UNLOCK(&sock->lock); return (ISC_R_CONNREFUSED); } REQUIRE(buflist != NULL); REQUIRE(!ISC_LIST_EMPTY(*buflist)); REQUIRE(task != NULL); REQUIRE(action != NULL); manager = sock->manager; REQUIRE(VALID_MANAGER(manager)); iocount = isc_bufferlist_availablecount(buflist); REQUIRE(iocount > 0); INSIST(sock->bound); dev = allocate_socketevent(manager->mctx, sock, ISC_SOCKEVENT_RECVDONE, action, arg); if (dev == NULL) { UNLOCK(&sock->lock); return (ISC_R_NOMEMORY); } /* * UDP sockets are always partial read */ if (sock->type == isc_sockettype_udp) dev->minimum = 1; else { if (minimum == 0) dev->minimum = iocount; else dev->minimum = minimum; } /* * Move each buffer from the passed in list to our internal one. */ buffer = ISC_LIST_HEAD(*buflist); while (buffer != NULL) { ISC_LIST_DEQUEUE(*buflist, buffer, link); ISC_LIST_ENQUEUE(dev->bufferlist, buffer, link); buffer = ISC_LIST_HEAD(*buflist); } ret = socket_recv(sock, dev, task, 0); UNLOCK(&sock->lock); return (ret); } isc_result_t isc__socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, isc_task_t *task, isc_taskaction_t action, void *arg) { isc_socketevent_t *dev; isc_socketmgr_t *manager; isc_result_t ret; REQUIRE(VALID_SOCKET(sock)); LOCK(&sock->lock); CONSISTENT(sock); /* * make sure that the socket's not closed */ if (sock->fd == INVALID_SOCKET) { UNLOCK(&sock->lock); return (ISC_R_CONNREFUSED); } REQUIRE(action != NULL); manager = sock->manager; REQUIRE(VALID_MANAGER(manager)); INSIST(sock->bound); dev = allocate_socketevent(manager->mctx, sock, ISC_SOCKEVENT_RECVDONE, action, arg); if (dev == NULL) { UNLOCK(&sock->lock); return (ISC_R_NOMEMORY); } ret = isc_socket_recv2(sock, region, minimum, task, dev, 0); UNLOCK(&sock->lock); return (ret); } isc_result_t isc__socket_recv2(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, isc_task_t *task, isc_socketevent_t *event, unsigned int flags) { isc_result_t ret; REQUIRE(VALID_SOCKET(sock)); LOCK(&sock->lock); CONSISTENT(sock); event->result = ISC_R_UNEXPECTED; event->ev_sender = sock; /* * make sure that the socket's not closed */ if (sock->fd == INVALID_SOCKET) { UNLOCK(&sock->lock); return (ISC_R_CONNREFUSED); } ISC_LIST_INIT(event->bufferlist); event->region = *region; event->n = 0; event->offset = 0; event->attributes = 0; /* * UDP sockets are always partial read. */ if (sock->type == isc_sockettype_udp) event->minimum = 1; else { if (minimum == 0) event->minimum = region->length; else event->minimum = minimum; } ret = socket_recv(sock, event, task, flags); UNLOCK(&sock->lock); return (ret); } /* * Caller must have the socket locked. */ static isc_result_t socket_send(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, unsigned int flags) { int io_state; int send_errno = 0; int cc = 0; isc_task_t *ntask = NULL; isc_result_t result = ISC_R_SUCCESS; dev->ev_sender = task; set_dev_address(address, sock, dev); if (pktinfo != NULL) { socket_log(__LINE__, sock, NULL, TRACE, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_PKTINFOPROVIDED, "pktinfo structure provided, ifindex %u (set to 0)", pktinfo->ipi6_ifindex); dev->attributes |= ISC_SOCKEVENTATTR_PKTINFO; dev->pktinfo = *pktinfo; /* * Set the pktinfo index to 0 here, to let the kernel decide * what interface it should send on. */ dev->pktinfo.ipi6_ifindex = 0; } io_state = startio_send(sock, dev, &cc, &send_errno); switch (io_state) { case DOIO_PENDING: /* I/O started. Enqueue completion event. */ case DOIO_SOFT: /* * We couldn't send all or part of the request right now, so * queue it unless ISC_SOCKFLAG_NORETRY is set. */ if ((flags & ISC_SOCKFLAG_NORETRY) == 0 || io_state == DOIO_PENDING) { isc_task_attach(task, &ntask); dev->attributes |= ISC_SOCKEVENTATTR_ATTACHED; /* * Enqueue the request. */ INSIST(!ISC_LINK_LINKED(dev, ev_link)); ISC_LIST_ENQUEUE(sock->send_list, dev, ev_link); socket_log(__LINE__, sock, NULL, EVENT, NULL, 0, 0, "socket_send: event %p -> task %p", dev, ntask); if ((flags & ISC_SOCKFLAG_IMMEDIATE) != 0) result = ISC_R_INPROGRESS; break; } case DOIO_SUCCESS: break; } return (result); } isc_result_t isc__socket_send(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, isc_taskaction_t action, void *arg) { /* * REQUIRE() checking is performed in isc_socket_sendto(). */ return (isc_socket_sendto(sock, region, task, action, arg, NULL, NULL)); } isc_result_t isc__socket_sendto(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo) { isc_socketevent_t *dev; isc_socketmgr_t *manager; isc_result_t ret; REQUIRE(VALID_SOCKET(sock)); REQUIRE(sock->type != isc_sockettype_fdwatch); LOCK(&sock->lock); CONSISTENT(sock); /* * make sure that the socket's not closed */ if (sock->fd == INVALID_SOCKET) { UNLOCK(&sock->lock); return (ISC_R_CONNREFUSED); } REQUIRE(region != NULL); REQUIRE(task != NULL); REQUIRE(action != NULL); manager = sock->manager; REQUIRE(VALID_MANAGER(manager)); INSIST(sock->bound); dev = allocate_socketevent(manager->mctx, sock, ISC_SOCKEVENT_SENDDONE, action, arg); if (dev == NULL) { UNLOCK(&sock->lock); return (ISC_R_NOMEMORY); } dev->region = *region; ret = socket_send(sock, dev, task, address, pktinfo, 0); UNLOCK(&sock->lock); return (ret); } isc_result_t isc__socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist, isc_task_t *task, isc_taskaction_t action, void *arg) { return (isc_socket_sendtov2(sock, buflist, task, action, arg, NULL, NULL, 0)); } isc_result_t isc__socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist, isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo) { return (isc_socket_sendtov2(sock, buflist, task, action, arg, address, pktinfo, 0)); } isc_result_t isc__socket_sendtov2(isc_socket_t *sock, isc_bufferlist_t *buflist, isc_task_t *task, isc_taskaction_t action, void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, unsigned int flags) { isc_socketevent_t *dev; isc_socketmgr_t *manager; unsigned int iocount; isc_buffer_t *buffer; isc_result_t ret; REQUIRE(VALID_SOCKET(sock)); LOCK(&sock->lock); CONSISTENT(sock); /* * make sure that the socket's not closed */ if (sock->fd == INVALID_SOCKET) { UNLOCK(&sock->lock); return (ISC_R_CONNREFUSED); } REQUIRE(buflist != NULL); REQUIRE(!ISC_LIST_EMPTY(*buflist)); REQUIRE(task != NULL); REQUIRE(action != NULL); manager = sock->manager; REQUIRE(VALID_MANAGER(manager)); iocount = isc_bufferlist_usedcount(buflist); REQUIRE(iocount > 0); dev = allocate_socketevent(manager->mctx, sock, ISC_SOCKEVENT_SENDDONE, action, arg); if (dev == NULL) { UNLOCK(&sock->lock); return (ISC_R_NOMEMORY); } /* * Move each buffer from the passed in list to our internal one. */ buffer = ISC_LIST_HEAD(*buflist); while (buffer != NULL) { ISC_LIST_DEQUEUE(*buflist, buffer, link); ISC_LIST_ENQUEUE(dev->bufferlist, buffer, link); buffer = ISC_LIST_HEAD(*buflist); } ret = socket_send(sock, dev, task, address, pktinfo, flags); UNLOCK(&sock->lock); return (ret); } isc_result_t isc__socket_sendto2(isc_socket_t *sock, isc_region_t *region, isc_task_t *task, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo, isc_socketevent_t *event, unsigned int flags) { isc_result_t ret; REQUIRE(VALID_SOCKET(sock)); LOCK(&sock->lock); CONSISTENT(sock); REQUIRE((flags & ~(ISC_SOCKFLAG_IMMEDIATE|ISC_SOCKFLAG_NORETRY)) == 0); if ((flags & ISC_SOCKFLAG_NORETRY) != 0) REQUIRE(sock->type == isc_sockettype_udp); event->ev_sender = sock; event->result = ISC_R_UNEXPECTED; /* * make sure that the socket's not closed */ if (sock->fd == INVALID_SOCKET) { UNLOCK(&sock->lock); return (ISC_R_CONNREFUSED); } ISC_LIST_INIT(event->bufferlist); event->region = *region; event->n = 0; event->offset = 0; event->attributes = 0; ret = socket_send(sock, event, task, address, pktinfo, flags); UNLOCK(&sock->lock); return (ret); } isc_result_t isc__socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr, unsigned int options) { int bind_errno; char strbuf[ISC_STRERRORSIZE]; int on = 1; REQUIRE(VALID_SOCKET(sock)); LOCK(&sock->lock); CONSISTENT(sock); /* * make sure that the socket's not closed */ if (sock->fd == INVALID_SOCKET) { UNLOCK(&sock->lock); return (ISC_R_CONNREFUSED); } INSIST(!sock->bound); INSIST(!sock->dupped); if (sock->pf != sockaddr->type.sa.sa_family) { UNLOCK(&sock->lock); return (ISC_R_FAMILYMISMATCH); } /* * Only set SO_REUSEADDR when we want a specific port. */ if ((options & ISC_SOCKET_REUSEADDRESS) != 0 && isc_sockaddr_getport(sockaddr) != (in_port_t)0 && setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) { UNEXPECTED_ERROR(__FILE__, __LINE__, "setsockopt(%d) %s", sock->fd, isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); /* Press on... */ } if (bind(sock->fd, &sockaddr->type.sa, sockaddr->length) < 0) { bind_errno = WSAGetLastError(); UNLOCK(&sock->lock); switch (bind_errno) { case WSAEACCES: return (ISC_R_NOPERM); case WSAEADDRNOTAVAIL: return (ISC_R_ADDRNOTAVAIL); case WSAEADDRINUSE: return (ISC_R_ADDRINUSE); case WSAEINVAL: return (ISC_R_BOUND); default: isc__strerror(bind_errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "bind: %s", strbuf); return (ISC_R_UNEXPECTED); } } socket_log(__LINE__, sock, sockaddr, TRACE, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_BOUND, "bound"); sock->bound = 1; UNLOCK(&sock->lock); return (ISC_R_SUCCESS); } isc_result_t isc__socket_filter(isc_socket_t *sock, const char *filter) { UNUSED(sock); UNUSED(filter); REQUIRE(VALID_SOCKET(sock)); return (ISC_R_NOTIMPLEMENTED); } /* * Set up to listen on a given socket. We do this by creating an internal * event that will be dispatched when the socket has read activity. The * watcher will send the internal event to the task when there is a new * connection. * * Unlike in read, we don't preallocate a done event here. Every time there * is a new connection we'll have to allocate a new one anyway, so we might * as well keep things simple rather than having to track them. */ isc_result_t isc__socket_listen(isc_socket_t *sock, unsigned int backlog) { char strbuf[ISC_STRERRORSIZE]; REQUIRE(VALID_SOCKET(sock)); LOCK(&sock->lock); CONSISTENT(sock); /* * make sure that the socket's not closed */ if (sock->fd == INVALID_SOCKET) { UNLOCK(&sock->lock); return (ISC_R_CONNREFUSED); } REQUIRE(!sock->listener); REQUIRE(sock->bound); REQUIRE(sock->type == isc_sockettype_tcp); if (backlog == 0) backlog = SOMAXCONN; if (listen(sock->fd, (int)backlog) < 0) { UNLOCK(&sock->lock); isc__strerror(WSAGetLastError(), strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "listen: %s", strbuf); return (ISC_R_UNEXPECTED); } socket_log(__LINE__, sock, NULL, TRACE, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_BOUND, "listening"); sock->listener = 1; _set_state(sock, SOCK_LISTEN); UNLOCK(&sock->lock); return (ISC_R_SUCCESS); } /* * This should try to do aggressive accept() XXXMLG */ isc_result_t isc__socket_accept(isc_socket_t *sock, isc_task_t *task, isc_taskaction_t action, void *arg) { isc_socket_newconnev_t *adev; isc_socketmgr_t *manager; isc_task_t *ntask = NULL; isc_socket_t *nsock; isc_result_t result; IoCompletionInfo *lpo; REQUIRE(VALID_SOCKET(sock)); manager = sock->manager; REQUIRE(VALID_MANAGER(manager)); LOCK(&sock->lock); CONSISTENT(sock); /* * make sure that the socket's not closed */ if (sock->fd == INVALID_SOCKET) { UNLOCK(&sock->lock); return (ISC_R_CONNREFUSED); } REQUIRE(sock->listener); /* * Sender field is overloaded here with the task we will be sending * this event to. Just before the actual event is delivered the * actual ev_sender will be touched up to be the socket. */ adev = (isc_socket_newconnev_t *) isc_event_allocate(manager->mctx, task, ISC_SOCKEVENT_NEWCONN, action, arg, sizeof(*adev)); if (adev == NULL) { UNLOCK(&sock->lock); return (ISC_R_NOMEMORY); } ISC_LINK_INIT(adev, ev_link); result = allocate_socket(manager, sock->type, &nsock); if (result != ISC_R_SUCCESS) { isc_event_free((isc_event_t **)&adev); UNLOCK(&sock->lock); return (result); } /* * AcceptEx() requires we pass in a socket. */ nsock->fd = socket(sock->pf, SOCK_STREAM, IPPROTO_TCP); if (nsock->fd == INVALID_SOCKET) { free_socket(&nsock, __LINE__); isc_event_free((isc_event_t **)&adev); UNLOCK(&sock->lock); return (ISC_R_FAILURE); // XXXMLG need real error message } /* * Attach to socket and to task. */ isc_task_attach(task, &ntask); if (isc_task_exiting(ntask)) { free_socket(&nsock, __LINE__); isc_task_detach(&ntask); isc_event_free(ISC_EVENT_PTR(&adev)); UNLOCK(&sock->lock); return (ISC_R_SHUTTINGDOWN); } nsock->references++; adev->ev_sender = ntask; adev->newsocket = nsock; _set_state(nsock, SOCK_ACCEPT); /* * Queue io completion for an accept(). */ lpo = (IoCompletionInfo *)HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, sizeof(IoCompletionInfo)); RUNTIME_CHECK(lpo != NULL); lpo->acceptbuffer = (void *)HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, (sizeof(SOCKADDR_STORAGE) + 16) * 2); RUNTIME_CHECK(lpo->acceptbuffer != NULL); lpo->adev = adev; lpo->request_type = SOCKET_ACCEPT; ISCAcceptEx(sock->fd, nsock->fd, /* Accepted Socket */ lpo->acceptbuffer, /* Buffer for initial Recv */ 0, /* Length of Buffer */ sizeof(SOCKADDR_STORAGE) + 16, /* Local address length + 16 */ sizeof(SOCKADDR_STORAGE) + 16, /* Remote address lengh + 16 */ (LPDWORD)&lpo->received_bytes, /* Bytes Recved */ (LPOVERLAPPED)lpo /* Overlapped structure */ ); iocompletionport_update(nsock); socket_log(__LINE__, sock, NULL, TRACE, isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_BOUND, "accepting for nsock %p fd %d", nsock, nsock->fd); /* * Enqueue the event */ ISC_LIST_ENQUEUE(sock->accept_list, adev, ev_link); sock->pending_accept++; sock->pending_iocp++; UNLOCK(&sock->lock); return (ISC_R_SUCCESS); } isc_result_t isc__socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr, isc_task_t *task, isc_taskaction_t action, void *arg) { char strbuf[ISC_STRERRORSIZE]; isc_socket_connev_t *cdev; isc_task_t *ntask = NULL; isc_socketmgr_t *manager; IoCompletionInfo *lpo; int bind_errno; REQUIRE(VALID_SOCKET(sock)); REQUIRE(addr != NULL); REQUIRE(task != NULL); REQUIRE(action != NULL); manager = sock->manager; REQUIRE(VALID_MANAGER(manager)); REQUIRE(addr != NULL); if (isc_sockaddr_ismulticast(addr)) return (ISC_R_MULTICAST); LOCK(&sock->lock); CONSISTENT(sock); /* * make sure that the socket's not closed */ if (sock->fd == INVALID_SOCKET) { UNLOCK(&sock->lock); return (ISC_R_CONNREFUSED); } /* * Windows sockets won't connect unless the socket is bound. */ if (!sock->bound) { isc_sockaddr_t any; isc_sockaddr_anyofpf(&any, isc_sockaddr_pf(addr)); if (bind(sock->fd, &any.type.sa, any.length) < 0) { bind_errno = WSAGetLastError(); UNLOCK(&sock->lock); switch (bind_errno) { case WSAEACCES: return (ISC_R_NOPERM); case WSAEADDRNOTAVAIL: return (ISC_R_ADDRNOTAVAIL); case WSAEADDRINUSE: return (ISC_R_ADDRINUSE); case WSAEINVAL: return (ISC_R_BOUND); default: isc__strerror(bind_errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "bind: %s", strbuf); return (ISC_R_UNEXPECTED); } } sock->bound = 1; } REQUIRE(!sock->pending_connect); cdev = (isc_socket_connev_t *)isc_event_allocate(manager->mctx, sock, ISC_SOCKEVENT_CONNECT, action, arg, sizeof(*cdev)); if (cdev == NULL) { UNLOCK(&sock->lock); return (ISC_R_NOMEMORY); } ISC_LINK_INIT(cdev, ev_link); if (sock->type == isc_sockettype_tcp) { /* * Queue io completion for an accept(). */ lpo = (IoCompletionInfo *)HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, sizeof(IoCompletionInfo)); lpo->cdev = cdev; lpo->request_type = SOCKET_CONNECT; sock->address = *addr; ISCConnectEx(sock->fd, &addr->type.sa, addr->length, NULL, 0, NULL, (LPOVERLAPPED)lpo); /* * Attach to task. */ isc_task_attach(task, &ntask); cdev->ev_sender = ntask; sock->pending_connect = 1; _set_state(sock, SOCK_CONNECT); /* * Enqueue the request. */ sock->connect_ev = cdev; sock->pending_iocp++; } else { WSAConnect(sock->fd, &addr->type.sa, addr->length, NULL, NULL, NULL, NULL); cdev->result = ISC_R_SUCCESS; isc_task_send(task, (isc_event_t **)&cdev); } CONSISTENT(sock); UNLOCK(&sock->lock); return (ISC_R_SUCCESS); } isc_result_t isc__socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp) { isc_result_t result; REQUIRE(VALID_SOCKET(sock)); REQUIRE(addressp != NULL); LOCK(&sock->lock); CONSISTENT(sock); /* * make sure that the socket's not closed */ if (sock->fd == INVALID_SOCKET) { UNLOCK(&sock->lock); return (ISC_R_CONNREFUSED); } if (sock->connected) { *addressp = sock->address; result = ISC_R_SUCCESS; } else { result = ISC_R_NOTCONNECTED; } UNLOCK(&sock->lock); return (result); } isc_result_t isc__socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) { ISC_SOCKADDR_LEN_T len; isc_result_t result; char strbuf[ISC_STRERRORSIZE]; REQUIRE(VALID_SOCKET(sock)); REQUIRE(addressp != NULL); LOCK(&sock->lock); CONSISTENT(sock); /* * make sure that the socket's not closed */ if (sock->fd == INVALID_SOCKET) { UNLOCK(&sock->lock); return (ISC_R_CONNREFUSED); } if (!sock->bound) { result = ISC_R_NOTBOUND; goto out; } result = ISC_R_SUCCESS; len = sizeof(addressp->type); if (getsockname(sock->fd, &addressp->type.sa, (void *)&len) < 0) { isc__strerror(WSAGetLastError(), strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "getsockname: %s", strbuf); result = ISC_R_UNEXPECTED; goto out; } addressp->length = (unsigned int)len; out: UNLOCK(&sock->lock); return (result); } /* * Run through the list of events on this socket, and cancel the ones * queued for task "task" of type "how". "how" is a bitmask. */ void isc__socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) { REQUIRE(VALID_SOCKET(sock)); /* * Quick exit if there is nothing to do. Don't even bother locking * in this case. */ if (how == 0) return; LOCK(&sock->lock); CONSISTENT(sock); /* * make sure that the socket's not closed */ if (sock->fd == INVALID_SOCKET) { UNLOCK(&sock->lock); return; } /* * All of these do the same thing, more or less. * Each will: * o If the internal event is marked as "posted" try to * remove it from the task's queue. If this fails, mark it * as canceled instead, and let the task clean it up later. * o For each I/O request for that task of that type, post * its done event with status of "ISC_R_CANCELED". * o Reset any state needed. */ if ((how & ISC_SOCKCANCEL_RECV) == ISC_SOCKCANCEL_RECV) { isc_socketevent_t *dev; isc_socketevent_t *next; isc_task_t *current_task; dev = ISC_LIST_HEAD(sock->recv_list); while (dev != NULL) { current_task = dev->ev_sender; next = ISC_LIST_NEXT(dev, ev_link); if ((task == NULL) || (task == current_task)) { dev->result = ISC_R_CANCELED; send_recvdone_event(sock, &dev); } dev = next; } } how &= ~ISC_SOCKCANCEL_RECV; if ((how & ISC_SOCKCANCEL_SEND) == ISC_SOCKCANCEL_SEND) { isc_socketevent_t *dev; isc_socketevent_t *next; isc_task_t *current_task; dev = ISC_LIST_HEAD(sock->send_list); while (dev != NULL) { current_task = dev->ev_sender; next = ISC_LIST_NEXT(dev, ev_link); if ((task == NULL) || (task == current_task)) { dev->result = ISC_R_CANCELED; send_senddone_event(sock, &dev); } dev = next; } } how &= ~ISC_SOCKCANCEL_SEND; if (((how & ISC_SOCKCANCEL_ACCEPT) == ISC_SOCKCANCEL_ACCEPT) && !ISC_LIST_EMPTY(sock->accept_list)) { isc_socket_newconnev_t *dev; isc_socket_newconnev_t *next; isc_task_t *current_task; dev = ISC_LIST_HEAD(sock->accept_list); while (dev != NULL) { current_task = dev->ev_sender; next = ISC_LIST_NEXT(dev, ev_link); if ((task == NULL) || (task == current_task)) { dev->newsocket->references--; closesocket(dev->newsocket->fd); dev->newsocket->fd = INVALID_SOCKET; free_socket(&dev->newsocket, __LINE__); dev->result = ISC_R_CANCELED; send_acceptdone_event(sock, &dev); } dev = next; } } how &= ~ISC_SOCKCANCEL_ACCEPT; /* * Connecting is not a list. */ if (((how & ISC_SOCKCANCEL_CONNECT) == ISC_SOCKCANCEL_CONNECT) && sock->connect_ev != NULL) { isc_socket_connev_t *dev; isc_task_t *current_task; INSIST(sock->pending_connect); dev = sock->connect_ev; current_task = dev->ev_sender; if ((task == NULL) || (task == current_task)) { closesocket(sock->fd); sock->fd = INVALID_SOCKET; _set_state(sock, SOCK_CLOSED); sock->connect_ev = NULL; dev->result = ISC_R_CANCELED; send_connectdone_event(sock, &dev); } } how &= ~ISC_SOCKCANCEL_CONNECT; maybe_free_socket(&sock, __LINE__); } isc_sockettype_t isc__socket_gettype(isc_socket_t *sock) { isc_sockettype_t type; REQUIRE(VALID_SOCKET(sock)); LOCK(&sock->lock); /* * make sure that the socket's not closed */ if (sock->fd == INVALID_SOCKET) { UNLOCK(&sock->lock); return (ISC_R_CONNREFUSED); } type = sock->type; UNLOCK(&sock->lock); return (type); } isc_boolean_t isc__socket_isbound(isc_socket_t *sock) { isc_boolean_t val; REQUIRE(VALID_SOCKET(sock)); LOCK(&sock->lock); CONSISTENT(sock); /* * make sure that the socket's not closed */ if (sock->fd == INVALID_SOCKET) { UNLOCK(&sock->lock); return (ISC_FALSE); } val = ((sock->bound) ? ISC_TRUE : ISC_FALSE); UNLOCK(&sock->lock); return (val); } void isc__socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) { #if defined(IPV6_V6ONLY) int onoff = yes ? 1 : 0; #else UNUSED(yes); #endif REQUIRE(VALID_SOCKET(sock)); #ifdef IPV6_V6ONLY if (sock->pf == AF_INET6) { (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&onoff, sizeof(onoff)); } #endif } void isc__socket_dscp(isc_socket_t *sock, isc_dscp_t dscp) { #if !defined(IP_TOS) && !defined(IPV6_TCLASS) UNUSED(dscp); #else if (dscp < 0) return; dscp <<= 2; dscp &= 0xff; #endif REQUIRE(VALID_SOCKET(sock)); #ifdef IP_TOS if (sock->pf == AF_INET) { (void)setsockopt(sock->fd, IPPROTO_IP, IP_TOS, (char *)&dscp, sizeof(dscp)); } #endif #ifdef IPV6_TCLASS if (sock->pf == AF_INET6) { (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_TCLASS, (char *)&dscp, sizeof(dscp)); } #endif } void isc__socket_cleanunix(isc_sockaddr_t *addr, isc_boolean_t active) { UNUSED(addr); UNUSED(active); } isc_result_t isc__socket_permunix(isc_sockaddr_t *addr, isc_uint32_t perm, isc_uint32_t owner, isc_uint32_t group) { UNUSED(addr); UNUSED(perm); UNUSED(owner); UNUSED(group); return (ISC_R_NOTIMPLEMENTED); } void isc__socket_setname(isc_socket_t *socket, const char *name, void *tag) { /* * Name 'socket'. */ REQUIRE(VALID_SOCKET(socket)); LOCK(&socket->lock); memset(socket->name, 0, sizeof(socket->name)); strncpy(socket->name, name, sizeof(socket->name) - 1); socket->tag = tag; UNLOCK(&socket->lock); } const char * isc__socket_getname(isc_socket_t *socket) { return (socket->name); } void * isc__socket_gettag(isc_socket_t *socket) { return (socket->tag); } int isc__socket_getfd(isc_socket_t *socket) { return ((short) socket->fd); } void isc__socketmgr_setreserved(isc_socketmgr_t *manager, isc_uint32_t reserved) { UNUSED(manager); UNUSED(reserved); } void isc___socketmgr_maxudp(isc_socketmgr_t *manager, int maxudp) { UNUSED(manager); UNUSED(maxudp); } isc_socketevent_t * isc_socket_socketevent(isc_mem_t *mctx, void *sender, isc_eventtype_t eventtype, isc_taskaction_t action, void *arg) { return (allocate_socketevent(mctx, sender, eventtype, action, arg)); } #ifdef HAVE_LIBXML2 static const char * _socktype(isc_sockettype_t type) { if (type == isc_sockettype_udp) return ("udp"); else if (type == isc_sockettype_tcp) return ("tcp"); else if (type == isc_sockettype_unix) return ("unix"); else if (type == isc_sockettype_fdwatch) return ("fdwatch"); else return ("not-initialized"); } #define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0) int isc_socketmgr_renderxml(isc_socketmgr_t *mgr, xmlTextWriterPtr writer) { isc_socket_t *sock = NULL; char peerbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_t addr; ISC_SOCKADDR_LEN_T len; int xmlrc; LOCK(&mgr->lock); #ifndef ISC_PLATFORM_USETHREADS TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references")); TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->refs)); TRY0(xmlTextWriterEndElement(writer)); #endif TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "sockets")); sock = ISC_LIST_HEAD(mgr->socklist); while (sock != NULL) { LOCK(&sock->lock); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "socket")); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "id")); TRY0(xmlTextWriterWriteFormatString(writer, "%p", sock)); TRY0(xmlTextWriterEndElement(writer)); if (sock->name[0] != 0) { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); TRY0(xmlTextWriterWriteFormatString(writer, "%s", sock->name)); TRY0(xmlTextWriterEndElement(writer)); /* name */ } TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references")); TRY0(xmlTextWriterWriteFormatString(writer, "%d", sock->references)); TRY0(xmlTextWriterEndElement(writer)); TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "type", ISC_XMLCHAR _socktype(sock->type))); if (sock->connected) { isc_sockaddr_format(&sock->address, peerbuf, sizeof(peerbuf)); TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "peer-address", ISC_XMLCHAR peerbuf)); } len = sizeof(addr); if (getsockname(sock->fd, &addr.type.sa, (void *)&len) == 0) { isc_sockaddr_format(&addr, peerbuf, sizeof(peerbuf)); TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "local-address", ISC_XMLCHAR peerbuf)); } TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "states")); if (sock->pending_recv) TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", ISC_XMLCHAR "pending-receive")); if (sock->pending_send) TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", ISC_XMLCHAR "pending-send")); if (sock->pending_accept) TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", ISC_XMLCHAR "pending_accept")); if (sock->listener) TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", ISC_XMLCHAR "listener")); if (sock->connected) TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", ISC_XMLCHAR "connected")); if (sock->pending_connect) TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", ISC_XMLCHAR "connecting")); if (sock->bound) TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state", ISC_XMLCHAR "bound")); TRY0(xmlTextWriterEndElement(writer)); /* states */ TRY0(xmlTextWriterEndElement(writer)); /* socket */ UNLOCK(&sock->lock); sock = ISC_LIST_NEXT(sock, link); } TRY0(xmlTextWriterEndElement(writer)); /* sockets */ error: if (sock != NULL) UNLOCK(&sock->lock); UNLOCK(&mgr->lock); return (xmlrc); } #endif /* HAVE_LIBXML2 */ /* * Replace ../socket_api.c */ isc_result_t isc__socket_register(void) { return (ISC_R_SUCCESS); } isc_result_t isc_socketmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx, isc_socketmgr_t **managerp) { isc_result_t result; result = isc_socketmgr_create(mctx, managerp); if (result == ISC_R_SUCCESS) isc_appctx_setsocketmgr(actx, *managerp); return (result); } bind9-9.10.3.dfsg.P4/lib/isc/win32/Makefile.in0000644000470500017500000000256412664710322017733 0ustar lamontlamont# Copyright (C) 2004, 2007, 2009, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1999-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.14 2009/12/05 23:31:41 each Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ CINCLUDES = -I${srcdir}/.. \ -I./include \ -I${srcdir}/include \ -I${srcdir}/../include CDEFINES = CWARNINGS = # Alphabetically OBJS = condition.@O@ dir.@O@ file.@O@ fsaccess.@O@ once.@O@ \ stdtime.@O@ thread.@O@ time.@O@ @ISC_PK11_API_O@ # Alphabetically SRCS = condition.c dir.c file.c once.c fsaccess.c \ stdtime.c thread.c time.c @ISC_PK11_API_C@ SUBDIRS = include TARGETS = ${OBJS} @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/win32/libisc.def.in0000644000470500017500000003460312664710322020217 0ustar lamontlamontLIBRARY libisc ; Exported Functions EXPORTS NTReportError closelog @IF PKCS11 getpassphrase @END PKCS11 isc___socketmgr_maxudp isc__app_block isc__app_ctxfinish isc__app_ctxonrun isc__app_ctxrun isc__app_ctxshutdown isc__app_ctxstart isc__app_ctxsuspend isc__app_finish isc__app_onrun isc__app_reload isc__app_run isc__app_shutdown isc__app_start isc__app_unblock isc__appctx_create isc__appctx_destroy isc__appctx_setsocketmgr isc__appctx_settaskmgr isc__appctx_settimermgr isc__backtrace_nsymbols isc__backtrace_symtable isc__buffer_activeregion isc__buffer_add isc__buffer_availableregion isc__buffer_back isc__buffer_clear isc__buffer_consumedregion isc__buffer_first isc__buffer_forward isc__buffer_init isc__buffer_initnull isc__buffer_invalidate isc__buffer_putmem isc__buffer_putstr isc__buffer_putuint16 isc__buffer_putuint24 isc__buffer_putuint32 isc__buffer_putuint48 isc__buffer_putuint8 isc__buffer_region isc__buffer_remainingregion isc__buffer_setactive isc__buffer_subtract isc__buffer_usedregion isc__mem_allocate isc__mem_free isc__mem_get isc__mem_put isc__mem_putanddetach isc__mem_reallocate isc__mem_strdup isc__mempool_get isc__mempool_put isc__socket_accept isc__socket_attach isc__socket_bind isc__socket_cancel isc__socket_cleanunix isc__socket_close isc__socket_connect isc__socket_create isc__socket_detach isc__socket_dscp isc__socket_dup isc__socket_filter isc__socket_getfd isc__socket_getname isc__socket_getpeername isc__socket_getsockname isc__socket_gettag isc__socket_gettype isc__socket_ipv6only isc__socket_isbound isc__socket_listen isc__socket_open isc__socket_permunix isc__socket_recv isc__socket_recv2 isc__socket_recvv isc__socket_register isc__socket_send isc__socket_sendto isc__socket_sendto2 isc__socket_sendtov isc__socket_sendtov2 isc__socket_sendv isc__socket_setname isc__socketmgr_create isc__socketmgr_create2 isc__socketmgr_destroy isc__socketmgr_getmaxsockets isc__socketmgr_setreserved isc__socketmgr_setstats isc__strerror isc__task_getname isc__task_gettag isc__task_unsendrange isc__taskmgr_mode @IF AES isc_aes128_crypt isc_aes192_crypt isc_aes256_crypt @END AES isc_app_block isc_app_ctxfinish isc_app_ctxonrun isc_app_ctxrun isc_app_ctxshutdown isc_app_ctxstart isc_app_ctxsuspend isc_app_finish isc_app_isrunning isc_app_onrun isc_app_register isc_app_reload isc_app_run isc_app_shutdown isc_app_start isc_app_unblock isc_appctx_create isc_appctx_destroy isc_appctx_setsocketmgr isc_appctx_settaskmgr isc_appctx_settimermgr isc_assertion_failed isc_assertion_setcallback isc_assertion_typetotext isc_backtrace_getsymbol isc_backtrace_getsymbolfromindex isc_backtrace_gettrace isc_base32_decoderegion isc_base32_decodestring isc_base32_tobuffer isc_base32_totext isc_base32hex_decoderegion isc_base32hex_decodestring isc_base32hex_tobuffer isc_base32hex_totext isc_base32hexnp_decoderegion isc_base32hexnp_decodestring isc_base32hexnp_tobuffer isc_base32hexnp_totext isc_base64_decodestring isc_base64_tobuffer isc_base64_totext isc_buffer_allocate isc_buffer_compact isc_buffer_copyregion isc_buffer_free isc_buffer_getuint16 isc_buffer_getuint32 isc_buffer_getuint48 isc_buffer_getuint8 isc_buffer_reinit isc_bufferlist_availablecount isc_bufferlist_usedcount isc_commandline_parse isc_condition_broadcast isc_condition_destroy isc_condition_init isc_condition_signal isc_condition_wait isc_condition_waituntil isc_counter_attach isc_counter_create isc_counter_detach isc_counter_increment isc_counter_setlimit isc_counter_used isc_crc64_final isc_crc64_init isc_crc64_update isc_dir_chdir isc_dir_chroot isc_dir_close isc_dir_createunique isc_dir_init isc_dir_open isc_dir_read isc_dir_reset isc_dscp_check_value isc_entropy_addcallbacksample isc_entropy_addsample isc_entropy_attach isc_entropy_create isc_entropy_createcallbacksource isc_entropy_createfilesource isc_entropy_createsamplesource isc_entropy_destroysource isc_entropy_detach isc_entropy_getdata isc_entropy_putdata isc_entropy_stats isc_entropy_status isc_entropy_stopcallbacksources isc_entropy_usebestsource isc_error_fatal isc_error_runtimecheck isc_error_setfatal isc_error_setunexpected isc_error_unexpected isc_event_allocate isc_event_constallocate isc_event_free isc_file_absolutepath isc_file_basename isc_file_bopenunique isc_file_bopenuniquemode isc_file_bopenuniqueprivate isc_file_exists isc_file_getmodtime isc_file_getsize isc_file_getsizefd isc_file_isabsolute isc_file_ischdiridempotent isc_file_iscurrentdir isc_file_isdirectory isc_file_isplainfile isc_file_isplainfilefd isc_file_mktemplate isc_file_mmap isc_file_mode isc_file_munmap isc_file_openunique isc_file_openuniquemode isc_file_openuniqueprivate isc_file_progname isc_file_remove isc_file_rename isc_file_renameunique isc_file_safecreate isc_file_safemovefile isc_file_settime isc_file_splitpath isc_file_template isc_file_truncate isc_fsaccess_add isc_fsaccess_changeowner isc_fsaccess_remove isc_fsaccess_set isc_hash_calc isc_hash_create isc_hash_ctxattach isc_hash_ctxcalc isc_hash_ctxcreate isc_hash_ctxdetach isc_hash_ctxinit isc_hash_destroy isc_hash_init isc_heap_create isc_heap_decreased isc_heap_delete isc_heap_destroy isc_heap_foreach isc_heap_element isc_heap_increased isc_heap_insert isc_hex_decodestring isc_hex_tobuffer isc_hex_totext isc_hmacmd5_init isc_hmacmd5_invalidate isc_hmacmd5_sign isc_hmacmd5_update isc_hmacmd5_verify isc_hmacmd5_verify2 isc_hmacsha1_init isc_hmacsha1_invalidate isc_hmacsha1_sign isc_hmacsha1_update isc_hmacsha1_verify isc_hmacsha224_init isc_hmacsha224_invalidate isc_hmacsha224_sign isc_hmacsha224_update isc_hmacsha224_verify isc_hmacsha256_init isc_hmacsha256_invalidate isc_hmacsha256_sign isc_hmacsha256_update isc_hmacsha256_verify isc_hmacsha384_init isc_hmacsha384_invalidate isc_hmacsha384_sign isc_hmacsha384_update isc_hmacsha384_verify isc_hmacsha512_init isc_hmacsha512_invalidate isc_hmacsha512_sign isc_hmacsha512_update isc_hmacsha512_verify isc_httpd_addheader isc_httpd_addheaderuint isc_httpd_response isc_httpdmgr_addurl isc_httpdmgr_addurl2 isc_httpdmgr_create isc_httpdmgr_shutdown isc_interfaceiter_create isc_interfaceiter_current isc_interfaceiter_destroy isc_interfaceiter_first isc_interfaceiter_next isc_interval_iszero isc_interval_set isc_iterated_hash isc_keyboard_canceled isc_keyboard_close isc_keyboard_getchar isc_keyboard_open isc_lex_close isc_lex_create isc_lex_destroy isc_lex_getcomments isc_lex_getlasttokentext isc_lex_getmastertoken isc_lex_getoctaltoken isc_lex_getsourceline isc_lex_getsourcename isc_lex_getspecials isc_lex_gettoken isc_lex_isfile isc_lex_openbuffer isc_lex_openfile isc_lex_openstream isc_lex_setcomments isc_lex_setsourcename isc_lex_setspecials isc_lex_ungettoken isc_lfsr_generate isc_lfsr_generate32 isc_lfsr_init isc_lfsr_skip isc_lib_initmsgcat isc_lib_register isc_log_categorybyname isc_log_closefilelogs isc_log_create isc_log_createchannel isc_log_destroy isc_log_getdebuglevel isc_log_getduplicateinterval isc_log_gettag isc_log_ivwrite isc_log_ivwrite1 isc_log_iwrite isc_log_iwrite1 isc_log_modulebyname isc_log_opensyslog isc_log_registercategories isc_log_registermodules isc_log_setcontext isc_log_setdebuglevel isc_log_setduplicateinterval isc_log_settag isc_log_usechannel isc_log_vwrite isc_log_vwrite1 isc_log_wouldlog isc_log_write isc_log_write1 isc_logconfig_create isc_logconfig_destroy isc_logconfig_get isc_logconfig_use isc_md5_final isc_md5_init isc_md5_invalidate isc_md5_update isc_mem_attach isc_mem_checkdestroyed isc_mem_create isc_mem_create2 isc_mem_createx isc_mem_createx2 isc_mem_destroy isc_mem_detach isc_mem_getname isc_mem_getquota isc_mem_gettag isc_mem_inuse isc_mem_isovermem isc_mem_maxinuse isc_mem_ondestroy isc_mem_printallactive isc_mem_references isc_mem_register @IF JSON isc_mem_renderjson @END JSON @IF LIBXML2 isc_mem_renderxml @END LIBXML2 isc_mem_setdestroycheck isc_mem_setname isc_mem_setquota isc_mem_setwater isc_mem_stats isc_mem_total isc_mem_waterack isc_mempool_associatelock isc_mempool_create isc_mempool_destroy isc_mempool_getallocated isc_mempool_getfillcount isc_mempool_getfreecount isc_mempool_getfreemax isc_mempool_getmaxalloc isc_mempool_setfillcount isc_mempool_setfreemax isc_mempool_setmaxalloc isc_mempool_setname isc_msgcat_close isc_msgcat_get isc_msgcat_open isc_mutexblock_destroy isc_mutexblock_init isc_net_aton isc_net_disableipv4 isc_net_disableipv6 isc_net_getudpportrange isc_net_ntop isc_net_probe_ipv6only isc_net_probe_ipv6pktinfo isc_net_probedscp isc_net_probeipv4 isc_net_probeipv6 isc_net_probeunix isc_net_pton isc_netaddr_any isc_netaddr_any6 isc_netaddr_eqprefix isc_netaddr_equal isc_netaddr_format isc_netaddr_fromin isc_netaddr_fromin6 isc_netaddr_frompath isc_netaddr_fromsockaddr isc_netaddr_fromv4mapped isc_netaddr_getzone isc_netaddr_isexperimental isc_netaddr_islinklocal isc_netaddr_ismulticast isc_netaddr_issitelocal isc_netaddr_masktoprefixlen isc_netaddr_prefixok isc_netaddr_setzone isc_netaddr_totext isc_netscope_pton isc_ntpaths_get isc_ntpaths_init isc_once_do isc_ondestroy_init isc_ondestroy_notify isc_ondestroy_register isc_os_ncpus isc_parse_uint16 isc_parse_uint32 isc_parse_uint8 isc_pool_count isc_pool_create isc_pool_destroy isc_pool_expand isc_pool_get isc_portset_add isc_portset_addrange isc_portset_create isc_portset_destroy isc_portset_isset isc_portset_nports isc_portset_remove isc_portset_removerange isc_quota_attach isc_quota_destroy isc_quota_detach isc_quota_init isc_quota_max isc_quota_release isc_quota_reserve isc_quota_soft isc_radix_create isc_radix_destroy isc_radix_insert isc_radix_process isc_radix_remove isc_radix_search isc_random_get isc_random_jitter isc_random_seed isc_ratelimiter_attach isc_ratelimiter_create isc_ratelimiter_dequeue isc_ratelimiter_detach isc_ratelimiter_enqueue isc_ratelimiter_release isc_ratelimiter_setinterval isc_ratelimiter_setpertic isc_ratelimiter_shutdown isc_ratelimiter_stall isc_refcount_init isc_regex_validate isc_region_compare isc_resource_getcurlimit isc_resource_getlimit isc_resource_setlimit isc_result_register isc_result_totext isc_rwlock_destroy isc_rwlock_downgrade isc_rwlock_init isc_rwlock_lock isc_rwlock_trylock isc_rwlock_tryupgrade isc_rwlock_unlock isc_safe_memcompare isc_safe_memequal isc_serial_eq isc_serial_ge isc_serial_gt isc_serial_le isc_serial_lt isc_serial_ne isc_sha1_final isc_sha1_init isc_sha1_invalidate isc_sha1_update isc_sha224_final isc_sha224_init isc_sha224_invalidate isc_sha224_update isc_sha256_data isc_sha256_final isc_sha256_init isc_sha256_invalidate isc_sha256_update isc_sha384_final isc_sha384_init isc_sha384_invalidate isc_sha384_update isc_sha512_final isc_sha512_init isc_sha512_invalidate isc_sha512_update isc_sockaddr_any isc_sockaddr_any6 isc_sockaddr_anyofpf isc_sockaddr_compare isc_sockaddr_eqaddr isc_sockaddr_eqaddrprefix isc_sockaddr_equal isc_sockaddr_format isc_sockaddr_fromin isc_sockaddr_fromin6 isc_sockaddr_fromnetaddr isc_sockaddr_frompath isc_sockaddr_getport isc_sockaddr_hash isc_sockaddr_isexperimental isc_sockaddr_islinklocal isc_sockaddr_ismulticast isc_sockaddr_issitelocal isc_sockaddr_pf isc_sockaddr_setport isc_sockaddr_totext isc_sockaddr_v6fromin isc_socket_socketevent isc_socketmgr_createinctx @IF LIBXML2 isc_socketmgr_renderxml @END LIBXML2 isc_stats_attach isc_stats_create isc_stats_decrement isc_stats_detach isc_stats_dump isc_stats_increment isc_stats_ncounters isc_stats_set isc_stdio_close isc_stdio_flush isc_stdio_open isc_stdio_read isc_stdio_seek isc_stdio_sync isc_stdio_tell isc_stdio_write isc_stdtime_get isc_string_append isc_string_append_truncate isc_string_copy isc_string_copy_truncate isc_string_printf isc_string_printf_truncate isc_string_regiondup isc_string_separate isc_string_strcasestr isc_string_strlcat isc_string_strlcpy isc_string_touint64 isc_symtab_count isc_symtab_create isc_symtab_define isc_symtab_destroy isc_symtab_lookup isc_symtab_undefine isc_syslog_facilityfromstring isc_task_attach isc_task_beginexclusive isc_task_create isc_task_destroy isc_task_detach isc_task_endexclusive isc_task_exiting isc_task_getcurrenttime isc_task_onshutdown isc_task_privilege isc_task_purge isc_task_purgeevent isc_task_purgerange isc_task_register isc_task_send isc_task_sendanddetach isc_task_setname isc_task_setprivilege isc_task_shutdown isc_task_unsend isc_taskmgr_create isc_taskmgr_createinctx isc_taskmgr_destroy isc_taskmgr_excltask isc_taskmgr_mode @IF JSON isc_taskmgr_renderjson @END JSON @IF LIBXML2 isc_taskmgr_renderxml @END LIBXML2 isc_taskmgr_setexcltask isc_taskmgr_setmode isc_taskpool_create isc_taskpool_destroy isc_taskpool_expand isc_taskpool_gettask isc_taskpool_setprivilege isc_taskpool_size isc_thread_create isc_thread_join isc_thread_key_create isc_thread_key_delete isc_thread_key_getspecific isc_thread_key_setspecific isc_thread_setconcurrency isc_time_add isc_time_compare isc_time_formatISO8601 isc_time_formathttptimestamp isc_time_formattimestamp isc_time_isepoch isc_time_microdiff isc_time_nanoseconds isc_time_now isc_time_nowplusinterval isc_time_parsehttptimestamp isc_time_secondsastimet isc_time_seconds isc_time_set isc_time_settoepoch isc_time_subtract isc_timer_attach isc_timer_create isc_timer_detach isc_timer_gettype isc_timer_register isc_timer_reset isc_timer_touch isc_timermgr_create isc_timermgr_createinctx isc_timermgr_destroy isc_timermgr_poke isc_tm_timegm isc_tm_strptime isc_win32os_versioncheck openlog @IF PKCS11 pk11_attribute_bytype pk11_attribute_first pk11_attribute_next pk11_dump_tokens pk11_error_fatalcheck pk11_finalize pk11_get_best_token pk11_get_lib_name pk11_get_session pk11_initialize pk11_initmsgcat pk11_mem_get pk11_mem_put pk11_numbits pk11_parse_uri pk11_rand_bytes pk11_rand_seed_fromfile pk11_result_register pk11_result_totext pk11_return_session pk11_set_lib_name pkcs_C_CloseSession pkcs_C_CreateObject pkcs_C_DeriveKey pkcs_C_DestroyObject pkcs_C_DigestFinal pkcs_C_DigestInit pkcs_C_DigestUpdate pkcs_C_Encrypt pkcs_C_EncryptInit pkcs_C_Finalize pkcs_C_FindObjects pkcs_C_FindObjectsFinal pkcs_C_FindObjectsInit pkcs_C_GenerateKey pkcs_C_GenerateKeyPair pkcs_C_GenerateRandom pkcs_C_GetAttributeValue pkcs_C_GetMechanismInfo pkcs_C_GetSlotList pkcs_C_GetTokenInfo pkcs_C_Initialize pkcs_C_Login pkcs_C_Logout pkcs_C_OpenSession pkcs_C_SeedRandom pkcs_C_SetAttributeValue pkcs_C_Sign pkcs_C_SignFinal pkcs_C_SignInit pkcs_C_SignUpdate pkcs_C_Verify pkcs_C_VerifyFinal pkcs_C_VerifyInit pkcs_C_VerifyUpdate @END PKCS11 syslog @IF NOLONGER ; Exported Data EXPORTS isc_bind9 DATA isc_commandline_argument DATA isc_commandline_errprint DATA isc_commandline_index DATA isc_commandline_option DATA isc_commandline_progname DATA isc_commandline_reset DATA isc_mem_debugging DATA @END NOLONGER bind9-9.10.3.dfsg.P4/lib/isc/win32/libisc.mak.in0000644000470500017500000014012512664710322020226 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on libisc.dsp !IF "$(CFG)" == "" CFG=libisc - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to libisc - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "libisc - @PLATFORM@ Release" && "$(CFG)" != "libisc - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "libisc.mak" CFG="libisc - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "libisc - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE "libisc - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF CPP=cl.exe MTL=midl.exe RSC=rc.exe LIBXML=@LIBXML2_LIB@ !IF "$(CFG)" == "libisc - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "libisc - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release ALL : "..\..\..\Build\Release\libisc.dll" CLEAN : @IF AES -@erase "$(INTDIR)\aes.obj" @END AES -@erase "$(INTDIR)\app.obj" -@erase "$(INTDIR)\assertions.obj" -@erase "$(INTDIR)\backtrace.obj" -@erase "$(INTDIR)\backtrace-emptytbl.obj" -@erase "$(INTDIR)\base32.obj" -@erase "$(INTDIR)\base64.obj" -@erase "$(INTDIR)\bind9.obj" -@erase "$(INTDIR)\buffer.obj" -@erase "$(INTDIR)\bufferlist.obj" -@erase "$(INTDIR)\commandline.obj" -@erase "$(INTDIR)\counter.obj" -@erase "$(INTDIR)\condition.obj" -@erase "$(INTDIR)\crc64.obj" -@erase "$(INTDIR)\dir.obj" -@erase "$(INTDIR)\DLLMain.obj" -@erase "$(INTDIR)\entropy.obj" -@erase "$(INTDIR)\errno2result.obj" -@erase "$(INTDIR)\error.obj" -@erase "$(INTDIR)\event.obj" -@erase "$(INTDIR)\file.obj" -@erase "$(INTDIR)\fsaccess.obj" -@erase "$(INTDIR)\hash.obj" -@erase "$(INTDIR)\heap.obj" -@erase "$(INTDIR)\hex.obj" -@erase "$(INTDIR)\hmacmd5.obj" -@erase "$(INTDIR)\hmacsha.obj" -@erase "$(INTDIR)\httpd.obj" -@erase "$(INTDIR)\inet_aton.obj" -@erase "$(INTDIR)\inet_ntop.obj" -@erase "$(INTDIR)\inet_pton.obj" -@erase "$(INTDIR)\interfaceiter.obj" -@erase "$(INTDIR)\ipv6.obj" -@erase "$(INTDIR)\iterated_hash.obj" -@erase "$(INTDIR)\keyboard.obj" -@erase "$(INTDIR)\lex.obj" -@erase "$(INTDIR)\lfsr.obj" -@erase "$(INTDIR)\lib.obj" -@erase "$(INTDIR)\log.obj" -@erase "$(INTDIR)\md5.obj" -@erase "$(INTDIR)\mem.obj" -@erase "$(INTDIR)\msgcat.obj" -@erase "$(INTDIR)\mutexblock.obj" -@erase "$(INTDIR)\net.obj" -@erase "$(INTDIR)\netaddr.obj" -@erase "$(INTDIR)\netscope.obj" -@erase "$(INTDIR)\ntpaths.obj" -@erase "$(INTDIR)\once.obj" -@erase "$(INTDIR)\ondestroy.obj" -@erase "$(INTDIR)\os.obj" -@erase "$(INTDIR)\parseint.obj" @IF PKCS11 -@erase "$(INTDIR)\pk11.obj" -@erase "$(INTDIR)\pk11_api.obj" -@erase "$(INTDIR)\pk11_result.obj" @END PKCS11 -@erase "$(INTDIR)\pool.obj" -@erase "$(INTDIR)\portset.obj" -@erase "$(INTDIR)\quota.obj" -@erase "$(INTDIR)\radix.obj" -@erase "$(INTDIR)\random.obj" -@erase "$(INTDIR)\ratelimiter.obj" -@erase "$(INTDIR)\refcount.obj" -@erase "$(INTDIR)\regex.obj" -@erase "$(INTDIR)\region.obj" -@erase "$(INTDIR)\resource.obj" -@erase "$(INTDIR)\result.obj" -@erase "$(INTDIR)\rwlock.obj" -@erase "$(INTDIR)\safe.obj" -@erase "$(INTDIR)\serial.obj" -@erase "$(INTDIR)\sha1.obj" -@erase "$(INTDIR)\sha2.obj" -@erase "$(INTDIR)\sockaddr.obj" -@erase "$(INTDIR)\socket.obj" -@erase "$(INTDIR)\stats.obj" -@erase "$(INTDIR)\stdio.obj" -@erase "$(INTDIR)\stdtime.obj" -@erase "$(INTDIR)\strerror.obj" -@erase "$(INTDIR)\string.obj" -@erase "$(INTDIR)\symtab.obj" -@erase "$(INTDIR)\syslog.obj" -@erase "$(INTDIR)\task.obj" -@erase "$(INTDIR)\taskpool.obj" -@erase "$(INTDIR)\thread.obj" -@erase "$(INTDIR)\time.obj" -@erase "$(INTDIR)\timer.obj" -@erase "$(INTDIR)\tm.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\version.obj" -@erase "$(INTDIR)\win32os.obj" -@erase "$(OUTDIR)\libisc.exp" -@erase "$(OUTDIR)\libisc.lib" -@erase "..\..\..\Build\Release\libisc.dll" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" @IF PKCS11 CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" /I "include" /I "../include" /I "win32" /I "../../isccfg/include" /I "../../dns/win32/include" /I "../../dns/include" @LIBXML2_INC@ @OPENSSL_INC@ /D "BIND9" @CRYPTO@ @PK11_LIB_LOCATION@ /D "WIN32" /D "NDEBUG" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" /Fp"$(INTDIR)\libisc.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c @ELSE PKCS11 CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" /I "include" /I "../include" /I "win32" /I "../../isccfg/include" @LIBXML2_INC@ @OPENSSL_INC@ /D "BIND9" /D "WIN32" /D "NDEBUG" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" /Fp"$(INTDIR)\libisc.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c @END PKCS11 MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\libisc.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib $(LIBXML) @OPENSSL_LIB@ /nologo /dll /incremental:no /pdb:"$(OUTDIR)\libisc.pdb" @MACHINE@ /def:".\libisc.def" /out:"../../../Build/Release/libisc.dll" /implib:"$(OUTDIR)\libisc.lib" DEF_FILE= \ ".\libisc.def" LINK32_OBJS= \ "$(INTDIR)\app.obj" \ "$(INTDIR)\condition.obj" \ "$(INTDIR)\dir.obj" \ "$(INTDIR)\DLLMain.obj" \ "$(INTDIR)\entropy.obj" \ "$(INTDIR)\errno2result.obj" \ "$(INTDIR)\file.obj" \ "$(INTDIR)\fsaccess.obj" \ "$(INTDIR)\interfaceiter.obj" \ "$(INTDIR)\ipv6.obj" \ "$(INTDIR)\iterated_hash.obj" \ "$(INTDIR)\keyboard.obj" \ "$(INTDIR)\net.obj" \ "$(INTDIR)\ntpaths.obj" \ "$(INTDIR)\once.obj" \ "$(INTDIR)\os.obj" \ @IF PKCS11 "$(INTDIR)\pk11_api.obj" \ @END PKCS11 "$(INTDIR)\resource.obj" \ "$(INTDIR)\socket.obj" \ "$(INTDIR)\stdio.obj" \ "$(INTDIR)\stdtime.obj" \ "$(INTDIR)\strerror.obj" \ "$(INTDIR)\syslog.obj" \ "$(INTDIR)\thread.obj" \ "$(INTDIR)\time.obj" \ "$(INTDIR)\version.obj" \ "$(INTDIR)\win32os.obj" \ @IF AES "$(INTDIR)\aes.obj" \ @END AES "$(INTDIR)\assertions.obj" \ "$(INTDIR)\backtrace.obj" \ "$(INTDIR)\backtrace-emptytbl.obj" \ "$(INTDIR)\base32.obj" \ "$(INTDIR)\base64.obj" \ "$(INTDIR)\bind9.obj" \ "$(INTDIR)\buffer.obj" \ "$(INTDIR)\bufferlist.obj" \ "$(INTDIR)\commandline.obj" \ "$(INTDIR)\counter.obj" \ "$(INTDIR)\crc64.obj" \ "$(INTDIR)\error.obj" \ "$(INTDIR)\event.obj" \ "$(INTDIR)\hash.obj" \ "$(INTDIR)\heap.obj" \ "$(INTDIR)\hex.obj" \ "$(INTDIR)\hmacmd5.obj" \ "$(INTDIR)\hmacsha.obj" \ "$(INTDIR)\httpd.obj" \ "$(INTDIR)\inet_aton.obj" \ "$(INTDIR)\inet_ntop.obj" \ "$(INTDIR)\inet_pton.obj" \ "$(INTDIR)\lex.obj" \ "$(INTDIR)\lfsr.obj" \ "$(INTDIR)\lib.obj" \ "$(INTDIR)\log.obj" \ "$(INTDIR)\md5.obj" \ "$(INTDIR)\mem.obj" \ "$(INTDIR)\msgcat.obj" \ "$(INTDIR)\mutexblock.obj" \ "$(INTDIR)\netaddr.obj" \ "$(INTDIR)\netscope.obj" \ "$(INTDIR)\ondestroy.obj" \ @IF PKCS11 "$(INTDIR)\pk11.obj" \ "$(INTDIR)\pk11_result.obj" \ @END PKCS11 "$(INTDIR)\quota.obj" \ "$(INTDIR)\radix.obj" \ "$(INTDIR)\random.obj" \ "$(INTDIR)\ratelimiter.obj" \ "$(INTDIR)\refcount.obj" \ "$(INTDIR)\result.obj" \ "$(INTDIR)\rwlock.obj" \ "$(INTDIR)\safe.obj" \ "$(INTDIR)\serial.obj" \ "$(INTDIR)\sha1.obj" \ "$(INTDIR)\sha2.obj" \ "$(INTDIR)\sockaddr.obj" \ "$(INTDIR)\stats.obj" \ "$(INTDIR)\string.obj" \ "$(INTDIR)\symtab.obj" \ "$(INTDIR)\task.obj" \ "$(INTDIR)\taskpool.obj" \ "$(INTDIR)\timer.obj" \ "$(INTDIR)\tm.obj" \ "$(INTDIR)\parseint.obj" \ "$(INTDIR)\pool.obj" \ "$(INTDIR)\portset.obj" \ "$(INTDIR)\regex.obj" \ "$(INTDIR)\region.obj" "..\..\..\Build\Release\libisc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_DLL) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros ALL : "..\..\..\Build\Debug\libisc.dll" "$(OUTDIR)\libisc.bsc" CLEAN : @IF AES -@erase "$(INTDIR)\aes.obj" -@erase "$(INTDIR)\aes.sbr" @END AES -@erase "$(INTDIR)\app.obj" -@erase "$(INTDIR)\app.sbr" -@erase "$(INTDIR)\assertions.obj" -@erase "$(INTDIR)\assertions.sbr" -@erase "$(INTDIR)\backtrace.obj" -@erase "$(INTDIR)\backtrace-emptytbl.obj" -@erase "$(INTDIR)\backtrace.sbr" -@erase "$(INTDIR)\backtrace-emptytbl.sbr" -@erase "$(INTDIR)\base32.obj" -@erase "$(INTDIR)\base32.sbr" -@erase "$(INTDIR)\base64.obj" -@erase "$(INTDIR)\base64.sbr" -@erase "$(INTDIR)\bind9.obj" -@erase "$(INTDIR)\bind9.sbr" -@erase "$(INTDIR)\buffer.obj" -@erase "$(INTDIR)\buffer.sbr" -@erase "$(INTDIR)\bufferlist.obj" -@erase "$(INTDIR)\bufferlist.sbr" -@erase "$(INTDIR)\commandline.obj" -@erase "$(INTDIR)\commandline.sbr" -@erase "$(INTDIR)\counter.obj" -@erase "$(INTDIR)\counter.sbr" -@erase "$(INTDIR)\condition.obj" -@erase "$(INTDIR)\condition.sbr" -@erase "$(INTDIR)\crc64.obj" -@erase "$(INTDIR)\crc64.sbr" -@erase "$(INTDIR)\dir.obj" -@erase "$(INTDIR)\dir.sbr" -@erase "$(INTDIR)\DLLMain.obj" -@erase "$(INTDIR)\DLLMain.sbr" -@erase "$(INTDIR)\entropy.obj" -@erase "$(INTDIR)\entropy.sbr" -@erase "$(INTDIR)\errno2result.obj" -@erase "$(INTDIR)\errno2result.sbr" -@erase "$(INTDIR)\error.obj" -@erase "$(INTDIR)\error.sbr" -@erase "$(INTDIR)\event.obj" -@erase "$(INTDIR)\event.sbr" -@erase "$(INTDIR)\file.obj" -@erase "$(INTDIR)\file.sbr" -@erase "$(INTDIR)\fsaccess.obj" -@erase "$(INTDIR)\fsaccess.sbr" -@erase "$(INTDIR)\hash.obj" -@erase "$(INTDIR)\hash.sbr" -@erase "$(INTDIR)\heap.obj" -@erase "$(INTDIR)\heap.sbr" -@erase "$(INTDIR)\hex.obj" -@erase "$(INTDIR)\hex.sbr" -@erase "$(INTDIR)\hmacmd5.obj" -@erase "$(INTDIR)\hmacmd5.sbr" -@erase "$(INTDIR)\hmacsha.obj" -@erase "$(INTDIR)\hmacsha.sbr" -@erase "$(INTDIR)\httpd.obj" -@erase "$(INTDIR)\httpd.sbr" -@erase "$(INTDIR)\inet_aton.obj" -@erase "$(INTDIR)\inet_aton.sbr" -@erase "$(INTDIR)\inet_ntop.obj" -@erase "$(INTDIR)\inet_ntop.sbr" -@erase "$(INTDIR)\inet_pton.obj" -@erase "$(INTDIR)\inet_pton.sbr" -@erase "$(INTDIR)\interfaceiter.obj" -@erase "$(INTDIR)\interfaceiter.sbr" -@erase "$(INTDIR)\ipv6.obj" -@erase "$(INTDIR)\ipv6.sbr" -@erase "$(INTDIR)\iterated_hash.obj" -@erase "$(INTDIR)\iterated_hash.sbr" -@erase "$(INTDIR)\keyboard.obj" -@erase "$(INTDIR)\keyboard.sbr" -@erase "$(INTDIR)\lex.obj" -@erase "$(INTDIR)\lex.sbr" -@erase "$(INTDIR)\lfsr.obj" -@erase "$(INTDIR)\lfsr.sbr" -@erase "$(INTDIR)\lib.obj" -@erase "$(INTDIR)\lib.sbr" -@erase "$(INTDIR)\log.obj" -@erase "$(INTDIR)\log.sbr" -@erase "$(INTDIR)\md5.obj" -@erase "$(INTDIR)\md5.sbr" -@erase "$(INTDIR)\mem.obj" -@erase "$(INTDIR)\mem.sbr" -@erase "$(INTDIR)\msgcat.obj" -@erase "$(INTDIR)\msgcat.sbr" -@erase "$(INTDIR)\mutexblock.obj" -@erase "$(INTDIR)\mutexblock.sbr" -@erase "$(INTDIR)\net.obj" -@erase "$(INTDIR)\net.sbr" -@erase "$(INTDIR)\netaddr.obj" -@erase "$(INTDIR)\netaddr.sbr" -@erase "$(INTDIR)\netscope.obj" -@erase "$(INTDIR)\netscope.sbr" -@erase "$(INTDIR)\ntpaths.obj" -@erase "$(INTDIR)\ntpaths.sbr" -@erase "$(INTDIR)\once.obj" -@erase "$(INTDIR)\once.sbr" -@erase "$(INTDIR)\ondestroy.obj" -@erase "$(INTDIR)\ondestroy.sbr" -@erase "$(INTDIR)\os.obj" -@erase "$(INTDIR)\os.sbr" -@erase "$(INTDIR)\parseint.obj" -@erase "$(INTDIR)\parseint.sbr" @IF PKCS11 -@erase "$(INTDIR)\pk11.obj" -@erase "$(INTDIR)\pk11_api.obj" -@erase "$(INTDIR)\pk11_result.obj" @END PKCS11 -@erase "$(INTDIR)\pool.obj" -@erase "$(INTDIR)\pool.sbr" -@erase "$(INTDIR)\portset.obj" -@erase "$(INTDIR)\portset.sbr" -@erase "$(INTDIR)\quota.obj" -@erase "$(INTDIR)\quota.sbr" -@erase "$(INTDIR)\radix.obj" -@erase "$(INTDIR)\radix.sbr" -@erase "$(INTDIR)\random.obj" -@erase "$(INTDIR)\random.sbr" -@erase "$(INTDIR)\ratelimiter.obj" -@erase "$(INTDIR)\ratelimiter.sbr" -@erase "$(INTDIR)\refcount.obj" -@erase "$(INTDIR)\refcount.sbr" -@erase "$(INTDIR)\regex.obj" -@erase "$(INTDIR)\regex.sbr" -@erase "$(INTDIR)\region.obj" -@erase "$(INTDIR)\region.sbr" -@erase "$(INTDIR)\resource.obj" -@erase "$(INTDIR)\resource.sbr" -@erase "$(INTDIR)\result.obj" -@erase "$(INTDIR)\result.sbr" -@erase "$(INTDIR)\rwlock.obj" -@erase "$(INTDIR)\rwlock.sbr" -@erase "$(INTDIR)\safe.obj" -@erase "$(INTDIR)\safe.sbr" -@erase "$(INTDIR)\serial.obj" -@erase "$(INTDIR)\serial.sbr" -@erase "$(INTDIR)\sha1.obj" -@erase "$(INTDIR)\sha1.sbr" -@erase "$(INTDIR)\sha2.obj" -@erase "$(INTDIR)\sha2.sbr" -@erase "$(INTDIR)\sockaddr.obj" -@erase "$(INTDIR)\sockaddr.sbr" -@erase "$(INTDIR)\socket.obj" -@erase "$(INTDIR)\socket.sbr" -@erase "$(INTDIR)\stats.obj" -@erase "$(INTDIR)\stats.sbr" -@erase "$(INTDIR)\stdio.obj" -@erase "$(INTDIR)\stdio.sbr" -@erase "$(INTDIR)\stdtime.obj" -@erase "$(INTDIR)\stdtime.sbr" -@erase "$(INTDIR)\strerror.obj" -@erase "$(INTDIR)\strerror.sbr" -@erase "$(INTDIR)\string.obj" -@erase "$(INTDIR)\string.sbr" -@erase "$(INTDIR)\symtab.obj" -@erase "$(INTDIR)\symtab.sbr" -@erase "$(INTDIR)\syslog.obj" -@erase "$(INTDIR)\syslog.sbr" -@erase "$(INTDIR)\task.obj" -@erase "$(INTDIR)\task.sbr" -@erase "$(INTDIR)\taskpool.obj" -@erase "$(INTDIR)\taskpool.sbr" -@erase "$(INTDIR)\thread.obj" -@erase "$(INTDIR)\thread.sbr" -@erase "$(INTDIR)\time.obj" -@erase "$(INTDIR)\time.sbr" -@erase "$(INTDIR)\timer.obj" -@erase "$(INTDIR)\timer.sbr" -@erase "$(INTDIR)\tm.obj" -@erase "$(INTDIR)\tm.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(INTDIR)\version.obj" -@erase "$(INTDIR)\version.sbr" -@erase "$(INTDIR)\win32os.obj" -@erase "$(INTDIR)\win32os.sbr" -@erase "$(OUTDIR)\libisc.bsc" -@erase "$(OUTDIR)\libisc.exp" -@erase "$(OUTDIR)\libisc.lib" -@erase "$(OUTDIR)\libisc.map" -@erase "$(OUTDIR)\libisc.pdb" -@erase "..\..\..\Build\Debug\libisc.dll" -@erase "..\..\..\Build\Debug\libisc.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" @IF PKCS11 CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" /I "include" /I "../include" /I "win32" /I "../../isccfg/include" /I "../../dns/win32/include" /I "../../dns/include" @LIBXML2_INC@ @OPENSSL_INC@ /D "BIND9" @CRYPTO@ @PK11_LIB_LOCATION@ /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\libisc.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c @ELSE PKCS11 CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" /I "include" /I "../include" /I "win32" /I "../../isccfg/include" @LIBXML2_INC@ @OPENSSL_INC@ /D "BIND9" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "LIBISC_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\libisc.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c @END PKCS11 MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\libisc.bsc" BSC32_SBRS= \ "$(INTDIR)\app.sbr" \ "$(INTDIR)\condition.sbr" \ "$(INTDIR)\dir.sbr" \ "$(INTDIR)\DLLMain.sbr" \ "$(INTDIR)\entropy.sbr" \ "$(INTDIR)\errno2result.sbr" \ "$(INTDIR)\file.sbr" \ "$(INTDIR)\fsaccess.sbr" \ "$(INTDIR)\interfaceiter.sbr" \ "$(INTDIR)\ipv6.sbr" \ "$(INTDIR)\iterated_hash.sbr" \ "$(INTDIR)\keyboard.sbr" \ "$(INTDIR)\net.sbr" \ "$(INTDIR)\ntpaths.sbr" \ "$(INTDIR)\once.sbr" \ "$(INTDIR)\os.sbr" \ @IF PKCS11 "$(INTDIR)\pk11_api.sbr" \ @END PKCS11 "$(INTDIR)\resource.sbr" \ "$(INTDIR)\socket.sbr" \ "$(INTDIR)\stdio.sbr" \ "$(INTDIR)\stdtime.sbr" \ "$(INTDIR)\strerror.sbr" \ "$(INTDIR)\syslog.sbr" \ "$(INTDIR)\thread.sbr" \ "$(INTDIR)\time.sbr" \ "$(INTDIR)\version.sbr" \ "$(INTDIR)\win32os.sbr" \ @IF AES "$(INTDIR)\aes.sbr" \ @END AES "$(INTDIR)\assertions.sbr" \ "$(INTDIR)\backtrace.sbr" \ "$(INTDIR)\backtrace-emptytbl.sbr" \ "$(INTDIR)\base32.sbr" \ "$(INTDIR)\base64.sbr" \ "$(INTDIR)\bind9.sbr" \ "$(INTDIR)\buffer.sbr" \ "$(INTDIR)\bufferlist.sbr" \ "$(INTDIR)\commandline.sbr" \ "$(INTDIR)\counter.sbr" \ "$(INTDIR)\crc64.sbr" \ "$(INTDIR)\error.sbr" \ "$(INTDIR)\event.sbr" \ "$(INTDIR)\hash.sbr" \ "$(INTDIR)\heap.sbr" \ "$(INTDIR)\hex.sbr" \ "$(INTDIR)\hmacmd5.sbr" \ "$(INTDIR)\hmacsha.sbr" \ "$(INTDIR)\httpd.sbr" \ "$(INTDIR)\inet_aton.sbr" \ "$(INTDIR)\inet_ntop.sbr" \ "$(INTDIR)\inet_pton.sbr" \ "$(INTDIR)\lex.sbr" \ "$(INTDIR)\lfsr.sbr" \ "$(INTDIR)\lib.sbr" \ "$(INTDIR)\log.sbr" \ "$(INTDIR)\md5.sbr" \ "$(INTDIR)\mem.sbr" \ "$(INTDIR)\msgcat.sbr" \ "$(INTDIR)\mutexblock.sbr" \ "$(INTDIR)\netaddr.sbr" \ "$(INTDIR)\netscope.sbr" \ "$(INTDIR)\ondestroy.sbr" \ @IF PKCS11 "$(INTDIR)\pk11.sbr" \ "$(INTDIR)\pk11_result.sbr" \ @END PKCS11 "$(INTDIR)\quota.sbr" \ "$(INTDIR)\radix.sbr" \ "$(INTDIR)\random.sbr" \ "$(INTDIR)\ratelimiter.sbr" \ "$(INTDIR)\refcount.sbr" \ "$(INTDIR)\result.sbr" \ "$(INTDIR)\rwlock.sbr" \ "$(INTDIR)\safe.sbr" \ "$(INTDIR)\serial.sbr" \ "$(INTDIR)\sha1.sbr" \ "$(INTDIR)\sha2.sbr" \ "$(INTDIR)\sockaddr.sbr" \ "$(INTDIR)\stats.sbr" \ "$(INTDIR)\string.sbr" \ "$(INTDIR)\symtab.sbr" \ "$(INTDIR)\task.sbr" \ "$(INTDIR)\taskpool.sbr" \ "$(INTDIR)\timer.sbr" \ "$(INTDIR)\tm.sbr" \ "$(INTDIR)\parseint.sbr" \ "$(INTDIR)\pool.sbr" \ "$(INTDIR)\portset.sbr" \ "$(INTDIR)\regex.sbr" \ "$(INTDIR)\region.sbr" "$(OUTDIR)\libisc.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib $(LIBXML) @OPENSSL_LIB@ /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\libisc.pdb" /map:"$(INTDIR)\libisc.map" /debug @MACHINE@ /def:".\libisc.def" /out:"../../../Build/Debug/libisc.dll" /implib:"$(OUTDIR)\libisc.lib" /pdbtype:sept DEF_FILE= \ ".\libisc.def" LINK32_OBJS= \ "$(INTDIR)\app.obj" \ "$(INTDIR)\condition.obj" \ "$(INTDIR)\dir.obj" \ "$(INTDIR)\DLLMain.obj" \ "$(INTDIR)\entropy.obj" \ "$(INTDIR)\errno2result.obj" \ "$(INTDIR)\file.obj" \ "$(INTDIR)\fsaccess.obj" \ "$(INTDIR)\interfaceiter.obj" \ "$(INTDIR)\ipv6.obj" \ "$(INTDIR)\iterated_hash.obj" \ "$(INTDIR)\keyboard.obj" \ "$(INTDIR)\net.obj" \ "$(INTDIR)\ntpaths.obj" \ "$(INTDIR)\once.obj" \ "$(INTDIR)\os.obj" \ @IF PKCS11 "$(INTDIR)\pk11_api.obj" \ @END PKCS11 "$(INTDIR)\resource.obj" \ "$(INTDIR)\socket.obj" \ "$(INTDIR)\stdio.obj" \ "$(INTDIR)\stdtime.obj" \ "$(INTDIR)\strerror.obj" \ "$(INTDIR)\syslog.obj" \ "$(INTDIR)\thread.obj" \ "$(INTDIR)\time.obj" \ "$(INTDIR)\version.obj" \ "$(INTDIR)\win32os.obj" \ @IF AES "$(INTDIR)\aes.obj" \ @END AES "$(INTDIR)\assertions.obj" \ "$(INTDIR)\backtrace.obj" \ "$(INTDIR)\backtrace-emptytbl.obj" \ "$(INTDIR)\base32.obj" \ "$(INTDIR)\base64.obj" \ "$(INTDIR)\bind9.obj" \ "$(INTDIR)\buffer.obj" \ "$(INTDIR)\bufferlist.obj" \ "$(INTDIR)\commandline.obj" \ "$(INTDIR)\counter.obj" \ "$(INTDIR)\crc64.obj" \ "$(INTDIR)\error.obj" \ "$(INTDIR)\event.obj" \ "$(INTDIR)\hash.obj" \ "$(INTDIR)\heap.obj" \ "$(INTDIR)\hex.obj" \ "$(INTDIR)\hmacmd5.obj" \ "$(INTDIR)\hmacsha.obj" \ "$(INTDIR)\httpd.obj" \ "$(INTDIR)\inet_aton.obj" \ "$(INTDIR)\inet_ntop.obj" \ "$(INTDIR)\inet_pton.obj" \ "$(INTDIR)\lex.obj" \ "$(INTDIR)\lfsr.obj" \ "$(INTDIR)\lib.obj" \ "$(INTDIR)\log.obj" \ "$(INTDIR)\md5.obj" \ "$(INTDIR)\mem.obj" \ "$(INTDIR)\msgcat.obj" \ "$(INTDIR)\mutexblock.obj" \ "$(INTDIR)\netaddr.obj" \ "$(INTDIR)\netscope.obj" \ "$(INTDIR)\ondestroy.obj" \ @IF PKCS11 "$(INTDIR)\pk11.obj" \ "$(INTDIR)\pk11_result.obj" \ @END PKCS11 "$(INTDIR)\quota.obj" \ "$(INTDIR)\radix.obj" \ "$(INTDIR)\random.obj" \ "$(INTDIR)\ratelimiter.obj" \ "$(INTDIR)\refcount.obj" \ "$(INTDIR)\result.obj" \ "$(INTDIR)\rwlock.obj" \ "$(INTDIR)\safe.obj" \ "$(INTDIR)\serial.obj" \ "$(INTDIR)\sha1.obj" \ "$(INTDIR)\sha2.obj" \ "$(INTDIR)\sockaddr.obj" \ "$(INTDIR)\stats.obj" \ "$(INTDIR)\string.obj" \ "$(INTDIR)\symtab.obj" \ "$(INTDIR)\task.obj" \ "$(INTDIR)\taskpool.obj" \ "$(INTDIR)\timer.obj" \ "$(INTDIR)\tm.obj" \ "$(INTDIR)\parseint.obj" \ "$(INTDIR)\pool.obj" \ "$(INTDIR)\portset.obj" \ "$(INTDIR)\regex.obj" \ "$(INTDIR)\region.obj" "..\..\..\Build\Debug\libisc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_DLL) !ENDIF .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("libisc.dep") !INCLUDE "libisc.dep" !ELSE !MESSAGE Warning: cannot find "libisc.dep" !ENDIF !ENDIF !IF "$(CFG)" == "libisc - @PLATFORM@ Release" || "$(CFG)" == "libisc - @PLATFORM@ Debug" SOURCE=.\app.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\app.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\app.obj" "$(INTDIR)\app.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\condition.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\condition.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\condition.obj" "$(INTDIR)\condition.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\dir.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\dir.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\dir.obj" "$(INTDIR)\dir.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\DLLMain.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\DLLMain.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\DLLMain.obj" "$(INTDIR)\DLLMain.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\entropy.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\entropy.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\entropy.obj" "$(INTDIR)\entropy.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\errno2result.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\errno2result.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\errno2result.obj" "$(INTDIR)\errno2result.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\file.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\file.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\file.obj" "$(INTDIR)\file.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\fsaccess.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\fsaccess.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\fsaccess.obj" "$(INTDIR)\fsaccess.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\interfaceiter.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\interfaceiter.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\interfaceiter.obj" "$(INTDIR)\interfaceiter.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\ipv6.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\ipv6.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\ipv6.obj" "$(INTDIR)\ipv6.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\keyboard.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\keyboard.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\keyboard.obj" "$(INTDIR)\keyboard.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\net.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\net.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\net.obj" "$(INTDIR)\net.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\ntpaths.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\ntpaths.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\ntpaths.obj" "$(INTDIR)\ntpaths.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\once.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\once.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\once.obj" "$(INTDIR)\once.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\os.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\os.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\os.obj" "$(INTDIR)\os.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\pk11_api.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\pk11_api.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\pk11_api.obj" "$(INTDIR)\pk11_api.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=.\resource.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\resource.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\resource.obj" "$(INTDIR)\resource.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\socket.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\socket.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\socket.obj" "$(INTDIR)\socket.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\stdio.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\stdio.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\stdio.obj" "$(INTDIR)\stdio.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\stdtime.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\stdtime.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\stdtime.obj" "$(INTDIR)\stdtime.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\strerror.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\strerror.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\strerror.obj" "$(INTDIR)\strerror.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\syslog.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\syslog.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\syslog.obj" "$(INTDIR)\syslog.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\thread.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\thread.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\thread.obj" "$(INTDIR)\thread.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\time.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\time.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\time.obj" "$(INTDIR)\time.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\version.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\version.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\version.obj" "$(INTDIR)\version.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=.\win32os.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\win32os.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\win32os.obj" "$(INTDIR)\win32os.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF @IF AES SOURCE=..\aes.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\aes.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\aes.obj" "$(INTDIR)\aes.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF @END AES SOURCE=..\assertions.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\assertions.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\assertions.obj" "$(INTDIR)\assertions.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\backtrace.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\backtrace.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\backtrace.obj" "$(INTDIR)\backtrace.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\backtrace-emptytbl.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\backtrace-emptytbl.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\backtrace-emptytbl.obj" "$(INTDIR)\backtrace-emptytbl.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\base32.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\base32.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\base32.obj" "$(INTDIR)\base32.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\base64.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\base64.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\base64.obj" "$(INTDIR)\base64.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\bind9.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\bind9.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\bind9.obj" "$(INTDIR)\bind9.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\buffer.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\buffer.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\buffer.obj" "$(INTDIR)\buffer.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\bufferlist.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\bufferlist.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\bufferlist.obj" "$(INTDIR)\bufferlist.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\commandline.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\commandline.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\commandline.obj" "$(INTDIR)\commandline.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\counter.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\counter.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\counter.obj" "$(INTDIR)\counter.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\crc64.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\crc64.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\crc64.obj" "$(INTDIR)\crc64.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\error.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\error.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\error.obj" "$(INTDIR)\error.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\event.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\event.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\event.obj" "$(INTDIR)\event.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\hash.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\hash.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\hash.obj" "$(INTDIR)\hash.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\heap.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\heap.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\heap.obj" "$(INTDIR)\heap.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\hex.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\hex.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\hex.obj" "$(INTDIR)\hex.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\hmacmd5.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\hmacmd5.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\hmacmd5.obj" "$(INTDIR)\hmacmd5.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\hmacsha.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\hmacsha.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\hmacsha.obj" "$(INTDIR)\hmacsha.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\httpd.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\httpd.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\httpd.obj" "$(INTDIR)\httpd.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\inet_aton.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\inet_aton.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\inet_aton.obj" "$(INTDIR)\inet_aton.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\inet_ntop.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\inet_ntop.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\inet_ntop.obj" "$(INTDIR)\inet_ntop.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\inet_pton.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\inet_pton.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\inet_pton.obj" "$(INTDIR)\inet_pton.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\iterated_hash.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\iterated_hash.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\iterated_hash.obj" "$(INTDIR)\iterated_hash.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\lex.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\lex.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\lex.obj" "$(INTDIR)\lex.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\lfsr.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\lfsr.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\lfsr.obj" "$(INTDIR)\lfsr.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\lib.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\lib.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\lib.obj" "$(INTDIR)\lib.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\log.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\log.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\log.obj" "$(INTDIR)\log.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\md5.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\md5.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\md5.obj" "$(INTDIR)\md5.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\mem.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\mem.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\mem.obj" "$(INTDIR)\mem.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\nls\msgcat.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\msgcat.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\msgcat.obj" "$(INTDIR)\msgcat.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\mutexblock.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\mutexblock.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\mutexblock.obj" "$(INTDIR)\mutexblock.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\netaddr.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\netaddr.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\netaddr.obj" "$(INTDIR)\netaddr.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\netscope.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\netscope.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\netscope.obj" "$(INTDIR)\netscope.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\ondestroy.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\ondestroy.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\ondestroy.obj" "$(INTDIR)\ondestroy.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\parseint.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\parseint.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\parseint.obj" "$(INTDIR)\parseint.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\pk11.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\pk11.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\pk11.obj" "$(INTDIR)\pk11.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\pk11_result.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\pk11_result.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\pk11_result.obj" "$(INTDIR)\pk11_result.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\pool.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\pool.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\pool.obj" "$(INTDIR)\pool.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\portset.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\portset.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\portset.obj" "$(INTDIR)\portset.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\quota.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\quota.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\quota.obj" "$(INTDIR)\quota.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\radix.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\radix.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\radix.obj" "$(INTDIR)\radix.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\random.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\random.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\random.obj" "$(INTDIR)\random.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\ratelimiter.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\ratelimiter.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\ratelimiter.obj" "$(INTDIR)\ratelimiter.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\refcount.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\refcount.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\refcount.obj" "$(INTDIR)\refcount.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\regex.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\regex.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\regex.obj" "$(INTDIR)\regex.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\region.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\region.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\region.obj" "$(INTDIR)\region.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\result.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\result.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\result.obj" "$(INTDIR)\result.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\rwlock.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\rwlock.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\rwlock.obj" "$(INTDIR)\rwlock.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\safe.c !IF "$(CFG)" == "libisc - Win32 Release" "$(INTDIR)\safe.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - Win32 Debug" "$(INTDIR)\safe.obj" "$(INTDIR)\safe.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\serial.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\serial.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\serial.obj" "$(INTDIR)\serial.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\sha1.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\sha1.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\sha1.obj" "$(INTDIR)\sha1.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\sha2.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\sha2.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\sha2.obj" "$(INTDIR)\sha2.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\sockaddr.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\sockaddr.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\sockaddr.obj" "$(INTDIR)\sockaddr.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\stats.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\stats.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\stats.obj" "$(INTDIR)\stats.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\string.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\string.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\string.obj" "$(INTDIR)\string.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\symtab.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\symtab.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\symtab.obj" "$(INTDIR)\symtab.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\task.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\task.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\task.obj" "$(INTDIR)\task.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\taskpool.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\taskpool.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\taskpool.obj" "$(INTDIR)\taskpool.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\timer.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\timer.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\timer.obj" "$(INTDIR)\timer.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\tm.c !IF "$(CFG)" == "libisc - @PLATFORM@ Release" "$(INTDIR)\tm.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisc - @PLATFORM@ Debug" "$(INTDIR)\tm.obj" "$(INTDIR)\tm.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/lib/isc/win32/thread.c0000644000470500017500000000436512664710322017302 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: thread.c,v 1.24 2007/06/19 23:47:19 tbox Exp $ */ #include #include #include isc_result_t isc_thread_create(isc_threadfunc_t start, isc_threadarg_t arg, isc_thread_t *threadp) { isc_thread_t thread; unsigned int id; thread = (isc_thread_t)_beginthreadex(NULL, 0, start, arg, 0, &id); if (thread == NULL) { /* XXX */ return (ISC_R_UNEXPECTED); } *threadp = thread; return (ISC_R_SUCCESS); } isc_result_t isc_thread_join(isc_thread_t thread, isc_threadresult_t *rp) { DWORD result; result = WaitForSingleObject(thread, INFINITE); if (result != WAIT_OBJECT_0) { /* XXX */ return (ISC_R_UNEXPECTED); } if (rp != NULL && !GetExitCodeThread(thread, rp)) { /* XXX */ return (ISC_R_UNEXPECTED); } (void)CloseHandle(thread); return (ISC_R_SUCCESS); } void isc_thread_setconcurrency(unsigned int level) { /* * This is unnecessary on Win32 systems, but is here so that the * call exists */ } void * isc_thread_key_getspecific(isc_thread_key_t key) { return(TlsGetValue(key)); } int isc_thread_key_setspecific(isc_thread_key_t key, void *value) { return (TlsSetValue(key, value) ? 0 : GetLastError()); } int isc_thread_key_create(isc_thread_key_t *key, void (*func)(void *)) { *key = TlsAlloc(); return ((*key != -1) ? 0 : GetLastError()); } int isc_thread_key_delete(isc_thread_key_t key) { return (TlsFree(key) ? 0 : GetLastError()); } bind9-9.10.3.dfsg.P4/lib/isc/win32/interfaceiter.c0000644000470500017500000003122412664710322020651 0ustar lamontlamont/* * Copyright (C) 2004, 2007-2009, 2013-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: interfaceiter.c,v 1.15 2009/01/18 23:48:14 tbox Exp $ */ /* * Note that this code will need to be revisited to support IPv6 Interfaces. * For now we just iterate through IPv4 interfaces. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void InitSockets(void); /* Common utility functions */ /* * Extract the network address part from a "struct sockaddr". * * The address family is given explicitly * instead of using src->sa_family, because the latter does not work * for copying a network mask obtained by SIOCGIFNETMASK (it does * not have a valid address family). */ #define IFITER_MAGIC 0x49464954U /* IFIT. */ #define VALID_IFITER(t) ((t) != NULL && (t)->magic == IFITER_MAGIC) struct isc_interfaceiter { unsigned int magic; /* Magic number. */ isc_mem_t *mctx; SOCKET socket; INTERFACE_INFO IFData; /* Current Interface Info */ int numIF; /* Current Interface count */ int v4IF; /* Number of IPv4 Interfaces */ INTERFACE_INFO *buf4; /* Buffer for WSAIoctl data. */ unsigned int buf4size; /* Bytes allocated. */ INTERFACE_INFO *pos4; /* Current offset in IF List */ SOCKET_ADDRESS_LIST *buf6; unsigned int buf6size; /* Bytes allocated. */ unsigned int pos6; isc_interface_t current; /* Current interface data. */ isc_result_t result; /* Last result code. */ }; /* * Size of buffer for SIO_GET_INTERFACE_LIST, in number of interfaces. * We assume no sane system will have more than than 1K of IP addresses on * all of its adapters. */ #define IFCONF_SIZE_INITIAL 16 #define IFCONF_SIZE_INCREMENT 64 #define IFCONF_SIZE_MAX 1040 static void get_addr(unsigned int family, isc_netaddr_t *dst, struct sockaddr *src) { dst->family = family; switch (family) { case AF_INET: memmove(&dst->type.in, &((struct sockaddr_in *) src)->sin_addr, sizeof(struct in_addr)); break; case AF_INET6: memmove(&dst->type.in6, &((struct sockaddr_in6 *) src)->sin6_addr, sizeof(struct in6_addr)); dst->zone = ((struct sockaddr_in6 *) src)->sin6_scope_id; break; default: INSIST(0); break; } } isc_result_t isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { char strbuf[ISC_STRERRORSIZE]; isc_interfaceiter_t *iter; isc_result_t result; int error; unsigned long bytesReturned = 0; REQUIRE(mctx != NULL); REQUIRE(iterp != NULL); REQUIRE(*iterp == NULL); iter = isc_mem_get(mctx, sizeof(*iter)); if (iter == NULL) return (ISC_R_NOMEMORY); InitSockets(); iter->mctx = mctx; iter->buf4 = NULL; iter->buf6 = NULL; iter->pos4 = NULL; iter->pos6 = 0; iter->buf6size = 0; iter->buf4size = 0; iter->result = ISC_R_FAILURE; iter->numIF = 0; iter->v4IF = 0; /* * Create an unbound datagram socket to do the * SIO_GET_INTERFACE_LIST WSAIoctl on. */ iter->socket = socket(AF_INET, SOCK_DGRAM, 0); if (iter->socket == INVALID_SOCKET) { error = WSAGetLastError(); if (error == WSAEAFNOSUPPORT) goto inet6_only; isc__strerror(error, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "making interface scan socket: %s", strbuf); result = ISC_R_UNEXPECTED; goto socket_failure; } /* * Get the interface configuration, allocating more memory if * necessary. */ iter->buf4size = IFCONF_SIZE_INITIAL*sizeof(INTERFACE_INFO); for (;;) { iter->buf4 = isc_mem_get(mctx, iter->buf4size); if (iter->buf4 == NULL) { result = ISC_R_NOMEMORY; goto alloc_failure; } if (WSAIoctl(iter->socket, SIO_GET_INTERFACE_LIST, 0, 0, iter->buf4, iter->buf4size, &bytesReturned, 0, 0) == SOCKET_ERROR) { error = WSAGetLastError(); if (error != WSAEFAULT && error != WSAENOBUFS) { errno = error; isc__strerror(error, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "get interface configuration: %s", strbuf); result = ISC_R_UNEXPECTED; goto ioctl_failure; } /* * EINVAL. Retry with a bigger buffer. */ } else { /* * The WSAIoctl succeeded. * If the number of the returned bytes is the same * as the buffer size, we will grow it just in * case and retry. */ if (bytesReturned > 0 && (bytesReturned < iter->buf4size)) break; } if (iter->buf4size >= IFCONF_SIZE_MAX*sizeof(INTERFACE_INFO)) { UNEXPECTED_ERROR(__FILE__, __LINE__, "get interface configuration: " "maximum buffer size exceeded"); result = ISC_R_UNEXPECTED; goto ioctl_failure; } isc_mem_put(mctx, iter->buf4, iter->buf4size); iter->buf4size += IFCONF_SIZE_INCREMENT * sizeof(INTERFACE_INFO); } /* * A newly created iterator has an undefined position * until isc_interfaceiter_first() is called. */ iter->v4IF = bytesReturned/sizeof(INTERFACE_INFO); /* We don't need the socket any more, so close it */ closesocket(iter->socket); inet6_only: /* * Create an unbound datagram socket to do the * SIO_ADDRESS_LIST_QUERY WSAIoctl on. */ iter->socket = socket(AF_INET6, SOCK_DGRAM, 0); if (iter->socket == INVALID_SOCKET) { error = WSAGetLastError(); if (error == WSAEAFNOSUPPORT) goto inet_only; isc__strerror(error, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "making interface scan socket: %s", strbuf); result = ISC_R_UNEXPECTED; goto ioctl_failure; } /* * Get the interface configuration, allocating more memory if * necessary. */ iter->buf6size = sizeof(SOCKET_ADDRESS_LIST) + IFCONF_SIZE_INITIAL*sizeof(SOCKET_ADDRESS); for (;;) { iter->buf6 = isc_mem_get(mctx, iter->buf6size); if (iter->buf6 == NULL) { result = ISC_R_NOMEMORY; goto ioctl_failure; } if (WSAIoctl(iter->socket, SIO_ADDRESS_LIST_QUERY, 0, 0, iter->buf6, iter->buf6size, &bytesReturned, 0, 0) == SOCKET_ERROR) { error = WSAGetLastError(); if (error != WSAEFAULT && error != WSAENOBUFS) { errno = error; isc__strerror(error, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "sio address list query: %s", strbuf); result = ISC_R_UNEXPECTED; goto ioctl6_failure; } /* * EINVAL. Retry with a bigger buffer. */ } else break; if (iter->buf6size >= IFCONF_SIZE_MAX*sizeof(SOCKET_ADDRESS)) { UNEXPECTED_ERROR(__FILE__, __LINE__, "get interface configuration: " "maximum buffer size exceeded"); result = ISC_R_UNEXPECTED; goto ioctl6_failure; } isc_mem_put(mctx, iter->buf6, iter->buf6size); iter->buf6size += IFCONF_SIZE_INCREMENT * sizeof(SOCKET_ADDRESS); } closesocket(iter->socket); inet_only: iter->magic = IFITER_MAGIC; *iterp = iter; return (ISC_R_SUCCESS); ioctl6_failure: isc_mem_put(mctx, iter->buf6, iter->buf6size); ioctl_failure: if (iter->buf4 != NULL) isc_mem_put(mctx, iter->buf4, iter->buf4size); alloc_failure: if (iter->socket != INVALID_SOCKET) (void) closesocket(iter->socket); socket_failure: isc_mem_put(mctx, iter, sizeof(*iter)); return (result); } /* * Get information about the current interface to iter->current. * If successful, return ISC_R_SUCCESS. * If the interface has an unsupported address family, or if * some operation on it fails, return ISC_R_IGNORE to make * the higher-level iterator code ignore it. */ static isc_result_t internal_current(isc_interfaceiter_t *iter) { BOOL ifNamed = FALSE; unsigned long flags; REQUIRE(VALID_IFITER(iter)); REQUIRE(iter->numIF >= 0); memset(&iter->current, 0, sizeof(iter->current)); iter->current.af = AF_INET; get_addr(AF_INET, &iter->current.address, (struct sockaddr *)&(iter->IFData.iiAddress)); /* * Get interface flags. */ iter->current.flags = 0; flags = iter->IFData.iiFlags; if ((flags & IFF_UP) != 0) iter->current.flags |= INTERFACE_F_UP; if ((flags & IFF_POINTTOPOINT) != 0) { iter->current.flags |= INTERFACE_F_POINTTOPOINT; sprintf(iter->current.name, "PPP Interface %d", iter->numIF); ifNamed = TRUE; } if ((flags & IFF_LOOPBACK) != 0) { iter->current.flags |= INTERFACE_F_LOOPBACK; sprintf(iter->current.name, "Loopback Interface %d", iter->numIF); ifNamed = TRUE; } /* * If the interface is point-to-point, get the destination address. */ if ((iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) { get_addr(AF_INET, &iter->current.dstaddress, (struct sockaddr *)&(iter->IFData.iiBroadcastAddress)); } if (ifNamed == FALSE) sprintf(iter->current.name, "TCP/IP Interface %d", iter->numIF); /* * Get the network mask. */ get_addr(AF_INET, &iter->current.netmask, (struct sockaddr *)&(iter->IFData.iiNetmask)); return (ISC_R_SUCCESS); } static isc_result_t internal_current6(isc_interfaceiter_t *iter) { BOOL ifNamed = FALSE; int i; REQUIRE(VALID_IFITER(iter)); REQUIRE(iter->pos6 >= 0); REQUIRE(iter->buf6 != 0); memset(&iter->current, 0, sizeof(iter->current)); iter->current.af = AF_INET6; get_addr(AF_INET6, &iter->current.address, iter->buf6->Address[iter->pos6].lpSockaddr); /* * Get interface flags. */ iter->current.flags = INTERFACE_F_UP; if (ifNamed == FALSE) sprintf(iter->current.name, "TCP/IPv6 Interface %d", iter->pos6 + 1); for (i = 0; i< 16; i++) iter->current.netmask.type.in6.s6_addr[i] = 0xff; iter->current.netmask.family = AF_INET6; return (ISC_R_SUCCESS); } /* * Step the iterator to the next interface. Unlike * isc_interfaceiter_next(), this may leave the iterator * positioned on an interface that will ultimately * be ignored. Return ISC_R_NOMORE if there are no more * interfaces, otherwise ISC_R_SUCCESS. */ static isc_result_t internal_next(isc_interfaceiter_t *iter) { if (iter->numIF >= iter->v4IF) return (ISC_R_NOMORE); /* * The first one needs to be set up to point to the last * Element of the array. Go to the end and back up * Microsoft's implementation is peculiar for returning * the list in reverse order */ if (iter->numIF == 0) iter->pos4 = (INTERFACE_INFO *)(iter->buf4 + (iter->v4IF)); iter->pos4--; if (&(iter->pos4) < &(iter->buf4)) return (ISC_R_NOMORE); memset(&(iter->IFData), 0, sizeof(INTERFACE_INFO)); memmove(&(iter->IFData), iter->pos4, sizeof(INTERFACE_INFO)); iter->numIF++; return (ISC_R_SUCCESS); } static isc_result_t internal_next6(isc_interfaceiter_t *iter) { if (iter->pos6 == 0) return (ISC_R_NOMORE); iter->pos6--; return (ISC_R_SUCCESS); } isc_result_t isc_interfaceiter_current(isc_interfaceiter_t *iter, isc_interface_t *ifdata) { REQUIRE(iter->result == ISC_R_SUCCESS); memmove(ifdata, &iter->current, sizeof(*ifdata)); return (ISC_R_SUCCESS); } isc_result_t isc_interfaceiter_first(isc_interfaceiter_t *iter) { REQUIRE(VALID_IFITER(iter)); if (iter->buf6 != NULL) iter->pos6 = iter->buf6->iAddressCount; iter->result = ISC_R_SUCCESS; return (isc_interfaceiter_next(iter)); } isc_result_t isc_interfaceiter_next(isc_interfaceiter_t *iter) { isc_result_t result; REQUIRE(VALID_IFITER(iter)); REQUIRE(iter->result == ISC_R_SUCCESS); for (;;) { result = internal_next(iter); if (result == ISC_R_NOMORE) { result = internal_next6(iter); if (result != ISC_R_SUCCESS) break; result = internal_current6(iter); if (result != ISC_R_IGNORE) break; } else if (result != ISC_R_SUCCESS) break; result = internal_current(iter); if (result != ISC_R_IGNORE) break; } iter->result = result; return (result); } void isc_interfaceiter_destroy(isc_interfaceiter_t **iterp) { isc_interfaceiter_t *iter; REQUIRE(iterp != NULL); iter = *iterp; REQUIRE(VALID_IFITER(iter)); if (iter->buf4 != NULL) isc_mem_put(iter->mctx, iter->buf4, iter->buf4size); if (iter->buf6 != NULL) isc_mem_put(iter->mctx, iter->buf6, iter->buf6size); iter->magic = 0; isc_mem_put(iter->mctx, iter, sizeof(*iter)); *iterp = NULL; } bind9-9.10.3.dfsg.P4/lib/isc/win32/condition.c0000644000470500017500000001421412664710322020013 0ustar lamontlamont/* * Copyright (C) 2004, 2006, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: condition.c,v 1.23 2007/06/18 23:47:49 tbox Exp $ */ #include #include #include #include #include #include #define LSIGNAL 0 #define LBROADCAST 1 isc_result_t isc_condition_init(isc_condition_t *cond) { HANDLE h; REQUIRE(cond != NULL); cond->waiters = 0; /* * This handle is shared across all threads */ h = CreateEvent(NULL, FALSE, FALSE, NULL); if (h == NULL) { /* XXX */ return (ISC_R_UNEXPECTED); } cond->events[LSIGNAL] = h; /* * The threadlist will hold the actual events needed * for the wait condition */ ISC_LIST_INIT(cond->threadlist); return (ISC_R_SUCCESS); } /* * Add the thread to the threadlist along with the required events */ static isc_result_t register_thread(unsigned long thrd, isc_condition_t *gblcond, isc_condition_thread_t **localcond) { HANDLE hc; isc_condition_thread_t *newthread; REQUIRE(localcond != NULL && *localcond == NULL); newthread = malloc(sizeof(isc_condition_thread_t)); if (newthread == NULL) return (ISC_R_NOMEMORY); /* * Create the thread-specific handle */ hc = CreateEvent(NULL, FALSE, FALSE, NULL); if (hc == NULL) { free(newthread); return (ISC_R_UNEXPECTED); } /* * Add the thread ID and handles to list of threads for broadcast */ newthread->handle[LSIGNAL] = gblcond->events[LSIGNAL]; newthread->handle[LBROADCAST] = hc; newthread->th = thrd; /* * The thread is holding the manager lock so this is safe */ ISC_LIST_APPEND(gblcond->threadlist, newthread, link); *localcond = newthread; return (ISC_R_SUCCESS); } static isc_result_t find_thread_condition(unsigned long thrd, isc_condition_t *cond, isc_condition_thread_t **threadcondp) { isc_condition_thread_t *threadcond; REQUIRE(threadcondp != NULL && *threadcondp == NULL); /* * Look for the thread ID. */ for (threadcond = ISC_LIST_HEAD(cond->threadlist); threadcond != NULL; threadcond = ISC_LIST_NEXT(threadcond, link)) { if (threadcond->th == thrd) { *threadcondp = threadcond; return (ISC_R_SUCCESS); } } /* * Not found, so add it. */ return (register_thread(thrd, cond, threadcondp)); } isc_result_t isc_condition_signal(isc_condition_t *cond) { /* * Unlike pthreads, the caller MUST hold the lock associated with * the condition variable when calling us. */ REQUIRE(cond != NULL); if (!SetEvent(cond->events[LSIGNAL])) { /* XXX */ return (ISC_R_UNEXPECTED); } return (ISC_R_SUCCESS); } isc_result_t isc_condition_broadcast(isc_condition_t *cond) { isc_condition_thread_t *threadcond; isc_boolean_t failed = ISC_FALSE; /* * Unlike pthreads, the caller MUST hold the lock associated with * the condition variable when calling us. */ REQUIRE(cond != NULL); /* * Notify every thread registered for this */ for (threadcond = ISC_LIST_HEAD(cond->threadlist); threadcond != NULL; threadcond = ISC_LIST_NEXT(threadcond, link)) { if (!SetEvent(threadcond->handle[LBROADCAST])) failed = ISC_TRUE; } if (failed) return (ISC_R_UNEXPECTED); return (ISC_R_SUCCESS); } isc_result_t isc_condition_destroy(isc_condition_t *cond) { isc_condition_thread_t *next, *threadcond; REQUIRE(cond != NULL); REQUIRE(cond->waiters == 0); (void)CloseHandle(cond->events[LSIGNAL]); /* * Delete the threadlist */ threadcond = ISC_LIST_HEAD(cond->threadlist); while (threadcond != NULL) { next = ISC_LIST_NEXT(threadcond, link); DEQUEUE(cond->threadlist, threadcond, link); (void) CloseHandle(threadcond->handle[LBROADCAST]); free(threadcond); threadcond = next; } return (ISC_R_SUCCESS); } /* * This is always called when the mutex (lock) is held, but because * we are waiting we need to release it and reacquire it as soon as the wait * is over. This allows other threads to make use of the object guarded * by the mutex but it should never try to delete it as long as the * number of waiters > 0. Always reacquire the mutex regardless of the * result of the wait. Note that EnterCriticalSection will wait to acquire * the mutex. */ static isc_result_t wait(isc_condition_t *cond, isc_mutex_t *mutex, DWORD milliseconds) { DWORD result; isc_result_t tresult; isc_condition_thread_t *threadcond = NULL; /* * Get the thread events needed for the wait */ tresult = find_thread_condition(isc_thread_self(), cond, &threadcond); if (tresult != ISC_R_SUCCESS) return (tresult); cond->waiters++; LeaveCriticalSection(mutex); result = WaitForMultipleObjects(2, threadcond->handle, FALSE, milliseconds); EnterCriticalSection(mutex); cond->waiters--; if (result == WAIT_FAILED) { /* XXX */ return (ISC_R_UNEXPECTED); } if (result == WAIT_TIMEOUT) return (ISC_R_TIMEDOUT); return (ISC_R_SUCCESS); } isc_result_t isc_condition_wait(isc_condition_t *cond, isc_mutex_t *mutex) { return (wait(cond, mutex, INFINITE)); } isc_result_t isc_condition_waituntil(isc_condition_t *cond, isc_mutex_t *mutex, isc_time_t *t) { DWORD milliseconds; isc_uint64_t microseconds; isc_time_t now; if (isc_time_now(&now) != ISC_R_SUCCESS) { /* XXX */ return (ISC_R_UNEXPECTED); } microseconds = isc_time_microdiff(t, &now); if (microseconds > 0xFFFFFFFFi64 * 1000) milliseconds = 0xFFFFFFFF; else milliseconds = (DWORD)(microseconds / 1000); return (wait(cond, mutex, milliseconds)); } bind9-9.10.3.dfsg.P4/lib/isc/win32/stdtime.c0000644000470500017500000000226512664710322017501 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: stdtime.c,v 1.12 2007/06/19 23:47:19 tbox Exp $ */ #include #include #include #include #include void isc_stdtime_get(isc_stdtime_t *t) { /* * Set 't' to the number of seconds past 00:00:00 UTC, January 1, 1970. */ REQUIRE(t != NULL); (void)_time32(t); } bind9-9.10.3.dfsg.P4/lib/isc/win32/errno2result.c0000644000470500017500000000652212664710322020476 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2008, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: errno2result.c,v 1.17 2008/09/12 04:46:25 marka Exp $ */ #include #include #include "errno2result.h" #include #include #include /* * Convert a POSIX errno value into an isc_result_t. The * list of supported errno values is not complete; new users * of this function should add any expected errors that are * not already there. */ isc_result_t isc__errno2resultx(int posixerrno, const char *file, int line) { char strbuf[ISC_STRERRORSIZE]; switch (posixerrno) { case ENOTDIR: case WSAELOOP: case WSAEINVAL: case EINVAL: /* XXX sometimes this is not for files */ case ENAMETOOLONG: case WSAENAMETOOLONG: case EBADF: case WSAEBADF: return (ISC_R_INVALIDFILE); case ENOENT: return (ISC_R_FILENOTFOUND); case EACCES: case WSAEACCES: case EPERM: return (ISC_R_NOPERM); case EEXIST: return (ISC_R_FILEEXISTS); case EIO: return (ISC_R_IOERROR); case ENOMEM: return (ISC_R_NOMEMORY); #ifdef EOVERFLOW case EOVERFLOW: return (ISC_R_RANGE); #endif case ENFILE: case EMFILE: case WSAEMFILE: return (ISC_R_TOOMANYOPENFILES); case ERROR_CANCELLED: return (ISC_R_CANCELED); case ERROR_CONNECTION_REFUSED: case WSAECONNREFUSED: return (ISC_R_CONNREFUSED); case WSAENOTCONN: case ERROR_CONNECTION_INVALID: return (ISC_R_NOTCONNECTED); case ERROR_HOST_UNREACHABLE: case WSAEHOSTUNREACH: return (ISC_R_HOSTUNREACH); case ERROR_NETWORK_UNREACHABLE: case WSAENETUNREACH: return (ISC_R_NETUNREACH); case ERROR_NO_NETWORK: return (ISC_R_NETUNREACH); case ERROR_PORT_UNREACHABLE: return (ISC_R_HOSTUNREACH); case ERROR_SEM_TIMEOUT: return (ISC_R_TIMEDOUT); case WSAECONNRESET: case WSAENETRESET: case WSAECONNABORTED: case WSAEDISCON: case ERROR_OPERATION_ABORTED: case ERROR_CONNECTION_ABORTED: case ERROR_REQUEST_ABORTED: return (ISC_R_CONNECTIONRESET); case WSAEADDRNOTAVAIL: return (ISC_R_ADDRNOTAVAIL); case ERROR_NETNAME_DELETED: case WSAENETDOWN: return (ISC_R_NETUNREACH); case WSAEHOSTDOWN: return (ISC_R_HOSTUNREACH); case WSAENOBUFS: return (ISC_R_NORESOURCES); default: isc__strerror(posixerrno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(file, line, "unable to convert errno " "to isc_result: %d: %s", posixerrno, strbuf); /* * XXXDCL would be nice if perhaps this function could * return the system's error string, so the caller * might have something more descriptive than "unexpected * error" to log with. */ return (ISC_R_UNEXPECTED); } } bind9-9.10.3.dfsg.P4/lib/isc/win32/pk11_api.c0000644000470500017500000004050012664710322017427 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ /* missing code for WIN32 */ #include #include #include #include #include #include #include #include #include #include #include #define HAVE_GETPASSPHRASE char * getpassphrase(const char *prompt) { static char buf[128]; HANDLE h; DWORD cc, mode; int cnt; h = GetStdHandle(STD_INPUT_HANDLE); fputs(prompt, stderr); fflush(stderr); fflush(stdout); FlushConsoleInputBuffer(h); GetConsoleMode(h, &mode); SetConsoleMode(h, ENABLE_PROCESSED_INPUT); for (cnt = 0; cnt < sizeof(buf) - 1; cnt++) { ReadFile(h, buf + cnt, 1, &cc, NULL); if (buf[cnt] == '\r') break; fputc('*', stdout); fflush(stderr); fflush(stdout); } SetConsoleMode(h, mode); buf[cnt] = '\0'; fputs("\n", stderr); return (buf); } /* load PKCS11 DLL */ static HINSTANCE hPK11 = NULL; CK_RV pkcs_C_Initialize(CK_VOID_PTR pReserved) { CK_C_Initialize sym; const char *lib_name = pk11_get_lib_name(); if (hPK11 != NULL) return (CKR_LIBRARY_ALREADY_INITIALIZED); if (lib_name == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); /* Visual Studio convertion issue... */ if (*lib_name == ' ') lib_name++; hPK11 = LoadLibraryA(lib_name); if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); sym = (CK_C_Initialize)GetProcAddress(hPK11, "C_Initialize"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(pReserved); } CK_RV pkcs_C_Finalize(CK_VOID_PTR pReserved) { CK_C_Finalize sym; CK_RV rv; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); sym = (CK_C_Finalize)GetProcAddress(hPK11, "C_Finalize"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); rv = (*sym)(pReserved); if ((rv == CKR_OK) && (FreeLibrary(hPK11) == 0)) return (CKR_LIBRARY_FAILED_TO_LOAD); hPK11 = NULL; return (rv); } CK_RV pkcs_C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) { static CK_C_GetSlotList sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_GetSlotList)GetProcAddress(hPK11, "C_GetSlotList"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(tokenPresent, pSlotList, pulCount); } CK_RV pkcs_C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) { static CK_C_GetTokenInfo sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_GetTokenInfo)GetProcAddress(hPK11, "C_GetTokenInfo"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(slotID, pInfo); } CK_RV pkcs_C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo) { static CK_C_GetMechanismInfo sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_GetMechanismInfo)GetProcAddress(hPK11, "C_GetMechanismInfo"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(slotID, type, pInfo); } CK_RV pkcs_C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_RV (*Notify) (CK_SESSION_HANDLE hSession, CK_NOTIFICATION event, CK_VOID_PTR pApplication), CK_SESSION_HANDLE_PTR phSession) { static CK_C_OpenSession sym = NULL; if (hPK11 == NULL) hPK11 = LoadLibraryA(pk11_get_lib_name()); if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_OpenSession)GetProcAddress(hPK11, "C_OpenSession"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(slotID, flags, pApplication, Notify, phSession); } CK_RV pkcs_C_CloseSession(CK_SESSION_HANDLE hSession) { static CK_C_CloseSession sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_CloseSession)GetProcAddress(hPK11, "C_CloseSession"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession); } CK_RV pkcs_C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG usPinLen) { static CK_C_Login sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_Login)GetProcAddress(hPK11, "C_Login"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, userType, pPin, usPinLen); } CK_RV pkcs_C_Logout(CK_SESSION_HANDLE hSession) { static CK_C_Logout sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_Logout)GetProcAddress(hPK11, "C_Logout"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession); } CK_RV pkcs_C_CreateObject(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount, CK_OBJECT_HANDLE_PTR phObject) { static CK_C_CreateObject sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_CreateObject)GetProcAddress(hPK11, "C_CreateObject"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pTemplate, usCount, phObject); } CK_RV pkcs_C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) { static CK_C_DestroyObject sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_DestroyObject)GetProcAddress(hPK11, "C_DestroyObject"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, hObject); } CK_RV pkcs_C_GetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount) { static CK_C_GetAttributeValue sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_GetAttributeValue)GetProcAddress(hPK11, "C_GetAttributeValue"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, hObject, pTemplate, usCount); } CK_RV pkcs_C_SetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount) { static CK_C_SetAttributeValue sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_SetAttributeValue)GetProcAddress(hPK11, "C_SetAttributeValue"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, hObject, pTemplate, usCount); } CK_RV pkcs_C_FindObjectsInit(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount) { static CK_C_FindObjectsInit sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_FindObjectsInit)GetProcAddress(hPK11, "C_FindObjectsInit"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pTemplate, usCount); } CK_RV pkcs_C_FindObjects(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG usMaxObjectCount, CK_ULONG_PTR pusObjectCount) { static CK_C_FindObjects sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_FindObjects)GetProcAddress(hPK11, "C_FindObjects"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, phObject, usMaxObjectCount, pusObjectCount); } CK_RV pkcs_C_FindObjectsFinal(CK_SESSION_HANDLE hSession) { static CK_C_FindObjectsFinal sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_FindObjectsFinal)GetProcAddress(hPK11, "C_FindObjectsFinal"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession); } CK_RV pkcs_C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { static CK_C_EncryptInit sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_EncryptInit)GetProcAddress(hPK11, "C_EncryptInit"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pMechanism, hKey); } CK_RV pkcs_C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen) { static CK_C_Encrypt sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_Encrypt)GetProcAddress(hPK11, "C_Encrypt"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pData, ulDataLen, pEncryptedData, pulEncryptedDataLen); } CK_RV pkcs_C_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism) { static CK_C_DigestInit sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_DigestInit)GetProcAddress(hPK11, "C_DigestInit"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pMechanism); } CK_RV pkcs_C_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) { static CK_C_DigestUpdate sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_DigestUpdate)GetProcAddress(hPK11, "C_DigestUpdate"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pPart, ulPartLen); } CK_RV pkcs_C_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen) { static CK_C_DigestFinal sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_DigestFinal)GetProcAddress(hPK11, "C_DigestFinal"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pDigest, pulDigestLen); } CK_RV pkcs_C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { static CK_C_SignInit sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_SignInit)GetProcAddress(hPK11, "C_SignInit"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pMechanism, hKey); } CK_RV pkcs_C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) { static CK_C_Sign sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_Sign)GetProcAddress(hPK11, "C_Sign"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pData, ulDataLen, pSignature, pulSignatureLen); } CK_RV pkcs_C_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) { static CK_C_SignUpdate sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_SignUpdate)GetProcAddress(hPK11, "C_SignUpdate"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pPart, ulPartLen); } CK_RV pkcs_C_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) { static CK_C_SignFinal sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_SignFinal)GetProcAddress(hPK11, "C_SignFinal"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pSignature, pulSignatureLen); } CK_RV pkcs_C_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { static CK_C_VerifyInit sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_VerifyInit)GetProcAddress(hPK11, "C_VerifyInit"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pMechanism, hKey); } CK_RV pkcs_C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) { static CK_C_Verify sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_Verify)GetProcAddress(hPK11, "C_Verify"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pData, ulDataLen, pSignature, ulSignatureLen); } CK_RV pkcs_C_VerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) { static CK_C_VerifyUpdate sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_VerifyUpdate)GetProcAddress(hPK11, "C_VerifyUpdate"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pPart, ulPartLen); } CK_RV pkcs_C_VerifyFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) { static CK_C_VerifyFinal sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_VerifyFinal)GetProcAddress(hPK11, "C_VerifyFinal"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pSignature, ulSignatureLen); } CK_RV pkcs_C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey) { static CK_C_GenerateKey sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_GenerateKey)GetProcAddress(hPK11, "C_GenerateKey"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pMechanism, pTemplate, ulCount, phKey); } CK_RV pkcs_C_GenerateKeyPair(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG usPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG usPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPrivateKey, CK_OBJECT_HANDLE_PTR phPublicKey) { static CK_C_GenerateKeyPair sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_GenerateKeyPair)GetProcAddress(hPK11, "C_GenerateKeyPair"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pMechanism, pPublicKeyTemplate, usPublicKeyAttributeCount, pPrivateKeyTemplate, usPrivateKeyAttributeCount, phPrivateKey, phPublicKey); } CK_RV pkcs_C_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) { static CK_C_DeriveKey sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_DeriveKey)GetProcAddress(hPK11, "C_DeriveKey"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pMechanism, hBaseKey, pTemplate, ulAttributeCount, phKey); } CK_RV pkcs_C_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen) { static CK_C_SeedRandom sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_SeedRandom)GetProcAddress(hPK11, "C_SeedRandom"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, pSeed, ulSeedLen); } CK_RV pkcs_C_GenerateRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR RandomData, CK_ULONG ulRandomLen) { static CK_C_GenerateRandom sym = NULL; if (hPK11 == NULL) return (CKR_LIBRARY_FAILED_TO_LOAD); if (sym == NULL) sym = (CK_C_GenerateRandom)GetProcAddress(hPK11, "C_GenerateRandom"); if (sym == NULL) return (CKR_SYMBOL_RESOLUTION_FAILED); return (*sym)(hSession, RandomData, ulRandomLen); } bind9-9.10.3.dfsg.P4/lib/isc/win32/DLLMain.c0000644000470500017500000000313312664710322017243 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: DLLMain.c,v 1.7 2007/06/18 23:47:49 tbox Exp $ */ #include #include /* * Called when we enter the DLL */ __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { /* * The DLL is loading due to process * initialization or a call to LoadLibrary. */ case DLL_PROCESS_ATTACH: break; /* The attached process creates a new thread. */ case DLL_THREAD_ATTACH: break; /* The thread of the attached process terminates. */ case DLL_THREAD_DETACH: break; /* * The DLL is unloading from a process due to * process termination or a call to FreeLibrary. */ case DLL_PROCESS_DETACH: break; default: break; } return (TRUE); } bind9-9.10.3.dfsg.P4/lib/isc/win32/libisc.vcxproj.user0000644000470500017500000000021712664710322021516 0ustar lamontlamont bind9-9.10.3.dfsg.P4/lib/isc/win32/ntgroups.c0000644000470500017500000001173512664710322017713 0ustar lamontlamont/* * Copyright (C) 2004, 2006, 2007, 2009, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ntgroups.c,v 1.12 2009/09/29 23:48:04 tbox Exp $ */ /* * The NT Groups have two groups that are not well documented and are * not normally seen: None and Everyone. A user account belongs to * any number of groups, but if it is not a member of any group then * it is a member of the None Group. The None group is not listed * anywhere. You cannot remove an account from the none group except * by making it a member of some other group, The second group is the * Everyone group. All accounts, no matter how many groups that they * belong to, also belong to the Everyone group. You cannot remove an * account from the Everyone group. */ #ifndef UNICODE #define UNICODE #endif /* UNICODE */ /* * Silence warnings. */ #define _CRT_SECURE_NO_DEPRECATE 1 #include #include #include #include #include #define MAX_NAME_LENGTH 256 isc_result_t isc_ntsecurity_getaccountgroups(char *username, char **GroupList, unsigned int maxgroups, unsigned int *totalGroups) { LPGROUP_USERS_INFO_0 pTmpBuf; LPLOCALGROUP_USERS_INFO_0 pTmpLBuf; DWORD i; LPLOCALGROUP_USERS_INFO_0 pBuf = NULL; LPGROUP_USERS_INFO_0 pgrpBuf = NULL; DWORD dwLevel = 0; DWORD dwFlags = LG_INCLUDE_INDIRECT; DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH; DWORD dwEntriesRead = 0; DWORD dwTotalEntries = 0; NET_API_STATUS nStatus; size_t retlen; wchar_t user[MAX_NAME_LENGTH]; retlen = mbstowcs(user, username, MAX_NAME_LENGTH); *totalGroups = 0; /* * Call the NetUserGetLocalGroups function * specifying information level 0. * * The LG_INCLUDE_INDIRECT flag specifies that the * function should also return the names of the local * groups in which the user is indirectly a member. */ nStatus = NetUserGetLocalGroups(NULL, user, dwLevel, dwFlags, (LPBYTE *) &pBuf, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries); /* * See if the call succeeds, */ if (nStatus != NERR_Success) { if (nStatus == ERROR_ACCESS_DENIED) return (ISC_R_NOPERM); if (nStatus == ERROR_MORE_DATA) return (ISC_R_NOSPACE); if (nStatus == NERR_UserNotFound) dwEntriesRead = 0; } if (pBuf != NULL) { pTmpLBuf = pBuf; /* * Loop through the entries */ for (i = 0; (i < dwEntriesRead && *totalGroups < maxgroups); i++) { assert(pTmpLBuf != NULL); if (pTmpLBuf == NULL) break; retlen = wcslen(pTmpLBuf->lgrui0_name); GroupList[*totalGroups] = (char *) malloc(retlen +1); if (GroupList[*totalGroups] == NULL) return (ISC_R_NOMEMORY); retlen = wcstombs(GroupList[*totalGroups], pTmpLBuf->lgrui0_name, retlen); GroupList[*totalGroups][retlen] = '\0'; if (strcmp(GroupList[*totalGroups], "None") == 0) free(GroupList[*totalGroups]); else (*totalGroups)++; pTmpLBuf++; } } /* Free the allocated memory. */ if (pBuf != NULL) NetApiBufferFree(pBuf); /* * Call the NetUserGetGroups function, specifying level 0. */ nStatus = NetUserGetGroups(NULL, user, dwLevel, (LPBYTE*)&pgrpBuf, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries); /* * See if the call succeeds, */ if (nStatus != NERR_Success) { if (nStatus == ERROR_ACCESS_DENIED) return (ISC_R_NOPERM); if (nStatus == ERROR_MORE_DATA) return (ISC_R_NOSPACE); if (nStatus == NERR_UserNotFound) dwEntriesRead = 0; } if (pgrpBuf != NULL) { pTmpBuf = pgrpBuf; /* * Loop through the entries */ for (i = 0; (i < dwEntriesRead && *totalGroups < maxgroups); i++) { assert(pTmpBuf != NULL); if (pTmpBuf == NULL) break; retlen = wcslen(pTmpBuf->grui0_name); GroupList[*totalGroups] = (char *) malloc(retlen +1); if (GroupList[*totalGroups] == NULL) return (ISC_R_NOMEMORY); retlen = wcstombs(GroupList[*totalGroups], pTmpBuf->grui0_name, retlen); GroupList[*totalGroups][retlen] = '\0'; if (strcmp(GroupList[*totalGroups], "None") == 0) free(GroupList[*totalGroups]); else (*totalGroups)++; pTmpBuf++; } } /* * Free the allocated memory. */ if (pgrpBuf != NULL) NetApiBufferFree(pgrpBuf); return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/isc/win32/resource.c0000644000470500017500000000377212664710322017663 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: resource.c,v 1.10 2008/07/11 23:47:09 tbox Exp $ */ #include #include #include #include #include #include #include "errno2result.h" /* * Windows limits the maximum number of open files to 2048 */ #define WIN32_MAX_OPEN_FILES 2048 isc_result_t isc_resource_setlimit(isc_resource_t resource, isc_resourcevalue_t value) { isc_resourcevalue_t rlim_value; int wresult; if (resource != isc_resource_openfiles) return (ISC_R_NOTIMPLEMENTED); if (value == ISC_RESOURCE_UNLIMITED) rlim_value = WIN32_MAX_OPEN_FILES; else rlim_value = min(value, WIN32_MAX_OPEN_FILES); wresult = _setmaxstdio((int) rlim_value); if (wresult > 0) return (ISC_R_SUCCESS); else return (isc__errno2result(errno)); } isc_result_t isc_resource_getlimit(isc_resource_t resource, isc_resourcevalue_t *value) { if (resource != isc_resource_openfiles) return (ISC_R_NOTIMPLEMENTED); *value = WIN32_MAX_OPEN_FILES; return (ISC_R_SUCCESS); } isc_result_t isc_resource_getcurlimit(isc_resource_t resource, isc_resourcevalue_t *value) { return (isc_resource_getlimit(resource, value)); } bind9-9.10.3.dfsg.P4/lib/isc/win32/keyboard.c0000644000470500017500000000407112664710322017625 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: keyboard.c,v 1.7 2007/06/19 23:47:19 tbox Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include isc_result_t isc_keyboard_open(isc_keyboard_t *keyboard) { int fd; REQUIRE(keyboard != NULL); fd = _fileno(stdin); if (fd < 0) return (ISC_R_IOERROR); keyboard->fd = fd; keyboard->result = ISC_R_SUCCESS; return (ISC_R_SUCCESS); } isc_result_t isc_keyboard_close(isc_keyboard_t *keyboard, unsigned int sleeptime) { REQUIRE(keyboard != NULL); if (sleeptime > 0 && keyboard->result != ISC_R_CANCELED) (void)Sleep(sleeptime*1000); keyboard->fd = -1; return (ISC_R_SUCCESS); } isc_result_t isc_keyboard_getchar(isc_keyboard_t *keyboard, unsigned char *cp) { ssize_t cc; unsigned char c; REQUIRE(keyboard != NULL); REQUIRE(cp != NULL); cc = read(keyboard->fd, &c, 1); if (cc < 0) { keyboard->result = ISC_R_IOERROR; return (keyboard->result); } *cp = c; return (ISC_R_SUCCESS); } isc_boolean_t isc_keyboard_canceled(isc_keyboard_t *keyboard) { return (ISC_TF(keyboard->result == ISC_R_CANCELED)); } bind9-9.10.3.dfsg.P4/lib/isc/win32/syslog.h0000644000470500017500000000423312664710322017352 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001, 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: syslog.h,v 1.7 2007/06/19 23:47:19 tbox Exp $ */ #ifndef _SYSLOG_H #define _SYSLOG_H #include /* Constant definitions for openlog() */ #define LOG_PID 1 #define LOG_CONS 2 /* NT event log does not support facility level */ #define LOG_KERN 0 #define LOG_USER 0 #define LOG_MAIL 0 #define LOG_DAEMON 0 #define LOG_AUTH 0 #define LOG_SYSLOG 0 #define LOG_LPR 0 #define LOG_LOCAL0 0 #define LOG_LOCAL1 0 #define LOG_LOCAL2 0 #define LOG_LOCAL3 0 #define LOG_LOCAL4 0 #define LOG_LOCAL5 0 #define LOG_LOCAL6 0 #define LOG_LOCAL7 0 #define LOG_EMERG 0 /* system is unusable */ #define LOG_ALERT 1 /* action must be taken immediately */ #define LOG_CRIT 2 /* critical conditions */ #define LOG_ERR 3 /* error conditions */ #define LOG_WARNING 4 /* warning conditions */ #define LOG_NOTICE 5 /* normal but signification condition */ #define LOG_INFO 6 /* informational */ #define LOG_DEBUG 7 /* debug-level messages */ void syslog(int level, const char *fmt, ...); void openlog(const char *, int, ...); void closelog(void); void ModifyLogLevel(int level); void InitNTLogging(FILE *, int); void NTReportError(const char *, const char *); /* * Include the event codes required for logging. */ #include #endif bind9-9.10.3.dfsg.P4/lib/isc/win32/stdio.c0000644000470500017500000000556212664710322017155 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: stdio.c,v 1.6 2007/06/19 23:47:19 tbox Exp $ */ #include #include #include #include #include #include "errno2result.h" isc_result_t isc_stdio_open(const char *filename, const char *mode, FILE **fp) { FILE *f; f = fopen(filename, mode); if (f == NULL) return (isc__errno2result(errno)); *fp = f; return (ISC_R_SUCCESS); } isc_result_t isc_stdio_close(FILE *f) { int r; r = fclose(f); if (r == 0) return (ISC_R_SUCCESS); else return (isc__errno2result(errno)); } isc_result_t isc_stdio_seek(FILE *f, off_t offset, int whence) { int r; #ifndef _WIN64 r = fseek(f, offset, whence); #else r = _fseeki64(f, offset, whence); #endif if (r == 0) return (ISC_R_SUCCESS); else return (isc__errno2result(errno)); } isc_result_t isc_stdio_tell(FILE *f, off_t *offsetp) { #ifndef _WIN64 long r; #else __int64 r; #endif REQUIRE(offsetp != NULL); #ifndef _WIN64 r = ftell(f); #else r = _ftelli64(f); #endif if (r >= 0) { *offsetp = r; return (ISC_R_SUCCESS); } else return (isc__errno2result(errno)); } isc_result_t isc_stdio_read(void *ptr, size_t size, size_t nmemb, FILE *f, size_t *nret) { isc_result_t result = ISC_R_SUCCESS; size_t r; clearerr(f); r = fread(ptr, size, nmemb, f); if (r != nmemb) { if (feof(f)) result = ISC_R_EOF; else result = isc__errno2result(errno); } if (nret != NULL) *nret = r; return (result); } isc_result_t isc_stdio_write(const void *ptr, size_t size, size_t nmemb, FILE *f, size_t *nret) { isc_result_t result = ISC_R_SUCCESS; size_t r; clearerr(f); r = fwrite(ptr, size, nmemb, f); if (r != nmemb) result = isc__errno2result(errno); if (nret != NULL) *nret = r; return (result); } isc_result_t isc_stdio_flush(FILE *f) { int r; r = fflush(f); if (r == 0) return (ISC_R_SUCCESS); else return (isc__errno2result(errno)); } isc_result_t isc_stdio_sync(FILE *f) { int r; r = _commit(_fileno(f)); if (r == 0) return (ISC_R_SUCCESS); else return (isc__errno2result(errno)); } bind9-9.10.3.dfsg.P4/lib/isc/win32/app.c0000644000470500017500000002604012664710322016605 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: app.c,v 1.9 2009/09/02 23:48:03 tbox Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /*% * For BIND9 internal applications built with threads, we use a single app * context and let multiple worker, I/O, timer threads do actual jobs. */ static isc_thread_t blockedthread; /*% * The following are intended for internal use (indicated by "isc__" * prefix) but are not declared as static, allowing direct access from * unit tests etc. */ isc_result_t isc__app_start(void); isc_result_t isc__app_ctxstart(isc_appctx_t *ctx); isc_result_t isc__app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action, void *arg); isc_result_t isc__app_ctxrun(isc_appctx_t *ctx); isc_result_t isc__app_run(void); isc_result_t isc__app_ctxshutdown(isc_appctx_t *ctx); isc_result_t isc__app_shutdown(void); isc_result_t isc__app_reload(void); isc_result_t isc__app_ctxsuspend(isc_appctx_t *ctx); void isc__app_ctxfinish(isc_appctx_t *ctx); void isc__app_finish(void); void isc__app_block(void); void isc__app_unblock(void); isc_result_t isc__appctx_create(isc_mem_t *mctx, isc_appctx_t **ctxp); void isc__appctx_destroy(isc_appctx_t **ctxp); void isc__appctx_settaskmgr(isc_appctx_t *ctx, isc_taskmgr_t *taskmgr); void isc__appctx_setsocketmgr(isc_appctx_t *ctx, isc_socketmgr_t *socketmgr); void isc__appctx_settimermgr(isc_appctx_t *ctx, isc_timermgr_t *timermgr); isc_result_t isc__app_ctxonrun(isc_appctx_t *ctx, isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action, void *arg); /* * The application context of this module. This implementation actually * doesn't use it. (This may change in the future). */ #define APPCTX_MAGIC ISC_MAGIC('A', 'p', 'c', 'x') #define VALID_APPCTX(c) ISC_MAGIC_VALID(c, APPCTX_MAGIC) /* Events to wait for */ #define NUM_EVENTS 2 enum { RELOAD_EVENT, SHUTDOWN_EVENT }; typedef struct isc__appctx { isc_appctx_t common; isc_mem_t *mctx; isc_eventlist_t on_run; isc_mutex_t lock; isc_boolean_t shutdown_requested; isc_boolean_t running; /* * We assume that 'want_shutdown' can be read and written atomically. */ isc_boolean_t want_shutdown; /* * We assume that 'want_reload' can be read and written atomically. */ isc_boolean_t want_reload; isc_boolean_t blocked; HANDLE hEvents[NUM_EVENTS]; isc_taskmgr_t *taskmgr; isc_socketmgr_t *socketmgr; isc_timermgr_t *timermgr; } isc__appctx_t; static isc__appctx_t isc_g_appctx; static struct { isc_appmethods_t methods; /*% * The following are defined just for avoiding unused static functions. */ void *run, *shutdown, *start, *reload, *finish, *block, *unblock; } appmethods = { { isc__appctx_destroy, isc__app_ctxstart, isc__app_ctxrun, isc__app_ctxsuspend, isc__app_ctxshutdown, isc__app_ctxfinish, isc__appctx_settaskmgr, isc__appctx_setsocketmgr, isc__appctx_settimermgr, isc__app_ctxonrun }, (void *)isc__app_run, (void *)isc__app_shutdown, (void *)isc__app_start, (void *)isc__app_reload, (void *)isc__app_finish, (void *)isc__app_block, (void *)isc__app_unblock }; /* * We need to remember which thread is the main thread... */ static isc_thread_t main_thread; isc_result_t isc__app_ctxstart(isc_appctx_t *ctx0) { isc__appctx_t *ctx = (isc__appctx_t *)ctx0; isc_result_t result; REQUIRE(VALID_APPCTX(ctx)); /* * Start an ISC library application. */ main_thread = GetCurrentThread(); result = isc_mutex_init(&ctx->lock); if (result != ISC_R_SUCCESS) return (result); ctx->shutdown_requested = ISC_FALSE; ctx->running = ISC_FALSE; ctx->want_shutdown = ISC_FALSE; ctx->want_reload = ISC_FALSE; ctx->blocked = ISC_FALSE; /* Create the reload event in a non-signaled state */ ctx->hEvents[RELOAD_EVENT] = CreateEvent(NULL, FALSE, FALSE, NULL); /* Create the shutdown event in a non-signaled state */ ctx->hEvents[SHUTDOWN_EVENT] = CreateEvent(NULL, FALSE, FALSE, NULL); ISC_LIST_INIT(ctx->on_run); return (ISC_R_SUCCESS); } isc_result_t isc__app_start(void) { isc_g_appctx.common.impmagic = APPCTX_MAGIC; isc_g_appctx.common.magic = ISCAPI_APPCTX_MAGIC; isc_g_appctx.common.methods = &appmethods.methods; isc_g_appctx.mctx = NULL; /* The remaining members will be initialized in ctxstart() */ return (isc__app_ctxstart((isc_appctx_t *)&isc_g_appctx)); } isc_result_t isc__app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action, void *arg) { return (isc__app_ctxonrun((isc_appctx_t *)&isc_g_appctx, mctx, task, action, arg)); } isc_result_t isc__app_ctxonrun(isc_appctx_t *ctx0, isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action, void *arg) { isc__appctx_t *ctx = (isc__appctx_t *)ctx0; isc_event_t *event; isc_task_t *cloned_task = NULL; isc_result_t result; LOCK(&ctx->lock); if (ctx->running) { result = ISC_R_ALREADYRUNNING; goto unlock; } /* * Note that we store the task to which we're going to send the event * in the event's "sender" field. */ isc_task_attach(task, &cloned_task); event = isc_event_allocate(mctx, cloned_task, ISC_APPEVENT_SHUTDOWN, action, arg, sizeof(*event)); if (event == NULL) { result = ISC_R_NOMEMORY; goto unlock; } ISC_LIST_APPEND(ctx->on_run, event, ev_link); result = ISC_R_SUCCESS; unlock: UNLOCK(&ctx->lock); return (result); } isc_result_t isc__app_ctxrun(isc_appctx_t *ctx0) { isc__appctx_t *ctx = (isc__appctx_t *)ctx0; isc_event_t *event, *next_event; isc_task_t *task; HANDLE *pHandles = NULL; DWORD dwWaitResult; REQUIRE(VALID_APPCTX(ctx)); REQUIRE(main_thread == GetCurrentThread()); LOCK(&ctx->lock); if (!ctx->running) { ctx->running = ISC_TRUE; /* * Post any on-run events (in FIFO order). */ for (event = ISC_LIST_HEAD(ctx->on_run); event != NULL; event = next_event) { next_event = ISC_LIST_NEXT(event, ev_link); ISC_LIST_UNLINK(ctx->on_run, event, ev_link); task = event->ev_sender; event->ev_sender = NULL; isc_task_sendanddetach(&task, &event); } } UNLOCK(&ctx->lock); /* * There is no danger if isc_app_shutdown() is called before we wait * for events. */ while (!ctx->want_shutdown) { dwWaitResult = WaitForMultipleObjects(NUM_EVENTS, ctx->hEvents, FALSE, INFINITE); /* See why we returned */ if (WaitSucceeded(dwWaitResult, NUM_EVENTS)) { /* * The return was due to one of the events * being signaled */ switch (WaitSucceededIndex(dwWaitResult)) { case RELOAD_EVENT: ctx->want_reload = ISC_TRUE; break; case SHUTDOWN_EVENT: ctx->want_shutdown = ISC_TRUE; break; } } if (ctx->want_reload) { ctx->want_reload = ISC_FALSE; return (ISC_R_RELOAD); } if (ctx->want_shutdown && ctx->blocked) exit(-1); } return (ISC_R_SUCCESS); } isc_result_t isc__app_run(void) { return (isc__app_ctxrun((isc_appctx_t *)&isc_g_appctx)); } isc_result_t isc__app_ctxshutdown(isc_appctx_t *ctx0) { isc__appctx_t *ctx = (isc__appctx_t *)ctx0; isc_boolean_t want_kill = ISC_TRUE; REQUIRE(VALID_APPCTX(ctx)); LOCK(&ctx->lock); REQUIRE(ctx->running); if (ctx->shutdown_requested) want_kill = ISC_FALSE; /* We're only signaling once */ else ctx->shutdown_requested = ISC_TRUE; UNLOCK(&ctx->lock); if (want_kill) SetEvent(ctx->hEvents[SHUTDOWN_EVENT]); return (ISC_R_SUCCESS); } isc_result_t isc__app_shutdown(void) { return (isc__app_ctxshutdown((isc_appctx_t *)&isc_g_appctx)); } isc_result_t isc__app_ctxsuspend(isc_appctx_t *ctx0) { isc__appctx_t *ctx = (isc__appctx_t *)ctx0; isc_boolean_t want_kill = ISC_TRUE; REQUIRE(VALID_APPCTX(ctx)); LOCK(&ctx->lock); REQUIRE(ctx->running); /* * Don't send the reload signal if we're shutting down. */ if (ctx->shutdown_requested) want_kill = ISC_FALSE; UNLOCK(&ctx->lock); if (want_kill) SetEvent(ctx->hEvents[RELOAD_EVENT]); return (ISC_R_SUCCESS); } isc_result_t isc__app_reload(void) { return (isc__app_ctxsuspend((isc_appctx_t *)&isc_g_appctx)); } void isc__app_ctxfinish(isc_appctx_t *ctx0) { isc__appctx_t *ctx = (isc__appctx_t *)ctx0; REQUIRE(VALID_APPCTX(ctx)); DESTROYLOCK(&ctx->lock); } void isc__app_finish(void) { isc__app_ctxfinish((isc_appctx_t *)&isc_g_appctx); } void isc__app_block(void) { REQUIRE(isc_g_appctx.running); REQUIRE(!isc_g_appctx.blocked); isc_g_appctx.blocked = ISC_TRUE; blockedthread = GetCurrentThread(); } void isc__app_unblock(void) { REQUIRE(isc_g_appctx.running); REQUIRE(isc_g_appctx.blocked); isc_g_appctx.blocked = ISC_FALSE; REQUIRE(blockedthread == GetCurrentThread()); } isc_result_t isc__appctx_create(isc_mem_t *mctx, isc_appctx_t **ctxp) { isc__appctx_t *ctx; REQUIRE(mctx != NULL); REQUIRE(ctxp != NULL && *ctxp == NULL); ctx = isc_mem_get(mctx, sizeof(*ctx)); if (ctx == NULL) return (ISC_R_NOMEMORY); ctx->common.impmagic = APPCTX_MAGIC; ctx->common.magic = ISCAPI_APPCTX_MAGIC; ctx->common.methods = &appmethods.methods; ctx->mctx = NULL; isc_mem_attach(mctx, &ctx->mctx); ctx->taskmgr = NULL; ctx->socketmgr = NULL; ctx->timermgr = NULL; *ctxp = (isc_appctx_t *)ctx; return (ISC_R_SUCCESS); } void isc__appctx_destroy(isc_appctx_t **ctxp) { isc__appctx_t *ctx; REQUIRE(ctxp != NULL); ctx = (isc__appctx_t *)*ctxp; REQUIRE(VALID_APPCTX(ctx)); isc_mem_putanddetach(&ctx->mctx, ctx, sizeof(*ctx)); *ctxp = NULL; } void isc__appctx_settaskmgr(isc_appctx_t *ctx0, isc_taskmgr_t *taskmgr) { isc__appctx_t *ctx = (isc__appctx_t *)ctx0; REQUIRE(VALID_APPCTX(ctx)); ctx->taskmgr = taskmgr; } void isc__appctx_setsocketmgr(isc_appctx_t *ctx0, isc_socketmgr_t *socketmgr) { isc__appctx_t *ctx = (isc__appctx_t *)ctx0; REQUIRE(VALID_APPCTX(ctx)); ctx->socketmgr = socketmgr; } void isc__appctx_settimermgr(isc_appctx_t *ctx0, isc_timermgr_t *timermgr) { isc__appctx_t *ctx = (isc__appctx_t *)ctx0; REQUIRE(VALID_APPCTX(ctx)); ctx->timermgr = timermgr; } isc_result_t isc__app_register(void) { return (isc_app_register(isc__appctx_create)); } #include "../app_api.c" bind9-9.10.3.dfsg.P4/lib/isc/win32/include/0002755000470500017500000000000012672612753017314 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/win32/include/Makefile.in0000644000470500017500000000177212664710322021356 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1999-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.9 2007/06/19 23:47:19 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = isc pkcs11 TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/pkcs11/0002755000470500017500000000000012664710322020406 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/win32/include/pkcs11/cryptoki.h0000644000470500017500000000410712664710322022423 0ustar lamontlamont/* cryptoki.h include file for PKCS #11. */ /* $Revision: 1.2 $ */ /* License to copy and use this software is granted provided that it is * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface * (Cryptoki)" in all material mentioning or referencing this software. * License is also granted to make and use derivative works provided that * such works are identified as "derived from the RSA Security Inc. PKCS #11 * Cryptographic Token Interface (Cryptoki)" in all material mentioning or * referencing the derived work. * RSA Security Inc. makes no representations concerning either the * merchantability of this software or the suitability of this software for * any particular purpose. It is provided "as is" without express or implied * warranty of any kind. */ /* This is a sample file containing the top level include directives * for building Win32 Cryptoki libraries and applications. */ #ifndef ___CRYPTOKI_H_INC___ #define ___CRYPTOKI_H_INC___ #pragma pack(push, cryptoki, 1) /* Specifies that the function is a DLL entry point. */ #define CK_IMPORT_SPEC __declspec(dllimport) /* Define CRYPTOKI_EXPORTS during the build of cryptoki libraries. Do * not define it in applications. */ #ifdef CRYPTOKI_EXPORTS /* Specified that the function is an exported DLL entry point. */ #define CK_EXPORT_SPEC __declspec(dllexport) #else #define CK_EXPORT_SPEC CK_IMPORT_SPEC #endif /* Ensures the calling convention for Win32 builds */ #define CK_CALL_SPEC __cdecl #define CK_PTR * #define CK_DEFINE_FUNCTION(returnType, name) \ returnType CK_EXPORT_SPEC CK_CALL_SPEC name #define CK_DECLARE_FUNCTION(returnType, name) \ returnType CK_EXPORT_SPEC CK_CALL_SPEC name #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ returnType CK_IMPORT_SPEC (CK_CALL_SPEC CK_PTR name) #define CK_CALLBACK_FUNCTION(returnType, name) \ returnType (CK_CALL_SPEC CK_PTR name) #ifndef NULL_PTR #define NULL_PTR 0 #endif #include #pragma pack(pop, cryptoki) #endif /* ___CRYPTOKI_H_INC___ */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/pkcs11/Makefile.in0000644000470500017500000000212612664710322022452 0ustar lamontlamont# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id$ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ HEADERS = cryptoki.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/pkcs11 install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/pkcs11 ; \ done bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/0002755000470500017500000000000012672612753020072 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/bindevt.h0000644000470500017500000000426712664710322021675 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: bindevt.h,v 1.6 2007/06/19 23:47:20 tbox Exp $ */ #ifndef ISC_BINDEVT_H #define ISC_BINDEVT_H 1 /* * This is used for the event log for both logging the messages and * later on by the event viewer when looking at the events */ /* * Values are 32 bit values layed out as follows: * * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 * +---+-+-+-----------------------+-------------------------------+ * |Sev|C|R| Facility | Code | * +---+-+-+-----------------------+-------------------------------+ * * where * * Sev - is the severity code * * 00 - Success * 01 - Informational * 10 - Warning * 11 - Error * * C - is the Customer code flag * * R - is a reserved bit * * Facility - is the facility code * * Code - is the facility's status code * * * Define the facility codes */ /* * Define the severity codes */ /* * MessageId: BIND_ERR_MSG * * MessageText: * * %1 */ #define BIND_ERR_MSG ((DWORD)0xC0000001L) /* * MessageId: BIND_WARN_MSG * * MessageText: * * %1 */ #define BIND_WARN_MSG ((DWORD)0x80000002L) /* * MessageId: BIND_INFO_MSG * * MessageText: * * %1 */ #define BIND_INFO_MSG ((DWORD)0x40000003L) #endif /* ISC_BINDEVT_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/ntpaths.h0000644000470500017500000000366412664710322021723 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ntpaths.h,v 1.20 2009/07/14 22:54:57 each Exp $ */ /* * Windows-specific path definitions * These routines are used to set up and return system-specific path * information about the files enumerated in NtPaths */ #ifndef ISC_NTPATHS_H #define ISC_NTPATHS_H #include /* * Index of paths needed */ enum NtPaths { NAMED_CONF_PATH, LWRES_CONF_PATH, RESOLV_CONF_PATH, RNDC_CONF_PATH, NAMED_PID_PATH, LWRESD_PID_PATH, LOCAL_STATE_DIR, SYS_CONF_DIR, RNDC_KEY_PATH, SESSION_KEY_PATH }; /* * Define macros to get the path of the config files */ #define NAMED_CONFFILE isc_ntpaths_get(NAMED_CONF_PATH) #define RNDC_CONFFILE isc_ntpaths_get(RNDC_CONF_PATH) #define RNDC_KEYFILE isc_ntpaths_get(RNDC_KEY_PATH) #define SESSION_KEYFILE isc_ntpaths_get(SESSION_KEY_PATH) #define RESOLV_CONF isc_ntpaths_get(RESOLV_CONF_PATH) /* * Information about where the files are on disk */ #define NS_LOCALSTATEDIR "/dns/bin" #define NS_SYSCONFDIR "/dns/etc" ISC_LANG_BEGINDECLS void isc_ntpaths_init(void); char * isc_ntpaths_get(int); ISC_LANG_ENDDECLS #endif /* ISC_NTPATHS_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/int.h0000644000470500017500000000351212664710322021024 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: int.h,v 1.13 2007/06/19 23:47:20 tbox Exp $ */ #ifndef ISC_INT_H #define ISC_INT_H 1 #define _INTEGRAL_MAX_BITS 64 #include typedef __int8 isc_int8_t; typedef unsigned __int8 isc_uint8_t; typedef __int16 isc_int16_t; typedef unsigned __int16 isc_uint16_t; typedef __int32 isc_int32_t; typedef unsigned __int32 isc_uint32_t; typedef __int64 isc_int64_t; typedef unsigned __int64 isc_uint64_t; #define ISC_INT8_MIN -128 #define ISC_INT8_MAX 127 #define ISC_UINT8_MAX 255 #define ISC_INT16_MIN -32768 #define ISC_INT16_MAX 32767 #define ISC_UINT16_MAX 65535 /* * Note that "int" is 32 bits on all currently supported Unix-like operating * systems, but "long" can be either 32 bits or 64 bits, thus the 32 bit * constants are not qualified with "L". */ #define ISC_INT32_MIN _I32_MIN #define ISC_INT32_MAX _I32_MAX #define ISC_UINT32_MAX _UI32_MAX #define ISC_INT64_MIN _I64_MIN #define ISC_INT64_MAX _I64_MAX #define ISC_UINT64_MAX _UI64_MAX #endif /* ISC_INT_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/once.h0000644000470500017500000000243512664710322021161 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: once.h,v 1.9 2007/06/19 23:47:20 tbox Exp $ */ #ifndef ISC_ONCE_H #define ISC_ONCE_H 1 #include #include ISC_LANG_BEGINDECLS typedef struct { int status; int counter; } isc_once_t; #define ISC_ONCE_INIT_NEEDED 0 #define ISC_ONCE_INIT_DONE 1 #define ISC_ONCE_INIT { ISC_ONCE_INIT_NEEDED, 1 } isc_result_t isc_once_do(isc_once_t *controller, void(*function)(void)); ISC_LANG_ENDDECLS #endif /* ISC_ONCE_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/platform.h.in0000644000470500017500000000772112664710322022471 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007-2009, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: platform.h,v 1.19 2009/09/29 23:48:04 tbox Exp $ */ #ifndef ISC_PLATFORM_H #define ISC_PLATFORM_H 1 /***** ***** Platform-dependent defines. *****/ #define ISC_PLATFORM_USETHREADS 1 /*** *** Network. ***/ #define ISC_PLATFORM_HAVEIPV6 #if _MSC_VER > 1200 #define ISC_PLATFORM_HAVEIN6PKTINFO #endif #define ISC_PLATFORM_HAVESCOPEID #define ISC_PLATFORM_NEEDPORTT #undef MSG_TRUNC #define ISC_PLATFORM_NEEDNTOP #define ISC_PLATFORM_NEEDPTON #define ISC_PLATFORM_HAVESOCKADDRSTORAGE #define ISC_PLATFORM_QUADFORMAT "I64" #define ISC_PLATFORM_NEEDSTRSEP #define ISC_PLATFORM_NEEDSTRLCPY #define ISC_PLATFORM_NEEDSTRLCAT #define ISC_PLATFORM_NEEDSTRLCPY /* * Used to control how extern data is linked; needed for Win32 platforms. */ #define ISC_PLATFORM_USEDECLSPEC 1 /* * Define this here for now as winsock2.h defines h_errno * and we don't want to redeclare it. */ #define ISC_PLATFORM_NONSTDHERRNO /* * Define if the platform has . */ #undef ISC_PLATFORM_HAVESYSUNH /* * Define if we want to log backtrace */ @ISC_PLATFORM_USEBACKTRACE@ /* * Defines for the noreturn attribute. */ #define ISC_PLATFORM_NORETURN_PRE __declspec(noreturn) #define ISC_PLATFORM_NORETURN_POST /* * Define if the hash functions must be provided by OpenSSL. */ @ISC_PLATFORM_OPENSSLHASH@ /* * Define if AES support is wanted */ @ISC_PLATFORM_WANTAES@ /* * If the "xadd" operation is available on this architecture, * ISC_PLATFORM_HAVEXADD will be defined. */ @ISC_PLATFORM_HAVEXADD@ /* * If the "xaddq" operation (64bit xadd) is available on this architecture, * ISC_PLATFORM_HAVEXADDQ will be defined. */ @ISC_PLATFORM_HAVEXADDQ@ /* * If the "atomic swap" operation is available on this architecture, * ISC_PLATFORM_HAVEATOMICSTORE" will be defined. */ @ISC_PLATFORM_HAVEATOMICSTORE@ /* * If the "compare-and-exchange" operation is available on this architecture, * ISC_PLATFORM_HAVECMPXCHG will be defined. */ @ISC_PLATFORM_HAVECMPXCHG@ /* * If the strcasestr() operation is not available on this platform, * ISC_PLATFORM_NEEDSTRCASESTR will be defined. */ @ISC_PLATFORM_NEEDSTRCASESTR@ /* * Defined if we are enabling SIT (Source Identity Token). */ @ISC_PLATFORM_USESIT@ /* * Set up a macro for importing and exporting from the DLL */ #ifdef LIBISC_EXPORTS #define LIBISC_EXTERNAL_DATA __declspec(dllexport) #else #define LIBISC_EXTERNAL_DATA __declspec(dllimport) #endif #ifdef LIBDNS_EXPORTS #define LIBDNS_EXTERNAL_DATA __declspec(dllexport) #else #define LIBDNS_EXTERNAL_DATA __declspec(dllimport) #endif #ifdef LIBISCCC_EXPORTS #define LIBISCCC_EXTERNAL_DATA __declspec(dllexport) #else #define LIBISCCC_EXTERNAL_DATA __declspec(dllimport) #endif #ifdef LIBISCCFG_EXPORTS #define LIBISCCFG_EXTERNAL_DATA __declspec(dllexport) #else #define LIBISCCFG_EXTERNAL_DATA __declspec(dllimport) #endif #ifdef LIBBIND9_EXPORTS #define LIBBIND9_EXTERNAL_DATA __declspec(dllexport) #else #define LIBBIND9_EXTERNAL_DATA __declspec(dllimport) #endif #ifdef LIBTESTS_EXPORTS #define LIBTESTS_EXTERNAL_DATA __declspec(dllexport) #else #define LIBTESTS_EXTERNAL_DATA __declspec(dllimport) #endif #endif /* ISC_PLATFORM_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/Makefile.in0000644000470500017500000000244212664710322022127 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012-2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1999-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.11 2007/06/19 23:47:20 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ HEADERS = dir.h int.h keyboard.h mutex.h net.h netdb.h once.h \ stat.h stdtime.h thread.h time.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}\isc install:: installdirs for i in $(HEADERS); do \ $(INSTALL_DATA) $(srcdir)\$$i $(includedir)\isc ; \ done bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/dir.h0000644000470500017500000000411712664710322021012 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: dir.h,v 1.15 2007/06/19 23:47:20 tbox Exp $ */ /* Principal Authors: DCL */ #ifndef ISC_DIR_H #define ISC_DIR_H 1 #include #include #include #include #include #define ISC_DIR_NAMEMAX _MAX_FNAME #define ISC_DIR_PATHMAX _MAX_PATH typedef struct { char name[ISC_DIR_NAMEMAX]; unsigned int length; WIN32_FIND_DATA find_data; } isc_direntry_t; typedef struct { unsigned int magic; char dirname[ISC_DIR_PATHMAX]; isc_direntry_t entry; isc_boolean_t entry_filled; HANDLE search_handle; } isc_dir_t; ISC_LANG_BEGINDECLS void isc_dir_init(isc_dir_t *dir); isc_result_t isc_dir_open(isc_dir_t *dir, const char *dirname); isc_result_t isc_dir_read(isc_dir_t *dir); isc_result_t isc_dir_reset(isc_dir_t *dir); void isc_dir_close(isc_dir_t *dir); isc_result_t isc_dir_chdir(const char *dirname); isc_result_t isc_dir_chroot(const char *dirname); isc_result_t isc_dir_createunique(char *templet); /* * Use a templet (such as from isc_file_mktemplate()) to create a uniquely * named, empty directory. The templet string is modified in place. * If result == ISC_R_SUCCESS, it is the name of the directory that was * created. */ ISC_LANG_ENDDECLS #endif /* ISC_DIR_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/condition.h0000644000470500017500000000347412664710322022227 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: condition.h,v 1.17 2007/06/18 23:47:49 tbox Exp $ */ #ifndef ISC_CONDITION_H #define ISC_CONDITION_H 1 #include #include #include #include #include typedef struct isc_condition_thread isc_condition_thread_t; struct isc_condition_thread { unsigned long th; HANDLE handle[2]; ISC_LINK(isc_condition_thread_t) link; }; typedef struct isc_condition { HANDLE events[2]; unsigned int waiters; ISC_LIST(isc_condition_thread_t) threadlist; } isc_condition_t; ISC_LANG_BEGINDECLS isc_result_t isc_condition_init(isc_condition_t *); isc_result_t isc_condition_wait(isc_condition_t *, isc_mutex_t *); isc_result_t isc_condition_signal(isc_condition_t *); isc_result_t isc_condition_broadcast(isc_condition_t *); isc_result_t isc_condition_destroy(isc_condition_t *); isc_result_t isc_condition_waituntil(isc_condition_t *, isc_mutex_t *, isc_time_t *); ISC_LANG_ENDDECLS #endif /* ISC_CONDITION_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/ntgroups.h0000644000470500017500000000226112664710322022113 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ntgroups.h,v 1.5 2007/06/19 23:47:20 tbox Exp $ */ #ifndef ISC_NTGROUPS_H #define ISC_NTGROUPS_H 1 #include #include ISC_LANG_BEGINDECLS isc_result_t isc_ntsecurity_getaccountgroups(char *name, char **Groups, unsigned int maxgroups, unsigned int *total); ISC_LANG_ENDDECLS #endif /* ISC_NTGROUPS_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/offset.h0000644000470500017500000000343012664710322021517 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: offset.h,v 1.6 2007/06/19 23:47:20 tbox Exp $ */ #ifndef ISC_OFFSET_H #define ISC_OFFSET_H 1 /* * File offsets are operating-system dependent. */ #include /* Required for CHAR_BIT. */ #include typedef _off_t isc_offset_t; /* * POSIX says "Additionally, blkcnt_t and off_t are extended signed integral * types", so the maximum value is all 1s except for the high bit. * This definition is more complex than it really needs to be because it was * crafted to keep both the SunOS 5.6 and the HP/UX 11 compilers quiet about * integer overflow. For example, though this is equivalent to just left * shifting 1 to the high bit and then inverting the bits, the SunOS compiler * is unhappy about shifting a positive "1" to negative in a signed integer. */ #define ISC_OFFSET_MAXIMUM \ (~(((off_t)-1 >> (sizeof(off_t) * CHAR_BIT - 1)) \ << (sizeof(off_t) * CHAR_BIT - 1))) #endif /* ISC_OFFSET_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/mutex.h0000644000470500017500000000352012664710322021373 0ustar lamontlamont/* * Copyright (C) 2004, 2007-2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: mutex.h,v 1.22 2009/01/18 23:48:14 tbox Exp $ */ #ifndef ISC_MUTEX_H #define ISC_MUTEX_H 1 #include #include #include typedef CRITICAL_SECTION isc_mutex_t; /* * This definition is here since some versions of WINBASE.H * omits it for some reason. */ #if (_WIN32_WINNT < 0x0400) WINBASEAPI BOOL WINAPI TryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection); #endif /* _WIN32_WINNT < 0x0400 */ #define isc_mutex_init(mp) \ (InitializeCriticalSection((mp)), ISC_R_SUCCESS) #define isc_mutex_lock(mp) \ (EnterCriticalSection((mp)), ISC_R_SUCCESS) #define isc_mutex_unlock(mp) \ (LeaveCriticalSection((mp)), ISC_R_SUCCESS) #define isc_mutex_trylock(mp) \ (TryEnterCriticalSection((mp)) ? ISC_R_SUCCESS : ISC_R_LOCKBUSY) #define isc_mutex_destroy(mp) \ (DeleteCriticalSection((mp)), ISC_R_SUCCESS) /* * This is a placeholder for now since we are not keeping any mutex stats */ #define isc_mutex_stats(fp) do {} while (0) #endif /* ISC_MUTEX_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/atomic.h0000644000470500017500000000413112664710322021504 0ustar lamontlamont/* * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef ISC_ATOMIC_H #define ISC_ATOMIC_H 1 #include #include #include /* * This routine atomically increments the value stored in 'p' by 'val', and * returns the previous value. */ #ifdef ISC_PLATFORM_HAVEXADD static __inline isc_int32_t isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) { return (isc_int32_t) _InterlockedExchangeAdd((long *)p, (long)val); } #endif #ifdef ISC_PLATFORM_HAVEXADDQ static __inline isc_int64_t isc_atomic_xaddq(isc_int64_t *p, isc_int64_t val) { return (isc_int64_t) _InterlockedExchangeAdd64((__int64 *)p, (__int64) val); } #endif /* * This routine atomically stores the value 'val' in 'p'. */ #ifdef ISC_PLATFORM_HAVEATOMICSTORE static __inline void isc_atomic_store(isc_int32_t *p, isc_int32_t val) { (void) _InterlockedExchange((long *)p, (long)val); } #endif /* * This routine atomically replaces the value in 'p' with 'val', if the * original value is equal to 'cmpval'. The original value is returned in any * case. */ #ifdef ISC_PLATFORM_HAVECMPXCHG static __inline isc_int32_t isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) { /* beware: swap arguments */ return (isc_int32_t) _InterlockedCompareExchange((long *)p, (long)val, (long)cmpval); } #endif #endif /* ISC_ATOMIC_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/bind_registry.h0000644000470500017500000000341712664710322023102 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: bind_registry.h,v 1.8 2007/06/19 23:47:20 tbox Exp $ */ #ifndef ISC_BINDREGISTRY_H #define ISC_BINDREGISTRY_H /* * BIND makes use of the following Registry keys in various places, especially * during startup and installation */ #define BIND_SUBKEY "Software\\ISC\\BIND" #define BIND_SESSION "CurrentSession" #define BIND_SESSION_SUBKEY "Software\\ISC\\BIND\\CurrentSession" #define BIND_UNINSTALL_SUBKEY \ "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ISC BIND" #define EVENTLOG_APP_SUBKEY \ "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application" #define BIND_MESSAGE_SUBKEY \ "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\named" #define BIND_MESSAGE_NAME "named" #define BIND_SERVICE_SUBKEY \ "SYSTEM\\CurrentControlSet\\Services\\named" #define BIND_CONFIGFILE 0 #define BIND_DEBUGLEVEL 1 #define BIND_QUERYLOG 2 #define BIND_FOREGROUND 3 #define BIND_PORT 4 #endif /* ISC_BINDREGISTRY_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/win32os.h0000644000470500017500000000304612664710322021540 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: win32os.h,v 1.7 2009/06/25 23:48:02 tbox Exp $ */ #ifndef ISC_WIN32OS_H #define ISC_WIN32OS_H 1 #include ISC_LANG_BEGINDECLS /* * Return the number of CPUs available on the system, or 1 if this cannot * be determined. */ int isc_win32os_versioncheck(unsigned int major, unsigned int minor, unsigned int updatemajor, unsigned int updateminor); /* * Checks the current version of the operating system with the * supplied version information. * Returns: * -1 if less than the version information supplied * 0 if equal to all of the version information supplied * +1 if greater than the version information supplied */ ISC_LANG_ENDDECLS #endif /* ISC_WIN32OS_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/ipv6.h0000644000470500017500000000575012664710322021124 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef ISC_IPV6_H #define ISC_IPV6_H 1 /***** ***** Module Info *****/ /* * IPv6 definitions for systems which do not support IPv6. * * MP: * No impact. * * Reliability: * No anticipated impact. * * Resources: * N/A. * * Security: * No anticipated impact. * * Standards: * RFC2553. */ #if _MSC_VER < 1300 #define in6_addr in_addr6 #endif #ifndef IN6ADDR_ANY_INIT #define IN6ADDR_ANY_INIT {{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }} #endif #ifndef IN6ADDR_LOOPBACK_INIT #define IN6ADDR_LOOPBACK_INIT {{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }} #endif LIBISC_EXTERNAL_DATA extern const struct in6_addr isc_in6addr_any; LIBISC_EXTERNAL_DATA extern const struct in6_addr isc_in6addr_loopback; /* * Unspecified */ #ifndef IN6_IS_ADDR_UNSPECIFIED #define IN6_IS_ADDR_UNSPECIFIED(a) (\ *((u_long *)((a)->s6_addr) ) == 0 && \ *((u_long *)((a)->s6_addr) + 1) == 0 && \ *((u_long *)((a)->s6_addr) + 2) == 0 && \ *((u_long *)((a)->s6_addr) + 3) == 0 \ ) #endif /* * Loopback */ #ifndef IN6_IS_ADDR_LOOPBACK #define IN6_IS_ADDR_LOOPBACK(a) (\ *((u_long *)((a)->s6_addr) ) == 0 && \ *((u_long *)((a)->s6_addr) + 1) == 0 && \ *((u_long *)((a)->s6_addr) + 2) == 0 && \ *((u_long *)((a)->s6_addr) + 3) == htonl(1) \ ) #endif /* * IPv4 compatible */ #define IN6_IS_ADDR_V4COMPAT(a) (\ *((u_long *)((a)->s6_addr) ) == 0 && \ *((u_long *)((a)->s6_addr) + 1) == 0 && \ *((u_long *)((a)->s6_addr) + 2) == 0 && \ *((u_long *)((a)->s6_addr) + 3) != 0 && \ *((u_long *)((a)->s6_addr) + 3) != htonl(1) \ ) /* * Mapped */ #define IN6_IS_ADDR_V4MAPPED(a) (\ *((u_long *)((a)->s6_addr) ) == 0 && \ *((u_long *)((a)->s6_addr) + 1) == 0 && \ *((u_long *)((a)->s6_addr) + 2) == htonl(0x0000ffff)) /* * Multicast */ #define IN6_IS_ADDR_MULTICAST(a) \ ((a)->s6_addr[0] == 0xffU) /* * Unicast link / site local. */ #ifndef IN6_IS_ADDR_LINKLOCAL #define IN6_IS_ADDR_LINKLOCAL(a) (\ ((a)->s6_addr[0] == 0xfe) && \ (((a)->s6_addr[1] & 0xc0) == 0x80)) #endif #ifndef IN6_IS_ADDR_SITELOCAL #define IN6_IS_ADDR_SITELOCAL(a) (\ ((a)->s6_addr[0] == 0xfe) && \ (((a)->s6_addr[1] & 0xc0) == 0xc0)) #endif #endif /* ISC_IPV6_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/syslog.h0000644000470500017500000000247112664710322021555 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: syslog.h,v 1.5 2007/06/19 23:47:20 tbox Exp $ */ #ifndef ISC_SYSLOG_H #define ISC_SYSLOG_H 1 #include #include ISC_LANG_BEGINDECLS isc_result_t isc_syslog_facilityfromstring(const char *str, int *facilityp); /* * Convert 'str' to the appropriate syslog facility constant. * * Requires: * * 'str' is not NULL * 'facilityp' is not NULL * * Returns: * ISC_R_SUCCESS * ISC_R_NOTFOUND */ ISC_LANG_ENDDECLS #endif /* ISC_SYSLOG_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/net.h0000644000470500017500000002361512664710322021026 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2008, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef ISC_NET_H #define ISC_NET_H 1 /* * Also define LWRES_IPV6_H to keep it from being included if liblwres is * being used, or redefinition errors will occur. */ #define LWRES_IPV6_H 1 /***** ***** Module Info *****/ /* * Basic Networking Types * * This module is responsible for defining the following basic networking * types: * * struct in_addr * struct in6_addr * struct in6_pktinfo * struct sockaddr * struct sockaddr_in * struct sockaddr_in6 * in_port_t * * It ensures that the AF_ and PF_ macros are defined. * * It declares ntoh[sl]() and hton[sl](). * * It declares inet_aton(), inet_ntop(), and inet_pton(). * * It ensures that INADDR_ANY, IN6ADDR_ANY_INIT, in6addr_any, and * in6addr_loopback are available. * * It ensures that IN_MULTICAST() is available to check for multicast * addresses. * * MP: * No impact. * * Reliability: * No anticipated impact. * * Resources: * N/A. * * Security: * No anticipated impact. * * Standards: * BSD Socket API * RFC2553 */ /*** *** Imports. ***/ #include /* * Because of some sort of problem in the MS header files, this cannot * be simple "#include ", because winsock2.h tries to include * windows.h, which then generates an error out of mswsock.h. _You_ * figure it out. */ #ifndef _WINSOCKAPI_ #define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */ #endif #include #include #include #include #include #include /* * This is here because named client, interfacemgr.c, etc. use the name as * a variable */ #undef interface #ifndef INADDR_LOOPBACK #define INADDR_LOOPBACK 0x7f000001UL #endif #ifndef ISC_PLATFORM_HAVEIN6PKTINFO struct in6_pktinfo { struct in6_addr ipi6_addr; /* src/dst IPv6 address */ unsigned int ipi6_ifindex; /* send/recv interface index */ }; #endif #if _MSC_VER < 1300 #define in6addr_any isc_in6addr_any #define in6addr_loopback isc_in6addr_loopback #endif /* * Ensure type in_port_t is defined. */ #ifdef ISC_PLATFORM_NEEDPORTT typedef isc_uint16_t in_port_t; #endif /* * If this system does not have MSG_TRUNC (as returned from recvmsg()) * ISC_PLATFORM_RECVOVERFLOW will be defined. This will enable the MSG_TRUNC * faking code in socket.c. */ #ifndef MSG_TRUNC #define ISC_PLATFORM_RECVOVERFLOW #endif #define ISC__IPADDR(x) ((isc_uint32_t)htonl((isc_uint32_t)(x))) #define ISC_IPADDR_ISMULTICAST(i) \ (((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \ == ISC__IPADDR(0xe0000000)) #define ISC_IPADDR_ISEXPERIMENTAL(i) \ (((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \ == ISC__IPADDR(0xf0000000)) /* * Fix the FD_SET and FD_CLR Macros to properly cast */ #undef FD_CLR #define FD_CLR(fd, set) do { \ u_int __i; \ for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { \ if (((fd_set FAR *)(set))->fd_array[__i] == (SOCKET) fd) { \ while (__i < ((fd_set FAR *)(set))->fd_count-1) { \ ((fd_set FAR *)(set))->fd_array[__i] = \ ((fd_set FAR *)(set))->fd_array[__i+1]; \ __i++; \ } \ ((fd_set FAR *)(set))->fd_count--; \ break; \ } \ } \ } while (0) #undef FD_SET #define FD_SET(fd, set) do { \ u_int __i; \ for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { \ if (((fd_set FAR *)(set))->fd_array[__i] == (SOCKET)(fd)) { \ break; \ } \ } \ if (__i == ((fd_set FAR *)(set))->fd_count) { \ if (((fd_set FAR *)(set))->fd_count < FD_SETSIZE) { \ ((fd_set FAR *)(set))->fd_array[__i] = (SOCKET)(fd); \ ((fd_set FAR *)(set))->fd_count++; \ } \ } \ } while (0) /* * Windows Sockets errors redefined as regular Berkeley error constants. * These are usually commented out in Windows NT to avoid conflicts with errno.h. * Use the WSA constants instead. */ #include #ifndef EWOULDBLOCK #define EWOULDBLOCK WSAEWOULDBLOCK #endif #ifndef EINPROGRESS #define EINPROGRESS WSAEINPROGRESS #endif #ifndef EALREADY #define EALREADY WSAEALREADY #endif #ifndef ENOTSOCK #define ENOTSOCK WSAENOTSOCK #endif #ifndef EDESTADDRREQ #define EDESTADDRREQ WSAEDESTADDRREQ #endif #ifndef EMSGSIZE #define EMSGSIZE WSAEMSGSIZE #endif #ifndef EPROTOTYPE #define EPROTOTYPE WSAEPROTOTYPE #endif #ifndef ENOPROTOOPT #define ENOPROTOOPT WSAENOPROTOOPT #endif #ifndef EPROTONOSUPPORT #define EPROTONOSUPPORT WSAEPROTONOSUPPORT #endif #ifndef ESOCKTNOSUPPORT #define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT #endif #ifndef EOPNOTSUPP #define EOPNOTSUPP WSAEOPNOTSUPP #endif #ifndef EPFNOSUPPORT #define EPFNOSUPPORT WSAEPFNOSUPPORT #endif #ifndef EAFNOSUPPORT #define EAFNOSUPPORT WSAEAFNOSUPPORT #endif #ifndef EADDRINUSE #define EADDRINUSE WSAEADDRINUSE #endif #ifndef EADDRNOTAVAIL #define EADDRNOTAVAIL WSAEADDRNOTAVAIL #endif #ifndef ENETDOWN #define ENETDOWN WSAENETDOWN #endif #ifndef ENETUNREACH #define ENETUNREACH WSAENETUNREACH #endif #ifndef ENETRESET #define ENETRESET WSAENETRESET #endif #ifndef ECONNABORTED #define ECONNABORTED WSAECONNABORTED #endif #ifndef ECONNRESET #define ECONNRESET WSAECONNRESET #endif #ifndef ENOBUFS #define ENOBUFS WSAENOBUFS #endif #ifndef EISCONN #define EISCONN WSAEISCONN #endif #ifndef ENOTCONN #define ENOTCONN WSAENOTCONN #endif #ifndef ESHUTDOWN #define ESHUTDOWN WSAESHUTDOWN #endif #ifndef ETOOMANYREFS #define ETOOMANYREFS WSAETOOMANYREFS #endif #ifndef ETIMEDOUT #define ETIMEDOUT WSAETIMEDOUT #endif #ifndef ECONNREFUSED #define ECONNREFUSED WSAECONNREFUSED #endif #ifndef ELOOP #define ELOOP WSAELOOP #endif #ifndef EHOSTDOWN #define EHOSTDOWN WSAEHOSTDOWN #endif #ifndef EHOSTUNREACH #define EHOSTUNREACH WSAEHOSTUNREACH #endif #ifndef EPROCLIM #define EPROCLIM WSAEPROCLIM #endif #ifndef EUSERS #define EUSERS WSAEUSERS #endif #ifndef EDQUOT #define EDQUOT WSAEDQUOT #endif #ifndef ESTALE #define ESTALE WSAESTALE #endif #ifndef EREMOTE #define EREMOTE WSAEREMOTE #endif /*** *** Functions. ***/ ISC_LANG_BEGINDECLS isc_result_t isc_net_probeipv4(void); /* * Check if the system's kernel supports IPv4. * * Returns: * * ISC_R_SUCCESS IPv4 is supported. * ISC_R_NOTFOUND IPv4 is not supported. * ISC_R_DISABLED IPv4 is disabled. * ISC_R_UNEXPECTED */ isc_result_t isc_net_probeipv6(void); /* * Check if the system's kernel supports IPv6. * * Returns: * * ISC_R_SUCCESS IPv6 is supported. * ISC_R_NOTFOUND IPv6 is not supported. * ISC_R_DISABLED IPv6 is disabled. * ISC_R_UNEXPECTED */ isc_result_t isc_net_probeunix(void); /* * Check if UNIX domain sockets are supported. * * Returns: * * ISC_R_SUCCESS * ISC_R_NOTFOUND */ #define ISC_NET_DSCPRECVV4 0x01 /* Can receive sent DSCP value IPv4 */ #define ISC_NET_DSCPRECVV6 0x02 /* Can receive sent DSCP value IPv6 */ #define ISC_NET_DSCPSETV4 0x04 /* Can set DSCP on socket IPv4 */ #define ISC_NET_DSCPSETV6 0x08 /* Can set DSCP on socket IPv6 */ #define ISC_NET_DSCPPKTV4 0x10 /* Can set DSCP on per packet IPv4 */ #define ISC_NET_DSCPPKTV6 0x20 /* Can set DSCP on per packet IPv6 */ #define ISC_NET_DSCPALL 0x3f /* All valid flags */ unsigned int isc_net_probedscp(void); /*%< * Probe the level of DSCP support. */ isc_result_t isc_net_probe_ipv6only(void); /* * Check if the system's kernel supports the IPV6_V6ONLY socket option. * * Returns: * * ISC_R_SUCCESS the option is supported for both TCP and UDP. * ISC_R_NOTFOUND IPv6 itself or the option is not supported. * ISC_R_UNEXPECTED */ isc_result_t isc_net_probe_ipv6pktinfo(void); /* * Check if the system's kernel supports the IPV6_(RECV)PKTINFO socket option * for UDP sockets. * * Returns: * * ISC_R_SUCCESS the option is supported. * ISC_R_NOTFOUND IPv6 itself or the option is not supported. * ISC_R_UNEXPECTED */ void isc_net_disableipv4(void); void isc_net_disableipv6(void); void isc_net_enableipv4(void); void isc_net_enableipv6(void); isc_result_t isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high); /*%< * Returns system's default range of ephemeral UDP ports, if defined. * If the range is not available or unknown, ISC_NET_PORTRANGELOW and * ISC_NET_PORTRANGEHIGH will be returned. * * Requires: * *\li 'low' and 'high' must be non NULL. * * Returns: * *\li *low and *high will be the ports specifying the low and high ends of * the range. */ #ifdef ISC_PLATFORM_NEEDNTOP const char * isc_net_ntop(int af, const void *src, char *dst, size_t size); #define inet_ntop isc_net_ntop #endif #ifdef ISC_PLATFORM_NEEDPTON int isc_net_pton(int af, const char *src, void *dst); #define inet_pton isc_net_pton #endif int isc_net_aton(const char *cp, struct in_addr *addr); #define inet_aton isc_net_aton ISC_LANG_ENDDECLS #endif /* ISC_NET_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/strerror.h0000644000470500017500000000235212664710322022115 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: strerror.h,v 1.5 2007/06/19 23:47:20 tbox Exp $ */ #ifndef ISC_STRERROR_H #define ISC_STRERROR_H #include #include ISC_LANG_BEGINDECLS #define ISC_STRERRORSIZE 128 /* * Provide a thread safe wrapper to strerrror(). * * Requires: * 'buf' to be non NULL. */ void isc__strerror(int num, char *buf, size_t bufsize); ISC_LANG_ENDDECLS #endif /* ISC_STRERROR_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/stdtime.h0000644000470500017500000000341712664710322021707 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef ISC_STDTIME_H #define ISC_STDTIME_H 1 #include #include /* * It's public information that 'isc_stdtime_t' is an unsigned integral type. * Applications that want maximum portability should not assume anything * about its size. */ typedef isc_uint32_t isc_stdtime_t; /* but this flag helps... */ #define STDTIME_ON_32BITS 1 /* * isc_stdtime32_t is a 32-bit version of isc_stdtime_t. A variable of this * type should only be used as an opaque integer (e.g.,) to compare two * time values. */ typedef isc_uint32_t isc_stdtime32_t; ISC_LANG_BEGINDECLS void isc_stdtime_get(isc_stdtime_t *t); /* * Set 't' to the number of seconds since 00:00:00 UTC, January 1, 1970. * * Requires: * * 't' is a valid pointer. */ #define isc_stdtime_convert32(t, t32p) (*(t32p) = t) /* * Convert the standard time to its 32-bit version. */ ISC_LANG_ENDDECLS #endif /* ISC_STDTIME_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/time.h0000644000470500017500000002047012664710322021172 0ustar lamontlamont/* * Copyright (C) 2004, 2006-2009, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: time.h,v 1.35 2009/01/05 23:47:54 tbox Exp $ */ #ifndef ISC_TIME_H #define ISC_TIME_H 1 #include #include #include /*** *** Intervals ***/ /* * The contents of this structure are private, and MUST NOT be accessed * directly by callers. * * The contents are exposed only to allow callers to avoid dynamic allocation. */ struct isc_interval { isc_int64_t interval; }; LIBISC_EXTERNAL_DATA extern const isc_interval_t * const isc_interval_zero; /* * ISC_FORMATHTTPTIMESTAMP_SIZE needs to be 30 in C locale and potentially * more for other locales to handle longer national abbreviations when * expanding strftime's %a and %b. */ #define ISC_FORMATHTTPTIMESTAMP_SIZE 50 ISC_LANG_BEGINDECLS void isc_interval_set(isc_interval_t *i, unsigned int seconds, unsigned int nanoseconds); /* * Set 'i' to a value representing an interval of 'seconds' seconds and * 'nanoseconds' nanoseconds, suitable for use in isc_time_add() and * isc_time_subtract(). * * Requires: * * 't' is a valid pointer. * nanoseconds < 1000000000. */ isc_boolean_t isc_interval_iszero(const isc_interval_t *i); /* * Returns ISC_TRUE iff. 'i' is the zero interval. * * Requires: * * 'i' is a valid pointer. */ /*** *** Absolute Times ***/ /* * The contents of this structure are private, and MUST NOT be accessed * directly by callers. * * The contents are exposed only to allow callers to avoid dynamic allocation. */ struct isc_time { FILETIME absolute; }; LIBISC_EXTERNAL_DATA extern const isc_time_t * const isc_time_epoch; void isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds); /*%< * Set 't' to a value which represents the given number of seconds and * nanoseconds since 00:00:00 January 1, 1970, UTC. * * Requires: *\li 't' is a valid pointer. *\li nanoseconds < 1000000000. */ void isc_time_settoepoch(isc_time_t *t); /* * Set 't' to the time of the epoch. * * Notes: * The date of the epoch is platform-dependent. * * Requires: * * 't' is a valid pointer. */ isc_boolean_t isc_time_isepoch(const isc_time_t *t); /* * Returns ISC_TRUE iff. 't' is the epoch ("time zero"). * * Requires: * * 't' is a valid pointer. */ isc_result_t isc_time_now(isc_time_t *t); /* * Set 't' to the current absolute time. * * Requires: * * 't' is a valid pointer. * * Returns: * * Success * Unexpected error * Getting the time from the system failed. * Out of range * The time from the system is too large to be represented * in the current definition of isc_time_t. */ isc_result_t isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i); /* * Set *t to the current absolute time + i. * * Note: * This call is equivalent to: * * isc_time_now(t); * isc_time_add(t, i, t); * * Requires: * * 't' and 'i' are valid pointers. * * Returns: * * Success * Unexpected error * Getting the time from the system failed. * Out of range * The interval added to the time from the system is too large to * be represented in the current definition of isc_time_t. */ int isc_time_compare(const isc_time_t *t1, const isc_time_t *t2); /* * Compare the times referenced by 't1' and 't2' * * Requires: * * 't1' and 't2' are valid pointers. * * Returns: * * -1 t1 < t2 (comparing times, not pointers) * 0 t1 = t2 * 1 t1 > t2 */ isc_result_t isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result); /* * Add 'i' to 't', storing the result in 'result'. * * Requires: * * 't', 'i', and 'result' are valid pointers. * * Returns: * Success * Out of range * The interval added to the time is too large to * be represented in the current definition of isc_time_t. */ isc_result_t isc_time_subtract(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result); /* * Subtract 'i' from 't', storing the result in 'result'. * * Requires: * * 't', 'i', and 'result' are valid pointers. * * Returns: * Success * Out of range * The interval is larger than the time since the epoch. */ isc_uint64_t isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2); /* * Find the difference in milliseconds between time t1 and time t2. * t2 is the subtrahend of t1; ie, difference = t1 - t2. * * Requires: * * 't1' and 't2' are valid pointers. * * Returns: * The difference of t1 - t2, or 0 if t1 <= t2. */ isc_result_t isc_time_parsehttptimestamp(char *input, isc_time_t *t); /*%< * Parse the time in 'input' into the isc_time_t pointed to by 't', * expecting a format like "Mon, 30 Aug 2000 04:06:47 GMT" * * Requires: *\li 'buf' and 't' are not NULL. */ isc_uint32_t isc_time_nanoseconds(const isc_time_t *t); /* * Return the number of nanoseconds stored in a time structure. * * Notes: * This is the number of nanoseconds in excess of the number * of seconds since the epoch; it will always be less than one * full second. * * Requires: * 't' is a valid pointer. * * Ensures: * The returned value is less than 1*10^9. */ void isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len); /* * Format the time 't' into the buffer 'buf' of length 'len', * using a format like "30-Aug-2000 04:06:47.997" and the local time zone. * If the text does not fit in the buffer, the result is indeterminate, * but is always guaranteed to be null terminated. * * Requires: * 'len' > 0 * 'buf' points to an array of at least len chars * */ void isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len); /* * Format the time 't' into the buffer 'buf' of length 'len', * using a format like "Mon, 30 Aug 2000 04:06:47 GMT" * If the text does not fit in the buffer, the result is indeterminate, * but is always guaranteed to be null terminated. * * Requires: * 'len' > 0 * 'buf' points to an array of at least len chars * */ isc_result_t isc_time_parsehttptimestamp(char *input, isc_time_t *t); /*%< * Parse the time in 'input' into the isc_time_t pointed to by 't', * expecting a format like "Mon, 30 Aug 2000 04:06:47 GMT" * * Requires: *\li 'buf' and 't' are not NULL. */ void isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len); /*%< * Format the time 't' into the buffer 'buf' of length 'len', * using the ISO8601 format: "yyyy-mm-ddThh:mm:ssZ" * If the text does not fit in the buffer, the result is indeterminate, * but is always guaranteed to be null terminated. * * Requires: *\li 'len' > 0 *\li 'buf' points to an array of at least len chars * */ isc_uint32_t isc_time_seconds(const isc_time_t *t); /*%< * Return the number of seconds since the epoch stored in a time structure. * * Requires: * *\li 't' is a valid pointer. */ isc_result_t isc_time_secondsastimet(const isc_time_t *t, time_t *secondsp); /*%< * Ensure the number of seconds in an isc_time_t is representable by a time_t. * * Notes: *\li The number of seconds stored in an isc_time_t might be larger * than the number of seconds a time_t is able to handle. Since * time_t is mostly opaque according to the ANSI/ISO standard * (essentially, all you can be sure of is that it is an arithmetic type, * not even necessarily integral), it can be tricky to ensure that * the isc_time_t is in the range a time_t can handle. Use this * function in place of isc_time_seconds() any time you need to set a * time_t from an isc_time_t. * * Requires: *\li 't' is a valid pointer. * * Returns: *\li Success *\li Out of range */ ISC_LANG_ENDDECLS #endif /* ISC_TIME_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/netdb.h0000644000470500017500000000246512664710322021334 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: netdb.h,v 1.9 2007/06/19 23:47:20 tbox Exp $ */ #ifndef ISC_NETDB_H #define ISC_NETDB_H 1 /***** ***** Module Info *****/ /* * Portable netdb.h support. * * This module is responsible for defining the getby APIs. * * MP: * No impact. * * Reliability: * No anticipated impact. * * Resources: * N/A. * * Security: * No anticipated impact. * * Standards: * BSD API */ /*** *** Imports. ***/ #include #endif /* ISC_NETDB_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/keyboard.h0000644000470500017500000000263712664710322022041 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: keyboard.h,v 1.6 2007/06/19 23:47:20 tbox Exp $ */ #ifndef ISC_KEYBOARD_H #define ISC_KEYBOARD_H 1 #include #include ISC_LANG_BEGINDECLS typedef struct { int fd; isc_result_t result; } isc_keyboard_t; isc_result_t isc_keyboard_open(isc_keyboard_t *keyboard); isc_result_t isc_keyboard_close(isc_keyboard_t *keyboard, unsigned int sleepseconds); isc_result_t isc_keyboard_getchar(isc_keyboard_t *keyboard, unsigned char *cp); isc_boolean_t isc_keyboard_canceled(isc_keyboard_t *keyboard); ISC_LANG_ENDDECLS #endif /* ISC_KEYBOARD_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/thread.h0000644000470500017500000000552312664710322021505 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: thread.h,v 1.25 2009/09/29 04:37:08 marka Exp $ */ #ifndef ISC_THREAD_H #define ISC_THREAD_H 1 #include #include #include /* * Inlines to help with wait return checking */ /* check handle for NULL and INVALID_HANDLE */ inline BOOL IsValidHandle( HANDLE hHandle) { return ((hHandle != NULL) && (hHandle != INVALID_HANDLE_VALUE)); } /* validate wait return codes... */ inline BOOL WaitSucceeded( DWORD dwWaitResult, DWORD dwHandleCount) { return ((dwWaitResult >= WAIT_OBJECT_0) && (dwWaitResult < WAIT_OBJECT_0 + dwHandleCount)); } inline BOOL WaitAbandoned( DWORD dwWaitResult, DWORD dwHandleCount) { return ((dwWaitResult >= WAIT_ABANDONED_0) && (dwWaitResult < WAIT_ABANDONED_0 + dwHandleCount)); } inline BOOL WaitTimeout( DWORD dwWaitResult) { return (dwWaitResult == WAIT_TIMEOUT); } inline BOOL WaitFailed( DWORD dwWaitResult) { return (dwWaitResult == WAIT_FAILED); } /* compute object indices for waits... */ inline DWORD WaitSucceededIndex( DWORD dwWaitResult) { return (dwWaitResult - WAIT_OBJECT_0); } inline DWORD WaitAbandonedIndex( DWORD dwWaitResult) { return (dwWaitResult - WAIT_ABANDONED_0); } typedef HANDLE isc_thread_t; typedef DWORD isc_threadresult_t; typedef void * isc_threadarg_t; typedef isc_threadresult_t (WINAPI *isc_threadfunc_t)(isc_threadarg_t); typedef DWORD isc_thread_key_t; #define isc_thread_self (unsigned long)GetCurrentThreadId ISC_LANG_BEGINDECLS isc_result_t isc_thread_create(isc_threadfunc_t, isc_threadarg_t, isc_thread_t *); isc_result_t isc_thread_join(isc_thread_t, isc_threadresult_t *); void isc_thread_setconcurrency(unsigned int level); int isc_thread_key_create(isc_thread_key_t *key, void (*func)(void *)); int isc_thread_key_delete(isc_thread_key_t key); void * isc_thread_key_getspecific(isc_thread_key_t); int isc_thread_key_setspecific(isc_thread_key_t key, void *value); #define isc_thread_yield() Sleep(0) ISC_LANG_ENDDECLS #endif /* ISC_THREAD_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/include/isc/stat.h0000644000470500017500000000400212664710322021200 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: stat.h,v 1.9 2009/10/01 23:48:08 tbox Exp $ */ #ifndef ISC_STAT_H #define ISC_STAT_H 1 #include /* * Windows doesn't typedef this. */ typedef unsigned short mode_t; /* open() under unix allows setting of read/write permissions * at the owner, group and other levels. These don't exist in NT * We'll just map them all to the NT equivalent */ #define S_IREAD _S_IREAD /* read permission, owner */ #define S_IWRITE _S_IWRITE /* write permission, owner */ #define S_IRUSR _S_IREAD /* Owner read permission */ #define S_IWUSR _S_IWRITE /* Owner write permission */ #define S_IRGRP _S_IREAD /* Group read permission */ #define S_IWGRP _S_IWRITE /* Group write permission */ #define S_IROTH _S_IREAD /* Other read permission */ #define S_IWOTH _S_IWRITE /* Other write permission */ #ifndef S_IFMT # define S_IFMT _S_IFMT #endif #ifndef S_IFDIR # define S_IFDIR _S_IFDIR #endif #ifndef S_IFCHR # define S_IFCHR _S_IFCHR #endif #ifndef S_IFREG # define S_IFREG _S_IFREG #endif #ifndef S_ISDIR # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) #endif #ifndef S_ISREG # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) #endif #endif /* ISC_STAT_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/errno2result.h0000644000470500017500000000256212664710322020503 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: errno2result.h,v 1.10 2007/06/19 23:47:19 tbox Exp $ */ #ifndef UNIX_ERRNO2RESULT_H #define UNIX_ERRNO2RESULT_H 1 /* XXXDCL this should be moved to lib/isc/include/isc/errno2result.h. */ #include /* Provides errno. */ #include #include ISC_LANG_BEGINDECLS #define isc__errno2result(posixerrno) \ isc__errno2resultx(posixerrno, __FILE__, __LINE__) isc_result_t isc__errno2resultx(int posixerrno, const char *file, int line); ISC_LANG_ENDDECLS #endif /* UNIX_ERRNO2RESULT_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/net.c0000644000470500017500000001701312664710322016613 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007-2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #include #include #include #include #include #include #include #include #include #include /*% * Definitions about UDP port range specification. This is a total mess of * portability variants: some use sysctl (but the sysctl names vary), some use * system-specific interfaces, some have the same interface for IPv4 and IPv6, * some separate them, etc... */ /*% * The last resort defaults: use all non well known port space */ #ifndef ISC_NET_PORTRANGELOW #define ISC_NET_PORTRANGELOW 1024 #endif /* ISC_NET_PORTRANGELOW */ #ifndef ISC_NET_PORTRANGEHIGH #define ISC_NET_PORTRANGEHIGH 65535 #endif /* ISC_NET_PORTRANGEHIGH */ #if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRANY) const struct in6_addr isc_net_in6addrany = IN6ADDR_ANY_INIT; #endif static isc_once_t once = ISC_ONCE_INIT; static isc_once_t once_ipv6only = ISC_ONCE_INIT; static isc_once_t once_ipv6pktinfo = ISC_ONCE_INIT; static isc_result_t ipv4_result = ISC_R_NOTFOUND; static isc_result_t ipv6_result = ISC_R_NOTFOUND; static isc_result_t ipv6only_result = ISC_R_NOTFOUND; static isc_result_t ipv6pktinfo_result = ISC_R_NOTFOUND; void InitSockets(void); static isc_result_t try_proto(int domain) { SOCKET s; char strbuf[ISC_STRERRORSIZE]; int errval; s = socket(domain, SOCK_STREAM, IPPROTO_TCP); if (s == INVALID_SOCKET) { errval = WSAGetLastError(); switch (errval) { case WSAEAFNOSUPPORT: case WSAEPROTONOSUPPORT: case WSAEINVAL: return (ISC_R_NOTFOUND); default: isc__strerror(errval, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "socket() %s: %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); return (ISC_R_UNEXPECTED); } } closesocket(s); return (ISC_R_SUCCESS); } static void initialize_action(void) { InitSockets(); ipv4_result = try_proto(PF_INET); #ifdef ISC_PLATFORM_HAVEIPV6 #ifdef WANT_IPV6 #ifdef ISC_PLATFORM_HAVEIN6PKTINFO ipv6_result = try_proto(PF_INET6); #endif #endif #endif } static void initialize(void) { RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); } isc_result_t isc_net_probeipv4(void) { initialize(); return (ipv4_result); } isc_result_t isc_net_probeipv6(void) { initialize(); return (ipv6_result); } isc_result_t isc_net_probeunix(void) { return (ISC_R_NOTFOUND); } #ifdef ISC_PLATFORM_HAVEIPV6 #ifdef WANT_IPV6 static void try_ipv6only(void) { #ifdef IPV6_V6ONLY SOCKET s; int on; char strbuf[ISC_STRERRORSIZE]; #endif isc_result_t result; result = isc_net_probeipv6(); if (result != ISC_R_SUCCESS) { ipv6only_result = result; return; } #ifndef IPV6_V6ONLY ipv6only_result = ISC_R_NOTFOUND; return; #else /* check for TCP sockets */ s = socket(PF_INET6, SOCK_STREAM, 0); if (s == INVALID_SOCKET) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "socket() %s: %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); ipv6only_result = ISC_R_UNEXPECTED; return; } on = 1; if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)&on, sizeof(on)) < 0) { ipv6only_result = ISC_R_NOTFOUND; goto close; } closesocket(s); /* check for UDP sockets */ s = socket(PF_INET6, SOCK_DGRAM, 0); if (s == INVALID_SOCKET) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "socket() %s: %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); ipv6only_result = ISC_R_UNEXPECTED; return; } on = 1; if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)&on, sizeof(on)) < 0) { ipv6only_result = ISC_R_NOTFOUND; goto close; } ipv6only_result = ISC_R_SUCCESS; close: closesocket(s); return; #endif /* IPV6_V6ONLY */ } static void initialize_ipv6only(void) { RUNTIME_CHECK(isc_once_do(&once_ipv6only, try_ipv6only) == ISC_R_SUCCESS); } #ifdef __notyet__ /* * XXXMPA requires win32/socket.c to be updated to support * WSASendMsg and WSARecvMsg which are themselves Winsock * and compiler version dependent. */ static void try_ipv6pktinfo(void) { SOCKET s; int on; char strbuf[ISC_STRERRORSIZE]; isc_result_t result; int optname; result = isc_net_probeipv6(); if (result != ISC_R_SUCCESS) { ipv6pktinfo_result = result; return; } /* we only use this for UDP sockets */ s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); if (s == INVALID_SOCKET) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "socket() %s: %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), strbuf); ipv6pktinfo_result = ISC_R_UNEXPECTED; return; } #ifdef IPV6_RECVPKTINFO optname = IPV6_RECVPKTINFO; #else optname = IPV6_PKTINFO; #endif on = 1; if (setsockopt(s, IPPROTO_IPV6, optname, (const char *) &on, sizeof(on)) < 0) { ipv6pktinfo_result = ISC_R_NOTFOUND; goto close; } ipv6pktinfo_result = ISC_R_SUCCESS; close: closesocket(s); return; } static void initialize_ipv6pktinfo(void) { RUNTIME_CHECK(isc_once_do(&once_ipv6pktinfo, try_ipv6pktinfo) == ISC_R_SUCCESS); } #endif /* __notyet__ */ #endif /* WANT_IPV6 */ #endif /* ISC_PLATFORM_HAVEIPV6 */ isc_result_t isc_net_probe_ipv6only(void) { #ifdef ISC_PLATFORM_HAVEIPV6 #ifdef WANT_IPV6 initialize_ipv6only(); #else ipv6only_result = ISC_R_NOTFOUND; #endif #endif return (ipv6only_result); } isc_result_t isc_net_probe_ipv6pktinfo(void) { #ifdef __notyet__ #ifdef ISC_PLATFORM_HAVEIPV6 #ifdef WANT_IPV6 initialize_ipv6pktinfo(); #else ipv6pktinfo_result = ISC_R_NOTFOUND; #endif #endif #endif /* __notyet__ */ return (ipv6pktinfo_result); } isc_result_t isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high) { int result = ISC_R_FAILURE; REQUIRE(low != NULL && high != NULL); UNUSED(af); if (result != ISC_R_SUCCESS) { *low = ISC_NET_PORTRANGELOW; *high = ISC_NET_PORTRANGEHIGH; } return (ISC_R_SUCCESS); /* we currently never fail in this function */ } void isc_net_disableipv4(void) { initialize(); if (ipv4_result == ISC_R_SUCCESS) ipv4_result = ISC_R_DISABLED; } void isc_net_disableipv6(void) { initialize(); if (ipv6_result == ISC_R_SUCCESS) ipv6_result = ISC_R_DISABLED; } void isc_net_enableipv4(void) { initialize(); if (ipv4_result == ISC_R_DISABLED) ipv4_result = ISC_R_SUCCESS; } void isc_net_enableipv6(void) { initialize(); if (ipv6_result == ISC_R_DISABLED) ipv6_result = ISC_R_SUCCESS; } unsigned int isc_net_probedscp(void) { return (0); } bind9-9.10.3.dfsg.P4/lib/isc/win32/once.c0000644000470500017500000000320612664710322016750 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: once.c,v 1.12 2007/06/18 23:47:49 tbox Exp $ */ /* Principal Authors: DCL */ #include #include #include #include #include isc_result_t isc_once_do(isc_once_t *controller, void(*function)(void)) { REQUIRE(controller != NULL && function != NULL); if (controller->status == ISC_ONCE_INIT_NEEDED) { if (InterlockedDecrement(&controller->counter) == 0) { if (controller->status == ISC_ONCE_INIT_NEEDED) { function(); controller->status = ISC_ONCE_INIT_DONE; } } else { while (controller->status == ISC_ONCE_INIT_NEEDED) { /* * Sleep(0) indicates that this thread * should be suspended to allow other * waiting threads to execute. */ Sleep(0); } } } return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/isc/win32/entropy.c0000644000470500017500000001671212664710322017532 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2009, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: entropy.c,v 1.10 2009/01/18 23:48:14 tbox Exp $ */ /* * This is the system dependent part of the ISC entropy API. */ #include #include #include #include #include #include /* * There is only one variable in the entropy data structures that is not * system independent, but pulling the structure that uses it into this file * ultimately means pulling several other independent structures here also to * resolve their interdependencies. Thus only the problem variable's type * is defined here. */ #define FILESOURCE_HANDLE_TYPE HCRYPTPROV typedef struct { int dummy; } isc_entropyusocketsource_t; #include "../entropy.c" static unsigned int get_from_filesource(isc_entropysource_t *source, isc_uint32_t desired) { isc_entropy_t *ent = source->ent; unsigned char buf[128]; HCRYPTPROV hcryptprov = source->sources.file.handle; ssize_t ndesired; unsigned int added; if (source->bad) return (0); desired = desired / 8 + (((desired & 0x07) > 0) ? 1 : 0); added = 0; while (desired > 0) { ndesired = ISC_MIN(desired, sizeof(buf)); if (!CryptGenRandom(hcryptprov, (DWORD)ndesired, buf)) { CryptReleaseContext(hcryptprov, 0); source->bad = ISC_TRUE; goto out; } entropypool_adddata(ent, buf, (unsigned int)ndesired, (unsigned int)ndesired * 8); added += (unsigned int)ndesired * 8; desired -= (isc_uint32_t)ndesired; } out: return (added); } /* * Poll each source, trying to get data from it to stuff into the entropy * pool. */ static void fillpool(isc_entropy_t *ent, unsigned int desired, isc_boolean_t blocking) { unsigned int added; unsigned int remaining; unsigned int needed; unsigned int nsource; isc_entropysource_t *source; isc_entropysource_t *firstsource; REQUIRE(VALID_ENTROPY(ent)); needed = desired; /* * This logic is a little strange, so an explanation is in order. * * If needed is 0, it means we are being asked to "fill to whatever * we think is best." This means that if we have at least a * partially full pool (say, > 1/4th of the pool) we probably don't * need to add anything. * * Also, we will check to see if the "pseudo" count is too high. * If it is, try to mix in better data. Too high is currently * defined as 1/4th of the pool. * * Next, if we are asked to add a specific bit of entropy, make * certain that we will do so. Clamp how much we try to add to * (DIGEST_SIZE * 8 < needed < POOLBITS - entropy). * * Note that if we are in a blocking mode, we will only try to * get as much data as we need, not as much as we might want * to build up. */ if (needed == 0) { REQUIRE(!blocking); if ((ent->pool.entropy >= RND_POOLBITS / 4) && (ent->pool.pseudo <= RND_POOLBITS / 4)) return; needed = THRESHOLD_BITS * 4; } else { needed = ISC_MAX(needed, THRESHOLD_BITS); needed = ISC_MIN(needed, RND_POOLBITS); } /* * In any case, clamp how much we need to how much we can add. */ needed = ISC_MIN(needed, RND_POOLBITS - ent->pool.entropy); /* * But wait! If we're not yet initialized, we need at least * THRESHOLD_BITS * of randomness. */ if (ent->initialized < THRESHOLD_BITS) needed = ISC_MAX(needed, THRESHOLD_BITS - ent->initialized); /* * Poll each file source to see if we can read anything useful from * it. XXXMLG When where are multiple sources, we should keep a * record of which one we last used so we can start from it (or the * next one) to avoid letting some sources build up entropy while * others are always drained. */ added = 0; remaining = needed; if (ent->nextsource == NULL) { ent->nextsource = ISC_LIST_HEAD(ent->sources); if (ent->nextsource == NULL) return; } source = ent->nextsource; /* * Remember the first source so we can break if we have looped back to * the beginning and still have nothing */ firstsource = source; again_file: for (nsource = 0; nsource < ent->nsources; nsource++) { unsigned int got; if (remaining == 0) break; got = 0; if (source->type == ENTROPY_SOURCETYPE_FILE) got = get_from_filesource(source, remaining); added += got; remaining -= ISC_MIN(remaining, got); source = ISC_LIST_NEXT(source, link); if (source == NULL) source = ISC_LIST_HEAD(ent->sources); } ent->nextsource = source; /* * Go again only if there's been progress and we've not * gone back to the beginning */ if (!(ent->nextsource == firstsource && added == 0)) { if (blocking && remaining != 0) { goto again_file; } } /* * Here, if there are bits remaining to be had and we can block, * check to see if we have a callback source. If so, call them. */ source = ISC_LIST_HEAD(ent->sources); while ((remaining != 0) && (source != NULL)) { unsigned int got; got = 0; if (source->type == ENTROPY_SOURCETYPE_CALLBACK) got = get_from_callback(source, remaining, blocking); added += got; remaining -= ISC_MIN(remaining, got); if (added >= needed) break; source = ISC_LIST_NEXT(source, link); } /* * Mark as initialized if we've added enough data. */ if (ent->initialized < THRESHOLD_BITS) ent->initialized += added; } /* * Requires "ent" be locked. */ static void destroyfilesource(isc_entropyfilesource_t *source) { CryptReleaseContext(source->handle, 0); } static void destroyusocketsource(isc_entropyusocketsource_t *source) { UNUSED(source); } isc_result_t isc_entropy_createfilesource(isc_entropy_t *ent, const char *fname) { isc_result_t ret; isc_entropysource_t *source; HCRYPTPROV hcryptprov; BOOL err; REQUIRE(VALID_ENTROPY(ent)); REQUIRE(fname != NULL); LOCK(&ent->lock); source = NULL; /* * The first time we just try to acquire the context */ err = CryptAcquireContext(&hcryptprov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); if (!err){ (void)GetLastError(); ret = ISC_R_IOERROR; goto errout; } source = isc_mem_get(ent->mctx, sizeof(isc_entropysource_t)); if (source == NULL) { ret = ISC_R_NOMEMORY; goto closecontext; } /* * From here down, no failures can occur. */ source->magic = SOURCE_MAGIC; source->type = ENTROPY_SOURCETYPE_FILE; source->ent = ent; source->total = 0; source->bad = ISC_FALSE; memset(source->name, 0, sizeof(source->name)); ISC_LINK_INIT(source, link); source->sources.file.handle = hcryptprov; /* * Hook it into the entropy system. */ ISC_LIST_APPEND(ent->sources, source, link); ent->nsources++; UNLOCK(&ent->lock); return (ISC_R_SUCCESS); closecontext: CryptReleaseContext(hcryptprov, 0); errout: if (source != NULL) isc_mem_put(ent->mctx, source, sizeof(isc_entropysource_t)); UNLOCK(&ent->lock); return (ret); } bind9-9.10.3.dfsg.P4/lib/isc/win32/netdb.h0000644000470500017500000001154312664710322017130 0ustar lamontlamont/* * Copyright (C) 2004, 2006, 2007, 2009, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: netdb.h,v 1.9 2009/01/18 23:48:14 tbox Exp $ */ #ifndef NETDB_H #define NETDB_H 1 #include #include /* * Define if does not declare struct addrinfo. */ #if _MSC_VER < 1600 struct addrinfo { int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ int ai_family; /* PF_xxx */ int ai_socktype; /* SOCK_xxx */ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ size_t ai_addrlen; /* Length of ai_addr */ char *ai_canonname; /* Canonical name for hostname */ struct sockaddr *ai_addr; /* Binary address */ struct addrinfo *ai_next; /* Next structure in linked list */ }; #endif /* * Undefine all \#defines we are interested in as may or may not have * defined them. */ /* * Error return codes from gethostbyname() and gethostbyaddr() * (left in extern int h_errno). */ #undef NETDB_INTERNAL #undef NETDB_SUCCESS #undef HOST_NOT_FOUND #undef TRY_AGAIN #undef NO_RECOVERY #undef NO_DATA #undef NO_ADDRESS #define NETDB_INTERNAL -1 /* see errno */ #define NETDB_SUCCESS 0 /* no problem */ #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */ #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL */ #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ #define NO_DATA 4 /* Valid name, no data record of requested type */ #define NO_ADDRESS NO_DATA /* no address, look for MX record */ /* * Error return codes from getaddrinfo() */ #undef EAI_ADDRFAMILY #undef EAI_AGAIN #undef EAI_BADFLAGS #undef EAI_FAIL #undef EAI_FAMILY #undef EAI_MEMORY #undef EAI_NODATA #undef EAI_NONAME #undef EAI_SERVICE #undef EAI_SOCKTYPE #undef EAI_SYSTEM #undef EAI_BADHINTS #undef EAI_PROTOCOL #undef EAI_MAX #define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ #define EAI_AGAIN 2 /* temporary failure in name resolution */ #define EAI_BADFLAGS 3 /* invalid value for ai_flags */ #define EAI_FAIL 4 /* non-recoverable failure in name resolution */ #define EAI_FAMILY 5 /* ai_family not supported */ #define EAI_MEMORY 6 /* memory allocation failure */ #define EAI_NODATA 7 /* no address associated with hostname */ #define EAI_NONAME 8 /* hostname nor servname provided, or not known */ #define EAI_SERVICE 9 /* servname not supported for ai_socktype */ #define EAI_SOCKTYPE 10 /* ai_socktype not supported */ #define EAI_SYSTEM 11 /* system error returned in errno */ #define EAI_BADHINTS 12 #define EAI_PROTOCOL 13 #define EAI_MAX 14 /* * Flag values for getaddrinfo() */ #undef AI_PASSIVE #undef AI_CANONNAME #undef AI_NUMERICHOST #define AI_PASSIVE 0x00000001 #define AI_CANONNAME 0x00000002 #define AI_NUMERICHOST 0x00000004 /* * Flag values for getipnodebyname() */ #undef AI_V4MAPPED #undef AI_ALL #undef AI_ADDRCONFIG #undef AI_DEFAULT #define AI_V4MAPPED 0x00000008 #define AI_ALL 0x00000010 #define AI_ADDRCONFIG 0x00000020 #define AI_DEFAULT (AI_V4MAPPED|AI_ADDRCONFIG) /* * Constants for getnameinfo() */ #undef NI_MAXHOST #undef NI_MAXSERV #define NI_MAXHOST 1025 #define NI_MAXSERV 32 /* * Flag values for getnameinfo() */ #undef NI_NOFQDN #undef NI_NUMERICHOST #undef NI_NAMEREQD #undef NI_NUMERICSERV #undef NI_DGRAM #undef NI_NUMERICSCOPE #define NI_NOFQDN 0x00000001 #define NI_NUMERICHOST 0x00000002 #define NI_NAMEREQD 0x00000004 #define NI_NUMERICSERV 0x00000008 #define NI_DGRAM 0x00000010 #define NI_NUMERICSCOPE 0x00000020 /*2553bis-00*/ /* * Structures for getrrsetbyname() */ struct rdatainfo { unsigned int rdi_length; unsigned char *rdi_data; }; struct rrsetinfo { unsigned int rri_flags; int rri_rdclass; int rri_rdtype; unsigned int rri_ttl; unsigned int rri_nrdatas; unsigned int rri_nsigs; char *rri_name; struct rdatainfo *rri_rdatas; struct rdatainfo *rri_sigs; }; /* * Flags for getrrsetbyname() */ #define RRSET_VALIDATED 0x00000001 /* Set was dnssec validated */ /* * Return codes for getrrsetbyname() */ #define ERRSET_SUCCESS 0 #define ERRSET_NOMEMORY 1 #define ERRSET_FAIL 2 #define ERRSET_INVAL 3 #endif /* NETDB_H */ bind9-9.10.3.dfsg.P4/lib/isc/win32/ipv6.c0000644000470500017500000000215312664710322016710 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ipv6.c,v 1.8 2007/06/19 23:47:19 tbox Exp $ */ #include #include LIBISC_EXTERNAL_DATA const struct in6_addr isc_in6addr_any = IN6ADDR_ANY_INIT; LIBISC_EXTERNAL_DATA const struct in6_addr isc_in6addr_loopback = IN6ADDR_LOOPBACK_INIT; bind9-9.10.3.dfsg.P4/lib/isc/win32/os.c0000644000470500017500000000242512664710322016447 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: os.c,v 1.8 2007/06/19 23:47:19 tbox Exp $ */ #include #include static BOOL bInit = FALSE; static SYSTEM_INFO SystemInfo; static void initialize_action(void) { if (bInit) return; GetSystemInfo(&SystemInfo); bInit = TRUE; } unsigned int isc_os_ncpus(void) { long ncpus; initialize_action(); ncpus = SystemInfo.dwNumberOfProcessors; if (ncpus <= 0) ncpus = 1; return ((unsigned int)ncpus); } bind9-9.10.3.dfsg.P4/lib/isc/win32/win32os.c0000644000470500017500000000650112664710322017331 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2013-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #ifndef TESTVERSION #include #else #include #endif #include int isc_win32os_versioncheck(unsigned int major, unsigned int minor, unsigned int spmajor, unsigned int spminor) { OSVERSIONINFOEX osVer; DWORD typeMask; ULONGLONG conditionMask; memset(&osVer, 0, sizeof(OSVERSIONINFOEX)); osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); typeMask = 0; conditionMask = 0; /* Optimistic: likely greater */ osVer.dwMajorVersion = major; typeMask |= VER_MAJORVERSION; conditionMask = VerSetConditionMask(conditionMask, VER_MAJORVERSION, VER_GREATER); osVer.dwMinorVersion = minor; typeMask |= VER_MINORVERSION; conditionMask = VerSetConditionMask(conditionMask, VER_MINORVERSION, VER_GREATER); osVer.wServicePackMajor = spmajor; typeMask |= VER_SERVICEPACKMAJOR; conditionMask = VerSetConditionMask(conditionMask, VER_SERVICEPACKMAJOR, VER_GREATER); osVer.wServicePackMinor = spminor; typeMask |= VER_SERVICEPACKMINOR; conditionMask = VerSetConditionMask(conditionMask, VER_SERVICEPACKMINOR, VER_GREATER); if (VerifyVersionInfo(&osVer, typeMask, conditionMask)) return (1); /* Failed: retry with equal */ conditionMask = 0; conditionMask = VerSetConditionMask(conditionMask, VER_MAJORVERSION, VER_EQUAL); conditionMask = VerSetConditionMask(conditionMask, VER_MINORVERSION, VER_EQUAL); conditionMask = VerSetConditionMask(conditionMask, VER_SERVICEPACKMAJOR, VER_EQUAL); conditionMask = VerSetConditionMask(conditionMask, VER_SERVICEPACKMINOR, VER_EQUAL); if (VerifyVersionInfo(&osVer, typeMask, conditionMask)) return (0); else return (-1); } #ifdef TESTVERSION int main(int argc, char **argv) { unsigned int major = 0; unsigned int minor = 0; unsigned int spmajor = 0; unsigned int spminor = 0; int ret; if (argc > 1) { --argc; ++argv; major = (unsigned int) atoi(argv[0]); } if (argc > 1) { --argc; ++argv; minor = (unsigned int) atoi(argv[0]); } if (argc > 1) { --argc; ++argv; spmajor = (unsigned int) atoi(argv[0]); } if (argc > 1) { --argc; ++argv; spminor = (unsigned int) atoi(argv[0]); } ret = isc_win32os_versioncheck(major, minor, spmajor, spminor); printf("%s major %u minor %u SP major %u SP minor %u\n", ret > 0 ? "greater" : (ret == 0 ? "equal" : "less"), major, minor, spmajor, spminor); return (ret); } #endif bind9-9.10.3.dfsg.P4/lib/isc/win32/dir.c0000644000470500017500000001563312664710322016611 0ustar lamontlamont/* * Copyright (C) 2004, 2007-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* Principal Authors: DCL */ #include #include #include #include #include #include #include #include #include #include #include "errno2result.h" #define ISC_DIR_MAGIC ISC_MAGIC('D', 'I', 'R', '*') #define VALID_DIR(dir) ISC_MAGIC_VALID(dir, ISC_DIR_MAGIC) static isc_result_t start_directory(isc_dir_t *p); void isc_dir_init(isc_dir_t *dir) { REQUIRE(dir != NULL); dir->dirname[0] = '\0'; dir->entry.name[0] = '\0'; dir->entry.length = 0; memset(&(dir->entry.find_data), 0, sizeof(dir->entry.find_data)); dir->entry_filled = ISC_FALSE; dir->search_handle = INVALID_HANDLE_VALUE; dir->magic = ISC_DIR_MAGIC; } /* * Allocate workspace and open directory stream. If either one fails, * NULL will be returned. */ isc_result_t isc_dir_open(isc_dir_t *dir, const char *dirname) { char *p; isc_result_t result; REQUIRE(dirname != NULL); REQUIRE(VALID_DIR(dir) && dir->search_handle == INVALID_HANDLE_VALUE); /* * Copy directory name. Need to have enough space for the name, * a possible path separator, the wildcard, and the final NUL. */ if (strlen(dirname) + 3 > sizeof(dir->dirname)) /* XXXDCL ? */ return (ISC_R_NOSPACE); strcpy(dir->dirname, dirname); /* * Append path separator, if needed, and "*". */ p = dir->dirname + strlen(dir->dirname); if (dir->dirname < p && *(p - 1) != '\\' && *(p - 1) != ':') *p++ = '\\'; *p++ = '*'; *p = '\0'; /* * Open stream. */ result = start_directory(dir); return (result); } /* * Return previously retrieved file or get next one. Unix's dirent has * separate open and read functions, but the Win32 and DOS interfaces open * the dir stream and reads the first file in one operation. */ isc_result_t isc_dir_read(isc_dir_t *dir) { REQUIRE(VALID_DIR(dir) && dir->search_handle != INVALID_HANDLE_VALUE); if (dir->entry_filled) /* * start_directory() already filled in the first entry. */ dir->entry_filled = ISC_FALSE; else { /* * Fetch next file in directory. */ if (FindNextFile(dir->search_handle, &dir->entry.find_data) == FALSE) /* * Either the last file has been processed or * an error has occurred. The former is not * really an error, but the latter is. */ if (GetLastError() == ERROR_NO_MORE_FILES) return (ISC_R_NOMORE); else return (ISC_R_UNEXPECTED); } /* * Make sure that the space for the name is long enough. */ strcpy(dir->entry.name, dir->entry.find_data.cFileName); dir->entry.length = strlen(dir->entry.name); return (ISC_R_SUCCESS); } /* * Close directory stream. */ void isc_dir_close(isc_dir_t *dir) { REQUIRE(VALID_DIR(dir) && dir->search_handle != INVALID_HANDLE_VALUE); FindClose(dir->search_handle); dir->search_handle = INVALID_HANDLE_VALUE; } /* * Reposition directory stream at start. */ isc_result_t isc_dir_reset(isc_dir_t *dir) { isc_result_t result; REQUIRE(VALID_DIR(dir) && dir->search_handle != INVALID_HANDLE_VALUE); REQUIRE(dir->dirname != NULL); /* * NT cannot reposition the seek pointer to the beginning of the * the directory stream, but rather the directory needs to be * closed and reopened. The latter might fail. */ isc_dir_close(dir); result = start_directory(dir); return (result); } /* * Initialize isc_dir_t structure with new directory. The function * returns 0 on failure and nonzero on success. * * Note: * - Be sure to close previous stream before opening new one */ static isc_result_t start_directory(isc_dir_t *dir) { REQUIRE(VALID_DIR(dir)); REQUIRE(dir->search_handle == INVALID_HANDLE_VALUE); dir->entry_filled = ISC_FALSE; /* * Open stream and retrieve first file. */ dir->search_handle = FindFirstFile(dir->dirname, &dir->entry.find_data); if (dir->search_handle == INVALID_HANDLE_VALUE) { /* * Something went wrong but we don't know what. GetLastError() * could give us more information about the error, but the * MSDN documentation is frustratingly thin about what * possible errors could have resulted. (Score one for * the Unix manual pages.) So there is just this lame error * instead of being able to differentiate ISC_R_NOTFOUND * from ISC_R_UNEXPECTED. */ return (ISC_R_FAILURE); } /* * Make sure that the space for the name is long enough. */ INSIST(sizeof(dir->entry.name) > strlen(dir->entry.find_data.cFileName)); /* * Fill in the data for the first entry of the directory. */ strcpy(dir->entry.name, dir->entry.find_data.cFileName); dir->entry.length = strlen(dir->entry.name); dir->entry_filled = ISC_TRUE; return (ISC_R_SUCCESS); } isc_result_t isc_dir_chdir(const char *dirname) { /* * Change the current directory to 'dirname'. */ REQUIRE(dirname != NULL); if (chdir(dirname) < 0) return (isc__errno2result(errno)); return (ISC_R_SUCCESS); } isc_result_t isc_dir_chroot(const char *dirname) { return (ISC_R_NOTIMPLEMENTED); } isc_result_t isc_dir_createunique(char *templet) { isc_result_t result; char *x; char *p; int i; int pid; REQUIRE(templet != NULL); /* * mkdtemp is not portable, so this emulates it. */ pid = getpid(); /* * Replace trailing Xs with the process-id, zero-filled. */ for (x = templet + strlen(templet) - 1; *x == 'X' && x >= templet; x--, pid /= 10) *x = pid % 10 + '0'; x++; /* Set x to start of ex-Xs. */ do { i = mkdir(templet); if (i == 0) i = chmod(templet, 0700); if (i == 0 || errno != EEXIST) break; /* * The BSD algorithm. */ p = x; while (*p != '\0') { if (isdigit(*p & 0xff)) *p = 'a'; else if (*p != 'z') ++*p; else { /* * Reset character and move to next. */ *p++ = 'a'; continue; } break; } if (*p == '\0') { /* * Tried all combinations. errno should already * be EEXIST, but ensure it is anyway for * isc__errno2result(). */ errno = EEXIST; break; } } while (1); if (i == -1) result = isc__errno2result(errno); else result = ISC_R_SUCCESS; return (result); } bind9-9.10.3.dfsg.P4/lib/isc/win32/unistd.h0000644000470500017500000000275512664710322017347 0ustar lamontlamont/* * Copyright (C) 2004, 2007-2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: unistd.h,v 1.10 2009/07/17 23:47:41 tbox Exp $ */ /* None of these are defined in NT, so define them for our use */ #define O_NONBLOCK 1 #define PORT_NONBLOCK O_NONBLOCK /* * fcntl() commands */ #define F_SETFL 0 #define F_GETFL 1 #define F_SETFD 2 #define F_GETFD 3 /* * Enough problems not having full fcntl() without worrying about this! */ #undef F_DUPFD int fcntl(int, int, ...); /* * access() related definitions for winXP */ #include #ifndef F_OK #define F_OK 0 #endif #ifndef X_OK #define X_OK 1 #endif #ifndef W_OK #define W_OK 2 #endif #ifndef R_OK #define R_OK 4 #endif #define access _access #include bind9-9.10.3.dfsg.P4/lib/isc/win32/libisc.vcxproj.in0000644000470500017500000005162412664710322021156 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {3840E563-D180-4761-AA9C-E6155F02EAFF} Win32Proj libisc DynamicLibrary true MultiByte DynamicLibrary false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ Level3 Disabled @IF PKCS11 BIND9;@CRYPTO@@PK11_LIB_LOCATION@WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBISC_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions) .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@include;..\include;win32;..\..\isccfg\include;..\..\dns\win32\include;..\..\dns\include;%(AdditionalIncludeDirectories) @ELSE PKCS11 BIND9;WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBISC_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions) .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@include;..\include;win32;..\..\isccfg\include;%(AdditionalIncludeDirectories) @END PKCS11 false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) @LIBXML2_LIB@@OPENSSL_LIB@ws2_32.lib;%(AdditionalDependencies) $(ProjectName).def .\$(Configuration)\$(ProjectName).lib cd ..\..\..\win32utils if NOT Exist ..\Build mkdir ..\Build if NOT Exist ..\Build\Debug mkdir ..\Build\Debug echo Copying COPYRIGHT notice. copy ..\COPYRIGHT ..\Build\Debug @IF OPENSSL echo Copying the OpenSSL DLL and LICENSE. copy @OPENSSL_DLL@ ..\Build\Debug\ copy @OPENSSL_PATH@\LICENSE ..\Build\Debug\OpenSSL-LICENSE @END OPENSSL @IF LIBXML2 echo Copying the libxml DLL. copy @LIBXML2_DLL@ ..\Build\Debug\ @END LIBXML2 @IF GSSAPI echo Copying the GSSAPI and KRB5 DLLs. copy @GSSAPI_DLL@ ..\Build\Debug\ copy @KRB5_DLL@ ..\Build\Debug\ copy @COMERR_DLL@ ..\Build\Debug\ copy @K5SPRT_DLL@ ..\Build\Debug\ copy @WSHELP_DLL@ ..\Build\Debug\ @END GSSAPI @IF GEOIP echo Copying the GeoIP DLL. copy @GEOIP_DLL@ ..\Build\Debug\ @END GEOIP @IF IDNKIT echo Copying the IDN kit DLL. copy @IDN_DLL@ ..\Build\Debug\ copy @ICONV_DLL@ ..\Build\Debug\ @END IDNKIT echo Copying Visual C x86 Redistributable Installer. copy /Y @VCREDIST_PATH@ ..\Build\Debug\ Level3 MaxSpeed true @INTRINSIC@ @IF PKCS11 BIND9;@CRYPTO@@PK11_LIB_LOCATION@WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBISC_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions) .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@include;..\include;win32;..\..\isccfg\include;..\..\dns\win32\include;..\..\dns\include;%(AdditionalIncludeDirectories) @ELSE PKCS11 BIND9;WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBISC_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions) .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@include;..\include;win32;..\..\isccfg\include;%(AdditionalIncludeDirectories) @END PKCS11 OnlyExplicitInline false true .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) @LIBXML2_LIB@@OPENSSL_LIB@ws2_32.lib;%(AdditionalDependencies) $(ProjectName).def .\$(Configuration)\$(ProjectName).lib Default cd ..\..\..\win32utils if NOT Exist ..\Build mkdir ..\Build if NOT Exist ..\Build\Release mkdir ..\Build\Release echo Copying the ARM and the Installation Notes. copy ..\COPYRIGHT ..\Build\Release copy ..\README ..\Build\Release copy ..\HISTORY ..\Build\Release copy readme1st.txt ..\Build\Release copy index.html ..\Build\Release copy ..\doc\arm\*.html ..\Build\Release copy ..\doc\arm\notes.pdf ..\Build\Release copy ..\doc\arm\Bv9ARM.pdf ..\Build\Release copy ..\CHANGES ..\Build\Release if Exist ..\CHANGES.SE copy ..\CHANGES.SE ..\Build\Release copy ..\FAQ ..\Build\Release echo Copying the standalone manual pages. copy ..\bin\named\named.html ..\Build\Release copy ..\bin\rndc\*.html ..\Build\Release copy ..\bin\confgen\*.html ..\Build\Release copy ..\bin\dig\*.html ..\Build\Release copy ..\bin\delv\*.html ..\Build\Release copy ..\bin\nsupdate\*.html ..\Build\Release copy ..\bin\check\*.html ..\Build\Release copy ..\bin\dnssec\dnssec-keygen.html ..\Build\Release copy ..\bin\dnssec\dnssec-signzone.html ..\Build\Release copy ..\bin\dnssec\dnssec-dsfromkey.html ..\Build\Release copy ..\bin\dnssec\dnssec-keyfromlabel.html ..\Build\Release copy ..\bin\dnssec\dnssec-settime.html ..\Build\Release copy ..\bin\dnssec\dnssec-revoke.html ..\Build\Release copy ..\bin\dnssec\dnssec-verify.html ..\Build\Release copy ..\bin\dnssec\dnssec-importkey.html ..\Build\Release @IF PYTHON copy ..\bin\python\dnssec-checkds.html ..\Build\Release copy ..\bin\python\dnssec-coverage.html ..\Build\Release @END PYTHON @IF PKCS11 copy ..\bin\pkcs11\pkcs11-keygen.html ..\Build\Release copy ..\bin\pkcs11\pkcs11-list.html ..\Build\Release copy ..\bin\pkcs11\pkcs11-destroy.html ..\Build\Release copy ..\bin\pkcs11\pkcs11-tokens.html ..\Build\Release @END PKCS11 copy ..\bin\tools\arpaname.html ..\Build\Release copy ..\bin\tools\genrandom.html ..\Build\Release copy ..\bin\tools\isc-hmac-fixup.html ..\Build\Release copy ..\bin\tools\named-journalprint.html ..\Build\Release copy ..\bin\tools\named-rrchecker.html ..\Build\Release copy ..\bin\tools\nsec3hash.html ..\Build\Release echo Copying the migration notes. copy ..\doc\misc\migration ..\Build\Release copy ..\doc\misc\migration-4to9 ..\Build\Release @IF OPENSSL echo Copying the OpenSSL DLL and LICENSE. copy @OPENSSL_DLL@ ..\Build\Release\ copy @OPENSSL_PATH@\LICENSE ..\Build\Release\OpenSSL-LICENSE @END OPENSSL @IF LIBXML2 echo Copying the libxml DLL. copy @LIBXML2_DLL@ ..\Build\Release\ @END LIBXML2 @IF GSSAPI echo Copying the GSSAPI and KRB5 DLLs. copy @GSSAPI_DLL@ ..\Build\Release\ copy @KRB5_DLL@ ..\Build\Release\ copy @COMERR_DLL@ ..\Build\Release\ copy @K5SPRT_DLL@ ..\Build\Release\ copy @WSHELP_DLL@ ..\Build\Release\ @END GSSAPI @IF GEOIP echo Copying the GeoIP DLL. copy @GEOIP_DLL@ ..\Build\Release\ @END GEOIP @IF IDNKIT echo Copying the IDN kit DLL. copy @IDN_DLL@ ..\Build\Release\ copy @ICONV_DLL@ ..\Build\Release\ @END IDNKIT echo Copying Visual C x86 Redistributable Installer. copy /Y @VCREDIST_PATH@ ..\Build\Release\ @IF AES @END AES @IF PKCS11 @END PKCS11 @IF ATOMIC @ELSE ATOMIC @END ATOMIC @IF PKCS11 @END PKCS11 @IF AES @END AES @IF PKCS11 @END PKCS11 @IF PKCS11 @END PKCS11 bind9-9.10.3.dfsg.P4/lib/isc/win32/fsaccess.c0000644000470500017500000002364112664710322017623 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: fsaccess.c,v 1.15 2007/06/19 23:47:19 tbox Exp $ */ /* * Note that Win32 does not have the concept of files having access * and ownership bits. The FAT File system only has a readonly flag * for everyone and that's all. NTFS uses ACL's which is a totally * different concept of controlling access. * * This code needs to be revisited to set up proper access control for * NTFS file systems. Nothing can be done for FAT file systems. */ #include #include #include #include #include #include #include #include #include "errno2result.h" /* * The OS-independent part of the API is in lib/isc. */ #include "../fsaccess.c" /* Store the user account name locally */ static char username[255] = "\0"; static DWORD namelen = 0; /* * In order to set or retrieve access information, we need to obtain * the File System type. These could be UNC-type shares. */ BOOL is_ntfs(const char * file) { char drive[255]; char FSType[20]; char tmpbuf[256]; char *machinename; char *sharename; char filename[1024]; REQUIRE(filename != NULL); if (isc_file_absolutepath(file, filename, sizeof(filename)) != ISC_R_SUCCESS) { return (FALSE); } /* * Look for c:\path\... style, c:/path/... or \\computer\shar\path... * the UNC style file specs */ if (isalpha(filename[0]) && filename[1] == ':' && (filename[2] == '\\' || filename[2] == '/')) { strncpy(drive, filename, 3); drive[3] = '\0'; } else if ((filename[0] == '\\') && (filename[1] == '\\')) { /* Find the machine and share name and rebuild the UNC */ strcpy(tmpbuf, filename); machinename = strtok(tmpbuf, "\\"); sharename = strtok(NULL, "\\"); strcpy(drive, "\\\\"); strcat(drive, machinename); strcat(drive, "\\"); strcat(drive, sharename); strcat(drive, "\\"); } else /* Not determinable */ return (FALSE); GetVolumeInformation(drive, NULL, 0, NULL, 0, NULL, FSType, sizeof(FSType)); if(strcmp(FSType,"NTFS") == 0) return (TRUE); else return (FALSE); } /* * If it's not NTFS, we assume that it is FAT and proceed * with almost nothing to do. Only the write flag can be set or * cleared. */ isc_result_t FAT_fsaccess_set(const char *path, isc_fsaccess_t access) { int mode; isc_fsaccess_t bits; /* * Done with checking bad bits. Set mode_t. */ mode = 0; #define SET_AND_CLEAR1(modebit) \ if ((access & bits) != 0) { \ mode |= modebit; \ access &= ~bits; \ } #define SET_AND_CLEAR(user, group, other) \ SET_AND_CLEAR1(user); \ bits <<= STEP; \ SET_AND_CLEAR1(group); \ bits <<= STEP; \ SET_AND_CLEAR1(other); bits = ISC_FSACCESS_READ | ISC_FSACCESS_LISTDIRECTORY; SET_AND_CLEAR(S_IRUSR, S_IRGRP, S_IROTH); bits = ISC_FSACCESS_WRITE | ISC_FSACCESS_CREATECHILD | ISC_FSACCESS_DELETECHILD; SET_AND_CLEAR(S_IWUSR, S_IWGRP, S_IWOTH); INSIST(access == 0); if (_chmod(path, mode) < 0) return (isc__errno2result(errno)); return (ISC_R_SUCCESS); } isc_result_t NTFS_Access_Control(const char *filename, const char *user, int access, isc_boolean_t isdir) { SECURITY_DESCRIPTOR sd; BYTE aclBuffer[1024]; PACL pacl=(PACL)&aclBuffer; BYTE sidBuffer[100]; PSID psid=(PSID) &sidBuffer; DWORD sidBufferSize = sizeof(sidBuffer); BYTE adminSidBuffer[100]; PSID padminsid=(PSID) &adminSidBuffer; DWORD adminSidBufferSize = sizeof(adminSidBuffer); BYTE otherSidBuffer[100]; PSID pothersid=(PSID) &otherSidBuffer; DWORD otherSidBufferSize = sizeof(otherSidBuffer); char domainBuffer[100]; DWORD domainBufferSize = sizeof(domainBuffer); SID_NAME_USE snu; DWORD NTFSbits; int caccess; /* Initialize an ACL */ if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) return (ISC_R_NOPERM); if (!InitializeAcl(pacl, sizeof(aclBuffer), ACL_REVISION)) return (ISC_R_NOPERM); if (!LookupAccountName(0, user, psid, &sidBufferSize, domainBuffer, &domainBufferSize, &snu)) return (ISC_R_NOPERM); domainBufferSize = sizeof(domainBuffer); if (!LookupAccountName(0, "Administrators", padminsid, &adminSidBufferSize, domainBuffer, &domainBufferSize, &snu)) { (void)GetLastError(); return (ISC_R_NOPERM); } domainBufferSize = sizeof(domainBuffer); if (!LookupAccountName(0, "Everyone", pothersid, &otherSidBufferSize, domainBuffer, &domainBufferSize, &snu)) { (void)GetLastError(); return (ISC_R_NOPERM); } caccess = access; /* Owner check */ NTFSbits = 0; if (caccess & ISC_FSACCESS_READ) NTFSbits |= FILE_GENERIC_READ; if (caccess & ISC_FSACCESS_WRITE) NTFSbits |= FILE_GENERIC_WRITE; if (caccess & ISC_FSACCESS_EXECUTE) NTFSbits |= FILE_GENERIC_EXECUTE; /* For directories check the directory-specific bits */ if (isdir == ISC_TRUE) { if (caccess & ISC_FSACCESS_CREATECHILD) NTFSbits |= FILE_ADD_SUBDIRECTORY | FILE_ADD_FILE; if (caccess & ISC_FSACCESS_DELETECHILD) NTFSbits |= FILE_DELETE_CHILD; if (caccess & ISC_FSACCESS_LISTDIRECTORY) NTFSbits |= FILE_LIST_DIRECTORY; if (caccess & ISC_FSACCESS_ACCESSCHILD) NTFSbits |= FILE_TRAVERSE; } if (NTFSbits == (FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE)) NTFSbits |= FILE_ALL_ACCESS; /* * Owner and Administrator also get STANDARD_RIGHTS_ALL * to ensure that they have full control */ NTFSbits |= STANDARD_RIGHTS_ALL; /* Add the ACE to the ACL */ if (!AddAccessAllowedAce(pacl, ACL_REVISION, NTFSbits, psid)) return (ISC_R_NOPERM); if (!AddAccessAllowedAce(pacl, ACL_REVISION, NTFSbits, padminsid)) return (ISC_R_NOPERM); /* * Group is ignored since we can be in multiple groups or no group * and its meaning is not clear on Win32 */ caccess = caccess >> STEP; /* * Other check. We translate this to be the same as Everyone */ caccess = caccess >> STEP; NTFSbits = 0; if (caccess & ISC_FSACCESS_READ) NTFSbits |= FILE_GENERIC_READ; if (caccess & ISC_FSACCESS_WRITE) NTFSbits |= FILE_GENERIC_WRITE; if (caccess & ISC_FSACCESS_EXECUTE) NTFSbits |= FILE_GENERIC_EXECUTE; /* For directories check the directory-specific bits */ if (isdir == TRUE) { if (caccess & ISC_FSACCESS_CREATECHILD) NTFSbits |= FILE_ADD_SUBDIRECTORY | FILE_ADD_FILE; if (caccess & ISC_FSACCESS_DELETECHILD) NTFSbits |= FILE_DELETE_CHILD; if (caccess & ISC_FSACCESS_LISTDIRECTORY) NTFSbits |= FILE_LIST_DIRECTORY; if (caccess & ISC_FSACCESS_ACCESSCHILD) NTFSbits |= FILE_TRAVERSE; } /* Add the ACE to the ACL */ if (!AddAccessAllowedAce(pacl, ACL_REVISION, NTFSbits, pothersid)) return (ISC_R_NOPERM); if (!SetSecurityDescriptorDacl(&sd, TRUE, pacl, FALSE)) return (ISC_R_NOPERM); if (!SetFileSecurity(filename, DACL_SECURITY_INFORMATION, &sd)) { return (ISC_R_NOPERM); } return(ISC_R_SUCCESS); } isc_result_t NTFS_fsaccess_set(const char *path, isc_fsaccess_t access, isc_boolean_t isdir){ /* * For NTFS we first need to get the name of the account under * which BIND is running */ if (namelen == 0) { namelen = sizeof(username); if (GetUserName(username, &namelen) == 0) return (ISC_R_FAILURE); } return (NTFS_Access_Control(path, username, access, isdir)); } isc_result_t isc_fsaccess_set(const char *path, isc_fsaccess_t access) { struct stat statb; isc_boolean_t is_dir = ISC_FALSE; isc_result_t result; if (stat(path, &statb) != 0) return (isc__errno2result(errno)); if ((statb.st_mode & S_IFDIR) != 0) is_dir = ISC_TRUE; else if ((statb.st_mode & S_IFREG) == 0) return (ISC_R_INVALIDFILE); result = check_bad_bits(access, is_dir); if (result != ISC_R_SUCCESS) return (result); /* * Determine if this is a FAT or NTFS disk and * call the appropriate function to set the permissions */ if (is_ntfs(path)) return (NTFS_fsaccess_set(path, access, is_dir)); else return (FAT_fsaccess_set(path, access)); } isc_result_t isc_fsaccess_changeowner(const char *filename, const char *user) { SECURITY_DESCRIPTOR psd; BYTE sidBuffer[500]; BYTE groupBuffer[500]; PSID psid=(PSID) &sidBuffer; DWORD sidBufferSize = sizeof(sidBuffer); char domainBuffer[100]; DWORD domainBufferSize = sizeof(domainBuffer); SID_NAME_USE snu; PSID pSidGroup = (PSID) &groupBuffer; DWORD groupBufferSize = sizeof(groupBuffer); /* * Determine if this is a FAT or NTFS disk and * call the appropriate function to set the ownership * FAT disks do not have ownership attributes so it's * a noop. */ if (is_ntfs(filename) == FALSE) return (ISC_R_SUCCESS); if (!InitializeSecurityDescriptor(&psd, SECURITY_DESCRIPTOR_REVISION)) return (ISC_R_NOPERM); if (!LookupAccountName(0, user, psid, &sidBufferSize, domainBuffer, &domainBufferSize, &snu)) return (ISC_R_NOPERM); /* Make sure administrators can get to it */ domainBufferSize = sizeof(domainBuffer); if (!LookupAccountName(0, "Administrators", pSidGroup, &groupBufferSize, domainBuffer, &domainBufferSize, &snu)) return (ISC_R_NOPERM); if (!SetSecurityDescriptorOwner(&psd, psid, FALSE)) return (ISC_R_NOPERM); if (!SetSecurityDescriptorGroup(&psd, pSidGroup, FALSE)) return (ISC_R_NOPERM); if (!SetFileSecurity(filename, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION, &psd)) return (ISC_R_NOPERM); return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/isc/win32/time.c0000644000470500017500000002072212664710322016764 0ustar lamontlamont/* * Copyright (C) 2004, 2006-2009, 2012-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: time.c,v 1.52 2009/08/14 07:51:08 marka Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include /* * struct FILETIME uses "100-nanoseconds intervals". * NS / S = 1000000000 (10^9). * While it is reasonably obvious that this makes the needed * conversion factor 10^7, it is coded this way for additional clarity. */ #define NS_PER_S 1000000000 #define NS_INTERVAL 100 #define INTERVALS_PER_S (NS_PER_S / NS_INTERVAL) #define UINT64_MAX _UI64_MAX /*** *** Absolute Times ***/ static const isc_time_t epoch = { { 0, 0 } }; LIBISC_EXTERNAL_DATA const isc_time_t * const isc_time_epoch = &epoch; /*** *** Intervals ***/ static const isc_interval_t zero_interval = { 0 }; LIBISC_EXTERNAL_DATA const isc_interval_t * const isc_interval_zero = &zero_interval; void isc_interval_set(isc_interval_t *i, unsigned int seconds, unsigned int nanoseconds) { REQUIRE(i != NULL); REQUIRE(nanoseconds < NS_PER_S); /* * This rounds nanoseconds up not down. */ i->interval = (LONGLONG)seconds * INTERVALS_PER_S + (nanoseconds + NS_INTERVAL - 1) / NS_INTERVAL; } isc_boolean_t isc_interval_iszero(const isc_interval_t *i) { REQUIRE(i != NULL); if (i->interval == 0) return (ISC_TRUE); return (ISC_FALSE); } void isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) { SYSTEMTIME epoch = { 1970, 1, 4, 1, 0, 0, 0, 0 }; FILETIME temp; ULARGE_INTEGER i1; REQUIRE(t != NULL); REQUIRE(nanoseconds < NS_PER_S); SystemTimeToFileTime(&epoch, &temp); i1.LowPart = temp.dwLowDateTime; i1.HighPart = temp.dwHighDateTime; i1.QuadPart += (unsigned __int64)nanoseconds/100; i1.QuadPart += (unsigned __int64)seconds*10000000; t->absolute.dwLowDateTime = i1.LowPart; t->absolute.dwHighDateTime = i1.HighPart; } void isc_time_settoepoch(isc_time_t *t) { REQUIRE(t != NULL); t->absolute.dwLowDateTime = 0; t->absolute.dwHighDateTime = 0; } isc_boolean_t isc_time_isepoch(const isc_time_t *t) { REQUIRE(t != NULL); if (t->absolute.dwLowDateTime == 0 && t->absolute.dwHighDateTime == 0) return (ISC_TRUE); return (ISC_FALSE); } isc_result_t isc_time_now(isc_time_t *t) { REQUIRE(t != NULL); GetSystemTimeAsFileTime(&t->absolute); return (ISC_R_SUCCESS); } isc_result_t isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i) { ULARGE_INTEGER i1; REQUIRE(t != NULL); REQUIRE(i != NULL); GetSystemTimeAsFileTime(&t->absolute); i1.LowPart = t->absolute.dwLowDateTime; i1.HighPart = t->absolute.dwHighDateTime; if (UINT64_MAX - i1.QuadPart < (unsigned __int64)i->interval) return (ISC_R_RANGE); i1.QuadPart += i->interval; t->absolute.dwLowDateTime = i1.LowPart; t->absolute.dwHighDateTime = i1.HighPart; return (ISC_R_SUCCESS); } int isc_time_compare(const isc_time_t *t1, const isc_time_t *t2) { REQUIRE(t1 != NULL && t2 != NULL); return ((int)CompareFileTime(&t1->absolute, &t2->absolute)); } isc_result_t isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result) { ULARGE_INTEGER i1; REQUIRE(t != NULL && i != NULL && result != NULL); i1.LowPart = t->absolute.dwLowDateTime; i1.HighPart = t->absolute.dwHighDateTime; if (UINT64_MAX - i1.QuadPart < (unsigned __int64)i->interval) return (ISC_R_RANGE); i1.QuadPart += i->interval; result->absolute.dwLowDateTime = i1.LowPart; result->absolute.dwHighDateTime = i1.HighPart; return (ISC_R_SUCCESS); } isc_result_t isc_time_subtract(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result) { ULARGE_INTEGER i1; REQUIRE(t != NULL && i != NULL && result != NULL); i1.LowPart = t->absolute.dwLowDateTime; i1.HighPart = t->absolute.dwHighDateTime; if (i1.QuadPart < (unsigned __int64) i->interval) return (ISC_R_RANGE); i1.QuadPart -= i->interval; result->absolute.dwLowDateTime = i1.LowPart; result->absolute.dwHighDateTime = i1.HighPart; return (ISC_R_SUCCESS); } isc_uint64_t isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2) { ULARGE_INTEGER i1, i2; LONGLONG i3; REQUIRE(t1 != NULL && t2 != NULL); i1.LowPart = t1->absolute.dwLowDateTime; i1.HighPart = t1->absolute.dwHighDateTime; i2.LowPart = t2->absolute.dwLowDateTime; i2.HighPart = t2->absolute.dwHighDateTime; if (i1.QuadPart <= i2.QuadPart) return (0); /* * Convert to microseconds. */ i3 = (i1.QuadPart - i2.QuadPart) / 10; return (i3); } isc_uint32_t isc_time_seconds(const isc_time_t *t) { SYSTEMTIME epoch = { 1970, 1, 4, 1, 0, 0, 0, 0 }; FILETIME temp; ULARGE_INTEGER i1, i2; LONGLONG i3; SystemTimeToFileTime(&epoch, &temp); i1.LowPart = t->absolute.dwLowDateTime; i1.HighPart = t->absolute.dwHighDateTime; i2.LowPart = temp.dwLowDateTime; i2.HighPart = temp.dwHighDateTime; i3 = (i1.QuadPart - i2.QuadPart) / 10000000; return ((isc_uint32_t)i3); } isc_result_t isc_time_secondsastimet(const isc_time_t *t, time_t *secondsp) { time_t seconds; REQUIRE(t != NULL); seconds = (time_t)isc_time_seconds(t); INSIST(sizeof(unsigned int) == sizeof(isc_uint32_t)); INSIST(sizeof(time_t) >= sizeof(isc_uint32_t)); if (isc_time_seconds(t) > (~0U>>1) && seconds <= (time_t)(~0U>>1)) return (ISC_R_RANGE); *secondsp = seconds; return (ISC_R_SUCCESS); } isc_uint32_t isc_time_nanoseconds(const isc_time_t *t) { ULARGE_INTEGER i; i.LowPart = t->absolute.dwLowDateTime; i.HighPart = t->absolute.dwHighDateTime; return ((isc_uint32_t)(i.QuadPart % 10000000) * 100); } void isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len) { FILETIME localft; SYSTEMTIME st; char DateBuf[50]; char TimeBuf[50]; static const char badtime[] = "99-Bad-9999 99:99:99.999"; REQUIRE(len > 0); if (FileTimeToLocalFileTime(&t->absolute, &localft) && FileTimeToSystemTime(&localft, &st)) { GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, "dd-MMM-yyyy", DateBuf, 50); GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOTIMEMARKER| TIME_FORCE24HOURFORMAT, &st, NULL, TimeBuf, 50); snprintf(buf, len, "%s %s.%03u", DateBuf, TimeBuf, st.wMilliseconds); } else snprintf(buf, len, badtime); } void isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len) { SYSTEMTIME st; char DateBuf[50]; char TimeBuf[50]; /* strftime() format: "%a, %d %b %Y %H:%M:%S GMT" */ REQUIRE(len > 0); if (FileTimeToSystemTime(&t->absolute, &st)) { GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, "ddd',' dd MMM yyyy", DateBuf, 50); GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &st, "hh':'mm':'ss", TimeBuf, 50); snprintf(buf, len, "%s %s GMT", DateBuf, TimeBuf); } else { buf[0] = 0; } } isc_result_t isc_time_parsehttptimestamp(char *buf, isc_time_t *t) { struct tm t_tm; time_t when; char *p; REQUIRE(buf != NULL); REQUIRE(t != NULL); p = isc_tm_strptime(buf, "%a, %d %b %Y %H:%M:%S", &t_tm); if (p == NULL) return (ISC_R_UNEXPECTED); when = isc_tm_timegm(&t_tm); if (when == -1) return (ISC_R_UNEXPECTED); isc_time_set(t, (unsigned int)when, 0); return (ISC_R_SUCCESS); } void isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len) { SYSTEMTIME st; char DateBuf[50]; char TimeBuf[50]; /* strtime() format: "%Y-%m-%dT%H:%M:%SZ" */ REQUIRE(len > 0); if (FileTimeToSystemTime(&t->absolute, &st)) { GetDateFormat(LOCALE_NEUTRAL, 0, &st, "yyyy-MM-dd", DateBuf, 50); GetTimeFormat(LOCALE_NEUTRAL, TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &st, "hh':'mm':'ss", TimeBuf, 50); snprintf(buf, len, "%sT%sZ", DateBuf, TimeBuf); } else { buf[0] = 0; } } bind9-9.10.3.dfsg.P4/lib/isc/win32/libisc.dsw0000644000470500017500000000103112664710322017636 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "libisc"=".\libisc.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/lib/isc/stats.c0000644000470500017500000002173012664710322016222 0ustar lamontlamont/* * Copyright (C) 2009, 2012-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #define ISC_STATS_MAGIC ISC_MAGIC('S', 't', 'a', 't') #define ISC_STATS_VALID(x) ISC_MAGIC_VALID(x, ISC_STATS_MAGIC) #ifndef ISC_STATS_USEMULTIFIELDS #if defined(ISC_RWLOCK_USEATOMIC) && defined(ISC_PLATFORM_HAVEXADD) && !defined(ISC_PLATFORM_HAVEXADDQ) #define ISC_STATS_USEMULTIFIELDS 1 #else #define ISC_STATS_USEMULTIFIELDS 0 #endif #endif /* ISC_STATS_USEMULTIFIELDS */ #if ISC_STATS_USEMULTIFIELDS typedef struct { isc_uint32_t hi; isc_uint32_t lo; } isc_stat_t; #else typedef isc_uint64_t isc_stat_t; #endif struct isc_stats { /*% Unlocked */ unsigned int magic; isc_mem_t *mctx; int ncounters; isc_mutex_t lock; unsigned int references; /* locked by lock */ /*% * Locked by counterlock or unlocked if efficient rwlock is not * available. */ #ifdef ISC_RWLOCK_USEATOMIC isc_rwlock_t counterlock; #endif isc_stat_t *counters; /*% * We don't want to lock the counters while we are dumping, so we first * copy the current counter values into a local array. This buffer * will be used as the copy destination. It's allocated on creation * of the stats structure so that the dump operation won't fail due * to memory allocation failure. * XXX: this approach is weird for non-threaded build because the * additional memory and the copy overhead could be avoided. We prefer * simplicity here, however, under the assumption that this function * should be only rarely called. */ isc_uint64_t *copiedcounters; }; static isc_result_t create_stats(isc_mem_t *mctx, int ncounters, isc_stats_t **statsp) { isc_stats_t *stats; isc_result_t result = ISC_R_SUCCESS; REQUIRE(statsp != NULL && *statsp == NULL); stats = isc_mem_get(mctx, sizeof(*stats)); if (stats == NULL) return (ISC_R_NOMEMORY); result = isc_mutex_init(&stats->lock); if (result != ISC_R_SUCCESS) goto clean_stats; stats->counters = isc_mem_get(mctx, sizeof(isc_stat_t) * ncounters); if (stats->counters == NULL) { result = ISC_R_NOMEMORY; goto clean_mutex; } stats->copiedcounters = isc_mem_get(mctx, sizeof(isc_uint64_t) * ncounters); if (stats->copiedcounters == NULL) { result = ISC_R_NOMEMORY; goto clean_counters; } #ifdef ISC_RWLOCK_USEATOMIC result = isc_rwlock_init(&stats->counterlock, 0, 0); if (result != ISC_R_SUCCESS) goto clean_copiedcounters; #endif stats->references = 1; memset(stats->counters, 0, sizeof(isc_stat_t) * ncounters); stats->mctx = NULL; isc_mem_attach(mctx, &stats->mctx); stats->ncounters = ncounters; stats->magic = ISC_STATS_MAGIC; *statsp = stats; return (result); clean_counters: isc_mem_put(mctx, stats->counters, sizeof(isc_stat_t) * ncounters); #ifdef ISC_RWLOCK_USEATOMIC clean_copiedcounters: isc_mem_put(mctx, stats->copiedcounters, sizeof(isc_stat_t) * ncounters); #endif clean_mutex: DESTROYLOCK(&stats->lock); clean_stats: isc_mem_put(mctx, stats, sizeof(*stats)); return (result); } void isc_stats_attach(isc_stats_t *stats, isc_stats_t **statsp) { REQUIRE(ISC_STATS_VALID(stats)); REQUIRE(statsp != NULL && *statsp == NULL); LOCK(&stats->lock); stats->references++; UNLOCK(&stats->lock); *statsp = stats; } void isc_stats_detach(isc_stats_t **statsp) { isc_stats_t *stats; REQUIRE(statsp != NULL && ISC_STATS_VALID(*statsp)); stats = *statsp; *statsp = NULL; LOCK(&stats->lock); stats->references--; if (stats->references == 0) { isc_mem_put(stats->mctx, stats->copiedcounters, sizeof(isc_stat_t) * stats->ncounters); isc_mem_put(stats->mctx, stats->counters, sizeof(isc_stat_t) * stats->ncounters); UNLOCK(&stats->lock); DESTROYLOCK(&stats->lock); #ifdef ISC_RWLOCK_USEATOMIC isc_rwlock_destroy(&stats->counterlock); #endif isc_mem_putanddetach(&stats->mctx, stats, sizeof(*stats)); return; } UNLOCK(&stats->lock); } int isc_stats_ncounters(isc_stats_t *stats) { REQUIRE(ISC_STATS_VALID(stats)); return (stats->ncounters); } static inline void incrementcounter(isc_stats_t *stats, int counter) { isc_int32_t prev; #ifdef ISC_RWLOCK_USEATOMIC /* * We use a "read" lock to prevent other threads from reading the * counter while we "writing" a counter field. The write access itself * is protected by the atomic operation. */ isc_rwlock_lock(&stats->counterlock, isc_rwlocktype_read); #endif #if ISC_STATS_USEMULTIFIELDS prev = isc_atomic_xadd((isc_int32_t *)&stats->counters[counter].lo, 1); /* * If the lower 32-bit field overflows, increment the higher field. * Note that it's *theoretically* possible that the lower field * overlaps again before the higher field is incremented. It doesn't * matter, however, because we don't read the value until * isc_stats_copy() is called where the whole process is protected * by the write (exclusive) lock. */ if (prev == (isc_int32_t)0xffffffff) isc_atomic_xadd((isc_int32_t *)&stats->counters[counter].hi, 1); #elif defined(ISC_PLATFORM_HAVEXADDQ) UNUSED(prev); isc_atomic_xaddq((isc_int64_t *)&stats->counters[counter], 1); #else UNUSED(prev); stats->counters[counter]++; #endif #ifdef ISC_RWLOCK_USEATOMIC isc_rwlock_unlock(&stats->counterlock, isc_rwlocktype_read); #endif } static inline void decrementcounter(isc_stats_t *stats, int counter) { isc_int32_t prev; #ifdef ISC_RWLOCK_USEATOMIC isc_rwlock_lock(&stats->counterlock, isc_rwlocktype_read); #endif #if ISC_STATS_USEMULTIFIELDS prev = isc_atomic_xadd((isc_int32_t *)&stats->counters[counter].lo, -1); if (prev == 0) isc_atomic_xadd((isc_int32_t *)&stats->counters[counter].hi, -1); #elif defined(ISC_PLATFORM_HAVEXADDQ) UNUSED(prev); isc_atomic_xaddq((isc_int64_t *)&stats->counters[counter], -1); #else UNUSED(prev); stats->counters[counter]--; #endif #ifdef ISC_RWLOCK_USEATOMIC isc_rwlock_unlock(&stats->counterlock, isc_rwlocktype_read); #endif } static void copy_counters(isc_stats_t *stats) { int i; #ifdef ISC_RWLOCK_USEATOMIC /* * We use a "write" lock before "reading" the statistics counters as * an exclusive lock. */ isc_rwlock_lock(&stats->counterlock, isc_rwlocktype_write); #endif #if ISC_STATS_USEMULTIFIELDS for (i = 0; i < stats->ncounters; i++) { stats->copiedcounters[i] = (isc_uint64_t)(stats->counters[i].hi) << 32 | stats->counters[i].lo; } #else UNUSED(i); memmove(stats->copiedcounters, stats->counters, stats->ncounters * sizeof(isc_stat_t)); #endif #ifdef ISC_RWLOCK_USEATOMIC isc_rwlock_unlock(&stats->counterlock, isc_rwlocktype_write); #endif } isc_result_t isc_stats_create(isc_mem_t *mctx, isc_stats_t **statsp, int ncounters) { REQUIRE(statsp != NULL && *statsp == NULL); return (create_stats(mctx, ncounters, statsp)); } void isc_stats_increment(isc_stats_t *stats, isc_statscounter_t counter) { REQUIRE(ISC_STATS_VALID(stats)); REQUIRE(counter < stats->ncounters); incrementcounter(stats, (int)counter); } void isc_stats_decrement(isc_stats_t *stats, isc_statscounter_t counter) { REQUIRE(ISC_STATS_VALID(stats)); REQUIRE(counter < stats->ncounters); decrementcounter(stats, (int)counter); } void isc_stats_dump(isc_stats_t *stats, isc_stats_dumper_t dump_fn, void *arg, unsigned int options) { int i; REQUIRE(ISC_STATS_VALID(stats)); copy_counters(stats); for (i = 0; i < stats->ncounters; i++) { if ((options & ISC_STATSDUMP_VERBOSE) == 0 && stats->copiedcounters[i] == 0) continue; dump_fn((isc_statscounter_t)i, stats->copiedcounters[i], arg); } } void isc_stats_set(isc_stats_t *stats, isc_uint64_t val, isc_statscounter_t counter) { REQUIRE(ISC_STATS_VALID(stats)); REQUIRE(counter < stats->ncounters); #ifdef ISC_RWLOCK_USEATOMIC /* * We use a "write" lock before "reading" the statistics counters as * an exclusive lock. */ isc_rwlock_lock(&stats->counterlock, isc_rwlocktype_write); #endif #if ISC_STATS_USEMULTIFIELDS stats->counters[counter].hi = (isc_uint32_t)((val >> 32) & 0xffffffff); stats->counters[counter].lo = (isc_uint32_t)(val & 0xffffffff); #else stats->counters[counter] = val; #endif #ifdef ISC_RWLOCK_USEATOMIC isc_rwlock_unlock(&stats->counterlock, isc_rwlocktype_write); #endif } bind9-9.10.3.dfsg.P4/lib/isc/radix.c0000644000470500017500000004204012664710322016170 0ustar lamontlamont/* * Copyright (C) 2007-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* * This source was adapted from MRT's RCS Ids: * Id: radix.c,v 1.10.2.1 1999/11/29 05:16:24 masaki Exp * Id: prefix.c,v 1.37.2.9 2000/03/10 02:53:19 labovit Exp */ #include #include #include #include #include static isc_result_t _new_prefix(isc_mem_t *mctx, isc_prefix_t **target, int family, void *dest, int bitlen); static void _deref_prefix(isc_prefix_t *prefix); static isc_result_t _ref_prefix(isc_mem_t *mctx, isc_prefix_t **target, isc_prefix_t *prefix); static int _comp_with_mask(void *addr, void *dest, u_int mask); static void _clear_radix(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func); static isc_result_t _new_prefix(isc_mem_t *mctx, isc_prefix_t **target, int family, void *dest, int bitlen) { isc_prefix_t *prefix; REQUIRE(target != NULL); if (family != AF_INET6 && family != AF_INET && family != AF_UNSPEC) return (ISC_R_NOTIMPLEMENTED); prefix = isc_mem_get(mctx, sizeof(isc_prefix_t)); if (prefix == NULL) return (ISC_R_NOMEMORY); if (family == AF_INET6) { prefix->bitlen = (bitlen >= 0) ? bitlen : 128; memmove(&prefix->add.sin6, dest, 16); } else { /* AF_UNSPEC is "any" or "none"--treat it as AF_INET */ prefix->bitlen = (bitlen >= 0) ? bitlen : 32; memmove(&prefix->add.sin, dest, 4); } prefix->family = family; prefix->mctx = NULL; isc_mem_attach(mctx, &prefix->mctx); isc_refcount_init(&prefix->refcount, 1); *target = prefix; return (ISC_R_SUCCESS); } static void _deref_prefix(isc_prefix_t *prefix) { int refs; if (prefix == NULL) return; isc_refcount_decrement(&prefix->refcount, &refs); if (refs <= 0) { isc_refcount_destroy(&prefix->refcount); isc_mem_putanddetach(&prefix->mctx, prefix, sizeof(isc_prefix_t)); } } static isc_result_t _ref_prefix(isc_mem_t *mctx, isc_prefix_t **target, isc_prefix_t *prefix) { INSIST(prefix != NULL); INSIST((prefix->family == AF_INET && prefix->bitlen <= 32) || (prefix->family == AF_INET6 && prefix->bitlen <= 128) || (prefix->family == AF_UNSPEC && prefix->bitlen == 0)); REQUIRE(target != NULL && *target == NULL); /* * If this prefix is a static allocation, copy it into new memory. * (Note, the refcount still has to be destroyed by the calling * routine.) */ if (isc_refcount_current(&prefix->refcount) == 0) { isc_result_t ret; ret = _new_prefix(mctx, target, prefix->family, &prefix->add, prefix->bitlen); return (ret); } isc_refcount_increment(&prefix->refcount, NULL); *target = prefix; return (ISC_R_SUCCESS); } static int _comp_with_mask(void *addr, void *dest, u_int mask) { /* Mask length of zero matches everything */ if (mask == 0) return (1); if (memcmp(addr, dest, mask / 8) == 0) { int n = mask / 8; int m = ((~0) << (8 - (mask % 8))); if ((mask % 8) == 0 || (((u_char *)addr)[n] & m) == (((u_char *)dest)[n] & m)) return (1); } return (0); } isc_result_t isc_radix_create(isc_mem_t *mctx, isc_radix_tree_t **target, int maxbits) { isc_radix_tree_t *radix; REQUIRE(target != NULL && *target == NULL); radix = isc_mem_get(mctx, sizeof(isc_radix_tree_t)); if (radix == NULL) return (ISC_R_NOMEMORY); radix->mctx = NULL; isc_mem_attach(mctx, &radix->mctx); radix->maxbits = maxbits; radix->head = NULL; radix->num_active_node = 0; radix->num_added_node = 0; RUNTIME_CHECK(maxbits <= RADIX_MAXBITS); /* XXX */ radix->magic = RADIX_TREE_MAGIC; *target = radix; return (ISC_R_SUCCESS); } /* * if func is supplied, it will be called as func(node->data) * before deleting the node */ static void _clear_radix(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func) { REQUIRE(radix != NULL); if (radix->head != NULL) { isc_radix_node_t *Xstack[RADIX_MAXBITS+1]; isc_radix_node_t **Xsp = Xstack; isc_radix_node_t *Xrn = radix->head; while (Xrn != NULL) { isc_radix_node_t *l = Xrn->l; isc_radix_node_t *r = Xrn->r; if (Xrn->prefix != NULL) { _deref_prefix(Xrn->prefix); if (func != NULL && (Xrn->data[0] != NULL || Xrn->data[1] != NULL)) func(Xrn->data); } else { INSIST(Xrn->data[0] == NULL && Xrn->data[1] == NULL); } isc_mem_put(radix->mctx, Xrn, sizeof(*Xrn)); radix->num_active_node--; if (l != NULL) { if (r != NULL) { *Xsp++ = r; } Xrn = l; } else if (r != NULL) { Xrn = r; } else if (Xsp != Xstack) { Xrn = *(--Xsp); } else { Xrn = NULL; } } } RUNTIME_CHECK(radix->num_active_node == 0); } void isc_radix_destroy(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func) { REQUIRE(radix != NULL); _clear_radix(radix, func); isc_mem_putanddetach(&radix->mctx, radix, sizeof(*radix)); } /* * func will be called as func(node->prefix, node->data) */ void isc_radix_process(isc_radix_tree_t *radix, isc_radix_processfunc_t func) { isc_radix_node_t *node; REQUIRE(func != NULL); RADIX_WALK(radix->head, node) { func(node->prefix, node->data); } RADIX_WALK_END; } isc_result_t isc_radix_search(isc_radix_tree_t *radix, isc_radix_node_t **target, isc_prefix_t *prefix) { isc_radix_node_t *node; isc_radix_node_t *stack[RADIX_MAXBITS + 1]; u_char *addr; isc_uint32_t bitlen; int tfamily = -1; int cnt = 0; REQUIRE(radix != NULL); REQUIRE(prefix != NULL); REQUIRE(target != NULL && *target == NULL); RUNTIME_CHECK(prefix->bitlen <= radix->maxbits); *target = NULL; if (radix->head == NULL) { return (ISC_R_NOTFOUND); } node = radix->head; addr = isc_prefix_touchar(prefix); bitlen = prefix->bitlen; while (node->bit < bitlen) { if (node->prefix) stack[cnt++] = node; if (BIT_TEST(addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) node = node->r; else node = node->l; if (node == NULL) break; } if (node && node->prefix) stack[cnt++] = node; while (cnt-- > 0) { node = stack[cnt]; if (prefix->bitlen < node->bit) continue; if (_comp_with_mask(isc_prefix_tochar(node->prefix), isc_prefix_tochar(prefix), node->prefix->bitlen)) { if (node->node_num[ISC_IS6(prefix->family)] != -1 && ((*target == NULL) || (*target)->node_num[ISC_IS6(tfamily)] > node->node_num[ISC_IS6(prefix->family)])) { *target = node; tfamily = prefix->family; } } } if (*target == NULL) { return (ISC_R_NOTFOUND); } else { return (ISC_R_SUCCESS); } } isc_result_t isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, isc_radix_node_t *source, isc_prefix_t *prefix) { isc_radix_node_t *node, *new_node, *parent, *glue = NULL; u_char *addr, *test_addr; isc_uint32_t bitlen, fam, check_bit, differ_bit; isc_uint32_t i, j, r; isc_result_t result; REQUIRE(radix != NULL); REQUIRE(target != NULL && *target == NULL); REQUIRE(prefix != NULL || (source != NULL && source->prefix != NULL)); RUNTIME_CHECK(prefix == NULL || prefix->bitlen <= radix->maxbits); if (prefix == NULL) prefix = source->prefix; INSIST(prefix != NULL); bitlen = prefix->bitlen; fam = prefix->family; if (radix->head == NULL) { node = isc_mem_get(radix->mctx, sizeof(isc_radix_node_t)); if (node == NULL) return (ISC_R_NOMEMORY); node->bit = bitlen; node->node_num[0] = node->node_num[1] = -1; node->prefix = NULL; result = _ref_prefix(radix->mctx, &node->prefix, prefix); if (result != ISC_R_SUCCESS) { isc_mem_put(radix->mctx, node, sizeof(isc_radix_node_t)); return (result); } node->parent = NULL; node->l = node->r = NULL; if (source != NULL) { /* * If source is non-NULL, then we're merging in a * node from an existing radix tree. To keep * the node_num values consistent, the calling * function will add the total number of nodes * added to num_added_node at the end of * the merge operation--we don't do it here. */ if (source->node_num[0] != -1) node->node_num[0] = radix->num_added_node + source->node_num[0]; if (source->node_num[1] != -1) node->node_num[1] = radix->num_added_node + source->node_num[1]; node->data[0] = source->data[0]; node->data[1] = source->data[1]; } else { if (fam == AF_UNSPEC) { /* "any" or "none" */ node->node_num[0] = node->node_num[1] = ++radix->num_added_node; } else { node->node_num[ISC_IS6(fam)] = ++radix->num_added_node; } node->data[0] = NULL; node->data[1] = NULL; } radix->head = node; radix->num_active_node++; *target = node; return (ISC_R_SUCCESS); } addr = isc_prefix_touchar(prefix); node = radix->head; while (node->bit < bitlen || node->prefix == NULL) { if (node->bit < radix->maxbits && BIT_TEST(addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) { if (node->r == NULL) break; node = node->r; } else { if (node->l == NULL) break; node = node->l; } INSIST(node != NULL); } INSIST(node->prefix != NULL); test_addr = isc_prefix_touchar(node->prefix); /* Find the first bit different. */ check_bit = (node->bit < bitlen) ? node->bit : bitlen; differ_bit = 0; for (i = 0; i*8 < check_bit; i++) { if ((r = (addr[i] ^ test_addr[i])) == 0) { differ_bit = (i + 1) * 8; continue; } /* I know the better way, but for now. */ for (j = 0; j < 8; j++) { if (BIT_TEST (r, (0x80 >> j))) break; } /* Must be found. */ INSIST(j < 8); differ_bit = i * 8 + j; break; } if (differ_bit > check_bit) differ_bit = check_bit; parent = node->parent; while (parent != NULL && parent->bit >= differ_bit) { node = parent; parent = node->parent; } if (differ_bit == bitlen && node->bit == bitlen) { if (node->prefix != NULL) { /* Set node_num only if it hasn't been set before */ if (source != NULL) { /* Merging node */ if (node->node_num[0] == -1 && source->node_num[0] != -1) { node->node_num[0] = radix->num_added_node + source->node_num[0]; node->data[0] = source->data[0]; } if (node->node_num[1] == -1 && source->node_num[0] != -1) { node->node_num[1] = radix->num_added_node + source->node_num[1]; node->data[1] = source->data[1]; } } else { if (fam == AF_UNSPEC) { /* "any" or "none" */ int next = radix->num_added_node + 1; if (node->node_num[0] == -1) { node->node_num[0] = next; radix->num_added_node = next; } if (node->node_num[1] == -1) { node->node_num[1] = next; radix->num_added_node = next; } } else { if (node->node_num[ISC_IS6(fam)] == -1) node->node_num[ISC_IS6(fam)] = ++radix->num_added_node; } } *target = node; return (ISC_R_SUCCESS); } else { result = _ref_prefix(radix->mctx, &node->prefix, prefix); if (result != ISC_R_SUCCESS) return (result); } INSIST(node->data[0] == NULL && node->node_num[0] == -1 && node->data[1] == NULL && node->node_num[1] == -1); if (source != NULL) { /* Merging node */ if (source->node_num[0] != -1) { node->node_num[0] = radix->num_added_node + source->node_num[0]; node->data[0] = source->data[0]; } if (source->node_num[1] != -1) { node->node_num[1] = radix->num_added_node + source->node_num[1]; node->data[1] = source->data[1]; } } else { if (fam == AF_UNSPEC) { /* "any" or "none" */ node->node_num[0] = node->node_num[1] = ++radix->num_added_node; } else { node->node_num[ISC_IS6(fam)] = ++radix->num_added_node; } } *target = node; return (ISC_R_SUCCESS); } new_node = isc_mem_get(radix->mctx, sizeof(isc_radix_node_t)); if (new_node == NULL) return (ISC_R_NOMEMORY); if (node->bit != differ_bit && bitlen != differ_bit) { glue = isc_mem_get(radix->mctx, sizeof(isc_radix_node_t)); if (glue == NULL) { isc_mem_put(radix->mctx, new_node, sizeof(isc_radix_node_t)); return (ISC_R_NOMEMORY); } } new_node->bit = bitlen; new_node->prefix = NULL; result = _ref_prefix(radix->mctx, &new_node->prefix, prefix); if (result != ISC_R_SUCCESS) { isc_mem_put(radix->mctx, new_node, sizeof(isc_radix_node_t)); if (glue != NULL) isc_mem_put(radix->mctx, glue, sizeof(isc_radix_node_t)); return (result); } new_node->parent = NULL; new_node->l = new_node->r = NULL; new_node->node_num[0] = new_node->node_num[1] = -1; radix->num_active_node++; if (source != NULL) { /* Merging node */ if (source->node_num[0] != -1) new_node->node_num[0] = radix->num_added_node + source->node_num[0]; if (source->node_num[1] != -1) new_node->node_num[1] = radix->num_added_node + source->node_num[1]; new_node->data[0] = source->data[0]; new_node->data[1] = source->data[1]; } else { if (fam == AF_UNSPEC) { /* "any" or "none" */ new_node->node_num[0] = new_node->node_num[1] = ++radix->num_added_node; } else { new_node->node_num[ISC_IS6(fam)] = ++radix->num_added_node; } new_node->data[0] = NULL; new_node->data[1] = NULL; } if (node->bit == differ_bit) { INSIST(glue == NULL); new_node->parent = node; if (node->bit < radix->maxbits && BIT_TEST(addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) { INSIST(node->r == NULL); node->r = new_node; } else { INSIST(node->l == NULL); node->l = new_node; } *target = new_node; return (ISC_R_SUCCESS); } if (bitlen == differ_bit) { INSIST(glue == NULL); if (bitlen < radix->maxbits && BIT_TEST(test_addr[bitlen >> 3], 0x80 >> (bitlen & 0x07))) { new_node->r = node; } else { new_node->l = node; } new_node->parent = node->parent; if (node->parent == NULL) { INSIST(radix->head == node); radix->head = new_node; } else if (node->parent->r == node) { node->parent->r = new_node; } else { node->parent->l = new_node; } node->parent = new_node; } else { INSIST(glue != NULL); glue->bit = differ_bit; glue->prefix = NULL; glue->parent = node->parent; glue->data[0] = glue->data[1] = NULL; glue->node_num[0] = glue->node_num[1] = -1; radix->num_active_node++; if (differ_bit < radix->maxbits && BIT_TEST(addr[differ_bit>>3], 0x80 >> (differ_bit & 07))) { glue->r = new_node; glue->l = node; } else { glue->r = node; glue->l = new_node; } new_node->parent = glue; if (node->parent == NULL) { INSIST(radix->head == node); radix->head = glue; } else if (node->parent->r == node) { node->parent->r = glue; } else { node->parent->l = glue; } node->parent = glue; } *target = new_node; return (ISC_R_SUCCESS); } void isc_radix_remove(isc_radix_tree_t *radix, isc_radix_node_t *node) { isc_radix_node_t *parent, *child; REQUIRE(radix != NULL); REQUIRE(node != NULL); if (node->r && node->l) { /* * This might be a placeholder node -- have to check and * make sure there is a prefix associated with it! */ if (node->prefix != NULL) _deref_prefix(node->prefix); node->prefix = NULL; node->data[0] = node->data[1] = NULL; return; } if (node->r == NULL && node->l == NULL) { parent = node->parent; _deref_prefix(node->prefix); if (parent == NULL) { INSIST(radix->head == node); radix->head = NULL; isc_mem_put(radix->mctx, node, sizeof(*node)); radix->num_active_node--; return; } if (parent->r == node) { parent->r = NULL; child = parent->l; } else { INSIST(parent->l == node); parent->l = NULL; child = parent->r; } isc_mem_put(radix->mctx, node, sizeof(*node)); radix->num_active_node--; if (parent->prefix) return; /* We need to remove parent too. */ if (parent->parent == NULL) { INSIST(radix->head == parent); radix->head = child; } else if (parent->parent->r == parent) { parent->parent->r = child; } else { INSIST(parent->parent->l == parent); parent->parent->l = child; } child->parent = parent->parent; isc_mem_put(radix->mctx, parent, sizeof(*parent)); radix->num_active_node--; return; } if (node->r) { child = node->r; } else { INSIST(node->l != NULL); child = node->l; } parent = node->parent; child->parent = parent; _deref_prefix(node->prefix); if (parent == NULL) { INSIST(radix->head == node); radix->head = child; isc_mem_put(radix->mctx, node, sizeof(*node)); radix->num_active_node--; return; } isc_mem_put(radix->mctx, node, sizeof(*node)); radix->num_active_node--; if (parent->r == node) { parent->r = child; } else { INSIST(parent->l == node); parent->l = child; } } /* Local Variables: c-basic-offset: 4 indent-tabs-mode: t End: */ bind9-9.10.3.dfsg.P4/lib/isc/md5.c0000644000470500017500000002335012664710322015551 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: md5.c,v 1.16 2009/02/06 23:47:42 tbox Exp $ */ /*! \file * This code implements the MD5 message-digest algorithm. * The algorithm is due to Ron Rivest. This code was * written by Colin Plumb in 1993, no copyright is claimed. * This code is in the public domain; do with it what you wish. * * Equivalent code is available from RSA Data Security, Inc. * This code has been tested against that, and is equivalent, * except that you don't need to include two pages of legalese * with every copy. * * To compute the message digest of a chunk of bytes, declare an * MD5Context structure, pass it to MD5Init, call MD5Update as * needed on buffers full of bytes, and then call MD5Final, which * will fill a supplied 16-byte array with the digest. */ #include "config.h" #include #include #include #include #include #if PKCS11CRYPTO #include #include #endif #include #ifdef ISC_PLATFORM_OPENSSLHASH void isc_md5_init(isc_md5_t *ctx) { RUNTIME_CHECK(EVP_DigestInit(ctx, EVP_md5()) == 1); } void isc_md5_invalidate(isc_md5_t *ctx) { EVP_MD_CTX_cleanup(ctx); } void isc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len) { RUNTIME_CHECK(EVP_DigestUpdate(ctx, (const void *) buf, (size_t) len) == 1); } void isc_md5_final(isc_md5_t *ctx, unsigned char *digest) { RUNTIME_CHECK(EVP_DigestFinal(ctx, digest, NULL) == 1); } #elif PKCS11CRYPTO void isc_md5_init(isc_md5_t *ctx) { CK_RV rv; CK_MECHANISM mech = { CKM_MD5, NULL, 0 }; RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech)); } void isc_md5_invalidate(isc_md5_t *ctx) { CK_BYTE garbage[ISC_MD5_DIGESTLENGTH]; CK_ULONG len = ISC_MD5_DIGESTLENGTH; if (ctx->handle == NULL) return; (void) pkcs_C_DigestFinal(ctx->session, garbage, &len); memset(garbage, 0, sizeof(garbage)); pk11_return_session(ctx); } void isc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len) { CK_RV rv; CK_BYTE_PTR pPart; DE_CONST(buf, pPart); PK11_FATALCHECK(pkcs_C_DigestUpdate, (ctx->session, pPart, (CK_ULONG) len)); } void isc_md5_final(isc_md5_t *ctx, unsigned char *digest) { CK_RV rv; CK_ULONG len = ISC_MD5_DIGESTLENGTH; PK11_FATALCHECK(pkcs_C_DigestFinal, (ctx->session, (CK_BYTE_PTR) digest, &len)); pk11_return_session(ctx); } #else static void byteSwap(isc_uint32_t *buf, unsigned words) { unsigned char *p = (unsigned char *)buf; do { *buf++ = (isc_uint32_t)((unsigned)p[3] << 8 | p[2]) << 16 | ((unsigned)p[1] << 8 | p[0]); p += 4; } while (--words); } /*! * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious * initialization constants. */ void isc_md5_init(isc_md5_t *ctx) { ctx->buf[0] = 0x67452301; ctx->buf[1] = 0xefcdab89; ctx->buf[2] = 0x98badcfe; ctx->buf[3] = 0x10325476; ctx->bytes[0] = 0; ctx->bytes[1] = 0; } void isc_md5_invalidate(isc_md5_t *ctx) { memset(ctx, 0, sizeof(isc_md5_t)); } /*@{*/ /*! The four core functions - F1 is optimized somewhat */ /* #define F1(x, y, z) (x & y | ~x & z) */ #define F1(x, y, z) (z ^ (x & (y ^ z))) #define F2(x, y, z) F1(z, x, y) #define F3(x, y, z) (x ^ y ^ z) #define F4(x, y, z) (y ^ (x | ~z)) /*@}*/ /*! This is the central step in the MD5 algorithm. */ #define MD5STEP(f,w,x,y,z,in,s) \ (w += f(x,y,z) + in, w = (w<>(32-s)) + x) /*! * The core of the MD5 algorithm, this alters an existing MD5 hash to * reflect the addition of 16 longwords of new data. MD5Update blocks * the data and converts bytes into longwords for this routine. */ static void transform(isc_uint32_t buf[4], isc_uint32_t const in[16]) { register isc_uint32_t a, b, c, d; a = buf[0]; b = buf[1]; c = buf[2]; d = buf[3]; MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); buf[0] += a; buf[1] += b; buf[2] += c; buf[3] += d; } /*! * Update context to reflect the concatenation of another buffer full * of bytes. */ void isc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len) { isc_uint32_t t; /* Update byte count */ t = ctx->bytes[0]; if ((ctx->bytes[0] = t + len) < t) ctx->bytes[1]++; /* Carry from low to high */ t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */ if (t > len) { memmove((unsigned char *)ctx->in + 64 - t, buf, len); return; } /* First chunk is an odd size */ memmove((unsigned char *)ctx->in + 64 - t, buf, t); byteSwap(ctx->in, 16); transform(ctx->buf, ctx->in); buf += t; len -= t; /* Process data in 64-byte chunks */ while (len >= 64) { memmove(ctx->in, buf, 64); byteSwap(ctx->in, 16); transform(ctx->buf, ctx->in); buf += 64; len -= 64; } /* Handle any remaining bytes of data. */ memmove(ctx->in, buf, len); } /*! * Final wrapup - pad to 64-byte boundary with the bit pattern * 1 0* (64-bit count of bits processed, MSB-first) */ void isc_md5_final(isc_md5_t *ctx, unsigned char *digest) { int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */ unsigned char *p = (unsigned char *)ctx->in + count; /* Set the first char of padding to 0x80. There is always room. */ *p++ = 0x80; /* Bytes of padding needed to make 56 bytes (-8..55) */ count = 56 - 1 - count; if (count < 0) { /* Padding forces an extra block */ memset(p, 0, count + 8); byteSwap(ctx->in, 16); transform(ctx->buf, ctx->in); p = (unsigned char *)ctx->in; count = 56; } memset(p, 0, count); byteSwap(ctx->in, 14); /* Append length in bits and transform */ ctx->in[14] = ctx->bytes[0] << 3; ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29; transform(ctx->buf, ctx->in); byteSwap(ctx->buf, 4); memmove(digest, ctx->buf, 16); memset(ctx, 0, sizeof(isc_md5_t)); /* In case it's sensitive */ } #endif bind9-9.10.3.dfsg.P4/lib/isc/sha2.c0000644000470500017500000013650712664710322015732 0ustar lamontlamont/* * Copyright (C) 2005-2007, 2009, 2011, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /* $FreeBSD: src/sys/crypto/sha2/sha2.c,v 1.2.2.2 2002/03/05 08:36:47 ume Exp $ */ /* $KAME: sha2.c,v 1.8 2001/11/08 01:07:52 itojun Exp $ */ /* * sha2.c * * Version 1.0.0beta1 * * Written by Aaron D. Gifford * * Copyright 2000 Aaron D. Gifford. 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. Neither the name of the copyright holder nor the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``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(S) OR CONTRIBUTOR(S) 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. * */ #include #include #include #include #include #include #if PKCS11CRYPTO #include #include #endif #ifdef ISC_PLATFORM_OPENSSLHASH void isc_sha224_init(isc_sha224_t *context) { if (context == (isc_sha224_t *)0) { return; } RUNTIME_CHECK(EVP_DigestInit(context, EVP_sha224()) == 1); } void isc_sha224_invalidate(isc_sha224_t *context) { EVP_MD_CTX_cleanup(context); } void isc_sha224_update(isc_sha224_t *context, const isc_uint8_t* data, size_t len) { if (len == 0U) { /* Calling with no data is valid - we do nothing */ return; } /* Sanity check: */ REQUIRE(context != (isc_sha224_t *)0 && data != (isc_uint8_t*)0); RUNTIME_CHECK(EVP_DigestUpdate(context, (const void *) data, len) == 1); } void isc_sha224_final(isc_uint8_t digest[], isc_sha224_t *context) { /* Sanity check: */ REQUIRE(context != (isc_sha224_t *)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (isc_uint8_t*)0) { RUNTIME_CHECK(EVP_DigestFinal(context, digest, NULL) == 1); } else { EVP_MD_CTX_cleanup(context); } } void isc_sha256_init(isc_sha256_t *context) { if (context == (isc_sha256_t *)0) { return; } RUNTIME_CHECK(EVP_DigestInit(context, EVP_sha256()) == 1); } void isc_sha256_invalidate(isc_sha256_t *context) { EVP_MD_CTX_cleanup(context); } void isc_sha256_update(isc_sha256_t *context, const isc_uint8_t *data, size_t len) { if (len == 0U) { /* Calling with no data is valid - we do nothing */ return; } /* Sanity check: */ REQUIRE(context != (isc_sha256_t *)0 && data != (isc_uint8_t*)0); RUNTIME_CHECK(EVP_DigestUpdate(context, (const void *) data, len) == 1); } void isc_sha256_final(isc_uint8_t digest[], isc_sha256_t *context) { /* Sanity check: */ REQUIRE(context != (isc_sha256_t *)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (isc_uint8_t*)0) { RUNTIME_CHECK(EVP_DigestFinal(context, digest, NULL) == 1); } else { EVP_MD_CTX_cleanup(context); } } void isc_sha512_init(isc_sha512_t *context) { if (context == (isc_sha512_t *)0) { return; } RUNTIME_CHECK(EVP_DigestInit(context, EVP_sha512()) == 1); } void isc_sha512_invalidate(isc_sha512_t *context) { EVP_MD_CTX_cleanup(context); } void isc_sha512_update(isc_sha512_t *context, const isc_uint8_t *data, size_t len) { if (len == 0U) { /* Calling with no data is valid - we do nothing */ return; } /* Sanity check: */ REQUIRE(context != (isc_sha512_t *)0 && data != (isc_uint8_t*)0); RUNTIME_CHECK(EVP_DigestUpdate(context, (const void *) data, len) == 1); } void isc_sha512_final(isc_uint8_t digest[], isc_sha512_t *context) { /* Sanity check: */ REQUIRE(context != (isc_sha512_t *)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (isc_uint8_t*)0) { RUNTIME_CHECK(EVP_DigestFinal(context, digest, NULL) == 1); } else { EVP_MD_CTX_cleanup(context); } } void isc_sha384_init(isc_sha384_t *context) { if (context == (isc_sha384_t *)0) { return; } RUNTIME_CHECK(EVP_DigestInit(context, EVP_sha384()) == 1); } void isc_sha384_invalidate(isc_sha384_t *context) { EVP_MD_CTX_cleanup(context); } void isc_sha384_update(isc_sha384_t *context, const isc_uint8_t* data, size_t len) { if (len == 0U) { /* Calling with no data is valid - we do nothing */ return; } /* Sanity check: */ REQUIRE(context != (isc_sha512_t *)0 && data != (isc_uint8_t*)0); RUNTIME_CHECK(EVP_DigestUpdate(context, (const void *) data, len) == 1); } void isc_sha384_final(isc_uint8_t digest[], isc_sha384_t *context) { /* Sanity check: */ REQUIRE(context != (isc_sha384_t *)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (isc_uint8_t*)0) { RUNTIME_CHECK(EVP_DigestFinal(context, digest, NULL) == 1); } else { EVP_MD_CTX_cleanup(context); } } #elif PKCS11CRYPTO void isc_sha224_init(isc_sha224_t *context) { CK_RV rv; CK_MECHANISM mech = { CKM_SHA224, NULL, 0 }; if (context == (isc_sha224_t *)0) { return; } RUNTIME_CHECK(pk11_get_session(context, OP_DIGEST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); PK11_FATALCHECK(pkcs_C_DigestInit, (context->session, &mech)); } void isc_sha224_invalidate(isc_sha224_t *context) { CK_BYTE garbage[ISC_SHA224_DIGESTLENGTH]; CK_ULONG len = ISC_SHA224_DIGESTLENGTH; if (context->handle == NULL) return; (void) pkcs_C_DigestFinal(context->session, garbage, &len); memset(garbage, 0, sizeof(garbage)); pk11_return_session(context); } void isc_sha224_update(isc_sha224_t *context, const isc_uint8_t* data, size_t len) { CK_RV rv; CK_BYTE_PTR pPart; if (len == 0U) { /* Calling with no data is valid - we do nothing */ return; } /* Sanity check: */ REQUIRE(context != (isc_sha224_t *)0 && data != (isc_uint8_t*)0); DE_CONST(data, pPart); PK11_FATALCHECK(pkcs_C_DigestUpdate, (context->session, pPart, (CK_ULONG) len)); } void isc_sha224_final(isc_uint8_t digest[], isc_sha224_t *context) { CK_RV rv; CK_ULONG len = ISC_SHA224_DIGESTLENGTH; /* Sanity check: */ REQUIRE(context != (isc_sha224_t *)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (isc_uint8_t*)0) { PK11_FATALCHECK(pkcs_C_DigestFinal, (context->session, (CK_BYTE_PTR) digest, &len)); } else { CK_BYTE garbage[ISC_SHA224_DIGESTLENGTH]; (void) pkcs_C_DigestFinal(context->session, garbage, &len); memset(garbage, 0, sizeof(garbage)); } pk11_return_session(context); } void isc_sha256_init(isc_sha256_t *context) { CK_RV rv; CK_MECHANISM mech = { CKM_SHA256, NULL, 0 }; if (context == (isc_sha256_t *)0) { return; } RUNTIME_CHECK(pk11_get_session(context, OP_DIGEST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); PK11_FATALCHECK(pkcs_C_DigestInit, (context->session, &mech)); } void isc_sha256_invalidate(isc_sha256_t *context) { CK_BYTE garbage[ISC_SHA256_DIGESTLENGTH]; CK_ULONG len = ISC_SHA256_DIGESTLENGTH; if (context->handle == NULL) return; (void) pkcs_C_DigestFinal(context->session, garbage, &len); memset(garbage, 0, sizeof(garbage)); pk11_return_session(context); } void isc_sha256_update(isc_sha256_t *context, const isc_uint8_t* data, size_t len) { CK_RV rv; CK_BYTE_PTR pPart; if (len == 0U) { /* Calling with no data is valid - we do nothing */ return; } /* Sanity check: */ REQUIRE(context != (isc_sha256_t *)0 && data != (isc_uint8_t*)0); DE_CONST(data, pPart); PK11_FATALCHECK(pkcs_C_DigestUpdate, (context->session, pPart, (CK_ULONG) len)); } void isc_sha256_final(isc_uint8_t digest[], isc_sha256_t *context) { CK_RV rv; CK_ULONG len = ISC_SHA256_DIGESTLENGTH; /* Sanity check: */ REQUIRE(context != (isc_sha256_t *)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (isc_uint8_t*)0) { PK11_FATALCHECK(pkcs_C_DigestFinal, (context->session, (CK_BYTE_PTR) digest, &len)); } else { CK_BYTE garbage[ISC_SHA256_DIGESTLENGTH]; (void) pkcs_C_DigestFinal(context->session, garbage, &len); memset(garbage, 0, sizeof(garbage)); } pk11_return_session(context); } void isc_sha512_init(isc_sha512_t *context) { CK_RV rv; CK_MECHANISM mech = { CKM_SHA512, NULL, 0 }; if (context == (isc_sha512_t *)0) { return; } RUNTIME_CHECK(pk11_get_session(context, OP_DIGEST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); PK11_FATALCHECK(pkcs_C_DigestInit, (context->session, &mech)); } void isc_sha512_invalidate(isc_sha512_t *context) { CK_BYTE garbage[ISC_SHA512_DIGESTLENGTH]; CK_ULONG len = ISC_SHA512_DIGESTLENGTH; if (context->handle == NULL) return; (void) pkcs_C_DigestFinal(context->session, garbage, &len); memset(garbage, 0, sizeof(garbage)); pk11_return_session(context); } void isc_sha512_update(isc_sha512_t *context, const isc_uint8_t* data, size_t len) { CK_RV rv; CK_BYTE_PTR pPart; if (len == 0U) { /* Calling with no data is valid - we do nothing */ return; } /* Sanity check: */ REQUIRE(context != (isc_sha512_t *)0 && data != (isc_uint8_t*)0); DE_CONST(data, pPart); PK11_FATALCHECK(pkcs_C_DigestUpdate, (context->session, pPart, (CK_ULONG) len)); } void isc_sha512_final(isc_uint8_t digest[], isc_sha512_t *context) { CK_RV rv; CK_ULONG len = ISC_SHA512_DIGESTLENGTH; /* Sanity check: */ REQUIRE(context != (isc_sha512_t *)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (isc_uint8_t*)0) { PK11_FATALCHECK(pkcs_C_DigestFinal, (context->session, (CK_BYTE_PTR) digest, &len)); } else { CK_BYTE garbage[ISC_SHA512_DIGESTLENGTH]; (void) pkcs_C_DigestFinal(context->session, garbage, &len); memset(garbage, 0, sizeof(garbage)); } pk11_return_session(context); } void isc_sha384_init(isc_sha384_t *context) { CK_RV rv; CK_MECHANISM mech = { CKM_SHA384, NULL, 0 }; if (context == (isc_sha384_t *)0) { return; } RUNTIME_CHECK(pk11_get_session(context, OP_DIGEST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); PK11_FATALCHECK(pkcs_C_DigestInit, (context->session, &mech)); } void isc_sha384_invalidate(isc_sha384_t *context) { CK_BYTE garbage[ISC_SHA384_DIGESTLENGTH]; CK_ULONG len = ISC_SHA384_DIGESTLENGTH; if (context->handle == NULL) return; (void) pkcs_C_DigestFinal(context->session, garbage, &len); memset(garbage, 0, sizeof(garbage)); pk11_return_session(context); } void isc_sha384_update(isc_sha384_t *context, const isc_uint8_t* data, size_t len) { CK_RV rv; CK_BYTE_PTR pPart; if (len == 0U) { /* Calling with no data is valid - we do nothing */ return; } /* Sanity check: */ REQUIRE(context != (isc_sha384_t *)0 && data != (isc_uint8_t*)0); DE_CONST(data, pPart); PK11_FATALCHECK(pkcs_C_DigestUpdate, (context->session, pPart, (CK_ULONG) len)); } void isc_sha384_final(isc_uint8_t digest[], isc_sha384_t *context) { CK_RV rv; CK_ULONG len = ISC_SHA384_DIGESTLENGTH; /* Sanity check: */ REQUIRE(context != (isc_sha384_t *)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (isc_uint8_t*)0) { PK11_FATALCHECK(pkcs_C_DigestFinal, (context->session, (CK_BYTE_PTR) digest, &len)); } else { CK_BYTE garbage[ISC_SHA384_DIGESTLENGTH]; (void) pkcs_C_DigestFinal(context->session, garbage, &len); memset(garbage, 0, sizeof(garbage)); } pk11_return_session(context); } #else /* * UNROLLED TRANSFORM LOOP NOTE: * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform * loop version for the hash transform rounds (defined using macros * later in this file). Either define on the command line, for example: * * cc -DISC_SHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c * * or define below: * * \#define ISC_SHA2_UNROLL_TRANSFORM * */ /*** SHA-256/384/512 Machine Architecture Definitions *****************/ /* * BYTE_ORDER NOTE: * * Please make sure that your system defines BYTE_ORDER. If your * architecture is little-endian, make sure it also defines * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are * equivalent. * * If your system does not define the above, then you can do so by * hand like this: * * \#define LITTLE_ENDIAN 1234 * \#define BIG_ENDIAN 4321 * * And for little-endian machines, add: * * \#define BYTE_ORDER LITTLE_ENDIAN * * Or for big-endian machines: * * \#define BYTE_ORDER BIG_ENDIAN * * The FreeBSD machine this was written on defines BYTE_ORDER * appropriately by including (which in turn includes * where the appropriate definitions are actually * made). */ #if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) #ifndef BYTE_ORDER #ifndef BIG_ENDIAN #define BIG_ENDIAN 4321 #endif #ifndef LITTLE_ENDIAN #define LITTLE_ENDIAN 1234 #endif #ifdef WORDS_BIGENDIAN #define BYTE_ORDER BIG_ENDIAN #else #define BYTE_ORDER LITTLE_ENDIAN #endif #else #error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN #endif #endif /*** SHA-256/384/512 Various Length Definitions ***********************/ /* NOTE: Most of these are in sha2.h */ #define ISC_SHA256_SHORT_BLOCK_LENGTH (ISC_SHA256_BLOCK_LENGTH - 8) #define ISC_SHA384_SHORT_BLOCK_LENGTH (ISC_SHA384_BLOCK_LENGTH - 16) #define ISC_SHA512_SHORT_BLOCK_LENGTH (ISC_SHA512_BLOCK_LENGTH - 16) /*** ENDIAN REVERSAL MACROS *******************************************/ #if BYTE_ORDER == LITTLE_ENDIAN #define REVERSE32(w,x) { \ isc_uint32_t tmp = (w); \ tmp = (tmp >> 16) | (tmp << 16); \ (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ } #ifdef WIN32 #define REVERSE64(w,x) { \ isc_uint64_t tmp = (w); \ tmp = (tmp >> 32) | (tmp << 32); \ tmp = ((tmp & 0xff00ff00ff00ff00UL) >> 8) | \ ((tmp & 0x00ff00ff00ff00ffUL) << 8); \ (x) = ((tmp & 0xffff0000ffff0000UL) >> 16) | \ ((tmp & 0x0000ffff0000ffffUL) << 16); \ } #else #define REVERSE64(w,x) { \ isc_uint64_t tmp = (w); \ tmp = (tmp >> 32) | (tmp << 32); \ tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ ((tmp & 0x0000ffff0000ffffULL) << 16); \ } #endif #endif /* BYTE_ORDER == LITTLE_ENDIAN */ /* * Macro for incrementally adding the unsigned 64-bit integer n to the * unsigned 128-bit integer (represented using a two-element array of * 64-bit words): */ #define ADDINC128(w,n) { \ (w)[0] += (isc_uint64_t)(n); \ if ((w)[0] < (n)) { \ (w)[1]++; \ } \ } /*** THE SIX LOGICAL FUNCTIONS ****************************************/ /* * Bit shifting and rotation (used by the six SHA-XYZ logical functions: * * NOTE: The naming of R and S appears backwards here (R is a SHIFT and * S is a ROTATION) because the SHA-256/384/512 description document * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this * same "backwards" definition. */ /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ #define R(b,x) ((x) >> (b)) /* 32-bit Rotate-right (used in SHA-256): */ #define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ #define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) /* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) /* Four of six logical functions used in SHA-256: */ #define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) #define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) #define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) #define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) /* Four of six logical functions used in SHA-384 and SHA-512: */ #define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) #define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) #define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) #define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) /*** INTERNAL FUNCTION PROTOTYPES *************************************/ /* NOTE: These should not be accessed directly from outside this * library -- they are intended for private internal visibility/use * only. */ void isc_sha512_last(isc_sha512_t *); void isc_sha256_transform(isc_sha256_t *, const isc_uint32_t*); void isc_sha512_transform(isc_sha512_t *, const isc_uint64_t*); /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ /* Hash constant words K for SHA-224 and SHA-256: */ static const isc_uint32_t K256[64] = { 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL }; /* Initial hash value H for SHA-224: */ static const isc_uint32_t sha224_initial_hash_value[8] = { 0xc1059ed8UL, 0x367cd507UL, 0x3070dd17UL, 0xf70e5939UL, 0xffc00b31UL, 0x68581511UL, 0x64f98fa7UL, 0xbefa4fa4UL }; /* Initial hash value H for SHA-256: */ static const isc_uint32_t sha256_initial_hash_value[8] = { 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL, 0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL }; #ifdef WIN32 /* Hash constant words K for SHA-384 and SHA-512: */ static const isc_uint64_t K512[80] = { 0x428a2f98d728ae22UL, 0x7137449123ef65cdUL, 0xb5c0fbcfec4d3b2fUL, 0xe9b5dba58189dbbcUL, 0x3956c25bf348b538UL, 0x59f111f1b605d019UL, 0x923f82a4af194f9bUL, 0xab1c5ed5da6d8118UL, 0xd807aa98a3030242UL, 0x12835b0145706fbeUL, 0x243185be4ee4b28cUL, 0x550c7dc3d5ffb4e2UL, 0x72be5d74f27b896fUL, 0x80deb1fe3b1696b1UL, 0x9bdc06a725c71235UL, 0xc19bf174cf692694UL, 0xe49b69c19ef14ad2UL, 0xefbe4786384f25e3UL, 0x0fc19dc68b8cd5b5UL, 0x240ca1cc77ac9c65UL, 0x2de92c6f592b0275UL, 0x4a7484aa6ea6e483UL, 0x5cb0a9dcbd41fbd4UL, 0x76f988da831153b5UL, 0x983e5152ee66dfabUL, 0xa831c66d2db43210UL, 0xb00327c898fb213fUL, 0xbf597fc7beef0ee4UL, 0xc6e00bf33da88fc2UL, 0xd5a79147930aa725UL, 0x06ca6351e003826fUL, 0x142929670a0e6e70UL, 0x27b70a8546d22ffcUL, 0x2e1b21385c26c926UL, 0x4d2c6dfc5ac42aedUL, 0x53380d139d95b3dfUL, 0x650a73548baf63deUL, 0x766a0abb3c77b2a8UL, 0x81c2c92e47edaee6UL, 0x92722c851482353bUL, 0xa2bfe8a14cf10364UL, 0xa81a664bbc423001UL, 0xc24b8b70d0f89791UL, 0xc76c51a30654be30UL, 0xd192e819d6ef5218UL, 0xd69906245565a910UL, 0xf40e35855771202aUL, 0x106aa07032bbd1b8UL, 0x19a4c116b8d2d0c8UL, 0x1e376c085141ab53UL, 0x2748774cdf8eeb99UL, 0x34b0bcb5e19b48a8UL, 0x391c0cb3c5c95a63UL, 0x4ed8aa4ae3418acbUL, 0x5b9cca4f7763e373UL, 0x682e6ff3d6b2b8a3UL, 0x748f82ee5defb2fcUL, 0x78a5636f43172f60UL, 0x84c87814a1f0ab72UL, 0x8cc702081a6439ecUL, 0x90befffa23631e28UL, 0xa4506cebde82bde9UL, 0xbef9a3f7b2c67915UL, 0xc67178f2e372532bUL, 0xca273eceea26619cUL, 0xd186b8c721c0c207UL, 0xeada7dd6cde0eb1eUL, 0xf57d4f7fee6ed178UL, 0x06f067aa72176fbaUL, 0x0a637dc5a2c898a6UL, 0x113f9804bef90daeUL, 0x1b710b35131c471bUL, 0x28db77f523047d84UL, 0x32caab7b40c72493UL, 0x3c9ebe0a15c9bebcUL, 0x431d67c49c100d4cUL, 0x4cc5d4becb3e42b6UL, 0x597f299cfc657e2aUL, 0x5fcb6fab3ad6faecUL, 0x6c44198c4a475817UL }; /* Initial hash value H for SHA-384: */ static const isc_uint64_t sha384_initial_hash_value[8] = { 0xcbbb9d5dc1059ed8UL, 0x629a292a367cd507UL, 0x9159015a3070dd17UL, 0x152fecd8f70e5939UL, 0x67332667ffc00b31UL, 0x8eb44a8768581511UL, 0xdb0c2e0d64f98fa7UL, 0x47b5481dbefa4fa4UL }; /* Initial hash value H for SHA-512: */ static const isc_uint64_t sha512_initial_hash_value[8] = { 0x6a09e667f3bcc908U, 0xbb67ae8584caa73bUL, 0x3c6ef372fe94f82bUL, 0xa54ff53a5f1d36f1UL, 0x510e527fade682d1UL, 0x9b05688c2b3e6c1fUL, 0x1f83d9abfb41bd6bUL, 0x5be0cd19137e2179UL }; #else /* Hash constant words K for SHA-384 and SHA-512: */ static const isc_uint64_t K512[80] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL }; /* Initial hash value H for SHA-384: */ static const isc_uint64_t sha384_initial_hash_value[8] = { 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL, 0x152fecd8f70e5939ULL, 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL, 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL }; /* Initial hash value H for SHA-512: */ static const isc_uint64_t sha512_initial_hash_value[8] = { 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL }; #endif /*** SHA-224: *********************************************************/ void isc_sha224_init(isc_sha224_t *context) { if (context == (isc_sha256_t *)0) { return; } memmove(context->state, sha224_initial_hash_value, ISC_SHA256_DIGESTLENGTH); memset(context->buffer, 0, ISC_SHA256_BLOCK_LENGTH); context->bitcount = 0; } void isc_sha224_invalidate(isc_sha224_t *context) { memset(context, 0, sizeof(isc_sha224_t)); } void isc_sha224_update(isc_sha224_t *context, const isc_uint8_t* data, size_t len) { isc_sha256_update((isc_sha256_t *)context, data, len); } void isc_sha224_final(isc_uint8_t digest[], isc_sha224_t *context) { isc_uint8_t sha256_digest[ISC_SHA256_DIGESTLENGTH]; isc_sha256_final(sha256_digest, (isc_sha256_t *)context); memmove(digest, sha256_digest, ISC_SHA224_DIGESTLENGTH); memset(sha256_digest, 0, ISC_SHA256_DIGESTLENGTH); } /*** SHA-256: *********************************************************/ void isc_sha256_init(isc_sha256_t *context) { if (context == (isc_sha256_t *)0) { return; } memmove(context->state, sha256_initial_hash_value, ISC_SHA256_DIGESTLENGTH); memset(context->buffer, 0, ISC_SHA256_BLOCK_LENGTH); context->bitcount = 0; } void isc_sha256_invalidate(isc_sha256_t *context) { memset(context, 0, sizeof(isc_sha256_t)); } #ifdef ISC_SHA2_UNROLL_TRANSFORM /* Unrolled SHA-256 round macros: */ #if BYTE_ORDER == LITTLE_ENDIAN #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ REVERSE32(*data++, W256[j]); \ T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ K256[j] + W256[j]; \ (d) += T1; \ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ j++ #else /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ K256[j] + (W256[j] = *data++); \ (d) += T1; \ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ j++ #endif /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND256(a,b,c,d,e,f,g,h) \ s0 = W256[(j+1)&0x0f]; \ s0 = sigma0_256(s0); \ s1 = W256[(j+14)&0x0f]; \ s1 = sigma1_256(s1); \ T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ (d) += T1; \ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ j++ void isc_sha256_transform(isc_sha256_t *context, const isc_uint32_t* data) { isc_uint32_t a, b, c, d, e, f, g, h, s0, s1; isc_uint32_t T1, *W256; int j; W256 = (isc_uint32_t*)context->buffer; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; b = context->state[1]; c = context->state[2]; d = context->state[3]; e = context->state[4]; f = context->state[5]; g = context->state[6]; h = context->state[7]; j = 0; do { /* Rounds 0 to 15 (unrolled): */ ROUND256_0_TO_15(a,b,c,d,e,f,g,h); ROUND256_0_TO_15(h,a,b,c,d,e,f,g); ROUND256_0_TO_15(g,h,a,b,c,d,e,f); ROUND256_0_TO_15(f,g,h,a,b,c,d,e); ROUND256_0_TO_15(e,f,g,h,a,b,c,d); ROUND256_0_TO_15(d,e,f,g,h,a,b,c); ROUND256_0_TO_15(c,d,e,f,g,h,a,b); ROUND256_0_TO_15(b,c,d,e,f,g,h,a); } while (j < 16); /* Now for the remaining rounds to 64: */ do { ROUND256(a,b,c,d,e,f,g,h); ROUND256(h,a,b,c,d,e,f,g); ROUND256(g,h,a,b,c,d,e,f); ROUND256(f,g,h,a,b,c,d,e); ROUND256(e,f,g,h,a,b,c,d); ROUND256(d,e,f,g,h,a,b,c); ROUND256(c,d,e,f,g,h,a,b); ROUND256(b,c,d,e,f,g,h,a); } while (j < 64); /* Compute the current intermediate hash value */ context->state[0] += a; context->state[1] += b; context->state[2] += c; context->state[3] += d; context->state[4] += e; context->state[5] += f; context->state[6] += g; context->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = 0; /* Avoid compiler warnings */ POST(a); POST(b); POST(c); POST(d); POST(e); POST(f); POST(g); POST(h); POST(T1); } #else /* ISC_SHA2_UNROLL_TRANSFORM */ void isc_sha256_transform(isc_sha256_t *context, const isc_uint32_t* data) { isc_uint32_t a, b, c, d, e, f, g, h, s0, s1; isc_uint32_t T1, T2, *W256; int j; W256 = (isc_uint32_t*)context->buffer; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; b = context->state[1]; c = context->state[2]; d = context->state[3]; e = context->state[4]; f = context->state[5]; g = context->state[6]; h = context->state[7]; j = 0; do { #if BYTE_ORDER == LITTLE_ENDIAN /* Copy data while converting to host byte order */ REVERSE32(*data++,W256[j]); /* Apply the SHA-256 compression function to update a..h */ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; #else /* BYTE_ORDER == LITTLE_ENDIAN */ /* Apply the SHA-256 compression function to update a..h with copy */ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); #endif /* BYTE_ORDER == LITTLE_ENDIAN */ T2 = Sigma0_256(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 16); do { /* Part of the message block expansion: */ s0 = W256[(j+1)&0x0f]; s0 = sigma0_256(s0); s1 = W256[(j+14)&0x0f]; s1 = sigma1_256(s1); /* Apply the SHA-256 compression function to update a..h */ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); T2 = Sigma0_256(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 64); /* Compute the current intermediate hash value */ context->state[0] += a; context->state[1] += b; context->state[2] += c; context->state[3] += d; context->state[4] += e; context->state[5] += f; context->state[6] += g; context->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = T2 = 0; /* Avoid compiler warnings */ POST(a); POST(b); POST(c); POST(d); POST(e); POST(f); POST(g); POST(h); POST(T1); POST(T2); } #endif /* ISC_SHA2_UNROLL_TRANSFORM */ void isc_sha256_update(isc_sha256_t *context, const isc_uint8_t *data, size_t len) { unsigned int freespace, usedspace; if (len == 0U) { /* Calling with no data is valid - we do nothing */ return; } /* Sanity check: */ REQUIRE(context != (isc_sha256_t *)0 && data != (isc_uint8_t*)0); usedspace = (unsigned int)((context->bitcount >> 3) % ISC_SHA256_BLOCK_LENGTH); if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ freespace = ISC_SHA256_BLOCK_LENGTH - usedspace; if (len >= freespace) { /* Fill the buffer completely and process it */ memmove(&context->buffer[usedspace], data, freespace); context->bitcount += freespace << 3; len -= freespace; data += freespace; isc_sha256_transform(context, (isc_uint32_t*)context->buffer); } else { /* The buffer is not yet full */ memmove(&context->buffer[usedspace], data, len); context->bitcount += len << 3; /* Clean up: */ usedspace = freespace = 0; /* Avoid compiler warnings: */ POST(usedspace); POST(freespace); return; } } while (len >= ISC_SHA256_BLOCK_LENGTH) { /* Process as many complete blocks as we can */ memmove(context->buffer, data, ISC_SHA256_BLOCK_LENGTH); isc_sha256_transform(context, (isc_uint32_t*)context->buffer); context->bitcount += ISC_SHA256_BLOCK_LENGTH << 3; len -= ISC_SHA256_BLOCK_LENGTH; data += ISC_SHA256_BLOCK_LENGTH; } if (len > 0U) { /* There's left-overs, so save 'em */ memmove(context->buffer, data, len); context->bitcount += len << 3; } /* Clean up: */ usedspace = freespace = 0; /* Avoid compiler warnings: */ POST(usedspace); POST(freespace); } void isc_sha256_final(isc_uint8_t digest[], isc_sha256_t *context) { isc_uint32_t *d = (isc_uint32_t*)digest; unsigned int usedspace; /* Sanity check: */ REQUIRE(context != (isc_sha256_t *)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (isc_uint8_t*)0) { usedspace = (unsigned int)((context->bitcount >> 3) % ISC_SHA256_BLOCK_LENGTH); #if BYTE_ORDER == LITTLE_ENDIAN /* Convert FROM host byte order */ REVERSE64(context->bitcount,context->bitcount); #endif if (usedspace > 0) { /* Begin padding with a 1 bit: */ context->buffer[usedspace++] = 0x80; if (usedspace <= ISC_SHA256_SHORT_BLOCK_LENGTH) { /* Set-up for the last transform: */ memset(&context->buffer[usedspace], 0, ISC_SHA256_SHORT_BLOCK_LENGTH - usedspace); } else { if (usedspace < ISC_SHA256_BLOCK_LENGTH) { memset(&context->buffer[usedspace], 0, ISC_SHA256_BLOCK_LENGTH - usedspace); } /* Do second-to-last transform: */ isc_sha256_transform(context, (isc_uint32_t*)context->buffer); /* And set-up for the last transform: */ memset(context->buffer, 0, ISC_SHA256_SHORT_BLOCK_LENGTH); } } else { /* Set-up for the last transform: */ memset(context->buffer, 0, ISC_SHA256_SHORT_BLOCK_LENGTH); /* Begin padding with a 1 bit: */ *context->buffer = 0x80; } /* Set the bit count: */ *(isc_uint64_t*)&context->buffer[ISC_SHA256_SHORT_BLOCK_LENGTH] = context->bitcount; /* Final transform: */ isc_sha256_transform(context, (isc_uint32_t*)context->buffer); #if BYTE_ORDER == LITTLE_ENDIAN { /* Convert TO host byte order */ int j; for (j = 0; j < 8; j++) { REVERSE32(context->state[j],context->state[j]); *d++ = context->state[j]; } } #else memmove(d, context->state, ISC_SHA256_DIGESTLENGTH); #endif } /* Clean up state data: */ memset(context, 0, sizeof(*context)); usedspace = 0; POST(usedspace); } /*** SHA-512: *********************************************************/ void isc_sha512_init(isc_sha512_t *context) { if (context == (isc_sha512_t *)0) { return; } memmove(context->state, sha512_initial_hash_value, ISC_SHA512_DIGESTLENGTH); memset(context->buffer, 0, ISC_SHA512_BLOCK_LENGTH); context->bitcount[0] = context->bitcount[1] = 0; } void isc_sha512_invalidate(isc_sha512_t *context) { memset(context, 0, sizeof(isc_sha512_t)); } #ifdef ISC_SHA2_UNROLL_TRANSFORM /* Unrolled SHA-512 round macros: */ #if BYTE_ORDER == LITTLE_ENDIAN #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ REVERSE64(*data++, W512[j]); \ T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ K512[j] + W512[j]; \ (d) += T1, \ (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ j++ #else /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ K512[j] + (W512[j] = *data++); \ (d) += T1; \ (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ j++ #endif /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND512(a,b,c,d,e,f,g,h) \ s0 = W512[(j+1)&0x0f]; \ s0 = sigma0_512(s0); \ s1 = W512[(j+14)&0x0f]; \ s1 = sigma1_512(s1); \ T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ (d) += T1; \ (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ j++ void isc_sha512_transform(isc_sha512_t *context, const isc_uint64_t* data) { isc_uint64_t a, b, c, d, e, f, g, h, s0, s1; isc_uint64_t T1, *W512 = (isc_uint64_t*)context->buffer; int j; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; b = context->state[1]; c = context->state[2]; d = context->state[3]; e = context->state[4]; f = context->state[5]; g = context->state[6]; h = context->state[7]; j = 0; do { ROUND512_0_TO_15(a,b,c,d,e,f,g,h); ROUND512_0_TO_15(h,a,b,c,d,e,f,g); ROUND512_0_TO_15(g,h,a,b,c,d,e,f); ROUND512_0_TO_15(f,g,h,a,b,c,d,e); ROUND512_0_TO_15(e,f,g,h,a,b,c,d); ROUND512_0_TO_15(d,e,f,g,h,a,b,c); ROUND512_0_TO_15(c,d,e,f,g,h,a,b); ROUND512_0_TO_15(b,c,d,e,f,g,h,a); } while (j < 16); /* Now for the remaining rounds up to 79: */ do { ROUND512(a,b,c,d,e,f,g,h); ROUND512(h,a,b,c,d,e,f,g); ROUND512(g,h,a,b,c,d,e,f); ROUND512(f,g,h,a,b,c,d,e); ROUND512(e,f,g,h,a,b,c,d); ROUND512(d,e,f,g,h,a,b,c); ROUND512(c,d,e,f,g,h,a,b); ROUND512(b,c,d,e,f,g,h,a); } while (j < 80); /* Compute the current intermediate hash value */ context->state[0] += a; context->state[1] += b; context->state[2] += c; context->state[3] += d; context->state[4] += e; context->state[5] += f; context->state[6] += g; context->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = 0; /* Avoid compiler warnings */ POST(a); POST(b); POST(c); POST(d); POST(e); POST(f); POST(g); POST(h); POST(T1); } #else /* ISC_SHA2_UNROLL_TRANSFORM */ void isc_sha512_transform(isc_sha512_t *context, const isc_uint64_t* data) { isc_uint64_t a, b, c, d, e, f, g, h, s0, s1; isc_uint64_t T1, T2, *W512 = (isc_uint64_t*)context->buffer; int j; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; b = context->state[1]; c = context->state[2]; d = context->state[3]; e = context->state[4]; f = context->state[5]; g = context->state[6]; h = context->state[7]; j = 0; do { #if BYTE_ORDER == LITTLE_ENDIAN /* Convert TO host byte order */ REVERSE64(*data++, W512[j]); /* Apply the SHA-512 compression function to update a..h */ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; #else /* BYTE_ORDER == LITTLE_ENDIAN */ /* Apply the SHA-512 compression function to update a..h with copy */ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); #endif /* BYTE_ORDER == LITTLE_ENDIAN */ T2 = Sigma0_512(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 16); do { /* Part of the message block expansion: */ s0 = W512[(j+1)&0x0f]; s0 = sigma0_512(s0); s1 = W512[(j+14)&0x0f]; s1 = sigma1_512(s1); /* Apply the SHA-512 compression function to update a..h */ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); T2 = Sigma0_512(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 80); /* Compute the current intermediate hash value */ context->state[0] += a; context->state[1] += b; context->state[2] += c; context->state[3] += d; context->state[4] += e; context->state[5] += f; context->state[6] += g; context->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = T2 = 0; /* Avoid compiler warnings */ POST(a); POST(b); POST(c); POST(d); POST(e); POST(f); POST(g); POST(h); POST(T1); POST(T2); } #endif /* ISC_SHA2_UNROLL_TRANSFORM */ void isc_sha512_update(isc_sha512_t *context, const isc_uint8_t *data, size_t len) { unsigned int freespace, usedspace; if (len == 0U) { /* Calling with no data is valid - we do nothing */ return; } /* Sanity check: */ REQUIRE(context != (isc_sha512_t *)0 && data != (isc_uint8_t*)0); usedspace = (unsigned int)((context->bitcount[0] >> 3) % ISC_SHA512_BLOCK_LENGTH); if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ freespace = ISC_SHA512_BLOCK_LENGTH - usedspace; if (len >= freespace) { /* Fill the buffer completely and process it */ memmove(&context->buffer[usedspace], data, freespace); ADDINC128(context->bitcount, freespace << 3); len -= freespace; data += freespace; isc_sha512_transform(context, (isc_uint64_t*)context->buffer); } else { /* The buffer is not yet full */ memmove(&context->buffer[usedspace], data, len); ADDINC128(context->bitcount, len << 3); /* Clean up: */ usedspace = freespace = 0; /* Avoid compiler warnings: */ POST(usedspace); POST(freespace); return; } } while (len >= ISC_SHA512_BLOCK_LENGTH) { /* Process as many complete blocks as we can */ memmove(context->buffer, data, ISC_SHA512_BLOCK_LENGTH); isc_sha512_transform(context, (isc_uint64_t*)context->buffer); ADDINC128(context->bitcount, ISC_SHA512_BLOCK_LENGTH << 3); len -= ISC_SHA512_BLOCK_LENGTH; data += ISC_SHA512_BLOCK_LENGTH; } if (len > 0U) { /* There's left-overs, so save 'em */ memmove(context->buffer, data, len); ADDINC128(context->bitcount, len << 3); } /* Clean up: */ usedspace = freespace = 0; /* Avoid compiler warnings: */ POST(usedspace); POST(freespace); } void isc_sha512_last(isc_sha512_t *context) { unsigned int usedspace; usedspace = (unsigned int)((context->bitcount[0] >> 3) % ISC_SHA512_BLOCK_LENGTH); #if BYTE_ORDER == LITTLE_ENDIAN /* Convert FROM host byte order */ REVERSE64(context->bitcount[0],context->bitcount[0]); REVERSE64(context->bitcount[1],context->bitcount[1]); #endif if (usedspace > 0) { /* Begin padding with a 1 bit: */ context->buffer[usedspace++] = 0x80; if (usedspace <= ISC_SHA512_SHORT_BLOCK_LENGTH) { /* Set-up for the last transform: */ memset(&context->buffer[usedspace], 0, ISC_SHA512_SHORT_BLOCK_LENGTH - usedspace); } else { if (usedspace < ISC_SHA512_BLOCK_LENGTH) { memset(&context->buffer[usedspace], 0, ISC_SHA512_BLOCK_LENGTH - usedspace); } /* Do second-to-last transform: */ isc_sha512_transform(context, (isc_uint64_t*)context->buffer); /* And set-up for the last transform: */ memset(context->buffer, 0, ISC_SHA512_BLOCK_LENGTH - 2); } } else { /* Prepare for final transform: */ memset(context->buffer, 0, ISC_SHA512_SHORT_BLOCK_LENGTH); /* Begin padding with a 1 bit: */ *context->buffer = 0x80; } /* Store the length of input data (in bits): */ *(isc_uint64_t*)&context->buffer[ISC_SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1]; *(isc_uint64_t*)&context->buffer[ISC_SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0]; /* Final transform: */ isc_sha512_transform(context, (isc_uint64_t*)context->buffer); } void isc_sha512_final(isc_uint8_t digest[], isc_sha512_t *context) { isc_uint64_t *d = (isc_uint64_t*)digest; /* Sanity check: */ REQUIRE(context != (isc_sha512_t *)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (isc_uint8_t*)0) { isc_sha512_last(context); /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN { /* Convert TO host byte order */ int j; for (j = 0; j < 8; j++) { REVERSE64(context->state[j],context->state[j]); *d++ = context->state[j]; } } #else memmove(d, context->state, ISC_SHA512_DIGESTLENGTH); #endif } /* Zero out state data */ memset(context, 0, sizeof(*context)); } /*** SHA-384: *********************************************************/ void isc_sha384_init(isc_sha384_t *context) { if (context == (isc_sha384_t *)0) { return; } memmove(context->state, sha384_initial_hash_value, ISC_SHA512_DIGESTLENGTH); memset(context->buffer, 0, ISC_SHA384_BLOCK_LENGTH); context->bitcount[0] = context->bitcount[1] = 0; } void isc_sha384_invalidate(isc_sha384_t *context) { memset(context, 0, sizeof(isc_sha384_t)); } void isc_sha384_update(isc_sha384_t *context, const isc_uint8_t* data, size_t len) { isc_sha512_update((isc_sha512_t *)context, data, len); } void isc_sha384_final(isc_uint8_t digest[], isc_sha384_t *context) { isc_uint64_t *d = (isc_uint64_t*)digest; /* Sanity check: */ REQUIRE(context != (isc_sha384_t *)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (isc_uint8_t*)0) { isc_sha512_last((isc_sha512_t *)context); /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN { /* Convert TO host byte order */ int j; for (j = 0; j < 6; j++) { REVERSE64(context->state[j],context->state[j]); *d++ = context->state[j]; } } #else memmove(d, context->state, ISC_SHA384_DIGESTLENGTH); #endif } /* Zero out state data */ memset(context, 0, sizeof(*context)); } #endif /* !ISC_PLATFORM_OPENSSLHASH */ /* * Constant used by SHA256/384/512_End() functions for converting the * digest to a readable hexadecimal character string: */ static const char *sha2_hex_digits = "0123456789abcdef"; char * isc_sha224_end(isc_sha224_t *context, char buffer[]) { isc_uint8_t digest[ISC_SHA224_DIGESTLENGTH], *d = digest; unsigned int i; /* Sanity check: */ REQUIRE(context != (isc_sha224_t *)0); if (buffer != (char*)0) { isc_sha224_final(digest, context); for (i = 0; i < ISC_SHA224_DIGESTLENGTH; i++) { *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *buffer++ = sha2_hex_digits[*d & 0x0f]; d++; } *buffer = (char)0; } else { #ifdef ISC_PLATFORM_OPENSSLHASH EVP_MD_CTX_cleanup(context); #elif PKCS11CRYPTO pk11_return_session(context); #else memset(context, 0, sizeof(*context)); #endif } memset(digest, 0, ISC_SHA224_DIGESTLENGTH); return buffer; } char * isc_sha224_data(const isc_uint8_t *data, size_t len, char digest[ISC_SHA224_DIGESTSTRINGLENGTH]) { isc_sha224_t context; isc_sha224_init(&context); isc_sha224_update(&context, data, len); return (isc_sha224_end(&context, digest)); } char * isc_sha256_end(isc_sha256_t *context, char buffer[]) { isc_uint8_t digest[ISC_SHA256_DIGESTLENGTH], *d = digest; unsigned int i; /* Sanity check: */ REQUIRE(context != (isc_sha256_t *)0); if (buffer != (char*)0) { isc_sha256_final(digest, context); for (i = 0; i < ISC_SHA256_DIGESTLENGTH; i++) { *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *buffer++ = sha2_hex_digits[*d & 0x0f]; d++; } *buffer = (char)0; } else { #ifdef ISC_PLATFORM_OPENSSLHASH EVP_MD_CTX_cleanup(context); #elif PKCS11CRYPTO pk11_return_session(context); #else memset(context, 0, sizeof(*context)); #endif } memset(digest, 0, ISC_SHA256_DIGESTLENGTH); return buffer; } char * isc_sha256_data(const isc_uint8_t* data, size_t len, char digest[ISC_SHA256_DIGESTSTRINGLENGTH]) { isc_sha256_t context; isc_sha256_init(&context); isc_sha256_update(&context, data, len); return (isc_sha256_end(&context, digest)); } char * isc_sha512_end(isc_sha512_t *context, char buffer[]) { isc_uint8_t digest[ISC_SHA512_DIGESTLENGTH], *d = digest; unsigned int i; /* Sanity check: */ REQUIRE(context != (isc_sha512_t *)0); if (buffer != (char*)0) { isc_sha512_final(digest, context); for (i = 0; i < ISC_SHA512_DIGESTLENGTH; i++) { *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *buffer++ = sha2_hex_digits[*d & 0x0f]; d++; } *buffer = (char)0; } else { #ifdef ISC_PLATFORM_OPENSSLHASH EVP_MD_CTX_cleanup(context); #elif PKCS11CRYPTO pk11_return_session(context); #else memset(context, 0, sizeof(*context)); #endif } memset(digest, 0, ISC_SHA512_DIGESTLENGTH); return buffer; } char * isc_sha512_data(const isc_uint8_t *data, size_t len, char digest[ISC_SHA512_DIGESTSTRINGLENGTH]) { isc_sha512_t context; isc_sha512_init(&context); isc_sha512_update(&context, data, len); return (isc_sha512_end(&context, digest)); } char * isc_sha384_end(isc_sha384_t *context, char buffer[]) { isc_uint8_t digest[ISC_SHA384_DIGESTLENGTH], *d = digest; unsigned int i; /* Sanity check: */ REQUIRE(context != (isc_sha384_t *)0); if (buffer != (char*)0) { isc_sha384_final(digest, context); for (i = 0; i < ISC_SHA384_DIGESTLENGTH; i++) { *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *buffer++ = sha2_hex_digits[*d & 0x0f]; d++; } *buffer = (char)0; } else { #ifdef ISC_PLATFORM_OPENSSLHASH EVP_MD_CTX_cleanup(context); #elif PKCS11CRYPTO pk11_return_session(context); #else memset(context, 0, sizeof(*context)); #endif } memset(digest, 0, ISC_SHA384_DIGESTLENGTH); return buffer; } char * isc_sha384_data(const isc_uint8_t *data, size_t len, char digest[ISC_SHA384_DIGESTSTRINGLENGTH]) { isc_sha384_t context; isc_sha384_init(&context); isc_sha384_update(&context, data, len); return (isc_sha384_end(&context, digest)); } bind9-9.10.3.dfsg.P4/lib/isc/random.c0000644000470500017500000000604112664710322016342 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: random.c,v 1.28 2009/07/16 05:52:46 marka Exp $ */ /*! \file */ #include #include #include /* Required for time(). */ #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #include static isc_once_t once = ISC_ONCE_INIT; static void initialize_rand(void) { #ifndef HAVE_ARC4RANDOM unsigned int pid = getpid(); /* * The low bits of pid generally change faster. * Xor them with the high bits of time which change slowly. */ pid = ((pid << 16) & 0xffff0000) | ((pid >> 16) & 0xffff); srand((unsigned)time(NULL) ^ pid); #endif } static void initialize(void) { RUNTIME_CHECK(isc_once_do(&once, initialize_rand) == ISC_R_SUCCESS); } void isc_random_seed(isc_uint32_t seed) { initialize(); #ifndef HAVE_ARC4RANDOM srand(seed); #elif defined(HAVE_ARC4RANDOM_ADDRANDOM) arc4random_addrandom((u_char *) &seed, sizeof(isc_uint32_t)); #else /* * If arcrandom() is available and no corresponding seeding * function arc4random_addrandom() is available, no seeding is * done on such platforms (e.g., OpenBSD 5.5). This is because * the OS itself is supposed to seed the RNG and it is assumed * that no explicit seeding is required. */ #endif } void isc_random_get(isc_uint32_t *val) { REQUIRE(val != NULL); initialize(); #ifndef HAVE_ARC4RANDOM /* * rand()'s lower bits are not random. * rand()'s upper bit is zero. */ #if RAND_MAX >= 0xfffff /* We have at least 20 bits. Use lower 16 excluding lower most 4 */ *val = ((rand() >> 4) & 0xffff) | ((rand() << 12) & 0xffff0000); #elif RAND_MAX >= 0x7fff /* We have at least 15 bits. Use lower 10/11 excluding lower most 4 */ *val = ((rand() >> 4) & 0x000007ff) | ((rand() << 7) & 0x003ff800) | ((rand() << 18) & 0xffc00000); #else #error RAND_MAX is too small #endif #else *val = arc4random(); #endif } isc_uint32_t isc_random_jitter(isc_uint32_t max, isc_uint32_t jitter) { isc_uint32_t rnd; REQUIRE(jitter < max || (jitter == 0 && max == 0)); if (jitter == 0) return (max); isc_random_get(&rnd); return (max - rnd % jitter); } bind9-9.10.3.dfsg.P4/lib/isc/portset.c0000644000470500017500000000667012664710322016572 0ustar lamontlamont/* * Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: portset.c,v 1.4 2008/06/24 23:24:35 marka Exp $ */ /*! \file */ #include #include #include #include #include #include #define ISC_PORTSET_BUFSIZE (65536 / (sizeof(isc_uint32_t) * 8)) /*% * Internal representation of portset. It's an array of 32-bit integers, each * bit corresponding to a single port in the ascending order. For example, * the second most significant bit of buf[0] corresponds to port 1. */ struct isc_portset { unsigned int nports; /*%< number of ports in the set */ isc_uint32_t buf[ISC_PORTSET_BUFSIZE]; }; static inline isc_boolean_t portset_isset(isc_portset_t *portset, in_port_t port) { return (ISC_TF((portset->buf[port >> 5] & (1 << (port & 31))) != 0)); } static inline void portset_add(isc_portset_t *portset, in_port_t port) { if (!portset_isset(portset, port)) { portset->nports++; portset->buf[port >> 5] |= (1 << (port & 31)); } } static inline void portset_remove(isc_portset_t *portset, in_port_t port) { if (portset_isset(portset, port)) { portset->nports--; portset->buf[port >> 5] &= ~(1 << (port & 31)); } } isc_result_t isc_portset_create(isc_mem_t *mctx, isc_portset_t **portsetp) { isc_portset_t *portset; REQUIRE(portsetp != NULL && *portsetp == NULL); portset = isc_mem_get(mctx, sizeof(*portset)); if (portset == NULL) return (ISC_R_NOMEMORY); /* Make the set 'empty' by default */ memset(portset, 0, sizeof(*portset)); *portsetp = portset; return (ISC_R_SUCCESS); } void isc_portset_destroy(isc_mem_t *mctx, isc_portset_t **portsetp) { isc_portset_t *portset; REQUIRE(portsetp != NULL); portset = *portsetp; isc_mem_put(mctx, portset, sizeof(*portset)); } isc_boolean_t isc_portset_isset(isc_portset_t *portset, in_port_t port) { REQUIRE(portset != NULL); return (portset_isset(portset, port)); } unsigned int isc_portset_nports(isc_portset_t *portset) { REQUIRE(portset != NULL); return (portset->nports); } void isc_portset_add(isc_portset_t *portset, in_port_t port) { REQUIRE(portset != NULL); portset_add(portset, port); } void isc_portset_remove(isc_portset_t *portset, in_port_t port) { portset_remove(portset, port); } void isc_portset_addrange(isc_portset_t *portset, in_port_t port_lo, in_port_t port_hi) { in_port_t p; REQUIRE(portset != NULL); REQUIRE(port_lo <= port_hi); p = port_lo; do { portset_add(portset, p); } while (p++ < port_hi); } void isc_portset_removerange(isc_portset_t *portset, in_port_t port_lo, in_port_t port_hi) { in_port_t p; REQUIRE(portset != NULL); REQUIRE(port_lo <= port_hi); p = port_lo; do { portset_remove(portset, p); } while (p++ < port_hi); } bind9-9.10.3.dfsg.P4/lib/isc/inet_ntop.c0000644000470500017500000001214112664710322017057 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1996-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #if defined(LIBC_SCCS) && !defined(lint) static char rcsid[] = "$Id: inet_ntop.c,v 1.21 2009/07/17 23:47:41 tbox Exp $"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include #define NS_INT16SZ 2 #define NS_IN6ADDRSZ 16 /* * WARNING: Don't even consider trying to compile this on a system where * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ static const char *inet_ntop4(const unsigned char *src, char *dst, size_t size); #ifdef AF_INET6 static const char *inet_ntop6(const unsigned char *src, char *dst, size_t size); #endif /*! char * * isc_net_ntop(af, src, dst, size) * convert a network format address to presentation format. * \return * pointer to presentation format address (`dst'), or NULL (see errno). * \author * Paul Vixie, 1996. */ const char * isc_net_ntop(int af, const void *src, char *dst, size_t size) { switch (af) { case AF_INET: return (inet_ntop4(src, dst, size)); #ifdef AF_INET6 case AF_INET6: return (inet_ntop6(src, dst, size)); #endif default: errno = EAFNOSUPPORT; return (NULL); } /* NOTREACHED */ } /*! const char * * inet_ntop4(src, dst, size) * format an IPv4 address * \return * `dst' (as a const) * \note * (1) uses no statics * \note * (2) takes a unsigned char* not an in_addr as input * \author * Paul Vixie, 1996. */ static const char * inet_ntop4(const unsigned char *src, char *dst, size_t size) { static const char *fmt = "%u.%u.%u.%u"; char tmp[sizeof("255.255.255.255")]; if ((size_t)sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) >= size) { errno = ENOSPC; return (NULL); } strcpy(dst, tmp); return (dst); } /*! const char * * isc_inet_ntop6(src, dst, size) * convert IPv6 binary address into presentation (printable) format * \author * Paul Vixie, 1996. */ #ifdef AF_INET6 static const char * inet_ntop6(const unsigned char *src, char *dst, size_t size) { /* * Note that int32_t and int16_t need only be "at least" large enough * to contain a value of the specified size. On some systems, like * Crays, there is no such thing as an integer variable with 16 bits. * Keep this in mind if you think this function should have been coded * to use pointer overlays. All the world's not a VAX. */ char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")], *tp; struct { int base, len; } best, cur; unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ]; int i; /* * Preprocess: * Copy the input (bytewise) array into a wordwise array. * Find the longest run of 0x00's in src[] for :: shorthanding. */ memset(words, '\0', sizeof(words)); for (i = 0; i < NS_IN6ADDRSZ; i++) words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); best.base = -1; cur.base = -1; for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { if (words[i] == 0) { if (cur.base == -1) cur.base = i, cur.len = 1; else cur.len++; } else { if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; cur.base = -1; } } } if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; } if (best.base != -1 && best.len < 2) best.base = -1; /* * Format the result. */ tp = tmp; for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { /* Are we inside the best run of 0x00's? */ if (best.base != -1 && i >= best.base && i < (best.base + best.len)) { if (i == best.base) *tp++ = ':'; continue; } /* Are we following an initial run of 0x00s or any real hex? */ if (i != 0) *tp++ = ':'; /* Is this address an encapsulated IPv4? */ if (i == 6 && best.base == 0 && (best.len == 6 || (best.len == 7 && words[7] != 0x0001) || (best.len == 5 && words[5] == 0xffff))) { if (!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp))) return (NULL); tp += strlen(tp); break; } tp += sprintf(tp, "%x", words[i]); } /* Was it a trailing run of 0x00's? */ if (best.base != -1 && (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ)) *tp++ = ':'; *tp++ = '\0'; /* * Check for overflow, copy, and we're done. */ if ((size_t)(tp - tmp) > size) { errno = ENOSPC; return (NULL); } strcpy(dst, tmp); return (dst); } #endif /* AF_INET6 */ bind9-9.10.3.dfsg.P4/lib/isc/entropy.c0000644000470500017500000007257412664710322016600 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2010, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: entropy.c,v 1.22 2010/08/10 23:48:19 tbox Exp $ */ /*! \file * \brief * This is the system independent part of the entropy module. It is * compiled via inclusion from the relevant OS source file, ie, * \link unix/entropy.c unix/entropy.c \endlink or win32/entropy.c. * * \author Much of this code is modeled after the NetBSD /dev/random implementation, * written by Michael Graff . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef PKCS11CRYPTO #include #endif #define ENTROPY_MAGIC ISC_MAGIC('E', 'n', 't', 'e') #define SOURCE_MAGIC ISC_MAGIC('E', 'n', 't', 's') #define VALID_ENTROPY(e) ISC_MAGIC_VALID(e, ENTROPY_MAGIC) #define VALID_SOURCE(s) ISC_MAGIC_VALID(s, SOURCE_MAGIC) /*** *** "constants." Do not change these unless you _really_ know what *** you are doing. ***/ /*% * Size of entropy pool in 32-bit words. This _MUST_ be a power of 2. */ #define RND_POOLWORDS 128 /*% Pool in bytes. */ #define RND_POOLBYTES (RND_POOLWORDS * 4) /*% Pool in bits. */ #define RND_POOLBITS (RND_POOLWORDS * 32) /*% * Number of bytes returned per hash. This must be true: * threshold * 2 <= digest_size_in_bytes */ #define RND_ENTROPY_THRESHOLD 10 #define THRESHOLD_BITS (RND_ENTROPY_THRESHOLD * 8) /*% * Size of the input event queue in samples. */ #define RND_EVENTQSIZE 32 /*% * The number of times we'll "reseed" for pseudorandom seeds. This is an * extremely weak pseudorandom seed. If the caller is using lots of * pseudorandom data and they cannot provide a stronger random source, * there is little we can do other than hope they're smart enough to * call _adddata() with something better than we can come up with. */ #define RND_INITIALIZE 128 /*% Entropy Pool */ typedef struct { isc_uint32_t cursor; /*%< current add point in the pool */ isc_uint32_t entropy; /*%< current entropy estimate in bits */ isc_uint32_t pseudo; /*%< bits extracted in pseudorandom */ isc_uint32_t rotate; /*%< how many bits to rotate by */ isc_uint32_t pool[RND_POOLWORDS]; /*%< random pool data */ } isc_entropypool_t; struct isc_entropy { unsigned int magic; isc_mem_t *mctx; isc_mutex_t lock; unsigned int refcnt; isc_uint32_t initialized; isc_uint32_t initcount; isc_entropypool_t pool; unsigned int nsources; isc_entropysource_t *nextsource; ISC_LIST(isc_entropysource_t) sources; }; /*% Sample Queue */ typedef struct { isc_uint32_t last_time; /*%< last time recorded */ isc_uint32_t last_delta; /*%< last delta value */ isc_uint32_t last_delta2; /*%< last delta2 value */ isc_uint32_t nsamples; /*%< number of samples filled in */ isc_uint32_t *samples; /*%< the samples */ isc_uint32_t *extra; /*%< extra samples added in */ } sample_queue_t; typedef struct { sample_queue_t samplequeue; } isc_entropysamplesource_t; typedef struct { isc_boolean_t start_called; isc_entropystart_t startfunc; isc_entropyget_t getfunc; isc_entropystop_t stopfunc; void *arg; sample_queue_t samplequeue; } isc_cbsource_t; typedef struct { FILESOURCE_HANDLE_TYPE handle; } isc_entropyfilesource_t; struct isc_entropysource { unsigned int magic; unsigned int type; isc_entropy_t *ent; isc_uint32_t total; /*%< entropy from this source */ ISC_LINK(isc_entropysource_t) link; char name[32]; isc_boolean_t bad; isc_boolean_t warn_keyboard; isc_keyboard_t kbd; union { isc_entropysamplesource_t sample; isc_entropyfilesource_t file; isc_cbsource_t callback; isc_entropyusocketsource_t usocket; } sources; }; #define ENTROPY_SOURCETYPE_SAMPLE 1 /*%< Type is a sample source */ #define ENTROPY_SOURCETYPE_FILE 2 /*%< Type is a file source */ #define ENTROPY_SOURCETYPE_CALLBACK 3 /*%< Type is a callback source */ #define ENTROPY_SOURCETYPE_USOCKET 4 /*%< Type is a Unix socket source */ /*@{*/ /*% * The random pool "taps" */ #define TAP1 99 #define TAP2 59 #define TAP3 31 #define TAP4 9 #define TAP5 7 /*@}*/ /*@{*/ /*% * Declarations for function provided by the system dependent sources that * include this file. */ static void fillpool(isc_entropy_t *, unsigned int, isc_boolean_t); static int wait_for_sources(isc_entropy_t *); static void destroyfilesource(isc_entropyfilesource_t *source); static void destroyusocketsource(isc_entropyusocketsource_t *source); /*@}*/ static void samplequeue_release(isc_entropy_t *ent, sample_queue_t *sq) { REQUIRE(sq->samples != NULL); REQUIRE(sq->extra != NULL); isc_mem_put(ent->mctx, sq->samples, RND_EVENTQSIZE * 4); isc_mem_put(ent->mctx, sq->extra, RND_EVENTQSIZE * 4); sq->samples = NULL; sq->extra = NULL; } static isc_result_t samplesource_allocate(isc_entropy_t *ent, sample_queue_t *sq) { sq->samples = isc_mem_get(ent->mctx, RND_EVENTQSIZE * 4); if (sq->samples == NULL) return (ISC_R_NOMEMORY); sq->extra = isc_mem_get(ent->mctx, RND_EVENTQSIZE * 4); if (sq->extra == NULL) { isc_mem_put(ent->mctx, sq->samples, RND_EVENTQSIZE * 4); sq->samples = NULL; return (ISC_R_NOMEMORY); } sq->nsamples = 0; return (ISC_R_SUCCESS); } /*% * Add in entropy, even when the value we're adding in could be * very large. */ static inline void add_entropy(isc_entropy_t *ent, isc_uint32_t entropy) { /* clamp input. Yes, this must be done. */ entropy = ISC_MIN(entropy, RND_POOLBITS); /* Add in the entropy we already have. */ entropy += ent->pool.entropy; /* Clamp. */ ent->pool.entropy = ISC_MIN(entropy, RND_POOLBITS); } /*% * Decrement the amount of entropy the pool has. */ static inline void subtract_entropy(isc_entropy_t *ent, isc_uint32_t entropy) { entropy = ISC_MIN(entropy, ent->pool.entropy); ent->pool.entropy -= entropy; } /*! * Add in entropy, even when the value we're adding in could be * very large. */ static inline void add_pseudo(isc_entropy_t *ent, isc_uint32_t pseudo) { /* clamp input. Yes, this must be done. */ pseudo = ISC_MIN(pseudo, RND_POOLBITS * 8); /* Add in the pseudo we already have. */ pseudo += ent->pool.pseudo; /* Clamp. */ ent->pool.pseudo = ISC_MIN(pseudo, RND_POOLBITS * 8); } /*! * Decrement the amount of pseudo the pool has. */ static inline void subtract_pseudo(isc_entropy_t *ent, isc_uint32_t pseudo) { pseudo = ISC_MIN(pseudo, ent->pool.pseudo); ent->pool.pseudo -= pseudo; } /*! * Add one word to the pool, rotating the input as needed. */ static inline void entropypool_add_word(isc_entropypool_t *rp, isc_uint32_t val) { /* * Steal some values out of the pool, and xor them into the * word we were given. * * Mix the new value into the pool using xor. This will * prevent the actual values from being known to the caller * since the previous values are assumed to be unknown as well. */ val ^= rp->pool[(rp->cursor + TAP1) & (RND_POOLWORDS - 1)]; val ^= rp->pool[(rp->cursor + TAP2) & (RND_POOLWORDS - 1)]; val ^= rp->pool[(rp->cursor + TAP3) & (RND_POOLWORDS - 1)]; val ^= rp->pool[(rp->cursor + TAP4) & (RND_POOLWORDS - 1)]; val ^= rp->pool[(rp->cursor + TAP5) & (RND_POOLWORDS - 1)]; if (rp->rotate == 0) rp->pool[rp->cursor++] ^= val; else rp->pool[rp->cursor++] ^= ((val << rp->rotate) | (val >> (32 - rp->rotate))); /* * If we have looped around the pool, increment the rotate * variable so the next value will get xored in rotated to * a different position. * Increment by a value that is relatively prime to the word size * to try to spread the bits throughout the pool quickly when the * pool is empty. */ if (rp->cursor == RND_POOLWORDS) { rp->cursor = 0; rp->rotate = (rp->rotate + 7) & 31; } } /*! * Add a buffer's worth of data to the pool. * * Requires that the lock is held on the entropy pool. */ static void entropypool_adddata(isc_entropy_t *ent, void *p, unsigned int len, isc_uint32_t entropy) { isc_uint32_t val; unsigned long addr; isc_uint8_t *buf; /* Silly MSVC in 64 bit mode complains here... */ #ifdef _WIN64 addr = (unsigned long)((unsigned long long)p); #else addr = (unsigned long)p; #endif buf = p; if ((addr & 0x03U) != 0U) { val = 0; switch (len) { case 3: val = *buf++; len--; case 2: val = val << 8 | *buf++; len--; case 1: val = val << 8 | *buf++; len--; } entropypool_add_word(&ent->pool, val); } for (; len > 3; len -= 4) { val = *((isc_uint32_t *)buf); entropypool_add_word(&ent->pool, val); buf += 4; } if (len != 0) { val = 0; switch (len) { case 3: val = *buf++; case 2: val = val << 8 | *buf++; case 1: val = val << 8 | *buf++; } entropypool_add_word(&ent->pool, val); } add_entropy(ent, entropy); subtract_pseudo(ent, entropy); } static inline void reseed(isc_entropy_t *ent) { isc_time_t t; pid_t pid; if (ent->initcount == 0) { pid = getpid(); entropypool_adddata(ent, &pid, sizeof(pid), 0); pid = getppid(); entropypool_adddata(ent, &pid, sizeof(pid), 0); } /*! * After we've reseeded 100 times, only add new timing info every * 50 requests. This will keep us from using lots and lots of * CPU just to return bad pseudorandom data anyway. */ if (ent->initcount > 100) if ((ent->initcount % 50) != 0) return; TIME_NOW(&t); entropypool_adddata(ent, &t, sizeof(t), 0); ent->initcount++; } static inline unsigned int estimate_entropy(sample_queue_t *sq, isc_uint32_t t) { isc_int32_t delta; isc_int32_t delta2; isc_int32_t delta3; /*! * If the time counter has overflowed, calculate the real difference. * If it has not, it is simpler. */ if (t < sq->last_time) delta = UINT_MAX - sq->last_time + t; else delta = sq->last_time - t; if (delta < 0) delta = -delta; /* * Calculate the second and third order differentials */ delta2 = sq->last_delta - delta; if (delta2 < 0) delta2 = -delta2; delta3 = sq->last_delta2 - delta2; if (delta3 < 0) delta3 = -delta3; sq->last_time = t; sq->last_delta = delta; sq->last_delta2 = delta2; /* * If any delta is 0, we got no entropy. If all are non-zero, we * might have something. */ if (delta == 0 || delta2 == 0 || delta3 == 0) return 0; /* * We could find the smallest delta and claim we got log2(delta) * bits, but for now return that we found 1 bit. */ return 1; } static unsigned int crunchsamples(isc_entropy_t *ent, sample_queue_t *sq) { unsigned int ns; unsigned int added; if (sq->nsamples < 6) return (0); added = 0; sq->last_time = sq->samples[0]; sq->last_delta = 0; sq->last_delta2 = 0; /* * Prime the values by adding in the first 4 samples in. This * should completely initialize the delta calculations. */ for (ns = 0; ns < 4; ns++) (void)estimate_entropy(sq, sq->samples[ns]); for (ns = 4; ns < sq->nsamples; ns++) added += estimate_entropy(sq, sq->samples[ns]); entropypool_adddata(ent, sq->samples, sq->nsamples * 4, added); entropypool_adddata(ent, sq->extra, sq->nsamples * 4, 0); /* * Move the last 4 samples into the first 4 positions, and start * adding new samples from that point. */ for (ns = 0; ns < 4; ns++) { sq->samples[ns] = sq->samples[sq->nsamples - 4 + ns]; sq->extra[ns] = sq->extra[sq->nsamples - 4 + ns]; } sq->nsamples = 4; return (added); } static unsigned int get_from_callback(isc_entropysource_t *source, unsigned int desired, isc_boolean_t blocking) { isc_entropy_t *ent = source->ent; isc_cbsource_t *cbs = &source->sources.callback; unsigned int added; unsigned int got; isc_result_t result; if (desired == 0) return (0); if (source->bad) return (0); if (!cbs->start_called && cbs->startfunc != NULL) { result = cbs->startfunc(source, cbs->arg, blocking); if (result != ISC_R_SUCCESS) return (0); cbs->start_called = ISC_TRUE; } added = 0; result = ISC_R_SUCCESS; while (desired > 0 && result == ISC_R_SUCCESS) { result = cbs->getfunc(source, cbs->arg, blocking); if (result == ISC_R_QUEUEFULL) { got = crunchsamples(ent, &cbs->samplequeue); added += got; desired -= ISC_MIN(got, desired); result = ISC_R_SUCCESS; } else if (result != ISC_R_SUCCESS && result != ISC_R_NOTBLOCKING) source->bad = ISC_TRUE; } return (added); } /* * Extract some number of bytes from the random pool, decreasing the * estimate of randomness as each byte is extracted. * * Do this by stiring the pool and returning a part of hash as randomness. * Note that no secrets are given away here since parts of the hash are * xored together before returned. * * Honor the request from the caller to only return good data, any data, * etc. */ isc_result_t isc_entropy_getdata(isc_entropy_t *ent, void *data, unsigned int length, unsigned int *returned, unsigned int flags) { unsigned int i; isc_sha1_t hash; unsigned char digest[ISC_SHA1_DIGESTLENGTH]; isc_uint32_t remain, deltae, count, total; isc_uint8_t *buf; isc_boolean_t goodonly, partial, blocking; REQUIRE(VALID_ENTROPY(ent)); REQUIRE(data != NULL); REQUIRE(length > 0); goodonly = ISC_TF((flags & ISC_ENTROPY_GOODONLY) != 0); partial = ISC_TF((flags & ISC_ENTROPY_PARTIAL) != 0); blocking = ISC_TF((flags & ISC_ENTROPY_BLOCKING) != 0); REQUIRE(!partial || returned != NULL); LOCK(&ent->lock); remain = length; buf = data; total = 0; while (remain != 0) { count = ISC_MIN(remain, RND_ENTROPY_THRESHOLD); /* * If we are extracting good data only, make certain we * have enough data in our pool for this pass. If we don't, * get some, and fail if we can't, and partial returns * are not ok. */ if (goodonly) { unsigned int fillcount; fillcount = ISC_MAX(remain * 8, count * 8); /* * If, however, we have at least THRESHOLD_BITS * of entropy in the pool, don't block here. It is * better to drain the pool once in a while and * then refill it than it is to constantly keep the * pool full. */ if (ent->pool.entropy >= THRESHOLD_BITS) fillpool(ent, fillcount, ISC_FALSE); else fillpool(ent, fillcount, blocking); /* * Verify that we got enough entropy to do one * extraction. If we didn't, bail. */ if (ent->pool.entropy < THRESHOLD_BITS) { if (!partial) goto zeroize; else goto partial_output; } } else { /* * If we've extracted half our pool size in bits * since the last refresh, try to refresh here. */ if (ent->initialized < THRESHOLD_BITS) fillpool(ent, THRESHOLD_BITS, blocking); else fillpool(ent, 0, ISC_FALSE); /* * If we've not initialized with enough good random * data, seed with our crappy code. */ if (ent->initialized < THRESHOLD_BITS) reseed(ent); } isc_sha1_init(&hash); isc_sha1_update(&hash, (void *)(ent->pool.pool), RND_POOLBYTES); isc_sha1_final(&hash, digest); /* * Stir the extracted data (all of it) back into the pool. */ entropypool_adddata(ent, digest, ISC_SHA1_DIGESTLENGTH, 0); for (i = 0; i < count; i++) buf[i] = digest[i] ^ digest[i + RND_ENTROPY_THRESHOLD]; buf += count; remain -= count; deltae = count * 8; deltae = ISC_MIN(deltae, ent->pool.entropy); total += deltae; subtract_entropy(ent, deltae); add_pseudo(ent, count * 8); } partial_output: memset(digest, 0, sizeof(digest)); if (returned != NULL) *returned = (length - remain); UNLOCK(&ent->lock); return (ISC_R_SUCCESS); zeroize: /* put the entropy we almost extracted back */ add_entropy(ent, total); memset(data, 0, length); memset(digest, 0, sizeof(digest)); if (returned != NULL) *returned = 0; UNLOCK(&ent->lock); return (ISC_R_NOENTROPY); } static void isc_entropypool_init(isc_entropypool_t *pool) { pool->cursor = RND_POOLWORDS - 1; pool->entropy = 0; pool->pseudo = 0; pool->rotate = 0; memset(pool->pool, 0, RND_POOLBYTES); } static void isc_entropypool_invalidate(isc_entropypool_t *pool) { pool->cursor = 0; pool->entropy = 0; pool->pseudo = 0; pool->rotate = 0; memset(pool->pool, 0, RND_POOLBYTES); } isc_result_t isc_entropy_create(isc_mem_t *mctx, isc_entropy_t **entp) { isc_result_t result; isc_entropy_t *ent; REQUIRE(mctx != NULL); REQUIRE(entp != NULL && *entp == NULL); ent = isc_mem_get(mctx, sizeof(isc_entropy_t)); if (ent == NULL) return (ISC_R_NOMEMORY); /* * We need a lock. */ result = isc_mutex_init(&ent->lock); if (result != ISC_R_SUCCESS) goto errout; /* * From here down, no failures will/can occur. */ ISC_LIST_INIT(ent->sources); ent->nextsource = NULL; ent->nsources = 0; ent->mctx = NULL; isc_mem_attach(mctx, &ent->mctx); ent->refcnt = 1; ent->initialized = 0; ent->initcount = 0; ent->magic = ENTROPY_MAGIC; isc_entropypool_init(&ent->pool); *entp = ent; return (ISC_R_SUCCESS); errout: isc_mem_put(mctx, ent, sizeof(isc_entropy_t)); return (result); } /*! * Requires "ent" be locked. */ static void destroysource(isc_entropysource_t **sourcep) { isc_entropysource_t *source; isc_entropy_t *ent; isc_cbsource_t *cbs; source = *sourcep; *sourcep = NULL; ent = source->ent; ISC_LIST_UNLINK(ent->sources, source, link); ent->nextsource = NULL; REQUIRE(ent->nsources > 0); ent->nsources--; switch (source->type) { case ENTROPY_SOURCETYPE_FILE: if (! source->bad) destroyfilesource(&source->sources.file); break; case ENTROPY_SOURCETYPE_USOCKET: if (! source->bad) destroyusocketsource(&source->sources.usocket); break; case ENTROPY_SOURCETYPE_SAMPLE: samplequeue_release(ent, &source->sources.sample.samplequeue); break; case ENTROPY_SOURCETYPE_CALLBACK: cbs = &source->sources.callback; if (cbs->start_called && cbs->stopfunc != NULL) { cbs->stopfunc(source, cbs->arg); cbs->start_called = ISC_FALSE; } samplequeue_release(ent, &cbs->samplequeue); break; } memset(source, 0, sizeof(isc_entropysource_t)); isc_mem_put(ent->mctx, source, sizeof(isc_entropysource_t)); } static inline isc_boolean_t destroy_check(isc_entropy_t *ent) { isc_entropysource_t *source; if (ent->refcnt > 0) return (ISC_FALSE); source = ISC_LIST_HEAD(ent->sources); while (source != NULL) { switch (source->type) { case ENTROPY_SOURCETYPE_FILE: case ENTROPY_SOURCETYPE_USOCKET: break; default: return (ISC_FALSE); } source = ISC_LIST_NEXT(source, link); } return (ISC_TRUE); } static void destroy(isc_entropy_t **entp) { isc_entropy_t *ent; isc_entropysource_t *source; isc_mem_t *mctx; REQUIRE(entp != NULL && *entp != NULL); ent = *entp; *entp = NULL; LOCK(&ent->lock); REQUIRE(ent->refcnt == 0); /* * Here, detach non-sample sources. */ source = ISC_LIST_HEAD(ent->sources); while (source != NULL) { switch(source->type) { case ENTROPY_SOURCETYPE_FILE: case ENTROPY_SOURCETYPE_USOCKET: destroysource(&source); break; } source = ISC_LIST_HEAD(ent->sources); } /* * If there are other types of sources, we've found a bug. */ REQUIRE(ISC_LIST_EMPTY(ent->sources)); mctx = ent->mctx; isc_entropypool_invalidate(&ent->pool); UNLOCK(&ent->lock); DESTROYLOCK(&ent->lock); memset(ent, 0, sizeof(isc_entropy_t)); isc_mem_put(mctx, ent, sizeof(isc_entropy_t)); isc_mem_detach(&mctx); } void isc_entropy_destroysource(isc_entropysource_t **sourcep) { isc_entropysource_t *source; isc_entropy_t *ent; isc_boolean_t killit; REQUIRE(sourcep != NULL); REQUIRE(VALID_SOURCE(*sourcep)); source = *sourcep; *sourcep = NULL; ent = source->ent; REQUIRE(VALID_ENTROPY(ent)); LOCK(&ent->lock); destroysource(&source); killit = destroy_check(ent); UNLOCK(&ent->lock); if (killit) destroy(&ent); } isc_result_t isc_entropy_createcallbacksource(isc_entropy_t *ent, isc_entropystart_t start, isc_entropyget_t get, isc_entropystop_t stop, void *arg, isc_entropysource_t **sourcep) { isc_result_t result; isc_entropysource_t *source; isc_cbsource_t *cbs; REQUIRE(VALID_ENTROPY(ent)); REQUIRE(get != NULL); REQUIRE(sourcep != NULL && *sourcep == NULL); LOCK(&ent->lock); source = isc_mem_get(ent->mctx, sizeof(isc_entropysource_t)); if (source == NULL) { result = ISC_R_NOMEMORY; goto errout; } source->bad = ISC_FALSE; cbs = &source->sources.callback; result = samplesource_allocate(ent, &cbs->samplequeue); if (result != ISC_R_SUCCESS) goto errout; cbs->start_called = ISC_FALSE; cbs->startfunc = start; cbs->getfunc = get; cbs->stopfunc = stop; cbs->arg = arg; /* * From here down, no failures can occur. */ source->magic = SOURCE_MAGIC; source->type = ENTROPY_SOURCETYPE_CALLBACK; source->ent = ent; source->total = 0; memset(source->name, 0, sizeof(source->name)); ISC_LINK_INIT(source, link); /* * Hook it into the entropy system. */ ISC_LIST_APPEND(ent->sources, source, link); ent->nsources++; *sourcep = source; UNLOCK(&ent->lock); return (ISC_R_SUCCESS); errout: if (source != NULL) isc_mem_put(ent->mctx, source, sizeof(isc_entropysource_t)); UNLOCK(&ent->lock); return (result); } void isc_entropy_stopcallbacksources(isc_entropy_t *ent) { isc_entropysource_t *source; isc_cbsource_t *cbs; REQUIRE(VALID_ENTROPY(ent)); LOCK(&ent->lock); source = ISC_LIST_HEAD(ent->sources); while (source != NULL) { if (source->type == ENTROPY_SOURCETYPE_CALLBACK) { cbs = &source->sources.callback; if (cbs->start_called && cbs->stopfunc != NULL) { cbs->stopfunc(source, cbs->arg); cbs->start_called = ISC_FALSE; } } source = ISC_LIST_NEXT(source, link); } UNLOCK(&ent->lock); } isc_result_t isc_entropy_createsamplesource(isc_entropy_t *ent, isc_entropysource_t **sourcep) { isc_result_t result; isc_entropysource_t *source; sample_queue_t *sq; REQUIRE(VALID_ENTROPY(ent)); REQUIRE(sourcep != NULL && *sourcep == NULL); LOCK(&ent->lock); source = isc_mem_get(ent->mctx, sizeof(isc_entropysource_t)); if (source == NULL) { result = ISC_R_NOMEMORY; goto errout; } sq = &source->sources.sample.samplequeue; result = samplesource_allocate(ent, sq); if (result != ISC_R_SUCCESS) goto errout; /* * From here down, no failures can occur. */ source->magic = SOURCE_MAGIC; source->type = ENTROPY_SOURCETYPE_SAMPLE; source->ent = ent; source->total = 0; memset(source->name, 0, sizeof(source->name)); ISC_LINK_INIT(source, link); /* * Hook it into the entropy system. */ ISC_LIST_APPEND(ent->sources, source, link); ent->nsources++; *sourcep = source; UNLOCK(&ent->lock); return (ISC_R_SUCCESS); errout: if (source != NULL) isc_mem_put(ent->mctx, source, sizeof(isc_entropysource_t)); UNLOCK(&ent->lock); return (result); } /*! * Add a sample, and return ISC_R_SUCCESS if the queue has become full, * ISC_R_NOENTROPY if it has space remaining, and ISC_R_NOMORE if the * queue was full when this function was called. */ static isc_result_t addsample(sample_queue_t *sq, isc_uint32_t sample, isc_uint32_t extra) { if (sq->nsamples >= RND_EVENTQSIZE) return (ISC_R_NOMORE); sq->samples[sq->nsamples] = sample; sq->extra[sq->nsamples] = extra; sq->nsamples++; if (sq->nsamples >= RND_EVENTQSIZE) return (ISC_R_QUEUEFULL); return (ISC_R_SUCCESS); } isc_result_t isc_entropy_addsample(isc_entropysource_t *source, isc_uint32_t sample, isc_uint32_t extra) { isc_entropy_t *ent; sample_queue_t *sq; unsigned int entropy; isc_result_t result; REQUIRE(VALID_SOURCE(source)); ent = source->ent; LOCK(&ent->lock); sq = &source->sources.sample.samplequeue; result = addsample(sq, sample, extra); if (result == ISC_R_QUEUEFULL) { entropy = crunchsamples(ent, sq); add_entropy(ent, entropy); } UNLOCK(&ent->lock); return (result); } isc_result_t isc_entropy_addcallbacksample(isc_entropysource_t *source, isc_uint32_t sample, isc_uint32_t extra) { sample_queue_t *sq; isc_result_t result; REQUIRE(VALID_SOURCE(source)); REQUIRE(source->type == ENTROPY_SOURCETYPE_CALLBACK); sq = &source->sources.callback.samplequeue; result = addsample(sq, sample, extra); return (result); } void isc_entropy_putdata(isc_entropy_t *ent, void *data, unsigned int length, isc_uint32_t entropy) { REQUIRE(VALID_ENTROPY(ent)); LOCK(&ent->lock); entropypool_adddata(ent, data, length, entropy); if (ent->initialized < THRESHOLD_BITS) ent->initialized = THRESHOLD_BITS; UNLOCK(&ent->lock); } static void dumpstats(isc_entropy_t *ent, FILE *out) { fprintf(out, isc_msgcat_get(isc_msgcat, ISC_MSGSET_ENTROPY, ISC_MSG_ENTROPYSTATS, "Entropy pool %p: refcnt %u cursor %u," " rotate %u entropy %u pseudo %u nsources %u" " nextsource %p initialized %u initcount %u\n"), ent, ent->refcnt, ent->pool.cursor, ent->pool.rotate, ent->pool.entropy, ent->pool.pseudo, ent->nsources, ent->nextsource, ent->initialized, ent->initcount); } /* * This function ignores locking. Use at your own risk. */ void isc_entropy_stats(isc_entropy_t *ent, FILE *out) { REQUIRE(VALID_ENTROPY(ent)); LOCK(&ent->lock); dumpstats(ent, out); UNLOCK(&ent->lock); } unsigned int isc_entropy_status(isc_entropy_t *ent) { unsigned int estimate; LOCK(&ent->lock); estimate = ent->pool.entropy; UNLOCK(&ent->lock); return estimate; } void isc_entropy_attach(isc_entropy_t *ent, isc_entropy_t **entp) { REQUIRE(VALID_ENTROPY(ent)); REQUIRE(entp != NULL && *entp == NULL); LOCK(&ent->lock); ent->refcnt++; *entp = ent; UNLOCK(&ent->lock); } void isc_entropy_detach(isc_entropy_t **entp) { isc_entropy_t *ent; isc_boolean_t killit; REQUIRE(entp != NULL && VALID_ENTROPY(*entp)); ent = *entp; *entp = NULL; LOCK(&ent->lock); REQUIRE(ent->refcnt > 0); ent->refcnt--; killit = destroy_check(ent); UNLOCK(&ent->lock); if (killit) destroy(&ent); } static isc_result_t kbdstart(isc_entropysource_t *source, void *arg, isc_boolean_t blocking) { /* * The intent of "first" is to provide a warning message only once * during the run of a program that might try to gather keyboard * entropy multiple times. */ static isc_boolean_t first = ISC_TRUE; UNUSED(arg); if (! blocking) return (ISC_R_NOENTROPY); if (first) { if (source->warn_keyboard) fprintf(stderr, "You must use the keyboard to create " "entropy, since your system is lacking\n" "/dev/random (or equivalent)\n\n"); first = ISC_FALSE; } fprintf(stderr, "start typing:\n"); return (isc_keyboard_open(&source->kbd)); } static void kbdstop(isc_entropysource_t *source, void *arg) { UNUSED(arg); if (! isc_keyboard_canceled(&source->kbd)) fprintf(stderr, "stop typing.\r\n"); (void)isc_keyboard_close(&source->kbd, 3); } static isc_result_t kbdget(isc_entropysource_t *source, void *arg, isc_boolean_t blocking) { isc_result_t result; isc_time_t t; isc_uint32_t sample; isc_uint32_t extra; unsigned char c; UNUSED(arg); if (!blocking) return (ISC_R_NOTBLOCKING); result = isc_keyboard_getchar(&source->kbd, &c); if (result != ISC_R_SUCCESS) return (result); TIME_NOW(&t); sample = isc_time_nanoseconds(&t); extra = c; result = isc_entropy_addcallbacksample(source, sample, extra); if (result != ISC_R_SUCCESS) { fprintf(stderr, "\r\n"); return (result); } fprintf(stderr, "."); fflush(stderr); return (result); } isc_result_t isc_entropy_usebestsource(isc_entropy_t *ectx, isc_entropysource_t **source, const char *randomfile, int use_keyboard) { isc_result_t result; isc_result_t final_result = ISC_R_NOENTROPY; isc_boolean_t userfile = ISC_TRUE; REQUIRE(VALID_ENTROPY(ectx)); REQUIRE(source != NULL && *source == NULL); REQUIRE(use_keyboard == ISC_ENTROPY_KEYBOARDYES || use_keyboard == ISC_ENTROPY_KEYBOARDNO || use_keyboard == ISC_ENTROPY_KEYBOARDMAYBE); #ifdef PKCS11CRYPTO if (randomfile != NULL) pk11_rand_seed_fromfile(randomfile); #endif #ifdef PATH_RANDOMDEV if (randomfile == NULL) { randomfile = PATH_RANDOMDEV; userfile = ISC_FALSE; } #endif if (randomfile != NULL && use_keyboard != ISC_ENTROPY_KEYBOARDYES) { result = isc_entropy_createfilesource(ectx, randomfile); if (result == ISC_R_SUCCESS && use_keyboard == ISC_ENTROPY_KEYBOARDMAYBE) use_keyboard = ISC_ENTROPY_KEYBOARDNO; if (result != ISC_R_SUCCESS && userfile) return (result); final_result = result; } if (use_keyboard != ISC_ENTROPY_KEYBOARDNO) { result = isc_entropy_createcallbacksource(ectx, kbdstart, kbdget, kbdstop, NULL, source); if (result == ISC_R_SUCCESS) (*source)->warn_keyboard = ISC_TF(use_keyboard == ISC_ENTROPY_KEYBOARDMAYBE); if (final_result != ISC_R_SUCCESS) final_result = result; } /* * final_result is ISC_R_SUCCESS if at least one source of entropy * could be started, otherwise it is the error from the most recently * failed operation (or ISC_R_NOENTROPY if PATH_RANDOMDEV is not * defined and use_keyboard is ISC_ENTROPY_KEYBOARDNO). */ return (final_result); } bind9-9.10.3.dfsg.P4/lib/isc/base32.c0000644000470500017500000002565612664710322016156 0ustar lamontlamont/* * Copyright (C) 2008, 2009, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: base32.c,v 1.6.698.1 2012/02/15 05:00:16 marka Exp $ */ /*! \file */ #include #include #include #include #include #include #include #define RETERR(x) do { \ isc_result_t _r = (x); \ if (_r != ISC_R_SUCCESS) \ return (_r); \ } while (0) /*@{*/ /*! * These static functions are also present in lib/dns/rdata.c. I'm not * sure where they should go. -- bwelling */ static isc_result_t str_totext(const char *source, isc_buffer_t *target); static isc_result_t mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length); /*@}*/ static const char base32[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=abcdefghijklmnopqrstuvwxyz234567"; static const char base32hex[] = "0123456789ABCDEFGHIJKLMNOPQRSTUV=0123456789abcdefghijklmnopqrstuv"; static isc_result_t base32_totext(isc_region_t *source, int wordlength, const char *wordbreak, isc_buffer_t *target, const char base[], char pad) { char buf[9]; unsigned int loops = 0; if (wordlength >= 0 && wordlength < 8) wordlength = 8; memset(buf, 0, sizeof(buf)); while (source->length > 0) { buf[0] = base[((source->base[0]>>3)&0x1f)]; /* 5 + */ if (source->length == 1) { buf[1] = base[(source->base[0]<<2)&0x1c]; buf[2] = buf[3] = buf[4] = pad; buf[5] = buf[6] = buf[7] = pad; RETERR(str_totext(buf, target)); break; } buf[1] = base[((source->base[0]<<2)&0x1c)| /* 3 = 8 */ ((source->base[1]>>6)&0x03)]; /* 2 + */ buf[2] = base[((source->base[1]>>1)&0x1f)]; /* 5 + */ if (source->length == 2) { buf[3] = base[(source->base[1]<<4)&0x10]; buf[4] = buf[5] = buf[6] = buf[7] = pad; RETERR(str_totext(buf, target)); break; } buf[3] = base[((source->base[1]<<4)&0x10)| /* 1 = 8 */ ((source->base[2]>>4)&0x0f)]; /* 4 + */ if (source->length == 3) { buf[4] = base[(source->base[2]<<1)&0x1e]; buf[5] = buf[6] = buf[7] = pad; RETERR(str_totext(buf, target)); break; } buf[4] = base[((source->base[2]<<1)&0x1e)| /* 4 = 8 */ ((source->base[3]>>7)&0x01)]; /* 1 + */ buf[5] = base[((source->base[3]>>2)&0x1f)]; /* 5 + */ if (source->length == 4) { buf[6] = base[(source->base[3]<<3)&0x18]; buf[7] = pad; RETERR(str_totext(buf, target)); break; } buf[6] = base[((source->base[3]<<3)&0x18)| /* 2 = 8 */ ((source->base[4]>>5)&0x07)]; /* 3 + */ buf[7] = base[source->base[4]&0x1f]; /* 5 = 8 */ RETERR(str_totext(buf, target)); isc_region_consume(source, 5); loops++; if (source->length != 0 && wordlength >= 0 && (int)((loops + 1) * 8) >= wordlength) { loops = 0; RETERR(str_totext(wordbreak, target)); } } if (source->length > 0) isc_region_consume(source, source->length); return (ISC_R_SUCCESS); } isc_result_t isc_base32_totext(isc_region_t *source, int wordlength, const char *wordbreak, isc_buffer_t *target) { return (base32_totext(source, wordlength, wordbreak, target, base32, '=')); } isc_result_t isc_base32hex_totext(isc_region_t *source, int wordlength, const char *wordbreak, isc_buffer_t *target) { return (base32_totext(source, wordlength, wordbreak, target, base32hex, '=')); } isc_result_t isc_base32hexnp_totext(isc_region_t *source, int wordlength, const char *wordbreak, isc_buffer_t *target) { return (base32_totext(source, wordlength, wordbreak, target, base32hex, 0)); } /*% * State of a base32 decoding process in progress. */ typedef struct { int length; /*%< Desired length of binary data or -1 */ isc_buffer_t *target; /*%< Buffer for resulting binary data */ int digits; /*%< Number of buffered base32 digits */ isc_boolean_t seen_end; /*%< True if "=" end marker seen */ int val[8]; const char *base; /*%< Which encoding we are using */ int seen_32; /*%< Number of significant bytes if non zero */ isc_boolean_t pad; /*%< Expect padding */ } base32_decode_ctx_t; static inline void base32_decode_init(base32_decode_ctx_t *ctx, int length, const char base[], isc_boolean_t pad, isc_buffer_t *target) { ctx->digits = 0; ctx->seen_end = ISC_FALSE; ctx->seen_32 = 0; ctx->length = length; ctx->target = target; ctx->base = base; ctx->pad = pad; } static inline isc_result_t base32_decode_char(base32_decode_ctx_t *ctx, int c) { char *s; unsigned int last; if (ctx->seen_end) return (ISC_R_BADBASE32); if ((s = strchr(ctx->base, c)) == NULL) return (ISC_R_BADBASE32); last = (unsigned int)(s - ctx->base); /* * Handle lower case. */ if (last > 32) last -= 33; /* * Check that padding is contiguous. */ if (last != 32 && ctx->seen_32 != 0) return (ISC_R_BADBASE32); /* * If padding is not permitted flag padding as a error. */ if (last == 32 && !ctx->pad) return (ISC_R_BADBASE32); /* * Check that padding starts at the right place and that * bits that should be zero are. * Record how many significant bytes in answer (seen_32). */ if (last == 32 && ctx->seen_32 == 0) switch (ctx->digits) { case 0: case 1: return (ISC_R_BADBASE32); case 2: if ((ctx->val[1]&0x03) != 0) return (ISC_R_BADBASE32); ctx->seen_32 = 1; break; case 3: return (ISC_R_BADBASE32); case 4: if ((ctx->val[3]&0x0f) != 0) return (ISC_R_BADBASE32); ctx->seen_32 = 3; break; case 5: if ((ctx->val[4]&0x01) != 0) return (ISC_R_BADBASE32); ctx->seen_32 = 3; break; case 6: return (ISC_R_BADBASE32); case 7: if ((ctx->val[6]&0x07) != 0) return (ISC_R_BADBASE32); ctx->seen_32 = 4; break; } /* * Zero fill pad values. */ ctx->val[ctx->digits++] = (last == 32) ? 0 : last; if (ctx->digits == 8) { int n = 5; unsigned char buf[5]; if (ctx->seen_32 != 0) { ctx->seen_end = ISC_TRUE; n = ctx->seen_32; } buf[0] = (ctx->val[0]<<3)|(ctx->val[1]>>2); buf[1] = (ctx->val[1]<<6)|(ctx->val[2]<<1)|(ctx->val[3]>>4); buf[2] = (ctx->val[3]<<4)|(ctx->val[4]>>1); buf[3] = (ctx->val[4]<<7)|(ctx->val[5]<<2)|(ctx->val[6]>>3); buf[4] = (ctx->val[6]<<5)|(ctx->val[7]); RETERR(mem_tobuffer(ctx->target, buf, n)); if (ctx->length >= 0) { if (n > ctx->length) return (ISC_R_BADBASE32); else ctx->length -= n; } ctx->digits = 0; } return (ISC_R_SUCCESS); } static inline isc_result_t base32_decode_finish(base32_decode_ctx_t *ctx) { if (ctx->length > 0) return (ISC_R_UNEXPECTEDEND); /* * Add missing padding if required. */ if (!ctx->pad && ctx->digits != 0) { ctx->pad = ISC_TRUE; do { RETERR(base32_decode_char(ctx, '=')); } while (ctx->digits != 0); } if (ctx->digits != 0) return (ISC_R_BADBASE32); return (ISC_R_SUCCESS); } static isc_result_t base32_tobuffer(isc_lex_t *lexer, const char base[], isc_boolean_t pad, isc_buffer_t *target, int length) { base32_decode_ctx_t ctx; isc_textregion_t *tr; isc_token_t token; isc_boolean_t eol; base32_decode_init(&ctx, length, base, pad, target); while (!ctx.seen_end && (ctx.length != 0)) { unsigned int i; if (length > 0) eol = ISC_FALSE; else eol = ISC_TRUE; RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, eol)); if (token.type != isc_tokentype_string) break; tr = &token.value.as_textregion; for (i = 0; i < tr->length; i++) RETERR(base32_decode_char(&ctx, tr->base[i])); } if (ctx.length < 0 && !ctx.seen_end) isc_lex_ungettoken(lexer, &token); RETERR(base32_decode_finish(&ctx)); return (ISC_R_SUCCESS); } isc_result_t isc_base32_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) { return (base32_tobuffer(lexer, base32, ISC_TRUE, target, length)); } isc_result_t isc_base32hex_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) { return (base32_tobuffer(lexer, base32hex, ISC_TRUE, target, length)); } isc_result_t isc_base32hexnp_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) { return (base32_tobuffer(lexer, base32hex, ISC_FALSE, target, length)); } static isc_result_t base32_decodestring(const char *cstr, const char base[], isc_boolean_t pad, isc_buffer_t *target) { base32_decode_ctx_t ctx; base32_decode_init(&ctx, -1, base, pad, target); for (;;) { int c = *cstr++; if (c == '\0') break; if (c == ' ' || c == '\t' || c == '\n' || c== '\r') continue; RETERR(base32_decode_char(&ctx, c)); } RETERR(base32_decode_finish(&ctx)); return (ISC_R_SUCCESS); } isc_result_t isc_base32_decodestring(const char *cstr, isc_buffer_t *target) { return (base32_decodestring(cstr, base32, ISC_TRUE, target)); } isc_result_t isc_base32hex_decodestring(const char *cstr, isc_buffer_t *target) { return (base32_decodestring(cstr, base32hex, ISC_TRUE, target)); } isc_result_t isc_base32hexnp_decodestring(const char *cstr, isc_buffer_t *target) { return (base32_decodestring(cstr, base32hex, ISC_FALSE, target)); } static isc_result_t base32_decoderegion(isc_region_t *source, const char base[], isc_boolean_t pad, isc_buffer_t *target) { base32_decode_ctx_t ctx; base32_decode_init(&ctx, -1, base, pad, target); while (source->length != 0) { int c = *source->base; RETERR(base32_decode_char(&ctx, c)); isc_region_consume(source, 1); } RETERR(base32_decode_finish(&ctx)); return (ISC_R_SUCCESS); } isc_result_t isc_base32_decoderegion(isc_region_t *source, isc_buffer_t *target) { return (base32_decoderegion(source, base32, ISC_TRUE, target)); } isc_result_t isc_base32hex_decoderegion(isc_region_t *source, isc_buffer_t *target) { return (base32_decoderegion(source, base32hex, ISC_TRUE, target)); } isc_result_t isc_base32hexnp_decoderegion(isc_region_t *source, isc_buffer_t *target) { return (base32_decoderegion(source, base32hex, ISC_FALSE, target)); } static isc_result_t str_totext(const char *source, isc_buffer_t *target) { unsigned int l; isc_region_t region; isc_buffer_availableregion(target, ®ion); l = strlen(source); if (l > region.length) return (ISC_R_NOSPACE); memmove(region.base, source, l); isc_buffer_add(target, l); return (ISC_R_SUCCESS); } static isc_result_t mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) { isc_region_t tr; isc_buffer_availableregion(target, &tr); if (length > tr.length) return (ISC_R_NOSPACE); memmove(tr.base, base, length); isc_buffer_add(target, length); return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/isc/lex.c0000644000470500017500000005507112664710322015661 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2013-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lex.c,v 1.86 2007/09/17 09:56:29 shane Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include typedef struct inputsource { isc_result_t result; isc_boolean_t is_file; isc_boolean_t need_close; isc_boolean_t at_eof; isc_boolean_t last_was_eol; isc_buffer_t * pushback; unsigned int ignored; void * input; char * name; unsigned long line; unsigned long saved_line; ISC_LINK(struct inputsource) link; } inputsource; #define LEX_MAGIC ISC_MAGIC('L', 'e', 'x', '!') #define VALID_LEX(l) ISC_MAGIC_VALID(l, LEX_MAGIC) struct isc_lex { /* Unlocked. */ unsigned int magic; isc_mem_t * mctx; size_t max_token; char * data; unsigned int comments; isc_boolean_t comment_ok; isc_boolean_t last_was_eol; unsigned int paren_count; unsigned int saved_paren_count; isc_lexspecials_t specials; LIST(struct inputsource) sources; }; static inline isc_result_t grow_data(isc_lex_t *lex, size_t *remainingp, char **currp, char **prevp) { char *new; new = isc_mem_get(lex->mctx, lex->max_token * 2 + 1); if (new == NULL) return (ISC_R_NOMEMORY); memmove(new, lex->data, lex->max_token + 1); *currp = new + (*currp - lex->data); if (*prevp != NULL) *prevp = new + (*prevp - lex->data); isc_mem_put(lex->mctx, lex->data, lex->max_token + 1); lex->data = new; *remainingp += lex->max_token; lex->max_token *= 2; return (ISC_R_SUCCESS); } isc_result_t isc_lex_create(isc_mem_t *mctx, size_t max_token, isc_lex_t **lexp) { isc_lex_t *lex; /* * Create a lexer. */ REQUIRE(lexp != NULL && *lexp == NULL); REQUIRE(max_token > 0U); lex = isc_mem_get(mctx, sizeof(*lex)); if (lex == NULL) return (ISC_R_NOMEMORY); lex->data = isc_mem_get(mctx, max_token + 1); if (lex->data == NULL) { isc_mem_put(mctx, lex, sizeof(*lex)); return (ISC_R_NOMEMORY); } lex->mctx = mctx; lex->max_token = max_token; lex->comments = 0; lex->comment_ok = ISC_TRUE; lex->last_was_eol = ISC_TRUE; lex->paren_count = 0; lex->saved_paren_count = 0; memset(lex->specials, 0, 256); INIT_LIST(lex->sources); lex->magic = LEX_MAGIC; *lexp = lex; return (ISC_R_SUCCESS); } void isc_lex_destroy(isc_lex_t **lexp) { isc_lex_t *lex; /* * Destroy the lexer. */ REQUIRE(lexp != NULL); lex = *lexp; REQUIRE(VALID_LEX(lex)); while (!EMPTY(lex->sources)) RUNTIME_CHECK(isc_lex_close(lex) == ISC_R_SUCCESS); if (lex->data != NULL) isc_mem_put(lex->mctx, lex->data, lex->max_token + 1); lex->magic = 0; isc_mem_put(lex->mctx, lex, sizeof(*lex)); *lexp = NULL; } unsigned int isc_lex_getcomments(isc_lex_t *lex) { /* * Return the current lexer commenting styles. */ REQUIRE(VALID_LEX(lex)); return (lex->comments); } void isc_lex_setcomments(isc_lex_t *lex, unsigned int comments) { /* * Set allowed lexer commenting styles. */ REQUIRE(VALID_LEX(lex)); lex->comments = comments; } void isc_lex_getspecials(isc_lex_t *lex, isc_lexspecials_t specials) { /* * Put the current list of specials into 'specials'. */ REQUIRE(VALID_LEX(lex)); memmove(specials, lex->specials, 256); } void isc_lex_setspecials(isc_lex_t *lex, isc_lexspecials_t specials) { /* * The characters in 'specials' are returned as tokens. Along with * whitespace, they delimit strings and numbers. */ REQUIRE(VALID_LEX(lex)); memmove(lex->specials, specials, 256); } static inline isc_result_t new_source(isc_lex_t *lex, isc_boolean_t is_file, isc_boolean_t need_close, void *input, const char *name) { inputsource *source; isc_result_t result; source = isc_mem_get(lex->mctx, sizeof(*source)); if (source == NULL) return (ISC_R_NOMEMORY); source->result = ISC_R_SUCCESS; source->is_file = is_file; source->need_close = need_close; source->at_eof = ISC_FALSE; source->last_was_eol = lex->last_was_eol; source->input = input; source->name = isc_mem_strdup(lex->mctx, name); if (source->name == NULL) { isc_mem_put(lex->mctx, source, sizeof(*source)); return (ISC_R_NOMEMORY); } source->pushback = NULL; result = isc_buffer_allocate(lex->mctx, &source->pushback, (unsigned int)lex->max_token); if (result != ISC_R_SUCCESS) { isc_mem_free(lex->mctx, source->name); isc_mem_put(lex->mctx, source, sizeof(*source)); return (result); } source->ignored = 0; source->line = 1; ISC_LIST_INITANDPREPEND(lex->sources, source, link); return (ISC_R_SUCCESS); } isc_result_t isc_lex_openfile(isc_lex_t *lex, const char *filename) { isc_result_t result; FILE *stream = NULL; /* * Open 'filename' and make it the current input source for 'lex'. */ REQUIRE(VALID_LEX(lex)); result = isc_stdio_open(filename, "r", &stream); if (result != ISC_R_SUCCESS) return (result); result = new_source(lex, ISC_TRUE, ISC_TRUE, stream, filename); if (result != ISC_R_SUCCESS) (void)fclose(stream); return (result); } isc_result_t isc_lex_openstream(isc_lex_t *lex, FILE *stream) { char name[128]; /* * Make 'stream' the current input source for 'lex'. */ REQUIRE(VALID_LEX(lex)); snprintf(name, sizeof(name), "stream-%p", stream); return (new_source(lex, ISC_TRUE, ISC_FALSE, stream, name)); } isc_result_t isc_lex_openbuffer(isc_lex_t *lex, isc_buffer_t *buffer) { char name[128]; /* * Make 'buffer' the current input source for 'lex'. */ REQUIRE(VALID_LEX(lex)); snprintf(name, sizeof(name), "buffer-%p", buffer); return (new_source(lex, ISC_FALSE, ISC_FALSE, buffer, name)); } isc_result_t isc_lex_close(isc_lex_t *lex) { inputsource *source; /* * Close the most recently opened object (i.e. file or buffer). */ REQUIRE(VALID_LEX(lex)); source = HEAD(lex->sources); if (source == NULL) return (ISC_R_NOMORE); ISC_LIST_UNLINK(lex->sources, source, link); lex->last_was_eol = source->last_was_eol; if (source->is_file) { if (source->need_close) (void)fclose((FILE *)(source->input)); } isc_mem_free(lex->mctx, source->name); isc_buffer_free(&source->pushback); isc_mem_put(lex->mctx, source, sizeof(*source)); return (ISC_R_SUCCESS); } typedef enum { lexstate_start, lexstate_crlf, lexstate_string, lexstate_number, lexstate_maybecomment, lexstate_ccomment, lexstate_ccommentend, lexstate_eatline, lexstate_qstring } lexstate; #define IWSEOL (ISC_LEXOPT_INITIALWS | ISC_LEXOPT_EOL) static void pushback(inputsource *source, int c) { REQUIRE(source->pushback->current > 0); if (c == EOF) { source->at_eof = ISC_FALSE; return; } source->pushback->current--; if (c == '\n') source->line--; } static isc_result_t pushandgrow(isc_lex_t *lex, inputsource *source, int c) { if (isc_buffer_availablelength(source->pushback) == 0) { isc_buffer_t *tbuf = NULL; unsigned int oldlen; isc_region_t used; isc_result_t result; oldlen = isc_buffer_length(source->pushback); result = isc_buffer_allocate(lex->mctx, &tbuf, oldlen * 2); if (result != ISC_R_SUCCESS) return (result); isc_buffer_usedregion(source->pushback, &used); result = isc_buffer_copyregion(tbuf, &used); INSIST(result == ISC_R_SUCCESS); tbuf->current = source->pushback->current; isc_buffer_free(&source->pushback); source->pushback = tbuf; } isc_buffer_putuint8(source->pushback, (isc_uint8_t)c); return (ISC_R_SUCCESS); } isc_result_t isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { inputsource *source; int c; isc_boolean_t done = ISC_FALSE; isc_boolean_t no_comments = ISC_FALSE; isc_boolean_t escaped = ISC_FALSE; lexstate state = lexstate_start; lexstate saved_state = lexstate_start; isc_buffer_t *buffer; FILE *stream; char *curr, *prev; size_t remaining; isc_uint32_t as_ulong; unsigned int saved_options; isc_result_t result; /* * Get the next token. */ REQUIRE(VALID_LEX(lex)); source = HEAD(lex->sources); REQUIRE(tokenp != NULL); if (source == NULL) { if ((options & ISC_LEXOPT_NOMORE) != 0) { tokenp->type = isc_tokentype_nomore; return (ISC_R_SUCCESS); } return (ISC_R_NOMORE); } if (source->result != ISC_R_SUCCESS) return (source->result); lex->saved_paren_count = lex->paren_count; source->saved_line = source->line; if (isc_buffer_remaininglength(source->pushback) == 0 && source->at_eof) { if ((options & ISC_LEXOPT_DNSMULTILINE) != 0 && lex->paren_count != 0) { lex->paren_count = 0; return (ISC_R_UNBALANCED); } if ((options & ISC_LEXOPT_EOF) != 0) { tokenp->type = isc_tokentype_eof; return (ISC_R_SUCCESS); } return (ISC_R_EOF); } isc_buffer_compact(source->pushback); saved_options = options; if ((options & ISC_LEXOPT_DNSMULTILINE) != 0 && lex->paren_count > 0) options &= ~IWSEOL; curr = lex->data; *curr = '\0'; prev = NULL; remaining = lex->max_token; #ifdef HAVE_FLOCKFILE if (source->is_file) flockfile(source->input); #endif do { if (isc_buffer_remaininglength(source->pushback) == 0) { if (source->is_file) { stream = source->input; #if defined(HAVE_FLOCKFILE) && defined(HAVE_GETCUNLOCKED) c = getc_unlocked(stream); #else c = getc(stream); #endif if (c == EOF) { if (ferror(stream)) { source->result = ISC_R_IOERROR; result = source->result; goto done; } source->at_eof = ISC_TRUE; } } else { buffer = source->input; if (buffer->current == buffer->used) { c = EOF; source->at_eof = ISC_TRUE; } else { c = *((unsigned char *)buffer->base + buffer->current); buffer->current++; } } if (c != EOF) { source->result = pushandgrow(lex, source, c); if (source->result != ISC_R_SUCCESS) { result = source->result; goto done; } } } if (!source->at_eof) { if (state == lexstate_start) /* Token has not started yet. */ source->ignored = isc_buffer_consumedlength(source->pushback); c = isc_buffer_getuint8(source->pushback); } else { c = EOF; } if (c == '\n') source->line++; if (lex->comment_ok && !no_comments) { if (!escaped && c == ';' && ((lex->comments & ISC_LEXCOMMENT_DNSMASTERFILE) != 0)) { saved_state = state; state = lexstate_eatline; no_comments = ISC_TRUE; continue; } else if (c == '/' && (lex->comments & (ISC_LEXCOMMENT_C| ISC_LEXCOMMENT_CPLUSPLUS)) != 0) { saved_state = state; state = lexstate_maybecomment; no_comments = ISC_TRUE; continue; } else if (c == '#' && ((lex->comments & ISC_LEXCOMMENT_SHELL) != 0)) { saved_state = state; state = lexstate_eatline; no_comments = ISC_TRUE; continue; } } no_read: /* INSIST(c == EOF || (c >= 0 && c <= 255)); */ switch (state) { case lexstate_start: if (c == EOF) { lex->last_was_eol = ISC_FALSE; if ((options & ISC_LEXOPT_DNSMULTILINE) != 0 && lex->paren_count != 0) { lex->paren_count = 0; result = ISC_R_UNBALANCED; goto done; } if ((options & ISC_LEXOPT_EOF) == 0) { result = ISC_R_EOF; goto done; } tokenp->type = isc_tokentype_eof; done = ISC_TRUE; } else if (c == ' ' || c == '\t') { if (lex->last_was_eol && (options & ISC_LEXOPT_INITIALWS) != 0) { lex->last_was_eol = ISC_FALSE; tokenp->type = isc_tokentype_initialws; tokenp->value.as_char = c; done = ISC_TRUE; } } else if (c == '\n') { if ((options & ISC_LEXOPT_EOL) != 0) { tokenp->type = isc_tokentype_eol; done = ISC_TRUE; } lex->last_was_eol = ISC_TRUE; } else if (c == '\r') { if ((options & ISC_LEXOPT_EOL) != 0) state = lexstate_crlf; } else if (c == '"' && (options & ISC_LEXOPT_QSTRING) != 0) { lex->last_was_eol = ISC_FALSE; no_comments = ISC_TRUE; state = lexstate_qstring; } else if (lex->specials[c]) { lex->last_was_eol = ISC_FALSE; if ((c == '(' || c == ')') && (options & ISC_LEXOPT_DNSMULTILINE) != 0) { if (c == '(') { if (lex->paren_count == 0) options &= ~IWSEOL; lex->paren_count++; } else { if (lex->paren_count == 0) { result = ISC_R_UNBALANCED; goto done; } lex->paren_count--; if (lex->paren_count == 0) options = saved_options; } continue; } tokenp->type = isc_tokentype_special; tokenp->value.as_char = c; done = ISC_TRUE; } else if (isdigit((unsigned char)c) && (options & ISC_LEXOPT_NUMBER) != 0) { lex->last_was_eol = ISC_FALSE; if ((options & ISC_LEXOPT_OCTAL) != 0 && (c == '8' || c == '9')) state = lexstate_string; else state = lexstate_number; goto no_read; } else { lex->last_was_eol = ISC_FALSE; state = lexstate_string; goto no_read; } break; case lexstate_crlf: if (c != '\n') pushback(source, c); tokenp->type = isc_tokentype_eol; done = ISC_TRUE; lex->last_was_eol = ISC_TRUE; break; case lexstate_number: if (c == EOF || !isdigit((unsigned char)c)) { if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == EOF || lex->specials[c]) { int base; if ((options & ISC_LEXOPT_OCTAL) != 0) base = 8; else if ((options & ISC_LEXOPT_CNUMBER) != 0) base = 0; else base = 10; pushback(source, c); result = isc_parse_uint32(&as_ulong, lex->data, base); if (result == ISC_R_SUCCESS) { tokenp->type = isc_tokentype_number; tokenp->value.as_ulong = as_ulong; } else if (result == ISC_R_BADNUMBER) { isc_tokenvalue_t *v; tokenp->type = isc_tokentype_string; v = &(tokenp->value); v->as_textregion.base = lex->data; v->as_textregion.length = (unsigned int) (lex->max_token - remaining); } else goto done; done = ISC_TRUE; continue; } else if (!(options & ISC_LEXOPT_CNUMBER) || ((c != 'x' && c != 'X') || (curr != &lex->data[1]) || (lex->data[0] != '0'))) { /* Above test supports hex numbers */ state = lexstate_string; } } else if ((options & ISC_LEXOPT_OCTAL) != 0 && (c == '8' || c == '9')) { state = lexstate_string; } if (remaining == 0U) { result = grow_data(lex, &remaining, &curr, &prev); if (result != ISC_R_SUCCESS) goto done; } INSIST(remaining > 0U); *curr++ = c; *curr = '\0'; remaining--; break; case lexstate_string: /* * EOF needs to be checked before lex->specials[c] * as lex->specials[EOF] is not a good idea. */ if (c == '\r' || c == '\n' || c == EOF || (!escaped && (c == ' ' || c == '\t' || lex->specials[c]))) { pushback(source, c); if (source->result != ISC_R_SUCCESS) { result = source->result; goto done; } tokenp->type = isc_tokentype_string; tokenp->value.as_textregion.base = lex->data; tokenp->value.as_textregion.length = (unsigned int) (lex->max_token - remaining); done = ISC_TRUE; continue; } if ((options & ISC_LEXOPT_ESCAPE) != 0) escaped = (!escaped && c == '\\') ? ISC_TRUE : ISC_FALSE; if (remaining == 0U) { result = grow_data(lex, &remaining, &curr, &prev); if (result != ISC_R_SUCCESS) goto done; } INSIST(remaining > 0U); *curr++ = c; *curr = '\0'; remaining--; break; case lexstate_maybecomment: if (c == '*' && (lex->comments & ISC_LEXCOMMENT_C) != 0) { state = lexstate_ccomment; continue; } else if (c == '/' && (lex->comments & ISC_LEXCOMMENT_CPLUSPLUS) != 0) { state = lexstate_eatline; continue; } pushback(source, c); c = '/'; no_comments = ISC_FALSE; state = saved_state; goto no_read; case lexstate_ccomment: if (c == EOF) { result = ISC_R_UNEXPECTEDEND; goto done; } if (c == '*') state = lexstate_ccommentend; break; case lexstate_ccommentend: if (c == EOF) { result = ISC_R_UNEXPECTEDEND; goto done; } if (c == '/') { /* * C-style comments become a single space. * We do this to ensure that a comment will * act as a delimiter for strings and * numbers. */ c = ' '; no_comments = ISC_FALSE; state = saved_state; goto no_read; } else if (c != '*') state = lexstate_ccomment; break; case lexstate_eatline: if ((c == '\n') || (c == EOF)) { no_comments = ISC_FALSE; state = saved_state; goto no_read; } break; case lexstate_qstring: if (c == EOF) { result = ISC_R_UNEXPECTEDEND; goto done; } if (c == '"') { if (escaped) { escaped = ISC_FALSE; /* * Overwrite the preceding backslash. */ INSIST(prev != NULL); *prev = '"'; } else { tokenp->type = isc_tokentype_qstring; tokenp->value.as_textregion.base = lex->data; tokenp->value.as_textregion.length = (unsigned int) (lex->max_token - remaining); no_comments = ISC_FALSE; done = ISC_TRUE; } } else { if (c == '\n' && !escaped && (options & ISC_LEXOPT_QSTRINGMULTILINE) == 0) { pushback(source, c); result = ISC_R_UNBALANCEDQUOTES; goto done; } if (c == '\\' && !escaped) escaped = ISC_TRUE; else escaped = ISC_FALSE; if (remaining == 0U) { result = grow_data(lex, &remaining, &curr, &prev); if (result != ISC_R_SUCCESS) goto done; } INSIST(remaining > 0U); prev = curr; *curr++ = c; *curr = '\0'; remaining--; } break; default: FATAL_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_LEX, ISC_MSG_UNEXPECTEDSTATE, "Unexpected state %d"), state); /* Does not return. */ } } while (!done); result = ISC_R_SUCCESS; done: #ifdef HAVE_FLOCKFILE if (source->is_file) funlockfile(source->input); #endif return (result); } isc_result_t isc_lex_getmastertoken(isc_lex_t *lex, isc_token_t *token, isc_tokentype_t expect, isc_boolean_t eol) { unsigned int options = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF | ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE; isc_result_t result; if (expect == isc_tokentype_qstring) options |= ISC_LEXOPT_QSTRING; else if (expect == isc_tokentype_number) options |= ISC_LEXOPT_NUMBER; result = isc_lex_gettoken(lex, options, token); if (result == ISC_R_RANGE) isc_lex_ungettoken(lex, token); if (result != ISC_R_SUCCESS) return (result); if (eol && ((token->type == isc_tokentype_eol) || (token->type == isc_tokentype_eof))) return (ISC_R_SUCCESS); if (token->type == isc_tokentype_string && expect == isc_tokentype_qstring) return (ISC_R_SUCCESS); if (token->type != expect) { isc_lex_ungettoken(lex, token); if (token->type == isc_tokentype_eol || token->type == isc_tokentype_eof) return (ISC_R_UNEXPECTEDEND); if (expect == isc_tokentype_number) return (ISC_R_BADNUMBER); return (ISC_R_UNEXPECTEDTOKEN); } return (ISC_R_SUCCESS); } isc_result_t isc_lex_getoctaltoken(isc_lex_t *lex, isc_token_t *token, isc_boolean_t eol) { unsigned int options = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF | ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE| ISC_LEXOPT_NUMBER | ISC_LEXOPT_OCTAL; isc_result_t result; result = isc_lex_gettoken(lex, options, token); if (result == ISC_R_RANGE) isc_lex_ungettoken(lex, token); if (result != ISC_R_SUCCESS) return (result); if (eol && ((token->type == isc_tokentype_eol) || (token->type == isc_tokentype_eof))) return (ISC_R_SUCCESS); if (token->type != isc_tokentype_number) { isc_lex_ungettoken(lex, token); if (token->type == isc_tokentype_eol || token->type == isc_tokentype_eof) return (ISC_R_UNEXPECTEDEND); return (ISC_R_BADNUMBER); } return (ISC_R_SUCCESS); } void isc_lex_ungettoken(isc_lex_t *lex, isc_token_t *tokenp) { inputsource *source; /* * Unget the current token. */ REQUIRE(VALID_LEX(lex)); source = HEAD(lex->sources); REQUIRE(source != NULL); REQUIRE(tokenp != NULL); REQUIRE(isc_buffer_consumedlength(source->pushback) != 0 || tokenp->type == isc_tokentype_eof); UNUSED(tokenp); isc_buffer_first(source->pushback); lex->paren_count = lex->saved_paren_count; source->line = source->saved_line; source->at_eof = ISC_FALSE; } void isc_lex_getlasttokentext(isc_lex_t *lex, isc_token_t *tokenp, isc_region_t *r) { inputsource *source; REQUIRE(VALID_LEX(lex)); source = HEAD(lex->sources); REQUIRE(source != NULL); REQUIRE(tokenp != NULL); REQUIRE(isc_buffer_consumedlength(source->pushback) != 0 || tokenp->type == isc_tokentype_eof); UNUSED(tokenp); INSIST(source->ignored <= isc_buffer_consumedlength(source->pushback)); r->base = (unsigned char *)isc_buffer_base(source->pushback) + source->ignored; r->length = isc_buffer_consumedlength(source->pushback) - source->ignored; } char * isc_lex_getsourcename(isc_lex_t *lex) { inputsource *source; REQUIRE(VALID_LEX(lex)); source = HEAD(lex->sources); if (source == NULL) return (NULL); return (source->name); } unsigned long isc_lex_getsourceline(isc_lex_t *lex) { inputsource *source; REQUIRE(VALID_LEX(lex)); source = HEAD(lex->sources); if (source == NULL) return (0); return (source->line); } isc_result_t isc_lex_setsourcename(isc_lex_t *lex, const char *name) { inputsource *source; char *newname; REQUIRE(VALID_LEX(lex)); source = HEAD(lex->sources); if (source == NULL) return(ISC_R_NOTFOUND); newname = isc_mem_strdup(lex->mctx, name); if (newname == NULL) return (ISC_R_NOMEMORY); isc_mem_free(lex->mctx, source->name); source->name = newname; return (ISC_R_SUCCESS); } isc_boolean_t isc_lex_isfile(isc_lex_t *lex) { inputsource *source; REQUIRE(VALID_LEX(lex)); source = HEAD(lex->sources); if (source == NULL) return (ISC_FALSE); return (source->is_file); } bind9-9.10.3.dfsg.P4/lib/isc/alpha/0002755000470500017500000000000012672612753016014 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/alpha/Makefile.in0000644000470500017500000000166312664710322020055 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = include TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/alpha/include/0002755000470500017500000000000012664710322017427 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/alpha/include/Makefile.in0000644000470500017500000000165712664710322021503 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = isc TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/alpha/include/isc/0002755000470500017500000000000012664710322020205 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/alpha/include/isc/Makefile.in0000644000470500017500000000223012664710322022245 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ HEADERS = atomic.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \ done bind9-9.10.3.dfsg.P4/lib/isc/alpha/include/isc/atomic.h0000644000470500017500000001323512664710322021634 0ustar lamontlamont/* * Copyright (C) 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: atomic.h,v 1.7 2009/04/08 06:48:23 tbox Exp $ */ /* * This code was written based on FreeBSD's kernel source whose copyright * follows: */ /*- * Copyright (c) 1998 Doug Rabson * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. * * $FreeBSD: src/sys/alpha/include/atomic.h,v 1.18.6.1 2004/09/13 21:52:04 wilko Exp $ */ #ifndef ISC_ATOMIC_H #define ISC_ATOMIC_H 1 #include #include #ifdef ISC_PLATFORM_USEOSFASM #include #pragma intrinsic(asm) /* * This routine atomically increments the value stored in 'p' by 'val', and * returns the previous value. Memory access ordering around this function * can be critical, so we add explicit memory block instructions at the * beginning and the end of it (same for other functions). */ static inline isc_int32_t isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) { return (asm("mb;" "1:" "ldl_l %t0, 0(%a0);" /* load old value */ "mov %t0, %v0;" /* copy the old value */ "addl %t0, %a1, %t0;" /* calculate new value */ "stl_c %t0, 0(%a0);" /* attempt to store */ "beq %t0, 1b;" /* spin if failed */ "mb;", p, val)); } /* * This routine atomically stores the value 'val' in 'p'. */ static inline void isc_atomic_store(isc_int32_t *p, isc_int32_t val) { (void)asm("mb;" "1:" "ldl_l %t0, 0(%a0);" /* load old value */ "mov %a1, %t0;" /* value to store */ "stl_c %t0, 0(%a0);" /* attempt to store */ "beq %t0, 1b;" /* spin if failed */ "mb;", p, val); } /* * This routine atomically replaces the value in 'p' with 'val', if the * original value is equal to 'cmpval'. The original value is returned in any * case. */ static inline isc_int32_t isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) { return(asm("mb;" "1:" "ldl_l %t0, 0(%a0);" /* load old value */ "mov %t0, %v0;" /* copy the old value */ "cmpeq %t0, %a1, %t0;" /* compare */ "beq %t0, 2f;" /* exit if not equal */ "mov %a2, %t0;" /* value to store */ "stl_c %t0, 0(%a0);" /* attempt to store */ "beq %t0, 1b;" /* if it failed, spin */ "2:" "mb;", p, cmpval, val)); } #elif defined (ISC_PLATFORM_USEGCCASM) static inline isc_int32_t isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) { isc_int32_t temp, prev; __asm__ volatile( "mb;" "1:" "ldl_l %0, %1;" /* load old value */ "mov %0, %2;" /* copy the old value */ "addl %0, %3, %0;" /* calculate new value */ "stl_c %0, %1;" /* attempt to store */ "beq %0, 1b;" /* spin if failed */ "mb;" : "=&r"(temp), "+m"(*p), "=&r"(prev) : "r"(val) : "memory"); return (prev); } static inline void isc_atomic_store(isc_int32_t *p, isc_int32_t val) { isc_int32_t temp; __asm__ volatile( "mb;" "1:" "ldl_l %0, %1;" /* load old value */ "mov %2, %0;" /* value to store */ "stl_c %0, %1;" /* attempt to store */ "beq %0, 1b;" /* if it failed, spin */ "mb;" : "=&r"(temp), "+m"(*p) : "r"(val) : "memory"); } static inline isc_int32_t isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) { isc_int32_t temp, prev; __asm__ volatile( "mb;" "1:" "ldl_l %0, %1;" /* load old value */ "mov %0, %2;" /* copy the old value */ "cmpeq %0, %3, %0;" /* compare */ "beq %0, 2f;" /* exit if not equal */ "mov %4, %0;" /* value to store */ "stl_c %0, %1;" /* attempt to store */ "beq %0, 1b;" /* if it failed, spin */ "2:" "mb;" : "=&r"(temp), "+m"(*p), "=&r"(prev) : "r"(cmpval), "r"(val) : "memory"); return (prev); } #else #error "unsupported compiler. disable atomic ops by --disable-atomic" #endif #endif /* ISC_ATOMIC_H */ bind9-9.10.3.dfsg.P4/lib/isc/pool.c0000644000470500017500000000775712664710322016052 0ustar lamontlamont/* * Copyright (C) 2013, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include /*** *** Types. ***/ struct isc_pool { isc_mem_t * mctx; unsigned int count; isc_pooldeallocator_t free; isc_poolinitializer_t init; void * initarg; void ** pool; }; /*** *** Functions. ***/ static isc_result_t alloc_pool(isc_mem_t *mctx, unsigned int count, isc_pool_t **poolp) { isc_pool_t *pool; pool = isc_mem_get(mctx, sizeof(*pool)); if (pool == NULL) return (ISC_R_NOMEMORY); pool->count = count; pool->free = NULL; pool->init = NULL; pool->initarg = NULL; pool->mctx = NULL; isc_mem_attach(mctx, &pool->mctx); pool->pool = isc_mem_get(mctx, count * sizeof(void *)); if (pool->pool == NULL) { isc_mem_put(mctx, pool, sizeof(*pool)); return (ISC_R_NOMEMORY); } memset(pool->pool, 0, count * sizeof(void *)); *poolp = pool; return (ISC_R_SUCCESS); } isc_result_t isc_pool_create(isc_mem_t *mctx, unsigned int count, isc_pooldeallocator_t release, isc_poolinitializer_t init, void *initarg, isc_pool_t **poolp) { isc_pool_t *pool = NULL; isc_result_t result; unsigned int i; INSIST(count > 0); /* Allocate the pool structure */ result = alloc_pool(mctx, count, &pool); if (result != ISC_R_SUCCESS) return (result); pool->free = release; pool->init = init; pool->initarg = initarg; /* Populate the pool */ for (i = 0; i < count; i++) { result = init(&pool->pool[i], initarg); if (result != ISC_R_SUCCESS) { isc_pool_destroy(&pool); return (result); } } *poolp = pool; return (ISC_R_SUCCESS); } void * isc_pool_get(isc_pool_t *pool) { isc_uint32_t i; isc_random_get(&i); return (pool->pool[i % pool->count]); } int isc_pool_count(isc_pool_t *pool) { REQUIRE(pool != NULL); return (pool->count); } isc_result_t isc_pool_expand(isc_pool_t **sourcep, unsigned int count, isc_pool_t **targetp) { isc_result_t result; isc_pool_t *pool; REQUIRE(sourcep != NULL && *sourcep != NULL); REQUIRE(targetp != NULL && *targetp == NULL); pool = *sourcep; if (count > pool->count) { isc_pool_t *newpool = NULL; unsigned int i; /* Allocate a new pool structure */ result = alloc_pool(pool->mctx, count, &newpool); if (result != ISC_R_SUCCESS) return (result); newpool->free = pool->free; newpool->init = pool->init; newpool->initarg = pool->initarg; /* Copy over the objects from the old pool */ for (i = 0; i < pool->count; i++) { newpool->pool[i] = pool->pool[i]; pool->pool[i] = NULL; } /* Populate the new entries */ for (i = pool->count; i < count; i++) { result = pool->init(&newpool->pool[i], pool->initarg); if (result != ISC_R_SUCCESS) { isc_pool_destroy(&pool); return (result); } } isc_pool_destroy(&pool); pool = newpool; } *sourcep = NULL; *targetp = pool; return (ISC_R_SUCCESS); } void isc_pool_destroy(isc_pool_t **poolp) { unsigned int i; isc_pool_t *pool = *poolp; for (i = 0; i < pool->count; i++) { if (pool->free != NULL && pool->pool[i] != NULL) pool->free(&pool->pool[i]); } isc_mem_put(pool->mctx, pool->pool, pool->count * sizeof(void *)); isc_mem_putanddetach(&pool->mctx, pool, sizeof(*pool)); *poolp = NULL; } bind9-9.10.3.dfsg.P4/lib/isc/print.c0000644000470500017500000003316112664710322016221 0ustar lamontlamont/* * Copyright (C) 2004-2008, 2010, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include /* for sprintf() */ #include /* for strlen() */ #include /* for assert() */ #define ISC__PRINT_SOURCE /* Used to get the isc_print_* prototypes. */ #include #include #include #include #include #include /* * We use the system's sprintf so we undef it here. */ #undef sprintf static int isc__print_printf(void (*emit)(char, void *), void *arg, const char *format, va_list ap); static void file_emit(char c, void *arg) { FILE *fp = arg; int i = c & 0xff; putc(i, fp); } #if 0 static int isc_print_vfprintf(FILE *fp, const char *format, va_list ap) { assert(fp != NULL); assert(format != NULL); return (isc__print_printf(file_emit, fp, format, ap)); } #endif int isc_print_printf(const char *format, ...) { va_list ap; int n; assert(format != NULL); va_start(ap, format); n = isc__print_printf(file_emit, stdout, format, ap); va_end(ap); return (n); } int isc_print_fprintf(FILE *fp, const char *format, ...) { va_list ap; int n; assert(fp != NULL); assert(format != NULL); va_start(ap, format); n = isc__print_printf(file_emit, fp, format, ap); va_end(ap); return (n); } static void nocheck_emit(char c, void *arg) { struct { char *str; } *a = arg; *(a->str)++ = c; } int isc_print_sprintf(char *str, const char *format, ...) { struct { char *str; } arg; int n; va_list ap; arg.str = str; va_start(ap, format); n = isc__print_printf(nocheck_emit, &arg, format, ap); va_end(ap); return (n); } /*! * Return length of string that would have been written if not truncated. */ int isc_print_snprintf(char *str, size_t size, const char *format, ...) { va_list ap; int ret; va_start(ap, format); ret = isc_print_vsnprintf(str, size, format, ap); va_end(ap); return (ret); } /*! * Return length of string that would have been written if not truncated. */ static void string_emit(char c, void *arg) { struct { char *str; size_t size; } *p = arg; if (p->size > 0) { *(p->str)++ = c; p->size--; } } int isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { struct { char *str; size_t size; } arg; int n; assert(str != NULL); assert(format != NULL); arg.str = str; arg.size = size; n = isc__print_printf(string_emit, &arg, format, ap); if (arg.size > 0) *arg.str = '\0'; return (n); } static int isc__print_printf(void (*emit)(char, void *), void *arg, const char *format, va_list ap) { int h; int l; int z; int q; int alt; int zero; int left; int plus; int space; int neg; isc_int64_t tmpi; isc_uint64_t tmpui; unsigned long width; unsigned long precision; unsigned int length; char buf[1024]; char c; void *v; const char *cp; const char *head; int count = 0; int pad; int zeropad; int dot; double dbl; isc_boolean_t precision_set; #ifdef HAVE_LONG_DOUBLE long double ldbl; #endif char fmt[32]; assert(emit != NULL); assert(arg != NULL); assert(format != NULL); while (*format != '\0') { if (*format != '%') { emit(*format++, arg); count++; continue; } format++; /* * Reset flags. */ dot = neg = space = plus = left = zero = alt = h = l = q = z = 0; width = precision = 0; head = ""; pad = zeropad = 0; precision_set = ISC_FALSE; do { if (*format == '#') { alt = 1; format++; } else if (*format == '-') { left = 1; zero = 0; format++; } else if (*format == ' ') { if (!plus) space = 1; format++; } else if (*format == '+') { plus = 1; space = 0; format++; } else if (*format == '0') { if (!left) zero = 1; format++; } else break; } while (1); /* * Width. */ if (*format == '*') { width = va_arg(ap, int); format++; } else if (isdigit((unsigned char)*format)) { char *e; width = strtoul(format, &e, 10); format = e; } /* * Precision. */ if (*format == '.') { format++; dot = 1; if (*format == '*') { precision = va_arg(ap, int); precision_set = ISC_TRUE; format++; } else if (isdigit((unsigned char)*format)) { char *e; precision = strtoul(format, &e, 10); precision_set = ISC_TRUE; format = e; } } switch (*format) { case '\0': continue; case '%': emit(*format, arg); count++; break; case 'q': q = 1; format++; goto doint; case 'h': h = 1; format++; goto doint; case 'l': l = 1; format++; if (*format == 'l') { q = 1; format++; } goto doint; case 'z': z = 1; format++; goto doint; case 'n': case 'i': case 'd': case 'o': case 'u': case 'x': case 'X': doint: if (precision != 0) zero = 0; switch (*format) { case 'n': if (h) { short int *p; p = va_arg(ap, short *); assert(p != NULL); *p = count; } else if (l) { long int *p; p = va_arg(ap, long *); assert(p != NULL); *p = count; } else if (z) { size_t *p; p = va_arg(ap, size_t *); assert(p != NULL); *p = count; } else { int *p; p = va_arg(ap, int *); assert(p != NULL); *p = count; } break; case 'i': case 'd': if (q) tmpi = va_arg(ap, isc_int64_t); else if (l) tmpi = va_arg(ap, long int); else if (z) tmpi = va_arg(ap, ssize_t); else tmpi = va_arg(ap, int); if (tmpi < 0) { head = "-"; tmpui = -tmpi; } else { if (plus) head = "+"; else if (space) head = " "; else head = ""; tmpui = tmpi; } if (tmpui <= 0xffffffffU) sprintf(buf, "%lu", (unsigned long)tmpui); else { unsigned long mid; unsigned long lo; unsigned long hi; lo = tmpui % 1000000000; tmpui /= 1000000000; mid = tmpui % 1000000000; hi = tmpui / 1000000000; if (hi != 0U) { sprintf(buf, "%lu", hi); sprintf(buf + strlen(buf), "%09lu", mid); } else sprintf(buf, "%lu", mid); sprintf(buf + strlen(buf), "%09lu", lo); } goto printint; case 'o': if (q) tmpui = va_arg(ap, isc_uint64_t); else if (l) tmpui = va_arg(ap, long int); else if (z) tmpui = va_arg(ap, size_t); else tmpui = va_arg(ap, int); if (tmpui <= 0xffffffffU) sprintf(buf, alt ? "%#lo" : "%lo", (unsigned long)tmpui); else { unsigned long mid; unsigned long lo; unsigned long hi; lo = tmpui % 010000000000; tmpui /= 010000000000; mid = tmpui % 010000000000; hi = tmpui / 010000000000; if (hi != 0) { sprintf(buf, alt ? "%#lo" : "%lo", hi); sprintf(buf + strlen(buf), "%09lo", mid); } else sprintf(buf, alt ? "%#lo" : "%lo", mid); sprintf(buf + strlen(buf), "%09lo", lo); } goto printint; case 'u': if (q) tmpui = va_arg(ap, isc_uint64_t); else if (l) tmpui = va_arg(ap, unsigned long int); else if (z) tmpui = va_arg(ap, size_t); else tmpui = va_arg(ap, unsigned int); if (tmpui <= 0xffffffffU) sprintf(buf, "%lu", (unsigned long)tmpui); else { unsigned long mid; unsigned long lo; unsigned long hi; lo = tmpui % 1000000000; tmpui /= 1000000000; mid = tmpui % 1000000000; hi = tmpui / 1000000000; if (hi != 0U) { sprintf(buf, "%lu", hi); sprintf(buf + strlen(buf), "%09lu", mid); } else sprintf(buf, "%lu", mid); sprintf(buf + strlen(buf), "%09lu", lo); } goto printint; case 'x': if (q) tmpui = va_arg(ap, isc_uint64_t); else if (l) tmpui = va_arg(ap, unsigned long int); else if (z) tmpui = va_arg(ap, size_t); else tmpui = va_arg(ap, unsigned int); if (alt) { head = "0x"; if (precision > 2) precision -= 2; } if (tmpui <= 0xffffffffU) sprintf(buf, "%lx", (unsigned long)tmpui); else { unsigned long hi = tmpui>>32; unsigned long lo = tmpui & 0xffffffff; sprintf(buf, "%lx", hi); sprintf(buf + strlen(buf), "%08lx", lo); } goto printint; case 'X': if (q) tmpui = va_arg(ap, isc_uint64_t); else if (l) tmpui = va_arg(ap, unsigned long int); else if (z) tmpui = va_arg(ap, size_t); else tmpui = va_arg(ap, unsigned int); if (alt) { head = "0X"; if (precision > 2) precision -= 2; } if (tmpui <= 0xffffffffU) sprintf(buf, "%lX", (unsigned long)tmpui); else { unsigned long hi = tmpui>>32; unsigned long lo = tmpui & 0xffffffff; sprintf(buf, "%lX", hi); sprintf(buf + strlen(buf), "%08lX", lo); } goto printint; printint: if (precision_set || width != 0U) { length = strlen(buf); if (length < precision) zeropad = precision - length; else if (length < width && zero) zeropad = width - length; if (width != 0) { pad = width - length - zeropad - strlen(head); if (pad < 0) pad = 0; } } count += strlen(head) + strlen(buf) + pad + zeropad; if (!left) { while (pad > 0) { emit(' ', arg); pad--; } } cp = head; while (*cp != '\0') emit(*cp++, arg); while (zeropad > 0) { emit('0', arg); zeropad--; } cp = buf; while (*cp != '\0') emit(*cp++, arg); while (pad > 0) { emit(' ', arg); pad--; } break; default: break; } break; case 's': cp = va_arg(ap, char *); if (precision_set) { /* * cp need not be NULL terminated. */ const char *tp; unsigned long n; if (precision != 0U) assert(cp != NULL); n = precision; tp = cp; while (n != 0 && *tp != '\0') n--, tp++; length = precision - n; } else { assert(cp != NULL); length = strlen(cp); } if (width != 0) { pad = width - length; if (pad < 0) pad = 0; } count += pad + length; if (!left) while (pad > 0) { emit(' ', arg); pad--; } if (precision_set) while (precision > 0U && *cp != '\0') { emit(*cp++, arg); precision--; } else while (*cp != '\0') emit(*cp++, arg); while (pad > 0) { emit(' ', arg); pad--; } break; case 'c': c = va_arg(ap, int); if (width > 0) { count += width; width--; if (left) emit(c, arg); while (width-- > 0) emit(' ', arg); if (!left) emit(c, arg); } else { count++; emit(c, arg); } break; case 'p': v = va_arg(ap, void *); sprintf(buf, "%p", v); length = strlen(buf); if (precision > length) zeropad = precision - length; if (width > 0) { pad = width - length - zeropad; if (pad < 0) pad = 0; } count += length + pad + zeropad; if (!left) while (pad > 0) { emit(' ', arg); pad--; } cp = buf; if (zeropad > 0 && buf[0] == '0' && (buf[1] == 'x' || buf[1] == 'X')) { emit(*cp++, arg); emit(*cp++, arg); while (zeropad > 0) { emit('0', arg); zeropad--; } } while (*cp != '\0') emit(*cp++, arg); while (pad > 0) { emit(' ', arg); pad--; } break; case 'D': /*deprecated*/ assert("use %ld instead of %D" == NULL); case 'O': /*deprecated*/ assert("use %lo instead of %O" == NULL); case 'U': /*deprecated*/ assert("use %lu instead of %U" == NULL); case 'L': #ifdef HAVE_LONG_DOUBLE l = 1; #else assert("long doubles are not supported" == NULL); #endif /*FALLTHROUGH*/ case 'e': case 'E': case 'f': case 'g': case 'G': if (!dot) precision = 6; /* * IEEE floating point. * MIN 2.2250738585072014E-308 * MAX 1.7976931348623157E+308 * VAX floating point has a smaller range than IEEE. * * precisions > 324 don't make much sense. * if we cap the precision at 512 we will not * overflow buf. */ if (precision > 512) precision = 512; sprintf(fmt, "%%%s%s.%lu%s%c", alt ? "#" : "", plus ? "+" : space ? " " : "", precision, l ? "L" : "", *format); switch (*format) { case 'e': case 'E': case 'f': case 'g': case 'G': #ifdef HAVE_LONG_DOUBLE if (l) { ldbl = va_arg(ap, long double); sprintf(buf, fmt, ldbl); } else #endif { dbl = va_arg(ap, double); sprintf(buf, fmt, dbl); } length = strlen(buf); if (width > 0) { pad = width - length; if (pad < 0) pad = 0; } count += length + pad; if (!left) while (pad > 0) { emit(' ', arg); pad--; } cp = buf; while (*cp != ' ') emit(*cp++, arg); while (pad > 0) { emit(' ', arg); pad--; } break; default: continue; } break; default: continue; } format++; } return (count); } bind9-9.10.3.dfsg.P4/lib/isc/counter.c0000644000470500017500000000637212664710322016550 0ustar lamontlamont/* * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #include #include #include #define COUNTER_MAGIC ISC_MAGIC('C', 'n', 't', 'r') #define VALID_COUNTER(r) ISC_MAGIC_VALID(r, COUNTER_MAGIC) struct isc_counter { unsigned int magic; isc_mem_t *mctx; isc_mutex_t lock; unsigned int references; unsigned int limit; unsigned int used; }; isc_result_t isc_counter_create(isc_mem_t *mctx, int limit, isc_counter_t **counterp) { isc_result_t result; isc_counter_t *counter; REQUIRE(counterp != NULL && *counterp == NULL); counter = isc_mem_get(mctx, sizeof(*counter)); if (counter == NULL) return (ISC_R_NOMEMORY); result = isc_mutex_init(&counter->lock); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, counter, sizeof(*counter)); return (result); } counter->mctx = NULL; isc_mem_attach(mctx, &counter->mctx); counter->references = 1; counter->limit = limit; counter->used = 0; counter->magic = COUNTER_MAGIC; *counterp = counter; return (ISC_R_SUCCESS); } isc_result_t isc_counter_increment(isc_counter_t *counter) { isc_result_t result = ISC_R_SUCCESS; LOCK(&counter->lock); counter->used++; if (counter->limit != 0 && counter->used >= counter->limit) result = ISC_R_QUOTA; UNLOCK(&counter->lock); return (result); } unsigned int isc_counter_used(isc_counter_t *counter) { REQUIRE(VALID_COUNTER(counter)); return (counter->used); } void isc_counter_setlimit(isc_counter_t *counter, int limit) { REQUIRE(VALID_COUNTER(counter)); LOCK(&counter->lock); counter->limit = limit; UNLOCK(&counter->lock); } void isc_counter_attach(isc_counter_t *source, isc_counter_t **targetp) { REQUIRE(VALID_COUNTER(source)); REQUIRE(targetp != NULL && *targetp == NULL); LOCK(&source->lock); source->references++; INSIST(source->references > 0); UNLOCK(&source->lock); *targetp = source; } static void destroy(isc_counter_t *counter) { counter->magic = 0; isc_mutex_destroy(&counter->lock); isc_mem_putanddetach(&counter->mctx, counter, sizeof(*counter)); } void isc_counter_detach(isc_counter_t **counterp) { isc_counter_t *counter; isc_boolean_t want_destroy = ISC_FALSE; REQUIRE(counterp != NULL && *counterp != NULL); counter = *counterp; REQUIRE(VALID_COUNTER(counter)); *counterp = NULL; LOCK(&counter->lock); INSIST(counter->references > 0); counter->references--; if (counter->references == 0) want_destroy = ISC_TRUE; UNLOCK(&counter->lock); if (want_destroy) destroy(counter); } bind9-9.10.3.dfsg.P4/lib/isc/mem.c0000644000470500017500000021201312664710322015636 0ustar lamontlamont/* * Copyright (C) 2004-2010, 2012-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1997-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MCTXLOCK(m, l) if (((m)->flags & ISC_MEMFLAG_NOLOCK) == 0) LOCK(l) #define MCTXUNLOCK(m, l) if (((m)->flags & ISC_MEMFLAG_NOLOCK) == 0) UNLOCK(l) #ifndef ISC_MEM_DEBUGGING #define ISC_MEM_DEBUGGING 0 #endif LIBISC_EXTERNAL_DATA unsigned int isc_mem_debugging = ISC_MEM_DEBUGGING; LIBISC_EXTERNAL_DATA unsigned int isc_mem_defaultflags = ISC_MEMFLAG_DEFAULT; /* * Constants. */ #define DEF_MAX_SIZE 1100 #define DEF_MEM_TARGET 4096 #define ALIGNMENT_SIZE 8U /*%< must be a power of 2 */ #define NUM_BASIC_BLOCKS 64 /*%< must be > 1 */ #define TABLE_INCREMENT 1024 #define DEBUGLIST_COUNT 1024 /* * Types. */ typedef struct isc__mem isc__mem_t; typedef struct isc__mempool isc__mempool_t; #if ISC_MEM_TRACKLINES typedef struct debuglink debuglink_t; struct debuglink { ISC_LINK(debuglink_t) link; const void *ptr[DEBUGLIST_COUNT]; size_t size[DEBUGLIST_COUNT]; const char *file[DEBUGLIST_COUNT]; unsigned int line[DEBUGLIST_COUNT]; unsigned int count; }; #define FLARG_PASS , file, line #define FLARG , const char *file, unsigned int line #else #define FLARG_PASS #define FLARG #endif typedef struct element element; struct element { element * next; }; typedef struct { /*! * This structure must be ALIGNMENT_SIZE bytes. */ union { size_t size; isc__mem_t *ctx; char bytes[ALIGNMENT_SIZE]; } u; } size_info; struct stats { unsigned long gets; unsigned long totalgets; unsigned long blocks; unsigned long freefrags; }; #define MEM_MAGIC ISC_MAGIC('M', 'e', 'm', 'C') #define VALID_CONTEXT(c) ISC_MAGIC_VALID(c, MEM_MAGIC) #if ISC_MEM_TRACKLINES typedef ISC_LIST(debuglink_t) debuglist_t; #endif /* List of all active memory contexts. */ static ISC_LIST(isc__mem_t) contexts; static isc_once_t once = ISC_ONCE_INIT; static isc_mutex_t contextslock; static isc_mutex_t createlock; /*% * Total size of lost memory due to a bug of external library. * Locked by the global lock. */ static isc_uint64_t totallost; struct isc__mem { isc_mem_t common; isc_ondestroy_t ondestroy; unsigned int flags; isc_mutex_t lock; isc_memalloc_t memalloc; isc_memfree_t memfree; void * arg; size_t max_size; isc_boolean_t checkfree; struct stats * stats; unsigned int references; char name[16]; void * tag; size_t quota; size_t total; size_t inuse; size_t maxinuse; size_t hi_water; size_t lo_water; isc_boolean_t hi_called; isc_boolean_t is_overmem; isc_mem_water_t water; void * water_arg; ISC_LIST(isc__mempool_t) pools; unsigned int poolcnt; /* ISC_MEMFLAG_INTERNAL */ size_t mem_target; element ** freelists; element * basic_blocks; unsigned char ** basic_table; unsigned int basic_table_count; unsigned int basic_table_size; unsigned char * lowest; unsigned char * highest; #if ISC_MEM_TRACKLINES debuglist_t * debuglist; unsigned int debuglistcnt; #endif unsigned int memalloc_failures; ISC_LINK(isc__mem_t) link; }; #define MEMPOOL_MAGIC ISC_MAGIC('M', 'E', 'M', 'p') #define VALID_MEMPOOL(c) ISC_MAGIC_VALID(c, MEMPOOL_MAGIC) struct isc__mempool { /* always unlocked */ isc_mempool_t common; /*%< common header of mempool's */ isc_mutex_t *lock; /*%< optional lock */ isc__mem_t *mctx; /*%< our memory context */ /*%< locked via the memory context's lock */ ISC_LINK(isc__mempool_t) link; /*%< next pool in this mem context */ /*%< optionally locked from here down */ element *items; /*%< low water item list */ size_t size; /*%< size of each item on this pool */ unsigned int maxalloc; /*%< max number of items allowed */ unsigned int allocated; /*%< # of items currently given out */ unsigned int freecount; /*%< # of items on reserved list */ unsigned int freemax; /*%< # of items allowed on free list */ unsigned int fillcount; /*%< # of items to fetch on each fill */ /*%< Stats only. */ unsigned int gets; /*%< # of requests to this pool */ /*%< Debugging only. */ #if ISC_MEMPOOL_NAMES char name[16]; /*%< printed name in stats reports */ #endif }; /* * Private Inline-able. */ #if ! ISC_MEM_TRACKLINES #define ADD_TRACE(a, b, c, d, e) #define DELETE_TRACE(a, b, c, d, e) #define ISC_MEMFUNC_SCOPE #else #define ADD_TRACE(a, b, c, d, e) \ do { \ if ((isc_mem_debugging & (ISC_MEM_DEBUGTRACE | \ ISC_MEM_DEBUGRECORD)) != 0 && \ b != NULL) \ add_trace_entry(a, b, c, d, e); \ } while (0) #define DELETE_TRACE(a, b, c, d, e) delete_trace_entry(a, b, c, d, e) static void print_active(isc__mem_t *ctx, FILE *out); #endif /* ISC_MEM_TRACKLINES */ /*% * The following are intended for internal use (indicated by "isc__" * prefix) but are not declared as static, allowing direct access * from unit tests, etc. */ isc_result_t isc__mem_create2(size_t init_max_size, size_t target_size, isc_mem_t **ctxp, unsigned int flags); void isc__mem_attach(isc_mem_t *source, isc_mem_t **targetp); void isc__mem_detach(isc_mem_t **ctxp); void isc___mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG); void isc__mem_destroy(isc_mem_t **ctxp); isc_result_t isc__mem_ondestroy(isc_mem_t *ctx, isc_task_t *task, isc_event_t **event); void * isc___mem_get(isc_mem_t *ctx, size_t size FLARG); void isc___mem_put(isc_mem_t *ctx, void *ptr, size_t size FLARG); void isc__mem_stats(isc_mem_t *ctx, FILE *out); void * isc___mem_allocate(isc_mem_t *ctx, size_t size FLARG); void * isc___mem_reallocate(isc_mem_t *ctx, void *ptr, size_t size FLARG); void isc___mem_free(isc_mem_t *ctx, void *ptr FLARG); char * isc___mem_strdup(isc_mem_t *mctx, const char *s FLARG); void isc__mem_setdestroycheck(isc_mem_t *ctx, isc_boolean_t flag); void isc__mem_setquota(isc_mem_t *ctx, size_t quota); size_t isc__mem_getquota(isc_mem_t *ctx); size_t isc__mem_inuse(isc_mem_t *ctx); size_t isc__mem_maxinuse(isc_mem_t *ctx); size_t isc__mem_total(isc_mem_t *ctx); isc_boolean_t isc__mem_isovermem(isc_mem_t *ctx); void isc__mem_setwater(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg, size_t hiwater, size_t lowater); void isc__mem_waterack(isc_mem_t *ctx0, int flag); void isc__mem_setname(isc_mem_t *ctx, const char *name, void *tag); const char * isc__mem_getname(isc_mem_t *ctx); void * isc__mem_gettag(isc_mem_t *ctx); isc_result_t isc__mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp); void isc__mempool_setname(isc_mempool_t *mpctx, const char *name); void isc__mempool_destroy(isc_mempool_t **mpctxp); void isc__mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock); void * isc___mempool_get(isc_mempool_t *mpctx FLARG); void isc___mempool_put(isc_mempool_t *mpctx, void *mem FLARG); void isc__mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit); unsigned int isc__mempool_getfreemax(isc_mempool_t *mpctx); unsigned int isc__mempool_getfreecount(isc_mempool_t *mpctx); void isc__mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit); unsigned int isc__mempool_getmaxalloc(isc_mempool_t *mpctx); unsigned int isc__mempool_getallocated(isc_mempool_t *mpctx); void isc__mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit); unsigned int isc__mempool_getfillcount(isc_mempool_t *mpctx); void isc__mem_printactive(isc_mem_t *ctx0, FILE *file); void isc__mem_printallactive(FILE *file); unsigned int isc__mem_references(isc_mem_t *ctx0); static struct isc__memmethods { isc_memmethods_t methods; /*% * The following are defined just for avoiding unused static functions. */ void *createx, *create, *create2, *ondestroy, *stats, *setquota, *getquota, *setname, *getname, *gettag; } memmethods = { { isc__mem_attach, isc__mem_detach, isc__mem_destroy, isc___mem_get, isc___mem_put, isc___mem_putanddetach, isc___mem_allocate, isc___mem_reallocate, isc___mem_strdup, isc___mem_free, isc__mem_setdestroycheck, isc__mem_setwater, isc__mem_waterack, isc__mem_inuse, isc__mem_maxinuse, isc__mem_total, isc__mem_isovermem, isc__mempool_create }, (void *)isc_mem_createx, (void *)isc_mem_create, (void *)isc_mem_create2, (void *)isc_mem_ondestroy, (void *)isc_mem_stats, (void *)isc_mem_setquota, (void *)isc_mem_getquota, (void *)isc_mem_setname, (void *)isc_mem_getname, (void *)isc_mem_gettag }; static struct isc__mempoolmethods { isc_mempoolmethods_t methods; /*% * The following are defined just for avoiding unused static functions. */ void *getfreemax, *getfreecount, *getmaxalloc, *getfillcount; } mempoolmethods = { { isc__mempool_destroy, isc___mempool_get, isc___mempool_put, isc__mempool_getallocated, isc__mempool_setmaxalloc, isc__mempool_setfreemax, isc__mempool_setname, isc__mempool_associatelock, isc__mempool_setfillcount }, (void *)isc_mempool_getfreemax, (void *)isc_mempool_getfreecount, (void *)isc_mempool_getmaxalloc, (void *)isc_mempool_getfillcount }; #if ISC_MEM_TRACKLINES /*! * mctx must be locked. */ static inline void add_trace_entry(isc__mem_t *mctx, const void *ptr, size_t size FLARG) { debuglink_t *dl; unsigned int i; size_t mysize = size; if ((isc_mem_debugging & ISC_MEM_DEBUGTRACE) != 0) fprintf(stderr, isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM, ISC_MSG_ADDTRACE, "add %p size %u " "file %s line %u mctx %p\n"), ptr, size, file, line, mctx); if (mctx->debuglist == NULL) return; if (mysize > mctx->max_size) mysize = mctx->max_size; dl = ISC_LIST_HEAD(mctx->debuglist[mysize]); while (dl != NULL) { if (dl->count == DEBUGLIST_COUNT) goto next; for (i = 0; i < DEBUGLIST_COUNT; i++) { if (dl->ptr[i] == NULL) { dl->ptr[i] = ptr; dl->size[i] = size; dl->file[i] = file; dl->line[i] = line; dl->count++; return; } } next: dl = ISC_LIST_NEXT(dl, link); } dl = malloc(sizeof(debuglink_t)); INSIST(dl != NULL); ISC_LINK_INIT(dl, link); for (i = 1; i < DEBUGLIST_COUNT; i++) { dl->ptr[i] = NULL; dl->size[i] = 0; dl->file[i] = NULL; dl->line[i] = 0; } dl->ptr[0] = ptr; dl->size[0] = size; dl->file[0] = file; dl->line[0] = line; dl->count = 1; ISC_LIST_PREPEND(mctx->debuglist[mysize], dl, link); mctx->debuglistcnt++; } static inline void delete_trace_entry(isc__mem_t *mctx, const void *ptr, size_t size, const char *file, unsigned int line) { debuglink_t *dl; unsigned int i; if ((isc_mem_debugging & ISC_MEM_DEBUGTRACE) != 0) fprintf(stderr, isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM, ISC_MSG_DELTRACE, "del %p size %u " "file %s line %u mctx %p\n"), ptr, size, file, line, mctx); if (mctx->debuglist == NULL) return; if (size > mctx->max_size) size = mctx->max_size; dl = ISC_LIST_HEAD(mctx->debuglist[size]); while (dl != NULL) { for (i = 0; i < DEBUGLIST_COUNT; i++) { if (dl->ptr[i] == ptr) { dl->ptr[i] = NULL; dl->size[i] = 0; dl->file[i] = NULL; dl->line[i] = 0; INSIST(dl->count > 0); dl->count--; if (dl->count == 0) { ISC_LIST_UNLINK(mctx->debuglist[size], dl, link); free(dl); } return; } } dl = ISC_LIST_NEXT(dl, link); } /* * If we get here, we didn't find the item on the list. We're * screwed. */ INSIST(dl != NULL); } #endif /* ISC_MEM_TRACKLINES */ static inline size_t rmsize(size_t size) { /* * round down to ALIGNMENT_SIZE */ return (size & (~(ALIGNMENT_SIZE - 1))); } static inline size_t quantize(size_t size) { /*! * Round up the result in order to get a size big * enough to satisfy the request and be aligned on ALIGNMENT_SIZE * byte boundaries. */ if (size == 0U) return (ALIGNMENT_SIZE); return ((size + ALIGNMENT_SIZE - 1) & (~(ALIGNMENT_SIZE - 1))); } static inline isc_boolean_t more_basic_blocks(isc__mem_t *ctx) { void *new; unsigned char *curr, *next; unsigned char *first, *last; unsigned char **table; unsigned int table_size; size_t increment; int i; /* Require: we hold the context lock. */ /* * Did we hit the quota for this context? */ increment = NUM_BASIC_BLOCKS * ctx->mem_target; if (ctx->quota != 0U && ctx->total + increment > ctx->quota) return (ISC_FALSE); INSIST(ctx->basic_table_count <= ctx->basic_table_size); if (ctx->basic_table_count == ctx->basic_table_size) { table_size = ctx->basic_table_size + TABLE_INCREMENT; table = (ctx->memalloc)(ctx->arg, table_size * sizeof(unsigned char *)); if (table == NULL) { ctx->memalloc_failures++; return (ISC_FALSE); } if (ctx->basic_table_size != 0) { memmove(table, ctx->basic_table, ctx->basic_table_size * sizeof(unsigned char *)); (ctx->memfree)(ctx->arg, ctx->basic_table); } ctx->basic_table = table; ctx->basic_table_size = table_size; } new = (ctx->memalloc)(ctx->arg, NUM_BASIC_BLOCKS * ctx->mem_target); if (new == NULL) { ctx->memalloc_failures++; return (ISC_FALSE); } ctx->total += increment; ctx->basic_table[ctx->basic_table_count] = new; ctx->basic_table_count++; curr = new; next = curr + ctx->mem_target; for (i = 0; i < (NUM_BASIC_BLOCKS - 1); i++) { ((element *)curr)->next = (element *)next; curr = next; next += ctx->mem_target; } /* * curr is now pointing at the last block in the * array. */ ((element *)curr)->next = NULL; first = new; last = first + NUM_BASIC_BLOCKS * ctx->mem_target - 1; if (first < ctx->lowest || ctx->lowest == NULL) ctx->lowest = first; if (last > ctx->highest) ctx->highest = last; ctx->basic_blocks = new; return (ISC_TRUE); } static inline isc_boolean_t more_frags(isc__mem_t *ctx, size_t new_size) { int i, frags; size_t total_size; void *new; unsigned char *curr, *next; /*! * Try to get more fragments by chopping up a basic block. */ if (ctx->basic_blocks == NULL) { if (!more_basic_blocks(ctx)) { /* * We can't get more memory from the OS, or we've * hit the quota for this context. */ /* * XXXRTH "At quota" notification here. */ return (ISC_FALSE); } } total_size = ctx->mem_target; new = ctx->basic_blocks; ctx->basic_blocks = ctx->basic_blocks->next; frags = (int)(total_size / new_size); ctx->stats[new_size].blocks++; ctx->stats[new_size].freefrags += frags; /* * Set up a linked-list of blocks of size * "new_size". */ curr = new; next = curr + new_size; total_size -= new_size; for (i = 0; i < (frags - 1); i++) { ((element *)curr)->next = (element *)next; curr = next; next += new_size; total_size -= new_size; } /* * Add the remaining fragment of the basic block to a free list. */ total_size = rmsize(total_size); if (total_size > 0U) { ((element *)next)->next = ctx->freelists[total_size]; ctx->freelists[total_size] = (element *)next; ctx->stats[total_size].freefrags++; } /* * curr is now pointing at the last block in the * array. */ ((element *)curr)->next = NULL; ctx->freelists[new_size] = new; return (ISC_TRUE); } static inline void * mem_getunlocked(isc__mem_t *ctx, size_t size) { size_t new_size = quantize(size); void *ret; if (new_size >= ctx->max_size) { /* * memget() was called on something beyond our upper limit. */ if (ctx->quota != 0U && ctx->total + size > ctx->quota) { ret = NULL; goto done; } ret = (ctx->memalloc)(ctx->arg, size); if (ret == NULL) { ctx->memalloc_failures++; goto done; } ctx->total += size; ctx->inuse += size; ctx->stats[ctx->max_size].gets++; ctx->stats[ctx->max_size].totalgets++; /* * If we don't set new_size to size, then the * ISC_MEM_FILL code might write over bytes we * don't own. */ new_size = size; goto done; } /* * If there are no blocks in the free list for this size, get a chunk * of memory and then break it up into "new_size"-sized blocks, adding * them to the free list. */ if (ctx->freelists[new_size] == NULL && !more_frags(ctx, new_size)) return (NULL); /* * The free list uses the "rounded-up" size "new_size". */ ret = ctx->freelists[new_size]; ctx->freelists[new_size] = ctx->freelists[new_size]->next; /* * The stats[] uses the _actual_ "size" requested by the * caller, with the caveat (in the code above) that "size" >= the * max. size (max_size) ends up getting recorded as a call to * max_size. */ ctx->stats[size].gets++; ctx->stats[size].totalgets++; ctx->stats[new_size].freefrags--; ctx->inuse += new_size; done: #if ISC_MEM_FILL if (ret != NULL) memset(ret, 0xbe, new_size); /* Mnemonic for "beef". */ #endif return (ret); } #if ISC_MEM_FILL && ISC_MEM_CHECKOVERRUN static inline void check_overrun(void *mem, size_t size, size_t new_size) { unsigned char *cp; cp = (unsigned char *)mem; cp += size; while (size < new_size) { INSIST(*cp == 0xbe); cp++; size++; } } #endif /* coverity[+free : arg-1] */ static inline void mem_putunlocked(isc__mem_t *ctx, void *mem, size_t size) { size_t new_size = quantize(size); if (new_size >= ctx->max_size) { /* * memput() called on something beyond our upper limit. */ #if ISC_MEM_FILL memset(mem, 0xde, size); /* Mnemonic for "dead". */ #endif (ctx->memfree)(ctx->arg, mem); INSIST(ctx->stats[ctx->max_size].gets != 0U); ctx->stats[ctx->max_size].gets--; INSIST(size <= ctx->inuse); ctx->inuse -= size; return; } #if ISC_MEM_FILL #if ISC_MEM_CHECKOVERRUN check_overrun(mem, size, new_size); #endif memset(mem, 0xde, new_size); /* Mnemonic for "dead". */ #endif /* * The free list uses the "rounded-up" size "new_size". */ ((element *)mem)->next = ctx->freelists[new_size]; ctx->freelists[new_size] = (element *)mem; /* * The stats[] uses the _actual_ "size" requested by the * caller, with the caveat (in the code above) that "size" >= the * max. size (max_size) ends up getting recorded as a call to * max_size. */ INSIST(ctx->stats[size].gets != 0U); ctx->stats[size].gets--; ctx->stats[new_size].freefrags++; ctx->inuse -= new_size; } /*! * Perform a malloc, doing memory filling and overrun detection as necessary. */ static inline void * mem_get(isc__mem_t *ctx, size_t size) { char *ret; #if ISC_MEM_CHECKOVERRUN size += 1; #endif ret = (ctx->memalloc)(ctx->arg, size); if (ret == NULL) ctx->memalloc_failures++; #if ISC_MEM_FILL if (ret != NULL) memset(ret, 0xbe, size); /* Mnemonic for "beef". */ #else # if ISC_MEM_CHECKOVERRUN if (ret != NULL) ret[size-1] = 0xbe; # endif #endif return (ret); } /*! * Perform a free, doing memory filling and overrun detection as necessary. */ /* coverity[+free : arg-1] */ static inline void mem_put(isc__mem_t *ctx, void *mem, size_t size) { #if ISC_MEM_CHECKOVERRUN INSIST(((unsigned char *)mem)[size] == 0xbe); #endif #if ISC_MEM_FILL memset(mem, 0xde, size); /* Mnemonic for "dead". */ #else UNUSED(size); #endif (ctx->memfree)(ctx->arg, mem); } /*! * Update internal counters after a memory get. */ static inline void mem_getstats(isc__mem_t *ctx, size_t size) { ctx->total += size; ctx->inuse += size; if (size > ctx->max_size) { ctx->stats[ctx->max_size].gets++; ctx->stats[ctx->max_size].totalgets++; } else { ctx->stats[size].gets++; ctx->stats[size].totalgets++; } } /*! * Update internal counters after a memory put. */ static inline void mem_putstats(isc__mem_t *ctx, void *ptr, size_t size) { UNUSED(ptr); INSIST(ctx->inuse >= size); ctx->inuse -= size; if (size > ctx->max_size) { INSIST(ctx->stats[ctx->max_size].gets > 0U); ctx->stats[ctx->max_size].gets--; } else { INSIST(ctx->stats[size].gets > 0U); ctx->stats[size].gets--; } } /* * Private. */ static void * default_memalloc(void *arg, size_t size) { UNUSED(arg); if (size == 0U) size = 1; return (malloc(size)); } static void default_memfree(void *arg, void *ptr) { UNUSED(arg); free(ptr); } static void initialize_action(void) { RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_mutex_init(&contextslock) == ISC_R_SUCCESS); ISC_LIST_INIT(contexts); totallost = 0; } /* * Public. */ isc_result_t isc_mem_createx(size_t init_max_size, size_t target_size, isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg, isc_mem_t **ctxp) { return (isc_mem_createx2(init_max_size, target_size, memalloc, memfree, arg, ctxp, isc_mem_defaultflags)); } isc_result_t isc_mem_createx2(size_t init_max_size, size_t target_size, isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg, isc_mem_t **ctxp, unsigned int flags) { isc__mem_t *ctx; isc_result_t result; REQUIRE(ctxp != NULL && *ctxp == NULL); REQUIRE(memalloc != NULL); REQUIRE(memfree != NULL); INSIST((ALIGNMENT_SIZE & (ALIGNMENT_SIZE - 1)) == 0); RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); ctx = (memalloc)(arg, sizeof(*ctx)); if (ctx == NULL) return (ISC_R_NOMEMORY); if ((flags & ISC_MEMFLAG_NOLOCK) == 0) { result = isc_mutex_init(&ctx->lock); if (result != ISC_R_SUCCESS) { (memfree)(arg, ctx); return (result); } } if (init_max_size == 0U) ctx->max_size = DEF_MAX_SIZE; else ctx->max_size = init_max_size; ctx->flags = flags; ctx->references = 1; memset(ctx->name, 0, sizeof(ctx->name)); ctx->tag = NULL; ctx->quota = 0; ctx->total = 0; ctx->inuse = 0; ctx->maxinuse = 0; ctx->hi_water = 0; ctx->lo_water = 0; ctx->hi_called = ISC_FALSE; ctx->is_overmem = ISC_FALSE; ctx->water = NULL; ctx->water_arg = NULL; ctx->common.impmagic = MEM_MAGIC; ctx->common.magic = ISCAPI_MCTX_MAGIC; ctx->common.methods = (isc_memmethods_t *)&memmethods; isc_ondestroy_init(&ctx->ondestroy); ctx->memalloc = memalloc; ctx->memfree = memfree; ctx->arg = arg; ctx->stats = NULL; ctx->checkfree = ISC_TRUE; #if ISC_MEM_TRACKLINES ctx->debuglist = NULL; ctx->debuglistcnt = 0; #endif ISC_LIST_INIT(ctx->pools); ctx->poolcnt = 0; ctx->freelists = NULL; ctx->basic_blocks = NULL; ctx->basic_table = NULL; ctx->basic_table_count = 0; ctx->basic_table_size = 0; ctx->lowest = NULL; ctx->highest = NULL; ctx->stats = (memalloc)(arg, (ctx->max_size+1) * sizeof(struct stats)); if (ctx->stats == NULL) { result = ISC_R_NOMEMORY; goto error; } memset(ctx->stats, 0, (ctx->max_size + 1) * sizeof(struct stats)); if ((flags & ISC_MEMFLAG_INTERNAL) != 0) { if (target_size == 0U) ctx->mem_target = DEF_MEM_TARGET; else ctx->mem_target = target_size; ctx->freelists = (memalloc)(arg, ctx->max_size * sizeof(element *)); if (ctx->freelists == NULL) { result = ISC_R_NOMEMORY; goto error; } memset(ctx->freelists, 0, ctx->max_size * sizeof(element *)); } #if ISC_MEM_TRACKLINES if ((isc_mem_debugging & ISC_MEM_DEBUGRECORD) != 0) { unsigned int i; ctx->debuglist = (memalloc)(arg, (ctx->max_size+1) * sizeof(debuglist_t)); if (ctx->debuglist == NULL) { result = ISC_R_NOMEMORY; goto error; } for (i = 0; i <= ctx->max_size; i++) ISC_LIST_INIT(ctx->debuglist[i]); } #endif ctx->memalloc_failures = 0; LOCK(&contextslock); ISC_LIST_INITANDAPPEND(contexts, ctx, link); UNLOCK(&contextslock); *ctxp = (isc_mem_t *)ctx; return (ISC_R_SUCCESS); error: if (ctx != NULL) { if (ctx->stats != NULL) (memfree)(arg, ctx->stats); if (ctx->freelists != NULL) (memfree)(arg, ctx->freelists); #if ISC_MEM_TRACKLINES if (ctx->debuglist != NULL) (ctx->memfree)(ctx->arg, ctx->debuglist); #endif /* ISC_MEM_TRACKLINES */ if ((ctx->flags & ISC_MEMFLAG_NOLOCK) == 0) DESTROYLOCK(&ctx->lock); (memfree)(arg, ctx); } return (result); } static void destroy(isc__mem_t *ctx) { unsigned int i; isc_ondestroy_t ondest; LOCK(&contextslock); ISC_LIST_UNLINK(contexts, ctx, link); totallost += ctx->inuse; UNLOCK(&contextslock); ctx->common.impmagic = 0; ctx->common.magic = 0; INSIST(ISC_LIST_EMPTY(ctx->pools)); #if ISC_MEM_TRACKLINES if (ctx->debuglist != NULL) { if (ctx->checkfree) { for (i = 0; i <= ctx->max_size; i++) { if (!ISC_LIST_EMPTY(ctx->debuglist[i])) print_active(ctx, stderr); INSIST(ISC_LIST_EMPTY(ctx->debuglist[i])); } } else { debuglink_t *dl; for (i = 0; i <= ctx->max_size; i++) for (dl = ISC_LIST_HEAD(ctx->debuglist[i]); dl != NULL; dl = ISC_LIST_HEAD(ctx->debuglist[i])) { ISC_LIST_UNLINK(ctx->debuglist[i], dl, link); free(dl); } } (ctx->memfree)(ctx->arg, ctx->debuglist); } #endif INSIST(ctx->references == 0); if (ctx->checkfree) { for (i = 0; i <= ctx->max_size; i++) { if (ctx->stats[i].gets != 0U) { fprintf(stderr, "Failing assertion due to probable " "leaked memory in context %p (\"%s\") " "(stats[%u].gets == %lu).\n", ctx, ctx->name, i, ctx->stats[i].gets); #if ISC_MEM_TRACKLINES print_active(ctx, stderr); #endif INSIST(ctx->stats[i].gets == 0U); } } } (ctx->memfree)(ctx->arg, ctx->stats); if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { for (i = 0; i < ctx->basic_table_count; i++) (ctx->memfree)(ctx->arg, ctx->basic_table[i]); (ctx->memfree)(ctx->arg, ctx->freelists); if (ctx->basic_table != NULL) (ctx->memfree)(ctx->arg, ctx->basic_table); } ondest = ctx->ondestroy; if ((ctx->flags & ISC_MEMFLAG_NOLOCK) == 0) DESTROYLOCK(&ctx->lock); (ctx->memfree)(ctx->arg, ctx); isc_ondestroy_notify(&ondest, ctx); } void isc__mem_attach(isc_mem_t *source0, isc_mem_t **targetp) { isc__mem_t *source = (isc__mem_t *)source0; REQUIRE(VALID_CONTEXT(source)); REQUIRE(targetp != NULL && *targetp == NULL); MCTXLOCK(source, &source->lock); source->references++; MCTXUNLOCK(source, &source->lock); *targetp = (isc_mem_t *)source; } void isc__mem_detach(isc_mem_t **ctxp) { isc__mem_t *ctx; isc_boolean_t want_destroy = ISC_FALSE; REQUIRE(ctxp != NULL); ctx = (isc__mem_t *)*ctxp; REQUIRE(VALID_CONTEXT(ctx)); MCTXLOCK(ctx, &ctx->lock); INSIST(ctx->references > 0); ctx->references--; if (ctx->references == 0) want_destroy = ISC_TRUE; MCTXUNLOCK(ctx, &ctx->lock); if (want_destroy) destroy(ctx); *ctxp = NULL; } /* * isc_mem_putanddetach() is the equivalent of: * * mctx = NULL; * isc_mem_attach(ptr->mctx, &mctx); * isc_mem_detach(&ptr->mctx); * isc_mem_put(mctx, ptr, sizeof(*ptr); * isc_mem_detach(&mctx); */ void isc___mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) { isc__mem_t *ctx; isc_boolean_t want_destroy = ISC_FALSE; size_info *si; size_t oldsize; REQUIRE(ctxp != NULL); ctx = (isc__mem_t *)*ctxp; REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(ptr != NULL); /* * Must be before mem_putunlocked() as ctxp is usually within * [ptr..ptr+size). */ *ctxp = NULL; if ((isc_mem_debugging & (ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0) { if ((isc_mem_debugging & ISC_MEM_DEBUGSIZE) != 0) { si = &(((size_info *)ptr)[-1]); oldsize = si->u.size - ALIGNMENT_SIZE; if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) oldsize -= ALIGNMENT_SIZE; INSIST(oldsize == size); } isc__mem_free((isc_mem_t *)ctx, ptr FLARG_PASS); MCTXLOCK(ctx, &ctx->lock); ctx->references--; if (ctx->references == 0) want_destroy = ISC_TRUE; MCTXUNLOCK(ctx, &ctx->lock); if (want_destroy) destroy(ctx); return; } MCTXLOCK(ctx, &ctx->lock); DELETE_TRACE(ctx, ptr, size, file, line); if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { mem_putunlocked(ctx, ptr, size); } else { mem_putstats(ctx, ptr, size); mem_put(ctx, ptr, size); } INSIST(ctx->references > 0); ctx->references--; if (ctx->references == 0) want_destroy = ISC_TRUE; MCTXUNLOCK(ctx, &ctx->lock); if (want_destroy) destroy(ctx); } void isc__mem_destroy(isc_mem_t **ctxp) { isc__mem_t *ctx; /* * This routine provides legacy support for callers who use mctxs * without attaching/detaching. */ REQUIRE(ctxp != NULL); ctx = (isc__mem_t *)*ctxp; REQUIRE(VALID_CONTEXT(ctx)); MCTXLOCK(ctx, &ctx->lock); #if ISC_MEM_TRACKLINES if (ctx->references != 1) print_active(ctx, stderr); #endif REQUIRE(ctx->references == 1); ctx->references--; MCTXUNLOCK(ctx, &ctx->lock); destroy(ctx); *ctxp = NULL; } isc_result_t isc_mem_ondestroy(isc_mem_t *ctx0, isc_task_t *task, isc_event_t **event) { isc__mem_t *ctx = (isc__mem_t *)ctx0; isc_result_t res; MCTXLOCK(ctx, &ctx->lock); res = isc_ondestroy_register(&ctx->ondestroy, task, event); MCTXUNLOCK(ctx, &ctx->lock); return (res); } void * isc___mem_get(isc_mem_t *ctx0, size_t size FLARG) { isc__mem_t *ctx = (isc__mem_t *)ctx0; void *ptr; isc_boolean_t call_water = ISC_FALSE; REQUIRE(VALID_CONTEXT(ctx)); if ((isc_mem_debugging & (ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0) return (isc__mem_allocate(ctx0, size FLARG_PASS)); if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { MCTXLOCK(ctx, &ctx->lock); ptr = mem_getunlocked(ctx, size); } else { ptr = mem_get(ctx, size); MCTXLOCK(ctx, &ctx->lock); if (ptr != NULL) mem_getstats(ctx, size); } ADD_TRACE(ctx, ptr, size, file, line); if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water) { ctx->is_overmem = ISC_TRUE; if (!ctx->hi_called) call_water = ISC_TRUE; } if (ctx->inuse > ctx->maxinuse) { ctx->maxinuse = ctx->inuse; if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water && (isc_mem_debugging & ISC_MEM_DEBUGUSAGE) != 0) fprintf(stderr, "maxinuse = %lu\n", (unsigned long)ctx->inuse); } MCTXUNLOCK(ctx, &ctx->lock); if (call_water && (ctx->water != NULL)) (ctx->water)(ctx->water_arg, ISC_MEM_HIWATER); return (ptr); } void isc___mem_put(isc_mem_t *ctx0, void *ptr, size_t size FLARG) { isc__mem_t *ctx = (isc__mem_t *)ctx0; isc_boolean_t call_water = ISC_FALSE; size_info *si; size_t oldsize; REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(ptr != NULL); if ((isc_mem_debugging & (ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0) { if ((isc_mem_debugging & ISC_MEM_DEBUGSIZE) != 0) { si = &(((size_info *)ptr)[-1]); oldsize = si->u.size - ALIGNMENT_SIZE; if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) oldsize -= ALIGNMENT_SIZE; INSIST(oldsize == size); } isc__mem_free((isc_mem_t *)ctx, ptr FLARG_PASS); return; } MCTXLOCK(ctx, &ctx->lock); DELETE_TRACE(ctx, ptr, size, file, line); if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { mem_putunlocked(ctx, ptr, size); } else { mem_putstats(ctx, ptr, size); mem_put(ctx, ptr, size); } /* * The check against ctx->lo_water == 0 is for the condition * when the context was pushed over hi_water but then had * isc_mem_setwater() called with 0 for hi_water and lo_water. */ if ((ctx->inuse < ctx->lo_water) || (ctx->lo_water == 0U)) { ctx->is_overmem = ISC_FALSE; if (ctx->hi_called) call_water = ISC_TRUE; } MCTXUNLOCK(ctx, &ctx->lock); if (call_water && (ctx->water != NULL)) (ctx->water)(ctx->water_arg, ISC_MEM_LOWATER); } void isc__mem_waterack(isc_mem_t *ctx0, int flag) { isc__mem_t *ctx = (isc__mem_t *)ctx0; REQUIRE(VALID_CONTEXT(ctx)); MCTXLOCK(ctx, &ctx->lock); if (flag == ISC_MEM_LOWATER) ctx->hi_called = ISC_FALSE; else if (flag == ISC_MEM_HIWATER) ctx->hi_called = ISC_TRUE; MCTXUNLOCK(ctx, &ctx->lock); } #if ISC_MEM_TRACKLINES static void print_active(isc__mem_t *mctx, FILE *out) { if (mctx->debuglist != NULL) { debuglink_t *dl; unsigned int i, j; const char *format; isc_boolean_t found; fprintf(out, "%s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM, ISC_MSG_DUMPALLOC, "Dump of all outstanding " "memory allocations:\n")); found = ISC_FALSE; format = isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM, ISC_MSG_PTRFILELINE, "\tptr %p size %u file %s line %u\n"); for (i = 0; i <= mctx->max_size; i++) { dl = ISC_LIST_HEAD(mctx->debuglist[i]); if (dl != NULL) found = ISC_TRUE; while (dl != NULL) { for (j = 0; j < DEBUGLIST_COUNT; j++) if (dl->ptr[j] != NULL) fprintf(out, format, dl->ptr[j], dl->size[j], dl->file[j], dl->line[j]); dl = ISC_LIST_NEXT(dl, link); } } if (!found) fputs(isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM, ISC_MSG_NONE, "\tNone.\n"), out); } } #endif /* * Print the stats[] on the stream "out" with suitable formatting. */ void isc_mem_stats(isc_mem_t *ctx0, FILE *out) { isc__mem_t *ctx = (isc__mem_t *)ctx0; size_t i; const struct stats *s; const isc__mempool_t *pool; REQUIRE(VALID_CONTEXT(ctx)); MCTXLOCK(ctx, &ctx->lock); for (i = 0; i <= ctx->max_size; i++) { s = &ctx->stats[i]; if (s->totalgets == 0U && s->gets == 0U) continue; fprintf(out, "%s%5lu: %11lu gets, %11lu rem", (i == ctx->max_size) ? ">=" : " ", (unsigned long) i, s->totalgets, s->gets); if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0 && (s->blocks != 0U || s->freefrags != 0U)) fprintf(out, " (%lu bl, %lu ff)", s->blocks, s->freefrags); fputc('\n', out); } /* * Note that since a pool can be locked now, these stats might be * somewhat off if the pool is in active use at the time the stats * are dumped. The link fields are protected by the isc_mem_t's * lock, however, so walking this list and extracting integers from * stats fields is always safe. */ pool = ISC_LIST_HEAD(ctx->pools); if (pool != NULL) { fprintf(out, "%s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM, ISC_MSG_POOLSTATS, "[Pool statistics]\n")); fprintf(out, "%15s %10s %10s %10s %10s %10s %10s %10s %1s\n", isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM, ISC_MSG_POOLNAME, "name"), isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM, ISC_MSG_POOLSIZE, "size"), isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM, ISC_MSG_POOLMAXALLOC, "maxalloc"), isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM, ISC_MSG_POOLALLOCATED, "allocated"), isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM, ISC_MSG_POOLFREECOUNT, "freecount"), isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM, ISC_MSG_POOLFREEMAX, "freemax"), isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM, ISC_MSG_POOLFILLCOUNT, "fillcount"), isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM, ISC_MSG_POOLGETS, "gets"), "L"); } while (pool != NULL) { fprintf(out, "%15s %10lu %10u %10u %10u %10u %10u %10u %s\n", #if ISC_MEMPOOL_NAMES pool->name, #else "(not tracked)", #endif (unsigned long) pool->size, pool->maxalloc, pool->allocated, pool->freecount, pool->freemax, pool->fillcount, pool->gets, (pool->lock == NULL ? "N" : "Y")); pool = ISC_LIST_NEXT(pool, link); } #if ISC_MEM_TRACKLINES print_active(ctx, out); #endif MCTXUNLOCK(ctx, &ctx->lock); } /* * Replacements for malloc() and free() -- they implicitly remember the * size of the object allocated (with some additional overhead). */ static void * mem_allocateunlocked(isc_mem_t *ctx0, size_t size) { isc__mem_t *ctx = (isc__mem_t *)ctx0; size_info *si; size += ALIGNMENT_SIZE; if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) size += ALIGNMENT_SIZE; if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) si = mem_getunlocked(ctx, size); else si = mem_get(ctx, size); if (si == NULL) return (NULL); if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) { si->u.ctx = ctx; si++; } si->u.size = size; return (&si[1]); } void * isc___mem_allocate(isc_mem_t *ctx0, size_t size FLARG) { isc__mem_t *ctx = (isc__mem_t *)ctx0; size_info *si; isc_boolean_t call_water = ISC_FALSE; REQUIRE(VALID_CONTEXT(ctx)); MCTXLOCK(ctx, &ctx->lock); si = mem_allocateunlocked((isc_mem_t *)ctx, size); if (((ctx->flags & ISC_MEMFLAG_INTERNAL) == 0) && (si != NULL)) mem_getstats(ctx, si[-1].u.size); #if ISC_MEM_TRACKLINES ADD_TRACE(ctx, si, si[-1].u.size, file, line); #endif if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water && !ctx->is_overmem) { ctx->is_overmem = ISC_TRUE; } if (ctx->hi_water != 0U && !ctx->hi_called && ctx->inuse > ctx->hi_water) { ctx->hi_called = ISC_TRUE; call_water = ISC_TRUE; } if (ctx->inuse > ctx->maxinuse) { ctx->maxinuse = ctx->inuse; if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water && (isc_mem_debugging & ISC_MEM_DEBUGUSAGE) != 0) fprintf(stderr, "maxinuse = %lu\n", (unsigned long)ctx->inuse); } MCTXUNLOCK(ctx, &ctx->lock); if (call_water) (ctx->water)(ctx->water_arg, ISC_MEM_HIWATER); return (si); } void * isc___mem_reallocate(isc_mem_t *ctx0, void *ptr, size_t size FLARG) { isc__mem_t *ctx = (isc__mem_t *)ctx0; void *new_ptr = NULL; size_t oldsize, copysize; REQUIRE(VALID_CONTEXT(ctx)); /* * This function emulates the realloc(3) standard library function: * - if size > 0, allocate new memory; and if ptr is non NULL, copy * as much of the old contents to the new buffer and free the old one. * Note that when allocation fails the original pointer is intact; * the caller must free it. * - if size is 0 and ptr is non NULL, simply free the given ptr. * - this function returns: * pointer to the newly allocated memory, or * NULL if allocation fails or doesn't happen. */ if (size > 0U) { new_ptr = isc__mem_allocate(ctx0, size FLARG_PASS); if (new_ptr != NULL && ptr != NULL) { oldsize = (((size_info *)ptr)[-1]).u.size; INSIST(oldsize >= ALIGNMENT_SIZE); oldsize -= ALIGNMENT_SIZE; if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) { INSIST(oldsize >= ALIGNMENT_SIZE); oldsize -= ALIGNMENT_SIZE; } copysize = (oldsize > size) ? size : oldsize; memmove(new_ptr, ptr, copysize); isc__mem_free(ctx0, ptr FLARG_PASS); } } else if (ptr != NULL) isc__mem_free(ctx0, ptr FLARG_PASS); return (new_ptr); } void isc___mem_free(isc_mem_t *ctx0, void *ptr FLARG) { isc__mem_t *ctx = (isc__mem_t *)ctx0; size_info *si; size_t size; isc_boolean_t call_water= ISC_FALSE; REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(ptr != NULL); if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) { si = &(((size_info *)ptr)[-2]); REQUIRE(si->u.ctx == ctx); size = si[1].u.size; } else { si = &(((size_info *)ptr)[-1]); size = si->u.size; } MCTXLOCK(ctx, &ctx->lock); DELETE_TRACE(ctx, ptr, size, file, line); if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { mem_putunlocked(ctx, si, size); } else { mem_putstats(ctx, si, size); mem_put(ctx, si, size); } /* * The check against ctx->lo_water == 0 is for the condition * when the context was pushed over hi_water but then had * isc_mem_setwater() called with 0 for hi_water and lo_water. */ if (ctx->is_overmem && (ctx->inuse < ctx->lo_water || ctx->lo_water == 0U)) { ctx->is_overmem = ISC_FALSE; } if (ctx->hi_called && (ctx->inuse < ctx->lo_water || ctx->lo_water == 0U)) { ctx->hi_called = ISC_FALSE; if (ctx->water != NULL) call_water = ISC_TRUE; } MCTXUNLOCK(ctx, &ctx->lock); if (call_water) (ctx->water)(ctx->water_arg, ISC_MEM_LOWATER); } /* * Other useful things. */ char * isc___mem_strdup(isc_mem_t *mctx0, const char *s FLARG) { isc__mem_t *mctx = (isc__mem_t *)mctx0; size_t len; char *ns; REQUIRE(VALID_CONTEXT(mctx)); REQUIRE(s != NULL); len = strlen(s); ns = isc__mem_allocate((isc_mem_t *)mctx, len + 1 FLARG_PASS); if (ns != NULL) strncpy(ns, s, len + 1); return (ns); } void isc__mem_setdestroycheck(isc_mem_t *ctx0, isc_boolean_t flag) { isc__mem_t *ctx = (isc__mem_t *)ctx0; REQUIRE(VALID_CONTEXT(ctx)); MCTXLOCK(ctx, &ctx->lock); ctx->checkfree = flag; MCTXUNLOCK(ctx, &ctx->lock); } /* * Quotas */ void isc_mem_setquota(isc_mem_t *ctx0, size_t quota) { isc__mem_t *ctx = (isc__mem_t *)ctx0; REQUIRE(VALID_CONTEXT(ctx)); MCTXLOCK(ctx, &ctx->lock); ctx->quota = quota; MCTXUNLOCK(ctx, &ctx->lock); } size_t isc_mem_getquota(isc_mem_t *ctx0) { isc__mem_t *ctx = (isc__mem_t *)ctx0; size_t quota; REQUIRE(VALID_CONTEXT(ctx)); MCTXLOCK(ctx, &ctx->lock); quota = ctx->quota; MCTXUNLOCK(ctx, &ctx->lock); return (quota); } size_t isc__mem_inuse(isc_mem_t *ctx0) { isc__mem_t *ctx = (isc__mem_t *)ctx0; size_t inuse; REQUIRE(VALID_CONTEXT(ctx)); MCTXLOCK(ctx, &ctx->lock); inuse = ctx->inuse; MCTXUNLOCK(ctx, &ctx->lock); return (inuse); } size_t isc__mem_maxinuse(isc_mem_t *ctx0) { isc__mem_t *ctx = (isc__mem_t *)ctx0; size_t maxinuse; REQUIRE(VALID_CONTEXT(ctx)); MCTXLOCK(ctx, &ctx->lock); maxinuse = ctx->maxinuse; MCTXUNLOCK(ctx, &ctx->lock); return (maxinuse); } size_t isc__mem_total(isc_mem_t *ctx0) { isc__mem_t *ctx = (isc__mem_t *)ctx0; size_t total; REQUIRE(VALID_CONTEXT(ctx)); MCTXLOCK(ctx, &ctx->lock); total = ctx->total; MCTXUNLOCK(ctx, &ctx->lock); return (total); } void isc__mem_setwater(isc_mem_t *ctx0, isc_mem_water_t water, void *water_arg, size_t hiwater, size_t lowater) { isc__mem_t *ctx = (isc__mem_t *)ctx0; isc_boolean_t callwater = ISC_FALSE; isc_mem_water_t oldwater; void *oldwater_arg; REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(hiwater >= lowater); MCTXLOCK(ctx, &ctx->lock); oldwater = ctx->water; oldwater_arg = ctx->water_arg; if (water == NULL) { callwater = ctx->hi_called; ctx->water = NULL; ctx->water_arg = NULL; ctx->hi_water = 0; ctx->lo_water = 0; } else { if (ctx->hi_called && (ctx->water != water || ctx->water_arg != water_arg || ctx->inuse < lowater || lowater == 0U)) callwater = ISC_TRUE; ctx->water = water; ctx->water_arg = water_arg; ctx->hi_water = hiwater; ctx->lo_water = lowater; } MCTXUNLOCK(ctx, &ctx->lock); if (callwater && oldwater != NULL) (oldwater)(oldwater_arg, ISC_MEM_LOWATER); } isc_boolean_t isc__mem_isovermem(isc_mem_t *ctx0) { isc__mem_t *ctx = (isc__mem_t *)ctx0; REQUIRE(VALID_CONTEXT(ctx)); /* * We don't bother to lock the context because 100% accuracy isn't * necessary (and even if we locked the context the returned value * could be different from the actual state when it's used anyway) */ return (ctx->is_overmem); } void isc_mem_setname(isc_mem_t *ctx0, const char *name, void *tag) { isc__mem_t *ctx = (isc__mem_t *)ctx0; REQUIRE(VALID_CONTEXT(ctx)); LOCK(&ctx->lock); memset(ctx->name, 0, sizeof(ctx->name)); strncpy(ctx->name, name, sizeof(ctx->name) - 1); ctx->tag = tag; UNLOCK(&ctx->lock); } const char * isc_mem_getname(isc_mem_t *ctx0) { isc__mem_t *ctx = (isc__mem_t *)ctx0; REQUIRE(VALID_CONTEXT(ctx)); if (ctx->name[0] == 0) return (""); return (ctx->name); } void * isc_mem_gettag(isc_mem_t *ctx0) { isc__mem_t *ctx = (isc__mem_t *)ctx0; REQUIRE(VALID_CONTEXT(ctx)); return (ctx->tag); } /* * Memory pool stuff */ isc_result_t isc__mempool_create(isc_mem_t *mctx0, size_t size, isc_mempool_t **mpctxp) { isc__mem_t *mctx = (isc__mem_t *)mctx0; isc__mempool_t *mpctx; REQUIRE(VALID_CONTEXT(mctx)); REQUIRE(size > 0U); REQUIRE(mpctxp != NULL && *mpctxp == NULL); /* * Allocate space for this pool, initialize values, and if all works * well, attach to the memory context. */ mpctx = isc_mem_get((isc_mem_t *)mctx, sizeof(isc__mempool_t)); if (mpctx == NULL) return (ISC_R_NOMEMORY); mpctx->common.methods = (isc_mempoolmethods_t *)&mempoolmethods; mpctx->common.impmagic = MEMPOOL_MAGIC; mpctx->common.magic = ISCAPI_MPOOL_MAGIC; mpctx->lock = NULL; mpctx->mctx = mctx; mpctx->size = size; mpctx->maxalloc = UINT_MAX; mpctx->allocated = 0; mpctx->freecount = 0; mpctx->freemax = 1; mpctx->fillcount = 1; mpctx->gets = 0; #if ISC_MEMPOOL_NAMES mpctx->name[0] = 0; #endif mpctx->items = NULL; *mpctxp = (isc_mempool_t *)mpctx; MCTXLOCK(mctx, &mctx->lock); ISC_LIST_INITANDAPPEND(mctx->pools, mpctx, link); mctx->poolcnt++; MCTXUNLOCK(mctx, &mctx->lock); return (ISC_R_SUCCESS); } void isc__mempool_setname(isc_mempool_t *mpctx0, const char *name) { isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; REQUIRE(name != NULL); REQUIRE(VALID_MEMPOOL(mpctx)); #if ISC_MEMPOOL_NAMES if (mpctx->lock != NULL) LOCK(mpctx->lock); strncpy(mpctx->name, name, sizeof(mpctx->name) - 1); mpctx->name[sizeof(mpctx->name) - 1] = '\0'; if (mpctx->lock != NULL) UNLOCK(mpctx->lock); #else UNUSED(mpctx); UNUSED(name); #endif } void isc__mempool_destroy(isc_mempool_t **mpctxp) { isc__mempool_t *mpctx; isc__mem_t *mctx; isc_mutex_t *lock; element *item; REQUIRE(mpctxp != NULL); mpctx = (isc__mempool_t *)*mpctxp; REQUIRE(VALID_MEMPOOL(mpctx)); #if ISC_MEMPOOL_NAMES if (mpctx->allocated > 0) UNEXPECTED_ERROR(__FILE__, __LINE__, "isc__mempool_destroy(): mempool %s " "leaked memory", mpctx->name); #endif REQUIRE(mpctx->allocated == 0); mctx = mpctx->mctx; lock = mpctx->lock; if (lock != NULL) LOCK(lock); /* * Return any items on the free list */ MCTXLOCK(mctx, &mctx->lock); while (mpctx->items != NULL) { INSIST(mpctx->freecount > 0); mpctx->freecount--; item = mpctx->items; mpctx->items = item->next; if ((mctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { mem_putunlocked(mctx, item, mpctx->size); } else { mem_putstats(mctx, item, mpctx->size); mem_put(mctx, item, mpctx->size); } } MCTXUNLOCK(mctx, &mctx->lock); /* * Remove our linked list entry from the memory context. */ MCTXLOCK(mctx, &mctx->lock); ISC_LIST_UNLINK(mctx->pools, mpctx, link); mctx->poolcnt--; MCTXUNLOCK(mctx, &mctx->lock); mpctx->common.impmagic = 0; mpctx->common.magic = 0; isc_mem_put((isc_mem_t *)mpctx->mctx, mpctx, sizeof(isc__mempool_t)); if (lock != NULL) UNLOCK(lock); *mpctxp = NULL; } void isc__mempool_associatelock(isc_mempool_t *mpctx0, isc_mutex_t *lock) { isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; REQUIRE(VALID_MEMPOOL(mpctx)); REQUIRE(mpctx->lock == NULL); REQUIRE(lock != NULL); mpctx->lock = lock; } void * isc___mempool_get(isc_mempool_t *mpctx0 FLARG) { isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; element *item; isc__mem_t *mctx; unsigned int i; REQUIRE(VALID_MEMPOOL(mpctx)); mctx = mpctx->mctx; if (mpctx->lock != NULL) LOCK(mpctx->lock); /* * Don't let the caller go over quota */ if (mpctx->allocated >= mpctx->maxalloc) { item = NULL; goto out; } /* * if we have a free list item, return the first here */ item = mpctx->items; if (item != NULL) { mpctx->items = item->next; INSIST(mpctx->freecount > 0); mpctx->freecount--; mpctx->gets++; mpctx->allocated++; goto out; } /* * We need to dip into the well. Lock the memory context here and * fill up our free list. */ MCTXLOCK(mctx, &mctx->lock); for (i = 0; i < mpctx->fillcount; i++) { if ((mctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { item = mem_getunlocked(mctx, mpctx->size); } else { item = mem_get(mctx, mpctx->size); if (item != NULL) mem_getstats(mctx, mpctx->size); } if (item == NULL) break; item->next = mpctx->items; mpctx->items = item; mpctx->freecount++; } MCTXUNLOCK(mctx, &mctx->lock); /* * If we didn't get any items, return NULL. */ item = mpctx->items; if (item == NULL) goto out; mpctx->items = item->next; mpctx->freecount--; mpctx->gets++; mpctx->allocated++; out: if (mpctx->lock != NULL) UNLOCK(mpctx->lock); #if ISC_MEM_TRACKLINES if (item != NULL) { MCTXLOCK(mctx, &mctx->lock); ADD_TRACE(mctx, item, mpctx->size, file, line); MCTXUNLOCK(mctx, &mctx->lock); } #endif /* ISC_MEM_TRACKLINES */ return (item); } /* coverity[+free : arg-1] */ void isc___mempool_put(isc_mempool_t *mpctx0, void *mem FLARG) { isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; isc__mem_t *mctx; element *item; REQUIRE(VALID_MEMPOOL(mpctx)); REQUIRE(mem != NULL); mctx = mpctx->mctx; if (mpctx->lock != NULL) LOCK(mpctx->lock); INSIST(mpctx->allocated > 0); mpctx->allocated--; #if ISC_MEM_TRACKLINES MCTXLOCK(mctx, &mctx->lock); DELETE_TRACE(mctx, mem, mpctx->size, file, line); MCTXUNLOCK(mctx, &mctx->lock); #endif /* ISC_MEM_TRACKLINES */ /* * If our free list is full, return this to the mctx directly. */ if (mpctx->freecount >= mpctx->freemax) { MCTXLOCK(mctx, &mctx->lock); if ((mctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { mem_putunlocked(mctx, mem, mpctx->size); } else { mem_putstats(mctx, mem, mpctx->size); mem_put(mctx, mem, mpctx->size); } MCTXUNLOCK(mctx, &mctx->lock); if (mpctx->lock != NULL) UNLOCK(mpctx->lock); return; } /* * Otherwise, attach it to our free list and bump the counter. */ mpctx->freecount++; item = (element *)mem; item->next = mpctx->items; mpctx->items = item; if (mpctx->lock != NULL) UNLOCK(mpctx->lock); } /* * Quotas */ void isc__mempool_setfreemax(isc_mempool_t *mpctx0, unsigned int limit) { isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; REQUIRE(VALID_MEMPOOL(mpctx)); if (mpctx->lock != NULL) LOCK(mpctx->lock); mpctx->freemax = limit; if (mpctx->lock != NULL) UNLOCK(mpctx->lock); } unsigned int isc_mempool_getfreemax(isc_mempool_t *mpctx0) { isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; unsigned int freemax; REQUIRE(VALID_MEMPOOL(mpctx)); if (mpctx->lock != NULL) LOCK(mpctx->lock); freemax = mpctx->freemax; if (mpctx->lock != NULL) UNLOCK(mpctx->lock); return (freemax); } unsigned int isc_mempool_getfreecount(isc_mempool_t *mpctx0) { isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; unsigned int freecount; REQUIRE(VALID_MEMPOOL(mpctx)); if (mpctx->lock != NULL) LOCK(mpctx->lock); freecount = mpctx->freecount; if (mpctx->lock != NULL) UNLOCK(mpctx->lock); return (freecount); } void isc__mempool_setmaxalloc(isc_mempool_t *mpctx0, unsigned int limit) { isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; REQUIRE(limit > 0); REQUIRE(VALID_MEMPOOL(mpctx)); if (mpctx->lock != NULL) LOCK(mpctx->lock); mpctx->maxalloc = limit; if (mpctx->lock != NULL) UNLOCK(mpctx->lock); } unsigned int isc_mempool_getmaxalloc(isc_mempool_t *mpctx0) { isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; unsigned int maxalloc; REQUIRE(VALID_MEMPOOL(mpctx)); if (mpctx->lock != NULL) LOCK(mpctx->lock); maxalloc = mpctx->maxalloc; if (mpctx->lock != NULL) UNLOCK(mpctx->lock); return (maxalloc); } unsigned int isc__mempool_getallocated(isc_mempool_t *mpctx0) { isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; unsigned int allocated; REQUIRE(VALID_MEMPOOL(mpctx)); if (mpctx->lock != NULL) LOCK(mpctx->lock); allocated = mpctx->allocated; if (mpctx->lock != NULL) UNLOCK(mpctx->lock); return (allocated); } void isc__mempool_setfillcount(isc_mempool_t *mpctx0, unsigned int limit) { isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; REQUIRE(limit > 0); REQUIRE(VALID_MEMPOOL(mpctx)); if (mpctx->lock != NULL) LOCK(mpctx->lock); mpctx->fillcount = limit; if (mpctx->lock != NULL) UNLOCK(mpctx->lock); } unsigned int isc_mempool_getfillcount(isc_mempool_t *mpctx0) { isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0; unsigned int fillcount; REQUIRE(VALID_MEMPOOL(mpctx)); if (mpctx->lock != NULL) LOCK(mpctx->lock); fillcount = mpctx->fillcount; if (mpctx->lock != NULL) UNLOCK(mpctx->lock); return (fillcount); } isc_result_t isc__mem_register(void) { return (isc_mem_register(isc_mem_create2)); } void isc__mem_printactive(isc_mem_t *ctx0, FILE *file) { #if ISC_MEM_TRACKLINES isc__mem_t *ctx = (isc__mem_t *)ctx0; REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(file != NULL); print_active(ctx, file); #else UNUSED(ctx0); UNUSED(file); #endif } void isc_mem_printallactive(FILE *file) { #if !ISC_MEM_TRACKLINES UNUSED(file); #else isc__mem_t *ctx; RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); LOCK(&contextslock); for (ctx = ISC_LIST_HEAD(contexts); ctx != NULL; ctx = ISC_LIST_NEXT(ctx, link)) { fprintf(file, "context: %p\n", ctx); print_active(ctx, file); } UNLOCK(&contextslock); #endif } void isc_mem_checkdestroyed(FILE *file) { #if !ISC_MEM_TRACKLINES UNUSED(file); #endif RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); LOCK(&contextslock); if (!ISC_LIST_EMPTY(contexts)) { #if ISC_MEM_TRACKLINES isc__mem_t *ctx; for (ctx = ISC_LIST_HEAD(contexts); ctx != NULL; ctx = ISC_LIST_NEXT(ctx, link)) { fprintf(file, "context: %p\n", ctx); print_active(ctx, file); } fflush(file); #endif INSIST(0); } UNLOCK(&contextslock); } unsigned int isc_mem_references(isc_mem_t *ctx0) { isc__mem_t *ctx = (isc__mem_t *)ctx0; unsigned int references; REQUIRE(VALID_CONTEXT(ctx)); MCTXLOCK(ctx, &ctx->lock); references = ctx->references; MCTXUNLOCK(ctx, &ctx->lock); return (references); } #if defined(HAVE_LIBXML2) || defined(HAVE_JSON) typedef struct summarystat { isc_uint64_t total; isc_uint64_t inuse; isc_uint64_t blocksize; isc_uint64_t contextsize; } summarystat_t; #endif #ifdef HAVE_LIBXML2 #define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0) static int xml_renderctx(isc__mem_t *ctx, summarystat_t *summary, xmlTextWriterPtr writer) { int xmlrc; REQUIRE(VALID_CONTEXT(ctx)); MCTXLOCK(ctx, &ctx->lock); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "context")); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "id")); TRY0(xmlTextWriterWriteFormatString(writer, "%p", ctx)); TRY0(xmlTextWriterEndElement(writer)); /* id */ if (ctx->name[0] != 0) { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); TRY0(xmlTextWriterWriteFormatString(writer, "%s", ctx->name)); TRY0(xmlTextWriterEndElement(writer)); /* name */ } summary->contextsize += sizeof(*ctx) + (ctx->max_size + 1) * sizeof(struct stats) + ctx->max_size * sizeof(element *) + ctx->basic_table_count * sizeof(char *); #if ISC_MEM_TRACKLINES if (ctx->debuglist != NULL) { summary->contextsize += (ctx->max_size + 1) * sizeof(debuglist_t) + ctx->debuglistcnt * sizeof(debuglink_t); } #endif TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references")); TRY0(xmlTextWriterWriteFormatString(writer, "%d", ctx->references)); TRY0(xmlTextWriterEndElement(writer)); /* references */ summary->total += ctx->total; TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "total")); TRY0(xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", (isc_uint64_t)ctx->total)); TRY0(xmlTextWriterEndElement(writer)); /* total */ summary->inuse += ctx->inuse; TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "inuse")); TRY0(xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", (isc_uint64_t)ctx->inuse)); TRY0(xmlTextWriterEndElement(writer)); /* inuse */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "maxinuse")); TRY0(xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", (isc_uint64_t)ctx->maxinuse)); TRY0(xmlTextWriterEndElement(writer)); /* maxinuse */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "blocksize")); if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { summary->blocksize += ctx->basic_table_count * NUM_BASIC_BLOCKS * ctx->mem_target; TRY0(xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", (isc_uint64_t) ctx->basic_table_count * NUM_BASIC_BLOCKS * ctx->mem_target)); } else TRY0(xmlTextWriterWriteFormatString(writer, "%s", "-")); TRY0(xmlTextWriterEndElement(writer)); /* blocksize */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "pools")); TRY0(xmlTextWriterWriteFormatString(writer, "%u", ctx->poolcnt)); TRY0(xmlTextWriterEndElement(writer)); /* pools */ summary->contextsize += ctx->poolcnt * sizeof(isc_mempool_t); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "hiwater")); TRY0(xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", (isc_uint64_t)ctx->hi_water)); TRY0(xmlTextWriterEndElement(writer)); /* hiwater */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "lowater")); TRY0(xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", (isc_uint64_t)ctx->lo_water)); TRY0(xmlTextWriterEndElement(writer)); /* lowater */ TRY0(xmlTextWriterEndElement(writer)); /* context */ error: MCTXUNLOCK(ctx, &ctx->lock); return (xmlrc); } int isc_mem_renderxml(xmlTextWriterPtr writer) { isc__mem_t *ctx; summarystat_t summary; isc_uint64_t lost; int xmlrc; memset(&summary, 0, sizeof(summary)); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "contexts")); RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); LOCK(&contextslock); lost = totallost; for (ctx = ISC_LIST_HEAD(contexts); ctx != NULL; ctx = ISC_LIST_NEXT(ctx, link)) { xmlrc = xml_renderctx(ctx, &summary, writer); if (xmlrc < 0) { UNLOCK(&contextslock); goto error; } } UNLOCK(&contextslock); TRY0(xmlTextWriterEndElement(writer)); /* contexts */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "summary")); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "TotalUse")); TRY0(xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", summary.total)); TRY0(xmlTextWriterEndElement(writer)); /* TotalUse */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "InUse")); TRY0(xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", summary.inuse)); TRY0(xmlTextWriterEndElement(writer)); /* InUse */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "BlockSize")); TRY0(xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", summary.blocksize)); TRY0(xmlTextWriterEndElement(writer)); /* BlockSize */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "ContextSize")); TRY0(xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", summary.contextsize)); TRY0(xmlTextWriterEndElement(writer)); /* ContextSize */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "Lost")); TRY0(xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", lost)); TRY0(xmlTextWriterEndElement(writer)); /* Lost */ TRY0(xmlTextWriterEndElement(writer)); /* summary */ error: return (xmlrc); } #endif /* HAVE_LIBXML2 */ #ifdef HAVE_JSON #define CHECKMEM(m) do { \ if (m == NULL) { \ result = ISC_R_NOMEMORY;\ goto error;\ } \ } while(0) static isc_result_t json_renderctx(isc__mem_t *ctx, summarystat_t *summary, json_object *array) { isc_result_t result = ISC_R_FAILURE; json_object *ctxobj, *obj; char buf[1024]; REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(summary != NULL); REQUIRE(array != NULL); MCTXLOCK(ctx, &ctx->lock); summary->contextsize += sizeof(*ctx) + (ctx->max_size + 1) * sizeof(struct stats) + ctx->max_size * sizeof(element *) + ctx->basic_table_count * sizeof(char *); summary->total += ctx->total; summary->inuse += ctx->inuse; if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) summary->blocksize += ctx->basic_table_count * NUM_BASIC_BLOCKS * ctx->mem_target; #if ISC_MEM_TRACKLINES if (ctx->debuglist != NULL) { summary->contextsize += (ctx->max_size + 1) * sizeof(debuglist_t) + ctx->debuglistcnt * sizeof(debuglink_t); } #endif ctxobj = json_object_new_object(); CHECKMEM(ctxobj); sprintf(buf, "%p", ctx); obj = json_object_new_string(buf); CHECKMEM(obj); json_object_object_add(ctxobj, "id", obj); if (ctx->name[0] != 0) { obj = json_object_new_string(ctx->name); CHECKMEM(obj); json_object_object_add(ctxobj, "name", obj); } obj = json_object_new_int64(ctx->references); CHECKMEM(obj); json_object_object_add(ctxobj, "references", obj); obj = json_object_new_int64(ctx->total); CHECKMEM(obj); json_object_object_add(ctxobj, "total", obj); obj = json_object_new_int64(ctx->inuse); CHECKMEM(obj); json_object_object_add(ctxobj, "inuse", obj); obj = json_object_new_int64(ctx->maxinuse); CHECKMEM(obj); json_object_object_add(ctxobj, "maxinuse", obj); if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { isc_uint64_t blocksize; blocksize = ctx->basic_table_count * NUM_BASIC_BLOCKS * ctx->mem_target; obj = json_object_new_int64(blocksize); CHECKMEM(obj); json_object_object_add(ctxobj, "blocksize", obj); } obj = json_object_new_int64(ctx->poolcnt); CHECKMEM(obj); json_object_object_add(ctxobj, "pools", obj); summary->contextsize += ctx->poolcnt * sizeof(isc_mempool_t); obj = json_object_new_int64(ctx->hi_water); CHECKMEM(obj); json_object_object_add(ctxobj, "hiwater", obj); obj = json_object_new_int64(ctx->lo_water); CHECKMEM(obj); json_object_object_add(ctxobj, "lowater", obj); MCTXUNLOCK(ctx, &ctx->lock); json_object_array_add(array, ctxobj); return (ISC_R_SUCCESS); error: MCTXUNLOCK(ctx, &ctx->lock); if (ctxobj != NULL) json_object_put(ctxobj); return (result); } isc_result_t isc_mem_renderjson(json_object *memobj) { isc_result_t result = ISC_R_SUCCESS; isc__mem_t *ctx; summarystat_t summary; isc_uint64_t lost; json_object *ctxarray, *obj; memset(&summary, 0, sizeof(summary)); RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); ctxarray = json_object_new_array(); CHECKMEM(ctxarray); LOCK(&contextslock); lost = totallost; for (ctx = ISC_LIST_HEAD(contexts); ctx != NULL; ctx = ISC_LIST_NEXT(ctx, link)) { result = json_renderctx(ctx, &summary, ctxarray); if (result != ISC_R_SUCCESS) { UNLOCK(&contextslock); goto error; } } UNLOCK(&contextslock); obj = json_object_new_int64(summary.total); CHECKMEM(obj); json_object_object_add(memobj, "TotalUse", obj); obj = json_object_new_int64(summary.inuse); CHECKMEM(obj); json_object_object_add(memobj, "InUse", obj); obj = json_object_new_int64(summary.blocksize); CHECKMEM(obj); json_object_object_add(memobj, "BlockSize", obj); obj = json_object_new_int64(summary.contextsize); CHECKMEM(obj); json_object_object_add(memobj, "ContextSize", obj); obj = json_object_new_int64(lost); CHECKMEM(obj); json_object_object_add(memobj, "Lost", obj); json_object_object_add(memobj, "contexts", ctxarray); return (ISC_R_SUCCESS); error: if (ctxarray != NULL) json_object_put(ctxarray); return (result); } #endif /* HAVE_JSON */ static isc_memcreatefunc_t mem_createfunc = NULL; isc_result_t isc_mem_register(isc_memcreatefunc_t createfunc) { isc_result_t result = ISC_R_SUCCESS; RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); LOCK(&createlock); if (mem_createfunc == NULL) mem_createfunc = createfunc; else result = ISC_R_EXISTS; UNLOCK(&createlock); return (result); } isc_result_t isc__mem_create2(size_t init_max_size, size_t target_size, isc_mem_t **mctxp, unsigned int flags) { isc_result_t result; LOCK(&createlock); REQUIRE(mem_createfunc != NULL); result = (*mem_createfunc)(init_max_size, target_size, mctxp, flags); UNLOCK(&createlock); return (result); } isc_result_t isc_mem_create(size_t init_max_size, size_t target_size, isc_mem_t **mctxp) { isc_result_t result; if (isc_bind9) return (isc_mem_createx2(init_max_size, target_size, default_memalloc, default_memfree, NULL, mctxp, isc_mem_defaultflags)); LOCK(&createlock); REQUIRE(mem_createfunc != NULL); result = (*mem_createfunc)(init_max_size, target_size, mctxp, isc_mem_defaultflags); UNLOCK(&createlock); return (result); } isc_result_t isc_mem_create2(size_t init_max_size, size_t target_size, isc_mem_t **mctxp, unsigned int flags) { if (isc_bind9) return (isc_mem_createx2(init_max_size, target_size, default_memalloc, default_memfree, NULL, mctxp, flags)); return (isc_mem_createx2(init_max_size, target_size, default_memalloc, default_memfree, NULL, mctxp, flags)); } void isc_mem_attach(isc_mem_t *source, isc_mem_t **targetp) { REQUIRE(ISCAPI_MCTX_VALID(source)); REQUIRE(targetp != NULL && *targetp == NULL); if (isc_bind9) isc__mem_attach(source, targetp); else source->methods->attach(source, targetp); ENSURE(*targetp == source); } void isc_mem_detach(isc_mem_t **mctxp) { REQUIRE(mctxp != NULL && ISCAPI_MCTX_VALID(*mctxp)); if (isc_bind9) isc__mem_detach(mctxp); else (*mctxp)->methods->detach(mctxp); ENSURE(*mctxp == NULL); } void isc_mem_destroy(isc_mem_t **mctxp) { REQUIRE(mctxp != NULL && ISCAPI_MCTX_VALID(*mctxp)); if (isc_bind9) isc__mem_destroy(mctxp); else (*mctxp)->methods->destroy(mctxp); ENSURE(*mctxp == NULL); } void isc_mem_setdestroycheck(isc_mem_t *mctx, isc_boolean_t flag) { REQUIRE(ISCAPI_MCTX_VALID(mctx)); mctx->methods->setdestroycheck(mctx, flag); } void isc_mem_setwater(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg, size_t hiwater, size_t lowater) { REQUIRE(ISCAPI_MCTX_VALID(ctx)); if (isc_bind9) isc__mem_setwater(ctx, water, water_arg, hiwater, lowater); else ctx->methods->setwater(ctx, water, water_arg, hiwater, lowater); } void isc_mem_waterack(isc_mem_t *ctx, int flag) { REQUIRE(ISCAPI_MCTX_VALID(ctx)); if (isc_bind9) isc__mem_waterack(ctx, flag); else ctx->methods->waterack(ctx, flag); } size_t isc_mem_inuse(isc_mem_t *mctx) { REQUIRE(ISCAPI_MCTX_VALID(mctx)); if (isc_bind9) return (isc__mem_inuse(mctx)); return (mctx->methods->inuse(mctx)); } size_t isc_mem_maxinuse(isc_mem_t *mctx) { REQUIRE(ISCAPI_MCTX_VALID(mctx)); if (isc_bind9) return (isc__mem_maxinuse(mctx)); return (mctx->methods->maxinuse(mctx)); } size_t isc_mem_total(isc_mem_t *mctx) { REQUIRE(ISCAPI_MCTX_VALID(mctx)); if (isc_bind9) return (isc__mem_total(mctx)); return (mctx->methods->total(mctx)); } isc_boolean_t isc_mem_isovermem(isc_mem_t *mctx) { REQUIRE(ISCAPI_MCTX_VALID(mctx)); if (isc_bind9) return (isc__mem_isovermem(mctx)); return (mctx->methods->isovermem(mctx)); } isc_result_t isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp) { REQUIRE(ISCAPI_MCTX_VALID(mctx)); return (mctx->methods->mpcreate(mctx, size, mpctxp)); } void isc_mempool_destroy(isc_mempool_t **mpctxp) { REQUIRE(mpctxp != NULL && ISCAPI_MPOOL_VALID(*mpctxp)); if (isc_bind9) isc__mempool_destroy(mpctxp); else (*mpctxp)->methods->destroy(mpctxp); ENSURE(*mpctxp == NULL); } unsigned int isc_mempool_getallocated(isc_mempool_t *mpctx) { REQUIRE(ISCAPI_MPOOL_VALID(mpctx)); if (isc_bind9) return (isc__mempool_getallocated(mpctx)); return (mpctx->methods->getallocated(mpctx)); } void isc_mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit) { REQUIRE(ISCAPI_MPOOL_VALID(mpctx)); if (isc_bind9) isc__mempool_setmaxalloc(mpctx, limit); else mpctx->methods->setmaxalloc(mpctx, limit); } void isc_mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit) { REQUIRE(ISCAPI_MPOOL_VALID(mpctx)); if (isc_bind9) isc__mempool_setfreemax(mpctx, limit); else mpctx->methods->setfreemax(mpctx, limit); } void isc_mempool_setname(isc_mempool_t *mpctx, const char *name) { REQUIRE(ISCAPI_MPOOL_VALID(mpctx)); if (isc_bind9) isc__mempool_setname(mpctx, name); else mpctx->methods->setname(mpctx, name); } void isc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock) { REQUIRE(ISCAPI_MPOOL_VALID(mpctx)); if (isc_bind9) isc__mempool_associatelock(mpctx, lock); else mpctx->methods->associatelock(mpctx, lock); } void isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit) { REQUIRE(ISCAPI_MPOOL_VALID(mpctx)); if (isc_bind9) isc__mempool_setfillcount(mpctx, limit); else mpctx->methods->setfillcount(mpctx, limit); } void * isc__mem_get(isc_mem_t *mctx, size_t size FLARG) { REQUIRE(ISCAPI_MCTX_VALID(mctx)); if (isc_bind9) return (isc___mem_get(mctx, size FLARG_PASS)); return (mctx->methods->memget(mctx, size FLARG_PASS)); } void isc__mem_put(isc_mem_t *mctx, void *ptr, size_t size FLARG) { REQUIRE(ISCAPI_MCTX_VALID(mctx)); if (isc_bind9) isc___mem_put(mctx, ptr, size FLARG_PASS); else mctx->methods->memput(mctx, ptr, size FLARG_PASS); } void isc__mem_putanddetach(isc_mem_t **mctxp, void *ptr, size_t size FLARG) { REQUIRE(mctxp != NULL && ISCAPI_MCTX_VALID(*mctxp)); if (isc_bind9) isc___mem_putanddetach(mctxp, ptr, size FLARG_PASS); else (*mctxp)->methods->memputanddetach(mctxp, ptr, size FLARG_PASS); /* * XXX: We cannot always ensure *mctxp == NULL here * (see lib/isc/mem.c). */ } void * isc__mem_allocate(isc_mem_t *mctx, size_t size FLARG) { REQUIRE(ISCAPI_MCTX_VALID(mctx)); if (isc_bind9) return (isc___mem_allocate(mctx, size FLARG_PASS)); return (mctx->methods->memallocate(mctx, size FLARG_PASS)); } void * isc__mem_reallocate(isc_mem_t *mctx, void *ptr, size_t size FLARG) { REQUIRE(ISCAPI_MCTX_VALID(mctx)); if (isc_bind9) return (isc___mem_reallocate(mctx, ptr, size FLARG_PASS)); return (mctx->methods->memreallocate(mctx, ptr, size FLARG_PASS)); } char * isc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) { REQUIRE(ISCAPI_MCTX_VALID(mctx)); if (isc_bind9) return (isc___mem_strdup(mctx, s FLARG_PASS)); return (mctx->methods->memstrdup(mctx, s FLARG_PASS)); } void isc__mem_free(isc_mem_t *mctx, void *ptr FLARG) { REQUIRE(ISCAPI_MCTX_VALID(mctx)); if (isc_bind9) isc___mem_free(mctx, ptr FLARG_PASS); else mctx->methods->memfree(mctx, ptr FLARG_PASS); } void * isc__mempool_get(isc_mempool_t *mpctx FLARG) { REQUIRE(ISCAPI_MPOOL_VALID(mpctx)); if (isc_bind9) return (isc___mempool_get(mpctx FLARG_PASS)); return (mpctx->methods->get(mpctx FLARG_PASS)); } void isc__mempool_put(isc_mempool_t *mpctx, void *mem FLARG) { REQUIRE(ISCAPI_MPOOL_VALID(mpctx)); if (isc_bind9) isc___mempool_put(mpctx, mem FLARG_PASS); else mpctx->methods->put(mpctx, mem FLARG_PASS); } bind9-9.10.3.dfsg.P4/lib/isc/ondestroy.c0000644000470500017500000000423712664710322017115 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ondestroy.c,v 1.16 2007/06/19 23:47:17 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #define ONDESTROY_MAGIC ISC_MAGIC('D', 'e', 'S', 't') #define VALID_ONDESTROY(s) ISC_MAGIC_VALID(s, ONDESTROY_MAGIC) void isc_ondestroy_init(isc_ondestroy_t *ondest) { ondest->magic = ONDESTROY_MAGIC; ISC_LIST_INIT(ondest->events); } isc_result_t isc_ondestroy_register(isc_ondestroy_t *ondest, isc_task_t *task, isc_event_t **eventp) { isc_event_t *theevent; isc_task_t *thetask = NULL; REQUIRE(VALID_ONDESTROY(ondest)); REQUIRE(task != NULL); REQUIRE(eventp != NULL); theevent = *eventp; REQUIRE(theevent != NULL); isc_task_attach(task, &thetask); theevent->ev_sender = thetask; ISC_LIST_APPEND(ondest->events, theevent, ev_link); return (ISC_R_SUCCESS); } void isc_ondestroy_notify(isc_ondestroy_t *ondest, void *sender) { isc_event_t *eventp; isc_task_t *task; REQUIRE(VALID_ONDESTROY(ondest)); eventp = ISC_LIST_HEAD(ondest->events); while (eventp != NULL) { ISC_LIST_UNLINK(ondest->events, eventp, ev_link); task = eventp->ev_sender; eventp->ev_sender = sender; isc_task_sendanddetach(&task, &eventp); eventp = ISC_LIST_HEAD(ondest->events); } } bind9-9.10.3.dfsg.P4/lib/isc/quota.c0000644000470500017500000000457712664710322016227 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: quota.c,v 1.18 2007/06/19 23:47:17 tbox Exp $ */ /*! \file */ #include #include #include #include isc_result_t isc_quota_init(isc_quota_t *quota, int max) { quota->max = max; quota->used = 0; quota->soft = 0; return (isc_mutex_init("a->lock)); } void isc_quota_destroy(isc_quota_t *quota) { INSIST(quota->used == 0); quota->max = 0; quota->used = 0; quota->soft = 0; DESTROYLOCK("a->lock); } void isc_quota_soft(isc_quota_t *quota, int soft) { LOCK("a->lock); quota->soft = soft; UNLOCK("a->lock); } void isc_quota_max(isc_quota_t *quota, int max) { LOCK("a->lock); quota->max = max; UNLOCK("a->lock); } isc_result_t isc_quota_reserve(isc_quota_t *quota) { isc_result_t result; LOCK("a->lock); if (quota->max == 0 || quota->used < quota->max) { if (quota->soft == 0 || quota->used < quota->soft) result = ISC_R_SUCCESS; else result = ISC_R_SOFTQUOTA; quota->used++; } else result = ISC_R_QUOTA; UNLOCK("a->lock); return (result); } void isc_quota_release(isc_quota_t *quota) { LOCK("a->lock); INSIST(quota->used > 0); quota->used--; UNLOCK("a->lock); } isc_result_t isc_quota_attach(isc_quota_t *quota, isc_quota_t **p) { isc_result_t result; INSIST(p != NULL && *p == NULL); result = isc_quota_reserve(quota); if (result == ISC_R_SUCCESS || result == ISC_R_SOFTQUOTA) *p = quota; return (result); } void isc_quota_detach(isc_quota_t **p) { INSIST(p != NULL && *p != NULL); isc_quota_release(*p); *p = NULL; } bind9-9.10.3.dfsg.P4/lib/isc/bufferlist.c0000644000470500017500000000333312664710322017230 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: bufferlist.c,v 1.17 2007/06/19 23:47:17 tbox Exp $ */ /*! \file */ #include #include #include #include #include unsigned int isc_bufferlist_usedcount(isc_bufferlist_t *bl) { isc_buffer_t *buffer; unsigned int length; REQUIRE(bl != NULL); length = 0; buffer = ISC_LIST_HEAD(*bl); while (buffer != NULL) { REQUIRE(ISC_BUFFER_VALID(buffer)); length += isc_buffer_usedlength(buffer); buffer = ISC_LIST_NEXT(buffer, link); } return (length); } unsigned int isc_bufferlist_availablecount(isc_bufferlist_t *bl) { isc_buffer_t *buffer; unsigned int length; REQUIRE(bl != NULL); length = 0; buffer = ISC_LIST_HEAD(*bl); while (buffer != NULL) { REQUIRE(ISC_BUFFER_VALID(buffer)); length += isc_buffer_availablelength(buffer); buffer = ISC_LIST_NEXT(buffer, link); } return (length); } bind9-9.10.3.dfsg.P4/lib/isc/inet_aton.c0000644000470500017500000001431112664710322017041 0ustar lamontlamont/* * Portions Copyright (C) 2004, 2005, 2007, 2008, 2012-2014 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1996-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (c) 1983, 1990, 1993 * The Regents of the University of California. 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. Neither the name of the University 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 REGENTS 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. */ /* * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /*! \file */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; static char rcsid[] = "$Id: inet_aton.c,v 1.23 2008/12/01 23:47:45 tbox Exp $"; #endif /* LIBC_SCCS and not lint */ #include #include #include /* Required for NULL. */ #include #include /*% * Check whether "cp" is a valid ascii representation * of an Internet address and convert to a binary address. * Returns 1 if the address is valid, 0 if not. * This replaces inet_addr, the return value from which * cannot distinguish between failure and a local broadcast address. */ int isc_net_aton(const char *cp, struct in_addr *addr) { isc_uint32_t val; int base; ptrdiff_t n; unsigned char c; isc_uint8_t parts[4]; isc_uint8_t *pp = parts; int digit; c = *cp; for (;;) { /* * Collect number up to ``.''. * Values are specified as for C: * 0x=hex, 0=octal, isdigit=decimal. */ if (!isdigit(c & 0xff)) return (0); val = 0; base = 10; digit = 0; if (c == '0') { c = *++cp; if (c == 'x' || c == 'X') base = 16, c = *++cp; else { base = 8; digit = 1; } } for (;;) { /* * isascii() is valid for all integer values, and * when it is true, c is known to be in scope * for isdigit(). No cast necessary. Similar * comment applies for later ctype uses. */ if (isascii(c) && isdigit(c)) { if (base == 8 && (c == '8' || c == '9')) return (0); val = (val * base) + (c - '0'); c = *++cp; digit = 1; } else if (base == 16 && isascii(c) && isxdigit(c)) { val = (val << 4) | (c + 10 - (islower(c) ? 'a' : 'A')); c = *++cp; digit = 1; } else break; } if (c == '.') { /* * Internet format: * a.b.c.d * a.b.c (with c treated as 16 bits) * a.b (with b treated as 24 bits) */ if (pp >= parts + 3 || val > 0xffU) return (0); *pp++ = (isc_uint8_t)val; c = *++cp; } else break; } /* * Check for trailing characters. */ if (c != '\0' && (!isascii(c) || !isspace(c))) return (0); /* * Did we get a valid digit? */ if (!digit) return (0); /* * Concoct the address according to * the number of parts specified. */ n = pp - parts + 1; switch (n) { case 1: /* a -- 32 bits */ break; case 2: /* a.b -- 8.24 bits */ if (val > 0xffffffU) return (0); val |= parts[0] << 24; break; case 3: /* a.b.c -- 8.8.16 bits */ if (val > 0xffffU) return (0); val |= (parts[0] << 24) | (parts[1] << 16); break; case 4: /* a.b.c.d -- 8.8.8.8 bits */ if (val > 0xffU) return (0); val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); break; } if (addr != NULL) addr->s_addr = htonl(val); return (1); } bind9-9.10.3.dfsg.P4/lib/isc/powerpc/0002755000470500017500000000000012672612753016406 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/powerpc/Makefile.in0000644000470500017500000000166312664710322020447 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = include TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/powerpc/include/0002755000470500017500000000000012664710322020021 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/powerpc/include/Makefile.in0000644000470500017500000000165712664710322022075 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = isc TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/powerpc/include/isc/0002755000470500017500000000000012664710322020577 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/powerpc/include/isc/Makefile.in0000644000470500017500000000223012664710322022637 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ HEADERS = atomic.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \ done bind9-9.10.3.dfsg.P4/lib/isc/powerpc/include/isc/atomic.h0000644000470500017500000000735712664710322022236 0ustar lamontlamont/* * Copyright (C) 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef ISC_ATOMIC_H #define ISC_ATOMIC_H 1 #include #include /*!\file * static inline isc_int32_t * isc_atomic_xadd(isc_int32_t *p, isc_int32_t val); * * This routine atomically increments the value stored in 'p' by 'val', and * returns the previous value. * * static inline void * isc_atomic_store(void *p, isc_int32_t val); * * This routine atomically stores the value 'val' in 'p'. * * static inline isc_int32_t * isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val); * * This routine atomically replaces the value in 'p' with 'val', if the * original value is equal to 'cmpval'. The original value is returned in any * case. */ #if defined(_AIX) #include #define isc_atomic_store(p, v) _clear_lock(p, v) #ifdef __GNUC__ static inline isc_int32_t #else static isc_int32_t #endif isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) { int ret; #ifdef __GNUC__ asm("ics"); #else __isync(); #endif ret = fetch_and_add((atomic_p)p, (int)val); #ifdef __GNUC__ asm("ics"); #else __isync(); #endif return (ret); } #ifdef __GNUC__ static inline int #else static int #endif isc_atomic_cmpxchg(atomic_p p, int old, int new) { int orig = old; #ifdef __GNUC__ asm("ics"); #else __isync(); #endif if (compare_and_swap(p, &orig, new)) orig = old; #ifdef __GNUC__ asm("ics"); #else __isync(); #endif return (orig); } #elif defined(ISC_PLATFORM_USEGCCASM) || defined(ISC_PLATFORM_USEMACASM) static inline isc_int32_t isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) { isc_int32_t orig; __asm__ volatile ( #ifdef ISC_PLATFORM_USEMACASM "1:" "lwarx r6, 0, %1\n" "mr %0, r6\n" "add r6, r6, %2\n" "stwcx. r6, 0, %1\n" "bne- 1b\n" "sync" #else "1:" "lwarx 6, 0, %1\n" "mr %0, 6\n" "add 6, 6, %2\n" "stwcx. 6, 0, %1\n" "bne- 1b\n" "sync" #endif : "=&r"(orig) : "r"(p), "r"(val) : "r6", "memory" ); return (orig); } static inline void isc_atomic_store(void *p, isc_int32_t val) { __asm__ volatile ( #ifdef ISC_PLATFORM_USEMACASM "1:" "lwarx r6, 0, %0\n" "lwz r6, %1\n" "stwcx. r6, 0, %0\n" "bne- 1b\n" "sync" #else "1:" "lwarx 6, 0, %0\n" "lwz 6, %1\n" "stwcx. 6, 0, %0\n" "bne- 1b\n" "sync" #endif : : "r"(p), "m"(val) : "r6", "memory" ); } static inline isc_int32_t isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) { isc_int32_t orig; __asm__ volatile ( #ifdef ISC_PLATFORM_USEMACASM "1:" "lwarx r6, 0, %1\n" "mr %0,r6\n" "cmpw r6, %2\n" "bne 2f\n" "mr r6, %3\n" "stwcx. r6, 0, %1\n" "bne- 1b\n" "2:\n" "sync" #else "1:" "lwarx 6, 0, %1\n" "mr %0,6\n" "cmpw 6, %2\n" "bne 2f\n" "mr 6, %3\n" "stwcx. 6, 0, %1\n" "bne- 1b\n" "2:\n" "sync" #endif : "=&r" (orig) : "r"(p), "r"(cmpval), "r"(val) : "r6", "memory" ); return (orig); } #else #error "unsupported compiler. disable atomic ops by --disable-atomic" #endif #endif /* ISC_ATOMIC_H */ bind9-9.10.3.dfsg.P4/lib/isc/log.c0000644000470500017500000013173012664710322015647 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file * \author Principal Authors: DCL */ #include #include #include #include #include #include /* dev_t FreeBSD 2.1 */ #include #include #include #include #include #include #include #include #include #include #include #include #define LCTX_MAGIC ISC_MAGIC('L', 'c', 't', 'x') #define VALID_CONTEXT(lctx) ISC_MAGIC_VALID(lctx, LCTX_MAGIC) #define LCFG_MAGIC ISC_MAGIC('L', 'c', 'f', 'g') #define VALID_CONFIG(lcfg) ISC_MAGIC_VALID(lcfg, LCFG_MAGIC) /* * XXXDCL make dynamic? */ #define LOG_BUFFER_SIZE (8 * 1024) #ifndef PATH_MAX #define PATH_MAX 1024 /* AIX and others don't define this. */ #endif /*! * This is the structure that holds each named channel. A simple linked * list chains all of the channels together, so an individual channel is * found by doing strcmp()s with the names down the list. Their should * be no performance penalty from this as it is expected that the number * of named channels will be no more than a dozen or so, and name lookups * from the head of the list are only done when isc_log_usechannel() is * called, which should also be very infrequent. */ typedef struct isc_logchannel isc_logchannel_t; struct isc_logchannel { char * name; unsigned int type; int level; unsigned int flags; isc_logdestination_t destination; ISC_LINK(isc_logchannel_t) link; }; /*! * The logchannellist structure associates categories and modules with * channels. First the appropriate channellist is found based on the * category, and then each structure in the linked list is checked for * a matching module. It is expected that the number of channels * associated with any given category will be very short, no more than * three or four in the more unusual cases. */ typedef struct isc_logchannellist isc_logchannellist_t; struct isc_logchannellist { const isc_logmodule_t * module; isc_logchannel_t * channel; ISC_LINK(isc_logchannellist_t) link; }; /*! * This structure is used to remember messages for pruning via * isc_log_[v]write1(). */ typedef struct isc_logmessage isc_logmessage_t; struct isc_logmessage { char * text; isc_time_t time; ISC_LINK(isc_logmessage_t) link; }; /*! * The isc_logconfig structure is used to store the configurable information * about where messages are actually supposed to be sent -- the information * that could changed based on some configuration file, as opposed to the * the category/module specification of isc_log_[v]write[1] that is compiled * into a program, or the debug_level which is dynamic state information. */ struct isc_logconfig { unsigned int magic; isc_log_t * lctx; ISC_LIST(isc_logchannel_t) channels; ISC_LIST(isc_logchannellist_t) *channellists; unsigned int channellist_count; unsigned int duplicate_interval; int highest_level; char * tag; isc_boolean_t dynamic; }; /*! * This isc_log structure provides the context for the isc_log functions. * The log context locks itself in isc_log_doit, the internal backend to * isc_log_write. The locking is necessary both to provide exclusive access * to the buffer into which the message is formatted and to guard against * competing threads trying to write to the same syslog resource. (On * some systems, such as BSD/OS, stdio is thread safe but syslog is not.) * Unfortunately, the lock cannot guard against a _different_ logging * context in the same program competing for syslog's attention. Thus * There Can Be Only One, but this is not enforced. * XXXDCL enforce it? * * Note that the category and module information is not locked. * This is because in the usual case, only one isc_log_t is ever created * in a program, and the category/module registration happens only once. * XXXDCL it might be wise to add more locking overall. */ struct isc_log { /* Not locked. */ unsigned int magic; isc_mem_t * mctx; isc_logcategory_t * categories; unsigned int category_count; isc_logmodule_t * modules; unsigned int module_count; int debug_level; isc_mutex_t lock; /* Locked by isc_log lock. */ isc_logconfig_t * logconfig; char buffer[LOG_BUFFER_SIZE]; ISC_LIST(isc_logmessage_t) messages; }; /*! * Used when ISC_LOG_PRINTLEVEL is enabled for a channel. */ static const char *log_level_strings[] = { "debug", "info", "notice", "warning", "error", "critical" }; /*! * Used to convert ISC_LOG_* priorities into syslog priorities. * XXXDCL This will need modification for NT. */ static const int syslog_map[] = { LOG_DEBUG, LOG_INFO, LOG_NOTICE, LOG_WARNING, LOG_ERR, LOG_CRIT }; /*! * When adding new categories, a corresponding ISC_LOGCATEGORY_foo * definition needs to be added to . * * The default category is provided so that the internal default can * be overridden. Since the default is always looked up as the first * channellist in the log context, it must come first in isc_categories[]. */ LIBISC_EXTERNAL_DATA isc_logcategory_t isc_categories[] = { { "default", 0 }, /* "default" must come first. */ { "general", 0 }, { NULL, 0 } }; /*! * See above comment for categories on LIBISC_EXTERNAL_DATA, and apply it to modules. */ LIBISC_EXTERNAL_DATA isc_logmodule_t isc_modules[] = { { "socket", 0 }, { "time", 0 }, { "interface", 0 }, { "timer", 0 }, { "file", 0 }, { "other", 0 }, { NULL, 0 } }; /*! * This essentially constant structure must be filled in at run time, * because its channel member is pointed to a channel that is created * dynamically with isc_log_createchannel. */ static isc_logchannellist_t default_channel; /*! * libisc logs to this context. */ LIBISC_EXTERNAL_DATA isc_log_t *isc_lctx = NULL; /*! * Forward declarations. */ static isc_result_t assignchannel(isc_logconfig_t *lcfg, unsigned int category_id, const isc_logmodule_t *module, isc_logchannel_t *channel); static isc_result_t sync_channellist(isc_logconfig_t *lcfg); static isc_result_t greatest_version(isc_logchannel_t *channel, int *greatest); static isc_result_t roll_log(isc_logchannel_t *channel); static void isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, isc_boolean_t write_once, isc_msgcat_t *msgcat, int msgset, int msg, const char *format, va_list args) ISC_FORMAT_PRINTF(9, 0); /*@{*/ /*! * Convenience macros. */ #define FACILITY(channel) (channel->destination.facility) #define FILE_NAME(channel) (channel->destination.file.name) #define FILE_STREAM(channel) (channel->destination.file.stream) #define FILE_VERSIONS(channel) (channel->destination.file.versions) #define FILE_MAXSIZE(channel) (channel->destination.file.maximum_size) #define FILE_MAXREACHED(channel) (channel->destination.file.maximum_reached) /*@}*/ /**** **** Public interfaces. ****/ /* * Establish a new logging context, with default channels. */ isc_result_t isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp, isc_logconfig_t **lcfgp) { isc_log_t *lctx; isc_logconfig_t *lcfg = NULL; isc_result_t result; REQUIRE(mctx != NULL); REQUIRE(lctxp != NULL && *lctxp == NULL); REQUIRE(lcfgp == NULL || *lcfgp == NULL); lctx = isc_mem_get(mctx, sizeof(*lctx)); if (lctx != NULL) { lctx->mctx = NULL; isc_mem_attach(mctx, &lctx->mctx); lctx->categories = NULL; lctx->category_count = 0; lctx->modules = NULL; lctx->module_count = 0; lctx->debug_level = 0; ISC_LIST_INIT(lctx->messages); result = isc_mutex_init(&lctx->lock); if (result != ISC_R_SUCCESS) { isc_mem_putanddetach(&mctx, lctx, sizeof(*lctx)); return (result); } /* * Normally setting the magic number is the last step done * in a creation function, but a valid log context is needed * by isc_log_registercategories and isc_logconfig_create. * If either fails, the lctx is destroyed and not returned * to the caller. */ lctx->magic = LCTX_MAGIC; isc_log_registercategories(lctx, isc_categories); isc_log_registermodules(lctx, isc_modules); result = isc_logconfig_create(lctx, &lcfg); } else result = ISC_R_NOMEMORY; if (result == ISC_R_SUCCESS) result = sync_channellist(lcfg); if (result == ISC_R_SUCCESS) { lctx->logconfig = lcfg; *lctxp = lctx; if (lcfgp != NULL) *lcfgp = lcfg; } else { if (lcfg != NULL) isc_logconfig_destroy(&lcfg); if (lctx != NULL) isc_log_destroy(&lctx); } return (result); } isc_result_t isc_logconfig_create(isc_log_t *lctx, isc_logconfig_t **lcfgp) { isc_logconfig_t *lcfg; isc_logdestination_t destination; isc_result_t result = ISC_R_SUCCESS; int level = ISC_LOG_INFO; REQUIRE(lcfgp != NULL && *lcfgp == NULL); REQUIRE(VALID_CONTEXT(lctx)); lcfg = isc_mem_get(lctx->mctx, sizeof(*lcfg)); if (lcfg != NULL) { lcfg->lctx = lctx; lcfg->channellists = NULL; lcfg->channellist_count = 0; lcfg->duplicate_interval = 0; lcfg->highest_level = level; lcfg->tag = NULL; lcfg->dynamic = ISC_FALSE; ISC_LIST_INIT(lcfg->channels); /* * Normally the magic number is the last thing set in the * structure, but isc_log_createchannel() needs a valid * config. If the channel creation fails, the lcfg is not * returned to the caller. */ lcfg->magic = LCFG_MAGIC; } else result = ISC_R_NOMEMORY; /* * Create the default channels: * default_syslog, default_stderr, default_debug and null. */ if (result == ISC_R_SUCCESS) { destination.facility = LOG_DAEMON; result = isc_log_createchannel(lcfg, "default_syslog", ISC_LOG_TOSYSLOG, level, &destination, 0); } if (result == ISC_R_SUCCESS) { destination.file.stream = stderr; destination.file.name = NULL; destination.file.versions = ISC_LOG_ROLLNEVER; destination.file.maximum_size = 0; result = isc_log_createchannel(lcfg, "default_stderr", ISC_LOG_TOFILEDESC, level, &destination, ISC_LOG_PRINTTIME); } if (result == ISC_R_SUCCESS) { /* * Set the default category's channel to default_stderr, * which is at the head of the channels list because it was * just created. */ default_channel.channel = ISC_LIST_HEAD(lcfg->channels); destination.file.stream = stderr; destination.file.name = NULL; destination.file.versions = ISC_LOG_ROLLNEVER; destination.file.maximum_size = 0; result = isc_log_createchannel(lcfg, "default_debug", ISC_LOG_TOFILEDESC, ISC_LOG_DYNAMIC, &destination, ISC_LOG_PRINTTIME); } if (result == ISC_R_SUCCESS) result = isc_log_createchannel(lcfg, "null", ISC_LOG_TONULL, ISC_LOG_DYNAMIC, NULL, 0); if (result == ISC_R_SUCCESS) *lcfgp = lcfg; else if (lcfg != NULL) isc_logconfig_destroy(&lcfg); return (result); } isc_logconfig_t * isc_logconfig_get(isc_log_t *lctx) { REQUIRE(VALID_CONTEXT(lctx)); ENSURE(lctx->logconfig != NULL); return (lctx->logconfig); } isc_result_t isc_logconfig_use(isc_log_t *lctx, isc_logconfig_t *lcfg) { isc_logconfig_t *old_cfg; isc_result_t result; REQUIRE(VALID_CONTEXT(lctx)); REQUIRE(VALID_CONFIG(lcfg)); REQUIRE(lcfg->lctx == lctx); /* * Ensure that lcfg->channellist_count == lctx->category_count. * They won't be equal if isc_log_usechannel has not been called * since any call to isc_log_registercategories. */ result = sync_channellist(lcfg); if (result != ISC_R_SUCCESS) return (result); LOCK(&lctx->lock); old_cfg = lctx->logconfig; lctx->logconfig = lcfg; UNLOCK(&lctx->lock); isc_logconfig_destroy(&old_cfg); return (ISC_R_SUCCESS); } void isc_log_destroy(isc_log_t **lctxp) { isc_log_t *lctx; isc_logconfig_t *lcfg; isc_mem_t *mctx; isc_logmessage_t *message; REQUIRE(lctxp != NULL && VALID_CONTEXT(*lctxp)); lctx = *lctxp; mctx = lctx->mctx; if (lctx->logconfig != NULL) { lcfg = lctx->logconfig; lctx->logconfig = NULL; isc_logconfig_destroy(&lcfg); } DESTROYLOCK(&lctx->lock); while ((message = ISC_LIST_HEAD(lctx->messages)) != NULL) { ISC_LIST_UNLINK(lctx->messages, message, link); isc_mem_put(mctx, message, sizeof(*message) + strlen(message->text) + 1); } lctx->buffer[0] = '\0'; lctx->debug_level = 0; lctx->categories = NULL; lctx->category_count = 0; lctx->modules = NULL; lctx->module_count = 0; lctx->mctx = NULL; lctx->magic = 0; isc_mem_putanddetach(&mctx, lctx, sizeof(*lctx)); *lctxp = NULL; } void isc_logconfig_destroy(isc_logconfig_t **lcfgp) { isc_logconfig_t *lcfg; isc_mem_t *mctx; isc_logchannel_t *channel; isc_logchannellist_t *item; char *filename; unsigned int i; REQUIRE(lcfgp != NULL && VALID_CONFIG(*lcfgp)); lcfg = *lcfgp; /* * This function cannot be called with a logconfig that is in * use by a log context. */ REQUIRE(lcfg->lctx != NULL && lcfg->lctx->logconfig != lcfg); mctx = lcfg->lctx->mctx; while ((channel = ISC_LIST_HEAD(lcfg->channels)) != NULL) { ISC_LIST_UNLINK(lcfg->channels, channel, link); if (channel->type == ISC_LOG_TOFILE) { /* * The filename for the channel may have ultimately * started its life in user-land as a const string, * but in isc_log_createchannel it gets copied * into writable memory and is not longer truly const. */ DE_CONST(FILE_NAME(channel), filename); isc_mem_free(mctx, filename); if (FILE_STREAM(channel) != NULL) (void)fclose(FILE_STREAM(channel)); } isc_mem_free(mctx, channel->name); isc_mem_put(mctx, channel, sizeof(*channel)); } for (i = 0; i < lcfg->channellist_count; i++) while ((item = ISC_LIST_HEAD(lcfg->channellists[i])) != NULL) { ISC_LIST_UNLINK(lcfg->channellists[i], item, link); isc_mem_put(mctx, item, sizeof(*item)); } if (lcfg->channellist_count > 0) isc_mem_put(mctx, lcfg->channellists, lcfg->channellist_count * sizeof(ISC_LIST(isc_logchannellist_t))); lcfg->dynamic = ISC_FALSE; if (lcfg->tag != NULL) isc_mem_free(lcfg->lctx->mctx, lcfg->tag); lcfg->tag = NULL; lcfg->highest_level = 0; lcfg->duplicate_interval = 0; lcfg->magic = 0; isc_mem_put(mctx, lcfg, sizeof(*lcfg)); *lcfgp = NULL; } void isc_log_registercategories(isc_log_t *lctx, isc_logcategory_t categories[]) { isc_logcategory_t *catp; REQUIRE(VALID_CONTEXT(lctx)); REQUIRE(categories != NULL && categories[0].name != NULL); /* * XXXDCL This somewhat sleazy situation of using the last pointer * in one category array to point to the next array exists because * this registration function returns void and I didn't want to have * change everything that used it by making it return an isc_result_t. * It would need to do that if it had to allocate memory to store * pointers to each array passed in. */ if (lctx->categories == NULL) lctx->categories = categories; else { /* * Adjust the last (NULL) pointer of the already registered * categories to point to the incoming array. */ for (catp = lctx->categories; catp->name != NULL; ) if (catp->id == UINT_MAX) /* * The name pointer points to the next array. * Ick. */ DE_CONST(catp->name, catp); else catp++; catp->name = (void *)categories; catp->id = UINT_MAX; } /* * Update the id number of the category with its new global id. */ for (catp = categories; catp->name != NULL; catp++) catp->id = lctx->category_count++; } isc_logcategory_t * isc_log_categorybyname(isc_log_t *lctx, const char *name) { isc_logcategory_t *catp; REQUIRE(VALID_CONTEXT(lctx)); REQUIRE(name != NULL); for (catp = lctx->categories; catp->name != NULL; ) if (catp->id == UINT_MAX) /* * catp is neither modified nor returned to the * caller, so removing its const qualifier is ok. */ DE_CONST(catp->name, catp); else { if (strcmp(catp->name, name) == 0) return (catp); catp++; } return (NULL); } void isc_log_registermodules(isc_log_t *lctx, isc_logmodule_t modules[]) { isc_logmodule_t *modp; REQUIRE(VALID_CONTEXT(lctx)); REQUIRE(modules != NULL && modules[0].name != NULL); /* * XXXDCL This somewhat sleazy situation of using the last pointer * in one category array to point to the next array exists because * this registration function returns void and I didn't want to have * change everything that used it by making it return an isc_result_t. * It would need to do that if it had to allocate memory to store * pointers to each array passed in. */ if (lctx->modules == NULL) lctx->modules = modules; else { /* * Adjust the last (NULL) pointer of the already registered * modules to point to the incoming array. */ for (modp = lctx->modules; modp->name != NULL; ) if (modp->id == UINT_MAX) /* * The name pointer points to the next array. * Ick. */ DE_CONST(modp->name, modp); else modp++; modp->name = (void *)modules; modp->id = UINT_MAX; } /* * Update the id number of the module with its new global id. */ for (modp = modules; modp->name != NULL; modp++) modp->id = lctx->module_count++; } isc_logmodule_t * isc_log_modulebyname(isc_log_t *lctx, const char *name) { isc_logmodule_t *modp; REQUIRE(VALID_CONTEXT(lctx)); REQUIRE(name != NULL); for (modp = lctx->modules; modp->name != NULL; ) if (modp->id == UINT_MAX) /* * modp is neither modified nor returned to the * caller, so removing its const qualifier is ok. */ DE_CONST(modp->name, modp); else { if (strcmp(modp->name, name) == 0) return (modp); modp++; } return (NULL); } isc_result_t isc_log_createchannel(isc_logconfig_t *lcfg, const char *name, unsigned int type, int level, const isc_logdestination_t *destination, unsigned int flags) { isc_logchannel_t *channel; isc_mem_t *mctx; REQUIRE(VALID_CONFIG(lcfg)); REQUIRE(name != NULL); REQUIRE(type == ISC_LOG_TOSYSLOG || type == ISC_LOG_TOFILE || type == ISC_LOG_TOFILEDESC || type == ISC_LOG_TONULL); REQUIRE(destination != NULL || type == ISC_LOG_TONULL); REQUIRE(level >= ISC_LOG_CRITICAL); REQUIRE((flags & (unsigned int)~(ISC_LOG_PRINTALL | ISC_LOG_DEBUGONLY)) == 0); /* XXXDCL find duplicate names? */ mctx = lcfg->lctx->mctx; channel = isc_mem_get(mctx, sizeof(*channel)); if (channel == NULL) return (ISC_R_NOMEMORY); channel->name = isc_mem_strdup(mctx, name); if (channel->name == NULL) { isc_mem_put(mctx, channel, sizeof(*channel)); return (ISC_R_NOMEMORY); } channel->type = type; channel->level = level; channel->flags = flags; ISC_LINK_INIT(channel, link); switch (type) { case ISC_LOG_TOSYSLOG: FACILITY(channel) = destination->facility; break; case ISC_LOG_TOFILE: /* * The file name is copied because greatest_version wants * to scribble on it, so it needs to be definitely in * writable memory. */ FILE_NAME(channel) = isc_mem_strdup(mctx, destination->file.name); FILE_STREAM(channel) = NULL; FILE_VERSIONS(channel) = destination->file.versions; FILE_MAXSIZE(channel) = destination->file.maximum_size; FILE_MAXREACHED(channel) = ISC_FALSE; break; case ISC_LOG_TOFILEDESC: FILE_NAME(channel) = NULL; FILE_STREAM(channel) = destination->file.stream; FILE_MAXSIZE(channel) = 0; FILE_VERSIONS(channel) = ISC_LOG_ROLLNEVER; break; case ISC_LOG_TONULL: /* Nothing. */ break; default: isc_mem_free(mctx, channel->name); isc_mem_put(mctx, channel, sizeof(*channel)); return (ISC_R_UNEXPECTED); } ISC_LIST_PREPEND(lcfg->channels, channel, link); /* * If default_stderr was redefined, make the default category * point to the new default_stderr. */ if (strcmp(name, "default_stderr") == 0) default_channel.channel = channel; return (ISC_R_SUCCESS); } isc_result_t isc_log_usechannel(isc_logconfig_t *lcfg, const char *name, const isc_logcategory_t *category, const isc_logmodule_t *module) { isc_log_t *lctx; isc_logchannel_t *channel; isc_result_t result = ISC_R_SUCCESS; unsigned int i; REQUIRE(VALID_CONFIG(lcfg)); REQUIRE(name != NULL); lctx = lcfg->lctx; REQUIRE(category == NULL || category->id < lctx->category_count); REQUIRE(module == NULL || module->id < lctx->module_count); for (channel = ISC_LIST_HEAD(lcfg->channels); channel != NULL; channel = ISC_LIST_NEXT(channel, link)) if (strcmp(name, channel->name) == 0) break; if (channel == NULL) return (ISC_R_NOTFOUND); if (category != NULL) result = assignchannel(lcfg, category->id, module, channel); else /* * Assign to all categories. Note that this includes * the default channel. */ for (i = 0; i < lctx->category_count; i++) { result = assignchannel(lcfg, i, module, channel); if (result != ISC_R_SUCCESS) break; } return (result); } void isc_log_write(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, const char *format, ...) { va_list args; /* * Contract checking is done in isc_log_doit(). */ va_start(args, format); isc_log_doit(lctx, category, module, level, ISC_FALSE, NULL, 0, 0, format, args); va_end(args); } void isc_log_vwrite(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, const char *format, va_list args) { /* * Contract checking is done in isc_log_doit(). */ isc_log_doit(lctx, category, module, level, ISC_FALSE, NULL, 0, 0, format, args); } void isc_log_write1(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, const char *format, ...) { va_list args; /* * Contract checking is done in isc_log_doit(). */ va_start(args, format); isc_log_doit(lctx, category, module, level, ISC_TRUE, NULL, 0, 0, format, args); va_end(args); } void isc_log_vwrite1(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, const char *format, va_list args) { /* * Contract checking is done in isc_log_doit(). */ isc_log_doit(lctx, category, module, level, ISC_TRUE, NULL, 0, 0, format, args); } void isc_log_iwrite(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, isc_msgcat_t *msgcat, int msgset, int msg, const char *format, ...) { va_list args; /* * Contract checking is done in isc_log_doit(). */ va_start(args, format); isc_log_doit(lctx, category, module, level, ISC_FALSE, msgcat, msgset, msg, format, args); va_end(args); } void isc_log_ivwrite(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, isc_msgcat_t *msgcat, int msgset, int msg, const char *format, va_list args) { /* * Contract checking is done in isc_log_doit(). */ isc_log_doit(lctx, category, module, level, ISC_FALSE, msgcat, msgset, msg, format, args); } void isc_log_iwrite1(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, isc_msgcat_t *msgcat, int msgset, int msg, const char *format, ...) { va_list args; /* * Contract checking is done in isc_log_doit(). */ va_start(args, format); isc_log_doit(lctx, category, module, level, ISC_TRUE, msgcat, msgset, msg, format, args); va_end(args); } void isc_log_ivwrite1(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, isc_msgcat_t *msgcat, int msgset, int msg, const char *format, va_list args) { /* * Contract checking is done in isc_log_doit(). */ isc_log_doit(lctx, category, module, level, ISC_TRUE, msgcat, msgset, msg, format, args); } void isc_log_setcontext(isc_log_t *lctx) { isc_lctx = lctx; } void isc_log_setdebuglevel(isc_log_t *lctx, unsigned int level) { isc_logchannel_t *channel; REQUIRE(VALID_CONTEXT(lctx)); LOCK(&lctx->lock); lctx->debug_level = level; /* * Close ISC_LOG_DEBUGONLY channels if level is zero. */ if (lctx->debug_level == 0) for (channel = ISC_LIST_HEAD(lctx->logconfig->channels); channel != NULL; channel = ISC_LIST_NEXT(channel, link)) if (channel->type == ISC_LOG_TOFILE && (channel->flags & ISC_LOG_DEBUGONLY) != 0 && FILE_STREAM(channel) != NULL) { (void)fclose(FILE_STREAM(channel)); FILE_STREAM(channel) = NULL; } UNLOCK(&lctx->lock); } unsigned int isc_log_getdebuglevel(isc_log_t *lctx) { REQUIRE(VALID_CONTEXT(lctx)); return (lctx->debug_level); } void isc_log_setduplicateinterval(isc_logconfig_t *lcfg, unsigned int interval) { REQUIRE(VALID_CONFIG(lcfg)); lcfg->duplicate_interval = interval; } unsigned int isc_log_getduplicateinterval(isc_logconfig_t *lcfg) { REQUIRE(VALID_CONTEXT(lcfg)); return (lcfg->duplicate_interval); } isc_result_t isc_log_settag(isc_logconfig_t *lcfg, const char *tag) { REQUIRE(VALID_CONFIG(lcfg)); if (tag != NULL && *tag != '\0') { if (lcfg->tag != NULL) isc_mem_free(lcfg->lctx->mctx, lcfg->tag); lcfg->tag = isc_mem_strdup(lcfg->lctx->mctx, tag); if (lcfg->tag == NULL) return (ISC_R_NOMEMORY); } else { if (lcfg->tag != NULL) isc_mem_free(lcfg->lctx->mctx, lcfg->tag); lcfg->tag = NULL; } return (ISC_R_SUCCESS); } char * isc_log_gettag(isc_logconfig_t *lcfg) { REQUIRE(VALID_CONFIG(lcfg)); return (lcfg->tag); } /* XXXDCL NT -- This interface will assuredly be changing. */ void isc_log_opensyslog(const char *tag, int options, int facility) { (void)openlog(tag, options, facility); } void isc_log_closefilelogs(isc_log_t *lctx) { isc_logchannel_t *channel; REQUIRE(VALID_CONTEXT(lctx)); LOCK(&lctx->lock); for (channel = ISC_LIST_HEAD(lctx->logconfig->channels); channel != NULL; channel = ISC_LIST_NEXT(channel, link)) if (channel->type == ISC_LOG_TOFILE && FILE_STREAM(channel) != NULL) { (void)fclose(FILE_STREAM(channel)); FILE_STREAM(channel) = NULL; } UNLOCK(&lctx->lock); } /**** **** Internal functions ****/ static isc_result_t assignchannel(isc_logconfig_t *lcfg, unsigned int category_id, const isc_logmodule_t *module, isc_logchannel_t *channel) { isc_logchannellist_t *new_item; isc_log_t *lctx; isc_result_t result; REQUIRE(VALID_CONFIG(lcfg)); lctx = lcfg->lctx; REQUIRE(category_id < lctx->category_count); REQUIRE(module == NULL || module->id < lctx->module_count); REQUIRE(channel != NULL); /* * Ensure lcfg->channellist_count == lctx->category_count. */ result = sync_channellist(lcfg); if (result != ISC_R_SUCCESS) return (result); new_item = isc_mem_get(lctx->mctx, sizeof(*new_item)); if (new_item == NULL) return (ISC_R_NOMEMORY); new_item->channel = channel; new_item->module = module; ISC_LIST_INITANDPREPEND(lcfg->channellists[category_id], new_item, link); /* * Remember the highest logging level set by any channel in the * logging config, so isc_log_doit() can quickly return if the * message is too high to be logged by any channel. */ if (channel->type != ISC_LOG_TONULL) { if (lcfg->highest_level < channel->level) lcfg->highest_level = channel->level; if (channel->level == ISC_LOG_DYNAMIC) lcfg->dynamic = ISC_TRUE; } return (ISC_R_SUCCESS); } /* * This would ideally be part of isc_log_registercategories(), except then * that function would have to return isc_result_t instead of void. */ static isc_result_t sync_channellist(isc_logconfig_t *lcfg) { unsigned int bytes; isc_log_t *lctx; void *lists; REQUIRE(VALID_CONFIG(lcfg)); lctx = lcfg->lctx; REQUIRE(lctx->category_count != 0); if (lctx->category_count == lcfg->channellist_count) return (ISC_R_SUCCESS); bytes = lctx->category_count * sizeof(ISC_LIST(isc_logchannellist_t)); lists = isc_mem_get(lctx->mctx, bytes); if (lists == NULL) return (ISC_R_NOMEMORY); memset(lists, 0, bytes); if (lcfg->channellist_count != 0) { bytes = lcfg->channellist_count * sizeof(ISC_LIST(isc_logchannellist_t)); memmove(lists, lcfg->channellists, bytes); isc_mem_put(lctx->mctx, lcfg->channellists, bytes); } lcfg->channellists = lists; lcfg->channellist_count = lctx->category_count; return (ISC_R_SUCCESS); } static isc_result_t greatest_version(isc_logchannel_t *channel, int *greatestp) { /* XXXDCL HIGHLY NT */ char *basename, *digit_end; const char *dirname; int version, greatest = -1; size_t basenamelen; isc_dir_t dir; isc_result_t result; char sep = '/'; #ifdef _WIN32 char *basename2; #endif REQUIRE(channel->type == ISC_LOG_TOFILE); /* * It is safe to DE_CONST the file.name because it was copied * with isc_mem_strdup in isc_log_createchannel. */ basename = strrchr(FILE_NAME(channel), sep); #ifdef _WIN32 basename2 = strrchr(FILE_NAME(channel), '\\'); if ((basename != NULL && basename2 != NULL && basename2 > basename) || (basename == NULL && basename2 != NULL)) { basename = basename2; sep = '\\'; } #endif if (basename != NULL) { *basename++ = '\0'; dirname = FILE_NAME(channel); } else { DE_CONST(FILE_NAME(channel), basename); dirname = "."; } basenamelen = strlen(basename); isc_dir_init(&dir); result = isc_dir_open(&dir, dirname); /* * Replace the file separator if it was taken out. */ if (basename != FILE_NAME(channel)) *(basename - 1) = sep; /* * Return if the directory open failed. */ if (result != ISC_R_SUCCESS) return (result); while (isc_dir_read(&dir) == ISC_R_SUCCESS) { if (dir.entry.length > basenamelen && strncmp(dir.entry.name, basename, basenamelen) == 0 && dir.entry.name[basenamelen] == '.') { version = strtol(&dir.entry.name[basenamelen + 1], &digit_end, 10); if (*digit_end == '\0' && version > greatest) greatest = version; } } isc_dir_close(&dir); *greatestp = ++greatest; return (ISC_R_SUCCESS); } static isc_result_t roll_log(isc_logchannel_t *channel) { int i, n, greatest; char current[PATH_MAX + 1]; char new[PATH_MAX + 1]; const char *path; isc_result_t result; /* * Do nothing (not even excess version trimming) if ISC_LOG_ROLLNEVER * is specified. Apparently complete external control over the log * files is desired. */ if (FILE_VERSIONS(channel) == ISC_LOG_ROLLNEVER) return (ISC_R_SUCCESS); path = FILE_NAME(channel); /* * Set greatest_version to the greatest existing version * (not the maximum requested version). This is 1 based even * though the file names are 0 based, so an oldest log of log.1 * is a greatest_version of 2. */ result = greatest_version(channel, &greatest); if (result != ISC_R_SUCCESS) return (result); /* * Now greatest should be set to the highest version number desired. * Since the highest number is one less than FILE_VERSIONS(channel) * when not doing infinite log rolling, greatest will need to be * decremented when it is equal to -- or greater than -- * FILE_VERSIONS(channel). When greatest is less than * FILE_VERSIONS(channel), it is already suitable for use as * the maximum version number. */ if (FILE_VERSIONS(channel) == ISC_LOG_ROLLINFINITE || FILE_VERSIONS(channel) > greatest) ; /* Do nothing. */ else /* * When greatest is >= FILE_VERSIONS(channel), it needs to * be reduced until it is FILE_VERSIONS(channel) - 1. * Remove any excess logs on the way to that value. */ while (--greatest >= FILE_VERSIONS(channel)) { n = snprintf(current, sizeof(current), "%s.%d", path, greatest); if (n >= (int)sizeof(current) || n < 0) result = ISC_R_NOSPACE; else result = isc_file_remove(current); if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) syslog(LOG_ERR, "unable to remove log file '%s.%d': %s", path, greatest, isc_result_totext(result)); } for (i = greatest; i > 0; i--) { result = ISC_R_SUCCESS; n = snprintf(current, sizeof(current), "%s.%d", path, i - 1); if (n >= (int)sizeof(current) || n < 0) result = ISC_R_NOSPACE; if (result == ISC_R_SUCCESS) { n = snprintf(new, sizeof(new), "%s.%d", path, i); if (n >= (int)sizeof(new) || n < 0) result = ISC_R_NOSPACE; } if (result == ISC_R_SUCCESS) result = isc_file_rename(current, new); if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) syslog(LOG_ERR, "unable to rename log file '%s.%d' to " "'%s.%d': %s", path, i - 1, path, i, isc_result_totext(result)); } if (FILE_VERSIONS(channel) != 0) { n = snprintf(new, sizeof(new), "%s.0", path); if (n >= (int)sizeof(new) || n < 0) result = ISC_R_NOSPACE; else result = isc_file_rename(path, new); if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) syslog(LOG_ERR, "unable to rename log file '%s' to '%s.0': %s", path, path, isc_result_totext(result)); } else { result = isc_file_remove(path); if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) syslog(LOG_ERR, "unable to remove log file '%s': %s", path, isc_result_totext(result)); } return (ISC_R_SUCCESS); } static isc_result_t isc_log_open(isc_logchannel_t *channel) { struct stat statbuf; isc_boolean_t regular_file; isc_boolean_t roll = ISC_FALSE; isc_result_t result = ISC_R_SUCCESS; const char *path; REQUIRE(channel->type == ISC_LOG_TOFILE); REQUIRE(FILE_STREAM(channel) == NULL); path = FILE_NAME(channel); REQUIRE(path != NULL && *path != '\0'); /* * Determine type of file; only regular files will be * version renamed, and only if the base file exists * and either has no size limit or has reached its size limit. */ if (stat(path, &statbuf) == 0) { regular_file = S_ISREG(statbuf.st_mode) ? ISC_TRUE : ISC_FALSE; /* XXXDCL if not regular_file complain? */ if ((FILE_MAXSIZE(channel) == 0 && FILE_VERSIONS(channel) != ISC_LOG_ROLLNEVER) || (FILE_MAXSIZE(channel) > 0 && statbuf.st_size >= FILE_MAXSIZE(channel))) roll = regular_file; } else if (errno == ENOENT) { regular_file = ISC_TRUE; POST(regular_file); } else result = ISC_R_INVALIDFILE; /* * Version control. */ if (result == ISC_R_SUCCESS && roll) { if (FILE_VERSIONS(channel) == ISC_LOG_ROLLNEVER) return (ISC_R_MAXSIZE); result = roll_log(channel); if (result != ISC_R_SUCCESS) { if ((channel->flags & ISC_LOG_OPENERR) == 0) { syslog(LOG_ERR, "isc_log_open: roll_log '%s' " "failed: %s", FILE_NAME(channel), isc_result_totext(result)); channel->flags |= ISC_LOG_OPENERR; } return (result); } } result = isc_stdio_open(path, "a", &FILE_STREAM(channel)); return (result); } isc_boolean_t isc_log_wouldlog(isc_log_t *lctx, int level) { /* * Try to avoid locking the mutex for messages which can't * possibly be logged to any channels -- primarily debugging * messages that the debug level is not high enough to print. * * If the level is (mathematically) less than or equal to the * highest_level, or if there is a dynamic channel and the level is * less than or equal to the debug level, the main loop must be * entered to see if the message should really be output. * * NOTE: this is UNLOCKED access to the logconfig. However, * the worst thing that can happen is that a bad decision is made * about returning without logging, and that's not a big concern, * because that's a risk anyway if the logconfig is being * dynamically changed. */ if (lctx == NULL || lctx->logconfig == NULL) return (ISC_FALSE); return (ISC_TF(level <= lctx->logconfig->highest_level || (lctx->logconfig->dynamic && level <= lctx->debug_level))); } static void isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category, isc_logmodule_t *module, int level, isc_boolean_t write_once, isc_msgcat_t *msgcat, int msgset, int msg, const char *format, va_list args) { int syslog_level; char time_string[64]; char level_string[24]; const char *iformat; struct stat statbuf; isc_boolean_t matched = ISC_FALSE; isc_boolean_t printtime, printtag, printcolon; isc_boolean_t printcategory, printmodule, printlevel; isc_logconfig_t *lcfg; isc_logchannel_t *channel; isc_logchannellist_t *category_channels; isc_result_t result; REQUIRE(lctx == NULL || VALID_CONTEXT(lctx)); REQUIRE(category != NULL); REQUIRE(module != NULL); REQUIRE(level != ISC_LOG_DYNAMIC); REQUIRE(format != NULL); /* * Programs can use libraries that use this logging code without * wanting to do any logging, thus the log context is allowed to * be non-existent. */ if (lctx == NULL) return; REQUIRE(category->id < lctx->category_count); REQUIRE(module->id < lctx->module_count); if (! isc_log_wouldlog(lctx, level)) return; if (msgcat != NULL) iformat = isc_msgcat_get(msgcat, msgset, msg, format); else iformat = format; time_string[0] = '\0'; level_string[0] = '\0'; LOCK(&lctx->lock); lctx->buffer[0] = '\0'; lcfg = lctx->logconfig; category_channels = ISC_LIST_HEAD(lcfg->channellists[category->id]); /* * XXXDCL add duplicate filtering? (To not write multiple times to * the same source via various channels). */ do { /* * If the channel list end was reached and a match was made, * everything is finished. */ if (category_channels == NULL && matched) break; if (category_channels == NULL && ! matched && category_channels != ISC_LIST_HEAD(lcfg->channellists[0])) /* * No category/module pair was explicitly configured. * Try the category named "default". */ category_channels = ISC_LIST_HEAD(lcfg->channellists[0]); if (category_channels == NULL && ! matched) /* * No matching module was explicitly configured * for the category named "default". Use the internal * default channel. */ category_channels = &default_channel; if (category_channels->module != NULL && category_channels->module != module) { category_channels = ISC_LIST_NEXT(category_channels, link); continue; } matched = ISC_TRUE; channel = category_channels->channel; category_channels = ISC_LIST_NEXT(category_channels, link); if (((channel->flags & ISC_LOG_DEBUGONLY) != 0) && lctx->debug_level == 0) continue; if (channel->level == ISC_LOG_DYNAMIC) { if (lctx->debug_level < level) continue; } else if (channel->level < level) continue; if ((channel->flags & ISC_LOG_PRINTTIME) != 0 && time_string[0] == '\0') { isc_time_t isctime; TIME_NOW(&isctime); isc_time_formattimestamp(&isctime, time_string, sizeof(time_string)); } if ((channel->flags & ISC_LOG_PRINTLEVEL) != 0 && level_string[0] == '\0') { if (level < ISC_LOG_CRITICAL) snprintf(level_string, sizeof(level_string), isc_msgcat_get(isc_msgcat, ISC_MSGSET_LOG, ISC_MSG_LEVEL, "level %d: "), level); else if (level > ISC_LOG_DYNAMIC) snprintf(level_string, sizeof(level_string), "%s %d: ", log_level_strings[0], level); else snprintf(level_string, sizeof(level_string), "%s: ", log_level_strings[-level]); } /* * Only format the message once. */ if (lctx->buffer[0] == '\0') { (void)vsnprintf(lctx->buffer, sizeof(lctx->buffer), iformat, args); /* * Check for duplicates. */ if (write_once) { isc_logmessage_t *message, *new; isc_time_t oldest; isc_interval_t interval; isc_interval_set(&interval, lcfg->duplicate_interval, 0); /* * 'oldest' is the age of the oldest messages * which fall within the duplicate_interval * range. */ TIME_NOW(&oldest); if (isc_time_subtract(&oldest, &interval, &oldest) != ISC_R_SUCCESS) /* * Can't effectively do the checking * without having a valid time. */ message = NULL; else message =ISC_LIST_HEAD(lctx->messages); while (message != NULL) { if (isc_time_compare(&message->time, &oldest) < 0) { /* * This message is older * than the duplicate_interval, * so it should be dropped from * the history. * * Setting the interval to be * to be longer will obviously * not cause the expired * message to spring back into * existence. */ new = ISC_LIST_NEXT(message, link); ISC_LIST_UNLINK(lctx->messages, message, link); isc_mem_put(lctx->mctx, message, sizeof(*message) + 1 + strlen(message->text)); message = new; continue; } /* * This message is in the duplicate * filtering interval ... */ if (strcmp(lctx->buffer, message->text) == 0) { /* * ... and it is a duplicate. * Unlock the mutex and * get the hell out of Dodge. */ UNLOCK(&lctx->lock); return; } message = ISC_LIST_NEXT(message, link); } /* * It wasn't in the duplicate interval, * so add it to the message list. */ new = isc_mem_get(lctx->mctx, sizeof(isc_logmessage_t) + strlen(lctx->buffer) + 1); if (new != NULL) { /* * Put the text immediately after * the struct. The strcpy is safe. */ new->text = (char *)(new + 1); strcpy(new->text, lctx->buffer); TIME_NOW(&new->time); ISC_LINK_INIT(new, link); ISC_LIST_APPEND(lctx->messages, new, link); } } } printtime = ISC_TF((channel->flags & ISC_LOG_PRINTTIME) != 0); printtag = ISC_TF((channel->flags & (ISC_LOG_PRINTTAG|ISC_LOG_PRINTPREFIX)) != 0 && lcfg->tag != NULL); printcolon = ISC_TF((channel->flags & ISC_LOG_PRINTTAG) != 0 && lcfg->tag != NULL); printcategory = ISC_TF((channel->flags & ISC_LOG_PRINTCATEGORY) != 0); printmodule = ISC_TF((channel->flags & ISC_LOG_PRINTMODULE) != 0); printlevel = ISC_TF((channel->flags & ISC_LOG_PRINTLEVEL) != 0); switch (channel->type) { case ISC_LOG_TOFILE: if (FILE_MAXREACHED(channel)) { /* * If the file can be rolled, OR * If the file no longer exists, OR * If the file is less than the maximum size, * (such as if it had been renamed and * a new one touched, or it was truncated * in place) * ... then close it to trigger reopening. */ if (FILE_VERSIONS(channel) != ISC_LOG_ROLLNEVER || (stat(FILE_NAME(channel), &statbuf) != 0 && errno == ENOENT) || statbuf.st_size < FILE_MAXSIZE(channel)) { (void)fclose(FILE_STREAM(channel)); FILE_STREAM(channel) = NULL; FILE_MAXREACHED(channel) = ISC_FALSE; } else /* * Eh, skip it. */ break; } if (FILE_STREAM(channel) == NULL) { result = isc_log_open(channel); if (result != ISC_R_SUCCESS && result != ISC_R_MAXSIZE && (channel->flags & ISC_LOG_OPENERR) == 0) { syslog(LOG_ERR, "isc_log_open '%s' failed: %s", FILE_NAME(channel), isc_result_totext(result)); channel->flags |= ISC_LOG_OPENERR; } if (result != ISC_R_SUCCESS) break; channel->flags &= ~ISC_LOG_OPENERR; } /* FALLTHROUGH */ case ISC_LOG_TOFILEDESC: fprintf(FILE_STREAM(channel), "%s%s%s%s%s%s%s%s%s%s\n", printtime ? time_string : "", printtime ? " " : "", printtag ? lcfg->tag : "", printcolon ? ": " : "", printcategory ? category->name : "", printcategory ? ": " : "", printmodule ? (module != NULL ? module->name : "no_module") : "", printmodule ? ": " : "", printlevel ? level_string : "", lctx->buffer); fflush(FILE_STREAM(channel)); /* * If the file now exceeds its maximum size * threshold, note it so that it will not be logged * to any more. */ if (FILE_MAXSIZE(channel) > 0) { INSIST(channel->type == ISC_LOG_TOFILE); /* XXXDCL NT fstat/fileno */ /* XXXDCL complain if fstat fails? */ if (fstat(fileno(FILE_STREAM(channel)), &statbuf) >= 0 && statbuf.st_size > FILE_MAXSIZE(channel)) FILE_MAXREACHED(channel) = ISC_TRUE; } break; case ISC_LOG_TOSYSLOG: if (level > 0) syslog_level = LOG_DEBUG; else if (level < ISC_LOG_CRITICAL) syslog_level = LOG_CRIT; else syslog_level = syslog_map[-level]; (void)syslog(FACILITY(channel) | syslog_level, "%s%s%s%s%s%s%s%s%s%s", printtime ? time_string : "", printtime ? " " : "", printtag ? lcfg->tag : "", printcolon ? ": " : "", printcategory ? category->name : "", printcategory ? ": " : "", printmodule ? (module != NULL ? module->name : "no_module") : "", printmodule ? ": " : "", printlevel ? level_string : "", lctx->buffer); break; case ISC_LOG_TONULL: break; } } while (1); UNLOCK(&lctx->lock); } bind9-9.10.3.dfsg.P4/lib/isc/ia64/0002755000470500017500000000000012672612753015472 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/ia64/Makefile.in0000644000470500017500000000166312664710322017533 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = include TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/ia64/include/0002755000470500017500000000000012664710322017105 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/ia64/include/Makefile.in0000644000470500017500000000165712664710322021161 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = isc TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/ia64/include/isc/0002755000470500017500000000000012664710322017663 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/ia64/include/isc/Makefile.in0000644000470500017500000000223012664710322021723 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ HEADERS = atomic.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \ done bind9-9.10.3.dfsg.P4/lib/isc/ia64/include/isc/atomic.h0000644000470500017500000000502712664710322021312 0ustar lamontlamont/* * Copyright (C) 2006, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: atomic.h,v 1.7 2009/06/24 02:22:50 marka Exp $ */ #ifndef ISC_ATOMIC_H #define ISC_ATOMIC_H 1 #include #include #ifdef ISC_PLATFORM_USEGCCASM /* * This routine atomically increments the value stored in 'p' by 'val', and * returns the previous value. * * Open issue: can 'fetchadd' make the code faster for some particular values * (e.g., 1 and -1)? */ static inline isc_int32_t #ifdef __GNUC__ __attribute__ ((unused)) #endif isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) { isc_int32_t prev, swapped; for (prev = *(volatile isc_int32_t *)p; ; prev = swapped) { swapped = prev + val; __asm__ volatile( "mov ar.ccv=%2;;" "cmpxchg4.acq %0=%4,%3,ar.ccv" : "=r" (swapped), "=m" (*p) : "r" (prev), "r" (swapped), "m" (*p) : "memory"); if (swapped == prev) break; } return (prev); } /* * This routine atomically stores the value 'val' in 'p'. */ static inline void #ifdef __GNUC__ __attribute__ ((unused)) #endif isc_atomic_store(isc_int32_t *p, isc_int32_t val) { __asm__ volatile( "st4.rel %0=%1" : "=m" (*p) : "r" (val) : "memory" ); } /* * This routine atomically replaces the value in 'p' with 'val', if the * original value is equal to 'cmpval'. The original value is returned in any * case. */ static inline isc_int32_t #ifdef __GNUC__ __attribute__ ((unused)) #endif isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) { isc_int32_t ret; __asm__ volatile( "mov ar.ccv=%2;;" "cmpxchg4.acq %0=%4,%3,ar.ccv" : "=r" (ret), "=m" (*p) : "r" (cmpval), "r" (val), "m" (*p) : "memory"); return (ret); } #else /* !ISC_PLATFORM_USEGCCASM */ #error "unsupported compiler. disable atomic ops by --disable-atomic" #endif #endif /* ISC_ATOMIC_H */ bind9-9.10.3.dfsg.P4/lib/isc/timer.c0000644000470500017500000007117312664710322016212 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007-2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef OPENSSL_LEAKS #include #endif /* See task.c about the following definition: */ #ifdef ISC_PLATFORM_USETHREADS #define USE_TIMER_THREAD #else #define USE_SHARED_MANAGER #endif /* ISC_PLATFORM_USETHREADS */ #ifndef USE_TIMER_THREAD #include "timer_p.h" #endif /* USE_TIMER_THREAD */ #ifdef ISC_TIMER_TRACE #define XTRACE(s) fprintf(stderr, "%s\n", (s)) #define XTRACEID(s, t) fprintf(stderr, "%s %p\n", (s), (t)) #define XTRACETIME(s, d) fprintf(stderr, "%s %u.%09u\n", (s), \ (d).seconds, (d).nanoseconds) #define XTRACETIME2(s, d, n) fprintf(stderr, "%s %u.%09u %u.%09u\n", (s), \ (d).seconds, (d).nanoseconds, (n).seconds, (n).nanoseconds) #define XTRACETIMER(s, t, d) fprintf(stderr, "%s %p %u.%09u\n", (s), (t), \ (d).seconds, (d).nanoseconds) #else #define XTRACE(s) #define XTRACEID(s, t) #define XTRACETIME(s, d) #define XTRACETIME2(s, d, n) #define XTRACETIMER(s, t, d) #endif /* ISC_TIMER_TRACE */ #define TIMER_MAGIC ISC_MAGIC('T', 'I', 'M', 'R') #define VALID_TIMER(t) ISC_MAGIC_VALID(t, TIMER_MAGIC) typedef struct isc__timer isc__timer_t; typedef struct isc__timermgr isc__timermgr_t; struct isc__timer { /*! Not locked. */ isc_timer_t common; isc__timermgr_t * manager; isc_mutex_t lock; /*! Locked by timer lock. */ unsigned int references; isc_time_t idle; /*! Locked by manager lock. */ isc_timertype_t type; isc_time_t expires; isc_interval_t interval; isc_task_t * task; isc_taskaction_t action; void * arg; unsigned int index; isc_time_t due; LINK(isc__timer_t) link; }; #define TIMER_MANAGER_MAGIC ISC_MAGIC('T', 'I', 'M', 'M') #define VALID_MANAGER(m) ISC_MAGIC_VALID(m, TIMER_MANAGER_MAGIC) struct isc__timermgr { /* Not locked. */ isc_timermgr_t common; isc_mem_t * mctx; isc_mutex_t lock; /* Locked by manager lock. */ isc_boolean_t done; LIST(isc__timer_t) timers; unsigned int nscheduled; isc_time_t due; #ifdef USE_TIMER_THREAD isc_condition_t wakeup; isc_thread_t thread; #endif /* USE_TIMER_THREAD */ #ifdef USE_SHARED_MANAGER unsigned int refs; #endif /* USE_SHARED_MANAGER */ isc_heap_t * heap; }; /*% * The following are intended for internal use (indicated by "isc__" * prefix) but are not declared as static, allowing direct access from * unit tests etc. */ isc_result_t isc__timer_create(isc_timermgr_t *manager, isc_timertype_t type, const isc_time_t *expires, const isc_interval_t *interval, isc_task_t *task, isc_taskaction_t action, void *arg, isc_timer_t **timerp); isc_result_t isc__timer_reset(isc_timer_t *timer, isc_timertype_t type, const isc_time_t *expires, const isc_interval_t *interval, isc_boolean_t purge); isc_timertype_t isc_timer_gettype(isc_timer_t *timer); isc_result_t isc__timer_touch(isc_timer_t *timer); void isc__timer_attach(isc_timer_t *timer0, isc_timer_t **timerp); void isc__timer_detach(isc_timer_t **timerp); isc_result_t isc__timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp); void isc_timermgr_poke(isc_timermgr_t *manager0); void isc__timermgr_destroy(isc_timermgr_t **managerp); static struct isc__timermethods { isc_timermethods_t methods; /*% * The following are defined just for avoiding unused static functions. */ void *gettype; } timermethods = { { isc__timer_attach, isc__timer_detach, isc__timer_reset, isc__timer_touch }, (void *)isc_timer_gettype }; static struct isc__timermgrmethods { isc_timermgrmethods_t methods; void *poke; /* see above */ } timermgrmethods = { { isc__timermgr_destroy, isc__timer_create }, (void *)isc_timermgr_poke }; #ifdef USE_SHARED_MANAGER /*! * If the manager is supposed to be shared, there can be only one. */ static isc__timermgr_t *timermgr = NULL; #endif /* USE_SHARED_MANAGER */ static inline isc_result_t schedule(isc__timer_t *timer, isc_time_t *now, isc_boolean_t signal_ok) { isc_result_t result; isc__timermgr_t *manager; isc_time_t due; int cmp; #ifdef USE_TIMER_THREAD isc_boolean_t timedwait; #endif /*! * Note: the caller must ensure locking. */ REQUIRE(timer->type != isc_timertype_inactive); #ifndef USE_TIMER_THREAD UNUSED(signal_ok); #endif /* USE_TIMER_THREAD */ manager = timer->manager; #ifdef USE_TIMER_THREAD /*! * If the manager was timed wait, we may need to signal the * manager to force a wakeup. */ timedwait = ISC_TF(manager->nscheduled > 0 && isc_time_seconds(&manager->due) != 0); #endif /* * Compute the new due time. */ if (timer->type != isc_timertype_once) { result = isc_time_add(now, &timer->interval, &due); if (result != ISC_R_SUCCESS) return (result); if (timer->type == isc_timertype_limited && isc_time_compare(&timer->expires, &due) < 0) due = timer->expires; } else { if (isc_time_isepoch(&timer->idle)) due = timer->expires; else if (isc_time_isepoch(&timer->expires)) due = timer->idle; else if (isc_time_compare(&timer->idle, &timer->expires) < 0) due = timer->idle; else due = timer->expires; } /* * Schedule the timer. */ if (timer->index > 0) { /* * Already scheduled. */ cmp = isc_time_compare(&due, &timer->due); timer->due = due; switch (cmp) { case -1: isc_heap_increased(manager->heap, timer->index); break; case 1: isc_heap_decreased(manager->heap, timer->index); break; case 0: /* Nothing to do. */ break; } } else { timer->due = due; result = isc_heap_insert(manager->heap, timer); if (result != ISC_R_SUCCESS) { INSIST(result == ISC_R_NOMEMORY); return (ISC_R_NOMEMORY); } manager->nscheduled++; } XTRACETIMER(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER, ISC_MSG_SCHEDULE, "schedule"), timer, due); /* * If this timer is at the head of the queue, we need to ensure * that we won't miss it if it has a more recent due time than * the current "next" timer. We do this either by waking up the * run thread, or explicitly setting the value in the manager. */ #ifdef USE_TIMER_THREAD /* * This is a temporary (probably) hack to fix a bug on tru64 5.1 * and 5.1a. Sometimes, pthread_cond_timedwait() doesn't actually * return when the time expires, so here, we check to see if * we're 15 seconds or more behind, and if we are, we signal * the dispatcher. This isn't such a bad idea as a general purpose * watchdog, so perhaps we should just leave it in here. */ if (signal_ok && timedwait) { isc_interval_t fifteen; isc_time_t then; isc_interval_set(&fifteen, 15, 0); result = isc_time_add(&manager->due, &fifteen, &then); if (result == ISC_R_SUCCESS && isc_time_compare(&then, now) < 0) { SIGNAL(&manager->wakeup); signal_ok = ISC_FALSE; isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_TIMER, ISC_LOG_WARNING, "*** POKED TIMER ***"); } } if (timer->index == 1 && signal_ok) { XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER, ISC_MSG_SIGNALSCHED, "signal (schedule)")); SIGNAL(&manager->wakeup); } #else /* USE_TIMER_THREAD */ if (timer->index == 1 && isc_time_compare(&timer->due, &manager->due) < 0) manager->due = timer->due; #endif /* USE_TIMER_THREAD */ return (ISC_R_SUCCESS); } static inline void deschedule(isc__timer_t *timer) { #ifdef USE_TIMER_THREAD isc_boolean_t need_wakeup = ISC_FALSE; #endif isc__timermgr_t *manager; /* * The caller must ensure locking. */ manager = timer->manager; if (timer->index > 0) { #ifdef USE_TIMER_THREAD if (timer->index == 1) need_wakeup = ISC_TRUE; #endif isc_heap_delete(manager->heap, timer->index); timer->index = 0; INSIST(manager->nscheduled > 0); manager->nscheduled--; #ifdef USE_TIMER_THREAD if (need_wakeup) { XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER, ISC_MSG_SIGNALDESCHED, "signal (deschedule)")); SIGNAL(&manager->wakeup); } #endif /* USE_TIMER_THREAD */ } } static void destroy(isc__timer_t *timer) { isc__timermgr_t *manager = timer->manager; /* * The caller must ensure it is safe to destroy the timer. */ LOCK(&manager->lock); (void)isc_task_purgerange(timer->task, timer, ISC_TIMEREVENT_FIRSTEVENT, ISC_TIMEREVENT_LASTEVENT, NULL); deschedule(timer); UNLINK(manager->timers, timer, link); UNLOCK(&manager->lock); isc_task_detach(&timer->task); DESTROYLOCK(&timer->lock); timer->common.impmagic = 0; timer->common.magic = 0; isc_mem_put(manager->mctx, timer, sizeof(*timer)); } isc_result_t isc__timer_create(isc_timermgr_t *manager0, isc_timertype_t type, const isc_time_t *expires, const isc_interval_t *interval, isc_task_t *task, isc_taskaction_t action, void *arg, isc_timer_t **timerp) { isc__timermgr_t *manager = (isc__timermgr_t *)manager0; isc__timer_t *timer; isc_result_t result; isc_time_t now; /* * Create a new 'type' timer managed by 'manager'. The timers * parameters are specified by 'expires' and 'interval'. Events * will be posted to 'task' and when dispatched 'action' will be * called with 'arg' as the arg value. The new timer is returned * in 'timerp'. */ REQUIRE(VALID_MANAGER(manager)); REQUIRE(task != NULL); REQUIRE(action != NULL); if (expires == NULL) expires = isc_time_epoch; if (interval == NULL) interval = isc_interval_zero; REQUIRE(type == isc_timertype_inactive || !(isc_time_isepoch(expires) && isc_interval_iszero(interval))); REQUIRE(timerp != NULL && *timerp == NULL); REQUIRE(type != isc_timertype_limited || !(isc_time_isepoch(expires) || isc_interval_iszero(interval))); /* * Get current time. */ if (type != isc_timertype_inactive) { TIME_NOW(&now); } else { /* * We don't have to do this, but it keeps the compiler from * complaining about "now" possibly being used without being * set, even though it will never actually happen. */ isc_time_settoepoch(&now); } timer = isc_mem_get(manager->mctx, sizeof(*timer)); if (timer == NULL) return (ISC_R_NOMEMORY); timer->manager = manager; timer->references = 1; if (type == isc_timertype_once && !isc_interval_iszero(interval)) { result = isc_time_add(&now, interval, &timer->idle); if (result != ISC_R_SUCCESS) { isc_mem_put(manager->mctx, timer, sizeof(*timer)); return (result); } } else isc_time_settoepoch(&timer->idle); timer->type = type; timer->expires = *expires; timer->interval = *interval; timer->task = NULL; isc_task_attach(task, &timer->task); timer->action = action; /* * Removing the const attribute from "arg" is the best of two * evils here. If the timer->arg member is made const, then * it affects a great many recipients of the timer event * which did not pass in an "arg" that was truly const. * Changing isc_timer_create() to not have "arg" prototyped as const, * though, can cause compilers warnings for calls that *do* * have a truly const arg. The caller will have to carefully * keep track of whether arg started as a true const. */ DE_CONST(arg, timer->arg); timer->index = 0; result = isc_mutex_init(&timer->lock); if (result != ISC_R_SUCCESS) { isc_task_detach(&timer->task); isc_mem_put(manager->mctx, timer, sizeof(*timer)); return (result); } ISC_LINK_INIT(timer, link); timer->common.impmagic = TIMER_MAGIC; timer->common.magic = ISCAPI_TIMER_MAGIC; timer->common.methods = (isc_timermethods_t *)&timermethods; LOCK(&manager->lock); /* * Note we don't have to lock the timer like we normally would because * there are no external references to it yet. */ if (type != isc_timertype_inactive) result = schedule(timer, &now, ISC_TRUE); else result = ISC_R_SUCCESS; if (result == ISC_R_SUCCESS) APPEND(manager->timers, timer, link); UNLOCK(&manager->lock); if (result != ISC_R_SUCCESS) { timer->common.impmagic = 0; timer->common.magic = 0; DESTROYLOCK(&timer->lock); isc_task_detach(&timer->task); isc_mem_put(manager->mctx, timer, sizeof(*timer)); return (result); } *timerp = (isc_timer_t *)timer; return (ISC_R_SUCCESS); } isc_result_t isc__timer_reset(isc_timer_t *timer0, isc_timertype_t type, const isc_time_t *expires, const isc_interval_t *interval, isc_boolean_t purge) { isc__timer_t *timer = (isc__timer_t *)timer0; isc_time_t now; isc__timermgr_t *manager; isc_result_t result; /* * Change the timer's type, expires, and interval values to the given * values. If 'purge' is ISC_TRUE, any pending events from this timer * are purged from its task's event queue. */ REQUIRE(VALID_TIMER(timer)); manager = timer->manager; REQUIRE(VALID_MANAGER(manager)); if (expires == NULL) expires = isc_time_epoch; if (interval == NULL) interval = isc_interval_zero; REQUIRE(type == isc_timertype_inactive || !(isc_time_isepoch(expires) && isc_interval_iszero(interval))); REQUIRE(type != isc_timertype_limited || !(isc_time_isepoch(expires) || isc_interval_iszero(interval))); /* * Get current time. */ if (type != isc_timertype_inactive) { TIME_NOW(&now); } else { /* * We don't have to do this, but it keeps the compiler from * complaining about "now" possibly being used without being * set, even though it will never actually happen. */ isc_time_settoepoch(&now); } LOCK(&manager->lock); LOCK(&timer->lock); if (purge) (void)isc_task_purgerange(timer->task, timer, ISC_TIMEREVENT_FIRSTEVENT, ISC_TIMEREVENT_LASTEVENT, NULL); timer->type = type; timer->expires = *expires; timer->interval = *interval; if (type == isc_timertype_once && !isc_interval_iszero(interval)) { result = isc_time_add(&now, interval, &timer->idle); } else { isc_time_settoepoch(&timer->idle); result = ISC_R_SUCCESS; } if (result == ISC_R_SUCCESS) { if (type == isc_timertype_inactive) { deschedule(timer); result = ISC_R_SUCCESS; } else result = schedule(timer, &now, ISC_TRUE); } UNLOCK(&timer->lock); UNLOCK(&manager->lock); return (result); } isc_timertype_t isc_timer_gettype(isc_timer_t *timer0) { isc__timer_t *timer = (isc__timer_t *)timer0; isc_timertype_t t; REQUIRE(VALID_TIMER(timer)); LOCK(&timer->lock); t = timer->type; UNLOCK(&timer->lock); return (t); } isc_result_t isc__timer_touch(isc_timer_t *timer0) { isc__timer_t *timer = (isc__timer_t *)timer0; isc_result_t result; isc_time_t now; /* * Set the last-touched time of 'timer' to the current time. */ REQUIRE(VALID_TIMER(timer)); LOCK(&timer->lock); /* * We'd like to * * REQUIRE(timer->type == isc_timertype_once); * * but we cannot without locking the manager lock too, which we * don't want to do. */ TIME_NOW(&now); result = isc_time_add(&now, &timer->interval, &timer->idle); UNLOCK(&timer->lock); return (result); } void isc__timer_attach(isc_timer_t *timer0, isc_timer_t **timerp) { isc__timer_t *timer = (isc__timer_t *)timer0; /* * Attach *timerp to timer. */ REQUIRE(VALID_TIMER(timer)); REQUIRE(timerp != NULL && *timerp == NULL); LOCK(&timer->lock); timer->references++; UNLOCK(&timer->lock); *timerp = (isc_timer_t *)timer; } void isc__timer_detach(isc_timer_t **timerp) { isc__timer_t *timer; isc_boolean_t free_timer = ISC_FALSE; /* * Detach *timerp from its timer. */ REQUIRE(timerp != NULL); timer = (isc__timer_t *)*timerp; REQUIRE(VALID_TIMER(timer)); LOCK(&timer->lock); REQUIRE(timer->references > 0); timer->references--; if (timer->references == 0) free_timer = ISC_TRUE; UNLOCK(&timer->lock); if (free_timer) destroy(timer); *timerp = NULL; } static void dispatch(isc__timermgr_t *manager, isc_time_t *now) { isc_boolean_t done = ISC_FALSE, post_event, need_schedule; isc_timerevent_t *event; isc_eventtype_t type = 0; isc__timer_t *timer; isc_result_t result; isc_boolean_t idle; /*! * The caller must be holding the manager lock. */ while (manager->nscheduled > 0 && !done) { timer = isc_heap_element(manager->heap, 1); INSIST(timer != NULL && timer->type != isc_timertype_inactive); if (isc_time_compare(now, &timer->due) >= 0) { if (timer->type == isc_timertype_ticker) { type = ISC_TIMEREVENT_TICK; post_event = ISC_TRUE; need_schedule = ISC_TRUE; } else if (timer->type == isc_timertype_limited) { int cmp; cmp = isc_time_compare(now, &timer->expires); if (cmp >= 0) { type = ISC_TIMEREVENT_LIFE; post_event = ISC_TRUE; need_schedule = ISC_FALSE; } else { type = ISC_TIMEREVENT_TICK; post_event = ISC_TRUE; need_schedule = ISC_TRUE; } } else if (!isc_time_isepoch(&timer->expires) && isc_time_compare(now, &timer->expires) >= 0) { type = ISC_TIMEREVENT_LIFE; post_event = ISC_TRUE; need_schedule = ISC_FALSE; } else { idle = ISC_FALSE; LOCK(&timer->lock); if (!isc_time_isepoch(&timer->idle) && isc_time_compare(now, &timer->idle) >= 0) { idle = ISC_TRUE; } UNLOCK(&timer->lock); if (idle) { type = ISC_TIMEREVENT_IDLE; post_event = ISC_TRUE; need_schedule = ISC_FALSE; } else { /* * Idle timer has been touched; * reschedule. */ XTRACEID(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER, ISC_MSG_IDLERESCHED, "idle reschedule"), timer); post_event = ISC_FALSE; need_schedule = ISC_TRUE; } } if (post_event) { XTRACEID(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER, ISC_MSG_POSTING, "posting"), timer); /* * XXX We could preallocate this event. */ event = (isc_timerevent_t *)isc_event_allocate(manager->mctx, timer, type, timer->action, timer->arg, sizeof(*event)); if (event != NULL) { event->due = timer->due; isc_task_send(timer->task, ISC_EVENT_PTR(&event)); } else UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER, ISC_MSG_EVENTNOTALLOC, "couldn't " "allocate event")); } timer->index = 0; isc_heap_delete(manager->heap, 1); manager->nscheduled--; if (need_schedule) { result = schedule(timer, now, ISC_FALSE); if (result != ISC_R_SUCCESS) UNEXPECTED_ERROR(__FILE__, __LINE__, "%s: %u", isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER, ISC_MSG_SCHEDFAIL, "couldn't schedule " "timer"), result); } } else { manager->due = timer->due; done = ISC_TRUE; } } } #ifdef USE_TIMER_THREAD static isc_threadresult_t #ifdef _WIN32 /* XXXDCL */ WINAPI #endif run(void *uap) { isc__timermgr_t *manager = uap; isc_time_t now; isc_result_t result; LOCK(&manager->lock); while (!manager->done) { TIME_NOW(&now); XTRACETIME(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_RUNNING, "running"), now); dispatch(manager, &now); if (manager->nscheduled > 0) { XTRACETIME2(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_WAITUNTIL, "waituntil"), manager->due, now); result = WAITUNTIL(&manager->wakeup, &manager->lock, &manager->due); INSIST(result == ISC_R_SUCCESS || result == ISC_R_TIMEDOUT); } else { XTRACETIME(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_WAIT, "wait"), now); WAIT(&manager->wakeup, &manager->lock); } XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER, ISC_MSG_WAKEUP, "wakeup")); } UNLOCK(&manager->lock); #ifdef OPENSSL_LEAKS ERR_remove_state(0); #endif return ((isc_threadresult_t)0); } #endif /* USE_TIMER_THREAD */ static isc_boolean_t sooner(void *v1, void *v2) { isc__timer_t *t1, *t2; t1 = v1; t2 = v2; REQUIRE(VALID_TIMER(t1)); REQUIRE(VALID_TIMER(t2)); if (isc_time_compare(&t1->due, &t2->due) < 0) return (ISC_TRUE); return (ISC_FALSE); } static void set_index(void *what, unsigned int index) { isc__timer_t *timer; timer = what; REQUIRE(VALID_TIMER(timer)); timer->index = index; } isc_result_t isc__timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) { isc__timermgr_t *manager; isc_result_t result; /* * Create a timer manager. */ REQUIRE(managerp != NULL && *managerp == NULL); #ifdef USE_SHARED_MANAGER if (timermgr != NULL) { timermgr->refs++; *managerp = (isc_timermgr_t *)timermgr; return (ISC_R_SUCCESS); } #endif /* USE_SHARED_MANAGER */ manager = isc_mem_get(mctx, sizeof(*manager)); if (manager == NULL) return (ISC_R_NOMEMORY); manager->common.impmagic = TIMER_MANAGER_MAGIC; manager->common.magic = ISCAPI_TIMERMGR_MAGIC; manager->common.methods = (isc_timermgrmethods_t *)&timermgrmethods; manager->mctx = NULL; manager->done = ISC_FALSE; INIT_LIST(manager->timers); manager->nscheduled = 0; isc_time_settoepoch(&manager->due); manager->heap = NULL; result = isc_heap_create(mctx, sooner, set_index, 0, &manager->heap); if (result != ISC_R_SUCCESS) { INSIST(result == ISC_R_NOMEMORY); isc_mem_put(mctx, manager, sizeof(*manager)); return (ISC_R_NOMEMORY); } result = isc_mutex_init(&manager->lock); if (result != ISC_R_SUCCESS) { isc_heap_destroy(&manager->heap); isc_mem_put(mctx, manager, sizeof(*manager)); return (result); } isc_mem_attach(mctx, &manager->mctx); #ifdef USE_TIMER_THREAD if (isc_condition_init(&manager->wakeup) != ISC_R_SUCCESS) { isc_mem_detach(&manager->mctx); DESTROYLOCK(&manager->lock); isc_heap_destroy(&manager->heap); isc_mem_put(mctx, manager, sizeof(*manager)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_condition_init() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); return (ISC_R_UNEXPECTED); } if (isc_thread_create(run, manager, &manager->thread) != ISC_R_SUCCESS) { isc_mem_detach(&manager->mctx); (void)isc_condition_destroy(&manager->wakeup); DESTROYLOCK(&manager->lock); isc_heap_destroy(&manager->heap); isc_mem_put(mctx, manager, sizeof(*manager)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_thread_create() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); return (ISC_R_UNEXPECTED); } #endif #ifdef USE_SHARED_MANAGER manager->refs = 1; timermgr = manager; #endif /* USE_SHARED_MANAGER */ *managerp = (isc_timermgr_t *)manager; return (ISC_R_SUCCESS); } void isc_timermgr_poke(isc_timermgr_t *manager0) { #ifdef USE_TIMER_THREAD isc__timermgr_t *manager = (isc__timermgr_t *)manager0; REQUIRE(VALID_MANAGER(manager)); SIGNAL(&manager->wakeup); #else UNUSED(manager0); #endif } void isc__timermgr_destroy(isc_timermgr_t **managerp) { isc__timermgr_t *manager; isc_mem_t *mctx; /* * Destroy a timer manager. */ REQUIRE(managerp != NULL); manager = (isc__timermgr_t *)*managerp; REQUIRE(VALID_MANAGER(manager)); LOCK(&manager->lock); #ifdef USE_SHARED_MANAGER manager->refs--; if (manager->refs > 0) { UNLOCK(&manager->lock); *managerp = NULL; return; } timermgr = NULL; #endif /* USE_SHARED_MANAGER */ #ifndef USE_TIMER_THREAD isc__timermgr_dispatch((isc_timermgr_t *)manager); #endif REQUIRE(EMPTY(manager->timers)); manager->done = ISC_TRUE; #ifdef USE_TIMER_THREAD XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER, ISC_MSG_SIGNALDESTROY, "signal (destroy)")); SIGNAL(&manager->wakeup); #endif /* USE_TIMER_THREAD */ UNLOCK(&manager->lock); #ifdef USE_TIMER_THREAD /* * Wait for thread to exit. */ if (isc_thread_join(manager->thread, NULL) != ISC_R_SUCCESS) UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_thread_join() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); #endif /* USE_TIMER_THREAD */ /* * Clean up. */ #ifdef USE_TIMER_THREAD (void)isc_condition_destroy(&manager->wakeup); #endif /* USE_TIMER_THREAD */ DESTROYLOCK(&manager->lock); isc_heap_destroy(&manager->heap); manager->common.impmagic = 0; manager->common.magic = 0; mctx = manager->mctx; isc_mem_put(mctx, manager, sizeof(*manager)); isc_mem_detach(&mctx); *managerp = NULL; #ifdef USE_SHARED_MANAGER timermgr = NULL; #endif } #ifndef USE_TIMER_THREAD isc_result_t isc__timermgr_nextevent(isc_timermgr_t *manager0, isc_time_t *when) { isc__timermgr_t *manager = (isc__timermgr_t *)manager0; #ifdef USE_SHARED_MANAGER if (manager == NULL) manager = timermgr; #endif if (manager == NULL || manager->nscheduled == 0) return (ISC_R_NOTFOUND); *when = manager->due; return (ISC_R_SUCCESS); } void isc__timermgr_dispatch(isc_timermgr_t *manager0) { isc__timermgr_t *manager = (isc__timermgr_t *)manager0; isc_time_t now; #ifdef USE_SHARED_MANAGER if (manager == NULL) manager = timermgr; #endif if (manager == NULL) return; TIME_NOW(&now); dispatch(manager, &now); } #endif /* USE_TIMER_THREAD */ isc_result_t isc__timer_register(void) { return (isc_timer_register(isc__timermgr_create)); } static isc_mutex_t createlock; static isc_once_t once = ISC_ONCE_INIT; static isc_timermgrcreatefunc_t timermgr_createfunc = NULL; static void initialize(void) { RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS); } isc_result_t isc_timer_register(isc_timermgrcreatefunc_t createfunc) { isc_result_t result = ISC_R_SUCCESS; RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); LOCK(&createlock); if (timermgr_createfunc == NULL) timermgr_createfunc = createfunc; else result = ISC_R_EXISTS; UNLOCK(&createlock); return (result); } isc_result_t isc_timermgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx, isc_timermgr_t **managerp) { isc_result_t result; LOCK(&createlock); REQUIRE(timermgr_createfunc != NULL); result = (*timermgr_createfunc)(mctx, managerp); UNLOCK(&createlock); if (result == ISC_R_SUCCESS) isc_appctx_settimermgr(actx, *managerp); return (result); } isc_result_t isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) { isc_result_t result; if (isc_bind9) return (isc__timermgr_create(mctx, managerp)); LOCK(&createlock); REQUIRE(timermgr_createfunc != NULL); result = (*timermgr_createfunc)(mctx, managerp); UNLOCK(&createlock); return (result); } void isc_timermgr_destroy(isc_timermgr_t **managerp) { REQUIRE(*managerp != NULL && ISCAPI_TIMERMGR_VALID(*managerp)); if (isc_bind9) isc__timermgr_destroy(managerp); else (*managerp)->methods->destroy(managerp); ENSURE(*managerp == NULL); } isc_result_t isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type, const isc_time_t *expires, const isc_interval_t *interval, isc_task_t *task, isc_taskaction_t action, void *arg, isc_timer_t **timerp) { REQUIRE(ISCAPI_TIMERMGR_VALID(manager)); if (isc_bind9) return (isc__timer_create(manager, type, expires, interval, task, action, arg, timerp)); return (manager->methods->timercreate(manager, type, expires, interval, task, action, arg, timerp)); } void isc_timer_attach(isc_timer_t *timer, isc_timer_t **timerp) { REQUIRE(ISCAPI_TIMER_VALID(timer)); REQUIRE(timerp != NULL && *timerp == NULL); if (isc_bind9) isc__timer_attach(timer, timerp); else timer->methods->attach(timer, timerp); ENSURE(*timerp == timer); } void isc_timer_detach(isc_timer_t **timerp) { REQUIRE(timerp != NULL && ISCAPI_TIMER_VALID(*timerp)); if (isc_bind9) isc__timer_detach(timerp); else (*timerp)->methods->detach(timerp); ENSURE(*timerp == NULL); } isc_result_t isc_timer_reset(isc_timer_t *timer, isc_timertype_t type, const isc_time_t *expires, const isc_interval_t *interval, isc_boolean_t purge) { REQUIRE(ISCAPI_TIMER_VALID(timer)); if (isc_bind9) return (isc__timer_reset(timer, type, expires, interval, purge)); return (timer->methods->reset(timer, type, expires, interval, purge)); } isc_result_t isc_timer_touch(isc_timer_t *timer) { REQUIRE(ISCAPI_TIMER_VALID(timer)); if (isc_bind9) return (isc__timer_touch(timer)); return (timer->methods->touch(timer)); } bind9-9.10.3.dfsg.P4/lib/isc/parseint.c0000644000470500017500000000445012664710322016711 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: parseint.c,v 1.8 2007/06/19 23:47:17 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include isc_result_t isc_parse_uint32(isc_uint32_t *uip, const char *string, int base) { unsigned long n; isc_uint32_t r; char *e; if (! isalnum((unsigned char)(string[0]))) return (ISC_R_BADNUMBER); errno = 0; n = strtoul(string, &e, base); if (*e != '\0') return (ISC_R_BADNUMBER); /* * Where long is 64 bits we need to convert to 32 bits then test for * equality. This is a no-op on 32 bit machines and a good compiler * will optimise it away. */ r = (isc_uint32_t)n; if ((n == ULONG_MAX && errno == ERANGE) || (n != (unsigned long)r)) return (ISC_R_RANGE); *uip = r; return (ISC_R_SUCCESS); } isc_result_t isc_parse_uint16(isc_uint16_t *uip, const char *string, int base) { isc_uint32_t val; isc_result_t result; result = isc_parse_uint32(&val, string, base); if (result != ISC_R_SUCCESS) return (result); if (val > 0xFFFF) return (ISC_R_RANGE); *uip = (isc_uint16_t) val; return (ISC_R_SUCCESS); } isc_result_t isc_parse_uint8(isc_uint8_t *uip, const char *string, int base) { isc_uint32_t val; isc_result_t result; result = isc_parse_uint32(&val, string, base); if (result != ISC_R_SUCCESS) return (result); if (val > 0xFF) return (ISC_R_RANGE); *uip = (isc_uint8_t) val; return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/isc/commandline.c0000644000470500017500000001522412664710322017353 0ustar lamontlamont/* * Portions Copyright (C) 2004, 2005, 2007, 2008, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. 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. Neither the name of the University 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 REGENTS 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. */ /* $Id: commandline.c,v 1.22 2008/09/25 04:02:39 tbox Exp $ */ /*! \file * This file was adapted from the NetBSD project's source tree, RCS ID: * NetBSD: getopt.c,v 1.15 1999/09/20 04:39:37 lukem Exp * * The primary change has been to rename items to the ISC namespace * and format in the ISC coding style. */ /* * \author Principal Authors: Computer Systems Research Group at UC Berkeley * \author Principal ISC caretaker: DCL */ #include #include #include #include #include #include #include /*% Index into parent argv vector. */ LIBISC_EXTERNAL_DATA int isc_commandline_index = 1; /*% Character checked for validity. */ LIBISC_EXTERNAL_DATA int isc_commandline_option; /*% Argument associated with option. */ LIBISC_EXTERNAL_DATA char *isc_commandline_argument; /*% For printing error messages. */ LIBISC_EXTERNAL_DATA char *isc_commandline_progname; /*% Print error messages. */ LIBISC_EXTERNAL_DATA isc_boolean_t isc_commandline_errprint = ISC_TRUE; /*% Reset processing. */ LIBISC_EXTERNAL_DATA isc_boolean_t isc_commandline_reset = ISC_TRUE; static char endopt = '\0'; #define BADOPT '?' #define BADARG ':' #define ENDOPT &endopt /*! * getopt -- * Parse argc/argv argument vector. */ int isc_commandline_parse(int argc, char * const *argv, const char *options) { static char *place = ENDOPT; char *option; /* Index into *options of option. */ REQUIRE(argc >= 0 && argv != NULL && options != NULL); /* * Update scanning pointer, either because a reset was requested or * the previous argv was finished. */ if (isc_commandline_reset || *place == '\0') { if (isc_commandline_reset) { isc_commandline_index = 1; isc_commandline_reset = ISC_FALSE; } if (isc_commandline_progname == NULL) isc_commandline_progname = argv[0]; if (isc_commandline_index >= argc || *(place = argv[isc_commandline_index]) != '-') { /* * Index out of range or points to non-option. */ place = ENDOPT; return (-1); } if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { /* * Found '--' to signal end of options. Advance * index to next argv, the first non-option. */ isc_commandline_index++; place = ENDOPT; return (-1); } } isc_commandline_option = *place++; option = strchr(options, isc_commandline_option); /* * Ensure valid option has been passed as specified by options string. * '-:' is never a valid command line option because it could not * distinguish ':' from the argument specifier in the options string. */ if (isc_commandline_option == ':' || option == NULL) { if (*place == '\0') isc_commandline_index++; if (isc_commandline_errprint && *options != ':') fprintf(stderr, "%s: %s -- %c\n", isc_commandline_progname, isc_msgcat_get(isc_msgcat, ISC_MSGSET_COMMANDLINE, ISC_MSG_ILLEGALOPT, "illegal option"), isc_commandline_option); return (BADOPT); } if (*++option != ':') { /* * Option does not take an argument. */ isc_commandline_argument = NULL; /* * Skip to next argv if at the end of the current argv. */ if (*place == '\0') ++isc_commandline_index; } else { /* * Option needs an argument. */ if (*place != '\0') /* * Option is in this argv, -D1 style. */ isc_commandline_argument = place; else if (argc > ++isc_commandline_index) /* * Option is next argv, -D 1 style. */ isc_commandline_argument = argv[isc_commandline_index]; else { /* * Argument needed, but no more argv. */ place = ENDOPT; /* * Silent failure with "missing argument" return * when ':' starts options string, per historical spec. */ if (*options == ':') return (BADARG); if (isc_commandline_errprint) fprintf(stderr, "%s: %s -- %c\n", isc_commandline_progname, isc_msgcat_get(isc_msgcat, ISC_MSGSET_COMMANDLINE, ISC_MSG_OPTNEEDARG, "option requires " "an argument"), isc_commandline_option); return (BADOPT); } place = ENDOPT; /* * Point to argv that follows argument. */ isc_commandline_index++; } return (isc_commandline_option); } bind9-9.10.3.dfsg.P4/lib/isc/noatomic/0002755000470500017500000000000012672612753016540 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/noatomic/Makefile.in0000644000470500017500000000166312664710322020601 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = include TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/noatomic/include/0002755000470500017500000000000012664710322020153 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/noatomic/include/Makefile.in0000644000470500017500000000165712664710322022227 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = isc TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/noatomic/include/isc/0002755000470500017500000000000012664710322020731 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/noatomic/include/isc/Makefile.in0000644000470500017500000000223012664710322022771 0ustar lamontlamont# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2007/09/14 04:09:59 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ HEADERS = atomic.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \ done bind9-9.10.3.dfsg.P4/lib/isc/noatomic/include/isc/atomic.h0000644000470500017500000000170512664710322022357 0ustar lamontlamont/* * Copyright (C) 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: atomic.h,v 1.4 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_ATOMIC_H #define ISC_ATOMIC_H 1 /* This file is inherently empty. */ #endif /* ISC_ATOMIC_H */ bind9-9.10.3.dfsg.P4/lib/isc/hex.c0000644000470500017500000001146312664710322015652 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2008, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: hex.c,v 1.20 2008/09/25 04:02:39 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #define RETERR(x) do { \ isc_result_t _r = (x); \ if (_r != ISC_R_SUCCESS) \ return (_r); \ } while (0) /* * BEW: These static functions are copied from lib/dns/rdata.c. */ static isc_result_t str_totext(const char *source, isc_buffer_t *target); static isc_result_t mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length); static const char hex[] = "0123456789ABCDEF"; isc_result_t isc_hex_totext(isc_region_t *source, int wordlength, const char *wordbreak, isc_buffer_t *target) { char buf[3]; unsigned int loops = 0; if (wordlength < 2) wordlength = 2; memset(buf, 0, sizeof(buf)); while (source->length > 0) { buf[0] = hex[(source->base[0] >> 4) & 0xf]; buf[1] = hex[(source->base[0]) & 0xf]; RETERR(str_totext(buf, target)); isc_region_consume(source, 1); loops++; if (source->length != 0 && (int)((loops + 1) * 2) >= wordlength) { loops = 0; RETERR(str_totext(wordbreak, target)); } } return (ISC_R_SUCCESS); } /*% * State of a hex decoding process in progress. */ typedef struct { int length; /*%< Desired length of binary data or -1 */ isc_buffer_t *target; /*%< Buffer for resulting binary data */ int digits; /*%< Number of buffered hex digits */ int val[2]; } hex_decode_ctx_t; static inline void hex_decode_init(hex_decode_ctx_t *ctx, int length, isc_buffer_t *target) { ctx->digits = 0; ctx->length = length; ctx->target = target; } static inline isc_result_t hex_decode_char(hex_decode_ctx_t *ctx, int c) { char *s; if ((s = strchr(hex, toupper(c))) == NULL) return (ISC_R_BADHEX); ctx->val[ctx->digits++] = (int)(s - hex); if (ctx->digits == 2) { unsigned char num; num = (ctx->val[0] << 4) + (ctx->val[1]); RETERR(mem_tobuffer(ctx->target, &num, 1)); if (ctx->length >= 0) { if (ctx->length == 0) return (ISC_R_BADHEX); else ctx->length -= 1; } ctx->digits = 0; } return (ISC_R_SUCCESS); } static inline isc_result_t hex_decode_finish(hex_decode_ctx_t *ctx) { if (ctx->length > 0) return (ISC_R_UNEXPECTEDEND); if (ctx->digits != 0) return (ISC_R_BADHEX); return (ISC_R_SUCCESS); } isc_result_t isc_hex_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) { hex_decode_ctx_t ctx; isc_textregion_t *tr; isc_token_t token; isc_boolean_t eol; hex_decode_init(&ctx, length, target); while (ctx.length != 0) { unsigned int i; if (length > 0) eol = ISC_FALSE; else eol = ISC_TRUE; RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, eol)); if (token.type != isc_tokentype_string) break; tr = &token.value.as_textregion; for (i = 0; i < tr->length; i++) RETERR(hex_decode_char(&ctx, tr->base[i])); } if (ctx.length < 0) isc_lex_ungettoken(lexer, &token); RETERR(hex_decode_finish(&ctx)); return (ISC_R_SUCCESS); } isc_result_t isc_hex_decodestring(const char *cstr, isc_buffer_t *target) { hex_decode_ctx_t ctx; hex_decode_init(&ctx, -1, target); for (;;) { int c = *cstr++; if (c == '\0') break; if (c == ' ' || c == '\t' || c == '\n' || c== '\r') continue; RETERR(hex_decode_char(&ctx, c)); } RETERR(hex_decode_finish(&ctx)); return (ISC_R_SUCCESS); } static isc_result_t str_totext(const char *source, isc_buffer_t *target) { unsigned int l; isc_region_t region; isc_buffer_availableregion(target, ®ion); l = strlen(source); if (l > region.length) return (ISC_R_NOSPACE); memmove(region.base, source, l); isc_buffer_add(target, l); return (ISC_R_SUCCESS); } static isc_result_t mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) { isc_region_t tr; isc_buffer_availableregion(target, &tr); if (length > tr.length) return (ISC_R_NOSPACE); memmove(tr.base, base, length); isc_buffer_add(target, length); return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/isc/fsaccess.c0000644000470500017500000000532112664710322016654 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: fsaccess.c,v 1.10 2007/06/19 23:47:17 tbox Exp $ */ /*! \file * \brief * This file contains the OS-independent functionality of the API. */ #include #include #include /*! * Shorthand. Maybe ISC__FSACCESS_PERMISSIONBITS should not even be in * . Could check consistency with sizeof(isc_fsaccess_t) * and the number of bits in each function. */ #define STEP (ISC__FSACCESS_PERMISSIONBITS) #define GROUP (STEP) #define OTHER (STEP * 2) void isc_fsaccess_add(int trustee, int permission, isc_fsaccess_t *access) { REQUIRE(trustee <= 0x7); REQUIRE(permission <= 0xFF); if ((trustee & ISC_FSACCESS_OWNER) != 0) *access |= permission; if ((trustee & ISC_FSACCESS_GROUP) != 0) *access |= (permission << GROUP); if ((trustee & ISC_FSACCESS_OTHER) != 0) *access |= (permission << OTHER); } void isc_fsaccess_remove(int trustee, int permission, isc_fsaccess_t *access) { REQUIRE(trustee <= 0x7); REQUIRE(permission <= 0xFF); if ((trustee & ISC_FSACCESS_OWNER) != 0) *access &= ~permission; if ((trustee & ISC_FSACCESS_GROUP) != 0) *access &= ~(permission << GROUP); if ((trustee & ISC_FSACCESS_OTHER) != 0) *access &= ~(permission << OTHER); } static isc_result_t check_bad_bits(isc_fsaccess_t access, isc_boolean_t is_dir) { isc_fsaccess_t bits; /* * Check for disallowed user bits. */ if (is_dir) bits = ISC_FSACCESS_READ | ISC_FSACCESS_WRITE | ISC_FSACCESS_EXECUTE; else bits = ISC_FSACCESS_CREATECHILD | ISC_FSACCESS_ACCESSCHILD | ISC_FSACCESS_DELETECHILD | ISC_FSACCESS_LISTDIRECTORY; /* * Set group bad bits. */ bits |= bits << STEP; /* * Set other bad bits. */ bits |= bits << STEP; if ((access & bits) != 0) { if (is_dir) return (ISC_R_NOTFILE); else return (ISC_R_NOTDIRECTORY); } return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/isc/pthreads/0002755000470500017500000000000012672612753016541 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/pthreads/Makefile.in0000644000470500017500000000235212664710322020576 0ustar lamontlamont# Copyright (C) 2004, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.22 2009/12/05 23:31:41 each Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ CINCLUDES = -I${srcdir}/include \ -I${srcdir}/../unix/include \ -I../include \ -I${srcdir}/../include \ -I${srcdir}/.. CDEFINES = CWARNINGS = OBJS = condition.@O@ mutex.@O@ thread.@O@ SRCS = condition.c mutex.c thread.c SUBDIRS = include TARGETS = ${OBJS} @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/pthreads/thread.c0000644000470500017500000000451412664710322020146 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: thread.c,v 1.17 2007/06/19 23:47:18 tbox Exp $ */ /*! \file */ #include #if defined(HAVE_SCHED_H) #include #endif #include #include #ifndef THREAD_MINSTACKSIZE #define THREAD_MINSTACKSIZE (1024U * 1024) #endif isc_result_t isc_thread_create(isc_threadfunc_t func, isc_threadarg_t arg, isc_thread_t *thread) { pthread_attr_t attr; size_t stacksize; int ret; pthread_attr_init(&attr); #if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \ defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) ret = pthread_attr_getstacksize(&attr, &stacksize); if (ret != 0) return (ISC_R_UNEXPECTED); if (stacksize < THREAD_MINSTACKSIZE) { ret = pthread_attr_setstacksize(&attr, THREAD_MINSTACKSIZE); if (ret != 0) return (ISC_R_UNEXPECTED); } #endif #if defined(PTHREAD_SCOPE_SYSTEM) && defined(NEED_PTHREAD_SCOPE_SYSTEM) ret = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); if (ret != 0) return (ISC_R_UNEXPECTED); #endif ret = pthread_create(thread, &attr, func, arg); if (ret != 0) return (ISC_R_UNEXPECTED); pthread_attr_destroy(&attr); return (ISC_R_SUCCESS); } void isc_thread_setconcurrency(unsigned int level) { #if defined(CALL_PTHREAD_SETCONCURRENCY) (void)pthread_setconcurrency(level); #else UNUSED(level); #endif } void isc_thread_yield(void) { #if defined(HAVE_SCHED_YIELD) sched_yield(); #elif defined( HAVE_PTHREAD_YIELD) pthread_yield(); #elif defined( HAVE_PTHREAD_YIELD_NP) pthread_yield_np(); #endif } bind9-9.10.3.dfsg.P4/lib/isc/pthreads/condition.c0000644000470500017500000000460612664710322020667 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: condition.c,v 1.36 2007/06/19 23:47:18 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include isc_result_t isc_condition_waituntil(isc_condition_t *c, isc_mutex_t *m, isc_time_t *t) { int presult; isc_result_t result; struct timespec ts; char strbuf[ISC_STRERRORSIZE]; REQUIRE(c != NULL && m != NULL && t != NULL); /* * POSIX defines a timespec's tv_sec as time_t. */ result = isc_time_secondsastimet(t, &ts.tv_sec); /* * If we have a range error ts.tv_sec is most probably a signed * 32 bit value. Set ts.tv_sec to INT_MAX. This is a kludge. */ if (result == ISC_R_RANGE) ts.tv_sec = INT_MAX; else if (result != ISC_R_SUCCESS) return (result); /*! * POSIX defines a timespec's tv_nsec as long. isc_time_nanoseconds * ensures its return value is < 1 billion, which will fit in a long. */ ts.tv_nsec = (long)isc_time_nanoseconds(t); do { #if ISC_MUTEX_PROFILE presult = pthread_cond_timedwait(c, &m->mutex, &ts); #else presult = pthread_cond_timedwait(c, m, &ts); #endif if (presult == 0) return (ISC_R_SUCCESS); if (presult == ETIMEDOUT) return (ISC_R_TIMEDOUT); } while (presult == EINTR); isc__strerror(presult, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "pthread_cond_timedwait() %s %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_RETURNED, "returned"), strbuf); return (ISC_R_UNEXPECTED); } bind9-9.10.3.dfsg.P4/lib/isc/pthreads/include/0002755000470500017500000000000012672612753020164 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/pthreads/include/Makefile.in0000644000470500017500000000175612664710322022230 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.14 2007/06/19 23:47:18 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = isc TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isc/pthreads/include/isc/0002755000470500017500000000000012664710322020732 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isc/pthreads/include/isc/once.h0000644000470500017500000000274612664710322022036 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: once.h,v 1.13 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_ONCE_H #define ISC_ONCE_H 1 /*! \file */ #include #include #include typedef pthread_once_t isc_once_t; #ifdef ISC_PLATFORM_BRACEPTHREADONCEINIT /*! * This accomodates systems that define PTHRAD_ONCE_INIT improperly. */ #define ISC_ONCE_INIT { PTHREAD_ONCE_INIT } #else /*! * This is the usual case. */ #define ISC_ONCE_INIT PTHREAD_ONCE_INIT #endif /* XXX We could do fancier error handling... */ #define isc_once_do(op, f) \ ((pthread_once((op), (f)) == 0) ? \ ISC_R_SUCCESS : ISC_R_UNEXPECTED) #endif /* ISC_ONCE_H */ bind9-9.10.3.dfsg.P4/lib/isc/pthreads/include/isc/Makefile.in0000644000470500017500000000236212664710322023000 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.16 2007/06/19 23:47:18 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ HEADERS = condition.h mutex.h once.h thread.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \ done bind9-9.10.3.dfsg.P4/lib/isc/pthreads/include/isc/condition.h0000644000470500017500000000373312664710322023075 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: condition.h,v 1.26 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_CONDITION_H #define ISC_CONDITION_H 1 /*! \file */ #include #include #include #include typedef pthread_cond_t isc_condition_t; #define isc_condition_init(cp) \ ((pthread_cond_init((cp), NULL) == 0) ? \ ISC_R_SUCCESS : ISC_R_UNEXPECTED) #if ISC_MUTEX_PROFILE #define isc_condition_wait(cp, mp) \ ((pthread_cond_wait((cp), &((mp)->mutex)) == 0) ? \ ISC_R_SUCCESS : ISC_R_UNEXPECTED) #else #define isc_condition_wait(cp, mp) \ ((pthread_cond_wait((cp), (mp)) == 0) ? \ ISC_R_SUCCESS : ISC_R_UNEXPECTED) #endif #define isc_condition_signal(cp) \ ((pthread_cond_signal((cp)) == 0) ? \ ISC_R_SUCCESS : ISC_R_UNEXPECTED) #define isc_condition_broadcast(cp) \ ((pthread_cond_broadcast((cp)) == 0) ? \ ISC_R_SUCCESS : ISC_R_UNEXPECTED) #define isc_condition_destroy(cp) \ ((pthread_cond_destroy((cp)) == 0) ? \ ISC_R_SUCCESS : ISC_R_UNEXPECTED) ISC_LANG_BEGINDECLS isc_result_t isc_condition_waituntil(isc_condition_t *, isc_mutex_t *, isc_time_t *); ISC_LANG_ENDDECLS #endif /* ISC_CONDITION_H */ bind9-9.10.3.dfsg.P4/lib/isc/pthreads/include/isc/mutex.h0000644000470500017500000000773512664710322022257 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: mutex.h,v 1.30 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_MUTEX_H #define ISC_MUTEX_H 1 /*! \file */ #include #include #include #include /* for ISC_R_ codes */ ISC_LANG_BEGINDECLS /*! * Supply mutex attributes that enable deadlock detection * (helpful when debugging). This is system dependent and * currently only supported on NetBSD. */ #if ISC_MUTEX_DEBUG && defined(__NetBSD__) && defined(PTHREAD_MUTEX_ERRORCHECK) extern pthread_mutexattr_t isc__mutex_attrs; #define ISC__MUTEX_ATTRS &isc__mutex_attrs #else #define ISC__MUTEX_ATTRS NULL #endif /* XXX We could do fancier error handling... */ /*! * Define ISC_MUTEX_PROFILE to turn on profiling of mutexes by line. When * enabled, isc_mutex_stats() can be used to print a table showing the * number of times each type of mutex was locked and the amount of time * waiting to obtain the lock. */ #ifndef ISC_MUTEX_PROFILE #define ISC_MUTEX_PROFILE 0 #endif #if ISC_MUTEX_PROFILE typedef struct isc_mutexstats isc_mutexstats_t; typedef struct { pthread_mutex_t mutex; /*%< The actual mutex. */ isc_mutexstats_t * stats; /*%< Mutex statistics. */ } isc_mutex_t; #else typedef pthread_mutex_t isc_mutex_t; #endif #if ISC_MUTEX_PROFILE #define isc_mutex_init(mp) \ isc_mutex_init_profile((mp), __FILE__, __LINE__) #else #if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK) #define isc_mutex_init(mp) \ isc_mutex_init_errcheck((mp)) #else #define isc_mutex_init(mp) \ isc__mutex_init((mp), __FILE__, __LINE__) isc_result_t isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line); #endif #endif #if ISC_MUTEX_PROFILE #define isc_mutex_lock(mp) \ isc_mutex_lock_profile((mp), __FILE__, __LINE__) #else #define isc_mutex_lock(mp) \ ((pthread_mutex_lock((mp)) == 0) ? \ ISC_R_SUCCESS : ISC_R_UNEXPECTED) #endif #if ISC_MUTEX_PROFILE #define isc_mutex_unlock(mp) \ isc_mutex_unlock_profile((mp), __FILE__, __LINE__) #else #define isc_mutex_unlock(mp) \ ((pthread_mutex_unlock((mp)) == 0) ? \ ISC_R_SUCCESS : ISC_R_UNEXPECTED) #endif #if ISC_MUTEX_PROFILE #define isc_mutex_trylock(mp) \ ((pthread_mutex_trylock((&(mp)->mutex)) == 0) ? \ ISC_R_SUCCESS : ISC_R_LOCKBUSY) #else #define isc_mutex_trylock(mp) \ ((pthread_mutex_trylock((mp)) == 0) ? \ ISC_R_SUCCESS : ISC_R_LOCKBUSY) #endif #if ISC_MUTEX_PROFILE #define isc_mutex_destroy(mp) \ ((pthread_mutex_destroy((&(mp)->mutex)) == 0) ? \ ISC_R_SUCCESS : ISC_R_UNEXPECTED) #else #define isc_mutex_destroy(mp) \ ((pthread_mutex_destroy((mp)) == 0) ? \ ISC_R_SUCCESS : ISC_R_UNEXPECTED) #endif #if ISC_MUTEX_PROFILE #define isc_mutex_stats(fp) isc_mutex_statsprofile(fp); #else #define isc_mutex_stats(fp) #endif #if ISC_MUTEX_PROFILE isc_result_t isc_mutex_init_profile(isc_mutex_t *mp, const char * _file, int _line); isc_result_t isc_mutex_lock_profile(isc_mutex_t *mp, const char * _file, int _line); isc_result_t isc_mutex_unlock_profile(isc_mutex_t *mp, const char * _file, int _line); void isc_mutex_statsprofile(FILE *fp); isc_result_t isc_mutex_init_errcheck(isc_mutex_t *mp); #endif /* ISC_MUTEX_PROFILE */ ISC_LANG_ENDDECLS #endif /* ISC_MUTEX_H */ bind9-9.10.3.dfsg.P4/lib/isc/pthreads/include/isc/thread.h0000644000470500017500000000357212664710322022357 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: thread.h,v 1.26 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_THREAD_H #define ISC_THREAD_H 1 /*! \file */ #include #include #include ISC_LANG_BEGINDECLS typedef pthread_t isc_thread_t; typedef void * isc_threadresult_t; typedef void * isc_threadarg_t; typedef isc_threadresult_t (*isc_threadfunc_t)(isc_threadarg_t); typedef pthread_key_t isc_thread_key_t; isc_result_t isc_thread_create(isc_threadfunc_t, isc_threadarg_t, isc_thread_t *); void isc_thread_setconcurrency(unsigned int level); void isc_thread_yield(void); /* XXX We could do fancier error handling... */ #define isc_thread_join(t, rp) \ ((pthread_join((t), (rp)) == 0) ? \ ISC_R_SUCCESS : ISC_R_UNEXPECTED) #define isc_thread_self \ (unsigned long)pthread_self #define isc_thread_key_create pthread_key_create #define isc_thread_key_getspecific pthread_getspecific #define isc_thread_key_setspecific pthread_setspecific #define isc_thread_key_delete pthread_key_delete ISC_LANG_ENDDECLS #endif /* ISC_THREAD_H */ bind9-9.10.3.dfsg.P4/lib/isc/pthreads/mutex.c0000644000470500017500000002054512664710322020043 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2008, 2011, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: mutex.c,v 1.18 2011/01/04 23:47:14 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #if ISC_MUTEX_PROFILE /*@{*/ /*% Operations on timevals; adapted from FreeBSD's sys/time.h */ #define timevalclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0) #define timevaladd(vvp, uvp) \ do { \ (vvp)->tv_sec += (uvp)->tv_sec; \ (vvp)->tv_usec += (uvp)->tv_usec; \ if ((vvp)->tv_usec >= 1000000) { \ (vvp)->tv_sec++; \ (vvp)->tv_usec -= 1000000; \ } \ } while (0) #define timevalsub(vvp, uvp) \ do { \ (vvp)->tv_sec -= (uvp)->tv_sec; \ (vvp)->tv_usec -= (uvp)->tv_usec; \ if ((vvp)->tv_usec < 0) { \ (vvp)->tv_sec--; \ (vvp)->tv_usec += 1000000; \ } \ } while (0) /*@}*/ #define ISC_MUTEX_MAX_LOCKERS 32 typedef struct { const char * file; int line; unsigned count; struct timeval locked_total; struct timeval wait_total; } isc_mutexlocker_t; struct isc_mutexstats { const char * file; /*%< File mutex was created in. */ int line; /*%< Line mutex was created on. */ unsigned count; struct timeval lock_t; struct timeval locked_total; struct timeval wait_total; isc_mutexlocker_t * cur_locker; isc_mutexlocker_t lockers[ISC_MUTEX_MAX_LOCKERS]; }; #ifndef ISC_MUTEX_PROFTABLESIZE #define ISC_MUTEX_PROFTABLESIZE (1024 * 1024) #endif static isc_mutexstats_t stats[ISC_MUTEX_PROFTABLESIZE]; static int stats_next = 0; static isc_boolean_t stats_init = ISC_FALSE; static pthread_mutex_t statslock = PTHREAD_MUTEX_INITIALIZER; isc_result_t isc_mutex_init_profile(isc_mutex_t *mp, const char *file, int line) { int i, err; err = pthread_mutex_init(&mp->mutex, NULL); if (err == ENOMEM) return (ISC_R_NOMEMORY); if (err != 0) return (ISC_R_UNEXPECTED); RUNTIME_CHECK(pthread_mutex_lock(&statslock) == 0); if (stats_init == ISC_FALSE) stats_init = ISC_TRUE; /* * If all statistics entries have been used, give up and trigger an * assertion failure. There would be no other way to deal with this * because we'd like to keep record of all locks for the purpose of * debugging and the number of necessary locks is unpredictable. * If this failure is triggered while debugging, named should be * rebuilt with an increased ISC_MUTEX_PROFTABLESIZE. */ RUNTIME_CHECK(stats_next < ISC_MUTEX_PROFTABLESIZE); mp->stats = &stats[stats_next++]; RUNTIME_CHECK(pthread_mutex_unlock(&statslock) == 0); mp->stats->file = file; mp->stats->line = line; mp->stats->count = 0; timevalclear(&mp->stats->locked_total); timevalclear(&mp->stats->wait_total); for (i = 0; i < ISC_MUTEX_MAX_LOCKERS; i++) { mp->stats->lockers[i].file = NULL; mp->stats->lockers[i].line = 0; mp->stats->lockers[i].count = 0; timevalclear(&mp->stats->lockers[i].locked_total); timevalclear(&mp->stats->lockers[i].wait_total); } return (ISC_R_SUCCESS); } isc_result_t isc_mutex_lock_profile(isc_mutex_t *mp, const char *file, int line) { struct timeval prelock_t; struct timeval postlock_t; isc_mutexlocker_t *locker = NULL; int i; gettimeofday(&prelock_t, NULL); if (pthread_mutex_lock(&mp->mutex) != 0) return (ISC_R_UNEXPECTED); gettimeofday(&postlock_t, NULL); mp->stats->lock_t = postlock_t; timevalsub(&postlock_t, &prelock_t); mp->stats->count++; timevaladd(&mp->stats->wait_total, &postlock_t); for (i = 0; i < ISC_MUTEX_MAX_LOCKERS; i++) { if (mp->stats->lockers[i].file == NULL) { locker = &mp->stats->lockers[i]; locker->file = file; locker->line = line; break; } else if (mp->stats->lockers[i].file == file && mp->stats->lockers[i].line == line) { locker = &mp->stats->lockers[i]; break; } } if (locker != NULL) { locker->count++; timevaladd(&locker->wait_total, &postlock_t); } mp->stats->cur_locker = locker; return (ISC_R_SUCCESS); } isc_result_t isc_mutex_unlock_profile(isc_mutex_t *mp, const char *file, int line) { struct timeval unlock_t; UNUSED(file); UNUSED(line); if (mp->stats->cur_locker != NULL) { gettimeofday(&unlock_t, NULL); timevalsub(&unlock_t, &mp->stats->lock_t); timevaladd(&mp->stats->locked_total, &unlock_t); timevaladd(&mp->stats->cur_locker->locked_total, &unlock_t); mp->stats->cur_locker = NULL; } return ((pthread_mutex_unlock((&mp->mutex)) == 0) ? \ ISC_R_SUCCESS : ISC_R_UNEXPECTED); } void isc_mutex_statsprofile(FILE *fp) { isc_mutexlocker_t *locker; int i, j; fprintf(fp, "Mutex stats (in us)\n"); for (i = 0; i < stats_next; i++) { fprintf(fp, "%-12s %4d: %10u %lu.%06lu %lu.%06lu %5d\n", stats[i].file, stats[i].line, stats[i].count, stats[i].locked_total.tv_sec, stats[i].locked_total.tv_usec, stats[i].wait_total.tv_sec, stats[i].wait_total.tv_usec, i); for (j = 0; j < ISC_MUTEX_MAX_LOCKERS; j++) { locker = &stats[i].lockers[j]; if (locker->file == NULL) continue; fprintf(fp, " %-11s %4d: %10u %lu.%06lu %lu.%06lu %5d\n", locker->file, locker->line, locker->count, locker->locked_total.tv_sec, locker->locked_total.tv_usec, locker->wait_total.tv_sec, locker->wait_total.tv_usec, i); } } } #endif /* ISC_MUTEX_PROFILE */ #if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK) static isc_boolean_t errcheck_initialized = ISC_FALSE; static pthread_mutexattr_t errcheck; static isc_once_t once_errcheck = ISC_ONCE_INIT; static void initialize_errcheck(void) { RUNTIME_CHECK(pthread_mutexattr_init(&errcheck) == 0); RUNTIME_CHECK(pthread_mutexattr_settype (&errcheck, PTHREAD_MUTEX_ERRORCHECK) == 0); errcheck_initialized = ISC_TRUE; } isc_result_t isc_mutex_init_errcheck(isc_mutex_t *mp) { isc_result_t result; int err; result = isc_once_do(&once_errcheck, initialize_errcheck); RUNTIME_CHECK(result == ISC_R_SUCCESS); err = pthread_mutex_init(mp, &errcheck); if (err == ENOMEM) return (ISC_R_NOMEMORY); return ((err == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED); } #endif #if ISC_MUTEX_DEBUG && defined(__NetBSD__) && defined(PTHREAD_MUTEX_ERRORCHECK) pthread_mutexattr_t isc__mutex_attrs = { PTHREAD_MUTEX_ERRORCHECK, /* m_type */ 0 /* m_flags, which appears to be unused. */ }; #endif #if !(ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)) && !ISC_MUTEX_PROFILE #ifdef HAVE_PTHREAD_MUTEX_ADAPTIVE_NP static isc_boolean_t attr_initialized = ISC_FALSE; static pthread_mutexattr_t attr; static isc_once_t once_attr = ISC_ONCE_INIT; #endif /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */ #ifdef HAVE_PTHREAD_MUTEX_ADAPTIVE_NP static void initialize_attr(void) { RUNTIME_CHECK(pthread_mutexattr_init(&attr) == 0); RUNTIME_CHECK(pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ADAPTIVE_NP) == 0); attr_initialized = ISC_TRUE; } #endif /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */ isc_result_t isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line) { char strbuf[ISC_STRERRORSIZE]; isc_result_t result = ISC_R_SUCCESS; int err; #ifdef HAVE_PTHREAD_MUTEX_ADAPTIVE_NP result = isc_once_do(&once_attr, initialize_attr); RUNTIME_CHECK(result == ISC_R_SUCCESS); err = pthread_mutex_init(mp, &attr); #else /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */ err = pthread_mutex_init(mp, ISC__MUTEX_ATTRS); #endif /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */ if (err == ENOMEM) return (ISC_R_NOMEMORY); if (err != 0) { isc__strerror(err, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(file, line, "isc_mutex_init() failed: %s", strbuf); result = ISC_R_UNEXPECTED; } return (result); } #endif bind9-9.10.3.dfsg.P4/lib/isc/rwlock.c0000644000470500017500000005433312664710322016372 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include #include #include #include #include #define RWLOCK_MAGIC ISC_MAGIC('R', 'W', 'L', 'k') #define VALID_RWLOCK(rwl) ISC_MAGIC_VALID(rwl, RWLOCK_MAGIC) #ifdef ISC_PLATFORM_USETHREADS #ifndef RWLOCK_DEFAULT_READ_QUOTA #define RWLOCK_DEFAULT_READ_QUOTA 4 #endif #ifndef RWLOCK_DEFAULT_WRITE_QUOTA #define RWLOCK_DEFAULT_WRITE_QUOTA 4 #endif #ifdef ISC_RWLOCK_TRACE #include /* Required for fprintf/stderr. */ #include /* Required for isc_thread_self(). */ static void print_lock(const char *operation, isc_rwlock_t *rwl, isc_rwlocktype_t type) { fprintf(stderr, isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK, ISC_MSG_PRINTLOCK, "rwlock %p thread %lu %s(%s): %s, %u active, " "%u granted, %u rwaiting, %u wwaiting\n"), rwl, isc_thread_self(), operation, (type == isc_rwlocktype_read ? isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK, ISC_MSG_READ, "read") : isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK, ISC_MSG_WRITE, "write")), (rwl->type == isc_rwlocktype_read ? isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK, ISC_MSG_READING, "reading") : isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK, ISC_MSG_WRITING, "writing")), rwl->active, rwl->granted, rwl->readers_waiting, rwl->writers_waiting); } #endif isc_result_t isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota, unsigned int write_quota) { isc_result_t result; REQUIRE(rwl != NULL); /* * In case there's trouble initializing, we zero magic now. If all * goes well, we'll set it to RWLOCK_MAGIC. */ rwl->magic = 0; #if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG) rwl->write_requests = 0; rwl->write_completions = 0; rwl->cnt_and_flag = 0; rwl->readers_waiting = 0; rwl->write_granted = 0; if (read_quota != 0) { UNEXPECTED_ERROR(__FILE__, __LINE__, "read quota is not supported"); } if (write_quota == 0) write_quota = RWLOCK_DEFAULT_WRITE_QUOTA; rwl->write_quota = write_quota; #else rwl->type = isc_rwlocktype_read; rwl->original = isc_rwlocktype_none; rwl->active = 0; rwl->granted = 0; rwl->readers_waiting = 0; rwl->writers_waiting = 0; if (read_quota == 0) read_quota = RWLOCK_DEFAULT_READ_QUOTA; rwl->read_quota = read_quota; if (write_quota == 0) write_quota = RWLOCK_DEFAULT_WRITE_QUOTA; rwl->write_quota = write_quota; #endif result = isc_mutex_init(&rwl->lock); if (result != ISC_R_SUCCESS) return (result); result = isc_condition_init(&rwl->readable); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_condition_init(readable) %s: %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), isc_result_totext(result)); result = ISC_R_UNEXPECTED; goto destroy_lock; } result = isc_condition_init(&rwl->writeable); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_condition_init(writeable) %s: %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed"), isc_result_totext(result)); result = ISC_R_UNEXPECTED; goto destroy_rcond; } rwl->magic = RWLOCK_MAGIC; return (ISC_R_SUCCESS); destroy_rcond: (void)isc_condition_destroy(&rwl->readable); destroy_lock: DESTROYLOCK(&rwl->lock); return (result); } void isc_rwlock_destroy(isc_rwlock_t *rwl) { REQUIRE(VALID_RWLOCK(rwl)); #if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG) REQUIRE(rwl->write_requests == rwl->write_completions && rwl->cnt_and_flag == 0 && rwl->readers_waiting == 0); #else LOCK(&rwl->lock); REQUIRE(rwl->active == 0 && rwl->readers_waiting == 0 && rwl->writers_waiting == 0); UNLOCK(&rwl->lock); #endif rwl->magic = 0; (void)isc_condition_destroy(&rwl->readable); (void)isc_condition_destroy(&rwl->writeable); DESTROYLOCK(&rwl->lock); } #if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG) /* * When some architecture-dependent atomic operations are available, * rwlock can be more efficient than the generic algorithm defined below. * The basic algorithm is described in the following URL: * http://www.cs.rochester.edu/u/scott/synchronization/pseudocode/rw.html * * The key is to use the following integer variables modified atomically: * write_requests, write_completions, and cnt_and_flag. * * write_requests and write_completions act as a waiting queue for writers * in order to ensure the FIFO order. Both variables begin with the initial * value of 0. When a new writer tries to get a write lock, it increments * write_requests and gets the previous value of the variable as a "ticket". * When write_completions reaches the ticket number, the new writer can start * writing. When the writer completes its work, it increments * write_completions so that another new writer can start working. If the * write_requests is not equal to write_completions, it means a writer is now * working or waiting. In this case, a new readers cannot start reading, or * in other words, this algorithm basically prefers writers. * * cnt_and_flag is a "lock" shared by all readers and writers. This integer * variable is a kind of structure with two members: writer_flag (1 bit) and * reader_count (31 bits). The writer_flag shows whether a writer is working, * and the reader_count shows the number of readers currently working or almost * ready for working. A writer who has the current "ticket" tries to get the * lock by exclusively setting the writer_flag to 1, provided that the whole * 32-bit is 0 (meaning no readers or writers working). On the other hand, * a new reader tries to increment the "reader_count" field provided that * the writer_flag is 0 (meaning there is no writer working). * * If some of the above operations fail, the reader or the writer sleeps * until the related condition changes. When a working reader or writer * completes its work, some readers or writers are sleeping, and the condition * that suspended the reader or writer has changed, it wakes up the sleeping * readers or writers. * * As already noted, this algorithm basically prefers writers. In order to * prevent readers from starving, however, the algorithm also introduces the * "writer quota" (Q). When Q consecutive writers have completed their work, * suspending readers, the last writer will wake up the readers, even if a new * writer is waiting. * * Implementation specific note: due to the combination of atomic operations * and a mutex lock, ordering between the atomic operation and locks can be * very sensitive in some cases. In particular, it is generally very important * to check the atomic variable that requires a reader or writer to sleep after * locking the mutex and before actually sleeping; otherwise, it could be very * likely to cause a deadlock. For example, assume "var" is a variable * atomically modified, then the corresponding code would be: * if (var == need_sleep) { * LOCK(lock); * if (var == need_sleep) * WAIT(cond, lock); * UNLOCK(lock); * } * The second check is important, since "var" is protected by the atomic * operation, not by the mutex, and can be changed just before sleeping. * (The first "if" could be omitted, but this is also important in order to * make the code efficient by avoiding the use of the mutex unless it is * really necessary.) */ #define WRITER_ACTIVE 0x1 #define READER_INCR 0x2 isc_result_t isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { isc_int32_t cntflag; REQUIRE(VALID_RWLOCK(rwl)); #ifdef ISC_RWLOCK_TRACE print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK, ISC_MSG_PRELOCK, "prelock"), rwl, type); #endif if (type == isc_rwlocktype_read) { if (rwl->write_requests != rwl->write_completions) { /* there is a waiting or active writer */ LOCK(&rwl->lock); if (rwl->write_requests != rwl->write_completions) { rwl->readers_waiting++; WAIT(&rwl->readable, &rwl->lock); rwl->readers_waiting--; } UNLOCK(&rwl->lock); } cntflag = isc_atomic_xadd(&rwl->cnt_and_flag, READER_INCR); POST(cntflag); while (1) { if ((rwl->cnt_and_flag & WRITER_ACTIVE) == 0) break; /* A writer is still working */ LOCK(&rwl->lock); rwl->readers_waiting++; if ((rwl->cnt_and_flag & WRITER_ACTIVE) != 0) WAIT(&rwl->readable, &rwl->lock); rwl->readers_waiting--; UNLOCK(&rwl->lock); /* * Typically, the reader should be able to get a lock * at this stage: * (1) there should have been no pending writer when * the reader was trying to increment the * counter; otherwise, the writer should be in * the waiting queue, preventing the reader from * proceeding to this point. * (2) once the reader increments the counter, no * more writer can get a lock. * Still, it is possible another writer can work at * this point, e.g. in the following scenario: * A previous writer unlocks the writer lock. * This reader proceeds to point (1). * A new writer appears, and gets a new lock before * the reader increments the counter. * The reader then increments the counter. * The previous writer notices there is a waiting * reader who is almost ready, and wakes it up. * So, the reader needs to confirm whether it can now * read explicitly (thus we loop). Note that this is * not an infinite process, since the reader has * incremented the counter at this point. */ } /* * If we are temporarily preferred to writers due to the writer * quota, reset the condition (race among readers doesn't * matter). */ rwl->write_granted = 0; } else { isc_int32_t prev_writer; /* enter the waiting queue, and wait for our turn */ prev_writer = isc_atomic_xadd(&rwl->write_requests, 1); while (rwl->write_completions != prev_writer) { LOCK(&rwl->lock); if (rwl->write_completions != prev_writer) { WAIT(&rwl->writeable, &rwl->lock); UNLOCK(&rwl->lock); continue; } UNLOCK(&rwl->lock); break; } while (1) { cntflag = isc_atomic_cmpxchg(&rwl->cnt_and_flag, 0, WRITER_ACTIVE); if (cntflag == 0) break; /* Another active reader or writer is working. */ LOCK(&rwl->lock); if (rwl->cnt_and_flag != 0) WAIT(&rwl->writeable, &rwl->lock); UNLOCK(&rwl->lock); } INSIST((rwl->cnt_and_flag & WRITER_ACTIVE) != 0); rwl->write_granted++; } #ifdef ISC_RWLOCK_TRACE print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK, ISC_MSG_POSTLOCK, "postlock"), rwl, type); #endif return (ISC_R_SUCCESS); } isc_result_t isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { isc_int32_t cntflag; REQUIRE(VALID_RWLOCK(rwl)); #ifdef ISC_RWLOCK_TRACE print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK, ISC_MSG_PRELOCK, "prelock"), rwl, type); #endif if (type == isc_rwlocktype_read) { /* If a writer is waiting or working, we fail. */ if (rwl->write_requests != rwl->write_completions) return (ISC_R_LOCKBUSY); /* Otherwise, be ready for reading. */ cntflag = isc_atomic_xadd(&rwl->cnt_and_flag, READER_INCR); if ((cntflag & WRITER_ACTIVE) != 0) { /* * A writer is working. We lose, and cancel the read * request. */ cntflag = isc_atomic_xadd(&rwl->cnt_and_flag, -READER_INCR); /* * If no other readers are waiting and we've suspended * new writers in this short period, wake them up. */ if (cntflag == READER_INCR && rwl->write_completions != rwl->write_requests) { LOCK(&rwl->lock); BROADCAST(&rwl->writeable); UNLOCK(&rwl->lock); } return (ISC_R_LOCKBUSY); } } else { /* Try locking without entering the waiting queue. */ cntflag = isc_atomic_cmpxchg(&rwl->cnt_and_flag, 0, WRITER_ACTIVE); if (cntflag != 0) return (ISC_R_LOCKBUSY); /* * XXXJT: jump into the queue, possibly breaking the writer * order. */ (void)isc_atomic_xadd(&rwl->write_completions, -1); rwl->write_granted++; } #ifdef ISC_RWLOCK_TRACE print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK, ISC_MSG_POSTLOCK, "postlock"), rwl, type); #endif return (ISC_R_SUCCESS); } isc_result_t isc_rwlock_tryupgrade(isc_rwlock_t *rwl) { isc_int32_t prevcnt; REQUIRE(VALID_RWLOCK(rwl)); /* Try to acquire write access. */ prevcnt = isc_atomic_cmpxchg(&rwl->cnt_and_flag, READER_INCR, WRITER_ACTIVE); /* * There must have been no writer, and there must have been at least * one reader. */ INSIST((prevcnt & WRITER_ACTIVE) == 0 && (prevcnt & ~WRITER_ACTIVE) != 0); if (prevcnt == READER_INCR) { /* * We are the only reader and have been upgraded. * Now jump into the head of the writer waiting queue. */ (void)isc_atomic_xadd(&rwl->write_completions, -1); } else return (ISC_R_LOCKBUSY); return (ISC_R_SUCCESS); } void isc_rwlock_downgrade(isc_rwlock_t *rwl) { isc_int32_t prev_readers; REQUIRE(VALID_RWLOCK(rwl)); /* Become an active reader. */ prev_readers = isc_atomic_xadd(&rwl->cnt_and_flag, READER_INCR); /* We must have been a writer. */ INSIST((prev_readers & WRITER_ACTIVE) != 0); /* Complete write */ (void)isc_atomic_xadd(&rwl->cnt_and_flag, -WRITER_ACTIVE); (void)isc_atomic_xadd(&rwl->write_completions, 1); /* Resume other readers */ LOCK(&rwl->lock); if (rwl->readers_waiting > 0) BROADCAST(&rwl->readable); UNLOCK(&rwl->lock); } isc_result_t isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { isc_int32_t prev_cnt; REQUIRE(VALID_RWLOCK(rwl)); #ifdef ISC_RWLOCK_TRACE print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK, ISC_MSG_PREUNLOCK, "preunlock"), rwl, type); #endif if (type == isc_rwlocktype_read) { prev_cnt = isc_atomic_xadd(&rwl->cnt_and_flag, -READER_INCR); /* * If we're the last reader and any writers are waiting, wake * them up. We need to wake up all of them to ensure the * FIFO order. */ if (prev_cnt == READER_INCR && rwl->write_completions != rwl->write_requests) { LOCK(&rwl->lock); BROADCAST(&rwl->writeable); UNLOCK(&rwl->lock); } } else { isc_boolean_t wakeup_writers = ISC_TRUE; /* * Reset the flag, and (implicitly) tell other writers * we are done. */ (void)isc_atomic_xadd(&rwl->cnt_and_flag, -WRITER_ACTIVE); (void)isc_atomic_xadd(&rwl->write_completions, 1); if (rwl->write_granted >= rwl->write_quota || rwl->write_requests == rwl->write_completions || (rwl->cnt_and_flag & ~WRITER_ACTIVE) != 0) { /* * We have passed the write quota, no writer is * waiting, or some readers are almost ready, pending * possible writers. Note that the last case can * happen even if write_requests != write_completions * (which means a new writer in the queue), so we need * to catch the case explicitly. */ LOCK(&rwl->lock); if (rwl->readers_waiting > 0) { wakeup_writers = ISC_FALSE; BROADCAST(&rwl->readable); } UNLOCK(&rwl->lock); } if (rwl->write_requests != rwl->write_completions && wakeup_writers) { LOCK(&rwl->lock); BROADCAST(&rwl->writeable); UNLOCK(&rwl->lock); } } #ifdef ISC_RWLOCK_TRACE print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK, ISC_MSG_POSTUNLOCK, "postunlock"), rwl, type); #endif return (ISC_R_SUCCESS); } #else /* ISC_PLATFORM_HAVEXADD && ISC_PLATFORM_HAVECMPXCHG */ static isc_result_t doit(isc_rwlock_t *rwl, isc_rwlocktype_t type, isc_boolean_t nonblock) { isc_boolean_t skip = ISC_FALSE; isc_boolean_t done = ISC_FALSE; isc_result_t result = ISC_R_SUCCESS; REQUIRE(VALID_RWLOCK(rwl)); LOCK(&rwl->lock); #ifdef ISC_RWLOCK_TRACE print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK, ISC_MSG_PRELOCK, "prelock"), rwl, type); #endif if (type == isc_rwlocktype_read) { if (rwl->readers_waiting != 0) skip = ISC_TRUE; while (!done) { if (!skip && ((rwl->active == 0 || (rwl->type == isc_rwlocktype_read && (rwl->writers_waiting == 0 || rwl->granted < rwl->read_quota))))) { rwl->type = isc_rwlocktype_read; rwl->active++; rwl->granted++; done = ISC_TRUE; } else if (nonblock) { result = ISC_R_LOCKBUSY; done = ISC_TRUE; } else { skip = ISC_FALSE; rwl->readers_waiting++; WAIT(&rwl->readable, &rwl->lock); rwl->readers_waiting--; } } } else { if (rwl->writers_waiting != 0) skip = ISC_TRUE; while (!done) { if (!skip && rwl->active == 0) { rwl->type = isc_rwlocktype_write; rwl->active = 1; rwl->granted++; done = ISC_TRUE; } else if (nonblock) { result = ISC_R_LOCKBUSY; done = ISC_TRUE; } else { skip = ISC_FALSE; rwl->writers_waiting++; WAIT(&rwl->writeable, &rwl->lock); rwl->writers_waiting--; } } } #ifdef ISC_RWLOCK_TRACE print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK, ISC_MSG_POSTLOCK, "postlock"), rwl, type); #endif UNLOCK(&rwl->lock); return (result); } isc_result_t isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { return (doit(rwl, type, ISC_FALSE)); } isc_result_t isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { return (doit(rwl, type, ISC_TRUE)); } isc_result_t isc_rwlock_tryupgrade(isc_rwlock_t *rwl) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(VALID_RWLOCK(rwl)); LOCK(&rwl->lock); REQUIRE(rwl->type == isc_rwlocktype_read); REQUIRE(rwl->active != 0); /* If we are the only reader then succeed. */ if (rwl->active == 1) { rwl->original = (rwl->original == isc_rwlocktype_none) ? isc_rwlocktype_read : isc_rwlocktype_none; rwl->type = isc_rwlocktype_write; } else result = ISC_R_LOCKBUSY; UNLOCK(&rwl->lock); return (result); } void isc_rwlock_downgrade(isc_rwlock_t *rwl) { REQUIRE(VALID_RWLOCK(rwl)); LOCK(&rwl->lock); REQUIRE(rwl->type == isc_rwlocktype_write); REQUIRE(rwl->active == 1); rwl->type = isc_rwlocktype_read; rwl->original = (rwl->original == isc_rwlocktype_none) ? isc_rwlocktype_write : isc_rwlocktype_none; /* * Resume processing any read request that were blocked when * we upgraded. */ if (rwl->original == isc_rwlocktype_none && (rwl->writers_waiting == 0 || rwl->granted < rwl->read_quota) && rwl->readers_waiting > 0) BROADCAST(&rwl->readable); UNLOCK(&rwl->lock); } isc_result_t isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { REQUIRE(VALID_RWLOCK(rwl)); LOCK(&rwl->lock); REQUIRE(rwl->type == type); UNUSED(type); #ifdef ISC_RWLOCK_TRACE print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK, ISC_MSG_PREUNLOCK, "preunlock"), rwl, type); #endif INSIST(rwl->active > 0); rwl->active--; if (rwl->active == 0) { if (rwl->original != isc_rwlocktype_none) { rwl->type = rwl->original; rwl->original = isc_rwlocktype_none; } if (rwl->type == isc_rwlocktype_read) { rwl->granted = 0; if (rwl->writers_waiting > 0) { rwl->type = isc_rwlocktype_write; SIGNAL(&rwl->writeable); } else if (rwl->readers_waiting > 0) { /* Does this case ever happen? */ BROADCAST(&rwl->readable); } } else { if (rwl->readers_waiting > 0) { if (rwl->writers_waiting > 0 && rwl->granted < rwl->write_quota) { SIGNAL(&rwl->writeable); } else { rwl->granted = 0; rwl->type = isc_rwlocktype_read; BROADCAST(&rwl->readable); } } else if (rwl->writers_waiting > 0) { rwl->granted = 0; SIGNAL(&rwl->writeable); } else { rwl->granted = 0; } } } INSIST(rwl->original == isc_rwlocktype_none); #ifdef ISC_RWLOCK_TRACE print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK, ISC_MSG_POSTUNLOCK, "postunlock"), rwl, type); #endif UNLOCK(&rwl->lock); return (ISC_R_SUCCESS); } #endif /* ISC_PLATFORM_HAVEXADD && ISC_PLATFORM_HAVECMPXCHG */ #else /* ISC_PLATFORM_USETHREADS */ isc_result_t isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota, unsigned int write_quota) { REQUIRE(rwl != NULL); UNUSED(read_quota); UNUSED(write_quota); rwl->type = isc_rwlocktype_read; rwl->active = 0; rwl->magic = RWLOCK_MAGIC; return (ISC_R_SUCCESS); } isc_result_t isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { REQUIRE(VALID_RWLOCK(rwl)); if (type == isc_rwlocktype_read) { if (rwl->type != isc_rwlocktype_read && rwl->active != 0) return (ISC_R_LOCKBUSY); rwl->type = isc_rwlocktype_read; rwl->active++; } else { if (rwl->active != 0) return (ISC_R_LOCKBUSY); rwl->type = isc_rwlocktype_write; rwl->active = 1; } return (ISC_R_SUCCESS); } isc_result_t isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { return (isc_rwlock_lock(rwl, type)); } isc_result_t isc_rwlock_tryupgrade(isc_rwlock_t *rwl) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(VALID_RWLOCK(rwl)); REQUIRE(rwl->type == isc_rwlocktype_read); REQUIRE(rwl->active != 0); /* If we are the only reader then succeed. */ if (rwl->active == 1) rwl->type = isc_rwlocktype_write; else result = ISC_R_LOCKBUSY; return (result); } void isc_rwlock_downgrade(isc_rwlock_t *rwl) { REQUIRE(VALID_RWLOCK(rwl)); REQUIRE(rwl->type == isc_rwlocktype_write); REQUIRE(rwl->active == 1); rwl->type = isc_rwlocktype_read; } isc_result_t isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { REQUIRE(VALID_RWLOCK(rwl)); REQUIRE(rwl->type == type); UNUSED(type); INSIST(rwl->active > 0); rwl->active--; return (ISC_R_SUCCESS); } void isc_rwlock_destroy(isc_rwlock_t *rwl) { REQUIRE(rwl != NULL); REQUIRE(rwl->active == 0); rwl->magic = 0; } #endif /* ISC_PLATFORM_USETHREADS */ bind9-9.10.3.dfsg.P4/lib/isc/strtoul.c0000644000470500017500000001000612664710322016572 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (c) 1990, 1993 * The Regents of the University of California. 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. Neither the name of the University 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 REGENTS 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 */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)strtoul.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ /* $Id: strtoul.c,v 1.7 2007/06/19 23:47:17 tbox Exp $ */ #include #include #include #include #include #include /*! * Convert a string to an unsigned long integer. * * Ignores `locale' stuff. Assumes that the upper and lower case * alphabets and digits are each contiguous. */ unsigned long isc_strtoul(const char *nptr, char **endptr, int base) { const char *s = nptr; unsigned long acc; unsigned char c; unsigned long cutoff; int neg = 0, any, cutlim; /* * See strtol for comments as to the logic used. */ do { c = *s++; } while (isspace(c)); if (c == '-') { neg = 1; c = *s++; } else if (c == '+') c = *s++; if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { c = s[1]; s += 2; base = 16; } if (base == 0) base = c == '0' ? 8 : 10; cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; for (acc = 0, any = 0;; c = *s++) { if (!isascii(c)) break; if (isdigit(c)) c -= '0'; else if (isalpha(c)) c -= isupper(c) ? 'A' - 10 : 'a' - 10; else break; if (c >= base) break; if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) any = -1; else { any = 1; acc *= base; acc += c; } } if (any < 0) { acc = ULONG_MAX; errno = ERANGE; } else if (neg) acc = -acc; if (endptr != 0) DE_CONST(any ? s - 1 : nptr, *endptr); return (acc); } bind9-9.10.3.dfsg.P4/lib/isc/api0000644000470500017500000000026712664710322015416 0ustar lamontlamont# LIBINTERFACE ranges # 9.6: 50-59, 110-119 # 9.7: 60-79 # 9.8: 80-89, 120-129 # 9.9: 90-109 # 9.9-sub: 130-139 # 9.10: 140-149, 160-169 LIBINTERFACE = 160 LIBREVISION = 0 LIBAGE = 0 bind9-9.10.3.dfsg.P4/lib/isc/event.c0000644000470500017500000000564212664710322016211 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: event.c,v 1.21 2007/06/19 23:47:17 tbox Exp $ */ /*! * \file * \author Principal Author: Bob Halley */ #include #include #include #include /*** *** Events. ***/ static void destroy(isc_event_t *event) { isc_mem_t *mctx = event->ev_destroy_arg; isc_mem_put(mctx, event, event->ev_size); } isc_event_t * isc_event_allocate(isc_mem_t *mctx, void *sender, isc_eventtype_t type, isc_taskaction_t action, void *arg, size_t size) { isc_event_t *event; REQUIRE(size >= sizeof(struct isc_event)); REQUIRE(action != NULL); event = isc_mem_get(mctx, size); if (event == NULL) return (NULL); ISC_EVENT_INIT(event, size, 0, NULL, type, action, arg, sender, destroy, mctx); return (event); } isc_event_t * isc_event_constallocate(isc_mem_t *mctx, void *sender, isc_eventtype_t type, isc_taskaction_t action, const void *arg, size_t size) { isc_event_t *event; void *deconst_arg; REQUIRE(size >= sizeof(struct isc_event)); REQUIRE(action != NULL); event = isc_mem_get(mctx, size); if (event == NULL) return (NULL); /* * Removing the const attribute from "arg" is the best of two * evils here. If the event->ev_arg member is made const, then * it affects a great many users of the task/event subsystem * which are not passing in an "arg" which starts its life as * const. Changing isc_event_allocate() and isc_task_onshutdown() * to not have "arg" prototyped as const (which is quite legitimate, * because neither of those functions modify arg) can cause * compiler whining anytime someone does want to use a const * arg that they themselves never modify, such as with * gcc -Wwrite-strings and using a string "arg". */ DE_CONST(arg, deconst_arg); ISC_EVENT_INIT(event, size, 0, NULL, type, action, deconst_arg, sender, destroy, mctx); return (event); } void isc_event_free(isc_event_t **eventp) { isc_event_t *event; REQUIRE(eventp != NULL); event = *eventp; REQUIRE(event != NULL); if (event->ev_destroy != NULL) (event->ev_destroy)(event); *eventp = NULL; } bind9-9.10.3.dfsg.P4/lib/isc/taskpool.c0000644000470500017500000001072712664710322016724 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ /*! \file */ #include #include #include #include #include /*** *** Types. ***/ struct isc_taskpool { isc_mem_t * mctx; isc_taskmgr_t * tmgr; unsigned int ntasks; unsigned int quantum; isc_task_t ** tasks; }; /*** *** Functions. ***/ static isc_result_t alloc_pool(isc_taskmgr_t *tmgr, isc_mem_t *mctx, unsigned int ntasks, unsigned int quantum, isc_taskpool_t **poolp) { isc_taskpool_t *pool; unsigned int i; pool = isc_mem_get(mctx, sizeof(*pool)); if (pool == NULL) return (ISC_R_NOMEMORY); pool->mctx = NULL; isc_mem_attach(mctx, &pool->mctx); pool->ntasks = ntasks; pool->quantum = quantum; pool->tmgr = tmgr; pool->tasks = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *)); if (pool->tasks == NULL) { isc_mem_putanddetach(&pool->mctx, pool, sizeof(*pool)); return (ISC_R_NOMEMORY); } for (i = 0; i < ntasks; i++) pool->tasks[i] = NULL; *poolp = pool; return (ISC_R_SUCCESS); } isc_result_t isc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx, unsigned int ntasks, unsigned int quantum, isc_taskpool_t **poolp) { unsigned int i; isc_taskpool_t *pool = NULL; isc_result_t result; INSIST(ntasks > 0); /* Allocate the pool structure */ result = alloc_pool(tmgr, mctx, ntasks, quantum, &pool); if (result != ISC_R_SUCCESS) return (result); /* Create the tasks */ for (i = 0; i < ntasks; i++) { result = isc_task_create(tmgr, quantum, &pool->tasks[i]); if (result != ISC_R_SUCCESS) { isc_taskpool_destroy(&pool); return (result); } isc_task_setname(pool->tasks[i], "taskpool", NULL); } *poolp = pool; return (ISC_R_SUCCESS); } void isc_taskpool_gettask(isc_taskpool_t *pool, isc_task_t **targetp) { isc_uint32_t i; isc_random_get(&i); isc_task_attach(pool->tasks[i % pool->ntasks], targetp); } int isc_taskpool_size(isc_taskpool_t *pool) { REQUIRE(pool != NULL); return (pool->ntasks); } isc_result_t isc_taskpool_expand(isc_taskpool_t **sourcep, unsigned int size, isc_taskpool_t **targetp) { isc_result_t result; isc_taskpool_t *pool; REQUIRE(sourcep != NULL && *sourcep != NULL); REQUIRE(targetp != NULL && *targetp == NULL); pool = *sourcep; if (size > pool->ntasks) { isc_taskpool_t *newpool = NULL; unsigned int i; /* Allocate a new pool structure */ result = alloc_pool(pool->tmgr, pool->mctx, size, pool->quantum, &newpool); if (result != ISC_R_SUCCESS) return (result); /* Copy over the tasks from the old pool */ for (i = 0; i < pool->ntasks; i++) { newpool->tasks[i] = pool->tasks[i]; pool->tasks[i] = NULL; } /* Create new tasks */ for (i = pool->ntasks; i < size; i++) { result = isc_task_create(pool->tmgr, pool->quantum, &newpool->tasks[i]); if (result != ISC_R_SUCCESS) { isc_taskpool_destroy(&newpool); return (result); } isc_task_setname(newpool->tasks[i], "taskpool", NULL); } isc_taskpool_destroy(&pool); pool = newpool; } *sourcep = NULL; *targetp = pool; return (ISC_R_SUCCESS); } void isc_taskpool_destroy(isc_taskpool_t **poolp) { unsigned int i; isc_taskpool_t *pool = *poolp; for (i = 0; i < pool->ntasks; i++) { if (pool->tasks[i] != NULL) isc_task_detach(&pool->tasks[i]); } isc_mem_put(pool->mctx, pool->tasks, pool->ntasks * sizeof(isc_task_t *)); isc_mem_putanddetach(&pool->mctx, pool, sizeof(*pool)); *poolp = NULL; } void isc_taskpool_setprivilege(isc_taskpool_t *pool, isc_boolean_t priv) { unsigned int i; REQUIRE(pool != NULL); for (i = 0; i < pool->ntasks; i++) { if (pool->tasks[i] != NULL) isc_task_setprivilege(pool->tasks[i], priv); } } bind9-9.10.3.dfsg.P4/lib/isc/lfsr.c0000644000470500017500000000714412664710322016035 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lfsr.c,v 1.20 2007/06/19 23:47:17 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #define VALID_LFSR(x) (x != NULL) void isc_lfsr_init(isc_lfsr_t *lfsr, isc_uint32_t state, unsigned int bits, isc_uint32_t tap, unsigned int count, isc_lfsrreseed_t reseed, void *arg) { REQUIRE(VALID_LFSR(lfsr)); REQUIRE(8 <= bits && bits <= 32); REQUIRE(tap != 0); lfsr->state = state; lfsr->bits = bits; lfsr->tap = tap; lfsr->count = count; lfsr->reseed = reseed; lfsr->arg = arg; if (count == 0 && reseed != NULL) reseed(lfsr, arg); if (lfsr->state == 0) lfsr->state = 0xffffffffU >> (32 - lfsr->bits); } /*! * Return the next state of the lfsr. */ static inline isc_uint32_t lfsr_generate(isc_lfsr_t *lfsr) { /* * If the previous state is zero, we must fill it with something * here, or we will begin to generate an extremely predictable output. * * First, give the reseed function a crack at it. If the state is * still 0, set it to all ones. */ if (lfsr->state == 0) { if (lfsr->reseed != NULL) lfsr->reseed(lfsr, lfsr->arg); if (lfsr->state == 0) lfsr->state = 0xffffffffU >> (32 - lfsr->bits); } if (lfsr->state & 0x01) { lfsr->state = (lfsr->state >> 1) ^ lfsr->tap; return (1); } else { lfsr->state >>= 1; return (0); } } void isc_lfsr_generate(isc_lfsr_t *lfsr, void *data, unsigned int count) { unsigned char *p; unsigned int bit; unsigned int byte; REQUIRE(VALID_LFSR(lfsr)); REQUIRE(data != NULL); REQUIRE(count > 0); p = data; byte = count; while (byte--) { *p = 0; for (bit = 0; bit < 7; bit++) { *p |= lfsr_generate(lfsr); *p <<= 1; } *p |= lfsr_generate(lfsr); p++; } if (lfsr->count != 0 && lfsr->reseed != NULL) { if (lfsr->count <= count * 8) lfsr->reseed(lfsr, lfsr->arg); else lfsr->count -= (count * 8); } } static inline isc_uint32_t lfsr_skipgenerate(isc_lfsr_t *lfsr, unsigned int skip) { while (skip--) (void)lfsr_generate(lfsr); (void)lfsr_generate(lfsr); return (lfsr->state); } /* * Skip "skip" states in "lfsr". */ void isc_lfsr_skip(isc_lfsr_t *lfsr, unsigned int skip) { REQUIRE(VALID_LFSR(lfsr)); while (skip--) (void)lfsr_generate(lfsr); } /* * Skip states in lfsr1 and lfsr2 using the other's current state. * Return the final state of lfsr1 ^ lfsr2. */ isc_uint32_t isc_lfsr_generate32(isc_lfsr_t *lfsr1, isc_lfsr_t *lfsr2) { isc_uint32_t state1, state2; isc_uint32_t skip1, skip2; REQUIRE(VALID_LFSR(lfsr1)); REQUIRE(VALID_LFSR(lfsr2)); skip1 = lfsr1->state & 0x01; skip2 = lfsr2->state & 0x01; /* cross-skip. */ state1 = lfsr_skipgenerate(lfsr1, skip2); state2 = lfsr_skipgenerate(lfsr2, skip1); return (state1 ^ state2); } bind9-9.10.3.dfsg.P4/lib/isccc/0002755000470500017500000000000012672612753015235 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isccc/version.c0000644000470500017500000000217612664710322017062 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: version.c,v 1.7 2007/06/19 23:47:22 tbox Exp $ */ /*! \file */ #include const char isccc_version[] = VERSION; const unsigned int isccc_libinterface = LIBINTERFACE; const unsigned int isccc_librevision = LIBREVISION; const unsigned int isccc_libage = LIBAGE; bind9-9.10.3.dfsg.P4/lib/isccc/lib.c0000644000470500017500000000450412664710322016140 0ustar lamontlamont/* * Portions Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 2001 Nominum, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lib.c,v 1.9 2007/08/28 07:20:43 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include /*** *** Globals ***/ LIBISCCC_EXTERNAL_DATA isc_msgcat_t * isccc_msgcat = NULL; /*** *** Private ***/ static isc_once_t msgcat_once = ISC_ONCE_INIT; /*** *** Functions ***/ static void open_msgcat(void) { isc_msgcat_open("libisccc.cat", &isccc_msgcat); } void isccc_lib_initmsgcat(void) { /* * Initialize the DNS library's message catalog, isccc_msgcat, if it * has not already been initialized. */ RUNTIME_CHECK(isc_once_do(&msgcat_once, open_msgcat) == ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/isccc/base64.c0000644000470500017500000000547612664710322016467 0ustar lamontlamont/* * Portions Copyright (C) 2004, 2005, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 2001 Nominum, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: base64.c,v 1.8 2007/08/28 07:20:43 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include isc_result_t isccc_base64_encode(isccc_region_t *source, int wordlength, const char *wordbreak, isccc_region_t *target) { isc_region_t sr; isc_buffer_t tb; isc_result_t result; sr.base = source->rstart; sr.length = (unsigned int)(source->rend - source->rstart); isc_buffer_init(&tb, target->rstart, (unsigned int)(target->rend - target->rstart)); result = isc_base64_totext(&sr, wordlength, wordbreak, &tb); if (result != ISC_R_SUCCESS) return (result); source->rstart = source->rend; target->rstart = isc_buffer_used(&tb); return (ISC_R_SUCCESS); } isc_result_t isccc_base64_decode(const char *cstr, isccc_region_t *target) { isc_buffer_t b; isc_result_t result; isc_buffer_init(&b, target->rstart, (unsigned int)(target->rend - target->rstart)); result = isc_base64_decodestring(cstr, &b); if (result != ISC_R_SUCCESS) return (result); target->rstart = isc_buffer_used(&b); return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/isccc/result.c0000644000470500017500000000530512664710322016710 0ustar lamontlamont/* * Portions Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 2001 Nominum, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: result.c,v 1.10 2007/08/28 07:20:43 tbox Exp $ */ /*! \file */ #include #include #include #include #include static const char *text[ISCCC_R_NRESULTS] = { "unknown version", /* 1 */ "syntax error", /* 2 */ "bad auth", /* 3 */ "expired", /* 4 */ "clock skew", /* 5 */ "duplicate" /* 6 */ }; #define ISCCC_RESULT_RESULTSET 2 static isc_once_t once = ISC_ONCE_INIT; static void initialize_action(void) { isc_result_t result; result = isc_result_register(ISC_RESULTCLASS_ISCCC, ISCCC_R_NRESULTS, text, isccc_msgcat, ISCCC_RESULT_RESULTSET); if (result != ISC_R_SUCCESS) UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_result_register() failed: %u", result); } static void initialize(void) { isccc_lib_initmsgcat(); RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); } const char * isccc_result_totext(isc_result_t result) { initialize(); return (isc_result_totext(result)); } void isccc_result_register(void) { initialize(); } bind9-9.10.3.dfsg.P4/lib/isccc/sexpr.c0000644000470500017500000001671712664710322016544 0ustar lamontlamont/* * Portions Copyright (C) 2004, 2005, 2007, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 2001 Nominum, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: sexpr.c,v 1.9 2007/08/28 07:20:43 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include static isccc_sexpr_t sexpr_t = { ISCCC_SEXPRTYPE_T, { NULL } }; #define CAR(s) (s)->value.as_dottedpair.car #define CDR(s) (s)->value.as_dottedpair.cdr isccc_sexpr_t * isccc_sexpr_cons(isccc_sexpr_t *car, isccc_sexpr_t *cdr) { isccc_sexpr_t *sexpr; sexpr = malloc(sizeof(*sexpr)); if (sexpr == NULL) return (NULL); sexpr->type = ISCCC_SEXPRTYPE_DOTTEDPAIR; CAR(sexpr) = car; CDR(sexpr) = cdr; return (sexpr); } isccc_sexpr_t * isccc_sexpr_tconst(void) { return (&sexpr_t); } isccc_sexpr_t * isccc_sexpr_fromstring(const char *str) { isccc_sexpr_t *sexpr; sexpr = malloc(sizeof(*sexpr)); if (sexpr == NULL) return (NULL); sexpr->type = ISCCC_SEXPRTYPE_STRING; sexpr->value.as_string = strdup(str); if (sexpr->value.as_string == NULL) { free(sexpr); return (NULL); } return (sexpr); } isccc_sexpr_t * isccc_sexpr_frombinary(const isccc_region_t *region) { isccc_sexpr_t *sexpr; unsigned int region_size; sexpr = malloc(sizeof(*sexpr)); if (sexpr == NULL) return (NULL); sexpr->type = ISCCC_SEXPRTYPE_BINARY; region_size = REGION_SIZE(*region); /* * We add an extra byte when we malloc so we can NUL terminate * the binary data. This allows the caller to use it as a C * string. It's up to the caller to ensure this is safe. We don't * add 1 to the length of the binary region, because the NUL is * not part of the binary data. */ sexpr->value.as_region.rstart = malloc(region_size + 1); if (sexpr->value.as_region.rstart == NULL) { free(sexpr); return (NULL); } sexpr->value.as_region.rend = sexpr->value.as_region.rstart + region_size; memmove(sexpr->value.as_region.rstart, region->rstart, region_size); /* * NUL terminate. */ sexpr->value.as_region.rstart[region_size] = '\0'; return (sexpr); } void isccc_sexpr_free(isccc_sexpr_t **sexprp) { isccc_sexpr_t *sexpr; isccc_sexpr_t *item; sexpr = *sexprp; if (sexpr == NULL) return; switch (sexpr->type) { case ISCCC_SEXPRTYPE_STRING: free(sexpr->value.as_string); break; case ISCCC_SEXPRTYPE_DOTTEDPAIR: item = CAR(sexpr); if (item != NULL) isccc_sexpr_free(&item); item = CDR(sexpr); if (item != NULL) isccc_sexpr_free(&item); break; case ISCCC_SEXPRTYPE_BINARY: free(sexpr->value.as_region.rstart); break; } free(sexpr); *sexprp = NULL; } static isc_boolean_t printable(isccc_region_t *r) { unsigned char *curr; curr = r->rstart; while (curr != r->rend) { if (!isprint(*curr)) return (ISC_FALSE); curr++; } return (ISC_TRUE); } void isccc_sexpr_print(isccc_sexpr_t *sexpr, FILE *stream) { isccc_sexpr_t *cdr; unsigned int size, i; unsigned char *curr; if (sexpr == NULL) { fprintf(stream, "nil"); return; } switch (sexpr->type) { case ISCCC_SEXPRTYPE_T: fprintf(stream, "t"); break; case ISCCC_SEXPRTYPE_STRING: fprintf(stream, "\"%s\"", sexpr->value.as_string); break; case ISCCC_SEXPRTYPE_DOTTEDPAIR: fprintf(stream, "("); do { isccc_sexpr_print(CAR(sexpr), stream); cdr = CDR(sexpr); if (cdr != NULL) { fprintf(stream, " "); if (cdr->type != ISCCC_SEXPRTYPE_DOTTEDPAIR) { fprintf(stream, ". "); isccc_sexpr_print(cdr, stream); cdr = NULL; } } sexpr = cdr; } while (sexpr != NULL); fprintf(stream, ")"); break; case ISCCC_SEXPRTYPE_BINARY: size = REGION_SIZE(sexpr->value.as_region); curr = sexpr->value.as_region.rstart; if (printable(&sexpr->value.as_region)) { fprintf(stream, "'%.*s'", (int)size, curr); } else { fprintf(stream, "0x"); for (i = 0; i < size; i++) fprintf(stream, "%02x", *curr++); } break; default: INSIST(0); } } isccc_sexpr_t * isccc_sexpr_car(isccc_sexpr_t *list) { REQUIRE(list->type == ISCCC_SEXPRTYPE_DOTTEDPAIR); return (CAR(list)); } isccc_sexpr_t * isccc_sexpr_cdr(isccc_sexpr_t *list) { REQUIRE(list->type == ISCCC_SEXPRTYPE_DOTTEDPAIR); return (CDR(list)); } void isccc_sexpr_setcar(isccc_sexpr_t *pair, isccc_sexpr_t *car) { REQUIRE(pair->type == ISCCC_SEXPRTYPE_DOTTEDPAIR); CAR(pair) = car; } void isccc_sexpr_setcdr(isccc_sexpr_t *pair, isccc_sexpr_t *cdr) { REQUIRE(pair->type == ISCCC_SEXPRTYPE_DOTTEDPAIR); CDR(pair) = cdr; } isccc_sexpr_t * isccc_sexpr_addtolist(isccc_sexpr_t **l1p, isccc_sexpr_t *l2) { isccc_sexpr_t *last, *elt, *l1; REQUIRE(l1p != NULL); l1 = *l1p; REQUIRE(l1 == NULL || l1->type == ISCCC_SEXPRTYPE_DOTTEDPAIR); elt = isccc_sexpr_cons(l2, NULL); if (elt == NULL) return (NULL); if (l1 == NULL) { *l1p = elt; return (elt); } for (last = l1; CDR(last) != NULL; last = CDR(last)) /* Nothing */; CDR(last) = elt; return (elt); } isc_boolean_t isccc_sexpr_listp(isccc_sexpr_t *sexpr) { if (sexpr == NULL || sexpr->type == ISCCC_SEXPRTYPE_DOTTEDPAIR) return (ISC_TRUE); return (ISC_FALSE); } isc_boolean_t isccc_sexpr_emptyp(isccc_sexpr_t *sexpr) { if (sexpr == NULL) return (ISC_TRUE); return (ISC_FALSE); } isc_boolean_t isccc_sexpr_stringp(isccc_sexpr_t *sexpr) { if (sexpr != NULL && sexpr->type == ISCCC_SEXPRTYPE_STRING) return (ISC_TRUE); return (ISC_FALSE); } isc_boolean_t isccc_sexpr_binaryp(isccc_sexpr_t *sexpr) { if (sexpr != NULL && sexpr->type == ISCCC_SEXPRTYPE_BINARY) return (ISC_TRUE); return (ISC_FALSE); } char * isccc_sexpr_tostring(isccc_sexpr_t *sexpr) { REQUIRE(sexpr != NULL && (sexpr->type == ISCCC_SEXPRTYPE_STRING || sexpr->type == ISCCC_SEXPRTYPE_BINARY)); if (sexpr->type == ISCCC_SEXPRTYPE_BINARY) return ((char *)sexpr->value.as_region.rstart); return (sexpr->value.as_string); } isccc_region_t * isccc_sexpr_tobinary(isccc_sexpr_t *sexpr) { REQUIRE(sexpr != NULL && sexpr->type == ISCCC_SEXPRTYPE_BINARY); return (&sexpr->value.as_region); } bind9-9.10.3.dfsg.P4/lib/isccc/Makefile.in0000644000470500017500000000440612664710322017274 0ustar lamontlamont# Copyright (C) 2004, 2007, 2009, 2011, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001, 2003 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id$ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ @LIBISCCC_API@ @BIND9_MAKE_INCLUDES@ CINCLUDES = -I. ${DNS_INCLUDES} ${ISC_INCLUDES} ${ISCCC_INCLUDES} @ISC_OPENSSL_INC@ CDEFINES = CWARNINGS = ISCLIBS = ../../lib/isc/libisc.@A@ ISCCCLIBS = ../../lib/isccc/libisccc.@A@ ISCDEPLIBS = ../../lib/isc/libisc.@A@ ISCCCDEPLIBS = libisccc.@A@ LIBS = @LIBS@ SUBDIRS = include # Alphabetically OBJS = alist.@O@ base64.@O@ cc.@O@ ccmsg.@O@ \ lib.@O@ \ result.@O@ sexpr.@O@ symtab.@O@ version.@O@ # Alphabetically SRCS = alist.c base64.c cc.c ccmsg.c \ lib.c \ result.c sexpr.c symtab.c version.c TARGETS = timestamp @BIND9_MAKE_RULES@ version.@O@: version.c ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ -DVERSION=\"${VERSION}\" \ -DLIBINTERFACE=${LIBINTERFACE} \ -DLIBREVISION=${LIBREVISION} \ -DLIBAGE=${LIBAGE} \ -c ${srcdir}/version.c libisccc.@SA@: ${OBJS} ${AR} ${ARFLAGS} $@ ${OBJS} ${RANLIB} $@ libisccc.la: ${OBJS} ${LIBTOOL_MODE_LINK} \ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisccc.la -rpath ${libdir} \ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \ ${OBJS} ${ISCLIBS} ${LIBS} timestamp: libisccc.@A@ touch timestamp installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${libdir} install:: timestamp installdirs ${LIBTOOL_MODE_INSTALL} ${INSTALL_LIBRARY} libisccc.@A@ ${DESTDIR}${libdir} clean distclean:: rm -f libisccc.@A@ timestamp bind9-9.10.3.dfsg.P4/lib/isccc/symtab.c0000644000470500017500000001641412664710322016674 0ustar lamontlamont/* * Portions Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 2001 Nominum, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: symtab.c,v 1.11 2007/09/13 04:45:18 each Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include typedef struct elt { char * key; unsigned int type; isccc_symvalue_t value; ISC_LINK(struct elt) link; } elt_t; typedef ISC_LIST(elt_t) eltlist_t; #define SYMTAB_MAGIC ISC_MAGIC('S', 'y', 'm', 'T') #define VALID_SYMTAB(st) ISC_MAGIC_VALID(st, SYMTAB_MAGIC) struct isccc_symtab { unsigned int magic; unsigned int size; eltlist_t * table; isccc_symtabundefaction_t undefine_action; void * undefine_arg; isc_boolean_t case_sensitive; }; isc_result_t isccc_symtab_create(unsigned int size, isccc_symtabundefaction_t undefine_action, void *undefine_arg, isc_boolean_t case_sensitive, isccc_symtab_t **symtabp) { isccc_symtab_t *symtab; unsigned int i; REQUIRE(symtabp != NULL && *symtabp == NULL); REQUIRE(size > 0); /* Should be prime. */ symtab = malloc(sizeof(*symtab)); if (symtab == NULL) return (ISC_R_NOMEMORY); symtab->table = malloc(size * sizeof(eltlist_t)); if (symtab->table == NULL) { free(symtab); return (ISC_R_NOMEMORY); } for (i = 0; i < size; i++) ISC_LIST_INIT(symtab->table[i]); symtab->size = size; symtab->undefine_action = undefine_action; symtab->undefine_arg = undefine_arg; symtab->case_sensitive = case_sensitive; symtab->magic = SYMTAB_MAGIC; *symtabp = symtab; return (ISC_R_SUCCESS); } static inline void free_elt(isccc_symtab_t *symtab, unsigned int bucket, elt_t *elt) { ISC_LIST_UNLINK(symtab->table[bucket], elt, link); if (symtab->undefine_action != NULL) (symtab->undefine_action)(elt->key, elt->type, elt->value, symtab->undefine_arg); free(elt); } void isccc_symtab_destroy(isccc_symtab_t **symtabp) { isccc_symtab_t *symtab; unsigned int i; elt_t *elt, *nelt; REQUIRE(symtabp != NULL); symtab = *symtabp; REQUIRE(VALID_SYMTAB(symtab)); for (i = 0; i < symtab->size; i++) { for (elt = ISC_LIST_HEAD(symtab->table[i]); elt != NULL; elt = nelt) { nelt = ISC_LIST_NEXT(elt, link); free_elt(symtab, i, elt); } } free(symtab->table); symtab->magic = 0; free(symtab); *symtabp = NULL; } static inline unsigned int hash(const char *key, isc_boolean_t case_sensitive) { const char *s; unsigned int h = 0; unsigned int g; int c; /* * P. J. Weinberger's hash function, adapted from p. 436 of * _Compilers: Principles, Techniques, and Tools_, Aho, Sethi * and Ullman, Addison-Wesley, 1986, ISBN 0-201-10088-6. */ if (case_sensitive) { for (s = key; *s != '\0'; s++) { h = ( h << 4 ) + *s; if ((g = ( h & 0xf0000000 )) != 0) { h = h ^ (g >> 24); h = h ^ g; } } } else { for (s = key; *s != '\0'; s++) { c = *s; c = tolower((unsigned char)c); h = ( h << 4 ) + c; if ((g = ( h & 0xf0000000 )) != 0) { h = h ^ (g >> 24); h = h ^ g; } } } return (h); } #define FIND(s, k, t, b, e) \ b = hash((k), (s)->case_sensitive) % (s)->size; \ if ((s)->case_sensitive) { \ for (e = ISC_LIST_HEAD((s)->table[b]); \ e != NULL; \ e = ISC_LIST_NEXT(e, link)) { \ if (((t) == 0 || e->type == (t)) && \ strcmp(e->key, (k)) == 0) \ break; \ } \ } else { \ for (e = ISC_LIST_HEAD((s)->table[b]); \ e != NULL; \ e = ISC_LIST_NEXT(e, link)) { \ if (((t) == 0 || e->type == (t)) && \ strcasecmp(e->key, (k)) == 0) \ break; \ } \ } isc_result_t isccc_symtab_lookup(isccc_symtab_t *symtab, const char *key, unsigned int type, isccc_symvalue_t *value) { unsigned int bucket; elt_t *elt; REQUIRE(VALID_SYMTAB(symtab)); REQUIRE(key != NULL); FIND(symtab, key, type, bucket, elt); if (elt == NULL) return (ISC_R_NOTFOUND); if (value != NULL) *value = elt->value; return (ISC_R_SUCCESS); } isc_result_t isccc_symtab_define(isccc_symtab_t *symtab, char *key, unsigned int type, isccc_symvalue_t value, isccc_symexists_t exists_policy) { unsigned int bucket; elt_t *elt; REQUIRE(VALID_SYMTAB(symtab)); REQUIRE(key != NULL); REQUIRE(type != 0); FIND(symtab, key, type, bucket, elt); if (exists_policy != isccc_symexists_add && elt != NULL) { if (exists_policy == isccc_symexists_reject) return (ISC_R_EXISTS); INSIST(exists_policy == isccc_symexists_replace); ISC_LIST_UNLINK(symtab->table[bucket], elt, link); if (symtab->undefine_action != NULL) (symtab->undefine_action)(elt->key, elt->type, elt->value, symtab->undefine_arg); } else { elt = malloc(sizeof(*elt)); if (elt == NULL) return (ISC_R_NOMEMORY); ISC_LINK_INIT(elt, link); } elt->key = key; elt->type = type; elt->value = value; /* * We prepend so that the most recent definition will be found. */ ISC_LIST_PREPEND(symtab->table[bucket], elt, link); return (ISC_R_SUCCESS); } isc_result_t isccc_symtab_undefine(isccc_symtab_t *symtab, const char *key, unsigned int type) { unsigned int bucket; elt_t *elt; REQUIRE(VALID_SYMTAB(symtab)); REQUIRE(key != NULL); FIND(symtab, key, type, bucket, elt); if (elt == NULL) return (ISC_R_NOTFOUND); free_elt(symtab, bucket, elt); return (ISC_R_SUCCESS); } void isccc_symtab_foreach(isccc_symtab_t *symtab, isccc_symtabforeachaction_t action, void *arg) { unsigned int i; elt_t *elt, *nelt; REQUIRE(VALID_SYMTAB(symtab)); REQUIRE(action != NULL); for (i = 0; i < symtab->size; i++) { for (elt = ISC_LIST_HEAD(symtab->table[i]); elt != NULL; elt = nelt) { nelt = ISC_LIST_NEXT(elt, link); if ((action)(elt->key, elt->type, elt->value, arg)) free_elt(symtab, i, elt); } } } bind9-9.10.3.dfsg.P4/lib/isccc/cc.c0000644000470500017500000006367412664710322015774 0ustar lamontlamont/* * Portions Copyright (C) 2004-2007, 2012, 2013, 2015, 2016 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2001-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 2001 Nominum, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: cc.c,v 1.18 2007/08/28 07:20:43 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_TAGS 256 #define DUP_LIFETIME 900 typedef isccc_sexpr_t *sexpr_ptr; static unsigned char auth_hmd5[] = { 0x05, 0x5f, 0x61, 0x75, 0x74, 0x68, /*%< len + _auth */ ISCCC_CCMSGTYPE_TABLE, /*%< message type */ 0x00, 0x00, 0x00, 0x20, /*%< length == 32 */ 0x04, 0x68, 0x6d, 0x64, 0x35, /*%< len + hmd5 */ ISCCC_CCMSGTYPE_BINARYDATA, /*%< message type */ 0x00, 0x00, 0x00, 0x16, /*%< length == 22 */ /* * The base64 encoding of one of our HMAC-MD5 signatures is * 22 bytes. */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; #define HMD5_OFFSET 21 /*%< 21 = 6 + 1 + 4 + 5 + 1 + 4 */ #define HMD5_LENGTH 22 static unsigned char auth_hsha[] = { 0x05, 0x5f, 0x61, 0x75, 0x74, 0x68, /*%< len + _auth */ ISCCC_CCMSGTYPE_TABLE, /*%< message type */ 0x00, 0x00, 0x00, 0x63, /*%< length == 99 */ 0x04, 0x68, 0x73, 0x68, 0x61, /*%< len + hsha */ ISCCC_CCMSGTYPE_BINARYDATA, /*%< message type */ 0x00, 0x00, 0x00, 0x59, /*%< length == 89 */ 0x00, /*%< algorithm */ /* * The base64 encoding of one of our HMAC-SHA* signatures is * 88 bytes. */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; #define HSHA_OFFSET 22 /*%< 21 = 6 + 1 + 4 + 5 + 1 + 4 + 1 */ #define HSHA_LENGTH 88 static isc_result_t table_towire(isccc_sexpr_t *alist, isccc_region_t *target); static isc_result_t list_towire(isccc_sexpr_t *alist, isccc_region_t *target); static isc_result_t value_towire(isccc_sexpr_t *elt, isccc_region_t *target) { unsigned int len; unsigned char *lenp; isccc_region_t *vr; isc_result_t result; if (isccc_sexpr_binaryp(elt)) { vr = isccc_sexpr_tobinary(elt); len = REGION_SIZE(*vr); if (REGION_SIZE(*target) < 1 + 4 + len) return (ISC_R_NOSPACE); PUT8(ISCCC_CCMSGTYPE_BINARYDATA, target->rstart); PUT32(len, target->rstart); if (REGION_SIZE(*target) < len) return (ISC_R_NOSPACE); PUT_MEM(vr->rstart, len, target->rstart); } else if (isccc_alist_alistp(elt)) { if (REGION_SIZE(*target) < 1 + 4) return (ISC_R_NOSPACE); PUT8(ISCCC_CCMSGTYPE_TABLE, target->rstart); /* * Emit a placeholder length. */ lenp = target->rstart; PUT32(0, target->rstart); /* * Emit the table. */ result = table_towire(elt, target); if (result != ISC_R_SUCCESS) return (result); len = (unsigned int)(target->rstart - lenp); /* * 'len' is 4 bytes too big, since it counts * the placeholder length too. Adjust and * emit. */ INSIST(len >= 4U); len -= 4; PUT32(len, lenp); } else if (isccc_sexpr_listp(elt)) { if (REGION_SIZE(*target) < 1 + 4) return (ISC_R_NOSPACE); PUT8(ISCCC_CCMSGTYPE_LIST, target->rstart); /* * Emit a placeholder length and count. */ lenp = target->rstart; PUT32(0, target->rstart); /* * Emit the list. */ result = list_towire(elt, target); if (result != ISC_R_SUCCESS) return (result); len = (unsigned int)(target->rstart - lenp); /* * 'len' is 4 bytes too big, since it counts * the placeholder length. Adjust and emit. */ INSIST(len >= 4U); len -= 4; PUT32(len, lenp); } return (ISC_R_SUCCESS); } static isc_result_t table_towire(isccc_sexpr_t *alist, isccc_region_t *target) { isccc_sexpr_t *kv, *elt, *k, *v; char *ks; isc_result_t result; unsigned int len; for (elt = isccc_alist_first(alist); elt != NULL; elt = ISCCC_SEXPR_CDR(elt)) { kv = ISCCC_SEXPR_CAR(elt); k = ISCCC_SEXPR_CAR(kv); ks = isccc_sexpr_tostring(k); v = ISCCC_SEXPR_CDR(kv); len = (unsigned int)strlen(ks); INSIST(len <= 255U); /* * Emit the key name. */ if (REGION_SIZE(*target) < 1 + len) return (ISC_R_NOSPACE); PUT8(len, target->rstart); PUT_MEM(ks, len, target->rstart); /* * Emit the value. */ result = value_towire(v, target); if (result != ISC_R_SUCCESS) return (result); } return (ISC_R_SUCCESS); } static isc_result_t list_towire(isccc_sexpr_t *list, isccc_region_t *target) { isc_result_t result; while (list != NULL) { result = value_towire(ISCCC_SEXPR_CAR(list), target); if (result != ISC_R_SUCCESS) return (result); list = ISCCC_SEXPR_CDR(list); } return (ISC_R_SUCCESS); } static isc_result_t sign(unsigned char *data, unsigned int length, unsigned char *hmac, isc_uint32_t algorithm, isccc_region_t *secret) { union { isc_hmacmd5_t hmd5; isc_hmacsha1_t hsha; isc_hmacsha224_t h224; isc_hmacsha256_t h256; isc_hmacsha384_t h384; isc_hmacsha512_t h512; } ctx; isc_result_t result; isccc_region_t source, target; unsigned char digest[ISC_SHA512_DIGESTLENGTH]; unsigned char digestb64[HSHA_LENGTH + 4]; source.rstart = digest; switch (algorithm) { case ISCCC_ALG_HMACMD5: isc_hmacmd5_init(&ctx.hmd5, secret->rstart, REGION_SIZE(*secret)); isc_hmacmd5_update(&ctx.hmd5, data, length); isc_hmacmd5_sign(&ctx.hmd5, digest); source.rend = digest + ISC_MD5_DIGESTLENGTH; break; case ISCCC_ALG_HMACSHA1: isc_hmacsha1_init(&ctx.hsha, secret->rstart, REGION_SIZE(*secret)); isc_hmacsha1_update(&ctx.hsha, data, length); isc_hmacsha1_sign(&ctx.hsha, digest, ISC_SHA1_DIGESTLENGTH); source.rend = digest + ISC_SHA1_DIGESTLENGTH; break; case ISCCC_ALG_HMACSHA224: isc_hmacsha224_init(&ctx.h224, secret->rstart, REGION_SIZE(*secret)); isc_hmacsha224_update(&ctx.h224, data, length); isc_hmacsha224_sign(&ctx.h224, digest, ISC_SHA224_DIGESTLENGTH); source.rend = digest + ISC_SHA224_DIGESTLENGTH; break; case ISCCC_ALG_HMACSHA256: isc_hmacsha256_init(&ctx.h256, secret->rstart, REGION_SIZE(*secret)); isc_hmacsha256_update(&ctx.h256, data, length); isc_hmacsha256_sign(&ctx.h256, digest, ISC_SHA256_DIGESTLENGTH); source.rend = digest + ISC_SHA256_DIGESTLENGTH; break; case ISCCC_ALG_HMACSHA384: isc_hmacsha384_init(&ctx.h384, secret->rstart, REGION_SIZE(*secret)); isc_hmacsha384_update(&ctx.h384, data, length); isc_hmacsha384_sign(&ctx.h384, digest, ISC_SHA384_DIGESTLENGTH); source.rend = digest + ISC_SHA384_DIGESTLENGTH; break; case ISCCC_ALG_HMACSHA512: isc_hmacsha512_init(&ctx.h512, secret->rstart, REGION_SIZE(*secret)); isc_hmacsha512_update(&ctx.h512, data, length); isc_hmacsha512_sign(&ctx.h512, digest, ISC_SHA512_DIGESTLENGTH); source.rend = digest + ISC_SHA512_DIGESTLENGTH; break; default: return (ISC_R_FAILURE); } memset(digestb64, 0, sizeof(digestb64)); target.rstart = digestb64; target.rend = digestb64 + sizeof(digestb64); result = isccc_base64_encode(&source, 64, "", &target); if (result != ISC_R_SUCCESS) return (result); if (algorithm == ISCCC_ALG_HMACMD5) PUT_MEM(digestb64, HMD5_LENGTH, hmac); else PUT_MEM(digestb64, HSHA_LENGTH, hmac); return (ISC_R_SUCCESS); } isc_result_t isccc_cc_towire(isccc_sexpr_t *alist, isccc_region_t *target, isc_uint32_t algorithm, isccc_region_t *secret) { unsigned char *hmac_rstart, *signed_rstart; isc_result_t result; if (algorithm == ISCCC_ALG_HMACMD5) { if (REGION_SIZE(*target) < 4 + sizeof(auth_hmd5)) return (ISC_R_NOSPACE); } else { if (REGION_SIZE(*target) < 4 + sizeof(auth_hsha)) return (ISC_R_NOSPACE); } /* * Emit protocol version. */ PUT32(1, target->rstart); if (secret != NULL) { /* * Emit _auth section with zeroed HMAC signature. * We'll replace the zeros with the real signature once * we know what it is. */ if (algorithm == ISCCC_ALG_HMACMD5) { hmac_rstart = target->rstart + HMD5_OFFSET; PUT_MEM(auth_hmd5, sizeof(auth_hmd5), target->rstart); } else { unsigned char *hmac_alg; hmac_rstart = target->rstart + HSHA_OFFSET; hmac_alg = hmac_rstart - 1; PUT_MEM(auth_hsha, sizeof(auth_hsha), target->rstart); PUT8(algorithm, hmac_alg); } } else hmac_rstart = NULL; signed_rstart = target->rstart; /* * Delete any existing _auth section so that we don't try * to encode it. */ isccc_alist_delete(alist, "_auth"); /* * Emit the message. */ result = table_towire(alist, target); if (result != ISC_R_SUCCESS) return (result); if (secret != NULL) return (sign(signed_rstart, (unsigned int)(target->rstart - signed_rstart), hmac_rstart, algorithm, secret)); return (ISC_R_SUCCESS); } static isc_result_t verify(isccc_sexpr_t *alist, unsigned char *data, unsigned int length, isc_uint32_t algorithm, isccc_region_t *secret) { union { isc_hmacmd5_t hmd5; isc_hmacsha1_t hsha; isc_hmacsha224_t h224; isc_hmacsha256_t h256; isc_hmacsha384_t h384; isc_hmacsha512_t h512; } ctx; isccc_region_t source; isccc_region_t target; isc_result_t result; isccc_sexpr_t *_auth, *hmac; unsigned char digest[ISC_SHA512_DIGESTLENGTH]; unsigned char digestb64[HSHA_LENGTH * 4]; /* * Extract digest. */ _auth = isccc_alist_lookup(alist, "_auth"); if (!isccc_alist_alistp(_auth)) return (ISC_R_FAILURE); if (algorithm == ISCCC_ALG_HMACMD5) hmac = isccc_alist_lookup(_auth, "hmd5"); else hmac = isccc_alist_lookup(_auth, "hsha"); if (!isccc_sexpr_binaryp(hmac)) return (ISC_R_FAILURE); /* * Compute digest. */ source.rstart = digest; target.rstart = digestb64; switch (algorithm) { case ISCCC_ALG_HMACMD5: isc_hmacmd5_init(&ctx.hmd5, secret->rstart, REGION_SIZE(*secret)); isc_hmacmd5_update(&ctx.hmd5, data, length); isc_hmacmd5_sign(&ctx.hmd5, digest); source.rend = digest + ISC_MD5_DIGESTLENGTH; break; case ISCCC_ALG_HMACSHA1: isc_hmacsha1_init(&ctx.hsha, secret->rstart, REGION_SIZE(*secret)); isc_hmacsha1_update(&ctx.hsha, data, length); isc_hmacsha1_sign(&ctx.hsha, digest, ISC_SHA1_DIGESTLENGTH); source.rend = digest + ISC_SHA1_DIGESTLENGTH; break; case ISCCC_ALG_HMACSHA224: isc_hmacsha224_init(&ctx.h224, secret->rstart, REGION_SIZE(*secret)); isc_hmacsha224_update(&ctx.h224, data, length); isc_hmacsha224_sign(&ctx.h224, digest, ISC_SHA224_DIGESTLENGTH); source.rend = digest + ISC_SHA224_DIGESTLENGTH; break; case ISCCC_ALG_HMACSHA256: isc_hmacsha256_init(&ctx.h256, secret->rstart, REGION_SIZE(*secret)); isc_hmacsha256_update(&ctx.h256, data, length); isc_hmacsha256_sign(&ctx.h256, digest, ISC_SHA256_DIGESTLENGTH); source.rend = digest + ISC_SHA256_DIGESTLENGTH; break; case ISCCC_ALG_HMACSHA384: isc_hmacsha384_init(&ctx.h384, secret->rstart, REGION_SIZE(*secret)); isc_hmacsha384_update(&ctx.h384, data, length); isc_hmacsha384_sign(&ctx.h384, digest, ISC_SHA384_DIGESTLENGTH); source.rend = digest + ISC_SHA384_DIGESTLENGTH; break; case ISCCC_ALG_HMACSHA512: isc_hmacsha512_init(&ctx.h512, secret->rstart, REGION_SIZE(*secret)); isc_hmacsha512_update(&ctx.h512, data, length); isc_hmacsha512_sign(&ctx.h512, digest, ISC_SHA512_DIGESTLENGTH); source.rend = digest + ISC_SHA512_DIGESTLENGTH; break; default: return (ISC_R_FAILURE); } target.rstart = digestb64; target.rend = digestb64 + sizeof(digestb64); memset(digestb64, 0, sizeof(digestb64)); result = isccc_base64_encode(&source, 64, "", &target); if (result != ISC_R_SUCCESS) return (result); /* * Verify. */ if (algorithm == ISCCC_ALG_HMACMD5) { unsigned char *value; value = (unsigned char *) isccc_sexpr_tostring(hmac); if (!isc_safe_memequal(value, digestb64, HMD5_LENGTH)) return (ISCCC_R_BADAUTH); } else { unsigned char *value; isc_uint32_t valalg; value = (unsigned char *) isccc_sexpr_tostring(hmac); GET8(valalg, value); if ((valalg != algorithm) || !isc_safe_memequal(value, digestb64, HSHA_LENGTH)) return (ISCCC_R_BADAUTH); } return (ISC_R_SUCCESS); } static isc_result_t table_fromwire(isccc_region_t *source, isccc_region_t *secret, isc_uint32_t algorithm, isccc_sexpr_t **alistp); static isc_result_t list_fromwire(isccc_region_t *source, isccc_sexpr_t **listp); static isc_result_t value_fromwire(isccc_region_t *source, isccc_sexpr_t **valuep) { unsigned int msgtype; isc_uint32_t len; isccc_sexpr_t *value; isccc_region_t active; isc_result_t result; if (REGION_SIZE(*source) < 1 + 4) return (ISC_R_UNEXPECTEDEND); GET8(msgtype, source->rstart); GET32(len, source->rstart); if (REGION_SIZE(*source) < len) return (ISC_R_UNEXPECTEDEND); active.rstart = source->rstart; active.rend = active.rstart + len; source->rstart = active.rend; if (msgtype == ISCCC_CCMSGTYPE_BINARYDATA) { value = isccc_sexpr_frombinary(&active); if (value != NULL) { *valuep = value; result = ISC_R_SUCCESS; } else result = ISC_R_NOMEMORY; } else if (msgtype == ISCCC_CCMSGTYPE_TABLE) result = table_fromwire(&active, NULL, 0, valuep); else if (msgtype == ISCCC_CCMSGTYPE_LIST) result = list_fromwire(&active, valuep); else result = ISCCC_R_SYNTAX; return (result); } static isc_result_t table_fromwire(isccc_region_t *source, isccc_region_t *secret, isc_uint32_t algorithm, isccc_sexpr_t **alistp) { char key[256]; isc_uint32_t len; isc_result_t result; isccc_sexpr_t *alist, *value; isc_boolean_t first_tag; unsigned char *checksum_rstart; REQUIRE(alistp != NULL && *alistp == NULL); checksum_rstart = NULL; first_tag = ISC_TRUE; alist = isccc_alist_create(); if (alist == NULL) return (ISC_R_NOMEMORY); while (!REGION_EMPTY(*source)) { GET8(len, source->rstart); if (REGION_SIZE(*source) < len) { result = ISC_R_UNEXPECTEDEND; goto bad; } GET_MEM(key, len, source->rstart); key[len] = '\0'; /* Ensure NUL termination. */ value = NULL; result = value_fromwire(source, &value); if (result != ISC_R_SUCCESS) goto bad; if (isccc_alist_define(alist, key, value) == NULL) { result = ISC_R_NOMEMORY; goto bad; } if (first_tag && secret != NULL && strcmp(key, "_auth") == 0) checksum_rstart = source->rstart; first_tag = ISC_FALSE; } if (secret != NULL) { if (checksum_rstart != NULL) result = verify(alist, checksum_rstart, (unsigned int) (source->rend - checksum_rstart), algorithm, secret); else result = ISCCC_R_BADAUTH; } else result = ISC_R_SUCCESS; bad: if (result == ISC_R_SUCCESS) *alistp = alist; else isccc_sexpr_free(&alist); return (result); } static isc_result_t list_fromwire(isccc_region_t *source, isccc_sexpr_t **listp) { isccc_sexpr_t *list, *value; isc_result_t result; list = NULL; while (!REGION_EMPTY(*source)) { value = NULL; result = value_fromwire(source, &value); if (result != ISC_R_SUCCESS) { isccc_sexpr_free(&list); return (result); } if (isccc_sexpr_addtolist(&list, value) == NULL) { isccc_sexpr_free(&value); isccc_sexpr_free(&list); return (result); } } *listp = list; return (ISC_R_SUCCESS); } isc_result_t isccc_cc_fromwire(isccc_region_t *source, isccc_sexpr_t **alistp, isc_uint32_t algorithm, isccc_region_t *secret) { unsigned int size; isc_uint32_t version; size = REGION_SIZE(*source); if (size < 4) return (ISC_R_UNEXPECTEDEND); GET32(version, source->rstart); if (version != 1) return (ISCCC_R_UNKNOWNVERSION); return (table_fromwire(source, secret, algorithm, alistp)); } static isc_result_t createmessage(isc_uint32_t version, const char *from, const char *to, isc_uint32_t serial, isccc_time_t now, isccc_time_t expires, isccc_sexpr_t **alistp, isc_boolean_t want_expires) { isccc_sexpr_t *alist, *_ctrl, *_data; isc_result_t result; REQUIRE(alistp != NULL && *alistp == NULL); if (version != 1) return (ISCCC_R_UNKNOWNVERSION); alist = isccc_alist_create(); if (alist == NULL) return (ISC_R_NOMEMORY); result = ISC_R_NOMEMORY; _ctrl = isccc_alist_create(); if (_ctrl == NULL) goto bad; if (isccc_alist_define(alist, "_ctrl", _ctrl) == NULL) { isccc_sexpr_free(&_ctrl); goto bad; } _data = isccc_alist_create(); if (_data == NULL) goto bad; if (isccc_alist_define(alist, "_data", _data) == NULL) { isccc_sexpr_free(&_data); goto bad; } if (isccc_cc_defineuint32(_ctrl, "_ser", serial) == NULL || isccc_cc_defineuint32(_ctrl, "_tim", now) == NULL || (want_expires && isccc_cc_defineuint32(_ctrl, "_exp", expires) == NULL)) goto bad; if (from != NULL && isccc_cc_definestring(_ctrl, "_frm", from) == NULL) goto bad; if (to != NULL && isccc_cc_definestring(_ctrl, "_to", to) == NULL) goto bad; *alistp = alist; return (ISC_R_SUCCESS); bad: isccc_sexpr_free(&alist); return (result); } isc_result_t isccc_cc_createmessage(isc_uint32_t version, const char *from, const char *to, isc_uint32_t serial, isccc_time_t now, isccc_time_t expires, isccc_sexpr_t **alistp) { return (createmessage(version, from, to, serial, now, expires, alistp, ISC_TRUE)); } isc_result_t isccc_cc_createack(isccc_sexpr_t *message, isc_boolean_t ok, isccc_sexpr_t **ackp) { char *_frm, *_to; isc_uint32_t serial; isccc_sexpr_t *ack, *_ctrl; isc_result_t result; isccc_time_t t; REQUIRE(ackp != NULL && *ackp == NULL); _ctrl = isccc_alist_lookup(message, "_ctrl"); if (!isccc_alist_alistp(_ctrl) || isccc_cc_lookupuint32(_ctrl, "_ser", &serial) != ISC_R_SUCCESS || isccc_cc_lookupuint32(_ctrl, "_tim", &t) != ISC_R_SUCCESS) return (ISC_R_FAILURE); /* * _frm and _to are optional. */ _frm = NULL; (void)isccc_cc_lookupstring(_ctrl, "_frm", &_frm); _to = NULL; (void)isccc_cc_lookupstring(_ctrl, "_to", &_to); /* * Create the ack. */ ack = NULL; result = createmessage(1, _to, _frm, serial, t, 0, &ack, ISC_FALSE); if (result != ISC_R_SUCCESS) return (result); _ctrl = isccc_alist_lookup(ack, "_ctrl"); if (_ctrl == NULL) { result = ISC_R_FAILURE; goto bad; } if (isccc_cc_definestring(ack, "_ack", (ok) ? "1" : "0") == NULL) { result = ISC_R_NOMEMORY; goto bad; } *ackp = ack; return (ISC_R_SUCCESS); bad: isccc_sexpr_free(&ack); return (result); } isc_boolean_t isccc_cc_isack(isccc_sexpr_t *message) { isccc_sexpr_t *_ctrl; _ctrl = isccc_alist_lookup(message, "_ctrl"); if (!isccc_alist_alistp(_ctrl)) return (ISC_FALSE); if (isccc_cc_lookupstring(_ctrl, "_ack", NULL) == ISC_R_SUCCESS) return (ISC_TRUE); return (ISC_FALSE); } isc_boolean_t isccc_cc_isreply(isccc_sexpr_t *message) { isccc_sexpr_t *_ctrl; _ctrl = isccc_alist_lookup(message, "_ctrl"); if (!isccc_alist_alistp(_ctrl)) return (ISC_FALSE); if (isccc_cc_lookupstring(_ctrl, "_rpl", NULL) == ISC_R_SUCCESS) return (ISC_TRUE); return (ISC_FALSE); } isc_result_t isccc_cc_createresponse(isccc_sexpr_t *message, isccc_time_t now, isccc_time_t expires, isccc_sexpr_t **alistp) { char *_frm, *_to, *type = NULL; isc_uint32_t serial; isccc_sexpr_t *alist, *_ctrl, *_data; isc_result_t result; REQUIRE(alistp != NULL && *alistp == NULL); _ctrl = isccc_alist_lookup(message, "_ctrl"); _data = isccc_alist_lookup(message, "_data"); if (!isccc_alist_alistp(_ctrl) || !isccc_alist_alistp(_data) || isccc_cc_lookupuint32(_ctrl, "_ser", &serial) != ISC_R_SUCCESS || isccc_cc_lookupstring(_data, "type", &type) != ISC_R_SUCCESS) return (ISC_R_FAILURE); /* * _frm and _to are optional. */ _frm = NULL; (void)isccc_cc_lookupstring(_ctrl, "_frm", &_frm); _to = NULL; (void)isccc_cc_lookupstring(_ctrl, "_to", &_to); /* * Create the response. */ alist = NULL; result = isccc_cc_createmessage(1, _to, _frm, serial, now, expires, &alist); if (result != ISC_R_SUCCESS) return (result); _ctrl = isccc_alist_lookup(alist, "_ctrl"); if (_ctrl == NULL) { result = ISC_R_FAILURE; goto bad; } _data = isccc_alist_lookup(alist, "_data"); if (_data == NULL) { result = ISC_R_FAILURE; goto bad; } if (isccc_cc_definestring(_ctrl, "_rpl", "1") == NULL || isccc_cc_definestring(_data, "type", type) == NULL) { result = ISC_R_NOMEMORY; goto bad; } *alistp = alist; return (ISC_R_SUCCESS); bad: isccc_sexpr_free(&alist); return (result); } isccc_sexpr_t * isccc_cc_definestring(isccc_sexpr_t *alist, const char *key, const char *str) { size_t len; isccc_region_t r; len = strlen(str); DE_CONST(str, r.rstart); r.rend = r.rstart + len; return (isccc_alist_definebinary(alist, key, &r)); } isccc_sexpr_t * isccc_cc_defineuint32(isccc_sexpr_t *alist, const char *key, isc_uint32_t i) { char b[100]; size_t len; isccc_region_t r; snprintf(b, sizeof(b), "%u", i); len = strlen(b); r.rstart = (unsigned char *)b; r.rend = (unsigned char *)b + len; return (isccc_alist_definebinary(alist, key, &r)); } isc_result_t isccc_cc_lookupstring(isccc_sexpr_t *alist, const char *key, char **strp) { isccc_sexpr_t *kv, *v; REQUIRE(strp == NULL || *strp == NULL); kv = isccc_alist_assq(alist, key); if (kv != NULL) { v = ISCCC_SEXPR_CDR(kv); if (isccc_sexpr_binaryp(v)) { if (strp != NULL) *strp = isccc_sexpr_tostring(v); return (ISC_R_SUCCESS); } else return (ISC_R_EXISTS); } return (ISC_R_NOTFOUND); } isc_result_t isccc_cc_lookupuint32(isccc_sexpr_t *alist, const char *key, isc_uint32_t *uintp) { isccc_sexpr_t *kv, *v; kv = isccc_alist_assq(alist, key); if (kv != NULL) { v = ISCCC_SEXPR_CDR(kv); if (isccc_sexpr_binaryp(v)) { if (uintp != NULL) *uintp = (isc_uint32_t) strtoul(isccc_sexpr_tostring(v), NULL, 10); return (ISC_R_SUCCESS); } else return (ISC_R_EXISTS); } return (ISC_R_NOTFOUND); } static void symtab_undefine(char *key, unsigned int type, isccc_symvalue_t value, void *arg) { UNUSED(type); UNUSED(value); UNUSED(arg); free(key); } static isc_boolean_t symtab_clean(char *key, unsigned int type, isccc_symvalue_t value, void *arg) { isccc_time_t *now; UNUSED(key); UNUSED(type); now = arg; if (*now < value.as_uinteger) return (ISC_FALSE); if ((*now - value.as_uinteger) < DUP_LIFETIME) return (ISC_FALSE); return (ISC_TRUE); } isc_result_t isccc_cc_createsymtab(isccc_symtab_t **symtabp) { return (isccc_symtab_create(11897, symtab_undefine, NULL, ISC_FALSE, symtabp)); } void isccc_cc_cleansymtab(isccc_symtab_t *symtab, isccc_time_t now) { isccc_symtab_foreach(symtab, symtab_clean, &now); } static isc_boolean_t has_whitespace(const char *str) { char c; if (str == NULL) return (ISC_FALSE); while ((c = *str++) != '\0') { if (c == ' ' || c == '\t' || c == '\n') return (ISC_TRUE); } return (ISC_FALSE); } isc_result_t isccc_cc_checkdup(isccc_symtab_t *symtab, isccc_sexpr_t *message, isccc_time_t now) { const char *_frm; const char *_to; char *_ser = NULL, *_tim = NULL, *tmp; isc_result_t result; char *key; size_t len; isccc_symvalue_t value; isccc_sexpr_t *_ctrl; _ctrl = isccc_alist_lookup(message, "_ctrl"); if (!isccc_alist_alistp(_ctrl) || isccc_cc_lookupstring(_ctrl, "_ser", &_ser) != ISC_R_SUCCESS || isccc_cc_lookupstring(_ctrl, "_tim", &_tim) != ISC_R_SUCCESS) return (ISC_R_FAILURE); INSIST(_ser != NULL); INSIST(_tim != NULL); /* * _frm and _to are optional. */ tmp = NULL; if (isccc_cc_lookupstring(_ctrl, "_frm", &tmp) != ISC_R_SUCCESS) _frm = ""; else _frm = tmp; tmp = NULL; if (isccc_cc_lookupstring(_ctrl, "_to", &tmp) != ISC_R_SUCCESS) _to = ""; else _to = tmp; /* * Ensure there is no newline in any of the strings. This is so * we can write them to a file later. */ if (has_whitespace(_frm) || has_whitespace(_to) || has_whitespace(_ser) || has_whitespace(_tim)) return (ISC_R_FAILURE); len = strlen(_frm) + strlen(_to) + strlen(_ser) + strlen(_tim) + 4; key = malloc(len); if (key == NULL) return (ISC_R_NOMEMORY); snprintf(key, len, "%s;%s;%s;%s", _frm, _to, _ser, _tim); value.as_uinteger = now; result = isccc_symtab_define(symtab, key, ISCCC_SYMTYPE_CCDUP, value, isccc_symexists_reject); if (result != ISC_R_SUCCESS) { free(key); return (result); } return (ISC_R_SUCCESS); } bind9-9.10.3.dfsg.P4/lib/isccc/alist.c0000644000470500017500000001654512664710322016516 0ustar lamontlamont/* * Portions Copyright (C) 2004, 2005, 2007, 2015 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 2001 Nominum, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: alist.c,v 1.8 2007/08/28 07:20:43 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include #define CAR(s) (s)->value.as_dottedpair.car #define CDR(s) (s)->value.as_dottedpair.cdr #define ALIST_TAG "*alist*" #define MAX_INDENT 64 static char spaces[MAX_INDENT + 1] = " "; isccc_sexpr_t * isccc_alist_create(void) { isccc_sexpr_t *alist, *tag; tag = isccc_sexpr_fromstring(ALIST_TAG); if (tag == NULL) return (NULL); alist = isccc_sexpr_cons(tag, NULL); if (alist == NULL) { isccc_sexpr_free(&tag); return (NULL); } return (alist); } isc_boolean_t isccc_alist_alistp(isccc_sexpr_t *alist) { isccc_sexpr_t *car; if (alist == NULL || alist->type != ISCCC_SEXPRTYPE_DOTTEDPAIR) return (ISC_FALSE); car = CAR(alist); if (car == NULL || car->type != ISCCC_SEXPRTYPE_STRING) return (ISC_FALSE); if (strcmp(car->value.as_string, ALIST_TAG) != 0) return (ISC_FALSE); return (ISC_TRUE); } isc_boolean_t isccc_alist_emptyp(isccc_sexpr_t *alist) { REQUIRE(isccc_alist_alistp(alist)); if (CDR(alist) == NULL) return (ISC_TRUE); return (ISC_FALSE); } isccc_sexpr_t * isccc_alist_first(isccc_sexpr_t *alist) { REQUIRE(isccc_alist_alistp(alist)); return (CDR(alist)); } isccc_sexpr_t * isccc_alist_assq(isccc_sexpr_t *alist, const char *key) { isccc_sexpr_t *car, *caar; REQUIRE(isccc_alist_alistp(alist)); /* * Skip alist type tag. */ alist = CDR(alist); while (alist != NULL) { INSIST(alist->type == ISCCC_SEXPRTYPE_DOTTEDPAIR); car = CAR(alist); INSIST(car->type == ISCCC_SEXPRTYPE_DOTTEDPAIR); caar = CAR(car); if (caar->type == ISCCC_SEXPRTYPE_STRING && strcmp(caar->value.as_string, key) == 0) return (car); alist = CDR(alist); } return (NULL); } void isccc_alist_delete(isccc_sexpr_t *alist, const char *key) { isccc_sexpr_t *car, *caar, *rest, *prev; REQUIRE(isccc_alist_alistp(alist)); prev = alist; rest = CDR(alist); while (rest != NULL) { INSIST(rest->type == ISCCC_SEXPRTYPE_DOTTEDPAIR); car = CAR(rest); INSIST(car != NULL && car->type == ISCCC_SEXPRTYPE_DOTTEDPAIR); caar = CAR(car); if (caar->type == ISCCC_SEXPRTYPE_STRING && strcmp(caar->value.as_string, key) == 0) { CDR(prev) = CDR(rest); CDR(rest) = NULL; isccc_sexpr_free(&rest); break; } prev = rest; rest = CDR(rest); } } isccc_sexpr_t * isccc_alist_define(isccc_sexpr_t *alist, const char *key, isccc_sexpr_t *value) { isccc_sexpr_t *kv, *k, *elt; kv = isccc_alist_assq(alist, key); if (kv == NULL) { /* * New association. */ k = isccc_sexpr_fromstring(key); if (k == NULL) return (NULL); kv = isccc_sexpr_cons(k, value); if (kv == NULL) { isccc_sexpr_free(&kv); return (NULL); } elt = isccc_sexpr_addtolist(&alist, kv); if (elt == NULL) { isccc_sexpr_free(&kv); return (NULL); } } else { /* * We've already got an entry for this key. Replace it. */ isccc_sexpr_free(&CDR(kv)); CDR(kv) = value; } return (kv); } isccc_sexpr_t * isccc_alist_definestring(isccc_sexpr_t *alist, const char *key, const char *str) { isccc_sexpr_t *v, *kv; v = isccc_sexpr_fromstring(str); if (v == NULL) return (NULL); kv = isccc_alist_define(alist, key, v); if (kv == NULL) isccc_sexpr_free(&v); return (kv); } isccc_sexpr_t * isccc_alist_definebinary(isccc_sexpr_t *alist, const char *key, isccc_region_t *r) { isccc_sexpr_t *v, *kv; v = isccc_sexpr_frombinary(r); if (v == NULL) return (NULL); kv = isccc_alist_define(alist, key, v); if (kv == NULL) isccc_sexpr_free(&v); return (kv); } isccc_sexpr_t * isccc_alist_lookup(isccc_sexpr_t *alist, const char *key) { isccc_sexpr_t *kv; kv = isccc_alist_assq(alist, key); if (kv != NULL) return (CDR(kv)); return (NULL); } isc_result_t isccc_alist_lookupstring(isccc_sexpr_t *alist, const char *key, char **strp) { isccc_sexpr_t *kv, *v; kv = isccc_alist_assq(alist, key); if (kv != NULL) { v = CDR(kv); if (isccc_sexpr_stringp(v)) { if (strp != NULL) *strp = isccc_sexpr_tostring(v); return (ISC_R_SUCCESS); } else return (ISC_R_EXISTS); } return (ISC_R_NOTFOUND); } isc_result_t isccc_alist_lookupbinary(isccc_sexpr_t *alist, const char *key, isccc_region_t **r) { isccc_sexpr_t *kv, *v; kv = isccc_alist_assq(alist, key); if (kv != NULL) { v = CDR(kv); if (isccc_sexpr_binaryp(v)) { if (r != NULL) *r = isccc_sexpr_tobinary(v); return (ISC_R_SUCCESS); } else return (ISC_R_EXISTS); } return (ISC_R_NOTFOUND); } void isccc_alist_prettyprint(isccc_sexpr_t *sexpr, unsigned int indent, FILE *stream) { isccc_sexpr_t *elt, *kv, *k, *v; if (isccc_alist_alistp(sexpr)) { fprintf(stream, "{\n"); indent += 4; for (elt = isccc_alist_first(sexpr); elt != NULL; elt = CDR(elt)) { kv = CAR(elt); INSIST(isccc_sexpr_listp(kv)); k = CAR(kv); v = CDR(kv); INSIST(isccc_sexpr_stringp(k)); fprintf(stream, "%.*s%s => ", (int)indent, spaces, isccc_sexpr_tostring(k)); isccc_alist_prettyprint(v, indent, stream); if (CDR(elt) != NULL) fprintf(stream, ","); fprintf(stream, "\n"); } indent -= 4; fprintf(stream, "%.*s}", (int)indent, spaces); } else if (isccc_sexpr_listp(sexpr)) { fprintf(stream, "(\n"); indent += 4; for (elt = sexpr; elt != NULL; elt = CDR(elt)) { fprintf(stream, "%.*s", (int)indent, spaces); isccc_alist_prettyprint(CAR(elt), indent, stream); if (CDR(elt) != NULL) fprintf(stream, ","); fprintf(stream, "\n"); } indent -= 4; fprintf(stream, "%.*s)", (int)indent, spaces); } else isccc_sexpr_print(sexpr, stream); } bind9-9.10.3.dfsg.P4/lib/isccc/ccmsg.c0000644000470500017500000001376612664710322016500 0ustar lamontlamont/* * Portions Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 2001 Nominum, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ccmsg.c,v 1.10 2007/08/28 07:20:43 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #define CCMSG_MAGIC ISC_MAGIC('C', 'C', 'm', 's') #define VALID_CCMSG(foo) ISC_MAGIC_VALID(foo, CCMSG_MAGIC) static void recv_length(isc_task_t *, isc_event_t *); static void recv_message(isc_task_t *, isc_event_t *); static void recv_length(isc_task_t *task, isc_event_t *ev_in) { isc_socketevent_t *ev = (isc_socketevent_t *)ev_in; isc_event_t *dev; isccc_ccmsg_t *ccmsg = ev_in->ev_arg; isc_region_t region; isc_result_t result; INSIST(VALID_CCMSG(ccmsg)); dev = &ccmsg->event; if (ev->result != ISC_R_SUCCESS) { ccmsg->result = ev->result; goto send_and_free; } /* * Success. */ ccmsg->size = ntohl(ccmsg->size); if (ccmsg->size == 0) { ccmsg->result = ISC_R_UNEXPECTEDEND; goto send_and_free; } if (ccmsg->size > ccmsg->maxsize) { ccmsg->result = ISC_R_RANGE; goto send_and_free; } region.base = isc_mem_get(ccmsg->mctx, ccmsg->size); region.length = ccmsg->size; if (region.base == NULL) { ccmsg->result = ISC_R_NOMEMORY; goto send_and_free; } isc_buffer_init(&ccmsg->buffer, region.base, region.length); result = isc_socket_recv(ccmsg->sock, ®ion, 0, task, recv_message, ccmsg); if (result != ISC_R_SUCCESS) { ccmsg->result = result; goto send_and_free; } isc_event_free(&ev_in); return; send_and_free: isc_task_send(ccmsg->task, &dev); ccmsg->task = NULL; isc_event_free(&ev_in); return; } static void recv_message(isc_task_t *task, isc_event_t *ev_in) { isc_socketevent_t *ev = (isc_socketevent_t *)ev_in; isc_event_t *dev; isccc_ccmsg_t *ccmsg = ev_in->ev_arg; (void)task; INSIST(VALID_CCMSG(ccmsg)); dev = &ccmsg->event; if (ev->result != ISC_R_SUCCESS) { ccmsg->result = ev->result; goto send_and_free; } ccmsg->result = ISC_R_SUCCESS; isc_buffer_add(&ccmsg->buffer, ev->n); ccmsg->address = ev->address; send_and_free: isc_task_send(ccmsg->task, &dev); ccmsg->task = NULL; isc_event_free(&ev_in); } void isccc_ccmsg_init(isc_mem_t *mctx, isc_socket_t *sock, isccc_ccmsg_t *ccmsg) { REQUIRE(mctx != NULL); REQUIRE(sock != NULL); REQUIRE(ccmsg != NULL); ccmsg->magic = CCMSG_MAGIC; ccmsg->size = 0; ccmsg->buffer.base = NULL; ccmsg->buffer.length = 0; ccmsg->maxsize = 4294967295U; /* Largest message possible. */ ccmsg->mctx = mctx; ccmsg->sock = sock; ccmsg->task = NULL; /* None yet. */ ccmsg->result = ISC_R_UNEXPECTED; /* None yet. */ /* * Should probably initialize the event here, but it can wait. */ } void isccc_ccmsg_setmaxsize(isccc_ccmsg_t *ccmsg, unsigned int maxsize) { REQUIRE(VALID_CCMSG(ccmsg)); ccmsg->maxsize = maxsize; } isc_result_t isccc_ccmsg_readmessage(isccc_ccmsg_t *ccmsg, isc_task_t *task, isc_taskaction_t action, void *arg) { isc_result_t result; isc_region_t region; REQUIRE(VALID_CCMSG(ccmsg)); REQUIRE(task != NULL); REQUIRE(ccmsg->task == NULL); /* not currently in use */ if (ccmsg->buffer.base != NULL) { isc_mem_put(ccmsg->mctx, ccmsg->buffer.base, ccmsg->buffer.length); ccmsg->buffer.base = NULL; ccmsg->buffer.length = 0; } ccmsg->task = task; ccmsg->action = action; ccmsg->arg = arg; ccmsg->result = ISC_R_UNEXPECTED; /* unknown right now */ ISC_EVENT_INIT(&ccmsg->event, sizeof(isc_event_t), 0, 0, ISCCC_EVENT_CCMSG, action, arg, ccmsg, NULL, NULL); region.base = (unsigned char *)&ccmsg->size; region.length = 4; /* isc_uint32_t */ result = isc_socket_recv(ccmsg->sock, ®ion, 0, ccmsg->task, recv_length, ccmsg); if (result != ISC_R_SUCCESS) ccmsg->task = NULL; return (result); } void isccc_ccmsg_cancelread(isccc_ccmsg_t *ccmsg) { REQUIRE(VALID_CCMSG(ccmsg)); isc_socket_cancel(ccmsg->sock, NULL, ISC_SOCKCANCEL_RECV); } #if 0 void isccc_ccmsg_freebuffer(isccc_ccmsg_t *ccmsg) { REQUIRE(VALID_CCMSG(ccmsg)); if (ccmsg->buffer.base == NULL) return; isc_mem_put(ccmsg->mctx, ccmsg->buffer.base, ccmsg->buffer.length); ccmsg->buffer.base = NULL; ccmsg->buffer.length = 0; } #endif void isccc_ccmsg_invalidate(isccc_ccmsg_t *ccmsg) { REQUIRE(VALID_CCMSG(ccmsg)); ccmsg->magic = 0; if (ccmsg->buffer.base != NULL) { isc_mem_put(ccmsg->mctx, ccmsg->buffer.base, ccmsg->buffer.length); ccmsg->buffer.base = NULL; ccmsg->buffer.length = 0; } } bind9-9.10.3.dfsg.P4/lib/isccc/include/0002755000470500017500000000000012672612753016660 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isccc/include/Makefile.in0000644000470500017500000000175212664710322020720 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.5 2007/06/19 23:47:22 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = isccc TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/lib/isccc/include/isccc/0002755000470500017500000000000012664710322017734 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isccc/include/isccc/alist.h0000644000470500017500000000556712664710322021234 0ustar lamontlamont/* * Portions Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 2001 Nominum, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: alist.h,v 1.10 2007/08/28 07:20:43 tbox Exp $ */ #ifndef ISCCC_ALIST_H #define ISCCC_ALIST_H 1 /*! \file isccc/alist.h */ #include #include #include ISC_LANG_BEGINDECLS isccc_sexpr_t * isccc_alist_create(void); isc_boolean_t isccc_alist_alistp(isccc_sexpr_t *alist); isc_boolean_t isccc_alist_emptyp(isccc_sexpr_t *alist); isccc_sexpr_t * isccc_alist_first(isccc_sexpr_t *alist); isccc_sexpr_t * isccc_alist_assq(isccc_sexpr_t *alist, const char *key); void isccc_alist_delete(isccc_sexpr_t *alist, const char *key); isccc_sexpr_t * isccc_alist_define(isccc_sexpr_t *alist, const char *key, isccc_sexpr_t *value); isccc_sexpr_t * isccc_alist_definestring(isccc_sexpr_t *alist, const char *key, const char *str); isccc_sexpr_t * isccc_alist_definebinary(isccc_sexpr_t *alist, const char *key, isccc_region_t *r); isccc_sexpr_t * isccc_alist_lookup(isccc_sexpr_t *alist, const char *key); isc_result_t isccc_alist_lookupstring(isccc_sexpr_t *alist, const char *key, char **strp); isc_result_t isccc_alist_lookupbinary(isccc_sexpr_t *alist, const char *key, isccc_region_t **r); void isccc_alist_prettyprint(isccc_sexpr_t *sexpr, unsigned int indent, FILE *stream); ISC_LANG_ENDDECLS #endif /* ISCCC_ALIST_H */ bind9-9.10.3.dfsg.P4/lib/isccc/include/isccc/events.h0000644000470500017500000000403712664710322021413 0ustar lamontlamont/* * Portions Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 2001 Nominum, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: events.h,v 1.10 2007/08/28 07:20:43 tbox Exp $ */ #ifndef ISCCC_EVENTS_H #define ISCCC_EVENTS_H 1 /*! \file isccc/events.h */ #include /*% * Registry of ISCCC event numbers. */ #define ISCCC_EVENT_CCMSG (ISC_EVENTCLASS_ISCCC + 0) #define ISCCC_EVENT_FIRSTEVENT (ISC_EVENTCLASS_ISCCC + 0) #define ISCCC_EVENT_LASTEVENT (ISC_EVENTCLASS_ISCCC + 65535) #endif /* ISCCC_EVENTS_H */ bind9-9.10.3.dfsg.P4/lib/isccc/include/isccc/Makefile.in0000644000470500017500000000271412664710322022003 0ustar lamontlamont# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.7 2007/06/19 23:47:22 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ # # Only list headers that are to be installed and are not # machine generated. The latter are handled specially in the # install target below. # HEADERS = alist.h base64.h cc.h ccmsg.h events.h lib.h result.h \ sexpr.h symtab.h symtype.h types.h util.h version.h SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isccc install:: installdirs for i in ${HEADERS}; do \ ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/isccc ; \ done bind9-9.10.3.dfsg.P4/lib/isccc/include/isccc/symtype.h0000644000470500017500000000371312664710322021621 0ustar lamontlamont/* * Portions Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 2001 Nominum, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: symtype.h,v 1.10 2007/08/28 07:20:43 tbox Exp $ */ #ifndef ISCCC_SYMTYPE_H #define ISCCC_SYMTYPE_H 1 /*! \file isccc/symtype.h */ #define ISCCC_SYMTYPE_ZONESTATS 0x0001 #define ISCCC_SYMTYPE_CCDUP 0x0002 #define ISCCC_SYMTYPE_TELLSERVICE 0x0003 #define ISCCC_SYMTYPE_TELLRESPONSE 0x0004 #endif /* ISCCC_SYMTYPE_H */ bind9-9.10.3.dfsg.P4/lib/isccc/include/isccc/types.h0000644000470500017500000000441312664710322021251 0ustar lamontlamont/* * Portions Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 2001 Nominum, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: types.h,v 1.10 2007/08/28 07:20:43 tbox Exp $ */ #ifndef ISCCC_TYPES_H #define ISCCC_TYPES_H 1 /*! \file isccc/types.h */ #include #include #include /*% isccc_time_t typedef */ typedef isc_uint32_t isccc_time_t; /*% isccc_sexpr_t typedef */ typedef struct isccc_sexpr isccc_sexpr_t; /*% isccc_dottedpair_t typedef */ typedef struct isccc_dottedpair isccc_dottedpair_t; /*% isccc_symtab_t typedef */ typedef struct isccc_symtab isccc_symtab_t; /*% iscc region structure */ typedef struct isccc_region { unsigned char * rstart; unsigned char * rend; } isccc_region_t; #endif /* ISCCC_TYPES_H */ bind9-9.10.3.dfsg.P4/lib/isccc/include/isccc/lib.h0000644000470500017500000000407112664710322020653 0ustar lamontlamont/* * Portions Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 2001 Nominum, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lib.h,v 1.11 2007/08/28 07:20:43 tbox Exp $ */ #ifndef ISCCC_LIB_H #define ISCCC_LIB_H 1 /*! \file isccc/lib.h */ #include #include ISC_LANG_BEGINDECLS LIBISCCC_EXTERNAL_DATA extern isc_msgcat_t *isccc_msgcat; void isccc_lib_initmsgcat(void); /*% * Initialize the ISCCC library's message catalog, isccc_msgcat, if it * has not already been initialized. */ ISC_LANG_ENDDECLS #endif /* ISCCC_LIB_H */ bind9-9.10.3.dfsg.P4/lib/isccc/include/isccc/base64.h0000644000470500017500000000564212664710322021176 0ustar lamontlamont/* * Portions Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 2001 Nominum, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: base64.h,v 1.10 2007/08/28 07:20:43 tbox Exp $ */ #ifndef ISCCC_BASE64_H #define ISCCC_BASE64_H 1 /*! \file isccc/base64.h */ #include #include ISC_LANG_BEGINDECLS /*** *** Functions ***/ isc_result_t isccc_base64_encode(isccc_region_t *source, int wordlength, const char *wordbreak, isccc_region_t *target); /*%< * Convert data into base64 encoded text. * * Notes: *\li The base64 encoded text in 'target' will be divided into * words of at most 'wordlength' characters, separated by * the 'wordbreak' string. No parentheses will surround * the text. * * Requires: *\li 'source' is a region containing binary data. *\li 'target' is a text region containing available space. *\li 'wordbreak' points to a null-terminated string of * zero or more whitespace characters. */ isc_result_t isccc_base64_decode(const char *cstr, isccc_region_t *target); /*%< * Decode a null-terminated base64 string. * * Requires: *\li 'cstr' is non-null. *\li 'target' is a valid region. * * Returns: *\li #ISC_R_SUCCESS -- the entire decoded representation of 'cstring' * fit in 'target'. *\li #ISC_R_BADBASE64 -- 'cstr' is not a valid base64 encoding. *\li #ISC_R_NOSPACE -- 'target' is not big enough. */ ISC_LANG_ENDDECLS #endif /* ISCCC_BASE64_H */ bind9-9.10.3.dfsg.P4/lib/isccc/include/isccc/result.h0000644000470500017500000000513312664710322021423 0ustar lamontlamont/* * Portions Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 2001 Nominum, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: result.h,v 1.12 2007/08/28 07:20:43 tbox Exp $ */ #ifndef ISCCC_RESULT_H #define ISCCC_RESULT_H 1 /*! \file isccc/result.h */ #include #include #include #include /*% Unknown Version */ #define ISCCC_R_UNKNOWNVERSION (ISC_RESULTCLASS_ISCCC + 0) /*% Syntax Error */ #define ISCCC_R_SYNTAX (ISC_RESULTCLASS_ISCCC + 1) /*% Bad Authorization */ #define ISCCC_R_BADAUTH (ISC_RESULTCLASS_ISCCC + 2) /*% Expired */ #define ISCCC_R_EXPIRED (ISC_RESULTCLASS_ISCCC + 3) /*% Clock Skew */ #define ISCCC_R_CLOCKSKEW (ISC_RESULTCLASS_ISCCC + 4) /*% Duplicate */ #define ISCCC_R_DUPLICATE (ISC_RESULTCLASS_ISCCC + 5) #define ISCCC_R_NRESULTS 6 /*%< Number of results */ ISC_LANG_BEGINDECLS const char * isccc_result_totext(isc_result_t result); /*% * Convert a isccc_result_t into a string message describing the result. */ void isccc_result_register(void); ISC_LANG_ENDDECLS #endif /* ISCCC_RESULT_H */ bind9-9.10.3.dfsg.P4/lib/isccc/include/isccc/version.h0000644000470500017500000000231112664710322021565 0ustar lamontlamont/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: version.h,v 1.9 2007/06/19 23:47:22 tbox Exp $ */ /*! \file isccc/version.h */ #include LIBISCCC_EXTERNAL_DATA extern const char isccc_version[]; LIBISCCC_EXTERNAL_DATA extern const unsigned int isccc_libinterface; LIBISCCC_EXTERNAL_DATA extern const unsigned int isccc_librevision; LIBISCCC_EXTERNAL_DATA extern const unsigned int isccc_libage; bind9-9.10.3.dfsg.P4/lib/isccc/include/isccc/util.h0000644000470500017500000001266512664710322021072 0ustar lamontlamont/* * Portions Copyright (C) 2004-2007, 2014 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 2001 Nominum, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: util.h,v 1.11 2007/08/28 07:20:43 tbox Exp $ */ #ifndef ISCCC_UTIL_H #define ISCCC_UTIL_H 1 #include /*! \file isccc/util.h * \brief * Macros for dealing with unaligned numbers. * * \note no side effects are allowed when invoking these macros! */ #define GET8(v, w) \ do { \ v = *w; \ w++; \ } while (0) #define GET16(v, w) \ do { \ v = (unsigned int)w[0] << 8; \ v |= (unsigned int)w[1]; \ w += 2; \ } while (0) #define GET24(v, w) \ do { \ v = (unsigned int)w[0] << 16; \ v |= (unsigned int)w[1] << 8; \ v |= (unsigned int)w[2]; \ w += 3; \ } while (0) #define GET32(v, w) \ do { \ v = (unsigned int)w[0] << 24; \ v |= (unsigned int)w[1] << 16; \ v |= (unsigned int)w[2] << 8; \ v |= (unsigned int)w[3]; \ w += 4; \ } while (0) #define GET64(v, w) \ do { \ v = (isc_uint64_t)w[0] << 56; \ v |= (isc_uint64_t)w[1] << 48; \ v |= (isc_uint64_t)w[2] << 40; \ v |= (isc_uint64_t)w[3] << 32; \ v |= (isc_uint64_t)w[4] << 24; \ v |= (isc_uint64_t)w[5] << 16; \ v |= (isc_uint64_t)w[6] << 8; \ v |= (isc_uint64_t)w[7]; \ w += 8; \ } while (0) #define GETC16(v, w, d) \ do { \ GET8(v, w); \ if (v == 0) \ d = ISCCC_TRUE; \ else { \ d = ISCCC_FALSE; \ if (v == 255) \ GET16(v, w); \ } \ } while (0) #define GETC32(v, w) \ do { \ GET24(v, w); \ if (v == 0xffffffu) \ GET32(v, w); \ } while (0) #define GET_OFFSET(v, w) GET32(v, w) #define GET_MEM(v, c, w) \ do { \ memmove(v, w, c); \ w += c; \ } while (0) #define GET_TYPE(v, w) \ do { \ GET8(v, w); \ if (v > 127) { \ if (v < 255) \ v = ((v & 0x7f) << 16) | ISCCC_RDATATYPE_SIG; \ else \ GET32(v, w); \ } \ } while (0) #define PUT8(v, w) \ do { \ *w = (v & 0x000000ffU); \ w++; \ } while (0) #define PUT16(v, w) \ do { \ w[0] = (v & 0x0000ff00U) >> 8; \ w[1] = (v & 0x000000ffU); \ w += 2; \ } while (0) #define PUT24(v, w) \ do { \ w[0] = (v & 0x00ff0000U) >> 16; \ w[1] = (v & 0x0000ff00U) >> 8; \ w[2] = (v & 0x000000ffU); \ w += 3; \ } while (0) #define PUT32(v, w) \ do { \ w[0] = (v & 0xff000000U) >> 24; \ w[1] = (v & 0x00ff0000U) >> 16; \ w[2] = (v & 0x0000ff00U) >> 8; \ w[3] = (v & 0x000000ffU); \ w += 4; \ } while (0) #define PUT64(v, w) \ do { \ w[0] = (v & 0xff00000000000000ULL) >> 56; \ w[1] = (v & 0x00ff000000000000ULL) >> 48; \ w[2] = (v & 0x0000ff0000000000ULL) >> 40; \ w[3] = (v & 0x000000ff00000000ULL) >> 32; \ w[4] = (v & 0x00000000ff000000ULL) >> 24; \ w[5] = (v & 0x0000000000ff0000ULL) >> 16; \ w[6] = (v & 0x000000000000ff00ULL) >> 8; \ w[7] = (v & 0x00000000000000ffULL); \ w += 8; \ } while (0) #define PUTC16(v, w) \ do { \ if (v > 0 && v < 255) \ PUT8(v, w); \ else { \ PUT8(255, w); \ PUT16(v, w); \ } \ } while (0) #define PUTC32(v, w) \ do { \ if (v < 0xffffffU) \ PUT24(v, w); \ else { \ PUT24(0xffffffU, w); \ PUT32(v, w); \ } \ } while (0) #define PUT_OFFSET(v, w) PUT32(v, w) #include #define PUT_MEM(s, c, w) \ do { \ memmove(w, s, c); \ w += c; \ } while (0) /* * Regions. */ #define REGION_SIZE(r) ((unsigned int)((r).rend - (r).rstart)) #define REGION_EMPTY(r) ((r).rstart == (r).rend) #define REGION_FROMSTRING(r, s) do { \ (r).rstart = (unsigned char *)s; \ (r).rend = (r).rstart + strlen(s); \ } while (0) /*% * Use this to remove the const qualifier of a variable to assign it to * a non-const variable or pass it as a non-const function argument ... * but only when you are sure it won't then be changed! * This is necessary to sometimes shut up some compilers * (as with gcc -Wcast-qual) when there is just no other good way to avoid the * situation. */ #define DE_CONST(konst, var) \ do { \ union { const void *k; void *v; } _u; \ _u.k = konst; \ var = _u.v; \ } while (0) #endif /* ISCCC_UTIL_H */ bind9-9.10.3.dfsg.P4/lib/isccc/include/isccc/ccmsg.h0000644000470500017500000001011012664710322021170 0ustar lamontlamont/* * Portions Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 2001 Nominum, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ccmsg.h,v 1.11 2007/08/28 07:20:43 tbox Exp $ */ #ifndef ISCCC_CCMSG_H #define ISCCC_CCMSG_H 1 /*! \file isccc/ccmsg.h */ #include #include #include /*% ISCCC Message Structure */ typedef struct isccc_ccmsg { /* private (don't touch!) */ unsigned int magic; isc_uint32_t size; isc_buffer_t buffer; unsigned int maxsize; isc_mem_t *mctx; isc_socket_t *sock; isc_task_t *task; isc_taskaction_t action; void *arg; isc_event_t event; /* public (read-only) */ isc_result_t result; isc_sockaddr_t address; } isccc_ccmsg_t; ISC_LANG_BEGINDECLS void isccc_ccmsg_init(isc_mem_t *mctx, isc_socket_t *sock, isccc_ccmsg_t *ccmsg); /*% * Associate a cc message state with a given memory context and * TCP socket. * * Requires: * *\li "mctx" and "sock" be non-NULL and valid types. * *\li "sock" be a read/write TCP socket. * *\li "ccmsg" be non-NULL and an uninitialized or invalidated structure. * * Ensures: * *\li "ccmsg" is a valid structure. */ void isccc_ccmsg_setmaxsize(isccc_ccmsg_t *ccmsg, unsigned int maxsize); /*% * Set the maximum packet size to "maxsize" * * Requires: * *\li "ccmsg" be valid. * *\li 512 <= "maxsize" <= 4294967296 */ isc_result_t isccc_ccmsg_readmessage(isccc_ccmsg_t *ccmsg, isc_task_t *task, isc_taskaction_t action, void *arg); /*% * Schedule an event to be delivered when a command channel message is * readable, or when an error occurs on the socket. * * Requires: * *\li "ccmsg" be valid. * *\li "task", "taskaction", and "arg" be valid. * * Returns: * *\li #ISC_R_SUCCESS -- no error *\li Anything that the isc_socket_recv() call can return. XXXMLG * * Notes: * *\li The event delivered is a fully generic event. It will contain no * actual data. The sender will be a pointer to the isccc_ccmsg_t. * The result code inside that structure should be checked to see * what the final result was. */ void isccc_ccmsg_cancelread(isccc_ccmsg_t *ccmsg); /*% * Cancel a readmessage() call. The event will still be posted with a * CANCELED result code. * * Requires: * *\li "ccmsg" be valid. */ void isccc_ccmsg_invalidate(isccc_ccmsg_t *ccmsg); /*% * Clean up all allocated state, and invalidate the structure. * * Requires: * *\li "ccmsg" be valid. * * Ensures: * *\li "ccmsg" is invalidated and disassociated with all memory contexts, * sockets, etc. */ ISC_LANG_ENDDECLS #endif /* ISCCC_CCMSG_H */ bind9-9.10.3.dfsg.P4/lib/isccc/include/isccc/sexpr.h0000644000470500017500000000673712664710322021261 0ustar lamontlamont/* * Portions Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 2001 Nominum, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: sexpr.h,v 1.11 2007/08/28 07:20:43 tbox Exp $ */ #ifndef ISCCC_SEXPR_H #define ISCCC_SEXPR_H 1 /*! \file isccc/sexpr.h */ #include #include #include ISC_LANG_BEGINDECLS /*% dotted pair structure */ struct isccc_dottedpair { isccc_sexpr_t *car; isccc_sexpr_t *cdr; }; /*% iscc_sexpr structure */ struct isccc_sexpr { unsigned int type; union { char * as_string; isccc_dottedpair_t as_dottedpair; isccc_region_t as_region; } value; }; #define ISCCC_SEXPRTYPE_NONE 0x00 /*%< Illegal. */ #define ISCCC_SEXPRTYPE_T 0x01 #define ISCCC_SEXPRTYPE_STRING 0x02 #define ISCCC_SEXPRTYPE_DOTTEDPAIR 0x03 #define ISCCC_SEXPRTYPE_BINARY 0x04 #define ISCCC_SEXPR_CAR(s) (s)->value.as_dottedpair.car #define ISCCC_SEXPR_CDR(s) (s)->value.as_dottedpair.cdr isccc_sexpr_t * isccc_sexpr_cons(isccc_sexpr_t *car, isccc_sexpr_t *cdr); isccc_sexpr_t * isccc_sexpr_tconst(void); isccc_sexpr_t * isccc_sexpr_fromstring(const char *str); isccc_sexpr_t * isccc_sexpr_frombinary(const isccc_region_t *region); void isccc_sexpr_free(isccc_sexpr_t **sexprp); void isccc_sexpr_print(isccc_sexpr_t *sexpr, FILE *stream); isccc_sexpr_t * isccc_sexpr_car(isccc_sexpr_t *list); isccc_sexpr_t * isccc_sexpr_cdr(isccc_sexpr_t *list); void isccc_sexpr_setcar(isccc_sexpr_t *pair, isccc_sexpr_t *car); void isccc_sexpr_setcdr(isccc_sexpr_t *pair, isccc_sexpr_t *cdr); isccc_sexpr_t * isccc_sexpr_addtolist(isccc_sexpr_t **l1p, isccc_sexpr_t *l2); isc_boolean_t isccc_sexpr_listp(isccc_sexpr_t *sexpr); isc_boolean_t isccc_sexpr_emptyp(isccc_sexpr_t *sexpr); isc_boolean_t isccc_sexpr_stringp(isccc_sexpr_t *sexpr); isc_boolean_t isccc_sexpr_binaryp(isccc_sexpr_t *sexpr); char * isccc_sexpr_tostring(isccc_sexpr_t *sexpr); isccc_region_t * isccc_sexpr_tobinary(isccc_sexpr_t *sexpr); ISC_LANG_ENDDECLS #endif /* ISCCC_SEXPR_H */ bind9-9.10.3.dfsg.P4/lib/isccc/include/isccc/symtab.h0000644000470500017500000001123512664710322021404 0ustar lamontlamont/* * Portions Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 2001 Nominum, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: symtab.h,v 1.10 2007/08/28 07:20:43 tbox Exp $ */ #ifndef ISCCC_SYMTAB_H #define ISCCC_SYMTAB_H 1 /***** ***** Module Info *****/ /*! \file isccc/symtab.h * \brief * Provides a simple memory-based symbol table. * * Keys are C strings. A type may be specified when looking up, * defining, or undefining. A type value of 0 means "match any type"; * any other value will only match the given type. * * It's possible that a client will attempt to define a tuple when a tuple with the given key and type already * exists in the table. What to do in this case is specified by the * client. Possible policies are: * *\li isccc_symexists_reject Disallow the define, returning #ISC_R_EXISTS *\li isccc_symexists_replace Replace the old value with the new. The * undefine action (if provided) will be called * with the old tuple. *\li isccc_symexists_add Add the new tuple, leaving the old tuple in * the table. Subsequent lookups will retrieve * the most-recently-defined tuple. * * A lookup of a key using type 0 will return the most-recently * defined symbol with that key. An undefine of a key using type 0 * will undefine the most-recently defined symbol with that key. * Trying to define a key with type 0 is illegal. * * The symbol table library does not make a copy the key field, so the * caller must ensure that any key it passes to isccc_symtab_define() * will not change until it calls isccc_symtab_undefine() or * isccc_symtab_destroy(). * * A user-specified action will be called (if provided) when a symbol * is undefined. It can be used to free memory associated with keys * and/or values. */ /*** *** Imports. ***/ #include #include /*** *** Symbol Tables. ***/ typedef union isccc_symvalue { void * as_pointer; int as_integer; unsigned int as_uinteger; } isccc_symvalue_t; typedef void (*isccc_symtabundefaction_t)(char *key, unsigned int type, isccc_symvalue_t value, void *userarg); typedef isc_boolean_t (*isccc_symtabforeachaction_t)(char *key, unsigned int type, isccc_symvalue_t value, void *userarg); typedef enum { isccc_symexists_reject = 0, isccc_symexists_replace = 1, isccc_symexists_add = 2 } isccc_symexists_t; ISC_LANG_BEGINDECLS isc_result_t isccc_symtab_create(unsigned int size, isccc_symtabundefaction_t undefine_action, void *undefine_arg, isc_boolean_t case_sensitive, isccc_symtab_t **symtabp); void isccc_symtab_destroy(isccc_symtab_t **symtabp); isc_result_t isccc_symtab_lookup(isccc_symtab_t *symtab, const char *key, unsigned int type, isccc_symvalue_t *value); isc_result_t isccc_symtab_define(isccc_symtab_t *symtab, char *key, unsigned int type, isccc_symvalue_t value, isccc_symexists_t exists_policy); isc_result_t isccc_symtab_undefine(isccc_symtab_t *symtab, const char *key, unsigned int type); void isccc_symtab_foreach(isccc_symtab_t *symtab, isccc_symtabforeachaction_t action, void *arg); ISC_LANG_ENDDECLS #endif /* ISCCC_SYMTAB_H */ bind9-9.10.3.dfsg.P4/lib/isccc/include/isccc/cc.h0000644000470500017500000001020612664710322020467 0ustar lamontlamont/* * Portions Copyright (C) 2004-2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 2001 Nominum, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: cc.h,v 1.11 2007/08/28 07:20:43 tbox Exp $ */ #ifndef ISCCC_CC_H #define ISCCC_CC_H 1 /*! \file isccc/cc.h */ #include #include ISC_LANG_BEGINDECLS /*% from lib/dns/include/dst/dst.h */ #define ISCCC_ALG_UNKNOWN 0 #define ISCCC_ALG_HMACMD5 157 #define ISCCC_ALG_HMACSHA1 161 #define ISCCC_ALG_HMACSHA224 162 #define ISCCC_ALG_HMACSHA256 163 #define ISCCC_ALG_HMACSHA384 164 #define ISCCC_ALG_HMACSHA512 165 /*% Maximum Datagram Package */ #define ISCCC_CC_MAXDGRAMPACKET 4096 /*% Message Type String */ #define ISCCC_CCMSGTYPE_STRING 0x00 /*% Message Type Binary Data */ #define ISCCC_CCMSGTYPE_BINARYDATA 0x01 /*% Message Type Table */ #define ISCCC_CCMSGTYPE_TABLE 0x02 /*% Message Type List */ #define ISCCC_CCMSGTYPE_LIST 0x03 /*% Send to Wire */ isc_result_t isccc_cc_towire(isccc_sexpr_t *alist, isccc_region_t *target, isc_uint32_t algorithm, isccc_region_t *secret); /*% Get From Wire */ isc_result_t isccc_cc_fromwire(isccc_region_t *source, isccc_sexpr_t **alistp, isc_uint32_t algorithm, isccc_region_t *secret); /*% Create Message */ isc_result_t isccc_cc_createmessage(isc_uint32_t version, const char *from, const char *to, isc_uint32_t serial, isccc_time_t now, isccc_time_t expires, isccc_sexpr_t **alistp); /*% Create Acknowledgment */ isc_result_t isccc_cc_createack(isccc_sexpr_t *message, isc_boolean_t ok, isccc_sexpr_t **ackp); /*% Is Ack? */ isc_boolean_t isccc_cc_isack(isccc_sexpr_t *message); /*% Is Reply? */ isc_boolean_t isccc_cc_isreply(isccc_sexpr_t *message); /*% Create Response */ isc_result_t isccc_cc_createresponse(isccc_sexpr_t *message, isccc_time_t now, isccc_time_t expires, isccc_sexpr_t **alistp); /*% Define String */ isccc_sexpr_t * isccc_cc_definestring(isccc_sexpr_t *alist, const char *key, const char *str); /*% Define uint 32 */ isccc_sexpr_t * isccc_cc_defineuint32(isccc_sexpr_t *alist, const char *key, isc_uint32_t i); /*% Lookup String */ isc_result_t isccc_cc_lookupstring(isccc_sexpr_t *alist, const char *key, char **strp); /*% Lookup uint 32 */ isc_result_t isccc_cc_lookupuint32(isccc_sexpr_t *alist, const char *key, isc_uint32_t *uintp); /*% Create Symbol Table */ isc_result_t isccc_cc_createsymtab(isccc_symtab_t **symtabp); /*% Clean up Symbol Table */ void isccc_cc_cleansymtab(isccc_symtab_t *symtab, isccc_time_t now); /*% Check for Duplicates */ isc_result_t isccc_cc_checkdup(isccc_symtab_t *symtab, isccc_sexpr_t *message, isccc_time_t now); ISC_LANG_ENDDECLS #endif /* ISCCC_CC_H */ bind9-9.10.3.dfsg.P4/lib/isccc/win32/0002755000470500017500000000000012664730167016200 5ustar lamontlamontbind9-9.10.3.dfsg.P4/lib/isccc/win32/libisccc.def0000644000470500017500000000241012664710322020415 0ustar lamontlamontLIBRARY libisccc ; Exported Functions EXPORTS isccc_alist_create isccc_alist_alistp isccc_alist_emptyp isccc_alist_first isccc_alist_assq isccc_alist_delete isccc_alist_define isccc_alist_definestring isccc_alist_definebinary isccc_alist_lookup isccc_alist_lookupstring isccc_alist_lookupbinary isccc_alist_prettyprint isccc_base64_encode isccc_base64_decode isccc_cc_towire isccc_cc_fromwire isccc_cc_createmessage isccc_cc_createack isccc_cc_isack isccc_cc_isreply isccc_cc_createresponse isccc_cc_definestring isccc_cc_defineuint32 isccc_cc_lookupstring isccc_cc_lookupuint32 isccc_cc_createsymtab isccc_cc_cleansymtab isccc_cc_checkdup isccc_ccmsg_init isccc_ccmsg_setmaxsize isccc_ccmsg_readmessage isccc_ccmsg_cancelread isccc_ccmsg_invalidate isccc_lib_initmsgcat isccc_result_totext isccc_result_register isccc_sexpr_cons isccc_sexpr_tconst isccc_sexpr_fromstring isccc_sexpr_frombinary isccc_sexpr_free isccc_sexpr_print isccc_sexpr_car isccc_sexpr_cdr isccc_sexpr_setcar isccc_sexpr_setcdr isccc_sexpr_addtolist isccc_sexpr_listp isccc_sexpr_emptyp isccc_sexpr_stringp isccc_sexpr_binaryp isccc_sexpr_tostring isccc_sexpr_tobinary isccc_symtab_destroy isccc_symtab_create isccc_symtab_destroy isccc_symtab_lookup isccc_symtab_define isccc_symtab_undefine isccc_symtab_foreach bind9-9.10.3.dfsg.P4/lib/isccc/win32/version.c0000644000470500017500000000233012664710322020014 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: version.c,v 1.7 2007/06/19 23:47:22 tbox Exp $ */ #include #include LIBISCCC_EXTERNAL_DATA const char isccc_version[] = VERSION; LIBISCCC_EXTERNAL_DATA const unsigned int isccc_libinterface = LIBINTERFACE; LIBISCCC_EXTERNAL_DATA const unsigned int isccc_librevision = LIBREVISION; LIBISCCC_EXTERNAL_DATA const unsigned int isccc_libage = LIBAGE; bind9-9.10.3.dfsg.P4/lib/isccc/win32/libisccc.mak.in0000644000470500017500000003233112664710322021041 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on libisccc.dsp !IF "$(CFG)" == "" CFG=libisccc - @PLATFORM@ Release !MESSAGE No configuration specified. Defaulting to libisccc - @PLATFORM@ Release. !ENDIF !IF "$(CFG)" != "libisccc - @PLATFORM@ Release" && "$(CFG)" != "libisccc - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "libisccc.mak" CFG="libisccc - @PLATFORM@ Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "libisccc - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE "libisccc - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "libisccc - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "libisccc - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release !IF "$(RECURSE)" == "0" ALL : "..\..\..\Build\Release\libisccc.dll" !ELSE ALL : "libisc - @PLATFORM@ Release" "..\..\..\Build\Release\libisccc.dll" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libisc - @PLATFORM@ ReleaseCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\alist.obj" -@erase "$(INTDIR)\base64.obj" -@erase "$(INTDIR)\cc.obj" -@erase "$(INTDIR)\ccmsg.obj" -@erase "$(INTDIR)\DLLMain.obj" -@erase "$(INTDIR)\lib.obj" -@erase "$(INTDIR)\result.obj" -@erase "$(INTDIR)\sexpr.obj" -@erase "$(INTDIR)\symtab.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\version.obj" -@erase "$(OUTDIR)\libisccc.exp" -@erase "$(OUTDIR)\libisccc.lib" -@erase "..\..\..\Build\Release\libisccc.dll" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isc/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ /D "LIBISCCC_EXPORTS" /Fp"$(INTDIR)\libisccc.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\libisccc.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Release/libisc.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\libisccc.pdb" @MACHINE@ /def:".\libisccc.def" /out:"../../../Build/Release/libisccc.dll" /implib:"$(OUTDIR)\libisccc.lib" DEF_FILE= \ ".\libisccc.def" LINK32_OBJS= \ "$(INTDIR)\alist.obj" \ "$(INTDIR)\base64.obj" \ "$(INTDIR)\cc.obj" \ "$(INTDIR)\ccmsg.obj" \ "$(INTDIR)\DLLMain.obj" \ "$(INTDIR)\lib.obj" \ "$(INTDIR)\result.obj" \ "$(INTDIR)\sexpr.obj" \ "$(INTDIR)\symtab.obj" \ "$(INTDIR)\version.obj" \ "..\..\isc\win32\Release\libisc.lib" "..\..\..\Build\Release\libisccc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_DLL) !ELSEIF "$(CFG)" == "libisccc - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros !IF "$(RECURSE)" == "0" ALL : "..\..\..\Build\Debug\libisccc.dll" "$(OUTDIR)\libisccc.bsc" !ELSE ALL : "libisc - @PLATFORM@ Debug" "..\..\..\Build\Debug\libisccc.dll" "$(OUTDIR)\libisccc.bsc" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libisc - @PLATFORM@ DebugCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\alist.obj" -@erase "$(INTDIR)\alist.sbr" -@erase "$(INTDIR)\base64.obj" -@erase "$(INTDIR)\base64.sbr" -@erase "$(INTDIR)\cc.obj" -@erase "$(INTDIR)\cc.sbr" -@erase "$(INTDIR)\ccmsg.obj" -@erase "$(INTDIR)\ccmsg.sbr" -@erase "$(INTDIR)\DLLMain.obj" -@erase "$(INTDIR)\DLLMain.sbr" -@erase "$(INTDIR)\lib.obj" -@erase "$(INTDIR)\lib.sbr" -@erase "$(INTDIR)\result.obj" -@erase "$(INTDIR)\result.sbr" -@erase "$(INTDIR)\sexpr.obj" -@erase "$(INTDIR)\sexpr.sbr" -@erase "$(INTDIR)\symtab.obj" -@erase "$(INTDIR)\symtab.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(INTDIR)\version.obj" -@erase "$(INTDIR)\version.sbr" -@erase "$(OUTDIR)\libisccc.bsc" -@erase "$(OUTDIR)\libisccc.exp" -@erase "$(OUTDIR)\libisccc.lib" -@erase "$(OUTDIR)\libisccc.pdb" -@erase "..\..\..\Build\Debug\libisccc.dll" -@erase "..\..\..\Build\Debug\libisccc.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isc/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ /D "LIBISCCC_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\libisccc.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\libisccc.bsc" BSC32_SBRS= \ "$(INTDIR)\alist.sbr" \ "$(INTDIR)\base64.sbr" \ "$(INTDIR)\cc.sbr" \ "$(INTDIR)\ccmsg.sbr" \ "$(INTDIR)\DLLMain.sbr" \ "$(INTDIR)\lib.sbr" \ "$(INTDIR)\result.sbr" \ "$(INTDIR)\sexpr.sbr" \ "$(INTDIR)\symtab.sbr" \ "$(INTDIR)\version.sbr" "$(OUTDIR)\libisccc.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../isc/win32/debug/libisc.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\libisccc.pdb" /debug @MACHINE@ /def:".\libisccc.def" /out:"../../../Build/Debug/libisccc.dll" /implib:"$(OUTDIR)\libisccc.lib" /pdbtype:sept DEF_FILE= \ ".\libisccc.def" LINK32_OBJS= \ "$(INTDIR)\alist.obj" \ "$(INTDIR)\base64.obj" \ "$(INTDIR)\cc.obj" \ "$(INTDIR)\ccmsg.obj" \ "$(INTDIR)\DLLMain.obj" \ "$(INTDIR)\lib.obj" \ "$(INTDIR)\result.obj" \ "$(INTDIR)\sexpr.obj" \ "$(INTDIR)\symtab.obj" \ "$(INTDIR)\version.obj" \ "..\..\isc\win32\Debug\libisc.lib" "..\..\..\Build\Debug\libisccc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_DLL) !ENDIF .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("libisccc.dep") !INCLUDE "libisccc.dep" !ELSE !MESSAGE Warning: cannot find "libisccc.dep" !ENDIF !ENDIF !IF "$(CFG)" == "libisccc - @PLATFORM@ Release" || "$(CFG)" == "libisccc - @PLATFORM@ Debug" SOURCE=..\alist.c !IF "$(CFG)" == "libisccc - @PLATFORM@ Release" "$(INTDIR)\alist.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisccc - @PLATFORM@ Debug" "$(INTDIR)\alist.obj" "$(INTDIR)\alist.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\base64.c !IF "$(CFG)" == "libisccc - @PLATFORM@ Release" "$(INTDIR)\base64.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisccc - @PLATFORM@ Debug" "$(INTDIR)\base64.obj" "$(INTDIR)\base64.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\cc.c !IF "$(CFG)" == "libisccc - @PLATFORM@ Release" "$(INTDIR)\cc.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisccc - @PLATFORM@ Debug" "$(INTDIR)\cc.obj" "$(INTDIR)\cc.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\ccmsg.c !IF "$(CFG)" == "libisccc - @PLATFORM@ Release" "$(INTDIR)\ccmsg.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisccc - @PLATFORM@ Debug" "$(INTDIR)\ccmsg.obj" "$(INTDIR)\ccmsg.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=.\DLLMain.c !IF "$(CFG)" == "libisccc - @PLATFORM@ Release" "$(INTDIR)\DLLMain.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisccc - @PLATFORM@ Debug" "$(INTDIR)\DLLMain.obj" "$(INTDIR)\DLLMain.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF SOURCE=..\lib.c !IF "$(CFG)" == "libisccc - @PLATFORM@ Release" "$(INTDIR)\lib.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisccc - @PLATFORM@ Debug" "$(INTDIR)\lib.obj" "$(INTDIR)\lib.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\result.c !IF "$(CFG)" == "libisccc - @PLATFORM@ Release" "$(INTDIR)\result.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisccc - @PLATFORM@ Debug" "$(INTDIR)\result.obj" "$(INTDIR)\result.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\sexpr.c !IF "$(CFG)" == "libisccc - @PLATFORM@ Release" "$(INTDIR)\sexpr.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisccc - @PLATFORM@ Debug" "$(INTDIR)\sexpr.obj" "$(INTDIR)\sexpr.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\symtab.c !IF "$(CFG)" == "libisccc - @PLATFORM@ Release" "$(INTDIR)\symtab.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "libisccc - @PLATFORM@ Debug" "$(INTDIR)\symtab.obj" "$(INTDIR)\symtab.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=.\version.c !IF "$(CFG)" == "libisccc - @PLATFORM@ Release" "$(INTDIR)\version.obj" : $(SOURCE) "$(INTDIR)" !ELSEIF "$(CFG)" == "libisccc - @PLATFORM@ Debug" "$(INTDIR)\version.obj" "$(INTDIR)\version.sbr" : $(SOURCE) "$(INTDIR)" !ENDIF !IF "$(CFG)" == "libisccc - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" cd "..\..\isccc\win32" "libisc - @PLATFORM@ ReleaseCLEAN" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\isccc\win32" !ELSEIF "$(CFG)" == "libisccc - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" cd "..\..\isccc\win32" "libisc - @PLATFORM@ DebugCLEAN" : cd "..\..\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\isccc\win32" !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/lib/isccc/win32/libisccc.vcxproj.filters.in0000644000470500017500000000614312664710322023435 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files bind9-9.10.3.dfsg.P4/lib/isccc/win32/libisccc.vcxproj.user0000644000470500017500000000021712664710322022332 0ustar lamontlamont bind9-9.10.3.dfsg.P4/lib/isccc/win32/libisccc.dsp.in0000644000470500017500000001370112664710322021057 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="libisccc" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Dynamic-Link Library" 0x0102 CFG=libisccc - @PLATFORM@ Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "libisccc.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "libisccc.mak" CFG="libisccc - @PLATFORM@ Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "libisccc - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE "libisccc - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "libisccc - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "libisccc_EXPORTS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isc/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ /D "LIBISCCC_EXPORTS" @COPTY@ /FD /c # SUBTRACT CPP /X # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll @MACHINE@ # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../isc/win32/Release/libisc.lib /nologo /dll @MACHINE@ /out:"../../../Build/Release/libisccc.dll" !ELSEIF "$(CFG)" == "libisccc - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "libisccc_EXPORTS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "include" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/dns/win32/include" /I "../../../lib/dns/include" /I "../../../lib/isc/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "USE_MD5" @CRYPTO@ /D "LIBISCCC_EXPORTS" /FR @COPTY@ /FD /GZ /c # SUBTRACT CPP /X # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib ws2_32.lib ../../isc/win32/debug/libisc.lib /nologo /dll /debug @MACHINE@ /out:"../../../Build/Debug/libisccc.dll" /pdbtype:sept !ENDIF # Begin Target # Name "libisccc - @PLATFORM@ Release" # Name "libisccc - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\alist.c # End Source File # Begin Source File SOURCE=..\base64.c # End Source File # Begin Source File SOURCE=..\cc.c # End Source File # Begin Source File SOURCE=..\ccmsg.c # End Source File # Begin Source File SOURCE=.\DLLMain.c # End Source File # Begin Source File SOURCE=..\lib.c # End Source File # Begin Source File SOURCE=..\result.c # End Source File # Begin Source File SOURCE=..\sexpr.c # End Source File # Begin Source File SOURCE=..\symtab.c # End Source File # Begin Source File SOURCE=.\version.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=..\include\isccc\alist.h # End Source File # Begin Source File SOURCE=..\include\isccc\base64.h # End Source File # Begin Source File SOURCE=..\include\isccc\cc.h # End Source File # Begin Source File SOURCE=..\include\isccc\ccmsg.h # End Source File # Begin Source File SOURCE=..\include\isccc\events.h # End Source File # Begin Source File SOURCE=..\include\isccc\lib.h # End Source File # Begin Source File SOURCE=..\include\isccc\result.h # End Source File # Begin Source File SOURCE=..\include\isccc\sexpr.h # End Source File # Begin Source File SOURCE=..\include\isccc\symtab.h # End Source File # Begin Source File SOURCE=..\include\isccc\symtype.h # End Source File # Begin Source File SOURCE=..\include\isccc\types.h # End Source File # Begin Source File SOURCE=..\include\isccc\util.h # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # Begin Source File SOURCE=.\libisccc.def # End Source File # End Target # End Project bind9-9.10.3.dfsg.P4/lib/isccc/win32/DLLMain.c0000644000470500017500000000313212664710322017550 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: DLLMain.c,v 1.6 2007/06/18 23:47:50 tbox Exp $ */ #include #include /* * Called when we enter the DLL */ __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { /* * The DLL is loading due to process * initialization or a call to LoadLibrary. */ case DLL_PROCESS_ATTACH: break; /* The attached process creates a new thread. */ case DLL_THREAD_ATTACH: break; /* The thread of the attached process terminates. */ case DLL_THREAD_DETACH: break; /* * The DLL is unloading from a process due to * process termination or a call to FreeLibrary. */ case DLL_PROCESS_DETACH: break; default: break; } return (TRUE); } bind9-9.10.3.dfsg.P4/lib/isccc/win32/libisccc.dsw0000644000470500017500000000103312664710322020454 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "libisccc"=.\libisccc.dsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/lib/isccc/win32/libisccc.vcxproj.in0000644000470500017500000001726612664710322021776 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {B556705F-1920-4400-878A-B259D3556047} Win32Proj libisccc DynamicLibrary true MultiByte DynamicLibrary false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ Level3 Disabled WIN32;USE_MD5;@CRYPTO@_DEBUG;_WINDOWS;_USRDLL;LIBISCCC_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions) .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@include;..\include;..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;..\..\dns\include;%(AdditionalIncludeDirectories) false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) ..\..\isc\win32\$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;ws2_32.lib;%(AdditionalDependencies) $(ProjectName).def .\$(Configuration)\$(ProjectName).lib Level3 MaxSpeed true @INTRINSIC@ WIN32;USE_MD5;@CRYPTO@NDEBUG;_WINDOWS;_USRDLL;LIBISCCC_EXPORTS;%(PreprocessorDefinitions);%(PreprocessorDefinitions) .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@include;..\include;..\..\isc\win32;..\..\isc\win32\include;..\..\isc\include;..\..\dns\include;%(AdditionalIncludeDirectories) OnlyExplicitInline true .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb false Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) ..\..\isc\win32\$(Configuration);%(AdditionalLibraryDirectories) libisc.lib;ws2_32.lib;%(AdditionalDependencies) $(ProjectName).def .\$(Configuration)\$(ProjectName).lib Default bind9-9.10.3.dfsg.P4/lib/isccc/api0000644000470500017500000000025612664710322015722 0ustar lamontlamont# LIBINTERFACE ranges # 9.6: 50-59, 110-119 # 9.7: 60-79 # 9.8: 80-89, 120-129 # 9.9: 90-109 # 9.9-sub: 130-139 # 9.10: 140-149 LIBINTERFACE = 140 LIBREVISION = 4 LIBAGE = 0 bind9-9.10.3.dfsg.P4/CHANGES0000644000470500017500000157025712664710322014405 0ustar lamontlamont --- 9.10.3-P4 released --- 4322. [security] Duplicate EDNS COOKIE options in a response could trigger an assertion failure. (CVE-2016-2088) [RT #41809] 4319. [security] Fix resolver assertion failure due to improper DNAME handling when parsing fetch reply messages. (CVE-2016-1286) [RT #41753] 4318. [security] Malformed control messages can trigger assertions in named and rndc. (CVE-2016-1285) [RT #41666] --- 9.10.3-P3 released --- 4288. [bug] Fixed a regression in resolver.c:possibly_mark() which caused known-bogus servers to be queried anyway. [RT #41321] 4286. [security] render_ecs errors were mishandled when printing out a OPT record resulting in a assertion failure. (CVE-2015-8705) [RT #41397] 4285. [security] Specific APL data could trigger a INSIST. (CVE-2015-8704) [RT #41396] --- 9.10.3-P2 released --- 4270. [security] Update allowed OpenSSL versions as named is potentially vulnerable to CVE-2015-3193. 4261. [maint] H.ROOT-SERVERS.NET is 198.97.190.53 and 2001:500:1::53. [RT #40556] 4260. [security] Insufficient testing when parsing a message allowed records with an incorrect class to be be accepted, triggering a REQUIRE failure when those records were subsequently cached. (CVE-2015-8000) [RT #40987] 4253. [security] Address fetch context reference count handling error on socket error. (CVE-2015-8461) [RT#40945] --- 9.10.3-P1 (withdrawn) --- --- 9.10.3 released --- --- 9.10.3rc1 released --- 4193. [bug] Handle broken servers that return BADVERS incorrectly. [RT #40427] 4192. [bug] The default rrset-order of random was not always being applied. [RT #40456] 4191. [protocol] Accept DNS-SD non LDH PTR records in reverse zones as per RFC 6763. [RT #37889] 4190. [protocol] Accept Active Diretory gc._msdcs. name as valid with check-names. still needs to be LDH. [RT #40399] 4189. [cleanup] Don't exit on overly long tokens in named.conf. [RT #40418] 4188. [bug] Support HTTP/1.0 client properly on the statistics channel. [RT #40261] 4187. [func] When any RR type implementation doesn't implement totext() for the RDATA's wire representation and returns ISC_R_NOTIMPLEMENTED, such RDATA is now printed in unknown presentation format (RFC 3597). RR types affected include LOC(29) and APL(42). [RT #40317]. 4186. [bug] Fixed an RPZ bug where a QNAME would be matched against a policy RR with wildcard owner name (trigger) where the QNAME was the wildcard owner name's parent. For example, the bug caused a query with QNAME "example.com" to match a policy RR with "*.example.com" as trigger. [RT #40357] 4185. [bug] Fixed an RPZ bug where a policy RR with wildcard owner name (trigger) would prevent another policy RR with its parent owner name from being loaded. For example, the bug caused a policy RR with trigger "example.com" to not have any effect when a previous policy RR with trigger "*.example.com" existed in that RPZ zone. [RT #40357] 4183. [cleanup] Use timing-safe memory comparisons in cryptographic code. Also, the timing-safe comparison functions have been renamed to avoid possible confusion with memcmp(). Thanks to Loganaden Velvindron of AFRINIC. [RT #40148] 4182. [cleanup] Use mnemonics for RR class and type comparisons. [RT #40297] 4181. [bug] Queued notify messages could be dequeued from the wrong rate limiter queue. [RT #40350] 4179. [bug] Fix double frees in getaddrinfo() in libirs. [RT #40209] 4178. [bug] Fix assertion failure in parsing UNSPEC(103) RR from text. [RT #40274] 4177. [bug] Fix assertion failure in parsing NSAP records from text. [RT #40285] 4176. [bug] Address race issues with lwresd. [RT #40284] 4175. [bug] TKEY with GSS-API keys needed bigger buffers. [RT #40333] 4174. [bug] "dnssec-coverage -r" didn't handle time unit suffixes correctly. [RT #38444] 4173. [bug] dig +sigchase was not properly matching the trusted key. [RT #40188] 4172. [bug] Named / named-checkconf didn't handle a view of CLASS0. [RT #40265] 4171. [bug] Fixed incorrect class checks in TSIG RR implementation. [RT #40287] 4170. [security] An incorrect boundary check in the OPENPGPKEY rdatatype could trigger an assertion failure. (CVE-2015-5986) [RT #40286] 4169. [test] Added a 'wire_test -d' option to read input as raw binary data, for use as a fuzzing harness. [RT #40312] 4168. [security] A buffer accounting error could trigger an assertion failure when parsing certain malformed DNSSEC keys. (CVE-2015-5722) [RT #40212] --- 9.10.3b1 released --- 4165. [security] A failure to reset a value to NULL in tkey.c could result in an assertion failure. (CVE-2015-5477) [RT #40046] 4164. [bug] Don't rename slave files and journals on out of memory. [RT #40033] 4163. [bug] Address compiler warnings. [RT #40024] 4162. [bug] httpdmgr->flags was not being initialized. [RT #40017] 4161. [test] Test for consistency between "rndc stats" and the XML and JSON statistics channel contents. [RT #38700] 4159. [cleanup] Alphabetize dig's help output. [RT #39966] 4157. [protocol] Update experimental SIT code to use the EDNS COOKIE option code point (10). This is the minimal change required to use the new code point. [RT #39928] 4154. [bug] A OPT record should be included with the FORMERR response when there is a malformed EDNS option. [RT #39647] 4153. [bug] Dig should zero non significant +subnet bits. Check that non significant ECS bits are zero on receipt. [RT #39647] 4151. [bug] 'rndc flush' could cause a deadlock. [RT #39835] 4150. [bug] win32: listen-on-v6 { any; }; was not working. Apply minimal fix. [RT #39667] 4149. [bug] Fixed a race condition in the getaddrinfo() implementation in libirs, which caused the delv utility to crash with an assertion failure when using the '@server' syntax with a hostname argument. [RT #39899] 4148. [bug] Fix a bug when printing zone names with '/' character in XML and JSON statistics output. [RT #39873] 4147. [bug] Filter-aaaa / filter-aaaa-on-v4 / filter-aaaa-on-v6 was returning referrals rather than nodata responses when the AAAA records were filtered. [RT #39843] 4146. [bug] Address reference leak that could prevent a clean shutdown. [RT #37125] 4145. [bug] Not all unassociated adb entries where being printed. [RT #37125] 4143. [bug] serial-query-rate was not effective for notify. [RT #39858] 4142. [bug] rndc addzone with view specified saved NZF config that could not be read back by named. This has now been fixed. [RT #39845] 4141. [bug] A formatting bug caused rndc zonestatus to print negative numbers for large serial values. This has now been fixed. [RT #39854] 4139. [doc] Fix rpz-client-ip documentation. [RT #39783] 4138. [security] An uninitialized value in validator.c could result in an assertion failure. (CVE-2015-4620) [RT #39795] 4137. [bug] Make rndc reconfig report configuration errors the same way rndc reload does. [RT #39635] 4136. [bug] Stale statistics counters with the leading '#' prefix (such as #NXDOMAIN) were not being updated correctly. This has been fixed. [RT #39141] 4134. [cleanup] Include client-ip rules when logging the number of RPZ rules of each type. [RT #39670] 4133. [port] Update how various json libraries are handled. [RT #39646] 4132. [cleanup] dig: added +rd as a synonym for +recurse, added +class as an unabbreviated alternative to +cl. [RT #39686] 4131. [bug] Addressed further problems with reloading RPZ zones. [RT #39649] 4130. [bug] The compatibility shim for *printf() misprinted some large numbers. [RT #39586] 4129. [port] Address API changes in OpenSSL 1.1.0. [RT #39532] 4128. [bug] Address issues raised by Coverity 7.6. [RT #39537] 4127. [protocol] CDS and CDNSKEY need to be signed by the key signing key as per RFC 7344, Section 4.1. [RT #37215] 4126. [bug] Addressed a regression introduced in change #4121. [RT #39611] 4123. [port] Added %z (size_t) format options to the portable internal printf/sprintf implementation. [RT #39586] 4122. [bug] The server could match a shorter prefix than what was available in CLIENT-IP policy triggers, and so, an unexpected action could be taken. This has been corrected. [RT #39481] 4121. [bug] On servers with one or more policy zones configured as slaves, if a policy zone updated during regular operation (rather than at startup) using a full zone reload, such as via AXFR, a bug could allow the RPZ summary data to fall out of sync, potentially leading to an assertion failure in rpz.c when further incremental updates were made to the zone, such as via IXFR. [RT #39567] 4120. [bug] A bug in RPZ could cause the server to crash if policy zones were updated while recursion was pending for RPZ processing of an active query. [RT #39415] 4119. [test] Allow dig to set the message opcode. [RT #39550] 4118. [bug] Teach isc-config.sh about irs. [RT #39213] 4117. [protocol] Add EMPTY.AS112.ARPA as per RFC 7534. 4116. [bug] Fix a bug in RPZ that could cause some policy zones that did not specifically require recursion to be treated as if they did; consequently, setting qname-wait-recurse no; was sometimes ineffective. [RT #39229] 4113. [test] Check for Net::DNS is some system test prerequisites. [RT #39369] 4112. [bug] Named failed to load when "root-delegation-only" was used without a list of domains to exclude. [RT #39380] 4111. [doc] Alphabetize rndc man page. [RT #39360] 4110. [bug] Address memory leaks / null pointer dereferences on out of memory. [RT #39310] 4109. [port] linux: support reading the local port range from net.ipv4.ip_local_port_range. [RT # 39379] 4107. [bug] Address potential deadlock when updating zone content. [RT #39269] 4106. [port] Improve readline support. [RT #38938] 4105. [port] Misc fixes for Microsoft Visual Studio 2015 CTP6 in 64 bit mode. [RT #39308] 4104. [bug] Address uninitialized elements. [RT #39252] 4102. [bug] Fix a use after free bug introduced in change #4094. [RT #39281] 4101. [bug] dig: the +split and +rrcomments options didn't work with +short. [RT #39291] 4100. [bug] Inherited owernames on the line immediately following a $INCLUDE were not working. [RT #39268] 4099. [port] clang: make unknown commandline options hard errors when determining what options are supported. [RT #39273] 4098. [bug] Address use-after-free issue when using a predecessor key with dnssec-settime. [RT #39272] 4097. [func] Add additional logging about xfrin transfer status. [RT #39170] 4096. [bug] Fix a use after free of query->sendevent. [RT #39132] 4095. [bug] zone->options2 was not being properly initialized. [RT #39228] 4094. [bug] A race during shutdown or reconfiguration could cause an assertion in mem.c. [RT #38979] 4093. [func] Dig now learns the SIT value from truncated responses when it retries over TCP. [RT #39047] 4092. [bug] 'in-view' didn't work for zones beneath a empty zone. [RT #39173] 4091. [cleanup] Some cleanups in isc mem code. [RT #38896] 4090. [bug] Fix a crash while parsing malformed CAA RRs in presentation format, i.e., from text such as from master files. Thanks to John Van de Meulebrouck Brendgard for discovering and reporting this problem. [RT #39003] 4089. [bug] Send notifies immediately for slave zones during startup. [RT #38843] 4088. [port] Fixed errors when building with libressl. [RT #38899] 4087. [bug] Fix a crash due to use-after-free due to sequencing of tasks actions. [RT #38495] 4086. [bug] Fix out-of-srcdir build with native pkcs11. [RT #38831] 4085. [bug] ISC_PLATFORM_HAVEXADDQ could be inconsistently set. [RT #38828] 4084. [bug] Fix a possible race in updating stats counters. [RT #38826] 4082. [bug] Incrementally sign large inline zone deltas. [RT #37927] 4081. [cleanup] Use dns_rdatalist_init consistently. [RT #38759] 4078. [bug] Handle the case where CMSG_SPACE(sizeof(int)) != CMSG_SPACE(sizeof(char)). [RT #38621] 4077. [test] Add static-stub regression test for DS NXDOMAIN return making the static stub disappear. [RT #38564] 4076. [bug] Named could crash on shutdown with outstanding reload / reconfig events. [RT #38622] 4074. [cleanup] Cleaned up more warnings from gcc -Wshadow. [RT #38708] 4073. [cleanup] Add libjson-c version number reporting to "named -V"; normalize version number formatting. [RT #38056] 4072. [func] Add a --enable-querytrace configure switch for very verbose query trace logging. (This option has a negative performance impact and should be used only for debugging.) [RT #37520] 4071. [cleanup] Initialize pthread mutex attrs just once, instead of doing it per mutex creation. [RT #38547] 4070. [bug] Fix a segfault in nslookup in a query such as "nslookup isc.org AMS.SNS-PB.ISC.ORG -all". [RT #38548] 4069. [doc] Reorganize options in the nsupdate man page. [RT #38515] 4068. [bug] Omit unknown serial number from JSON zone statistics. [RT #38604] 4067. [cleanup] Reduce noise from RRL when query logging is disabled. [RT #38648] 4066. [doc] Reorganize options in the dig man page. [RT #38516] 4064. [contrib] dnssec-keyset.sh: Generates a specified number of DNSSEC keys with timing set to implement a pre-publication key rollover strategy. Thanks to Jeffry A. Spain. [RT #38459] 4063. [bug] Asynchronous zone loads were not handled correctly when the zone load was already in progress; this could trigger a crash in zt.c. [RT #37573] 4062. [bug] Fix an out-of-bounds read in RPZ code. If the read succeeded, it doesn't result in a bug during operation. If the read failed, named could segfault. [RT #38559] 3993. [func] Dig now supports EDNS negotiation by default. (dig +[no]ednsnegotiation). Note: This is disabled by default in BIND 9.10 and enabled by default in BIND 9.11. [RT #37604] 3951. [func] Add the ability to set yet-to-be-defined EDNS flags to dig (+ednsflags=#). [RT #37142] 3938. [func] Added quotas to be used in recursive resolvers that are under high query load for names in zones whose authoritative servers are nonresponsive or are experiencing a denial of service attack. - "fetches-per-server" limits the number of simultaneous queries that can be sent to any single authoritative server. The configured value is a starting point; it is automatically adjusted downward if the server is partially or completely non-responsive. The algorithm used to adjust the quota can be configured via the "fetch-quota-params" option. - "fetches-per-zone" limits the number of simultaneous queries that can be sent for names within a single domain. (Note: Unlike "fetches-per-server", this value is not self-tuning.) - New stats counters have been added to count queries spilled due to these quotas. These options are not available by default; use "configure --enable-fetchlimit" (or --enable-developer) to include them in the build. See the ARM for details of these options. [RT #37125] 3937. [func] Added some debug logging to better indicate the conditions causing SERVFAILs when resolving. [RT #35538] 3812. [func] Dig now supports sending arbitary EDNS options from the command line (+ednsopt=code[:value]). [RT #35584] --- 9.10.2 released --- --- 9.10.2rc2 released --- 4061. [bug] Handle timeout in legacy system test. [RT #38573] 4060. [bug] dns_rdata_freestruct could be called on a uninitialized structure when handling a error. [RT #38568] 4059. [bug] Addressed valgrind warnings. [RT #38549] 4058. [bug] UDP dispatches could use the wrong pseudorandom number generator context. [RT #38578] 4056. [bug] Fixed several small bugs in automatic trust anchor management, including a memory leak and a possible loss of key state information. [RT #38458] 4057. [bug] 'dnssec-dsfromkey -T 0' failed to add ttl field. [RT #38565] 4053. [security] Revoking a managed trust anchor and supplying an untrusted replacement could cause named to crash with an assertion failure. (CVE-2015-1349) [RT #38344] 4052. [bug] Fix a leak of query fetchlock. [RT #38454] 4051. [bug] Fix a leak of pthread_mutexattr_t. [RT #38454] 4050. [bug] RPZ could send spurious SERVFAILs in response to duplicate queries. [RT #38510] 4049. [bug] CDS and CDNSKEY had the wrong attributes. [RT #38491] 4048. [bug] adb hash table was not being grown. [RT #38470] --- 9.10.2rc1 released --- 4047. [cleanup] "named -V" now reports the current running versions of OpenSSL and the libxml2 libraries, in addition to the versions that were in use at build time. 4046. [bug] Accounting of "total use" in memory context statistics was not correct. [RT #38370] 4045. [bug] Skip to next master on dns_request_createvia4 failure. [RT #25185] 4044. [bug] Change 3955 was not complete, resulting in an assertion failure if the timing was just right. [RT #38352] 4039. [cleanup] Cleaned up warnings from gcc -Wshadow. [RT #37381] 4038. [bug] Add 'rpz' flag to node and use it to determine whether to call dns_rpz_delete. This should prevent unbalanced add / delete calls. [RT #36888] 4037. [bug] also-notify was ignoring the tsig key when checking for duplicates resulting in some expected notify messages not being sent. [RT #38369] 4035. [bug] Close temporary and NZF FILE pointers before moving the former into the latter's place, as required on Windows. [RT #38332] 4033. [bug] Missing out of memory check in request.c:req_send. [RT #38311] 4032. [bug] Built-in "empty" zones did not correctly inherit the "allow-transfer" ACL from the options or view. [RT #38310] 4031. [bug] named-checkconf -z failed to report a missing file with a hint zone. [RT #38294] 4028. [bug] $GENERATE with a zero step was not being caught as a error. A $GENERATE with a / but no step was not being caught as a error. [RT #38262] 3973. [test] Added hooks for Google Performance Tools CPU profiler, including real-time/wall-clock profiling. Use "configure --with-gperftools-profiler" to enable. [RT #37339] --- 9.10.2b1 released --- 4027. [port] Net::DNS 0.81 compatibility. [RT #38165] 4026. [bug] Fix RFC 3658 reference in dig +sigchase. [RT #38173] 4025. [port] bsdi: failed to build. [RT #38047] 4024. [bug] dns_rdata_opt_first, dns_rdata_opt_next, dns_rdata_opt_current, dns_rdata_txt_first, dns_rdata_txt_next and dns_rdata_txt_current were documented but not implemented. These have now been implemented. dns_rdata_spf_first, dns_rdata_spf_next and dns_rdata_spf_current were documented but not implemented. The prototypes for these functions have been removed. [RT #38068] 4023. [bug] win32: socket handling with explicit ports and invoking named with -4 was broken for some configurations. [RT #38068] 4021. [bug] Adjust max-recursion-queries to accommodate the need for more queries when the cache is empty. [RT #38104] 4020. [bug] Change 3736 broke nsupdate's SOA MNAME discovery resulting in updates being sent to the wrong server. [RT #37925] 4019. [func] If named is not configured to validate the answer then allow fallback to plain DNS on timeout even when we know the server supports EDNS. [RT #37978] 4017. [test] Add system test to check lookups to legacy servers with broken DNS behavior. [RT #37965] 4016. [bug] Fix a dig segfault due to bad linked list usage. [RT #37591] 4015. [bug] Nameservers that are skipped due to them being CNAMEs were not being logged. They are now logged to category 'cname' as per BIND 8. [RT #37935] 4014. [bug] When including a master file origin_changed was not being properly set leading to a potentially spurious 'inherited owner' warning. [RT #37919] 4012. [bug] Check returned status of OpenSSL digest and HMAC functions when they return one. Note this applies only to FIPS capable OpenSSL libraries put in FIPS mode and MD5. [RT #37944] 4011. [bug] master's list port and dscp inheritance was not properly implemented. [RT #37792] 4010. [cleanup] Clear the prefetchable state when initiating a prefetch. [RT #37399] 4008. [contrib] Updated zkt to latest version (1.1.3). [RT #37886] 4007. [doc] Remove acl forward reference restriction. [RT #37772] 4006. [security] A flaw in delegation handling could be exploited to put named into an infinite loop. This has been addressed by placing limits on the number of levels of recursion named will allow (default 7), and the number of iterative queries that it will send (default 50) before terminating a recursive query (CVE-2014-8500). The recursion depth limit is configured via the "max-recursion-depth" option, and the query limit via the "max-recursion-queries" option. [RT #37580] 4004. [bug] When delegations had AAAA glue but not A, a reference could be leaked causing an assertion failure on shutdown. [RT #37796] 4003. [security] When geoip-directory was reconfigured during named run-time, the previously loaded GeoIP data could remain, potentially causing wrong ACLs to be used or wrong results to be served based on geolocation (CVE-2014-8680). [RT #37720] 4002. [security] Lookups in GeoIP databases that were not loaded could cause an assertion failure (CVE-2014-8680). [RT #37679] 4001. [security] The caching of GeoIP lookups did not always handle address families correctly, potentially resulting in an assertion failure (CVE-2014-8680). [RT #37672] 4000. [bug] NXDOMAIN redirection incorrectly handled NXRRSET from the redirect zone. [RT #37722] 3998. [bug] isc_radix_search was returning matches that were too precise. [RT #37680] 3997. [protocol] Add OPENGPGKEY record. [RT# 37671] 3996. [bug] Address use after free on out of memory error in keyring_add. [RT #37639] 3995. [bug] receive_secure_serial holds the zone lock for too long. [RT #37626] 3990. [testing] Add tests for unknown DNSSEC algorithm handling. [RT #37541] 3989. [cleanup] Remove redundant dns_db_resigned calls. [RT #35748] 3987. [func] Handle future Visual Studio 14 incompatible changes. [RT #37380] 3986. [doc] Add the BIND version number to page footers in the ARM. [RT #37398] 3985. [doc] Describe how +ndots and +search interact in dig. [RT #37529] 3984. [func] Accept 256 byte long PINs in native PKCS#11 crypto. [RT #37410] 3982. [doc] Include release notes in product documentation. [RT #37272] 3981. [bug] Cache DS/NXDOMAIN independently of other query types. [RT #37467] 3980. [bug] Improve --with-tuning=large by self tuning of SO_RCVBUF size. [RT #37187] 3978. [test] Added a unit test for Diffie-Hellman key computation, completing change #3974. [RT #37477] 3976. [bug] When refreshing managed-key trust anchors, clear any cached trust so that they will always be revalidated with the current set of secure roots. [RT #37506] 3974. [bug] Handle DH_compute_key() failure correctly in openssldh_link.c. [RT #37477] 3972. [bug] Fix host's usage statement. [RT #37397] 3971. [bug] Reduce the cascading failures due to a bad $TTL line in named-checkconf / named-checkzone. [RT #37138] 3970. [contrib] Fixed a use after free bug in the SDB LDAP driver. [RT #37237] 3969. [test] Added 'delv' system test. [RT #36901] 3968. [bug] Silence spurious log messages when using 'named -[46]'. [RT #37308] 3967. [test] Add test for inlined signed zone in multiple views with different DNSKEY sets. [RT #35759] 3966. [bug] Missing dns_db_closeversion call in receive_secure_db. [RT #35746] 3962. [bug] 'dig +topdown +trace +sigchase' address unhandled error conditions. [RT #34663] 3961. [bug] Forwarding of SIG(0) signed UPDATE messages failed with BADSIG. [RT #37216] 3960. [bug] 'dig +sigchase' could loop forever. [RT #37220] 3959. [bug] Updates could be lost if they arrived immediately after a rndc thaw. [RT #37233] 3958. [bug] Detect when writeable files have multiple references in named.conf. [RT #37172] 3957. [bug] "dnssec-keygen -S" failed for ECCGOST, ECDSAP256SHA256 and ECDSAP384SHA384. [RT #37183] 3955. [bug] Notify messages due to changes are no longer queued behind startup notify messages. [RT #24454] 3954. [bug] Unchecked mutex init in dlz_dlopen_driver.c [RT #37112] 3953. [bug] Don't escape semi-colon in TXT fields. [RT #37159] 3952. [bug] dns_name_fullcompare failed to set *nlabelsp when the two name pointers were the same. [RT #37176] --- 9.10.1 released --- 3950. [port] Changed the bin/python Makefile to work around a bmake bug in FreeBSD 10 and NetBSD 6. [RT #36993] 3948. [port] solaris: RCVBUFSIZE was too large on Solaris with --with-tuning=large. [RT #37059] --- 9.10.1rc2 released --- 3947. [cleanup] Set the executable bit on libraries when using libtool. [RT #36786] 3946. [cleanup] Improved "configure" search for a python interpreter. [RT #36992] 3945. [bug] Invalid wildcard expansions could be incorrectly accepted by the validator. [RT #37093] 3944. [test] Added a regression test for "server-id". [RT #37057] 3942. [bug] Wildcard responses from a optout range should be marked as insecure. [RT #37072] 3941. [doc] Include the BIND version number in the ARM. [RT #37067] --- 9.10.1rc1 released --- 3935. [bug] "geoip asnum" ACL elements would not match unless the full organization name was specified. They can now match against the AS number alone (e.g., AS1234). [RT #36945] 3934. [bug] Catch bad 'sit-secret' in named-checkconf. Improve sit-secret documentation. [RT #36980] 3933. [bug] Corrected the implementation of dns_rdata_casecompare() for the HIP rdata type. [RT #36911] 3932. [test] Improved named-checkconf tests. [RT #36911] 3931. [cleanup] Cleanup how dlz grammar is defined. [RT #36879] 3929. [bug] 'host -a' needed to clear idnoptions. [RT #36963] 3928. [test] Improve rndc system test. [RT #36898] 3927. [bug] dig: report PKCS#11 error codes correctly when compiled with --enable-native-pkcs11. [RT #36956] 3926. [doc] Added doc for geoip-directory. [RT #36877] 3925. [bug] DS lookup of RFC 1918 empty zones failed. [RT #36917] 3924. [bug] Improve 'rndc addzone' error reporting. [RT #35187] 3923. [bug] Sanity check the xml2-config output. [RT #22246] 3922. [bug] When resigning, dnssec-signzone was removing all signatures from delegation nodes. It now retains DS and (if applicable) NSEC signatures. [RT #36946] 3921. [bug] AD was inappropriately set on RPZ responses. [RT #36833] 3919. [bug] dig: continue to next line if a address lookup fails in batch mode. [RT #36755] 3918. [doc] Update check-spf documentation. [RT #36910] 3917. [bug] dig, nslookup and host now continue on names that are too long after applying a search list elements. [RT #36892] 3916. [contrib] zone2sqlite checked wrong result code. Address compiler warnings. [RT #36931] 3915. [bug] Address a assertion if a route event arrived while shutting down. [RT #36887] --- 9.10.1b2 released --- 3914. [bug] Allow the URI target and CAA value fields to be zero length. [RT #36737] 3913. [bug] Address race issue in dispatch. [RT #36731] 3912. [bug] Address some unrecoverable lookup failures. [RT #36330] 3910. [bug] Fix races to free event during shutdown. [RT #36720] 3909. [bug] When computing the number of elements required for a acl count_acl_elements could have a short count leading to a assertion failure. Also zero out new acl elements in dns_acl_merge. [RT #36675] 3908. [bug] rndc now differentiates between a zone in multiple views and a zone that doesn't exist at all. [RT #36691] 3907. [cleanup] Alphabetize rndc help. [RT #36683] 3906. [protocol] Update URI record format to comply with draft-faltstrom-uri-08. [RT #36642] 3905. [bug] Address deadlock between view.c and adb.c. [RT #36341] 3904. [func] Add the RPZ SOA to the additional section. [RT36507] 3903. [bug] Improve the accuracy of DiG's reported round trip time. [RT 36611] 3902. [bug] liblwres wasn't handling link-local addresses in nameserver clauses in resolv.conf. [RT #36039] 3901. [protocol] Added support for CAA record type (RFC 6844). [RT #36625] 3900. [bug] Fix a crash in PostgreSQL DLZ driver. [RT #36637] 3899. [bug] "request-ixfr" is only applicable to slave and redirect zones. [RT #36608] 3898. [bug] Too small a buffer in tohexstr() calls in test code. [RT #36598] 3897. [bug] RPZ summary information was not properly being updated after a AXFR resulting in changes sometimes being ignored. [RT #35885] 3896. [bug] Address performance issues with DSCP code on some platforms. [RT #36534] 3894. [bug] Buffers in isc_print_vsnprintf were not properly initialized leading to potential overflows when printing out quad values. [RT #36505] 3893. [bug] Peer DSCP values could be returned without being set. [RT #36538] 3892. [bug] Setting '-t aaaa' in .digrc had unintended side effects. [RT #36452] 3891. [bug] Use ${INSTALL_SCRIPT} rather than ${INSTALL_PROGRAM} to install python programs. 3890. [bug] RRSIG sets that were not loaded in a single transaction at start up where not being correctly added to re-signing heaps. [RT #36302] 3889. [port] hurd: configure fixes as per: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=746540 3887. [cleanup] Make all static symbols in rbtdb64 end in "64" so they are easier to use in a debugger. [RT #36373] 3886. [bug] rbtdb_write_header should use a once to initialize FILE_VERSION. [RT #36374] --- 9.10.1b1 released --- 3885. [port] Use 'open()' rather than 'file()' to open files in python. 3884. [protocol] Add CDS and CDNSKEY record types. [RT #36333] 3881. [bug] Address memory leak with UPDATE error handling. [RT #36303] 3880. [test] Update ans.pl to work with new TSIG support in Net::DNS; add additional Net::DNS version prerequisite checks. [RT #36327] 3879. [func] Add version printing option to various BIND utilities. [RT #10686] 3878. [bug] Using the incorrect filename for a DLZ module caused a segmentation fault on startup. [RT #36286] 3877. [bug] Inserting and deleting parent and child nodes in response policy zones could trigger an assertion failure. [RT #36272] 3874. [test] Check that only "check-names master" is needed for updates to be accepted. 3873. [protocol] Only warn for SPF without TXT spf record. [RT #36210] 3872. [bug] Address issues found by static analysis. [RT #36209] 3871. [bug] Don't publish an activated key automatically before its publish time. [RT #35063] 3869. [doc] Document that in-view zones cannot be used for response policy zones. [RT #35941] 3868. [bug] isc_mem_setwater incorrectly cleared hi_called potentially leaving over memory cleaner running. [RT #35270] 3866. [bug] Named could die on disk full in generate_session_key. [RT #36119] 3865. [test] Improved testability of the red-black tree implementation and added unit tests. [RT #35904] 3864. [bug] RPZ didn't work well when being used as forwarder. [RT #36060] 3863. [bug] The "E" flag was missing from the query log as a unintended side effect of code rearrangement to support EDNS EXPIRE. [RT #36117] 3862. [cleanup] Return immediately if we are not going to log the message in ns_client_dumpmessage. 3861. [security] Missing isc_buffer_availablelength check results in a REQUIRE assertion when printing out a packet (CVE-2014-3859). [RT #36078] 3860. [bug] ioctl(DP_POLL) array size needs to be determined at run time as it is limited to {OPEN_MAX}. [RT #35878] 3858. [bug] Disable GCC 4.9 "delete null pointer check". [RT #35968] 3857. [bug] Make it harder for a incorrect NOEDNS classification to be made. [RT #36020] 3856. [bug] Configuring libjson without also configuring libxml resulting in a REQUIRE assertion when retrieving statistics using json. [RT #36009] 3855. [bug] Limit smoothed round trip time aging to no more than once a second. [RT #32909] 3854. [cleanup] Report unrecognized options, if any, in the final configure summary. [RT #36014] 3853. [cleanup] Refactor dns_rdataslab_fromrdataset to separate out the handling of a rdataset with no records. [RT #35968] 3851. [func] Allow libseccomp based system-call filtering on Linux; use "configure --enable-seccomp" to turn it on. Thanks to Loganaden Velvindron for the contribution. [RT #35347] 3850. [bug] Disabling forwarding could trigger a REQUIRE assertion. [RT #35979] 3849. [doc] Alphabetized dig's +options. [RT #35992] 3848. [bug] Adjust 'statistics-channels specified but not effective' error message to account for JSON support. [RT #36008] 3847. [bug] 'configure --with-dlz-postgres' failed to fail when there is not support available. 3846. [bug] "dig +notcp ixfr=" should result in a UDP ixfr query. [RT #35980] 3845. [doc] Remove documention for yet to be committed RRL changes. [RT #35897] 3844. [bug] Use the x64 version of the Microsoft Visual C++ Redistributable when built for 64 bit Windows. [RT #35973] 3843. [protocol] Check EDNS EXPIRE option in dns_rdata_fromwire. [RT #35969] 3842. [bug] Adjust RRL log-only logging category. [RT #35945] 3841. [cleanup] Refactor zone.c:add_opt to use dns_message_buildopt. [RT #35924] 3840. [port] Check for arc4random_addrandom() before using it; it's been removed from OpenBSD 5.5. [RT #35907] 3839. [test] Use only posix-compatible shell in system tests. [RT #35625] 3838. [protocol] EDNS EXPIRE as been assigned a code point of 9. 3837. [security] A NULL pointer is passed to query_prefetch resulting a REQUIRE assertion failure when a fetch is actually initiated (CVE-2014-3214). [RT #35899] 3836. [bug] Address C++ keyword usage in header file. 3835. [bug] Geoip ACL elements didn't work correctly when referenced via named or nested ACLs. [RT #35879] 3834. [bug] The re-signing heaps were not being updated soon enough leading to multiple re-generations of the same RRSIG when a zone transfer was in progress. [RT #35273] 3833. [bug] Cross compiling was broken due to calling genrandom at build time. [RT #35869] 3831. [cleanup] Reduce logging noise when EDNS state changes occur. [RT #35843] 3827. [contrib] The example DLZ driver (a version of which is also used in the dlzexternal system test) could use absolute names as relative. [RT #35802] 3826. [bug] Corrected bad INSIST logic in isc_radix_remove(). [RT #35870] 3825. [bug] Address sign extension bug in isc_regex_validate. [RT #35758] 3822. [bug] Log the correct type of static-stub zones when removing them. [RT #35842] 3819. [bug] NSEC3 hashes need to be able to be entered and displayed without padding. This is not a issue for currently defined algorithms but may be for future hash algorithms. [RT #27925] 3818. [bug] Stop lying to the optimizer that 'void *arg' is a constant in isc_event_allocate. --- 9.10.0 released --- 3824. [bug] A collision between two flag values could cause problems with cache cleaning when SIT was enabled. [RT #35858] --- 9.10.0rc2 released --- 3817. [func] The "delve" command is now spelled "delv" to avoid a namespace collision with the Xapian project. [RT #35801] 3815. [doc] Clarify "nsupdate -y" usage in man page. [RT #35808] 3810. [bug] Work around broken nameservers that fail to ignore unknown EDNS options. [RT #35766] 3809. [doc] Fix SIT and NSID documentation. 3808. [doc] Clean up "prefetch" documentation. [RT #35751] 3807. [bug] Fix sign extension bug in dns_name_fromtext when lowercase is set. [RT #35743] 3806. [test] Improved system test portability. [RT #35625] 3805. [contrib] Added contrib/perftcpdns, a performance testing tool for DNS over TCP. [RT #35710] --- 9.10.0rc1 released --- 3804. [bug] Corrected a race condition in dispatch.c in which portentry could be reset leading to an assertion failure in socket_search(). (Change #3708 addressed the same issue but was incomplete.) [RT #35128] 3803. [bug] "named-checkconf -z" incorrectly rejected zones using alternate data sources for not having a "file" option. [RT #35685] 3802. [bug] Various header files were not being installed. 3801. [port] Fix probing for gssapi support on FreeBSD. [RT #35615] 3800. [bug] A pending event on the route socket could cause an assertion failure when shutting down named. [RT #35674] 3799. [bug] Improve named's command line error reporting. [RT #35603] 3798. [bug] 'rndc zonestatus' was reporting the wrong re-signing time. [RT #35659] 3797. [port] netbsd: geoip support probing was broken. [RT #35642] 3796. [bug] Register dns and pkcs#11 error codes. [RT #35629] 3795. [bug] Make named-checkconf detect raw masterfiles for hint zones and reject them. [RT #35268] 3794. [maint] Added AAAA for C.ROOT-SERVERS.NET. 3793. [bug] zone.c:save_nsec3param() could assert when out of memory. [RT #35621] 3792. [func] Provide links to the alternate statistics views when displaying in a browser. [RT #35605] 3791. [placeholder] 3790. [bug] Handle broken nameservers that send BADVERS in response to unknown EDNS options. Maintain statistics on BADVERS responses. 3789. [bug] Null pointer dereference on rbt creation failure. 3788. [bug] dns_peer_getrequestsit was returning request_nsid by mistake. --- 9.10.0b2 released --- 3787. [bug] The code that checks whether "auto-dnssec" is allowed was ignoring "allow-update" ACLs set at the options or view level. [RT #29536] 3786. [func] Provide more detailed error codes when using native PKCS#11. "pkcs11-tokens" now fails robustly rather than asserting when run against an HSM with an incomplete PKCS#11 API implementation. [RT #35479] 3785. [bug] Debugging code dumphex didn't accept arbitrarily long input (only compiled with -DDEBUG). [RT #35544] 3784. [bug] Using "rrset-order fixed" when it had not been enabled at compile time caused inconsistent results. It now works as documented, defaulting to cyclic mode. [RT #28104] 3783. [func] "tsig-keygen" is now available as an alternate command name for "ddns-confgen". It generates a TSIG key in named.conf format without comments. [RT #35503] 3782. [func] Specifying "auto" as the salt when using "rndc signing -nsec3param" causes named to generate a 64-bit salt at random. [RT #35322] 3781. [tuning] Use adaptive mutex locks when available; this has been found to improve performance under load on many systems. "configure --with-locktype=standard" restores conventional mutex locks. [RT #32576] 3780. [bug] $GENERATE handled negative numbers incorrectly. [RT #25528] 3779. [cleanup] Clarify the error message when using an option that was not enabled at compile time. [RT #35504] 3778. [bug] Log a warning when the wrong address family is used in "listen-on" or "listen-on-v6". [RT #17848] 3777. [bug] EDNS EXPIRE code could dump core when processing DLZ queries. [RT #35493] 3776. [func] "rndc -q" suppresses output from successful rndc commands. Errors are printed on stderr. [RT #21393] 3775. [bug] dlz_dlopen driver could return the wrong error code on API version mismatch, leading to a segfault. [RT #35495] 3774. [func] When using "request-nsid", log the NSID value in printable form as well as hex. [RT #20864] 3773. [func] "host", "nslookup" and "nsupdate" now have options to print the version number and exit. [RT #26057] 3772. [contrib] Added sqlite3 dynamically-loadable DLZ module. (Based in part on a contribution from Tim Tessier.) [RT #20822] 3771. [cleanup] Adjusted log level for "using built-in key" messages. [RT #24383] 3770. [bug] "dig +trace" could fail with an assertion when it needed to fall back to TCP due to a truncated response. [RT #24660] 3769. [doc] Improved documentation of "rndc signing -list". [RT #30652] 3768. [bug] "dnssec-checkds" was missing the SHA-384 digest algorithm. [RT #34000] 3767. [func] Log explicitly when using rndc.key to configure command channel. [RT #35316] 3766. [cleanup] Fixed problems with building outside the source tree when using native PKCS#11. [RT #35459] 3765. [bug] Fixed a bug in "rndc secroots" that could crash named when dumping an empty keynode. [RT #35469] 3764. [bug] The dnssec-keygen/settime -S and -i options (to set up a successor key and set the prepublication interval) were missing from dnssec-keyfromlabel. [RT #35394] 3763. [bug] delve: Cache DNSSEC records to avoid the need to re-fetch them when restarting validation. [RT #35476] 3762. [bug] Address build problems with --pkcs11-native + --with-openssl with ECDSA support. [RT #35467] 3761. [bug] Address dangling reference bug in dns_keytable_add. [RT #35471] 3760. [bug] Improve SIT with native PKCS#11 and on Windows. [RT #35433] 3759. [port] Enable delve on Windows. [RT #35441] 3758. [port] Enable export library APIs on Windows. [RT #35382] 3757. [port] Enable Python tools (dnssec-coverage, dnssec-checkds) to run on Windows. [RT #34355] 3756. [bug] GSSAPI Kerberos realm checking was broken in check_config leading to spurious messages being logged. [RT #35443] --- 9.10.0b1 released --- 3755. [func] Add stats counters for known EDNS options + others. [RT #35447] 3754. [cleanup] win32: Installer now places files in the Program Files area rather than system services. [RT #35361] 3753. [bug] allow-notify was ignoring keys. [RT #35425] 3752. [bug] Address potential REQUIRE failure if DNS_STYLEFLAG_COMMENTDATA is set when printing out a rdataset. 3751. [tuning] The default setting for the -U option (setting the number of UDP listeners per interface) has been adjusted to improve performance. [RT #35417] 3750. [experimental] Partially implement EDNS EXPIRE option as described in draft-andrews-dnsext-expire-00. Retrieval of the remaining time until expiry for slave zones is supported. EXPIRE uses an experimental option code (65002), which is subject to change. [RT #35416] 3749. [func] "dig +subnet" sends an EDNS client subnet option containing the specified address/prefix when querying. (Thanks to Wilmer van der Gaast.) [RT #35415] 3748. [test] Use delve to test dns_client interfaces. [RT #35383] 3747. [bug] A race condition could lead to a core dump when destroying a resolver fetch object. [RT #35385] 3746. [func] New "max-zone-ttl" option enforces maximum TTLs for zones. If loading a zone containing a higher TTL, the load fails. DDNS updates with higher TTLs are accepted but the TTL is truncated. (Note: Currently supported for master zones only; inline-signing slaves will be added.) [RT #38405] 3745. [func] "configure --with-tuning=large" adjusts various compiled-in constants and default settings to values suited to large servers with abundant memory. [RT #29538] 3744. [experimental] SIT: send and process Source Identity Tokens (similar to DNS Cookies by Donald Eastlake 3rd), which are designed to help clients detect off-path spoofed responses and for servers to identify legitimate clients. SIT uses an experimental EDNS option code (65001), which will be changed to an IANA-assigned value if the experiment is deemed a success. SIT can be enabled via "configure --enable-sit" (or --enable-developer). It is enabled by default in Windows. Servers can be configured to send smaller responses to clients that have not identified themselves via SIT. RRL processing has also been updated; legitimate clients are not subject to rate limiting. [RT #35389] 3743. [bug] delegation-only flag wasn't working in forward zone declarations despite being documented. This is needed to support turning off forwarding and turning on delegation only at the same name. [RT #35392] 3742. [port] linux: libcap support: declare curval at start of block. [RT #35387] 3741. [func] "delve" (domain entity lookup and validation engine): A new tool with dig-like semantics for performing DNS lookups, with internal DNSSEC validation, using the same resolver and validator logic as named. This allows easy validation of DNSSEC data in environments with untrustworthy resolvers, and assists with troubleshooting of DNSSEC problems. [RT #32406] 3740. [contrib] Minor fixes to configure --with-dlz-bdb, --with-dlz-postgres and --with-dlz-odbc. [RT #35340] 3739. [func] Added per-zone stats counters to track TCP and UDP queries. [RT #35375] 3738. [bug] --enable-openssl-hash failed to build. [RT #35343] 3737. [bug] 'rndc retransfer' could trigger a assertion failure with inline zones. [RT #35353] 3736. [bug] nsupdate: When specifying a server by name, fall back to alternate addresses if the first address for that name is not reachable. [RT #25784] 3735. [cleanup] Merged the libiscpk11 library into libisc to simplify dependencies. [RT #35205] 3734. [bug] Improve building with libtool. [RT #35314] 3733. [func] Improve interface scanning support. Interface information will be automatically updated if the OS supports routing sockets (MacOS, *BSD, Linux). Use "automatic-interface-scan no;" to disable. Add "rndc scan" to trigger a scan. [RT #23027] 3732. [contrib] Fixed a type mismatch causing the ODBC DLZ driver to dump core on 64-bit systems. [RT #35324] 3731. [func] Added a "no-case-compress" ACL, which causes named to use case-insensitive compression (disabling change #3645) for specified clients. (This is useful when dealing with broken client implementations that use case-sensitive name comparisons, rejecting responses that fail to match the capitalization of the query that was sent.) [RT #35300] 3730. [cleanup] Added "never" as a synonym for "none" when configuring key event dates in the dnssec tools. [RT #35277] 3729. [bug] dnssec-keygen could set the publication date incorrectly when only the activation date was specified on the command line. [RT #35278] 3728. [doc] Expanded native-PKCS#11 documentation, specifically pkcs11: URI labels. [RT #35287] 3727. [func] The isc_bitstring API is no longer used and has been removed from libisc. [RT #35284] 3726. [cleanup] Clarified the error message when attempting to configure more than 32 response-policy zones. [RT #35283] 3725. [contrib] Updated zkt and nslint to newest versions, cleaned up and rearranged the contrib directory, and added a README. --- 9.10.0a2 released --- 3724. [bug] win32: Fixed a bug that prevented dig and host from exiting properly after completing a UDP query. [RT #35288] 3723. [cleanup] Imported keys are now handled the same way regardless of DNSSEC algorithm. [RT #35215] 3722. [bug] Using geoip ACLs in a blackhole statement could cause a segfault. [RT #35272] 3721. [doc] Improved documentation of the EDNS processing enhancements introduced in change #3593. [RT #35275] 3720. [bug] Address compiler warnings. [RT #35261] 3719. [bug] Address memory leak in in peer.c. [RT #35255] 3718. [bug] A missing ISC_LINK_INIT in log.c. [RT #35260] 3717. [port] hpux: Treat EOPNOTSUPP as a expected error code when probing to see if it is possible to set dscp values on a per packet basis. [RT #35252] 3716. [bug] The dns_request code was setting dcsp values when not requested. [RT #35252] 3715. [bug] The region and city databases could fail to initialize when using some versions of libGeoIP, causing assertion failures when named was configured to use them. [RT #35427] 3714. [test] System tests that need to test for cryptography support before running can now use a common "testcrypto.sh" script to do so. [RT #35213] 3713. [bug] Save memory by not storing "also-notify" addresses in zone objects that are configured not to send notify requests. [RT #35195] 3712. [placeholder] 3711. [placeholder] 3710. [bug] Address double dns_zone_detach when switching to using automatic empty zones from regular zones. [RT #35177] 3709. [port] Use built-in versions of strptime() and timegm() on all platforms to avoid portability issues. [RT #35183] 3708. [bug] Address a portentry locking issue in dispatch.c. [RT #35128] 3707. [bug] irs_resconf_load now returns ISC_R_FILENOTFOUND on a missing resolv.conf file and initializes the structure as if it had been configured with: nameserver ::1 nameserver 127.0.0.1 Note: Callers will need to be updated to treat ISC_R_FILENOTFOUND as a qualified success or else they will leak memory. The following code fragment will work with both old and new versions without changing the behaviour of the existing code. resconf = NULL; result = irs_resconf_load(mctx, "/etc/resolv.conf", &resconf); if (result != ISC_SUCCESS) { if (resconf != NULL) irs_resconf_destroy(&resconf); .... } [RT #35194] 3706. [contrib] queryperf: Fixed a possible integer overflow when printing results. [RT #35182] 3705. [func] "configure --enable-native-pkcs11" enables BIND to use the PKCS#11 API for all cryptographic functions, so that it can drive a hardware service module directly without the need to use a modified OpenSSL as intermediary (so long as the HSM's vendor provides a complete-enough implementation of the PKCS#11 interface). This has been tested successfully with the Thales nShield HSM and with SoftHSMv2 from the OpenDNSSEC project. [RT #29031] 3704. [protocol] Accept integer timestamps in RRSIG records. [RT #35185] 3703. [func] To improve recursive resolver performance, cache records which are still being requested by clients can now be automatically refreshed from the authoritative server before they expire, reducing or eliminating the time window in which no answer is available in the cache. See the "prefetch" option for more details. [RT #35041] 3702. [func] 'dnssec-coverage -l' option specifies a length of time to check for coverage; events further into the future are ignored. 'dnssec-coverage -z' checks only ZSK events, and 'dnssec-coverage -k' checks only KSK events. (Thanks to Peter Palfrader.) [RT #35168] 3701. [func] named-checkconf can now obscure shared secrets when printing by specifying '-x'. [RT #34465] 3700. [func] Allow access to subgroups of XML statistics via special URLs http://:/xml/v3/server, /zones, /net, /tasks, /mem, and /status. [RT #35115] 3699. [bug] Improvements to statistics channel XSL stylesheet: the stylesheet can now be cached by the browser; section headers are omitted from the stats display when there is no data in those sections to be displayed; counters are now right-justified for easier readability. [RT #35117] 3698. [cleanup] Replaced all uses of memcpy() with memmove(). [RT #35120] 3697. [bug] Handle "." as a search list element when IDN support is enabled. [RT #35133] 3696. [bug] dig failed to handle AXFR style IXFR responses which span multiple messages. [RT #35137] 3695. [bug] Address a possible race in dispatch.c. [RT #35107] 3694. [bug] Warn when a key-directory is configured for a zone, but does not exist or is not a directory. [RT #35108] 3693. [security] memcpy was incorrectly called with overlapping ranges resulting in malformed names being generated on some platforms. This could cause INSIST failures when serving NSEC3 signed zones (CVE-2014-0591). [RT #35120] 3692. [bug] Two calls to dns_db_getoriginnode were fatal if there was no data at the node. [RT #35080] 3691. [contrib] Address null pointer dereference in LDAP and MySQL DLZ modules. 3690. [bug] Iterative responses could be missed when the source port for an upstream query was the same as the listener port (53). [RT #34925] 3689. [bug] Fixed a bug causing an insecure delegation from one static-stub zone to another to fail with a broken trust chain. [RT #35081] 3688. [bug] loadnode could return a freed node on out of memory. [RT #35106] 3687. [bug] Address null pointer dereference in zone_xfrdone. [RT #35042] 3686. [func] "dnssec-signzone -Q" drops signatures from keys that are still published but no longer active. [RT #34990] 3685. [bug] "rndc refresh" didn't work correctly with slave zones using inline-signing. [RT #35105] 3684. [bug] The list of included files would grow on reload. [RT 35090] 3683. [cleanup] Add a more detailed "not found" message to rndc commands which specify a zone name. [RT #35059] 3682. [bug] Correct the behavior of rndc retransfer to allow inline-signing slave zones to retain NSEC3 parameters instead of reverting to NSEC. [RT #34745] 3681. [port] Update the Windows build system to support feature selection and WIN64 builds. This is a work in progress. [RT #34160] 3680. [bug] Ensure buffer space is available in "rndc zonestatus". [RT #35084] 3679. [bug] dig could fail to clean up TCP sockets still waiting on connect(). [RT #35074] 3678. [port] Update config.guess and config.sub. [RT #35060] 3677. [bug] 'nsupdate' leaked memory if 'realm' was used multiple times. [RT #35073] 3676. [bug] "named-checkconf -z" now checks zones of type hint and redirect as well as master. [RT #35046] 3675. [misc] Provide a place for third parties to add version information for their extensions in the version file by setting the EXTENSIONS variable. --- 9.10.0a1 released --- 3674. [bug] RPZ zeroed ttls if the query type was '*'. [RT #35026] 3673. [func] New "in-view" zone option allows direct sharing of zones between views. [RT #32968] 3672. [func] Local address can now be specified when using dns_client API. [RT #34811] 3671. [bug] Don't allow dnssec-importkey overwrite a existing non-imported private key. 3670. [bug] Address read after free in server side of lwres_getrrsetbyname. [RT #29075] 3669. [port] freebsd: --with-gssapi needs -lhx509. [RT #35001] 3668. [bug] Fix cast in lex.c which could see 0xff treated as eof. [RT #34993] 3667. [test] dig: add support to keep the TCP socket open between successive queries (+[no]keepopen). [RT #34918] 3666. [func] Add a tool, named-rrchecker, for checking the syntax of individual resource records. This tool is intended to be called by provisioning systems so that the front end does not need to be upgraded to support new DNS record types. [RT #34778] 3665. [bug] Failure to release lock on error in receive_secure_db. [RT #34944] 3664. [bug] Updated OpenSSL PKCS#11 patches to fix active list locking and other bugs. [RT #34855] 3663. [bug] Address bugs in dns_rdata_fromstruct and dns_rdata_tostruct for WKS and ISDN types. [RT #34910] 3662. [bug] 'host' could die if a UDP query timed out. [RT #34870] 3661. [bug] Address lock order reversal deadlock with inline zones. [RT #34856] 3660. [cleanup] Changed the name of "isc-config.sh" to "bind9-config". [RT #23825] 3659. [port] solaris: don't add explicit dependencies/rules for python programs as make won't use the implicit rules. [RT #34835] 3658. [port] linux: Address platform specific compilation issue when libcap-devel is installed. [RT #34838] 3657. [port] Some readline clones don't accept NULL pointers when calling add_history. [RT #34842] 3656. [security] Treat an all zero netmask as invalid when generating the localnets acl. (The prior behavior could allow unexpected matches when using some versions of Winsock: CVE-2013-6320.) [RT #34687] 3655. [cleanup] Simplify TCP message processing when requesting a zone transfer. [RT #34825] 3654. [bug] Address race condition with manual notify requests. [RT #34806] 3653. [func] Create delegations for all "children" of empty zones except "forward first". [RT #34826] 3652. [bug] Address bug with rpz-drop policy. [RT #34816] 3651. [tuning] Adjust when a master server is deemed unreachable. [RT #27075] 3650. [tuning] Use separate rate limiting queues for refresh and notify requests. [RT #30589] 3649. [cleanup] Include a comment in .nzf files, giving the name of the associated view. [RT #34765] 3648. [test] Updated the ATF test framework to version 0.17. [RT #25627] 3647. [bug] Address a race condition when shutting down a zone. [RT #34750] 3646. [bug] Journal filename string could be set incorrectly, causing garbage in log messages. [RT #34738] 3645. [protocol] Use case sensitive compression when responding to queries. [RT #34737] 3644. [protocol] Check that EDNS subnet client options are well formed. [RT #34718] 3643. [doc] Clarify RRL "slip" documentation. 3642. [func] Allow externally generated DNSKEY to be imported into the DNSKEY management framework. A new tool dnssec-importkey is used to do this. [RT #34698] 3641. [bug] Handle changes to sig-validity-interval settings better. [RT #34625] 3640. [bug] ndots was not being checked when searching. Only continue searching on NXDOMAIN responses. Add the ability to specify ndots to nslookup. [RT #34711] 3639. [bug] Treat type 65533 (KEYDATA) as opaque except when used in a key zone. [RT #34238] 3638. [cleanup] Add the ability to handle ENOPROTOOPT in case it is encountered. [RT #34668] 3637. [bug] 'allow-query-on' was checking the source address rather than the destination address. [RT #34590] 3636. [bug] Automatic empty zones now behave better with forward only "zones" beneath them. [RT #34583] 3635. [bug] Signatures were not being removed from a zone with only KSK keys for a algorithm. [RT #34439] 3634. [func] Report build-id in rndc status. Report build-id when building from a git repository. [RT #20422] 3633. [cleanup] Refactor OPT processing in named to make it easier to support new EDNS options. [RT #34414] 3632. [bug] Signature from newly inactive keys were not being removed. [RT #32178] 3631. [bug] Remove spurious warning about missing signatures when qtype is SIG. [RT #34600] 3630. [bug] Ensure correct ID computation for MD5 keys. [RT #33033] 3629. [func] Allow the printing of cryptographic fields in DNSSEC records by dig to be suppressed (dig +nocrypto). [RT #34534] 3628. [func] Report DNSKEY key id's when dumping the cache. [RT #34533] 3627. [bug] RPZ changes were not effective on slaves. [RT #34450] 3626. [func] dig: NSID output now easier to read. [RT #21160] 3625. [bug] Don't send notify messages to machines outside of the test setup. 3624. [bug] Look for 'json_object_new_int64' when looking for a the json library. [RT #34449] 3623. [placeholder] 3622. [tuning] Eliminate an unnecessary lock when incrementing cache statistics. [RT #34339] 3621. [security] Incorrect bounds checking on private type 'keydata' can lead to a remotely triggerable REQUIRE failure (CVE-2013-4854). [RT #34238] 3620. [func] Added "rpz-client-ip" policy triggers, enabling RPZ responses to be configured on the basis of the client IP address; this can be used, for example, to blacklist misbehaving recursive or stub resolvers. [RT #33605] 3619. [bug] Fixed a bug in RPZ with "recursive-only no;" [RT #33776] 3618. [func] "rndc reload" now checks modification times of include files as well as master files to determine whether to skip reloading a zone. [RT #33936] 3617. [bug] Named was failing to answer queries during "rndc reload" [RT #34098] 3616. [bug] Change #3613 was incomplete. [RT #34177] 3615. [cleanup] "configure" now finishes by printing a summary of optional BIND features and whether they are active or inactive. ("configure --enable-full-report" increases the verbosity of the summary.) [RT #31777] 3614. [port] Check for . [RT #34162] 3613. [bug] named could crash when deleting inline-signing zones with "rndc delzone". [RT #34066] 3612. [port] Check whether to use -ljson or -ljson-c. [RT #34115] 3611. [bug] Improved resistance to a theoretical authentication attack based on differential timing. [RT #33939] 3610. [cleanup] win32: Some executables had been omitted from the installer. [RT #34116] 3609. [bug] Corrected a possible deadlock in applications using the export version of the isc_app API. [RT #33967] 3608. [port] win32: added todos.pl script to ensure all text files the win32 build depends on are converted to DOS newline format. [RT #22067] 3607. [bug] dnssec-keygen had broken 'Invalid keyfile' error message. [RT #34045] 3606. [func] "rndc flushtree" now flushes matching records in the address database and bad cache as well as the DNS cache. (Previously only the DNS cache was flushed.) [RT #33970] 3605. [port] win32: Addressed several compatibility issues with newer versions of Visual Studio. [RT #33916] 3604. [bug] Fixed a compile-time error when building with JSON but not XML. [RT #33959] 3603. [bug] Install . [RT #33956] 3602. [contrib] Added DLZ Perl module, allowing Perl scripts to integrate with named and serve DNS data. (Contributed by John Eaglesham of Yahoo.) 3601. [bug] Added to PKCS#11 openssl patches a value len attribute in DH derive key. [RT #33928] 3600. [cleanup] dig: Fixed a typo in the warning output when receiving an oversized response. [RT #33910] 3599. [tuning] Check for pointer equivalence in name comparisons. [RT #18125] 3598. [cleanup] Improved portability of map file code. [RT #33820] 3597. [bug] Ensure automatic-resigning heaps are reconstructed when loading zones in map format. [RT #33381] 3596. [port] Updated win32 build documentation, added dnssec-verify. [RT #22067] 3595. [port] win32: Fix build problems introduced by change #3550. [RT #33807] 3594. [maint] Update config.guess and config.sub. [RT #33816] 3593. [func] Update EDNS processing to better track remote server capabilities. [RT #30655] 3592. [doc] Moved documentation of rndc command options to the rndc man page. [RT #33506] 3591. [func] Use CRC-64 to detect map file corruption at load time. [RT #33746] 3590. [bug] When using RRL on recursive servers, defer rate-limiting until after recursion is complete; also, use correct rcode for slipped NXDOMAIN responses. [RT #33604] 3589. [func] Report serial numbers in when starting zone transfers. Report accepted NOTIFY requests including serial. [RT #33037] 3588. [bug] dig: addressed a memory leak in the sigchase code that could cause a shutdown crash. [RT #33733] 3587. [func] 'named -g' now checks the logging configuration but does not use it. [RT #33473] 3586. [bug] Handle errors in xmlDocDumpFormatMemoryEnc. [RT #33706] 3585. [func] "rndc delzone -clean" option removes zone files when deleting a zone. [RT #33570] 3584. [security] Caching data from an incompletely signed zone could trigger an assertion failure in resolver.c (CVE-2013-3919). [RT #33690] 3583. [bug] Address memory leak in GSS-API processing [RT #33574] 3582. [bug] Silence false positive warning regarding missing file directive for inline slave zones. [RT #33662] 3581. [bug] Changed the tcp-listen-queue default to 10. [RT #33029] 3580. [bug] Addressed a possible race in acache.c [RT #33602] 3579. [maint] Updates to PKCS#11 openssl patches, supporting versions 0.9.8y, 1.0.0k, 1.0.1e [RT #33463] 3578. [bug] 'rndc -c file' now fails if 'file' does not exist. [RT #33571] 3577. [bug] Handle zero TTL values better. [RT #33411] 3576. [bug] Address a shutdown race when validating. [RT #33573] 3575. [func] Changed the logging category for RRL events from 'queries' to 'query-errors'. [RT #33540] 3574. [doc] The 'hostname' keyword was missing from server-id description in the named.conf man page. [RT #33476] 3573. [bug] "rndc addzone" and "rndc delzone" incorrectly handled zone names containing punctuation marks and other nonstandard characters. [RT #33419] 3572. [func] Threads are now enabled by default on most operating systems. [RT #25483] 3571. [bug] Address race condition in dns_client_startresolve(). [RT #33234] 3570. [bug] Check internal pointers are valid when loading map files. [RT #33403] 3569. [contrib] Ported mysql DLZ driver to dynamically-loadable module, and added multithread support. [RT #33394] 3568. [cleanup] Add a product description line to the version file, to be reported by named -v/-V. [RT #33366] 3567. [bug] Silence clang static analyzer warnings. [RT #33365] 3566. [func] Log when forwarding updates to master. [RT #33240] 3565. [placeholder] 3564. [bug] Improved handling of corrupted map files. [RT #33380] 3563. [contrib] zone2sqlite failed with some table names. [RT #33375] 3562. [func] Update map file header format to include a SHA-1 hash of the database content, so that corrupted map files can be rejected at load time. [RT #32459] 3561. [bug] dig: issue a warning if an EDNS query returns FORMERR or NOTIMP. Adjust usage message. [RT #33363] 3560. [bug] isc-config.sh did not honor includedir and libdir when set via configure. [RT #33345] 3559. [func] Check that both forms of Sender Policy Framework records exist or do not exist. [RT #33355] 3558. [bug] IXFR of a DLZ stored zone was broken. [RT #33331] 3557. [bug] Reloading redirect zones was broken. [RT #33292] 3556. [maint] Added AAAA for D.ROOT-SERVERS.NET. 3555. [bug] Address theoretical race conditions in acache.c (change #3553 was incomplete). [RT #33252] 3554. [bug] RRL failed to correctly rate-limit upward referrals and failed to count dropped error responses in the statistics. [RT #33225] 3553. [bug] Address suspected double free in acache. [RT #33252] 3552. [bug] Wrong getopt option string for 'nsupdate -r'. [RT #33280] 3551. [bug] resolver.querydscp[46] were uninitialized. [RT #32686] 3550. [func] Unified the internal and export versions of the BIND libraries, allowing external clients to use the same libraries as BIND. [RT #33131] 3549. [doc] Documentation for "request-nsid" was missing. [RT #33153] 3548. [bug] The NSID request code in resolver.c was broken resulting in invalid EDNS options being sent. [RT #33153] 3547. [bug] Some malformed unknown rdata records were not properly detected and rejected. [RT #33129] 3546. [func] Add EUI48 and EUI64 types. [RT #33082] 3545. [bug] RRL slip behavior was incorrect when set to 1. [RT #33111] 3544. [contrib] check5011.pl: Script to report the status of managed keys as recorded in managed-keys.bind. Contributed by Tony Finch 3543. [bug] Update socket structure before attaching to socket manager after accept. [RT #33084] 3542. [placeholder] 3541. [bug] Parts of libdns were not properly initialized when built in libexport mode. [RT #33028] 3540. [test] libt_api: t_info and t_assert were not thread safe. 3539. [port] win32: timestamp format didn't match other platforms. 3538. [test] Running "make test" now requires loopback interfaces to be set up. [RT #32452] 3537. [tuning] Slave zones, when updated, now send NOTIFY messages to peers before being dumped to disk rather than after. [RT #27242] 3536. [func] Add support for setting Differentiated Services Code Point (DSCP) values in named. Most configuration options which take a "port" option (e.g., listen-on, forwarders, also-notify, masters, notify-source, etc) can now also take a "dscp" option specifying a code point for use with outgoing traffic, if supported by the underlying OS. [RT #27596] 3535. [bug] Minor win32 cleanups. [RT #32962] 3534. [bug] Extra text after an embedded NULL was ignored when parsing zone files. [RT #32699] 3533. [contrib] query-loc-0.4.0: memory leaks. [RT #32960] 3532. [contrib] zkt: fixed buffer overrun, resource leaks. [RT #32960] 3531. [bug] win32: A uninitialized value could be returned on out of memory. [RT #32960] 3530. [contrib] Better RTT tracking in queryperf. [RT #30128] 3529. [func] Named now listens on both IPv4 and IPv6 interfaces by default. Named previously only listened on IPv4 interfaces by default unless named was running in IPv6 only mode. [RT #32945] 3528. [func] New "dnssec-coverage" command scans the timing metadata for a set of DNSSEC keys and reports if a lapse in signing coverage has been scheduled inadvertently. (Note: This tool depends on python; it will not be built or installed on systems that do not have a python interpreter.) [RT #28098] 3527. [compat] Add a URI to allow applications to explicitly request a particular XML schema from the statistics channel, returning 404 if not supported. [RT #32481] 3526. [cleanup] Set up dependencies for unit tests correctly during build. [RT #32803] 3525. [func] Support for additional signing algorithms in rndc: hmac-sha1, -sha224, -sha256, -sha384, and -sha512. The -A option to rndc-confgen can be used to select the algorithm for the generated key. (The default is still hmac-md5; this may change in a future release.) [RT #20363] 3524. [func] Added an alternate statistics channel in JSON format, when the server is built with the json-c library: http://[address]:[port]/json. [RT #32630] 3523. [contrib] Ported filesystem and ldap DLZ drivers to dynamically-loadable modules, and added the "wildcard" module based on a contribution from Vadim Goncharov . [RT #23569] 3522. [bug] DLZ lookups could fail to return SERVFAIL when they ought to. [RT #32685] 3521. [bug] Address memory leak in opensslecdsa_link.c. [RT #32249] 3520. [bug] 'mctx' was not being referenced counted in some places where it should have been. [RT #32794] 3519. [func] Full replay protection via four-way handshake is now mandatory for rndc clients. Very old versions of rndc will no longer work. [RT #32798] 3518. [bug] Increase the size of dns_rrl_key.s.rtype by one bit so that all dns_rrl_rtype_t enum values fit regardless of whether it is teated as signed or unsigned by the compiler. [RT #32792] 3517. [bug] Reorder destruction to avoid shutdown race. [RT #32777] 3516. [placeholder] 3515. [port] '%T' is not portable in strftime(). [RT #32763] 3514. [bug] The ranges for valid key sizes in ddns-confgen and rndc-confgen were too constrained. Keys up to 512 bits are now allowed for most algorithms, and up to 1024 bits for hmac-sha384 and hmac-sha512. [RT #32753] 3513. [func] "dig -u" prints times in microseconds rather than milliseconds. [RT #32704] 3512. [func] "rndc validation check" reports the current status of DNSSEC validation. [RT #21397] 3511. [doc] Improve documentation of redirect zones. [RT #32756] 3510. [func] "rndc status" and XML statistics channel now report server start and reconfiguration times. [RT #21048] 3509. [cleanup] Added a product line to version file to allow for easy naming of different products (BIND vs BIND ESV, for example). [RT #32755] 3508. [contrib] queryperf was incorrectly rejecting the -T option. [RT #32338] 3507. [bug] Statistics channel XSL had a glitch when attempting to chart query data before any queries had been received. [RT #32620] 3506. [func] When setting "max-cache-size" and "max-acache-size", the keyword "unlimited" is no longer defined as equal to 4 gigabytes (except on 32-bit platforms); it means literally unlimited. [RT #32358] 3505. [bug] When setting "max-cache-size" and "max-acache-size", larger values than 4 gigabytes could not be set explicitly, though larger sizes were available when setting cache size to 0. This has been corrected; the full range is now available. [RT #32358] 3504. [func] Add support for ACLs based on geographic location, using MaxMind GeoIP databases. Based on code contributed by Ken Brownfield . [RT #30681] 3503. [doc] Clarify size_spec syntax. [RT #32449] 3502. [func] zone-statistics: "no" is now a synonym for "none", instead of "terse". [RT #29165] 3501. [func] zone-statistics now takes three options: full, terse, and none. "yes" and "no" are retained as synonyms for full and terse, respectively. [RT #29165] 3500. [security] Support NAPTR regular expression validation on all platforms without using libregex, which can be vulnerable to memory exhaustion attack (CVE-2013-2266). [RT #32688] 3499. [doc] Corrected ARM documentation of built-in zones. [RT #32694] 3498. [bug] zone statistics for zones which matched a potential empty zone could have their zone-statistics setting overridden. 3497. [func] When deleting a slave/stub zone using 'rndc delzone' report the files that were being used so they can be cleaned up if desired. [RT #27899] 3496. [placeholder] 3495. [func] Support multiple response-policy zones (up to 32), while improving RPZ performance. "response-policy" syntax now includes a "min-ns-dots" clause, with default 1, to exclude top-level domains from NSIP and NSDNAME checking. --enable-rpz-nsip and --enable-rpz-nsdname are now the default. [RT #32251] 3494. [func] DNS RRL: Blunt the impact of DNS reflection and amplification attacks by rate-limiting substantially- identical responses. [RT #28130] 3493. [contrib] Added BDBHPT dynamically-loadable DLZ module, contributed by Mark Goldfinch. [RT #32549] 3492. [bug] Fixed a regression in zone loading performance due to lock contention. [RT #30399] 3491. [bug] Slave zones using inline-signing must specify a file name. [RT #31946] 3490. [bug] When logging RDATA during update, truncate if it's too long. [RT #32365] 3489. [bug] --enable-developer now turns on ISC_LIST_CHECKINIT. dns_dlzcreate() failed to properly initialize dlzdb.link. When cloning a rdataset do not copy the link contents. [RT #32651] 3488. [bug] Use after free error with DH generated keys. [RT #32649] 3487. [bug] Change 3444 was not complete. There was a additional place where the NOQNAME proof needed to be saved. [RT #32629] 3486. [bug] named could crash when using TKEY-negotiated keys that had been deleted and then recreated. [RT #32506] 3485. [cleanup] Only compile openssl_gostlink.c if we support GOST. 3484. [bug] Some statistics were incorrectly rendered in XML. [RT #32587] 3483. [placeholder] 3482. [func] dig +nssearch now prints name servers that don't have address records (missing AAAA or A, or the name doesn't exist). [RT #29348] 3481. [cleanup] Removed use of const const in atf. 3480. [bug] Silence logging noise when setting up zone statistics. [RT #32525] 3479. [bug] Address potential memory leaks in gssapi support code. [RT #32405] 3478. [port] Fix a build failure in strict C99 environments [RT #32475] 3477. [func] Expand logging when adding records via DDNS update [RT #32365] 3476. [bug] "rndc zonestatus" could report a spurious "not found" error on inline-signing zones. [RT #29226] 3475. [cleanup] Changed name of 'map' zone file format (previously 'fast'). [RT #32458] 3474. [bug] nsupdate could assert when the local and remote address families didn't match. [RT #22897] 3473. [bug] dnssec-signzone/verify could incorrectly report an error condition due to an empty node above an opt-out delegation lacking an NSEC3. [RT #32072] 3472. [bug] The active-connections counter in the socket statistics could underflow. [RT #31747] 3471. [bug] The number of UDP dispatches now defaults to the number of CPUs even if -n has been set to a higher value. [RT #30964] 3470. [bug] Slave zones could fail to dump when successfully refreshing after an initial failure. [RT #31276] 3469. [bug] Handle DLZ lookup failures more gracefully. Improve backward compatibility between versions of DLZ dlopen API. [RT #32275] 3468. [security] RPZ rules to generate A records (but not AAAA records) could trigger an assertion failure when used in conjunction with DNS64 (CVE-2012-5689). [RT #32141] 3467. [bug] Added checks in dnssec-keygen and dnssec-settime to check for delete date < inactive date. [RT #31719] 3466. [contrib] Corrected the DNS_CLIENTINFOMETHODS_VERSION check in DLZ example driver. [RT #32275] 3465. [bug] Handle isolated reserved ports. [RT #31778] 3464. [maint] Updates to PKCS#11 openssl patches, supporting versions 0.9.8x, 1.0.0j, 1.0.1c [RT #29749] 3463. [doc] Clarify managed-keys syntax in ARM. [RT #32232] 3462. [doc] Clarify server selection behavior of dig when using -4 or -6 options. [RT #32181] 3461. [bug] Negative responses could incorrectly have AD=1 set. [RT #32237] 3460. [bug] Only link against readline where needed. [RT #29810] 3459. [func] Added -J option to named-checkzone/named-compilezone to specify the path to the journal file. [RT #30958] 3458. [bug] Return FORMERR when presented with a overly long domain named in a request. [RT #29682] 3457. [protocol] Add ILNP records (NID, LP, L32, L64). [RT #31836] 3456. [port] g++47: ATF failed to compile. [RT #32012] 3455. [contrib] queryperf: fix getopt option list. [RT #32338] 3454. [port] sparc64: improve atomic support. [RT #25182] 3453. [bug] 'rndc addzone' of a zone with 'inline-signing yes;' failed. [RT #31960] 3452. [bug] Accept duplicate singleton records. [RT #32329] 3451. [port] Increase per thread stack size from 64K to 1M. [RT #32230] 3450. [bug] Stop logfileconfig system test spam system logs. [RT #32315] 3449. [bug] gen.c: use the pre-processor to construct format strings so that compiler can perform sanity checks; check the snprintf results. [RT #17576] 3448. [bug] The allow-query-on ACL was not processed correctly. [RT #29486] 3447. [port] Add support for libxml2-2.9.x [RT #32231] 3446. [port] win32: Add source ID (see change #3400) to build. [RT #31683] 3445. [bug] Warn about zone files with blank owner names immediately after $ORIGIN directives. [RT #31848] 3444. [bug] The NOQNAME proof was not being returned from cached insecure responses. [RT #21409] 3443. [bug] ddns-confgen: Some TSIG algorithms were incorrectly rejected when generating keys. [RT #31927] 3442. [port] Net::DNS 0.69 introduced a non backwards compatible change. [RT #32216] 3441. [maint] D.ROOT-SERVERS.NET is now 199.7.91.13. 3440. [bug] Reorder get_key_struct to not trigger a assertion when cleaning up due to out of memory error. [RT #32131] 3439. [placeholder] 3438. [bug] Don't accept unknown data escape in quotes. [RT #32031] 3437. [bug] isc_buffer_init -> isc_buffer_constinit to initialize buffers with constant data. [RT #32064] 3436. [bug] Check malloc/calloc return values. [RT #32088] 3435. [bug] Cross compilation support in configure was broken. [RT #32078] 3434. [bug] Pass client info to the DLZ findzone() entry point in addition to lookup(). This makes it possible for a database to answer differently whether it's authoritative for a name depending on the address of the client. [RT #31775] 3433. [bug] dlz_findzone() did not correctly handle ISC_R_NOMORE. [RT #31172] 3432. [func] Multiple DLZ databases can now be configured. DLZ databases are searched in the order configured, unless set to "search no", in which case a zone can be configured to be retrieved from a particular DLZ database by using a "dlz " option in the zone statement. DLZ databases can support type "master" and "redirect" zones. [RT #27597] 3431. [bug] ddns-confgen: Some valid key algorithms were not accepted. [RT #31927] 3430. [bug] win32: isc_time_formatISO8601 was missing the 'T' between the date and time. [RT #32044] 3429. [bug] dns_zone_getserial2 could a return success without returning a valid serial. [RT #32007] 3428. [cleanup] dig: Add timezone to date output. [RT #2269] 3427. [bug] dig +trace incorrectly displayed name server addresses instead of names. [RT #31641] 3426. [bug] dnssec-checkds: Clearer output when records are not found. [RT #31968] 3425. [bug] "acacheentry" reference counting was broken resulting in use after free. [RT #31908] 3424. [func] dnssec-dsfromkey now emits the hash without spaces. [RT #31951] 3423. [bug] "rndc signing -nsec3param" didn't accept the full range of possible values. Address portability issues. [RT #31938] 3422. [bug] Added a clear error message for when the SOA does not match the referral. [RT #31281] 3421. [bug] Named loops when re-signing if all keys are offline. [RT #31916] 3420. [bug] Address VPATH compilation issues. [RT #31879] 3419. [bug] Memory leak on validation cancel. [RT #31869] 3418. [func] New XML schema (version 3.0) for the statistics channel adds query type statistics at the zone level, and flattens the XML tree and uses compressed format to optimize parsing. Includes new XSL that permits charting via the Google Charts API on browsers that support javascript in XSL. The old XML schema has been deprecated. [RT #30023] 3417. [placeholder] 3416. [bug] Named could die on shutdown if running with 128 UDP dispatches per interface. [RT #31743] 3415. [bug] named could die with a REQUIRE failure if a validation was canceled. [RT #31804] 3414. [bug] Address locking issues found by Coverity. [RT #31626] 3413. [func] Record the number of DNS64 AAAA RRsets that have been synthesized. [RT #27636] 3412. [bug] Copy timeval structure from control message data. [RT #31548] 3411. [tuning] Use IPV6_USE_MIN_MTU or equivalent with TCP in addition to UDP. [RT #31690] 3410. [bug] Addressed Coverity warnings. [RT #31626] 3409. [contrib] contrib/dane/mkdane.sh: Tool to generate TLSA RR's from X.509 certificates, for use with DANE (DNS-based Authentication of Named Entities). [RT #30513] 3408. [bug] Some DNSSEC-related options (update-check-ksk, dnssec-loadkeys-interval, dnssec-dnskey-kskonly) are now legal in slave zones as long as inline-signing is in use. [RT #31078] 3407. [placeholder] 3406. [bug] mem.c: Fix compilation errors when building with ISC_MEM_TRACKLINES or ISC_MEMPOOL_NAMES disabled. Also, ISC_MEM_DEBUG is no longer optional. [RT #31559] 3405. [bug] Handle time going backwards in acache. [RT #31253] 3404. [bug] dnssec-signzone: When re-signing a zone, remove RRSIG and NSEC records from nodes that used to be in-zone but are now below a zone cut. [RT #31556] 3403. [bug] Silence noisy OpenSSL logging. [RT #31497] 3402. [test] The IPv6 interface numbers used for system tests were incorrect on some platforms. [RT #25085] 3401. [bug] Addressed Coverity warnings. [RT #31484] 3400. [cleanup] "named -V" can now report a source ID string, defined in the "srcid" file in the build tree and normally set to the most recent git hash. [RT #31494] 3399. [port] netbsd: rename 'bool' parameter to avoid namespace clash. [RT #31515] 3398. [bug] SOA parameters were not being updated with inline signed zones if the zone was modified while the server was offline. [RT #29272] 3397. [bug] dig crashed when using +nssearch with +tcp. [RT #25298] 3396. [bug] OPT records were incorrectly removed from signed, truncated responses. [RT #31439] 3395. [protocol] Add RFC 6598 reverse zones to built in empty zones list, 64.100.IN-ADDR.ARPA ... 127.100.IN-ADDR.ARPA. [RT #31336] 3394. [bug] Adjust 'successfully validated after lower casing signer' log level and category. [RT #31414] 3393. [bug] 'host -C' could core dump if REFUSED was received. [RT #31381] 3392. [func] Keep statistics on REFUSED responses. [RT #31412] 3391. [bug] A DNSKEY lookup that encountered a CNAME failed. [RT #31262] 3390. [bug] Silence clang compiler warnings. [RT #30417] 3389. [bug] Always return NOERROR (not 0) in TSIG. [RT #31275] 3388. [bug] Fixed several Coverity warnings. Note: This change includes a fix for a bug that was subsequently determined to be an exploitable security vulnerability, CVE-2012-5688: named could die on specific queries with dns64 enabled. [RT #30996] 3387. [func] DS digest can be disabled at runtime with disable-ds-digests. [RT #21581] 3386. [bug] Address locking violation when generating new NSEC / NSEC3 chains. [RT #31224] 3385. [bug] named-checkconf didn't detect missing master lists in also-notify clauses. [RT #30810] 3384. [bug] Improved logging of crypto errors. [RT #30963] 3383. [security] A certain combination of records in the RBT could cause named to hang while populating the additional section of a response. [RT #31090] 3382. [bug] SOA query from slave used use-v6-udp-ports range, if set, regardless of the address family in use. [RT #24173] 3381. [contrib] Update queryperf to support more RR types. [RT #30762] 3380. [bug] named could die if a nonexistent master list was referenced in a also-notify. [RT #31004] 3379. [bug] isc_interval_zero and isc_time_epoch should be "const (type)* const". [RT #31069] 3378. [bug] Handle missing 'managed-keys-directory' better. [RT #30625] 3377. [bug] Removed spurious newline from NSEC3 multiline output. [RT #31044] 3376. [bug] Lack of EDNS support was being recorded without a successful response. [RT #30811] 3375. [bug] 'rndc dumpdb' failed on empty caches. [RT #30808] 3374. [bug] isc_parse_uint32 failed to return a range error on systems with 64 bit longs. [RT #30232] 3373. [bug] win32: open raw files in binary mode. [RT #30944] 3372. [bug] Silence spurious "deleted from unreachable cache" messages. [RT #30501] 3371. [bug] AD=1 should behave like DO=1 when deciding whether to add NS RRsets to the additional section or not. [RT #30479] 3370. [bug] Address use after free while shutting down. [RT #30241] 3369. [bug] nsupdate terminated unexpectedly in interactive mode if built with readline support. [RT #29550] 3368. [bug] , and were not C++ safe. 3367. [bug] dns_dnsseckey_create() result was not being checked. [RT #30685] 3366. [bug] Fixed Read-After-Write dependency violation for IA64 atomic operations. [RT #25181] 3365. [bug] Removed spurious newlines from log messages in zone.c [RT #30675] 3364. [security] Named could die on specially crafted record. [RT #30416] 3363. [bug] Need to allow "forward" and "fowarders" options in static-stub zones; this had been overlooked. [RT #30482] 3362. [bug] Setting some option values to 0 in named.conf could trigger an assertion failure on startup. [RT #27730] 3361. [bug] "rndc signing -nsec3param" didn't work correctly when salt was set to '-' (no salt). [RT #30099] 3360. [bug] 'host -w' could die. [RT #18723] 3359. [bug] An improperly-formed TSIG secret could cause a memory leak. [RT #30607] 3358. [placeholder] 3357. [port] Add support for libxml2-2.8.x [RT #30440] 3356. [bug] Cap the TTL of signed RRsets when RRSIGs are approaching their expiry, so they don't remain in caches after expiry. [RT #26429] 3355. [port] Use more portable awk in verify system test. 3354. [func] Improve OpenSSL error logging. [RT #29932] 3353. [bug] Use a single task for task exclusive operations. [RT #29872] 3352. [bug] Ensure that learned server attributes timeout of the adb cache. [RT #29856] 3351. [bug] isc_mem_put and isc_mem_putanddetach didn't report caller if either ISC_MEM_DEBUGSIZE or ISC_MEM_DEBUGCTX memory debugging flags are set. [RT #30243] 3350. [bug] Memory read overrun in isc___mem_reallocate if ISC_MEM_DEBUGCTX memory debugging flag is set. [RT #30240] 3349. [bug] Change #3345 was incomplete. [RT #30233] 3348. [bug] Prevent RRSIG data from being cached if a negative record matching the covering type exists at a higher trust level. Such data already can't be retrieved from the cache since change 3218 -- this prevents it being inserted into the cache as well. [RT #26809] 3347. [bug] dnssec-settime: Issue a warning when writing a new private key file would cause a change in the permissions of the existing file. [RT #27724] 3346. [security] Bad-cache data could be used before it was initialized, causing an assert. [RT #30025] 3345. [bug] Addressed race condition when removing the last item or inserting the first item in an ISC_QUEUE. [RT #29539] 3344. [func] New "dnssec-checkds" command checks a zone to determine which DS records should be published in the parent zone, or which DLV records should be published in a DLV zone, and queries the DNS to ensure that it exists. (Note: This tool depends on python; it will not be built or installed on systems that do not have a python interpreter.) [RT #28099] 3343. [placeholder] 3342. [bug] Change #3314 broke saving of stub zones to disk resulting in excessive cpu usage in some cases. [RT #29952] 3341. [func] New "dnssec-verify" command checks a signed zone to ensure correctness of signatures and of NSEC/NSEC3 chains. [RT #23673] 3340. [func] Added new 'map' zone file format, which is an image of a zone database that can be loaded directly into memory via mmap(), allowing much faster zone loading. (Note: Because of pointer sizes and other considerations, this file format is platform-dependent; 'map' zone files cannot always be transferred from one server to another.) [RT #25419] 3339. [func] Allow the maximum supported rsa exponent size to be specified: "max-rsa-exponent-size ;" [RT #29228] 3338. [bug] Address race condition in units tests: asyncload_zone and asyncload_zt. [RT #26100] 3337. [bug] Change #3294 broke support for the multiple keys in controls. [RT #29694] 3336. [func] Maintain statistics for RRsets tagged as "stale". [RT #29514] 3335. [func] nslookup: return a nonzero exit code when unable to get an answer. [RT #29492] 3334. [bug] Hold a zone table reference while performing a asynchronous load of a zone. [RT #28326] 3333. [bug] Setting resolver-query-timeout too low can cause named to not recover if it loses connectivity. [RT #29623] 3332. [bug] Re-use cached DS rrsets if possible. [RT #29446] 3331. [security] dns_rdataslab_fromrdataset could produce bad rdataslabs. [RT #29644] 3330. [func] Fix missing signatures on NOERROR results despite RPZ rewriting. Also - add optional "recursive-only yes|no" to the response-policy statement - add optional "max-policy-ttl" to the response-policy statement to limit the false data that "recursive-only no" can introduce into resolvers' caches - add a RPZ performance test to bin/tests/system/rpz when queryperf is available. - the encoding of PASSTHRU action to "rpz-passthru". (The old encoding is still accepted.) [RT #26172] 3329. [bug] Handle RRSIG signer-name case consistently: We generate RRSIG records with the signer-name in lower case. We accept them with any case, but if they fail to validate, we try again in lower case. [RT #27451] 3328. [bug] Fixed inconsistent data checking in dst_parse.c. [RT #29401] 3327. [func] Added 'filter-aaaa-on-v6' option; this is similar to 'filter-aaaa-on-v4' but applies to IPv6 connections. (Use "configure --enable-filter-aaaa" to enable this option.) [RT #27308] 3326. [func] Added task list statistics: task model, worker threads, quantum, tasks running, tasks ready. [RT #27678] 3325. [func] Report cache statistics: memory use, number of nodes, number of hash buckets, hit and miss counts. [RT #27056] 3324. [test] Add better tests for ADB stats [RT #27057] 3323. [func] Report the number of buckets the resolver is using. [RT #27020] 3322. [func] Monitor the number of active TCP and UDP dispatches. [RT #27055] 3321. [func] Monitor the number of recursive fetches and the number of open sockets, and report these values in the statistics channel. [RT #27054] 3320. [func] Added support for monitoring of recursing client count. [RT #27009] 3319. [func] Added support for monitoring of ADB entry count and hash size. [RT #27057] 3318. [tuning] Reduce the amount of work performed while holding a bucket lock when finished with a fetch context. [RT #29239] 3317. [func] Add ECDSA support (RFC 6605). [RT #21918] 3316. [tuning] Improved locking performance when recursing. [RT #28836] 3315. [tuning] Use multiple dispatch objects for sending upstream queries; this can improve performance on busy multiprocessor systems by reducing lock contention. [RT #28605] 3314. [bug] The masters list could be updated while stub_callback or refresh_callback were using it. [RT #26732] 3313. [protocol] Add TLSA record type. [RT #28989] 3312. [bug] named-checkconf didn't detect a bad dns64 clients acl. [RT #27631] 3311. [bug] Abort the zone dump if zone->db is NULL in zone.c:zone_gotwritehandle. [RT #29028] 3310. [test] Increase table size for mutex profiling. [RT #28809] 3309. [bug] resolver.c:fctx_finddone() was not thread safe. [RT #27995] 3308. [placeholder] 3307. [bug] Add missing ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS. [RT #28956] 3306. [bug] Improve DNS64 reverse zone performance. [RT #28563] 3305. [func] Add wire format lookup method to sdb. [RT #28563] 3304. [bug] Use hmctx, not mctx when freeing rbtdb->heaps. [RT #28571] 3303. [bug] named could die when reloading. [RT #28606] 3302. [bug] dns_dnssec_findmatchingkeys could fail to find keys if the zone name contained character that required special mappings. [RT #28600] 3301. [contrib] Update queryperf to build on darwin. Add -R flag for non-recursive queries. [RT #28565] 3300. [bug] Named could die if gssapi was enabled in named.conf but was not compiled in. [RT #28338] 3299. [bug] Make SDB handle errors from database drivers better. [RT #28534] 3298. [bug] Named could dereference a NULL pointer in zmgr_start_xfrin_ifquota if the zone was being removed. [RT #28419] 3297. [bug] Named could die on a malformed master file. [RT #28467] 3296. [bug] Named could die with a INSIST failure in client.c:exit_check. [RT #28346] 3295. [bug] Adjust isc_time_secondsastimet range check to be more portable. [RT # 26542] 3294. [bug] isccc/cc.c:table_fromwire failed to free alist on error. [RT #28265] 3293. [func] nsupdate: list supported type. [RT #28261] 3292. [func] Log messages in the axfr stream at debug 10. [RT #28040] 3291. [port] Fixed a build error on systems without ENOTSUP. [RT #28200] 3290. [bug] was not being installed. [RT #28169] 3289. [bug] 'rndc retransfer' failed for inline zones. [RT #28036] 3288. [bug] dlz_destroy() function wasn't correctly registered by the DLZ dlopen driver. [RT #28056] 3287. [port] Update ans.pl to work with Net::DNS 0.68. [RT #28028] 3286. [bug] Managed key maintenance timer could fail to start after 'rndc reconfig'. [RT #26786] 3285. [bug] val-frdataset was incorrectly disassociated in proveunsecure after calling startfinddlvsep. [RT #27928] 3284. [bug] Address race conditions with the handling of rbtnode.deadlink. [RT #27738] 3283. [bug] Raw zones with with more than 512 records in a RRset failed to load. [RT #27863] 3282. [bug] Restrict the TTL of NS RRset to no more than that of the old NS RRset when replacing it. [RT #27792] [RT #27884] 3281. [bug] SOA refresh queries could be treated as cancelled despite succeeding over the loopback interface. [RT #27782] 3280. [bug] Potential double free of a rdataset on out of memory with DNS64. [RT #27762] 3279. [bug] Hold a internal reference to the zone while performing a asynchronous load. Address potential memory leak if the asynchronous is cancelled. [RT #27750] 3278. [bug] Make sure automatic key maintenance is started when "auto-dnssec maintain" is turned on during "rndc reconfig". [RT #26805] 3277. [bug] win32: isc_socket_dup is not implemented. [RT #27696] 3276. [bug] win32: ns_os_openfile failed to return NULL on safe_open failure. [RT #27696] 3275. [bug] Corrected rndc -h output; the 'rndc sync -clean' option had been misspelled as '-clear'. (To avoid future confusion, both options now work.) [RT #27173] 3274. [placeholder] 3273. [bug] AAAA responses could be returned in the additional section even when filter-aaaa-on-v4 was in use. [RT #27292] 3272. [func] New "rndc zonestatus" command prints information about the specified zone. [RT #21671] 3271. [port] darwin: mksymtbl is not always stable, loop several times before giving up. mksymtbl was using non portable perl to covert 64 bit hex strings. [RT #27653] --- 9.9.0rc2 released --- 3270. [bug] "rndc reload" didn't reuse existing zones correctly when inline-signing was in use. [RT #27650] 3269. [port] darwin 11 and later now built threaded by default. 3268. [bug] Convert RRSIG expiry times to 64 timestamps to work out the earliest expiry time. [RT #23311] 3267. [bug] Memory allocation failures could be mis-reported as unexpected error. New ISC_R_UNSET result code. [RT #27336] 3266. [bug] The maximum number of NSEC3 iterations for a DNSKEY RRset was not being properly computed. [RT #26543] 3265. [bug] Corrected a problem with lock ordering in the inline-signing code. [RT #27557] 3264. [bug] Automatic regeneration of signatures in an inline-signing zone could stall when the server was restarted. [RT #27344] 3263. [bug] "rndc sync" did not affect the unsigned side of an inline-signing zone. [RT #27337] 3262. [bug] Signed responses were handled incorrectly by RPZ. [RT #27316] 3261. [func] RRset ordering now defaults to random. [RT #27174] 3260. [bug] "rrset-order cyclic" could appear not to rotate for some query patterns. [RT #27170/27185] --- 9.9.0rc1 released --- 3259. [bug] named-compilezone: Suppress "dump zone to " message when writing to stdout. [RT #27109] 3258. [test] Add "forcing full sign with unreadable keys" test. [RT #27153] 3257. [bug] Do not generate a error message when calling fsync() in a pipe or socket. [RT #27109] 3256. [bug] Disable empty zones for lwresd -C. [RT #27139] 3255. [func] No longer require that a empty zones be explicitly enabled or that a empty zone is disabled for RFC 1918 empty zones to be configured. [RT #27139] 3254. [bug] Set isc_socket_ipv6only() on the IPv6 control channels. [RT #22249] 3253. [bug] Return DNS_R_SYNTAX when the input to a text field is too long. [RT #26956] 3252. [bug] When master zones using inline-signing were updated while the server was offline, the source zone could fall out of sync with the signed copy. They can now resynchronize. [RT #26676] 3251. [bug] Enforce a upper bound (65535 bytes) on the amount of memory dns_sdlz_putrr() can allocate per record to prevent run away memory consumption on ISC_R_NOSPACE. [RT #26956] 3250. [func] 'configure --enable-developer'; turn on various configure options, normally off by default, that we want developers to build and test with. [RT #27103] 3249. [bug] Update log message when saving slave zones files for analysis after load failures. [RT #27087] 3248. [bug] Configure options --enable-fixed-rrset and --enable-exportlib were incompatible with each other. [RT #27087] 3247. [bug] 'raw' format zones failed to preserve load order breaking 'fixed' sort order. [RT #27087] 3246. [bug] Named failed to start with a empty also-notify list. [RT #27087] 3245. [bug] Don't report a error unchanged serials unless there were other changes when thawing a zone with ixfr-fromdifferences. [RT #26845] 3244. [func] Added readline support to nslookup and nsupdate. Also simplified nsupdate syntax to make "update" and "prereq" optional. [RT #24659] 3243. [port] freebsd,netbsd,bsdi: the thread defaults were not being properly set. 3242. [func] Extended the header of raw-format master files to include the serial number of the zone from which they were generated, if different (as in the case of inline-signing zones). This is to be used in inline-signing zones, to track changes between the unsigned and signed versions of the zone, which may have different serial numbers. (Note: raw zonefiles generated by this version of BIND are no longer compatible with prior versions. To generate a backward-compatible raw zonefile using dnssec-signzone or named-compilezone, specify output format "raw=0" instead of simply "raw".) [RT #26587] 3241. [bug] Address race conditions in the resolver code. [RT #26889] 3240. [bug] DNSKEY state change events could be missed. [RT #26874] 3239. [bug] dns_dnssec_findmatchingkeys needs to use a consistent timestamp. [RT #26883] 3238. [bug] keyrdata was not being reinitialized in lib/dns/rbtdb.c:iszonesecure. [RT #26913] 3237. [bug] dig -6 didn't work with +trace. [RT #26906] 3236. [bug] Backed out changes #3182 and #3202, related to EDNS(0) fallback behavior. [RT #26416] 3235. [func] dns_db_diffx, a extended dns_db_diff which returns the generated diff and optionally writes it to a journal. [RT #26386] 3234. [bug] 'make depend' produced invalid makefiles. [RT #26830] 3233. [bug] 'rndc freeze/thaw' didn't work for inline zones. [RT #26632] 3232. [bug] Zero zone->curmaster before return in dns_zone_setmasterswithkeys(). [RT #26732] 3231. [bug] named could fail to send a incompressible zone. [RT #26796] 3230. [bug] 'dig axfr' failed to properly handle a multi-message axfr with a serial of 0. [RT #26796] 3229. [bug] Fix local variable to struct var assignment found by CLANG warning. 3228. [tuning] Dynamically grow symbol table to improve zone loading performance. [RT #26523] 3227. [bug] Interim fix to make WKS's use of getprotobyname() and getservbyname() self thread safe. [RT #26232] 3226. [bug] Address minor resource leakages. [RT #26624] 3225. [bug] Silence spurious "setsockopt(517, IPV6_V6ONLY) failed" messages. [RT #26507] 3224. [bug] 'rndc signing' argument parsing was broken. [RT #26684] 3223. [bug] 'task_test privilege_drop' generated false positives. [RT #26766] 3222. [cleanup] Replace dns_journal_{get,set}_bitws with dns_journal_{get,set}_sourceserial. [RT #26634] 3221. [bug] Fixed a potential core dump on shutdown due to referencing fetch context after it's been freed. [RT #26720] --- 9.9.0b2 released --- 3220. [bug] Change #3186 was incomplete; dns_db_rpz_findips() could fail to set the database version correctly, causing an assertion failure. [RT #26180] 3219. [bug] Disable NOEDNS caching following a timeout. 3218. [security] Cache lookup could return RRSIG data associated with nonexistent records, leading to an assertion failure. [RT #26590] 3217. [cleanup] Fix build problem with --disable-static. [RT #26476] 3216. [bug] resolver.c:validated() was not thread-safe. [RT #26478] 3215. [bug] 'rndc recursing' could cause a core dump. [RT #26495] 3214. [func] Add 'named -U' option to set the number of UDP listener threads per interface. [RT #26485] 3213. [doc] Clarify ixfr-from-differences behavior. [RT #25188] 3212. [bug] rbtdb.c: failed to remove a node from the deadnodes list prior to adding a reference to it leading a possible assertion failure. [RT #23219] 3211. [func] dnssec-signzone: "-f -" prints to stdout; "-O full" option prints in single-line-per-record format. [RT #20287] 3210. [bug] Canceling the oldest query due to recursive-client overload could trigger an assertion failure. [RT #26463] 3209. [func] Add "dnssec-lookaside 'no'". [RT #24858] 3208. [bug] 'dig -y' handle unknown tsig algorithm better. [RT #25522] 3207. [contrib] Fixed build error in Berkeley DB DLZ module. [RT #26444] 3206. [cleanup] Add ISC information to log at start time. [RT #25484] 3205. [func] Upgrade dig's defaults to better reflect modern nameserver behavior. Enable "dig +adflag" and "dig +edns=0" by default. Enable "+dnssec" when running "dig +trace". [RT #23497] 3204. [bug] When a master server that has been marked as unreachable sends a NOTIFY, mark it reachable again. [RT #25960] 3203. [bug] Increase log level to 'info' for validation failures from expired or not-yet-valid RRSIGs. [RT #21796] 3202. [bug] NOEDNS caching on timeout was too aggressive. [RT #26416] 3201. [func] 'rndc querylog' can now be given an on/off parameter instead of only being used as a toggle. [RT #18351] 3200. [doc] Some rndc functions were undocumented or were missing from 'rndc -h' output. [RT #25555] 3199. [func] When logging client information, include the name being queried. [RT #25944] 3198. [doc] Clarified that dnssec-settime can alter keyfile permissions. [RT #24866] 3197. [bug] Don't try to log the filename and line number when the config parser can't open a file. [RT #22263] 3196. [bug] nsupdate: return nonzero exit code when target zone doesn't exist. [RT #25783] 3195. [cleanup] Silence "file not found" warnings when loading managed-keys zone. [RT #26340] 3194. [doc] Updated RFC references in the 'empty-zones-enable' documentation. [RT #25203] 3193. [cleanup] Changed MAXZONEKEYS to DNS_MAXZONEKEYS, moved to dnssec.h. [RT #26415] 3192. [bug] A query structure could be used after being freed. [RT #22208] 3191. [bug] Print NULL records using "unknown" format. [RT #26392] 3190. [bug] Underflow in error handling in isc_mutexblock_init. [RT #26397] 3189. [test] Added a summary report after system tests. [RT #25517] 3188. [bug] zone.c:zone_refreshkeys() could fail to detach references correctly when errors occurred, causing a hang on shutdown. [RT #26372] 3187. [port] win32: support for Visual Studio 2008. [RT #26356] --- 9.9.0b1 released --- 3186. [bug] Version/db mis-match in rpz code. [RT #26180] 3185. [func] New 'rndc signing' option for auto-dnssec zones: - 'rndc signing -list' displays the current state of signing operations - 'rndc signing -clear' clears the signing state records for keys that have fully signed the zone - 'rndc signing -nsec3param' sets the NSEC3 parameters for the zone The 'rndc keydone' syntax is removed. [RT #23729] 3184. [bug] named had excessive cpu usage when a redirect zone was configured. [RT #26013] 3183. [bug] Added RTLD_GLOBAL flag to dlopen call. [RT #26301] 3182. [bug] Auth servers behind firewalls which block packets greater than 512 bytes may cause other servers to perform poorly. Now, adb retains edns information and caches noedns servers. [RT #23392/24964] 3181. [func] Inline-signing is now supported for master zones. [RT #26224] 3180. [func] Local copies of slave zones are now saved in raw format by default, to improve startup performance. 'masterfile-format text;' can be used to override the default, if desired. [RT #25867] 3179. [port] kfreebsd: build issues. [RT #26273] 3178. [bug] A race condition introduced by change #3163 could cause an assertion failure on shutdown. [RT #26271] 3177. [func] 'rndc keydone', remove the indicator record that named has finished signing the zone with the corresponding key. [RT #26206] 3176. [doc] Corrected example code and added a README to the sample external DLZ module in contrib/dlz/example. [RT #26215] 3175. [bug] Fix how DNSSEC positive wildcard responses from a NSEC3 signed zone are validated. Stop sending a unnecessary NSEC3 record when generating such responses. [RT #26200] 3174. [bug] Always compute to revoked key tag from scratch. [RT #26186] 3173. [port] Correctly validate root DS responses. [RT #25726] 3172. [port] darwin 10.* and freebsd [89] are now built threaded by default. 3171. [bug] Exclusively lock the task when adding a zone using 'rndc addzone'. [RT #25600] --- 9.9.0a3 released --- 3170. [func] RPZ update: - fix precedence among competing rules - improve ARM text including documenting rule precedence - try to rewrite CNAME chains until first hit - new "rpz" logging channel - RDATA for CNAME rules can include wildcards - replace "NO-OP" named.conf policy override with "PASSTHRU" and add "DISABLED" override ("NO-OP" is still recognized) [RT #25172] 3169. [func] Catch db/version mis-matches when calling dns_db_*(). [RT #26017] 3168. [bug] Nxdomain redirection could trigger an assert with a ANY query. [RT #26017] 3167. [bug] Negative answers from forwarders were not being correctly tagged making them appear to not be cached. [RT #25380] 3166. [bug] Upgrading a zone to support inline-signing failed. [RT #26014] 3165. [bug] dnssec-signzone could generate new signatures when resigning, even when valid signatures were already present. [RT #26025] 3164. [func] Enable DLZ modules to retrieve client information, so that responses can be changed depending on the source address of the query. [RT #25768] 3163. [bug] Use finer-grained locking in client.c to address concurrency problems with large numbers of threads. [RT #26044] 3162. [test] start.pl: modified to allow for "named.args" in ns*/ subdirectory to override stock arguments to named. Largely from RT #26044, but no separate ticket. 3161. [bug] zone.c:del_sigs failed to always reset rdata leading assertion failures. [RT #25880] 3160. [bug] When printing out a NSEC3 record in multiline form the newline was not being printed causing type codes to be run together. [RT #25873] 3159. [bug] On some platforms, named could assert on startup when running in a chrooted environment without /proc. [RT #25863] 3158. [bug] Recursive servers would prefer a particular UDP socket instead of using all available sockets. [RT #26038] 3157. [tuning] Reduce the time spent in "rndc reconfig" by parsing the config file before pausing the server. [RT #21373] 3156. [placeholder] --- 9.9.0a2 released --- 3155. [bug] Fixed a build failure when using contrib DLZ drivers (e.g., mysql, postgresql, etc). [RT #25710] 3154. [bug] Attempting to print an empty rdataset could trigger an assert. [RT #25452] 3153. [func] Extend request-ixfr to zone level and remove the side effect of forcing an AXFR. [RT #25156] 3152. [cleanup] Some versions of gcc and clang failed due to incorrect use of __builtin_expect. [RT #25183] 3151. [bug] Queries for type RRSIG or SIG could be handled incorrectly. [RT #21050] 3150. [func] Improved startup and reconfiguration time by enabling zones to load in multiple threads. [RT #25333] 3149. [placeholder] 3148. [bug] Processing of normal queries could be stalled when forwarding a UPDATE message. [RT #24711] 3147. [func] Initial inline signing support. [RT #23657] --- 9.9.0a1 released --- 3146. [test] Fixed gcc4.6.0 errors in ATF. [RT #25598] 3145. [test] Capture output of ATF unit tests in "./atf.out" if there were any errors while running them. [RT #25527] 3144. [bug] dns_dbiterator_seek() could trigger an assert when used with a nonexistent database node. [RT #25358] 3143. [bug] Silence clang compiler warnings. [RT #25174] 3142. [bug] NAPTR is class agnostic. [RT #25429] 3141. [bug] Silence spurious "zone serial (0) unchanged" messages associated with empty zones. [RT #25079] 3140. [func] New command "rndc flushtree " clears the specified name from the server cache along with all names under it. [RT #19970] 3139. [test] Added tests from RFC 6234, RFC 2202, and RFC 1321 for the hashing algorithms (md5, sha1 - sha512, and their hmac counterparts). [RT #25067] 3138. [bug] Address memory leaks and out-of-order operations when shutting named down. [RT #25210] 3137. [func] Improve hardware scalability by allowing multiple worker threads to process incoming UDP packets. This can significantly increase query throughput on some systems. [RT #22992] 3136. [func] Add RFC 1918 reverse zones to the list of built-in empty zones switched on by the 'empty-zones-enable' option. [RT #24990] 3135. [port] FreeBSD: workaround broken IPV6_USE_MIN_MTU processing. See http://www.freebsd.org/cgi/query-pr.cgi?pr=158307 [RT #24950] 3134. [bug] Improve the accuracy of dnssec-signzone's signing statistics. [RT #16030] 3133. [bug] Change #3114 was incomplete. [RT #24577] 3132. [placeholder] 3131. [tuning] Improve scalability by allocating one zone task per 100 zones at startup time, rather than using a fixed-size task table. [RT #24406] 3130. [func] Support alternate methods for managing a dynamic zone's serial number. Two methods are currently defined using serial-update-method, "increment" (default) and "unixtime". [RT #23849] 3129. [bug] Named could crash on 'rndc reconfig' when allow-new-zones was set to yes and named ACLs were used. [RT #22739] 3128. [func] Inserting an NSEC3PARAM via dynamic update in an auto-dnssec zone that has not been signed yet will cause it to be signed with the specified NSEC3 parameters when keys are activated. The NSEC3PARAM record will not appear in the zone until it is signed, but the parameters will be stored. [RT #23684] 3127. [bug] 'rndc thaw' will now remove a zone's journal file if the zone serial number has been changed and ixfr-from-differences is not in use. [RT #24687] 3126. [security] Using DNAME record to generate replacements caused RPZ to exit with a assertion failure. [RT #24766] 3125. [security] Using wildcard CNAME records as a replacement with RPZ caused named to exit with a assertion failure. [RT #24715] 3124. [bug] Use an rdataset attribute flag to indicate negative-cache records rather than using rrtype 0; this will prevent problems when that rrtype is used in actual DNS packets. [RT #24777] 3123. [security] Change #2912 exposed a latent flaw in dns_rdataset_totext() that could cause named to crash with an assertion failure. [RT #24777] 3122. [cleanup] dnssec-settime: corrected usage message. [RT #24664] 3121. [security] An authoritative name server sending a negative response containing a very large RRset could trigger an off-by-one error in the ncache code and crash named. [RT #24650] 3120. [bug] Named could fail to validate zones listed in a DLV that validated insecure without using DLV and had DS records in the parent zone. [RT #24631] 3119. [bug] When rolling to a new DNSSEC key, a private-type record could be created and never marked complete. [RT #23253] 3118. [bug] nsupdate could dump core on shutdown when using SIG(0) keys. [RT #24604] 3117. [cleanup] Remove doc and parser references to the never-implemented 'auto-dnssec create' option. [RT #24533] 3116. [func] New 'dnssec-update-mode' option controls updates of DNSSEC records in signed dynamic zones. Set to 'no-resign' to disable automatic RRSIG regeneration while retaining the ability to sign new or changed data. [RT #24533] 3115. [bug] Named could fail to return requested data when following a CNAME that points into the same zone. [RT #24455] 3114. [bug] Retain expired RRSIGs in dynamic zones if key is inactive and there is no replacement key. [RT #23136] 3113. [doc] Document the relationship between serial-query-rate and NOTIFY messages. 3112. [doc] Add missing descriptions of the update policy name types "ms-self", "ms-subdomain", "krb5-self" and "krb5-subdomain", which allow machines to update their own records, to the BIND 9 ARM. 3111. [bug] Improved consistency checks for dnssec-enable and dnssec-validation, added test cases to the checkconf system test. [RT #24398] 3110. [bug] dnssec-signzone: Wrong error message could appear when attempting to sign with no KSK. [RT #24369] 3109. [func] The also-notify option now uses the same syntax as a zone's masters clause. This means it is now possible to specify a TSIG key to use when sending notifies to a given server, or to include an explicit named masters list in an also-notify statement. [RT #23508] 3108. [cleanup] dnssec-signzone: Clarified some error and warning messages; removed #ifdef ALLOW_KSKLESS_ZONES code (use -P instead). [RT #20852] 3107. [bug] dnssec-signzone: Report the correct number of ZSKs when using -x. [RT #20852] 3106. [func] When logging client requests, include the name of the TSIG key if any. [RT #23619] 3105. [bug] GOST support can be suppressed by "configure --without-gost" [RT #24367] 3104. [bug] Better support for cross-compiling. [RT #24367] 3103. [bug] Configuring 'dnssec-validation auto' in a view instead of in the options statement could trigger an assertion failure in named-checkconf. [RT #24382] 3102. [func] New 'dnssec-loadkeys-interval' option configures how often, in minutes, to check the key repository for updates when using automatic key maintenance. Default is every 60 minutes (formerly hard-coded to 12 hours). [RT #23744] 3101. [bug] Zones using automatic key maintenance could fail to check the key repository for updates. [RT #23744] 3100. [security] Certain response policy zone configurations could trigger an INSIST when receiving a query of type RRSIG. [RT #24280] 3099. [test] "dlz" system test now runs but gives R:SKIPPED if not compiled with --with-dlz-filesystem. [RT #24146] 3098. [bug] DLZ zones were answering without setting the AA bit. [RT #24146] 3097. [test] Add a tool to test handling of malformed packets. [RT #24096] 3096. [bug] Set KRB5_KTNAME before calling log_cred() in dst_gssapi_acceptctx(). [RT #24004] 3095. [bug] Handle isolated reserved ports in the port range. [RT #23957] 3094. [doc] Expand dns64 documentation. 3093. [bug] Fix gssapi/kerberos dependencies [RT #23836] 3092. [bug] Signatures for records at the zone apex could go stale due to an incorrect timer setting. [RT #23769] 3091. [bug] Fixed a bug in which zone keys that were published and then subsequently activated could fail to trigger automatic signing. [RT #22911] 3090. [func] Make --with-gssapi default [RT #23738] 3089. [func] dnssec-dsfromkey now supports reading keys from standard input "dnssec-dsfromkey -f -". [RT #20662] 3088. [bug] Remove bin/tests/system/logfileconfig/ns1/named.conf and add setup.sh in order to resolve changing named.conf issue. [RT #23687] 3087. [bug] DDNS updates using SIG(0) with update-policy match type "external" could cause a crash. [RT #23735] 3086. [bug] Running dnssec-settime -f on an old-style key will now force an update to the new key format even if no other change has been specified, using "-P now -A now" as default values. [RT #22474] 3085. [func] New '-R' option in dnssec-signzone forces removal of signatures which have not yet expired but were generated by a key that no longer exists. [RT #22471] 3084. [func] A new command "rndc sync" dumps pending changes in a dynamic zone to disk; "rndc sync -clean" also removes the journal file after syncing. Also, "rndc freeze" no longer removes journal files. [RT #22473] 3083. [bug] NOTIFY messages were not being sent when generating a NSEC3 chain incrementally. [RT #23702] 3082. [port] strtok_r is threads only. [RT #23747] 3081. [bug] Failure of DNAME substitution did not return YXDOMAIN. [RT #23591] 3080. [cleanup] Replaced compile time constant by STDTIME_ON_32BITS. [RT #23587] 3079. [bug] Handle isc_event_allocate failures in t_tasks. [RT #23572] 3078. [func] Added a new include file with function typedefs for the DLZ "dlopen" driver. [RT #23629] 3077. [bug] zone.c:zone_refreshkeys() incorrectly called dns_zone_attach(), use zone->irefs instead. [RT #23303] 3076. [func] New '-L' option in dnssec-keygen, dnsset-settime, and dnssec-keyfromlabel sets the default TTL of the key. When possible, automatic signing will use that TTL when the key is published. [RT #23304] 3075. [bug] dns_dnssec_findzonekeys{2} used a inconsistent timestamp when determining which keys are active. [RT #23642] 3074. [bug] Make the adb cache read through for zone data and glue learn for zone named is authoritative for. [RT #22842] 3073. [bug] managed-keys changes were not properly being recorded. [RT #20256] 3072. [bug] dns_dns64_aaaaok() potential NULL pointer dereference. [RT #20256] 3071. [bug] has_nsec could be used uninitialized in update.c:next_active. [RT #20256] 3070. [bug] dnssec-signzone potential NULL pointer dereference. [RT #20256] 3069. [cleanup] Silence warnings messages from clang static analysis. [RT #20256] 3068. [bug] Named failed to build with a OpenSSL without engine support. [RT #23473] 3067. [bug] ixfr-from-differences {master|slave}; failed to select the master/slave zones. [RT #23580] 3066. [func] The DLZ "dlopen" driver is now built by default, no longer requiring a configure option. To disable it, use "configure --without-dlopen". Driver also supported on win32. [RT #23467] 3065. [bug] RRSIG could have time stamps too far in the future. [RT #23356] 3064. [bug] powerpc: add sync instructions to the end of atomic operations. [RT #23469] 3063. [contrib] More verbose error reporting from DLZ LDAP. [RT #23402] 3062. [func] Made several changes to enhance human readability of DNSSEC data in dig output and in generated zone files: - DNSKEY record comments are more verbose, no longer used in multiline mode only - multiline RRSIG records reformatted - multiline output mode for NSEC3PARAM records - "dig +norrcomments" suppresses DNSKEY comments - "dig +split=X" breaks hex/base64 records into fields of width X; "dig +nosplit" disables this. [RT #22820] 3061. [func] New option "dnssec-signzone -D", only write out generated DNSSEC records. [RT #22896] 3060. [func] New option "dnssec-signzone -X " allows specification of a separate expiration date for DNSKEY RRSIGs and other RRSIGs. [RT #22141] 3059. [test] Added a regression test for change #3023. 3058. [bug] Cause named to terminate at startup or rndc reconfig/ reload to fail, if a log file specified in the conf file isn't a plain file. [RT #22771] 3057. [bug] "rndc secroots" would abort after the first error and so could miss some views. [RT #23488] 3056. [func] Added support for URI resource record. [RT #23386] 3055. [placeholder] 3054. [bug] Added elliptic curve support check in GOST OpenSSL engine detection. [RT #23485] 3053. [bug] Under a sustained high query load with a finite max-cache-size, it was possible for cache memory to be exhausted and not recovered. [RT #23371] 3052. [test] Fixed last autosign test report. [RT #23256] 3051. [bug] NS records obscure DNAME records at the bottom of the zone if both are present. [RT #23035] 3050. [bug] The autosign system test was timing dependent. Wait for the initial autosigning to complete before running the rest of the test. [RT #23035] 3049. [bug] Save and restore the gid when creating creating named.pid at startup. [RT #23290] 3048. [bug] Fully separate view key management. [RT #23419] 3047. [bug] DNSKEY NODATA responses not cached fixed in validator.c. Tests added to dnssec system test. [RT #22908] 3046. [bug] Use RRSIG original TTL to compute validated RRset and RRSIG TTL. [RT #23332] 3045. [removed] Replaced by change #3050. 3044. [bug] Hold the socket manager lock while freeing the socket. [RT #23333] 3043. [test] Merged in the NetBSD ATF test framework (currently version 0.12) for development of future unit tests. Use configure --with-atf to build ATF internally or configure --with-atf=prefix to use an external copy. [RT #23209] 3042. [bug] dig +trace could fail attempting to use IPv6 addresses on systems with only IPv4 connectivity. [RT #23297] 3041. [bug] dnssec-signzone failed to generate new signatures on ttl changes. [RT #23330] 3040. [bug] Named failed to validate insecure zones where a node with a CNAME existed between the trust anchor and the top of the zone. [RT #23338] 3039. [func] Redirect on NXDOMAIN support. [RT #23146] 3038. [bug] Install . [RT #23342] 3037. [doc] Update COPYRIGHT to contain all the individual copyright notices that cover various parts. 3036. [bug] Check built-in zone arguments to see if the zone is re-usable or not. [RT #21914] 3035. [cleanup] Simplify by using strlcpy. [RT #22521] 3034. [cleanup] nslookup: use strlcpy instead of safecopy. [RT #22521] 3033. [cleanup] Add two INSIST(bucket != DNS_ADB_INVALIDBUCKET). [RT #22521] 3032. [bug] rdatalist.c: add missing REQUIREs. [RT #22521] 3031. [bug] dns_rdataclass_format() handle a zero sized buffer. [RT #22521] 3030. [bug] dns_rdatatype_format() handle a zero sized buffer. [RT #22521] 3029. [bug] isc_netaddr_format() handle a zero sized buffer. [RT #22521] 3028. [bug] isc_sockaddr_format() handle a zero sized buffer. [RT #22521] 3027. [bug] Add documented REQUIREs to cfg_obj_asnetprefix() to catch NULL pointer dereferences before they happen. [RT #22521] 3026. [bug] lib/isc/httpd.c: check that we have enough space after calling grow_headerspace() and if not re-call grow_headerspace() until we do. [RT #22521] 3025. [bug] Fixed a possible deadlock due to zone resigning. [RT #22964] 3024. [func] RTT Banding removed due to minor security increase but major impact on resolver latency. [RT #23310] 3023. [bug] Named could be left in an inconsistent state when receiving multiple AXFR response messages that were not all TSIG-signed. [RT #23254] 3022. [bug] Fixed rpz SERVFAILs after failed zone transfers [RT #23246] 3021. [bug] Change #3010 was incomplete. [RT #22296] 3020. [bug] auto-dnssec failed to correctly update the zone when changing the DNSKEY RRset. [RT #23232] 3019. [test] Test: check apex NSEC3 records after adding DNSKEY record via UPDATE. [RT #23229] 3018. [bug] Named failed to check for the "none;" acl when deciding if a zone may need to be re-signed. [RT #23120] 3017. [doc] dnssec-keyfromlabel -I was not properly documented. [RT #22887] 3016. [bug] rndc usage missing '-b'. [RT #22937] 3015. [port] win32: fix IN6_IS_ADDR_LINKLOCAL and IN6_IS_ADDR_SITELOCAL macros. [RT #22724] 3014. [placeholder] 3013. [bug] The DNS64 ttl was not always being set as expected. [RT #23034] 3012. [bug] Remove DNSKEY TTL change pairs before generating signing records for any remaining DNSKEY changes. [RT #22590] 3011. [func] Change the default query timeout from 30 seconds to 10. Allow setting this in named.conf using the new 'resolver-query-timeout' option, which specifies a max time in seconds. 0 means 'default' and anything longer than 30 will be silently set to 30. [RT #22852] 3010. [bug] Fixed a bug where "rndc reconfig" stopped the timer for refreshing managed-keys. [RT #22296] 3009. [bug] clients-per-query code didn't work as expected with particular query patterns. [RT #22972] --- 9.8.0b1 released --- 3008. [func] Response policy zones (RPZ) support. [RT #21726] 3007. [bug] Named failed to preserve the case of domain names in rdata which is not compressible when writing master files. [RT #22863] 3006. [func] Allow dynamically generated TSIG keys to be preserved across restarts of named. Initially this is for TSIG keys generated using GSSAPI. [RT #22639] 3005. [port] Solaris: Work around the lack of gsskrb5_register_acceptor_identity() by setting the KRB5_KTNAME environment variable to the contents of tkey-gssapi-keytab. Also fixed test errors on MacOSX. [RT #22853] 3004. [func] DNS64 reverse support. [RT #22769] 3003. [experimental] Added update-policy match type "external", enabling named to defer the decision of whether to allow a dynamic update to an external daemon. (Contributed by Andrew Tridgell.) [RT #22758] 3002. [bug] isc_mutex_init_errcheck() failed to destroy attr. [RT #22766] 3001. [func] Added a default trust anchor for the root zone, which can be switched on by setting "dnssec-validation auto;" in the named.conf options. [RT #21727] 3000. [bug] More TKEY/GSS fixes: - nsupdate can now get the default realm from the user's Kerberos principal - corrected gsstest compilation flags - improved documentation - fixed some NULL dereferences [RT #22795] 2999. [func] Add GOST support (RFC 5933). [RT #20639] 2998. [func] Add isc_task_beginexclusive and isc_task_endexclusive to the task api. [RT #22776] 2997. [func] named -V now reports the OpenSSL and libxml2 verions it was compiled against. [RT #22687] 2996. [security] Temporarily disable SO_ACCEPTFILTER support. [RT #22589] 2995. [bug] The Kerberos realm was not being correctly extracted from the signer's identity. [RT #22770] 2994. [port] NetBSD: use pthreads by default on NetBSD >= 5.0, and do not use threads on earlier versions. Also kill the unproven-pthreads, mit-pthreads, and ptl2 support. 2993. [func] Dynamically grow adb hash tables. [RT #21186] 2992. [contrib] contrib/check-secure-delegation.pl: A simple tool for looking at a secure delegation. [RT #22059] 2991. [contrib] contrib/zone-edit.sh: A simple zone editing tool for dynamic zones. [RT #22365] 2990. [bug] 'dnssec-settime -S' no longer tests prepublication interval validity when the interval is set to 0. [RT #22761] 2989. [func] Added support for writable DLZ zones. (Contributed by Andrew Tridgell of the Samba project.) [RT #22629] 2988. [experimental] Added a "dlopen" DLZ driver, allowing the creation of external DLZ drivers that can be loaded as shared objects at runtime rather than linked with named. Currently this is switched on via a compile-time option, "configure --with-dlz-dlopen". Note: the syntax for configuring DLZ zones is likely to be refined in future releases. (Contributed by Andrew Tridgell of the Samba project.) [RT #22629] 2987. [func] Improve ease of configuring TKEY/GSS updates by adding a "tkey-gssapi-keytab" option. If set, updates will be allowed with any key matching a principal in the specified keytab file. "tkey-gssapi-credential" is no longer required and is expected to be deprecated. (Contributed by Andrew Tridgell of the Samba project.) [RT #22629] 2986. [func] Add new zone type "static-stub". It's like a stub zone, but the nameserver names and/or their IP addresses are statically configured. [RT #21474] 2985. [bug] Add a regression test for change #2896. [RT #21324] 2984. [bug] Don't run MX checks when the target of the MX record is ".". [RT #22645] 2983. [bug] Include "loadkeys" in rndc help output. [RT #22493] --- 9.8.0a1 released --- 2982. [bug] Reference count dst keys. dst_key_attach() can be used increment the reference count. Note: dns_tsigkey_createfromkey() callers should now always call dst_key_free() rather than setting it to NULL on success. [RT #22672] 2981. [func] Partial DNS64 support (AAAA synthesis). [RT #21991] 2980. [bug] named didn't properly handle UPDATES that changed the TTL of the NSEC3PARAM RRset. [RT #22363] 2979. [bug] named could deadlock during shutdown if two "rndc stop" commands were issued at the same time. [RT #22108] 2978. [port] hpux: look for [RT #21919] 2977. [bug] 'nsupdate -l' report if the session key is missing. [RT #21670] 2976. [bug] named could die on exit after negotiating a GSS-TSIG key. [RT #22573] 2975. [bug] rbtdb.c:cleanup_dead_nodes_callback() acquired the wrong lock which could lead to server deadlock. [RT #22614] 2974. [bug] Some valid UPDATE requests could fail due to a consistency check examining the existing version of the zone rather than the new version resulting from the UPDATE. [RT #22413] 2973. [bug] bind.keys.h was being removed by the "make clean" at the end of configure resulting in build failures where there is very old version of perl installed. Move it to "make maintainer-clean". [RT #22230] 2972. [bug] win32: address windows socket errors. [RT #21906] 2971. [bug] Fixed a bug that caused journal files not to be compacted on Windows systems as a result of non-POSIX-compliant rename() semantics. [RT #22434] 2970. [security] Adding a NO DATA negative cache entry failed to clear any matching RRSIG records. A subsequent lookup of of NO DATA cache entry could trigger a INSIST when the unexpected RRSIG was also returned with the NO DATA cache entry. CVE-2010-3613, VU#706148. [RT #22288] 2969. [security] Fix acl type processing so that allow-query works in options and view statements. Also add a new set of tests to verify proper functioning. CVE-2010-3615, VU#510208. [RT #22418] 2968. [security] Named could fail to prove a data set was insecure before marking it as insecure. One set of conditions that can trigger this occurs naturally when rolling DNSKEY algorithms. CVE-2010-3614, VU#837744. [RT #22309] 2967. [bug] 'host -D' now turns on debugging messages earlier. [RT #22361] 2966. [bug] isc_print_vsnprintf() failed to check if there was space available in the buffer when adding a left justified character with a non zero width, (e.g. "%-1c"). [RT #22270] 2965. [func] Test HMAC functions using test data from RFC 2104 and RFC 4634. [RT #21702] 2964. [placeholder] 2963. [security] The allow-query acl was being applied instead of the allow-query-cache acl to cache lookups. [RT #22114] 2962. [port] win32: add more dependencies to BINDBuild.dsw. [RT #22062] 2961. [bug] Be still more selective about the non-authoritative answers we apply change 2748 to. [RT #22074] 2960. [func] Check that named accepts non-authoritative answers. [RT #21594] 2959. [func] Check that named starts with a missing masterfile. [RT #22076] 2958. [bug] named failed to start with a missing master file. [RT #22076] 2957. [bug] entropy_get() and entropy_getpseudo() failed to match the API for RAND_bytes() and RAND_pseudo_bytes() respectively. [RT #21962] 2956. [port] Enable atomic operations on the PowerPC64. [RT #21899] 2955. [func] Provide more detail in the recursing log. [RT #22043] 2954. [bug] contrib: dlz_mysql_driver.c bad error handling on build_sqldbinstance failure. [RT #21623] 2953. [bug] Silence spurious "expected covering NSEC3, got an exact match" message when returning a wildcard no data response. [RT #21744] 2952. [port] win32: named-checkzone and named-checkconf failed to initialize winsock. [RT #21932] 2951. [bug] named failed to generate a correct signed response in a optout, delegation only zone with no secure delegations. [RT #22007] 2950. [bug] named failed to perform a SOA up to date check when falling back to TCP on UDP timeouts when ixfr-from-differences was set. [RT #21595] 2949. [bug] dns_view_setnewzones() contained a memory leak if it was called multiple times. [RT #21942] 2948. [port] MacOS: provide a mechanism to configure the test interfaces at reboot. See bin/tests/system/README for details. 2947. [placeholder] 2946. [doc] Document the default values for the minimum and maximum zone refresh and retry values in the ARM. [RT #21886] 2945. [doc] Update empty-zones list in ARM. [RT #21772] 2944. [maint] Remove ORCHID prefix from built in empty zones. [RT #21772] 2943. [func] Add support to load new keys into managed zones without signing immediately with "rndc loadkeys". Add support to link keys with "dnssec-keygen -S" and "dnssec-settime -S". [RT #21351] 2942. [contrib] zone2sqlite failed to setup the entropy sources. [RT #21610] 2941. [bug] sdb and sdlz (dlz's zone database) failed to support DNAME at the zone apex. [RT #21610] 2940. [port] Remove connection aborted error message on Windows. [RT #21549] 2939. [func] Check that named successfully skips NSEC3 records that fail to match the NSEC3PARAM record currently in use. [RT #21868] 2938. [bug] When generating signed responses, from a signed zone that uses NSEC3, named would use a uninitialized pointer if it needed to skip a NSEC3 record because it didn't match the selected NSEC3PARAM record for zone. [RT #21868] 2937. [bug] Worked around an apparent race condition in over memory conditions. Without this fix a DNS cache DB or ADB could incorrectly stay in an over memory state, effectively refusing further caching, which subsequently made a BIND 9 caching server unworkable. This fix prevents this problem from happening by polling the state of the memory context, rather than making a copy of the state, which appeared to cause a race. This is a "workaround" in that it doesn't solve the possible race per se, but several experiments proved this change solves the symptom. Also, the polling overhead hasn't been reported to be an issue. This bug should only affect a caching server that specifies a finite max-cache-size. It's also quite likely that the bug happens only when enabling threads, but it's not confirmed yet. [RT #21818] 2936. [func] Improved configuration syntax and multiple-view support for addzone/delzone feature (see change #2930). Removed "new-zone-file" option, replaced with "allow-new-zones (yes|no)". The new-zone-file for each view is now created automatically, with a filename generated from a hash of the view name. It is no longer necessary to "include" the new-zone-file in named.conf; this happens automatically. Zones that were not added via "rndc addzone" can no longer be removed with "rndc delzone". [RT #19447] 2935. [bug] nsupdate: improve 'file not found' error message. [RT #21871] 2934. [bug] Use ANSI C compliant shift range in lib/isc/entropy.c. [RT #21871] 2933. [bug] 'dig +nsid' used stack memory after it went out of scope. This could potentially result in a unknown, potentially malformed, EDNS option being sent instead of the desired NSID option. [RT #21781] 2932. [cleanup] Corrected a numbering error in the "dnssec" test. [RT #21597] 2931. [bug] Temporarily and partially disable change 2864 because it would cause infinite attempts of RRSIG queries. This is an urgent care fix; we'll revisit the issue and complete the fix later. [RT #21710] 2930. [experimental] New "rndc addzone" and "rndc delzone" commands allow dynamic addition and deletion of zones. To enable this feature, specify a "new-zone-file" option at the view or options level in named.conf. Zone configuration information for the new zones will be written into that file. To make the new zones persist after a restart, "include" the file into named.conf in the appropriate view. (Note: This feature is not yet documented, and its syntax is expected to change.) [RT #19447] 2929. [bug] Improved handling of GSS security contexts: - added LRU expiration for generated TSIGs - added the ability to use a non-default realm - added new "realm" keyword in nsupdate - limited lifetime of generated keys to 1 hour or the lifetime of the context (whichever is smaller) [RT #19737] 2928. [bug] Be more selective about the non-authoritative answer we apply change 2748 to. [RT #21594] 2927. [placeholder] 2926. [placeholder] 2925. [bug] Named failed to accept uncachable negative responses from insecure zones. [RT #21555] 2924. [func] 'rndc secroots' dump a combined summary of the current managed keys combined with trusted keys. [RT #20904] 2923. [bug] 'dig +trace' could drop core after "connection timeout". [RT #21514] 2922. [contrib] Update zkt to version 1.0. 2921. [bug] The resolver could attempt to destroy a fetch context too soon. [RT #19878] 2920. [func] Allow 'filter-aaaa-on-v4' to be applied selectively to IPv4 clients. New acl 'filter-aaaa' (default any). 2919. [func] Add autosign-ksk and autosign-zsk virtual time tests. [RT #20840] 2918. [maint] Add AAAA address for I.ROOT-SERVERS.NET. 2917. [func] Virtual time test framework. [RT #20801] 2916. [func] Add framework to use IPv6 in tests. fd92:7065:b8e:ffff::1 ... fd92:7065:b8e:ffff::7 2915. [cleanup] Be smarter about which objects we attempt to compile based on configure options. [RT #21444] 2914. [bug] Make the "autosign" system test more portable. [RT #20997] 2913. [func] Add pkcs#11 system tests. [RT #20784] 2912. [func] Windows clients don't like UPDATE responses that clear the zone section. [RT #20986] 2911. [bug] dnssec-signzone didn't handle out of zone records well. [RT #21367] 2910. [func] Sanity check Kerberos credentials. [RT #20986] 2909. [bug] named-checkconf -p could die if "update-policy local;" was specified in named.conf. [RT #21416] 2908. [bug] It was possible for re-signing to stop after removing a DNSKEY. [RT #21384] 2907. [bug] The export version of libdns had undefined references. [RT #21444] 2906. [bug] Address RFC 5011 implementation issues. [RT #20903] 2905. [port] aix: set use_atomic=yes with native compiler. [RT #21402] 2904. [bug] When using DLV, sub-zones of the zones in the DLV, could be incorrectly marked as insecure instead of secure leading to negative proofs failing. This was a unintended outcome from change 2890. [RT #21392] 2903. [bug] managed-keys-directory missing from namedconf.c. [RT #21370] 2902. [func] Add regression test for change 2897. [RT #21040] 2901. [port] Use AC_C_FLEXIBLE_ARRAY_MEMBER. [RT #21316] 2900. [bug] The placeholder negative caching element was not properly constructed triggering a INSIST in dns_ncache_towire(). [RT #21346] 2899. [port] win32: Support linking against OpenSSL 1.0.0. 2898. [bug] nslookup leaked memory when -domain=value was specified. [RT #21301] 2897. [bug] NSEC3 chains could be left behind when transitioning to insecure. [RT #21040] 2896. [bug] "rndc sign" failed to properly update the zone when adding a DNSKEY for publication only. [RT #21045] 2895. [func] genrandom: add support for the generation of multiple files. [RT #20917] 2894. [contrib] DLZ LDAP support now use '$' not '%'. [RT #21294] 2893. [bug] Improve managed keys support. New named.conf option managed-keys-directory. [RT #20924] 2892. [bug] Handle REVOKED keys better. [RT #20961] 2891. [maint] Update empty-zones list to match draft-ietf-dnsop-default-local-zones-13. [RT #21099] 2890. [bug] Handle the introduction of new trusted-keys and DS, DLV RRsets better. [RT #21097] 2889. [bug] Elements of the grammar where not properly reported. [RT #21046] 2888. [bug] Only the first EDNS option was displayed. [RT #21273] 2887. [bug] Report the keytag times in UTC in the .key file, local time is presented as a comment within the comment. [RT #21223] 2886. [bug] ctime() is not thread safe. [RT #21223] 2885. [bug] Improve -fno-strict-aliasing support probing in configure. [RT #21080] 2884. [bug] Insufficient validation in dns_name_getlabelsequence(). [RT #21283] 2883. [bug] 'dig +short' failed to handle really large datasets. [RT #21113] 2882. [bug] Remove memory context from list of active contexts before clearing 'magic'. [RT #21274] 2881. [bug] Reduce the amount of time the rbtdb write lock is held when closing a version. [RT #21198] 2880. [cleanup] Make the output of dnssec-keygen and dnssec-revoke consistent. [RT #21078] 2879. [contrib] DLZ bdbhpt driver fails to close correct cursor. [RT #21106] 2878. [func] Incrementally write the master file after performing a AXFR. [RT #21010] 2877. [bug] The validator failed to skip obviously mismatching RRSIGs. [RT #21138] 2876. [bug] Named could return SERVFAIL for negative responses from unsigned zones. [RT #21131] 2875. [bug] dns_time64_fromtext() could accept non digits. [RT #21033] 2874. [bug] Cache lack of EDNS support only after the server successfully responds to the query using plain DNS. [RT #20930] 2873. [bug] Canceling a dynamic update via the dns/client module could trigger an assertion failure. [RT #21133] 2872. [bug] Modify dns/client.c:dns_client_createx() to only require one of IPv4 or IPv6 rather than both. [RT #21122] 2871. [bug] Type mismatch in mem_api.c between the definition and the header file, causing build failure with --enable-exportlib. [RT #21138] 2870. [maint] Add AAAA address for L.ROOT-SERVERS.NET. 2869. [bug] Fix arguments to dns_keytable_findnextkeynode() call. [RT #20877] 2868. [cleanup] Run "make clean" at the end of configure to ensure any changes made by configure are integrated. Use --with-make-clean=no to disable. [RT #20994] 2867. [bug] Don't set GSS_C_SEQUENCE_FLAG as Windows DNS servers don't like it. [RT #20986] 2866. [bug] Windows does not like the TSIG name being compressed. [RT #20986] 2865. [bug] memset to zero event.data. [RT #20986] 2864. [bug] Direct SIG/RRSIG queries were not handled correctly. [RT #21050] 2863. [port] linux: disable IPv6 PMTUD and use network minimum MTU. [RT #21056] 2862. [bug] nsupdate didn't default to the parent zone when updating DS records. [RT #20896] 2861. [doc] dnssec-settime man pages didn't correctly document the inactivation time. [RT #21039] 2860. [bug] named-checkconf's usage was out of date. [RT #21039] 2859. [bug] When canceling validation it was possible to leak memory. [RT #20800] 2858. [bug] RTT estimates were not being adjusted on ICMP errors. [RT #20772] 2857. [bug] named-checkconf did not fail on a bad trusted key. [RT #20705] 2856. [bug] The size of a memory allocation was not always properly recorded. [RT #20927] 2855. [func] nsupdate will now preserve the entered case of domain names in update requests it sends. [RT #20928] 2854. [func] dig: allow the final soa record in a axfr response to be suppressed, dig +onesoa. [RT #20929] 2853. [bug] add_sigs() could run out of scratch space. [RT #21015] 2852. [bug] Handle broken DNSSEC trust chains better. [RT #15619] 2851. [doc] nslookup.1, removed from the docbook source as it produced bad nroff. [RT #21007] 2850. [bug] If isc_heap_insert() failed due to memory shortage the heap would have corrupted entries. [RT #20951] 2849. [bug] Don't treat errors from the xml2 library as fatal. [RT #20945] 2848. [doc] Moved README.dnssec, README.libdns, README.pkcs11 and README.rfc5011 into the ARM. [RT #20899] 2847. [cleanup] Corrected usage message in dnssec-settime. [RT #20921] 2846. [bug] EOF on unix domain sockets was not being handled correctly. [RT #20731] 2845. [bug] RFC 5011 client could crash on shutdown. [RT #20903] 2844. [doc] notify-delay default in ARM was wrong. It should have been five (5) seconds. 2843. [func] Prevent dnssec-keygen and dnssec-keyfromlabel from creating key files if there is a chance that the new key ID will collide with an existing one after either of the keys has been revoked. (To override this in the case of dnssec-keyfromlabel, use the -y option. dnssec-keygen will simply create a different, non-colliding key, so an override is not necessary.) [RT #20838] 2842. [func] Added "smartsign" and improved "autosign" and "dnssec" regression tests. [RT #20865] 2841. [bug] Change 2836 was not complete. [RT #20883] 2840. [bug] Temporary fixed pkcs11-destroy usage check. [RT #20760] 2839. [bug] A KSK revoked by named could not be deleted. [RT #20881] 2838. [placeholder] 2837. [port] Prevent Linux spurious warnings about fwrite(). [RT #20812] 2836. [bug] Keys that were scheduled to become active could be delayed. [RT #20874] 2835. [bug] Key inactivity dates were inadvertently stored in the private key file with the outdated tag "Unpublish" rather than "Inactive". This has been fixed; however, any existing keys that had Inactive dates set will now need to have them reset, using 'dnssec-settime -I'. [RT #20868] 2834. [bug] HMAC-SHA* keys that were longer than the algorithm digest length were used incorrectly, leading to interoperability problems with other DNS implementations. This has been corrected. (Note: If an oversize key is in use, and compatibility is needed with an older release of BIND, the new tool "isc-hmac-fixup" can convert the key secret to a form that will work with all versions.) [RT #20751] 2833. [cleanup] Fix usage messages in dnssec-keygen and dnssec-settime. [RT #20851] 2832. [bug] Modify "struct stat" in lib/export/samples/nsprobe.c to avoid redefinition in some OSs [RT 20831] 2831. [security] Do not attempt to validate or cache out-of-bailiwick data returned with a secure answer; it must be re-fetched from its original source and validated in that context. [RT #20819] 2830. [bug] Changing the OPTOUT setting could take multiple passes. [RT #20813] 2829. [bug] Fixed potential node inconsistency in rbtdb.c. [RT #20808] 2828. [security] Cached CNAME or DNAME RR could be returned to clients without DNSSEC validation. [RT #20737] 2827. [security] Bogus NXDOMAIN could be cached as if valid. [RT #20712] 2826. [bug] NSEC3->NSEC transitions could fail due to a lock not being released. [RT #20740] 2825. [bug] Changing the setting of OPTOUT in a NSEC3 chain that was in the process of being created was not properly recorded in the zone. [RT #20786] 2824. [bug] "rndc sign" was not being run by the correct task. [RT #20759] 2823. [bug] rbtdb.c:getsigningtime() was missing locks. [RT #20781] 2822. [bug] rbtdb.c:loadnode() could return the wrong result. [RT #20802] 2821. [doc] Add note that named-checkconf doesn't automatically read rndc.key and bind.keys [RT #20758] 2820. [func] Handle read access failure of OpenSSL configuration file more user friendly (PKCS#11 engine patch). [RT #20668] 2819. [cleanup] Removed unnecessary DNS_POINTER_MAXHOPS define. [RT #20771] 2818. [cleanup] rndc could return an incorrect error code when a zone was not found. [RT #20767] 2817. [cleanup] Removed unnecessary isc_task_endexclusive() calls. [RT #20768] 2816. [bug] previous_closest_nsec() could fail to return data for NSEC3 nodes [RT #29730] 2815. [bug] Exclusively lock the task when freezing a zone. [RT #19838] 2814. [func] Provide a definitive error message when a master zone is not loaded. [RT #20757] 2813. [bug] Better handling of unreadable DNSSEC key files. [RT #20710] 2812. [bug] Make sure updates can't result in a zone with NSEC-only keys and NSEC3 records. [RT #20748] 2811. [cleanup] Add "rndc sign" to list of commands in rndc usage output. [RT #20733] 2810. [doc] Clarified the process of transitioning an NSEC3 zone to insecure. [RT #20746] 2809. [cleanup] Restored accidentally-deleted text in usage output in dnssec-settime and dnssec-revoke [RT #20739] 2808. [bug] Remove the attempt to install atomic.h from lib/isc. atomic.h is correctly installed by the architecture specific subdirectories. [RT #20722] 2807. [bug] Fixed a possible ASSERT when reconfiguring zone keys. [RT #20720] --- 9.7.0rc1 released --- 2806. [bug] "rdnc sign" could delay re-signing the DNSKEY when it had changed. [RT #20703] 2805. [bug] Fixed namespace problems encountered when building external programs using non-exported BIND9 libraries (i.e., built without --enable-exportlib). [RT #20679] 2804. [bug] Send notifies when a zone is signed with "rndc sign" or as a result of a scheduled key change. [RT #20700] 2803. [port] win32: Install named-journalprint, nsec3hash, arpaname and genrandom under windows. [RT #20670] 2802. [cleanup] Rename journalprint to named-journalprint. [RT #20670] 2801. [func] Detect and report records that are different according to DNSSEC but are semantically equal according to plain DNS. Apply plain DNS comparisons rather than DNSSEC comparisons when processing UPDATE requests. dnssec-signzone now removes such semantically duplicate records prior to signing the RRset. named-checkzone -r {ignore|warn|fail} (default warn) named-compilezone -r {ignore|warn|fail} (default warn) named.conf: check-dup-records {ignore|warn|fail}; 2800. [func] Reject zones which have NS records which refer to CNAMEs, DNAMEs or don't have address record (class IN only). Reject UPDATEs which would cause the zone to fail the above checks if committed. [RT #20678] 2799. [cleanup] Changed the "secure-to-insecure" option to "dnssec-secure-to-insecure", and "dnskey-ksk-only" to "dnssec-dnskey-kskonly", for clarity. [RT #20586] 2798. [bug] Addressed bugs in managed-keys initialization and rollover. [RT #20683] 2797. [bug] Don't decrement the dispatch manager's maxbuffers. [RT #20613] 2796. [bug] Missing dns_rdataset_disassociate() call in dns_nsec3_delnsec3sx(). [RT #20681] 2795. [cleanup] Add text to differentiate "update with no effect" log messages. [RT #18889] 2794. [bug] Install . [RT #20677] 2793. [func] Add "autosign" and "metadata" tests to the automatic tests. [RT #19946] 2792. [func] "filter-aaaa-on-v4" can now be set in view options (if compiled in). [RT #20635] 2791. [bug] The installation of isc-config.sh was broken. [RT #20667] 2790. [bug] Handle DS queries to stub zones. [RT #20440] 2789. [bug] Fixed an INSIST in dispatch.c [RT #20576] 2788. [bug] dnssec-signzone could sign with keys that were not requested [RT #20625] 2787. [bug] Spurious log message when zone keys were dynamically reconfigured. [RT #20659] 2786. [bug] Additional could be promoted to answer. [RT #20663] --- 9.7.0b3 released --- 2785. [bug] Revoked keys could fail to self-sign [RT #20652] 2784. [bug] TC was not always being set when required glue was dropped. [RT #20655] 2783. [func] Return minimal responses to EDNS/UDP queries with a UDP buffer size of 512 or less. [RT #20654] 2782. [port] win32: use getaddrinfo() for hostname lookups. [RT #20650] 2781. [bug] Inactive keys could be used for signing. [RT #20649] 2780. [bug] dnssec-keygen -A none didn't properly unset the activation date in all cases. [RT #20648] 2779. [bug] Dynamic key revocation could fail. [RT #20644] 2778. [bug] dnssec-signzone could fail when a key was revoked without deleting the unrevoked version. [RT #20638] 2777. [contrib] DLZ MYSQL auto reconnect support discovery was wrong. 2776. [bug] Change #2762 was not correct. [RT #20647] 2775. [bug] Accept RSASHA256 and RSASHA512 as NSEC3 compatible in dnssec-keyfromlabel. [RT #20643] 2774. [bug] Existing cache DB wasn't being reused after reconfiguration. [RT #20629] 2773. [bug] In autosigned zones, the SOA could be signed with the KSK. [RT #20628] 2772. [security] When validating, track whether pending data was from the additional section or not and only return it if validates as secure. [RT #20438] 2771. [bug] dnssec-signzone: DNSKEY records could be corrupted when importing from key files [RT #20624] 2770. [cleanup] Add log messages to resolver.c to indicate events causing FORMERR responses. [RT #20526] 2769. [cleanup] Change #2742 was incomplete. [RT #19589] 2768. [bug] dnssec-signzone: -S no longer implies -g [RT #20568] 2767. [bug] named could crash on startup if a zone was configured with auto-dnssec and there was no key-directory. [RT #20615] 2766. [bug] isc_socket_fdwatchpoke() should only update the socketmgr state if the socket is not pending on a read or write. [RT #20603] 2765. [bug] Skip masters for which the TSIG key cannot be found. [RT #20595] 2764. [bug] "rndc-confgen -a" could trigger a REQUIRE. [RT #20610] 2763. [bug] "rndc sign" didn't create an NSEC chain. [RT #20591] 2762. [bug] DLV validation failed with a local slave DLV zone. [RT #20577] 2761. [cleanup] Enable internal symbol table for backtrace only for systems that are known to work. Currently, BSD variants, Linux and Solaris are supported. [RT #20202] 2760. [cleanup] Corrected named-compilezone usage summary. [RT #20533] 2759. [doc] Add information about .jbk/.jnw files to the ARM. [RT #20303] 2758. [bug] win32: Added a workaround for a windows 2008 bug that could cause the UDP client handler to shut down. [RT #19176] 2757. [bug] dig: assertion failure could occur in connect timeout. [RT #20599] 2756. [bug] Fixed corrupt logfile message in update.c. [RT #20597] 2755. [placeholder] 2754. [bug] Secure-to-insecure transitions failed when zone was signed with NSEC3. [RT #20587] 2753. [bug] Removed an unnecessary warning that could appear when building an NSEC chain. [RT #20589] 2752. [bug] Locking violation. [RT #20587] 2751. [bug] Fixed a memory leak in dnssec-keyfromlabel. [RT #20588] 2750. [bug] dig: assertion failure could occur when a server didn't have an address. [RT #20579] 2749. [bug] ixfr-from-differences generated a non-minimal ixfr for NSEC3 signed zones. [RT #20452] 2748. [func] Identify bad answers from GTLD servers and treat them as referrals. [RT #18884] 2747. [bug] Journal roll forwards failed to set the re-signing time of RRSIGs correctly. [RT #20541] 2746. [port] hpux: address signed/unsigned expansion mismatch of dns_rbtnode_t.nsec. [RT #20542] 2745. [bug] configure script didn't probe the return type of gai_strerror(3) correctly. [RT #20573] 2744. [func] Log if a query was over TCP. [RT #19961] 2743. [bug] RRSIG could be incorrectly set in the NSEC3 record for a insecure delegation. --- 9.7.0b2 released --- 2742. [cleanup] Clarify some DNSSEC-related log messages in validator.c. [RT #19589] 2741. [func] Allow the dnssec-keygen progress messages to be suppressed (dnssec-keygen -q). Automatically suppress the progress messages when stdin is not a tty. [RT #20474] 2740. [placeholder] 2739. [cleanup] Clean up API for initializing and clearing trust anchors for a view. [RT #20211] 2738. [func] Add RSASHA256 and RSASHA512 tests to the dnssec system test. [RT #20453] 2737. [func] UPDATE requests can leak existence information. [RT #17261] 2736. [func] Improve the performance of NSEC signed zones with more than a normal amount of glue below a delegation. [RT #20191] 2735. [bug] dnssec-signzone could fail to read keys that were specified on the command line with full paths, but weren't in the current directory. [RT #20421] 2734. [port] cygwin: arpaname did not compile. [RT #20473] 2733. [cleanup] Clean up coding style in pkcs11-* tools. [RT #20355] 2732. [func] Add optional filter-aaaa-on-v4 option, available if built with './configure --enable-filter-aaaa'. Filters out AAAA answers to clients connecting via IPv4. (This is NOT recommended for general use.) [RT #20339] 2731. [func] Additional work on change 2709. The key parser will now ignore unrecognized fields when the minor version number of the private key format has been increased. It will reject any key with the major version number increased. [RT #20310] 2730. [func] Have dnssec-keygen display a progress indication a la 'openssl genrsa' on standard error. Note when the first '.' is followed by a long stop one has the choice between slow generation vs. poor random quality, i.e., '-r /dev/urandom'. [RT #20284] 2729. [func] When constructing a CNAME from a DNAME use the DNAME TTL. [RT #20451] 2728. [bug] dnssec-keygen, dnssec-keyfromlabel and dnssec-signzone now warn immediately if asked to write into a nonexistent directory. [RT #20278] 2727. [func] The 'key-directory' option can now specify a relative path. [RT #20154] 2726. [func] Added support for SHA-2 DNSSEC algorithms, RSASHA256 and RSASHA512. [RT #20023] 2725. [doc] Added information about the file "managed-keys.bind" to the ARM. [RT #20235] 2724. [bug] Updates to a existing node in secure zone using NSEC were failing. [RT #20448] 2723. [bug] isc_base32_totext(), isc_base32hex_totext(), and isc_base64_totext(), didn't always mark regions of memory as fully consumed after conversion. [RT #20445] 2722. [bug] Ensure that the memory associated with the name of a node in a rbt tree is not altered during the life of the node. [RT #20431] 2721. [port] Have dst__entropy_status() prime the random number generator. [RT #20369] 2720. [bug] RFC 5011 trust anchor updates could trigger an assert if the DNSKEY record was unsigned. [RT #20406] 2719. [func] Skip trusted/managed keys for unsupported algorithms. [RT #20392] 2718. [bug] The space calculations in opensslrsa_todns() were incorrect. [RT #20394] 2717. [bug] named failed to update the NSEC/NSEC3 record when the last private type record was removed as a result of completing the signing the zone with a key. [RT #20399] 2716. [bug] nslookup debug mode didn't return the ttl. [RT #20414] --- 9.7.0b1 released --- 2715. [bug] Require OpenSSL support to be explicitly disabled. [RT #20288] 2714. [port] aix/powerpc: 'asm("ics");' needs non standard assembler flags. 2713. [bug] powerpc: atomic operations missing asm("ics") / __isync() calls. 2712. [func] New 'auto-dnssec' zone option allows zone signing to be fully automated in zones configured for dynamic DNS. 'auto-dnssec allow;' permits a zone to be signed by creating keys for it in the key-directory and using 'rndc sign '. 'auto-dnssec maintain;' allows that too, plus it also keeps the zone's DNSSEC keys up to date according to their timing metadata. [RT #19943] 2711. [port] win32: Add the bin/pkcs11 tools into the full build. [RT #20372] 2710. [func] New 'dnssec-signzone -x' flag and 'dnskey-ksk-only' zone option cause a zone to be signed with only KSKs signing the DNSKEY RRset, not ZSKs. This reduces the size of a DNSKEY answer. [RT #20340] 2709. [func] Added some data fields, currently unused, to the private key file format, to allow implementation of explicit key rollover in a future release without impairing backward or forward compatibility. [RT #20310] 2708. [func] Insecure to secure and NSEC3 parameter changes via update are now fully supported and no longer require defines to enable. We now no longer overload the NSEC3PARAM flag field, nor the NSEC OPT bit at the apex. Secure to insecure changes are controlled by by the named.conf option 'secure-to-insecure'. Warning: If you had previously enabled support by adding defines at compile time to BIND 9.6 you should ensure that all changes that are in progress have completed prior to upgrading to BIND 9.7. BIND 9.7 is not backwards compatible. 2707. [func] dnssec-keyfromlabel no longer require engine name to be specified in the label if there is a default engine or the -E option has been used. Also, it now uses default algorithms as dnssec-keygen does (i.e., RSASHA1, or NSEC3RSASHA1 if -3 is used). [RT #20371] 2706. [bug] Loading a zone with a very large NSEC3 salt could trigger an assert. [RT #20368] 2705. [placeholder] 2704. [bug] Serial of dynamic and stub zones could be inconsistent with their SOA serial. [RT #19387] 2703. [func] Introduce an OpenSSL "engine" argument with -E for all binaries which can take benefit of crypto hardware. [RT #20230] 2702. [func] Update PKCS#11 tools (bin/pkcs11) [RT #20225 & all] 2701. [doc] Correction to ARM: hmac-md5 is no longer the only supported TSIG key algorithm. [RT #18046] 2700. [doc] The match-mapped-addresses option is discouraged. [RT #12252] 2699. [bug] Missing lock in rbtdb.c. [RT #20037] 2698. [placeholder] 2697. [port] win32: ensure that S_IFMT, S_IFDIR, S_IFCHR and S_IFREG are defined after including . [RT #20309] 2696. [bug] named failed to successfully process some valid acl constructs. [RT #20308] 2695. [func] DHCP/DDNS - update fdwatch code for use by DHCP. Modify the api to isc_sockfdwatch_t (the callback function for isc_socket_fdwatchcreate) to include information about the direction (read or write) and add isc_socket_fdwatchpoke. [RT #20253] 2694. [bug] Reduce default NSEC3 iterations from 100 to 10. [RT #19970] 2693. [port] Add some noreturn attributes. [RT #20257] 2692. [port] win32: 32/64 bit cleanups. [RT #20335] 2691. [func] dnssec-signzone: retain the existing NSEC or NSEC3 chain when re-signing a previously-signed zone. Use -u to modify NSEC3 parameters or switch between NSEC and NSEC3. [RT #20304] 2690. [bug] win32: fix isc_thread_key_getspecific() prototype. [RT #20315] 2689. [bug] Correctly handle snprintf result. [RT #20306] 2688. [bug] Use INTERFACE_F_POINTTOPOINT, not IFF_POINTOPOINT, to decide to fetch the destination address. [RT #20305] 2687. [bug] Fixed dnssec-signzone -S handling of revoked keys. Also, added warnings when revoking a ZSK, as this is not defined by protocol (but is legal). [RT #19943] 2686. [bug] dnssec-signzone should clean the old NSEC chain when signing with NSEC3 and vice versa. [RT #20301] 2685. [contrib] Update contrib/zkt to version 0.99c. [RT #20054] 2684. [cleanup] dig: formalize +ad and +cd as synonyms for +adflag and +cdflag. [RT #19305] 2683. [bug] dnssec-signzone should clean out old NSEC3 chains when the NSEC3 parameters used to sign the zone change. [RT #20246] 2682. [bug] "configure --enable-symtable=all" failed to build. [RT #20282] 2681. [bug] IPSECKEY RR of gateway type 3 was not correctly decoded. [RT #20269] 2680. [func] Move contrib/pkcs11-keygen to bin/pkcs11. [RT #20067] 2679. [func] dig -k can now accept TSIG keys in named.conf format. [RT #20031] 2678. [func] Treat DS queries as if "minimal-response yes;" was set. [RT #20258] 2677. [func] Changes to key metadata behavior: - Keys without "publish" or "active" dates set will no longer be used for smart signing. However, those dates will be set to "now" by default when a key is created; to generate a key but not use it yet, use dnssec-keygen -G. - New "inactive" date (dnssec-keygen/settime -I) sets the time when a key is no longer used for signing but is still published. - The "unpublished" date (-U) is deprecated in favor of "deleted" (-D). [RT #20247] 2676. [bug] --with-export-installdir should have been --with-export-includedir. [RT #20252] 2675. [bug] dnssec-signzone could crash if the key directory did not exist. [RT #20232] --- 9.7.0a3 released --- 2674. [bug] "dnssec-lookaside auto;" crashed if named was built without openssl. [RT #20231] 2673. [bug] The managed-keys.bind zone file could fail to load due to a spurious result from sync_keyzone() [RT #20045] 2672. [bug] Don't enable searching in 'host' when doing reverse lookups. [RT #20218] 2671. [bug] Add support for PKCS#11 providers not returning the public exponent in RSA private keys (OpenCryptoki for instance) in dnssec-keyfromlabel. [RT #19294] 2670. [bug] Unexpected connect failures failed to log enough information to be useful. [RT #20205] 2669. [func] Update PKCS#11 support to support Keyper HSM. Update PKCS#11 patch to be against openssl-0.9.8i. 2668. [func] Several improvements to dnssec-* tools, including: - dnssec-keygen and dnssec-settime can now set key metadata fields 0 (to unset a value, use "none") - dnssec-revoke sets the revocation date in addition to the revoke bit - dnssec-settime can now print individual metadata fields instead of always printing all of them, and can print them in unix epoch time format for use by scripts [RT #19942] 2667. [func] Add support for logging stack backtrace on assertion failure (not available for all platforms). [RT #19780] 2666. [func] Added an 'options' argument to dns_name_fromstring() (API change from 9.7.0a2). [RT #20196] 2665. [func] Clarify syntax for managed-keys {} statement, add ARM documentation about RFC 5011 support. [RT #19874] 2664. [bug] create_keydata() and minimal_update() in zone.c didn't properly check return values for some functions. [RT #19956] 2663. [func] win32: allow named to run as a service using "NT AUTHORITY\LocalService" as the account. [RT #19977] 2662. [bug] lwres_getipnodebyname() and lwres_getipnodebyaddr() returned a misleading error code when lwresd was down. [RT #20028] 2661. [bug] Check whether socket fd exceeds FD_SETSIZE when creating lwres context. [RT #20029] 2660. [func] Add a new set of DNS libraries for non-BIND9 applications. See README.libdns. [RT #19369] 2659. [doc] Clarify dnssec-keygen doc: key name must match zone name for DNSSEC keys. [RT #19938] 2658. [bug] dnssec-settime and dnssec-revoke didn't process key file paths correctly. [RT #20078] 2657. [cleanup] Lower "journal file does not exist, creating it" log level to debug 1. [RT #20058] 2656. [func] win32: add a "tools only" check box to the installer which causes it to only install dig, host, nslookup, nsupdate and relevant DLLs. [RT #19998] 2655. [doc] Document that key-directory does not affect bind.keys, rndc.key or session.key. [RT #20155] 2654. [bug] Improve error reporting on duplicated names for deny-answer-xxx. [RT #20164] 2653. [bug] Treat ENGINE_load_private_key() failures as key not found rather than out of memory. [RT #18033] 2652. [func] Provide more detail about what record is being deleted. [RT #20061] 2651. [bug] Dates could print incorrectly in K*.key files on 64-bit systems. [RT #20076] 2650. [bug] Assertion failure in dnssec-signzone when trying to read keyset-* files. [RT #20075] 2649. [bug] Set the domain for forward only zones. [RT #19944] 2648. [port] win32: isc_time_seconds() was broken. [RT #19900] 2647. [bug] Remove unnecessary SOA updates when a new KSK is added. [RT #19913] 2646. [bug] Incorrect cleanup on error in socket.c. [RT #19987] 2645. [port] "gcc -m32" didn't work on amd64 and x86_64 platforms which default to 64 bits. [RT #19927] --- 9.7.0a2 released --- 2644. [bug] Change #2628 caused a regression on some systems; named was unable to write the PID file and would fail on startup. [RT #20001] 2643. [bug] Stub zones interacted badly with NSEC3 support. [RT #19777] 2642. [bug] nsupdate could dump core on solaris when reading improperly formatted key files. [RT #20015] 2641. [bug] Fixed an error in parsing update-policy syntax, added a regression test to check it. [RT #20007] 2640. [security] A specially crafted update packet will cause named to exit. [RT #20000] 2639. [bug] Silence compiler warnings in gssapi code. [RT #19954] 2638. [bug] Install arpaname. [RT #19957] 2637. [func] Rationalize dnssec-signzone's signwithkey() calling. [RT #19959] 2636. [func] Simplify zone signing and key maintenance with the dnssec-* tools. Major changes: - all dnssec-* tools now take a -K option to specify a directory in which key files will be stored - DNSSEC can now store metadata indicating when they are scheduled to be published, activated, revoked or removed; these values can be set by dnssec-keygen or overwritten by the new dnssec-settime command - dnssec-signzone -S (for "smart") option reads key metadata and uses it to determine automatically which keys to publish to the zone, use for signing, revoke, or remove from the zone [RT #19816] 2635. [bug] isc_inet_ntop() incorrectly handled 0.0/16 addresses. [RT #19716] 2634. [port] win32: Add support for libxml2, enable statschannel. [RT #19773] 2633. [bug] Handle 15 bit rand() functions. [RT #19783] 2632. [func] util/kit.sh: warn if documentation appears to be out of date. [RT #19922] 2631. [bug] Handle "//", "/./" and "/../" in mkdirpath(). [RT #19926 ] 2630. [func] Improved syntax for DDNS autoconfiguration: use "update-policy local;" to switch on local DDNS in a zone. (The "ddns-autoconf" option has been removed.) [RT #19875] 2629. [port] Check for seteuid()/setegid(), use setresuid()/ setresgid() if not present. [RT #19932] 2628. [port] linux: Allow /var/run/named/named.pid to be opened at startup with reduced capabilities in operation. [RT #19884] 2627. [bug] Named aborted if the same key was included in trusted-keys more than once. [RT #19918] 2626. [bug] Multiple trusted-keys could trigger an assertion failure. [RT #19914] 2625. [bug] Missing UNLOCK in rbtdb.c. [RT #19865] 2624. [func] 'named-checkconf -p' will print out the parsed configuration. [RT #18871] 2623. [bug] Named started searches for DS non-optimally. [RT #19915] 2622. [bug] Printing of named.conf grammar was broken. [RT #19919] 2621. [doc] Made copyright boilerplate consistent. [RT #19833] 2620. [bug] Delay thawing the zone until the reload of it has completed successfully. [RT #19750] 2619. [func] Add support for RFC 5011, automatic trust anchor maintenance. The new "managed-keys" statement can be used in place of "trusted-keys" for zones which support this protocol. (Note: this syntax is expected to change prior to 9.7.0 final.) [RT #19248] 2618. [bug] The sdb and sdlz db_interator_seek() methods could loop infinitely. [RT #19847] 2617. [bug] ifconfig.sh failed to emit an error message when run from the wrong location. [RT #19375] 2616. [bug] 'host' used the nameservers from resolv.conf even when a explicit nameserver was specified. [RT #19852] 2615. [bug] "__attribute__((unused))" was in the wrong place for ia64 gcc builds. [RT #19854] 2614. [port] win32: 'named -v' should automatically be executed in the foreground. [RT #19844] 2613. [placeholder] --- 9.7.0a1 released --- 2612. [func] Add default values for the arguments to dnssec-keygen. Without arguments, it will now generate a 1024-bit RSASHA1 zone-signing key, or with the -f KSK option, a 2048-bit RSASHA1 key-signing key. [RT #19300] 2611. [func] Add -l option to dnssec-dsfromkey to generate DLV records instead of DS records. [RT #19300] 2610. [port] sunos: Change #2363 was not complete. [RT #19796] 2609. [func] Simplify the configuration of dynamic zones: - add ddns-confgen command to generate configuration text for named.conf - add zone option "ddns-autoconf yes;", which causes named to generate a TSIG session key and allow updates to the zone using that key - add '-l' (localhost) option to nsupdate, which causes nsupdate to connect to a locally-running named process using the session key generated by named [RT #19284] 2608. [func] Perform post signing verification checks in dnssec-signzone. These can be disabled with -P. The post sign verification test ensures that for each algorithm in use there is at least one non revoked self signed KSK key. That all revoked KSK keys are self signed. That all records in the zone are signed by the algorithm. [RT #19653] 2607. [bug] named could incorrectly delete NSEC3 records for empty nodes when processing a update request. [RT #19749] 2606. [bug] "delegation-only" was not being accepted in delegation-only type zones. [RT #19717] 2605. [bug] Accept DS responses from delegation only zones. [RT # 19296] 2604. [func] Add support for DNS rebinding attack prevention through new options, deny-answer-addresses and deny-answer-aliases. Based on contributed code from JD Nurmi, Google. [RT #18192] 2603. [port] win32: handle .exe extension of named-checkzone and named-comilezone argv[0] names under windows. [RT #19767] 2602. [port] win32: fix debugging command line build of libisccfg. [RT #19767] 2601. [doc] Mention file creation mode mask in the named manual page. 2600. [doc] ARM: miscellaneous reformatting for different page widths. [RT #19574] 2599. [bug] Address rapid memory growth when validation fails. [RT #19654] 2598. [func] Reserve the -F flag. [RT #19657] 2597. [bug] Handle a validation failure with a insecure delegation from a NSEC3 signed master/slave zone. [RT #19464] 2596. [bug] Stale tree nodes of cache/dynamic rbtdb could stay long, leading to inefficient memory usage or rejecting newer cache entries in the worst case. [RT #19563] 2595. [bug] Fix unknown extended rcodes in dig. [RT #19625] 2594. [func] Have rndc warn if using its default configuration file when the key file also exists. [RT #19424] 2593. [bug] Improve a corner source of SERVFAILs [RT #19632] 2592. [bug] Treat "any" as a type in nsupdate. [RT #19455] 2591. [bug] named could die when processing a update in removed_orphaned_ds(). [RT #19507] 2590. [func] Report zone/class of "update with no effect". [RT #19542] 2589. [bug] dns_db_unregister() failed to clear '*dbimp'. [RT #19626] 2588. [bug] SO_REUSEADDR could be set unconditionally after failure of bind(2) call. This should be rare and mostly harmless, but may cause interference with other processes that happen to use the same port. [RT #19642] 2587. [func] Improve logging by reporting serial numbers for when zone serial has gone backwards or unchanged. [RT #19506] 2586. [bug] Missing cleanup of SIG rdataset in searching a DLZ DB or SDB. [RT #19577] 2585. [bug] Uninitialized socket name could be referenced via a statistics channel, triggering an assertion failure in XML rendering. [RT #19427] 2584. [bug] alpha: gcc optimization could break atomic operations. [RT #19227] 2583. [port] netbsd: provide a control to not add the compile date to the version string, -DNO_VERSION_DATE. 2582. [bug] Don't emit warning log message when we attempt to remove non-existent journal. [RT #19516] 2581. [contrib] dlz/mysql set MYSQL_OPT_RECONNECT option on connection. Requires MySQL 5.0.19 or later. [RT #19084] 2580. [bug] UpdateRej statistics counter could be incremented twice for one rejection. [RT #19476] 2579. [bug] DNSSEC lookaside validation failed to handle unknown algorithms. [RT #19479] 2578. [bug] Changed default sig-signing-type to 65534, because 65535 turns out to be reserved. [RT #19477] 2577. [doc] Clarified some statistics counters. [RT #19454] 2576. [bug] NSEC record were not being correctly signed when a zone transitions from insecure to secure. Handle such incorrectly signed zones. [RT #19114] 2575. [func] New functions dns_name_fromstring() and dns_name_tostring(), to simplify conversion of a string to a dns_name structure and vice versa. [RT #19451] 2574. [doc] Document nsupdate -g and -o. [RT #19351] 2573. [bug] Replacing a non-CNAME record with a CNAME record in a single transaction in a signed zone failed. [RT #19397] 2572. [func] Simplify DLV configuration, with a new option "dnssec-lookaside auto;" This is the equivalent of "dnssec-lookaside . trust-anchor dlv.isc.org;" plus setting a trusted-key for dlv.isc.org. Note: The trusted key is hard-coded into named, but is also stored in (and can be overridden by) $sysconfdir/bind.keys. As the ISC DLV key rolls over it can be kept up to date by replacing the bind.keys file with a key downloaded from https://www.isc.org/solutions/dlv. [RT #18685] 2571. [func] Add a new tool "arpaname" which translates IP addresses to the corresponding IN-ADDR.ARPA or IP6.ARPA name. [RT #18976] 2570. [func] Log the destination address the query was sent to. [RT #19209] 2569. [func] Move journalprint, nsec3hash, and genrandom commands from bin/tests into bin/tools; "make install" will put them in $sbindir. [RT #19301] 2568. [bug] Report when the write to indicate a otherwise successful start fails. [RT #19360] 2567. [bug] dst__privstruct_writefile() could miss write errors. write_public_key() could miss write errors. dnssec-dsfromkey could miss write errors. [RT #19360] 2566. [cleanup] Clarify logged message when an insecure DNSSEC response arrives from a zone thought to be secure: "insecurity proof failed" instead of "not insecure". [RT #19400] 2565. [func] Add support for HIP record. Includes new functions dns_rdata_hip_first(), dns_rdata_hip_next() and dns_rdata_hip_current(). [RT #19384] 2564. [bug] Only take EDNS fallback steps when processing timeouts. [RT #19405] 2563. [bug] Dig could leak a socket causing it to wait forever to exit. [RT #19359] 2562. [doc] ARM: miscellaneous improvements, reorganization, and some new content. 2561. [doc] Add isc-config.sh(1) man page. [RT #16378] 2560. [bug] Add #include to iptable.c. [RT #18258] 2559. [bug] dnssec-dsfromkey could compute bad DS records when reading from a K* files. [RT #19357] 2558. [func] Set the ownership of missing directories created for pid-file if -u has been specified on the command line. [RT #19328] 2557. [cleanup] PCI compliance: * new libisc log module file * isc_dir_chroot() now also changes the working directory to "/". * additional INSISTs * additional logging when files can't be removed. 2556. [port] Solaris: mkdir(2) on tmpfs filesystems does not do the error checks in the correct order resulting in the wrong error code sometimes being returned. [RT #19249] 2555. [func] dig: when emitting a hex dump also display the corresponding characters. [RT #19258] 2554. [bug] Validation of uppercase queries from NSEC3 zones could fail. [RT #19297] 2553. [bug] Reference leak on DNSSEC validation errors. [RT #19291] 2552. [bug] zero-no-soa-ttl-cache was not being honored. [RT #19340] 2551. [bug] Potential Reference leak on return. [RT #19341] 2550. [bug] Check --with-openssl= finds . [RT #19343] 2549. [port] linux: define NR_OPEN if not currently defined. [RT #19344] 2548. [bug] Install iterated_hash.h. [RT #19335] 2547. [bug] openssl_link.c:mem_realloc() could reference an out-of-range area of the source buffer. New public function isc_mem_reallocate() was introduced to address this bug. [RT #19313] 2546. [func] Add --enable-openssl-hash configure flag to use OpenSSL (in place of internal routine) for hash functions (MD5, SHA[12] and HMAC). [RT #18815] 2545. [doc] ARM: Legal hostname checking (check-names) is for SRV RDATA too. [RT #19304] 2544. [cleanup] Removed unused structure members in adb.c. [RT #19225] 2543. [contrib] Update contrib/zkt to version 0.98. [RT #19113] 2542. [doc] Update the description of dig +adflag. [RT #19290] 2541. [bug] Conditionally update dispatch manager statistics. [RT #19247] 2540. [func] Add a nibble mode to $GENERATE. [RT #18872] 2539. [security] Update the interaction between recursion, allow-query, allow-query-cache and allow-recursion. [RT #19198] 2538. [bug] cache/ADB memory could grow over max-cache-size, especially with threads and smaller max-cache-size values. [RT #19240] 2537. [func] Added more statistics counters including those on socket I/O events and query RTT histograms. [RT #18802] 2536. [cleanup] Silence some warnings when -Werror=format-security is specified. [RT #19083] 2535. [bug] dig +showsearch and +trace interacted badly. [RT #19091] 2534. [func] Check NAPTR records regular expressions and replacement strings to ensure they are syntactically valid and consistent. [RT #18168] 2533. [doc] ARM: document @ (at-sign). [RT #17144] 2532. [bug] dig: check the question section of the response to see if it matches the asked question. [RT #18495] 2531. [bug] Change #2207 was incomplete. [RT #19098] 2530. [bug] named failed to reject insecure to secure transitions via UPDATE. [RT #19101] 2529. [cleanup] Upgrade libtool to silence complaints from recent version of autoconf. [RT #18657] 2528. [cleanup] Silence spurious configure warning about --datarootdir [RT #19096] 2527. [placeholder] 2526. [func] New named option "attach-cache" that allows multiple views to share a single cache to save memory and improve lookup efficiency. Based on contributed code from Barclay Osborn, Google. [RT #18905] 2525. [func] New logging category "query-errors" to provide detailed internal information about query failures, especially about server failures. [RT #19027] 2524. [port] sunos: dnssec-signzone needs strtoul(). [RT #19129] 2523. [bug] Random type rdata freed by dns_nsec_typepresent(). [RT #19112] 2522. [security] Handle -1 from DSA_do_verify() and EVP_VerifyFinal(). 2521. [bug] Improve epoll cross compilation support. [RT #19047] 2520. [bug] Update xml statistics version number to 2.0 as change #2388 made the schema incompatible to the previous version. [RT #19080] 2519. [bug] dig/host with -4 or -6 didn't work if more than two nameserver addresses of the excluded address family preceded in resolv.conf. [RT #19081] 2518. [func] Add support for the new CERT types from RFC 4398. [RT #19077] 2517. [bug] dig +trace with -4 or -6 failed when it chose a nameserver address of the excluded address type. [RT #18843] 2516. [bug] glue sort for responses was performed even when not needed. [RT #19039] 2515. [port] win32: build dnssec-dsfromkey and dnssec-keyfromlabel. [RT #19063] 2514. [bug] dig/host failed with -4 or -6 when resolv.conf contains a nameserver of the excluded address family. [RT #18848] 2513. [bug] Fix windows cli build. [RT #19062] 2512. [func] Print a summary of the cached records which make up the negative response. [RT #18885] 2511. [cleanup] dns_rdata_tofmttext() add const to linebreak. [RT #18885] 2510. [bug] "dig +sigchase" could trigger REQUIRE failures. [RT #19033] 2509. [bug] Specifying a fixed query source port was broken. [RT #19051] 2508. [placeholder] 2507. [func] Log the recursion quota values when killing the oldest query or refusing to recurse due to quota. [RT #19022] 2506. [port] solaris: Check at configure time if hack_shutup_pthreadonceinit is needed. [RT #19037] 2505. [port] Treat amd64 similarly to x86_64 when determining atomic operation support. [RT #19031] 2504. [bug] Address race condition in the socket code. [RT #18899] 2503. [port] linux: improve compatibility with Linux Standard Base. [RT #18793] 2502. [cleanup] isc_radix: Improve compliance with coding style, document function in . [RT #18534] 2501. [func] $GENERATE now supports all rdata types. Multi-field rdata types need to be quoted. See the ARM for details. [RT #18368] 2500. [contrib] contrib/sdb/pgsql/zonetodb.c called non-existent function. [RT #18582] 2499. [port] solaris: lib/lwres/getaddrinfo.c namespace clash. [RT #18837] --- 9.6.0rc1 released --- 2498. [bug] Removed a bogus function argument used with ISC_SOCKET_USE_POLLWATCH: it could cause compiler warning or crash named with the debug 1 level of logging. [RT #18917] 2497. [bug] Don't add RRSIG bit to NSEC3 bit map for insecure delegation. 2496. [bug] Add sanity length checks to NSID option. [RT #18813] 2495. [bug] Tighten RRSIG checks. [RT #18795] 2494. [bug] isc/radix.h, dns/sdlz.h and dns/dlz.h were not being installed. [RT #18826] 2493. [bug] The linux capabilities code was not correctly cleaning up after itself. [RT #18767] 2492. [func] Rndc status now reports the number of cpus discovered and the number of worker threads when running multi-threaded. [RT #18273] 2491. [func] Attempt to re-use a local port if we are already using the port. [RT #18548] 2490. [port] aix: work around a kernel bug where IPV6_RECVPKTINFO is cleared when IPV6_V6ONLY is set. [RT #18785] 2489. [port] solaris: Workaround Solaris's kernel bug about /dev/poll: http://bugs.opensolaris.org/view_bug.do?bug_id=6724237 Define ISC_SOCKET_USE_POLLWATCH at build time to enable this workaround. [RT #18870] 2488. [func] Added a tool, dnssec-dsfromkey, to generate DS records from keyset and .key files. [RT #18694] 2487. [bug] Give TCP connections longer to complete. [RT #18675] 2486. [func] The default locations for named.pid and lwresd.pid are now /var/run/named/named.pid and /var/run/lwresd/lwresd.pid respectively. This allows the owner of the containing directory to be set, for "named -u" support, and allows there to be a permanent symbolic link in the path, for "named -t" support. [RT #18306] 2485. [bug] Change update's the handling of obscured RRSIG records. Not all orphaned DS records were being removed. [RT #18828] 2484. [bug] It was possible to trigger a REQUIRE failure when adding NSEC3 proofs to the response in query_addwildcardproof(). [RT #18828] 2483. [port] win32: chroot() is not supported. [RT #18805] 2482. [port] libxml2: support versions 2.7.* in addition to 2.6.*. [RT #18806] --- 9.6.0b1 released --- 2481. [bug] rbtdb.c:matchparams() failed to handle NSEC3 chain collisions. [RT #18812] 2480. [bug] named could fail to emit all the required NSEC3 records. [RT #18812] 2479. [bug] xfrout:covers was not properly initialized. [RT #18801] 2478. [bug] 'addresses' could be used uninitialized in configure_forward(). [RT #18800] 2477. [bug] dig: the global option to print the command line is +cmd not print_cmd. Update the output to reflect this. [RT #17008] 2476. [doc] ARM: improve documentation for max-journal-size and ixfr-from-differences. [RT #15909] [RT #18541] 2475. [bug] LRU cache cleanup under overmem condition could purge particular entries more aggressively. [RT #17628] 2474. [bug] ACL structures could be allocated with insufficient space, causing an array overrun. [RT #18765] 2473. [port] linux: raise the limit on open files to the possible maximum value before spawning threads; 'files' specified in named.conf doesn't seem to work with threads as expected. [RT #18784] 2472. [port] linux: check the number of available cpu's before calling chroot as it depends on "/proc". [RT #16923] 2471. [bug] named-checkzone was not reporting missing mandatory glue when sibling checks were disabled. [RT #18768] 2470. [bug] Elements of the isc_radix_node_t could be incorrectly overwritten. [RT #18719] 2469. [port] solaris: Work around Solaris's select() limitations. [RT #18769] 2468. [bug] Resolver could try unreachable servers multiple times. [RT #18739] 2467. [bug] Failure of fcntl(F_DUPFD) wasn't logged. [RT #18740] 2466. [doc] ARM: explain max-cache-ttl 0 SERVFAIL issue. [RT #18302] 2465. [bug] Adb's handling of lame addresses was different for IPv4 and IPv6. [RT #18738] 2464. [port] linux: check that a capability is present before trying to set it. [RT #18135] 2463. [port] linux: POSIX doesn't include the IPv6 Advanced Socket API and glibc hides parts of the IPv6 Advanced Socket API as a result. This is stupid as it breaks how the two halves (Basic and Advanced) of the IPv6 Socket API were designed to be used but we have to live with it. Define _GNU_SOURCE to pull in the IPv6 Advanced Socket API. [RT #18388] 2462. [doc] Document -m (enable memory usage debugging) option for dig. [RT #18757] 2461. [port] sunos: Change #2363 was not complete. [RT #17513] --- 9.6.0a1 released --- 2460. [bug] Don't call dns_db_getnsec3parameters() on the cache. [RT #18697] 2459. [contrib] Import dnssec-zkt to contrib/zkt. [RT #18448] 2458. [doc] ARM: update and correction for max-cache-size. [RT #18294] 2457. [tuning] max-cache-size is reverted to 0, the previous default. It should be safe because expired cache entries are also purged. [RT #18684] 2456. [bug] In ACLs, ::/0 and 0.0.0.0/0 would both match any address, regardless of family. They now correctly distinguish IPv4 from IPv6. [RT #18559] 2455. [bug] Stop metadata being transferred via axfr/ixfr. [RT #18639] 2454. [func] nsupdate: you can now set a default ttl. [RT #18317] 2453. [bug] Remove NULL pointer dereference in dns_journal_print(). [RT #18316] 2452. [func] Improve bin/test/journalprint. [RT #18316] 2451. [port] solaris: handle runtime linking better. [RT #18356] 2450. [doc] Fix lwresd docbook problem for manual page. [RT #18672] 2449. [placeholder] 2448. [func] Add NSEC3 support. [RT #15452] 2447. [cleanup] libbind has been split out as a separate product. 2446. [func] Add a new log message about build options on startup. A new command-line option '-V' for named is also provided to show this information. [RT #18645] 2445. [doc] ARM out-of-date on empty reverse zones (list includes RFC1918 address, but these are not yet compiled in). [RT #18578] 2444. [port] Linux, FreeBSD, AIX: Turn off path mtu discovery (clear DF) for UDP responses and requests. 2443. [bug] win32: UDP connect() would not generate an event, and so connected UDP sockets would never clean up. Fix this by doing an immediate WSAConnect() rather than an io completion port type for UDP. 2442. [bug] A lock could be destroyed twice. [RT #18626] 2441. [bug] isc_radix_insert() could copy radix tree nodes incompletely. [RT #18573] 2440. [bug] named-checkconf used an incorrect test to determine if an ACL was set to none. 2439. [bug] Potential NULL dereference in dns_acl_isanyornone(). [RT #18559] 2438. [bug] Timeouts could be logged incorrectly under win32. 2437. [bug] Sockets could be closed too early, leading to inconsistent states in the socket module. [RT #18298] 2436. [security] win32: UDP client handler can be shutdown. [RT #18576] 2435. [bug] Fixed an ACL memory leak affecting win32. 2434. [bug] Fixed a minor error-reporting bug in lib/isc/win32/socket.c. 2433. [tuning] Set initial timeout to 800ms. 2432. [bug] More Windows socket handling improvements. Stop using I/O events and use IO Completion Ports throughout. Rewrite the receive path logic to make it easier to support multiple simultaneous requesters in the future. Add stricter consistency checking as a compile-time option (define ISC_SOCKET_CONSISTENCY_CHECKS; defaults to off). 2431. [bug] Acl processing could leak memory. [RT #18323] 2430. [bug] win32: isc_interval_set() could round down to zero if the input was less than NS_INTERVAL nanoseconds. Round up instead. [RT #18549] 2429. [doc] nsupdate should be in section 1 of the man pages. [RT #18283] 2428. [bug] dns_iptable_merge() mishandled merges of negative tables. [RT #18409] 2427. [func] Treat DNSKEY queries as if "minimal-response yes;" was set. [RT #18528] 2426. [bug] libbind: inet_net_pton() can sometimes return the wrong value if excessively large net masks are supplied. [RT #18512] 2425. [bug] named didn't detect unavailable query source addresses at load time. [RT #18536] 2424. [port] configure now probes for a working epoll implementation. Allow the use of kqueue, epoll and /dev/poll to be selected at compile time. [RT #18277] 2423. [security] Randomize server selection on queries, so as to make forgery a little more difficult. Instead of always preferring the server with the lowest RTT, pick a server with RTT within the same 128 millisecond band. [RT #18441] 2422. [bug] Handle the special return value of a empty node as if it was a NXRRSET in the validator. [RT #18447] 2421. [func] Add new command line option '-S' for named to specify the max number of sockets. [RT #18493] Use caution: this option may not work for some operating systems without rebuilding named. 2420. [bug] Windows socket handling cleanup. Let the io completion event send out canceled read/write done events, which keeps us from writing to memory we no longer have ownership of. Add debugging socket_log() function. Rework TCP socket handling to not leak sockets. 2419. [cleanup] Document that isc_socket_create() and isc_socket_open() should not be used for isc_sockettype_fdwatch sockets. [RT #18521] 2418. [bug] AXFR request on a DLZ could trigger a REQUIRE failure [RT #18430] 2417. [bug] Connecting UDP sockets for outgoing queries could unexpectedly fail with an 'address already in use' error. [RT #18411] 2416. [func] Log file descriptors that cause exceeding the internal maximum. [RT #18460] 2415. [bug] 'rndc dumpdb' could trigger various assertion failures in rbtdb.c. [RT #18455] 2414. [bug] A masterdump context held the database lock too long, causing various troubles such as dead lock and recursive lock acquisition. [RT #18311, #18456] 2413. [bug] Fixed an unreachable code path in socket.c. [RT #18442] 2412. [bug] win32: address a resource leak. [RT #18374] 2411. [bug] Allow using a larger number of sockets than FD_SETSIZE for select(). To enable this, set ISC_SOCKET_MAXSOCKETS at compilation time. [RT #18433] Note: with changes #2469 and #2421 above, there is no need to tweak ISC_SOCKET_MAXSOCKETS at compilation time any more. 2410. [bug] Correctly delete m_versionInfo. [RT #18432] 2409. [bug] Only log that we disabled EDNS processing if we were subsequently successful. [RT #18029] 2408. [bug] A duplicate TCP dispatch event could be sent, which could then trigger an assertion failure in resquery_response(). [RT #18275] 2407. [port] hpux: test for sys/dyntune.h. [RT #18421] 2406. [placeholder] 2405. [cleanup] The default value for dnssec-validation was changed to "yes" in 9.5.0-P1 and all subsequent releases; this was inadvertently omitted from CHANGES at the time. 2404. [port] hpux: files unlimited support. 2403. [bug] TSIG context leak. [RT #18341] 2402. [port] Support Solaris 2.11 and over. [RT #18362] 2401. [bug] Expect to get E[MN]FILE errno internal_accept() (from accept() or fcntl() system calls). [RT #18358] 2400. [bug] Log if kqueue()/epoll_create()/open(/dev/poll) fails. [RT #18297] 2399. [placeholder] 2398. [bug] Improve file descriptor management. New, temporary, named.conf option reserved-sockets, default 512. [RT #18344] 2397. [bug] gssapi_functions had too many elements. [RT #18355] 2396. [bug] Don't set SO_REUSEADDR for randomized ports. [RT #18336] 2395. [port] Avoid warning and no effect from "files unlimited" on Linux when running as root. [RT #18335] 2394. [bug] Default configuration options set the limit for open files to 'unlimited' as described in the documentation. [RT #18331] 2393. [bug] nested acls containing keys could trigger an assertion in acl.c. [RT #18166] 2392. [bug] remove 'grep -q' from acl test script, some platforms don't support it. [RT #18253] 2391. [port] hpux: cover additional recvmsg() error codes. [RT #18301] 2390. [bug] dispatch.c could make a false warning on 'odd socket'. [RT #18301]. 2389. [bug] Move the "working directory writable" check to after the ns_os_changeuser() call. [RT #18326] 2388. [bug] Avoid using tables for layout purposes in statistics XSL [RT #18159]. 2387. [bug] Silence compiler warnings in lib/isc/radix.c. [RT #18147] [RT #18258] 2386. [func] Add warning about too small 'open files' limit. [RT #18269] 2385. [bug] A condition variable in socket.c could leak in rare error handling [RT #17968]. 2384. [security] Fully randomize UDP query ports to improve forgery resilience. [RT #17949, #18098] 2383. [bug] named could double queries when they resulted in SERVFAIL due to overkilling EDNS0 failure detection. [RT #18182] 2382. [doc] Add descriptions of DHCID, IPSECKEY, SPF and SSHFP to ARM. 2381. [port] dlz/mysql: support multiple install layouts for mysql. /include/{,mysql/}mysql.h and /lib/{,mysql/}. [RT #18152] 2380. [bug] dns_view_find() was not returning NXDOMAIN/NXRRSET proofs which, in turn, caused validation failures for insecure zones immediately below a secure zone the server was authoritative for. [RT #18112] 2379. [contrib] queryperf/gen-data-queryperf.py: removed redundant TLDs and supported RRs with TTLs [RT #17972] 2378. [bug] gssapi_functions{} had a redundant member in BIND 9.5. [RT #18169] 2377. [bug] Address race condition in dnssec-signzone. [RT #18142] 2376. [bug] Change #2144 was not complete. 2375. [placeholder] 2374. [bug] "blackhole" ACLs could cause named to segfault due to some uninitialized memory. [RT #18095] 2373. [bug] Default values of zone ACLs were re-parsed each time a new zone was configured, causing an overconsumption of memory. [RT #18092] 2372. [bug] Fixed incorrect TAG_HMACSHA256_BITS value [RT #18047] 2371. [doc] Add +nsid option to dig man page. [RT #18039] 2370. [bug] "rndc freeze" could trigger an assertion in named when called on a nonexistent zone. [RT #18050] 2369. [bug] libbind: Array bounds overrun on read in bitncmp(). [RT #18054] 2368. [port] Linux: use libcap for capability management if possible. [RT #18026] 2367. [bug] Improve counting of dns_resstatscounter_retry [RT #18030] 2366. [bug] Adb shutdown race. [RT #18021] 2365. [bug] Fix a bug that caused dns_acl_isany() to return spurious results. [RT #18000] 2364. [bug] named could trigger a assertion when serving a malformed signed zone. [RT #17828] 2363. [port] sunos: pre-set "lt_cv_sys_max_cmd_len=4096;". [RT #17513] 2362. [cleanup] Make "rrset-order fixed" a compile-time option. settable by "./configure --enable-fixed-rrset". Disabled by default. [RT #17977] 2361. [bug] "recursion" statistics counter could be counted multiple times for a single query. [RT #17990] 2360. [bug] Fix a condition where we release a database version (which may acquire a lock) while holding the lock. 2359. [bug] Fix NSID bug. [RT #17942] 2358. [doc] Update host's default query description. [RT #17934] 2357. [port] Don't use OpenSSL's engine support in versions before OpenSSL 0.9.7f. [RT #17922] 2356. [bug] Built in mutex profiler was not scalable enough. [RT #17436] 2355. [func] Extend the number statistics counters available. [RT #17590] 2354. [bug] Failed to initialize some rdatasetheader_t elements. [RT #17927] 2353. [func] Add support for Name Server ID (RFC 5001). 'dig +nsid' requests NSID from server. 'request-nsid yes;' causes recursive server to send NSID requests to upstream servers. Server responds to NSID requests with the string configured by 'server-id' option. [RT #17091] 2352. [bug] Various GSS_API fixups. [RT #17729] 2351. [bug] convertxsl.pl generated very long lines. [RT #17906] 2350. [port] win32: IPv6 support. [RT #17797] 2349. [func] Provide incremental re-signing support for secure dynamic zones. [RT #1091] 2348. [func] Use the EVP interface to OpenSSL. Add PKCS#11 support. Documentation is in the new README.pkcs11 file. New tool, dnssec-keyfromlabel, which takes the label of a key pair in a HSM and constructs a DNS key pair for use by named and dnssec-signzone. [RT #16844] 2347. [bug] Delete now traverses the RB tree in the canonical order. [RT #17451] 2346. [func] Memory statistics now cover all active memory contexts in increased detail. [RT #17580] 2345. [bug] named-checkconf failed to detect when forwarders were set at both the options/view level and in a root zone. [RT #17671] 2344. [bug] Improve "logging{ file ...; };" documentation. [RT #17888] 2343. [bug] (Seemingly) duplicate IPv6 entries could be created in ADB. [RT #17837] 2342. [func] Use getifaddrs() if available under Linux. [RT #17224] 2341. [bug] libbind: add missing -I../include for off source tree builds. [RT #17606] 2340. [port] openbsd: interface configuration. [RT #17700] 2339. [port] tru64: support for libbind. [RT #17589] 2338. [bug] check_ds() could be called with a non DS rdataset. [RT #17598] 2337. [bug] BUILD_LDFLAGS was not being correctly set. [RT #17614] 2336. [func] If "named -6" is specified then listen on all IPv6 interfaces if there are not listen-on-v6 clauses in named.conf. [RT #17581] 2335. [port] sunos: libbind and *printf() support for long long. [RT #17513] 2334. [bug] Bad REQUIRES in fromstruct_in_naptr(), off by one bug in fromstruct_txt(). [RT #17609] 2333. [bug] Fix off by one error in isc_time_nowplusinterval(). [RT #17608] 2332. [contrib] query-loc-0.4.0. [RT #17602] 2331. [bug] Failure to regenerate any signatures was not being reported nor being past back to the UPDATE client. [RT #17570] 2330. [bug] Remove potential race condition when handling over memory events. [RT #17572] WARNING: API CHANGE: over memory callback function now needs to call isc_mem_waterack(). See for details. 2329. [bug] Clearer help text for dig's '-x' and '-i' options. 2328. [maint] Add AAAA addresses for A.ROOT-SERVERS.NET, F.ROOT-SERVERS.NET, H.ROOT-SERVERS.NET, J.ROOT-SERVERS.NET, K.ROOT-SERVERS.NET and M.ROOT-SERVERS.NET. 2327. [bug] It was possible to dereference a NULL pointer in rbtdb.c. Implement dead node processing in zones as we do for caches. [RT #17312] 2326. [bug] It was possible to trigger a INSIST in the acache processing. 2325. [port] Linux: use capset() function if available. [RT #17557] 2324. [bug] Fix IPv6 matching against "any;". [RT #17533] 2323. [port] tru64: namespace clash. [RT #17547] 2322. [port] MacOS: work around the limitation of setrlimit() for RLIMIT_NOFILE. [RT #17526] 2321. [placeholder] 2320. [func] Make statistics counters thread-safe for platforms that support certain atomic operations. [RT #17466] 2319. [bug] Silence Coverity warnings in lib/dns/rdata/in_1/apl_42.c. [RT #17469] 2318. [port] sunos fixes for libbind. [RT #17514] 2317. [bug] "make distclean" removed bind9.xsl.h. [RT #17518] 2316. [port] Missing #include in lib/dns/gssapictx.c. [RT #17513] 2315. [bug] Used incorrect address family for mapped IPv4 addresses in acl.c. [RT #17519] 2314. [bug] Uninitialized memory use on error path in bin/named/lwdnoop.c. [RT #17476] 2313. [cleanup] Silence Coverity warnings. Handle private stacks. [RT #17447] [RT #17478] 2312. [cleanup] Silence Coverity warning in lib/isc/unix/socket.c. [RT #17458] 2311. [bug] IPv6 addresses could match IPv4 ACL entries and vice versa. [RT #17462] 2310. [bug] dig, host, nslookup: flush stdout before emitting debug/fatal messages. [RT #17501] 2309. [cleanup] Fix Coverity warnings in lib/dns/acl.c and iptable.c. [RT #17455] 2308. [cleanup] Silence Coverity warning in bin/named/controlconf.c. [RT #17495] 2307. [bug] Remove infinite loop from lib/dns/sdb.c. [RT #17496] 2306. [bug] Remove potential race from lib/dns/resolver.c. [RT #17470] 2305. [security] inet_network() buffer overflow. CVE-2008-0122. 2304. [bug] Check returns from all dns_rdata_tostruct() calls. [RT #17460] 2303. [bug] Remove unnecessary code from bin/named/lwdgnba.c. [RT #17471] 2302. [bug] Fix memset() calls in lib/tests/t_api.c. [RT #17472] 2301. [bug] Remove resource leak and fix error messages in bin/tests/system/lwresd/lwtest.c. [RT #17474] 2300. [bug] Fixed failure to close open file in bin/tests/names/t_names.c. [RT #17473] 2299. [bug] Remove unnecessary NULL check in bin/nsupdate/nsupdate.c. [RT #17475] 2298. [bug] isc_mutex_lock() failure not caught in bin/tests/timers/t_timers.c. [RT #17468] 2297. [bug] isc_entropy_createfilesource() failure not caught in bin/tests/dst/t_dst.c. [RT #17467] 2296. [port] Allow docbook stylesheet location to be specified to configure. [RT #17457] 2295. [bug] Silence static overrun error in bin/named/lwaddr.c. [RT #17459] 2294. [func] Allow the experimental statistics channels to have multiple connections and ACL. Note: the stats-server and stats-server-v6 options available in the previous beta releases are replaced with the generic statistics-channels statement. 2293. [func] Add ACL regression test. [RT #17375] 2292. [bug] Log if the working directory is not writable. [RT #17312] 2291. [bug] PR_SET_DUMPABLE may be set too late. Also report failure to set PR_SET_DUMPABLE. [RT #17312] 2290. [bug] Let AD in the query signal that the client wants AD set in the response. [RT #17301] 2289. [func] named-checkzone now reports the out-of-zone CNAME found. [RT #17309] 2288. [port] win32: mark service as running when we have finished loading. [RT #17441] 2287. [bug] Use 'volatile' if the compiler supports it. [RT #17413] 2286. [func] Allow a TCP connection to be used as a weak authentication method for reverse zones. New update-policy methods tcp-self and 6to4-self. [RT #17378] 2285. [func] Test framework for client memory context management. [RT #17377] 2284. [bug] Memory leak in UPDATE prerequisite processing. [RT #17377] 2283. [bug] TSIG keys were not attaching to the memory context. TSIG keys should use the rings memory context rather than the clients memory context. [RT #17377] 2282. [bug] Acl code fixups. [RT #17346] [RT #17374] 2281. [bug] Attempts to use undefined acls were not being logged. [RT #17307] 2280. [func] Allow the experimental http server to be reached over IPv6 as well as IPv4. [RT #17332] 2279. [bug] Use setsockopt(SO_NOSIGPIPE), when available, to protect applications from receiving spurious SIGPIPE signals when using the resolver. 2278. [bug] win32: handle the case where Windows returns no search list or DNS suffix. [RT #17354] 2277. [bug] Empty zone names were not correctly being caught at in the post parse checks. [RT #17357] 2276. [bug] Install . [RT #17359] 2275. [func] Add support to dig to perform IXFR queries over UDP. [RT #17235] 2274. [func] Log zone transfer statistics. [RT #17336] 2273. [bug] Adjust log level to WARNING when saving inconsistent stub/slave master and journal files. [RT #17279] 2272. [bug] Handle illegal dnssec-lookaside trust-anchor names. [RT #17262] 2271. [bug] Fix a memory leak in http server code [RT #17100] 2270. [bug] dns_db_closeversion() version->writer could be reset before it is tested. [RT #17290] 2269. [contrib] dbus memory leaks and missing va_end calls. [RT #17232] 2268. [bug] 0.IN-ADDR.ARPA was missing from the empty zones list. --- 9.5.0b1 released --- 2267. [bug] Radix tree node_num value could be set incorrectly, causing positive ACL matches to look like negative ones. [RT #17311] 2266. [bug] client.c:get_clientmctx() returned the same mctx once the pool of mctx's was filled. [RT #17218] 2265. [bug] Test that the memory context's basic_table is non NULL before freeing. [RT #17265] 2264. [bug] Server prefix length was being ignored. [RT #17308] 2263. [bug] "named-checkconf -z" failed to set default value for "check-integrity". [RT #17306] 2262. [bug] Error status from all but the last view could be lost. [RT #17292] 2261. [bug] Fix memory leak with "any" and "none" ACLs [RT #17272] 2260. [bug] Reported wrong clients-per-query when increasing the value. [RT #17236] 2259. [placeholder] --- 9.5.0a7 released --- 2258. [bug] Fallback from IXFR/TSIG to SOA/AXFR/TSIG broken. [RT #17241] 2257. [bug] win32: Use the full path to vcredist_x86.exe when calling it. [RT #17222] 2256. [bug] win32: Correctly register the installation location of bindevt.dll. [RT #17159] 2255. [maint] L.ROOT-SERVERS.NET is now 199.7.83.42. 2254. [bug] timer.c:dispatch() failed to lock timer->lock when reading timer->idle allowing it to see intermediate values as timer->idle was reset by isc_timer_touch(). [RT #17243] 2253. [func] "max-cache-size" defaults to 32M. "max-acache-size" defaults to 16M. 2252. [bug] Fixed errors in sortlist code [RT #17216] 2251. [placeholder] 2250. [func] New flag 'memstatistics' to state whether the memory statistics file should be written or not. Additionally named's -m option will cause the statistics file to be written. [RT #17113] 2249. [bug] Only set Authentic Data bit if client requested DNSSEC, per RFC 3655 [RT #17175] 2248. [cleanup] Fix several errors reported by Coverity. [RT #17160] 2247. [doc] Sort doc/misc/options. [RT #17067] 2246. [bug] Make the startup of test servers (ans.pl) more robust. [RT #17147] 2245. [bug] Validating lack of DS records at trust anchors wasn't working. [RT #17151] 2244. [func] Allow the check of nameserver names against the SOA MNAME field to be disabled by specifying 'notify-to-soa yes;'. [RT #17073] 2243. [func] Configuration files without a newline at the end now parse without error. [RT #17120] 2242. [bug] nsupdate: GSS-TSIG support using the Heimdal Kerberos library could require a source of random data. [RT #17127] 2241. [func] nsupdate: add a interactive 'help' command. [RT #17099] 2240. [bug] Cleanup nsupdates GSS-TSIG support. Convert a number of INSIST()s into plain fatal() errors which report the triggering result code. The 'key' command wasn't disabling GSS-TSIG. [RT #17099] 2239. [func] Ship a pre built bin/named/bind9.xsl.h. [RT #17114] 2238. [bug] It was possible to trigger a REQUIRE when a validation was canceled. [RT #17106] 2237. [bug] libbind: res_init() was not thread aware. [RT #17123] 2236. [bug] dnssec-signzone failed to preserve the case of of wildcard owner names. [RT #17085] 2235. [bug] was not being installed. [RT #17135] 2234. [port] Correct some compiler warnings on SCO OSr5 [RT #17134] 2233. [func] Add support for O(1) ACL processing, based on radix tree code originally written by Kevin Brintnall. [RT #16288] 2232. [bug] dns_adb_findaddrinfo() could fail and return ISC_R_SUCCESS. [RT #17137] 2231. [bug] Building dlzbdb (contrib/dlz/bin/dlzbdb) was broken. [RT #17088] 2230. [bug] We could INSIST reading a corrupted journal. [RT #17132] 2229. [bug] Null pointer dereference on query pool creation failure. [RT #17133] 2228. [contrib] contrib: Change 2188 was incomplete. 2227. [cleanup] Tidied up the FAQ. [RT #17121] 2226. [placeholder] 2225. [bug] More support for systems with no IPv4 addresses. [RT #17111] 2224. [bug] Defer journal compaction if a xfrin is in progress. [RT #17119] 2223. [bug] Make a new journal when compacting. [RT #17119] 2222. [func] named-checkconf now checks server key references. [RT #17097] 2221. [bug] Set the event result code to reflect the actual record turned to caller when a cache update is rejected due to a more credible answer existing. [RT #17017] 2220. [bug] win32: Address a race condition in final shutdown of the Windows socket code. [RT #17028] 2219. [bug] Apply zone consistency checks to additions, not removals, when updating. [RT #17049] 2218. [bug] Remove unnecessary REQUIRE from dns_validator_create(). [RT #16976] 2217. [func] Adjust update log levels. [RT #17092] 2216. [cleanup] Fix a number of errors reported by Coverity. [RT #17094] 2215. [bug] Bad REQUIRE check isc_hmacsha1_verify(). [RT #17094] 2214. [bug] Deregister OpenSSL lock callback when cleaning up. Reorder OpenSSL cleanup so that RAND_cleanup() is called before the locks are destroyed. [RT #17098] 2213. [bug] SIG0 diagnostic failure messages were looking at the wrong status code. [RT #17101] 2212. [func] 'host -m' now causes memory statistics and active memory to be printed at exit. [RT 17028] 2211. [func] Update "dynamic update temporarily disabled" message. [RT #17065] 2210. [bug] Deleting class specific records via UPDATE could fail. [RT #17074] 2209. [port] osx: linking against user supplied static OpenSSL libraries failed as the system ones were still being found. [RT #17078] 2208. [port] win32: make sure both build methods produce the same output. [RT #17058] 2207. [port] Some implementations of getaddrinfo() fail to set ai_canonname correctly. [RT #17061] --- 9.5.0a6 released --- 2206. [security] "allow-query-cache" and "allow-recursion" now cross inherit from each other. If allow-query-cache is not set in named.conf then allow-recursion is used if set, otherwise allow-query is used if set, otherwise the default (localnets; localhost;) is used. If allow-recursion is not set in named.conf then allow-query-cache is used if set, otherwise allow-query is used if set, otherwise the default (localnets; localhost;) is used. [RT #16987] 2205. [bug] libbind: change #2119 broke thread support. [RT #16982] 2204. [bug] "rndc flushname name unknown-view" caused named to crash. [RT #16984] 2203. [security] Query id generation was cryptographically weak. [RT # 16915] 2202. [security] The default acls for allow-query-cache and allow-recursion were not being applied. [RT #16960] 2201. [bug] The build failed in a separate object directory. [RT #16943] 2200. [bug] The search for cached NSEC records was stopping to early leading to excessive DLV queries. [RT #16930] 2199. [bug] win32: don't call WSAStartup() while loading dlls. [RT #16911] 2198. [bug] win32: RegCloseKey() could be called when RegOpenKeyEx() failed. [RT #16911] 2197. [bug] Add INSIST to catch negative responses which are not setting the event result code appropriately. [RT #16909] 2196. [port] win32: yield processor while waiting for once to to complete. [RT #16958] 2195. [func] dnssec-keygen now defaults to nametype "ZONE" when generating DNSKEYs. [RT #16954] 2194. [bug] Close journal before calling 'done' in xfrin.c. --- 9.5.0a5 released --- 2193. [port] win32: BINDInstall.exe is now linked statically. [RT #16906] 2192. [port] win32: use vcredist_x86.exe to install Visual Studio's redistributable dlls if building with Visual Stdio 2005 or later. 2191. [func] named-checkzone now allows dumping to stdout (-). named-checkconf now has -h for help. named-checkzone now has -h for help. rndc now has -h for help. Better handling of '-?' for usage summaries. [RT #16707] 2190. [func] Make fallback to plain DNS from EDNS due to timeouts more visible. New logging category "edns-disabled". [RT #16871] 2189. [bug] Handle socket() returning EINTR. [RT #15949] 2188. [contrib] queryperf: autoconf changes to make the search for libresolv or libbind more robust. [RT #16299] 2187. [bug] query_addds(), query_addwildcardproof() and query_addnxrrsetnsec() should take a version argument. [RT #16368] 2186. [port] cygwin: libbind: check for struct sockaddr_storage independently of IPv6. [RT #16482] 2185. [port] sunos: libbind: check for ssize_t, memmove() and memchr(). [RT #16463] 2184. [bug] bind9.xsl.h didn't build out of the source tree. [RT #16830] 2183. [bug] dnssec-signzone didn't handle offline private keys well. [RT #16832] 2182. [bug] dns_dispatch_createtcp() and dispatch_createudp() could return ISC_R_SUCCESS when they ran out of memory. [RT #16365] 2181. [port] sunos: libbind: add paths.h from BIND 8. [RT #16462] 2180. [cleanup] Remove bit test from 'compress_test' as they are no longer needed. [RT #16497] 2179. [func] 'rndc command zone' will now find 'zone' if it is unique to all the views. [RT #16821] 2178. [bug] 'rndc reload' of a slave or stub zone resulted in a reference leak. [RT #16867] 2177. [bug] Array bounds overrun on read (rcodetext) at debug level 10+. [RT #16798] 2176. [contrib] dbus update to handle race condition during initialization (Bugzilla 235809). [RT #16842] 2175. [bug] win32: windows broadcast condition variable support was broken. [RT #16592] 2174. [bug] I/O errors should always be fatal when reading master files. [RT #16825] 2173. [port] win32: When compiling with MSVS 2005 SP1 we also need to ship Microsoft.VC80.MFCLOC. --- 9.5.0a4 released --- 2172. [bug] query_addsoa() was being called with a non zone db. [RT #16834] 2171. [bug] Handle breaks in DNSSEC trust chains where the parent servers are not DS aware (DS queries to the parent return a referral to the child). 2170. [func] Add acache processing to test suite. [RT #16711] 2169. [bug] host, nslookup: when reporting NXDOMAIN report the given name and not the last name searched for. [RT #16763] 2168. [bug] nsupdate: in non-interactive mode treat syntax errors as fatal errors. [RT #16785] 2167. [bug] When re-using a automatic zone named failed to attach it to the new view. [RT #16786] --- 9.5.0a3 released --- 2166. [bug] When running in batch mode, dig could misinterpret a server address as a name to be looked up, causing unexpected output. [RT #16743] 2165. [func] Allow the destination address of a query to determine if we will answer the query or recurse. allow-query-on, allow-recursion-on and allow-query-cache-on. [RT #16291] 2164. [bug] The code to determine how named-checkzone / named-compilezone was called failed under windows. [RT #16764] 2163. [bug] If only one of query-source and query-source-v6 specified a port the query pools code broke (change 2129). [RT #16768] 2162. [func] Allow "rrset-order fixed" to be disabled at compile time. [RT #16665] 2161. [bug] Fix which log messages are emitted for 'rndc flush'. [RT #16698] 2160. [bug] libisc wasn't handling NULL ifa_addr pointers returned from getifaddrs(). [RT #16708] --- 9.5.0a2 released --- 2159. [bug] Array bounds overrun in acache processing. [RT #16710] 2158. [bug] ns_client_isself() failed to initialize key leading to a REQUIRE failure. [RT #16688] 2157. [func] dns_db_transfernode() created. [RT #16685] 2156. [bug] Fix node reference leaks in lookup.c:lookup_find(), resolver.c:validated() and resolver.c:cache_name(). Fix a memory leak in rbtdb.c:free_noqname(). Make lookup.c:lookup_find() robust against event leaks. [RT #16685] 2155. [contrib] SQLite sdb module from jaboydjr@netwalk.com. [RT #16694] 2154. [func] Scoped (e.g. IPv6 link-local) addresses may now be matched in acls by omitting the scope. [RT #16599] 2153. [bug] nsupdate could leak memory. [RT #16691] 2152. [cleanup] Use sizeof(buf) instead of fixed number in dighost.c:get_trusted_key(). [RT #16678] 2151. [bug] Missing newline in usage message for journalprint. [RT #16679] 2150. [bug] 'rrset-order cyclic' uniformly distribute the starting point for the first response for a given RRset. [RT #16655] 2149. [bug] isc_mem_checkdestroyed() failed to abort on if there were still active memory contexts. [RT #16672] 2148. [func] Add positive logging for rndc commands. [RT #14623] 2147. [bug] libbind: remove potential buffer overflow from hmac_link.c. [RT #16437] 2146. [cleanup] Silence Linux's spurious "obsolete setsockopt SO_BSDCOMPAT" message. [RT #16641] 2145. [bug] Check DS/DLV digest lengths for known digests. [RT #16622] 2144. [cleanup] Suppress logging of SERVFAIL from forwarders. [RT #16619] 2143. [bug] We failed to restart the IPv6 client when the kernel failed to return the destination the packet was sent to. [RT #16613] 2142. [bug] Handle master files with a modification time that matches the epoch. [RT #16612] 2141. [bug] dig/host should not be setting IDN_ASCCHECK (IDN equivalent of LDH checks). [RT #16609] 2140. [bug] libbind: missing unlock on pthread_key_create() failures. [RT #16654] 2139. [bug] dns_view_find() was being called with wrong type in adb.c. [RT #16670] 2138. [bug] Lock order reversal in resolver.c. [RT #16653] 2137. [port] Mips little endian and/or mips 64 bit are now supported for atomic operations. [RT #16648] 2136. [bug] nslookup/host looped if there was no search list and the host didn't exist. [RT #16657] 2135. [bug] Uninitialized rdataset in sdlz.c. [RT #16656] 2134. [func] Additional statistics support. [RT #16666] 2133. [port] powerpc: Support both IBM and MacOS Power PC assembler syntaxes. [RT #16647] 2132. [bug] Missing unlock on out of memory in dns_dispatchmgr_setudp(). 2131. [contrib] dlz/mysql: AXFR was broken. [RT #16630] 2130. [func] Log if CD or DO were set. [RT #16640] 2129. [func] Provide a pool of UDP sockets for queries to be made over. See use-queryport-pool, queryport-pool-ports and queryport-pool-updateinterval. [RT #16415] 2128. [doc] xsltproc --nonet, update DTD versions. [RT #16635] 2127. [port] Improved OpenSSL 0.9.8 support. [RT #16563] 2126. [security] Serialize validation of type ANY responses. [RT #16555] 2125. [bug] dns_zone_getzeronosoattl() REQUIRE failure if DLZ was defined. [RT #16574] 2124. [security] It was possible to dereference a freed fetch context. [RT #16584] --- 9.5.0a1 released --- 2123. [func] Use Doxygen to generate internal documentation. [RT #11398] 2122. [func] Experimental http server and statistics support for named via xml. 2121. [func] Add a 10 slot dead masters cache (LRU) with a 600 second timeout. [RT #16553] 2120. [doc] Fix markup on nsupdate man page. [RT #16556] 2119. [compat] libbind: allow res_init() to succeed enough to return the default domain even if it was unable to allocate memory. 2118. [bug] Handle response with long chains of domain name compression pointers which point to other compression pointers. [RT #16427] 2117. [bug] DNSSEC fixes: named could fail to cache NSEC records which could lead to validation failures. named didn't handle negative DS responses that were in the process of being validated. Check CNAME bit before accepting NODATA proof. To be able to ignore a child NSEC there must be SOA (and NS) set in the bitmap. [RT #16399] 2116. [bug] 'rndc reload' could cause the cache to continually be cleaned. [RT #16401] 2115. [bug] 'rndc reconfig' could trigger a INSIST if the number of masters for a zone was reduced. [RT #16444] 2114. [bug] dig/host/nslookup: searches for names with multiple labels were failing. [RT #16447] 2113. [bug] nsupdate: if a zone is specified it should be used for server discover. [RT #16455] 2112. [security] Warn if weak RSA exponent is used. [RT #16460] 2111. [bug] Fix a number of errors reported by Coverity. [RT #16507] 2110. [bug] "minimal-responses yes;" interacted badly with BIND 8 priming queries. [RT #16491] 2109. [port] libbind: silence aix 5.3 compiler warnings. [RT #16502] 2108. [func] DHCID support. [RT #16456] 2107. [bug] dighost.c: more cleanup of buffers. [RT #16499] 2106. [func] 'rndc status' now reports named's version. [RT #16426] 2105. [func] GSS-TSIG support (RFC 3645). 2104. [port] Fix Solaris SMF error message. 2103. [port] Add /usr/sfw to list of locations for OpenSSL under Solaris. 2102. [port] Silence Solaris 10 warnings. 2101. [bug] OpenSSL version checks were not quite right. [RT #16476] 2100. [port] win32: copy libeay32.dll to Build\Debug. Copy Debug\named-checkzone to Debug\named-compilezone. 2099. [port] win32: more manifest issues. 2098. [bug] Race in rbtdb.c:no_references(), which occasionally triggered an INSIST failure about the node lock reference. [RT #16411] 2097. [bug] named could reference a destroyed memory context after being reloaded / reconfigured. [RT #16428] 2096. [bug] libbind: handle applications that fail to detect res_init() failures better. 2095. [port] libbind: alway prototype inet_cidr_ntop_ipv6() and net_cidr_ntop_ipv6(). [RT #16388] 2094. [contrib] Update named-bootconf. [RT #16404] 2093. [bug] named-checkzone -s was broken. 2092. [bug] win32: dig, host, nslookup. Use registry config if resolv.conf does not exist or no nameservers listed. [RT #15877] 2091. [port] dighost.c: race condition on cleanup. [RT #16417] 2090. [port] win32: Visual C++ 2005 command line manifest support. [RT #16417] 2089. [security] Raise the minimum safe OpenSSL versions to OpenSSL 0.9.7l and OpenSSL 0.9.8d. Versions prior to these have known security flaws which are (potentially) exploitable in named. [RT #16391] 2088. [security] Change the default RSA exponent from 3 to 65537. [RT #16391] 2087. [port] libisc failed to compile on OS's w/o a vsnprintf. [RT #16382] 2086. [port] libbind: FreeBSD now has get*by*_r() functions. [RT #16403] 2085. [doc] win32: added index.html and README to zip. [RT #16201] 2084. [contrib] dbus update for 9.3.3rc2. 2083. [port] win32: Visual C++ 2005 support. 2082. [doc] Document 'cache-file' as a test only option. 2081. [port] libbind: minor 64-bit portability fix in memcluster.c. [RT #16360] 2080. [port] libbind: res_init.c did not compile on older versions of Solaris. [RT #16363] 2079. [bug] The lame cache was not handling multiple types correctly. [RT #16361] 2078. [bug] dnssec-checkzone output style "default" was badly named. It is now called "relative". [RT #16326] 2077. [bug] 'dnssec-signzone -O raw' wasn't outputting the complete signed zone. [RT #16326] 2076. [bug] Several files were missing #include causing build failures on OSF. [RT #16341] 2075. [bug] The spillat timer event hander could leak memory. [RT #16357] 2074. [bug] dns_request_createvia2(), dns_request_createvia3(), dns_request_createraw2() and dns_request_createraw3() failed to send multiple UDP requests. [RT #16349] 2073. [bug] Incorrect semantics check for update policy "wildcard". [RT #16353] 2072. [bug] We were not generating valid HMAC SHA digests. [RT #16320] 2071. [port] Test whether gcc accepts -fno-strict-aliasing. [RT #16324] 2070. [bug] The remote address was not always displayed when reporting dispatch failures. [RT #16315] 2069. [bug] Cross compiling was not working. [RT #16330] 2068. [cleanup] Lower incremental tuning message to debug 1. [RT #16319] 2067. [bug] 'rndc' could close the socket too early triggering a INSIST under Windows. [RT #16317] 2066. [security] Handle SIG queries gracefully. [RT #16300] 2065. [bug] libbind: probe for HPUX prototypes for endprotoent_r() and endservent_r(). [RT 16313] 2064. [bug] libbind: silence AIX compiler warnings. [RT #16218] 2063. [bug] Change #1955 introduced a bug which caused the first 'rndc flush' call to not free memory. [RT #16244] 2062. [bug] 'dig +nssearch' was reusing a buffer before it had been returned by the socket code. [RT #16307] 2061. [bug] Accept expired wildcard message reversed. [RT #16296] 2060. [bug] Enabling DLZ support could leave views partially configured. [RT #16295] 2059. [bug] Search into cache rbtdb could trigger an INSIST failure while cleaning up a stale rdataset. [RT #16292] 2058. [bug] Adjust how we calculate rtt estimates in the presence of authoritative servers that drop EDNS and/or CD requests. Also fallback to EDNS/512 and plain DNS faster for zones with less than 3 servers. [RT #16187] 2057. [bug] Make setting "ra" dependent on both allow-query-cache and allow-recursion. [RT #16290] 2056. [bug] dig: ixfr= was not being treated case insensitively at all times. [RT #15955] 2055. [bug] Missing goto after dropping multicast query. [RT #15944] 2054. [port] freebsd: do not explicitly link against -lpthread. [RT #16170] 2053. [port] netbsd:libbind: silence compiler warnings. [RT #16220] 2052. [bug] 'rndc' improve connect failed message to report the failing address. [RT #15978] 2051. [port] More strtol() fixes. [RT #16249] 2050. [bug] Parsing of NSAP records was not case insensitive. [RT #16287] 2049. [bug] Restore SOA before AXFR when falling back from a attempted IXFR when transferring in a zone. Allow a initial SOA query before attempting a AXFR to be requested. [RT #16156] 2048. [bug] It was possible to loop forever when using avoid-v4-udp-ports / avoid-v6-udp-ports when the OS always returned the same local port. [RT #16182] 2047. [bug] Failed to initialize the interface flags to zero. [RT #16245] 2046. [bug] rbtdb.c:rdataset_setadditional() could cause duplicate cleanup [RT #16247]. 2045. [func] Use lock buckets for acache entries to limit memory consumption. [RT #16183] 2044. [port] Add support for atomic operations for Itanium. [RT #16179] 2043. [port] nsupdate/nslookup: Force the flushing of the prompt for interactive sessions. [RT #16148] 2042. [bug] named-checkconf was incorrectly rejecting the logging category "config". [RT #16117] 2041. [bug] "configure --with-dlz-bdb=yes" produced a bad set of libraries to be linked. [RT #16129] 2040. [bug] rbtdb no_references() could trigger an INSIST failure with --enable-atomic. [RT #16022] 2039. [func] Check that all buffers passed to the socket code have been retrieved when the socket event is freed. [RT #16122] 2038. [bug] dig/nslookup/host was unlinking from wrong list when handling errors. [RT #16122] 2037. [func] When unlinking the first or last element in a list check that the list head points to the element to be unlinked. [RT #15959] 2036. [bug] 'rndc recursing' could cause trigger a REQUIRE. [RT #16075] 2035. [func] Make falling back to TCP on UDP refresh failure optional. Default "try-tcp-refresh yes;" for BIND 8 compatibility. [RT #16123] 2034. [bug] gcc: set -fno-strict-aliasing. [RT #16124] 2033. [bug] We weren't creating multiple client memory contexts on demand as expected. [RT #16095] 2032. [bug] Remove a INSIST in query_addadditional2(). [RT #16074] 2031. [bug] Emit a error message when "rndc refresh" is called on a non slave/stub zone. [RT # 16073] 2030. [bug] We were being overly conservative when disabling openssl engine support. [RT #16030] 2029. [bug] host printed out the server multiple times when specified on the command line. [RT #15992] 2028. [port] linux: socket.c compatibility for old systems. [RT #16015] 2027. [port] libbind: Solaris x86 support. [RT #16020] 2026. [bug] Rate limit the two recursive client exceeded messages. [RT #16044] 2025. [func] Update "zone serial unchanged" message. [RT #16026] 2024. [bug] named emitted spurious "zone serial unchanged" messages on reload. [RT #16027] 2023. [bug] "make install" should create ${localstatedir}/run and ${sysconfdir} if they do not exist. [RT #16033] 2022. [bug] If dnssec validation is disabled only assert CD if CD was requested. [RT #16037] 2021. [bug] dnssec-enable no; triggered a REQUIRE. [RT #16037] 2020. [bug] rdataset_setadditional() could leak memory. [RT #16034] 2019. [tuning] Reduce the amount of work performed per quantum when cleaning the cache. [RT #15986] 2018. [bug] Checking if the HMAC MD5 private file was broken. [RT #15960] 2017. [bug] allow-query default was not correct. [RT #15946] 2016. [bug] Return a partial answer if recursion is not allowed but requested and we had the answer to the original qname. [RT #15945] 2015. [cleanup] use-additional-cache is now acache-enable for consistency. Default acache-enable off in BIND 9.4 as it requires memory usage to be configured. It may be enabled by default in BIND 9.5 once we have more experience with it. 2014. [func] Statistics about acache now recorded and sent to log. [RT #15976] 2013. [bug] Handle unexpected TSIGs on unsigned AXFR/IXFR responses more gracefully. [RT #15941] 2012. [func] Don't insert new acache entries if acache is full. [RT #15970] 2011. [func] dnssec-signzone can now update the SOA record of the signed zone, either as an increment or as the system time(). [RT #15633] 2010. [placeholder] rt15958 2009. [bug] libbind: Coverity fixes. [RT #15808] 2008. [func] It is now possible to enable/disable DNSSEC validation from rndc. This is useful for the mobile hosts where the current connection point breaks DNSSEC (firewall/proxy). [RT #15592] rndc validation newstate [view] 2007. [func] It is now possible to explicitly enable DNSSEC validation. default dnssec-validation no; to be changed to yes in 9.5.0. [RT #15674] 2006. [security] Allow-query-cache and allow-recursion now default to the built in acls "localnets" and "localhost". This is being done to make caching servers less attractive as reflective amplifying targets for spoofed traffic. This still leave authoritative servers exposed. The best fix is for full BCP 38 deployment to remove spoofed traffic. 2005. [bug] libbind: Retransmission timeouts should be based on which attempt it is to the nameserver and not the nameserver itself. [RT #13548] 2004. [bug] dns_tsig_sign() could pass a NULL pointer to dst_context_destroy() when cleaning up after a error. [RT #15835] 2003. [bug] libbind: The DNS name/address lookup functions could occasionally follow a random pointer due to structures not being completely zeroed. [RT #15806] 2002. [bug] libbind: tighten the constraints on when struct addrinfo._ai_pad exists. [RT #15783] 2001. [func] Check the KSK flag when updating a secure dynamic zone. New zone option "update-check-ksk yes;". [RT #15817] 2000. [bug] memmove()/strtol() fix was incomplete. [RT #15812] 1999. [func] Implement "rrset-order fixed". [RT #13662] 1998. [bug] Restrict handling of fifos as sockets to just SunOS. This allows named to connect to entropy gathering daemons that use fifos instead of sockets. [RT #15840] 1997. [bug] Named was failing to replace negative cache entries when a positive one for the type was learnt. [RT #15818] 1996. [bug] nsupdate: if a zone has been specified it should appear in the output of 'show'. [RT #15797] 1995. [bug] 'host' was reporting multiple "is an alias" messages. [RT #15702] 1994. [port] OpenSSL 0.9.8 support. [RT #15694] 1993. [bug] Log messages, via syslog, were missing the space after the timestamp if "print-time yes" was specified. [RT #15844] 1992. [bug] Not all incoming zone transfer messages included the view. [RT #15825] 1991. [cleanup] The configuration data, once read, should be treated as read only. Expand the use of const to enforce this at compile time. [RT #15813] 1990. [bug] libbind: isc's override of broken gettimeofday() implementations was not always effective. [RT #15709] 1989. [bug] win32: don't check the service password when re-installing. [RT #15882] 1988. [bug] Remove a bus error from the SHA256/SHA512 support. [RT #15878] 1987. [func] DS/DLV SHA256 digest algorithm support. [RT #15608] 1986. [func] Report when a zone is removed. [RT #15849] 1985. [protocol] DLV has now been assigned a official type code of 32769. [RT #15807] Note: care should be taken to ensure you upgrade both named and dnssec-signzone at the same time for zones with DLV records where named is the master server for the zone. Also any zones that contain DLV records should be removed when upgrading a slave zone. You do not however have to upgrade all servers for a zone with DLV records simultaneously. 1984. [func] dig, nslookup and host now advertise a 4096 byte EDNS UDP buffer size by default. [RT #15855] 1983. [func] Two new update policies. "selfsub" and "selfwild". [RT #12895] 1982. [bug] DNSKEY was being accepted on the parent side of a delegation. KEY is still accepted there for RFC 3007 validated updates. [RT #15620] 1981. [bug] win32: condition.c:wait() could fail to reattain the mutex lock. 1980. [func] dnssec-signzone: output the SOA record as the first record in the signed zone. [RT #15758] 1979. [port] linux: allow named to drop core after changing user ids. [RT #15753] 1978. [port] Handle systems which have a broken recvmsg(). [RT #15742] 1977. [bug] Silence noisy log message. [RT #15704] 1976. [bug] Handle systems with no IPv4 addresses. [RT #15695] 1975. [bug] libbind: isc_gethexstring() could misparse multi-line hex strings with comments. [RT #15814] 1974. [doc] List each of the zone types and associated zone options separately in the ARM. 1973. [func] TSIG HMACSHA1, HMACSHA224, HMACSHA256, HMACSHA384 and HMACSHA512 support. [RT #13606] 1972. [contrib] DBUS dynamic forwarders integration from Jason Vas Dias . 1971. [port] linux: make detection of missing IF_NAMESIZE more robust. [RT #15443] 1970. [bug] nsupdate: adjust UDP timeout when falling back to unsigned SOA query. [RT #15775] 1969. [bug] win32: the socket code was freeing the socket structure too early. [RT #15776] 1968. [bug] Missing lock in resolver.c:validated(). [RT #15739] 1967. [func] dig/nslookup/host: warn about missing "QR". [RT #15779] 1966. [bug] Don't set CD when we have fallen back to plain DNS. [RT #15727] 1965. [func] Suppress spurious "recursion requested but not available" warning with 'dig +qr'. [RT #15780]. 1964. [func] Separate out MX and SRV to CNAME checks. [RT #15723] 1963. [port] Tru64 4.0E doesn't support send() and recv(). [RT #15586] 1962. [bug] Named failed to clear old update-policy when it was removed. [RT #15491] 1961. [bug] Check the port and address of responses forwarded to dispatch. [RT #15474] 1960. [bug] Update code should set NSEC ttls from SOA MINIMUM. [RT #15465] 1959. [func] Control the zeroing of the negative response TTL to a soa query. Defaults "zero-no-soa-ttl yes;" and "zero-no-soa-ttl-cache no;". [RT #15460] 1958. [bug] Named failed to update the zone's secure state until the zone was reloaded. [RT #15412] 1957. [bug] Dig mishandled responses to class ANY queries. [RT #15402] 1956. [bug] Improve cross compile support, 'gen' is now built by native compiler. See README for additional cross compile support information. [RT #15148] 1955. [bug] Pre-allocate the cache cleaning iterator. [RT #14998] 1954. [func] Named now falls back to advertising EDNS with a 512 byte receive buffer if the initial EDNS queries fail. [RT #14852] 1953. [func] The maximum EDNS UDP response named will send can now be set in named.conf (max-udp-size). This is independent of the advertised receive buffer (edns-udp-size). [RT #14852] 1952. [port] hpux: tell the linker to build a runtime link path "-Wl,+b:". [RT #14816]. 1951. [security] Drop queries from particular well known ports. Don't return FORMERR to queries from particular well known ports. [RT #15636] 1950. [port] Solaris 2.5.1 and earlier cannot bind() then connect() a TCP socket. This prevents the source address being set for TCP connections. [RT #15628] 1949. [func] Addition memory leakage checks. [RT #15544] 1948. [bug] If was possible to trigger a REQUIRE failure in xfrin.c:maybe_free() if named ran out of memory. [RT #15568] 1947. [func] It is now possible to configure named to accept expired RRSIGs. Default "dnssec-accept-expired no;". Setting "dnssec-accept-expired yes;" leaves named vulnerable to replay attacks. [RT #14685] 1946. [bug] resume_dslookup() could trigger a REQUIRE failure when using forwarders. [RT #15549] 1945. [cleanup] dnssec-keygen: RSA (RSAMD5) is no longer recommended. To generate a RSAMD5 key you must explicitly request RSAMD5. [RT #13780] 1944. [cleanup] isc_hash_create() does not need a read/write lock. [RT #15522] 1943. [bug] Set the loadtime after rolling forward the journal. [RT #15647] 1942. [bug] If the name of a DNSKEY match that of one in trusted-keys do not attempt to validate the DNSKEY using the parents DS RRset. [RT #15649] 1941. [bug] ncache_adderesult() should set eresult even if no rdataset is passed to it. [RT #15642] 1940. [bug] Fixed a number of error conditions reported by Coverity. 1939. [bug] The resolver could dereference a null pointer after validation if all the queries have timed out. [RT #15528] 1938. [bug] The validator was not correctly handling unsecure negative responses at or below a SEP. [RT #15528] 1937. [bug] sdlz doesn't handle RRSIG records. [RT #15564] 1936. [bug] The validator could leak memory. [RT #15544] 1935. [bug] 'acache' was DO sensitive. [RT #15430] 1934. [func] Validate pending NS RRsets, in the authority section, prior to returning them if it can be done without requiring DNSKEYs to be fetched. [RT #15430] 1933. [bug] dump_rdataset_raw() had a incorrect INSIST. [RT #15534] 1932. [bug] hpux: LDFLAGS was getting corrupted. [RT #15530] 1931. [bug] Per-client mctx could require a huge amount of memory, particularly for a busy caching server. [RT #15519] 1930. [port] HPUX: ia64 support. [RT #15473] 1929. [port] FreeBSD: extend use of PTHREAD_SCOPE_SYSTEM. 1928. [bug] Race in rbtdb.c:currentversion(). [RT #15517] 1927. [bug] Access to soanode or nsnode in rbtdb violated the lock order rule and could cause a dead lock. [RT #15518] 1926. [bug] The Windows installer did not check for empty passwords. BINDinstall was being installed in the wrong place. [RT #15483] 1925. [port] All outer level AC_TRY_RUNs need cross compiling defaults. [RT #15469] 1924. [port] libbind: hpux ia64 support. [RT #15473] 1923. [bug] ns_client_detach() called too early. [RT #15499] 1922. [bug] check-tool.c:setup_logging() missing call to dns_log_setcontext(). 1921. [bug] Client memory contexts were not using internal malloc. [RT #15434] 1920. [bug] The cache rbtdb lock array was too small to have the desired performance characteristics. [RT #15454] 1919. [contrib] queryperf: a set of new features: collecting/printing response delays, printing intermediate results, and adjusting query rate for the "target" qps. 1918. [bug] Memory leak when checking acls. [RT #15391] 1917. [doc] funcsynopsisinfo wasn't being treated as verbatim when generating man pages. [RT #15385] 1916. [func] Integrate contributed IDN code from JPNIC. [RT #15383] 1915. [bug] dig +ndots was broken. [RT #15215] 1914. [protocol] DS is required to accept mnemonic algorithms (RFC 4034). Still emit numeric algorithms for compatibility with RFC 3658. [RT #15354] 1913. [func] Integrate contributed DLZ code into named. [RT #11382] 1912. [port] aix: atomic locking for powerpc. [RT #15020] 1911. [bug] Update windows socket code. [RT #14965] 1910. [bug] dig's +sigchase code overhauled. [RT #14933] 1909. [bug] The DLV code has been re-worked to make no longer query order sensitive. [RT #14933] 1908. [func] dig now warns if 'RA' is not set in the answer when 'RD' was set in the query. host/nslookup skip servers that fail to set 'RA' when 'RD' is set unless a server is explicitly set. [RT #15005] 1907. [func] host/nslookup now continue (default)/fail on SERVFAIL. [RT #15006] 1906. [func] dig now has a '-q queryname' and '+showsearch' options. [RT #15034] 1905. [bug] Strings returned from cfg_obj_asstring() should be treated as read-only. The prototype for cfg_obj_asstring() has been updated to reflect this. [RT #15256] 1904. [func] Automatic empty zone creation for D.F.IP6.ARPA and friends. Note: RFC 1918 zones are not yet covered by this but are likely to be in a future release. New options: empty-server, empty-contact, empty-zones-enable and disable-empty-zone. 1903. [func] ISC string copy API. 1902. [func] Attempt to make the amount of work performed in a iteration self tuning. The covers nodes clean from the cache per iteration, nodes written to disk when rewriting a master file and nodes destroyed per iteration when destroying a zone or a cache. [RT #14996] 1901. [cleanup] Don't add DNSKEY records to the additional section. 1900. [bug] ixfr-from-differences failed to ensure that the serial number increased. [RT #15036] 1899. [func] named-checkconf now validates update-policy entries. [RT #14963] 1898. [bug] Extend ISC_SOCKADDR_FORMATSIZE and ISC_NETADDR_FORMATSIZE to allow for scope details. 1897. [func] x86 and x86_64 now have separate atomic locking implementations. 1896. [bug] Recursive clients soft quota support wasn't working as expected. [RT #15103] 1895. [bug] A escaped character is, potentially, converted to the output character set too early. [RT #14666] 1894. [doc] Review ARM for BIND 9.4. 1893. [port] Use uintptr_t if available. [RT #14606] 1892. [func] Support for SPF rdata type. [RT #15033] 1891. [port] freebsd: pthread_mutex_init can fail if it runs out of memory. [RT #14995] 1890. [func] Raise the UDP receive buffer size to 32k if it is less than 32k. [RT #14953] 1889. [port] sunos: non blocking i/o support. [RT #14951] 1888. [func] Support for IPSECKEY rdata type. [RT #14967] 1887. [bug] The cache could delete expired records too fast for clients with a virtual time in the past. [RT #14991] 1886. [bug] fctx_create() could return success even though it failed. [RT #14993] 1885. [func] dig: report the number of extra bytes still left in the packet after processing all the records. 1884. [cleanup] dighost.c: move external declarations into . 1883. [bug] dnssec-signzone, dnssec-keygen: handle negative debug levels. [RT #14962] 1882. [func] Limit the number of recursive clients that can be waiting for a single query () to resolve. New options clients-per-query and max-clients-per-query. 1881. [func] Add a system test for named-checkconf. [RT #14931] 1880. [func] The lame cache is now done on a basis as some servers only appear to be lame for certain query types. [RT #14916] 1879. [func] "USE INTERNAL MALLOC" is now runtime selectable. [RT #14892] 1878. [func] Detect duplicates of UDP queries we are recursing on and drop them. New stats category "duplicate". [RT #2471] 1877. [bug] Fix unreasonably low quantum on call to dns_rbt_destroy2(). Remove unnecessary unhash_node() call. [RT #14919] 1876. [func] Additional memory debugging support to track size and mctx arguments. [RT #14814] 1875. [bug] process_dhtkey() was using the wrong memory context to free some memory. [RT #14890] 1874. [port] sunos: portability fixes. [RT #14814] 1873. [port] win32: isc__errno2result() now reports its caller. [RT #13753] 1872. [port] win32: Handle ERROR_NETNAME_DELETED. [RT #13753] 1871. [placeholder] 1870. [func] Added framework for handling multiple EDNS versions. [RT #14873] 1869. [func] dig can now specify the EDNS version when making a query. [RT #14873] 1868. [func] edns-udp-size can now be overridden on a per server basis. [RT #14851] 1867. [bug] It was possible to trigger a INSIST in dlv_validatezonekey(). [RT #14846] 1866. [bug] resolv.conf parse errors were being ignored by dig/host/nslookup. [RT #14841] 1865. [bug] Silently ignore nameservers in /etc/resolv.conf with bad addresses. [RT #14841] 1864. [bug] Don't try the alternative transfer source if you got a answer / transfer with the main source address. [RT #14802] 1863. [bug] rrset-order "fixed" error messages not complete. 1862. [func] Add additional zone data constancy checks. named-checkzone has extended checking of NS, MX and SRV record and the hosts they reference. named has extended post zone load checks. New zone options: check-mx and integrity-check. [RT #4940] 1861. [bug] dig could trigger a INSIST on certain malformed responses. [RT #14801] 1860. [port] solaris 2.8: hack_shutup_pthreadmutexinit was incorrectly set. [RT #14775] 1859. [func] Add support for CH A record. [RT #14695] 1858. [bug] The flush-zones-on-shutdown option wasn't being parsed. [RT #14686] 1857. [bug] named could trigger a INSIST() if reconfigured / reloaded too fast. [RT #14673] 1856. [doc] Switch Docbook toolchain from DSSSL to XSL. [RT #11398] 1855. [bug] ixfr-from-differences was failing to detect changes of ttl due to dns_diff_subtract() was ignoring the ttl of records. [RT #14616] 1854. [bug] lwres also needs to know the print format for (long long). [RT #13754] 1853. [bug] Rework how DLV interacts with proveunsecure(). [RT #13605] 1852. [cleanup] Remove last vestiges of dnssec-signkey and dnssec-makekeyset (removed from Makefile years ago). 1851. [doc] Doxygen comment markup. [RT #11398] 1850. [bug] Memory leak in lwres_getipnodebyaddr(). [RT #14591] 1849. [doc] All forms of the man pages (docbook, man, html) should have consistent copyright dates. 1848. [bug] Improve SMF integration. [RT #13238] 1847. [bug] isc_ondestroy_init() is called too late in dns_rbtdb_create()/dns_rbtdb64_create(). [RT #13661] 1846. [contrib] query-loc-0.3.0 from Stephane Bortzmeyer . 1845. [bug] Improve error reporting to distinguish between accept()/fcntl() and socket()/fcntl() errors. [RT #13745] 1844. [bug] inet_pton() accepted more that 4 hexadecimal digits for each 16 bit piece of the IPv6 address. The text representation of a IPv6 address has been tightened to disallow this (draft-ietf-ipv6-addr-arch-v4-02.txt). [RT #5662] 1843. [cleanup] CINCLUDES takes precedence over CFLAGS. This helps when CFLAGS contains "-I /usr/local/include" resulting in old header files being used. 1842. [port] cmsg_len() could produce incorrect results on some platform. [RT #13744] 1841. [bug] "dig +nssearch" now makes a recursive query to find the list of nameservers to query. [RT #13694] 1840. [func] dnssec-signzone can now randomize signature end times (dnssec-signzone -j jitter). [RT #13609] 1839. [bug] was not being installed. 1838. [cleanup] Don't allow Linux capabilities to be inherited. [RT #13707] 1837. [bug] Compile time option ISC_FACILITY was not effective for 'named -u '. [RT #13714] 1836. [cleanup] Silence compiler warnings in hash_test.c. 1835. [bug] Update dnssec-signzone's usage message. [RT #13657] 1834. [bug] Bad memset in rdata_test.c. [RT #13658] 1833. [bug] Race condition in isc_mutex_lock_profile(). [RT #13660] 1832. [bug] named fails to return BADKEY on unknown TSIG algorithm. [RT #13620] 1831. [doc] Update named-checkzone documentation. [RT #13604] 1830. [bug] adb lame cache has sence of test reversed. [RT #13600] 1829. [bug] win32: "pid-file none;" broken. [RT #13563] 1828. [bug] isc_rwlock_init() failed to properly cleanup if it encountered a error. [RT #13549] 1827. [bug] host: update usage message for '-a'. [RT #37116] 1826. [bug] Missing DESTROYLOCK() in isc_mem_createx() on out of memory error. [RT #13537] 1825. [bug] Missing UNLOCK() on out of memory error from in rbtdb.c:subtractrdataset(). [RT #13519] 1824. [bug] Memory leak on dns_zone_setdbtype() failure. [RT #13510] 1823. [bug] Wrong macro used to check for point to point interface. [RT #13418] 1822. [bug] check-names test for RT was reversed. [RT #13382] 1821. [placeholder] 1820. [bug] Gracefully handle acl loops. [RT #13659] 1819. [bug] The validator needed to check both the algorithm and digest types of the DS to determine if it could be used to introduce a secure zone. [RT #13593] 1818. [bug] 'named-checkconf -z' triggered an INSIST. [RT #13599] 1817. [func] Add support for additional zone file formats for improving loading performance. The masterfile-format option in named.conf can be used to specify a non-default format. A separate command named-compilezone was provided to generate zone files in the new format. Additionally, the -I and -O options for dnssec-signzone specify the input and output formats. 1816. [port] UnixWare: failed to compile lib/isc/unix/net.c. [RT #13597] 1815. [bug] nsupdate triggered a REQUIRE if the server was set without also setting the zone and it encountered a CNAME and was using TSIG. [RT #13086] 1814. [func] UNIX domain controls are now supported. 1813. [func] Restructured the data locking framework using architecture dependent atomic operations (when available), improving response performance on multi-processor machines significantly. x86, x86_64, alpha, powerpc, and mips are currently supported. 1812. [port] win32: IN6_IS_ADDR_UNSPECIFIED macro is incorrect. [RT #13453] 1811. [func] Preserve the case of domain names in rdata during zone transfers. [RT #13547] 1810. [bug] configure, lib/bind/configure make different default decisions about whether to do a threaded build. [RT #13212] 1809. [bug] "make distclean" failed for libbind if the platform is not supported. 1808. [bug] zone.c:notify_zone() contained a race condition, zone->db could change underneath it. [RT #13511] 1807. [bug] When forwarding (forward only) set the active domain from the forward zone name. [RT #13526] 1806. [bug] The resolver returned the wrong result when a CNAME / DNAME was encountered when fetching glue from a secure namespace. [RT #13501] 1805. [bug] Pending status was not being cleared when DLV was active. [RT #13501] 1804. [bug] Ensure that if we are queried for glue that it fits in the additional section or TC is set to tell the client to retry using TCP. [RT #10114] 1803. [bug] dnssec-signzone sometimes failed to remove old RRSIGs. [RT #13483] 1802. [bug] Handle connection resets better. [RT #11280] 1801. [func] Report differences between hints and real NS rrset and associated address records. 1800. [bug] Changes #1719 allowed a INSIST to be triggered. [RT #13428] 1799. [bug] 'rndc flushname' failed to flush negative cache entries. [RT #13438] 1798. [func] The server syntax has been extended to support a range of servers. [RT #11132] 1797. [func] named-checkconf now check acls to verify that they only refer to existing acls. [RT #13101] 1796. [func] "rndc freeze/thaw" now freezes/thaws all zones. 1795. [bug] "rndc dumpdb" was not fully documented. Minor formating issues with "rndc dumpdb -all". [RT #13396] 1794. [func] Named and named-checkzone can now both check for non-terminal wildcard records. 1793. [func] Extend adjusting TTL warning messages. [RT #13378] 1792. [func] New zone option "notify-delay". Specify a minimum delay between sets of NOTIFY messages. 1791. [bug] 'host -t a' still printed out AAAA and MX records. [RT #13230] 1790. [cleanup] Move lib/dns/sec/dst up into lib/dns. This should allow parallel make to succeed. 1789. [bug] Prerequisite test for tkey and dnssec could fail with "configure --with-libtool". 1788. [bug] libbind9.la/libbind9.so needs to link against libisccfg.la/libisccfg.so. 1787. [port] HPUX: both "cc" and "gcc" need -Wl,+vnocompatwarnings. 1786. [port] AIX: libt_api needs to be taught to look for T_testlist in the main executable (--with-libtool). [RT #13239] 1785. [bug] libbind9.la/libbind9.so needs to link against libisc.la/libisc.so. 1784. [cleanup] "libtool -allow-undefined" is the default. Leave hooks in configure to allow it to be set if needed in the future. 1783. [cleanup] We only need one copy of libtool.m4, ltmain.sh in the source tree. 1782. [port] OSX: --with-libtool + --enable-libbind broke on __evOptMonoTime. [RT #13219] 1781. [port] FreeBSD 5.3: set PTHREAD_SCOPE_SYSTEM. [RT #12810] 1780. [bug] Update libtool to 1.5.10. 1779. [port] OSF 5.1: libtool didn't handle -pthread correctly. 1778. [port] HUX 11.11: fix broken IN6ADDR_ANY_INIT and IN6ADDR_LOOPBACK_INIT macros. 1777. [port] OSF 5.1: fix broken IN6ADDR_ANY_INIT and IN6ADDR_LOOPBACK_INIT macros. 1776. [port] Solaris 2.9: fix broken IN6ADDR_ANY_INIT and IN6ADDR_LOOPBACK_INIT macros. 1775. [bug] Only compile getnetent_r.c when threaded. [RT #13205] 1774. [port] Aix: Silence compiler warnings / build failures. [RT #13154] 1773. [bug] Fast retry on host / net unreachable. [RT #13153] 1772. [placeholder] 1771. [placeholder] 1770. [bug] named-checkconf failed to report missing a missing file clause for rbt{64} master/hint zones. [RT #13009] 1769. [port] win32: change compiler flags /MTd ==> /MDd, /MT ==> /MD. 1768. [bug] nsecnoexistnodata() could be called with a non-NSEC rdataset. [RT #12907] 1767. [port] Builds on IPv6 platforms without IPv6 Advanced API support for (struct in6_pktinfo) failed. [RT #13077] 1766. [bug] Update the master file timestamp on successful refresh as well as the journal's timestamp. [RT #13062] 1765. [bug] configure --with-openssl=auto failed. [RT #12937] 1764. [bug] dns_zone_replacedb failed to emit a error message if there was no SOA record in the replacement db. [RT #13016] 1763. [func] Perform sanity checks on NS records which refer to 'in zone' names. [RT #13002] 1762. [bug] isc_interfaceiter_create() could return ISC_R_SUCCESS even when it failed. [RT #12995] 1761. [bug] 'rndc dumpdb' didn't report unassociated entries. [RT #12971] 1760. [bug] Host / net unreachable was not penalising rtt estimates. [RT #12970] 1759. [bug] Named failed to startup if the OS supported IPv6 but had no IPv6 interfaces configured. [RT #12942] 1758. [func] Don't send notify messages to self. [RT #12933] 1757. [func] host now can turn on memory debugging flags with '-m'. 1756. [func] named-checkconf now checks the logging configuration. [RT #12352] 1755. [func] allow-update is now settable at the options / view level. [RT #6636] 1754. [bug] We weren't always attempting to query the parent server for the DS records at the zone cut. [RT #12774] 1753. [bug] Don't serve a slave zone which has no NS records. [RT #12894] 1752. [port] Move isc_app_start() to after ns_os_daemonise() as some fork() implementations unblock the signals that are blocked by isc_app_start(). [RT #12810] 1751. [bug] --enable-getifaddrs failed under linux. [RT #12867] 1750. [port] lib/bind/make/rules.in:subdirs was not bash friendly. [RT #12864] 1749. [bug] 'check-names response ignore;' failed to ignore. [RT #12866] 1748. [func] dig now returns the byte count for axfr/ixfr. 1747. [bug] BIND 8 compatibility: named/named-checkconf failed to parse "host-statistics-max" in named.conf. 1746. [func] Make public the function to read a key file, dst_key_read_public(). [RT #12450] 1745. [bug] Dig/host/nslookup accept replies from link locals regardless of scope if no scope was specified when query was sent. [RT #12745] 1744. [bug] If tuple2msgname() failed to convert a tuple to a name a REQUIRE could be triggered. [RT #12796] 1743. [bug] If isc_taskmgr_create() was not able to create the requested number of worker threads then destruction of the manager would trigger an INSIST() failure. [RT #12790] 1742. [bug] Deleting all records at a node then adding a previously existing record, in a single UPDATE transaction, failed to leave / regenerate the associated RRSIG records. [RT #12788] 1741. [bug] Deleting all records at a node in a secure zone using a update-policy grant failed. [RT #12787] 1740. [bug] Replace rbt's hash algorithm as it performed badly with certain zones. [RT #12729] NOTE: a hash context now needs to be established via isc_hash_create() if the application was not already doing this. 1739. [bug] dns_rbt_deletetree() could incorrectly return ISC_R_QUOTA. [RT #12695] 1738. [bug] Enable overrun checking by default. [RT #12695] 1737. [bug] named failed if more than 16 masters were specified. [RT #12627] 1736. [bug] dst_key_fromnamedfile() could fail to read a public key. [RT #12687] 1735. [bug] 'dig +sigtrace' could die with a REQUIRE failure. [RE #12688] 1734. [cleanup] 'rndc-confgen -a -t' remove extra '/' in path. [RT #12588] 1733. [bug] Return non-zero exit status on initial load failure. [RT #12658] 1732. [bug] 'rrset-order name "*"' wasn't being applied to ".". [RT #12467] 1731. [port] darwin: relax version test in ifconfig.sh. [RT #12581] 1730. [port] Determine the length type used by the socket API. [RT #12581] 1729. [func] Improve check-names error messages. 1728. [doc] Update check-names documentation. 1727. [bug] named-checkzone: check-names support didn't match documentation. 1726. [port] aix5: add support for aix5. 1725. [port] linux: update error message on interaction of threads, capabilities and setuid support (named -u). [RT #12541] 1724. [bug] Look for DNSKEY records with "dig +sigtrace". [RT #12557] 1723. [cleanup] Silence compiler warnings from t_tasks.c. [RT #12493] 1722. [bug] Don't commit the journal on malformed ixfr streams. [RT #12519] 1721. [bug] Error message from the journal processing were not always identifying the relevant journal. [RT #12519] 1720. [bug] 'dig +chase' did not terminate on a RFC 2308 Type 1 negative response. [RT #12506] 1719. [bug] named was not correctly caching a RFC 2308 Type 1 negative response. [RT #12506] 1718. [bug] nsupdate was not handling RFC 2308 Type 3 negative responses when looking for the zone / master server. [RT #12506] 1717. [port] solaris: ifconfig.sh did not support Solaris 10. "ifconfig.sh down" didn't work for Solaris 9. 1716. [doc] named.conf(5) was being installed in the wrong location. [RT #12441] 1715. [func] 'dig +trace' now randomly selects the next servers to try. Report if there is a bad delegation. 1714. [bug] dig/host/nslookup were only trying the first address when a nameserver was specified by name. [RT #12286] 1713. [port] linux: extend capset failure message to say: please ensure that the capset kernel module is loaded. see insmod(8) 1712. [bug] Missing FULLCHECK for "trusted-key" in dig. 1711. [func] 'rndc unfreeze' has been deprecated by 'rndc thaw'. 1710. [func] 'rndc notify zone [class [view]]' resend the NOTIFY messages for the specified zone. [RT #9479] 1709. [port] solaris: add SMF support from Sun. 1708. [cleanup] Replaced dns_fullname_hash() with dns_name_fullhash() for conformance to the name space convention. Binary backward compatibility to the old function name is provided. [RT #12376] 1707. [contrib] sdb/ldap updated to version 1.0-beta. 1706. [bug] 'rndc stop' failed to cause zones to be flushed sometimes. [RT #12328] 1705. [func] Allow the journal's name to be changed via named.conf. 1704. [port] lwres needed a snprintf() implementation for platforms without snprintf(). Add missing "#include ". [RT #12321] 1703. [bug] named would loop sending NOTIFY messages when it failed to receive a response. [RT #12322] 1702. [bug] also-notify should not be applied to built in zones. [RT #12323] 1701. [doc] A minimal named.conf man page. 1700. [func] nslookup is no longer to be treated as deprecated. Remove "deprecated" warning message. Add man page. 1699. [bug] dnssec-signzone can generate "not exact" errors when resigning. [RT #12281] 1698. [doc] Use reserved IPv6 documentation prefix. 1697. [bug] xxx-source{,-v6} was not effective when it specified one of listening addresses and a different port than the listening port. [RT #12257] 1696. [bug] dnssec-signzone failed to clean out nodes that consisted of only NSEC and RRSIG records. [RT #12154] 1695. [bug] DS records when forwarding require special handling. [RT #12133] 1694. [bug] Report if the builtin views of "_default" / "_bind" are defined in named.conf. [RT #12023] 1693. [bug] max-journal-size was not effective for master zones with ixfr-from-differences set. [RT #12024] 1692. [bug] Don't set -I, -L and -R flags when libcrypto is in /usr/lib. [RT #11971] 1691. [bug] sdb's attachversion was not complete. [RT #11990] 1690. [bug] Delay detaching view from the client until UPDATE processing completes when shutting down. [RT #11714] 1689. [bug] DNS_NAME_TOREGION() and DNS_NAME_SPLIT() macros contained gratuitous semicolons. [RT #11707] 1688. [bug] LDFLAGS was not supported. 1687. [bug] Race condition in dispatch. [RT #10272] 1686. [bug] Named sent a extraneous NOTIFY when it received a redundant UPDATE request. [RT #11943] 1685. [bug] Change #1679 loop tests weren't quite right. 1684. [func] ixfr-from-differences now takes master and slave in addition to yes and no at the options and view levels. 1683. [bug] dig +sigchase could leak memory. [RT #11445] 1682. [port] Update configure test for (long long) printf format. [RT #5066] 1681. [bug] Only set SO_REUSEADDR when a port is specified in isc_socket_bind(). [RT #11742] 1680. [func] rndc: the source address can now be specified. 1679. [bug] When there was a single nameserver with multiple addresses for a zone not all addresses were tried. [RT #11706] 1678. [bug] RRSIG should use TYPEXXXXX for unknown types. 1677. [bug] dig: +aaonly didn't work, +aaflag undocumented. 1676. [func] New option "allow-query-cache". This lets allow-query be used to specify the default zone access level rather than having to have every zone override the global value. allow-query-cache can be set at both the options and view levels. If allow-query-cache is not set allow-query applies. 1675. [bug] named would sometimes add extra NSEC records to the authority section. 1674. [port] linux: increase buffer size used to scan /proc/net/if_inet6. 1673. [port] linux: issue a error messages if IPv6 interface scans fails. 1672. [cleanup] Tests which only function in a threaded build now return R:THREADONLY (rather than R:UNTESTED) in a non-threaded build. 1671. [contrib] queryperf: add NAPTR to the list of known types. 1670. [func] Log UPDATE requests to slave zones without an acl as "disabled" at debug level 3. [RT #11657] 1669. [placeholder] 1668. [bug] DIG_SIGCHASE was making bin/dig/host dump core. 1667. [port] linux: not all versions have IF_NAMESIZE. 1666. [bug] The optional port on hostnames in dual-stack-servers was being ignored. 1665. [func] rndc now allows addresses to be set in the server clauses. 1664. [bug] nsupdate needed KEY for SIG(0), not DNSKEY. 1663. [func] Look for OpenSSL by default. 1662. [bug] Change #1658 failed to change one use of 'type' to 'keytype'. 1661. [bug] Restore dns_name_concatenate() call in adb.c:set_target(). [RT #11582] 1660. [bug] win32: connection_reset_fix() was being called unconditionally. [RT #11595] 1659. [cleanup] Cleanup some messages that were referring to KEY vs DNSKEY, NXT vs NSEC and SIG vs RRSIG. 1658. [func] Update dnssec-keygen to default to KEY for HMAC-MD5 and DH. Tighten which options apply to KEY and DNSKEY records. 1657. [doc] ARM: document query log output. 1656. [doc] Update DNSSEC description in ARM to cover DS, NSEC DNSKEY and RRSIG. [RT #11542] 1655. [bug] Logging multiple versions w/o a size was broken. [RT #11446] 1654. [bug] isc_result_totext() contained array bounds read error. 1653. [func] Add key type checking to dst_key_fromfilename(), DST_TYPE_KEY should be used to read TSIG, TKEY and SIG(0) keys. 1652. [bug] TKEY still uses KEY. 1651. [bug] dig: process multiple dash options. 1650. [bug] dig, nslookup: flush standard out after each command. 1649. [bug] Silence "unexpected non-minimal diff" message. [RT #11206] 1648. [func] Update dnssec-lookaside named.conf syntax to support multiple dnssec-lookaside namespaces (not yet implemented). 1647. [bug] It was possible trigger a INSIST when chasing a DS record that required walking back over a empty node. [RT #11445] 1646. [bug] win32: logging file versions didn't work with non-UNC filenames. [RT #11486] 1645. [bug] named could trigger a REQUIRE failure if multiple masters with keys are specified. 1644. [bug] Update the journal modification time after a successful refresh query. [RT #11436] 1643. [bug] dns_db_closeversion() could leak memory / node references. [RT #11163] 1642. [port] Support OpenSSL implementations which don't have DSA support. [RT #11360] 1641. [bug] Update the check-names description in ARM. [RT #11389] 1640. [bug] win32: isc_socket_cancel(ISC_SOCKCANCEL_ACCEPT) was incorrectly closing the socket. [RT #11291] 1639. [func] Initial dlv system test. 1638. [bug] "ixfr-from-differences" could generate a REQUIRE failure if the journal open failed. [RT #11347] 1637. [bug] Node reference leak on error in addnoqname(). 1636. [bug] The dump done callback could get ISC_R_SUCCESS even if a error had occurred. The database version no longer matched the version of the database that was dumped. 1635. [bug] Memory leak on error in query_addds(). 1634. [bug] named didn't supply a useful error message when it detected duplicate views. [RT #11208] 1633. [bug] named should return NOTIMP to update requests to a slaves without a allow-update-forwarding acl specified. [RT #11331] 1632. [bug] nsupdate failed to send prerequisite only UPDATE messages. [RT #11288] 1631. [bug] dns_journal_compact() could sometimes corrupt the journal. [RT #11124] 1630. [contrib] queryperf: add support for IPv6 transport. 1629. [func] dig now supports IPv6 scoped addresses with the extended format in the local-server part. [RT #8753] 1628. [bug] Typo in Compaq Trucluster support. [RT #11264] 1627. [bug] win32: sockets were not being closed when the last external reference was removed. [RT #11179] 1626. [bug] --enable-getifaddrs was broken. [RT #11259] 1625. [bug] named failed to load/transfer RFC2535 signed zones which contained CNAMES. [RT #11237] 1624. [bug] zonemgr_putio() call should be locked. [RT #11163] 1623. [bug] A serial number of zero was being displayed in the "sending notifies" log message when also-notify was used. [RT #11177] 1622. [func] probe the system to see if IPV6_(RECV)PKTINFO is available, and suppress wildcard binding if not. 1621. [bug] match-destinations did not work for IPv6 TCP queries. [RT #11156] 1620. [func] When loading a zone report if it is signed. [RT #11149] 1619. [bug] Missing ISC_LIST_UNLINK in end_reserved_dispatches(). [RT #11118] 1618. [bug] Fencepost errors in dns_name_ishostname() and dns_name_ismailbox() could trigger a INSIST(). 1617. [port] win32: VC++ 6.0 support. 1616. [compat] Ensure that named's version is visible in the core dump. [RT #11127] 1615. [port] Define ISC_SOCKADDR_LEN_T based on _BSD_SOCKLEN_T_ if it is defined. 1614. [port] win32: silence resource limit messages. [RT #11101] 1613. [bug] Builds would fail on machines w/o a if_nametoindex(). Missing #ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX/#endif. [RT #11119] 1612. [bug] check-names at the option/view level could trigger an INSIST. [RT #11116] 1611. [bug] solaris: IPv6 interface scanning failed to cope with no active IPv6 interfaces. 1610. [bug] On dual stack machines "dig -b" failed to set the address type to be looked up with "@server". [RT #11069] 1609. [func] dig now has support to chase DNSSEC signature chains. Requires -DDIG_SIGCHASE=1 to be set in STD_CDEFINES. DNSSEC validation code in dig coded by Olivier Courtay (olivier.courtay@irisa.fr) for the IDsA project (http://idsa.irisa.fr). 1608. [func] dig and host now accept -4/-6 to select IP transport to use when making queries. 1607. [bug] dig, host and nslookup were still using random() to generate query ids. [RT #11013] 1606. [bug] DLV insecurity proof was failing. 1605. [func] New dns_db_find() option DNS_DBFIND_COVERINGNSEC. 1604. [bug] A xfrout_ctx_create() failure would result in xfrout_ctx_destroy() being called with a partially initialized structure. 1603. [bug] nsupdate: set interactive based on isatty(). [RT #10929] 1602. [bug] Logging to a file failed unless a size was specified. [RT #10925] 1601. [bug] Silence spurious warning 'both "recursion no;" and "allow-recursion" active' warning from view "_bind". [RT #10920] 1600. [bug] Duplicate zone pre-load checks were not case insensitive. 1599. [bug] Fix memory leak on error path when checking named.conf. 1598. [func] Specify that certain parts of the namespace must be secure (dnssec-must-be-secure). 1597. [func] Allow notify-source and query-source to be specified on a per server basis similar to transfer-source. [RT #6496] 1596. [func] Accept 'notify-source' style syntax for query-source. 1595. [func] New notify type 'master-only'. Enable notify for master zones only. 1594. [bug] 'rndc dumpdb' could prevent named from answering queries while the dump was in progress. [RT #10565] 1593. [bug] rndc should return "unknown command" to unknown commands. [RT #10642] 1592. [bug] configure_view() could leak a dispatch. [RT #10675] 1591. [bug] libbind: updated to BIND 8.4.5. 1590. [port] netbsd: update thread support. 1589. [func] DNSSEC lookaside validation. 1588. [bug] win32: TCP sockets could become blocked. [RT #10115] 1587. [bug] dns_message_settsigkey() failed to clear existing key. [RT #10590] 1586. [func] "check-names" is now implemented. 1585. [placeholder] 1584. [bug] "make test" failed with a read only source tree. [RT #10461] 1583. [bug] Records add via UPDATE failed to get the correct trust level. [RT #10452] 1582. [bug] rrset-order failed to work on RRsets with more than 32 elements. [RT #10381] 1581. [func] Disable DNSSEC support by default. To enable DNSSEC specify "dnssec-enable yes;" in named.conf. 1580. [bug] Zone destruction on final detach takes a long time. [RT #3746] 1579. [bug] Multiple task managers could not be created. 1578. [bug] Don't use CLASS E IPv4 addresses when resolving. [RT #10346] 1577. [bug] Use isc_uint32_t in ultrasparc optimizer bug workaround code. [RT #10331] 1576. [bug] Race condition in dns_dispatch_addresponse(). [RT #10272] 1575. [func] Log TSIG name on TSIG verify failure. [RT #4404] 1574. [bug] Don't attempt to open the controls socket(s) when running tests. [RT #9091] 1573. [port] linux: update to libtool 1.5.2 so that "make install DESTDIR=/xx" works with "configure --with-libtool". [RT #9941] 1572. [bug] nsupdate: sign the soa query to find the enclosing zone if the server is specified. [RT #10148] 1571. [bug] rbt:hash_node() could fail leaving the hash table in an inconsistent state. [RT #10208] 1570. [bug] nsupdate failed to handle classes other than IN. New keyword 'class' which sets the default class. [RT #10202] 1569. [func] nsupdate new command 'answer' which displays the complete answer message to the last update. 1568. [bug] nsupdate now reports that the update failed in interactive mode. [RT #10236] 1567. [maint] B.ROOT-SERVERS.NET is now 192.228.79.201. 1566. [port] Support for the cmsg framework on Solaris and HP/UX. This also solved the problem that match-destinations for IPv6 addresses did not work on these systems. [RT #10221] 1565. [bug] CD flag should be copied to outgoing queries unless the query is under a secure entry point in which case CD should be set. 1564. [func] Attempt to provide a fallback entropy source to be used if named is running chrooted and named is unable to open entropy source within the chroot area. [RT #10133] 1563. [bug] Gracefully fail when unable to obtain neither an IPv4 nor an IPv6 dispatch. [RT #10230] 1562. [bug] isc_socket_create() and isc_socket_accept() could leak memory under error conditions. [RT #10230] 1561. [bug] It was possible to release the same name twice if named ran out of memory. [RT #10197] 1560. [port] FreeBSD: work around FreeBSD 5.2 mapping EAI_NODATA and EAI_NONAME to the same value. 1559. [port] named should ignore SIGFSZ. 1558. [func] New DNSSEC 'disable-algorithms'. Support entry into child zones for which we don't have a supported algorithm. Such child zones are treated as unsigned. 1557. [func] Implement missing DNSSEC tests for * NOQNAME proof with wildcard answers. * NOWILDARD proof with NXDOMAIN. Cache and return NOQNAME with wildcard answers. 1556. [bug] nsupdate now treats all names as fully qualified. [RT #6427] 1555. [func] 'rrset-order cyclic' no longer has a random starting point per query. [RT #7572] 1554. [bug] dig, host, nslookup failed when no nameservers were specified in /etc/resolv.conf. [RT #8232] 1553. [bug] The windows socket code could stop accepting connections. [RT #10115] 1552. [bug] Accept NOTIFY requests from mapped masters if matched-mapped is set. [RT #10049] 1551. [port] Open "/dev/null" before calling chroot(). 1550. [port] Call tzset(), if available, before calling chroot(). 1549. [func] named-checkzone can now write out the zone contents in a easily parsable format (-D and -o). 1548. [bug] When parsing APL records it was possible to silently accept out of range ADDRESSFAMILY values. [RT #9979] 1547. [bug] Named wasted memory recording duplicate lame zone entries. [RT #9341] 1546. [bug] We were rejecting valid secure CNAME to negative answers. 1545. [bug] It was possible to leak memory if named was unable to bind to the specified transfer source and TSIG was being used. [RT #10120] 1544. [bug] Named would logged a single entry to a file despite it being over the specified size limit. 1543. [bug] Logging using "versions unlimited" did not work. 1542. [placeholder] 1541. [func] NSEC now uses new bitmap format. 1540. [bug] "rndc reload " was silently accepted. [RT #8934] 1539. [bug] Open UDP sockets for notify-source and transfer-source that use reserved ports at startup. [RT #9475] 1538. [placeholder] rt9997 1537. [func] New option "querylog". If set specify whether query logging is to be enabled or disabled at startup. 1536. [bug] Windows socket code failed to log a error description when returning ISC_R_UNEXPECTED. [RT #9998] 1535. [placeholder] 1534. [bug] Race condition when priming cache. [RT #9940] 1533. [func] Warn if both "recursion no;" and "allow-recursion" are active. [RT #4389] 1532. [port] netbsd: the configure test for requires . 1531. [port] AIX more libtool fixes. 1530. [bug] It was possible to trigger a INSIST() failure if a slave master file was removed at just the correct moment. [RT #9462] 1529. [bug] "notify explicit;" failed to log that NOTIFY messages were being sent for the zone. [RT #9442] 1528. [cleanup] Simplify some dns_name_ functions based on the deprecation of bitstring labels. 1527. [cleanup] Reduce the number of gettimeofday() calls without losing necessary timer granularity. 1526. [func] Implemented "additional section caching (or acache)", an internal cache framework for additional section content to improve response performance. Several configuration options were provided to control the behavior. 1525. [bug] dns_cache_create() could trigger a REQUIRE failure in isc_mem_put() during error cleanup. [RT #9360] 1524. [port] AIX needs to be able to resolve all symbols when creating shared libraries (--with-libtool). 1523. [bug] Fix race condition in rbtdb. [RT #9189] 1522. [bug] dns_db_findnode() relax the requirements on 'name'. [RT #9286] 1521. [bug] dns_view_createresolver() failed to check the result from isc_mem_create(). [RT #9294] 1520. [protocol] Add SSHFP (SSH Finger Print) type. 1519. [bug] dnssec-signzone:nsec_setbit() computed the wrong length of the new bitmap. 1518. [bug] dns_nsec_buildrdata(), and hence dns_nsec_build(), contained a off-by-one error when working out the number of octets in the bitmap. 1517. [port] Support for IPv6 interface scanning on HP/UX and TrueUNIX 5.1. 1516. [func] Roll the DNSSEC types to RRSIG, NSEC and DNSKEY. 1515. [func] Allow transfer source to be set in a server statement. [RT #6496] 1514. [bug] named: isc_hash_destroy() was being called too early. [RT #9160] 1513. [doc] Add "US" to root-delegation-only exclude list. 1512. [bug] Extend the delegation-only logging to return query type, class and responding nameserver. 1511. [bug] delegation-only was generating false positives on negative answers from sub-zones. 1510. [func] New view option "root-delegation-only". Apply delegation-only check to all TLDs and root. Note there are some TLDs that are NOT delegation only (e.g. DE, LV, US and MUSEUM) these can be excluded from the checks by using exclude. root-delegation-only exclude { "DE"; "LV"; "US"; "MUSEUM"; }; 1509. [bug] Hint zones should accept delegation-only. Forward zone should not accept delegation-only. 1508. [bug] Don't apply delegation-only checks to answers from forwarders. 1507. [bug] Handle BIND 8 style returns to NS queries to parents when making delegation-only checks. 1506. [bug] Wrong return type for dns_view_isdelegationonly(). 1505. [bug] Uninitialized rdataset in sdb. [RT #8750] 1504. [func] New zone type "delegation-only". 1503. [port] win32: install libeay32.dll outside of system32. 1502. [bug] nsupdate: adjust timeouts for UPDATE requests over TCP. 1501. [func] Allow TCP queue length to be specified via named.conf, tcp-listen-queue. 1500. [bug] host failed to lookup MX records. Also look up AAAA records. 1499. [bug] isc_random need to be seeded better if arc4random() is not used. 1498. [port] bsdos: 5.x support. 1497. [placeholder] 1496. [port] test for pthread_attr_setstacksize(). 1495. [cleanup] Replace hash functions with universal hash. 1494. [security] Turn on RSA BLINDING as a precaution. 1493. [placeholder] 1492. [cleanup] Preserve rwlock quota context when upgrading / downgrading. [RT #5599] 1491. [bug] dns_master_dump*() would produce extraneous $ORIGIN lines. [RT #6206] 1490. [bug] Accept reading state as well as working state in ns_client_next(). [RT #6813] 1489. [compat] Treat 'allow-update' on slave zones as a warning. [RT #3469] 1488. [bug] Don't override trust levels for glue addresses. [RT #5764] 1487. [bug] A REQUIRE() failure could be triggered if a zone was queued for transfer and the zone was then removed. [RT #6189] 1486. [bug] isc_print_snprintf() '%%' consumed one too many format characters. [RT #8230] 1485. [bug] gen failed to handle high type values. [RT #6225] 1484. [bug] The number of records reported after a AXFR was wrong. [RT #6229] 1483. [bug] dig axfr failed if the message id in the answer failed to match that in the request. Only the id in the first message is required to match. [RT #8138] 1482. [bug] named could fail to start if the kernel supports IPv6 but no interfaces are configured. Similarly for IPv4. [RT #6229] 1481. [bug] Refresh and stub queries failed to use masters keys if specified. [RT #7391] 1480. [bug] Provide replay protection for rndc commands. Full replay protection requires both rndc and named to be updated. Partial replay protection (limited exposure after restart) is provided if just named is updated. 1479. [bug] cfg_create_tuple() failed to handle out of memory cleanup. parse_list() would leak memory on syntax errors. 1478. [port] ifconfig.sh didn't account for other virtual interfaces. It now takes a optional argument to specify the first interface number. [RT #3907] 1477. [bug] memory leak using stub zones and TSIG. 1476. [placeholder] 1475. [port] Probe for old sprintf(). 1474. [port] Provide strtoul() and memmove() for platforms without them. 1473. [bug] create_map() and create_string() failed to handle out of memory cleanup. [RT #6813] 1472. [contrib] idnkit-1.0 from JPNIC, replaces mdnkit. 1471. [bug] libbind: updated to BIND 8.4.0. 1470. [bug] Incorrect length passed to snprintf. [RT #5966] 1469. [func] Log end of outgoing zone transfer at same level as the start of transfer is logged. [RT #4441] 1468. [func] Internal zones are no longer counted for 'rndc status'. [RT #4706] 1467. [func] $GENERATES now supports optional class and ttl. 1466. [bug] lwresd configuration errors resulted in memory and lock leaks. [RT #5228] 1465. [bug] isc_base64_decodestring() and isc_base64_tobuffer() failed to check that trailing bits were zero allowing some invalid base64 strings to be accepted. [RT #5397] 1464. [bug] Preserve "out of zone" data for outgoing zone transfers. [RT #5192] 1463. [bug] dns_rdata_from{wire,struct}() failed to catch bad NXT bit maps. [RT #5577] 1462. [bug] parse_sizeval() failed to check the token type. [RT #5586] 1461. [bug] Remove deadlock from rbtdb code. [RT #5599] 1460. [bug] inet_pton() failed to reject certain malformed IPv6 literals. 1459. [placeholder] 1458. [cleanup] sprintf() -> snprintf(). 1457. [port] Provide strlcat() and strlcpy() for platforms without them. 1456. [contrib] gen-data-queryperf.py from Stephane Bortzmeyer. 1455. [bug] missing from server grammar in doc/misc/options. [RT #5616] 1454. [port] Use getifaddrs() if available for interface scanning. --disable-getifaddrs to override. Glibc currently has a getifaddrs() that does not support IPv6. Use --enable-getifaddrs=glibc to force the use of this version under linux machines. 1453. [doc] ARM: $GENERATE example wasn't accurate. [RT #5298] 1452. [placeholder] 1451. [bug] rndc-confgen didn't exit with a error code for all failures. [RT #5209] 1450. [bug] Fetching expired glue failed under certain circumstances. [RT #5124] 1449. [bug] query_addbestns() didn't handle running out of memory gracefully. 1448. [bug] Handle empty wildcards labels. 1447. [bug] We were casting (unsigned int) to and from (void *). rdataset->private4 is now rdataset->privateuint4 to reflect a type change. 1446. [func] Implemented undocumented alternate transfer sources from BIND 8. See use-alt-transfer-source, alt-transfer-source and alt-transfer-source-v6. SECURITY: use-alt-transfer-source is ENABLED unless you are using views. This may cause a security risk resulting in accidental disclosure of wrong zone content if the master supplying different source content based on IP address. If you are not certain ISC recommends setting use-alt-transfer-source no; 1445. [bug] DNS_ADBFIND_STARTATROOT broke stub zones. This has been replaced with DNS_ADBFIND_STARTATZONE which causes the search to start using the closest zone. 1444. [func] dns_view_findzonecut2() allows you to specify if the cache should be searched for zone cuts. 1443. [func] Masters lists can now be specified and referenced in zone masters clauses and other masters lists. 1442. [func] New functions for manipulating port lists: dns_portlist_create(), dns_portlist_add(), dns_portlist_remove(), dns_portlist_match(), dns_portlist_attach() and dns_portlist_detach(). 1441. [func] It is now possible to tell dig to bind to a specific source port. 1440. [func] It is now possible to tell named to avoid using certain source ports (avoid-v4-udp-ports, avoid-v6-udp-ports). 1439. [bug] Named could return NOERROR with certain NOTIFY failures. Return NOTAUTH if the NOTIFY zone is not being served. 1438. [func] Log TSIG (if any) when logging NOTIFY requests. 1437. [bug] Leave space for stdio to work in. [RT #5033] 1436. [func] dns_zonemgr_resumexfrs() can be used to restart stalled transfers. 1435. [bug] zmgr_resume_xfrs() was being called read locked rather than write locked. zmgr_resume_xfrs() was not being called if the zone was being shutdown. 1434. [bug] "rndc reconfig" failed to initiate the initial zone transfer of new slave zones. 1433. [bug] named could trigger a REQUIRE failure if it could not get a file descriptor when attempting to write a master file. [RT #4347] 1432. [func] The advertised EDNS UDP buffer size can now be set via named.conf (edns-udp-size). 1431. [bug] isc_print_snprintf() "%s" with precision could walk off end of argument. [RT #5191] 1430. [port] linux: IPv6 interface scanning support. 1429. [bug] Prevent the cache getting locked to old servers. 1428. [placeholder] 1427. [bug] Race condition in adb with threaded build. 1426. [placeholder] 1425. [port] linux/libbind: define __USE_MISC when testing *_r() function prototypes in netdb.h. [RT #4921] 1424. [bug] EDNS version not being correctly printed. 1423. [contrib] queryperf: added A6 and SRV. 1422. [func] Log name/type/class when denying a query. [RT #4663] 1421. [func] Differentiate updates that don't succeed due to prerequisites (unsuccessful) vs other reasons (failed). 1420. [port] solaris: work around gcc optimizer bug. 1419. [port] openbsd: use /dev/arandom. [RT #4950] 1418. [bug] 'rndc reconfig' did not cause new slaves to load. 1417. [func] ID.SERVER/CHAOS is now a built in zone. See "server-id" for how to configure. 1416. [bug] Empty node should return NOERROR NODATA, not NXDOMAIN. [RT #4715] 1415. [func] DS TTL now derived from NS ttl. NXT TTL now derived from SOA MINIMUM. 1414. [func] Support for KSK flag. 1413. [func] Explicitly request the (re-)generation of DS records from keysets (dnssec-signzone -g). 1412. [func] You can now specify servers to be tried if a nameserver has IPv6 address and you only support IPv4 or the reverse. See dual-stack-servers. 1411. [bug] empty nodes should stop wildcard matches. [RT #4802] 1410. [func] Handle records that live in the parent zone, e.g. DS. 1409. [bug] DS should have attribute DNS_RDATATYPEATTR_DNSSEC. 1408. [bug] "make distclean" was not complete. [RT #4700] 1407. [bug] lfsr incorrectly implements the shift register. [RT #4617] 1406. [bug] dispatch initializes one of the LFSR's with a incorrect polynomial. [RT #4617] 1405. [func] Use arc4random() if available. 1404. [bug] libbind: ns_name_ntol() could overwrite a zero length buffer. 1403. [func] dnssec-signzone, dnssec-keygen, dnssec-makekeyset dnssec-signkey now report their version in the usage message. 1402. [cleanup] A6 has been moved to experimental and is no longer fully supported. 1401. [bug] adb wasn't clearing state when the timer expired. 1400. [bug] Block the addition of wildcard NS records by IXFR or UPDATE. [RT #3502] 1399. [bug] Use serial number arithmetic when testing SIG timestamps. [RT #4268] 1398. [doc] ARM: notify-also should have been also-notify. [RT #4345] 1397. [maint] J.ROOT-SERVERS.NET is now 192.58.128.30. 1396. [func] dnssec-signzone: adjust the default signing time by 1 hour to allow for clock skew. 1395. [port] OpenSSL 0.9.7 defines CRYPTO_LOCK_ENGINE but doesn't have a working implementation. [RT #4079] 1394. [func] It is now possible to check if a particular element is in a acl. Remove duplicate entries from the localnets acl. 1393. [port] Bind to individual IPv6 interfaces if IPV6_IPV6ONLY is not available in the kernel to prevent accidently listening on IPv4 interfaces. 1392. [bug] named-checkzone: update usage. 1391. [func] Add support for IPv6 scoped addresses in named. 1390. [func] host now supports ixfr. 1389. [bug] named could fail to rotate long log files. [RT #3666] 1388. [port] irix: check for sys/sysctl.h and NET_RT_IFLIST before defining HAVE_IFLIST_SYSCTL. [RT #3770] 1387. [bug] named could crash due to an access to invalid memory space (which caused an assertion failure) in incremental cleaning. [RT #3588] 1386. [bug] named-checkzone -z stopped on errors in a zone. [RT #3653] 1385. [bug] Setting serial-query-rate to 10 would trigger a REQUIRE failure. 1384. [bug] host was incompatible with BIND 8 in its exit code and in the output with the -l option. [RT #3536] 1383. [func] Track the serial number in a IXFR response and log if a mismatch occurs. This is a more specific error than "not exact". [RT #3445] 1382. [bug] make install failed with --enable-libbind. [RT #3656] 1381. [bug] named failed to correctly process answers that contained DNAME records where the resulting CNAME resulted in a negative answer. 1380. [func] 'rndc recursing' dump recursing queries to 'recursing-file = "named.recursing";'. 1379. [func] 'rndc status' now reports tcp and recursion quota states. 1378. [func] Improved positive feedback for 'rndc {reload|refresh}. 1377. [func] dns_zone_load{new}() now reports if the zone was loaded, queued for loading to up to date. 1376. [func] New function dns_zone_logc() to log to specified category. 1375. [func] 'rndc dumpdb' now dumps the adb cache along with the data cache. 1374. [func] dns_adb_dump() now logs the lame zones associated with each server. 1373. [bug] Recovery from expired glue failed under certain circumstances. 1372. [bug] named crashes with an assertion failure on exit when sharing the same port for listening and querying, and changing listening addresses several times. [RT #3509] 1371. [bug] notify-source-v6, transfer-source-v6 and query-source-v6 with explicit addresses and using the same ports as named was listening on could interfere with named's ability to answer queries sent to those addresses. 1370. [bug] dig '+[no]recurse' was incorrectly documented. 1369. [bug] Adding an NS record as the lexicographically last record in a secure zone didn't work. 1368. [func] remove support for bitstring labels. 1367. [func] Use response times to select forwarders. 1366. [contrib] queryperf usage was incomplete. Add '-h' for help. 1365. [func] "localhost" and "localnets" acls now include IPv6 addresses / prefixes. 1364. [func] Log file name when unable to open memory statistics and dump database files. [RT #3437] 1363. [func] Listen-on-v6 now supports specific addresses. 1362. [bug] remove IFF_RUNNING test when scanning interfaces. 1361. [func] log the reason for rejecting a server when resolving queries. 1360. [bug] --enable-libbind would fail when not built in the source tree for certain OS's. 1359. [security] Support patches OpenSSL libraries. http://www.cert.org/advisories/CA-2002-23.html 1358. [bug] It was possible to trigger a INSIST when debugging large dynamic updates. [RT #3390] 1357. [bug] nsupdate was extremely wasteful of memory. 1356. [tuning] Reduce the number of events / quantum for zone tasks. 1355. [bug] Fix DNSSEC wildcard proof for CNAME/DNAME. 1354. [doc] lwres man pages had illegal nroff. 1353. [contrib] sdb/ldap to version 0.9. 1352. [bug] dig, host, nslookup when falling back to TCP use the current search entry (if any). [RT #3374] 1351. [bug] lwres_getipnodebyname() returned the wrong name when given a IPv4 literal, af=AF_INET6 and AI_MAPPED was set. 1350. [bug] dns_name_fromtext() failed to handle too many labels gracefully. 1349. [security] Minimum OpenSSL version now 0.9.6e (was 0.9.5a). http://www.cert.org/advisories/CA-2002-23.html 1348. [port] win32: Rewrote code to use I/O Completion Ports in socket.c and eliminating a host of socket errors. Performance is enhanced. 1347. [placeholder] 1346. [placeholder] 1345. [port] Use a explicit -Wformat with gcc. Not all versions include it in -Wall. 1344. [func] Log if the serial number on the master has gone backwards. If you have multiple machines specified in the masters clause you may want to set 'multi-master yes;' to suppress this warning. 1343. [func] Log successful notifies received (info). Adjust log level for failed notifies to notice. 1342. [func] Log remote address with TCP dispatch failures. 1341. [func] Allow a rate limiter to be stalled. 1340. [bug] Delay and spread out the startup refresh load. 1339. [func] dig, host and nslookup now use IP6.ARPA for nibble lookups. Bit string lookups are no longer attempted. 1338. [placeholder] 1337. [placeholder] 1336. [func] Nibble lookups under IP6.ARPA are now supported by dns_byaddr_create(). dns_byaddr_createptrname() is deprecated, use dns_byaddr_createptrname2() instead. 1335. [bug] When performing a nonexistence proof, the validator should discard parent NXTs from higher in the DNS. 1334. [bug] When signing/verifying rdatasets, duplicate rdatas need to be suppressed. 1333. [contrib] queryperf now reports a summary of returned rcodes (-c), rcodes are printed in mnemonic form (-v). 1332. [func] Report the current serial with periodic commits when rolling forward the journal. 1331. [func] Generate DNSSEC wildcard proofs. 1330. [bug] When processing events (non-threaded) only allow the task one chance to use to use its quantum. 1329. [func] named-checkzone will now check if nameservers that appear to be IP addresses. Available modes "fail", "warn" (default) and "ignore" the results of the check. 1328. [bug] The validator could incorrectly verify an invalid negative proof. 1327. [bug] The validator would incorrectly mark data as insecure when seeing a bogus signature before a correct signature. 1326. [bug] DNAME/CNAME signatures were not being cached when validation was not being performed. [RT #3284] 1325. [bug] If the tcpquota was exhausted it was possible to to trigger a INSIST() failure. 1324. [port] darwin: ifconfig.sh now supports darwin. 1323. [port] linux: Slackware 4.0 needs . [RT #3205] 1322. [bug] dnssec-signzone usage message was misleading. 1321. [bug] If the last RRset in a zone is glue, dnssec-signzone would incorrectly duplicate its output and sign it. 1320. [doc] query-source-v6 was missing from options section. [RT #3218] 1319. [func] libbind: log attempts to exploit #1318. 1318. [bug] libbind: Remote buffer overrun. 1317. [port] libbind: TrueUNIX 5.1 does not like __align as a element name. 1316. [bug] libbind: gethostans() could get out of sync parsing the response if there was a very long CNAME chain. 1315. [bug] Options should apply to the internal _bind view. 1314. [port] Handle ECONNRESET from sendmsg() [unix]. 1313. [func] Query log now says if the query was signed (S) or if EDNS was used (E). 1312. [func] Log TSIG key used w/ outgoing zone transfers. 1311. [bug] lwres_getrrsetbyname leaked memory. [RT #3159] 1310. [bug] 'rndc stop' failed to cause zones to be flushed sometimes. [RT #3157] 1309. [func] Log that a zone transfer was covered by a TSIG. 1308. [func] DS (delegation signer) support. 1307. [bug] nsupdate: allow white space base64 key data. 1306. [bug] Badly encoded LOC record when the size, horizontal precision or vertical precision was 0.1m. 1305. [bug] Document that internal zones are included in the rndc status results. 1304. [func] New function: dns_zone_name(). 1303. [func] Option 'flush-zones-on-shutdown ;'. 1302. [func] Extended rndc dumpdb to support dumping of zones and view selection: 'dumpdb [-all|-zones|-cache] [view]'. 1301. [func] New category 'update-security'. 1300. [port] Compaq Trucluster support. 1299. [bug] Set AI_ADDRCONFIG when looking up addresses via getaddrinfo() (affects dig, host, nslookup, rndc and nsupdate). 1298. [bug] The CINCLUDES macro in lib/dns/sec/dst/Makefile could be left with a trailing "\" after configure has been run. 1297. [port] linux: make handling EINVAL from socket() no longer conditional on #ifdef LINUX. 1296. [bug] isc_log_closefilelogs() needed to lock the log context. 1295. [bug] isc_log_setdebuglevel() needed to lock the log context. 1294. [func] libbind: no longer attempts bit string labels for IPv6 reverse resolution. Try IP6.ARPA then IP6.INT for nibble style resolution. 1293. [func] Entropy can now be retrieved from EGDs. [RT #2438] 1292. [func] Enable IPv6 support when using ioctl style interface scanning and OS supports SIOCGLIFADDR using struct if_laddrreq. 1291. [func] Enable IPv6 support when using sysctl style interface scanning. 1290. [func] "dig axfr" now reports the number of messages as well as the number of records. 1289. [port] See if -ldl is required for OpenSSL? [RT #2672] 1288. [bug] Adjusted REQUIRE's in lib/dns/name.c to better reflect written requirements. 1287. [bug] REQUIRE that DNS_DBADD_MERGE only be set when adding a rdataset to a zone db in the rbtdb implementation of addrdataset. 1286. [bug] dns_name_downcase() enforce requirement that target != NULL or name->buffer != NULL. 1285. [func] lwres: probe the system to see what address families are currently in use. 1284. [bug] The RTT estimate on unused servers was not aged. [RT #2569] 1283. [func] Use "dataready" accept filter if available. 1282. [port] libbind: hpux 11.11 interface scanning. 1281. [func] Log zone when unable to get private keys to update zone. Log zone when NXT records are missing from secure zone. 1280. [bug] libbind: escape '(' and ')' when converting to presentation form. 1279. [port] Darwin uses (unsigned long) for size_t. [RT #2590] 1278. [func] dig: now supports +[no]cl +[no]ttlid. 1277. [func] You can now create your own customized printing styles: dns_master_stylecreate() and dns_master_styledestroy(). 1276. [bug] libbind: const pointer conflicts in res_debug.c. 1275. [port] libbind: hpux: treat all hpux systems as BIG_ENDIAN. 1274. [bug] Memory leak in lwres_gnbarequest_parse(). 1273. [port] libbind: solaris: 64 bit binary compatibility. 1272. [contrib] Berkeley DB 4.0 sdb implementation from Nuno Miguel Rodrigues . 1271. [bug] "recursion available: {denied,approved}" was too confusing. 1270. [bug] Check that system inet_pton() and inet_ntop() support AF_INET6. 1269. [port] Openserver: ifconfig.sh support. 1268. [port] Openserver: the value FD_SETSIZE depends on whether is included or not. Be consistent. 1267. [func] isc_file_openunique() now creates file using mode 0666 rather than 0600. 1266. [bug] ISC_LINK_INIT, ISC_LINK_UNLINK, ISC_LIST_DEQUEUE, __ISC_LINK_UNLINKUNSAFE and __ISC_LIST_DEQUEUEUNSAFE are not C++ compatible, use *_TYPE versions instead. 1265. [bug] libbind: LINK_INIT and UNLINK were not compatible with C++, use LINK_INIT_TYPE and UNLINK_TYPE instead. 1264. [placeholder] 1263. [bug] Reference after free error if dns_dispatchmgr_create() failed. 1262. [bug] ns_server_destroy() failed to set *serverp to NULL. 1261. [func] libbind: ns_sign2() and ns_sign_tcp() now provide support for compressed TSIG owner names. 1260. [func] libbind: res_update can now update IPv6 servers, new function res_findzonecut2(). 1259. [bug] libbind: get_salen() IPv6 support was broken for OSs w/o sa_len. 1258. [bug] libbind: res_nametotype() and res_nametoclass() were broken. 1257. [bug] Failure to write pid-file should not be fatal on reload. [RT #2861] 1256. [contrib] 'queryperf' now has EDNS (-e) + DNSSEC DO (-D) support. 1255. [bug] When verifying that an NXT proves nonexistence, check the rcode of the message and only do the matching NXT check. That is, for NXDOMAIN responses, check that the name is in the range between the NXT owner and next name, and for NOERROR NODATA responses, check that the type is not present in the NXT bitmap. 1254. [func] preferred-glue option from BIND 8.3. 1253. [bug] The dnssec system test failed to remove the correct files. 1252. [bug] Dig, host and nslookup were not checking the address the answer was coming from against the address it was sent to. [RT #2692] 1251. [port] win32: a make file contained absolute version specific references. 1250. [func] Nsupdate will report the address the update was sent to. 1249. [bug] Missing masters clause was not handled gracefully. [RT #2703] 1248. [bug] DESTDIR was not being propagated between makes. 1247. [bug] Don't reset the interface index for link/site local addresses. [RT #2576] 1246. [func] New functions isc_sockaddr_issitelocal(), isc_sockaddr_islinklocal(), isc_netaddr_issitelocal() and isc_netaddr_islinklocal(). 1245. [bug] Treat ENOBUFS, ENOMEM and ENFILE as soft errors for accept(). 1244. [bug] Receiving a TCP message from a blackhole address would prevent further messages being received over that interface. 1243. [bug] It was possible to trigger a REQUIRE() in dns_message_findtype(). [RT #2659] 1242. [bug] named-checkzone failed if a journal existed. [RT #2657] 1241. [bug] Drop received UDP messages with a zero source port as these are invariably forged. [RT #2621] 1240. [bug] It was possible to leak zone references by specifying an incorrect zone to rndc. 1239. [bug] Under certain circumstances named could continue to use a name after it had been freed triggering INSIST() failures. [RT #2614] 1238. [bug] It is possible to lockup the server when shutting down if notifies were being processed. [RT #2591] 1237. [bug] nslookup: "set q=type" failed. 1236. [bug] dns_rdata{class,type}_fromtext() didn't handle non NULL terminated text regions. [RT #2588] 1235. [func] Report 'out of memory' errors from openssl. 1234. [bug] contrib/sdb: 'zonetodb' failed to call dns_result_register(). DNS_R_SEENINCLUDE should not be fatal. 1233. [bug] The flags field of a KEY record can be expressed in hex as well as decimal. 1232. [bug] unix/errno2result() didn't handle EADDRNOTAVAIL. 1231. [port] HPUX 11.11 recvmsg() can return spurious EADDRNOTAVAIL. 1230. [bug] isccc_cc_isreply() and isccc_cc_isack() were broken. 1229. [bug] named would crash if it received a TSIG signed query as part of an AXFR response. [RT #2570] 1228. [bug] 'make install' did not depend on 'make all'. [RT #2559] 1227. [bug] dns_lex_getmastertoken() now returns ISC_R_BADNUMBER if a number was expected and some other token was found. [RT #2532] 1226. [func] Use EDNS for zone refresh queries. [RT #2551] 1225. [func] dns_message_setopt() no longer requires that dns_message_renderbegin() to have been called. 1224. [bug] 'rrset-order' and 'sortlist' should be additive not exclusive. 1223. [func] 'rrset-order' partially works 'cyclic' and 'random' are supported. 1222. [bug] Specifying 'port *' did not always result in a system selected (non-reserved) port being used. [RT #2537] 1221. [bug] Zone types 'master', 'slave' and 'stub' were not being compared case insensitively. [RT #2542] 1220. [func] Support for APL rdata type. 1219. [func] Named now reports the TSIG extended error code when signature verification fails. [RT #1651] 1218. [bug] Named incorrectly returned SERVFAIL rather than NOTAUTH when there was a TSIG BADTIME error. [RT #2519] 1217. [func] Report locations of previous key definition when a duplicate is detected. 1216. [bug] Multiple server clauses for the same server were not reported. [RT #2514] 1215. [port] solaris: add support to ifconfig.sh for x86 2.5.1 1214. [bug] Win32: isc_file_renameunique() could leave zero length files behind. 1213. [func] Report view associated with client if it is not a standard view (_default or _bind). 1212. [port] libbind: 64k answer buffers were causing stack space to be exceeded for certain OS. Use heap space instead. 1211. [bug] dns_name_fromtext() incorrectly handled certain valid octal bitlabels. [RT #2483] 1210. [bug] libbind: getnameinfo() failed to lookup IPv4 mapped / compatible addresses. [RT #2461] 1209. [bug] Dig, host, nslookup were not checking the message ids on the responses. [RT #2454] 1208. [bug] dns_master_load*() failed to log a error message if an error was detected when parsing the owner name of a record. [RT #2448] 1207. [bug] libbind: getaddrinfo() could call freeaddrinfo() with an invalid pointer. 1206. [bug] SERVFAIL and NOTIMP responses to an EDNS query should trigger a non-EDNS retry. 1205. [bug] OPT, TSIG and TKEY cannot be used to set the "class" of the message. [RT #2449] 1204. [bug] libbind: res_nupdate() failed to update the name server addresses before sending the update. 1203. [func] Report locations of previous acl and zone definitions when a duplicate is detected. 1202. [func] New functions: cfg_obj_line() and cfg_obj_file(). 1201. [bug] Require that if 'callbacks' is passed to dns_rdata_fromtext(), callbacks->error and callbacks->warn are initialized. 1200. [bug] Log 'errno' that we are unable to convert to isc_result_t. [RT #2404] 1199. [doc] ARM reference to RFC 2157 should have been RFC 1918. [RT #2436] 1198. [bug] OPT printing style was not consistent with the way the header fields are printed. The DO bit was not reported if set. Report if any of the MBZ bits are set. 1197. [bug] Attempts to define the same acl multiple times were not detected. 1196. [contrib] update mdnkit to 2.2.3. 1195. [bug] Attempts to redefine builtin acls should be caught. [RT #2403] 1194. [bug] Not all duplicate zone definitions were being detected at the named.conf checking stage. [RT #2431] 1193. [bug] dig +besteffort parsing didn't handle packet truncation. dns_message_parse() has new flag DNS_MESSAGE_IGNORETRUNCATION. 1192. [bug] The seconds fields in LOC records were restricted to three decimal places. More decimal places should be allowed but warned about. 1191. [bug] A dynamic update removing the last non-apex name in a secure zone would fail. [RT #2399] 1190. [func] Add the "rndc freeze" and "rndc unfreeze" commands. [RT #2394] 1189. [bug] On some systems, malloc(0) returns NULL, which could cause the caller to report an out of memory error. [RT #2398] 1188. [bug] Dynamic updates of a signed zone would fail if some of the zone private keys were unavailable. 1187. [bug] named was incorrectly returning DNSSEC records in negative responses when the DO bit was not set. 1186. [bug] isc_hex_tobuffer(,,length = 0) failed to unget the EOL token when reading to end of line. 1185. [bug] libbind: don't assume statp->_u._ext.ext is valid unless RES_INIT is set when calling res_*init(). 1184. [bug] libbind: call res_ndestroy() if RES_INIT is set when res_*init() is called. 1183. [bug] Handle ENOSR error when writing to the internal control pipe. [RT #2395] 1182. [bug] The server could throw an assertion failure when constructing a negative response packet. 1181. [func] Add the "key-directory" configuration statement, which allows the server to look for online signing keys in alternate directories. 1180. [func] dnssec-keygen should always generate keys with protocol 3 (DNSSEC), since it's less confusing that way. 1179. [func] Add SIG(0) support to nsupdate. 1178. [bug] Follow and cache (if appropriate) A6 and other data chains to completion in the additional section. 1177. [func] Report view when loading zones if it is not a standard view (_default or _bind). [RT #2270] 1176. [doc] Document that allow-v6-synthesis is only performed for clients that are supplied recursive service. [RT #2260] 1175. [bug] named-checkzone and named-checkconf failed to call dns_result_register() at startup which could result in runtime exceptions when printing "out of memory" errors. [RT #2335] 1174. [bug] Win32: add WSAECONNRESET to the expected errors from connect(). [RT #2308] 1173. [bug] Potential memory leaks in isc_log_create() and isc_log_settag(). [RT #2336] 1172. [doc] Add CERT, GPOS, KX, NAPTR, NSAP, PX and TXT to table of RR types in ARM. 1171. [func] Added function isc_region_compare(), updated files in lib/dns to use this function instead of local one. 1170. [bug] Don't attempt to print the token when a I/O error occurs when parsing named.conf. [RT #2275] 1169. [func] Identify recursive queries in the query log. 1168. [bug] Empty also-notify clauses were not handled. [RT #2309] 1167. [contrib] nslint-2.1a3 (from author). 1166. [bug] "Not Implemented" should be reported as NOTIMP, not NOTIMPL. [RT #2281] 1165. [bug] We were rejecting notify-source{-v6} in zone clauses. 1164. [bug] Empty masters clauses in slave / stub zones were not handled gracefully. [RT #2262] 1163. [func] isc_time_formattimestamp() now includes the year. 1162. [bug] The allow-notify option was not accepted in slave zone statements. 1161. [bug] named-checkzone looped on unbalanced brackets. [RT #2248] 1160. [bug] Generating Diffie-Hellman keys longer than 1024 bits could fail. [RT #2241] 1159. [bug] MD and MF are not permitted to be loaded by RFC1123. 1158. [func] Report the client's address when logging notify messages. 1157. [func] match-clients and match-destinations now accept keys. [RT #2045] 1156. [port] The configure test for strsep() incorrectly succeeded on certain patched versions of AIX 4.3.3. [RT #2190] 1155. [func] Recover from master files being removed from under us. 1154. [bug] Don't attempt to obtain the netmask of a interface if there is no address configured. [RT #2176] 1153. [func] 'rndc {stop|halt} -p' now reports the process id of the instance of named being shutdown. 1152. [bug] libbind: read buffer overflows. 1151. [bug] nslookup failed to check that the arguments to the port, timeout, and retry options were valid integers and in range. [RT #2099] 1150. [bug] named incorrectly accepted TTL values containing plus or minus signs, such as 1d+1h-1s. 1149. [func] New function isc_parse_uint32(). 1148. [func] 'rndc-confgen -a' now provides positive feedback. 1147. [func] Set IPV6_V6ONLY on IPv6 sockets if supported by the OS. listen-on-v6 { any; }; should no longer result in IPv4 queries be accepted. Similarly control { inet :: ... }; should no longer result in IPv4 connections being accepted. This can be overridden at compile time by defining ISC_ALLOW_MAPPED=1. 1146. [func] Allow IPV6_IPV6ONLY to be set/cleared on a socket if supported by the OS by a new function isc_socket_ipv6only(). 1145. [func] "host" no longer reports a NOERROR/NODATA response by printing nothing. [RT #2065] 1144. [bug] rndc-confgen would crash if both the -a and -t options were specified. [RT #2159] 1143. [bug] When a trusted-keys statement was present and named was built without crypto support, it would leak memory. 1142. [bug] dnssec-signzone would fail to delete temporary files in some failure cases. [RT #2144] 1141. [bug] When named rejected a control message, it would leak a file descriptor and memory. It would also fail to respond, causing rndc to hang. [RT #2139, #2164] 1140. [bug] rndc-confgen did not accept IPv6 addresses as arguments to the -s option. [RT #2138] 1139. [func] It is now possible to flush a given name from the cache(s) via 'rndc flushname name [view]'. [RT #2051] 1138. [func] It is now possible to flush a given name from the cache by calling the new function dns_cache_flushname(). 1137. [func] It is now possible to flush a given name from the ADB by calling the new function dns_adb_flushname(). 1136. [bug] CNAME records synthesized from DNAMEs did not have a TTL of zero as required by RFC2672. [RT #2129] 1135. [func] You can now override the default syslog() facility for named/lwresd at compile time. [RT #1982] 1134. [bug] Multi-threaded servers could deadlock in ferror() when reloading zone files. [RT #1951, #1998] 1133. [bug] IN6_IS_ADDR_LOOPBACK was not portably defined on platforms without IN6_IS_ADDR_LOOPBACK. [RT #2106] 1132. [func] Improve UPDATE prerequisite failure diagnostic messages. 1131. [bug] The match-destinations view option did not work with IPv6 destinations. [RT #2073, #2074] 1130. [bug] Log messages reporting an out-of-range serial number did not include the out-of-range number but the following token. [RT #2076] 1129. [bug] Multi-threaded servers could crash under heavy resolution load due to a race condition. [RT #2018] 1128. [func] sdb drivers can now provide RR data in either text or wire format, the latter using the new functions dns_sdb_putrdata() and dns_sdb_putnamedrdata(). 1127. [func] rndc: If the server to contact has multiple addresses, try all of them. 1126. [bug] The server could access a freed event if shut down while a client start event was pending delivery. [RT #2061] 1125. [bug] rndc: -k option was missing from usage message. [RT #2057] 1124. [doc] dig: +[no]dnssec, +[no]besteffort and +[no]fail are now documented. [RT #2052] 1123. [bug] dig +[no]fail did not match description. [RT #2052] 1122. [tuning] Resolution timeout reduced from 90 to 30 seconds. [RT #2046] 1121. [bug] The server could attempt to access a NULL zone table if shut down while resolving. [RT #1587, #2054] 1120. [bug] Errors in options were not fatal. [RT #2002] 1119. [func] Added support in Win32 for NTFS file/directory ACL's for access control. 1118. [bug] On multi-threaded servers, a race condition could cause an assertion failure in resolver.c during resolver shutdown. [RT #2029] 1117. [port] The configure check for in6addr_loopback incorrectly succeeded on AIX 4.3 when compiling with -O2 because the test code was optimized away. [RT #2016] 1116. [bug] Setting transfers in a server clause, transfers-in, or transfers-per-ns to a value greater than 2147483647 disabled transfers. [RT #2002] 1115. [func] Set maximum values for cleaning-interval, heartbeat-interval, interface-interval, max-transfer-idle-in, max-transfer-idle-out, max-transfer-time-in, max-transfer-time-out, statistics-interval of 28 days and sig-validity-interval of 3660 days. [RT #2002] 1114. [port] Ignore more accept() errors. [RT #2021] 1113. [bug] The allow-update-forwarding option was ignored when specified in a view. [RT #2014] 1112. [placeholder] 1111. [bug] Multi-threaded servers could deadlock processing recursive queries due to a locking hierarchy violation in adb.c. [RT #2017] 1110. [bug] dig should only accept valid abbreviations of +options. [RT #2003] 1109. [bug] nsupdate accepted illegal ttl values. 1108. [bug] On Win32, rndc was hanging when named was not running due to failure to select for exceptional conditions in select(). [RT #1870] 1107. [bug] nsupdate could catch an assertion failure if an invalid domain name was given as the argument to the "zone" command. 1106. [bug] After seeing an out of range TTL, nsupdate would treat all TTLs as out of range. [RT #2001] 1105. [port] OpenUNIX 8 enable threads by default. [RT #1970] 1104. [bug] Invalid arguments to the transfer-format option could cause an assertion failure. [RT #1995] 1103. [port] OpenUNIX 8 support (ifconfig.sh). [RT #1970] 1102. [doc] Note that query logging is enabled by directing the queries category to a channel. 1101. [bug] Array bounds read error in lwres_gai_strerror. 1100. [bug] libbind: DNSSEC key ids were computed incorrectly. 1099. [cleanup] libbind: defining REPORT_ERRORS in lib/bind/dst caused compile time errors. 1098. [bug] libbind: HMAC-MD5 key files are now mode 0600. 1097. [func] libbind: RES_PRF_TRUNC for dig. 1096. [func] libbind: "DNSSEC OK" (DO) support. 1095. [func] libbind: resolver option: no-tld-query. disables trying unqualified as a tld. no_tld_query is also supported for FreeBSD compatibility. 1094. [func] libbind: add support gcc's format string checking. 1093. [doc] libbind: miscellaneous nroff fixes. 1092. [bug] libbind: get*by*() failed to check if res_init() had been called. 1091. [bug] libbind: misplaced va_end(). 1090. [bug] libbind: dns_ho.c:add_hostent() was not returning the amount of memory consumed resulting in garbage address being returned. Alignment calculations were wasting space. We weren't suppressing duplicate addresses. 1089. [func] libbind: inet_{cidr,net}_{pton,ntop}() now have IPv6 support. 1088. [port] libbind: MPE/iX C.70 (incomplete) 1087. [bug] libbind: struct __res_state too large on 64 bit arch. 1086. [port] libbind: sunos: old sprintf. 1085. [port] libbind: solaris: sys_nerr and sys_errlist do not exist when compiling in 64 bit mode. 1084. [cleanup] libbind: gai_strerror() rewritten. 1083. [bug] The default control channel listened on the wildcard address, not the loopback as documented. [RT #1975] 1082. [bug] The -g option to named incorrectly caused logging to be sent to syslog in addition to stderr. [RT #1974] 1081. [bug] Multicast queries were incorrectly identified based on the source address, not the destination address. 1080. [bug] BIND 8 compatibility: accept bare IP prefixes as the second element of a two-element top level sort list statement. [RT #1964] 1079. [bug] BIND 8 compatibility: accept bare elements at top level of sort list treating them as if they were a single element list. [RT #1963] 1078. [bug] We failed to correct bad tv_usec values in one case. [RT #1966] 1077. [func] Do not accept further recursive clients when the total number of recursive lookups being processed exceeds max-recursive-clients, even if some of the lookups are internally generated. [RT #1915, #1938] 1076. [bug] A badly defined global key could trigger an assertion on load/reload if views were used. [RT #1947] 1075. [bug] Out-of-range network prefix lengths were not reported. [RT #1954] 1074. [bug] Running out of memory in dump_rdataset() could cause an assertion failure. [RT #1946] 1073. [bug] The ADB cache cleaning should also be space driven. [RT #1915, #1938] 1072. [bug] The TCP client quota could be exceeded when recursion occurred. [RT #1937] 1071. [bug] Sockets listening for TCP DNS connections specified an excessive listen backlog. [RT #1937] 1070. [bug] Copy DNSSEC OK (DO) to response as specified by draft-ietf-dnsext-dnssec-okbit-03.txt. 1069. [placeholder] 1068. [bug] errno could be overwritten by catgets(). [RT #1921] 1067. [func] Allow quotas to be soft, isc_quota_soft(). 1066. [bug] Provide a thread safe wrapper for strerror(). [RT #1689] 1065. [func] Runtime support to select new / old style interface scanning using ioctls. 1064. [bug] Do not shut down active network interfaces if we are unable to scan the interface list. [RT #1921] 1063. [bug] libbind: "make install" was failing on IRIX. [RT #1919] 1062. [bug] If the control channel listener socket was shut down before server exit, the listener object could be freed twice. [RT #1916] 1061. [bug] If periodic cache cleaning happened to start while cleaning due to reaching the configured maximum cache size was in progress, the server could catch an assertion failure. [RT #1912] 1060. [func] Move refresh, stub and notify UDP retry processing into dns_request. 1059. [func] dns_request now support will now retry UDP queries, dns_request_createvia2() and dns_request_createraw2(). 1058. [func] Limited lifetime ticker timers are now available, isc_timertype_limited. 1057. [bug] Reloading the server after adding a "file" clause to a zone statement could cause the server to crash due to a typo in change 1016. 1056. [bug] Rndc could catch an assertion failure on SIGINT due to an uninitialized variable. [RT #1908] 1055. [func] Version and hostname queries can now be disabled using "version none;" and "hostname none;", respectively. 1054. [bug] On Win32, cfg_categories and cfg_modules need to be exported from the libisccfg DLL. 1053. [bug] Dig did not increase its timeout when receiving AXFRs unless the +time option was used. [RT #1904] 1052. [bug] Journals were not being created in binary mode resulting in "journal format not recognized" error under Win32. [RT #1889] 1051. [bug] Do not ignore a network interface completely just because it has a noncontiguous netmask. Instead, omit it from the localnets ACL and issue a warning. [RT #1891] 1050. [bug] Log messages reporting malformed IP addresses in address lists such as that of the forwarders option failed to include the correct error code, file name, and line number. [RT #1890] 1049. [func] "pid-file none;" will disable writing a pid file. [RT #1848] 1048. [bug] Servers built with -DISC_MEM_USE_INTERNAL_MALLOC=1 didn't work. 1047. [bug] named was incorrectly refusing all requests signed with a TSIG key derived from an unsigned TKEY negotiation with a NOERROR response. [RT #1886] 1046. [bug] The help message for the --with-openssl configure option was inaccurate. [RT #1880] 1045. [bug] It was possible to skip saving glue for a nameserver for a stub zone. 1044. [bug] Specifying allow-transfer, notify-source, or notify-source-v6 in a stub zone was not treated as an error. 1043. [bug] Specifying a transfer-source or transfer-source-v6 option in the zone statement for a master zone was not treated as an error. [RT #1876] 1042. [bug] The "config" logging category did not work properly. [RT #1873] 1041. [bug] Dig/host/nslookup could catch an assertion failure on SIGINT due to an uninitialized variable. [RT #1867] 1040. [bug] Multiple listen-on-v6 options with different ports were not accepted. [RT #1875] 1039. [bug] Negative responses with CNAMEs in the answer section were cached incorrectly. [RT #1862] 1038. [bug] In servers configured with a tkey-domain option, TKEY queries with an owner name other than the root could cause an assertion failure. [RT #1866, #1869] 1037. [bug] Negative responses whose authority section contain SOA or NS records whose owner names are not equal equal to or parents of the query name should be rejected. [RT #1862] 1036. [func] Silently drop requests received via multicast as long as there is no final multicast DNS standard. 1035. [bug] If we respond to multicast queries (which we currently do not), respond from a unicast address as specified in RFC 1123. [RT #137] 1034. [bug] Ignore the RD bit on multicast queries as specified in RFC 1123. [RT #137] 1033. [bug] Always respond to requests with an unsupported opcode with NOTIMP, even if we don't have a matching view or cannot determine the class. 1032. [func] hostname.bind/txt/chaos now returns the name of the machine hosting the nameserver. This is useful in diagnosing problems with anycast servers. 1031. [bug] libbind.a: isc__gettimeofday() infinite recursion. [RT #1858] 1030. [bug] On systems with no resolv.conf file, nsupdate exited with an error rather than defaulting to using the loopback address. [RT #1836] 1029. [bug] Some named.conf errors did not cause the loading of the configuration file to return a failure status even though they were logged. [RT #1847] 1028. [bug] On Win32, dig/host/nslookup looked for resolv.conf in the wrong directory. [RT #1833] 1027. [bug] RRs having the reserved type 0 should be rejected. [RT #1471] 1026. [placeholder] 1025. [bug] Don't use multicast addresses to resolve iterative queries. [RT #101] 1024. [port] Compilation failed on HP-UX 11.11 due to incompatible use of the SIOCGLIFCONF macro name. [RT #1831] 1023. [func] Accept hints without TTLs. 1022. [bug] Don't report empty root hints as "extra data". [RT #1802] 1021. [bug] On Win32, log message timestamps were one month later than they should have been, and the server would exhibit unspecified behavior in December. 1020. [bug] IXFR log messages did not distinguish between true IXFRs, AXFR-style IXFRs, and mere version polls. [RT #1811] 1019. [bug] The value of the lame-ttl option was limited to 18000 seconds, not 1800 seconds as documented. [RT #1803] 1018. [bug] The default log channel was not always initialized correctly. [RT #1813] 1017. [bug] When specifying TSIG keys to dig and nsupdate using the -k option, they must be HMAC-MD5 keys. [RT #1810] 1016. [bug] Slave zones with no backup file were re-transferred on every server reload. 1015. [bug] Log channels that had a "versions" option but no "size" option failed to create numbered log files. [RT #1783] 1014. [bug] Some queries would cause statistics counters to increment more than once or not at all. [RT #1321] 1013. [bug] It was possible to cancel a query twice when marking a server as bogus or by having a blackhole acl. [RT #1776] 1012. [bug] The -p option to named did not behave as documented. 1011. [cleanup] Removed isc_dir_current(). 1010. [bug] The server could attempt to execute a command channel command after initiating server shutdown, causing an assertion failure. [RT #1766] 1009. [port] OpenUNIX 8 support. [RT #1728] 1008. [port] libtool.m4, ltmain.sh from libtool-1.4.2. 1007. [port] config.guess, config.sub from autoconf-2.52. 1006. [bug] If a KEY RR was found missing during DNSSEC validation, an assertion failure could subsequently be triggered in the resolver. [RT #1763] 1005. [bug] Don't copy nonzero RCODEs from request to response. [RT #1765] 1004. [port] Deal with recvfrom() returning EHOSTDOWN. [RT #1770] 1003. [func] Add the +retry option to dig. 1002. [bug] When reporting an unknown class name in named.conf, including the file name and line number. [RT #1759] 1001. [bug] win32 socket code doio_recv was not catching a WSACONNRESET error when a client was timing out the request and closing its socket. [RT #1745] 1000. [bug] BIND 8 compatibility: accept "HESIOD" as an alias for class "HS". [RT #1759] 999. [func] "rndc retransfer zone [class [view]]" added. [RT #1752] 998. [func] named-checkzone now has arguments to specify the chroot directory (-t) and working directory (-w). [RT #1755] 997. [func] Add support for RSA-SHA1 keys (RFC3110). 996. [func] Issue warning if the configuration filename contains the chroot path. 995. [bug] dig, host, nslookup: using a raw IPv6 address as a target address should be fatal on a IPv4 only system. 994. [func] Treat non-authoritative responses to queries for type NS as referrals even if the NS records are in the answer section, because BIND 8 servers incorrectly send them that way. This is necessary for DNSSEC validation of the NS records of a secure zone to succeed when the parent is a BIND 8 server. [RT #1706] 993. [func] dig: -v now reports the version. 992. [doc] dig: ~/.digrc is now documented. 991. [func] Lower UDP refresh timeout messages to level debug 1. 990. [bug] The rndc-confgen man page was not installed. 989. [bug] Report filename if $INCLUDE fails for file related errors. [RT #1736] 988. [bug] 'additional-from-auth no;' did not work reliably in the case of queries answered from the cache. [RT #1436] 987. [bug] "dig -help" didn't show "+[no]stats". 986. [bug] "dig +noall" failed to clear stats and command printing. 985. [func] Consider network interfaces to be up iff they have a nonzero IP address rather than based on the IFF_UP flag. [RT #1160] 984. [bug] Multi-threading should be enabled by default on Solaris 2.7 and newer, but it wasn't. 983. [func] The server now supports generating IXFR difference sequences for non-dynamic zones by comparing zone versions, when enabled using the new config option "ixfr-from-differences". [RT #1727] 982. [func] If "memstatistics-file" is set in options the memory statistics will be written to it. 981. [func] The dnssec tools can now take multiple '-r randomfile' arguments. 980. [bug] Incoming zone transfers restarting after an error could trigger an assertion failure. [RT #1692] 979. [func] Incremental master file dumping. dns_master_dumpinc(), dns_master_dumptostreaminc(), dns_dumpctx_attach(), dns_dumpctx_detach(), dns_dumpctx_cancel(), dns_dumpctx_db() and dns_dumpctx_version(). 978. [bug] dns_db_attachversion() had an invalid REQUIRE() condition. 977. [bug] Improve "not at top of zone" error message. 976. [func] named-checkconf can now test load master zones (named-checkconf -z). [RT #1468] 975. [bug] "max-cache-size default;" as a view option caused an assertion failure. 974. [bug] "max-cache-size unlimited;" as a global option was not accepted. 973. [bug] Failed to log the question name when logging: "bad zone transfer request: non-authoritative zone (NOTAUTH)". 972. [bug] The file modification time code in zone.c was using the wrong epoch. [RT #1667] 971. [placeholder] 970. [func] 'max-journal-size' can now be used to set a target size for a journal. 969. [func] dig now supports the undocumented dig 8 feature of allowing arbitrary labels, not just dotted decimal quads, with the -x option. This can be used to conveniently look up RFC2317 names as in "dig -x 10.0.0.0-127". [RT #827, #1576, #1598] 968. [bug] On win32, the isc_time_now() function was unnecessarily calling strtime(). [RT #1671] 967. [bug] On win32, the link for bindevt was not including the required resource file to enable the event viewer to interpret the error messages in the event log, [RT #1668] 966. [placeholder] 965. [bug] Including data other than root server NS and A records in the root hint file could cause a rbtdb node reference leak. [RT #1581, #1618] 964. [func] Warn if data other than root server NS and A records are found in the root hint file. [RT #1581, #1618] 963. [bug] Bad ISC_LANG_ENDDECLS. [RT #1645] 962. [bug] libbind: bad "#undef", don't attempt to install non-existent nlist.h. [RT #1640] 961. [bug] Tried to use a IPV6 feature when ISC_PLATFORM_HAVEIPV6 was not defined. [RT #1482] 960. [port] liblwres failed to build on systems with support for getrrsetbyname() in the OS. [RT #1592] 959. [port] On FreeBSD, determine the number of CPUs by calling sysctlbyname(). [RT #1584] 958. [port] ssize_t is not available on all platforms. [RT #1607] 957. [bug] sys/select.h inclusion was broken on older platforms. [RT #1607] 956. [bug] ns_g_autorndcfile changed to ns_g_keyfile in named/win32/os.c due to code changes in change #953. win32 .make file for rndc-confgen updated to add include path for os.h header. --- 9.2.0rc1 released --- 955. [bug] When using views, the zone's class was not being inherited from the view's class. [RT #1583] 954. [bug] When requesting AXFRs or IXFRs using dig, host, or nslookup, the RD bit should not be set as zone transfers are inherently non-recursive. [RT #1575] 953. [func] The /var/run/named.key file from change #843 has been replaced by /etc/rndc.key. Both named and rndc will look for this file and use it to configure a default control channel key if not already configured using a different method (rndc.conf / controls). Unlike named.key, rndc.key is not created automatically; it must be created by manually running "rndc-confgen -a". 952. [bug] The server required manual intervention to serve the affected zones if it died between creating a journal and committing the first change to it. 951. [bug] CFLAGS was not passed to the linker when linking some of the test programs under bin/tests. [RT #1555]. 950. [bug] Explicit TTLs did not properly override $TTL due to a bug in change 834. [RT #1558] 949. [bug] host was unable to print records larger than 512 bytes. [RT #1557] --- 9.2.0b2 released --- 948. [port] Integrated support for building on Windows NT / Windows 2000. 947. [bug] dns_rdata_soa_t had a badly named element "mname" which was really the RNAME field from RFC1035. To avoid confusion and silent errors that would occur it the "origin" and "mname" elements were given their correct names "mname" and "rname" respectively, the "mname" element is renamed to "contact". 946. [cleanup] doc/misc/options is now machine-generated from the configuration parser syntax tables, and therefore more likely to be correct. 945. [func] Add the new view-specific options "match-destinations" and "match-recursive-only". 944. [func] Check for expired signatures on load. 943. [bug] The server could crash when receiving a command via rndc if the configuration file listed only nonexistent keys in the controls statement. [RT #1530] 942. [port] libbind: GETNETBYADDR_ADDR_T was not correctly defined on some platforms. 941. [bug] The configuration checker crashed if a slave zone didn't contain a masters statement. [RT #1514] 940. [bug] Double zone locking failure on error path. [RT #1510] --- 9.2.0b1 released --- 939. [port] Add the --disable-linux-caps option to configure for systems that manage capabilities outside of named. [RT #1503] 938. [placeholder] 937. [bug] A race when shutting down a zone could trigger a INSIST() failure. [RT #1034] 936. [func] Warn about IPv4 addresses that are not complete dotted quads. [RT #1084] 935. [bug] inet_pton failed to reject leading zeros. 934. [port] Deal with systems where accept() spuriously returns ECONNRESET. 933. [bug] configure failed doing libbind on platforms not supported by BIND 8. [RT #1496] --- 9.2.0a3 released --- 932. [bug] Use INSTALL_SCRIPT, not INSTALL_PROGRAM, when installing isc-config.sh. [RT #198, #1466] 931. [bug] The controls statement only attempted to verify messages using the first key in the key list. (9.2.0a1/a2 only). 930. [func] Query performance testing tool added as contrib/queryperf. 929. [placeholder] 928. [bug] nsupdate would send empty update packets if the send (or empty line) command was run after another send but before any new updates or prerequisites were specified. It should simply ignore this command. 927. [bug] Don't hold the zone lock for the entire dump to disk. [RT #1423] 926. [bug] The resolver could deadlock with the ADB when shutting down (multi-threaded builds only). [RT #1324] 925. [cleanup] Remove openssl from the distribution; require that --with-openssl be specified if DNSSEC is needed. 924. [port] Extend support for pre-RFC2133 IPv6 implementation. [RT #987] 923. [bug] Multiline TSIG secrets (and other multiline strings) were not accepted in named.conf. [RT #1469] 922. [func] Added two new lwres_getrrsetbyname() result codes, ERR_NONAME and ERR_NODATA. 921. [bug] lwres returned an incorrect error code if it received a truncated message. 920. [func] Increase the lwres receive buffer size to 16K. [RT #1451] 919. [placeholder] 918. [func] In nsupdate, TSIG errors are no longer treated as fatal errors. 917. [func] New nsupdate command 'key', allowing TSIG keys to be specified in the nsupdate command stream rather than the command line. 916. [bug] Specifying type ixfr to dig without specifying a serial number failed in unexpected ways. 915. [func] The named-checkconf and named-checkzone programs now have a '-v' option for printing their version. [RT #1151] 914. [bug] Global 'server' statements were rejected when using views, even though they were accepted in 9.1. [RT #1368] 913. [bug] Cache cleaning was not sufficiently aggressive. [RT #1441, #1444] 912. [bug] Attempts to set the 'additional-from-cache' or 'additional-from-auth' option to 'no' in a server with recursion enabled will now be ignored and cause a warning message. [RT #1145] 911. [placeholder] 910. [port] Some pre-RFC2133 IPv6 implementations do not define IN6ADDR_ANY_INIT. [RT #1416] 909. [placeholder] 908. [func] New program, rndc-confgen, to simplify setting up rndc. 907. [func] The ability to get entropy from either the random device, a user-provided file or from the keyboard was migrated from the DNSSEC tools to libisc as isc_entropy_usebestsource(). 906. [port] Separated the system independent portion of lib/isc/unix/entropy.c into lib/isc/entropy.c and added lib/isc/win32/entropy.c. 905. [bug] Configuring a forward "zone" for the root domain did not work. [RT #1418] 904. [bug] The server would leak memory if attempting to use an expired TSIG key. [RT #1406] 903. [bug] dig should not crash when receiving a TCP packet of length 0. 902. [bug] The -d option was ignored if both -t and -g were also specified. 901. [placeholder] 900. [bug] A config.guess update changed the system identification string of FreeBSD systems; configure and bin/tests/system/ifconfig.sh now recognize the new string. --- 9.2.0a2 released --- 899. [bug] lib/dns/soa.c failed to compile on many platforms due to inappropriate use of a void value. [RT #1372, #1373, #1386, #1387, #1395] 898. [bug] "dig" failed to set a nonzero exit status on UDP query timeout. [RT #1323] 897. [bug] A config.guess update changed the system identification string of UnixWare systems; configure now recognizes the new string. 896. [bug] If a configuration file is set on named's command line and it has a relative pathname, the current directory (after any possible jailing resulting from named -t) will be prepended to it so that reloading works properly even when a directory option is present. 895. [func] New function, isc_dir_current(), akin to POSIX's getcwd(). 894. [bug] When using the DNSSEC tools, a message intended to warn when the keyboard was being used because of the lack of a suitable random device was not being printed. 893. [func] Removed isc_file_test() and added isc_file_exists() for the basic functionality that was being added with isc_file_test(). 892. [placeholder] 891. [bug] Return an error when a SIG(0) signed response to an unsigned query is seen. This should actually do the verification, but it's not currently possible. [RT #1391] 890. [cleanup] The man pages no longer require the mandoc macros and should now format cleanly using most versions of nroff, and HTML versions of the man pages have been added. Both are generated from DocBook source. 889. [port] Eliminated blank lines before .TH in nroff man pages since they cause problems with some versions of nroff. [RT #1390] 888. [bug] Don't die when using TKEY to delete a nonexistent TSIG key. [RT #1392] 887. [port] Detect broken compilers that can't call static functions from inline functions. [RT #1212] 886. [placeholder] 885. [placeholder] 884. [placeholder] 883. [placeholder] 882. [placeholder] 881. [placeholder] 880. [placeholder] 879. [placeholder] 878. [placeholder] 877. [placeholder] 876. [placeholder] 875. [placeholder] 874. [placeholder] 873. [placeholder] 872. [placeholder] 871. [placeholder] 870. [placeholder] 869. [placeholder] 868. [placeholder] 867. [placeholder] 866. [func] Close debug only file channels when debug is set to zero. [RT #1246] 865. [bug] The new configuration parser did not allow the optional debug level in a "severity debug" clause of a logging channel to be omitted. This is now allowed and treated as "severity debug 1;" like it does in BIND 8.2.4, not as "severity debug 0;" like it did in BIND 9.1. [RT #1367] 864. [cleanup] Multi-threading is now enabled by default on OSF1, Solaris 2.7 and newer, AIX, IRIX, and HP-UX. 863. [bug] If an error occurred while an outgoing zone transfer was starting up, the server could access a domain name that had already been freed when logging a message saying that the transfer was starting. [RT #1383] 862. [bug] Use after realloc(), non portable pointer arithmetic in grmerge(). 861. [port] Add support for Mac OS X, by making it equivalent to Darwin. This was derived from the config.guess file shipped with Mac OS X. [RT #1355] 860. [func] Drop cross class glue in zone transfers. 859. [bug] Cache cleaning now won't swamp the CPU if there is a persistent over limit condition. 858. [func] isc_mem_setwater() no longer requires that when the callback function is non-NULL then its hi_water argument must be greater than its lo_water argument (they can now be equal) or that they be non-zero. 857. [cleanup] Use ISC_MAGIC() to define all magic numbers for structs, for our friends in EBCDIC-land. 856. [func] Allow partial rdatasets to be returned in answer and authority sections to help non-TCP capable clients recover from truncation. [RT #1301] 855. [bug] Stop spurious "using RFC 1035 TTL semantics" warnings. 854. [bug] The config parser didn't properly handle config options that were specified in units of time other than seconds. [RT #1372] 853. [bug] configure_view_acl() failed to detach existing acls. [RT #1374] 852. [bug] Handle responses from servers which do not know about IXFR. 851. [cleanup] The obsolete support-ixfr option was not properly ignored. --- 9.2.0a1 released --- 850. [bug] dns_rbt_findnode() would not find nodes that were split on a bitstring label somewhere other than in the last label of the node. [RT #1351] 849. [func] will ensure INADDR_LOOPBACK is defined. 848. [func] A minimum max-cache-size of two megabytes is enforced by the cache cleaner. 847. [func] Added isc_file_test(), which currently only has some very basic functionality to test for the existence of a file, whether a pathname is absolute, or whether a pathname is the fundamental representation of the current directory. It is intended that this function can be expanded to test other things a programmer might want to know about a file. 846. [func] A non-zero 'param' to dst_key_generate() when making an hmac-md5 key means that good entropy is not required. 845. [bug] The access rights on the public file of a symmetric key are now restricted as soon as the file is opened, rather than after it has been written and closed. 844. [func] will ensure INADDR_LOOPBACK is defined, just as does. 843. [func] If no controls statement is present in named.conf, or if any inet phrase of a controls statement is lacking a keys clause, then a key will be automatically generated by named and an rndc.conf-style file named named.key will be written that uses it. rndc will use this file only if its normal configuration file, or one provided on the command line, does not exist. 842. [func] 'rndc flush' now takes an optional view. 841. [bug] When sdb modules were not declared threadsafe, their create and destroy functions were not serialized. 840. [bug] The config file parser could print the wrong file name if an error was detected after an included file was parsed. [RT #1353] 839. [func] Dump packets for which there was no view or that the class could not be determined to category "unmatched". 838. [port] UnixWare 7.x.x is now suported by bin/tests/system/ifconfig.sh. 837. [cleanup] Multi-threading is now enabled by default only on OSF1, Solaris 2.7 and newer, and AIX. 836. [func] Upgraded libtool to 1.4. 835. [bug] The dispatcher could enter a busy loop if it got an I/O error receiving on a UDP socket. [RT #1293] 834. [func] Accept (but warn about) master files beginning with an SOA record without an explicit TTL field and lacking a $TTL directive, by using the SOA MINTTL as a default TTL. This is for backwards compatibility with old versions of BIND 8, which accepted such files without warning although they are illegal according to RFC1035. 833. [cleanup] Moved dns_soa_*() from to , and extended them to support all the integer-valued fields of the SOA RR. 832. [bug] The default location for named.conf in named-checkconf should depend on --sysconfdir like it does in named. [RT #1258] 831. [placeholder] 830. [func] Implement 'rndc status'. 829. [bug] The DNS_R_ZONECUT result code should only be returned when an ANY query is made with DNS_DBFIND_GLUEOK set. In all other ANY query cases, returning the delegation is better. 828. [bug] The errno value from recvfrom() could be overwritten by logging code. [RT #1293] 827. [bug] When an IXFR protocol error occurs, the slave should retry with AXFR. 826. [bug] Some IXFR protocol errors were not detected. 825. [bug] zone.c:ns_query() detached from the wrong zone reference. [RT #1264] 824. [bug] Correct line numbers reported by dns_master_load(). [RT #1263] 823. [func] The output of "dig -h" now goes to stdout so that it can easily be piped through "more". [RT #1254] 822. [bug] Sending nxrrset prerequisites would crash nsupdate. [RT #1248] 821. [bug] The program name used when logging to syslog should be stripped of leading path components. [RT #1178, #1232] 820. [bug] Name server address lookups failed to follow A6 chains into the glue of local authoritative zones. 819. [bug] In certain cases, the resolver's attempts to restart an address lookup at the root could cause the fetch to deadlock (with itself) instead of restarting. [RT #1225] 818. [bug] Certain pathological responses to ANY queries could cause an assertion failure. [RT #1218] 817. [func] Adjust timeouts for dialup zone queries. 816. [bug] Report potential problems with log file accessibility at configuration time, since such problems can't reliably be reported at the time they actually occur. 815. [bug] If a log file was specified with a path separator character (i.e. "/") in its name and the directory did not exist, the log file's name was treated as though it were the directory name. [RT #1189] 814. [bug] Socket objects left over from accept() failures were incorrectly destroyed, causing corruption of socket manager data structures. 813. [bug] File descriptors exceeding FD_SETSIZE were handled badly. [RT #1192] 812. [bug] dig sometimes printed incomplete IXFR responses due to an uninitialized variable. [RT #1188] 811. [bug] Parentheses were not quoted in zone dumps. [RT #1194] 810. [bug] The signer name in SIG records was not properly down-cased when signing/verifying records. [RT #1186] 809. [bug] Configuring a non-local address as a transfer-source could cause an assertion failure during load. 808. [func] Add 'rndc flush' to flush the server's cache. 807. [bug] When setting up TCP connections for incoming zone transfers, the transfer-source port was not ignored like it should be. 806. [bug] DNS_R_SEENINCLUDE was failing to propagate back up the calling stack to the zone maintenance level, causing zones to not reload when an included file was touched but the top-level zone file was not. 805. [bug] When using "forward only", missing root hints should not cause queries to fail. [RT #1143] 804. [bug] Attempting to obtain entropy could fail in some situations. This would be most common on systems with user-space threads. [RT #1131] 803. [bug] Treat all SIG queries as if they have the CD bit set, otherwise no data will be returned [RT #749] 802. [bug] DNSSEC key tags were computed incorrectly in almost all cases. [RT #1146] 801. [bug] nsupdate should treat lines beginning with ';' as comments. [RT #1139] 800. [bug] dnssec-signzone produced incorrect statistics for large zones. [RT #1133] 799. [bug] The ADB didn't find AAAA glue in a zone unless A6 glue was also present. 798. [bug] nsupdate should be able to reject bad input lines and continue. [RT #1130] 797. [func] Issue a warning if the 'directory' option contains a relative path. [RT #269] 796. [func] When a size limit is associated with a log file, only roll it when the size is reached, not every time the log file is opened. [RT #1096] 795. [func] Add the +multiline option to dig. [RT #1095] 794. [func] Implement the "port" and "default-port" statements in rndc.conf. 793. [cleanup] The DNSSEC tools could create filenames that were illegal or contained shell meta-characters. They now use a different text encoding of names that doesn't have these problems. [RT #1101] 792. [cleanup] Replace the OMAPI command channel protocol with a simpler one. 791. [bug] The command channel now works over IPv6. 790. [bug] Wildcards created using dynamic update or IXFR could fail to match. [RT #1111] 789. [bug] The "localhost" and "localnets" ACLs did not match when used as the second element of a two-element sortlist item. 788. [func] Add the "match-mapped-addresses" option, which causes IPv6 v4mapped addresses to be treated as IPv4 addresses for the purpose of acl matching. 787. [bug] The DNSSEC tools failed to downcase domain names when mapping them into file names. 786. [bug] When DNSSEC signing/verifying data, owner names were not properly down-cased. 785. [bug] A race condition in the resolver could cause an assertion failure. [RT #673, #872, #1048] 784. [bug] nsupdate and other programs would not quit properly if some signals were blocked by the caller. [RT #1081] 783. [bug] Following CNAMEs could cause an assertion failure when either using an sdb database or under very rare conditions. 782. [func] Implement the "serial-query-rate" option. 781. [func] Avoid error packet loops by dropping duplicate FORMERR responses. [RT #1006] 780. [bug] Error handling code dealing with out of memory or other rare errors could lead to assertion failures by calling functions on uninitialized names. [RT #1065] 779. [func] Added the "minimal-responses" option. 778. [bug] When starting cache cleaning, cleaning_timer_action() returned without first pausing the iterator, which could cause deadlock. [RT #998] 777. [bug] An empty forwarders list in a zone failed to override global forwarders. [RT #995] 776. [func] Improved error reporting in denied messages. [RT #252] 775. [placeholder] 774. [func] max-cache-size is implemented. 773. [func] Added isc_rwlock_trylock() to attempt to lock without blocking. 772. [bug] Owner names could be incorrectly omitted from cache dumps in the presence of negative caching entries. [RT #991] 771. [cleanup] TSIG errors related to unsynchronized clocks are logged better. [RT #919] 770. [func] Add the "edns yes_or_no" statement to the server clause. [RT #524] 769. [func] Improved error reporting when parsing rdata. [RT #740] 768. [bug] The server did not emit an SOA when a CNAME or DNAME chain ended in NXDOMAIN in an authoritative zone. 767. [placeholder] 766. [bug] A few cases in query_find() could leak fname. This would trigger the mpctx->allocated == 0 assertion when the server exited. [RT #739, #776, #798, #812, #818, #821, #845, #892, #935, #966] 765. [func] ACL names are once again case insensitive, like in BIND 8. [RT #252] 764. [func] Configuration files now allow "include" directives in more places, such as inside the "view" statement. [RT #377, #728, #860] 763. [func] Configuration files no longer have reserved words. [RT #731, #753] 762. [cleanup] The named.conf and rndc.conf file parsers have been completely rewritten. 761. [bug] _REENTRANT was still defined when building with --disable-threads. 760. [contrib] Significant enhancements to the pgsql sdb driver. 759. [bug] The resolver didn't turn off "avoid fetches" mode when restarting, possibly causing resolution to fail when it should not. This bug only affected platforms which support both IPv4 and IPv6. [RT #927] 758. [bug] The "avoid fetches" code did not treat negative cache entries correctly, causing fetches that would be useful to be avoided. This bug only affected platforms which support both IPv4 and IPv6. [RT #927] 757. [func] Log zone transfers. 756. [bug] dns_zone_load() could "return" success when no master file was configured. 755. [bug] Fix incorrectly formatted log messages in zone.c. 754. [bug] Certain failure conditions sending UDP packets could cause the server to retry the transmission indefinitely. [RT #902] 753. [bug] dig, host, and nslookup would fail to contact a remote server if getaddrinfo() returned an IPv6 address on a system that doesn't support IPv6. [RT #917] 752. [func] Correct bad tv_usec elements returned by gettimeofday(). 751. [func] Log successful zone loads / transfers. [RT #898] 750. [bug] A query should not match a DNAME whose trust level is pending. [RT #916] 749. [bug] When a query matched a DNAME in a secure zone, the server did not return the signature of the DNAME. [RT #915] 748. [doc] List supported RFCs in doc/misc/rfc-compliance. [RT #781] 747. [bug] The code to determine whether an IXFR was possible did not properly check for a database that could not have a journal. [RT #865, #908] 746. [bug] The sdb didn't clone rdatasets properly, causing a crash when the server followed delegations. [RT #905] 745. [func] Report the owner name of records that fail semantic checks while loading. 744. [bug] When returning DNS_R_CNAME or DNS_R_DNAME as the result of an ANY or SIG query, the resolver failed to setup the return event's rdatasets, causing an assertion failure in the query code. [RT #881] 743. [bug] Receiving a large number of certain malformed answers could cause named to stop responding. [RT #861] 742. [placeholder] 741. [port] Support openssl-engine. [RT #709] 740. [port] Handle openssl library mismatches slightly better. 739. [port] Look for /dev/random in configure, rather than assuming it will be there for only a predefined set of OSes. 738. [bug] If a non-threadsafe sdb driver supported AXFR and received an AXFR request, it would deadlock or die with an assertion failure. [RT #852] 737. [port] stdtime.c failed to compile on certain platforms. 736. [func] New functions isc_task_{begin,end}exclusive(). 735. [doc] Add BIND 4 migration notes. 734. [bug] An attempt to re-lock the zone lock could occur if the server was shutdown during a zone transfer. [RT #830] 733. [bug] Reference counts of dns_acl_t objects need to be locked but were not. [RT #801, #821] 732. [bug] Glue with 0 TTL could also cause SERVFAIL. [RT #828] 731. [bug] Certain zone errors could cause named-checkzone to fail ungracefully. [RT #819] 730. [bug] lwres_getaddrinfo() returns the correct result when it fails to contact a server. [RT #768] 729. [port] pthread_setconcurrency() needs to be called on Solaris. 728. [bug] Fix comment processing on master file directives. [RT #757] 727. [port] Work around OS bug where accept() succeeds but fails to fill in the peer address of the accepted connection, by treating it as an error rather than an assertion failure. [RT #809] 726. [func] Implement the "trace" and "notrace" commands in rndc. 725. [bug] Installing man pages could fail. 724. [func] New libisc functions isc_netaddr_any(), isc_netaddr_any6(). 723. [bug] Referrals whose NS RRs had a 0 TTL caused the resolver to return DNS_R_SERVFAIL. [RT #783] 722. [func] Allow incremental loads to be canceled. 721. [cleanup] Load manager and dns_master_loadfilequota() are no more. 720. [bug] Server could enter infinite loop in dispatch.c:do_cancel(). [RT #733] 719. [bug] Rapid reloads could trigger an assertion failure. [RT #743, #763] 718. [cleanup] "internal" is no longer a reserved word in named.conf. [RT #753, #731] 717. [bug] Certain TKEY processing failure modes could reference an uninitialized variable, causing the server to crash. [RT #750] 716. [bug] The first line of a $INCLUDE master file was lost if an origin was specified. [RT #744] 715. [bug] Resolving some A6 chains could cause an assertion failure in adb.c. [RT #738] 714. [bug] Preserve interval timers across reloads unless changed. [RT #729] 713. [func] named-checkconf takes '-t directory' similar to named. [RT #726] 712. [bug] Sending a large signed update message caused an assertion failure. [RT #718] 711. [bug] The libisc and liblwres implementations of inet_ntop contained an off by one error. 710. [func] The forwarders statement now takes an optional port. [RT #418] 709. [bug] ANY or SIG queries for data with a TTL of 0 would return SERVFAIL. [RT #620] 708. [bug] When building with --with-openssl, the openssl headers included with BIND 9 should not be used. [RT #702] 707. [func] The "filename" argument to named-checkzone is no longer optional, to reduce confusion. [RT #612] 706. [bug] Zones with an explicit "allow-update { none; };" were considered dynamic and therefore not reloaded on SIGHUP or "rndc reload". 705. [port] Work out resource limit type for use where rlim_t is not available. [RT #695] 704. [port] RLIMIT_NOFILE is not available on all platforms. [RT #695] 703. [port] sys/select.h is needed on older platforms. [RT #695] 702. [func] If the address 0.0.0.0 is seen in resolv.conf, use 127.0.0.1 instead. [RT #693] 701. [func] Root hints are now fully optional. Class IN views use compiled-in hints by default, as before. Non-IN views with no root hints now provide authoritative service but not recursion. A warning is logged if a view has neither root hints nor authoritative data for the root. [RT #696] 700. [bug] $GENERATE range check was wrong. [RT #688] 699. [bug] The lexer mishandled empty quoted strings. [RT #694] 698. [bug] Aborting nsupdate with ^C would lead to several race conditions. 697. [bug] nsupdate was not compatible with the undocumented BIND 8 behavior of ignoring TTLs in "update delete" commands. [RT #693] 696. [bug] lwresd would die with an assertion failure when passed a zero-length name. [RT #692] 695. [bug] If the resolver attempted to query a blackholed or bogus server, the resolution would fail immediately. 694. [bug] $GENERATE did not produce the last entry. [RT #682, #683] 693. [bug] An empty lwres statement in named.conf caused the server to crash while loading. 692. [bug] Deal with systems that have getaddrinfo() but not gai_strerror(). [RT #679] 691. [bug] Configuring per-view forwarders caused an assertion failure. [RT #675, #734] 690. [func] $GENERATE now supports DNAME. [RT #654] 689. [doc] man pages are now installed. [RT #210] 688. [func] "make tags" now works on systems with the "Exuberant Ctags" etags. 687. [bug] Only say we have IPv6, with sufficient functionality, if it has actually been tested. [RT #586] 686. [bug] dig and nslookup can now be properly aborted during blocking operations. [RT #568] 685. [bug] nslookup should use the search list/domain options from resolv.conf by default. [RT #405, #630] 684. [bug] Memory leak with view forwarders. [RT #656] 683. [bug] File descriptor leak in isc_lex_openfile(). 682. [bug] nslookup displayed SOA records incorrectly. [RT #665] 681. [bug] $GENERATE specifying output format was broken. [RT #653] 680. [bug] dns_rdata_fromstruct() mishandled options bigger than 255 octets. 679. [bug] $INCLUDE could leak memory and file descriptors on reload. [RT #639] 678. [bug] "transfer-format one-answer;" could trigger an assertion failure. [RT #646] 677. [bug] dnssec-signzone would occasionally use the wrong ttl for database operations and fail. [RT #643] 676. [bug] Log messages about lame servers to category 'lame-servers' rather than 'resolver', so as not to be gratuitously incompatible with BIND 8. 675. [bug] TKEY queries could cause the server to leak memory. 674. [func] Allow messages to be TSIG signed / verified using a offset from the current time. 673. [func] The server can now convert RFC1886-style recursive lookup requests into RFC2874-style lookups, when enabled using the new option "allow-v6-synthesis". 672. [bug] The wrong time was in the "time signed" field when replying with BADTIME error. 671. [bug] The message code was failing to parse a message with no question section and a TSIG record. [RT #628] 670. [bug] The lwres replacements for getaddrinfo and getipnodebyname didn't properly check for the existence of the sockaddr sa_len field. 669. [bug] dnssec-keygen now makes the public key file non-world-readable for symmetric keys. [RT #403] 668. [func] named-checkzone now reports multiple errors in master files. 667. [bug] On Linux, running named with the -u option and a non-world-readable configuration file didn't work. [RT #626] 666. [bug] If a request sent by dig is longer than 512 bytes, use TCP. 665. [bug] Signed responses were not sent when the size of the TSIG + question exceeded the maximum message size. [RT #628] 664. [bug] The t_tasks and t_timers module tests are now skipped when building without threads, since they require threads. 663. [func] Accept a size_spec, not just an integer, in the (unimplemented and ignored) max-ixfr-log-size option for compatibility with recent versions of BIND 8. [RT #613] 662. [bug] dns_rdata_fromtext() failed to log certain errors. 661. [bug] Certain UDP IXFR requests caused an assertion failure (mpctx->allocated == 0). [RT #355, #394, #623] 660. [port] Detect multiple CPUs on HP-UX and IRIX. 659. [performance] Rewrite the name compression code to be much faster. 658. [cleanup] Remove all vestiges of 16 bit global compression. 657. [bug] When a listen-on statement in an lwres block does not specify a port, use 921, not 53. Also update the listen-on documentation. [RT #616] 656. [func] Treat an unescaped newline in a quoted string as an error. This means that TXT records with missing close quotes should have meaningful errors printed. 655. [bug] Improve error reporting on unexpected eof when loading zones. [RT #611] 654. [bug] Origin was being forgotten in TCP retries in dig. [RT #574] 653. [bug] +defname option in dig was reversed in sense. [RT #549] 652. [bug] zone_saveunique() did not report the new name. 651. [func] The AD bit in responses now has the meaning specified in . 650. [bug] SIG(0) records were being generated and verified incorrectly. [RT #606] 649. [bug] It was possible to join to an already running fctx after it had "cloned" its events, but before it sent them. In this case, the event of the newly joined fetch would not contain the answer, and would trigger the INSIST() in fctx_sendevents(). In BIND 9.0, this bug did not trigger an INSIST(), but caused the fetch to fail with a SERVFAIL result. [RT #588, #597, #605, #607] 648. [port] Add support for pre-RFC2133 IPv6 implementations. 647. [bug] Resolver queries sent after following multiple referrals had excessively long retransmission timeouts due to incorrectly counting the referrals as "restarts". 646. [bug] The UnixWare ISC_PLATFORM_FIXIN6INADDR fix in isc/net.h didn't _cleanly_ fix the problem it was trying to fix. 645. [port] BSD/OS 3.0 needs pthread_init(). [RT #603] 644. [bug] #622 needed more work. [RT #562] 643. [bug] xfrin error messages made more verbose, added class of the zone. [RT #599] 642. [bug] Break the exit_check() race in the zone module. [RT #598] --- 9.1.0b2 released --- 641. [bug] $GENERATE caused a uninitialized link to be used. [RT #595] 640. [bug] Memory leak in error path could cause "mpctx->allocated == 0" failure. [RT #584] 639. [bug] Reading entropy from the keyboard would sometimes fail. [RT #591] 638. [port] lib/isc/random.c needed to explicitly include time.h to get a prototype for time() when pthreads was not being used. [RT #592] 637. [port] Use isc_u?int64_t instead of (unsigned) long long in lib/isc/print.c. Also allow lib/isc/print.c to be compiled even if the platform does not need it. [RT #592] 636. [port] Shut up MSVC++ about a possible loss of precision in the ISC__BUFFER_PUTUINT*() macros. [RT #592] 635. [bug] Reloading a server with a configured blackhole list would cause an assertion. [RT #590] 634. [bug] A log file will completely stop being written when it reaches the maximum size in all cases, not just when versioning is also enabled. [RT #570] 633. [port] Cope with rlim_t missing on BSD/OS systems. [RT #575] 632. [bug] The index array of the journal file was corrupted as it was written to disk. 631. [port] Build without thread support on systems without pthreads. 630. [bug] Locking failure in zone code. [RT #582] 629. [bug] 9.1.0b1 dereferenced a null pointer and crashed when responding to a UDP IXFR request. 628. [bug] If the root hints contained only AAAA addresses, named would be unable to perform resolution. 627. [bug] The EDNS0 blackhole detection code of change 324 waited for three retransmissions to each server, which takes much too long when a domain has many name servers and all of them drop EDNS0 queries. Now we retry without EDNS0 after three consecutive timeouts, even if they are all from different servers. [RT #143] 626. [bug] The lightweight resolver daemon no longer crashes when asked for a SIG rrset. [RT #558] 625. [func] Zones now inherit their class from the enclosing view. 624. [bug] The zone object could get timer events after it had been destroyed, causing a server crash. [RT #571] 623. [func] Added "named-checkconf" and "named-checkzone" program for syntax checking named.conf files and zone files, respectively. 622. [bug] A canceled request could be destroyed before dns_request_destroy() was called. [RT #562] 621. [port] Disable IPv6 at runtime if IPv6 sockets are unusable. This mostly affects Red Hat Linux 7.0, which has conflicts between libc and the kernel. 620. [bug] dns_master_load*inc() now require 'task' and 'load' to be non-null. Also 'done' will not be called if dns_master_load*inc() fails immediately. [RT #565] 619. [placeholder] 618. [bug] Queries to a signed zone could sometimes cause an assertion failure. 617. [bug] When using dynamic update to add a new RR to an existing RRset with a different TTL, the journal entries generated from the update did not include explicit deletions and re-additions of the existing RRs to update their TTL to the new value. 616. [func] dnssec-signzone -t output now includes performance statistics. 615. [bug] dnssec-signzone did not like child keysets signed by multiple keys. 614. [bug] Checks for uninitialized link fields were prone to false positives, causing assertion failures. The checks are now disabled by default and may be re-enabled by defining ISC_LIST_CHECKINIT. 613. [bug] "rndc reload zone" now reloads primary zones. It previously only updated slave and stub zones, if an SOA query indicated an out of date serial. 612. [cleanup] Shutup a ridiculously noisy HP-UX compiler that complains relentlessly about how its treatment of 'const' has changed as well as how casting sometimes tightens alignment constraints. 611. [func] allow-notify can be used to permit processing of notify messages from hosts other than a slave's masters. 610. [func] rndc dumpdb is now supported. 609. [bug] getrrsetbyname() would crash lwresd if the server found more SIGs than answers. [RT #554] 608. [func] dnssec-signzone now adds a comment to the zone with the time the file was signed. 607. [bug] nsupdate would fail if it encountered a CNAME or DNAME in a response to an SOA query. [RT #515] 606. [bug] Compiling with --disable-threads failed due to isc_thread_self() being incorrectly defined as an integer rather than a function. 605. [func] New function isc_lex_getlasttokentext(). 604. [bug] The named.conf parser could print incorrect line numbers when long comments were present. 603. [bug] Make dig handle multiple types or classes on the same query more correctly. 602. [func] Cope automatically with UnixWare's broken IN6_IS_ADDR_* macros. [RT #539] 601. [func] Return a non-zero exit code if an update fails in nsupdate. 600. [bug] Reverse lookups sometimes failed in dig, etc... 599. [func] Added four new functions to the libisc log API to support i18n messages. isc_log_iwrite(), isc_log_ivwrite(), isc_log_iwrite1() and isc_log_ivwrite1() were added. 598. [bug] An update-policy statement would cause the server to assert while loading. [RT #536] 597. [func] dnssec-signzone is now multi-threaded. 596. [bug] DNS_RDATASLAB_FORCE and DNS_RDATASLAB_EXACT are not mutually exclusive. 595. [port] On Linux 2.2, socket() returns EINVAL when it should return EAFNOSUPPORT. Work around this. [RT #531] 594. [func] sdb drivers are now assumed to not be thread-safe unless the DNS_SDBFLAG_THREADSAFE flag is supplied. 593. [bug] If a secure zone was missing all its NXTs and a dynamic update was attempted, the server entered an infinite loop. 592. [bug] The sig-validity-interval option now specifies a number of days, not seconds. This matches the documentation. [RT #529] --- 9.1.0b1 released --- 591. [bug] Work around non-reentrancy in openssl by disabling pre-computation in keys. 590. [doc] There are now man pages for the lwres library in doc/man/lwres. 589. [bug] The server could deadlock if a zone was updated while being transferred out. 588. [bug] ctx->in_use was not being correctly initialized when when pushing a file for $INCLUDE. [RT #523] 587. [func] A warning is now printed if the "allow-update" option allows updates based on the source IP address, to alert users to the fact that this is insecure and becoming increasingly so as servers capable of update forwarding are being deployed. 586. [bug] multiple views with the same name were fatal. [RT #516] 585. [func] dns_db_addrdataset() and and dns_rdataslab_merge() now support 'exact' additions in a similar manner to dns_db_subtractrdataset() and dns_rdataslab_subtract(). 584. [func] You can now say 'notify explicit'; to suppress notification of the servers listed in NS records and notify only those servers listed in the 'also-notify' option. 583. [func] "rndc querylog" will now toggle logging of queries, like "ndc querylog" in BIND 8. 582. [bug] dns_zone_idetach() failed to lock the zone. [RT #199, #463] 581. [bug] log severity was not being correctly processed. [RT #485] 580. [func] Ignore trailing garbage on incoming DNS packets, for interoperability with broken server implementations. [RT #491] 579. [bug] nsupdate did not take a filename to read update from. [RT #492] 578. [func] New config option "notify-source", to specify the source address for notify messages. 577. [func] Log illegal RDATA combinations. e.g. multiple singleton types, cname and other data. 576. [doc] isc_log_create() description did not match reality. 575. [bug] isc_log_create() was not setting internal state correctly to reflect the default channels created. 574. [bug] TSIG signed queries sent by the resolver would fail to have their responses validated and would leak memory. 573. [bug] The journal files of IXFRed slave zones were inadvertently discarded on server reload, causing "journal out of sync with zone" errors on subsequent reloads. [RT #482] 572. [bug] Quoted strings were not accepted as key names in address match lists. 571. [bug] It was possible to create an rdataset of singleton type which had more than one rdata. [RT #154] [RT #279] 570. [bug] rbtdb.c allowed zones containing nodes which had both a CNAME and "other data". [RT #154] 569. [func] The DNSSEC AD bit will not be set on queries which have not requested a DNSSEC response. 568. [func] Add sample simple database drivers in contrib/sdb. 567. [bug] Setting the zone transfer timeout to zero caused an assertion failure. [RT #302] 566. [func] New public function dns_timer_setidle(). 565. [func] Log queries more like BIND 8: query logging is now done to category "queries", level "info". [RT #169] 564. [func] Add sortlist support to lwresd. 563. [func] New public functions dns_rdatatype_format() and dns_rdataclass_format(), for convenient formatting of rdata type/class mnemonics in log messages. 562. [cleanup] Moved lib/dns/*conf.c to bin/named where they belong. 561. [func] The 'datasize', 'stacksize', 'coresize' and 'files' clauses of the options{} statement are now implemented. 560. [bug] dns_name_split did not properly the resulting prefix when a maximal length bitstring label was split which was preceded by another bitstring label. [RT #429] 559. [bug] dns_name_split did not properly create the suffix when splitting within a maximal length bitstring label. 558. [func] New functions, isc_resource_getlimit and isc_resource_setlimit. 557. [func] Symbolic constants for libisc integral types. 556. [func] The DNSSEC OK bit in the EDNS extended flags is now implemented. Responses to queries without this bit set will not contain any DNSSEC records. 555. [bug] A slave server attempting a zone transfer could crash with an assertion failure on certain malformed responses from the master. [RT #457] 554. [bug] In some cases, not all of the dnssec tools were properly installed. 553. [bug] Incoming zone transfers deferred due to quota were not started when quota was increased but only when a transfer in progress finished. [RT #456] 552. [bug] We were not correctly detecting the end of all c-style comments. [RT #455] 551. [func] Implemented the 'sortlist' option. 550. [func] Support unknown rdata types and classes. 549. [bug] "make" did not immediately abort the build when a subdirectory make failed [RT #450]. 548. [func] The lexer now ungets tokens more correctly. 547. [placeholder] 546. [func] Option 'lame-ttl' is now implemented. 545. [func] Name limit and counting options removed from dig; they didn't work properly, and cannot be correctly implemented without significant changes. 544. [func] Add statistics option, enable statistics-file option, add RNDC option "dump-statistics" to write out a query statistics file. 543. [doc] The 'port' option is now documented. 542. [func] Add support for update forwarding as required for full compliance with RFC2136. It is turned off by default and can be enabled using the 'allow-update-forwarding' option. 541. [func] Add bogus server support. 540. [func] Add dialup support. 539. [func] Support the blackhole option. 538. [bug] fix buffer overruns by 1 in lwres_getnameinfo(). 537. [placeholder] 536. [func] Use transfer-source{-v6} when sending refresh queries. Transfer-source{-v6} now take a optional port parameter for setting the UDP source port. The port parameter is ignored for TCP. 535. [func] Use transfer-source{-v6} when forwarding update requests. 534. [func] Ancestors have been removed from RBT chains. Ancestor information can be discerned via node parent pointers. 533. [func] Incorporated name hashing into the RBT database to improve search speed. 532. [func] Implement DNS UPDATE pseudo records using DNS_RDATA_UPDATE flag. 531. [func] Rdata really should be initialized before being assigned to (dns_rdata_fromwire(), dns_rdata_fromtext(), dns_rdata_clone(), dns_rdata_fromregion()), check that it is. 530. [func] New function dns_rdata_invalidate(). 529. [bug] 521 contained a bug which caused zones to always reload. [RT #410] 528. [func] The ISC_LIST_XXXX macros now perform sanity checks on their arguments. ISC_LIST_XXXXUNSAFE can be use to skip the checks however use with caution. 527. [func] New function dns_rdata_clone(). 526. [bug] nsupdate incorrectly refused to add RRs with a TTL of 0. 525. [func] New arguments 'options' for dns_db_subtractrdataset(), and 'flags' for dns_rdataslab_subtract() allowing you to request that the RR's must exist prior to deletion. DNS_R_NOTEXACT is returned if the condition is not met. 524. [func] The 'forward' and 'forwarders' statement in non-forward zones should work now. 523. [doc] The source to the Administrator Reference Manual is now an XML file using the DocBook DTD, and is included in the distribution. The plain text version of the ARM is temporarily unavailable while we figure out how to generate readable plain text from the XML. 522. [func] The lightweight resolver daemon can now use a real configuration file, and its functionality can be provided by a name server. Also, the -p and -P options to lwresd have been reversed. 521. [bug] Detect master files which contain $INCLUDE and always reload. [RT #196] 520. [bug] Upgraded libtool to 1.3.5, which makes shared library builds almost work on AIX (and possibly others). 519. [bug] dns_name_split() would improperly split some bitstring labels, zeroing a few of the least significant bits in the prefix part. When such an improperly created prefix was returned to the RBT database, the bogus label was dutifully stored, corrupting the tree. [RT #369] 518. [bug] The resolver did not realize that a DNAME which was "the answer" to the client's query was "the answer", and such queries would fail. [RT #399] 517. [bug] The resolver's DNAME code would trigger an assertion if there was more than one DNAME in the chain. [RT #399] 516. [bug] Cache lookups which had a NULL node pointer, e.g. those by dns_view_find(), and which would match a DNAME, would trigger an INSIST(!search.need_cleanup) assertion. [RT #399] 515. [bug] The ssu table was not being attached / detached by dns_zone_[sg]etssutable. [RT #397] 514. [func] Retry refresh and notify queries if they timeout. [RT #388] 513. [func] New functionality added to rdnc and server to allow individual zones to be refreshed or reloaded. 512. [bug] The zone transfer code could throw an exception with an invalid IXFR stream. 511. [bug] The message code could throw an assertion on an out of memory failure. [RT #392] 510. [bug] Remove spurious view notify warning. [RT #376] 509. [func] Add support for write of zone files on shutdown. 508. [func] dns_message_parse() can now do a best-effort attempt, which should allow dig to print more invalid messages. 507. [func] New functions dns_zone_flush(), dns_zt_flushanddetach() and dns_view_flushanddetach(). 506. [func] Do not fail to start on errors in zone files. 505. [bug] nsupdate was printing "unknown result code". [RT #373] 504. [bug] The zone was not being marked as dirty when updated via IXFR. 503. [bug] dumptime was not being set along with DNS_ZONEFLG_NEEDDUMP. 502. [func] On a SERVFAIL reply, DiG will now try the next server in the list, unless the +fail option is specified. 501. [bug] Incorrect port numbers were being displayed by nslookup. [RT #352] 500. [func] Nearly useless +details option removed from DiG. 499. [func] In DiG, specifying a class with -c or type with -t changes command-line parsing so that classes and types are only recognized if following -c or -t. This allows hosts with the same name as a class or type to be looked up. 498. [doc] There is now a man page for "dig" in doc/man/bin/dig.1. 497. [bug] The error messages printed when an IP match list contained a network address with a nonzero host part where not sufficiently detailed. [RT #365] 496. [bug] named didn't sanity check numeric parameters. [RT #361] 495. [bug] nsupdate was unable to handle large records. [RT #368] 494. [func] Do not cache NXDOMAIN responses for SOA queries. 493. [func] Return non-cachable (ttl = 0) NXDOMAIN responses for SOA queries. This makes it easier to locate the containing zone without polluting intermediate caches. 492. [bug] attempting to reload a zone caused the server fail to shutdown cleanly. [RT #360] 491. [bug] nsupdate would segfault when sending certain prerequisites with empty RDATA. [RT #356] 490. [func] When a slave/stub zone has not yet successfully obtained an SOA containing the zone's configured retry time, perform the SOA query retries using exponential backoff. [RT #337] 489. [func] The zone manager now has a "i/o" queue. 488. [bug] Locks weren't properly destroyed in some cases. 487. [port] flockfile() is not defined on all systems. 486. [bug] nslookup: "set all" and "server" commands showed the incorrect port number if a port other than 53 was specified. [RT #352] 485. [func] When dig had more than one server to query, it would send all of the messages at the same time. Add rate limiting of the transmitted messages. 484. [bug] When the server was reloaded after removing addresses from the named.conf "listen-on" statement, sockets were still listening on the removed addresses due to reference count loops. [RT #325] 483. [bug] nslookup: "set all" showed a "search" option but it was not settable. 482. [bug] nslookup: a plain "server" or "lserver" should be treated as a lookup. 481. [bug] nslookup:get_next_command() stack size could exceed per thread limit. 480. [bug] strtok() is not thread safe. [RT #349] 479. [func] The test suite can now be run by typing "make check" or "make test" at the top level. 478. [bug] "make install" failed if the directory specified with --prefix did not already exist. 477. [bug] The the isc-config.sh script could be installed before its directory was created. [RT #324] 476. [bug] A zone could expire while a zone transfer was in progress triggering a INSIST failure. [RT #329] 475. [bug] query_getzonedb() sometimes returned a non-null version on failure. This caused assertion failures when generating query responses where names subject to additional section processing pointed to a zone to which access had been denied by means of the allow-query option. [RT #336] 474. [bug] The mnemonic of the CHAOS class is CH according to RFC1035, but it was printed and read only as CHAOS. We now accept both forms as input, and print it as CH. [RT #305] 473. [bug] nsupdate overran the end of the list of name servers when no servers could be reached, typically causing it to print the error message "dns_request_create: not implemented". 472. [bug] Off-by-one error caused isc_time_add() to sometimes produce invalid time values. 471. [bug] nsupdate didn't compile on HP/UX 10.20 470. [func] $GENERATE is now supported. See also doc/misc/migration. 469. [bug] "query-source address * port 53;" now works. 468. [bug] dns_master_load*() failed to report file and line number in certain error conditions. 467. [bug] dns_master_load*() failed to log an error if pushfile() failed. 466. [bug] dns_master_load*() could return success when it failed. 465. [cleanup] Allow 0 to be set as an omapi_value_t value by omapi_value_storeint(). 464. [cleanup] Build with openssl's RSA code instead of dnssafe. 463. [bug] nsupdate sent malformed SOA queries to the second and subsequent name servers in resolv.conf if the query sent to the first one failed. 462. [bug] --disable-ipv6 should work now. 461. [bug] Specifying an unknown key in the "keys" clause of the "controls" statement caused a NULL pointer dereference. [RT #316] 460. [bug] Much of the DNSSEC code only worked with class IN. 459. [bug] Nslookup processed the "set" command incorrectly. 458. [bug] Nslookup didn't properly check class and type values. [RT #305] 457. [bug] Dig/host/hslookup didn't properly handle connect timeouts in certain situations, causing an unnecessary warning message to be printed. 456. [bug] Stub zones were not resetting the refresh and expire counters, loadtime or clearing the DNS_ZONE_REFRESH (refresh in progress) flag upon successful update. This disabled further refreshing of the stub zone, causing it to eventually expire. [RT #300] 455. [doc] Document IPv4 prefix notation does not require a dotted decimal quad but may be just dotted decimal. 454. [bug] Enforce dotted decimal and dotted decimal quad where documented as such in named.conf. [RT #304, RT #311] 453. [bug] Warn if the obsolete option "maintain-ixfr-base" is specified in named.conf. [RT #306] 452. [bug] Warn if the unimplemented option "statistics-file" is specified in named.conf. [RT #301] 451. [func] Update forwarding implemented. 450. [func] New function ns_client_sendraw(). 449. [bug] isc_bitstring_copy() only works correctly if the two bitstrings have the same lsb0 value, but this requirement was not documented, nor was there a REQUIRE for it. 448. [bug] Host output formatting change, to match v8. [RT #255] 447. [bug] Dig didn't properly retry in TCP mode after a truncated reply. [RT #277] 446. [bug] Confusing notify log message. [RT #298] 445. [bug] Doing a 0 bit isc_bitstring_copy() of an lsb0 bitstring triggered a REQUIRE statement. The REQUIRE statement was incorrect. [RT #297] 444. [func] "recursion denied" messages are always logged at debug level 1, now, rather than sometimes at ERROR. This silences these warnings in the usual case, where some clients set the RD bit in all queries. 443. [bug] When loading a master file failed because of an unrecognized RR type name, the error message did not include the file name and line number. [RT #285] 442. [bug] TSIG signed messages that did not match any view crashed the server. [RT #290] 441. [bug] Nodes obscured by a DNAME were inaccessible even when DNS_DBFIND_GLUEOK was set. 440. [func] New function dns_zone_forwardupdate(). 439. [func] New function dns_request_createraw(). 438. [func] New function dns_message_getrawmessage(). 437. [func] Log NOTIFY activity to the notify channel. 436. [bug] If recvmsg() returned EHOSTUNREACH or ENETUNREACH, which sometimes happens on Linux, named would enter a busy loop. Also, unexpected socket errors were not logged at a high enough logging level to be useful in diagnosing this situation. [RT #275] 435. [bug] dns_zone_dump() overwrote existing zone files rather than writing to a temporary file and renaming. This could lead to empty or partial zone files being left around in certain error conditions involving the initial transfer of a slave zone, interfering with subsequent server startup. [RT #282] 434. [func] New function isc_file_isabsolute(). 433. [func] isc_base64_decodestring() now accepts newlines within the base64 data. This makes it possible to break up the key data in a "trusted-keys" statement into multiple lines. [RT #284] 432. [func] Added refresh/retry jitter. The actual refresh/ retry time is now a random value between 75% and 100% of the configured value. 431. [func] Log at ISC_LOG_INFO when a zone is successfully loaded. 430. [bug] Rewrote the lightweight resolver client management code to handle shutdown correctly and general cleanup. 429. [bug] The space reserved for a TSIG record in a response was 2 bytes too short, leading to message generation failures. 428. [bug] rbtdb.c:find_closest_nxt() erroneously returned DNS_R_BADDB for nodes which had neither NXT nor SIG NXT (e.g. glue). This could cause SERVFAILs when generating negative responses in a secure zone. 427. [bug] Avoid going into an infinite loop when the validator gets a negative response to a key query where the records are signed by the missing key. 426. [bug] Attempting to generate an oversized RSA key could cause dnssec-keygen to dump core. 425. [bug] Warn about the auth-nxdomain default value change if there is no auth-nxdomain statement in the config file. [RT #287] 424. [bug] notify_createmessage() could trigger an assertion failure when creating the notify message failed, e.g. due to corrupt zones with multiple SOA records. [RT #279] 423. [bug] When responding to a recursive query, errors that occur after following a CNAME should cause the query to fail. [RT #274] 422. [func] get rid of isc_random_t, and make isc_random_get() and isc_random_jitter() use rand() internally instead of local state. Note that isc_random_*() functions are only for weak, non-critical "randomness" such as timing jitter and such. 421. [bug] nslookup would exit when given a blank line as input. 420. [bug] nslookup failed to implement the "exit" command. 419. [bug] The certificate type PKIX was misspelled as SKIX. 418. [bug] At debug levels >= 10, getting an unexpected socket receive error would crash the server while trying to log the error message. 417. [func] Add isc_app_block() and isc_app_unblock(), which allow an application to handle signals while blocking. 416. [bug] Slave zones with no master file tried to use a NULL pointer for a journal file name when they received an IXFR. [RT #273] 415. [bug] The logging code leaked file descriptors. 414. [bug] Server did not shut down until all incoming zone transfers were finished. 413. [bug] Notify could attempt to use the zone database after it had been unloaded. [RT #267] 412. [bug] named -v didn't print the version. 411. [bug] A typo in the HS A code caused an assertion failure. 410. [bug] lwres_gethostbyname() and company set lwres_h_errno to a random value on success. 409. [bug] If named was shut down early in the startup process, ns_omapi_shutdown() would attempt to lock an uninitialized mutex. [RT #262] 408. [bug] stub zones could leak memory and reference counts if all the masters were unreachable. 407. [bug] isc_rwlock_lock() would needlessly block readers when it reached the read quota even if no writers were waiting. 406. [bug] Log messages were occasionally lost or corrupted due to a race condition in isc_log_doit(). 405. [func] Add support for selective forwarding (forward zones) 404. [bug] The request library didn't completely work with IPv6. 403. [bug] "host" did not use the search list. 402. [bug] Treat undefined acls as errors, rather than warning and then later throwing an assertion. [RT #252] 401. [func] Added simple database API. 400. [bug] SIG(0) signing and verifying was done incorrectly. [RT #249] 399. [bug] When reloading the server with a config file containing a syntax error, it could catch an assertion failure trying to perform zone maintenance on, or sending notifies from, tentatively created zones whose views were never fully configured and lacked an address database and request manager. 398. [bug] "dig" sometimes caught an assertion failure when using TSIG, depending on the key length. 397. [func] Added utility functions dns_view_gettsig() and dns_view_getpeertsig(). 396. [doc] There is now a man page for "nsupdate" in doc/man/bin/nsupdate.8. 395. [bug] nslookup printed incorrect RR type mnemonics for RRs of type >= 21 [RT #237]. 394. [bug] Current name was not propagated via $INCLUDE. 393. [func] Initial answer while loading (awl) support. Entry points: dns_master_loadfileinc(), dns_master_loadstreaminc(), dns_master_loadbufferinc(). Note: calls to dns_master_load*inc() should be rate be rate limited so as to not use up all file descriptors. 392. [func] Add ISC_R_FAMILYNOSUPPORT. Returned when OS does not support the given address family requested. 391. [clarity] ISC_R_FAMILY -> ISC_R_FAMILYMISMATCH. 390. [func] The function dns_zone_setdbtype() now takes an argc/argv style vector of words and sets both the zone database type and its arguments, making the functions dns_zone_adddbarg() and dns_zone_cleardbargs() unnecessary. 389. [bug] Attempting to send a request over IPv6 using dns_request_create() on a system without IPv6 support caused an assertion failure [RT #235]. 388. [func] dig and host can now do reverse ipv6 lookups. 387. [func] Add dns_byaddr_createptrname(), which converts an address into the name used by a PTR query. 386. [bug] Missing strdup() of ACL name caused random ACL matching failures [RT #228]. 385. [cleanup] Removed functions dns_zone_equal(), dns_zone_print(), and dns_zt_print(). 384. [bug] nsupdate was incorrectly limiting TTLs to 65535 instead of 2147483647. 383. [func] When writing a master file, print the SOA and NS records (and their SIGs) before other records. 382. [bug] named -u failed on many Linux systems where the libc provided kernel headers do not match the current kernel. 381. [bug] Check for IPV6_RECVPKTINFO and use it instead of IPV6_PKTINFO if found. [RT #229] 380. [bug] nsupdate didn't work with IPv6. 379. [func] New library function isc_sockaddr_anyofpf(). 378. [func] named and lwresd will log the command line arguments they were started with in the "starting ..." message. 377. [bug] When additional data lookups were refused due to "allow-query", the databases were still being attached causing reference leaks. 376. [bug] The server should always use good entropy when performing cryptographic functions needing entropy. 375. [bug] Per-zone "allow-query" did not properly override the view/global one for CNAME targets and additional data [RT #220]. 374. [bug] SOA in authoritative negative responses had wrong TTL. 373. [func] nslookup is now installed by "make install". 372. [bug] Deal with Microsoft DNS servers appending two bytes of garbage to zone transfer requests. 371. [bug] At high debug levels, doing an outgoing zone transfer of a very large RRset could cause an assertion failure during logging. 370. [bug] The error messages for roll-forward failures were overly terse. 369. [func] Support new named.conf options, view and zone statements: max-retry-time, min-retry-time, max-refresh-time, min-refresh-time. 368. [func] Restructure the internal ".bind" view so that more zones can be added to it. 367. [bug] Allow proper selection of server on nslookup command line. 366. [func] Allow use of '-' batch file in dig for stdin. 365. [bug] nsupdate -k leaked memory. 364. [func] Added additional-from-{cache,auth} 363. [placeholder] 362. [bug] rndc no longer aborts if the configuration file is missing an options statement. [RT #209] 361. [func] When the RBT find or chain functions set the name and origin for a node that stores the root label the name is now set to an empty name, instead of ".", to simplify later use of the name and origin by dns_name_concatenate(), dns_name_totext() or dns_name_format(). 360. [func] dns_name_totext() and dns_name_format() now allow an empty name to be passed, which is formatted as "@". 359. [bug] dnssec-signzone occasionally signed glue records. 358. [cleanup] Rename the intermediate files used by the dnssec programs. 357. [bug] The zone file parser crashed if the argument to $INCLUDE was a quoted string. 356. [cleanup] isc_task_send no longer requires event->sender to be non-null. 355. [func] Added isc_dir_createunique(), similar to mkdtemp(). 354. [doc] Man pages for the dnssec tools are now included in the distribution, in doc/man/dnssec. 353. [bug] double increment in lwres/gethost.c:copytobuf(). [RT #187] 352. [bug] Race condition in dns_client_t startup could cause an assertion failure. 351. [bug] Constructing a response with rcode SERVFAIL to a TSIG signed query could crash the server. 350. [bug] Also-notify lists specified in the global options block were not correctly reference counted, causing a memory leak. 349. [bug] Processing a query with the CD bit set now works as expected. 348. [func] New boolean named.conf options 'additional-from-auth' and 'additional-from-cache' now supported in view and global options statement. 347. [bug] Don't crash if an argument is left off options in dig. 346. [placeholder] 345. [bug] Large-scale changes/cleanups to dig: * Significantly improve structure handling * Don't pre-load entire batch files * Add name/rr counting/limiting * Fix SIGINT handling * Shorten timeouts to match v8's behavior 344. [bug] When shutting down, lwresd sometimes tried to shut down its client tasks twice, triggering an assertion. 343. [bug] Although zone maintenance SOA queries and notify requests were signed with TSIG keys when configured for the server in case, the TSIG was not verified on the response. 342. [bug] The wrong name was being passed to dns_name_dup() when generating a TSIG key using TKEY. 341. [func] Support 'key' clause in named.conf zone masters statement to allow authentication via TSIG keys: masters { 10.0.0.1 port 5353 key "foo"; 10.0.0.2 ; }; 340. [bug] The top-level COPYRIGHT file was missing from the distribution. 339. [bug] DNSSEC validation of the response to an ANY query at a name with a CNAME RR in a secure zone triggered an assertion failure. 338. [bug] lwresd logged to syslog as named, not lwresd. 337. [bug] "dig" did not recognize "nsap-ptr" as an RR type on the command line. 336. [bug] "dig -f" used 64 k of memory for each line in the file. It now uses much less, though still proportionally to the file size. 335. [bug] named would occasionally attempt recursion when it was disallowed or undesired. 334. [func] Added hmac-md5 to libisc. 333. [bug] The resolver incorrectly accepted referrals to domains that were not parents of the query name, causing assertion failures. 332. [func] New function dns_name_reset(). 331. [bug] Only log "recursion denied" if RD is set. [RT #178] 330. [bug] Many debugging messages were partially formatted even when debugging was turned off, causing a significant decrease in query performance. 329. [func] omapi_auth_register() now takes a size_t argument for the length of a key's secret data. Previously OMAPI only stored secrets up to the first NUL byte. 328. [func] Added isc_base64_decodestring(). 327. [bug] rndc.conf parser wasn't correctly recognizing an IP address where a host specification was required. 326. [func] 'keys' in an 'inet' control statement is now required and must have at least one item in it. A "not supported" warning is now issued if a 'unix' control channel is defined. 325. [bug] isc_lex_gettoken was processing octal strings when ISC_LEXOPT_CNUMBER was not set. 324. [func] In the resolver, turn EDNS0 off if there is no response after a number of retransmissions. This is to allow queries some chance of succeeding even if all the authoritative servers of a zone silently discard EDNS0 requests instead of sending an error response like they ought to. 323. [bug] dns_rbt_findname() did not ignore empty rbt nodes. Because of this, servers authoritative for a parent and grandchild zone but not authoritative for the intervening child zone did not correctly issue referrals to the servers of the child zone. 322. [bug] Queries for KEY RRs are now sent to the parent server before the authoritative one, making DNSSEC insecurity proofs work in many cases where they previously didn't. 321. [bug] When synthesizing a CNAME RR for a DNAME response, query_addcname() failed to initialize the type and class of the CNAME dns_rdata_t, causing random failures. 320. [func] Multiple rndc changes: parses an rndc.conf file, uses authentication to talk to named, command line syntax changed. This will all be described in the ARM. 319. [func] The named.conf "controls" statement is now used to configure the OMAPI command channel. 318. [func] dns_c_ndcctx_destroy() could never return anything except ISC_R_SUCCESS; made it have void return instead. 317. [func] Use callbacks from libomapi to determine if a new connection is valid, and if a key requested to be used with that connection is valid. 316. [bug] Generate a warning if we detect an unexpected but treat as . 315. [bug] Handle non-empty blanks lines. [RT #163] 314. [func] The named.conf controls statement can now have more than one key specified for the inet clause. 313. [bug] When parsing resolv.conf, don't terminate on an error. Instead, parse as much as possible, but still return an error if one was found. 312. [bug] Increase the number of allowed elements in the resolv.conf search path from 6 to 8. If there are more than this, ignore the remainder rather than returning a failure in lwres_conf_parse. 311. [bug] lwres_conf_parse failed when the first line of resolv.conf was empty or a comment. 310. [func] Changes to named.conf "controls" statement (inet subtype only) - support "keys" clause controls { inet * port 1024 allow { any; } keys { "foo"; } } - allow "port xxx" to be left out of statement, in which case it defaults to omapi's default port of 953. 309. [bug] When sending a referral, the server did not look for name server addresses as glue in the zone holding the NS RRset in the case where this zone was not the same as the one where it looked for name server addresses as authoritative data. 308. [bug] Treat a SOA record not at top of zone as an error when loading a zone. [RT #154] 307. [bug] When canceling a query, the resolver didn't check for isc_socket_sendto() calls that did not yet have their completion events posted, so it could (rarely) end up destroying the query context and then want to use it again when the send event posted, triggering an assertion as it tried to cancel an already-canceled query. [RT #77] 306. [bug] Reading HMAC-MD5 private key files didn't work. 305. [bug] When reloading the server with a config file containing a syntax error, it could catch an assertion failure trying to perform zone maintenance on tentatively created zones whose views were never fully configured and lacked an address database. 304. [bug] If more than LWRES_CONFMAXNAMESERVERS servers are listed in resolv.conf, silently ignore them instead of returning failure. 303. [bug] Add additional sanity checks to differentiate a AXFR response vs a IXFR response. [RT #157] 302. [bug] In dig, host, and nslookup, MXNAME should be large enough to hold any legal domain name in presentation format + terminating NULL. 301. [bug] Uninitialized pointer in host:printmessage(). [RT #159] 300. [bug] Using both and didn't work on platforms lacking IPv6 because each included their own ipv6 header file for the missing definitions. Now each library's ipv6.h defines the wrapper symbol of the other (ISC_IPV6_H and LWRES_IPV6_H). 299. [cleanup] Get the user and group information before changing the root directory, so the administrator does not need to keep a copy of the user and group databases in the chroot'ed environment. Suggested by Hakan Olsson. 298. [bug] A mutex deadlock occurred during shutdown of the interface manager under certain conditions. Digital Unix systems were the most affected. 297. [bug] Specifying a key name that wasn't fully qualified in certain parts of the config file could cause an assertion failure. 296. [bug] "make install" from a separate build directory failed unless configure had been run in the source directory, too. 295. [bug] When invoked with type==CNAME and a message not constructed by dns_message_parse(), dns_message_findname() failed to find anything due to checking for attribute bits that are set only in dns_message_parse(). This caused an infinite loop when constructing the response to an ANY query at a CNAME in a secure zone. 294. [bug] If we run out of space in while processing glue when reading a master file and commit "current name" reverts to "name_current" instead of staying as "name_glue". 293. [port] Add support for FreeBSD 4.0 system tests. 292. [bug] Due to problems with the way some operating systems handle simultaneous listening on IPv4 and IPv6 addresses, the server no longer listens on IPv6 addresses by default. To revert to the previous behavior, specify "listen-on-v6 { any; };" in the config file. 291. [func] Caching servers no longer send outgoing queries over TCP just because the incoming recursive query was a TCP one. 290. [cleanup] +twiddle option to dig (for testing only) removed. 289. [cleanup] dig is now installed in $bindir instead of $sbindir. host is now installed in $bindir. (Be sure to remove any $sbindir/dig from a previous release.) 288. [func] rndc is now installed by "make install" into $sbindir. 287. [bug] rndc now works again as "rndc 127.1 reload" (for only that task). Parsing its configuration file and using digital signatures for authentication has been disabled until named supports the "controls" statement, post-9.0.0. 286. [bug] On Solaris 2, when named inherited a signal state where SIGHUP had the SIG_IGN action, SIGHUP would be ignored rather than causing the server to reload its configuration. 285. [bug] A change made to the dst API for beta4 inadvertently broke OMAPI's creation of a dst key from an incoming message, causing an assertion to be triggered. Fixed. 284. [func] The DNSSEC key generation and signing tools now generate randomness from keyboard input on systems that lack /dev/random. 283. [cleanup] The 'lwresd' program is now a link to 'named'. 282. [bug] The lexer now returns ISC_R_RANGE if parsed integer is too big for an unsigned long. 281. [bug] Fixed list of recognized config file category names. 280. [func] Add isc-config.sh, which can be used to more easily build applications that link with our libraries. 279. [bug] Private omapi function symbols shared between two or more files in libomapi.a were not namespace protected using the ISC convention of starting with the library name and two underscores ("omapi__"...) 278. [bug] bin/named/logconf.c:category_fromconf() didn't take note of when isc_log_categorybyname() wasn't able to find the category name and would then apply the channel list of the unknown category to all categories. 277. [bug] isc_log_categorybyname() and isc_log_modulebyname() would fail to find the first member of any category or module array apart from the internal defaults. Thus, for example, the "notify" category was improperly configured by named. 276. [bug] dig now supports maximum sized TCP messages. 275. [bug] The definition of lwres_gai_strerror() was missing the lwres_ prefix. 274. [bug] TSIG AXFR verify failed when talking to a BIND 8 server. 273. [func] The default for the 'transfer-format' option is now 'many-answers'. This will break zone transfers to BIND 4.9.5 and older unless there is an explicit 'one-answer' configuration. 272. [bug] The sending of large TCP responses was canceled in mid-transmission due to a race condition caused by the failure to set the client object's "newstate" variable correctly when transitioning to the "working" state. 271. [func] Attempt to probe the number of cpus in named if unspecified rather than defaulting to 1. 270. [func] Allow maximum sized TCP answers. 269. [bug] Failed DNSSEC validations could cause an assertion failure by causing clone_results() to be called with with hevent->node == NULL. 268. [doc] A plain text version of the Administrator Reference Manual is now included in the distribution, as doc/arm/Bv9ARM.txt. 267. [func] Nsupdate is now provided in the distribution. 266. [bug] zone.c:save_nsrrset() node was not initialized. 265. [bug] dns_request_create() now works for TCP. 264. [func] Dispatch can not take TCP sockets in connecting state. Set DNS_DISPATCHATTR_CONNECTED when calling dns_dispatch_createtcp() for connected TCP sockets or call dns_dispatch_starttcp() when the socket is connected. 263. [func] New logging channel type 'stderr' channel some-name { stderr; severity error; } 262. [bug] 'master' was not initialized in zone.c:stub_callback(). 261. [func] Add dns_zone_markdirty(). 260. [bug] Running named as a non-root user failed on Linux kernels new enough to support retaining capabilities after setuid(). 259. [func] New random-device and random-seed-file statements for global options block of named.conf. Both accept a single string argument. 258. [bug] Fixed printing of lwres_addr_t.address field. 257. [bug] The server detached the last zone manager reference too early, while it could still be in use by queries. This manifested itself as assertion failures during the shutdown process for busy name servers. [RT #133] 256. [func] isc_ratelimiter_t now has attach/detach semantics, and isc_ratelimiter_shutdown guarantees that the rate limiter is detached from its task. 255. [func] New function dns_zonemgr_attach(). 254. [bug] Suppress "query denied" messages on additional data lookups. --- 9.0.0b4 released --- 253. [func] resolv.conf parser now recognizes ';' and '#' as comments (anywhere in line, not just as the beginning). 252. [bug] resolv.conf parser mishandled masks on sortlists. It also aborted when an unrecognized keyword was seen, now it silently ignores the entire line. 251. [bug] lwresd caught an assertion failure on startup. 250. [bug] fixed handling of size+unit when value would be too large for internal representation. 249. [cleanup] max-cache-size config option now takes a size-spec like 'datasize', except 'default' is not allowed. 248. [bug] global lame-ttl option was not being printed when config structures were written out. 247. [cleanup] Rename cache-size config option to max-cache-size. 246. [func] Rename global option cachesize to cache-size and add corresponding option to view statement. 245. [bug] If an uncompressed name will take more than 255 bytes and the buffer is sufficiently long, dns_name_fromwire should return DNS_R_FORMERR, not ISC_R_NOSPACE. This bug caused cause the server to catch an assertion failure when it received a query for a name longer than 255 bytes. 244. [bug] empty named.conf file and empty options statement are now parsed properly. 243. [func] new cachesize option for named.conf 242. [cleanup] fixed incorrect warning about auth-nxdomain usage. 241. [cleanup] nscount and soacount have been removed from the dns_master_*() argument lists. 240. [func] databases now come in three flavours: zone, cache and stub. 239. [func] If ISC_MEM_DEBUG is enabled, the variable isc_mem_debugging controls whether messages are printed or not. 238. [cleanup] A few more compilation warnings have been quieted: + missing sigwait prototype on BSD/OS 4.0/4.0.1. + PTHREAD_ONCE_INIT unbraced initializer warnings on Solaris 2.8. + IN6ADDR_ANY_INIT unbraced initializer warnings on BSD/OS 4.*, Linux and Solaris 2.8. 237. [bug] If connect() returned ENOBUFS when the resolver was initiating a TCP query, the socket didn't get destroyed, and the server did not shut down cleanly. 236. [func] Added new listen-on-v6 config file statement. 235. [func] Consider it a config file error if a listen-on statement has an IPv6 address in it, or a listen-on-v6 statement has an IPv4 address in it. 234. [bug] Allow a trusted-key's first field (domain-name) be either a quoted or an unquoted string, instead of requiring a quoted string. 233. [cleanup] Convert all config structure integer values to unsigned integer (isc_uint32_t) to match grammar. 232. [bug] Allow slave zones to not have a file. 231. [func] Support new 'port' clause in config file options section. Causes 'listen-on', 'masters' and 'also-notify' statements to use its value instead of default (53). 230. [func] Replace the dst sign/verify API with a cleaner one. 229. [func] Support config file sig-validity-interval statement in options, views and zone statements (master zones only). 228. [cleanup] Logging messages in config module stripped of trailing period. 227. [cleanup] The enumerated identifiers dns_rdataclass_*, dns_rcode_*, dns_opcode_*, and dns_trust_* are also now cast to their appropriate types, as with dns_rdatatype_* in item number 225 below. 226. [func] dns_name_totext() now always prints the root name as '.', even when omit_final_dot is true. 225. [cleanup] The enumerated dns_rdatatype_* identifiers are now cast to dns_rdatatype_t via macros of their same name so that they are of the proper integral type wherever a dns_rdatatype_t is needed. 224. [cleanup] The entire project builds cleanly with gcc's -Wcast-qual and -Wwrite-strings warnings enabled, which is now the default when using gcc. (Warnings from confparser.c, because of yacc's code, are unfortunately to be expected.) 223. [func] Several functions were re-prototyped to qualify one or more of their arguments with "const". Similarly, several functions that return pointers now have those pointers qualified with const. 222. [bug] The global 'also-notify' option was ignored. 221. [bug] An uninitialized variable was sometimes passed to dns_rdata_freestruct() when loading a zone, causing an assertion failure. 220. [cleanup] Set the default outgoing port in the view, and set it in sockaddrs returned from the ADB. [31-May-2000 explorer] 219. [bug] Signed truncated messages more correctly follow the respective specs. 218. [func] When an rdataset is signed, its ttl is normalized based on the signature validity period. 217. [func] Also-notify and trusted-keys can now be used in the 'view' statement. 216. [func] The 'max-cache-ttl' and 'max-ncache-ttl' options now work. 215. [bug] Failures at certain points in request processing could cause the assertion INSIST(client->lockview == NULL) to be triggered. 214. [func] New public function isc_netaddr_format(), for formatting network addresses in log messages. 213. [bug] Don't leak memory when reloading the zone if an update-policy clause was present in the old zone. 212. [func] Added dns_message_get/settsigkey, to make TSIG key management reasonable. 211. [func] The 'key' and 'server' statements can now occur inside 'view' statements. 210. [bug] The 'allow-transfer' option was ignored for slave zones, and the 'transfers-per-ns' option was was ignored for all zones. 209. [cleanup] Upgraded openssl files to new version 0.9.5a 208. [func] Added ISC_OFFSET_MAXIMUM for the maximum value of an isc_offset_t. 207. [func] The dnssec tools properly use the logging subsystem. 206. [cleanup] dst now stores the key name as a dns_name_t, not a char *. 205. [cleanup] On IRIX, turn off the mostly harmless warnings 1692 ("prototyped function redeclared without prototype") and 1552 ("variable ... set but not used") when compiling in the lib/dns/sec/{dnssafe,openssl} directories, which contain code imported from outside sources. 204. [cleanup] On HP/UX, pass +vnocompatwarnings to the linker to quiet the warnings that "The linked output may not run on a PA 1.x system." 203. [func] notify and zone soa queries are now tsig signed when appropriate. 202. [func] isc_lex_getsourceline() changed from returning int to returning unsigned long, the type of its underlying counter. 201. [cleanup] Removed the test/sdig program, it has been replaced by bin/dig/dig. --- 9.0.0b3 released --- 200. [bug] Failures in sending query responses to clients (e.g., running out of network buffers) were not logged. 199. [bug] isc_heap_delete() sometimes violated the heap invariant, causing timer events not to be posted when due. 198. [func] Dispatch managers hold memory pools which any managed dispatcher may use. This allows us to avoid dipping into the memory context for most allocations. [19-May-2000 explorer] 197. [bug] When an incoming AXFR or IXFR completes, the zone's internal state is refreshed from the SOA data. [19-May-2000 explorer] 196. [func] Dispatchers can be shared easily between views and/or interfaces. [19-May-2000 explorer] 195. [bug] Including the NXT record of the root domain in a negative response caused an assertion failure. 194. [doc] The PDF version of the Administrator's Reference Manual is no longer included in the ISC BIND9 distribution. 193. [func] changed dst_key_free() prototype. 192. [bug] Zone configuration validation is now done at end of config file parsing, and before loading callbacks. 191. [func] Patched to compile on UnixWare 7.x. This platform is not directly supported by the ISC. 190. [cleanup] The DNSSEC tools have been moved to a separate directory dnssec/ and given the following new, more descriptive names: dnssec-keygen dnssec-signzone dnssec-signkey dnssec-makekeyset Their command line arguments have also been changed to be more consistent. dnssec-keygen now prints the name of the generated key files (sans extension) on standard output to simplify its use in automated scripts. 189. [func] isc_time_secondsastimet(), a new function, will ensure that the number of seconds in an isc_time_t does not exceed the range of a time_t, or return ISC_R_RANGE. Similarly, isc_time_now(), isc_time_nowplusinterval(), isc_time_add() and isc_time_subtract() now check the range for overflow/underflow. In the case of isc_time_subtract, this changed a calling requirement (ie, something that could generate an assertion) into merely a condition that returns an error result. isc_time_add() and isc_time_subtract() were void- valued before but now return isc_result_t. 188. [func] Log a warning message when an incoming zone transfer contains out-of-zone data. 187. [func] isc_ratelimiter_enqueue() has an additional argument 'task'. 186. [func] dns_request_getresponse() has an additional argument 'preserve_order'. 185. [bug] Fixed up handling of ISC_MEMCLUSTER_LEGACY. Several public functions did not have an isc__ prefix, and referred to functions that had previously been renamed. 184. [cleanup] Variables/functions which began with two leading underscores were made to conform to the ANSI/ISO standard, which says that such names are reserved. 183. [func] ISC_LOG_PRINTTAG option for log channels. Useful for logging the program name or other identifier. 182. [cleanup] New command-line parameters for dnssec tools 181. [func] Added dst_key_buildfilename and dst_key_parsefilename 180. [func] New isc_result_t ISC_R_RANGE. Supersedes DNS_R_RANGE. 179. [func] options named.conf statement *must* now come before any zone or view statements. 178. [func] Post-load of named.conf check verifies a slave zone has non-empty list of masters defined. 177. [func] New per-zone boolean: enable-zone yes | no ; intended to let a zone be disabled without having to comment out the entire zone statement. 176. [func] New global and per-view option: max-cache-ttl number 175. [func] New global and per-view option: additional-data internal | minimal | maximal; 174. [func] New public function isc_sockaddr_format(), for formatting socket addresses in log messages. 173. [func] Keep a queue of zones waiting for zone transfer quota so that a new transfer can be dispatched immediately whenever quota becomes available. 172. [bug] $TTL directive was sometimes missing from dumped master files because totext_ctx_init() failed to initialize ctx->current_ttl_valid. 171. [cleanup] On NetBSD systems, the mit-pthreads or unproven-pthreads library is now always used unless --with-ptl2 is explicitly specified on the configure command line. The --with-mit-pthreads option is no longer needed and has been removed. 170. [cleanup] Remove inter server consistency checks from zone, these should return as a separate module in 9.1. dns_zone_checkservers(), dns_zone_checkparents(), dns_zone_checkchildren(), dns_zone_checkglue(). Remove dns_zone_setadb(), dns_zone_setresolver(), dns_zone_setrequestmgr() these should now be found via the view. 169. [func] ratelimiter can now process N events per interval. 168. [bug] include statements in named.conf caused syntax errors due to not consuming the semicolon ending the include statement before switching input streams. 167. [bug] Make lack of masters for a slave zone a soft error. 166. [bug] Keygen was overwriting existing keys if key_id conflicted, now it will retry, and non-null keys with key_id == 0 are not generated anymore. Key was not able to generate NOAUTHCONF DSA key, increased RSA key size to 2048 bits. 165. [cleanup] Silence "end-of-loop condition not reached" warnings from Solaris compiler. 164. [func] Added functions isc_stdio_open(), isc_stdio_close(), isc_stdio_seek(), isc_stdio_read(), isc_stdio_write(), isc_stdio_flush(), isc_stdio_sync(), isc_file_remove() to encapsulate nonportable usage of errno and sync. 163. [func] Added result codes ISC_R_FILENOTFOUND and ISC_R_FILEEXISTS. 162. [bug] Ensure proper range for arguments to ctype.h functions. 161. [cleanup] error in yyparse prototype that only HPUX caught. 160. [cleanup] getnet*() are not going to be implemented at this stage. 159. [func] Redefinition of config file elements is now an error (instead of a warning). 158. [bug] Log channel and category list copy routines weren't assigning properly to output parameter. 157. [port] Fix missing prototype for getopt(). 156. [func] Support new 'database' statement in zone. database "quoted-string"; 155. [bug] ns_notify_start() was not detaching the found zone. 154. [func] The signer now logs libdns warnings to stderr even when not verbose, and in a nicer format. 153. [func] dns_rdata_tostruct() 'mctx' is now optional. If 'mctx' is NULL then you need to preserve the 'rdata' until you have finished using the structure as there may be references to the associated memory. If 'mctx' is non-NULL it is guaranteed that there are no references to memory associated with 'rdata'. dns_rdata_freestruct() must be called if 'mctx' was non-NULL and may safely be called if 'mctx' was NULL. 152. [bug] keygen dumped core if domain name argument was omitted from command line. 151. [func] Support 'disabled' statement in zone config (causes zone to be parsed and then ignored). Currently must come after the 'type' clause. 150. [func] Support optional ports in masters and also-notify statements: masters [ port xxx ] { y.y.y.y [ port zzz ] ; } 149. [cleanup] Removed unused argument 'olist' from dns_c_view_unsetordering(). 148. [cleanup] Stop issuing some warnings about some configuration file statements that were not implemented, but now are. 147. [bug] Changed yacc union size to be smaller for yaccs that put yacc-stack on the real stack. 146. [cleanup] More general redundant header file cleanup. Rather than continuing to itemize every header which changed, this changelog entry just notes that if a header file did not need another header file that it was including in order to provide its advertised functionality, the inclusion of the other header file was removed. See util/check-includes for how this was tested. 145. [cleanup] Added and ISC_LANG_BEGINDECLS/ ISC_LANG_ENDDECLS to header files that had function prototypes, and removed it from those that did not. 144. [cleanup] libdns header files too numerous to name were made to conform to the same style for multiple inclusion protection. 143. [func] Added function dns_rdatatype_isknown(). 142. [cleanup] does not need or . 141. [bug] Corrupt requests with multiple questions could cause an assertion failure. 140. [cleanup] does not need or . 139. [cleanup] now includes instead of and . 138. [cleanup] isc_strtouq moved from str.[ch] to string.[ch] and renamed isc_string_touint64. isc_strsep moved from strsep.c to string.c and renamed isc_string_separate. 137. [cleanup] , , , and made to conform to the same style for multiple inclusion protection. 136. [cleanup] , , and Win32's needed ISC_LANG_BEGINDECLS/ISC_LANG_ENDDECLS. 135. [cleanup] Win32's did not need or , now uses in place of , and needed ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS. 134. [cleanup] does not need . 133. [cleanup] needs . 132. [cleanup] does not need , but does need . 131. [cleanup] and need for ISC_R_* codes used in macros. 130. [cleanup] does not need or , and now includes instead of . 129. [bug] The 'default_debug' log channel was not set up when 'category default' was present in the config file 128. [cleanup] had ISC_LANG_BEGINDECLS instead of ISC_LANG_ENDDECLS at end of header. 127. [cleanup] The contracts for the comparison routines dns_name_fullcompare(), dns_name_compare(), dns_name_rdatacompare(), and dns_rdata_compare() now specify that the order value returned is < 0, 0, or > 0 instead of -1, 0, or 1. 126. [cleanup] and need . 125. [cleanup] , , , , , , and do not need . 124. [func] signer now imports parent's zone key signature and creates null keys/sets zone status bit for children when necessary 123. [cleanup] does not need . 122. [cleanup] does not need or . 121. [cleanup] does not need or . Multiple inclusion protection symbol fixed from ISC_SYMBOL_H to ISC_SYMTAB_H. isc_symtab_t moved to . 120. [cleanup] does not need , , , or . 119. [cleanup] structure definitions for generic rdata structures do not have _generic_ in their names. 118. [cleanup] libdns.a is now namespace-clean, on NetBSD, excepting YACC crust (yyparse, etc) [2000-apr-27 explorer] 117. [cleanup] libdns.a changes: dns_zone_clearnotify() and dns_zone_addnotify() are replaced by dns_zone_setnotifyalso(). dns_zone_clearmasters() and dns_zone_addmaster() are replaced by dns_zone_setmasters(). 116. [func] Added for isc_offset_t (aka off_t on Unix systems). 115. [port] Shut up the -Wmissing-declarations warning about 's __sputaux on BSD/OS pre-4.1. 114. [cleanup] does not need or . 113. [func] Utility programs dig and host added. 112. [cleanup] does not need . 111. [cleanup] does not need or . 110. [cleanup] does not need or . 109. [bug] "make depend" did nothing for bin/tests/{db,mem,sockaddr,tasks,timers}/. 108. [cleanup] DNS_SETBIT/DNS_GETBIT/DNS_CLEARBIT moved from to and renamed to DNS_BIT_SET/DNS_BIT_GET/DNS_BIT_CLEAR. 107. [func] Add keysigner and keysettool. 106. [func] Allow dnssec verifications to ignore the validity period. Used by several of the dnssec tools. 105. [doc] doc/dev/coding.html expanded with other implicit conventions the developers have used. 104. [bug] Made compress_add and compress_find static to lib/dns/compress.c. 103. [func] libisc buffer API changes for : Added: isc_buffer_base(b) (pointer) isc_buffer_current(b) (pointer) isc_buffer_active(b) (pointer) isc_buffer_used(b) (pointer) isc_buffer_length(b) (int) isc_buffer_usedlength(b) (int) isc_buffer_consumedlength(b) (int) isc_buffer_remaininglength(b) (int) isc_buffer_activelength(b) (int) isc_buffer_availablelength(b) (int) Removed: ISC_BUFFER_USEDCOUNT(b) ISC_BUFFER_AVAILABLECOUNT(b) isc_buffer_type(b) Changed names: isc_buffer_used(b, r) -> isc_buffer_usedregion(b, r) isc_buffer_available(b, r) -> isc_buffer_available_region(b, r) isc_buffer_consumed(b, r) -> isc_buffer_consumedregion(b, r) isc_buffer_active(b, r) -> isc_buffer_activeregion(b, r) isc_buffer_remaining(b, r) -> isc_buffer_remainingregion(b, r) Buffer types were removed, so the ISC_BUFFERTYPE_* macros are no more, and the type argument to isc_buffer_init and isc_buffer_allocate were removed. isc_buffer_putstr is now void (instead of isc_result_t) and requires that the caller ensure that there is enough available buffer space for the string. 102. [port] Correctly detect inet_aton, inet_pton and inet_ptop on BSD/OS 4.1. 101. [cleanup] Quieted EGCS warnings from lib/isc/print.c. 100. [cleanup] does not need or . isc_random_t moved to . 99. [cleanup] Rate limiter now has separate shutdown() and destroy() functions, and it guarantees that all queued events are delivered even in the shutdown case. 98. [cleanup] does not need or unless ISC_PLATFORM_NEEDVSNPRINTF is defined. 97. [cleanup] does not need or . 96. [cleanup] does not need . 95. [cleanup] does not need . 94. [cleanup] Some installed header files did not compile as C++. 93. [cleanup] does not need . 92. [cleanup] does not need , , or . 91. [cleanup] does not need or . 90. [cleanup] Removed unneeded ISC_LANG_BEGINDECLS/ISC_LANG_ENDDECLS from . 89. [cleanup] does not need . 88. [cleanup] does not need or . isc_interface_t and isc_interfaceiter_t moved to . 87. [cleanup] does not need , or . 86. [cleanup] isc_bufferlist_t moved from to . 85. [cleanup] does not need , , , or . 84. [func] allow-query ACL checks now apply to all data added to a response. 83. [func] If the server is authoritative for both a delegating zone and its (nonsecure) delegatee, and a query is made for a KEY RR at the top of the delegatee, then the server will look for a KEY in the delegator if it is not found in the delegatee. 82. [cleanup] does not need . 81. [cleanup] and do not need . 80. [cleanup] does not need or . 79. [cleanup] does not need . 78. [cleanup] lwres_conftest renamed to lwresconf_test for consistency with other *_test programs. 77. [cleanup] typedef of isc_time_t and isc_interval_t moved from to . 76. [cleanup] Rewrote keygen. 75. [func] Don't load a zone if its database file is older than the last time the zone was loaded. 74. [cleanup] Removed mktemplate.o and ufile.o from libisc.a, subsumed by file.o. 73. [func] New "file" API in libisc, including new function isc_file_getmodtime, isc_mktemplate renamed to isc_file_mktemplate and isc_ufile renamed to isc_file_openunique. By no means an exhaustive API, it is just what's needed for now. 72. [func] DNS_RBTFIND_NOPREDECESSOR and DNS_RBTFIND_NOOPTIONS added for dns_rbt_findnode, the former to disable the setting of the chain to the predecessor, and the latter to make clear when no options are set. 71. [cleanup] Made explicit the implicit REQUIREs of isc_time_seconds, isc_time_nanoseconds, and isc_time_subtract. 70. [func] isc_time_set() added. 69. [bug] The zone object's master and also-notify lists grew longer with each server reload. 68. [func] Partial support for SIG(0) on incoming messages. 67. [performance] Allow use of alternate (compile-time supplied) OpenSSL libraries/headers. 66. [func] Data in authoritative zones should have a trust level beyond secure. 65. [cleanup] Removed obsolete typedef of dns_zone_callbackarg_t from . 64. [func] The RBT, DB, and zone table APIs now allow the caller find the most-enclosing superdomain of a name. 63. [func] Generate NOTIFY messages. 62. [func] Add UDP refresh support. 61. [cleanup] Use single quotes consistently in log messages. 60. [func] Catch and disallow singleton types on message parse. 59. [bug] Cause net/host unreachable to be a hard error when sending and receiving. 58. [bug] bin/named/query.c could sometimes trigger the (client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) == 0 assertion in query_newname(). 57. [func] Added dns_nxt_typepresent() 56. [bug] SIG records were not properly returned in cached negative answers. 55. [bug] Responses containing multiple names in the authority section were not negatively cached. 54. [bug] If a fetch with sigrdataset==NULL joined one with sigrdataset!=NULL or vice versa, the resolver could catch an assertion or lose signature data, respectively. 53. [port] freebsd 4.0: lib/isc/unix/socket.c requires . 52. [bug] rndc: taskmgr and socketmgr were not initialized to NULL. 51. [cleanup] dns/compress.h and dns/zt.h did not need to include dns/rbt.h; it was needed only by compress.c and zt.c. 50. [func] RBT deletion no longer requires a valid chain to work, and dns_rbt_deletenode was added. 49. [func] Each cache now has its own mctx. 48. [func] isc_task_create() no longer takes an mctx. isc_task_mem() has been eliminated. 47. [func] A number of modules now use memory context reference counting. 46. [func] Memory contexts are now reference counted. Added isc_mem_inuse() and isc_mem_preallocate(). Renamed isc_mem_destroy_check() to isc_mem_setdestroycheck(). 45. [bug] The trusted-key statement incorrectly loaded keys. 44. [bug] Don't include authority data if it would force us to unset the AD bit in the message. 43. [bug] DNSSEC verification of cached rdatasets was failing. 42. [cleanup] Simplified logging of messages with embedded domain names by introducing a new convenience function dns_name_format(). 41. [func] Use PR_SET_KEEPCAPS on Linux 2.3.99-pre3 and later to allow 'named' to run as a non-root user while retaining the ability to bind() to privileged ports. 40. [func] Introduced new logging category "dnssec" and logging module "dns/validator". 39. [cleanup] Moved the typedefs for isc_region_t, isc_textregion_t, and isc_lex_t to . 38. [bug] TSIG signed incoming zone transfers work now. 37. [bug] If the first RR in an incoming zone transfer was not an SOA, the server died with an assertion failure instead of just reporting an error. 36. [cleanup] Change DNS_R_SUCCESS (and others) to ISC_R_SUCCESS 35. [performance] Log messages which are of a level too high to be logged by any channel in the logging configuration will not cause the log mutex to be locked. 34. [bug] Recursion was allowed even with 'recursion no'. 33. [func] The RBT now maintains a parent pointer at each node. 32. [cleanup] bin/lwresd/client.c needs for memset() prototype. 31. [bug] Use ${LIBTOOL} to compile bin/named/main.@O@. 30. [func] config file grammar change to support optional class type for a view. 29. [func] support new config file view options: auth-nxdomain recursion query-source query-source-v6 transfer-source transfer-source-v6 max-transfer-time-out max-transfer-idle-out transfer-format request-ixfr provide-ixfr cleaning-interval fetch-glue notify rfc2308-type1 lame-ttl max-ncache-ttl min-roots 28. [func] support lame-ttl, min-roots and serial-queries config global options. 27. [bug] Only include on BSD/OS 4.[01]*. Including it on other platforms (eg, NetBSD) can cause a forced #error from the C preprocessor. 26. [func] new match-clients statement in config file view. 25. [bug] make install failed to install and . 24. [cleanup] Eliminate some unnecessary #includes of header files from header files. 23. [cleanup] Provide more context in log messages about client requests, using a new function ns_client_log(). 22. [bug] SIGs weren't returned in the answer section when the query resulted in a fetch. 21. [port] Look at STD_CINCLUDES after CINCLUDES during compilation, so additional system include directories can be searched but header files in the bind9 source tree with conflicting names take precedence. This avoids issues with installed versions of dnssafe and openssl. 20. [func] Configuration file post-load validation of zones failed if there were no zones. 19. [bug] dns_zone_notifyreceive() failed to unlock the zone lock in certain error cases. 18. [bug] Use AC_TRY_LINK rather than AC_TRY_COMPILE in configure.in to check for presence of in6addr_any. 17. [func] Do configuration file post-load validation of zones. 16. [bug] put quotes around key names on config file output to avoid possible keyword clashes. 15. [func] Add dns_name_dupwithoffsets(). This function is improves comparison performance for duped names. 14. [bug] free_rbtdb() could have 'put' unallocated memory in an unlikely error path. 13. [bug] lib/dns/master.c and lib/dns/xfrin.c didn't ignore out-of-zone data. 12. [bug] Fixed possible uninitialized variable error. 11. [bug] axfr_rrstream_first() didn't check the result code of db_rr_iterator_first(), possibly causing an assertion to be triggered later. 10. [bug] A bug in the code which makes EDNS0 OPT records in bin/named/client.c and lib/dns/resolver.c could trigger an assertion. 9. [cleanup] replaced bit-setting code in confctx.c and replaced repeated code with macro calls. 8. [bug] Shutdown of incoming zone transfer accessed freed memory. 7. [cleanup] removed 'listen-on' from view statement. 6. [bug] quote RR names when generating config file to prevent possible clash with config file keywords (such as 'key'). 5. [func] syntax change to named.conf file: new ssu grant/deny statements must now be enclosed by an 'update-policy' block. 4. [port] bin/named/unix/os.c didn't compile on systems with linux 2.3 kernel includes due to conflicts between C library includes and the kernel includes. We now get only what we need from , and avoid pulling in other linux kernel .h files. 3. [bug] TKEYs go in the answer section of responses, not the additional section. 2. [bug] Generating cryptographic randomness failed on systems without /dev/random. 1. [bug] The installdirs rule in lib/isc/unix/include/isc/Makefile.in had a typo which prevented the isc directory from being created if it didn't exist. --- 9.0.0b2 released --- # This tells Emacs to use hard tabs in this file. # Local Variables: # indent-tabs-mode: t # End: bind9-9.10.3.dfsg.P4/doc/0002755000470500017500000000000012672612753014150 5ustar lamontlamontbind9-9.10.3.dfsg.P4/doc/xsl/0002755000470500017500000000000012664730166014756 5ustar lamontlamontbind9-9.10.3.dfsg.P4/doc/xsl/isc-docbook-chunk.xsl.in0000644000470500017500000000454412664710322021412 0ustar lamontlamont ansi - $Id$

@BIND9_VERSIONSTRING@

bind9-9.10.3.dfsg.P4/doc/xsl/isc-docbook-text.xsl0000644000470500017500000000336512664710322020661 0ustar lamontlamont bind9-9.10.3.dfsg.P4/doc/xsl/Makefile.in0000644000470500017500000000204112664710322017006 0ustar lamontlamont# Copyright (C) 2005, 2007, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = TARGETS = @BIND9_MAKE_RULES@ distclean:: rm -f isc-docbook-chunk.xsl isc-docbook-html.xsl \ isc-docbook-latex.xsl isc-manpage.xsl \ isc-notes-html.xsl isc-notes-latex.xsl bind9-9.10.3.dfsg.P4/doc/xsl/isc-manpage.xsl.in0000644000470500017500000001117012664710322020265 0ustar lamontlamont .\" ansi .\" .\" $Id$ .\" .hy 0 .ad l .RS .B " : :" .RE .HP .nf .fi bind9-9.10.3.dfsg.P4/doc/xsl/isc-docbook-html.xsl.in0000644000470500017500000000411612664710322021241 0ustar lamontlamont ansi - $Id$

@BIND9_VERSIONSTRING@

bind9-9.10.3.dfsg.P4/doc/xsl/pre-latex.xsl0000644000470500017500000000356612664710322017407 0ustar lamontlamont --- bind9-9.10.3.dfsg.P4/doc/xsl/isc-notes-html.xsl.in0000644000470500017500000000407512664710322020755 0ustar lamontlamont ansi - $Id$

@BIND9_VERSIONSTRING@

bind9-9.10.3.dfsg.P4/doc/xsl/isc-docbook-latex-mappings.xml0000644000470500017500000000301112664710322022604 0ustar lamontlamont % % ------------------------------------------------------------- % Refentry % ------------------------------------------------------------- \section{%title%} \label{%id%}\hypertarget{%id%}{}% bind9-9.10.3.dfsg.P4/doc/xsl/isc-docbook-latex.xsl.in0000644000470500017500000001447012664710322021416 0ustar lamontlamont 10pt,twoside,openright ansi , % \par [ ] \begin{titlepage} \null\vfil \vskip 60pt \begin{center}% { %\LARGE \Huge \bfseries \par}% \vskip 3em% { %\large \Large \lineskip .75em% \par} %\vskip 1.5em% \vfil % Not sure exactly how much to trim logo, but given that % this is a centered environment, we need not be too precise % so long as the image is centered in the input PDF, we % trim enough for it to fit on page, and we do not trim % so much that we clip out part of the graphic itself. % This seems to work, anyway. \includegraphics[trim=400 400 400 400,scale=2.5]{isc-logo} \end{center}\par \vfil\null \end{titlepage} \pagestyle{fancy} \fancyfoot[ce,co]{\thepage} \fancyfoot[le,ro]{@BIND9_VERSIONSTRING@} \renewcommand{\headrulewidth}{0.4 pt} \fancypagestyle{plain}{% \fancyhf{}% \fancyfoot[ce,co]{\thepage}% \fancyfoot[le,ro]{@BIND9_VERSIONSTRING@}% \renewcommand{\headrulewidth}{0 pt} } \thispagestyle{empty} \begin{center} \end{center} \begin{center} \end{center} \vfill \begin{center} Internet System Consortium \\ 950 Charter Street \\ Redwood City, California \\ USA \\ http://www.isc.org/ \end{center} \newpage \pagenumbering{roman} \tableofcontents \newpage \pagenumbering{arabic} \mbox{ } bind9-9.10.3.dfsg.P4/doc/xsl/copyright.xsl0000644000470500017500000000575712664710322017522 0ustar lamontlamont Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. Copyright (C) bind9-9.10.3.dfsg.P4/doc/xsl/isc-notes-latex.xsl.in0000644000470500017500000000711212664710322021121 0ustar lamontlamont 10pt,twoside,openright ansi , a4paper,10pt,twoside,openright \par [ ] \mbox{ } bind9-9.10.3.dfsg.P4/doc/doxygen/0002755000470500017500000000000012672612753015625 5ustar lamontlamontbind9-9.10.3.dfsg.P4/doc/doxygen/doxygen-input-filter.in0000644000470500017500000000354112664710322022243 0ustar lamontlamont#!@PERL@ -w # # Copyright (C) 2006, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: doxygen-input-filter.in,v 1.4 2007/06/19 23:47:13 tbox Exp $ # Input filter for feeding our source code into Doxygen. # Slurp whole file at once undef $/; $_ = <>; # It turns out that there are a lot of cases where we'd really like to # use what Doxygen calls "brief" documentation in a comment. Doxygen # has a shorthand way of doing this -- if one is writing C++. ISC # coding conventions require C, not C++, so we have to do it the # verbose way, which makes a lot of comments too long to fit on a # single line without violating another ISC coding standard (80 # character line limit). # # So we use Doxygen's input filter mechanism to define our own # brief comment convention: # # /*% foo */ # # expands to # # /*! \brief foo */ # # and # # /*%< foo */ # # expands to # # /*!< \brief foo */ # s{/\*%( $title bind9-9.10.3.dfsg.P4/doc/doxygen/mainpage0000644000470500017500000000754112664710322017326 0ustar lamontlamont// -*- C++ -*- // $Id: mainpage,v 1.2 2006/12/22 01:44:59 marka Exp $ // // Doxygen text. Lines beginning with two slashes are comments; lines // beginning with three slashes are Doxygen input. /// \mainpage /// \section mainpage_overview Overview /// \par /// /// This is the beginning of an internals manual for BIND9. It's /// still very rough in many places. /// /// \li See the files in doc/doxygen for the source to this page and /// the Doxygen configuration that generates the rest of the manual. /// /// \li See the tabs at the top of the screen to navigate through the /// generated documentation. /// /// \li See
the Doxygen web site /// for more information about Doxygen, including its manual. /// /// \section mainpage_knownissues Known Issues /// \par /// /// Known issues with our current use of Doxygen: /// /// \li In a major departure from previous attempts to use Doxygen /// with BIND9, this manual attempts to take the simplest approach /// to every choice Doxygen gives us. We don't generate fancy /// extra Doxygen tags files from the RFC database. We don't /// attempt to use Doxygen as a wrapper framework for other /// documentation (eg, ISC Tech Notes, the ARM, ...). We don't /// try to generate the list of files to document on the fly. /// Instead, we attempt to use Doxygen's native facilities /// wherever possible, on the assumption that we'll add new /// features later as we need them but should start as simply as /// we can. /// /// \li Our use of \\file is wrong in many places. We probably should /// be marking header files with the names by which we include /// them (eg, "dns/resolver.h"). Doxygen reports filename /// conflicts in a few cases where it can't work out which of /// several files to use. /// /// \li At the moment we're instructing Doxygen to document all /// functions, whether they have proper comment markup or not. /// This is a good way to see what's been marked up, but might not /// be the right approach in the long run. /// /// \li See doc/doxygen/doxygen-input-filter.in for local abbreviations. /// /// \li We're probably over-using the \\brief markup tag. /// /// \li We may in fact be confusing Doxygen to the point where it's /// not finding markup comments that it should. Needs /// investigation. /// /// \li At the moment I have all the cool "dot" stuff turned off, /// both because it's a distraction and because it slows down /// doxygen runs. Maybe after I get a faster desk machine. :) /// /// \li At the moment we're producing a single "BIND9 Internals" /// manual. One of our previous complications was an attempt to /// produce separate manuals for each library, then cross-link /// them. We might still need separate library manuals, but, if /// so, it might be easier to have the BIND9 Internals manual be a /// superset of the library manuals (ie, reuse the same source to /// produce differently scoped manuals). Would certainly be /// simpler than the cross-linking mess, but partly it's a /// question of how we want to present the material. /// /// \li Doxygen is slanted towards C++. It can be tuned towards plain /// old C, but the C++ bias still shows up in places, eg, the lack /// of top-level menu support for functions (in C++, the basic /// unit of programming is the class, which Doxygen does support /// directly). This is a bit annoying, but not all that /// critical. /// /// \li If we ever get really ambitious, we might try processing /// Doxygen's XML output, which is basicly a dump of what Doxygen /// was able to scrape from the sources. This would be a major /// project, just something to think about if there's something we /// really don't like about the output Doxygen generates. Punt /// for now. bind9-9.10.3.dfsg.P4/doc/doxygen/isc-footer.html0000644000470500017500000000207212664710322020554 0ustar lamontlamont
Generated on $datetime by Doxygen $doxygenversion for $projectname $projectnumber
bind9-9.10.3.dfsg.P4/doc/doxygen/Doxyfile.in0000644000470500017500000014647012664710322017742 0ustar lamontlamont# $Id: Doxyfile.in,v 1.2 2006/12/22 01:44:59 marka Exp $ # Doxyfile 1.4.7 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = "BIND9 Internals" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = $(BIND9_VERSION) # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, # Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, # Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, # Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, # Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # This tag can be used to specify the encoding used in the generated output. # The encoding is not always determined by the language that is chosen, # but also whether or not the output is meant for Windows or non-Windows users. # In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES # forces the Windows encoding (this is the default for the Windows binary), # whereas setting the tag to NO uses a Unix-style encoding (the default for # all platforms other than Windows). USE_WINDOWS_ENCODING = NO # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = @BIND9_TOP_BUILDDIR@/ # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like the Qt-style comments (thus requiring an # explicit @brief command for a brief description. JAVADOC_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the DETAILS_AT_TOP tag is set to YES then Doxygen # will output the detailed description near the top, like JavaDoc. # If set to NO, the detailed description appears after the member # documentation. DETAILS_AT_TOP = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for Java. # For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to # include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = YES # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = YES # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = YES # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = NO # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from the # version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = YES # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = @BIND9_TOP_BUILDDIR@/lib/isc \ @BIND9_TOP_BUILDDIR@/lib/dns \ @BIND9_TOP_BUILDDIR@/lib/isccfg \ @BIND9_TOP_BUILDDIR@/lib/isccc \ @BIND9_TOP_BUILDDIR@/lib/bind9 \ @BIND9_TOP_BUILDDIR@/bin/check \ @BIND9_TOP_BUILDDIR@/bin/dig \ @BIND9_TOP_BUILDDIR@/bin/dnssec \ @BIND9_TOP_BUILDDIR@/bin/named \ @BIND9_TOP_BUILDDIR@/bin/nsupdate \ @BIND9_TOP_BUILDDIR@/bin/rndc \ @BIND9_TOP_BUILDDIR@/doc/doxygen/mainpage # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py FILE_PATTERNS = *.c *.h *.dox # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = */win32/* */lib/dns/gen* */lib/dns/rdata/*.h # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = * # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = ./doxygen-input-filter # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = NO # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentstion. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = isc-header.html # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = isc-footer.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = YES # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = letter # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = YES # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = YES #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = YES # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = @PERL@ #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a call dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a caller dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable caller graphs for selected # functions only using the \callergraph command. CALLER_GRAPH = YES # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_WIDTH = 1024 # The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_HEIGHT = 1024 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that a graph may be further truncated if the graph's # image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH # and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), # the graph is not depth-constrained. MAX_DOT_GRAPH_DEPTH = 1000 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, which results in a white background. # Warning: Depending on the platform used, enabling this option may lead to # badly anti-aliased labels on the edges of a graph (i.e. they become hard to # read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = YES # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO # Local Variables: # compile-command: "doxygen" # End: bind9-9.10.3.dfsg.P4/doc/Makefile.in0000644000470500017500000000227012664710322016204 0ustar lamontlamont# Copyright (C) 2004-2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000, 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.11 2007/06/19 23:47:13 tbox Exp $ # This Makefile is a placeholder. It exists merely to make # sure that its directory gets created in the object directory # tree when doing a build using separate object directories. srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = arm misc xsl doxygen TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/doc/arm/0002755000470500017500000000000012672612753014727 5ustar lamontlamontbind9-9.10.3.dfsg.P4/doc/arm/man.dnssec-dsfromkey.html0000644000470500017500000002422512664710322021642 0ustar lamontlamont dnssec-dsfromkey

Name

dnssec-dsfromkey — DNSSEC DS RR generation tool

Synopsis

dnssec-dsfromkey [-v level] [-1] [-2] [-a alg] [-C] [-l domain] [-T TTL] {keyfile}

dnssec-dsfromkey {-s} [-1] [-2] [-a alg] [-K directory] [-l domain] [-s] [-c class] [-T TTL] [-f file] [-A] [-v level] {dnsname}

dnssec-dsfromkey [-h] [-V]

DESCRIPTION

dnssec-dsfromkey outputs the Delegation Signer (DS) resource record (RR), as defined in RFC 3658 and RFC 4509, for the given key(s).

OPTIONS

-1

Use SHA-1 as the digest algorithm (the default is to use both SHA-1 and SHA-256).

-2

Use SHA-256 as the digest algorithm.

-a algorithm

Select the digest algorithm. The value of algorithm must be one of SHA-1 (SHA1), SHA-256 (SHA256), GOST or SHA-384 (SHA384). These values are case insensitive.

-C

Generate CDS records rather than DS records. This is mutually exclusive with generating lookaside records.

-T TTL

Specifies the TTL of the DS records.

-K directory

Look for key files (or, in keyset mode, keyset- files) in directory.

-f file

Zone file mode: in place of the keyfile name, the argument is the DNS domain name of a zone master file, which can be read from file. If the zone name is the same as file, then it may be omitted.

If file is set to "-", then the zone data is read from the standard input. This makes it possible to use the output of the dig command as input, as in:

dig dnskey example.com | dnssec-dsfromkey -f - example.com

-A

Include ZSK's when generating DS records. Without this option, only keys which have the KSK flag set will be converted to DS records and printed. Useful only in zone file mode.

-l domain

Generate a DLV set instead of a DS set. The specified domain is appended to the name for each record in the set. The DNSSEC Lookaside Validation (DLV) RR is described in RFC 4431. This is mutually exclusive with generating CDS records.

-s

Keyset mode: in place of the keyfile name, the argument is the DNS domain name of a keyset file.

-c class

Specifies the DNS class (default is IN). Useful only in keyset or zone file mode.

-v level

Sets the debugging level.

-h

Prints usage information.

-V

Prints version information.

EXAMPLE

To build the SHA-256 DS RR from the Kexample.com.+003+26160 keyfile name, the following command would be issued:

dnssec-dsfromkey -2 Kexample.com.+003+26160

The command would print something like:

example.com. IN DS 26160 5 2 3A1EADA7A74B8D0BA86726B0C227AA85AB8BBD2B2004F41A868A54F0 C5EA0B94

FILES

The keyfile can be designed by the key identification Knnnn.+aaa+iiiii or the full file name Knnnn.+aaa+iiiii.key as generated by dnssec-keygen(8).

The keyset file name is built from the directory, the string keyset- and the dnsname.

CAVEAT

A keyfile error can give a "file not found" even if the file exists.

SEE ALSO

dnssec-keygen(8), dnssec-signzone(8), BIND 9 Administrator Reference Manual, RFC 3658, RFC 4431. RFC 4509.

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/Bv9ARM.ch07.html0000644000470500017500000002765312664710322017360 0ustar lamontlamont Chapter 7. BIND 9 Security Considerations

Chapter 7. BIND 9 Security Considerations

Access Control Lists

Access Control Lists (ACLs) are address match lists that you can set up and nickname for future use in allow-notify, allow-query, allow-query-on, allow-recursion, allow-recursion-on, blackhole, allow-transfer, etc.

Using ACLs allows you to have finer control over who can access your name server, without cluttering up your config files with huge lists of IP addresses.

It is a good idea to use ACLs, and to control access to your server. Limiting access to your server by outside parties can help prevent spoofing and denial of service (DoS) attacks against your server.

Here is an example of how to properly apply ACLs:

// Set up an ACL named "bogusnets" that will block
// RFC1918 space and some reserved space, which is
// commonly used in spoofing attacks.
acl bogusnets {
        0.0.0.0/8;  192.0.2.0/24; 224.0.0.0/3;
        10.0.0.0/8; 172.16.0.0/12; 192.168.0.0/16;
};

// Set up an ACL called our-nets. Replace this with the
// real IP numbers.
acl our-nets { x.x.x.x/24; x.x.x.x/21; };
options {
  ...
  ...
  allow-query { our-nets; };
  allow-recursion { our-nets; };
  ...
  blackhole { bogusnets; };
  ...
};

zone "example.com" {
  type master;
  file "m/example.com";
  allow-query { any; };
};

This allows recursive queries of the server from the outside unless recursion has been previously disabled.

Chroot and Setuid

On UNIX servers, it is possible to run BIND in a chrooted environment (using the chroot() function) by specifying the "-t" option for named. This can help improve system security by placing BIND in a "sandbox", which will limit the damage done if a server is compromised.

Another useful feature in the UNIX version of BIND is the ability to run the daemon as an unprivileged user ( -u user ). We suggest running as an unprivileged user when using the chroot feature.

Here is an example command line to load BIND in a chroot sandbox, /var/named, and to run named setuid to user 202:

/usr/local/sbin/named -u 202 -t /var/named

The chroot Environment

In order for a chroot environment to work properly in a particular directory (for example, /var/named), you will need to set up an environment that includes everything BIND needs to run. From BIND's point of view, /var/named is the root of the filesystem. You will need to adjust the values of options like like directory and pid-file to account for this.

Unlike with earlier versions of BIND, you typically will not need to compile named statically nor install shared libraries under the new root. However, depending on your operating system, you may need to set up things like /dev/zero, /dev/random, /dev/log, and /etc/localtime.

Using the setuid Function

Prior to running the named daemon, use the touch utility (to change file access and modification times) or the chown utility (to set the user id and/or group id) on files to which you want BIND to write.

Note

Note that if the named daemon is running as an unprivileged user, it will not be able to bind to new restricted ports if the server is reloaded.

Dynamic Update Security

Access to the dynamic update facility should be strictly limited. In earlier versions of BIND, the only way to do this was based on the IP address of the host requesting the update, by listing an IP address or network prefix in the allow-update zone option. This method is insecure since the source address of the update UDP packet is easily forged. Also note that if the IP addresses allowed by the allow-update option include the address of a slave server which performs forwarding of dynamic updates, the master can be trivially attacked by sending the update to the slave, which will forward it to the master with its own source IP address causing the master to approve it without question.

For these reasons, we strongly recommend that updates be cryptographically authenticated by means of transaction signatures (TSIG). That is, the allow-update option should list only TSIG key names, not IP addresses or network prefixes. Alternatively, the new update-policy option can be used.

Some sites choose to keep all dynamically-updated DNS data in a subdomain and delegate that subdomain to a separate zone. This way, the top-level zone containing critical data such as the IP addresses of public web and mail servers need not allow dynamic update at all.

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/notes.pdf0000644000470500017500000020143112664710322016541 0ustar lamontlamont%PDF-1.4 5 0 obj << /S /GoTo /D [6 0 R /FitH ] >> endobj 8 0 obj << /Length 2174 /Filter /FlateDecode >> stream xÚ­YK“Û¸¾ûW¨j/RÕŠC€ï­­T­=r¢¬­ñÎŒÃz3b™"µ|X™üú4Ð ¢H*©¤tÐh¢›ýü±… ?¶ð|Ëx´Çâ. Éá½x½¿¾aÄã†Ì Ã(„ÅÈîÚsBË y°X›‡¼}|sóÞq̵×ç‹Çç^<`óÀ]<¦¿/ÙjÍlÛ^Þ‹\ĵX­¹g/we#jœ>—NÞnw·8û²bŒ-EUge”Èb¶å¬?¹«?ÿŽb™yžk/Ö³¸ TýE¿AnqÛìKx…¸É¾“›áùï¢Òó\`t©e³)fNq­jÔá2 •—ŒÃ‡30¼aw¹Ý¹\zC»Kew9éí.9µÝåŽaw¹”šH–ζ‹Üúj{öÝQ`Ê~DjïÈ/R¤Hû½1ƒ#¿ë³™À2Sœ]˜0)Ç\4äŒZ“ã”5û´ŠOd×#8˜Ô”DjŸò,‰¥«¬© â[*!œJÈmy*ò2Nÿ“ò!£>–y ¥­Áùw¬a5®Êg)™`áP—ÏÍ)F"%YÉð]³¥ÌŒÀ‡?ůtÌñ<—­J˜BÜ)3ä‘myk[)ø³dy³yìêºã¹V!<Î-׉8Üþ¶Ð³_ûFÐ=±6ÁF’/O– ì›æøÓÍÍét²²:±Êêå&%óÖ7Cå<B[qœrÃΤ¹.:3ÅåiR¡¿Œx5°7Ô&È]»Ad9QÄÎãÞyÌ÷—¯e‹“S–ç8“ÅHy毙 ¿˜ö²úÞ!Æâ¡žÊ¶Á©ˆ“=ÎP€ê›¤[]¶Š˜Ø¤LõV¬eñ±µÌ›,D5bV²ëž%+¦ãÇ,Áz%Csç+ŠH®¢t+¢Å‹*‚¯u#õ|^°Ê«‡¾¥Áï3Y³‡@`Â…îŒûŸxÖzß5}Ê,ßñû“¤*_m %p ù¬DÍs!ñ,ŠOyQäI¼mª©2æ/7·»œ½»»ûu»ÁyylÐG\‰1Tï°Og$e›§8mªìåû< „æPéþ>³£G@uxÐa«N|¹¦¥¦yY‹t¬¬ë.6Àªñÿ~¿ràpdøÁe¡ý1é^Û‡"jWükpÍ8Xs]õðœÐÞÅC¡ã>6…ª.À™«Uæ˜Ó9 6!׫§²w±@>Ói@6œ†„´¥‰jnð@vÀ„—y‰;·»_>np `5Í1Wõ´tì1†j€d!¨8#NF¹Çœòôh#ìKnîs=ö²CÑ]ôœ¡ž3:/çLÆ tC‹³Ð›“k:^:®kñ2+´‹— ¡£ñr&ôcœË> pRj¼˜#A[\®ø2‰ (wÙ®`®˜ÚDÓ|YÄݹŠ®Š4QàÙ%ïhVÞC”N½÷ž<ËDè ¿6&<êûþ´G]Œäó+5¸f<ª¹®ztNhïÑ¡ÐqšBß/bi.òMTèͪ–kN_n_ $Qâ9Å @·-B)1c%ÀÚ»®¤+° ÉêJB^¾¼t»1=s÷é xfRª‘äÊ`Mû‡ÆûîÃv³{”`ýðùín#]êrêS8—¯p5Å•|9²ZÕ‘ÊPW«P·9A£JޱÒËA¿²»~{]Åq1f%ͬ8xúÂ~GŽE«ÓÑj;Và…á•h5¸f¢Us]Ö9¡}´…ŽG«)ôá(’LâÔ_þ—O¨zÇML÷dØ&Ȱ dØËíîaûð¸ \€ËŠð¿´üôŸtËt‘¥¾1¯À“kÚ-×5·Ì íÜr!tÔ-gBwXºM»ËF@þǹnÆßÛ¼ þ”‹óo]¼6‚ }¾Ÿsgy‡ºÍË£1OÈËkÒÞ~`1ßõ¯ØÛàš±·æºjï9¡½½‡BÇím ÝBé­¨FJ`æ0*WÏTñ–ÏQÙ@UX2éÜèøeyõ2§CikJ5?Çt’ù™˜qY—É7Açt-9Ê>œº!Nû,§cJ4!Õ)å”ÏyY~kÿ§ouÌ\ýÁµ#×›ÎRøŠw¯DÁ55šëjÔÌ í£f(t> endobj 26 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [353.9971 518.6335 529.3396 530.6932] /Subtype/Link/A<> >> endobj 9 0 obj << /D [6 0 R /XYZ 56.6929 773.2417 null] >> endobj 10 0 obj << /D [6 0 R /XYZ 56.6929 748.3351 null] >> endobj 11 0 obj << /D [6 0 R /XYZ 56.6929 748.3351 null] >> endobj 15 0 obj << /D [6 0 R /XYZ 56.6929 726.8519 null] >> endobj 16 0 obj << /D [6 0 R /XYZ 56.6929 726.8519 null] >> endobj 17 0 obj << /D [6 0 R /XYZ 56.6929 699.4258 null] >> endobj 21 0 obj << /D [6 0 R /XYZ 56.6929 565.396 null] >> endobj 22 0 obj << /D [6 0 R /XYZ 56.6929 540.5212 null] >> endobj 30 0 obj << /D [6 0 R /XYZ 56.6929 479.6797 null] >> endobj 31 0 obj << /D [6 0 R /XYZ 56.6929 451.8401 null] >> endobj 35 0 obj << /D [6 0 R /XYZ 56.6929 195.1691 null] >> endobj 36 0 obj << /D [6 0 R /XYZ 56.6929 169.2781 null] >> endobj 37 0 obj << /D [6 0 R /XYZ 56.6929 134.997 null] >> endobj 38 0 obj << /D [6 0 R /XYZ 56.6929 104.5073 null] >> endobj 7 0 obj << /Font << /F34 14 0 R /F36 20 0 R /F11 25 0 R /F37 29 0 R /F14 34 0 R >> /ProcSet [ /PDF /Text ] >> endobj 42 0 obj << /Length 950 /Filter /FlateDecode >> stream xÚVMÛ6½ï¯Ћ T4?E)( tۤضè¡ñ%Èæ Û´EX+º"µ®ÿ}‡"å•-'­}àœ™÷H͉$þ$9ÊKZ&R2D9‘Éæå'{ØûõD^Te“;»™`•I6Mò¸zX~`šÏX`…öh‘ "ÒuSmµiÆÝ†qcÚgŒé¾ïÞÄEÓE<íêÑýµjô¶Íü Á¹³ðLÃ9¶œµÊ6 O𲟭•nã£ý»Wölü¤jÏ§ê¼ „¤Ècàôó_ &ÓUØþŽFÉz[Iå¨ÄyždL B°Œ¥$c)½o#„Ù…ñ½S1ÑôÁà‰“P‹«Ú3æ$UC<§!?X;MÞx|úó—àT"‚Ú¶a<+¶œ ë½UNu/ºU1ÿºwa㤛&X­qÓðQ3^ç˜x`Špðª+;†©6X!¨Q•á.äó{òÅ´®¶(Ü!“{Áó Àûýp«‚bTˆ$§%ây»HØ>$£õû›n.Ù4$(GN€ç™=Ú¹£}·\žN'¤í™n¿ÜšSÛ˜jk—ÖìÜ©êTÀ©íGÓ¹09šFoÎË[þœJ¨"Ânøßhýâ5ç|uYólžówë˜IŒ8)øXÈy,ä"òª®ÚC(áO ÉSÓÿŸ*Ž1"=ƒ?y¨CXPÐ`ΦUavªMØ®¬ÕÖ]ŠÔ÷?únáw_ªC°€¶¤ã‚ÛÑ@–u£¼–iž>í®8šé›mpmô!R‰AGr9¨kÂO¾.U:œÑoCsˆÄƒ=´@‡&£O©Û~ îçc Ç÷RJ¡A{sç°lŽ*ZÓ‡Û¨q>ÔpÞïa‰•é1žÛo¿j«#8[Ó5R:Vûè M}./Î9¢‚‘¯éKà^l¼H„PQDü§¾.Ù4d®¯yæQ_ï†kϸ€ƒIy}ý·ÒƒÃª™ªà½ˆ(üÁ8gwUuñʦnsUͳMU5•ƒD’ƒèÂ]¢¯}GŒã7¿#&Nó·:-A²\ÒK*Ggxã×ÑÀ}êG2endstream endobj 41 0 obj << /Type /Page /Contents 42 0 R /Resources 40 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 39 0 R /Annots [ 48 0 R 51 0 R 52 0 R ] >> endobj 48 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [102.3292 626.9083 428.1075 637.7226] /Subtype/Link/A<> >> endobj 51 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [507.6985 553.6558 539.579 565.7155] /Subtype/Link/A<> >> endobj 52 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [55.6967 542.946 183.2184 553.1078] /Subtype/Link/A<> >> endobj 43 0 obj << /D [41 0 R /XYZ 56.6929 773.2417 null] >> endobj 44 0 obj << /D [41 0 R /XYZ 56.6929 748.3351 null] >> endobj 45 0 obj << /D [41 0 R /XYZ 56.6929 728.1838 null] >> endobj 46 0 obj << /D [41 0 R /XYZ 56.6929 683.4811 null] >> endobj 47 0 obj << /D [41 0 R /XYZ 56.6929 659.1415 null] >> endobj 49 0 obj << /D [41 0 R /XYZ 56.6929 612.7192 null] >> endobj 50 0 obj << /D [41 0 R /XYZ 56.6929 587.1343 null] >> endobj 40 0 obj << /Font << /F34 14 0 R /F14 34 0 R /F36 20 0 R /F11 25 0 R /F37 29 0 R >> /ProcSet [ /PDF /Text ] >> endobj 33 0 obj << /Length1 750 /Length2 576 /Length3 532 /Length 1110 /Filter /FlateDecode >> stream xÚSU ÖuLÉOJuËÏ+Ñ5Ô3´Rpö Ž44P0Ô3àRUu.JM,ÉÌÏsI,IµR0´´4Tp,MW04U00·22°25çRUpÎ/¨,ÊLÏ(QÐpÖ)2WpÌM-ÊLNÌSðM,ÉHÍš‘œ˜£œŸœ™ZR©§à˜“£ÒQ¬”ZœZT–š¢Çeh¨’™\¢”šž™Ç¥r‘g^Z¾‚9D8¥´&U–ZT t”‚Бš @'¦äçåT*¤¤¦qéûåíJº„ŽB7Ü­4'Ç/1d<8”0äs3s*¡*òs JKR‹|óSR‹òЕ†§B盚’Yš‹.ëY’˜“™ì˜—ž“ª kh¢g`l ‘È,vˬHM È,IÎPHKÌ)N‹§æ¥ ;|`‡è‡ùùúiCã,˜™WRYª`€P æ"øÀP*ʬPˆ6Ð300*B+Í2×¼äü”̼t#S3…Ä¢¢ÄJ.` òLª 2óRR+R+€.Ö×ËË/jQM­BZ~(ZÉI? ´©% q.L89åWTëY*èZš 644S077­EQ˜\ZT”šWN+Àà€ñÓ2A˜šZ‘šÌuóZ~²uKÖômm+ë\_XŪÏùóÄÚ—7ÙD쨛™Rl:/P1½dÉ«…¶öϾ(á•l=U¸h‹d¯_OÜ—EÂk¶v-X1¡Át¿Þ`ñÊæ®i¼ÿ´Õ_y. ›1§õ‘´Õþ¢Ç³:•un~Q®?Á3/å…SÔâ}ßï]ãÒ š¤¥$e~sû]F1ñÊ»Ï/ËÚQ?ý¸mò»³·|<ċݺÔ/¦Ùq'}Iüö„+6­ìâEíÀgޝ¼xT.‘òGÀ¿gtÅÙ¥vÕG‚—U|íª“®¾~ª€]üRÇëÞ…_kü9¹öË:½{ápËñGúý îûd}dN<6Îø-uBÛošHºÁ=c¦MÏvHžÎzºq½aûÿìRKë~,KÌž³}Š¬Ë›ªÂå»m¿‡Š÷Öêyo›ù~ÉîÃÜ×v‹ Û_¹éÜÿs>§ß¶.#ßҭߦíÈè{­/þô­É™kÜ—öÉ\mü|¢Ðr¢úÿXöÑñßϾØad­j|ïÇéÖR/ü,2 p0, HÎIM,*ÉÏM,ÊæfÎr”endstream endobj 34 0 obj << /Type /Font /Subtype /Type1 /Encoding 53 0 R /FirstChar 15 /LastChar 15 /Widths 54 0 R /BaseFont /VNRMMR+CMSY10 /FontDescriptor 32 0 R >> endobj 32 0 obj << /Ascent 750 /CapHeight 683 /Descent -194 /FontName /VNRMMR+CMSY10 /ItalicAngle -14.035 /StemV 85 /XHeight 431 /FontBBox [-29 -960 1116 775] /Flags 4 /CharSet (/bullet) /FontFile 33 0 R >> endobj 54 0 obj [500 ] endobj 53 0 obj << /Type /Encoding /Differences [ 0 /.notdef 15/bullet 16/.notdef] >> endobj 55 0 obj << /Type /Encoding /Differences [ 0 /.notdef 1/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash/ogonek/ring 10/.notdef 11/breve/minus 13/.notdef 14/Zcaron/zcaron/caron/dotlessi/dotlessj/ff/ffi/ffl/notequal/infinity/lessequal/greaterequal/partialdiff/summation/product/pi/grave/quotesingle/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde 127/.notdef 128/Euro/integral/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl/circumflex/perthousand/Scaron/guilsinglleft/OE/Omega/radical/approxequal 144/.notdef 147/quotedblleft/quotedblright/bullet/endash/emdash/tilde/trademark/scaron/guilsinglright/oe/Delta/lozenge/Ydieresis 160/.notdef 161/exclamdown/cent/sterling/currency/yen/brokenbar/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis] >> endobj 28 0 obj << /Length1 1612 /Length2 8314 /Length3 532 /Length 9143 /Filter /FlateDecode >> stream xÚíweT\ݲ-„„ Á îîÁ%Xp·¦Fº¡iÚ¸ ¸»{p× Á5Hp‚ .GòÝ{Ï}ß;ïÏ=ç×o±ÇØ«ªÖ¬Y5k­MK©ªÎ"n5É@!pVvA€2ØÎÌÉQ QdQY:Œ<è´´’0) …H™ÂA‚m9@ pr8Ði’P{WØÒ  ×TÓf`bbþ‡åwÀÌõ?=;Á–Àë‡g-ÔÞ?@ü7ªƒ@¸`¶$UTuå•eô²ÊšY3µ¨:™Ù‚E0q1, 0€í_  1ÿ.Í‘õKÜ` p´ÁÛ@.@ýo3À³;:>|ÀŽK˜)þÐ8†mÌx°[@ÿ²‡A"ì|`ªPG¸#¶‡²ªJÉüÅne ÿÛüà@-"Í¡@§ß%ýñ=ÀäÂr[‚!èl¿Ebp°ÿe7w²ÿOŸ3ö§Aô¿g†á„©9bë 0Y ³)Cá)ôÿ3•Yÿ}"ÿ$þ·üo‘÷_÷ïý·Cü¯žç¿CË8ÙÚ*›Ú= À_ àᆿï[SØÿnj¶uý'þ¨ ú‹äÿGnúÐ qˆåƒ ì¬ìÁŽ2`¹*´X˜Ú>tê]b‚Ù‚! Eÿ4ÀÂÁÎþ7Ÿ†hùÝzž¿\ ˆùßÉ?ˆô‡:›„¤ªÊ;M¦¿ß©¢T´‡k¸Ú?ûR” æÿµø!!u¸³<œ@N.>ïCB~Ï’í Ç?ÖJ¦pØ ÿP2;ÇŸÂÿãýÇÊðo0Ò Ôü÷¬¨ÃM!æãõ_†ßn  ö êŸÿPð®ÿ :ä¢ÏÍ@BþÖ‰)IðJÂŒÞ!)ý®”Þû‚jÜlïrh»WbðŠ@‰ÉmEk͈à]£ëô®ý¯ ÆÍþŽ—¶tíñ ƒ,ROj†Îlœo¯›ù˜6}ÙŒ 0“ö´Ãݧ—ëñ²km®½S3Ê¿E%iæ‚¡^0xS;g{ãÓœÛc!€ U‘-Ø5H¸•9»{¯c¶/Îé>ôõö´?éÜ aJ|F+äüóu˜·C:‰˜žf‰{jRís’ã¦Ã; í6w£LZbšP;ÅkUˬyH“âm쓤&1á%˜\ÃF©ÎË£‰‘0añ˜ñŒû'ZiGBáZÒa¿®Ÿc64~£)O«È{ÏÑw9»WÚ•3^wbeLö¾k)¨z_ºAËÎÒâTŠ%Ù`ïHëf0+ñÖ t[˜ ‰Œû|>¥m&ÒÜ1nS±§hža«Ly¥Êº[´C°SË›cZs,Õ=¬ØëW{¤§üEŽ:oïk3â ̹‹„æc‘ Ú9G˜Ž>FYâ)[MfK½â¤ÆEl[^ã‹F+’iÿ4i„@Ìó`š(j¬—f“©ƒAú÷»Ý[É.KÜÄ’·@§Ï/©ÐÇ&s@ÞlŒ„ÅY4¶âv:¹=lͯ‹Oê.t¸*"‹â)?Tä9Üô Îa¤ ûˆD¾ 7 l¾~nP áaÙ̼œ¤ò‚õ<±¹Ñ´¹êÅBqÃ’²Dÿ Ü’Ltâ:ø¡Ãâ]h¸˜’¸ï¹ÌÁD…YŽuØX+î çwÇÞ-ÿ꽜Ÿ[äI1ˆPþKU¹D\$é×[ˆ¶œ†)Vö5Å9N£yéc –‹»£€¥^¢Åpÿ!m+Jz¼4|Xhõê¸1ãå7Õh©ìk‚•­[Ä=ªxšä8³wI`aÙ'B#.tvË}&/”¨p[²©òôa<÷k.ؾ¦›ˆ,TÙ/ênÉS©ÍSi(ÂØCë—-O™?Ážƒ`º¥Ík|›U&˜vòéšO²„.w„·Í|£PêìJŸçQír…t)"H³÷½` Áû¤1æltAõ5Ž#/¿'!z [Ü/³eåö†\)l9–,oö3‹=ììÂ<7üúŸS>FO¹R2¶.ƒKºMùºðfÖØJi':ò‰°€]ÇàfY¦ôÙ5á'Ói>_ά‰Üéeüw_.Þ¿¤ÃhN°LIxVõ‰ÁÕz¹oGgƒû ‹;Ï-g§ò©V`´:ž}ˆ™ Í̬ö]–ºfòñ`möMûZÆò¿Éƒ~GƼ,,Ae¦P Mÿ=tÄÇÜÛÆ–‰29«`¹¥™í}k^C7³®_­^u_!ÕÖËývüù“…ø÷Èô]é^ZÈ­ÉÚ¡¹z§©‚¬'³·Io8³;]¯éíodU%•äÏRvóŸR_«¾«ž•¬8œCONÞ_ÜIv&wCËr—÷Ø +tpQ7ƒFÞ ñaËúi(—ÕGñ¸xJ<ÆIY;ÍØëÛþQÈ˶ãHɃ×N ¸ç‚¢Ë¡Syûûf«+ŸžŠB1ìv/m¸N"=ÂY į­µ@8™¼l‡þ̶­¸ t³Ý.‚X{ GfC=Mã.¾y6,“? õ2ÌÑdæë[˜e1šØäOm–¼ºU‚³¤ ø¬ÜtEl©?ÞSNí ‹Vþ,Ióß ¤¬SQü²’°¤­vÅÉ©š®ûÔ϶;Z¥½yjÕ{ØÔe÷á>¾¡ªóÉO9úy>,ª \Ab%öýîÓ‚ŠRm¦lÃ4Üùcp‡éÊSžyÞj,‘?:ùU¢ËïßI{CçtG,Ò6t¸ïz°¾œ~k2'o;B^R¤â–BŒ) ¦5q{;_® Ê%V•‘åä¡0EÌ›0X²M 6#/ö75.Å]g0ÑqÏ^ËË9bê½jV)ÎÁ¬;.¿,÷—kHMÇ©P>¼ªÝ¡ÖàdBÓt,ØOR®^Bû¤Ò?ÅÍ-S½sáÞ›R2è)Ù+5¯’ðÄz¿ÜŠ×Z·N~Kkú¤_Š"goWöâpÔ¯ ¿ÆM¼M¬‹î¢smÎý«;`–g›ù…IÑÔÛ{ ðíÓ/†gÏ„<æ½½—.Q1=3‘Ë’ & QZ"]É›´ŽæžH²rïmµó”µò‚âÏÖßî³ãÙ„5Ñ+Sdò±º&_¥í™ßð[ižiÆËZ%ö®ž¡ðù)•‰ŸX›\†º’®ÓØÙ}ó–6Î.‚Ë=óÈî€Õ{ûçËàÎ ƒ¥æ©Ö@ Ùi¦l‰zd“dz=&ÜM"¶Õ­ÞÃgÏÜa´_—DYñGDùgW„ç{¹}ûxÈ"à‚R9<]Î|[!èP2ÞûMØbÅdnÓ™®ThñqÅŒBjIÐàó‹%…íålrê,'´¤ÙWœÕaþÇ·Ç¥òL¬y,ô: ×Qâ Ÿ ÍÐÓùjÌÿë¬)ú‰8êœC"/ÿ›pÃ$×Dž Ï©Kk¯‘`›ˆAb¶ =>JRTÔÝÏ]û¬\É…–6RR—K®¾6b±#Œ€ŸÂ~ÃÊSdаð|ú'φé¢8Ÿ¶×Ç)PáëZ…n¿{j}u½#ñK¤ʤl¥ Ë/j/–¿ôPé( y…V*Ï1A…NJ,ÛR[Iòø¬;“DhB2 —*m.fœü]Fì…F÷“—(µ­A(®È@­“?v€H°YqŠx#ž«ÜÅXá~ ¨ã«*O eRÃ&rsû6×ïZÖ‚b>?áFÇdj¡¦b6‰*ŠFm‘•T¤(ª¸ÒY"?ŽqšÙl¡¥$Ñ·G+y•h-;}’aaÐ^ÄmÑ j6ÌÂPŸª±û<’r¾§ÏÚ0X¦bœÔí¦Ô&¡Wýüˆ¯È´tvµ„²£õ‚8ŠWn\ˆ_E•z·YBX3O`óþŽ÷Û6.û‹!]ÜlÊTk9õfÿ|cÛH*¼þg°)tlEÉ…QvZ™‚¤Â#·:½á8SÖŠ_«i,j¤Â¥B&áFFõ¢«èËQõ»b3Ædô葾“ã*èùÚ¸«ÿ2{lƒòvœt¢õD¥çª²«<÷6¼5Ô9ίªü1õ{2¯WÀ—b1nm=¤µjýXAº™rÃÀcJ¿ôíèD)ƒ÷hͨ^ÁDÕž…2y¥hÕåjzì’1aÒŒ¼;ûõª‘á:‚ú&H”&8ÕCU±˜c»Ö¶ˆ®Ÿ›I $ÑãÉqdœ§moÀPóf—-Ö×}õÕ…VN [j?½æ:U}aÉ­Q“WdžòZPg‡Tlðq×ǘŒ,[¤ÄRFŒä©•t-T³‘hD·â<ΰE«b8úûm¥ŒA ¯RD·Hø3ãožÔ%†rˆØÆwÓsPãJ‚fÞCaÕF¥‰×YYh¦–F³î>}Xž/„äÄ‚·…GñŽj˜Æ¬¤Nž…—#O2@s+öÙ±ì½KÚGT’IùÖ’,Æ…Å£x>$KT²|pE#Ê=³&`¾ºD IÓ°´fÁ (!uäî}·Þ®ÕêKÁunÜék†&Š1€ œü_¬X~i*F¹õž6 ãds¯ )Çì.¥Ÿ8X¾å£GgC«6>³ï¯]Ÿœ;¥mó¨¤$šc6/vü*NÎ[KS%Øîø_\™Ó¡‡ÑÍDǘTvŸ±]†ÇÌyb¾J„/M[?4wL[¥›¢[¶î@òƒÖB@AÏÅw™)(Æ8ÝoŸ}å 3¦xu [hÌäÀ²fÀkâ™ÿ‚Ü¥¨ž!’w×¼\õèt8ØwÚð»ím‹»XÅëFKÙBÂÝ×E/¤ýÜ»îv°Òc;O^ wùýüêð´Í¢×eyøh°E~X‹/==ñýgƒ§>%#‡ƒƒÙmb;WÍÈ·ÎÐ~ÃBcÞ3"\'üä°Õð[0WÔžL^w„ÏIwìRowËP4q÷=‘€+˜5ó¹Hsq“Y ŠËÌ$d ð k‡GÂÎWéĆ;ååä¶=ò‰${ûçTK¼#”1&Ž?*N.(šè}a{‰¸B2Ä"Á´ ±^J6‚ù[^RþraÁw:Ò¡±±ˆ-²}›þá•%×ón.c(+uSÉíÚ˜~»ù­bZ:žPv;!œÜVWŠŒ‰ÑåcYö¾RŒé·ÙÛV•˜~Ü8ö/æù`ßCBd"ñC‚­H4¥lËòÓËïv:w¿(åâå0GÙ§“ ëÊâÜ¢˜óÒU;JG6_Þ¼Fp½uš¡á÷˜'Ö‡Šdù=áñ½ä—c…ÈôO®sY¿É€´ª ù"OØãØΗ ©?ºÁ?©Æž÷ʺ>{KDi ­euµ»rÓÈÙÕVec  {-dW.냥7aT:PŽB:$òP•GYT«ÛɘJÃ8±þ= õc‹çi3ŠtôD+W½WÖ禳óç©#4Ìi£`pn‹q°ì/ð‹xç~|àkßðÆ·¸›n„Àq‡wqGØ–oŸè¦½ï¸™ÛÃd¼HÊB(¿”†#ü¨¶×ÃÍö• W:Î…î<0]ñ³¹$I 2ÜYbFä¾òvêš b+Øñ(.’ë*¾‡_¨] «èk#‡å(ƒÛã<ñ´ê÷ò¨,’‡©sBËrÝÔ¢¶û1ZÃòM=°Qêš·½Zädù©•&eIÙÃx¨¹m¦‹>Ž…‰³iÒdiP0 ç©£+®q µ -šTË ÌSPÆñ}¥*¬c2:ÿ1 ¸ØÚ{î¨ï‹™w¼1úÝå7«›w±÷êwG‘… Ï£Ýï56Èk¯øì@¢‡Üî3¥Äýç>Û¿d ò®¦¾³†ø ãÁT)+<:¥/ò ì÷½ ]iŸ•.ú›lú>7ï’MKoÞµ  JãÚI™ëÆs† èw0RxÜãÀãUiR<õœ(Øe0ˆ,ùÅܱ&Ýï?½v)`ÉýŽÚ.®éãºL61:Ñ­üäõž§uT šD|ÍeÅž ­l?g“H)_6ÇPIÉ ÿŠä¡+a=<Ðmå+#ŸÉå8ï~—Äé4ÀÆü…é ÿ­ 9¬Ï~™³cRÞ4œŒlµ”G\y$‰&b~ã)´­©µ && Ë~¤–úëpÙ8ýù²8ÞÄx Ÿ]Sß!{•ñ‡ªÕXâ¼9æk±$¶-ôDAÖùü¨Æ©ýN‚¬ìÛ8,Öû;'0Ç÷#²?ò³f“‘:®ŠW¯…7é+Æ«4…P‘ݵvñV1òC’z²ï]”§-ébè5üõ1.‹ë²ˆó™oï-¸½¿\›¹JÅ· ^ïÌa3£õ_O ælX¢Ó„Ã*Þf\xX¾Ydû¶\çß×i¥¥óþ0d`ÿ‰ÞÂÂ<{qYRk¿‹6[þ-õ©£+aw±!._™«o5¯µbB>ãœ$Ç !ö¼ïˆc…1y=*mûsmöØ "õv“BrüNvïÓ… 7"W©Õ…! NmÅd}‹ù2ôØçWE@PS>+²jÌdpÂó}ø¸Ïà&fô…dô ”hëÔé, ê;A’-NkÿÛ¹]ZG¶)ÉH \é.㦊½ æ»odsî@‰%b{|[>¨ƒèÜâŽz¥é5©ýê…ãóLÌi$$/~Àvï»s/Jt.^Ÿ1K# /ë—~‰²t|B±W²´¶…~ýE_t±G{žÍ¾h]iQôˆ’Š‘%XF´€§0 +(~rL(K3kÉ={W;r?@!¤CÈ´ ÜðÞ¼øÈ²®AÑ•A7kþqÁûÚèàü?¾GÞˆÞùaõÐÉÊñ„Ne(◪Ʒ$4_Å…üy¤Ë§Ÿ/Âdrø'À?rgݾë†WÓÃ,k}£]>ᢠòåGè&½Cö([dæz&Ï(R-‘^%º÷¸œÖ•&繜ò~äákÈrðɆ±Ô¶ò$'Ðýº'yqùû&|Œu\¥ËJÑ’|z vèA¡ñÞ÷ülo§ccEº/A냳a‰~8•Ö7EŸ”…NDøüù7w1är˜/NåЧø\³ÜæJ€Üc)×1´’Í î3í€MêšJμ/Z$åGlÁ©®)D³ÖB—4ß={²Å³/§y‹ÈeP¤ºZ¬JÝõ¶bl+¾±êcÌ ¸ê{2LewÓ(®¹‰ ùå).béúe0ç¾hÇÂc±Xi :³0Ó^¡íW'•väá;ëÕÙ¯Ù)3Ì|Ãd¶šR&Kó*¾RµhvD7.Ÿœ>…+k!§±,Þ³Þ(€©yátÅÕ- ™ÍŽÙ„·Ë ~â+½b_s*J¡Q’‚ù§y×+öC%„¢ñÎÓýùô¸×]zöÞü€.>EÝïSLg¢q‹êò͵öëI>åwÉMiwYœ¥.¹JÜÖê³[š]RôC_T"§C&0>ÕQ²!%ŠãSs6˜?Gc‡*Êê2ªœM™ã;y%Ñl'ïøÀç˜1së»Í”ÔóIqíb ¿–¿u™ ›p Ã\õ[vKdn;¡ø…džڠsQ–9+é8ÕU4–b1ûÔ]žÎ³Ö31¨ p©p¨ÐƒmøÊ^SÑBŽ9c°ÍDr§Å6Þ©g׌ÞªºÎWëŒæAŸ«_õ’NpßÙ•¨œùˆ)Ð ä̳թ$ÁÍhsÜq)Fmìb† +t«¢9‰|êH‰ å‘Š?îîceÙ¬CNª€?ƒt*#IsTfÎ…›¼ ÖìÎ ý>o—C@‰“@§-ÑB$J„¼Íl}?û"˜u‚O×´ 30o|—>G™{ÂyÂÎލŒ îr\r8Æ^ëlJÈ.]{{Wœ}…{_3âßÈÞs“eY™¶NËg Z*W}q@héNÆfœZvOÁ7©y[ð[F§©-:ã(¸é;¬â)2$C½s3wñfd¦–d`ŒV驪cêã~¦²¥¾_|Ùd'Áiy*ô‚3çXF÷Ú¸à#ró\}ÊÐnú›[ãž)ÊíW8;ºá"v4 üभO·?Å7K`Ú,ö2½¿ÀÏÀª/G€Ïßdê$E,?õâáZÁ;ƒðò¢ˆü›°Ÿ0K\[ÓA8b„„±]ôêÞbwY\…Ù ð]ä|}¹W®§žüš¾ïÅfîWn$ÐêàÏØGÆÊà8öZgR–<3dûWϽc§í²°JwúÇ“Ð0]^îTcoغ\Qç Ù%ÒOç™D.q³ÎL3!èƒóʈrMï¸,|Þ*²AÙ™™^Ö‰5Ï÷nTnZ›bۉ봦mË—ôÝ}B¯µu«í6¯xéZ¨Æè÷â}.ݤǶ6­ûx-ßê½è*/)õ8È¿.abxüóˆ°£¡7Xl‰±gER‰áÑ®Ox£p”~y‘§-@Éc¯têlª¾˜ˆrGÇçô˳ºI“º0t'ºã%•ÑFéS¤‚ƒØw]ly3ü¹â˜À´¦—˜ìÎ%”`³äצoõmb¦ß´š»û5= / ýì}”(-;ßÕV¹Ÿ§l‚ƒ_ïôú»ÁÝó°Ú­±< ®e GEÓ^÷i÷]}‚Ùªonвï³ÌZ4Ezþê·aÄ_œ¿ZÙÚö„#3N^-h{N>—rÅöQ:bôÜr©ÍÝe!àdÁs•±ò«‚IYÕQP‡qzYÇ-ëmMe<ØçøÌâ7ÙÿÅýÿü?´™ÂàP;S˜ úÿ¢Ã{endstream endobj 29 0 obj << /Type /Font /Subtype /Type1 /Encoding 55 0 R /FirstChar 45 /LastChar 121 /Widths 56 0 R /BaseFont /BCPOQU+NimbusMonL-Regu /FontDescriptor 27 0 R >> endobj 27 0 obj << /Ascent 625 /CapHeight 557 /Descent -147 /FontName /BCPOQU+NimbusMonL-Regu /ItalicAngle 0 /StemV 41 /XHeight 426 /FontBBox [-12 -237 650 811] /Flags 4 /CharSet (/hyphen/period/slash/colon/a/c/d/e/f/g/h/i/l/n/o/p/r/s/t/u/w/y) /FontFile 28 0 R >> endobj 56 0 obj [600 600 600 0 0 0 0 0 0 0 0 0 0 600 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 0 0 0 0 0 0 600 0 600 600 600 600 600 600 600 0 0 600 0 600 600 600 0 600 600 600 600 0 600 0 600 ] endobj 24 0 obj << /Length1 771 /Length2 1151 /Length3 532 /Length 1712 /Filter /FlateDecode >> stream xÚíRkTSW‘ª¡¬òRIÕzX%2yj   b,žò˜{CnIH@Ä•TeYÄF—‡_E)šY{ëæ«'yé›:û-_CžC¥”äò3kö±ÿ¼[|uâAVYj.ÏOÚÿÌõµ…Úv§'ý¶£I`,—ÚÝ0ù¿œÃ¦ë”ÎôÅ–ø2Áj™pöBŸë±&`󡿇)> ¥9BúëìÁnº`ÐÃô~¤ ·4x-œßX± ¼]¹~´rÂÿn÷„6ßõÊHQç/gVH•Ò7‰²½©ó•Ùz]×¼ìæî²Nº`†×Ö3Ÿ¾ä~uÚØ´Ùf¾V }g«êØ~Ýõjx¬£†³%N ã>?ßY`÷~nÑj*õ3Ô¸´~L·¿>¼ÌÚtç¥ì˜ Íw½bÝËÄ¥¯mbë‡:lË“s….MЦãž‹U%ŽǪƒñ²èEûí”-«‡¥õ'v;ìàRå”tÏ-l™µpçæŸÝ/Ë’U~½>à<¿ +ö\(¯?pÎ÷ž‹‹U”’{r¨X\s0ힸ7<çyà@ïÙ‡Œ.ywÖTTøÂªê;ã[Q"¾Ò%ºÕ¶‡V×­n®)+Ü#[ë²á½0§ÃW„לüww”tð>k§.#^¾N<µÜí[}j1'¤Çø(¬uM6„iÅB×ö5¹´2óóEeAÝ7v¨R;¯—çÿ‚ÆÈ©íÕûçpbòYí³ðÅ»Y÷?ºšðùw©5üÁ± âÖäk½_ŽFíä¿´$³èÉÅ 9±ª‡7ϲñiväá‚jjÝû?\”ÿøŸ( PÃrœÀ4r<òo®Œ§endstream endobj 25 0 obj << /Type /Font /Subtype /Type1 /Encoding 57 0 R /FirstChar 60 /LastChar 62 /Widths 58 0 R /BaseFont /KCXQIW+CMMI10 /FontDescriptor 23 0 R >> endobj 23 0 obj << /Ascent 694 /CapHeight 683 /Descent -194 /FontName /KCXQIW+CMMI10 /ItalicAngle -14.04 /StemV 72 /XHeight 431 /FontBBox [-32 -250 1048 750] /Flags 4 /CharSet (/less/greater) /FontFile 24 0 R >> endobj 58 0 obj [778 0 778 ] endobj 57 0 obj << /Type /Encoding /Differences [ 0 /.notdef 60/less 61/.notdef 62/greater 63/.notdef] >> endobj 19 0 obj << /Length1 1616 /Length2 21460 /Length3 532 /Length 22359 /Filter /FlateDecode >> stream xÚ¬¸ct¥]´%'W’ŠqbÛ¶m›'fEÛ¶íTl۬ضí¯Þ÷öíÛãvÿê¯Ôœ,CˆOÈÀ-0#‚àƒîÝmñ5Äð°úš'?ü쎲iLÇ@ìУƒ)àê,qK”œ5Ò²Nð°k÷Øn$µN•ú v†ˆS¬ „@P#³”µMæIâ\=ó½}Ó|E-0ÃãÚ"s~÷†~Ç C?döz>mÎ1ðIÌqtDÍžƒ§Xäuüì¸â8ùœæ$܆…ò×<Ö^/]“ÉÀp¦al ëÑQy’¦ÑßAÒ®èn=5 C…+=Z›Àƒ±”Å<ª?E0†3‹$vÅо„$G>=?½ëľ UUÑYΘPª’%›&š0¹nwÊ÷âä’Ã#ÊÀ×¶åÍÝ×âS³^;Ù¿Œ|ÄÕ~?#‘ŸR§O–G且žVs?\8CÛùÓÂXOᇔ «$*tÖFžj,$w^Ô û½'5õ£6Ž«”UENET‘®MÁv1湋¾2ìse¼oxM_A¿0›Ñ¬«“Ì p‘Æg¨„E”5F1 ÝdÈVãmEC…Gˆàj먭aéRø½§ÿÖŒ º%r&¢CzôU<àûÆÚ·Eîêë){YÅ_…/ÆŽ#’XxÞÀCN‹×Ó½UŠþV¨¸þhÉù îË…Œ‹tÞE ~•Ú¯§[¶àbrµŒ4À+^?ø‹ÉÇÍÞWÁUv*¦÷Áq¬‘ú§Ù§ÖŒOÇQÓ°˜5[ï'Är°]¼b­$­Ã(ãÆ2±ôNSÇÏCű žÑÊÑèéå=5bµæe,öŒéŽR†Ô°>±'‡ß)UêÒŸi"b“‰0#Q–|­•—Ù¯K6j®uŒŽÞa;ÈOáÒû,0Ã}Ä´;ϾŠ2¨l9ö 5Í" €<]1dáŽ=JaÇL>-Mµ`α¿¢Ó)uì»èF‘6t } vÂ*<\r‡G ¯û†@ ,¦DÀ·ï*´AUØP¢jº¾36‰æj’'‹¤¿Ôy‚¼-`gTC›¨ç–3ô˜Cü-—†9ñÔž³¶HR{2eû¼Oë…ëîœF•ÃÃo©G3 0gi2ÑV=QEp?Ø7ÕC®F€î19žN“>Þ v¸‚Ï d[’¢&Iæ9„Á±u2"`cÊÀH¢&E©ë½äÅ>R2×ÑLJ,ãö`6ìcûú“…L[«ÄJ»7C §Uƒ§C©FH »ýŠ›²T(cÙs†Ðnõ);hRÞ šüáDþ. iÈ4Là†}¯«ªíf•A=h<Æz´‹¼ª-P‰¡¸ÉªŸøÝ™½@–_>¨‚)ÈíP¬ X-¶Ý#ToÞ\¼DÐb_Ôö?[˜=‡ã$@ˇŽûm7[°†;‡˜ÕÑKÑs.HƒŸ”tg¿ª]%Ú}»kž›KËâg'}çÚî“JG00›*EËÊK{IYÃT¹aíkÊ‚;œ `«¤ÙîÂ_BÍ6:ŠƒŒ,Ú }O‚OשßËÁÖÖ$j†‹hå6¾¬É¡¸K¶îÉt‹òVÓ^ÿÆ;êP[âþà¿Aù½¯ŽÕYÜ?öîWßv(jJ‰L¤àܯùë`sŠç†V‹³±öoµÞAÃ]A5C³òeU~¯‰™ú,ðå°CΚ诘íQ×V<¸Ã?b*¿/Ùz¡s9 OΙÑkkóI_=‹/þ ½ä°hŠ[ž8™8±t{ß–m(—@©õo[z|rOx—ì×ú38Æ);¨õ~Dúõô1è³T<`CK¡˜Í[Ó]3…¤Úô’ä}“e U#ôÓ Y—ʹ‡}5#‰h)E¥MŒºÅJG¬"Rw‘c”¤°éúŠÆ¼÷Ý”u9'd¬LÆ‹,ݼ1ÅŠj†½P²LjÖ‘º ¸ÐÚäcÛÑ Œ–“´ð¡ÖOãqBkqYÎ÷Âêhñ—R¦Èv¸ÃêWÐçç2øœ@k¬fbm~Å€Guí•&§Qá®¶Îød8Ý¿L ÐçßÓbεá•v¼eF“D·]uÃzgìl>RÞ^ŒùÃQص†×ÍÍÃ`7‚AlòÛáÿF›hŽÅæÁU)¬&Aï–ßåý(ÂØÈxؘÇÐçÃ7¤Y9þ¼*¬#µ_?@Þ˲XK‰ &¹_§r0;N0Œ‘ÃÝ™º[R¯gŸ º Œhý@š¥gì1)¨ô€±oV×5 Ù&M£ñÛÃ'²šÃ¹0œÿ(LgçÅrïoÌp釒‹‰çñÈD~ž©ç1h}[ÕHDñ/>nGþšÆ8&ÚKúÉ/Éíz9’¢çoP³ï^z+¾£ÒÑaA¯ÓÛ“¾Ý-BùiñÛù4ý—>Ã@ÍŠx-g ´³X]#½$Ø`«ÌÐï~UV…@Ÿ”ÃDiÛ:&"òp|èÔÒfŸ±¨à» ¤YR½ß‡6–µ2|¨ÏÚNú<—ÓX„b¶½ÖÇ%q@/>›º¨ðA­=««.-j4ë\2¡^ƒ°Mº¼E’_™†NÆû[Ÿ,¯y¹‹ÜRÕ—‘b¼ôc–)Ó†p²µ4ñ©§,ÖèX¿™”œú™ØÖ„)ø`gsÀ€¥B"y[öÁÁë'O}úN»•ÉZUkÀT®z”œ%ë¢ÿm5,IŽÓ´©1R[®¢šÖ¸¡ì`hkMT¾o6[XjY L%й`¾#ØOhä5i¨*ê„n&Žx]"Ó9òæçWþ3\H±yüž»MЈB«_Ñ֖oÄx7 Ýæ”,,—ïìoñzRÜBáyö·#FÎäÓ´¾M v‘€÷ÞÔ„ž™ŒÐ/½níì‹Ð8Žñh«NÊ6(nÙóp²qò%nð^ƒÇý>¡“¹ù:äûcD“$¯<,@+ÊýìT²§÷–heT%}è …™Ãè#3;Ó]S±W,’SÒÎO–~8…s;µX£Íè>NøÔÛª‚%üðuîbÀ‘*űmÙ‚ÈûåhÔ¬µê+šÙ HŒZËj(ä kºF›¶ü̳N.ÌV^ÌåTüÊ쩲t{-ï.! ø¶nšT&íýgyLuJåM¦ˆ/"?oŠ:›´>Ô¿aÜÍÏFå‘[çtsæû"v Øºïî]è¢éÊÒôîTDWß®˜”(£u/¢H‡¬ÓÇžÿöŠüGŸ“©èóôb—Ö.ê|ôŽs6ÚÅ€´ÔÑ‚Ÿ¨êŒ×sOì oFèrìùØÁL o α¿Ó=mõ>;¬Ä&)kûæÞhêqdæíƒI¸–aDM‡`{NH«äAÉ ÷¼ #ÑÔâ®›) ôÕ‚™ßœåh¢ 酪ˠŒ™]eðgK3(Ž"ç{?iet SÅ‚“³’ÜyªÄäŸR”ÜëPtç\åÕ”èãè`ìÕIàyͲobdWƒ ‚÷”Vbà;ÌÊ6ñ†Ö6S.ßÚm6ƒ `°G¸  „ïdXî}=↞c+·ÔeÄJ~Ë%¹îkyQX%V§P]˜‘ Áú.+lM>!vùŒDxH·Šp,@UD>P:k“Nkk2äÆ%öå"‚ œHÓW†}cÎ*ÉG<·d\ 厃J|K6@iÌJ ðs$+BðS½¨%çfaýú1>졜å,Ð\Cà“|6zÞÝ<𸄅¸[ì³Òç»­!Æç„q#¨g2Ž®9RVÏ‚@6è9ã`×ÏñÇþm© ËiQ íb¾×m¥=ÃàQ^ !{ñ¸ÿ°S–,à².ÅLëã,“‹0R˧ý훨BP„\1–*OWÁ(ÿl‰ÆURÈèîdã2‘hk•s-=U`¯à3zÁTiÒ|gIýõê–kÕ-{ã8ÙI•ljä] ÕçR7~¦µX¢nyü¢d‘,áMárà”?lÜè¤ö×Å`q÷:j÷ôÞ¹á O©¦8i!E3’Ò€’Tž ­'ñ¼õ#†ð’!PÁhû*Qæ`Ï y ¿›]Ôú–Åg€Nh8˜Œ×® 9E dìP”åY0Û†Bk:¨D=[1—Žð»ßJJb›S5Ž¿ªs0¹è69Ø´¡x¥’{##ãÔäwî‚Úß(œëE!EÙ Rþ¯!æÉˆ’?Hй¬ãEƒ•*!0öƒ=¯^l[ü¯ÿã¯Q‰É«`®!Ý2r=ÖVs‘Òá"±î¶ð¥Â´KMÓQæ÷zÊ$—…r{Lëˆá…9Ny讼ç¨À¨î!›-˜Ÿ=èަwÃ#Hý~ýŽd ®½€”uÌvªÕ²U©iûž[w*δƒkýŒþÏ{‡BC‚ʾ&F8M?Îýw™(9Z¤ᢤTz(›wãüJã¡0Ŷ –Å™²jG\Yª<ý-¯äÍë& òMɪ 2_JC” igej¼*/(¹JÅúËâE¦²êm¶÷a —MP æ[R¾ïÀn™B 3—`w±ôp̦…iUºï¨P—ÞuÙFÁ AŒë`L&ÀÓÏñDqA“j¥K…0K•=5^©nƒì Û¹Àþâ´€é¸úb Ù²à§^ÃDõgCÕ‡ß:Ǻ‰oáÇç:oWéB®a]¶Ç`äkÇ´Sâò·38ò™[íCÇâ^÷á÷{\‡ Ÿ³;§° ÉRJÔ”Wp&Üþ@N aÎñ«©v¦’ÊXºåÁbÚø²ß|¡@~èÜOM.Mó;Î/6Ž'¹àÊ9ÖRe„Á:Bšáyüê¤ )ê›Ô–Y|$1©ê£’ÃY½fÕ»2¬†N4KèÞZÞˆ²Â’ƒîe2â{ÐÁÁ0ŸöÓJl­pʵ?ïþãØN)œ)yòîI󄇔1«AžIºÆ 4>b ö2ýQæDïøÛŒ÷XYmáïNò]N@R”ë76¼;‚9 eý¨{•,*²³\Ûõ¤HœHô»#LËÖ9>Gù²þõ½¾ÖÍÅɬïFT7/0÷_Ià?Wíï@§¸/‹L¯9÷‚´”PHþ±ÐBh’^?~ÿ¨¯7*çv?Vßï«4ÖýªÔÿF”Gœµ=gÆz…µ)Åg¤³›ÙþJ†Ë´>X°¯ê(’¡»°V‚Õ}Òusû´-iÀ.30:›²ÿþLØ ¢,µÐ¬>dx£ÊxÄz§ÔlæµÕLª(ä'# ÃcñݘõÖ|ê~IZl›_Zñ{}Âvœ’,òÖWzÒ)ݶ'«dú*<è±6Tg¼¯0>ôɆš²†50¾îo4)ô=hÊ¢žÂéÈôpG?lÃÕ y<=P)ö8zÈ×õÉ…=‚09‚‹ÂGøþ~5kC×±TÅ pA¯’È\H0F<ʨ``WëŠ\t¾ºF³†Qyµž×ô}Õ¯mtˆ*¨æ•Û °ØšqC¾^žý Ž4Úàƒ ¿Å¥ß.¿ŽsÑD^³¢ôðQÁLßëMž§@¸À%ƒÈ´;ÌÓòyÖ´)X놢v—lßVá[ #§èÅ¥£h(Ú@Ëo£øxÒ|,µùÄ®ãÄ Ž(2IÉÏEÍÊÓÞÉACÝŸ©ŽóGAÝK·V<§#}ë÷/Fñ’9ˆ‹gÀ\íh­fmБbÑqqÛ8$ÄË÷"'Ÿ Å~I¾E‚.ºënö6ïI ]ƒâ„ Ù_!N•,«vdõˆüAx*éÙ™¢ëñ¿¡Q2c'#]<’]žç/9F 'EFGšCȤä!\)»¾)î`ÜŠ%ÞhdFp 0ßOúóm8´{_äJ@ùZÍŽÎ#À½‹ôì6]Àoé`²¶åYÑ„F¶/)W÷ûz%d—mvƒ;i¡-9w @ØL‘í3föü2ÅAŠ9ÀÇ~ 1îÊÅFŸ›\ßd…t3b„X™ŠÁ嬉•g‘ñ¸‡®õ0& úÊ Êíàcµp)”6¶¯¬ãÞ$a7´Ìœu_i±ŸE¨®Ÿ´`bW¶¿ŒCË—‡î‘eí[É üö©Ý„H ¹QnÄ÷7hÎZü^.kº™ˆ‰m}Ó»âÐy+å¬êKÕ¡¹CÅѳ/f+;_oÏŒ{žÊlP±úÝä’± ×)bÑ÷sfÔšv §~W„_j d©¥Eo”§é;¥[ɇ[öØr¸Ð­šŽÄm†W¨­ðBÃ/ž­HÇšõÜÀ “Ø­Ç9W/hE¶þx¢àà %øºgRâçOçgW¸¤9òñ—jã]©‰›qS`481ºÏVײÊþƒÈCÆzÃëöõZ@ÔÇ”W`FX4ÇÄC¤©s¤´”• Yƒ2ñï»=ÜŒ–ÞehºN\,ÅÖ$O;§-]OM=Z½ñR-VÈ»Qƒ†VëªJ O+tLª\Ž[ìþ—£7Íúj’ í§î°””vˆÓ«ºÔ²YP×0æ¢{%Ô" Èø9£Í¨'ÀRÍ¢ÆCŒ gPC— ó^ß+^õ‘sà*úß#)Â8æÔ¡ï+U3“†u|7¯ÿ™ÁV6P8$¤éä4„rìIÎÛ.pà !zOwéPZŒ$› ]°«êWØZ-î„Ä’_õꌹE­‚´by÷œéå•zÎ|B1‰ÉkïÅÈwÌøè]Dš1ÄaÄßÇ•ÍK2¼nzý’nQåQˆû OmÊqÜü »!ä3äuš€WýÒ) ÛR±„¤¢©§±“` 7uúaa+”,膢—ñ1ÚWÉJQ™u÷H•fý£±T= ‰*?ªÇõ’ž¨þåžk%çªF«Eºhgõ“ªŽêèø¡eHÌD¾âL¯WMáH¡7ܯñPùÒíï–¹«Äºþ¡C-¬ÑâßXôpA‡ÖŶòÁ_‡!_3 $ÅBwÝÖ¢íÏÊÚÏŒóyh¥‡¢#ø©€Õa–åLÛud÷\èøZm5€Æ‘#îµòäSÖ¤Ûh{Pä•›‹t [Åj4ÞÒsCvÀl˜¥VÀ;7ð8l„±ÛòWK[Í\8g’êŸÝá;ªK¹ˆvGºÈ”¹ìÚsÆ »ã¨á1hBÈýžÝ:±Zl[µ÷0DçL5™_RÈÆNÿAáå'¾Ô1¯¦ª5õFqu¯ö‘D—Èìc½¡úóì‰TSÑð.Ó‰D·ã’!\R“pŒs1{\Öõ·_ÛO=ÿ> ÷x]9ÐËÁ–³‘>”}Éóm9º³ícª„ÞhÄŽˆlgP6ûö‘‘ãÛílò?ç,¹Ðu+u&ñ•ø?ïK^?¦ ›…'øVQw¢+œ ñ…ÍšËdoÑIUùèL{(С†ÛË‹=Ϥ,pÕÈ™ó—HflB:+"eµÊSâE‰wGay›9*clÊûgê}¿:+¬dêj5’°h.Òéü¥0çÂ8>|»»Ýr)&È÷ÝÝn(ßY©wSÊP¸Ë“-‰ äIÔŠ±¼˜´%B«b6+~€2Û4P‡D™·ÙÙôÝ_H¡'øèJ~²É:†©N½É–W»MÒJº]±gG [ˈ»„­FIN&ïÌ’›IÝÒK^¼1ßy­Ëvh;—œ¬XYNxÉ-ˆ—åhæ F`6M`¸J&acxOmmÒ¡–3»Y;WpJ¿k®Œ¦[xoýQ2 Ý\eoàZWf×À†¬ó”*ý˜´ïמQÖ2{œ.9þ\c‘ÙÝw¯,"H”N–kæýÄ`­iYê`»Œ³œ>BËõ xuÒ@~§@¬ Ä|&Pæb:_ Ð^”„{ qLØ«­s#«° h¡¢îd¾Lv_Žtà= dÇÉáS‹ñÞ+²"YT; ¥ÍÆQ÷9ã/ZÖi„/¼¯&§JÝÙ—!¢&?xûôÆìIã°¨Æzk£‰‹¿MY©àÀ‹i1œÓäj’ùIp=S6ÿQ¦g)QèôF}–¿½BqŒwêNaV÷±Åp!}¸@§ßx r6Z`å*õ¼`£ì4^ZñüŽÕJb¥r\A(?D56Óó¬V#ßýÊàÒ'°¬ð§lÄ“9ŸØßDªÿ½ùùA/hY潌ÙïÑÈCçœÐoˆ0í§ÈÐÄ%ø…øüóŒ·õ,F$–EÕÂ;pï°I üK&þbæãŠÀÖÏNÒùiM±›ÉøíËŒ'ìN®©É’öæm'³…}’55ÎG¤¡=3/GxæèoŸñɽék.0óà¶R™nîP„SP«éâ¤Å4-6Ä £â=’ëShý’åbûµÞ,£Ö ö"Ê v 'ü˜²6ÜEÿVtã}£ -RmØiþ3ÜéÙynXbÀ´¥óº&ô‡Ä×ÉþIëxÐÍL¡£Uƒ1‹ÕÒ]@'¹€õÔ ÄÁ¥ùñ{ŽoˆÓ,?sÈÅa\¦ÌþÆø ¸~¾‘fÇxŠ%M ‰‰|üžhjç3v1Zæ„,²1¦#´ïêaÊó¶0ÖÖ{B’±˜ù¥Ê£¹bÐ%GL3aKí%V”O–áó†û¼xp1H9iÁ=½ïŒ‚5˜#GÙeö(åÚvb¶@ÉZLÕLA¼IðËìËÛàc}…2}ªäO9h7Ž+ˆ²§Í“œÅUêßÊÏöèï!ÍÖmE¡‚¬:J½1-ŠèçúÅ‘b(ÔƒvŽÊD 0¹ô3@à÷à ?†€9Ó"j·Ïóàj¼ÂßNÔýëÙØݬØÂFÀ …ί‚þ¨ TâÊö'^¥ Ki:Aôá«}ŒØmeü$aìµ€Þ륈°"‰-Õ†‘“nØn¤½°Îûh`Ž3;s¢/üí1á ³¥„eáÔ‹¡ˆD­ë¨ç¬Ö´'âñ“^³ˆz¿–^ÓHº³#L\ÑåÁßÙ7wxCþÎŽF‡ºËd&#ùRr— Ñ‚ŽàR³E±qžÎ©î>ôWÁïÂ9 8ØÚ“©–ΓI7Š_B…³þUºÄØâuÙŠå¿£w\w3a~°›ý*g:édõDtÈeEÖ ¤¯IdÞqµßcD³qVØ­%†ºIì˜Q‚ÞDúB7®ËM…%ü1º¦ñg=v+')=Η°éI³3µ”¡–©¶‰aY'bŠÿ.½©’s/tHær••)b}“ë| UÊX,þþ{9yCyÁ)í›j¥`ÀíT°Ää@,ô÷¬tžÄ¨¶š¹Ÿìe8bá?÷$0+bS†bv^k­Ã×,kUV’:2Woäü£˜8üßb38Ï Žnv° Z²*?GóIÉ8öevÊ ÀÂÿÈçãÒxD 9 8¿$¦9r¡ Ú“S/•ÜÏï¾Ñ˜Ç_–x{µ­^zHDIãêÕ¤ô”šbÜlÑæÒ¨AT¾dëàØŸý¨ÚÏEºŸÌw¾ºÅ¦ÞPйâ³<š´-N 5þêØ÷™Ím“uBzÊDQ•¤cž&O ˆMãd•j3WYXcƒ£[\8{ó+Ôí3ä…Æ^Æòü¾SS> »–%Q÷¿|˜\,ªð?YǽˆEq¤«¼ñÎÝÏh{€á²×b\Ä>Yõ $£äÝŽPȪü™Ž ñì>Κ–Ìÿ¶AŸòJmaìÕóö(Ô&‹ª4ÿ&·Ï$ËuY£ªGö‹•ƒsrdªÖNÒí&Dž3 )Ü™§æømº²…R§E?´//ŸnúJlqÃà ç€Q*‹LY²é¹¬ÖZ% ¦r- vÈ?ÃCøÝšk7çÁ^UáGv‹µ¯ßFg@¼µ©òå§Æ¯c•Àciá´?C´A#z*Òšû%R´pôªdtëû/î?]íß!ôíêSLÒŸ_†åØÊøBे‰’¬÷”qTŒsÓ¿[(dD!8²ûë6>Õû¿-†÷Ë †DSƒtïšMÊá&7¶ÖŠv™zÊ»©4”Iì€í 3î…’ÞµÈ ÅS ë)Œ€vÜÔâ üúùåàž{‘¬¦ðÝfàNËVªlêÐU‹ßß‹lJ@“¤x¥ñ ¢°%`áu„\¡Úªßužèeù–s‰_” ÑôÌcÈM"ÅîÀýž32ãD{“…Hül°€Ö=¶Ë‚ä\ì•НÓâíä¢;¥ª»Û+oGN×êiÈ&™Ã‹…—œt>/VW`MÅÌc‘þÕØ$ai?º+³+0,8¢OvIõëóþ×84i¨ŒuÈ÷\A‡䇻jrvF÷…÷‡ÇiÄô‡fAØB‹‘¹¸Æ ¶•,Ö˜F2N!O¯¨;o8rAÂ÷Ñ¢6ƒú¬'vè' ¶/ð;mŒe+D¢¢*ÕÏ  œ'j …ñÓ±èy=›åiÕV®»Þ¢Ì1ü¥,g%q5«ŠÙô"ï£Ãq·>³ 9 ‡NÝ™ŽQ¼Û• Ï|¦;T¤G²4½=\Ý „±ãÖù­—¯Ê&Û “Çœê­Ê?¬kdk{aS³±J1/·Øµãe5g³öKи>%äö‚TòÙ¶©T¼Ê×–<ꊘU¿×L4ôúïÓv‚ìuyZòÈš #°/ÒVžB×ůëÜiÜ¿žWÖèè›"J ï¾ÛQ ©tåjÔªñħf;tæD‡>³Jd¥ öØ0ý—ßœ&ªQðI’ù[õhÞW·qÜÒLÌ÷ì8Àøœ#R5–ÂY¬À›ÓRª°Px‚$Ly&çwÖ+™ü(-ë ¶ö1BÔŠ,²{ÄsRéNéÀ–&„r¤¸.¯±¢Ê U£}¨žî”3 §K#}¸æ3s|ÂER´=5ü¼(v®ßºŒù¶b}¸çširwþ†0~Æ›ŠyšBË[C–³rD´Üo ^å[¤‰‘¾[áøÝëêw5¤RíÞ+0èì÷¤÷°0ÂÛÔSûÔï ¯Î8;Ó4Y…_ß¹‡ç‹äñpˆ¢>|¦v„.ZR¬]n½ Ü :°jZÊÎRl4ØVÉ+,ó¬ Éí”ø0mG57ýOÄ~¥†¸÷ìî\Aï EÁ\f¹üXtn’±l´Ìäð˜åE3$ùiÙŒ¨k÷øGŽ;ù²~ßâj $3°Ý!˜Å]ß=bãÍ ÛE¨îJÒxøÿàpà *α`›5[f’¥³Ýø  ‰8u–çõe3{YæÁåÎëéX;ž¢ C®I¯§„Gì/Ûj6b$\mÿ>¦ïJ‡xñÓmZï§Â}U¦ i‚ù,eÊp[HÒ¡Ù¹1kž L­®ðCëpæÂ±t¢Áø™A„ˆð.7­-€Äsë‹`ÇP8ä©_œL ,·0fÖ­é¹É_N@»xÐ5ß6yÐÓ³7 F¿*Œâ…Üê½Q~QÎäµÂ*k`­§+¾ð ΖØe¢{—p…)Ü—h¡æb©9õ*‹ÊQq(HÓæ=L`ª‹–®½BTßPG‰œ†/|[s5÷ƒq1Zµ:è¾:8²„oã@ŽØ¸w!ðkvT$œÏ¶]P(†qD޲¶G[ï½­‚]4Q*ï¿ïdRZ½Ú3Ç›¤V; $óùŽ»va:Ù¹£Ü3{º>$ôhc úùqBûdV„¶Áÿ©Ï´çÔeKÚˆ(îZM ~ pîBé—']°7ÀmñúÇ&Giˆ¤h*’T˜w±e Jä–ñh Z+æ[ÐjŠ`MÁÛ¤­xT’ú­ì±M_šå#—yoC€ÜÄ*å¼Ä…ÂuÂ'Q«tŒá|¤Md­aXgz’Ý¿8­åþ(¢\E)ãTÑ{‹pQ¾Â-€ºzS½ ºHœéêú•²F5ôËÇh”N’{ßUÞlË•S_˜w9Ñ Üe3 ¾r?½.Cðùì3W3F‡Máyú[¾J¢÷çÞ]&«D#Ñ0Ô÷ðÏd‚R³{/æ{F›‚ÛÍÞ{OTdU‹Ù2 ´F’Äü9S:ôk }?oÇ—„Kâ·ž›¤jo;YÀ÷•%êª/ÛŒë €Õ”˜úˆó7<ï¯y ÷¦v )õâ‹¶“0Ò0n.‰Í ª>Eè¯4/IüYϳ¾3Á#Þø¯¨BÝ™Gûh&—„ŒXiøû¡2ëºü+Ëz,ÂâÄD;!Ê„hmR¦÷Pûê^ÏòæîÍíñ:Ò™,ÎâUŽ÷çìüŽw•v,CJØÝÀ$ôòk‘ Œað£ç,iÛ0ÊD™ÚÁœ £Ó^ÿÚ¯A·ÊâÁ——µ#½´/ž—Þ³õaTøÊv³Âðæ† ÈéIõƒ¶1!™è}>vÕ™ +w¹Õ!K7fcÖªÛ-9Ú[ÖqÔNèƒsG/ˆ'ääJ35¸ÀC9§Õ/Êvòœ@ã×—Fð°ª}+0G-¥¤ÀoÌ[0Û˜Œê8±_Ä4`߉NŒ&]lL–•jã¹™&âÉN0 FnQt›¿cŠäÒ®V°ÜæMú¢ïÈø¤MW òÿøÉïSsÎ÷ÔÌ1ۆ肥®éÑ_ÉŽê–2A¶DÙƒbäÃxñ©}Á®‡'Tñ&S]å€ê} „PDxÓ[›><îç<àãæ¾lÈ)íâȈ!h蹛ߙ˜2%Ü-¢¸ª9Kà†ªS±Zšô=ÑU æ[TݾŠAîŸÄ7}<6$}vUõ‘n‚)È#Êð-×0aF†Ú –N© ‡Ôƒ†òÐ"õ†Çqå ܇6î‘Ãø‡ýÒÈ ´*B/´0ZMN÷±‹ŒWPFeúG&êYÛ„?“Ðk…nW¤[¯îåáŠ3AÒRsJ=G_•ä.Ånäét×~aye0Øj²³lŽIxôkW—cE¹g=R+‹‚TÙw¼k}@uÆpÏ{{`ù˜pŽ’¢‚=6Bš“¹ï“HŒæô‰¼,QêÚ#lé[ç-{à(#„rŸƒí9æ}xn¨{s}ô`>y0Îû_™«Qf§ö–x¯GÖÖÂÃÕ«vߣ²éI;+˜½‡D²±>‚Äû¹Ç*ß– ”Zà§ÜK Xå™Tzn÷”ð7çW³¢þyzm&7Šë°H›Cž@¥ï=]Ž00þ‘É”Èdë´œûtEƇ%yd}pÓPW-&}þ¬³Áèß<‡eGnYf:çþ' ÖµsðÑ|(Ð)Ú"†Y5¨½Š%ÂÔöþƒç5[ø÷‡‡阞•åÉwóuž£P!ºƒÉM·q'(À·°s»‰•;üÒÖ÷ؘN*ìBX_>ë aw&Dl'Üù7i«<‚š€\€ði¦ñ ™ºÿò3@.™\Ç{YKP)á2ðŠ©G]žžÅíUŸïÁôc¢„s—4‘±GGl»þ 2­—xÌH<ˆ½X’Ú0ôGs´[w dÇÒîËÆ/§ÍuD[^ýͶ—êå5ZîFýŽÜ‡ø<|È›¤ÕX0Ï!F¥Ô§Ì¶ü7gfHdhþ§RTdâ¥:í"Jn^;OGw×z%V§‘VÑ@žÿR Š­µ;&Ͱ5rÚ©\xTi™>³61µ°”ÙzFb¾l÷nŽa*~´Ng Žß"è@œ)¬ó]&²ÑÞö½”3³øQàø0,6ɪ´X®(oµE)•ñ7ÈzàüoPï}‘L^â,¢›sÎ4wäoñÑ3;¥ä]´ü<Ç^?¹ÜýML*ƒ×ú]ùXÚ­`û7®þx-Fœˆì¦{ÄÁX~»9¹4ÿ=Z¡G>êžÍû«ƒ` 5Æú[Äç—54>þüU—ójmÆ÷lÍáçowÝuï£3‘¦sŸ ,RÛ&*ôx$ßs†k"}ß«¨_=Iù3%ôPß²m¬Ã§i€Á…øÞ¨ªjj$´G³=%¡UA‡TÚujÁÏx¢M:ráÙ°/i˜6•T$bâªd‘„ ÈSí=¡lò«JÓ."`ó~‡v:ŽYò–™ÖV*[.æ#Bä EÜï€ëÅl™ S«—Æ ñ…Ì´·¨×Oï9 ðèN}Õ-öWêÞIÞÃ3†Ÿt‘ªVÄé)ëjŸ".;Ó8Cl«â…h~ÄU­•ÃÅåÌE€JJ˜µçØb …\Hƒ:àØ%pÞzQŠÐMÂÇf7üýiköBçü¬¡¹ãóñþx ‰¯KÔÎ×ÏÝÓôTÔXËï”Û÷#®hÞ•–aåTìQ˜ÃOsðïð5·- C¾çÊhy.$ºÝ>9ÔÐҰœ[Ë<‡n ÂPííðÈׂ™§A;‚£„‰rºµÇùšïóêåŽÚW¨ž«Yõ¢¾ÛRñÚ¿Y~¨×Îê¹TX£ª°b­‹Ž!O%xi<3è ìb[•? à-•¢%[ 7‚£6×á«ý¦F°À­á4q9h]ݗ˾=Ÿ~ößê7,õO0'r-Ö~œ¢=‚IýZ­úÈW‰PõFä¸0’mkEHägÌáâVM{;PE´aÊn´(èpGŠÏ%‘TÀB–uõí¸çû?>Y¹ &o ´oSwjqÇ•Yr2`ñ 8-Óúo6Ûú לçn„üÊ.‹åìF›§–ç»!0¸P¯ÇàÕQÐsÖ’VEÎNäf%‡¤~—‚I`OM‘p@sÂÑ¢Œˆ`±ZÚ¦Ëó¹Ðl*Ê–Ú¢œ+!ƒ¥%p®,iiê#H%4©5(Â8Ì)‡oˆ6…ùÏcQŒØ+ÒE¥E+ÿß?ÌÅI‹(W.î»q`‚Moš¨içS(³äxƒ*"µ©PyßRyÑÿ^­uy|]áƒü±'£Žàyd)i©AB¯xÄ„ê_ÜQÐDZþ>_•l¢ªYYi糘´0x6TänV[ÐÑ÷Ásßx@æÀÿ:2A3£c|û›Õæl´…&!&SEÌþ|D¦MU< _oæéÂò²ÍG) ¦ž•šû~™]!Q[»«æ%£Ë­ ŸÔˆÊù̱%³ ï87MŒÒ…ûÓódgpVk“@€ÎF¦Lwzéq‚в¬nø{ •Š5ætù8ï—ë&Ñ[üÙnÅÁ‘¹âòfJÑSR½:P˶ÅHݱê¾n˜ºªÀ'W»œ³uPÕ¢ib‚×h!™TŒòiÍAJ)À™Zcfͳ™áÍùÿ”l *“ŸOkï6é˜3'zëã„«:¨Yï †‘BjS+´K`HÓ1»wã¾9g’ÂõÄü „1¥™Ü5ç[Vö½…#R|É*lý©v|÷žô§9í Ñ—µ¢Á/Â+pÁiœ*Å‘< ÂŸtiÉÀžkÛ2&÷ h Ã[Ÿ±:íK‹šÈ4I€B,Aÿæ!ÉJ?ÉPb©ÑâÈì¡[–º™‡˜·çÖ >‰chý¦kZ9!6'Û`ËœÚõ{mÒI9—PB?íBPØöÁÛëòèçD– xºFÝ.^ì¼U5gpH¯úTŠŽm¤{hŸJ0çxHÔ$mz±Žü\/MQ¸Óì1rÜB˜iªÔlPƒ\H¡x!ðV†—·LˆJM=a¬®Š›"û iv.шCð¡Á$ÇyËÖË}ÃUó,©D׿F@œû Yöx°€íU3‡% Ê!X§¥á.¶b>LËt·÷µ’OŠ{/jõpãhãÃÇ_¦tÏp«ÀMwóŠY©ŒïçEL–JÚµ¢HÛíîùëüŽ?gº;>HÁ§B$'7Æ#&–Ä*ëÍ®1:²Ý&ûâz¥©’ÃU#µ»l“ Û_žK@r O3št®ºécz·ÒZ•îÅSX™~.i´bKSÐàK,JÐÎÉMØ1Rà"C®Eõ>8‡Ê2¤ #“ô,¸ ˜G¦è˃ w`Ä<Ëý >v‘ÜŒ9­)¥$`è¹.m¯&wàÐCÄ]1‚ ŸG:˜ÚbÄWØôº0Y <àzÓßÐŽL oH)Ð-¿ÁstC [ç`b-û Ó[Ò•Ý2RµU¿Ÿ­Z0êÐ=å×hÃtgmï÷RYkß);?YK*77žõ]ýy?ÎÔ>W4”LÑ õbs ÐOئˆ;è>¯ßÊiw”¾5ÇÂxQ+ñðF'¡ ¯[`Ö­ãÇ 2´}ª<á2Âó-a¤všœÙª/ŒmW:õòÔ}shÀ‡Ž¾R>€v-ž‘5y7d¨ñm9Âî9ô}µÊë'¼ÿ˜ÞO:ú‘¿sU^ßÿþ‘({ëuG»iÈ× ø{FÅ}ËW¥|ˆò† ^u7PhñäjZÆÎ»¤Q ö®ál©$wûyÀþÿµ_VkQ0€¤YBŽ¥»‰¥»›¥»»aYJ:¤»ki)éîfA:¤»¤„ó¿Ã¹;ß™˜ë•Ô΃´¹ìø¥Éךn­hsþþï|„1%íÎÁ a¯7÷ÿˆ¨!Šu¶BŸ¨H[nÔ/óÕ®bÌFäF›©Ö6g³Ð=h¿è!Zñ+ÛaÆ4õ¬“`8³ èFiŒø‰Çs–!ÉMs寿Ÿc t͵HO‹ ÛRÛ÷Ùæ©®™ ìÅ!0uÝUØa› 8VB™IB‘I”yÅIJmái×;è<½ Åé•r$ žv´h7DŸp×ß©óÙ>^îp²™ßº/ü‘šô3V3æ‹2¯h ÙIôaø¤“miìÙoàs–Èx¶£®!¬@:V‹S{("&€ø¢ëJƒƒ°k·t›C*ìÞŸñ‘!¾þ •pdðüÙ"…¼Í ÷ëßÓÙkt«tÐ5ï÷W÷ê ÑñXͼyhM°Î÷OAW£Öì²ÁÈŽ_¦°Æc´‚I¨¨[ž!|=k‹Ö p–sªtEDðjÖ¦=}Ø(Q šX¬Žl£”æ—Üøy©Ò¬Ï$–fß7*ÇÌé—ã¼ôšÈƒ5´¯:Z«eßüŽ~½ßõ§kWõª*nòÀƒZkƒX/Qèϲ(”LÔ©1šÜ’”fƒYñÝ=•Þ&û^üÅSio¦küKžBÏ[û8»ÛÛ‘*>‹.Z[fÚͱ] Ð ²YÅrL›ÝX)9FDáF¡¸…ÔFÌè2Î]ùÍêÖXrd,o·MÕàˆ©†3¹}‡ÑFH ñš…ùöÃ#Ë’,,¡êHQ%£ßö±ûÕh'§ß6ãC T–Ntý,5Žãf[™%8We3»H…Ò–-Èf]¿\ÓÚâ§ŸÚYÃP¶ümBäÄ”Mn(qt#s£6Á·H à w.Ô˜)+¡ÚbÌ 1Ã+£g%)&ît7¾c^5âI8Áç9Ùu{§ã ¨¥ÈòM ßèÿ 1ñ9”þ‹ãîŒn0TƒˆPÛa‡ðÆDYlBy[beZ±¡‰÷ˆ0MÆ®‡fŒé év… †( b|¨îÓ”ú¶Àá®BŽ~j[‘¿yŒ¸0O½24ó–0€œö›EÙa$)ŠfZ,C¼¬Rõd=ø¥=|‹}yq뙿N$—ÛcmÆ>ô‘F1OjŸ ªB1_ÜcDÍ:/ÏÄ&ŸÌéÕ‹ú&Cî7·>ÍÎC ¯ó`ÖJ7L-©Žr{·M“â«ôR¦w!”µ Ío†î¨&Ò`X±jfJðÐ ³ö`¤kT.ç8’êõì8o†#b0‰­1/êÙ$9s̲K/ßÂû~‘éŸly†%ý,ºí-£g û¤‰>¤{ÿD§f7ÃóýVîÓ™nÿ¨«e"ÛÇÒj¼BO9wã4d*„i¶*‡êÝ 7Ê”Ìb¢ãø†U•`¶®ln‹ÆO˜;> 6#ƒ"jEãe£|„:Û§1§§¢s…Øýúáà{éºý#%ƒ—á[Šá—fù—,´#*¼?!·¾ä=Y\ZÁ dbÐp 6O|œÑC;io¼ÖŸw$˃.q ëA£u)6©ßàšuQ§U„HµÎÄ_´.ÇÃS‡"MËDí©~çŸþŒ­SÙ+YÍ7 þ8㻬&&þ›ªÆöÍÕ~]‘¬±ÕxHÁ6 ~cöN‹Â(µŸƒ/ç×ÉYæHzáRÙ‡§¼ù—ÍÑÉ2½“‚oZ²–Cëû•Í+sø¤‹úµ‚<¸£Zı!¯ÝùËX”(ƒ¦a³ÜŸ9‰áD÷ð…'X—é¢ç拾ÔujÔ;?#ÏR^§WJúÛÉÀº´Éè±èÓFãˆhâ¶ôeò~ï!Gבõ´/;ž[¼4†ø¤p(!®´sÏbÜK¼°¿Cz½Ñåú^j&ö(ºË…\^LbßOF!PwéÕ½Ò Æ¼¯Ê ;ob/QJ§»(—®à~Ì_šn8‡÷~k}0㸚Ay‰è¼þèߣa¹!Õšp‘ktEœ:®Ùг|§Á„XJРg„ýpƒð™»t€Æï2ãâOä•/¨G s~¦OâÚ΂¹NÆÛéœ"íáƒäÇ5ù?·ÕG4Øòl¿¹±9·(•ôð*n•ý­*ßÝÔ¦«2ÔØsªd&ïÈí©„;ïlù”‘õ`û·Ä% ¸JñK(m)}GñƒŽædê1î³ò» S¯TÁ¶Jy¥G¾ŠéÚLñÛO‚ŸÑ’'ÈÚXÎá^lXaƒQ-FûO¼ÁnuÃFJ~î}Ìð{A=_à3ô‹²°Ú”šal PÐë}ºbÆmØ3åØYÛ‰…Ré”bÍ7DÆBA?×@Ͳ´¶Ó¬—ïÄGs]m#xaÿÀªÏ‹éRººó2p¨\t.™ÛßD›l0"ºù¨Ì!Ù$ކ£y°X+™ºSøP|Ù¡ Ùöš–z®¹ó¸m§†ƒÄÚ6gÙ´wÖBiÕóZÐA½7Ÿ¬^)SâØ{è²Îy÷ Oþ‹"eF V[ÿ.IJ"^&†6QÉ—„e¸qÍF'3(ÛM¼Røàýì:³+*jE(@3ÿþq%ý‹g´@òmÐÞt’WK2èU:² Öw|ˆŸp<  »Ã-œ4…†Wã9»]­çptĵ¼£Šu ¶wü› tÍ«“ûyt‰¸}ïè0޳^w`K½wNìM©A–hE„|þ¦ÐÏ'šg¨Wu+ÇK€lõ嵜 ÊF ‰E½€LMžØë†Ê0Þ«[ûƒÃ6Œbȳ§óÃÚ®JÒÔay‡¹gE"1ŠÊ;?C¸öŽ|ø Gù+;:Ã,&<ß¿Ä[PÏÒè#Ì€“³r»á—E·qpÎC0Zê  „²qü_¬>³§Ùë[2ä–~ûZqDØæï.ϵÌV\`> <´d€ë›¸e^Z${Ä:¬-7¹—eŒ²ˆú}k"šÒÐy«ApQF"m›xI…ó~k·nEÌ?v´‹-HZÙáå5ª¶rvÎjÔ{téo?柃åªõ _9ª90®(¥‹³0\»š'ý—55¦ S˜s¸%†Mf÷Ù=^õyÑ©¤·+w”ÂqEªâûîV9ã1fØ_(šŠ–‡ñˆÉ¢y¡T‡YU¥øœR÷òªyâª3;ô²Òž.Wb×3ú]ò–U[S=ÖLQï;¯º%ƒ?ž¬æ¸s¨¯Ð¸á ý ÁVÎò˜ MS~ÿ›¡c½³Å%¶Tšk &!=Þǃ1äü0~šìÃEBÜF|ÑRïwÕEú„îŸ/ú¦<\ .уÁXó`ç’©?â~Î<Ž6Fµ k]^™”Ñ7È 9›¨¥I¶º÷%S¡ÿ5äè¿lÈ‘å >@÷wQÕYš:»màSo¨ŽBƒ g!³Þ€ƒûÑiô½ããƒl¤Ý‘Ùê¼Ùam;¸ê5:Ïbrt„Ûš†¯Œ7çö匧|àŠ’zdÎȾˆýÊÅ,½`7Q³¾ëu•„ïÅôiOÖÎ8û ¸_¿Ò¼ÇCϯåæiþü·î@zУQç ƒd‹9`ÅpáèwžJ²6&Èýˆ™üý¯ÈÒCÏû)Y@½´úš˜IqCOfæì,Ó«¨fÞï— RÿF—=;ÎyÊ?q‘’õ¬e&µmÊý‘·ÿBzÈ»þËÙ ,ò$w:}~#ÊÕ“€p= ý‚3þ…&®þ¸Œi®c¨biO ÃbÖi‘Dtl6RŒ¡µfpÅm»ê+øÑ] @•bQ®#„9¢li¥S¼†õ1}1¥úµý+"<… "ø—ëÜ4GÝÇîg—®I{5?Z-¡VplpÓî„Àê{ýé +NtžÈŒŽJª¶…,¦Mk'I»8àKšW”H‘­[8?T@ssÝREpÙ! –r¿úm<`‰S‘–u å)<Ò%®ƒ« (<ŸË¶]càrseEÔFöõJçΈݔm½”Õÿ#âüÛlü¾g¬qÚ%ÛÍÆ‘AMŽŒ-˜«üKH!ò;tóƒ&ÙMw²=-“ª!ß ¤Â™1ƽRë%íTyò$MÔˆ¬^ö Fe.#Cz£"åwò~°`Ž!œ^¦<§k©TNåÞÃj¤Ãn#êÑ*qf´Ö¡‰„„`‘y¸Z®‡àN¡}}Xª'”Uבlym»ÊPÇZö £¯ßjE ¶èñe’þáŸx'ÄI!‚€ô´VÂbþ\žú7KÏÝt(p€1¹ yçˆ;.!wýA½öøÕ•x¿!j;\±õ‰vžXº*šDìIùŸ¸7kçéÕ¡C#É‚i¢Ué silÁÖ ‹Rx&µ´šÜAþ|Eo ÷†ôzdJlþ/”w¥áÎÞ/;ËYÜ(ž<œwÌó/5 º.|ÿfæÊ¨ÈÕH¼¥q•N-¨¢U¿^k0³Ð'¡ë¢åë0-‚ÞI¦¸1woí®¶Ë¡ž„ùšð¥˜Ãð³Ë'R*÷S×€ÿC=ÿ)@C[;ùn«Ç´M§=›]Bfl’>“QŸŽh§6Æ5pàÄQõ|µÄÞ™„'Ä©6¥p€²§ÒëD?§)î½oÿÇ7òB¦vœ,t+Ý–v«y‡é4£ÓvX Kkç=&Üi´^bçëŸæ¢Y-Ù`û´ÝêoЉìu¯˜¶¤,âÄ-‡‡MºX%Îi ü³$„$>s—5oŒ¸òuÅú’¿zº™4»;gˆ©Âñ|Ξ5æÈgø[<ŸÅ`z|'Xx³Ø&@¯ÝHSœë4K¿B ¶Iqs¼`×Xù %ô·ë‹¯»T¾î¯Ýe*°Ò¢IÊdn(ªà"ÝVÜÏ¢÷¿Uï¿'´?%dUx•œ`8øˆçãøÑzîßs½^¬†ŸP«rüAÑàOõ,åsË·R6üRÕ Qcê¬KÙ©séÄDBºTì”åÄ¡—Ve¿–—Òt_hü°»Øn' Æ[ ¦ œEl:C-dÎÁû½ñ°Þ|êÚà æ^v‘šDL î(ô!Cv©„sª}7 ´Ri»=W¥Ð†lÜ‹ÒËZpe>_…#mÐ7Ü›Præru•LAåµUó£ºá±Ø´çí.cc/cW$4K+ãÀ B!Jn]Žfž"îÍz÷Ó¸‘<‰ žæîDbœ(/‚R¹½µ™Ùò4‚`úvô7‡®:[1Üàh¿¤•¶á[ÄFk'B\£zœ‡=Ãß;;,ÛIÕr9ŽÔ¾²è(·20Üû¾#),e.µäløæ³ÇÁ¥³è§¨Ð<‘ÏnÏe¹<ÍoüZ”MȸbfJRŒÜ õã‘N´ž”­ñÑ_HÞïÙC¤}²ÂZ£ùLc&Ós€SË‚vš ê>˜ØrbᦚÚ@_æ*‘q’ÈÓ£`¹©¥­ `ª°cÝ%«¼åäpKUx¯ACÁwõe¹åÙaÁ½d4r²…Æ1­æ6@üï¼K…ÀšÔýe¥‘T3€KT×’²Š®ÛE£«ýOÖ9ã´ðX‚å›Ù° ÷l…JË¡ìøù†õ®™öXu–2ôSË‘¶›»f—ÅaéÝqþõ_6ð» 6 Œ?8ü ´›(àICÀ#­/KáÑòç±oS×Î’ôzPÉCÒ‡x!‡²âÐN†nüj|±Ä8ÏZ ]¡ÇyTˆ¼‡[¤=qÛéå°qO_%Åve]rÞÁ‘©þñ(¿2/ÚUQºð/]$Õ—Y†OMÈÐì2n¼ß§‘éøÅíGÌ¥2^Šë0¨äí´€©BƒÆÒ ‹¬|;är‚Vf±½ ܸI¸åÌóÛ‘-Æž}júØ2gî®4‹-@.®†ÉYÜ9:·ÃŸ¼ aØî%ÀFý¼Ù&Ÿ›´5ÛôàÄGzR€3eF“›©½£¹ÞÃ+‘ÎDQ·{ø“ÃÊÈuÀB“ü§-ÁâÞÍÛ^¿qoÙe{ð¨‰y« $q° ™%¸ŸãÑQUé_49ðÛ=òñ>9ñj&é ûûa¤Bõ O&ÁYãÅd<Œá9ƒäB³*£†aàKfkÁˆÜwÖˆ®ƒ*‘:ªöíai°Ú[ñÈú}fÿQÆ|ýVÔ6—½P—ÞmèQkX PÄ•y¡‰£t¬•úÅØxÇ¥F¹ ¨Þ7qE÷®‘ñG/Ž—Ý#™i0äîI î¡Ô¼­¤úÀUã ‰ÀЦþÉLTºkQÿ˜¸n¦íè©pȈÆy¼öo' á¿KÕÉ1p‡Æ0œ_yZfVkŸ[»Ž ¾y³¼Zú‰fÓhû¦~<\{\°À~Ú’ùX8rTkEm²¥¨UÙ¼“²ÿêÌö «H\É÷ê‡ù'Ê•3ô·­ˆ?i™\?¾5f˜›lÀ$è„øBóĤçiDp‘Nv#üU;¢5´ˆZÿ=­eYFJÙ‚Э[ÚkÑÐqÑ"ƒŒ³¬búÛö—0‚&€. ¡³Z‚¸|ñÇv¿+nûv瘟[>ÅAßßA¤ŽBD–[ÔR@Жõ£KÔèÝÅ¢ËM›?·n¼¨è bX+Xr<¸~_*µâc§—V¶ ¢#½2‰Ì¸|†7=ô÷™f/“æ‹W"À%ò¡GOqxÂ’ƒE²—¯w< JɺýÝ6<&{Œ´.æ—‹WaHgÝžHó‹üä#ôõ9O:9i’õúÿÅÕÞNÜøp[ÁmOU¶·«¨”Oüg\ [›Ó±Žº†¡KÆæ°vð¸cGš€”0N[yKQG”þÜìmbL`Tñ¼„ß´gƒéÜéå­ºbˆ‚#¢þ ÞàhÐ2ÖÍÃV:°§÷°ù}·‰íÐã{”eJžÁRLÕ/(´”îØup¡²ˆ•Št%ªëÓÉ vª°qVu³m²\Œ|.x·5åõéŒ5›Cþà»P“îã‚]‡ÈºãÀçŸö?ª×ãŽëAï| ­983;Žéñr>þ/ÁüÁÿ µ‹­%êîj qÆüç„0wendstream endobj 20 0 obj << /Type /Font /Subtype /Type1 /Encoding 55 0 R /FirstChar 2 /LastChar 122 /Widths 59 0 R /BaseFont /LYKVHV+URWPalladioL-Roma /FontDescriptor 18 0 R >> endobj 18 0 obj << /Ascent 715 /CapHeight 680 /Descent -282 /FontName /LYKVHV+URWPalladioL-Roma /ItalicAngle 0 /StemV 84 /XHeight 469 /FontBBox [-166 -283 1021 943] /Flags 4 /CharSet (/fi/fl/numbersign/parenleft/parenright/comma/hyphen/period/zero/one/two/three/four/five/six/seven/eight/nine/colon/A/B/C/D/E/H/I/K/L/M/N/O/P/Q/R/S/T/U/V/W/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z) /FontFile 19 0 R >> endobj 59 0 obj [605 608 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 500 0 0 0 0 333 333 0 0 250 333 250 0 500 500 500 500 500 500 500 500 500 500 250 0 0 0 0 0 0 778 611 709 774 611 0 0 832 337 0 726 611 946 831 786 604 786 668 525 613 778 722 1000 0 0 0 333 0 333 0 0 0 500 553 444 611 479 333 556 582 291 0 556 291 883 582 546 601 560 395 424 326 603 565 834 516 556 500 ] endobj 13 0 obj << /Length1 1614 /Length2 16836 /Length3 532 /Length 17741 /Filter /FlateDecode >> stream xÚ¬·Stm]´%ÛÆ‰mÛ¶œØ¶mãĶmÛ¶“Û6þ|ß­[·Ú­zª¿vkkôÑÇèsε6 ¼€‘­±¨­ -='¾Š¢š¼¾••¾‘¹­4 ­•þ™Š„DÈÁXßÉÜÖFXßɘ_ÍØ_ØØŸ‘ŸƒƒŠ_ÈÖÎÝÁÜÔÌ Ÿüƒ‚ŠŠú¿,ÿ„à¸ÿ§ç'ÓÑÜÔŸôçÁÅØÊÖÎÚØÆéâÿ:QÉØßÉÌßÄÜÊ_HN^CBV Ÿ\LV_ÌØÆØAß _ÞÙÀÊÜ_ÚÜÐØÆÑ˜ßÄÖßê?ø†¶6Fæÿ´æHûƒ%àˆ¯ïhglhþ“fìfhl÷‹ßÎØÁÚÜÑñçßÜßÔA߯égN¶øæ6†VÎFÿø±›ØþKÈÎÁö'ÂúÇ÷&oëèähè`nç„ÿSU^Xô?x:™é;ýSÛÑüÇokòidkèüOKÿú~`~¼Núæ6ŽøNÆnNÿÔ20Æ72w´³Òwÿ©ýfç`þ/ gGsÓÿb@ï`lªï`deìèøóƒýÏtþ«Oüÿ¥{};;+÷³mÿúŸÌ­Lh¡j:ýÔ65·¢ûg«HؘØâ3Ðÿ‡ÝÈÙî?}.ÆÿˆüŸ=CñCBßÈÖÆÊßÈØŠNÖÖé§$>ùÿÊ´ÿïDþ ñÿÿŸÈûÿOÜÿ®Ñÿrˆÿÿžçÿ-êle%«omüoþÞ1øÒøÿ\2ÿ[°¾µ¹•ûÿ)ü¿GªÿÇÿŠ„“þÏ lLÄ §¥ÿ£¹£¨¹›±‘¼¹“¡¾‰¾ÕÏ”þµ«Ø;X™Ûÿ¨ùï ñièéÿ›OÙÌÜÐÒæŸ±³ü‡ËØÆè¿Sÿè_âtÒ‚ŠòTÿûúoœüòNÊîv?ÔþG'2¶FÿsñŠ  ­¾'  #> =ÃÏûáÃÁÄâý¨ø/íeôÌÝðµ~ÚþÉü§ùÿñû¯•öƒ±1´5úg¯(9éÛýl¯ÿiøÇmèìàð£ê¿'þ§éÿ\ÿ»ÑÝŒ ¡Ö–m ¹‚,R3ÒœjÑs†'…µú{€‡ƒíJ” óýªm{|SÃv8*ô>j‚i§9¿ÚÜ—Îì>$)G{ѬÈz’¯ò~yQôå#þ%í`£:  Ó)M;W‹ò¼^”ÞÑd¥W=ÜTPÔ)þÙî`r€¸~¦ð#rÉ÷C!~²ƒó1L©EíDh@ª-8;'M8y~"ê¹í;À¦ÊŽ…$ár%ô³ÏÆæÓT)©l¤½jˉ4âÞhÎ^*aÒ³›œòÜç5„I(³:/r¾:LˆæuM³ V=¯V¬·Ã9ÓaåMÓœ¾üüõr9Bf–„ÜôBHÒГDx„éqËcW?…Èç 8•ÀtžN>•¥ ›Îi–"°¨æêjª‡êÀƒÌCŽŠDÅF¬°«=oßnÆðÞ¦tÃÓŠ÷ë0}òÓŠÆt¯y´|ä*eqÈ2V±³jl3pidP÷·ÞvN¢ý"Ž­ÈuêùfJ÷ó’¹lúIjMž^xšrUm5)ƒR¼Á ×¾µU »i]öö+\&··;¤è½˜`qXÏ\`½‹D­Mu9MŒú¯?¿‰ƒ…ñ¦uß_o×Rc‡†g“P ¹”ÜŒ¢ŠuilùŸ'‰âÐC ”'™ÑPƒ2euIº§Z"vÀ/àؤM®ñÝ]ûû§uW¡œÖÓÌFÐãlQÂß5I‚·stÀ’ïÿ¤¥Åïq8sÄæ>rä§]CBgæÙ$‚èKÊ•/Hh8?UÇ)’¨5ÜÐU®7Çô¼·ª¥ºÜ¤&­ü}ø¬6ú=ï|_º%\>·ØŸêiµ ÛÁ@®°ª¾wð¡g#ÐÒÆÁ[äáÛÇ}ÂÒƒcÚ§3Z“ ‹òVWds[L‹¢ÌT ¯‡ˆÂ¿%´8zç‡,/ÙSÔÍ¿]DÃ\C‚FQlæXO;ê&3D·ß"C’­Ç‘\þëJ/iÂ0¬x°8`¡“/ØðTæÎ„Ý”py—C“5Ü Õ®îrÈc?Ù…Š+圥äBU¹¥-B¹Šé…RŠv”cä2ZxÛM~ô>µìºÈ–•\ævYæObÌ\,è%zcèa2ƒ°{¾¢¾0¾è‹» i ÏÚs˜._$ó1æv}¨‡ÈiÀ Wíý}n&Zæ+Ü®Ÿ¼}sZ^ÏÇ|FRÑ)¿E$6áCGõŽš$Ü*‚Ì7Å•#:7dP vz„²tÎÖ¬ÛuˆïlfÊÀN<>PÍ þ’&üY45™ï7Tèu¹ÕJZѧŽíÒlÍ–²eÆoå^Ø„µmäjqÚYn­€lpœ ¿MnÍÿ$³.eg[áik[FO%¬b‚òsžRfZò@Y!pe܃Bhª\HþÜî+žÿIµŸiüˆÀ k@6¾ev‚†Täï¾…†®“jÐìþüC­l¢Ž°€†g%Ö<èõ–È÷Zöx²t;p4ùö»SÁÈëÛqøŽúHÆÐzëLã©(*÷SØ<,ZZt #ˆ_üÙ ”ÓMº ¢ ÁÆF‘þtˆ¢· zÚTÜšU­MÓ¡‰&Ðo‘NºsÂm`;':`í2ñÑ„.¥«ŸÏÝýhIœpòÚ·©õ4ìÅYñ0\}þIºÝ›ä/ŒoÕ–Dv¹ ]“pKW3[H H1Õïä>ù·CûA-ÌÍêCI÷‡:åÑ}Ð3gÎ\÷Óz9ÎèŽlÂ%øjuTœˆw˜—Éç€ÕÞN&D®TPƒq0ͪ¹ðq¦Þy8ÊáQs~xБ¯èb±³¯Yƒ¡ìÙâž´jå=óœ#8=tŸ2×ZJFdù;õœ£H ôtÞ”‚›M¾“m-Ò–¼bRz#Wü©‹˜° ðî瓉ÞRùùÉ(Éü•œQšAzwð$ptI¸ÎƉܰ…xÚ+{yNÑ³çøˆŽúÞúGÈ­”óú ÷&u[ø»ƒp´UD-É»µmÑÝÃBöàÜHòEa6ç+Å ¶ ß}›kò¶”nDop³@Ü"ÚÞþA14²w]à®Ëq‚í­‘`¿’k÷Q/§%HB¡9â§ØWXîKÝ@SÛõ#"DøF¼˜‹ð{™Ù¯5èR¤˜ )‰B³¶€Ú!Ç7œ«• WÉÖº´¿TK  ]®Õ÷Ô©±{©M[sÒèË …oá`xÖÙi²'uB,ùüihÈ>ê ^ÙÈÈ s¤ÊSM„åØüúU”̯Q`&ÝäZÌV¤êçwÙúU€5{æÒΦƒÖÊ·[Ž"nAçk2 C5'²vÒ®åæwé ,©.^71l ù¬Hµ«ã´ñ¬›LµOÛìû·¬‘SÊ)dÒP¦1XÚôϲ}*ëÅ«éJª¢Ç­ V÷~ Ç?ôðÎøúFGd Û®ˆ•‡Ñ<ÃMà³ó¬OvÒ·>Å~-½K •fg–ar£zCi1öPmÆöô pÏtËÈW[˜Ê¤ArÄŽ°\Ø[O÷âyøuJƒ=ž0ã•ùU»[}{=Ó‰ ÆQukö°da™)ËÉEï¸YF”ìîÀW0éî©jÑLѹ Ö R7Öõ«0MÚ]Qð›9ÀÕ*GN´7 D V[<†nó¤nÇËß§Lß¶EÙ»zÃ!»+=Mòµ÷?Ç <ë¿ «zñ¡¢Iü®´™òʯg1W¹™OèJ}„7®ùÜõÿÍ¢;¼Pyç²<‚~¬£Aö·<«Ç $Fhw®¹©Ñ‘©Ò[*HñHno}q½bL0Û¸×6(ÿÏÄû° Ö‰hÛàÌç´Ø0·Ò=ØgïéPSÛ[Vç+ÇÔ »ªKX’ë«cFD¾wõžø9­“ß.þ}œ¡¦£8Àß’x¬o¥õ§ïÁ«B›²Jq® ß,÷а˜Å܆jY>2¦é™†$Ï!ÏvAêÝ«Œi¬E›gœK£ëX­cÞµ´‰zîéé¨÷.”  3¾¿[àæèÏÙuÖÞóY4€ˆc¶õѾC=€ÎÞ܆Ÿ´Qld|ƒ†pûz0îteÞÐÑÑáLDÓªÑ5ÕöL.M#yø ùÉüŒ¤8ëHå0ÌôðÝöE“í |¿_`“¼\q<,P›Eé€(„Y‘2c…FuKC°„iCïK׆K$ô¹¯ÕmV§F~ñ2GÌ‚!ó>žÆ¹ýÑuM’˜äbh÷ggk°[3»ýMhG­ÒØ.IP@=€07RíÎR½ÁP¤ÛlY"Jû†XÇп$ŸÅßTy‹Êg0¬Œ(¹î˜“Œögb€ez,È8ù’EÖetù¬&¥O|VdiÓ'¼E9†cœpÝàŽŸ³k3®h<'Ç cŠúãùF‡ âÖŸËê ŸS3O5_ÚX/jö T@I“ä7…˜:Ì«î”Ûß/AN€éå ÐR:T਴£ÒC_û ÿ‚åI^àŒÙäGqþ—.è þZ5ŽÃ¾LE8Ü­ÕuY@©X5¢¥Ùž“Îs^ðå«·· 6YÖ4+v¿ÖªÎ8ͽá>4tÏ÷øÖfIÍ •úI\6“ç ¸¸^{…1­ÕvˆçNE¯n߈gð%ãÉÍ?ÍÇ|Gô]¦Ø¶FMºyÁYP&\ÃÀDÇ_[-åN[¶ÒKˆÜÎRb$šGШž[éUî}|˜rH¸>ƘٜƒýVý0LÐ&ˆÒŸL*ö·óÏñHõJGª¥+/%Ø"Ô¯ú{¸:)%-x_˜Pm’WÞX?³rDxAˆø‹˜=(‡ Ò:óâV­xwQû¸Ûzæ| µ{¯ZÌîD¿©Î— ez‚WèÞ+J)_‹ïpœ*2’(q¦W̲iê¢ûÙß^`ë¤`’™¿Í“Í=~¼Ë+‡ñ–Ð úœí²±˜Fc/Lž´Ežè­Ô8ƒ Ä!vÅFëŠbT¸fÇ {ìZ•zT<áhÕµr˜¿Ç}à¢!¹éIÙÏjS¶cŽ}¬§k^ÏÜV`S)dé1mR-€úï_‹(ΫþmE”®$çÆ³òÌÔïwA­©ë†q~  LÔoŒ(@”Pk–ÓÞ&î×v³Õ‘Mg»T,©@ø Wî÷'¿×oPô˜S½þc&äR‰ÓŒS¿K6XsÈ€è£_…Ú*ir§©©:·N¢r†¯ŠiQ¼«!d>Š! o'Èqn·Ž±nÝÙ~6ä-Ê5{Ûì6ŸD‡N ÌUËï_iög6fNÏÃ*Ùrp€ô×§„K°ZVóͲˆ|TÔlY#^‹A¶@Èš­a©ŠãxÜ#˜½ŸZO7𪛃ÄâN3g¸Ýb'%/æŠõI«ädNq~Æáw‘7ëGOÜ>²£0ÓÙ\Ù:JPÚí¸“egÇ$$EÐu‡£¹ídeU{B 6†´T¸8D³MÆ~ ÿ~¿”0¸ÖÊ4æàÚE2Õ)á5úF­ÆƒøM|RðʈÎM±£ÿä©yÅŸS%ï³1]úÂâô2¨7ÍÌûREVCOùÜÍÅw*‹ŸÀΣ:Ýl=–\p¢ þCc²Ò\ÓŒ­½ &ÕÉÈdŒ©“`à!9çÅþjm:O¨"¨‹¤-ïF» ¼cE´§7ÕMžšÆQÊ2ÝæÃW“ýv¬K÷‘jà‹"u´ße5â½ms_X²ªÔ³aI„ (iŒÌà*Ur;Ñã™Õõ›o<ïݮ܀óÚÓòÊG°·ŒjÚžç–‘†ôήeðyQQ+í¦t óŽ|ŠÓŸŠÂVƒ1“ˆ1a,(’‘Àµ˜:Zb²¤&µy?Ÿ+9A)OéAE1J~ó¼Ìx}¡àà²L¸Ž”ÌÈ7pb(T¢vøð3¶ï©ºßnòE+…{>Bˆ “Ò¦¦Ã5ËTHú»Ÿ‚õLœÉ¡ ƒ6ê4ñpK‹'Ç2<9+xÁr'ÃO9"Д3•+h¤Ö ßŸ\ = «ã…õå™d¿)õ[ç“g‡E$³è™ç|öñËClŒ ?ƒgC®òãÏ1È&Œè¹†®ºUžÖÌŠ£V©Î,á!Ï„³ÿú«ÕB”­y†þë§/H1¬F5=.ÆsÇÔÙåÑô92Ü5—R×÷hîág7%òé‰ÔjÏ…ŽF#ž”ujmm2ÕX¤€Ýó˜Ó·$4…e3r‹+P¨ؼҥË_hëß1×›õ§Êé‹hOgrçKøÝzI ROIÜOàgê«õÎæOi¡½ïáRëÔìáç+“Í I+µÏjxbÅæ¥b*È\œMt´"Šéj™ËbÀzn°õ‹Ì¤†c‚\åx“Îð2ÙêÁ%ÁúÌ)´'$õøŽáLWÀÕíG”¢Ö…²w®K¨Y³Ê9ÜÂ"ÔŒ_´ ¸ŠFŽ}üí dVÚ»ƒX^aô¶žº(BçGø ‡« À JÈ£,Ã.%–-·4³ã‰4âOƒU L¯w%]”Ó´¢;ðÈ$ÝY‰/Ø#YmÏùã…ý¾ynM½‘ß»ºÇmÎñŽ ¿,Ñü 9 D.Žå`,}ñễƒÁ*h(ì:¼•çSàËP,Z0ÛgÑ…ÉR†á;äBË¥Ð;w Î#qÏÁ®«4$ Ê眸8Pºo¯¬ø±ðYL9Q~Ð |þ½ø^òëŠÝvÓ¶,_dt!R ÕÝúÒÊ3)x€÷Ôñxâ¢òZG~ޱüùx€2Ç–e†cx`'È8܇}wûa´Ÿ(7)ì ˜¢Y ÷8£«±è‡ä>ŸpÉo{[Ì ì Ú4ù |‡hBs@W!S5Pƒ '¬þSǺV©@ݘ.i@§ªÄH-W|“wîcwøãº\äçÅêä¥}ÎÚÊMÇk` Ôh§æ`]Ð.g»$†¸'BhL–Ti7_”½Ìl#Oˆœr‚pÃüâH@íRê_4šŒùÈ×S°5 d;G·»¹D™¹ùÆ|7Ú¨¸ŸK@ÏU/Œî7ÞZÙ6ÙŽ³­›Ó£Ž¨ ­™Ñ–ªì«cˆÃ-ÚÅâñðÿ{(v­3)Oà=¥òœ¿›BpÏP]ñ~üû~‡ý·7#—¦Á:§´Ëµ?)g:®Oá¯|´~¹pð7Íj£Ð‘×¥€jðÆBgø1™îƒ*¡\J"ô^3×”x@ óÔú«¬í%¼€Ñkåê„¡im3U„) _ø¹r£ 4˜PÜ)Íò¸_½åé¶l*dp¦¢²‘#xœ)C­ë4*]\]¢Ì¾5ýÙò¢ÙCi«Èè´|*L8 Ÿ/Å E‚ûw„¨Zêi‡{—8ƒJäå]W„‹¶™Q&×8¦hÍR`µk;‹2ðÍ=FT]•Bx~Åú¾âíµ·&ˆŽü;¡-ƒ¦¿_(¶[Pé}M!µæþ|‡ ~¥\”,æpæp?D7bè½q=†•v14VƳô)›áPbÞ¬ C@à ÜÕ'·ð Qmž…¶pHÀNðFàaº{qÂõ®ÏKßÛ`œ¬Øk:òßô9oêi ϧá­Nöjê~}6Ë ¶pf0,ôØTj÷: õã¿óR›#DôQ•Ä!ƼÛQ¸V¸çóæ4ëwŠ ,l¨šjÈUâW§ž÷¿É…Ë` lólÐB‡3P rlóÆñß7H3f›“};8ÙÖÆÎÞ#J"3¢ø!û<ÁL\KÛ § äÚ…™7¢‡L{`Þ[&>Ó[%ÉÜê{¢M´«xÙ0ù_ª›ÚŠ;ƒ}œôÑ6À÷ rß“òÕφ3²†V†—VS,|¨ôѦ…a‹ŸÀ‡vµ‹—òlà’ ²~Ñw4¡ ‰TrÔʼ¬zHÑŒš¥øXxMëWùPuI¦*WtôµØÎGé‹Zmâ“nÇÑ™ii‡ˆÄ„‰¯ÎíÑZ‰OKÃy!"8À\Ì–o?&¬ß=›hÁ{|Äj!•/ÓÉŽîúe]á6¬D¸ÞÜ›>ü<&‡Í„¶“‚îºÐ¤ÉBE’¥-ÅŸF$_J.wŽÉ†,Dp,L‚‚°¦y›Ìé±^–m&æöâÉånèܱ‰¢Þ$J×0#É.4⪦˜¢EÚõDî¼õÈo£ÔƇ2A˜Ú"¦Mè-û¸àr!1SXf«èx\¯Å 6½m¢vüHíNª‚ªfmòR¤G|¶K1 qµ+ëÔÿÈJ®ï¡øí™ùM„Eú"rÍíŽ Š&¯¼œ›V4Û_&^2x=,ƒÊ× Ṳ̀'óê¯;`†ÔôNvG$#óZÉ×±4ã,K¢vn14cspq>áĘTŽù÷ÕD,*åqjÛL/Izâ³}üo7¦‘dÞ/˜åôÏ&—÷ZY ×bË/´ãÜhþåµ‚àœšÏ!el3zAÏ1˜\K®WíÕÝ~þ‡ßWè*8ºÌÏn–om¤Ûûz¥vÅùB¢Î¨>2 óÛûÍeq7š¶¡+WÇZñÂè¤ÑàÆ 3‡1õÏ&·Ô1«D˜Ç<Ÿò5Ȇ„F´[ Ç4 ãc>§mQ*³þ¾7³ðŸ»·M¦‘öºg&ÕlƸň#“£´’Í ®&ÐÆ"‘w.<õõ,›p é¼àé®rDÚÌ» V#ÓÄà’À¼91H8ÃO>'–S)sÇ3K•ÖæÓØ/žw¦ Ž£dèëéÛW´UW w\h¬ºz¡L)Ò,|à%h¯)qÀáòpiƒ)‘»š§Ì›”/Ë3/mZ©é¨m²­UÒ'0uJ#øtq¥HŒƒÞ¤½)švWr€Ynr9乨ƒøþ̦©–+…/Ȩ %ìa`øTžòýefUeüwgTYL°™Áš†8¢]š&SB}ŒLü4»¥ã°N"ÀŸb¶ªò·³Ž oÄʼ¹¯T¾‚­b§*èõ¡¦ã’pRGŸãÕîèóòtF_± ê¯y) \èC8d$ÚE’¾!½íosБ–W)…«ngËXl¦E 1=—Ã=Luëé½õbÕ¹² e9JY=ãSºÑQÐñýLœndº¬'3(âd‡˜{K³ò(ÝyƯ˜ öÝ"î FbçvÚa¿Á Í7îG§þ”Ú†ƒlÁãf³5›óD;a(1ô¾“‚˜×6Ù±ãòƒ§¤î”£Dè }Ê`¤ÅÈìÒ»a³ÄX ?N±Ú5Õ3Э"Zf7`ô“…Þ¿sÔóË å SH:'wAD5T^¢óý×}KY÷#ÈÃÛÉ÷zp5• £ýúV¼K£ŒNpŠÅ® Ð8u4‹<5d”f19ùŸÃØ·¹VI=§­Ð}Û/¬oŒjüÖ’€…Ìim††Rõl9±û;½ àÊàwÎ]Oð¿*Õ’U•ÕÙàS0'äôØáͦj3ìkkjZ|ðY,ªÞøð›MN£˜dFs;åë ÃW>Ñî+kè .ݶ&EÞïÚ3VßÉ¥KðÔWÆTg`$k!.Yë‘‘Hºƒ£(ä„Mó®“DµóÞ¸õü!‚þâcmÍ}€(T‡)g’ÕRêCZñçs°/be?/´©ãçÌBÐc_kB "wç°.E(–ÇL“nyëá¹Ð­ž39‘¢=Ož#$Oªý.LzʉÆÔEï#»ðµcôÔç}öƧŒ½Gþëk—6„°3ƒÓ¿ÁÀÀ1Dš…·= ³Sâô¾U½ø§X”‰1/<ºÃ&Dº#ðz®e€ŒEçÙ]@•;íý›¤”ÖÀóCâîò#ëÁ“(ù*íÃ<µ2TÑ”µ-Þ’¦C 2°O͵ueci?Ü€dúéË’öq1÷=»Ar#&&õåî•-åwƒëøÐƒ6œ[íÀžØ^,‹HÑP’Øê:×AàQ¦§…ak%ô:Bx±øa‡k4H“Kí¢¿Ðß÷¡ÒsQ}¦ª¤üÐŒ·FÄYÀ60r/^’„I%–#¬kÊu‘2uNý3N‚‡4ƒx¹âlÆvËiÏeo6¡¦wîg9î³?‡Å€ >í§Bó‘0l/o"yJ$ºOÃN¾ n¬šhA"„>ÆŽþšÒÅiØ«6:ÇÅ[¹å][È.€l¦ä†d…ñ„–_$ã-"¢ÎËú^¼ã/Gû„.¡«'³PF}—/Ò‚¢c—¯gtæ¯Gé_…ÊãrzA²øË¬üÉî„ÙÂMÓlÍv|T!ñ½àcÊ ˜^ž¦6üõ"×È0X5Ê‚!å[3ŸrVBYV>ƒÓjæ*ú [ö„ÖÑÇa™¤[›¹ƒr¾õÃüÉpM ×e É×hS–ŸZyB÷Ëóù›Cãx«¯~»sݽJG#ëu[Í+ÌáØÕU<Ÿ¥^kº–úèìsÚw¡k=¶uhÝÕöÈ—“ Õ‹¿0Ù0‹z®yÇÆN§õ C"”˜ã/ÊÃ{ÛH¸ñ挩/$I5:º 2Ì&CÃÝô¡•YÈ$ÈÀ¢¾…MÑN #ë({Ð'ºYDƒÅ[^ð´|)<ŠU“1ó-€uÝ'T,}6~’_ ,½æ£jå¶¡=_N^Ÿù!ì*üŠ—+±ä®\ã}c7òƒž€kxb22öNš0'!`kZÜ›âÞ9t_æ×n.¢™dŽ/‘C®E“;$ƒ Í…-,¸u‡ãÄLGé;Ï+qõæ"=¬ò~q2ídÑyt*§=o,,“I‰¬Í} W•„£AãÝ%I¼TüÍÖ÷ 啸À>—xÑLË FÁ“«2ÇU»w'ü%ª(3XŸÑzò ÏXÀú¤okÍÂ'¦†½õ%\d…¦²b£Ëø€ÖNF§þØÆ6í¸’ÚþˆÉ':Á»_‡ÿEz¯*tµøÐcÀ£þK(<øÀªyÙ§Tˆw/ÀëC¤ú¥¦:PüQc¹Š|‡">ŠM®ˆ÷º ƒÑy§“…mº ó!BycŸÞGÜúukwÔ(Ž:t%žVu*hùN>ŽE´[Dü4È/³FÏÓMˆ;ñ8Ë: ­zç …”¬¤iI,Ï]¯{ûÊrxsî[g+]ˆ½s`$æXîS×ÚM¹IÆÑËú>™*©±q.Ü¢¶Ä÷=£#%÷5è¿­#ÚcL̪¤N±x†ðÚ¬þáÍnGyAqárJÌç«^cÓÒû+лA×ú¶éžoÿ@1Bçœ.Љ‚%z¾<(yh'õ9ŸéÏØL—½%1 ×Á¹·ˆ]¡‰¥¿“qB&aC;”»oÂÙh+ÀÑý¨†ÔF3“ ÓP ܹó;áþÜD.Oõ×Þ´]*ô¥V¶×¬¦f!?pèCuW ˆr½Ý›,·Qú²š¼Ÿ´ÅiÌ%Åâ`~”£?p€híè²]ÇÏü=1„Ðó´áêß³‹>Ĺ3jüý¡hKœ3‘Niüý³.­ê7–ü eö®m^ A¿6®D2Ëp’)Pë‡j\ˆ€´@&t½S)Câ‚Dbt·3C¶LRŽ@Ø×]r‹ VKhYÄ¡ªªB®µ®~óCÛ€v±¯è‹« á]mÚ%k?î:Ý8áë@œIªiá‰òB#IŠO˜ù^ wúˆûQdìÒÓ7•ìÉÿI"À»-L\q⡚ÊZ“PÍã8ÊOaø®:® Ç mwš&«Tñ–9~¶GP ,¹4¾Ëî±wÓkYÙ¿=Áº¾hbà¦î;Ò3_²5v7çn–WêQ£pØÒR=•¯âRoÇpgéðžL™£ ±Þ¨?]®¥‘-â¶,n\x ½lîž—>S¾+µÀe?oJÛ3BSRg•/̹Ì|MBCO§Wh0“•dâþ„YsØH»žŒÏn<Œ& ¨á+èË=€ã§K³7hHª´© àkÁjŽ­’e°T‘eþèòŠÔP/-ÿ:ºÑq£DƒƒAc¦dõ´8wæUßJÆ3–EbׯíÇÁ<êF˰79û+¾ÑŠõjÅšÁPîÓ¢ç™êZè3bîs½/ül¢­‹Œ¤D{ íÉãU©4JÁS@‘0ÙˆßZ?âú6‚·¤©7úGð.Hºåˆ… 0ÀßçƒQô†ÍN|0¢vV'>—oм®¿óîmêú«Nø@aøå/T{]fú?ª\úa€‡V8Evo²|uUÂs%†–‡ÎBkìQ'ö2&ˬی©ãeǤYõ»¯È¨Cò—4J¤Ð÷@›ñ©õ?÷Åh:úè0’‘8ÚJ¥¦kNt@Ù,klþËÙgR&À;a>³luíì8Èði<ò39Ϩ/øŸKó·zï1wasx¥ÉzÓ†)YZï_Û–R¸sú¹rP¡Íº L-p>ù¸ïÄ êpéAï_þp_íWr§wxšÑCŽÈ˜XUkЪºÔ¸GGÃÖ„’Ç©YâœW¨ö"ô˳°3NðzÿáòêÆ:ðÏ.¶£<®{©ño¸óÐ7r\X¶T\àÌöLËäýÿ=2úA]²CO ¹Ã²¼áŠ~CVímöl£WÚ¯QU·ºYß \ÈzÄoŽóšAÙò5˜…;=¦çx#3åÚ1óL§–y„ÓªK\âÛí"|`ØX}Ù/'Ÿv‘Ö-¬0MР…{òˆ[‰¬( 9X|nÈ(ªÛ²Œû öòM©_5[=·×ôB8ÿeq.9®¿fvÙÛ]Tm xµ¦÷ÂV¨ù3’ÏnI¼òé`2è*_εƒIê?_Œ†Ð%fa™u*ç‘–èà PœIØ‘ÁÌ äæJ9Ÿ?êȯ ò#t©M–ãß6ó³óÒ`š¥ñÑŒæçx\] 0d‹‘™F¸çH˜žzrß‘é¶Å‡â “œCh7RS„wlúæV™Já™QΈ]R1ÅZA0‡U¨ÆböTŒÈþúrWð»bÞòúÿÑ Ï©þ:ì>Å/q Õ!Nòk±Ÿªª§éè³—G«†«ÌË¿7 ‹¡Õ\iÓqp£eLíèj@,À{`¨0$/0²`Š ä¸óÍàM{>—Åù¥3“¿F²Ëµ²ì‚ß´øWæˆÓMDà öÅ"Ð’û©Â{ÈÉâSžô(?®M;ßåGu¢\W=býé>*+vT"ôï³jÁyõ^¶=5투UˆkÊ<ò[*´öí\iíò<8 "¯B~NÊû]r_TMr äçÿlG0´ÅèFis- Ÿ´‰HgIyY¢ ;ùÖÞÖßS<…I·*Ñ¢ã–vYñ/œ¥_Vd¥^§ú;©vRÞ7¬X%‹ÏäÝ-²Gžà®&VX‡’—?ÄM_£³W‰ª1Œ­vŽëmLJöú%\|3è׿þ&ÑC+¯æÈ°bh}ôÁ‚šb2©>ÊÝSÄ–sp Ì·@!ñ¶DL˜vº~ OòµxâkB©$Ÿ:+œ›ÃäîêÏ/ãþöü‹Stv=ç¨A—œ]Û²k>[µq£¼ažMäå‘-šqÙåˆÆïrÍ-ÛÙ›ï?œÄÎtö4qgn¨ØÒâŽ2íOƒ@Dë“õbq\Â@åÔtwuú½@S’Éän¯k–¡%†}úµ&'ö¸Ã,άþ’uƒ|ŠÔÃU¹®È͵÷µ–HBQʆåÓw›ÍL¾åÐ.KTd€òÊm6Ò„~¯g .Ó7°D)³l_ü.—Ù²4ÕnHšxl»¦×r"6HR¤3ÚVÂí(Ëw/Žš¶_jЉh +¹ú29Ì1É_÷\®ƒª¡cXDÝÅ)¶”Âþj…Ô-´OC#ýf›HÔßE„!ËH7Vv3ð°V¦«“§ãä d´½2hHV¥‰)?'öa[¿No²ìŽí¶´—íÈølÈÜØ—àÝÈøðë…¬¨‡ê©Ü£^Å ¹äôo$ñ[)‘’DÿGö(îU¹—nàÝŸ“ ÐŒÉ3¨íŒw5ʸCpL>—³äKöKc*äé¤aǓīad=o›Ð,[!Sãêýã!hÈÏ› Íó…B'jëvFNAüÓ¾‰ð¯\/ýl&¢_¿5%"ý×è ÅM‹Ak .c3GÌM£Bb Ì ¿ 'ÂcSu/€ÔGèâ;Xnê^fBG”_}:î–Ѩ÷lªx¾•Þ¯ŠÈ)Â3•¦Æh*Duî2Òéqô-&\ìwÕTEmY.;WçMêq>éb=AD£-àeSTÔ×ÚmàÆ›(šYöIÊ›qW^7 ÃÑÕ½ vⱓ Â?jðp¬?À³6rœpêvÔé„T8¿2M’µ˜6Ð×èˆx˸•ÌjQШá ?èà¨M+‘%Mzñ vyï2Îü5’¿Øà;–›õµ”ŽRúdÞÌ™à€ü³+Ó›ž²¹Ö9›á4^A?¶¢üU÷à^fèƒÚ@€¨?[¥ù‰h ÐÁ‘ {ÏeÓ²‚ø’’ä\ ÐM”w“È®ÿ…, ±‰å"á lˆ)WX›Id½F˜„F \Æ0¥•,ßxà¼'æx›ÎŸ†Z”"© ¯îaW0•ÓȬÐÜ!q¾HúÔ5!…‰y˜Ôª7ÍÁ)ÿ[Dª€q&åéä²ÍKL*SÛ'ª%08„nQø‚â…©—vþˆ<Á¦ø”\8Uþ ^ró­)Cö¢Øì)Ã7øÙâd©;-=/ÇÚÉV÷ýÌ ½·£ṅ¦ÞƒÀAÌÛÙ†CÞ‘uxÈØS{Ü–ƒ§J`í7cá—šÎÚdÕja7$,vñe,ÿoQ(Ó•f­ê‰ùsñå•ü©ìï{Aò±?[w8|R+ä7Ž8È1’Æ|Eú4W¿ é©Ô#Q\›@¿2‘Ts q“¦üL¹»ßäÒ_¬ÒtPÝUÚ^_._rA6.£ù답á_K–Ð0ùЖT1¤NUyJÀ è"v6 1û·o5Î|%`Ï÷P÷ïùCßïôt_KÚÁZÓµïÑ òñ1Ò¢‹ÔRXk‡„3jÂjzè£-—Ž3h½J‘ØRieÃY\o26ï ‹ÝjþûþÊ]Î{Á‘Ý+Óí³i'h mŽS3©ª¿&>kïzI®Ÿ¿.ÜòC‹<¦ k6ê ²V;Ü)|×d¥µK#åmc6l§ßÀ¢7»=òÖȺ@ùNÿ›Á*¢c•â©´vÝψRM2È÷®}c'F„ëÒã­sø^Ã}¯·„º%]/ d[®?èÔ“áıÈOm–ÃÍîOgfröÚKƘwûÈ^‡º{ÏvŒ¶Æò½õúœ¹hð>~¨Ü[S—SÚùÀtDÓí±×(v~…†üw1áÈž I5þêië8´&kã$µ²±Æ¸w~V¬HçÜ¿†(<ŸÂ#_£Ø·w`åe¢¼£qçÐÝu±¬Á—Âe–Ê+®8\Fß mŸG×ýš ]h÷ÁNkI ÂK‹ šêŠ:FBö¸ ‡RØ×yùhoHÈרÀ°¬{½{d˜©½8À»P-4 ð¤ú©mÀMÚî—ÏŽwýQ «ÓtwOuÔyŸ(¦Ú N2 k §8Äj£—¥¦6lý>Uö*¡žYªµ¹Kû8öÐuD‚”n+t¯vJ<í¾øú£:P陿m¡nÛ±ÙCж¤ #j¥íÆžê<1yƒ«]œÃÑq ¯ß]1ç°Ó'©œ¢ åEêoÕt‡rËå‡j­ÖÑxOþv‡#„*=Úhí¦ºÅm‰{1ˆGUÐ §ˆð»¨n¾VÎé]õ6…˜ø_ßÃòEèô€ÓbHi U¾yA¬÷{3¹ŸÄÕˆ›g—µëÍ®Òþª¨*ùúQ()Ã=3ã&¬‚ ¶¦ú¾Ìxü{ÖLÂ, êêœÕRØe¯Íœ¨jUf¿4SˆCžêÚ’;vÀi>ÒHœ\2Aó13ž~—R.A‹7·‚=ÃJ‚è–Þ”AîD>i_êr]³Ej+ÿ%ï¸de’@ ßÜLr¨¦‘Žà¥IâéoíyF‡½ÿýØZêœäiÒfž-Þ¦Sw~Àót%N:9z[MíűûíAÇüù;aʈÃÁÄñ`p¯¬€ò°çr9¦kºvge“ÿËätpµôÀðºà\v™â ˜ñ™º¹¦xNÜàò(ÍH:Öó[FÌbÌ„¿¥Q:Í×'J )é> ÄU59@,-{ û”¯?æ{€'uMÕÍ8ú—èųRJ XRÌT7½.ª¶QöN¼£nfá#­F[žµcwé”™½õ*AÑg÷/ÔѾ 6H<=ÃÜÆ›Z™C&ÒøggËÆËè¯Ö“~ð¢ß\²kÏmˆ :Å^ 㘞’w›».Eåî×)oÜ4.à6ÛØP‹øçÚ¤jj½ûú¤BÛ:Ú·ª+ Ñ7´‰™‹G½÷¶Œe!#Ür=Æ3~qðàP¦äñê~ 4Œ£*Km¼ ;1¶ÕÉÓLâCÖn Õ®`x•ðüAc ×À5Š=Ýœ6—µðÈ©ëÑéWj„@#ër#ÜFVREí—)Ö'øƒÀáÙ4Ãß5û°¦f;ÑYìô-U¸FâäXnÃn‘©g•Y !UìÁ濲;(=v!¯xÎX ræyXw~ÛÕ«Íf¸ë ¦/IÝ\fW1Ë~aÔ6÷½FiM•(þm+ŒM%  ZLà0cÏ×4¥¥ÊP§;Èæàc€†çPCè¥Ïç9V©ý$>ÞVG¨x›²óµ/¾.õœ:=ý]³l¡Ó1âtŽJ­$ß͑ߓ«è7“vœö0B† &HÄ^¢æš_Å^¥uÄɈ q‚)!ä^çGc9{…³Üð‹Ñ§á^ïZà3®UQU:q@­ífó¶ k}¤(_†êšØ¯3¤™Òà–E‰H9Ö”¾ç âÄiîPâOÛ¦ mß¹Mó¸Ý2ß(8BÐðÌï’º›P\’êL ƒéXçÙh±Ï` ÞHhÅfíúàdÚT+ªEôÀÅùYZ¡gºÒm£·Po¯ªó&a˜ºwoÏçeÁû1wiëïþ‡«ýN€'WqÏý¡¿çHòm4à®ó3+}Ò5ž(Š?4Úvv“ƒ0Rµ+þ²o†_¾¾ñŠ£}NŒ˜fœv•REìV€l³EB¡4­~äH[(wR£ÏEu+« ÎOÔ÷æ«tæ;B©øOGyüߘø¶.FdGIª¨[™˜ãÖäÈÁ"ªŒÏI_ÎÈàÜúj€ÚÖé³Å4ÄXLʽæöüd¾ÚpóØjë&bSt©œµ‹šƒFôüòJ* Á¾™™³ Á³ÍËl6Õ´?ò¦ äý·2—!âÀ/–Ñ^­qO_Øy‚ªªv¯w¬»á3nwOžÖzlÈŠÈ–÷W–…ifžÇªèÜ`¤PaÞ|ê<‚Î^½¥|¤ìµ $37¢{5ÕJ£&5Ű˜0—V×ùïxrÚñÆX8ßã¾€hl¦ãý¢=–°YãèméÞ©Ð0œëÚ²Ùr§dòÒ\åc…0KIz‹_¿d]]t£Çàä’´rÒcºgèau™%O%HÐ…gÛË\3qûЊ¡VØaÄj݇‰°(c«²±ýŽà5Ôô‚iLH´)Ék¸^q_éÀýý"«þ¿¹­xl/ç.ï*N]íßü?ZÖúCB[VŸÎ¢’y¾ÏNî÷y—öv’ò–Ò¢™çoÇ] ʹØìÐýgpüù·¢1þí˯/¹úZcžƒâ‡ÉF»Å+Ÿ­Ûßã³™YsêÞwÿm³¾žÖ[´ÆÍÇPçhm”ËwmSÓë;=‹8¥÷Nzn ›àÀª—’ü.éåÙƒâ‚ö[~½­«ÌÛ_ü?$¾7Øàõẇû#ëÜÞ-+vÝß‘õn‚ÿÆ¿]é^ÓÿÅEm]ò;hÇ–þ-L_¦(}eí7p;ovF÷¸ÜûCm.î}?¿íºÃq7åëò'-c•güòa§wuÏív¯yR_îrÜšõŠSü®ìÚèã¯S¶­qùö•5žºËZÓn±ñ,appÜ.ôï€[Ìq–$Õ/:¡G¦ú—ÎS\x¥ï“¥fôIߪ3+—Ýâçû“ðs¡hZùã_-'ö¬¨¸ÄÖ×òΓmMezýîWÌ»O.ùU·n§G–Ô˳Usc wÌ~´jób»Ž‰ÉѦ_˜7ÖUë…ö74–´X”>Ü=ýzÁý3Ïo’49Ç$h·Ñ6J{Õ‹Î|÷—S‚õ™&MÛ3i“«KÑ%íï½Ï÷­Wg—P>êæ_û WLÒ æ@”}¢È›¥›ïoÈøyâÛþR“ÖÉÝ]¢/Å­ÓkOœp}…ë‹Moë_Ý[7a?“ʶ¹‹?î÷á={êšÙªÝ¢J­¬>ÿ´ó9;ï’‰rÛÿÄKVûirX|­"þòo±Qõžb~‚V‡Šžuªi;4í6³Y}qæ{•éŸÜ/žâ*ÔÛõN’'ì‘ß™÷‘R‰sdçÜæùÿÅ‚7ˆó¡Þ§B_¬“Òü¿6$–ÜW“o)Ô³¾®0Ûݤ[ÍIíÐVÞD«ä_Ï7-Q5yù–ë¾É~oÿƒ¯ç/?à5QÐX¹Â\¥¬îè´’šäê~=ÓâŸÈ§MVX5¥r‹§(SOº|¼AÜSñ=›¥­±;™÷èqÓMÖk×3'ÌwÙyŽý¹E­ND•ù¿‹ÓCÙY«‚ü3,Ïξ¢Vù#úñåo_7a‘õRÏ=Å=‡Ìþ??²õ÷ªF#í>rÙ¢Ë×¾‰î0J~»9÷íVã.éuË¿ò8-¬ú÷¹$ßFå¦êòå“_y_¿}!k[Õ{3çK3Øn,<1[wÏîé^“> endobj 12 0 obj << /Ascent 708 /CapHeight 672 /Descent -266 /FontName /LABRPI+URWPalladioL-Bold /ItalicAngle 0 /StemV 123 /XHeight 471 /FontBBox [-152 -301 1000 935] /Flags 4 /CharSet (/hyphen/period/zero/one/two/three/four/five/six/seven/eight/nine/B/C/D/E/F/I/L/N/P/R/S/T/V/Y/a/c/d/e/f/g/h/i/k/l/n/o/r/s/t/u/w/x/y) /FontFile 13 0 R >> endobj 60 0 obj [333 250 0 500 500 500 500 500 500 500 500 500 500 0 0 0 0 0 0 0 0 667 722 833 611 556 0 0 389 0 0 611 0 833 0 611 0 722 611 667 0 778 0 0 667 0 0 0 0 0 0 0 500 0 444 611 500 389 556 611 333 0 611 333 0 611 556 0 0 389 444 333 611 0 833 500 556 ] endobj 39 0 obj << /Type /Pages /Count 2 /Kids [6 0 R 41 0 R] >> endobj 61 0 obj << /Names [(Doc-Start) 10 0 R (end_of_life) 47 0 R (id2464483) 15 0 R (page.1) 9 0 R (page.2) 43 0 R (relnotes_bugs) 45 0 R (relnotes_changes) 38 0 R (relnotes_download) 22 0 R (relnotes_features) 36 0 R (relnotes_intro) 17 0 R (relnotes_security) 31 0 R (relnotes_thanks) 50 0 R (section.1) 11 0 R (subsection.1.1) 16 0 R (subsection.1.2) 21 0 R (subsection.1.3) 30 0 R (subsection.1.4) 35 0 R (subsection.1.5) 37 0 R (subsection.1.6) 44 0 R (subsection.1.7) 46 0 R (subsection.1.8) 49 0 R] /Limits [(Doc-Start) (subsection.1.8)] >> endobj 62 0 obj << /Kids [61 0 R] >> endobj 63 0 obj << /Dests 62 0 R >> endobj 64 0 obj << /Type /Catalog /Pages 39 0 R /Names 63 0 R /PageMode /UseOutlines /OpenAction 5 0 R >> endobj 65 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfeTeX-1.21a)/Keywords() /CreationDate (D:20160228232822Z) /PTEX.Fullbanner (This is pdfeTeX, Version 3.141592-1.21a-2.2 (Web2C 7.5.4) kpathsea version 3.5.4) >> endobj xref 0 66 0000000001 65535 f 0000000002 00000 f 0000000003 00000 f 0000000004 00000 f 0000000000 00000 f 0000000009 00000 n 0000002310 00000 n 0000003461 00000 n 0000000058 00000 n 0000002624 00000 n 0000002683 00000 n 0000002743 00000 n 0000063201 00000 n 0000045170 00000 n 0000063032 00000 n 0000002803 00000 n 0000002863 00000 n 0000002923 00000 n 0000044341 00000 n 0000021693 00000 n 0000044173 00000 n 0000002983 00000 n 0000003042 00000 n 0000021346 00000 n 0000019358 00000 n 0000021189 00000 n 0000002444 00000 n 0000018877 00000 n 0000009447 00000 n 0000018710 00000 n 0000003102 00000 n 0000003162 00000 n 0000007244 00000 n 0000005859 00000 n 0000007087 00000 n 0000003222 00000 n 0000003282 00000 n 0000003342 00000 n 0000003401 00000 n 0000063801 00000 n 0000005741 00000 n 0000004607 00000 n 0000003578 00000 n 0000005314 00000 n 0000005375 00000 n 0000005436 00000 n 0000005497 00000 n 0000005558 00000 n 0000004758 00000 n 0000005619 00000 n 0000005680 00000 n 0000004963 00000 n 0000005139 00000 n 0000007474 00000 n 0000007451 00000 n 0000007560 00000 n 0000019141 00000 n 0000021587 00000 n 0000021558 00000 n 0000044776 00000 n 0000063538 00000 n 0000063866 00000 n 0000064416 00000 n 0000064453 00000 n 0000064489 00000 n 0000064596 00000 n trailer << /Size 66 /Root 64 0 R /Info 65 0 R /ID [<8D03CD0FFC6CF74826E115F9B2541EE1> <8D03CD0FFC6CF74826E115F9B2541EE1>] >> startxref 64852 %%EOF bind9-9.10.3.dfsg.P4/doc/arm/man.dnssec-verify.html0000644000470500017500000001731512664710322021145 0ustar lamontlamont dnssec-verify

Name

dnssec-verify — DNSSEC zone verification tool

Synopsis

dnssec-verify [-c class] [-E engine] [-I input-format] [-o origin] [-v level] [-V] [-x] [-z] {zonefile}

DESCRIPTION

dnssec-verify verifies that a zone is fully signed for each algorithm found in the DNSKEY RRset for the zone, and that the NSEC / NSEC3 chains are complete.

OPTIONS

-c class

Specifies the DNS class of the zone.

-E engine

Specifies the cryptographic hardware to use, when applicable.

When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (--enable-native-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "--with-pkcs11".

-I input-format

The format of the input zone file. Possible formats are "text" (default) and "raw". This option is primarily intended to be used for dynamic signed zones so that the dumped zone file in a non-text format containing updates can be verified independently. The use of this option does not make much sense for non-dynamic zones.

-o origin

The zone origin. If not specified, the name of the zone file is assumed to be the origin.

-v level

Sets the debugging level.

-V

Prints version information.

-x

Only verify that the DNSKEY RRset is signed with key-signing keys. Without this flag, it is assumed that the DNSKEY RRset will be signed by all active keys. When this flag is set, it will not be an error if the DNSKEY RRset is not signed by zone-signing keys. This corresponds to the -x option in dnssec-signzone.

-z

Ignore the KSK flag on the keys when determining whether the zone if correctly signed. Without this flag it is assumed that there will be a non-revoked, self-signed DNSKEY with the KSK flag set for each algorithm and that RRsets other than DNSKEY RRset will be signed with a different DNSKEY without the KSK flag set.

With this flag set, we only require that for each algorithm, there will be at least one non-revoked, self-signed DNSKEY, regardless of the KSK flag state, and that other RRsets will be signed by a non-revoked key for the same algorithm that includes the self-signed key; the same key may be used for both purposes. This corresponds to the -z option in dnssec-signzone.

zonefile

The file containing the zone to be signed.

SEE ALSO

dnssec-signzone(8), BIND 9 Administrator Reference Manual, RFC 4033.

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/man.dnssec-revoke.html0000644000470500017500000001357412664710322021137 0ustar lamontlamont dnssec-revoke

Name

dnssec-revoke — Set the REVOKED bit on a DNSSEC key

Synopsis

dnssec-revoke [-hr] [-v level] [-V] [-K directory] [-E engine] [-f] [-R] {keyfile}

DESCRIPTION

dnssec-revoke reads a DNSSEC key file, sets the REVOKED bit on the key as defined in RFC 5011, and creates a new pair of key files containing the now-revoked key.

OPTIONS

-h

Emit usage message and exit.

-K directory

Sets the directory in which the key files are to reside.

-r

After writing the new keyset files remove the original keyset files.

-v level

Sets the debugging level.

-V

Prints version information.

-E engine

Specifies the cryptographic hardware to use, when applicable.

When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (--enable-native-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "--with-pkcs11".

-f

Force overwrite: Causes dnssec-revoke to write the new key pair even if a file already exists matching the algorithm and key ID of the revoked key.

-R

Print the key tag of the key with the REVOKE bit set but do not revoke the key.

SEE ALSO

dnssec-keygen(8), BIND 9 Administrator Reference Manual, RFC 5011.

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/man.named.html0000644000470500017500000004241312664710322017445 0ustar lamontlamont named

Name

named — Internet domain name server

Synopsis

named [-4] [-6] [-c config-file] [-d debug-level] [-D string] [-E engine-name] [-f] [-g] [-M option] [-m flag] [-n #cpus] [-p port] [-s] [-S #max-socks] [-t directory] [-U #listeners] [-u user] [-v] [-V] [-x cache-file]

DESCRIPTION

named is a Domain Name System (DNS) server, part of the BIND 9 distribution from ISC. For more information on the DNS, see RFCs 1033, 1034, and 1035.

When invoked without arguments, named will read the default configuration file /etc/named.conf, read any initial data, and listen for queries.

OPTIONS

-4

Use IPv4 only even if the host machine is capable of IPv6. -4 and -6 are mutually exclusive.

-6

Use IPv6 only even if the host machine is capable of IPv4. -4 and -6 are mutually exclusive.

-c config-file

Use config-file as the configuration file instead of the default, /etc/named.conf. To ensure that reloading the configuration file continues to work after the server has changed its working directory due to to a possible directory option in the configuration file, config-file should be an absolute pathname.

-d debug-level

Set the daemon's debug level to debug-level. Debugging traces from named become more verbose as the debug level increases.

-D string

Specifies a string that is used to identify a instance of named in a process listing. The contents of string are not examined.

-E engine-name

When applicable, specifies the hardware to use for cryptographic operations, such as a secure key store used for signing.

When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (--enable-native-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "--with-pkcs11".

-f

Run the server in the foreground (i.e. do not daemonize).

-g

Run the server in the foreground and force all logging to stderr.

-M option

Sets the default memory context options. Currently the only supported option is external, which causes the internal memory manager to be bypassed in favor of system-provided memory allocation functions.

-m flag

Turn on memory usage debugging flags. Possible flags are usage, trace, record, size, and mctx. These correspond to the ISC_MEM_DEBUGXXXX flags described in <isc/mem.h>.

-n #cpus

Create #cpus worker threads to take advantage of multiple CPUs. If not specified, named will try to determine the number of CPUs present and create one thread per CPU. If it is unable to determine the number of CPUs, a single worker thread will be created.

-p port

Listen for queries on port port. If not specified, the default is port 53.

-s

Write memory usage statistics to stdout on exit.

Note

This option is mainly of interest to BIND 9 developers and may be removed or changed in a future release.

-S #max-socks

Allow named to use up to #max-socks sockets. The default value is 4096 on systems built with default configuration options, and 21000 on systems built with "configure --with-tuning=large".

Warning

This option should be unnecessary for the vast majority of users. The use of this option could even be harmful because the specified value may exceed the limitation of the underlying system API. It is therefore set only when the default configuration causes exhaustion of file descriptors and the operational environment is known to support the specified number of sockets. Note also that the actual maximum number is normally a little fewer than the specified value because named reserves some file descriptors for its internal use.

-t directory

Chroot to directory after processing the command line arguments, but before reading the configuration file.

Warning

This option should be used in conjunction with the -u option, as chrooting a process running as root doesn't enhance security on most systems; the way chroot(2) is defined allows a process with root privileges to escape a chroot jail.

-U #listeners

Use #listeners worker threads to listen for incoming UDP packets on each address. If not specified, named will calculate a default value based on the number of detected CPUs: 1 for 1 CPU, 2 for 2-4 CPUs, and the number of detected CPUs divided by 2 for values higher than 4. If -n has been set to a higher value than the number of detected CPUs, then -U may be increased as high as that value, but no higher.

-u user

Setuid to user after completing privileged operations, such as creating sockets that listen on privileged ports.

Note

On Linux, named uses the kernel's capability mechanism to drop all root privileges except the ability to bind(2) to a privileged port and set process resource limits. Unfortunately, this means that the -u option only works when named is run on kernel 2.2.18 or later, or kernel 2.3.99-pre3 or later, since previous kernels did not allow privileges to be retained after setuid(2).

-v

Report the version number and exit.

-V

Report the version number and build options, and exit.

-x cache-file

Load data from cache-file into the cache of the default view.

Warning

This option must not be used. It is only of interest to BIND 9 developers and may be removed or changed in a future release.

SIGNALS

In routine operation, signals should not be used to control the nameserver; rndc should be used instead.

SIGHUP

Force a reload of the server.

SIGINT, SIGTERM

Shut down the server.

The result of sending any other signals to the server is undefined.

CONFIGURATION

The named configuration file is too complex to describe in detail here. A complete description is provided in the BIND 9 Administrator Reference Manual.

named inherits the umask (file creation mode mask) from the parent process. If files created by named, such as journal files, need to have custom permissions, the umask should be set explicitly in the script used to start the named process.

FILES

/etc/named.conf

The default configuration file.

/var/run/named/named.pid

The default process-id file.

SEE ALSO

RFC 1033, RFC 1034, RFC 1035, named-checkconf(8), named-checkzone(8), rndc(8), lwresd(8), named.conf(5), BIND 9 Administrator Reference Manual.

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/managed-keys.xml0000644000470500017500000001213112664710322020002 0ustar lamontlamont Dynamic Trust Anchor Management BIND 9.7.0 introduces support for RFC 5011, dynamic trust anchor management. Using this feature allows named to keep track of changes to critical DNSSEC keys without any need for the operator to make changes to configuration files. Validating Resolver To configure a validating resolver to use RFC 5011 to maintain a trust anchor, configure the trust anchor using a managed-keys statement. Information about this can be found in . Authoritative Server To set up an authoritative zone for RFC 5011 trust anchor maintenance, generate two (or more) key signing keys (KSKs) for the zone. Sign the zone with one of them; this is the "active" KSK. All KSK's which do not sign the zone are "stand-by" keys. Any validating resolver which is configured to use the active KSK as an RFC 5011-managed trust anchor will take note of the stand-by KSKs in the zone's DNSKEY RRset, and store them for future reference. The resolver will recheck the zone periodically, and after 30 days, if the new key is still there, then the key will be accepted by the resolver as a valid trust anchor for the zone. Any time after this 30-day acceptance timer has completed, the active KSK can be revoked, and the zone can be "rolled over" to the newly accepted key. The easiest way to place a stand-by key in a zone is to use the "smart signing" features of dnssec-keygen and dnssec-signzone. If a key with a publication date in the past, but an activation date which is unset or in the future, " dnssec-signzone -S" will include the DNSKEY record in the zone, but will not sign with it: $ dnssec-keygen -K keys -f KSK -P now -A now+2y example.net $ dnssec-signzone -S -K keys example.net To revoke a key, the new command dnssec-revoke has been added. This adds the REVOKED bit to the key flags and re-generates the K*.key and K*.private files. After revoking the active key, the zone must be signed with both the revoked KSK and the new active KSK. (Smart signing takes care of this automatically.) Once a key has been revoked and used to sign the DNSKEY RRset in which it appears, that key will never again be accepted as a valid trust anchor by the resolver. However, validation can proceed using the new active key (which had been accepted by the resolver when it was a stand-by key). See RFC 5011 for more details on key rollover scenarios. When a key has been revoked, its key ID changes, increasing by 128, and wrapping around at 65535. So, for example, the key "Kexample.com.+005+10000" becomes "Kexample.com.+005+10128". If two keys have ID's exactly 128 apart, and one is revoked, then the two key ID's will collide, causing several problems. To prevent this, dnssec-keygen will not generate a new key if another key is present which may collide. This checking will only occur if the new keys are written to the same directory which holds all other keys in use for that zone. Older versions of BIND 9 did not have this precaution. Exercise caution if using key revocation on keys that were generated by previous releases, or if using keys stored in multiple directories or on multiple machines. It is expected that a future release of BIND 9 will address this problem in a different way, by storing revoked keys with their original unrevoked key ID's. bind9-9.10.3.dfsg.P4/doc/arm/man.dig.html0000644000470500017500000010771012664710322017126 0ustar lamontlamont dig

Name

dig — DNS lookup utility

Synopsis

dig [@server] [-b address] [-c class] [-f filename] [-k filename] [-m] [-p port#] [-q name] [-t type] [-v] [-x addr] [-y [hmac:]name:key] [-4] [-6] [name] [type] [class] [queryopt...]

dig [-h]

dig [global-queryopt...] [query...]

DESCRIPTION

dig (domain information groper) is a flexible tool for interrogating DNS name servers. It performs DNS lookups and displays the answers that are returned from the name server(s) that were queried. Most DNS administrators use dig to troubleshoot DNS problems because of its flexibility, ease of use and clarity of output. Other lookup tools tend to have less functionality than dig.

Although dig is normally used with command-line arguments, it also has a batch mode of operation for reading lookup requests from a file. A brief summary of its command-line arguments and options is printed when the -h option is given. Unlike earlier versions, the BIND 9 implementation of dig allows multiple lookups to be issued from the command line.

Unless it is told to query a specific name server, dig will try each of the servers listed in /etc/resolv.conf. If no usable server addresses are found, dig will send the query to the local host.

When no command line arguments or options are given, dig will perform an NS query for "." (the root).

It is possible to set per-user defaults for dig via ${HOME}/.digrc. This file is read and any options in it are applied before the command line arguments.

The IN and CH class names overlap with the IN and CH top level domain names. Either use the -t and -c options to specify the type and class, use the -q the specify the domain name, or use "IN." and "CH." when looking up these top level domains.

SIMPLE USAGE

A typical invocation of dig looks like:

 dig @server name type 

where:

server

is the name or IP address of the name server to query. This can be an IPv4 address in dotted-decimal notation or an IPv6 address in colon-delimited notation. When the supplied server argument is a hostname, dig resolves that name before querying that name server.

If no server argument is provided, dig consults /etc/resolv.conf; if an address is found there, it queries the name server at that address. If either of the -4 or -6 options are in use, then only addresses for the corresponding transport will be tried. If no usable addresses are found, dig will send the query to the local host. The reply from the name server that responds is displayed.

name

is the name of the resource record that is to be looked up.

type

indicates what type of query is required — ANY, A, MX, SIG, etc. type can be any valid query type. If no type argument is supplied, dig will perform a lookup for an A record.

OPTIONS

-4

Use IPv4 only.

-6

Use IPv6 only.

-b address[#port]

Set the source IP address of the query. The address must be a valid address on one of the host's network interfaces, or "0.0.0.0" or "::". An optional port may be specified by appending "#<port>"

-c class

Set the query class. The default class is IN; other classes are HS for Hesiod records or CH for Chaosnet records.

-f file

Batch mode: dig reads a list of lookup requests to process from the given file. Each line in the file should be organized in the same way they would be presented as queries to dig using the command-line interface.

-i

Do reverse IPv6 lookups using the obsolete RFC1886 IP6.INT domain, which is no longer in use. Obsolete bit string label queries (RFC2874) are not attempted.

-k keyfile

Sign queries using TSIG using a key read from the given file. Key files can be generated using tsig-keygen(8). When using TSIG authentication with dig, the name server that is queried needs to know the key and algorithm that is being used. In BIND, this is done by providing appropriate key and server statements in named.conf.

-m

Enable memory usage debugging.

-p port

Send the query to a non-standard port on the server, instead of the defaut port 53. This option would be used to test a name server that has been configured to listen for queries on a non-standard port number.

-q name

The domain name to query. This is useful to distinguish the name from other arguments.

-t type

The resource record type to query. It can be any valid query type which is supported in BIND 9. The default query type is "A", unless the -x option is supplied to indicate a reverse lookup. A zone transfer can be requested by specifying a type of AXFR. When an incremental zone transfer (IXFR) is required, set the type to ixfr=N. The incremental zone transfer will contain the changes made to the zone since the serial number in the zone's SOA record was N.

-v

Print the version number and exit.

-x addr

Simplified reverse lookups, for mapping addresses to names. The addr is an IPv4 address in dotted-decimal notation, or a colon-delimited IPv6 address. When the -x is used, there is no need to provide the name, class and type arguments. dig automatically performs a lookup for a name like 94.2.0.192.in-addr.arpa and sets the query type and class to PTR and IN respectively. IPv6 addresses are looked up using nibble format under the IP6.ARPA domain (but see also the -i option).

-y [hmac:]keyname:secret

Sign queries using TSIG with the given authentication key. keyname is the name of the key, and secret is the base64 encoded shared secret. hmac is the name of the key algorithm; valid choices are hmac-md5, hmac-sha1, hmac-sha224, hmac-sha256, hmac-sha384, or hmac-sha512. If hmac is not specified, the default is hmac-md5.

NOTE: You should use the -k option and avoid the -y option, because with -y the shared secret is supplied as a command line argument in clear text. This may be visible in the output from ps(1) or in a history file maintained by the user's shell.

QUERY OPTIONS

dig provides a number of query options which affect the way in which lookups are made and the results displayed. Some of these set or reset flag bits in the query header, some determine which sections of the answer get printed, and others determine the timeout and retry strategies.

Each query option is identified by a keyword preceded by a plus sign (+). Some keywords set or reset an option. These may be preceded by the string no to negate the meaning of that keyword. Other keywords assign values to options like the timeout interval. They have the form +keyword=value. Keywords may be abbreviated, provided the abbreviation is unambiguous; for example, +cd is equivalent to +cdflag. The query options are:

+[no]aaflag

A synonym for +[no]aaonly.

+[no]aaonly

Sets the "aa" flag in the query.

+[no]additional

Display [do not display] the additional section of a reply. The default is to display it.

+[no]adflag

Set [do not set] the AD (authentic data) bit in the query. This requests the server to return whether all of the answer and authority sections have all been validated as secure according to the security policy of the server. AD=1 indicates that all records have been validated as secure and the answer is not from a OPT-OUT range. AD=0 indicate that some part of the answer was insecure or not validated. This bit is set by default.

+[no]all

Set or clear all display flags.

+[no]answer

Display [do not display] the answer section of a reply. The default is to display it.

+[no]authority

Display [do not display] the authority section of a reply. The default is to display it.

+[no]besteffort

Attempt to display the contents of messages which are malformed. The default is to not display malformed answers.

+bufsize=B

Set the UDP message buffer size advertised using EDNS0 to B bytes. The maximum and minimum sizes of this buffer are 65535 and 0 respectively. Values outside this range are rounded up or down appropriately. Values other than zero will cause a EDNS query to be sent.

+[no]cdflag

Set [do not set] the CD (checking disabled) bit in the query. This requests the server to not perform DNSSEC validation of responses.

+[no]class

Display [do not display] the CLASS when printing the record.

+[no]cmd

Toggles the printing of the initial comment in the output identifying the version of dig and the query options that have been applied. This comment is printed by default.

+[no]comments

Toggle the display of comment lines in the output. The default is to print comments.

+[no]crypto

Toggle the display of cryptographic fields in DNSSEC records. The contents of these field are unnecessary to debug most DNSSEC validation failures and removing them makes it easier to see the common failures. The default is to display the fields. When omitted they are replaced by the string "[omitted]" or in the DNSKEY case the key id is displayed as the replacement, e.g. "[ key id = value ]".

+[no]defname

Deprecated, treated as a synonym for +[no]search

+[no]dnssec

Requests DNSSEC records be sent by setting the DNSSEC OK bit (DO) in the OPT record in the additional section of the query.

+domain=somename

Set the search list to contain the single domain somename, as if specified in a domain directive in /etc/resolv.conf, and enable search list processing as if the +search option were given.

+[no]edns[=#]

Specify the EDNS version to query with. Valid values are 0 to 255. Setting the EDNS version will cause a EDNS query to be sent. +noedns clears the remembered EDNS version. EDNS is set to 0 by default.

+[no]ednsflags[=#]

Set the must-be-zero EDNS flags bits (Z bits) to the specified value. Decimal, hex and octal encodings are accepted. Setting a named flag (e.g. DO) will silently be ignored. By default, no Z bits are set.

+[no]ednsnegotiation

Enable / disable EDNS version negotiation. By default EDNS version negotiation is enabled.

+[no]ednsopt[=code[:value]]

Specify EDNS option with code point code and optionally payload of value as a hexadecimal string. +noednsopt clears the EDNS options to to be sent.

+[no]expire

Send an EDNS Expire option.

+[no]fail

Do not try the next server if you receive a SERVFAIL. The default is to not try the next server which is the reverse of normal stub resolver behavior.

+[no]identify

Show [or do not show] the IP address and port number that supplied the answer when the +short option is enabled. If short form answers are requested, the default is not to show the source address and port number of the server that provided the answer.

+[no]ignore

Ignore truncation in UDP responses instead of retrying with TCP. By default, TCP retries are performed.

+[no]keepopen

Keep the TCP socket open between queries and reuse it rather than creating a new TCP socket for each lookup. The default is +nokeepopen.

+[no]multiline

Print records like the SOA records in a verbose multi-line format with human-readable comments. The default is to print each record on a single line, to facilitate machine parsing of the dig output.

+ndots=D

Set the number of dots that have to appear in name to D for it to be considered absolute. The default value is that defined using the ndots statement in /etc/resolv.conf, or 1 if no ndots statement is present. Names with fewer dots are interpreted as relative names and will be searched for in the domains listed in the search or domain directive in /etc/resolv.conf if +search is set.

+[no]nsid

Include an EDNS name server ID request when sending a query.

+[no]nssearch

When this option is set, dig attempts to find the authoritative name servers for the zone containing the name being looked up and display the SOA record that each name server has for the zone.

+[no]onesoa

Print only one (starting) SOA record when performing an AXFR. The default is to print both the starting and ending SOA records.

+[no]opcode=value

Set [restore] the DNS message opcode to the specified value. The default value is QUERY (0).

+[no]qr

Print [do not print] the query as it is sent. By default, the query is not printed.

+[no]question

Print [do not print] the question section of a query when an answer is returned. The default is to print the question section as a comment.

+[no]rdflag

A synonym for +[no]recurse.

+[no]recurse

Toggle the setting of the RD (recursion desired) bit in the query. This bit is set by default, which means dig normally sends recursive queries. Recursion is automatically disabled when the +nssearch or +trace query options are used.

+retry=T

Sets the number of times to retry UDP queries to server to T instead of the default, 2. Unlike +tries, this does not include the initial query.

+[no]rrcomments

Toggle the display of per-record comments in the output (for example, human-readable key information about DNSKEY records). The default is not to print record comments unless multiline mode is active.

+[no]search

Use [do not use] the search list defined by the searchlist or domain directive in resolv.conf (if any). The search list is not used by default.

'ndots' from resolv.conf (default 1) which may be overridden by +ndots determines if the name will be treated as relative or not and hence whether a search is eventually performed or not.

+[no]short

Provide a terse answer. The default is to print the answer in a verbose form.

+[no]showsearch

Perform [do not perform] a search showing intermediate results.

+[no]sigchase

Chase DNSSEC signature chains. Requires dig be compiled with -DDIG_SIGCHASE.

+[no]sit[=####]

Send a Source Identity Token EDNS option, with optional value. Replaying a SIT from a previous response will allow the server to identify a previous client. The default is +nosit. Currently using experimental value 65001 for the option code.

+split=W

Split long hex- or base64-formatted fields in resource records into chunks of W characters (where W is rounded up to the nearest multiple of 4). +nosplit or +split=0 causes fields not to be split at all. The default is 56 characters, or 44 characters when multiline mode is active.

+[no]stats

This query option toggles the printing of statistics: when the query was made, the size of the reply and so on. The default behavior is to print the query statistics.

+[no]subnet=addr/prefix

Send an EDNS Client Subnet option with the specified IP address or network prefix.

+[no]tcp

Use [do not use] TCP when querying name servers. The default behavior is to use UDP unless an ixfr=N query is requested, in which case the default is TCP. AXFR queries always use TCP.

+time=T

Sets the timeout for a query to T seconds. The default timeout is 5 seconds. An attempt to set T to less than 1 will result in a query timeout of 1 second being applied.

+[no]topdown

When chasing DNSSEC signature chains perform a top-down validation. Requires dig be compiled with -DDIG_SIGCHASE.

+[no]trace

Toggle tracing of the delegation path from the root name servers for the name being looked up. Tracing is disabled by default. When tracing is enabled, dig makes iterative queries to resolve the name being looked up. It will follow referrals from the root servers, showing the answer from each server that was used to resolve the lookup.

If @server is also specified, it affects only the initial query for the root zone name servers.

+dnssec is also set when +trace is set to better emulate the default queries from a nameserver.

+tries=T

Sets the number of times to try UDP queries to server to T instead of the default, 3. If T is less than or equal to zero, the number of tries is silently rounded up to 1.

+trusted-key=####

Specifies a file containing trusted keys to be used with +sigchase. Each DNSKEY record must be on its own line.

If not specified, dig will look for /etc/trusted-key.key then trusted-key.key in the current directory.

Requires dig be compiled with -DDIG_SIGCHASE.

+[no]ttlid

Display [do not display] the TTL when printing the record.

+[no]vc

Use [do not use] TCP when querying name servers. This alternate syntax to +[no]tcp is provided for backwards compatibility. The "vc" stands for "virtual circuit".

MULTIPLE QUERIES

The BIND 9 implementation of dig supports specifying multiple queries on the command line (in addition to supporting the -f batch file option). Each of those queries can be supplied with its own set of flags, options and query options.

In this case, each query argument represent an individual query in the command-line syntax described above. Each consists of any of the standard options and flags, the name to be looked up, an optional query type and class and any query options that should be applied to that query.

A global set of query options, which should be applied to all queries, can also be supplied. These global query options must precede the first tuple of name, class, type, options, flags, and query options supplied on the command line. Any global query options (except the +[no]cmd option) can be overridden by a query-specific set of query options. For example:

dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr

shows how dig could be used from the command line to make three lookups: an ANY query for www.isc.org, a reverse lookup of 127.0.0.1 and a query for the NS records of isc.org. A global query option of +qr is applied, so that dig shows the initial query it made for each lookup. The final query has a local query option of +noqr which means that dig will not print the initial query when it looks up the NS records for isc.org.

IDN SUPPORT

If dig has been built with IDN (internationalized domain name) support, it can accept and display non-ASCII domain names. dig appropriately converts character encoding of domain name before sending a request to DNS server or displaying a reply from the server. If you'd like to turn off the IDN support for some reason, defines the IDN_DISABLE environment variable. The IDN support is disabled if the variable is set when dig runs.

FILES

/etc/resolv.conf

${HOME}/.digrc

SEE ALSO

host(1), named(8), dnssec-keygen(8), RFC1035.

BUGS

There are probably too many query options.

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/Bv9ARM.ch04.html0000644000470500017500000033130512664710322017345 0ustar lamontlamont Chapter 4. Advanced DNS Features

Chapter 4. Advanced DNS Features

Notify

DNS NOTIFY is a mechanism that allows master servers to notify their slave servers of changes to a zone's data. In response to a NOTIFY from a master server, the slave will check to see that its version of the zone is the current version and, if not, initiate a zone transfer.

For more information about DNS NOTIFY, see the description of the notify option in the section called “Boolean Options” and the description of the zone option also-notify in the section called “Zone Transfers”. The NOTIFY protocol is specified in RFC 1996.

Note

As a slave zone can also be a master to other slaves, named, by default, sends NOTIFY messages for every zone it loads. Specifying notify master-only; will cause named to only send NOTIFY for master zones that it loads.

Dynamic Update

Dynamic Update is a method for adding, replacing or deleting records in a master server by sending it a special form of DNS messages. The format and meaning of these messages is specified in RFC 2136.

Dynamic update is enabled by including an allow-update or an update-policy clause in the zone statement.

If the zone's update-policy is set to local, updates to the zone will be permitted for the key local-ddns, which will be generated by named at startup. See the section called “Dynamic Update Policies” for more details.

Dynamic updates using Kerberos signed requests can be made using the TKEY/GSS protocol by setting either the tkey-gssapi-keytab option, or alternatively by setting both the tkey-gssapi-credential and tkey-domain options. Once enabled, Kerberos signed requests will be matched against the update policies for the zone, using the Kerberos principal as the signer for the request.

Updating of secure zones (zones using DNSSEC) follows RFC 3007: RRSIG, NSEC and NSEC3 records affected by updates are automatically regenerated by the server using an online zone key. Update authorization is based on transaction signatures and an explicit server policy.

The journal file

All changes made to a zone using dynamic update are stored in the zone's journal file. This file is automatically created by the server when the first dynamic update takes place. The name of the journal file is formed by appending the extension .jnl to the name of the corresponding zone file unless specifically overridden. The journal file is in a binary format and should not be edited manually.

The server will also occasionally write ("dump") the complete contents of the updated zone to its zone file. This is not done immediately after each dynamic update, because that would be too slow when a large zone is updated frequently. Instead, the dump is delayed by up to 15 minutes, allowing additional updates to take place. During the dump process, transient files will be created with the extensions .jnw and .jbk; under ordinary circumstances, these will be removed when the dump is complete, and can be safely ignored.

When a server is restarted after a shutdown or crash, it will replay the journal file to incorporate into the zone any updates that took place after the last zone dump.

Changes that result from incoming incremental zone transfers are also journalled in a similar way.

The zone files of dynamic zones cannot normally be edited by hand because they are not guaranteed to contain the most recent dynamic changes — those are only in the journal file. The only way to ensure that the zone file of a dynamic zone is up to date is to run rndc stop.

If you have to make changes to a dynamic zone manually, the following procedure will work: Disable dynamic updates to the zone using rndc freeze zone. This will update the zone's master file with the changes stored in its .jnl file. Edit the zone file. Run rndc thaw zone to reload the changed zone and re-enable dynamic updates.

rndc sync zone will update the zone file with changes from the journal file without stopping dynamic updates; this may be useful for viewing the current zone state. To remove the .jnl file after updating the zone file, use rndc sync -clean.

Incremental Zone Transfers (IXFR)

The incremental zone transfer (IXFR) protocol is a way for slave servers to transfer only changed data, instead of having to transfer the entire zone. The IXFR protocol is specified in RFC 1995. See Proposed Standards.

When acting as a master, BIND 9 supports IXFR for those zones where the necessary change history information is available. These include master zones maintained by dynamic update and slave zones whose data was obtained by IXFR. For manually maintained master zones, and for slave zones obtained by performing a full zone transfer (AXFR), IXFR is supported only if the option ixfr-from-differences is set to yes.

When acting as a slave, BIND 9 will attempt to use IXFR unless it is explicitly disabled. For more information about disabling IXFR, see the description of the request-ixfr clause of the server statement.

Split DNS

Setting up different views, or visibility, of the DNS space to internal and external resolvers is usually referred to as a Split DNS setup. There are several reasons an organization would want to set up its DNS this way.

One common reason for setting up a DNS system this way is to hide "internal" DNS information from "external" clients on the Internet. There is some debate as to whether or not this is actually useful. Internal DNS information leaks out in many ways (via email headers, for example) and most savvy "attackers" can find the information they need using other means. However, since listing addresses of internal servers that external clients cannot possibly reach can result in connection delays and other annoyances, an organization may choose to use a Split DNS to present a consistent view of itself to the outside world.

Another common reason for setting up a Split DNS system is to allow internal networks that are behind filters or in RFC 1918 space (reserved IP space, as documented in RFC 1918) to resolve DNS on the Internet. Split DNS can also be used to allow mail from outside back in to the internal network.

Example split DNS setup

Let's say a company named Example, Inc. (example.com) has several corporate sites that have an internal network with reserved Internet Protocol (IP) space and an external demilitarized zone (DMZ), or "outside" section of a network, that is available to the public.

Example, Inc. wants its internal clients to be able to resolve external hostnames and to exchange mail with people on the outside. The company also wants its internal resolvers to have access to certain internal-only zones that are not available at all outside of the internal network.

In order to accomplish this, the company will set up two sets of name servers. One set will be on the inside network (in the reserved IP space) and the other set will be on bastion hosts, which are "proxy" hosts that can talk to both sides of its network, in the DMZ.

The internal servers will be configured to forward all queries, except queries for site1.internal, site2.internal, site1.example.com, and site2.example.com, to the servers in the DMZ. These internal servers will have complete sets of information for site1.example.com, site2.example.com, site1.internal, and site2.internal.

To protect the site1.internal and site2.internal domains, the internal name servers must be configured to disallow all queries to these domains from any external hosts, including the bastion hosts.

The external servers, which are on the bastion hosts, will be configured to serve the "public" version of the site1 and site2.example.com zones. This could include things such as the host records for public servers (www.example.com and ftp.example.com), and mail exchange (MX) records (a.mx.example.com and b.mx.example.com).

In addition, the public site1 and site2.example.com zones should have special MX records that contain wildcard (`*') records pointing to the bastion hosts. This is needed because external mail servers do not have any other way of looking up how to deliver mail to those internal hosts. With the wildcard records, the mail will be delivered to the bastion host, which can then forward it on to internal hosts.

Here's an example of a wildcard MX record:

*   IN MX 10 external1.example.com.

Now that they accept mail on behalf of anything in the internal network, the bastion hosts will need to know how to deliver mail to internal hosts. In order for this to work properly, the resolvers on the bastion hosts will need to be configured to point to the internal name servers for DNS resolution.

Queries for internal hostnames will be answered by the internal servers, and queries for external hostnames will be forwarded back out to the DNS servers on the bastion hosts.

In order for all this to work properly, internal clients will need to be configured to query only the internal name servers for DNS queries. This could also be enforced via selective filtering on the network.

If everything has been set properly, Example, Inc.'s internal clients will now be able to:

  • Look up any hostnames in the site1 and site2.example.com zones.
  • Look up any hostnames in the site1.internal and site2.internal domains.
  • Look up any hostnames on the Internet.
  • Exchange mail with both internal and external people.

Hosts on the Internet will be able to:

  • Look up any hostnames in the site1 and site2.example.com zones.
  • Exchange mail with anyone in the site1 and site2.example.com zones.

Here is an example configuration for the setup we just described above. Note that this is only configuration information; for information on how to configure your zone files, see the section called “Sample Configurations”.

Internal DNS server config:


acl internals { 172.16.72.0/24; 192.168.1.0/24; };

acl externals { bastion-ips-go-here; };

options {
    ...
    ...
    forward only;
    // forward to external servers
    forwarders {
        bastion-ips-go-here;
    };
    // sample allow-transfer (no one)
    allow-transfer { none; };
    // restrict query access
    allow-query { internals; externals; };
    // restrict recursion
    allow-recursion { internals; };
    ...
    ...
};

// sample master zone
zone "site1.example.com" {
  type master;
  file "m/site1.example.com";
  // do normal iterative resolution (do not forward)
  forwarders { };
  allow-query { internals; externals; };
  allow-transfer { internals; };
};

// sample slave zone
zone "site2.example.com" {
  type slave;
  file "s/site2.example.com";
  masters { 172.16.72.3; };
  forwarders { };
  allow-query { internals; externals; };
  allow-transfer { internals; };
};

zone "site1.internal" {
  type master;
  file "m/site1.internal";
  forwarders { };
  allow-query { internals; };
  allow-transfer { internals; }
};

zone "site2.internal" {
  type slave;
  file "s/site2.internal";
  masters { 172.16.72.3; };
  forwarders { };
  allow-query { internals };
  allow-transfer { internals; }
};

External (bastion host) DNS server config:

acl internals { 172.16.72.0/24; 192.168.1.0/24; };

acl externals { bastion-ips-go-here; };

options {
  ...
  ...
  // sample allow-transfer (no one)
  allow-transfer { none; };
  // default query access
  allow-query { any; };
  // restrict cache access
  allow-query-cache { internals; externals; };
  // restrict recursion
  allow-recursion { internals; externals; };
  ...
  ...
};

// sample slave zone
zone "site1.example.com" {
  type master;
  file "m/site1.foo.com";
  allow-transfer { internals; externals; };
};

zone "site2.example.com" {
  type slave;
  file "s/site2.foo.com";
  masters { another_bastion_host_maybe; };
  allow-transfer { internals; externals; }
};

In the resolv.conf (or equivalent) on the bastion host(s):

search ...
nameserver 172.16.72.2
nameserver 172.16.72.3
nameserver 172.16.72.4

TSIG

This is a short guide to setting up Transaction SIGnatures (TSIG) based transaction security in BIND. It describes changes to the configuration file as well as what changes are required for different features, including the process of creating transaction keys and using transaction signatures with BIND.

BIND primarily supports TSIG for server to server communication. This includes zone transfer, notify, and recursive query messages. Resolvers based on newer versions of BIND 8 have limited support for TSIG.

TSIG can also be useful for dynamic update. A primary server for a dynamic zone should control access to the dynamic update service, but IP-based access control is insufficient. The cryptographic access control provided by TSIG is far superior. The nsupdate program supports TSIG via the -k and -y command line options or inline by use of the key.

Generate Shared Keys for Each Pair of Hosts

A shared secret is generated to be shared between host1 and host2. An arbitrary key name is chosen: "host1-host2.". The key name must be the same on both hosts.

Automatic Generation

The following command will generate a 128-bit (16 byte) HMAC-SHA256 key as described above. Longer keys are better, but shorter keys are easier to read. Note that the maximum key length is the digest length, here 256 bits.

dnssec-keygen -a hmac-sha256 -b 128 -n HOST host1-host2.

The key is in the file Khost1-host2.+163+00000.private. Nothing directly uses this file, but the base-64 encoded string following "Key:" can be extracted from the file and used as a shared secret:

Key: La/E5CjG9O+os1jq0a2jdA==

The string "La/E5CjG9O+os1jq0a2jdA==" can be used as the shared secret.

Manual Generation

The shared secret is simply a random sequence of bits, encoded in base-64. Most ASCII strings are valid base-64 strings (assuming the length is a multiple of 4 and only valid characters are used), so the shared secret can be manually generated.

Also, a known string can be run through mmencode or a similar program to generate base-64 encoded data.

Copying the Shared Secret to Both Machines

This is beyond the scope of DNS. A secure transport mechanism should be used. This could be secure FTP, ssh, telephone, etc.

Informing the Servers of the Key's Existence

Imagine host1 and host 2 are both servers. The following is added to each server's named.conf file:

key host1-host2. {
  algorithm hmac-sha256;
  secret "La/E5CjG9O+os1jq0a2jdA==";
};

The secret is the one generated above. Since this is a secret, it is recommended that either named.conf be non-world readable, or the key directive be added to a non-world readable file that is included by named.conf.

At this point, the key is recognized. This means that if the server receives a message signed by this key, it can verify the signature. If the signature is successfully verified, the response is signed by the same key.

Instructing the Server to Use the Key

Since keys are shared between two hosts only, the server must be told when keys are to be used. The following is added to the named.conf file for host1, if the IP address of host2 is 10.1.2.3:

server 10.1.2.3 {
  keys { host1-host2. ;};
};

Multiple keys may be present, but only the first is used. This directive does not contain any secrets, so it may be in a world-readable file.

If host1 sends a message that is a request to that address, the message will be signed with the specified key. host1 will expect any responses to signed messages to be signed with the same key.

A similar statement must be present in host2's configuration file (with host1's address) for host2 to sign request messages to host1.

TSIG Key Based Access Control

BIND allows IP addresses and ranges to be specified in ACL definitions and allow-{ query | transfer | update } directives. This has been extended to allow TSIG keys also. The above key would be denoted key host1-host2.

An example of an allow-update directive would be:

allow-update { key host1-host2. ;};

This allows dynamic updates to succeed only if the request was signed by a key named "host1-host2.".

See the section called “Dynamic Update Policies” for a discussion of the more flexible update-policy statement.

Errors

The processing of TSIG signed messages can result in several errors. If a signed message is sent to a non-TSIG aware server, a FORMERR (format error) will be returned, since the server will not understand the record. This is a result of misconfiguration, since the server must be explicitly configured to send a TSIG signed message to a specific server.

If a TSIG aware server receives a message signed by an unknown key, the response will be unsigned with the TSIG extended error code set to BADKEY. If a TSIG aware server receives a message with a signature that does not validate, the response will be unsigned with the TSIG extended error code set to BADSIG. If a TSIG aware server receives a message with a time outside of the allowed range, the response will be signed with the TSIG extended error code set to BADTIME, and the time values will be adjusted so that the response can be successfully verified. In any of these cases, the message's rcode (response code) is set to NOTAUTH (not authenticated).

TKEY

TKEY is a mechanism for automatically generating a shared secret between two hosts. There are several "modes" of TKEY that specify how the key is generated or assigned. BIND 9 implements only one of these modes, the Diffie-Hellman key exchange. Both hosts are required to have a Diffie-Hellman KEY record (although this record is not required to be present in a zone). The TKEY process must use signed messages, signed either by TSIG or SIG(0). The result of TKEY is a shared secret that can be used to sign messages with TSIG. TKEY can also be used to delete shared secrets that it had previously generated.

The TKEY process is initiated by a client or server by sending a signed TKEY query (including any appropriate KEYs) to a TKEY-aware server. The server response, if it indicates success, will contain a TKEY record and any appropriate keys. After this exchange, both participants have enough information to determine the shared secret; the exact process depends on the TKEY mode. When using the Diffie-Hellman TKEY mode, Diffie-Hellman keys are exchanged, and the shared secret is derived by both participants.

SIG(0)

BIND 9 partially supports DNSSEC SIG(0) transaction signatures as specified in RFC 2535 and RFC 2931. SIG(0) uses public/private keys to authenticate messages. Access control is performed in the same manner as TSIG keys; privileges can be granted or denied based on the key name.

When a SIG(0) signed message is received, it will only be verified if the key is known and trusted by the server; the server will not attempt to locate and/or validate the key.

SIG(0) signing of multiple-message TCP streams is not supported.

The only tool shipped with BIND 9 that generates SIG(0) signed messages is nsupdate.

DNSSEC

Cryptographic authentication of DNS information is possible through the DNS Security (DNSSEC-bis) extensions, defined in RFC 4033, RFC 4034, and RFC 4035. This section describes the creation and use of DNSSEC signed zones.

In order to set up a DNSSEC secure zone, there are a series of steps which must be followed. BIND 9 ships with several tools that are used in this process, which are explained in more detail below. In all cases, the -h option prints a full list of parameters. Note that the DNSSEC tools require the keyset files to be in the working directory or the directory specified by the -d option, and that the tools shipped with BIND 9.2.x and earlier are not compatible with the current ones.

There must also be communication with the administrators of the parent and/or child zone to transmit keys. A zone's security status must be indicated by the parent zone for a DNSSEC capable resolver to trust its data. This is done through the presence or absence of a DS record at the delegation point.

For other servers to trust data in this zone, they must either be statically configured with this zone's zone key or the zone key of another zone above this one in the DNS tree.

Generating Keys

The dnssec-keygen program is used to generate keys.

A secure zone must contain one or more zone keys. The zone keys will sign all other records in the zone, as well as the zone keys of any secure delegated zones. Zone keys must have the same name as the zone, a name type of ZONE, and must be usable for authentication. It is recommended that zone keys use a cryptographic algorithm designated as "mandatory to implement" by the IETF; currently the only one is RSASHA1.

The following command will generate a 768-bit RSASHA1 key for the child.example zone:

dnssec-keygen -a RSASHA1 -b 768 -n ZONE child.example.

Two output files will be produced: Kchild.example.+005+12345.key and Kchild.example.+005+12345.private (where 12345 is an example of a key tag). The key filenames contain the key name (child.example.), algorithm (3 is DSA, 1 is RSAMD5, 5 is RSASHA1, etc.), and the key tag (12345 in this case). The private key (in the .private file) is used to generate signatures, and the public key (in the .key file) is used for signature verification.

To generate another key with the same properties (but with a different key tag), repeat the above command.

The dnssec-keyfromlabel program is used to get a key pair from a crypto hardware and build the key files. Its usage is similar to dnssec-keygen.

The public keys should be inserted into the zone file by including the .key files using $INCLUDE statements.

Signing the Zone

The dnssec-signzone program is used to sign a zone.

Any keyset files corresponding to secure subzones should be present. The zone signer will generate NSEC, NSEC3 and RRSIG records for the zone, as well as DS for the child zones if '-g' is specified. If '-g' is not specified, then DS RRsets for the secure child zones need to be added manually.

The following command signs the zone, assuming it is in a file called zone.child.example. By default, all zone keys which have an available private key are used to generate signatures.

dnssec-signzone -o child.example zone.child.example

One output file is produced: zone.child.example.signed. This file should be referenced by named.conf as the input file for the zone.

dnssec-signzone will also produce a keyset and dsset files and optionally a dlvset file. These are used to provide the parent zone administrators with the DNSKEYs (or their corresponding DS records) that are the secure entry point to the zone.

Configuring Servers

To enable named to respond appropriately to DNS requests from DNSSEC aware clients, dnssec-enable must be set to yes. (This is the default setting.)

To enable named to validate answers from other servers, the dnssec-enable option must be set to yes, and the dnssec-validation options must be set to yes or auto.

If dnssec-validation is set to auto, then a default trust anchor for the DNS root zone will be used. If it is set to yes, however, then at least one trust anchor must be configured with a trusted-keys or managed-keys statement in named.conf, or DNSSEC validation will not occur. The default setting is yes.

trusted-keys are copies of DNSKEY RRs for zones that are used to form the first link in the cryptographic chain of trust. All keys listed in trusted-keys (and corresponding zones) are deemed to exist and only the listed keys will be used to validated the DNSKEY RRset that they are from.

managed-keys are trusted keys which are automatically kept up to date via RFC 5011 trust anchor maintenance.

trusted-keys and managed-keys are described in more detail later in this document.

Unlike BIND 8, BIND 9 does not verify signatures on load, so zone keys for authoritative zones do not need to be specified in the configuration file.

After DNSSEC gets established, a typical DNSSEC configuration will look something like the following. It has one or more public keys for the root. This allows answers from outside the organization to be validated. It will also have several keys for parts of the namespace the organization controls. These are here to ensure that named is immune to compromises in the DNSSEC components of the security of parent zones.

managed-keys {
        /* Root Key */
        "." initial-key 257 3 3 "BNY4wrWM1nCfJ+CXd0rVXyYmobt7sEEfK3clRbGaTwS
                                 JxrGkxJWoZu6I7PzJu/E9gx4UC1zGAHlXKdE4zYIpRh
                                 aBKnvcC2U9mZhkdUpd1Vso/HAdjNe8LmMlnzY3zy2Xy
                                 4klWOADTPzSv9eamj8V18PHGjBLaVtYvk/ln5ZApjYg
                                 hf+6fElrmLkdaz MQ2OCnACR817DF4BBa7UR/beDHyp
                                 5iWTXWSi6XmoJLbG9Scqc7l70KDqlvXR3M/lUUVRbke
                                 g1IPJSidmK3ZyCllh4XSKbje/45SKucHgnwU5jefMtq
                                 66gKodQj+MiA21AfUVe7u99WzTLzY3qlxDhxYQQ20FQ
                                 97S+LKUTpQcq27R7AT3/V5hRQxScINqwcz4jYqZD2fQ
                                 dgxbcDTClU0CRBdiieyLMNzXG3";
};

trusted-keys {
        /* Key for our organization's forward zone */
        example.com. 257 3 5 "AwEAAaxPMcR2x0HbQV4WeZB6oEDX+r0QM6
                              5KbhTjrW1ZaARmPhEZZe3Y9ifgEuq7vZ/z
                              GZUdEGNWy+JZzus0lUptwgjGwhUS1558Hb
                              4JKUbbOTcM8pwXlj0EiX3oDFVmjHO444gL
                              kBOUKUf/mC7HvfwYH/Be22GnClrinKJp1O
                              g4ywzO9WglMk7jbfW33gUKvirTHr25GL7S
                              TQUzBb5Usxt8lgnyTUHs1t3JwCY5hKZ6Cq
                              FxmAVZP20igTixin/1LcrgX/KMEGd/biuv
                              F4qJCyduieHukuY3H4XMAcR+xia2nIUPvm
                              /oyWR8BW/hWdzOvnSCThlHf3xiYleDbt/o
                              1OTQ09A0=";

        /* Key for our reverse zone. */
        2.0.192.IN-ADDRPA.NET. 257 3 5 "AQOnS4xn/IgOUpBPJ3bogzwc
                                       xOdNax071L18QqZnQQQAVVr+i
                                       LhGTnNGp3HoWQLUIzKrJVZ3zg
                                       gy3WwNT6kZo6c0tszYqbtvchm
                                       gQC8CzKojM/W16i6MG/eafGU3
                                       siaOdS0yOI6BgPsw+YZdzlYMa
                                       IJGf4M4dyoKIhzdZyQ2bYQrjy
                                       Q4LB0lC7aOnsMyYKHHYeRvPxj
                                       IQXmdqgOJGq+vsevG06zW+1xg
                                       YJh9rCIfnm1GX/KMgxLPG2vXT
                                       D/RnLX+D3T3UL7HJYHJhAZD5L
                                       59VvjSPsZJHeDCUyWYrvPZesZ
                                       DIRvhDD52SKvbheeTJUm6Ehkz
                                       ytNN2SN96QRk8j/iI8ib";
};

options {
        ...
        dnssec-enable yes;
        dnssec-validation yes;
};

Note

None of the keys listed in this example are valid. In particular, the root key is not valid.

When DNSSEC validation is enabled and properly configured, the resolver will reject any answers from signed, secure zones which fail to validate, and will return SERVFAIL to the client.

Responses may fail to validate for any of several reasons, including missing, expired, or invalid signatures, a key which does not match the DS RRset in the parent zone, or an insecure response from a zone which, according to its parent, should have been secure.

Note

When the validator receives a response from an unsigned zone that has a signed parent, it must confirm with the parent that the zone was intentionally left unsigned. It does this by verifying, via signed and validated NSEC/NSEC3 records, that the parent zone contains no DS records for the child.

If the validator can prove that the zone is insecure, then the response is accepted. However, if it cannot, then it must assume an insecure response to be a forgery; it rejects the response and logs an error.

The logged error reads "insecurity proof failed" and "got insecure response; parent indicates it should be secure". (Prior to BIND 9.7, the logged error was "not insecure". This referred to the zone, not the response.)

DNSSEC, Dynamic Zones, and Automatic Signing

As of BIND 9.7.0 it is possible to change a dynamic zone from insecure to signed and back again. A secure zone can use either NSEC or NSEC3 chains.

Converting from insecure to secure

Changing a zone from insecure to secure can be done in two ways: using a dynamic DNS update, or the auto-dnssec zone option.

For either method, you need to configure named so that it can see the K* files which contain the public and private parts of the keys that will be used to sign the zone. These files will have been generated by dnssec-keygen. You can do this by placing them in the key-directory, as specified in named.conf:

        zone example.net {
                type master;
                update-policy local;
                file "dynamic/example.net/example.net";
                key-directory "dynamic/example.net";
        };

If one KSK and one ZSK DNSKEY key have been generated, this configuration will cause all records in the zone to be signed with the ZSK, and the DNSKEY RRset to be signed with the KSK as well. An NSEC chain will be generated as part of the initial signing process.

Dynamic DNS update method

To insert the keys via dynamic update:

        % nsupdate
        > ttl 3600
        > update add example.net DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8=
        > update add example.net DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk=
        > send

While the update request will complete almost immediately, the zone will not be completely signed until named has had time to walk the zone and generate the NSEC and RRSIG records. The NSEC record at the apex will be added last, to signal that there is a complete NSEC chain.

If you wish to sign using NSEC3 instead of NSEC, you should add an NSEC3PARAM record to the initial update request. If you wish the NSEC3 chain to have the OPTOUT bit set, set it in the flags field of the NSEC3PARAM record.

        % nsupdate
        > ttl 3600
        > update add example.net DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8=
        > update add example.net DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk=
        > update add example.net NSEC3PARAM 1 1 100 1234567890
        > send

Again, this update request will complete almost immediately; however, the record won't show up until named has had a chance to build/remove the relevant chain. A private type record will be created to record the state of the operation (see below for more details), and will be removed once the operation completes.

While the initial signing and NSEC/NSEC3 chain generation is happening, other updates are possible as well.

Fully automatic zone signing

To enable automatic signing, add the auto-dnssec option to the zone statement in named.conf. auto-dnssec has two possible arguments: allow or maintain.

With auto-dnssec allow, named can search the key directory for keys matching the zone, insert them into the zone, and use them to sign the zone. It will do so only when it receives an rndc sign <zonename>.

auto-dnssec maintain includes the above functionality, but will also automatically adjust the zone's DNSKEY records on schedule according to the keys' timing metadata. (See dnssec-keygen(8) and dnssec-settime(8) for more information.)

named will periodically search the key directory for keys matching the zone, and if the keys' metadata indicates that any change should be made the zone, such as adding, removing, or revoking a key, then that action will be carried out. By default, the key directory is checked for changes every 60 minutes; this period can be adjusted with the dnssec-loadkeys-interval, up to a maximum of 24 hours. The rndc loadkeys forces named to check for key updates immediately.

If keys are present in the key directory the first time the zone is loaded, the zone will be signed immediately, without waiting for an rndc sign or rndc loadkeys command. (Those commands can still be used when there are unscheduled key changes, however.)

When new keys are added to a zone, the TTL is set to match that of any existing DNSKEY RRset. If there is no existing DNSKEY RRset, then the TTL will be set to the TTL specified when the key was created (using the dnssec-keygen -L option), if any, or to the SOA TTL.

If you wish the zone to be signed using NSEC3 instead of NSEC, submit an NSEC3PARAM record via dynamic update prior to the scheduled publication and activation of the keys. If you wish the NSEC3 chain to have the OPTOUT bit set, set it in the flags field of the NSEC3PARAM record. The NSEC3PARAM record will not appear in the zone immediately, but it will be stored for later reference. When the zone is signed and the NSEC3 chain is completed, the NSEC3PARAM record will appear in the zone.

Using the auto-dnssec option requires the zone to be configured to allow dynamic updates, by adding an allow-update or update-policy statement to the zone configuration. If this has not been done, the configuration will fail.

Private-type records

The state of the signing process is signaled by private-type records (with a default type value of 65534). When signing is complete, these records will have a nonzero value for the final octet (for those records which have a nonzero initial octet).

The private type record format: If the first octet is non-zero then the record indicates that the zone needs to be signed with the key matching the record, or that all signatures that match the record should be removed.



  algorithm (octet 1)
  key id in network order (octet 2 and 3)
  removal flag (octet 4)
  complete flag (octet 5)

Only records flagged as "complete" can be removed via dynamic update. Attempts to remove other private type records will be silently ignored.

If the first octet is zero (this is a reserved algorithm number that should never appear in a DNSKEY record) then the record indicates changes to the NSEC3 chains are in progress. The rest of the record contains an NSEC3PARAM record. The flag field tells what operation to perform based on the flag bits.



  0x01 OPTOUT
  0x80 CREATE
  0x40 REMOVE
  0x20 NONSEC

DNSKEY rollovers

As with insecure-to-secure conversions, rolling DNSSEC keys can be done in two ways: using a dynamic DNS update, or the auto-dnssec zone option.

Dynamic DNS update method

To perform key rollovers via dynamic update, you need to add the K* files for the new keys so that named can find them. You can then add the new DNSKEY RRs via dynamic update. named will then cause the zone to be signed with the new keys. When the signing is complete the private type records will be updated so that the last octet is non zero.

If this is for a KSK you need to inform the parent and any trust anchor repositories of the new KSK.

You should then wait for the maximum TTL in the zone before removing the old DNSKEY. If it is a KSK that is being updated, you also need to wait for the DS RRset in the parent to be updated and its TTL to expire. This ensures that all clients will be able to verify at least one signature when you remove the old DNSKEY.

The old DNSKEY can be removed via UPDATE. Take care to specify the correct key. named will clean out any signatures generated by the old key after the update completes.

Automatic key rollovers

When a new key reaches its activation date (as set by dnssec-keygen or dnssec-settime), if the auto-dnssec zone option is set to maintain, named will automatically carry out the key rollover. If the key's algorithm has not previously been used to sign the zone, then the zone will be fully signed as quickly as possible. However, if the new key is replacing an existing key of the same algorithm, then the zone will be re-signed incrementally, with signatures from the old key being replaced with signatures from the new key as their signature validity periods expire. By default, this rollover completes in 30 days, after which it will be safe to remove the old key from the DNSKEY RRset.

NSEC3PARAM rollovers via UPDATE

Add the new NSEC3PARAM record via dynamic update. When the new NSEC3 chain has been generated, the NSEC3PARAM flag field will be zero. At this point you can remove the old NSEC3PARAM record. The old chain will be removed after the update request completes.

Converting from NSEC to NSEC3

To do this, you just need to add an NSEC3PARAM record. When the conversion is complete, the NSEC chain will have been removed and the NSEC3PARAM record will have a zero flag field. The NSEC3 chain will be generated before the NSEC chain is destroyed.

Converting from NSEC3 to NSEC

To do this, use nsupdate to remove all NSEC3PARAM records with a zero flag field. The NSEC chain will be generated before the NSEC3 chain is removed.

Converting from secure to insecure

To convert a signed zone to unsigned using dynamic DNS, delete all the DNSKEY records from the zone apex using nsupdate. All signatures, NSEC or NSEC3 chains, and associated NSEC3PARAM records will be removed automatically. This will take place after the update request completes.

This requires the dnssec-secure-to-insecure option to be set to yes in named.conf.

In addition, if the auto-dnssec maintain zone statement is used, it should be removed or changed to allow instead (or it will re-sign).

Periodic re-signing

In any secure zone which supports dynamic updates, named will periodically re-sign RRsets which have not been re-signed as a result of some update action. The signature lifetimes will be adjusted so as to spread the re-sign load over time rather than all at once.

NSEC3 and OPTOUT

named only supports creating new NSEC3 chains where all the NSEC3 records in the zone have the same OPTOUT state. named supports UPDATES to zones where the NSEC3 records in the chain have mixed OPTOUT state. named does not support changing the OPTOUT state of an individual NSEC3 record, the entire chain needs to be changed if the OPTOUT state of an individual NSEC3 needs to be changed.

Dynamic Trust Anchor Management

BIND 9.7.0 introduces support for RFC 5011, dynamic trust anchor management. Using this feature allows named to keep track of changes to critical DNSSEC keys without any need for the operator to make changes to configuration files.

Validating Resolver

To configure a validating resolver to use RFC 5011 to maintain a trust anchor, configure the trust anchor using a managed-keys statement. Information about this can be found in the section called “managed-keys Statement Definition and Usage”.

Authoritative Server

To set up an authoritative zone for RFC 5011 trust anchor maintenance, generate two (or more) key signing keys (KSKs) for the zone. Sign the zone with one of them; this is the "active" KSK. All KSK's which do not sign the zone are "stand-by" keys.

Any validating resolver which is configured to use the active KSK as an RFC 5011-managed trust anchor will take note of the stand-by KSKs in the zone's DNSKEY RRset, and store them for future reference. The resolver will recheck the zone periodically, and after 30 days, if the new key is still there, then the key will be accepted by the resolver as a valid trust anchor for the zone. Any time after this 30-day acceptance timer has completed, the active KSK can be revoked, and the zone can be "rolled over" to the newly accepted key.

The easiest way to place a stand-by key in a zone is to use the "smart signing" features of dnssec-keygen and dnssec-signzone. If a key with a publication date in the past, but an activation date which is unset or in the future, " dnssec-signzone -S" will include the DNSKEY record in the zone, but will not sign with it:

$ dnssec-keygen -K keys -f KSK -P now -A now+2y example.net
$ dnssec-signzone -S -K keys example.net

To revoke a key, the new command dnssec-revoke has been added. This adds the REVOKED bit to the key flags and re-generates the K*.key and K*.private files.

After revoking the active key, the zone must be signed with both the revoked KSK and the new active KSK. (Smart signing takes care of this automatically.)

Once a key has been revoked and used to sign the DNSKEY RRset in which it appears, that key will never again be accepted as a valid trust anchor by the resolver. However, validation can proceed using the new active key (which had been accepted by the resolver when it was a stand-by key).

See RFC 5011 for more details on key rollover scenarios.

When a key has been revoked, its key ID changes, increasing by 128, and wrapping around at 65535. So, for example, the key "Kexample.com.+005+10000" becomes "Kexample.com.+005+10128".

If two keys have ID's exactly 128 apart, and one is revoked, then the two key ID's will collide, causing several problems. To prevent this, dnssec-keygen will not generate a new key if another key is present which may collide. This checking will only occur if the new keys are written to the same directory which holds all other keys in use for that zone.

Older versions of BIND 9 did not have this precaution. Exercise caution if using key revocation on keys that were generated by previous releases, or if using keys stored in multiple directories or on multiple machines.

It is expected that a future release of BIND 9 will address this problem in a different way, by storing revoked keys with their original unrevoked key ID's.

PKCS#11 (Cryptoki) support

PKCS#11 (Public Key Cryptography Standard #11) defines a platform-independent API for the control of hardware security modules (HSMs) and other cryptographic support devices.

BIND 9 is known to work with three HSMs: The AEP Keyper, which has been tested with Debian Linux, Solaris x86 and Windows Server 2003; the Thales nShield, tested with Debian Linux; and the Sun SCA 6000 cryptographic acceleration board, tested with Solaris x86. In addition, BIND can be used with all current versions of SoftHSM, a software-based HSM simulator library produced by the OpenDNSSEC project.

PKCS#11 makes use of a "provider library": a dynamically loadable library which provides a low-level PKCS#11 interface to drive the HSM hardware. The PKCS#11 provider library comes from the HSM vendor, and it is specific to the HSM to be controlled.

There are two available mechanisms for PKCS#11 support in BIND 9: OpenSSL-based PKCS#11 and native PKCS#11. When using the first mechanism, BIND uses a modified version of OpenSSL, which loads the provider library and operates the HSM indirectly; any cryptographic operations not supported by the HSM can be carried out by OpenSSL instead. The second mechanism enables BIND to bypass OpenSSL completely; BIND loads the provider library itself, and uses the PKCS#11 API to drive the HSM directly.

Prerequisites

See the documentation provided by your HSM vendor for information about installing, initializing, testing and troubleshooting the HSM.

Native PKCS#11

Native PKCS#11 mode will only work with an HSM capable of carrying out every cryptographic operation BIND 9 may need. The HSM's provider library must have a complete implementation of the PKCS#11 API, so that all these functions are accessible. As of this writing, only the Thales nShield HSM and SoftHSMv2 can be used in this fashion. For other HSMs, including the AEP Keyper, Sun SCA 6000 and older versions of SoftHSM, use OpenSSL-based PKCS#11. (Note: Eventually, when more HSMs become capable of supporting native PKCS#11, it is expected that OpenSSL-based PKCS#11 will be deprecated.)

To build BIND with native PKCS#11, configure as follows:

$ cd bind9
$ ./configure --enable-native-pkcs11 \
    --with-pkcs11=provider-library-path
    

This will cause all BIND tools, including named and the dnssec-* and pkcs11-* tools, to use the PKCS#11 provider library specified in provider-library-path for cryptography. (The provider library path can be overridden using the -E in named and the dnssec-* tools, or the -m in the pkcs11-* tools.)

Building SoftHSMv2

SoftHSMv2, the latest development version of SoftHSM, is available from https://github.com/opendnssec/SoftHSMv2 . It is a software library developed by the OpenDNSSEC project ( http://www.opendnssec.org ) which provides a PKCS#11 interface to a virtual HSM, implemented in the form of a SQLite3 database on the local filesystem. It provides less security than a true HSM, but it allows you to experiment with native PKCS#11 when an HSM is not available. SoftHSMv2 can be configured to use either OpenSSL or the Botan library to perform cryptographic functions, but when using it for native PKCS#11 in BIND, OpenSSL is required.

By default, the SoftHSMv2 configuration file is prefix/etc/softhsm2.conf (where prefix is configured at compile time). This location can be overridden by the SOFTHSM2_CONF environment variable. The SoftHSMv2 cryptographic store must be installed and initialized before using it with BIND.

$  cd SoftHSMv2 
$  configure --with-crypto-backend=openssl --prefix=/opt/pkcs11/usr --enable-gost 
$  make 
$  make install 
$  /opt/pkcs11/usr/bin/softhsm-util --init-token 0 --slot 0 --label softhsmv2 
      

OpenSSL-based PKCS#11

OpenSSL-based PKCS#11 mode uses a modified version of the OpenSSL library; stock OpenSSL does not fully support PKCS#11. ISC provides a patch to OpenSSL to correct this. This patch is based on work originally done by the OpenSolaris project; it has been modified by ISC to provide new features such as PIN management and key-by-reference.

There are two "flavors" of PKCS#11 support provided by the patched OpenSSL, one of which must be chosen at configuration time. The correct choice depends on the HSM hardware:

  • Use 'crypto-accelerator' with HSMs that have hardware cryptographic acceleration features, such as the SCA 6000 board. This causes OpenSSL to run all supported cryptographic operations in the HSM.

  • Use 'sign-only' with HSMs that are designed to function primarily as secure key storage devices, but lack hardware acceleration. These devices are highly secure, but are not necessarily any faster at cryptography than the system CPU — often, they are slower. It is therefore most efficient to use them only for those cryptographic functions that require access to the secured private key, such as zone signing, and to use the system CPU for all other computationally-intensive operations. The AEP Keyper is an example of such a device.

The modified OpenSSL code is included in the BIND 9 release, in the form of a context diff against the latest versions of OpenSSL. OpenSSL 0.9.8, 1.0.0, and 1.0.1 are supported; there are separate diffs for each version. In the examples to follow, we use OpenSSL 0.9.8, but the same methods work with OpenSSL 1.0.0 and 1.0.1.

Note

The latest OpenSSL versions as of this writing (January 2015) are 0.9.8zc, 1.0.0o, and 1.0.1j. ISC will provide updated patches as new versions of OpenSSL are released. The version number in the following examples is expected to change.

Before building BIND 9 with PKCS#11 support, it will be necessary to build OpenSSL with the patch in place, and configure it with the path to your HSM's PKCS#11 provider library.

Patching OpenSSL

$ wget http://www.openssl.org/source/openssl-0.9.8zc.tar.gz
  

Extract the tarball:

$ tar zxf openssl-0.9.8zc.tar.gz

Apply the patch from the BIND 9 release:

$ patch -p1 -d openssl-0.9.8zc \
	      < bind9/bin/pkcs11/openssl-0.9.8zc-patch

Note

Note that the patch file may not be compatible with the "patch" utility on all operating systems. You may need to install GNU patch.

When building OpenSSL, place it in a non-standard location so that it does not interfere with OpenSSL libraries elsewhere on the system. In the following examples, we choose to install into "/opt/pkcs11/usr". We will use this location when we configure BIND 9.

Later, when building BIND 9, the location of the custom-built OpenSSL library will need to be specified via configure.

Building OpenSSL for the AEP Keyper on Linux

The AEP Keyper is a highly secure key storage device, but does not provide hardware cryptographic acceleration. It can carry out cryptographic operations, but it is probably slower than your system's CPU. Therefore, we choose the 'sign-only' flavor when building OpenSSL.

The Keyper-specific PKCS#11 provider library is delivered with the Keyper software. In this example, we place it /opt/pkcs11/usr/lib:

$ cp pkcs11.GCC4.0.2.so.4.05 /opt/pkcs11/usr/lib/libpkcs11.so

This library is only available for Linux as a 32-bit binary. If we are compiling on a 64-bit Linux system, it is necessary to force a 32-bit build, by specifying -m32 in the build options.

Finally, the Keyper library requires threads, so we must specify -pthread.

$ cd openssl-0.9.8zc
$ ./Configure linux-generic32 -m32 -pthread \
	    --pk11-libname=/opt/pkcs11/usr/lib/libpkcs11.so \
	    --pk11-flavor=sign-only \
	    --prefix=/opt/pkcs11/usr

After configuring, run "make" and "make test". If "make test" fails with "pthread_atfork() not found", you forgot to add the -pthread above.

Building OpenSSL for the SCA 6000 on Solaris

The SCA-6000 PKCS#11 provider is installed as a system library, libpkcs11. It is a true crypto accelerator, up to 4 times faster than any CPU, so the flavor shall be 'crypto-accelerator'.

In this example, we are building on Solaris x86 on an AMD64 system.

$ cd openssl-0.9.8zc
$ ./Configure solaris64-x86_64-cc \
	    --pk11-libname=/usr/lib/64/libpkcs11.so \
	    --pk11-flavor=crypto-accelerator \
	    --prefix=/opt/pkcs11/usr

(For a 32-bit build, use "solaris-x86-cc" and /usr/lib/libpkcs11.so.)

After configuring, run make and make test.

Building OpenSSL for SoftHSM

SoftHSM (version 1) is a software library developed by the OpenDNSSEC project ( http://www.opendnssec.org ) which provides a PKCS#11 interface to a virtual HSM, implemented in the form of a SQLite3 database on the local filesystem. SoftHSM uses the Botan library to perform cryptographic functions. Though less secure than a true HSM, it can allow you to experiment with PKCS#11 when an HSM is not available.

The SoftHSM cryptographic store must be installed and initialized before using it with OpenSSL, and the SOFTHSM_CONF environment variable must always point to the SoftHSM configuration file:

$  cd softhsm-1.3.7 
$  configure --prefix=/opt/pkcs11/usr 
$  make 
$  make install 
$  export SOFTHSM_CONF=/opt/pkcs11/softhsm.conf 
$  echo "0:/opt/pkcs11/softhsm.db" > $SOFTHSM_CONF 
$  /opt/pkcs11/usr/bin/softhsm --init-token 0 --slot 0 --label softhsm 

SoftHSM can perform all cryptographic operations, but since it only uses your system CPU, there is no advantage to using it for anything but signing. Therefore, we choose the 'sign-only' flavor when building OpenSSL.

$ cd openssl-0.9.8zc
$ ./Configure linux-x86_64 -pthread \
	    --pk11-libname=/opt/pkcs11/usr/lib/libsofthsm.so \
	    --pk11-flavor=sign-only \
	    --prefix=/opt/pkcs11/usr

After configuring, run "make" and "make test".

Once you have built OpenSSL, run "apps/openssl engine pkcs11" to confirm that PKCS#11 support was compiled in correctly. The output should be one of the following lines, depending on the flavor selected:

	(pkcs11) PKCS #11 engine support (sign only)

Or:

	(pkcs11) PKCS #11 engine support (crypto accelerator)

Next, run "apps/openssl engine pkcs11 -t". This will attempt to initialize the PKCS#11 engine. If it is able to do so successfully, it will report “[ available ]”.

If the output is correct, run "make install" which will install the modified OpenSSL suite to /opt/pkcs11/usr.

Configuring BIND 9 for Linux with the AEP Keyper

To link with the PKCS#11 provider, threads must be enabled in the BIND 9 build.

The PKCS#11 library for the AEP Keyper is currently only available as a 32-bit binary. If we are building on a 64-bit host, we must force a 32-bit build by adding "-m32" to the CC options on the "configure" command line.

$ cd ../bind9
$ ./configure CC="gcc -m32" --enable-threads \
	   --with-openssl=/opt/pkcs11/usr \
	   --with-pkcs11=/opt/pkcs11/usr/lib/libpkcs11.so

Configuring BIND 9 for Solaris with the SCA 6000

To link with the PKCS#11 provider, threads must be enabled in the BIND 9 build.

$ cd ../bind9
$ ./configure CC="cc -xarch=amd64" --enable-threads \
	    --with-openssl=/opt/pkcs11/usr \
	    --with-pkcs11=/usr/lib/64/libpkcs11.so

(For a 32-bit build, omit CC="cc -xarch=amd64".)

If configure complains about OpenSSL not working, you may have a 32/64-bit architecture mismatch. Or, you may have incorrectly specified the path to OpenSSL (it should be the same as the --prefix argument to the OpenSSL Configure).

Configuring BIND 9 for SoftHSM

$ cd ../bind9
$ ./configure --enable-threads \
	   --with-openssl=/opt/pkcs11/usr \
	   --with-pkcs11=/opt/pkcs11/usr/lib/libsofthsm.so

After configuring, run "make", "make test" and "make install".

(Note: If "make test" fails in the "pkcs11" system test, you may have forgotten to set the SOFTHSM_CONF environment variable.)

PKCS#11 Tools

BIND 9 includes a minimal set of tools to operate the HSM, including pkcs11-keygen to generate a new key pair within the HSM, pkcs11-list to list objects currently available, pkcs11-destroy to remove objects, and pkcs11-tokens to list available tokens.

In UNIX/Linux builds, these tools are built only if BIND 9 is configured with the --with-pkcs11 option. (Note: If --with-pkcs11 is set to "yes", rather than to the path of the PKCS#11 provider, then the tools will be built but the provider will be left undefined. Use the -m option or the PKCS11_PROVIDER environment variable to specify the path to the provider.)

Using the HSM

For OpenSSL-based PKCS#11, we must first set up the runtime environment so the OpenSSL and PKCS#11 libraries can be loaded:

$ export LD_LIBRARY_PATH=/opt/pkcs11/usr/lib:${LD_LIBRARY_PATH}

This causes named and other binaries to load the OpenSSL library from /opt/pkcs11/usr/lib rather than from the default location. This step is not necessary when using native PKCS#11.

Some HSMs require other environment variables to be set. For example, when operating an AEP Keyper, it is necessary to specify the location of the "machine" file, which stores information about the Keyper for use by the provider library. If the machine file is in /opt/Keyper/PKCS11Provider/machine, use:

$ export KEYPER_LIBRARY_PATH=/opt/Keyper/PKCS11Provider

Such environment variables must be set whenever running any tool that uses the HSM, including pkcs11-keygen, pkcs11-list, pkcs11-destroy, dnssec-keyfromlabel, dnssec-signzone, dnssec-keygen, and named.

We can now create and use keys in the HSM. In this case, we will create a 2048 bit key and give it the label "sample-ksk":

$ pkcs11-keygen -b 2048 -l sample-ksk

To confirm that the key exists:

$ pkcs11-list
Enter PIN:
object[0]: handle 2147483658 class 3 label[8] 'sample-ksk' id[0]
object[1]: handle 2147483657 class 2 label[8] 'sample-ksk' id[0]

Before using this key to sign a zone, we must create a pair of BIND 9 key files. The "dnssec-keyfromlabel" utility does this. In this case, we will be using the HSM key "sample-ksk" as the key-signing key for "example.net":

$ dnssec-keyfromlabel -l sample-ksk -f KSK example.net

The resulting K*.key and K*.private files can now be used to sign the zone. Unlike normal K* files, which contain both public and private key data, these files will contain only the public key data, plus an identifier for the private key which remains stored within the HSM. Signing with the private key takes place inside the HSM.

If you wish to generate a second key in the HSM for use as a zone-signing key, follow the same procedure above, using a different keylabel, a smaller key size, and omitting "-f KSK" from the dnssec-keyfromlabel arguments:

(Note: When using OpenSSL-based PKCS#11 the label is an arbitrary string which identifies the key. With native PKCS#11, the label is a PKCS#11 URI string which may include other details about the key and the HSM, including its PIN. See dnssec-keyfromlabel(8) for details.)

$ pkcs11-keygen -b 1024 -l sample-zsk
$ dnssec-keyfromlabel -l sample-zsk example.net

Alternatively, you may prefer to generate a conventional on-disk key, using dnssec-keygen:

$ dnssec-keygen example.net

This provides less security than an HSM key, but since HSMs can be slow or cumbersome to use for security reasons, it may be more efficient to reserve HSM keys for use in the less frequent key-signing operation. The zone-signing key can be rolled more frequently, if you wish, to compensate for a reduction in key security. (Note: When using native PKCS#11, there is no speed advantage to using on-disk keys, as cryptographic operations will be done by the HSM regardless.)

Now you can sign the zone. (Note: If not using the -S option to dnssec-signzone, it will be necessary to add the contents of both K*.key files to the zone master file before signing it.)

$ dnssec-signzone -S example.net
Enter PIN:
Verifying the zone using the following algorithms:
NSEC3RSASHA1.
Zone signing complete:
Algorithm: NSEC3RSASHA1: ZSKs: 1, KSKs: 1 active, 0 revoked, 0 stand-by
example.net.signed

Specifying the engine on the command line

When using OpenSSL-based PKCS#11, the "engine" to be used by OpenSSL can be specified in named and all of the BIND dnssec-* tools by using the "-E <engine>" command line option. If BIND 9 is built with the --with-pkcs11 option, this option defaults to "pkcs11". Specifying the engine will generally not be necessary unless for some reason you wish to use a different OpenSSL engine.

If you wish to disable use of the "pkcs11" engine — for troubleshooting purposes, or because the HSM is unavailable — set the engine to the empty string. For example:

$ dnssec-signzone -E '' -S example.net

This causes dnssec-signzone to run as if it were compiled without the --with-pkcs11 option.

When built with native PKCS#11 mode, the "engine" option has a different meaning: it specifies the path to the PKCS#11 provider library. This may be useful when testing a new provider library.

Running named with automatic zone re-signing

If you want named to dynamically re-sign zones using HSM keys, and/or to to sign new records inserted via nsupdate, then named must have access to the HSM PIN. In OpenSSL-based PKCS#11, this is accomplished by placing the PIN into the openssl.cnf file (in the above examples, /opt/pkcs11/usr/ssl/openssl.cnf).

The location of the openssl.cnf file can be overridden by setting the OPENSSL_CONF environment variable before running named.

Sample openssl.cnf:

	openssl_conf = openssl_def
	[ openssl_def ]
	engines = engine_section
	[ engine_section ]
	pkcs11 = pkcs11_section
	[ pkcs11_section ]
	PIN = <PLACE PIN HERE>

This will also allow the dnssec-* tools to access the HSM without PIN entry. (The pkcs11-* tools access the HSM directly, not via OpenSSL, so a PIN will still be required to use them.)

In native PKCS#11 mode, the PIN can be provided in a file specified as an attribute of the key's label. For example, if a key had the label pkcs11:object=local-zsk;pin-source=/etc/hsmpin, then the PIN would be read from the file /etc/hsmpin.

Warning

Placing the HSM's PIN in a text file in this manner may reduce the security advantage of using an HSM. Be sure this is what you want to do before configuring the system in this way.

DLZ (Dynamically Loadable Zones)

DLZ (Dynamically Loadable Zones) is an extension to BIND 9 that allows zone data to be retrieved directly from an external database. There is no required format or schema. DLZ drivers exist for several different database backends including PostgreSQL, MySQL, and LDAP and can be written for any other.

Historically, DLZ drivers had to be statically linked with the named binary and were turned on via a configure option at compile time (for example, "configure --with-dlz-ldap"). Currently, the drivers provided in the BIND 9 tarball in contrib/dlz/drivers are still linked this way.

In BIND 9.8 and higher, it is possible to link some DLZ modules dynamically at runtime, via the DLZ "dlopen" driver, which acts as a generic wrapper around a shared object implementing the DLZ API. The "dlopen" driver is linked into named by default, so configure options are no longer necessary when using these dynamically linkable drivers, but are still needed for the older drivers in contrib/dlz/drivers.

When the DLZ module provides data to named, it does so in text format. The response is converted to DNS wire format by named. This conversion, and the lack of any internal caching, places significant limits on the query performance of DLZ modules. Consequently, DLZ is not recommended for use on high-volume servers. However, it can be used in a hidden master configuration, with slaves retrieving zone updates via AXFR. (Note, however, that DLZ has no built-in support for DNS notify; slaves are not automatically informed of changes to the zones in the database.)

Configuring DLZ

A DLZ database is configured with a dlz statement in named.conf:

    dlz example {
        database "dlopen driver.so args";
        search yes;
    };
    

This specifies a DLZ module to search when answering queries; the module is implemented in driver.so and is loaded at runtime by the dlopen DLZ driver. Multiple dlz statements can be specified; when answering a query, all DLZ modules with search set to yes will be queried to find out if they contain an answer for the query name; the best available answer will be returned to the client.

The search option in the above example can be omitted, because yes is the default value.

If search is set to no, then this DLZ module is not searched for the best match when a query is received. Instead, zones in this DLZ must be separately specified in a zone statement. This allows you to configure a zone normally using standard zone option semantics, but specify a different database back-end for storage of the zone's data. For example, to implement NXDOMAIN redirection using a DLZ module for back-end storage of redirection rules:

    dlz other {
        database "dlopen driver.so args";
        search no;
    };

    zone "." {
        type redirect;
        dlz other;
    };
    

Sample DLZ Driver

For guidance in implementation of DLZ modules, the directory contrib/dlz/example contains a basic dynamically-linkable DLZ module--i.e., one which can be loaded at runtime by the "dlopen" DLZ driver. The example sets up a single zone, whose name is passed to the module as an argument in the dlz statement:

    dlz other {
        database "dlopen driver.so example.nil";
    };
    

In the above example, the module is configured to create a zone "example.nil", which can answer queries and AXFR requests, and accept DDNS updates. At runtime, prior to any updates, the zone contains an SOA, NS, and a single A record at the apex:

 example.nil.  3600    IN      SOA     example.nil. hostmaster.example.nil. (
                                               123 900 600 86400 3600
                                       )
 example.nil.  3600    IN      NS      example.nil.
 example.nil.  1800    IN      A       10.53.0.1
    

The sample driver is capable of retrieving information about the querying client, and altering its response on the basis of this information. To demonstrate this feature, the example driver responds to queries for "source-addr.zonename>/TXT" with the source address of the query. Note, however, that this record will *not* be included in AXFR or ANY responses. Normally, this feature would be used to alter responses in some other fashion, e.g., by providing different address records for a particular name depending on the network from which the query arrived.

Documentation of the DLZ module API can be found in contrib/dlz/example/README. This directory also contains the header file dlz_minimal.h, which defines the API and should be included by any dynamically-linkable DLZ module.

IPv6 Support in BIND 9

BIND 9 fully supports all currently defined forms of IPv6 name to address and address to name lookups. It will also use IPv6 addresses to make queries when running on an IPv6 capable system.

For forward lookups, BIND 9 supports only AAAA records. RFC 3363 deprecated the use of A6 records, and client-side support for A6 records was accordingly removed from BIND 9. However, authoritative BIND 9 name servers still load zone files containing A6 records correctly, answer queries for A6 records, and accept zone transfer for a zone containing A6 records.

For IPv6 reverse lookups, BIND 9 supports the traditional "nibble" format used in the ip6.arpa domain, as well as the older, deprecated ip6.int domain. Older versions of BIND 9 supported the "binary label" (also known as "bitstring") format, but support of binary labels has been completely removed per RFC 3363. Many applications in BIND 9 do not understand the binary label format at all any more, and will return an error if given. In particular, an authoritative BIND 9 name server will not load a zone file containing binary labels.

For an overview of the format and structure of IPv6 addresses, see the section called “IPv6 addresses (AAAA)”.

Address Lookups Using AAAA Records

The IPv6 AAAA record is a parallel to the IPv4 A record, and, unlike the deprecated A6 record, specifies the entire IPv6 address in a single record. For example,

$ORIGIN example.com.
host            3600    IN      AAAA    2001:db8::1

Use of IPv4-in-IPv6 mapped addresses is not recommended. If a host has an IPv4 address, use an A record, not a AAAA, with ::ffff:192.168.42.1 as the address.

Address to Name Lookups Using Nibble Format

When looking up an address in nibble format, the address components are simply reversed, just as in IPv4, and ip6.arpa. is appended to the resulting name. For example, the following would provide reverse name lookup for a host with address 2001:db8::1.

$ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0  14400   IN    PTR    (
                                    host.example.com. )

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/man.rndc.html0000644000470500017500000007612412664710322017315 0ustar lamontlamont rndc

Name

rndc — name server control utility

Synopsis

rndc [-b source-address] [-c config-file] [-k key-file] [-s server] [-p port] [-q] [-V] [-y key_id] {command}

DESCRIPTION

rndc controls the operation of a name server. It supersedes the ndc utility that was provided in old BIND releases. If rndc is invoked with no command line options or arguments, it prints a short summary of the supported commands and the available options and their arguments.

rndc communicates with the name server over a TCP connection, sending commands authenticated with digital signatures. In the current versions of rndc and named, the only supported authentication algorithms are HMAC-MD5 (for compatibility), HMAC-SHA1, HMAC-SHA224, HMAC-SHA256 (default), HMAC-SHA384 and HMAC-SHA512. They use a shared secret on each end of the connection. This provides TSIG-style authentication for the command request and the name server's response. All commands sent over the channel must be signed by a key_id known to the server.

rndc reads a configuration file to determine how to contact the name server and decide what algorithm and key it should use.

OPTIONS

-b source-address

Use source-address as the source address for the connection to the server. Multiple instances are permitted to allow setting of both the IPv4 and IPv6 source addresses.

-c config-file

Use config-file as the configuration file instead of the default, /etc/rndc.conf.

-k key-file

Use key-file as the key file instead of the default, /etc/rndc.key. The key in /etc/rndc.key will be used to authenticate commands sent to the server if the config-file does not exist.

-s server

server is the name or address of the server which matches a server statement in the configuration file for rndc. If no server is supplied on the command line, the host named by the default-server clause in the options statement of the rndc configuration file will be used.

-p port

Send commands to TCP port port instead of BIND 9's default control channel port, 953.

-q

Quiet mode: Message text returned by the server will not be printed except when there is an error.

-V

Enable verbose logging.

-y key_id

Use the key key_id from the configuration file. key_id must be known by named with the same algorithm and secret string in order for control message validation to succeed. If no key_id is specified, rndc will first look for a key clause in the server statement of the server being used, or if no server statement is present for that host, then the default-key clause of the options statement. Note that the configuration file contains shared secrets which are used to send authenticated control commands to name servers. It should therefore not have general read or write access.

COMMANDS

A list of commands supported by rndc can be seen by running rndc without arguments.

Currently supported commands are:

addzone zone [class [view]] configuration

Add a zone while the server is running. This command requires the allow-new-zones option to be set to yes. The configuration string specified on the command line is the zone configuration text that would ordinarily be placed in named.conf.

The configuration is saved in a file called hash.nzf, where hash is a cryptographic hash generated from the name of the view. When named is restarted, the file will be loaded into the view configuration, so that zones that were added can persist after a restart.

This sample addzone command would add the zone example.com to the default view:

$ rndc addzone example.com '{ type master; file "example.com.db"; };'

(Note the brackets and semi-colon around the zone configuration text.)

See also rndc delzone and rndc modzone.

delzone [-clean] zone [class [view]]

Delete a zone while the server is running. Only zones that were originally added via rndc addzone can be deleted in this manner.

If the -clean is specified, the zone's master file (and journal file, if any) will be deleted along with the zone. Without the -clean option, zone files must be cleaned up by hand. (If the zone is of type "slave" or "stub", the files needing to be cleaned up will be reported in the output of the rndc delzone command.)

See also rndc addzone and rndc modzone.

dumpdb [-all|-cache|-zone|-adb|-bad] [view ...]

Dump the server's caches (default) and/or zones to the dump file for the specified views. If no view is specified, all views are dumped. (See the dump-file option in the BIND 9 Administrator Reference Manual.)

flush

Flushes the server's cache.

flushname name [view]

Flushes the given name from the server's DNS cache and, if applicable, from the server's nameserver address database or bad-server cache.

flushtree name [view]

Flushes the given name, and all of its subdomains, from the server's DNS cache, the address database, and the bad server cache.

freeze [zone [class [view]]]

Suspend updates to a dynamic zone. If no zone is specified, then all zones are suspended. This allows manual edits to be made to a zone normally updated by dynamic update. It also causes changes in the journal file to be synced into the master file. All dynamic update attempts will be refused while the zone is frozen.

See also rndc thaw.

halt [-p]

Stop the server immediately. Recent changes made through dynamic update or IXFR are not saved to the master files, but will be rolled forward from the journal files when the server is restarted. If -p is specified named's process id is returned. This allows an external process to determine when named had completed halting.

See also rndc stop.

loadkeys zone [class [view]]

Fetch all DNSSEC keys for the given zone from the key directory. If they are within their publication period, merge them into the zone's DNSKEY RRset. Unlike rndc sign, however, the zone is not immediately re-signed by the new keys, but is allowed to incrementally re-sign over time.

This command requires that the auto-dnssec zone option be set to maintain, and also requires the zone to be configured to allow dynamic DNS. (See "Dynamic Update Policies" in the Administrator Reference Manual for more details.)

See also rndc loadkeys.

notify zone [class [view]]

Resend NOTIFY messages for the zone.

notrace

Sets the server's debugging level to 0.

See also rndc trace.

querylog [on|off]

Enable or disable query logging. (For backward compatibility, this command can also be used without an argument to toggle query logging on and off.)

Query logging can also be enabled by explicitly directing the queries category to a channel in the logging section of named.conf or by specifying querylog yes; in the options section of named.conf.

reconfig

Reload the configuration file and load new zones, but do not reload existing zone files even if they have changed. This is faster than a full reload when there is a large number of zones because it avoids the need to examine the modification times of the zones files.

recursing

Dump the list of queries named is currently recursing on, and the list of domains to which iterative queries are currently being sent. (The second list includes the number of fetches currently active for the given domain, and how many have been passed or dropped because of the fetches-per-zone option.)

refresh zone [class [view]]

Schedule zone maintenance for the given zone.

reload

Reload configuration file and zones.

reload zone [class [view]]

Reload the given zone.

retransfer zone [class [view]]

Retransfer the given slave zone from the master server.

If the zone is configured to use inline-signing, the signed version of the zone is discarded; after the retransfer of the unsigned version is complete, the signed version will be regenerated with all new signatures.

scan

Scan the list of available network interfaces for changes, without performing a full reconfig or waiting for the interface-interval timer.

secroots [view ...]

Dump the server's security roots to the secroots file for the specified views. If no view is specified, security roots for all views are dumped.

sign zone [class [view]]

Fetch all DNSSEC keys for the given zone from the key directory (see the key-directory option in the BIND 9 Administrator Reference Manual). If they are within their publication period, merge them into the zone's DNSKEY RRset. If the DNSKEY RRset is changed, then the zone is automatically re-signed with the new key set.

This command requires that the auto-dnssec zone option be set to allow or maintain, and also requires the zone to be configured to allow dynamic DNS. (See "Dynamic Update Policies" in the Administrator Reference Manual for more details.)

See also rndc loadkeys.

signing [( -list | -clear keyid/algorithm | -clear all | -nsec3param ( parameters | none ) ) ] zone [class [view]]

List, edit, or remove the DNSSEC signing state records for the specified zone. The status of ongoing DNSSEC operations (such as signing or generating NSEC3 chains) is stored in the zone in the form of DNS resource records of type sig-signing-type. rndc signing -list converts these records into a human-readable form, indicating which keys are currently signing or have finished signing the zone, and which NSEC3 chains are being created or removed.

rndc signing -clear can remove a single key (specified in the same format that rndc signing -list uses to display it), or all keys. In either case, only completed keys are removed; any record indicating that a key has not yet finished signing the zone will be retained.

rndc signing -nsec3param sets the NSEC3 parameters for a zone. This is the only supported mechanism for using NSEC3 with inline-signing zones. Parameters are specified in the same format as an NSEC3PARAM resource record: hash algorithm, flags, iterations, and salt, in that order.

Currently, the only defined value for hash algorithm is 1, representing SHA-1. The flags may be set to 0 or 1, depending on whether you wish to set the opt-out bit in the NSEC3 chain. iterations defines the number of additional times to apply the algorithm when generating an NSEC3 hash. The salt is a string of data expressed in hexadecimal, a hyphen (`-') if no salt is to be used, or the keyword auto, which causes named to generate a random 64-bit salt.

So, for example, to create an NSEC3 chain using the SHA-1 hash algorithm, no opt-out flag, 10 iterations, and a salt value of "FFFF", use: rndc signing -nsec3param 1 0 10 FFFF zone. To set the opt-out flag, 15 iterations, and no salt, use: rndc signing -nsec3param 1 1 15 - zone.

rndc signing -nsec3param none removes an existing NSEC3 chain and replaces it with NSEC.

stats

Write server statistics to the statistics file. (See the statistics-file option in the BIND 9 Administrator Reference Manual.)

status

Display status of the server. Note that the number of zones includes the internal bind/CH zone and the default ./IN hint zone if there is not an explicit root zone configured.

stop [-p]

Stop the server, making sure any recent changes made through dynamic update or IXFR are first saved to the master files of the updated zones. If -p is specified named's process id is returned. This allows an external process to determine when named had completed stopping.

See also rndc halt.

sync [-clean] [zone [class [view]]]

Sync changes in the journal file for a dynamic zone to the master file. If the "-clean" option is specified, the journal file is also removed. If no zone is specified, then all zones are synced.

thaw [zone [class [view]]]

Enable updates to a frozen dynamic zone. If no zone is specified, then all frozen zones are enabled. This causes the server to reload the zone from disk, and re-enables dynamic updates after the load has completed. After a zone is thawed, dynamic updates will no longer be refused. If the zone has changed and the ixfr-from-differences option is in use, then the journal file will be updated to reflect changes in the zone. Otherwise, if the zone has changed, any existing journal file will be removed.

See also rndc freeze.

trace

Increment the servers debugging level by one.

trace level

Sets the server's debugging level to an explicit value.

See also rndc notrace.

tsig-delete keyname [view]

Delete a given TKEY-negotiated key from the server. (This does not apply to statically configured TSIG keys.)

tsig-list

List the names of all TSIG keys currently configured for use by named in each view. The list both statically configured keys and dynamic TKEY-negotiated keys.

validation ( on | off | check ) [view ...]

Enable, disable, or check the current status of DNSSEC validation. Note dnssec-enable also needs to be set to yes or auto to be effective. It defaults to enabled.

zonestatus zone [class [view]]

Displays the current status of the given zone, including the master file name and any include files from which it was loaded, when it was most recently loaded, the current serial number, the number of nodes, whether the zone supports dynamic updates, whether the zone is DNSSEC signed, whether it uses automatic DNSSEC key management or inline signing, and the scheduled refresh or expiry times for the zone.

LIMITATIONS

There is currently no way to provide the shared secret for a key_id without using the configuration file.

Several error messages could be clearer.

SEE ALSO

rndc.conf(5), rndc-confgen(8), named(8), named.conf(5), ndc(8), BIND 9 Administrator Reference Manual.

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/Bv9ARM.ch13.html0000644000470500017500000001752712664710322017354 0ustar lamontlamont Manual pages

Manual pages


Table of Contents

dig — DNS lookup utility
host — DNS lookup utility
delv — DNS lookup and validation utility
dnssec-checkds — A DNSSEC delegation consistency checking tool.
dnssec-coverage — checks future DNSKEY coverage for a zone
dnssec-dsfromkey — DNSSEC DS RR generation tool
dnssec-importkey — Import DNSKEY records from external systems so they can be managed.
dnssec-keyfromlabel — DNSSEC key generation tool
dnssec-keygen — DNSSEC key generation tool
dnssec-revoke — Set the REVOKED bit on a DNSSEC key
dnssec-settime — Set the key timing metadata for a DNSSEC key
dnssec-signzone — DNSSEC zone signing tool
dnssec-verify — DNSSEC zone verification tool
named-checkconf — named configuration file syntax checking tool
named-checkzone — zone file validity checking or converting tool
named — Internet domain name server
named-journalprint — print zone journal in human-readable form
named-rrchecker — A syntax checker for individual DNS resource records
nsupdate — Dynamic DNS update utility
rndc — name server control utility
rndc.conf — rndc configuration file
rndc-confgen — rndc key generation tool
ddns-confgen — ddns key generation tool
arpaname — translate IP addresses to the corresponding ARPA names
genrandom — generate a file containing random data
isc-hmac-fixup — fixes HMAC keys generated by older versions of BIND
nsec3hash — generate NSEC3 hash

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/man.nsec3hash.html0000644000470500017500000001047412664710322020242 0ustar lamontlamont nsec3hash

Name

nsec3hash — generate NSEC3 hash

Synopsis

nsec3hash {salt} {algorithm} {iterations} {domain}

DESCRIPTION

nsec3hash generates an NSEC3 hash based on a set of NSEC3 parameters. This can be used to check the validity of NSEC3 records in a signed zone.

ARGUMENTS

salt

The salt provided to the hash algorithm.

algorithm

A number indicating the hash algorithm. Currently the only supported hash algorithm for NSEC3 is SHA-1, which is indicated by the number 1; consequently "1" is the only useful value for this argument.

iterations

The number of additional times the hash should be performed.

domain

The domain name to be hashed.

SEE ALSO

BIND 9 Administrator Reference Manual, RFC 5155.

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/Makefile.in0000644000470500017500000000763012664710322016770 0ustar lamontlamont# Copyright (C) 2004-2007, 2009, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001, 2002 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.22 2009/02/12 23:47:56 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_MAKE_RULES@ @BIND9_VERSION@ PKGVERSION = @PACKAGE_VERSION@ MANOBJS = Bv9ARM.html notes.html PDFOBJS = Bv9ARM.pdf notes.pdf doc man:: ${MANOBJS} ${PDFOBJS} clean:: rm -f Bv9ARM.aux Bv9ARM.brf Bv9ARM.glo Bv9ARM.idx Bv9ARM.toc rm -f Bv9ARM.log Bv9ARM.out Bv9ARM.tex Bv9ARM.tex.tmp rm -f notes.aux notes.brf notes.glo notes.idx notes.toc rm -f notes.log notes.out notes.tex notes.tex.tmp docclean manclean maintainer-clean:: clean rm -f *.html ${PDFOBJS} docclean manclean maintainer-clean distclean:: rm -f releaseinfo.xml rm -f pkgversion.xml rm -f noteversion.xml notes.html: notes-wrapper.xml notes.xml releaseinfo.xml pkgversion.xml noteversion.xml expand notes-wrapper.xml | \ ${XSLTPROC} --stringparam generate.toc "" ../xsl/isc-notes-html.xsl - |\ @PERL@ html-fixup.pl > notes.html notes.tex: notes-wrapper.xml notes.xml releaseinfo.xml pkgversion.xml noteversion.xml expand notes-wrapper.xml | \ ${XSLTPROC} --stringparam generate.toc "book toc" ${top_srcdir}/doc/xsl/pre-latex.xsl - | \ ${XSLTPROC} ${top_srcdir}/doc/xsl/isc-notes-latex.xsl - | \ @PERL@ latex-fixup.pl >$@.tmp if test -s $@.tmp; then mv $@.tmp $@; else rm -f $@.tmp; exit 1; fi notes.pdf: notes.tex releaseinfo.xml pkgversion.xml noteversion.xml rm -f notes-wrapper.aux notes.pdf notes.log ${PDFLATEX} '\batchmode\input notes.tex' || (rm -f $@ ; exit 1) Bv9ARM.html: Bv9ARM-book.xml releaseinfo.xml pkgversion.xml noteversion.xml expand Bv9ARM-book.xml | \ ${XSLTPROC} --stringparam root.filename Bv9ARM \ ${top_srcdir}/doc/xsl/isc-docbook-chunk.xsl - Bv9ARM-all.html: Bv9ARM-book.xml releaseinfo.xml pkgversion.xml noteversion.xml expand Bv9ARM-book.xml | \ ${XSLTPROC} -o Bv9ARM-all.html ../xsl/isc-docbook-html.xsl - Bv9ARM.tex: Bv9ARM-book.xml releaseinfo.xml pkgversion.xml noteversion.xml expand Bv9ARM-book.xml | \ ${XSLTPROC} ${top_srcdir}/doc/xsl/pre-latex.xsl - | \ ${XSLTPROC} ${top_srcdir}/doc/xsl/isc-docbook-latex.xsl - | \ @PERL@ latex-fixup.pl >$@.tmp if test -s $@.tmp; then mv $@.tmp $@; else rm -f $@.tmp; exit 1; fi Bv9ARM.dvi: Bv9ARM.tex releaseinfo.xml pkgversion.xml noteversion.xml rm -f Bv9ARM-book.aux Bv9ARM-book.dvi Bv9ARM-book.log ${LATEX} '\batchmode\input Bv9ARM.tex' || (rm -f $@ ; exit 1) ${LATEX} '\batchmode\input Bv9ARM.tex' || (rm -f $@ ; exit 1) ${LATEX} '\batchmode\input Bv9ARM.tex' || (rm -f $@ ; exit 1) Bv9ARM.pdf: Bv9ARM.tex releaseinfo.xml pkgversion.xml noteversion.xml rm -f Bv9ARM-book.aux Bv9ARM-book.pdf Bv9ARM-book.log ${PDFLATEX} '\batchmode\input Bv9ARM.tex' || (rm -f $@ ; exit 1) ${PDFLATEX} '\batchmode\input Bv9ARM.tex' || (rm -f $@ ; exit 1) ${PDFLATEX} '\batchmode\input Bv9ARM.tex' || (rm -f $@ ; exit 1) FORCE: releaseinfo.xml: FORCE echo >$@ 'BIND Version ${VERSION}' noteversion.xml: FORCE echo >$@ 'Release Notes for BIND Version ${VERSION}' pkgversion.xml: FORCE echo >$@ ' This version of the manual corresponds to BIND version ${PKGVERSION}.' bind9-9.10.3.dfsg.P4/doc/arm/notes-wrapper.xml0000644000470500017500000000214412664710322020246 0ustar lamontlamont]>
<xi:include href="notes.xml"/> </article> <!-- - Local variables: - mode: sgml - End: --> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������bind9-9.10.3.dfsg.P4/doc/arm/Bv9ARM.ch01.html�������������������������������������������������������0000644�0004705�0001750�00000061764�12664710322�017353� 0����������������������������������������������������������������������������������������������������ustar �lamont��������������������������lamont�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- - Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") - Copyright (C) 2000-2003 Internet Software Consortium. - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. --> <!-- $Id$ --> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Chapter 1. Introduction

Chapter 1. Introduction

The Internet Domain Name System (DNS) consists of the syntax to specify the names of entities in the Internet in a hierarchical manner, the rules used for delegating authority over names, and the system implementation that actually maps names to Internet addresses. DNS data is maintained in a group of distributed hierarchical databases.

Scope of Document

The Berkeley Internet Name Domain (BIND) implements a domain name server for a number of operating systems. This document provides basic information about the installation and care of the Internet Systems Consortium (ISC) BIND version 9 software package for system administrators.

This version of the manual corresponds to BIND version 9.10.

Organization of This Document

In this document, Chapter 1 introduces the basic DNS and BIND concepts. Chapter 2 describes resource requirements for running BIND in various environments. Information in Chapter 3 is task-oriented in its presentation and is organized functionally, to aid in the process of installing the BIND 9 software. The task-oriented section is followed by Chapter 4, which contains more advanced concepts that the system administrator may need for implementing certain options. Chapter 5 describes the BIND 9 lightweight resolver. The contents of Chapter 6 are organized as in a reference manual to aid in the ongoing maintenance of the software. Chapter 7 addresses security considerations, and Chapter 8 contains troubleshooting help. The main body of the document is followed by several appendices which contain useful reference information, such as a bibliography and historic information related to BIND and the Domain Name System.

Conventions Used in This Document

In this document, we use the following general typographic conventions:

To describe:

We use the style:

a pathname, filename, URL, hostname, mailing list name, or new term or concept

Fixed width

literal user input

Fixed Width Bold

program output

Fixed Width

The following conventions are used in descriptions of the BIND configuration file:

To describe:

We use the style:

keywords

Fixed Width

variables

Fixed Width

Optional input

[Text is enclosed in square brackets]

The Domain Name System (DNS)

The purpose of this document is to explain the installation and upkeep of the BIND (Berkeley Internet Name Domain) software package, and we begin by reviewing the fundamentals of the Domain Name System (DNS) as they relate to BIND.

DNS Fundamentals

The Domain Name System (DNS) is a hierarchical, distributed database. It stores information for mapping Internet host names to IP addresses and vice versa, mail routing information, and other data used by Internet applications.

Clients look up information in the DNS by calling a resolver library, which sends queries to one or more name servers and interprets the responses. The BIND 9 software distribution contains a name server, named, and a resolver library, liblwres. The older libbind resolver library is also available from ISC as a separate download.

Domains and Domain Names

The data stored in the DNS is identified by domain names that are organized as a tree according to organizational or administrative boundaries. Each node of the tree, called a domain, is given a label. The domain name of the node is the concatenation of all the labels on the path from the node to the root node. This is represented in written form as a string of labels listed from right to left and separated by dots. A label need only be unique within its parent domain.

For example, a domain name for a host at the company Example, Inc. could be ourhost.example.com, where com is the top level domain to which ourhost.example.com belongs, example is a subdomain of com, and ourhost is the name of the host.

For administrative purposes, the name space is partitioned into areas called zones, each starting at a node and extending down to the leaf nodes or to nodes where other zones start. The data for each zone is stored in a name server, which answers queries about the zone using the DNS protocol.

The data associated with each domain name is stored in the form of resource records (RRs). Some of the supported resource record types are described in the section called “Types of Resource Records and When to Use Them”.

For more detailed information about the design of the DNS and the DNS protocol, please refer to the standards documents listed in the section called “Request for Comments (RFCs)”.

Zones

To properly operate a name server, it is important to understand the difference between a zone and a domain.

As stated previously, a zone is a point of delegation in the DNS tree. A zone consists of those contiguous parts of the domain tree for which a name server has complete information and over which it has authority. It contains all domain names from a certain point downward in the domain tree except those which are delegated to other zones. A delegation point is marked by one or more NS records in the parent zone, which should be matched by equivalent NS records at the root of the delegated zone.

For instance, consider the example.com domain which includes names such as host.aaa.example.com and host.bbb.example.com even though the example.com zone includes only delegations for the aaa.example.com and bbb.example.com zones. A zone can map exactly to a single domain, but could also include only part of a domain, the rest of which could be delegated to other name servers. Every name in the DNS tree is a domain, even if it is terminal, that is, has no subdomains. Every subdomain is a domain and every domain except the root is also a subdomain. The terminology is not intuitive and we suggest that you read RFCs 1033, 1034 and 1035 to gain a complete understanding of this difficult and subtle topic.

Though BIND is called a "domain name server", it deals primarily in terms of zones. The master and slave declarations in the named.conf file specify zones, not domains. When you ask some other site if it is willing to be a slave server for your domain, you are actually asking for slave service for some collection of zones.

Authoritative Name Servers

Each zone is served by at least one authoritative name server, which contains the complete data for the zone. To make the DNS tolerant of server and network failures, most zones have two or more authoritative servers, on different networks.

Responses from authoritative servers have the "authoritative answer" (AA) bit set in the response packets. This makes them easy to identify when debugging DNS configurations using tools like dig (the section called “Diagnostic Tools”).

The Primary Master

The authoritative server where the master copy of the zone data is maintained is called the primary master server, or simply the primary. Typically it loads the zone contents from some local file edited by humans or perhaps generated mechanically from some other local file which is edited by humans. This file is called the zone file or master file.

In some cases, however, the master file may not be edited by humans at all, but may instead be the result of dynamic update operations.

Slave Servers

The other authoritative servers, the slave servers (also known as secondary servers) load the zone contents from another server using a replication process known as a zone transfer. Typically the data are transferred directly from the primary master, but it is also possible to transfer it from another slave. In other words, a slave server may itself act as a master to a subordinate slave server.

Stealth Servers

Usually all of the zone's authoritative servers are listed in NS records in the parent zone. These NS records constitute a delegation of the zone from the parent. The authoritative servers are also listed in the zone file itself, at the top level or apex of the zone. You can list servers in the zone's top-level NS records that are not in the parent's NS delegation, but you cannot list servers in the parent's delegation that are not present at the zone's top level.

A stealth server is a server that is authoritative for a zone but is not listed in that zone's NS records. Stealth servers can be used for keeping a local copy of a zone to speed up access to the zone's records or to make sure that the zone is available even if all the "official" servers for the zone are inaccessible.

A configuration where the primary master server itself is a stealth server is often referred to as a "hidden primary" configuration. One use for this configuration is when the primary master is behind a firewall and therefore unable to communicate directly with the outside world.

Caching Name Servers

The resolver libraries provided by most operating systems are stub resolvers, meaning that they are not capable of performing the full DNS resolution process by themselves by talking directly to the authoritative servers. Instead, they rely on a local name server to perform the resolution on their behalf. Such a server is called a recursive name server; it performs recursive lookups for local clients.

To improve performance, recursive servers cache the results of the lookups they perform. Since the processes of recursion and caching are intimately connected, the terms recursive server and caching server are often used synonymously.

The length of time for which a record may be retained in the cache of a caching name server is controlled by the Time To Live (TTL) field associated with each resource record.

Forwarding

Even a caching name server does not necessarily perform the complete recursive lookup itself. Instead, it can forward some or all of the queries that it cannot satisfy from its cache to another caching name server, commonly referred to as a forwarder.

There may be one or more forwarders, and they are queried in turn until the list is exhausted or an answer is found. Forwarders are typically used when you do not wish all the servers at a given site to interact directly with the rest of the Internet servers. A typical scenario would involve a number of internal DNS servers and an Internet firewall. Servers unable to pass packets through the firewall would forward to the server that can do it, and that server would query the Internet DNS servers on the internal server's behalf.

Name Servers in Multiple Roles

The BIND name server can simultaneously act as a master for some zones, a slave for other zones, and as a caching (recursive) server for a set of local clients.

However, since the functions of authoritative name service and caching/recursive name service are logically separate, it is often advantageous to run them on separate server machines. A server that only provides authoritative name service (an authoritative-only server) can run with recursion disabled, improving reliability and security. A server that is not authoritative for any zones and only provides recursive service to local clients (a caching-only server) does not need to be reachable from the Internet at large and can be placed inside a firewall.

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/man.isc-hmac-fixup.html0000644000470500017500000001211212664710322021167 0ustar lamontlamont isc-hmac-fixup

Name

isc-hmac-fixup — fixes HMAC keys generated by older versions of BIND

Synopsis

isc-hmac-fixup {algorithm} {secret}

DESCRIPTION

Versions of BIND 9 up to and including BIND 9.6 had a bug causing HMAC-SHA* TSIG keys which were longer than the digest length of the hash algorithm (i.e., SHA1 keys longer than 160 bits, SHA256 keys longer than 256 bits, etc) to be used incorrectly, generating a message authentication code that was incompatible with other DNS implementations.

This bug has been fixed in BIND 9.7. However, the fix may cause incompatibility between older and newer versions of BIND, when using long keys. isc-hmac-fixup modifies those keys to restore compatibility.

To modify a key, run isc-hmac-fixup and specify the key's algorithm and secret on the command line. If the secret is longer than the digest length of the algorithm (64 bytes for SHA1 through SHA256, or 128 bytes for SHA384 and SHA512), then a new secret will be generated consisting of a hash digest of the old secret. (If the secret did not require conversion, then it will be printed without modification.)

SECURITY CONSIDERATIONS

Secrets that have been converted by isc-hmac-fixup are shortened, but as this is how the HMAC protocol works in operation anyway, it does not affect security. RFC 2104 notes, "Keys longer than [the digest length] are acceptable but the extra length would not significantly increase the function strength."

SEE ALSO

BIND 9 Administrator Reference Manual, RFC 2104.

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/Bv9ARM.ch05.html0000644000470500017500000001446412664710322017352 0ustar lamontlamont Chapter 5. The BIND 9 Lightweight Resolver

Chapter 5. The BIND 9 Lightweight Resolver

The Lightweight Resolver Library

Traditionally applications have been linked with a stub resolver library that sends recursive DNS queries to a local caching name server.

IPv6 once introduced new complexity into the resolution process, such as following A6 chains and DNAME records, and simultaneous lookup of IPv4 and IPv6 addresses. Though most of the complexity was then removed, these are hard or impossible to implement in a traditional stub resolver.

BIND 9 therefore can also provide resolution services to local clients using a combination of a lightweight resolver library and a resolver daemon process running on the local host. These communicate using a simple UDP-based protocol, the "lightweight resolver protocol" that is distinct from and simpler than the full DNS protocol.

Running a Resolver Daemon

To use the lightweight resolver interface, the system must run the resolver daemon lwresd or a local name server configured with a lwres statement.

By default, applications using the lightweight resolver library will make UDP requests to the IPv4 loopback address (127.0.0.1) on port 921. The address can be overridden by lwserver lines in /etc/resolv.conf.

The daemon currently only looks in the DNS, but in the future it may use other sources such as /etc/hosts, NIS, etc.

The lwresd daemon is essentially a caching-only name server that responds to requests using the lightweight resolver protocol rather than the DNS protocol. Because it needs to run on each host, it is designed to require no or minimal configuration. Unless configured otherwise, it uses the name servers listed on nameserver lines in /etc/resolv.conf as forwarders, but is also capable of doing the resolution autonomously if none are specified.

The lwresd daemon may also be configured with a named.conf style configuration file, in /etc/lwresd.conf by default. A name server may also be configured to act as a lightweight resolver daemon using the lwres statement in named.conf.

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/README-SGML0000644000470500017500000002720312664710322016341 0ustar lamontlamontCopyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") Copyright (C) 2000, 2001 Internet Software Consortium. See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. The BIND v9 ARM master document is now kept in DocBook XML format. Version: $Id: README-SGML,v 1.17 2004/03/05 05:04:43 marka Exp $ The entire ARM is in the single file: Bv9ARM-book.xml All of the other documents - HTML, PDF, etc - are generated from this master source. This file attempts to describe what tools are necessary for the maintenance of this document as well as the generation of the alternate formats of this document. This file will also spend a very little time describing the XML and SGML headers so you can understand a bit what you may need to do to be able to work with this document in any fashion other than simply editing it. We will spend almost no time on the actual tags and how to write an XML DocBook compliant document. If you are at all familiar with SGML or HTML it will be very evident. You only need to know what the tags are and how to use them. You can find a good resource either for this either online or in printed form: DocBook: The Definitive Guide By Norman Walsh and Leonard Muellner ISBN: 156592-580-7 1st Edition, October 1999 Copyright (C) 1999 by O'Reilly & Associates, Inc. All rights reserved. The book is available online in HTML format: http://docbook.org/ and buried in: http://www.nwalsh.com/docbook/defguide/index.html A lot of useful stuff is at NWalsh's site in general. You may also want to look at: http://www.xml.com/ The BIND v9 ARM is based on the XML 4.0 DocBook DTD. Every XML and SGML document begins with a prefix that tells where to find the file that describes the meaning and structure of the tags used in the rest of the document. For our XML DocBook 4.0 based document this prefix looks like this: This "DOCTYPE" statement has three parts, of which we are only using two: o The highest level term that represents this document (in this case it is "book" o The identifier that tells us which DTD to use. This identifier has two parts, the "Formal Public Identifier" (or FPI) and the system identifier. In SGML you can have either a FPI or a SYSTEM identifier but you have to have at least one of them. In XML you have to have a SYSTEM identifier. FP & SYSTEM identifiers - These are names/lookups for the actual DTD. The FPI is a globally unique name that should, on a properly configured system, tell you exactly what DTD to use. The SYSTEM identifier gives an absolute location for the DTD. In XML these are supposed to be properly formatted URL's. SGML has these things called "catalogs" that are files that map FPI's in to actual files. A "catalog" can also be used to remap a SYSTEM identifier so you can say something like: "http://www.oasis.org/foo" is actually "/usr/local/share/xml/foo.dtd" When you use various SGML/XML tools they need to be configured to look at the same "catalog" files so that as you move from tool to tool they all refer to the same DTD for the same document. We will be spending most of our configuration time making sure our tools use the same "catalog" files and that we have the same DTD's installed on our machines. XML's requirement of the SYSTEM identifier over the FPI will probably lead to more problems as it does not guarantee that everyone is using the same DTD. I did my initial work with the "sgmltools" the XML 4.0 DocBook DTD and "jade" or "openjade." You can get the 4.0 XML DocBook DTD from: http://www.docbook.org/xml/4.0/ (download the .zip file.) NOTE: We will eventually be changing the SYSTEM identifier to the recommended value of: http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd NOTE: Under FreeBSD this is the package: /usr/ports/textproc/docbook-xml NetBSD instructions are coming soon. With packages listed below installed under FreeBSD the "catalog" file that all the tools refer to at least one is in: /usr/local/share/sgml/catalog In order for our SYSTEM identifier for the XML DocBook dtd to be found I create a new catalog file at the top of the XML directory created on FreeBSD: /usr/local/share/xml/catalog This file has one line: SYSTEM "http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd" "/usr/local/share/xml/dtd/docbook/docbookx.dtd" Then in the main "catalog" I have it include this XML catalog: CATALOG "/usr/local/share/xml/catalog" On your systems you need to replace "/usr/local/share" with your prefix root (probably /usr/pkg under NetBSD.) NOTE: The URL used above is supposed to the be the proper one for this XML DocBook DTD... but there is nothing at that URL so you really do need the "SYSTEM" identifier mapping in your catalog (or make the SYSTEM identifier in your document refer to the real location of the file on your local system.) HOW TO VALIDATE A DOCUMENT: I use the sgmltools "nsgmls" document validator. Since we are using XML we need to use the XML declarations, which are installed as part of the modular DSSL style sheets: nsgmls -sv /usr/local/share/sgml/docbook/dsssl/modular/dtds/decls/xml.dcl \ Bv9ARM-book.xml A convenient shell script "validate.sh" is now generated by configure to invoke the above command with the correct system-dependent paths. The SGML tools can be found at: ftp://ftp.us.sgmltools.org/pub/SGMLtools/v2.0/source/ \ ftp://ftp.nllgg.nl/pub/SGMLtools/v2.0/source/ FreeBSD package for these is: /usr/ports/textproc/sgmltools HOW TO RENDER A DOCUMENT AS HTML or TeX: o Generate html doc with: openjade -v -d ./nominum-docbook-html.dsl \ -t sgml \ /usr/local/share/sgml/docbook/dsssl/modular/dtds/decls/xml.dcl \ Bv9ARM-book.xml A convenient shell script "genhtml.sh" is now generated by configure to invoke the above command with the correct system-dependent paths. On NetBSD there is no port for "openjade" however "jade" does still work. However you need to specify the "catalog" file to use for style sheets on the command line AND you need to have a default "catalog" mapping where to find various DTDs. It seems that "jade" installed out of the box on NetBSD does not use a globally defined "catalog" file for mapping PUBLIC identifiers in to SYSTEM identifiers. So you need to have a "catalog" file in your current working directory that has in it this: (these are probably more entries than you need!) CATALOG "/usr/pkg/share/sgml/iso8879/catalog" CATALOG "/usr/pkg/share/sgml/docbook/2.4.1/catalog" CATALOG "/usr/pkg/share/sgml/docbook/3.0/catalog" CATALOG "/usr/pkg/share/sgml/docbook/3.1/catalog" CATALOG "/usr/pkg/share/sgml/jade/catalog" CATALOG "/usr/local/share/xml/catalog" (These would all be "/usr/local" on FreeBSD) So the command for jade on NetBSD will look like this: jade -v -c /usr/pkg/share/sgml/catalog -t sgml \ -d ./nominum-docbook-html.dsl \ /usr/pkg/share/sgml/docbook/dsssl/modular/dtds/decls/xml.dcl \ ./Bv9ARM-book.xml Furthermore, since the style sheet subset we define has in it a hard coded path to the style sheet is based, it is actually generated by configure from a .in file so that it will contain the correct system-dependent path: where on FreeBSD the second line reads: On NetBSD it needs to read: NOTE: This is usually solved by having this style sheet modification be installed in a system directory and have it reference the style sheet it is based on via a relative path. o Generate TeX documentation: openjade -d ./nominum-docbook-print.dsl -t tex -v \ /usr/local/share/sgml/docbook/dsssl/modular/dtds/decls/xml.dcl \ Bv9ARM-book.xml If you have "jade" installed instead of "openjade" then use that as the command. There is little difference, openjade has some bug fixes and is in more active development. To convert the resulting TeX file in to a DVI file you need to do: tex "&jadetex" Bv9ARM-book.tex You can also directly generate the pdf file via: pdftex "&pdfjadetex" Bv9ARM-book.tex The scripts "genpdf.sh" and "gendvi." have been added to simply generating the PDF and DVI output. These substitute the correct paths of NetBSD & FreeBSD. You still need to have TeX, jadeTeX, and pdfTeX installed and configured properly for these to work. You will need to up both the "pool_size" and "hash_extra" variables in your texmf.cnf file and regenerate them. See below. You can see that I am using a DSSSL style sheet for DocBook. Actually two different ones - one for rendering html, and one for 'print' media. NOTE: For HTML we are using a Nominum DSSSL style instead of the default one (all it does is change the chunking to the chapter level and makes the files end with ".html" instead of ".htm" so far.) If you want to use the plain jane DSSSL style sheet replace the: -d ./nominum-docbook-html.dsl with -d /usr/local/share/sgml/docbook/dsssl/modular/html/docbook.dsl This style sheet will attempt to reference the one above. I am currently working on fixing these up so that it works the same on our various systems. The main trick is knowing which DTD's and DSSSL stylesheets you have installed, installing the right ones, and configuring a CATALOG that refers to them in the same way. We will probably end up putting our CATALOG's in the same place and then we should be able to generate and validate our documents with a minimal number of command line arguments. When running these commands you will get a lot of messages about a bunch of general entities not being defined and having no default entity. You can ignore those for now. Also with the style sheets we have and jade as it is you will get messages about "xref to title" being unsupported. You can ignore these for now as well. === Getting the various tools installed on FreeBSD (NetBSD coming soon..) o On freebsd you need to install the following packages: o print/teTeX o textproc/openjade o textproc/docbook o textproc/docbook-xml o textproc/dsssl-docbook-modular o textproc/dtd-catalogs o on freebsd you need to make some entities visible to the docbook xml dtd by making a symlink (can probably be done with a catalog too) ln -s /usr/local/share/xml/entity /usr/local/share/xml/dtd/docbook/ent o you may need to edit /usr/local/share/sgml/catalog and add the line: CATALOG "/usr/local/share/sgml/openjade/catalog" o add "hugelatex," Enlarge pool sizes, install the jadetex TeX driver file. cd /usr/local/share/texmf/web2c/ sudo cp texmf.cnf texmf.cnf.bak o edit the lines in texmf.cnf with these keys to these values: main_memory = 1100000 hash_extra = 15000 pool_size = 500000 string_vacancies = 45000 max_strings = 55000 pool_free = 47500 nest_size = 500 param_size = 1500 save_size = 5000 stack_size = 1500 sudo tex -ini -progname=hugelatex -fmt=hugelatex latex.ltx sudo texconfig init sudo texhash o For the jadetex macros you will need I recommend you get a more current version than what is packaged with openjade or jade. Checkout http://www.tug.org/applications/jadetex/ Unzip the file you get from there (should be jadetex-2.20 or newer.) In the directory you unzip: sudo make install sudo texhash NOTE: In the most uptodate "ports" for FreeBSD, jadetext is 2.20+ so on this platform you should be set as of 2001.01.08. bind9-9.10.3.dfsg.P4/doc/arm/Bv9ARM.ch03.html0000644000470500017500000007124612664710322017351 0ustar lamontlamont Chapter 3. Name Server Configuration

Chapter 3. Name Server Configuration

In this chapter we provide some suggested configurations along with guidelines for their use. We suggest reasonable values for certain option settings.

Sample Configurations

A Caching-only Name Server

The following sample configuration is appropriate for a caching-only name server for use by clients internal to a corporation. All queries from outside clients are refused using the allow-query option. Alternatively, the same effect could be achieved using suitable firewall rules.

// Two corporate subnets we wish to allow queries from.
acl corpnets { 192.168.4.0/24; 192.168.7.0/24; };
options {
     // Working directory
     directory "/etc/namedb";

     allow-query { corpnets; };
};
// Provide a reverse mapping for the loopback
// address 127.0.0.1
zone "0.0.127.in-addr.arpa" {
     type master;
     file "localhost.rev";
     notify no;
};

An Authoritative-only Name Server

This sample configuration is for an authoritative-only server that is the master server for "example.com" and a slave for the subdomain "eng.example.com".

options {
     // Working directory
     directory "/etc/namedb";
     // Do not allow access to cache
     allow-query-cache { none; };
     // This is the default
     allow-query { any; };
     // Do not provide recursive service
     recursion no;
};

// Provide a reverse mapping for the loopback
// address 127.0.0.1
zone "0.0.127.in-addr.arpa" {
     type master;
     file "localhost.rev";
     notify no;
};
// We are the master server for example.com
zone "example.com" {
     type master;
     file "example.com.db";
     // IP addresses of slave servers allowed to
     // transfer example.com
     allow-transfer {
          192.168.4.14;
          192.168.5.53;
     };
};
// We are a slave server for eng.example.com
zone "eng.example.com" {
     type slave;
     file "eng.example.com.bk";
     // IP address of eng.example.com master server
     masters { 192.168.4.12; };
};

Load Balancing

A primitive form of load balancing can be achieved in the DNS by using multiple records (such as multiple A records) for one name.

For example, if you have three WWW servers with network addresses of 10.0.0.1, 10.0.0.2 and 10.0.0.3, a set of records such as the following means that clients will connect to each machine one third of the time:

Name

TTL

CLASS

TYPE

Resource Record (RR) Data

www

600

IN

A

10.0.0.1

600

IN

A

10.0.0.2

600

IN

A

10.0.0.3

When a resolver queries for these records, BIND will rotate them and respond to the query with the records in a different order. In the example above, clients will randomly receive records in the order 1, 2, 3; 2, 3, 1; and 3, 1, 2. Most clients will use the first record returned and discard the rest.

For more detail on ordering responses, check the rrset-order sub-statement in the options statement, see RRset Ordering.

Name Server Operations

Tools for Use With the Name Server Daemon

This section describes several indispensable diagnostic, administrative and monitoring tools available to the system administrator for controlling and debugging the name server daemon.

Diagnostic Tools

The dig, host, and nslookup programs are all command line tools for manually querying name servers. They differ in style and output format.

dig

The domain information groper (dig) is the most versatile and complete of these lookup tools. It has two modes: simple interactive mode for a single query, and batch mode which executes a query for each in a list of several query lines. All query options are accessible from the command line.

dig [@server] domain [query-type] [query-class] [+query-option] [-dig-option] [%comment]

The usual simple use of dig will take the form

dig @server domain query-type query-class

For more information and a list of available commands and options, see the dig man page.

host

The host utility emphasizes simplicity and ease of use. By default, it converts between host names and Internet addresses, but its functionality can be extended with the use of options.

host [-aCdlnrsTwv] [-c class] [-N ndots] [-t type] [-W timeout] [-R retries] [-m flag] [-4] [-6] hostname [server]

For more information and a list of available commands and options, see the host man page.

nslookup

nslookup has two modes: interactive and non-interactive. Interactive mode allows the user to query name servers for information about various hosts and domains or to print a list of hosts in a domain. Non-interactive mode is used to print just the name and requested information for a host or domain.

nslookup [-option...] [[host-to-find] | [- [server]]]

Interactive mode is entered when no arguments are given (the default name server will be used) or when the first argument is a hyphen (`-') and the second argument is the host name or Internet address of a name server.

Non-interactive mode is used when the name or Internet address of the host to be looked up is given as the first argument. The optional second argument specifies the host name or address of a name server.

Due to its arcane user interface and frequently inconsistent behavior, we do not recommend the use of nslookup. Use dig instead.

Administrative Tools

Administrative tools play an integral part in the management of a server.

named-checkconf

The named-checkconf program checks the syntax of a named.conf file.

named-checkconf [-jvz] [-t directory] [filename]

named-checkzone

The named-checkzone program checks a master file for syntax and consistency.

named-checkzone [-djqvD] [-c class] [-o output] [-t directory] [-w directory] [-k (ignore|warn|fail)] [-n (ignore|warn|fail)] [-W (ignore|warn)] zone [filename]

named-compilezone

Similar to named-checkzone, but it always dumps the zone content to a specified file (typically in a different format).

rndc

The remote name daemon control (rndc) program allows the system administrator to control the operation of a name server. Since BIND 9.2, rndc supports all the commands of the BIND 8 ndc utility except ndc start and ndc restart, which were also not supported in ndc's channel mode. If you run rndc without any options it will display a usage message as follows:

rndc [-c config] [-s server] [-p port] [-y key] command [command...]

See rndc(8) for details of the available rndc commands.

rndc requires a configuration file, since all communication with the server is authenticated with digital signatures that rely on a shared secret, and there is no way to provide that secret other than with a configuration file. The default location for the rndc configuration file is /etc/rndc.conf, but an alternate location can be specified with the -c option. If the configuration file is not found, rndc will also look in /etc/rndc.key (or whatever sysconfdir was defined when the BIND build was configured). The rndc.key file is generated by running rndc-confgen -a as described in the section called “controls Statement Definition and Usage”.

The format of the configuration file is similar to that of named.conf, but limited to only four statements, the options, key, server and include statements. These statements are what associate the secret keys to the servers with which they are meant to be shared. The order of statements is not significant.

The options statement has three clauses: default-server, default-key, and default-port. default-server takes a host name or address argument and represents the server that will be contacted if no -s option is provided on the command line. default-key takes the name of a key as its argument, as defined by a key statement. default-port specifies the port to which rndc should connect if no port is given on the command line or in a server statement.

The key statement defines a key to be used by rndc when authenticating with named. Its syntax is identical to the key statement in named.conf. The keyword key is followed by a key name, which must be a valid domain name, though it need not actually be hierarchical; thus, a string like "rndc_key" is a valid name. The key statement has two clauses: algorithm and secret. While the configuration parser will accept any string as the argument to algorithm, currently only the strings "hmac-md5", "hmac-sha1", "hmac-sha224", "hmac-sha256", "hmac-sha384" and "hmac-sha512" have any meaning. The secret is a base-64 encoded string as specified in RFC 3548.

The server statement associates a key defined using the key statement with a server. The keyword server is followed by a host name or address. The server statement has two clauses: key and port. The key clause specifies the name of the key to be used when communicating with this server, and the port clause can be used to specify the port rndc should connect to on the server.

A sample minimal configuration file is as follows:

key rndc_key {
     algorithm "hmac-sha256";
     secret
       "c3Ryb25nIGVub3VnaCBmb3IgYSBtYW4gYnV0IG1hZGUgZm9yIGEgd29tYW4K";
};
options {
     default-server 127.0.0.1;
     default-key    rndc_key;
};

This file, if installed as /etc/rndc.conf, would allow the command:

$ rndc reload

to connect to 127.0.0.1 port 953 and cause the name server to reload, if a name server on the local machine were running with following controls statements:

controls {
        inet 127.0.0.1
            allow { localhost; } keys { rndc_key; };
};

and it had an identical key statement for rndc_key.

Running the rndc-confgen program will conveniently create a rndc.conf file for you, and also display the corresponding controls statement that you need to add to named.conf. Alternatively, you can run rndc-confgen -a to set up a rndc.key file and not modify named.conf at all.

Signals

Certain UNIX signals cause the name server to take specific actions, as described in the following table. These signals can be sent using the kill command.

SIGHUP

Causes the server to read named.conf and reload the database.

SIGTERM

Causes the server to clean up and exit.

SIGINT

Causes the server to clean up and exit.

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/Bv9ARM.ch10.html0000644000470500017500000001744212664710322017345 0ustar lamontlamont Appendix B. A Brief History of the DNS and BIND

Appendix B. A Brief History of the DNS and BIND

Table of Contents

Although the "official" beginning of the Domain Name System occurred in 1984 with the publication of RFC 920, the core of the new system was described in 1983 in RFCs 882 and 883. From 1984 to 1987, the ARPAnet (the precursor to today's Internet) became a testbed of experimentation for developing the new naming/addressing scheme in a rapidly expanding, operational network environment. New RFCs were written and published in 1987 that modified the original documents to incorporate improvements based on the working model. RFC 1034, "Domain Names-Concepts and Facilities", and RFC 1035, "Domain Names-Implementation and Specification" were published and became the standards upon which all DNS implementations are built.

The first working domain name server, called "Jeeves", was written in 1983-84 by Paul Mockapetris for operation on DEC Tops-20 machines located at the University of Southern California's Information Sciences Institute (USC-ISI) and SRI International's Network Information Center (SRI-NIC). A DNS server for Unix machines, the Berkeley Internet Name Domain (BIND) package, was written soon after by a group of graduate students at the University of California at Berkeley under a grant from the US Defense Advanced Research Projects Administration (DARPA).

Versions of BIND through 4.8.3 were maintained by the Computer Systems Research Group (CSRG) at UC Berkeley. Douglas Terry, Mark Painter, David Riggle and Songnian Zhou made up the initial BIND project team. After that, additional work on the software package was done by Ralph Campbell. Kevin Dunlap, a Digital Equipment Corporation employee on loan to the CSRG, worked on BIND for 2 years, from 1985 to 1987. Many other people also contributed to BIND development during that time: Doug Kingston, Craig Partridge, Smoot Carl-Mitchell, Mike Muuss, Jim Bloom and Mike Schwartz. BIND maintenance was subsequently handled by Mike Karels and Øivind Kure.

BIND versions 4.9 and 4.9.1 were released by Digital Equipment Corporation (now Compaq Computer Corporation). Paul Vixie, then a DEC employee, became BIND's primary caretaker. He was assisted by Phil Almquist, Robert Elz, Alan Barrett, Paul Albitz, Bryan Beecher, Andrew Partan, Andy Cherenson, Tom Limoncelli, Berthold Paffrath, Fuat Baran, Anant Kumar, Art Harkin, Win Treese, Don Lewis, Christophe Wolfhugel, and others.

In 1994, BIND version 4.9.2 was sponsored by Vixie Enterprises. Paul Vixie became BIND's principal architect/programmer.

BIND versions from 4.9.3 onward have been developed and maintained by the Internet Systems Consortium and its predecessor, the Internet Software Consortium, with support being provided by ISC's sponsors.

As co-architects/programmers, Bob Halley and Paul Vixie released the first production-ready version of BIND version 8 in May 1997.

BIND version 9 was released in September 2000 and is a major rewrite of nearly all aspects of the underlying BIND architecture.

BIND versions 4 and 8 are officially deprecated. No additional development is done on BIND version 4 or BIND version 8.

BIND development work is made possible today by the sponsorship of several corporations, and by the tireless work efforts of numerous individuals.

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/Bv9ARM.ch12.html0000644000470500017500000005200412664710322017340 0ustar lamontlamont Appendix D. BIND 9 DNS Library Support

Appendix D. BIND 9 DNS Library Support

BIND 9 DNS Library Support

This version of BIND 9 "exports" its internal libraries so that they can be used by third-party applications more easily (we call them "export" libraries in this document). In addition to all major DNS-related APIs BIND 9 is currently using, the export libraries provide the following features:

  • The newly created "DNS client" module. This is a higher level API that provides an interface to name resolution, single DNS transaction with a particular server, and dynamic update. Regarding name resolution, it supports advanced features such as DNSSEC validation and caching. This module supports both synchronous and asynchronous mode.

  • The new "IRS" (Information Retrieval System) library. It provides an interface to parse the traditional resolv.conf file and more advanced, DNS-specific configuration file for the rest of this package (see the description for the dns.conf file below).

  • As part of the IRS library, newly implemented standard address-name mapping functions, getaddrinfo() and getnameinfo(), are provided. They use the DNSSEC-aware validating resolver backend, and could use other advanced features of the BIND 9 libraries such as caching. The getaddrinfo() function resolves both A and AAAA RRs concurrently (when the address family is unspecified).

  • An experimental framework to support other event libraries than BIND 9's internal event task system.

Prerequisite

GNU make is required to build the export libraries (other part of BIND 9 can still be built with other types of make). In the reminder of this document, "make" means GNU make. Note that in some platforms you may need to invoke a different command name than "make" (e.g. "gmake") to indicate it's GNU make.

Compilation

$ ./configure --enable-exportlib [other flags]
$ make

This will create (in addition to usual BIND 9 programs) and a separate set of libraries under the lib/export directory. For example, lib/export/dns/libdns.a is the archive file of the export version of the BIND 9 DNS library. Sample application programs using the libraries will also be built under the lib/export/samples directory (see below).

Installation

$ cd lib/export
$ make install

This will install library object files under the directory specified by the --with-export-libdir configure option (default: EPREFIX/lib/bind9), and header files under the directory specified by the --with-export-includedir configure option (default: PREFIX/include/bind9). Root privilege is normally required. "make install" at the top directory will do the same.

To see how to build your own application after the installation, see lib/export/samples/Makefile-postinstall.in.

Known Defects/Restrictions

  • Currently, win32 is not supported for the export library. (Normal BIND 9 application can be built as before).

  • The "fixed" RRset order is not (currently) supported in the export library. If you want to use "fixed" RRset order for, e.g. named while still building the export library even without the fixed order support, build them separately:

    $ ./configure --enable-fixed-rrset [other flags, but not --enable-exportlib]
    $ make
    $ ./configure --enable-exportlib [other flags, but not --enable-fixed-rrset]
    $ cd lib/export
    $ make
    

  • The client module and the IRS library currently do not support DNSSEC validation using DLV (the underlying modules can handle it, but there is no tunable interface to enable the feature).

  • RFC 5011 is not supported in the validating stub resolver of the export library. In fact, it is not clear whether it should: trust anchors would be a system-wide configuration which would be managed by an administrator, while the stub resolver will be used by ordinary applications run by a normal user.

  • Not all common /etc/resolv.conf options are supported in the IRS library. The only available options in this version are "debug" and "ndots".

The dns.conf File

The IRS library supports an "advanced" configuration file related to the DNS library for configuration parameters that would be beyond the capability of the resolv.conf file. Specifically, it is intended to provide DNSSEC related configuration parameters. By default the path to this configuration file is /etc/dns.conf. This module is very experimental and the configuration syntax or library interfaces may change in future versions. Currently, only the trusted-keys statement is supported, whose syntax is the same as the same name of statement for named.conf. (See the section called “trusted-keys Statement Grammar” for details.)

Sample Applications

Some sample application programs using this API are provided for reference. The following is a brief description of these applications.

sample: a simple stub resolver utility

It sends a query of a given name (of a given optional RR type) to a specified recursive server, and prints the result as a list of RRs. It can also act as a validating stub resolver if a trust anchor is given via a set of command line options.

Usage: sample [options] server_address hostname

Options and Arguments:

-t RRtype

specify the RR type of the query. The default is the A RR.

[-a algorithm] [-e] -k keyname -K keystring

specify a command-line DNS key to validate the answer. For example, to specify the following DNSKEY of example.com:


                example.com. 3600 IN DNSKEY 257 3 5 xxx

specify the options as follows:


          -e -k example.com -K "xxx"

-e means that this key is a zone's "key signing key" (as known as "secure Entry point"). When -a is omitted rsasha1 will be used by default.

-s domain:alt_server_address

specify a separate recursive server address for the specific "domain". Example: -s example.com:2001:db8::1234

server_address

an IP(v4/v6) address of the recursive server to which queries are sent.

hostname

the domain name for the query

sample-async: a simple stub resolver, working asynchronously

Similar to "sample", but accepts a list of (query) domain names as a separate file and resolves the names asynchronously.

Usage: sample-async [-s server_address] [-t RR_type] input_file

Options and Arguments:

-s server_address
an IPv4 address of the recursive server to which queries are sent. (IPv6 addresses are not supported in this implementation)
-t RR_type
specify the RR type of the queries. The default is the A RR.
input_file
a list of domain names to be resolved. each line consists of a single domain name. Example:


  www.example.com
  mx.example.net
  ns.xxx.example

sample-request: a simple DNS transaction client

It sends a query to a specified server, and prints the response with minimal processing. It doesn't act as a "stub resolver": it stops the processing once it gets any response from the server, whether it's a referral or an alias (CNAME or DNAME) that would require further queries to get the ultimate answer. In other words, this utility acts as a very simplified dig.

Usage: sample-request [-t RRtype] server_address hostname

Options and Arguments:

-t RRtype

specify the RR type of the queries. The default is the A RR.

server_address

an IP(v4/v6) address of the recursive server to which the query is sent.

hostname

the domain name for the query

sample-gai: getaddrinfo() and getnameinfo() test code

This is a test program to check getaddrinfo() and getnameinfo() behavior. It takes a host name as an argument, calls getaddrinfo() with the given host name, and calls getnameinfo() with the resulting IP addresses returned by getaddrinfo(). If the dns.conf file exists and defines a trust anchor, the underlying resolver will act as a validating resolver, and getaddrinfo()/getnameinfo() will fail with an EAI_INSECUREDATA error when DNSSEC validation fails.

Usage: sample-gai hostname

sample-update: a simple dynamic update client program

It accepts a single update command as a command-line argument, sends an update request message to the authoritative server, and shows the response from the server. In other words, this is a simplified nsupdate.

Usage: sample-update [options] (add|delete) "update data"

Options and Arguments:

-a auth_server

An IP address of the authoritative server that has authority for the zone containing the update name. This should normally be the primary authoritative server that accepts dynamic updates. It can also be a secondary server that is configured to forward update requests to the primary server.

-k keyfile

A TSIG key file to secure the update transaction. The keyfile format is the same as that for the nsupdate utility.

-p prerequisite

A prerequisite for the update (only one prerequisite can be specified). The prerequisite format is the same as that is accepted by the nsupdate utility.

-r recursive_server

An IP address of a recursive server that this utility will use. A recursive server may be necessary to identify the authoritative server address to which the update request is sent.

-z zonename

The domain name of the zone that contains

(add|delete)

Specify the type of update operation. Either "add" or "delete" must be specified.

"update data"

Specify the data to be updated. A typical example of the data would look like "name TTL RRtype RDATA".

Note

In practice, either -a or -r must be specified. Others can be optional; the underlying library routine tries to identify the appropriate server and the zone name for the update.

Examples: assuming the primary authoritative server of the dynamic.example.com zone has an IPv6 address 2001:db8::1234,

$ sample-update -a sample-update -k Kxxx.+nnn+mmmm.key add "foo.dynamic.example.com 30 IN A 192.168.2.1"

adds an A RR for foo.dynamic.example.com using the given key.

$ sample-update -a sample-update -k Kxxx.+nnn+mmmm.key delete "foo.dynamic.example.com 30 IN A"

removes all A RRs for foo.dynamic.example.com using the given key.

   
$ sample-update -a sample-update -k Kxxx.+nnn+mmmm.key delete "foo.dynamic.example.com"

removes all RRs for foo.dynamic.example.com using the given key.

nsprobe: domain/name server checker in terms of RFC 4074

It checks a set of domains to see the name servers of the domains behave correctly in terms of RFC 4074. This is included in the set of sample programs to show how the export library can be used in a DNS-related application.

Usage: nsprobe [-d] [-v [-v...]] [-c cache_address] [input_file]

Options

-d

run in the "debug" mode. with this option nsprobe will dump every RRs it receives.

-v

increase verbosity of other normal log messages. This can be specified multiple times

-c cache_address

specify an IP address of a recursive (caching) name server. nsprobe uses this server to get the NS RRset of each domain and the A and/or AAAA RRsets for the name servers. The default value is 127.0.0.1.

input_file

a file name containing a list of domain (zone) names to be probed. when omitted the standard input will be used. Each line of the input file specifies a single domain name such as "example.com". In general this domain name must be the apex name of some DNS zone (unlike normal "host names" such as "www.example.com"). nsprobe first identifies the NS RRsets for the given domain name, and sends A and AAAA queries to these servers for some "widely used" names under the zone; specifically, adding "www" and "ftp" to the zone name.

Library References

As of this writing, there is no formal "manual" of the libraries, except this document, header files (some of them provide pretty detailed explanations), and sample application programs.

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/notes.xml0000644000470500017500000001255612664710322016600 0ustar lamontlamont Introduction This document summarizes changes since BIND 9.10.3: BIND 9.10.3-P4 addresses the security issues described in CVE-2016-1285, CVE-2016-1286 and CVE-2016-2088. BIND 9.10.3-P3 addresses the security issues described in CVE-2015-8704 and CVE-2015-8705. It also fixes a serious regression in authoritative server selection that was introduced in BIND 9.10.3. BIND 9.10.3-P2 addresses the security issues described in CVE-2015-3193 (OpenSSL), CVE-2015-8000 and CVE-2015-8461. BIND 9.10.3-P1 was incomplete and was withdrawn prior to publication. Download The latest versions of BIND 9 software can always be found at http://www.isc.org/downloads/. There you will find additional information about each release, source code, and pre-compiled versions for Microsoft Windows operating systems. Security Fixes Duplicate EDNS COOKIE options in a response could trigger an assertion failure. This flaw is disclosed in CVE-2016-2088. [RT #41809] The resolver could abort with an assertion failure due to improper DNAME handling when parsing fetch reply messages. This flaw is disclosed in CVE-2016-1286. [RT #41753] Malformed control messages can trigger assertions in named and rndc. This flaw is disclosed in CVE-2016-1285. [RT #41666] Certain errors that could be encountered when printing out or logging an OPT record containing a CLIENT-SUBNET option could be mishandled, resulting in an assertion failure. This flaw is disclosed in CVE-2015-8705. [RT #41397] Specific APL data could trigger an INSIST. This flaw is disclosed in CVE-2015-8704. [RT #41396] Named is potentially vulnerable to the OpenSSL vulnerability described in CVE-2015-3193. Incorrect reference counting could result in an INSIST failure if a socket error occurred while performing a lookup. This flaw is disclosed in CVE-2015-8461. [RT#40945] Insufficient testing when parsing a message allowed records with an incorrect class to be be accepted, triggering a REQUIRE failure when those records were subsequently cached. This flaw is disclosed in CVE-2015-8000. [RT #40987] New Features None. Feature Changes Updated the compiled in addresses for H.ROOT-SERVERS.NET. Bug Fixes Authoritative servers that were marked as bogus (e.g. blackholed in configuration or with invalid addresses) were being queried anyway. [RT #41321] End of Life The end of life for BIND 9.10 is yet to be determined but will not be before BIND 9.12.0 has been released for 6 months. https://www.isc.org/downloads/software-support-policy/ Thank You Thank you to everyone who assisted us in making this release possible. If you would like to contribute to ISC to assist us in continuing to make quality open source software, please visit our donations page at http://www.isc.org/donate/. bind9-9.10.3.dfsg.P4/doc/arm/libdns.xml0000644000470500017500000004265112664710322016722 0ustar lamontlamont BIND 9 DNS Library Support This version of BIND 9 "exports" its internal libraries so that they can be used by third-party applications more easily (we call them "export" libraries in this document). In addition to all major DNS-related APIs BIND 9 is currently using, the export libraries provide the following features: The newly created "DNS client" module. This is a higher level API that provides an interface to name resolution, single DNS transaction with a particular server, and dynamic update. Regarding name resolution, it supports advanced features such as DNSSEC validation and caching. This module supports both synchronous and asynchronous mode. The new "IRS" (Information Retrieval System) library. It provides an interface to parse the traditional resolv.conf file and more advanced, DNS-specific configuration file for the rest of this package (see the description for the dns.conf file below). As part of the IRS library, newly implemented standard address-name mapping functions, getaddrinfo() and getnameinfo(), are provided. They use the DNSSEC-aware validating resolver backend, and could use other advanced features of the BIND 9 libraries such as caching. The getaddrinfo() function resolves both A and AAAA RRs concurrently (when the address family is unspecified). An experimental framework to support other event libraries than BIND 9's internal event task system. Prerequisite GNU make is required to build the export libraries (other part of BIND 9 can still be built with other types of make). In the reminder of this document, "make" means GNU make. Note that in some platforms you may need to invoke a different command name than "make" (e.g. "gmake") to indicate it's GNU make. Compilation $ ./configure --enable-exportlib [other flags] $ make This will create (in addition to usual BIND 9 programs) and a separate set of libraries under the lib/export directory. For example, lib/export/dns/libdns.a is the archive file of the export version of the BIND 9 DNS library. Sample application programs using the libraries will also be built under the lib/export/samples directory (see below). Installation $ cd lib/export $ make install This will install library object files under the directory specified by the --with-export-libdir configure option (default: EPREFIX/lib/bind9), and header files under the directory specified by the --with-export-includedir configure option (default: PREFIX/include/bind9). Root privilege is normally required. "make install" at the top directory will do the same. To see how to build your own application after the installation, see lib/export/samples/Makefile-postinstall.in. Known Defects/Restrictions Currently, win32 is not supported for the export library. (Normal BIND 9 application can be built as before). The "fixed" RRset order is not (currently) supported in the export library. If you want to use "fixed" RRset order for, e.g. named while still building the export library even without the fixed order support, build them separately: $ ./configure --enable-fixed-rrset [other flags, but not --enable-exportlib] $ make $ ./configure --enable-exportlib [other flags, but not --enable-fixed-rrset] $ cd lib/export $ make The client module and the IRS library currently do not support DNSSEC validation using DLV (the underlying modules can handle it, but there is no tunable interface to enable the feature). RFC 5011 is not supported in the validating stub resolver of the export library. In fact, it is not clear whether it should: trust anchors would be a system-wide configuration which would be managed by an administrator, while the stub resolver will be used by ordinary applications run by a normal user. Not all common /etc/resolv.conf options are supported in the IRS library. The only available options in this version are "debug" and "ndots". The dns.conf File The IRS library supports an "advanced" configuration file related to the DNS library for configuration parameters that would be beyond the capability of the resolv.conf file. Specifically, it is intended to provide DNSSEC related configuration parameters. By default the path to this configuration file is /etc/dns.conf. This module is very experimental and the configuration syntax or library interfaces may change in future versions. Currently, only the trusted-keys statement is supported, whose syntax is the same as the same name of statement for named.conf. (See for details.) Sample Applications Some sample application programs using this API are provided for reference. The following is a brief description of these applications. sample: a simple stub resolver utility It sends a query of a given name (of a given optional RR type) to a specified recursive server, and prints the result as a list of RRs. It can also act as a validating stub resolver if a trust anchor is given via a set of command line options. Usage: sample [options] server_address hostname Options and Arguments: -t RRtype specify the RR type of the query. The default is the A RR. [-a algorithm] [-e] -k keyname -K keystring specify a command-line DNS key to validate the answer. For example, to specify the following DNSKEY of example.com: example.com. 3600 IN DNSKEY 257 3 5 xxx specify the options as follows: -e -k example.com -K "xxx" -e means that this key is a zone's "key signing key" (as known as "secure Entry point"). When -a is omitted rsasha1 will be used by default. -s domain:alt_server_address specify a separate recursive server address for the specific "domain". Example: -s example.com:2001:db8::1234 server_address an IP(v4/v6) address of the recursive server to which queries are sent. hostname the domain name for the query sample-async: a simple stub resolver, working asynchronously Similar to "sample", but accepts a list of (query) domain names as a separate file and resolves the names asynchronously. Usage: sample-async [-s server_address] [-t RR_type] input_file Options and Arguments: -s server_address an IPv4 address of the recursive server to which queries are sent. (IPv6 addresses are not supported in this implementation) -t RR_type specify the RR type of the queries. The default is the A RR. input_file a list of domain names to be resolved. each line consists of a single domain name. Example: www.example.com mx.example.net ns.xxx.example sample-request: a simple DNS transaction client It sends a query to a specified server, and prints the response with minimal processing. It doesn't act as a "stub resolver": it stops the processing once it gets any response from the server, whether it's a referral or an alias (CNAME or DNAME) that would require further queries to get the ultimate answer. In other words, this utility acts as a very simplified dig. Usage: sample-request [-t RRtype] server_address hostname Options and Arguments: -t RRtype specify the RR type of the queries. The default is the A RR. server_address an IP(v4/v6) address of the recursive server to which the query is sent. hostname the domain name for the query sample-gai: getaddrinfo() and getnameinfo() test code This is a test program to check getaddrinfo() and getnameinfo() behavior. It takes a host name as an argument, calls getaddrinfo() with the given host name, and calls getnameinfo() with the resulting IP addresses returned by getaddrinfo(). If the dns.conf file exists and defines a trust anchor, the underlying resolver will act as a validating resolver, and getaddrinfo()/getnameinfo() will fail with an EAI_INSECUREDATA error when DNSSEC validation fails. Usage: sample-gai hostname sample-update: a simple dynamic update client program It accepts a single update command as a command-line argument, sends an update request message to the authoritative server, and shows the response from the server. In other words, this is a simplified nsupdate. Usage: sample-update [options] (add|delete) "update data" Options and Arguments: -a auth_server An IP address of the authoritative server that has authority for the zone containing the update name. This should normally be the primary authoritative server that accepts dynamic updates. It can also be a secondary server that is configured to forward update requests to the primary server. -k keyfile A TSIG key file to secure the update transaction. The keyfile format is the same as that for the nsupdate utility. -p prerequisite A prerequisite for the update (only one prerequisite can be specified). The prerequisite format is the same as that is accepted by the nsupdate utility. -r recursive_server An IP address of a recursive server that this utility will use. A recursive server may be necessary to identify the authoritative server address to which the update request is sent. -z zonename The domain name of the zone that contains (add|delete) Specify the type of update operation. Either "add" or "delete" must be specified. "update data" Specify the data to be updated. A typical example of the data would look like "name TTL RRtype RDATA". In practice, either -a or -r must be specified. Others can be optional; the underlying library routine tries to identify the appropriate server and the zone name for the update. Examples: assuming the primary authoritative server of the dynamic.example.com zone has an IPv6 address 2001:db8::1234, $ sample-update -a sample-update -k Kxxx.+nnn+mmmm.key add "foo.dynamic.example.com 30 IN A 192.168.2.1" adds an A RR for foo.dynamic.example.com using the given key. $ sample-update -a sample-update -k Kxxx.+nnn+mmmm.key delete "foo.dynamic.example.com 30 IN A" removes all A RRs for foo.dynamic.example.com using the given key. $ sample-update -a sample-update -k Kxxx.+nnn+mmmm.key delete "foo.dynamic.example.com" removes all RRs for foo.dynamic.example.com using the given key. nsprobe: domain/name server checker in terms of RFC 4074 It checks a set of domains to see the name servers of the domains behave correctly in terms of RFC 4074. This is included in the set of sample programs to show how the export library can be used in a DNS-related application. Usage: nsprobe [-d] [-v [-v...]] [-c cache_address] [input_file] Options -d run in the "debug" mode. with this option nsprobe will dump every RRs it receives. -v increase verbosity of other normal log messages. This can be specified multiple times -c cache_address specify an IP address of a recursive (caching) name server. nsprobe uses this server to get the NS RRset of each domain and the A and/or AAAA RRsets for the name servers. The default value is 127.0.0.1. input_file a file name containing a list of domain (zone) names to be probed. when omitted the standard input will be used. Each line of the input file specifies a single domain name such as "example.com". In general this domain name must be the apex name of some DNS zone (unlike normal "host names" such as "www.example.com"). nsprobe first identifies the NS RRsets for the given domain name, and sends A and AAAA queries to these servers for some "widely used" names under the zone; specifically, adding "www" and "ftp" to the zone name. Library References As of this writing, there is no formal "manual" of the libraries, except this document, header files (some of them provide pretty detailed explanations), and sample application programs. bind9-9.10.3.dfsg.P4/doc/arm/man.dnssec-importkey.html0000644000470500017500000002223212664710322021656 0ustar lamontlamont dnssec-importkey

Name

dnssec-importkey — Import DNSKEY records from external systems so they can be managed.

Synopsis

dnssec-importkey [-K directory] [-L ttl] [-P date/offset] [-D date/offset] [-h] [-v level] [-V] {keyfile}

dnssec-importkey {-f filename} [-K directory] [-L ttl] [-P date/offset] [-D date/offset] [-h] [-v level] [-V] [dnsname]

DESCRIPTION

dnssec-importkey reads a public DNSKEY record and generates a pair of .key/.private files. The DNSKEY record may be read from an existing .key file, in which case a corresponding .private file will be generated, or it may be read from any other file or from the standard input, in which case both .key and .private files will be generated.

The newly-created .private file does not contain private key data, and cannot be used for signing. However, having a .private file makes it possible to set publication (-P) and deletion (-D) times for the key, which means the public key can be added to and removed from the DNSKEY RRset on schedule even if the true private key is stored offline.

OPTIONS

-f filename

Zone file mode: instead of a public keyfile name, the argument is the DNS domain name of a zone master file, which can be read from file. If the domain name is the same as file, then it may be omitted.

If file is set to "-", then the zone data is read from the standard input.

-K directory

Sets the directory in which the key files are to reside.

-L ttl

Sets the default TTL to use for this key when it is converted into a DNSKEY RR. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence. Setting the default TTL to 0 or none removes it.

-h

Emit usage message and exit.

-v level

Sets the debugging level.

-V

Prints version information.

TIMING OPTIONS

Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24-hour days, ignoring leap years), months (defined as 30 24-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To explicitly prevent a date from being set, use 'none' or 'never'.

-P date/offset

Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it.

-D date/offset

Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.)

FILES

A keyfile can be designed by the key identification Knnnn.+aaa+iiiii or the full file name Knnnn.+aaa+iiiii.key as generated by dnssec-keygen(8).

SEE ALSO

dnssec-keygen(8), dnssec-signzone(8), BIND 9 Administrator Reference Manual, RFC 5011.

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/man.delv.html0000644000470500017500000005653212664710322017322 0ustar lamontlamont delv

Name

delv — DNS lookup and validation utility

Synopsis

delv [@server] [-4] [-6] [-a anchor-file] [-b address] [-c class] [-d level] [-i] [-m] [-p port#] [-q name] [-t type] [-x addr] [name] [type] [class] [queryopt...]

delv [-h]

delv [-v]

delv [queryopt...] [query...]

DESCRIPTION

delv (Domain Entity Lookup & Validation) is a tool for sending DNS queries and validating the results, using the the same internal resolver and validator logic as named.

delv will send to a specified name server all queries needed to fetch and validate the requested data; this includes the original requested query, subsequent queries to follow CNAME or DNAME chains, and queries for DNSKEY, DS and DLV records to establish a chain of trust for DNSSEC validation. It does not perform iterative resolution, but simulates the behavior of a name server configured for DNSSEC validating and forwarding.

By default, responses are validated using built-in DNSSEC trust anchors for the root zone (".") and for the ISC DNSSEC lookaside validation zone ("dlv.isc.org"). Records returned by delv are either fully validated or were not signed. If validation fails, an explanation of the failure is included in the output; the validation process can be traced in detail. Because delv does not rely on an external server to carry out validation, it can be used to check the validity of DNS responses in environments where local name servers may not be trustworthy.

Unless it is told to query a specific name server, delv will try each of the servers listed in /etc/resolv.conf. If no usable server addresses are found, delv will send queries to the localhost addresses (127.0.0.1 for IPv4, ::1 for IPv6).

When no command line arguments or options are given, delv will perform an NS query for "." (the root zone).

SIMPLE USAGE

A typical invocation of delv looks like:

 delv @server name type 

where:

server

is the name or IP address of the name server to query. This can be an IPv4 address in dotted-decimal notation or an IPv6 address in colon-delimited notation. When the supplied server argument is a hostname, delv resolves that name before querying that name server (note, however, that this initial lookup is not validated by DNSSEC).

If no server argument is provided, delv consults /etc/resolv.conf; if an address is found there, it queries the name server at that address. If either of the -4 or -6 options are in use, then only addresses for the corresponding transport will be tried. If no usable addresses are found, delv will send queries to the localhost addresses (127.0.0.1 for IPv4, ::1 for IPv6).

name

is the domain name to be looked up.

type

indicates what type of query is required — ANY, A, MX, etc. type can be any valid query type. If no type argument is supplied, delv will perform a lookup for an A record.

OPTIONS

-a anchor-file

Specifies a file from which to read DNSSEC trust anchors. The default is /etc/bind.keys, which is included with BIND 9 and contains trust anchors for the root zone (".") and for the ISC DNSSEC lookaside validation zone ("dlv.isc.org").

Keys that do not match the root or DLV trust-anchor names are ignored; these key names can be overridden using the +dlv=NAME or +root=NAME options.

Note: When reading the trust anchor file, delv treats managed-keys statements and trusted-keys statements identically. That is, for a managed key, it is the initial key that is trusted; RFC 5011 key management is not supported. delv will not consult the managed-keys database maintained by named. This means that if either of the keys in /etc/bind.keys is revoked and rolled over, it will be necessary to update /etc/bind.keys to use DNSSEC validation in delv.

-b address

Sets the source IP address of the query to address. This must be a valid address on one of the host's network interfaces or "0.0.0.0" or "::". An optional source port may be specified by appending "#<port>"

-c class

Sets the query class for the requested data. Currently, only class "IN" is supported in delv and any other value is ignored.

-d level

Set the systemwide debug level to level. The allowed range is from 0 to 99. The default is 0 (no debugging). Debugging traces from delv become more verbose as the debug level increases. See the +mtrace, +rtrace, and +vtrace options below for additional debugging details.

-h

Display the delv help usage output and exit.

-i

Insecure mode. This disables internal DNSSEC validation. (Note, however, this does not set the CD bit on upstream queries. If the server being queried is performing DNSSEC validation, then it will not return invalid data; this can cause delv to time out. When it is necessary to examine invalid data to debug a DNSSEC problem, use dig +cd.)

-m

Enables memory usage debugging.

-p port#

Specifies a destination port to use for queries instead of the standard DNS port number 53. This option would be used with a name server that has been configured to listen for queries on a non-standard port number.

-q name

Sets the query name to name. While the query name can be specified without using the -q, it is sometimes necessary to disambiguate names from types or classes (for example, when looking up the name "ns", which could be misinterpreted as the type NS, or "ch", which could be misinterpreted as class CH).

-t type

Sets the query type to type, which can be any valid query type supported in BIND 9 except for zone transfer types AXFR and IXFR. As with -q, this is useful to distinguish query name type or class when they are ambiguous. it is sometimes necessary to disambiguate names from types.

The default query type is "A", unless the -x option is supplied to indicate a reverse lookup, in which case it is "PTR".

-v

Print the delv version and exit.

-x addr

Performs a reverse lookup, mapping an addresses to a name. addr is an IPv4 address in dotted-decimal notation, or a colon-delimited IPv6 address. When -x is used, there is no need to provide the name or type arguments. delv automatically performs a lookup for a name like 11.12.13.10.in-addr.arpa and sets the query type to PTR. IPv6 addresses are looked up using nibble format under the IP6.ARPA domain.

-4

Forces delv to only use IPv4.

-6

Forces delv to only use IPv6.

QUERY OPTIONS

delv provides a number of query options which affect the way results are displayed, and in some cases the way lookups are performed.

Each query option is identified by a keyword preceded by a plus sign (+). Some keywords set or reset an option. These may be preceded by the string no to negate the meaning of that keyword. Other keywords assign values to options like the timeout interval. They have the form +keyword=value. The query options are:

+[no]cdflag

Controls whether to set the CD (checking disabled) bit in queries sent by delv. This may be useful when troubleshooting DNSSEC problems from behind a validating resolver. A validating resolver will block invalid responses, making it difficult to retrieve them for analysis. Setting the CD flag on queries will cause the resolver to return invalid responses, which delv can then validate internally and report the errors in detail.

+[no]class

Controls whether to display the CLASS when printing a record. The default is to display the CLASS.

+[no]ttl

Controls whether to display the TTL when printing a record. The default is to display the TTL.

+[no]rtrace

Toggle resolver fetch logging. This reports the name and type of each query sent by delv in the process of carrying out the resolution and validation process: this includes including the original query and all subsequent queries to follow CNAMEs and to establish a chain of trust for DNSSEC validation.

This is equivalent to setting the debug level to 1 in the "resolver" logging category. Setting the systemwide debug level to 1 using the -d option will product the same output (but will affect other logging categories as well).

+[no]mtrace

Toggle message logging. This produces a detailed dump of the responses received by delv in the process of carrying out the resolution and validation process.

This is equivalent to setting the debug level to 10 for the the "packets" module of the "resolver" logging category. Setting the systemwide debug level to 10 using the -d option will produce the same output (but will affect other logging categories as well).

+[no]vtrace

Toggle validation logging. This shows the internal process of the validator as it determines whether an answer is validly signed, unsigned, or invalid.

This is equivalent to setting the debug level to 3 for the the "validator" module of the "dnssec" logging category. Setting the systemwide debug level to 3 using the -d option will produce the same output (but will affect other logging categories as well).

+[no]short

Provide a terse answer. The default is to print the answer in a verbose form.

+[no]comments

Toggle the display of comment lines in the output. The default is to print comments.

+[no]rrcomments

Toggle the display of per-record comments in the output (for example, human-readable key information about DNSKEY records). The default is to print per-record comments.

+[no]crypto

Toggle the display of cryptographic fields in DNSSEC records. The contents of these field are unnecessary to debug most DNSSEC validation failures and removing them makes it easier to see the common failures. The default is to display the fields. When omitted they are replaced by the string "[omitted]" or in the DNSKEY case the key id is displayed as the replacement, e.g. "[ key id = value ]".

+[no]trust

Controls whether to display the trust level when printing a record. The default is to display the trust level.

+[no]split[=W]

Split long hex- or base64-formatted fields in resource records into chunks of W characters (where W is rounded up to the nearest multiple of 4). +nosplit or +split=0 causes fields not to be split at all. The default is 56 characters, or 44 characters when multiline mode is active.

+[no]all

Set or clear the display options +[no]comments, +[no]rrcomments, and +[no]trust as a group.

+[no]multiline

Print long records (such as RRSIG, DNSKEY, and SOA records) in a verbose multi-line format with human-readable comments. The default is to print each record on a single line, to facilitate machine parsing of the delv output.

+[no]dnssec

Indicates whether to display RRSIG records in the delv output. The default is to do so. Note that (unlike in dig) this does not control whether to request DNSSEC records or whether to validate them. DNSSEC records are always requested, and validation will always occur unless suppressed by the use of -i or +noroot and +nodlv.

+[no]root[=ROOT]

Indicates whether to perform conventional (non-lookaside) DNSSEC validation, and if so, specifies the name of a trust anchor. The default is to validate using a trust anchor of "." (the root zone), for which there is a built-in key. If specifying a different trust anchor, then -a must be used to specify a file containing the key.

+[no]dlv[=DLV]

Indicates whether to perform DNSSEC lookaside validation, and if so, specifies the name of the DLV trust anchor. The default is to perform lookaside validation using a trust anchor of "dlv.isc.org", for which there is a built-in key. If specifying a different name, then -a must be used to specify a file containing the DLV key.

FILES

/etc/bind.keys

/etc/resolv.conf

SEE ALSO

dig(1), named(8), RFC4034, RFC4035, RFC4431, RFC5074, RFC5155.

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/Bv9ARM.html0000644000470500017500000006552612664710322016621 0ustar lamontlamont BIND 9 Administrator Reference Manual

BIND 9 Administrator Reference Manual

BIND Version 9.10.3-P4


Table of Contents

1. Introduction
Scope of Document
Organization of This Document
Conventions Used in This Document
The Domain Name System (DNS)
DNS Fundamentals
Domains and Domain Names
Zones
Authoritative Name Servers
Caching Name Servers
Name Servers in Multiple Roles
2. BIND Resource Requirements
Hardware requirements
CPU Requirements
Memory Requirements
Name Server Intensive Environment Issues
Supported Operating Systems
3. Name Server Configuration
Sample Configurations
A Caching-only Name Server
An Authoritative-only Name Server
Load Balancing
Name Server Operations
Tools for Use With the Name Server Daemon
Signals
4. Advanced DNS Features
Notify
Dynamic Update
The journal file
Incremental Zone Transfers (IXFR)
Split DNS
Example split DNS setup
TSIG
Generate Shared Keys for Each Pair of Hosts
Copying the Shared Secret to Both Machines
Informing the Servers of the Key's Existence
Instructing the Server to Use the Key
TSIG Key Based Access Control
Errors
TKEY
SIG(0)
DNSSEC
Generating Keys
Signing the Zone
Configuring Servers
DNSSEC, Dynamic Zones, and Automatic Signing
Converting from insecure to secure
Dynamic DNS update method
Fully automatic zone signing
Private-type records
DNSKEY rollovers
Dynamic DNS update method
Automatic key rollovers
NSEC3PARAM rollovers via UPDATE
Converting from NSEC to NSEC3
Converting from NSEC3 to NSEC
Converting from secure to insecure
Periodic re-signing
NSEC3 and OPTOUT
Dynamic Trust Anchor Management
Validating Resolver
Authoritative Server
PKCS#11 (Cryptoki) support
Prerequisites
Native PKCS#11
OpenSSL-based PKCS#11
PKCS#11 Tools
Using the HSM
Specifying the engine on the command line
Running named with automatic zone re-signing
DLZ (Dynamically Loadable Zones)
Configuring DLZ
Sample DLZ Driver
IPv6 Support in BIND 9
Address Lookups Using AAAA Records
Address to Name Lookups Using Nibble Format
5. The BIND 9 Lightweight Resolver
The Lightweight Resolver Library
Running a Resolver Daemon
6. BIND 9 Configuration Reference
Configuration File Elements
Address Match Lists
Comment Syntax
Configuration File Grammar
acl Statement Grammar
acl Statement Definition and Usage
controls Statement Grammar
controls Statement Definition and Usage
include Statement Grammar
include Statement Definition and Usage
key Statement Grammar
key Statement Definition and Usage
logging Statement Grammar
logging Statement Definition and Usage
lwres Statement Grammar
lwres Statement Definition and Usage
masters Statement Grammar
masters Statement Definition and Usage
options Statement Grammar
options Statement Definition and Usage
server Statement Grammar
server Statement Definition and Usage
statistics-channels Statement Grammar
statistics-channels Statement Definition and Usage
trusted-keys Statement Grammar
trusted-keys Statement Definition and Usage
managed-keys Statement Grammar
managed-keys Statement Definition and Usage
view Statement Grammar
view Statement Definition and Usage
zone Statement Grammar
zone Statement Definition and Usage
Zone File
Types of Resource Records and When to Use Them
Discussion of MX Records
Setting TTLs
Inverse Mapping in IPv4
Other Zone File Directives
BIND Master File Extension: the $GENERATE Directive
Additional File Formats
BIND9 Statistics
Statistics Counters
7. BIND 9 Security Considerations
Access Control Lists
Chroot and Setuid
The chroot Environment
Using the setuid Function
Dynamic Update Security
8. Troubleshooting
Common Problems
It's not working; how can I figure out what's wrong?
Incrementing and Changing the Serial Number
Where Can I Get Help?
A. Release Notes
Release Notes for BIND Version 9.10.3-P4
Introduction
Download
Security Fixes
New Features
Feature Changes
Bug Fixes
End of Life
Thank You
B. A Brief History of the DNS and BIND
C. General DNS Reference Information
IPv6 addresses (AAAA)
Bibliography (and Suggested Reading)
Request for Comments (RFCs)
Internet Drafts
Other Documents About BIND
D. BIND 9 DNS Library Support
BIND 9 DNS Library Support
Prerequisite
Compilation
Installation
Known Defects/Restrictions
The dns.conf File
Sample Applications
Library References
I. Manual pages
dig — DNS lookup utility
host — DNS lookup utility
delv — DNS lookup and validation utility
dnssec-checkds — A DNSSEC delegation consistency checking tool.
dnssec-coverage — checks future DNSKEY coverage for a zone
dnssec-dsfromkey — DNSSEC DS RR generation tool
dnssec-importkey — Import DNSKEY records from external systems so they can be managed.
dnssec-keyfromlabel — DNSSEC key generation tool
dnssec-keygen — DNSSEC key generation tool
dnssec-revoke — Set the REVOKED bit on a DNSSEC key
dnssec-settime — Set the key timing metadata for a DNSSEC key
dnssec-signzone — DNSSEC zone signing tool
dnssec-verify — DNSSEC zone verification tool
named-checkconf — named configuration file syntax checking tool
named-checkzone — zone file validity checking or converting tool
named — Internet domain name server
named-journalprint — print zone journal in human-readable form
named-rrchecker — A syntax checker for individual DNS resource records
nsupdate — Dynamic DNS update utility
rndc — name server control utility
rndc.conf — rndc configuration file
rndc-confgen — rndc key generation tool
ddns-confgen — ddns key generation tool
arpaname — translate IP addresses to the corresponding ARPA names
genrandom — generate a file containing random data
isc-hmac-fixup — fixes HMAC keys generated by older versions of BIND
nsec3hash — generate NSEC3 hash

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/isc-logo.eps0000644000470500017500000177021512664710322017157 0ustar lamontlamont%!PS-Adobe-3.1 EPSF-3.0 %ADO_DSC_Encoding: MacOS Roman %%Title: ISC_logo_only_RGB.eps %%Creator: Adobe Illustrator(R) 13.0 %%For: Brian Reid %%CreationDate: 3/25/10 %%BoundingBox: 0 0 118 46 %%HiResBoundingBox: 0 0 117.9991 45.0176 %%CropBox: 0 0 117.9991 45.0176 %%LanguageLevel: 2 %%DocumentData: Clean7Bit %ADOBeginClientInjection: DocumentHeader "AI11EPS" %%AI8_CreatorVersion: 13.0.2 %AI9_PrintingDataBegin %ADO_BuildNumber: Adobe Illustrator(R) 13.0.2 x434 R agm 4.4379 ct 5.1039 %ADO_ContainsXMP: MainFirst %ADOEndClientInjection: DocumentHeader "AI11EPS" %%Pages: 1 %%DocumentNeededResources: %%DocumentSuppliedResources: procset Adobe_AGM_Image 1.0 0 %%+ procset Adobe_CoolType_Utility_T42 1.0 0 %%+ procset Adobe_CoolType_Utility_MAKEOCF 1.23 0 %%+ procset Adobe_CoolType_Core 2.31 0 %%+ procset Adobe_AGM_Core 2.0 0 %%+ procset Adobe_AGM_Utils 1.0 0 %%DocumentFonts: %%DocumentNeededFonts: %%DocumentNeededFeatures: %%DocumentSuppliedFeatures: %%DocumentCustomColors: %%CMYKCustomColor: %%RGBCustomColor: %%EndComments %%BeginDefaults %%ViewingOrientation: 1 0 0 1 %%EndDefaults %%BeginProlog %%BeginResource: procset Adobe_AGM_Utils 1.0 0 %%Version: 1.0 0 %%Copyright: Copyright(C)2000-2006 Adobe Systems, Inc. All Rights Reserved. systemdict/setpacking known {currentpacking true setpacking}if userdict/Adobe_AGM_Utils 73 dict dup begin put /bdf {bind def}bind def /nd{null def}bdf /xdf {exch def}bdf /ldf {load def}bdf /ddf {put}bdf /xddf {3 -1 roll put}bdf /xpt {exch put}bdf /ndf { exch dup where{ pop pop pop }{ xdf }ifelse }def /cdndf { exch dup currentdict exch known{ pop pop }{ exch def }ifelse }def /gx {get exec}bdf /ps_level /languagelevel where{ pop systemdict/languagelevel gx }{ 1 }ifelse def /level2 ps_level 2 ge def /level3 ps_level 3 ge def /ps_version {version cvr}stopped{-1}if def /set_gvm {currentglobal exch setglobal}bdf /reset_gvm {setglobal}bdf /makereadonlyarray { /packedarray where{pop packedarray }{ array astore readonly}ifelse }bdf /map_reserved_ink_name { dup type/stringtype eq{ dup/Red eq{ pop(_Red_) }{ dup/Green eq{ pop(_Green_) }{ dup/Blue eq{ pop(_Blue_) }{ dup()cvn eq{ pop(Process) }if }ifelse }ifelse }ifelse }if }bdf /AGMUTIL_GSTATE 22 dict def /get_gstate { AGMUTIL_GSTATE begin /AGMUTIL_GSTATE_clr_spc currentcolorspace def /AGMUTIL_GSTATE_clr_indx 0 def /AGMUTIL_GSTATE_clr_comps 12 array def mark currentcolor counttomark {AGMUTIL_GSTATE_clr_comps AGMUTIL_GSTATE_clr_indx 3 -1 roll put /AGMUTIL_GSTATE_clr_indx AGMUTIL_GSTATE_clr_indx 1 add def}repeat pop /AGMUTIL_GSTATE_fnt rootfont def /AGMUTIL_GSTATE_lw currentlinewidth def /AGMUTIL_GSTATE_lc currentlinecap def /AGMUTIL_GSTATE_lj currentlinejoin def /AGMUTIL_GSTATE_ml currentmiterlimit def currentdash/AGMUTIL_GSTATE_do xdf/AGMUTIL_GSTATE_da xdf /AGMUTIL_GSTATE_sa currentstrokeadjust def /AGMUTIL_GSTATE_clr_rnd currentcolorrendering def /AGMUTIL_GSTATE_op currentoverprint def /AGMUTIL_GSTATE_bg currentblackgeneration cvlit def /AGMUTIL_GSTATE_ucr currentundercolorremoval cvlit def currentcolortransfer cvlit/AGMUTIL_GSTATE_gy_xfer xdf cvlit/AGMUTIL_GSTATE_b_xfer xdf cvlit/AGMUTIL_GSTATE_g_xfer xdf cvlit/AGMUTIL_GSTATE_r_xfer xdf /AGMUTIL_GSTATE_ht currenthalftone def /AGMUTIL_GSTATE_flt currentflat def end }def /set_gstate { AGMUTIL_GSTATE begin AGMUTIL_GSTATE_clr_spc setcolorspace AGMUTIL_GSTATE_clr_indx{AGMUTIL_GSTATE_clr_comps AGMUTIL_GSTATE_clr_indx 1 sub get /AGMUTIL_GSTATE_clr_indx AGMUTIL_GSTATE_clr_indx 1 sub def}repeat setcolor AGMUTIL_GSTATE_fnt setfont AGMUTIL_GSTATE_lw setlinewidth AGMUTIL_GSTATE_lc setlinecap AGMUTIL_GSTATE_lj setlinejoin AGMUTIL_GSTATE_ml setmiterlimit AGMUTIL_GSTATE_da AGMUTIL_GSTATE_do setdash AGMUTIL_GSTATE_sa setstrokeadjust AGMUTIL_GSTATE_clr_rnd setcolorrendering AGMUTIL_GSTATE_op setoverprint AGMUTIL_GSTATE_bg cvx setblackgeneration AGMUTIL_GSTATE_ucr cvx setundercolorremoval AGMUTIL_GSTATE_r_xfer cvx AGMUTIL_GSTATE_g_xfer cvx AGMUTIL_GSTATE_b_xfer cvx AGMUTIL_GSTATE_gy_xfer cvx setcolortransfer AGMUTIL_GSTATE_ht/HalftoneType get dup 9 eq exch 100 eq or { currenthalftone/HalftoneType get AGMUTIL_GSTATE_ht/HalftoneType get ne { mark AGMUTIL_GSTATE_ht{sethalftone}stopped cleartomark }if }{ AGMUTIL_GSTATE_ht sethalftone }ifelse AGMUTIL_GSTATE_flt setflat end }def /get_gstate_and_matrix { AGMUTIL_GSTATE begin /AGMUTIL_GSTATE_ctm matrix currentmatrix def end get_gstate }def /set_gstate_and_matrix { set_gstate AGMUTIL_GSTATE begin AGMUTIL_GSTATE_ctm setmatrix end }def /AGMUTIL_str256 256 string def /AGMUTIL_src256 256 string def /AGMUTIL_dst64 64 string def /AGMUTIL_srcLen nd /AGMUTIL_ndx nd /AGMUTIL_cpd nd /capture_cpd{ //Adobe_AGM_Utils/AGMUTIL_cpd currentpagedevice ddf }def /thold_halftone { level3 {sethalftone currenthalftone} { dup/HalftoneType get 3 eq { sethalftone currenthalftone }{ begin Width Height mul{ Thresholds read{pop}if }repeat end currenthalftone }ifelse }ifelse }def /rdcmntline { currentfile AGMUTIL_str256 readline pop (%)anchorsearch{pop}if }bdf /filter_cmyk { dup type/filetype ne{ exch()/SubFileDecode filter }{ exch pop } ifelse [ exch { AGMUTIL_src256 readstring pop dup length/AGMUTIL_srcLen exch def /AGMUTIL_ndx 0 def AGMCORE_plate_ndx 4 AGMUTIL_srcLen 1 sub{ 1 index exch get AGMUTIL_dst64 AGMUTIL_ndx 3 -1 roll put /AGMUTIL_ndx AGMUTIL_ndx 1 add def }for pop AGMUTIL_dst64 0 AGMUTIL_ndx getinterval } bind /exec cvx ]cvx }bdf /filter_indexed_devn { cvi Names length mul names_index add Lookup exch get }bdf /filter_devn { 4 dict begin /srcStr xdf /dstStr xdf dup type/filetype ne{ 0()/SubFileDecode filter }if [ exch [ /devicen_colorspace_dict/AGMCORE_gget cvx/begin cvx currentdict/srcStr get/readstring cvx/pop cvx /dup cvx/length cvx 0/gt cvx[ Adobe_AGM_Utils/AGMUTIL_ndx 0/ddf cvx names_index Names length currentdict/srcStr get length 1 sub{ 1/index cvx/exch cvx/get cvx currentdict/dstStr get/AGMUTIL_ndx/load cvx 3 -1/roll cvx/put cvx Adobe_AGM_Utils/AGMUTIL_ndx/AGMUTIL_ndx/load cvx 1/add cvx/ddf cvx }for currentdict/dstStr get 0/AGMUTIL_ndx/load cvx/getinterval cvx ]cvx/if cvx /end cvx ]cvx bind /exec cvx ]cvx end }bdf /AGMUTIL_imagefile nd /read_image_file { AGMUTIL_imagefile 0 setfileposition 10 dict begin /imageDict xdf /imbufLen Width BitsPerComponent mul 7 add 8 idiv def /imbufIdx 0 def /origDataSource imageDict/DataSource get def /origMultipleDataSources imageDict/MultipleDataSources get def /origDecode imageDict/Decode get def /dstDataStr imageDict/Width get colorSpaceElemCnt mul string def imageDict/MultipleDataSources known{MultipleDataSources}{false}ifelse { /imbufCnt imageDict/DataSource get length def /imbufs imbufCnt array def 0 1 imbufCnt 1 sub{ /imbufIdx xdf imbufs imbufIdx imbufLen string put imageDict/DataSource get imbufIdx[AGMUTIL_imagefile imbufs imbufIdx get/readstring cvx/pop cvx]cvx put }for DeviceN_PS2{ imageDict begin /DataSource[DataSource/devn_sep_datasource cvx]cvx def /MultipleDataSources false def /Decode[0 1]def end }if }{ /imbuf imbufLen string def Indexed_DeviceN level3 not and DeviceN_NoneName or{ /srcDataStrs[imageDict begin currentdict/MultipleDataSources known{MultipleDataSources{DataSource length}{1}ifelse}{1}ifelse { Width Decode length 2 div mul cvi string }repeat end]def imageDict begin /DataSource[AGMUTIL_imagefile Decode BitsPerComponent false 1/filter_indexed_devn load dstDataStr srcDataStrs devn_alt_datasource/exec cvx]cvx def /Decode[0 1]def end }{ imageDict/DataSource[1 string dup 0 AGMUTIL_imagefile Decode length 2 idiv string/readstring cvx/pop cvx names_index/get cvx/put cvx]cvx put imageDict/Decode[0 1]put }ifelse }ifelse imageDict exch load exec imageDict/DataSource origDataSource put imageDict/MultipleDataSources origMultipleDataSources put imageDict/Decode origDecode put end }bdf /write_image_file { begin {(AGMUTIL_imagefile)(w+)file}stopped{ false }{ Adobe_AGM_Utils/AGMUTIL_imagefile xddf 2 dict begin /imbufLen Width BitsPerComponent mul 7 add 8 idiv def MultipleDataSources{DataSource 0 get}{DataSource}ifelse type/filetype eq{ /imbuf imbufLen string def }if 1 1 Height MultipleDataSources not{Decode length 2 idiv mul}if{ pop MultipleDataSources{ 0 1 DataSource length 1 sub{ DataSource type dup /arraytype eq{ pop DataSource exch gx }{ /filetype eq{ DataSource exch get imbuf readstring pop }{ DataSource exch get }ifelse }ifelse AGMUTIL_imagefile exch writestring }for }{ DataSource type dup /arraytype eq{ pop DataSource exec }{ /filetype eq{ DataSource imbuf readstring pop }{ DataSource }ifelse }ifelse AGMUTIL_imagefile exch writestring }ifelse }for end true }ifelse end }bdf /close_image_file { AGMUTIL_imagefile closefile(AGMUTIL_imagefile)deletefile }def statusdict/product known userdict/AGMP_current_show known not and{ /pstr statusdict/product get def pstr(HP LaserJet 2200)eq pstr(HP LaserJet 4000 Series)eq or pstr(HP LaserJet 4050 Series )eq or pstr(HP LaserJet 8000 Series)eq or pstr(HP LaserJet 8100 Series)eq or pstr(HP LaserJet 8150 Series)eq or pstr(HP LaserJet 5000 Series)eq or pstr(HP LaserJet 5100 Series)eq or pstr(HP Color LaserJet 4500)eq or pstr(HP Color LaserJet 4600)eq or pstr(HP LaserJet 5Si)eq or pstr(HP LaserJet 1200 Series)eq or pstr(HP LaserJet 1300 Series)eq or pstr(HP LaserJet 4100 Series)eq or { userdict/AGMP_current_show/show load put userdict/show{ currentcolorspace 0 get /Pattern eq {false charpath f} {AGMP_current_show}ifelse }put }if currentdict/pstr undef }if /consumeimagedata { begin AGMIMG_init_common currentdict/MultipleDataSources known not {/MultipleDataSources false def}if MultipleDataSources { DataSource 0 get type dup/filetype eq { 1 dict begin /flushbuffer Width cvi string def 1 1 Height cvi { pop 0 1 DataSource length 1 sub { DataSource exch get flushbuffer readstring pop pop }for }for end }if dup/arraytype eq exch/packedarraytype eq or DataSource 0 get xcheck and { Width Height mul cvi { 0 1 DataSource length 1 sub {dup DataSource exch gx length exch 0 ne{pop}if}for dup 0 eq {pop exit}if sub dup 0 le {exit}if }loop pop }if } { /DataSource load type dup/filetype eq { 1 dict begin /flushbuffer Width Decode length 2 idiv mul cvi string def 1 1 Height{pop DataSource flushbuffer readstring pop pop}for end }if dup/arraytype eq exch/packedarraytype eq or/DataSource load xcheck and { Height Width BitsPerComponent mul 8 BitsPerComponent sub add 8 idiv Decode length 2 idiv mul mul { DataSource length dup 0 eq {pop exit}if sub dup 0 le {exit}if }loop pop }if }ifelse end }bdf /addprocs { 2{/exec load}repeat 3 1 roll [5 1 roll]bind cvx }def /modify_halftone_xfer { currenthalftone dup length dict copy begin currentdict 2 index known{ 1 index load dup length dict copy begin currentdict/TransferFunction known{ /TransferFunction load }{ currenttransfer }ifelse addprocs/TransferFunction xdf currentdict end def currentdict end sethalftone }{ currentdict/TransferFunction known{ /TransferFunction load }{ currenttransfer }ifelse addprocs/TransferFunction xdf currentdict end sethalftone pop }ifelse }def /clonearray { dup xcheck exch dup length array exch Adobe_AGM_Core/AGMCORE_tmp -1 ddf { Adobe_AGM_Core/AGMCORE_tmp 2 copy get 1 add ddf dup type/dicttype eq { Adobe_AGM_Core/AGMCORE_tmp get exch clonedict Adobe_AGM_Core/AGMCORE_tmp 4 -1 roll ddf }if dup type/arraytype eq { Adobe_AGM_Core/AGMCORE_tmp get exch clonearray Adobe_AGM_Core/AGMCORE_tmp 4 -1 roll ddf }if exch dup Adobe_AGM_Core/AGMCORE_tmp get 4 -1 roll put }forall exch{cvx}if }bdf /clonedict { dup length dict begin { dup type/dicttype eq {clonedict}if dup type/arraytype eq {clonearray}if def }forall currentdict end }bdf /DeviceN_PS2 { /currentcolorspace AGMCORE_gget 0 get/DeviceN eq level3 not and }bdf /Indexed_DeviceN { /indexed_colorspace_dict AGMCORE_gget dup null ne{ dup/CSDBase known{ /CSDBase get/CSD get_res/Names known }{ pop false }ifelse }{ pop false }ifelse }bdf /DeviceN_NoneName { /Names where{ pop false Names { (None)eq or }forall }{ false }ifelse }bdf /DeviceN_PS2_inRip_seps { /AGMCORE_in_rip_sep where { pop dup type dup/arraytype eq exch/packedarraytype eq or { dup 0 get/DeviceN eq level3 not and AGMCORE_in_rip_sep and { /currentcolorspace exch AGMCORE_gput false }{ true }ifelse }{ true }ifelse }{ true }ifelse }bdf /base_colorspace_type { dup type/arraytype eq{0 get}if }bdf /currentdistillerparams where{pop currentdistillerparams/CoreDistVersion get 5000 lt}{true}ifelse { /pdfmark_5{cleartomark}bind def }{ /pdfmark_5{pdfmark}bind def }ifelse /ReadBypdfmark_5 { currentfile exch 0 exch/SubFileDecode filter /currentdistillerparams where {pop currentdistillerparams/CoreDistVersion get 5000 lt}{true}ifelse {flushfile cleartomark} {/PUT pdfmark}ifelse }bdf /xpdfm { { dup 0 get/Label eq { aload length[exch 1 add 1 roll/PAGELABEL }{ aload pop [{ThisPage}<<5 -2 roll>>/PUT }ifelse pdfmark_5 }forall }bdf /ds{ Adobe_AGM_Utils begin }bdf /dt{ currentdict Adobe_AGM_Utils eq{ end }if }bdf systemdict/setpacking known {setpacking}if %%EndResource %%BeginResource: procset Adobe_AGM_Core 2.0 0 %%Version: 2.0 0 %%Copyright: Copyright(C)1997-2007 Adobe Systems, Inc. All Rights Reserved. systemdict/setpacking known { currentpacking true setpacking }if userdict/Adobe_AGM_Core 209 dict dup begin put /Adobe_AGM_Core_Id/Adobe_AGM_Core_2.0_0 def /AGMCORE_str256 256 string def /AGMCORE_save nd /AGMCORE_graphicsave nd /AGMCORE_c 0 def /AGMCORE_m 0 def /AGMCORE_y 0 def /AGMCORE_k 0 def /AGMCORE_cmykbuf 4 array def /AGMCORE_screen[currentscreen]cvx def /AGMCORE_tmp 0 def /AGMCORE_&setgray nd /AGMCORE_&setcolor nd /AGMCORE_&setcolorspace nd /AGMCORE_&setcmykcolor nd /AGMCORE_cyan_plate nd /AGMCORE_magenta_plate nd /AGMCORE_yellow_plate nd /AGMCORE_black_plate nd /AGMCORE_plate_ndx nd /AGMCORE_get_ink_data nd /AGMCORE_is_cmyk_sep nd /AGMCORE_host_sep nd /AGMCORE_avoid_L2_sep_space nd /AGMCORE_distilling nd /AGMCORE_composite_job nd /AGMCORE_producing_seps nd /AGMCORE_ps_level -1 def /AGMCORE_ps_version -1 def /AGMCORE_environ_ok nd /AGMCORE_CSD_cache 0 dict def /AGMCORE_currentoverprint false def /AGMCORE_deltaX nd /AGMCORE_deltaY nd /AGMCORE_name nd /AGMCORE_sep_special nd /AGMCORE_err_strings 4 dict def /AGMCORE_cur_err nd /AGMCORE_current_spot_alias false def /AGMCORE_inverting false def /AGMCORE_feature_dictCount nd /AGMCORE_feature_opCount nd /AGMCORE_feature_ctm nd /AGMCORE_ConvertToProcess false def /AGMCORE_Default_CTM matrix def /AGMCORE_Default_PageSize nd /AGMCORE_Default_flatness nd /AGMCORE_currentbg nd /AGMCORE_currentucr nd /AGMCORE_pattern_paint_type 0 def /knockout_unitsq nd currentglobal true setglobal [/CSA/Gradient/Procedure] { /Generic/Category findresource dup length dict copy/Category defineresource pop }forall setglobal /AGMCORE_key_known { where{ /Adobe_AGM_Core_Id known }{ false }ifelse }ndf /flushinput { save 2 dict begin /CompareBuffer 3 -1 roll def /readbuffer 256 string def mark { currentfile readbuffer{readline}stopped {cleartomark mark} { not {pop exit} if CompareBuffer eq {exit} if }ifelse }loop cleartomark end restore }bdf /getspotfunction { AGMCORE_screen exch pop exch pop dup type/dicttype eq{ dup/HalftoneType get 1 eq{ /SpotFunction get }{ dup/HalftoneType get 2 eq{ /GraySpotFunction get }{ pop { abs exch abs 2 copy add 1 gt{ 1 sub dup mul exch 1 sub dup mul add 1 sub }{ dup mul exch dup mul add 1 exch sub }ifelse }bind }ifelse }ifelse }if }def /np {newpath}bdf /clp_npth {clip np}def /eoclp_npth {eoclip np}def /npth_clp {np clip}def /graphic_setup { /AGMCORE_graphicsave save store concat 0 setgray 0 setlinecap 0 setlinejoin 1 setlinewidth []0 setdash 10 setmiterlimit np false setoverprint false setstrokeadjust //Adobe_AGM_Core/spot_alias gx /Adobe_AGM_Image where{ pop Adobe_AGM_Image/spot_alias 2 copy known{ gx }{ pop pop }ifelse }if /sep_colorspace_dict null AGMCORE_gput 100 dict begin /dictstackcount countdictstack def /showpage{}def mark }def /graphic_cleanup { cleartomark dictstackcount 1 countdictstack 1 sub{end}for end AGMCORE_graphicsave restore }def /compose_error_msg { grestoreall initgraphics /Helvetica findfont 10 scalefont setfont /AGMCORE_deltaY 100 def /AGMCORE_deltaX 310 def clippath pathbbox np pop pop 36 add exch 36 add exch moveto 0 AGMCORE_deltaY rlineto AGMCORE_deltaX 0 rlineto 0 AGMCORE_deltaY neg rlineto AGMCORE_deltaX neg 0 rlineto closepath 0 AGMCORE_&setgray gsave 1 AGMCORE_&setgray fill grestore 1 setlinewidth gsave stroke grestore currentpoint AGMCORE_deltaY 15 sub add exch 8 add exch moveto /AGMCORE_deltaY 12 def /AGMCORE_tmp 0 def AGMCORE_err_strings exch get { dup 32 eq { pop AGMCORE_str256 0 AGMCORE_tmp getinterval stringwidth pop currentpoint pop add AGMCORE_deltaX 28 add gt { currentpoint AGMCORE_deltaY sub exch pop clippath pathbbox pop pop pop 44 add exch moveto }if AGMCORE_str256 0 AGMCORE_tmp getinterval show( )show 0 1 AGMCORE_str256 length 1 sub { AGMCORE_str256 exch 0 put }for /AGMCORE_tmp 0 def }{ AGMCORE_str256 exch AGMCORE_tmp xpt /AGMCORE_tmp AGMCORE_tmp 1 add def }ifelse }forall }bdf /AGMCORE_CMYKDeviceNColorspaces[ [/Separation/None/DeviceCMYK{0 0 0}] [/Separation(Black)/DeviceCMYK{0 0 0 4 -1 roll}bind] [/Separation(Yellow)/DeviceCMYK{0 0 3 -1 roll 0}bind] [/DeviceN[(Yellow)(Black)]/DeviceCMYK{0 0 4 2 roll}bind] [/Separation(Magenta)/DeviceCMYK{0 exch 0 0}bind] [/DeviceN[(Magenta)(Black)]/DeviceCMYK{0 3 1 roll 0 exch}bind] [/DeviceN[(Magenta)(Yellow)]/DeviceCMYK{0 3 1 roll 0}bind] [/DeviceN[(Magenta)(Yellow)(Black)]/DeviceCMYK{0 4 1 roll}bind] [/Separation(Cyan)/DeviceCMYK{0 0 0}] [/DeviceN[(Cyan)(Black)]/DeviceCMYK{0 0 3 -1 roll}bind] [/DeviceN[(Cyan)(Yellow)]/DeviceCMYK{0 exch 0}bind] [/DeviceN[(Cyan)(Yellow)(Black)]/DeviceCMYK{0 3 1 roll}bind] [/DeviceN[(Cyan)(Magenta)]/DeviceCMYK{0 0}] [/DeviceN[(Cyan)(Magenta)(Black)]/DeviceCMYK{0 exch}bind] [/DeviceN[(Cyan)(Magenta)(Yellow)]/DeviceCMYK{0}] [/DeviceCMYK] ]def /ds{ Adobe_AGM_Core begin /currentdistillerparams where { pop currentdistillerparams/CoreDistVersion get 5000 lt {<>setdistillerparams}if }if /AGMCORE_ps_version xdf /AGMCORE_ps_level xdf errordict/AGM_handleerror known not{ errordict/AGM_handleerror errordict/handleerror get put errordict/handleerror{ Adobe_AGM_Core begin $error/newerror get AGMCORE_cur_err null ne and{ $error/newerror false put AGMCORE_cur_err compose_error_msg }if $error/newerror true put end errordict/AGM_handleerror get exec }bind put }if /AGMCORE_environ_ok ps_level AGMCORE_ps_level ge ps_version AGMCORE_ps_version ge and AGMCORE_ps_level -1 eq or def AGMCORE_environ_ok not {/AGMCORE_cur_err/AGMCORE_bad_environ def}if /AGMCORE_&setgray systemdict/setgray get def level2{ /AGMCORE_&setcolor systemdict/setcolor get def /AGMCORE_&setcolorspace systemdict/setcolorspace get def }if /AGMCORE_currentbg currentblackgeneration def /AGMCORE_currentucr currentundercolorremoval def /AGMCORE_Default_flatness currentflat def /AGMCORE_distilling /product where{ pop systemdict/setdistillerparams known product(Adobe PostScript Parser)ne and }{ false }ifelse def /AGMCORE_GSTATE AGMCORE_key_known not{ /AGMCORE_GSTATE 21 dict def /AGMCORE_tmpmatrix matrix def /AGMCORE_gstack 32 array def /AGMCORE_gstackptr 0 def /AGMCORE_gstacksaveptr 0 def /AGMCORE_gstackframekeys 14 def /AGMCORE_&gsave/gsave ldf /AGMCORE_&grestore/grestore ldf /AGMCORE_&grestoreall/grestoreall ldf /AGMCORE_&save/save ldf /AGMCORE_&setoverprint/setoverprint ldf /AGMCORE_gdictcopy{ begin {def}forall end }def /AGMCORE_gput{ AGMCORE_gstack AGMCORE_gstackptr get 3 1 roll put }def /AGMCORE_gget{ AGMCORE_gstack AGMCORE_gstackptr get exch get }def /gsave{ AGMCORE_&gsave AGMCORE_gstack AGMCORE_gstackptr get AGMCORE_gstackptr 1 add dup 32 ge{limitcheck}if /AGMCORE_gstackptr exch store AGMCORE_gstack AGMCORE_gstackptr get AGMCORE_gdictcopy }def /grestore{ AGMCORE_&grestore AGMCORE_gstackptr 1 sub dup AGMCORE_gstacksaveptr lt{1 add}if dup AGMCORE_gstack exch get dup/AGMCORE_currentoverprint known {/AGMCORE_currentoverprint get setoverprint}{pop}ifelse /AGMCORE_gstackptr exch store }def /grestoreall{ AGMCORE_&grestoreall /AGMCORE_gstackptr AGMCORE_gstacksaveptr store }def /save{ AGMCORE_&save AGMCORE_gstack AGMCORE_gstackptr get AGMCORE_gstackptr 1 add dup 32 ge{limitcheck}if /AGMCORE_gstackptr exch store /AGMCORE_gstacksaveptr AGMCORE_gstackptr store AGMCORE_gstack AGMCORE_gstackptr get AGMCORE_gdictcopy }def /setoverprint{ dup/AGMCORE_currentoverprint exch AGMCORE_gput AGMCORE_&setoverprint }def 0 1 AGMCORE_gstack length 1 sub{ AGMCORE_gstack exch AGMCORE_gstackframekeys dict put }for }if level3/AGMCORE_&sysshfill AGMCORE_key_known not and { /AGMCORE_&sysshfill systemdict/shfill get def /AGMCORE_&sysmakepattern systemdict/makepattern get def /AGMCORE_&usrmakepattern/makepattern load def }if /currentcmykcolor[0 0 0 0]AGMCORE_gput /currentstrokeadjust false AGMCORE_gput /currentcolorspace[/DeviceGray]AGMCORE_gput /sep_tint 0 AGMCORE_gput /devicen_tints[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]AGMCORE_gput /sep_colorspace_dict null AGMCORE_gput /devicen_colorspace_dict null AGMCORE_gput /indexed_colorspace_dict null AGMCORE_gput /currentcolor_intent()AGMCORE_gput /customcolor_tint 1 AGMCORE_gput /absolute_colorimetric_crd null AGMCORE_gput /relative_colorimetric_crd null AGMCORE_gput /saturation_crd null AGMCORE_gput /perceptual_crd null AGMCORE_gput currentcolortransfer cvlit/AGMCore_gray_xfer xdf cvlit/AGMCore_b_xfer xdf cvlit/AGMCore_g_xfer xdf cvlit/AGMCore_r_xfer xdf << /MaxPatternItem currentsystemparams/MaxPatternCache get >> setuserparams end }def /ps { /setcmykcolor where{ pop Adobe_AGM_Core/AGMCORE_&setcmykcolor/setcmykcolor load put }if Adobe_AGM_Core begin /setcmykcolor { 4 copy AGMCORE_cmykbuf astore/currentcmykcolor exch AGMCORE_gput 1 sub 4 1 roll 3{ 3 index add neg dup 0 lt{ pop 0 }if 3 1 roll }repeat setrgbcolor pop }ndf /currentcmykcolor { /currentcmykcolor AGMCORE_gget aload pop }ndf /setoverprint {pop}ndf /currentoverprint {false}ndf /AGMCORE_cyan_plate 1 0 0 0 test_cmyk_color_plate def /AGMCORE_magenta_plate 0 1 0 0 test_cmyk_color_plate def /AGMCORE_yellow_plate 0 0 1 0 test_cmyk_color_plate def /AGMCORE_black_plate 0 0 0 1 test_cmyk_color_plate def /AGMCORE_plate_ndx AGMCORE_cyan_plate{ 0 }{ AGMCORE_magenta_plate{ 1 }{ AGMCORE_yellow_plate{ 2 }{ AGMCORE_black_plate{ 3 }{ 4 }ifelse }ifelse }ifelse }ifelse def /AGMCORE_have_reported_unsupported_color_space false def /AGMCORE_report_unsupported_color_space { AGMCORE_have_reported_unsupported_color_space false eq { (Warning: Job contains content that cannot be separated with on-host methods. This content appears on the black plate, and knocks out all other plates.)== Adobe_AGM_Core/AGMCORE_have_reported_unsupported_color_space true ddf }if }def /AGMCORE_composite_job AGMCORE_cyan_plate AGMCORE_magenta_plate and AGMCORE_yellow_plate and AGMCORE_black_plate and def /AGMCORE_in_rip_sep /AGMCORE_in_rip_sep where{ pop AGMCORE_in_rip_sep }{ AGMCORE_distilling { false }{ userdict/Adobe_AGM_OnHost_Seps known{ false }{ level2{ currentpagedevice/Separations 2 copy known{ get }{ pop pop false }ifelse }{ false }ifelse }ifelse }ifelse }ifelse def /AGMCORE_producing_seps AGMCORE_composite_job not AGMCORE_in_rip_sep or def /AGMCORE_host_sep AGMCORE_producing_seps AGMCORE_in_rip_sep not and def /AGM_preserve_spots /AGM_preserve_spots where{ pop AGM_preserve_spots }{ AGMCORE_distilling AGMCORE_producing_seps or }ifelse def /AGM_is_distiller_preserving_spotimages { currentdistillerparams/PreserveOverprintSettings known { currentdistillerparams/PreserveOverprintSettings get { currentdistillerparams/ColorConversionStrategy known { currentdistillerparams/ColorConversionStrategy get /sRGB ne }{ true }ifelse }{ false }ifelse }{ false }ifelse }def /convert_spot_to_process where{pop}{ /convert_spot_to_process { //Adobe_AGM_Core begin dup map_alias{ /Name get exch pop }if dup dup(None)eq exch(All)eq or { pop false }{ AGMCORE_host_sep { gsave 1 0 0 0 setcmykcolor currentgray 1 exch sub 0 1 0 0 setcmykcolor currentgray 1 exch sub 0 0 1 0 setcmykcolor currentgray 1 exch sub 0 0 0 1 setcmykcolor currentgray 1 exch sub add add add 0 eq { pop false }{ false setoverprint current_spot_alias false set_spot_alias 1 1 1 1 6 -1 roll findcmykcustomcolor 1 setcustomcolor set_spot_alias currentgray 1 ne }ifelse grestore }{ AGMCORE_distilling { pop AGM_is_distiller_preserving_spotimages not }{ //Adobe_AGM_Core/AGMCORE_name xddf false //Adobe_AGM_Core/AGMCORE_pattern_paint_type get 0 eq AGMUTIL_cpd/OverrideSeparations known and { AGMUTIL_cpd/OverrideSeparations get { /HqnSpots/ProcSet resourcestatus { pop pop pop true }if }if }if { AGMCORE_name/HqnSpots/ProcSet findresource/TestSpot gx not }{ gsave [/Separation AGMCORE_name/DeviceGray{}]AGMCORE_&setcolorspace false AGMUTIL_cpd/SeparationColorNames 2 copy known { get {AGMCORE_name eq or}forall not }{ pop pop pop true }ifelse grestore }ifelse }ifelse }ifelse }ifelse end }def }ifelse /convert_to_process where{pop}{ /convert_to_process { dup length 0 eq { pop false }{ AGMCORE_host_sep { dup true exch { dup(Cyan)eq exch dup(Magenta)eq 3 -1 roll or exch dup(Yellow)eq 3 -1 roll or exch dup(Black)eq 3 -1 roll or {pop} {convert_spot_to_process and}ifelse } forall { true exch { dup(Cyan)eq exch dup(Magenta)eq 3 -1 roll or exch dup(Yellow)eq 3 -1 roll or exch (Black)eq or and }forall not }{pop false}ifelse }{ false exch { /PhotoshopDuotoneList where{pop false}{true}ifelse { dup(Cyan)eq exch dup(Magenta)eq 3 -1 roll or exch dup(Yellow)eq 3 -1 roll or exch dup(Black)eq 3 -1 roll or {pop} {convert_spot_to_process or}ifelse } { convert_spot_to_process or } ifelse } forall }ifelse }ifelse }def }ifelse /AGMCORE_avoid_L2_sep_space version cvr 2012 lt level2 and AGMCORE_producing_seps not and def /AGMCORE_is_cmyk_sep AGMCORE_cyan_plate AGMCORE_magenta_plate or AGMCORE_yellow_plate or AGMCORE_black_plate or def /AGM_avoid_0_cmyk where{ pop AGM_avoid_0_cmyk }{ AGM_preserve_spots userdict/Adobe_AGM_OnHost_Seps known userdict/Adobe_AGM_InRip_Seps known or not and }ifelse { /setcmykcolor[ { 4 copy add add add 0 eq currentoverprint and{ pop 0.0005 }if }/exec cvx /AGMCORE_&setcmykcolor load dup type/operatortype ne{ /exec cvx }if ]cvx def }if /AGMCORE_IsSeparationAProcessColor { dup(Cyan)eq exch dup(Magenta)eq exch dup(Yellow)eq exch(Black)eq or or or }def AGMCORE_host_sep{ /setcolortransfer { AGMCORE_cyan_plate{ pop pop pop }{ AGMCORE_magenta_plate{ 4 3 roll pop pop pop }{ AGMCORE_yellow_plate{ 4 2 roll pop pop pop }{ 4 1 roll pop pop pop }ifelse }ifelse }ifelse settransfer } def /AGMCORE_get_ink_data AGMCORE_cyan_plate{ {pop pop pop} }{ AGMCORE_magenta_plate{ {4 3 roll pop pop pop} }{ AGMCORE_yellow_plate{ {4 2 roll pop pop pop} }{ {4 1 roll pop pop pop} }ifelse }ifelse }ifelse def /AGMCORE_RemoveProcessColorNames { 1 dict begin /filtername { dup/Cyan eq 1 index(Cyan)eq or {pop(_cyan_)}if dup/Magenta eq 1 index(Magenta)eq or {pop(_magenta_)}if dup/Yellow eq 1 index(Yellow)eq or {pop(_yellow_)}if dup/Black eq 1 index(Black)eq or {pop(_black_)}if }def dup type/arraytype eq {[exch{filtername}forall]} {filtername}ifelse end }def level3{ /AGMCORE_IsCurrentColor { dup AGMCORE_IsSeparationAProcessColor { AGMCORE_plate_ndx 0 eq {dup(Cyan)eq exch/Cyan eq or}if AGMCORE_plate_ndx 1 eq {dup(Magenta)eq exch/Magenta eq or}if AGMCORE_plate_ndx 2 eq {dup(Yellow)eq exch/Yellow eq or}if AGMCORE_plate_ndx 3 eq {dup(Black)eq exch/Black eq or}if AGMCORE_plate_ndx 4 eq {pop false}if }{ gsave false setoverprint current_spot_alias false set_spot_alias 1 1 1 1 6 -1 roll findcmykcustomcolor 1 setcustomcolor set_spot_alias currentgray 1 ne grestore }ifelse }def /AGMCORE_filter_functiondatasource { 5 dict begin /data_in xdf data_in type/stringtype eq { /ncomp xdf /comp xdf /string_out data_in length ncomp idiv string def 0 ncomp data_in length 1 sub { string_out exch dup ncomp idiv exch data_in exch ncomp getinterval comp get 255 exch sub put }for string_out }{ string/string_in xdf /string_out 1 string def /component xdf [ data_in string_in/readstring cvx [component/get cvx 255/exch cvx/sub cvx string_out/exch cvx 0/exch cvx/put cvx string_out]cvx [/pop cvx()]cvx/ifelse cvx ]cvx/ReusableStreamDecode filter }ifelse end }def /AGMCORE_separateShadingFunction { 2 dict begin /paint? xdf /channel xdf dup type/dicttype eq { begin FunctionType 0 eq { /DataSource channel Range length 2 idiv DataSource AGMCORE_filter_functiondatasource def currentdict/Decode known {/Decode Decode channel 2 mul 2 getinterval def}if paint? not {/Decode[1 1]def}if }if FunctionType 2 eq { paint? { /C0[C0 channel get 1 exch sub]def /C1[C1 channel get 1 exch sub]def }{ /C0[1]def /C1[1]def }ifelse }if FunctionType 3 eq { /Functions[Functions{channel paint? AGMCORE_separateShadingFunction}forall]def }if currentdict/Range known {/Range[0 1]def}if currentdict end}{ channel get 0 paint? AGMCORE_separateShadingFunction }ifelse end }def /AGMCORE_separateShading { 3 -1 roll begin currentdict/Function known { currentdict/Background known {[1 index{Background 3 index get 1 exch sub}{1}ifelse]/Background xdf}if Function 3 1 roll AGMCORE_separateShadingFunction/Function xdf /ColorSpace[/DeviceGray]def }{ ColorSpace dup type/arraytype eq{0 get}if/DeviceCMYK eq { /ColorSpace[/DeviceN[/_cyan_/_magenta_/_yellow_/_black_]/DeviceCMYK{}]def }{ ColorSpace dup 1 get AGMCORE_RemoveProcessColorNames 1 exch put }ifelse ColorSpace 0 get/Separation eq { { [1/exch cvx/sub cvx]cvx }{ [/pop cvx 1]cvx }ifelse ColorSpace 3 3 -1 roll put pop }{ { [exch ColorSpace 1 get length 1 sub exch sub/index cvx 1/exch cvx/sub cvx ColorSpace 1 get length 1 add 1/roll cvx ColorSpace 1 get length{/pop cvx}repeat]cvx }{ pop[ColorSpace 1 get length{/pop cvx}repeat cvx 1]cvx }ifelse ColorSpace 3 3 -1 roll bind put }ifelse ColorSpace 2/DeviceGray put }ifelse end }def /AGMCORE_separateShadingDict { dup/ColorSpace get dup type/arraytype ne {[exch]}if dup 0 get/DeviceCMYK eq { exch begin currentdict AGMCORE_cyan_plate {0 true}if AGMCORE_magenta_plate {1 true}if AGMCORE_yellow_plate {2 true}if AGMCORE_black_plate {3 true}if AGMCORE_plate_ndx 4 eq {0 false}if dup not currentoverprint and {/AGMCORE_ignoreshade true def}if AGMCORE_separateShading currentdict end exch }if dup 0 get/Separation eq { exch begin ColorSpace 1 get dup/None ne exch/All ne and { ColorSpace 1 get AGMCORE_IsCurrentColor AGMCORE_plate_ndx 4 lt and ColorSpace 1 get AGMCORE_IsSeparationAProcessColor not and { ColorSpace 2 get dup type/arraytype eq{0 get}if/DeviceCMYK eq { /ColorSpace [ /Separation ColorSpace 1 get /DeviceGray [ ColorSpace 3 get/exec cvx 4 AGMCORE_plate_ndx sub -1/roll cvx 4 1/roll cvx 3[/pop cvx]cvx/repeat cvx 1/exch cvx/sub cvx ]cvx ]def }{ AGMCORE_report_unsupported_color_space AGMCORE_black_plate not { currentdict 0 false AGMCORE_separateShading }if }ifelse }{ currentdict ColorSpace 1 get AGMCORE_IsCurrentColor 0 exch dup not currentoverprint and {/AGMCORE_ignoreshade true def}if AGMCORE_separateShading }ifelse }if currentdict end exch }if dup 0 get/DeviceN eq { exch begin ColorSpace 1 get convert_to_process { ColorSpace 2 get dup type/arraytype eq{0 get}if/DeviceCMYK eq { /ColorSpace [ /DeviceN ColorSpace 1 get /DeviceGray [ ColorSpace 3 get/exec cvx 4 AGMCORE_plate_ndx sub -1/roll cvx 4 1/roll cvx 3[/pop cvx]cvx/repeat cvx 1/exch cvx/sub cvx ]cvx ]def }{ AGMCORE_report_unsupported_color_space AGMCORE_black_plate not { currentdict 0 false AGMCORE_separateShading /ColorSpace[/DeviceGray]def }if }ifelse }{ currentdict false -1 ColorSpace 1 get { AGMCORE_IsCurrentColor { 1 add exch pop true exch exit }if 1 add }forall exch dup not currentoverprint and {/AGMCORE_ignoreshade true def}if AGMCORE_separateShading }ifelse currentdict end exch }if dup 0 get dup/DeviceCMYK eq exch dup/Separation eq exch/DeviceN eq or or not { exch begin ColorSpace dup type/arraytype eq {0 get}if /DeviceGray ne { AGMCORE_report_unsupported_color_space AGMCORE_black_plate not { ColorSpace 0 get/CIEBasedA eq { /ColorSpace[/Separation/_ciebaseda_/DeviceGray{}]def }if ColorSpace 0 get dup/CIEBasedABC eq exch dup/CIEBasedDEF eq exch/DeviceRGB eq or or { /ColorSpace[/DeviceN[/_red_/_green_/_blue_]/DeviceRGB{}]def }if ColorSpace 0 get/CIEBasedDEFG eq { /ColorSpace[/DeviceN[/_cyan_/_magenta_/_yellow_/_black_]/DeviceCMYK{}]def }if currentdict 0 false AGMCORE_separateShading }if }if currentdict end exch }if pop dup/AGMCORE_ignoreshade known { begin /ColorSpace[/Separation(None)/DeviceGray{}]def currentdict end }if }def /shfill { AGMCORE_separateShadingDict dup/AGMCORE_ignoreshade known {pop} {AGMCORE_&sysshfill}ifelse }def /makepattern { exch dup/PatternType get 2 eq { clonedict begin /Shading Shading AGMCORE_separateShadingDict def Shading/AGMCORE_ignoreshade known currentdict end exch {pop<>}if exch AGMCORE_&sysmakepattern }{ exch AGMCORE_&usrmakepattern }ifelse }def }if }if AGMCORE_in_rip_sep{ /setcustomcolor { exch aload pop dup 7 1 roll inRip_spot_has_ink not { 4{4 index mul 4 1 roll} repeat /DeviceCMYK setcolorspace 6 -2 roll pop pop }{ //Adobe_AGM_Core begin /AGMCORE_k xdf/AGMCORE_y xdf/AGMCORE_m xdf/AGMCORE_c xdf end [/Separation 4 -1 roll/DeviceCMYK {dup AGMCORE_c mul exch dup AGMCORE_m mul exch dup AGMCORE_y mul exch AGMCORE_k mul} ] setcolorspace }ifelse setcolor }ndf /setseparationgray { [/Separation(All)/DeviceGray{}]setcolorspace_opt 1 exch sub setcolor }ndf }{ /setseparationgray { AGMCORE_&setgray }ndf }ifelse /findcmykcustomcolor { 5 makereadonlyarray }ndf /setcustomcolor { exch aload pop pop 4{4 index mul 4 1 roll}repeat setcmykcolor pop }ndf /has_color /colorimage where{ AGMCORE_producing_seps{ pop true }{ systemdict eq }ifelse }{ false }ifelse def /map_index { 1 index mul exch getinterval{255 div}forall }bdf /map_indexed_devn { Lookup Names length 3 -1 roll cvi map_index }bdf /n_color_components { base_colorspace_type dup/DeviceGray eq{ pop 1 }{ /DeviceCMYK eq{ 4 }{ 3 }ifelse }ifelse }bdf level2{ /mo/moveto ldf /li/lineto ldf /cv/curveto ldf /knockout_unitsq { 1 setgray 0 0 1 1 rectfill }def level2/setcolorspace AGMCORE_key_known not and{ /AGMCORE_&&&setcolorspace/setcolorspace ldf /AGMCORE_ReplaceMappedColor { dup type dup/arraytype eq exch/packedarraytype eq or { /AGMCORE_SpotAliasAry2 where{ begin dup 0 get dup/Separation eq { pop dup length array copy dup dup 1 get current_spot_alias { dup map_alias { false set_spot_alias dup 1 exch setsepcolorspace true set_spot_alias begin /sep_colorspace_dict currentdict AGMCORE_gput pop pop pop [ /Separation Name CSA map_csa MappedCSA /sep_colorspace_proc load ] dup Name end }if }if map_reserved_ink_name 1 xpt }{ /DeviceN eq { dup length array copy dup dup 1 get[ exch{ current_spot_alias{ dup map_alias{ /Name get exch pop }if }if map_reserved_ink_name }forall ]1 xpt }if }ifelse end }if }if }def /setcolorspace { dup type dup/arraytype eq exch/packedarraytype eq or { dup 0 get/Indexed eq { AGMCORE_distilling { /PhotoshopDuotoneList where { pop false }{ true }ifelse }{ true }ifelse { aload pop 3 -1 roll AGMCORE_ReplaceMappedColor 3 1 roll 4 array astore }if }{ AGMCORE_ReplaceMappedColor }ifelse }if DeviceN_PS2_inRip_seps{AGMCORE_&&&setcolorspace}if }def }if }{ /adj { currentstrokeadjust{ transform 0.25 sub round 0.25 add exch 0.25 sub round 0.25 add exch itransform }if }def /mo{ adj moveto }def /li{ adj lineto }def /cv{ 6 2 roll adj 6 2 roll adj 6 2 roll adj curveto }def /knockout_unitsq { 1 setgray 8 8 1[8 0 0 8 0 0]{}image }def /currentstrokeadjust{ /currentstrokeadjust AGMCORE_gget }def /setstrokeadjust{ /currentstrokeadjust exch AGMCORE_gput }def /setcolorspace { /currentcolorspace exch AGMCORE_gput }def /currentcolorspace { /currentcolorspace AGMCORE_gget }def /setcolor_devicecolor { base_colorspace_type dup/DeviceGray eq{ pop setgray }{ /DeviceCMYK eq{ setcmykcolor }{ setrgbcolor }ifelse }ifelse }def /setcolor { currentcolorspace 0 get dup/DeviceGray ne{ dup/DeviceCMYK ne{ dup/DeviceRGB ne{ dup/Separation eq{ pop currentcolorspace 3 gx currentcolorspace 2 get }{ dup/Indexed eq{ pop currentcolorspace 3 get dup type/stringtype eq{ currentcolorspace 1 get n_color_components 3 -1 roll map_index }{ exec }ifelse currentcolorspace 1 get }{ /AGMCORE_cur_err/AGMCORE_invalid_color_space def AGMCORE_invalid_color_space }ifelse }ifelse }if }if }if setcolor_devicecolor }def }ifelse /sop/setoverprint ldf /lw/setlinewidth ldf /lc/setlinecap ldf /lj/setlinejoin ldf /ml/setmiterlimit ldf /dsh/setdash ldf /sadj/setstrokeadjust ldf /gry/setgray ldf /rgb/setrgbcolor ldf /cmyk[ /currentcolorspace[/DeviceCMYK]/AGMCORE_gput cvx /setcmykcolor load dup type/operatortype ne{/exec cvx}if ]cvx bdf level3 AGMCORE_host_sep not and{ /nzopmsc{ 6 dict begin /kk exch def /yy exch def /mm exch def /cc exch def /sum 0 def cc 0 ne{/sum sum 2#1000 or def cc}if mm 0 ne{/sum sum 2#0100 or def mm}if yy 0 ne{/sum sum 2#0010 or def yy}if kk 0 ne{/sum sum 2#0001 or def kk}if AGMCORE_CMYKDeviceNColorspaces sum get setcolorspace sum 0 eq{0}if end setcolor }bdf }{ /nzopmsc/cmyk ldf }ifelse /sep/setsepcolor ldf /devn/setdevicencolor ldf /idx/setindexedcolor ldf /colr/setcolor ldf /csacrd/set_csa_crd ldf /sepcs/setsepcolorspace ldf /devncs/setdevicencolorspace ldf /idxcs/setindexedcolorspace ldf /cp/closepath ldf /clp/clp_npth ldf /eclp/eoclp_npth ldf /f/fill ldf /ef/eofill ldf /@/stroke ldf /nclp/npth_clp ldf /gset/graphic_setup ldf /gcln/graphic_cleanup ldf /ct/concat ldf /cf/currentfile ldf /fl/filter ldf /rs/readstring ldf /AGMCORE_def_ht currenthalftone def /clonedict Adobe_AGM_Utils begin/clonedict load end def /clonearray Adobe_AGM_Utils begin/clonearray load end def currentdict{ dup xcheck 1 index type dup/arraytype eq exch/packedarraytype eq or and{ bind }if def }forall /getrampcolor { /indx exch def 0 1 NumComp 1 sub { dup Samples exch get dup type/stringtype eq{indx get}if exch Scaling exch get aload pop 3 1 roll mul add }for ColorSpaceFamily/Separation eq {sep} { ColorSpaceFamily/DeviceN eq {devn}{setcolor}ifelse }ifelse }bdf /sssetbackground{ aload pop ColorSpaceFamily/Separation eq {sep} { ColorSpaceFamily/DeviceN eq {devn}{setcolor}ifelse }ifelse }bdf /RadialShade { 40 dict begin /ColorSpaceFamily xdf /background xdf /ext1 xdf /ext0 xdf /BBox xdf /r2 xdf /c2y xdf /c2x xdf /r1 xdf /c1y xdf /c1x xdf /rampdict xdf /setinkoverprint where{pop/setinkoverprint{pop}def}if gsave BBox length 0 gt { np BBox 0 get BBox 1 get moveto BBox 2 get BBox 0 get sub 0 rlineto 0 BBox 3 get BBox 1 get sub rlineto BBox 2 get BBox 0 get sub neg 0 rlineto closepath clip np }if c1x c2x eq { c1y c2y lt{/theta 90 def}{/theta 270 def}ifelse }{ /slope c2y c1y sub c2x c1x sub div def /theta slope 1 atan def c2x c1x lt c2y c1y ge and{/theta theta 180 sub def}if c2x c1x lt c2y c1y lt and{/theta theta 180 add def}if }ifelse gsave clippath c1x c1y translate theta rotate -90 rotate {pathbbox}stopped {0 0 0 0}if /yMax xdf /xMax xdf /yMin xdf /xMin xdf grestore xMax xMin eq yMax yMin eq or { grestore end }{ /max{2 copy gt{pop}{exch pop}ifelse}bdf /min{2 copy lt{pop}{exch pop}ifelse}bdf rampdict begin 40 dict begin background length 0 gt{background sssetbackground gsave clippath fill grestore}if gsave c1x c1y translate theta rotate -90 rotate /c2y c1x c2x sub dup mul c1y c2y sub dup mul add sqrt def /c1y 0 def /c1x 0 def /c2x 0 def ext0 { 0 getrampcolor c2y r2 add r1 sub 0.0001 lt { c1x c1y r1 360 0 arcn pathbbox /aymax exch def /axmax exch def /aymin exch def /axmin exch def /bxMin xMin axmin min def /byMin yMin aymin min def /bxMax xMax axmax max def /byMax yMax aymax max def bxMin byMin moveto bxMax byMin lineto bxMax byMax lineto bxMin byMax lineto bxMin byMin lineto eofill }{ c2y r1 add r2 le { c1x c1y r1 0 360 arc fill } { c2x c2y r2 0 360 arc fill r1 r2 eq { /p1x r1 neg def /p1y c1y def /p2x r1 def /p2y c1y def p1x p1y moveto p2x p2y lineto p2x yMin lineto p1x yMin lineto fill }{ /AA r2 r1 sub c2y div def AA -1 eq {/theta 89.99 def} {/theta AA 1 AA dup mul sub sqrt div 1 atan def} ifelse /SS1 90 theta add dup sin exch cos div def /p1x r1 SS1 SS1 mul SS1 SS1 mul 1 add div sqrt mul neg def /p1y p1x SS1 div neg def /SS2 90 theta sub dup sin exch cos div def /p2x r1 SS2 SS2 mul SS2 SS2 mul 1 add div sqrt mul def /p2y p2x SS2 div neg def r1 r2 gt { /L1maxX p1x yMin p1y sub SS1 div add def /L2maxX p2x yMin p2y sub SS2 div add def }{ /L1maxX 0 def /L2maxX 0 def }ifelse p1x p1y moveto p2x p2y lineto L2maxX L2maxX p2x sub SS2 mul p2y add lineto L1maxX L1maxX p1x sub SS1 mul p1y add lineto fill }ifelse }ifelse }ifelse }if c1x c2x sub dup mul c1y c2y sub dup mul add 0.5 exp 0 dtransform dup mul exch dup mul add 0.5 exp 72 div 0 72 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt 72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt 1 index 1 index lt{exch}if pop /hires xdf hires mul /numpix xdf /numsteps NumSamples def /rampIndxInc 1 def /subsampling false def numpix 0 ne { NumSamples numpix div 0.5 gt { /numsteps numpix 2 div round cvi dup 1 le{pop 2}if def /rampIndxInc NumSamples 1 sub numsteps div def /subsampling true def }if }if /xInc c2x c1x sub numsteps div def /yInc c2y c1y sub numsteps div def /rInc r2 r1 sub numsteps div def /cx c1x def /cy c1y def /radius r1 def np xInc 0 eq yInc 0 eq rInc 0 eq and and { 0 getrampcolor cx cy radius 0 360 arc stroke NumSamples 1 sub getrampcolor cx cy radius 72 hires div add 0 360 arc 0 setlinewidth stroke }{ 0 numsteps { dup subsampling{round cvi}if getrampcolor cx cy radius 0 360 arc /cx cx xInc add def /cy cy yInc add def /radius radius rInc add def cx cy radius 360 0 arcn eofill rampIndxInc add }repeat pop }ifelse ext1 { c2y r2 add r1 lt { c2x c2y r2 0 360 arc fill }{ c2y r1 add r2 sub 0.0001 le { c2x c2y r2 360 0 arcn pathbbox /aymax exch def /axmax exch def /aymin exch def /axmin exch def /bxMin xMin axmin min def /byMin yMin aymin min def /bxMax xMax axmax max def /byMax yMax aymax max def bxMin byMin moveto bxMax byMin lineto bxMax byMax lineto bxMin byMax lineto bxMin byMin lineto eofill }{ c2x c2y r2 0 360 arc fill r1 r2 eq { /p1x r2 neg def /p1y c2y def /p2x r2 def /p2y c2y def p1x p1y moveto p2x p2y lineto p2x yMax lineto p1x yMax lineto fill }{ /AA r2 r1 sub c2y div def AA -1 eq {/theta 89.99 def} {/theta AA 1 AA dup mul sub sqrt div 1 atan def} ifelse /SS1 90 theta add dup sin exch cos div def /p1x r2 SS1 SS1 mul SS1 SS1 mul 1 add div sqrt mul neg def /p1y c2y p1x SS1 div sub def /SS2 90 theta sub dup sin exch cos div def /p2x r2 SS2 SS2 mul SS2 SS2 mul 1 add div sqrt mul def /p2y c2y p2x SS2 div sub def r1 r2 lt { /L1maxX p1x yMax p1y sub SS1 div add def /L2maxX p2x yMax p2y sub SS2 div add def }{ /L1maxX 0 def /L2maxX 0 def }ifelse p1x p1y moveto p2x p2y lineto L2maxX L2maxX p2x sub SS2 mul p2y add lineto L1maxX L1maxX p1x sub SS1 mul p1y add lineto fill }ifelse }ifelse }ifelse }if grestore grestore end end end }ifelse }bdf /GenStrips { 40 dict begin /ColorSpaceFamily xdf /background xdf /ext1 xdf /ext0 xdf /BBox xdf /y2 xdf /x2 xdf /y1 xdf /x1 xdf /rampdict xdf /setinkoverprint where{pop/setinkoverprint{pop}def}if gsave BBox length 0 gt { np BBox 0 get BBox 1 get moveto BBox 2 get BBox 0 get sub 0 rlineto 0 BBox 3 get BBox 1 get sub rlineto BBox 2 get BBox 0 get sub neg 0 rlineto closepath clip np }if x1 x2 eq { y1 y2 lt{/theta 90 def}{/theta 270 def}ifelse }{ /slope y2 y1 sub x2 x1 sub div def /theta slope 1 atan def x2 x1 lt y2 y1 ge and{/theta theta 180 sub def}if x2 x1 lt y2 y1 lt and{/theta theta 180 add def}if } ifelse gsave clippath x1 y1 translate theta rotate {pathbbox}stopped {0 0 0 0}if /yMax exch def /xMax exch def /yMin exch def /xMin exch def grestore xMax xMin eq yMax yMin eq or { grestore end }{ rampdict begin 20 dict begin background length 0 gt{background sssetbackground gsave clippath fill grestore}if gsave x1 y1 translate theta rotate /xStart 0 def /xEnd x2 x1 sub dup mul y2 y1 sub dup mul add 0.5 exp def /ySpan yMax yMin sub def /numsteps NumSamples def /rampIndxInc 1 def /subsampling false def xStart 0 transform xEnd 0 transform 3 -1 roll sub dup mul 3 1 roll sub dup mul add 0.5 exp 72 div 0 72 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt 72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt 1 index 1 index lt{exch}if pop mul /numpix xdf numpix 0 ne { NumSamples numpix div 0.5 gt { /numsteps numpix 2 div round cvi dup 1 le{pop 2}if def /rampIndxInc NumSamples 1 sub numsteps div def /subsampling true def }if }if ext0 { 0 getrampcolor xMin xStart lt { xMin yMin xMin neg ySpan rectfill }if }if /xInc xEnd xStart sub numsteps div def /x xStart def 0 numsteps { dup subsampling{round cvi}if getrampcolor x yMin xInc ySpan rectfill /x x xInc add def rampIndxInc add }repeat pop ext1{ xMax xEnd gt { xEnd yMin xMax xEnd sub ySpan rectfill }if }if grestore grestore end end end }ifelse }bdf }def /pt { end }def /dt{ }def /pgsv{ //Adobe_AGM_Core/AGMCORE_save save put }def /pgrs{ //Adobe_AGM_Core/AGMCORE_save get restore }def systemdict/findcolorrendering known{ /findcolorrendering systemdict/findcolorrendering get def }if systemdict/setcolorrendering known{ /setcolorrendering systemdict/setcolorrendering get def }if /test_cmyk_color_plate { gsave setcmykcolor currentgray 1 ne grestore }def /inRip_spot_has_ink { dup//Adobe_AGM_Core/AGMCORE_name xddf convert_spot_to_process not }def /map255_to_range { 1 index sub 3 -1 roll 255 div mul add }def /set_csa_crd { /sep_colorspace_dict null AGMCORE_gput begin CSA get_csa_by_name setcolorspace_opt set_crd end } def /map_csa { currentdict/MappedCSA known{MappedCSA null ne}{false}ifelse {pop}{get_csa_by_name/MappedCSA xdf}ifelse }def /setsepcolor { /sep_colorspace_dict AGMCORE_gget begin dup/sep_tint exch AGMCORE_gput TintProc end }def /setdevicencolor { /devicen_colorspace_dict AGMCORE_gget begin Names length copy Names length 1 sub -1 0 { /devicen_tints AGMCORE_gget 3 1 roll xpt }for TintProc end }def /sep_colorspace_proc { /AGMCORE_tmp exch store /sep_colorspace_dict AGMCORE_gget begin currentdict/Components known{ Components aload pop TintMethod/Lab eq{ 2{AGMCORE_tmp mul NComponents 1 roll}repeat LMax sub AGMCORE_tmp mul LMax add NComponents 1 roll }{ TintMethod/Subtractive eq{ NComponents{ AGMCORE_tmp mul NComponents 1 roll }repeat }{ NComponents{ 1 sub AGMCORE_tmp mul 1 add NComponents 1 roll }repeat }ifelse }ifelse }{ ColorLookup AGMCORE_tmp ColorLookup length 1 sub mul round cvi get aload pop }ifelse end }def /sep_colorspace_gray_proc { /AGMCORE_tmp exch store /sep_colorspace_dict AGMCORE_gget begin GrayLookup AGMCORE_tmp GrayLookup length 1 sub mul round cvi get end }def /sep_proc_name { dup 0 get dup/DeviceRGB eq exch/DeviceCMYK eq or level2 not and has_color not and{ pop[/DeviceGray] /sep_colorspace_gray_proc }{ /sep_colorspace_proc }ifelse }def /setsepcolorspace { current_spot_alias{ dup begin Name map_alias{ exch pop }if end }if dup/sep_colorspace_dict exch AGMCORE_gput begin CSA map_csa /AGMCORE_sep_special Name dup()eq exch(All)eq or store AGMCORE_avoid_L2_sep_space{ [/Indexed MappedCSA sep_proc_name 255 exch {255 div}/exec cvx 3 -1 roll[4 1 roll load/exec cvx]cvx ]setcolorspace_opt /TintProc{ 255 mul round cvi setcolor }bdf }{ MappedCSA 0 get/DeviceCMYK eq currentdict/Components known and AGMCORE_sep_special not and{ /TintProc[ Components aload pop Name findcmykcustomcolor /exch cvx/setcustomcolor cvx ]cvx bdf }{ AGMCORE_host_sep Name(All)eq and{ /TintProc{ 1 exch sub setseparationgray }bdf }{ AGMCORE_in_rip_sep MappedCSA 0 get/DeviceCMYK eq and AGMCORE_host_sep or Name()eq and{ /TintProc[ MappedCSA sep_proc_name exch 0 get/DeviceCMYK eq{ cvx/setcmykcolor cvx }{ cvx/setgray cvx }ifelse ]cvx bdf }{ AGMCORE_producing_seps MappedCSA 0 get dup/DeviceCMYK eq exch/DeviceGray eq or and AGMCORE_sep_special not and{ /TintProc[ /dup cvx MappedCSA sep_proc_name cvx exch 0 get/DeviceGray eq{ 1/exch cvx/sub cvx 0 0 0 4 -1/roll cvx }if /Name cvx/findcmykcustomcolor cvx/exch cvx AGMCORE_host_sep{ AGMCORE_is_cmyk_sep /Name cvx /AGMCORE_IsSeparationAProcessColor load/exec cvx /not cvx/and cvx }{ Name inRip_spot_has_ink not }ifelse [ /pop cvx 1 ]cvx/if cvx /setcustomcolor cvx ]cvx bdf }{ /TintProc{setcolor}bdf [/Separation Name MappedCSA sep_proc_name load]setcolorspace_opt }ifelse }ifelse }ifelse }ifelse }ifelse set_crd setsepcolor end }def /additive_blend { 3 dict begin /numarrays xdf /numcolors xdf 0 1 numcolors 1 sub { /c1 xdf 1 0 1 numarrays 1 sub { 1 exch add/index cvx c1/get cvx/mul cvx }for numarrays 1 add 1/roll cvx }for numarrays[/pop cvx]cvx/repeat cvx end }def /subtractive_blend { 3 dict begin /numarrays xdf /numcolors xdf 0 1 numcolors 1 sub { /c1 xdf 1 1 0 1 numarrays 1 sub { 1 3 3 -1 roll add/index cvx c1/get cvx/sub cvx/mul cvx }for /sub cvx numarrays 1 add 1/roll cvx }for numarrays[/pop cvx]cvx/repeat cvx end }def /exec_tint_transform { /TintProc[ /TintTransform cvx/setcolor cvx ]cvx bdf MappedCSA setcolorspace_opt }bdf /devn_makecustomcolor { 2 dict begin /names_index xdf /Names xdf 1 1 1 1 Names names_index get findcmykcustomcolor /devicen_tints AGMCORE_gget names_index get setcustomcolor Names length{pop}repeat end }bdf /setdevicencolorspace { dup/AliasedColorants known{false}{true}ifelse current_spot_alias and{ 7 dict begin /names_index 0 def dup/names_len exch/Names get length def /new_names names_len array def /new_LookupTables names_len array def /alias_cnt 0 def dup/Names get { dup map_alias{ exch pop dup/ColorLookup known{ dup begin new_LookupTables names_index ColorLookup put end }{ dup/Components known{ dup begin new_LookupTables names_index Components put end }{ dup begin new_LookupTables names_index[null null null null]put end }ifelse }ifelse new_names names_index 3 -1 roll/Name get put /alias_cnt alias_cnt 1 add def }{ /name xdf new_names names_index name put dup/LookupTables known{ dup begin new_LookupTables names_index LookupTables names_index get put end }{ dup begin new_LookupTables names_index[null null null null]put end }ifelse }ifelse /names_index names_index 1 add def }forall alias_cnt 0 gt{ /AliasedColorants true def /lut_entry_len new_LookupTables 0 get dup length 256 ge{0 get length}{length}ifelse def 0 1 names_len 1 sub{ /names_index xdf new_LookupTables names_index get dup length 256 ge{0 get length}{length}ifelse lut_entry_len ne{ /AliasedColorants false def exit }{ new_LookupTables names_index get 0 get null eq{ dup/Names get names_index get/name xdf name(Cyan)eq name(Magenta)eq name(Yellow)eq name(Black)eq or or or not{ /AliasedColorants false def exit }if }if }ifelse }for lut_entry_len 1 eq{ /AliasedColorants false def }if AliasedColorants{ dup begin /Names new_names def /LookupTables new_LookupTables def /AliasedColorants true def /NComponents lut_entry_len def /TintMethod NComponents 4 eq{/Subtractive}{/Additive}ifelse def /MappedCSA TintMethod/Additive eq{/DeviceRGB}{/DeviceCMYK}ifelse def currentdict/TTTablesIdx known not{ /TTTablesIdx -1 def }if end }if }if end }if dup/devicen_colorspace_dict exch AGMCORE_gput begin currentdict/AliasedColorants known{ AliasedColorants }{ false }ifelse dup not{ CSA map_csa }if /TintTransform load type/nulltype eq or{ /TintTransform[ 0 1 Names length 1 sub { /TTTablesIdx TTTablesIdx 1 add def dup LookupTables exch get dup 0 get null eq { 1 index Names exch get dup(Cyan)eq { pop exch LookupTables length exch sub /index cvx 0 0 0 } { dup(Magenta)eq { pop exch LookupTables length exch sub /index cvx 0/exch cvx 0 0 }{ (Yellow)eq { exch LookupTables length exch sub /index cvx 0 0 3 -1/roll cvx 0 }{ exch LookupTables length exch sub /index cvx 0 0 0 4 -1/roll cvx }ifelse }ifelse }ifelse 5 -1/roll cvx/astore cvx }{ dup length 1 sub LookupTables length 4 -1 roll sub 1 add /index cvx/mul cvx/round cvx/cvi cvx/get cvx }ifelse Names length TTTablesIdx add 1 add 1/roll cvx }for Names length[/pop cvx]cvx/repeat cvx NComponents Names length TintMethod/Subtractive eq { subtractive_blend }{ additive_blend }ifelse ]cvx bdf }if AGMCORE_host_sep{ Names convert_to_process{ exec_tint_transform } { currentdict/AliasedColorants known{ AliasedColorants not }{ false }ifelse 5 dict begin /AvoidAliasedColorants xdf /painted? false def /names_index 0 def /names_len Names length def AvoidAliasedColorants{ /currentspotalias current_spot_alias def false set_spot_alias }if Names{ AGMCORE_is_cmyk_sep{ dup(Cyan)eq AGMCORE_cyan_plate and exch dup(Magenta)eq AGMCORE_magenta_plate and exch dup(Yellow)eq AGMCORE_yellow_plate and exch (Black)eq AGMCORE_black_plate and or or or{ /devicen_colorspace_dict AGMCORE_gget/TintProc[ Names names_index/devn_makecustomcolor cvx ]cvx ddf /painted? true def }if painted?{exit}if }{ 0 0 0 0 5 -1 roll findcmykcustomcolor 1 setcustomcolor currentgray 0 eq{ /devicen_colorspace_dict AGMCORE_gget/TintProc[ Names names_index/devn_makecustomcolor cvx ]cvx ddf /painted? true def exit }if }ifelse /names_index names_index 1 add def }forall AvoidAliasedColorants{ currentspotalias set_spot_alias }if painted?{ /devicen_colorspace_dict AGMCORE_gget/names_index names_index put }{ /devicen_colorspace_dict AGMCORE_gget/TintProc[ names_len[/pop cvx]cvx/repeat cvx 1/setseparationgray cvx 0 0 0 0/setcmykcolor cvx ]cvx ddf }ifelse end }ifelse } { AGMCORE_in_rip_sep{ Names convert_to_process not }{ level3 }ifelse { [/DeviceN Names MappedCSA/TintTransform load]setcolorspace_opt /TintProc level3 not AGMCORE_in_rip_sep and{ [ Names/length cvx[/pop cvx]cvx/repeat cvx ]cvx bdf }{ {setcolor}bdf }ifelse }{ exec_tint_transform }ifelse }ifelse set_crd /AliasedColorants false def end }def /setindexedcolorspace { dup/indexed_colorspace_dict exch AGMCORE_gput begin currentdict/CSDBase known{ CSDBase/CSD get_res begin currentdict/Names known{ currentdict devncs }{ 1 currentdict sepcs }ifelse AGMCORE_host_sep{ 4 dict begin /compCnt/Names where{pop Names length}{1}ifelse def /NewLookup HiVal 1 add string def 0 1 HiVal{ /tableIndex xdf Lookup dup type/stringtype eq{ compCnt tableIndex map_index }{ exec }ifelse /Names where{ pop setdevicencolor }{ setsepcolor }ifelse currentgray tableIndex exch 255 mul cvi NewLookup 3 1 roll put }for [/Indexed currentcolorspace HiVal NewLookup]setcolorspace_opt end }{ level3 { currentdict/Names known{ [/Indexed[/DeviceN Names MappedCSA/TintTransform load]HiVal Lookup]setcolorspace_opt }{ [/Indexed[/Separation Name MappedCSA sep_proc_name load]HiVal Lookup]setcolorspace_opt }ifelse }{ [/Indexed MappedCSA HiVal [ currentdict/Names known{ Lookup dup type/stringtype eq {/exch cvx CSDBase/CSD get_res/Names get length dup/mul cvx exch/getinterval cvx{255 div}/forall cvx} {/exec cvx}ifelse /TintTransform load/exec cvx }{ Lookup dup type/stringtype eq {/exch cvx/get cvx 255/div cvx} {/exec cvx}ifelse CSDBase/CSD get_res/MappedCSA get sep_proc_name exch pop/load cvx/exec cvx }ifelse ]cvx ]setcolorspace_opt }ifelse }ifelse end set_crd } { CSA map_csa AGMCORE_host_sep level2 not and{ 0 0 0 0 setcmykcolor }{ [/Indexed MappedCSA level2 not has_color not and{ dup 0 get dup/DeviceRGB eq exch/DeviceCMYK eq or{ pop[/DeviceGray] }if HiVal GrayLookup }{ HiVal currentdict/RangeArray known{ { /indexed_colorspace_dict AGMCORE_gget begin Lookup exch dup HiVal gt{ pop HiVal }if NComponents mul NComponents getinterval{}forall NComponents 1 sub -1 0{ RangeArray exch 2 mul 2 getinterval aload pop map255_to_range NComponents 1 roll }for end }bind }{ Lookup }ifelse }ifelse ]setcolorspace_opt set_crd }ifelse }ifelse end }def /setindexedcolor { AGMCORE_host_sep{ /indexed_colorspace_dict AGMCORE_gget begin currentdict/CSDBase known{ CSDBase/CSD get_res begin currentdict/Names known{ map_indexed_devn devn } { Lookup 1 3 -1 roll map_index sep }ifelse end }{ Lookup MappedCSA/DeviceCMYK eq{4}{1}ifelse 3 -1 roll map_index MappedCSA/DeviceCMYK eq{setcmykcolor}{setgray}ifelse }ifelse end }{ level3 not AGMCORE_in_rip_sep and/indexed_colorspace_dict AGMCORE_gget/CSDBase known and{ /indexed_colorspace_dict AGMCORE_gget/CSDBase get/CSD get_res begin map_indexed_devn devn end } { setcolor }ifelse }ifelse }def /ignoreimagedata { currentoverprint not{ gsave dup clonedict begin 1 setgray /Decode[0 1]def /DataSourcedef /MultipleDataSources false def /BitsPerComponent 8 def currentdict end systemdict/image gx grestore }if consumeimagedata }def /add_res { dup/CSD eq{ pop //Adobe_AGM_Core begin /AGMCORE_CSD_cache load 3 1 roll put end }{ defineresource pop }ifelse }def /del_res { { aload pop exch dup/CSD eq{ pop {//Adobe_AGM_Core/AGMCORE_CSD_cache get exch undef}forall }{ exch {1 index undefineresource}forall pop }ifelse }forall }def /get_res { dup/CSD eq{ pop dup type dup/nametype eq exch/stringtype eq or{ AGMCORE_CSD_cache exch get }if }{ findresource }ifelse }def /get_csa_by_name { dup type dup/nametype eq exch/stringtype eq or{ /CSA get_res }if }def /paintproc_buf_init { /count get 0 0 put }def /paintproc_buf_next { dup/count get dup 0 get dup 3 1 roll 1 add 0 xpt get }def /cachepaintproc_compress { 5 dict begin currentfile exch 0 exch/SubFileDecode filter/ReadFilter exch def /ppdict 20 dict def /string_size 16000 def /readbuffer string_size string def currentglobal true setglobal ppdict 1 array dup 0 1 put/count xpt setglobal /LZWFilter { exch dup length 0 eq{ pop }{ ppdict dup length 1 sub 3 -1 roll put }ifelse {string_size}{0}ifelse string }/LZWEncode filter def { ReadFilter readbuffer readstring exch LZWFilter exch writestring not{exit}if }loop LZWFilter closefile ppdict end }def /cachepaintproc { 2 dict begin currentfile exch 0 exch/SubFileDecode filter/ReadFilter exch def /ppdict 20 dict def currentglobal true setglobal ppdict 1 array dup 0 1 put/count xpt setglobal { ReadFilter 16000 string readstring exch ppdict dup length 1 sub 3 -1 roll put not{exit}if }loop ppdict dup dup length 1 sub()put end }def /make_pattern { exch clonedict exch dup matrix currentmatrix matrix concatmatrix 0 0 3 2 roll itransform exch 3 index/XStep get 1 index exch 2 copy div cvi mul sub sub exch 3 index/YStep get 1 index exch 2 copy div cvi mul sub sub matrix translate exch matrix concatmatrix 1 index begin BBox 0 get XStep div cvi XStep mul/xshift exch neg def BBox 1 get YStep div cvi YStep mul/yshift exch neg def BBox 0 get xshift add BBox 1 get yshift add BBox 2 get xshift add BBox 3 get yshift add 4 array astore /BBox exch def [xshift yshift/translate load null/exec load]dup 3/PaintProc load put cvx/PaintProc exch def end gsave 0 setgray makepattern grestore }def /set_pattern { dup/PatternType get 1 eq{ dup/PaintType get 1 eq{ currentoverprint sop[/DeviceGray]setcolorspace 0 setgray }if }if setpattern }def /setcolorspace_opt { dup currentcolorspace eq{pop}{setcolorspace}ifelse }def /updatecolorrendering { currentcolorrendering/RenderingIntent known{ currentcolorrendering/RenderingIntent get } { Intent/AbsoluteColorimetric eq { /absolute_colorimetric_crd AGMCORE_gget dup null eq } { Intent/RelativeColorimetric eq { /relative_colorimetric_crd AGMCORE_gget dup null eq } { Intent/Saturation eq { /saturation_crd AGMCORE_gget dup null eq } { /perceptual_crd AGMCORE_gget dup null eq }ifelse }ifelse }ifelse { pop null } { /RenderingIntent known{null}{Intent}ifelse }ifelse }ifelse Intent ne{ Intent/ColorRendering{findresource}stopped { pop pop systemdict/findcolorrendering known { Intent findcolorrendering { /ColorRendering findresource true exch } { /ColorRendering findresource product(Xerox Phaser 5400)ne exch }ifelse dup Intent/AbsoluteColorimetric eq { /absolute_colorimetric_crd exch AGMCORE_gput } { Intent/RelativeColorimetric eq { /relative_colorimetric_crd exch AGMCORE_gput } { Intent/Saturation eq { /saturation_crd exch AGMCORE_gput } { Intent/Perceptual eq { /perceptual_crd exch AGMCORE_gput } { pop }ifelse }ifelse }ifelse }ifelse 1 index{exch}{pop}ifelse } {false}ifelse } {true}ifelse { dup begin currentdict/TransformPQR known{ currentdict/TransformPQR get aload pop 3{{}eq 3 1 roll}repeat or or } {true}ifelse currentdict/MatrixPQR known{ currentdict/MatrixPQR get aload pop 1.0 eq 9 1 roll 0.0 eq 9 1 roll 0.0 eq 9 1 roll 0.0 eq 9 1 roll 1.0 eq 9 1 roll 0.0 eq 9 1 roll 0.0 eq 9 1 roll 0.0 eq 9 1 roll 1.0 eq and and and and and and and and } {true}ifelse end or { clonedict begin /TransformPQR[ {4 -1 roll 3 get dup 3 1 roll sub 5 -1 roll 3 get 3 -1 roll sub div 3 -1 roll 3 get 3 -1 roll 3 get dup 4 1 roll sub mul add}bind {4 -1 roll 4 get dup 3 1 roll sub 5 -1 roll 4 get 3 -1 roll sub div 3 -1 roll 4 get 3 -1 roll 4 get dup 4 1 roll sub mul add}bind {4 -1 roll 5 get dup 3 1 roll sub 5 -1 roll 5 get 3 -1 roll sub div 3 -1 roll 5 get 3 -1 roll 5 get dup 4 1 roll sub mul add}bind ]def /MatrixPQR[0.8951 -0.7502 0.0389 0.2664 1.7135 -0.0685 -0.1614 0.0367 1.0296]def /RangePQR[-0.3227950745 2.3229645538 -1.5003771057 3.5003465881 -0.1369979095 2.136967392]def currentdict end }if setcolorrendering_opt }if }if }def /set_crd { AGMCORE_host_sep not level2 and{ currentdict/ColorRendering known{ ColorRendering/ColorRendering{findresource}stopped not{setcolorrendering_opt}if }{ currentdict/Intent known{ updatecolorrendering }if }ifelse currentcolorspace dup type/arraytype eq {0 get}if /DeviceRGB eq { currentdict/UCR known {/UCR}{/AGMCORE_currentucr}ifelse load setundercolorremoval currentdict/BG known {/BG}{/AGMCORE_currentbg}ifelse load setblackgeneration }if }if }def /set_ucrbg { dup null eq{pop/AGMCORE_currentbg load}{/Procedure get_res}ifelse setblackgeneration dup null eq{pop/AGMCORE_currentucr load}{/Procedure get_res}ifelse setundercolorremoval }def /setcolorrendering_opt { dup currentcolorrendering eq{ pop }{ clonedict begin /Intent Intent def currentdict end setcolorrendering }ifelse }def /cpaint_gcomp { convert_to_process//Adobe_AGM_Core/AGMCORE_ConvertToProcess xddf //Adobe_AGM_Core/AGMCORE_ConvertToProcess get not { (%end_cpaint_gcomp)flushinput }if }def /cpaint_gsep { //Adobe_AGM_Core/AGMCORE_ConvertToProcess get { (%end_cpaint_gsep)flushinput }if }def /cpaint_gend {np}def /T1_path { currentfile token pop currentfile token pop mo { currentfile token pop dup type/stringtype eq {pop exit}if 0 exch rlineto currentfile token pop dup type/stringtype eq {pop exit}if 0 rlineto }loop }def /T1_gsave level3 {/clipsave} {/gsave}ifelse load def /T1_grestore level3 {/cliprestore} {/grestore}ifelse load def /set_spot_alias_ary { dup inherit_aliases //Adobe_AGM_Core/AGMCORE_SpotAliasAry xddf }def /set_spot_normalization_ary { dup inherit_aliases dup length /AGMCORE_SpotAliasAry where{pop AGMCORE_SpotAliasAry length add}if array //Adobe_AGM_Core/AGMCORE_SpotAliasAry2 xddf /AGMCORE_SpotAliasAry where{ pop AGMCORE_SpotAliasAry2 0 AGMCORE_SpotAliasAry putinterval AGMCORE_SpotAliasAry length }{0}ifelse AGMCORE_SpotAliasAry2 3 1 roll exch putinterval true set_spot_alias }def /inherit_aliases { {dup/Name get map_alias{/CSD put}{pop}ifelse}forall }def /set_spot_alias { /AGMCORE_SpotAliasAry2 where{ /AGMCORE_current_spot_alias 3 -1 roll put }{ pop }ifelse }def /current_spot_alias { /AGMCORE_SpotAliasAry2 where{ /AGMCORE_current_spot_alias get }{ false }ifelse }def /map_alias { /AGMCORE_SpotAliasAry2 where{ begin /AGMCORE_name xdf false AGMCORE_SpotAliasAry2{ dup/Name get AGMCORE_name eq{ /CSD get/CSD get_res exch pop true exit }{ pop }ifelse }forall end }{ pop false }ifelse }bdf /spot_alias { true set_spot_alias /AGMCORE_&setcustomcolor AGMCORE_key_known not{ //Adobe_AGM_Core/AGMCORE_&setcustomcolor/setcustomcolor load put }if /customcolor_tint 1 AGMCORE_gput //Adobe_AGM_Core begin /setcustomcolor { //Adobe_AGM_Core begin dup/customcolor_tint exch AGMCORE_gput 1 index aload pop pop 1 eq exch 1 eq and exch 1 eq and exch 1 eq and not current_spot_alias and{1 index 4 get map_alias}{false}ifelse { false set_spot_alias /sep_colorspace_dict AGMCORE_gget null ne 3 1 roll 2 index{ exch pop/sep_tint AGMCORE_gget exch }if mark 3 1 roll setsepcolorspace counttomark 0 ne{ setsepcolor }if pop not{/sep_tint 1.0 AGMCORE_gput}if pop true set_spot_alias }{ AGMCORE_&setcustomcolor }ifelse end }bdf end }def /begin_feature { Adobe_AGM_Core/AGMCORE_feature_dictCount countdictstack put count Adobe_AGM_Core/AGMCORE_feature_opCount 3 -1 roll put {Adobe_AGM_Core/AGMCORE_feature_ctm matrix currentmatrix put}if }def /end_feature { 2 dict begin /spd/setpagedevice load def /setpagedevice{get_gstate spd set_gstate}def stopped{$error/newerror false put}if end count Adobe_AGM_Core/AGMCORE_feature_opCount get sub dup 0 gt{{pop}repeat}{pop}ifelse countdictstack Adobe_AGM_Core/AGMCORE_feature_dictCount get sub dup 0 gt{{end}repeat}{pop}ifelse {Adobe_AGM_Core/AGMCORE_feature_ctm get setmatrix}if }def /set_negative { //Adobe_AGM_Core begin /AGMCORE_inverting exch def level2{ currentpagedevice/NegativePrint known AGMCORE_distilling not and{ currentpagedevice/NegativePrint get//Adobe_AGM_Core/AGMCORE_inverting get ne{ true begin_feature true{ <>setpagedevice }end_feature }if /AGMCORE_inverting false def }if }if AGMCORE_inverting{ [{1 exch sub}/exec load dup currenttransfer exch]cvx bind settransfer AGMCORE_distilling{ erasepage }{ gsave np clippath 1/setseparationgray where{pop setseparationgray}{setgray}ifelse /AGMIRS_&fill where{pop AGMIRS_&fill}{fill}ifelse grestore }ifelse }if end }def /lw_save_restore_override{ /md where{ pop md begin initializepage /initializepage{}def /pmSVsetup{}def /endp{}def /pse{}def /psb{}def /orig_showpage where {pop} {/orig_showpage/showpage load def} ifelse /showpage{orig_showpage gR}def end }if }def /pscript_showpage_override{ /NTPSOct95 where { begin showpage save /showpage/restore load def /restore{exch pop}def end }if }def /driver_media_override { /md where{ pop md/initializepage known{ md/initializepage{}put }if md/rC known{ md/rC{4{pop}repeat}put }if }if /mysetup where{ /mysetup[1 0 0 1 0 0]put }if Adobe_AGM_Core/AGMCORE_Default_CTM matrix currentmatrix put level2 {Adobe_AGM_Core/AGMCORE_Default_PageSize currentpagedevice/PageSize get put}if }def /driver_check_media_override { /PrepsDict where {pop} { Adobe_AGM_Core/AGMCORE_Default_CTM get matrix currentmatrix ne Adobe_AGM_Core/AGMCORE_Default_PageSize get type/arraytype eq { Adobe_AGM_Core/AGMCORE_Default_PageSize get 0 get currentpagedevice/PageSize get 0 get eq and Adobe_AGM_Core/AGMCORE_Default_PageSize get 1 get currentpagedevice/PageSize get 1 get eq and }if { Adobe_AGM_Core/AGMCORE_Default_CTM get setmatrix }if }ifelse }def AGMCORE_err_strings begin /AGMCORE_bad_environ(Environment not satisfactory for this job. Ensure that the PPD is correct or that the PostScript level requested is supported by this printer. )def /AGMCORE_color_space_onhost_seps(This job contains colors that will not separate with on-host methods. )def /AGMCORE_invalid_color_space(This job contains an invalid color space. )def end /set_def_ht {AGMCORE_def_ht sethalftone}def /set_def_flat {AGMCORE_Default_flatness setflat}def end systemdict/setpacking known {setpacking}if %%EndResource %%BeginResource: procset Adobe_CoolType_Core 2.31 0 %%Copyright: Copyright 1997-2006 Adobe Systems Incorporated. All Rights Reserved. %%Version: 2.31 0 10 dict begin /Adobe_CoolType_Passthru currentdict def /Adobe_CoolType_Core_Defined userdict/Adobe_CoolType_Core known def Adobe_CoolType_Core_Defined {/Adobe_CoolType_Core userdict/Adobe_CoolType_Core get def} if userdict/Adobe_CoolType_Core 70 dict dup begin put /Adobe_CoolType_Version 2.31 def /Level2? systemdict/languagelevel known dup {pop systemdict/languagelevel get 2 ge} if def Level2? not { /currentglobal false def /setglobal/pop load def /gcheck{pop false}bind def /currentpacking false def /setpacking/pop load def /SharedFontDirectory 0 dict def } if currentpacking true setpacking currentglobal false setglobal userdict/Adobe_CoolType_Data 2 copy known not {2 copy 10 dict put} if get begin /@opStackCountByLevel 32 dict def /@opStackLevel 0 def /@dictStackCountByLevel 32 dict def /@dictStackLevel 0 def end setglobal currentglobal true setglobal userdict/Adobe_CoolType_GVMFonts known not {userdict/Adobe_CoolType_GVMFonts 10 dict put} if setglobal currentglobal false setglobal userdict/Adobe_CoolType_LVMFonts known not {userdict/Adobe_CoolType_LVMFonts 10 dict put} if setglobal /ct_VMDictPut { dup gcheck{Adobe_CoolType_GVMFonts}{Adobe_CoolType_LVMFonts}ifelse 3 1 roll put }bind def /ct_VMDictUndef { dup Adobe_CoolType_GVMFonts exch known {Adobe_CoolType_GVMFonts exch undef} { dup Adobe_CoolType_LVMFonts exch known {Adobe_CoolType_LVMFonts exch undef} {pop} ifelse }ifelse }bind def /ct_str1 1 string def /ct_xshow { /_ct_na exch def /_ct_i 0 def currentpoint /_ct_y exch def /_ct_x exch def { pop pop ct_str1 exch 0 exch put ct_str1 show {_ct_na _ct_i get}stopped {pop pop} { _ct_x _ct_y moveto 0 rmoveto } ifelse /_ct_i _ct_i 1 add def currentpoint /_ct_y exch def /_ct_x exch def } exch @cshow }bind def /ct_yshow { /_ct_na exch def /_ct_i 0 def currentpoint /_ct_y exch def /_ct_x exch def { pop pop ct_str1 exch 0 exch put ct_str1 show {_ct_na _ct_i get}stopped {pop pop} { _ct_x _ct_y moveto 0 exch rmoveto } ifelse /_ct_i _ct_i 1 add def currentpoint /_ct_y exch def /_ct_x exch def } exch @cshow }bind def /ct_xyshow { /_ct_na exch def /_ct_i 0 def currentpoint /_ct_y exch def /_ct_x exch def { pop pop ct_str1 exch 0 exch put ct_str1 show {_ct_na _ct_i get}stopped {pop pop} { {_ct_na _ct_i 1 add get}stopped {pop pop pop} { _ct_x _ct_y moveto rmoveto } ifelse } ifelse /_ct_i _ct_i 2 add def currentpoint /_ct_y exch def /_ct_x exch def } exch @cshow }bind def /xsh{{@xshow}stopped{Adobe_CoolType_Data begin ct_xshow end}if}bind def /ysh{{@yshow}stopped{Adobe_CoolType_Data begin ct_yshow end}if}bind def /xysh{{@xyshow}stopped{Adobe_CoolType_Data begin ct_xyshow end}if}bind def currentglobal true setglobal /ct_T3Defs { /BuildChar { 1 index/Encoding get exch get 1 index/BuildGlyph get exec }bind def /BuildGlyph { exch begin GlyphProcs exch get exec end }bind def }bind def setglobal /@_SaveStackLevels { Adobe_CoolType_Data begin /@vmState currentglobal def false setglobal @opStackCountByLevel @opStackLevel 2 copy known not { 2 copy 3 dict dup/args 7 index 5 add array put put get } { get dup/args get dup length 3 index lt { dup length 5 add array exch 1 index exch 0 exch putinterval 1 index exch/args exch put } {pop} ifelse } ifelse begin count 1 sub 1 index lt {pop count} if dup/argCount exch def dup 0 gt { args exch 0 exch getinterval astore pop } {pop} ifelse count /restCount exch def end /@opStackLevel @opStackLevel 1 add def countdictstack 1 sub @dictStackCountByLevel exch @dictStackLevel exch put /@dictStackLevel @dictStackLevel 1 add def @vmState setglobal end }bind def /@_RestoreStackLevels { Adobe_CoolType_Data begin /@opStackLevel @opStackLevel 1 sub def @opStackCountByLevel @opStackLevel get begin count restCount sub dup 0 gt {{pop}repeat} {pop} ifelse args 0 argCount getinterval{}forall end /@dictStackLevel @dictStackLevel 1 sub def @dictStackCountByLevel @dictStackLevel get end countdictstack exch sub dup 0 gt {{end}repeat} {pop} ifelse }bind def /@_PopStackLevels { Adobe_CoolType_Data begin /@opStackLevel @opStackLevel 1 sub def /@dictStackLevel @dictStackLevel 1 sub def end }bind def /@Raise { exch cvx exch errordict exch get exec stop }bind def /@ReRaise { cvx $error/errorname get errordict exch get exec stop }bind def /@Stopped { 0 @#Stopped }bind def /@#Stopped { @_SaveStackLevels stopped {@_RestoreStackLevels true} {@_PopStackLevels false} ifelse }bind def /@Arg { Adobe_CoolType_Data begin @opStackCountByLevel @opStackLevel 1 sub get begin args exch argCount 1 sub exch sub get end end }bind def currentglobal true setglobal /CTHasResourceForAllBug Level2? { 1 dict dup /@shouldNotDisappearDictValue true def Adobe_CoolType_Data exch/@shouldNotDisappearDict exch put begin count @_SaveStackLevels {(*){pop stop}128 string/Category resourceforall} stopped pop @_RestoreStackLevels currentdict Adobe_CoolType_Data/@shouldNotDisappearDict get dup 3 1 roll ne dup 3 1 roll { /@shouldNotDisappearDictValue known { { end currentdict 1 index eq {pop exit} if } loop } if } { pop end } ifelse } {false} ifelse def true setglobal /CTHasResourceStatusBug Level2? { mark {/steveamerige/Category resourcestatus} stopped {cleartomark true} {cleartomark currentglobal not} ifelse } {false} ifelse def setglobal /CTResourceStatus { mark 3 1 roll /Category findresource begin ({ResourceStatus}stopped)0()/SubFileDecode filter cvx exec {cleartomark false} {{3 2 roll pop true}{cleartomark false}ifelse} ifelse end }bind def /CTWorkAroundBugs { Level2? { /cid_PreLoad/ProcSet resourcestatus { pop pop currentglobal mark { (*) { dup/CMap CTHasResourceStatusBug {CTResourceStatus} {resourcestatus} ifelse { pop dup 0 eq exch 1 eq or { dup/CMap findresource gcheck setglobal /CMap undefineresource } { pop CTHasResourceForAllBug {exit} {stop} ifelse } ifelse } {pop} ifelse } 128 string/CMap resourceforall } stopped {cleartomark} stopped pop setglobal } if } if }bind def /ds { Adobe_CoolType_Core begin CTWorkAroundBugs /mo/moveto load def /nf/newencodedfont load def /msf{makefont setfont}bind def /uf{dup undefinefont ct_VMDictUndef}bind def /ur/undefineresource load def /chp/charpath load def /awsh/awidthshow load def /wsh/widthshow load def /ash/ashow load def /@xshow/xshow load def /@yshow/yshow load def /@xyshow/xyshow load def /@cshow/cshow load def /sh/show load def /rp/repeat load def /.n/.notdef def end currentglobal false setglobal userdict/Adobe_CoolType_Data 2 copy known not {2 copy 10 dict put} if get begin /AddWidths? false def /CC 0 def /charcode 2 string def /@opStackCountByLevel 32 dict def /@opStackLevel 0 def /@dictStackCountByLevel 32 dict def /@dictStackLevel 0 def /InVMFontsByCMap 10 dict def /InVMDeepCopiedFonts 10 dict def end setglobal }bind def /dt { currentdict Adobe_CoolType_Core eq {end} if }bind def /ps { Adobe_CoolType_Core begin Adobe_CoolType_GVMFonts begin Adobe_CoolType_LVMFonts begin SharedFontDirectory begin }bind def /pt { end end end end }bind def /unload { systemdict/languagelevel known { systemdict/languagelevel get 2 ge { userdict/Adobe_CoolType_Core 2 copy known {undef} {pop pop} ifelse } if } if }bind def /ndf { 1 index where {pop pop pop} {dup xcheck{bind}if def} ifelse }def /findfont systemdict begin userdict begin /globaldict where{/globaldict get begin}if dup where pop exch get /globaldict where{pop end}if end end Adobe_CoolType_Core_Defined {/systemfindfont exch def} { /findfont 1 index def /systemfindfont exch def } ifelse /undefinefont {pop}ndf /copyfont { currentglobal 3 1 roll 1 index gcheck setglobal dup null eq{0}{dup length}ifelse 2 index length add 1 add dict begin exch { 1 index/FID eq {pop pop} {def} ifelse } forall dup null eq {pop} {{def}forall} ifelse currentdict end exch setglobal }bind def /copyarray { currentglobal exch dup gcheck setglobal dup length array copy exch setglobal }bind def /newencodedfont { currentglobal { SharedFontDirectory 3 index known {SharedFontDirectory 3 index get/FontReferenced known} {false} ifelse } { FontDirectory 3 index known {FontDirectory 3 index get/FontReferenced known} { SharedFontDirectory 3 index known {SharedFontDirectory 3 index get/FontReferenced known} {false} ifelse } ifelse } ifelse dup { 3 index findfont/FontReferenced get 2 index dup type/nametype eq {findfont} if ne {pop false} if } if dup { 1 index dup type/nametype eq {findfont} if dup/CharStrings known { /CharStrings get length 4 index findfont/CharStrings get length ne { pop false } if } {pop} ifelse } if { pop 1 index findfont /Encoding get exch 0 1 255 {2 copy get 3 index 3 1 roll put} for pop pop pop } { currentglobal 4 1 roll dup type/nametype eq {findfont} if dup gcheck setglobal dup dup maxlength 2 add dict begin exch { 1 index/FID ne 2 index/Encoding ne and {def} {pop pop} ifelse } forall /FontReferenced exch def /Encoding exch dup length array copy def /FontName 1 index dup type/stringtype eq{cvn}if def dup currentdict end definefont ct_VMDictPut setglobal } ifelse }bind def /SetSubstituteStrategy { $SubstituteFont begin dup type/dicttype ne {0 dict} if currentdict/$Strategies known { exch $Strategies exch 2 copy known { get 2 copy maxlength exch maxlength add dict begin {def}forall {def}forall currentdict dup/$Init known {dup/$Init get exec} if end /$Strategy exch def } {pop pop pop} ifelse } {pop pop} ifelse end }bind def /scff { $SubstituteFont begin dup type/stringtype eq {dup length exch} {null} ifelse /$sname exch def /$slen exch def /$inVMIndex $sname null eq { 1 index $str cvs dup length $slen sub $slen getinterval cvn } {$sname} ifelse def end {findfont} @Stopped { dup length 8 add string exch 1 index 0(BadFont:)putinterval 1 index exch 8 exch dup length string cvs putinterval cvn {findfont} @Stopped {pop/Courier findfont} if } if $SubstituteFont begin /$sname null def /$slen 0 def /$inVMIndex null def end }bind def /isWidthsOnlyFont { dup/WidthsOnly known {pop pop true} { dup/FDepVector known {/FDepVector get{isWidthsOnlyFont dup{exit}if}forall} { dup/FDArray known {/FDArray get{isWidthsOnlyFont dup{exit}if}forall} {pop} ifelse } ifelse } ifelse }bind def /ct_StyleDicts 4 dict dup begin /Adobe-Japan1 4 dict dup begin Level2? { /Serif /HeiseiMin-W3-83pv-RKSJ-H/Font resourcestatus {pop pop/HeiseiMin-W3} { /CIDFont/Category resourcestatus { pop pop /HeiseiMin-W3/CIDFont resourcestatus {pop pop/HeiseiMin-W3} {/Ryumin-Light} ifelse } {/Ryumin-Light} ifelse } ifelse def /SansSerif /HeiseiKakuGo-W5-83pv-RKSJ-H/Font resourcestatus {pop pop/HeiseiKakuGo-W5} { /CIDFont/Category resourcestatus { pop pop /HeiseiKakuGo-W5/CIDFont resourcestatus {pop pop/HeiseiKakuGo-W5} {/GothicBBB-Medium} ifelse } {/GothicBBB-Medium} ifelse } ifelse def /HeiseiMaruGo-W4-83pv-RKSJ-H/Font resourcestatus {pop pop/HeiseiMaruGo-W4} { /CIDFont/Category resourcestatus { pop pop /HeiseiMaruGo-W4/CIDFont resourcestatus {pop pop/HeiseiMaruGo-W4} { /Jun101-Light-RKSJ-H/Font resourcestatus {pop pop/Jun101-Light} {SansSerif} ifelse } ifelse } { /Jun101-Light-RKSJ-H/Font resourcestatus {pop pop/Jun101-Light} {SansSerif} ifelse } ifelse } ifelse /RoundSansSerif exch def /Default Serif def } { /Serif/Ryumin-Light def /SansSerif/GothicBBB-Medium def { (fonts/Jun101-Light-83pv-RKSJ-H)status }stopped {pop}{ {pop pop pop pop/Jun101-Light} {SansSerif} ifelse /RoundSansSerif exch def }ifelse /Default Serif def } ifelse end def /Adobe-Korea1 4 dict dup begin /Serif/HYSMyeongJo-Medium def /SansSerif/HYGoThic-Medium def /RoundSansSerif SansSerif def /Default Serif def end def /Adobe-GB1 4 dict dup begin /Serif/STSong-Light def /SansSerif/STHeiti-Regular def /RoundSansSerif SansSerif def /Default Serif def end def /Adobe-CNS1 4 dict dup begin /Serif/MKai-Medium def /SansSerif/MHei-Medium def /RoundSansSerif SansSerif def /Default Serif def end def end def Level2?{currentglobal true setglobal}if /ct_BoldRomanWidthProc { stringwidth 1 index 0 ne{exch .03 add exch}if setcharwidth 0 0 }bind def /ct_Type0WidthProc { dup stringwidth 0 0 moveto 2 index true charpath pathbbox 0 -1 7 index 2 div .88 setcachedevice2 pop 0 0 }bind def /ct_Type0WMode1WidthProc { dup stringwidth pop 2 div neg -0.88 2 copy moveto 0 -1 5 -1 roll true charpath pathbbox setcachedevice }bind def /cHexEncoding [/c00/c01/c02/c03/c04/c05/c06/c07/c08/c09/c0A/c0B/c0C/c0D/c0E/c0F/c10/c11/c12 /c13/c14/c15/c16/c17/c18/c19/c1A/c1B/c1C/c1D/c1E/c1F/c20/c21/c22/c23/c24/c25 /c26/c27/c28/c29/c2A/c2B/c2C/c2D/c2E/c2F/c30/c31/c32/c33/c34/c35/c36/c37/c38 /c39/c3A/c3B/c3C/c3D/c3E/c3F/c40/c41/c42/c43/c44/c45/c46/c47/c48/c49/c4A/c4B /c4C/c4D/c4E/c4F/c50/c51/c52/c53/c54/c55/c56/c57/c58/c59/c5A/c5B/c5C/c5D/c5E /c5F/c60/c61/c62/c63/c64/c65/c66/c67/c68/c69/c6A/c6B/c6C/c6D/c6E/c6F/c70/c71 /c72/c73/c74/c75/c76/c77/c78/c79/c7A/c7B/c7C/c7D/c7E/c7F/c80/c81/c82/c83/c84 /c85/c86/c87/c88/c89/c8A/c8B/c8C/c8D/c8E/c8F/c90/c91/c92/c93/c94/c95/c96/c97 /c98/c99/c9A/c9B/c9C/c9D/c9E/c9F/cA0/cA1/cA2/cA3/cA4/cA5/cA6/cA7/cA8/cA9/cAA /cAB/cAC/cAD/cAE/cAF/cB0/cB1/cB2/cB3/cB4/cB5/cB6/cB7/cB8/cB9/cBA/cBB/cBC/cBD /cBE/cBF/cC0/cC1/cC2/cC3/cC4/cC5/cC6/cC7/cC8/cC9/cCA/cCB/cCC/cCD/cCE/cCF/cD0 /cD1/cD2/cD3/cD4/cD5/cD6/cD7/cD8/cD9/cDA/cDB/cDC/cDD/cDE/cDF/cE0/cE1/cE2/cE3 /cE4/cE5/cE6/cE7/cE8/cE9/cEA/cEB/cEC/cED/cEE/cEF/cF0/cF1/cF2/cF3/cF4/cF5/cF6 /cF7/cF8/cF9/cFA/cFB/cFC/cFD/cFE/cFF]def /ct_BoldBaseFont 11 dict begin /FontType 3 def /FontMatrix[1 0 0 1 0 0]def /FontBBox[0 0 1 1]def /Encoding cHexEncoding def /_setwidthProc/ct_BoldRomanWidthProc load def /_bcstr1 1 string def /BuildChar { exch begin _basefont setfont _bcstr1 dup 0 4 -1 roll put dup _setwidthProc 3 copy moveto show _basefonto setfont moveto show end }bind def currentdict end def systemdict/composefont known { /ct_DefineIdentity-H { /Identity-H/CMap resourcestatus { pop pop } { /CIDInit/ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo 3 dict dup begin /Registry(Adobe)def /Ordering(Identity)def /Supplement 0 def end def /CMapName/Identity-H def /CMapVersion 1.000 def /CMapType 1 def 1 begincodespacerange <0000> endcodespacerange 1 begincidrange <0000>0 endcidrange endcmap CMapName currentdict/CMap defineresource pop end end } ifelse } def /ct_BoldBaseCIDFont 11 dict begin /CIDFontType 1 def /CIDFontName/ct_BoldBaseCIDFont def /FontMatrix[1 0 0 1 0 0]def /FontBBox[0 0 1 1]def /_setwidthProc/ct_Type0WidthProc load def /_bcstr2 2 string def /BuildGlyph { exch begin _basefont setfont _bcstr2 1 2 index 256 mod put _bcstr2 0 3 -1 roll 256 idiv put _bcstr2 dup _setwidthProc 3 copy moveto show _basefonto setfont moveto show end }bind def currentdict end def }if Level2?{setglobal}if /ct_CopyFont{ { 1 index/FID ne 2 index/UniqueID ne and {def}{pop pop}ifelse }forall }bind def /ct_Type0CopyFont { exch dup length dict begin ct_CopyFont [ exch FDepVector { dup/FontType get 0 eq { 1 index ct_Type0CopyFont /_ctType0 exch definefont } { /_ctBaseFont exch 2 index exec } ifelse exch } forall pop ] /FDepVector exch def currentdict end }bind def /ct_MakeBoldFont { dup/ct_SyntheticBold known { dup length 3 add dict begin ct_CopyFont /ct_StrokeWidth .03 0 FontMatrix idtransform pop def /ct_SyntheticBold true def currentdict end definefont } { dup dup length 3 add dict begin ct_CopyFont /PaintType 2 def /StrokeWidth .03 0 FontMatrix idtransform pop def /dummybold currentdict end definefont dup/FontType get dup 9 ge exch 11 le and { ct_BoldBaseCIDFont dup length 3 add dict copy begin dup/CIDSystemInfo get/CIDSystemInfo exch def ct_DefineIdentity-H /_Type0Identity/Identity-H 3 -1 roll[exch]composefont /_basefont exch def /_Type0Identity/Identity-H 3 -1 roll[exch]composefont /_basefonto exch def currentdict end /CIDFont defineresource } { ct_BoldBaseFont dup length 3 add dict copy begin /_basefont exch def /_basefonto exch def currentdict end definefont } ifelse } ifelse }bind def /ct_MakeBold{ 1 index 1 index findfont currentglobal 5 1 roll dup gcheck setglobal dup /FontType get 0 eq { dup/WMode known{dup/WMode get 1 eq}{false}ifelse version length 4 ge and {version 0 4 getinterval cvi 2015 ge} {true} ifelse {/ct_Type0WidthProc} {/ct_Type0WMode1WidthProc} ifelse ct_BoldBaseFont/_setwidthProc 3 -1 roll load put {ct_MakeBoldFont}ct_Type0CopyFont definefont } { dup/_fauxfont known not 1 index/SubstMaster known not and { ct_BoldBaseFont/_setwidthProc /ct_BoldRomanWidthProc load put ct_MakeBoldFont } { 2 index 2 index eq {exch pop } { dup length dict begin ct_CopyFont currentdict end definefont } ifelse } ifelse } ifelse pop pop pop setglobal }bind def /?str1 256 string def /?set { $SubstituteFont begin /$substituteFound false def /$fontname 1 index def /$doSmartSub false def end dup findfont $SubstituteFont begin $substituteFound {false} { dup/FontName known { dup/FontName get $fontname eq 1 index/DistillerFauxFont known not and /currentdistillerparams where {pop false 2 index isWidthsOnlyFont not and} if } {false} ifelse } ifelse exch pop /$doSmartSub true def end { 5 1 roll pop pop pop pop findfont } { 1 index findfont dup/FontType get 3 eq { 6 1 roll pop pop pop pop pop false } {pop true} ifelse { $SubstituteFont begin pop pop /$styleArray 1 index def /$regOrdering 2 index def pop pop 0 1 $styleArray length 1 sub { $styleArray exch get ct_StyleDicts $regOrdering 2 copy known { get exch 2 copy known not {pop/Default} if get dup type/nametype eq { ?str1 cvs length dup 1 add exch ?str1 exch(-)putinterval exch dup length exch ?str1 exch 3 index exch putinterval add ?str1 exch 0 exch getinterval cvn } { pop pop/Unknown } ifelse } { pop pop pop pop/Unknown } ifelse } for end findfont }if } ifelse currentglobal false setglobal 3 1 roll null copyfont definefont pop setglobal }bind def setpacking userdict/$SubstituteFont 25 dict put 1 dict begin /SubstituteFont dup $error exch 2 copy known {get} {pop pop{pop/Courier}bind} ifelse def /currentdistillerparams where dup { pop pop currentdistillerparams/CannotEmbedFontPolicy 2 copy known {get/Error eq} {pop pop false} ifelse } if not { countdictstack array dictstack 0 get begin userdict begin $SubstituteFont begin /$str 128 string def /$fontpat 128 string def /$slen 0 def /$sname null def /$match false def /$fontname null def /$substituteFound false def /$inVMIndex null def /$doSmartSub true def /$depth 0 def /$fontname null def /$italicangle 26.5 def /$dstack null def /$Strategies 10 dict dup begin /$Type3Underprint { currentglobal exch false setglobal 11 dict begin /UseFont exch $WMode 0 ne { dup length dict copy dup/WMode $WMode put /UseFont exch definefont } if def /FontName $fontname dup type/stringtype eq{cvn}if def /FontType 3 def /FontMatrix[.001 0 0 .001 0 0]def /Encoding 256 array dup 0 1 255{/.notdef put dup}for pop def /FontBBox[0 0 0 0]def /CCInfo 7 dict dup begin /cc null def /x 0 def /y 0 def end def /BuildChar { exch begin CCInfo begin 1 string dup 0 3 index put exch pop /cc exch def UseFont 1000 scalefont setfont cc stringwidth/y exch def/x exch def x y setcharwidth $SubstituteFont/$Strategy get/$Underprint get exec 0 0 moveto cc show x y moveto end end }bind def currentdict end exch setglobal }bind def /$GetaTint 2 dict dup begin /$BuildFont { dup/WMode known {dup/WMode get} {0} ifelse /$WMode exch def $fontname exch dup/FontName known { dup/FontName get dup type/stringtype eq{cvn}if } {/unnamedfont} ifelse exch Adobe_CoolType_Data/InVMDeepCopiedFonts get 1 index/FontName get known { pop Adobe_CoolType_Data/InVMDeepCopiedFonts get 1 index get null copyfont } {$deepcopyfont} ifelse exch 1 index exch/FontBasedOn exch put dup/FontName $fontname dup type/stringtype eq{cvn}if put definefont Adobe_CoolType_Data/InVMDeepCopiedFonts get begin dup/FontBasedOn get 1 index def end }bind def /$Underprint { gsave x abs y abs gt {/y 1000 def} {/x -1000 def 500 120 translate} ifelse Level2? { [/Separation(All)/DeviceCMYK{0 0 0 1 pop}] setcolorspace } {0 setgray} ifelse 10 setlinewidth x .8 mul [7 3] { y mul 8 div 120 sub x 10 div exch moveto 0 y 4 div neg rlineto dup 0 rlineto 0 y 4 div rlineto closepath gsave Level2? {.2 setcolor} {.8 setgray} ifelse fill grestore stroke } forall pop grestore }bind def end def /$Oblique 1 dict dup begin /$BuildFont { currentglobal exch dup gcheck setglobal null copyfont begin /FontBasedOn currentdict/FontName known { FontName dup type/stringtype eq{cvn}if } {/unnamedfont} ifelse def /FontName $fontname dup type/stringtype eq{cvn}if def /currentdistillerparams where {pop} { /FontInfo currentdict/FontInfo known {FontInfo null copyfont} {2 dict} ifelse dup begin /ItalicAngle $italicangle def /FontMatrix FontMatrix [1 0 ItalicAngle dup sin exch cos div 1 0 0] matrix concatmatrix readonly end 4 2 roll def def } ifelse FontName currentdict end definefont exch setglobal }bind def end def /$None 1 dict dup begin /$BuildFont{}bind def end def end def /$Oblique SetSubstituteStrategy /$findfontByEnum { dup type/stringtype eq{cvn}if dup/$fontname exch def $sname null eq {$str cvs dup length $slen sub $slen getinterval} {pop $sname} ifelse $fontpat dup 0(fonts/*)putinterval exch 7 exch putinterval /$match false def $SubstituteFont/$dstack countdictstack array dictstack put mark { $fontpat 0 $slen 7 add getinterval {/$match exch def exit} $str filenameforall } stopped { cleardictstack currentdict true $SubstituteFont/$dstack get { exch { 1 index eq {pop false} {true} ifelse } {begin false} ifelse } forall pop } if cleartomark /$slen 0 def $match false ne {$match(fonts/)anchorsearch pop pop cvn} {/Courier} ifelse }bind def /$ROS 1 dict dup begin /Adobe 4 dict dup begin /Japan1 [/Ryumin-Light/HeiseiMin-W3 /GothicBBB-Medium/HeiseiKakuGo-W5 /HeiseiMaruGo-W4/Jun101-Light]def /Korea1 [/HYSMyeongJo-Medium/HYGoThic-Medium]def /GB1 [/STSong-Light/STHeiti-Regular]def /CNS1 [/MKai-Medium/MHei-Medium]def end def end def /$cmapname null def /$deepcopyfont { dup/FontType get 0 eq { 1 dict dup/FontName/copied put copyfont begin /FDepVector FDepVector copyarray 0 1 2 index length 1 sub { 2 copy get $deepcopyfont dup/FontName/copied put /copied exch definefont 3 copy put pop pop } for def currentdict end } {$Strategies/$Type3Underprint get exec} ifelse }bind def /$buildfontname { dup/CIDFont findresource/CIDSystemInfo get begin Registry length Ordering length Supplement 8 string cvs 3 copy length 2 add add add string dup 5 1 roll dup 0 Registry putinterval dup 4 index(-)putinterval dup 4 index 1 add Ordering putinterval 4 2 roll add 1 add 2 copy(-)putinterval end 1 add 2 copy 0 exch getinterval $cmapname $fontpat cvs exch anchorsearch {pop pop 3 2 roll putinterval cvn/$cmapname exch def} {pop pop pop pop pop} ifelse length $str 1 index(-)putinterval 1 add $str 1 index $cmapname $fontpat cvs putinterval $cmapname length add $str exch 0 exch getinterval cvn }bind def /$findfontByROS { /$fontname exch def $ROS Registry 2 copy known { get Ordering 2 copy known {get} {pop pop[]} ifelse } {pop pop[]} ifelse false exch { dup/CIDFont resourcestatus { pop pop save 1 index/CIDFont findresource dup/WidthsOnly known {dup/WidthsOnly get} {false} ifelse exch pop exch restore {pop} {exch pop true exit} ifelse } {pop} ifelse } forall {$str cvs $buildfontname} { false(*) { save exch dup/CIDFont findresource dup/WidthsOnly known {dup/WidthsOnly get not} {true} ifelse exch/CIDSystemInfo get dup/Registry get Registry eq exch/Ordering get Ordering eq and and {exch restore exch pop true exit} {pop restore} ifelse } $str/CIDFont resourceforall {$buildfontname} {$fontname $findfontByEnum} ifelse } ifelse }bind def end end currentdict/$error known currentdict/languagelevel known and dup {pop $error/SubstituteFont known} if dup {$error} {Adobe_CoolType_Core} ifelse begin { /SubstituteFont /CMap/Category resourcestatus { pop pop { $SubstituteFont begin /$substituteFound true def dup length $slen gt $sname null ne or $slen 0 gt and { $sname null eq {dup $str cvs dup length $slen sub $slen getinterval cvn} {$sname} ifelse Adobe_CoolType_Data/InVMFontsByCMap get 1 index 2 copy known { get false exch { pop currentglobal { GlobalFontDirectory 1 index known {exch pop true exit} {pop} ifelse } { FontDirectory 1 index known {exch pop true exit} { GlobalFontDirectory 1 index known {exch pop true exit} {pop} ifelse } ifelse } ifelse } forall } {pop pop false} ifelse { exch pop exch pop } { dup/CMap resourcestatus { pop pop dup/$cmapname exch def /CMap findresource/CIDSystemInfo get{def}forall $findfontByROS } { 128 string cvs dup(-)search { 3 1 roll search { 3 1 roll pop {dup cvi} stopped {pop pop pop pop pop $findfontByEnum} { 4 2 roll pop pop exch length exch 2 index length 2 index sub exch 1 sub -1 0 { $str cvs dup length 4 index 0 4 index 4 3 roll add getinterval exch 1 index exch 3 index exch putinterval dup/CMap resourcestatus { pop pop 4 1 roll pop pop pop dup/$cmapname exch def /CMap findresource/CIDSystemInfo get{def}forall $findfontByROS true exit } {pop} ifelse } for dup type/booleantype eq {pop} {pop pop pop $findfontByEnum} ifelse } ifelse } {pop pop pop $findfontByEnum} ifelse } {pop pop $findfontByEnum} ifelse } ifelse } ifelse } {//SubstituteFont exec} ifelse /$slen 0 def end } } { { $SubstituteFont begin /$substituteFound true def dup length $slen gt $sname null ne or $slen 0 gt and {$findfontByEnum} {//SubstituteFont exec} ifelse end } } ifelse bind readonly def Adobe_CoolType_Core/scfindfont/systemfindfont load put } { /scfindfont { $SubstituteFont begin dup systemfindfont dup/FontName known {dup/FontName get dup 3 index ne} {/noname true} ifelse dup { /$origfontnamefound 2 index def /$origfontname 4 index def/$substituteFound true def } if exch pop { $slen 0 gt $sname null ne 3 index length $slen gt or and { pop dup $findfontByEnum findfont dup maxlength 1 add dict begin {1 index/FID eq{pop pop}{def}ifelse} forall currentdict end definefont dup/FontName known{dup/FontName get}{null}ifelse $origfontnamefound ne { $origfontname $str cvs print ( substitution revised, using )print dup/FontName known {dup/FontName get}{(unspecified font)} ifelse $str cvs print(.\n)print } if } {exch pop} ifelse } {exch pop} ifelse end }bind def } ifelse end end Adobe_CoolType_Core_Defined not { Adobe_CoolType_Core/findfont { $SubstituteFont begin $depth 0 eq { /$fontname 1 index dup type/stringtype ne{$str cvs}if def /$substituteFound false def } if /$depth $depth 1 add def end scfindfont $SubstituteFont begin /$depth $depth 1 sub def $substituteFound $depth 0 eq and { $inVMIndex null ne {dup $inVMIndex $AddInVMFont} if $doSmartSub { currentdict/$Strategy known {$Strategy/$BuildFont get exec} if } if } if end }bind put } if } if end /$AddInVMFont { exch/FontName 2 copy known { get 1 dict dup begin exch 1 index gcheck def end exch Adobe_CoolType_Data/InVMFontsByCMap get exch $DictAdd } {pop pop pop} ifelse }bind def /$DictAdd { 2 copy known not {2 copy 4 index length dict put} if Level2? not { 2 copy get dup maxlength exch length 4 index length add lt 2 copy get dup length 4 index length add exch maxlength 1 index lt { 2 mul dict begin 2 copy get{forall}def 2 copy currentdict put end } {pop} ifelse } if get begin {def} forall end }bind def end end %%EndResource currentglobal true setglobal %%BeginResource: procset Adobe_CoolType_Utility_MAKEOCF 1.23 0 %%Copyright: Copyright 1987-2006 Adobe Systems Incorporated. %%Version: 1.23 0 systemdict/languagelevel known dup {currentglobal false setglobal} {false} ifelse exch userdict/Adobe_CoolType_Utility 2 copy known {2 copy get dup maxlength 27 add dict copy} {27 dict} ifelse put Adobe_CoolType_Utility begin /@eexecStartData def /@recognizeCIDFont null def /ct_Level2? exch def /ct_Clone? 1183615869 internaldict dup /CCRun known not exch/eCCRun known not ct_Level2? and or def ct_Level2? {globaldict begin currentglobal true setglobal} if /ct_AddStdCIDMap ct_Level2? {{ mark Adobe_CoolType_Utility/@recognizeCIDFont currentdict put { ((Hex)57 StartData 0615 1e27 2c39 1c60 d8a8 cc31 fe2b f6e0 7aa3 e541 e21c 60d8 a8c9 c3d0 6d9e 1c60 d8a8 c9c2 02d7 9a1c 60d8 a849 1c60 d8a8 cc36 74f4 1144 b13b 77)0()/SubFileDecode filter cvx exec } stopped { cleartomark Adobe_CoolType_Utility/@recognizeCIDFont get countdictstack dup array dictstack exch 1 sub -1 0 { 2 copy get 3 index eq {1 index length exch sub 1 sub{end}repeat exit} {pop} ifelse } for pop pop Adobe_CoolType_Utility/@eexecStartData get eexec } {cleartomark} ifelse }} {{ Adobe_CoolType_Utility/@eexecStartData get eexec }} ifelse bind def userdict/cid_extensions known dup{cid_extensions/cid_UpdateDB known and}if { cid_extensions begin /cid_GetCIDSystemInfo { 1 index type/stringtype eq {exch cvn exch} if cid_extensions begin dup load 2 index known { 2 copy cid_GetStatusInfo dup null ne { 1 index load 3 index get dup null eq {pop pop cid_UpdateDB} { exch 1 index/Created get eq {exch pop exch pop} {pop cid_UpdateDB} ifelse } ifelse } {pop cid_UpdateDB} ifelse } {cid_UpdateDB} ifelse end }bind def end } if ct_Level2? {end setglobal} if /ct_UseNativeCapability? systemdict/composefont known def /ct_MakeOCF 35 dict def /ct_Vars 25 dict def /ct_GlyphDirProcs 6 dict def /ct_BuildCharDict 15 dict dup begin /charcode 2 string def /dst_string 1500 string def /nullstring()def /usewidths? true def end def ct_Level2?{setglobal}{pop}ifelse ct_GlyphDirProcs begin /GetGlyphDirectory { systemdict/languagelevel known {pop/CIDFont findresource/GlyphDirectory get} { 1 index/CIDFont findresource/GlyphDirectory get dup type/dicttype eq { dup dup maxlength exch length sub 2 index lt { dup length 2 index add dict copy 2 index /CIDFont findresource/GlyphDirectory 2 index put } if } if exch pop exch pop } ifelse + }def /+ { systemdict/languagelevel known { currentglobal false setglobal 3 dict begin /vm exch def } {1 dict begin} ifelse /$ exch def systemdict/languagelevel known { vm setglobal /gvm currentglobal def $ gcheck setglobal } if ?{$ begin}if }def /?{$ type/dicttype eq}def /|{ userdict/Adobe_CoolType_Data known { Adobe_CoolType_Data/AddWidths? known { currentdict Adobe_CoolType_Data begin begin AddWidths? { Adobe_CoolType_Data/CC 3 index put ?{def}{$ 3 1 roll put}ifelse CC charcode exch 1 index 0 2 index 256 idiv put 1 index exch 1 exch 256 mod put stringwidth 2 array astore currentfont/Widths get exch CC exch put } {?{def}{$ 3 1 roll put}ifelse} ifelse end end } {?{def}{$ 3 1 roll put}ifelse} ifelse } {?{def}{$ 3 1 roll put}ifelse} ifelse }def /! { ?{end}if systemdict/languagelevel known {gvm setglobal} if end }def /:{string currentfile exch readstring pop}executeonly def end ct_MakeOCF begin /ct_cHexEncoding [/c00/c01/c02/c03/c04/c05/c06/c07/c08/c09/c0A/c0B/c0C/c0D/c0E/c0F/c10/c11/c12 /c13/c14/c15/c16/c17/c18/c19/c1A/c1B/c1C/c1D/c1E/c1F/c20/c21/c22/c23/c24/c25 /c26/c27/c28/c29/c2A/c2B/c2C/c2D/c2E/c2F/c30/c31/c32/c33/c34/c35/c36/c37/c38 /c39/c3A/c3B/c3C/c3D/c3E/c3F/c40/c41/c42/c43/c44/c45/c46/c47/c48/c49/c4A/c4B /c4C/c4D/c4E/c4F/c50/c51/c52/c53/c54/c55/c56/c57/c58/c59/c5A/c5B/c5C/c5D/c5E /c5F/c60/c61/c62/c63/c64/c65/c66/c67/c68/c69/c6A/c6B/c6C/c6D/c6E/c6F/c70/c71 /c72/c73/c74/c75/c76/c77/c78/c79/c7A/c7B/c7C/c7D/c7E/c7F/c80/c81/c82/c83/c84 /c85/c86/c87/c88/c89/c8A/c8B/c8C/c8D/c8E/c8F/c90/c91/c92/c93/c94/c95/c96/c97 /c98/c99/c9A/c9B/c9C/c9D/c9E/c9F/cA0/cA1/cA2/cA3/cA4/cA5/cA6/cA7/cA8/cA9/cAA /cAB/cAC/cAD/cAE/cAF/cB0/cB1/cB2/cB3/cB4/cB5/cB6/cB7/cB8/cB9/cBA/cBB/cBC/cBD /cBE/cBF/cC0/cC1/cC2/cC3/cC4/cC5/cC6/cC7/cC8/cC9/cCA/cCB/cCC/cCD/cCE/cCF/cD0 /cD1/cD2/cD3/cD4/cD5/cD6/cD7/cD8/cD9/cDA/cDB/cDC/cDD/cDE/cDF/cE0/cE1/cE2/cE3 /cE4/cE5/cE6/cE7/cE8/cE9/cEA/cEB/cEC/cED/cEE/cEF/cF0/cF1/cF2/cF3/cF4/cF5/cF6 /cF7/cF8/cF9/cFA/cFB/cFC/cFD/cFE/cFF]def /ct_CID_STR_SIZE 8000 def /ct_mkocfStr100 100 string def /ct_defaultFontMtx[.001 0 0 .001 0 0]def /ct_1000Mtx[1000 0 0 1000 0 0]def /ct_raise{exch cvx exch errordict exch get exec stop}bind def /ct_reraise {cvx $error/errorname get(Error: )print dup( )cvs print errordict exch get exec stop }bind def /ct_cvnsi { 1 index add 1 sub 1 exch 0 4 1 roll { 2 index exch get exch 8 bitshift add } for exch pop }bind def /ct_GetInterval { Adobe_CoolType_Utility/ct_BuildCharDict get begin /dst_index 0 def dup dst_string length gt {dup string/dst_string exch def} if 1 index ct_CID_STR_SIZE idiv /arrayIndex exch def 2 index arrayIndex get 2 index arrayIndex ct_CID_STR_SIZE mul sub { dup 3 index add 2 index length le { 2 index getinterval dst_string dst_index 2 index putinterval length dst_index add/dst_index exch def exit } { 1 index length 1 index sub dup 4 1 roll getinterval dst_string dst_index 2 index putinterval pop dup dst_index add/dst_index exch def sub /arrayIndex arrayIndex 1 add def 2 index dup length arrayIndex gt {arrayIndex get} { pop exit } ifelse 0 } ifelse } loop pop pop pop dst_string 0 dst_index getinterval end }bind def ct_Level2? { /ct_resourcestatus currentglobal mark true setglobal {/unknowninstancename/Category resourcestatus} stopped {cleartomark setglobal true} {cleartomark currentglobal not exch setglobal} ifelse { { mark 3 1 roll/Category findresource begin ct_Vars/vm currentglobal put ({ResourceStatus}stopped)0()/SubFileDecode filter cvx exec {cleartomark false} {{3 2 roll pop true}{cleartomark false}ifelse} ifelse ct_Vars/vm get setglobal end } } {{resourcestatus}} ifelse bind def /CIDFont/Category ct_resourcestatus {pop pop} { currentglobal true setglobal /Generic/Category findresource dup length dict copy dup/InstanceType/dicttype put /CIDFont exch/Category defineresource pop setglobal } ifelse ct_UseNativeCapability? { /CIDInit/ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo 3 dict dup begin /Registry(Adobe)def /Ordering(Identity)def /Supplement 0 def end def /CMapName/Identity-H def /CMapVersion 1.000 def /CMapType 1 def 1 begincodespacerange <0000> endcodespacerange 1 begincidrange <0000>0 endcidrange endcmap CMapName currentdict/CMap defineresource pop end end } if } { /ct_Category 2 dict begin /CIDFont 10 dict def /ProcSet 2 dict def currentdict end def /defineresource { ct_Category 1 index 2 copy known { get dup dup maxlength exch length eq { dup length 10 add dict copy ct_Category 2 index 2 index put } if 3 index 3 index put pop exch pop } {pop pop/defineresource/undefined ct_raise} ifelse }bind def /findresource { ct_Category 1 index 2 copy known { get 2 index 2 copy known {get 3 1 roll pop pop} {pop pop/findresource/undefinedresource ct_raise} ifelse } {pop pop/findresource/undefined ct_raise} ifelse }bind def /resourcestatus { ct_Category 1 index 2 copy known { get 2 index known exch pop exch pop { 0 -1 true } { false } ifelse } {pop pop/findresource/undefined ct_raise} ifelse }bind def /ct_resourcestatus/resourcestatus load def } ifelse /ct_CIDInit 2 dict begin /ct_cidfont_stream_init { { dup(Binary)eq { pop null currentfile ct_Level2? { {cid_BYTE_COUNT()/SubFileDecode filter} stopped {pop pop pop} if } if /readstring load exit } if dup(Hex)eq { pop currentfile ct_Level2? { {null exch/ASCIIHexDecode filter/readstring} stopped {pop exch pop(>)exch/readhexstring} if } {(>)exch/readhexstring} ifelse load exit } if /StartData/typecheck ct_raise } loop cid_BYTE_COUNT ct_CID_STR_SIZE le { 2 copy cid_BYTE_COUNT string exch exec pop 1 array dup 3 -1 roll 0 exch put } { cid_BYTE_COUNT ct_CID_STR_SIZE div ceiling cvi dup array exch 2 sub 0 exch 1 exch { 2 copy 5 index ct_CID_STR_SIZE string 6 index exec pop put pop } for 2 index cid_BYTE_COUNT ct_CID_STR_SIZE mod string 3 index exec pop 1 index exch 1 index length 1 sub exch put } ifelse cid_CIDFONT exch/GlyphData exch put 2 index null eq { pop pop pop } { pop/readstring load 1 string exch { 3 copy exec pop dup length 0 eq { pop pop pop pop pop true exit } if 4 index eq { pop pop pop pop false exit } if } loop pop } ifelse }bind def /StartData { mark { currentdict dup/FDArray get 0 get/FontMatrix get 0 get 0.001 eq { dup/CDevProc known not { /CDevProc 1183615869 internaldict/stdCDevProc 2 copy known {get} { pop pop {pop pop pop pop pop 0 -1000 7 index 2 div 880} } ifelse def } if } { /CDevProc { pop pop pop pop pop 0 1 cid_temp/cid_CIDFONT get /FDArray get 0 get /FontMatrix get 0 get div 7 index 2 div 1 index 0.88 mul }def } ifelse /cid_temp 15 dict def cid_temp begin /cid_CIDFONT exch def 3 copy pop dup/cid_BYTE_COUNT exch def 0 gt { ct_cidfont_stream_init FDArray { /Private get dup/SubrMapOffset known { begin /Subrs SubrCount array def Subrs SubrMapOffset SubrCount SDBytes ct_Level2? { currentdict dup/SubrMapOffset undef dup/SubrCount undef /SDBytes undef } if end /cid_SD_BYTES exch def /cid_SUBR_COUNT exch def /cid_SUBR_MAP_OFFSET exch def /cid_SUBRS exch def cid_SUBR_COUNT 0 gt { GlyphData cid_SUBR_MAP_OFFSET cid_SD_BYTES ct_GetInterval 0 cid_SD_BYTES ct_cvnsi 0 1 cid_SUBR_COUNT 1 sub { exch 1 index 1 add cid_SD_BYTES mul cid_SUBR_MAP_OFFSET add GlyphData exch cid_SD_BYTES ct_GetInterval 0 cid_SD_BYTES ct_cvnsi cid_SUBRS 4 2 roll GlyphData exch 4 index 1 index sub ct_GetInterval dup length string copy put } for pop } if } {pop} ifelse } forall } if cleartomark pop pop end CIDFontName currentdict/CIDFont defineresource pop end end } stopped {cleartomark/StartData ct_reraise} if }bind def currentdict end def /ct_saveCIDInit { /CIDInit/ProcSet ct_resourcestatus {true} {/CIDInitC/ProcSet ct_resourcestatus} ifelse { pop pop /CIDInit/ProcSet findresource ct_UseNativeCapability? {pop null} {/CIDInit ct_CIDInit/ProcSet defineresource pop} ifelse } {/CIDInit ct_CIDInit/ProcSet defineresource pop null} ifelse ct_Vars exch/ct_oldCIDInit exch put }bind def /ct_restoreCIDInit { ct_Vars/ct_oldCIDInit get dup null ne {/CIDInit exch/ProcSet defineresource pop} {pop} ifelse }bind def /ct_BuildCharSetUp { 1 index begin CIDFont begin Adobe_CoolType_Utility/ct_BuildCharDict get begin /ct_dfCharCode exch def /ct_dfDict exch def CIDFirstByte ct_dfCharCode add dup CIDCount ge {pop 0} if /cid exch def { GlyphDirectory cid 2 copy known {get} {pop pop nullstring} ifelse dup length FDBytes sub 0 gt { dup FDBytes 0 ne {0 FDBytes ct_cvnsi} {pop 0} ifelse /fdIndex exch def dup length FDBytes sub FDBytes exch getinterval /charstring exch def exit } { pop cid 0 eq {/charstring nullstring def exit} if /cid 0 def } ifelse } loop }def /ct_SetCacheDevice { 0 0 moveto dup stringwidth 3 -1 roll true charpath pathbbox 0 -1000 7 index 2 div 880 setcachedevice2 0 0 moveto }def /ct_CloneSetCacheProc { 1 eq { stringwidth pop -2 div -880 0 -1000 setcharwidth moveto } { usewidths? { currentfont/Widths get cid 2 copy known {get exch pop aload pop} {pop pop stringwidth} ifelse } {stringwidth} ifelse setcharwidth 0 0 moveto } ifelse }def /ct_Type3ShowCharString { ct_FDDict fdIndex 2 copy known {get} { currentglobal 3 1 roll 1 index gcheck setglobal ct_Type1FontTemplate dup maxlength dict copy begin FDArray fdIndex get dup/FontMatrix 2 copy known {get} {pop pop ct_defaultFontMtx} ifelse /FontMatrix exch dup length array copy def /Private get /Private exch def /Widths rootfont/Widths get def /CharStrings 1 dict dup/.notdef dup length string copy put def currentdict end /ct_Type1Font exch definefont dup 5 1 roll put setglobal } ifelse dup/CharStrings get 1 index/Encoding get ct_dfCharCode get charstring put rootfont/WMode 2 copy known {get} {pop pop 0} ifelse exch 1000 scalefont setfont ct_str1 0 ct_dfCharCode put ct_str1 exch ct_dfSetCacheProc ct_SyntheticBold { currentpoint ct_str1 show newpath moveto ct_str1 true charpath ct_StrokeWidth setlinewidth stroke } {ct_str1 show} ifelse }def /ct_Type4ShowCharString { ct_dfDict ct_dfCharCode charstring FDArray fdIndex get dup/FontMatrix get dup ct_defaultFontMtx ct_matrixeq not {ct_1000Mtx matrix concatmatrix concat} {pop} ifelse /Private get Adobe_CoolType_Utility/ct_Level2? get not { ct_dfDict/Private 3 -1 roll {put} 1183615869 internaldict/superexec get exec } if 1183615869 internaldict Adobe_CoolType_Utility/ct_Level2? get {1 index} {3 index/Private get mark 6 1 roll} ifelse dup/RunInt known {/RunInt get} {pop/CCRun} ifelse get exec Adobe_CoolType_Utility/ct_Level2? get not {cleartomark} if }bind def /ct_BuildCharIncremental { { Adobe_CoolType_Utility/ct_MakeOCF get begin ct_BuildCharSetUp ct_ShowCharString } stopped {stop} if end end end end }bind def /BaseFontNameStr(BF00)def /ct_Type1FontTemplate 14 dict begin /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0]def /FontBBox [-250 -250 1250 1250]def /Encoding ct_cHexEncoding def /PaintType 0 def currentdict end def /BaseFontTemplate 11 dict begin /FontMatrix [0.001 0 0 0.001 0 0]def /FontBBox [-250 -250 1250 1250]def /Encoding ct_cHexEncoding def /BuildChar/ct_BuildCharIncremental load def ct_Clone? { /FontType 3 def /ct_ShowCharString/ct_Type3ShowCharString load def /ct_dfSetCacheProc/ct_CloneSetCacheProc load def /ct_SyntheticBold false def /ct_StrokeWidth 1 def } { /FontType 4 def /Private 1 dict dup/lenIV 4 put def /CharStrings 1 dict dup/.notdefput def /PaintType 0 def /ct_ShowCharString/ct_Type4ShowCharString load def } ifelse /ct_str1 1 string def currentdict end def /BaseFontDictSize BaseFontTemplate length 5 add def /ct_matrixeq { true 0 1 5 { dup 4 index exch get exch 3 index exch get eq and dup not {exit} if } for exch pop exch pop }bind def /ct_makeocf { 15 dict begin exch/WMode exch def exch/FontName exch def /FontType 0 def /FMapType 2 def dup/FontMatrix known {dup/FontMatrix get/FontMatrix exch def} {/FontMatrix matrix def} ifelse /bfCount 1 index/CIDCount get 256 idiv 1 add dup 256 gt{pop 256}if def /Encoding 256 array 0 1 bfCount 1 sub{2 copy dup put pop}for bfCount 1 255{2 copy bfCount put pop}for def /FDepVector bfCount dup 256 lt{1 add}if array def BaseFontTemplate BaseFontDictSize dict copy begin /CIDFont exch def CIDFont/FontBBox known {CIDFont/FontBBox get/FontBBox exch def} if CIDFont/CDevProc known {CIDFont/CDevProc get/CDevProc exch def} if currentdict end BaseFontNameStr 3(0)putinterval 0 1 bfCount dup 256 eq{1 sub}if { FDepVector exch 2 index BaseFontDictSize dict copy begin dup/CIDFirstByte exch 256 mul def FontType 3 eq {/ct_FDDict 2 dict def} if currentdict end 1 index 16 BaseFontNameStr 2 2 getinterval cvrs pop BaseFontNameStr exch definefont put } for ct_Clone? {/Widths 1 index/CIDFont get/GlyphDirectory get length dict def} if FontName currentdict end definefont ct_Clone? { gsave dup 1000 scalefont setfont ct_BuildCharDict begin /usewidths? false def currentfont/Widths get begin exch/CIDFont get/GlyphDirectory get { pop dup charcode exch 1 index 0 2 index 256 idiv put 1 index exch 1 exch 256 mod put stringwidth 2 array astore def } forall end /usewidths? true def end grestore } {exch pop} ifelse }bind def currentglobal true setglobal /ct_ComposeFont { ct_UseNativeCapability? { 2 index/CMap ct_resourcestatus {pop pop exch pop} { /CIDInit/ProcSet findresource begin 12 dict begin begincmap /CMapName 3 index def /CMapVersion 1.000 def /CMapType 1 def exch/WMode exch def /CIDSystemInfo 3 dict dup begin /Registry(Adobe)def /Ordering CMapName ct_mkocfStr100 cvs (Adobe-)search { pop pop (-)search { dup length string copy exch pop exch pop } {pop(Identity)} ifelse } {pop (Identity)} ifelse def /Supplement 0 def end def 1 begincodespacerange <0000> endcodespacerange 1 begincidrange <0000>0 endcidrange endcmap CMapName currentdict/CMap defineresource pop end end } ifelse composefont } { 3 2 roll pop 0 get/CIDFont findresource ct_makeocf } ifelse }bind def setglobal /ct_MakeIdentity { ct_UseNativeCapability? { 1 index/CMap ct_resourcestatus {pop pop} { /CIDInit/ProcSet findresource begin 12 dict begin begincmap /CMapName 2 index def /CMapVersion 1.000 def /CMapType 1 def /CIDSystemInfo 3 dict dup begin /Registry(Adobe)def /Ordering CMapName ct_mkocfStr100 cvs (Adobe-)search { pop pop (-)search {dup length string copy exch pop exch pop} {pop(Identity)} ifelse } {pop(Identity)} ifelse def /Supplement 0 def end def 1 begincodespacerange <0000> endcodespacerange 1 begincidrange <0000>0 endcidrange endcmap CMapName currentdict/CMap defineresource pop end end } ifelse composefont } { exch pop 0 get/CIDFont findresource ct_makeocf } ifelse }bind def currentdict readonly pop end end %%EndResource setglobal %%BeginResource: procset Adobe_CoolType_Utility_T42 1.0 0 %%Copyright: Copyright 1987-2004 Adobe Systems Incorporated. %%Version: 1.0 0 userdict/ct_T42Dict 15 dict put ct_T42Dict begin /Is2015? { version cvi 2015 ge }bind def /AllocGlyphStorage { Is2015? { pop } { {string}forall }ifelse }bind def /Type42DictBegin { 25 dict begin /FontName exch def /CharStrings 256 dict begin /.notdef 0 def currentdict end def /Encoding exch def /PaintType 0 def /FontType 42 def /FontMatrix[1 0 0 1 0 0]def 4 array astore cvx/FontBBox exch def /sfnts }bind def /Type42DictEnd { currentdict dup/FontName get exch definefont end ct_T42Dict exch dup/FontName get exch put }bind def /RD{string currentfile exch readstring pop}executeonly def /PrepFor2015 { Is2015? { /GlyphDirectory 16 dict def sfnts 0 get dup 2 index (glyx) putinterval 2 index (locx) putinterval pop pop } { pop pop }ifelse }bind def /AddT42Char { Is2015? { /GlyphDirectory get begin def end pop pop } { /sfnts get 4 index get 3 index 2 index putinterval pop pop pop pop }ifelse }bind def /T0AddT42Mtx2 { /CIDFont findresource/Metrics2 get begin def end }bind def end %%EndResource currentglobal true setglobal %%BeginFile: MMFauxFont.prc %%Copyright: Copyright 1987-2001 Adobe Systems Incorporated. %%All Rights Reserved. userdict /ct_EuroDict 10 dict put ct_EuroDict begin /ct_CopyFont { { 1 index /FID ne {def} {pop pop} ifelse} forall } def /ct_GetGlyphOutline { gsave initmatrix newpath exch findfont dup length 1 add dict begin ct_CopyFont /Encoding Encoding dup length array copy dup 4 -1 roll 0 exch put def currentdict end /ct_EuroFont exch definefont 1000 scalefont setfont 0 0 moveto [ <00> stringwidth <00> false charpath pathbbox [ {/m cvx} {/l cvx} {/c cvx} {/cp cvx} pathforall grestore counttomark 8 add } def /ct_MakeGlyphProc { ] cvx /ct_PSBuildGlyph cvx ] cvx } def /ct_PSBuildGlyph { gsave 8 -1 roll pop 7 1 roll 6 -2 roll ct_FontMatrix transform 6 2 roll 4 -2 roll ct_FontMatrix transform 4 2 roll ct_FontMatrix transform currentdict /PaintType 2 copy known {get 2 eq}{pop pop false} ifelse dup 9 1 roll { currentdict /StrokeWidth 2 copy known { get 2 div 0 ct_FontMatrix dtransform pop 5 1 roll 4 -1 roll 4 index sub 4 1 roll 3 -1 roll 4 index sub 3 1 roll exch 4 index add exch 4 index add 5 -1 roll pop } { pop pop } ifelse } if setcachedevice ct_FontMatrix concat ct_PSPathOps begin exec end { currentdict /StrokeWidth 2 copy known { get } { pop pop 0 } ifelse setlinewidth stroke } { fill } ifelse grestore } def /ct_PSPathOps 4 dict dup begin /m {moveto} def /l {lineto} def /c {curveto} def /cp {closepath} def end def /ct_matrix1000 [1000 0 0 1000 0 0] def /ct_AddGlyphProc { 2 index findfont dup length 4 add dict begin ct_CopyFont /CharStrings CharStrings dup length 1 add dict copy begin 3 1 roll def currentdict end def /ct_FontMatrix ct_matrix1000 FontMatrix matrix concatmatrix def /ct_PSBuildGlyph /ct_PSBuildGlyph load def /ct_PSPathOps /ct_PSPathOps load def currentdict end definefont pop } def systemdict /languagelevel known { /ct_AddGlyphToPrinterFont { 2 copy ct_GetGlyphOutline 3 add -1 roll restore ct_MakeGlyphProc ct_AddGlyphProc } def } { /ct_AddGlyphToPrinterFont { pop pop restore Adobe_CTFauxDict /$$$FONTNAME get /Euro Adobe_CTFauxDict /$$$SUBSTITUTEBASE get ct_EuroDict exch get ct_AddGlyphProc } def } ifelse /AdobeSansMM { 556 0 24 -19 541 703 { 541 628 m 510 669 442 703 354 703 c 201 703 117 607 101 444 c 50 444 l 25 372 l 97 372 l 97 301 l 49 301 l 24 229 l 103 229 l 124 67 209 -19 350 -19 c 435 -19 501 25 509 32 c 509 131 l 492 105 417 60 343 60 c 267 60 204 127 197 229 c 406 229 l 430 301 l 191 301 l 191 372 l 455 372 l 479 444 l 194 444 l 201 531 245 624 348 624 c 433 624 484 583 509 534 c cp 556 0 m } ct_PSBuildGlyph } def /AdobeSerifMM { 500 0 10 -12 484 692 { 347 298 m 171 298 l 170 310 170 322 170 335 c 170 362 l 362 362 l 374 403 l 172 403 l 184 580 244 642 308 642 c 380 642 434 574 457 457 c 481 462 l 474 691 l 449 691 l 433 670 429 657 410 657 c 394 657 360 692 299 692 c 204 692 94 604 73 403 c 22 403 l 10 362 l 70 362 l 69 352 69 341 69 330 c 69 319 69 308 70 298 c 22 298 l 10 257 l 73 257 l 97 57 216 -12 295 -12 c 364 -12 427 25 484 123 c 458 142 l 425 101 384 37 316 37 c 256 37 189 84 173 257 c 335 257 l cp 500 0 m } ct_PSBuildGlyph } def end %%EndFile setglobal Adobe_CoolType_Core begin /$Oblique SetSubstituteStrategy end %%BeginResource: procset Adobe_AGM_Image 1.0 0 %%Version: 1.0 0 %%Copyright: Copyright(C)2000-2006 Adobe Systems, Inc. All Rights Reserved. systemdict/setpacking known { currentpacking true setpacking }if userdict/Adobe_AGM_Image 71 dict dup begin put /Adobe_AGM_Image_Id/Adobe_AGM_Image_1.0_0 def /nd{ null def }bind def /AGMIMG_&image nd /AGMIMG_&colorimage nd /AGMIMG_&imagemask nd /AGMIMG_mbuf()def /AGMIMG_ybuf()def /AGMIMG_kbuf()def /AGMIMG_c 0 def /AGMIMG_m 0 def /AGMIMG_y 0 def /AGMIMG_k 0 def /AGMIMG_tmp nd /AGMIMG_imagestring0 nd /AGMIMG_imagestring1 nd /AGMIMG_imagestring2 nd /AGMIMG_imagestring3 nd /AGMIMG_imagestring4 nd /AGMIMG_imagestring5 nd /AGMIMG_cnt nd /AGMIMG_fsave nd /AGMIMG_colorAry nd /AGMIMG_override nd /AGMIMG_name nd /AGMIMG_maskSource nd /AGMIMG_flushfilters nd /invert_image_samples nd /knockout_image_samples nd /img nd /sepimg nd /devnimg nd /idximg nd /ds { Adobe_AGM_Core begin Adobe_AGM_Image begin /AGMIMG_&image systemdict/image get def /AGMIMG_&imagemask systemdict/imagemask get def /colorimage where{ pop /AGMIMG_&colorimage/colorimage ldf }if end end }def /ps { Adobe_AGM_Image begin /AGMIMG_ccimage_exists{/customcolorimage where { pop /Adobe_AGM_OnHost_Seps where { pop false }{ /Adobe_AGM_InRip_Seps where { pop false }{ true }ifelse }ifelse }{ false }ifelse }bdf level2{ /invert_image_samples { Adobe_AGM_Image/AGMIMG_tmp Decode length ddf /Decode[Decode 1 get Decode 0 get]def }def /knockout_image_samples { Operator/imagemask ne{ /Decode[1 1]def }if }def }{ /invert_image_samples { {1 exch sub}currenttransfer addprocs settransfer }def /knockout_image_samples { {pop 1}currenttransfer addprocs settransfer }def }ifelse /img/imageormask ldf /sepimg/sep_imageormask ldf /devnimg/devn_imageormask ldf /idximg/indexed_imageormask ldf /_ctype 7 def currentdict{ dup xcheck 1 index type dup/arraytype eq exch/packedarraytype eq or and{ bind }if def }forall }def /pt { end }def /dt { }def /AGMIMG_flushfilters { dup type/arraytype ne {1 array astore}if dup 0 get currentfile ne {dup 0 get flushfile}if { dup type/filetype eq { dup status 1 index currentfile ne and {closefile} {pop} ifelse }{pop}ifelse }forall }def /AGMIMG_init_common { currentdict/T known{/ImageType/T ldf currentdict/T undef}if currentdict/W known{/Width/W ldf currentdict/W undef}if currentdict/H known{/Height/H ldf currentdict/H undef}if currentdict/M known{/ImageMatrix/M ldf currentdict/M undef}if currentdict/BC known{/BitsPerComponent/BC ldf currentdict/BC undef}if currentdict/D known{/Decode/D ldf currentdict/D undef}if currentdict/DS known{/DataSource/DS ldf currentdict/DS undef}if currentdict/O known{ /Operator/O load 1 eq{ /imagemask }{ /O load 2 eq{ /image }{ /colorimage }ifelse }ifelse def currentdict/O undef }if currentdict/HSCI known{/HostSepColorImage/HSCI ldf currentdict/HSCI undef}if currentdict/MD known{/MultipleDataSources/MD ldf currentdict/MD undef}if currentdict/I known{/Interpolate/I ldf currentdict/I undef}if currentdict/SI known{/SkipImageProc/SI ldf currentdict/SI undef}if /DataSource load xcheck not{ DataSource type/arraytype eq{ DataSource 0 get type/filetype eq{ /_Filters DataSource def currentdict/MultipleDataSources known not{ /DataSource DataSource dup length 1 sub get def }if }if }if currentdict/MultipleDataSources known not{ /MultipleDataSources DataSource type/arraytype eq{ DataSource length 1 gt } {false}ifelse def }if }if /NComponents Decode length 2 div def currentdict/SkipImageProc known not{/SkipImageProc{false}def}if }bdf /imageormask_sys { begin AGMIMG_init_common save mark level2{ currentdict Operator/imagemask eq{ AGMIMG_&imagemask }{ use_mask{ process_mask AGMIMG_&image }{ AGMIMG_&image }ifelse }ifelse }{ Width Height Operator/imagemask eq{ Decode 0 get 1 eq Decode 1 get 0 eq and ImageMatrix/DataSource load AGMIMG_&imagemask }{ BitsPerComponent ImageMatrix/DataSource load AGMIMG_&image }ifelse }ifelse currentdict/_Filters known{_Filters AGMIMG_flushfilters}if cleartomark restore end }def /overprint_plate { currentoverprint{ 0 get dup type/nametype eq{ dup/DeviceGray eq{ pop AGMCORE_black_plate not }{ /DeviceCMYK eq{ AGMCORE_is_cmyk_sep not }if }ifelse }{ false exch { AGMOHS_sepink eq or }forall not }ifelse }{ pop false }ifelse }def /process_mask { level3{ dup begin /ImageType 1 def end 4 dict begin /DataDict exch def /ImageType 3 def /InterleaveType 3 def /MaskDict 9 dict begin /ImageType 1 def /Width DataDict dup/MaskWidth known{/MaskWidth}{/Width}ifelse get def /Height DataDict dup/MaskHeight known{/MaskHeight}{/Height}ifelse get def /ImageMatrix[Width 0 0 Height neg 0 Height]def /NComponents 1 def /BitsPerComponent 1 def /Decode DataDict dup/MaskD known{/MaskD}{[1 0]}ifelse get def /DataSource Adobe_AGM_Core/AGMIMG_maskSource get def currentdict end def currentdict end }if }def /use_mask { dup/Mask known {dup/Mask get}{false}ifelse }def /imageormask { begin AGMIMG_init_common SkipImageProc{ currentdict consumeimagedata } { save mark level2 AGMCORE_host_sep not and{ currentdict Operator/imagemask eq DeviceN_PS2 not and{ imagemask }{ AGMCORE_in_rip_sep currentoverprint and currentcolorspace 0 get/DeviceGray eq and{ [/Separation/Black/DeviceGray{}]setcolorspace /Decode[Decode 1 get Decode 0 get]def }if use_mask{ process_mask image }{ DeviceN_NoneName DeviceN_PS2 Indexed_DeviceN level3 not and or or AGMCORE_in_rip_sep and { Names convert_to_process not{ 2 dict begin /imageDict xdf /names_index 0 def gsave imageDict write_image_file{ Names{ dup(None)ne{ [/Separation 3 -1 roll/DeviceGray{1 exch sub}]setcolorspace Operator imageDict read_image_file names_index 0 eq{true setoverprint}if /names_index names_index 1 add def }{ pop }ifelse }forall close_image_file }if grestore end }{ Operator/imagemask eq{ imagemask }{ image }ifelse }ifelse }{ Operator/imagemask eq{ imagemask }{ image }ifelse }ifelse }ifelse }ifelse }{ Width Height Operator/imagemask eq{ Decode 0 get 1 eq Decode 1 get 0 eq and ImageMatrix/DataSource load /Adobe_AGM_OnHost_Seps where{ pop imagemask }{ currentgray 1 ne{ currentdict imageormask_sys }{ currentoverprint not{ 1 AGMCORE_&setgray currentdict imageormask_sys }{ currentdict ignoreimagedata }ifelse }ifelse }ifelse }{ BitsPerComponent ImageMatrix MultipleDataSources{ 0 1 NComponents 1 sub{ DataSource exch get }for }{ /DataSource load }ifelse Operator/colorimage eq{ AGMCORE_host_sep{ MultipleDataSources level2 or NComponents 4 eq and{ AGMCORE_is_cmyk_sep{ MultipleDataSources{ /DataSource DataSource 0 get xcheck { [ DataSource 0 get/exec cvx DataSource 1 get/exec cvx DataSource 2 get/exec cvx DataSource 3 get/exec cvx /AGMCORE_get_ink_data cvx ]cvx }{ DataSource aload pop AGMCORE_get_ink_data }ifelse def }{ /DataSource Width BitsPerComponent mul 7 add 8 idiv Height mul 4 mul /DataSource load filter_cmyk 0()/SubFileDecode filter def }ifelse /Decode[Decode 0 get Decode 1 get]def /MultipleDataSources false def /NComponents 1 def /Operator/image def invert_image_samples 1 AGMCORE_&setgray currentdict imageormask_sys }{ currentoverprint not Operator/imagemask eq and{ 1 AGMCORE_&setgray currentdict imageormask_sys }{ currentdict ignoreimagedata }ifelse }ifelse }{ MultipleDataSources NComponents AGMIMG_&colorimage }ifelse }{ true NComponents colorimage }ifelse }{ Operator/image eq{ AGMCORE_host_sep{ /DoImage true def currentdict/HostSepColorImage known{HostSepColorImage not}{false}ifelse { AGMCORE_black_plate not Operator/imagemask ne and{ /DoImage false def currentdict ignoreimagedata }if }if 1 AGMCORE_&setgray DoImage {currentdict imageormask_sys}if }{ use_mask{ process_mask image }{ image }ifelse }ifelse }{ Operator/knockout eq{ pop pop pop pop pop currentcolorspace overprint_plate not{ knockout_unitsq }if }if }ifelse }ifelse }ifelse }ifelse cleartomark restore }ifelse currentdict/_Filters known{_Filters AGMIMG_flushfilters}if end }def /sep_imageormask { /sep_colorspace_dict AGMCORE_gget begin CSA map_csa begin AGMIMG_init_common SkipImageProc{ currentdict consumeimagedata }{ save mark AGMCORE_avoid_L2_sep_space{ /Decode[Decode 0 get 255 mul Decode 1 get 255 mul]def }if AGMIMG_ccimage_exists MappedCSA 0 get/DeviceCMYK eq and currentdict/Components known and Name()ne and Name(All)ne and Operator/image eq and AGMCORE_producing_seps not and level2 not and { Width Height BitsPerComponent ImageMatrix [ /DataSource load/exec cvx { 0 1 2 index length 1 sub{ 1 index exch 2 copy get 255 xor put }for }/exec cvx ]cvx bind MappedCSA 0 get/DeviceCMYK eq{ Components aload pop }{ 0 0 0 Components aload pop 1 exch sub }ifelse Name findcmykcustomcolor customcolorimage }{ AGMCORE_producing_seps not{ level2{ //Adobe_AGM_Core/AGMCORE_pattern_paint_type get 2 ne AGMCORE_avoid_L2_sep_space not and currentcolorspace 0 get/Separation ne and{ [/Separation Name MappedCSA sep_proc_name exch dup 0 get 15 string cvs(/Device)anchorsearch{pop pop 0 get}{pop}ifelse exch load]setcolorspace_opt /sep_tint AGMCORE_gget setcolor }if currentdict imageormask }{ currentdict Operator/imagemask eq{ imageormask }{ sep_imageormask_lev1 }ifelse }ifelse }{ AGMCORE_host_sep{ Operator/knockout eq{ currentdict/ImageMatrix get concat knockout_unitsq }{ currentgray 1 ne{ AGMCORE_is_cmyk_sep Name(All)ne and{ level2{ Name AGMCORE_IsSeparationAProcessColor { Operator/imagemask eq{ //Adobe_AGM_Core/AGMCORE_pattern_paint_type get 2 ne{ /sep_tint AGMCORE_gget 1 exch sub AGMCORE_&setcolor }if }{ invert_image_samples }ifelse }{ //Adobe_AGM_Core/AGMCORE_pattern_paint_type get 2 ne{ [/Separation Name[/DeviceGray] { sep_colorspace_proc AGMCORE_get_ink_data 1 exch sub }bind ]AGMCORE_&setcolorspace /sep_tint AGMCORE_gget AGMCORE_&setcolor }if }ifelse currentdict imageormask_sys }{ currentdict Operator/imagemask eq{ imageormask_sys }{ sep_image_lev1_sep }ifelse }ifelse }{ Operator/imagemask ne{ invert_image_samples }if currentdict imageormask_sys }ifelse }{ currentoverprint not Name(All)eq or Operator/imagemask eq and{ currentdict imageormask_sys }{ currentoverprint not { gsave knockout_unitsq grestore }if currentdict consumeimagedata }ifelse }ifelse }ifelse }{ //Adobe_AGM_Core/AGMCORE_pattern_paint_type get 2 ne{ currentcolorspace 0 get/Separation ne{ [/Separation Name MappedCSA sep_proc_name exch 0 get exch load]setcolorspace_opt /sep_tint AGMCORE_gget setcolor }if }if currentoverprint MappedCSA 0 get/DeviceCMYK eq and Name AGMCORE_IsSeparationAProcessColor not and //Adobe_AGM_Core/AGMCORE_pattern_paint_type get 2 ne{Name inRip_spot_has_ink not and}{false}ifelse Name(All)ne and{ imageormask_l2_overprint }{ currentdict imageormask }ifelse }ifelse }ifelse }ifelse cleartomark restore }ifelse currentdict/_Filters known{_Filters AGMIMG_flushfilters}if end end }def /colorSpaceElemCnt { mark currentcolor counttomark dup 2 add 1 roll cleartomark }bdf /devn_sep_datasource { 1 dict begin /dataSource xdf [ 0 1 dataSource length 1 sub{ dup currentdict/dataSource get/exch cvx/get cvx/exec cvx /exch cvx names_index/ne cvx[/pop cvx]cvx/if cvx }for ]cvx bind end }bdf /devn_alt_datasource { 11 dict begin /convProc xdf /origcolorSpaceElemCnt xdf /origMultipleDataSources xdf /origBitsPerComponent xdf /origDecode xdf /origDataSource xdf /dsCnt origMultipleDataSources{origDataSource length}{1}ifelse def /DataSource origMultipleDataSources { [ BitsPerComponent 8 idiv origDecode length 2 idiv mul string 0 1 origDecode length 2 idiv 1 sub { dup 7 mul 1 add index exch dup BitsPerComponent 8 idiv mul exch origDataSource exch get 0()/SubFileDecode filter BitsPerComponent 8 idiv string/readstring cvx/pop cvx/putinterval cvx }for ]bind cvx }{origDataSource}ifelse 0()/SubFileDecode filter def [ origcolorSpaceElemCnt string 0 2 origDecode length 2 sub { dup origDecode exch get dup 3 -1 roll 1 add origDecode exch get exch sub 2 BitsPerComponent exp 1 sub div 1 BitsPerComponent 8 idiv{DataSource/read cvx/not cvx{0}/if cvx/mul cvx}repeat/mul cvx/add cvx }for /convProc load/exec cvx origcolorSpaceElemCnt 1 sub -1 0 { /dup cvx 2/add cvx/index cvx 3 1/roll cvx/exch cvx 255/mul cvx/cvi cvx/put cvx }for ]bind cvx 0()/SubFileDecode filter end }bdf /devn_imageormask { /devicen_colorspace_dict AGMCORE_gget begin CSA map_csa 2 dict begin dup /srcDataStrs[3 -1 roll begin AGMIMG_init_common currentdict/MultipleDataSources known{MultipleDataSources{DataSource length}{1}ifelse}{1}ifelse { Width Decode length 2 div mul cvi { dup 65535 gt{1 add 2 div cvi}{exit}ifelse }loop string }repeat end]def /dstDataStr srcDataStrs 0 get length string def begin AGMIMG_init_common SkipImageProc{ currentdict consumeimagedata }{ save mark AGMCORE_producing_seps not{ level3 not{ Operator/imagemask ne{ /DataSource[[ DataSource Decode BitsPerComponent currentdict/MultipleDataSources known{MultipleDataSources}{false}ifelse colorSpaceElemCnt/devicen_colorspace_dict AGMCORE_gget/TintTransform get devn_alt_datasource 1/string cvx/readstring cvx/pop cvx]cvx colorSpaceElemCnt 1 sub{dup}repeat]def /MultipleDataSources true def /Decode colorSpaceElemCnt[exch{0 1}repeat]def }if }if currentdict imageormask }{ AGMCORE_host_sep{ Names convert_to_process{ CSA get_csa_by_name 0 get/DeviceCMYK eq{ /DataSource Width BitsPerComponent mul 7 add 8 idiv Height mul 4 mul DataSource Decode BitsPerComponent currentdict/MultipleDataSources known{MultipleDataSources}{false}ifelse 4/devicen_colorspace_dict AGMCORE_gget/TintTransform get devn_alt_datasource filter_cmyk 0()/SubFileDecode filter def /MultipleDataSources false def /Decode[1 0]def /DeviceGray setcolorspace currentdict imageormask_sys }{ AGMCORE_report_unsupported_color_space AGMCORE_black_plate{ /DataSource DataSource Decode BitsPerComponent currentdict/MultipleDataSources known{MultipleDataSources}{false}ifelse CSA get_csa_by_name 0 get/DeviceRGB eq{3}{1}ifelse/devicen_colorspace_dict AGMCORE_gget/TintTransform get devn_alt_datasource /MultipleDataSources false def /Decode colorSpaceElemCnt[exch{0 1}repeat]def currentdict imageormask_sys }{ gsave knockout_unitsq grestore currentdict consumeimagedata }ifelse }ifelse } { /devicen_colorspace_dict AGMCORE_gget/names_index known{ Operator/imagemask ne{ MultipleDataSources{ /DataSource[DataSource devn_sep_datasource/exec cvx]cvx def /MultipleDataSources false def }{ /DataSource/DataSource load dstDataStr srcDataStrs 0 get filter_devn def }ifelse invert_image_samples }if currentdict imageormask_sys }{ currentoverprint not Operator/imagemask eq and{ currentdict imageormask_sys }{ currentoverprint not { gsave knockout_unitsq grestore }if currentdict consumeimagedata }ifelse }ifelse }ifelse }{ currentdict imageormask }ifelse }ifelse cleartomark restore }ifelse currentdict/_Filters known{_Filters AGMIMG_flushfilters}if end end end }def /imageormask_l2_overprint { currentdict currentcmykcolor add add add 0 eq{ currentdict consumeimagedata }{ level3{ currentcmykcolor /AGMIMG_k xdf /AGMIMG_y xdf /AGMIMG_m xdf /AGMIMG_c xdf Operator/imagemask eq{ [/DeviceN[ AGMIMG_c 0 ne{/Cyan}if AGMIMG_m 0 ne{/Magenta}if AGMIMG_y 0 ne{/Yellow}if AGMIMG_k 0 ne{/Black}if ]/DeviceCMYK{}]setcolorspace AGMIMG_c 0 ne{AGMIMG_c}if AGMIMG_m 0 ne{AGMIMG_m}if AGMIMG_y 0 ne{AGMIMG_y}if AGMIMG_k 0 ne{AGMIMG_k}if setcolor }{ /Decode[Decode 0 get 255 mul Decode 1 get 255 mul]def [/Indexed [ /DeviceN[ AGMIMG_c 0 ne{/Cyan}if AGMIMG_m 0 ne{/Magenta}if AGMIMG_y 0 ne{/Yellow}if AGMIMG_k 0 ne{/Black}if ] /DeviceCMYK{ AGMIMG_k 0 eq{0}if AGMIMG_y 0 eq{0 exch}if AGMIMG_m 0 eq{0 3 1 roll}if AGMIMG_c 0 eq{0 4 1 roll}if } ] 255 { 255 div mark exch dup dup dup AGMIMG_k 0 ne{ /sep_tint AGMCORE_gget mul MappedCSA sep_proc_name exch pop load exec 4 1 roll pop pop pop counttomark 1 roll }{ pop }ifelse AGMIMG_y 0 ne{ /sep_tint AGMCORE_gget mul MappedCSA sep_proc_name exch pop load exec 4 2 roll pop pop pop counttomark 1 roll }{ pop }ifelse AGMIMG_m 0 ne{ /sep_tint AGMCORE_gget mul MappedCSA sep_proc_name exch pop load exec 4 3 roll pop pop pop counttomark 1 roll }{ pop }ifelse AGMIMG_c 0 ne{ /sep_tint AGMCORE_gget mul MappedCSA sep_proc_name exch pop load exec pop pop pop counttomark 1 roll }{ pop }ifelse counttomark 1 add -1 roll pop } ]setcolorspace }ifelse imageormask_sys }{ write_image_file{ currentcmykcolor 0 ne{ [/Separation/Black/DeviceGray{}]setcolorspace gsave /Black [{1 exch sub/sep_tint AGMCORE_gget mul}/exec cvx MappedCSA sep_proc_name cvx exch pop{4 1 roll pop pop pop 1 exch sub}/exec cvx] cvx modify_halftone_xfer Operator currentdict read_image_file grestore }if 0 ne{ [/Separation/Yellow/DeviceGray{}]setcolorspace gsave /Yellow [{1 exch sub/sep_tint AGMCORE_gget mul}/exec cvx MappedCSA sep_proc_name cvx exch pop{4 2 roll pop pop pop 1 exch sub}/exec cvx] cvx modify_halftone_xfer Operator currentdict read_image_file grestore }if 0 ne{ [/Separation/Magenta/DeviceGray{}]setcolorspace gsave /Magenta [{1 exch sub/sep_tint AGMCORE_gget mul}/exec cvx MappedCSA sep_proc_name cvx exch pop{4 3 roll pop pop pop 1 exch sub}/exec cvx] cvx modify_halftone_xfer Operator currentdict read_image_file grestore }if 0 ne{ [/Separation/Cyan/DeviceGray{}]setcolorspace gsave /Cyan [{1 exch sub/sep_tint AGMCORE_gget mul}/exec cvx MappedCSA sep_proc_name cvx exch pop{pop pop pop 1 exch sub}/exec cvx] cvx modify_halftone_xfer Operator currentdict read_image_file grestore }if close_image_file }{ imageormask }ifelse }ifelse }ifelse }def /indexed_imageormask { begin AGMIMG_init_common save mark currentdict AGMCORE_host_sep{ Operator/knockout eq{ /indexed_colorspace_dict AGMCORE_gget dup/CSA known{ /CSA get get_csa_by_name }{ /Names get }ifelse overprint_plate not{ knockout_unitsq }if }{ Indexed_DeviceN{ /devicen_colorspace_dict AGMCORE_gget dup/names_index known exch/Names get convert_to_process or{ indexed_image_lev2_sep }{ currentoverprint not{ knockout_unitsq }if currentdict consumeimagedata }ifelse }{ AGMCORE_is_cmyk_sep{ Operator/imagemask eq{ imageormask_sys }{ level2{ indexed_image_lev2_sep }{ indexed_image_lev1_sep }ifelse }ifelse }{ currentoverprint not{ knockout_unitsq }if currentdict consumeimagedata }ifelse }ifelse }ifelse }{ level2{ Indexed_DeviceN{ /indexed_colorspace_dict AGMCORE_gget begin }{ /indexed_colorspace_dict AGMCORE_gget dup null ne { begin currentdict/CSDBase known{CSDBase/CSD get_res/MappedCSA get}{CSA}ifelse get_csa_by_name 0 get/DeviceCMYK eq ps_level 3 ge and ps_version 3015.007 lt and AGMCORE_in_rip_sep and{ [/Indexed[/DeviceN[/Cyan/Magenta/Yellow/Black]/DeviceCMYK{}]HiVal Lookup] setcolorspace }if end } {pop}ifelse }ifelse imageormask Indexed_DeviceN{ end }if }{ Operator/imagemask eq{ imageormask }{ indexed_imageormask_lev1 }ifelse }ifelse }ifelse cleartomark restore currentdict/_Filters known{_Filters AGMIMG_flushfilters}if end }def /indexed_image_lev2_sep { /indexed_colorspace_dict AGMCORE_gget begin begin Indexed_DeviceN not{ currentcolorspace dup 1/DeviceGray put dup 3 currentcolorspace 2 get 1 add string 0 1 2 3 AGMCORE_get_ink_data 4 currentcolorspace 3 get length 1 sub { dup 4 idiv exch currentcolorspace 3 get exch get 255 exch sub 2 index 3 1 roll put }for put setcolorspace }if currentdict Operator/imagemask eq{ AGMIMG_&imagemask }{ use_mask{ process_mask AGMIMG_&image }{ AGMIMG_&image }ifelse }ifelse end end }def /OPIimage { dup type/dicttype ne{ 10 dict begin /DataSource xdf /ImageMatrix xdf /BitsPerComponent xdf /Height xdf /Width xdf /ImageType 1 def /Decode[0 1 def] currentdict end }if dup begin /NComponents 1 cdndf /MultipleDataSources false cdndf /SkipImageProc{false}cdndf /Decode[ 0 currentcolorspace 0 get/Indexed eq{ 2 BitsPerComponent exp 1 sub }{ 1 }ifelse ]cdndf /Operator/image cdndf end /sep_colorspace_dict AGMCORE_gget null eq{ imageormask }{ gsave dup begin invert_image_samples end sep_imageormask grestore }ifelse }def /cachemask_level2 { 3 dict begin /LZWEncode filter/WriteFilter xdf /readBuffer 256 string def /ReadFilter currentfile 0(%EndMask)/SubFileDecode filter /ASCII85Decode filter /RunLengthDecode filter def { ReadFilter readBuffer readstring exch WriteFilter exch writestring not{exit}if }loop WriteFilter closefile end }def /spot_alias { /mapto_sep_imageormask { dup type/dicttype ne{ 12 dict begin /ImageType 1 def /DataSource xdf /ImageMatrix xdf /BitsPerComponent xdf /Height xdf /Width xdf /MultipleDataSources false def }{ begin }ifelse /Decode[/customcolor_tint AGMCORE_gget 0]def /Operator/image def /SkipImageProc{false}def currentdict end sep_imageormask }bdf /customcolorimage { Adobe_AGM_Image/AGMIMG_colorAry xddf /customcolor_tint AGMCORE_gget << /Name AGMIMG_colorAry 4 get /CSA[/DeviceCMYK] /TintMethod/Subtractive /TintProc null /MappedCSA null /NComponents 4 /Components[AGMIMG_colorAry aload pop pop] >> setsepcolorspace mapto_sep_imageormask }ndf Adobe_AGM_Image/AGMIMG_&customcolorimage/customcolorimage load put /customcolorimage { Adobe_AGM_Image/AGMIMG_override false put current_spot_alias{dup 4 get map_alias}{false}ifelse { false set_spot_alias /customcolor_tint AGMCORE_gget exch setsepcolorspace pop mapto_sep_imageormask true set_spot_alias }{ //Adobe_AGM_Image/AGMIMG_&customcolorimage get exec }ifelse }bdf }def /snap_to_device { 6 dict begin matrix currentmatrix dup 0 get 0 eq 1 index 3 get 0 eq and 1 index 1 get 0 eq 2 index 2 get 0 eq and or exch pop { 1 1 dtransform 0 gt exch 0 gt/AGMIMG_xSign? exch def/AGMIMG_ySign? exch def 0 0 transform AGMIMG_ySign?{floor 0.1 sub}{ceiling 0.1 add}ifelse exch AGMIMG_xSign?{floor 0.1 sub}{ceiling 0.1 add}ifelse exch itransform/AGMIMG_llY exch def/AGMIMG_llX exch def 1 1 transform AGMIMG_ySign?{ceiling 0.1 add}{floor 0.1 sub}ifelse exch AGMIMG_xSign?{ceiling 0.1 add}{floor 0.1 sub}ifelse exch itransform/AGMIMG_urY exch def/AGMIMG_urX exch def [AGMIMG_urX AGMIMG_llX sub 0 0 AGMIMG_urY AGMIMG_llY sub AGMIMG_llX AGMIMG_llY]concat }{ }ifelse end }def level2 not{ /colorbuf { 0 1 2 index length 1 sub{ dup 2 index exch get 255 exch sub 2 index 3 1 roll put }for }def /tint_image_to_color { begin Width Height BitsPerComponent ImageMatrix /DataSource load end Adobe_AGM_Image begin /AGMIMG_mbuf 0 string def /AGMIMG_ybuf 0 string def /AGMIMG_kbuf 0 string def { colorbuf dup length AGMIMG_mbuf length ne { dup length dup dup /AGMIMG_mbuf exch string def /AGMIMG_ybuf exch string def /AGMIMG_kbuf exch string def }if dup AGMIMG_mbuf copy AGMIMG_ybuf copy AGMIMG_kbuf copy pop } addprocs {AGMIMG_mbuf}{AGMIMG_ybuf}{AGMIMG_kbuf}true 4 colorimage end }def /sep_imageormask_lev1 { begin MappedCSA 0 get dup/DeviceRGB eq exch/DeviceCMYK eq or has_color not and{ { 255 mul round cvi GrayLookup exch get }currenttransfer addprocs settransfer currentdict imageormask }{ /sep_colorspace_dict AGMCORE_gget/Components known{ MappedCSA 0 get/DeviceCMYK eq{ Components aload pop }{ 0 0 0 Components aload pop 1 exch sub }ifelse Adobe_AGM_Image/AGMIMG_k xddf Adobe_AGM_Image/AGMIMG_y xddf Adobe_AGM_Image/AGMIMG_m xddf Adobe_AGM_Image/AGMIMG_c xddf AGMIMG_y 0.0 eq AGMIMG_m 0.0 eq and AGMIMG_c 0.0 eq and{ {AGMIMG_k mul 1 exch sub}currenttransfer addprocs settransfer currentdict imageormask }{ currentcolortransfer {AGMIMG_k mul 1 exch sub}exch addprocs 4 1 roll {AGMIMG_y mul 1 exch sub}exch addprocs 4 1 roll {AGMIMG_m mul 1 exch sub}exch addprocs 4 1 roll {AGMIMG_c mul 1 exch sub}exch addprocs 4 1 roll setcolortransfer currentdict tint_image_to_color }ifelse }{ MappedCSA 0 get/DeviceGray eq{ {255 mul round cvi ColorLookup exch get 0 get}currenttransfer addprocs settransfer currentdict imageormask }{ MappedCSA 0 get/DeviceCMYK eq{ currentcolortransfer {255 mul round cvi ColorLookup exch get 3 get 1 exch sub}exch addprocs 4 1 roll {255 mul round cvi ColorLookup exch get 2 get 1 exch sub}exch addprocs 4 1 roll {255 mul round cvi ColorLookup exch get 1 get 1 exch sub}exch addprocs 4 1 roll {255 mul round cvi ColorLookup exch get 0 get 1 exch sub}exch addprocs 4 1 roll setcolortransfer currentdict tint_image_to_color }{ currentcolortransfer {pop 1}exch addprocs 4 1 roll {255 mul round cvi ColorLookup exch get 2 get}exch addprocs 4 1 roll {255 mul round cvi ColorLookup exch get 1 get}exch addprocs 4 1 roll {255 mul round cvi ColorLookup exch get 0 get}exch addprocs 4 1 roll setcolortransfer currentdict tint_image_to_color }ifelse }ifelse }ifelse }ifelse end }def /sep_image_lev1_sep { begin /sep_colorspace_dict AGMCORE_gget/Components known{ Components aload pop Adobe_AGM_Image/AGMIMG_k xddf Adobe_AGM_Image/AGMIMG_y xddf Adobe_AGM_Image/AGMIMG_m xddf Adobe_AGM_Image/AGMIMG_c xddf {AGMIMG_c mul 1 exch sub} {AGMIMG_m mul 1 exch sub} {AGMIMG_y mul 1 exch sub} {AGMIMG_k mul 1 exch sub} }{ {255 mul round cvi ColorLookup exch get 0 get 1 exch sub} {255 mul round cvi ColorLookup exch get 1 get 1 exch sub} {255 mul round cvi ColorLookup exch get 2 get 1 exch sub} {255 mul round cvi ColorLookup exch get 3 get 1 exch sub} }ifelse AGMCORE_get_ink_data currenttransfer addprocs settransfer currentdict imageormask_sys end }def /indexed_imageormask_lev1 { /indexed_colorspace_dict AGMCORE_gget begin begin currentdict MappedCSA 0 get dup/DeviceRGB eq exch/DeviceCMYK eq or has_color not and{ {HiVal mul round cvi GrayLookup exch get HiVal div}currenttransfer addprocs settransfer imageormask }{ MappedCSA 0 get/DeviceGray eq{ {HiVal mul round cvi Lookup exch get HiVal div}currenttransfer addprocs settransfer imageormask }{ MappedCSA 0 get/DeviceCMYK eq{ currentcolortransfer {4 mul HiVal mul round cvi 3 add Lookup exch get HiVal div 1 exch sub}exch addprocs 4 1 roll {4 mul HiVal mul round cvi 2 add Lookup exch get HiVal div 1 exch sub}exch addprocs 4 1 roll {4 mul HiVal mul round cvi 1 add Lookup exch get HiVal div 1 exch sub}exch addprocs 4 1 roll {4 mul HiVal mul round cvi Lookup exch get HiVal div 1 exch sub}exch addprocs 4 1 roll setcolortransfer tint_image_to_color }{ currentcolortransfer {pop 1}exch addprocs 4 1 roll {3 mul HiVal mul round cvi 2 add Lookup exch get HiVal div}exch addprocs 4 1 roll {3 mul HiVal mul round cvi 1 add Lookup exch get HiVal div}exch addprocs 4 1 roll {3 mul HiVal mul round cvi Lookup exch get HiVal div}exch addprocs 4 1 roll setcolortransfer tint_image_to_color }ifelse }ifelse }ifelse end end }def /indexed_image_lev1_sep { /indexed_colorspace_dict AGMCORE_gget begin begin {4 mul HiVal mul round cvi Lookup exch get HiVal div 1 exch sub} {4 mul HiVal mul round cvi 1 add Lookup exch get HiVal div 1 exch sub} {4 mul HiVal mul round cvi 2 add Lookup exch get HiVal div 1 exch sub} {4 mul HiVal mul round cvi 3 add Lookup exch get HiVal div 1 exch sub} AGMCORE_get_ink_data currenttransfer addprocs settransfer currentdict imageormask_sys end end }def }if end systemdict/setpacking known {setpacking}if %%EndResource currentdict Adobe_AGM_Utils eq {end} if %%EndProlog %%BeginSetup Adobe_AGM_Utils begin 2 2010 Adobe_AGM_Core/ds gx Adobe_CoolType_Core/ds get exec Adobe_AGM_Image/ds gx currentdict Adobe_AGM_Utils eq {end} if %%EndSetup %%Page: (Page 1) 1 %%EndPageComments %%BeginPageSetup %ADOBeginClientInjection: PageSetup Start "AI11EPS" %AI12_RMC_Transparency: Balance=75 RasterRes=300 GradRes=150 Text=0 Stroke=1 Clip=1 OP=0 %ADOEndClientInjection: PageSetup Start "AI11EPS" Adobe_AGM_Utils begin Adobe_AGM_Core/ps gx Adobe_AGM_Utils/capture_cpd gx Adobe_CoolType_Core/ps get exec Adobe_AGM_Image/ps gx %ADOBeginClientInjection: PageSetup End "AI11EPS" /currentdistillerparams where {pop currentdistillerparams /CoreDistVersion get 5000 lt} {true} ifelse { userdict /AI11_PDFMark5 /cleartomark load put userdict /AI11_ReadMetadata_PDFMark5 {flushfile cleartomark } bind put} { userdict /AI11_PDFMark5 /pdfmark load put userdict /AI11_ReadMetadata_PDFMark5 {/PUT pdfmark} bind put } ifelse [/NamespacePush AI11_PDFMark5 [/_objdef {ai_metadata_stream_123} /type /stream /OBJ AI11_PDFMark5 [{ai_metadata_stream_123} currentfile 0 (% &&end XMP packet marker&&) /SubFileDecode filter AI11_ReadMetadata_PDFMark5 application/postscript ISC_logo_only_RGB Adobe Illustrator CS3 2010-03-25T14:28-07:00 2010-03-25T14:28-07:00 2010-03-25T14:28-07:00 256 100 JPEG /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAZAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A53hQ7FXYq7FXYq7FXAEk ACpPQYq9K8sfkxeTWA1vzfeL5c0NaMTOQtxIp3oqtshPblv/AJJxVM5PzH/LXymDb+S/Lyahdpt+ mNRBJJH7ShgZKHwHp/LFKQ6p+en5k37HjqS2UZ/3VawxqB8mYPJ/w2KEri/Nb8xYpDIuv3ZYmpDs HX6FYFR92Ksk0/8APzzG8P1PzLYWXmDT3/vYp4ljc9tioMfT/ivFKLk8kfl/56he48i3f6J1sKXk 0C9JCvQVPpMS34Fh4hcVeYatpGp6Rfy6fqVs9reQGkkMgoR4HwIPYjY4oQmKuxV2KuxV2KuxV2Kp nYeWPMmo2Ut9YaXdXVnDX1biGGR4xTc/EoI274qlmKuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2 KovSdI1LV9Qh07Tbd7q8uG4xQxipPiT2AA3JOwxV6/Fp/k38pbVLnU/T13zzIoaC0U1htaioY1Hw /wCsRyb9kAVOKXmHmrzl5h8035vNYummYV9GAfDDED+zGnQfPqe5xQkmKuxV2KuxVfBPPbzJPBI0 M8TB45YyVdWBqCrDcEYq9c0TzHo35mabH5a82PHa+Z4l46Lr3EKZW7Qy0pufDo3ajdVLzHzD5f1X y/q9xpWqQ+jd25ow6qyndXQ91Ybg4oS7FXYq7FXYq7FWZflr5Jt/MWoXF7q0htvLekRm51a6rT4Q CREpG9Xoenb3pirIL/8APvzHBq8S+XoodO8uWZWO20oRR0eFD0kbiWUsP5CKe/UqUp/OHRrC21+1 1zS04aV5ktU1K3UCgWSQfvU29yGPhyxQwPFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYqm/ljzVrf ljUW1HRpxBdPE8DOyK44PQnZgR1UH6MVS27u7q8uZbq6lee5mYvLNISzsx6kk7nFVLFXYq7FXYq7 FXYq2jujq6MVdSCrA0II3BBGKvY7SSL82PJr2U5X/HWgRcraYkBry3HZie56Hwah/aOKXjskckcj RyKUkQlXRgQQQaEEHoRihbirsVdiq+GGWaVIYkMksjBI0UVLMxoAB4k4q9T/ADJmi8n+T9K/L6xc C8mVb/zFIhrzlfdIyR2BH3Kvjil5Tih6f5nj/SH5G+VNRPxTabeXFkx7hJWkYfhEgxV5hirsVZF5 Z/L7zh5lIOk6bLLATQ3bj04B4/vH4qaeAqcVZ7D+ROlaUiy+cPNFrp5pU2tvRpCP8lpCrH6IzluP DOf0glozanFi+uQiriw/5x70v4TFqOuEU+MtIlfuNoMzYdlZjzofH9VutydvaaPImXuH66cfMv5L oCkXk12RvtF5PiHyPqMfxy4djT/nBxj7SYukZfYsaX8g9QJSXRb/AEt229eKR2UCnWnqy/8AEMhL sjKORBbYe0OA8xIfj3oa5/JTRdZhe48i+YodRKgt+j7ukc4X/WAU17fFGo98wMunyY/qFO10+rxZ vokD9/yeZaxouq6NfyWGqWslneR/ahlFDQ9GHZlPYjY5S5CCxV2KuxV2KuxV2KuxV2KuxV2KuxV2 KuxV2Kpn5Z8w6h5d1y01iwalxaOG4n7Lqdnjb/JdSQcVZ5+cnl/T7ldP8+aEv+4jzAoa5AH93dUP LlTYF+Jr/lK3jil5hih2KuxV6R+RugWt15kuPMOo0XS/LcJvZnYVAloTH/wIVn+ajFLCvM+vXOv+ YL/WbnaW9maXj14p0RPkiAL9GKEsxVOT5t1s+Vh5Y9Vf0QLj60I+C8+dOnPrSu+Kojyh5D8y+bLv 0NItS8SECe8kqkEVf53od/8AJFT7Yq9Ph8tflZ+Xy11hh5n8xJ1tAFMETU6MhLIP9nyPfiMzdNoM mXflHvLrNb2thwbXxS7h+nuSnzD+cPm7VVMFpKNJsQOKW9n8LBQKAGX7f/A8R7ZvMHZmKHMcR8/1 PMartvPl2B4I+X62ESSSSO0kjF5GNWdiSST3JObACnUEkmytwodirsVVLe5uLadJ7eV4Z4zyjljY qykdww3GCUQRR5MoyMTYNF6bovmLRvzBsE8recgo1ShXR9bUBZBKdlRj/Mfuf/Woc5/X9ncA44cu oet7J7ZOQjHl+roe/wAj5vDc0z0bsVdiq+GGaeVYoY2llc0SNAWYnwAG5xVluk/lF+YuqANBok8U Z353XG2FPGkxRj9AxVksH/OOnm4RiXUNR06wjPXnLIzDueiBen+VjaVT/lRmlJ8Nx520uKUdUqhp 4dZVP4Yq1/yozTJKLbeddLmk/kqg28fhlfFVKf8A5x385GMy2F9p1/H29KZwT3/aQL/w2KsZ1b8p /wAxNKBa50O4eNdy9sFuRQdz6JkIHzxQxSWKSKRo5UaORTRkYEEH3BxVbirsVdirsVet/k7fW3mH Q9Z/LvU5P3V/E1xpLNv6c6fE3H5ELIB7N44peV31lc2N7cWV0hiubWR4Z4z1V42KsPoIxQoYq7FX r+qj/B/5G2VgP3eqebZfrE/Zvq9Ffr4emIwR/lHFLyDFDsVen+RfykhnsB5l86T/AKK8uxgSRwse E1wDutP2lVu1Pib9nxyePHKZ4Yiy15s0MceKZoBNPNH5qyyWY0TynbjRNChHBPRAjmkX5r9gHvTc 9znQ6TsuMN5+qX2PH9oduTy+nH6Yfaf1PPSSTU7k9Tm2dC7FXYq7FXYq7FXYq2rMrBlJVlNVYbEE YqCx3OFfUk78r+S/Mvme6+r6NZPccSBLN9mGOv8API1FHy6+GKvQv+Vcflx5PQSeetc+vaiBU6Np xJNf5WIpJv2J9PFKnN+eGn6PG1t5I8tWmkwmq/Wp1DzOOxYJx3/1nbFWI6v+an5g6qzG51y5RW/3 XbN9WSnhSEJX6cUMYnuLi4kMk8ryyHq7sWb7ziqnirsVVILi4t5BJBK8Ug6OjFW+8YqybSfzS/MH SiPquuXTKOkdw31haeAWYSAfRirKovzuttWjW286eW7LWYQOP1mNfSnX/KBbnv8A6pXFKoPI35We bt/KGtto+pv9jSNTrxLHoiOSW6/ytJ8sVYR5r8g+a/K03DWLF44SaR3afvIH+Ui7V9jQ+2KGPYq7 FUx8u61c6Hrtjq9sf31lMkoHTkFPxIfZlqpxVnv576LbJr9j5n0/4tN8x2yXKOBt6qqvL/gkZG+d cVeY4qm/lLQn17zNpmjrWl5cJHIR1EdayN/sUBOKsz/P3XEvvO502Cgs9FgjtY0X7Icj1JKfLkE/ 2OKXmuKHr/kfyHovljSY/OPnmP4m+LR9FcfHI4+JXkQ9/BTsOreGX6fTyyy4YuLq9ZDTw4pn3DvS Hzj521rzVqBub5+FuhP1WzQ/u4l9v5mPdjv9G2dVptLDDGo8+94TW6/JqJXLl0HQMfzJcJ2KuxV2 KuxV2KuxV2KuxVmui/lbofl3TYvMH5kXX1OB/itdDiNbiYjfi/H4h7qvT9pl6Zwr6mgPNP5z6veW v6I8sQL5d0GMcI4bUBJmX/Kdaca+CfSTih5yzMzFmJLE1JO5JOKtYq7FXYq7FXYq7FXYq7FXYqzr yl+cHmfQ4jYXxXW9EkHCbTr4+oPT6FUduRUexBX2xVkFz5E8l+e7aTUfINwLDV0UyXPly6YLU9SY WJNBX3K/6mKXl2o6bqGmXstjqFvJa3cB4ywSqVZT8j49jihDYq9csCfNf5EXlo3x6h5TuPXi/m+r mrGp8BG8n/ADFLyPFD1f/nHzToE1zVfMt2KWmhWTuX/leUGp+iJH+/FLzLVdRn1LU7vUbjee8mkn l7/FIxY/rxQ9N/LPydpej6V/j7zYlLGA10WwYDlczb8X4nqKj4P+C+yN7sGCWWXDFx9VqoYIGcv7 fJIvNfmrVPM2ryajfv1+GCAGqRR12Rf4nuc63T6eOKPDF8/1mrnnmZy+A7kmy9xXYq7FURFp9/LG ZIraWSMCpdUZlA+YGRM4jmWYxyIsAqDKysVYFWGxB2IyTAhrFXYqrwWN7cAm3t5JgOpjRm/UMiZg cyzjjlLkCVF0dGKupVh1UihwgsSKawoS7Xdf1jXtRk1HVrp7q7k6u52A7KqjZVHYDOFfUkvxV2Ku xV2KuxV2KuxV2KuxV2KuxV2Kq1neXdldRXdnM9vdQsHhmiYo6sOhVhuMVetaT5q8tfmTYw6B5zKW PmNB6el+YECqHPZJR8I3P7J+Fu3Fuql5z5t8oa35V1d9M1aHhIPihmXeOWOtA8bdx+I74oZr/wA4 /wCqRJ5sutCufis9ds5beSM9GeNS4r/zz9QfTirzzWdMm0vV73TJv72ynkt3PiYnK1+mmKvVNL/5 1z/nHy/vPsXXmW6METHY+mW9Mr/yLhkI+eKWK/lZ5Gi8y6xLdakfR8vaSv1jVJ2NFKrUiKv+VxNf 8kHvTDGJJocywlIRBJ5BM/P/AJzl8zaqDCvoaPZD0dMtAOKpGKDkVGwZqD5Cg7Z1ui0gwwr+I83g O09edTkv+Ach+O9DeQVVvOuiKwDKbyEEHcH4xk9Z/cy9xa+zh/hEP6wfUN7ZWf1Of9xH/dv+wv8A KfbORjI2N30GcI8J2HJ8gKrMwVQWZjRVG5JOdu+YgPpPyF+V2ieX9PgnvbaO71p1DTzygOI2I+xE DUDj05dT+GcprNfPJIgGoPedndk48MQZC8n3e5MtR/MvyPp2ovp15qscd3G3CRAkrqrdKM6IyAjv U7d8qhoc0o8Qjs35e1NPCfBKfq+P9iM8xeVPL3maxMWoW0cwdf3N2gHqpUVDRyDf38DkMOoniNxP wbdTo8WeNSF+fX4F8u+YNGuNF1u90q4PKWzlaMuNgwG6sB/lLQ512HKMkBIdXz7U4DiyGB/hL2P8 pvyv0tNKt9e1q3W6u7tRLaW0q8o4ojujlTszOPiFegp3zR9o6+XEYQNAc3qOx+yYCAy5BZlyB6Bn OueevJ/l2dLLU79LWbiCtuiSSFV7VWJX4+1c12LSZcouIv8AHm7fUdoYMB4Zyo92/wChW1TRPLXm zSUN1DFe2lzGGtrpQOaqwqrxyUqp3/rgx5cmGW2xDLLgxamG4EokbH9T5l83eXZ/LvmG80iVuf1d h6UvTnG4DI30qd/fOs02cZYCQ6vA6zTHBlMD0+5g2cY+kOxV2KuxV2KuxV2KuxV2KuxV2KuxV2Ku xV2KvXvJfmjTPPWjL5F84SgXwFNA1l95EkA+GN2JFTtQVPxjb7VDilhVvaar5E/MCzXUk9G40u8i kkYV4vCHBLIe6ulf9vFCdfnzpA0/8xryVF4xajFFdpTp8S+m5+l42OKsj/OCyuoNL8keRbGMyXkd ujPAvV5nCwofpcSYpd55ntPKnluy/L/SpA0kYW51+5Tb1bhwG4H26H5BR45veydL/lD8P1vK9v6/ /Ix/zv0D9PyedZvXlmQfl/8A8pvof/MbD/xMZjaz+5l7i5vZ3+MQ/rB9TXv+8Vx/xjf/AIic4+HM PoeT6T7nyT5eeGPX9NkmIEKXUDSlugUSKWr7UztMwJhKu4vmumIGWJPLiH3vrzOJfTXyX5t0TU9G 8wXllqKMswld1katJUZiVkUnqG/z3ztNNljkgDF821mCeLKYy538/N6T5b/PPT9L0Gw02506eeaz gSBpVdQG9McQd9+gzVZ+yZTmZAjcu90vb8ceOMDEkxFMA8363F5q84T6jbQtbrfvBGkbkMwKxpFv Sg/ZzZabEcOIRJur/W6bW5xqM5mBXFX3APqeCGOCCOCJeMUShEUdlUUA+7OPJs2X0SMQBQ6PlHzt qEmoeb9Yu5G5c7uVUPX4I2KIPoRQM7LSw4cUR5PnGvyGeecj/OL1b8tPzM8oaR5NsdO1fUvRvLcy gxmGeSitKzL8SIy9G8c02u0GWeUyiNj5h6PsvtXBiwRhOVSF9D3+5gv5veYdC17zPDf6NcfWbf6p HHNJwkj/AHqySVFJFQ/ZK9s2PZuGePGYzFG3T9s6nHmzCWM2OHz52e95PnKveOxV2KuxV2KuxV2K uxV2Kppo3lfzHrb8dJ025vexaGNmQf6z04r9JxVm+mf84+fmDdqHu0tdNTq31mYMQPGkIl/E4qjz +Snley21nz3p1rIPtQp6ZavtzmVttv2cUrX/AC9/JuIN6nnnlx2bgitv024hq7+GKFv/ACrn8o51 UW/nxI3bcNNGoFKdwxjp9JxVa35EPfAny15p0vWSASI1kCOQPaNpx95xSw/zD5A86eWG9bU9Nmt4 o2BW8j/eRA1+E+rGWVT4VIOKHoc5T81Py+a5oG86+Wk/eU+3dW/XoOpYA0/yx2DYpRfmjTv8Tt+V up0EhvhFaXzHv6RjaT9UuKsi1Q2sHnnzL581FRJbeW4YtN0eNukl20QZ/wDgXm4/ST2y7T4TkmIj q42r1Iw4zM9Pv6PE769ub68nvbpzLc3LtLNIerO5qTnZQiIgAcg+cZMhnIylzKhkmDIPy/8A+U30 P/mNh/4mMxtZ/cy9xc3s7/GIf1g+pr3/AHiuP+Mb/wDETnHw5h9DyfSfc+Oc7l8ve/flf+a1hqdn b6NrUwg1aJRFDcSGiXAGy/EeknYg9e3hnN6/s+UCZwFx+79j2fZPa8ckRjyGpjr3/tZ35g8s6H5g s/qurWiXMYr6bHZ0J7o4+JT8s12HPPGbiadxqdLjzR4Zi3h/nz8mtS0KKXUdIdr/AEuMFpYyP38K juwGzqB1YfdTfOg0facch4ZbS+wvJdodiTwgzh6ofaP1sD0X/js2H/MRF/xMZscv0H3Omwf3kfeH 1/nEPpz5A1r/AI7N/wD8xEv/ABM52+L6B7nzHP8A3kveUFljU7FWPZwr6k7FXYq7FXYq7FV0cckk ixxqXkchURQSSSaAADqTir0LQvyV16e0/SfmS5h8s6QKFp75lEpB8IiVofZyp9sVTQa9+SvlP4dJ 0uXzXqKbfXL2i29f8lXXjsen7r/ZYpS3WPz68+3qejYyQaPagcUis4lqF7DnJzI/2NMUMI1PzBru qsW1PUbm9J3/ANImeQfQGJpiqAxV2KuxVtWZWDKSGBqCNiCMVZr5Z/ODzvoRERvTqVh9mSxvqzoU 6FQzHmu3gae2KvTvIbeVNd1uHzR5Kj/RGu21BrflwsFintpCBIYvsqKbMpFF5Acgta4pelQeULC3 OnLCeMGmX9xf2sVBRfrMcwaMf5Ie5LL4UAwK8p/PDVYbWW18s2Tfu0kl1G//AMqe5kZ1B+XNj8iM 3/Y+CgZn3B5P2i1VyjiHTc/oeUZvHmHYqyD8v/8AlN9D/wCY2H/iYzG1n9zL3Fzezv8AGIf1g+pr 3/eK4/4xv/xE5x8OYfQ8n0n3PkCxsbu/u4rOziae6nbjFEv2mbwGdvOYiLPJ8yx45TkIxFkp7L+X HnmKJ5ZNGuFjjUs7ECgUCpPXMca7CduIOYezNQBZgU78kfm/r2gPFaagzajpIopic1miXpWJz4fy tt8sx9X2bDJvH0ycrQdtZMNRl6ofaPc+hbC+tNQsYL60cS2tzGssLjurio2/hnMTgYkg8w9vjyRn ESjuC+cfPWi2egfmU0Fsojs2uILmKNeiLIVZlA8A1aDwzqdJlOTT2edEPC9oYI4dXQ+mwX0tnKPe vkLX42i17Uo2+0l1MrfMSMM7bCbgPcHzLUiskh/SP3p/5W/K/wAy+ZtMOpac1utuJGipNIytyUAn YK23xZjajX48UuGV25uk7Jy54ccKq63QHm7yVrHlW5t7fU2haS5QyR+ixcUU0NaquW6bVRzAmPRo 1mhyacgTrfuef5xz6M7FXYq7FXYqy7yR+Wev+aud1HxsNFgqbrVrn4YUVd241pzIpvQ0HcjFWUTe d/I/kZGtPI1kuqayoKzeY71eQB6H0E22+VB/rYpeea95l17zBeG81i9lvZ9+JkPwqD2RBRUHsoxQ lmKuxV2KuxV2KuxV2KuxVHaHrepaJqttqmmymG8tXDxuOh8VYd1YbEdxir7K8s+YbPX/AC5Y65AQ kF3CJWBP2GG0iE7fYdSpPtgpNvl7zXrTa35j1HVSSVupmaKvURj4Yx9CADO10+Lw8Yj3B811mfxc sp95+zp9iU5c4zsVZB+X/wDym+h/8xsP/ExmNrP7mXuLm9nf4xD+sH1Ne/7xXH/GN/8AiJzj4cw+ h5PpPufKPlDU4tM806VfzNxht7qJpm8I+QDn/gSc7LU4+PHKI6h850WUY80JHkJB9YTRRXNs8THl FMhUkd1cU2+g5xgJBt9HkBIV0L5wvfyZ8+Qai9rBYi5g50iu1liWNlrsxDMGX5EZ1Me1MJjZNHue Fydh6kSoRsd9h7/5V0d9F8uadpcjiSS0gWORx0L0q1Om1TtnN6jL4mQy7y9ppMHhYowP8IfPH5t6 vb6l57v5LZg0Vvwtlcd2iUB/ueozp+zsZhhF9d3iO2cwyamRHIbfJ9CeUteg17y7Y6pEwZp4l9cD 9mVRSRT8mrnM6nCceQxL2uj1AzYozHUfb1eQfmL+UvmebzPd6jotqL2z1CQzkK6K8ckm8gYOV2LV IIzd6LtHGMYjM0YvM9p9j5jmM8Y4oyN/F6j+XXlq48ueU7TTbog3YLy3IU1AeRi3EH/JFBmo1ucZ cpkOT0PZmlODCIS+rq8Z/PDWIb/zqbeFgyadAls5FCPUq0j7+3MKfcZveycRjhs/xG3le3swnqKH 8Ir9LI/+sZv+XX/p9zmHuXf9Yzf8uv8A0+4q7/rGb/l1/wCn3FXf9Yzf8uv/AE+4q2P+hZ6j/eX/ AKfcVZ35o/5V9/hS2/TPpf4Y/d/V/q/q/VaU/d/7y/Dw/lrtX3wKwP8A6xm/5df+n3Crv+sZv+XX /p9xV3/WM3/Lr/0+4q7/AKxm/wCXX/p9xV3/AFjN/wAuv/T7irv+sZv+XX/p9xV3/WM3/Lr/ANPu Ku/6xm/5df8Ap9xV3/WM3/Lr/wBPuKu/6xm/5df+n3FXf9Yzf8uv/T7ir0Lyt/gj/CMn+H+P+G6T 8+Hrcab+tTn+88en0YYXxCubDJw8J4uVbsM/6x8/5d/+nvNx/h3n9jz3+tnl/snf9Y+f8u//AE94 /wCHef2L/rZ5f7J3/WPn/Lv/ANPeP+Hef2L/AK2eX+yR2h/8qQ/TFn+ifQ/SfrJ9T4/Wq+rX4acv h6+OV5fzfCeK+HrybdP/ACf4g4K472+rm9Jm9P0n9X+74nn/AKtN81Q5u+lVbvKP+sfP+Xf/AKe8 3P8Ah3n9jzn+tnl/snpmifo79EWn6M5fo/01+q8vUr6f7NPV+OlOle2anLxcR4vq6u+wcHAOD6a2 5/pRuVtyleej9Un9fl6Ppt6vDnz48Ty4+n8dadOO/hko3YpjOuE3yeVn/oXyu/1evf8A3rzcf4b5 /Y87/rZ5f7JmXkX/AAR9Vuv8JU+qcx9Y4ev6fqU7er8PLjSvH2r2zA1fjWPF5/D9DtOz/wAvR8Dl 15/pZPmI7Bx6Yq8quf8AlQn1mX6z6P1jm3rep9c586/FyrvWvXNzH87W11/mvOS/k2zdX/nP/9k= uuid:7127DB5039AC11DFBC4CC917F60414F5 uuid:7127DB5139AC11DFBC4CC917F60414F5 uuid:7127DB4D39AC11DFBC4CC917F60414F5 uuid:9EF2320A284E11DFACBCF5F943788E24 51.000000 66.000000 Picas 1 False False Cyan Magenta Yellow Black Default Swatch Group 0 White RGB PROCESS 255 255 255 Black RGB PROCESS 39 37 37 Yellow RGB PROCESS 255 242 45 Lime RGB PROCESS 189 213 118 Night Blue RGB PROCESS 31 113 184 ISC logo blue PROCESS 100.000000 RGB 0 153 203 PANTONE 425 U PROCESS 100.000000 RGB 94 96 98 % &&end XMP packet marker&& [{ai_metadata_stream_123} <> /PUT AI11_PDFMark5 [/Document 1 dict begin /Metadata {ai_metadata_stream_123} def currentdict end /BDC AI11_PDFMark5 %ADOEndClientInjection: PageSetup End "AI11EPS" %%EndPageSetup 1 -1 scale 0 -45.0176 translate pgsv [1 0 0 1 0 0 ]ct gsave np gsave 0 0 mo 0 45.0176 li 117.999 45.0176 li 117.999 0 li cp clp [1 0 0 1 0 0 ]ct 20.5381 45.0176 mo 63.8301 45.0176 li 60.3721 31.124 32.5381 35.542 20.5381 45.0176 cv cp false sop /0 [/DeviceRGB] /CSA add_res 0.372549 0.376471 0.384314 rgb f 62.46 39.5361 mo 54.5381 21.667 23.9551 8.62402 0 27.083 cv 0 45.0176 li 18.1216 45.0176 li 33.1802 33.3477 54.6216 31.624 62.46 39.5361 cv cp f 63.7471 38.749 mo 60.9551 20.874 52.6006 1.02051 38.0801 0.666992 cv 38.0801 0.666992 li 32.1006 0.864258 27.0381 3.77051 21.9551 8.37402 cv 21.2773 8.9873 20.1318 7.98926 21.0381 7.14551 cv 24.5068 3.95801 29.2256 0.833008 33.0381 0 cv 0 0.0263672 li 0 25.249 li 25.0801 6.70801 56.0381 21.333 63.7471 38.749 cv cp f 65.2041 38.874 mo 68.8721 15.208 81.1221 -10.792 83.7041 11.542 cv 83.7471 12.583 82.2471 12.583 82.2471 11.667 cv 80.9541 -8.08301 70.3721 17.833 66.8291 38.292 cv 78.4131 10.792 107.704 1.29199 117.999 12.917 cv 117.999 0.0263672 li 42.9546 0.0263672 li 55.5381 4.42676 62.7471 21.749 65.2041 38.874 cv cp f 66.0381 45.0176 mo 80.543 45.0176 li 80.543 25.8945 li 84.7637 25.8945 li 84.7637 45.0176 li 89.2861 45.0176 li 87.9697 43.7939 87.6777 41.8916 87.8086 39.8379 cv 92.0273 39.8379 li 92.0273 41.7656 92.1133 43.3867 94.4316 43.3867 cv 95.8555 43.3867 96.5547 42.4648 96.5547 41.0957 cv 96.5547 37.4629 88.0605 37.2402 88.0605 31.2324 cv 88.0605 28.0742 89.5684 25.5586 94.7109 25.5586 cv 98.8184 25.5586 100.858 27.4043 100.579 31.623 cv 96.4707 31.623 li 96.4707 30.1133 96.2207 28.5781 94.5156 28.5781 cv 93.1465 28.5781 92.3359 29.3301 92.3359 30.7285 cv 92.3359 34.5566 100.829 34.2207 100.829 40.5645 cv 100.829 42.7754 100.14 44.1553 99.1064 45.0176 cv 105.153 45.0176 li 102.93 43.1367 102.927 39.5938 102.927 35.9824 cv 102.927 30.6445 102.927 25.5586 109.884 25.5586 cv 114.187 25.5586 115.919 27.9355 115.753 32.2656 cv 111.616 32.2656 li 111.616 29.584 111.142 28.5781 109.884 28.5781 cv 107.509 28.5781 107.202 30.8125 107.202 35.9824 cv 107.202 41.1504 107.509 43.3867 109.884 43.3867 cv 111.841 43.3867 111.757 40.8711 111.812 39.2793 cv 115.976 39.2793 li 115.976 42.1104 115.377 43.9248 114.243 45.0176 cv 117.999 45.0176 li 117.999 15.374 li 108.704 0.791992 74.0381 14.624 66.0381 45.0176 cv cp 0 0.6 0.796078 rgb f %ADOBeginClientInjection: EndPageContent "AI11EPS" userdict /annotatepage 2 copy known {get exec}{pop pop} ifelse %ADOEndClientInjection: EndPageContent "AI11EPS" grestore grestore pgrs %%PageTrailer %ADOBeginClientInjection: PageTrailer Start "AI11EPS" [/EMC AI11_PDFMark5 [/NamespacePop AI11_PDFMark5 %ADOEndClientInjection: PageTrailer Start "AI11EPS" [ [/CSA [/0 ]] ] del_res Adobe_AGM_Image/pt gx Adobe_CoolType_Core/pt get exec Adobe_AGM_Core/pt gx currentdict Adobe_AGM_Utils eq {end} if %%Trailer Adobe_AGM_Image/dt get exec Adobe_CoolType_Core/dt get exec Adobe_AGM_Core/dt get exec %%EOF %AI9_PrintingDataEnd userdict /AI9_read_buffer 256 string put userdict begin /ai9_skip_data { mark { currentfile AI9_read_buffer { readline } stopped { } { not { exit } if (%AI9_PrivateDataEnd) eq { exit } if } ifelse } loop cleartomark } def end userdict /ai9_skip_data get exec %AI9_PrivateDataBegin %!PS-Adobe-3.0 EPSF-3.0 %%Creator: Adobe Illustrator(R) 13.0 %%AI8_CreatorVersion: 13.0.2 %%For: (Brian Reid) () %%Title: (ISC_logo_only_RGB.eps) %%CreationDate: 3/25/10 2:28 PM %AI9_DataStream %Gb"-6l`OMbE[LJ_q]3tS#.hk;RCln\`W52%O[2PJ[A8p.$lUE-e`+)02HWtBjem;l`:l^'^%YrXh)pjOjoWZBi7b__jiWO/I.<,% %gjf7q_jBgUr;Q]Us8D8Q<;K=,o"3_BQqtKl`IE=1f5JF<]]V232W_s5g1jbTe4$?XI3dY"+Wl(/pu^?*Da/X@Rnk-`]`%]mLQ>ej %r:KZcD]\oFM[qarn\stKs*ShXJ%kmHX,m:,F8sc,DuQrh0CJhPrpKU<=)X]qIX;%52`L=d#VDq2h1,=iX"XMDg\:aCp=$3`8hNHU %^XEepp?OTc)HD5Ent1DVo@:,M;G8rrP\-omT_?iK3U0E:1;r1rE#WJrVkW.?XmRDGCT>Nh3\$+pN/4X%t0&aEVM]mgEsJ& %pR?*XI__c2G's(C4\c9lJ+;:dNDCY1I/*JCQ@J;1?ehiOrF,)p[<:j9r+Gu#p$lu#@'eI7s6_O)Y.N;t>%=0';ZCD-mPeL$]Dh-B %5(3A&%tFT;T0AiqH2$F@IscV7RkMMOkB11hIe`L"?ep6Es1GU4/F)PFs74`S[pQfF_lpdq]YF7f]B&]FJ+\m&j6`=SeqZQD5Q1<1 %GMg(3irf8RN@`PVS,6"=If7SOJ+N3j=$FCjs70lUXAlb15K7pF7R-D$YbI[TBhm!+O5P""K?[VOs]AJ,7 %iXc(em`eC3nA>5&2qe60J1k,>r6sF!H2T,jrZ9hbhqnCna04?JrI44T"6DIKI/*oGhd[UTou2\>52@XCLD9Hgp@%!Rk:F_g %5%soN@Z3h.pZg:QnAKcss5EJ)J+i,b0Ae@!qs0_Yrp>IO?bCmcjj!6[qUOi![!6u3\c;6m&#]I+']Q]Q`a>X9F0P\*#5l:JI/5L3 %V='uD+7C<>n*f`5kC(*`p[u8UkPKKGm[ihfn*]Z4mcM+W?+VV2q(CKWq)k;3_n;W4CWn]'OttJp1Q:MeF;b\MIOt=4UQ))sNjPt9 %TDRZ[*r:;WlPdJ2\usI[O$0r7p9_!CG2LmF[*e`]=tAp]Vj:P%TnW>JT@W\>Xu4=I=4cXk7]iDVXt-\+Xt/!uT%EYBY(q-_QM!f1 %:9RO7Baq\g\EIQ4IjJ?^=+9"mXjf/0-b]6"lgKVu&G8i0i^6mN`8Bf&YDYX"^ZD&3E^DncDu99kG5OA(-fX$(l$D".-iI]LX.EU` %<;sMi)HW/P>"&6@?N+;eY;s5G8qjZRO*+_;QbN:9JSX8V_f`07""sS!o'9G]e)U$u^_Li8^Tq2M=7rU7Y3sn$4Uo0giOV*UpLi*q %`V"J)S^nmTqt9mXV7UJZo=d-\>hf7,Xl&0-kAq1":o']70!4FbaKMiYc.tEC%r3VdqXXt;lG6Y)aZ9WCoHD!3\3$hApRj&81nNbTal/cU9X"'%Nq&l.p[_Zm='Wd-YH-H\e$T\FqSp-e\f9u5bHLfTLNU^3PN@)(&*o,=9'aXcP%,h/F$7V(,lN2: %jBfT4nWpe6qt4q.E3_EOG)UZfK(&ZE';6pVYiF>\hUg68H9PZP"V+Tr]96DHqeKL5i[Pbrjf`iM.5O'=?[dtNYPHl;md`DEOm`8% %[8s<_r8MqpT0rr;Ni]u3qpjSPEDcV^Y/Md]2m80)m7Q]M5Eer>p`]H_b8#$=Y9,0Erhi<;2)j>TlZm%fmaeOh>\rI]`jkC2fTu<# %nSW3Ra8!<=-`+Ja6q_qKS%H)7*uBQTc7u5%f%0&1X93L8+.#Z'CDBKKqa8ao)Dk-OK`Umn6`[k4fM@I^&S[GGmpZEeY3S9I!\ %l`B-B(HLTTFi`s+b5msi?1_O.6`h_>::$I$42l5lp%5D.S+OqIGo_3)f)_/3H."KOoe]E,JIcefF>_?GR2eUTe%uNQ5E]L`#C`*dg$GO$mS3CjY\j@??Pmhf8@Tn!b:.?7#/.,Xp6V&,'`9Z'K\6R3't\H!E#iiH\^)CQo)&rLeZ3](\k-e63d3.uLtc*OE$d %0H)\f#d!3cTKG/<'c2-%eUW<'l4rZ+Ia2:Q%een&J`WW%U%IS^92;b2jn9EP@APFOYe7IoL%pSL_Srs!*gV2DYjPbCXM=._TbFFe %!VoK;M2s^WSW;(iG'QUKIY,>&HX2&(H-o9jkV";hn"Za?%_?7MD=^p'bm.pP6T*-rSMNUuHrRfNDU-^o@3)@\?Df!9o!of7[*Lha %5.g*P75`Gj)X%hkcoYp69f:9K3p:9t`Fi1:+&iQ;We<8D4BDSM&,dTbqTILTJhXpZ28AHl;gT6L,js-1:e:@#*_f>+#!FhO5aC&-6=2\^B3.=W`D40?\T/ZsTO^[Md3)=5;qfhjKnW7M.NHk;S* %m*C%+MsSb'r\4r8P-:b%%FsK,(Q^SJ(8m4&[4!,Z@jO6."SbrcV(Lq.@'bXjU/m0npd_Yk:AQU)`HSdhQ2o><(D6TkXASsT9:4Ol-Fa1_?XG7jNek9Vrkt;E)j7\H(EeWSb:O*\[C"IGkn;+dE%OJuYQM5-Y,DsBiq@)78m]r- %GHW4!/-.9\ol5i>[&2[2@lu=04fh.)H6VcWQAQYfHIPN?kd(Um&YE!UkOY-J?737de%B4gWl01RGYs)8Q<#ZMY=Zp2g@""LEoUUV %9=$cI:d1hVN%-3aP^HGQe4cs@k0MjmCCc?>4g/]8f8:?ODRs"-,0:m$@]65";Uiu/C-FaF\>VAbjV]7WM_5YU,1rK(/#oh;mmnr- %1)/PjYc.E?c)IHeFYoo&$)R4Ob];DqPM8\W2j@\k\QsNM %b*V4cnicNl7/1I;eOsu/n$6uFE)P<3it,b$NZC9R5Z8q&TuUG3`.C,^G'W]*@W;=B?SZ$M@mbXZ[!ZoS1;gckl:s#Ho?iQA">fYUNht4@Zh1P1l0)-9 %E%#RIOu\`MQ)'G9'DtDImR&Jn+.;F#Jl\:a"T(*`F;t`gF/')'VC,<0ZRK#!hhQ5u?Ho[K"(WpefroM-U0T/*V>Cl3KBq_&FN`q: %_64c4J3':2JG=n`K_&.,Th5a.,=Ou:q3&3aKdO>N7FF*Z3X#7*h:-DMNg'tAgX@g)pYuLgs8!FIQ\%:tP1rS< %F6F,j,YKpq,%/P@j`d/'h7>e@lYToTo;;69`FOnQj(B4OB#In@P+OSK68Ma)VtC1lb7EnHJr[71HjkA#>&RUbLC*q/O`Wc!q(kI* %0jF@mmG]L/9Zb%P,,T"LaQ)$q9=^T>+(k'W`m?`e@f#Zd#@5FaUTS]r[E\[(m3U(_Of*OE5AccFPP[k2KefP$rPG(?_n?WG'^ACt %hnid!rJKm-2-lnA:RGmI4i$),>!dhs>h,\mW[$<"Jc93BI#9<8#j)=3E.gER/(?D/ZqS]Dg;+C:9;/nKIddd%+K6C5i7jVHeIA/h %*+W/k))`"C;NkOd$;cISMF!8n<"lPS$"Y!N)g)D-WK;!EhsM==GsI='M)lAp_$+/"K7u%EIYab$,Xl/k%k7fAU2gld %-l2q8nR2$#BDL)[T8%;XGL8/$(/fMCF:^ME*f+5Y#"Fap9"a0B9'=e4;&_uBp2qERfOD:]?/sq5-NneAYIi+cf=r@ZY7ll)bNnE5 %?Dk,Z56(9@o[ATjUBAr>_F#@VJ"]_YH.;5c5P]k[n]7?\Fuqe[C)iHS%fQR)+EmC@HC2j+!A#"*EZX_[1^i7E`WHS-,NcnVK-Iq\ %^fG%dQiU1?'5W=L\.F@P:2)uI]['-%j %&`k=:Bts'G9]b-!$5e\TCCe'ho9T`BOk2@8ce6R*l-t>LH=T8=TY2BaO^=qASojttZR>^eZEC@ZkPjLna*mFBoYWoamm#_@4lUY# %T+;Pt+-&9jq?_.`4lCY!H,/_RP5TX@m;UPR2u10_pIUG?P6Aa%bhE0%I_b.*J3P.:r3fX?YJLN`;JY5>oTL5tEkqD][iPT$TP6F@S2SO8@Os5S60"/jIa %KpSu9?L_0iEIIfL?`3@4cZ_1?MsL#QDZ`HYPf:G].C9BGSp=d9H&]t]q.(Y@;1+UOf:]Il7=!!N("bn %qK.UmM\stB72"ML=VN>jAb',4VmH$0QP08BYO^?Sq%T_o7c4flg@]T7JL!b`q>'i#4mKpgo"2l:LLufNbor4^OeC %GG`=c5.6f@/[!PSY2`(9JW_Y51<)r3_auq_F:9VcjGP$Y@U'5%V3=M1$SF0H_uLH<9FN[2bbTe:%lILoM.mh53*F>EJkd5-o"^HC %Sh*fblIkL'/6M+!la_r[6tn(7K_YGX8)Pt;\7m]?1PaFJmdR!+E#t*&4>fqmPY!^R+Pot@AdqCJ[t0 %a5D66gXU2nkq&$-psfmV4']gBc>n)>MOJpY\p/L+b,Y(!q[(/)*Uu?7nNS&a5998Y*Uu?7nNS&aruW?Q@j(SDE1Urf\BS/d_)kKk %R2\!$Lfj%]P6baL+#G#g&^iWX9BWLqcTh2W5:qgR?OS/S#pX$m,>OWf_dDOg][3"f830H@G+eU<5@+3=j[V!(jE81HCtImCVeZqE %^7I\VS+lH`VJk/"'E38ihO1I*M@N/BK3G59N%jG[5bZ8_(Q&q%;<^M,&$#G$q['E(opVUWKL+!Ic09L7P`(oI'U_(=(hc:ALjBi\ %hjLTQ"Q^hg8:=4$r7VpQ4td^$aOIb!a.amE,c8D$Fi6FF%Wc@Oi,p(0]^ke[VK)7FRNL)nMZR@n%(RM*W9@dXKf=11?60]W[IB)S %^=_IJJK'$D9B_nq.=6ldTJVBefdGi/KsP/[;\:rfgta1e=Bqn"'[h8q=9Ppf5L)nd5%"$RS`r,3(\;X\,9uBX#rtPu3W8H;SF`bL %Z]puVKq+Nq@qs=_MTnpF"$'ZDU<.Z*jnHi.JpHmP!k8Zq20-S0u*eoa:OLN?uXaqZ8XGS.u<\0YC %dlg;#8W0O1Q;K4sn"bisK,5_9.U>9>6Om:T>a9:7bHOD(#ka(4V.G.s'/`E.IQo6%%]HV3)Of@dhk'8LF1kFbouL=;P6RR[CitLG %RjX1A71BM;NR)]"=1UnYdZ]tD74h#5lq>rkWB'_o&[>,e)#Z0TLT,a_&?0-:+p8mpYSc- %:bQ$Qmomk7!oYUaQ"6i8U@CKC<^dmtaK6mi=$Cgu`Y1It`#h&79%#A,%na8*i1"gb,*r#\T3h"_I^b)q5"]8uSbX\Q9=_*Qc[D%M %pJ>2m-d=_uY*C`N58jmk;@BSO+maT+9mj-KAN=EB5ORR/I8MSbpr)R(_?Na&LH`2eocNf6Y*GQM36k=KG4LRF:4CFi;LOjLE;,[#l#"\uW-jW=I72iQ]]i>gM>reX5.(OP/ %f$TsUIhk1Nn7fF7lNq&aSGBUZ@U[n>lJPQ/ffWO3ERDs@*gN@n6+l-/3.4$iiH$&r+'R#,IZCEfauu&kAND=+G$^-.-r=%k(-!s^ %P$5hHSBObMl[2Hm';)9UfJkFCX=T'!G5DZQpns,Cdq!HH;&36L"*IbJL6;l:&OhnE'8ie^K6G^NG$0!/=)%eGH,;>#2l/Vp %3VNMm)7bPuciGgF=8'Edi7ab;d%Dh&b`g'$Wb2#E8qE\U9W^=6#cgZs8=!N(lLVMQU2JPleiX7N%(mQ[4WFt^+nAP$mh@Fpcsh_: %M'jFb(efl*j<>KlI*6B*]9C$;$>rZ0sAdl-V) %W);aQN0fojB/kiOY_rKa4<:[A%rdEh@#:s`HpGBtUFR3XX;ur!&P`cQ&Z@NXf]L-<,+<#rEDSGPkqY3,q&N`'XSY&EK:j@J:d+YA %6-*clK:j4FWYFer#BjBZ\k>@d#]_sV"$819pe7CG2>6K76t?t-i:J$2LED>mB$/!T8,+#5JLll<>PS9A*Du*8AW?j-!upAW]B(hG %-f?&se'[a6D1$H0.\_c;XrXo7U/[9C;MQaXWL"O'5s!<'q_RV]HVn/>Tq5S2U5F1O*S>Ko9)\VZG52P6D)GRf,(Wg4h9TAY3TFWU$:iOY1&THA+Vf&&+dh[6$^>"mf+W\66cP:kRJH^)V(Ms&4=*sa(II9>FDYc#QhcsL#nr$Rq %nVS^Ts'8siGaVb*1En3)coo'=")sL:.XA4JhtP^348a1*#[@;(\_K:F[2b?t$n^;3kIP">T$9Q6al-A!I=Gfha.H<=gF)gf7MsNqEFTM+,K2\Go8>EZbZ_UN>XRgh> %5_gT?JGO7V#kDN;.UV`jrhOPJMj+1&/k"D$8cM;M9;+r/B(RhXl4e.(f'gBRf@.4pg)]b`rnl9krf?`is&c(H]dYmiEUs_@4ktE6 %p\sjM<=.)6nYYq\6thjTpSV)eq;0Dnm2X3NccBs`>HsrVbRn0U*BsHgBD#?lh)&rRgZCiN;==d5(M+PA1lkmOr:'GfSBiif5rbo/ %m2AVPE_H(;dIMU-bK;MBC^mbJJjlAugYUu8_o\i5<1.lB9:]3!HN!DY]fuCYhOe];q<@SpFY:'g-^"#fHA6+N%)(J70$Dg$W]2=k %NjlDCO@:2&Z$U9P3^R0\`*,>LEd%D)#bKfR#$=*B]G<*ZhR/H46B6[#>YOkmcV^!_eu%7TFrd0L/e':SOQDJT]jp;'p2rC!(Lfcr %KZlAbAr@SM1hnLuEu8m;EI?@nFiqse'>Vig3mu2>PlF;F]m.e[glbAUhZc47,3I:Q&]JJdZ,AY^R$[TQW@`.\'a$!S[GftEqQqn[ %Ru[YVb[=66@Ur5N)0XEKAa(EVAF3YrD4)c6`3o&n\5og0e7tM@)HU36*ALuQff25g'*FJbp9U%:0L/bf\)1CLXfuubB,4"0Xl\:t %ZCZN5>/RZuo&@5JaKcV?5$L[hh*t`FVY)Yi`l4ug2e'k-gXI"Lg<2_@.W(`'%+(2$gU]37#blQoDX>*Krb^Q-N!o!Y3cBdE"2-WH %2*gT3911(3noaETn4$Xfa,YibjUBiCCXXp%&W`#@`;ic$7#Bob!&9721"R^8I/pZ)C^.1:N4?B*ZS0M(l?fIH4jCdLZ>CtN439(@ %@1+<'8^P]uf6T9C6^`jNg;MQ_QD#\1['^#&/M(eNP\V4^OW,?.6=$GI?;ZNB5>m=Q]0ngJ3 %SE9G6AK9a3f1G,32Y1aUbc0iB/Fcc)A!@KUou8>d2Hm)i;g3f;TWArmRrO1nfWa4:f1%R91rRIn+P&`m1Y4_J!(.rWi30P."`p'U %5//.>[qq&5UP0!5qD[8)>5P8X?=hk\%-p#bZ6a]+A$r;Y&l]jk\e[,d'mDYPp1gA@8M`?u3mo,Y^1u`_N6sB;ROKJIWC3J&s0Xr? %EcAa.UQc(^mE`5dF18-NV %ng>!Z@-b+Cs"q0q%XsZ@VfsW2Ifk/(=DTp:_QFX10aI/QCCK33lfBhc"8G_3"'\&OZOpCI_h_/b)"(Y_0kBiGg%cVsJhW-;E,T(\ %gh+oPR+Inpf^`HTgB3\J=0TMUL*e*\FdO.O>6=ZGil[rqLtRqQM#K+5Y[ee$NlgVX91mdQstNR7HBg'=+Z9/ha6#g0nQ5Y]J:IiU#k/ZiS`lM%trA'$H*s %[,I+TAobM?7Ra_`eF&sTc*kYR%FI.@P>;W=2s#MScI*J(N;dS'lTf4eW>5mbY%BAKDMjGc;oEBD6KA-GE3bo#G(%>=NFW8*fkZS" %WD?poD/K=,0"Ap4D,btM,';Y/,7eY6"c'Ogh:j1)]$WS,/NH'8YD&Sjpa4Z;rr1K5L9]FE2eMZ0[A:^->`t$d["PiFi$LO(@XoeG %pGL!.__jlqQGjV5Tki%gRSAJA8Tuj1$>NC6`Pj[5FU"`abp5?-l"=-5lA@krI[_gqjCddX*co3#TiYuseJM/Mf'64JL&^c)ZV\JB %$:Mn995X+l4H=bql;[&9e3TEPCGN>Hf"KIiM_8Woi4C=96%PuCoj==?#qOBS"q*Sd^Qq;&-b%pD2M7"#2Y]%VmEQQj0,AgN:q/I\ %CCsRYo$-`=0;L2^%MF/8iGo=@P1cd-LB'7ZV[D-SNOV^;jhcLb]OinACD?8 %mA+,#0a,cbj.30R2e!XOI%mV$3pp,M&-cgO17OdOU'+8.UbJS7a&,OD=(2sZf*3Ys'frK=`Rc5.BO,C,UhiCL"uRWK\8kLk$7!ZV %&)=uGL+k$IOY0hCNOr9t7#GXa!MX>1(Y!/'OE7ONf0$;32)\id#,jZKTSLa1GX4XN$:9]kn8+GZoU0J``oOe&+Y<34MQe6o25rL? %.EAk;X0KRQG!*.,@MXn30P(c7is]([&k(=Yp*/(cg,.f8kIEo+XbYC,QL6DTNhHf7o)(-*Fq:He41V+=pGL#baCF#FKiBi=(?=EA'?&N-mT_lF01[(Q'io+-M>-#^ %Lj<0-"];g\g%Zf]go\gT/*pk(R-`!Whh*"?EFT0%^QAaCgJo?*KTqIi/96>3]C$FZaN2Ug!VRjnNu3.ZPF-?9EWPor0]0gi*HqE] %mS07`ds3gGHVoID)p=i4E:3M,B#`M5?VB>SuAEFc3/dkQ-M`oCK68"gesJI(l#iOpPNGl/u!6M>%c!L!_hb2",uedNsK,2CM=r %P2T&tEFC>U5e\R_'c:1#fUK?UgW#QWTrA&88#4E?SVD'+D>RY<.J;)nfKkH2)^(9pa?/VZ^-hu3F9)PiAQ44T+KDS6>@Em//P@TA %k;@(C`C9IfV4te^C9_0O)r-ZPG;5Y%eU;475!+"g,qQ?5hP?pPXCXqE.B4bQ%Z!+.4e1MR^/V*L=S_E(^`V@Hhl92Q0a$!87?@g%l:AV.q!R?QS:9]6`)PLScsiEV7GBBd#Zff3tZ" %8(5RR$!umaKVmq8,uIa;)b1S>Y@%2cb[Ri;Y+jD*/FTQO9X_7fmguC6B\61hOOINb*TW+n_,K+![KBij% %bq<>lnk8#&,c>:*FlK7R8gY#@@7sk+%j]N;b %Ns=4i7<%XLL=aLeMb+Oe*\i/FYp#39T90pO>'hPSO/CSQT-59\OZ;*FqXtVA*YE:"!%kN(0f-9#1"P&U*a+og;lugW7GC3ZRfV)g %?YY3V66'kE/ZB41/rB?E+BHM:](%coa0OID4a\LkG^"iI>C(.m@J_C0Mn[*"eG;^"^^,d3h_*%N&n7dW&LR]u/XKV3nE#UY6%jZ)TebQ1jqIjSm'Urf*)Jed'B5 %]$I*^*1V/YKt"e4kNS\-@W,6$.li\J#Y^po';/9G&T\s0TSqiicIQ\FA6krs##+cre7Ad-5W<1\r)0=sGA"XS_[6pU@Kf"kU;(qD %k`G@42`k"`C*+"V@Mg=8jYM/+]LQK3TrUqZ]?X-!BKk %k`ZKt3e/$O%M)FP9=9RdPO%g'ddtmB4SDbp7W_g!.S-)1'Nj)6UHB/(.lKYmoZo4W,"1eKCm-(ui0e,R^#A,dTIn0DN7b]Z^I8j'!ge(L?W7ijjpc^aoNWtgV;;DHdS^X&VhW6ZEB1s!`0lD`:rKIs %E,Se)V=u1P-,dgt5A3JL=ZVY.?JB!uH,a@$dn.]n+Egi;/`B$OCnJS`@+kXOnfsp5#kgdHhU*!eELr\,*i\1,.c0UNpdEoNZ`n?81!P %j^,lFQG!d77Ri*02;7r5)>%(*eP*HqQG#:+PsMuH`%aVTYsp"t:e2&L*Q++6VIKf_0)?H#U44di\-\#t"_7nOYi9+n!2%^/EMk5k %17OSSDc9f5MVtcTkQ"K+JJ'2qlOp6A.^dtLH_i@YojC.Cin1QeP&RlKS5&oq@em]G4Ar:@+ihFoXa0ht(8cqD-)-1k&V[a^7?R(S %m3m7\#VgJGb%5r:2d*Rl7<.1u_#R>B0Q!tbZ:,6>ES9$uLuo\`))N:4FdNXF\!Bj3Kp3R:)-$:89[e]d5Bh&P+fZm6Gbg$tKWJf` %Gu<+?W;:Wo)8ASuZJP*YOumb;m/m#o6pX6&%0O0r(u/THgk7sLSW#X3n_E0U!HhelQR_++pA(.kc_Whp72g!O"V=`@/W!,mn-r0"a]2;;e";XW)VJ.TmX2*i+o %.b[hFr!4Gr:,Z*/oc+C(nkfJ)>f7ue:tD:cr*+g1=G*.")-e`gb#UEU!>Ztm'R1#O&`Mt5Rb`_c"2167'8=$3Ju$I#5V16j@*'6cb7dbI_F+&F>mh-3$[VX])\%Y:'jD=*-Bq2=//kIXOI4MH16c+B#Y^A.>=2nr[p?bV\DpK0o_e]iUCm5LZoIJEcc %0CSAuhRr[XrEk'PjpS`o=#^0F](:DU^R%+W#R`jAJ1DLm%=*T>9@dUkknsb6h6_+d<#c!f<4.L+h"4"!r[mLLO"!N+b;^-$->YN(N#Q:0?O5N9_co:0W@R7\"KH@@qZ"Y/>ph.1#1\42r0a990'M %o0S\*/[":ANuH/5?A;];?!>V$:AFG=@2$f:0SpaoiRS(Ue+ZNHk?OIXd!:gLJ/1qSAZ(hI7YV-5N=J %-J8U'#C5;q$TM&-&hCKD;Mp.+adk*QUS!GZ@GeGNkD3$&?nUcA#/u.kXq7'K2*@A>r#qUg>uikCXoe"h[HJ`#,8M:o=hjB.\8dfq %f36.j;`SC^C9i&chdsV`o:i2GV>L[oWQ#LRC.KD7C(f^0,`>%+L_d-*@LJG:X+g>5M:(:Te4La>(AIZQ0f;&Ohn#MsD*j=sLGU6f2Db4lDlCE@QQFa<3%e5i3tFre*6d\VC!NoNlEmPYH;GZ2r2G$#XQc %DkEYaJ_#QCWe#,/+MHt+."uZ]DAl4g%,.]LDD73OoR`H502r"!Aj/^Q_E3RF+W[dNP4W9sHdlR7-sABDA`,8M_$$[D#FHYDSg7H7 %V'3L:4Qj0_qF"i_fPO8&_[`i"Y;KF#>D&Fa!h`&c;$@d,FSDON;%)kPd#^mInQZY,&,87:$"O,,hFIjNWQRstGk!*XN,Nrs&'('1 %7'f&E1sLbQEeDDQZ,&;<2r]M:\Z&(WRI)Qp%QjTe=lj[Bi;#kmQP*F5d6thd%Nr27?$7-KhIIi`Xgo9G$Dak]!l4od %k+JVGM8Bg_d0(^SWIB`7j4_O.kDC&h4FTn64KGm\#+BLr)pC*+9mBe&TR@lAA)2L?Y1`*Sb\JU=kDjc0ie0=R*2GYSHEKqWk%Z;V %"MI)6O1GdZ/4K[\HnEaV'a%C&!j$t?HIg"`o3:KW*gVX.4K"V$h4[&JTPqM)(>28_i>]f:`aG<\RO`>Yj!e%oM]R`XVG&seA^JYO %mM(t&7*>s9iir>$aa[u9TaWk>FfGJ27#.qH.:*c>CV%<6SmMkT.F/U@&$qXrg!AYLM%`WPcd5gA,'KL8)4?to;-u(+NtEtsJb*%S %bPjq"qK$Z@@q[k>]'Kn6YJ7e6[@\rTrNd2_-3iWZ8&R/35^e&MQ1l^eC?O]LfsX5$[MC'3Gd(3>S]^6A^j5UCI!LiR.(lfhi)GNR_ND?IjIh@?bCYP% %c\p\8&^"'6n'q[X_M`@T2m8s;SNouK%+(EV":6K`^_]k+"n\uW(m8$r#faaZre*t>\8:"YOL[JCja+$RdE`HFSNJ*;oP:83\CASY %%)YG;a>ril1*n<*YL<.NT=@6#d,8[u"$Cc%BTtK)PBD,,lq!Lq'dY!b+^$T&i\1bego?X]f5^TNaQ[Dk'1`4#i0YaG85YRnljRXK %:=WZ/J+=C1G,k=dO`bc,o>TuJZM;m`.2.N)JY$1cKUSDW:qI:EViTGA_EHk;>'&[&Q2Cn7J< %Ue'Jn!RCMGlpi-VN67C^_Xpm"g-@ZL3qI/&\IZVV`rgOa/OC0L.BYXbSM0Y:2r1U0r)a&D4.+a5(KL_j;`INGZZ$N@P8U$Z3ZQZ5 %L77%0)'m`?>Na9b5#f-LVa835oH%!,9#`%!r;-@7q,u8U=jBpI>k$a+>aVA=,]iXdPBYu]WN8-KUrM$P\9W)LL])qJi5urGr?L4? %ic=Q7fSc%CaD#[J8b^*tYa[!t:Sh?o3p[k1cUd1,DtbH!W$'Qs_j?b:GB*@f3_$K,J@-&dPZ&:?3;&nXp]9(^r9B!Z0?o[pWkX+r*=aE?Nm^ %eQ3#-'T;aeiU1g6KjtE<6l\4t*%snLE>48PPf)u.)U0Em_E=JY54XEiU_j)DQZKXB<+PQcpH:lcB %q21`hM[JO"o+?I=a+VM,5B_+\^ZO@NQg,W:(1MHZ7S,Nl%_HRfefdK*`,jru\SeuqgL:m#;8K$eKu,2$&a^]-%I$@'JKFcp%KG[E %:_hr[[ZFTD*Gi_^gj33j^7Zc>Quc,>Zd#nPoiZ9`pL0hE%X)S\]"uK7ko@M?%D2G&KF_Sp)_%SW58dAN(6PO;'4K&Pi^58KR&H*D %@eQ=:'YMoRihg;DqB@-',tVCIqg&iSJMr+]CaDhCm)RmhLCPiU %^)L6*6AQ05qM7ZCAtS?]I7k(n1el0%ZJC4t4FI@mn5@V4.u6%r;*g0hE^Q/lMNSA1ls:MT-88^_*ObOMpHbZC\MJ3S9?8pOq]Ka> %k2PI8G'5ueIYXIW3Wrm0m-GgKl)2RkIbF0*5L"r!#IF&DLj:o=,,&OBd*_#LqO$r\kPH5Q$6\BGM19Id;<\\VT"(370At9k_QPkEiCS-G!J6(q0 %55$12e\YUO#eo5N>%1qY\e(&-l))@&+L&9Aq?D:2g/6e%gWh*UKLsst;d%\7m'@XbB?m%W7HKXlV;2`f7%X+l4Pank1Yi4pZPKXF %a2l/+"+W5hD_snH]eKkd](s'OA^\QY]^r$M2?1gfajC14X#Ild96Ygf$^e7ScP)6=rGEg8$?cp;W`e^eTC8" %'be?F*%"VH"44J70=`-j?Pjn7,RgB>YlqltAP'cNU9YC7-`EZWU(`gVr4<@n!1^Ts0m_qqURf/ggfJZ&C>$`\c'SVM+.n'1# %PLXAtLa)7t2YFu2?Usa\i9;!(&m2i#!K*AYVi+NFEL@,c/OU*RlGe(ak=]9-6(I(DeH$Qn7B,\I"SO?SL"*L#_=o4q8TOL3cX(=b %c;Y@mi18-?#QjdONGEg966(gaUfK_Snm7h'f!9I?K36o'[c`"#I@()]-]m7@k49F\&0%Zn2\r4ui%o!@Q4VU?dfFt>HT_H`Ai"h\ %@TauXgJ,b.Nl>:j,5BfM\3nJ'mLJq4D9G/V4>%54MAO`EG@nYcV()s,*li]9:npo7?`(hj\7HT&5!do(S %_M)JdD9qr!_](%Z/fm#A7ld-3A""*]T=0%nE2XNPdf-)T6,'EoHK654Y%Ou:FtkbM`jR1&DKh,R:$@>eU(fb;D-EA;Vaaq!l*V`s %WZ1Kt`OthZp,^627fM[05_f"Y41]]g%pt+mJJJ1gYSVK7$)r#Z^7C?_]Y#,Z%a[IGqj9nd(Gg=*,I!@\X8$[Z"G5eAl`.VoI#@'> %YY0b'R5c2J8S%7"2C4E$g:;4@_plf4.ldSchNDq@boQ30c*3A+JuXDC.C:3^:QLB$J-/_?d>L>A#2i%.gX-]eCs/Ca=(OlS,jA@?k$F%^]`k92!)m:N-+:gV[[8%VZ:fN>qE/dMdlHX)'p?.]Q'QpL(isT3`6:5Tp^VY %!8_j,(^71jkeN1XAMp+4,Zo(EJXh<@)+J\NP"[#S+agfW2',uOpa[F-J!0$_phn*`6'sg3*6O^::*-R,:3PtQW6X6lm%G[89j\qq %5]m7@+H.djbD_*^eq>P##RYiT`mPl.UEb7_Mh_0NmS07?=M),f %^,78;r5El"'%o^s0S/orA[46$6KYdK9+u51"Jh>'>]t[,?Ed$ug.O(-9>un+@_mp%W4?%5"@EJ>4,g6 %'I*)[S!@PKE.H0h*mBet!Gqcm/%,[;7MnX$BHb^fj*NG2 %gKqEGS`)33[h>$_b+O\#4LO=+I;+]^>>9Wf"rt*Ueq5OUo1,h$"Vq]P[ff'I\%ZUdhXV0_R[n_1o(?_de,)]obfSu/l_Y&b0Gdh= %>5dK72:X(/6_Fj+F&9!kq_^m'PZ;4mkYAj<[ii.R1*V0Yf*b0f)lFj/VsPBJH*t^TB\Ss(>m]iTcds-"_0=JLhXI)tkm4!YX/08N %3S/HPL$7oN,3&_k%1K[8jS%kL)4$<`JpM-Pg<>^=FHdCI5GdUpgIcu/+\!5G0YsV33oLe_2Jh`JNn;i&(o&?#^?YciUL)/PQO5RF %g"Shi[;YXS!L;:1W)3=Yjs&`P`>&+R+rZ;VMa]pqVG]GI^Y)$'K;3I8,ZZ^b;25jrkP%YcWXLj*aolUTm>8\kXe:rgP% %-W>CLL]f#!!icc#Mg0HL/lAr0Q[:qsaT\Zn6UWJtO"A?,+I %+oIF*T9(G4Qr+jrFBG=>4@6#%KBoR@>b2&Ii=4-,]nfnWQQ8Pb]Tjh#\Y?)Nm]+1'q=W3Nt@X6j`@md[$#n<.m1qhPPl:sk(MRr?Y#%[gABA.q2a\gs#8lX41):i3E5!%blar!k&]Z'S:2 %(tkI?XU9[C:UNI8]E8>k7P%F;:0.?b?C&K7QK0LVKJ$U&7[gaGdA92t`8(qM,W;Yo8?<\k\K\?7b^A;G8s7Ds/+2s9q6F=o3-[E' %.--^o.C_+%208@UNT:N\iEMF2NCH@?YYe+YG^+gqY=<]*j5G80,6J.hE[!RY]6;b=3BTUbpsEoGQFpLk&/,Ell>T\2Oql*PQDPc> %ZN,-pZ4;2[-soI6nt^8]pdna^,I2K31k`+IgUe2U)0'smg,.L!B5IL<>44qK?T0pGL=]T&5*+%1Q$EJ"f?Ti+;k0+I-WYAGZ\5W,@O#Qd+BFX(OZY#i?VVXPGmMX.jLRi %o4]T58j*kK9[C$Z1h@L33WON+15/'R9%cj[%^J.7RA)%N+tGsT8t7F@a6?SgW^K`=$_.ki;R<`mf-Cl^eHOZ)G,88>K1[?JBC-9" %'C;Xa5A34\]*EHP>0lP=A9XPiqm+^)=H\&7VA/ERm0M!6TY72t)B=;&g]3 %C4sl7l7;6maQA-21Nt1n(sTED?]2F%&S#TWHh@B3rS6WdYZ_)qh`heljGpBa_c[f#-R2DZGD.5B)BBb;87G2eS^ie'!g5A$DQkj3 %O[fS=XmiX*q;%&W-1BH&IRYV=,VI5*,RrSh[';VU9lmc]7[4R0O'XE'1?,ag;i&6$;Ks=a9NKZ>pG0(J)[N,L8"]iOI0A7<2HL^I %QN92cMO4En"](58cME9G@FKEN?f3n]GP0I98>UU)H;M`,Cn$#p';d&BT2Tfnjo2It[tK7[qmBRUHlB7L.2oOuZ^\;Z!31At>rpnn)M5=8;-`#A9oP:`1O7hS(&iB9;)=WjgYG%p),!'M5.>8ZtJ) %3W"SIB+Ba^f@DE.d"c=hcq<@*XKJ/K\@H$u&um0iTZ_4-G7*&MH37d('_@<8?!PU5Nc!1r`^ZB1d0@FmWkUbuZAcD^%EgIgA6-M& %X]m2]:WffS6[>A]Af"Crm8di7jF&Y:U85ogrp;e@`Op:Xf4,I3bMojHp\)u:f`su9fXjE8.r$.hW5Xno<7j:p4R,A_0SOa]rqqbP %3l8Bf)l$AK[-X1uef"]thhjG']`AD_NXVQm@p+HJ:+"qbMp=j="+&2`?6f_j*4`C1C)6"U$m@MXD@M9W0mG#a2R3/LThVJYdBJss %Q1dLWFFjMS_>^8>],"322Q;<[eEk9^dRIY#gBaK/ObMJ0Jh!JL"VAR+d+"7fT-r)50UfCX.=lEM\=,;27*=YlGRa3H+3M[k[J$GI %774>h&_T+@Qo`''qt098<)37pa[6m>XC8RtWd@dRWJ`(`@0r#WJKr>Ai7U.>3EL_H)\Jic+!JIJDUfY5o1#f8T^u#2m4>6qqdNXX %r>HBj%7I"dCAj6RW_#u/VEHC\\*P[ljq/8dH*;9/g:ee69(e$t)P_K]fmj-lX>#D[0U_q!fqL5%jB:38+Pdu@mU?oF+-W)N]Go?+ %88$ko`(,K`=)btM%&-Ke/-;][[Duf(n2@5B*FK1_A#NJ%Gr)/:QHiu-*0C?V5jb5Ek!L/X!ol=f)9O$(_R>Y1Od[V!YOE#jeuh@$ %a0CW\Ys^,d:Uji8LHo/^G/D`f@fo8=@02j.A2?339:k_uUKVYu657"Z'hgcp02".@6=JR^X..+N0JLW#@J9Qiib2&$pXY_]J[>/Q %?qkg"AFsV'\JIHDNT2DKBHSu;c`Q-;:F:FL6YBdR\I6s4A:j]t?)BUmBT/oOfYV_m_e@n%)doGXe*E3NS=,:h#ekI) %+P[tn'Vqir,VaQfHZp;\'L0sH0dAJbh.bDX#F?>dXkbk-`"Zh\1uTr0X:Y'*j?mh8,arKs%Z33Y5-_>@7.\;W*A\*ZLsJ5:QBE>- %D[S+%QlWHYYs"Pb2H)7gBZ,<4'FFg3FLE+g7lSquC"sF7C53+,/&p_lfod=H)QuH0%UuAgrmEHbXDccB_[pf1`fLQo5aiKsG_MdJ %^dRm6b,H%kK46TR]G?X#hW$M[NC6VA'pp.U'rJ^u(f:jJ-hOG!+d=>!K5>JAMl*>S9XF@d/ebA$FC.cu8/WO+d5M]8DmC?ZM9S\Y %"#neQ[OmNocGXl`87&9ZQUa,`&5O:_g"Z-[RXu72B#:VY+L0#$ZX0/Q?.Q**i4M*Mr4UVk=69LpKVH`U9nbABd:jP0%M08:9j*n6 %O6DZ8`mMJ/#LfDKT>8"Ll(!o,@24e\KeO]NTXYBmROa`1V$9T'WWut,G>m]?WF2.p$AD9l4,alK=-@D3=m;d'9$>EHeol#sYheZ` %%],pnc+ILfM47$e3kq#$kJO;HD[7dd!V7o_,^*pELV*c44k[<>mJ/Vi++rii,Yuu#jacYUlGXagL-Q-P %cf=j>'YSAZ]!2EaPT'unYAsMIBdqooD\1"ldYslnj'197`gXeB]\8"18*^ZL>/eA1,.K>[Omfr_1_PEe %"F;"57Z/CRFSXR6Rh]5*VLuj1l1bjAAZ'/".kB1ac^t6BML&GH5o5'kl`+9p@XV %0#=g8?!SBFH+&Lli"tM-?*n>7H+l!$"5;nrh([P,6tEh=&+`CN3-oo[Z\1==>GMb<]qh0'eI,s<:n=H;oAoU+Uo6qs#g);8fEUmN %XU]KX`4Y5sfUTk6AHT0c-3.Frl'UP!Zl*0@g,M3GlAmh'ZUK#I;=>\2pg[;GPe$\DEVB2/P=R&$"flbK`D-1gG&0ZOlSs.WK^:'N %6=l94lcs7uEI5LqW2sXYM'7$8E7ocj^BSs/G!PbU1rCR0!UX-.%2&/^@uoZ1:/kKh.@EP2&j*4<+hE7?$\R/j2;g>e,PhBm!J82o %0ROoOJ_)g91(E(g=EfVZlM(T@60"XE>T:<&B;9T2QkU0,,!p2@W'8!tSn0.`,`*!r-HciG5]cu]H!c2X`SL%bYL.e*le]s8@'J(*D59N;\7^Od5fI%Gn'=.cBFg^2G.@RN-hF'SI)i'8Rs\Q7B[[Ej=!?W]MOX!I1AU;5,c^fn^YKSB;.EndEk:8 %k]u%=SZ4r0FeC?8O];p\V?>gg=nIaI[uGSC2OJT+0_F:/%YRq5n#JBNCt4aHU'"+(:RKe+J6($+cWkQKoiaX'C+DUrY\ulj?J?OB %j-+hf>M$qmBbIUh]@,YN>P9s*&Wo!u![q+;h4:pN!u1+I"%(i[>A[m`a^)fi_bEjk\rT=US%(@N/Qu=dRn6#'fL+nZ&[Q7)D$9=-*ue]Yp1+G]$X2F#OeKj4Lnn^,R.,J>p;;5W8rUUE9jQU1&"cAJpm+@-/1U\8b-6Pak"%nLGuQVbfe %[$:Xs+GN=(%B1B8&mk^>U87mp!M\;n(^h8_4hIU?Gan?l&^Xnd+l?Q1V)fYi&'qKc82e5Ih;-^:00/@g'dn$q(X_d=qI""We#d]l %.^_)Ep"XM#F_,g?3jnOuqMnSd?acA`+\sNr*\]UcM>KhNrV=k6:1:d6OpX\HjKoet5H6U5YfU]ZN2@;/'=Kine<^otZcgsi&W!gF*hYZ2kKS$(PWm/n85c.h'M1naQuhCX7,!Wp"=rrUFs=LAIdOCGFhldTSA %U9/[2:bVIn+B0Y^Q9Z\5]1fWjD4e6k>D[<6mr=NC7cEL.C_L++\ek2r-4m!iZ(R@i2c/^>eh".(+4NVe)ZZ<&>KsK`_eKZPHSke< %(4;^h2?t6?Uc#bi0FirT2'ZA'.mB=?cUe[N^Mu7A`!g%pb5";BnKXfEF]Z?n9R&4"&$p^@?R-,)$@Bq9YDWrHq %:Q^e]2OmOKP%8p@e9obCgXX/5@3"rgjs/#4aqRsn+-ItlKfhiB_Z'A$?++>5`i9;NHGViVNalV;N&,a7pX8#9d;>7#gVFfRPZ]>M %%q&[T%4'(nWVXFMR(Qq82E#f6 %[?BQ:\]Olqffgu4]V&Q1r)Yr=l4"W`]+^jr& %#K1Xi+Z:[\KKODaHAYCT?mjNoXD5.F6ooRJgI`,e)e)-O*[N*'Npmh;$R9N_4]J(3qgA$"3RMS.E%gKoZibRTOm,"I)ti[Wnp2G, %/X&LBb6C.rVhtn#'>:-'].nO8c$h4EN!ol&6&rtDs^YaH%.i>A %/+,'cmYILF#Wr$`=I2K.m['S,>^(3rYd_qI@&!BbR4.[rc7?>O@@mbS)4XEcER9'LAC&"GOF,-S#H;hR=HpnlXc.HZ/h#V3!iVkU %:M,pWh,,Gnj!pM_joib/b=N>/At!aPt&i_L+FJQV+aCmKb9"Q71o*(.mS&@%p2rI>U2U?5urHq&3?r.^&ZU %2^:>]G58Mqg8]cPp$ai'fbc5,4K%NsFtn7T#7+PYUYls8Kh64UJ4?Mg%3EYW258Sr-Q:[MAW2^Z[[PnD)V!\k4g4oZ72T0AdEDq$ %X^LXXeH&9SkO3,mP=Fo&#F@/*8%gSaK)Xe.ggL\b_J>7"TIT+pV!JR=_5jtS[`oCc$3Bel+elT=![hRdpU]UO<$AU@YR.Y2D.PiH %:,er`.j3.]m)Nst=)F![RIqr[)3rtiU:<&@`#`2ZV&s#GE\KntaXFP<\=+#A@sYH[e%mTjNPkiep6?KuZ_02im+<.0]3=X%%tYeL %ahN[m,gVq$H(l,Af>OUup1,=L/!iO*9kr`l4a2Kd,MCgo-;#f2'fd:`]P%P9iA'NVnC"TlJLPNjgWg/:o-e?j5A$Ca-*j[JgpG6goI%)/r0c`iGPsK`YHKl&`atgH9 %A>$i4CH3[_31]28g:58Z1. %:l0/=l,"Q./`5W*69>3gJEU,q$oaJo$k'q^.)^6^&`A%/FQH(W%j;EKMfH_+Fm;El!X8=Nq%AK*bi=sf:l63*_')'sk\4Y@UJBM0 %Jtca^^H@,O9P)DrF5`R(3_"i@9jS+4h?Nmc,opHNl2g)2K0rB(I7J4p&M5<[Lob'G#Mc';3OA8,/Z.N5(,ZK>U'n7a/!K-%2d:l$ %D$csWHY7U3hLPrZ$1+1Z_6<&FfUi#Nj$n=,^%aR:%O %fn(Nj?ilppV:H6nNYV*#!AQlefTug]6cQ# %oI3H!N."nRH+4Y:R$6?^g\8eE`]Q@:"@YU75X,Bh(n](O(s5=0l151,40OZ^3^M,6Ip>@j7$bW07^XA1O0J.b$1T:IFTh2i8f/^@ %U?ndO4'`'[2.0pM4P3Xc7!D&@/'jeQmcm%YlrJ8e1:#j+kM8F[+*tGF+4($75NPZF%C:q@K$]3I>IF['DN;Icm290\@Et4%=&U %cI]V26!2e/rp*<+.u-K20r'dY'OIFo$.:*,BN.pkm/F5aIjl`Q.i9/O]"ClsU['KlGQh8)+:&o/\AB3kELqe!3(D6*9[aBbik_O\ %G1iQs2u((c0t2cr;Arl$)%Op6dr#n[PS"=#R#Ig/e*^a8BKS9Ldl?Qk"^MU:5N"U>8Ct3ln\QFY0K%0/M&(Lui^T:FE4%#am\`*G %?&;nKURSMu!rIp2[m0OQGPM>oI6T\*!HtXX*)86m=RPdh'0P5fGj12,*(`D\r6*8iJ$4mb4jN`.E5U/:-A)f6W.FOa$_=sFKW:P? %)hSVk85<"(lkGmf9Z%PG40FE%=?c3HL;_,q#KU/K_`O]$d!:(I`^$OUKeWUKjdEPKM]S6AUcp>CkH%rEGV!P(h]GC%Z5e %>hnR$Y_gRhhHL3H %KbBo_\lKRjd)l6V&F@?$(T4=*)\s; %&:gllUdZumKd:34,%DKk8e)ONSP?lGp;tC2Ji=OeMb&p>62QF&9&AT`C%rW3nNHaNFgr6&!r?$`a90'7#A"#/WR.VVaEOW"'sCW %KFGUcG'BFmr-QCIZC,(bnm^Ya[5iTR<:o$Z63QTd@O(A1p%"T^263g4WpE;B9t30gX%X9:P=7FSXE&/qm&'(#)?#Z"Wo?2S=jPnF_UKrQ %ZO4M17+t[3WrjnYWZKqsf6Hh*ZXY`O%c=976A5\H9Ht54!\Tf,V9u8&k<$PbmFU"!7(?"uEl^,75@CliJ;k06Mo])[$p0@;aYPd3T6dQ;3CXPRg=N!:U]Vj;6oppuEY(.D.[HNuY#J %F?J)K1[h4%o)Y"=5c83[I&Ob`Jn-No)!8Bl8_@_=$CqTn1q6SfI7hm=UjbSp:XLuncaN0P(=^qn\53k"XhgT*/(_2p-C_>i-BcTA.HKXhD]?)JSouV %i5Q_NY4s^Y0%.>][c87`XcSiDM3=1D-"E^=b&]SC.99J5?J52nD2#.In[Lu(4N0B9Q@bST>/XAp!Cdk+.Ko_1jUP\jc;+Q9"#7"r %\gEMK?OVB`G*c4_TTR]m5,lQB^?P:6Uu_$Zo>mQN2:cAiMJplOrN#XZOhJMQio6Y[l1F6TOZh@&e,*XN`9tnPK]WFT.33`>0Mbd4 %C:\CQOsO`Z6&_D$U%_;=lXa!?d=]-EGt,u8jPX7rf!fHaR`U!,SX72M$JWi8F>k"FB>_4D.>'C+^DcPc\6Wu^O.'?c`le,X&-lMY %SeU4$@L8,^SK&nZT"kGYC,K,RDUG]*2@?_"'P/q:>W1Hq('^G\Y_35h"aa:a/O\HBnQhLu:7(1ImPZMS7Ceo;b63>]1:Jc0*2h?r %4riC-)b!5$p:7b6hi7!B6.T6d^.pWQ2:h+@q@C_63X%e[eYqiFIjE:CLl'k(L?]o7gq_] %IV<<+H&jrLC_c!ulR%Ym"kPQWp?-"pSFrc<:A!d"HYK_%Y\o(af,JH)@lslRKP[W[;'curD-Un&"b2:hpT\5+)=bccMpS?bfS5S\ %2"I_SBp$%n;udp&iYnnU;^1%VaR##7Hb$ZAC:ZlnSg5dLjheabc3u%0#Qj@[gj#;^hi77_"(ajW$1rnm@eY,+e`OYBLsbN!ZUDOV %jS%8uF6hj5hsErb3I:"6h^H)mKKKeGEH>Sb9UV-sMro-6<#H-@Unb@<'?GStR,QA7ISuPfoCRK2jl!CQRSPPh_"+c5o8b3QC`.@*R`I`9Lm_UI<;LZGYu3J`UkKDt%\g=I&]K %SKreR#YC'IL/6LG4="0lr12'3U^34!=-g^6Nd[oL2F*sG5ns[OiM>ZG7%KE-9DJ%SQ"/S3.mog]m,h94.D'R%OHi:kVMJ1r)kbTq %LhF8:SNa6e/&aB^R*qT9-&UG?ZDrUn@+j08Oq^$HjsR+Zgd3YSqgQ[8[pEY6oOP6a#9DnLR$Kq7c`"eqR4?/IX)<1'=*cEq&C`TVJ9R1#MJc$+koB\#l43`N&gBZn#*IbV!=I&OPC%3i\-rqi-lLEqZ5Q-GVE5!Xm\0/1D1#Nd[0a4J.Otk4`?&GgH9"MCUJ_LuI\%S/V`A^5 %A]hhVV&e7Z%$@*b"1n#-pRC5jfU`4!p5Fc=E?,71p!0QE\@tU+X@hs6HDjG(QDQ[32qI?@O`=]\`-g]bdql11bFXrRYlSrQ\;XWdYLrjj`,>r>JJ5foO^;fD'9W:_Y=.]B&cs'H0F\8b(@]ef*lU_j#X_]r*ej69] %0sk-mRfT,Fo0W05kLq,1V/t$%X-XBD7nAmfR2(6S!`f6_?C@pg<5uGK#H6bJ,1Ti=-(WF'aq_B&D0q161d#8b@'N>3@]#hbe$bte %Se4C"^VT)kJc3],JZp9iP%NUl6d;b"8e/'E7F]G:.0G<;2:s1KKXO>S?^uMSg5=CU;k7b$FgbU.0H)Mr]ar\udtlZQH4+Q!'G%a> %$8Y!A#CE.)2R_6Wcjj6P_csjr5s;khM+['4R[JI[FnpG=pc.4djih#9hYT[t"Z1EF:Q.SRc.Q*S/IC-tDc;q3IBiX0t_J,R9KUodJ67eM>U"FNZ!T %2WRUL,,6:_4&O'm4Io7+AL:E>9SA<2kPgc>$81B8^U'm$lBk0iTUHS'6&EDkR+@g*X2O[.VrMM,M2B](7$OG*mY,%^TgjuF8NUBt %>]^X'3/j)m*=Y3N@<3-<\*<>DdN6'810F$ZCr+L\p'HEdYt=.5d)Q!5H$e:O9:"p(lj<)AoH++0i>u!JB1fq[[XZqC6\Z#l,RcsU %1eEN.c3P6t+mA=,A$(QPFa@\+$J)%.(nbM9S_R4J=deS#,1bE#6VFS.&"u'iCK)<]TIFuC(knfJ+ndFOU-S*9"1SgB4BV93m7mL: %$blFf+?7OA.8-uA!'T?./KNR6R4bnTlWsI*[7=q]*a=Ep.p]M)^Y:&;W6(Co<*oMdPBF<*H-h@5MuMRD"*pr[X6We7l2fW/aIr*- %,+!.68p[QWnaWJf6C3Sc!g_<]6C012Lh']Q3Xl8g9WGoE-+oeglobJVkIuWk.<=H^Bj)^G5)"(Aj5qhL`mFT7jXVTTn#DqSl\;P+ %j&Q[ea%uV8C_;RWjS?hAalgJ20.k_W<(Ik!p %fo&XE`c,D`E.M;9"Ll)LIP%PO-R%`gDLSXpZd2?jMqE;6=l(3FT!=bcF@TlQ;>oSP?+4]#k-c>\!q5(hgt(!qo87Dn4co-m$39L5 %/rp4=]49Mp<>>(CKOcr^#,B_rVtX2cToKff=-WLWr[q5>Z->j%\cGA]))!eqn7j8>5bpiik-9@($p@`e$H%_/Ks\&<4UKOl;O#\` %PZY+X/q1D=LdA53oSs]s+O"7o9-C3k_8r3?c0<"#3.QO>/KE0#648ik056r&YD.UgoeP(7Hg=M@GA*:F^s(Ulc#ec:nR[`Qql,4M %p"oAm5"cn,D0,`=\O?a2p$J4B#-J.JfD>AJ<9=3p._YO#*#j="II#lj0kJ.q7Nh$KmZHJu9s[*^i" %Xp4M(:Wj4leZf25NYB]uhhWJN>s)e!+,jC37Y]cr=RGA)Ds"JBT\>[='08o@0/6PqSK`5\DM3THet2O)cu;lB%l>#bifkreBPo'>atH/m3G'HXm8l.Fu8G`#DKNe %IKis%SfA6tN.QM:'MZZeqE59._*?a]3pR!J1leNW`Oh&.>$9qBBX)o!gPqAu6.;6P81]Ol\QQG_'qh/4BaQAZ %Tm+i$WT&=0Ga;MCG_.2_T^##8;gUU99+@3$gN;Q6P4Zp#'],g2`aR`ul>$BE/QI(&FP5WP69"%l,&CJ83K31X]E,8[3F;Se0"SL;,r@!'&b&^m-k*<)BRh+J#n:V#WeQUR8.?c9k)E:@pk*3e*$q%uD&S#0 %`n(:]K?>=;8V+LL>GgER@olb'HEm9bj^,ptL/hC;P0KYZQ#pdI0A"aWe/Y8t?\<@YK2nfd(^!nm:((qi3ndfp8-=\0fPcqM-&'o@ %&,Jdf+[4M1]m6(LA?N9c(R%Dsf@A3[P(L0n6_Y$N41&XgK'NpWE*ZYAC0cQs.-_Ks/W6n<0%s#l&U2#$YF/>W2CTEKcupl4m]fuE %%d#_aEcA[%O]R<,`&"M!465\9Muf0JC2B3!!LpQoLB<[Nq46?bA1I3&W,,)LZ-JFNmt"pOGT`@\d8La/Ijshs'`?<: %ZOTFt5ml1o5.K=76X"8YcS9erBjAWUF'%8a<"Aeo+oa9,:RPGPBf#YLbq#me"r%XJXfgEf02=\&c'C,'k,a$lI*7B')_;D`X:V-F6Ui.lQY!$_mEN%5dkYKmlo_&!!WOS?s7JUu?k%bbtcKA/_:X[cfB\*ia>V",V. %7!Q78kQM!R@#PHTm^P;!HC6)\Id&^^@I4*h9DM>P6(tYH>#bPM> %q"!FRX:X_fJL6M5ctkR_J7"muq=2Y+8\DLK4''DK9ng7(%(a>uP`'EeQc4,DPFH==`X^K1qn_oN4cNSPgl>Hq.oFY:,V^E76Fh@JfHq@S`2'6,*f=/fki"nI^+@-kh,rc$N$t5aLb$o`+gk?g:rM#9J:l5g>ER46Rn5;c*DfDm %nP#oqf8V)FhMb!TY7?B(VJu.K!Wa4e.a+d>EHpm#5EQXC)nO(TI]_l\4^.%!*&,$S(\a*$Q5uCYUh1N?;jf,HTE$?o^E)g\9uu_2 %'mdi2h7[_G0'6%4P %\Jqd[N,"W5UWpDenWN=cK,]%2_dIa.5XHDQMW&-Er'?-TK#:4ZUtq4$2s>)LZBTI&B%1DQ1uMfSGeRYTf%lq23BL,W7aaZKf=eWUrP-19Dp".@T*Dg_JQan*(7-:& %H-oV;^"/00p9gCRM9WlJqtAHOPXnQ-DO@r".^D"JMkTInC*G\FM0K9^35A)p/I^;Gp(99>>Peq-72iap1I1[sA_\S0?Tg]J#?cV;,+\n$k\BVY^"acp/k-)VN*0mX99Gp>$LB %\(.mh']S@].U,"1EXW%0rp#PQ=r>sRRWbJGS@(DI8Z:V_1'_j@=q4SI%F)oecrDf;NO04ahB+TCGb6ghti\$bfEpXA+M4S@rZnV`)@VIqT(3Rde!oSF.h-"<2oX-u;[t=V*umOd %oXhDa7T0n>$)WBIh`>I3o*hJEOboi&>;)C&F3i#1F31=10p"D%g?$2'S`-g@-lA^ %E_'JMdEa:A3:+$&!&Y-I@3p&9-e.@`],[0]/J(UDD7QFlQCeji4\^Adeo%>=hJZ+RN:HE]F%CcgU^gW$B8KZa>97r0/U$CHZl.N> %>8NNn1"9@Nq!EH55]uu8J#1:86m.fB2YLc*1eV,ThDL\cPfooCP#/Dk%]\CF0UQXo's,bIL#O"kqDbPEG;OXh2\$t5fi0RSbp^+H/WurnQ*S-;eT>E# %l(Xm%Ec__30kcb#8u`q,V@eKNH)mI5&^\;O3",bkXUS6!(k8!+rJ#(6^Pp73=!T4;SfX>/.3^?>/]bS'ZfWZ`5EF&*P'8CB'!&l? %#c2pf"p*Ms,shQ7![C"&NiDsNXUhFua&W4Y]ZF#`!AAo5!C7C&aQ[p_2+K"]L-lZIrGLa;&?j:9i%V$42\ZXc:;_,G;=lO,^h'12 %&"9[FF7,C;nY<$]PlRaPad/+Jm\j##CtnE8\Q_B*_US!+ELKf7Y^>HEhq7\5A&nJWXE7*Ta5ZeuTql=9du-;[I5YuUk`)6_WXeP9 %2r=_R_&SCk\S7QUF$-Kml.+*#"*D[6U.uZUNBUjY83\*EHMNeA0hE:a5GlH$/HBVe9(&?&\E2h)`k$NO82K,c\(H4=+HVi %rsF6moOmbkKC"G'-ZC:PV&C!l-9&>Z,s\\$)C,QWnU6M4;"TT=T0+]iSN\u60VBU_qGN6qTX%ej@2"aiVd]BMeU2/D@2[i2RRbrG %X<@^K%4dRKZ>Se;Wiq`>q0jAh%lpDM`,]GV%qRH$fP2UoK;VN?eF&ArQ;W%nhL+rX^^T5KDVb,;#F^^*cU=2jUg&I3K%fF.F-f5" %nd(5+(,r-_K`e:UF\.6od%R\Pf1Z&fI_()[o$1,9MmkcHX,F^(>J2?YUF("MNk%VJ_JhHaJN8/WqQ7I/OgPeSNMg4@U:]517+(pD %Kn:<=/F*QdO-o-4ABH*L)^5%`GlYQ?$sT"4'*W#9/knl%Z?@S\&.,uqi,_##%C%bJLftW;EgoFiTjf_QYmA_B2E$+MCZlr%B`kIY %m7#7rML[M:6iAjL)a0l)1t-4b+&$N/p,\QA/VXm'0_16q"DA-cuOb[UZH&^Rkc,*q+3UD9]_A %iaC([p"U=+Y@ZulQn^*mWG]B"nVrS=rAX\#A./fh:hpG5PiDT/s+iTh6WMYLJU/Q'^C/SM%3c-&MG4du2^fWJ*J(;d[q.3qnuKe& %55tIT\)(@sBK7NtW]9k+/%LOdH#5_gN6tjOGPl7NY#CMM6%@I[7`0!*o6pqU2,H-+j1<'$.5mE&!Ut;:e[r88`VfUQM!sjlQp/Qr %6:tF"K.+O;6Ieu<_QVeoonojKnn@`$gdP64P1b'O&u[GM76e%hD0msF5DFKm9k!5YUM %D`T6)AZ)1i\"n2T.@N'u$SYj0'RY52^LqFT^m*d`b7CG>](0aiC7E4n:hUago>fiLNCXGm(^.mZn)E^=FD'_/`"k[QcVRN)DUWf9 %]sjS".48n+/%;MEp?^WYhDKCAVBoc';fqtPl;$J.%k4k^VUWA,!+=]&G8$=u6*e1>kW/KW<]Y0t@;rV__dGC!9UX(-gru5n7@p%B %QA%U-qWZ&7`Ehijdk:Ikoq-$aMQ;@6VO$L'&?#!WlLhQXnIN[FI*aE@i,F@L)s&`5kj*t.A:sr[`tB,^^j@$dJ3Wb#?Y>kNe8+GF8Lse!"`>VB[d. %o-Sc,*qE$(&d"mciZJ*PO=$ZYn=()Z[Se;e+N5-2C2iXNbNB_#'M*.JnXsV&k1U:Q-$R %nJsg,N$WdoD6;\MaT\q%X\3SH9_.*na1s0m%5E-I2H!i#P.mX_KbW$H9Qi5b]Sr%k`k6HO;Ic(KK@>'*aB&HL3jD[6`XIkA0o0`> %MOmUp)Ff`YY_YF[S"5MS)O8!i/t:I:bSDY9JZPds4B!G?$qemOEV-!Q;HLT.Q-=t?4Cuj8O22A,mLI.U^9?"Lchd5I:9IJe0]jpq %Z>7gFc!]^/qeZUAl=N%)6RYdcDF_p.Vh4gSp(%E&DoAOB6"=(rf7(u=dhj>@_5M#NCM;tK9P6fs\D\Mmmi0ZQfge"TDa/-SMRN/m]Da#AdS'F$EiU[c:!/urHed)_AI(3 %@&uP0-;)S-dsX=qfn+GQ]6C9/VVcr(%-M.I?ZCkYf:Wn=X^kJakD9(b2bTe'[dU#*Gr(3`AF-Is0Qs=dU,0%nXlGUp[/ofd,FWFS %TqX<_/J0If!4R)d\1C5YbVM#8<#!1Ld1]5k,NafnY4\16!'Sg3W.3mJ)D.Qdl`[WL19aJNb-8*noqW>I@^])=fFf11"Vfq,;+bF. %VE3NeIlI&O#WWR/1"!X*blC2RSb:P7DX75E%B`;UYbZ9f<1g,Wmbo_+I_hSLjKhC_$b%(r+IMbuL;VoV6AtP`6/O"-"tJr;k+"42 %$i@Lm$Ge[LU5a*l?tKa&/S#;2K/6GVfFaf(I6.75;'?mukZ/QSiej1M$;h&`eqfoGH1)#r$7LA,IATK7?EO+0fO60hH6<(cqJPcb %i.nbaVR3Lh>WB_?`*<=6)^@tpGMP[!%fK %4/R]+)i["VIEQZDnB9J]N(f0'L=+\2_`(+XXMR*-q6TEN3gn`oJ'28Zma%#EHbWdqI%:npG,Wn*:Ea@u#)I);Y!A&9*4bW^Z9LRm %W]J\?f[PZ&IZ#>h\(g`p\#YL(H(utIYI^K,au:;s:cQWAe,2DNp4'PpV=A$Us%9+s3[pYLU9H9"[MjCO4oRQ^pQl51eldWs9*g`V %L.jAgqsX"BDM5g7D4trZSpH/[=7!dXGNfJFeUQJsi);;X.hAG/Wb*abJJCETpFTGZ_8c=s3nALlIc9C9\o/QR8Z=5'Ft6/*bm%8g %i28Zh+8*$@lIjT*F"t#Z-_1V[bs@I44)9b7:UN-j5EK*3);Qmb)/2n94Lqpq04CDEIXu'ZA2ZGfh]Z.WSs(bhbh,r5QP/1+5019P %"]FRf9sr6RTSb%S\VQc\V[1T;639Icn8>>50'[Z8r\I%NZdkH!9Hrl8_G+@rLVQr5]?Htb>Y$sH3E*Y&sV4kq,:(!M(E/!:,QcF[-2^olN@TB4[\R+>\sP@^)FYMJglbg %+Pk=SZI>>Jh2lhd[l6G4e,X=l^*N-*I1lZSC]s`0_)f10J%0YXQn&`KViQ^ZRoF0'@;i;V`*CS;3duGqQB,AhiFuP7"-uZCT=-7/GR(g\n:M>*PCSB(RH;fF/C=1hc"UOUKL+?*^]F!lo:h!O %qipm`JUemhF58ngDk%K43Zp$>1kbr_D:[.?[%gqJeosG%""\R(2fG*K7\-/%fVb&&e<`.L!k\13dh@@-Y&qZ5&iEjP\Y>e*TZoh< %p?RHJH66[YrmNP>?2@b%Fh9['(X,IfQ30-8EKo"*7s^58:,hRLd@!u*qce01?=mh=glbpCZW!dBO8N*A.ILfLnsJ9hh2a/)b&qcN %MR7po;qh.Whh9O.b;Bp'icXl>fIl74rM*7dt8WHleaKZ,#9P2VjJ!LEk<^Bp&JNE %;Mo2_WnAlALk:ROpqIo+ek[(SgbYX,\R2]"i$+.4Q"K5?h:a;#IZ8ZAV5k?uWbIG!1(T,Dk(ID4>E^U,P,N*bJn/dEPbNO,ZqK`dJC:[.,h" %IkC&2OQ^'$#tdrsF`KGJM+.Q+#H;BS,dhB%MVkQWIUb9NkTqodSG?S7#&G0!0V1W@tA %^75uF9"tkMY^ZUg*SKK3n"5A[0ZP#[Y^?7+^HdMj/Y:3=J/`9,p@d4rXi37b"2+Tig[A<'[G_ACaPqha4$256Wo@M,G3QD^b\65c %2qC$8jm*+&>W&j=k'_aqJ):!"Ss?]*>"GW[Z"q#)<7l^*+o %1B!V0bHE_pcbKD$s5Qn)r.dN7a"Mr9Q[efI5CWOja1qT!J,2;\rUV]Bj6OR3rVE]\KQY?$I(&%%.5S_&W(AdgC:>cXS;Gsem5?ga %U"t[Zi8tAdGr+m/8AHh(#hR4kc(cumqq$aU]emTBZBW6"aR)<`+HASWZ,6Wg!0D[]pe)Y %68b%JUesA6^i0)+/XbV!%oIl6qmc9Y4U?-S:nE+TBtmAkc1l\%T)@8TX4Q7uW:.1D>;n5a5H)dV-i!CQ1W8>F`8]LOlQtVpRt(7/ %Hm44ASt>r]O-qk,eBF\&@]d2Fg#cW&3%iF`$kB:U:X_!*lLXqr#+sM:W;SM:)N*+`p3"IMjnKrL1M'Sp7VU)TOQPZdAN-%sAB*&' %h$,VWSh;kkbNa-N%]A\0poRm$MlI7kU!WrL1Rj]AIgH%@E"ccQ/J.[<+Unf1*Ylm2f0>bk'qnj?bZNeo'Q7!oln<`f)n&B;N.(L7.f)^\i'l>h<`! %4I;7Yr@C9hc"o<&E>JDT^b3#S0J:'ka@'!%^umTIRk7Dq(j"pS'b3/bkV$X-]JF#<&<*Sks^-bi!obZ!9!F[Og@\_(C.JBZt`]Tf4OGp-q'rKa/sfC@GoYe4R5$kBGLt[;e:.ngC(@Ii#J%fjq,VM0 %GGk&31k<VUaf:OX1'Y=u,>7Dn"3m6R[E<+s]^9:5?7t3E^2#$1`4kkR=/Rd^U>*gq+`;1+Sh$ra;kNQe %N@T1G4T-sZR9sink+H>B_(-Sfh3PJ;@)TpY=HMEWf.Q,03Ie37CPR7brG"-LE&rK8Dar#rqUjtD/JLbil9P1 %#Ok'Q)9467egg=3iauLq"2'XUIpMI8N>XstNV9thYOVg[2&##2V-,ZYqgI@\%sQB0Z:r_IcaCbgbOBch>d4^he;r!U\hCsI>K:Q4 %kkCqH_?\o5f9&]BE]j.U/r`T.]Z&/Qju%%JE=BW-hg!g.:"LfS9s#aPe%oXIK)[j^ZY"AcS1V*u.eF3E>1S\qSC-6^)?B%VRVpqshV!VI %6b0H3D6Kr)%^M?Wq.$b"df?/*pADs-Z2]$\G+kMQ([dbc7UkZ2p,5'EaG.%%Da0QcMLAJ"W&(RsN)O_#aO-Apa_cShYD[;WlRc.4 %c&Tg]]%M2iF0R%gj-PNoO(1BRro%1E:\?[LRTX`HpId:\,^!&_RqJk*""4PF!g%*X,SDDMiC:u!/I'!II)Ch$2b\Y3`(m-<@D7_fLpLU^$ %h>U[(pKnj>.RtPNN(PG4bKU8DbI7S0`q`gUQhMeuaAA<^SddB2[o5-Tj^-uSPG-D!E[/dfN>pO*a9F^[=9!8U?i&;NSiM1JY!K,9 %l?$]Fn_uC^TnQP#n(<-E!XTCs4T0iiV[%c5aE]Ep29J#g9C@t&*9Y?49bfHn71]A1<4qVOd607QPN5LF-*(nkC8)lQVhe"tcf75$ %gD^"uUV?Q]eo5Q/"nnZf%tln)7ue<.-bm&mS6bkE2uc4LG(ua(M5$Xj&Mi'q2ia?fiT6aa/Z^!F^K/(oa(]k;^4R+g]&Ta!ak^^`KUiT$oW'lV>.g>M"n.Ge.=h.)]t7Sn4*"=uVn[L)]7M>b2"<@qj)s!%-;XJ4kij %OZTVg$aVHY4"Kkp95^%G^=+Vla-s++`*O%n_:W79(ph0]F_PSCjgY:&D9BNAWbgD]a:Lh2/jFf1]_5d`LH@KPmI@`IF$M^j^N/H- %]-G&"'c&)+m1.BSVrBYtrY1_Na2?*arqhQ`e0LLU#aOeDmDgjA,SmDBNH_TD7$3r-eZt7)KBWAE+2H=\]J8l1Ce"6o7&@Il'ntb, %nJX[\p2Zi\T9q-,I?B)OSk>gYek6EJRfY2XZg\7O=i\iEUjMpA.Ij==epC)b+bBH"QR9?[AKsZic0W4*[H3QM,<'&/HO\psIVlfC %k%lKe2GJf`VJCF,HgPVh5bMWR!Q%oZ!ROb7j_oUSCe^o^<6a'RR8)GgMGb2bMEneZgc2'PL?nqhTMOg@W[$[JkQ(sf@8Mkp?P2tcHB=/U=f:qL9$fZQrMajEB+?`AO[>N %2``/NAL``*Go8'rmDeQu$FG5L<%]M?KrOM0$&7Q&9c;9#,h&caDId%iN.T!Y\M"HN?AI4hF77_p-U84orpK$:eOCX4C%DkH4f>^_Rf+*"?Le2'Dmu(k=ZqW?_d#2]< %a<##G;U*8"W-2(S`_7ZGC.qB2"e!hXTK4[MYC2-"f]bIqMH8?GQ0-#uN$dL(IrD\J]@8/37LEXnZ18o7'>*=jC%,5Vfjo$f"t[u? %,M+eVH#a?oCDb[ZBJ,2IGca`dQ6WDXJBM1@lcX)SQMjdk=QT3fq\XY[H87XqcFH/k#m&Zdk@&#L[ENcA)/J[sk+G(%`6>@p@)c*g %O6F\]HoKb/Z,J_hjq+!K6VAID(4XNF)Fu*NG_18;NaiNQH9?b`K?a=OnMK,sk!;GhX1N!9j:G:TO^6B8aPC2b&'@.2`qL,#Bs\IX=U#0matH"^0LX&m\()(k3asKK*EY-.*>"H7[_dc(d3B=17HC_!N_l,k.3NVW2aN]dX3Q8f8Zd\,7t*c %$1"&5fm@=Ag"QX,f&Gl+VJSBhWA7Zd@%WKugW!^o!QO1?\/5Tt%gO7iBH?lT_f1qC- %YX9>Ff3Xg>k.WZRI#5YA=0CuMaZTU.`9fCq"#Ml2]J?m$p(R3MLN,K)Dq!7&p1$Ue^h>Oe7[<#]KP+$Io#npI1JV:]MnE:R3lh:/ %55%<`_q[IN/35,96[Fn.1mq!"%htN(&#a$ %oOR/6&J^b>BG">ngYL;BDQARGctg7`9.TEFc?;.dD+t%X9EZkHd86:4jT'C)Y@7#:OEIX+G[&:6\EpJtk("$VK_dem@.SO:.8u%_ %[$T]nW0bb8Z;tE)K+aM's6.j=2#0uVgGZ$]3#$*A'0H[,RJalk2C%h04SI(?o-O%nLMe+c%dYun6=Jge;W*RMIOMdgMO5h %P@L(dr)P!&`WHDd5&`C7=*]]U4sQA#d0g^+&gYJq_D9%oi5"/oTY3a"NLGo\n8KfHcIrb&Q`mfVT^u[);&# %YYcH#e`6@MhPuXkqY:+NT+t/Bb38meT2gYVm,Y!=4^H_1bD_q %n's+nB(T':Xc'>:R6H;/`F$*SNK^RRfXaC^R-Wh,e2,DWp:]s292k>*gng&nqJktR3%#cmPf)bWE)JihC5;ELiN,/5X2bnKiO"%n %g#%4.#Ck^r>9(>[9O2Of[1nHGRZm'HJB-\8MHNbc=O3rC3?U'SuWK[`-Yfsd=Gn]TsE3%gbWATh7>Vkn`Dj6)K^r7*pJ,_u0V %+jtXlM@L6J1"LZ0bDn=41"n]YL;t_5(iLH?dpif5N-69fj'rdON44kQq([mo7f;H1^dB1%OE#Nd:)l&-a.11[IcQkh3G)QW)4E#H %.C(snq5i\R0/F6Sg+JZh45%LEpJQ-WF7YsRUkO6*+TCesZZbRZRPDe=cXlPakq(k-#;SmjULU@NF+BN\Gj %^:/U!nFQ#UfspN@>O`aU9G9$aCBtKdf;nZK+CjUF5he0Fd/nsP=mC^G$%:ZG3.^is!71=chHUt,.Y2??Vg_U\7IZB?X2o'f".@M/ %l-D,<[I;5"3+fl5kqK>6MNpKcXXsL4n:Xl?Z)Q//3]^(i\jeJ;bq:f7c&2N5g6 %e*\8QiV_jbB>0;)q_BK=*E]tM._(">nLH33mK;t#I65aRh+o"sKDR[p5X=S,,]#@H[f#UI$Bou.9*U&r5NQicb9tm9qK@,XbDS;C %!(bUnf=K8%)6Goo)p+A4_\")7n<8J/a!AX@c%A68jfNgM/-O52]W[=cKpb+@!YSE_H5RkiV#_pXYIWZV\9=#@g-er-^5a#m![Pej %qql&W-h(Smj+N#C@V^dP22,1sTC"t>i6iT?&d2#h9"`U3+Wg\QJYr$_OtP0F2DJ_$k5i+.L7cpp4a[6qX6eP`"j)PY-e+6U04Y_1 %dN-Og2tMeU#P.qmLi"fsWTu-Z;&kMSJ$G"^A84N9&p']Y1:U7]^&h.gW:9Q*?SX0tMXc@Ki_m%?K$`%35q63IW;sMh%=Zsi1*'mj %M7?]0S/hH'S2-$N=PO;ng^?ANWrpRY:F.3>q2"o> %p%MLWo>N/gIii!)UP=Ph#H^OnqsgL:Wr7btj+ %:6'nX>NM,E8Jo@GZV['g/SE-`ePt!e=%p:/]U'f:9%q:%tIT&cDtP
M>)%c*Au&A0ta<)-32d2(92K#sPn1=-=9i(jG';qO4'QEGl'Ia06nN=Iu)DHM`W<&b@5FueUc#AoJ%=gHRVV:Mp)__?5U23Rp;[W]I %!%(Jk'`nnk,=$rAc7C^e:4iaM4O=_T/o"g;mC%c^+QbsOd-j(X!:QGS61aG/_M %#KO@E[F]R?M5N5RR'4bS6aI\bep#pk8f#:?]!7Yn#nDRDG2&.=OW>Wg+mPS2of`Q7#n0Pa(lI(cC&k@q!9S+:)XP!_ag.FD!%%0' %X$/p`j/:Q+gpDIJK)H7cXA0%On(ZiAW0W0]X`B6@?"GrEe$`MPh2Pqs^sc%&i#/+KZW=G>Rt:"Y@?oE-h&REo^jH'><(Tf8[A*?q %ke#%h8kht#<[33@1)Q-JdQ5;SF1$k5n]M,;%W?GB9_"Pn\p7j&[(ei^&]@%*#.QUq>;tS1oINkrj,^) %E&ra/EWmdQ7J83VVSJ8G6*G_N6lOgMd];Pf^9kG\$V_T9@@"tOqsSSO%E,Mc1K(I/mhh9sn$jPumttkaR/%2dKr"SU,>+NM3E^5N %I;o/R&#aW%-S;XtQY#:M,bQ]NrmnkKnWuRB`0jqcgR))ThX$h@WseOrQ*\Vh'C#gN,4/LmGFH=A6f)XnM]ltKi[:9Hho9[E)&!)ljGQp&Or=-l%q]rl*ofa?X)K-l=F9NPag-u2iC)fAT^;KK7(;KOdSC&tR,d.o", %$jOf,DCM7[A+#IKWCecC!Sfa!n7n;=N:]Pd,9puSf5tb=#I>61!dC]M@$9t<27T8qKOYO?K3&7n\L0NAi&mFV^gR?DNqJ($Jl@k:,V2HE(mn#oa,H//=@*i^EeI<`X175,q1^D\kY^FDgOeL]<qh(DFE>DV0Cd]G@"o+;k+ %.k0r<'j;b"P7*R'@S<%<9&3/5:`-@,%sh)mh'pC98[(?:94,L""9)22U_p:.b::Xl`WMgdnlDZ5a`OB]B9`nT=#ehI %e6&NA*2u2].k(F3aS.LN''#;c3\]+rAJq)IpS[,5"(P3$,2!&8SYT`O:>V4Dj)Y!^6&mpH9phlO_:XMsMK:cr"gaG,AlTdW&Hs>> %Pj[Q&kUd]WXV*s/fd%YilmNnePdr2kZ?]-\=.>)WU+g%,rkVPqWTu7i/hNok_oVGr[)'.ah3:p@X"L$gg(o1GqLOL_m`0H[)g^Hh %S3jT[XZE7ESS/+jL5Re^Q$X!=pbWd-$obN"Z[tCG]hWT]VjKfqHHk^C8\=QRYV+IAa<,8')[6J8Ga.Sb@NaS:-]d]!&e"CJ*^t$sj_u9PGBe+;,&4-5VLStc_UL^/niooI::91s(E,qLW$NcT9iJ7e6B_QFMVV/1 %i!jJ8kd\JUCB4^Lp5GR:'O/\`:/[9f+^Q964Yr'=fu#-Ig9n!fI@q[W0e&2AnjH-rGRTd4_CQj)p0X3(g4p3'!W`j9n-NQV+L&R8h?.4^s+N-?WJcj;_mXhIq([lbTS*A1>Hc; %dY&i9!Ob8*U1VViAIn.9GP0o(#XYklIXqaVmm$\YnAQ_+^D-21-3BkuoEeE-D(6F0jb0*d*ss7ab]^<&pOp%=B:sTSc-,Or3]e*=(p@U)5o&35(q&k82G!+L),U7j[rWJ1Tsg<#=L %,0h.SL?S1R@2ljoC,<42?0KPW=po6!CFs]]:UZ7p0PM&QGbhJ;!;qnd`Z-*3-s0`,!shU-W"D>6aeMlU^gn`,Vb8_HYlh5sM.PY7 %`0[`Vb)]mL0-uB-#8e"$@]qED&\N\s\.p/Apo-\*+Fpf*B-`7*\ri9M)moi`hl>:AWPEElJGOICZfo4-87YGR:*NV>)J%63i'0!0 %?MV#9pJ5B$=f(;mLic*9Q.'3Ch&`3o=G[i:Bi6)r2&ug[PipChf;UP7TL;j6`9d"%1eMniH7'4$0c3b$=XRkr"tR6/S,.etII>rt %G%f9)6UD81GN47+n;PVY;0<@t\a>T5f2CW=TM#>SN1(H)@,r]\FJH.EI:lP:VO7R"/!#+Xc[bN%%V %R%=>#o*WXI,R1Q]!tFM=CdIb?N"=8^+V;6NLlA84o]AmRX'LJ7g8mmDHAi@&#LEHQn'!=k:Bj]qP %*,Pm)59eU_WGk\Yn$XMJCXSO7`A6)eA;?.7.<+ZU$"MEmVAnc8H%$2l_lNX-+e3TdFJG+jTWTT-Wm&s3Xs&#oisjVdc)KKo+6jSG %V\4l8N!U#*eqd;8$^l>8ufb>-BLY)8D`#ga+_-6F_da'2T,GFTt4Zj9`Icau7GDL=Il4?lEakAZL6*n@^%&EZl3gL.BCTm-@ %-tpH,*B%kC*"Zcem`A1Sg+aGo8TO=K$-hD`2M:R)VR:?XpXUVRK)a'O\D.r5*CVMo&Hj:$t_qt\]e("\D_m7pGVq#FE/dQY.;!>2On %c0UhipQP2[mBQ6Db7]pTkon5ajpDrM*q^IUIPY>4GTWe^\N!aH=0hgKKm1=IJR(q(-pNit%(HGM]&E=_)ut@Sj9\V"#\GWX`*&?? %f(SG4FAKdL!1Lhe0)Y%%TQ"Y5p<2&=SFo"uqMa62RWPA_>a-'t>cq!$QLX'A`F0itm767W_.X&NpS^of*2mCBg7a!2Ua,D!; %D)@TR"C(TKpkNmF?:?QS6XkT(pWB#s\W^*4\hs-k9\`_;)$NT8Qg50G5(OD378?.uIPc %M2TYW7C3ki92s8djiZEftulI%#Ye\maJZ"#c(31X=AflLUs*!O66'P>4HO^e)*f&\,1V=H,-G15-`%-#*G7o.E5XR"c0>ZL7eU %5m8rr2f"9hhR=mm&d!)I9pT&KAVo2EWG=@nRHtF(V#WAm:P/Ef"!ae %f8U1Uc$4*Z#?-%lKDpe.kKm=bp*_srk'\U,`>eEYN&Jdn:o!Mb'@P3.(9k^LdAp'Rc$u^mRp&$a8)-Iq`W6c#DgmPc_/O7/:^Zg2 %k\!Ul;$fdF27Y&lU+=n-@mI)f&*[&.ld\`)84_m[3@.-3Z5m7ra,KZ$;(^JU)jiOoImG3OZr!VIcGHGM9%QGY1!X?M^$l_tkY7nA %TdKpeWQCF@&EjRgkG2<&C04G*oVa0SJo/k)ShD=h %aCijiC*P*-[F"u#g>q0\s"Pk\7LH5C[8\,5MkVbV_'dnpmYZG2#4S3WTaD1fnhAAKQ--RHm?K* %qe'^]?!,E%Xk?r%+5)#gCb %HNg_XAMH!dVDf_%Lu"$j`msm!jZPjA)91gc5C#p-k:6_aG%;3Kn?/O!egU9l+c$EoY;>r)@WXPK!";s)D$E$/)hfAI-Mp'R8lb-] %;&j`;;%BDbKqc0ZAmgt,_;CFUN:o"O,#3aVX?Z&L`#1hp@@0k[ZFl8Fl*21M=S!4qg]lN[?PA]@R6]X/&G?j2>??lQbMDXdeeRsCnBQq9>*=ahcK?\m#qV4UncG3f#0o2&^X5[cH\N[cE#`dVJ*G\pqE4*.H(YqsT9\nK8>OCrc++eZmkg\p;- %AgkV>]us4/)o1$IIta<[7"4W$`GA&nW1c;Nj(>)#G9iePCLYA9K5t\sM-r+h*9SQG9b?`5^V(=dh\(Sa(eHkA6(iJbh&SJ$-SjR( %n*e=04L,8hbekYun]YWni'&3-P"/"'"8hZ1e3%b4+8DH5Wp#RDqSYT]E`J1%ejfr2JLu60eNS"mO*oacZhK"SI,kYWGf:15j]J-#GgO>fC1eMd2BESnhS_L9.N_HD+@l*d#G$t^9p1-Xa\h<`/;eJt:H@X?4=IKTeQYd(0+Wpo %n(KKdNL;.WR\P&N;fT[NS-k]bDQHdE']C'l$4#9T0;:SNS6otq$2`1s?l8Up7rX78d5nYcG5Rf&,Dmoa<`jP:*(6%mo5STj5kh4 %o>%.^F)Fb>S0O*XaS7d$K8rX",Nn9AT6-qc*B6h*r2:j,lH$P_?t^S6>Y!Z&"%V]G-TgnE*]Rm^3noekp:uf;i6r^7G:/^5OjSC8 %r]T`R:R&^@p[Fp@8=7q109/U/)kVeji4'Oh:S-o7#VN+5,[%UA9q8INks[nD'(pp`k.bJSBUEje(f7-`6p-._nnGi1r5Leg3:*(d+`;4=DEo %1__#'(67)W7hpda`J:3L`)0%a6$)$OTAlMSnXt3uUl]TGdQ$Q1*&Td;C*#n,O/#=g8PeD5HfV8,E`=l@:d6rHV&U4M*n48O8hDD^ %QO!2MK20Wf:Zarik+kps<4$r!^,`.Q*;+Cp[Qr#6ZdjfVM@jG,Tg]dh? %2<6j7"[rU#(H5I61LMA(sRsLCNY"6+O=UlL&m`e:$t&Y/+fc,oq5E0e@%F'?l]rf*gF'm.U3LA>t8b8UCPq/B%Tsdls5D5 %W*"5o2ET*T4Xd0J[FL9uCepL:7s2;)'&6>Am\hf5TLJUJ>Ba&VHVhUA.d%g0p)`l$%bc>$Q+mPm^ls$$;.]5_OmkZMn>LDQdR64_ %-_?S=c_?@YSGK46R+H@eW0:GS(3f0qjQnHLY'='hY5]kmGLSeWiD9NW"f*$.XG&:4\:o&Wg^X0 %TH9@r+&u<:!j(i_X[c+;Zhj!?:@(hVp8C4QTN(faCAY/aHdp2dd+*Qki'"%34t-:lVuRq4Jq'($5,o,8Fc+M6`^g!fUJUNVVXdT5 %q5DbidW@\<59H/b+'#.E*fa!(^-nF'-u$>0M:9#DF1k8FD:m/i"t9CW]#E.N>YU_[eJaqdrj,/?_hM0DoGckAJC&#L7X+CI36+/BMre!D+XoqBA("q">=6ibJ5__3Pc`jrXbOM+*EZO9Q*CdhF?mq/`D&m3d3WA %8XT_B^I9V$b($peE*X,Li^k%6CQp&iT^GHtGZf/*;qGV6lIu*gW3(3aAMql=XE13+V,mY_>@:K9P_RHHNPi%%1uK`<+IZ %?Mo>Wk_^PGbPA,?)8=31llLi3jTSDjQnns9JhqdR/m/%9WnVK*Xi>'eA%N7HbR"H0R\X2RYn_U1\E %K^\TfNKIY8IVK5HpQ^FlDFpK9P;F[jjmFVJ2C^[R-VWK5$=SdR\M?S8^/EJWOt-fP!:k2*8hT04FM?hWQsIOWBuH.4fOU(E5:!5( %LBWZod!Le'?I).,WD>Da&%fL:L]V!L+%j*""tQ:TGM9/4:W9g`/YKp><6 %Gn'Nb&9M2bf4nS(2bUAX>Ufp'WBp]7KKQ%]9CB-[ouF631[)j]1obTi!,5]\HNH+PrVO%:>Tfj\j8n#ZQ3;I=lE]5b8hTg3RIk-B %bKDC=;rG!lb3qa[j8cHd8=g^%3XHMie*k%9 %?@KFC$]pn1Wl2%Cm\n7liUOo<1qW7u".1-7om2I&!;Q/ZqEoWupF3T7bIb_.?DU#Z12;tP?kCIB)tc9baTB2oI'lRb?][/SYRqLI %%a$lqXZ&D]]W:SQ72u/BM2?ki48'uh#bl4EY2#e*ecNLJS,1MW#'&]YN5?h0TH66l7hpcafgK/P_p==#>`A)Jkmn^5Vc+A+LuP7rCbWnWFme'ZN!0=3 %<+Ha^7ckX`XR=O*cR;>D^la.ghPHGQ_OHZ.#Hgne%/bMcV(*g-8Da_VN^D^P&TGhRns+NQ,q!9L+X\!pE'Mct7&\ %oX`4<)Adlp!75!X(fO8BY.CH.=_9F(T5W9lAG%E5OGBFa_j05C(8l(b!+qc`S8DU7`F8/J5@lGu#WlX]YDg?mNJil)AqN8W>q6Or %V)N[%`'<*[\nN!/EnJ2EE:(q%YW2-QcKbTkOabCpmG3uGlgclc)jThscFD4$!]c#F%429)JLms[mDBXB2ZG;e7R`eb9nA1HP&X>c0e>SP9sI\T.!&/`CuAP@CJ=8Q4ED,)q`dY %`G+O`:9L*%P)&p]5is^m&_%:+4*lu7XGuA)HiP\Z,lX/WqnF%W40?UnDIi4m%m6?996i%Wql_ad]4aDf!C\.8b_nN&,W"FHW6P!ldJ%2ffnWV*Yi^VC:Zpsh4mI.K:_Oap?tj) %pd%dP9mcZ6;>d)"I+1>DW['eW.R0jb+*F#JRa+G%kHe(YK<"Qr!qfEkH:qH-Dc0pNS;9"M`eoT+"N_lQsZ3Ht8,(^^f"H,&k?U!n"#rj_%c,ELA6^k1"KkXlUU<:/@m5bdj7d^N$"nXq;CC?#YLQSb@lB;uYq4Fi0^FkAUY_Eb;.n5+.a0V@]3rbaqdXC.R"d[LllM=:LIC&TAb_X!4Jj;EP*X,k %kN1"$-VbuC.s1D1KO:&gTLeUQT=`I3pSHNS'H+]M/4@6_/d^$8F=R`Z"bKJ+IA/YtJ#pMSZ2iigBA'4Eu]dfsl;K:CB*$Zsub<3`?=7H3gGh!r,CGaD[#L1^0Tod'R#4!!c7g]-WF=Ft2 %.J'6JK(b3EJ4^s^h35bWP^A*@CtB[q:D@&,RN]nN(o0eeX'3!:lJ!PRSo_hG2ufU9=>j&X[pcM^!5Ne8lGZ %)Xf<.@riBdTOtqT()WU5oXZsD.e-U.-rql/;#D%54YqWH*LYf1J"UDL_cjGh62``OV@#\2("e %Lt[#D+u'Xo?cDrL$aVk6G"CGV&VSWe0bo1DkRLi3^O9I?n#>A3O=LRJo8C^uG\T>HUA=J">P\2XSmSP?P0'j\Cg09o-;UWfc742N %%\ZUc1CRZm;B6h(jK>sk1>W3#]!X%6ZRW%l^EGDtB=$-(kl\_6PlO0HU7*6,[hgm5h7u!05g\J*pO53][*"`<-/fY065Jp**Pc9] %_3X?$W5(5YC##Hb4@7/TX.15DA`D?D3FP,Ek38WN:JW'V5S]8@7Gt..FQ-^#KFgWGc,e-tJ\oVtCgIa_KTQg:aL8\NE2?*jhuQMD %e`"jLeO=)`O:(6u/pP3T2-q,,)&O)@8n]EB=3(S+$J:;)!j=VF[)WSsKW?T<.PW00Q$a/P;9=gnE;A30*ch#Up*!t78K2?k)1uof %Y9r8WN17:QRpNRWiPBMQG%tT%kshQ8CV(b(93;,>jB%9/+\X&qR:_!l8B8Ogf):T(tTfVRaf'qs8(U*fEA %4[Sg8Z#L338qW`tb3)[J$"eBf@,,*@F61D3i#Hi'i-^&#Pp";e&tk"R7MCJ-U(\*G$3=?GKn'G$AT8(skn6[GaZ[R+Rnc4C/9B8B %-<+75cAs]@#CQR_M5n]rAooeX0kAE%R2-E($[!)VCC/!bZ(a9T)rp\fLV/+$`sb64C;k0_aC8Jmkgm&ISu;A%0J5@d3V;1oV.BU*@NZ9J"'S[_-[Uh,IQl//e*?O5M1,:ND"Z1'H6sU)LLh7im&@f %qPH_h(aN4D=9B,B=,ZYiFAlAf#/GQ[7c%DMpCI)[QcG0d\37KA-/Z(pn4:`RO"cNF)@4CLiW,I%A*-662,9CodAp:-nIZ8W %g">0#I9$L!+#L<:6JX>4muL%I2KKZji*"1u0#\Q>=UE.f"\KHdDYc-]\KZ[b+NS;"?2f8fTq1p8H)XOJ[Q\`,*6@CtT+=b9*kGET %EDr+aJAs\(W0dU`p=4P;;$MHm=ure)[7(\1,`U]Zn2Ka9#W9@?c@k.o*:;/8"r[#I$.g:jmYDA3-a:M?#@,1R5Of#e&.?*=U+JmM %2\bPEQSN%AOIAH@6flZs#<8=--p0$]XWs8J^X'\%Xmq.2E3r)^"K8\PqS?PC>pWlQ'*&GD'e;ol#?[Z+R%\o)2/b)EZ-F'Z'3aAr %=`M5b4Q&*Bd#N;Ua8mm`hjj9kC*N^Y)jSdMEbs;gUT.KfH-Ze]IGP<.<'mtCEj"'sE.jR#nRF+p2:4(Mjk]+&%$H6Sl=?J626',X %HJW=G^J]/5Q7%]HN.3Tms)peYr:9'T*Bh$PcMMChoPm+q]_DHa!!50X/T'4+?%l?DY2)dj0o!esl?q&*'LRN',X_iqPX@,kn3;'< %*`(kgg&:`2J",PDJ,b/`jd:hW6G=.:3Yrm;S,-Zc@\$D$5np^4!Z\\I\'[>u:`)`3G@6l6H83DEke\-=+t&`ibloqDhi5PWeGE:V %bN40X=-JR$aE6__in&&iqC,s##]G`Scs+lh51]AG.HEo,Ko-p[dGZ-sD$&5!\`p:AIg=UE]i;N,jTYbBr+'*&;u>Wfio %.kd2>990j;$i7p[q-$< %MI'ksgmMasjL]FPcVX*UCA`T8J&J'',-cojm4H%6,,)X&>1c:q-o@pa5kInf'\XppZk5Xkl`Z/[*ee'aP-RURg$JN'8)@*?ddeiF %LiIUM^m0T\ff)uL(h$Pf5?LCaa/'nMh70d*IAtsRR2Y@8M>*[_nL]Ik8./,Oq]qbF]#>keAD@F7#)[KC2pnimR_VVa7@(7kN83o1 %IZp`%#[toB=U*RH6@mH+`8)@tmcuZrmL6`)$(]\]'$N=@5>@*'5r/BHD]o`V2AO]b^,rAE%?1D+X^pt8:YdJHB*uI2.Ib2;cl\.? %J3,+L?n4OP)haTL[*31q\OYAP$qkc%,l(k1V,Burh\ie%MP$c3pl0LE4]?lQ<$DH$&EJ(=h"BMGiUiWj6jfE)N]q-BHWLG%0=i;H=L;fakaSqR95hp/*I41Q\)5tk%TeR3siW( %DSo1Q]Ml=,oXLr"[0g1pR&+YDq^LaX-a*D>[:Gq-]ncld-T+nZRC-"ep:1Kjm4=9JC(GbIriW]JrX.P-`7]ZIYQ!KjVkP7Dm&\*X %9`S2/o!*cd5!7j$C*N[oRr%F")NugN2hi8*2iTqQC$`m=[bB8c#,B>q]=!'==aJI(f^3,'@;+MZd%5;,>-07A5%$4c+,B!L4mG#=1m!t %GKkkfF82.17r$[:Jn>t/>nO%][J@_a$ML\,:`O5BbQt659=qja-sU:+@XM$KRC0)I(#F(uOEb]Z3HP=@J=/enqHkiDqe<[W0!!(fgYN$tDrq7PA`Lgi61ea'tJZHj!#W![#p%B;/eaDJ&FQOAE+HT-:N_['j(O %X&&f0X$<3GcABGe_sH)_T(0Ka,k*$nG^*NC<#=@8=Ynd:K^,SrY)B)1Cnpp:mi]fd48?=sV?m;L_2\];=Ee`_n@Y!Te!)qpLnFbr9[Ag:I=&UJ=`29og4$aGG=Yptpb^p6s %RS%_s]Q:mDQ@QFeDA2PTJ::-51;;k#Ik>#TbUfBld*ot5]a@#ajuO3M(qc`EMtaJ_n5NUO`q:J0FVOXtO97R:LRhDa*otD&dU`qEB*U`0BCW?QTs^(0gOjn.=mGAs %$25P`pE2;:Pb`YfY<,;2*C]K>"n^)LHUh5Q#78/?gttsGn15c.'HB5+'0aJS5"H_9`=X2F'T\uH7sW+LPiGX7nL+tE+=?n,4F*0i %4K2JTF>&[VR?(gGBAq+17-?k\o-F6ZPR)\6'0Q\`*X,.XUeHiTV[%e&#;OaA6?dKpGHTn4bc#q#]H>,f>E'K%jNDGH1"9Re_Bn(G %S5]dSW!^3_Ej_e9=eb3/FLjt*@"uh+FdJEBH%Dc\&$Qd]?=rn#7bd_%A1*$l!pWTWcD#Ku/G82&0[G&R-ZtEA%Ycp+QdBqOdZ9l! %aHA4FkO$:JjEHgFG";eRN2q#3,PnbohpIQRjL,pO9Y>Cg1oG)Un(Vh'9T$4Q-9YZ$Cg*$)X]VL5_FU[eN*"l`>`iW$\Q(Uls. %C'!7I\k?#pf)V!-CXN!*ZM%lP4gfmhI_@90[7#ZH?5^F#%6.l$k^Sq$7#6`4DmrGR"jA#RD7(k!*s7/Omr,kS#dkd2*.N!R%j'O;!0g+C6^p"\_NXRfM\/0NZ;6N)1gNO[,\H %$c_kRMfeWC`qo;FL@$sJIe<]LSS?JGN&V2WWJG.@VI<.tJBn8(_L>QTjmD#jNZPc\feK6Y-KRZE*B,PP.:'dg!KIpY@Zn=?_+;_T %Bm][W5?cQjPP=kF!G^[lErbGp%Au,[S+AulQ]U?g`q(FUA7p]*"?6^Ln/p@2C**aQr`dC+5qn^'$kE&bejaI]=h/&-^!Kol9m-h;2U&6]QBU+`URr@("q8 %\Hlt^<`n5BkfPA\hM-'>7\$3&iao!pDc`HH!J:oEr$1mHQa$B7W(*iEfqXUaKsGbi"RO!:3er+\.lOi;O_M=ZHML7*<5lhW;,f/&+r@-o5H.8T?gnk&bSd,,AU)02:ZNG(-GHLtB!nI-igG-]%;b*!a>)F'Ye\G-,"[S%2MK-0.u %L/U1Xea51C!s)2?M0l[S8-^;Y!KO'N)l)*5SL]u"UKD-UrCmG:07(/'`0j+0E5JpWm;W5<;309F@JN5.jp>ET(NMGaEI %.(Fo9og*ZD.9t`2F)bH"[^%O;]Uh+hlcVXE5:fH,3bAs"As"p+XX*`R-1lr4m\=:Mk"]iUC9oknUJ(RNd8t\alOFuoK=CX6=WVt; %K>79SRqe=;A94cq55nFLY.e#=9.07/l"KL#S1j5R`HP^GQf1^_Ou(nS;>BK+P'3'gH]VPQJT+[j#MV^N"Hf&]cdsu.i9N0Uij7c*Z3=-gGA24]kdlIkQapUD_QIK8.M]DEa+YM\6M.. %=Bi#HAJC:._n;Y1DJ,FX6iWO*ZuCtO2e7)1,Zif%)SQErWZKD4CtYI`9P]Q#IDqb[?u([@q5>g!b]23_sjQ@r1@:eer+.PRhj(/*-q(+WR?n+:c#P7S+3HF6;E %?W("T=ZpYu%R".>i9XNnBL9^RJ.5RS,a5Wq/r'rnF9a=LK.;mN*rtP<$/o+Ug:qC5)jfju\8f^P?WiIt_!YekfjGO3]*/p&<_/l. %`cDGH`!`9dZVR:+6I,mD?'6[_85NXX<,!;$&nEq]"tXr#5jS@\F_Ie#4e[ms#iu:>o?XAuIg4fkIAR1f4M6s>qg3S>a*$pVJt?#t %Bk8@:nABQ*YuON+BebFAn$R;U'HboK_n%n3^phkjNl?D#dQW,*f_eL6jMQ^uhKk5eoPlrg[tR>PR;%r3p*hS,dXY&AD`;-t_q#uI %f1+->K.ThU_Q$rg@#sX?u>]JUG3/&K;TK_F)QR:'WK0I'bF4?^'VeqAc?pTD[ %&=A^NE##dB2@S"@\-fn^PW1:TC70Ad8X*T-D03!QM9m0G):=-a:6ld/\c]K-Kts"-'f;r/<^je6Cm9o]No['WkQWr$!qhX;GdE@r %@:\ubh'q;oHUS,?@0?iLQ&jL^?4C=b>lc06.XL5J,C7:BkBG\50['+``"8RO^eX7''?UA!h^t5F2[NI8MM[!'1^A:Pc(eOEM_4<%>i?>us#4T@P#3@$MBC%Ii %JL''22KRK28X=GmiS_`BD-H8X1-PoaAW!HY>TSu5c:];:7qf?#'NC-a8@YQoN<2eANAg&K_'9]^:l:_V's,F$iLWE!ih^.c;XE(r %;B?c`&_(,jSQB4D".$lt-[369i=R8ADXkX9Z@3eKAYVYb!g^^(9JuZsj5=WNrYV6:s2";c8F?;^d/t<,mI^G>i'2kqkBPqs>9)[b %F2W*TDVbP6LT1p\cL;0*A?HhI?Himh^LbG+1AB:Mk1Hj!eC`oW$-oe_cDe"m@ga>YSh%V`DRAE758F-QQ.-i*Ror9p1P`3n'Kujn %&bMugk@cfMNFKI]LCXCGM%[aYj$W'p-h_Z.orACAeukCdqL//>9hjhe:s'n(96I]magajbi"9>kJ4+cM/KPI`7kE^GDK<@V@ZLPc %=`cW0<6g7'CqPGj3?TQ9M@Q/n@akR]SX-?BC0,Gcp?*Y>NP=H^9b3t@+o>;G:B/*L5,dbd#;LaTg7H7,(11h^+C %6(Rno7/o%0JQ'PZX,DRF@sY3JCIknO_R+Oflc.4=5S>ds;l-EKV;l_nV7:LE>Heo/9-(s6@@`"Ye55#2:2eG>Z$f3\JWO^@EoK9Q %9nnpgc#aK@NU,$G*c-%BX36B\#]N-547?L8%u-ITP\q-Tkrc>l,9d-j<$%8!NY=`Tm,? %SBSHcM[0&QdgstP.\RHQQ*Ed3E($R!MUER+-?YK+H;W5K/3``WhfaQS;AUUdhSm[ %r_,aO!>qA,L39>8h7`c;"s>5[-8V'Ig=4WFJ)LkAO3Qeg><]ht1/pWsd8hNu-=i<_Tq#"aM-%,9Q\`\*Z3GA'-o$p*.[;HmFp=EUrUV_HpfUZdeUR.:?EUM28:XF.' %UlRobDCYtp93V,?FgVmc94Hb<4WS-&$U^T5GAS0Cjk'H3HrTpnrSEhofEl[gTEK/L-"g8t!rNaBFX2N*]R2-2lBHInsq`DTch0k3,[u%1S6/['ENuC%m\F]uh'5r+7?P!#DDB %*+UH;pQZi66"8rAhY&oV(r0ei[_E[MB]dl`*%jSQNK3Opgf5)#%RGoOUJfo;9sdOPV>`[!q]8hKcjk*'Coiu4hAu4^DI3t"PkHq" %QQJ'AP#1KYOK3_)IQeA`Q0U"LEWldr\!o1HY8,c.8T'Gd`80'ljBA^o2*smF0c3;8/m_O3#a<("l6;u5D7>^NBE3r-jg]G'ioKKg %:9V!RFd^]tnRh8E9`7q1M=tTGUb^"!L+3m;g"4YmF)kMX]&iiNp4'hXo7c@JJ3lgNYVeT/n,WOe<$!U>bqpU+/C9R`K;4Kq1/f*a %7qcsBQ-Dt0Kha$qWAigBmkI':53is^QV2C$S0bogg1Qb`(L)aQ#ADObL$tc3C:Aj,AS#8>JQn"a$i8#4]LO<*9hs1-^K)B>P3^XV %FRLY`QIp#>#V4=s-@$"Y0H@Z$08EfD&T>YnW7rh.WguFEQoIH+=^>c9hKEQIi-_K("eJGU8/"]ueUWl`CQ7b#dE7qVq1K1'V:]JW %r\dK:?I:?OH($-`FCtORJ@DKDgGjeWJJ?RD %\R#V$NFcR#iOlD2kf6]Z@r"0D':2ZT0q&=P=>I6D3D25pJ2t!q?#%u6[%ZD!,aPk,BKk.>!#r.@+)*Q`jZ+UUp:sL2VU/EhAUQ5,pNpZiufL(DZJXOjoCZ-C"IX0(J!2eYFrlU'3pc&p3qYo>T-`& %9(0!a0/0VSg"O'NmL($($[hJMB)+UsI@%.ObA?'I_='/A06$7OB_]2urEX=@IMmZ2_16E7J`S?aSVdU,g'3IX&3;Z^]%%N2.PZ%G %2K\7HCt+%r;r%^/J9&#s_DG5jKpjM\63m7mOe-ONM2Y5Goe7`];#sf/>NrRZVgL3`R@[FR;a^o)cs024g0LUc#["i?T`:]M&OpIs'Z'&W+:_aC*1d\.`81[^e:kFUNX%Bs;QeHtA.J`lVX-N6J$]K'* %Ush/!'-e5`;?"e^&X!]_L=m\,`E@m,;qA!KjAM^qj2?m)$-Ba(UAc\t?[#)I]6)a7eCt+dp=_&;?-.WSe18cTi.rYe!+Y,1E@UoS %bU@>IQgB7UC-)e4I#OQ(>.:NeVu$"$:0IOu9<(?X:+CX#)MmGY=&66B)b)47ZlUgn %NPoGGCAa1&MM'pu;"hlAg=b*6';./+,3HL9^6>SH':bCd-NuYX!k3X4KD49'\<@9H9c@,/0^.RAFHRF9q$d_2&=o&BDK8/n%AT8m %Z&m\EPQoQ1(g0B^EH.F21$>M!YbVlY=*D/I8'lD=NjA0cnD$O5?qBkoJnbZJ&E5Adbhg?phbstjGRN"18L_CikOd%t2E&uF2AXD( %!n+2C#OnXid9VJEpm,jh;bit%$?:[Cjt;h,!j%?7>hk9g7Ca!ho<7Z\:9%>RWG*Y;r %CH7VO0K?lS?oJB,P='P25YcduVZ2\/*\)F>4:Fh.^iJOuNVU0r#j;Q(8`7M/.cPifGe[7= %ea;MlG&r0MZ@t7/MRsbIrESH<]]O)9F>m-E.BC%HJ_eT$?HDHh9E=PDM(dqS,B[M-24:EPS5M>C.FCf5qf-4gdT">sT*Ug9p`0W9k`@0Dr4t-#=F/p=e0X>K$)Ru?R5he\!!=Lq4Yb.1mNdO:N9m5^JMkR* %W`kCI`*,U"18;Wn%)A1O3ard7Xul_AjM'H5\*//L"fB6PXJK_CSn3n2Q\tO((qA;"]&WOOl.3K9LXM\VUiO4CS@>%uVI,FK(8Mc/'R#^a%;dZK+tg5!WFE@*!mDMmh8fE %2[FG"QcX@H[(CaD?3N>&85Q=9ENd=T9!l@Knjf2W\P-7@L%bgf=d3lcSA5-dO4MY@]F#I"UcY*q?$>MpXN4]PAN/5HS!Rht-P@pJ %QS(f>L1O1'DleO3Hg_14r`7"7TFSE]N9&,Ip8hF\"J&%#X?d,f\bU&6atu]aEOM7*OrQN62Q/fV/;[OB>LYj]La()P7"')e %%!iG)IPP"_il9(8!V$t'0])t[mt9\JB_ie>4pZsM*X0f`:[@4?P3+k*-K'=!W`dET)_An?'>3&YJN'4;nu %TOb/A65]h,9JDZF+McG9E3Zk$=-=;kb]$cnd`5[$JEejj$X]SBBad.EI:QF6mn\&RsM?,VU9JtSJdrU %b_>/p!2ri+nI^-;j:1h9>89Y:hal$hr(RH_DC;O:,%QpR[JCsH_h_@-_Wf0F-ZV,ie0CZLLG2LQnma2PT;lZ.)kmY(/W2H?PRPRZ %K1@R\WOnhh-mJ9bsMN)[:7b %:a_;60G+n23"EM;eCu-%QJ;W6F96nhVjHDp^%q5Tr>UH;RlCb.SJ4PQ:(IAQ9QYBO;dktJQHdo#OqFu\URWTkVl"ZtnuG^/P>4S- %"0eVQ3m.hhb5X4j:A4c_013,tD%7@#7aUF?^d/r4_`3;!<-@%-UZ#HJ!L%R,DZ42]D;Skr$,k+n6!:_>@61E%LW5S%hg;'XTX\QHJb"uH,qE(HoF]7_8'5,&O+M](eS8f*$$[U8&Wf9IZ+OMPjd$]dlp!TTBZ>`9@7.2%aJX%Mo7-b9_ %6^MY(32fK/+YOu8!!AE,AF7L&#*g>K\rg&:4+f6VlDHGJ\q=QbqEm,rJg1q3^#-WT]k0s&*+Nl=O(KNI/[[<$=;0>V4rk?TGYLV//G(EQ&%TG6;n8KTr*Gf3n`5A"P8dBde&SgSq"lV$7p,_-G/du\21>%-oG(GI-TZ%DVYmZ7jKM?V4QrGJW5G5k6PkHi]hQ!+kW9hE(`5"Yb?@Gi+5= %G5u!JMqG6DLhm*2`^*_f&1X).?$%29AQ^Oe#@04 %WIhGgX6)6%;"hB\,ZHp;$UA?'?`,_F&h7:/R&Ju-PSoX0.`MIW-6',HYC.*0q`3eZuiIL@pj?X]hq6Eq9X\YZ/Ndp<)0fW %^n3-kUZ=P[*"gQ3==p$'VG&G_]2aW!e((J=Tf`^L#fAX4[OY&',kN4XOX%^oi,IsIatSY'L=!g=4/B^>6\EC.Wc8"'34ZDm#Xc`A %Em\Xp$s/HK'\T8&h.2l(Lp\W7fII2$UFgi#gIJeVj]FFI,*&l[kpr`+MG1Sna>Zhsfc39gaVsOLW\\l?77]:X4dt+P-PRCj((M[b %EbH%L&BG$c##H>I!@ss6J-VP2s"@C5]OuWDTL7.KJ"C3m\bB,TO0UBS[LeOh#gj?%pfnRT>SnLmu=o[jnPHmhh;TY8Rd)j,$&#L;YkpLdeNX`^17BKEUU_ %-,]jHHnjL1ND4SkQjXMP1f(C#IIY!=[!AEnfIl!^e_Po7mFp7Fh#h&Aj`$%gZ,`EF_6_d(R9SED!orJWD_+_,FQkp!e/pi:O9It555@a9VIY>-":ZJjbu?Y8Jj24< %dt#$+J8O;BZ-ib317r]qX1c[BGn.jrW(IkdQ),.mG?/RNCV:Y#X3<;siS,NDl-ds1:tKf'DRtK\$fjFe0m?nYWnT6Q %XbI`*S%D1^ZYAoH0Laf4n?p.`e`EE,i2Z)5>'1^eqIE_l>-0FWecJoSQe/:Y!4KZY7OEW)Mujga#Lds78!;D\pe$hRF(ac1n/5FK %&U6sH,FPi5\S@KuWn!g^.h,kl=;&T/afp"&n093sG"@e!"E-(G#Ude(+;_CGk*tcGOf$qGR8QLW)95i@jj-9H:5XlI/Js(J/f>UI %P*E+B>lgCC6=LE#d'D#hP&NuGP)XU@agr0u*P/RO^V`M^riO1O3][)nm/E'^"L-:u:!/8r'gFck7/,)HUYQE%451cVLGbi.qKn4[ %"JrlFA1/JPP_DNo@VS/Z?]BN)4U^5V#f-P6[4DL'0J-E_gZA/4SJ\$RBdA88 %V'C(A/+@1R3`^F*i:UK2pY#IK,g>HPmT1m_S^E(#BpkBn>e".RH?D%.j\Rs6WnCT_FqW",IU<7a1Fm'5mi'#pM#3@; %1l,&b=!ijIPZd3I[Cr:o&Qb;0i7'.j[Z-G.Uu,/QRaJF!\U&LSE3r&=jAo`pJiQsnTXW'[cRJW,6:L;,HIGlaXILK$AqP9HVhtb2 %i(+NSQFDgM=X9@X,h0UCoftdB]\tuO2HVOs"(%(!%(+DR,dPOl%=kF0G'Ca?0LH+@!gMl(#/s/7N'0ojV?L:f,mobefgq0kUe>1& %5^1Xd7d6)7/C:M@WEC!M>WRNkMhDa,DMg''`E>1^ %m:s/]EG?tH[.5D_#&+'t]HE)9>b[PJd84ok/!e:/3`T4moiN#F[s%)MFt:FI<0'1@GC?h:$>O$NXt'K8QT(!3RmEiB5&5Sp5VSeC %A;Du*Q5"cmj$bWrpY7A?(K'qH>.EB(DSkh4\T#<$hSn;THg-:R.g'(ZTrVUD[?7WKda<&`>"*Q).jM(C>nPo#dp6VBMT4snNu+f@ %G:P+dCG,A)1M\iQq0f[Ac2`YpH^?/pcqDACo.D91L^MW@FsPV9[R)!#Gq"VkhoHT\%0euB,[J!-'YB]sF@_(bekjo]&KV!d*'h&< %2@16LJm[TWOc^8E*sLLeY3BWW&'1T+9J[09.Gcp"*G4c1p^!5Dju@9d/^?q3p(h:%$=aI# %;)Z'(kUE9+bgJn%kB(/+2nme-HpM%5PWjH:!n0c.Q).".ZH2Y>o"f)2H2>5M;3;/Pq7RZD.g'n?!Lt/JRH-1+/`B8fKdSKhWMT"6 %h5J"]h)tb(Nf*h8d]F&;XX*p'=\TLhJY4-C!tS$*_qb_=%OY %/at6@#f\B%5?1/DdB=!o@g7GJ]5_mFgo=K*^M+iZn77)JG;NDkM6f]DB@q5N$/hLZ %%n`iCO:Y=78OT1AduO^n-S;,J0ZAnC\#E66F>"Iu>e<5hdm0Z'5MRI$@Q6H?(<58Yr] %RMntYd8N:i+Gs,];WFM&IFA3*JQ&qfcf3NQ&:fLd9'*Z#%#!=R=A^9 %@>C4l[X'7DJVO`>Z@R'^=U=5g<$d*O4L7^k(gY?VS]%B)$;E_mr"`gUh,-*?XeH.nbk0E8[_8Yfq %g"F%`@.CVfSh/\RB]Hc%Bl>j13XT2RS3R4Z]2^TNZka>nk!4`T+q5N!004-b'M7PC>S_$u2[FcB`4h-T^g4h80"#YZL:BlZga>$e %+@:7XBIg^:7-JHqR4U[WHt6<]X&N^p8-//7@8QOF8bJ.CUflBM'X\0H=Ihro-'[>tVb'i7j!Zl9RI'2gJ0*hkiMC#XJLJYq4!T&O^c@':_G>jBlb;=B]-*B!YN$Vq\u):Sg8t[o-DG&-9G[CVE]l8 %))QVANkX!rYl^jf/CtU'/bo@bhn.G06(/X#%^c-rd0< %BD"i)i@Z!^Q(-ld"+s"m]WfR&(4"'P8>SQZCDm1fP\+sXB_Hu=@Ls8TK`9cq9BVJiqQ'c=@l1!C5]&BTTJLZ1.C8U/#t,4> %gBQ2=[[A2,Z65t]>;"7oBqN9*FHPsg9+07G&F('cmT,BT,M\G"k](Zd8\?qe^Z>+sA[T,R\@]_k#K+-5!eQSra5iRL/"2^MiB6-) %#if3Q1)Z=uMMMHAjJ=qlH7i2[mhJ@]<`*5&\DAa]hQ>eO;=U3,T16>!H&q:b;19N(WigekpPtPk+#A@PNC%fM1,H3beY>G)^QOC- %Tf82;Fs18r\'BMZTi_DLE@[uicR46_Q7t3f)T[N_(2ZY/#q,F@l*G,/0gfB(Br$\B,+^cl2&aNu+PbKga"`kN*i!B4lOLC+^lJG+_3E-l0ZF=\c[4?&j/pAZZa10EWPc_QHG.fsof>=&-=3q8_FMB6HZfkMRQ9[h+J#c3_K* %4GG!#)6?I&dS)5TgMM)8#9SXAFV@b+GhJ^^I/4>_k"SA#3Wo5\9"SWu?!?onS:^\aTZf>PQ]L(9Ti.9oXokFh'C$1GiOXu\Cu@oWj,)V2(tC!q6%^W.Z49,&iMPq*ogAmDQM!r0]3uE7 %Lb*Kka/'hjY9MES(k3RR!HOGJAj%V&p+Xn+-'Vl:FDi;0Os%0XoII5p=p9iI;.<_n6"b_q_+;M>ZKOm_`)ee/9X2ti*(/eQ(s4&0 %GnY,,JZBNuj[-rC:2Sm2%L705/C?V&M'3Y7(3M)H/_!*jW12;=Z.,nqZr":^g70WO-Kg%#5R*f(ibJnj'Xb>0nR/^s)mNu9jWV@: %$o8ms:Cl6n#s$fiF*=VD:._g!n[+!:C]0uDh=>CjV;AdpiOT3R(5g@Z$e'5kfI`?"l^#QV(=??.G]]H#>rPBr<5l2JidnuoO$Ei: %7p.cBW*JmJbpY)O0T9("[L.e8_U1'Sk\>2##FK&K9aU%CW,HpVJY1s!]PcTdb$2`Jr$$R!#$g?V';Rq^"IM+AZ %g4SJf,lQ]+]_=P#ecQ?7(r9X%4eh;N$pZ@eQn(rNba,A!Y %X+rbKrpo?Xf68b)TDusfh8Sd3RhM*ZW;)ugUS#$qroO#8_t9S[`6EYu^Y0e0eO8;e`09)Lr1F!NS@kPns.(2/oX-,V[8&9sBbHu_ %78@17AcpIA'oa0W;VSEB3Wd03g(BoW@4"Zu3YBJ(QbGs&g %E6m0jgE?F8_2%;%>'mF36.3"$NEQ[_$'h]uWf\Fk1=I_@A`B%?e(4c>PYg6?GKLql6o&LW,-riM-cs+Z,IhVpVtO3\5Ai?anP9V4 %?p4!Nqe?Oi,Yg]r]-(RC?m;Z.8j%')2_,)sb8TOQLh=ul:o32!jFpO+Jo,aM-/(lZd%[OgB?K`rkX+u(3R"R^Dp]UEFaflV%t1+$ %*\1#@4ZNp3[K>_:(<<6L(cB?qQ>'d8[0BI"G'\+>?-C3HQsh6cf7[@^Sf]K2]G3e.RGHd$:D.&qkQ1cHZ %VQ<-9[SB6RO]9K!fHM"KP_D,,q)7V24(8+Eg*7?.k=nmnmq[k0h%!h=$8NLhoW="9erdrg/[\s@KlqEd^SbR>p5!?j6lQ(JKG$DQ %&TmA3I`QSlm.Xi]m:k[\B9OC%Z7T(Ik;"f(NMDb;NQRb"P,Mh=Oi0"0jE]_J?6QGSk]pUDYp@ULkdKD_o==S<8J$EjR[m,7"rW?8 %j(0/CHhPrm?j7Ya$dGd^Y%l.GMO]Cq@hPNV8n#]P82`O2[)'1qmpa@]Fu#W'orP.F\tI\IHOd=9VS'HF0_&lsfE,)_PZA=JMF]^f %,=`RGo/S'h1]+hTq*W!MfAoQXS/u5/Pd)iU,`.4sNa"(p'btQ#.GQ/^SY_[9\EY7!R;;G"V9684lUUp0[0k,EL9.Q3c%0:]8R6=^ %eM=)a(?-OmaA&HBUnu.YGCXtF0Lc>Sjen0\%3dMD.S-=k.a4Z*\;_PCf8..hO='n$CJpIGc@^QSN`)IL=95;+kk1;eTrYU>,BEVq %a%p%UkS6kc+/?^o1S=bk<)jD(Lf!]+/(`T+2WSI8;o;_X*0*JYdp]=P4ek()W]F %&3VU?T4u=1Lq7AT8()o,[9PFoV(*]u&JhD3,uY5UX*X:rB^OT*?8&J[o9aBWN;BQRmRbsWUXB/;!=Wee`SO;0FA&VG>*/rCJf\0" %:24DQjas'o?MKr#MeTWB,'G-"d3Q\^9pG;;LZ`nA([Om`9Up=]d,Te:85pR$6\/_"`$+,ti2kUQ(&OF^DM*ak#FYikX&AMZ=m1I/ %#,C!e,RuiYDAa$ADknp!X[>H5$lmd00X2pKPT6F"VucB7,]ut2Rro5F]/j/'/,2K1l@k3kS:13@Rra5B].u"F(^*B#(]$W$k-]->OaY$IM1+XPQT=Z-=>_CLeT!>9ob3kY,;THG9,XGW4W0 %)1tE]=Yroe(< %n2"oHMuL!k(!o4pZH(W*'VVC;br721(%jjc_A@Q"+MuTbik?2l@g4n)MVf>F=?+Y.%h\)l@S)r][6W?NJ2\.Q%]0h-B?uSM2THMj %dTf(aQ/t:?)T1!g=qOCG4K^dkktUOLL2uF7EQ8^2IXi'4cDN!_ft%@T=Fu8reT@^8Zr@j<67]LsgOP)?XTb]<2(FNh4Qn:j9aZI\ %qC&K\V88:dU\^"6)!QYsdA21La;XV>k%ELdPNRMV5`f0+o%n9_:B_7Hb5o,EZeK!/!6BG/Cckc9;3L2.EuC<)kMD2sN/ %iHD.JJ&He1=megFjT_U\KhY(EJ@J4Y-4C3#WWg5Ji:'S6aI1^B-F)%bgbPTOX]s%<9%H6HJSl]k+G$5C7t?anhK4>M$m$\FXB;Vd %>P(Xdi+m&<)%0GOGJ_IThfGlU`=[;CeKG40;IU3tP3AP`p2C$=UG+pe3C8oU$Yr0/%pD==-5qW,B>Z-F#J"^5cq:b#[IT?b>9st; %33`"[&jI*C;B&I**"/;A=KP1'8hsTS;)-\pfV7_?oV5->8pC1cil(F/7ca4'DAkHr@I>pfY1'Sk&heNIdk^5Mul*A %Ur/*(,X-k7J_GWp84S$X$U'9:/eVlqWV)(_Ok<%e*)jdI'[=^?;leB$a!_TXTQ)$!A"9Eo.?.N1^q?)A7W$mB3*LLL-:j %bRKa(6s%]:3970k^T3QH*7E**rEF1Q@]6mD.PX@k/0f:C]p1bANm7I'Q'E.i3iPr6X7^u5f_Ug;El=Qk7Tp^@C6=UY;G2ZlPGHiQC3rhlT%r,JlA7BkBXfS %r>mR!\5JPGYB0as+eQGG(5(s,@Y'`Y0#`%!*R."rg1K=-Tm0KZ[fJ*I'XMcdZBFf\dg04^aYUt#AgQ?!g76seUr)U\*-m:t(KJd' %EQ39beV]j@);?Up:fb*F+cVE_?J7,HMD"^\-0KjuL__WgLcZMgJFu&nBk$6oXd_8_9%;j=KK>jb\A\'E"1bgUNF*SXj53[Sa/Ck)OW2/I(JJ#?l>#cb#RTqnU7*PS-o) %Bkkup,IV-6.;9;!*OJ4R`cG9.gm%_Vc?'?7m)"*h6k;W'H%bN].Ub?S3b='SH4W6:;&tq=U5ImhTR2^//oA%o9IV/e*>"Lf<*<\R %*1Y'`)8WAQ(bM0XgS#nD$/hW7EtsE1nSC9a'9QF^fi"&UIe$WTN(0D0SBL8&8%Y:#>N[IjQ+%[VSYL'5C)=]ZD)-`cMY]/%NOpL1 %o2(RIWYQl21EmZu'QKM/gW2Qd[MV;t'@pbO$%gR4;G[kdSsJ!j?4CSt!c$Kk>W2'^IE9$N=/)*&qg<^Y7:aMG%1Aen0 %gNjhEI,p+q"i`IS`="3eGi3Y-(QJL>ZQUZ!&Nr5.[=g#@'fE-p>_#4iCF9H+DRDk`I7T()]*]rGihQ:VVEJs-;KqLf6]iMMfb%XO %eBjGRL=3CD&S;4^&Oq\_Tcu0LJ;oXUA52&4L5fr%D?TS!C]^O@:5!UK_,fA?G+MC/(7XfG3=rk9P>VMZA<<$:_=q[S]e!#l0(=LT %5g-ad3g'W9SgMjD?4mMa_;)YY_\*;/EC/T"Co;S'g5NA:C0::FD.dpL,`8QJPe,CRsuPU%S3RD %,g0CBP`$*eVMI2eQbV(,72,O^p\9KZNXgLP@n"'AWfC':_[XmnI@[p;#l"OUF_=NgVCf'j)o(R9S>'>Q)t[A_[]%If/PEm=@*p2B %=I"mGM].BRcJFF./gOIo!D.q&'qfa_K=$8rQ)`5C1T=Y;0F=1j'eV=d`hVA+G"BHK>%SS"#.8ZCGqQ*?eQjmOrP[;RK[o5\8&@,@ %@.5gZ*H':R)"]98+sb_a/is5J'01;l(;U\XBV8IH7Urp_.nNcP-#^^6V`C_mZe<='ED"(R.\QF7&m;kIknIPU'N[=snR.sVPYG._ %De!ND3\5chFO2u]\,]PlIUNGVC:(/a4Ml>Jg!maUV!b;+9gT*W@"D@gd/gp;]UPT\pb-0#<0p6][iG9/q,B?9P0WgSU2DGUa %:S5diSA?\J[D+Kjq`(T07%j7RK>L:@!UV?uiCl^OS?c`b-P/(,FNX].[0Q)OVh>]WK`"fb'Hq^[\36%%LZcd^lDFlR=9'^ %,6ckbE.Xo\je(a>Dd%Lhi)j(3"MW?m3*\0[dOYSt@N:KYNq^NJ*g;MSSkKe'eB[Z#.P#e"7GmY><1f,&&K/.BJ9YK*,^s+F?OVn- %-aXT[2(QaS%1K%M1hg?f,JFf5WA>pqFP)B\Md(sohq&-i&;iDk8kU8XDWK2]^UXFi%#1df!$2LW`e^-0Won9)#kjQT"-sA;\#2,< %GDmZ,Ko.aWL9O(1VlqR-ND[]:dg[9&,.2A6odUpD8j,DDpNP/Y5^]JEk?%RqAMi%*u9_N,,G7X"5ODC#q.L!^c"i %D'_s1U/W5-=FaGo'^92Fb\@P:978&\$K)[&UAgZM$SSpZn"0Mt+$1+X,=%gL)``r?l,Z&uc%H!E[tHofe%Ks$>eL,H6qn%h-( %VB1PgBNt8tU"7=h)Tn]qqB^1Djj7lIB3'_('h3/U]V;8B;oh&! %FlQH/Ua@'h:,>d(l(\E,4_#DT!F3G,!l>2`@J4[ua\7MliU4O)SqCHtFIAiY=B!.=KBkF2"AeJBn\\3G*%ijWTp`V3p8T/Y,"CcO %$FuHtN`77%;^d^ZO";P`9naf=I35+rJ=`D&l5g7ZH3R7"!S+u[(e`;m'T@oiRu)(kCk,eL%i4dI&fj:@YjIYE1/\ut>Ec;AM).Aj %>?mMP)k_ep_+m\'R)cTRe;#.5iZtfT_a7,bYc4!.X*&,OR7\PCEr*@8XJECY;=5iH+OBSFfud/7%MK!N01)dR?fs])AB_aRUX\QJ %>">F7h$mWJ*=J)<+jbb&Q-UE5[S$7Eh&<.]96"UgXTlcoESP#+5d+'/l@@DrW(ms9$LEbpcGe=<]I!9E\5NAF0RV4;HTLZ#90&VB %KZ0,,i9Vh',9]^X]p*/Dg=&Yp85F944=q+4&Fn4_h]T]M+^Q3g,6MQ$cb>at>0fV''.j13=@\dUdD;eGBUoAeb:Z5>N_$)UI&Xr< %B:+8+%P"@kCn)d)<=:A!PK9-^1P,ntJ[[WJ)8cpG4bg+-K=))UlZ$,2$Hik!/>\\-Gh\s[8kKH:(71DNC')6j/BZ'Co#'8'-,Q&0 %I)/DWeWP2%$DgecF[?0Y/OY74A!h%NBE3"V+N9E&asgdSl+*suQl2/XfH@J'DT_1Y!riT$>q)7"'8WKZ\gWD0$Jnfd92pibYT;ho+1q[@q$F1k8VL?M6"IO1j=\' %%rH@LnJPtTJ9,e-JbH5PLSe\GOno62O5\YYWA>V>P0`![lP7#Z"uUC6ZlXc@d&T[r0ahS;K(4Yg27%[0DBbZ)48FIe,+enM*Qr51 %[[;[)%U9t#Jaj?I4EVN9GiaGa!4< %I^3jP7Y@8r[Md2$KKoP7T1#%TbqXo-8=Za^[Cque$Qit-S7T<89U.5-%u`Kj@%iUX.Mo\8-`jVGd>u\'D.',!MmeaQ+@``4)R+&h %N?Su4?+bl^*(jEH41im)!0^+Qb(,rj=CA!./VqIKgWa:?/::\r4%kkQ=pD3G4%i.aNP_B[d&-HND-@&.P>"2)qaDBM)[Zn)oFereNF\X[cR&FZki,U[[q;afAJSS!O1Q'&O,?l,Mr:EU`jO'm+E69jQG&srd? %:Us\$:I?VF@R*RFUR/8\MkcUgs-Z#()RB %1gKL3@!M=`hZrpui\-SC`]r\.%KIKWj:p7tL(_Vq%SL+PA>m6SHgf.4P4V9`.@#<"X6$ES3 %Log(H"p)SOo]0+5>k:oBc^B:!/H0?eP,;egC"O#T7Blh@M$'nVSr@a`,]MsJ%QVM@AI"Mfp15NE1=k5Nl;o0qF]V7\hl+F7co4&1"B.N;+ZJO&)?0?u"JJAL305eb.$dPRU3V/!\#5ZAOsD'6:Z %A:@!Hd%Y506oLr/e0HH`;_F[IQp;@UR=&X>i3#+L,N;,%=pdOS47AE7ifsX>&Ad1-$tgJk+=@e_Ql=C1cW089F-BR7H?rH1$$F0] %jAJiqps:MW9DUf;8='0UR=_)C7^M2MboE_9'$B2BURihYFHj[DKNbmc7\lekV9YU).?&#FGg^1]9^I&#*Mql %TJri/+]!Btd84:Oh-ijACugpp9#M_ApTR1DrG'\*!,-B_eu-%\OnP.dmt8uk8-AIb'EROHP6k&;F-;DU'\0IP'MeH4=MJ2=@*B]u8O/Ic4$BSrEf_F@p'@\?j-%XtS/kmGY0?@cWr %9Z\/-fP!9jEL+[5i`Jp!%2t-VH>Q=l[Kr#/)9l;Rn-OEA9#IGt0P^S,:FAEP %X`>cU1Q9Tdi_;\\H0lq.eu8)C,g\^)7MN\)i9-sIfT]2,oeO9P2-.o+TX#aEK:R#HJEqT>9\MO[[Ke2olJ(=:BcD`:X#Y#X.W[+E %g>"J6.A;N)!^A#5HIL5[P2[f4oMN&H&j2cpXYqEJl*IhIWmOX2J[UFi-G)s8btUVM9\"O9==p&_6t"1b3`.5;,`$+fVU7R9nVP0d'rMgi!ba.Spg;`&6M2!MG7+gF3qJ1/CX_;;SS'H-j`J^6Fldh3:`o$R,p^#Pm"&,HcYe %0k:g4.OAe`Y(b))/fSL@&"P;%en6Ao%'#4a28[`t3'EeAPb>#BAqX)7&h1F[?VTK'e3Jg,fI/p`.XMedR0#A(-u6+r=!O91qO)MD %Kb'FopY@ge>]_rc8.jPFtbO:)&+=B'np*ejH7ZKEDVH&<^;-"Qb6B_,TF8Ej9&0sTt0GM1n;ajR_5NH*:J&or^ %LCL5,pRI]j5BTRsRk\j(2Ae#;J+IcMNh(@Bl]1#\#TPo3$RaDr38I/4I0HnjQMm:s?o/2!bhHrna %gkg\krr2obNt9idO4ST*4ZsN7'6DM"iRRD3V13K;r6lI3rjUcihm@!%rPJOrq:A]_pri-OIt.L\MZ3P(p#Y6,rS>H1&+BCNcVArg %pY21Lp.qTg>7]=m]mIDo'.$`5 %i<`s8V[(pkJ)Gd'g7EfngFke+q=^;90AVg:\:4&A&EoNX5)(Y$s6ia-rU8(ZF#Rp_p[>2LkFa&*<6YMoY/(bGE+&)UVc!mcmSDD5!rLn!Wou4M@odQBpH6Z(Zq:q1AJ&rnYKRe\=7PI/D1]jV@sOAfT,NN5^fOID>gUlJ^amro*)R9M[k,?9#R3rV$6X %p#@r7iF?t[Q&-mGrJP#gI=:\>d9ufA##dW&9RCMj*"Ad?_6i)La5.b/?U%dP/c+W(pXa?pT7rr.l2pCFnI%VXn:rV#OI&+>g1HpG=;L9q9( %ZsDPGgct`&pYRNk47au^LRTlcBDU9N,l1BOIi9j-p>*X<(RJ31>[D7>'ipoTL;:XSj(Y"Ih9EpVYQ+UhrS?#[(>EEl(S?.]>7^&d %rpK16`K(nfoSZ)bnk\)gro[,&rR8,JkP*IuDAN40^&O_&HiH=VW!3+hrqc'QHn.#Jj#Ghs^3seO0=u %^%qQ2WGep]s*/OsW&bpFY24Uhm-Tg^+]5hKeV([hGnajrVe>_.lUu!g]^'Ggc%Wod/\3"sZg1i^ftT\jQG%OQIf/@%l>_a\qN#ie %*KF_,,M_A7+1okkl$djLnCK1Z]9fIN]VsN`GTAd'8NtYMYtZKl:E<-$s7XXBqtlji5$VClcdON?r<8C\Vn^$=HHD[=@S)S>r-_Uf %[d\P/lacM,fD",lnKIrsme,&>aU]2+Y2=*$O7:pP+2jZ7Ru8lXcj+-grU0[DgMcLumf3-jI^22,rt_j8I6EZu5XNri(ci^*a('r! %nc>NS\*3_G+%4jo=7,6[2Wj?ai!JpN=BfUb(r3QdUFrEBan-4_A[UZa`6hcrpd,+2XlEFPlim %db*R-hHtBM+^]Lj0:oXW@f;o*jT#&)6+O=?0(//1DSEWl\[pS=A+Zl+ZWd8[ZN3Z*,P* %(+Ft[RB'b'G1"bpnb'fum2!JKIVKD,-BIn*SA4gEdIj@%D<=%>JoX4"qXagP*@D:T>WN@L"$o %?:Q.K#KO*o+gCV`I&=)jL]h&=T[8_jrmT3j:RT"J!7Ur;3q,fr5CCJXc[YiRYF*;ebFd4^GW7Y-$R+on_Q.u.ds-Vbn]-`**"T"B %+&McX5TT7np%69d*`0lZl9GlY?U$B`;1UdhoB?E,:fk"2O2o`>Gj6AH8+l+sO/Eee4ro]^j71V^T&sIA07QU,_Vq"_a/\IG*O>&B %.K>JkjQTM`GK<#<%f,/XhlgqsG]WDmQNs#^pM$[7HtoC+i?UPq'U(`[q_hQ]fqX=EOLZ&!R3,1/CB&W?C&e.5rS@JQce:UR*'TJ0 %D*^R/,_S,i6>VqHYn(?W5ig>s/+$S%UP'o[DtD5&in2/AK0YDi*H4a\a)S/Y:oDp]orjfGD6_X0&D& %m]1*9FRo4cg,YIC*X*PB=8qD>/1206Z\Ij#fOt3V@%?fIqbYl,R(XHb6J2e8`+0qtk(lhVXVC %>-kB\1],htV;3oq\pK175Jal;4K'B9h:VN.ce"aFaC&c4sNfMefcfX?aeMS:!kB&[J(I6t]@S!'U"`ZfNqX(anQgJ%)GS,c$_tI0AQfbO)@Q_6uIf9"ZgPrn+b@:&Z %c[[CqHE2`R/mLoN`Gb(OL)]h7Ucd5(InSdIkp*a3jQ(IJ?,ZIS@^FhIYHuAM8R;k/Z_1H[DH' %X^)q8Z=iFu^>++DV[V'g;i<4hC^BTa`10\nZR9ok:-tU-fk2OYapW!UXMdorNP<#.Ck*R!u2bNAaCe_sgi(nT*I/W`mX%2II %_pt7D!c-t2Uq3cZtqU1'Sn+tq6E?"q/pVT4Mmem05s$\Bqqskak<[?c,5/GVVg,hC[e>8d#\Ho[SJY(m'RV]J9 %jojN*")Mt5$b!'#$:nE/+3YX_m\d1`a&qkG48-X_k8+$BZ%F"&.n %!W2C-Nh1c^d".r>?jCKDnR"p[7_cm/qgH%=,tkfhXet]DF6&Y9,Ea>_R5X!Bp.Sl^MaG[.<]0S_;c!eup1`Dn!6bpo.oYDGQJ5 %5Mg22>0kDs.+qa'@bUdA5`-I529ZHXtHA4"+_N_Cik-BuKPDU!k*;*61THM?pZ]:66e&'o*9n2q$3)!1X0'`K?+,94CP?#BUS %#E0jqNkmB8Eq^'Z;msXmfN0'?n,dPsgPk*I,TGH7ah`"RSM[)Rn`q[rr1/L+"k!(f6_9hD=n)+eS7]0^hVS8 %$qIA_5cppNP$%JOCj8PIp'4ski+_N@QuW-4&%qXJ(a$QE4u*<^hYuA9`df:Xi28ei[]?S@I'gD9So%IAUgaBN8?4$2eWne1EU%q7*C>F4]B#P#O.*WO2EfmPl[[]V$gYG]mY"5*LGl**m< %VkH1jh`Z@8EI%5rji(7=a3)l'hDP/:=X!,!m/E"Q05k9/XT)Z=#:5:Xb>5M9n0]=%pYTeN#CWADW));p^3Sr`=,d*_XZuQ'A&,Z9;n8(>l=qrpB[?eM_0bjtHF):I-A;f=j.mER\*^rFiihc])sE=H3a3+Y,*Nk^dg)=S;cI %EU^-f+'1"A:\Cod_tWscpX\HkpO6anmCM03?2[+Z@8ABbIp37Kcalltm%LQO\"uUW?$H0+lUrKko<*lIm.qKEp2A9^AM5+-+2>A" %g4nJ`GaBH>ZB(a:mHo>1o`mK`A^AftID*e3\:s\M.bg]`a/eP,YHl(9U)p@SmDjGG#aaELbl5ZK^]Al[-[?".8/6Ob2.Bo&fua\5 %W&th7H88ZPA6\lV&+XZ+Vf1Gph`.9mpda*hH[?=9PFA`d[.OCj,,e@'i*b:!+P?B'aPNLY8"eF^D=JE=])5'h=F7Y7g_RknO"0Op %>ucCMqWd#uf+0OMiU\dANl-]`5$iWE`Q7f-=mo.XG&?h)s1G0iCZXO3MGBD9tJ3dM=.Iu?+7lLUL7O0H/*a.i?kkM-Z9pJ^&A5/tcq<5julIK!G0 %I/3*?2cb3W7#<0rrr2obO0&^89fNmX0]%YHHa]GO*\XiT0V(hnOR=lm/E7$C_s>="kd8a!P:*&RS`>f-0"&#?eb3eta4I;MN'#dcBY>^#lTd(oL$j(%4U]I!S6XPJg6W^- %MsK[G9%!ouRR_XkMDcgYo$u@A5]&`,K@a7Jg%/:8u3%'n@T>A2^on1f9'>nYs2+\m;.J.=i*FD<$ %E6#i]_55i2l_#=YL+'6_m>LS[[TA18gA`rngSUB"hSd=t;T=4fQf:EsSKG7j+a>Y'E5RK'FDWkKOP$t%j8!8'@WDl[B%DsqgX8.C %j'<7:>J0AlKYbbk#d:r6C3-iR)$1S:o9S=9qa,n[V>9;(k%XjD2Tg7bian)d%=QdqdX?iCZab!:*I3o5?4A,eE[/"p\g`\NdD'e.Tfj:YN1n*o&Y7pT9ZXg;N=IXO_nAd^9Iq([2j67h<@+emuZ9B*+P'`S82?3[jj$,g%.2o&g`Yn8VG(%$=W"`,p@Db^Ht\t]2!:"G0Xmrc=.@Vd %=&*S$7"=*k,6bcPC0Oa:Y')rg\T4]T"8iliI76.^`cdYIDDu2i0\b!s;ijL`Bn!S8,&#f@CV]6`B_&NV?aL(&<+!=Ag<+0AJ6T^@ %g7(Q\q>@sA;prsF]RI?O[TnQgQRcui'"4Pni?!ksRV[F$g.D>BY%_(SU5%Bc""c'QBq_;l5@g65?[S$e<(E>sk@NE>]#>;%WL\5n %8-aF,Ee@!C2aGD<%j3c!a%,P_D7sCYXdtucl&1C[%rq#&C;"V7QJ+p3\-cd-G79> %Q!IL?[[eM.:VT;TX5"gR=Z]jBc):m/>b#7b5'V;52TgTc/NoZX5+qL'#H&J]athePSI]uoEit*MlJbEXoi0H]]_3k`912f.D5G)= %Hmed!U85."g#`a%/$!t\W,eFlegBeZWi'=l.-jfZXO=(kL?iI`%C#51?[2uVS=Q=t!)pkFM4:38\oGr^^Hm32'S\Ti.W1#V]?U"r %itLTRVlF$e;-rAKTTO(f=SJS.e`n[Y#-/n(It?*4=iKc59f\(jitA7o3al9>K@1ZOhe4@$]+[TFB!#`#i%=kGX!+7pu+ %Bpaji[e*PVp0!FI2Ta7a'oEY,/%3bBe(Pe#FE-Tr(u'0(bJn]l%s\R=YIXU^L#-VJ0.4,/G]ZXpD:c617!gUj?(S4-s&kXAP"Z2NN0.KsA_Y+E>"-nAXsco\"C[kV@7S23AHRC4gLpNfDGoc0VI4A$J2OI8Z5$=RfB"g89XMn()XefsuCP %6,!FS<&)LMOUi]59JE^)g!73^pEtC/ZWHI%hTb5!ijJif$Yh^,5O]8YHE\Gg\`anupXkm;=K2IbSPnQEC!4\dW.u?C*n"^sUE8[4 %Wl;uQI4'eg';pd!kcuLCONl.*I,9^!^rC672RdI,`)SDCVR0uBhsI.YkWlap,>V_]#!,+_Am;Tuc^f7?2_?QGieW;lau1e.NnO_S %.\`Hhm9K.\D);D!G7'a;_.A&'>rk)$X]LX-qU(Ed&A:b\V;%Sgi7mhEU;\t.13%5&:KhS^4jNr1#m7;/m)Hk%h+WA>.V[CNbK&Dj %mcE6L??oUV.3`TC&$.A02f.rEhii45c#;VoSpM@/!FEbZHLA7K=WX:K/d@"MHkWk@IT16ENM^TMHD+&i&4+#_n %=*::;&DU?uB;0Hfe+tIC^8\JV;KuV0;>?pf\e2S]lYW9arlj_+U@6p,8jRWKU8>aHYmCZ6S5"!<]d4&@e--ouDBLrB-;E-QjS&!T %)/QWCSHoVjAGH@FA-4n9RTOtdoXS.\WX/9f*dq_U*A:pN9W.tp73e+74pK1XiRI;%NqjfXGk>_u64YB#]r*:*Hl<ju:%2"RrM2E^!u %+`DuoRRm#kptO/3lF9B'%S0um2JbGf#DtJ0,X@&GGcTTSn1/$*dY3.L;^QS?KOUI\WGV@; %>,EpZe]YWu`=<2XF^ih,jqD[g68trhYTK$5CIo4m1NboJP9OZ9B\$@XNYje;BMI`Bkf&+-j]Mh6)/4D+ZaW0jfF3k!\Le)'#NTtQRVKTE:&k*ZaV,(AOZ"efFKH\GQNu=O%Ed@l% %/SPeB[d;Xb'#aNOt@+pG3A %JYTRlW[[l!gm3%&B9D+@t,3MfjdE:7,Z_7MFGKAo/SuN[KFDDE7/#^&sAuoQ%G(GNkS^4B)N36Rg_m/^d.ub0/^[8X/jLXa!%J# %,!WUD8R#6-0gROsKFSQ/1lu"bqh'E?5#p<.?92QKU262Y)Q4ZOc8JlD2e$B[dUOcGnM`]@8@S\g.'JWqT[kJdk;6(E2!LRWmLe-Z&P!Y:!^dT10%0DV67C#:7T1"j&.=dVQf(gM"#"pS/4D/AIDiUD:h)=='22+o%E"%g %=iWrLWl,&(WckICOu;Rd?mi?j5Qdh]M>)P5j+UJo&k[85D@r62d\R.qO<,,3R*pLjDmV>FhqG2&mCf9tXBLe@mb2?>!0tb.D8]Cb %&WB_koU'=&l"A@1QJ;VGp^plf[S%'W%?a@QLIu0"&>rE1bVA<&*1Ws/,AU3HE=B,Za^$PpQF>B!]b'9s-[RFA4GFR\MBnCcH)[ho %Q(WJ8TOWe2m:K+ph,FpB'+*Cnbf_dHD1KPRW*"J(,g7+(%h?Wf4+4Mf(`eX\Fs"_$Qa!LiD*D=I>'++20k9HiQLu?V`[C %oZS6UI,o-e7LdV):KC41Jf(ut]TO'5>3nC"(]$tQCZ+S\U_5C#bAI\EVCD3uUoLZd>0&S*k %@0`pe\VlI*ht=*4b3%$-B.uE]a4ean?8)Okb'>s6&b5W>TVMfBI"gY\^uA9`+I"IeWPtD"8)u@G//I %h9]ud`$V'Mj?"O=Ukp*GD4%mF8$tnr45no'M;=81gr)t?2Juq^FIVX(Sa^JUnTR7.aVhf#`m&VY%nF0u9(Ck"2nSuO)!Qc:Hir[] %s0*0j9pWsTGW.1`%n=4bRJ_=+TlG6$QXf4QH:*h7:5JFLL*[1`sebsC%cj2jOP"NNl'@g>8j1pIE6%sR8n %KCTQqkQ:AF%m*&J`9,\YS0q%t!md&GFopl!'0AMP6s8CRUk^:?JE]W=3s##Y/9ZR/fs9@clTtHBJ3=e.:67VQ@MdC_['0pScXu>B %JU>kcmXY&m+*N5(8IIT\pr*0f$,S&jpeDqqBjq;aT?P4`5X'"^%u0Yk.J(A`5-2.4i-`tk:4PNB@L#Gr1p@XlcgI54L\5(&Fo_6h %hX,mk0Zjo]pYcn`E.FSV<'D;]#LC[*+?t*NGC]M29G>]i4See;Sc%T!\%hof!VSH#)'6',SQlfHjL`#_-Z?c1q"F"6Q9"sDV*4KS %qeu@]J,0,us5I\I+"nZWY9*-2nF#i/qX3W-pCCVYqf))Ce\ga!Hb$E>$%H69dI*>[n#fE7GQ71"2tnhmG01uGe94m$O8eb2R-NDq %`!0etD&:R0-E/LmrBDjYD'PRlZRLurRE;EZ(C1m%@T&CDN(C/s0o'1/bjegJ3f_gS0T.8F6LPa\6!KB9#;hMDLX=e-jF'A3+Qj8" %gWkhR6B:Y4:J(_G<7W7&mrShPKafc\?FDKI82C:d6Z8P6iCJS-6D7'QWP`?TNJ&^E)W,sajF$K55\ %I^oIgG_sAF\>4djjX;DuK=1>C!>@K)]>63fm0ZUcM0"bM,VO?2qQ-`,2Y(_.F5Rqi2#B! %**?L(5_B49j`Omf*.T4A(/59jI\Bg,_>u;,#8J(TjtpgQ#W5d#^GkbE9L@?QCeONn["TBH`6g*C,LtE`XT?j=,h>>6[>H-3hC<8b %'sFPC$cb#kO:`e:m(;?f@^aTPUAuNDilLNtH<-8fap%qi`(e>#cuibji+8TYO;f;P".[o:=oq\(c72L7SCiCuHkL:(Pa>q^]CKpo %WY&Z;SR`G42Y+3Y>015/?Z&ie?:5Qi3f>8I;#2:]gUba9nhgTb>]_d,$ELXK($fK\T2DdkkuWRm:Z*=u0<5_#Qd-5^jj/0p9OVO6 %Mbp*sFYjdVUNtMn6jmE+-&I5OFEp9eX(f@h[Uqq[/=ElMOQL$/6*%lRPZUkb_X-Qh#80)Vj\`+_8K/\-2&ZY!`CndfrMRJ4$!`C- %XAKp:fH<%O-*gXkFa0dOO2Fe9-R<\m';WjfWsB#5;-?R>^Re)V'?,h??$b]CM?+]Bq\lQk))DeK=p8"L,fk#KJcER.nPDZ\3T\%@ %44O)k)3\[tZW]8Ggq\`e'0/:3aS9c'A*XEtTW+t`DRkSqA8sXi'b@U%86qIY-K?>k"JK/:K80@OeV2fY?H$[&Gd`-T_D]r.iQ6`@ %'^X-HB_d(`7"g*&:P=jni&thYPfAd8AV\'.H\fB4((Fho?WaIA[XC-%" %@&T9QI?)_V;Y.gc:"NKF@SaBke1&EY-l_,!:OE;1=n7qr`1pO?'ai:IJ<`$^U7D>OK5j6s`U9:_&i/8ir3"$,MLhG8/6TX=2 %eF4JJeLmi139%T**'&QS*NsqKHVag;4R4DZh/K,:bN"R\idH>kZ4BKq3j6RW_/g8]lSo %HuFI#/CakC9H8qYLTCc>;"A^!BH1u4Z%p5PhuIXk)/&lGk?r6I!bJ8EdK/Gp2R/35"-nQ$n-TdQ*"Sd`,:1K_p8UYe;Dtm,S`jRL %QsPlT;1tGk_87XnPn\K5O_)sNj/C;428h+t6#`s3ZH]2Ali.j00R %X#go$8/r^G3)om5M*0?M!lEHl0p5G=H\SbE'!+b-0p7[3*'QeAIE:]t/=($ZDg]8]_cmlLD3"P;$A:LiI %QF[T@'e&.1FB_0LHO3G6@hge^"-OQ,Vd2Gr`0?#_TPgK3L]h>HnS]5NRP3Z&'@Tj2LSa\E534JLD+:Bn3BmK`X\N8HoJ*nqtu(Yjt9Hj[LTP!+i>F7[VMW*%&mQ7W3"[C2t=$ %/"bURP[NO^a>im^=L1fE&"I0A&<=V1cGdm%.$9CQ_$6;1$dW;!_=4d`!(`S58uA6e?'[FKj7hoj\lcXDPJ=4!`l.5t^k9nR1BD^'l]GEZKHKB-]:s7sB=NFL,s`$/aMW&fn[nHB4D)#tHFR^sHEOEq3A %>Wf/7oWjOOKYh5rLAn!YS',d %Z^QZ+PDB7h/4M0SN6&OTf@%IE5D&373fd54M&Q^hO9t7n$_"3IKVK31;aqao)F2TGjmW/&ZH*?/5^H>MYu%h?W]EHm7E@(.3]'Z1 %&N@/7:q[Gj8jX7`nlVl$J%8D+::%oIeD7.WnM*UEgpNUUi"*$R$3Q.8W@mH;)DGS2Do*cQ.b_W+k-L8uf=EDQ+;CL5PD!k>Y'8$; %*X1(Y#qpG*7AkA'/8%OUR<)rD,;%&2,-.3\r3L_6?(?c'T4RY`#US&068Y>XrmbX/iN*9JO?GKU_L7N.c$DYbaupViNt9oA]hVV[f-<)-`<@^ %cqEMrf3uN[#T6R#f[OI!PGoZQ+L[+sn`l0U/AQQHbS,gBs"P=1&H'jhXQu!.DjQP5H+aFs7.bK-ZS'iJQo:II?bKhFp& %-7hDN-D;8k,iiJ"LKCNNGff_bm=@_ck3a+-f/J+&=DooL5=LbB0q-V"%m-fug$pXsla:Oei.,d:GKXFtPLG4JMW:WlmZTTN`2iJe %=L,k]@KqZh@D4G$_8$c6ZZNS^<,gD?#hLu[lEe(DV9m"!G9)Ln%h[Wop(5DX'6/&Xt8jZ>htB*]K>_u(oGFdZg/:[7Ijt<@pStfe!!cUDO7C_ %lKg'qZuqmU31J!!NFS?:D#$*%ppjV=2FLY_7\Cb\<2CG4??*f+p]t[br$Si:0FZs?;lG5?9\Zf7\--[ld!MSoHI7XIYb7d)PS"2[ %Z%P6gf&ZRB`NumYXqo9RSb1X(:c0qK!:NhUNJa2gbug4H&<>5GIXir-KJ"R!P'tMeG7k]dcWq-C6)SK2\uE-_Cr3ge,Li`4(b:8V %$Jhd`1k9Q#lt(h1E@_FJH8(1g4i#6AKPQ]7=WOqakQLCSXtI["NAFN"!2`oJpX&?>OF-KQ`j;&$klP-*D@UjD[&Ztt64A$+3#h56 %.dOE:M@?.71F02X:0.k,a^WmZkF"E!Y`hsp1r36IEtPqUJjcm]g0^7R"OT)TJ6`<=1)2DqG-@&h-^FJ,\5gLVQB>IgVrW^ONYjJR %%%ISQW]QE_Sr!\Q*22b9'E9\]ArYa+cpS;-M&UOhp"=I*MblrSlq))Fd%(TtRerT]4^&]d3U=M=O9)U'!npZKngWUY'UV", %6t]o#P)i,9od?dFIXItp"8fp.s@,u&;];fI3/54?6C"Iq4#2_`AptM$+ %IbsG_:h$0/6HKC;"Ns4a4iBVoP@'@&oTF.p'p %^e[,Z"MQ5"SFTp@"qVI!b9VJAt8",Ztom9[@Irr&ge7-%biC"tHVU/Eb>S6D[+S(\/l)8;G2L#[BsD_"h.6-;*"Q9)Jf8 %_c7l!<1U?$8/6q$V+A3Re]SLT)P:+M=`R%oV#5$81##<:W"`A;5/A1T"d8K4IZ3/&I5ZjLLAF/CjnDfo0c` %R`&*W\n5Nb9+dcDbLMY@C5S+KE!EWO5)D*i_;hjLWuU2eY?!hJ`9Ta*?kO6k`*(kidfc\DV,nEQd>M`'R6))&.LBkbu676I1Ps^\$*_%7hVNZnC15&24G1cMBFRc)Qo1B+[=JU#3(KQLFDQ+0Vkcn7' %EGj$u5]KTc_Fa9d^)*[PQ*e,<-j*H5H6U0c$Rg-ga-<,K(L-BN/l[WA$)=AHW=TM0\cIZ<-K^Dk6sg86-DVsZn?'Q8&\agS%"qn& %7SP%n[5s("KK#pg+NWOIW4\25u` %#G/_Mgs$(l6iMGQm,O=P8nLKTsnj_,JTT5&Oci=nW`(X'#20iAD7Adn!k#N)(Q#+,N3MTkd'.e$JCJP'3ns %Cs:m(SLF>LJ(59UW<3q6'H,M1"DGXbLO&)YK^B]_Z-=.6N!:W6\p#WfcQ`;>%FbV)F&b?K<(YW2e$S?$Jb<]@gpCf==:5J-g:a$a=jPtNS:HM9-")WoSOH;a_?6/>jaroJro:qqg6+e^`_C>k(X&k2JS;4c)_!Fh^@\oqp %0cNI/mPNlWMs_Dd[`mk8?8ce,"u!a]V+m'qh#Oes-#0"CO5Q];dOBaZRQ(=-XG0BMPial(HqI=r0\ObcM.FAX\8Z=?G8N %^bi$E"r>!k>p.oJN(Vqh;oFi(8scQM+aYXF'DUhI/=NPtPP%cZ(m$*[;sa^$Su6XhSp2cM(jm"T#<.:(j/Z?=SomO&\ft[,1)a9D %s%h7*LN-"*X]m9.iSK!+68Ne='u5?"1%RW4$OI:L01-703QY[Y9U:t_8o(ar\"Cn0L[_o5)cH(/dhR4NB#.>>Je4HSfT;<53jU!S %P)$Sm\mk-.@0o"6ipO.:BtGRZb[=(0St!r05jB\@(!BfUQ+>:[CS&Z#%/l&2j8;HVD8Z;&CJQu:4&Mn@#WW6%pmN^Bjp[YIQ0FMj %X%`7-1LQrIjih^BKO]#`HVki$;ulM8bVSQr7@[!,I+J3`[_X+lpChZi9o5Se)`"%uX]S,N;l-XD]%Wu_fDQ!E[:+9"S:98t2[PHe %Dt:97'+hcs69rj:H^h8'9aLFG!OM(3liONF5hsdQ(\$77LA+R+ICshAR(`Q0TA80ATD,DfXY_fDbV.K[Y5-9.0+dkV>HY!\T)JX6 %gq_lUC,DW:fr)34U58lTC3BUIoSsh&iToE"UD1rg9IHkA*+[Zb:oUTX$XOI"&6$-hn;/9T'-42X=U25Yhp=5*`:9._:;V"h8O.Po %FVr_:B#P/?_Mqe)"L5O`&'6QrnN9]*"gN/YetZX%I*Ej>/&EaD2Dq]_L@;+2UTk],6N`n7&#\p]q6qpcR9>=`8cqW'?O8el@?T$A %/gMo6&4TCB@#bH06LtcNimX1&kq#*"jIjt"7P$I'WB&iD7JYT5I<2t8oX21=jjX`GV49#V\s+VLOAqF[-]J\D#W9A8(@VJkDE\'G9^N1sEj:b>+8haR-8[<6[lN %E9bR(m*S,"M9HohC.&uQU^F:n^fJBIcRTG1,%aQ*=/k\*XTp()i061a`DQeVm]'*)*&3+U%=h)a&f+K_CC,WQ\tkZWHI%UFJ.&"#5gN %d$92=;U%QBS'_9/b>\A\PLWE2](9Z4B/;fQB[P^iV7##?7m+JPf;Y[Kmt[b&m4bB_V,Yb`h4=Lj*pb.V>1aD/<',e?s8PW:G9'>> %>tOYrnfP;fJ3&La7tdCb/!W.7(cd-tFc1GGrV(Mu1aA!o1:n&N>*bF,L51OKk^44WF^J,f8-\_mZEUNHr5r5Yo4m#mE(A$p"??Y\ %!bWPdSu<`T8#F2&:u(uC"$8Y9^+!'A'jagAn]8%lj#2,eLI=9)TY>"@D"hqB/MlF.#nYMmU5aW#k*A@FouT!!UISr4d#m9K=b^^H %GOAQ?3]4qdqR&-B0=lW[UR0YI(@j@1X8>1@$A*[*&U#^P&6>`aiZ1EUNh81*V%&4aD#'mZ'!YrJurS-5KCRd#$8Bfa=e?>_R_!cE"H2&Ic:SoC<# %q[OfQTnp"\rMC7J@*hj0eUpefZVa',_/:pc=!VS_=m%p(:W?3G#U:+_&]qB-N)e))pWsR,U4l:D+_s?I_;1&N%jAJ-$Jh %@u,XUDQ"\ZX;[lOWBGY=[ZfSB,qogl\BeJs,t8@PJ@p\.1mj^K,+4QH7i]G.S@^(nDNL%qnd_@_UX7),Lg!Dr-Q"2 %0ojM37TO[CB]Y3[O_CB^\Q@,B(R?:k02T(F=1^prdBa#*'.A1kR_/:*Z>.M!s*#X&B(6Be0cIi4!B/r.3+4AuD1n6+7qaI`uc^0N%<>H2Y(t@+eHTXmkjQ'@\7LZ!iG>]9G%E?OXNH&A]ae1o!H)N=RPXZ:4_[ %]%hSEQ%?!7DhT?B:[@'Sk*=gGZNsl,T:K]g2@JHqDr@'_cA9p]Hs/pR`mu1g.4(_Z3C;nuge6m%Ip(82CgR@`mV?gcEa&5/4>,/)U4L5hdWf %mR\$TJe[,DkIp6_L$8`g7+h^Y[s1P2]5c\5#l`0.HY3s0@5YtsLnVA2A#tWm!PU1[gEb_E;=criUUgSV)-D3P5g@r8>>OW,& %!eS]9J=do>S?K/[bZ^jG)'1Dmr]4teJ-*%^$YrW36!Q14*!6+aK2Eao87d_%@Pg]S=Y>PgcO5K0mn_EioF!mXG^(&BE.X2*rLcu.g2$"62R+iBI$iWea?uCb2$VD44ALu@AeblL:`;Pum;VD]Lnpc$Dh21V0 %d]hUo^UJU(a\>K06+?RfKno'S'i\0lPrs$fGWF*J?Qkm/-oQH'I?_B[="sK-9$2O@YE'RHX23(3,>Hou=$E0/q[:"/'oNsdnZG'* %Nu`=.1_fr_-IL:2\u$PYq/@h[jhlSTL*\&HjSj^N`?E%V3_pU#[jZjm7CpBh/6?&RJNdMUp.Oo<8&&1M5%4_Ahj*LCE_Rq^;,O*i %'0h'7(20s;5?c+g@7GYb4H'.Qp/m0ahGXF6i!>)lYts9[28n(:7iY&hG7FUs=/#es;sG]+s,A-sB7^a^b\#;H_+5dXrk* %/nnlIQpr:)8rCe>8(J[[cSBMR^ecF&7E4>tCst^qJJ#SaYsT4U)8jCrR%(>CN%.d*DE8)BA6N6\)[XuO3?Ql%C`+"=qV!@kf,rRi %4>b)@N9+TGf:N^-#4GffP"$auW*+XhncVQaR'_RHZjfZ$GS4*]e;=p_p+>uYR@NrSK2`_o)>s](JD0fYjZ6M[C9=<[ZcrQcD-O2? %)^iI9P8._")7id^JZT/mqJobDfVu4_H2ho5[=u%fI+6pm(DV]9HuREnJ0G4n&%Y?7q`9 %Lalk`9h1rnadXqF&e$GJ59,em+#?#UW2?^ol5qThW]=2IC*p+1d]k9sTKkJ]WSg`S+dF^BA][A.dYr(kOLY!lr^)a8@KpA^I/70D/#Ud[D4/aHtQ/R^>k]5^HVKB[#Pmb'C7r%D40k?H7L+n&`BaCM[-qM %VP^kN?0L3RdhTJ#$=o$h/Tmsp3n3QsBp%@l_=^3M8eh7PXHuY3AWfLY=HBu=X%_A&'[50W]Cc$YL36)i"G.`q"RO+_6H'kbXA0NF %+WDlQQ'Q9\0GU2aEW[+%Qc=W_b8HE+)Z)IkKk*X1>k-,aF>f;MOi\5#JWd0UaOuk!2jkO,?>];EUaf73dB0OO*PVV2@A4Hs#1C49 %=VPTY2C!TC:'hrMo"%\]6:0"PqFI.np5&C/4?u6_<&@1MNh\.0A+DC_1L_*C>'-hY<3'$HbFW6sL'lgSft-aVC\k6ld%p %d=XNtJVUb_C-gqO&?d.T%4llX$cO_FkH8#E[_\Hna3g(K[3B=U$j[0I3@qlR=VpP2iFp2ql38D;WB %QU*0'\[EQ;b>"Ei%0a %&/qU()T=s`Z`MDAl/V,,\QM9K"k9DMhJV$GFM"tJ\&[QBmGKeh[J,07N`NXY$?mBrbBW;l;lkAV;U;70CWf+.J<;@0B@qpF=RRQ6G-M=]*[#i//1u)+nk'oc:cJdQ'MN)T.PMhL;?2+6g9u=S5^Bh&8T\q*8/'YRZJ4-eGcVLP!f9/NAP)!;&e]M!+9+!)7DPdWd#h$NZiYM-Z[S?TSBfZp'?/E$gfq(@=cTr^="[+kcSH[%Lui.SSEGQ^Gb_#L&ZM&FGT,(+b!@qf?470nSLE[^neHtBkl;_&bW>>t]_T2=Uc %7+GY=JU@W+P1_Qf6e"a7M*ngtKeFXuX1kIg^Rbe0)X4=sc_;N.:jF4l`+&T!5OYP6fKtj+.=LY$BY0H-dd,qQ6Bcomj_srepWW[=$'a41VN/,I(U$Y!ZHl9K]$r=p9k-fD5Mk!5Zl&,iO1PCJ/Xe2L@a`+ %%s[X#aN,-*NdO7X$g5uG%GJD.Wj,:d,;Ef]RY\HdIr6R(GrEVCA=P$dc1Jj>&iRJhbtaS>!O6&Zk'OF03Eq\Z'cGPbY+ %0:T]8$`;JuDZK:12I'.O]\4\_B*[$Z8`Y+d`tJ@tgcdrSIOeoH$Vmj#Pq$27^qn@]'u0kH98JP&\k@%d<1T"7eD9VdDZZ_O#nX(PGtC>t0Z9^#IfkjC(*uR$T\sbCU8D<'Z\iCNf8X]6G1XZc(UXT8.b1K+/<&i2%Eo`fSVVGSB.O6_ %SSpr'fm#f@kVDJ4.4:t=H5<8%

DUjG/I%`SU.133j=@H_"<%,+YBS_12j>[`B'>i9]Xe7Qa/lHg&eela^r4?4&ga4F[ %=/*Wr.jYr?mBrXP8<7iQT!XBiJ16kH">\-dL8ED1BMgIf86&V[ %/3Q'([+%[W4<[PTQD/+oo[B$H>iqn`M#T(f=cGJ&2o!gUt#'lD@7E@b&n>IXRESC-gZq<:5K739B"ob>;\8\;_KG51"59?87q;Un4Y*C,50=%oK4XN.RckOuT>+o.Y5& %Q-*3Y<=.VV#_$%NN@J9f=,%L`!;U+,%PS1eKllrYAqF:MU`D`-A8*t:Em9b@gV'kD:m]1i+bP;X;PVbQ7;k@b!5IKum5Z:j<9n^INt[U7"nY@M5;,a)RHHQ'g\`ZiN;*>326q<9S&8d8TQc %F_LSs@bfe"[;0*.JcT&V5^LNYVd7]EfZb-lgd)]LCgLTYF%lm`J9h>R3ntPR)Y7V^6PKpj84T432M[Y=k?mXP6Yu_oeo;K>=\jP< %:TDn4N#1h;fBTKU#7O^e2KDj]K'Al,5']BWY#'o7X]U<@ch`nqp(29?oID2V:8/gUet!1NX]B=\eAXDp\<)1i\Ja8QK%4Ch:Ir(8 %?q;F(3YirqXG8a3.E9oSb/tcGCKd8uQE)(J4MthC3:6H0P1f)q!rSr'gRCDcrI.UY9,TT'k>Bai53C2.g;*CDZJDK:\.j'?EsP'74!;Y%bYAuKuT,Mk;%Yen<'kU=6; %!Am3!N1r.dM9g7G'qk0ba/;Bc=&B3+o6`cobb^.%lHh<>pN/X?.]aKLnDE20[GW/JKOK7T==35&Mo %a`eFN\r,65@QRIa8:mG_2Gr@/8>]UH`l>M>12%nIT"0HGkfRO1R3Uam9!B=K7Pa6?DTs6AllI1i#2D^#SgWY9F_jdA`Ml`li4<#'*a,S_M_GZb%YB]7GLR)n1rB;S8:>#7_Z-toX--:gY+9*1l_ %[PlUA%otiqi0tFAac9%k@'cM-[DbE!n6B8#i??Vsd_]r!N!*b>gSi'EfJGPB6?^rAG,ch?L(^L%+SW]EfqO=o(S_u2_D>?SqY;/: %XZ8f5)hCY9a@ghW#rr3BaMfuie!9?Cg)X];mA&sJEZ>lFFNGC^K!;Cc*uX7BX'N1Zrq4S/*(=JC=O=E53suCO^U]jRP"aXmRG_!8 %7B.W[2!e1#guXj8HL72_H-3/XNHG-OfP9<53gt0oj0S936S[Jq2X5/rQh28N;Taf!'iX?+6>ja*d"(ubkSjB?eE?4AllO.P904Tj %RJ3UV\t.@l%=kkUAg^!.I;g&^LDV>t811tX#6ngaFXJ)8U9m=mKmhn,_*Li\nCW#u*/E>#NL:n5fWhk*F3m68D"CE=YJuR1bssu> %LRZt^e3)cO0\=#hnS;33eZf0KEI-A\k_1oSgLYZFS]Nq_";lhKFU4apE`X%tm,fUM6Bl44;@"bLK&0d7b#dM!njmaNW'< %^%XLSZkZP?r8Y;sB#0VK2&K7^`.8h>`i]Z]&G,"/UG3AOG\X=4gVc/g7;)(7gl8Tup#2/F.YZPo'YH(lIlo<*PCNlUQ7N\E:9gMNd^Z< %H`V\h4feUarr7[r?i;)GXZu:] %-P)euo'"W]ID?jcA+cH%+*HMqeUK_iocO!ZT)[]%7h:9*DIlF3j+Z*gqTiLHO,'q8*d'.W4QkYA%rhh-UB,i%J6;/5'fiU^;=#;_ %V#1\>0`K(CO)\sZZ+6,Q9LMi7ngt@/.1q0Tfo@--,-(e[chgP"do1r\@jb_.kSpL2$)8!N4mesq$-]c\oV\SA* %T(0nPX8d_QX(/CV4EL1&DIpF#Hk]kOLj;X\TE!cR\[IpNRVRS1eOCj^`ba#3bB&`MDp?$3[@ZY"UJ?fY!ubQ^k1q2R?p[=oNE]DH %*fC)ZHj=i(o5D[^VGT:E_K=MV9f0f#lhbcWn/A.O2H;L %*k#7`LCYKZB+MTCs.Bhd>2G6>06$Sko_L3'J"IK=\a>I+R)$^s3jNHN8&?9&eMVPq7:)`UHJ,6]^"aIOfEX8@FnCXX3@K8:_+%#) %hdnJoTs,tA8^cl4h;:n^Po>!LIiac"K_^FCnu"NOm\m)6A3"F>7.j23]g?HJ7U8V;;E9qARM28Eq\ofJ[&SZ(edkR=r"?:1Zk&^>mt.?TGm %&LAe[auk@J99FK&XqqV)%H[#XDCHY%7m=R5[0.$,%@\cb8/YQ&OAg6\s!\E3[#ot[(r@[:allRf##SBDBQYQ@5L].89\"Z:Gkk;TV]U]nZ(=1A:72!T?Ua7\/"'#kq;h`]+F>Jg-#hGREWrE7DrDlB@5nH5\Wq7 %d`N(%Brr'aPLMFn4+mYCdM/TnY],`RhjX$NSIXIkUMk*@nNOUIe]n)p>u#MQae5\+DldGdq``5PIQ`a-'Z0HIN"eA0F$U%oiB016 %@UDja\YXl^2icM+'`Ca=NC$mIH,BpG[\P=IWp=t.$-!MVLpG)\Eflr8S!#ZrQemX0,r`-sJKY:Ai:K_e=AFg^BPUf48L[Z#CUH4P %08d[h[Bo5&R/^[GNk&"N_kXJ3in@6e#IpO56<"@<2CXbe9hHGDNF=A3rcO-7^K+fT*>dE96;K$h&Jd;kW%Is&=RLk%KL^1CSQbFG %B_,YokABaUclqI2neZ;sZ_++n_\Wum*k+FEi$E6NkG%diH%KVAB0;#%Bq`f7<^]K)q.iu>?bVSq-f`5$UFk1@>V^jpQ[N(B'm(S0 %/P?A,>`88EQ7m,bA8tl.ZA+i\@M^Q/.8jmMD,BM.l^-*Y`4l$73jA^gJ"^sLD19\See@r7Qf"(XA)8FYlW%0Ageh0K][Z'B6Z+K6 %--\LdiQ[;8ZENZilZq9im4QEHao\lbp>QQ^frCM7e#qMl:MkN@V[J7-QKJ:Bmhc?pT,_)rd6#XA@GZq4ST--)#SKLgH^nFGe.6iJ %Bh&t][4KWn_qr_;kl-X,I\#&>]c;7-MmDI*?b>KW?Z2@g`j7r01e=]r(a`q?&WLK]er%I9r=piLMS\>T7Oi2nULWn'q>^`;0,H;"MsM]gWa1mKNPl-gEc %RQR!uHk+A>nmk@P97reJ(o_@V1[eHN)OV[,".`)*r6fGTUeF0oAb%Rs^$2LL*>0!Z=4$_]>q!H7Fa@h`%fI``[WIF@1^D>6%MYa^ %P]C=!DKRT!BlM?!#R=H);MQ%nAb;cao=U_jjS:n':pm!sAqE%!BFNHOTLSQiFb0_d6W39>$Q7f7Y@-3mo3M6`/qBimY?b[Z-_Hd* %&V>(F#J %#^sdC&O'WP`U9(4QHnb3D)3Y/gP548:,*aJMGsh%7!k:d12VjWd<;@)S6'+#eM-7SM2rks,ed@uJdfn8!kIY5NA`T=1U*f#KC0R4ri8dnml`o0nS5 %F-lVao*`g,bbJEd4H:sjD=aOGP"M5cSNc0u%`e*+P*k(Kf9aEk)FNFo-f^nkQ:3Q"gfQu*KCgk$A>ClQPYOt(PO^^dp#S4]YA#2h %+02!K$,J5!ro@JFdIB(+Kk^8P6Ip(9\7.`5Wh8M5di;^N,L5>^MY5G2R949Wi-b,P8ZZec"Oj>f-Gs(kJ4`)0d`\rJH&uhHgFdV] %j9i1L%fm_cB3Euoj0C%MgSO>ajL=opPX$SlR9b%`JP,`OZM*PiKk4C].9Tebc`5DNp"<+T2*\FF>\OqdpYWDXWj/W*$B;`$MUL"5!es5/.'[2[]?o!#+Ou$j!4aP'f+Ljr6MXNlglnj+/9mum0/\g(R9F7?5*=PY"$at&1](Zu+ %PF3/D,c5>&_9^FNfNjjS'S:tm\/n9'7On&%6](C1K;n7C%@HG#\4VXfjY"L-iEmrThKqm%N<,$hDQK+_)!lp2OcBQN4">Sn7rG9J.(`VW,DI^(X>akp2jM#/i+?'rX>onde-g0+u`2EUk\ %T2FcuR(fF?oHDCrce(#9YET$Y)38G0VEJ$ekq3Oa,euYRfIIlI+JFE/-Q5EF[UJ(22T3]q#A"iF=X3%;^:d[$E8D!NTqnr1:3oIS %:"IaWduHQ=RFB_MEh@+drCE/Ja21BH:'\j2^oe\:,@*AO:*Zr(*Fg<%]QWMD+DK#B6K3U%2E`7X/'fPDO#VF`XBc-0]4m'PKanK[ %L""^<_`Sh.?q^SnF-,&#cr6<%fQSC&qd*T)ZfI=01ihks2U][^:H$YBePA*OaR$+`8-9)Nfgl3"0\Ju!?a+.M%Q)%5issk]A.9'2 %_j]sT+;'g64hq_p9g53c9*9Y$1+$dd+?5*[0]4!f5/[GV9Wli0OUN=I5YflMZ2mdigp[;qR2im@Hs(Lu#>A`M+pXcQE]47$B$E=V %@%GE)*O)-WkoCn>2&CO'L*h\%J;Yc+HU*_E*;'>;Rb[ajE#S`UJ4$FB$O1ch6l$!JC'm378CgtS@K-7g0D\eIpnO %^U5i1jGOI%&>aREXc?XZ>AgqO?rb"0SB6[;&8:At0NTckiu>,A#n`U%hLT[T(m0TGN[GBtf*'m/Z8GN:W@Z=RTq.nbai)d2`?']iON1js"s0i7:KD?g[.X7$*#;5*XmA%"g*)8H8f&(k_lYEeqO7]Q6W4h+U!c$jj*`\V=Le&Wj>P;oaV\f34b' %"Kgf\kU([8?#C7fjf2GslX$($4A!sT.s`RZO,QXgQZPE'ZU^c\.?`nG`>5lT0A#>&-CZqBD-SmMB$bD!Wjo@aZ"IMDNSA5BWPHDNCiY;S.IeRTYX\'gO+'uk7YCI>=GXEj^]!?AqF82gR'ok6&HU$&j=NHpBqHjuPA %BA20)lMtgn:-f+D7#;Hm`8D*Y.oZn@>Np"uA6-F+![Oj>10^Gs1C+Z++n@nM!6,fd"W`86O;MYW&IX2S51I6k;J#i %:iVK\H@KWe=qZ]`eDR=LEU80sDFV+G3:j+f_8eXO)*<(=N]6)bE<@&Ys8C=u.[iU?WZDX8pT^8-.30A]VRl %DbO9a!44'U0R3X#\>iZU)FcX2(g/R)(W\e<^6g&?RR*5UZ^>C87)'3H@1$lQ=5-]h]Red>TSm!76r6K_JR0l`!a!`'4@BOT,o9T? %_,$dn4XL$1:U)7o+i]R/U_+#Gk)I)l@iFqQ&`?uf@b#m80i1_b$b<(\ODrQYo*27C=,Y`_5bFE%fYfZh&f%"8](S[q)Bk#o^HRX& %MG*a-C6@jca1uBCP+l-#5eLt(26!S2>cLLc0T1WZYgTiV!RO;I..ITJgVr&T0$:=re;NG#0op%3S@!#(XUdT58c)KR$u'74db5bZ %jD6DVa-k:7EN6;m<[YD^NNM.F7gL?*)2?\3t %%[br_V`7G2jZNT3(I;Ec-[t6+@*1L1V*-:43VhrjC_VFA:8\G?p3_*X7oJ'^ %ER`GK%?3%K2CC9+Z9SU]D5\Ujh()Hc?uV7Mk[B1]1o!,h;MrGo[(OdK6rEUUC`kLQ+K_&?LD44u)@b0RAW/oY>'Cq7R&@I4:JQgj %/)$/h"H+6X2W%mEMK?)EAV^]jh=)PUb@_%UTP_eekrqHV;$WYG":fqM4)FP@!S1kfS75DRT/niVf"ppAl2i7sC]FXaODMA(CpoT'5!K^X&L8+nQeBu/nE6_oAY4;ufu1=*6l`!HA,OF1B:'8:>TD"se/NfL:/,`GM#AJ0X,GGc%Y`s;j` %*^uS2?ie]FW1`(>TdU@19D4,M`EI;a(rCBcfB+e`EXD*&FKGiV(=fgI/':tuN2lbgZW*?"]#F#J5asRu*755PW.W)?lp5dSL\9sG %MP*3*"1(AlCs/L!%6[>?/NC6"b(O.V:!SBt9NEnl$t6aE2V6_!NIrFq($YR,&Y$]9qOMfh5XZDe&S@J@O>V]2N$$joeg`Y*YM^ %>\g>@$e3,eW!721!k5cADW<$RZ)s@r.n]qSg[pft*cEWg'&-O_&6DDtFCVE5e_)Xl`\g*DP9\B5%Vp]g<3Sfi?W.U+I(;!kE5el# %SFdk!qpA.5-B#"9iIp/K.N9Jg-EDk[O;>">4JmSSuBRYM)s9D;)MOVQlY$ %b[$E`9HHC[(jsanG7@JmWMt=H6AU"#Gti"UQ"tJ%DCLn0%,L<(Q?OD0$Qu4<,;A#.P,r]01YHhU:1J!9JF1bm'PEdIX0Z/5-n5We %Z4`lYMF3pgce1"u4\_,NSP)O)/!'-;QJ--^W&&<6Y=ia6G>W@m=(,rV,/e6kn)ZsGRYOG*&+d$7@L-d%KPP&2B_"8"S#$+AqslmL %A4:bLZS8HLU/MC`RVfN;+UWTLF5\FuUIcW]/UD>&GeKc$ml)T!eWg/9@bCJh7prDdCN)[>!WY8pSs8ViVkE0Dl:?ZN#t)M3;Yk22 %CkVd0,*eW"(hCK@o2iE:Hu.)#'b6JWjEKpX5X6P?,%G9#.kD"R3]>!`U7F7Y0L>k=.-Cp(K^q;Nh"MWe7?01(23);`Kka2q %:(c\p:p5o_b5*CGq4X!+Gm9U?9=XB#i0\I5$q:cXe]e]+S%s7Fc-bP$==5?[Y!V'ZV@_N85/cRBUDoHe5;1Q,6LkC. %@UUVec(-_HWi;m?or#+Dk%&oAYqN4Pf=)0^.sQ+VRqZV1dJtdUOsmIY6^DFIJM:b+_.ad4LC=pe]#MmV,r[GDkUsc7]rYG!"&UG` %c/u.kLu$oka,Y;Hqmh_jX58&ZD>:QI)/eT?/K;1-rRQPhSUbSS5iD>>bW4X6T!hfto+g$2UUDIg;q.#5]2f/4N6=2ek2Wq?h %mV6&C=LaLg<.)eeI7'WBm+PRI)gFJ,A#?7I)PVAlhK^AeRumS(`_N![oj=%_`Mum`!khO%L^3-%5X]L6D&USXC5.,\>2Xf)30FY) %o%;-T"fjUWDmpQ2OBV_FFR=-Ihg#GW6mKX?A](,r"U[7&)K[#)@%3S/0=/c^Z2N8V;3=gp(mPE;n)hcMs40p(K^?E0aWn@:L@0hlZis38rT)(B7(L`'-) %;2Za)Erf$W4t;OBU*8&)8*Pi!n>/U&oaiP)`,!ZjOp2(qTK=ll)$`2u%o`N.2FHqY='r@Zm,So%Y.\G`cjPk?IgZR.8Zbt8E9$6N %&:fLK=BFetMI+D^)S0:X`%9=s8ST8-UK,7&D4hM*HcQkUc&7Y8RN&";D[eP5>lD'ZCDHY"EoAITn''\9.e#?Bfj#b0*-:n]c3i>M5C%GM&C0+_@Q: %3FQ0Z>L68/HF^R2BVP8Q;J=KV71.%6<,M+t^s+d>9$l04UFL_Oe,cr[9$162bn.otQ+q6P9X8[LX.DlBaquS]fM-'ce+$E&6L5!$ %Va[MF<_u\m^qu5M8lR#NXGF/%@c+Rl;:1R*af//=K-O@UM>Udn>\elJcbn2C@eG^J*0a8X0McNFH#ZJ'A21[Vn$P,f[86sZERXI_ % %AY02*I4>e&KIipt!*YlWq6e)?-U1d+h"d>)*O@R=P)Y=M,%Vooe^]P^oQEROf+^de6/V@NUiq5W1n3t&$ %Ha>8q.3D&80>3;q,&@#>V7_@Xm>P_[\=PPeL6lK'?Tp#%qEn3-$hXR4Phf?0-EP]HV.q8K.hR?O!6*^3C^)m9$e`sS&5f2HN'$V) %7H@W?'i/*CQ3[$)_h;Tj[G4OG8d;4,0B%m]GK8qP8.iune[Q&Bmn_uAj4p&OauWG$kC/u)N7qcKCkT>dBSk?9f!79o*TXWQi%MVV %WUYhRpaEm'I6S>9c$`,'HOqjlT\)UL''jg:.Z62;$m2%icd=GQP9Lm"#45fo*9Y"i4qDKmmU:/J_3p4M5mr7ooA+q!`Hjo^qt:&"\7<<@<:Sf^;a@?adQ- %Ha*7Tok$u!JR_32T6'YceQ4r'NRT1cS9:](n3K9Ze^]#pV<7$bL:urRLE4"fN3i@,WuF%ujRpQS>r"#o)6m_"??k/W6O[>?6Njq_ %cbHE8]T7&]qDh'LGm+.#J+3*J=']tHi2Je>Sp82YbN&kqfj9L%M9^Q]=6E6EGNJ@)pVahNNVrrLY?>#nX/=FD#8rS$#`m]19.CYe^649,%Zku-Dd>)RU7Q*,8mH_5HL45W)c]&OYE>^TlTQN&J(4T"meT)Rf75Br5niEH'*a$'=qc[,5;\&,PemG*magiV#O+8+R(Id+&$G+\E$T6]Z1 %=.ap<0DVI4Y]K@q5P'c%SpIJeaY.eZBb,L+MdGrEku7(5OtY#KXX2/g?63:A^A'Xh!b$$?g@PI;ag4ST=Qo+8ucL=;iSJ*b2<4lsg>m=PAD0B<)Dl[uBhg'p8d=o+:flRT]$s6Fi@52u*. %II,AV-,%l2X"BMVqP_G!qNp1Y %:HM:O90N'E#N%bKm1\pI7mHs,Vd/iOr>*KA:;>udSG')bPtR[5DS+L!DnQi-a15SJ[a9>^"kgnE7"i%kO&$;J/eNl5Pp4sI-A94ppnF/E/W=lg\X24YtobkZ2<=nM1&%N\`gnO %b-kHTr]0jYDghZ#IJT-Lq=D)OoZ4bCs8.g@q8T="4J++!.'^N[Hkr2^jor\pI\q;tKQj1A[iPR$#aZiA+s2n\X*O2'bA %)*taDpI2]\md.R'SpfW\5P3WuDnc$WmsFZtNc)RsDgUu7^YiaBHJ69_puYe$Xj\>5jkcj.g#i[5Em",@kCp42`*`Pa$[+I) %::L,-QbDs&T!`e;Q<`_cpV5]bf,ef+p7LsShta1roLjFQ9"kM!+cclX'CoF8+ubr7&4Tm:YVprl#hJ\EP-,qN.WQm'"(qkFQh8^@,I<=RUP+ %V/LbYYJ9G(Yg750I+.P4A@46Xqr)btb`s.)`PDdas.WkLrMs<'j6%N>kKj1_QVIL#YK+CEQErT?Cnj0Kf4IP@;jN441bVY/UQ^$Y?=Xm]Rt^Z\aKlh>ko%55HlHUm,-:\Kcl]`%I6bK4+9pHR-9qVcY5 %k)!`R:[@3Ci$5VtIcbQtD/XjF]?bcYn%@i>s7=c:qk4T5rbq*Tff+EX[nd\7cD*>sp-6oln];=?YFkjBjXWFY)/oKSm27j4k3q1! %\E1BkoUmSFlF6f[I=M1gQ_1qBB\dY-^?*XaR16b)4nVO!`<1Se"7LKNdJ5<)g[SACr]ef;DZ8EUrml.Vqeit0V/QC?^]!(4^Zg$m %L\YL#516p3HB7k1?7kJee,-oUoDeC9:IEsDbZCLKL?MC$%IH3caH0sXQN5ihlbQ$A[*oX9Z0`Cloc[G]JIYscI %5JHIH:(3W`/m#^PpHJLX\^i/.qTVg'NK*CSfF-U4JUdXmIoq-Xdg#i;)_TRJgnTW"KD;#[qisD-;rd"9]`5)m?>OuapH@s;J,V15 %e8!lccd2XT[(ibEe/s/7;kO'Y]3]O*1t'ulGXr)-rk8&dPDSsk+8Rh/QB/]UQ`de'e,u<>cG07`?L-`LrS;Djo^T2,me-A, %^\?VLs7q_gl_Xn]e,#s;ETmS8f@ag!ahG:R'41F2rur-RlaK%?4Dhdt,CYZfA,YTNmsjLp-YtHIcVr]mrmceu07WcF$cY/5Hi*h_ %@/X9dEQ7ejm'L2QhrW9&]^p(:NIC5in,A"SGI'g7(]SB>](tstp/g^1q/p?9U:];=hYK133IgBk?[:lQpT*b-Qg^cM55N %QTVL3KcdJn`HQh(F7R?-%&;gP)h-h"T,uUqq/[YT_!h9^P928ikKISPrU2p;9BM6*P.?4gG@0s&^?(q&??(AeS7r#kXDD*Ih4OT6 %]3]XaS*f,'0`B#3bWc#M^]3",GPP_B^Yp1T>$^H8s7EI\?TrYN44YWhKJd9:Zj/bRjOHch57X5Oa'\A>J#&;-k)]K:lQ4(c5reE* %GCB7-2_Y1+jPU!b)kM8Adqd?jI,_?dnr.Y0"8gqrci=!UoT/Efm_c5Xm)c$s*p_k1-a.]?)Xc((qi9jDm84r#ZQ%N-q,8C7j#90b %@B8GHX;g%_cZ&Q/s6,fQ0/g"\4o!H\5-Q\Fe(Yp(p6[6-`5rCBNH*R*^$muVKDtd=J,eVsdjO:\I-GSLrFa]aFn;Lqr5ZSKX<51J %.;.Q-)f5'"r2II2h3[THQN-FP_CJD%Hf/UrM5>tkk%W.fi`/o>4C.iap\ZhLn;mP4X08:Zp.djMgp_aj'C48]q,@=_qlb>4rDns, %>(#h2a*#,e%=t\i&BNmmi0k^m4GMeg*Pq\poFGU?a\jbs6S?UI-=jX %gdaKc),Ied)OB7"%mTbJ0D_ZG*^=Ec=jMB=DpgE?e6fud.:RATqpE1JHQW+F`l1.8(N4]@\Yi^-_V`0GnX4n'UL3g'4_;h)j)9>= %PP4E/YJiSNs,TA875',8O'OkAN75!/Q,!)R?0a(3HmuR%PoNJ/_G3P!)plgc??gNsuI-WT74QZ"O=69O,bE)\b>Aj@I[KQ#;mWHj)nI(q7q818K[WATs %k)4,gn_/'(6bMkDhnJqN=7>IspX,;U/pmSerq%FN$ia-II*:"-GKMAt55T3<^XPlp(I-00P%+e1':!ieEf4oJtNp]1@Im9:t^; %07No\Is=)o6]ZQ2#+k!=&6:`h9uNT#BcFA:_X%f+;cPc %)F1=DPV<@m-B]np'bN.('N>KK>Uh.h`MEWfR#kkZ'LGo7h\=0,,+prUnr'VeWn'!HNB!/`4q2]]0CM*23@69n %s1l(PB:W=M>;5QTAa@+UhR2aQgU]u0(2qP1hY"]pQZFZ!2u*5P[p;p6ZCUmKH.U9NB856U\kNPsfS-D=Q<.k/g2;8^tP@TmueUoB(+HfB#,muTQoC;2btB>:?g'oN,'M? %o'H:tW(m4Se!AA/]RAo.ZV0^:*'a+]/[iX,YFt;XORtf$$:T %oNd0ecYTmCriQbQW9;36]sUS_p2>EQf'[qOM%/'1]rHSHiP])Xc*442Q_=Em7/,(ab7!=dgOd!=E8'!c-,bfW#n-NGmE]Bf5/onrU/\n`q-+84o_f: %;_C/HUhc@Be_=G>i:#G!mC0^6H"b7PLRRf2hnO9G@.H,>F)/t5YLbsdlaU/j=M;[;ZubV_%;\e9"0T@Hb33.X43]Q./RDeu`adKl %k58*3J,aoUBkR)V2.`p.bkX?oD?"/.X"2b>bKBS(MV1,+O7(S@rQS81F=uu"poFfqHo%(`[iUu?G>@lRk7517o$)A2>diqhSHk&? %33[&9f/n0=d_:0?L5bS)1\"1W4JDPV9P[W^?0L#@e_4RFc(-Y'mR'c%I;RM))o(')q7c4L])3r9:qE;h_9k1t#_D6`-ZN/bW(kWE$q*Vas2]NR,(msfW5Wb(p` %.KW,10Q,;83tIlNl`]clG\c/hgE(kAj3Kr9AaZdsDV06gZ41B"h[s.@2S]"+MKN:nfY6>;48\3'I=E)Qf3;H`f>Cd?mG#$sa6n?\ %^>HSN^qnAMm[Ynn0]gK37Z1]OWOf09('q53)j\TYYJn,3*q3_WfVkoo6"+*d0ZpZT]r_/P1q %I_'ajh=1?MH,i7r2,CFUWTrugQ8`F:c>mlmo\iTr2k"s)pX%":_/VGT_4%!pcbn%22Q_&oY2Augo?AjOnlW?PJSjl25<.7V\kH?) %fh^-YRWj8XgnZ`IF73ZJf5CVf5&C8M(%[/kqlaMqDLZrL:\J5SY$ZS:q3aNUF87&]\,M0k=OFPNb;\RC3RaRt*-:*2-0p#[Y./u) %4,YFkOI]"S6gfDG_a06N,ItPG]Q2EL\g0B8D1DA6Dh%;@]PRV.orlT3E3>\DlOW/QH$&.DnZmR)5'q@uNIu!:Ap2qC;]gF7j/sK7 %k9&?iFkuAEgt5^1#HFqtqXF&OGPnDQnb[5_XBmr;@_WRLSVh:1]COep5MZ+qNO/(tCg?l._HS\\e$`(r*Re`@XCkUQh"d^mgAX7i %2netNUU./6psdFu&jcO:*dR.jc+B#.D$Te&gA9L7Y<4`/MZ3!IoI./[i6"-RIe2SOh]Bnop6gp07k9lgEr2.#3Z\^mHq_Q]f?A[* %XcL3O^AE\um_HP"]?H:^jblpi4)Je>c(P^!D,,#:2#"!$f7(;Vql\c4n(kIfFi3.QrpP("g:m7'cTYV0ne:Vl:De3)M(Kmuo%1X# %]&]mEO">SDSI[p`Cr<,'^\[er?/L(FGQ7XE(#O>q_#D#o^,9j)I/O<=]^bQU8+4.Unj2),DKVaARu[He:;1T%_P\/6s2)s_]k)AO %GitAE>Ka3%>;guAn^A"M^[^md:G8/$l_]O!0'R]1iJ!O:F8T`8/fB*![?IKEE:`Jg(-V9eM_Dj9l>*T:?@'mZfj',H)jmPi;Bn+k$B:RMQESRs#VVQLGoU@@9dr2g;g>m%h%.)[C[$p$(KFj2&a45:ueEMoJ.pZeXdHU95VoF4?5a&n8 %$h:#5#5:JA.Df[mfD&I3AtritI-/UXI&gECB^KLmeR6MNT+W*'t`9bk9&q!(&2O %SdL/W,77BR$@E&'`WkD2!4/-,bGKjI8u/"Cg(QQBi^fTRr4LoF#neBqMZYaRE>2ueG:g0]Oq'kO6 %S;]1RjJS@J5h4*\B'CNY"Qb7Zl9D#]!TcZ-Bb8$lq-_(J5&T:f`Ek*CAAV-)'`^W58Xru4#aMlT1E!5q8[6^&0`a*fOR5adLVrYI %7"E8D,0.%^&EV4s.@Z)+MTQo1RM=:Q9&t/`=KjGhhiY3#AD+sh8=qO8&TO[7d#k\X,3g*#"IalqLM.q%GHo(!qP!OUnB:XOP2iiQ %/+]/sclEV+[?RI%j93[/@1o>/7U7:G9n*XUbe:Nj&3``dI@PG1_"YjTsbVpkWS81Q*IgLO!fTMaMP=9,57o8/4 %Nb73Q4qj9^$^i<[(Psa$$LuhZR:f[T7laj!-;eeNo>7dIP4cINY0*TqsSsAl-@GcsV6[Pa",gfd'1k %>&Q#jjuCX/9?q,TE'(V#k[Z.oB%inY":J21O,$?r%X&^DE&'/18*!8Z#9nehK&Oq3E`3i?O$9[^F[WE89nZ.`NLiq)L$cqkAEA_i %SZlXVJbY<4*i;t6g*RH_9d0^K7+mf>O0p7SA[s9RQO*S&9oHq<9LT[BAAW7]B)*uaDOT4#FZKWN4&_."((-.0bLGceFPO;-q>)<* %!M6idrDNF;R!9_FM6'!p@L:M@P'3+$&46:<8r>hVoOX%LVEW>'&7Yp0'gM.iZ5Bh2':0M+f!N3E'a98,9(4.'WfoIhr<&bEESTOT %A5dD!KDZ^S]@X2Lq0*EjEZja\HDdCF7IssQ5d;LJ.Oj><7j<#`@<=KeGZOAo@6t;7+lNHUN)2,1Wm]m,NqXkd&D2]mZ@d!N=0nTcV$DL#agZq*>e)P3nmU1*sJK>BH!?cf)\aXO/:+V#0'6, %M[:^i-I;XM/pDtTru9CZoe,g %.4b=b_qeFeEc/q8I,`B/K+9\b]Z2n]of;YMqT\^g7nhMh>Mk],h@E`\=d&'R$5d'r,>j2Tt>U[MVS;7PQ(S,45_'.8g0 %G3NGdmmYifY7SiuYcHsK:$i=Bs8+LAkVf0l0Dt`E6&p6/q,mg3((.f<">@\Xk:jto0C3%E-ldSi*rP?ZWViag(H@,c?WmdXP3_aqK_ki]`Dn]N7+amRR4)CNiV&+e0^CQ37$eZ1 %#^`.[5I/2fKo794kfE-QqNAu5CMr%G=if3NVcPI`9`@5Y@<[`EC3=FGWGuL=`F<3WO@_'dP1du&/N\fSmIc%ctmG$sH %oIl3+_,Yj*/JlR%rLWh^\bZ1SlqbY\%&kq)<=QKKNXiTCYO#t@rp\(sa'QZpQTn=aE;0:(o&h;PmVZqABL;DsO"j!ON5kkg+.jma %eh3#2h;#[2WpI4O'oB/.$"Rmom]/[Wa>kA"'"(Gl_))kgs2s?DmKDLub\-R[ZO2>o<@2!2r,L<%&/\ %^9@@J$Mq??`sgG-bI`!A*q&\P+;^Y6[Sd^h)t#blE;=k*c!(tc9TtLJVGX7oZS*=/W;'B]dsW)FlLW[V'Q3imI.q1,FoLI$g:-,$ %f)e]qrj/Hhm<9ol\h)Rd]QZC4o^Uu)gj#DQdJ^YU[AMgDI9,pSm[&YB/pV/ToTeQ2b;O?L3&"HW:p=c,# %:T!*RJTosp[6R8YQn\9co*T+oYdrhG]l0@rfDiDK]2t%LGFa!G"*Y9==7i#3hp":lNA'`LqK$V2X#n>SRed#jQB:M3H %hQ)YiN.-P"qtS9WjSQ]=N>c6bM@UdsT=T"(IFi.#h>'"eAif;R[CC)FSV>'`r5>LSC"//kkq*hCI;bT85TBXVBfDK,^4I9`'/T%l %P4O%`di@FlktA&n!F+%A[MsSZ'>5_e3DZ:BG[dAu$e204]:+5_D#'r.R(7t/29CIB4&;5gDLm+dkuCXij/@3LQ^u=7:0>,@qst8N %^'gODf(S`\jOIk"*kN=LDRlf%Rqhc2#NaPV2`Qk).I^2@s1GRi:_LfR0%:Vkp=RZG(6h]pWn7<8*Uc$B.o\)YAi+% %dO.Yj:N_gOS2u#98$=N@oM?&TmoX6>d#%4>^UFs7q0fI!JC1D^4S8$N#;:TV67T=D;1@U"*:$@+n+]CkV0 %[A&odNHb&PWNH)Wk10%ah4J@,E9G$kQc^_'Vj4I\mKHdg$`D6fAPG%3E?FqG[tTL^X1gTe(uZ]f&u+n\h\#$I'<$mV5f1t8oC.m!aG$H&WI3^$ftuZ1*q3j@8p\gMSmAYm:+Z4+\>kb1kC1D0B0LAlBO\O %b#Q8e#QdgC,\T;I[*oX"gGJYnNg=^[\7T]Xe.skGTL)U*)%_3\(G'!m'bZ-eS^'=pIKpqUg`rI,Tp%eC0(Q-P#01!)UaWH %aG$l+("IW+69dc)LuVMN5"H;WIGCV#Tc(dg,f35!cq=O=O.U/f5U.ih"C+=X!Ic(sUTW*;3WO[kSlB)AIUC0/,Z`H%*TnbL*.I,0 %!K6Or*fEX2V1d7sT$$]%n9]jl"u6e-#;3l>oIeQ@9LVR*@0WIN"^u%FFeM@CObPd4TN(\4Lj_V%3164./6EFU-V.FH7[.7hcPO,A %p&("H2$c2EX%8ZBKLlij(Ye\BqKrY;=&2(!*[?$)B;5poYac_65[_!_-ok6eGsUSG!ob@N]aS:6RWrjK"9,;=!NV=M.V5(PY!RbM %c4l,8h?1_:7UH./'kZGk;HD,p2(B^orCQ2i9+T*,n#.#6<\3u'kg=>c_B]pF,%N%Q"c*^GL57mhcJkeSR.VY'$\t"aBW=e/12S9\ %mXP^6Ji\^i[N"]c^1X-+XMKh2iAukI$J8\q8M;J7f16*$/Yehm$L*Gb-tW]!0f1fn.\;o-E>Ai<"84U=@CE.0[LFtZRV5@#uplF[E'sVCfN.BFBd>u/Bg8c %%9.X%Z/5/lZ-*;rD7*fb,SIY$(GHlS_"UB('Ar#Lg']ahcq8gsQ#He-"3kIO'tCh__f/7ID(j4pFhNp&8bJ.dk/i#Pjo?;d0Q8eh %Csu!uYA\&3-k5bn%(.0IbsCt=T!'>nH`$iPGf;tC$=K8TLcAH;4(d<9o]fgA"b@WF/tWLAKS0RjdtlD5:gpYC8Djk=!^7H"8tfZa %oMn:3&;2;)$hj^QRaBhnLMEP0]Y8E\lc,*g9PruG0n](j;f?;WLq`G("W?OM/>'0oqCK\.:rZ&UUBopi#=:ZX+`]/<$f+VZJs]CU %eX&uJ%2-NsFkkCR_V",U;Emf"d1%<^52#3,,@1[u/:40=#XF976I8bE4[pQ?*/-_:+Vk8B9>XYjBKDRB3/SSLRcq*n`[XN9$qUA_ %YWnokC-e^J72S<=OHikAPQet(>%l4I>iEgM?YBk`$Gn^d3L`*hQ$8>t899<9C8W7C] %LCUj)C.,6UPS,AqalK9&*Gk)0-YYCcj-jE<>C4LO3hMcEa#:R3XV-,`td'cbZ+Fh %0\!4"P3p'3UD&o"f%DmeU2rSHV=k:ihTej:W3-8,?\qcO($3CG!&"u`MrG`G1lUh!0!M"daL*$]eh1Z&[Sfu;YVB*29u(?f.n>>F %)(;3E#`;CO"Hap4IMd(3phL'7Qb_)^)4K>6]SJu&6Yr*7/jj)5ZG1s,fG0i-0YAN:=>B"(YlnhB8d %&:Z1X#]#BbDNgFq01Z4]NT;4i,0rA/plXB5`=dSa8ph]@*-EuEr,q3.4+4(KaOKLP#4B94O;g[ko:FbMf[QsWB`?!_?Kps.[G*6E4\!BnGU[@DY&+9S7t6THkFkVK25lPQAWO;c[Y%G?Ar %^b]oQJligV,c7Qd/Ttne8,.PY+DJ,.5BDk>;>g?=_8;2ZSX_)XcX%QgkV,(_ltVoAPJh:?K?0b %k--O=4OP&B,SRHPqgc3PB-F7[%\c_S8rKPUjV+SGp)0Z08ald3Nu'Wg$mZ\!2."0Bi2@d %"pb:=h,:S]kO+5Za1Q3]3@mG,&0Lfs1#q&)F;Qe\4L*>K1cb&k'8L#/4f(=nRs@pEW@5P+?TfTPFF0I>KK,A032GWaF&H0(3AZ.Q %Me!-"13:.!EoLYFl.UY"Re1&H^?fT*pj4r]GU.-C-armEk%0+n/9P6u6o2su5I-Jei3I6AP/UIT](Elies[&uI`?AkRRCi.=:X7f %4,uZ;:I+s]2^6\Og+Fi?l3Bl7+r#g/mcjClnepqAdHAUmd\C%DH9QY-;=)H7,"B_;'-3V_E*h^@J<6O=*!fp1,m"=kNd)l.RITC+ %=8$gu/YZ9sDZPT9bu)I%Ai*+J)+%O%7)qFY3*%:gjr"g6hR]/<)i83:S<<&NB#ZWFn0(m$VkGC$l'H*Wq0[:)Ne0P*$C;gSSgs4^ %7h2&!-mpj^k'(r"-)']kQ>N%X0s9.E5bb@K)F(4;.OsPNA8A`BgHFcklK_S"HnTX`EY.dXbL!\;/_3CNZ*d=QcTif]1Ms'U3lU$q %<)Me'`t??qC>B")X3G^[@fohHBi&;/KWoG#ag3r>I;XP)/;o6;l+ZatV?c3k0aH1[DF)O+-0KqqUeX/XiQ4guM*-V;":+8!qYOgR %KqF-e@`jss6;2)NCb:W(Cb6DY>>((1W[102FMU?Yoq8P5j&suk\/*Ed'1,cjfQ;D/<`/XCl0?8$J.5meAf'%1`f6',Etk%&n)7;I %M2%)12sk7h27Wut`$>PC"Z+[]]6SXAHqu;/#=4/9-kh$-ErDU?A8+K_r\o^F8Mi=/Z!&-:@[:abqC4t?<4El3ne:rYXb^Koc!KsZ %+HkiA>\+'55NMZL&m<3*5Q2MZZbL1e3`:mfc`<(29DDS<4S"+%/ug<%Fa/2%g>U+A8);H2O'L[#3pVI:mq\a1Uh?;rpj3(V+%FIT %4tu*e9o^Up5)"@M59>P'=h]YYJtRNt[mC+7oj>2,BMs$P;dM0Bf;=aS)*RtNp0alsD7c)k",j@4q+XU\mT8f"bBlsqCDmKkrR*24 %s/C,=qNtd`+5Rc:Bc#V$jF*B+#V,Vm+_#E#2NKlDbEr!k;ZRdYnB`ZnLDC6sqR]'r:B0qsH""=W6Wg&L=e1EWHr;U_[RVlopUO.T %_B7+jG"ubQb0duMbF;g\H;a'Eq=Oa,2Z!qUEph=g?nd3f]YfnKYGWk-DVOb5?+HY;c#pAU[MBs`Y<;H-$YM*%[D,XRP>ZW"K3&nu,R6.(EljRo %bO*&_qaX>H4bjblEW4f`/RLV]c8[W2S5[eTX*^AonUeC)=ci'sf5FLLB@smBR)r)C41R8AaYE!JdC<=']]le(nY0NI&-S* %/uKk#jm3p.]YbGlgS9^0h>-DkKn#hZH/d?:f=ZE8TuZpU5PjN#`Im`LF>63tGj(Q2$LJ)J;>"4:ca#t>^>H;KCNZN=T/<+/[p\$p %Y?0PhGg4eAc+@>$b1B5:?H3kbI:M*V1[gbeJg.N*4LTPr!fEj1Y^FWa6G]Q[^YdLER[a%hs-AmihTa"Z'abrd?Ztgp?glgYn_GQQ %kbms]9jbVV9s;Db7L"@WC.dO*`4K7NFKX:Uh3Xlb %e8(@eV=`)P2Tp<<;#gGgT^FTbM(bJ=c\(hD%9Y$i?Ha+H&8-7=]q9A$Gk6ZPI=oD)$VN2$?U!29Dk=3g9AHd/CS%uuU1<'B0(J=a %ceW3Eo;iRloX``Rq7WEG_8*g1<5W&Ma)jGo[,0JojPB\k52/ot=ooTAp;LHoT:+"fp!sX/\GFL[VHKmpj*HjKbOp`ehm7'&@DlBh %.,n%cFt*>Lq/,*M-amV)^H:2qKZA7#Y9VP>YHkD5)eKdr('iOZ=[(P5\Qsj)OI%OoqqJN&AT>(KT:RltB)r0_f0/Y$1#;Q37GS;f %cgQ'u@FUcM_XH?n.nB/VnjOPnET?5m2]((\o>Y!.%iO&B7c@66n:1JSh#(u/H3<-,04%hb04M-0\!c2:l.YQ.-D/Q/"2tZ(YF.Rt %o_@`ZpocA;#`du*]E%![$9\h=ObI(O%G[SNOZ=6M:Z %^%TV.9L_2@p50@jM3^*P=&8NAS?[UZHM(il]U]NQ))_h %X4BJb[nrH5Yf;f!&EIp"3r43JebMo(T@gC>o8!/XjrQ9%Vg5'%/;9L!d,,r$RU>mr/2g:BI-n33LWlN=pNptYh789\_g=?'fB(_a %;1sA"i\oZfeV5_;O52H"bC<:-HbX7=o-N#>LU!^gqukWZ1)d+TqWnFXj>"Imr`(N4d49YGcfD"$[DO&Vg8Lu2E7mNHDbJ\`ZO:E+ %)O4HMBABudcjuCJqq']2E7+'@d8RPqoaghhrS,'anF=?*T!IF4On`g@jm"Ci]&VSoaN)k;hn1ol(G.iA`R[]cV:Y^m*j3i^\'o!& %o)fnEo1N#&C3jL^];%5\5K26okAKWk.(X`LrSTA$a>Z:CVG,pRfA)DsMqE3ro4(D!0\PU^7[_;_5 %%@-Tfe%td^q>*pAftV=o]%+urRTV('T!'3E4S@9[m<`$fU%j)c4"i]Ml*B8r%n7(MC;2:^4h#gX40)Gd?6e(6mshWSf:IEfp[?kC %j,4W[Y&Al[M7!8j]F*IVPAGJ#[88IH5?G %QDuk!#Lj6c5II26E5-:u,6r=*cYmZAArF.j(c/P5XD!@rc@QQt,";F&D(>$33bid>NK6;URPNMk\G10!RjZ+tW7>nP1BjFg%37q$BF[6B9UD&nnQqmQG)1fX=o/ %.o!m6('gui?6FBZ7N):.pDSB+iCS.q@c/sX<*aLK'1afZ'F"?@)YN4$obctQ>eSc'lj$tmX?W?96A0)cE'7H?>d]Ca&u9LSd#'?p %dj3$If1Fn(PZX)2J4!QfQj[1G^6>;2ES_T$=q@ZDWk^[?"IG+8XdCOcdu5j+kEmjoU^9UDh#(=AT"+0PK*E<,RiIOWNWJR %+ATh;7W9*A+q]OopPg&R$RE$r-QpWo"$mK*`S>sR0*(DSD4mInFXP2+RrKuZp0dr=$FhX&""gNbTZOa#^5SdD+rjXI"S<##Jip'I %#4r3%)890pEeXoqf?_m6eSJfI'QjNIrsH1TnWuoP$A::h,"oWcpj?pJ>@%%Y5uU*YmgV$J23L*lirO2C86tJ"!@PGaI,J([!ZhN@ %+NT?uji]tD_p*HF@hBnU:;[JD-Od4kAGs/L%bi">:h6O"/mr-/iPr60Kb6!TMZ6+AUqg^ibL$ZHV?@F@%&W/K,7+dDQI2'hQ`5RZ %i"m\/&ocK&HuCY,JQgiO9*V`#BP0+i3-j6,J>;,p&-^$0`_t\P-o/5-INX[r%A*tbW_2$> %Rc=aM5[$Ii\qpUBB]%/:8g4)V2bmC.=eEl$5o0\DJ`gtXVdl,j!>CQ'PJm\0LeAG#I@QAVF1?QDY%>i^dPJ<3,miKrYT^nd!#]to %qn+VA+t&?cN,/n8ieLh$5k[/?&'sGJOjtT>h/tU1ds#)S[gE9@%877qIOAHVc9Z=E%.CFd(Bs+rkDX4>#l'jB$9V]9#=%Z\LfZKO %A7a"d?ka`>A*L04TLPW765Z7*QQq73-%&I5sh+;"sc %7%Q?&g`'a4PZpki$^uiIaN?pm8MG?rWMKWIMdhP;d\%LHic3SsAO^[l6'=k4]FGFoeWYQc;'oFS!U@#m\l_W0Djt0W@N-QopnJC$ %k0WI23bKI*HCF``I>%d>D=PM`?S#+[2TSEChuI %K$-!:cXE#pH*Al_G*FDN$1TkSni)UU#ZtJ$G-N2U>Mq2EM$"2T$UZ5Zc^G&;_8>OIeaIr5u81U %$IlJ[FoZ^:L6!bK2s',*m_c69'<,@;ZN;=*l]j39Unih[J]X&CA^+:EtKJcYCD(8iV?f+Gu\ %a8iW!;4[nT(L+rddZKpdfTQ18qoeYl!*H?jE&>KGk"EK^%DRu)E8WSc8B`ANRHacoj=j80SADV\qIUaV9L$B\@L4r:'PC5<'WKrG %kt$GD&k=l\_V.`S69H"qm117Q^6@gI.0SP2^EK[mJp8Lq=P+Ap#+nKrETlV8+H(-S8g$8/CPF+sU33aMj9mfK`T83\bcUpp=&XL8 %m&<8?0=*s/E?jO'":,t.Lr@qUO>kdb`/s%lK@&?)72&j*>4[JJXF.*g(4P^c#%mh,0`#7:.mcc=LJh"=EYWdY&a9S;mL\\#a:]P] %\Kk&CG/WoiKNrCK_?^Z8=[?WtaXXo9XitMqTj5! %PC&hm/r?A6>`M`6)G;"?;U+JUCpG4s-pJf1'gR"8M<[JsU*J&?)P.Wk&V0?5ip"6S^_$u=X;nLb+]+ju5H^p"9F^()5G)dKHj%2d %S@%W4I4qA!00@Em(%Tjm,s7@,SV_!:S`*;&"_.b<)h@e$N#U68:`\\FE%3*0XBFdMg?d0gX^J"+gagT* %Xtir&6"-Y$]*W(A:[ikCL+qEmj8Yu1dus%c%t2VEY+PZ..rT51FSHCHr5Vj4)ZRO*df/^1$\']o=14'+Ck6L$?emp_r)<0dN%H8g %>A3\:SraXIG0^Gg$iek"`VdJ&Un<$`T0`ErTW)97c`+)tl@3B8A=Y>Zg8 %?X-"RrTCP^lJq,])L<4IBZI#b"1:]rX/XDEeFnjp^rR5h-3$D`547d/29"Lm'@&\+&HY8%o/h^rEf%R"g`7N:haJDpZL-n)H6-G9 %0Rgm3b6FYd]o,D3\qT&@,6-E>kF[0=iE%Ct@9]u'Kh\>bq>8kU\GjKfSI1&l=&86g./^sX9G %Dg:cflams&cC5'7_/ZC7^@RE!/i3_om^uk0s(>'=lfJPmeAkq(kk18`Sb)2PYKlQ5n9aneE^TY]F%p5Q3ToDqo'\@^cC<:t4GuPn %I4I7(n]?Lp+2'dPE8r7X"+c)nld%`k!(YGIi?E"3GjO42'.QhET/>f_c+A1J^@qL?:Z"),U6Eh%qR++9:HZ*:i-ArF+50GDBN4k`Nt-b&TIag>`RV@=HY/bPG*!5PFgTB>DHb_g".a %))^c&PJ_AHC+-dfSgW]\5H-JtIeQ$K(Eo?\N?*qkpRCZ>6Dk-6#lF,]_lp_ke518s1IJXDo'"PHQ$u>\Rhm`giFMj$NLDUH.29YZ %O"POdrk\K1B#7t8:.6+$GEc7-mdA%i?=2\@+8Wpu-/sItEr-:^'p@u3^Woao4`r:Qa?=Eg?tNd;^V;k:)\;1s-U,9:i@FIqcU+i4 %hV[fX1U!B)rK.8mN#Fq#HqiBQJ*@V*Sm<`QHsl1@oL8.#3/a\q$g0X]jR2rDS:94]S_pOpK%M\S+'nI4]Y!X'!L-!-)je4Jm'^sB %f=\E_=o+j&obT=CkIA\W>5#nQ>j#dHGt2rIqO*%(f9,eYH0*FXYIJGs_OFE%!u@tCp\'ep^V9N5W]?W:)k:D%-MADuQh&hf,J)==s[dDrMfn6ub5VKkCgeD'J %'ArE&f%dVV&*3MM#gu4+^]'F`-C\&HD!BYR:YrG3h!rA,pJ.a7M&f8oq;)e%=^D'WQ9;0T %,>hWOr:m-p)]gkJDg^L-g#j0S>P!:7[qd'(/^;p^^o/c\^V/aPk65NTDIjF:E5uIe`t%i\Cu2k\2"RA#\!a\hrpYY*?SA#UK%/i+ %+*uIccbI$aoA.[K]Z@2G*Th4[kKpm1D$&-[q4tRsiu*QRdr$7W1>_WFBCF(IHoSh+^),Z)JgH;h'_H;!1F;OZYFbhhH.&TuUV6PU %LMim?V=oJlT-[=gH1TnkL9VKj\%Hi*GHQZ:9>P"C4uM;h_OU[omeu-tAWpgrSoid5o8*WqOCG>9Y'YQUQ+\W2V")DZGg88:/Ud+5 %Ias`s"V5t-N7mjTLt;t1Ea[@sZd14n_#qFFl0Y`R5C[GWt:upFc5eE`]'iTk.W]&k5K>Ic#]X-gVCTa59$B9 %Gk9J;c+`YT_(oskc/3KE/=Q]=-)$QJ$o$D %cgUjJbmOn+>rM'/;_$s>(k?hHmlI0r_ECiUk?E:6Xq[X]2V!h`L1&\M`s$<+P+HgUbX+]BS(ZLBCiVjBDl+f&J\5lut!7>3@$4JI^657df %M=MsTm3H^%SN)bn?:b2Y.8D&j7_):Kcm)mkBKc>c,Z\T%cj4Ul(eFl%&2M.mZ@"XU>=S$F&N*8s3J(1J=4FR5]7W\Q6=@qKjjOc) %#rmhE?X[3VHOO4$\8;q6Pqo1,i+:CM)'<$q'es!@0HXkR#)'*ff.O]=)>crUHF)`IV$]K$@7=k3^R3Y8\@Um1TC9a=\g'Ttf#'k> %(;>sN=ISYG=_#8UVX+]+s,^.lN]p+5"oLcW+F"pZ[NU!f:hjF?Wkf*tUF4@s8MP]qm %GSO08KO>p'>56%ae6sI+J-kWFn]lfR;\3]j_TD!%(iA6$A+!JrAd\8PLie(9Qq1YdKi+>p9>oDY>TKKMAoZ`KXZY6HfF&4fCPK)+ %;0A$4=7/&h;9S`n)<2m:@W,EqLsRJ7NgQ+Kn;l,\#0\A"M@42\?:]N^mB6:5a@*SCi+*@(_*TQ:r=d %BU6Rd!\ZUM6)JB<>?^_Ca9dP&jM>0p+CqZl28LWXh]<&dY?L_qPjC*Ej0lh=Q!#C/_ %bdo>*(-Fe^;k[UVgrmJl)lr'E$.6U0i?LXi&fLD'#hGN\n@(_^f'JU,ppln5E43nk %\VYk+*K9QGF,1su",mCQTL;YMK=4D4@0UrfqVmV5OHr*D?>7I6)6hK?its&cNnIsX2+hp9OQL0)@h:Aq52YTZ\37pSnd(+>)?hg> %$*YO8QKL1kKCNAa'-bUJO&e%e.4^1(G#Xf\fWo[H2DL\YI6WK.cIP"#qdG$El>;t7j]l(UYo4hq\FXd3P;%P#2Cl'A#Ve!OneFQ! %_<>eH>TdW3GMnQ6G[^lG$PO8="/'EPSSA`h:efcs4Q9e.K;U3;W(j97KbHG'q@"Q'iCm+*h=CT4BRs2cj*qHD5c"DZ343FNW604g %MJ.PJG8"/1T&BWd"^8_9r;X3=J\OEY>,mm9h6"C$LE3>aoukL,mR(@]O+.%G>#-bMFCf$eqVB!UC\c,qrbogum(O7<^WVuB&+T*! %4+i%X=^FAk2^b/@f\c5"?PEjfAfh!IN8u*?QdA<$rVtjf5;*_`%Mk0:7i1#;\tAT8+C2a?S@ %G$Y.5kb8Ims8#Ngmb:'NrIf_H/l3D&8U\o`^4LjC5`]DN3"Ddd.`"ON`jF\H$(Bc\RP7Xqo)IS4r8ZmsX),EGmd.OAD+t&+@S"]b %IUDl8c]Ep2PHV?KX#9(-*<#tGga99(Ut]HjH^K#KE)N8ml8N^P_S7BrpuBE>&ERqRSUqi[O0q!a8q6TG@J5s6((,NRdrQoFpZ-fW %r%b"(5B$DS;lsGCVt3ZJ55(K>*OO>(F.]$gYYb+Ca51+'Ie,:lK3[UnGY?<3pY:+TT(&=.T`,)ciDeNp\ghHjiUM+uT@(L);V/WG %2%(T:/%"X+'KV2fF2@7]L$R]V1"QkT9]a;pjrYW?-qp?!PqP'KL6'tIs,p^TSTS[#!HZJik6r=eFmaiAQh*^h(jc'(F"b?7S79'A %d]_QMP/DG2n(mlgST+4F*B&F2?eqqCWo*-'XSEK?[^eCVsi?U"q=FdGtCa=.[ZS3Dc> %pNt]baHL\c16G:tR;ZuroBk7'e9p;S9Y:;H$bdDBIdJ.3SpBF[9.9>cH-9R)JmU3I %Af]bgHDS20f$CNU4o9a-?]kKtKN$H/D;)Sc"bql`bZaPn_c6K[$Qg"%Vp!Yi-fbA["+G-CeVH/)NgDo0KK&#(2-\Zs3NcS[mj"l7 %biQ:CncPB!2f%a>?Gk[\MGJ+Es#d!-:(R;hjF*lZ((rbr\&V@Z#JSps\)\A"UO2^Z %3&/-qZ+b0Ls1UPWSp#$YeopLdjFj/0.d+e,o@C=H7N]qGHYcu6e#h(gS?/>;iSD0$kj-3blME_C7.[d$`LP\LDT^kErOle:N3Ii: %L1Nf<*F"iSSGcn'j377)D(]h^D1*q4mb2AmZ"3?J?Yr!6J*r5-0$h@$L-C*#I[ZF8gT+9E"EYYrX?J`ol%,t?9eTtt/+f?Q=MEKp %T.HC6S3`ifp785pk!1T2^AIiYH\S+m.(sr`ZLkKSI*)AY)d^5PdPK(<7pV(Bs8(n?^-AReo7:2:f">tJW"rZsB/\TEm&MYohlrk2 %--!Z)?`m^Yhh6aTo&n3DDtqt#mpEYRjZAb;"+1q-J%9^FLA0S32Le%\`T!4!V1*YD)91d%mX93)ghW>_*e@\'r<3uWN6($ti;+P! %jC*9Z>M.ZXhY#4-H0o@UY^H#1$%TUI!t#G76)6t80/"K:399g:"B28Ej[bYHD,]"nXiYSh.EE^X,3R/,f?;tJT`O3ghk$j.RY\"(?3e;84Hd#(/>)Arq=hL&I+q^f-=[a3c*FR"Ukq+(5srkdg3&AJ:R.71_!k0l$pON<;[A9djVCh-D5F!7r&KQtDIo5E823M*5H:OGZee$HGI= %,?8acG_7jYBJ6C6K8O*RM<_"eGW+1a9KA4D7hXsHg-jdMH0?C"l\\:a>R.u6mul[R2$Z4Lj"_(f(M18kGK21_//h;(>Kr>N0ags$ %.7D*!9h!W!gOm1:&Irb[eLZi%qT+MqQDGteMTBpC"]7K/&pBDY%J+V^$mm^hQ7!$-K5s2D!?5^-%9Zjp[.12Q;eEKBJd%pNp#0-c %!*gXhAmaVE,7_sSM&u!.E$EIJ7g)Q.Eem#K,4AHVO&uS"U$kZ]gg9^B&0[576Xnm9@DiN!&/aufEF1%)X]\U7PV*cDXs?k=),qBY %DF+-19I&jgb)91:*Me'@MBW_+)+cNn"-M$6Rt^?sRS;9E$,[YMF;E'_V\TstnR %,M,h!0Jcc5)%d(jE#+IY`mJ3`HjQWWSqY7F/TD8T2FZo"Y@6@HIRqC`DX,3D["g+uMA1J,8eEgaR[,rHi@/7S[`qWLjMj&kOUB/U1aj"%/.&qa %lUhQD\9@59b,Jfb3M3M/iL0i_*-n2=G.GJ&0M<%/>Y/#TY_s`p7T*bAU1(4la(G%&+pJoG9'DF/OF0cg"]HYn(Q-:tULleY<#\i&A\0c$dn^UZ %AJH>0*#T'IW'EpUjnf\G"s90lIAM7B*D %l1QP:nV#Gm]i[m--:>l3d=Q%?"aRum;M^hHUrOM/\eE_N94f)1/E'-qfN^\MG[p%.%_B[RXO&,<-`M*D"DUEKkd$VNbaP+<",q%+ %kj8N3:4VNf5#fgefuMr$a=Q&#qC8ok1H?`segM"Rd?k-DDfS[DqEj,&>VTk*X:/sp=LXbf#:51GAllf2c*0LZ+qgq&UpZ=2$mDIi %n15]@0i#.#$23/[P/u

=$3DA/FhCO$Y"ZE+ %/$=KNBgkVCEqNE1$lE2KKOE8c(04Y.$L3q');gj:ar2[SlrofPO9gb;l8u7MI?;#A;\iCH;WeeRDA'+seHERSP^H'oYp0+E:GuK( %Jafo=RCK6V19ASq:pDQ_,`*RO&TjBD\qp6Wg1;#_;6oFmli<]R"?Qma,GDFp*u&>"5r&('m)I2eJcVP,-*dg;m[-^UbHg9n.-7+n %mRgsT-!:FacbSm)^<\p"eHF-V*GQ5Ej\Ai^R:_148N>c""?NElD\?ZK!iLX`_p4A,H6cs8T\D#Y)hMg\[V)nfAm?O5Um4R[N+0&4 %j^e$LYW+SkoL*E!4SarWg0']nG3na"))k>[(8"3X5CCOa:O<).Q]isgRfq7*5r[r((:<>(.b(&%)_E0sIHk!lD?q,LB!Uo//007E %3T$h^!O&=*H-LqI4ATpT4nV3G?=n,'LbRG7U.)+c&DDjaK`Vdq8Q\Ht>A\d33jpOuGMV!3]6NZCi>^Ig1=0jZ0masN>7lfuMVHAcQRdZ89)ueV %m+m?!VB>"JS7m5/@/Dh"KKu]6cEep/f%=.#:D?s!/>"R\.@^"Yl%D,.,QPtQa`9DOJWu2EBr/FdSe0V%Ehl<\@]h=7\ZJ$+.V$K7 %<@D'@[$c^o.ss:sM9cNSTQW91on)I-G*hFbE^Ci"n]-*-%]`ehmeeD3-_Sp]jtVnO(OCm)=/r@:l1=e`Utc:1f@)KPQ%@ %2Ej#eSg4q1@Wc89EO?$]b5j%8DkKiA->gdA)7YfQEcdQ1Gkj\9SckL\3'$'"A"0T9-+cgMU/#I(\q8pXA%(\p@NkE?[8.D;8$$\n %Nl0F(ocsc'V:7)tq&sp7n2sP7A!7b.TXHMo$J3`#fMAV`h5k48Cq+@ulTrD(&N3Y/I=CSnr$'J1G$.cj^sX %/eU0kGUF*e;.K3XGkFSV8Dn/@*PI3*X2J*%lo7n,OE`+Y/5je1i_/8=A33?;W"^A>8t++8,;#B?9tG.e1&n1A11p@#dn.[/*/$O0 %OtCF.bsFh7a^3L;bj+Fc>*.IVaM'1M:@u@&T)(4M&ZrcpZ`dVmQF+B-3GPk.MI?jHEp2S/B#$6,,:SH^3E%*4F\WXRI%3Z?*1EHq %dOl)(CM%3Ni#F_:dnhK-BeGbN&dJr,SiAOJO&GL8EaK-^1$cLt6J'Jr1:1JGY^aRp'&#gETVtb[0Ys*t)q?X#?H$[HYbC.K_,u]!AiFlZ&=Q-2V=+:]W]5h=#uK1q\bRJGO:Ngab$c9L[[tPgk&=c9k!`bC %8J%R:e!>bge_)LtE_O@TNd6V3d9o&fEe#Ah@:!l]aCM0[@gV*(a@"33@[gg0a#;hYuPNC$1fb8MYl %e1(3"GWnjSV[BFSAI:#;ljG,6(?c7u_o#qUmitug.(Gi %NBII?Pe9dX@t/@sn)dTWlSNi3@!AbPJm41q3-m8$548%ZmYPYNH91*5J:i*_0mo0!_p<&Lp2oY?AV$X*V"-Vb#9ID %"o*W&GF5:\I=i"OZ[68H]ud+35]G=b^`W %?q,WlhSZ%-B-_i'*<*cW7,u*Bec;>-d#?6SRr8[g6Y:]\$C)_\=&;I#is7[RiP1oO`8UrbOXbG^Jb>CUn9r.eH63.&=MB;Dkkoh&*"IKlLnE.OD&pf]Q8&:.r_eBi;"HIQWuS&Ei.(8= %:hIg6CEr^LJ%LXl^<$]WFS9T8ohlOO6Sp*Trim!.u&TYUsG=^bAQh9:7D9p[Ys_lpSsH#[8M8=qq8n="$#nJj/:HW"eV>-$'[b9 %"NY5r*!h'K_Y9q@JG01Z6Pepd0teDNVhfL0j5&OW>q$_$iIW#O'i, %l=H26A>KG:_c#W\e<@>cO57a`o8Lj%?7-@Q?J4rag@Y^64H`!ljSAnBTLNNu9hs@Ki/'G!NLja1dC(Y;]/3m8-K`O.`2kkc*+cGh %9Rg-P2lc3*a*K.hK2#-3L``U\%ZFqLqnRXEHb-Oo1E?Bb-d#L,I@),2aY'%u_7CsNPP]s]cDs]X@`EF(VLlo&P6]&\H'X,n3\XT38BU_!WNe@=!0I@gSA_PLudaSn!GZZ\0l %!7XtW;,Yci/YSa]AR'C*KePd)2j94fTp9'd%\HVV>=;/K][]^=f90"oWG2dUU62?3\.bg\-3rE>L;Qkp/O#-Ue;-ma %1@?IRAUKpUe@*40+u[.`;%CMj>M&.]nMUf4ih_\f+VJN9jc'9DI0-POg+Mum&d_m-c%_V[rBS`Qa\?0@#s_qik.2mpq,o.N8Y"#- %Z7BH*B/>NB$?3UgZ^i1Y2r_%Z_0Q>Ir[>EJf$[1VmZC_JDUg1'b;Xi)/8Z9+"dVrM_d%9d=Kb:mA6kqUQ'e(("ClV^(>WbCepOX2 %`$gsto+HUfWB8TuXHEcnOQjT&7ETj54uHfQ/O!B# %@$GN'rS5E>bGlse+C4tQ#tEiIUgSkgL_$F%:Dfq5h1_#g,4T3+4AS]t9(QQW3[W<(FZ!%2^hdo=UR9g-4'%.hYahGZ_ru2+Md^6L %B-=un9pRAPk_bKs87#%:TGX*mjAFhJGh/V`,WH(;,p5CE2>,HCqZ9@Mk9C@SbhX3mELMCnH):!A%2"G'2&Ug"1/R&1*K;Jr],0dt %QT/-]`!W$a6s].-Ej5=F-rhQ+OX3:+q8AB(5Fb$*S64!?Q>>b6rE$-)R]%Sm&Sm?gmm[/4.r]!PY[Jp$8'2P--&[f$(.lA8WdHd^ %a12kFgG8)K&igY:6DeE`O.-oS$b=gU5-SN(9)F\M%r5^MOBj$BZ+fT-#m8;ta@]R0=a4n_+eP1T\]u?'So/GU;C#(rCuIq58DK?U %M!e$M5f-%R!;$XUcpQk0Sb1BfI&nYc>eUll7%cGVXO\[E%BTXi9?a7WZ+=`;$q7n91f@^GN>QqDC,>AGr_Lks8nVqOPeig0lrti1 %FR0@(D+Lrg22'PjNckL"Y1W<(k3"KSV\;Hu@oms#TR8g"0ilqZ76jp:6YWnl*5O'2BAq$o"[As'%kpB;!@^lO?8r;? %BJFO4L$nW9-,YO-b#KWNb0NU9$UBAi0B07IeN*N#/49r(*X=ZZ:J8@fSX9$&ei8"+ORHcJ?mG*Ae@ZM66a"0PV!-0+:$IcVF#s)D&uR[a+8d]Jta%2_K&qeu2Npt#C8T(?4=:,T&8!!AfrDT6M?F\MMJQ.@\8_W1D+qB:t%m3-#j %Q,!S:3Yq%J6U_QuPCZUdFpXU(=[X/4Of5K8peE-(Wkq53Vn42+b%hbWHo#]Sh`lKM:K^ZNd.7c<[&(6)S&a(JF%D378i45\H?$D= %Oic-^S:j1s>Brkh1K(k1o?OS,qJXqNr>u-2lA&G`*7?OF[XY9+\gq$%jP1&)/2JdXBaKM@0eQR&V]r:\8E+&ql.H`9[E8(:3rm3B1jO3REs$a!M/E^R+Z)%SXA@1pgk'P7'%G9``Nl\1e31SJV@T4 %!I3nZb=^^(MJ'Dgnl[mQ:iI)YI61"^"f,)R(IbIH#B %6QCdT3;#UqB5Vo+*f%PWB1#NT!+*TS!\p4/NRBBuVNPo)5m0Q,,TP/aC&^n5-u^"i8A3Xlre/)9Y\\Pq"mcAto7-r#4aX,&UEJZB %=b$M+00rPuAZ?.mNX.&[E!pLn"I^kVnd`Y<+[h)>T?&iT;_siP-Qt&:GCdW$@Sho$J77o&INho#-6,RqIh_sc&;J/rji=)OJDmA% %`U\n_A';:mc^(q6_dB)Y;b@[3l2c/\SMmMT)os2P`r%`18]jb]]bFPJ'3WnALijE16n(kqRtM'OCL-ipSEg%>1]* %e*+YS^p>0&a.&q4/ZpnZ0[^4l>jhLj_Kopt'@^/RD\*d$e$-hu:mn![kYIV0aGBE4-d:0RGYHi1M-`ICq@RoPSh*3?N::B[i53LN %)c-A>+q4SUKFjqIp)n>,/.i)JYGKL,Yo?WlQV]ri[!-RNE/Q]8@dt_m@B^Bj#GQ."g=S=])%b$C$Z)bEQ=u4Ea0Ek]V(LQn'2/E4 %Yp3;5#fmL?Z;KoEA!VupZ#gW*-m4*jC+J55RUcd!kY<3='4"j'DDgtg_9FQ#TE:<*@Sa#2On&q?HchM+ZZMc=HrlB!W1GH@%-q2, %[>7(g6C'N5>'@tT^Co!l2[4`4g(@Hd"-Sd*k*jT\5XR%&LuhnM[B'-F/&^)JJd?BN=p2h\8s@Y1+e1YrT+H;OTi)%o97/$;budbe %F,`',-`..X$XTgTg4Z"_dYq(K>bUO.&s(??F=p7Pt@b>q<`_t-UPC#_.d<;!KWsg-_oS%C&&G$g;K2q9B+LI=d'Oo,faqoTX %FQg5/)bmH"e00h_/;L3&[eVBHV:`epPuipGJH@+H9gVC##3s&]#sh/r%MA!<_FfWG!"P:d4>shk`PKbF.SMJRI3PLGAu,!/Eb>E^ %:aJq'n0:G4NfApK!1L-!i;A_J4X(cAMKBK=3!r8.IN/SaZ#6NEPb(LTWH0_)758VRQ,ir]Vb"[^"=ZnP4',ZM_E#T5>9V$bVlhfG %V%gT1MH<.gW]4N\q'=5F0O`4V=42Hs]L:DO#`40Pok"5,UsMW?DBL<_O+Ogia=NZ4mf8:VF1Uq/a^(5//,JoF[='1DIpM[0bY)&$S_00`j'EPBnOC<;VD5(LiO[K*eM1i_\--/ %\QAX54O^tm%m]c0-@!p+/h>4)*P_AU;Z\j'ng2)KMNurgX44O,i_HGUR-AC,21RJp?i?692;>_((n^&5kVls7JV7m)c]kZD1h.)J %S\nX!E:X,1B0T>?_#rY]nM6CoR9a@iZ;tTf@?'ORQNL,(HBLRe15.]2(L9fFkYNE?`.Ord>@oBQEoK1GYEsKKpcj2sM_cJ\MO"%, %JKmf/--Jk)n/p),,*i_'6k19gn']lViZ$9reHKg@5qeJub7dFFkGdAV:n"EYKeJVqA2k7T5\#jE,,Ya!2YM+0TdL82W-.3;2H2%A %*@445A5oWap(T:.Th"5,>*gNl;\6(LHuI)'aZQRK'W\m]Y`42T'1nR^c[KnolNk-oTPu+#7IFJo5/rPBM-E')_i-m\Qar5'M[j\^ %4GZ-3Kl^EnC/Bo,/cb>%eFjeT%+JCSAUlYU;PCS))8r,NY:5&5!$N\ZTp[$`V6lrc'B3R`s0a"(JZEETO)g7,0@L`VkDC)n1.\p- %:jiLF=p=#Pf.G=oSsbXRMIdekq(ptYfKn"b#ZssFPB-m`,u/R9!&5-6?V1uk";OpBdq3d36X[@,-05Gp"!+BR6KAfll!m4)p0*TM7T-`T/LjStP&!o.K?eg0EDM9q.WQ6QU?#d=2og/L,bk@dOfnq=o`\>r"YQNVkcTO?%N %8J&H?bdF=CMTUIl'a;RNJlt!%GRQ`lFL=A;33ATf.CFK1i8ZMr3:\6PA]^"BU0'Ki,XPmAM*LPQu5.tdfC*,'a'\j6&5OTA+5&K#S/+)L13,.h+3?u-E.S1U0.L4["^/WUVFtrA;k<9s@^.=k,mAfZ/NT".Z0PQ!>s^Kd.*KgEGe\-<;Pc/nQ5=.mF+Z(U6ARS] %GWCh1F(o[G6UMi@nRmNHX[bG7V82/JR'qC1DE2/HRsrP/CfcPqG*eeK+9jga2']?L@bId^F:n@mTJCf3^_s`g@j#kbNn>PV6:sO5 %FD-3R2!/-+,&m/5?-:Sj_=)L:N^GQJ*-Gf'`_hI4qt==>/VFdKih5@dN%ICJ:-gA*fk'j18n/lSjZM)/kE$6pL[7rRqh#d%c75OO %7F8+;66I>&^93chM\:m;M6/Qa!VNLs,E"eee?`.s(^#LO\jRI]jAZsLEkhrpQH!gFm])Gj\0f_#Wk(P])G:QR>[86#a=P=0gh!3WP!#[D*g-pfcEF9EL+eBug!eWTA6dssSF=?'Qo$K,TdWmOQN]9S?0)E3B]V>hYXM/+:Fg.S %*7&<[H-.q'a[O4CX0o,T@Y>LrE=g`^8Lhj30<$!f@d?Qh$ %o0F5$$'s3j3Ht,tXm*pUq9>3#`Sm0cSr5_90mkjU`1diA>o3SC:F3!'m?;o_A>?epX7do$8Ai:`$J_%O?Q/#G6B5-(XIkQ?!RVJ; %+H_T0#%Xng7Z*:U&D8eUcN%gG,?%*k-j&!46At#>?OtsH76-K"m0]]s7Mm@KY\2t[fl?Y#MJr/s:Cn44,XV_'b)9$l$#Mo_Q\W0: %Tp:Gub:+bjNMWk>7,2Cp.qmI8_2B3@J<%m"Ot*r20:,ZiRdZ@/<7R8,17@i73O#@n!iHZ5LY5*G6@126J1:PRPh@RO8=<<5PiOCi %;rO0<-(5cJBjh-ffGCP--_Oe&L%[cI46_]MIk,,=4ODj*bAEM@"*5FaQ0HDW[nA2u\Wh$e-mX'+G=V'6?6]Yq*M %'C^j,[HM*SkT]!\Lb&qnq'$&Z-jsK0Rlk`<-Hq6Bd;O'ql,&?kHZ:Y0=beDH0F4>iI5*$;m %N(V@lCuVAJ4#rEuTZIB_6'@0U;OM>Vbp,"$6F#1-d2uQt*fuC%7qJCpI!Ua8!LJ$"jl[EtT6pBJ8**[3ZL\aTT]0ZY`H.FSB/lE8 %US2qjF)uKIT=S'A8.Nh689OgfD[?;$pW6r2!88?@+M4?#qLdejq %;ldTp/%")K.XED+SZER^Z":)m3ZA<$mcZ6H$;9n=]9"O'Rk$Lr9><1P@TRYq=)a.7N='>^c$%LeDu-0=0,u^=!K4E17Cb)jV*PT5 %i)SEmalI108R`=)b1+Hf+Yp8tPkp>l#c7s13$dF!Dj_;h'fpib06J+Q5$be7p2Xi^c0Nj9$-M1f>s!fH.PIY1VgGH8""d/#f,M#8#/& %Y"7RA9@S?L1HHcjG7r5,7aW/X:>.\sPpTVcfctKP<'68oeus=G?ZsrVa1ed0A"WuA6A`=Jc?:=#[1l'J.V(/$qReM@PU]6^@sp8( %op`XBi0N_A-l+\^bE).].Jq">AY6cnq7pHc6Dmb %P`).lbbEJbCKf$@1RC_nkgh4XMY7V>_A'8Y+ELj8b(5N..<)rPY,CK%)8d_^GgVoa<(o],YP]LgP>)a/Hr%,PZpnab6UBY(N"T\Q %/TI.l2AP%`PoOe/S9DPl;Aqes#>9Rl_%W4p%QXhtU2Ua,5d6U;2IONoM.QT5$FC4p04h;BfIm@$B/`lt"fN7p:a*W)Z`"_$:ap@W %;NQNKX"&ilPQsu`$FJ_h<"-sK(r/ulfYd83Q\C/n$mMYbE5H5gQ,6HL#-sK4]LWNt"(]Q+C&4(MSV>p"%+;*hcsnMhbE"(km12M, %@G:gT!-'49AXo\cRXsBq-o(;`;N-QcTQAN!duuq)f>Loi60]qQg/nA1=#JrbZM>kBZrUmWEM=7qidb'upk0d.ihN0;6^EGEG9D4d %ZO2rZTB^u;H*3#p[Md\=.23t9M%BM`8&+i25d8A;K7U(@:Ma,H(Ad^;]KU?U=@R?O;s6U_7DqS%i3JXC;*B]1-t"d,4sD8-&h3t1 %h:OK/$YOG32sC#7D3<;%pub(Y%2mrY8TI-l9A)Wm4-ofVlFKq7K38lpNLGP*EcD,rhCErU7R[ %qSV0+],\RF`;`8$p4)F_qXIp_oj)mKq5;8?C2=*+2Ru&op\H0N>nu(.:<``_m%X;IhWts,[/$Uqh]+^Ulg@R@ak;VA0/i-MoWN"W %DKRJEq8XH\Q%ln">Of(Q5%<[,Sq@:"2V.W'o%R1/J'^..9.=ojJM=m>59\X %9n$@r.14r[p<$aO<+X6K8^W^\XqNMCp[CdtfRkm>?VHToNuZVF5N8VbB+>u'l!X@C0aZUA+#<+j#R0FZX(ljE.BG8ig7;\(a/40r %Z!E>kM]E$\R*W^GVDAW#>fAX@lC[8Bg;tprWUs$]OgV(N%f4PO[3Gn,je"eD*qU&*rbgp\>jaJ;j:,Jf9g_DL7t'2)@hJFPO*mFE %>#f?\&*T%&-L:O.X?+)\W2_bdCg[Mj?U\n83rZ(XG26ngO0%h&2+%TB)`;SF$_NQ2n-;s;akKW>#Ck[)[=lT,3[.I^.fOof+:g^U %CE-VLc,"@o_[r'JI74ldhi);-"[:HFYc9TE8(;`rWZU$(?b]Xm2NQE1_eTLH`pp%BofX"uGfBY*@T%YW@?\ %D\r`hAK='dD6Y2DVT2_["4t#SGKSkCglFfskruKJs(h)8pCg&_KteG^*=0YqOG&EJQlHOCZ,$Gg9X9Y7-L@O*4&YciGh65]\nI[/"8O4P5Y\@/hp/:L*18&N90ZN=fnhkHI;li7qYI>IZL=aR+V#3ZN31hi6P!N_a]%>i>2fM+:d&J;Kh!_6f>%&(IY[`1\C)n`Mg %$_u6]df%#[A@oe>-BB_Id=6F2^cg!R^,E%b<8cMIlcfj+m?;gFr9%`N'Yh7cX@@hN!K]i=9+=.^q%?&1i__HYJLZ:;l_q$2,5X(* %jW!#EbiWG*_WZJM+n\q/#L:r.5%KrC+7[9$8g44PAuSJHJKeK=rAj5)[riba<*eBi^+h%s\BPsI35OY/kC!)4r.LCp+A:9,nL*-q %s&8Jr^0+*^AG;9b'Ol[8lMeU>Nq).OH`QsQZQ=/XcbQ\'=sfZ$.(LD'#rh%ZqH/@+Kh4d*9G(#GEZadN/pDQB\C&M1\dS;\=lB8I %P^AU`/NbJ+2ld[,L">$iZW+m[8Lr87o.e:]Sf;\:ZH[d))NPT*m/V:h[))e/-e5EHnUIn8riJ?3b4XQRU$_m.YZCLk]C',kMURL2 %K-mW")h>nY`A$9t#8b>Y6g@(94'Gg/?)41oFumSAVT\UEX7S67kuacp0-BKo9G+<`4/obARmND>jV8&-bs%X_oS(WP1l;!QA%ou@U^eh)OVXSGB=)]5I\FehD)35!A4-&(p#0sIR>Q_2cpF[-F89!5nAlD:iH.%&%]q="3q_ocT+6a %U(f20+*s.XLV%Yo:IL4`Pa(+4PS$p^5pEB/A1:hbJ$nYC)S,^FjAEYn(s$6C;C_ %K/I0,nIK$As-7m?jmL>5PlBRqr5X?o5MbO97esZ`qI*2%@a%99U4^iAldC]4p4%ZS+B>c8_`u,Gs8@rmGU5UqX<;fbn$0`)=4E"$dIX$=R %GPAu_IJf+Cpg@@F)9!L=`ElZ-mYQ`fd;`!73@Xs8^8$1ll$UnWZ'bP4Z*/p*lbC74H\:?;)!<9`;`4p2.S+](0c(VsCA*\)c5t3d %@Ir!Y0Pia2]6\s6%G/[?BD>9#W[1N1nDIMZ,j:3d%9[jZ(X8K^Vqd6r7*U#]\;apE+2"PmLNnE5kqhJ?g %QU?#p]:mC7GQN8e"r\acsd'YNh,[J.2c7@a#.4)CXga2(3]dNlMJB:G?'.Vp\EP?84@u6j42f-f4bSK*6f.6L#!b)]ZJF %CET9k.2G">Ce\^\;#D<6pMU@qf\[V^/D&tSYf(Djc7_u"_Nhf8q&dT&53nI('X[0e"i:*b2&h$<= %OolF0)6[BZ^Go$PJ&8_S4U:J_4P;Gr0Y79Ja7)o4'YqZCgO>%dXGQfqHm/_]> %J8e!Y[fc3E!qt;u%p??Za83j9=#kOD&(Y1N`ii>gJ%rq3J%c6i,,;dI2IV.+"cO&"q %>P!Ap`PJ78^i+M6rYp(drqU.uCU@8^J9Q2R0^&@]1?j8cO%'rclT7#i+(=3&#iSAt-=IAj0fGUYMQ\j(JZ-=7G?aeSebir\fb/Q) %/gY;04*b2ZB>Yk@<)N-V>8icU#-UeHO&BD6CT8cIW1T+FhtB&+r?_B5U#/1`q_@q1&\c#EhRXW_n^c6-i%8$b.UIT"A$nf!fD_f[ %3MG-P\pu]mSj-9[.$1aHB8PO,mTJiE>lXQ\*p.]to&\%q.e9Y/?iHC7r6%-M1$bM4f2tP)i0'N'3sF;VD+VN(G:>8cRa_9d*rg8A %?cPMfb^><4QiZYZ>maQ'IOaeuGbTAJ2[:WM!krm;i#$cgb&reR8IHMtrN!;hJ[:h/%6@!Q/aR]#GFc2bK!%EGSn;8,Ij5hTB:H.e=$:kcFo>Q?5naKnD %r4/ZOhhIHorc>Ff1@OoHP_6(CXbQ5ekV\7e=aN+oR4?F)AkuLeqtb!K/Rc\e*U)R)o^TI]27/%>TG9%b1;Uh_;n0@H7sDA/[nc'- %F));7c>:;K,(%PNR*3P3X5ud[r$7.mi!sh9a2?\ldU?`?mRHoUF`giodT"/2.h!\ON!=%XG_G,H9#*8<$@RUZ68(`q$%#mo&7+UE %o%iQi"/d'SO"r83B['=2X#5W')$JC3RU%K6Cs0=+_!mC.Y584j#LrXWqZ?k2\l]GD/"kMAC?jc>&rZu&g?!]C>^m5B/+d>X>TbEp %9L/NkK,_$mQIaK31;Z,j/--M=t?=1<\dOB0)Jk&A":=A'=' %-_T8%#-8KH)_lL]-FS9aFFa@\am!hh_?=dn01J7i))!5HPL3"rBXO52AWN]JHkpqGCFP/oUNJRY-YUrZlt/DihK70%YtBbL"+ZVY %JSALLRVjI">dUiTfB@`#+QkGe>5QCI_liIeU4.q=$VI(FOoI5.bi!UD!!J+k=V'3IKX/d4QYH-!]/W(UU/q6=d:BI$ZJa]IbIP+G %T/F@X$GCR(cW6T$]$&W\#_Bogs6*q;MVFlg/!Y96*hV)QXqXaeh(EG#FEFa*Kp'7(`'j*^^08H&"q`KG]f?6!]p*0l!p*[XroA:l$7!D(E_3rX64J@YSI;u%e;l0A5nhcLfs %@PV%[7fC(`0+LK^_+7N2N)s6L%jS^`j&\$DMN.jsGVl,'Rf=5AeR-!.P)KPX$/NSua^g=p0Bc1aXn5[IMN.fGjMfMLeE7BG]gc&A %[J\!j`>OGG$gQ!gT^UBcn*@%9LcNW/?/#!2^Obmp>d$0F/Gm=)EanrekmoQ7=&36c>^)TLJGnVmfQ/*o!UFJTJmG+j1A:uE>.Jk. %nI3X[q.=J4Sui1RP]_%`H["c2fuKue0sik$$a+n7&d_'->pECu]&`5)#Xq[3op1gWSa4KV-TkSW-f+IBg-\@ACjs'R5&k*!GZt)$ %['k_h=^-f:dCS'O9h+Fj#3Xb$6*<:XTd_E)SOP1aL9",,`IrY1+s38:lrG>:%k>\#dpQh$LCG`GNR'>"IC;UGB#^_Wj\/qTc\kQ[%585DJAMcJ%SZ]!MCE?Vg77S?9?+ %"ru;c,,LSUHj7@6DVUkC('&5_5Q(gFjo_9Qo>Q=!DuG9C]U%3#j5^]dHk]VOBSfAB\9/'Fn1j!nS$;Pj;IQVa>+HOoQNLf %=aL%%];9Uqc-=nfA)WbNcHpgGZ@PY`k0Ou-6A+2]1`d^m/Z^Y_)bV[Kf9[9u3I%uG %B_3DO(GhQc]HhleD2sYV;9?:Q8?j?"Ra$;X4mUE,/#Yuh2JhjQSMUG`5:=H=1)_@8p(Fs<\)Q;DEEhnft(nB=898]b=t,b$3i'&?[\BG(42L*&h%pqENKWJ8*K)XgB2WD:YHgY=C%9grFLV %>]IS$)Jq`;F,GcgS,RHB:nR=UC`OKh,[7"qB!plCWsUA:ZjKP2iM]9kX'cGC"`$eU'q>^t\gT=5ZVc39@m[aag.Y&5&TlW/]L(1e %p"9K\-"=uRXcVh`h$,07DW4^s=Tj(,+e[3^@_t*3+X57MQm:t!"CX@.5[oZ>4ORD %&''68$C:K#BsB^L64Mh'%<7_8Mdo"_/7E7'3J`S'f2RoG"Y^-T#_sL>5a5meK[Z'"rJ4a %Obi.aU^>bM`I'Pk)&m]YS06loL9)gc=L;=O),n]F5cciN%K%umUQd.Rl8eXCoT@(W\pc9)rel4m7FnO/mnj!d[eGUEqm=6Y#]`' %K/(%m#/f,OG9H4r*#SN=FXe[jOd,i2)g?)PSrhab[<*'L:nBGR:h[M5.(k/UG$u8VU1YdK>-D)qSmX(QSa?/U^V[ZnWB'2 %YEFJdBl4K18MfR'RR(:I%=Rh4\hdXI-&gk:@1%2b;n,Jf_Hk"emLlC9QS='(`&@$Q'btu`-RNf!OQ!?#1(nW_ea;-7mLj,NQOr1p %<5!!q^+kN(OY$uS;kKdm$=uWiIP*tW+JFDf&K-l>8V8*%6hH0Cd=]SS/DD8.7Sk4:$J-M7E':M',O;`rJ`m[`U2/Zrhcb]sg'Vu@ %0VV(5Loptu'24iq6X_mP:\Sob$HI7I'A=.qVG6#&D2M3>Arr?;KtOc1jJ>Qp05Uo=Bc6Ik3R$Qd%3mNC(jTgOa@hGRQh-eJB4EI7 %)&0VUFIX8l^.HgWUJU76.uju.5A*[`^fIfUV$&64O/p@2TC'o'd,5Iu:\01iZSn6]e:F@f'cU/Jjb2_Z/MF_#G$V$<>PU%^-B,Z< %SZg%W(\?=ms,$;=KlI8-.6H:l^6Pmgeq=e'6%-F=`3;D5inc.'%G\Eop_]n3+(pr+5Ng40?/*u1qHZkBV5jCRNSjpspL0!O[&TX_ %hTeUSngYpl_Y#>\M_UnZg;fH5='X6c[_J@,]'F\:a)JT;r/AK#^k%+djDVI2>ND?gFJLX`N&^Oset'7J-Zo"h5&$qs;dQe324hm&[S0k5j.)$qqFqbB<":ba*.GeBinFY<'s:e[o^CkL[P;tj45Js,Dc>r4:`6+k4_)a07K,J%P6'I+%b %k.;!J;Kt%J34\'-rcU0;-P.k,!0%bg1tUR:!1.t1F0#\b#t9c2`'MS8U&jXqGLMXHr(D\ %aUHN62YgHe4UJ#CL_`Yl_\Hu-`[*@uC!B6s8<#5+I:djYg]1J/1R`+7>)oHrkb(S`l-8_8?qUq+SE:D?:CnY6X8JB]AkOI9"\k[: %.&naeU[mO&9>gVU5KKN3c+<\7?)R(LR>tL?8,\UJ@e$Y0gWY=@>hCa0WDk`64XBR\Zh4dE>Q*FSOC?E4d>i(qA-L2$/Puk,.>]RL %5uH/":,:_V\*Vp@5;"f\`OOL'4ELr?4$r6HA:PC1CL)E"X_`fX(%qffJX,oScf**ZlMc@Sm`qnCR=oYbCNkIRZR']#,sFI>APPB?C"VlQW[joOF^AFV/h\2!lEAj.CEn'($al^m>GVS('dI_1GQ*foS=F2^iF?6_df8IQjB]6kr,C[jhjlhm:\t%X)#Z>_(#S>LbfD%AlGf-bUUT=JomDjj36ti\V=/\nXZ)LhLHc]f2IFlu8\i:#8VU)5=//DF&LU50QQ1U'",i<+HE5&mcYf0kbfR9,(,Y.Z,(\X3.8@\j%@;Z]n9UQX&lcr2SKN\e)QV9pUEVd7+$oog^A"/E=tE] %Q,\=Nd\Tn9YLEAXNG5!Y(Z1V*W&@WZe9rHel#bZ$'=T)%;I_qn["$'=6O$g %"0%m>dDtHP5MIZ8q$QSag39gVFWKS<^"_l%8thHo[QaTSCu_IDO_ms(f_oXQVn4KmY/RjVP(TTh'6%!N1Vbf6B[/C"o9C?$o]-=i,rO!N\V %1,3878On.!bXlSecaM-NRr)!EG#AHeDW;h)2Y='SI-`pSb0&\M\Od3&mc0!Kru&Lq/G=luDdg.\qMAW*Fi$q-!='-oH9'_?-S`'# %#2Vt.;JX*8odeU)BV3u)Gk68cb?hmE/kYs6o/K%eH@o+E0Pt=^WNZWhga&?"(]'/pl`%p0V<(7ik$W2G/;@5[o%5sUTrq0'LC"X_ %anto-Cut'\n<\W1?J'U]K^XT.PX4B+\sgCs8#oK$EQc-rKCV"%'k()i_rU>%./Cl8d-JQ83e'9T#5rcN4r/m^cFUKtmL5uGk1b/) %1eP;O9F($h8i5;6R"&Z7>1IMi(r(O(3)=rjnX0X&U?J4V;PiDencAH3P:6.FhoFLPQpWmn_gli/K`gee%BgcETSV26kJb9P=JKnV6hXi)Zf,EK;3CDh^#mFW %^7IW?V#eQW'J\r#cUbf4J&X]G>Fa,[R$RLbqO']E0onQ;5GQIaFcG7TnCRR6fh.> %9;*G>'JuDgM[ViG2#kN$DLuKL^f/*kJ@.X,=_9-sREU91U_%WOkh-:19GdqW+U8UJZI5E@-OVZY@oE_.r65OoMjJE1J)TV1C!Eb;]FhGdYW-25_0glc-1m1`J`.jX7gcFlpkcWB7kP0jYW/J+R8uX7bq3A$N;qm=`=+6oA8k3S0as]Y %C0]q'-(p,8B:60+!\;6k'N5JHNg-b[eG)WBW%puQ3-c(4ABX%BP*C-0-Cmk;p_LW0%Ee*s5^+E2OmHgd^foM15pE?p.OY-&)a*_" %OH`m@$,[@!CD>9m3G@C[#!)$6Jg9/s>)<:>V=C?q%Lqr_0G$>-#JbDnM8i-5(&j*l5JPWKoIfnK%/_X"b.U2dQG%SDW.A,T>K?q: %[WPZ@PqjUF[Q)IUEX,tbECWI/al_<&>3`1nhTQ;RYka0#%i%j("cc"9KLdVT>=mgtJB>kd@+5u(_*3uq7OGoYWTBj,;#NLPWn(/9 %jKW%6L;ugIfFEuqaG13-M_dO]-Xt&Fs.(dlcG"#_.(RVWHS]HoAt/,O[-4QGgsWZq;C:@-E(7g+7khZE!NJqtn*F%N`N/\f*2(eZU%=J_5D]o!Un^gNLrP*0>?[faase=R>`m==_$k %YF;.^isF5tich!A\&4I/8_Y([22*SVYq[M3-s@O!@6\;+8qjJG:4DgM%@t.-SKFN^H:`WYqCNJp)9gLh!ePm>Wj0gjMpN2H1>CJH %ag-_KH%/)jn.G/[0`t[9dr1nX?+KNu^32[s8uIj=?:j*$YslZ_p;)o"#Ql.^mm3_#_%20Q*QWM&B5jG2:=2JZN/HXPKBE::1b'0C %/-PoYWr7i&RMZQNH!&G/=*j2.'8:Hgp($50OWp_ZI3J(Qg?*[H)(>uS'tIc1Xpa^-^,#3B;M"BIM@9Yt9,5R!"N.`U:QNP2F;6=> %^3CZpib\3U3>9k$]DJN*UX2q%eut_/XrA6\97)!,)Yff11OFQ']IO^Z"7Cknm.4^22W"'E7(q/U#WB!DkJPYHD=3s(6!?ofHm&@k3UIMBF8@.>\)IHZe2:$GPL\r5LSn*I4Sbmi$WAPQuW4.))$2JM&M %fk,O!"oFHd;OL`n!q-0HJWtLK%2$aritoMOc9>;K]ZH"G@&bp'CDXQqXbrYQfuoo@\q2+R)&8Rl:Yn$iYAEO5gP,`l';G,h$,^R/ %!M2Br*>fQ)@T&Z0X'lFY[qp'6/+1V(onLF,7;_lIW+bn7d%c@j?0W/!"B"Um?ujB*DRLkM#!77hL])Q^.1@"oFf\>+*Hg(eSl(2FlbY7_ %+1n#l>9N.TNf"idp/6-R(#COfU47Wsa[S&=VddCqn]93+ehd-\*!8Q&fOLu/j^#;pcQFu:"L]\-lHUp_M+tEu'7*61?K:LYj7cm4 %(Qj$]LndoT0W+7A"m,Qge2d=5aTnZjhc&1g%pS2nX?RD*TY9&ij1WE%OK@75fk7P.TT?L@^&o\U4Q2F9,(&u4-$6uH=#B$^5]/>' %h>q!'O3r(?Wgu.Q,foALZ0foP5g*:-HL=dMKUX4lKAQ?GPK,q>83FIUq-eB8D&'WmDA%03$-N92as=0n-[DPJ*B"HM`-'1MITB6DSkEj"$"c+N#`)N>T%&e+ %mtD:m$QVkmJpC1J7UDc=XS&:4hM60*FAJg+,A.6ipM$lKH<`uuDelQip54-O+!,En1:c$]q!\kE@*>diMULm %F_m6ab?:,![a'2u=L>"_9UP_QXF_Q07k('Y!>R=fI/lH3n@'USc]FQ3@[o$YZE_?m7tQ359js/E6F@+4"C5OfGlfdOMc\6?$>\Ig %NAIKs`BD;bac&2[k[Knu]@Q.*\o#3aUn2:eTp;ouStm0Hn/73@Y$Q_U;4NR//t/1QBm>YcSZpm?fE!>9@m]B'8]GV6,u;.XcIU_1 %5W!/SFu^rZV?t$4bQ;D="tkB_rXeiX_h@2kT+M[3nu!94_t@<\^C'Fdo1>Y=*B=f+\)h_U?B#FQ&8iYB2n-6 %D\iiW/K>F^mD\"sjK=a]i_@G&HN!1q0.,@aDt2+TMcA4*Odk(b?Qr2n;d"Kh<%5m)4N`*IZl;*;^1q2JRp0W3TL>*"l?'B7Z'Cfq %$n'HNgP%GWXoVcR:N$5B(PB:dH+Q)-,+b0WqSh=('$t@E3kg(mG2K=ngsgO!'$qVYM6r>Mb6Q\aOm(S,esV?^[T87gb'O@OZ/Y]d %Q+M@a8S$%/^Qu$Xdd^p(bgDn"=?9i(MemFhAEo0W#7VFr\Z`2+VGJ:d\PrT5Qt6hc=(L8fB7] %`\&86KQmF^[C65NZ9KYSm.bt7-E9l';].a&CB4U8hb%4hp,8bV=)*V3/Bf355Di;e29^p05GE3'%SgL2"N'-6?$JS?325`m3`YH= %Jg&5aUK@I#m)I0e9>:7kkWHp6hj:Q[(']JCmUg1"CRu[;CS>RW]NV)7!Dr![h1s4so3a6$cXkkkVQ %.+AJPWKt`IrDhA-nOOume0*(S%SIR+5jV`?HW@+gd7J:]@"bJ]'f2h)Ha2HL5+Qfa5rT)b^L31\q5F)bn9N2J54JuI`c'8ZX/@TT %mooD4Z`J)=0sZqn-hCe3lA=RS4J#DdjIt6f*%Z#;#-b/AaXa?@[/e$ROoM/!R>53QZWKUY/S1;11 %g("^h$&"4)&?u0`.@i6O623M@R2H,7eOfa(43tXQ-.,PjFNVS/NCX"R[!mkX4,Q?@>fH]^5!flB;XCfK&`Kft1@eop'U?f@gW4q+ %j$JHtM9Pq+mo[D7T*2^pjj25tClQl4qh7ATn6@r^]b@-^Z$gh&:T@K]RqVBO[KgRcQEWmLjfOJO+$5LEgeV"EZeONZ;<#%ZFHlR1?c(#:1bt>&RID)]j8YtOlm`?J(2LV#&TTC;JZU3cm)3?>ab?tY<^L3!>6lcj %6L)p?8TUbsr8ppt&)q%h>KL)9_+JDF3"uP=,^d.2Pkh_anKJ;>fG=g0DN[:s6q\bYNRq28NmIC3>. %Kb4oC(rq:V(8nCRj`C0QL)%Wc^3&%O9WtDF"ZNE*RG,%*HLS7'+U6!SK"0R!e\gss;n*r:FOMgJF(^kq07Am8MOd@ciBqX?ApYgB %o]7u7:`VB5*?Hla#(9^iI'7IB6#lOo0PnH>^$,_L`BdSqHW"_-$Cu-Ja3'%+g5di2Q0W+t:g31*o+jH/pPs-_Pm6oP;K]C47NIN$ %a308m.+5[qqpp3A9"F/N,(T'WYP?KrI*th0PUO6>/#n5*SAu?"/h4&iD@_PDH.c6Te^F1DQ#H>cn/4CHg/HT[aU[$D\R8d?],G#4 %Kg,%"Uc7$Y8pBrBq,4_'$Ee=V9QCSGL<[Z14kcUmEB\C/2<#sIGr5`+l%16lRT%ZNS %eY7&:L@oEbpq#NLMe-]1^p/T@d!@7pAd;J.qY5@bS9bnTI9?fY<=of%cc;dAWg`j:'8Y4@I&(;BoJ %PsOFFg\iEqB*RbWf4@&m)MO;2[^5)XreX*sqR24Bb&QEdh+TmaBPJtYn`r&,@8[;YBWkDF1:?/$f*IJ0e.hBL8&Ff!4JWo6d# %%sq.DgRPgL!d^o_ep=Z9XE6k)[p)C5YC%ss1KQDlWD`!ZC`0j2WC0_BY1IYKr>8I^>L7"b"U$X1^HTZ+GPGfC@$Sdc3N&P%[VY@ZcNa?u!1S#![fpN;Lrb$h&9;T %$sG!@&q*G7/Cl7L#=U\mXVuH_We2KZX0jqL#jXIokFTX>3n?`.b&QQYL8'nuI=1%usU@Y9%a2$\>:O.+!h4#BX1c\>bgk1o_28Sdmd-%Xk7/o7A!PICm3*M!g %4;CD*m]4:ia^L&#$.rQF?$(u'!R<*,bh&r.9PE3@roTZRb7u?tS4B)E'YanQ60KFG(>,$\nLH$_d_0Tg"@*R[bI7rUH&Tt&NE9gd %Jff`8e4P'cTogSaa8[j_A:-!b:ETc1qF1HFf(g&3NrQX%gXQYs4!SN`^%K3+a@b_]'XW'^.5;p3Z@=364iQU^69G7_H;2u. %Gi>I1nQI2r0<6kc79CFXjk;GiPUXDNpjBK8;WZJW0Q6]\J"FSrdk02eOVM,"@G<82ktsaRf4+O=UfQAcC"PZDm*H"10ge)gGSLIKC %O.%;A9M0M7HX1XAAjq0X`&@uY4F)9,rC&sB&%boe+iQ?CoYPbRgW@TdQ4%.lZiVOtm2)R5B;*Y^0=)ml8&7>C0gn+"#mOB`eaF0;L\+KO$rG$M-!F %d_U1#%^d`s"I^)!%pMUT4/eq&FZ(kIqe'p6WH:VoEu\QXU.X:-`OS?K"';sFC0j$3h!Ric;"e'2:eB'6rmF+=?2` %-5Xf#[(DBd(p4P<+>9:VE-*Z$Lc&ZKZi9gl-glG,fKlt)Jk0C7Y?(o`>64`k@Y2E>h0.1%chE'K0i\Sia^ %d[@_O2E-/D;ko3Ygp3piUVo>q#R&@*72`9c-2(;;@oA(i!5N"Ujfds#(]^Z+fW;ci]"YN3on<^4c,IRK9WGpmd;A)d-0o:hO8tLs*Ga;ZZoBVsj86j,$i]1U6,g(p4erI+s %7\ffAkfH=dj=&A2M@I(+cfP!b^GJX]il,Uac+Tm!6f]7Nh\+*opjK%&`,ITJQS""VZS8YWo8S#;h3J`_+!nYc*<@Ac94t6al]\RT %T/q'Nr&%qa+Rh+jY/eDrA]N@S`$H1KZ9'n0Sj %DJ@=+)a:lVL:;[?'>:?C,0KNQ7o*8,8G;M%"K"5B_ON(@tZ4Fi[WeBj!%9F@O:J5C.RbRS+a_Y4@DEV-P\s$(5)R-Q=bOEEk*R=IGC7_K[<\2 %1:MM=3>;$ZSm0'14f2Z;Knd1%MArOehj!.)buWlO8*,\*9o4+.)$HdE./D %I?Z]05'^3fV,1gShAct5KVj0Ig:oM\d>ZHOmG8flgFp(/]la\;b5ompEBbJoUU(@`>i19<*0TLe,0hjtZ4fRTh&n^=h"%t3_a<%5 %\F@Ueg+*Qrg+i(_@J+isN7QLu%33L-FrFbo(8ilF$_;!Hp"E)?b*/O*]qZZGS;uB8'VE&W-KjB0_.SWSW8JNbUSGmJS4uiBmFelh %,FY:E5X4OuUT]i=:D7\[j;sj`*EaGu9GTC2m/CDhrU[L]/2V)2+WF'EJ18T,bBC0GgR05V;*UKNF[aK$YWF"3f02=N?]*\.mEuVj %It.Fr?<%c0P@F7joR!E@`7_P'5J'HRPmt?u2#PJXV'-0PpWI*@&Ga1argfnEK9fH(%@prP\j_/eWp>G.]l)?.6iou3+B;4pOKkIR %;&\#-Te"h6k;P``8U!SKX'gHtEtFfY:j3ZA5rg8V(o25Tdo.@mRHn&=\^D"dP>=c@84=A(0e/QB$:\4RW*$@hL=(WFWF;S?Lg6.t %qe^U0]c&;Y&6J:.Cd1b'/aD\,8$n*5MtZBEl>4-a&oU.]Ld,%<@Rs5uUcU"5^/ad@ZCRtn)#7Q1,PY;u&Ku_CBMD*B%(]B=W`W&/ %K#/8B'BdQLDiS;j16s90N2t\7nN[?BctR.>=e(8hU!q;[ZT&JZ6`6J@-bI'#k8ZPM$p$tgi#Xn#g)5"\Cr+qKkd3/0jOo-sk0RgT %crlloae@2/TT`ppm[QYBSO(+-^NPtV\e:@0G@*^\ofX;?C[0U36ALCUnL3mg>EO"sf,$7t,p\T^ %9M0Vu@sUbAbXW[4Qj0(&;s(;K=iY`&$t7oiV5i2rNZ?VCTMeQ]edDYD=a[ElIGDi*V$07AT,LRA3_M7B$DJ;MhtA^fJjIU--F3X1 %]f`tsUW59_Q)%)'-pLF3k;RYD!+6C9V%H'__[M+A<:dHcR>#NkdL[t6=j'".&lI)ca\D9cY5LZ:Vkdhpb%#cj7[$Mg;bXeLJc0RN %H$A#WUj89N\4IAY'"b1$;EnM`V$it!+>!?Tju#U&WS`WF%.ubjc&WSp;r-% %c(gliVFUM=?moW`;5V-;+@f0MY)`gCQKD)m^[f=:jVsQOOjqRS(R43I

J9R22c^aY0]_)7P<+HCRIEOHf(0B1*V.:H#)2_5*$# %I&S0)9(]BT[JT_AE,s'tZkYl;'MdBM*>o2tGcl"'S/G+TqNPC^Fm_$=`_3]gL!<1DXUI9i*ZWPK+(fO2#7En*YX@5>_/`kYII14)TC>BkA1jr'phCsj"dRBR6Hf^;D(11q! %GeL5l3gCBlBr8+`J-\oQ;no,#KmL_LV(>RV7Wu:P-`QUZXWZ;+L_C3IS>is>*Krjk5]%KHJ,a'c/*T\oOB"*>b]lOEZ!;o %oSOO"gSQg?d`C$1g3p9:,4nQ!J/L/A;$PGl1/aaZ&"&IdSK0=-p%eIb)6'E;Soh;;7V^P(iA\aE<&.@FT*+RWkXBSKZ<'7[bU;5* %<9)RqCUg`2T+W=ZND!3p"rSTXi"q32+!p1&fa*4@W0do>n1h9&3bD:K3"8p55BrPp3"a(;q/^^PKeqo$gbfgAa0%O$.NG0!F\-qY %<&hmu?m*p?Y>dL<5@uJ5%a!$;DM2)VaM!iq5[oM]3an/,.X-rJQ$&rB'.CJ>d!u39Ff'2ATm7ZU[ut&Q]^+MX:14glW2&+8MJth# %#O4V[@t_g85WjknlAT/)>W?]Z;+<[P5+l\gC7HJ/98\GDhOiY7>]&t8]srGaF],?YR*=_[kP#/#n@Vm`o/0_fB57G.Mo+B5#./L6 %9+T@F!Tcr.$]I'^mTu#?q//:_/:MjkcGbs3Mf[[])j1J,BaRs'R=AtP-+c==-G(igDb3hbW&V\T-kY;DPsM1*UY(Rh74m1e1W+)B %f#k3I4!&L&&u_bSo]mQ^k7;K'7kF[qWAsarfOI %i`)/'SC`Y/f+#9UKun\J&W^lt`5qn/aT*^]e=Mn6@%$r:_H>2=W@"]2-0:LEQrIB>T%%/6hb$,qC8X[E$<(tKN&l6,/'/\%_Vo:V %%K`Q=<6X[KopI6QVsB&k]ni2@ol5-3N5k/J9hDhFJ75)ibnUeeV!(f4:d<8#P`Yc3Za-B)\EclnkdEUeHY:eFp;?6^9rF4K-\C!% %ZK[U>AiY)oSJo0]2OeUAbfAP#Ym#u3W,+L@\^()l&!fq&m"UUMZft.Sj?9g5Uta#PdM_OXS'7a.o!=-iTK5n-SPh)2H>Lp1flTiD %TgESAT%S4[^g0-j:?,Z7*OG!pEp9f6H-g@gV(%8^bCQt`P]H#aRaN@bl'.E2hU?hUCc\Ek@s")*B%&3.K=d`EWb9d0Fet^;Bf;GU %)e+TFVGkX6gBV26MP1Nup<'723^uu+J_rJW:=K=5(uufO\dMeu,L3.'')A3RFNQ?-LX)bql@@j8LWlVo8ftqcEY"U5VdqnoZsD*A %ACDt-K/.l`N@HmrLc=uG%X60p;c63+p%\.dVWf%MBCY1RCo[Ra!D5<]<_otSL'!(:C)pJ$le0X\bch/rPa&5lm=S2t.kuOFAE>X[,%<\i.:h#iE4iD:VKsTt,\Psh& %`#flebafh")TlHU48)DaD3]M;13\oHE^n?0G:I[CbagpE)iI&4 %/p!qVqe#3a."$4(Eu7.HmU/8BoK0t-UNP4a3GlSMRZ8#Ma4G#FIXXu)G8B/]Hb5us]g6hMQ3 %j)t5eafi^!UoGii25Bt8U:\o3.r7)?g\F6sWDPsZF"W3qeUmZ79KQcA<:c4!:egQ0:-%oc8)f`p(OCae&;FM7m7079HEhM7!@P79IJDKo>KaI[0ftL_m>T9PW!t@+R1L2:L>iQiCUVT%+Z7.aY$RiILX!ETN%rcWYIl1g6tO'a8jP. %MDWF,ERbok>GF'U[51bLk(h>0R'$p#_=2>[1m((fp/g8plI;6Q4.OF5?j61U0Ij3Z*Q&o1>t %.Y1>M>>2dRom>XSP*l$g'R@7%Sb(UF&#)2fG5%hDpol[po(d!Q"s6c<@o<>=B;qH-_T0P28n32"d;2n>Q\U3!D2u1/Z[I&4V%dCm %[^ujX&g_klR)C9@O.eDJ4*APZ:,,.8P/f&>]Tlj,)!6I%/]BCc'MV]segAe*CKu-&tr2NTJR^VAi@jdQY3+X8^V=E`S-$d;S,qR/1ra3 %9!i_YETV>YIQjA3ePI)qF2<\SkH-rFa@Y#P[c3eSJ-G5%h9@W*0;Q3.H@T^k-[8`,CI<0Wh`EFJps&"iM.Q/"U9>;\9T\ToFMPONst-WBQ[@.H-:NTth3qai=0 %DlT1BaCV35k,jrt>4J9+p#5(!D:"tW'&N;6KNlUJn1L?U.YG_kP2_2d6*Ick'VC5g'7diC9M[.G<+pJbW#bhAQf_AL\+DMEG-%(4 %7hq7`Nc7X\a]@dV9g;9u\6BY+(?ApGli`O1P?C=Vi"2-`0cBEkmT %gLVP"=WS2'0/dgYIuV)4fGVLD:Gq[R?V%.'@eO':D6R]SUR)pYpkO)[,b4C1lQ:aB2fN<0GH^[*4Ng1E5INda%-NQ5=tQ[/ %l!8950DXS;V(?;U8'U-uZX%o`Hd,#?9TRmI`^Z7SK@OlB2K7qedYsS-R=3M.9,4W;\qEcUZ7?#04.[qtZ822e#Y>"^=o[%V*IU>[ %OU#G,iFjj+/A@G7,76;,%&X0@C>X)?.`Y.7/mdOsGB`!FiENB3XW;lImDN""9EfB!VJ;889X[;!T/8eLjNse<=%=-F3]3joD]W %In,!od2YC\h9nP(T[=`E6WM?0?t-dCSjol]JLj']3IjT)Ct,ckNTXECK#?A$0Ub"PVJKeNdl6Y65X&[kCQi>`e%S9HZn&F&W[OK" %0AN^!q(.EWJD-fB/]stfOmOM1j\t;OLG$_^dGoue.E[FR5#_ROV\\AmYEj=PU3s!6/,(I7-_"#)I[6R_MBbH*%Aa8MFo?tR-rorp %l#%o'\pc`Z_X11O:Bb3DF*Dm2p1\Uop>-SC0^gqIs%(1OM-G:0g)ZG=1b!f2"q-e@Z`8canSZ+c@b\7GjeSW32cddO`\]eFbmk"VCXDIbG0=V:aXIrO@MBX]s'EYNr),EMf7i\7>At3:ql"5!mj`1Mb[YY+JU0 %Rm;+CAYnXW+u+BGQ-m0lg86L#.IC?kO+Xl]397JbO.`EZ\5"kUUX8sP11l_e%=mk@mY-1*QO6t^moeb.BTkh=/oh6F,TG#c:?lLC8j'!,)oDspmmpo8cJWQ1p;`#He[ %fWOOQ0^h:^g30[2IL:?2U+8Z$U[2"4:E6^R?.El6X>H.2)&SPJ:tJM7]K$M0Iuq6jg1I^[H@3?VlB]r[3rg-J=7t=M*hQS>>3Ya8 %mCIbD9(C$8P2E4E7pS@HWdYkSO/D4=mENZ[eb.BlEs*K;YHFL6?8AR-QWorDlMBo+leA,9T3sE2F:rLEJWp?Rb(iGlimTA(:"dEh'5IH[eZZZ5R:M_T-_pnA.NX&V/Y2,eST.7cuVL\YKP-GXGg'9Ucm+U:]qIp%MR-O6(L4i(P2Imk5m<8CY-FXG5l,Y,a=:-bO(f7uqgtFmZGF9/e#@q_ag)C>M#ZcLIu=G7?bQJS;Ch %h2.*rooI>lmIJ`cX::YU`8u(%qlWLCC@BEnld=e%*4jeXFikbLVj$k#^=n^QX(fIqo"OTVB%BUfe*UlMnf>.BR:ZqPrcIB!#''A='< %:4"4CGHoG6ol9CB6>G!7aC %i[9q[ZdC=r]AB",'V.4tM#-o-:tVZ.@N\]9rW9IrPudTV2.0XK?:$&ko*.V+eP]k70iT?1=)ZB@`4(WR$.e"&':'t9+#+b\@]ne^ %S>(r9\aR.(B^IAOLIok+:p*>h1@Xqq4S+$V]$+3LDjS1+,^!-[*8M%o0B\?&?7D.Tqhbejj%J4Vja/pI@<)/OIcmThY#MH4nMPT\ %+*Bprg724W(pp^-UQYX!0ZkB-mBjc^'9.VRZG@!\+Uq.Y2OW;_hF'n+r$_6pa8k%MI1e-hY@t@kXFF.qT6F\o\c!tjgr.K5P'^MQX>An %quYWoQN?WW7?Tp^6EE_6>S8GnBhDF#FUJ)CR(dpN:;614+4I$p+9Uh?J7gi3J1Bso*p#H(2!RU&W1Ri,?Q2f7.p)KngMQu\M8X!5 %&SdY[To8%m$u]@!r0HnAP65^Lk->hK5%RCo@*B\)%,bITQr8?;PIkaLM>Mp=97UA;Slb-(aB-$$ %W$"o#Z]WHDdZ)Fci]2o$Im$(qHn$gCd7@+;LK4brcpj^WuddR#@+mS`VaZ?[r %T&(AQU_Y?T[-g;>&f5D^gkg2VONmQgh4?e\ZYDgAmM.6NJ@-L9 %98oJS2^X:Q84_=J_a>ZlFF`dZ8<)CK*=a/>@DRV@W;(`Q#To[$Oap425@UsX#)f+)!dtkqT"V3d@>q"Y,'=KQ^H--2mM88=Yr<@n %+4iii@AL*ZKps6IjKkTtD/#C?*"baAI;::A%l77\M.V0It#s>]3sh#.c-!'mA8N+ %KFD[MC`DHEcZqrb3)=C0>Seh]kec.;\p7?08WP&l!L#BR+mm.]iuE;Jm*-3rG8W\H:gtD#Z4''rM\IIOk?!G+$k`GeK0AdhB.Bfd %En>tl&CP`t`Mq^hTgef,@42?+ft1=#H.i"Ba=E_//:>m-h-GVT!Ka:K'dH#Wg#oFcPoTEN7Z@=GQ(6s%5?T:FI!pX>XHErPs3FZd %;*578jZcloLOE#uTb")b$QS;AWoTh4,Gk;cX5pK<81E^B3&,m*NYt!4;1__`2kpKlT[B!P+/>7SD`P(UZ;m(#SIO_Xj`&ijrb#N(pG^R[Ci)mM6eQ(c>)c#Z_u>$;K]WQiDo+DY=dL5rLC:.CkY=q` %QX&K4;'&dY2lU]RSS4q_mQ44SP!\TK)iN2-992kcc66>sq*2W_k\#`Lg)0]]jqD?kpGYo1UL$H!\BJfI^5Mi9TiSQY"k=Zp^6)!j %pg&+q7DOT&<[(+JiQV&lP^C$hsili1ZL'KX:`C%W,rH9_(VT1\iFcHSrq//@ %ZLiag'@@3eR<0Z]<#BZc*S]+Y[L9;Pf:5]@,m::r.c#6!6XhJN#V2"a_,3D8]uUFHXQ]o;KKp-d$_Y\(/GJ.]jBoR*VHZ(B'qU7P %0'E0WGJpP,luFt>'EKjh2:#AOHU%^`D;`ABM1:+R\&$B[7d.I:irn:C$&`OOYcqOG@iI20j4LJ;O(7&m1qF#;9AL*\Hlp2N>MQ?I %fpkn!.EkF/!5IRDJc,U'5S+&a],hMC2E(u_pd]j:+k/Y<:4CDl\#%OtrP]GBRl,`>&(ffN+/LA&Wh+`TcLO<2Z;*hS%d(@aHm#q' %c[#FL&MKJ+Y$nA-*MdL&?*tbF!L$`P8G%-R*=!t%\hjqNXr,Q4=."d>=Z5$H%C$&_HQ^C9^$:0`5ia`,V"[KTUq%rYqpt(fnR'^S %(aZXG`rLA\e7Sai+"JHp5=L'mUOUQ+0&Zb9>U_H/T#7c@+EYhrj,?OAR'FiE)L=+ail`X:f]hG:=2A`FlW?h(G?:>/(:6R@odF*9[?I@SLe:\-ko9`2]6diQX;lYb)&KQ=pEa)aF;JD.Nl[9QUb3"ZdfTst?`I6KE6apOZ-6@W>b9O7"_S:0 %DtRe3ZNa^gGenOlk*1"=N4<3S>O5@9UsA(>.9if8jkWhD>Abn$h%4e7mFMD5%Tf9U/t15##pYC4bn+6]j.\Zb>RY&>)iT:X!o^MA %IFeAjZHpO6+54I8n'E%FP"ce[hqci!fQ>jXRTJWjd"&17D9Tr;GE$H"Q2m-1XsJHW'!i_IVbk,!Pe"(if'^r) %%\e;:\T:%I\lUcJ&0N1?G"%F)KmD]Efo7,,l96S#^/&/^AD:L3W]L0aIsW:++\X]ZAbSW?(@#1]*.GJ?^t7+SFWoVqSX+h/Amd:d %SP/)GPfuFPqZ=k#&:9_PjC,+FUTf'=P`&kiDOhMX(Ktl:7(<<@&X>\h`t(%k?bYe;r6kA#@(t_1cf"@b71QR8,h8b$.-H32K2p6I %MK6uFd>?BET;%k9,&:Z\r21t+]\1K-klA!t'*G>nc4NJo#JJiV^KJa/;s6qE6F(HMH;(@(qN;JcneO[sH/#hVk4t0LA:gX&p3B_&q#_5r&l_BT+?]7)CIs8e^/k!d.1( %LN2r\4;*T<2o5Z*2H2LGUkj7`ngk9dM?72&0K"A.D+-h2E%?0eqVIeSSgCHr*iAHpoNsGq31a&.JNA7`GJ*@W[]bYA*2bNrG]G$$PhqX=%HD_oguTE0LiBGXN1,(ksSq^.+)+M(j#RD4#2b5rp"'5QW@nGGo:> %_,rN2`f8@'BYjoD%7p^JnZWk5pe`;oV^qg4((>sQ=CW&O/f5!K-4KJinc"Y:oH+t?(k>LM.RE',#^coO,0U6:TNfnP(!#X:WA*p* %9E\kp"\k'qS+7?e"SG7u"LLq^aiOHn!K[(Dhp<(a&Zd0MZC%)RdDCH^E5OBF*_cuiJ.N(tKn]^u@>4tGiCO,d!R@A,'=^:%J9rPr %'VI+<)A,1A',60ag&j)C%:ae'^e(aqOoYaf$^SVj1$fG?!#cG-UA]%_U#'2,MI7)D@WAH\g<^4N(8]&nh\\&@6c2J6]sq>'t!HaTOTO5Q5'U#7VN!@R!&P^KV$*q&]?#p@#U+"3t#Rb!f$!6Y`pGkSf9eb-l,`p.Yaf@L$_2?'#XrE^`Z)+*>`ZG!lR>nRD*>Qm4Wo$ %No:!PnV#s0C^%ZA'E8IV")K\9C;oX,,T9@pLmV_FU;-n@(f4J<-qF[H$U,J*#&SdQ!b+pCn[=)_Y+iH/#nUNCGZGVFK:*phK*N)* %([[/p$Gp+]':>ds~> %AI9_PrivateDataEnd bind9-9.10.3.dfsg.P4/doc/arm/Bv9ARM.pdf0000644000470500017500000535256012664710322016430 0ustar lamontlamont%PDF-1.4 5 0 obj << /S /GoTo /D (chapter.1) >> endobj 8 0 obj (1 Introduction) endobj 9 0 obj << /S /GoTo /D (section.1.1) >> endobj 12 0 obj (1.1 Scope of Document) endobj 13 0 obj << /S /GoTo /D (section.1.2) >> endobj 16 0 obj (1.2 Organization of This Document) endobj 17 0 obj << /S /GoTo /D (section.1.3) >> endobj 20 0 obj (1.3 Conventions Used in This Document) endobj 21 0 obj << /S /GoTo /D (section.1.4) >> endobj 24 0 obj (1.4 The Domain Name System \(DNS\)) endobj 25 0 obj << /S /GoTo /D (subsection.1.4.1) >> endobj 28 0 obj (1.4.1 DNS Fundamentals) endobj 29 0 obj << /S /GoTo /D (subsection.1.4.2) >> endobj 32 0 obj (1.4.2 Domains and Domain Names) endobj 33 0 obj << /S /GoTo /D (subsection.1.4.3) >> endobj 36 0 obj (1.4.3 Zones) endobj 37 0 obj << /S /GoTo /D (subsection.1.4.4) >> endobj 40 0 obj (1.4.4 Authoritative Name Servers) endobj 41 0 obj << /S /GoTo /D (subsubsection.1.4.4.1) >> endobj 44 0 obj (1.4.4.1 The Primary Master) endobj 45 0 obj << /S /GoTo /D (subsubsection.1.4.4.2) >> endobj 48 0 obj (1.4.4.2 Slave Servers) endobj 49 0 obj << /S /GoTo /D (subsubsection.1.4.4.3) >> endobj 52 0 obj (1.4.4.3 Stealth Servers) endobj 53 0 obj << /S /GoTo /D (subsection.1.4.5) >> endobj 56 0 obj (1.4.5 Caching Name Servers) endobj 57 0 obj << /S /GoTo /D (subsubsection.1.4.5.1) >> endobj 60 0 obj (1.4.5.1 Forwarding) endobj 61 0 obj << /S /GoTo /D (subsection.1.4.6) >> endobj 64 0 obj (1.4.6 Name Servers in Multiple Roles) endobj 65 0 obj << /S /GoTo /D (chapter.2) >> endobj 68 0 obj (2 BIND Resource Requirements) endobj 69 0 obj << /S /GoTo /D (section.2.1) >> endobj 72 0 obj (2.1 Hardware requirements) endobj 73 0 obj << /S /GoTo /D (section.2.2) >> endobj 76 0 obj (2.2 CPU Requirements) endobj 77 0 obj << /S /GoTo /D (section.2.3) >> endobj 80 0 obj (2.3 Memory Requirements) endobj 81 0 obj << /S /GoTo /D (section.2.4) >> endobj 84 0 obj (2.4 Name Server Intensive Environment Issues) endobj 85 0 obj << /S /GoTo /D (section.2.5) >> endobj 88 0 obj (2.5 Supported Operating Systems) endobj 89 0 obj << /S /GoTo /D (chapter.3) >> endobj 92 0 obj (3 Name Server Configuration) endobj 93 0 obj << /S /GoTo /D (section.3.1) >> endobj 96 0 obj (3.1 Sample Configurations) endobj 97 0 obj << /S /GoTo /D (subsection.3.1.1) >> endobj 100 0 obj (3.1.1 A Caching-only Name Server) endobj 101 0 obj << /S /GoTo /D (subsection.3.1.2) >> endobj 104 0 obj (3.1.2 An Authoritative-only Name Server) endobj 105 0 obj << /S /GoTo /D (section.3.2) >> endobj 108 0 obj (3.2 Load Balancing) endobj 109 0 obj << /S /GoTo /D (section.3.3) >> endobj 112 0 obj (3.3 Name Server Operations) endobj 113 0 obj << /S /GoTo /D (subsection.3.3.1) >> endobj 116 0 obj (3.3.1 Tools for Use With the Name Server Daemon) endobj 117 0 obj << /S /GoTo /D (subsubsection.3.3.1.1) >> endobj 120 0 obj (3.3.1.1 Diagnostic Tools) endobj 121 0 obj << /S /GoTo /D (subsubsection.3.3.1.2) >> endobj 124 0 obj (3.3.1.2 Administrative Tools) endobj 125 0 obj << /S /GoTo /D (subsection.3.3.2) >> endobj 128 0 obj (3.3.2 Signals) endobj 129 0 obj << /S /GoTo /D (chapter.4) >> endobj 132 0 obj (4 Advanced DNS Features) endobj 133 0 obj << /S /GoTo /D (section.4.1) >> endobj 136 0 obj (4.1 Notify) endobj 137 0 obj << /S /GoTo /D (section.4.2) >> endobj 140 0 obj (4.2 Dynamic Update) endobj 141 0 obj << /S /GoTo /D (subsection.4.2.1) >> endobj 144 0 obj (4.2.1 The journal file) endobj 145 0 obj << /S /GoTo /D (section.4.3) >> endobj 148 0 obj (4.3 Incremental Zone Transfers \(IXFR\)) endobj 149 0 obj << /S /GoTo /D (section.4.4) >> endobj 152 0 obj (4.4 Split DNS) endobj 153 0 obj << /S /GoTo /D (subsection.4.4.1) >> endobj 156 0 obj (4.4.1 Example split DNS setup) endobj 157 0 obj << /S /GoTo /D (section.4.5) >> endobj 160 0 obj (4.5 TSIG) endobj 161 0 obj << /S /GoTo /D (subsection.4.5.1) >> endobj 164 0 obj (4.5.1 Generate Shared Keys for Each Pair of Hosts) endobj 165 0 obj << /S /GoTo /D (subsubsection.4.5.1.1) >> endobj 168 0 obj (4.5.1.1 Automatic Generation) endobj 169 0 obj << /S /GoTo /D (subsubsection.4.5.1.2) >> endobj 172 0 obj (4.5.1.2 Manual Generation) endobj 173 0 obj << /S /GoTo /D (subsection.4.5.2) >> endobj 176 0 obj (4.5.2 Copying the Shared Secret to Both Machines) endobj 177 0 obj << /S /GoTo /D (subsection.4.5.3) >> endobj 180 0 obj (4.5.3 Informing the Servers of the Key's Existence) endobj 181 0 obj << /S /GoTo /D (subsection.4.5.4) >> endobj 184 0 obj (4.5.4 Instructing the Server to Use the Key) endobj 185 0 obj << /S /GoTo /D (subsection.4.5.5) >> endobj 188 0 obj (4.5.5 TSIG Key Based Access Control) endobj 189 0 obj << /S /GoTo /D (subsection.4.5.6) >> endobj 192 0 obj (4.5.6 Errors) endobj 193 0 obj << /S /GoTo /D (section.4.6) >> endobj 196 0 obj (4.6 TKEY) endobj 197 0 obj << /S /GoTo /D (section.4.7) >> endobj 200 0 obj (4.7 SIG\(0\)) endobj 201 0 obj << /S /GoTo /D (section.4.8) >> endobj 204 0 obj (4.8 DNSSEC) endobj 205 0 obj << /S /GoTo /D (subsection.4.8.1) >> endobj 208 0 obj (4.8.1 Generating Keys) endobj 209 0 obj << /S /GoTo /D (subsection.4.8.2) >> endobj 212 0 obj (4.8.2 Signing the Zone) endobj 213 0 obj << /S /GoTo /D (subsection.4.8.3) >> endobj 216 0 obj (4.8.3 Configuring Servers) endobj 217 0 obj << /S /GoTo /D (section.4.9) >> endobj 220 0 obj (4.9 DNSSEC, Dynamic Zones, and Automatic Signing) endobj 221 0 obj << /S /GoTo /D (subsection.4.9.1) >> endobj 224 0 obj (4.9.1 Converting from insecure to secure) endobj 225 0 obj << /S /GoTo /D (subsection.4.9.2) >> endobj 228 0 obj (4.9.2 Dynamic DNS update method) endobj 229 0 obj << /S /GoTo /D (subsection.4.9.3) >> endobj 232 0 obj (4.9.3 Fully automatic zone signing) endobj 233 0 obj << /S /GoTo /D (subsection.4.9.4) >> endobj 236 0 obj (4.9.4 Private-type records) endobj 237 0 obj << /S /GoTo /D (subsection.4.9.5) >> endobj 240 0 obj (4.9.5 DNSKEY rollovers) endobj 241 0 obj << /S /GoTo /D (subsection.4.9.6) >> endobj 244 0 obj (4.9.6 Dynamic DNS update method) endobj 245 0 obj << /S /GoTo /D (subsection.4.9.7) >> endobj 248 0 obj (4.9.7 Automatic key rollovers) endobj 249 0 obj << /S /GoTo /D (subsection.4.9.8) >> endobj 252 0 obj (4.9.8 NSEC3PARAM rollovers via UPDATE) endobj 253 0 obj << /S /GoTo /D (subsection.4.9.9) >> endobj 256 0 obj (4.9.9 Converting from NSEC to NSEC3) endobj 257 0 obj << /S /GoTo /D (subsection.4.9.10) >> endobj 260 0 obj (4.9.10 Converting from NSEC3 to NSEC) endobj 261 0 obj << /S /GoTo /D (subsection.4.9.11) >> endobj 264 0 obj (4.9.11 Converting from secure to insecure) endobj 265 0 obj << /S /GoTo /D (subsection.4.9.12) >> endobj 268 0 obj (4.9.12 Periodic re-signing) endobj 269 0 obj << /S /GoTo /D (subsection.4.9.13) >> endobj 272 0 obj (4.9.13 NSEC3 and OPTOUT) endobj 273 0 obj << /S /GoTo /D (section.4.10) >> endobj 276 0 obj (4.10 Dynamic Trust Anchor Management) endobj 277 0 obj << /S /GoTo /D (subsection.4.10.1) >> endobj 280 0 obj (4.10.1 Validating Resolver) endobj 281 0 obj << /S /GoTo /D (subsection.4.10.2) >> endobj 284 0 obj (4.10.2 Authoritative Server) endobj 285 0 obj << /S /GoTo /D (section.4.11) >> endobj 288 0 obj (4.11 PKCS\04311 \(Cryptoki\) support) endobj 289 0 obj << /S /GoTo /D (subsection.4.11.1) >> endobj 292 0 obj (4.11.1 Prerequisites) endobj 293 0 obj << /S /GoTo /D (subsection.4.11.2) >> endobj 296 0 obj (4.11.2 Native PKCS\04311) endobj 297 0 obj << /S /GoTo /D (subsubsection.4.11.2.1) >> endobj 300 0 obj (4.11.2.1 Building SoftHSMv2) endobj 301 0 obj << /S /GoTo /D (subsection.4.11.3) >> endobj 304 0 obj (4.11.3 OpenSSL-based PKCS\04311) endobj 305 0 obj << /S /GoTo /D (subsubsection.4.11.3.1) >> endobj 308 0 obj (4.11.3.1 Patching OpenSSL) endobj 309 0 obj << /S /GoTo /D (subsubsection.4.11.3.2) >> endobj 312 0 obj (4.11.3.2 Building OpenSSL for the AEP Keyper on Linux) endobj 313 0 obj << /S /GoTo /D (subsubsection.4.11.3.3) >> endobj 316 0 obj (4.11.3.3 Building OpenSSL for the SCA 6000 on Solaris) endobj 317 0 obj << /S /GoTo /D (subsubsection.4.11.3.4) >> endobj 320 0 obj (4.11.3.4 Building OpenSSL for SoftHSM) endobj 321 0 obj << /S /GoTo /D (subsubsection.4.11.3.5) >> endobj 324 0 obj (4.11.3.5 Configuring BIND 9 for Linux with the AEP Keyper) endobj 325 0 obj << /S /GoTo /D (subsubsection.4.11.3.6) >> endobj 328 0 obj (4.11.3.6 Configuring BIND 9 for Solaris with the SCA 6000) endobj 329 0 obj << /S /GoTo /D (subsubsection.4.11.3.7) >> endobj 332 0 obj (4.11.3.7 Configuring BIND 9 for SoftHSM) endobj 333 0 obj << /S /GoTo /D (subsection.4.11.4) >> endobj 336 0 obj (4.11.4 PKCS\04311 Tools) endobj 337 0 obj << /S /GoTo /D (subsection.4.11.5) >> endobj 340 0 obj (4.11.5 Using the HSM) endobj 341 0 obj << /S /GoTo /D (subsection.4.11.6) >> endobj 344 0 obj (4.11.6 Specifying the engine on the command line) endobj 345 0 obj << /S /GoTo /D (subsection.4.11.7) >> endobj 348 0 obj (4.11.7 Running named with automatic zone re-signing) endobj 349 0 obj << /S /GoTo /D (section.4.12) >> endobj 352 0 obj (4.12 DLZ \(Dynamically Loadable Zones\)) endobj 353 0 obj << /S /GoTo /D (subsection.4.12.1) >> endobj 356 0 obj (4.12.1 Configuring DLZ) endobj 357 0 obj << /S /GoTo /D (subsection.4.12.2) >> endobj 360 0 obj (4.12.2 Sample DLZ Driver) endobj 361 0 obj << /S /GoTo /D (section.4.13) >> endobj 364 0 obj (4.13 IPv6 Support in BIND 9) endobj 365 0 obj << /S /GoTo /D (subsection.4.13.1) >> endobj 368 0 obj (4.13.1 Address Lookups Using AAAA Records) endobj 369 0 obj << /S /GoTo /D (subsection.4.13.2) >> endobj 372 0 obj (4.13.2 Address to Name Lookups Using Nibble Format) endobj 373 0 obj << /S /GoTo /D (chapter.5) >> endobj 376 0 obj (5 The BIND 9 Lightweight Resolver) endobj 377 0 obj << /S /GoTo /D (section.5.1) >> endobj 380 0 obj (5.1 The Lightweight Resolver Library) endobj 381 0 obj << /S /GoTo /D (section.5.2) >> endobj 384 0 obj (5.2 Running a Resolver Daemon) endobj 385 0 obj << /S /GoTo /D (chapter.6) >> endobj 388 0 obj (6 BIND 9 Configuration Reference) endobj 389 0 obj << /S /GoTo /D (section.6.1) >> endobj 392 0 obj (6.1 Configuration File Elements) endobj 393 0 obj << /S /GoTo /D (subsection.6.1.1) >> endobj 396 0 obj (6.1.1 Address Match Lists) endobj 397 0 obj << /S /GoTo /D (subsubsection.6.1.1.1) >> endobj 400 0 obj (6.1.1.1 Syntax) endobj 401 0 obj << /S /GoTo /D (subsubsection.6.1.1.2) >> endobj 404 0 obj (6.1.1.2 Definition and Usage) endobj 405 0 obj << /S /GoTo /D (subsection.6.1.2) >> endobj 408 0 obj (6.1.2 Comment Syntax) endobj 409 0 obj << /S /GoTo /D (subsubsection.6.1.2.1) >> endobj 412 0 obj (6.1.2.1 Syntax) endobj 413 0 obj << /S /GoTo /D (subsubsection.6.1.2.2) >> endobj 416 0 obj (6.1.2.2 Definition and Usage) endobj 417 0 obj << /S /GoTo /D (section.6.2) >> endobj 420 0 obj (6.2 Configuration File Grammar) endobj 421 0 obj << /S /GoTo /D (subsection.6.2.1) >> endobj 424 0 obj (6.2.1 acl Statement Grammar) endobj 425 0 obj << /S /GoTo /D (subsection.6.2.2) >> endobj 428 0 obj (6.2.2 acl Statement Definition and Usage) endobj 429 0 obj << /S /GoTo /D (subsection.6.2.3) >> endobj 432 0 obj (6.2.3 controls Statement Grammar) endobj 433 0 obj << /S /GoTo /D (subsection.6.2.4) >> endobj 436 0 obj (6.2.4 controls Statement Definition and Usage) endobj 437 0 obj << /S /GoTo /D (subsection.6.2.5) >> endobj 440 0 obj (6.2.5 include Statement Grammar) endobj 441 0 obj << /S /GoTo /D (subsection.6.2.6) >> endobj 444 0 obj (6.2.6 include Statement Definition and Usage) endobj 445 0 obj << /S /GoTo /D (subsection.6.2.7) >> endobj 448 0 obj (6.2.7 key Statement Grammar) endobj 449 0 obj << /S /GoTo /D (subsection.6.2.8) >> endobj 452 0 obj (6.2.8 key Statement Definition and Usage) endobj 453 0 obj << /S /GoTo /D (subsection.6.2.9) >> endobj 456 0 obj (6.2.9 logging Statement Grammar) endobj 457 0 obj << /S /GoTo /D (subsection.6.2.10) >> endobj 460 0 obj (6.2.10 logging Statement Definition and Usage) endobj 461 0 obj << /S /GoTo /D (subsubsection.6.2.10.1) >> endobj 464 0 obj (6.2.10.1 The channel Phrase) endobj 465 0 obj << /S /GoTo /D (subsubsection.6.2.10.2) >> endobj 468 0 obj (6.2.10.2 The category Phrase) endobj 469 0 obj << /S /GoTo /D (subsubsection.6.2.10.3) >> endobj 472 0 obj (6.2.10.3 The query-errors Category) endobj 473 0 obj << /S /GoTo /D (subsection.6.2.11) >> endobj 476 0 obj (6.2.11 lwres Statement Grammar) endobj 477 0 obj << /S /GoTo /D (subsection.6.2.12) >> endobj 480 0 obj (6.2.12 lwres Statement Definition and Usage) endobj 481 0 obj << /S /GoTo /D (subsection.6.2.13) >> endobj 484 0 obj (6.2.13 masters Statement Grammar) endobj 485 0 obj << /S /GoTo /D (subsection.6.2.14) >> endobj 488 0 obj (6.2.14 masters Statement Definition and Usage) endobj 489 0 obj << /S /GoTo /D (subsection.6.2.15) >> endobj 492 0 obj (6.2.15 options Statement Grammar) endobj 493 0 obj << /S /GoTo /D (subsection.6.2.16) >> endobj 496 0 obj (6.2.16 options Statement Definition and Usage) endobj 497 0 obj << /S /GoTo /D (subsubsection.6.2.16.1) >> endobj 500 0 obj (6.2.16.1 Boolean Options) endobj 501 0 obj << /S /GoTo /D (subsubsection.6.2.16.2) >> endobj 504 0 obj (6.2.16.2 Forwarding) endobj 505 0 obj << /S /GoTo /D (subsubsection.6.2.16.3) >> endobj 508 0 obj (6.2.16.3 Dual-stack Servers) endobj 509 0 obj << /S /GoTo /D (subsubsection.6.2.16.4) >> endobj 512 0 obj (6.2.16.4 Access Control) endobj 513 0 obj << /S /GoTo /D (subsubsection.6.2.16.5) >> endobj 516 0 obj (6.2.16.5 Interfaces) endobj 517 0 obj << /S /GoTo /D (subsubsection.6.2.16.6) >> endobj 520 0 obj (6.2.16.6 Query Address) endobj 521 0 obj << /S /GoTo /D (subsubsection.6.2.16.7) >> endobj 524 0 obj (6.2.16.7 Zone Transfers) endobj 525 0 obj << /S /GoTo /D (subsubsection.6.2.16.8) >> endobj 528 0 obj (6.2.16.8 UDP Port Lists) endobj 529 0 obj << /S /GoTo /D (subsubsection.6.2.16.9) >> endobj 532 0 obj (6.2.16.9 Operating System Resource Limits) endobj 533 0 obj << /S /GoTo /D (subsubsection.6.2.16.10) >> endobj 536 0 obj (6.2.16.10 Server Resource Limits) endobj 537 0 obj << /S /GoTo /D (subsubsection.6.2.16.11) >> endobj 540 0 obj (6.2.16.11 Periodic Task Intervals) endobj 541 0 obj << /S /GoTo /D (subsubsection.6.2.16.12) >> endobj 544 0 obj (6.2.16.12 Topology) endobj 545 0 obj << /S /GoTo /D (subsubsection.6.2.16.13) >> endobj 548 0 obj (6.2.16.13 The sortlist Statement) endobj 549 0 obj << /S /GoTo /D (subsubsection.6.2.16.14) >> endobj 552 0 obj (6.2.16.14 RRset Ordering) endobj 553 0 obj << /S /GoTo /D (subsubsection.6.2.16.15) >> endobj 556 0 obj (6.2.16.15 Tuning) endobj 557 0 obj << /S /GoTo /D (subsubsection.6.2.16.16) >> endobj 560 0 obj (6.2.16.16 Built-in server information zones) endobj 561 0 obj << /S /GoTo /D (subsubsection.6.2.16.17) >> endobj 564 0 obj (6.2.16.17 Built-in Empty Zones) endobj 565 0 obj << /S /GoTo /D (subsubsection.6.2.16.18) >> endobj 568 0 obj (6.2.16.18 Additional Section Caching) endobj 569 0 obj << /S /GoTo /D (subsubsection.6.2.16.19) >> endobj 572 0 obj (6.2.16.19 Content Filtering) endobj 573 0 obj << /S /GoTo /D (subsubsection.6.2.16.20) >> endobj 576 0 obj (6.2.16.20 Response Policy Zone \(RPZ\) Rewriting) endobj 577 0 obj << /S /GoTo /D (subsubsection.6.2.16.21) >> endobj 580 0 obj (6.2.16.21 Response Rate Limiting) endobj 581 0 obj << /S /GoTo /D (subsection.6.2.17) >> endobj 584 0 obj (6.2.17 server Statement Grammar) endobj 585 0 obj << /S /GoTo /D (subsection.6.2.18) >> endobj 588 0 obj (6.2.18 server Statement Definition and Usage) endobj 589 0 obj << /S /GoTo /D (subsection.6.2.19) >> endobj 592 0 obj (6.2.19 statistics-channels Statement Grammar) endobj 593 0 obj << /S /GoTo /D (subsection.6.2.20) >> endobj 596 0 obj (6.2.20 statistics-channels Statement Definition and Usage) endobj 597 0 obj << /S /GoTo /D (subsection.6.2.21) >> endobj 600 0 obj (6.2.21 trusted-keys Statement Grammar) endobj 601 0 obj << /S /GoTo /D (subsection.6.2.22) >> endobj 604 0 obj (6.2.22 trusted-keys Statement Definition and Usage) endobj 605 0 obj << /S /GoTo /D (subsection.6.2.23) >> endobj 608 0 obj (6.2.23 managed-keys Statement Grammar) endobj 609 0 obj << /S /GoTo /D (subsection.6.2.24) >> endobj 612 0 obj (6.2.24 managed-keys Statement Definition and Usage) endobj 613 0 obj << /S /GoTo /D (subsection.6.2.25) >> endobj 616 0 obj (6.2.25 view Statement Grammar) endobj 617 0 obj << /S /GoTo /D (subsection.6.2.26) >> endobj 620 0 obj (6.2.26 view Statement Definition and Usage) endobj 621 0 obj << /S /GoTo /D (subsection.6.2.27) >> endobj 624 0 obj (6.2.27 zone Statement Grammar) endobj 625 0 obj << /S /GoTo /D (subsection.6.2.28) >> endobj 628 0 obj (6.2.28 zone Statement Definition and Usage) endobj 629 0 obj << /S /GoTo /D (subsubsection.6.2.28.1) >> endobj 632 0 obj (6.2.28.1 Zone Types) endobj 633 0 obj << /S /GoTo /D (subsubsection.6.2.28.2) >> endobj 636 0 obj (6.2.28.2 Class) endobj 637 0 obj << /S /GoTo /D (subsubsection.6.2.28.3) >> endobj 640 0 obj (6.2.28.3 Zone Options) endobj 641 0 obj << /S /GoTo /D (subsubsection.6.2.28.4) >> endobj 644 0 obj (6.2.28.4 Dynamic Update Policies) endobj 645 0 obj << /S /GoTo /D (subsubsection.6.2.28.5) >> endobj 648 0 obj (6.2.28.5 Multiple views) endobj 649 0 obj << /S /GoTo /D (section.6.3) >> endobj 652 0 obj (6.3 Zone File) endobj 653 0 obj << /S /GoTo /D (subsection.6.3.1) >> endobj 656 0 obj (6.3.1 Types of Resource Records and When to Use Them) endobj 657 0 obj << /S /GoTo /D (subsubsection.6.3.1.1) >> endobj 660 0 obj (6.3.1.1 Resource Records) endobj 661 0 obj << /S /GoTo /D (subsubsection.6.3.1.2) >> endobj 664 0 obj (6.3.1.2 Textual expression of RRs) endobj 665 0 obj << /S /GoTo /D (subsection.6.3.2) >> endobj 668 0 obj (6.3.2 Discussion of MX Records) endobj 669 0 obj << /S /GoTo /D (subsection.6.3.3) >> endobj 672 0 obj (6.3.3 Setting TTLs) endobj 673 0 obj << /S /GoTo /D (subsection.6.3.4) >> endobj 676 0 obj (6.3.4 Inverse Mapping in IPv4) endobj 677 0 obj << /S /GoTo /D (subsection.6.3.5) >> endobj 680 0 obj (6.3.5 Other Zone File Directives) endobj 681 0 obj << /S /GoTo /D (subsubsection.6.3.5.1) >> endobj 684 0 obj (6.3.5.1 The @ \(at-sign\)) endobj 685 0 obj << /S /GoTo /D (subsubsection.6.3.5.2) >> endobj 688 0 obj (6.3.5.2 The \044ORIGIN Directive) endobj 689 0 obj << /S /GoTo /D (subsubsection.6.3.5.3) >> endobj 692 0 obj (6.3.5.3 The \044INCLUDE Directive) endobj 693 0 obj << /S /GoTo /D (subsubsection.6.3.5.4) >> endobj 696 0 obj (6.3.5.4 The \044TTL Directive) endobj 697 0 obj << /S /GoTo /D (subsection.6.3.6) >> endobj 700 0 obj (6.3.6 BIND Master File Extension: the \044GENERATE Directive) endobj 701 0 obj << /S /GoTo /D (subsection.6.3.7) >> endobj 704 0 obj (6.3.7 Additional File Formats) endobj 705 0 obj << /S /GoTo /D (section.6.4) >> endobj 708 0 obj (6.4 BIND9 Statistics) endobj 709 0 obj << /S /GoTo /D (subsubsection.6.4.0.1) >> endobj 712 0 obj (6.4.0.1 The Statistics File) endobj 713 0 obj << /S /GoTo /D (subsection.6.4.1) >> endobj 716 0 obj (6.4.1 Statistics Counters) endobj 717 0 obj << /S /GoTo /D (subsubsection.6.4.1.1) >> endobj 720 0 obj (6.4.1.1 Name Server Statistics Counters) endobj 721 0 obj << /S /GoTo /D (subsubsection.6.4.1.2) >> endobj 724 0 obj (6.4.1.2 Zone Maintenance Statistics Counters) endobj 725 0 obj << /S /GoTo /D (subsubsection.6.4.1.3) >> endobj 728 0 obj (6.4.1.3 Resolver Statistics Counters) endobj 729 0 obj << /S /GoTo /D (subsubsection.6.4.1.4) >> endobj 732 0 obj (6.4.1.4 Socket I/O Statistics Counters) endobj 733 0 obj << /S /GoTo /D (subsubsection.6.4.1.5) >> endobj 736 0 obj (6.4.1.5 Compatibility with BIND 8 Counters) endobj 737 0 obj << /S /GoTo /D (chapter.7) >> endobj 740 0 obj (7 BIND 9 Security Considerations) endobj 741 0 obj << /S /GoTo /D (section.7.1) >> endobj 744 0 obj (7.1 Access Control Lists) endobj 745 0 obj << /S /GoTo /D (section.7.2) >> endobj 748 0 obj (7.2 Chroot and Setuid) endobj 749 0 obj << /S /GoTo /D (subsection.7.2.1) >> endobj 752 0 obj (7.2.1 The chroot Environment) endobj 753 0 obj << /S /GoTo /D (subsection.7.2.2) >> endobj 756 0 obj (7.2.2 Using the setuid Function) endobj 757 0 obj << /S /GoTo /D (section.7.3) >> endobj 760 0 obj (7.3 Dynamic Update Security) endobj 761 0 obj << /S /GoTo /D (chapter.8) >> endobj 764 0 obj (8 Troubleshooting) endobj 765 0 obj << /S /GoTo /D (section.8.1) >> endobj 768 0 obj (8.1 Common Problems) endobj 769 0 obj << /S /GoTo /D (subsection.8.1.1) >> endobj 772 0 obj (8.1.1 It's not working; how can I figure out what's wrong?) endobj 773 0 obj << /S /GoTo /D (section.8.2) >> endobj 776 0 obj (8.2 Incrementing and Changing the Serial Number) endobj 777 0 obj << /S /GoTo /D (section.8.3) >> endobj 780 0 obj (8.3 Where Can I Get Help?) endobj 781 0 obj << /S /GoTo /D (appendix.A) >> endobj 784 0 obj (A Release Notes) endobj 785 0 obj << /S /GoTo /D (section.A.1) >> endobj 788 0 obj (A.1 Release Notes for BIND Version 9.10.3-P4) endobj 789 0 obj << /S /GoTo /D (subsection.A.1.1) >> endobj 792 0 obj (A.1.1 Introduction) endobj 793 0 obj << /S /GoTo /D (subsection.A.1.2) >> endobj 796 0 obj (A.1.2 Download) endobj 797 0 obj << /S /GoTo /D (subsection.A.1.3) >> endobj 800 0 obj (A.1.3 Security Fixes) endobj 801 0 obj << /S /GoTo /D (subsection.A.1.4) >> endobj 804 0 obj (A.1.4 New Features) endobj 805 0 obj << /S /GoTo /D (subsection.A.1.5) >> endobj 808 0 obj (A.1.5 Feature Changes) endobj 809 0 obj << /S /GoTo /D (subsection.A.1.6) >> endobj 812 0 obj (A.1.6 Bug Fixes) endobj 813 0 obj << /S /GoTo /D (subsection.A.1.7) >> endobj 816 0 obj (A.1.7 End of Life) endobj 817 0 obj << /S /GoTo /D (subsection.A.1.8) >> endobj 820 0 obj (A.1.8 Thank You) endobj 821 0 obj << /S /GoTo /D (appendix.B) >> endobj 824 0 obj (B A Brief History of the DNS and BIND) endobj 825 0 obj << /S /GoTo /D (section.B.1) >> endobj 828 0 obj (B.1 Section) endobj 829 0 obj << /S /GoTo /D (appendix.C) >> endobj 832 0 obj (C General DNS Reference Information) endobj 833 0 obj << /S /GoTo /D (section.C.1) >> endobj 836 0 obj (C.1 IPv6 addresses \(AAAA\)) endobj 837 0 obj << /S /GoTo /D (section.C.2) >> endobj 840 0 obj (C.2 Bibliography \(and Suggested Reading\)) endobj 841 0 obj << /S /GoTo /D (subsection.C.2.1) >> endobj 844 0 obj (C.2.1 Request for Comments \(RFCs\)) endobj 845 0 obj << /S /GoTo /D (subsection.C.2.2) >> endobj 848 0 obj (C.2.2 Internet Drafts) endobj 849 0 obj << /S /GoTo /D (subsection.C.2.3) >> endobj 852 0 obj (C.2.3 Other Documents About BIND) endobj 853 0 obj << /S /GoTo /D (appendix.D) >> endobj 856 0 obj (D BIND 9 DNS Library Support) endobj 857 0 obj << /S /GoTo /D (section.D.1) >> endobj 860 0 obj (D.1 BIND 9 DNS Library Support) endobj 861 0 obj << /S /GoTo /D (subsection.D.1.1) >> endobj 864 0 obj (D.1.1 Prerequisite) endobj 865 0 obj << /S /GoTo /D (subsection.D.1.2) >> endobj 868 0 obj (D.1.2 Compilation) endobj 869 0 obj << /S /GoTo /D (subsection.D.1.3) >> endobj 872 0 obj (D.1.3 Installation) endobj 873 0 obj << /S /GoTo /D (subsection.D.1.4) >> endobj 876 0 obj (D.1.4 Known Defects/Restrictions) endobj 877 0 obj << /S /GoTo /D (subsection.D.1.5) >> endobj 880 0 obj (D.1.5 The dns.conf File) endobj 881 0 obj << /S /GoTo /D (subsection.D.1.6) >> endobj 884 0 obj (D.1.6 Sample Applications) endobj 885 0 obj << /S /GoTo /D (subsubsection.D.1.6.1) >> endobj 888 0 obj (D.1.6.1 sample: a simple stub resolver utility) endobj 889 0 obj << /S /GoTo /D (subsubsection.D.1.6.2) >> endobj 892 0 obj (D.1.6.2 sample-async: a simple stub resolver, working asynchronously) endobj 893 0 obj << /S /GoTo /D (subsubsection.D.1.6.3) >> endobj 896 0 obj (D.1.6.3 sample-request: a simple DNS transaction client) endobj 897 0 obj << /S /GoTo /D (subsubsection.D.1.6.4) >> endobj 900 0 obj (D.1.6.4 sample-gai: getaddrinfo\(\) and getnameinfo\(\) test code) endobj 901 0 obj << /S /GoTo /D (subsubsection.D.1.6.5) >> endobj 904 0 obj (D.1.6.5 sample-update: a simple dynamic update client program) endobj 905 0 obj << /S /GoTo /D (subsubsection.D.1.6.6) >> endobj 908 0 obj (D.1.6.6 nsprobe: domain/name server checker in terms of RFC 4074) endobj 909 0 obj << /S /GoTo /D (subsection.D.1.7) >> endobj 912 0 obj (D.1.7 Library References) endobj 913 0 obj << /S /GoTo /D (appendix.E) >> endobj 916 0 obj (E Manual pages) endobj 917 0 obj << /S /GoTo /D (section.E.1) >> endobj 920 0 obj (E.1 dig) endobj 921 0 obj << /S /GoTo /D (section.E.2) >> endobj 924 0 obj (E.2 host) endobj 925 0 obj << /S /GoTo /D (section.E.3) >> endobj 928 0 obj (E.3 delv) endobj 929 0 obj << /S /GoTo /D (section.E.4) >> endobj 932 0 obj (E.4 dnssec-checkds) endobj 933 0 obj << /S /GoTo /D (section.E.5) >> endobj 936 0 obj (E.5 dnssec-coverage) endobj 937 0 obj << /S /GoTo /D (section.E.6) >> endobj 940 0 obj (E.6 dnssec-dsfromkey) endobj 941 0 obj << /S /GoTo /D (section.E.7) >> endobj 944 0 obj (E.7 dnssec-importkey) endobj 945 0 obj << /S /GoTo /D (section.E.8) >> endobj 948 0 obj (E.8 dnssec-keyfromlabel) endobj 949 0 obj << /S /GoTo /D (section.E.9) >> endobj 952 0 obj (E.9 dnssec-keygen) endobj 953 0 obj << /S /GoTo /D (section.E.10) >> endobj 956 0 obj (E.10 dnssec-revoke) endobj 957 0 obj << /S /GoTo /D (section.E.11) >> endobj 960 0 obj (E.11 dnssec-settime) endobj 961 0 obj << /S /GoTo /D (section.E.12) >> endobj 964 0 obj (E.12 dnssec-signzone) endobj 965 0 obj << /S /GoTo /D (section.E.13) >> endobj 968 0 obj (E.13 dnssec-verify) endobj 969 0 obj << /S /GoTo /D (section.E.14) >> endobj 972 0 obj (E.14 named-checkconf) endobj 973 0 obj << /S /GoTo /D (section.E.15) >> endobj 976 0 obj (E.15 named-checkzone) endobj 977 0 obj << /S /GoTo /D (section.E.16) >> endobj 980 0 obj (E.16 named) endobj 981 0 obj << /S /GoTo /D (section.E.17) >> endobj 984 0 obj (E.17 named-journalprint) endobj 985 0 obj << /S /GoTo /D (section.E.18) >> endobj 988 0 obj (E.18 named-rrchecker) endobj 989 0 obj << /S /GoTo /D (section.E.19) >> endobj 992 0 obj (E.19 nsupdate) endobj 993 0 obj << /S /GoTo /D (section.E.20) >> endobj 996 0 obj (E.20 rndc) endobj 997 0 obj << /S /GoTo /D (section.E.21) >> endobj 1000 0 obj (E.21 rndc.conf) endobj 1001 0 obj << /S /GoTo /D (section.E.22) >> endobj 1004 0 obj (E.22 rndc-confgen) endobj 1005 0 obj << /S /GoTo /D (section.E.23) >> endobj 1008 0 obj (E.23 ddns-confgen) endobj 1009 0 obj << /S /GoTo /D (section.E.24) >> endobj 1012 0 obj (E.24 arpaname) endobj 1013 0 obj << /S /GoTo /D (section.E.25) >> endobj 1016 0 obj (E.25 genrandom) endobj 1017 0 obj << /S /GoTo /D (section.E.26) >> endobj 1020 0 obj (E.26 isc-hmac-fixup) endobj 1021 0 obj << /S /GoTo /D (section.E.27) >> endobj 1024 0 obj (E.27 nsec3hash) endobj 1025 0 obj << /S /GoTo /D [1026 0 R /FitH ] >> endobj 1029 0 obj << /Length 278 /Filter /FlateDecode >> stream xÚ‘MOA †ïû+z„Ö¶3£5˜hÄl¸C"KXðÿÛe‘õ`&™vÚ'íÛÙaHŠä²‡˜=*±Âr[¼[î¾à3ãÕ¡zçìñG¶ô1Ç PŠèˆÝ5ö g! J5\ˆ¤ÃÇU1ºñSd¨ÖÀ¢¨)*\¸jõ:OŸ&ÃR”¹77«í¦ÙŽíâ¸kûÐK½®ÛºYÖ÷êØ rðÁôeL)Ê<.šÏÅG—·¶b :oš¬mGeÃmì˜Ó϶ó!3êö°Ù5g!È„®|ö]¹â¶ºÌª>`bÉàDzÇ&…=ê‰ø¶Ý_퓨¿,<šn&»bVÀ슌1ºnãÉ6n"ÿÿm_Lkgendstream endobj 1026 0 obj << /Type /Page /Contents 1029 0 R /Resources 1028 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1038 0 R >> endobj 1027 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./isc-logo.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 1039 0 R /Matrix [1.00000000 0.00000000 0.00000000 1.00000000 0.00000000 0.00000000] /BBox [0.00000000 0.00000000 612.00000000 792.00000000] /PieceInfo << /Illustrator 1040 0 R >> /Resources << /ColorSpace << /CS0 1041 0 R >>/Properties << /MC0 1042 0 R >>/ExtGState << /GS0 1043 0 R >>>> /Length 843 /Filter /FlateDecode >> stream H‰tUIŽ$7 ¼ç+ôb‹‹¶«Û†OcàƒP°}©`ÜÿÁLU7Ð6 ÈT¤$.Aëå·×òòåµ–Ÿ~~-Ç£–±¬tµrãâŸ??Ê÷ãåõ÷Zîo¥ŠÏgçsF)owlÿŠí¿ßŽEKÅO‹õ!ÝZq¼[oQîßî|;ÂÅ`¸–ÇáK¦GQ—¹ð²²$h¿ûñ×ñõƒ=¯KZôUà_*Oƒ·!ˬè‰Ï7ŸÒ*WYL¢›D‡m‰æ°zá[“˜Šnâ>?|°%6Kø ›Øiê?ÃÒš)0*¾ßƒ2!} j´rS…[2 1Z“ÞGA¨u£r•~îωãÞeTä²އ¦1'ïÇIŒ‚HGGŠ`´kf ò¸—wa±FÚFBA[c)L‡4SzZŠÓ¼ÄÓSF¬äDZÊІ9ù¸> Hº¡ J‚xi†þOá@½-M†xôÉ‚î³_¨OC8³Ä:JXl 0$‡(•vàª~FC¬žm†¢Ëj£4QzÐŒT³«´$Ù‚±³ ¬‘î5Þ[š¸FÚ3föòùˆÏAk€¥ûl0,¥·'XIo Ïy*æ#Až‡?+E#;™J¹–ºp”UQ–§Â< F ‘åReBC[¬ÐWçz %A2×¹NôØV𑿠BqÕ•l9uš× ^D5 ™]ÀS—÷ã‚H¯X4¾¢oÆØ ŒÉÆÞõcUÑrΣe©úx"E]æ†`¦Øº:AcÁѶÓ}¸oüxbˆ Òétž^‚fO„€PÈúÄÙt“ÍÚ16 Ì‹<{a˜ïºõ4ÖØ(®)tAtR÷´[bvL·>³o [Õ³ü˜“ÓÓ–²\AYŸ`IõÌõ„ˆ‰sz£“$Œ‰ýÁ˜˜IO !=§ ¨Œø†vGc £I#/'~<1‚ÀÔRPy±´ýl1½Ͷw1 чd }¡þa#fßËþÚF¯ÞƒÇY}ïAô Ë9b :žÎÞF" ‹>64”~0IGD˜Ë ذ$ÙtMâ¯%Z½Gð¾¥Úñ§aÑÌ‘ I¼ ý—/øýzü+À0huendstream endobj 1039 0 obj << /CreationDate (D:20100303120319-08'00') /Creator (Adobe Illustrator CS3) /Producer (Adobe PDF library 8.00) /ModDate (D:20100412113401-07'00') /Title (ISC_logo_only_RGB) >> endobj 1040 0 obj << /Private 1044 0 R /LastModified (D:20100412113400-07'00') >> endobj 1041 0 obj [/ICCBased 1045 0 R] endobj 1042 0 obj << /Intent 1046 0 R /Usage 1047 0 R /Name (Layer 1) /Type /OCG >> endobj 1043 0 obj << /OPM 1 /BM /Normal /CA 1 /OP false /SMask /None /ca 1 /AIS false /op false /Type /ExtGState /SA true >> endobj 1044 0 obj << /RoundtripVersion 13 /ContainerVersion 11 /CreatorVersion 13 /AIMetaData 1048 0 R /AIPrivateData1 1049 0 R /AIPrivateData2 1050 0 R /AIPrivateData3 1051 0 R /AIPrivateData4 1052 0 R /AIPrivateData5 1053 0 R /NumBlock 5 /RoundtripStreamType 1 >> endobj 1045 0 obj << /Length 281 /Filter /FlateDecode /N 3 >> stream H‰b``2ptqre``ÈÍ+) rwRˆˆŒR`?ÏÀÆÀ̉ÉÅŽ> v^~^*øvD_Ö™…)p%•é?@l”’ZœÌÀÀhdg——ÅçÙ"IÙ`ö»($ÈÈ>dó¥CØW@ì$û ˆ]ôý¤>Ìfâ›aË€Ø%© {œó *‹2Ó3J ---Sò“R‚+‹KRs‹<ó’ó‹ ò‹KRS€j!îAˆBPˆi5Zh’èo‚Öç@pø2ŠAˆ!@riQ”ÉÈdL˜0cŽƒÿR–?1“^†: üSbj† ú ûæÀÆOýendstream endobj 1046 0 obj [/View/Design] endobj 1047 0 obj << /CreatorInfo << /Subtype /Artwork /Creator (Adobe Illustrator 13.0) >> >> endobj 1048 0 obj << /Length 981 >> stream %!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 13.0 %%AI8_CreatorVersion: 13.0.2 %%For: (Brian Reid) () %%Title: (ISC_logo_only_RGB.ai) %%CreationDate: 4/12/10 11:34 AM %%BoundingBox: 247 367 366 413 %%HiResBoundingBox: 247.0869 367.5654 365.0859 412.583 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 9.0 %AI12_BuildNumber: 434 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0.658824 0.8 (ISC logo blue) %%+ 0.372549 0.376471 0.384314 (PANTONE 425 U) %%+ 0 0 0 ([Registration]) %AI3_TemplateBox: 306.5 395.5 306.5 395.5 %AI3_TileBox: 18 33.1201 594 786.96 %AI3_DocumentPreview: None %AI5_ArtSize: 612 792 %AI5_RulerUnits: 3 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 0 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI9_OpenToView: -381 793 0.92 1268 743 26 0 0 117 75 0 0 1 1 1 0 1 %AI5_OpenViewLayers: 7 %%PageOrigin:0 0 %AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 1049 0 obj << /Length 11082 >> stream %%BoundingBox: 247 367 366 413 %%HiResBoundingBox: 247.0869 367.5654 365.0859 412.583 %AI7_Thumbnail: 128 52 8 %%BeginData: 10932 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C45FD1F52285252A8FD04FFFD05A8FFFFFFA87DFD4F52285252522852 %525228525252285252522852525228525252285252522852277DA8FFFFA8 %7D7D525227FD04527DA8FFFFA85252275252522852525228525252285252 %522852525228525252285252522852525228525252285252522852525228 %52525228525252285252522852525228525252285252522852525228FD21 %52A8FFFF7D7D525227FD0752275252A8FFFF7DFD215227FD2A522E522752 %2E5227522E5227522E5227522E5227522E5227522E5227527DFFFFA85252 %27522E5227522E5227522E5227522752A8FF7D5227522E5227522E522752 %2E5227522E5227522E5227522E5227522E522752277D7D7D275227522E52 %27522E5227522E5227522E5227522E5227522E5227522E5227522E522752 %2E5227FD1A52277DA8FFA87D2EFD11522E527DFFA853FD1D52A8FFFFFF7D %28FD285228525252285252522852525228525252285252522852277DFFFF %7D522752525228525252285252522852525228525252275252FFA8522752 %285252522852525228525252285252522852525228525252277DFFA852A8 %FF5227525252285252522852525228525252285252522852525228525252 %285252522852525228FD1852277DFFFFFD1B52FFA8FD1A527DFFA8275252 %FF7DFD265227522E5227522E5227522E5227522E5227522E522752277DFF %FF525227522E5227522E5227522E5227522E5227522E5227522E52275252 %FFA852275227522E5227522E5227522E5227522E5227522E522752A8A827 %522E527DA9275227522E5227522E5227522E5227522E5227522E52275227 %5227522E5227522E5227522EFD17527DFFA8FD1E527DFFA8FD17527DFFFD %0452287DFFFD155228FD075228FD08522852525228525252285252522852 %5252285252522852527D2752525228525252285252522852525228525252 %2852525228525252285252527DFF7D522852525228525252285252522852 %525228FD0452FF7D5228FD0452FF52522852525228525252285252522752 %2752527DA1A8A8FFCACFA8CAA17D5252275228FD3C52A8FFFD145228A8FF %53FD0652FFA82EFD0C527D7DCAFD04FFAFAF85AF85AFAFFFFFFFA87DFD05 %522E5227522E5227522E5227522E5227522E5227522E5227522E5227522E %5227522E5227522E5227522E5227522E5227522E5227522E5227522752A8 %FF275227522E5227522E5227522E5227522E522752FFA827522E5227522E %FF7D522E5227522E522752275252A8FFFFAFAF603CFD041413FD04143C60 %AFFFFF535227FD3A52277DFFA827FD11527DFFFD0852A8FFFD0952A8CFFF %FFAF3C3D1414141A141A141A141A141A14141461AFFFA8FD045228525252 %285252522852525228525252285252522852525228525252285252522852 %5252285252522852525228525252285252522852525227A8FF5227525252 %2852525228525252285252522EFFA85227525252285228A87D5252522852 %27527DFFFFAF603CFD07141A1414141A1414141AFD041460FFA8FD3D52FF %A8FD10527DFF7DFD0F527DFFFFA9611414141A141A141A141A141A141A14 %1A141A141A141A14143CFFA827522E5227522E5227522E5227522E522752 %2E5227522E5227522E5227522E5227522E5227522E5227522E5227522E52 %27522E5227522E5227522E527DFF525227522E5227522E5227522E522752 %A8FF27522E5227522E5227522852275252A8FFFF3C1413FD191436FFFD3C %5259FFA828FD0E52FF7DFD0D527DFFFF8B1414141A141A141A141A141A14 %1A141A141A141A141A141A141A141A141460285252522852525228525252 %285252522852525228525252275227522752275227525252285252522852 %52522852525228525252285252522852525227A8FF7D2752525228525252 %2852525227A8FF52275252522852525228522752A8FFA93CFD05141A1414 %141A1414141A1414141A1414141A1414141A1414141A1414FD1552285252 %7D527D597D527DFD065227FD1852FFA8FD0D52FFFFFD0A52277DFFFF601A %141A141A141A141A141A141A141A141A141A141A141A141A141A141A141A %141A142E5227522E5227522E5227522E5227522752527D7DA8A8FD09FFA8 %FFA8A87D532852275227522E5227522E5227522E5227522E5227522E527D %FF525227522E5227522E52275252FF7D522E5227522E522752277DFFFF36 %FD2314FD0E527D7DFD07FFA8A87DA87DA87DFD04A8FD05FFA87DFD15527D %FFA827FD0A52A8FF7DFD0952A8FFAF1414141A141A141A141A141A141A14 %1A141A141A141A141A141A141A141A141A141A141A145252285252522852 %525227527DA8FFFFFFA87D7D52522752275227522752275227522752527D %A8FFFFFFA87E52522752525228525252285252522852525227A8FF522752 %5252285252522752FFA8275252522852525227A8FF85FD05141A1414141A %1414141A1414141A1414141A1414141A1414141A1414141A1414141AFD07 %52275253A8FFFFFFA8FD045227FD0F522EFD04527D7DFFFFFFA87DFD1052 %7DFF7DFD0A52FF7DFD0852A8FF8B1414141A141A141A141A141A141A141A %141A141A141A141A141A141A141A141A141A141A141A1427522E52275227 %7DA8FFFFA85252275227522E5227522E5227522E5227522E5227522E5227 %522E52275227527DFFFFFF7D52275227522E5227522E5227522752A8A827 %5227522E52275227A8FF5227522752525227A8FF6113FD2714FD0652A8FF %FF7D7D28FD22527DA8FFFF7DFD0C5227A8FF7DFD0852A8FFFD06522EA8FF %61141A141A141A141A141A141A141A141A141A141A141A141A141A141A14 %1A141A141A141A141A141A14285227527DFFFF7D52522752285252522852 %525228525252285252522852525228525252285252522852525228522752 %52FFFFA8525228522852525228FD0452FF7D5228525252285252FF7D5252 %52285227A8FF611414141A1414141A1414141A1414141A1414141A141414 %1A1414141A1414141A1414141A1414141A141452277DFFFFA87D28FD2952 %287DFFFF7EFD0B52A8FFFD065227A8FF7D2752525227A8FF8B141A141A14 %1A141A141A141A141A141A141A141A141A141A141A141A141A141A141A14 %1A141A141A141A1428A8FFFF525227522E5227522E5227522E5227522E52 %27522E5227522E5227522E5227522E5227522E5227522E5227522E522752 %7DFFA87D275227522E522752277EFF52275227522852A8FF52522752277D %FF8BFD121413FD0F1413FD0914FFFFA8FD3352FFFFA8FD0952FF7DFD0652 %FFA8FD04527DFFAF141A141A141A141A141A141A141A141A141A14613C3C %141A141A141A141A141A141A143D3C3C141A141A141A14FF7D2752525228 %525252285252522852525228525252285252522852525228525252285252 %522852525228525252285252522852525227A8FFA8FD045228525252A8A8 %27522852277DFF7D27522752A8FFFD051461A9AF848B1414141A141436AF %AFFFFFFFAFAF36FD04141A14141461A9FFAFFFAFAF601A1414141A7D2EFD %3552277DFFFFFD0752A8FFFD05527DFFFD04527DFF3C14141A141484FFFF %FFAF1A141A141A85FD09FF841A141A141A14AFFD08FF841A141A1427522E %5227522E5227522E5227522E5227522E5227522E5227522E5227522E5227 %522E5227522E5227522E5227522E5227522E5227522E52277DA8FF52522E %5227527DFF52522E5227FFA852275252FF60FD061485FFFFFFAFFD041460 %FD0BFF36FD0414AFFD0AFF60141414FD3A5253FFFF7DFD04527DFFA85252 %527DFFA8285252FFAF1A141A141A141A84FFFFFFAF3D141A14FD05FF603D %60FD04FFAF141A1461FD04FFA96136AFFD04FF141A142852525228525252 %285252522852525228525252285252522852525228525252285252522852 %52522852525228525252285252522852525228522752A8FF5252285252FF %A8FD0452FF7D5227A8FF3C141AFD051485FFFFFFAF14141460FD04FF3614 %141460FFFFFFA91A141484FFFFFFA91A141414FD04FF611414FD3D52A8FF %FD0452A8FF525228A8FF7D277DFF8B141A141A141A141A85FFFFFFAF1A14 %1A60FD04FF3C141A1461FD04FF141A14FD04FF8B141A141AAFFFFFFF601A %142E5227522E5227522E5227522E5227522E5227522E5227522E5227522E %5227522E5227522E5227522E5227522E5227522E5227522E5227522E5227 %522752A8FF5252277DFF7D2752A8FF2752A8FFFD08141385FFFFFFAF1414 %1361FD04FF36FD04148584856014133CFD04FF60FD0414FD04FF851314FD %3D52287DFFFF525252FF7D5252FFA8527DFF3C1A141A141A141A141A85FF %FFFFAF1A141A60FD04FFAF141A141A141A141A141A3CFD04FF61141A141A %3C616061361A145252285252522852525228525252285252522852525228 %525252285252522852525228525252285252522852525228525252275252 %522752525228525252277DFF7E2752FFA82753FF7E27FFA914141A141414 %1A1414148BFFFFFFAF1414143CAFFD04FFAFFD091461FD04FF3614141AFD %07141AFD2B522852285227FD075227FD075227A8FF7D27FFA8527DFF7D7D %FF3D141A141A141A141A141484FFFFFFA91A141A1485FD06FF603C141A14 %1A14143CFD04FF61141A141A141A141A141A1427522E5227522E5227522E %5227522E5227522E5227522E5227522E5227522E5227522E522752275227 %FD04527D7DA8A8FFA8FFA8FFA8A87D7D52522752275227FFA8527DFF277D %FF52A8AF13FD0A1485FFFFFFAFFD0414138BFD06FFA860FD05143CFD04FF %36FD0B14FD2852A8A8FD07FFA8FFA8FFA8FD06FFA87D5227527DFF7D7DFF %7DA8FF7DFF3C1A141A141A141A141A141A84FFFFFFAF3D141A141A148BFD %07FF8B141A141A3CFD04FF61141A141A141A141A141A1428525252285252 %522852525228525252285252522852525228525252285252522752275252 %A8A8FFFFFFA8A87D7DFD065227FD04527D7DA8FFFFA87D2752A8FF52FF7D %A8A8CAA914141A1414141A1414141A1485FFFFFFAFFD071460A8FD06FF8B %1414143CFD04FF36FD04141A1414141A1414FD2252A8FD04FF7D7D525228 %5227FD0B52275252527DFFFFFF5253FFA8A8A8FFA8FF61141A141A141A14 %1A141A141A85FFFFFFAF1A141A141A141A141A60FD06FF85141A3CFD04FF %61141A141A141A141A141A142E5227522E5227522E5227522E5227522E52 %27522E5227522E5227522752277DA8FFFFA859522752275227522E522752 %2E5227522E5227522E5227522752277DA8FF7DA8FFFFA8FFFFAFFD0C1413 %85FFFFFFAFFD061413FD0414AFFD04FFA9141360FD04FF36FD051413FD05 %14FD1D527DFFFFFF7D7DFD1E52A8FFA8FD05FF601A141A141A141A141A14 %1A141A85FFFFFFAF1A141A143D363D141A141A14FD05FF3C1A3CFD04FF61 %141A141A60AF85AF601A1452522852525228525252285252522852525228 %52525228525252277DFFFFA87D2E52275252522852525228525252285252 %52285252522852525228525252285228527DFD06FF3C141A1414141A1414 %141A1414148BFFFFFFAF141414AFFFFFAF8BFD04143CFD04FF3C143CFD04 %FF60FD04148BFFFFFFAF1414FD1752285259FFFFA9525227FD2352A8FD04 %FFAF141A141A141A141A141A141A141484FFFFFFA91A141484FFFFFFA91A %141A1461FD04FF3C1414FD04FF8B141A141AA9FFFFFF85141427522E5227 %522E5227522E5227522E5227522E52275227527DFFA87D27522E5227522E %5227522E5227522E5227522E5227522E5227522E5227522E5227522E5227 %522752A8FFFFFF60FD0E1485FFFFFFAF14141485FD04FFFD041436FD04FF %3C141484FFFFFFA8FD0414FD04FF611414FD16527DFFFF7D5228FD275227 %A8FFFFFF3D141A141A141A141A141A141A141A84FFFFFFAF3D141460FD04 %FFAF363C3CFD05FF141A1461FD04FF853C148BFD04FF3C1A142752275227 %52275227522752275227522752275227A8FFA82852275227522752275227 %522752275227522752275227522752275227522752275227522752275227 %52275252FFFFAFFD0F1485FFFFFFAFFD0414A8FD05FFAFFD05FF36FD0414 %AFFD0AFF841414147D527D527D527D527D527D527D527D527D527D52A8FF %FF527D527D527D527D527D527D527D527D527D527D527D527D527D527D52 %7D527D527D527D527D527D527D527D527DA8FF853C363D3C3C363D3C3C36 %3D3C3C363D85FFFFFFAF3D363D3685FD0AFFAF3C363D3C3C60FD0AFF6136 %3D3CFD16FFA8FD49FFAFFD11FFAFFD09FFAFFFFFFF %%EndData endstream endobj 1050 0 obj << /Length 65536 >> stream %AI12_CompressedDataxœì½ëŽ]Iv&öçÒ?tM*î—¶1@æÉLY%5º[ @±¨ÇE²Áª’Ü~zÇZëûVìs2Y]7Æ@ç“™+÷‰;"ÖýöÿÓ¯ûâöËÿüöE~nNñçOo_óñÓ¯nzó×_}õí×ß|Ð/~óË›¸îZ7Ýþõø7þÃÛO_¿ûøáWú§—iýñQ>ý‹»Oï^¸ùÍÛw_þòæ¿\àß½ûæ«·ëýÛó_}üýÇ/>~øê_üæ¯î^¾~÷K>xtÿú›u[ù˘þ2†›•ËÍí߬î>~ûáËw~÷ñÿþÕM*ý&7ù×nJÌëÏÿû»ß¼ýúúž—a´)7¾¬­–õC]:×GÒË:äc÷ß|ûþí‡o~ýéã›·_}þøÕÇO_ÿêæüÇ5û¿yýûõ—×7ÿçÛ¯¾úøï7w_½~óÖË×/ß}õv½çû×ßÜLY‘Û¿Žé‹»oß}õåß~ûþŸß®(¹8¡#þý×k¨5ªü,àþÅ_¿_ß¾ýæ›5Ûõ~õZWL¯ˆÿÃM°~÷úÓïß~³ŽÂǯ¾ýFæøÓÚšW¯ÿøV¶7Úþîo?üîã?èü^ä×lòZÀ™nbj㦗|“š='ö›^ñȨŌd C÷µÐ¿^{ûwŸÞýþ݇_abý‹¿úôî˽ß=Ý û¦o°vwÿ›üg“\ïûÍ7o?`ÒëœÿæpnÂË¿ùízâÇ/ÏßË‚-¨²¶÷Ã:Kë°ØßügýËúø·°Ùëï_¬½ùõ§wdÌÓßê_Æ¿þêÛõ§¿úôñÛ?üõ‡ùxú…„_¿þæ_&¼ýðå× ± f¿ÞØ'ôÕ»{k°…ÛøåwŽ÷»O¯ß¬ÇÞüÝ?ÿ··o¾Y`ÿôÛoß}óöOôÛ7²LŸnî>}ûõ¿Þüîãǯ|~—òi¬P¹ÿŒgüZ?ðáï>ØJ?}n¸~ÒÂŒÿáž²îþüÖÿGýüú«¯ÞýþÓë?üë»7Ï=à™¿û“ìo?àa Ç?½ÝŸ×_ùÿ÷8–|ÿÏ¿z÷õû}_¿þôÍ»7_½ýí¿þæíû?=ÚýÛYœí°l }øðoo¿úø‡Ã$òú×7ÿåõ§?|×вMÿòî× CŸ÷2~|ÿaÚ7¿ý××x«Óýæ_õÎß~cüÕë¯?Ý(܇ò³Îï¢g—$É`>hýbÆ#é{ñâ;hb¿¹ûpøó_}zýå»Em—@ó÷>¼~ÿöË›ßôËÓSТñõæîËÓ?þ·Sˆëú¿N?ç`ÿ øƒ_øôŸ×JÝ=ÜÝßïîînïæ]¿kwõ®Üå»xnnïoïnooçºúm»-·ù6݆ù8æyÞMù³Í%–Ì4à ãq<œÆyÜc´±ä¿‘Öúc¿_×¹ßõ¹®Ñ{¯ë*=õØc{lëºowm=§Ö×ÕZYW>µÜR -ÔÇú°®óºÖ$ëm]£ËµŠÜ¹®¼®¸®PCy\×úÎëº/ë•Ê­^£ŒÓv=¸èg ¿®È+?îËVê׃^ûçõÿ9œ£~—+žÓº"þOç¼.þl¿Ë=ñä€xñgûý;þœ×ñ¹t=ìç“þÚüª×5”¿w\ã ¤ŸÐþÄËÿtxÌŵV*¬µº¯ëj¸tçﮉë×^g\üzðëQ®ÓýãCÀq%¿²_Wõ«®î×8= ¿æáº=\w×ù꺿¼NëÛ羟¿ôT­cÞןëØß­õ»_ó|ìa!EêyÒº0A¾ÆBšÛ…<çµ”ýq„±–²Ð >äkŽÛÓ¾³®ôÃx\Hj¦™ŠÖuµ…|‚œsáôÂ÷…Æ÷úÞ·a]q¡w^W¹]صq=ñvœnÇÂùº»=¯K6M–çñ.¬+®+­+¯KÐLPs½È¢$ýnÍäNŸ²hËí}ïÎ'Ûñ 4"ê?û¡+Upâ>ïëáp=/¡‡+^\I®“ý·®|u•«ëú«=¹”˜ì?¿Æ³×üìu{}ž€îþÔµVªÜüÅwŸ„ .ЬÿùÕ}QQûn×¢“úWÆw»Òºì{2È ?$ÿ³\—|ý@ôß…«®¹éñYï++q»Níý"#1Æ¥ÁǶØÏŒ·ëÀÝÇÇõ>)åu$Zê mn×ɾ_æ1ÇœrYG£ç±ä.ß/ž°Ö*–¼Î‡°“¹¿œÌG=kIM[»-[v^tèq­w\œ¬¬Ó"ø.ؾp˜^ËO É ÅÁ½‹"öBjÅhÁfÁdÃbÁ`ÅÞ…·IqVðu(š.Ô<)NVÅÆ©x´ÓÕ¸ e‚ˆ‚ÓB >’b ½À± j›7 >]ü!‘X Ù^ô[ä½Òwà¾Ò}ãB«„?§¨z)bŸÖ·µÌë{º_[s¿6íü¸®‡5ÊYÿõ^w~ •ZK~E–·¸cV²BC†õ¸”dž«â"-¡pE½‚]NÏùåì`/.X.rrŸ~±äd[\n_ÑVšÜË‹‹\ˆ_\.¶]ó°äã„uçÚcýít PÕ È3mïuÄ[¡ëí²G²?ÁwæNWßV^ä’,òËI×û(iŽƒ¬™TÚ|Tyó ‰s¨ÄY!sFH÷*wÞÎyZ<¬CôÌ +¢ ŸëµDú¼U鳫üYT*>@½…ÚTÍ"ƒžU|Tô¬BèT!´ãyÂéÿôÕŸ¿NW€ñ=®ù]×ɼý^×ÝŸºNJÍž\G梤ÿQH¦aÃ:“ OùýApv}?ëÿü~qa}¿Õÿù]þ¿=­ÿ¦^ßåêz5¥ÒòÝø7t|—ÿ“þŸÖe_‹êŸô?ü‚ïÁ0ÖpGÙÀ½^g|?‹HsñýNä"û~Â/óp-þjRÜP9NdÙù´(}­E鈠•Ð aàSu–¶¸CÎ"ˆj-Šð÷¦­œt/eã»k)‹é‹ ‹~Ò(z…r£…‹/­gªø"_²£ÿºê´˜Ù­H‚‹±õõHÑu„ÕÅõ;‰’ÝàÈâÛrËc-mõNºD²4\ ‘1 a×Q¢Ý>¬OÉ& Ù{e±e1Xa¯÷‹µ¦5í¾^㼤÷°^±(FÜ)/>ºä¨“2ÑGe Â>§2ÏÇ5»¼0¸/l^‰¢¢:IQ=c¨úpsQv¤Â3XÔf]Æ$„±=ÚQTf'ÏHÊþ2ÝzШúÉÕ©£*uT¤¶ ¥üáBsÚ:“ëJ'W” ¹^tÔ„Žz«5`ƒFŒ=.VyZßT ×˸ê"Àz:TÍ ¢AUÄ—¡¶Ó5¨m¨®ñDÛ8觃²AE㬢Žé®WP/®S»µ ÂÖœ|g±ã{?¸ÍuZn€->ž‹® ~òÕ¦Fj:¨¬Æ%£üé|òtÉ(:Ÿ<]2Êçù¤Ò=±ÓDØiîÕJsIï²RºpRÓÌýb(b”™JãZ©Gæ²6árÄQ’%úîº\Y]š“K¶,Ûj±wn°*#阩jè»g}o¨­?­Ö×Uò~Öíþ’b~’÷“·ëJ½“Ú“î•^ÏEîÚ"æi1¬Ç…Šg!̧¥Ì·E—…"›aju3Ñb»^¢ÅÜEÉ%ØgŒÎø¢p“.*ÌÕñãi¡gRšŸ•úw1(G¼Ð¾¨BPÖ!êNU†Ò•6‹zVrô¨³‘ç”Óz/JB&{Ü)ÙvUж0%êÈ:¬ དྷ†Åh©F'ÕŽL?\ƒàª¥\ £y7^({O!û ¢Á»¾ùgQ8Ò— ùÚ`P-\¹ÌP/»šLżw%3AÍü¬aét°,=oW:Z•& JÛœdÆ$3%©!é;Ò£Û ìGf:£U"A¾M-GÅǪ̂B£iÉâl–Ò÷¡”žWóëhÙBlö+®h×Ih龄Ãà:š]sº=ûuw¸ö×<)ë²køÕWóktŽbyöKeµ“ýw«8lZÙÖ2 ?§`•˧Šå…Ry©RÊ£2y¾ÒÛ·"9\w‡y:*ð_²Qˆ5ÁõøGˆ>6¾}5xÕáO`jxÞ âŸNâÎO¥‡*>üŽ  qçK¤FX }HHÇ¢=£å›tSÃÍB)à·§¿øâÇp÷õ)¼\îLIn+5Ì¡?Ì,Ì`±€)Ÿ”iŽuëút®/ëÂÌ›Ú_."[|?ÃP6#Þ’ü¤³"?­7H]~X:Özó1ì¥j}Ùâ8Lè§Ž¤ó‰ˆ˜)²ŒÙ¢G^.z²Æ”ˆ›ÅbzVˆ¼¾}¼”—³äÃL~Â:YL_^þ +YbÔ•N±¶¹·Ý6y¾~º§ñÓ†Y3¹»w_(}šßÏ͹Ü3žNÞÄõ:;í+ªaÖd…9aªv†ÅS¤„½¹ªN=TF¸SýÁÔùOÌ :`=«)Ô$„´T̪ÒÁbK ¹…|ðÙ ©×`Û˜'• xXq6fRãa& ‡‘‹T2 y¹ù8xZ_ËjN©ànÆßné59ÃGµX2»à /ÃÀBJ?øQÌ“"¾”³òAõ¨œ„ÊÇJÄŸ"y„ÿ…JÁ5ª²?8Â?‹ò'˜Ý.ð^•ƒò âŸá1ÔOja*°HÀÉiÀý’,„ (ð˜ ó‚ì&[˜m iOÐ`Bª@Ù–Ò-iæg•C`pj>4Gj9¨Ä8P ÒŠM-(†Ñ RŒ†ëài5L½ƒsÜ(ÇÃõ ÿ59¡·¯]Ð¥%§i_·¢rçD„ÅܵÚ²éK„ÄÈk©½—äæHtêA=’Ÿ~^„H¯ÓMºüú,¦HÖ“ëô¹?\Ѹï}~øGþãü¡(nþxàèù€Þàé'øÑÁ½‰àõÎ~DpCnêÿÆßvŸ½Ä¦lÞ¼:‚Ï‚?øüÖV©¯ÂpRmáÈô“+¯‚àÅí„~Š«$pRQ€!ÝÑü(¢?ѯƒ/½!z?Û‡bè­2º£˜ ¨~ìñ á³;iíOO0þîB’ø,Ú‘ÿôy쿸ž¢ÿñ:Óg¨Âó×5­ø,Íxzýè¯Ó÷¸ç»‰ÑÕuúa·ÿ¨/Qüg4ý‡¯®t¸2²­—UcNhÃ4Œ¹…ó(²MK iFÕ¨©ÜžàK¤Ð’°Á ¡h´g>êL\1j6%ï4€ãAýMé´è˜‰)awj¾°¢¤.¨¢¡CqE¤’%XIµ”²ÈÔЀŽ[%N§ö 4)Ã9ÕS„øÐ†dµ,˜½3[¾ÒEîúš4øµ-*}™.R©s«†E ÒI ƒíjˆ;[ sií`u°¼òߦq´ÂšÖ‹|²t¹ ̨èdë•5v»^îá¨5÷‹e¾ØëX‚m³‹éœÔ({ðÀ 5†6ÙÄ(… gKS7”ÝÝ!XL«‹Òxš˜²“?.S?>Ÿöñá8§gãq¾#"ç³9É9ýð˜œË¬š‹œ%…œ•cbÏs‚ÍOH9]ç|gôæhp«E&?"ê‹‚Ô¥:¶¶8u¨¶HuªÚI§f“Óé«£he= W6Ý-^Ù¤Ï'7$¬+Ë¢s->÷ZÄšˆÓ}"bDÂë"oÐräî5G.)ù3Ï’xŒÕø w’ÀH’9©Ÿ­ìk)«(+uíî+ñ¸²L{Ö%¤Ë°^þÎcqåMí°®M¨k-n×v=ªõSÂ÷ïî4t_÷‡š3×Ѭë˜ÞÞß/|Jë0u¸"ç…æ]&z=>gŸÞ¶Mé¤|Ö´ ~£C%ˆô¯EýÄâ1DqD‡¼pr DpÞ>ãǾŽy9z¯Ý›¥Cþ©mØ>ÄkCjŽ*/?¨¤|§2ò¸¯ád1ö&[ bíˆ'+ëÀÊEþ*b˜!„*¼¬Ÿ‰Lû±C!Tn}Jo襪è…q%â.J¸ŸÄœUh¨ýdnùåÌ©gôS‡Ò%ó³ñd$Ùyð%‡Ië÷0ž‘)Ú0?IÂLϪ¥«@5¦׋ÿËáÿç‘/sŽãÖN.öÿLå>þ;9ÔŽ±ë;uúÚ…vAhM/âî,ÞFbm¢º°*œð[°dlM÷ ñM¢JšFµä¼“ vgOD¶Pº~‘‡4¹*á’aàâK‹þŽ'J–ü>+qȰªêšÚßî½c½‘iuÏ\«“:˜lu‹›õ%EuõÏtOWºCŠÒƒ¦&EMGZäKס9øá±Oý1@‡¡~ãિEéuÖŸà¥gÔŸ®‚dd«Ç²¥þ+žìdø®K4ÔwHv:Ý^ÖVx®¾B‡ƒo*»cºÓƒ:ú©NÙJ‚ÔCŽÓ­»ø‘Ô´š˜Ît«¢¥, =t"üUHÈŸÉi~šÕ¼…ÝËdò«ìæÓ“Lòí WðÎr~šçìÂðéVs‘î|‹ŸÊÆ[>Þaë’O»îñëÁ¾£Øw$;cٟij[¶×g¤lÞ×és Ò?V4>}.AúÇæ}ž‘"¡V¶ªÖµ”-ÂEd É“E☬‚2,‘[R¦¬|iŽŒ'X$YèÒ*I»¤½(ÅæƒmÒ‹1Å÷îôŒ}ò»-”´Q²FÑ…R¬”;û÷ÒFùy åµ}Ò¬“—RcûEèbvª–çv¼¿¾×-²$÷q“¾(M|âå°Ä î‡<·ÆõôO…Ÿ8ÎO“vò³ÒN~Ξ6žØÒ¶%m@cØV«~aÛö¬õ™ÓÁ÷Ü üËzÐ.xÂÁ(s–,ÿ>jT`ñx@Ú±¢ªp»ÜÉC '4Ú³‚FsAãž%FhEÚŸÕ~@ëØh=¨VäCÉ©ò˜(4UµbGm<ŸP¢ŒÖ‚¸Hâý-³¸œz] jñ‹£„ºäÓ“†F•œ¦Ê¥¬°¤%T8?€tG¤:Zšã@ÆÀ.ó˜]ó™Èp ëé¨ùè1>Xµ¢‰®íµ?V©"Í »²ãI ª4§^K¨VÒqÞÞ]H§ÛŠúŒ õôœUØ›ÉÀ.éGáí(¾™ðv¯ÇúNú<Ä~µ£Íe„Ó…ÙÅÌ-óÊÜâ5ž-úËí-´¹œ=¿x½íÉ /r=ý"†¦'cÜ£×éPÙð TÄô3SÛ¢J⦑V•4QãÃÍ4Ñ¥|Ý/\L<ÉÀ³ª ª€žÔ¥©(ð (M8ëùoRZhDºE ìŒê×g}ñ®Eä´àµÅ¼ÑšÔÁàÅ…¬8…ß5Y!8)QüíNO¸ðè’ÒI#ÉîÁ‰ÇZ1)íË`~WÇc£<ý)’ñCm”§?M4~Í8}ÆÓit¸¸?wðÙ+¯Óůé³WþŽë¢.äéâ×Ï”>d/?½úåu:ürñe¨ËÔÏva[¸NüüEŠž-ýLìïS¦H3±O‡8 gk}ÏRE^¬èô¹jE—:&j,UH%‡£Rè¥C hî6-I¡9_–uÌ‚?ÛV %ÁEYg& íѱ”I…ÞÆj4ôUçŽøŸa,Ó?ùfï14úÑôFT}yY8 ö)ü¾Æíá§[”°åO˽Ã_Ë!˜Éª¥Ûu¾ª:bÚ1£ä{—˜cæ«eÏ;Fõhù´Îvyft‘wtâ¶Òoû<ýÎÛ,o¾eé{N‰ùœ se9„]ËŽÂö1Mš³öb“nÊx™^Üíaëðq€«ì©]Ì©-Å.¸,yƒ¬³‹©-õ$¸Î½×êUŸZSãªË¨#& 0(ib€ÒÒ~·(Kåö{ §Ö)øÌâ軵ürެØ/Skx·^TwXÎbÑwkée·‘×½i}LqÑêØ rê6µ®¶ùT¥-¼Ç=Ù»­;cŠèÆî«ëw{þR.pÎê|9„è½y‰ro],*é’¯{×7àBC  ÚëÐ.í¯CÅQ–Db0‡X1×Å>}Õ*lrH ¸¨`³‡åVuj[o30­lÇ àNpËeØÂˆ^ôðŵÍæP梛6±µœe(–¶N€í¢¦K¸¶q¸á%ÄÕU*îØ€¹ØYXÀŽ+>ØÇ×ó?–2_ŠH‘u)pEÇ`4<ËëãK9®×Iâ´ólÄ©é6–øRƒc”-ñÆ&µZ©¸SOÍ ¬ ÉÍ(Ã\dXï­ë a¢äEkŸ ™k8ÀÏèkm\Áf³Ï¯—Õ#[ãËÑBpýŽIëUÜ«dÛ€aá#&[r0V›ª,A:Öµ ™¤¸ RØÖFñ“fPè…ÒK}Õȵ£c¾5“G,U‰@é÷kw®åà|×A)DÛßmás·©­U’LAVç•Mü¡ÀѺâ˜ë8>?ãÀÙœL• ÖjÄÚ¤hÇSÌZi«Cטä–×ì|ù_°uY´Y]ˆåüéJñ߀,Û œpj…vÌÁ{׸Èz9Œz=Jcà((e6` a0 †áÎ%ƒ'”Îñ(Á÷æEÏm ȼî\hË—mmPÖYÁ«’ˆÕa|d È7‹*‡ZÁfKî.Äâid±q£ IJ¥ý4Ü»”%°tRºEÖù¨EÜZæÄ²„±aÏÊœå… à›ùêýó ã)SôEÛ^a^yg³CÓªu˜6 ¥XƒL,°‹QÎ/ª„Úaer0¼i퀻z>m€…-±b”cpa´5ãÛM$*ŠE¥vÿ|nv<6D£tM>5°Üäû­;I[41úÖt—ÖR-@LÍ Ý¦lLä©p²™{»±H#ÉXöZã`â}[Ç¿¶+ª±n•Ÿ% ]wæH¤M¹iÛ:½=R¬­ãÞ’¤ñZøù'É ñý[SFfó>˜ÍÏÕâcrI2NÐbÖ΂›œ¼‰šðÝW· —±-‹,˜@×¢Ï4›’ž`¾Ä  ‚‹IR §¡fÅä³,uŠ¿M[ü³u 9áÖÐ+¥Ìj„¨K3u ´BÿùñY(à-"ãÖ%6w|èÞ—8•:&u%ËšŒŸuo4å¢ ®:;ˆ²b$ÒÙƒnû%p  (À*£lPe5ê ÃdhYZÁœWÐaÕ»—ˆ%ªÅ‚Ån0S6=Å4¢U·­=±ÙÁJ-n‘Íó& •e-C¢IQ-Q4@ÄAëáóâ+ܽƥ|‹t•ÕtD‘?£rž<FEy $ô&/:01˜PÕL>®”ÖY޳¸â•,‡à#(BÒi°l±–²írô#dJ•8^=?È+7õ®Í‡¤69qµÉšj!6|—a)ÈG“ÉL^âC„¤ç¦%W!Gcü¯ž}f±HGWÖé~–÷´ª)Ya‹†b1’£¤÷ÂB&‚V´„ïqkܬ”FÀMÌ<ÔT¤`0ÿÁÓ `g­¤Œ.YnÑ&6¥‰JbÔê´BØžbˆ:%BÄä‡`ª%À!'MçÐ??D†×[)A>y¾ÌëïOóæ¿¼ùÇÿrñ“úÑ>|yáEû“εvå\û¡î5’ÜbœD—GÔßjdàWàEŽÖYÉͽi6ÈgÀ‡AÄÏöŸ¾=Å›{¸Ûè@ËÌIÌô­¹µv¤GVÆ÷TëhdÞ6Êf€vß—Ø`¯‡«@‹«C‹K¾€•þ¶ntÎØ±œ63ÁÖ]B—^ÇlعÉb¢ï0'µ>’0B¢Ø7ÌôŸÅPk Zÿ²8Œ(Æ- f”…ª5<ñ`3OË¢u9As)‘žƒƒ®VëÑ›;¾ÌBQª0n3-²ˆ°C`v³QY2n˼w˜y¹“UmT[Á"Z5' ÜÞ>ŸÜ~8ܾQ’æú`YMöY° ÄY¨-´õ >O Å}£â^‰¤B`Åš¢ ˜ëÀ] o4¶NÓ ë<`º¥.%hšý—Âõºó%Vh`-bíÅC\‡äzØ)QúÛÅ.©bFUÂÜEËëÅ?Mñm±«’(<Õ9#ùvnµPÊRñÞ¨¸#%MZ)÷ã¢/ÌŠ r1§ì8yg¥…£OÌi^À:ÜE+Õ’L®Ï÷HËK˰ØW1Ñh® ~®R i7÷òˆW¬PÖFe/àþа§Å–éþ‚îÂöVçÁ½™+Íå¥ÐrTaê¦ÙH¬Y4÷ ¸Ð>C_ŠqZ³MŽÀ€w’“ö†Ÿ‡ƒ¶92`ë¦ü\ LÚÁmQ]T›7°=ÓrµÀ•r IK@è}Æåàïc" ˆYuàÞ¬¬Kï…‹K€û?ܽ„ßh9†M¦õØ@5[¥IU:»»¢ÔGu z³¦èK¦Ç’a’Á¶‹F Tœª3ü”BokI¸ª’œj °œ\êéà)Eb°ºKð° +w¥ûäRå·7Ð9Lß`¦®¶sl‹úŠÓo‹è:ͶPœ¼Åÿõ’.ïÍz»¸ç:´‚¹D.÷³ôu¨52*,­ÑöËfÐg…T3]/[úæœià -Åê‘„A!5HwtS*˜†˜¸hg¨‰ö¹4a&(î!°aÅÙ®|JÃÇ& ÈlZâ½My‰ ‚KW D- Œ$®‹­†¨Ðj;öBMÐëņŰe«%înU8›ØÓDó{C¤jqŽƒþ[³ø ,Lc‹Eµ# pë‹ÂáUÛQðbꘕóø.f²l³Šb¼}ƒ¢ú`Ú\?eó.àÒ³³Í8f3h6ªÊ0n-¡Æ )81¨jg™& ;}î TIšþHs·XqQiQÕs¨òu5¿XáÒÞ±É ºv{3¼ "ò†Ùn‘g ‘NF«Xîqë€8°øK•ô[û|ÍÔçRx:ÛmÄB £–Î8 ofrKjjrqçb– °‘>x]˜mÅæl³ÓX!;ÅDþm-S°Úœy¯ðØy¯ [|^À¥)Àš#&¿d;³fGʽê`&&(ÁWA{ŠšÁdÅȦ‚¦âÁ0.ÅÌElBe ªû¿Õé5ÈÙÁÅ‚¯les Q’F]X¯³~]ÂvAì™.s¦ÕœSÏe ûaK™“Fsa H¤t4lÆ»PÖÆPlÇAº+Usf3Ê‹1¹õú\²™SgŸ$¿7’x`I\3’óÒs-c*0*¤ÁØ<ámµaý"\±Â›Rƽêô3`œan©‘¨‘Úî­î7Sÿ¾G‡@Lzªíˆ>ù_üåí§oîß½ùæÝǯ?ýñæW ô‹’îˈ¿¼ùËß~óé݇ßßüâîîöÍ›oßÿæã7¯åÞ_Þü/ëÎÿuý[úØ=4ü ®D6Ä ö.QØ3ྪÆe §k¤aJÕ-CiEºØ xSD„HÍ‘DÁ}.¢D5=þq¬õ& ÊW˜æ:˜»Êdjwù?× ý§¿‡•rIŠÓPåï÷´ªGFHF¨%þ½B:Rª¬¾dJÀ÷QGÁKÈ  Ôã€{iÅà4§N4 ¡ H´2#ž %x´DìàøZƒµÛêäT-j"¸€§› EÍÁßC,™øs…œñydÈ`½‘T—xðì&üŒ;<ĆcDP¼Ùîwš¦C)¸Áb¹Èà¹pÂæÜÔ"›Lw–òÛý¨Qåro þ#”K̈hÂá ݘ&;õHo°—Ô\ ( ÒO€R‚Çmv4 äã¥ÊGÒ0r=ß@%£;Á’n$“=\tTŠŒ®Ï¸˜NœÍ\c°l$TýÙŒA%;j>øNP7—øî‰­‚ñ‹)¼gH—Û·%±Ïê00¸@D옊§PàqÔÐXÚUÔŠo¤Y2jÉ™Ÿ°¬±Û Ë4™ ê”Î[¡=ËÌà°;.´Öˆ³ÀcœBÒTĦ\Šä]Cé 9(–)P‚š€'•Oáw\ç8æ\±1Áý§Ƴj+o W¹Á,C”„‡EÚça8Ö³gëš-ïˬ†âqîØ[&'Ìà =±ÑceZ3SC1%è ‚xÔl``Q`àk‰Æ­Ê  lÓ³N™ÝRQyX$’Мfbw‡ü¨Ž¾µuL²“°Â7ôÿA?ï4SàÎÆSª~á=L™0ÜÊ ™Ý)$×€¤Àañ;ÿÐLC®pêT$‰YYC¼ÌUÖt-¿æþRš#vF1A²ŸÅƒ'Œˆ¡³ÎDìÀᛪ^_'÷-Þ|­VËþYBúsQé£k9XuÙí^ÿ}yj?—úgIðLtÎKŒˆERúê*û)uÔ.Ó;ŸÂö§?`R?S~g¤¦náÜ”¼£ßÔY«ÑÝXÍMl΢f¦ÈlpØ?p ¦ #›GÀ@ÛÒ}9j,>Jm€âAñKèlF7ÅñˆSÉÄ3ËÜÙ+€ÝS¢$h'Ó‡–#ãndÄ@h¬owpžŒà¦ÙPóäÜß|ï¨8÷:“ãÄŠ“¨Ý\|\5¸Ù¸6%ø» ½m-Dp÷`«f;•Õ™óê9ùò"¨Phc7Ç©…#~áÈAc—¥" >/vz(Sé¼W=Pp/Â|Ü<‹BN-2@gø8 À7¢sè?=`f‰Â ãû"‰âÒyÓ@äò•ëµP¢_Œ;xDÆè×Hkq©‘; ÅCLÈ9s+’ÅVég„oÜ!¨óµ›;l4 œ~È:¬D†&`Eqˆ¹KÖ”€8L4³jeðu¾:‚=mpiÀs$!j²ŽNÍØ)ÚËáO¾c‡Šï¬£»Ÿ/VßÈâo«©Lbн<59I t!`¯Í˜{¤QNˆ)`§«¼z«€'íø*`½¸æA"Lm Ø:±i¤Hà(Æù±ôG7ŒÊûÂðVÚ@:ólyDSÇ wˆ-”úS\q 9-ZK6¦1?aM™ xy¸÷¡¿ZÄ÷o'~5MA1Ï”áºú<:>ïaÔ ¼ÞF ¾K~j‘Œ÷`Ù ½.ÆËŠ{¥h H¶#&~FHà N}=þQsj¢fDõ ³’q\¦UöE.‰{ Ö̉1qOHÕ_¹7O4,8 ]àí¦7ì“PÔäñG`’;Á¢Ä,è³ÉŒÐ*Ñâ‘í1%vѡ̽›æÝ7àú‰‘YPpžînœæ0ÓKŽ¢î›B[Jˆª£1‚!_ökܘ3š<Òº[_"¦jÁ½}0ŒÊ⟙O”„ïd„,­…ÄaÕ£Wèò¡°úƒ¤VeÏ™¶fЩû•I`WãòêæC g™¬°¢ùb‰#3¾XŒ¼K¦»{v’¨„»Œ}‚ bí&0Íg€ñôqj-AµnàÅ‹á…G"w‡¨eXÇM͈LŠh‹fÀ˜'SÜse0B2kÀFfhžÅ¸­™O&ÀÂÍÖOõÕÝÌhÖ-ÕÁt1î1y0"$a¸·g5ŸÖT¡„x¯îŠÜ0ƒÁP÷ä¸ f¡I$€ð4M4ÄÒi ”:Éä¼L÷_¡õ£»–-}“ÝÒÕQ·©­{be°4…ãÄ4 ž>™r©ÃAŒnÈ .AR=±uîøâC¶+cÔ-AëA…­dÂ̟e­å,ÙÊ'àÂ(µ&‘«¯¼'MdÕ!"%¾^Çͳãž÷Á•Õú'žÇär±$ØFËä49¤yárØM“š‡Ò.UúŽ€g$q†µ{;DéÒásÄ绨{ÉÓ­*S5nȦ€¸Û§óÚÞýÊÉ–Ÿe2ŽÐ’Ü,Z‘ó4¤5ÉPhF±§#©‘^+Ätõ\’Ö€Šé‚T!pñÕ\l2¡:•#’‚¶/}Hb>+gLà˜8Ãû@ÒUîæzy†Ö`^éUÑüȨÌ}z%*ugå™Vð<™}/ â¶n Ñ” +£%ûõSDëôå–‘ä¢>J¼Scîýp(Êb iÓåß@‚ÑQ–ÚB³eTwƒŽl96ƒbв8µM*—¬¦Rè¨N–[¢©J\@vÔœ³É`àƒT V°3[eU2Ÿ/jkñZ3þ¤Tà±PÚ „W”ºJ¾þE2~h″Q²¯àX(æñÐ$÷x´4ŒÌ*'šÓp#Î`vqbdF·Ë²$$–åCF‘j(—Û½cÁ@ì ÄS¢&Žô;Ú6aMŠÓ±‡è´Ï_ûÃ}E=Yfe Ñt:naú¾€+Ëõt¿5uf•ùiOàD=IÏÐWå m'Ya•÷26}à!¡µ?«ïlÏaú±´œè8}sx.93 ³E…0:PI:ciRáÛ3As¾-©NJ+&ƒÇj$ÞÁ¨\Y=DœI¬J'þ¶XLc~q]üY÷Pó¢Y^¨!<å‹ ±Þ!DϦ2øyY6áQÁj0[¬±d“wJqÒ¼ÇÝYÌwh$„´J\£!¿¤ê™}úÃ3 ¾êíà]ºoĨ€êg¦§ÃIå$¡ ³Û´¦ ‹-füϬd§.rKÁ˜\òV½Ó ’öº›Z›%SÐe-ϸÈ®fD«FæfŸ‘!–N**…¸v¬²QX'ºÊ¦¯6Õh*PC€Á+ÎôºKŸA¦ð¶\ÁO&Ó h#×3@ d‘¬sãë2b0mé3QÐ,?Çž„¬R¸‹Á¼PJLLC`òBºé° ,l­§¾A߆ Dºm\BD˜ø:…eMɾ¸QhæÜÑPSÚ½–ðÓÞ§ÛÍy¦§Àë¬Ëë1ð°²*ò¤^2gÚéL° qçfqÑTº²0·ˆ+*°Km•@ bù©›l ¨ªì­à¢ŠR…ªrt"XÖ$ËýqR‡q§Ñ]é]2Ùx7³ñÛd†Øá 4äŸ_j]m2ýE56¥§”s'zÀ %ù½^ä(ºL-4Öꬪ%Ѥ;¥ÇÅÕ>”+|B¤…ˆ#ç§M·†€&¼–ê¨,ô)å=c½ @MæHXñ—¾V‡fѤ]ïÔé=Á~éTíTH*A¥[;àÀÄrmÙKÀ‰h.k©Ø=„àZéÉ G«m•Tæ×Õtëq¿&CæªmmZòt\>0€SˆB‹Æ²Ž Kꆑ•Ep‚ÚiÌ;QοÓ0 s?LÅ­ØÉªf¿'º€Y-/jŠú ¶ûdy"‰;™N}~þq¬þ<¼"Z«§0@psót‘¬3.3Ë` Ðz0Îø|IŒ.ˆÓÌ«:@ã Hµ}:½%Ìš–>øžà8 ®¾öÙ3-Õ˜ `¼³y5‚:`ãZ\©Gâ©ÕÏmÞ³ÃZÖnfó»Éñ|O°S@ù¤$xŒùÒG'ÀƬÝ]‹Rð3}K€ªûé¨ût\Ìfõ=‹E•7Ã8w^ŠÔÇn¬;ÄØãîÅþ£ùóóã²âRñäx±Ñ!'…/5‡-óú¾Ð œåç%SË'ãž}ñ›.Uv¸ø´HFãFâÄ©› ÌLú"0—~ÀDZUí:x1äÕã‰èm©Ï 6•÷Ó‘0€1fæÁ+êxæ(QÌmóêùÇaC⎡8Öìp CnóØ ARºqæ<ÉFE$›^ëÕL€gŸÏîÍ«YJò{Bû*0Ú?ÃÿÔžÕ>‰£j Ä\à`,òP«U€µDµ2÷sàΩ † Õ=ß k¤(ºxå½ÊéôÓ¤õ÷©«wÕ@ê¿47ÈÃʤEÜãé öÔ®FæÔضDÔíΑ· Ý[”¢G¯M ³áÔXWmzêJu'Ú£:B Ó¡™…ÌÖu!¾Ïè…UÊj>±ÉbÉÕr &dÌ­J2…È€ðáv×xlQã[>Üÿ$ÞÛñÝ„waör?œs½:õX_U|‰-9: ¯–½`st—†ÞÍ”¸:vB :NFAh4dßtõ¸ƒ¨à]L´jE©*f`­MQa«íÌlå ÛÑXûtÜÍ’ ô-gá™Å2 J~ZW]GV`nO£2¦LÂÚhIÒ‚ò½ƒi`…RIN½x]ªN;ƒ;›·Ì¸ºuƒ^L€3‹h £r¥¨®ï<\4ìØS½…ØCJš¾œ1@u¹À*@Ôs™~6ŸÎà¸h4 ÄÇ#ØQì¨AÆœ<÷ÊO>~¸×²•Ÿ<žRfd f ¸b€ €'y,Ía5zå¯iÞ°À½©3k7—Ù·ÆäŸ¿z'‘µ cXïŸ{“ DŽ ·4ö&@”ÔÄeÆ+¥¾ô̰ÜXX,X%7k€`U‚Xž‘Àƒ-Å dÊàÁ£8åÞÆjtïÉ Ãã Ycèɧçcüð ›WjÊÁ(ÃDK§2¢`²ØÀbñÌzˆŸzovìòÕ\6ð eMÛî4IÝZñ\¼Ø*2(òe§S4GC"±YZæ™döö`”¬`ç§Y²=€1è}WžNŒö4%*Öh@­Z`T¤c5 S¤IÒK$0{Ó%wõH7*ˆ¤Í,²/¬´Çõqß‹Ôm¯\™Nw—Ü[Y—‡Â ŒŠzjÍûÒ¼vl5ÆpÜjQ¶Œ©îX@´Þ’ò»õU{é-ÿPA³3ÎKŸ?½ßTÝœ\nn7M…±À:ÑêgYS}cÊð6Õ’½_qÔH^5–ˆîà'{ pËÃãWv¾4¼qâwÚÎA’­EÜAÛÆœîBX}~z€Î~²®Î†Ÿ,GÍ·–‚‘Ä\ú ÐÛ÷DúèlˆíÕÉÒ-Qê¹Ãi3KÞÐQR4KÓ¡n+ ”02™‚6%ѯÕ`î=Ó±mÝ c”ÄŠï:@ç¨W3Ø© aööÎL`Øq7Êm@¸Ù4½aÐOGé[ºx„mœ¿Ó•‘`õíÛ=r«ï\•xÈÐØÁO¦»;c2¨Z|À{‚'‘•1¡Ò«cT •n™°/V)`L¥_œ6lzFÉC;kv§'+•ÀêÅð²Mb»Ùá8-ÚHž¾Â>×ÔªüX'—BÄ8EvscÝÏS,Ŀɽ=‘ºÑöQ]á2³/:…”ff.:üR_MYšÓ°_Küæè.þvvÊRI/'‚ ï…éB@|lŽmÞ,f—к݌‚áa^âÇ÷é+ðÝ$áƒC¨á⽃É>X‚' ª¢.Ýç§F;xó(ã«Q7ìb—zm EŽ¥Š7ãá Ñ·+[äƒÑð 'y"ïÎtØû›Zy@ý~bc·ÇSÏZ‘©¾±Cè!¥>Ov1#;êé°Hõ%Ç ¦¯f~yP‡7<Û÷Âo¥;ŒêUûç~1vô“Öf·¶Ý,±zSÚ¡Ï‘¸};Idýˆì½ÿ$“l0öàù`7Êäýå<Ô³¢,íq:ÏgàÞD¹ÞqÜWÖ¸¦UIýîäcý¢»ézDOõ2‰Íñ½ï¤÷nr-£ai)¦0x2\%Z¾|™#Ñ®,q7¼á«rʳvv]§‘££á<©±»±«íhÃîþ¢~°’tmûˆ ¨SÑ€L›o&‘VÍx?Þº ”œë``YPi¯ûL¿Ôú Àb/¡îedw8¶ ?ÕYóvh±H8™ù#qY^î²$)géâ5o„YK]:4DÜýPBb£š„Àš+"ËÍÈ÷Í¥$ÈŒ²âN¿‡õÂÀÁÊ!‘_B¥`ÆlÖÌÍ5’7D„mE5½ÂF5ù`á î¾Ùë+eP,&²3°kG–Ãô]?š-Ó’·+`b¢C®êV’"¹×Â$cE4­ƒV*ò—Q<=i<~’ÒXY;x5„±Û»%‡pzGÚ4ÙÁgKŽ‹ŠseŸÄ€2†4yMfÐÛ®f8Ø)Ÿi­·{awÛâh(óklù2;;¿[ °ûuÓ+@du6½Éë.w=ºç3 ó6tHs êÁ¢­yº'„åc]éydk¸×YkkH©ÒÈSÛRÛý•Š+¿”gpÙ #åã|›J©¹HÑUÞ^̉u7ÑÎp`K¥f´â!˜êÝdœñ-×HÅÃêL+2ƒÆþp;éSŠN’µ2Yuœme„Rv¾í_©‡$‡éq–RMÊ‚À^ª ¡Ðr¥ì¥:IÖ™¢$Ê$+©H•8Y(ŽÓ³~Tˆ$c–rN HÍÂF^<¼¬.ª-ezE4¨ÒÖ?©ý´íÍ`÷€îVë™]Šì^§Þ–úI’‡erÑߎÔ Ô·4^ƒ°¾vs³°TnJ ‡‹kVo'ÚŒŸÚçŤCF#âL¨’¹¦@ 25B§/õ…v$dóÁî‘;“ÕMµ3[‹˜`áck–{uF¡ýÜi)°\«¾H0È]熓.ªOžäîZŠ\a4ltTS õ¬~lœ(w+Ãy0Ù /{›ßmXRðÞn³3*.q"aè§Íùiª»ÍjTp÷èÕT)ný<…ˆzWZˆ"“%u齌,èV„Ѐ##?m ›‹ ìË AÌ ~‡Ìú†æŸVnà8wµÔH¡y {PÁ[mSJö `d«r»¬~¦¦àgª2´JíÅ<¬C$åÕ`'ÞÙ| &&1á½}ÿÓ~—tT™uâ²UfÚ6)+4«Mð 4wKæhýJíA“Í:U@åÍŒü¯°ÙYÎLÛ H½}=ÜÏÃ.U_fÿ{º·ˆ>00ÜÞl_«öÑ‚Z¼Ÿ2{¯9|Q4La½1ÿÆT!\Q*ZöÈ k‚®oÅŒÛÞjGF¡#YƒÕŒÃ+‘• h1Ó{¬~äÎÆ¨YJaÑIqk` +ÏdÃ&v?>´ •j4ìec©}`E€ò`ÿRº]‹‡w×Ajöài£0m×™ðÂì1A•¥Ü¥ †×@SK†}žD“…Ѭ K ÜñâbÖt)›©âÀt(#²×Ú—¢,’½ Ⱦ9ÅÄ ŽÛ§o„rÊÃ&‘.ð]ÃnqT÷¬¨S Èà v(Ë n„œ'-vEŒÊs„ó¹Ek›7`…RigJ ÷‹]Y÷6h7ŠªùC6ª=˜ö¨Ôܲ·˜ÇšhŒ{ãÐöÎRŠO Ô½{‘ És¸“á-*€Ÿ¥]¤{cˬ"íc#œwƒ)Òx/ë#BÖ+@0¾ƒˆÓ‹€©né1Y ¼ ªaX‚Øèê•Ò¼™¥Ê–ÌcC+²ÚAT͇<4-ŒëÕËþ %l;¡iRëÖ¡ÈÜUˆü@ÛèKDò€æzHÉëÂN˜º36€ä&€™F6ƒS¹ä12ª%÷h‰Bׯ‚‰ö°DU,†M1»iL/&ñ:Œ^Ÿž­AíÞ“2p6Û ´Éî%=›Pî…o×ñu4°0 ñVê»O{Cg`¹ ÔÕd÷‹;Msª1¦êŦ×3Œfí´vU¸ [ÖèV{Ïîôü$gÆbÁƒ¯XîŽ ÒV ˜<‘½{0$?Ь1##dÝhÕ_.5rZ»K@‰!Ìöi–¯ŒÐBÔ®’±U“Õ\Cñ¢xÓó óG4>¬Ó0C'ƒØÜ3`)9r{[`éÂì ½¶GóÖfjŒuߤЄz:Ù (G7ÔªiÔ%ÔÊ–ŒÍ³%9‚4^\½ˆ¡2úk»T²¾e/¬†ˆb ¹°Hó Ïð“:0‘½›rꬶA6w½áÞã6–]‰ ú˜"e¦~ØèQ«'äª#JçA²7`EÓÔW†Yz'—‰V_z.' ¤ èY¦o2PÍS•Öt²-†ÛÎÀvUH^¨‘—¨݉'áìmz½š‚$ßf–Y¨Ä"÷Îz…;­YûÀyv¨Ø{«#Wæ;…¢ÍéM…3ÑicƒM™™ÔÕ!½G÷ŒL‹V}ÎÝMç< ³p´)„)Å8×\¸”#5˜ÊUÝ ½›B¯ÓP|Z¼Ã@1z&Ù."+½ô˜iyýlm—ÇÍ>ì¥t4¼±ûcŃv¾Pÿ#,£©Wt+ñ‰Fç÷Òï|XÕä !¥)`Þiƒ¬Ý /Žröíh{þ´€êe$Ö åP×oÔ«9\ dŸ¯ëg¥èíÈ×][¨Ü˜èù´®ß MÅ›{, Í:¾µj¬1ų=øy´î®UL,΋Â>á¢éÕÜ/@~, ‚ “½òg•FÖ` ÖFñÑ %]>v½ÍŠ®RÓ‹ÅuéøQËNÕÄ–¬‡¾³»3#úíŒÝP>"Û:p{>¨Å‚èÙ¦Öoéf‡BŽlõ4Ùp2_ïçWY©Ó{:f½@b2ÝÅš*c:ÛÁkF$ãN£³U`HD7«XÁ[zƒzn—6%¸`JÃÅr,cÔ½¹™M½¨]b"¶™´Üo‰S@ÄGÚºL¬z)z‚'å³c¸sõéìÂ*%ˆbæ!`á‰êÌØD¢€2Á(Ð+€©ŽE à ‰¥¶ܽ&tÅ\ƒwžê»sÀ´°;’nëz1µvX™^¼¸E‹ lŸt7J¢ÑdÛ´ŽÆž*<fâ’ÂÒØavÐ@¬¼{ŸÑ®sÒMàk`áÂþ²ìy6MSâ2ŽAÒи^×¶`P§¨Å VÇr%ž%¯÷²FT…Vn™îëWáö ›+LÔ F©lM`â^Fž¼W)¸óàj.ÇHê]⪢ëP÷:îšânI‰ý¬ÑYN𞹕=;‘›JeXa¬-CÞ¹÷1vkHtÒ©”‡$oƒjÇDFÓ•5ÿ Të¸Ñ|¦ö" Ä–‘q³×¢Ø*ÇeŽ8úã齬2!·ê³ÜÕ¤¡Ÿg{ˆzQŽÝE›öžç†yÐ6{Co‹å>ÜÍ+Ùàèí1Læl‘:\÷’tr/”PCt–nÏ“Çë¢.é"£Çbˆ´<ÔÁóšSbso—‚6V—ŽI^“6£k^‡7PùÑ`´¨.7ò]d­êƒ2v'Î>? é `µ§¸q¯Û‘Ö:–;;æGˆ,ò°î¤–·lJz’g“ (ý+€GbdoH3Ü3ÐÎÅÖ.ö8î謊K:%s b§¶.@°b¡S[k xŽÓˆ>€s€àåè>Çk›®™o¬§ÄoõúTAã! \»Ñf£y;˜L"\nöª>Àžå B%‰^€L–F€èÈd¿‹»×|Zí—e}Ûäî:†5·äoñBš !íPÏ‚ØvÎi Ì+€7:OvžÛUƒÖ¸7ƒd¡י€ …DfÓTôÊ1FŽ$‰ å˜Ûæ `ïƒÚ¼_-LufU'Z5Qzœ·v§*àaUȬ Óp2-zûúÛ®wv1éâÅЃw9`%¿¯Þh±Uî‹^h¢xÀĶ´‚{f¢£ª× úP[" û6´ãµã8>¹wºv•&þ×+½ülËÞf%Âó¦@Š•{w'íé vço­6‰ä¦a9á&&KÞG£Òͺ6M5Zja›HD/±‡Ôf—ZÚÞû IdáPB²íðŒ°ë‰ˆ»œµ%ô±/žOž8$µùyö/Üâw‹‡vÞ»ÒK£eŽ7jËÓeÄîè¬È«DêÔ~©jÈÂnýAM² •tN[pÖ°.!µ£^âK Y´Tv¨¶#ÆÂ.€žÝR¼Mzvh0‡Ÿ®ƒP©‡—µ6»”ÝÝØ//9éñgåBO¢ããú`jít µTo¸´º2IJN©¼1¿£•ÃÃ6ñ±ÊS ƒLP7ñéÖ_¢®w Ûù—0r'¥Í(ú£RCÌ&ÅhJáX–\‚í&(6VuÓ¹AzlRm2ÎÌû„[_p“½ˆŽ]è¤=¤e˜µ`ø¸ 7µè%Âd•MVî<ö ¯æËݤ4 ÷Ýö…)¼Vþ’[°l¬!Ù`Ö©ÏîE[ñ:!^(ÚÀU%£–@%Ä»LµàmŸ¶2[YáÔöqØFáá¨l]׺Ú/&*J/`A+ÁnE¡_X³ÌByPmDêo1Ï’ « mkP¨Yêó¶9èˆ ­Ùõ‚q®î2]ñÁà° §ž|xpj>Д‰"æ5»1¢¡«zó©O6 ü®)òJSÐϰ«v…cµ´±BÌ™”±€iº7mø2ÀL$`‡¥IÜvd¬0¡˜:KéMÀ®|³à™TDê´ 0É¿VO èâcPêLð½ÂF&­‰i’uÁ”IƒY.q&{Âï–^Ò÷!éa—Ói–’l¯•š:j{²°’GyŸñˆrŽ2êIäB£naÿ|ÎÎÛ²wcÕ ^ŠaŸ/Žc`«güûÒakÑc˜*ÛÁZ)ÓLÚÀºÌZ‘(¯JÕÖÀä›­I7±@˜¡ÚpÔ-ÑÅÀÊ3ù°·æe ‚Å—ñó,?<_» åÁýùÏ®x:¥hj÷êTÑ‹x Ð}@)S «;ût«uçÆMvöÉÒâ8@J¬§@7E°Z1×VdcUfj¤C%üÚÜ_´«bÈ)vqÅLžV1ò“Õ)#ª–Ãèûc¿§µÅÞºËF×êùÉÜj8óƒC¤;¼ã-ŽäyÀõÂI™¼âY¡Ïk—›°‹à,Ý&@Y6âIy5’N†—$¯A^³—šÙAB¥½—êùá;,A-! ô^ˆé¾l z yìôÁN¬5YÖj1tð·•*ÀVÄÜÜKHâa-² #l÷=ÔBköùè}r¢å„à^äÝhò Ã{Ô7êÏßüzÀÓ-“BË.|,oéܪ"pÐY@æë-ÂR!1ÆX©’³µL-‡B$4Öⱥіӹe¢PW§zÉ#IÐÞ|³Rö¥‘Ô4oRV*-[m€ÎZŒ5ó 5yÍ¡p<Ëâŵ­¾`™@–ñÔFǵ^ËõÚl™ŘI"K[Xo Â1.s*áÈíýùn›b×ïÀlÞÃÀ¶Ì»4†ÚZxØ”B Ò㌤ ÚåÓVk‹ÔÃm(³ÑWNÙQì¢ò$¶˜GÆ/E&­Õ¥lpW²%:QÉÞ-c µÕÔ¾W€—ëQ °T¸‘M­Ð¢t¾1;@Áìü=-wÒ€}qé“óª¦AÐ~\ŠÌaSxðbTåEÊîp<[KfÛ¼âJa}}‰è&§À‰YÀ½zUÈlÝmÂèh[÷°ÓÌ(åçöë6«Wm¯;õ'µ3*©%Xqiˆ‰=šœJ?lXòbˆR'£Ôz jì^Ó“ùŸ^ÌÂÍH`d_™Áb”f‚¡³‹åú •C:é7«#É»fRžè û5Ñ+™=XHÖÊyPA“yW ÛHÎv‰ÜŠ|E°ÃÑ‹z`îsN^^ZV%0ä-{ÛYw¢¢æöc¶™R"óÚdº—Ϭ»¤Ët† ¢!• ÜçM¼T/˜qñõèµÏ¬öUª+Á³1 •‚Dòšê"i°–IÀƒÀ0 œ½p†R°,aŽË¦¯ÁKÓ—âu‘‚™ ˆVgòn­ìqÃÞHÙì]‚ǃÊ}™r€b?ž'­š<`@FÞ…ÍX -v8ãÀb?Ý4EAÇ*ì~Î(ߦh#ª#Á±ÒIÏXO‚FYÆ—Œêð—RNÉJ§±–6nòv•Û³W"êh˜Ï,;% ßEçëþÝpôþ—pŒj°¶ÏÆ­»>Q¤ÄC Kʤ%zœ¨™öùè}v  a¢Ó…ƒZžädB;r€èQ8t7–tt B¹(¬ë`,Àé”ÈÊ“r\R-Æsæ©é ÜæK v0÷WR@)® /"@3ÛuÊn½öõó3H¨©lqzÎ\“MÇÀ`£ÉÖnÀVÒÁ‡¨p~>x©IîwôVÑBb È,æx¨[=f6¾t©x—E‚1ï‚ÍÊà9–›-ÁKm ¡ûdy Þ{ 윦ίèE°=øqûòô¶ÉìQ¯žÛ{Õ›ƒ‰ýÑK{åéô/z§³L×+˜çQ˜sù&Oöt *çÏ‚YB¤±Èg èlÁ‚c0ÑRíˆcF|pÑ/OöO Áœ¤&š‡¶r’‡§ý Ïy0YV0o Á5’“íæap‹ È’B×ù޵–Ï'ªõ‡JµÝ­œú”¥u¾µ<ÜŠÌÈnÀm{dlc‚¤  7ôÏæ~teÃÉôù z;®Žf:© çö¸¯‰,ÇŒjB<_aדe‰'™­WÈ„`d•ý”©§Ë¾l ‘»ª…è†(Ùòìä.äÁnU*# îv>„¢ê! qj·XÉ»˜+Z«©!Ñì„¶XÛÁܼM»€‡Wx• ìW3 0™Lé`/!­d‚)NdëYaÁêɵ®ˆu=T¦§*6ØÐ¬œêv˜£í.OJ´ diãù!P1söÔ¸hiiüüŽ7Wg°½Xö±Á;_çÂaa—÷_w2X9œ‹}L!𢺓Tš¤lŠœÝv´/ådnÃ[—wÍèrKž¬„ \`,qžƒ'8FºLÓÀâÁ¦™vÚ¡Ônð{Scle¤4<3š•§Ý*!# 0G÷ÓîdFh<øÓ8Ȫ]S?Ôw.à®i—Ä ‡0ÀÔ<º$š÷Ý€»Ât€©5Ip?Å©êBôÍŒØ8ÆØþÔÝå%ìûÁ ˆb÷Z‚ÃA&Ë}Þv‚ž†§Þ¸Â‘¤¨’?¼ìõ÷ìˆÝã\·…žÖ5tD à‹,töTŠr mt: 9A(3,4®˜† †®‰'X>ïù†¬%/¹P‡=¥\Љ?©{4s231_ŸòFbYâÿž¦ø´¸@ïMÉR ü `Ò†dÖTOæ ©£ô@A‰­ì*~j^^ ܘZõb(Ñ Nè½)PÆôßÕÓNƒ sIr# e 7,pÙ¢—+UoR¹{I0’k!6>Ë’ ²{;µ^홋;=§JëÄòùÃE<æ7¤íÊŽÕÝlÈGæç϶ uPz+˜%”ªkJö°pUrJœªWNò*@çh“ c*f`7l"3÷–QóBÅÝ@»BÞ3t-™ ÈŽ5ÌIÊFšŠ»È2ö‰mïD]U;t!Êìô¨ùåæªMù'µk̦ì§h÷K›oE¯Ó|xƒc´f*^‹ã@LŠåûÚÙ€vgt•¨õÝs‡âp<ø…S9UØ9^Ç%£×(¸Ï5â–oÅl—üKå óRN—lä^ Þy˜GMmX:jøu2Sñ’òÁ Ø*FjÃMHö,2¦a¥ä…¢“égÚ>øðåxY¤Cªýƒ¡%—Ò!²>%/t›¬tæ}ø²Æ”â¶SÚm4â¸F8¼˜ÃÉ»r§xÈv¼Ó¦ $“®ñJ³ O)¦)ÀÊ$KöÚNÁ ¥CöL ¥œX­;ÅCÏ×äóiÝn—wú_­Pˆ™[¼Înœ^Ú)[ÑE@À°{d7·i™ÏøG4ós]^ Ü 6g˜ŠÞÛL€ =l,Y7« ØœpÛêÕêP–.Uwî«i¼ø¸Ùk1åÛªB…®F&ÂL,ÝS£SsÊw,+ššËsÜ&Œ(¯4<«UEùà•>ëf¥“‡—"óži‹yWþr?–®#‹$2“\¸W<ÈtfvÃ#2êìR@ _Ë}7,žÂܬ£s-5S>TZGOM>(oÅ'kš#çÈË”…Ž·ÚaæÝ„|¾@òè”,Xªï– ÙS#†Yî‰ »š¹–NO\+æ>¥èR?TëOÑ#ø/Žì±,¨¯kp¦&•·{ŠQ²è‡Ú×­’æBtf@¤èJN7!'EOËØíÅŠhZ¥—SbñÐ9L&³<¤Æèì†f¬2¦'„`v‰Øå¥UNð"¬-³Ò¡žÇ§EÆ0ÊûÆ]v [A Pã]¿®8giÝrÛñ°VHK§DNËä’±«šÊ{yUS¬¬|¼²÷3Ú =mÇ㵋·c,WS4‰©bô.¢¨äç;€Ñ:?­°€½Ð5€çbðQÙMViœÞôI%>öM§e&%/ï;ô ]cmÈøÙеnjìýµíK§g§ïÁ‘Þ#%vw–Bhž€‘Ò¡ ãte®&GYr¦ÀèazïD³^6E9Ø»›g´¼H^|KÛú–-H3¸oºñRˆFaÛ¹îæìløV=dPð­ñ>‚Ûä6ö¨ÙEf¬¬và‰áIkœM,"¨“É–7p j Ö¸[$¬°•B.­²8.oo ¥Ó°„ gVž"ï½zæìÙÕÍ&ÅkQî&õ2Ô ™Û”'†SkŽf¿]EFLö¹:WßìÆ×[&¾N7Öm )‘k`®ˆäÞïݪŠÅ Ð° „Çp’uV@KØñ¦¥cÛç+]œ1ìæT•!»q +%š"Bl€F #^ľuÚ¼âÎ×cr6”(®÷ȪŠe×& àɨrZݦ+ªP g$ -¼9x·÷d$oÝ%Ї+žö:ÔHބ˶Ț71+Q!pT–ׇiUL§·¿Ð€{.xš™Qø4*ÏC,±Ü."øÔc›MÏÃJì#|ix~[bt¿ì‚è„ÌdH>‡ÉRS5±£ƒœz&ªDºå"Rë ˆ˜[9t^þRòGY"BÖžÞi Ì«“zo¸ H(éÑ’´x¿¦$ï¡v}Zɵ Ôµ*3 ³ù¡Vz:H&¡Ò¤ü<;¦O3àÚÊ”ƒ…J;²ã";atãyÚo’û°- žìÍâ:öêUµàúN±,½cë¡*YªælÞX³GÆeã™»e±ú‹¹`ÂX+ÀF]Ksä ÈF¾ÃòDÎ`·Ý¬ipöU¨×­@*¬ã eIº§³!ßÕ]‘b$sr§;1%3Õ·<û³Ð[SøuJÌïb®ç±Ö“,ZÙnj­ƒRô¢k·6¼çìÍϵESç¢VO!ôŽÊA23±*üϽ2[@©ôqWwP ê"ÔYÒ%ÐÒ7mûˆ‹7˜ÃN%bËë-°áR<ÄVj™ ’?è Íkc‹¾é ¼åA^ÔÖÈ9‚±P jP‡É°{´ÄøïLò³c2dgуTûû&ž98ºžkð ð nÂè—æÞFU 4oC½5®†µË–ÕùЕ™‘sLTÂsínNé»pOf¶æ‰5- ÂÉ:0™ÑN²0‘ëæ ”1xú|KŒUÝ&²$‚vi’j™a=zd+6äN"½!ÿ/oo»kÉ’‡=Á}‡þ#€4Ü£ÊïLéÙömÈA™„!ƒ&)ÑÀã!½½w¬±²Nï¬KÁº4ô¬©“»*++s}DÄ‚ìDÕfp:“—YrEŠ.“ûûT2q™ðÿc‹êáŽÙ©DU“ª6(é ÓëÊd,q{ÔºZ5q¥Ž¤RT#½p¹Z¨ÓvÒî?u9Œ\b;šzˆÛâ¨!o3"Ïe=xcf8áÉ·…PïØ_(“ˆ¥ÃK1æØÚCK®z¡;\kT_ )tŽ…¥!ö+•¢@íG¸…sèãæ*‹ÆÐû-å+$S瘝놭éãVPÇOüXl±8Çï´—lU¬ûñiÉÝï4Sm8íß&ÇïS¢A“jžIˆ9±º¥Y®» œ/_Ã![4%?œ²éëï_~+/VFž¨Ù‹OoÆpbúp]s·¾~-©Ø'!é¾n~«¶³ÏMx‹Øy7YÞyž±›VtGdºQýäú]·n)æ¶ÔïáÜÖÕóŠn =ïã îp.­»cÙVUôn„d5t£Õѧ÷U¢¡ŽW”øûþ.VD±ÍI;ºI7/3Ôðj%œ@¤EÈæ±}ð =YL ɶ…´¯Û= Ò2R”ÔØ”X¯E.~» ˆA¯˜ôޏ ÌaUK ©ŠÁÈžJÍé¿ß8€€Ž-Ñ‘B m/iœz¯†Žõ2ÕÂ{ëP¼wh–YÀÌÝ5Ítˆ£ñeŽŸû©ƒ­õÞõÖ>Kmsÿ¹E`õíš÷® tc’±³ ¡®åqe¬¥ÛŸ÷uyÛÝ~ÅâR[÷Ý–ºF3ž£'Žïpqvg— Þ6§T=šM›“¿•Ô¼Ky p©ÉT¾$pÈ¢“®áa%Œµ¢YìÌ›ÕÕl¾ßû3[ksÝWÏê,¯ìP¿ä(bÿêW€ë­Ý ¤­záµê´Ñ7í®ôOË"Õ±ߎΎ߈"¢]þÅŽ8v‹Eu©¶€§jn‰tz»,2övn›8Õ½výÑ”5*¯h‘WXl2a3˜ú·ó¸ßo+{Þš9WêCfÚäÛÌèÙÔÍÃô\›öÉí$CÑ­ëRvv4éU…´X~YОߌ‚~‹MÈÄú= Á?Ý<ûx÷=B¹|Èe¨ÚÓ¶®fM¼Gâ~DQËnÉHô$€î%Ë8³¯¯ˆ¯­Õyº’ú~cºã{Éô‘?hï•Õ.ý¿ !I3–è·Ö]ÄAÄŒ’fÄ0ãy¥a`:}9Íð²€sú ²BEQöµèïv!$"Ù´¿î(>l|nJ[hÍ—ƒ¢ƒHEé±ìÖæ[êPu”q—E¬Á̺?N¦¹ƒùYæá±RÄŒü|fha`êþÏßÅ=ýôoß6êâCÓ`õß™£‘¹’v0’ ·[»‚¼R…OܳþÅTÞŒ1”ÆYgÚýào ’¾‰:ë§4ލÊÅ»‹ªZYäÝh±{jÛ’­AÓ™€H,‡¤¹Y¸Ç ž¾i +š¡wÏÄ©â}x–Zx‚$t êFïS{;¸K ™Ü橇šõY5ßidËD#Yþ]¹uº£2¿’)wb^Fô¦¼ ¨#&5E#Ý ÿFÆú­Wòn„K#³œ¢I‡Z¦ZõHAµí˜>5Á(¬Z§âÂõðf8ý/#¯ÚÍØ@1ä–=K !à|:'ÞÌTà¦FÞw¯mÊ’ßiLÑõVÏÒ(Èáý›} .5,Ãñ ß~‘Y¿+êÍ5Îu)”­‘ŒöªúóÍ ê¸C{tXJ»ë%ÈóeÓZZ0/ÀZÌrk%?XŠðGöyÇ´”`Š ×-Uy^tÙá©B7æ•"l[‚9Œèݼ± 9^û[.º¶Ï%4'…ðSL( ¯Îh€x iת†oH " æSøƒg`%šxm‚¯Æ×ðƒÊ «I»¤[¦âöcWWóz±ùpå^Åó†UYä’Í •tk/×Õ®Ô¤h_ƒqãƒU§Y-N n+:Ú[ÞHˆåØo’¦%…ÖHúGI!>׃½y›d®´%“I ×Õϼ’‚·ÕC¢ ;´g™‚ëp]Z¢j]†Y(ê+-‹².ÚMJwÀ¯™Sî6)´Ðv)÷î±[}æ8rp¼d‘W‡EÄ3­WÂÍ[ô5ófXVÀW¬ú¹5¯OñãHqOÑ" ßWÕI`Œ}‹®²êD yò lFÆû C®Öá>‘š…Êl¡žß¶ð‚Ü*½­ÂÚ_¸»ó;äê·Œ”±jl–’›·¤‡“ºùÝËd*óרlJ˱Îïbx ˜ ÑS)ïdüÐ7³EöA Ö>¸Ú™CZk„Ï1|)i\ŨsWßêTûš!ÿ1cO™[êi3ûçÍ+¬óþ­®Û·/N=ôÍ–2oæ¬~ã|ˉÞTÌwUU¬b®@:¨˜‚kWçµÛª†_W×#l,R4xÄ¥\+à‡x¬# õŒ+ίÏ»Áýµ÷ÌÕqÚs;ƒÛBw­Gau·îð…¤ò«Dx¹Kè—`Œ æî¶ ³ƒÒ?evëÐù˜nJ`#ø+Ò-µ‡£ºnÁ™/å¦ê!ñ°á[öSj^zЬbé}'Üën…·ס6Ÿ`¿øòâ·¬ìF&‘…Ðl5v€_ž€ùñ˧I¼¶Â;VÇÐM…¼Ì ºÃt”‹n`—ÅvO“›jׯÔûÁôz=Y ÜŽW+QÐ!$-f;ëÔ–› )°KP ÛÄôªëÕ=#vRqÌ{€ µ¡Sêê‚LHk©gÝŒƒØ­,PdžÖ9B2â¥`Õ»²šÒé΋¼´göMúhD»sÇmg¢Šs×£ÙÞ!³üÍqׯJ-B¹y Ø&Ĥ¥¦Š[AèáCľ,œÝXå<Œ(Cˆ+Ò¸!µVnPÄØÔ€ƒÑ[‘ή›I0‚PKèñL©h×%šÞŒH¯ˆÀ¦póÉÑ*˨ÓqxíÔ?‘=ºÇ•~­ê$=ZçÕ0¼~÷’¶–™ê¤fNS™*º '†¿ðÂMÈí·zÅfݽo/­Jê†Lœun‰|w©1Àvù/ ^yi”«J©-Ñ>7+¹¬àvwwil2Š×] øÆŸÊ!…³ÄdÀ}ðWVHÄ p\ù¹± Œj•‡£Í»lñ’î΃wúÃ`y@B=Šáe§üAˆl‚ÃJý¤Ý’í7èló²”tžfÔeä4àa»x¾bîÖÝž½9;RoFÒCÍ×¹0®£(±­²5TØïiÑAº¦ ÏÔßm-ËœÁñDËø%ÕßI|4GpSoMÐjfû/N(OP·]­S€vIÞV?˜ÂÌ"Rõm‘%t±[!ìǺEô ÍÁ¡¹Ù ‘̼¢7´¯²òj/xk+zºÇçTo!’¢mˆ1öj©±Ó}åêÜmývRý¿Á˜oÊÿŸ¸ßZ4£—$3yÑU$½ÖBöµ›è‰ÍÁºûöÒh”HN‹n˜¸–)u4X ñÈÅc½ÁÒp¿#®vhHp‰ÕKÏ¥ŽHõÆ»«õFG÷B>‚*—ÕÉnÌÜéª;šò¡«7J ¦¸ò+ýLê×Ê NRRI*K¿sÅù\]?ÊHK·zõœ!ÚX¼/¥ÜV·ï¸B6¦úö§Ð@$ÙŪî}víöÝ‹·Õµ®âé[*[;ùr 8þêaZÚ9šv¤œµ:›I¨â2rÈZVi ÍÆ÷ÐU1m´™Þ4ïxŸ4y .™æk»…K»Eæ¶"ü†›Üßú—¨‚}72fAÆ/À¯-ä(Ûï‚Ó–Kån#r„ y?ʯ:s¬Q¸†•èW¿µG kíêÑòKޱ!›­ Q.C „ÑÕ¢»rë·ªÒî/tkŸÒ\XЯUmD¢µ \ß‹hh‘Ű.$ˆ¶žŸhhþ1·3¥T®½ä h;Â#4e—>B¤³ß$ÚQ ?UúŽ€¨r‡Âµì1oØ å »¨šþ$­Ã ‰ žòHV‚šÃ9Ó1@–÷ó…TÅTNTKkÆËfË psŸõáÍ jÂ)'Eî-àþy€îk7*‡¼7mF?ê~“ h+dn+nE“êí:µÇ8ëö Ó›é!+ cÔ7ÅІQéêMi+ÒÕÝo0`Âñ\ò‘Êΰ i}¯[\c¹»@rô»²‡FSr ¦„žVܤÆ-߬Ï/#1Ûþtc;µ#² æCüÿ 4¬h9­9NLWU¼sk¯#…‘h{[³óÞm—õS·n#Zzà‚HáÆ2 xÕïïeУ|J¶E‚Oc¶8ïjتŠgJî· ˆ`ë¦ÞĸwÒ©ŸjCô]’3%¿2]‘WP†œ¹`ìÔrH]iÑÏ*T8ì´Õ5 =a%uq'Ô读—Ì-L™m¹£Õ–ŸS=M~:Ön¥ÛÞoM@Œññ!sH ¤[ôg‰V£[v-véî´ØË[”›1ÔYÍøí|[@uü¥Ê'D –Ð6ög4K]«Þ5˜ê”˥ƒP±`ªÞâ0˜kĬÐ@…ârú8«ïw@/"­[ÿIwÖ eÒź‰BWj1¿}Ž%o ¥Ù£]ôB¶\øÛ¯}»H—BF<òÛ˜áJŒ€¨Cü#iߊ {[3Ðç7 ®ÙT.+Í(¹"-’¥’•²¾½Õtf¦é¢¡Õrt t1h“*JªM¦„›y«œ§пá8 ÿ±­ TFš‚ý†jпŒÈ§W$) žša)"-O-ȼS³æ(|?Í’w*—«ÂH¥|ÅÜÃ%AÿZ#AžŽ©ü÷­ª—ÇVn¼ÉQg/~ºA¯Èéx5G&î†CŸýnæ¯Ëáà0¦[7 –NÃröQô/êÀe Ÿš¯!sî—Êñ£¨S•¨FÉ–’àî¨RlÛ[BÂÔî.qšS °{ä½ßØ÷¸cÇû¹¬tKqÇâö]¡¤gjÓ‹;Ÿ}6n¼è |ªñ7Þè"³wš» èlÆi£&ï7¦;Cr)C?µ«£tXƒ¯¥qud%ßÇààH ÝâÔtì’»v:«ùLßσèÖW€—.ÿ môgóOƒì‰a'p#¥#&7µ{%@°B$›ñ}½Pô‰MŸ<-”>7W0 "KúR‹Ì ²[ïaí§aù)Õ|kºaÜšGÖ¬!X +‘µ²n檯–Öù~[9£•Äreíe0³Øj"“ƒ§OøÔîS–RzéÞ|ô<À âÏnÝù~š‚ÏD™ð¤[ƒ9‚Úèqs—B³ò7§I…©uI„`С°¶×Ký$~ºòÎR‹·;S«‹¾»[½%ù£&rE޹FEÂp7Õ9}ýú­½ü‘µÙ§aÝ¢»Ý)DÑüe…‚÷,ë#˜èWdÊ"„!úy¾; [•ÀgC.MH@²v&ë ¼%àskè!ãi­íEÌûŠ€3ÚCý4µ=¡4Ók#Lm5ö:˜-†@V—½ˆA‘¶Þ&6Z(J½òÞ)7±û€w^epwÑÈÎÄÊ­™ø7›‚5¿²á ÄæûèÑÞFþ Yug0ÒÚî`sëy|±«¡w«Ô‹BìfV^å",Ä[G³ÓéáÙôfÄÑQööÐDD´'Ê¡¶c­ç¿Ÿùït±mͼ}â`Ï'õÜv¯eêK˜1+W©n¼Öñ ý7ýyd wPk M”âûïÿˆ72CUÕz#‘¿ Õ‹ " !ŠMh7(®¬¢·e/Yò«Æô>þüN·Þ\_h9)ݪ8úÖ+¹Š~ym>!ŒÑ[twük÷®S’ìAÖ¢FÃjéó~º5P4¥ãºÁM)6”fðwZÕ»¶yÅüûqˆïñ6˜>DzBJZoƒ(À­BÕR°Â¯ÝýõЬüòhö[ÜEUð’Ùwô¨.íV ØŠtrtt‰Ô™‰U¿UUQƒ‘÷Ø“öÓÀš5ï{çzt±)¥Á¨lo:&âe§ E·¤vµ)š4 0]!|z°¿gnHÀ”áË¥œºònÖj›Æ€PhóÇâ7H ÀǪïâítgåöÄBhÏPR•nÓw^½·žB)'kN+·©ìöìÞ Þ5tB¦%d€StýiêNæB)´P¦Ô¿z`ßow—ÜA²½kè9únV:oýapµaÃ`6¥L™ËZÜÌ›Ežœõ–…AúéǾÅ]ìãÓ.ùøõŸk銫ƒ¦–ê3§ïãêõµ ñDZ|Ð,Pàp„ªå/Žèë†\d„¦Ç£À{ë€?ö¹Šs¼ÍE&YÛÚ&‘&RŸ+–x»Ç,škæÍ™9*äïƒè}#UYßÎ:c³$¾Áx€N2t2Y©'Øûìê9Žóý<¶~4ZQ'Jç둤w™?Ó“pE¦#0hó&z!òMS¥3âüÚ&¡Šð›™¶R"n Åjpï·Ëç‹Ho]U¸E½bk{çnÚX·Ë’‹ùg{+Ñ æ¥DOŒ•ñ>½Œ%zwm­ß1ɱ.­KoiLòà-ÇÀ*™ 1yp6R]Æ’¾¡õ…ÔcLv3õ¼Œ“mƼußRc˜1ƒÓx9ÈW:±U)Æ Ž1ˆnôŠžOFŽI°ˆ=›ŒÁ•½….›×wÌ)¶¬¨&n&JÎÌÓ}<Ù‚x»wª…¦ßT çd%_q‡ß× ­dV×çˆý}7KŸã¶ï¤hy3‡ dì®§0v¦ ¢3±­ã“µñš#šl]¡¢2Ç-*‡·uk¸,J Ì32TÂÑMm#戺®õ˜×=Ô¨äÆ-Ÿ믳12°MRʰ°võ¤Íb¶PسáºQJf ¦:Ý07õÖ9¹1ѼIÍEÈõÖnëüÌ ®J.°¤qÓTŸ¨îîá,·~Á¢ä³H² ·È ˜ó§†ÃßµB‹özAß&*ë¨æœ3 ûº5 Á7Ò¢p`f 4-d ƒ3S€Ø¡&}:û`Q!ÆèV/⊚y QÜÖˆž}yïŠ (~¯}¦F«^­û±Øa(:zýúnïçà‡¶Ë¦´®’\8ÆÄ\H#JÆwÝD»Víø„±QÓýÇNâ¿çfáÔR?·2oía­¶ÜAiï9ùš‘=¯Þ‡ÕT ¹Ðé”X‡,ŸŠ~;¦„ø=¤}Ër¼ðËØûŒL‹ö†ÑÙ‰Ã7HI¬Â<µù³ì=:™ÛžËaŒîÏ‘~{¿[¹|Ív¨ÔO!g|ˆlt®@™¹òt²??Ū:Õ¸ØÔ†Ð~‹ Ç·Ûú·«ky£-ݯº£RÊ7‰P8Ë!Óü>Èö·v¥ñbäÿJ¥b:)ž~¢°.Ô¶x=þȹnRéMµÍµ Š%Œ¹ˆœ±§ÎðBBðn¬².êwÛþ3G ³Õ˜ÝL"íºÂM^â‡ÀVu»Ì¡Á\H;ñ9S¾dUGÖ1hwŒÀ*Tó–ðîȬz¯ªf…¸«H¹ÍÌ~ (û%®†EõÕµÛz\ž¤ð¿Ïžÿ­hìq]AN]ùSOc‰,c‘N5j7´èwŽë {=CìG\m¨¾¼–‚)µ ÝÎe²Óœ°Ýw]·7<çÔm ¾$îŒ}JlþJÁ:»¸v3˜+«§Šw›TkUao®`Ä\Î*:~|–‘"œîÃÕ€ÜÜNà»ÌC@,#Ü}…½Ûái\n–MŸ¶+7x¬Q^¡FnÃÛxǺÝÇùöÔ?ì¶XðƒØ“€†™åÐÔ,ÐøûÍi_„AÛÀòAó¢‡û”ù €!$sÝ;oœž: -ê4….mÖÒ±´£^ÖwB,u 7o™?FŸ+ا–íÔ—8†»÷ÓƒL®tÆ*5Z¹¢¡µ ÍCöë†jzdþÓ0]úZûu»9ðÌI–9Dq”Õ‚GzpN7í·Ñ™Tóû[t™^fgEÜ’\«³S§ÇüX;)îf¬ò˜Þ‡Ý-ÂÊusyV»ùÜWt: ãf |OvwãeT®+”§ßî[ÜÇOó¬ûpª¥-*ÖÀ8U(\ÆÓ>¾ÿÓƒ^ëß3:"O&y§˜†r»'ËöavRŠi÷ªÙ*ƈ‚ŒAø¿‡ÖOõÜ3¡Y¹_³Þà"-•fè9ÝÚ) ~z™¥«íªi 2†°T†7AXǸ¿ß<$Š*¼þ♚%ZŸ£:«§f$™€ì–-æ1›èÊÓd“£—±F+œ¾–ŒW¨Ko#˜©Ïœ£ðÚFeVÇ“7P£¥‚Ýiã¥×à!U¥©áOå´ªZX&SÄh1À.F°]–›úmJ¿þj¨*”ö.‹yQ½ó.ž›B¾wöP‚NÒGÖ†M©²¥ÿdsmèâ{©þ^÷_<ÌwÍåRBùü}heTÕ ûjÑöì“PC3 i¶”"EPÓ5i´bQL-×g±„ƒ²PÝïûítg+ŠÛˆëöê[R[Fºy3”E˜–ªVk°áç *Û{~§y·±f÷$Z–Ù úýÆâŽyéüøõßJ¡'ºí\Ëß´—OCÞ&fm ! ažbÈHöy®[·H+Ð=<Í<ÜGÈ®™±uê»ÿûh÷'þÚb±2G.U褗QéIbä×™]YÞ×÷p¨OÇǸœ½ßÜÑ®–ZðRJ¢7:nfc&ÑÍWàOhÆ}´ñ0*-ívè_Ô JN[ur8 ‰F©hn$µjjŠß®~c6jèY6ét?ö­}Y·ÆÖfÈ?äyÅòñ@äeÜJTò[Cn1òÉa¸f¾iÀ%•Y‰éyÌ´Š0sž‰¿ÿå¯~Y_þìÏ¿üõÿùð¯ñÿËüÿóþö/ÿøÿÏúßÿ§?ýÝÿàÆ¿ü»ÿøødþ³¿úÃ~ÿñwû¥ÿù/×—¿xý÷¯ÿË/ÿøúÏõ%}¹ì?ý__ÿã}ýãÿ~™þË—úåûòýûëËßâÚûË×1_.„vÈGY3Åפ¾œJ¿¾°~ÿlÙãáx0ǰ{û7¿@†-žÍ-€kYööÚÝ­Å8@¼ýßÛïZ5µáØÈâƒf;;Ülªâcvéµ|Ìhé#7Ö:yåë-\5³æ}€ÞùSž•µZH©˜±e÷#Ìl*Íf;rcf4wüøX ÿâ?üË¿øãŸþ§øñ§øÏøýÿë—õ2ý™E˯3õÏ¿üËÿãOü‡?üÇ/ö—ù?~üãÇ¿ýÏú=.ýó/ÿãëÂýú¯=„uÇë|¶â˜)3¿>¨I3vj·-=œ‰Ú˜í65<¡ÝŒ×àæ qy3îÇHÀ-Ð×ÊŸÍ£0ÿû׋»´¼â[Ò ?Ýÿo87ÐñÒ )£sjò펽øhÆòòy©Äf´Rª]½ÙÍû–½šæ£B5•ƤQ?ßÀoúÞ-™â«Q€Þû¸ôŽ=t#Pž~i¿M~Íø|ÀžüÙh«×ßð¨ï¶Ó[70(?¨Ì+'øön3ÄãóÄâÚ«ë%ä®›ù£|"ƒýžžþÿ™5WÔÌ£jb­¹°Ùæ^å8.̶ ªoOÓ0 êóüʟכ¨ý3?ŠÖÃöuÈöåø ,3eV Fi̶æååe7šdÆÒ]Ý2 ž.4óËês§íø­^ý‹ª[¡Ñ 3›–µ™=Ñù26Mä¼öþÞ¼ _G‡¶ò®1‰B†–1}Ôµ8*ö³Üi,ÞMÎÆµ¯ÅÌÆß·»2mV³µÂ¿Ï øâÑú[keú ˜ŠÏšÚµt>ä×FÃiíR¾Ìóå¦äB3ÒÖnä–ãJ•ÆŒ8Îg¥¹@†™÷ï¿üq\×j¶<—“{ý,B…Íl6éqú°À.µ80.¾-ÈDTMÀç5ô›-O8sèûŸ)zà/'÷f¤°Üf-Ñ^6¥^Oþ7v)r]{»57ã˜ýóg6ÄAéÍY‡:ò­q\«N›ÑT¡Ìøúv' DT3Ö~éE€æàôàò»‘³KX¸ô´jXf×fîw(D¦ÁÇ­p»ÍØ/ÞVöøÃ¯$SÃÌ.5‹h,Ú©V-õËq¾ÓwiËÐç|\3¿ücί1RÝhê¼nœqsO×Vá´»Æyá›™1=Ãw×ÝìÔ åj°t¹ÅmùVq÷w§ó©4€¾ª—¹ ’çã `Œ«Óü†[9”‹.Žmû€ïåX O——–j*Å1lsCê Pe_’Ž`usi‹ÇëÕf¬=ÇôŽNcïZ§µ¶=·}üòn\1€7O{‹ë…»ñÊÜI‘è¡—j2º¶#KíFÍ™qµÊg¼íe®^.áµ¾k%kľôcW§1·¢ÛÊ\!nnaž+®SŸðµ+v¡<ý0y™_næ fÝÁ+äÝ–µï`ÄÂ¥Xßm×.ä$9®®k‡{W˜ÞÓ¯ÕÏ_¥òÍ8êŇK;Hßuþùz5mmèÒâÆÖ:ðB Ç+ Ö*ôÆâf^S¼Ž;]íö?Âö»\¯ò“5ã¥Y5Yû}ߌwÐb²LÓUϵÆOËðy\± ×ÔÑSº/Ãz[Çlƒè÷¥õÂÝÁײbðËØ‘ñÒpÉŸJÝoŸ n´2%àKé¾íSì08¦Äû„TMåÓ»*‡;¿‹€f¶Æßn¶Öâf4­7ZÔŒVq§[or<ù6.M®¼ÅÎ4æ5nžq À#ßxÙ0M×(äM­&cÓÁf‚ÿ9Ö³fv\œ-´€*ôLZÖæœÑßîê0šnÝkÞÙ…éC¹±m¯©ë²•5ùc³šÓ£‘öüÇP±ÿw¼v¡žÎî›KFbêÒö6=dȆ³«o?–üŠ}Tù¨3®ŒSq[ÈјqÉm9¯‹náë-VN͎ǺÙtés±%ûã—‡Kc>ÿþá^Oõ8šYti÷K3V´Û¥nÜN ûßg?­ÌldL:"Å3 'ó Ia´f~³7eðJÝÉI©1€áìigµ8)“æ/!!ÐÕZµÅRܘ·.6£‰:ùwQÂÃê£(‘C”¡qcƒ.^öB½ç‡FU¨ò õ•Ç(SOÀ­fžÓ7\ëN½ø[׎ xºa²(Ämfže“Z7š¸†åù\žsciʺ&×9€KŒ›‘;«Í ³.K;+òKKn–+¾Ó,7Çš¬úÄ^ÃÁØco³Åuij.å¸mʼժlÚôÈFœ.?~y¼öaÔ‡;8Þíñ¹Žs@8²¿råó»#¾¸%íÍh§â7æþ˜,ÇÃËèþûŠÔ$šõ•í—íÇ.æ$ª‘w°D‘šðÕ²šƒéaÀÒݼ1ï‡lFùöD¥ºQ…åŠñ@îör¡0Ÿ˜+R}‘žJ¤ÿÖK P›.³ðÖYÇÏ3¤{ù°)ñ§®Ö{L¢!ùd—&¼e#FyÍì¿ãµå’S#7a§{ á=~m¾wæl)Ç6Mƒ8¦kx€{íl@ cìÂWsÐSFåo~³lMª.TÍØ‹™MÛØŠRùŠ@»²Ü8£v†ì} O險#çè¨W+0SŠ“ÍcT ½+V”ucNáÇôØ„z„¿Íôü†…ðùßQ­wˆ,U™#ØŸÝ àÛõÞUéŽ?}0Ûßÿw„òwšô:àä½¶1ÿů;³ºí Ä%ÀðÒÃswXÞËpèCÖai”&ˆ“Y–àFñ¤q¦$¿=2XY>€Õð6/#€#–¾l&D=i¤‹cÉLŠB¯›—Ò(¾#bsó]»»‘•igï‡næîsÛLøÕov)“)/`dˆÁÚISå[`ÅöëFÔÎËXp¢ØùÚ†«›À˜TÙ‚q9 àeFn7:"îe*Žêy)êíÆî[ ´}™T.&u…©îð †åMÏv$Óªnd]ÂŒ‚Ĺ¹/à^‡ÙÜsï×¾'@,þîé–ÕF‚ióº=§ªoú2fö†u!°UÑáÿd€Î¾×wÔšýú^\v`¾Œme7fW‚2co—z.óß{Qô9LËV‹µõjˆIb™ï‹h´M3³Ð‹kýÈhRÍÇèvRÀÆL$îjLNa™Óo :-ί}…øØé;RŠVוæÄ½Œ&áo´0»Ô&F c™±òT»ä•iðX‚Ùdoì,Ìt#×5Zyr Uk×Ýh.‹x­NΖ#ª}€Ë\!ëËl–ýT¶Xåõfû{z2=»Î¹?‚ Ø çagϵÌu}kï3æ C9ÄÌ®`ÆRÌèÉO|7Ú*±Å9–æšíCK!ËÃH#§x‚zùŽc †z<±ƒÍüŠñ4ßLæAEÙ«»fôäT”‘]ÒV­6só(w0’o“=UÌÈ"Êm?@7< 6wcð¬, @îØS;¾\ýëî¡ iæî1xƒ&(ÊFCF™Õ7=ñ2šË¥¬žiæº8[¨ªh€Ò|+Gת+#³ ëšÙÙ{fdÙÛQÖâ罦m:ø©2[ `ŸoÛÆbóÆä¸jq/·¢‚00µ™þiÛ°½¸Å¼nʼnüJ3Û}Ûëzy¬×N«°CÁ×^—ùæ¾4W|‰À®W®îáÉ<ÿ±Äí4¾45O¼2µ^öø)‡q=ÑoÓÕ–öcG¢Àh3çF•ãÑ„gMîòËÃP3N_[‹¼\7:È >öBrÃÜ:øÉi\ø<Ë·óå¿A‡Àiè¡S«>DëÚéçßáò7äFC4šñ¹ÄDÐ[„2fÌûÞ¸‘Ît»Pìôóø·‚R]È—–õ²“—û&ŒYûy8NoZq<º-mo¦Z|ZÑÒ Å¶uœ_NíõA=Æ€“`Å_ð{3.—Ž.)£qTAÝÏâWP.En¼Šî?ÅÇQ~á¡.CÇl‰Eásl:r*^Þ‡Ìјû‘}+šÀ¸ªÁ2™>@õ—äOÖŒˆ†ÄKw«‰)'IIïðöÉ-ôdè(š±hX&ÛÝÒ”n«ˆ.Ðk»œK+îÎv7ÆmM{L+VÑPš«åtX¯aóu¬Wx[Éw¸ì±¦æ€„ú<;`óuù)SˆŽ´—àu¨—Í^²Vaòƒ—.ÿèÑa5é-2EƒeЧ{°Ù»Wÿ cÊ„2$ y¤æáj/cbg`3Úêñ+Ëv͇'-ð[ÖÍÔŒÚJŠbÄ‘Ûm²K“c›[üV!åÆ>p5ÜWy‹->#–_Ñ $ƨÂ2Ä?V~½x„.˃Ì£G5ü‡G.oßéÇ/ŸôáÓØ$ŽÊqëyئ¶´Ãæ÷°Q7Õãö{ÞªÛúù8ŸOÇÊé:ŸU‡cíx>–ǃõx?×Ç£ýÁ 8: 'ßâÁ ypXŽÎÍÁ zp™’Êt07yW×U¹4-UîïÕ0¬fôT¾­‹®1™>„±Å_·ª“° غBg˜ëä¡Ô3Ï ö½ðkKSðyÜ¥;úqï8'ΔÃéópR=œj‡óïá¬<ž«Çøá´~8Ùß}€áè[½ƒÃòó6›ñ Lì³ø‡'°ÍŽk½v:ü#¢̾„Ô<÷Ù·—üñËã‚8.‡evZ‘§¥{ZãçáüÕ<Ä$‡øå!ÒyˆŠÔ1ÖzŒËŽ1Ü1Ú;F†Ç(òo#Óc {Œv#ãc}Œ·±ù1Ž?FüçäÀCáqxÈN3ÇœÇc~ä˜K9f]Žš)ô)²9ù¬å¤/3½Ú.•ý;ÙÂö÷RuvsóÖ¤…}¶ þvé%š1ÅßÏeïé,ÔaL¾›‘àâÞ\ñËÿžb6ž¢òtÿhYX„¾·´ðóí Ù¸ðF[ñL.]k¿×«ø cè@Û5Óу×Yê…± }Þk8øJÏõ|Þ\`*j²§~TÀEð«Èke™ÐKéÏ2„µïÉ‘8f¾ é0°JŠ•Aà­,ÿŽð„W¦±©Ò5::P.ºF3;V3OcfŸ¡—± ÔáŒðz¤Õq[FN4㨞•Í*¹¼æ x™N£^AŸ:ÕpÿÎU€‘°,<¿ãR€œ86l€yݶûûî¨:O&Zäö2Ž`5ô짪mæ€ËôÎ'P^ÿeä¹Ú5'óâÎ4nÆãµC¦©Ïs6›­´nâ^8€â™a“¿¾Uý˜sÆø«•¡š:µ:–®0µ›Ù¹Ýžº–/õÐê Ü`/s€­ðn¸âPR ÿ6ŒË1ÓîOáüç%g¾‹«û2&X¼¤*¸€dñ+-ÇîðÉ};ÎþÝO^ƒû9ë@@é $l6 ¶üïÙ “ïK„{?åpWË'Öøúvx÷Ë‹7>Hԅ׺΢­9£É•˜Ã"tð“ƒÇ$ÅÂ̓?†å­yÉ,ͽ¼¯ò…™>S,z!>¥&¿¯¹âè¸v’ÚDU—¾Žç$Çûßgò'ðb|ã„‚Œbkˆƒ5…Y“ŸíB¢àÒNP6J¼Òâ!E¦ów’.Ò<61câ繆ŸÓU=|–«ìÚvɇá'Ô§/dÒÌ47ó‡,ó¦ˆm/שë-vQ‹ã±Ž(djD¯s 2¸SS¾Q4¨ð÷Ì_2,•Šñ„~âR±Œ‚ÐÕ>A*^³©º ~Øã2d@‰¸YsœüPœ2Œ'XÜ ÚÒ›"hâx.à+×OâÝØi]sÈž¨ïñóÿR8" :k·Æ®èâMB¤\z«ÌgO%"†ùˆûIõ÷VœóÅ)¸}qȬiFÈwÃËñ•6©ˆÊ Ïl †ZmU ƒÛù“xxøbì A¿/2'àEXÞÅ¿ƒDÊÛbFÝÀ%NŽØ[å•MIë³P™¨-gÈ7ÕTÓFWL½¼—!øJÚÇ_ ð_6ÕRß\R ôñП€Ý°ÈYˆû)Ç h<ø÷Âäd¤àg:/îå01¢¸æ»GA§jf6&ç6¦¿î.¤êVÂÈP½¿´i{£$3dc¬oÝ\š‹Î`œ]›+1€ý&G¬XùYhý<=µÉùwâÓÞ´†îÆà¨†Çñ†È³xî„`|È·ùwŒØ(éQ©;ñÕÐò“9Šá‰¯˜žzàk¯m¤{ÉU*‚‹% "œ>¯p§ãHõÍCAdãiL–‚‰È†ãNǸñµ×v‰§5ʘ¯ÍqC³…ÖwÝJÂ¥º±™G ‚ÞvÛ‘‘"u!êœhõ>Ü MÝŠÛÃj­8ælÅì¹(ɲœ_%ñ™«>Dfã§ØúÜ´|Å‚ý±¬N€ïÛâq¨–†v­rˆË]e7*Ó¶\Ýd-ÀÓN"àž<³V´^›îÖa•Ö“ÝãÀ{þŒTIMµ¢öè»Ì+JMKÉV#‚x2‘MÒ:Ä sµ‰¶ñËVUý§‘k¼ÉFG7¯XÃý;ÏËåª%óšOÞA©·Å¥Q-É Ñ3`H®üû2nDœÖ¨:u²(c¼C ù=zÍKs0Ör‘7ÈÁ3v/UH0–á!uà᡽.ï8Áy£yŒ|KX&)IãD¼­Õù…O—@ˆ]Šî yzƒ>lÕn@|hÿ<`[ÊLf•ö`¾’ÒR.&2ã­ž‚LÝ—“ˆ<`«],#˜Ëƒ¢.vAOãøä‹±½™š½—F^T¢/¶]G^Ô%%l3n‹©¾+X6¯¯Í¡Ô ÕIº‰½Ëw 4Ð8ç€ö¼‹:8dìöæ-Q#‹–ÐiUg”×[ñŇ ®õ’¾ yçùü1´4§¯iþ³XRp:†Ür&=Eö*y¦ÀÙA¯~Dۜҫ牾´¹¸ Mùa–Èûïs$ ıi3R°×ï”`ï¸"4ïŠj°˜ù £…¤û#JË9Yn,}pýï¨u'-²ö—eåó$ ,‘þÖÀ>ñ—BUÄ™^…Û˜XfÞìž_« óû•³Êˆê}"íXãwšÀ¢CÞl¾‹![ì/Fv7³5}1³5>t£º“ß$ k±äQ"·KëÓÅÐé¾Uü½•¶1Õ Œë³Ò´‡!^:Ç¥d–õ­Ô5PÝHœÊÚ>i³»x..†Ð®[ÉEŸP55`¡Àq§t9ÑùSn¤B3]Iˆ`N®@LÏìûST~˜=ÉW—<Ͻ®jwÙ ßîƒ&†JLWd>(kUãnSµRsµ‹Rt5‹j°îÐù& ÈÚn)¡cî‘F©J.Ü:çðj—~ŒôE|##k€×tje³èw«±`’ï85¸Ÿm„c|ƒWl¹'=à<™ÓU‡90vy‹/ŒS)Y;¿}€îÛ;)=ûîØŒ¡çÆÇ㌌?B# ÔCÉŒµë%x ­Ïü½–%u%[[~ÿ·jîŠs´`ÃRΩîàvÞVabh…vÒ`zöÀ¯$ܺ‘G«è~n ½Å‘—| ×CêyÆÑ6|½´­€Ø4‹ ¾hÙIR²Ú¾^¼ÐýÊ$  ~q厕'¶õþÔÔ¨ó®ÈEàÀÛšÎ=újqüê…`¥‹ ïIDm#¨¹–`Ðl1Õ #12˜«Ù4Ù5°|ÅS‘¡à\Uæ3We-®Ôù8Ý.MÊ[ˆß^Ò­4¡ó–+)ïÖZ!“ “)bK—+JÝKõP­€äwµ3<†Ep#Ÿ5# +TÛ[^QÕ_~€É–0“r  ’Yòš&¡Fî ¹Ü‘êWò:+Å6†ÎÒy¹+˜›èê8é#4ÍU‰?Ë'»/‰´] Ú¿¡Œ˜DzQqÝ)ÇžI°=7K_ÀêþRg¤¯KË*Ê5ÆžÚòV§xÉt¦g• ÔW8ØÔX¤£©@‹+(ÿiÈ÷3ãã— :0Öežµ÷§åŽcQ "Ù¤bÞNÞ”aãrú–AŽ8tM˜¨ŸÁ؇0Šs9³”hfU_!”îâóè-[­BaÙ$€ì(”¹(~²yLÂW›Š¸¢0b+þÁT;©ë0×.-¥žÃÈóдÁµiÝ”U¬«.ŸÌÚµú‰âîÇuczá%œB´¦­:¤Bh•†‹1ù•{Rø4 7³´³‚?½Nrh§˜BÍzÍéïI»òã°.ÕkÈm[Ÿ¬'„©ý]ŠÖ.ªQVwÅü©\àÌ%WÙÞ—êMËpx”íFb à 'î¯ öEp~åpºwxqc"jª‡¦€ gÂÔ<äò?OQNµåhKY¨%&?MS¯óB“õŠÝRà k½è¸Â%k¶öŒ÷[ɰNR“f!^ =3ÙÃ&_÷v„þ÷=2!=ɫ߽òÔ:í¶,ndü=€y«),ƬJ˜­©ÀŠ[-U*{õµƒ9–Éo_Ø*n¨˜fj<©ýo‹J=f¦TÊ*WYÈ-±%`M_®¥IíTJ,’´ÀÍ/N_V.S2êÖc>ÔÌ! g2ÜnœÒ„#H¶@»¢fÌreì¶wõá B³¢~Øï?ûbðÅ&-¿ðõ&¡5ô Rfm*³å„›= #óÌv³÷„¸•½6ÿûOXFÓ`w”ã2T”m]̦¼Ž¾jÿûÐmLY;tBuè./{XÖP/+JÎÀiÌ•8³ÂuöBK7ÆrYTÓê®7b\BM9{6F–ábuˆ¢¡<&© #ô>1,™­… ³ÍHÕe`X‰b2é–L «r5Öc:J”O€Xëâµôñ >"`mK{µ wsiÜ/™Û˜ÄVg—ÐLšPHî¹É7VXäõÝ;6Õc&WöømpÈX–%6Ë[½ÓÚÉN"ÎІèò$a¼jj3´]èÍÌZ nÖk-v-O¶»0i‡x¤­ùü¶Æ (X\ƒM ¨AÄÉ£VÀd%§K0®±°ì‰eášÄ—±|Ê_/%‡0)b¯.⼂¸!1ø©E! €³´g$‡Kº‘•ôµiߪ×h©Ào€úw/³èÁHdMŒN"SYdÑlà?2¼^ù¶ ÷OfY¥çºˆtF*•Ób«Ý X‰uiR!5Ž”çÐOש3  DW.Äìñ 4Ju©z'ý1QY'h+¹x›ú„}îÞ]vhÑWCB'wã‚ðŒÍ—Qu~¹í“ƒ×Rã KDŒšw`ä'Ît£²®}gU4¦™gU‘!yiÒ¨›tŸã$©¡Ó²’æœåËãÓ˜žtó Ê´$²´ éÌlAö$ŒÐöjjd˜äâ±.Fõ 1ÉG¥ð¥Ý|€ê‰M7»ãh„BšªJ`†õf6µZ‡ÿû®K i_äm#?"Ô²©pPÍï¶%kÒ–ëÅ2ØÈd‡G)píW cÓ ¦éky~ Fëú¡!œst£•› ®%—ªÌÔ®!xã ×Ïͩܤê\§z¸È99œçƒ×û`4ÇÀ¨Ùt‡×÷!Ä2IÁZó.ÒÏ$Á#¡ðH=<`~æ^üwˆs´êS+ÉÚ6úA³À‡ ¤ø¡:– Ek¯íÀ(hÁ¸6p^hîÉMÚ1ÔIrðÒ ÍàÜ6ƒò[¦µoÀ÷Ö$è‚ûÀ¨²VwR‡ÿôtåo/õ{ [WwÚŠç‰ä+h`Í+ȾOÞ2ÌW嵪a5¢ddeÂŒrWQs¡áNæßWlSa ®WÀv)ƒ·e˜÷Ýfák€‹D1D›Ð¢îÙzmôô+q[^½‡±y½×úƒ‘þ¶ýMà¼IÉÚ¸¾<¥Èb(0ìíf‚ vÄ€c* YÒÈ@ÑŸHƒ­6Ñ™pøAê2ÎÙJu¾Öú©B âìdö Çž†0W(x¦@WÐsÝ}G‘} ‰òcPæH‚e0<&¤d„÷Ø©ÛâÐ W#çß’‰à ü-œëzíS.îâ ¸þR¶¡ýé~Ã$Re ,d°v/"Ù„ë% Cò`ðG zåFò’QÇ^‹Æ+ký¦Œdä ŒûùÓz׌ÄíNOTùUiÒ>·§‡Ã;®bQ½¯­îƒ¿çt/_þ[Ú«–îè ì¾vîw¨_‹™“ܬLo‰å®¦x/ÓzÙëï™»~ÅK†cEá3Pˆ÷ŸÊ8ô[ÎÊ|ݤkkf´Àf$–Þ¶ðÓA°5Íì˜ô÷“óeí±òåË‘é!Ëiæ xõZ~3_Wx¦T¹8YÛW²þv…wÀj]KÜ(?‘¯ ¸¸ºáõ«|Dä Onf,œÄY•ÖöìtOÂùšÄÛ=ƒôÕBñáiRœA›¦àÇ7nt¼¯ž¤ðw@: Ò!ž‚ÆBÞh÷¢,!Ìž$©AT m¤(zŠU¤Ì#òNÒUO‡´~ ¾ ¶B5¿£qñ[Ë•hsˆT¡ãuúR8‹@à/©À¬Ç’d^ÐGàá‡ÎbÛs³É[E:¯¹*v¾EÖ9[7°ÈêFË(OÇŒTm4—¢[öÓø‡r‡^E0³Cb€à÷Ê Œ걦³®½L1Ï]¢W¹÷‘(kŸ´†F @š¹NØ(aüÁܩ䟋X0‚m‘E„+Š[†‰‹ÎRE´ŒKTÐUädàXD¸ªëݚѼE 9òÜï€âè|“‹F«]x¢šÅ@“ýM;MJÑH;ýÛ”UhæVEbxÅ ¼ò&uˆ¾ü_œÑÆÆà£W ûR\·vr’o|š‚ªºaß=6‹¢3ÎÑêó¨±fB“NB´ÀIº+¸´ X4 2…/%jÛó.>Ö˜†˜²ïæA0…7kŠÞ·(ŒM<-+ׯ lQ[*hëOl³é”Y„(+³Ç"—îu‰†Š9d`®Ñ´ª3>¢†áÒ¯˜,¢ Êóê@3¹Ë±qž¡Zj}Žåjɳgœ½.ÕøL±sðöÝ|.²`J›³ ùÚ–ipãºä•ÎYBQÖkp´i‚´„K±‰Pq4ì“BpQúÍÉ lI®J“r™@¼V”jÉÓù>õ8ðõË ’8x*—éƒèÑÓÚ%E½/ùÊ&aLÏËa¤>ÀŒ}ë"× URFUÂÞ¹‘uÜiÊ·~ô¾Çïü‘`‡$z]œµ1ÊfàYCÏß6NÔ>섯údLe á‹Mõ…Þ]pýÚ²ýl*ÖCC9'W`tùNÄ?XUfÙk°ØÌªô¼¬½uÈWH©‚PR³º9]ÙÅ]ºVÃ^6<)ÕcKçsfž½f[•¶qkƒûó,Û#1swìE7(ÂPÖ¹8&× ÍxmÚS}sƒþ‹©çÐX…ö(:Mæ}'*Åó¸Œ6ÉkP£ð\ÒÏW°ÃõÑ«O¹Í©ª›Z?`GÜC“Æ&o~‰ÊÁpmnP óÂègMXQ H‚5¹&‹¢+Ùc@« éTjëÕMøHHæÂ9%F²^xÇŒô¹Q-ÙÛ˜6¹A ¢´P¦'ΦIJ×CÒ1Îeq½ðèM¥™¡'#©ÈÈ{K¬&ád!D!Ð1u©öær‰à uàпÍK$óâ;0 7渴›.ŒØCrÔRѱ€JÀy…ŸÙãx‚쇃Õ6®ñˆ¸4Rp‰LÃð”ÆÏ]õJ uþîi.-µÚlŠ…ñj—§mc§Âq!LÉ7‘ ,´åXsxT¤ Õæå`¦Õž”àÉ®›Z¯h¤JõWƒ§1ß:B·rÖ¢lë`2Ô^#{loVÄ~ƒÆ¿ÇKí•Q[J'ϯû ·†^­U¥¾òÅ4bè •ç¤[jXTGô¨(l‚mÐGž/#«ÈgÐGj#'WµÑzÚäàEÿ1&ãF ¬zµTC‹¢,…Á'Ù7îŠ}ÄðžK¡ ãò0Îâ•Ê·X§è¦–—q¨-P¡5 ´Ôv“Žƒ°ÂIøMüU£Q.àYt‰×‰t*°\î¹øßïC‡©]Ù¼Y®Ÿ¥UèáNòÙòãßÿºKtE„#ôyÃ%nÿNõ­07Y@ù¶ÏÇ,'À^|#Áüûgl^\*å ¨y ]} šÄEç7 Ί1“&§dó?-Ë´èK°êk_“Îe%È›g¡Ãؾ¾äé‚`@ï—#‹``O þ¦ƒ{³e13Φ7#ˆÝÆÕùiå=@ÆæÐ?yLç+Òvdèð®£gÖ(÷©!ˆñ¯3ø,bt7q Wùm: …h&û@ÎJUêQuáQ¤ç…¢»f`—¬Áß’ÿŒö2#"N‚ì¬?ìRÄ@Ûa˜PE²¼%é±uXóEÜÛÐ_•l™@ÞÿöŸ[W˜ËÝÌtÐÆaÙ^EqêbÎubwÆ&• ücÍj܆ê/©Ë«þn¤ŽQ˜dZ»Š‹‰¯­á3¸(™T?Ià½è’c=gcн‡À3";Òá]¼)©-·@€o*hnñá›y§˜I:BY~(_ˆÏC¥ŸY£vëûóP]@@a3fŽ*'wÆ~e xmc0;s«W±3̺hË.gwE! ÈÛýçJf(ŽËOßÀÖu…™ðD~ðOÅlGÓ¨¡;§ãf¤w$ŸIkbȃriò‰`3*ç#©Mîr¿½\ß„I=,A xæÝ8z'2ß#ïïÈ<² OÌÃ#KñÌg|à>y’GFåûòÈÔrp|ݳ÷|ä xÅä#_ùÈl~`AŸÓGnõûÈÙ>²»ÏLð#küÌ/?SѬõ~û‰ dÍŸøõg*þ™µÿÀï?juúJGÕ‚£¾ÁQ ᨛpTXxTc8+7œ4ŽzG툳ÈÄYŽâ¨\qиxÐÃ8jgU69ÞÄ;Ž*OŠ Gõ‘M’ƒ~ÉQéä,ŠrÔO9è¬<(²Õ[N2/Š0ïÚ1G™'=š£vÍQåæA稞sÔÙyÐäyÐï9*ýUNB'¡¡GM¢ƒ~ÑQéèQé$ tPZzPe:*8½+==hBõ£ŽJSªTG«£ÖÕƒ.ÖQC먶õ Ìuñ:ª}=(ƒUÄzcÚd:fGųu´£’ÚQsíAŸí¨åvT}{Tˆ;¨ÉtçÎug5»£îÝ£FÞQOï ¼÷ Ò÷ èwÐþ{Ð (ÇUfOr´gåÚ£ÊíY÷A;÷¨³{Tä}Pï-BÐ šç§hm%/•=À­q–ÅÃ@Ê“æå. î€i;’@~ÃÒ¾Cu«P¸EPÝItXàñeXº®y-å×òÅ|Ìú:ͲûÎù ùÈ%9²N*ïT–ãåóÀ¤9snNìœ#çÈø9²ƒŽL¢#çèŸt¦28Oü¨#—êȺz`hÙ\GÞ×GìD';òÎ8j':Û‘÷öÀ‘{àÓ™w'–Þ‘Ñwæþ=ðO”Â#÷ð‘§xà4>±OLÉ3©òȾ<25#k¬N"šŠëÜû]qar‡xÆœä7öòÓù}¢OyÖGFö‘»ýÀó~à„Ùã'¢ù‘“~"¯?ðÜœø#{þidåŸéû'¦ÿ“*ÀQ?à¤5pÖ%8*<¨<(#4ôŽÚ G‡Ň£:ÄQGâAsâAŸâ dñ zñ¤qÔÒ8ën5:ŽjGå£JÈIOäA{ä¬SrT4yP?9 ¥UÔWŽJ-'I—õ—ƒNÌQOæA{æ¤SsT´yÒ¾9¨äõtµwŽ:=EŸgõŸƒPÐAQèQ}è TtÔ4zÐ?:j%U•˜P)ÑÓ*y c$WTÜŽ5ä;ÀE²7T¬°’ÏAñ¤Í‹ku| ÏeK†šwMî:l+ô¨Bõ XuÔ¶:ê`³”µŽ*\Š]Gm¯£؃fØQ]ì]‡ì¨XvÖ6;Ë =(¦µÕŽ:lOšmGu·“ÜQ5î¨/÷ E÷ [wT¸{PÃ;*ç5öôøÚ}G•¿EÀ“xàQeðA‘ðA½ð¨sxÒD<ê'ž•Ï¢Œ9œú©~˜Ó¨ýz‚FËO2‘þ×E=Õñ/‰W^£e½l÷³ž-ê—ï2™ŠšOê›g΃¦çQÿó¨ú *zT =I•>ªš¾  •RUUO¬ïJ­GM׳úëƒNìQSö¨?û Tû¤jû®€{ÔÊ}ÐÕ}Ðà=¨õ>(û>¨õ‚–>ªuŠÏšÆGýã£Pò£¦òQ~ù¨Ó|Òt>ê?•¢U¥_ŽNa¾?$Í+ŽØAAì Iry ˜É80r ¢XcŠÉà r[¹„™„· À ˆÑTÓÎï§Oá_ÿ'­žâèÝcu•WJ¤´Á8ÕGræ|)­ ¸xßš]01¬(¯6[WÕ­K­©nj k+2©$Ó0Jà¦nB¸­tj×ààSIÊ!¼Bý0š4Zµ?ÀļcÓ¸û‹ÉÉ–ªŒ7ÉKñpzˤmÊTi"ÀH‰wT&Ð;¦g `9[¤&Vâd­…Ñ&扙Ƭì¼ul5c¼×>ÚŒ;Ð!Ú¼H#3[¡t`ÆÉt×ÎNMÃM6.£’b”ÆJ—‡ÏVÒÚ¼a¾º|)9ÀQPfì}´ Uj‚˱¿|vÅP´»âlójíTt4=enÀT)Ã:GåÕláž»‹†LëXmJêgÙ¾¥/cËÀ..9ÁÛþš×u^LoF–ÞFí’-á{Á:w:‰I™ä¿E*)ʸ–p]JâI$k”#z îKxxYuS×f.êÚúÚ¨­uÉe5ѯ¬s¤ï¥W–[`V[”†ÍèàÕEDÑì ™nÅÒI^ü€¯èŠ!æËù©Y¾Éì„×åNº˜3ð‚3|T.Xü”ªÛpg­ÆifV¿Ìõu(Œdƒ'½® «ÆÉ–Ÿ‚åíoæò˜å«£ò ‹ÞžíÖc­sHHHMÑåàrê²Mf/Á²Ü?•)ûž#®—ûœ6€0Óe£O®]l2²# + e„KyEÊç¬*õ—ö‰´#‚í»”âÌ)3ƒŽLyxÛum¨\+¥\õP|¯/#Á¸r5%‡¶~PRSUƒš%Je)¤‘(ºb=S5Êõ¦"F]KY…”—åõ¾ZÎë5—|Yò€Ù7˜+Näœ#ù{mb™Õøøi„_®¼Ÿæ*§ˆg¶›šC¯Â*ˆÂ]çëw’ÐbAÄÐgñôƒÄ“—1×AɺTfd‡´½lY}u¤X“â›ÖDÚ±c2Õÿûªöµ¸û+éÒ׷ĉZÕé—1­Å9¹1‘‹¸Ô-`‘@1…‘\éé«'އ4÷v™ 0G}ÀÌ“¬gž:I¨Û—Ü´ü,ÍM—èÒçþ²í÷džӖ;÷BeöTyúV›Ìu(Oo>·¶¥„$ÀÕ[ge˜{¾¸‰0zœ{6Qun$2·±ÃŒ* eÕx׫ÅI’ÂÑBM„ïõÚ‘a–~j Þ÷•…8nI “4(Yåî*Ô6*8C'Lái a‰‘¹2Dæ¾RÔú’+iòsMJ.ä t¾äȘ]Á~iÄ‘¨ØdV?$©¤†ÊÖŒúx Q‚|Íðê’Z#&á4…L†E`5/7ö(d¢Dʼn…²k«ÍZöä’šI§M¹˜šoX×Bÿh­ƒ©šs}q̱ë•VfóåµC%ÜV'¡Z+Nùz-š®'šqÈ5©ÐÊ©ºD©·ÒlÕ]_@[ŠaØE…˜¤ì9ŽãvI¯–HÒzK1ÂLMC\K…•K®y øt]_×j]7K°Y\*Ï©B|„<¤,KõÇ®ú3èÇ4ªröi\Ê{6Ðýû¶½\ ¥äÛÌ–yê²ÝpJ.öM™ôg€ËË+Qç2ËåÿXùµb!F·\–©w¿ðl±šºðú¶­`õ*K ,½KnJð´g‘qT]6AËÊïDå䱬Hž®: ðÓï¿?^~¹6 œ×ªÄ®î¨ÉéáñÆ+4»ðȘ\õz‰`øó¡úC|D÷)·çË»Å^¥Cœ2j’U`Ê;õ;JɾÃ|µJo_6 °TÊ;æ­7=ļ«ñÕEün‰‰ƒ±;ö%ï¢nµ®Ü£„Ö¼“›úÑ#qä1ŒÂ#ñV}€0™N”ºýToB#ø>ø>ƒ?¿¡¯T½,¤jæìƒfIg5í̦»ÙD^²ÃÏ‹\ŒîQé§S£ˆâ¥•l0Ç|uêV6I¢š\«4É@]+a¥7yXÄ?ÞWºi'rØÁpíÎ,°8ð«Îë6‘~É íÞ Y ö82ËÅd’zµŸÀH(ëò4„•î]θÐ5GÕ 8ÊêÈ €e/ÊF) 9ºDÌÍq 5Æ¥‰ï~J¿h´(ów6ÜûƉAd*á?¬3Vã’vp ­ÆÈ7›¤°«6 Q<9‡ut³£†ö07–ô÷¯OI³åj»«,ÁAûßÞáaGFˆ‚oÅW¸¿è!õÇQö;7´«W)¥J@ JW¢ àZ Ñeõ3EÖ%Å ÁÜ ¤f;¼‰P6¶‡„êþ”ݧ¤š'éAo=£¨p«ìèÚꈎa «Â¥ªéP—^Ä­†Ô¦å^'ŸVHÿ¶E÷Š„ sxšè!ÍîN|“&Z|Ÿ(CÅLŒa·;m–ðuØØÅiè|N®œ’‡û{@æ/KÔ;z%¬æ‘|+æ$þ˜%û¿`;­ÉEn`  {€á×òÒ"± ØÈ¨À¶vIïpI/ËQ v[T?­Â:bVz(Ò)…YÁ'à¿¿ëBs ÚÆ¢êsK¿iªúïÒ«'}Ö³–ëI÷õ û ${T=ëÓ>hÙ>èÞrjºGåÝ£FïƒöïQ%øAQøM{ø¨Qü g|Ô>>ª$?(*?¨/ušOšÎGýç³RôƒªôƒõQ«zKZëoS¬à8‘±ÏJ"×»ãtØ¥zD?Ð?À:ýÙWú7x‰F’Z!Œ&²Iv¬ ”âat? ZdxáÏ)SÄ8UcºÏÜI1{ÉuP¯Íܼ" J²7Éhû·BhsyÁô¸À^º®É—¼< ]†¢XÚÊæ.¹vÅ”vöi°ªù} ó<—¾ÛÚ£ x”Òæµ¹Ê§•«-»i*ˆk3“1µl!‹•Ãx znY,7†¾³™½ZÐ\ªQÆ‹FÖsÍèŽP¥x² h"‚1‹32_>ît 83:ÍÅPX6RVµyû«+­ÖO»ž«,îEv¤ZÍ-…hfꬮ(W%`\Î?6cÈ+Xa×$ÇçÆÎ’åÿL©o7†ô$€êL4SwØTBÄ$H‰ê O¨zìRÝ8@#a\v­WÔsÙï.Ôcs¬ f¿ôº6ç*ñWî(V,PüWi¶|©¦ì!-emmõ ‰L,¡-ª©rñ×J8/n€x×\’Ź˜?¸2¨°ˆÚvI"1•_Åü³ ³9ÇvHݘ„ÓÚ1]è\¿}_ï©ä>+»ó‹É`xj<¢ùõn[ùüž_«É’É®0l[Cí&Oª%Î*| ¡Mš3 `¬RÎä®·T2Þ뺵+$³*¬k¿!3ég³ÕkéÀg•CN¢š!W·4»ÝÀ88@Ðák÷~;ß´Ê—®%áFBìnÀf¢Á–éÀ¨À4EiÜ£õæé£OOw@›N@M,sÓ&T\çÎ1}‰ªÊRft2ce[…o|ºu•Ð=ŸCx%øx].*¦d¼¿„¡\@-qLÈuìDz`Bô¿ì§‚M5ìÚËfœ £D­Š2™E u¢k Æ[±¢:Oã÷ø‡¼?Ç @þjÅqGÈb^ÂèÖ²µž§øÄ0.9V9ôÞëV™Í¡ÈS£zúxä݃£#ñàt”£+óàö]¤“3ut»ž´£+÷àö½9ˆGGòpä¥dÿTb êZTá'{0~>ÑÓêóa‰}üò¸ ÷§%þK|ºþ\{ì“âÎÑú¦F_$XŽXµW‹ótSZÍÀzøFÞ\ÿ÷ùã—Çþ¸=¼m%ß´•ðHË,CHû<)Çëâ›…cæF/5N”àÑ«UãñÏÙØÞÅ}VÒ4³gBÝ0mïI_6s3àYÉú.ÅiY ÈJànú2õ¹"ƒá ÈjX]þ}À¡÷5y©N ¶>r£Èê.ŸPnºWXqS”æ€Æ;Ù¨˜§öÕ|{Q}ÌZ:­ÅµE®$ß§ð7í¬5¿!΄áníÑåój × Hîˆá'°Ã×\Ä ?ñµ »E¢-G¿7ꘗ2bóšACåÐX8žØ(<,­#š¿ÏÀ ­ñ†•p´F|¨´xúÁ`]%`M Y+KX¡ ˜¡|¦5o-ü±ÎùZâYqÀ`<à5ÎÐŽwÈ-òßœó/j#U•ЪrlÖ;£ªZGyÏ ”}Þ QTB´Ör®Ùp„—uñc,x5Ñ/ åÝç® ’ƒeêdž'5ªFfzÞhd¿Rt8–'Ž…Œ2cÿvD}üòè¯=»ÃÎûk»ôq?ÿ¼÷ÿà9¦-mÚ”]…W>®ÝLÅ1†É{ê|Ó#CƒÕ$DŒ”C0Bð?uÊOäóÙýù”›åwÿƒæå˜‡ÚB¾Y:©›údœbR[Aµ·§·Ñ=8PHaw`š¢z1ÆèÂY"'˜Í4qßÄÔûV¸Ëå~W“‹áÈtëâ×nú)dyoŽÐ[Ðô>Ó`ˆhö,Ýî§üusŸ)KcãWC­ùtÆýÚyx<9O§ìNFdàk´›'Çf†_Õ îþ¦+Š p5#3i%àßïSðÏ"ªö~Ø}üò+ãñ}B6¾£ xÉ'h¥ÀØõÓßSe§†¦Œ”9qo÷K´»T]¬/× IV1€`'m }€Íoòýp­‘ìyðÞû·ŽÜ4»wú|?ôè~è4þЕü¡ƒù©Õù¹)ú¡ú±ÓúSSöCÿöc§÷Ç®ð‡òÇ^ó}é=ìÝîg,uJ›ù ¨EJ3Œ,É[½Ñ ‘¬ø;»ß, rÞÙÍ(@þ¾±ÓiJÏöºÌrY ׸RŒx†°¡ß-Ž\<Áž+/–,Wì`öº8¸&Y]âjŠÕž50¿ìj@¹ë’`û°„q_€µÅJŽÞ"ñ¶Ãrר.I¾ØÚâÆr9êTë(K˜›>ñFCY×.C^H©ÛßCÅZJúç!~¾-6Âu¦XeŸV´:…™Šõ0{Cü95‘¾¹ôqÿ´œv‹7ßþƒföÐ3søö<çad3Ð:µü H:bè¿Ba¾L'G|ý5tçzBŒÑ¥x5ê M=¿ÊxƒêN¸Ó嘋Äi0*Öiŵt>i[˜áQ Žf·e ðŠ^e®Ü™f ä»rÏPð#jü€/Ä¢"±‡˜í-¾;"¡»ÚZØF,(4©ä@ôQÚ'Ž´Bì믉¿…b’²GùÙìùEGÞQQÒò)‹ˆqv»À•… Ù7WmaY?XF·Ç¥ Iݸ³}©Û.™êx‰÷ Æñ-…úH Lãû$žfºÅ"¡dÜÍŠsÈ7Ѱ=šÀLíE–³ŒÜð`~“¨óaË–YÙíBÏ!ÄÝ@îë3˜î »û ×½Ì8]?MŒ—A2ý o!=6Ó̾;«) ídñ½OÝ)Ðg Á3)ðÂ=Њ£€;&ó`+A·„˜´Ìh¹GÚ¨ Kv‹$ùa;¥RLbß´VŠŸ¦–øwÐ=S€tT"3äxYÜõÞáôœ+D ›sŽ>h–{W¡e²R¯`ƒû^KÎQ¹RÜ&‹&QòÜŒëàp3›Ôc·ÁÛÎ1À¼9òb¾ÙºñÚ±ßáðœÃIôŠ-q÷A3ó&Õ˜¯&C.¿hz¸¯&X.ݱEöGôõ• ì“L )È0Ê_¥$§€KR+Ê¡GfHÕò+5–ÃpD¹ÿ} Ðåzc_]ÉÝ»ì™X˜o+èJ—‚ªŽæiŒþ; ¾YnÃM[¼S¸Bô¸«Rµ ]2˜¥mwû)èÓ'®ýIµd Q½ˆ¡'5U‡™µT ö¹ í,Ž€j~0þ®¶Äþ ßxÄÙ€^¯þác§¢ì¬Ã„MUÀò±‚><âúj"ÿl›lì “/P7†07<„iìǨ¶ÚÕ…£ÊÛ»µ}‚YzÑ ØíaÝahÞОs(Z­)î>`7XýÇS%cqpÎhÀÑvGs¼Aö¹ƒ:ô/£„kœØèSKo½:µÿWÐ-"}åµÚ¬yh “@§X¯%,ñ˜_:>,/{«×Öñ#>}é+f.9JèCsLG—íWõ–˜‰ „·ìeœÄ5d¹Slý»¥â5a3•÷–Æ4îj† aNj–9­›£"øòÚ.u’º¥Í¹,L†„ÂÞW¼Ókw͆ysø™ GjØ9‚f´]©$µùÃÌ ö°PjŸÌªéK»¼Ñ(\d!b|QO™µ±Ì E·[Àîßå¼ÇEeXE—­Õ,!Å5h{‘PµfZ«Ò‡ Åß%Ø‘)Öm«ZáV4®¶q½oV cKêF/pïÜqQOÇbš|IlÔcg¢`Õnfñ¾O°ëŸ!³´¶Xj«P½«?žñΉÃ}ÃìÚ]žñ½G$ð#jxx]ÓTÝ#Y3Ú±„êªá®‹¤1l£ü¶ï ˼;ø¸º¦ $ÁŽÄXwpýð¼”›Ó”*ÃCˈ6AÇyÞá»R²Þ:¹Œ8Vö5%£.Éü+ÂÛ·—pÊ!¿åÊ?hfn yõÎlýÐ^…D51Àðõæôµ©­ÅWS'JĦ´Ð;AîY4©Ì‚ LšJu÷¼sÀÜ–€· nñj€~K2¾å€-_|Ì,Ÿ²ÐÓÅ©½ @æ:¡¼¦¨‹÷±^ðT[8V!~®X¼¥±ï€%„bùl•Ÿ/$´QknÈkãÿzÍ%j ÐeBÒ› wѪ™WG)¬“lÖQbë(Æõ Üuùz;J‡TÆäÈŽÒe2gA´gñ´w¡µ“$Ûƒ|ÛYêí ÷ ÷ 4w”¤{¯;HÝEñôÎb{GY¾ ¿£ÜßQð,"xÈ>HÅ„¢‹GyÆ£”ãQöñ(ù &ù þQñ®¾X«K'ñTéhîkœ/ìxÅw`ˆ—áO ’3ÜäQøì(’v”S{^pWUÛFY‘˜Ï×3Üàë34ábx<0Sd‚‚B‘±ã %7"6Cµ›BýÔ¥Ö¾— È0²ªl%ïpÝvÅaì™ÃªY»mq‰×JÖ÷œsò!?oð ß>«x@Ë †¥¯2E©rß|K['ðŸ ð‡3Æ™ÎpkÚl)š¡m¸\Dï#mb$Uúq»7k’”½)®üÙtMÃ"cȼXº3ÎKB–ÚãH!eýX%C½õ‡-xÔÙ²{¤3’§ Ý8BÛ˜„‚¾\!œN?Þa2áo.bg³b³Ý¤Ü¯TÛbÒXÛ3ìl½løèPIo0y»H«Ër[‘"¸\~yØüN›äÆzÞz[ôq;O·…Gª™i•Îö)-hÒ€Mo7bŸÃÖ!lWSPøiñ¤¾Q¡êR”V´&”þûUt|Xt¨Ë!2'\É*X‹…•~] ?‹Õ\qÞ$8… ‘ >äD—&ÐRƒ>ÀsÔœ!§mŒK`Aƒ˜”ïpµ6 Ò ¸ ½”8.j™zI”_Îmt°H‰Ð±Ñ…%N–ºº¹?…À–„4ªÄVEÀl”XŽä¦qè6ˆõ*zæH#zÄiçwÛØ0ËôøÄ ÀNì´UÓ2•²·Ÿº!~¤í³EY“ôwÈÛ1tDpH˜¥|Ó;ê5õ°:±0[*B+-çuû}v¸7$éˆÓ«Aàs3iÂ&àDdß—©´½êwUçMF7V”ö©c.‘Â`¤<µ•ž.þ”Qc yjîÍøH¯_B\IÀ×¥Ò¶ 0z‰ì‡i"WS/±z¿h`hf®\Z‹Í¾úM;Iö)Á)éá!À9ð¾Îå"gì4¿$Ý6s×I–søáàÆìmZëØ2>ÉeŠ©I\^ÎK ÞGh¶›TH¸§PL™6ê&Á#íPŠ›¬ÆÏážC‘â¥c«RìÙR^Ô^ZW`Í–ÄŸ'w½á"`nñÃó²~Üe£Dž–«L5ú€ãàiTþž¸ÿÁóŒHíûµÑÆíôÿäà?„çxá[ãsÄrˆnÞm‡ªøÎð ?d®P^Í d¿eÇ2÷Ô‚æØ®æÔØæ¡ α_Ω¯Îc Vž+Á n´âº?ýˆ•ÔÖ›YHg3‡°á> Fô§˜çh7¤bº<‡ä‰Ä‚ãCé“'ötÏõ« uÖ®˜Ïú}ùMMèkPÊ !Ku·)ɸGÌà_ø€D|@-ŽG,ä#nr»˜b¤Yt8^T·l¼„ð9 #›ŠœÂbÔª–¬@jWr¸öç#¾ä MÜøú8о,¯¦]H=k[2å+è\EÒß8/ˆ'»ªz'˜+4h[ÔAûÈDÿ2íSÅó«‹‚kcz«ôkH¶Ã´xëÆÎE@1$S¥¨3¥ãvM¥¸pÿ[°@KÄ’a‚¶ÔPÞ·NoÎå±}IÂlõrâ>œM†•‡ÍtÍëÒÙlwt«ËŠŽpC;ï^†˜¯”né<´Å#"TŠm幈ۚí¥( ÅSq¡a¿Ö“¤èá—Ãï&ãeìYk%N‹×Ç'>®‰~V9¾jžæí†ÀAiF ö+4ò¥u‰@i«ž¦©ïÑXñRG ccÚ•¯  Hã’2¸Ij†o‰ùŠKG”ô ÅêõwœÌ·v‹ùNÓÕ!*¡¨•±EÚpD¦OŠÒã&u’†zQÕÝ,>õ€ßvZR$µÞÀa©"n_ á‹«Ü/H§ª.!8îcþ°˜7QþLEHT†u¥uݽý€ %î&3™ŠÚÔÔ áÍæ[>ÀN2TCÝÑV$²&d“u¡œRZ‰ZWŠž£ÖlÈ…6_7«¶† å»²¿‚“nòQaù]ù·‘4Ù‘Å–•¤92í¸z´¸­^áñºZaÂ\¹çuw9hôÊòÕCVµn<ö×^$£Â~Øk £—–¡qîÐOÐrȤDsn+KZøÔuµ®KbÞŽ=fD C Ïwm%å×ýV|Tù×ýÞ–0Ø uD nÂ%gVÅücu$C¼|(¯U‡æÛÇ”š€h €ä°ºaž¦=No¶ß-òBŒqlGë©GwT.†Ô­· ~êrðƒOnnËk¾æèQÝ ‹½´²Pñi÷Þ½Ê!üf(N¥ed(÷•½Abå–Þö8'Àh¶¿òhæÖn.BøŽñ–ÜUeAˆ«£RÝFM´Jâ¥þ>ÇûW¸Ðr´l¬—·Þó÷n_Í”ö4A—4ß’Pì«{P~>•ë-'r %·›3 ¯ÚmIn‹UÄÝØzäZ®µ5BI¹1D4.^U0“Àùê"£m·“th‹å¸uGâäíN¯³u™Ópñfð0LýTq‰ögè¤2È †*UÙ×Òrsr\Jºåü:ö¿Vó…çr€BI!°5=êðüT,ÓÍ4!æ,Гƒ£™2S GhsS•ÍKµ…N(T©7â]ï1@ >ëý—KsWœ%¿Úg—º[‰ÞhÒT…ï¢ùj·„ee`œ[Šƒ úÊ—¼G&‰MNÓñ¿Vé’ëÕ6tï)\–Øl–+ÒL&y 70ºQ¯ÿ—½w]Ž+¹ÎDŸ€ï€?Š°ç ¨÷Lwœe;‚÷ߨx 0LXO0ä" ’Æù +©ƒ”‰arÅ c”®±’Ú±–2LYI.qqž>1ç¨è°¤ÑWvºJèºqGÙø'xî£T0¤ùAµ…qfïãÃï©/¼ꆤ”_‹szg);é;‹d'éF¥øSÔè.Ó|Ë7ù9§Oa…8AgsI\VÆB.nAÀ¢Üˆ»ùWøý Uk˜Ôµ’6L¦•­¤ ­¤« Û†IpĹµÔºqÞ0eo˜Ü·’¨p)æ£uˆ¨À2²>ƒ”}¥DD$T{ùpÒ@]=+ö¨2;8ie¡´¬ZiŽbüî3b²}D¤ºdäöÁ±Ý¤Î¾¢VådóZ¥ NÐì&¡brè® ÈÉ/Þô߆]ÅÅÏ#<Õ­”uu²)œPÝ86s •i@gÇh ¶Z1)Ut`ݨ8ÍiÈ3œ8Q³ ã ^S^쥑áëOºCB‡„Q=¢‹yØèNƒ3–Ä) ‹)©ì¼XN\#‡ti/ª æHO.¢zð€Y(Xy£Ýñ&i'«öFÅà Üa®î0¯w˜¼’-¼›W<Ì@ç*¯ä53 ‡™ÒkYÕ£ ìa®öJ^÷nø0O|%§©ó­ÉLeà”Â)M‰^jÞ·…ÉIS%Û~&`¶‚†Œu§”N” äÄ™ïÂkB¥è2kvðè*– ¨7&øOè'‚üÁ2XzáÔ%èñ æf™9»$Ó=±ÈÕ$†Šì¡"5ÉݪZ•ÄZEœ2¢Âd Àši–…4áü=Ķâ!¯ñjšÕ0%k7yk=ÑKÂazj’Ô3à¡ 7a–­xœKÊG1(D¨z<Èh|‰Ì¬bW;Än¸I§ÅW8îí4U-¡ÆÌÎ7ÁÉ=¢ÜÄC1“D"óÌ2› .˜ iÁøzÁæ¶Àq§Í$nÀßĉ#Áþ}kîAîù:™î˜vwLÑ« g Jõ/î•ø^‰öXþˆS!—™ë¬ðþ`-‹Α üÑúiΫp…GzÀ9=d§^ÏŠePs-‡y™v"±¢qé‚ô`XõñÎ*±÷î`ïoT\ ê`kÍH®dϪÕCÐy”Áš„@Š{I$ÃúMS¦Iº³Åì”äÐ ´AõicIÔŠØ¢öiFi õÉ•1è=ÈùÙ`Õˆ#ç'Ä_DÁ|ð} ’¡éGÀû vy4V%)ª©v>ÊFyÃŒ„µì…•L‡ANÄJþÄ0×b˜•1ÈàØ¥UM€}°’µbeL0½´% 5pÂYÄù½„š+䛚ÎJÏ!ýç(t5E`˜N0Ê;¦(dC§·™.:/Ò÷Ôãøž$‰ABÅ0õb5M£ë":38™ ˃P§pç#ŽàÉ;ì³7*ŽÂ¾‘œ¡ø»,ÝNX­EÈ(×jõ?†­|…Ó“³Îälš©GB#ažRäÇVZ?U×6D*[i )Œc^ƒRA×›8i wLz@b! !LÆRW¡‘ÐižYÊÐèŸÀЦ¹3À§Zeõ\ŽAÞÇJ†È0›dÈ<äpï²ÏzDÏÁ†z£bP,„A™Sꑦ/©˜-,>ɵ¨oøªÀG«ÞÖŒ$¿%ár–ÍodZZpçDñ°MHš=~>¤n=_gyòÁ®àÀ˜ñ¸|‡>ĬÑí+Hø!j~ˆ¯_Áâ¯àö‡ÿ•l”ökV ²yð6 «h´Ôvx†oT-Gš© 'ñkœ31Øš,F¡7Mv{8Ié¡N`""Òpt ¨·Cd,¹äéü¤N/ů{óåû7 ÷vq;)Œžø˜èèF§Â"g,›©=%#duF9I OMïjò«sÆ“ÎF9°¥ºÈ Êÿ2ÍN÷ L/Sµ+m šhõ8à ¥©-`5U·S3œk097à–_FÑö]¦”@ì¼”…›]êÞß;ñŨ²)Î#çPpÖ@¯ŒJÌ~© 4%juÒ•s†ú‚Ôߥ«›s§8ó¥þÈ䌃ÐYЛPm4‚‰>Î\¨—U…3#z×ä ¬,‘ ZoºlKÃA]b yÙ˜ü$kOž4¨ ÁмÙ„W?ÁÕ,CÒªA™ÈêýæÍ{d’Qÿœ«Ð$ihòóe’u-pûb»½¡E”ÀXP3º ™O߀,³_XÝPØb2ªGÕ5ùûû²½VW#ØJé:PÍÂÃ5D:ØÆˆ‡3o•úœ!") Uƒéªœ¬ÎØ€ùÓ ò‹¹"„Šƒ1¦-WÛÍT¬TU»@ý£`ß™Õ~œUhFüå É&Ó8É7Üu¡Ù¢ò k'D¦çEÅ= ü“ÅÞ8°w.€= >LHŸfÀž3î’d5GgªãÉ8Ü(,?;•o .7„Ö Ax«€½¸o\… à…C â*hqpB!Wa“ˆåŒ9nAžc8è tt3RÇØÕ˜ë»žm‡Üøîê;¯ˆ‡`ã,y¼w£G ê!àz Í^q!ßCpø |:_§¯@Ù‡°÷@~L?Þ!úÀ×ù*6l"[œq9„JfN]L´ç+)dÃl³AVÚjþÚn®Û0+n%n˜k7ÌÊ[Éàfû óWr‡ù†ÃÌÄ•,Æ•ŒÇÌÈ•ÊQ¾å03s-‹s˜ñ9N ]É"ÝM8f¦®d±3^G©±+Y´£„ÛafîJï0ãw˜¼’G<Ì9d'¯d2¯d=ó£Ws©‡õj•mUpvbÕœ¦ÊþÞœ„ª§lèlêëœæGB,N35|’2C2OÅ@ÓlƒcÔ‹bîª0¡æ²(e0«uF∀«3Ú ÊK 啪ˆÄ ðœéª§ œ;S±d"^Ÿ£(É”Í+™ DBqŒ$õŽfp4ˤy »nT\Š”@¿s¤9`$lê&ìgŽ"5ô²Y‘.–ÏéôH prˆñ àB³>ÙÏʾ ð,§&¤šõ¼5„Á8]C4‚©â&ä¡ÍÔ2ój „d­Ò—°í½3îÿ4£Ý½3nÁd' ›rEWªÆÐ½•‹~µå½º^,I:jUŠˆ“Ì{X˜5?د'õY‡ç€Å;P¯L y@“à­´0ú%®=«šWÔoágžhÕevgo0ÅÞÂ…ÔI:lêW„â…¾/Ò»)÷eB´¾5©,3Š„7Ô‚Cl3YÅ+FËB³ÁøÏè] _©‚)Ðn4ÿ‚1ÜbjÐ&@µªqÆ“Øt¡x¨7²$$ÍïLÁ¨¶•·‡’@o`Д¢s Eô†«ˆçìB¨AFÂ"rÊLóÓ'as·G6ŽV6 K{h¹»1 h´´t®¨c`w£QF$ùЖ±áÈòTN´™ÀŸ+¾£ä<ÊоX-›äæL)Ì»U‡gÓժǡ< —Ã8¹¶+L×$ô ¨‘#Â,àpêAÊ0ˆ·†0Â;¤ÁÐC“ƪpÿê8¹´¥CÊ rÑjõ WŽ8Ù£ÈÝd—WÃZ”앃¦Ñ–½ÚíM.V9–ͬˆ Ö%}%uI‘I×€|ÓôšÝŒ¬ÑN º€×Q„TC×ÍÜ69¡ÀX²p0 •C‹ø@.È5€ê¤ X!%< , `ŒT7XX¸ZŸ¯’bþÔ¬‰,´’MiAÇ=W” J® (ñ´Ú½U|XÃ)øÉ.N)ÔÞåŸ2U­“Z$Ç!BJ*­S¨~ÐÁ8%á ÿACÄ€ŒÌÝì*lþѵ’¤CÜ%.»Qqµ|Ç \ÕX˜Oò7$ž1A,‚u0Š8 $X§+!Øá«ñÆalrÅ\‰x–Eþ¡²–q6=’ìÅøžÌûQ’þ0›%ó?Wd.9ÄXXJcup„Ù€áÖm5Î&Œ¬$äÕNñ˜æàEAõ'±²'Tg‰†Ir…ε®ç¤ô L4p×ÌÐd$Ö #, 7Q|ÎuÝænHˆ7 Ïû»y—äK}—pH¸N38¤$®ÇWéƒûÊvn­á&n×Á¾k,‡kŒˆ#îÄžÅËÜÖ–Çxc…¢cHç1¤þ‘„¬ŠŒÉG†4%;”&hik¦Â‘üÁ ™Ô-l/•& ‘ù¬›]íUfÏs8@Uºr¬¬@£³jç\ÕðÝdŽA ßÉÌŽf…ºfHs3$ÄY!Ïí¬Pò é{йë’QݶŒ´j@lîyήÁ»Ãu£Á׫Ôj…«jÈk5dÀ“ehµ†ü[+\]C^¯Ø [™ü3 \¼ŸLç±IV/â+Y ̽PW‚ÏØÒˆÀ[:É”}ÊUÃR­ÕXiSÀ’(FL†Å“€!!¶C’t%x›QA8Yf¹ Õ1ßuWˆ4í†È”2ÊÊ8ÆÚ)ÊvRLÜhÁ sÉØ€“¤t]ê ÐôkЇ–…Kz•llHL6¤0Ðíúvòðo4.3ÈÙf÷ &€nîRFܨøÑ)#†v`ØÙá°¬£Òß['(ý=$CЦ¬$zS üjô{e±§#BíéÃÊÏjÿ R¤‘¡Ý¤Ò0ÝLÈ$Ó´4x²RŬSÁéÊö…å¦YìÍñ°J´¶ÛZm°q±A½±•Úd+ŭÏVª£ SmG9¹ÃôÝb¹Ž\å•kÅØ•¥ée‰#Jz ç°ÈŸFqô,„×"|Ö²$ôdÉl—ßtb‚j§‘Ê–ŽÐá¬ÀŸaéXÙ±‚דÞgóo‘0£¸_©4wF’¥efÂrá~ñêÕͤ—Cå@©foyÙI0/ø}tÍ¢˜=½«÷#Õ\Hú\˜æ Ài¥¸¯L“)³Ð£j{Eq"®.À©Q,l%mH¿«4£esõð a³E\äVb±‚9Y8¡·ÊlÏ)øBEíêzÓUœ¬œ"—fƒvƧŠàH3 –·Œ¦Y$˜!$ÔÀõ@@ª¼á<¨6X-A^c ´ÑI$²Éª €©‚vwÀÄ0CN”çˆÅIVŒ=Î1¦^5 ‘!ÙȈ˜dHb²Bw2bF’¨¬Ð­ ©YVh\„/«„#nŠ!‰Åáŧ ÁÙYk œ®ËÁ ^Yí+;c¸‡†û-ۉŶÙ[}¾wµwÆ` öÛˆ™cëj¸Ñqj*v´ò"ti޼ Š[\£–ÑP +ÖÉ-UV‡õXWj·ë¼+ÂîT}¡îúh5ÔĬ\Wz.o vƒH•|Öú¤`<{ÉcÔ-)üFÆ‹^ðï¹]v.¢áµr»­Ü„Ã;så~ݽ‹‡·öÚ ?V†ZÃPÃj#C½e ãü¼ŠèîWFTg¸"†kg¸Î†·Ë¯TGVRÖ\—gÖjòûjå›÷.S& —Œæ]F”¨ìHªOm…:‚òR徑/L z Iºtõ(v/+éU­¡ªÓ g@¹Z6 (‚_äÄVä¾$=³¥ó±_Uɳ7 PP„¨ô‘‘DÞA®éhßÈ¥ŒL3Š)Þ5æèœø—ßî8ož­ÎÉpöVg: c ‰Q6¼è)£TÌÚD çteöw¾Ôž|ACN”1{Ê ÓÊ•eDß²ÊôòÁjñyú½ùQ‘ Cù½§+tМ™ä4-áIB…'®l©µí7ܨ£M=<ÖŽŠñ©2¬?¬$ÿ0YMä  ŠKÃÝV X"ˆ‰ Æù{3FÔ#Ž"3ÓÈ~*ÆÍ@¬F ÐYa52 ­p%­ð*Æ+_?UEóÑo jgî»qw/ܨXÓ¿i!DðdR·,£ÄEž2ÇHåv‰âo‘ÍìôsDAËfvøý¶É<7̼¦3l¹’ðP¬%UOH©æ$¢O¤éG“ñ“R‘À ÆÛù:óÔKÕˆÎjÌ|5\Oƒ•·Ê3ä•2Ь°Õ¨Ê‹[ iIÎ2x8žŒrtœ/ˆª%ND9õ ‡pöªXš1ÏRºßL·Ó ’_¬;•…r.Ã]Â^Dcr ¡!åaŬ̞.ù€ÓTŠªx*F8S)“]óAè8•÷ƒWSã)1zD‘ªGj\Ôºo:€Éê“Yÿ}2‹Ý@¸u’X¨ˆq£5€›ø2.ø‚ÅÂ=U‹U’UD³Œ¸šâ=U©Hiµjº0ðê%-ü ;Ĥ³Õ+a ‘N­S­Y )¯Vè±vwÖp®n×ÁΫ§ÅðdžA;çÕÏ{«ÐQðrä"hÝŠQ§µ È0BiàøFÑ‘óµHÊ(ä²JûCØ;$ö]%©…G4ÄCÊâ1¹ñ ²[D[ÙM&Bg³Íl"ä#»r]¥ºèA pïN“’¯ÎªD%ÍÊN¥¨=°Âê<2+¡Ç=M¢2GÁIÉdWWô0×'•U5ð½¡ïÕ „š­M¡Ed÷°5 ~™r>ÐÊÀF‹âhaÒx»V²–’åoÎnGŠ+AI´<¤Ýu< ÃžDìFìot’y’"Í“$ã™ìˆy™þ NeÐÀ%C)1k»lepTL;Ñe9%LôÂÝtÎ$\}cŠª¼ ÷š@©é}…3ZL1Ê&ú2ËU*D œ'ź3ìœ+oVgŠ‘P¨R•Îê“ÂÂ]2Ò*·È‰¬ya—C,òœ©‘JÖ5Ô(Íä’ÑìÍÅ *¬ýŸÿo:å—Î%¯õY'8ÆhH!ÚjNAgæsfåш0¶ ªÉl3=9eAJ ¶\žéó1…Ïù*ÛÏhH!4. =¬½E¸%30âæ’xí~ÉïWÊj p‹uO†um‚’Çä—<+š”1à<ãã]‘2”ÉŠˆ'ä¥;…z®U<GVQ_©¸>*Î>¬â¾SñŸܰ¼Çuû(¿ UW?¹{›¥àÇŒŸW£¤ÌŒlJõhÐý¯$bLè ¥€]HØÀ½3àa(ÖÀdÜ jëó `œ%Œ ’² ¶E[Òz‰}Sú¬ÚVÌP˜a)cŒˆgÎiÆñyU?\apÌ›À×L˜4Ìà0çÂѰ¬šV!2ëy9 ïÙ =F5—“4;Ð!: a’,'_.G¼Ê²V s˜KaW$Ôl\î+gÃüSpï3;¢‘sp‘ëˆEWçã CäLV%zm¦Vž¶ºÕƒOº‹*¼ìÏP>ý\ó®£m›ýF¥C²ô!­úÏNÁþ Pæ»TÉâtB Q%ZRï(9!dÖMñê—€A 'øEUÁ‘Å4ÍÅBžS’|7Ñ˸n¨T¦…ëÀèÑ…zDp¸.#/¸RÒx¢·šú2h0%YÖˆ Ütƒ²žhàÀ²ž |7Œ‚lÈWr\êö*"-Žñ× W bÖM¹±§™Þ-¡;¥{©•©õB¿"­U°x%¦•tŒD<*‹®4@|EóËÝà"·ÄTV¡Í»xË\­à-W*öjûns8°CdîaH ±RµhPáh¥ÒJݤa¥a5¦•ÊMÑæT¹19'Ô2ð_S€§¨¯Õ™£_Úˆ-+/ñEe˜á°Fàæ]ÈéN™³J¢Š§­Ze–o[)õ6, 7, ·RlnX˜nXÂn¥Üݰ4Þ°ˆÞªÃcàºQ¦*ž…6y"Ð<ʺIBå’iAYƒa¼²eHèB³Äª UøjC@š½­ø ^é@³ðä‹uXç>›É€¿Ñò ±ŠÓ¯LÞ$Ôt~vºD0(í™…m2 V§= À¨`ßÞëa¿•R?YÀ]|Ò úwXLiXtiXžÉðÈ#¯ñ®Ü”¬‹t û;Ä Å+èã!Ryˆi~1w>‚å$ýñ°¼÷<»WªŸ}³iFu 4¿çÑa£Û‘îåÿóÙtFÚøÙÄÿùÓOÏøÿ{õ,/ØüâWÿV¿ùç7¯~}÷îí÷¸¸¿¿º{#Â__ýùú͆øþóÍ›‹›«Wg,=Sñ?öFÕÿû§¿ö¦ÿLgnÙƒÿÑÿø?]ô׳xöÛ³ÿýÿMg¯èégG?}mJX­3 sšE/—"'1Ä—óïv%øÙîÆïéƒ72”èƒÓÿe˜Éþ#IÁäÄNbg…XNú‡ZNÚ ÐBôSõ â¦Àúªy‚ôˆ_ZxÙ¿Ú9§/«RCÁ=cîƒðƒÕK´ö¥Š'Iâ7j)„.T¾ÂªF‚´ËL«d–‰_ú…¾.¦„ú&¸Sî°$’Q«™e¡>IþÁu×:µ¿zÿq«‘j ëOÚWc$qš2ÚsYõVâ3»Y1 \Ö¸l@4{‡*7!/œ lÃs+Ñ>ЇUíSŽoA²×ÉafU|‹þPÓùu:=ôz¬<Åôä4éØ ¨ƒX“ö£iŽ!-ÓÂjk  >ôà…u-×0ÃHH® · =ß*Ò¼CM™ÝàO`ÙþœYŠšÑRžª-²­wa~H•ö oSÖ!['¢óH*eRlŠ Ê±|»v¤0ÿí‘ Òó®)â÷5Ƴa0=™ŒxúFÅJëHã‹–Ú/îÂ:;ÀßÓ1){Ä3ÑÆ? ¡¬Ž]Éy’ýÞ ¿=­õlÒ£R¶¥ªó\F¦¬q´rªQ™“AU,%’X&†#qÈaqˈy#e©hªaà æ…™-Á£ämE €w!©‹ÚÛ¬{(ØÕÙûZÁBU/ldâìãG†… d `Õ¡7º˜Äš6FbU’СWXQ4µa#¡E*¨‡Diñ€‚èù*–$vvß™|3@NH<_ßSSnˆ¥V bŽÞj›¢ }´!Da³Ñ­ «ú ©×´4:Þ‚œÚrbÌ_|kÑÌ+µ™ºÃXMNJÕ,žÅ²™°l *ŠÑ³ÉȶB´P«÷RQl·èYYU`Ђ²ÔyÛI§:“—’žïýÞ5œ/-x4Eótf¡ì¼î×°ëm‹ŽE‡ýÊåå³Í¦Õ0±À"ñA´eogµ·nl½NúÁtš¡êH8Cëâ)Ø«q‘±¹½–ïÂ~p§ÅþBТ¿lC4еì¶X"Ô­å†%±¢>hIøbÏ Dx^QÜ×}Ì'Bñ[ :à)B½R, S´èšðfB×É4ÂèìÙasÌÁ(ͤWYĤ1,]©±¤ÉãÊ3’ÞÔo`(g¾w,Qì(Áê|ê”­[àŽ%hXTMw®GKuQ*´b‹½Mˆ˜ÓZê[MYŒåA_qjRdÒGq¥( ŽüÕw”ÄH‰Öç-튵¨ù‹ôk¥ kÄu6™i^T6_÷òÂïµÆë¶Rί¥_¡zÐ$SÑW¡ ×$JÕŽ;ÚcÂíPQþˆýš²Ü‘~Ê Ìû ›Žhq•hMâT ‚oÁá¡ä‘ ³µ%±ÓêÒ2¢'­[ÝDJÖ@n#Œ ¡‰G€’HÞt‚ $Ö¬X®:[ôM¥àkiº U_wÂÉ„ßs¬‰Åw)Õ!ºRbã’è #öp £0?Û9B“% «¡þ­! MÓ³a¾“ܶrh%[íZyGÚ­ ˜ØyY‰Ÿ‹© ¨zŽ…N¬V¥%™­‚¨™@“£=HU˜ü¢³l0¼Tq_PIÐ/u,dÆö¶fý"íŒØ¾MMæu [endstream endobj 1051 0 obj << /Length 65536 >> stream ~òÐ~Œ<¤Ã‹$>“ÚÚ€rHG{Ö =‡ž.i¦©õˆÀ‘ØCël)â$Šfä¹¹ÕùÂc” Ð8=«Ù[Ôªº¢è’@£‹ÉªVH)¢l–’5PÅw°Ùú±¸Oæ*<¬oèlI8‹[†Ÿ0N¨"CˆûœÝòRÏø¥‹Í;·í&»çÊÂÖ™ƒÀ|Ëä CñÙì˙մ7]õàÓ¡—%3sƒä;ÑÕÓʦ=˘‰TM¨š*tè «Vh"Þs‡Y0Úð* ¢Œ«eg ”;W¤,Ä´©´ ¨!;]»xÂØ¢³¡Å¬ ƒ^™„Îëxh¶o¹(V$GU„@ss G ‡…14§ÇI$ϺԒ~ÃÉ}Hò¯Y¤^¯Œ»¹¬A`$í’.4™C9—èÙ ³Sɯ×'=‰ÇÏÎ ÄNuÔFH[èÕW´–$‘÷M¥#-üyê^c¡¤U­¿öbܯ—Úáhg±xÀŠ›ÉS¯wD4÷†ƒÍúžÓOU½q6áîuVÞh·˜JÊ¿€k ›yÕUì½­æ‚Òg'¸ò|ÍÄ€ã)Ùu”SзEEÃLzzi_'\r[¯Ÿ÷•&ÜcýbñÁ2s{} •¹à”çÕùr܈~—\)ʘW:—Ï^)‹Aö±ÀI`—â;ÊŽæ¢m³°y(ÞTÈm‚KÅlœ‚¬äüÕ4BAòÌqEÉ7¥6'÷;©0<GžaøEÕóGœqÞcµâfsÆvÊ6”nqH#〗vÌ™¢K>bɹ ¢ÅËâŽúÕSE Ž‘00& ã&kÀK«hŸ—”¥s­¦b¡1E2¹¥'oNs?öº·H§}©ÒÙ Ì'úìÍ´r²P<ÁL†LÎÞAÅ1ѯ·ô cgýäܤéb°Óšy ¼å‘°˜ÕmÕpæÚpwˆ°z(äSž0'“éÑ'äò£˜õ +[8 t§š_ °ûJ:@§.&µ˜Óˈ'±Ù¤ e'£bÎ%¾+í[eØÐÆÜ8Y|J_¦Ë¢@ã"#X-³Fmn^Æ66°tê8——é“(Äb€‡J:Nq U%£É¥ÓJÄ\Ÿ*l|¿8Ä4u…¶§&úÒ, ²0ïÚÙ— ʰˆO/Ê៧ 0bK˜’öÐAKg<—EÂMÉç…A™]x/6ô TœGÈ¥– Ö);\Ѓè1ê¨U'ÝsÄui³5gJ¹ê„¨¼¦Ê[æä<öM¯¦b´h l‡’X'€“r_ª0LˆgÛ‰šˆÌ¢,–¢œó³ÏBc4òìì\f×:ÚåÛºT‰©¼U3wŽº=¨]/µÉ Ò)êS“wkBç¡"ÏU-H¬gD0")â05·‘}Àl1‚°$¬Íf£k¥ Î=-¯Í½šÐ¨Ô¸ªÂ#´#á„PI¤áÎå©W¶s ´¡/P¡J¬ïeöƒé¶õ8øÈ! Œí´‹VäñÀç(/l̳!&Z=;Ùµ„*e5®6\€D|k' nµD,}H…¼» (8â£øµ¦=r`Rwm[ Hð숰jhÊPCéY‹3ƒŠ£EØP˜ÀFH ²&ñÃFµB×À¼»˜*‚aÜΰU×ÄΓ‰Õb~2¢7bRj@Ÿ ’R'ø^Í¡—%ªÌ~hY7ZG’€Óó$šÑKâ_¹Se‘(˜D0J1@Ø| yþ},9M ‹…ü« %ÜUÑC•÷”H‡ÖúfˆsE“¼ùâ쀔ŠG²¼µB¹ákŠˆ#sù[Xt¡ŸoìèàG1VÔû êH>ÜàŒÕ×™«‰€O@XåÚ;¼ñ{®Ê)ê%¹A_êÄÕù¢e ¸=‚UÙø¿¨8áì­¨âBb4^z1H;XY©]6“ÚU“ YWáBcg<Úl‡œªeqágP{—…ç¢RÝóÑÏ|DXmž$\Sÿ2Öá.‚AŸ.BbÝpÙ)(›ÈÁ3´¦XBÅ‚3»å^I²"+y Gœæ¤²ÍfËÎ) #¨€Ò¯JdñF¥s„©P\饊'ót§lªâvsÛÑaù³¥ƒÆ¡À°âñ 3 U;rðãqeSû³º¯*7 ЃZáNôÒðná¿ÕQ]6MÁéú¡Íav9dLBÙ´9:5è³û*ô²eå‰,¶ b5kŸ9æ*Â9Dƒpe†(`2.÷<—Bœ;th® ‹ÕûÅQ8ÓR}SH”°†³MÈõôRÛÄ0ˆ<}*;r&«€ÖÿÊØï­©0D öªƒÂKâ í*;áBFdœ²fv'3KtËvµ탧„܈(Õë©”‚ÙÊzQû¾ sÛ†…±8`ǪýL¿7°‘îH8ÃÒæòOô¬7­=Vp¬+kßéZ®˜i'1ÈyÇûbnÙÅOO¦jçy5••¼Ã¢oùªOFˆŒÜs@¼0¿¯æ/FßZ úšd¯R7š4Жˆ¯„rể=6"ÄâÖ¡â÷5"„â žÒÒÛÖÜÌö[:Âd¨* à±Ð`ŒÈ9¢zî‹`o‰4`É|{jKÇY¨X³ièÔñÂ4×`¼0ða}'5ž¥Ó IìVŒHë›ÍÄà%Â%\\ „Îvv²H³~¨âà·´°îü@ÛäVì¤Ùd›tÈ&}o1¸Š©®½½ šM Ämè@æõ váØæf3Õâét¨Î²iVZÏð…v€qMui•…$:­|U@¨¹­Ä9[”ê Ð*™"½,˜Yae©o$_Áj~Rb³‹A,”þ‘š´Ê9±1"êŸÅ Õ Qå—*–d¶_9×h'Í='ahˆä.hY FáJ uy©Ñ€èUp”qp( Ø N*Þî°AP´»n„âÉw‰´.ÃBAõ`€Ì`üÁéËšÇ%ɧS-RèºHhX+þÌ3lꈧùbÚtV·05Pq­môΕ %E8[CÅ9´ê º5çëQQù¹cØÁlåÅêö a ¯Á[¤@t“ùuY—“r²O`dÌQµ ëÂbdíVuÀúŒ:!5˜.í—{xŸ– ÌÇz¢RØE]-,|ú}ZfžGz6C«EfUB7û2 ú ¿`|ò2z©ÚI1o±YoÄúa˜$ãFAªzgíjÞ¶ 4¤>˜zÞæº¥…ãpjsÇz3t½30-A·ÈV}³‚«à}¶ †¯]= VBYqÞú(WMb rD£T"¡fÉD‹¯¯ #Ž2û*TCèw=>øV´k»‡Ò"£©# ãCÍãYœtsþÍ\c Tk뱤NÝ€^é±68VMáßÔwob[”[‹çöl*ƒgKY´«BóÏm*×Ãg/[·´óït³´š1ŒaÌ:3C¼°_˜DNÖË/ǨÍHµ F-¯ÞÏîbP¼ÄÓpÌJ˜@ÂÙZY½[íêp˜ <£ÀP§NPJòbS€­áBJa¾ŸAúµÕ®¾èî'`Ì+jº1…¼ƒZ׿ª%5ásš‘šI-ÀëÓhàf>@‹«IfBd w®ó Ó£Ë íÆš"¶\·Y#xzŸ‰ŽúàpqA ÍôŰWõ1B—Qȵtr¤ACyÄ~d!ùj*1éûMôü„W÷HàÓ3ˆÊ¨ÅX’æ`T”ÛL„s`ì²y² wè€mŸŒ—‘ÊÛš„­NœùÝâºTÜÜ vbJÅ<®Ý >üh'‘%rf‡MÅÔX­KsÎTúøó×%b%ÍŒrGIy‰ÇÌVŽq˜(8xj=ûºª&cîe¥VßÐ:*uénà ïX L”¬|ÙÀ°U²ìÖ0EZŠ;cn50N‰ãËz• Q¬.Cu’xR`oTv.®Þâ-±ÅÈ€á{–ßÓ‡]Êù”",–Äg?1 Y:í¥¼HÓžW²Bz’[äi ‚ˆŸš}ƒ[„xyL ˜-¿ø^^k=±O°üKce–F§ú¤uÜ"»!:"¡*ð¥#žav;¨œV°q’hW-° O"cÊ/"¨Þæ0d 7˜÷º Ö.h®Çm (,3 ³”^6ãm‹b*))<[\bAª k°('3ÈOK—cŽË+ TKæ‰(”Z™×  ´v´°ÔàÐàbAŠÉ•SÄbÒs]Y13*‹°AdµÜ”Ñ­,2L¤qT㉨)ül£Q®h'+ÆÊŒÅ,—š LI6ÒßžË\B~ÎM¬F-Ošö„>9gL(ñÓœæšcíò󰸹“>8»*`e³p#G //פ%ú¶e¯Ä¸0'g8qs:¼¼ùôef4!îŠl"æqAÿ“G¤•õòY½9ç£?-"‡·½«,»YÅšWÁŽè,Íka¨6Ãc•ý‚~Œîk-Y´ä1¢ Õ€m{h ϰü>ÚÊ2fïâ-ìäPÚ‚ØÙþ˜dÒW&ÜlÀ3hADØn.{`áãbÚY²œÐ2UÛYJ‚³Ú#Lp[Âæü g…y›Õ©Íܨ–÷kq¢A5ÑÎ4C†½#Ukà}6péqͲPZGZïìrÒíB¼Ç‘œÑíLmƒušÊTFÞ²€]„6>ƒ|”=‚Õù ý”SH`?çn%= ©ôŠ-Ý‚^Ê6-Ž^ªügöÀl 3­0ˆÕ`I…i‰­BF a|°E[#”ÕÌiU‹ÐÔ`PQ®'8!+–|Ê`£_Z¦ýÜ*8Ë4YJ*ÂPrVÈ‚ŒÐuÚ>%k?ÊnkyÒ|ò¹ÐfY¤à"XJö²žÆ3¦45¡^“0$ =;O ¬º .¯¥©¦T{"tÁ“±ƒîøYá „ÉèÉVw\óT'Ï™Á,þyZ’¦eRiØÅ¢X”Ä×'OÆKõ$pèV9że–Böe$ø2¶ÜGêW"–uWLwTÏ®eFa½„ØN…b¨_®‰Œ³ÆêcÎèwo®žÝ×ÍýØjý(·Û.ºN'x«òç­,ÞjøêD”‹inÜúÚ»Ææór0àïà kæx+ð8rñG\ÜMy#s@jZ‘¿T“²áæo ŒægÍÓTqi*/"Œ»=xa]ÓŠß8Ð5 0p¶$}ʼXÂÜk· w‰¦ð!ºà¥ŸÑ²/UÕZÐLós.ç.%uŠŽIå™ t3ÇK¶$ð¨¤B\ˆI£ñÑ”oªA£Ž“´(øPf/Šçœ+ÀàðJ ßáJiЊRµ^ ª‹¨6[z2?Í´hš ‘Íi5 òœËç&g&ß™¸«NXCœ(WKH|çsU¼’` "¸›‹áLãäD↩!]ó¥J]vn–ªLO/*9¡ŽØ™\*JZ…}I¿ÇÉ’+S´Ìh¶œ©…#5[BY\`Ô󌄎rØŠP WÕˆtÔ¬Ô™Ò­h~ÔlÜQ²&Ϲ,#ìHnBu×ÒØÒ@’Ê ô&õ&ä9Ï7JŒª;L “üÒL‰˜“þI¦_MºMÎÁú´t ÒSä}i`™•"`z2᪱Œ!#h’Ô«°íxÈɬ¯ Æø¹¢ß,~©â¤±Òøõ©lÓ°‹âø»ÂìÀº/Ÿ`2‡R±OÁëd5½)£ÕÙ¥E¶š±¨œJ£6gךŒEŒ.9- ¤ObËÙd¥íÃÄK•(”°>PŽwþ¢æliñ èž›C³ŠÈ W%€›Ùá‚‚‘sÙ×)ª’‘©.F„ðÇŒ„¢úÄ%Ðts±(c4e¬ áÊŽ‹AoTi˜u FÍ¿ÄÓ Ps«œIû £³‚x3rY»‰Š5*|, tOµE°%ø¹©6å3~½,ïQÕ²,¨¬Áà`\:àº\"³¶Î í Ê„ú¶8qÚ¡îjN›ŽÊÜÊ–6÷ŒJJè!˜ÀÉ•Þ44œ¤¸‰}”íŸÏ'C«Ýsú¬í´j4Q ­"ŒÉ.ÓdsSQS5Ÿ—*E„)Z$¥Ï€„É‚>¥H$_.î¼ød8/µ6·ë š»[ž—¦£ÔVùB¯íƒ˜±fî7ˆq( âšpÅPDÅí” 1™'§4”w¬KôÒÌ—²± »jqADaë${cÄu’(†ìaX¥$Íе™Ëe#í⡳åúì AuqªFØLƒÓÉK šÊnF8Õ"‘²;ôÕ.B „ˆ5ñ©RÙ“XÌÀéFY“»éÕ/´k+|¨$±:.˜Vuy<*€‰î|=›’åí×`_!I(]~,9³Ñ³Gç3r¼a3m*Œˆ²Ê’Ä×Ó/Î ↡ൟ+Šòÿ!ïúC~Ö;lH½»—ÜÌø©SšÚŒyS¶ÁhIú»§Ë|ìô›^wçFàØAX8™Í(ÑvçäÞwìPd¢Øìgt 9†IB"„ ‘XŒÝ޽ÜâçýµÆÀHøÍïnßüáîúÍýõ›?ŸŸ‹˜‰¹—ÿðìw?п¸Iþéë?þë¿\¿îÍ<û¥ýyöOÏ~ù§ß¾üÝí«+úó7×—÷×·o.î~zß?|uö»yý¦ÿÓyïÖÝõ·ïî¯ÞþãÙöË_ÝÝ]l=qùýõëWwWoèßýÙ/ÿíÍýüoô¿îúáŠþí¦_üãÙ/¿îͽùóæ?^¼~'ü´ò±Óýµ?q?Ž®ç{¸ç{„žÿêß¾ùÕ뾿øÆ=8‚ëWžùìcpÓóÿ×ëW÷ß?<}ì8ÇðýÕõŸ¿¿xxî³âöÛÿsuyÿëÛwo^õþýúvmÑÏCúŽ¡ÿ|s}ÿöáqm<üß÷ñœl÷ïî¾}p*î®Þ¾{½Ç×ÅsŸýëÒ(Þ½¾zsyõàXä7-æq¼¹ýúþúþrí4˜Gñ–ûë×W{,·?û˜üƒƒyóîæ÷—÷?î3–峟ÿ2íªîƒ£ùöâíÕ¿Ü]ýßw}9î¡l=¾ÏÙ±Òu÷ž®?xØ]ýÇC[hîó{æýO¯ë7kKp©ÐCŸ}A}}ûîîòê_ï.~øþúrì3ŽGÆjÇæ¾ßþpuwq{÷ðæ'm/¼¸½ùáöíõý>[áSt€•‰ßýËß\}wöÕÉ`:L[S<L'ƒéd0 ¦õQ|wwѵè׿»½~{2™ƒy\“éáü ™L»ïNÓ‘_'‹éd1}Ø^8YL‡®ˆsÿtm¦½ú~¼VÓ¯¯~¼zýõ÷¯nÿú¤ƒMñ °öÇÛNOǼøöõ»µsì ™rK³7âéÞÑkáoï_ýæêÇë êÉ>6ÅòéG»ªÿõâÝÛ·×o~½¾ÒŽQq½ýî»·W÷ïéôÚ{mò'¼/^í¡§¼z Ee®ï¡¦¼úÛ#nßßó>xB÷íW—¿·Öã'´k_“6A˜¶ËÛ×·wÿô×ï×ÍåñÓë=œgúØé$ú0mñáéï‹ïÝë‹»·oÞÞ_¼Ùcyíþâ{ëŸÿöÃ훫×ü‹Ï>®‡±oßÝ}wqyõõåÅ^›fã駤埻©ÿÏ“5÷Ó>?R{ÿÜï5õÿõpïÿëµ€?Ü^¿¹¹—üinW_ëyòRoÅ“FrìföÑúô÷ýG«‡ü={óeS¿¾¾ÿÃÅõª&ô„võþÛáhwô¥{XMøËšGaÑuz滾f=-»îŽÒªûKØ£ëá8»¾ÇžýËclÙ‹»ëûïo®î÷دwÙÓ±,?ÀM¾ÿ±ûHŸî·Ww¾¢¹ûÕ/jö?]Nx’õsìI?ZÓÃ]?R÷Ò¯þí›··¯}wuõ_GŽKâNX’ÿ˜‡=^Goèïá´;Öóá‹ø¸çç&ß]¼º~·Ç>ÂsŸ}¯®__ì‡~R6Ûooï~øþöõíŸÖOŽGóÿ²‚öÈ 8Öét Ž¡Ó1D{øaäñŸCO…¿OvÕ‘Dç?'²ó‘ö쓃G~»Çáôûõá1ï~Ýã¬9Ö {Êâ~ÿ`7‹ûa¸ãÊâ~x‡Ÿ²¸?㡵ÿÂ.ãE¸ìñNWÞ'èûÃÓþvOð8PãŸyÿþpdëÅ÷oÞ\½þúêõÕå^¶òî/>ÜëáXãk÷vKüæúí¯/.¯n®ÞÜÿö⇧tU} Ô­ÂÓñt:žÆÇÓI}zÂÇÓ >ާÓñ4<ž–aŽo~ÎXÿÓ9¥NU×O;dßRþ.wÈã>í¿ãò‡ë¿]½þÃ닟¾yÂécŸ·êÅç& ˜ÎÒÃ@1éã¿ïƒ[<ú”2wæ¾òÓ™KýOgý¿_õ¿ûÿÿUÿ‡³§¤s{œ!N„{‘)ÜÜ®R$<Bˆë7¯®¾»~³^‰q¹¦~¸º¸ÿÍ>{cñè#|•ÅÅ{Æò˜o ’‹Çó$(.Rþnø-ŽEoùvŸêªGÐÞkGk |ÈN–ü1mëKTŠþý»‡Ë÷ýöþÐhÏÑ&ïwNë_íØóü,åÔqc´Pvõí¾þ ãöh÷÷Ã~¼¿¬E´]§gޱëk»eÙu÷]xÿe Å´ìz8ήï±eÿò;öâîúþû›«û=ô‰¿¿;íé¸Ý?ì:a½SÄòï bÉó@1K?}µßœœ¢”§(å)J¹}Lœ¢”Ÿó«œ¢”G¥ü’ˆøOQʇ,Äcô›½³ó¥|tç)JyLÛúÕõwß½Ûƒçüèwö¾9ÚÍý´“Ó\½}w÷]W¿Þ“FxãéÏ>œŸ®^¿¾ýëƒcz}ýçïïû¿Ÿ_3äãÚ~þò÷üJá`ôPxqû¦›áoö8¾v~ð”ÜI²h¿úóÝÕÕ›¯úqrõU7?¯ÿ|ûÕ×·¯¯î¿º»zõÕíÝÅ›U÷òSò3Ê#žüL'?ÓÉÏtò3üLe îälúÜ·{}8vñ_×7ïî×j[-?üì‹+?<Š«×ýÿØÏѱxôѼ¿¹f½ø%íšÇHüFtô—ºsŸÐ²~ûÃÕe?´ï¾DøÓöWìQF_këq÷`í=®þÛ]-ùqÍ¿8Êq=%S·Å?ƒwééø.ÔS!¾ ud° ãä»8ù.N¾‹“ïâä»8ù.N¾‹­±œ|Çgä½~müÂÐ'×Ë`'׋ôák5O¾—SÎîgþ&GëI:¥ä?þæ~}}ÿ‡‹ëUWÖÚÙ{ÃØŽwW!ÄðO8¤ðcMÅßcÖ5®ŸRñOwÙ¾wÙ@-óaúÝÑ^h{k§»ìQº~¬wÙ‰Væt—Ù]ötÂû_ƒ'J™½:ðH/ÿ"(e¾þþâÕí_O0VÇ´Å'ótŽ™/#­ù‹H ~˜­é”üŒï¾{{uO¾»zµßÊ:úmò´!«—²{õpµD~滾v!-»þ·GÜÆ¿çýð÷¡{ÄÞÿ¢”ðcùŸ*’ò>ÁÉ::;èÜ¥_<¸÷¸ãÚ«ï{\A{„¾Ïöçæ3uqzøüõúÕ>¨2}ìó!ì1†ï¯öhÙs'OÀ‘o'OÀºÂð¹Á›'OÀi¡'OÀ±íút={týä 8žKñä 8Žïpò|‚œ<X¤÷û ,ŽÖ=YAãy¹|ØÇpôÊÝc8Úuyùsâ]>7gûÝÅåýÅëßÝ^ï‘À ¿zhhû³ç<}}¹æ‹ZÚ¡ôØ\¿Þ‡pbãáÏï½zIùæÝÍïûüqŸÁ,Ÿýü ÐçÓÁ|{ñöê_î®þﻫ7—{XC[?¥3{ŸÙøîîöfk‹Ÿz„Ïù0)üýí§Åí#tþDærd.'*”õor¢B9Q¡ìŒæK¢BÙç²ÿ»aBù$“ÿxw÷í»×}zŸžÛìÉó$ìcЫQø÷Lpòµý_DNµåA¯9†Úò¿‘y*-ÿÂ1Ǫ¤<|càcíeìþâЯ{ëŸÿöÃ훫×ü‹“Nù4tÊ'¦±œ–“Âò*,_ëùyÒXWcùBзV,ýHõ¯“Ã÷ñ7÷Þåê~gïíñ=Þ]ý…àÃV þ²I_tž9B“ð/k,»îŽsÖר|–]ÇÙõ=öì_cË^Ü]ßsµ½ýé.;ÝeŸD½;ÚûlïrºÊ¥ëÇz•íq ëU¶G×OWټʞŽõT…ë8¾Ã'¸üžÀìº<¡Oÿ /ÁRE¿ˆ±'²•B¡§bC?ÓXN•ÇuÿkÿéÛ÷àžÐIü·ÊÑÄîlÒÿŒþ2Ƀä¿ö8 ðÜgèÍEoêaî»kÍ€z}{÷Û÷ èwþ—•nõE¨a'â€cÚ ¿ÿ³?‘Ûãsó9=¬Cmþù)ÿóoerqÒÒÿ/‚õ#¦#‚íoíytj×ÿÊ®Љu´ÃíQLù¤Ò~ÞUõ§ï®îþåúî pø|Š›ãéÄ1ï/¾ÝcäGí¬÷g{¶y˜ÜÓµñðãÑï¼{sùïOèTøVÒór6}©ké_Oké³®%÷åK¿~,ˆ›”ûwoÞ~·úñ¬iê»ø—¿ ½éCÓ(ŽÖuðAêìÑI'ïÁãoqFPýêõëO°¹ŸŽEñçÜ —÷sáò>ÅË?¨âÈ/~õonúæŸß¼²Ê#$J$ùæw·oþЛ`Ò„sÿúêÏ×o–ÿðìw?hüO_ÿtóííëgÿð«»‹o¯ÞþßÞ¥gÓÙ¯úÿô×gïúÿ÷ûgÓóX¦TëÙô<Å45ú£ú|ëþŸþGœBóž$xÆû“;ûÓųñ§Ÿúÿñ?úÿ§‹þzÏ~{ö¿ÿ¿éì½ïߟ—ÚrIhg5OôWëM·©·ÛZ$q{^û Iæž×X³È|ˆ‘…á¹›B"a}îZˆg/´Y×R qz^Zig$ ÏK–úˆz[gÿ‹Ÿ-Ï»$ʳS^_VR©Ò¯§ª/«.ó“åy*>ðËZÿ™kÒ@~JáG{|LÒhÎÑi£!'OBÿ<Ç)Ÿ]jgcªýÙÔÚóÔGÆíOôÞ’°w ÏB÷<5ÏÂò<'µþ¥¦Êâú<†’´©æ&/SÑÎd_>ûލýgnò:‹.{þ Ô®wŽžwþ¹Ï)£±l ýóVMs2ÉòÜó¦¬FžnsªIúàK¡O[k{ýÄ Ï'—?¯“~Ü¢¼*ö/Î3Û_boÿülŸfêxOÏKi.ʼnÐ;ß´)x/=pSÃ$º>_HìúÇñü²>19†,3ëšö¶ôÎx¦–Š4Pûx¼+"î‹×‰08Yá¹—^íÎ6>CÀBr^–ߊ}(a!Vav…Áóƒð¨˜†)MÖ@àO6Åþ•æRÐîFŸæjñN¾dŸ™›þ!rJú²˜|ˆšúbLº>r’…Û§!FŒl sãB¬²}ÞKm ô)”…Û7-^£2¹}å³å|±°m /› ûiñìô<÷żÕj_Ôñ­”¾\Ë䤷­dy–6os;¾õÅôSßOÈæe•Æ©ïTþ”%ôö\‘‰ä㊄幫1Ë—H>‹°ÚÁæå,ã/Q’‚}M‰To5¶ /«Sÿ¾ü%J”êNu¼ÿJÆþëBWBÕ´2•)Ó3å7ïôÜÑGÝXå½³-V¿½#z³…îr÷ôô3Åmî³>]A‡µÜ“¹=/¾%Y¸Ag‹n£¤½ö#îl8Ý/ä;ä¾[ ò…síËõFÅE?{n—(‰|I",.V#Ï, ©+ürêÝuz;ôs^ûåSÒó¶¿2j¿ú”F¹rbß$úû>)èõTû²âwõëÉÉ•Så௘é+Ê ÒúYR¹ÝœíÀìG'OAnÒÒòp—Eлm×€×OÐåió¾èÒ©¾y³ô•Õu·y õ75~ùò¾êSÒÏ…¼}·å¾\¦¬—+okö£6áŠršì~(ÚIÿí]×´~C õ''ZXüÒBG9È>U¾ø$«©6™çeÛóºÅq©Ÿw9Hy—q]íÛºzU è¨îBߟ c’…SsÜkׇíŠÎZ6UƒöV_Û:Eýß_²´ß’¤Jpw[n¼÷\–#7ÉÒûUJÒ%’SÕ½çú-5á»…0ñ>£«MwN—ðϧ*+˜ÛäSþR§ËWyïUj¼Ž6Ël‰RûŠ‘Éî‰^¤¨L,¦S»NEoÒ–Hû )àÛOî1=À+µê÷>Ÿ=&Vad%´ K“˦³Ò©nÂK\WÙ…Ígûù‘ùôK¤¸Ê ²õ³µßŒzP.Å)öãƒwWøÛÒÓ™í:?spª1§,Óúù§"çZMW¢«§ªæàµ_©_"²:i+MŽç;Ñ·%¥/È>oX\YÕûI•ëì±6iÇW={GYŸâc•Nµ¸~&ÑûNö•§ ÅÅ Ú 0Ul»¸ZªÇœùô÷CaˆMVq?Tûm®çŸ8—:Uý¢Œò*OlƒÂºu«V_±7X ¡ù ¤îÉ*îçjÊQÄ—8ÝÒ ãÒ”Ö@ÿF ¡¬â~^7¿õ,Ùb¡N}'²°o.?éQšÓ4s}驾í³ç}’+'VìŸ5¦­9htqêÕûtóËZ?¡§Ü‚Ìkî?`¡7ÛÀË -]SEÛõýÑÌV—§«í©5(û‹–F?Q¸cýàî/Ô£Û{Ö(«ÍMï®ÐŠ,÷K_,·¤ÏöSB—¡­‰„xUŒ+rl4×7³«¶ŽÅöì÷II.aÅW1h»â½ÛÚdçæ–ƒ|^¨b’O#úL0°úÙλƒ÷'}Æ϶ż›_n‰û¬.¨éüÄG„êÁzHå¢g Ýc/ÔÂR€ì”*wJ_^¾D=äXñFsjz¤óªö¾]œ2: Ë–„A6Còy' ·/ÛܯqWµh»Òžy}÷‹Ê¡ýª<…]è •™íÍ&>wú‘ßµ¬¬‹#¾*û°Ô8ê°«ˆrv÷sÁ«¶ÑÜ)dR—õÙ~éð¼ô^EÖé›#u z™ìJ·=÷À÷å“E‹éŠeâÞ6OZlÑ=Îû² ­TìÆÉ9ÝL*©é·åc®õ{9÷³WÞÕWŠûïk ô û;ä÷$nYÅ1³MNÂn&ó°hû@æ3ëž]îŽØÏ_ôIU!I&€DYñ©Ñ _DÙ˜h#òûûÙÛ×½ª]…à¾Ò=“›ÖGYñ]¥í“ ÉÂ' ÐàõZïûŒ÷gf}ïÞT ²ë-Þˆ]8AåìŠSï-Y0¤.ø0qÉÉ2éÂ~$÷wŸÉ`»õéDXh'Ë'è#›ØÑÅêC¡ÏÕ;TE¨çtó¡kw¼ŒI3¡d5,Ù¬¾=MD¿¥—¾)ø@¤©ëÂþµHq‘#f‚ÑÍ“~'ñstXð* ežô9 Ö|Ç$î±¾83ß5höGmVÏ£Lª+,­+Èý^«2‹¾6§«»‰Ï,“!ƒ ¬V>!òâèk¢Ø‹Ð…¦B±ìXH'² ·}ÜäåÛôÓµŸ‰ABš¢n{¹*hÉ,|qAž`q•á’З Šó”2ΨÊ>Núnfé£î ã¶ó çJk¦l÷-O÷ ¨Û­o– SÙpiÄÄöH,ëó/TíÌbâ÷á–Xœê©ÉH÷m­¯²×±™ýè*6¯ú$‹Gßeu&™ 9Ï]ÄšW›OÄÝ~ÒïÅbU.ØIï÷r'±;%y]|'½€—ET\ˆw…Å„¢÷²0Ek >eiyƳ·wž×q_SÙë2O!µÑéMÕÖÄ]ÕŰpÉ_"›¹Ûää+úñt1^qýGº•Hér“Óκ  ÌŒ)ëBbŸªî)‹ Ü…jTõöÃ$ß›\¢ ÷f'Ý¥z#²ã³«ÛŒüßM_EŒ|¸àÉNéæaQm¸áþ!oƒ:šHóžøÛÐlê¸HoI—!íߪ⦈ƒÖ»ªZ>)éÓ”e`AmØ~$NoàI€:½|Q9æ<Úeñ” îw·ºYÕ·‹ˆûüp¡Ú-Þ÷BßUüq"œ~Üß î“~ÛéDJvÇH\¢I.jÏô²à+NEÆ7 Ò…4Ñ”D½C&ñV÷¹áWÈf¤ ýR§Læ¶ Å8ïSÛímµL]è«—{•Š´êĦéÍ'Þ¸…nVï`?$¹Ö’(/ÔýMŠœéͬµ:1rÈÑšÒÑ‹ ˳Nò2ÒôÄf@—†Cp8ŽèÃfL“S‹6d‰êWbã¼Èú¿c úiEžŠKÝaâc¥KL~_'ç è‘Èîjêrð¦vöïE%¥O]1±j€ˆ„!Éžgrz½-i$¶ìØoÄ÷Lêûži^b“SÖ“?n* !7àÉ1å­gû—u²b“yõ{Õ\?dz¾P/——«™¯ 1`&:ox‘gßÜD†¼¨ãý#»®£‹?HotqyñgMôe‚|Ή>¿ë¨#GÞ$^¼–dYûä­'¦¾4ÕŒæ;¥H‘oU¿`›¸º6¦ áiö-´ÍgKõ¦­ê‰ï$V¡=ð¸2¼è¢]ìžÃYÔ¿¡ìÇ~Ó¡@ڸ܃âÒsj2Í϶$³¢B¶5â©&š·—ºJŠ88I³˜ä´ *{ŒHˆ[X±¨¸f>Ç—Â~@xΆëHBR4¶RðqúÑw£Â¬ß¡k“!é8(À祆xhuõ™÷8DuXä'!iËj7&(Æ•Ðb²+y°¯³Á’©²|ÅFÓ7õoÐ&µòù–QI‘º_ŠºX©Y]Ü´Œ(H€û™ž•H ´:YÜ‘î[Z…#£$ ýž:ÃDymTµ=y:§‘£Iï|vȦ8ºH˜’s‘®÷¡,ãMQìB,Xº\‚S) ¼ä۵X÷ßúAÑÐM0515 '®gi¨ «Ú±RIÖ¬“ƒÔ† ú'ÞòŽVéH(ÑaºE\æK—ðAzPäcJv½ÑÒˆ|k÷õ÷6]Yµ$µÝµÑ**™Úˆ©Ê"hU¬ô˜h¹égÐC–Ü®ø†¯mÛ¥¾É¥¢C%³9ˆS©/ætNNÔ«Æš|“lBr׋“¥¯õ~/DyÒÉ^ a…ƒ"ɤj^êªJ%è^™è"a¿™k7ÕÃ÷DÂ>óò´  8«‘„õÁá짯6£Ã‘ÙïÃØt «úßçóy¬E÷…3–NgYÿAÌBy¿‡2LÎ~=mà$Ç íõ:ìnA½P]?³˜±“ÌòŽMýÙ1•û´Ïb·?à6P÷]²1 aCû„ Öi¡p˜úY’騽»zŒtw‚~É!{ …Ú÷¥‹›x#*b´ª\褴E‡H ]q/ÔI’Ä%C›Hϼ)ÀGÞWgÔÐùdåÄ!ˆ À+y1 ÅÞsr¡OÕ¼Þn³Ý)ä ì>ûÏg¿øæ—¿º»ß@>þâ›?ý¿ýý·wýÐN7ü⤉OÒ¹CfÅ~3yú ™tù˜Ù/¾ù®ÿ—béÜ]“~›ƒ@Lø4€Æ¤‰`cÖÀ^À1yú è^xxL>ÎùЄÏr¤‰›8 Ô„îD³&>І&ö£ÉÓÁÑÐÄ€4û¸» )ý¸‡Á¤¸‰ƒ€RÒ‰ƒiÒľØ4yú tš|˜CðiówÙ>ÝØ„}’¯røIZ8§& ‚T“öŪÉÓ Õð5>¯&_tÂG®ù&!9µEnæ(ÙþA<’»ŽüÿµxznÆÛÓu~Z1,;/|¡}z·¼{GH6ù‡ƒ°lÜÄah6ibÏ&òƒmÒĘ6LÝÇ£Ú¤…ƒpmÜÄaÈ6nâ l·pºMvÚAø6œø Üä ?ãfºìÇ£ÜL¥øxœ›]~tþƒu“8í&Ëå¼ÜG#Þì*Û ó&¯;õ†I;÷&Ÿô ä›,¬ƒ°o°3@¿‰åxþMšØSõ 7q Nš8'9 Ë ·ýކƒ±~N:q"Nš8'³|*N¾õA¸8nâ0d7q6Ž[8' „ã&CÈIa三ÃPrò9ÂÉɺ:)'Mì‹•“½°'ZM€—Ã@ÌIaæì ùxÔN²ÆÍ½°ÛúäÔÙÆÎÁ}zz×Âø9ó}<‚Mä"1Lò÷O†¡«Òg'úëªÝ,ÿÐïøªÿ 7$âd2© /²h´òƒÀuЀ×Á…rÀNôáC vШw@vf|<ÌŽ›íÄÐÝj'­ì ¶“§÷…ÛÉÓîæ Ür'ºƒíØ™/¼Ã>z‡øñà;™ÌƒàwXŸðÄësι@xâ¾:†·å ñä‚ã!¦q Oš8’‡»ôãAyˆ yø‡ ybsΓ&çI ô¤‰ƒ z¢¬ÒCÀô¤‰ƒ€zX@õlÙíÂõ þXÀž ð Èž4qhOZ8¶g³ó‘À½ycÀ{ò‡À÷¤…ƒ|bÿá+ü Ÿ4qŒOfâ ¶ÓGCùà”ùh0ÖÚp>iâ @Ÿ4q¤O8ÔgwÍÇÃú0ûlïŽÀ}åÇÃûp‹|<ÀÏ|*ñƒg缪Àüd¦ ç×ÎþáÏþô?û_ÿmö7)±Ì]Åä»7¯ÎÞ~ñÃÕÙ süý÷þÔWý¿ýÿýéÿéÿ‹Ÿu¸¸¿¿º{óûw÷¯¯ß\ýËíÝ×?Ü]ütu·xÞ^n,xÂ_7`´ûõëwWg¿½½ûáûÛ N;åaj;+ÛGÿù0¦º~<±AYsßt®IêJTÿ‹sßgòl ¤cfr*ËBFˆ˜Ô$ V$æ0,‰9>+BÇñ:fÑdHèÃ(hË‘ý€Ràz_¼OHäüágûÙQTÈqÞùIi ‘ÊZD졯°)†Å˶…Üê MÔ ¡hÇRž’y…íè~ëš±Ú¯q’’pJàÉìdñHs„3LtIЉB¸’_nB^"ñ,.)áY9JIÈ`-}RÀDŽînpLP»‚“éâdÉ‹]¼>몘|Ûò8Bû½\Ì$MUŒTríÊW$ìY˜Ú®0¶h#È 7g Ö#@:ü(+pŠUãi@7]s4‚OUA¡c¬›“BWD Xf&èºÕ'ë'Íne÷Œ«¼‰ÈT="!'gçÀêR$Ð/¯óZäa°hrô µJxÁ8¨À 2§Q«B¨Ñªø½…wdº®c[º—§-Ìð#Ž^©©ÆF³H‘XÖ*†Àz«¨áU¼¢*,ËèBF”œ³ï–3ˆÙ>kFF¸ÄÆîzV”ŠÊÄ]ÈÑÐmaLàe¡P› œÕM-*g&Îì@Y>‰6ÐäeYÀ®<\¶jD˜T'iâÔFž¶@+YLæËk³‘ÅMg‘dJŸÄdÛzK¾¦À—‹n!Vaõö¬bý åÓôJ•~UXøþñú²*¡vé,A\þˆg[ ³Z„ ý«ÍPˆŒæe-„JOéòˆxW×€ãb͈°[2ig!-żƒ6…½)±¦6…ÙÕE$tÂË£X_“6:k4 V‹—¬eûσ­¸a«QUØ 5U%²XÄuøB3§©èNHâ'H™W®¢²˜L~½”'Š!ºôЙØxû¬Ü3yZX$ÈrÎÿÉÉñPE³9çÀ?;ÔùêiI3õY-›7Ðy"çÇ?Nzlm°ººšä–‹HO§ƒSñ$+ˆÔE‰j2>²%õú4ô/©.äþ÷*V[Ƴ¶©ž O|§`@Ëï£%"Ü}"D©d’=ì¾!XÆü~/Ÿ]0|°MÈ÷í 0ƒ>(ö•¬ƒJ/”RFÔRo ù{m §9[¨ë8Eýà­-«vJ¤¢e°A&Á³˜p0üì$Ò.Œ’)(B—åMêø}ñl[¬^©Ùž#!ǧE¨¨üä©ÌÔ(wq÷™—xijˆÚ¤(©sFGLeÒ}Àê8+²6,.¢˜ÕÞQ§€þ½²‘T' $UYéYàÿÂÊ‘)v0ÑŒì(¾h¶Þ…NÂC”3¤†>A±›%™Óå ú ¾:ߨ+yÎ!uF1 –Œni`)NMð/‘ÂörsDss”½‰)Fk¤‚þ:6ÙêNÀÇï½Cf…lƒä—wœñéø¾JEšùOÁ¤܈6ªï¼™–ÜMŠ‘ ’£!ýçûŽ5Š–Õ‰EÈÀ¦:oø‚„‘ ‹zMÝYH½.WzÙÇPBá1SCÖMYÈZRn­I=#P`¥˜= 袨ˆA€"ŒMÐÍQRYÑ@hU“`Ùu'ɱÕÁ¸ÔsvVÂGhVó4s1€šÅˆÅ‡†œKr-MŒû#¸Ž¦ó8UŸ¸P™Àα ÙJ]Øœø›2âÀÔr>-ï_(‹œ¤'• U¡ª#TR„ܽCq­†êPQª@’[¥ŽýéBU;̓Qw£bÇÇ$‰q×î€?=[* $V§º¨ hÀ„A¼ ³ªhÿ»ÏÎB_ë®ÐP€¦O¾UºÝ)ûyTÿ,¼ÔÁÞųœ%]eΕÁŽ´(/‰¬nAóÏê¥wq!Þ~–Ñk"”Xƒ Ñ€‚ø7Ÿ…‹ÌBöØÀ÷AF¶èß©lµJ™¥^»Å§3 ’¾ðÛB,jÿÞºîšÚdÿöÓ²ÕíèâØœƒ™uŒj_u1bYø"t¤þ¹².ccÇúXÌžÉMá¼02eÊ»Y¶ýæ'ç™*ÐK–£×aÂ>SØÔlí“© ( ¶‰›xõ› °^óDbÃ,…ÿ£ëz$.Û%äIÞî}\ì¬Ë­æ çÙWï7¿•¹LwÚÍÏgçŒÄ<7Muk‹Ä‹g›Ïê×z­b¾d7>"%¸2G1–Oj<9˜²dÅN[Œ6ƒ7ûAHÈw†IÐèÈægˆf*/Ðh2¦ "“P 5ò±ôÓ³Í&¼dümö@£K÷ ¹ë»¾¬·™Ÿ£É„MêÚ‡Õ…ìø–¬õZvp@8.»e±ÙéBÅÖ”Æ}ö™xs¾&K–XLÌ$±*ÌF6˜b~–®V .ºáÖÆÙ|V7Ù¦P‡!†0|vØê°6fBñ;#È9íü|ÛïF2Ñù á\7¿¹CA<º)!ÃséÛŽMªðųå“¡­ÅΞc@‹õKÖ™×Ζ*Ä›#Úb:4ˆ´µY6_ö€Ë¥í6Àì7Û=Xç¾²ðÅæD»‹zS(éí&D³Øz»òp±ß±U¼¹üTøã³í>,ž…6·³0 öýrkYgÁînvÌ¢v³Ô„/¶z«í¾§UlR¥SÚ>¦l¸£5!Z]pn.ÛígtÍ[çã²yê“X³¸ÿaà5(bŒËVã\šfù,ÑwXªÓ,t‚Ì] ÃöE9E nîÆ Þå^ så‡Åõ î"y²”V·>âüd•ˆÛåæº8K(mgÎ&òXãæ#[~N.~î® ÖšhÇ U)ƪW\0>[ ÿÉâ: “xê*`(Ó>ì%.ô^é^ô",(©¥!ÜJÈ mM~ßW<; –jÑâÙY¯]UCð.¿Vq·§‹2Âq~ÖOp…‘Ð¥¤O²oíÎâ¢é¹Âtºf¡›kÛ,&Ì;0Bm §V!ìSè­¢„ã/›$cM¸ÕƒY¼è^¶!ÜŠüÉê°EC'€Ous)Îhœ…b0Í–¾‡v·…܃wžÅÔÌè¦pw°ó¦Ý|rb°ÂÅ`çVYŸ}Pd¥…!%t¾apÍî9ÏÜÁ„”£ ¾‚…‹Àõ$’ÅÐÿÊì"ˆ®ëì" —©p±{•Ì9©ÄWÅ­*³Œì>%7¼pĈ!`àDPQÝ™$öL<°áíg›øw)5«C1T&nÐ¥Tý…‡‘¨šú ·e샔·AFlø 9aBD2– ÚR,€þ’Ÿ;%t#qžÙCªç809.ážÝµ*ÜöâF„^H›Œ> þ@„!Ä´ð _>Û³ësè2¡ÆØ“Ü¡;°µô9z´0Ðsу !b1´«îåsÆ)0yéˆÎÀ@'…úŠ#:+ž‰EÈ9,ëBV¤…ª±Ø¥fÌB’±FÀ¾7ˆéÑ—Iu¬ —ÆF<`äj»ªfE,ÌÎxi×úßAøøû”K~ÞâóPb¢¸BÉ^ËE+=ĸXvâ¸]Š[±$Fñdn 9ì3 ÑÀðYøùç…ßwK“í !¯šT€¶OÙHéO ÀôÖœ{rÞ+b{ÃyŸ‘’L/Èg›Q‚¥ç?–=ùl[ŠHÑFà@Œ ™)$ö-èI”DÅ«ÒÈ€Q áVä@ìo £å .vÄ.Ÿm‹‹ËÂEèa)ôVø¡gÀ×D˜S^ Ñb"Þ²¼iEKHgÐXƒ$ë¢ùYM™_†T¼DÐ~Ò@E•€åòÙY¨´HÛB¾déÐø+Ix¹€‰’6¹?AÈpSH1Uç,RbG)Ò®Ìõ2‹Æ'–F–’)?[´‰’&œ¦Ž§,Z"¦P|sÂy’&I ÔÔè†ÜYï½qBIúm"B¾I1õ¡YÀi)æ ȶÈØ„Õa"à”2ï{bHFFÊ@K¡.·"VdÈhjñÝ¢˜¢¤’Ǧ‘α͘šE’1!n3R—B‚²Xtd ¶­yKêšé.ExJ/7?©)B’ÂÌø$Ò0/ž¬r_>Ûøèo ­YXgq7M¨‚–ÞXtD/¦ù«óú¤ô‚í]>Û«sg±J³˜Ó†B.uã̉ÃN÷mè ‡“D{·ˆ7…NÐЇ"1=4 擊²2„HiqØŽ…tñ¢|óFM,ҥР+Æf·TˆôX¬Þ8·S ¸§má¬xÍߋӃJÚÜ5”ªt=‘àœ”:¤cÊNXŠ-xº*ÄŠ„QS¿Tˆ$Ý€ÄjsHV¢¯„^Ò’eøVa°ßÎbÂn £¦,Z]B§c‘›R˜—}…t_øº%Ô¤}4 `w{DóA³ë…ØKHú³äØŒãIfS£”‹KmÀ[´8 J‰„’ÍÔ[Óf\š™ÐQu~”Ù~_j°¸ªK1 ÙâYõÉ“ Ó`´E›¢Íêµ¢hsÓÈ´yØH˜7ýŒÒ@|ž6<µ«–l¸„Ï9AE¨¤Hȸ«.eECG§¸ü…q_c™–Iå$Žª¸Rƪ BJé®à©f(7°ñ,ûŒ^ªXù»á5¡ÓH`0ŒO ‰?D¡kD»ó³ì_’v«òl,â@ƒ(úfÕt©ü×`è§eèN„ý±Í'Œf±ºw*“VM›>NuÌÁ½Ù€:bÆ=XL"Ñï´Ý)·(! wº%Ä$ªp{n-$L““„/-¦<Ä'œ3– 5sþ¡‚¯;_C œJ™{0‹5¾EBIëÝb\[ëŸÑü—‹¯0‡§H(é(sp†Ëbn³£ô¥J5‰Ì\ª‹ 2f ×KUùº@nˆy‡n m//…´Yä mîûo'Ä|¨ Hòñ2ͧŸ&š6ÇHÈ®äÍÈÀòY=·^.( ,ϲSBõÕ£QA•Y '¯&‹ÍÞú峿U_±êUÇÉ;s:ò‰¾ùì|#Ìg¼^Û7Ê$܉ˣŸ¹A¼+[Â* f›WŠðœ‡¼ÓÀâNb¥æK1BÔî4á1‰èžœäÞÞn`q[ç9Óú‹PÉY›› P-nkJý)°œŸÝÔðdžãò›Ê 24gY–tПm‹£:æ6„¦2ÍB¬½ØiÀ4©•VÀmC Ü,ŒJÞ¼PÄ’\J—ªŸ!{) øùÒ,Z¨³õQ gSíhžçKžx+”|à7ƒšã›Z2žuFÿº!dt2ØÒÿÏ·Œ‡Ö’Ûê– a¸ŸÑŒCa0`SÌüÛB‚CÂË0NÎ25³¥¥†ÒÖl/í'³ú!üqˆT»ì|ÃÞ\Xp”“ g6äl°.lH³äa.žoØ»jXÂŽ†xøìlÚng3ØR—&óº ^ÅòVSei´Ûšg26C¿âɸ<’mÛ0¿õÖ“ÉNÔ)B6a ßrE,œ!ó¨2²f•éžcL”³\8NŠp,n|/Ê£ `ž…ya½lˆSɻϚŸÈ68„Û~¢¡£)QdGæ“· )qªÔmOW¿ë¶¾6ìNŽÓo»àf¡1äÍž6ubwÎè…co½ ¡Þ:`6ý˜C`öˆ[¾‡Ðð1Š|Œ7ÓW@ì³{{àó^4 •Ff—ù¥zÂ5¹ÿâ~jËUu۳ߟ„;8üK& 0û”öP4 VÍ žÞ¦!¾.5JÑmÁt¶ÀAv= •êš³à%Q1•K Ÿ‚9ÑÑš•u [ò ]3Bo¹é$l 'å-Õ©m½ÌŠ,…;¹ b ó’câãe¤fbéÄlGÁæùZD¶6„slmn`C ßÓ0Gc78‡¹NáÓËo[2³3”Š¿v¤Â$Ío.$*Cš&i0Gb¡y KñùFÜt UrÐy)#ÙÔ\î…¢|ló¾9ß úZ\‡rê&¯RN•9_K”YIªÉà“FˆY„šß·ˆö”lœ8zlHúU([‹ QðInØ2šmÂÔ„¸õÅf[ýIŸåk“Å1&´;‡Î›rmП’ˆÑL{V8ÿcqÚ"6µ!tfî!Œã‹0û¤ÓÖñMjް+Bˆ8nãü_<«w…ƒ—L´±sÎÙbÐìÆ DªZÑ3Óž¿/ Ìwà†wà.~A0ý¡Ö&gôó™ËiH‚²&ú9ØOQBBL®$‚¨óÔÑߨXÃÑËIQ•PBUÁ¦BëÒ¦˜òuLN³HWàO¸=S\P ³š"¢]“†y˜jÙiÒ¹]¶„ªÙHN=9œ=:i5‘ePHƒ—Tá؆˜éy¥AÄl ñ*¾ØêAœò½XjàÍÝjŽ#†P¬péÌ¢ øFJ–"߈ójHÝ"€ß6±'­Í#ÈHáýÿI{wK’]Iô ò¶|€:ˆ§G„œƒ+•:9+u‹wý÷w‘4#¾2»0Z–•/†‡‡?è|©Gݹ¡;Ý,X©s`5Ù×kÕ]¤Aöƒ=Ðç&ËD½Aë4­¦M[ž&´îFe¶??f8©J3ÖÁGát5çLTó@b3;À~mV?ò_½S™îÜ{*#`ªè…ß“¥õÎsÎxz9®ÕÓþ|Þô¶ÜLísꙤ»òkuvÚ]:Ø®ªbÕ}Um Ô#Ⱦ¦ñ+o©Í«mŸÁ%7äà œyDx¢~Ü™£Bqó‹ìôù¦T5VxMeÅ#ÏŽÛàñüƒúš°ÝǶ̌Ï%@H/ˆ6ú¡š[=Ô'Ï4ŒY@G†ïd®Þ¹c)èÔ3è×Μ¿èþ™Œ^f£YÈÛ˜¬îÙ(òýGرœ=ú¨¬ìçžzôF¿ \3Ò¶PTã˜=8Á•¯N¸lÚô-èV¦bÝô>þù1Ã7xešTKªƒ@xT]ʤº.pA*Ï|¼Á ™¨WAñ¶WäUÆÄâÄ.p€Úh¦ßÁ¥é z¹Í  ¸ÅiÖ`¤4yÂ}Ní;ˆd…"ÊÎö›NƒAO}WNaÎF »½ˆ_‘°dóx?CU ŒXœF$ÏJ3V1gYí3òÔ4„aŠóø{­YÅ®4‹l¼i­*åMWD§D”Ì VäË빌½©(ÛÁƒŸÓï óåW ^ŽPwðïéÎÄ86YÙ= •7&D¢}âç^=«_XŽä½@Õ¾_í5EÏLO è¥kîÚïʪ%ÿß…›Å?ÈÄhs؈wℱ¨ª%¨íîäKKuwD¬ÐÉ=®ËßêYi”„•>¾DvI=äÝ~ôù1ÃYÃDÁäõÏJƒeKí·ÂÇ+MPÔņ!²ìRƈ~1è®BŸÔÓŒ5>¬ËõgêrçõV®¢¾†€=­“K˜W~Ì"x}v¦ÑÛ,€c¿kN9#NGði­[{Ô¤”ˆÊçoZ i¶jÊ5=â\3àÚ©àý”´XÑ'ÙSyŒÎ+ÁVȨÏ»õö p'ÓŽi[éXÖ=ðPùÂKcF©UãrÎWµZD®c÷àžP°øЭ¬Ÿ®M1¾ÊôX~„ÓP+ ì¶õ(€ó+´¶åÈìHóÎ\pP`níùüôlÐ/–¯ ó e‚J^„NæÖ–4÷ûú§á­‡eÛER ¤[œH2:‘r ´m:o{m´hA—o ú>úôT©ü´éÍ’vj+ zK¾„`¢ÔÑ¿/˜ª«€åx³úœØ’~áö’ÄsÛwÏ€ªû68{«àü#ú(€Ô<,cn[ -ø/U‚¹ê.(]D•±T;Tó³÷["IiC´ËÿñÑt'Â3HÃ~ýÞòõ&75UÝÚÿ¶‡WPUÝTòÄ àå<Ÿ~…hÊ£Øð­ôQò®]Áè'*)ó5¾>f8¯;¯Œ4mw]ùtÂì/èÚW,fxÇ»úü=vÐÑPøÛ›DOéš~4äéè—ÿÑ–Œ ûʇ‹ëB‚p ¦¹ÇMbpð7v|T35kXЮ H°Œd:Û [[‚bìVp£h-i$“!,Ke%'I–ˆ»¤•­`‰Ä*).ŸYsü?ËÈIC¡„‹ç²M áFôjÆQf ¿bnž3ªLù»é$¼‘iq)o$L/æ|\O³eXêk£Ø_XëñÐó0–“‘^N°¼suJ•¬¢f¾É(QaÒ¦Ò6,-áI`P+N,Û·ØËerÖÃReÈfôXjçã”ë`«µ–žÌ6 ø¶m½Bmœ§MVœeèR©¶¬éËima§Òäécþ…‡q> Î1Hû—,к;‹=¨ŽÉ âøR50ºI œ›¬ü¾üuTrç¦]°àóÀ…ªzçç_ýXõ²_¯©øÇô¸ElW9“²`™åÞÓú gì§AÐó¾t‹elf…ÃC0ßÕ*,ß)1e*„C}§àce…h*[' ‘¼+`£¬¥QQ.Ԡßpʉ[q€Mi¾®¥”Û)0@æ>Ã\úë;µZwÁŒòùgÐgoQU¨©øo—Œ_~!ªTs¹yèåIÚ~Öå à|yjmëîÃH§ÖÒow_½zua¹‰fG.Â#Ƀ Î{RÚt”AÌ»ªbö@o>y-åm†=@˜¦^r´-c¢šT¹}i[yÛ¶nñQùHœ.˯ ÷©šHþÚà¼f)Èø!5·,ïzÍ:3‚Wn/iÍgò|y+åD–(‚zæ–®òÌËñ;ôSÐãWÊ{íR¢áÉa¿õ¼×Wx¹l¾#ªˆý5V$o¾ìH0¼lÿpD~}Ìð@¡šºB©´”©æ`­«™¸BKǪŒ‚áूSM…T¾@–% I3ºEC‚€ßoð·"Ò™› iK5ÝO!5Z•Z·¥;&b¸þó1ãê±c•V!Ýš<ýÀ¶¥}ŠÔŸˆò5UùŽoþúè£Ð:V O°ÿ¼µe¾Gë­€F€³.ôššâòu¡ƒMWì"()޶ÔjéP·ÿ§E†»×*QøŸ°^6–Iéc=âB¯2y»P0_÷íÒóÖ) ~ü°s k$³:YP„l¤(WZ¶…ÂT|È \ˆ\ Ê.g@¦kìßœ’sÅ?‹ÐÙHfF&KüJºÆ!g[rÜdf„xµÍç’ªDÅG·¶®vüÌ„‰R<Hû®dQ¨-ØŒð19%tÜÊëFI =ê#u^Ø#Öcò QSÑ$½:޲lÉËÔΈU²d\À‘ö«‘E)Vkë+8H¨Ö,£R aBB%¤]£”C˜j<ÆÔ¶¨­Š‚ªé;Õ¬É%1v»u}™"î_¥â’ìŒ3ÊŒ©ÿX“Fš€õžåædÖ8øï·Þ¦Ü^áÛ×­” i[Ÿ\±XåÚz,V¹J‡P^AÁ ó¹òqì"þÌó øçšmëûý1·Î>Ôjh =ßÍÛÝáÜiêaé×G¡å»²Ê"ðˆDñ»¹Ë•F¯Bh¬jÑͲ6¥³Cåf ¥P›Zy»eûÓíÚ Ý“ŸµƒÏ¼×ÞÿM:ZÝÂ+Üi,,ã©ÇM±òáJ=Ÿ­-ñF®ðaÒVAÞß-^p£ëQ¦pŽ òúݤ:ÈÞVDzí`½—œÚÅ"Øz€ðM±¸Ô‘Ë+uô@á$ÌS0• «Àp(HðÁkÛêAáÙo¹R?µ-0Mt«ÓçÇܱl›yšbA(nÄÎùw…e¬™¸¤­(_6Æ=àšÞï®ú¨V˜TŒªk¾6º™½Y7ó..FÍN=Ks‹µ¥›??æ¶tÕŠ¦'R+¤ºLµ>w:;X¾Qlái¤€‚“¯4ãÊÕZ=?¥†_KqHr9V+c™-) `º™H#HË‹[̇Ú6‰Ä0]œ ³\[hÿ¥Ùàâ&÷P¬re‰²„Àä»…²îˆÐrÈïáá €ÞÆâ©ÿƒ¶$f(oˆðí•¥•!È¡øð•éL­h mQ ,~B‘ U‰òpIfÇH Q/!$åÞ¾ˆH¯úš~ÿz*˜j¤³2=‹~@Cå…Ô‹éwÿ¼£Jb Uf¥ô½_ íJþK¯7 MþÙ—¿å+Ý+/°œ+ùÉAc6Yû>! ªÖO`³U¹u¦•Ü…ª¥Îœûˆ_íx1Ïô²_óñB¸ h Î‚Ó ÙÛH¶™Va„Ûάj`Îί>àÅw##[„9òr $ýb1î%«%GÉb‚ˆÑâ3l üŒàWßÀ´mn**µÈ­HQm€lh[¤?`ƒ üÂÖcœë0Aäºóúß ÷D,°Æ¦(,@EÇ(ªz-q³~%[]ƒÇº¿·}@õV Y—瘷žoÛ ëSm=½EÕ"jïrèLÔâ%’\%UËcºÓ:¦¶[ñåUËMÊåa[fÝ6P\ƒÔiîÁÆZÂEûl±ÌzË=²{æì© ‰€ƒÅÝk I~ɯReö6"ã§·1z¼Aòõîcˆ‚ßís‘¿lúŠ/˜Z‡¼À¿ÚpIyòj›¬œ\#%‘ãKø—pûüú­Œ½-8¹>Uª€Õ?§Wè/!2’ê.EÄ:±z*œätd7Êš-ä5 ²1©ES¬bRáFA°æ}}ÌðŠhyXQuOëñt8)úꄃ´ZJ¹&}˜*HgˆôÕ–æWêBÒ»*Ÿ"iäȼ?OÎW–û%Lz:‘Ê/%ýc ³p†’àð@^z1 ²¶Ú/e$·iHBD!¯³Ì¡5\kZ:uA|ÃjŠ*7¿“ç²Q›²mQu6Qwþ ¶%@¤²å% ‹þþ HŠY”(¡€‚¿m‹š‚Ì*ž^7¾Ù]^Ô*©T£Ú²0¦70k˜v"Ú±­ðä¾N›wµ ^ÏOü>8¨ Í@Ùå¤ Od;À’<’' ÅVÛåœX-Û±XZ„e£xðž×wy$€”ò¥0Ï{oh‹ªbåcàŒ¤“ƒ³$ùgÍ8?‚xc‘§rè±Ó´Ã{€‘OþVsû=NÊÊ•q¾¯´4äKa»ò4©'Ò"[a»r%äR‡=ç5­õ±#[37‹O8—å‚îto+kìÄ×5LÞ‘%ܬeÞ¼-Á{Òæ°{ÝŠif êÍ•‡¶UH48ò*¥Ž^©$5p?—rÜ~mïÜ‚òŠê= I³@µ‹oÍ/1ýé.š¶ÃT*‹BêþîI¯ÜìɤÌÏ(=°¯mŸz€ÉÑ­—:g~)µ °”f¯Xg›ó³ÑTzæÃXÈ=oé¾j¯b¢ ›¦/Å5¯ù±ƒ4P[Ö=D¾M]9ÒÔjàkö>ÓàBó iä÷Ö{Hƒ¥·ÿÞ 2»vƒ¥¶Æ—‚êkÑ—ƒ—wØý^7Ìóânbfp}Û}´*ÑÀ¬dà"Vp]—2xRQȽ«BŽ;Ο“ De?áe–S à­˜Saÿè_XJØ’ÏŸîóT"èRQ`b²À¨€º¦¤‰•»ÿ`HéA®(så.oÝz©t™IUF¤çŽ#§¯;î ýp¡Ÿ{öñ$ùœ˜ð¨É$“×-bè@ËìAP)YǶ4"­»ÛŸŠ«³G‡b':'³#EpÔyoïA…Ç犩G‹Ä9¶½m{¸}Ú \=°WÀúƬ-ûÁlsæ>±ó‘Á賈Ùæs¤më9 ¿fÅ׃»äó *Çl.a“@I»ãA|*( à½j2ýè:@Žô )eóDè°ƒTÉäô`ãuP 4+Hö´& ŽE[¿wú!~s÷/K‡ Tܸ¡ÇƒÊ +l¶n–èÁ¾§Æ:˜W!k»Ýlû$K÷“R©ÚŸ+Âé{‘[ÎØ¨ÍÒ»pû+p}ÒܩуûN~@TÇ ’Œx…ô}±­KÝFþÞíIÑ4‡0bÆCš\ZÄãA—<ÿÜ.y_û¨/ n“W ùïzã{å&…;ƒOݪfW:¥‡‰Æ"[·ÉŒÏ³7ê<ØÑƒ'Lºfð´qͪ9®ƒp 'ìõ‡íYùmìÊî°~‡¨&9^Ó›½¥~·è, U剥cPe’ð¿úü& ÿšUËϱz.àåZp–ùy;h¬£´s+€í€_°:ĤPmk7Òx²ü4o¸Ç¶ßm¾°(êÝ_“jžŸOâ ÷u_?9,-´ë¶£*xÙ]óõ‰¿Ø­;ع rC²{”GaNÕVnÚËl¦S ‚œ[™­ -[-‘8Ób?—ÒK¯O5P©µj¦/¸‚9;†I¸nYÆG%%¸å¤’Ky(þ®Ç)纇—6£§¶}ªÆEõÀAŽ!‡Flc9Þ*àâêì  ë?‚Nœ––-^0æF(þ?n’ €ÓC ýa8×mn ¾Ñ‘.ºZ3«ù¬y$Ùëž”{Ã)mƒíÚh*—{˜3îî5clϤd=PÛx/³fÁ’鵘ýNµŽŒ<³Z¦çõb%¸Èò–ZÄ%¨Ò ¾÷;k¨„e½Jg» Ì6kCiNýg°l¬òq¥m}Ú2žçn²š•ðz›†e ®¯%æD“‰[Û¦…º@ÙÍëI(:Ïàü­Zô Â>ƒbýÿ¡-_¶I­¸.”ÛáÍ’^4QÉh‹€×i=ny/ZhãF’rŒ›ÃFXzø #öÚ{.¤ÃCX ;¡™Õ1³Záõ¦Þ®wR3Ø}"4ˆ*…®_`jèqP˜¤.ÆACìcŠÇ‚蔬«öÕ·Ãm ›ÛªÀkŠèÊ"n¼˜®:žÀØèµåÌd‚ó§¸M3 #Àf˜ 5£ˆì¥áÎq†9¶^èAÍÓ8ËÇ>E‹ÂöJçê.²hžuƒºðσ–û¶wÅí,Q‚̾"«oìtÝZÓJ“‰ØÇ>®•Ð@.PyW]Ìf$Cº+Âb¸žÐ. \WÚî. Áó”Ú%|™kLóœ¨xw_=SˆÛŸÏSùªRÖ{êòVÌÝéKÙà\µL·ÑN×ð†òôê|'L´1ZpuX,x¼[# ¨ ºKåy`ñæž$ãûÍNtNeéV3Y`öw˜yOÚ…e3‘nµ10’û{ÌZõÀ¡‹[·¸:N³Ñé8¶*â2r<¨Ub¬(ŒyG9@¬9õZf=’28˜Ça Ë35~o‡ýŽ3•£e7F÷l‚bÄ^!Ó7;þ>Hž½-ïvNh›ãÊè1¯§ú¿B‘¼rëµ+ÏÆt]…öß‘[ Þ”¼çW0cTâòÚÁµ›œH²~eœ(晫0dÂÍ`ôîR·Hþ¸:7:Àð×<3zMŽ!5«#H18gŒsƒª]ü^áäsÿ°”ËÌ6SM6ST;¤Òq¿éÒ™aàÍÄ䩊ӗ”œªâgy »dÐ “¹½¾«9cN!óå¶êÕYþž¿ OŒÃ¥îü}¤Š8†»oõñ0é³°ú%  ÍEõ°À­f¾àº—±¥ñÓÀýDÑZ&/”«U-‡šD‘4þ+mr\ˆ7©{^¦Ði©ÒŠ€ïõ)‘²3µ-P¤Â{Ø{ž>¹ª–²ƒ¶&€I|ía?€Ôv&S/1,6ù%vöy…‚Æt«FŸXñE™ÕGì?_Ö&€$åÞÒW¼gÏ»_Ù9µÃé,&&D&üù“õ\ GGfo ¸KQ ÷È\ð”±Äé‚(Oz”‘˲ ‡ö™ ¼»\”T\å9¿šAs  ³¸·Ë7v–™\Ó¾Q}ZDº¬ëYЄÁÖ•÷áû|-+<«¾»ÿù³Ö–UË1pÆÞ ró±¶k–á^ÓIE` ó¥ôà¼jlã½)¸Þßà ¯Æ;EF˜üI®‹'ÕI+|é©}ŽeíÂƒŽ“òÑÿÔ4XòýIiœG‰¡¹1Ÿß÷êw~ èžt&ÿù“òÕæÌ…'K#ûà.ÄÚ‡ˆÃÁé‘3ĵ‚ð<<5ïx.îôÇŸ+•!kz¤ÁwÇGi‹`q{™cðôŸáŒÊ9ÑxêÒXÓ¶hd,Y°‘×3Û9E2(t”éß-&#ý½ŸÈ¡0_ÇŠäa¾Á×ÈdËP猚A÷8e×âÖdm¯šþ;CAXpÉÖOUXWÅ¿/Ç g~5”k_vÖP’AŸž_pbÌÜèS::¦øÌÕC7éT\=Ãg‰Á,Dx&%¯[­©•-_o8ꦙY?¹·î'Û¦fY~Ö'H¶f·2๷߂ Çä»ñ£­Q %w†¸.›:³X—Û*—¯­gIJcq2”Wí%b»\ï÷ƒ–n㤀ãɰ¦t+g” ÌÔýz¯ @É ÆœÍžÝê0Ìiî7{n[n°œ6Äx•ëoCL÷‘W\}@]ú½µàªG§"»œ¿î»ª’§§òijkÏÊ®=uâúa½ÈãûƒäÊJS¨rÓCâ!Íü=Ïÿ+ýЭ³äx|Y)K¿ þçJ à fMC½W¹hò%¹ß "P–¼[¼Ùš§Ý9p+åÛpí$·þýÁÃ<ÕR7ö–:uyl×CcHH!îm×t¼Ó^ºGTå·cð)‡ðŽû¥)86³ <¤gÅŸ5M—07Äõðxä…)öŒˆk¬Ÿøî뙞µ·pç/Cä-Œ=Cžßœss¦ËxöÜ]<ŸÐA¿JÕ˜¸eÛ}/‡gAÏ®=£8höU—‚ö¸ßŒ pYòŠfÖ‡.3Z¶FTq«Pû7Sµc§1¨Õʹæµ\¬Ï³ÄÊëwë¼¥5öŠXÔ%œyÄ­~[~v¾ï•,wÒ3µïÕ_å*_¨˜yðÉЊîÓ+¹#VAt ׎uTPÙ<ï³DñÂ?'¸.t L‡d*âÝ!©ð}QµxIÂ¥X" 6Œ¬=rÜðVBkF¬«ªG‘²ùö|î5­¯8gô­–4|̽&á¥v;xÚ ˜Á D˜iœKÄFK¹*åÇë÷×z•¶ß:€žI>\àÂGƒŸçâ6q>ŒbH ³”…Gò†lcDJÕ“¦jm gþ®lg§æ : ŠâÃÎ##&.†œ°Ò¾¿|°³n/ým­ƒï>ÃL¸Uï5† dí¿ºº­VÝP'ï•v#Ö¤´a€íÐRƒòâÉÁ½ÀÅcF6jKzB¶ÙÕôåÛí’ËÁ ®ó÷*Õwœÿúß9{"¨ðˆyÍÍA÷V [æO8V¤4fdæ 3‰%?Þ÷^¹ÅÎáãðy¦}:Lüž °>$®¹Y×ìîO¤Ìެåmvÿ( màH÷“¿”ƒG97—L%)T|0S®°Ë«F™i¸ývŸ9·¡¢±·’0›ÙÉÌÇ` X$ VÂ@—0Ñõ¯€nž%¸]¬QWUd¯²:P*ò]ûKS[%:µM]öù®s* Vn7"U[žDUnìvÖF„¶‡nÄÚ—ÏY”p•“š``sŸú¯ ­$ÜzÎvæÒŸ–T°Ë,7BËödäá•+Yº¬¯‡J~mÔ=ìF›&Gƒ—º“£ø§H€,)oT@~:ðçf/Mzö){¢UÑõšÈ­­U+½qa£Š‘UÛ{à{Ö LøGðH[ 0CïåavKEýeVˆïTY#Þ#ßïƒm¯ÙVß‚îí¤Ô“—Œg#ÆâŒVñºUbžñÕ!@a:ªò¼ä\_Ø~¦¨é*HßTÛ›.³š<Á¿Õä%œ¼J×3ß,(L-^4¥$»€,/‘öΘº2þåQ®‡ Ÿ'Üa«r'Ð_ZKþ[,÷×ÇŒ^˜° rä‚ÿ?h‰Z¢vï¨ÊË?eØ®"äL¸óŽV½n2ˆâæ²·–^ð(+,;¹<ìÐ \g‰<¬|À¯¿iû­Ô¯äÎnŽcÍÒÚQ ]N3+cîÑý8¬Šá]@õ–Nû’ÊC–=€\á¥(©Dr‚Ÿ3̸½ª$mìˈخêÚM%‡I[ímö@qÍ $™t2v‘\®7eqùi>§©ŒÿýÑç=ZÿžZc2ýƺE ÙgKϹm~QXÐ ÷®ƒ„émݤj”5Zûa%Íäæ;í _È;j s8Ävöõ1ÃLíÈ£bãPI°@m£æØ6ßQîÝÂÛ`’w50Ï‹r£ÁyeÑà.™SYÈ krý¸Œ pGõ?Za”pή‡0ïî/Ýà‰X®e Ô/ kð¾×}dÏjÊ™@÷ ü•W—µ”›Î¡ †³ÆÃK²èf•ÃhmKx ™…‹÷a «æ|*˜9Ÿ zÎç×$àÊà $SÕ8ù$S#ìÜ–žÉñdÇ· &V\Éi`f`\©®…qÖ-Ľ+­ŸÎý¼º½ öy[!cÈF}!£ÈFh‹»†se¿Ô÷ÙFæÛCêQFüÄ f­wyÕ%S;‹x–‹ã+ߊnÞ0®•DÐ^̯º!rÏ@/£Bmö¾vì´ÄéZ”»5}ž3k°t·íp¦hA '+Êw'itT+ vÁ¾®r´Z1wdîo¬Áh¥ÎÏ ×!:{Þ|žkr [|Eìÿùsk•°/P…ÛŒ¼hÂÞnÀ®±&7×ûy?+VÛ‚$ 6® Nz×$9„¥4æÞ­jë7ªè¤ Gè[Óe@û^Fàë`†¥ Y.~ËÅ‘ñÜך |ƒ/enbq}M«s¤Áͦa„»˜·™ùz=ÝçžÓ;¯}Ú õ m·t$¾68ºX±Á}½írâ~.%e‹=Òá½¦ÍæBd[¬Ïs᩺!¹ó65cÌëy¨.„QÄ4@ÇtV“ ÑNU¾°¯x@¼vI­dhª•Â;É–á©LùA.°ånr•Ÿzãu_îßHaäfâ÷>‡ip4.PgêS&òª¤÷iàmfæÕãÆ/á±ö]ù’*ƒRò~'Ü·ÔÅxž3ŸÀøJË 30F.êËdN'ÏbÊ%Ùý(¶§;2žC&Ìôý*˜JŽ?Rv·CµÞ ‡êçÇ û±Ú_¶ŒÑj¤ 7òÒm1>KXL¬ªe¸Þ„HAºÕˆ'®$8«·æÞ]š$ØdÖtˆa‰`èí=}œÉ22Êìˆ(£hh;HŒá!–>†,’F«ÔÎL×·øÃÁÙ’÷]#ÎÀ*süÈà}KS;øø`êTÇ5^”{…eÞX0OĸGK²¦=RâÃÂ*Ï ½Kºp†$.1™h~Š RÌ`¼“ƒŠBHn¢¿ƒ“ÌJU"9H,ÜdâEL"Ôa£h`A’þ–%¯ìׂhn„#¿@®Ó 7>l)O|  ™Ë‘=jÀ;s7Ž\·-P".+åPb3áb $.shåùÀ†¹gôÁSŒ5» àe *Ëøaš•±Q a ^?3~ºÆ`rÚœFhÚÚ´°BVÝ¿Ç@Þ±5‰lük;çáJšƒ®Î‡3JÉ0{ùÐŽ×5ƒZÄn9j)M£w^ß i‚…ËÞ3Ùb-²šäæ1ÿä“ Iî;XAËÀfñI2'AǬ’` !¿{Ökâæé R‰)à= Ÿg©+a˜#êF4vùÊLb“AGîÃf¨R%Æz‹ÚÞ1z3‡ù–wàõµ…®{·>1‰éjß2èE´_›’€øg¾fRÛ —ˆÜEœ øvH¨Ÿq.á R˜‘úYk`™±¢©°žØð … ™ ®ÜŽÿ&½<‰ _;ç’®ï‹ Þ¦üÐ÷^”„’×0~?H޹‹Ã9Vë «+ ˆ¯ ›9ŒTøë£Ã#Ù5ë“zø4Vû,»SBÖöä`“AÀ¿+®Ìbm©G3yË€˜ÁÌ•¨‰Ñz m3Ù¢ÚyoÈ=Yà–­Á°¦¿KáÈY˜0 ›­ŠÅu ¼+gŒžŒüžFÒÁÊ£±bM™9£€÷'pŸ™m`°ÜY63õHMcñKì•èý°èSQ4@¦Ìœbˆ²:7ásaÊ“¹p4÷e¤/pÞIyFT]€g÷«“yS•Ìu‘¦¥¡næ‰ÉMÈ«ÈÄOÍZ†•)n!à@5UϾ#3Ï‘[¬­“¥ß1›ŒníB³ðÁ†ÊšÞ”oU(-ô*i¯Ò ¨¬¬Gµ½ I¾¸Â‰_3Øä' Û‚É–/z1lJJÀ-ó‹nFLìÂ8QZE–ÏМ¡Ÿ@f¡ª^Óà|˜‚·yd˜\{…CX/Dc[*lKÂÁPy)`~Ô·VZ>JÂÁÚL9™‹ËçjQ3s@Kµu¢Òp&7ÄR!¸yÍ2…ýº‚±Ú®‹,Å(éã˜8½ñNlmŸŒë¯ ²ã9**­Ð|¥ˆJ^E~I$H‚ÓJèmÝšMVÆ«"0Ýp&“E(îšm/¨Ä+aÔû‘ ÌM¾çŒÙ¹’?8ë¥j!2™ó{ DeÞ,kf;’K ¢ ³U²DÛ yì 9"Qãz}ûHd·0¸ód±›ã$Hƒe_Hîë/`húÁ µZÌ瘒ÃûÈçÖ ¼Á•]®DMÅ ÙˆšÊò m·xóf“’Ì,µ ;wW³™>g¦Ýï UÛ¨J‹PDƒéWËÁí*v<“ˆÑQ{š|X09w#[ÙRMjöüÁ0Ãöâ dæÒ)ÖÕT°±5Èäzç1Ê•£ì“ŠJtÙ?€ÂýøS%WNt5Þžü›Jý¨„´Kþà¢Q\¸A#£²(©Ù· ?ó$ àœÀ žïù?) ‚eܹðDE3Ãå'óhy‘=[âÂïÉ[åY_Ì ’lt]„xéÈÃ}ŽÌjBõz†¿Ú7ÌР¬›ã‹Ë}2ÕŽ,‹aL“êN.@÷tåòÅêa9Gf\"Já–Éå¤QÏ]ñ• ƒÊå/p…ÑIÞkÄeðkz×z_2nÎcbÝ¥æÜ2n¥/¾>:ÜòøxZ( £µ¤†õà¢«î½²Ì ¼&%9¹5ÅVîbäwµY¿î„ÕŸT Ò`msõÁÖk»»¶Š}.ÿÂ)Ùƒ ¨Ì(Ë#n©¼H’ pY÷ØÍ‚×JŠÜ™®ÕR$ü`Wô›ñµÒ,ƒCpžÞk(v”Ê"*¾¬ußêµ]¬·#~XMìÓ€«sMwLïÖ²nuH¢@¤mÇ< ŒïìX¯³3DLCxÏììŸ.F{c`褊2R½Ö Bm¼êψH6ÌD~öX´ñý¬}¾ØïR[à˜˜Vnc¢õ÷¼X×Ûª.q܈ÛpšõdÔ4‚wÏ|"dÛ …nã2¼UáOò´§Ï#ªNS;͈R´òTÕ%§;Ã"?K R]Å8îsOcp-´uªgövÜ{ 5½kV©³p×(ëJøW<|Øÿ|E_²(=³`³Æ<é@Dí&³]Á£62ÀÝÌ›W9~–Ý£¨,®l¥á(Ø »àÙ5[Nlü÷9g_0Z„?Èà×þñ`„úsÞk„QƶŲf¹› Œ÷R¤$'Ò LKB– ³²ý,uwXH F¦òKå¡UQ±Å•ÿ´zD7ŠýöY38Æ-„=(ãfiu|Ù°U*–%3Ñü^>–ÜõpfG÷qu©šjK¹Î ½å+ ›²Ç6x}D7-:Õ.Q\Ç×å‹À`V=Eg¡̳Ìèh“ùú;PêKx³ |" wÒ-Š>•Ðñ-˜àò8"|W>ÆÁ| {…ÚŸÁ»|ÝaÊå^ɼkÞmXóNO’€–ں̖¯h›7qš\W8]ÛnJð3äpÛ¹yaÚ ÝŽéÆ•o6P‹^¿Oò²<‘=Žè扌v¸VSç÷* V×ÖT•Lͮʀ¢Øe¿ó¼>“}$ËRö 3‚€2ç‘Ì­·^ ;Iq×b—%à×Ç gÁͬüª¥9³!Ëx²a1x}R±º17ö²àÖ4ØÊ)ß6PœÓQ Ö~NnÀÚrPœ4?¢_pí÷©—ÕÔÚ"Ó²ƒk|"neAã¥P×2à†jy­uqªðëc†Gm«óVyÈÙQãŠp ¦õðDð7%Kví¥kxÐò÷qÔ[¿˜V_Ÿk-6½Â,Ï#J¿D$MÐâ»Uþà×Ç 'cÎŒKKÛ¢zùß‚ïrŒXÁf·r X¯”c^¦VÆô„ÔäŠ-”Á Ò7êìb^”=©Qépuð›Ç`a ·tm’ΰU…gŒ›öç£(|>߃,´i-‘™ÁÙ?ýþȘmy¾]ñÇ=u`LÿÏé÷w­²öYY*»Eïv¸Òý áÇäxÁPÝÓ?oØrW¬U¡ÏÊXäAócÿ’P„ÜÌ>±xÌKl;(Fc±B1‰GYm†eÃöÍ›ùö#;Ö›î çÉiò‘ü&Cö† ª0ØM/ÑÛ—NøÈ[‚EêÄåÑä]ÛÂÂÊhÁ×ü#0Ùø^)5B}N›¢Énk?ë0Þ+ö-›#[• ã’M²,'YcKxÉÚÛÀã¤wÚBˆbhì@M¡èÓÅ~1Ì2œþ)ó“ÉêKÞ¦.#0Ôø0ìÀæc$9¼@÷Ç œðëœ_3ȵ±å:#:ãóݹsBÀ¡1 ñ DmS‹)”™g’»î,6.Uz¾¬;ãI ”Ìtéõè38;᤹¢{¦ÆÚ?âždúåuõ¼€¬³–‚jaÜ÷>º2kéÓ Á¬…æà¶RÀEû~œ2;) žýòboO2X±#3ÝÆfº¤ÞÍy„¯@=âºhËW†îÃ’0Š[J@Ë8äY9P›'ŽÅ‡ä¦gT7lGGæäùÉß#¯Ò¢F:hQs»? «Å‘°ð—õ1 ÞFfZ ÿ9#¾¸š×ªIÊX=Æšš$õ¸5c2mŸ EТíþÉ€k¤ÈðŽù¦J£dÆVûN»,GÏ'œ\Ü~q2þ¥Š³ 8> »,F:5Y–v­‹:¿­žW|-õ¿§"Kôæ €q]¶>Q‘eÀ¼µÜžê~¡~¨Í` yσòsð$™n’·C5?¡écwj193Ï H%héØ4ñÔŒcÛߘ²¸+š9˜dÕXñºWè³·Wð™~AÀ·Âx‰P%-ÅW™ÂršA¾‚MÁöÉíñ´OÖˆåòos!i*бąˆÛ ”ƒá€¼Ò³l •Õ Xù|=}‘^ȧ®x¸¼rãA¿ªÒ™íÖ^ÒÓÝ~Ë5a×”YžMÝ‹Žgž¹i·‹/B.‹"¡ëõâ‘¥óýºÀdîŽæ1˜1š%zc®tÞéj0ÿ]0³¸ë5.ôÖq¸éá=þ‚¯;I½éÝu0)5^šd˜çóÈÄîÁèë Ì«è—ïtÓFK~-õÝ68ùŽˆ¿ÕïX(ÍïhûZ„ÒØ,xxzq¯+_¤ìµù{„¬ØWâ‚=¶óêÉC“Z¬{NÍ· EeÔB:ÁÙÞ Ô‡ö#»‘Y2>%OÌ9F›BóÛÇp¬«œKE¬eŸ—YÅÜžxr+¨ŠÌÅ$!Å=d ]ól4q&Œ‡­ô(Ó‰TÄ^}ÔÃîÈdú¥ìGÚƒd¤°ˆ ËŠ¬Q Úapj,Œ”ØŒ¢YjA$FaµD”ÕÞ_Îé„PC‹A$­ð?­Áv’Ù¯žØÊ…jM»»€êj®¨-£(ŠYëÞ’ö¯FÀD½ôÕüx3ßKÀúÜ?û,°¾`\$Ã3l]Ÿ> w+3b/d- ôP{[îÑé30gáMõðÞ’3רÔÂz[u PdLû -¸Ï ·IdjXpÊß{-B¬£Û^¯œ…ãf8j˜ÝÊxÒ\HÎ…n0rØljcöïzy ºxRjíÆþ¬“{$¸Pòàü–—ÖÌbȵ¸n°Ï kpCב¤2µ¬+i‹+Ö}$9ºï s¨Ÿ|€ìáäçØKFYÁ†¾áܧ8¾íp ÉÄ/ú‰y"T2÷ò¤4nÙ'™RnäûÃQ.ȾJœók‰Èñ:Pï¡L)µ6,7ðuœý ÆÂý6 ÀÏ`@oàAƒåC‚<¥f¯ÿ.]i?3Øræ?ñÐÔ§t-¸îòÙ‚{ò’(3ÈÈǯ·yué:Žº@zÍÔ¾çéïk¶YqÄy"¶¶7¼ã/~XÆË…Á²æP‘®– |j $?SQSøØ“Ô5ªEhÔzÝsZԺݑN¹ëy&…Ó QH¼iî Û±"eySrÖï>X©“„(;0¼á Ië©;HCþ)¡wRbRÀuðmÏR¬#8âæŸ²‚/ïc¸$]Оù¥™S'mjê€ÛŽÖ!0zÁ6Ïê@pF,õ}Ötéþ’Þžz‰#I؈;XZÉ‹Jø—›îœÐ(È¿s'e¢²&«M²aÑþKºP&•‡r&EÏWqÿóCzZ†Y 2™[Í‘qÈÁ àœƒIük0¦’imü=öBÃNb¸Úóùü9,æRÀÆž¢´â<4Së ©›ƒ4Ì—ýTýZë@\åžJA¬‚p-çÈ`=[bèÑÛe 뉸iÎì¤îuФ¥ö°oÁzÀ¤Šq óÖJó|2·,ðÐ<ÊãÑC) s:,ÌÑJ‚ í3îÑ@_r™ä%ô5E¯(Œ8hÉ€(FRÇ„¿¦ÒÑŠ‘Ek MÏæwçß@+Ë7jûýÃjCÜŽ… ý(è%åN’„0l-?nr—~sÔw^ÖŒ^1g÷CVë|­$4Ák1òœ*Ëš†"kz1ÍîdªÄŽcÞ0¯G쪡5Ãá­øZ[1‡%SËæFJJ(.¶d}Z3úÂZF¥ö€˜(‰[Q€¾é»TFH[”¦v-ǹæªÙ‹ïheñ¯)v1@%ÛPÓ‹=½ƒ•5D\æ¨ZI{j#+0£gÑËj ÚÙ^ŸÍFõ“×”þð;HxB7{¬¢Ñyƒ[¬‚`@³Wê0¼A‚ÊUO Æb‚Ÿ0žcÿ›¶¸¹õ–²¯e¼µe·7m ðóc†‘}÷àô ^²¡¿ÂkMïËü^ ^¤‹ío†y—cz«Sjw¹zÁŸ/ Î]úD îüþu8}T¯uèÎŽpF¸Ã¨¥õx‰µ±IÛäPï°<¬@äëöGÉ+œp˜·×=“_J¤¨^’ {Pm½c|DkVï1n‰=^bOæ¬=88\žA®3GÇ6)²‡È‡geÚ´Ó”Å>b ÔЛKX‚-Ê™N0´Kž¨ëʪjsƒž ÛhxœÃu¯6°Jª7pϲY"àÂ]ÓM"oû±}5I&Q…ñqÏLî # ®Þ,Hn 9%~=ëëc†Që­KM°zp…•,zp’oÐι(+¬ ôàŒÐü’J)œþ‘Ô‚±·x€_GÔÉÙ)p¦?töM•:ªxo‹üæAi ‹µü‚ÐYõ¶ŠÔ¥{ĬtžQ¥:@Ö)Cþl¨Ps²d¶Qo#ÛΠ;Ùƒh›R7KTð]À·=ÀåOÁ¨S¿/± q†§¬a¼:Y°£'ÆO±=Ó dÕa€ï¿—¶‚»­ƒ -m½âÞ´³`€‚"€éð R@¸Rno›êSýÊðõ1ÃnÙ ðÈÛ€ #ÈÞ"ѹ eA€dwÞJ}X*¡à#ðÒÙX`e·º gÖ10c†k€F®ý¬`nã_,,eà‚ÂOH €;yôIIÖ@&Pš™%¸¿Ì„‘w3߀ÍgIæÍÒÕÑÀÖƒoÛò½šÔêß»(€ÌðOÖ¹òªÊìK¼J-Ê~nÒ2ÜIïÿ$)“´Ej|´¼¹2vÆ8X"poû$«QÏ'ÿ¹ƒ€L}ì¾MmAíÝ[Þ¡<¹"ïVÀeHÛ?&¹W´G[”Á~è÷V\)â$í!è WQÃH*@˜ y9h®0ë(HfF–m6ëhDy=¦PÅí9dæÛÆúçdÉsDrÁ“\#ò‹‹SkË”S‘»G$×'äÒŠ~¤£ü'pT J V´æ¤iáÒvO×­€[Øèøf3ÌR¤nþàW”ì&9?™GxEjÒƒ‚÷¬ k`½¬ƒìAÙ÷¥m=L^q ó+,m)µ“T ˜†f7T k WY_a`õÞ-wÆv{R­7Ó| ºÔ¯fî•ù@"@üY3WüÙÓI³§-{PmYZDzû-¸D¬Í×Ç _à1’‡50ª„&Ȍԫ'ù_ž…å› »óŠÇ+ÊxßH7oqÆ7pË”¼g#»Ò]QJÏFgÌ}G¸Qp‡•bJxE@•’g3"œ<ÚvMª™@TŒÂóMª€Õƒ-³ üm[y¯i ¾ÞQÚ(R l=@ •¾nÎ ý¶9ßøm§¥h%ÎN®Dl<‚Õ.½D€9wtnôKÆ[uÀHÐY\‡‡W)Zó¬ÚƒËÁ®"ȪýdÄ‹ÚE"«×%™«è5BsâûÃÂÓþ,ƒÊ"/þsÛËV\˜ºd^¸Ö:9ǶŸsw0}„ _0ö5(,¾Ã~ìN¸#÷ó;•+T5|i³7z`"ßl·g€âl]qY³¸Ë‚©O#hÅj¶… Ü•lô6.ìJ€Î¶(Þɨ™Œ¼“QÑØ5ø\ &ü ŸCõ »_{è+ÛŠ+t°À;X—m¤T˜sæÏ‘m“!< ¯¥ÀGYÅða}-ý×d]¤åo3êÖm8@p3XÀC¸üÍÊùRõ…à^±O?ý ª×åz&P¥:[ÒçG‡oÖêú,©²Ž;Œ5ßAì]jî¦Öv»¶§mÇ >ˆð5ìÙ†óϵ%F%@®÷/üüûÖVü³m±ùÔŠðõç0XæÁ¥gÜœªÏr]o#ˆ–”[0B, ãDiú(Ñ4: µ¦ƒP€ôÍDYÒ‡¥b¥Ýø×ÔÛÑ_϶“†¢´n•Š<—ùag$V÷ï×ýb#‚ >§)꣟áÃþ«OzŠ˜å­ª®ÿf<ˆÎ¯¸üüÑg"Ð{›Û[&³ÿõ¤ ’Ô.½ÖáþÌ“W4 áoÛÞáµîsà×ôZ[~WNwÞ(œWÊ.wÝÞÿúhK¼næõµÄ¸Pª;¶·uE/Ïvoc…¼Ú[o÷‡L­i0øÚÎuzØž±y(ØzPrW:JklÕêÒÀ›±ý oÁê¤KicÀü|@Ñf4ž@#“ŒÖFöyË¢•Ÿ¦%UÍ\9ài>›AÚ„Iîëc†Ïe›†k'SM®né“á*KŸ€"@ÁAr<Zél}Z€ÿþ»¶“Üo{ðõw½åÃÈ9§–ÑÖ–¦ÕÖ–c¨+Ju6à&²0¾¨Ø…Û'¸÷mú,e”–ŸÃ|ý5umÿ˜:…ÖLë³µ¶¤Ásï¦ñ&‚÷& Œó­#HBº€Ÿ_cžr­J l=ø¦­dJ­•€–üqŒ«3C–­¼W#øF¾>fÌýºÛw‚ŸoèJW4²§_Qø­+“ê“’íèb‘8}Ôd1nHM@×?Ju-P^9Ù›$‹úiÔY(ÓãŽb}ËÛ(RQ„²ëm ÷n}®KÐïN»¯W¢[îþŬXtö€žÑ©â0ý ¬Gº%TÇòaùÅ~¥ùq¬ŽÆØž©å4®¯À–ù Ë ö Ÿ]× ¯ó”=>=¯Á ovñäÍ :­ [„6¹Ò+[”Œ p ÜÞŸNÇ}Fødô`„ß¼¦'Á~3™Úr`XÖWG[ýî ~ÓÖÌÍÖpÒCz[Θt¥ÚpMÎÙÎÊí_ûéJ“‰a÷ÍB(#¯¹K·–Ø¢ÀÈW¡h†9©HyŸ\­V ç|ß‹ Ï" à×´„Z[‚{Ôù˜A¯˜ £OöÌ-ôÑé4 Ü¥V4ˆ|¿Ìó%s[†´È£4¨GV1A"AX3XAEòfÁ$ŸQÀ#‹Öi\TiCµYÉШ{#`Í­œ#9¯ƒ^@î¯iÒ]e4©9#j`®¨¹4ž”ÛNDv¬ž|m9cýí"¥Œî.wÐP÷½åÊÃIXoV¡Ôy€¶3¸1Ó¢Ãù°Á8?Ÿ]IDßÇë[ð*sÔ?´Eoû¬8Oº‹|{ýÛ ÈyÐ^¡æ—¼ní|Ò­Û *œ^Ó¾ìÁ]Ì•*À¬¹ãímŸ:9 güûü˜'( ûÔ8Ê’ÁÓ¨½ Ó”«¶"µZú„û|pÌf“I*—@¾\ ÒVÁ”šÚiŸ ‹‚2 tÑ9˜Çÿ ¿µ%ؤØzPŽ`·ì{^ûè^ +œ¡¥ ¶MÀ½pÙ} Ö~´3Àµõ M¤VyÓ`碀õÈblk¹¶û! Я ú ®7+Gõ¶f· Ä£>?ºÜÚRÿôúëM·ßö0='{:AÞåÎ#à4²_÷øÅÚW(°}…gÇÔ[Ÿ”ˆ×¥h½‚±&@ó±ZÌöýë¿þׇ/3ËÅqõÐíõµOÃŽýõ×xý1^êÁz#vÛzt‘1Ô3Œ<€ƒt” Øupßðýö´[-0s8<*6ê ;!æyÒ¿€ûò‚V°Ë©ZXÊÞ Qç¹` .±¡töN— æ_˹9(€ôÝùa<ˆLôGeY+üÓÀV.øœ–K°Ç•í޹ུ Àˆí¸fKîäeOAÎb šAÊàAðZêñ@ã eOQ¥Éva”Ó±ðÓ`±ç~ÍñÉѪãjmÉSÐBr®ˆçÀ“,5ž›˜ŸnK W‹H¹“jlË0r/)§\‡Qñ¹~ÒÉ)·–2äì‘ôÅèÑd[NzÁ3,£”pÖ6Bm„μ¤rÌõˆH›Øn””®ÃŒå»XáÎ@”Ò¶PÖH\70™BÍù[®QƒØÌF Å'3(¯p3zä:’ëÔJ‚^ÿ[¬PóW¨z:6Õƒªfc‘E1?õéÆ s GTŒñCÙO¾Âˆÿމt’ÈÁh/ŸŒ–Å®íD#Kz™ŒQs-«»ÆvhU‘¶‹ñŒwò/‘ƒÖÀâÊTË©m `=óp#FñH"»;ª›QÀ@‘˜;I’­F$˜±,;qsa`¼øM®ª„ûìÉ¥vgQ Y s‚!`*4²“yœÕZ©cÁjN2“ó×àð²Ý"p§¨‰bQÊJå¡ ¾êªØ³"íË0ð•YÌÉs¡ ™Ÿ6ñó…úú½FôY´=Pˆ¬h–D¨R:ÉóÁu7 øVjÑZ=¬…ë0ª<ÌÚöRrã`N0ò ¾°cU‹ÎBa"ÈA_¡@¥µ²ºP^Œ+jGtöNb[Ažm!Ý^:ÝAj¸:ÕÌ)61£(“ ]¹¶ÀLb®O¬Ã¸R:ßöˆáà@ýÇš„d•Š…Œì‚1µ£D‘:Ýûñz ¿/¾ÛUžæÜH˜ÚQÊÆê®¬[KF,FÐAöàõßË# 1ay]v«ª'J·Œúb¿ÞzøGƤkZë±ÁdtmDD&ÁÏ¿iû øö¨¹\)”ºì±ã™@üžÓõè„Ëâ £žÜKÀs­Óaß;0’Áidå[ ³ÚŸ{zƒšÉhə̶à¼j§«{â°_) 8¤ê\*i›ÌLÒÕ˯ŸÓ\¸ŒvlËQ-lÝj€©(ïet‰õò}ñ×Yõ^ÆÈ/}ƒ@j¹vn#àº70jž,îc¿w.±xÖ>2âŸP_¾PðRõ5x‡³¿€±æap²hï]Õ LÀV\el-¥&*˜YüõuWZжÆûRÁíj^Ë2rX]'j5sk²Zy]ð×ç·ˆN”C¶˜¸ŒÊv6SΟJ»`±MS”¢YQVÌ‘Á„m6ÏÀ'ÜxˆÑÜ2‘,ÈîY:9^áaY1Ââ*`g ÿ‚Ð71ÇÖõ¤Š7ËeÎB°·ƒ …(y@,Þ1q´ ìWÄ=y´N_4éªBÀÁÏhÑ”°Ydul¦Q_aüY’ƒÔv”eÛ+^:j³ÙgBÖ’¥èLGeVæŸNÒUÑHËÉ­„Ê΂åbÑxLýV©Ü%t6ú°bä F¯ÝU‚±=îäñ°3î¸û!8Ÿ†·\ (î6‹ºßYE\@δq&r‚{Ìo™]µ@´¶,&™ö#‹ª-Öm˜E,h¿ÏZÎã>ßÚb7—*àjq¿æ=HABÑÓçÊ\€-‚$fs§MÈÓ ÊZó»È%ùÇž·Wn) àÃ;Ë«WNØé#°mèÉ—‘¯xƒ©¨³âµ/NZ>ÙÌð•ÆŽ•,š ¥.…¢Mg,ZrÆìj3f$\âÕ©˜œHPËî¹G ƒ†NÅ#©8…QÏåä@|ü{¬ût¨í¬È£òócn‹z¡ž[âyÓžNvIPªÅE2M1u» {Té&ࢢñÓWkÁ°ˆîÇÁMn#Hàçt¬-J0[‰*vfRiíÜfçNƒÑÏ:Èae÷o$©¯IVx*˜©åÆQ ¬[ ¦’ÝÕ׎¿3Iàæç™Wm\-}ö:ËÚÀó𠦎¬àX.1W¤\éî Úƒ¼”w%[áT,ê¬Güü˜ÇVp`DG®AlçúÉBU¦XÔ€{ÂC€ÏΫn*Ôhú,øª‡áªÓA”Žol¹"@t€¼þ*XôÃéªü•[*Õ­N)_Ü`VSoà’Æ_Ê ,MøÐ!ÎRãj]e@/P‰fmÛ˜îòXqíXwi®äFZ[Aî’ºm´“NAßÑS7é&éèÜå·\óY½'Õáä˜Ü F ›æA§ ^à ž±ÑŲFˆ/Ê™ÇYÜÉëHí,rƒ…ÙQÛãòŽrÆ”"waËÈá“*')ÕãÎSq%`hrë@[Py:¸x‡×‰ç2ð+Ãà óéÆ:(1 {pf’Iù«ô@ÁûXgÐ.×ý¦]™;ð8ø°sÁÀ¤ÎûìA÷é 3£ê‡ÉX©únªÊ¸k ¤v¥,~ÿaFÇ YOõ ¹@µ¯§d³IÇpõn¤´+rgý΂ªõ»£¼òªß¹Ò7Ô¾Yk$(£ âJúw¢=<æ@pQjƒåCð…1ô‹DÁ^¹ŒŠ¾žíó,G~„‚ÁÓÚæmçGyK ¨‡¥€z­F„Ð$€A+: ¤míÍ”ä­pƒ1©¶ŽŒúi‘B9çCÊbÜB“jñ1ëµ Yt¦Ö¯Õl±4'Éæ’RÁä¾õ `PÖëÃ^;˵ßS·î¨†Ì1 ËÖ 06×?&ëÈÈbGc †/ă§ðÉï°Äá{ádvF™X" .[V™8¡,AadnöyÔkç¯Ãm¹: ®$–vá®/kè¼,œ†±õ¾~Mòؘ²Á¹¾ÖVGì ¼x.æóŸ"ÌÍÄå–YØãÖ%Ãë¾K»QÁϳÌÌQ¸ä£ÌU)Û;¶çangl;ƒÇ-FìôëF缬eû Ò¨Ek ¬rb_q¦v™‹cÍ&Ázƒ¤“ÄVg¹~Ãä,Z‚BÎ&/'̞ܛG&¨Õ<&È•4‚ßψ]G(hŸ¹2vô`Ü5%`EèiÚ`-èó>™¬/n¾g°|ŽLîBC€ój¬Ó³FÜo"±døúÿs«ª¯®€°¡‚Œú%ó])Àk©õ!PpÝ÷<"ª‚"Š+áX7øÌཛྷכ«½óàÛ €›QlÐÓ{ö‹;2¶(‚œGœ{´¶3Á6€ãœŽªÕ<üÉÙ[°ÆÉ,{/IdqªåÆÉ‰ü…78jΟâRä,¶nõÙ s|„£ÊõøW,[®«D@vÜe?¶i`°¾0^7•ù# ʺ-#´jšGW˜[&;Âêª-ˆ‹™,*+³ókZ 2i¯ã9dîõ`Û«/ð\0½¯‘„Ô8'Œ™©ß†Ž2¢²³Ç·o$i>È[|G‹ˆYgMy‡aïü5=e¾4£GÀOüúu|FÅA„'äÄÂà¯mœIj–yððÃg¦7ƒÖ¶+IqÂg»Ž÷¿Á™TZ`m0 ¼ž!¹*¹êQoÖÀ庛T ®¢Ôž°ôÑóš¶³ù%'ùƒv³ùí:]sfîú ÀÓÞ BHÇØI”½¨Û”n,ƒs¹ß¥®,êi±Ëzõe³ô€kôÈËb!~BÈ;e3ÛŒŠ4¦L“Jص(àÜãDØ£¦"¤Ž8¾PNR· §ŸŸ¿Ùƒóff%Oá½Ùv¿Î·øò¦ö¶Žp›ˆ÷†äÐÑ«Û ×KßN-!nYOgÚB‡›{{ÉÚ®Ñõ•ÍkEß³j²™qMjŒ¥ÃÝë1 ØQÛϳ€¯ÔáoÛ ŽnR[ª·ÔÄdÝ­i—‘E¦ãrmh›é–K&À4ß r*gÞ±»­°nŽJßë\¦µ]”–ýAJ}fÛ58ó\²‘,|S½sG7gØÝ{ nÉQ”ÚU|œÔ¹#/‡¼sC.ô»–ßagþöµYßó“·ý¹fl¹NÁx½ÔA‰íÈ“ç*¶0ôºNW 3Æ'çÙ.½>²|Æ•aþV`¸S ”³Ž,îzü`˜b“ª-Qî…¶Km÷--?û ð½€@·‰å p&=(:ìÂAÛ@~µöÉ›ÉõÞ&í1™¿j§nöÆÍÓChnjʉ®GRª€vÃ’?7š-²¼ŒÎå2jÕ¶sü@Í`£‘…6’:r“–Z6²“Ñt›TQÞ×û[òYU¤H'È¢&R™”jSž¥3?$¨/CUmë]@ù –©±IÕV­`nê? øöa´µÉ+¨¹Ñ^÷xÞÇ0­éIÿR+ܾ֯÷u¥’ÃÍlu¬$„”ˆ‹Æ×4Êö/mË!.-Õ§/7B:¶‚[¿6<ÌŸ3Lotéüh »)§¥xOd•‹zƒküîî—‹€ØÑÀ ì°ÑŠäV£`φ)ú ‡0ÏÕ¼Uµ „ºÞkü‚tà4°â2j—gÕ7= Ê¡/GŽD4ôۦ߂ ç[}.90ëÃÊf¨,Ù e´k3¬x™œYÂÒõi HíãQ­(b‡ÓºÅˆf0 Æ?¬o ¯û¸F/è¸ô†•% Í‹®û†çŠ0‡ýȬiT²¥»±Ê§€Ê9yÐý6aúúè[©¹7;Y‚}!k¤b'Ù¿Ëe»×‘#È7¨è ù.£2eyYì"7K†*X!œ¹™6Oríp*“qQ™k\Ò’^GÃÙŠfsÛ¢À‘FÿÜJZÝUØC~üd›y âÅȹ›”h5ܸëQ;V6¦Ü"%vO¿­¸óõu·âí¨ñÊèÁZ]€Á;#I{a_’¨’â8wÑP{œDvjÛ ¶¬=®U”9©µ¥®žºqµÐg¿= êh!ÃnÜh+‚Ô”º”µÐÿâË`´M•·Y¦ÀÔîÞSZô·Ìz‹'R~„ JWPJ0{oǹûÕªÃN÷H¦@›òÁv€ñÿÇZÆÈ6õü|¾/ëMNÕðbƒ \óYdd©¨~YµÕÕZõ™ü sP h;ŠŠïVk7¯¤+µ¬„‘;I•FZ)ÛŒ÷€wøòíూ79uä"4?àö Y‚ì¥ $?±P‡„¼+¯2:&9%}C=Ê]P?ÏŒ”Þ2³WÊ/)DeþöÒö, ÆhŠLª ¯Ñ•é/GZt—›¼ô–Á3gF>æ£Âñ•¤Òƒô[ISù­ZO‡‘kÓÁ¦Ç&õIGÆiJ¶O…n4Œ÷ÍGq 84Ò_JfR3‘ËÃ$±ˆNÍ@ØÞkÏ7Ĥ1‚ «ÐT™ÄVkrY0´Ç+|Ò%{vHÝÅßÌdûúhÑá÷²z[3r^LA©?Ùä…0Å.^Éø|Ø/¦d†^Œà¬`“.e¡“»Œœ" gÛ0#rOãÖ²ÙÌ,€¹]/ðØ‹'áu§‚Ü Ï†¹2^œDN´°<ò²Pð`Ñ<‘(!©} 2€µR"%ÔUG63cz´­@\­ö`®èj2ZW_áÒ†.à$ÿC0!8¼êÉt•{cV§¾äR ·•Á7Ãö m¸3 7@~ ÈñAn®%§s€)ÓGêe}×Ræžðè¼,ÅcuGÞúš!Ïu$™€õ*‹ªw\k¤ìáD?|Ò'uSóÑ;¿cþ?Ë¿þ×G‹Ïe>òŸ€¹Ð¤ž½Þž9ÌÄß#â;|$3\ƃfÏ 9ÑËä̃\wR|xtl¥7ð•´êu:^…‰šÔÑöf(/“^[êòŽð$‡GV$Úƒ#ÆÁ=Kô<÷Að®œÁ‰|[–*68rà¼^Øo§äé ›v·>Ñ”9Â’þ]åaÖÌ/ü> az[Öh{uöÜ!Àí =½Rù ¸|IéâŸ+“Ò ›æ€MdX‚9I‹kÃS±°;“—®‡±þ½Æ¹þ#Ësl ÉØ… Üóͦ|~ü¿ÿõ¿q/ËõóÿÄ9Ï´Î#9îÌAqðDcI–â‚Ò|kƒ9Ä8{~ÄFA#rx)X;YôMKv’Úà( ¬}7ct×Ë0Š&€Ñ}×ËøÝ!3´ ¥þŸ.·µ O¯ã\ßÁLÝÿA@é‘ò ùÃ~ýüº"àgÇ)a­· ÅHðß3,½eÇXݪ3MÖ¾.¥þðÉÛôرáÕ©*SIz  ¼nr˜i[dêxUW?UKÅ–ø)ÏjÆOçz)Ã" sÌT³`&SÓï$ó«tÁŠ€“­áÐÖ¥þŸoû0÷6Áz/,ýùu¼Û®ôp§iÇ7[•mcÿW¥àkycœåNü ØíŸ ø®u?ö"‘,p‹ÃþÆ–ˆbK‚º¨8H°î»é8ݹåEК ™¸Ñëåý³Sñ•À³€oA¿|ÁÚRc‘ºà€‡Ýabü¥Wíè9[Ýhp*‡i.bÛ_z[È!å„QÛàýIs¥V¾i)‡ã‰¨ÈÉÜó‚½Hé/5w\KÓ&îüt÷Yñ(„_Úå¹ÞÿšÁ |ìeXyû-YXaÏmIeÖZ:8oŠk]'‹ÍµA%R̈´¶u#œÚÏÉvkìZ¬Å“ök¶œìפÇú¥nb–ê -ÑÙø{Ñàþ8À3xŸ÷ ·T‡Éi'k ;pîØŠûǽÔ5À»¸¥¦ n4RëäÆp¾§co4 vêNít,uyÙï7_àçÔƒäqRÛÓòßQÐW66MÝZ‚À°ìÁÀ&{²´dì¬a¤¹Ë IŸç\S³!¼òj!ûf#¼²QKUäª0C Û¨j+z|‹n•<ª„çó߯!]*Øž¾>fØUþ?&¤Ý€©Ù䥿ž±?¢ßÉ(”‚˜4Tª‹Z+h‰æ ¸m9¶M@UÉúUîÐ>]jj,éxMôzÂñGŸo„Ûñóxf5§:“^ðŠZHÛÝÀôkœælo[à2‘&šLp]q9† æôî¯_F_7/ß‚Z®šjz£BÓO¿Ç|!È@ãѶ ÿÌjŸz#‰~ýþheÂ|qj÷·ª¾Ê'¨aÍWÕï²,gÍ ÌÍ뮜šÔŠfO¶GîÚ“g€{ü Ž;yǡ¤¨F½í· »pò.\#®ëý¨n‡ÔtôñD¬øÜ2š'G;ªyʳ"KÒLÕ@þçM±Èøújk:Ïäj&8ŸžàœìcpTz "ZΛ¼n­ûrÑêxÉü²d¶óœ–miµËvµìZÛEjÎy9OûA*ÌA®ÚI@Áò°³[µ˜Û+ärìm¿a¶œàëm Ìn)(¯Ö}Ý@˜ fìm)²Í¶yÀÞ¦}M™Êyv›OP›OéÈr,•’-' ‹‘5Zv(ï}Ÿ·n_ ¡úsëÀMéÕt9°#çµÌ{—É­z¹WcZŸqyÖ£Zrh—‘²«ûÅ…¿/øZ÷ùâÒ@>à¬×-IÀ´‡wл5ï§Ò¶Fº®N¥­Ä@MèËB®·á“ø¡ÿ3f¥ /”íMä¤à÷—¶µéÕíU6½V ¦%.µ¿?æÖ¤P™Ý@®½—Ùû€E4,Ðëd z`~”‘+6{@¸õ@oûÚR.ö*×áöÅ´Pl–œG]5-”!§ ÈcBÛ*˜=PÐßëó" u‹# “ ‘½½#©m:¤…©U{P8«=”Õ§Yˆ8ˆ#\ó ŽªxQŸQÊEØzPox½[ÿî‡uoû-È/ÁÏ7¤l`¹ôØ8~1)ÚV¿Øþ¤36A|ÆI]`Ûß] P;YÙ%ezäÜWC¬:í8Vù¨É#¢K/íëÄÍ–µ/\xaJ¿–`P£¯­ _‚Y¸ƒ ùß´U©Û¶]ß±‚sWRðÛ7óAœ¼M½-®ò}Àke£xò¦²¨´¾î­á›5Ú ãTº*|S'¨ƒóVõí¼ýaåøÒûz[9¹Q¼-ÓÿL[{[þÐ6 aáŸnèjã®­ªµ+y]™yWŠÊ2ým£LC_v9ÝnÙ­>ÜòV%à .ÿI£&ÜW£ wÍìH“ÃN¿—‚ùÁ ¼5•µæ¬È%ªS.×ç]`¬Ø#{Gúsu-®A°Rkñ †5„´±D’d/i¶prµLºOÁ¢Ž(H©ÉŽÐ«1Uð™(Oå„£žôKp-.¤¼R¢¾UPè¤B)œ¤¦Ym¢?U%ÍøyòO–ö^ô²¡æÿòž'ëgÔ…¢‚xäòÑ~îà¿n›¼»D¼ÁxXFÉõÇÒn"Cl E;ÈûSx3ø…·þ߀ß$Æ€bî ¤hä \Ô÷Û‡€p'ôàù¦’«eé¹h ß7?ß|Ó¶õ Àº^ˈÕMºõV¤²e{…šºIËÈxò<"Î…®O@Dš•ëX³-b×ÄZ&Ô²VœVXIô?|ÀèAFÚ‰ÑÖâQ-£ŒƒEé¨nކÂnÝ0s^ü…– ùL—†„@~¥ÕÛRož{² WSqçHK8‰ØQPZê ü  Z–C) ëÔ#Uì™úkLaWäP#.ó²2^V‰ÈŸÀ‘é— ÎJS51dÂØVLM Yr51šÔifS7ˆ¶º8áËô¾kp¾rn—aRÞK–\ÍÁö õäaõˆxSîá œû–‚nFýëcîM®òÈO®fÔ熪 oÔ½ MrìÖk ¿˜ZÊÚîMw´l};+ u0+K鱂ó. à.TKYRâ°äQU'Xž uÒ}s¨Ê³¿9~ëìÔSº°´§·|™“*>]Õ‰Œ§¡š¿Ïèª)¿ßÔÑsb/ –Ô%…iÌ ,íIø»U@²gÿ i}Ûƒ,„ØöÔ ¸j·ÄóBØ@Q©N=.®fÐJmSƒGÈÖ—–+ª«ç-QÁ¼%*(·ÄT˜U;O÷´sªîd»4h‘ͼ¶Ôåñ~µKƒEäß×Û­C‚› ܪ:lÝ~7-/K¢·& ºei ¨â¡Zµ/iʤj_Ý/Xe3@TZe½ùÕö›g!¾«? C0_{ö¬z.à–eÿä]Iø~·6X°u’V±-ê4þj/€üŠì­¨Þn,¢¦scpoNÄûf8[~„Œ~è 'bmëcðûcnCCº ä²È%†kšÄà (•"s1ò3RRŒX+r9=j?áô˜6: ¾k Wˆ€1çßGœ^”bØx€}~Ì-y?ìÇÖ;=—Ô2`ÔÖ/"ó”h×–¬‡™;têCUÓö}@ûïkaIK€ó·km äì‘¿KùîÖÖg{ÛÌ þç£`Íöº£k2H•3£Um}eô7«E(Ÿz cüÜÛ5’Kú›­Á[úï~v cݧ5´˜Enï ¶Õ ®{ZöêÑiq,©V7«ÝÖ*&t?´Å½Kâ…¥%¬ŽÓÝ@œ_uGëwËR.¯ SPXš&7‹Oü#èVýÉÔ!z  xù ä&Õ”éºÍ‰.\·9Qçë>©†S¹{–áT4©eú]@*ÞuÑHs Íò°Ì-3¯ä¼¶èæJ›U#kšfôJSà¢Kªu)éR~Y\ÁòïH©èRÒ먤ÿÕ{[TÞ¬ü;R“I§‡:(»º¶Mg¸Tìâ+„€Ìç­×•tàúbR‘N óR³¤nEZhx© ³ŠY\ê]]’Xµ’·LÑ«šÄ°â÷,?œðÞ+Ü%¡YÎ1¬qÉEÞ?B:7ô#¤'¥WÒÆæõMym~E~ñrUÕÝjk´²æ\ùÓd&7©,®>²Ó&“¶|@açÔã¦zPú¤–xw•¿‡M²Xçó+c¥=èHu.÷ö$l1ýçfnLCùô4ˆ6¬÷r2²ê¡DÖÝQ@(ŸsÛ<ìsÛ¤€É:§zgµ 5·ãv«.«ŸÜÀE*Àÿ]ÛInõö(DåÉÃC{[gZÓÓK9im LíªÀöº%·nÛeŒTÝ»ºµƒÀd–ÛvÀkµôZãü Ð1ÿ˜NvÑéK øôMœr©rXQ¥‡ê|6/5•Ì„šMýªÚR%/]ŒŠþ_ÝJJ¡cÂöyÚzO¦S(ï_Óï¯ÿ®¾BmŒ´/ì0îÿÉëÕšBdÓ¼Üà8ÇTIT{ŸƒÊןg‘Ü>j¼¶Ïc›¬òœTà Î[ËV®$µ¬AB5o2" 6C¹§Ô^¨¦¤ A7´òQm!TÇZÛóR¤ ¯Žy d)Ö+4}ݵ̬¶ÍG{+=˜^–ÇOyXh²ûÖé+Eá9©3EU«<'U)HU6Ò+ÚŽj ¥‰>¯šQjÞª5%VÕ4-µµ*bVʦfl®TìVß|‡ï‘»øû¢ŠA ÿJylºÄ+KÉk Eè0" :(= ˆG}~|Û±?¦7˨íXúîºÜt|õ7“¶¨úÝ¥ò#L+øÛ¶ß‚ 1Üôœ©âÜ@Îq§©–/˹¬Þ°¬! GÕ´Â*È[.u£R@\ÔfOgÅs·¶ß‚r,?6Úþþ˜ûÀÐm¹–-5á_‹¡7¹oˆ§N±ªÌR—Ò6~Øaèû“ëz eÓáÚøýѶ@H–VÝæÚ2¬/-«H??bl¤Î0çÄ|q“©¢ ÌµÝ!Lܵd¹|;YßÖûrùF@zªµ¥8æUnºÅuq§_]· ñ«ëîаmú¿û>"c%õ²P£JÍ¢ŽìÁ' $áY@¾‚¶ô€ƒèA’ÌT½T•:µjÀ¶rÿW0oÐ Žt –bwšmvëwåÓ>翚µå4:ÕëÉ_ÃÞr^Y ©ì"§9Ñ®Ù`.´ „¬ËþHšÝ2Áða]*l´@tÃB·•ˆÐ²t ôÇ!¤ù<ƒ~uYuP¬*¿à„óï Ê-—â9’¿¸œð Ÿ$bÃT@ú/OãNÍ(2¸? R@Áù éò>‡’¯Â­ÚÇ =ü* CôÊ 1ðm÷¶î¨æÔÀà RÍžeémz×;ï:Aú¶éònméo=(pÝ%ž†j Äc^Ä=Wøü˜Ûzþø˜['tIo+Їk):–1P§4gP6¶& Öhpel"¨†è£XõŸsÇIˆK«(i»H<9 VļW‘O²9UìÁOˆ²¹»MÌ‚ôÑWD.Ì ¼ªàQæÍ0Ââ÷ì­› ÑHž:‚ñÂE'm+/ìuß™mß‘ç}Á”…tµzK ˆ"_’ïf`ø•ü!£ÀoK˜ëpš²Œhû†A1m|[\†ïɯ°“½,Qe‹‹‘ÙaOåÇü„} ÄËê^J£Û÷`‹2R8 i7¬ø‘—M#%lqÍ.ÀÛþžŒé©”¨¦ruª%CB†Õæ¾e5/¤Š(ÑGÔF'›Ã >Îu Jª¥š=(8îé ‘ÐÞÂpŸ˜¼&rãþþçpDé ¡òt¸g:ßAº»áƒE5ƒA™\šÉ¢ì ­-í0bÇ(W·ÉaÏûß/uwìj"5O(ܲ~´¼®ô  9"µ¬Fí¾®mó¾ž1A¤ÝGoËbqZe–cŠôQ›En4«IYs^›Í¦$¤ 19â$þ‚݇A*GW—GÀ2æ’ýùÑÍ9¦+#,sñ;ˆ´}vëó£·mF"D}÷ A‘=x7=¥€z]ÙzY€´}}Û–Æ/|&tÒÐ&6žú8b5)›^›µõÉe~ýÖœqûÔüJ³`™[Ê,™KDAšGšµRÖM­†¶ô¹H%Úª–3Œ \xܧÚÞËØÏŒ÷ÒÐQÉ€è02 \YÞ®ƒ\Ö Ñ~ªtCxÞï”p#=–Ä>^¦øÌÐÑ£NÒ³º7€þ:™óz¯Ž‹iSžÑOJ7hž*’= Dñ©•¯’N)tB×.ý¢§'[Átš—~×ìVgÀY™Îø…JÔ¹\ bªñ‹–Ž)þñ-†höÌ*ŒuÏkyQjE©º¿iûÇGW~3£^ÛŠž­ ;—¿&íVà:Í-¼vaa½V) ;@ý¼a¸©›®uóº†ût«’[‚Þ)åBðC[^‹åcé­V^¿®eMª_öþúhk¯…ûSñ6èµ:©¶ArbëXm¬Lnƒê›]ñ\s¬q3,úk°®×ÖAù*‰­r“üZ/Æ" îÕèïàƒ•[ïÛ ,©IëýcÛoÁéQ¼ÆÃ ÐÛî(D–Äâ½¥×™íYs¥,jˆè J‰¹ˆwÙ¬ ¢R¥‚G‡¡q¨€*'jEæê“g98H%õ±3ËMgZÖC—]V<Ñé-r-i¹àËëÖõ¾Ê»ô–YùF–XUr‘Ũrçì=Èõ¬=PÒ-> àdŒè¯Ë¶R¾¯Æ@Š ª©+¨ ßRÿóÖ6¿Ø?‚Þƒ÷Þf Á¾X}[oÉ9Ãé‘•,µm–kÔAD¹Æù“gmHÝþPK³K5…û¸óØÛ¨[Ú?.ë{Êüž3cU3ÊVð‰ó>C¹XK¶i!Üq'ã¶­Âfw]Ãõ­¼–è¼Wg«):ÛßT Ôê¸î~sûN€Ã̺¹:],#Ë¥ÕLnm ¼®{Òmì0»Îc>. ·Eóèd‚_½þŽ÷9=,ëËÔ°—Ù‘ú Ô˜*t,_‘mgÐ+Q@Áò°’ú ˆ¾RE”žu‘úxN®Çj"AÉ`¸Ç¬rKÅÈÁ.gqÒר¦¶YÈ[ ÒÖ†ðjÖuU5\AÔ"§€‚%–©@Ô"×µp~…&€Ýº˜Û¥Þu%Èëá¸}X=÷q½…cýÔö[°õ—ªÝ.×¢Â`ifÃ}9óZ3$‹ÊÏRQ=^l£Z~¾?ì®@X1;ˆÜóT>°„n™r;¦d…²¯OPö”í[–Ñ’ú(ð‰»i\C‡Y šÉ «we‡u˜9o} fá:ºÔ0Pd¦r¸ã¨l˸ÞÏ+ü}Dyg[µ·fËw,ÚF<“5‹†a9ò{&ŒÒ‘p`*Ï}¢°3øÜ.Æ™…u³4÷½Â×µ.“ài:1Ø‹ªÑ3Ûªá$[¾ ÷`V\¤dx›Ã»ƒæ•]Ê CƒÏuŒ·¶¨šÜ[ÞÇ]”…KÛ›À0u%Øí)·ƒ+™–ÍÀ=KCeü™Á,G’68Ç5†µnxu»ëN#Ûþ0Ì£ Î=hm \Q¥~=¥€’;˜1¡=8—óy{ÐM©Ãj‰"à‘pcµ»8Êú1Ôm¬¯“õ¾8ë—°Z]‡R®|¯Ï{Û5ŸÚ£Þ{ǤmÄàýÞ¼Êþ(€ êUÏà¾^U¡9lÄ6^÷–,ªÁŸaKFJÚ6§yHëjÂ}Êì®Ý ­º5 v÷_ßzÌþ”Žîrp+róåFiù,ðœ2w¸YyaHyXs÷æön´„û™ðx_Wþ>„‰Î˜ü¼ÀÓ’Ž¾Þžïz~¸_w§AÈ–ý4x9.¶´_ªùV%ôáÕ–=ÀùN±½äžÓ5XÕüº¾˜Ý~¯ÛyÁ×ÓM^/%y[ë—’²Z²ù>ÛŸêj(¶²¸„Ò¨E˜m—Œ$b¼ ˜‘~il/ìaÓÊ@ œ!^ñÓAĤ€oÛ~+uêÁ×G‡_w¥qÞÿú¾ÒÙƒÇ,šÍ–!ãRF‹ºcCsîí×ÛþðÌͯP&ù ?€n:¢qÑPڶ̘ø‡(±2b¶TìÒA—aSª‚eÓjri’K,lZ}´¤²xo+fÌol›j‡-»žÌoéAlÛpK´mZWkd¿£ï, L“2•Åè[“-cGVbuÆ6Ò"ß[fYú¾Æ²š¤‚Y¾S»÷üœƒk»w¶6UæñÜoý—'e&}¿4¬‘`Ð8ÐoÚŠï¡ZüD^zÚä)P<%5¬Íȯp~C »¥öéç„ù¤T5/KÊÄ^Ÿ:‹jdÿêÞuç’å¸{‚~‡þc@’ÝTÞ/6üCúd4nc Ë:VÃ0r‹ÖÈ8Mò øö®ˆX+"kïý‘òi‡Ô9±ëËʪÊKäŠ+Þm€ˆïñ¾Ž8…“Vïpš½·AÛ=º­ÂøöáñZŸIN›½w‹·:Aë›ÙޏÙ͸#Çr/üXû¢Çz·Â•ìAjZׂKý½cSˆ‡…‘ïàåµaômél@/1ò?m¦il[¬ýÇG³ÑŸ®+¶ÂØ(έ46¤x,_:ÂÉ9£º7óÑUz>GŸÎ;÷§ß=}m£pÿk: ç•aã6íÐóŸ3þ}ùeÓŠ¦žê:¤mÆ´ªý¢Ô§-!òÐŽ%.ZÅ•l KDì±—­†QGås|Æ»ñœ.íi,• ` \ŽpjˆO$\FÍÚx4¶Ì™©e6@sDŸ/£Eñ<:Lù¶?.–-qÞÔ¼‚Ø£qRcß>²d£n€bÍt0ÅX¬^¡ð.ÌëIö|7 ÂÞ¬êÝm×iÿ§1”9ä8𔀽E?ßb€B¼³TÕS¼½ø§˜ÛVVöýZ#š-?Ët¥ñ±ÛµadˆûfŒxú­]½ö3ÌÙ²“õf$4;5ð´æf@ÀŒDó2o+.:]ar®<nq6¨QìG£Íl@cjÖ褫Õ="ÓÇ­_³dI² ‹qZ|óÑx-yåc`åÖÀõ!4e]Ðr ~˜±Ž^î`»7 Æ™;N="–¤Õ6’†gÉu—QÓß# ÍÂŒ •GªÏF>.ŒÏ ~¯Ý3[R×eÔ´þn[õX=¼mÆ¢Ž0ôuÑuh^ë-Û ?͈މQ“:Î(òݸ<£wJuï3»ÆFºÄ$s7¿iLèQxLRÿ^òÿlØæb(3Í3òh«¯7gÔF:ßÐ@² `„k—j&¥3XjÆeÆ3zš=‚zï­^{71\1£>ˆâE±C¦H¨¬ÇCº±,Î0´\Û»¾ÚóqÃxí,€/E¾ÚÒ!”nLQIØ„Z‡a"ÏÕmnf_¶qÿ}x4#â~7"6/ÆuØ?ŽkIûüfd«’8Qõ­œD1›ÀÀA¸_ zÁ½U§"ˆ9=Ò^oàdˆíÞ8æAtkiÉÇ#8ã]ã¶ø¢U6 ñãÍLdá]ã­aö©|Á(¹ßJoO ׆1åúhÜüíé¤K%ﮩŠÎô÷?7BÎc×ßܘEQà$äðö¼6(9÷í6m¥BaÉUa$R0j[O׆Ñ[½ü‡©XÑ{=¢ÏóÍ>=€"º+Qè3ÌwãÑêiœ#ϧ€ÁÜov3Žl+Œo¯M¦öuÂ=·:©FG²t[úáéZ¦¢] `ŸnØÒ Mwpꂯ׼Â-î:^v „]_¯¥rG'¯;â™ÍÑøÍ×F£7#ïÿР¹ûµ4Ûê´Ï—bw„ _Yø:îIëÁÞŠ§35ýïEž”°ì¢iׇ/á‹BéqܽÕDïQÎ,ÎêF;ÖßåÂŽkCÌïSÌ×'ä>Ë™QØÅ…C6ð×!d²QñÖë Ÿ­†°˜ã.XÃdÔÑuñÚ£ÕÄ ¸Ûep؃v|èö $é¦+hVèŠDvèrçÆ;üyH þzÈ |KµâC‹\Ì ²ã.«õŽ‘H¯ë&=7pô€×ºjѽW8ºw \bÔÂ8§LTÀÒ®IEA› JSŸÿÐå ß_Œ=BgMíófÄËŒ·º£ðbÍÆññ7£è7a¯@{ÏÞ: x(]Ãð̾›¡8ãùnÆc qÇ0ŒYàÂQÇ<nv3²[0¾}x4³úП6zQ÷{ŠÌËnñaâQ3ûpCC÷8u êÜHáuçN5~â`Ý·ÇSª"~ºšÂ >8‹'‘¨Œuß:|öSÐøðïCOœY§?ÉA–ã sœÚâJ?³G5cvžXœ§wx…áMr~SE^ñ›HÎ ¥åšìI”åwÉ]lצW®¹* õ-gjÍ7a;id§\ïF|(›oäf16è`‰±W‹j4É–Ih@©4úN.³¥z]ç“ë›Ø÷ku"üZ3V™äÊéb-Ûñë2'ÑÊüh6«‹1òf¢òeëÙÈטö×eÖ“®š{·p³Æ€ÄXeLÿðtmÅP¿¯}âÙ˜:ažË¬Ý0ßà4S½ £õÖßÁýZ§ÉH<§3½ŽvÅÁ5Qð£Âü(ãá}ÁÈG yضvo »<Ìu«nÍì}{è?Ì÷>u£Å=^ÙRá2šÑMš¯±ñVt ¹fï/ìlÚ.×6 p`ú"äfnR}ÇŒM1š£: a|Ãx×]Ù˜-´‰Üc¡°´j‘û¶,ü¨Ä”Âú!ws†‡pµL²2&è«7£v hhWÍ%®µLí‡L*]Y,.¬u\‹ŽÝ¦÷i<¯Ü®éf©éƒ˜F<—Ôé7­òŰèØeVí1^›–òªåÍêÉé2öksQ^¸¿nkàÚ´vm÷k/cQºµ²–Ša¸×­®ù~ÛÇG¸N™HJÂ>FQôI‚U¨ vö¿šPôýY±Ì›±ã\].šsh›ø ºèI„öŽ.×.J|íË8+½×Ûµj6ãÔH‹Leܯìçôø\ÇŒ›ÝŒ|ØËõ#F¯…ù~³›‘ïàš<îLï`xðý˜IrúmF¬Dl ̾”Iñ#ÄaÙ»ß W²vìXöâ%ÊA»?U¼€/3ô\ ãÅ­Æ0D¦âùñip³ÇÜ/üxܳét‰›Ù·‰0»×i¬Nî¸õÁˆ¯p40 >èW~¥³ ˜ém÷:ÚÀ -®ý ¸ê8<6†ì¹/ŸFÝØÙvm[²é}€ Äð¸9 ñÊâ£_«j‹3ƯîëÌ;×NÐ|nWNWA9V¥Ûµ\·Í(¾îcתš4]çt|õ¼Ü(ìŒ6‹P‡òã_‡ÃÕŧÌ3®4ÛÒ|©û__®™&lWž6¨kßl®Ò³QDÕšŒHvÙòý9¯;ï=àkÆ_ í5õÛs_¶¡j ¼ÎþúÚ)Æã'ê×V±ù*ù1/#äon¾_nÊ,#ç2NŸ<ýO©S¨Šç÷±Û»mB×Ò³R GUc¼»73'ëÍÎîífœÏ3céåi¢æãq£mzJfÔD’»½!݇јÞ7V/Oüüdv-¤ÖØ[1N“Š£+žà›¹­‡Ç½–A-6ó®ñ:©-oà}ýéfa<ˆŸüìíqm¶q º¸òö.£ö§ñ›Í˜L=™ì]SØü FW+̺í7cÇ¡;–%Ù–ã,çËÝÙªï†÷b\‹#æç»rž<}G>OGW9ÿý‡ÿâßÿå_ýöwó/_÷/¿þÕ?þöÿëËôÿíõ?ñûëä¿×_×먎É&vI˜é@\h›¼ót=1éÊJ×&ôÄέF$ŸÏöñÃóÕ’(ã ûâÀ¾ö‡¬kE!J£Ñþ‹´•úÑ‘\¸›lP ¤]-”ªíNƒ:Ÿ:Á” û˜tÓ\,‚žq“b•:­$¹5Q ä´©æ“M»ì2Ä®šÄs'ÒP MXQL¨8qž“Ï[?xUb¼’MT!wÛv¯Àí­FÖõ4`ÌÉ×å®!³àúå^Ôƒ³ðÇ'©5ñrJ¿3ùŠ7oâaaù?¬†…p#úyG­/é2®Å+-“КÀÊÄXà\_Fø“jìóɨíF}& ­[×-©.Æ2éR]o£V·L4Ñ JåèðÂûP`ZˆPG|±M° ‰“Ò¤t–g‚«™‹ÍlÙ~RÁV¥âƒlbZA7Û‡¸ec[Ɖ L×üG41ö*GÊg´«!$'ƺa\HRzµã²‰ø!î7ýžÔĈ•]8q-ZØR&š.²Í„ PŒy˜ç:òqM={ÃÐ,*™öâÆ5Ó,µì2z¤:ŒÝj²‰bký:y£Ò-X „¹R鳊´˜~Ò¶%IYÐÚ„—1 ®ÎËhóÃaX4Ò;’î~ð«_dʿ̩Ê¿ç _fë¿Ìë¡`M¼£ðR[àI‡€M¼P-x©oðB ÁšxG9á¥ÆÂƒÛ7ñR½áê¿øá¥ÊÆûÚ__4ñB½ã뇰‰gµ‘—º$Ï&hâO)ž¼’F±„+6ðRqå¥6Ë“Ž ›xGõå…>̃’ x©9óR›æAÇ&x©zóBçIK‡M4™ì6Q~hç~5[Ùþ€×•0®ãÐ%O®àʦu¡¯^â+-6ïD©çfPŒ.YfG 9阺ڭ§–w#˜bœ¿y˜ØâŒ»^øÀ’±5ÒÀ¬dÞâµå–69UóÑBYË/ž¼øòæ©â‡úÏÊ|ÑDFRlº ’×ìF;VÔÈ^ENçs´A]¯Z uôVêó©Ýq=6±ÄÇ‚>™¢"Ý– †ì*.LièŠ Ù±Ž&òæ''Ò‘Vs^ôñ¦k•kî”-P@©=ç°»í¸ö‡óÚÃþù°—m”ñl«¯û°ûââÙx±¢,w嵡lâ*оÔu¡@6AéÎÎQ%¸PÁµž,•WæócÌN­>r?ÔHÂË+ðvÑÌ›}=Þ$•UGõ&Fá«L=ÔÜ7õGUÝÿèE¢Ø?yHrÍŠêt¬ õfU-l;¾ãø+bÜëÙ¸“µ›È{a/;*S¶œ¸AO¹ƒµ’›‡NȈ¢D÷N,í,SGÚç:lઠ/ë+<Ôb`/+7¼Sãá¡D4ñ¢zÄË:O5)ØÄŸ¨`q–º¸Å`/+h¼¬µñT—ƒM¼SÅãe½§Ú lâe%‘—5Gžê“X/«™¼S÷ä©FŠ5ñ²¢Ê;µWžê´°‰—U]^Öy¨M€¯"•eU#•ÑÔ3còJܺب1P9¼Í®E§àbsÄ8X‚yÙçUãkMØk¶ú8÷+-O½hÎSÑ6ñ¢ÄÏ‹b@/ Yï”zYè©x›x§ÔÑË¢H”Ø„${µ¥Œêmr0« Oê÷B©F`V©¸l‚>Åð©q4GQ_k:«ô=ÊkN°÷°l²¬al168‚îoË~Ñ&òrÎÒf”âZ¤L@MÀe;V‰Qœ•ñ¹æk÷®oˆïh¶ŒIÜÏö 1ŽÁh½®oÞÄ*QBP.ÅØ#ë/Š8E/øC2†çý†7#ocôâú óhûÑè½…¬¾Ž+ÙDüpÜð4Ρ!›»q¤Ò&†ž„”æ`üU1^»®×ö¸òúv#EùaÏ:Ž>?ý°ÞU|3ʲ¢ƒÇ•ÓòÈžº'LÁÍ‹/o ghU/î ’j5\º1ú+£k¬†@̶Dü]$öfœÙjk(š(B(PZ“ÄF,i^Œ¥àݬW$u†d^]÷ÙÄà2',ߤÌW1*Êm4áÍéæJË$³_ˆÊV7UŒ-™êز>¦“…¥¯ ‹¤'6q}Ô‡‚€—ñ:RQÍ êë:.XËÆñÍ¢ø&s6ûÂÕ«f,ž,¶X„Z~À¥ÑúC¯¼Ö¢jœaL‹F?é˹nh€PÜE ãmd`y“ådè0–­pø Õð$Û<Í ãXg¶Ó¸ëžö*~F“ˆæ&‹ß˜Ñ\S»:Û›(Fž0ã8†Õµlâ¨àòlYírF¹áe^³w•çÍ^~H“/\56zHïRcYx:Ï£‰–&aÐM´ZÚTqß…v%<Õ`ÌÇ'Òù5bÔuÆÀ`“)£ä@™Q ØG׎ÊÊÄÛ4þ‰ªŒÃÞ;,¥âƒð%N}öòžëøÆkP=­XoG ~ 2þõc»\Ù°ð£>u¯§Ù×xGsS8¬ó…R ÎejlTlh_í½7tÝn2RæÄ8QQºÇ\8½—y<àå0 4éͨG«øxü!1dK »ØOz?_ÅÕDö×Ü+ 6Ÿ/p0M3?šX„¡”bú9~­ºÅc­íåW7õa;W¢†Ù—,ÍÆÊC®/ ×è,‡}­ÏM8 *ZZÒøÐ•c3B*P}ñ«UöÆ~0Õ25æÍ«­D‹5¤¤FEøxÃaÒÌzC£+ˆmæŽz|*PjÆeB/¢Šhéela C€ž†S‡hU³:j,WêÁ7FqJ mãµ€l3¢^òek%·°}õ ¦p»6l&‘u·Ná1¿âZf'¤ í¬K„mVΊ¥®ºŽ̈9÷žq˜ÿÕ›ˆŸ}öéÝ÷+!+cªšNà„ëÊX’ÆÕÿÂjÒ³s˜²ü±¸ZENþ€&ìý¨q¸1«Ç+Æy¼7WQ 6µ5"Ÿ½ÛjŽ›™Ç;;‹æz/’ݰ[d•MèÒ(Æä¢RjÔÀ×ñ xBäÕ~ñC¦w“MÛZóõ O2L5úÄÿã=ÕÔÁÜŠÏ(2,FôYÏ÷Fáj¦w]„å„%vÓKÞ’Q˜Ï!…‚£ü X/†$G¨omÍÆPŸ‰ê[ñyî»,—‹ xe2`õ›ÎЙ-.pޏB¯áÛnšªG$òPËG2”•i|´ÙгGc²d”Ó˜¨ýø*9SÇ” ‰cêP[#šÀD Ù±M¯«ÑsŽÅ‚W†GÐ’ ª,bßg»®Û!WjÆi\y,D³BNÃ]Ö2W1 £›ˆ1'u°Æ´?ÓÝM½lÆŽE&?X–ºk‡ÑdZdÃŒsßzÑ ÚžvN“ü0‹O©­Ðc*uÏÃx´M³fœO}¹WṟªCG&v¦aÊ¡O#ÆË݃êÒ_nÛ.õqžöcá—ÌÝ»V° Ó·Lîóºªñ ]г ïÖ®nØO9:U-3ãåÃàÊÜÒ8š0N¨v¯À«TÊI3cMžÉö6³¢ ²ùnh!Ý÷ŒÓÄØDü Ø1ü£Iý9¨ÚWBÛ(zQ!öâJHbDì>´êÄK[Е‘½¿o¯ç«ófôyÄH½¼#L/?\ß’wª2cÕ®K9‹J7¾b$zwS~ÈͯVÄX8Ž©Q'™(MYñoÂXGòÃÀètÿVŒœ§7c¤dé&H#?§þs¸ä9ãÐ7wóKµ¼²•DÙ9“)%É2ªÙv–c-üʨ“W»LØØjLTIÓ›EÙvwÉIh"ÉAlˆϗx¨§Ö[ ÅB ã‹Ñ„T°§›ä‚`ãÖËÅÊÈvÉ¿Ïþƒ.ÿ¡hF«0s( nAšS‚¾Ÿ¢]Œîœ?£"ÄhIdj4úÜìØû¤¸Œ2œµm ¨‰Lo1*ËŒ¨S.]ëÝýï´È¡9=K#k¢òWmâ½ ž.w¶Ò4f¬Š÷Y‹ØÊ ôŸE놅FÔrpoäPz³PšQf°_‡B[eÓ@æØV¾µ`y)þÃ' ÖmcuÝ£Û+‡‘Ïгóxuƒ e%éà~¥Ù‹f~©þ0pò|~è6{6Ñë"Æë¤t6º˜dpËöýÙÑ@¨øÃ' ^,8¹-ndÛÙT~ÓÏþÿBtðèÙ˜[qµÓ¼=:ß^Bª´~-TŒÛXнy•p»ÐcDŽ-¤,ƒ«ÍʸEÖI&¡üZÕy¾Ïö#ðHn^FÍ­yߨ™KÏM„^d° ½H„«î#¼2˜ 5„f¤E(Kœ1òƒnA!È gXîÎ)ðŒC„pW’F)™‘ø4§ ˆ’®A<¹ï´BSÑðMì´Ÿ½íh†2´‚FMÝÁfȲi¼Á¢9”B6ºføg€€Ì&2¤1ü‡G#%voF(>7AMà I‚ÈYÊ-Îp¶4*Â&äEÎrs…ÀTŒ¦& „i’nÞpHýikqY–4#’³¼NwÅa?(æQWøÅ‹Âć`Ծ剆M8CT‚HtuîðeìHì¸gÉÁíä¤É),êÆ«“­F²Ô)Ö ²ÏGRÆóŸýT3)¾1©vn‚ z"ýÌIâ×ö‘Nö8ªvÈëh‰MÀ¡¹šp-<ÇùÝÕÏ4ߨ®.ËÁjºÆÞålÑxpc„CQæiúrŸ”³o™¶2„8ۃȕ³Á&$K{ðêúËXÐð•‘û,FCöeh¦œæ$çB´í‚øÉ$oÍØ6³Zs£éQyFÛ»~@Îà^«â~µ„ìwçªÄQ@Å×W†Ä6SN—òï+§™ÕPÍÇMáPÝâUÈæ50sÔŒ-Wœ€cÚJãÅ‚åÑDÎþC÷L~ÅÈÌ%OI’±Î^h¶yü€ö UリP³75ÁuŒ²……dr]Éz§2¨$4›QsS>1«‹¡¦œEÖ +𱬉Ó©_Ó ÆÃ5ÊØÑ€ë‡Z{(­F/•·)ƪÞ4bi{ñjÍѰC½ábBÔžW8®þ`þ–üЦ_½ùtÇ»@ˆBö–\<4GC$ÀOÑ–*…{’õ¦QmÏŠ3»VÕJ [J3ÌITSZ &ët=Òd^O´píIlºdO3JvÔÕÙîµCPxŸo"ž=kò:dÙN“bDÕÍ.㺞ɚDAmzùÕÙ5à½fÙ4Íó ÆÙBj~qŠi|k…[b\ð J?Ÿ"YìbĶ2‡äd|9G§1è/úƒE©å–¡œuz46ow̳×ÍOPá‘2m*Y GxN™Š’áË‘©9lÝÀP ¯˜qf7nkÊ·&ü”UcñBÃÙkÑ¿êEÍÇÏÆ£ o7üô?ru{Õî{ïb²¢êf¬@.Vòº{øqøé"HÛ)ˆ=ü~Íð¾*.3<}qªÚ>žC³PìR¥Æƒ±Ä†ê»#yç£ ÍW7›B0oÈ…¾÷^Ì"…øõƒ§.?zê½ Êj›b’£cÆ w™WÉ„–]qÜ)y¥ƒU¢3¡6ŠÛË ÑqeÌHá÷áb ‡H¼*°&BÑþ&¨O=üIÀ!½?½yEQùâ)Gm†8•ê}Ñ<À ünÄ™únÔ•4šHiÖã‡O¨.Kpà0rÌß›âAdü€™.µ“Óæ©|WYµ¡Ø0` Q·¡ø*=&S¢îF–GÈF'`ÃÙJM´Sœ;óVDn¸L! ˆ Dœ£µŸ7rHéGŸ?©XÈ2rý0X BÎ~q}CÏëüÐ2ªí¤ÇšlBˆÍ ƒh ųZ6x >“Bc•ãûÈÌ’Ê „‡³¬óðC}¦-ív̯ÞB1ö3£ÃˆXŸœÑYû¡‰l暪±º±M7:f¡Uý¡ ´½Khß­…©žr®øÜ :Ãû—Ùi®¢, X¨Å8*ª¢ˆJÝÊ0¢ª ›Pó¶ZFñø:l&Fƒ 4d0x3"·ó€dДòpü@ið¤Ïã§XŒÓ?™à¡!µÇÿûå⌦ÞUÆÅæ®Ì¬É@‰Îl6!ծ̛–/öÊ?ôV/£¦'„1ZXÆ/NíPãj‡½r¢ Í:=šÈ ±.Tö½¹<íÚŽ ˜9? y%¨òƒ éAÏE*MÇNl”ú8Œg”ën¯FµQ¡ÊU`ôižP¤Æ~¨oÉ8òv×UL‹¶k™éFå>‹Q£$llzH²Q†Ä8ÛDÈ B¢ßi+Ð=à§̈QzxðnD¦ÃÝØ‚‹rþ 飙W#ðòI5¯,aç¨[ M¸tÖYgA„[y¨Þ ’©€Á¶EåÐ •ú2¼ÃÚ*t þkסÜY40jÂÜ*ÄØiä./Fc§‰+NûAÝ Ñõ®,&F×R\®B ‘¥®?l\Í•[ŒVShFC1ŽnÇé¯Ê{ƒ±±]ž¸±®E…Ú²l”ãÅUâ¡EEÌ ð$õ%šˆ®áÿ|5KªFpmbdbWw‰nbF =6a‚qg½7‘­µuEpd³Ç|&ï(fitåd]QÝ\7~ñ%g,§DÝmɰ* õe™›eoFÝuzq5ÏתmË"…Ô7ìycjµ„š-A!MhùOKæ W³Æ9uDz’/(!M0±"jËÆP ºQpþ±‰J¢²;'$×*ãF«ô½O©y°@b¬–!kgbl*,aaˆ·&ÆZ%#61ÆÔtW bœ‰±>6;ä4éÉ‘y3^¾r3ãN™]«Ù²LïzQ­! ãÊUv5tSwÍ–ãÊ»jYkßh— IŸŸ~ñF›$‘(¸ÅïÅbAÏi†MÓ³`£aþ4Ø>©ü)j¢jm"”jµ^ßBo•?ÜËÂÕŸTÃuAkYÝR6qþðòê1Ó³qÝ›€>¬2Xab²is{)Z­=&¶1NÜ…2$×0<ÔzUí*?© ®ŽÃSvø®ÊW…6ØÛñƒG§&#h2ªGœ©8*<Òò¦¬0–º жÔGD)œåædÕÍt4ÑŠ„.‚ «Ä@4¿Jˆk!R¬Y rŒYªIŒ–Ž*FS¨(×¢6]ÃØ‚ˆœ¸J'´ðÄØSFá5? TKÿgœïÊèß^üà:ê/ןÔÙãÜ; 3i{Åq¿K¾'›Àc¢Œ¬º{Çé»P$ÚÏœÝ3¦Mt"ÍéD´A.v…Î^½hÄ2ûü.ÞâEIth뎦o×Úõ-bIŠ yxfu{º©†£ÚDÒœºÀЂMîþùns°~ñ˜,÷/ozèÔÙãS3Mòoïýð¬Þö¯ù÷¹‰š)^ú-~(Z®¡&gjËv¬®'Fã¡(Ó!ÂBÒDmø!á$)å·"ÚÕ«Ho œŠØ‡8 ÑH­ru÷*óÕ6Ðå—Ïq¼LÑohÔŠ˜ë·°+Œ£vT‡£+@¬€ˆ c£¼Û©!² ˜¥ÆRÅc¢{šŒ1såÁa¢{š±춤l]ì`´ÉòŠ ±É8{ó"y#E.ž62™¼azåv·É^0é±k÷n+‘Zo« ðÑo8zrBBN¬ð¡5Å]VßO(Aжý0quÛ™¹$¦saÆÆ&@Z¾Þ~XÝ;Á²àÈà}~Œãþ;ƒoñCîüadgáç‚ì…¾&óöf¹Â‘û-#nd‚ÝMv±g”<¨ÍŒ8×Uuœ90`ìM? ¼èó—ÛGÃ`­Íøh׳9‚z±¥&F2f' P‹ñÈ›—d«ƒ´Ýýõ&°:‹>i^Ò4)ÁG¹Ü!°ó†ÓôŃ>p& |ó$y”:#âÛèz0¶Å¢è‡Jž´mj„‚LMˆýkÈF?)ŠŠ 1¬qÀÒ*ÿ>pC÷Æ·©‘£]^„O).öÇ?ûóÿð¿^ÿ”?þÍ 7çeûZò±öÈô-þûå¼ÖíG¬øˆxyy¿¸öìÃǾö|ÖJ¹>B è¼zd¨ÎþÒ£FâôÓ&ò&‰À8ôïPÂY@ÎDN !{ñåIš¶P¨ëúøEí 1äVÇÇÛý¤…žÖÇ—8zøŒ[}óšÅ€ä 15\Œ–ÿxD=hüMx~¿š ”ŒY¾ÆÎ¸Ê<¡ßâ‡<2ïGåÓ8{s”£P`õT^½ý \q3*&`ùù(Ñûa¡4òBßühlk†9 ¡X®¹Ö™è^åÝZ*(Ž%WƒR"Í*ÑM‹ždo÷¡Gƒç)Úvâ7}óÀLýº:~™Ú¥(Ëó$©ø ô aG2‚n·ó’¼O}8:¨¹W GCÕ€úöâ­ýeÆËGÁ±“ñ÷…òEâ³óêDU}Ô‘ÓðZlöý¢{{ÓƒE k/×ùüçWxÒèüæ?˜b˜é˜‚ó9ÈÛßÁµú£Š§«CBÔ_¹¬}ÓØ¨@úB)” Ö“4ý·ø¡»=à ÉýÌæo»&Z¦wcPB®5 ?8¯–Pc§æý |éâ_¼Ss*}üË¿ýÕï>þÙ_ýmN¿þúÛo~ýû_ýÓÇÿøþñ7¿üøí×ÿôË?ÿø_]Wý7ׯÿÿÿåõ?zmþŸþñw¿ûåoõï~ÿ»ÿåW¿üïýÛ¿ûÍoÿñ¿üíq½ïÿÒö¿ÿï~õO÷‡oÿǯÄ¿ÿõ/ÿù_~ËŸ½ýã·ßüóoåÖþ!}ü«ë¿ÿðŸ>üþCþøW¿¹þùo®ÿþ»’¥»ÄƒV‰°1¤^ôå À!âmSÖ#©5SÄõVåY+8ø‡¼ZÉRnúúÏ?üáú—{ýÃÿu™þÓÇöñüø¿ýïéã?Éÿg”§7lD~U‘þö`NÌЃrÇaÀ5«ÊXºÑÊho2shÖzb,3ãhB8ø…›ó†ni³aÖ}ófË!8Y@©Ž{‰Ø$Ää£_4¾}¸=ÍÚn<ñÑD¼šãf‡{{ýv?K‘pûÚöŸ¬ÿ±úßêâïbéqßðqž–艴«:e?Ë}xi†\Î()Åã=óÙˆž0Sy2Ÿ}ûQKï0ý¤Ôrpxx3{ì,•[‘MÇúpù)šJìùñu#?þ‰Ús/?9—Ú§!Â’WêõÐ{¦*ž†õç§b¼š,ÏëíñybÆèö8m_Îï§ÁŽäÃàþüôÃ1^Mšç·Íõú?Û¥úßüVî÷öãïÿãÕèmµþ Y°ÿ¿X««À4¢|r°úsÓ]Û9“&ë¶-ä0Iaì|ýp»Z5U¬GND ·Wíw¶Yz­ë~¥ø<¬DFúžªé«â^¿ðÅ\<¿’ Yë¦ü0«ÜU¦–ªn·r0Êý%«Ï¿k·º€Ÿ¡Mä¦fˆ—ý1™5sT:5[4ÉE¶å&¦b//½X98Kal•HÃÔû­êvSd¼·Ú² E³U/4d*o×}¯ƒ”©ü%iƭè 6Pé;®ÝÇͨòy¡h Ð,À7 ó©jÃ4cQ+IDüf3í±f¹ÄúEÂOrp* õÉôϪ)<¢Š#ø‰z6°¢£*ixÚ:D[…ùW÷4â"©9¾Â”ŽAÊë.ºM4ÇJ‹pì;4œˆþ•E=4µµ qlÞ¯­ò×âô`> ÇžÖ‚ZÇ×;'å^hTÆRIU@rÓÒŸ´ÿǵÃÅØ¢QÉ‚b…e>Ê~ì€Ð¡Ü%Ü›=^ö ªPÚýÚG«‡ñìA˜ÞjÊ–ïÏU„2Zöã;(¬ƒ±\Á È’¶‘à6­0É¡€§´³†‰$7kL[ëpk¥Öt›ê"¹”F[ $ÍJ‡ãÚkz“‚ºZ¥¬ía܆˜s)YÔróг¸Tò¦QaN‘êMŒâC<Ë„§è”g_/¯Õ‘©<Í,vÅ zGʹ¼í ¥$‚ÿ©:Æ>~a½<Ót7¤žÏ$©‰¥>³Qgž_NØX3Tä{€:J^ìµwÏ”CN«y:s¤z¿v)ó¼ÝZ=ŒgNs÷ü+­µa²D‹Ú¦’Ìï²­P"þfNÑ€l&å‡pØÝx¬$§yzU“”í+BvT_®ø7)üdiÕ™‚’PÅ#b;{†‹”=š¬u¤9M~6 s&P ÑR4îdÊ‚§+i©ƒ2‚Õ]qº÷׊¢IGJ•ÌÍXÖÀ•šuiú`²¸TBiÒEwBuÖRTIÂüŒ0ËHd¡ `ñ$åË÷µFú2H2=®•µÂV¸£Í0Þq`n­Ê{2cè_q`\&`q^»M9L,ϧºMøûQP ]\gÛgâïfL‹U¡¼ÌÙ¤L˜œLZñ“¥µf±#«hл*]n¥%G6íÃho l9¯U9Á"Ît‡ÕÓ°hVe¨ìŽà4'T{ÜÈoxœÇk¾‹Ê8wbû% / â»,J"LYù*‰ïâäž@ºRn¨þ½äçN¥nÐ9…1§ *fO¢‰ÈT¨ý#£HÌÒÁ ¶“¬ûVG=# [ül&wJ΂fkíY”&{öñß1øÀ ÛÄ%'DSì]-†ø,^¥·ä †¸ùì²WU`×z0,PZ“Ny}7/ì%ñ «×­Ð  F?؆Fß®U E2,„Ò -[‰Ðð~Eô׈bˆ¨<Þë‹uAhÜš:®—Ú[ɬëxÏ*}ñŠ–È¤”=cf身O©½S«!Ikà•O7C/¶ž[\ð9³Y%“׆Œ95ToÂK‰ýÐ2ïmñ\¤•_afbµîpe"YRC+ç°>…JÊò`u81‡¸[å8¼ÝŠ2#aG9u&«`æÚ3Æ KÞH¨ÃNk“‹:6÷ð¦/F ²ÈO}|}3RÖ$Yé…u:²—wENú쇦3,I=¡ÔwM{ æjˆ¼=ßî úÑýSTÛT¿}0GjÏŒ—©;èçæŸYÕ#•ÈGq •›«NÙÔo¾äØvöM¶¼¼ú¡ÜAWDœçoHÈ Í'L“…ÓÔöÌ\Kôæ4ûÉœoYäÍŸ›¦×ºð<ƒ\qùßôFs¦ç¹¨'¬‡~ž kS_LÓ`%AwMÈFH«ãϋ҈‚¤*»Ra6éñ‰RL/㤨RœD­R«ï¥&ÐÍÄýÇF¾«h¾vxïªý«¢Š~¥A$kïKDØ×+2 ÂHþòúvŸûA]„‡~çË臖AÝõ±VpÞû¡Þfêýàíд³endstream endobj 1052 0 obj << /Length 65536 >> stream ¨¥xø¯£Êq ý@Ç«T”©<:%`B{â›Ëš´\VGš<É·ÃxÕÑ]QÆLÃ`Ú §\³sñÀ.9k¬é¨B_>p&ÐêPêK:æ’o°¾¼¾ßÇÅSÝ$á¸ð};/7ã*,w£pŽ\—a XkÄqü­âºÌ^è}ƒ€YeeIȧŸ æjÚ¿Z´ÊN¸R“Çàa¿£šŠˆT¥$› ºº®u"ö/•?|x¹°~~w~¾ÝS?¸£¼¿û-`ŸßYë^,T?¼»¨=ßíßvÑoïî¸Ï»ó¯÷òÏïnÄÏ·ûáOD0ÿâ÷N™xŠ ñ‡ŸâŸÿ¼¸#¿#2Ä ìwĆ”Ãúó£Cöçß²¾+BÄ>|GŒÈ˜¼ß%rvóÏ‘¦ýó#EÖÂwÅŠ¬‰ïŠiß/²¾'bd-|WÌè¡?'jdïò»âFÃêçDŽ8(¾#vdM|WôÈféwÅ8ÑvÉ^æ÷Ĭ ßE²¾+Žôð~N$‰,ïˆ%‘lùÑ$òy¾#žÄùŽˆ’5ñ]1%'&ýü¨ïˆ+‘»ú‘%§ÖþÜØ’ó[~tÉXÂß_òLÉŸar:ØÏ1Yße²7ñ]q&kâ{"Mî;ÿÜXßåÏ6ÙC|W¼I›xqbbÀwÄœ"SíúýöŸ þFRßÏE¿­߃³…Ÿ€û+z…RÚß…S²íï@*­‰ïÂ*¹µZyK2¹Ç«‚sûó#VÜ-~ÌŠ}øùa;n1߸ûÿCú¿ùí/ù«õ›ßüøË#V©°8ðÿf«h°›¢ RHœ¼&ËKV´éœåõݹ޾ ®›'åFB‡TE(¥´+6Ü˨¢e¦åUvÉÉŸ ºšte H±„  w[Ý16-4¥eåéÜUK‹+¿v 5Ó‘ª?ì`ª¨Gi&“)2FVµ[êŒ[I8sQðrõ©NÜ»±™„ï×wsñ¼Õz·¼¶É@O_‘E¶õ´‡2„ó¯uÚ©ªÖf \XV$©‰0MAÍEKöS»äõòÚå æ‚…$Šˆ£U-¶2¬jžExíŽh@PìÊzyÙ´åNã:zfÕIH,pÑ2©}€âVkÇK—fY¶!d'Õœív7}`sÇÃè ãïVñ¼¯ÄÇ=Œr¸_ùÑ!<Âym÷š÷`5[‚ÂÈqó|­fÙ›q„±ðƒËÌðL‰»º¯ìmònIÕ ¼Äã+¬á»âDÇÕŒ¢€VZ°V5™ B°øºí¼®•‚Ô¨­>b¦}/Ò¡’/>î˜ìíðÁ!®=Çì>¾Â<‡2ÇÁœlUªÑð%z_U«·ÅWàd*þ¸ñEÀ”Æá­¶³Ÿ"¢ÃO>Ý8£§Ù¨Ô£_,YÃåMI¹TùÇz9]]3®‘»‡X$¿¡XðoS4¯¦ì<›L›N ]Ò>oòô‚r1/®¾%hx5LfUµ“a–;M$MËÏl.ZsÞ&š€d畬‡™ )Õ™õÖ¤,:Öâ©Bí«.Õ&š£“;‡à;µà(ÃVEµÚ±¹Y&£5P¨™²²KhbùF4E«ÄÙ€¤°E²SúWÄ„P7ôSpq“«¾Fÿä‰Ï*‚פ*Ë›a9žjõom€ó‘U¾Äƒgnþåá#ˆK•X‘@_­-l”V¯a³ ê‰h@é¾4£*œ¼x킼±ÎS/¤5)>¡gô•±«Ù%Ò&]¥X™í\2Üé?CϬ²¸$©#(ý¼^µdìä9DbG‚­òͤ\Èe’žr ôäYkMŠpBïÈZ«ÌRœE<Bc|`S¾#ÝËPyò E=dê€M?X_ží0FÏ…Xr5UÚ\nTÚäv­`¢Öa­VˆN$¨¤K´Þ2×lÓv454&àj-·A¾1Y…å×»n©³]IÏ3¡gž 9 ‘ª™Ö-ª“ÝÛ¶ ߬-wYÎÏ{ùîßV²¯ŽÔÏøQ#\¢§Ecæ5Ìüsp)'vÅÈã3fõ>£˜‘¥XÊjØ!•¼Ñ£CÈù+Xªx¦/Þu:„„õXޝ!u-4 –—ÿýØ–¯>͇³¿·"k›>qjq¸!•8YÛ4ñ°ej)Xû-Ü… ¾îÕFM±âwžÞ)//N-È43e0Ômó_E< Ž3ËùØ2¤¸€yžU”*–@yÙÌñ~þoÿ¯e˜NJÍl ¶‰_^¡ÆµXľ²´‚¸¶Åâm’¦_mZAT–ˆÛjƒõ¤P7YOëRQÄ2‰¼ë*¨6ëWYZ¦HýHXH›—[+á׋ç`µº‘+Þ>ðKè¢)*Ö†3‰b-jn–ˆÖ‡®¿kr™ÃfY´· *j)£µx-°Z}¡C_œª}maÝJNuÔ£ÂdOÆ\ÂÃ4ñ!9(pµ“imº<*•¿ÈÊE™–¾,Pco@k-™ø»è“ø^4Ê?PExc\[í†nÒ„2ið^påW PûZäð M×R†u°x½ù°¹šòr2h¦…hÕάW‰¿_ËÔ“ ƒAåÁ×ñ²Eöé ÊÌÄSI¯±@ˆ ÆÞý0’*Ü|âßÙ·×R”+_êÃÀÁN¶ÛEÌHsƒy²$´î]PèP!i¨¨Ù<Ç‘Ì{4Ç{š0°…Û ~+~³‰‰õ}AVa†í³CΦî«îËp”Ú|"ñ›‰×w–œëÝvÏ19c©.g‡=˜=T•SF¶¬WN3óÜ&ÝäÍêè;@lqÑS…²¤õÞ\u`»—h©“î«ÊýüoN-7ò”Ü^+Ü~ƒ7_M©MÅÎå7YñMÙˆråLÞÛ£ëžâ"ˆ&U&H^ðñ«É[é±s°öK³:uZ$Ñwx‰\L {W#VÓ̒ΊVå¾bÝæÒO4u „™¶U l] $æÛÊæØÐ/ãá9Ò#Ýøç—H@£Sj\*!Ê8¡ìáwsq"@aBæ|6uŸLë~!€Ë{-\B\ŽeÁê]†îéØÃº½úç‘uÄTƒëYH \JÙ\yÀ!œ3D½xš`Þ-GšEkéÀµ½úC*JNÈ+íIýR€s@\¿‚G¶ÀY¹Q¹(VÇ]ulÛv.’±>3Êiq|eE¦Œ‘DT7^ÅÀ‚K£v†• w©Ë]àkãÝpQLAí:èʰÕdª¥æž•QÜNpæ¶ÃƒR'u<;áö5Š 2}åQ˜w™º \ØBežH?‘oŠy››§o„9ª¥ eÅNCœø_^äÏ>ÂUŽ\±<8‘G·—}Éø¼Bë1VEHðžÔsRj€*‘Ëö}õ¶am¢Sß|Òµ—š˜æ%,f>£·%3ñÙ5 nÜ+Gâ¥Ëñjw´À«î7`Ÿi![º2°¤¨Û"ÆÅ‰§‡6ÑY•J~ȉDÚÔWæ ¾;»ÖŠGˆ1ÍSðò†Ù„Út('tm`­’ª Øó$vÎ"šÆÑ1ÒÝâÊ6@².Øûb±±ò;+Óóöj½³N¼\_®£/Ö\'G}Žk…NkÐ+°ÊQº”cN O`4ÐÊouQÊîȉE;l}ù.xÂOZL„-¡ 64(þÞjÝé³}ºFé0ùÁH®iy³ Ý{k·6ñä¸gêØ,q0”PÚ¹ÒAŒjOGE^Q%J3³à 8"g¢Í&¬¬Š£;Ž[bÜQg¹d§,,<,vë^$Bâ´VÈùa†Èá¢,ü0ë&þÑ’/#¤§_œ/ÈýŽS¶Eè¿çœm¡áï:iÛ«øž³¶Ónri÷òKe;Ñ\\ÓH̸O¶É5Ñer*&Á$U Q'FjRöŒÓSk9ÖÍ}}=£,ýtBXï&Lþéõ¹ÌÖ›W§¸—ç½WgC r»Lî+/…?$HlÊú6HSo5R™_®4á× iú˜D²ç;t¨D°yˆÓY`u’ùœÈ¡§ T’½­N¨ù½’g-ï¹*öÂ_:6¯\ Wî’ ß—ÎÕK7ì…ËfM¼pð^»‚Ï„ßì?wb‚Þöí×?ýò·ÿò«¾‘~(+âù‚6ůWÅ’ø“£ÅÃ/þ9j][åq5X$dPWô+8·IH—ÛÏ8PŒú˜½f½;}×j??}°9â«BìÅ T­Yëò O¤Ì+¿H®¨‰*íb“…ä'œÜj«4SX–DeþÈ]ÜÒ/8§–I&ã.^ǶõŠkµ.ËO¸vØz¯¬Îʳv3í.g àkP¥\þÒ`Óuä'ºñ‰,Ä>m“4©ÄaûãblˆÄ…?¶½œ ’Eõ~µÕfQb#صâ£RBòšºŽdÝT+šG -T­mñ¡ yEùR™H¾”€o±Z‚ϓޣ–n°íøŽ|Ûi¤B…‹Þˆ£±:ýu€ ò^»iÂNÃò¿«VW®…ªùò“2Ù¯¡ú¾6Á½ãʶaT`b VTÕJ5.£™O[ _e»*Ä«fiÛËm¹"œÒJÚÑ®¢ÀCá‹ š29íŒ4œ%®eóGÓ~Â[Å7 »œpÈzQ׬øËig5è5s²ÊwF[tÝj‡à潎 IãþBÖ biÃ4å?)x5p¯¡Â‹?aà®Öê'B8Ûš?¹ à!þ\íX·Y£]¸±Ø€ºíT?á¤)éO0ÐP@p2äH ÌZ»3]!ógdö€Dš Ûøbù©Úi¹QtZyú„›Ÿ€ºé ²{é¾WSµ&QûÖ"‡¨q X<"HÉË/"k²ëòò\?¢ õå OÉ ÙšÁÅY]'ZŠ=ÓkÕcÈ™-ª«yÈÙJq_sJîóÇÙT?óì9Ñf¤˜m.Ø2ûä¸ýXFöÉ0ÔTaÕæÖ>ÌH§¯(—¤nŽÅÝÔ“Æ`JVâ'\[´*å0â’¤#£Žðd*VF«1í¯õ“ØëæZØ3rµ¨ÐŽÃ‡dÚX¤CäiHVNoÈ"|ɳºÎ™’´oJÛÊOÙÍFµ$ í£Vm7^WM(8 AB, Ï^·±Ù57e|FŽÄl`ŠžR:’r«xü4vN’+}ÅÚª–6°ÂÕœ”ü—õ²»…¾àZÅk쨅’ bÄ*Ú¬ŠýO¼6o át!ïË*Åiм-3.h’«ÞªË(zÅŠ]PHWR¦T*[áÂ.!7ëU–­ÛV÷' ¾‘c©ÓD³B ¿€§|5À`ù'²—[»ÃžÑÂñH(¬×KJÙ':ì¬])Õì}0Bs,ý¡Äš†Ú¨97[µí72“xJÚlfpEØmlÓ=¨ Ê«O +ÂtÁ&ˆøúFaì „z9éÞ]&žê“·¦µìë½Ü,[]L¼E&52š–¿Üìf$wÁ™Ì§ªÆo²)²,S½=MŠÑÅNÊXù…Sôg˜áJ|×Ê' y½O«©m'ù €A#Ú‰b¯LjÊ%=óÈk೫1«SãÊðáÀ®U£Nt5ZM177–’GH–>™Ëb‰¥Æ¾ï6_ß°*ͱP©´‡Ïh–l F tY‘;°?`çƒUC[ÌØ×†Ï«øW[”|€«àÏÉPOhÜŒàžjêñ ”1W@ibä®2S%Ïe“ì:‡eèZ³5„³9þZ_вé„çdí Ö . ª 2üQƒZª»;\àÀ(%Îö,ådíÔY‹²ÑbœA[€ÓI³/•]¯NÈÆh( šÅùÁ^ôcf+ŽþɲÝlBÐHÇtÑóZ™IIúj¾ .8²!EÅFë'0K¬¨°€Í Y«­¼r5> ßÕÃ×&rDw؆ŸÁj;­pÞQÀ¸Zõrꨥ•a&d& 2†y5Ï™g%Œ]Ee*]\„$P+kˆ=C²o»raX«ð2úÝšðÅÌ•Å*R¶I›ÔÒc“_¬Ò{ĺª™?dEùå%ðgÿßüË¿ûÁ?þÙß ð×?þòWÿtõÿÃÿò‡ß ø³¿~÷¢¿ý›ãøŸ$ "›®HrKRÛQhxIÎQrPH°‹0„–¿4î^56Ÿ‘Qk9ø¨Žff–¿–µÿIs®¹ã5ç&Þ£H÷f'Ћ9q'Í¥x¦M¡Í›’ú..§ù•ƒbWæ?ÊP›ïïV0D<=ÇÙö>¦Ôm¢üÙ zñܶýbÙšf,¨à¢*íÞ-³‚¹Îõ°B]F»=¨Ù*Dš1“u½C­æ«fÄqô}Oòáé+«1#x©ŽÂ¿Í ASålgLFÇØT¦Ûô>¥éÞ˜Ö§23Ò®Õs£#Q'ÿºZ¥°…`ȶ`8ûš _HÜÔM á¢0,R)Éñ¯¾BŠÎŽUE”ïÊ/Ðít ã䎤U­ß0ô#ÃÜ]%¦%Þ™C§Ò1d7¨Ãë¯[Z‹Þ&«Ñ FTÂRc£¢A¨˜‹¹¶E³mµ€aØ5(jÁŠíÑœ9Ôå4°SÐ* $ªVƒíh7ç(MVAV˜ÍO^Èë±y@WìZÿÃ=RpÆŽ¯PÆQ9a[MmKN¤gSy‚2°×kyrW±ËtŪ‘>T°Âò¡Wò5/+1hûßy8Î-Ek)tV'ë‚ó•Ö™±Q[S“8:š•âTc£´dÕˆŒþnSò \å´éWô(‹|°N'Õef°>)ý–44IBª‰¬ô<é3²Âåbý#M»²m¤…_vdž™µ^!ý2:éɸÝfDôAÝÐðÖ¬X£xkka\(y®ð€ósÍ7Ë.U¸žZñ|{iDM±4×'þ/h3ÛÀsd2ûX»qØ2BW ±ñàvaÞåjŽGHÊé×°‰6ÏBèË“«guOMË—© ¥{NHÐ}ç ®»#UC£Ÿ¹NÉÃüÔíU”/åäÉ?Þ\øfõ„ >÷€kª°ö"Ev4U h7m§\^ΆÀ’8 Èò-†üß!ÙñEÌ ö*b!ŸWÙúv·ÌY¯X4<’kã¿«µB¢Õ‘áZÎîz®8i) iÍ4¶fÈ‚§5ËÅŸø8ì’˜ÌE¼3qû–²¡­jÒd2ÆxI7év^IGÇ´¨69>Ý š‰hÛøñ“Ì\–Î6‹Sgâ·gž)þoI °¤óBéW3²r‚IF0Ü0¬Ì¨† ÚàJ˜ºÓx ¤£`oøÚCñÌJÝ…,^!‡ƒÄ¨ÌXK.5bHQ™IÊb¸’wGNFª}ÕZ,:hK áÕdk“-üĹÊ|›qW/ú\^7 ²êº9û§Y¬]iˆ˜É’I™xtôt$!rM¬ÐŒŽŠÑc(ºa¿} y«¹ ,¢ ˆ?ÈPë“ YáH£\VuôÉè¡ØM»Å`ì<»o¾~1r+ÙP6Y_ˆÔÌ>H!ÂAT3HÝî†FŠëÓ8zêf‡ø=$« Š;å3Ÿ-Ø 7prj©kÑêF»ÓH©ùí©×b<ÓDÙ¥Ä]_Œy&°ét«à`²ºÅà‰Œ™lϪb4¦oXƒF^à×®Y<ñ¬3™ÓÙïÙjËëYC׎ßbH¬½kù\ Ç•”½¤_5Lëø„kÑ\§ bpšmº<½Â^·æÛ­üŸ3yðd0#ucg,£4ÓØ&•«ØòªNËæ%iüh1œ’÷‚(F©ûà¡Äšè)êgœð¯Æ'hܧ‘ï`B#YfzP&Â^ð¼[¼FVMPs£H嫆E+‚Ýj&u /ÂÚ×ÒW<äg»¡fG¡ˆ°qÆ,* ´ÆâÆÅÃh=ÓÍvÈge{¡§ý8Ý-iJ{@DŠ7Jó„$"ËFƒcv`«Ø2m”âò»¹2„i5Î…øéQl8ä·­d·¡h g'g—*††}qÛÊAhmîJ^Ò™ Èœ=,†Š”å½n+@,JF-FbͱB©ùœüªi…yõyÈKaΚžmÿ0ˆvMZ–å¹DŽÇpϲŒÙ£cYÝ„o0+ÝŠÔÜœ n`;4ÚP¬z±wë)9ÛyÒèìYL“ËŒ×S!Ý_£|5?ÛfŸ¼ÍŽð!Ò‡"ù.Û°gth;…`gFÄX¹@ÕùÄØÌm_¯yC„leò†š9¯2fZ[ÀH9oŠxœéþL±±H6ã¨d„k¥H@/¥2cÁ¹CÍFSsò˜·íW†›Ú&V6¤n¬ ö&ì—H =¢׵^IbQ['BY}¿³N<5CݤbQ#N¯Šú¹¶všÈ¯ÂWjÆŽ/_Ô¥¸T”š‘VE3Þ^gŠíÄÞN‡N ‹Œ0q!gļ§…Zä¤dn®|DcwMeà¡¥LÍ&®5מj«šëà^Bu0ÌÏ'EØ™Ÿ’¿º†V_À§÷*ÃUc­Ã‡a³ü<1sE+žñ–]jWŒFéãB¢•š-4¦Ì>ƒŸ%Q|¨#h¤ÆB<ÖËĨ٠ ¥­5\ºë8eq¥7v«oŽý ­phu,K Jc|«g]h´ä5ʪCà3`ñÞ7‘S:‰j´§麊Y½8&è{¹Úý² µ*»@3×÷+6;D hÜìâÉ•[³xáºnJÕdq¹Ù=˜YHfàÀ_‚\ä$ ÂÃÒàtH×¾JJA¡È…J‚|‹ôP° R´6Ù.Z¹ù;±é Ñ04eë`\[”ŸpmApTC¸^¶ (S1±ˆÀ¼A{ÊÚš¡ ì[«P\°¼1y\2Ű ˆ$Âè·Ã°0Kï­²Ú–þ¥FO¥Î^yøš(œ"ÄЧ±7H Mµ0"*!=/-”y;Ê l—AQc-;=aFŠŽR+7èºÎ Ñt/[ÂÖ3J†j™ÛbwDçU:Ëq=};ŸqÂ#©C½@&—¥mšQPÃ;çö×Ìh»ÖH’öÄ·[N™®°'id–]«¼ÝMöæðo<‚{¿ü_vmbCò)“Üð^—];‘åUh”} ÉA6èò?ÕrÖ´ÂôG‚+#PX±!òí´÷†K]ñH6 %[ت©ý$+&ê3ÓU3…˜$±¶âž(+†òòœm\Y _l7±™Ÿ‘Ùb㈙“vvTp4ƒ˜;,Ë‚O p(rvD¤vŽÃ@Y3â* ûÐGƒdÊäv•B¬¡ÚVs.$äܱÖÇðÁyËpC×)§!.*YźzWï:7d#}Eסè$ÿd+”àÉ\L¡q ú”úÉN-nøjFè+… ­MÕ˜ ±nU¢`Ö»øš•©è¡yËÚ@ç"0íPlÆ}œð±Ä.d“Ùú¤›‘¡£^O€ì¥aþ+{F€e)ÛTÃ4Væî·'M¤þíÂMºW3⤲ !f¢Ú:žtJñ«…z!…‰ÿ<\~‹4Éûö1 €‰´)~ÃQ´¾@Ö"÷ÛnæR¦*æiض{Ÿþ Iö¬tÒU¶ÓÐmQþÈP´Â#ª1ŠKÊDo»Äʪ˜0úÐ*ôäÄH”DÍ{šFÌpxWl #$)£ù{â®Eï]•ÃXý;B“K«Ðȸ‘˜Ažœô´d““8‘w"xfÜÍW¡aKž˜Gg( ¦4ƒ&+W9|Å2nk\«‹/(Àeàl1٩ͶgõÔž€T1kCQðÕâàTUY3º²‡äD×M¨ ÒÑ·16¤¦†%æø!ö%FÂ<“´]KÍŒS€Ÿ/íæØ›-àÎn™p ETIÙ¬‘áY&É »ûý7§2ÑøO`ß3«Ù’`VÊé)å+ü¤àiÊü¢Ì5_Øx˜锽¯ÓXF ¿@MíDÊ2õÚ®×Òéˆb T£‹)ápÌ:Ë£àD³±tš‘ I'î.èòŒ ×$E>‡Âð¢7m°j,ÈŸ&ÀkäØ øLÿW̠Ή±v™Þ<ÊpdlÖáÉòÃó=ô8X˜Æ¬DG Qã"ç¦9V<HË˃Š,üdäkÏòÐX½ßc‡Ø~â)ØDmÛ@²s‘°LÅ ŽØ‹«Ûp!D)ŸcTéˆk4ÇSuÀ¾t:¿hâxVšñGldWUËì%M¾VïÝ.!ÇBVÓ7³æŽžÁHÃ9«ÀœBÙlK9–IˆŒ9+ÎéÊo—;¹¯Q)F!|6âœÀ]µ…eËžáP(ÜP´ÃÈ]/þrºk× f¾ñÙ Ê[°;³ o!%1æ…, ÿ9+ )š—eßüÉ#´Ã’æÕ,¢™qš²rº– '!¯N— ¢¤ÉôþÌ(ƒï £ zòâ¡52ðÀ»V=µÎDhG- øü¶äFÙ() „#Ð ð¸;h¶,QÅ_ é¬åuuÊ ÁFZ-þZ!T%ÇÜÕfmµàÚÙœ^dÕ‡Ã~Jì6£ÅÙˆ»bF’‡@û8ÝTœwkò¯]¾QaR@²Oåìž9Š87ŒØzr¶—Øy-Aááy*ÝØ,0&ò!r=@F­ ©Øè0260RÖŒ8ž«qÇBy…ã`[†™h‹[=-¥”HÏT ¢íd„TЇ»²<õ:É›²u*Uä™DÊ&…±Ð«‰|Ì’ Ü®h%8®’àV 8qØùÙ Y`="œ¹œ2Ø3×éaz+€o’s0C™dYr–¶f ×ɦ9HYC­"1p#_v1ñ¥XzÈ–â gå)—›RröU§¦»33¢‡Šõ•Ô‚-åÞ•7sî±Un2>«Oe©[eN”‚ØÕº§%娾é+Þ’¾~Qm÷ø&YNʼn˪qê‰CB%¾ƒ…ÒÀ›"ÊžÙáÍ>phZ®µ”jâ9„7‡©I‹Ç,wÁÖLk›Íòœçv°?¹Š÷ÂÑ—ð&<Ÿ€.âK«¢ì–&2e•Rä+RV;ëÕHÖ^p.#ëŸËˆ*Ê]d÷‘Ã/î±¹lj\íp¹‰»núìpêŒý*ëÒø÷àûˆD‘$|&î hoš„ž1†Åø'â?ánúô6-Y(ã °5B²Ó–æ£Je•æ×v«³iP³|ÁÏ8×*/Àç`NTÊç<É~èl9µ+<ÂÊ[«NkMt¨ƒûSÀœÎ7¬Ó¹FÈR`8mœ$ãOáî*ÆMBV Z«¶M©Wcr×ÁùÌŒ}`[‚T$q²\EFH'“•ºyB‰œkûÉ’Ù™¾®i"W..+êˆ- ãÙËwøb« êþ„|¯ßU,Ÿ—¯’Fb¦:qöôËh™›L@§ºò;B!™µ¼ÄÁÌØ±ªbOÂz]DŒ8ó¶ –UÏ ýn¤6Á1)©7- ¿À &Hµ+“8½äH:€Æj‰A†ýrÏn…œ81ceíÜž K!‡³/,SŒÌ÷ƒ•'gz{¢Fnµ8«Á—e²äˆ4*T—؃Êt>5£ÂÕrD37B ©a_ÑRpÔj n0=öÖaë2‡:—“PuèÙ’´*Ù¡¾VfÔnUã*œGÓ_á rrõ³ªjØšRÛþ‘ñ„DmSã.L]Îä¬r±Þ†~8иˆ¤^7(»ÜF¶2Àù ¡j1¿!2`ä½£ä]$×±(ŒA㣄=ø Éã)ÎîUô±à„„Î8«ý&‰d¡îyzÛŠ§åYºº¼¼wÄ ®-A2rÇjhK`kËŸ‰È*A÷'rÑmvZ£|…Ý*“ÃhQ{5®êˆj¤cFÛI¤]1šK¿Áå,8ÊS¨WIÃÄT)ù§(ãF¥iÝì?•\–¹Àœ“|WÖSô¼E®jÌBMq9-Ä·_vƒcjFAD¿ò @ŠiLÐJ …¸ÇŠ‚F&¿®F&¸©däÁâØjkÀš™ ÁL‰vr Ë?›ÄÏžl–(BÂDùq5Vê .“ƒß«Šñ‰x@¾qbFtI5šžÃ¥¶âØÃ…ßËz(äËv§äÞR–7v€—¥ Qò=.ì:bF›È x ‘JÉoÑFá³ê^b=h<@*Læµ.Æ¢¾Gð㦡aÞ8#’æÏw8Œqh“9žb47e·ƒS)fO^E=¥Oú„ÍÃõ:Æ{ÓÈ;p„lvæß3b¸ýœ”]_ЈÓëX&Ô<áÓkEÃÁ:-×(v´'ÔÙ1åêJ"F(3 sb„–z¶yL¤3VmÒlÒfŽ¥Ö¹ë$…áXW< Þª|Ɔ”py*¤ßH_QYWŒ ±„É7:Ü$¼åìR«¢.e#CtjZ'tæ0„œŠŽëÉe ÎiÃY.,ƒ‘‰®b”÷"§Bœv󡥯5hÜüˆ×ü¨\ŠU4õ“2…°ÇÊb:k/’X+âäÅz°çѬ3™/X c@úœröpž–AÉNÑ+ Ù@*±êF-À»<¶G$­‚©ÛŒ"k L}–*ñÅ¿Ÿp°Ù÷W/b¡H˜9ÚâlÕL$ìŠÊÉJ½ÊÿÓz3¨@“¥œ…€›]@NùIYò¥H­¢œ™¼DâÌ\ÍS`dÙv!5:L˜½þ@2ž\¤ ‰/'{é²ÄÇùAµ‚ñZ@Ô\FM´y%ÚÈžraC­Þi§CM©&GV+}reÀaTÇÏ&”p!gV=YPò®% q ̤ärÿÅ28“ëØúNž ¤rj‰ìGGªQ?L·~]F§m¢œƒ§pW§ÿi+ç/6Tx)–Çg¢’Ñ–Éï®Ô{#K\)°h¹*jU±9×ѵ'ÔØn¥k"W£Õ¯ƒ dÈÀzºxw•¸bs†žV8â¬f$ƒ²p—4ªä@Ì!;«AÌ@PЧ kH}áË@Ñ\=Hä— £«¿ ùäb„sÁL‘ù1;óHõs6‘ ¥ÆI '˜|&‹£j»çAá„ 5óT¶¦ á4u– +s „ÖŽ}Ö6‘G›N‡š~ÉF1qMèRJ\)ûñ‚ÂÅɹi{Ð!YY&6C±%&ì$1ÆS«ðs7(š6ë"[¢’PL#9±$¹®6ürÇvMEw'¦ž(³ÕWÎiE¤Ô88¶¥ýŠ[ —R[ìô/,»²Â#ЬaFÄ “ì äÐ'†Ùr c¦ˆ¢–Æ`ˆ!k­P¦Lóuznd·f”m3£'K=äffüO*ö(d8ì%.(´û€w«³Ê¢&;™§](Û®àhœGMr6FÅD‚jŽÂ¨ï•Í4#âøܤX¡²œì¶ÃZ”ØùqPHœ¬£- f‘TôM\³P¦³S¦³J’º\œ­ ¼œ™,R¢•  gžʘ/0M4'®EhÎŒ…ŠD¹lÇgÈJ[v¸G«öµ R%ž§ð¯;9õÄËèNv^!#Ùy8:3ËáQÖÀ2%9‡<DU>–i“«Ê<é ÂÁ#† ´7\‹œ13z|ßyæãÀ©F/Æ–à gó:Cõ]ýhÇ×Bsq„2à8Ü^* ç–{¹-êo#µÅ^ ³}‰%Nëw²«iâW~ÿÎT®Ï„chœAÓ¨ fDц4Öæì5™ßcoÎ}óš‡rgRÄjT8²V3®\U0#ª¨­zL ß K rßü (ÁŒ^M„2ŠÀŸ54åÅ\‘áC±Ð±­¢–}P§Cª¦ÜhÆÅØ6 >™™êÃ…aÙ288‹ïÝð5B 8‰ã©e™H‰‹;’dÕ86z°ãô#Ÿ;lj‘.Œ•P¢ôÁõ“™°6CÎ<ŸVO”~ÖÐ \}X¾è?9 W‚ö²`M§Ñ…æ%à>"áùΛäÁZýŒ £Î¾Ä¼Ã æµÀÔØäêñÅQc'Å ­*­á‘Ñ­™FJªj!—ImwK̽÷C›}A„}XvëW †Yñ›úvõ´b×Î(µbi@·kéµXmäê"ƒæŠŒ´#!³a{•K5Žû…Ï«øC0ËRöÁ’ ‘\ePü qQÄŒs¯Jô›8ºìT9ZYÍ„JM)q#5@*݃%£>·ÖÈ#Š1Ê“m­,1$•!W¯B£œ®‘‘rÌrP¨—ØÞˆb'ÿ7so»kÉr‰=Á}‡ûGÀxŒ¦«ò;ø‡t`Ãc´aCjsDe°ÉL¶À·Ÿ±"VÖé¾2Œg` ¢šk×É]»>2WÆŠAëÚ[ 1l© á”ù»å †³%¤iWî`4áÌ$_v„ÄO°ñ4;בe05ÅÉP}‡Àiñk§î˜V™Ë̪ŧ@d*Æ­"{1Z kjŠágNã^2ÍàÇÚw'¶¨ f“öX¡RǰŒ}ŒvMŒë9h3~ ‚ÏG VNŒêµ`°rË#ÑðQ$Û(F5.2 üþNÄN ï$ÉQ|lú2´³¦‡c‰>Éh;zåFQÇëàV)Þ²ÒÞ4ïFËëßRˆö°ŽÓºòCÿYÌJã8ƯUÝš¾} )`ä¬>¥ŸXäà¸Ý28v¬`àôã«°ƒðüMdž頌4ÀÈ?Ç{£1éÇ%zX\­*¢˜’ÜkSÞƒŠÑqÚÌ6jåõjBжä^+ËsT¦:<‡&sŸø²ÝôS‹44~Wµ®Ú`cêÀÐCæõn±b´+þ;qÌwýiÕí±ã@pˆÖÍÛ"?§ÚUe4!W¯àë2+Yä÷Hÿ­Z6£²m䋎 ƒ¾qéEUP“' dYC3œbø"]6®·bö(j0™)-.Ñ^'Ùx`¥~fÄÙÔÚº\ÝXuJÔ ¼ÖC|€ÆÎ–Í?“\µ´/Eü†~nO³‡}Ñí¥í®á¾ix ¦ ¹1îýp ×< §L)Æï@–9,œÃoûMhÓ± ./Çè‡-‡{1Sü̩Ʃà‹NA.¿¯°\œÝ©ϧ;»Mº‹ü’^×ñV¿¤6žïºàw±>¯cµ|&Ÿy_^A„d7Å«t4òK`Ýñzœú'Îy®­t¢¸cwøYa¥K®x¯l½bù¦—ßL¿;µ z¶Ñf¬%¾o·áo=Û Þ©SÍAéWªÛ„¬ÂÞ³ÏÔ$pþ1žgÚõ+µ‹ZÌŽoš‘Œã´ òÖ°$X¬ho‹Å Ój  »œ_k?~–ñwÊ¡ÝQ ðl»®n`X¿wÜi*>"AóB¤ô”ÄŠ¢E¤d}qû)ÅâÜ ƒk¦-µ’F¸ÃŨ=õ½jd]†6˜‘zWÇȪe‰Îg"Þp]t<“Þìz‰UßVò·Uñ©ÝG–a ßf6.˜?/ëMu+ø0KI¯afŸ½-Öå™%Ü„ /-Ì\A'EƬÇN+þYuØæ~®‘fÅq±4-hcpfãBTJì",Rã¨Û% Š \'8îÜ…þ!ü)2wÌjt^É$=Íà•ÛaòГ^"mövé蓤’ ú°].êë!~sHë©GsÅ{ÇÎyzS‰;m€µloïf’ØvªÇä‡íì%—hn²áý÷~%3¶âF^–½£ÏVŠ\Ñ+͈zŒÓ²šŒÖ¡–9K—"]¥Ç,46äjË’ÄGç iYÒ¶£Aœé—D±µÕ‰TmæR¥j)x¿hÐÏö‘ûdö°ë º‘>ŸHà¤ã>ҰʤSµë⸵¡´®k†Ên<çjÂ=Aúh9FlÞ#̬aŒp‹äÅ•xнÌðc×®häUtð]pÎq¿‘C QÏì=g¥÷‹a¢iÖD,"Wë!OZ±);Øk9hÔ¶!±q8p[ç 4-¾í(>YI04‡Ž”Ji.}4KuÑÞ~ú>,'ÄÀ³‡’9•ªià2²ÑñN³ŽC)‰00víÏŠ^K(Xloù27Ÿ®6luÏÄè3M*Ä0:ØšæÈMo£7Øj¨\!K\µ~ÝÑÉÿ&ÄUU „Õ.„>8E`[¨HÄÞïº]bVaï'H·[jà·Õ{#hc‹cø(ùÊŸ›æ"º\4bX6ù÷Ø¿;Q—îÏo×’|¨ê%×ñ»É" °·ŸîNo±Ì±¬«ú@§…¢òE"ÿW´¡­P8ovZSQv»µSvâÛk¸¯”Ý¡]pè>±qYöÊÍQ­ca±Žýg›“Å5¬qÕ¢ƒôJSFØà¾ =–¯~‘jóˆ‡hÒuðîÚmvBZæ5±Äo*J¶×~̳²¤½NkÒ²Y\\®…€x+ávŸ$‚su>YÐ…»4<8-§\;´/µÛbËQ ‚Ñ&I rÊX¥ªë,¬‚‡}‰ $+˜ÎÈ5-$ÇoUÔà8ê^vFVi]uî§[(ãL£e=­Àà¨6Ïb¦óGXþÖM™RŽ–,®43ŸKÐ%1(-¬“­jgЖSÞóô%ˆµ?ÂY¥R½5“1lÝT­(§i;Â}=Â1G·,*ò´å”M§1Ý-Í¡‡’„)™¢ŸÛ£ ¢F GÓa»)]‹p÷c`¨½§‘Ö¯±]=ïº ÑÅZVè-q{þ¬êXdöå'Â-ÃñÎ#(H¾úo\0¼´52`í\­8¦l‚ˆàû~ T*º‡ðÍ™‰ÞŽg~BÖÆ¿@ÂÉÀ™e°Ûzºõaá˜H‰T¼»l‰Ë`kpKÜ7U ¼¥FY©Ô7ŒG!˜0˜Í\”¼s÷>fîów.% .=òe8Ê3;çr¤›WÑHÄŽ5«ÕuµRÆáð f½¤+% .ªKMÀ¤W]-¢ážá˜ÌFQÏv”Gb{5t‰´wÂÌU޾TžëíZœË”,ºåŽþö~{™&ç~: f( )=Ï@¯2ù‘ÝW _Ó,ëÊòÈ:çUO¶|E?Î Æ5@ñsn‡c=G9o7UxœO ¬¼®¦E7«|s«¼îºŸéÛÝÍáŒà5´÷ÂÅõHùæ Xõf,º ¦î eï€Þ˪‰ÆÜ‰Í˜'i)N#T×í %aVÑäm~•æ"]N<’¨½©n°OyæwÉ¿äö¨I÷x‘qÅŽ~ÚÂlÔµ#ÝŽ5ôe&4MÍ̼¶ÕDýn®§uÑ!¶¹PDÑ´(®ÓÁƒp@Ÿ¤CH¹½ucD_Ñ.èõh'ð—Và–Ïa]bÝò‰‘ÚïeðÏ.ã™åõÿo¶ZjñOk NsÒî€Dõl·zð³ŽõUá>ÿ¾F›³.ËÕD2¯pp(­)ζ]Žº`eËÁ>˜uÚícÌ–úª4=ñ·[Rq·é%Æ©@}š@…b"`¿<*Ê’™‚ƒY$+mYÇ  9`P®7Ò·}Sa̦öó<Õ2H{¥Øn+©JqÈ­,^'6HHóÓ£P˨¾ª%ª1ˆÝV+FxØËðJÛ¼ºÊŸÁê\©n÷<ª¡íJÈ5Y+ˆ @›‘öÇ÷_zá“,vÜ5yÄTàM°o¤/Y™,wÛy™owî"^Ixz Ò!tòfÔº&;LfŒí²°š…º ¬f †·pjÛÐ?a¥ _õïGlÚ amd«{vø`§(í®y[ÕþFô)ÁFµÑPÓ¶ú ´©YMÙ÷¶,帕Ëú ŒwˆaéÈ´™ÁÛ‡ 6ï­K « Å0rù"UëÅvÌ[ !§eMjwžƒð¶$GØgØSUçHæô#‹rÇÞå]Ó»”÷‰í¶¬‡{¨uÖS%‚&¸3\Œcæú´ o韀 Þ"–Õóï¹Ñ'#žÁ. Y^VûÖ¾BïØëQÄÀ§ᾓX×kênwâ§Þ·ýæIdó÷]ø³Öݪ þ}ˆD&ýàd¹¯u:x<5mñÆÇò "ö•,ÉËíR¡1aÍïz_˜ Õ.b43‘o:Ò’zòVŽ%yÅIÚ%”ÖU˜¿r2Ô²dÄ;ö‡G€dVÚëf!sÁÜâ0£ >²_šöÀG"h«õFNµ¯îêfft+‹åHŒ¦ÃN7íxc€šl TUKá,ÙúÑ£FÿM; W°{°°õçåž¾ 㨳S†(I͙‘̰³¼Ú½ãµù¬œ¹=šL#8‡»‰ñ¬Yå}5áX;ÙKµiŽ%Õ—mƒKŸpn¨óߺÀòσi]¾³a5†UÔž»R xZc’'+.ÃŒÎÛÙQÝîad˜`c60ª2Go$Âø¦›k—Ìû Ö%Ü3b>‹.%?üS§Ƶ ‚ò£Jjw>ps§•æo¦½òÜññ‹L=¼ÓÙƒºš)J6Ò;‰À?åB ˆ|Ú*âÖÂEܼ[ç`НÉì²FT©r€nY>+ââå)®Èeû |S—F,m§-:~_¤Œe”G=*hº¦™ˆRÍ•D¢Ýï:{§='(ÙÇ£º{Ê8Ε'ÕU0*è:×N@èNK+ÈA8sÛ3‘]¤ïºƒjÚã‰;H/*ý²ÔÅÜ ê‘ºå½“×»S{„\Y)ޤ)!(šÒb¤‘y—{g06âw™vªûü±Û4¿T€›;uÛwVE_‘œdP±Ÿ± dðÖ‘LÉŒëEVÌ \,RxÌZ¸Õ/œi ‚ ’H~‡<•¶òX;¦LËÝ {Êø6šÔY2OX‡ê˜¢Ë^Ú²¶Øwùøl›à©ís`³~¸¦¸qµ'º<  !,rP±ÄqÕ¯ÌçH€ÊxxOÙ,3\¢m$§Äa‹r-oXkú,!¬k˜æ<ƒQÄyvÉã€u :ÙC¸]†Da£«W¸j¤k] Zï®æ¤-"õáÔm;ê§ Öìç†î—ôºug¯‘8U`$SœÍV«ÉÂÐkÂ+.1˜¼lWÁ`ÔÑëxÓšrêPxxߨhÆ›Üänð€³ÝéÆh‚òÂAI5îlMUöp=žcC°ð a?"2쿘—»Äÿ®ôeaÃ’+‘º‘?êTÇÃâgÈ‘#†ĖV€¼ï&{kÏ|v-m•KÆóLLp©ÎÈ_%Žb_Ifoqr fñ+=¸ ÒéißGÖÔšei ;÷ ÝÆ÷£jéûêJw?ôöný|Ç*Çʨ¨qᑆìki½"¥Ï:û9¨2ûö³D¬äÇ·). ÕUÚ6¤VÈ`¢ók‚ëYël]nä<-QÙwqéua_wœASþK[;´ÖeÄçJ¤ÔÖ•­ñná¾y#¨å U%çÒ_öé—ÈïAMõMî k^O·”ipó#¦ 9'?¿|¾ ñ#Pr)Á‰î&œ1¯Še"Øìæø1\MÂ÷ZvgÙ¨É0— wcI?»]Bvéìu_ƒÃFAm–Ð:s/—g/ ´»»\í‚AÛjœã|¡¦ —ëí$¬¿éÉ’t>ÄŸÃeˆ÷u˜[)ïxüV+—® Vø¾šî·r¿ñ :Wœ,n ” ìxûð`„µ—x«©½S~A zìl<㪒ÚÛ;âØÀÛ»õ«#h•Ó¨a½x•‰Wª(¾¶7#7|€[ƒfE»/)ŒfÏ©qaîòR… `µ‹Ñ[^D3þŒ×lHi1-*¸Wn…®Ï‘¸f6EziãqGAK§ÖÀ†=?H7áV͹tWM•ób²âØÒì3¶nÞ‡v:ŸÄ£ì‚K]FïWja×xrbŠÄ£^„xÒ HÏìLPL W<±BëîÆÈ)Òä8}B—ÎÉÛî^híQÝF8ì¢Ö–©×‡Ì¬w1(P‰áTŽÛH„KÖèb‹…[¾Ì´UL¬RЏía'ÉpngoÓ8Øx(0¨½Y‹]­ÿ^ú3€ ÕmÕW2º›˜¹F^fwž–ã>²ºQ²…£·ì=ºÎÂՓøiRïÉï\qŠ6MgJj$w’Y)ü``ó<0Ús!#·PŠ½Ç¸f«ÃtÚ¹3{¹Ïéf#Ì Â4UOþŸ8m5±âg®Õ¬`?gO€Óz¨+óQ“1)ãw¥Z}*®Î9¯ëA7ÀybSRÀú”àÙLÆ>rã+¨–5è3çfX[tóTû“ûE ~¬À”ŸBJûÙ¸§À½EÎOÜdÔÛ(-Oì›6)BßÞˆvÿ`k†dgz\¯èÇ6Ö¨4vOù“Iú¬m­5rÛÚ¥ÝGÝ+n;eq«wñ»æ¥,¾ìpYîþɦyΣI)Ù07©'ÁCĸu2÷t7sÝ^rAIt X`¤êÏ™‚0+&Iý\aó-[ðs»ýÒ\-˜Õ:C` ±¨Öñqx½A¿V”žÙfÆ» ß!r}•KÜ€gÞ¹ÀCÇn )šƒúÄòo.?õÿýó¥D¶4W6z¤^| &惲`”àÈ)ÃÈ£€†îÖ–wS ‚-Bý:³Í!˳ÿ^æöóþ$ÜGò¡0}@LÓ³™¹å3Jìèm6½påBn1Èï`}+ˆ$RA³F¹gè>Vœš!B zuK°ˆPŒ)¯ÃAXŒÅzv‰;‹J% ñЬ&Qa_‚+™q&¶ó,EÖd+HÐô¼‰ ?`/Ä"\êÈ|â¾+8@Q·UcÝÊÚEጰ2—׆°h.mùz2èªÖAPú`ÄWIÓf÷ç\ªmW¿“9;±ß*ÏGQ$Õ˜ñÅ[£¹ eù?¶»Þj”fCàI†ÃQ›bÍ~  ; ùîâé¹çûQå†ÃC¯DG}RÃΖf¾k}0o¶&2€•[«üaãö[Øþ¨ö³ ~´0ìÔèÙüÏàhž&wµ¶ÔÆâ):r 7óX Í~jkÕ>I­iK‹²ÞmdÑœ~üÔËí£Óþ( T.ÙÊšpçÙªRÜÇ ­Q3û×J¦&É–Ç8›ûúÐÂO¨dÅ9Q6¢#ý`›W²9µ*x Š  É½Lló›„–vYjK¿’Å”Ù^xfö’î]°­¤Ô”ï‰D.ó<+Œk«À¢,T/î£{ª¥FÖõ,ç»Hϰr•ÑjÔbv[½ ×WÜžÏÊÛo‰ í|œ¥–•AkéŒñi–yÛê«U¿YÉÝöêüúÄ ›åwì7L,V…Nëf ×y«Q3ô«‹9½ öd–jat®3÷Qâ_tl“æÒ’™bQ¼ /ëŠa¯'ú¬1¬ù›Û®Ì{šeܧçû))£ˆš;v/Á¯U‘?«Z„–3·•Vú¸~uÔ YÇ“;|aÅP&—=÷tVÉP¢ð)@¤SÚðFó$-åÑSÎ=¥¿¦š Ú§òÞaû›/äÉ¥ÉÖ¬ªB=ÚSЄ•‘ª‹÷®Mù14íO]ΦuåR ‚Ù#À÷úͨùe2û­ýçgówWXÔ4“žvY] ;’º˜—-U܉«•lƘÑÈA³ŸW0›ôXoƒ ÄëýÛ)x§åù¼…ö¶:<¯‰lŽ`¾‚+3Ú)ë0OŠ¿3åÄNž*«é¾Ñ:B…È(yˆ·xwèJî¦ô}\1-ëTBÙºÒ†³@‰‹)ç{ÎâCÓZÀÛ´:ïå>oS`:“e¸µ¥÷)ÚÔê'7Ù¾†g?êä ¯@q·]"ŽE¶Oć“9ˆpƶ¦,s?lhsÂàºÏ:Ð,6ºÜ~% ©ž7ó5»½ëI—Õì [i ‰h¢j Q¿ÃUƶìÁ؇ÛB9íòú0EO+φè•lߣû‚·Ví£O{$ñ/d@4 ¼^„K}Œl×W>!Þ[ ±å:J h‰/vëC$I±'ËñL ë`1˜ÝÀ7?œlÜyµº( •xeœl5aÔ%g#hîäKäƒ$yGióÍÙZ÷ƒÜœ•ä—T,G©†âûAEGÊ)d‰®F¾x ¿Ã=IÁ¼ lû0 P^.脹ž]á·d›¯¨÷û "å+î”âÔ—½³"g^NëÜ€9M±r×!F½b•ÝϼÝ~2^4ÄYE¼"™ü¤ú>æÂ°ë$Ž©zÜŽ÷)áMÑ'v IŒ+UJ€žÁQNGz(´²ÁVK!9(ñd_‡W²²Ùw®g}gIæ:Íß;§Í;V`«Ÿl6Þ5@r}J]`¶HÔ‹È6<é@tY€Y [w¿Ï¬(ÜÙR‚à²X"{<ÀåYW(`ïÚ'S—Q­¬½…,tÛuvïkgØ=ýE©Oà… cI~ÝÏzÂẌ́Ĕƒ»µ×àiY£í²Œ¾4€Á¶ýø]Åé® óp#%•bÙ³;,ÃhÛ~ßÑ’G>ð›ïPH!›¯xBeó5WÌWî6¯ùèÁÅÆ?Ù`û\µ+É‚Äiö’óL쬟üúâNO&‚ž—Ùg(ºåÍØB=¦Kã›LºÎÂ1¢zËfòzM`˜Û]¼mJ õOý0È餘“š‚y%DR)hœÿ! ¢Î”D7CA=ÛÃÌZþ(‹2سȌ`wÙ^ôÅpg¾œ`Ú‘Q<êBÀ·–[¦R/°&‡´ÇÞû`a—~@9°—{}û™jb6=r ¯_ÀNê«éOßÇUQ¾=_†úB´Ãë²*b†Z×6%‚­ÝyýÏ_»9®ÛbÐŽ‹Î4mx×_µa—œÁN^ii¬ù¥¸©ýJ„§=SRîºÛ?ø¦›Ý¹ §_e€†A-#lzô;Êq¦¼m™þ¹Ð³†5ŠE~¼Õ̳ý:ÍØxëè‹\Å;Q¿+Ö2áE½\ÿ2„%Ö€çb«ß3»òUoIAfS·wœL!\+;{VKêt¼‰\F2ÍœêÑJáå,ªˆ^Îü¾ –ñæ·7§c-]sJáluïÞJV'°6«¶:#êéqL•ùåBòŠ÷0%Zvj È‘ò³!ZÝ/Ù(uÉ­<Ÿ-c™~‰ÛS(ÇÌÚ³°Ý,BZ)à{Ó?­Zdò)¯”-­6º‹´¤hÇküÍÇJæO³’¡•u„HµÉ?}*wÊÔxNŒÚרf›1‚šk€6›T¯FSÝýzZUÐ4?Ö©qZwPy¯%¨r‡¯Î M~o^þ¹÷³‘WíµKò ±J¯ø© >ŽaI½<¤âº¶åNV«Qâ’PÍhI0¿‡>TUËråù¬}GU·+TY$“Ú“‰uE"õMǶyO‡[¶è彄0ž+c¸}=¹+9Êc=îʯKÇ•óeØnw36º~wÂÞ:F¹³?iôœ)ïÓ2ÕÒŽ­SWËÔS–côï/£.Œ \÷ƒÑ=š…àtÈq$/Ë)8’Z 1ºü Òå( ÚŽ‘’4ØO3H3~)ŒØ5Ë#T¨~ZMÎÌÌ·†ëÿ»ð¤VS#eÊø2ÕíÜˬÃ:é/¯ŒSj% ,«¬u%‚­{ªÈxo)ËS:ä¨;WŸÕ™ü¸[ð ¸6Ò²]ݺ¬ÍNá´g_GêÊa€mµ‘m]ß³¶ƒ.9Mu;ŸCp¾‹"[1•ûÎ.ŸÍ™+@\ÎÂNžg5§ç£ÕSdA$ëèÇгTÏÅ•zÅ™Jâ zrH{f|xnƒ©¹Ùóú¸O_Òý!ûƒðrÁý©’CòÓ0!vzdÙF.!#r-‡“vs]éƒ1…³²IÍqz€ÜáÞ a[£ÛwÁa9„«³û•Я˼#z¬n¯Cr3#û×CºŸÂ™f´ ä40Ý‹UΜ³TÉ›QÏÔ©F;¶LÅÅS„•òÌälàËR÷)×ßþºg“ Ï`ä/óžcœRõ´O*ƒ)quv=|4»Nlyl‹ç¶<‚ÃÇLêqV6b?F]©ó1ŽªŽœg9p'ÏÊmËc‚¥£ƒ's©Ò‚ØïŠÂ8Üâ$ݯÖJ¾ö°Ð)ƒ6¶åj ­ˆõ,‘z=\Ù>-æ†<"Ö åMÿ°:³îK¢XÙÀ2ÃJ,µ>.Ëå—¸& c ¾æÍ~v,¼Ân@b~:¶C1üy Ï¿t3¸Ó…á>ökwú5¸¨óè¢Æ/Í3(«]gn»Z§š|J×OiB„¯<öàx·Ê%+ûÖŽŸÏ–4ƒ¾=Ö¶ÝÇ]Òu#¯AÉŠ¥î¶Ï@‚7<['—^eeͪ`ñ ¢à8õ²õ$ØÌjf³'‘Èîà¶Ô+ìme¸Ë kKD$ÕJîL üõÍgø~ª0ßÛç$qò­½á›3y¦3.SRÊò¶\­»šœi„U\[6F°K"keÅ”»™ËïæII.yåüAõ—ÔvÚëkÞâ‚>ƒ’Ö ‰gs‰•½v_Ã`C´Ù˜ÍE…GOàJð³v˜s $¾dØÑW¶9î'}T¦ÝÞɪW1|-£K`ˆÚWÂZá×Co¹Ÿ\U;ñOÄEvvû¾þÞAƒBOuÍÞ’(·ŽeX“v-oËu²^ኌˌ€,ªsp£*´v%þRxf  <“õyÁ™ü÷ÃðY~CB3­ °Ñ4šy<ç^'¥›n(C† Ö‹/{ÈÇwy937hfÌqï¢E!yYLNÜ€(o¦awrªÕE9N‰ê’*)+ÈͳpƒÛ“A’ž¦ sÐŒGgi·ß³¸™Â²‰ò¸ãäÇ‹õÿ#3ç×í‘Ò€l»uûoü7 Ù~8î°ÿÑÔy£¬RÔÚ·½¯žšxÅ^&ÚÊSgvLÂyý I|{ìyaƒ-8`ªQEÖí1ãP'¨‹ÇÞ¼ô35 a®­²)?W;äuÉä`³e…«bx9(ÔobÚ…LP‡ðøØ-ÚœÉÓ#ÔŠ}·¡È}Iºç:,?‡°$áæ±¤G‘Hݨrôù¦«+ªÄ:ezj‹r‚œ=ó³Û/èRfAódå=>ȼÚ[)÷\ǯÚÕ\üI²Âc`…mK‰n8>ÿÛNÏô+)Ýn,_®°™B¬ØQwKZ¯/ªzuÅ)À´1²[ùò¶QvhO©íí¤€ØAÛ±df¯ðöO’XQ{iM•FÈôݶy÷~ÑxþÑJO>ìÁø*–Õ×wÙÕÒd9Å÷•5\$õï@¡ìÐ7ºI0ø³Âã2É8ÝŒ%%µ‚ Úzöî^5y£ö\éZ¾ÔhÉKšñ”y'L*Ħ©O¥Çž¹è£{nœ"ÇÍ&ŠôN±í”´gf“ò6Ûw¯zÌ—]G¹bŠcå=ÆÛ¤MR1.)nº0<å¨-×wŽ ²sq‡÷áC™¬ˆZ²×ΕïjÏ´a$ÇQÌé¹p ­²é‡³#2Õ9sË;å½öY9¸c°L]²‡-Þ´ò.«ÞO(…i<Ôo[ Ïžú:Ýíi˜‰érdsé;àt„5™½bª¦yéÅÜu›1(_]DOÆJ,aG§Ë$žöltÀ6šu£3ˆAÍèlŠÒ$P¤ÔmÇUˆä˜w¤8Eâ ú öè]ü¢4V)ûxø¶!b¡€tšZÒŒ[UlØÛtUBêº|3úçìÇ/Ëþª‚ñ±DgÙ(à#4îG©D•dÐfÖÑ ö)Û k`JHbrWz™À"±ñá6.?ããÎ R_ÆÂ‡<(¿é.èõWŠ<ò˶‚ÄolÜŽæÕ¾[Ç4„õ™ÃîÀú1êF9 ôBp2ËÞ¥xIÂ/„–ZPÌcC„ü´´SfÐ&½iü1+/#2ü#ˆ¼Õ)ˆc—ÌËjÏöôÎnÙ~s*Ç6¬£˜W¦³6¨H#‡ôŒ'*±/pÌx5z€_Gï¨0} ÕØÀné|×Wj3[ŠçÁnFöçáëƒ'Ï+¾Tê"ìCŠA¬ÙÅF‚Œ¹²› QðÙ—Æm÷Þ!©Ì RÈ«nÏ‘ðÙ©XÍÒo_ióvÅvoÔ|N—›ÚqÜD²® ÐS§7lmßø1⥴q®Š•4 þÌ>?¢>è÷Èýb+lJÏ),!iL É~áäÇÞ·µh=%´skÜm…”}%L4R¹Ayb#ˆe;òâêÆ9‡#‡–ù{—úü:5^"¿.6ðâGDéAövðH&ïÚè "î§„û:fŠxï®Qµ¹Â ‰a¼ Ÿµ=Q“/)'clO„~jÁ«‘‡Ù¤ön¬†ØPƒÅÛõ+¦ÁžW6a+1TŒìžˆmù¬¢£9š§VJ¤%Z«˜¿¦!WD¦Œïxj¥aþfì0¢u—œÍoaaü’ãò½BF¬ÍJ‹të®Y)îÖ›Õͯ<ÒÕM4 ¥âûž²fæsk§¬¯k—ÃŽÝo:öŽÂl¦œb«¦WhÖx5¿xÓøÎa?ö ›ÛÙâùÓÅe´ïÇþüoþæ¯ßßÿôõoÿðÇßàXíàÿ¢fÐ-|`4 Ÿeûí‚'J%/­bn{îäµDGË.¶Ø_V‰ “„›]WèÿÅãºúYöxÕ4Iá0™d‘{Ûƒ@âAX¸÷8l&ØXº¯ò ¶DOÒH ñ}Òö) µïKaœ«™åkßËoá2]["¥¨Jô”ª6;¤kgÊz(Å2¬$O izxê´Æ¦™“d}Ȥj΀PI–8c–‰pÉ8rÈÔÚ%’ëÞÝá¤Ô¦å¨×áÊªÔ ð»›†Ü¢ùËZK^2Yb\s-(QlЫ˜ÑùàF´ÛýIóûwãiÁ][í|?‹XÁN±Wo/8>†èR?‰A““v l.¼Á~²È©*®@RâˆkèCªVB‘%ué݆¬Ñ]Ù³!,ž,ÄF{´\e:¼Ü¨"\ Z³!DË'ƒæG²{jn‡·U]J´ªŽc0Â`d¥Wì.Þ¼c"ÍÍò'îî‹Ö§µbòŽ`*Εg°’t_…@­ñh)c0Ÿ·T2ü¶‚\ââ!ë)aO¾Hy›0Lc'áBà5¹½ Y"c0Ü )mgR$a(|Ù?Qés¨©@Ox½•à:©œj»˜áÄ&AÒÖbáì±´Ä/èf¼¸idõZ2ئQ©+tñÀ׬·5®ù|£C r¹íš1s¨Ö… ÒÑê<]d»~íQÝZÙM?Ž0ÛãÞJ*Ëùt¼×z—€E}šeNƒ];¥‡p| 4ñ•¸D‘ÜMûË#²´/賨Ñ^«äòmÌ·‚Ååuf&ipyÜØÎ%M¢ÚÙI†-¦ÌÍÖ‚Kµº£6å’¸ ]Ü»‰ÍsD?’»¹&¸b+µ¯ùy¬_—S(àÄ kN¡nk¦t²§X°BÐY˜Tš#%¹£ˆû\Z‘ÍzÞ‘³ѱBnÀ^âkŠ,.Z¡Ü‘¡‡b¶fE:DXpãÌ–ç%îÀâÛn`Z[Yë,qfÛ\jÌ{ÁWD&@C—.ú½ŒTÍ4:ãwÅB8ÕöóMdžÚš@kwÅäPÐþ‡`•Qr\•Èfq·-sçXØŽ*ÔaMÎL$#φ˜P ¡3)€ûJ|Áæö  ÅZ†uB’o;]šfÉJ/ƒ—RÃc¸±Ó[c qÒ^!¦ñ™êÚ›Êô‘x÷zÓó¨ŽE„à “"D¬*‡M‰Œ²8‚§N –]ÚÔ¡Ñ{˜¬ÎŒÞIõB-y Çžá=ºeQKPs yx<œêí†,%¦·w=ˆmζe©…k-&­V¯åŠÍOpÓ˜S¨ÃqMD'cÅä* ªÌ¼®cùÈ(j9AŠäDl&¨R®;gŸèøf°ø$íöã±Úí±”kHîªÓ:'ÊD•ÔÆ^äÉ:S§Ùô­?‚^.ˆ­ÇNäNÇk¥™³Ú™n_vöSìMåmgzØ¡;ââëhÙ3jO€;j8ïšþí¤?:¥!!POƒ=ƒNþQ‘̰»zqèüfÛ&w¼B$ªêk£ ´Š¸9–å±ûÀ2¯>\í:´{–ÛׇcÞ†1ø²RwD>û.”EÜk¤7âꦡH¤Æ cƒèàÛOGA±§ï'`šÀ»×ÌVt¬íÍ'îÏß•´ˆò«Ú¶¼B»2××^̰޼Mú5¬8•;ƒw{ãIàã±ÊÔ÷d¤uZ¯ï˜_#Ë܆ Áùu±h§&æ}ìBöƒ2|i«¡úN¸ Ë\f·ºQg°I–˜ó»e+¬_i*Iö…îœAý?Á·Ÿ¾ÇwǦ¥ ’jÓî®eàÖÔ,4ç2¸‘öDê6U«`áaP];e0ΠÇÛöñØjz.JcŽÿ¢|,Í¡Þl\½é©ß;uDç^%ú­ YŽòðòC8šžÇÞž ibtg›¶fƒ0Ú»QÞ oÑi¤WÔˆêïí‘Ai€(øö“Ã×pxØJû”Kwº W ŒI‘½`§Û•oÕÛ=w!xõú Jt´=EêSEDxôÊ3Õ;AWмªÏäS“>àB`#ƒñ$;ø&œ[/#rÁ–Ž>òPÅ#©]/J¬±og0…<«[T,!ÇNUÚLDH˜™‚o?9å³Ç±É ¤áPõNXìž©¦>?ìWæ÷ÛÞ˜™æV 1%’o[¶Í§üž³ÒÇ’Ó%µTOÜ÷ï˜ù¦rì$/sOšIxÃ6b±ÃÌ0›ØAS¬³>Žm <Mz{Mï ½Cœ˜bº|ù\7ê&Lºân^XÏKc ´¶öK¤6mC” ¥ñ}L^|WÌÍñ]ª°ŠÞMw{-¶:²:#ÁIûN{ß¾mD‹—òX›r·»St'Á*ÈXؼèUÞ¨Èl»ïÈ™õÿaMd'‹ZúÄð0:Ílëš2½Âf8€QvI mÓ‘|UX4@ì[[î{˜‹l„"µIŸ¯ÖTBX3$F«v•ÝVªñƒlÝm\“§ÄPå^ÎŽ•,ilÝ6>pIì˜7#8—ïÂHi*¹·ïØJ?>Wå®Ð¡Š ø„ªëñ…”‹%nŽ1ÀdµãVÖÊ`‚r˜÷œ7?Âêð\Ù¼Mã¥5rN¸ìs5Ô>V7´)£¶[UC›ÚÙ=Úô##b¹‚AÒBPÏ‚±öŒù@&±?8{´Vڣ蹤JÈàÙëbûrJ¹RæYvâ«0¤X´¬/ždŠ·Ÿ~1llÔ5æ–Ù4òZQ7dÃòk qÏ[%xË!bÜàh!IH2¹€ÍhŸTíwÒ²Åí ´]ÈÛ£y=o\–¯c—ñ4”*Î:Úÿú*iÕõsµÃc²Ôõ¥Ö‚OŒAC¬ÚÆ=íi/‡gé§AÒ÷\ÔÈe'Íì ª‚öÓÝPhŠ®²Œ»úâh‹üE­@f[;î€Sf¢qtœ/‚"¦€"w`ÞfJ?[Út}_;ÁmÞS’B¶]ñxÅ| TÌém2¿Ñ óñ!bçg¡©J—ÇfS]d¾âÌÒÊwì»PÔ6f è TÙ(­^nøšÁ1I*"SCîaK´N{¨,6ïífwã¾Ï´ò}xÞº êÏá¬~7  R#Mjºîðt1»Å¸Ã¸•ÊU8è6—¢)ljûÿ¦çQm´óX¼m9¥Ì#_Äæ¼[NEÿùÛQ|UQÀ¶y¤(žAÝåϸÅe®™æöûJ¡Z$á!û~ p-²*Ã2Fxé%yq²5g0ˆ¼ôHU]”Oøò®§éAìf yŠêZ¢½¹<¬0,ñ}L„—õòÄ'Äaxéjù¦W-ü½4”A©RÛþ\có4Œ ’ë.åIéQþæ ïáÈëò8V@Ú`Lç&°I³,K鿦ó-©[N¶Æ7­KE}Ê»9èÒôÚÆjæ %À÷‚=‡òC¿ ú)£qðM3»y!=e øå £ftÀ–+nâz¤á ¤ëÒµRtÑ{ˆ†F‘À!(~¨‚iC~ø…™œÀÔâ1„éû•Éøî>Û¹ùFÝUÖ+U³×•2wCÍAWÛZBPÌEÀò8«p™%5pÔ£u þA·wÙ°®i•,n¯l»¨x0ÎE…%&ƒ¤Æ¦>K¸€–䨱R-G,ÌÆÚ¶ŽÐ?R¥ ù­š ƒÕܰê Ó¹">µÃ.p4»þ¬âµŠÁ¢épåÖÍaƒø°ŽH9.]l³™Úl×–ïÐâcøX7]‰ïi2ˆ ›(N79‘û»lº•‚‘Ã1jH"èg$ìQr[Bß…¼ Õ}mi’v§+¶ú"fàVM_Œî4OŠV2t²X¸6û¹ ŽçF$ë:6ÿ}ˆ·~O0Éà"ss4”C;üéÙ>±®¤šʉ.sÜ¡$êLI21l~æV–+3s5Í+häXÃÃ{z±Dh1W³#BÖ|P½99º{Â{ráUPU?}‡ŸŸÇ¶GÓSúT*­à}®ÁH,Ñ’¬ë¶å<ü‚u÷%(ì~î¨pÝ8Ó®ÎE³®J¾0í¦‚#š'€(°­Û¶P¾3õQõBX õ ÇHq£-­enD©ãXhÚñžA[GK¹ &9CY)PX ãÖAÃ÷î¸{{gMýØž OY'p¸BWÌqr=×c N­ëË›“­t…ÏÀ‡c‘ƒG?î”6‘ƒWy íˆè‚³ÝiÕf*¼†ÖA Î¥Ó"8oΙÖ³&@‰ÖédÞ½fìIŸÊÚÙ:g=éÈoÅ™»Í‡ALÏæ¸=Ã`7ÑMñÊÇv©žT>A+Ê ¼ƒ³Fâ¸)cÏ©ºª· ±oïÒ³{æ„ò¿pÊAà¦â‘N¹Tÿª?m?à¦ÍOñPvûUaêJÆVO° š:¢24Žø:2~f¶i=Ôêu¨l#Ù’_<‚Øg«þ°ï%µœt·g"^ÀåàÒÞq<º…ç+&+½)·¾yœ×Ríøê,Ì–J÷xS˜HŮܪT;÷¸-zLã䱂 ²žs¹… êNGSuNYÍÒ¦úŠ"<—«jîm`q[\åJÝË©ª©ùŸ˜ØÎ³ Í*T û¥èUÐiÂâ½B7çî®ÙeZŽhÇ{ è(¡:`â¹ß§þT½#"¨^B«¥è$75®ù¼@¸CïkäÆy¹'×Ù.¾,Z5©ÐP¼`¾“†ˆà*þ*'jˆ T»³ë k]è’c{ÛaP Á¸žÔiðÇóJ;N™ Œzº)wb¨5`à,±G :%ÊuS,b/ö@ûÆÿ{Wa’Ûè—•báŠ5Ÿ݇q´.YU¾†dñÅÓZÙcA¾)²a–4^ªbhº¹¤¯=€ðRR'ÔÝšÑ?’ùþp¯Ã`WÏ."’ le–Ѥ]Œ°k€d¨VLU¿!ë´iÂ:Éæjf°Q.I$҆ŠáÜ^7¾3æmÛÕüÐóç/Õ"‰Y±&j, W‚¾EÞ-à´èt1‘ðeÓ$ÛÛ-#ñe}ûlµ«¿’{ÛcšÊîóË…¥2ºwõL=hDEá›öß"Ä‚#êýwÉUN*îTïÉÚ·½Én´t§à!T&¶»®¬¾‚è †©ôO³SSLá¢#Íœ‘zÚ9³Y©(X/|£§nù¶ («ƒn7ÞI Æ“€Ùñ³aqIGôI u»\J$çЄXÙx`© V¾³Š¼^›bËnR“¡Ö "ÅÚVM€„s)ê"Aþ³QF=7ÛÝzªã˜ ’ù¬@Cuâ[ôÙ‘³­v’¦ÏÊ,Þ©¦‚·ë×´Lô¸ÂÎáìpoÿ ½T\êÄlÙ[|Å…4NÇ#",Žê•ý\@‡о’$Y•à 9k¯t§XȱFã´D•B0J­È¬‹õ}(û6u³§n˜Ðߦ°8rû zÂÔJnú BH¤³¸ý•,è`ÇýùÁP¡-ŽÔ™°âhn¶*¡±~Mgô£¬,náYÖ =û6²JÅ=¢QÇGФ&†›7[Ê¢Æ0çîç4SÒšïzDÕĈͯD ¡«£]MÏ *ðÔ;-dcŽâp7yWíEóˆðíd7LñÝýª“8®¦wÞÆªÊ@@SçÝÁ¼Ãýóc¥ÑHt9ŠV ^ª>Ѓ¸ý®¹J"d$ÚDqû4ˆNµÀFPä{ ˜ªh5ÅDúôlV˜Ç·ÁÛ]{×á”ÞÉÁngº+.4Òª[òéq‡@`MJç5. Úí+©¾3é,.‹¾0hÄ6ì; ¸ª¶½/ O‘”<ä&$¸pí8Îàrî°®Û‚1}TAàõʽœT9è…×å€ǾÖ1A7[æk&ˆz…5—ñR%`”wXnÝU š\agÛ•J¿úPŠWª&®ÃXÝI‘t±!µ õÓ†%äŠ0€éŒ½*G½O?óA–ó‡Ú]™ÀðTïuõfÁÁ7çnrÓvÜAÓ#«ñêb)€%=˜weêÓ^5M.–Ì5b€’Õz³Š¿«ÖKÏàyìå–>㇙y­%Z –`³AK¸ßi]ƒÛí#  áàÛOþ²’Çvc­ê ,Óc€µB¶ï‡êÁÚ¡cÃOÃðÕ°OúNI¥õðEX|·•’èÝ©GdsÚUOÜl‡gk›éý8Túø—²Ä9Ýkï ÑZ•®ŸÇBv¢êåN3«‘Á ÛQãtÚa’Ý+\tÚ˜“ƕ؟V©ˆùû¥8Ìh5PYjQEm“11а$Xœ&_óƒ%{Xš?—#5½*h˜Ð¢VŽUÏ·êßOÞXÆ|ý¯˜ÝΑx°«iK¤àÞ±-rÐ/KñûPt1µÝÖˆ2Ì9íŽÈàã0±æK€{™-༿ J æÑÎC¸õþݱÃîˆó(•ϔئtÕ½ó=ÿ³g¹¸HÕ‹±xÝ;q£ÅýˆÜÜW-›­%V>´8T3#ÌVøz¿ÄÅ-‚H´®’1_Àó›Õ>޼¬.5ËÁ®0]’Üÿm¹Ý¡œkló ‘6Ê*YxØmã¡Y:¼ÜŒ'¹úðrÁ9 ±z¥‰˜Šøù—GG_SÖ뾃G_ ÞD}+ƒýö¯À+õxt^®âQ¤üuS¿*¬ª ÎVb?4Ž›ÚMN;ÄYdFdÙx&n»›Ž‘~˜W¢‘#jàq`‰zØ98ë—•~®fm¨Û_Ÿ„{VÄ=í$ŒY׳¦öâ"Œyö[·¿É$°™]†£'[†mx׈]“ã;wè·](XA«"ZqتB Éâ©^ÒÉ£=8 ܇,N¹,µ‡4@N‹å…hU«y $ >’‚™*TŽ èÖ<­DÁø û'ÐZ ÂÊN°ÚÄÞeHI^×`Ly=[pZÞÃJÍ1×ïªÇçr&B*ìÍó²x;·Þ”=جª¹»ö0‹g¶ëSó8óÁêiÈØ¡'Áö¨$› Us«‡†nRŠœUŸÖÈ©y{Ÿ„k ú)R­È„¨ 5"ú«ÚC¢¥†ŸŽîÕte3Ï~·aK¸¤§ìï,ùоžÑ“êÁ`уÌ& gÉêi¬äl²Zýw´¤í# jù(tM5¨ä r5—ºþÙ#ßÄ^xÎó%ÛÇpBMÀ]é›÷aÔH­ŽôÕì÷÷û9³£‘äÕåîæÔ-[͈yëýwG{Ä‹îÎð¨Ñ±MŠ–å:Ümö½K%(ßÁÚ¯VrÓ¿Ö±ê¾#‹^û’ñààròûb45‰(y?½/,ÉÈç,f‰ÒõÖ…‚¶Ý_¾b7mçoãr¦'ÞéaOØ7™à:Œ©#˜î_Àû»Ã.=Qÿ¢)o'ž­`3i…›š8ƒ‘¤Çb/'ƒ³¤t=–†‡lôJ´¹>Áa6ÙæY_ÁvpiñÖïRÅ¥dý”{Çêåq·s \V-¹­’÷àNzÌJQð)+aÚÔ)PòM1‹Ëº«çÕÎö.$N=ÇG 5”ÎMêœÆ .“®-§j|vT§ßnFì'83 AŠ›ÊN‹;-×¢îd>­sð»Rާe4Ïí…ó˜nWް3R¦ø#ùIiM ™×ô>%½÷¸ÐsÿʯB~)L² ’’L*ô´ÎHÆ¿ºô1Lô²4‰ú]Aï܆În‡+t îD¸ô(Ó³ð¤$J:¢È”ůîVÈ)$=ïO pÍX3´î§|w%ú9Î<ûì³ å`½ÝS„™fÀÔ*‘ÀØÐŸf N¸=3ëÙÌ)maN¾1oe»²]D<Ü8Ž-.=÷ü÷$%Gl]žý•(’Íå=À†¾+kÛrr6¦Ó¢íEÕË\÷ˆ¸öS«ƒñmö›=72áà"®ìÉG¶ú1uúï/×–Mbê¡úœ´Có5•©ÅãSé6‚§ké5¹Jͱ'~²ÊC0×JCl·Úþ­‡ÍQ~e>šäÉ¿ºÉ,ì?ý¾8_Ó~…Ì77­ŸçÂÒ#¬¿2_ôe)”À÷¬ ,N×/÷ÉÎWMOíP#å㬾5MDÐö Ìå"Ä6ˆv(öçÕD0’¾šëd̃³èC«¼bpuôßÏ¡©˜Ø³SveF+Ëÿ÷AãF„…η€Ÿ$´@kâÔü‡ ìÖC⇀léfeÁó£àsðM»ÕÊÙ/]!@… ®ågjîü‡Qçå刳‹RY”álzö,/8*̳çÒ5ÏÞ²»½‹Šõ×ÁRo5ÌÏ“I—v‡´u¿éØ#ÆoèÇ&.HÑq»ï<¿ ´8h[ SNÌcGNF¢-ä¸ê+P;U 05ΤEAìüˆT‰Fø\œåó²þû|¨¬•âö3jŸ _蛇Á½­ rÑo†Ÿ³$ew—]kX(¦þnwwÒÿ ¹U-aCŽ<†‰Éè¶}¶ãJ×L±Å þ3#øuf9ò0äs^ÔTe¨!–ÁŸ±0Ÿ°o>P§$7rœÐ.ããã…àòµb{ž)ñó^‰líiî´žzÞ¯aº ©qm)Ò­jUÍßÊtg„曀-›:¬ôS§©·'”×Cq§æ%IY†ã»Â kH1‚NŒ´û ü†íìHÛ¹zMÁßFe%{œecXW–ö÷!Š^©5Ä3ØàtcíÛ>¤ëÎä8N“€)•ªàp»|je  Öelîˆ(˜ÉG2¢Bi›Ž DRmú¾[ûPoµ`ª•ä]¨=—Ž?YÄÑ7tÞ·¾›ƒó´º¸RÁËöB1AIR¿wˆ1Ú³òéQ$’9u]m‰˜`†/6ƒ†ö¬G{Ë*‚ƳµaŠ ¼SôG6Ã&>i>Ü’6Ž‰Ïø*KƒyÃû?ëüÀü+±ûÚow1¨ëƒÁÚsyŽg²1ÜÃÌý¢Çýš/#ÜÿÎìh¨;P/·Ã9ƒý”$m{q[á‚ÇFzø¨¬çÆøX¿³Ôie&:±ˆÎÔíp›7‚ R§n×ë"cI ÐïºÜŒÒ…å”Ç“LbiW¸ÔIMfÂÝê?†ÎôH‰žáéc•¶²Ps‚ÙáÛÊ£Y_¦>+Ø,hb†ÃjÉî.1M;kr'I˜5åÏu‰Á|F ’0{¯Ž­åò˜_ÐR]²Äræ30|VÜ¿Àd.!žlÌ:*#åaÚŒðèß[ݳ8Kb„…#Ê^sPj…ê¥63t· =ø 5{"R·ºÃ‘r‚Å;ôÔø~µÃâµ°ÎRu<Ö8]fLåQ®aЛ%´ůÝ@7ö9·g¾ƒðÅÎW´÷íýÓ¸ åþ­äµRð ÖÃÊ8Ç=A©ç®mZŒc*û̃XŸrd–vÊúJ=âv /5>ƒ;ÄDZÊÈçé%$ª9ïGÐg |˜áâ-èiƒÉ)µ$·ôzN©(Ûm¡¥n´â¨>væuÙO=è…®ôÖºSxý2þ¶¦}„¼ý¶Jýã¸×l 6˦¬Û^¤ìÉþ»ãòsEÑHÁuÄwµp*hüaßþAc[ËÂR 4_ã:BÞ—û‰©aëü)Ë%W2°ô x¿NçïN”kwKÙ»2sAÏ.ýõŽë PÓ{m+yUŠA8©bñ5a0éæít†™Y"GÑßF™iá„KŒt$p¹’^C¾ó¥ !Ö/mNFvßQíÕ,¥*W= Þ§Ä5(ÆSœôxGðñ´§,æ Û âà?‚‘IŒ4`ГeImÓ4ƒ\j[nÜt4DŠw5{ùZ~Õò r»×§±wè­ ÿìÔ´ºûžnH¿SÂim¹}ØnTpä\>ÏI &FºãÊià!’°_iœb/qY9F/óc ØòꆴS‰í MÛo¶cÅ‹‹îsT~¼^»ø_Ñ®ûÿåsý»ÿþõÿúO¯ÿ€›÷ë?ÿs) ð°õþ«¿]³dÓù–ëW}°Ó]x¥ w­æiBÁ¼Ø/qt½E½¿ypÑsÊØ¦çpŒ–~<«ø`ŠüWÑ#Ví;7͵›@ ÂÊMo ÑŒ$ ÉOZ²tqÝ3PmtÀ`¿°<Ç] Ùø ž« þ ö‚1DTâ*ÀÚ¡/c¡ý-‡À3ˆcMI¯èl:vé!8ä’Ç+IJ 0…ëð¥Ë­YûÄ«NØŒG7ÔR&ǾCÜÁ[†Lã’oѯ56}Íg|`Õª:´z#¸•^W´OžE5í+†êcÇV ¯†Ã´òweŸ‚ÁÝ:W¨+îº}m±AcÐÛ/Þ§LÓ÷¼Õ!c9(%µ›:TxhöEêýå<+¾pØ2nàÅ»:C{æ[þÀ:ÄfâViºplº£ñÚÇLÄÞó~Ħ™ß¥QžÿæÛD‰&ë’×^’ ¿è as×[Q—‚\}÷-„2`‹£ô·‡É§:7=Pãh˜Dðîãƒ)ið)Çv€gÓ ‡]‡èNîñA—lY§gd ýÞ\ñöï yˆ¦ÕRÄç…é|Œ€o=.ê^‚\3iç<15*Á(—R.|* J9°I8¸»Ù0üiÆ¥öM=0ô Œc Òpêí ^iYrˆÃn†JE~ ¶Ä¶­!Î÷÷ü-‡3~p©?§ÄÄS“eçØ;ØiØBßtåÌ¿˜Äë6JqÛJH¯$Dnfìô‘÷X/U‹¤l¼X,{¦S#Î"èp{¸S/Ïâ"2„®iáø×Í¿}ô•ÁðÕ䑽çÕ›Èc5ÄeE&P(ˆÑ¢ófŸD”T¶UÏI”ÊRÉVåI TÑü¾Óí‰ÁhFe°ÇRëÝf4)æï m˜8Ö¦ÈÊãF×O&2ùñú»"(2˖έ¯Ã²ó $Õ´Ý"éÙ㋎†“@ìã§›}²Ìg"dØo²ÈËÇK]t(aÑòX^šã”ëy@iÊ9u°µ°`»ÃIÊäÝCDöE„¡eÆÁ¿­`QŠGðµù,:3Ý}¤V=O÷1ëÜõùšÜwÌV[8A U5\ÁmÏ!òÕæ]û!ü5I¾ºÂ·½•9BÉñ]ŠGŽ[ä`øÅæø¼[\Ãlæ-‡ˆÎxb-1·¿†ÄÞ¥hã¡ËSÔ‘ÁÒ 0½ôW>ÓµM‘å.ó”qߪß¼­¬rÇž>‚^a$$§§¥^ªZñ¼c .;ž²xÞ‚6‚ÅÚÚ¡¾ç¬að‚v•Ú‡¦›8‰š†AÎC]ÛC¤Î¾0¶VBÁì¼›^[q´@z4eÊÁÐXE³'vìßÎÑ…0=º×‚*„3­Â~‘Õ¼æ<€Í ¾^OßAb•—†¦T9±1ȇÊAV¡"åøbÅ/ÇJË.\ L²F£®ýÂî´DP=¾­½PYÒÕ·€j2ñj¨ô5*¶žÞwzèÖêæ™-Æ„¯|IðØw®¸F!HS‚½ò²V¾¯ór%d°õAËCð•DÊ–ÀüYîD‚^ÉšÁº»†•ßæöZì«^CçÇ'tmèḗ–Wàs~l%ý† <(ý6ÏI° mžr3=žŠp޽¾ZÏÜ š3‡#¨ÉÁî.,[*/‚}t?üŽja "±ÞªtDP«‚š4ÚÇç ³xѽ9“÷‘z½º—svH_Ôz~ ?ÇmdJÚ3x/»äÞ]; ¥å›ùî¼>½ëömI* õ,²(x†à$K]rÇR†gá{*k4ÌY¡E–ù`ðA(o­‰ )T—P™:‹m~>º<‘!fŠvRùs>÷ÊŽçÉò£#·šbü:Ÿ.[c½&ŸË·Ð ?™^~9buÏ­:p9Ü…9ƒ·úíÜpõQOs3ð„õlp¦–Í'íAÜc;Ãâ$÷ sZU.ÀÓz©!•€zšVÕ“0¡@sÛµJÎŽØ5ÙÉbàÐëÖ‘ôÆ=Û´UÜ¿K¼àì¦%¾„¾Ü ŽPWxgðvhݾ…øÎ.v‹Ìª…Š{½íÜÒÎVúRGºÚWc„fQ%z`Î\¹ˆÑØ?CpDm_ø_VÙ#*žÕÖfd×úìª=fµO‚f¡Õ¨ÓG°F®ÉöÜ3ï`0,ÉÀdåóù@|¨äÆrÿI­LæÏèL߬f>6—)1×jˆ÷Ë£MSƯ,+·UV*V{ßÂny‹çe½×C_¢Ã{­¢;kYÄ̰U–íl¥¨Àþ }â/©PA¡(oµj¾·Í7´Ûàÿ·ÇØM¤?/ùÖÇ&Ü}¡_ò·¸Ñ`Åöù\Õe¢þµ–× 2hëÿuÎy³º]ãöE½³'K]Ûñ¹ée™ŽíéÀ^•i'Â68yì÷ÛMA[ D9Ká¸‡Ž–Þæ&ï+ü'3¯ö»Ý H{¢Ï9'ˆO»‰áÓLu±š[ØÊ€}!zàIÜÐÝÖ…-R ”Œ Ds0K«Çµ °|Z¤ò~­ŒÕ-Ùz^ä3Â7ФéuAJ’ÖÁU–‚Å ¸ƒ~›ýªœ‰z#‚ò«¢”P³ÆØy™©$+Öšú:¯‡ë>Û¢=îiEØ#¬t§–3m ûJ,å±ñ´Wâ gœyŠÞû´¢´ªÞŽ–íL2s0ÂM+U_ ëÄPW*n̆ÅO¡ÃÀð tß0W›´f×`Òø£^Ó)1°„¸Ä€\q£ëÝ«5UÆv?'¥º<ÄzôtŽ‘š&véÁ3Šàè›díÎC¤ &ÚxŽÒ‰<±(Õx¹–d{ài¢± -×ÕÝã6¶{çúrКZ+­ÝÙPw¨+çòQŸ=8Òï+6Ñ_ò²I ¥KwósžÉèLµú²q'%ÕÔ| ꯋT+6˜¸Æã>ðÁ=4 Ô´Þx%йårŠþ׃Ë{þ|t÷Â*3$!Ùp¡Hü—œ7¾>Ÿ2ÞJ µÄ®Z# P×OÝ”Ûåq[@7~ù•3ŠÁÒ¶†Ns“kÁ¥ºYá¶§‡˜{éíp{ȽBkzöj3¬ÇÜŒ¢»/Ý=|^ïŽ_O±+iùe¯´Ð³‹îìÒ®.DÐ,Ms•üh€4aiØô°ËN !£ø_ç¹½ò:­¡ÁIÀeï·&FëÂà&Iþ¤…Å{Þ¤+ì(ñA°èðP´K)k‡\±w*Þ˜é8ì·0ZÈC!ØC¾U)x¬ª½Ûzæ+‘0G- ÑB63Ž&š«ÔNx<8¬V¦¸%¬ñ z¡Ñ·ÿ-Ë Þ·HÉx–…_-¯–iʇÎÇúŽ_¨.’•­d½<¤*-ðÝ‹UŒíÐ÷žga•;õ´{uubŠ‘æ_x Q{¨hiˆ^u 8¿àŸ]Yu\Ùú5rÙÆó1̦e"ZÕ¢±©;KÌŠ¶PwSˆ›W¸=ô@û—Oâ¶3´Y‘îTO¤Šòôi.˦Ão91¶D«ÞÑrYgΚÃFh(ºÎŠÅ$üö]ïûH8iDÅ:‚´·ãSB߯ët—<-{/Ó™¼êjhÊæ¾MŠjjÎå ö;¸ b{cˆÙå_aû)¬—Õi£ð J$k5!0}ùšËj*m ;Æ’@ßrÙm©Pé†CX õfg&M^ôîé<Æcˆ"÷§yZz{4{oz8Ÿ!z)ðÁÎÅßmz#i¥?˜œÜv>2éEp[?2×þ4œJÇ=DIsF£LÜ¡7~¦ð8ƒ»<‚oçö…&ËÇ£å:N¸bÀ×ò¦q™í½åóbÑÆõ`)Bf!öéôš‡¼³õyø“¸°K®Dân024ìj|oi8/ÿ£„ÚŽ[A§Arö]—Õñü÷E¶êW$dz³wà÷wúSH«©R'c¿îmÛkÇ b ªEAMŠç8‰2Uôz?ø#¦ËVù}Ó€Ó)e,šQ¸ŠKêÄ[Ne4UZ,7JI³©jCnEp]û1Ä5‡JTö¥¦³®í‰,d‹EOžçE.2ž:ƒûGÅIâ¾] …“ïÜ:Û¾ÙZª\vWWd;Ï÷RLóî!­<ãð¶Ây©ÈåVÖAóPŸ…Éæ©„…/»Ïä[¬/Ž¡õÞYj±Ì{¡\ÑúúÇ MÂOl³ˆ6™NšMRø@&P;tO#è’öΗ¬oÛ:¾ôâ-‡qí(9rùèÂû;û{¶ïBõee  ƒ*>pJ‹£#ØÊ=c ¯‘XMòØ!cÔ‚äWB`]Cˆ=V2i éœU#ÔxGw5wÁW¾Ej† ŽcXyÖ@§ãßÑ­ï¡ña{5:p§>l¿‚Þ¬Gkçî­m±ýqk-7Ž£]u£–\6:–GN‘øÕå\¦gñcJö®0Ãë¢â°å)‚šÖ¡b-•Ó3Ânw|@_e¼5xl§÷ ‰´8E5´…N"-ÄÄ0}°˜ž5@×JÁG΀»œÈL’ä]_ùÀ‰¨§t;ÕºG{œ„,øÀ™ê2ŒD"Uñó)·CÚ¦Îù<‹á/d û§çÆÏ‹7~)‹¾ƒœÒõ|Ö(SF°…為Ã94b׌›lÙ`X©« O‘^ÁîîÝVÖ´òù¼5¶þØ€µK:v‰êIéý1Âkmz®ÜÃ…œ%®pIü¶7‹áM}þÖj| *žîjžiÁ×&S1!mŸEµ.þÏ9£¨ï5zq=B …t ¨b=ZûDEE#¨(!Ò•~G1tÆ#Û³;PÓ:m#ãg ;ú¾«h*¼méG'Ç$Ïàƒ+r°Ä¤ªÝ/5r6Õ…À”ÕER{fY¯^§4ô7Eh}Î`‹‰ ÁP½CЫN¢-W8–¨° ^)g÷`ÞÖ“e}R½_¦?ó1™dqz¾ºäH_Ã>À-/í²”ó]_`]lóޏx5lh é7<ZA™ ýmMz!wjÓà°»ßùñ<…€ ©Ó¤,‰:+/¥P„E-ü œÒî:½xTåÔ¥ÝV^JBp+dšž?µO6›÷‘e½ÞÔìè7š—féÈÙû‡_Á´™H¨ót§ÍwïçyyÉÆ×òÞS¯.;zwW‹ŸÛa ‚²†0,l#¸¶ƒÏæá‘}ÙN?Ý -pà£ü®(ùbÃÞ>ô÷Ä~ÜØÊà­­5]ú4Dˆs+z}ðA_ú@×ùÙ-yQoéµôø!ÍxŒä2H\ M P †Šë¾?²Ø¡at£¹ùMKCp5Þ͇‡1A¸ ôçïhÍ-úIYÆsxi\zÜüÂ[úxAh¤å?ô龋1(ã†>¸Ú‘ÔÛå>Q6œw4=¶9÷KsOåÄD:§4•³Ê>½é—E‘‡`»a¢-aU§©v»éèåÙ"#î%Å+qâCÕÅ¥n$H/Þê \g×jŽ¿Ûl,Ëíç¾<ꦻe…š_U‹uÅÓ§!Ft¶^ÖGF°Q‹¥×ÇÕ„@MXÏ­ëtyß*늟õ ÷ô™“R÷Ct‡^zî}èðxw°u©ãÁfõ×’XK?âƒ4} YÖBçnΦ<ðÑ{ÍÄæh¡ÌY¦|æÆCpoyö=8C/£kŸÝ¨îxäf3g“º¶­žØùò:ùx¬LÿZîªÙe{?Öffx˜'Õ2º”S—D"ƒdILûc>Ò$Sê6 Ç'BðnEâo¦ïô¿þ´I¯Ÿÿ»óû?þü¯þúßÜ×Ïïøúÿð§ßÿÃÏÿPþú‡øíCûô¯þþïþÛ×ðØûûÍÿøÛúýÿú§?þîÿÛÿñÿôoÿã?ýæÏ¿ý§Çñ[ª¨…±ÿþøý?üÛ?ý÷øþûßüö?üãïùWÿÓ?þ‡ÿëŸóçÿæ§ëç¿~ýßßýóOú Z©—ÄNoþïßýæøÛŸ.úè§îp-CÒ½ (ò:öW”Lµ†ªËþú§Ê©×Ïÿóëÿ÷+ôÏ?·Ÿÿ—Ÿÿwýüøâ¿µ„½ö1’Yú*!]¡ÍhM  ë¡êNÉé+Q¢X¡Þk»ð*Õ#߀bK®ÃÈBÀ.ÙŒ)3Mt/ 2ï’&2ôãî*úáÿ³-9J$3ºJg“‡Àmöq">?w‹-÷ÅþUÓ¢ éEÀ.Š÷›¥¢ƒ8¤“ø]È‚xò8ß9m’íßöMZѾ8ç:<‚(X¿f-ß][lŒ5%_!À‰¤¦7ìÇ›ûöÓ¿ÿUîýÏyÞ~“;b˦\QÞüš¼NÒùLõ¶Â‹>++}ëþ”_•”m@¼²‡Ô·Ëhß{éY¸åqÌÙj8sÞ–d—ªÂÜj|~|0óƒÔí] "³Ô–iÁžçs~ÐÛ°ìÈ>,%xé©–7£Ûlw›ï‘Æð¸wzäzZ} H¹ÎÙÕhqMvÄ0c†]Ñ®m˜ DžÌeežÇlK­¡ßƒ×è{·yþL¡óA ¯$| R6 •ÛçÑÝô:ºþÂY/Ãd߸ŸÊ/õûˆJãkwj׫?^mVŽûüñþ .ßQ¯Œž÷¿ìÇ_,â´P?>¸îúñÁ#‘e(‹é­üðSA©@*Á´Ào#úø·šýˆøUŸ,³Ö² àC6 z“]ˆ‹å·¦ Uô‡QPóÀRù@ÊÚ+X¶q¹¬Æ(!B91 Šz)3!6Ê I³PŽ6ÄÕ: S¸1Bq” (þ^1¼…°ÑXì’ÉÎRʹ"èTÛ’ßíl¼ÄÝíïöø«U*X«ÿ»VŠˆÒn0W‚hA®2伓Жrã„'AÛj1Àš@SÄPo­*oÆ|z½ª}—¡ØL'¥â¦ÈÍRèH)ƒ¬Ì7¢.€—ÎöÊ L븉bœ¨ê5k³>[z¸á;ä§fˆ våCeÅC‚JnŒÏ2¤¨8'‘hè +²3Þ}jl°!TšbÙ\쨘P¨«è˜×Ì^1QB ÛPºY0ñ!>9‹šÎEÅʸٕ†X¾ê3ÍYAȱÊ(èn×™9eÍð¸Td¿=vÎî¡_¦‰‡M¦B3 ·%{»œâlHh&jt¤¶‚º}ü}Éúh”K@ ¡ ÄÅàp±Á£™ÈßgsI8kðµ») ç:0dÐÄãV-­%éZ⺣¿ŽŠBͲ<ðr¢¾³vA oêSUé*™Ê;&[ÍúSoüÄhAâwB1Ë3sS—Š4 _z°49îQô;Tõ[!ÄGܯŸÆÉè&”ΜD]tZ)θNÆË¢9 åJU#·WÍ7&< s#t#U qþíü´mÔW°»ýÍÀxѲ !›&ïdòf¼‘ÓfƒpOU©M–îp¶+ÿ» ë!l«6‘åÜÑoR*P¸¹•hŒÀåyB{×f„£æª’ŒœLÓ®Zh°¸¾ _0f1Ý1i'c á P9áÙGÀ—&jz|}ÅVÚ/»=—¨U̼<ä™B©¨¬J7*ñH¢¤·;J&Ÿ£¿Ä3”âÀÂLÇÑÊPk `z€Ý**>¹Q {Ò<`Ÿû¸†è/~‚ð[ÿ+&0KèaNâ¬@†Ì©r ÑLd vº­® ÆS5i“mâª#ÍZÏU»½Ö ±²±bw·/dlJE0…rÆ:?ÂÅâö3/¿¢ãRLŸ¯ª¦àå&j!a|’z½:Yp-C‚šKµRÓk™^â<À8u¨+Ëf£Ëó¸:`ü‰³V^{WÖ‘»Ð0d¬oDTO4,“¥ù¦oÒUchÒšìÞ-ÝÃQf¸(–÷§Xœ*›I^ˆ9rcÇÊŒÈöu³¿WÕsú_*ºJÿSƒ Å`ô÷ÂtIF»y#°-øf•‘µªB€r3‹S mÚ®åïÁ*Ë;>±´ÂXÀ ;Ô!Šïä_âÅpJ“ßWÉØ»¨¹”Œî«5W¦ñbu†¬.ÉZ¬­]„*LVbjÀ—WÅ3…Ô=¾²"JÚè $¡‰[µ@Û¥×1‹ª;pB»EcWÜXì€[ûnv·Nôm ¬wéÃMRr”7Ç4~FÝÓVUì"Õ!EÏô*Ynñ-U‘›À°\|Í8›'ŽéáƒîX\z\›ƒ"€ Öµ˜X6‘æ±ùWkÄ‚ÆÍ |O&„¬¢Œ°ÌŽ0¸p¸þ¦a=Å„›ÕÙðQ;(2D®|Ä©å¦0…S\[³ ICÖA!2ÉuEºn<8ßäO<H-º×,…Ë'•¿J²áà¡HâÔ~¹£Í\"è% r/wnO¼˜ñ™õI°„ÉåОâ•q/Ö–‘eòª=n'4BÂËE˜{´´t¹hˆW!×ÉIuûkvÿE®¿‹eÜK‡ñ„ŸF]¯YDÿ¶­÷Ý­_dÄïÈ¿B5˜j•sºr…êÉ@°…§’R³œœ,½!z­dÞé‚ëθwÉ&žØø,ß®½t\hÆ€Œ ªæ9Ÿ"ÖÌ`ÒãÀ–­kº*^Ï.*ÞÅ¡0Ž)‹ Õœ=®»x.\!A¿Õ*GÀÄ0‰À7]ÉÌÖ9”«T…š¡r]`¯aÖ±W~2årŠcÍÄÓPÚ@åï]ñ½PEl “ªœVɬÎ*eôM"§Â7AdÁh˜‡ËãBsˆ÷Ž6"e ØÑ·£4gU±‡Ç7›“>ÉÚøy#¢S–ŸMƒa×ÝHt1äùÖ"#+¬Eó1IµÔ‹Ö:h³ž˜ PM1Ý(¿ø·B CJ˜Z ”­V7Ó€JyÇxºÌŒ*@¼É­ŸÓîö¯LíH ^uPgp}þšfž¤ŒÅ@ãå›â ³‘ˆ#VÂh‡u>7Wl¸¸R’å ƒ d€>TÄÑh9U¤ Ÿ*^s«0ôrÍQËšS—¦©eñCBœ¦A›¼e34ȧ«E ÐU͓֫r.„Ù% ÂhÍÍüõïØø5½_4+jŠÜäMâèAy=š§àQQÊt-ˆ—Išt±«0åˆ^xà²ØùQJ^?<Í&¬Â²jªÉfÓCInd}ˆÉ¶%UÈàPÊÆˆ‹a1;yX£øE¡…Þ­÷aý5¸±3èÞ«ÃS³-Q7/¦Á äÌ®¨ß)} š"᡼’ÕpàÁ<®îK1aÙ6oç!M¦CÁŽ#jV> !mÀRýLŒ)¾F䥨¥Mû4ÐÓè)r`Kê¤É}Qîr/ æ¸TvË<|+´nð#ŠV_,YÆjÃjSÀg‚4{³ï‘P%¦À7¨ÚÊQ¯”lŒÖXogwCwv•¯`œ™}üüåb_k–Æ v‰žØÚ¼‰nË"zÄG(pü–m%B).¤ï£a²’F“Ì>S<>U%;f]jŽ„Ó³Ð½1—IçƒMT€´cx»ôí²^±Ð-w3ÕÙ—ñóøüØNkÊ﫵µcs'Ú;}°l·ÈñâÄÜÕÄG*¨£3À\°óxp40õ—l ‹pÇ»i.ÞY.Eú»]ïvøj3"»:9DQ:gÕBì³ÁRõŒêb‚Àâ)®éÍe;§qît{»d©mÕ‡ƒÈGŸš%Ýïf¦³@úÆ—»»ýƒé&XžUö=µrÕø%°@eó%Þ3lXp0:æ,BÞ+”Ô`’@¾s pI¶…p|+º¯†"k^RdømƒGÀ•×výn·UÇõ­œµ)ì^Õß*Ó²!8ŽƒI^à~Œ‹…á9W”É[1,t6sä$”ÜÚ:êN¸³šf™b¯¤ –B’ „k¸­–àSrD[“-Ú2¶Õ„£³•A+¤îQŒM|jóK ]-jÙ—ÍU´»}qÁ fddo{³4j™YSÞÔ lm–F!º³á·kÍÒˆj%×䣚À[2¿î UØu«oBŸÅòº¼J ZÕC\B…fB†":¡¤s]9éÌÍ×}í'©@‚ R7Á5’"*R¹Ó¤PWp—è¥CïÉÛbÎhðJwÍ®»T;%$#8æ•Lª*to¶9•‘‚."ý¶ƒ/ACÌMŸøˆÕÓªwê´Ö‰^Æ…ð/Ù‘¾V£'¹9ýFõlàøš„J8Ê_‹b½4ÍL"7š¡;´±41w­þ4ëÍ6¹ê—hìBÕÚ«¡¸yÆû‚º$)ipFM+¶£u+·³µÑºi1ŒÅé ö5/›­À´ Ù6u9   nÔ,´Œô4ÕÚRª±1— @ѧ\ ¥ØÞ¦;¿-- ÝÚ¬KhÌð/8°µYµŠÛɵ¶6k£ØÆ¬;±zÆè@›˜ÁϪ» ¬™MÈ´î2cÔ n3á¼$sR‰» nùr€¡¦˜ ©ïCü‡ñ–èo‹žWYˆD¥“P‘“kñå몡#Ͼ\V6äU—ÇÃéB(Ó„Q+? ¼ºn‚ãôá)¹.ÁÉÈ«ÃA Bº,ANÙ;«‘ZÎÐió2èÈÔ<å'#f´{Ȉ·<›s³åð7ZåRM"ÀMÝ·k,/–- B¿MIÏ[L|·»’>Á°ãÉ@ Œýïe:‰1Ýh÷`Žeñ¶ àUcP/…¶‚kIBà Þhõ„÷´e…,œ otCŒÒ ¹–Éõ¡Ð¶.æ ¶¤´$ñX^D4°8o öDiS„`Å>¨Æ”åŸ<„ÌJƒˆWuˆõÃÔòaü½<Ýb*Ï #»ôöX«ÆÉc–Ì$ݪÅàm\6jN›%šmÙóZІ–{òÖ„?ÕíwþÞÒb´µW·»ýßpÊ» "Ny´ØQ3?™©àaúE5ÕÉÙRšS7-8¢ëV“«_xQúõ…WÏÎmQ?=7OQ˜¤D~¯åÈL°¾K׀ذԋÖÁ€—I!tÕ4jñÌS!fm]8aË?ɦ¿hž`1¨®ÙÚ X÷­´Y_X‰§þ]— ›o€ˆ/‹Ø|}ÓÍ ž á›ÕMWª~y^Þàmq0Ó'ÈêY-?­&ž$¬sÁß7%z²©ñ÷ˆªIX½Ô(ž3Y½0°˜>CG¼öMâžRåÒà*ô0…¢h½yo‹<àT ñüs0¾ª<¶‰YYõ í”ÎV¿Hm*ü@|±v%¦[Cø 7[͉fE QÏsÁ£œ‰`áKœöJyH%n‰#©mJ“%!8´9Ò®\¼s £‹ÐÓYR|>©‰Øóc¶†¨"#†Uš0zãõoÞ7c¹PÄ(ƒp.*̇‹öœ²‚WpVXET~£¬Ää3z«\´x!KùJ•Õ¨ägU¨¢§G P…뀖8W7Î%úúbbª4ÆÈY…‹*O¡Ôöø‚@WívAVƒ>Á^/EèAÓVE R =Ú@:ó=r³·3‡/ñk§òjup½F+Ÿ6§ìem:g´XvT€-÷§)z3¹¥>XåðGr-‹‘8ˆ­Òíj-O3šZÓ §3²œ(ïÔ ²tÔc:+‘Jvþ6wjÝ»íUi{Nê%+¸±˜m´ûdRt<•ÕîŠC†""HÄN W‹qägõ®á…ãÖlÕØŠÞ£Æˆ¢n+ÑnFDd:ÐúÎsÐz‚j)ïp±IÀ›Ñ 3Á.¢«¢é§ËÞÒ•Õ–²11Ug ê{q Ü®~xºÑPT, 4P94(¨öÃ.ÊÌâ—Z¦€<}á5gwÕC%²$0u¢ aãÃßݺÐ6ñ¥*þïrÍêÿ\Ãå§÷c€/«Àó¨Õaeb‹Ú³ïJ'kCñ·ÊÂ2QyEñ&"mAä;PüÍTÛúk”uqI¦×Ö‡E¡Að̃fÕÚAÀšúB<d.dÄ« úU8¬†›™QG‘ t;UPš«t æÁÄn\=Ä ‰eÕE-ä uíQÃÌbàªþÑž¢ ÖØ¡D¹Ñ0 •„4Ž›îoá{4¿²›0×xS™Ù]ÉZ¸kåãP„Óæ›ÎN7jÑÔ$§×ǪeS)Àu¢"® Šòó*ãElè{p¤‚ŒÆÝ±¥Q,f4À]û+í­VUÞ®öÀx+~ìx­Æéñ‡Šm¯†Ž[\yÇ`¦PñæâGѷܫΊ}8Ÿ]³¡TRËþ¡s¤95FœklbŒ/Ãëæe{ÕFµçFû¸˜C‡˜­·NÈÒ=ÊŽ4 Ip#˜ÄRªHÜÑpA8쎎?}&Ìì„_rNqy:A.öïWå9¨ƒÎ£û W» ®TFiª¾neê”<´@Ëxð&ûô×&‚Ú…›^¬ Šm}…x¿´ÏZ©ý%þསõÚµ0š-•½©ÃëGbËž>=2â¸úRߣ°–J‚r"ü ÔÑh›âx+$íäu$#UãÄ3XÀOn ëô”isY=a%t.ª¤G@ÔÞæ˜“•Þ2Å ’Ä!!Ç.­C—gǩ˲YÒ(4elÇYã‘_®mW5=¤à•ÂÅ´„¢nk”m×V|…,ÚH‡8¢×HP‡Dñ×äP®ãä6W.Az›ã^Qƒ4&ºfŠ’ô6ÊØ7¦Ž‚ I&AÑ"¶A ½¨,`ˆs2B“—xˆLt]ªCJxÒ*ƒ€ë¨—ã°öBâÐ, 9˜¿‹ƒÏžÒ8sí{å>Ø9Ä´S2¢0ÒëÐÈB´8sQ=ÌjB¾­(Ó«ÐÁP €ÖPI5ìXT½ÒУ$­ÓpŠ™5–=ä¨ÉàH'}+W”Áœj™ØÜí-€ëdØk¦ƒ¹Ê0稛>ÓìMh.ɾ³oÊb ! q"ͧÈuêS¾„€þ…÷Ú§‹!šR¥hÇæ^A¶Óx£,^“A@ÒÃÔ®ºîÔ®íD¢{O(xA6ÈÄ)›#HSé,˜:êhÈ­s&dÇ:”=•Åã¬!Á6‘ᥣ„3ô VHש0.é6ÄÉøãÙµå3xÆQ_¼Iû%“Ôbº…l’ŒO&E°3§AðŸJÕ[K}´5këó ¼5Šˆb2wP³\d[‚±2ou;_5Ža¢©±. aòàXIJgÅ¥ŽzÆvN• zèY^lÔ˜C™¹ðY Q± [­%,¸Æ& !*ÚÆ=VåHIƒ ÎËIïƒqôW±H¤mÊ•P8©tí€Úå¯ÙA—_ÎIY:âÄ1PPRu  3©Éè}Ôi£Üä ÛJaóè˜Þk1Äil¬DƇsÑŒTŒíœI 2$PA9“{\¹*‰ŒàYU·vX>ƒLxåm©;Ì’X2®Àß„bÊ”¾÷ð|Ä "äLn2¾j®ÊÑd 'ÉdiTH 7eibV›#ÓF›¢"„2„ýºn—ð#G¶ßÜú¼qééî䙢š¸”oMSqÑ Œö`±:»FŠX ª5üÚ…Ž`G3¼Ì8KóäΫ©^· LNr##0)9K¬³Ü„KØ8 8™“¥)-—î©ñé¡AÆ{F¬:ÎÖ.Q”Ú¯!|¡8m4_uerƒ:†ÞÒä«ñ” oÄ»J÷JRÄost „D´HÙ $6Á&òFª’kñBÃ}ìhLy£SgÞÜbvàI\Ùnº~Чµ ™ªMÙ9‰Ž¤ÝH%ôbªvÖg¤IÛ±EeUd.-`;¢T0p#§9¦hcpº·GõùI»€Fýš“æzx×'_CÜP:Μpl°láèÐ _Ì”w™u|M¸H’øâÚê£">»¼ð$æ­Ÿax†š@) ÏY™È/”ëJ5 ·o ëA›¢ä§]ŠGÐfµ£c„h³ÝRP½ê·É\û8Ö1«„˯ƒ~ DƒoD}Íc©öP.¶Ûp~S:°*£¹tÏ%Ü:‘íÛó5óM&„CmB¡ÿÞèÈ '&„ÊŽµûfÂRM³íeN#T@Ý!ÒM8¸`§"…@Eáø2gjFÚ"ižRžI­QEDÊY’ØM²¢¿ÅDÃÖzÅAYY¶+3)xD‚¦`òš^ 3…Aߘf£!¸#€ÌÎJ8ºÅÈIaA0ÍÁ¨öe„PVÕô)^…¢£‚zزRÆX.ðjUq’ C8u=Ø”‹ÂHÅÕI›Ä&*†`Q¶á pGÕ¯)jŒœAPQwúUÕ¥á •^Ø‚/Ž:lR²Ð’²²=;:p‚njTáB‚IV\tåqyiTraòbx ºxÅJ÷Ë•—òÍiV›í³Ò°c8 ™Šª|1›Å”>‹Ä¬ŽØÌn(q¤>Ö®ð$ëTXÐC͆¤42˜Lº ­ ªÊ‘ÕA6ðõgXÒnQ<šKÑ1¿ˆá+dWðøé*“I÷z ¦)œ"€p¼ÉI?"+U8¯k…œSc²sÚ™–ñjf +gÄêš*ÑIÇä·dÍKq»Ð±ÚÝ×Raw ïœ:4+Ü$m9uô¨v cvvì=¥ô¬ã•+Ÿ‰ˆ²¢G‹{GeßUÂAùÒ8˜­$Yµ´X-¥Â}¨õÐÂCãh%v \Ò CÁ‘®Y§ïTàRaý¼ç´¢_¼bN44#Q×$¶3N¹µ}ãäcðƒ>båKÛÞ_ôØ2\ñÎÔRNì!Xiô`ÏTõÂLM¶Ö{n¹“‹ ÝmæZÐ’+‡÷FÇøÄÆA»î+ä¶Fl}RàÄß]ð3qu º·4½ÚB|Ðqç­OÑwT"9oŒ±”»¡váp‹Ö3Ê·n›KVT^‘—}d¿™ïŒÇBqgñ}é¸ïuȨ:³[Ü9®F  ÐUnMnœN6;—¸Ã9„7˜$­ñ®qpµÐ˜ê²"–܆Ô43³Gý±ŠÞ Û›| €ÂEeudíÉé&2ð-ópf¤7"n}ÛqeKËÇ øŽ¯ËfO˜\ƒ; R"ŠÏúüØš‘Æ>¸3s±4ÇÈéÆ·Ê Ù0Õõí’#v€/ÆU Þtà׆äÐŒ™Óɺ¢£¿%($CÜ84‚Y¦¨Cƒ›WE¾Þ€¾A˜D‘<ì ÷³èþ¢›…P'"K­ QpÄs•-µ¢üeˆ ‘6§§¸X+kÚÞycå©J™¤fC$Á[NlDh²äQ”Y̸ȧM‰2ÙŒ«{cMNÿ —‘q¢Dœ¤fYDòá8=Á¨¨Ýƒ÷U2±U‘¸hUl;[0 «!ùû@)'³ÿª1Q& –ªîSüÆÄ0õÙãͲƒ#$¶¬¿Ì}`BÈŒ->ã.<øjÎàj£/`·VƒÓ¯P|0„ "©ƒ«.wÆíuÐîNcá–$Ç¡ÏBÝ£„;Æsî1£Ã¸IªÅQ[—’ ½ ÿ°«•ÛD~~ u/7Žëyg*ÙdÚŽ5#âc š:šÄêTeȱ‰¶!Ç”\4ÚêXÅø†q_Û÷6B´qä æd™‚ïkÅ€sJ_²qèÚsG6O!6Û©°k°=~éÐÝrˆÅíÍÇbjsžsåîMøôù+ONêwè!­ñH³ùwTÆÓ7&1 6/yoæz€Æ-çeö¬C4á¹#À©%ȼ>f[„ÀÊí¤R¾2#l"ÚαiÙYkÜiQs &ƒu2K®kJêÉÆèðЬ‹tSó "±ê›WÎ8XéÄÉe׃5‘‡+;t†d¤p‡p¡Wü&£§`·JÊ«í1TýEbãIõ°5zÇ m‡™. Ífxø¨a.®Æ×”YW'³UF!n&šWÍÊ3c²Ë´?•kU¥©u°!ªÀ5fPWDøZ”tL#¾h,H˜x³¶­,Fmë#}Ê’ ¥ÒWÙ!êнW{{žvQKìT¨0S†“ªT(q+^JÜèáà±7J•ªìÔ pJÓ§E/B à”’‹M0e³rª®ŽG}Í©;­ f:Iå’)(ue)Œ@ 6W±d+œ)Ř]]K°}'EÑÜf(êÐr>Æ¥Æ4-n…÷°xXœÚWÇp“vÝÑø ]™"˜†A?(/¢Ô^ð=ãTVîУ¤ƒÿ«zѵÆ7O0-O£”*f¯G r“æSQTˆíÀíéÐ{gÅž¦j¬.®xðÚ( ¦ÏöfKi_Òå:|ŠßHµ*_”4&%• ¨K¶ ‘²9ê=ü,}šTíàÔ)d—Þ` ó]ÄôÕÁWU5æM¸ FÒ—Ú{šFX­ñ‚}åh ¦¶^S[Û°·›+CEÃ.qöp°|ãšÛ鯥Q½ˆtMªé ú)TØW;ˆ×W¯w<Ú¸6wD°Žkå§4ƶý×üáŽbcô\T'–ñK!D°!¤Ü¯jUý=mŒ \þ%¾HŽfÎßR× •;v,ðïôý5ðí(þ³šÅG[ƒGyÃÐ2pì šögMgS·ÈµƒÊpT@4XJž0Ï:äÁ;‡Ï"=zÅ‘JÂ5U2ć^íl2šNæDIƒToA¥:i߬!N[¤ë9`ïÌ:c嚪 j/“R ³:°1(-Knº«Écñ“\ùò8¸sìàï¥}sl‘ í§Ï‘ÂÃbgÀìGGµ¯ºö0µ¯Žn|1ÎÏ  Kê˜+«Q\ˆð s¼XLj R‡«ú-(Ç< ?œÈAvkõ>OÇ©¿]R6xøsS»å-373‰ô-Gtdãc ŒÜIÖ'¸ü˜m¢Ø¯aéPµPÃóŽ6uÁ^rc¨Ë!`i²™ƒWV çƸË÷ˆW- fµÖu2üì T£ Õè)5ÆS$æ1V¢Â¸ÃH³²ÃÊÉZÆW8lª&àÆQ(ø×e¶\šàäÈ›"û2+UM*Kxjú‹‚õÆœ ÚŠ>Eoy óÓò’’ä&øfÙÖèéú•æ¹zŠyšr¨Ú5’y ÞˆR‡ò F Ó òGg8 þÈdóve¤3²4 ¡²S?Œe'¤tt£d½£`•ö_ÍÜNÐ$Yì,°@Ú*á0ubLU4ŠI£ÖXÓÆ3ݽ§{¶›|êÖ*.¡5â·X ·gÛIG=v]’aq§il4*€×UÔPîê«ÀÇí)Û ½Ê%éMÑ–këœþ*³¦ÄÌQæRç"ùdò",Y©– •”b‡ì¤5¾ÀÛÓ:Þ¬ì€8«¬Tê» IN?äój[׎§Çl…×$â0qQ‡PCRÇd> â„Ö’ec^g-_L¼ˆºþ²NØh*Ðòò(®½Û 7Èi\µ¥PŒ¬á©t\M§Ã0+|‚*F®ÞÔä*~™ý¨~Xv¨TUl^ÃhƒþÅüç%ª[¦újîèȨ‹ ·–ú¢ñc½¬™zÂk‚—Õõ(7¶µ­mIËÝ]I;Áئ#\~l' ¾ ý9Ê.•û’-w*#œOEå2OŠkÖ•Xí•òŠZ„ïRÚ G`òç`¢BØ”]/~vÆÀ¸6Ý1IâÍë8ix)à•­Žƒ¯9†Ã°¹«FðNØÜÂ%LiAÂÔDǪœ‡ì1xíÝÃöܵŸŒ«æËSÞº*LX;àÅ®DÍœ5ÔFa{¡Æ¹è£JþR:¼QœN eøh–ÆDškGö»¹µªžÊ„Ð ÈrGz÷TSªôµÍˆ"IúI­’j§1WÈ×s“ §Lð^8(ÆÃ—*%î˜UL|-ŠGÔ‘í­THu±ÂïEökeÿæõåæifMî0a¾T%ãç4™b©’âlNœ‚¯s•¥´uMEÂÊäð-”±jhM:Çš½š¦§A’òiÞÜLAŽð‘€€ÌÛ #ów²Ž^*¬å­"SúœxdòåÀ†8É8lSq|kÄΊi„.wéT{3Bœª(­=ëÈÂUÈZ6nñ”ÕÙCÒ¤q*O³ iŽvGœÌmÎԣɓ`'Cðõ&ÒØ»(Vˆlu”è(‡"ÀJoO[—@Q(»Lň]œ#Þ@QWÀ&>ÕKQyX+ƒ4É/¹ÔY‡ >ñBiÇVp'mú:‘ÖÍÞ-\q,œ\@ÝÔ†„=5fhaÍ1Û/‹u„ƒM­-j4gÚP£œq­ÉD3@雦¦OPµAâQìòUÐ "œJEo|GI(¶K–ÏV¿L‘¢G ‰"×y§dJ¯4Ï•UÜg$Âc2"ûµ¥yº æµÝf,çÎÙX=Mà½e–ÇÌò‡&T$¿Ù‰h’d­DR Öj j¢8 ëì!­rƒ¹ô¶?§ ¶1ƒü¥‹©-ÑóX­J„ãÒû B¬ªý jL:äŒGªFWrÅE•ºœ«ŒuÉP ®´¨¤£ Â,k± 7b;¦‡œtˆ™]¨Y©")ý‰_ÁX$§S{ËÊÁ-™3֔ݗ`í Œ®\Àôe3ê^Þôȵp(`×–$ƒÉ4Uœî\ U/9éÕ)ÙJ‚&¡G¤êÌ„Œñ]fäîP’l‚§b|WùÊ6}ú8-¡&º&µbÒ¦\AŒûšªX\CŸ<¯¥‘c5²<*(W«WQ™X7FJ+s²‘Ë65Ç”Lžx†Zƒ?@°ËÏlÃEÆTÓE™§‘Ú¡uÈ”y;S¦ÀUH;[FÍ?àŒ9”Ѩ¨ Âox×F¨š8Bm5 R›T¥š=Zm<2pðšñº‰ÏÐÕ +Ekg2€ U¯öÑàe`”{ØRFN"ÂÄâ¦a0Ú™|ä[ë‹)$Ѐ»SxDS*ݳQCžöç`#¬ìiD’´®žj[‚×;£²åq«ÿ(ÆÊäÃ(r™uË„0.Õ 9[óÂ8ÞV{;\V™kPyeÁmkh»O=¤0©¾&YUTÖ³7:D&'èµ{ÑœJXIÔ¨¹VTëH8°ªe-Ú¡jT¯–°/P#ä’œ ;d:æú"Ì5ÒâèˆÅ÷bÓ¸§˜TÒ/#¨¢uqÙÞ|³ 9ë £5gƒ£ Õ¨œ¯êÚ)ŠwKpýi.Þ ÔáݺºÏNõ<É%tÝÎ<„ €ê í1LC(/+íó"-ÁªR7ÀÊÁTd›ÄZŒ¬ÃuGh‡ó k_ü²Zþuùkè`ÐÚ"ÖŽt*^92dM¸00eख़˺v¬Ù{9ÑÚì41ì^ *$Ù„D·6rò ‰Š§Ñ061FÈ{ŽDWwà50)±©#B L™èígbf½mŒbÀSù[œð‰ŽçÚW?Xt)åÊòÌ{4:Še©üשg1='G™Vä®ql,:ç…äÏ ]Lªàlz‹ZåNË—ãô<þfthׇŀm±a˜¸9½hüZ‚ÿÌîßçQLWõ¤Qð mF¤®Ljmœ’é,–*8Q^ÇV|Åʈ‚FàµìýÔU7 ¦JXNΦo[—, Ę%ËÖ8·»”~©â@·Å‚¬r”ÛŒçoŒ:‚ÃÂ*À–Žd^XŠ5šA³Z|ÓÐò«"l0;zn:Èú nÞ´ÉËǹê¡!²ËÂЪJKeuY ¼UZŠäxµ29αk»¤²QRàW7rgòì´ñU2vÀ|…ò´¹¯^Ÿ¾9Û•sU›‡ƒ_ت›jòÄ‘&cùTaán SǤùЏ SG€Ý£*Ÿ&¾©%¤··4%[°£\ˆN+‘A`®€#álAÉÃèUôT c<ººJ{)ð‘—yã]„Ì%å«:”—Ë›G2®C&q‡GéÈß!Í3S„#³€nYÄF-ôˆ–gi˶¡‹С$dÒ¸:ßñä52H×r0!E_Úî!aµ¨¹LÁ§«°k¶‹ïµéꮓ–wuàÙÝÙÖµŽh†e–š¿‹ì×I‘áàöëf;%#šÆ0ŠÄd5hõ¹ÑuklÖÚtëR«);åTWàQìHK½´¹pȤ"ØqH˜ì…¿WE<ʃþÙÊ8öDÈ·—qÄFà©:ØUTÆUåÍÌþºkeóК*óšÏj‰¸¢U†„¦d%Ê$*jäßÈ4rï•ôš“˜ÁÞC¡‚ƒ¾eÞk!wŸ4 FÕÚ%¿¥‹Ù³é̬ƒ´¸Â%=™¿vÏ:\‡Î0šÉxë8ÆmS&²ÔŠƒ!šøºÓüZô¶\s³U–à!16}Ü0­‰£åánÄdNtÎPbæÇsJf\K•B›iN»öz`ƒW=ÞÊei£31ÜΖàôjí\™7:´B˜l¹ÖæKä”Õ ›xßÙ•ê]¶æ<ž©°üpкl¾\¹ža´ w4-•ÊÀÎSÙL°£6ë?5R¨s˜šˆ1ôa:Sm¯Üs73…›Ú»¤ÇÇŠ %çÃ5Xõ>5" k~b“™ÜÓDDí:¤‘§í»NÎ4/.Œ;©˜Ðã„ãÖÁ|ÁoE “\vi>¬P#“¨Ž!P½ÜÀbÀE°ÕŒt P£+øþ{“#6°6ü¤k…B†òÞxç°EÉb·ôòîì7ÔL?”ý˜ß9C±N«ß8k:€ÃÔ‘ñ8@Û­²µ% €ÈÔs«ˆÈŽìwÍå UQ_äåÛótC|ë¦*¿?ý¢Ù¯º¿&QöžŒO{⬣3椪2t«Óý»ÿ³5Zü”û¦±KP3•#‚H|%Ü^í[›áîbúQJîÉ-* ÁP¢nÀÅÁœ¨ƒ¹qÍåZt(”•Å;½†Œ( ðãšaÖs‡9â5=dG­W.Û͉™V· ‡ÐD%J#xÜÖÄ1?Xl«Óû»à¬¸Ñ! ÂÕGlÍ{Rqƒy×9TÖæF›79È‡ÙØ#"š1ki"ÍzÜÁÚþã¨9ç _\Ž7ärµ–†Pª¹ÃOÛšPž¶ 4Ĥ_Õƒ‰Œ Eï(ÈP3¸4ñi· t’ׯììhôài˜è$ 4—¬Õ?¾ÊQsÉ>yX(íN’"¢ba”¢Ø¡Ù+JXõp5Ù iÁÊfE+úË*ÎörÄѸFWEn„jsÑ®g!éáhr€öݪØ.׆ ëì½ûêCgÕû´«g”O¦X&c²ºQWYÀƒ –Ua:å•LʭƱÎVñjS”„y´C·[ƒ…¹1‘iÛr£-Mž¾Þ.[²¼ Y‹œ˜“½UcS ¾ÎŸ…1Ë[[ãý~í«¥·¥¨áÙlÜÅMÀk0#¨µÏ鋽Ž6ÄešAŽãñ )e21ˆ-8äo&&*Óó^‡‰Z:C7ÝŠæ·Ti¾T¥eÜÄ(I^vn·(ä¥ \¹)ËHíÊÕÃè;Aª‘¦©çWuKc¡BõM:¥„52 §äu¥àkáF©.¦DC„Q§]”©B:0Q2J½¼­0Õ¬$øB°1Ið™êA¥ízªMth~å œ1‹se4Qz»Å!ˆ—§Ó¹II@DîˆÃúÆsBzD^yy¸>Ú×èC7WÝ~¡á^ÒB 6ó÷FG2 âˆÂs‡†ý‚Qƒ:wEZ6¸lÔ ¢èœïÞkúÏKDwb¿–À7–Hä m¡Ž u„Ô!DܶѢëWÚæ¿F]Êô[©ãK©pZ £"CŽØ­ÁñPªô ¹;” Ý3Ү̎!è]¡¤Ñ;þ\"Æmâ oyy7Á"y(å=ºÞ³MÕ\ë¯XLJ¢†:7t’ù!eº‡<Mä·AîV³”~SˆYå E ªjý ɦ“è‰uçV«•Ûu1N4.äŸJn†÷´`5™â’.1ºŽÅÈ!ëáiŠqu°²²‡ÜšV§‘åª2Ï0ÚNû½ÑdO^bÁk¥òÍí„A§tnÄãOþàÖ—uÌr2 ÊÐÇÍ8j‰’Yì)•Ð’fþñ-³Cßõ@£g"-ÕÆ>ª X'h£Æ_ó³šÚ_Ç ¥›£Òx—Ú¾ä]‚”<ñ j^Õˆwͬð°3: pg ‘!£(bâóœkè<ûñ©ÑÍUÔÁÚüXÄ`BÉk›VhW94Ø ¨¢g•¡ë‰7áP³Àyƒ¢RUði9Ò“Ù€¦R?oò¡ 5èXJ]ÓHò¡ô8#4ÇIØ„,¦g«¦ãã±i£ËÆ¡E\¥_±»I¶Á§¢ÅØ¡ÈÊ.ßT®*¾wXŒA32Üh,êbpã` å N¯VòE‹®â6’ØŽ’ 'µMÔw’éÖ¡±1.‹ Úˆšg® (ºò™RæÈøªlÇ™‘Œ:„[³G1»G‡²÷Q‹ç‰¹E[Ófqª‘džtª³R¤Æ ººŒº;ú¢¿Æša• _ÛìúqHShÈãH£&Èi&Wd°UEI…H#^VZ85&2øÃ™iR°Ô' š*´ ÒQê’À¨¨­Í4íƒUO+ø&Åc²#Ø,èUm1;#ô6*±66Í ·u¹* ¶¡„ªÈ}°R¶hbçÅ(¹ðL–¸~~GlkúFàR!ò’žTBŽÁ r1Mát¥;vÙDû¨:«Ç… ]rÆŽ ¬+ØGÆùêj×툽3=G‘Ù+4­Í΂âo.ç†$÷N&¸}‘* 4 ;Õ w¹e¯^ûæcž²ª|#]?6¶Ú÷¦ŽfÁøl<âPÌ·©ºÛÅ%=¡”2¢VÅTzƒ1:4 >=º?2õy{»‡1ÂÒNŠ{æýi”nguG`-¼Ù d\†Í!FÉ8Ò‰nÃÁ™]݉˜(-laxtpS:Ûµ|»Õ{ú×Óϸêä½®Ø=yÅ•'Ž^uÝÁ»óŽ}úY'N<õŒ³¼;¸{åÞ#®¼æÄe¯¾üè#ŽÜ»ò²cßwðn«_}ÿê?«ÿá]Wÿ‡ëÏ;zò䱫NÜǯ8qì>W^uþ#®:zݱ«¦ßÛÅiìKî}â²ó¯Û{È•Çõß{è'´åÔs¯xèå'žòèUßwÀÖ‡n’ÜÙ~×4·­«óÔCT%ŸcoßwðôóO^uʼn‡<õðá3vw¯Ùûá+O¥ßN+Î<ã«WÿÃVÇb?xæê¿ÜÊv;øHº*ó–0?ÿ½esm3›5× «JLÙ q—çeßš+j=Õ/Fq4ÀÔÌ»C@Á„ŒÊ·ª&=ùìnçߎyM£n>ƒÝ‡bŸØáËWOðÔž8qtïØezÕÑË®8¶Ú¼û¾é”ÿæŸ?ô‰Ñ¬,}þ×Cø¾S½Q{Þ;ðÕÒ=|øÀ>{Ð…ÿmP×ðn´z«ÿ¢×÷Pþ÷iÁ“ÛþH l|¨#›Ær$Ü1S]s‡Wä5*¤—JÙË}P£PGϨžƒÂ·l”dû]ã ›ò”$­ÎÐýÍ„X©±Wõç!¹G˜'ª“厊JM–³–FT¿tÓ+¤FaÔ¥ÔRÙÞU‡ªHPÛø¦cMZY‰2|Ö­ÉÚÈÐÙ1r2ÞØ[Ô"“ãPE6Ú“ØÔ)›SŒµrÞZ„E‘Æn#´jYÈÖç'¡·Ì6󠻀s(Z¿ÃyÓ‰šÞ‹Îp›ê5„ªÑ(Ÿ™ˆQr"£ÌC(¿™Gàzñ€ØPî®ê–âäÃ{RKðÀÞ°‰RŒ”‘¥9E‡óŸÒ°M9¸!Œb‘ŒÅnUe‡V7‚lÕð­DXb›†(j4gÅ~ cÖÀ+IcOp¡{Ä…$™f)Ò¢›\´;+‚“Cd!sêJ!U¨™Ø+kPQgZ_q†ÂøÂÈ,»ê5H£×€Fº$iä²-ñÓH³{ôI"ú}MßU;ˆTxÊÉ NÓ+%àµdäÛà ¥š*Èÿ"uF >Q0 ÷z&Ùb9`í0älF ˜sVüærÂc•iU€ÿˆdÃA‚"JÝ:ëV5tÐ7GÕ1M#T‘~¢âI_¡XÑ{Õ!ªéƒ(Ò‚Ø?&ÊR vŠÁN{'~[­÷âœáUŒ–Œ9B8œDá£ÈгWštˆTŒl,ñ¶M ÞÔ¦µOÔt7ýTÓÔ ZZ ¯ªÝNÖ×ýÙü5[1®Ÿî¢o½ Á^¬Ý³ÐšÉìLTD¼y} ”Öô!­ü ÖJQ1IM»C(° Mqš 9ý­ Ñéн6úgïà YÝìÏÚåT÷ ºšôÆ:æ¶ïÃÜç×ó¸F!<ßÅH±Ó=t γ!öÕ´[*hpãxLÑßtÖ(Äeš7ŒnKŠBªº®•` €(‹|#éI·)i#té½(Vr#Û‚Nß‚åÄH‹¶¦Ež”Rõ¸V«3ý¢HìQ;ËîŠù?Fí˜å3<ë$®Us€;º%DÅ0b“9Õ¤Ô1ÜÆÂä_·¸ök%VÖq¡ ô”raq„ÚÒƒåN(NxTÞ©Õ®Ž6yÞ B®#g=ûiŠ:|11ëq$^Ò–{.š?œ'Xæ{ƓȒÚ|nE„¤—¿V%öåû(z2n¼=Ú¢íÁ%øsÙ·µUA¢Û²„ ÈµXodùâ&FÇ¥-k¸i&v±â›"•ߥN¶~I]Cì‹ï®àúJÔæÇLb=±¯}ù]I=æ=‚²^µ…Í…åÄK]î?äÖ²XÒ¼SÞ¼¸-ûÚ~¿žÇ Ûîbì®, l/îP•­ªi?íÚ]ùÔÖ÷xº`(myúŽ‘àóÉÁ•½ãœæ½ß§’‡ 14¹ÇùE@ý·œvtAWËòl4ìý|Šîÿ8é×iý×Ëq§»([Nþµ{Žøõ–Ùm< äOƒÄÚ‡a‚ÆјFc­h\Ô_±r©<Þj¤²f<:6¦`0üÒŠbxXk ‹«+ÏÒÂ4ã€4̰٣Р÷miöIjÎ/ìC…‘ Û5c’91X5™žä°ˆ˜ìd¤R”T E×LZŠ’Š®Çd³rÍKS™bž>m1¬É“éÈçÀ 'O¦Ô¸4ØÉ‹‘Ú¶5óže ‘ù3й$Ç/ÝJÊDäV&ƒÜ›žúÒ!!!z×…òkR§·æèÐorkK·ˆFsð¬à@QZG)G–îVçÒžç,€ppe/uxqPFO4Ï ÚDž¿³Uªj&˜ƒˆÆ`jDÏV'8 ?$Å®¹áö æÝ5ßµÏéxºôÚE&wò‰™ 1ùMšV޹ìð·i ÿéä™3M^®›~|Ÿ3&q&ìà g¦â”lP¡&Âí%¡]Ë–~jD6xÖµoºûg”l’"›,Ì>F­X‹‰Ð‡ìáæWì~gé¬~Ñ6£2´m?ìÃ!®Hu0G´‡ $Ó–ØmGšE‘$jÔø°…œz‡ÄÈZ|Š:Á5E³hG1•)îż” ´eS”¬sŽ..cjÔ©CôQô8E꨹!R§Q=ÔºF,‰ÿq£iÄ-”á5¶( ¿–(äÚ/òikÊ`}ì"” s8 ì:_´H:wyß3¿Ð<É<ÊeÇãÈ"Õ6?º,©ÄéÑécÎãp/$‰Ù½|}I¼¦1^v2ÚiY$ƒÄED>HóJFú"Jéä´2)ŸãR_®còš&bû±ê œìràO_Q˜f?/dýöˆ+Ô ú‰>Íñ53â<ΫX?}–‰Å&Î7?“Äê6C0êf2Ì•¨ä*½,{Éf°íRwF® Kóà‘v–µ;.{â¶]êþL~{^ìÏ=ïÂ×¶Ø÷™g?¬”ÛžPr¦h‡SIÖqújÀg;îäcnýádðÙX4уÏ ¦/A?Ôå‘˺ ÓÖV¥ªM@çËø2,Š IuT˜Ì›ÈMÏCx½ ¤èÁ¯:ïUÐj;xˆž2ùöd;ýká*#ðbˆhLÃûLÄ, þ5¬5IxذfÀ°ŽjŸPkG°£¸µ‹ª²ï-Œ(Ö> ~²ÃÔäb­)#§U㌅ÿUM9Ž^º2 ¡†KêÙh&" ‹G4ªAÉÂ]“-gæ'éÁÑm†jÍÆê>ÌZ–gí}B`Šð‚+ØÌeö*úp×T¦]ã|Ìi·þëÕ¸qc\•ãÙ¼ èp,îyËì²àÆ6Ÿ=9¿ùä¶>ch-ë9bC¬u QBdY‰A²Àö! Ó/š|ae”ɇ‘m’`íJ”Ï>LÑGŠ•¼ïc6‡§¦ñ™kDÃ6c½SGªjMÕBÝ.óF'§þYÀ–áÌQú¡„™gyåPhDØG̪˜¢Â\ìP‚j€m“^ ¬Æ‚GÒXSÔlÀ3f!*cžýsˆÆGU†e¿V"IñÏ“*¥1ÓˆUhý3%•ºÔö1®,€`XmÆC ~v*[1ê…j] ^AÁù&“‡*9£¦×£WÜ‚{D¯ø.”ÈNÃWÜÔ§?ßòË}Æ”ð™ÜÁÐT³`w¨{oa9™Y±Hbªöüü‚Ý…é@!8Èë¡Dn¤Bï9”(¯?˜ÚÛ€©nŒ«¤x[îBÜþuâ½·”ÐÐXíÆZÙˆÁNxéHàee±97“ÿ;›‡$Ø(ñ™ï#‚aý®£œË9R@º´µ§ðõƳC°{ñ¤£Iñ.Æ…q±qr_¼oç+‘üu„¸ÿbÕ…i\[ŸH'¬­å`j³Óo÷u¾‡ék B²üöŒ-sþJ à™ñxæoÚƒÕ•î!L Ä€½¢A :èq¢Q”dö=lCœlsP¶”5R~ëÛ›%çÍpJÛæ¤‡´Üd-M9íÈ#9mÝ#÷¹¶ÑDét,Œ”êt€ŒìÚq3ÒµÓá4òºÓ16²Àk‡ ’¶l'$.kÓ#ºòlrõˆ“×ÏÚ•µ›†ÈRè°°Y8Ý3Ì“1Æ 4‰ý =…y„}ça¹ïåõ4K>ÙH#§¾f# üd#\ýd#Ìþš4p“4“4ðkVë@#L6îÀ-LÖð9¬ÙÎ1YÚ<1Ùäj±4à.c²ö‚c¸î±æC pÈä: Éð±ädÍ!•É}P–ÉÑÀ—5·pÀd&'rj&wsÀoÖœÓÖ™\Ù뙜ÞZs‘dhr¨¸hr½iÍQÀ¥É­§áÿ8ÔZ°``§Fda€¬¦Ä€d­…+€k n ¨×À°µ É€‘M!–7³PÌÀ¦­…m&$ÛòL˜·šrËàÑ„§¡¦ y7‚R†Ò[°&DßvMØ¿›‚ Žî Vh7mTâu«CŸݰ¥¶!‘­°C®«qAŽ9îm\x Ïèñë­Èǩڒ'Ú,9Õ¦1ˆû;^­r&sØG{¬ Fb–±ùÁ?]ªãÁ‚ç.Ivss‚»cökãOÂñÓ­+#—‚]@BíÌåXma T³ù=/Ì¢K(+­1Cµ…Y4|½Ýt]ýè©ÇÏ$t9‘#‹éké1J»f.RWnÄüÕ®îO)(ìCÙMÌ0È” ð€A`$‡LÀ;‡¤ÙÍäóÂðZ’k69K8ulHt­åYCÐjÞ„nÂgÓåÑ[®š5±îµyÌ“$ ³¢wÂöȘdsIçc6{4z”"‰XlQkÿrm~a²yƒÒÆ5“mÝ«Š+K{V/¸‹©÷"š=Ö»‰Ì³ŒÂ ­im#_!·Êj±ÍäIöd«¡W*Sÿj#SVMƱx+]ùSa§¾6ǚǟÀ¼‰tPXÓznÓ˜§HÁ× ¹¦ÝݳàÖétpC”‘A Þ ½Bµ@¹•ÞfOfå )@ª$³Š7ƒ0±"t `œàÀs¥ãIã«VJ¨­™gI ž_”˜†Jx†€团CQŒòÚHKš²2 uALŽk‹Š=ŽÉÀÇš?éì•ëðå0ƒ¨Ua¦7S“«ÙŽ®&éÀ­Ó˜çÈî¹m(‚4„Ћz35Ãùd2pnSø׸®÷—fSµNP™š ¨4„kªpÕ„Ð[0ŒUë§k! 2¨¢* È ]×g1ͼ‘ôAÚF¥5³ò(ª®Í ]0_†ì›ðÆ„e @kB“0€«ŠÕ¬adóŒ‘qìsê‹ ²¯dy1‹y†KôëP¦àpµMõ˨º¨õH¥ôèÅ2#pÃC¤€Zraeü$JÔSÂûkbüDÁ@fÞèÛ6¦1Oîõ)VÝå¶K m6o°Êwµ˜Íô‰iƒMlã!Qáiªk´ª²endstream endobj 1053 0 obj << /Length 53114 >> stream xøëÓ˜§¸„®Éžu Œ¶-)ª%ÄÛ_“šÚÍ¥Ú4³XØ+-ëmT†Ÿ`°]üÍå¢ìJE½X¾ó˜&ÉI›fßúà“‘´OÅÎFæ(­í!LÎÖvœ §*‹bu‚ÛØŽpdЖ˜Ã:2OÍö fÜæËYÌS¤šõ¢{;‹ýîY(Wp@0R«wlâ­j£jJõ¶8ý)åY½½ôhC`w-qŠãÔXÞ@tôõ}âwÞ˜Æ9â<î°6èI[„ú5%ñΗ+sW¼ZÇIïµÝ„o²Øº[§±œ£Òs5­7s,ÚóÓÝðª4ûx¢Þ"%áú¼¸5²NÞ¢!å'(2©Ž.vŸMà²æÚù&lûªM娦{mË9ÆÜ5ÈäácŽÁ'½s×0E—šê „ȑהæZ¹F—ã–b ÎÐÝNhyç!¾2:óM(É*';“=çå4–&Ø.½@q†I±:ûU…¢Â°#+!j¢8Ô óœ óÜÓ4IÖ¹”´²òø®a©Í¦€:ãòºäpÇ{ÖF&B¬†ÿ^Nd«yˆäù0{+†ÀÖB¸&æ‹&ÏC±Y ¸/ßCEV”‡0 ³ /:¥ð£Ùv«¢Àç2^’=š‚Ý¢÷6„× ø~c"[]`%†/qÆJ´G$% ƒæIÙÎw jž¤Ždˆœ0ü*¥Ï&ÀFèÿ!R¹9€A&\3u ÌÇæ<–žwl]á@9M~·ž 4R"2vö»Â’­cc,+Ú‰S#4…ržÐN(ï#Â}!Pä8£ZãxFQ¨–ìÎõúH ¬ObžÊIÏÕ†ÒG{ ÜêWí÷ Rr.älk&ïa|¬W™IypR2@ Ž÷E¼nÇÇ.‘´iàn™#Ò ˆXŸ¥`Ü*†2ŒÛ4ÜþÐ9ÄÔùðT¡cç™gpɵ„Û® Ž §Â`ôP]Ý¡º |·ß-^u2Âî*Îk ÁíâC\.>ºA ÿóR'$P"vBÐÜYc¨šz*R*+mNæûÒºt}˺‚7ç±™¦¶$ °b#‰âJ2d™¦ƒVœ–‘wÈP¯k¬'õw°B4BÌIöƒ#ú)Æöµ-À+!¨mX!Á ˆkY‚ì›kÀ-rj/tàþ†FÆz½&hÞF€Þ`^űD-_æ9 Û1r0‚,&7FX›Æ6ÂW`BÍ .ÄxÃŽçnD\²;=F0Ä¡Ô'°aî¡)ò*ØïóºÛ°É^–©R†´2®Íbs2Hü¡1Ñ­Æ,{3cû¸OA†% ›áëU‡ðÒbÅ…³Ç°&¸j³ mu‚QÌî"Öb®Dkó˜×íÀ–©g;&éõºiq3ŠYK„|F›¨»síïp¸Å®›žu 6 Ùjóµ£Yä¥*ú Ÿ{sÓ$'ðß=™‘‚‹˜1…µX;à4ç£Ò¸"Rq”ޏ _jÔW’M¼æL/iPк3™q óô0õÿµzÏ»êʽc'/?vÍÕ †^pôú›HÈKj¥Z†Wo‡4DúZoPôJVÔÐýj%f‘ÎIRópíÑ fÐ{#ÆÕV²¨³!œ¥Q$Ì=)Úà°`æ[õ kÎ1'Qn·Fæ¹Î"Ðê'Ná%6|¤™™–8Æ¥‚îµ%©Y¯"¤#÷à 7sÃH]…3Ø¢i\ÇYêJPås9ÂIÏSÀÏ«§&ä7,†Ú$ÖABÆÊuM@Ïæ®ÊÎö ðkeô!iId¬¶Ûè–w`ÔA2@¡$2%ÁIü9TDgYÿ}Õ' À Ü—¤(VrUº{õÛ"AÀ­ðó¢ä;W^Ro®ëÝÊÆ\¼ÃÞÄ );Ê ãºÜ‚–ÒÑËÍAÅg‘B“–*R0¦¢jƒ_n¶iU‚¾Uñc¤¨%PR¾Êo†8ƪü}Sc’•{XõDWÆHÑÆnJ뚎§RbGX>-:…´‚’BŽ V¢±`E”åû®ŠŠ–ìON• ¡Oä+ãZ–Þ«oâ „²ybÏ‹[*!‹Ñ%¯Å9«…(Œ›–7°úækôS•i‘’ràù)-[t¦CÈßÃUmÒ«‡z-nVï!š"eUƒU|”Èî!%cJ<d€]Twù­—$Ð!Áî$A8ÕÓ&ê;b.û4èïSh"d!E 0X°‘ÅI‡#lBÝ\‘Q#ÓðgÊ^+QÓ`S#ïor}k›«8(sG%!_XeŸU'E®¯Ä®MªªL£&Të±gHB¥ÌÙ®ryCQ S´h¼vôø9GO^uÅ£ØH=rÆYgêðãW^µ']jž®lØË®|ȱKÎ8«_²ºóO^wüØ%㲓KÆç…—­=ÄðeW?vwü ÛØ?|ôê•¥¾jZ]j5—3Åè¿×±k¯Ø=¶zB׼܋I÷‚pPöÙÏæ£.¼®õçž|Ö 7<û‘¼óWþZi÷‰/ü…—<몳o÷¿ÔíwN>ç^qÃSŽÕ¯ø¥N9íAá+^öüGßK£?ìé/yù‹Ÿò°#_ùGx»s®yîK_úÜkÏýî¯ø¥N9õÂÇ<ÿç_øÄÝå+©ÕëzÜϼè¹×Þûf¸Ô)§?ø±Ï{Á3N|ÿWô"j8ºø'¯Þ“¯øÊ.ø¯þjþ¯;?ðš§>ë§/K_Ñk}í×òÝö̇?î)9¿¢×úµeÒƒù¸G]ò%®õÿ•zà_Ïÿ}êyäÕÎ_Ék}ãínÿ­ü?nsÏí¸äŒ[ïû˯þ²Mâ[ßñ{ÕH;õìK/¿ô¾ß³ï/¿æËµˆ¿õNþn:•[¶ó/yð9‡öýéWý—y±;¤»ûÛêÿ¾ý=pñù÷øïûþöë¾ñ˺حÃg$ÛØï|æ“ö5پ替óûÖþÈY÷ ¶nÕÎûÑ‹ÎÜ÷ý†oùºÿú¥Â½Ï9猻}›5ÜéÌ‹/½èÈöûý×~Û·ÿWgv›xæyçÿPŸ†¾õ÷_pÙC/>|p¿¿ø–[ßê›ÿk—J÷=ÿ‚óŽúö©í.ç{Ä•—Þw¿óòëou‡;Üú[þ+—:ëž¿X ·9ük{ÝÃιÓ>ôÍw¸ëÝîôŸvšV—zàE¼o\Û'ÜÅzÚ³ž|õ÷[ ·=ýîßÚ­þ+—:+Ýf­ý;ϽæÙ/ùùçÿÔŧoÿ»o;ýðÙ÷Îÿ)óçVñ¾Øv©SNùÁG<ïW^ÿÚ—=íŠ{niw¾Ïݯÿ'.v wŸ}.uJ¸üù¯{×»ßñÚ\{Á]·ýéϺäòËзüå>ÿ|ÏáûÓ¥n»¥ë».}Þ›ÞûñoyÙOÿȶòÝg;yÍ÷¿Éëmï~¿‹.8;o¿·û]ÿýÙ?|ì#þÎ_|Ìý·x}·¹÷Ãó„G»×MœØ-ÓÎEžS¶ÍjõÏÙÏ|Ûÿí³ŸþØ_¼ý†Gô-ý?xüI×?õšÜD‡ðÔûþèƒøûíçg=ëó™oüì?¾ï5O~Àwlö¹êY?÷¼Ç]rÓŒ ÛÞó¢ÝKwöÝaϾþ]ùü7Þø‰¼åyG7_Ëw>ð§^ð 7<õagÜâ¦\ë´\±wé½öy‚§œòCÏùÿð…Õµ>õ׿õ‚ÝÍ“Óí>õ¥¯ü…gî¾)׺ý}/ä5GÛ¾ýç<ÿwÿé‹|­·?÷âƒÝýÄséU/æû0ýüè'=öK8tçýÜ{>¾ºÔÿþ7=å¾›Ý÷¾î†WýÚËž¶{S ÉÛï\ýŒç?ýÄÝ÷ýÁE/{ÿ¿ÑµþùþÏë6õ½zê+^óêŸÂÅ7å;ôà'¾øå?÷¨Ãûõßåäk>ð©Õ¥>÷÷ï~Ñî÷ntßã'~öU¯{Õ ¹³e…nü“þÜ_}ý+Ÿzî~ý‡Ÿò¶¿ý=¿|ã6¤Sôä—¿öu¿øÌË÷}³Åz÷“/yÓ;~ó¥W†}~ûÀ~ÿc«¥ñù¾ç®Øø.ÞïºþÚ^ý¢Ÿ:ÿà>þU_=ýË=ýÊw½÷÷ßøÜK·G1]ýê?ÿ÷Õ´>ùÁ7?õ¬Þïß{ö/¿á ¯¼þaû®BõDäŸ3ûê÷|àïyÍ7G¢vžõNz„_üøüâñ}þ®—>å¯ãkVÓÚ7<öõ³¥uø ¯ÿ£|ôC¿÷KWo[µw;ñÊ÷ÿËjZŸýðÛŸ¾q3§^øø—¾þÍ¿ñÊ/ñq}íÙÐ:òÄßøóò_?øÛ7Fûîçþæ7öÖ§¼ûœ×ÿîûß÷?^ýÔá¯ZwÉnñ]ß5Mì{ŽÞðî 3ãÓùŸ¿ôËWvÖÓßò!Ú3nüÜß½ù±ËyÝáO|Õ»ÿìüŽ—¼ÇhÝpÿnyÇ;ÍÝ}žòæ¿â?ù¡w¾àèü•Ýåø+ÞûO4­¿ð¿óœå¾[®|É;þìo?üÇo~Þôa~õ†t«Sï6ŸÁ«eý>zÿ7~ñ_þüן4/ìûâ.n¼ñ_ßÿŠ-§üÄ׿ÿ#ûÈû_÷¸#£qñáò?·¾[¸ó·Nÿ~Þsßñ·Ÿá'õïùÅÃæ¼Óå/ýý~^®õé¿~Ëãgcã{òsïúпþû?¬¾ðiƒÿº é–w«aþ ¾ÿ'_û§|jÜø©¾íú‹m/ÿÁǾá/>!—Zíïÿ¥Ÿ˜ö×ÕŠúÃ~æ³}Ï‹/šFúÆ éÀ]àžq2±¾÷Ø‹ßý‘ÏòkùØû~õ:‹@Ýï¹ïú»ÏêµnüÌßýÎÏ+ç{ßÿÛ¿ø±÷Üð€iZß>?.}÷8ûÌ<Ù÷~üëÿô_dbýö眧­w~ø/òw¬ÿ|òƒïºá„íE÷zò›?¸úðþå_rÁç›n÷߬_ë»Ï8ÿ‚6Lð;]ú‚wý ¿±/|ü}¿|â.öÿòßíR7~ñßþê]/»öl]t÷yúÛþf5çOüé+/ã~ÃwÜé»çm‚þùÎ3~äè%÷ocᇫå}ÿ‚¼±·À¨8çY¿õáÏŽkÝø…O|è÷~åI–µsæ3ßñwŸ£%ó¦yÉÜÞå»®ùG·¼û…—ß=gZ@;+Û–W÷>úž—^Îfûw?D¿ñ1³OþÝ{_wý._ì¾ÏzçGV×úÂ?½çe»áwÔ#g„5cû´<üäUGï;CÇ_ñž¤“þÆOüÅëËA8ñ²÷|ô 7.þùôßÿÑŸw™ÓkÑ|ê¯ÞúôsÆûsÏÿ¡ºôîxîî{ÌÉ£÷ëãÌ'­v{î³ûÎç°íQñòkÝø™þñ›žóÕqpÖõï¤g¸zÁôk×›×=xéƒïß®émŽ{ô“~úä…ÃÆ¸óC~î·ùƒþâÇßû²‡Ò'æ®xÉ»ÿþsk׺ñ³ýã_æÝñ”³Ÿõ[lñÜø™¿ÿ½—íÁ–ÿoýÂ+N»ÿi‹‰¥?ú©Ï|•S<<]óª÷ÿ3­ðOü髯¥ö?öÜ·}èSë׺ñ3ÿðÞW=æ>+GémþŒ~&ï|áØ—O¿àÄ£®}èY‹£ó.<ù´ç^ÿøËï5ží=óíüןúÀo<öžÔpø1¿öþ­?ÄUÿ‡Þõ¢«Î;úLl•_¤Sö2ÝÙî|Þ‰Çþô£Žž÷ÛÛyü‰ÏûÙg]÷£Îšîú¿úÇÿJïÿƒo~"o§wÚ}Áo}ðß7®µÚ[^óÔKÎû©WÿÉ¿jÃ?ÿÙo^ÿà;é¸üÓŸ|Í4,½{Ìs^ø³O9~ÖH²žóœß¦eü™¿~Ë“Åæ¼ç£~ù÷?òé‹}â/ßôôsO¹ðç~_Äçþé^ûÓzÊ–ÝÇ]ÿì'îÝw^‹·ÿ¡ŸxÆ _ôœŸ¼x˜§_óÚ¿ü$]ë­O‘k}ÏEO{ýû?úÙõk}êCoyÆY§~âoâ¼¹ñ3ùŸ/ß“§xèâÇ<çgŸý“-¬ûtéãŸÿ¢<ùŠÉ¸àÅÿ÷Çy^z­SN»ôú7þÉÇÖ/öé¿ígžr×ã+ó»å'ÿŸ·^ÿcl ÜþÜkŸý¢<å¡ 'ã;Ϲú/¼áúkÎñÞÏxÇêû\½¯'ÝK[N»ìùoþÓ­-üÏ|ø­O»Ï)§œûì·Ëºúçóÿô‡¿úh^P§üà‰g½ø%ϹæÜE<^úøŸyÑó÷cã!zä?ô™ÿ_öÞ;Ê«*Mþýugîw?ׄ^=s;Ø]=ÝÚtO'u™ P‡ ˆ²¨$CQÂEP1‘d©¨€€¥ bãRAÁ,.IJ € ˆ„¥ ¡¾ý¼aŸó …hßžoÍé™îbÿÎÙgŸß½ßç}žïÖ?}ÍšäÕM{‹_¶÷Óç®7»š“®xD{¦]LÓPØoâœ{g\]¼E:þ¼ú›fN¿±_nê¬}týw‡ö|¸ht–æô½cñ‡;ЦÅïÖ?1ÖTÑ¿]rÇ«›µ¶¾ußÑ­.½~ÖÜY7\Vl …µ×Þ>cêˆó²SßÇ>ùîàÎ5Ì8~ßÛôMþe{>X07#ûЉoÖ<2šÌÄßt;ýÞÙêŠ ²ßvj˜:ó¶«/±•èŽ{þ‹ï~³òîü²næª/®Û•­™;WÝÕƒ~é<ýMÛ;vøø8n°3êo½kÖ„º’#ˆ¨ïÄ;gM`­ˆÎw¼¹íà¡ïÎ:¿è¶ ÿŒe¾ÍÞµã¥l‹7êïù艫¸•O|Ó¬××–lç~×ëú9÷M·»W·aáG{ÕÌËÝx÷›_fµøõÛwÈ&´ïãŸ}o¿kÑX¶I““¦ßvÍ¥Nq…sÆÏ}tþd5NzÌ|3Á7ïÞYºKˆ‡?´vwþ»ä†þÙ»v®Y0’+(îãmSÇ\Pºs<熇—vü³tfþ~ã‹“yö=þ¼&_USzÖ~Òóëv|÷íŽÍë?X»nã™pl~é†SKm¹~õƒ'¯j‹}öšZ±ß}òÔ8þ”V]9yò••t ³¹z÷+ ü{¿ývo6íZûHC~ÿû—vOznCnm9ðõÚgï{ûS«·Ù‡v¯}` ›Si¿ënž<ª{ÉN󜉋7”¯ñØô½=$÷ß?ŸzÖy=GNžksþŽ;?]ùúŠ ;²ò}³b6ïã;7ÜtÛ䊻>«Â߈åèG&Ô^Ð¥ë…C¯žtÛÝ —­úb÷¡¢;íÛõõ®½¹´¯ßš.ã»ÆL|“RüY¦µ*˜.tíýjí²GæÎ™3÷‘g–¾±jݦoöU¾/»¶/¿Ç÷Ão¹kÖÄ~aég­ØVñ³P»6¯[³jÕê6lújçwe†[ùe¾‹Æ÷.º~μ»n¬)vœ3¡rkÉuà»Ý;wîþvßþCMß“»L{ÑôsÆÈ™ ½çÚî¿É¿êÏæ¾Óägýeö+—"×Ú›~öÉ{¯,>kwóŸ|{ä<š{íýüÙñfœœ{ÝCK_]ìàöó†eû¯kï|uãOöaßnX|ËE™A_}Õc«·ÿˆ XѵË[óFŸkÏSN¸dÚ’õ?UW<¸í½E/ÎN¥Ü!÷¾¾ñ0ÆÍ±\ßo]¹hJm’þ¶¹êáw¿üI^vp׆׿¿ÐÍÞõ‡^“_ùS¼ìÀ®Ïß^tˀ꼙ݪ÷”ÇßÝ´çGîù‡ön_ÿæc· *µ¬™òèòÏvý¨½ñûo6®^:BŸSKŠ­z]sÿËoÿñÆÙ÷»6­}uáWôlU(»Nh?bÖó«7íþQ>íྛ?xýñÙW_vf剠ïͽññÖ=Çú¶Cû÷lÿüýמ˜uuß6Mz[_|ÍÝϾýɶoåmÌFxÝŠeÝyMŸv‡Ã9ŸÐ®ßõsŸ{gÝ–{ÈëØ·Çì¸W¾üÔýSÇÔV QÝâìç>óæÚ϶îܳ÷ûý6o:øýÞ=;·oùü㕯>5oÚøçÚ-ý{û˯ýØ’7Þûè“Ï7nÞòÕ×ßìùîûýªøÖC‡îß÷­yË>zï­W—<~ÿ­W è|z³#Z´ë3fÒŒy ŸYüâK¯¾ñŽÙQâÛ¶m/¿¶mÛºeÓg¯~ëÕŸ]4Ö­Æ^Þé´£ +9á䳺^>êš&N¹ù¶;ç-zîÅ—_}íõ7Þx³ôzã×_{yésß?ã–I×нC›“›SuåïKÎhsÖÙçœ×}ÐØ&O½åÖi·U¸¦ÝzËÔI×îß­ÃYÕ'ý!-Nªn×¾ý9çVºÎ9§ýÙmÏŒÿ $³âIÛîƒhR„Íž­ñ±&ÍFǶ«‚koÏhŸVµùþÏè*åÑâ z×’ÝX’œáõ|“£9´ÜP7¼^ƒwmrõÀþC‡öÜ·$¹Mÿ5— Ô»O¦\Zòj'Fhñá™qˆ;§6®H¬ÓR˜ìˆÄGÈv˜{ÂâY¼ì96*=lGÄ/‚¨yP©( ‚Ï!ôQÄ\L ´²æ©Pˆ0¢@U Àggl~ 0«É»lè­DÚ ¤=±#*ŽÄéËÏû­’ B±8`ÒŒLÊK¤ Âà$ªlù,«5þŠ¥UŠ˜Ÿ‚>ËÉH~ŠITÝ,`–>¢AP>¢þ#JP.$žñ{–&låã.VìÅÂG&üY@‘Ä©%Py‹8“±Š•+Í@CÙÞ$r8_IXÜ.rÀ3—²_ ïƒ>‘5HP,aZQÒ®’ Bˆ?DIñ'„¾ÌQÈÔçÙbÌ ²âç=KV}âòÉšö»¢€M ¾¤TµR‡¤ Ô:Ž[\€lêÍeŸ£r÷ÚÕ'ÿ."N¤½Lïô·h>L(V¤B%%òHdî6ŒÏJþ&LHa"$< °õ0Í1Üç&Ô»C‡)÷ùñXIÖ‚@Åa@ç° CÙòJ„8Ìï¬tdb—ønFÙXfý(:-¨{$Â]ã‚ÉóR æc]ÇE{ƒÎö̾ÇAéšÆ&Éu@Ôíci3·qÒçb‚ ŽÉ3ý˜ÙÉŽU§ÙåûožcäÙÑò¡¯:£y¤]\:U©›qëánüÈOð7ƒM'0³Ðß™Îÿú»£}¢ðz¤ë¨íŽ?jÊ ¿úh7Ög\Øî(Ÿ8wø€£ ïzý=|WþºðÖ9c+En5}õšþàÍ]|[îê:í¡éù¶ÜuÒ¸{§÷>ª' ßr[Ÿ£{âÔ±S¯8Êú½ôÆqB™wu»ª¡M¡ð?â‰Î#êüÂÏä˜GœŸ×¿S¡ð»#ðBüsƒÜ꒾Յ‰GèÁ¿ÎÊŸYw±S(ü¥©à!¹ŽÏªÏí ']tÖaGÖ¯r…öëúÁ7zJ&C¯ÌõÛ0Wèó‡üíÔÚKµœ”!yÛ^qùæ[÷һɸ³Vm3àÔÙãïœÀ³öÃFtlâ°Ûùö#ÛNZ¸h"ƒŽÜÞ£.¯±æöœ…|xvÕÒ+å*ôñuÎè«í»`á†moë…Ãë+–낉“u&h7óÃï¼?ξ½vtßÒØ\5·ß~‰üÙç¹o?¼ÚþtòÀ!殪!wÍÑ!7äµ}_“ýØ}X—ò' ýî?Tþ¼üå½ëÆg¿u=¤Âhì;ÿÉ©kíøØ×ë¯Í~ë1Ạ¡sµó—̽Tþž¸¾±ñÓ³ßjnŸVa"ºhî‹ GÈßõïhüò¶ì·áóï%(^ñ>ã¦Å‹gžÃwz|gã·OYÌã9³—.ˆ?~Ya0àÑמ"ßôyã¡·†ë/#—~ð"ýãßªŠžhç+¯Í<õ«MõN‘:=òéö·®À_'dÞšF-Yñ¤¼¤û‹û¿yBêg슽ûWÆ_Ì·†`ù> ß_>[‚zæïnÜÿö0ú³óÂí«è-²÷O˜CκoíúçúÓ¿{¼¼ßëj~Å{÷¿A‘TÉy9h)¾ñ½/¥ÇNø¸±±qÓ-ø³ãÂmßë+üºñÜõTgS9ó6’{çÁ&qÒ'û^£Êm×ët} Eá7lh<ônƒy×*Fµ½w%Óôü­ КAŸãuf‚HÞ±¹±ñóÙ…þ/ €ú£‰…ÂÐå­ ¯;ô0»¼ËúãáîÏrñÙ+q½ñžS W}ÐØ¸}!À4éÈëéÔuþÿöCº/B}1û”Â-Ÿ›ïž„».š4Eûv<üÀ©/z¾Ô½ýþøBÇE;÷/GŸ>yÜœ[zÉ]nœRcê}Þç%ì}eHáòWö6îX„¹®ÇmóíúÞçöi cÞ.uYnyè¼Â°7ö5~:wõ¿ûëBzÊø¹wô*œûÐÖ’ö¿mz_ßvî]=ÖÜuê Ý;@^ÑmÚ·u+ zu_ÉwozÐL í|ñÕ+hÈîw<›K£vÌ+ïЀï=cf?mð §ÞbêùjjŒO͸[HÎïÝÏrÛ¯¬^lMŸ·ôÐ'ºOœÜKŸødB¡ûKÔ©>¸Ž½rùæU˜¹†ß3Ñ‚ô;ŒŸpazƒéUS c©xû—]È¿Ž_»oç‹ ½qã§Í{bíUúÄeÛÄWËÚÜÍÇÈÍh¼¯OLiæg4®–/ïòT3;‡Þ½BFÙ{Í|Åw/Ñ]8k~3kªñ˸—Ô<ýuóØ¿R,®‹–N†M\[‘PÍ3o¿Y@Øo_·½ê‚{×6ž³oõôÌXì~ÏÊoŽôÀ÷kﲺÉUOþ¶oí]Š®Kî_ùõa€ûÞ¿»W¡ä:ïªGß)ãëÐÎU³/,}À\®zäÍ6–y¾ßñéêÅÓÊ7èê8ôê›måšµk?àkíÚ5+_]xÓØ¾‡Ûäu4jÜUWëuÕØQƒJã]þ×»¶‹\ÛÝJÕb*:¾Åà‡¢g‚câAâ@p“X„&“X} nêˆ0c¤îè—º¢§Búkê€H!‡ò‰¸â ªÊbà‰E;VW`d%¾Ô7“ª÷Y|·PÈpYSÍmå³?ÜÂKﲫZ29_x0Dó ¡ü²8§.*[~”f$‹r|Ÿâ!„’…ÀÑ¯ÚÆPËðÄKšîÕš(—D,ÅÞ!'%›(`o"Ÿ¿§!ÕvI''´N«Ð¾ÌúœT°´"<¼lùEŒŠ1 ÷ ¨…±ÚôX -U-Ïûi‘4¬Þš„*@íŠ^ê@CÚ1¹0V¡¢ZTè'HqܪÂI©›t 4ƒ8ŽD˜Iz©êñSÍ h¤…€k=ÀÏãkÔ•IPÇ“ LÄï ùŒÄªÚ«ãܤŠÃ<`qÞÄcQI®”PÀS™¾~¯0Ë@&BøÀEXÞE:…©HI0Ì@´¹ ììª.I8ÒІ” ¿±Oh'Ss‰ëôIKV‹òKìù"W¥žr©!g`)0i¢÷bû~QŸO¡ýê (Ãcdôl´–³£ ¬V%‡*'/ÈœP@<䤗 HOîiÀ_U-`Ò]¥l“ÀUhPÌ™"QÕ{ ˜Ãè ­ÂLZ6-ES4Q³( ´ЬJ¥UUr-²Ë [Õ‹6ÝÖµ sm•J¬w=qìrA^[m/‰D.ÚLG3ð=ÒÖÄ7:©öÍ5´`X%œ@Ö@óÙR®.Ø0ÜÒTÛËsc]odeRýc²yr_€9€† œL2Û´ÝëÛ™ JÃ< CíÇQs=†ç«ÈáÞ)^q¨Xæ "ΕÀŽY7&½:XMAà¶Ë§‚Ë12”1õ(¹ØÐ@ˆ\‹ÖB7€ fTGõeSFƒ„0\·4ƒ0¶ú€ÔÏItÃÈŽO¶:ˆWËi "¦´UYˆG¡bˆ…AÎ’0U$šN&9ŽbÆ“&:m…± R"’%ìé‚Z)KF d¥Õ(eÁpªZô¤¼O€î™ RÁ\©îȵ€R¡o»¢••*¬Š,o•ÝCi~ƒ½Šô"h€±‰ lªŒ.@W#Ov* }‡û1æ ™K ƒbNêbHxË@$ÂiÈi%’9Ï%>ëöš~"zcÆpÐ^-IWKŒT¬®/󹩟Č]i˜±¼%H¬ö$Fµ¨C‡\Õ¢×J –dòRƒ6vÌ“4”qͰò­=e’uñ€1ƒO‘È †ÕËj€Qm²­n 33-²¦Gè³9­R …ʘãŠéHf*}@êV'Év`èщÊ/ëlZÑ9 ½RûPoç&dTW­¯Äª¢Šòb€‰þEqxÆvSXÐaäÚŽ%k—´ [©¨_Ø*˜&`3“•#ÃÀ ”ÐuE§{‚È-?Œ8Zü5ƒ€K`jˆ Mî^D"è!¶Ë<—!1 Ùß@6ì M^0¬˜sõX‚5€ª[4¿<ÁùMùžÈ%« „.0wÂÐ긅Y/FÇà]‘IL\Ý„‘ZZø1`Qá2mX¥lÓ1R‡´»MZ ¡ÍjiÂÈ¥ñ:vù#ôa&S‰÷ë y-€(:˜cí°!½+0¿F®ö‚„t2IÞÎËÊ/‹oà[ûÃT€džµTàÄísÙ|Ñ6”3‹ÀÑm™éD2?û™F" ¶)}SP×ÏéA²µçÇÜ0-):ÀÉ*ÒkŒ–n“˜ /Hkä µ"Ï<5ø‘ÝVÅ}@J|äu1aüuè<#‰ )_€-˜XÕ‘F h¢î‹¤µs÷bô{´×ð­‚«Çë½Èª ãDº IVã#Í*Àç)¯%$…4_˜;É0V@0Ý89V0«£0e? „ YùÀerŧ"áŠdÁ#QŒ_Ï%.ë͸¦J £~¤ ¸Hô³ILD×׉µ š¶¦S Î QH·é"ë qb1¿¨º¼ØXñ¹­9’åpzŒ k9ûj@>ˇrbDÐgRÖ1DÉ!5¬²#gÞ˜±.†HLS[ìÖÊÓnâÈØLùˆ²Ñ®Ëì¦ÀcJt\6SÈxâ ›X‹ÆñäÞP¦‘POIäZ2HØJà ô0ÎØ®øMbƹWë0fLxb¥}irà-'Ãx{J}X6ó¦"RQ€E¾zDàèö4% q2pHɧ礲ÎsfþˆÉºdæz9åÄËÔÒµ#4éÅj|ÙÕð÷n ñHÚÚNlõëÍË©YêºT‰f”%~d'ÓÀeÝæ$‹­ué‡U¬5ªýŒã&5‰ÐбÀ§v‡ž‚nD¤Yµ]RÖÕ¶E(KÝÓëùä3àñ¢Ï“=¤G·öõ|ô£Ø•oEŒ”#'::7à¼ÎÑ!GÏ8¾ÂKŒñJÀ3ãË1¯ìíÈ[D­ß íê㊓Íh”ˆ2„´ð‰ŽyÞq¬H|Ì3&¼u5#7ÏÄ8#ÓÕÌŒgÞàC®ÜOCIÔÓ/Ó–òùèäƒ.=Ž=Uà]Ž8ÇPNhrÍïêZJBÛ,Û23c\±-€DYß5~RƒUTÊ;ÉÖr/·{ÐåÕ׳Lø^ì:ä ä/–¡mãZ¬ckJžL fÚPtŠÁ‰©¢ÌóŽ#ŽµÔº "V›çDǰÐÒ ÆŒaã ’gq$úÜþ8Y cÒ}çÃLÊÃb¦±Ý‚šKÎ ÓH€“ yAÖgõ÷ɪ ?/Å”+…˜ÒjØZkØZ,f¶– ±UKŽH邉&êAa™Ç³¶q-žó'„®8±éò8­¢ðÓÕ%À¬Ì.¬w!Mæ(2ßíª ‹oÚÏtkr¸ˆI  fª]vóðäøžXÖ‚Q&úHåú¿ÈÒŒªý/É’hl bµ86Å,ÕfôUŒd©p7~ä'ø¿›Éš½äß@$˹ÊðÈõÃ$²Š¯ü1ÄgÑ|u¤&¯ŸW»–ð¯þxìù]TQêèò8³í±‹ŽºÚ»ÄgtÞ)Gß×JHÏ?¥ð÷|?Š˜­|`Êß›Oíq÷Ø< E²|‡A›ÚÎ…àê¿nRѤìú§¼`Ò¯M'ë8jÜÅmÀR÷ÛÖMk_ÿò›œ Ü¯Z›—wŸzÏT"ú¥W.þSéúõ 'ä?¼´Ò.½ûé®pTð—#Äàpmžp’—/ñ g4Þï‘×-þõw…°œþéòÂv?‡°B«óÚø´î€lXòþ # …?žÛù‚ÒX•㟗7¡h ¿\Ø¿sþ–Ö5ƒ4ž°rËÊ …B‹š†a%*E¿KÃ"Ý?üδeÃuyEÂYc'*ú.Þ~ð«û §^unq&Qû(ÿÏ_y' 'Ìšœ§£ìzë¢Go¾ HËí/Ý6iÞý7žS”ljºE¹ý16™ô˜öМaN¡ uÕ}ÎòO>ÝÄ$‰»?[óæÂ±E/.œtÉEEâ= ÌÇõšñèÜQ§~Ù‚ª:N_‘ƒ0ïxoî%öþŸAi´Mß^ù‰æWzÀ%3ÜÑ×)´H©;üÁ+ [’ƒ™nYrÍérûï[ýÓe·aE\œ¿wQË—Íœ3ÖŒ5ç ôñ–]/jwñ½ë-Hw÷›7+ô3ìÒÌd§Ž™T“Ïäô¢hì¬›Ç ÎÄDÖqäÈŽ…‹žøJòØ»òvAp·î6j ýÙîÃ7手[žlÆH§Éw7ëÄ6§V™GN›Ô½P'AëïVVÊ o}èÓà…žóß~ûþ<ÔmçD¼Þ|Ldz°rþ-ße ÛùqF¬î~þ’Â?ÑÈòÜõ…6ýj©ú.½oÙ"ßoÝȵ:ÓôOšNz-X¿çëU,^³ýPãÞ7òuÒ©ûÉ…ÞZÿêÌ{¦ È¬~O¬^Ž€¢) ,ß6§PðiÎïóì¶ÆÆý;¿%¥œ÷s1G…B»ÁWÞðò×û÷lzÿiúôÂæ-¯\ß½0‹‘Á߯š<è2âÝ­y6×ì›ÈIÒå·/&°òîwX<ø¥];?|aÁz¡8޵⡱~rÖ9Àñ7‹³¨ÈŸÿºpæõ˶Sú·™å»P¨{q7P÷™”Ä–çÆñà¼yc–Éž—3…$ÄžwÿÜ!Þ¾¹¾wP8wa &zËã}ùæé›²Ä]K³æi….:ú]îß~ü Óg•À¤×ÏæÏïñlþåãþR8¡Ý™¦õÎ_$ï>°éù…N%ño_Vø™ùÌ3ïø(ƒ«ï~gª•Z:©;I¾Ü¤Øô}«ÆF¼SŒ"þlnÇŸ“ß.{j{–ñû³íLxb—^í ®{­Ø8½0³8ÈfßòQfÊ톼jqÚß®½'‹£Mzv£Y< (Ø¿þ©uÅtÛ;u.´º¨Ïé…‘ok ¿ûàžÉëé—ràÇ-_äÞ\\«›n7=¤¾áœÂŠàÿþ£¹ùÙä섯¾li¹¾ˆ½¶Î0Ãwâ ]²L>ŸŸŠº\?m̨q7½ôUÓy4~·ìòÂ÷MïUhx—»ðîçŠ5¤.¾kñK¯¯úôð¡ ;Þœ·ìõ‡.+ _Έñ S‹ò(ô{tÅú/H|»oÇŽÏžêSè+½öšâLF>ýˆ–7×WO÷.œ³€¿zõ•Eytœñâ7O{aûr0×–yí …Éèï÷Æäó8åÚg–N3ßôÚ‘Yƒ×Oκä{E%éyߪµÏô.æ®q$ùܰžþ^s]>“º§6îþâ‘Þ…¹GŒÈiÜd:Kaæ—ô÷º;òK¿ÅæéMo<±áˆy4îý`ÎÔ»×ðxøàæüº\ó,Šp YÜÆ¾Ú¸…óØûê°üç´»ÿËæ<_rmkjÆOpc3£Š®Ïo6Ožüá_ÅrµâðL~fZ;ìÚ¾…ššý—fô6u}5»pîÈ‘™…wΛŽüPéupí} Ý™=…kVÿ€ï9¸cËÇOÎõ”%?ŒÄwÇk×eÕíæ–F>6ïúæåñ¹hñú—›3”^?´.×ßΞþÞh ­¯LΩé™Åï®æDý_›^¸¥C¡èê>÷££$!ßôôè2Ëîs×±í¶G—fa® þ´ù·¾1­¢êçÀÇ>iæíÛñá³7WÖ_M?¸æë#æàž­ëW/ff¥øx¾ºÞþÌ;wîkZ‡âûÍï½ôÐÄ+‡÷>=È™}®™÷Âòï­^½z\ïøé¶=ûè’ñ7üm\ÿ:U:UñS[œû§ªÖ]ꇛ²TµèÒ¯fhÝ™ë÷é\S߯ëè¡uüÞmš¼©}›²¢)8 > ‰ñƒV©ïGßh$˜–„hêà'×fà±o¨Aü1(‘BgS7VL ðI »$76cšÂ”á°ê ^ÇÈKÀ¹*Î)0qF/þáHIã‚_ÂWå{¼£…%€¼å{„Âgl' Ò≓08ŒñKlàÂý8T)ö8j[ƒø¢@!: èC ŸðÁ‘§Ñ7©âzc X-}Þ¢mQ‰Pˆ%ò¼¡äÞ£Üjª]Ð<„BV.òH‚¹K- \K¼—Õ »†.3ŠÃ’T¢çupP®ž d2É P§ ÐÅb*xÛ £Û À…°:%V”FF í7Øé³Ø0ákVÛ¨%E0y"g\ªR(–=ÎBád|e÷­&·ˆ£˜âj—D“#¸Lcù6©˜ÛiG‰Bš_# óX‚€&d´“%'¹è“8Ð@´0TRü¬i@,ÌÎ@I¸–¬ÔZÝx¨Œ?V‚Œƒ %±£@][j`gmøˆ²~S®¾„Œ)ôµ!@hY»83.ãÔ-¶¡5:sëbJ8ò5"Å>¯0ެà ^Ša´:ur²pÈ,eqš~Q̈ PåIðs±…Œ ‰ -Ù?°¿\߀Õ:GC,a¾¬Ôð ^Ä\‚”©@GÄÅ\­oÖÆô#,$–`sGqö¤O‘꘎4Ø&qtS%¬Ý/ÄcÑþà¡æ;™¾žBðíúš&ˆ7"ƒ…m`ð©Ä‡Žî²è&¬Ò±fHb.Z'Ë@¾@[\¢Áì rKŠO“=(þe6ˆ2n„ü†a£‘{ òæ:”’ÜlZ»hBËJkÞŠ•ÎÂïÍÀ¬F_lqE)âP* ^®â.'"!ØbýYÂ3—$JÞŽ8ŽË Fá¡'+¨¬?Ye­•YÍ"”Ë·Ñt.ïÕ&|*æÏ@¢£y“« âÈ-¶¡Ýüh® Mç¸Q~½æÚbmƒürŸå`r³Þ%‘ÔËqŠEcIc^Z²z ›l/ÊÏGb^R¢:‘èHtŒ†'Jàû¹x:ðpƒ+G¬qThÐë)0SyòÏgÛ Á/'-»JßËèëËNsš…<õ› dpgâ™bgxScÁ˜ë ~0ãÆô&T‡ùœÊˆ)kV:ö3T,ÓnÇ8­\œÿë0ÓæÖã)˜)÷ 3«ÌtX˜iîn‚™ÒüßÍ!LwÃø¿(Ì´äúû#ßr„ëgÿÚÌ›þÃ?ÿ±™¨Æ¿o¢´ÿûøÂ‹Ð•Mã› ÛþW÷ÏÿŒ¼*cÓHÚ&Zý—§$…v]2‚èÂ?6]1ÿoé§_Ôs@Ÿhê×EóyÐÝÏ›Àƶ:v\¿ í÷þñ¹_«ò2è?;±XÃ^¯³G\ÓpA‰öëÔÉåÑvÿ9­¨úxö€=Šh´ã³´Z¤gU·ÌÿÔêœ6ÀÈþ%ÿE>éünÕÅàÅSz]È ûEÂ"¹ÄßwèÔï¢ 3ÙêìžÝN.e?eÀ•P½Þeõ5ná·¿ÈÿvúEçŸXøÕiçØluIÃÈrþ¾VýnºelûB¡ëu“z ¿pþ’«Ã¸×EIáøvÝ,kÛ1·NèV–E¡ÛÍ?|S—Bý¼y@œtVî;ÿØýSÀ“zu×ú?oÂ=·U ¦>ùÚEo¾òøœçßy}vׂߣ{”Êç\h*£Å—µ‘Ÿ;aÞœ¾åYjX¹ñËO7n\÷ê¬Áƒ.ïÔ\îÖ8Š/•–ÇÌ7¾eùi_ߺwÏk?\ñìŒQ—žnЯŽzê…Ï;wøÐÎ2¬zN{ð¶Kʳ(tyðãíŸ,¹ëÉ¥ONíA•ÿ[»÷ ä[‡‘õÝÑAþÎÔ˵G¨³«ªÁY—^Úº@—‘ƒ?ý`ÁëîzlÎe²õÔ’;Î-œ4|ò(þÎ3ÅŽjG½€ªÀëÛPcþøMkdÜuÚ¢Ç&µ-ËáÌ©O.‡ùiîìCÿÄßœ~¦ ãáØqä°³M'%¨¡ôŠûžž7î´Ò,úÜÿÌ=„tê}“K½:õ,tàï2óê9Ó[pûÈq£Í×Ä ó—>uËù…Bÿ‡–>D_Ôæâóxú¸dÎ KîÍÊÙ3Öìþn%Ävœòø’'çÝ{ÿt $ÚÞ²äíe3.(\ÿÚÚçé‹ÚÖ]ÌŸ“®zdÙSr£áÕ]f êï[òÚãw\=cÑÂÛP©ý¬\ÿîÓ÷¾¹õ›U“é—_*У³o\ôÂ=*ò‚ÇýÙ¿vÎí‹Þü𣧞_è?ÙsSÏ5M=ùÕ/¶}ùéŽÆÆo^0ÅN/»¼‹Î5æ,}v²£Ó½“{ÿÀW›wìÝûùÃÝÑ@/¿÷­Mß÷Á¶í›7îmlÜú̵CG ¿0›e¯}é …½Vߺ"äøŒÒG¾¸áÓW&™V¹réÚUOß·ÚÜñå«÷O¬Ë‰L]ùÁSÂY]÷̶<ª`QZ_öäæ=7eôг³/*ܸæûÆo×>2Jš±}¿‘WO{wÛ–h3veÞpרǶljÜ»Ü4ó€93LÛtyt㾯—OAêI ½öß^ûÅÞÆo^fÖù¶ó6æsh<ð.é&ÚØøÉôB§©wŽ;ïyíóæ>œ^ùÀKïÉÅ[½[û\ ¼æëçSžøØhï}è‘4»Ô<ôæójë5ïýo[qpÛ;pçør)lË3ã/(Ü €éþ/?Z6‰Fäi7>6ŸX€(Öz÷ú''\ÓƒBI½\Ïù惥¯ãWm{^ð°—NŸMx“°/‡6¿>ûÂÂ9<àkžÝYšEc£EÚn] (÷S¯= CóŠÈûàºGG·/üAØíÛ>¸¥< {m¼U»Á€¹^m:ã¢?þt>æ–à<ªO8&íËéšÅå¼ü ©qï£÷FÒÉÝ¥ƒ_ñîa\ß.QÐæÐ%¯¼·cá:À®Æ\&Lºý^¨PöúôAõŽ}wçŽ×îˆÜz'%õ¨¯áUò칇ãò>´ñ髹v»¹kÏÚ'Ö£È{_‚vC‡«'‘UmÄ+‡… n{oÑÍ×ß0kó ˆ¶¼|Ûu7Î~`Æ`¸íço<\ûw|¾î“ÍÅP¨o¿øhÕÛÏÝa²#„ìÐΟgm¾ ÛñæÍ¹eàü9ï7 5™¿ö­]d.u¿÷ã„ übATØXJ÷|pTyürñ°BÉuÁÜ£)ÇÞÏO(‡[u»gm3ëãÐÞ¯V?8´`ë‚{×6£]¾ÛºnõOO«`5âê:ûݯööù½_­yiÁÄ+‡]vFåLÛN{nõæ]ûç$’ãvaÿÐÊâ³j¡ƒ7 SsN,VÈm¥ZÊp.¦ ¨Q]v賿ÝXáyŽú—L±”þ¯b œ ÄJ ŸXš: $0Á] Þ™Ðr B Z8ùœ£-|sÌ= ÊLáž‘®O)lKaÔ&÷±µ)W(¯Y8G+6öÂÃéšalDTäÕ;rÔ2>cÆxH©Ø› "´A#¦åüc5¹sI‚⚎’_[»«¾Ëç "ÌX9€jàÁI¾M!_N-ïªÏœÞ ÜÆP.)Õ;ü‘pàgŒÎ©€Àõªp±Üó s1fÁe_o$4, 2Q.,8ÙCW°ÊeX¿0"dœòdX[œA˜#VwmÍä:7X£}éq `*¾2š%±ŠÀ‹p©šÇ––=rBáy°=Ù+Û’`âoÉ×Rø÷”ì0ÇU(/v®°ÐJˆ3¾#øˆX±VäÖö?/ƒ1rs‚P̺,Ï÷FJa V `âõTvÁ—¾‘q¡Âù¯DkðÕ Ÿ<Ô ôg¯® O@Ê&néP ÑÂá#A¬ôèß ‰nV-® @jj%šá&eøk®kEëÔE„%äÜ1‰2îþéPÞ/ôwù¶r”WZ9uj <‚À–óS¨×€¦¨AL¨ÞQî.`¼”>1¥ø”Eû;É‘[â ¹kB­à†Øòôfµc̼ϣidÖR¶¢³1‹æ|áX…›Vý×Â!Œ€¹gt²¨L“Âîè G]ˆßå«W:ƒÒñ®(WPzÊ1 /2i ‡ •KSâ;€qñƒüðhÓ<˜À2*O¡_Ó%™›@้€ðŒò‰sˆ âŒF DQ ƒ¶Jãaxúâú–?^iÇÚ°ÐØã$ÌŽÙ`¿5Js%æfÔc1«>ßé1¸=ÈÈòŠB0x ° =–ç7?ƒñai"Ë(V3+)+‡€vT—ƒØ²vz61›Š}?‡ÎÖ9xûa€ðêmš#å\]?±# ¸ósœ“06+² 1/ÅòD^Áèo\ f/wà,xbš “ k j.Ð’º­yÄÃOUˆQ›TA 'põDd™¢»åÿ/ÑÍ®ÆÿhHýÿqjÑQ•éfÑî&´=ÁÿÝ ´€ïùÿeÑÌ´TMùº›} ;Påë—•ýÜG¾þýúß4Ÿ\¨èÊÊ^õ»ÃÝ×ô••ýßN<Ü}M\—/ûâßuÿð³¼€øoN;õ¨¿ãW¿(NÌ<þñ9Éan.¡“¢úÿÅ~^(xm-"!èv~ËBé¥-UÊ^Ç/þ…N{uÓ€ï:÷>ÏâÔo~ÜñìºþÕñEþõŸLÝ·‚êú)ýG\¬0†Óz÷R¾‚¶@O9 ¥¬*ÁDüÆ´á šà _¯nùï~ÑÉòÅU¶]~w~mV¦€Q1$æ¿/üÊgÈCŸIרÃÕê Lÿ€/nØ~ÒùÊ1]Í;O9-O õ›¸Eáß*üÉc§‹r¹¹Î@ÔÇZœb¥¿{Þ<ûšS ¿ÃÙ9”…{ú¿~QÅ÷švï+ØÚ¾×©ÒÇ~Ó¦­–ºfî³óû ¿o×££Õo>ál ýo©¾î¾û¯×ÞÓúÕb>œJ{Z'E |ò½7§·5µÔ©w7Í‚à ­Û9…¶ãî^pçpáz8gôSùq•ùGÛž Shxm˦Åð;]Þ½³NÍå`Ž9ñ‚þ¦Ì]0ç*þˆ¶Cï|lîåø€3L×Lúô9]r¸ñÃýû×Ý G§aýØãÕiôªý®7ÜõÈÂ9c»“ëç¼i‹×|ø Ò¶©éuɈ+ˆ{ì‚g¾nlüúy8®;ŽFN ~ÚD:ÜïzócOÏÃD6g¾½mß·k'Ró›<õ¦k.áÞ~Ö¬u‡@ƒÏè4f$jwšrÿÄÃÒñ¦GL`2«3¦,‡í›gà5¾xÊ왓úKï¬$)‡Vƒ,äâñ Ôù.¼óñ{zãøÊ{g õÎ¥‹˜æâ“—Ú\që­×^.¥¶wo >¾Ö4Ï•S‡Q]:wñCLZP{û4ñÐ ÇèÏ]=†tQotís̲yz¡0èîÙ Eé=ÿ•'ع|É´[ÅOXÿ¶ø6ö¼àÆ¡3>¥Æù~í]ÓŸ{í±Ë)ñÂyË_ºš_0kf-ß8j¥º46̯5=ûýÉÂ)ë¯6oßüÃDªg­øàQ*ý¨…¹Ó•kÔòÀ?·ÃjÄ[9Ç˾U›rãšížÛ¹Ðû±Õ+ær[\ó‘ÍázóÏ?Ú14äµ¼ïoÃdNºáÐÁí+ÏyÓ·_¿Áª­Ó,ŧ·›žÒV§‡>Kò¾Ò ‰ž ó“¨ÞCßí€[òËÑ={gœß¾\W8£oosϺ?/k»ÿrÂ_•óâî{çS£æø=¶/½õŽ©#N×Ïÿ~ÞmôõbSõ}ž+¢yÚ³bÎK7çïÚùÁ²ûFX@ØÀeE”Û–Íœýr ãÌ÷_m-qÚm'§îÚ~n±dðw_m=²îËç®ÊÁC†¾xd~š’kÇëSòtm§¯>:'é¡íoL+bÉ+t›sT¾Ú=Ÿ.™RœA¡pþÝ«ç@/º¾ûâõû†žU(½ºÝ¾ôóæ|ÉÁÝ_¿ÿŠsËžG]Œœÿ滾?¬òó¡=›×¼tßÈ&]‹ç6Üûüë+?ܸ«2%Æ=[V/{`üÀòòçËÑgø˜\º|å{– |ŸlÙ¾mã‡ï.›?~`Åâ—¥nx1ÆUï|ÑÜëúƒ_±ÍÅŽÈãoàúo¯äQx%›ØÚÒÞõϼyíd·°|òš €ºŽ ýA¤F@//!™8ä÷YS¨ÎåH•cmSÖ`­Îr)È"Í"çËß×ÝÜýŸ²³v«Úð³åâPR¬ÊRRE§*Tq•Ô¬š½*“ÈâpôI0¹EøðË\QÙJ؇³\ËzN.0­GX@k òLjA÷=¡¯—‚E"˱U¦žs9ø~,’JApwFÁK-+‡rñgT üª"VN¦Y4|V¨ÖÓÞ]1¬­b\i¬œæPXW1¯<\O² Õ,O¢ÐŸÝ[‘£qh¹ãÚ°4ö¿C''—Õ6 ÑLM¤YùLØô ¹ÛŠÇUˆPÔ,ħ›Œ´Ü,œüí©" B ¯G¬bV†8UM Xƹt艪fs¢ï±R…Ïlš<©è2P€)'Æn"5a£/uÛQG§Šš8´&D¾i©/=ˆˆpºÛ›‰Þ…j^ý1iF–©Ÿag:Τ“pRˆ³…:™Q\™R¹RvÉVœg´Ä±z˜ÑýH£E|1 3‰>Â.ÈÐsáË&6ñ‹ X#ˆE'0áù¶c³F)gÙê†À)S„â^¨\KuÁÌ\dD ÃY8âG‡ñ%”‚y"7¶Ä9Ú©k¾†+ú!{¹©»Ò¾,»x1(5ØŠs/äÑI0-AÊ=6Þ˜„†`Ê}‚8l²Š#_5w–@KÌ~`ô*?XO @T]k!RôÓüÆdK` i•t„Í€ž`=žÃ$‡T! øfü†9‘;Džo—AèÞ“3ò¢¢, T”é`Æ­õR¬¦‡ž)SEêÈ`jÕŒdîài("‘ïY)Rô)EÈtiZæH„§ŒeØ*CY‘פE* —РH¨³$ì’®--„ãÚ±›*§†­å|¾j‡kPpäîØå ŸÁ,Ir)‰WÈš°îø6?èªB&-5ÏAi¬:£ ÞQr°XÚƒÖ” [º!ëã„2·X¬@æ6t+QfÊiEH2³+U¬¾ZQTåùr¯À.ŽhI‘ˆ†¹¶›Ù+Šdè(¡K"AòÕYLD_("OŽš QmTU–íÒ L?I¸–U€Ðqd$P¢%]•ïKD›NË*² aÈ$¿ð±Ì²Š T€“´±2±½ˆTß<V2V "¡IÇjRQ\?†žˆqjã1cº¬ˆSgÆÈóxÙÔqS– £3YÌ.ß :eêÀ’Ùe6C]ˈÊa§²åÉH¡€ä”uX2GiÅ…<¥°æ[ ¤|¡•RN™`° Ñ8Í¢‚Ä\E1º ÂuœE™1å¯s|½[ÖYI $?" ³^+Y)Á):±b¦U`]ÔêÄ$â ¹uML\MLTPècȶõ}-IY&âv¥Û§<ÄV«öb)Y™ !G¢…ä +H!rwdëN`.™i±„#‘bsÙâ©Ã;èjÛ³B‡ð¤Æ-¨)£ËfŠ2kzV 0²9 ·„;žûP97fO{· ³hê«ØfÌä”XX£8DcȾÉAmê GrÅœQ°2´McÝn” Æ™]ó4Ã9‹H¬–ÖF–0„”*ó€0Æ8Õ2'ØsËJ"g?¹DlõSý ­Ú›ô±ØÂÒb>È@•ëñ…a” 4t”5ö/+"ÖY5c Î?ÊUê(„ØÔñB­¸2éR­¸ B§%QËÕSõ3`lU‚M'ZXmi*¨[êe|g*k è±ke:A",.©ïÄRõAê LYXIHW„»I¸6WôjRò%ÍÇŠð£žÙt‘ÂÃâg⦎˰&KAŲ”‘$zˆEÐaè"î‡j—U Gɦ{±€Žì ŒŽ„β|P˜ñÅØ±+ €š—È"»c6}-ËšŸ£”ƒzº+‰±—d˜=³×ø>ó,¶$hnìP“ø.w²–•ifx“„3O cºû&av)p*Ø;ì y®G"¶ºÍò¸!¨†h{&›lÆ%BHZ¹¤À(+WNV‹sCMO”&˓ψ¬U‰mÇo•qóTdñ©ÄøÃ‡lö´py9ÉB´I@tc~jA›~ªBíi¶ÑòÓ§®…膱i& ŸÅÒ¨•ó­JðZŠ×,èÅóÇØSO”åeöƇs](Z´š‘ ŒÛX€–))UvNÚøq¢™ÖüIôžÙ‡!^% EÆ“==# ôH‡$¤su(‘b(ça-+q;õ´wÓ!(ÿ ‡È"ä…±Pà!7 Ëx«­/DÇvç®[;|= |#›Xš-9fÏCl+‚qKq»ÙárEo ¸§½›Öô½„MÏl¿†˜È5ÔyeÌ; ÿ‰" “åó(e³^:pÇ@9(Y.7Ò‘:­tÏB[OŽT‰PÌÕ…%·µGWeÌ8¸ eˈ6Qd…ï9ñY!Ôî&¸^P}Êî^NȾRî!©GŠ#N”̺Fa° ' ÿ@ &~ˆY™½øî$Ì t¶ú\Ž×É,1™pÍÖÆÇ†È“DbGlY™v\íÁØr@JȨӅIÛ±Fnäe:^¾®'&*N¹êØfëZÉî’ª¨•ÚjYAqvP¶ëIb!õ¤µOG¬q=ŽÃÖ3õ$:¥Ô-«ù!v„ð-ÜáZ*ÚÀq$”4*ÖD~èÚu9MxÛ4ÈþÀå8­ }6 G‘Ë^:Oj)!;øÈœ×‡`^ìÉÝN¢Î,ß¡š†^…t†ØŠ1¤I|芘j5T'†ìØçÊs•¿›ŽË(‘ÜÔZ 8¼h Çl'ÑSHäó†4óÇ(µV’r\–…D,“”ÆÊxî±6|Š˜naw”Ÿô¹“}üÀñ8wW~óT¡P£Òõ²É:uJ¾žOvÊý ¾rW¥R˜ rˆ#‹"%F6‹T"Í<Çaž;5H}9þ¢ùŒÍ>Ý…Ý$9û%Q-ÐÁ§jgÐx¢C£T\åd¨· +Y¡ãËÝÊ'Df%§f³"²ÑJ¤+æ²ðBùÁõãÌr51m)ŠuT2çSÕ•2…–žö…Q t‡øáa1¥ö&·?çTHßÄÒ†ØC4ÎÍ¥ÿô¨)÷5‰ 4íæ#Â:{%…uÄÇÑ*O…8ànßažö :|Ìî™ÑçDâã&,qcx ‹ Ðäì´R¿&Ã7XNÂX»ö΄ï¬V:ÂôÀ®Úžè Al&l~ “hd²ý€ýéy‡Êì¥røgßX|VB3:l¾-™ñU(T‚˜\A%EŒ#è „ÿr¾‹PFªÐ5ÖcæÁc–Èîˆ8KècQ1¡¯ÚOûµ¼Ô–ÁŒ©B´W·êYmùõ'âÐ…Gµí`,n‘€ë}cùÚ óó‰r8.!~N¶u,CZÂôËûK5"CÍÏ8¬r &€ÿÅ@™íºH4Ä`dŽÍ6ÊÞôPn¸8ôeÒ¡ðAB'A:äør„ìµ…×:ÀàUGÁ؆¯ªCåœ;÷ŸÇ<ÆñA Ä6¦ÔØ8ÃB3Æ–ÞLz *‘?ø£ý@œhÔ-Ñ~ôѾ#mï“á‚NèIµ4Õ3½TùeÏ ØÐؤ…(õ³\ÍUGf­” ”‚¹Ù½®-­g‘Y埀.À£CrF'²ßÚ]ƒäBCAž:QRÏò…ÃAÐh|¡5€Š¯}Þ Ì:C.;rTºÜQ ;æ@„¾7íÄOÃF¸¥zoD‡c©Ý'ú*—FÉ/ˆ–ºC]Ä*iЙ²Çܽ§ h‘W Ñ‘èU“ÑW-EŽÚш2½{±Ny‰“ÕK¬ÀIMÔÅŽ"‹ï…RU"Y$‘O yûÃdɉÅÌe¹¦ŽÒåJ ‰zr±Æxþ^Ä¿¸7Vv’|¤LQ^²è8l‘$¬¤Ê‡ƒxœ;¹-³^(‘CA&dŠ6ô¸i±¹[íî;¦ ´ ð°Z& ÙÂëÛ>0,¬„5š…gò™‰ërà鿆+E¥ÈŽ$Ä)èî´ $|d@¿@=DnÑI?ÈÇj‚Äå;qLjóÆj]bÒÐp³Äl*«»ÚÎPä+K#öÓˆ‘—¥6Ïîÿôì­t¶¶K¬‰Ì¾u²DÇ®°Ù†$;SChëh'ïŠ-Ïh~.SºVN>¹€Äe6Ý;v•× Ê§ãc…=\tÅ3”Aö‡c8Eá,|Ù±àuøfˆ= %ªË GA-† h.®н¾µd±H¹JHù©fˆïE<6·:d?”…¨!ÑãÀ%O‘@÷SœÅ1í¨Øéu,{*…2ÿð]•"ra_ÅYËΪcýƒöV”í8‘°> {Ǩð&…aÄva÷yï,²&í¡#¶Óà` ½°©é†³éV™ò"µb‰˜­lΕ¨pEჵ‰jc†gšTž¡SÇB>!ô6(1ÈB=|—Ñìò90Älj /œpcƒ€Žt…¤£ÍÇä<Ë®I©«aA„iYñ ŸO­+Ã3(‘£MÈy$šªë1¹,RW¶¢YŽÄ„qHt¬' l³¬YÄ…ˆ®&eËÁ&È5‘©¡f›‡ÔÁqàºzÞšò0ðkÆÌfÚ²òÎU³fp˜‚q¤•©âˆu‹9‘VÉ q-â,…T¨øéÖ’Ï DFûoöÊøÖýIžó\×N5ª“žZnÆlÑuLöÅ•Ö1ÎÂãøú!‘í!dÕ•À:ë—CE»“R1v šBYD‘¨°,øN%šªÂF^§»cØÊk?|3o½ß?|;OYTÚÐóÇ´¥·K›ÇÕïsH‹$J4½©zq·#‘ÉÕaœ„Aš[yK|3R¼cóΰ—úoÖAýýê†Wµ2°MßRÿt'¸³2ùäôÙÿ‡?á4Õ‰ØF/&ÆÕØ˜ÐÆÚ±îk¯îk"ÝfX©FÂþkH¨RèZ€- œ =tÉÍhà ždLÔ ï‹éÀC<Õ™ò•Õ$c„í‡ãêÂá[ŠpÄ%ÈUí0^’0YsB¬˜£rÖĦO1Þ0fÞ1jÒ Gœ²z¥dâ”c¾3Âct~ íB`¥ò#‡ 05ñè†%Êq$6±ö¸â{=a…¦¹r©ä@>¥ù³¨\ÀH‡–M1@|F°J2ÒˆNX¹´åÃ`.# íÁqÝ.âöS…­™žãñôR•ΖJt2Ÿ•m:Ñ0³Í;1ÁññË$(ˆX=¼Œ±&hŽ ǦðÔ©—•ÀuÏn9å³nœž[’JPNmq—Ë÷N_qØ/$®[Üå`_e™êyòp ­%#¡<ófõAøŠÙËc°ÉXD)Ζq§ç†8óqê…ÏÜî$<ŸÏ†¢n¼ˆÉb8'I·p˜JÂÍ ’p@¿¤ý7u¡Àa!õb_øOòá•°ÈÎ|÷ì¡:‚”ßeh¿Q锩2À8" @Ã-´=h²TÈ;û‡Â|"ÓMÍdæž„°äß sŠA%Ɔ½#ú‰d!˜p ÿU´B–‹Î†›BË+–Ž-[E<[Ò> …zL)Iˆ©ä­tÚlIØ@¡6æ·YKRn*쥸RȲ>D¬£@%JqúÙ Dè¥ î|­Øj'Gg9j\™Fîž)>Þ4Mhq¡†‘FârçÖKc Î*zƒÈ¨˜†5ö‚Ê %@Ê”DF”w>a¾†ÀcÒ.NôÊ׸ ðd2c„/6Þxâ_i „ %²Ãf‰0€|-m–ŒÝ˜ª¾„R¦½›Ã[Äi‹'™ƒ•x>}“ÔÆ¶áÏ€`¶^`CͲDc:Že®/mñ?Á€;b5‰€ì@)Iý{ÌR$–ND0Em¼SƒLÁÝécc¢‹+Ç­F¾ ¸¹¥T`EìI•6RžA|OYÒp–΀ïê‘Õ3Å•a½ ¬HNÈÒFKË™èWbêÆÀU;Ë@2òÆ\ÓYhh%±¼k¡vUßc…»VAF‹ÀØBi2,„“çêB Tª –_IK3ÖSÞ\c õ‰)ÂWª²6a§G.ú@ñÁøa| ±õPc‚ª€g#BJC¤ @ˆt–(‡ÄŠè%ÂÉF¬¢å"7M¬N£1u;îd:ô…â†݈«#ùBÌ…H÷" 6Uµ%Ðt…žÜë;Œ%:|RÕP|¯o÷ã¹—ù±£gÆ Ç: Ù)ú°Xý q°3Š*i”Wm-ã¤î’ ¥“Ò ™,)䤸hÙ'» Gj ænøêgÀ`‹„ƒÞk1l<^c©gÐɽ"‡h»M£U†úBº5ˆy ÓÁ*vXÚI 1då @j:tܦ¦ÖJêÇ–ÃT)Ûü”ûRlcÚÊ+FÖ@ê&!¤?uᙄ % ‡õ]a%DH‡JzÞƒÄÁÌ&*L.á}"¥6f¤òerg·P%P@ð#GbŽŠƒš°_àü‘¹="§Štµ8 J+~I±n©”žJµ©s/fE1l£•Ȉ§HŠ)I;W\=Â9ŧ[!ÇR§®2ò¥¼îŠWC!ª8dIù$Íã0aÍ€WÒ|¼DØ©‰ƒo()l¤ôVìƒQl…°áÌC”RàÖÕMþÃPWì.qcUÞ"6-3žFÇ•(ADÄg Šáˆ# íáãF¥'G–‹Ç6 úþ²ÖFØ—)Êã@˜ªª‹+²zNÆÃã(cŸç”»AøóŸhÔ'œwUóeU©Ð_kü…•q˜$*ÓÞ qÀ…1·tÄÁdÜzÚU1M‰ ZÚqÕY&nꂎ#ÝÊzQc&b`ækŒcÝ:Ó‹{¥´åD<#‡%´fr¯ôey¦{S€èëLð¢‰\Vœk:~ñ½¦lJäK€M+·éW©kUÄP_1Ó×äjg̾ú+Kj¶yË1>ÓåÐoÄ| ;H>SÂâÒŒAvkeÂÍüŸýL9„WÆËXúdv‘±ËZ©„5ª \HièIÊâØ]t=1 C…dšúo™­ ɉ憎^â©áÿôÅ/΀p)VêkŽ,y”,'ÀH÷‰X:P9xT¿Kg‰oDV´Y½Pæ/O ¡ž§‚c@iªÞ¾L"áL`=‰œ&ÚØÃ‡ž0D¢Ö•¯ÙPdt”)’Q±ÂØSÈ<‡•›k]–ÐLA´ó½!G%ó¨’P¬òþÂ6zL$av>ûÉ5®#ð"‰8¹{™ù3>&níH3¥^æFŽ,:ÀÍð ö@Îi=©A5 »¸›SÛk41Pc–Ö K…ÞÆf{¾¦:„˜p†f‚8–Ò†ÂOˆ—åüÛ~Ä®ž%=Ê9–¼L_Ÿ+b`È áBõHi”S^·<;{f>¦)–uôäÏ„§`QK!`E!OÎÌ”8ÑiÄL°”‰Ív7 ½¹V°1ba? ¤Í3ýáña¦Êý%Ù™œÃ´$x°/Ûø˜·Ë¼FÒ¾EKô¡+XÉ$!ß«Û/"…P=ÌŸOÂÌZDdÛÇ_Eçó…X\q´½O%1ä~sS™à‰â½¹±Š1oäÌ1\&:¨eõâó¥4ÑHPQÕ5mfg;f [Rž9С!D>±›>väa¯éi$…{Ó¢µ:Ùós ¸ÇË7‰Wl\î5œWeË{,–y:;'Xš€ÐBögšo ü2H, &ã†SZ{ š4R€;mÅä(ZqßrÄ`áµS›JçúiJžpØw•Hç’ PÌ! BW¹Öp\QP¹¢ XT0Ëæ¡'‘®H §5.¥VÏ|fï.Ó¤Êéï\AuÉ¡ð-™Þ‹÷ P”¿Ë;.×åc/v¬1ª–šı›tÊÄŠŽ*XYËü¦Ãt€„sÅ%gbÀÄ|`*ƒ‰¡NP7b©AjÄ‹hV€­a ž(ôâ´JM7'Õ½"Eþê~&VVr¢öˆ2K_Ú)¶„¦é’œÙT+{²X,ÊXI`N‹N$EìzÖl—ÐM0Ê2³Þ¯T錈å…Y# žæ² Q/ÂÉN‰è\¨¥@^«”ˆ©=pØa¨Z቞ :™™ë¡=aCbxÃ%JŒb¶âø˜IcËXA‚í|<E÷kÐ>NqÅåX{\;]ˆÖ'¡â 9^ÎcÞ\šœõÐ_ü¡g둎y)09"¦-_¦[ŽXǦßrÛ#€Ý¥gˆNxÍ,³Xö*]„¾¨L^1pÆ®Á]’#¶ÈªRà4¹W¹ܼx—²´Sð;¼ãL G™®q”áǾ}s áD™8(y!cË‹S ivY½6ÓXÇY9O5ð9$DÜ!ûTÚþ`°³J(z4«€ˆ¡¯«%æ¢D¢|bëÌJ@ýêëÈ"õlÆ€á.‘F39Æ‹0BÞW ¼¥‰Ãøà›_&2$ºo=¾àÃUl‚Ãij#€eÝávSF$L¶\Ÿ.X¿-c æ† º°Ä†I›ûø4´/`®Ž5«P¯rp;^pT•F¡Œ¥È W'öýtÜ€¦&|–º4Ñd9@_ãÕ%ÊÍÑ‘L ƉÂk“ÄÎ…¡+á¤LRÕ€É$Q߀+ì—šŠ6†utõ`µä»Ä4`—­8šÜ¼QiªŒŠn{K Væä¯ (ƒdlµå@ƒrPBF4Z†`¨u¨‹àªwe†u«r àgé?ä Ž‡+S£*œœú¢ á­ ŠÓŽÌäÎÐŽUéð„™Z*Ê”àè‡T:î)?RÝœˆ¹ÕÉÐQi)tU†é„Šæ'|CÊfZL+„¾.n ¤‡¾õÜÇ›OrÊÉiÊöÌ(®Z[o".Ö U ÙO‡´íkê„L«MÌE8Ç…ä ³.Ghx¡%èMÈUæÊÞ(ÉH…‰pÂñyŒfTjÞg?åÞɉtM6 ’dL‘Êd“i‘ùŠÅ¦ŒþØ:ð€tä8*àÓcœ ¸¼ƒ/?¿ÈøÜËO;*ŸŠ”ŸpO[*žËT8Ãá, ÅŸ›«[þÔµzCrXîDªÛCèǹO&Sн¾x c2x=SY‚2+Sg-A^j"’p9êöô#Bá|î*ERc®IäLYE,Ê›Zí•\¡ånSÑ+©ìd­èŽ-sÝÖÚ8ˆrGo¹SXŠWÙ…\ÉÙ\É1]ú…™»¢»»‚k\kT@ëi¶‹Æ~ÓÕ}áˆù X¼ )Ê…Ñ( r ¯Â–D>‡"y‘²6— › …=Z5´«¸‚c§Ò\/dE€8QO0ù¬ÙëÎaqEV(ñqèAEB !££+ƒ?Tp=+]EGu—vE÷7—¹¢³¼‚S½ÜûÎÏWòÔ7áÒ/qÿ×f3ž ÙžúsGÓp q V©GâÙ ¨ ¤‘rÅöÀÅsÅ&ÏÕ{ÙžXIõÄ=€hVvE‡_¢æsœÑ!i¸“xæ2ŠÞÈrÒÆ¯4ÁÂΉ[£â¼¶~Åãû²£þžö…M¸JÜ µ¶9ª¥("V!s1Òç…a¤TIªë³Ñ¬ßìå·d7C±¨I^~„×LÙ¦)-3›IöˆpŸ *­ 4©ÆJƲCé9DfEìf%œ'$”3BBèI*âC™Õ©ÿÊ‘'Ô¨t¡ß¢\ü´aXÓrþž¹TG·ViR´‡¦ˆ}™ó*QdôNãÅv=EË&‰Ä‹Î< b"Ú{å!™l¢pã{¢u¥5J“ e”(ci‰ÃL³©è^«äˆ«ä´ãݓ҂:X žÈ´qÐ9È…“€‚½4·36J,ãGQ e |)sEÄ~¸?»¹B(@Å  œEÅp„J •‚t[U1$¢ ¨žR1¥,æEr¨ SLÓ³ìî,ô¦bN¥€K¡\~L9ÈþĶð '’]Ɖ*¤>…#//ÅÈ:M<=Ù3vMÌõ¤®B¨sUÞ'›ÒDk•Æ'z¡'h¥‰OB,> Ú9dYH|¢·=«@iþ©8–çªxd›qM—B!2–øÀOuô‹¿ ›L;¸êöĆ5a¡_ßËë#Çe4Ç1…N4QDL´.[‰ÕsHŠcê#Br(¡"Ý-£·p—}ƒ~ßß9mˆ^zÞÁ‡÷\ßpß–-9™"ó?wÞPü’ð/Ž4ÿÝé²ËëjëkqFŸ!—ÕU9|äˆ~Uk×ô­^ÕixSˆÃÿVÅ?V× Ø¿ïðš¡ýú×Ê]‡ غʯZ_õ¨ˆÖnýSUK“Eþþ÷·XS_Uéþ¢[M%›{)‹&_Pü@ˆ:5Ô ,¾•²¨p¿çhaŽ˜5eá;¥ù›>Òi°iÞ~E7W÷«8 ªKíðþ—]6°Nï¥,*?ÐÆt°öƒ>WS”Eß~xÁðÚ!G*FWóª:× ®íŸÝÉuQéö jL'­2pÈðª.õÇ ¨k*wÊ‚Ÿi7²O]ë?UµângúiQ§û‘;oc:)÷ê$øzýÿ?»‚èWÔöfÛåøÅ!þ/r²ÿc/Ôÿâ¬ïÒ‹Í?=þRc3´ÉýI¾×/©èªÐVsbþÇcÍOòf§¨¦Í?}úæØ‘Zw¢OÎf,z±Y/¤µÄç¶læ7ÿ˜¡Òp7e+žvÐGÌÛmðàšAu}ªüÖUúôÖUâ=Ö¡ÑDYdF+)„åKå—œ?ua0K•”$úëV‡1¹i»´VþÊm“_JŠÂ÷‰½ò×-UÙòSR´¤¸ëŒö=ºRõ LùSä.õ£Ö8®õ¹ƒ‡\1˜þaLÂm†Œ¼ B:æªZŸg k̺Ög˱¡Nol]-Öb»þÍgâQÓú®â8õOô­å–¿Tz¨K}iºÃ>tf͈þµù'P—‡}Ä£¿v.÷šLò†¯ù¦!õÿQW;ÄX„}ð#ß&ŸVÕ\ݺ£Éºî?«N®:®ªE.Â'WÑ[«N>®ªuçšáõ¾¥zÈà>#û×7ñùPu—¼ urøWKæÆ3MÇ®jÑmD]Û†ºÁúôÁWRMgUG\UüÿŽ !@Ö𺌱ƒQHG¡3ûŠêÛ¾¹™µÍ£µëðšÁ#þsÈðA¢÷f_ßÂþÒª¦ÿPÓóy°™ßëd ´È=ÛºkÿúGìZ¶ÒêõI™ŠFü)ÿëðºÿhFtÏJ‰=s¤õÔÕ˜äµ5ëº_ÚÙÌ-uƒëéÇ’ŸÚÕÔÖ^”ýÒÁìÕFTÊíì¦s;»87þeøz3·]úÿµ÷Ýý‰ãÜÂïà; .˜’j ©¤N’ILI„±a÷™ýã~öW’›lK¶ dÊîìýÝy‚-«®stÎåNO6Wb{Ué¾(Ý®c‘ò 3|ïýƒ¶+«[ž#ÀR‡=mdÃLÞËÃQOû¼`ôü>ü .{Œž®ÚÀàoú.D0ÞRñcLhÀ‹&€v/ÂJÆ“æHnmcµóÒ=ù««ôåÑ•¬ôdØ3jv~æxÍ™ÛgÌÑÙ@r4€H¡Ò‡ÏlLÄá®{ñ+Ü¿+Ï’ô”`3XK‹šÔ¹bXxÕ^åÍ«D2¯ÿðª_žWý$¶3ëUâŸÆ<`Sêwé“AßU¶­™[ŸS§ÊTÿ×mOàÐ ô­ËÒQ†£˜Q󵫴ºãðÅ÷ѯhîx˜˜NV¡·ð%•€FZ?j/Õz`ºvúžóÍàæ+ØÍ¸>Œ‘7#w2;ÓÑ(ëìÞPASìãüør¤ö:Ý Øhüiì4ÆûÃöÛß=µ«©}t¾MÔñ»%Qô/€ÝÞûÇdF®…B£L*¯ôÔQ_þ®ýLÌI@~i@Ô°°!¤oÞò ï"Ös2%þ¶R±?P¾føf—Lèú(…ÿÝÌR‡”’7|ñwW~së<ð)]ßѾarõš’aàÚëPù=1å.fhŸÈƒö«íÁp2¶ IùUÓAò–0’ÿêÚÕ¹¥û“q×h »òƒdR0‰Rjî7\Z/ P³%Yù*ÖaEé|U*Í Ÿ6w;òüx¡ý¬·úç.<©ËUÚ^¸ÔŸ(T|±µ Œ7/C½RÏh·Û,ïï¤ hÛÝÄ"à¿èúþ·×·v í˨tQjÅáÃÈÿmµÆ;òXF*‹¡^ÂM]åd€ÅœÅ0ä%sÄÿ!ubOî)á’ 5ô_N‡øoºL’JŸE¢©ôúÄfž¥”åaP*ÐŽ²1áÝnÚ}¼YÔôg¨ô?ÅÐs.;S$¨|¼¯¡É{›™N#Òie62yv“ hhz»Cî ÿv¾Ó^Qmûœ Ö‚S¿ê ’B­þ ckÐBâ¨7&8:²ò¦.oÂn@oSŠF€R(ĸtÖLDÎ$S4³”!úÏ@ j»¯à«j«JûçÈÕŸ%öÛÝ_ƤŸ•€¬°îÀE5ús*ɘß1»B !˜¶Áà5 ¢É¢:cÍò4€ùþcwJêÊÜ,Jÿ/nþ£@„¯Ñ¯-/ ©/iŸ×.ÅN@sºï®`ØÿEí$”fÛ‹ŸbÙÿ9Vø L=É~¬`{äXaî–cNÒ­üÏ0çÔ;<ôcd±ËÆ)¤›ûCº?‰tÑ¥/“®Õ‰©0~iÒÍ}&åþToÃÕVŒ3¼…ÕüÓ8,hQGæ­òDöºÿè>ÿ©"û'˜ySM0Öþ¥Úq¼ýUN7’¹eDŽpPg‘ž§k˜^"Û4¾(‡M<Ø4þÓ8ù†¯/·Dõž‚Vß^‰‡îi€~k@˜ gŒhР·€`DÒ@ñ9?'DC©‹æµ²8æUÝy`ÄŠ¼vAEö·…©Í™X¡ã ¢ íT:gÀ+¯§–P ñ9ñæ?  X96lPª tìÈé5±) ø«÷·Eþ÷…Î5Í„+Ü b8೺p5keP@Qø½A¡³Š‚dˆR‹kšrÃ<€€€è\³ø[ƒÂHÁ1U)(xã6ЇÌÔ¯¸Ÿœ§óŸ0nLÏøYïO[‹ÍZk œ5ÝÞFà,)L–pÞÇèy3~L¿f°ÿÀWкýªEöý|Ûð_‚Ä›ÑàF’´hgþl~±¯?×ÑÆ7ïãfsŒýŽÑ¦jÀ6SÑòMϱabÒO ÚÚ fàþø×Œø"9Ø?,6FE `* 9Øæ­Öe¨·ÌêG¶ÄËøûèg9y5Ö|åÆÏT&½Ä¸¿ D†õós·}/Q-÷•=—ÀCw!…÷äþóx8覵¦DÁgoÉ*ý¯N-÷6Etkj"·ÐØè™¿£øû›õ{[í£KðwßúþØ~ëjaÊ[WÝÀST·ŠWV¾«cXíoÈYÍ>ëÚÜíð~ß‚ï¸{–ûEîžæÏõKîŒ/_ Ò»ùëøÃ:~2ëÈþazˆ–‘ãd^5¨GqÛâØK‰ÝÊþ£xüá?€{¬ý¢Üã3ïø‘ë(ü,³ú®Þ‡/J﹇ŽIÿƒ3Ê12fD£ÐKÁ:ô*]ç1Q«ùBÊ1.•¸Ùœ¿ÑE=ë!-95X>³},ÐÍ“o“2˜Ÿë;'gæÏÊúM=þYÚõÖ×é_ÈÓ}þ}QÝþ¹4—ónÿla~ÿl¿ÿ¯qáçÏsdß§ò¤?~À„q³÷>ê›Â˜rtp>spW{‚4[âH£1¶T¡¼:èìšõÉ}‹œŸ”D„VtÚb//¿;Ÿ«€!<7ÿ„œÏC§m7´âׯ½qW{7sDØz Õè±^£>»íöa¦Šö]ÐÓUð}£÷n,aʘÐÉqïåu kh™]÷6[÷rhyœ¦p›7q„ãûÍr¸?|†[ðsmÞBŽÇ:Œ|\³Zžd$" F·h)ˆ²áøéîñÅÉq5œ¤ð¥5ý1è´d"œW¦á(:iÈŠÞèÚxƒS åXÉ¥6ãY‹Žˆ9ë:R¬¦¥z%~1Ž# |1œÀ ^3/Yå¢;´_Ò#„ç´WÍïï­avóÿ`Ñ ¹ÕU?àfÆ!¦„†Êèu~•å÷Ñ J5?ê`ÉÝp¹?QÇ&u (áÝÑÍ¶ŽšþÕEåÀüêý-‡€y)]UôÚSßRcV¾wǯ݉ L”„€ ~àÁ9°R”pmØï¡Ñ–/€}ÿ+Ãön^X³¡ØcÆø ˜-ü…I ð;~wÔíô&ïáó.J÷Ó¸YdL€›4»ãÉ(\ëC=概u‚톌Š wï†ølµœ®Ø£È™Æö¨—Öž™¢Wî÷TÇ#u4;½£ðYÔ™)^G²¦ÈÅ×á¤Ã»“ñ0|.ýÓ%9Ö€Tx„h@í½OúfuìѬÈZ9‡°5܆ž}}7GcèX Œü¿÷þ¼^ˆ=wõådvEÖZ}vsèkÕ~íõ;JW‘]n¼…ÿŒÑÅWðm|i >þ%+ê:†@xÓ¿dÄYQ[ø\¥´˜ø¤ÏDµýúM¡3ÐÜ‚~€bºÈ-焘Ӯ«ÕîõÂ3¬ `!»ð_ÞzNÛ?#$xOH0­¿'qÇ‚ø¾»ú“ ½ ãðý³Hýwâbk1/6eGåÏÃÃ5U†6Ô‰±¢ã§Ó˜Ë/4••ªÏÿÂÒø'“Úïµw^,æòi)g¼ÓÖúew¿ÿlæ+dói®+ú­æL¸ú³WÃóùt±è»˜¿µ¼Lÿým$pþÌEe¥4½8>‹zíB«—eUFËŸ¼W†qH[Pk8úN£û<>QzÚQ¶ïÒÜßüÂq½æp¢´»%èÄøéÒȨŸ=…÷îXÖ¢f›GqÆy,ttW vaî žïÂo`&'ã0ôl̦º›ÃíÝiȃ—‰üÒ ŸGFûœ$‰Õ5æÃŠa‡JBV(Ð[ axÞ2ðœpOöåq7Ü‚Gz~=FŸ¨1r<)uÃÝÿÃÕNo,·zýÞø;ã|[&È}'l5å­¢Ó°åQW}5]Lȇ„ùÐì,6G§l# Jû;€B¯VMÏ”ï$Løú® ƒ¯ÈÙæ{2xÏØ¥ØØR³Ûß“Çaöa-ÛýŠŠÞ’X—Ù²1lË}hÃãmñPÛ†£ÚAö¶»*+à;0zýÚk¿ž*Ãç^¿{Øýn§y[Ëê{«Ûqµ´akÜœ´Ôî¸6ŒÕs¼k ÙlÍaü‚îØõjvZ©Á– C%³Ø¦éTHÝg¶ 7ºuûnLçÂϦ³udà<ô9 ãWõþ Ýï^@Cïƒ^À¼}¾êU*T‹àtÅR j-ófÚZ*åVÿêƒÚpKî˃¶ÉÆ2Ø©¥ÿœ‡šN–Q=mš¥9.ÌYð8sCM<à%„w÷å=T%g‚FÉX"<ómØJ·á©ÊØÅðÍF€Ã†ðÒMxö¦´PÔ.V±¯ÎÙR}ëZ°o&…éŒi [ûƒçaØ"3Ž"µN0âìPkR7‚¾a¾©ÆüGô‰ÆŽ2Wn”pÜà©›mÛ(w³2Dü²Žøç4ÄGÃÓ›²ŒÀÁcÃ.A zõä4¨ÀÑ1Œ‰ô”:ZŽ]¹ª—róZãrÞÔ†„‚m-ðÒb* ‹…jæ¤ê™= ú™ rw© 7] €Ã8+ÌQ›¿ËÊ›jGc†Æ&}0´Å°‰†çÁ8Ýé”ç¡©¹2têàónàöKqªÀ6º4Ôǵ.­t¶Ãö2_¤¶Â]¥”­lº MBÙp‡&ŸºÞ E_ÃÏÜñV¯ §‡Ú…×|ƒI{ÎYoó—Ëêw¶B‘ÃF_¾íþò'j{Ôo§£Ö¦=P½ ÚŒ{}ÓÛE¥gÕÉõhƒ(ÔOb(…‘¦¬ÑŒmKˆmÔIËX•H}›_ƒÔ¢…R·&:È(ß §•Ú#Ê -#…ªH§Ã~Ï‹WŸéÌýA»?q~vâå óIìÖèBÛ,訌õî0ÏD>`ªRÆö; /=µÎo”áÀkМ»€QµäqCþÞU¼3ÞËAZ~WÍÑbÁƒ¨Ÿiå}kÊð}Wÿ=TÞ.<µêgç–4 öaÉOÓ¢~Ù0•®¬°†ƒaû&c.îÃÞ@"Y¢€\þ=Ð"Šö¡•¼Ûþ…û¤¶z °¶@ß[óöú°ÔïØbu7¼ö P˜ù%}½d{Šüm•ê|„<á\€-ðx/}7í:;¿Ûïøz`ˆ޹¿æ­ÅJ›~raÆrx~xå¾étñe”%OÇÑœCKc}Þê©>¾&vãø]ò&P~]Ñ4#üZ%—Þˆ‘«®h—ª˜€ó\ ½}1¾˜4Š'K–Êu·uÕëþͰ È äq÷âuòÞȽ¾J·¬ñýsx·9$*CäǦàBh9%€ñ ^iªsÙÇLF%iR€ÃôÕqüO6q3Ò¬ð¦º÷•®Õâ­Ø+’®ck ävÌî7 ØÜ<èf7xs`8©–ºFdfxóg¥û1±H–ÈÎðd£8‰?¨{jûý»o·õÛ·û ¨µ¨µhðì|žíƒ¬.ÅY´D×#þµß)'ÞžLYǽÞ•Ø‘W ‚¼†¼$>fky¥`È+C^)(òJìÈ+Ù‘7Mv”Ûº€¿’Ó¼ÿÌí(Ì1~àDáœ(0 °…% { P{8aÃ^ŽÑ9;¢û5¶á¢wË ˆÎ9–K÷Þ .®sAqÃqÝoò5ѹ@Œšs`9[kÅ•a¨áòwyà‹á\ çî Mžwy;îzc$á®à×2îò.ÜÍ=øp—Š»<;îòAp—„»| Üåá.OÁÝ#`Î l¹´ïÙÑ—„¾;ú vôõFJC_’™ak}úò>è+C_!(ú ìè+A_!ú ÐW„¾}õ‹yü0R€½B ìÙ±W´c¯7NŠözëÒb0ìrÚÇ6ƒ!¯yEväƒ ¯yÅ@È+B^‘‚¼ÚeT~ø(À]ѻƑüþà- /ØÁÎâ}®•]nJãh,¹ÝÚ+™“½âzMŽ)›¥æóÑBcc·‰lˆ‹ÿì¬ìŒ¥ÉZéäŸÊZÿþ‹DO•Hde9‰Ä¢¡êèë?xImrG9ÛçÁ *üÙÜÍ?¼ôÁ‹çðFÛ|½´Ó­£yÄzð½´sõð‘,¡+n¥êÓÖükiþÌ”„×–6ÐÏ‹œôÞ£ŸÕ§öþüÙGß–ÄÂú6\aý Åv.¾´×àƒmô V~~Øü'÷%7z­¶.¸hm£º6Kñ`·Ð½$K+g)ÐfƒOî.îÝWž/ž UY^^ÜMõ/8´´B!­ Ê¡ØîáM'—Û¿ÄRqéàç¡øÁBîòY‡ÜÊÛí!øoGM¼P§ÑÈÃòóöÀÈñý6ú[:‹\x~/¸¨ñ0ú­Þ|)ƒ‡'#óáöø}öÀ /ÿß–‰;‚•B§Ÿt‡+úͱG)gÐ+¹¥å}\w»Í¬+èìw:A„Õîz‚ÑùÆ»r âOˆ˜›Ü’žòÉí«V†Ë$V’Û¯cþ%d7ÎÖDóÅ™ùz±.n_ŒK•çbýmoá|S®"©×o{æÉv:I=vî")¡ÖŒÄ÷Ôüy›ÅHrks˪ââ>»}ò´Åí=lÃÉ’[¹•…JW)MªÉ£Æuåp?Ò4ÞVÞÒUÚ+>]Ô7C±êu©{¾“Q_62{»_+_jWÍ̘‚–ïà›Ó2@Š”#}¥›·YmÊ¥¡z¬ý¥¯´¡*J¶Òã27oy«I(f­P¹—ï²`…Ir«Yʪ‚zdLªP&·O-ð³Þç:K·¼ÛuõFyHTޏL¶Ç×üØ-ƒ/“_À(Qam|ÈàlO°A.sê Ò™ø¦Ð}R>Æ—Ö `|Ør+w.¯ ÄAÕÂ5Ot/[Œí¾‘݈.…bêòâpDZ«2yJ/Æ[‹ç÷¤A“Bƒ¶ÒÜÂÂÕ—cÉ`2¾o·_¸Z)wBp´ö­°8×OIƒrµçöuÐPlIÈÞVÉkÍÞv¸z]¹%ïjíãR(_´bà³ìе§Ëïkú §ËË`_ì»**W™W4(¿²ÛªÚwõNy¨\ÂAnTÊ>dÇéËUÒ ¡˜ò0Ú;°†u š;æÖhƒ¶•¯þ†<èqueá#79BƒifV]•j´A÷¶…ÿ…pµ‡½s4(Ä1'*©ë±·ÌU“8h=59¦ºÜ}Ù9! Ö¢lD2Š::]„î¸|V[ÙÎïD €ó#ç |éVôv5î4×l¼]¡AC1¾zÿV³­õË׸«JÄA£{jþmá,GôhEé‘ Åа;oå]m­®Aï\s­«’=\½?ìtScâ ÍÇíu4(”bîµßï”hƒ–¹«å›yÐÆÂ¤ùÒꃂQаW ~Hðe=SïÓ=ä®FâeÐíÄÕ×ë§ÝPŒ¸ÖëíÖ uÐÇÇÝñ5eÐû,÷pr‘p Fц=>yùvSÙX!ú0NŸQ}?M.ÝЭqg`âZOvÊÝ®Z&Zý¶š£ ZØ‹\s mP9:®£Aá(š¬‰l+“ë»,4é"š“…õÄ×Éû#tSqú´r¾¨úV\± *½.qGÇÒ”ê}ay+¾gp‘´¢¾,ÀAWÝì¡‘ŽÜ/äj`ÐÕ%Sï‡EmÐíx5…E£èŽìÖN–µAÆkvVx™\ßÛ<€ƒfÜ2õ’_Í7–¾Akç Joð1}ص³´}­{—¥ØÒTܾl4l+]¸S¥Ö’4œ›é—¢7ã³}0¨piвÛ\&câ†õ[*,ß^6îˆo'rdƒÛ¿OŽIo!ç——·xY=] ½{PKEb¥Å |K`k­A._[äá[ÒD÷^G¹ÁrNDTIz?Pò'{åíx\à·¾äÉo÷—";'×Õ3ë­M‹î×÷TòׇÜC#™”&”·¹Çã­É2é-ÐÇ¢‡‡Ï§kù«Uâ×…ã/|"¾}÷ߦܜŠ[4wÒñÜÒ¥|WÝÒ Fx¿¿*o\ïPÞ–V®•^‰òv/õXÎ]Ü[oí;Ú­}ÛLˆ ò×Çç¯ßÔÇj’òöæÛ»¨fÒ[±ã÷áê[·@þúöáÔÐ oVîLìv¿}ü¸BÜ1ùFØŒ¦ò5òÛîÍqm=é’ß>s¯Ëßö£ˆÅ®Ï:WñÈñ6ékEÙ|<wÎâqø6í~+”öOÎJïð­“ Af÷ñ]¶uÅz¿5JlŒ0 ²™­âÞâ7Ä4û¬¼ºrxR#O3=uãråpveªr~I]}mBkò"¿KLà_§À¦|+GV%Ì~ÛÚ¾Ù4wÐxÖÈ™£Â`˜‚7ÈÏã€9>o˜ƒ?ÓÛl%€–­ª…ÓŒ÷)QayótUSm¡ƒ1Ü­q™žHŒ@;çÍb·ø ÙÄ=âÉø°Ø ÑÚ×Uê ÈΡ T[`ç<âú˜mØÛ¯ƒÖ#}Phç˜ƒŠ¶A ÀÞ‡úÿ½1l½oð>h¶¹ˆƒ÷lç´³´´` Š´kP(+m†Úÿˆh´öÂQT õÊZs PûoÑ•=­sk6}Ì>,Ò)¨ƒBâ’ÞuPÈÇjûKŽ]åS@_@ã¿ô8žt˜Ú,tí€eAj=ÙŒ0ô¨Lßb·€k¶9„tÂÕ5%ðu*ŽùnÀ_e¨Ãí#ÀjR|ýäÀø(¥ÿ³Íí[Æ:„öYVͦÎm:ÿÖé`qËwe}òy Ltm¸5Šw.œ¬ _ʼv+1øÏ‚9À >€A‹`6w~¥ô­¦éÉ¢ÍûØÞÖV5†ý8£¥1Ÿéî2«ñéÒ‡ÑD_®5aî@ŠÅÀ(ð :ØŒ}f'æ *É­–¸‡ƒ|ýòü\‚æÃd…4%Ë£MJõžT¦·°–BÿhðÔ|.O òÆÄ9Òù‰@Gÿœãv5a}ÛüaÃo}àh%É7ï·¯.Žüö/u¤ã‹fÓØÖ‡FA+\_ñûþÕ›~~K*°<:»bFvÜâ#‹{^þ¸™³,ÈjT9äåÅå½Y oÂ=C‚»¾/A!ßRqݧDb>`Ê©“õTïË#|sõž¬GóÂÙwãk•¯>¨u³ ‘ Àúá’®”`W½?Û©Ò5ÄÛSðŸ;Ümê‚]ZÁ‡¶M¡ÊѾVÅÅõÃÆ,KCþ±ûP/i4D›ו/©« ÅŒu%–Ъȼý65B‚bʦz_IÛ0Ý$CžsÝÓô’]WÇ·i«~ÿA Àä@€y^‹¡Ié3i,)ôÀd¾ Þ™êZÂêcvº“£ ⪃Š|¹f65žìÞËT5¥ý£ï•vHáF‹–eØN]îë\9¢ ”,Gxjg™×arÓ=¯µšÜo BéKñ€Œ°©Rœ …ymÉ[a„6Ä´^Á¤À×—Š'¯ee=u–šµfD•–`ò×±ýíÔí\Õ-– (†b~ûûV˜Ì¬=é´&ߊx ®/ã;¥bÔCVZóaPéÀx¯ ´)íX4kí²’(;è£Ò=N–Y÷/óSéXéó­ ˜¢ÊÙU(6Ege¹h^&·twf(3-ÊJ6œg茪ÕM1‹×ÎbvŽp‘º_ËôÃ¥›ÛU»áºI¥:³vœÜoi|Ñ‹¯)A¦ƒ—=Võ:£é {NK|jª|Ù{˜”ÊÚy,:Û1*WÕe%tØÍ>7l4M n÷é;«±@Ûi•ÊB1†©a7ñÑ,qm*~\€e"vÝÒ˜ˆS·ô‰Ù;,Ö˜0u»ˆ*ÝWþSâuz™Î¯wà qЇ$±¤{HȈÆ.z¬ú;Г× £ÀÏ(fpÉ8õwsiˆöñÅy.->¥{óޏÄò~Ÿ÷®«¾];¤ŸYXÐÁ$¸Î%ÅÄÅâGvJÀØÀò¨øøú¬ I‡Ž‡¿gÃ} eÆ"svUúЩJÓ°hŸ¢L¿0+쑴Ѿs>ÌšðèÐ. ×Îæ@/‡NHãJx¾v± ?Ñ®[²¹lÅí˘|A¶Uwn|ìž `tèv¸| » £0CÐÁÝ7´Ytò ÐaÐe‘n™ˆ'íñ`U7Í@tçaÂìô*LáćÎ÷Uï5‡˜åì,Â^o«‹'ÃθYùJÀsg“=qí»È³ŸX9û±’ÓÎævŠÍ£òI…ÕKˆ±ŸG%ˆïß)÷,¹:³ŸêÌá¯7–¾irKðÔi°ºÐ`Wvqc÷ór¼ÀÙzúPÎøhJÄÍ#(qõÓÎÑìTù”X!p´Ë™9šµ/WÃ9p4õÈ„pë•£©oôCGC'ïdS v&ÌÌрЌÎNû— …ö/gæhÈ~Aý̬S ^æpöŠúy¤ípÝñeFÇ!›.€q~û–­sTwƒíèÐåqÃÃBõ‰,£“÷­GP×”„Õ_!3ÚSg8’ÛÉÀdC166 :óÔê½™¬'ƒÎfŽ~€q:N“?{e&çê}%ˆ)Pp ôã£È1Î&íðöLÛ‹&bè‡N9þ*9~š€:ãgèÌîÈJ¤²Pãc×sÓïï?H²0 Åm,F’…!w²±Þ“ùèM»Ê:|°S!ší.Î.Å®gviY»?»~M•…Á¤Ø5ƒ~OêÏ®5ú™FR6ìHðð'—†0$<å…Vä‹Éù§–†7^Ne=tJ‹èÆ1¨ë3û:¡m‰ ”AROß ±à£Q2kº «,çg¡îµ¸äçU``ÜÄ ê.Ñtbò #{žRp¸®ž+ÿp:ç”èDŠaDˆU0¥ FÚ-«X ù†Ñ“ÒÃHcˆ\³Ûû·ÎXz(Yˆ«tóS´-ììÃG´`òÅûôv6ž‰Ýcñ'c*†ídÀ¾“Žà[šVb”Óà[#2‡ñš”ãtªXU\OÖ‚Â ãáùrñóÅ<¼Œ¥ 3ã‘ÕÂê#Ê¡óΠ Åæ“CçAŠÍ'‡Î;ƒÎq{ÃÔ9tÞt¶lÁrè¼3èìÙ‚ÓçÐygÐ9³§Í¡óΠ Åæ“CçAçÈœ:‡Î;ƒNÏ}›9‡Î;ƒÎÊá-‡.é™AGõÌ¡óΠÃ|žÉô´·ƒÑk§gí£ÏX§dZ¯§KŠ_àöf+ÎHŠr±ÛȬžüÓ%ŸXrvO/€ÓiXrêÖ-Gýâ”Xáä̲±‡…tÏ– – '«+—ý;KÍi}fÞœIû®H:Öõ¥¦%2äì‡9§„e>ú¸Á<àä›2‡üÉ>¾c6„½M)T³öK ¢§'û…‚8,¾¯ÕYÜÆ¶¥­b1ŸQj>K  B‹´¿MHÁ AuñLžÞ*ë±a%‘Iæ§Ñu~ÆŒ*Y 3tFÍÏBg¾ÙC°€ÍZOÚ•ˆš·M€'ËѪOÉÇèuÆöÔX“L}SLåšÅþ ž<½m_ó<ËÖÜ$„HÇaÒí&éÔˆO¬Þ ôÄ~†,0GßÝØ[`Ïã³9[1ðòÀ|s‡Ž†x ¼Ç¤ÆÛ1ÉžZˆ<ð`RôxSdÚ¿â"iÿ¦‰"py0}÷Ï+Ï7'†ྸïA˜³()2Ø™EÎ<¢êƒCŒœ33%ÄèG!I¾ bvÇo^q†ÖÃL¿L.6ûeÏ7Q'vªßÒ?_ŽÒ…Õ•áX™¼öu·‰Ôí}ÔA>u¹v=Œ=¢*&”n£Kv¯uð.nY¬ëXÃ3â™*ǺCÍCOqó£}0ˆYiB p0äÈâúLpxi.{þWž,xùÆíz¤ð ¶Òv=rß/+Ö¡EÒ1ùAq[ø¥Çyd Ù¹=#Š!=™M“bÉø¢nÚô±‡q|i.pZvLÉAÄ 'o÷Ž<%°û>w¹ñ’6%1˜óʰ ä‘¡F§[iqÓÀÉî‘ÙæT×ÝâbqäcÓ±xd¶ùCç (SD©÷ÈPcàßæä‘K[ž=‚è€Á#bIC›Ù#³‹3x{d°ŒT¿ü¼<2†&Pz=9À&Ç„ÉlQ;WêÚYÄ?nœEYÎ#'qû’÷Ž`54-—ÉÈ©3:dˆœ ù§¡m&fNƒ±£^7‡±¦yßb!]˜96Sþ¨fñN¯çÊ«£¤Ø3…ýDPrý’* õ⺥#TŒ¼°ì8IÏâÞYDAG°_ê§ïó·#ûùçÇtÿØÌùpz´##nÞùpÁ"T§Í‡sÆõ5ç’=â̇›%[=N…8§|8#Ùž7ï|8Ý£8¯37J>é–€¥¹çÃ7·x…ZN•ç²Å(Ç:З2‡”Ž•Ýšê“/Æé¸d˜®[²ÄDº¢$¦£ýËÙÓë!bŒ„dèÇ}­Eà^ØÃxžr6P‰Ÿ9“ öã{©ïñ|ééóI'Ð æ CÂQLb @†"´Y`#f¾¶ì¸!»óÆiv2¬Þ_1PŽQɰzUt^Aûev2¼Íå6`ÔO2¤E©Á~æ@†°·-ô®­†ìp›bOå0°3û3~·Myx¥¡¯&qEð™c3¨aÒ<2Rï?昑 :›_FêýÇ2Rù¨3éfªŒT9z” Äï(© Ÿ9ðMÐ v22S?,æ“oF*û5Ð.-ç ÄãÒÔ AF=¤,"4GY‹ûl#Sá,>4['H*œ¡ÁÒüƒóI…à ÆäÏ™..˜ßrÚT8»rN©p^è’v^©pšW!Ót¦T8Ó?Ævåç7ÂS%rKµHL‘Wg-RåôQ´ŽÎ¨1Ž»Ȱ3ÊE†Áu˜–j¿dxÚÔ†ݨãÛE8À¸ºAŠ1ˆ,¯Ž #œÂÁðŽjâA÷iUãˆèl+ž¾{εÁKªòuóqó¢òÆ—K™ƒëÊB÷ YÙN6/B±ÍáS2þ®Ÿ‚–ËåÚÍ}­#,oE+š8Bî^ÌŸ|åÎ;+oã¹XŽrq W·§¶U{ ØÖZùî––ìvCMvS&Ok¼cP<ÃŽ«q+G”As ‹ùóÄ-ÙÍ3Ãn$zeØÕ¾\R]Þo¥_h¹X G.–£Ÿ$`ƒÚSÀÔåü’UêÕ™ìK\ö)Yg Ï »hMNSåj‡§”As ±ìq剞a÷è•춘£Z?[øBÖã‹ôŽdZ†Ý¹G.áñá}Ðjõ²fóÀƒaµ Œ¿ô\¼ÉÊfƾû”vb™óngTa~ZYÛeè1¹6W-Ñ Ö|›u*¢æŽ%N±|ä²W̽oÈ­#L~eWJX'DšÜ¯ p¢§ölËœglE¿ìš°ÿ”È1W`ReŸxRÆ,?Õ?æjªJr„)ÅB¬N^ßJr¬^8tíÙ\à4´‹yÿ¸¾ Eä|½pÓ‘cYŸQ÷5V×oJ¾µ˜Îš+`M‰èU`¨Ç>%è¾ñ¬,I wªËÓ;s6³f¦l:R.±9eÓ‘–š{6^æ›M7kæãôÇØ–DžW6I®›¾ñ¹eÓ±Ý2k6]‰‘]¨³À‰µxž¸3±–pE1x¶é-¥Ùo„•é+4<[Wc!LvQAù­»â JR½W¯j ­%œ‰ à™O‘&§%N¡¾d­Qí™r5œ&¡u5¿ †WCÖDOÚWߦ¨Së Õ_Ù]_ Í¡Æë–â©N«Q?3åsu¬\WO»*{rºý†CÖT‹@%2øðBÝkÅ•O´üᳬx½ÆÝlGäF…;ψf2ô«p nõ 3—E'V¸›¶R^0ò¡WÊ›K>ge.yIŒîX|ã³W¸sÖ{uÖ¸Ûb©pÇz«9 Ra*í—EטâÞQØÙ#C.,¦æÝ’šX+G[,.OÓåÅ8Í!ó‘á²ß{®´~fôf!ß8èg‰µ°J “Ãóï‡~/œG“™™â,—7u~»û :±ªï¾ of&C3?óàcÔ4& (ï”3†)éfJ³¸/7s»ÚvÌöéý–vˆyÛîìJ˜è9eæƒi†WtÆL1„SrÆ*¼•ß©–Ó«.ŰœÆ&L»µ‰É>»e(÷ˆÝwá_‘î•zSƒO¹G‚>VNû˜EÌWS®$?ˆ±ç¸–Óλù¦Öa\ñAìµgÏq…EòÜ"œõ̘éyÇ›S8xÜAdÑ/—©=®’Æ3Ò̺eEÙæcZŠÞÅvþ¶ò¥v{QùRUvv÷r¡X¹”n—Ë¥Ì! ãlŽ ÑëÛ§§{—uØ.Gý;r>ÜFäÎÊœÒ|¶Ü¿³µS•lùpÉõö - Oz]‰mD†¤AC1˜°EÏýS£µN†:(W»(QÍ-X9búî۳Ğ<­¯±AuØÖ’ª9(–šŠ!go^ë”Ü¿hœšš¦Lžxz^rcý¿Ì™†çQ]/{{ç•ù÷NL74²ÒjË ÒZÑ Kîk‡6h×+ ïìÆÆ-ixÇwuÊ …=[ñBç g®=EgâúÀß&¦¯‘ZÚ­3µËÞ7ìù•ô–‰S­.&9‚ÒinmÒwÕ~òôï¢Ê½Â&“îÛåN—†óªbF …¡zHèù?SNÉq¾&(†žmeÓtg©ÌrWñ‹kÃnjõñ$.û„ 1l²Åî*ÁB«<²ÒÈUÓd¥ùEhº±‰v̺óDÎ뻊ôXŸ7j†‚Lʯê uJöÓ˜wç§Å6%úˆe#wêÂ1X"YaìÐG5S˜S¿zßs(ÇÊ/.Þæ¥L yG»Ô{´q|Jw§9%¤L´ó{–TNš¦ôVô5˜÷ïjÕß²`ócÊ}öΈgëÞó¢TeùÿeŸ?OˆÑ‹lM1z‘Ÿ) –¥væJ¦k‡z ]¾Í¤”+Ðëj+ê9¬×€Y€¬9€:çŸÒŸÌšè¡[2d²æ2U1£À„½¢žG®(C k K– = =ÇŠ Ž`×Àx沑i§oÞ9€fÆk“ÚÓ¬Eù¼+²Í«(_0/Ü´EùBDm€6©i‹ò*²}BQ>2›wQ¾?œKQ>¤õÁ xŸZ”^-kžEù¨õ+g(Êç˜R#{o?Å#B.™Rƒº~ÖHUý¦ºŠP×oŠX¸)êúQ ¦Wõ›ÇÝP°®ßìѶ,uý|ã”æR×Ï»ªóÝP>uýX­®Ÿ•Žèy7ÔŒuý¼Ca6Ç<êúy+줢iêú9—k¯êGô)MQ×Ï;ž)äïÐeªëç½´Pl>uýæQÄ¿®Ÿ÷‚t)6s]?#áÎëVóÙëúyGœ‘s§L?ÂCOÌä#xͳ¶–Ùëú‘rÛ,ª›)+Í· ë T¬uý¼M]CSšµ®ŸmrU¿àõøæó>u]?ïª~³Ôãc?P¡çŒ«ëç†2RçQ×O?P¡TõÃrxgMOñ¨êg‹»˜¡®ŸçQd’¾/Áêú\ #;UΣ®ŸwU¿ùd¥Õ¼×¼€ñÍT×Ïû Ë•+:e]?ïª~3Ôã P$Ø«ßÌ·x˜UýæRÏW‰gÈæp×õcÌ{ FÛÎT×÷€])Š2S]?uý¼A ëŠÎ£®Ÿ 1¢7Ç}/KΓ»®_0¿å´uý¼& 7ON‘óô¨xWõ =èQ×Ï[1ÄøØLuý¼C×Iâ”uý( Ô«úÑNF‚Öõó>± ÅæS×Ï;˜˜];E]?*ÄP¦€ÿY[ =ï{víôuý¼…ƒ3‹sÚº~dáÐȦ‘p°ÒÈzLY“ ^—˜"×®¸X|Ë8»¡é“5ðÞž¶ètiY>,MV.ÙÈ>þŽ»¼c6 ‚ 4#ª€;»í–(Ì‹Äï“ÈjfùåXF UQu7²ò¢œeVckKâõ‘´+å’êë~f8‘—÷º…âÊöÝâ—hdœˆìÖÎ3ÑÛ¯¹µÅæõB%ö6h6–»¯£Õ\³ññ˜ë4^vÞžŽ_C±Ãn³X<¾ßû¸jò£ÃçæëY¯YÏM®ë‰øãc9™øv+};y?M®?’_vÆJ¬_Vq1v‡™·øºžøÒh_%‹É£øÖÇâ{ƒëÄEÙ^;¬<ÔÁZ"B餟\ogw¸·½ÅÕ.®k\}axÌÕOŽ_¥·½ªL^·–ÕåÔq .<¢gZn}T“›…ã;¸%”öÆU¯òŠúr°ÀeNºØ6áž^}_P~é–:®|©í6j›»›m«¤VGp¹ôqNVŸÏ6_/?”Aî8r}|˜D+ ňk<¥W–b7§‹…õ~)vÚ¬,?5÷7³Å¥£\ÒLÛt_]Í7–¾´HÖÔhm5¢ô20óˆ–Åf‹iTbiWO±¾Í· Õ ÝßZ²–fIÛùåµ¥¡­^—>®v2ã• à0Ål+Sª {;àéÑÁÎóåÅñî^îé8Y”6·kÅÅóNùá`a­T(Ý&«a£Kݶê×qxÂOVR±I-¾·¿ÏW¿®m”{r†‡›3¨¶ß>Š^nÞV…ǽNŠËÈ«PÆ/ˆˆUø5˜›Ã7qû2šFÇ5o_XFÆ—‘² ô@lg~®%ÑO@ÌçàçΪ~Êzì¦ÐßââÆÆSí1qwÈ=ÝyÙYoD0ïC|¢)nðd¾XÁ_”c-óE qÉwB1óUõ²ùl¾à°«‹û¯Æ‹ãZ)_oDeóYk\ÿšn£ÈF>^Å_Ö8ø,£‹阃 Kïü^®!ÀŸ‚ÖwëkÌìû,©5iøUøsÕd8‹Uâ{h”³´Ö¨+Ã~Î8tm<ßÞ;A?õnÛ_îxd¦p™ÛZ2sÔ|ÁÛ‹z+$rkcЋ´6 —X,pB¿ ¤X5UL|ÝYç®q”,Sc©ÈÂt[¯:ç=f=’úC–8sÖ#ŸYP7’—ëJnë2{¼›èÄ5jJ|iFþ‚5ß »ïÆŠí^_?Yè%$&7céײ•½M¨ ^kØ-T¾ìóÚWÚ'’þWÿRÐÿšÜ}E¤.Tò£+vT“gX®ìæ(†‘½I•¬dh;»‚I÷;u´h¿2‘OOˆd祥«càÁ»fJÆœ@ËÜëQjÒhrõ,ñTn àÒ½ ßg’Õ«›=Ê{=’Yâ㨼&ªƒ ~æW4Š—£Í,êÚ4únŠG ÖPø¤ù•¢[âàŸü†Æ2Ÿ/×îˆ.Àîu1ÿ/øÔòkRo'ëâzz5" Åô§$¤§ÃU6R_ó]“öAù«½òÓÛn*(ýR?:¨9¹D>´u¤…Êê]’ËÔw’p׎ðø1M7±Û0§e:»œi–¬°¼i*Ä®…‰žóY’†XXíY´¼žaó+[¦·ÖEu¡wêU$Ë‹ÛUÝ®DE›…xñV´d3znm×u5as¸‚+Sk\¬i~BÔ˜ëF¥Œ£ƒ››Ó]­x¯Âf/Žépè@ &´CÕûõUqiýŽøTIA6«i°èP ¯ÒÚ³õQDHZ« Gð×ãØ‚{H“Iú ÂË™Unê+Qëf(ù¢ðÅ­=K~Ù\ÐëÊ"¶Œ«và Gôhñí»0ÑlÝyK‚žÁ÷%{ûÅR’ìE‹Â0Ú…Vuèówá+~2¢•ªÓTQ›æ‚•¢“”yÛ Uk hr‰¯hr:Ž!`᱇¨,‰¦3.¬{3v®Wd¤Ae RØéÐ]ë¹ò¦)þ次v¡Ïû+¾ýËcÚFd6± ÎÛçV°.b‘'£‹MÁê"ÞZ<¿§ìd‚T€Éž³°w‘šr¦-ö”Xui*(ޱ,ƒ£t±)ØÚ¥ès b*ÅØ£9y­rú±qMÈ goLJbô™™¬¡4<×ï^9,;Î÷3+ؤâú©ãî¤ ™º£jde÷~7Jô1MŒ~ªJ®sËOVÉ5__ç“UrKçÿL•ÆÃ¥ü“Ur°/4zŽ*¹Åa>S%Ú8TÊ?Y%û•rÓ“7·lIÓ34%xó6®)ÁÕû]D+Z4Gz@fàç­v-ç2ãx©HÙ@fofý|À‹Ã!³ÛK <€Âè'øçv˜Ö m'ò SSi3§@}™lìgz7ã´vvÞK­%·׫¶ètó Aܾ:>4tgýøâR—ç[ù„ ãÀkò€ö·6“Ø39ºö­2âq¡ôår;Ó¹ÍÖ~†“Z‡ÛZŠñöÕ¨¤7©¯%Ö‹ ˜KAÛ¾~/uáåD׃wÿo+”/¤pA*äÙóI¿«œ(½—Þ œ ­‡2»û<9è kJ·{Ñý߸2lOÞ»ƒqx-œÙm–÷÷ R¥Ûvº 9õ“µ+ºËO÷É4Ý:¬áRª<ëo{ ç›rå™»ÝrºïâÞ&t߇b‘äÖÛF$Öå#©×oMø³¦)mšýæð kÊûP;s+ •®RšT“GëÊá~¤i©öHõ•ú­êGåKM&üîž´«l'_ïJOÇB3¸³?Û«š…†Œ»›rþ¼é=¶åI!ý~¼Ilgá2®à¬‚Y¬2‘Tbg>=ˆ$ϢǑd;} _lGVwÅN$ut³YùXP ¦ Ku“Ôv˜YëúÆ× "=Z$ÐÆý²…lG»½EB/½ï}ÌqñtF³»òc\ÿë[wE§8F/èçZcO3×à±]#«w¬Ä±aTîsVs{ò¸h ±¬8è`±¼i¼(¯b¬éÑ„EÖ @—/»Æ‹Þ|ñU7Ýê›+Ö3|äz9…¹#¾âc×÷ÓPXVÍ=’É ‚¿MÀ‹sýB=~žîX}?¢8ð¬†Dõ `aÝÂ6hf[µQ@¾IÐè$-õàcü¼DÝ®h›“9½MIÀ¿°±€ü`€4·U‹c£ Œÿ VÉÈKk/ƒåËÚF5ûÍ$¾¸n×oÎðcRŒÐ(‚iÊV·ŽN± ‡`Ý>Ômâ pV,Ôk;ËÝ‹Ê~g3¢ÓÕí oaò…€‰žDÿqÁ\rÖ‚Œ#ZëñДÎf[—Z7ßjì'À_@äk²¤õU€IsûØ·–,¢¿ìÇ0$·±ÁLúôg«@:߀À¶5.ú€ÉatYÒÍqM$ ôeœtW%¢Ë%šÈé“BWÁ!U"§«¢×UY“w€ì¡ÜÜ‹k±«¾AuoE'v>šÑ*Òfʰã!í£dF𴜆ÇÄ7¦ûÇ(ä"Õ2ä£EÀ ,haà Ù,w7·€àâñ5ƒŽ×V4Õ7Ž«Ý[;)MÊù¼t~oå\wÝ[êù§(çÙÔs‚r^²¶.øI*:GÕ®yüÄ“T´*tœú™'©¦óöSOR Xý¿­ Nè"z¬:¸{(‹'Íîx2‚ ¤ÇR÷¥7hÈß»JˆkÿÇÿƒÿæ‹a^(„I?$ø´Ñ ÅQÛ0Ÿ7c~Ìì*ãJ¯=î ²ò=¼Ý5.÷+áµ°Öö´]ÇÁl¸GмJ@ŸÔ#˜ácˆ ï‚ÿ¿ùüsâÒ9A”„b˜KK"üþÁ \ü!ˆ¼˜‡Oļ e‹è\6ÏÃ? Y‘φ㧻Ç'ÇÕpV— ´Š›·§/ óü8|þgÃGá».Ü38 ¹<_ ‹à¥œ” ¿‡DžKù¼õ¨¹|:+ÃbGÿ+ä‹ÚWù|šËòaW/åÐ3ø¨˜–²9ðU^­À oŽ×á9Ð^ á,'¦‹°ã,è°¿)Hi tc=°f#䤴À$Û³VFSð̆áPyÔ ¼‚}»çƒf V[³è!ü_8Çš“X„€9Áb y)œåy0˜½&Ççòè\˜¦ã ˜˜o|•ç ¥òÙ4¾Î‚þ ð!WÔŸë)†Û`e…´˜ËŠRQÊ#È ðkØH*Š ÐFëFJgÅ<€"z»FÌçÒ"j‡æ´ox!-D®è‘”CS¶€ŸO‹"k^ÐÖƒ‹Á¼x´|þx@…´PäÑ3>ˆP’¶EÐ-ìD( õfQû-ré<ø"Ëñ›Ê!øö—å8кˆ&ãø[<ì ~“Uˆ¼Ž©Å,\8 ÔP°‡“‚@Ä‚CÁ!¢hC8¡IÔ8¿/¢þÀÆ#R}Á¨þLä{¸¼”¾!àu 9–aÐ3ðC‚ð¹BNÈkÔ›ÎI…‚9A!ßo–ÃýáË0ÜêOº&¥Ã%ò  9mDc=+ä:ºÏD>]¸ùö­Ð °!Û#¸p c¾—%Pæ²Ö`ÚEÀšà“BQ‚lBH£ÅÁdÁ 7Ÿ5ðg`|~ ˆ˜ã ዘY€â|!g=i‡Ä¬.ft°Vb:—åµ9ð|AÀŸÖUÈkß™ÏÕ œ;ø# ñ<ݰ'€å‰íö Ð"W€­Ü$IDà Ù,šg¾˜/ZOàxÿ9{«<˜9zºÌòè Â_ȬÚIJRÞ|ÒÀŸiÀ¾òhq€5çЄ8È8|Ž$ë ʈ€f+Þ¬ ÀIŠ€ŒÛ¸ýY -×x–4&äôi#¸A6%ˆØ!ÍÁÝ£éÀžÐÜÀAÐ1%+äá´s`»à„,q$`ZÈ¢·pLTÁç´¾²Y¸¿è‰˜G EÛ°œ¶Oæ3°À%¬•¹R—·íS0<”Ñ*$‡_  Üúœˆ¹X@Û"B\…s$À‰¼õ¬?3…dBÛl Ö^IYïc­çBô“Ïsö_²ù  ¹(äÂVO&q˜ãa$fUD{bµÒ) d ì)ÏóÚÌ Å‚ÆåÈ#¦£iú³þŒKgóB l[m=àdpw5‰â°­7y.¶õÎ#Y!*™¬±n×EQ^“.N>ù+QWã™ýÁXSÎÂíáûh8tÂê«<ê†ß‡.¦©5JšÂÔG¤Ö­k&v*¿t/¹×êã‹*ÿÕ ËƒÁp,»#ð&ü¢tÕñP邇Ã'à£9PDOj¡ÿIHÈ”endstream endobj 1030 0 obj << /D [1026 0 R /XYZ 85.0394 794.5015 null] >> endobj 1031 0 obj << /D [1026 0 R /XYZ 85.0394 769.5949 null] >> endobj 1028 0 obj << /Font << /F21 1034 0 R /F22 1037 0 R >> /XObject << /Im1 1027 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1056 0 obj << /Length 1079 /Filter /FlateDecode >> stream xÚµV[sªH~ϯà1VÅq.Üfߢ²…àžÔÖž} Š‘ªD,!ÇÊ¿ßfQ7µ/[>Ð3óÙýõ×=¢aøÍ0‘É)×,®#CÛ|<`í ÖæDatƒ!Cg wVǺn"Û†6f:²ÁÛ%êm2ÄLÃÒÆ–Á‘É(èçôa2£T㈛ÔÔÒfÚˆé–ÖÒí_nyü:oûzôwú»f`da¤ÃX6ba2#ú…£1E–É!Þî'$*¡ƒ˜„"HU¤)@cýi4¦¦Ñ›foZ½i÷&ïL‚{“ô&íMÖ›}4`×Xþ¡ÎO‡¼–£ä«ªóªIž`ŒˆœÄ ƒ*}Uyª‹Ï§öÿ43‚!cÿ¤T÷W|`H„Ÿ/í*CE†išE9²t]ÿ¶Œz| ¿­#aôŽÅ{¯ÿVIúV²¯îë€û:`vWñrWŸ³ÓˆØ¹œé%F×úÁ&¡Ûš%± 1¿•¯/Ñ·ê6¢˜’Þ§Hg•Ÿ>Šª*ʃäT—òûYå*Ÿ È;"„<ªñG¹-vƒ™ì°”'io‹ª>¯ŸµÊ±Þ•´ª›üwퟲ×4ŽŸ§cY©åsQï¥ÕâÄLù©ôÜå W¨.&ˆ2èAïsðUx;eP”­"~lË_Å6ß¶t³ºµ”ûìµü•÷RÈNk†‡².6y§ÁuÂÇ+iðã1ÏTV…ZÏÞße"ÜF›Ý~$²‰Ëc‘WM£@ób'ƒ’ qFí’.<ÕjÑ,}qúèÄjÆOäwG?ü©7•#±{¤Eˆ‘´pÚNºÒ˜‚8þR †Š;aê{jñÅOÒŠ½¹O嶄ÜÑaqR¡~$¡é¢¥x‡|èë©ί‚ûËUà·¹ÜcÍäwéÅîF–þè<ûŸþÙ'*Ø™ˆë¶5|æ§¡—$¨å ¿¡âëýðÀŸ$¼èµz=+êï<ÊžEqU…OVžë;ÁS«qì¹ ÇöÄ o¦ÀEÓ#ó꼎ÂÄûc ¬À£rè,y§ÅuðÁêËÂQÒ$‚Äâ¶zÉ:hf;égq´T‰EI/² „ŒW^'^››tß`È:”NžZtq<ÔÜi¿nêGá°´v;Boøs/t½a¤¨ñ,¸ÂÓ‚ÚdXnÙŒñˆYo´N.C*ÇNì'Ñ:2‰®X³Ð»`Üo‹nŸ‚>ƒ²ŠÏЏòb蜥Óç3ûnËÜ\%”˜ˆp˄үäÛ«¤/зW ¥ËæOAôÞãú¢kÒ¤¶3‡ús+ð>;#奖çw^«¾7‘E¬+…â|{.KuþºE=¸œÜì½€‹æPdÝ€'*»éSGºgÂ=Û×õñ·Éä|> …QQmPÙz›ÜÜÚêýË $^¸ÿùõûå‘£endstream endobj 1055 0 obj << /Type /Page /Contents 1056 0 R /Resources 1054 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1038 0 R >> endobj 1057 0 obj << /D [1055 0 R /XYZ 56.6929 794.5015 null] >> endobj 1054 0 obj << /Font << /F22 1037 0 R /F14 1060 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1063 0 obj << /Length 2948 /Filter /FlateDecode >> stream xÚí]wÛ6†ïý+t·ö…°ø$€KÇqR·›49g?Ú^ðÈŒ­=éJ”[ï¯_À‘NÌM›6–NΉeKÃÏûCšM¨ûÇ&F*¬œh+‰¢LMæË#:¹vï½>bþ3R ¢¤î›Ä»S% Q†ëÉäÅåÑ__q6á’h£ÙäòcïKq¹°“Ë«ŽÏª².Êz}òÓå·­%6ãYóy:™fœH#LûIv2e”Ò㋲^UW›y½¨ÊÆêèü2£„ er’K´¤¬ ¥{su=é^¼ßŠÝ~ Bì}(»Çí"ÚqïS†$l×)N­{i\Ú3­I&™Ïió èñl^Ý'Sî^V»¯/«ùfé²y2UÆ÷ÅåëY~‘ös~¿AjB¦wdû=ÀpWÈÝゞDE¨óHQ¦š³8óqOÑ÷«fޝórñß¼=£¶€º¼Y¬£%…Þ`I ÙM 0ÄHÙRk˜”D)¨óHŠï¥ô=)“âFê{€cÄ#ña]\u¯å0.BeÏA2BöF“ 12¶Ô&#Fê<’!Rû«‘žŒË›"¨¾Ì oó¥ÿéìa]Ëîõîó/ßÎÜwã™Ùç‹MHæhP€! ‹ƒ’uÎ8'Æjçœ[Â¥ 5‹l«îòáÄïHxµ)¯òfˆÈo›1Ƚ«BžˆIÈähL€!† T Á$† ê¼Ç„iÂÍ"&<`ÒŽ$þb’—WéñŽ/2ù,©Ä!dl4ÀÃ*‚àÃuÞã@ÝQqq‡We+6åÏzVóŒ.!ã£q†NPQ§DN¨óˆ“²œX%c¹Ò, N§›ú¦Z-j7ã¹/vÊ•bu_¬Úk’ÞǺ$fm,ÐAbK1ˆD*  Ü9S’h­íDJŒR}]ÒU&V±ïV‹e¾zè¾y“»âuår&ø^ 1Q£)†P„‚D¨óž‚Ì­t(àž‚Ùm~ÿx PÜìÏ•âS\„Ôæb\@i.a`\ Î{.TF2eàB.ê"¿­o‘‘Q{¨!bÖF# 1$ *‰00$Pç} !%Qëkåkˆ³|~³(¯«aØÞ›ƒ„„$Ž&b„@‘ä0!‰00BPçý !8‘ïK KŠWÕê—¼]`¿jQ‘_ÉüåK^OBöF£ 14 :‰004PçýàÁ)™ìëŒÌ©ÙXG³¹­w·þ#ï«ÛfòkEöÜg!]£Y† P„…D ;ÎáÎqØô–V-\ÝD¸ÛÊ~qñö¥×¸XW›Õ<(^ü¼Y¬ŠeØOf+ñ©[ÜÐÙâÞŠT f  ÉήÓÔÆ‚tiÊ„ðkÕq‹û?xúAÔg§{Ýd¨}ÑeijÄaá=»bŽÇž]Ð9»¶4D¸I„ñƒ:ühA”Öó6·ÏÞ}€'ÄESsX<ÏPÈóh†€!ÆÔa(Æê<2”¹+´ÈüÊwÜö~S,«°´‹‘´òÎSÀ É 0ÄÀâ!à$ÂÀÀAGp¤%Bi»âk¼îõEÓî¶ŽËÎçå}TUvíígÖëMSñý™š¸~«öˆ˜¬Ñ C (B" ÔyAhÂCs oW ÚF½ÍÝ]µªC³Ì÷wÅ*¯ãÒA×Ñ.†‹¨bÈähJ€!F T*¦$FÉŽóäL€¹y ͬ_ÎêféÁâ¬*¤”_oV9Úíùä©0À¦0T=œ&p4,=;N“'ug5ºKOßíš/ã„øQZš‘’f‡ËðSΫÜÑç0ÄÎ+(L" Ôy\m–ɨ äÄž£SM·b;­ÊÛ‡ô²­K{f÷ ˆ˜³±@@Cˆ-M†H…;ïІ÷]"túu¶­>” %ųëaŽé­=0Ä´‡éG´O„i:WW´Îü=&".ü­Ê}ö"¿ÍËy[…®íDŸËRÈ÷h–€!ÆÔÓ ³”c uYR’0¦BE"Ðù¯îÛªD>Ÿ›p~§«OÈìhj€!F TÎS“£uÞ_}$'”éPŽˆXŽ\žX~\U·~ÓçcµŠ÷St/þq¢Ôñ"4Ô7ÅÐU©í‰Í‹esÛŽ°ì+»ü„üŒbâÃü#â'ÂÀÄGÇMaÁÝ™å½øqSøå"¿.«u½˜û›fz”1{ÜGs6`ˆ5A€H„:ï`šN-"´œ^-åb]¯@;*€âO±±õEô)­?0Äô‡ ú'ÂÀôG÷Wªˆæ<q.2[\—ywò³Cúy$qC2NYŸì'’ì¦Ð0AÒÎñÛ¾Žá›ðRq`(íxO­r#5Vú.†nýðôêÞMgÂs“U‘×›U±ÌT<Ø'Vc† Abåpç¸m††›öàáÌìzMê\Sb-ëx—ßVõ⣛ٻ3uîù£f„‘€ ÆØs"çà–Øa‰80ÒPï‘4eܰ.ÞŸMÅizkëL»U¼×>n¶œnêj™Ç½C÷œ»l_NüžÑâCL|˜~LüD˜ø¨÷^üÌMž©Ú‡}•7y¹ ó (¼6j¿~Ÿ¡Ñò÷v˜ú ÿ˜ø»A`Úc®û1_QBC·a£}ØS9«îbƒuÜ?<öÏ ?aöei]ùÖ *l½¿i;›VüLˆ¯lĹ­:0Äd‡¹ÇtOÄ zXWIFåâ.Jw_&´‡·Ù†«y|×UñïÿºX×EÙ܉©™úÊ4Y­90Ä4‡YÇ4OÄiŽzï5犘ÐNØh.£æëzubŽ›GB¿}‚ÇF@3ɞϲVÌÖh€!ÆTƒ 獵âÀX@½÷,0A4“…ðPŽn^í=ãcjOçób½Ž÷ÔÝWm…=¨šÏÛh(z;Œ   †Än˜ëÊH:ý"“ÎWÊÝØx|àoÌSHûh €!F”C*Æê=¬]KÓ¡ÆÈÂÒÕwçÿjšuÄaéê‹-‘%ÆRìÈ Îc‰ ÄP×0­‰ ‰n:vg.^7;s´Û–“ÔûbZPd,iÀ! êÍé i‰ °¿º‚¹îŸéO÷ÏÇ"&ô«¼ÍÎÏÜDg?n€ùàòÉËTo† „EˆÚ`¨øW~¦Ü“zÞxó?cĪnMîç£~¢“+÷¡o(Ö¨É/îJ˜u4.ú?Ôýäöhvô÷Þ_hgœJM„Úd¬y¸Sáæ{¢kÕY8|•Ñ<>É’æsÓw¹Ç£µ¿ÔÿØ4¾Åendstream endobj 1062 0 obj << /Type /Page /Contents 1063 0 R /Resources 1061 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1038 0 R /Annots [ 1066 0 R 1067 0 R 1068 0 R 1069 0 R 1070 0 R 1071 0 R 1072 0 R 1073 0 R 1074 0 R 1075 0 R 1076 0 R 1077 0 R 1078 0 R 1079 0 R 1080 0 R 1081 0 R 1082 0 R 1083 0 R 1084 0 R 1085 0 R 1086 0 R 1087 0 R 1088 0 R 1089 0 R 1090 0 R 1091 0 R 1092 0 R 1093 0 R 1094 0 R 1095 0 R 1096 0 R 1097 0 R 1098 0 R 1099 0 R 1100 0 R 1101 0 R 1102 0 R 1103 0 R 1104 0 R 1105 0 R 1106 0 R 1107 0 R 1108 0 R 1109 0 R 1110 0 R 1111 0 R 1112 0 R 1113 0 R 1114 0 R 1115 0 R ] >> endobj 1066 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 688.709 539.579 697.4212] /Subtype /Link /A << /S /GoTo /D (chapter.1) >> >> endobj 1067 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 676.5858 539.579 685.5919] /Subtype /Link /A << /S /GoTo /D (section.1.1) >> >> endobj 1068 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 664.4876 539.579 673.4937] /Subtype /Link /A << /S /GoTo /D (section.1.2) >> >> endobj 1069 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 652.3894 539.579 661.3954] /Subtype /Link /A << /S /GoTo /D (section.1.3) >> >> endobj 1070 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 640.2911 539.579 649.1477] /Subtype /Link /A << /S /GoTo /D (section.1.4) >> >> endobj 1071 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 628.1929 539.579 637.0495] /Subtype /Link /A << /S /GoTo /D (subsection.1.4.1) >> >> endobj 1072 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 616.0946 539.579 624.9512] /Subtype /Link /A << /S /GoTo /D (subsection.1.4.2) >> >> endobj 1073 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 603.9964 539.579 612.853] /Subtype /Link /A << /S /GoTo /D (subsection.1.4.3) >> >> endobj 1074 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 591.7985 539.579 600.7547] /Subtype /Link /A << /S /GoTo /D (subsection.1.4.4) >> >> endobj 1075 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 579.7002 539.579 588.6565] /Subtype /Link /A << /S /GoTo /D (subsubsection.1.4.4.1) >> >> endobj 1076 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 567.6019 539.579 576.5582] /Subtype /Link /A << /S /GoTo /D (subsubsection.1.4.4.2) >> >> endobj 1077 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 555.5037 539.579 564.46] /Subtype /Link /A << /S /GoTo /D (subsubsection.1.4.4.3) >> >> endobj 1078 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 543.5051 539.579 552.5112] /Subtype /Link /A << /S /GoTo /D (subsection.1.4.5) >> >> endobj 1079 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 531.4069 539.579 540.413] /Subtype /Link /A << /S /GoTo /D (subsubsection.1.4.5.1) >> >> endobj 1080 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 519.3086 539.579 528.3147] /Subtype /Link /A << /S /GoTo /D (subsection.1.4.6) >> >> endobj 1081 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 496.5559 539.579 505.288] /Subtype /Link /A << /S /GoTo /D (chapter.2) >> >> endobj 1082 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 484.4775 539.579 493.4338] /Subtype /Link /A << /S /GoTo /D (section.2.1) >> >> endobj 1083 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 472.3792 539.579 481.3355] /Subtype /Link /A << /S /GoTo /D (section.2.2) >> >> endobj 1084 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 460.281 539.579 469.2373] /Subtype /Link /A << /S /GoTo /D (section.2.3) >> >> endobj 1085 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 448.1827 539.579 457.139] /Subtype /Link /A << /S /GoTo /D (section.2.4) >> >> endobj 1086 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 436.0845 539.579 445.0408] /Subtype /Link /A << /S /GoTo /D (section.2.5) >> >> endobj 1087 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 413.5759 539.579 422.1635] /Subtype /Link /A << /S /GoTo /D (chapter.3) >> >> endobj 1088 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 401.4527 539.579 410.3093] /Subtype /Link /A << /S /GoTo /D (section.3.1) >> >> endobj 1089 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 389.3544 539.579 398.2111] /Subtype /Link /A << /S /GoTo /D (subsection.3.1.1) >> >> endobj 1090 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 377.2562 539.579 386.1128] /Subtype /Link /A << /S /GoTo /D (subsection.3.1.2) >> >> endobj 1091 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 365.0583 539.579 374.0146] /Subtype /Link /A << /S /GoTo /D (section.3.2) >> >> endobj 1092 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 352.96 539.579 361.9163] /Subtype /Link /A << /S /GoTo /D (section.3.3) >> >> endobj 1093 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 340.8618 539.579 349.818] /Subtype /Link /A << /S /GoTo /D (subsection.3.3.1) >> >> endobj 1094 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 328.7635 539.579 337.7198] /Subtype /Link /A << /S /GoTo /D (subsubsection.3.3.1.1) >> >> endobj 1095 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [532.6051 316.6653 539.579 325.6216] /Subtype /Link /A << /S /GoTo /D (subsubsection.3.3.1.2) >> >> endobj 1096 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 304.6667 539.579 313.6728] /Subtype /Link /A << /S /GoTo /D (subsection.3.3.2) >> >> endobj 1097 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 281.9139 539.579 290.7706] /Subtype /Link /A << /S /GoTo /D (chapter.4) >> >> endobj 1098 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 269.8356 539.579 278.9413] /Subtype /Link /A << /S /GoTo /D (section.4.1) >> >> endobj 1099 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 257.7373 539.579 266.8431] /Subtype /Link /A << /S /GoTo /D (section.4.2) >> >> endobj 1100 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 245.7387 539.579 254.7448] /Subtype /Link /A << /S /GoTo /D (subsection.4.2.1) >> >> endobj 1101 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 233.6405 539.579 242.6465] /Subtype /Link /A << /S /GoTo /D (section.4.3) >> >> endobj 1102 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 221.5422 539.579 230.5483] /Subtype /Link /A << /S /GoTo /D (section.4.4) >> >> endobj 1103 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 209.3443 539.579 218.4501] /Subtype /Link /A << /S /GoTo /D (subsection.4.4.1) >> >> endobj 1104 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 197.3457 539.579 206.3518] /Subtype /Link /A << /S /GoTo /D (section.4.5) >> >> endobj 1105 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 185.1478 539.579 194.2536] /Subtype /Link /A << /S /GoTo /D (subsection.4.5.1) >> >> endobj 1106 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 173.0496 539.579 182.1553] /Subtype /Link /A << /S /GoTo /D (subsubsection.4.5.1.1) >> >> endobj 1107 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 160.9513 539.579 170.0571] /Subtype /Link /A << /S /GoTo /D (subsubsection.4.5.1.2) >> >> endobj 1108 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 148.8531 539.579 157.9588] /Subtype /Link /A << /S /GoTo /D (subsection.4.5.2) >> >> endobj 1109 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 136.7548 539.579 145.8606] /Subtype /Link /A << /S /GoTo /D (subsection.4.5.3) >> >> endobj 1110 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 124.6566 539.579 133.7623] /Subtype /Link /A << /S /GoTo /D (subsection.4.5.4) >> >> endobj 1111 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 112.5583 539.579 121.6641] /Subtype /Link /A << /S /GoTo /D (subsection.4.5.5) >> >> endobj 1112 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 100.4601 539.579 109.5658] /Subtype /Link /A << /S /GoTo /D (subsection.4.5.6) >> >> endobj 1113 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 88.3618 539.579 97.4676] /Subtype /Link /A << /S /GoTo /D (section.4.6) >> >> endobj 1114 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 76.2636 539.579 85.2199] /Subtype /Link /A << /S /GoTo /D (section.4.7) >> >> endobj 1115 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 64.1653 539.579 73.1216] /Subtype /Link /A << /S /GoTo /D (section.4.8) >> >> endobj 1064 0 obj << /D [1062 0 R /XYZ 85.0394 794.5015 null] >> endobj 1065 0 obj << /D [1062 0 R /XYZ 85.0394 711.9273 null] >> endobj 1061 0 obj << /Font << /F21 1034 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1118 0 obj << /Length 3287 /Filter /FlateDecode >> stream xÚíYs7Çßõ)Xµ/RÕ;¸GE’³IlYkÒ[µ9ÆÒXž -'ÚO¿€i’˜¶àõ&–ĤÊ‘ìéfÿlƒé pÿÓTDYfÚ " *×Ó£bpë^ûöˆú÷ Û†ð]ߌþö‚›%V15¿) “›“RC㛟ŽÏ^_Ž/.Ç£“_Æß]ŒãY¡gZðæ”ÿ>úé—bpãøþ¨ Ü9øÍýQj-L„äD ÎÃ3“£ÑÑ?â Á«Óä'¡a\±ÄGa |”æEIZZ¢8ã›"ˆ!ôdHYQ[ͪE¹ªg·'C&‹ãªûåÉÐ(vLN†Ò½áñ=k¿ØÉv¥.\Ö5W]>÷´YÜÚƒ7P­`7„†ûj퟿ы{qõSq`¬ Þ+BU*²Â<+£úvAY}¨Úƒç3w¤ u %&d5›`ˆUc´Ÿ˜D1¨÷@ —D*c#1Üs6Ÿý\ìv½ˆÜŒªÅÇjÑÔÊŸ+*½Œ„Âç­æ¶ô– 0Ä`€‚`0$âÀ`@½{”µDhn# ¡W±õwÕ =XßÝ”+/ÿ´Z}˜»ï¿¶üy´1W¹@C„ƒ--˜èå Âî=p`4‚Åf ö^¬'“{_í·‹ü6=ÌMå^ ù$;½D„¬e 1" *‰80"Pï-‰p}H„ðD\-ê® W÷w^ÿ¶ø_Ï77®©>t"wP éÌFb¨@¹˜ìG%† ê= ¢8áÚtˆ Èå臋Hæ“ɼg肆¤iRB6³I†)P-Œ”D)¨÷@Ф„‹n´AÔ¡»ÑËAÈU6Àãjqˆãõ8இAe׸hÏÁÎ@ò×ê>Y=¤0‡&%&1`ˆEbªD ¨÷Ó„n" Ær9º8ãW'–Ÿ¾9}•„£yêc]¶o¯ÎOO´8_¸¿yB}Ï¡lõ!¦>TS?¦>ê=¨O7WzhTß>hŠ¢ac{jbCËÉÐHõd‡ !UÙC (†A" Ô{À à„10¡EÓq||Ÿƒ§AHU6ÀÃJaˆÃõî1–jL×Pú ú¦+·'2Ÿâ„eLX. ÐaK†T ¸÷ƒvúKÝ5 ”µ0\U‹z~:Ž­¼ÃnfŠšg~!´–ÐlX€!  ƒ% ê=À¢´ãCŠÞšˆx ëõÕ¸æõÛ±« Êæ#‚€!‰Ù€C (Óý€$âÀA½‡ËŸRJRØ8Îh:r÷ŠçøÄ6ů—+¹svýa¾h_•³ò¶šV³U#‡~’¼ô¢²—0ÄЀê`h$âÀÐ@½‡Ú!8)Tƒ8cßëøg3ø,'õ XŸõ¦ZÎ'®/r2äLæ5Ó°„„fà 1X `,‰80XPïNIÁ ÑÁâ{%§ë•«õʱò±‚Km\—DŠC_d‘ÆlD€!†” C$†ê=65ÔkŒÐ¶©¹úálô—憟 Yœ-îïVó_kwìŸ]®ïîæ ×¾Xûüée%¤3›`ˆ±åb¦Ÿ•D+¨÷PN 垊ƒJCÛsÕŽkÚÿ½®—õªjf<Í#^æùç5H!ËÙCŒ ¨"FP"Œ Ô»'H¸GËãÈÇä¤KÐÅÒc…8 ‚¡Ó™‹ 4DPÙ’ A%‚ î2E§b #¶àÀÒãùf]OnºUÂó÷«¿^}dÍY=éCr²¥†˜ô0ùÌöKŸˆ“õª„.ˆ‰Wãî~zäõ]5^ß•Ëêf§V(­Ÿq5d,†Îcè¡°F溫Ò# X5àª\]ˆ5À³áòüõÝ[ò‡Ôƒ¨l€!Æ‚÷ßc”Š£õÞa 1¤8 Xª)ˆl.¼„ɰxûÑéÅU¼sí®ò¯ÎgíãËz¶þÝ”‹?gÚ*~Èl !&!L"&a"LBÔ{'!Dë-ùg(8:;mTQÛúæ“rQ»q‡åìO†š­cg‡ÉÉûoËI‰ˆ¹î4dŒh!·ª±x¸ˆ¾ŸÖ,È6ºµ iÈb Ã4c'âÀ4F½w";M¹‚"ËVäÄzß|wyÞÙµ}9m«W>U‰•PX¡ Ÿ0[?`ˆé3ÈY¿~‰80ýPïQ?n Q†Z¨Ÿú ýb9íQp§ëOÖ¿°ŒñƒæÊ ·‰È˜Š‘÷ÞÉhQr»ç«?KÆPt©|”Õ6&"[f`ˆÉ Éœˆ“õîGº\ ¢¨µVøU8ý>n.íÍç“æ>hi“¨&$6`ˆA…ãý7G¦âÀ A½h#Ò(Pàe ÍÛåþ† íW_Û5¡&d6›`ˆQ•èIÄQƒzÔÈÂ=J0«¦ZjFwÕuýþ~jv[‡{)Ã+¾x=ŸNã¥Éæ}ü¢ìK÷#Bf²U†˜ê0ó¼ÿvÉT˜ê¨÷ :7D2Ø™×­êoÖ³n{–Y9 ª]G¯÷¾ÚÝEŒÎÏW/qHC¶ÄÀ“¦“8&1ê=\ÁçM—Ñv~拽ü±»zïWŽ•ñ®é—óò¦|7Ûò,Û+ûZ?¯›¥cö²Ñ†PÞ?[* Ô{øöSA„*bÍg¤[¢¾;‚Øàâ`;ôPZBF³i†-P1Þ¿,9F ê=ÐR0"˜‘-þâü¨œÞ…J«Êù¢Þ¬cúÀJ+!ŸÙ¬CŒ¨ÆJ"ŒÔ{ht˜möì!¼mt¾»ú¨ü¼CXÖÞÜ’˜¦°ŒF%@1ǹAC - yÿºÃT@¸w_l˜6„«n8ÂCÓtzsÓv0—ËÐS™ÿº¾ó€!î©û/,s›|¥óÚõ˜—lÍ!¦9Ì;¦y"LsÔ{Ð\)Â9—æ¬Góxƒ¤˜à\Öïb/öÅ|á,ͱýêe©È–b2ÃTc2'âÀdÞóN¡w¿·-‚œ·+ ›MW —‹q˜9Ø›ª~Yß~XýV5ÿîܶЛ½àÀ…ñ°¬ƒDÜ{çÝd­¥ <–­=¯É–”3R4[òn²µÙö®Ùê0æ«?=þåw‹rqÿxVK~éoRH_ö7 bß$(ÆD"Œ Ô{dƒ6ÏYãÙ`ž­É›2EÅyYM›9;«åai~P2$3›`ˆ‘ÅÂHIÄ‘²ç=Us©ÕD)Û.ÕU¾æî•ÚnÜ_®ê0§û¦z_-ªÙuÕ›¹xò‡Ö[h€ÔÛ­ EÿBx:$Sû^Sß)j¤;ð hT¬·ÉÔ¼¨Cßâb²¹™²Ùä‡êç:^éå#¤4÷› ‘oÖ–d'‰80^Pï¾ÓJ5'ªP4à÷¥Ýë´¾j¤†FyÙ ¢4;ŒiwP éÌFb¨@¹Dÿ%¶T*¨÷¸hƒ*J¤¢ƒeƒ oæCîg«ò÷“!·ò0ÅúPB*³A†(P* ”D(¨÷a‰LP˜å¼jÚ¡YݵBñ:ëÛey[=h©ÕÓ˜AYÊfb @0q`  ÞC»Â5‘´kVXÜKlÚîÚÀ@ÑFŠJŠÏf6(Æ Ð Ãd?ŒÌuW(˜$BÛ®Ea‡ås ©Ì†b”@©Dÿ"€T'¨÷ʉݰ†°C‹’` d)›`ˆ1UÀHÄ1€z#Û‚A•'€=l`ûí¢œNËÍ…\~×îÐâš Kg‡±äÂPÙ#sí»ÆnœÍ€zgކSbL!Üé›w•×ÿž­Ú# £Ìø÷ŒVåªêº.‘+Í›"Ç”ç’ì’  ¢‰Q"„$ÔuøÑM¸d±âöÿ éÓÍ—±ôÉÕžÚì_÷éì°÷Â!Ä$‚À~Ús·Ú'œÑ ÿ$0×óÙjÑÜû°O ·¤ œ}¢þHó47Mìß “áüíùƒº9TO »íîE°MüÕÒ!³$¹'ló/¥ÄúÎÿÛ¤v¿å*£Æô­’ðïâ®ÇÍÛr .¡4û§ñáUóƒ3Rsz\×ÈRîÍ À‡ú/T‘¤endstream endobj 1117 0 obj << /Type /Page /Contents 1118 0 R /Resources 1116 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1038 0 R /Annots [ 1123 0 R 1124 0 R 1125 0 R 1126 0 R 1127 0 R 1128 0 R 1129 0 R 1130 0 R 1131 0 R 1132 0 R 1133 0 R 1134 0 R 1135 0 R 1136 0 R 1137 0 R 1138 0 R 1139 0 R 1140 0 R 1141 0 R 1142 0 R 1143 0 R 1144 0 R 1145 0 R 1146 0 R 1147 0 R 1148 0 R 1149 0 R 1150 0 R 1151 0 R 1152 0 R 1153 0 R 1154 0 R 1155 0 R 1156 0 R 1157 0 R 1158 0 R 1159 0 R 1160 0 R 1161 0 R 1162 0 R 1163 0 R 1164 0 R 1165 0 R 1166 0 R 1167 0 R 1168 0 R 1169 0 R 1170 0 R 1171 0 R 1172 0 R 1173 0 R 1174 0 R 1175 0 R 1176 0 R 1177 0 R 1178 0 R 1179 0 R ] >> endobj 1123 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 758.4766 511.2325 767.4329] /Subtype /Link /A << /S /GoTo /D (subsection.4.8.1) >> >> endobj 1124 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 746.5446 511.2325 755.5507] /Subtype /Link /A << /S /GoTo /D (subsection.4.8.2) >> >> endobj 1125 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 734.5129 511.2325 743.519] /Subtype /Link /A << /S /GoTo /D (subsection.4.8.3) >> >> endobj 1126 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 722.3816 511.2325 731.3379] /Subtype /Link /A << /S /GoTo /D (section.4.9) >> >> endobj 1127 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 710.3499 511.2325 719.3062] /Subtype /Link /A << /S /GoTo /D (subsection.4.9.1) >> >> endobj 1128 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 698.4179 511.2325 707.424] /Subtype /Link /A << /S /GoTo /D (subsection.4.9.2) >> >> endobj 1129 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 686.3862 511.2325 695.3923] /Subtype /Link /A << /S /GoTo /D (subsection.4.9.3) >> >> endobj 1130 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 674.2549 511.2325 683.2112] /Subtype /Link /A << /S /GoTo /D (subsection.4.9.4) >> >> endobj 1131 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 662.2232 511.2325 671.1795] /Subtype /Link /A << /S /GoTo /D (subsection.4.9.5) >> >> endobj 1132 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 650.1915 511.2325 659.1478] /Subtype /Link /A << /S /GoTo /D (subsection.4.9.6) >> >> endobj 1133 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 638.1599 511.2325 647.1161] /Subtype /Link /A << /S /GoTo /D (subsection.4.9.7) >> >> endobj 1134 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 626.1282 511.2325 635.0845] /Subtype /Link /A << /S /GoTo /D (subsection.4.9.8) >> >> endobj 1135 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 614.0965 511.2325 623.0528] /Subtype /Link /A << /S /GoTo /D (subsection.4.9.9) >> >> endobj 1136 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 602.0648 511.2325 611.0211] /Subtype /Link /A << /S /GoTo /D (subsection.4.9.10) >> >> endobj 1137 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 590.0331 511.2325 598.9894] /Subtype /Link /A << /S /GoTo /D (subsection.4.9.11) >> >> endobj 1138 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 578.0015 511.2325 586.9578] /Subtype /Link /A << /S /GoTo /D (subsection.4.9.12) >> >> endobj 1139 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 566.0695 511.2325 574.9261] /Subtype /Link /A << /S /GoTo /D (subsection.4.9.13) >> >> endobj 1140 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 554.0378 511.2325 562.8944] /Subtype /Link /A << /S /GoTo /D (section.4.10) >> >> endobj 1141 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 542.0061 511.2325 550.8627] /Subtype /Link /A << /S /GoTo /D (subsection.4.10.1) >> >> endobj 1142 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 529.9744 511.2325 538.831] /Subtype /Link /A << /S /GoTo /D (subsection.4.10.2) >> >> endobj 1143 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 517.8431 511.2325 526.7994] /Subtype /Link /A << /S /GoTo /D (section.4.11) >> >> endobj 1144 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 505.8114 511.2325 514.7677] /Subtype /Link /A << /S /GoTo /D (subsection.4.11.1) >> >> endobj 1145 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 493.7797 511.2325 502.736] /Subtype /Link /A << /S /GoTo /D (subsection.4.11.2) >> >> endobj 1146 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 481.7481 511.2325 490.7043] /Subtype /Link /A << /S /GoTo /D (subsubsection.4.11.2.1) >> >> endobj 1147 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 469.7164 511.2325 478.6727] /Subtype /Link /A << /S /GoTo /D (subsection.4.11.3) >> >> endobj 1148 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 457.6847 511.2325 466.641] /Subtype /Link /A << /S /GoTo /D (subsubsection.4.11.3.1) >> >> endobj 1149 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 445.653 511.2325 454.6093] /Subtype /Link /A << /S /GoTo /D (subsubsection.4.11.3.2) >> >> endobj 1150 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 433.6213 511.2325 442.7271] /Subtype /Link /A << /S /GoTo /D (subsubsection.4.11.3.3) >> >> endobj 1151 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 421.5897 511.2325 430.6954] /Subtype /Link /A << /S /GoTo /D (subsubsection.4.11.3.4) >> >> endobj 1152 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 409.558 511.2325 418.5143] /Subtype /Link /A << /S /GoTo /D (subsubsection.4.11.3.5) >> >> endobj 1153 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 397.5263 511.2325 406.4826] /Subtype /Link /A << /S /GoTo /D (subsubsection.4.11.3.6) >> >> endobj 1154 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 385.4946 511.2325 394.4509] /Subtype /Link /A << /S /GoTo /D (subsubsection.4.11.3.7) >> >> endobj 1155 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 373.4629 511.2325 382.4192] /Subtype /Link /A << /S /GoTo /D (subsection.4.11.4) >> >> endobj 1156 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 361.4313 511.2325 370.3876] /Subtype /Link /A << /S /GoTo /D (subsection.4.11.5) >> >> endobj 1157 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 349.3996 511.2325 358.5054] /Subtype /Link /A << /S /GoTo /D (subsection.4.11.6) >> >> endobj 1158 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 337.3679 511.2325 346.4737] /Subtype /Link /A << /S /GoTo /D (subsection.4.11.7) >> >> endobj 1159 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 325.3362 511.2325 334.2925] /Subtype /Link /A << /S /GoTo /D (section.4.12) >> >> endobj 1160 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 313.3046 511.2325 322.2609] /Subtype /Link /A << /S /GoTo /D (subsection.4.12.1) >> >> endobj 1161 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 301.2729 511.2325 310.2292] /Subtype /Link /A << /S /GoTo /D (subsection.4.12.2) >> >> endobj 1162 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 289.2412 511.2325 298.1975] /Subtype /Link /A << /S /GoTo /D (section.4.13) >> >> endobj 1163 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 277.2095 511.2325 286.1658] /Subtype /Link /A << /S /GoTo /D (subsection.4.13.1) >> >> endobj 1164 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 265.1779 511.2325 274.1341] /Subtype /Link /A << /S /GoTo /D (subsection.4.13.2) >> >> endobj 1165 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 242.8576 511.2325 251.5898] /Subtype /Link /A << /S /GoTo /D (chapter.5) >> >> endobj 1166 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 230.8458 511.2325 239.8021] /Subtype /Link /A << /S /GoTo /D (section.5.1) >> >> endobj 1167 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 218.8141 511.2325 227.7704] /Subtype /Link /A << /S /GoTo /D (section.5.2) >> >> endobj 1168 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 196.6384 511.2325 205.3506] /Subtype /Link /A << /S /GoTo /D (chapter.6) >> >> endobj 1169 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 184.5818 511.2325 193.5878] /Subtype /Link /A << /S /GoTo /D (section.6.1) >> >> endobj 1170 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 172.4504 511.2325 181.5562] /Subtype /Link /A << /S /GoTo /D (subsection.6.1.1) >> >> endobj 1171 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 160.4187 511.2325 169.5245] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.1.1.1) >> >> endobj 1172 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 148.3871 511.2325 157.4928] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.1.1.2) >> >> endobj 1173 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 136.3554 511.2325 145.4611] /Subtype /Link /A << /S /GoTo /D (subsection.6.1.2) >> >> endobj 1174 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 124.4234 511.2325 133.4295] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.1.2.1) >> >> endobj 1175 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 112.3917 511.2325 121.3978] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.1.2.2) >> >> endobj 1176 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 100.36 511.2325 109.3661] /Subtype /Link /A << /S /GoTo /D (section.6.2) >> >> endobj 1177 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 88.2287 511.2325 97.3344] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.1) >> >> endobj 1178 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 76.197 511.2325 85.3027] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.2) >> >> endobj 1179 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.2773 64.1653 511.2325 73.2711] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.3) >> >> endobj 1119 0 obj << /D [1117 0 R /XYZ 56.6929 794.5015 null] >> endobj 1116 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1182 0 obj << /Length 3344 /Filter /FlateDecode >> stream xÚíKs7ÇïúüÒ½!øíÚ4õA”°DYnŸ„sðIçÄ:ã£SŽhÁÅú£h‰¬?‡¿š«#ÖRé]ÔWç³Õb>]¶·ŽPVG¸¾ðãj´ª®ªÙêhÈ=<®~£”Ï&«É|Öüd4;o^|ZŽ.ª£¡Qü ¥ñtn»+ï­¸%šSsyO™ÅÅ yq µ vChx_«ûï_'Wê{qíSq`¤ Þ#)Ò­™ìHQ½¤LfãéÍy•Eã˜KƒòÃbtu5Z -{Lþ$ÿ@!ÅÅC (¡4y€q`¡Þ#@Bí¨êÒPKãŒÚ^² „Tƒ 1P T(‰80PPï.ˆaNw ˜^P¾V· H˜ïŽœ=­Œö©µ2Ðô„œ 1¢ ¦Q‰80¢Pï‘(ƈ‘ÖtDÙ‡ ª¿Ùñ²(KNÈm19À#j'mžœD9¨÷Ží1ƸŽ×KÎt~q1™]¤:-C„ö°âí‘Qr/[ @]ŠK‚†@"¥â@½G€¬!–Æ–‡Ñ‡h‹Q3»ÀK”6•ÅœD;  FÉý 0H0×LɆ m±B3 a~úã•;»¬¼hêçÙÒ„ ùåh6«¦)^,‘J…ëN.£¥ÇÀOöökPÓÇMHo18À#Ê']D;¨÷ÄjÅ!<¼߆\Ì©ÁޤÄó{Ií^“³ð„ôà 1x |ŠåáIÄÁƒzð(ßó8) ­F­žZ0¼·Ï‹“}„tƒ 16ä@ŒD ¨÷ƒòâsÃ! mïÝ|ñÝ÷Ìž×ëCIùóY±Þ’½b6€!ÆTÇäËt©806Pï‘ )ýD ÈF[¦;¾M‡ËÕhüµi+>V‹oõxuègÅϲ‘©*b @) σˆõA^{«A6 ¼«å²àM½E³n/æÓºÓxFÍD‹¸b,€!†Ã"†ê=bÁ)áLjˆ…j°øq槯_Fž#?ùa;Ño«(ÎŽ=\ŒfË/ëA…2ì‹.q¥X@C‹ aL~Ÿ* Ü{ÄÂJ"(ƒ• b,>Ÿ4TœÌmñáß“åªæB¾41sÅ\CŒ ¨ŒÉoQJÅqz\N„بU¸‹×Õb´ZÏL×3Û媺j^ŸVËùͺWW˜«IMŒ•j·–dÃç/7ÚaÚ‚ìš|*¦,æ: «)šnõC€n6Ù§¥azÏ·Çw9*VbòC 0ýq` Þ#ÒaÝFy±†€“j1™ŸOÆÝp€Ž–m­a=·ø6šÖ_gáö½uI*Fb@l¾Â”ŠCõšHfå¼A`-úüz>_ø©‚æe™&$ä°˜`ˆ5²ùC*ŒÔ{$„K"¥Ù(=1ѲÅ^Á¥3Nýh1µ¼% õ?¸·º%¬Ú/¸²ä„Ü“ 1r v9‰80rPï‘Ɖ4z£:ÅdCÎéé²j§šßß4#Iû2£è2WÌ0ĸ€ÊØ|Y*Æê=rA)QTm”¥˜êúzx3kPÐb—zœÇëB>‹i†-P/Œ–D-¨÷Ža½å*¦Z^ßL¦«á¤]._‚IËdöe¾¸ŽÍgu)Ü¿ãNn î²Pª14D4ÞȲÍß§›ŠÑ÷56š(½95)‰ß^]¯Ú²õçFPý*PÿDŸrT @´Ãô Ø|‰)¦>æ:Н%Qn³ÂÄl£þ«óóõþ¦Ñ4¬rãWúÍh|¹î(œÖûSrèÒQ,40Ä”†évùùf*LkÔ{[qß,:¹FìzõºÛÝöÎíÛ!¡â»Œó 1 ".?GHÅñ€z<Ô7*¶Q‚âmò´Z^ÏgË*¬=L'cÐö7¯~£Šžž|öÿ°P­ü¾˜4EiÉä“ïÖÃÇ/bâÂôºüÝc©80qQïQÜ:ŒzŸ+—¥Ä=õsP[n¾öNìûW;ä§X}`ˆ©óïò Š©80õQïÝNhQ¯+S Gýçù´CøD©ˆzxtïm;Üìóä0ËQÈt1GÀã*éÑa"Œ#Ô{äˆúæD€C|˜} ŽúwÔ[·eÇ.£Å¼CŒ¨ÆK"ŒÔ{Ç wœm@Á ÿ장a²\MÆËa{ªFêv «ˆT¶ïôBÉÍ.ß×.ˆ®sÜeq[FZ»!4L1r÷ýëT2J³¤A ÁÝGH,%Æût8ý' Ùâ¨0÷ˆLdaÙ*†b0@5P`0 î# Ú nKçý‡¬7ËUu>üZÝæNÀà¶o¸båþ I‚¢mJ‹‰v/@0Fó5ŒD-˜ï‹ÒÄ*ËUœ?(-ýMWbGÆA¾Âb:€!†”å#ê>"¥_ÆßæÀ‚™×2Kˆ'S(Ñw¢©–rÿ’ÌbV€!Æ  e%Æ ê>²"8qõÑé+òAYÙbŠCÍ“o?BÒŠ™†P”‰D ¨ûȧÄI '¼ÿ‚o“ê{ê”égdFõ´Jˆg°˜ž¥)¤»˜&`ˆÑåd4_aO‚Ñ„º4Q?º0 ŒnõƒÐÔß²h§wÿ¤® jHk15À£ʆR“£ußQÜ!”‚ókyñ¶Þb‘¦†×w вö9.òµjwé.¥ "4mÈÉh~O*„&Ü}¤©~(w±$ÇíƒÐ´Í£fØþô\]Z‹©†5P6Fó»‚R`Ô î»åCf¡u)-RŽI¹s£âíuµ¾M<ׂYBB ‹ †!P"”D !¨ûHˆfõ¹ íÑ)o¦£õíÌ;rbÊcï$ r¶ù,¦%Úa°µÍß씈CóI‘Ž0NÙñ¨ˆ»mIwÞ’à/MH§ZÈ\1À£*ƒb‘ãuÁ†0 ŽØñ`´'«ßÎFWá¸O×çÝ•õV¤IÝåH¥öV÷˜bÝ!¦;L> endobj 1184 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 758.4766 539.579 767.5824] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.4) >> >> endobj 1185 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 746.6054 539.579 755.6115] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.5) >> >> endobj 1186 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 734.6345 539.579 743.6406] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.6) >> >> endobj 1187 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 722.6636 539.579 731.6697] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.7) >> >> endobj 1188 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 710.5931 539.579 719.6988] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.8) >> >> endobj 1189 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 698.6222 539.579 707.728] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.9) >> >> endobj 1190 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 686.6513 539.579 695.7571] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.10) >> >> endobj 1191 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 674.6804 539.579 683.7862] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.10.1) >> >> endobj 1192 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 662.7096 539.579 671.8153] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.10.2) >> >> endobj 1193 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 650.7387 539.579 659.695] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.10.3) >> >> endobj 1194 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 638.7678 539.579 647.8735] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.11) >> >> endobj 1195 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 626.7969 539.579 635.9027] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.12) >> >> endobj 1196 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 614.826 539.579 623.7823] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.13) >> >> endobj 1197 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 602.8551 539.579 611.8114] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.14) >> >> endobj 1198 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 590.8843 539.579 599.8405] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.15) >> >> endobj 1199 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 578.9134 539.579 587.8696] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.16) >> >> endobj 1200 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 566.9425 539.579 575.8988] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.1) >> >> endobj 1201 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 555.0713 539.579 564.0773] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.2) >> >> endobj 1202 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 543.1004 539.579 551.957] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.3) >> >> endobj 1203 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 531.1295 539.579 539.9861] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.4) >> >> endobj 1204 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 519.1586 539.579 528.1647] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.5) >> >> endobj 1205 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 507.0881 539.579 516.0443] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.6) >> >> endobj 1206 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 495.1172 539.579 504.0735] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.7) >> >> endobj 1207 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 483.1463 539.579 492.1026] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.8) >> >> endobj 1208 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 471.1754 539.579 480.1317] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.9) >> >> endobj 1209 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 459.2045 539.579 468.1608] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.10) >> >> endobj 1210 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 447.2336 539.579 456.3394] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.11) >> >> endobj 1211 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 435.2628 539.579 444.219] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.12) >> >> endobj 1212 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 423.2919 539.579 432.2481] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.13) >> >> endobj 1213 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 411.321 539.579 420.4267] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.14) >> >> endobj 1214 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 399.3501 539.579 408.4558] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.15) >> >> endobj 1215 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 387.3792 539.579 396.3355] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.16) >> >> endobj 1216 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 375.4083 539.579 384.3646] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.17) >> >> endobj 1217 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 363.4374 539.579 372.5432] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.18) >> >> endobj 1218 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 351.4666 539.579 360.4228] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.19) >> >> endobj 1219 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 339.4957 539.579 348.452] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.20) >> >> endobj 1220 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 327.5248 539.579 336.4811] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.16.21) >> >> endobj 1221 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 315.5539 539.579 324.5102] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.17) >> >> endobj 1222 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [527.6238 303.583 539.579 312.5393] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.18) >> >> endobj 1223 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 291.6121 539.579 300.7179] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.19) >> >> endobj 1224 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 279.6413 539.579 288.747] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.20) >> >> endobj 1225 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 267.6704 539.579 276.7761] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.21) >> >> endobj 1226 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 255.6995 539.579 264.8052] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.22) >> >> endobj 1227 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 243.7286 539.579 252.8343] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.23) >> >> endobj 1228 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 231.7577 539.579 240.8635] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.24) >> >> endobj 1229 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 219.7868 539.579 228.8926] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.25) >> >> endobj 1230 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 207.8159 539.579 216.9217] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.26) >> >> endobj 1231 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 195.845 539.579 204.9508] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.27) >> >> endobj 1232 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 183.8742 539.579 192.9799] /Subtype /Link /A << /S /GoTo /D (subsection.6.2.28) >> >> endobj 1233 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 171.9033 539.579 181.009] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.28.1) >> >> endobj 1234 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 159.9324 539.579 169.0381] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.28.2) >> >> endobj 1235 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 147.9615 539.579 157.0673] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.28.3) >> >> endobj 1236 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 135.9906 539.579 145.0964] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.28.4) >> >> endobj 1237 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 124.0197 539.579 133.1255] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.2.28.5) >> >> endobj 1238 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 112.1485 539.579 121.1546] /Subtype /Link /A << /S /GoTo /D (section.6.3) >> >> endobj 1239 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 100.1776 539.579 109.1837] /Subtype /Link /A << /S /GoTo /D (subsection.6.3.1) >> >> endobj 1240 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 88.2068 539.579 97.2128] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.3.1.1) >> >> endobj 1241 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 76.1362 539.579 85.242] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.3.1.2) >> >> endobj 1242 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 64.265 539.579 73.2711] /Subtype /Link /A << /S /GoTo /D (subsection.6.3.2) >> >> endobj 1183 0 obj << /D [1181 0 R /XYZ 85.0394 794.5015 null] >> endobj 1180 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1245 0 obj << /Length 3368 /Filter /FlateDecode >> stream xÚí[wÛ6Çßý)ô°ç¬ý ”¸Ø}Øu|IݦN×vwÏnÛE¢mžÚ¤#Qqóíp$S#mÓ4VsN}ã`FóÿEG™ýGGRe˜åF™Q9šÞïe£û·—{Ô]3öáU/®ö¾8åzdˆQL®®GBJÂäª1M2­éèjöýþÑëó«“ó«Ëƒ¯¾Ú;¹ ­BÏ4ãm“o÷¾ÿ1Íl_íe„-Gö‡ŒPcØè~OHN¤àÜÿænïrï_¡Aðוiô•ÐŒ0®Xä¥0^JûGIG¹4DqÆW/DNøÁ˜²,Û¿,š¦¬nÆLfûWW¯c‘‰}r0–ö¯ŸÉaÌoÖØ†øÂXTŒMlÈð–Zó›Q÷ÍÐ/Ø¡á¶~Ûí· RF·(ô@ÄÁðAÝ{|DN”’=>ÂásV½+æ‹¢Ãç›ÉÃC`©¬º¯gß¾³3ÍŸ)ƒˆø,&# 1D J”±aD"`ˆ î="\ÚaP÷ˆH‡Èëæ¶˜w,ü¯®*§åûP½_L›ò]aG.èsFÄg1`ˆ!UB‰‚!‚º§LÁ©匓œS ¡ÞÞ{n‹6kI¥ÊHF…¶îZ‹º+Öð#†³Ü]ðC&³I3^”7•ýÖ6mÉÜÝšBÖ“¡†TPUªH T¨û*JI®P±¨þòúâìåÙy-;ìqûrÜukÕÁØ| dý:zyñ Mæb¼@ÁP^"`¼ î/Ê’›òÂSx9;?zõÝñI»lȧÀ0þÙ‘R™J 4DHY“Š2>HJ,„Ü}OŠÎ‰æ$E¤b×SJlëZ˜Jr)ŸÕ„'¤8™ `ˆ%D Š‚„ºwsb•K¢íâ*ð£ÜœøÅÙù±_3-?=î'Å'?7Eµ(ëêovBL³ý&JÍÉs)³òÜÀ“Ïx2OÀã *Šò ã ußÏ[øê—(’­-³·ê‡£Ù³äÁ',™`ˆñ±2 ó ãuïï>,'ÆÈžêkÿÕËÊNFìO:3»‘#NŠOf2)À#Š…’ #ußT‘ŒiÀJ9Î'÷~è(æïüœu˜!ÁôŸzië3‘,40Ä„†™F…Ž‚ ºï…Îì]AQ(´/šõUúo&¥³šTÓâ—Ô6¹øT„TÔ¿ädE!¦(L)ezXÑH ˜¢¨û ¨4ŒdF@E}Yë¢XÔwOè²Z±Ï§6ò‘*74Dä^Ë7&w,DnÜ}/·¶“:–C¹}m겞þT4nûõ‹×¿¤ºúÈûý¿“Ü>ÉrCLn˜oḚܑ̂@0¹Q÷½ÜJª2(·trÕ÷VÛ7å]Ù¼ïÄ},›Û®$²µÖr"L¦\ hU…ŠÔ'sÂßQÓ[´ðOmj8H„OY2À#J‚ #bË=,úùÓFR(Bµ+hµõ¤l­®è Åt9XÕÕ¢œóI[sZ 'Î7mxZ€ÁvÄÛí®Ƈ°Àö°Dm¹UW$„QWÛÉWÓÙ¶ºr8‹0VͪZ»:Ü+;R®þ&v5–ô~çžÜï€!Öï  (F‘@0œP÷'ÆÆãÄ"uy{…¡ÂoðÝÎ뺉Œ³Ö]&üîò¤šÅ*ü†p™ûÿeÑ,ËY¬%M,ª~È~ÅÁßšX¯i2±À#2Cùð†w,ŒXÔ½+ÿ¬.×,Ê?ñ-LI-•š;–¦ƒðÚõbÎüe'Õ»n;©®î‹ÊN=¹âÏgtÄÊg>+`ˆa•E±Š‚a…ºwX £ §’¬˜Ãê»E8ß¶ÌÑaû{18¦e$Ϙvº¬¦í¤Åª’?g¤BÖS‘‚†RkªbHÅAÂÝû{«ÐŠp¡=SÜMÕŽßW“ûrÚ1õÝÃlÒ›³Û\ªÝl,NŒÏi21À#j† #fË}l$” <§Ô¯UW« «Jéþ¼^¾¹+·öþÕHƒùñ-œÐ–-·Ñ$™pù‹£úþ¾vò¿ínÔ67÷ír^ˆÝÚ&½Sù4'w*`ˆu*(# O$ "Ô½¿³‹Œ‹šg(LÏš¿ºsU»òâc=ÿÉö®¿w?ÝÖÝ7Ó‰÷G÷å‡,c7ËîÀQ÷›zé[¸„fÝòævD§ú `PpŸ“dÁ!&8Ì9*x$LpÔ}5˜&v^ågnÔ8«¦díœ>LêÚ•jW5¹T7ks=¿;XúóLçËû7í¶ƒuò' !ðiJ†b@P"` îT™qŸ|ý§}÷Nßo6zöK¿Ñðeq÷`»­nw#y K>ÛÉ,CŒ%¨&ÊR$Œ¥-÷±ioo%LuÞí`ÎØþEqWLü[Ïë¦.@ó§ÎÉ 2'[ ‹ò|0)°=$Ûnc‹kfï«Æ%£½›æy4«o¯k·MÛ×òÿ½šÏóEéçp†Øøø[a'pŸÐ‰­ßxÃ>$.µ@C¤¬ ƒâ ÃuïfY<ψ4,PÑral79ó[³¥¯x0³RÓáñùM†bð@ýPx"`ð î=-nïHŠÊ? àøÜ&ƒ 1p v(8‘@0pP÷.ììŽöàˆœó­úO‹Iãù+tØt|v“ц:P=ʇ«ÅÁÐAÝ{t#9=:²Cj -=Zè6(/>¥É¼CŒ(ÊK$ŒÔ½çÅ^žË¼çEu¼¼XެݞŒÚU¯?œ Ÿäd‚€!F%(FêÞÄŒ&¹Éz‚òŽ _½¬¯ýQ¯k;öpÉw}(H!ש AC¤5-1b áî=HZí»Õr¤;Ž®ìê§Ž ÿ¶ï¸®—mí“ïF£†Èå9™¡ÞC¨ˆ´ЦïX-”)A´P݉k;±á¼­ˆ®*|ó²p£Ð—墩çïׇ¦°¥r|~¹±÷ânÇSé<>µz ®GЧðuP>|Ú´†¥nÓg¬rÊ$#:wº« 7íBµ+ŒÙ›Às?×øQz¦W!¹kC¬oB•Q²"`ˆm¹vOžãñµ¥y½ÿ²¨Š¹ß }.æEx+ÜYu½zDCKâ`æ\ÛOîˆýõXGS1|ü´†eiÓg´#RM —]’Ú~¨mŸì¨Ü°4›¹eÿÂoc´Ob;´ÿuaÓ<ßõ8´¹'w±Þëa@>”˜í(0r0ßœLÙßiGëÈyQ¾¹+ë›ùäáö}K¸¹].onŠESÌ|Ç›ÌÊê¦#É.Ÿ .qÉDôv@”ˆí(0"0ßn>Mm™›Ëu§Ñ¡Vä·K«ùÆh{n­¨0¦\œ-ü˜òLHðK%Ø!$@=0"Q $ ¾= š“Œ‹@ëH8kßhXùc%ÇóÉu«¿1l7Y{ ,.©É°ôv,@2*†•D¢À`Á|{Xì %Sy€…w°€‡ ×Ó%,ß„#†ÝI IŸËxáR•Œ@o‡!„@ØŽC`ÓwlªN…!™éž^w0V*ß~¿k˜­¿*ßÌ'~A}¹|x¨çÍpƺ†Ÿ:Mï/Gfé X*†7êú¶°ìl8ŒM´(Ï uŽãî‘JÍÏXQ³Û`ñº„&w£ÞëF@.”í(0P0ß~$e’P©<(ݹ#åÞàÎz¾]–‹²}—MNw“@Ç¥8ÞCˆ¢³†æÛ£C9¡ÚtX‡NûŠònâN«ñݧ‡|1.³ÉÄôv1@7”˜í(0b0ßž˜ÌRâÞ¡zìÏ);Ç_4“;Ìgû˜…BŽËp29½FЊá}“H9˜oGŽ6„IÀ8_Wõ£;}\\ÓfñÅE±hæå´{¤ÉØ|²3˜ßg²ïÒ”ª~o†ˆ$À´ß‘sì?I&'Lë ¼ì”.U 2­«køØR¥óÝ(~¤C—ÓätfØÇ9ôza˜l‡€}”âØ?ÖTîŽ_ûBjÿrrÿàŸ¡}øðpWNÝÃŽÚ§í¨Ø| ò*…éAöfè#ƒ<Û!lQ>oÌ Ñ1ŠÛÿSJŒìžoúë>}¯ÿÀöó_ôГ4Ã[$i› ÏSÛ|•ÒˆýòrÆ{ÕxQÿ(Îlendstream endobj 1244 0 obj << /Type /Page /Contents 1245 0 R /Resources 1243 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1038 0 R /Annots [ 1247 0 R 1248 0 R 1249 0 R 1250 0 R 1251 0 R 1252 0 R 1253 0 R 1254 0 R 1255 0 R 1256 0 R 1257 0 R 1258 0 R 1259 0 R 1260 0 R 1261 0 R 1262 0 R 1266 0 R 1267 0 R 1268 0 R 1269 0 R 1270 0 R 1271 0 R 1272 0 R 1273 0 R 1274 0 R 1275 0 R 1276 0 R 1277 0 R 1278 0 R 1279 0 R 1280 0 R 1281 0 R 1282 0 R 1283 0 R 1284 0 R 1285 0 R 1286 0 R 1287 0 R 1288 0 R 1289 0 R 1290 0 R 1291 0 R 1292 0 R 1293 0 R 1294 0 R 1295 0 R 1296 0 R 1297 0 R 1298 0 R 1299 0 R 1300 0 R 1301 0 R 1302 0 R 1303 0 R ] >> endobj 1247 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 758.5763 511.2325 767.5824] /Subtype /Link /A << /S /GoTo /D (subsection.6.3.3) >> >> endobj 1248 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 746.6093 511.2325 755.6154] /Subtype /Link /A << /S /GoTo /D (subsection.6.3.4) >> >> endobj 1249 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 734.6423 511.2325 743.6484] /Subtype /Link /A << /S /GoTo /D (subsection.6.3.5) >> >> endobj 1250 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 722.6753 511.2325 731.6814] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.3.5.1) >> >> endobj 1251 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 710.7083 511.2325 719.7144] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.3.5.2) >> >> endobj 1252 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 698.6416 511.2325 707.7473] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.3.5.3) >> >> endobj 1253 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 686.6746 511.2325 695.7804] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.3.5.4) >> >> endobj 1254 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 674.7076 511.2325 683.8133] /Subtype /Link /A << /S /GoTo /D (subsection.6.3.6) >> >> endobj 1255 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 662.7406 511.2325 671.8463] /Subtype /Link /A << /S /GoTo /D (subsection.6.3.7) >> >> endobj 1256 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 650.7736 511.2325 659.8793] /Subtype /Link /A << /S /GoTo /D (section.6.4) >> >> endobj 1257 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 638.8066 511.2325 647.9123] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.4.0.1) >> >> endobj 1258 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 626.8396 511.2325 635.9453] /Subtype /Link /A << /S /GoTo /D (subsection.6.4.1) >> >> endobj 1259 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 614.8726 511.2325 623.9783] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.4.1.1) >> >> endobj 1260 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 602.9055 511.2325 612.0113] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.4.1.2) >> >> endobj 1261 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 590.9386 511.2325 600.0443] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.4.1.3) >> >> endobj 1262 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 578.9715 511.2325 588.0773] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.4.1.4) >> >> endobj 1266 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 567.0045 511.2325 576.1103] /Subtype /Link /A << /S /GoTo /D (subsubsection.6.4.1.5) >> >> endobj 1267 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 545.0077 511.2325 553.8643] /Subtype /Link /A << /S /GoTo /D (chapter.7) >> >> endobj 1268 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 533.0605 511.2325 542.1663] /Subtype /Link /A << /S /GoTo /D (section.7.1) >> >> endobj 1269 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 521.0935 511.2325 530.1993] /Subtype /Link /A << /S /GoTo /D (section.7.2) >> >> endobj 1270 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 509.1265 511.2325 518.2323] /Subtype /Link /A << /S /GoTo /D (subsection.7.2.1) >> >> endobj 1271 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 497.1595 511.2325 506.2652] /Subtype /Link /A << /S /GoTo /D (subsection.7.2.2) >> >> endobj 1272 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 485.1925 511.2325 494.2982] /Subtype /Link /A << /S /GoTo /D (section.7.3) >> >> endobj 1273 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 463.1956 511.2325 472.0523] /Subtype /Link /A << /S /GoTo /D (chapter.8) >> >> endobj 1274 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 451.2485 511.2325 460.3542] /Subtype /Link /A << /S /GoTo /D (section.8.1) >> >> endobj 1275 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 439.2815 511.2325 448.3872] /Subtype /Link /A << /S /GoTo /D (subsection.8.1.1) >> >> endobj 1276 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 427.3145 511.2325 436.4202] /Subtype /Link /A << /S /GoTo /D (section.8.2) >> >> endobj 1277 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 415.3475 511.2325 424.4532] /Subtype /Link /A << /S /GoTo /D (section.8.3) >> >> endobj 1278 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 393.3506 511.2325 402.2073] /Subtype /Link /A << /S /GoTo /D (appendix.A) >> >> endobj 1279 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 381.4035 511.2325 390.5092] /Subtype /Link /A << /S /GoTo /D (section.A.1) >> >> endobj 1280 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 369.4365 511.2325 378.5422] /Subtype /Link /A << /S /GoTo /D (subsection.A.1.1) >> >> endobj 1281 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 357.4695 511.2325 366.5752] /Subtype /Link /A << /S /GoTo /D (subsection.A.1.2) >> >> endobj 1282 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 345.5024 511.2325 354.6082] /Subtype /Link /A << /S /GoTo /D (subsection.A.1.3) >> >> endobj 1283 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 333.5354 511.2325 342.6412] /Subtype /Link /A << /S /GoTo /D (subsection.A.1.4) >> >> endobj 1284 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 321.5684 511.2325 330.6742] /Subtype /Link /A << /S /GoTo /D (subsection.A.1.5) >> >> endobj 1285 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 309.6014 511.2325 318.7072] /Subtype /Link /A << /S /GoTo /D (subsection.A.1.6) >> >> endobj 1286 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 297.6344 511.2325 306.7402] /Subtype /Link /A << /S /GoTo /D (subsection.A.1.7) >> >> endobj 1287 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 285.6674 511.2325 294.7732] /Subtype /Link /A << /S /GoTo /D (subsection.A.1.8) >> >> endobj 1288 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 263.6705 511.2325 272.5272] /Subtype /Link /A << /S /GoTo /D (appendix.B) >> >> endobj 1289 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 251.7234 511.2325 260.8292] /Subtype /Link /A << /S /GoTo /D (section.B.1) >> >> endobj 1290 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 229.871 511.2325 238.5832] /Subtype /Link /A << /S /GoTo /D (appendix.C) >> >> endobj 1291 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 217.8791 511.2325 226.8851] /Subtype /Link /A << /S /GoTo /D (section.C.1) >> >> endobj 1292 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 205.912 511.2325 214.9181] /Subtype /Link /A << /S /GoTo /D (section.C.2) >> >> endobj 1293 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 193.9451 511.2325 202.9511] /Subtype /Link /A << /S /GoTo /D (subsection.C.2.1) >> >> endobj 1294 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 181.8784 511.2325 190.9841] /Subtype /Link /A << /S /GoTo /D (subsection.C.2.2) >> >> endobj 1295 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 169.9114 511.2325 179.0171] /Subtype /Link /A << /S /GoTo /D (subsection.C.2.3) >> >> endobj 1296 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 148.059 511.2325 156.7711] /Subtype /Link /A << /S /GoTo /D (appendix.D) >> >> endobj 1297 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 136.067 511.2325 145.0731] /Subtype /Link /A << /S /GoTo /D (section.D.1) >> >> endobj 1298 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 124.1 511.2325 133.1061] /Subtype /Link /A << /S /GoTo /D (subsection.D.1.1) >> >> endobj 1299 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 112.133 511.2325 121.1391] /Subtype /Link /A << /S /GoTo /D (subsection.D.1.2) >> >> endobj 1300 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 100.0663 511.2325 109.1721] /Subtype /Link /A << /S /GoTo /D (subsection.D.1.3) >> >> endobj 1301 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 88.0993 511.2325 97.2051] /Subtype /Link /A << /S /GoTo /D (subsection.D.1.4) >> >> endobj 1302 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 76.1323 511.2325 85.2381] /Subtype /Link /A << /S /GoTo /D (subsection.D.1.5) >> >> endobj 1303 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.296 64.1653 511.2325 73.2711] /Subtype /Link /A << /S /GoTo /D (subsection.D.1.6) >> >> endobj 1246 0 obj << /D [1244 0 R /XYZ 56.6929 794.5015 null] >> endobj 1243 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1306 0 obj << /Length 2130 /Filter /FlateDecode >> stream xÚíœßsã¶ÇßýWèQš©pXüF“»ë4Ó^ۜߒ<ð$ZfO¢Ivzýë Š´ŠÀMiË7É Çã%c¹‹ý~.@Z0áá&N3.½šX¯˜æ '‹Í Ÿ¬Âßþr]›yl4Ç­¾¹½yó^º‰gÞ3¹½CçrŒ;“ÛåÓoÿñáö݇۳Ÿn¿»yw›NŠ—Í¾ùá'>YÿßÝp&½Ó“_ÂÎÀ{1ÙÜ(-™VRÆOÖ7oþ•Nˆþz4ÍuDKÇ´6Ó!PO@+f­õ«=3RÈcWÞ2`†ÁlÜšé¾Ø<¬Ë?Ïæø´˜Í…æÓ}Õ|Ö?µG»¸i¹ß®ŸÊ]ûÉã¡ZW‡/³¹VvÊ ç×{QÞ¿ÀüW2i!Cœ=eâ"¯»Õ¤=øg:Úͱáe¦/Ïßd”¿$J— „štZYf¬$´8z^ì¿Ô‹Ár[5ýSûñ/ÛÝçª^µoŽ'»?¶ÜÖÛÇý:° ”x¡D±ƒ%B†”D8G¤D™@(‰H÷'‰¤fV€GÉs‰ÚÌÿüXîýB½ýð±=8ìŠz_,Õ¶n?X¬«²>ÌæžË×j½ÆRâ ‚æýf¡$ÝŸ qXcP ¸*ªN¸Uy(–Ë]Ußm䚇_èFN½lB‹ºØ”—-AþNÐí2ˆ®¥~}åb×+‡ )åpêHå2PÊ‘îOÊ0`rú\¹Ç‡eq ®†Ë/A¬jÑ]þŽÏ]süÐNˆ«]±™¨Äk{2X(dH …3E • „ŠtŸ„2Þ3§BB™N¨zߥ÷S”i¹ÝUý¦E`å.•(‹ûrñ9¾©ê8´v›}{¸½k_¿ÿm{ ¸ £ÙjsRG†ê„ ÎaêèÓ)¡í„`Î[51Î2ÏáTWÚpÙfú·êÓ®Ø}éR[Þ•í%­^”!í–ë«‹_íåeUéoÑÓ9˜dHÑ‚å-úiÉBÑrá2ë)c4óNê£÷w³¹s~ú÷¢~,ÖÝ´Y¬½¹‰ÖÁÇÿ—dpÔåyÛœÈþœ óQ¹¸p‹¥Ã*üQNL˜é¸p­ïšÅ˜—~º¬B]–„Üáñ»r¿5ò¢ƒG2¤FÖ›¤,Eé>ѦãVBG›hi»ß6¦¶#n_·(È`Ü!…Lù– „ÂtŸp“œ¸Ž6ÙÍmåú©I‹1ûê´uz †ídG±†ÔCT —QP¤Q¾hàISiõ~_.æÇÊêMgäÔKŠ™Ì2¤ ÂJ‚1ýe¡0"Ý'ޏa",.;Žô9GÛ°˜ ¥iH­ô#A/)¦z0HÈ KI‚” „‰tAÒ^1¡…ê@2g -÷wíÎÅæs–ÆÒ¹‘¦çb”=#lH`t&$׋Q.#Ú}ÂÈ &¼«C{†QµyØîG„´Ùy>B1ɃB†BXD°ý5x. !Ò}BÈr&•ˆK>w†P€'NEëâS¹5÷#B؉ÙÌ2¤ØÁêíߨËB±CºOìhǤ3¾cÇÿšUY7·yõXU_‰¦˜ïÁ4!CŠ&¬'XÝOS&Š&Ò}¢I¦dÚÞÒNí§íçP_ #RWB*&}0RÈB ‹ ¶ÿŠ\ R¤û„”TLY×kgHíËájîŽSÔõxŠÌ2¤xŠ‚#Š¥L O¤ûÄ“L ˆË6ç˜*dHQ…ugû©ÊBQEºT)‹9P-UÍ/ËvŸ{±­ïšJŒ=¡”ä¡aC¡3Áõ—L¹@„h÷ !g˜Ñ:®é@_ Ô]âô8 =¡˜äÁ!C !,"øþ*)…é>!d³œ§…œAÍæÎëñ^îëßËM" F Rˆa‘Á÷?¨’ „BŒtŸ3‚Y¥ÓÂÎâYêßÛÇ]]¬vUó ­2f„i8>1ÁƒñA†>X@ðý·ßrPøî>š3ëyZÇ9ŒÏî¸Õ”žö#?ÏÆ(&z0FÈ ¾¿ÜÎBaDºO…öNê´ˆóFûøÀ¿¶j¼Ö½&^Q€Áx!C /,0‰W& /Ò}ÂKæOOcvâ»z¹GàÆ'ã¾zQÌ2¤xÊ Þ¿'• „âtŸxżPqé'Žè½y¯p[!˜Õ¸h5(²ã–±åÙY 4ÿie»–#£Wå0*5˜CdHqˆIœ˜÷2P’î‡<@f|\? qš÷æ lÇÛÊä8Ç]ª˜öÁP!C *,«àľV& *Ò}„Jz`T\1Š¸á¾¬÷'¨œ±#Mס)å{(MØ éLOý“ç!h¢Ý'š¬g\û¸€ÝF{±{(º/5c%öšWÀ$À`¼!…X@%– „‹tŸð2–Wqa)ºMø0GíŠz¹Ý4—?3òõ*`ÅÔ R`aiôï›æ¡À"Ý'°´f |ZRv[óÕ~1¿ß‹ùœ‹ÿ<>Ìšip$êJDÅœ& RDaMI¢2PD‘îQJ2ð2-ãNü¾\Èûbß<*Ç©êUÀŠ© 2¤ÀÂÒ Pý`e¹+}_Ù\rˬá>÷òá˜×Z¼ü ÒN_ã¦,“Ή|w%wÌ{Ó Öœ«éìÓlÚ*>ýæ¯Þ¶_:àÃìÊäüŸDZ{Ô©ÿPrðendstream endobj 1305 0 obj << /Type /Page /Contents 1306 0 R /Resources 1304 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1346 0 R /Annots [ 1308 0 R 1309 0 R 1310 0 R 1311 0 R 1312 0 R 1313 0 R 1314 0 R 1315 0 R 1316 0 R 1317 0 R 1318 0 R 1319 0 R 1320 0 R 1321 0 R 1322 0 R 1323 0 R 1324 0 R 1325 0 R 1326 0 R 1327 0 R 1328 0 R 1329 0 R 1330 0 R 1331 0 R 1332 0 R 1333 0 R 1334 0 R 1335 0 R 1339 0 R 1340 0 R 1341 0 R 1342 0 R 1343 0 R 1344 0 R 1345 0 R ] >> endobj 1308 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 758.4766 539.579 767.5824] /Subtype /Link /A << /S /GoTo /D (subsubsection.D.1.6.1) >> >> endobj 1309 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 746.5215 539.579 755.6272] /Subtype /Link /A << /S /GoTo /D (subsubsection.D.1.6.2) >> >> endobj 1310 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 734.5663 539.579 743.672] /Subtype /Link /A << /S /GoTo /D (subsubsection.D.1.6.3) >> >> endobj 1311 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 722.6111 539.579 731.7169] /Subtype /Link /A << /S /GoTo /D (subsubsection.D.1.6.4) >> >> endobj 1312 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 710.656 539.579 719.7617] /Subtype /Link /A << /S /GoTo /D (subsubsection.D.1.6.5) >> >> endobj 1313 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 698.7008 539.579 707.8065] /Subtype /Link /A << /S /GoTo /D (subsubsection.D.1.6.6) >> >> endobj 1314 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 686.7456 539.579 695.8514] /Subtype /Link /A << /S /GoTo /D (subsection.D.1.7) >> >> endobj 1315 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 664.8079 539.579 673.6646] /Subtype /Link /A << /S /GoTo /D (appendix.E) >> >> endobj 1316 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 652.8727 539.579 661.9784] /Subtype /Link /A << /S /GoTo /D (section.E.1) >> >> endobj 1317 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 640.9175 539.579 650.0232] /Subtype /Link /A << /S /GoTo /D (section.E.2) >> >> endobj 1318 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 628.9623 539.579 638.0681] /Subtype /Link /A << /S /GoTo /D (section.E.3) >> >> endobj 1319 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 617.0071 539.579 626.1129] /Subtype /Link /A << /S /GoTo /D (section.E.4) >> >> endobj 1320 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 605.052 539.579 614.1577] /Subtype /Link /A << /S /GoTo /D (section.E.5) >> >> endobj 1321 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 593.0968 539.579 602.2026] /Subtype /Link /A << /S /GoTo /D (section.E.6) >> >> endobj 1322 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 581.1416 539.579 590.2474] /Subtype /Link /A << /S /GoTo /D (section.E.7) >> >> endobj 1323 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 569.2861 539.579 578.2922] /Subtype /Link /A << /S /GoTo /D (section.E.8) >> >> endobj 1324 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 557.2313 539.579 566.3371] /Subtype /Link /A << /S /GoTo /D (section.E.9) >> >> endobj 1325 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 545.2761 539.579 554.3819] /Subtype /Link /A << /S /GoTo /D (section.E.10) >> >> endobj 1326 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 533.321 539.579 542.4267] /Subtype /Link /A << /S /GoTo /D (section.E.11) >> >> endobj 1327 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 521.3658 539.579 530.4715] /Subtype /Link /A << /S /GoTo /D (section.E.12) >> >> endobj 1328 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 509.4106 539.579 518.5164] /Subtype /Link /A << /S /GoTo /D (section.E.13) >> >> endobj 1329 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 497.4555 539.579 506.5612] /Subtype /Link /A << /S /GoTo /D (section.E.14) >> >> endobj 1330 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 485.5003 539.579 494.606] /Subtype /Link /A << /S /GoTo /D (section.E.15) >> >> endobj 1331 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 473.5451 539.579 482.6509] /Subtype /Link /A << /S /GoTo /D (section.E.16) >> >> endobj 1332 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 461.59 539.579 470.6957] /Subtype /Link /A << /S /GoTo /D (section.E.17) >> >> endobj 1333 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 449.6348 539.579 458.7405] /Subtype /Link /A << /S /GoTo /D (section.E.18) >> >> endobj 1334 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 437.6796 539.579 446.7854] /Subtype /Link /A << /S /GoTo /D (section.E.19) >> >> endobj 1335 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 425.7245 539.579 434.6807] /Subtype /Link /A << /S /GoTo /D (section.E.20) >> >> endobj 1339 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 413.7693 539.579 422.7256] /Subtype /Link /A << /S /GoTo /D (section.E.21) >> >> endobj 1340 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 401.8141 539.579 410.7704] /Subtype /Link /A << /S /GoTo /D (section.E.22) >> >> endobj 1341 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 389.9586 539.579 398.9647] /Subtype /Link /A << /S /GoTo /D (section.E.23) >> >> endobj 1342 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 378.0034 539.579 387.0095] /Subtype /Link /A << /S /GoTo /D (section.E.24) >> >> endobj 1343 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 365.9486 539.579 375.0544] /Subtype /Link /A << /S /GoTo /D (section.E.25) >> >> endobj 1344 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 353.9934 539.579 363.0992] /Subtype /Link /A << /S /GoTo /D (section.E.26) >> >> endobj 1345 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [522.6425 342.1379 539.579 351.144] /Subtype /Link /A << /S /GoTo /D (section.E.27) >> >> endobj 1307 0 obj << /D [1305 0 R /XYZ 85.0394 794.5015 null] >> endobj 1304 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1349 0 obj << /Length 2203 /Filter /FlateDecode >> stream xÚÝYKã6¾ûWø¨ÆZ¾$’9ÎL²˜`1ûèrÈæ [l[[rôèŽ÷×o‘U´¥¶zz’i AÐ@›¤Šd±ê«¯Š_2øãK“¥LZµÔV¥ãÙrsX°åžý}ÁIFe2Í””ЙyºÊ¤I3#ôr5^äíÝâoß ¾,Ís‘-ïîÏ{åÚ¤V*»¼+JÞíŠcïÚ›•ÈXÂo~¾û§©TÍý4[d©¶Ì„ ê¾mÊaÓWMMâbiS›‹þI{c’aï7÷‹ +qü¾i±Qº½Û}UoiŸ¡ß5mÕƒš'iɆÃÑEM+ÑVŒ <9'ªǽ;€ŠàוEû]áÝ¥³¤ØôC±ßŸpüP;lES‚H°9 üì'–e°„ë:×¥ „‘ xEË¢/P¬êâÊhPÕÞ¾ â—Áî6¬Õ GïÍø¦´ÕzèÃ"Ùœ?ü¨ß|]­"æ¹J¥Ê¡X±Tä1ÏS!gŒ%·›æèp…ø}ßlo¹ù`&͵KÞºö85ØÓNBƒÅp€ñK°o?||OñOÏëP¢ÀŸ2N‘š"‹%kDühÀUœá¥†ÃÚÑü]°ØjÎÂE‘ITð,·p¾àH/£MBïˆ~{¨JGÏÁòÕ›U "ì` X7MĘ B]KÕ%66èÛ ¨È)£™gãÎù¦C7¾~iÚ¾Ø÷ÿpûŽ ÞüØSv¤K,þtÍ}ÿ8R…%Çbó©ØRîå"ÇA»(UíáZôM‹@ *j gàs„LÕÍl±GÇ ô2Dhoš–‚îØÔ%Mñù™S¤œ}Y$Š„¶Û¢®þwvÉE©‹Î_ΜS¡D½ÁÉŠ&HjÏa‘i ƒøÌ^J@þ´‚ÄbÄ\·u¸k&ŒOe5!ÛÁ$£;ö‘<&Ê ¦S– 5§xQ;‘ ÐWTŒÙ H`˜VR‹ÔpØbg”ýe¨°¹AKB4B®©kŒ_èÇ ¢Z™<mÕ 4ÏÕ¸XS‡Õ|œÂ‡,N¾¶ƒ„"Ï•¾¶ƒLä3và:Š ®—´©Q®©· U/ËM·"˜d"µŒÉi¸Ôn¤,F¥²—œ; º¶²©üÚH°†ž7S¹FWÎ8 ât€²ÿ„½p*¡´ °{CE]ιKó4—9ŸÓļ¨É(,ýé©_Ãe×4=YO‘gœO¡FÁ5¸Û/±K‹[ž¬›ò4­?û(4*$ ‘“acr2œ¨ÈDfИ¸8ROq<ºº¬|öŸ9|žr¥cöŽôdÎô„¸¦Ý{lO€í!Uª¤ybB­ÈÇU¯wÊÂFð,à_hÀýŒ+á>¯ó¨ÝºZï«fÛÇÝi. ÐAEÁ$ëC‰œÊœ©&¸-jmGò!ªà—Çk—B?Á¤ó]EÐ…cJñY“Oc Ëî/«6%U›P?xömj*-èâý®ª¿²ì utœ{);C÷‘büý¤âF —°dëê>:Ñ+xÉ Ø‰êãµZ|{w~cs¨C)<3P7JáßÞü²øég¶,lùý‚¥ÒšlùÖ„Jñ°Pš,3qd¿¸]üûwΊzŒ …g5Ày Ö¢fD÷t©U<ÓŠûpb†Ÿ_IMÑÌRÁ2 r´Utç åÝWbö»2›À8œ›åx‹¯Óú¼ä jK(T>Sµ¼,y.]Ú_"yªò,{ÅC(eóIŸæþqp2µàâßp¦8ãY8 (Ú­•—7œbNR¥ Û>í(¸÷;ÿ>âZ) ·{&öî< ’þó7(¹kº~$ ¼*ð™÷{ Rô.ɇ[0]ôk÷HpíaúˆÊ×ç=:å×n„è§–SbÑ#Ë}Wýê96ú}¬Ê~÷ËÕ¿Ô•wã§Mš?:Ôÿ«´1¡endstream endobj 1348 0 obj << /Type /Page /Contents 1349 0 R /Resources 1347 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1346 0 R >> endobj 6 0 obj << /D [1348 0 R /XYZ 85.0394 769.5949 null] >> endobj 1350 0 obj << /D [1348 0 R /XYZ 85.0394 582.8476 null] >> endobj 10 0 obj << /D [1348 0 R /XYZ 85.0394 512.9824 null] >> endobj 1351 0 obj << /D [1348 0 R /XYZ 85.0394 474.7837 null] >> endobj 14 0 obj << /D [1348 0 R /XYZ 85.0394 399.5462 null] >> endobj 1352 0 obj << /D [1348 0 R /XYZ 85.0394 363.8828 null] >> endobj 18 0 obj << /D [1348 0 R /XYZ 85.0394 223.0066 null] >> endobj 1353 0 obj << /D [1348 0 R /XYZ 85.0394 190.9009 null] >> endobj 1354 0 obj << /D [1348 0 R /XYZ 85.0394 170.4169 null] >> endobj 1355 0 obj << /D [1348 0 R /XYZ 85.0394 158.4617 null] >> endobj 1347 0 obj << /Font << /F21 1034 0 R /F22 1037 0 R /F40 1265 0 R /F42 1338 0 R /F49 1358 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1361 0 obj << /Length 3199 /Filter /FlateDecode >> stream xÚÍÛrã¶õÝ_¡Gyf…âBðÒ·½6ÎL¼ÉÚL»É-B6g)’)k¯ï98)Ñ»Û6fü@8Îý«…„?µ°±ˆ3-’,V*»Xo/äâÖþv¡f€Vc¨W·ygÒE&²XÇ‹ÛÍè¬TÈ4U‹ÛâãR‰H\ ryûÝÛË•¶rùæý/¯®i|ýòž½ùÇÍíÛhü‹´òÍõ |ÔåJ©8‘Ë×ß½üñöíZW|äÕõí‡÷oþþúöêýõ寷ß_¼½°S¦¤A”»øø«\@à÷R˜,µ‹üBe™^l/"k„Œ 3ÕÅÍÅOãU¿u–SJ mb=Ã*­çXe3m<«n‘·iªª9”õ=ý\7õ£«û²©;šÈw—*]2ð¾sÊš¾…ëÖ»²mh6ôíà ¯®®ß ‡ÿ"¥¾ßïrÜø/uåþzÊÒ8±’€u‰ðÿ&žêL$29áé¶+à! "³ö Ð> gñ0옵 4­£…UÑ ¯HŽä•D"K“EbbÐ%“¸.•RËfÌó;àÙJ¥Ú˜åÏ—ZŽDtÂÿ®šáo”%"SÞ3àòßQ‡|4`‹ÿ†i)¬…³g5rbt×`pFúÉlù6÷^–ê¦pϤS_4ÂLyWì£)^2ÃW£S01ȳ'Œ=ç&8ì4MìÈÂáðÞÎ!磨»«mTÏL‰£ØL5;ÈR+ÍÎI+¦ fˆ.5 SþÖñø9q®a Öh; SU'À„)D®ã{ê“õ6ïhjd§*0qñ1…—Î9)pŠI¦Æ^£iúÞ*¨,’88/<ŸB5A)ò)™2ì–Òôˆ³*ø’È9°@¤ü júveß;þF9ïÏéƒñÃGm{· ¼Â1(h8yÄD ¼èi虂ÀnÃ3ä`ð|v^üÓg,ð-š5ª½å˹\Í£@n©v¡Fmꊞ»ÐXªKˆø4>”P˰++{vt-[~Ý7›½óv ¹Ïù¶­¼1‘KÀÉAcaÌ UÅ&ìa(N%q¢'R!˜X7Û6¯çÜœŽ D5q0Ç·“ë¯êµ˜Ë5‘Æ&¸Æu³¯ ºæÎÍ4KL&t’„ šýñL§ÌæTa“H ÖOÚi• &ÚyÀœu”P8“êdÀtö.Ê48Ôp•¥Ä:(ÏA½Zš©Ü#jƒ<<`Cp”ž£ <ƒÍ¿K¿6ÊÂ&PǦ¾ï^Ìq½© ò©3'FF¤*ÍN¨Ì ÷nwôÃà6ÓD$Qt’…‚ÎP§„Žá>C ö1!¼8&3òŠ€Wi2åÕ5g’5“o=4.ÎzïžùDfjlñaåÌ &“'縉ÑaYŸ²y™8܇£ ú|#ö^ /1Pøxï 0Áãá)!gH313J„6i¨^~‡³æ­…2ñ()F$á·1ñYÞÝó—eƒ©$ö$û¦ÈcUÈÙvò àáZKù„FTï¨Àiö’oh„Çt4¤"è=Z:Ú1Ar- C¢×= è»! r¶­1ÄK?6á "<쟫`ƒÞŒsÈq;r.}ŒBg2ØÑQѸ¶™QÕTDf’Ç`¸õ#BwÀ’ÎÿU°ùX¢¾¿s9‰ÏÃÕ|: A­ÓhðìC†¢vÓ7릚sîVÄzp("x%TfOl…¤¡Y£¼ëšuÉ!~c\¤‹#E³dˆf W1ðç²—q6£Á#MlJ8e§µÓžš?|ÍBf]Ì&ò dþq(±µôáC‡­%T¼,ZÞ4iï^9bT"E,í‰ëìömÛìú _38 ³!ÛgÉ>µnîÙ1LÚȾß÷þÏNõ]E·>¾]BÍ$Ô)2˜ò+Åâøô³Vöõ$ÎO)ªN ìT™žsêÐ ½_iÎû²¢J,™6Ÿ|õE&8)(÷å}ÍÕÜf¾ÚŒ¹£’™¥±¢“6P€³ìŽ0ܸݸÚK;ñaà±fãg=N3©—Î?‡$zVQTU+”­ •J©RöMàWã çR:?÷LW^ }®+M@m¡}|üù³G€ú ç§ ºrÚ½ð”éÔ鬋a¸‹ñÏgâ.÷(lÆoøâ…R3ƒ³mÝ«œÁ±ï§íU8Çùƒ‘“”¯XLЂÏ&`G¹EO’×<Ýó=P¸CéIë  å1Øpl­×|óë 4š t‘Œ!Ë×f”sÌ¥ òÔDMúŽÏè‹K(Ï£Ùjük €`ß<91ï—ÜúûÐzhÃ{J³ïªcï6£J؇ái [¨åý~5gë@ ½þ`J9ÿdÑÆÇVþ¢Ì!ûȨÀÌBÖ?e‘úñCΗ`ùX¹žŸš¦-zXæç-@fØ:\a½ã¶î7žÛù¨ß•=Éȧv)½»@2wl(kz+0h´zx6éqŸSS> u»žQ¶àðI¼þ˜CÍ-í‚f¡œoMoqÓâ›äÚµ|Éï™2VDÓWÜãÒ|õñþ[ÿ=êø_bàñLšê/ÿçã„ü?þ3R&\¼úß„m’è¥>#)üƒÕ9Mÿy•®åendstream endobj 1360 0 obj << /Type /Page /Contents 1361 0 R /Resources 1359 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1346 0 R /Annots [ 1367 0 R 1368 0 R ] >> endobj 1367 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [272.8897 207.1951 329.1084 219.2548] /Subtype /Link /A << /S /GoTo /D (types_of_resource_records_and_when_to_use_them) >> >> endobj 1368 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [190.6691 179.6723 248.97 189.0819] /Subtype /Link /A << /S /GoTo /D (rfcs) >> >> endobj 1362 0 obj << /D [1360 0 R /XYZ 56.6929 756.8229 null] >> endobj 1363 0 obj << /D [1360 0 R /XYZ 56.6929 744.8677 null] >> endobj 22 0 obj << /D [1360 0 R /XYZ 56.6929 651.295 null] >> endobj 1364 0 obj << /D [1360 0 R /XYZ 56.6929 612.4036 null] >> endobj 26 0 obj << /D [1360 0 R /XYZ 56.6929 555.4285 null] >> endobj 1365 0 obj << /D [1360 0 R /XYZ 56.6929 530.6703 null] >> endobj 30 0 obj << /D [1360 0 R /XYZ 56.6929 416.0112 null] >> endobj 1366 0 obj << /D [1360 0 R /XYZ 56.6929 391.253 null] >> endobj 34 0 obj << /D [1360 0 R /XYZ 56.6929 164.815 null] >> endobj 1369 0 obj << /D [1360 0 R /XYZ 56.6929 137.4068 null] >> endobj 1359 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F40 1265 0 R /F42 1338 0 R /F21 1034 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1374 0 obj << /Length 3430 /Filter /FlateDecode >> stream xÚ¥ZKsã6¾ûWè¹jÍàAäÑÉÌlf«ÆÉŽ•ÚJ%9Pm±L‰ŠHÙq~ýv£ %Á3›ÚÒ` øÉYa2¡Ë|æÊ<3BšÙj{%fÐ÷Ï+Écn ›é¨ïWß~ÐŬÌJ«ìlñ0™«ÈDQÈÙbýëüûnZ¼ÿ|}£Œ˜ËìúÆX1ÿx·øü㻟¿_|üñîúFJë°/çÞÅïiø»?Ý~¼£öÝí'¦Þÿr¿xÿ‰Ú¿ #ÞÝÝÃC^ÿ¾ø×ÕûEäzº3)4²üÇÕ¯¿‹Ù6ø¯+‘é²0³x™,K5Û^åFg&×:PÚ«û«Ç '½þÓ”¤Œ.2S(—•R)Q™2³Zi/ª—M³Ú\ßh+çÕáZó_Ä|]·õc5Ôkê:zvæ>Ј¿º]݃ôl®ç·'5ÝŽFï»f7PWÓi[žÂ¤ËWžtÇ‹vÔ1+ Þo?äb² íŠL:[ÂÖ‘ý»{ú‚ƯºÃº§Nvž—™2Îñ7 s[Á±³›\¹,×¹Vd¥1ÊÛ³Ú)w=€^Є΄SgB{C!LV”6œÂôÒL–2s¹úŠ Ð1ÄõuùžÎ I•!I‰2CóUµ#Ò¶ÚS¦^ ^&ЇĊ}³{lùKR_4éæËã@¢RÀ«VVQIÖ/Zž¶}G->|| H„¨…í?¡G\æ'#Ç )ú³O€Cs²ö’¿™Â¸d—#ŒCÍŽZ}}x®ý x=^P†?PÂz E Á4ÞyPƒžxe2b?>«žK]fÂZ{Š -ÑŽ‚²ù³Èƒ9!+¼Ô—¼\ |©².ç9†ú°mvU›XLçp²Âž.6l<*ãb=“6ïl×%–³6*e\ÒÞ’þÉe. ôêk¦Ÿ²‰:ˆ¬”§äe¬W_mGÄEÒnMšç„æØoÁ Võ~ :%4&GÛqv¯Òq7òlkàu¾'évm÷È+ÒDÅKAhpl†æ¹¹tûf•ôÛ öZˆùwïÞQ‹Öï]µ­·pA¤ßÀy†3Æw¶rh‘•c?ŠEjo2ر®át©¹?4§5§pžÏ´§ehÓc˜c½á%¶U?xxA~Εöß·Õ³ ªZ¯Ú꼑Ž×³oÆ!üº(Ø^pgk𻇔_TYMÏ£åEû}½j^i=¿ ¯$‚Ô‰l­¸7WÎÿ³©wDg³š<¥ï¶Á9 ¯«¡¢¤c²°‚9|(ç¸Ñ…›/®K5G?á `ÁÊ×qƒ$ŠÒµõ¡ò ý¹5¨4Ò&¸«‡—îðDÔ‡ªi ¡'.dŒý@#½Zи×<¿ÒKGŽ'ަ§²¤oRH5UŽ8 ÉpÿPŸæ‹ÌrŸôÏu¿¼£„ÇÍÈÝnñ­8?xÀ+S?ïKw Äó‹ÏÐÑõ/öáÊÉ' '¾ŠË8wœPÁî—M}XÀ%¤Ç°Ú«nÿJÝ>Òq. ³ôÄ é(¸Å>ô¨®ÞLè1Bã‰.±?Çã.¢¦íY\Ÿâ¾Àݾ%ðß%DÚ!ñ »Üç1%ÙTé^€ÿJð™æ©ÔYae‚¥ótIe6*0`ÂDà–z…x–Â\¤¹†”šmWùR/íùáL½PÞCð€ 6"×>Ø¢9`n"†ÈÉõº¡:´—,@il–ç²<5—Íq[ùˆÑ$xîI56Õž;ëø(®¬éù¶^mª]ÜP&ìÁ³‡3R,ˆÍÀ)4#§ÐŽUD ð™7š ‡šÙÌ(<õÀš€Þq^Á“iA¨^0d’Öæ§e#_àö“%Úd2wA³ºd)AgL˜3˜ÔgÍef¤6QøÈJ@^aNÝæGÄ7i‚˜!_U=Âlº—z¢ëJ²rI32ŸDYyú+)-•kûÚB8 ¤ñ ¨1@óÅ yy¬ NŠUVŸ“N'Ž<±g}#CìÒÒUy,d¯_!lV$Þãà(%^p¦,ã¡íkv™Iv.+r§HçV Ò÷Ðÿ­™ YE«À€3ÞŽñ•ÎßÒYie&DÒ?J/ bÑä½8׿€§]÷²ã@=U4’ÂdªtãL€Në4æN'†ï¼&[>þï|yB©t „Ç"L˜Œ GÁ›á#Fêè7=: 3I³|Œ &=UÑ¡Ã×§àé“ã.¯ðÆAA‘MqrŸXÁëS­û:Ι8ïËKBåü¥ÝÐ Ç3µ”‰.3*Õõñ~6^2^½øl|šarx ìI²:0îÏׂGóÊ}%Ÿµ£ ý`²&5Š|LKÝX„ZdNU59a¬<´I×Ñ>,ûmû…×:*†C·§Á-ÄÉ‹‹2Ë¿•… îªÚצï Ì&²·!4†F¨­ävþ‹¯­‰NWZV{Qi,n|—˜èî„ÍÝоü«/ÊÀó\ÕHÚVe.7æüZî©'¦‚/J± (S†kê© x&Ø„ð9j¦?&Áhk¸Â Ø,Ï\†ýuÜo\°øÒ‚Ó¿(ÐЊ眺—3óÛ…‹÷=Çl±ÈsqQ%Lõ|jx1'ë@·iÑNÆ€#À¡¶¾Ü ŽûÅ=$lVK» Ê±Õc|`Ã}Rã 3@´¡ú7NÀ>Þ²;œ~M•shøÃ‘sú—Gη˜®A¨ô}®vœØ23ZŸ•9F¡§@¢Ã/P—|©tì=€@—ß’žêzï£x‹UÄM‡Ä‰Þ Ç›®p«Î~—Þ×5߬÷ÔU­(ˆò7`WbQ5tÂeø©°ày¹’êïhn"jð™žæ‚ÕsÕ´Õ2¤ˆ|qŠB жg“`Õ°/²šªå:âX¥mzýjÊ)„ ^>"eoýu rLü¿S¢0%bÿÿþ[Õøï²Üeº(TºÂ¥E‰Á‘)< SŒsŠïáp_© 7?åµÁðϬËMý0K,Kendstream endobj 1373 0 obj << /Type /Page /Contents 1374 0 R /Resources 1372 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1346 0 R /Annots [ 1377 0 R 1378 0 R ] >> endobj 1377 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [519.8432 463.1122 539.579 475.1718] /Subtype /Link /A << /S /GoTo /D (diagnostic_tools) >> >> endobj 1378 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [84.0431 451.8246 133.308 463.2167] /Subtype /Link /A << /S /GoTo /D (diagnostic_tools) >> >> endobj 1375 0 obj << /D [1373 0 R /XYZ 85.0394 794.5015 null] >> endobj 38 0 obj << /D [1373 0 R /XYZ 85.0394 570.5252 null] >> endobj 1376 0 obj << /D [1373 0 R /XYZ 85.0394 541.3751 null] >> endobj 42 0 obj << /D [1373 0 R /XYZ 85.0394 434.1868 null] >> endobj 1379 0 obj << /D [1373 0 R /XYZ 85.0394 406.5769 null] >> endobj 46 0 obj << /D [1373 0 R /XYZ 85.0394 301.1559 null] >> endobj 1380 0 obj << /D [1373 0 R /XYZ 85.0394 276.6843 null] >> endobj 50 0 obj << /D [1373 0 R /XYZ 85.0394 200.1512 null] >> endobj 1381 0 obj << /D [1373 0 R /XYZ 85.0394 175.6796 null] >> endobj 1372 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F40 1265 0 R /F42 1338 0 R /F21 1034 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1385 0 obj << /Length 2469 /Filter /FlateDecode >> stream xÚ¥Ërã6òî¯Ðm媘!>kO“Œ³ãTÆ“k[™ ²XÇ#‚V´_¿ÝèIIôlª¶t`£ÑýnH¬Bø‰UœI.óUšGAŠxU47áêæþq#˜æÎÝÍ©~ØÜ|ÿ“ÊVy'2Ymv³½² Ì2±Ú”¿­E·°C¸Þ|¸¿½“q¸~ÿé㻇G‚ß}dìÓ¿Ÿ6÷ þÆáûÇ'øˆÛ;!’4\ÿøáݯ›ûÏ4/xˇÇÍçOïÿõãæáÓãíoî7#×ó›‰P!ËÜüö{¸*á‚?߄ʳxu„Aˆ<—«æ&ŠUGJyL}ótóÏqÃÙ¬[º()R%rATR.‰*΃DIåDõ.'Âuѵ_ÂP>m«®%äqo·"[Ú=/‡ªÑ‡ Ý[ spo¯®loêÃ=}5“Y£k»_XÃtÝÎæØ™%³Òñ†nð‘2ÚWe ‹A1 ÐcDZtWe¶‘È“èòÒ _GëO­¡é¡g`×!I p^/%$MÆ(7ÆÈ5‰ °£Èfk¶f_µ%á4¡ðºõQ×õÒ´[;Õ° ºQc€Z½­v"‹QÓM3´U¡-O”-)l}"̱rʉ½ÊèÛW%ŽÝ¡.d,L¬FŽvÈŸŠ!ÂdôÜ) Á—t7|fÔ ïõäÔßófss…½d䑈Ü^ÇJ±Eô]Mf˜ºÚô¡2= _E÷ ü–„ÙžèÛt½%¨{1¨9Ç ûh¤qëãµf:–¢pÆ’L³@dÀeèXêí°½æié.qDR ^÷,ÊÕº1º9°{m=d˜]=êmg Ü)¥‚$ŒÔ¹)ú…u Ôíè —ƒhèÉÁ¢0(AÄ#`¼Â04K²0=›ýö4nÔ€{¿šK¼®¿Ž§]Nw|èÁî»CuwnÜÄ-èçéÒ˜‚Ä­XztRÆC‹A¤DIf‹,õ·pçÁ2wøjš¬»BׄiÉ9ÆÀ:þÒQnŒÜ›ùÞ3 '¸U¼ x²®wÌçÓPì=—¬<<æà‡ Înدõ‚f2È’L±-±ˆ‡Cº¶<•¡‚ OÔíèwtòßùhK_¾w¿p*øtH•/ë×]÷uxY²þ/îWR0uô¤ ¼r]™ÖöxQAfi+™’ÿßær úQI¶®ïã¹g\·…“€LyÉ ®ê9Ô¸„#ÆÛ=ï jÛÓ úNXOêïè×ÎŽ'·Ÿ*`cZ¸˜‰F¿r¤rrÙ(œóíl ¦(ÊG¡ã™¼ ±cp€AÕZÈ/– ?r鼿3ÎA"Á6 wÕ«€½0UohN`K½VnP*yí"¯ Æ“2žæìoî ZŒƒ<³ Ç™ç7_'`ªë½Ïô§¶kOM7ô ÅA0ª`nNT̤ëÚ´ÏT‹¤¤Ø„ɳd­÷UÁTš>,$J¸%á}¢¶fNduÕ&©ZúZÏ["®¢óÇ&AÁ€] ©bJ¹bÊPᖌʛ۞.Rúæ6Ž×U3ŽÈ½þeôi¬‰7›_¨&&D(Mí£SßwEfW^Ö F ù 98 0s¬—ÝTJœeÈsBÌ*z(,¸–ø©;õ¡DÙüϺáþ•L$¡˜›Ì¤ “Y(N×eçÜç;Ë€Ao…*ƒŠ¤d–#`ÀBM°ºz©åÑU”L8‚L%2f ™OmAwŸ•ñév©*ÁÎ'¦øŠ²YJ ŽÅK‡7Ç]ÑÄñ‹E&!0ì)öñÇ`¨¼ÂU*ÍØrrB¸‡¬ÝïN4Ø‘I6´‹uO°¿¸_ÇÇÃXÆò–¬$8%¹ÔH ir^(°æ 7•¸]ë«Ù…bVëþíL+¢<*Wç’]ŒVfe>F8Nd"Ë‚H é#Oæ#a ŒÀ… ¶ŒèZĤ¤èæôÄ…óHf˜í2I)B‘!òvz¾ˆÈ4íp`h€ôQÓ¡¤s4Ô keGßÓ×ü¹×Coý6ž=Ý.UoºíN™U6¨ô]7´%vÑiÎ.ì¯AtËh|§— K¡ÍQ|Ç ê®wêB•!È #ŒDýž¦È¨£Ðs>+ðHËd4|®^ýæ}es·3×DbÊ…¢°4:¯uCÁP%ÊWÒÇB^BÅ…œ¦pÇÖð4³‰5E”b›îhI(LQ˜ósìŒËÄÚ+v"4ÐÄD;4[²ÜË ‘·Gt¡Öm®bê =‰ dg0­[BÌx†ÑyÇêÞKÔØá¹u¾#Ejr|¨¶uϳ/ºøj,Ÿe÷=†ç½G"ûVcLÖÇÂJÍý’<_±Z1F~‡tm@kÝtÉô•Åð¢®Çp§‘x¾Åx¶tnwº8m’¢©ý™è K•Ÿz«|œ45ï! þýƒ™oAþZ‡žpV½nÊ©9à ë#ÔÅÕ‹NøÜÕæ/wíi¸þááñ=A¾õšu?iÈâFdÕÀAº5TÀA›Þ‰n†“.Z§ô”ÎÞž¦J 7èüþÿPŠrla²Ö¯æb§«íb5% îÖfÏX.åü©pšwzc 4vÖ׳ßn.jØÝÑL™/’Ð'së‘sɯr8mh lX{:w‡yn½}—S¤„Ûªà9=,á»~Ù[½µTÌŸR.åXwÏc|ÏpÙ‹>@)‰’J‹ŒSGšûJQº|Õ­ÕÏh „q$Åþ-ƒÃ¸½iêÚóˆÖëgw/ãbmž»X›…gÎÓ—bgëŸfNÎF“KÏ_’IJˆF³Y®ìB©ü»ÑÙŽwîì…f;Ò,O}•ç.ÁfG±›%£¬Éu{š\uŸ0YV=†l.L‘ ªH™ÇÛ©!§¢ L‘_b*½­êÊžI¦„†Š‡ š´»Â:Ê]N2HƵ&@ÎàK)·º°_@9¿¢cø<çÏG“Î:ÓÙ‚v/Ë÷<šé-W”Iòé] P쮄wz]ª+chft¶gýð[ â4 Õ’Bá nUàhjUÕWäÎÜ2÷t!8ŽŸ d*Ñ‘€² Ç,EJ¡¼Mq 9jÕäåÏœÆGi²5—Žøy©Ö…¯¿«vzOÖSo9¯ÞøoÒþ!²ðOH8&ºÿû—éï§( T–Éoÿ¥Â<¡T8ÑÁ} y€ƒï~ ¿Æi*×ÑÕ•ü?7×wú/ÙH?Óendstream endobj 1384 0 obj << /Type /Page /Contents 1385 0 R /Resources 1383 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1346 0 R >> endobj 1386 0 obj << /D [1384 0 R /XYZ 56.6929 794.5015 null] >> endobj 54 0 obj << /D [1384 0 R /XYZ 56.6929 717.7272 null] >> endobj 1387 0 obj << /D [1384 0 R /XYZ 56.6929 690.4227 null] >> endobj 58 0 obj << /D [1384 0 R /XYZ 56.6929 550.0786 null] >> endobj 1388 0 obj << /D [1384 0 R /XYZ 56.6929 525.2967 null] >> endobj 62 0 obj << /D [1384 0 R /XYZ 56.6929 393.0502 null] >> endobj 1389 0 obj << /D [1384 0 R /XYZ 56.6929 363.1913 null] >> endobj 1383 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1392 0 obj << /Length 2158 /Filter /FlateDecode >> stream xÚ•XI“Û¶¾Ï¯Ð‘S5âã¾ÇyqªâJ2óNqQÃE&@Éò¯O7ºÁe†Nù•J…Fh½~`¸ àîŠÔâ2Ùåeâ§A˜îí]°;ÁØïBž“¤±Ÿ&q Ñ}~ZDùn¿òãÓÝ~ŽÂ]øY¥»§ã´W–ç~–æÅî©úË{W‹³‘Ãý>J/ºÿûéWZ–øy‘‡¸,€-r?ÈòÒ.øñÃÇŸhöŸR÷ãp®÷yTƒlegô$&Lü8É"“áhÛÈï÷aÞ/b¨®b`)Ã[)Ñ®ôË,ÊXHøišÆVÊOaYyµîÃÂCAØ¢°,öˆF–@¡÷¡§i°I‹Í *eT߉¦¹ëYÊŽ(XmX\ÛWRÿ~'¹÷s?ЄVt¼HuÚ€¢ôòROËá"ÞÒÔÂà¥ðaè—iÙkðQàú¼/PgÙi#+êöG¼Â‘:G{Ÿ¾¥ž8åÖW£¹5Ë<ËáØ­“$ªV â¹áyBSKª‚OìO-ý((ÉjO5ÈŒƒg?¾GôQ 3’†5qà°¶%WAª¤¦7"Îtƒ ‹3=µÏÜg¥#ùî÷ÿ¡:ƒ*qKêþ*áœ÷yâªã0÷4 é­ì“èÔW2ïñ å·âÅ**ój).7"GͼþH­©Ás¤ã®¯Œ{3$®J×¼¤§öGP…Xæ5ä¡'××7mdk¥¤Þ±ÜvÓ^â|nÔn‚¾Sf¨Wl”^ß,´7;޳r;6F™šŽ,*Y=°õ›¦¿ªîÄ~ ˆjX}“ÿÍ‚Øz©uÏ™cqÀ]#XG±¬,ÕIç’ÊøßÈ $´8Í8eDœ2¬O|#çlf‹„R. Ë`+/h±'G‚TŒTÉkDw’¢ÉìúG€þ0¿]°û¾»¨¡ïì{”Ƶåw€ûèŒó‚<¨r¶Z^¬žH9¢Â !\Ú Ÿ¤IhcÜ]g‰¹%èÚ3·ßé„™„ÆÂºt‡éQ…ó-šÇqzÚñÌ¢0åø[æ%•S¬aðìšÚÙ3(6ŠÐ9ŽQ °ÄÂ~ûF¢Ï‘œÎœ{¤'š9\ð 7°,Ä’,DPÓ Õm­š™Q‘Âñøýæ^̲IÑÅk˜èP’péÇ‚¨.¢3â$—uð{׋͑ô=§ãâ8CZäÿ›{±ÍÖù˜µ½xìMù¼›Rêì Ø©W™¦«aQøÓ"ÿ5tB…âgÕ  6 ~¾ûëï`WÁ¤_ï cº»B'ðòŒvíÝü}–8ÍÝãÝ3 u»í“Ü‹"Ú†£qPúqL‡BU¥PTÒ<ß\K?„#ìOÞ@y÷øí¥þÍ6ýjendstream endobj 1391 0 obj << /Type /Page /Contents 1392 0 R /Resources 1390 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1346 0 R /Annots [ 1398 0 R 1399 0 R ] >> endobj 1398 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [519.8432 268.1131 539.579 280.1727] /Subtype /Link /A << /S /GoTo /D (acache) >> >> endobj 1399 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [84.0431 256.1579 143.5361 268.2175] /Subtype /Link /A << /S /GoTo /D (acache) >> >> endobj 1393 0 obj << /D [1391 0 R /XYZ 85.0394 794.5015 null] >> endobj 66 0 obj << /D [1391 0 R /XYZ 85.0394 769.5949 null] >> endobj 1394 0 obj << /D [1391 0 R /XYZ 85.0394 574.3444 null] >> endobj 70 0 obj << /D [1391 0 R /XYZ 85.0394 574.3444 null] >> endobj 1395 0 obj << /D [1391 0 R /XYZ 85.0394 540.5052 null] >> endobj 74 0 obj << /D [1391 0 R /XYZ 85.0394 447.7637 null] >> endobj 1396 0 obj << /D [1391 0 R /XYZ 85.0394 410.3389 null] >> endobj 78 0 obj << /D [1391 0 R /XYZ 85.0394 348.7624 null] >> endobj 1397 0 obj << /D [1391 0 R /XYZ 85.0394 311.223 null] >> endobj 82 0 obj << /D [1391 0 R /XYZ 85.0394 189.9853 null] >> endobj 1400 0 obj << /D [1391 0 R /XYZ 85.0394 156.0037 null] >> endobj 1390 0 obj << /Font << /F21 1034 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1404 0 obj << /Length 600 /Filter /FlateDecode >> stream xÚ¥TËr›0ÝóZŠ™ ê@ZæARgƉcp“fá9eŠ‘ 8iþ¾‚˜ÄîªÃ0÷ê>:Gº€ÍCP$©± Ç„ƒÕÆÃàÉä®<Ò×CQ0®:˼O—L‰dD#­GXa!Èò{HG¾AÀ0]Ìf·sŸÅ0K.ü€r ogÉüÔC˜Mn®\(ýžfÉ4õ&CÏ?ŸÎ²dîR´:›Üôýó$½]ÌÏ“au·˜Ì“ir“¥þCví%Ù‡1O‚™%ðÛ»À 7t¯=Œ˜¼˜FDJ 6^Èâ!cC¤ôRïî p”íZêF0¢,¢G„£±Ð$ÇÊq‰¨ˆé œŒ&»íV×­Ê{Õ¶ª^¶EõÔ+öÚ´jÓXÆ—Žƒ€ Å’u€“ôÜÈ*­'­!p¥7Û¢T .«Ü9µ/à®j\®ú¬3å²ö‰€OÊe«ÝæQÕ.¥×Î.ªâOP¿TÞoÛv4ý¶ßÒ}…Ài±êðu£×­¥fÉ‚$çN¯>ç°¨rýb (aªêg»ëSŒ™ó:à>$NŒKØ>v€ñmö¡ëKWÑ´Ksõ¨ ᥮‡ gwÛ ÕA¾l•[—¦ØyVk›ÑáÙ¥£}òž“›•F)w¤íO5\éÓ‹i½`LË>^T [½uN©žUéܼè$T«Vׯ.ÔmjÜ·Ÿ%éL£w]×J M[»¶Ðú×T1Žì(™óö‡öß·ÿ …1bBÐý0Ñ#¡~OV×I3üˆ³ÐLc £JÃÌrú -;|endstream endobj 1403 0 obj << /Type /Page /Contents 1404 0 R /Resources 1402 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1407 0 R >> endobj 1405 0 obj << /D [1403 0 R /XYZ 56.6929 794.5015 null] >> endobj 86 0 obj << /D [1403 0 R /XYZ 56.6929 769.5949 null] >> endobj 1406 0 obj << /D [1403 0 R /XYZ 56.6929 744.7247 null] >> endobj 1402 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1410 0 obj << /Length 1224 /Filter /FlateDecode >> stream xÚÍWI¯Û6¾ûWï$ÍE+Þéå¥-’C"rHr eÚ"‹Ž»¯Aÿ{‡RÞÔäÐKჸ g¾™ùfH³€ÂyB¨(â +b’P–å~Fƒ-ìý>cN&NIb!`2±%"'Iγ ºTòj9[üÆYÀ)ISžËÍh+Íà€€Ëõ§ðy'½jçOh(æ_–oñXL²sOô–˜&$ãpqbÏTZ|Óô›W/¡é߇„e¤> endobj 1411 0 obj << /D [1409 0 R /XYZ 85.0394 794.5015 null] >> endobj 90 0 obj << /D [1409 0 R /XYZ 85.0394 769.5949 null] >> endobj 1412 0 obj << /D [1409 0 R /XYZ 85.0394 575.896 null] >> endobj 94 0 obj << /D [1409 0 R /XYZ 85.0394 529.2011 null] >> endobj 1413 0 obj << /D [1409 0 R /XYZ 85.0394 492.9468 null] >> endobj 98 0 obj << /D [1409 0 R /XYZ 85.0394 492.9468 null] >> endobj 1414 0 obj << /D [1409 0 R /XYZ 85.0394 466.0581 null] >> endobj 102 0 obj << /D [1409 0 R /XYZ 85.0394 201.2466 null] >> endobj 1415 0 obj << /D [1409 0 R /XYZ 85.0394 170.5419 null] >> endobj 1408 0 obj << /Font << /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1418 0 obj << /Length 1782 /Filter /FlateDecode >> stream xÚÍXKsÛF¾óW t«Ìñ<ÁúD[¶W)…ÖÒÜU¥ ph¢ 4JQRùïéy JJâT¶p˜WO?¾ééî 0|$Ššq‘ÀDÙf„ƒÏ°ö~DÍÄMúT¯£—ï˜ ”D4 «/‰°”$X, ¢h pxùaz>žPÃ×ÓËéìÍÅìýxBˆ qøæßÓ«ÅÛ¹]eŽ~6ýþ­ùKB„ÿóo>ÌÞ]¼ÿï|:Žy¸¸ø0Z|7z»è4î[E0Óê~ýø K0î»F,‘"¸ƒF$Ih°qÁàŒù™bôqôŸŽaoÕlD‰`DYD`â´“ŒX±HPÄ(30½|9žD‡‹uÞØžoÛµ²¥Z¥»¢Õ¶‚@@%BP³;-Šênòu§ê{Kû«mÒòþ•íýöjhŸ—z^Ù¶¬ZÛÙÖÕm¾t‚k•íê&¿uÃFÕ·y¦ùÙÃv”UéÙY©š )ãäPø^%ÊP¢©¯ÒU_ƒÔ+r«êÆÍmÒí6/?ÛÁªªÐ*ªj{“f_3;].kÕ8œ † íø¥*ß3C´y9ÑûQZoÓ3ºÞzd¬E¦½ßvz7­ªc•^JQei±®šÑgƒÔpXùêþq¤ÉÒC(\{ku„¡Uuê¾ß¡­~N7ÛB¡¬Ú:ú{Û×Ò`¾-e=&2TYeÚec'Â7»líd5ƒÐwl4SÛq>Ä.?Ö㣺S¦…:Æ1J ãw†T2ù_À(¡a¾Ò³<¼¯Æ$ÜÙþÚÜMÛ®­he®¯¯í|†ôà.o×v½Tí]U±ÓÚ)ÍfÐôzµ²KÛ¬ætpCêö•KKí¦Ù‹Á bŠ´¶cÎÚ‡Àk* :ôR3ã&V•vöa¸Qôl·]§ŽwVäªlÝô]^nº*K•9¿¦U©µÑÎT:1•ï´ëܪfõðjk}¬lóú×q!C!cP¨ÿâ(ŽžUI¨¥”‡•äŸÛåõèézR»/×õ;YM¼MÊ ’„ò®L=’!Ì#P.@„ "3ðøñ„KFÂÅâR{T…o.§õ]å1 ?\AÍΠ¹jªÁ?s÷eÞùŠë;:ŸïoØyÚ¦ÇÀ%¼‹À)+þºýi’@¹ùw@ªã³ˆÙ‰ÊßCÊâœYLïîîà½SBœ×JXx1ƒ)NMPŠ0%Ý-> OOðÿ1<:J‚=ÃðïFL8C‡4gðñ¨ðcTð>˜D¥'ïÛ¢B¾%*X „ÇO‚¨éXôLPØiPöâ¾&ûWñ?)Ö¡Sï$2aýçùƒg:¡°’LŸ$ ‘Ðáøçÿ!@,C2¦Òà~½VºPáÌ$Eh\Ú­ Sïêý ÏuÖS4è$ýpÝoéÒ&$fEáë‹Ù¹]wYÏSVmÚªŽÉÆI׉»'[ù “-í^Ÿ{ÏYW~u >Èè4NLi¦ÛÔ6K(c`U¿V4qÙê ª"»GAiSëß2%2¼p›:ºãJ"Çò¦º5Õ‘Œ÷™_/X t^FËjSÜ»‘UP™ ´71¬q'Ô+W[]É‹¡Ç}áþ?½²m7v-qó¶hê/¸Vÿèb‡ßóÝÎìm‚³ z»ÆeD« I…˜Ö~סMý¹vW—jy¤Æ2o²´OÛquÎÑvE*(’ï©@°±‚ôÇ«Ú4/ìŠþcZŸ©Ý4ÕÞí àÔæCúÊÖ*ûb—{™ÉþFQ¸Å‰ hbœ­†ŠrRÕKû0:¾~(玶ÙÝL}6Öá@º9䓲‚ˆþi·WÛ6Uİ‚A{1^„1I@É«NýZŒ *²‰Å®ÔŸÛ™ý8ÝSŸ4ŽFë1Ÿ›b[Ÿá‡>öGº@9„˜€P¾gÿ Üu4êpÌI+N™Î⌠ŠÃÁ“éñ¹¿\÷àñ1)ŸÓ^)­¹¥½A:d“+o_C*åÿÚXõ;Ü!ƒÿendstream endobj 1417 0 obj << /Type /Page /Contents 1418 0 R /Resources 1416 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1407 0 R /Annots [ 1423 0 R ] >> endobj 1423 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [55.6967 61.5153 126.3509 73.5749] /Subtype /Link /A << /S /GoTo /D (rrset_ordering) >> >> endobj 1419 0 obj << /D [1417 0 R /XYZ 56.6929 794.5015 null] >> endobj 106 0 obj << /D [1417 0 R /XYZ 56.6929 372.6686 null] >> endobj 1420 0 obj << /D [1417 0 R /XYZ 56.6929 334.1957 null] >> endobj 1421 0 obj << /D [1417 0 R /XYZ 56.6929 266.1213 null] >> endobj 1422 0 obj << /D [1417 0 R /XYZ 56.6929 254.1661 null] >> endobj 1416 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F21 1034 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1427 0 obj << /Length 2712 /Filter /FlateDecode >> stream xÚÕZK“Û¸¾Ï¯Ð%NÅDˆ9­ŸoUÆŽ-gŽ«Â‘ ‰Y‰ÔŠÔŒ'•Ÿ€H ”ìò)5`³»ÑÏÀÐYt–K’ðB̲B™P9[ìn’ÙÞý|C-Mìˆâ>Õ‹ùÍŸßð|V"eél¾êñÊI’çt6_~Ž^þõùûùë·1“IÄÉm,Ó$º{þ·×8ó^IýÃQ¼|w÷æíÏŸ><¿ÍD4ûîî6Î’BÀ—׿}÷þõé»·_æ¿Ü¼žûUôWJ®—ðûÍç/Él þå&!¼ÈåìB‹‚Ív7Br"çnf{óñæïžaï­ù4d9És"s–LÇèŒ ÂEʶ“0•ÒØ}Ó$E—;e­ê`¼W‡²«šºÕ‹E–”R–É,æ”Pžyf„Zvó[JiÔ4Û­ËñSkÅüz˳¨ê6øÔmìtXW¥Ú5µÕõ"T`’ˆ$-Œ óMyRD­Zh½ña©ÚÅ¡ºWæ]ï€q¹ÅwU½¬Ú½ªÛò~«,yU®ë¦íªÅ3˜`<*—»ª®ÚNÛâÁ•õ XÕ5‡ª^ãs‡«64eµ5|As­«7èÚ5£¥·Om§v8îIt–ó&\4uw¸¥yÔl·Fªù@«£Ku\¯ý¼ç^{ö=Ã.a‰÷îÀ²â8Ëùɹ޽¯¼…MÏÝÓ>ʬ‹T@-H"©ŽjM³¬Ö>Ì…€z€4Ï\Éó¬°Ð/Ä¥ <͘ç3AõÎÙ1X?Ë…%­ÛmÓüvÜx )E3K¸Gç¬åNG?Ï£ÒÌhósŠígÍn‡nƒð¤Â‘MŠ.‡9 ;ÂwOøôûQžÐÃðdË ëØÖxbe¤` F˜ÿɺ¾Zi­V.ªÚ†G÷´U£ jŽÝþØù8Ü•9«~ xJ²ÌÁÀI’†ë¼%ŠûT®X×yOÕ Š¾Ì>É9»,Ódâ"ðJ… ›ôI²hÙìJc!¨U60õE¿\£Ç÷Æ”ðüÏD&¡ ‚@´ñïˆràD‘§.lZxç4Úéø6#ítÐÆx (Ðk0¶ßªÎÒ7+Ï µS6 ÍØ„t@V¤Ñ[ËxS¶6–$hžðtTÁ]ç(¨ö/·± ,j+-竺ƒB»pE qdBÌ•øÜB<»ÏL|›Š¢ë/®ÖÒè¾ì›1«ÇMå&ÕWµ8vXç©cìØWTU.6Ã$(ñg[µ6êõLñ´½C? gKY+m>N“èùöü}³Ç6ŠÜ}=Ћ…jÛêÞ%Ý ƒi7ªß§ja¥g €"–C6ˆŒP‘ñMIÁS ãPªØ0ÑçqžŸ4±HO’´5?µåZMêÄ%¡¹?¤S‡ÑI°NŽÊ¥XœB”}þ S æOŸežJiSͶEC6àÌS m-Ù—#T6¯±Tœ3”ä‚;FŸŒ$)²,µ&zâîi¯¼Åe™Ì½R¸ÊnÐ8Ë<Û²mLSI2ÉňéŸ\'…Ƹ}®â¶%ØOc Óñ‡ ù9¾nÜj=-(l”?\Õ_ç–ª»«.û¨×P 70ÓÊ{‘õ¤ê±=ºráJ#N+_X"IÕçÅåN‘Á… ßÇÊU®üMЇîW1€ä'x| »ÉýÙO¨è: +lš½ç^X`ŸýWvwM¿»j}Lã¾î—Èv ^°ô>s¼gœs“p½2¥ßcy‰÷P'qôtÂ2Ø‹]ÄE}ªi\ä©ú8·/TMØ¥—¥zª€ØqiåXäNy*Øe Π $¾¢ºTÁ¶2R»= Žê–FÿQ-N™´©žÄbfmÛ$L™€€È*݃½°ÄKµ*ÛN;ßì7q¶P×]‹_Ý«îQ©_mVÁ´ÖÿØŸ§ V+`o5Ì©Uç¶nK ë¶U.èîx®:·!>ÖfƒZÚ¥ëðuqto#T}íT½TVÊãùf¹_Dú¡> DƒŒþPî󘆞ê*4àEJ( ‡è·êÔç1 <•Mlqùr¹­íüñÁõŒxêDò>®?NuQVÀ6t܄⻫¤^6Ý$?¿­õ »« ' Ã°÷y~¿^çWíì¿¡MZ–,¡óç$-˜&ÓAu‡JµßÎ{wUÝÕ¶\‡–E/ËÙ˜Ÿð£4ñFÇŽÙv 'Yá¹_Åxß:‡Àƒ`Ëý¿í®Óí!—>à¿­½rð}–¤âr{íSM·WO5>ö´XFO2vY²§º"šr»–\NË>?r|莜ôF=fÇ-¹¸-9—Ùp®_¢ó`P7uÜ{«{gnûYŸ÷ÚæËí¶yt²6vÚÐûdZÊ™ï“ôtЙe$B[7bx²ÇV0²9@£Ÿq[že§˜…w&la®¼oL/…áL—‡ª9Úït4Ù¡]`jA«E¾©Wh€µãT‰36 `Â$g8<@(Ì0}¸d²ènhV$´FZs”3`·%Žð,˜{`êßÇÖŽl»çþ—¹ìã¦8Xˆi¤ìì(Ù™;éÿ…–b!NæÖŸ„,§Dô‡ZvŸÇ4ŒðTWaƒØKyJH§iá©)j›–CB´ʦöä‚}-sª‚q×Ä«ÊBwÏ9¡‰Kôÿ¢œØŠÃÔùnPFeZ »Ã0µóÂE%ŒLT¯Ò$&¬–8ñ¸1ظH \à ž_­zÓÜö§,«5°¯q¨B1€óÂq|°Ñœ§ - ·±02(¸0 wiŽA‘‹ñêUL=6Ö‚vÀ¸*Œt˜ƒ…I_xÜ<í‘…D•ÿÿѽJ{Õ3`Þ*ØA,¯ñFrͽqЏ.Põ´·y,¯·•µæ‰;LDÄ3ê¹ý¬ q&Ý *ŒÌ¥übAÒ#4¨™Ep–ZazÊÝÂïiߣŸÊ²Õ€ƒÛZ™©ïíCN´Î%-¯•]Ì7Z¶ø‹f†ÁÉåúmÏ-ïý掓ÔËÀ“wæè+ûv¯•æ¬Æâ¬Wadý Ð4L¤#Ï »CÕB~þf?¾:jƒQlú×ì'õ‡-¤!°=I´—VåÂ~‰gé0XùÞQwúf iÁ-4A³|=s¯6åCÕ•Ìmh=ZNK«CÝXZdˆ‡iKTÃÂÀñ‚/Ÿ~fÊ„‰—@€¦4s[-{ú®o˜ƒwy9Ð~DZÀ†N•K<7ãIR@ñ;RfïHŸ.¿óž4ôywºPßoË'‡ÄÂïÔÚ_MìËC7¼Ò𧨡Ú?/*£ íTÎèe¨}¢™Ú–Æ¥À2^lÔâ7ÁÕÚR€cÅ%ÑžæLöÐÉ úËúÂ'² b|ž+8âœ3’±‚ßÛý“þ´=»ó¯»òëØç Àœð×ÖF2¡GÊKSéo¶ ì›Ü^"Žó=òþÃÿÈrúÿ‘žççŒ\Ÿ3²Ä+¥Õ/ ›d–±èÅÛ»Whp ¨¿ã5ùÿ…9_ÔÿÀendstream endobj 1426 0 obj << /Type /Page /Contents 1427 0 R /Resources 1425 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1407 0 R >> endobj 1428 0 obj << /D [1426 0 R /XYZ 85.0394 794.5015 null] >> endobj 110 0 obj << /D [1426 0 R /XYZ 85.0394 769.5949 null] >> endobj 1429 0 obj << /D [1426 0 R /XYZ 85.0394 744.949 null] >> endobj 114 0 obj << /D [1426 0 R /XYZ 85.0394 744.949 null] >> endobj 1430 0 obj << /D [1426 0 R /XYZ 85.0394 721.0357 null] >> endobj 118 0 obj << /D [1426 0 R /XYZ 85.0394 672.3079 null] >> endobj 1382 0 obj << /D [1426 0 R /XYZ 85.0394 647.0603 null] >> endobj 122 0 obj << /D [1426 0 R /XYZ 85.0394 136.5325 null] >> endobj 1434 0 obj << /D [1426 0 R /XYZ 85.0394 113.5963 null] >> endobj 1425 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F54 1433 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1437 0 obj << /Length 4183 /Filter /FlateDecode >> stream xÚÝ[Ýsã¶÷_¡ÉK噃oíS’^®N§Izç$“¦™-ÑséˆÔ¹nÿù.°ø!ÐrzÓ—Ž‚ËÅØß.`º ðGReÊ0³ÈÈ$¡r±>\‘ÅÞ½¹¢žfˆVCªÏo¯>ý’ë…ÉŒbjq{?à¥3¢5]Ün~ZòŒg×À,¿þì/¯¯WL’å»×o¯¥\~?îù›o_¿ýì:ËÛ›o¾~w½Ê‰Ë/þôÙ··â2/¾ùúË›7ßõ|®¾ýêêõmœÅp¦”p;…_¯~ú™,60ᯮHÆ–‹Gx 5†-WBòL ÎCÏþêÝÕ_#ÃÁ[÷ijå„$™”B.V\dÆOQQ•®$´S,r›j i2Å‹Ïè`ñ5ͤ1r©ìâ×Ûòl!€@Ó|‘‹”FªŸk c2˜ ˆiTæÏ‹©2Œ‚)=1}FB¼«Õ¾°ŒËe×$«!t&°¾JEV×õ|¦c^¹_±,öÅS‹}›Óá¡ÅînWbú|Û¡âfeÃÏñ±}(וÂåÆŠ°X1"2¦;Áaœ¶zÞ==Tëb¿®ªEøMuoaÀ}éÐþPtV­³9%‘p¹ ”dH5¯$‘ÊNàXoÖÓAó Ž4ψƒŽ6‹ÁËœ½u{¡Ù×áÐtþÙY´èrS@w½vŸ?í±Ã®t ¢Á ‰ˆ¦6‘ˆ‘Ì ]1Ežc„°‹Íc‹ÒtAàö  V ت ×±èBƒ.§D)‰;Ä” <°nÄ­ÛPš‡¸Tvœˆes¿þàªp—myüÊi$‰"g`^õºDªÏo¾þ#¶LÆ^%,2gôÂò@¬'1r´§‡‡æØµ^žýn=l¼Ë h‹â¹ãë^&H›L\iZž• ,#|²`§®ÚWµ2X‹òŸëò¡K   #åÜ ø;ú¶+Ž]b(ˆEF‰¥-ÂN¦Ò05ey,g™jðŠ2¬ç+«dù¸«®)äøñ£÷øTì[«E9_ÖMçÆ](7Ø_Õ3ʯ-¨~n1TKc×ïZd¿Þu]î‘ù¡Ù” \´þæuÖâ?¥¤‡õ§æ„îëx­—§”Hra¦å}cÐäAìǪÛ5§.ä8Þ6Ö6|¶Tù·•ÕFt«íþx¹Ú“Ë;0¯*Ûþ¡hƒÏuæýû¹ÔDZÈF?¦†1à0Ÿ+¢‹©’»ÔRéhÀb>UŠTqϞɈ$‡LOå¶EŽj›Ê`T&8çS Ù^DÊÞß%92&Ø”ãÃEŽÖŽR¨o„—#¿§‹üÞ—©ü‡–F½‹z7š‘:cÔЗÂÑg9 íɲ,û9åk¹%r rt&ËÕgj )¾Vp ‘¶Våªbøî¸]`ãí@ùjHθ´_Ü?®‘,gÂŒIÔƒ<Õ…ñ)ç°Ú°·#býeSv'ybcýEh`=ËxYÜí“Å#0Q®Ùoñ„!²f v+ hÊ(—‘öi>¢+·Cͯ§ 6rSDTZ ¶ˆv{ŠhÞ!Æ…ÈÅ9Y¶pЀÜW‡Ã©ÜÛcý8¶ •·e×Y…aOðºîì§6¸Å/q{¹GQgSm«®°ŽŸƒ´²èNq&Œs¯èð-v;(ýLBoí®À÷Ϫ\ãsgC4W¾Àæöá«ë_?ºÀÃ=öƒ$?TÿEˆÁ7ãÄv!vitp!cb"ηÈf+¸EB­ÛélÊûâ´÷iѾYÇ„×iŸ+—1#.ê«&ÊôÎ*—èÓ#îöüÜ+é<ã2°ø´ìÖŸÚÁ2W.Od~ Zш¥œš¦ ³PãeìPØFoû®<‚²”Ø=X [CuTÐ}çmy˜ý¹~ l?lVÑ×ÍWIð%2!bŒALc·Œ‹´"óPÕ¬&¼« íÊ»!ĈÐqßœêM öÛÅ·JÌØæä<Â1DüÔ£RÛÚ7Í{l:Z‰\dRQu¶¥1PŽw3Éõ 0fÓ2«)ÓÁ`=å"h ¤dV]6Õ1Á_±,Ïc!ò±h‘ù¦´kY;ŸãÆ*klùÌ…bæ‚è—ÐLÉiõóîTí7˜:®Õ÷›†ž3úd½ý™Â&X'z×<¿N’ˆSy\'¯0zåß–µÍ!K/ÔÝþ"8¯«z› KLfBÆRŠe×r[ÖøõªHÈ;ÌhÄ^…O‘7e»>Vw¡\Âs@Tlšç¢ÆŒ€lÎÀ™1BÄ% áÉWCú˜rE³îMðc&Î bœS®FÒ$ bžê‚çÜôÂõQ°òTL€–óÜ\ _²mŸT«HU"Xª –ÀEWømCíÍ}Þ !F#ÛÓܧ™¶ÖO‡å¸9w ¹ —éS[nz^Ë~£cT·£CºÛøak’q–§£×ð¼71ôPQwåàAkC²Êgb•Ò™!täUÛ„°ÜŽ0 Óò˜-TÁúiú¬Hž¿”É0{ËB ºš‹…ab´Ôµ?mRçŒ ‹û5³‘ôTªµžv¾gŸPDX/¤@«hÛf]ÙH‰( &­™ácCö15†4:· ×⬅©@šûåðo}@µ­]å !Úmðvö²Áá,jÏ>0½ ÃGg-5¡´˜/׿qø \· È•LQFU a: ¡Ë"éÄfgÊDJ^ÖÊ7g“ÃÄ\‹ B*R6m4nÞ³@(P9Õ×2·ÌàÑ5²êŠ÷.­ Ü¡oøÙ5m‡-_ª¦lé ´%Ùl|&¾qÛ“ßQÛã’ h ყ÷êH¹7+½nŸ@@¯¯yAëÎÓÙJs±Æ°Õ½—®IøöU˜ÝH×Wí V5Dô×Z„ðÀSÓœ ¾A @l,cᆰË,Y†œ[åìeþ•Ä<:l §;0Œßha‚Žy<¾w®Å>û Tÿv¸M>§` ÊZ)6^)÷e.‡èÑ>:¨¿EJ3aÅyŒ3QÅd¼?‘ˆ> µX‚åú…v“g’ÅzBŸÒøYà’AÃ}Ž] þ¢KN•1@Ôœˆ‹' µqÜ]sÚû•e­„áƒSUøEUKå¢ë´Êì…³u_Ÿñl«¥qÌ Ò¦¨qÄiœ§;NãRz(2ÒÒž‹ÝTEÏ>Þ--‹®›‰ðê’j@z+áAó¨†->øƒz •ÞSÀ/„Œ FÝ=¥¤UeR¿`o ˆy“¼/äØTÃõ…JΙ,fÑ&ÂL¯³1Q{]e–7Ÿ¬¿ åS »b’i´˜Yƒ{rb¹RELÉ ”„l”X_˜Ý’œÄ–¸ÑR1ءɉ|9¢ÖƒIê³zô°ÆcÆ®Fió¼«a–>Ö®ÃáYà0s´½EŸ­à¯BJ¬Áô¤RåqÓËÃÉEIæ *ÐSàχb_m°¹i…³G BÖ¾XÖœ¶;ìv'=@Z—¥ÿq™å·îNþ˜}0Ê®‚Ø-Ðzg÷üþhwr)çA޶;¢šÂÇûê}9Æ€þÚ c"±Ì"3šò‰•Œ’H`B´6 &ˆ½1¿äú-®ö*Qêòí*r\ YâŽY–saºù5vBcAÁÎuTW*ð1l˜ÀMò媴?3Ö_ôgÄÄè¡?ƒvál®{l°ç9  ¬”ˆP Øo›#ø›Cê6‡Ì/Õl¶ÅeLmRS¦B*Sà ëíӮƻ*Tåâ1?×=÷ÈDΫzÂoqléɈï Z»3m׋砶„ÔÖv¶øë£:C›>œ[Ò°8Ö[®OÇpeï9cR>⇃µÿ­iìÅzuØÈô† .FYf.W0s|©´ÇøjÈò>šòŸî<’}$çH;N•d–K.>–·Tÿ3Þ\¿Ln›Eæ>1zn Îà;1"dT:Ë…žx^R–Šãã«8<ù®øPNŽùmž*7p2˜ƒK  èOú\)ϵ¬×OHHo.ƒsÿqe€ ß~ù…ÿÿ )´GsAö—€9mïŽèKè‘Ù&— ÈI_yi12؈ž‡y·Wpv|ÎPéRnøó.Ygº¿Ÿ2‘ÈWizYFì•ØD.€[Y²®sRžGÙ(T<†p@…Ñ!Pa¨À¯*ŒøÔÜvøûRÐr‡ –¤OÍí×0> ɵ-vå/HtÞ§8ƒ¹8f.ŽÙƳnkÃúRØÔäÂŤ•€…ÍóDö”ÞsjaLi:³" °ªÏøfP% Ùádaâöâ’µ¶kº y§íÃ:v¯µå¾ÄÝ¿òIŒëi°ã΃IŒíñg6¹?[{p/ñøÙ±ô>˜#LúÌmE}~5ù¿Š™bssõ™å” ¾ÛLÖ£?h´N« ×”‚rÁ:8¨û§Ib;iœ´ ùm7¬b>ާŒ>p–Tm“Ü<‡ðãÎv~ñ3O]ÂX{?òPìçŽ4'ÿçýzâŠÖ$¥"6É8·¨–îÆŽ]ħ;qÃ…î‘aôxÑQ~2ÏŸü!Uî!a¼º3zÿÉš¿}ºc²¾yóýéŽ__|~¸ã7Ûß}ÞýøƒØþXOnÞÐÝßÞ|·ýÛÁ<ݼy½Ý0cßý‡LýD ûow‰c(åøèÿîëÿéÑBe­g®òNd²³Æûv³LFaàÕ·‡)Å–”œße†¬„+–˜ÔÎDA#endstream endobj 1436 0 obj << /Type /Page /Contents 1437 0 R /Resources 1435 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1407 0 R /Annots [ 1439 0 R 1440 0 R ] >> endobj 1439 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [97.8684 502.256 131.7211 513.6481] /Subtype /Link /A << /S /GoTo /D (man.rndc) >> >> endobj 1440 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [91.7912 414.0448 148.0099 423.2602] /Subtype /Link /A << /S /GoTo /D (controls_statement_definition_and_usage) >> >> endobj 1438 0 obj << /D [1436 0 R /XYZ 56.6929 794.5015 null] >> endobj 1435 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F42 1338 0 R /F54 1433 0 R /F22 1037 0 R /F14 1060 0 R /F49 1358 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1445 0 obj << /Length 1577 /Filter /FlateDecode >> stream xÚÍXÝoÛ6÷_¡‡=Ø@ÅðS$×§´KÛhš%î0 +Õbb¡²”Yr²`èÿ¾£Hɲ̴Ygl…Ì»ãñîw‰0üH¤ÂLóHjŽ&"Z¬&8º†½—âiâŽ(R=›OŽ^0i¤šDó«,…°R$šgï§Ï_ŸÏO.f1xÊÐ, žž¿9q+—°%Äô—ŽâùÛ³§/ß]Ï$ŸÎOßžÍb‰5ίó¾=?Ùò]Î>Ì_ONæý-†7%˜Ù+ü1yÿG\øõ#¦•ˆî`‚ÑšF«  ÎX·RL.'?÷»-kÈr‚)$•Óq:0Á0æI$…F £¬5Ýç§ö (&i!h»ZÝ4yUÖ³8ÁxúWKA5RJê]ºÌ\¥›¢‰k³¾5kGN¨D~d$™ìp|2÷`Pôë2[üSGÏqZ½ Ãûà-±¥™/óÚùè7Œiaž¸I~åÿ˺I‹ÂdnšÖNâÈBi ~íÄ#Ó,ެzhQ•W C‰J¨'÷ÞU›¢;¤(ª;7l–Æ Õj•–Ùãc¢À*0’H3ªZ¹?xR= HK™øƒ­ŠÎökSTiÐ4ö ^°lùš T’T*K³hܤ[ìÝè¦7ÕÚhÁÜnáùÓMm<÷ÒÊtåG6†Â×3¢¦­®ÖhŠ8/Y™_â®ÊÑ!EµH‹~Wéb™—ÞâwÆçf뙚nÊ2/¯ýnÞ,Ý課îê7À*MËXW Æ¬LÙÔ!ïàØ²·¬Ûâ)Šå®® g3Šp i›CvÂÇ#ʉlÿZ,«ºyêæŸÝT½C· 3GæÃM$ùçÑæœoãªqÿË´}é72°TnÔN]À­ØY}ŠD…¥” >ʵŒp”Hˆ>›ÿxB’Çd[Š´R*œkã^b<¹ŸHQQÚSYíýö­Öű»ò)Ž ”¢v£ñ¢G¥–-Ä42ŒzFab`”Øf¦kSŽN¢RqO|ã |½NWî„»¼°žÑ‰Eê­)sðHqïö.`ÀOŽ" y”!IÂÊ<”&E‚¤`¥ËÎî ëüö„ûj™€amáC¦™ÛN‹ºr&c,Aœ’Qèdy}S¤ViB}V î³vú×7U™Y“î[’°ÜY²Õ}ÝÁÅ Óá»í‘iãÎýÝRiÚ Km®ƒ•4Û.ÌÈÁŒ€'ßæ½ìA3j$¡v÷XjMt\4f]¦M~kÀ{„(CÎbàN%ßÍNO›Ýº0uù06¥!¬µ|qPQBAĽ§[ ؈7>Ö77>E asc¢õNáׄ°1šÚÌãSPYùWU–_ÝNSi51{BµÑîHÓ¦/í¨7ZI(´Ä$Hˆ™@„`ܶµ¤³ h)óë2 ‚ÍæX=á®­5ë&Í[{“黳Ó_ݨöü0¡}í…ußb®zZÒ®zÚíÊq4é§n÷Æ,rkÀ…›§‹¶ë{âèÒÚ­f¦^¬ó®q‚J]ŽNÛ)›VüÇ Pë7_šÚ{jp…?v»}qØÔ}9gD(å}²9-„¡?f˜÷ÁÞ6`h\Od)àEÁ¡Oæ\=ª{gm£/FåÛ¸:E½Ìƒ8> ²ü°ã•´þR1Óq ¥¾+i»v¤!bá‹¥v¨½<}ùêÝùØPCÊ"P¾†"ÿš½È€šCOR¸·-ÈŽšÏm Ô£>{ }Ü'"_Ö²P& 2—ߺ¬³mjGªd)EZ›=È lÁhI¦’XBÛ¸}1þ¯ &1<°‰-Ç_1S IšÄó“‹7£x ó`(ÞÓ3ˆâ=âEaºŒÙÔƒæÏ¼ùÌvÕïf‡Í•’"©à̯ÀL&¶Ôóf§gó‡Q6y0”í©FÙPÍÿe»ê÷‚2¢)TxèÅö….w¿Ãí}ƒg+’Ú¾Üá=ƒ”2ôÙG_ÍýH¸ýv M4äÃðæ7C©•eá@4¥`y:}vzö“ó®K Ÿó=w½€Á­þÌþoendstream endobj 1444 0 obj << /Type /Page /Contents 1445 0 R /Resources 1443 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1407 0 R >> endobj 1446 0 obj << /D [1444 0 R /XYZ 85.0394 794.5015 null] >> endobj 126 0 obj << /D [1444 0 R /XYZ 85.0394 478.6238 null] >> endobj 1447 0 obj << /D [1444 0 R /XYZ 85.0394 451.3193 null] >> endobj 1448 0 obj << /D [1444 0 R /XYZ 85.0394 421.802 null] >> endobj 1449 0 obj << /D [1444 0 R /XYZ 85.0394 409.8468 null] >> endobj 1443 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F22 1037 0 R /F49 1358 0 R /F21 1034 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1452 0 obj << /Length 69 /Filter /FlateDecode >> stream xÚ3T0BCS3=3K#KsK=SCS…ä\.…t œ;—!T‰©±ž©‰±1ƒEV.­knj©g`fA‚!ÂVŒendstream endobj 1451 0 obj << /Type /Page /Contents 1452 0 R /Resources 1450 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1454 0 R >> endobj 1453 0 obj << /D [1451 0 R /XYZ 56.6929 794.5015 null] >> endobj 1450 0 obj << /ProcSet [ /PDF ] >> endobj 1458 0 obj << /Length 2439 /Filter /FlateDecode >> stream xÚ¥YKoÛH¾ûWè¶`2ýd³wO;yÁ3€³{ƒ™9´(Ê&F"‘JÆùõ[ÕÕM‘mˆŠý¨®WW}Õæ ÿø¢Ð“V-ŒU™f\/ÊÝ[<ÀÜÇ+Ö(-3­¤„™ÙTË"Ó…0‹tÌä§û«7_–å¹Ð‹ûÍpVnt–J.î׿%oݾ¯ËTh–¨å÷?Ó6•™ÂpÜÆà›1Å•ßðïõW×”Õšv¼»½#âCåúã¡ê\eRå"pÈMÆ8H†TÆ—)gŒ%·m_ožÂ±°™ÍEvH™)­èLŠ”yrûéþæÃ¯D×þšÄÑç®*]Sw;úì]æ·Ûö[¹Î+‹tW¾V‡0Ñ·´¸!‰‹ªŽk·îku±Í$í†ñè‡êŒ—CÅPÎ3«µðª|o›ê°PH¬]ï2XËtrÓÐÐaÉ‹¤êömÓU4‚Üð× –=™‰‹<“ÜpòÖ¹4§âY®¤ Ë6þvùúŸh¤IÅ¥QÉ5h‰0Cv@ò[½ÝU>VåŸSa»*JïÝ€TÝ­Ñzuô¢‘Rbs`,î%¥s!ºÐjD¡×ñw˜*2ZÓÓÀ‰?|¸f}6nè<Gšº¯]ø¸ó“úƒkº Ù!‹®<ã…¤¨üÐbt0“ìZ’€¾êfÓv®÷2à€[µÇžH ä7jÐY(óš¥Í$ƒZvM,½©‘ðAb]uå¡ÞŸðQVÌË çñôæ¹;)a™‚¨ñ¯\~õþþ”² Ïà*Á È]’hòð° âó(‡ ëÓñÊa“@¾à‹²ÜUåI˜<Ï!Åœ‰4¤Éñ /$Ó—‰¹TAj䢠p…`ƒÐQ:'èŠ%Ooàzc²(„œRѨ3>ÊmV(Ȇd|·íÚôYGA4åVÆ0¹td p8Z" ÿ²s†õéxÃ¥M.ùNœƒªç˜ ‘ ¬.\Ö¼&Ä'ÁçØ"¹Ÿ ¨t¹1êR¨Q,Ëö”Bû¶l·¤™ÏKàÂn_•õïŒ ¨>³É\ƒUŠ|ZêŸ>xK·6ÏÎÍ2DY.­A•¿\ýö[¬Á>?_±LÚB/¾ÁË€ƒXì®p­µZÅ‘íÕÝÕŽÂ ™åŒçÏó¢} x’vè3Vi”.•ðœzdPv³°˜_`VZ›)féÎÞŽl¬så‘g™–"ºâÓ2Íyrÿ‹äý¹e€§â šÔ:Fû[ºø²€+«¬•´hD{]O6ðonvbñ®#¥"ãtÌÙ+•O“&£@£2!•%l„AP¾–ÀTË¥€‚´‹ƒ(Lò}É!øû Jׄ p¡‰ZU#æT–a¨KZȇ™:ä}MvÍDZ %@ ’1ûç™Nî&³òT^„eÉ ù?Ñiëj³”P)Û>ÌvU³îfNL…§yõ·Ÿ–Š%§6=¢C[ŽßU]ç¤R‰?×—[ø¨ðƒTö8ñxMŽl‹«êž~·­[{Ë@М'wxA7Ouó0g)¸—‰³ZèùO€5Ò¶Ù"çÍha¶R$Q0\Ë À)ݱ«æä€J¯¬yÍa*+LÑŸáÑlŸˆBïÌ0×9ˆhäñ^òI‘Y¸Ù8F/ ó!2Ž–ïè3€> êð;rÂ9R°`™ËÅ8‰ü½¼„PÛÜ.Ò°÷ogÍqª+0çãkÔéÄuÂ@ùV,ô;"ô;ïžÀ•uIÿû5‚Ï×›ŸaSnã&Oû’¿Ž~vUÿØ"1,Ùx/áÜz ‘Ž·P,¡ÔýÖ•ý~>®[WÛªFiaI°vŽñ%kt\ô?Сaðôê‰D€¸æI³&žð ¡0i‡d"[øªé¶ôð™¨vsÖeƬ€3_ч-® \ ý ?~Ä rgWM™M‹qmÂY©\æ³ ÁȽ<9‚úÑYðIì9´)n3[âÎÉ\8ß”T’c0Œ¸Y -~!†é{Ûôø\$å"+˜Õûú9ÆBg\ExC Ó}»­Ë9„ F›Â†ÕåÖg±‘±ø3­†6Ю†]õ^²8Æ õëz”ƒ2¨‚a´°Ó’²ƒ¾ïÌ0nÀá܆F‰ÐyÏH¥à®æêGuW™5:êŽnå¾öḖö"¥Q‰­SÔ|Û–n;§:`üÂØQýe"ˆÓ Ì/u"ŠÚq¤Vad_vußc á§O “ÍVA?5‘‚ë,è16]¯›n®Ó] “Ÿtö4ÅÔOßëò‘b$¼hª¦:¸>Þ¸ÕÓl›ŠM2—5qŠÿ±þP'戣C܇´qWU Ó”×ñ!BåR¿ÖÅõéxÃL;rÁwÚlØAUQ"·ÅN$ºlŠÂ¢×Ä” ™ÀLÅ *™pxÀÀ¯uÕ»zÛÑ­à‡Nfrz»†T'å(F!Æ“cç3ŽÿRVuJa²«ô2ÎÒ‘_ŽU×w4âá0.[U4°së@ \yx瀱û_ÞÿúæãÝ O[2œ_=Ñ/ÜÍtî)ŽêÔ2©j‚ÔHÏg.0›€&&B-¸:éT}ÙCJ¿ŒÄ[vf'ï%øfc¨êJ- }C m\_­³áñ«ð BŸä[äI:n¡ÇvFºòP­!CÖ³ e¹™ÚÅEÔxvF¦y>>bÝî\ÝÌ¥HÀþ9Ÿ(î+¶.’OMéÑKî !TÁkBÓP¹B×NCGBjøAý/ã÷’u=}ÐC §: ˆŽCÍŒøœ_G@0ÜŽÉ+dx; ñ8™>ÓFö(ëõ>wþvéu<> endobj 1455 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (/usr/local/share/db2latex/xsl/figures/note.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 1472 0 R /Matrix [1.00000000 0.00000000 0.00000000 1.00000000 0.00000000 0.00000000] /BBox [0.00000000 0.00000000 27.00000000 27.00000000] /Resources << /ProcSet [ /PDF ] /ExtGState << /R4 1473 0 R >>>> /Length 1474 0 R /Filter /FlateDecode >> stream xœeU9²,GôûeË@@Q ‡!é¡%bd(dèúʤ—÷ÿ(žÑ¯ ’$¡T¬)ÿ®ïë¯ãïãÇ_¢ýþÏaíÏc‹®½Ú¿G—=ûÌöÓ1ÄF¬lÖ]töö×ãqu‰Ý¦‹÷5š”<8Ç—ý:\;âúãñ‰üéÆ&ÞЇ h—õ:ÀÀX=&02²oÒCó eD3PMtð1CrZûbœ7³}t€mA£d«·íä'ÐWŠ!è®»½KO(°ƒÔ¤‡tÙKb•^¦Ìì »å*’ÎÕBêFåmY¸™`Uõ´™Õ -¿nÜž í½³`*TûÞ£jg“¾=Ås–A½R?Ô =}³Ú§l ¤Ï’ÃigÙ¥—ÇáC6uéíÛ&”\Ê GTœ„Méêö–KòlÜ’Fyu|?é%åiÈ¥K”êNÊq{vˆ*êèJE¢]8hÍò¤p0R±ˆ$Á(+Á nÖN¬ qª„Ñ«ò^ÿï>‹«>÷— .13×…Óƒ!¶3¢SËAÕ”ih¥Å¨Š^…(€<Îm䦽ªšÛÆlLÊâ³ò7ÙaÆ´Ëdô 6(WðÚºK г2"ïE9~  n*Œ1½÷¨¾x¥Æˆpîâ‹&Xîܧ³±è\íD¤ßä0}#XŒûž˜‹¸À>#^V°¡|2Îi‰9ÊÎr)`˜¢Xh¡Ò& „hb—H°Œe"Ãêʱ„£~Ï“a³tŒºìZDß!#Z¶ÚÂk! e'jÝ=§ _tsÙ¬ûÍ&­Nå@‚i¬ˆ3t%kÐE„\H–YZxÿ/U¥Ç™åë—Φ@±¯iW H þrÓGçX5¾ûû8‡´ÕªOª«t–Ô³$Ây°‰—BÒ›ÀÄ5©/¨vp÷o`kA“ôr ±ñœÓ4N.4Žæ&F°ÑTÆG%V½ Î'ÌØR5¬BÔ‹`qUžv-UÍ=ëÆåQv2ë_ ”¿­qq‚~èr¯Ú5ÌJ¼ð˜°h»P¡õ‹kÜàéÚýªå>Ò¸D °o»Îi¸CrT]¿MJ¥ ÆÖ¹’°;¿ö‹ûóZ¼¬ å[Ç-œÁ¤ŸBx¿ýpü|üÈÂendstream endobj 1472 0 obj << /Producer (AFPL Ghostscript 6.50) >> endobj 1473 0 obj << /Type /ExtGState /Name /R4 /TR /Identity /OPM 1 /SM 0.02 /SA true >> endobj 1474 0 obj 1049 endobj 1462 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [470.3398 467.2776 539.579 479.3373] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj 1463 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [316.7164 455.3224 385.3363 467.3821] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj 1471 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [304.6433 163.6578 373.3153 175.7175] /Subtype /Link /A << /S /GoTo /D (dynamic_update_policies) >> >> endobj 1459 0 obj << /D [1457 0 R /XYZ 85.0394 794.5015 null] >> endobj 130 0 obj << /D [1457 0 R /XYZ 85.0394 769.5949 null] >> endobj 1460 0 obj << /D [1457 0 R /XYZ 85.0394 576.3463 null] >> endobj 134 0 obj << /D [1457 0 R /XYZ 85.0394 576.3463 null] >> endobj 1461 0 obj << /D [1457 0 R /XYZ 85.0394 533.5444 null] >> endobj 138 0 obj << /D [1457 0 R /XYZ 85.0394 299.6823 null] >> endobj 1470 0 obj << /D [1457 0 R /XYZ 85.0394 263.0631 null] >> endobj 1456 0 obj << /Font << /F21 1034 0 R /F22 1037 0 R /F61 1466 0 R /F62 1469 0 R /F49 1358 0 R /F42 1338 0 R >> /XObject << /Im2 1455 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1480 0 obj << /Length 3604 /Filter /FlateDecode >> stream xÚ¥ZIwܸ¾ëWô-Ô{n@‚Èœ4¶œñ¼ÄãHÊòf9@$[â˜Mö4Ù–5¿>U¨—':äõ…(ÔòU¡“€_²I³8³ÒnŒÕq*’tSì/ÄæÚþz‘pŸmè´÷úöîâÏïU¾±±Íd¶¹ÛÍæÊc‘çÉæ®ü)Ò±Š/a}øøöæúï×ï.Ž®þv¹•©ˆ~üáã5Qw7Woß_ßÜRñg‘Šÿyßär«Œ–ÑÛï®>Ý]ßP»æY¯Þýë2I’èêãÛëwÔôî#Ïñþú ׺ûçÍõíå/wß_\߇š< OôÛÅO¿ˆM çÿþBÄÊæéæ "N¬•›ý…NUœj¥BMsq{ñqÂY«ºÊÈDÄRer…“2Ù$IlÓT.X™Ú8SR1+e ¼H„n=VtÆ_»Ó±uM`šM…G… åìjÄf+ulu¢ýLWEÅ£kª i´weEÕCG_GŸß»¶¢.§¾n¨²|nݾ.¨p:”nàÁîx™ä臎Š%5Ö-¯ðXMsÿ‰70;KÆg[VÒÀqë~^Í“q; ÝOç¹çÜ»¡.\ÓTùcÍ›ŠîHÜïÝlo,Z@M+¢pµmª¾§b¨ŠÛé.‘ Û$Ock„^^x·w¬Ë²jQp’WôÄÓ5/B’)HæEt_·îÈüD»›Û’7õئێ[ïyÒª¬IÈ€Þ»öä÷f*ïÐÄVÉÜïš6™™Iü€~ª½’åš¾#ª+ ‡÷Ç"½ŽõÀƒÑbþ,¥.Oû~ÉrbËæ/ºý¡©†±Ô‚< =Ͻ;ëLò\Rï)ËéÒ¡¦}ÓŠdŽ ¬UØÊ(|‰g@”456íA”kXÔŸÎ&‘Û žÐV¹â‘û† ´É7pÙB÷ wêy²áÑñO|Q0á}hì:"ú¦{â^¤î@¹5SÒY{À ä(·@ùóÀwbv$ë¿€¿ãÍû=~hû¡r%ìX*ÍÌ–y„—¶œ¯¬÷æóší¡¯¿ø&)}÷u{ªÞϪ@`àT¤bÐæJF/4kç¢m÷´ š6÷æ )3Z/%TôîtäIó°q3n<þÌ]jë÷\>:07Àê@ÁK±xuÏ,˜¬3hz ‹óɈõ+VLKô—j2bO+Flz-Ä{Å,ÚØ@9aÂûÏkVQÅ1uú-¸ƒ¶$ÙM"re°( bEí«ŠÓ¾\[ø›Cé€SùeY9 -ñg6®\ŠlÂÜAå ë˜éYÐy^ìÖ»–,©Vq–ëd)ÁõnGÚˆò¡ ÎüÌŒ?æß´™z*³ÉœA‰uʇ€SYY2¯åpåG.Q¿þñ4”ÝOØqcqtý£—.ØÎ@mA’2žDö™ZXfæÀ £ñ— tpw-ø§Cw$î+¨‰ÊŠÞL„ù3©Øü ÕuŸ‰òÊăزùž\׸ž‡L“ã}®úŒ·r›/Æì=5\&CÔíƒi`çK,R ¢Á5NK{íÝUG^cëDpI“_m‚·;s£}½¯Ñtú“[u‚fæS5î@Î FÊ@)›îÛS=È3»a€Wè°ÉG¦¬?P;9eÉPIEìÏçÎ#õhŒÏŽ­‚Ÿ—ÑÃÉw†Š¦S(G+2‚Öy†Ø€x­‰ö¿fäµ içºMÐZÀŸª;²s  …®%§i¢ NÒog°Zæ"ž/F?y屬PÆöÄ ­8ù™˜1ž$h³èúF¹˜Ýâ|DcÞÏyÝáî]L=BËñ2SËF9™åTÇ€gƒé>¶%¯!Éaňk+%l°ôd±° ¡ Ýû€gÉMô܈xt_p{9{P¨Ù“Íç÷…Ðì¨÷Ä…|„X~ð 1¾™ß&ŒÙu“w‡¾£×-O£8ä#zDª;~þ Øþ<ÞÕ½»oVÍÙLôæ†Ì2£'3ÞöóÑàKÖc,‘huÆz‹Ö¨ª~çø4ÓóÔxPѰ˜lëknÖËd–bt˜bŠÄ¬XnÛšp–=XZrÎ3!õSx¸ÁÃHTC8Ÿ-Å~ºÔL,cÜ,˜@ëòKDae¬sm_³´Í§PXÙèºôŽ/ GËÆÉIJçͪ^$2‰Ež©ååøéÜÓÊÕèôBç¯\Íb¿"gÔt®œo8Cì+ÏwÏløIÇV¨l)£4ݶj½¿4#,¶ñÊ¡Ï| Ú@ÀÿÜk‡†87O쫇Îd.¹‹Ÿ™%Lë §4³˜h8 &‰‚ÂÌk昧V¦éNuGûv û`ÔÈ!ÏW£b‘ˆd5ø7ìõÉä $è Œ%ÿ àw§†êv‘Aå—ºbcdB´oØr´ï]›ã%hè7x £vw @´£ú ÝNs½Ô7“ «_UŸ,O“…úÐ*wØØ€Èo´Õé’7èÔÞ°ÈõÕŠ´™H-_z6Om‹¦ríÊÎñ†X›™¢Ü Žáè>7¸M@%­µ9@w ¡ÆD+ç?®[`ºÇÍßy—²v‹Lëzê03cÕ ¦åkè1Ù”'#z¤úe6kØo ]ÑñX/w0ÒQ‘€H.XÔ€èv³‚# @NUœ-ɨÉÚ@g¸s÷fÍÖ˜S&’ÐJ†Žár:&Egˤé”È.ÔóÌ'²bÌ^r²€¨³ãÉÌtJv-S¦itóþ-U$Ö¦~æ,º­ªóĶÎÒ8± B*ÂhÌ0SÛñaCÄÍ,%=vßÎúSFzŽÎgE–ýô‰NqHÊ–[‹þZ¹l2«/ÔZêKøÍ÷†j¨€V¿>5€ýX±±ŠŸ(®j­¹\}=4uQcò×—K ½JX÷ä%ë÷ÝZl-_ê²àî äIóñ3 ‰Êj髊~ö¾U_ëÃ4=ΤÄZÎ`êEnÃÍ1‹Ý[/)/¯ÜAšÚpEEÃ9”WWIM,…8Ž3…/§W"N’4H«ÇŽˆ7Ö‘—=FšÑ-ÜÉ0½¿Šun«eIf>%ßIGF€‹Õˆƒ}WS¶’êúú¾†5ÇH^1_'=áß«‘è>?¨81‰_°`a~,"Šêëp™Dc‹ y¿®!Xä‡ò÷ÔŸÆg3±QÁQ¦øUjNŠªˆì¯¦÷Ð^1ãTQq*Ä Œ…ÎëŒÕ:ÎÌÇÛNÿ¨€ñûèþüZS_cá4”¶Õ¼W×c⟶×RiЃkë߃®@mxôŽO®–'#Ëôž¢ù1 ZxûȦ$Îå‹p ¤Ÿþg*ó‡êÝ~ï7dæûç"(›ÆpÍoÈxÔEú+vzßµ1eÍq"adÃÂ(: A„P†hŽ„ijçyÕ™–1ô\Ï/Ó\ âÍ¢©é ¾ÜIòmðÉ ‡T ´Ṳ̂óÇÖšGöÝžkÊêž`„a nØ ÿä1+xFX¢6^N&EËRVÉ,=ÃSPqÛçžHoŒ©}÷þ))¸î„~ýKí¨P$á!ÖUE›`FÄ_>×ð¿^ ‚T'÷ic¤z÷åËóÝ8/W|†™ù‚0Ûâüþ(tõÓ¥ª#±> endobj 1487 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [464.1993 351.3684 511.2325 363.428] /Subtype /Link /A << /S /GoTo /D (proposed_standards) >> >> endobj 1488 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [55.6967 340.4294 105.4 351.4728] /Subtype /Link /A << /S /GoTo /D (proposed_standards) >> >> endobj 1481 0 obj << /D [1479 0 R /XYZ 56.6929 794.5015 null] >> endobj 142 0 obj << /D [1479 0 R /XYZ 56.6929 769.5949 null] >> endobj 1482 0 obj << /D [1479 0 R /XYZ 56.6929 749.4437 null] >> endobj 146 0 obj << /D [1479 0 R /XYZ 56.6929 417.0689 null] >> endobj 1486 0 obj << /D [1479 0 R /XYZ 56.6929 383.5701 null] >> endobj 150 0 obj << /D [1479 0 R /XYZ 56.6929 228.6753 null] >> endobj 1489 0 obj << /D [1479 0 R /XYZ 56.6929 193.1266 null] >> endobj 1478 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F64 1485 0 R /F49 1358 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1493 0 obj << /Length 3181 /Filter /FlateDecode >> stream xÚåZݓ۶¿¿Bo¡2‹OÌ›_g׉¯m¦qfÊ“xÇ©ˆÔÉ—¿¾»X€y”t7nŸ:z ‚ `÷·ŸŸ1øñ™Ñ1“™š¥™Š5ãz¶Ü^±ÙGx÷×+îæ,ü¤E8ëÛ›«¿|/Í,‹³D$³›»€–‰™1|v³ú-úïn®™/„f‘Šç °èå«Ì9çÑË·ß]¿¢W¯Þ¾§Æ÷×/穊nþþË5Œp£´ïü—ïß½y}ÓñûÍW×7ÝNÃÓp&q›\ýö;›­àP?^±XfFÏŽÐa1Ï21Û^)-c­¤ô#›«÷W?wƒ·öÓ)îhibmD:Á!¦Ø£³8‘BZö¼¬êv]ìáDRGËz»­+l'Ñ~ÎMTä õutWïéES´mY}¤ÑÃŽž9½{¿Û”-?qþÜGM[l©[6ô¾­©Ÿo6õ‘†Êª-öU¾¡^U´Çzÿ©¡ií:w„sÚ ßë²Z¡€ ÎãLkaö1±zð½LE„»ÇgYÑó—ï¿ÃxÆ 5»|YPóÓŒ–iŠý}±¢Ñ×/æ ÅD”;ú«zyØp€Õ™u€,§a<=>Ý"õæÞ­lÙf7ì€t¦Ž÷Úòªh–’³Žñ!—yE|ÓÔÔº-èyhpŸØjk?‡ÄÍm^n¨ug·Wo©WÚ¦\9 ·ùòµÊjH 7ì^t℞gŒ‡`òYwš;<›Ìàöh¨lÀ&΋®?çÛÝÆl& h Íì@R$±ŠØõ¦h¿BIe€Çü)bzè.¯Üp•o‹QT, È%l8Í4FŠng)AËxb è£RÜ}‚¨r„ÃI2–<õd "ã®&èé8ÕRõô8íyûÃ÷ÅYŽe½ßÕû¼-hRS¶…›FÚD_ZäÁ qlӱΔâ-fÚé&uŽe»¦ÖPepÄÃ{IôŽðÔÖËÚB–¼~GÁ¾ÓAlæÕÊ7èY|·°*¶%À!ß—úÅþ¬«‚B²¯~úÒ}1¥=Ö–z>¡¬±é!µlËÚ¡º¾sú1@ñ õÜáÑZ5œvÊ“ßzÄ>Ò‰ÝávSz¨ à…;ÌbÁ•ÁK*s^ØQÆõ“g)zn¬jˆx*ò™ÌûÌ$4‰Ðóî/ Œ#t¶‡Æõ¶p\Òil43c@ŒM¦pñ>Weã³: ϬC‚Fg»¹ÒîÍ~F§NÚïA(îAëÅ *«åæ°¢ú€ðNR²ÀíùθŽQ¨iS’ÛCýô«‹8%›àØé“så}o?;;«X_­Õ³Ê ôå‹“|ðÊ/x‹ ^`¶ŽÅÃFìe/a9a&òZ­JTfÔ`Ù©¡Ï¨§6Æd¬Ÿ S2fFˆ³g,fÉsU \®UŠŽÑ¬I‘pë.ÃÄÑ]±,ÉØ±è§_ið‘ÜqÐF÷®NÃc-š°c6/µP3·ZvQ3šg„Í¿¿þʃKMKE»Ü”«ñJç#”·å*°åðÖÙrðVÚ› tŽRU+ë—ð³b™¬— W^T§Þ9ÎÊæ.§ÊÂñ[䘠ás1hs?fÓmêú máiPÕS¸ÌH@&¼)ï= _ í_·p^·h˜k‹ž<‰þ9×:¢ª¬ëò%1ÇÄG²x1J·úº¬Ë.ƒ‚®ßµ¦jO½Ø4ežnŸx2ÆuáZƒÄ‹²C—-Žê¾ÃÒÃiÿƒÛæW¾dæèa©wTvY“’àsȳo&”+Á ˜œfvù¯ížÀfxAÃãTIª¸½~;_$Œ(ã“3zz¤âþ©jÜÂòÞ"À$^xPÍÕ¶ŠjaeiçFI¼Ø²‹U˜u¾¹scî H·.—zö–Aú’Ìà EöW(h2uÒOêÃ"è¸Ê6]Td?,&jã!–EŸ*{*–‘þt…#fzýÁAw¦îu6ˆ»@p¡LB†Ë:”½wò¨!-*é`Ë¥»b¿™óèÁÞíÙÈ[õÕªq©ÏWXvêŽå‘Â4cõ³|V€'Bó`–5°O»6±•¥}àCZ9ºéŽwÀ=OjÞÏ]äo¤£`fÌȰ¨‹/}Kº:šÚæ|ó@Ï.ØRìcw‘ùò ÷iˆ‹ÿìhàÜfSÁ´ßá¤- ,–ç{[UNñ=¸R ]W—¬hs²¼*ÀhÆ.”k—ŽñÄÁÚ¶jzºJ%´vs¤ óÁÝ![²ævµ}K‚˜ÂµGh@Þ² ?xŒÐn–¶ây˜¸¦€€#–¦KŠm‰{"þÉb“HïxüRDÊ0ÞS£XÿÉ€wr .ô°šG™ÊäÅge<ïÒCã¾Ìýr¼ø¹w3ýý±‹&p¶ºîü^Çyƒm“7~CÞÁRÍBoļœ'n!uC›=º…D '®‰ '€ðãÞïíLŸ¡ó—žáÝÖ7§þþÀ ‹›<ûgŽp–ý·$AšM#Z”-ðt¼(ÆÚY¢Òó«v³/;ŠÜ¡­’á²o rtç;´<ô °Fa|"%‘:Ö “—Ó|™ý„´K=3'Ó%Ã4ÿ”!¹°ÿ¼ƒYg$èg]–à¹U Ž—–`¸ìÿR‚j‚²×ý_fNñJÜØ%гÎðÊϺ̫s«¼/;Í«pÙ뾬4Jýå_ 8ô¥iÆcè¡ìÕ¼/ÜÃÎX’Œ’»>J>ÉÿSqÛ“\‹Q±–ú‚ˆ‚I§%ä']й%{ùŒ×œO¸æÿŸSIt,»`Š‚I§eç']”ݹ%{Ùל”]¸æeÍYÒ¿‘.ËOƒyÓiú$ù%Ïö$ÿEùÐ𯨼dÝ¿ù¾ø¯=DºÆˆi©H†ÿîËR¿)Ü=×ó‡MˆèÛ×oÝßz38^,ïÔøPÝ¿fŸê?÷¥r endstream endobj 1492 0 obj << /Type /Page /Contents 1493 0 R /Resources 1491 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1454 0 R >> endobj 1494 0 obj << /D [1492 0 R /XYZ 85.0394 794.5015 null] >> endobj 154 0 obj << /D [1492 0 R /XYZ 85.0394 714.7215 null] >> endobj 1495 0 obj << /D [1492 0 R /XYZ 85.0394 685.6298 null] >> endobj 1491 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F40 1265 0 R /F42 1338 0 R /F14 1060 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1498 0 obj << /Length 989 /Filter /FlateDecode >> stream xÚ½WKoÛ8¾ëW9ÉÀŠæC/®OiãlSA6öî¥íA‘™Ä…,¹¢7-úßKФ"Y”³h¶E€g¾™ù†2‘ ÅrÃDS7¦! Ýlã@÷Nìýå ­ã%¿«õjéLÏIâR@#¹ËÛŽ­À$AîrõÞ @&ÂôWï.–‡Ð;»\L|”aâ½~szµœ_+¹Q==ûw‚òN/_ÏÏ:Gää|~:‰oùÏõ|1ù¸|ëÌ—-Òn4 ó³óþ#tW"¨·„&¡» ¥ØÝ8AH@b$¹³pþn vv›£Öì 0‰°%=ÛÒRLšô¼aÕ%±‰ Ö\i¡Fö%Ýls½™•ÅñÝn‚¼*­×¥Vº-+5©ïµ&gõn«¦{-ú´ãµš­Ϫõ [iW7åi' ò.ËšSimf”Ë"<@äËBˆlø†¸ ­Å(ж.ÊM#˜)‰BÝßR3Þ—{5©K5¶îÚ” ác¹Ó†¾–…–I­œñ?ÔŠ3vÈB!h¸qƒ(Ž‘¬˜Ú¬î\5¹î”¸Õ÷»†%Ú•‰X°ì):Ð!š€Ä‡(ê¡ЬÕzÃКĚ ‰*C†I,*•’FËÍ‹¢fU‘æÆYõÀª~îÿ”v¦çA×£¨{€¦ m¬¥™0AYYe–«å75 ñNq0ÓB*… @]á÷™¡&€Ê~î™g_læoR.“í¯·Ü¿+ý{V±sAc®ÜJõÖ†Ô0ÛšÍ:ØH>"”Þ§ÕJY• 3ëk)›Ó©RèiK¶wÃS+U ~Ä—ÜAúªÖä4Ä8PWø¾Ïlþ j®ï&9Oó¼Üûu•üVRFÊ>À¥IKd3g;ªkYˆcƒâÙX1^Wë¬V«Ï;V=j\YÆ8wÛQýv@ÚÙËF€à#@*–í*.[ß‚]xR9ÂîôJúVÛ»ÀVÓ ‹)Hs·Z‚Pw®Ô8áëš! ¿X +7']:€=¤õã¶çËåíÚ:ÙL‡NŽòbU"‰/Œ¹•„#ñµy`mÅÊ|W·¬}:V÷tŒÂì‰Wû‘£­ö+Œ~ÁÕòk+þÒ˜dL¯..õcŠ× þU ^‰öP4ˆÉ¼º†AýoÊ/endstream endobj 1497 0 obj << /Type /Page /Contents 1498 0 R /Resources 1496 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1454 0 R /Annots [ 1500 0 R ] >> endobj 1500 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [389.5011 743.8714 438.2478 755.9311] /Subtype /Link /A << /S /GoTo /D (sample_configuration) >> >> endobj 1499 0 obj << /D [1497 0 R /XYZ 56.6929 794.5015 null] >> endobj 1496 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1503 0 obj << /Length 1089 /Filter /FlateDecode >> stream xÚ¥WÝs£6÷_Áä ÏYCó”»8×ÜCæz¡}¹»É( l¦qÜNÿ÷JHØØ–}I3ž1˲Ÿ¿]i%ä@ùCNH$‘ïL#Pˆ¨“,GЙËoŸFÈÈx½7”ú&7$t"8pâl`+0 ‘§ßÜ¿]}‰g_ǦÐõÁØ£t¯®ÿ#„Ü«»³kýéúî^7³«ñÔwã?¾ÎáHéQ£ßß~ÿˆ?fñ6¾aÜÓèÛè¤2•Ï#HRg-_ @Q„åȧPŸžSŒîG¿o ¾vª6L(  ñÔŠ Dˆ"Ÿ:S€`Ò²d¢áµ{„î?ú¦ Èr©9ÿ^ªL¥;!QŠ;ݬª×¬NÕí¬(ªµ÷Ôòz³'—ÒÉ aWFå¦f¥Èxm×ïCíô·Ú{1hã“<„Eº"߉Ì^´9Ýß!…¡¼*5cQ‰F2ÑA§^?«¸TåwñüWíË·ú2i%…„£:À öM~(RÌ !s‡& R·gž¿ØÌ›Ä¼|%¼yå-xÍÏš«VJ|kCIôàî¡ °5À[c0™hƒ‚-W×´­Üªe¥éªä]N¶™µSJ©v¶ŸûPRž±¶hôË cY’p!N÷çqs³ró*5M'ÆeÂ’?íòh=y…«bÛ—ç–™=œš'm-Ô8ÆNä=Aœí“žíY{ÎÞ±¶Þ{6äß²!ltüNâBä G€¿t@R-/~ÚþÍfe´õÞjE:Ëûx.–í$«ªÎÁåÛú•(¿·ðÿ Ãúgù‹‰öq6Û˜beÕÈMëÁìcjo~X²ÍãùUþ(­H¢WÌ-sk¦ˆ Û2ðTZó#©¤d嬊g‰H™Y Ë€}Yµ7Vfüð§6f/sªøíÛLƒB)ئ–'Oòl²7'gu²Ð°œØðK¶äý`ÜgØÖ§ÅÉÛ¬û/ä ?À¦TÍ Ó•§¤±‡ Üâ¬uÃa¨“¹l=nÿdú!UÝ(’ºó6O¹æ6•ùÊ›&/çú¥]ég<–§HÕ|,1%LEÉš¶£Ð寅*‰ Ï”QºUã©qqhA¨8o6&LÃýp{w 4yÛØPL¹HêüQù$ˆºÉ‚•óþE¥Ñ=U×t_Íɦ­™v¬˜ŠSf4×¼(8 ÖX\0±~Ñ´l_M¤š›©ÆVDšgН֬ú\{ß÷‹-żLŠ6Õu®U§TuóU¯’Ìà´5ÖìtöЖŒ¿øÆ(±2ÕD+N‹‹|¾_^É[çÍBSºH'n„uü·œûáv÷}÷-cw­ò§€„!Þ^ öVq4íƒR袩\I2Ü¥¡ŠäÝÔö¦rœÕº™òendstream endobj 1502 0 obj << /Type /Page /Contents 1503 0 R /Resources 1501 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1454 0 R >> endobj 1504 0 obj << /D [1502 0 R /XYZ 85.0394 794.5015 null] >> endobj 158 0 obj << /D [1502 0 R /XYZ 85.0394 146.2062 null] >> endobj 1505 0 obj << /D [1502 0 R /XYZ 85.0394 108.682 null] >> endobj 1501 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F22 1037 0 R /F21 1034 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1508 0 obj << /Length 2441 /Filter /FlateDecode >> stream xÚ¥ËvÛ6vï¯ðé¦ôIˆŸééBqœØm“fbÍlš. ’˜ð¡”Íœù÷¹¤(‰yÌŒ½ pÞ÷“â—üóË(fq&²Ë$ Yðè2¯.‚Ë5œ½ºàîŽß_òÇ·žÏ/~z)ÓËŒe±ˆ/ç«®”iÊ/çË?=x]†À›ßß½ºòYà]ßÎÞÎoÞÁ6 à ]˜½øÇçÜ›½¹¾yAG/ÞÜÓâåÍì* ½ùßßÝÜ_ý5ÿõâf>ð7–™ûtñç_ÁåDùõ"`2K£ËGØŒg™¸¬.ÂH²(”²‡”÷ŽNí«“:á2JbJ)QÆb)¤UÊó»7(`yÛ¶¨T[”{ÚšÝvÛ´Á]Ük ૦utû Ýºk许GàØË›ªÚÕE®º¢©Aµ2¼ù¦p8‹:/wKmÅ?›Z;d­ªÍ p€–Ÿ(^ÝtÅjoMòu‚ûœ³,Š„•BÕK¼xíO=ïZSè›6ïðĘ֋}§aÏiwûzvíßßÎD䎭Òp¡ áƒV!ÇZ,ôÒQX4šM¥æß›zuL"C+ç­´gí†&CFÒU8ŠÖvßx[+SôW(,¤k>ÔÝ-н7Mç.wÕõ+ªÔç¢ÚU Z”º^£©[²Zº4u*ä²€^Æy½ùÔy‰îYÅÕ¨u£bððâ#“{em øÀØ 8¯è¹©TîCÔ[”ö`AO0²¸7nÿ¸Ÿ»wFÁ1íoD\<ûrŠXØv1ãÐißõ7°ˆ—S…*“¾Cî‚ÿ·1Ox,ŸøÇ ïy˜.Ÿ<˜Dz,4ô<´3–ÙÁ#`Ó{"åq¬JÄIuVš ‚óq Ãëf»rÏðã±à,Ö[Ëò ÏçC{ø&˜zÌ·#׺g“›¦˜bßÐG”Ø É›­&}ðˆñ3£Ã ~mé_ÆMÕ'L‚T<¸.Lå^è¿XªC/Æ2Ë“µšLw/îˆMÄìËùÛ+.2ÏuAÆôýP§K½Ý4µv{Ýåßké,sWÃVMØÆ~01çce?ÄýxEž;¿ù\˜Îf¸oØç®Rkœ^ÏÇ™²X†é·ç¨ ΢¯R&²(‘#L®]œÂ³(¦75î.³ };2§ÃÏI§Rôå9ô5½ëa¾í?CAsþ£™ú„qQ¯«–,oêÕï1Ôê8îuAÍÉdkÂИf!Në“I ‡éÿ¼µY'ìýçøƒd¹nÚ¢ÛTg}óÏSžk\TãݾÔNü@¯ú')“ÿûçiŸ"QÂq‡ž¤ýÐÙDö~zôq/:ú€[7pùRpï¾ R `×ñz†ÔÜ ÙȃÁú„¢ë¢LäËž K¸Ò BÝNKBŸÄIô=à—4f?bðÈ«›ÚlZL5’ÇçԹÃT†ÅoÒðwh^Èa °Ÿ›ñ¬GëüAv>DmFGéBß@M;:rÊÔqŸÍîÅ~B;'ÞõUíDK’!’Ø—~Ñß!&~†ø¿í8ü¼&L¦©øúާÑÏ:2ưÿ 5¦„ÇÓ3™úLÎ…ú±ýлendstream endobj 1507 0 obj << /Type /Page /Contents 1508 0 R /Resources 1506 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1515 0 R >> endobj 1509 0 obj << /D [1507 0 R /XYZ 56.6929 794.5015 null] >> endobj 162 0 obj << /D [1507 0 R /XYZ 56.6929 662.3153 null] >> endobj 1510 0 obj << /D [1507 0 R /XYZ 56.6929 634.3021 null] >> endobj 166 0 obj << /D [1507 0 R /XYZ 56.6929 587.9857 null] >> endobj 1511 0 obj << /D [1507 0 R /XYZ 56.6929 564.9659 null] >> endobj 170 0 obj << /D [1507 0 R /XYZ 56.6929 418.0778 null] >> endobj 1512 0 obj << /D [1507 0 R /XYZ 56.6929 395.0579 null] >> endobj 174 0 obj << /D [1507 0 R /XYZ 56.6929 306.0653 null] >> endobj 1513 0 obj << /D [1507 0 R /XYZ 56.6929 275.4022 null] >> endobj 178 0 obj << /D [1507 0 R /XYZ 56.6929 229.0858 null] >> endobj 1514 0 obj << /D [1507 0 R /XYZ 56.6929 201.0727 null] >> endobj 1506 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R /F40 1265 0 R /F49 1358 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1518 0 obj << /Length 2743 /Filter /FlateDecode >> stream xÚ¥YYsÛF~ׯàÛRUæd3¸’'Ù–%kÇ+Ñ©ÚÊæ$@ (hZ»µÿ}û$dUj‹˜³§çëž¾hf~f–„JÛÔÍâÔ©P›p¶Þ]èÙ=Ì}adÍÂ/Z W½^^|óÎ&³T¥QÍ–›­Dé$1³eþëüÍW—×·—‹ Ôs§.a¤çWo¹4ÆÌ¯>¼¹~ËSo?ÜqãÝõÕeìæËO·×8¢SXçT$;—?]ÿóò·å×ËŽ¿áŒ¶ÈÜŸ¿þ¦g9\åÇ ­lš„³#t´2iÌv.´*tÖú‘íÅÝÅ?:‚ƒYÚ:…Ih&A<JL¦*²%P®Z¼k4oÊ[ñü±.«ö¶-xúâ‰~ÕþÒ$ób]ßWå¿‹ ±A:_ ‘h¾+²JV¶™œQnüˆPmŠýçbÏm!X”Ÿ Ù˜yRM“Ýûå}Uä<¿z:e¹Da¾B¹8 cT†Ý´.¬vóuVqŽ.7OÜ&–°dí¹k¹ØÌo6_[ÄCÈMÖk`xsØnŸúcþ¥uPäª5qO†÷7uÕœR‘kb{uÆb¶+¦.èo¯pdofÝì×Z§¬µ)­=Qîra´Öó›ªi÷‡u[V÷¬÷"=¿ëäƒ5?5ÅɪŸà\>q¨mp`àTꌣïÊjMü'Ègí¬G07ÒÍyrU´Ç¢¨¸Ókn<ÔM+»ëjëÅ Úg=@I§VØÞš–é¯d¶­·rÂñÁ“†¥¶ö¬ð÷Ъ»$UŸ”Á¦Þnëc‡$+¦žgyÎZÛãØ2oÞ¹!jÆð6#xïD®Qçj]W› „£@QÊRT±­HdSï…¶¬·FÙØ¤²4T£Â8ñ«^É=6'2¿ùØ]L´XnZo&NNRÛ œL씎R»¨e¿@ TÚ¨( SеT%IÌÊíåé~;÷þC2ó;}=_DhAÌ*ùî¿ßÑþÅ v/<9ñ ³„–¼?lÛò‘¤§rbƒ’fO<´’©Gµ`K ú¶:´À ¸ «ƒó(”hywó}ÍPãuÖx­¼¢˜ŽÛoÀ8îëíËÏ뛘P$fžaL@òØqâX/‡ªœû¬bd`=lDUÍÈ Ð²ª0qõæïÜÈ œ®JT3!‚”=.ƒxœ§ì:ârÁëà „÷qÃf‚R –ÈÉ<Èxÿ4E%…裋~Ÿ Òˆ½ZͦØOÐd'0©û … 5pŒQÁP9˜)Š«ÅÞ,ÞO6V‘éX¹Ð=lh½‡ÂùCF Û)vÅVñ¥Cò‚$P%¸yH”%$ é¦&âŽBM[Õäµa çc0v¬ÛÜŸÈsyž¼È'‘1*NM|î3HµGϤ~,måC¶{ôλÞx1q|‚Ilôm(•Óè6ÑÎL¡îã¾9y’ÉèÐ8«m’qt8:wð_üž î„°Ï~uÿà¡?A_®¹Ã§žzJL½©‘ðn*æ>³¡Ç¬9÷ «§Q”Õ —R ‰°‚ÀMÙƒíA÷´^ІK ¡¨dç–á!G.kË]QœKŒ†¸\»pf­V‹,[ðäþ~ÆÛA£[¿n8¯sœÓeÖâxR0k(QiþaxÂYÁ¥[õ#±Q.$FŒ óJ(/›õ¡i:ÞêS¹ïjŸ“Jxl‹/%†Ëç"4!Øê ð¶šÕmñXoËõTޡɵþAvaÒ´µJÅ_9Q×ùÐH|èõ~_ï›—#Û3KØU£oåŒÆèö&ò6F:å†ö j€Urp±xRÈ®x‚|"n- ̶Ü)ö|Üv&TÖÁ‰ìÙs„ZçHxˆœz´³ª«ÅT&$wÀr»ºv%Aå×AJ„`üÝÏ·ï¯oo¹ƒ!èÊŽ2 èwüKCbû_RjûŠÊMH»áÊ Î²Jõ œápWPr@"û&оH_J6uà­`Îý7²&B‚a’4|w ÿãà·ºg<ôŒ‡Æ»8>8¾£€¦—-™Ð`tû«=­*p(~xâž©ÌØ‚ËKîb3±ö½˜O²ÙØg³ 0¸?¬-09ÔœèÊYÐWI»Ý¥¾|m*⺊¿‡êª>V¼«/˜Â£–dÇO*“°µ„ž3§qÖ! ¹žÕƒxÇ;µæîºÎ ^Ö­¨ùûúê-–Ü9¤B¾ïðG˜‚Ðí„ö ‚Vón3@:ý²ç4bTޤ`u,£…CŸ³m‰¦˜*•ÚW*Ïp†-‚³Ž¥èõ8Ó¨0F ¹6 ÕñY˜duLÈN˜+ÂÙ…ˆ3PTÜ!ˆ]D 9ªbk±ë&¶O îw÷CGnâBž… •;™ªmSæ¾³á/ß—ctE—„M”+!¬Qúu3Õl´Ùp ¿ÄÆ× °ÅGšN³t:„ƇCW 6^y ›ü¨Ë›÷ׯ¸G–ut‚\Z +ÂÍ3:q%õ×üw0‚œZP=ŽS ®FE¢#Øc€#ì<¡áiÿ¹@:ý?”‰€Ç”-\ÿÙp:±èéBB‹<Öýñ"x*Jxn¬ 5D¿wÂnÈЊãÔÕ æ¡%þðóííÕ§å>\ 5û5´Óà¨jË5<Å© ",FÝ_%©rIl$ÄñŽÿÇï$èÂð&QQœJxÓ¯ NòßÐ¥Ãê6ø±€Ïú!«ÊfÇ£"Â80\C ³P` t“0áñèƒOp¸¯ÖúAþMÁIú7GéßrÜòaŒ2XlHQ€ïo2–ìÙŒJ.`MÚý0NòÒÚøã¬ \6º«(ˆ:Er°ø—v0}¶ÚkYšJ®“J ¾‚a‚ íyCÖÐs¿4´8Pl©ÕÀšT(`J‹±pÃ[$-C"U1¼ÞÔ¿¿6Tø—íDê »ˆúÿþg¸ÿ+ÜÅÊ&É39X~•iì™B@ \Ò¿7<Wvññ,%êþ]>¿Õÿ¶ùÐendstream endobj 1517 0 obj << /Type /Page /Contents 1518 0 R /Resources 1516 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1515 0 R /Annots [ 1522 0 R ] >> endobj 1522 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [101.3082 326.601 169.9802 338.5012] /Subtype /Link /A << /S /GoTo /D (dynamic_update_policies) >> >> endobj 1519 0 obj << /D [1517 0 R /XYZ 85.0394 794.5015 null] >> endobj 182 0 obj << /D [1517 0 R /XYZ 85.0394 718.5038 null] >> endobj 1520 0 obj << /D [1517 0 R /XYZ 85.0394 691.1994 null] >> endobj 186 0 obj << /D [1517 0 R /XYZ 85.0394 491.8561 null] >> endobj 1521 0 obj << /D [1517 0 R /XYZ 85.0394 464.5517 null] >> endobj 190 0 obj << /D [1517 0 R /XYZ 85.0394 313.1885 null] >> endobj 1523 0 obj << /D [1517 0 R /XYZ 85.0394 288.6895 null] >> endobj 194 0 obj << /D [1517 0 R /XYZ 85.0394 127.0564 null] >> endobj 1524 0 obj << /D [1517 0 R /XYZ 85.0394 94.9508 null] >> endobj 1516 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R /F40 1265 0 R /F14 1060 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1527 0 obj << /Length 3325 /Filter /FlateDecode >> stream xÚ¥ZÝsÜ6÷_á·®§Y•ŸúhžœÄiÓΤ½Øw7צZ-íÕT+©+­÷¯?€õ±«$7sã‹AAàj奀?yiã(ÎTv™d&²BÚËb!. ï‡ É<ëÀ´žr½º»øî­N/³(‹U|yw?™+DšÊË»íï+%ÑÌ V·ï~ø(¬ðO^­•Ht²zýãõ¯w7àÕ `%Æë7ÿº’R®®ß¿¾yC]oÞßRãíÍõUbVwÿüps{õÇÝO7wƒœS]¤Ð(ä_¿ÿ!.· ÒO"ÒYj/ŸàED2ËÔåþÂXY£u T·ÿ&œôú¡‹¶‘"R:V ÆQjÉ86‹b­´7N¿sŲlµo¶®{qµÖR!Ô.ï¯dºú(„rë]UíóšØÿtÏÄâ>»¼~p`;cÓÕ«¦ßÇ®éúŽxòΠQû¯cI-±ô ÊyíœË" ÃÏ7ÿÁ3¬¥Œ2k•׉¦-ÿ„Ù•ÆÑVäU¿kŽ(Î@Ų£¾%þÐW7=±Ÿ Ý^hxn=[êí\ÍÃÊš:rzüÝÔ½/BâÕ˜€’“Ò2‰LŽ-¼:w¬æÉvª ÷:0ÑÂMá:|ìX„cÇÂuåC ‚£ÅÖÚÄQ–Ùxn¹= ϼ(­Ã€µRÙÊ•àjožñ™®îà@¥ážé ó:j¯£ïcÓ«žÇÜ/讌¡äWu7"±Ìä÷ &ÌéÑíòq@ÊÎôÎëö»œ[…÷eTˆES±º~cÙŒ,¦ g:,&g£ØðTz߇š&ZÐN¨0±ùªz±Lf")aμêjyyáÉòZ>=ðܺÊõÜ;3¾†`qÙÐ*ù¹Ë™—ù±lŽ]õL´W»CÞ»mD‘JGq †XƒÃf†\hÙ¥„( ÞöEµµ€­·fÉ£µÍü6ûg]ö%ŠA¯èŒ:öÑ_‹ªô‡Ûè•øìÜáÑ&ìžVoËúa6v< §â'pZ„øŸä×Ìô×Ñx-<e]TG^HyýÌѦ‘ãlîVyËê·Tƒr‚ᮣԅo¸ãøÌéáeÊÔj? Áé¬;d,ÌmÓüyœôø6ŸÍ¶¹’«ºs˜´YAàõ½èþ &+@œŽ'8¸;ÌüTVÑ‹¦îs |$Þ¹9OâõçO„6›ó,H ªµo$ÞšD9µöB¦ê"Ì%ñêú¾÷A X9þC+$0Œz2^m(ÁÀ6?ôeQ¶yÝ3+%'ìs5§ –õ}sØç}Ù„XÁ¢ÏÔ n ô°/kΆ>Õbcv\ñ}8®/Á”JœîS^ôÔœÇ}?{ žÍ/ÏÕ©¹àÕi¥©ýªSKabŸç“Õ¿wŽ‘À±ón=Q&'möt ³fÂÎ==$ôsñŒŠ$Œ¯‰—ÚTOă]4Z?ƒà ;`ËŽ¨ÉÁ ¶¼å”Õ–Çõß·€ñT¦`ÄIv&•Æ´ØQ«=nª²ø¢Á#…Q …ý×Bá™aëÞÇ6¢„´ÎK\œ†  £ºŠ· ÖQ³uŒ¤Ÿfýt8~£äú]¾çL ¾Yû¸„Y¾µPà—!-—eåÀ1`ƒ€`Cúð›Cuh›|À M`€¢F ’EƒÈcrç3¯-áYsZQAÇ€¡—­H„¨MäÈ Û=±P A¦¦ö h„¬Í RÕà;~º{z’ðÚ°ð“…þ¬›§ mÍÁÎ¥à}˜eó<β´C>E¾<1SHœ„ø¼Èh³†1TÞ÷nßös\V5ä\ž¡Þ~¶æ1¯ÊíÐ3Û ,@—6áÄæ(ØœB0îê=ûí²­ÜzÜôª×¿òrb—ïÙ•ÊîDÜ BÈlÀyìEöMSäY¶mp³SðÁVv @¶d!–u 3ÎA7¾PCé$R© ˆ­e¼™Ï$¤a‡‚c1öÂ!Î" SžÆà”c0ɯFßׇç¶oàŒ¶»² D2‰=%¥ë˜¶0³|çÅ3€A„ŽžmÓuå¦rôÖC$ÚQl"l‚´w“ݺâx(ûgzC3“àFLí—Å ñPƒ‚ëÍ`ëÙÅ‚‘ †<¶²`,eÓyävŸzWw  U™1D'<×4WÌŠ’V¡FhͬLSH3Lã³­fÖŸ¼”¢ÆdÍæŽ­ëŠC¹ñ¤Uˆ!ÛùLŒœÃì\Ek.[O#EH“§®Š·tŠßÕtÀ€Öqa)%¹ó =!§×!{žâ8 èõŒ+H¦=#Ðg‚(Vú4)Èá<­w-“žÀCwD¥«$nx¾û¦ªš'Œ k9šA…@P±E!„Y}, á!†æ˜BEâ#sPHðrN…¦JyË:0–‹ûÔVP™ÐTñ0Õ¾™2>ÏKlã@O,«¼¦)ïÌ Q•\½[ÇÙˆ¹Í,Ú˜H™,5ëÝÂq‚Àc3 mÓ²3Ƴ?U"1%`xÜ}þVUú ŸØPø@öüyŠ „1ÚÚÕûÆ'šØ†À‡üžå‰´Ø<¹÷¢†AMÏ„§¸r}¨jS£íy¤Ý–iÅ[©RFØ@xjR‰ Ô-/Yô/¤¡ßôÓg<é ÊžÍó8è|CTj#k²PଷK;b#%S5Ûô4“0N…UØo§Â¯F¡8!R!$D”ÄI2?%‹i2Rѧ4PÃ凪Àâ°+ÓÌ]4ûbå…YDZ÷!ŸÆ©1Ñ‹Äá^¼)\GÅ >c\w¬ÇTfí°tHD8n Å/8+¤ûæÐQ'– S›OÅ‹'˜ –Ù•Õ–Ø0äñH–ÅW${@” Ç“/Œ«kÌ~ÆÿÆçRMá”ó¢Pe ÷°Î@õšfz¸ Ù2ù™Èœlõ\|^‡zî½@Êé}8v@*ò6çd®Ã•LSÖ„nPqA©iÃE£"@;9{)Bœ`¼-› bЦ2^en^Nä›)‘áf¾t¶6™8 wÔon—£16ýÜ-ÇÓ'’áçÃàc ia1 7/:ʤ‰ç>üÖ£V ]bk#ÅwD÷‘ Ÿƒ1‘mHt©€ÂI(!ÙR}¦nΔЮ˱½X樉^ŽCå6¼C1‰¡êá8^,À4œ%QžÙzßtKð÷°™Cývj0ÙOظš2çË7Íãà#Áo†Þò´t>qYá&@:Èêá0@3i¤:’ ¡ `(c~Æ*}P˜Ïd_¸m–Y$¡lgŸÚÖí5(EÆÂ”18©ÉäüÚ0ú~~fÎïÚCÍ2Véì„)@~™Ì]Ž3̆ïlp%BQb¼?Å—¡Ÿ>±ˆ X™çà†ßÅø“Ëi/µ¸bU„S©•Rph΢,WAª~ºÂ‹%¯ôןósËx ÐXh°tÒé$'dö7ºrrñ¿ß žƒ.w³Õo ó±U¡ÅW·SøZõÐZ”rYCèOu ­þ¹åÖâ§­821TT¿ýòþfùÒ[«,„Ã4åþtHDÐÚðJÇŽ3FRKªOjJÌx +ôþœêa÷{Wo/À¸Z¼9i¸/£Å˜”“Ÿgi¤tzr¡[œÔ¸)QÕC™u·§W¨¾ü-!-*Éä@ÿ¨”Ùƒ®99$ù£ÏrßV푇H›À‚E¯£ö»›»·/©98Uà l|eá[nikÙÿp{}ûãµüòCCàB‹`m¼š‹œIœBMÝÏ; Ó÷ÓX~žbµð^°©‡F‘û”£½Ü+õ¿2µîñ÷9˜o…Û~¿`=‹(ƒzŒíñó\¬o…°ßJ¥p;°KG‰Áø¸ë H@Ån‰ðt'ŸÆÕÃõõ‚?J×\x™ó4)ýÁmü h¬ð3>½7ñD`2úÊþ‡>àù1úx8ô›Œwƒ Ï>~ý3ü=(ðæÇ2€ð. ?mvø¿H3þ‚È$‘NSõåßȰLãªÆ$,¼þ¡ÔJ‰3ÂoqΕú/ “Ÿyendstream endobj 1526 0 obj << /Type /Page /Contents 1527 0 R /Resources 1525 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1515 0 R >> endobj 1528 0 obj << /D [1526 0 R /XYZ 56.6929 794.5015 null] >> endobj 198 0 obj << /D [1526 0 R /XYZ 56.6929 626.8646 null] >> endobj 1529 0 obj << /D [1526 0 R /XYZ 56.6929 593.5117 null] >> endobj 202 0 obj << /D [1526 0 R /XYZ 56.6929 468.186 null] >> endobj 1530 0 obj << /D [1526 0 R /XYZ 56.6929 436.0669 null] >> endobj 206 0 obj << /D [1526 0 R /XYZ 56.6929 238.9445 null] >> endobj 1531 0 obj << /D [1526 0 R /XYZ 56.6929 211.6265 null] >> endobj 1525 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F40 1265 0 R /F42 1338 0 R /F49 1358 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1534 0 obj << /Length 3375 /Filter /FlateDecode >> stream xÚ¥ZÝsã¶÷_á‡ÎDž±àúæœ}É%í5µÎ´i(‘¶8G‰ IÙñýõÝÅ. ’‚ïœéøð\,ûñÛ¥äyòS‹¢yl»zØlq·Ìî¦iãº'ÒõÝÕ%Q$h"_ÜÞ]ýý:a>ÉÉÜÝWn“jX‹ñž»’V>ä§ê…)Å#J¾”.UÆG.Y9Á#©t »)%õŸ øà¾HY}…;9è(ZÜãHßwõS1T´Üî†TdG<¤•åTÍ2ÏDG1+N8>§N"©Dy Gª±’°¤=m}è«’÷kéùXíªŽE“‹¾~Üá»ù¢ê/‘˜‘¾èœî8‡US¯ISJƒˆi’N5Egñg„qøŒ±2IÜ ñÅÓÓ©TÄ‘ ØÚÃÁ“£‡¶£Áä»b‹’‘çâ“/FÖBáùX 4(èÁÇÏû¢îhô@ܶ“uëîeïxl »¢|.¼)dΰa°:@üâ]7Õq™ÐYžÎCaŽ.£Å‡ÁÛ`ñXMͲ¯·uS°A‚@u‚ƳD«}‚Ù4™¦ Fî=†¥„8ž¨§×·Ôyä<ÖŽ1†ÉÜ}ÓðàH]ñÊz׃‘V¥ûUˆkÇês»ãé€_q/¬›CYïo²‡ÒBG‰þŠÓg"5 ÷±×÷´Ë¡ÇN5ã05üÊ_>||÷·_®o¼—q “EùÔúœ| žÖ ÏÝßú:D»ÄðjÌû @@¡þ"=µ tvðÔÕéîÀ"Z¤Uüe'“if¦Fís˜i–TºW0FZ×àI£‚ȞʤB' ÂĦ®v/+U @•rF‰&n{*$€’<1æäN#ÈmÇygßîÊâ¢5¢ˆr>A>”czí+–ß÷Ʊ1G’õPõp£à©q*Ù#`ŠÍ8" `4GêsÝ44âb„,x™‚ùÄp“ ð‘Áßܵ0ˆûèЗv‰Ð¹v±¹èî”Èr—1vð‚@b£Ûۻ߿Æ(rŽE*íÛ‰vb\5ìöHA}]’j ^ô\¡²p”€01`£\X»¾ ˆ‚0+ΜÀ¼«s ØÞ"Ë£=Q!/žn‡(±úfùøMHä‘vxªæƒôûjmAAU¢™hµøÚa©M$ò õ$h¼¾Õ³8ÿäÀnwÜòÒ vÄk®5noÁ‰ú¤ñ±eì ø¿SUrTnXÍ~Å닲tSþEӼت‡}ŸÅ¤“‚4MÓ>S”‡Vl UÃ?èN= )g˜Ìj¶èûÃÖ¿Yüìi!BEü¿ ‡Ï0¸ HX•ÁlC‚ÖΞmüšT$!»‹0ާÇ$ºÌ øŽS~ å $9õî²z(ÍÀ×UXÛO\>Ä%V=oêõ††›âÉ)ÜÅÙ§Áªaò±6 ¼h|µ§Q{Hç0×¥®ØL3Îø"çÙÂY´X¶ôœêÎ’Þ¤ÓÙÿ@¾¼«= ûÃ@cw¡8Æ;Ç''«ò°®Ê¿†âÜo’Iýêý ÁË`xA¤jÒã5£»ßoÜÖcq\þÀñŠi¤QÀו› Æ»LÄYâ‚ ÖÐ ª—±’"ÎS= ëv÷ðµÀQô3·¯wV™T[‘ôáøàóø W=ûMð"ILÆbQžT9€è¦oi4ºGž¢ƒ"YÈc¢ñ4F 2¨•°>³Qi̬lžf/bÄV6±÷n_ï;°‘õ*òø§¶ØB&Nø§ºÄp#cŽ]8SË/œ`à3E ¬îpĶëi–Š8œ C_¥#ǹ3’ëw?Ýü»è;Ž!eÇŽI„Ì|ëŽ6›A&‰§VAÊ‹“/&ábIPMi"5ÃÜLÍy²^MS ÇŽcܾ­wÃ4®½b½_Æàš1ø»v‡&ñxè<¿«:(øû7`pWí+ "Úè(/´ÈŒ‡`ÖÁCðJ %}¥;0ÓÑEQ7¥Ø»¦@WC$·vëh½âŽ£ñ÷CÕ[,”Q¹K vÚ™bTàÂ¿ë¦ÆZæ2p-\aOË‹ÉɧÐ'7B§ó†ØöÐSTAÎ9ºÑ_$£SèW$þÆ9½z6\¢mÛû¾9ó¥ëŠáºÌ®+“J¯ ˜>M]rÇôºëŸÑŒì?ãnáZA„¶Ævyì¿„ª:)r™¥oÔ;Ôú¹ñ«)&Òf¬z­*·ý@"¹&Ø8iwL¸•P È„Ñ**»)¢DÍú§ÇM½©y%"M“YñÊ:Å#ZÄP”H£&'eù²•ŽšcèL¾xTaXùB‚Ý)8nžút^|ïæõÚÎaçL‹$7c\M1µ”#MÿŒ¢`Ç‘'¾æv¦?ň1ÄN™Î›žPä¯3NÁØc#|/ qâÖPßq„o$b~ƒÔàÓ£ ± ±#æ>BÜ9c¨ 3T|©]#&[ÄÌd §ÉÇ9»÷”ƒXü>`HÔuÍå¬P|‹E‘¹[Âa#~ÓmâÕû¸îÓ¿„bzÝîíÇiÀ߈F€“Æ··= ¬³â*n Í¢=;šð¤R×b¦ä—·î^„Üõ­kêÝ'"cq?YG-úÇ®ØoÜç$wœ‰B×›Â~C2ÒžÃö¥Ø¥l¿F/®¨%] £¦îmÛ6Œv¡Ð p.Ïó7;Ö©áqÊ€FP¸%[]òW*ø÷ÌàŸ²ª¶N6‹8àYýQÛ4‡këv×pKBE€*UlfÕ‹Oþ°Ó6Díš«W; è”38æ Å7¢Ü|áGÁ^…CG!Ÿ¸¯…ôø¹]kÀ}îîmp4Ê}Ð0Úõ]8y3ÞbšêIzi?Ðè°g¶-1!؇”§º Áíûw4H")§BðÓíU‘ܳïkPéÈÛ­«7èåëo”ÿ.âÁó:É\TøzÜÖÉi!PÞ¯»zå¬Ã}ÉݶÓECQ³¡5 ¼nºxð˜¿lׇ­íÅSNS‘‚ö¦§ÿe×ÔŸÒ~÷á#þ"uΨÚQôÂÐDÙVŒË)¼ ?ñ>¼0(ž´ÆˆFRu[”̶gØÏÍ<˜d/B¼ß2¾+Úà¯Àžx•ë´ÂlÙ Ř|b%W}½;jÏçZ»¸¼æ»?³¯¶”2®èT:ªSü’ÚÓjI(8ê~CÝg-m{EAh¾‹—=ú ý?~ýT rˆQÓ¶ŸhÔ·Û .ÝBœ ëT©ûAv싪> Sét±ÁæHá £çÑþ´NŽ7a†cNj×…†žöÇ:9·‘AÒðk¾Ô³<|©gw? =õ‡Æ\I”ÇbWf½Øé–ž«*tBt€hcO¬R°ÓȵÕãÈ)V=`Ù/`ûL}ëÏ`§j`šM“©7!c±U¿/ÖÕ˜Ž O¤G*\õ@GozÑõ×Òc¼ü`S/Æbìùô‡ ;I³ •ü‘±úZ½ŽÝþ8×?À²Þn·#Ö½ýµ·X¶u_¹…;^´aaœ‰»7ÀØvCO‹P$0/¶Ý¬zxñÓÈ”*ÏgÉyÜ8ô_eÄk?ƒŠÑø)WäÛ_ÿ÷ÇŽ¿•‹yç¹ ÿ&LcÏP™Ì …§Q÷$¡\†å«^þÏå|vzªÿ‡‰G¢endstream endobj 1533 0 obj << /Type /Page /Contents 1534 0 R /Resources 1532 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1515 0 R >> endobj 1535 0 obj << /D [1533 0 R /XYZ 85.0394 794.5015 null] >> endobj 210 0 obj << /D [1533 0 R /XYZ 85.0394 626.7436 null] >> endobj 1536 0 obj << /D [1533 0 R /XYZ 85.0394 595.698 null] >> endobj 214 0 obj << /D [1533 0 R /XYZ 85.0394 395.3576 null] >> endobj 1537 0 obj << /D [1533 0 R /XYZ 85.0394 366.9621 null] >> endobj 1532 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F42 1338 0 R /F21 1034 0 R /F49 1358 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1540 0 obj << /Length 1612 /Filter /FlateDecode >> stream xÚ¥WY“²H}¯_a|/S5†@f²FÇ< P ¸±©ÐÑ (‹¢"Ð1ÿ}´¨ª®êf¦g¦Ã“¼Û¹7óäÍâþŠÆhr†#1ŠÔ`›=ƒè.“ŸÀ»ÎèCiôUkl=ᯈpGCz`í¾øb1‚eÁÀ ~~&1{¹{ žÅ¹iJÂËp…ž…_Z’ñ2‚qWêTxqõxæç‚$v¢»U7x•ø†|¶lC2_~±Ô'ÉúDø5 @ ¼ÓÓÏ¿ƒàžŒúD`ˆc©ÁíþA`€ãà {")„Q$B3é“ù¤:ü"}3í­ 0ˆhØSö•…d0šaº²d^îEa0:„ÍùeDÄó¯¤wÌ`v¯|SÆßDÆ1 }—` ‰È7Áßߪ_FQ\:·ZØtÖ»¯ ì1÷ûe¾‹7bŒ!XúKüö£sœäÉ%ñÒGݤ˜n€¾ýýÏòV®g vêPØD¹Ú4NVøæ,I; mS×=ëfvéF"Žþ^µ.åC­® ÷JO˜e«^q‰‹jÒ@+óJºÑ‰lÉш߼ßͽ±–W[Ú\æÆ‡À>`u.p…öóf³4oÔ6pÓ|7ßŇt½àEkÙšzÙž]v©ÈûñÔ[]œê€§9åòǽõEwCz'¥e6=^ÛÕe¦Ã…ó‚ÁF|%Çc± ÜE¥9öù ’µµY› ½É uêËœ¹=m™”!4ñ”VÍðÔ¶W†û2ˆÀd©šIiÈm„4É©ùû')S»n•(¿ÙÔ>ÜÍ.§¾è4iE ï‡³„‡€ßÙ«¹rܺµ¦÷ºÒZŒkG×!ñª÷™sŒ9œj¶uÔ·'È o!|Eņ^›ÛÉütÛ¶äÞ9¹"Üé}àƒ¨ö·¢%¤6!ã IÂf:›·ýø©Û«€c0Hß©ÿ-ì?úðÆ=N†Ç쥼ž/{Ô¿ã^'Ð>±+ÊnP\?eäåIë]’"ÿÛùSëæ•A÷Ñy·zq“ õ„üÊWê+_!0 ß%Ö^vLCl[dX?Q©w¢ò7‰ç½z9Û°&__‘ëÐÓ…$n†%¡Ïè.eî§Í~_"Jóck_®ëñF¶Œ%× ‘Ã%»Hºž˜ÊÅÛ¾}!»v Éóu3TÝöz&Rûx¹E{ùÛ& (Vñû¬HU³}amgìñ¶I÷„”lP!¾®²½² I2šöm¢ÃxaköÏF©v7GÁÇ!„r.¤e’kê,úbEdskÜ:JgfïïÖE¶V%¥¥”’§ŒÙgeév;ö)û\_Ø4ÊËVÎà‚Ô›àP±æÒ©ákñ+w ‰$²’:Éq0Ý–Ñ×f’à~r­úb½’'Uh‚k*×ÃÕA ¹™ñ[cX'Ì'ö²Êú¬ð¢YìxÇë ]T¹)XqªìP8i(ú¼èC–Np<ñOÞ}n†ŽaäÿÙ°þiʰ ËsøA°Î Ea$¸·Óÿ¡£†Ãd¨ïIAìq€Ød>âEÑXòØ\²þŒ+ú"7É:Ç'ÑÂ>Ž—*ò‹¨½m;h,…!‚ß+^/‚¹W ˜V?¹¹®ëüjU“¾å™Æ²•Ïå#Rе>µ'­Vª+µQïÙÞ õmnÑ· ·ÄåÜ:'ÿRmãÞ…tZ­ØÏð5 z&ã¡·“mÔ§|N¼E`ÍbB£åù6tÜ M™×c¢Ê;rFM¡Mâ6púŽ^î›>Ï:9©Àx‹üÝ Ed!{Ê(ª£¨1ïŠÔ´·s«jo.Ï®ª„¢`7k§¬–nxvû`ˆ£ŠE‘‚¦VùqZªÑR|è=›Ë|Í9GëÆÝãÉ„MüŠA„0)ö¿imÅñÑZþ¼«aÖÛgóó9ÜŽÂÜóÓwÂ5áù§>Ä歹—&Á[?ûú¨7n‡ºïêŽîlF¨ï¢M|žùZÿÛK掱,ü¼±Ã¾û;¦ðñdþþ yôe –äý%sŸ!üCN/ƒ?&õ/Tƒêendstream endobj 1539 0 obj << /Type /Page /Contents 1540 0 R /Resources 1538 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1515 0 R >> endobj 1541 0 obj << /D [1539 0 R /XYZ 56.6929 794.5015 null] >> endobj 1538 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1544 0 obj << /Length 2654 /Filter /FlateDecode >> stream xÚµYÝsÛ6÷_¡éu!Að£yr'usuz±Û›¶é-A/4©Š”]åæþ÷ÛÅ.HH¥¯w“Þd&„‹Åîâ‡ý€ÕLÂ?5˺HfY‘#•™-ïÏäìæÞœ)æYx¦EÈõÕÍÙó×:Ÿ¢Hãtv³dåB湚ݬ~Ž^~}þÝÍÅûù"62JÄ|aR¿úa®”ŠÎ¯^^¼¢©WW×4x}q>Ï’èæû÷×sfV¼˜®/^>ã?^{ù’~üôîêâš'ίXæù÷7s•Gï¾%‰ž÷úòÍÕåÕ›ù/7ßœ]Ü f†®PR£¿žýü‹œ­À#ßœI¡‹ÜÌᇪ(âÙýYb´0‰ÖžRŸ]Ÿým̺¥S®x@3¡¥QÿÕ¶*Ea’ém%œS*ÒDÆOË¢udñЯ85ž|ZĘ4N>ŽgJ‰Â˜¾"Spâ™1‡”Žþ =ì8 aÒD!£’Âè4wïæ‹TE7ð]œžÈLªûäÚí<ûu¦„LŠBO0v¦Ž.p„ç—÷ñìU Í›¼ÜE Ø™j`Vq&d–Àö±.p3©m,€(+¢vß<ê7Lø8edñ¿CGSuÕõvE³UãÙ«Ž(v®eô[y¿­-M•;–ô0MTÖÕ P¯]6Dß–»ù"‘Q_-÷5ŒÊÏN”صmO¤@Ö€µj€<0¡¤Ã 6=9‡¤ÈDªS= 1ðy°B›"-f‹ñj|葪L–…Hý}ŒJ³X$RfÎö¿o,º8Î9ÀÐø½QöUËsÎðµMy[»s…eãp8; 5íÖîê¹r>â²m>Hßíݤ]áqé˜ V¹kë»#ÊcU×áÜ?ì²÷;ü {´»ŽvXÓ¶÷ÇGJ`íª»†ö¤tvÉZÐïO€äކ›j¹¡áº¬jõ-}Ù –ޏˆ…Ií÷»†Ã+D{c¢^cÐ=¿üë±<²˺²M/Ås‘d€Tü½í¶mÓ9ýò$º/4`írCÒ€âµãùvGò Ü-þ΂‡Ëšˆ¤pÙÁhU¡áv.ëýªjîxêëà‡›Œ#ûÛ¶ ÎØý6Uãöç-ÀÛåbêjõìx·[’F%~LôÑhàýÃUëŒNwMé¾ìý,ù¯®éûþ}g™Í˜£îÚô$œpúKÙøµGè +ìN(Ðh%}PæòœE1ËeëÖ²,T=#pÔÕ£uÓîkFÚ¦|`ÈÜZÛœ¢Y<•ÆMžŠX+ó§$T•a6È’ÿ!ô Kž T‰, P%êRªÉ´Rý©)5ɵPy’þù95”ü’ªI€¨3†_íÁ«“1•½+ÌíìÒVŽî®ˆ&º‰§°r½sÕŒnøî „4ÿi®LDYÜmXö4Ú”¡Ô„ƒç¸¬Ôt©`¹.à–ΕŒöû•ú¸šã”ãx¬ú Í:+‘D’<±dQÃô¨*2<â/T§ª¦‡•šÊº>Ð|m×,`ß,žNXSè4ºD³ÍpLê+ ÝúªÆäp06¯ÖŽŠPŠ?T%q Î5ÆgžŸŸ»‚ÄúÿÓôγݭ:´êÙdÔ¤£«›|ðŽƒs„_àð¾„0æKúº0 _¿•û±ÆºË*½ÜTõjLF 3Η˜B”Ǧ2'Øt÷1M§ZÄ*ù>.†ÄstrKÍ,Û];÷r­ßÌn¬Ò¨‚"£ã!EoKž„ª ÃEÍÑò4¼%x”}!8ÛmoÙòE®ø‡¸ùÚi÷ˆw5«‡„/?¡´\ó·§/Ø é‹'Y—`z¼+ø«ìºý=—¯¥çô&QQ;ªŽòZúÞú5ôác½C¬Âèðb SUïuUw‚p_ÙaßÞužD_»ÛµÎþIÀÜxy°ðήÂ%lNé±ø!ŽŸ|Ý ëŒt(ä×^¡ð±+ä>Ò­pî|Ézm´æÅpw&‹ @2ƒÕ«j ×#ŒÌ)°Ùgb£Ëq޶Á½!š$PÐ~F~‡&@MÔîˆ Ï }u‰í8Ž ‘&´G%’¼‹p»Éc¬ƒ¸Ïïš‚¦·˜UÑPæÜl|£³³Îu ÖBßžœøp§øêp{ô,€I€¥êÉ)ÌèŸY%ü?;¤Dæõ1GÇj¦¡“4[$æB«‚`’ˆŽWÊÓ7˜CSÞWK~ƒÁ–â´O8ß÷-”°žç²ÖcãC"m\@SOvÞQ¢Âk õ# Œ„$¢)*fÞ¶P¸ßbC³@]nÊæŽi%‘V^oüñ‰r,ÌŽE®“zT‡}Îñ³'oËåG&ÝA.Â'« ìŸLÅÍwE%W¸ûŽ)ê×ÂøŠšSà Œ)š—n0 v­ kIØ^§¡dîS(>Ηm­Q?Ôæ\?au>†“ fgÚôù‘%ÜS¿D§“T­©¨Š½@Ú ­O ¸í`Å)üþa5ˆ¬x¦liðXº/1†(ðæ©*F0Øo}¯«¹MB;8õÈÞðHKÀùbÕt ð„sL ¡à|?žv»ÅŽ“/óu¯PÊ(€ñ½í7­ëESÚ=TÔXæ`Þù¾'¯6@¥.T\¤¬x„JÞíµ©„ìF\‹çFépR<5KJ ®KBy…&.|…ôÖ™oD‘e)XÒ‰›øË„*¹€¾.›\hbíŠXØØ·Òd=–„^WVh»¿­«%9\ãË^ì\$DŠ\PánwÕ=-÷öæê »Äl /Sb#ßy¹dxI%æàB³`ºJ…‹"LÙ0BÃUè–o0š,£dß¾1Úm쎋nÜüðÇÈ%Ð.À X<áò"‡\C§…ÚAùö㼈#½0h­†GžŠ;ûÛwøu¹ûÿbÌÉ«h±XñsËêëƒû;O*,´ÛÚe…N±«AÌïQ¦e"lEp @Åzê~BRÉŒGø—Ò:[ȹPkhvu¬‚»œB µô–+|‘AÂ?Ê’ 0&Óc—÷‡-¯º/»Þî&‹UŠE‹m €=wÝ.ËúÅTFYW5Kü‚#Ûó@¡püÅäzö;ûüIA¼xqb)ü¯žeÖìØm—.«kîn¡Ý~{ý–(œN?¥£Ÿh*Á(ýÚž‹é§{?CºH¢{€´á`ÅiF$òŒQ‘ßv‘.•›.]æuªxÑŸ±ºéJ” ÈÅê E×(·<34Ì0¦GÇ傹üðH‘hªœÐ|$ú·¿">ÙAMî¨æ||î>!­kWɧÑy3űîpEÆé ð-_Þ0ø×c'ç»õÉu¯šª¯JÓqmH‹¨@XÚ®{ò‰O@”VSX“3¯ÿgÿ/(œ3¡ó<žþË‚–)½È­Ðq±Æ¾ÎÄ1ׯhÔ^ Äâ»äÔ,£1»ÅÙ”]ÿT•jendstream endobj 1543 0 obj << /Type /Page /Contents 1544 0 R /Resources 1542 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1515 0 R >> endobj 1545 0 obj << /D [1543 0 R /XYZ 85.0394 794.5015 null] >> endobj 218 0 obj << /D [1543 0 R /XYZ 85.0394 386.1448 null] >> endobj 1549 0 obj << /D [1543 0 R /XYZ 85.0394 353.5014 null] >> endobj 222 0 obj << /D [1543 0 R /XYZ 85.0394 310.2645 null] >> endobj 1550 0 obj << /D [1543 0 R /XYZ 85.0394 279.5106 null] >> endobj 1542 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F61 1466 0 R /F66 1548 0 R /F21 1034 0 R /F42 1338 0 R >> /XObject << /Im2 1455 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1553 0 obj << /Length 3063 /Filter /FlateDecode >> stream xÚí]sÛFîÝ¿B/7•¦ÍÝåçõÚÅq\7‰“ØJ›~=PâÊbÍÙ¤¬8¿þ€–"eƹ¹öán2A,‹ÅbñE‰‘ ÿÄÈœ –ñ(Œ=Çw…?ZGîèÆÎŽÓL-Ñ´Kõl~tüBE£Ø‰Œæ«¯Èq£HŒæéocω ppÇÏ/®®NO¾™L¥/¿\Ì^ŸŸÐ˯o.N¯x`vñœ÷ó‰ˆÆo^Ï&¡7ž[Ú«ó³‹ó‹³‰ B|òÃìíüô’F<^göü§‰8œ2/Xš€§ÄíýåéÕäùG§óv›]UWáo~ûÃ¥ ‘\GÅ‘?ÚÁ‹ëˆ8–£âÈó•ã{JYL~tuô®eØ5SU+\Gª@èVŠ‘Nìû²§\?v%U«\9™ ×…=>”I‘-6¼Ý¤I£ .t³®RÜ60—ƒsG0îx ×ù$–ãŠæde­ï‚›53ºÑ5A÷YB@Ú]ý'­äuWòB'’n8š*ضpi½L¦l ¬YX˜†"ÑæÉŠ¾'’¦É Pð_ŸNvéì®NÒ”ý1)6¹vJÝ”ôòô‚¥0gz„ô˜íNg³_KnÞ¿p_nogrž} ƒŸ"ºwýr®Nfg«g«W‘~%¹ò?}RÌô\ÇW³wÏ>žß¾^½jÎw·?¿M¯›u½UAòéìÝìCôÝß¼‹ð³»HÃ*}x•|uVg«Å«æ]Ѽ‰ÒÏ›ùì×Wä×”>~‘߯ç?ܪ_\šý¡9qÏ·É.?¾½I^þôñƒ–y4_§¯ƒ÷zýpr{óÝgVërÈæ¦ƒ¦ðó:ËÑÈ\ÅÖ@kÂß¡Kз[]7„ØeyŽ/+Ô‹%Lò¢²4YQè4ùƒq èi„Ü/ð©*uŸ›—O^ðe<Ì{]—:e Ë&Ëy¢¯ºÇ 7D©B)'ˆ F¢u‚W+tH h²eŸ©³Kò3{€÷DIÉó®u©ïHs]Ê p”——àU $/+óLkp© (燓 —4Ʀ¼¡ž5´Î#Ùè±¶Zر45:0Oê†CBþUžäÖ%{¯D²°ÃbÏÄ~©c~+>â×IV:­ÙFŽôýÈz¾‚=Cy¨¶³^ A B˜m•×"oEãà4LJøjEÈ ~Ö°£uµÍS77‘I¹Ÿ Þ¢/ž]Î^ÓØ¡Ö»R¡†®aVfMfÔÄû»Ôž ¹KxÌAd¶ŽTF>hë{óoqF‡„5GÏur¯&¼yKq¹y_d QÔÚ0„ã}ŽÙ¡–­eò»ëªäšo¼H§Cž•Ý U‡JD\_‰Îߦä¦ÄÿÃÔÿL˜ú/vAæD¦„ï¢ÿpY!•ça»W`œ]Ã]Ãëâá­0NÎë\g€û¡Ñ‹­{õ¢®|î„Æo ³®vú<*\Ëv¹Þ —‹TåWÌ œÙΊÅÏ¿=Ç•"êFåzHèn¨\j‚/„çb›åé1 \T÷vtÍ äú~‚Q°iù`Hýƒ³ Ôæ.»7 6³6½é/ 8Ò¶Y›©–DóÓV8 ¼¯žQ<橬¼r\7,…¢pÒ«6峪$üï®ïÖš‰:Ç3A²p6¸¢²áßRÝ$Y^Ã,ÁI”à »#Å;²Ùê“I*V|+Žêˆ3p׬!Ö‘7ì%±õß±Û‰^1%&Þâ e/E¤c–â}XŠÛÈ(Çp«é¹N6¬pÏp+“D˜!ºRL—´™¼lªºÎù ãO8ëØé«¡ >/Ý%)¢¥ú‚$BùNà}IŒ6Mëª×Ý)a 0c%;¼Á!è_¨ƒàõTïÍ­ãá’)ÇÅfUjo— ¢^8A îMDNsNEÛ ¢šPûpÒãÂA@BñA™- f«ÇKá}2løí;n¸ƒPƒ d<·ÌÐQ”`étm6qÛ‹B¼éÇÁ³HRm'3`åŒüq½5º@†5ñ€L’ÓJn«…=Êhèi辺!= z .m‹62Áv°Ž ­(ºZré#„u“€5 <—ÉÝ]fŠ®¶Øçòbüì†S½J¶ycbo››ÈÇù4Ò€+\Þg[[ázFŸL‚e4Ï \z‚ ÜÂy|;Ô ª^g%ÛC8älFÑ‘ ‚œ¼Y°;ÌÇ Ôæîý<rw!cyù~çU’¢)M!ˆé»û$ cžr¼@¶¹µ;7$„IE”95|-’Y±-g TxJÁ¬î¸Þƒ!vüXÈþi·ˎØAØO1Lc˜…6 qÓFÞyŽ¥®‡2ÖÈñ¤’_Ê,A‘§˜Êö¡ÍÙغ)r~·~DwuðåÁ±™a|¡@é¹(Ó}å Iоü„— ½ÔT&"›ˆqI ÝNšKÀ¡/êaÿô®f.üua?Ù —`APç:5ý ±ç³§c¿ Ђ1íçe›LÓÁº¹÷QÆ4­0˜†úV»Šã!`„TíEé€ *ãÖ‘³¹õ>#íG_Ï cqPBõ9B å»òçíOÙärY8r쬻±IqæëªæNÖÜžÃ;n:hMÛ²[0%Ô©-Ê 4QÜ÷”Â|Iº/ÛÒæné¹²Çâ/-æ_^¿üL+B±Rêl±²»ªí×É_®Ed6ˆX¯‹Cóù+2æE_:“MädÅ2€LÇW61 úcV³ÕÀ›Mn¾¼–u|Ìe3Œ¬Ö†>˜6P8.Q€8è²lËF ëoè¬RPØ.VÈ{‹m&c ¢]ÆäS‡&A!»ÑËÌ|ôH™ ¯`µsMkƺÛ~¸yh‘üõÊ~0y| ‚õ£¶@ïeÉ4múj¨¬Žò<¿×â£qŠüOÌÞ|xµžÔzÙöÎÕ› çsÉ1äøK‹<ÔmÛpùûܸŠ"ùtjÍ2¡žÛŸµ@Tƒ…§o!: Jbœ<Ü“ýMÈãMýP7/nendstream endobj 1552 0 obj << /Type /Page /Contents 1553 0 R /Resources 1551 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1562 0 R /Annots [ 1560 0 R 1561 0 R ] >> endobj 1560 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [411.5778 223.879 489.9929 235.9386] /Subtype /Link /A << /S /GoTo /D (man.dnssec-keygen) >> >> endobj 1561 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [55.6967 212.5914 134.1116 223.9834] /Subtype /Link /A << /S /GoTo /D (man.dnssec-settime) >> >> endobj 1554 0 obj << /D [1552 0 R /XYZ 56.6929 794.5015 null] >> endobj 226 0 obj << /D [1552 0 R /XYZ 56.6929 769.5949 null] >> endobj 1555 0 obj << /D [1552 0 R /XYZ 56.6929 749.2922 null] >> endobj 230 0 obj << /D [1552 0 R /XYZ 56.6929 357.5215 null] >> endobj 1556 0 obj << /D [1552 0 R /XYZ 56.6929 327.0925 null] >> endobj 1551 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F11 1559 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1567 0 obj << /Length 2566 /Filter /FlateDecode >> stream xÚ¥]“Û¶ñý~…¥NÄ’H‚}Sl%uß¹wr:nœJ„NœP¤"Rw¾üúîHJ¢Ó›éèËÅb±»XìL|øy¾Jõ$IµùA4ÙìoüÉ#ÌýxÍÜ͇T߯nþþƒ2“ÔKã0ž¬¶^Æó &«ü×é›.>®–÷³yùSíÍæQìOo™A0]ܾY¾å©·· ü°\Ì=]}º_>ÌTœD°*•u@ô°|ó¬ø|»øðî üçîvù ‹[á¹ø´šfz÷9:Ú‡w?Þ¾»ýqöÛê§›åªSshŠÀW¨ã7¿þæOr°ÈO7¾§RMžáÃ÷‚4 'û)/ÒJ9Lyópó¯Žá`––Ž™6RÆ‹L˜ŒØ6 Çl¥^¬BE¶}·Í•‰§/õ‰ç¢Ù1Ôî,ÑôϺ²‚ªy\ËwSñÝãbO0ˆ=:ò¢D§°ɳS[ÏóªiìFh‡q*Š=­ƒPhëß5äÍŠüq*@[$©óÓù€¡ ƒSëY0µ nê =ûñ48bGh¦YYÖÏLØ…ÄsøhЇ ~­_˜$ËsÔ 1üÐóƒ887YV!P@;Åh˹ħk+ÄÊÓ©ßYá8Æ/ôàZi!aNóC ëeŒaì…QšuÓñÞV‚”#L ¶D@b>˜ª7E=L£A¡ K"´Ë^@1k‹·¡¸¡§ª¸ |ó B’èÜp»±ß‰³´ÍŠÒëLÑ-Ü¢CªÈ $«aº×38ߟ~9TüˆÜÁ„ñu¨°ÏÚ`ð5t¥Éʇ¬ü±ië”ÎFv>7¤4P1ß¶¨r,n(€Òª¬½X%¡7±öÒŽ’0d„)ׂ¡ékAÀ±³"–   ,b (¼Ùq©º€š 91XètJåqA ‘>CÇrÛeí©ËÌŒÉd“³RÙ|¹7¢›]}*óN—á…ûúÉæ{ô0h8£Ìuà:²ò±>‚öP AB•ÄϽh̨d%¤(r++Û>×Çßù¢Ö##ŒC¨œ@@]o$:¡>èØHµ-³ÇQvú[rºúã¬Üú‹8ÛñÇ÷LÄÄô®*ÑG´T”¤J}$J70~ CíÄA˜‰7ÔLÀ4¹gÇ’‘)¸_€™¾_,eQ¬0Ϩ¢ZH“‡Vö"Ÿ?cÆ«jp²ã˜úXñc®£ü0Ë­…¬)JÈÐå‹Ä¢ÇÊÕ§£E¥dí®]üP:qññ”±aìcSG¾dóMÆ«åšÙ£˜Ï ?«Ó~>Éd²Sw·€EeŸ+9i£j°‘Áöüýòó˜)ÏmFŽw6–˜§\ôR#1O…Ñ0æ! ÔÔÕ£ûàP6`àÚ0&„–áLB}àÀXRþ£˜{?èÈ9ôÂÐ1`ßþµ¬£w­jYÊTR]úWnåaíå»"Æ—ûÓÁÜä‘_Ú²t>È©“ÝÁK°V"`1i‰ŸfÝØnД6¯ŽœþW?àè½-öµ#ÑËÿj|¦ys¿\¬–cfó¿j¡¹_~¸ûå4¡ÐÜÞ¡AÇ*Ë>VéÄóy“ 3’ S|– †²ýÕål@Þçd¤)>–ؤ´9´HýS‚' k8êH|Éi°%åS$áç-f‡/²½Qká”S~ç=é…ÏÙKƒ‰ÑîI§3žt±rÄ–Ýë7"òF5šøÅuc |éT½¶- "×AJ}B~Ê]ÉèÉi|†3êª7ˆÝÉu½Þðùн!¼·P]æ¯hð&Öéº;‚\÷¸Úy¡$%ÔôöSI OG>­ÒV¶.Tζg—Kùà®qäÚÃ÷tf‘—&I –ñ­¸nýÛˆrÐ=)­'* ¥¹©òv;‹tϺBÔÔŽBÊõÑCð =$úÜ‹ÀvÌÜJy&H\÷JþÅýAÎÞ Âì!æiˆyŸé4NŒïˆ¥:™NPŒ!Ó]f€ïƒBLÿ8`ÜÛ¢7¢œÒ±§ãÀˆ¸¯SJò¿”šdhÏO“ð"#d'jxŒq $îFyÓ€q-3Ý;“q±æl¡hnÜÃ¥•ë {23hsa u Æ ÊÀ3–}ÕƒX®zŒyUsvU±‘%Ë4µ‹&.Muù¦ÌšvЦIÉÔt}¼`IÉ3ÚÁQF<Ý:7n]“>ñýÃ{èzÒÖÉØv­cŸ(;)RBT­Ë湤Êk3·›ßìÜÞ¼òP7E •—ÑêíÅ|ž,ähØ_ÕWh¡JÝýìsF¯¤±æÊ½²)l­¾ûÓž?V«Ÿyº•™ø£Âœ³­]Ù®xfwêA¿Ç¢te ¾ßzŒ¡ÃÁD0:E‰ Ñx"£O—ä(RІ¥ámµ{ÜÃ^'ø(©²%7”ª–;¥Sgí £a°t}à¢ùŸ«¸’gçßñ•» ó½·£ äȦmÃæÖô^÷¿ž ÓáÿE#ù]nü¿ÿ–êÿ΃šHŽÿã¤üØ3aš8¡ðDB¬š@ˆpúý;÷'[ YÚSóúR©î¯­k­þ ñ¬]endstream endobj 1566 0 obj << /Type /Page /Contents 1567 0 R /Resources 1565 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1562 0 R >> endobj 1568 0 obj << /D [1566 0 R /XYZ 85.0394 794.5015 null] >> endobj 234 0 obj << /D [1566 0 R /XYZ 85.0394 640.0062 null] >> endobj 1569 0 obj << /D [1566 0 R /XYZ 85.0394 612.6963 null] >> endobj 238 0 obj << /D [1566 0 R /XYZ 85.0394 265.9153 null] >> endobj 1570 0 obj << /D [1566 0 R /XYZ 85.0394 238.7609 null] >> endobj 242 0 obj << /D [1566 0 R /XYZ 85.0394 191.0809 null] >> endobj 1571 0 obj << /D [1566 0 R /XYZ 85.0394 163.771 null] >> endobj 1565 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1574 0 obj << /Length 2405 /Filter /FlateDecode >> stream xÚ­YÝsã6Ï_á·“gb?D}(²ëÖ–¼–œ¬û×@€²d+Ùôz“É‚@~AXŽüÉ‘ ý0QÉ(JßiFÙæBŒáÛ‡ É2'4éJ½›_üó;? U8š/;ºb_ıÍ¿yŸøcÐ ¼÷7÷÷³«ËñDxùõfúñúŠ^þýãÍìž?LoÞ3ñi>–±÷ãÇé8 ¼¹“½¿þps}óa¬ÃÈxWßOoç³;úð<Ó÷?¥” éjƺ`j"¾›‘¶Ow³ûñó.fóv›]SH¡q_.~ûCŒ`‘.„¯“ØŒžáEø2IÔhsí›@kÇY_Ü_üÔ*ì|µCM+…¯t¨l«ÔmMâ‡ZikÛüë¶Ø¡‘rغ¡7_5lT'^^Ö{ú„Œ@xÍ*mèSº^‘­‹¼lxÀsáØ9Ë=¬™j*z>å»by }NÛ:Ok&«’åëâ±LžŸÕ¯ò’¨Cµ'‚>oª'7Ë*'ÕÕz¾M¤ôc”Ý-8ñ_³_­kýö;X(’‘ý>·ãccǺ–™¥%1Xê8ý‚OEJŸnßJf>}™奟súœ¥íÆà›µ <ëmž‘q@¤qKɪ g }ùœŽ;ËŽuúI Nv?eºÉ,Ö…‚Ö~¬#ÉRì7œ \QZÃL@U¬œù(«}C1–"znª‰÷˜—ù.m¬MàõEiCF°mÀºe“ïN¤öÛè :«6ÛuÞäõqË­W—èÃÞ´ˆÚl'Rˆã}SmÒ¦ÈN&ÜUë5xmWØÔ©ԅƪûÅ¢Nkã¥ô(óg"¬6$h÷i¶B £h,xiÖO0Å*hKHý.ŒHY¼Î"ÀTç.UAà«DÆì¬EY×y6ÉÁÎË $ƹ¶Ú h”ʤ ú aM±É4†);qX¸„<«MèKZ6úlŠ¡/B7*GLXr™gõ"“V1UX¬ˆBÖó'%™bKfEÚf,xZC"e5]Mqâ«Ò$iÚ¤EÙÀÿÀ”Aȇ’àåÀÞ?–þv©È˜~ÁâRJÈ¢bA>Ø1I1¦\.‚P«8Û1r1¹ØŒ­½ëåù€Ôdl؆ǰԞ±Óõcµ+šÕ³¦òViMDY5Dl ÒOEµ¯íµ†¤GéWyûÚÆ6P”Õ•M̱‹=…ç±¶©lè+©u‡†âCCyË=Ù…õº¹Ü"¿ì‹ì³[TZ÷Ó<å©mU×=h )¼ï«çœM†+ ‹\|òy‘PPSDÀ˜ ܳ]§YQ>Ë ›-ê¦å¶#«Så5„3üe+Rž³e@ØZfàC;ióÊ&ÎF¡ÌøL‚SÙ  × }ÍŠFžfmä- ]Rd—ƒl›¬‘ l§ðl·[>®mãðWçØ¹"ŽØ pàYÏ;"OË`=¥ëbQ4Á;ÓnCÓ/[¥ËQB‚sÚ¢ç a«Œ2-9r¤9Ûò~B§-­r]ðB@@ê‡ÿIÓUx#Æ›6Ä&Œ"µ­à#ÒÖÃZ†T¡"§ ÆDåfÖÊÛ¸š}¨µó!R«Ô¢G DwÏŸø)-™ „iqŽ{-Î"÷¥‰RšÅaŸ˜mÐAƒAaŒ8 õßiÎ}œ§•|YµJŸG¼tÔœø€TZí!_¼£R¼ ¤ú¥¤ID M"R-,Þ Ú0ò£(qU6\ü)$jcã ©œ`Ãú{g¼Sˆ3p'ñ j¤ÂÁŽ¥Çøæ0À4c 0ŠOEyÉÖ¿ï:‰R}¸ÿ=(è±Ð‰Ž7#A~ p/ÚïNŠ‚¢dîÛáK£tÑÐKJ¶Ä–mí ܆GìËãwx«iyè·ö¸…(0.IÃ"Ç´ÃX#£²UÞÊQ!"‡P »bg¯kèØÝæ_17*^Ù9®\ëà ¸V¾0Ê]›1¿¨È›Ú ¥ôI1këi—pvØ„ct Ë¢ƒ$%'I…w˜ºÊ ÂY;€Ãc,=›.}j åDí®“ýšò 'nïºI#>ÊnZjQe«úÿË™}ÞdëÇ \èzý£ávBú"ÖÑiÓƒ`ÒT“WBÊØ#‡¶oЉ¦¶øÎ›öõ’nÿ@ú2 œžC>Ôær@›I½&nAiq !WC"WΨ¡ýxmhåE¼¤Ú—Z4ê›ÆÊ7Qw{4܇±º^i‘H!}ȨזÁ1u°ÀÛ'Ík‹U`cËÀ-©aÉUµ·Å(_ý‘wR^pdÁ§òÑ1wz{™ÈDšÓVǺzr¤ÈÀ´~ª›<åxÁÎ\µ{éžÖ¹tc'l0ÍOXùy²WœìoííÔµ%w¤ï˜Á^IçÖÏQHX$,ìù¨ÂwvP|ß´Bûí¶ÚÙ®$¼µ¹_(1S"â^ §ú,rwiׯBNÇ Ä°×ʺ;ï@º¦:O!7š‚È]°‚ð´›,{ Ã'Ér’€û:±©Ï›«l{$Ú¤„ƒ2 ŸŠ*Pö¤o¬u±Ì±óÉ“±«íÚXÓëy·¨º¢¯Ã'—Qjî 9Pµy³g9d¬+'ÃÍ”.\Ãj’Õ1÷ºÆSêИ2>«2Ëý—~ŒÒÆÇ_~:-jÿöUÇøHOq¬^ÿ Š×„&{wí~®ÃºØ×“Û¢¥<žíÉýÖu¾©ÿí^4endstream endobj 1573 0 obj << /Type /Page /Contents 1574 0 R /Resources 1572 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1562 0 R >> endobj 1575 0 obj << /D [1573 0 R /XYZ 56.6929 794.5015 null] >> endobj 246 0 obj << /D [1573 0 R /XYZ 56.6929 692.9743 null] >> endobj 1576 0 obj << /D [1573 0 R /XYZ 56.6929 662.6747 null] >> endobj 250 0 obj << /D [1573 0 R /XYZ 56.6929 551.3761 null] >> endobj 1577 0 obj << /D [1573 0 R /XYZ 56.6929 524.0414 null] >> endobj 254 0 obj << /D [1573 0 R /XYZ 56.6929 457.5986 null] >> endobj 1578 0 obj << /D [1573 0 R /XYZ 56.6929 427.299 null] >> endobj 258 0 obj << /D [1573 0 R /XYZ 56.6929 363.821 null] >> endobj 1579 0 obj << /D [1573 0 R /XYZ 56.6929 333.5214 null] >> endobj 262 0 obj << /D [1573 0 R /XYZ 56.6929 281.9986 null] >> endobj 1580 0 obj << /D [1573 0 R /XYZ 56.6929 251.699 null] >> endobj 266 0 obj << /D [1573 0 R /XYZ 56.6929 136.3226 null] >> endobj 1581 0 obj << /D [1573 0 R /XYZ 56.6929 106.023 null] >> endobj 1572 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R /F49 1358 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1584 0 obj << /Length 3127 /Filter /FlateDecode >> stream xÚ¥ZÝsã¶÷_¡‡ÎDn, ø¶OÎÙi.žø®¶.L’Z¢-ÎI¤jRç¸}÷ )Ñ“´{ ´X,‹ÝßîÂgfþ™™K”¶y<ËòX%Ú$³ÕîLÏž`îïgFxži1äúfyö—o­›å*O£t¶|ÈrJ;gfËõÏówß]~\^ß/¢DÏcu¾HR=¿¼úñÜ3¿¼}w}ÅSW·÷<øöúò<‹çËOw×@1Y”Á2£eåÕO·—?¼Ǭ˻O÷K‚¤ï>È.?\Þ^þýú‡ëÛåù¯ËïÏ®—á$ÃÓmñÿ:ûùW=[á¿?ÓÊæ.™½À­LžG³ÝYœX•ÄÖzÊöìþìAà`––NY/±N%.Ê&Ì™™1*O’hd¿$W©,Ù/V¹2 ¡µžßÞ_¿³|È¢^óàÃÇå‡OtR’×_‡žÁ¼ŠËHP]ìʵ°E6«8Ö)°#WSo_Ï6Nçía¿ož»–­žÏ›—EWÕOL©ËˆRĵ)ªZV¼lJ^Ã?‹í–ݦ^±£û"¡kø‹ê ÏÀ6ı‘¿_ž˜‰h’Ñ28É&d cµÊ¬ ¶à@ÜU¿ÁY6Ò#cØÈ¼m ˆ•icÏMÎ[cÝà)q›ºéD>ˆ© rýÄ^S|¹':iÖ‰yšG&5ÿ®êuõ¥ZŠ-ÓÙjrôL9—Ù±Œmy«L$;CP•uWOÕ:Ø4ÏÁÇKòF â-â÷¡çªŸÐ ÈW= “—9r7`ð§©Fxé4ðžY}XÀÔôöxP=> (Ó_¡‰DG$0eˆ Æ£M®^áB«•`)òó¡íPëÕ Æ€ZÔÅS¹CM\> @T’²üoÞߢ[€ê\e ¶² اîÈÂÍú°"ï€éÞ)àÇ#n…œwß¾c à¤Á›rÙ|íõD:rsÒÙ ÑgvAKÈ©ÍçŸZv3\µ©dÛGÀ°ƒ\÷È’%SÍK; ˜"›üHHáR˜‹. vú\–{å }±úÌDòøòݵ2/+VÏUW­ÈÁáäFp æø\¾¶L}©ºMsèøGQ¿ò<ú “ئ0`¯„¹f_>] 73iŠÙ:{Ô®ø\òåýða›ú­£§È«šš‰HÙ–íÀ ûÜf¶)dÐ,^¨Œø!×ŶZKzAaweÛl¿LN{Ü ±-ÏóhŽzŽ^çf~ ô‚?_x“sÄ'&1—쵈,ßÎÚ’ ä“HAŸäñÀÔ ¢c¸]P@pQ"²‹BF¸@‚Øn  #ú[‹'BþÐSSî éÐjï®ë9Ï©ASø`=ÊVIY£çïkð¤Ýàž‹r;òŠ+òˆBfÄo›ƒ/QÀ>G…X¬2"ÍãT¬cƒ%O>?Íxp7¨¡ÿb¸€k¨áINåâ‰îËU¯}ª"Å' ¡ ":)å×ï©q" Õ˜ @8«"çÜD€D —ˆt@¸ƒ/bÝûòù¿ ›fó¶ìxpØó—R~Çò‘$µŒF` МIàhÆ$΃qÆQÖ@*ÅótþTÖˆ>"µ{¥~щ‹8C—@“ Àa§œ¿­žjÆví<"ÂeÝÜß´²^{ ÔuNÇŽ]<¿)£Yç­]y$¤\27qïþC›ù¼Dÿ ¢~‰¢¸X¡EqÄ4PNñè’Êa ¤¯Ú©Lô²©V¾ìµ .T8hIs@qÖœÂ3à b2ì ]¯¯¬RÑd*lêT”dì.—˜F"“x¤dŒßG0iÒ LÀ÷ÙÖL%¬„Œ§HØÈ€ÍÃc°ƒ[f'<ߌ¾0@·[’‰ +iÁ)VŠ)«-Wp_œÖ`¶¤'bšÛÈ”·ÿB‡bF® Œhó¯ZC޾¹þ‰Çwwj|¿Ü§Áê¶kÂŰÈGipèúœ+xü(­D’šŠ…%ks’ÉrÎíçV›«$ÈŒ÷ AqP5k¬: ÄŒ|á Õ5³KÖs«ù».^[b3T$Sƒˆ bŸäØoÅ:ß ]„ ºf&ßÙ—„Ù8—ÃáˆJrtüÕª„Ô¾ï¨ÂT$¬ÒAæG&BJÑÊ—WÛË¢ÛâA¡ ãG?rTR ìÚoZídVìÆ+'´àŒ7Y‚Â1ö"'æ_K‚žy¸!u¡yY5»ý¶„ƒ¢Ù"¯ pøB& )$RnÆÁƒp±¾4ŸE€ãK¦Ý¼$BÜìx9 ×óÛm)ë0©±¾¶<º»VàøÌÉ¥ñ 0‘ëM‚{:T$eÑV%…=ØKñÊTÆðãm¦Ã¹‚)ƒ€6ÞuÎñl´ç’HÀ‰v,‘‘Kç¹VwÅs'p>€ÆA—!²e&ª4—ªÄÅþ¹a]·m¹Â* ’åDn_þ±ÃÔë©Þ=WqjÒ±hT”Îy*<‹Ušç±ðcš‚Zõ=ujÈD©7]j$;"©`Âþð°è2+Ed |M ›9õÀƒ}Ñ":F)x’¸0‘ÿ1&ˆÑ!ß Ä–I‡KjbðA/5cwãÜÏ ºs3Ú‹Þ¡'L茂¶6~Ä$jq?aJoî|èÓ¿ÇcnúWÛÃZd„WŸC8~³ð«Ž r²äx~• ü>…)œèè™Ln+õî¯|žø¨¦´PšÈûŸéô‘·iqÃ_.ɈòÈ_Â""|äoݼá2¾Ž^y\þV ¾©Z®÷GÆ ôBâîßRåHèiÝ<j"kÁíѲ÷Wü•‡`⋱‚‘? ÊC$Ê}å¥DEL½<ƒÓ3£õOò@ˆšvüM“Ä&ôBÏ)/ 6”t~qt»½Ÿ„šn„ÿy¦Lû²øÆ«Õ×Z'_ホž@wüËRìâxTÔ±ßÁZaolšDʹ¦6“ý±M%¡Ä0‚j=wHT®;ïk‘óÕ’øO¦8zõ•Ð@UG˜£Kcj±¤F³:i ‘ÈùÅIíí̱ç8ç[wç³È=ÙÆ›Ëã„ÃGû-€ݤ7+&‚A‡þN–fX¶å®Uü·¾hóÓ° î˜€yäb²‹T Ñü{°4WÐUeÂ-‡H3y›ƒAÿΉUa!³\f¾ƒÊø¹„Mz!î~¶¢•?½Mý_üÏÕ:¼3ÿßÿÏ¡ÿ/ 1Ô¢ÎEÓïÞV§ÊEyæ•BEÙù€‘üiÃ$Ç×m»øxò þ¯Äé©þ™6æWendstream endobj 1583 0 obj << /Type /Page /Contents 1584 0 R /Resources 1582 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1562 0 R /Annots [ 1589 0 R ] >> endobj 1589 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [408.1244 514.5985 469.3244 526.6581] /Subtype /Link /A << /S /GoTo /D (managed-keys) >> >> endobj 1585 0 obj << /D [1583 0 R /XYZ 85.0394 794.5015 null] >> endobj 270 0 obj << /D [1583 0 R /XYZ 85.0394 769.5949 null] >> endobj 1586 0 obj << /D [1583 0 R /XYZ 85.0394 752.2562 null] >> endobj 274 0 obj << /D [1583 0 R /XYZ 85.0394 666.4682 null] >> endobj 1587 0 obj << /D [1583 0 R /XYZ 85.0394 630.3274 null] >> endobj 278 0 obj << /D [1583 0 R /XYZ 85.0394 573.2187 null] >> endobj 1588 0 obj << /D [1583 0 R /XYZ 85.0394 545.437 null] >> endobj 282 0 obj << /D [1583 0 R /XYZ 85.0394 499.6475 null] >> endobj 1590 0 obj << /D [1583 0 R /XYZ 85.0394 474.8306 null] >> endobj 1582 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1594 0 obj << /Length 2864 /Filter /FlateDecode >> stream xÚ¥Y[oãÆ~÷¯Ð‘ ‹áeHqôÁ±ÆÙt×]9 Šl(rd±¦H…k_ßs’’ém€Â€yævæ\¿93òf.üy³0r"íëÙJ+'t½p–î/ÜÙ#Œýý“9K;i9žõíÃÅ×ßñL;:ò£ÙÃvÄ+vÜ8öfÙ/såxž³îüþÝõúOž·Xú¡;ÿä†îõÇE°šÿûþaáÅóïî OF×?ÝߠчÅ2ö]~ýýÕýÃíGVÂñêæ_ ÏóæWï¯ooxèæýš‰ïn¯+5øéãízñë÷½Fc­=7@u~»øåWw–ò?\¸N ãpv„†ëxZû³ý… 'TA`{Š‹õÅ?{†£QZ:iEÏuü ò'ÌèûSf µ~@f<îòtвûä wžVE‘glák0Ô.oxBº3éS^>rë˜ϯÊâ…ûª4íj&ó-¶;Ã¥92ñd^KjtŒë¼mMɶ’/¯vçM²—yYΫҶªe[V|YBXè0ôI»]Ud »-!i¨€gͤHT^ò·k ÛJæ´»¤eê÷ª›Ø]b'rÃíò¡Èˆ£ çϦnòªl¸UmùûíÝû¦4²ÀN(¶Ø4H%üÙvmgm„í‘êÜñ€_ޤ48—ˆU–ñ²¦±»ØÝÙ¶Õ¦0{«m¯À[œ°?•"ÜÒ± Œ„+òv£}Ñì>·qòD¶?É“cÞîl^˜\R=æe"ùÕ•S뙸»ùŠ- ÐäÍ<å p ° $P¾z*îÁ}±ô\w Üë—C[=å¨7ÝáPÕ­ðC°õ좕&¶¯Ø'^÷ݦÈSlów$$ ðurؽðкMÊŒÁ*ã9ÀEö‡áÌ|r]¿äðóÑØ{(’Pd¿ÌËÌ ü+[žpuÇSd ‡azÒªlÙÍÅ”gP@ãsí`}óVl½¯²®0Í`¸ï×ÿh£F¯ð04'«ŒlK ;}#Wã|Ÿ0>„b~0*«cÉ]„êð=Võ“PO0­Ý±*†PØ¿"\DpIßÕí=àªÈ §0"Š÷§ŒíÙwcŒÝÖ4 T£ ýùÙäIÉsÌËîóå>¬«"©s–ÏqĈŸ!æaViÊj¾6õ³üñ]7øQ[Y£2Iaqª\ïrSd‚н”ÀE¤„9½”@“”°— ç¼îJáúj*v"È&œ _¹9ŽçIšPÕö`€I›JbŒÄÓ$ÞÂ8Ö½„zl!‚sJùÑüNø åÈ•ØÄ6LP V+Gqœ½¯˜ã©=¡ Äùr¾öÆç®ö9M w]m[¤KîM¸³N›7ËM›jŠ8™Ã‘´”›Ð_ä›:¡Jƃ³.µË62Â~€ŽëP,®o¯§âIüΑÉ4Á\É'ph “H "m ÿ“ï+áùœsƒ"3B¾ÇÓá¼|)“}ž‚Y_x}Q%Y²)ÌÉ:nؤ û£whFÛÂê¸,̳™ôR¯K ÊÖÔÛ$5ÜD(ÀoVçÏÔ%Ä>òç0‡Õy,€€+N68µöôÚ`#­ö(;’[ž¹IÆÛNhñ Ð]õ`3FÎ\`1m :Èñ(ì$¸ m ‡Øhd##Ø/L6»¾þ ”Jgl´ÇJzŸ“¼`wbsoÒ]RæÍ¾á67ŠÇ†ÓÄcƒj øJ‰”† ¡ðĸ^¯´)ƒC'lÐ,_¦‡½•nôüùÏ;hì—IöhǺi¹Ñ+rÉ¥ŽH€¼hxN"S«Œ|@2B[T€ÁWt¹do^09зn(>t£³0á!i ÁÁDu ú¸áU²<”péÐèk×âå<‡ KKasÑ=C9hóÕx‹ÿL6¥•{°KoWN.¼@$%I“jèŒ;«®•Ñ—“qg^ÂY•däÈ@òæ@R• w7M‰a)®ÜG0@»’¦™ŠŸa_Ê“=Ôñ­!ƒ)¨… ‰¯›oHœAÎê!ò·1Ń`%Ž ø xÎgˆshPõHã×B˜¬˜pBŸ÷c—SQ>*†í|ªZƒ•D^4¼tôåpmjó[—79ÆÖtÅ:š/÷k¬¦[$p‹Êª´Ûé)=ŽŒ”q¹&¿Tx™Çš8´`H[Kä%Ö¹=K°å†Ã‡ÆšNÈïK¬ ð¦ å@Rä¿SׄñÐàûàk; ¢]U 3Æàúek®kúbÍ÷NþÈÉoÚª â`ÁÝeŒ€Bu¯ì}NEò6‚½DQyƒó(•µ/ir°ðÍG=ÎÂÄ|a„ÄÞNn:Êɨîx+°(#Éå¯U=Ü V2ë eˆûaIN›Žï§ÜWˆã[¬²·Xz@B¢4†°!R‚ ßW§Y›–À`HKdÓ5ruåG‘Ñ׿¿Ü±1ŽæÑûLÊ+¥0“ñHWÔ„Ü#¯ÐÃÏEÔeø¡®k]™Z†‘áî…ó¡€nš|'ï4W2‹ß€‚þYGÑCçó㙲w¥†;,“;¼ªP8c$I´­wŸ}nr… —}…Ù÷.m¥j›4;ye VóïøùK·CMW2:Âb.-ºLrPÛÔrCâô†yr;AávB"Ð}dÂE Ä k!©äâQyO[þå=¶¨BFâU¡ ¨§è2ü¾j 6Ñü@­í¨$¶ï$+¸(ru‚UT5ÔZ1Yaò 5XaÂírÃe©6 ¬ûË4§2ÜnúÚH÷ðC(©¨´Äôö££—'mß$qü\W=>¬è&E@¤©ÔœÌôŒÀÝ¡ç©âs·*©Y»¼P–ËÜÉ»PùR/û" ³Çnüf‘4ö½µ€»\ùÚÎà7p0r~ÿŒNn7PHé)‡È<çkØw›Ã®†;–K®E–,éòð”6h.ûäŠxù£ñÿÄXË%ª) þv¨Á–^ËCÒî& wÙókÁ¯êž¶g…§±"£ÆÎ„ûl©„T[UåŸòÏxÃ~Þ*r"ÜÏ•ú{Ï•á™XŠiOfQÒÑ.Œ›g<,C{¸de•Þò/\•ëx?b:!_ìÄoç°1ßâi™6Vë.µ7Ápt„ƒµUiÿ4*ÎÊ÷x|¿½á gä¡€’$ ÕX /XYþ`$x~ìÀ)fOßþõ/?8rUÅ­"œâǯØ%¸7†eK,UB'R±w»r WÎ 0µÎ³Ìô¿|œ”T¯ÓЃÚ!\­B‘~y;¥¡r” ­Ó¬íNݵl¼Òÿ+:GÅ*Gç‰d§Ñ Gý®_ŽÎ(\ùç1EOØ_R=µÜÐJ³Ü¿©y> endobj 1595 0 obj << /D [1593 0 R /XYZ 56.6929 794.5015 null] >> endobj 286 0 obj << /D [1593 0 R /XYZ 56.6929 653.8593 null] >> endobj 1596 0 obj << /D [1593 0 R /XYZ 56.6929 617.2073 null] >> endobj 290 0 obj << /D [1593 0 R /XYZ 56.6929 383.5656 null] >> endobj 1597 0 obj << /D [1593 0 R /XYZ 56.6929 355.3681 null] >> endobj 294 0 obj << /D [1593 0 R /XYZ 56.6929 308.3188 null] >> endobj 1598 0 obj << /D [1593 0 R /XYZ 56.6929 282.9907 null] >> endobj 1592 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F40 1265 0 R /F42 1338 0 R /F54 1433 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1601 0 obj << /Length 3314 /Filter /FlateDecode >> stream xÚ¥koÛFò»…€; `ÑÜ_íõ€Äq®nz‰[;Ú~ ¨•ÅZ"‘²¢þú›Ù™¥V2íôPggggwfç¹²EðOŒ²8ŒT®Gi®Ã8ñ¨\E£{˜û×™`š‰#šøToîÎ.Þ©l”‡y"“ÑÝÜã•…Q–‰ÑÝì—àòû×7wW?'2ŽŽ'q¯ßþg,„^¸¼zKSo?Üðîêõ8ÕÁݧŸ¯“ÉHÂ2!xåÍûËÛ¿ A¤¿FqtùóX¥ÁoîÆ" >¾¿ÏÞ~º¹ùhgïÆ¿Ýýpvu×KäK-"…â|>ûå·h4á8‹B•gñhƒ(y.G«3«0ÖJ9Ìòìöì§ž¡7k—i1VYg2P£CjŒó0QRY5ZÈDQo¶ÕrVÕ÷,i3﾿ý÷£D9›ô¸E£‰LÂHêÄòéIÏa)¨¶[`™GÁ²èLÛ<3fÙ¬W¦fÄ£Ù´USÓ ™Ó—YÓ¨jé[<Õ²˜.™í|ƒ÷Ò¬h´èºuûÍÅÅ}Õ-¶Ó°lVÍÚÔ³ºmMyq"†Çb€ò8–VŒœÞh.ÃM.•"LbÉ7@³#½?܆[0ñWØËоúžðÅÝÿ1ü3*‡¹PùÉ!O̤§zz²#<å†Gûç€ ¤aª³¸#ø‘„›¸îN®>-œ}WØ;svQM7ÅfdfFÃ)£{#úZG¾½ºÄc€åé,L¤’Ç—·&›øÝ”afýu *Ýívã\áAŸacÉïŒB$q íD{b2ÎBÉl”FàJyª¾jýЉ¿ä©Y<åìì‚d8>ÿýéÁt„w"õÉÁN,¡§zz˜#5<åö¢%d¬.Ž” ÿÝ¢*òÝ1‰ƒeSº½"¹4í¾íÌ ³ŠRè (W4h§¬ ç,c.v»©º=ºE&Ö,b3΂­¡ ÐtÛPñ·X.›]KK÷Í–7ô5_ÖfSQÆñ AuÑU̽ψÈc·0õ(öxBáQ@¿ÇoÝtôqT¢óÜË)vºt¦†MмßR°˜Ö¾Û–É œÙlÆèp{û# FÒ ð¦éÜ}Ìa–G‘­fÈ.0ÿ•›ýºkî7Å ™Póm]v²Ús[Í#`5d¡mÛ'Њ'çx*œ‚>*9*^üæúÃ[fÝ‹eç[ú’V>o+VOØ 1Hˆ7(¢J ¬Î‹í²³F’²Fí_Š=MÆHCÆL0ìm]>Ö~¤²¿t1r½1óêË@hPq˜%qÌd¦+/0,Ú•„WÏÝvq´Ã µ âénBªP+!¿º[J%Lf¸; 'e´a¬Ž ù`nR‚ûà½É ®Öª‘¸ Æ60d©ànaï¨0æÌZ4SCÓ T9›j63¿g~ &¸ýøîîCEóXBüMÔhþL=)Ã<ÃP*=1|ŽfhÍd‚ÛNHöÉ´( ¹‡)¾m—Ž„lý;¨»‹õCÙ q±m7nÖÔ¨òÉ}Ó¦·ñªx0_·,Y©/Iqr”‹iU;Ÿžl»ª?9ÞäkÐð¹‰v‰Ùá)ÂðBfÕwbÔŸØÞ‚ÎÁ{ýöEqóÂs‚ézvc¿Ú¿œ¬U"ö ÐÁª™BC j *èS†Z§M NÚÒB¸ªf½d»„ô-ŒtŠ_>ÐÄÕ¬1íÐåQŽÕ˜”–Ë=ív½n6Œg °É 4¿½$ôz,0¤A€«B4Õ8]tXµ!hÓ®öR‘,› 9UÉÛuy/ Ž'ÜÊéÀf°ªØ5Ô\i³©î«º ñ`5`2Öô»K-‚ÛËׄ jÚðQlA—º‚#[AA^ú¡—`@¤íÂjÂa²´Hökÿz@$°ý5Ëü+f§ƒ ÈðYKSPÉ݈v zÁΘèëfö–ž•ì9ldÞždci¼j«ûzÒÔË=šTš8“‚)6)À±Iî`?)v:¸Øª¦ì5Ö5k„]CÏ ÙS NZ´í¸{V)†\"Àú¢2ag梘ÝÀ=q(‚eù¡a+÷M:¤.âTÛ#»1ðÖ·ê~a ðá¸ç„èw?ÚÊÖˆ­ ðlÜHV30/ÚÆPWkµôM×hÅ8Çž%zð éË›O„„Ä’Åœ©ñ¨Ú¾š0ŸÃY‘òÙÁA –°'^wDEþh÷â x(ãazÕ´|P3G4&„²¢$Š«"Ã7ƒLW|ÄÚê‘út»cÓräxâÇòðàˆIaâ´;§i¼õ¶õˆ¯½þ:gDVúXt<‹¶ˆ¿gœ“$\A ÏÁ‚ðβ@ Þ=®Ë—«$ãg8u{·˜¹[€Ô@±„¿$¸¡‡±=ÞvÖœ±D›àC]ÝÒð<„;|û‰r›”Žýúꆌö½Ù¯ÍæøÁ£àào¾ø¢Ç©zî…"ó}(t¯Äa%ÉñÛˆ- T’W|0>Ô¸0(©ÜÈ­ø­ËåvæˆícbÂ=<Ø5”Ó‡.ui ÖÅ÷—|` ?@d»ønwPä,VS©²Æí(î ìІÔÈï;ªÿÉanFZÙ}Tÿbp ƒ(ÌÃ̾é@„Q1lm©)ì½íl„3 ÖÛi|ðÛ!r³.6ÖÐqä„,œ­*™¦°­@,và ×5aùUöøgÁŸ‚ji;ÀÓÓq ñ}@é4¤^Hï‹@qÐ z@“FO­‡Í +†VâÆ¬¥71ÀÔæ± ;z೺>©þ­ªŸ-D.B)£?õ*„O^yëáw!8W®Âöß:Æ¡VJ õqÑÈ ö—ÿrå`': U–=Óª( 3™§ý©P£2Ç KÙ[Dä!d5¹Ñ§bõþ2 ×ÿ1Ô;Ùendstream endobj 1600 0 obj << /Type /Page /Contents 1601 0 R /Resources 1599 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1562 0 R /Annots [ 1604 0 R 1605 0 R ] >> endobj 1604 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [91.7919 717.8468 326.9102 729.9065] /Subtype/Link/A<> >> endobj 1605 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [257.3066 705.8917 408.7387 717.9513] /Subtype/Link/A<> >> endobj 1602 0 obj << /D [1600 0 R /XYZ 85.0394 794.5015 null] >> endobj 298 0 obj << /D [1600 0 R /XYZ 85.0394 769.5949 null] >> endobj 1603 0 obj << /D [1600 0 R /XYZ 85.0394 749.6278 null] >> endobj 302 0 obj << /D [1600 0 R /XYZ 85.0394 511.9806 null] >> endobj 1606 0 obj << /D [1600 0 R /XYZ 85.0394 480.8791 null] >> endobj 1599 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F11 1559 0 R /F42 1338 0 R /F54 1433 0 R /F14 1060 0 R /F61 1466 0 R >> /XObject << /Im2 1455 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1609 0 obj << /Length 2065 /Filter /FlateDecode >> stream xÚ¥X[oÛÆ~÷¯ ЄÌÕÞx+ÚÇqR7ã+§(š>P%¦H†¤,+¿þÌî,/¢é$m8œ½ÍìÌ|3;#fQøÇ,×#^ÈCË%q)s­xwF­ ¬½9cfÓnr†»^.Îæ¯E`…$ô¸g-Ö^¡AÀ¬Åê/[ÆÈ XPûöíåÝOŒÍîRûué凙ðí?o3Øïß^ÜY½ûx{û^¯.fNÀ)·/»¸]\}Àei8^¼úߌ1f_Ü\^½Â¥W7wH¼¾º˜ùÒ^|üpu7û{ñûÙÕ¢Óh¨5£B©óù쯿©µå?£D„k`@ CníΤ+ˆ+…hg²³»³ÿv «úè¤%\x|ÂŒœM™Ñ ‰'¸èÍ(˜‡Q ¦Œšx›æTõ}™äwwï”–ó×’xQË>°3ÎøÏÌñàôa“4Hm›¦üy>?¤&u‘¢ÚÌëb_ÅÉÜL9”„$ø“&ªÈæ Šác1”€þ®sõØTQÜàåšmbˆ¨ZFYöó3ל7ׄH|y\#ño/tQ–ÙqtR™Éu¥XìF;^^ßP…øÑÛ’,‰êä«ZxC-ŒE:%3ÄjRœüÄ„TÜ-À„’°p}èºèÂ_pÓ2ÍWáþŸ—÷qÍØØWŠ}÷®”DzÀoŸq†®œ>èìÀ<ï+A„ç(ð2d{â”UŸf¤çæ.ïãƒ[h®ììq"|æ}ãÚ.7¸ždj#œ+8Ü\ïx–c*Ÿxܾ[xRŸû– |BC_‹¶>[ŒP†7 h­ko=1¿ÞqëUY¥ZÆÎ³VÊ=¤LØå[.q†°½)Å@a2Rá0ƒÎ Ço r)åY‚ë»h&¨}Ä…¼hXšÕ¸ØÁ¹t9ãÔÎ £CÚlG¼?q.5EàÔ¾I³´9âÆ"ÇIg$}•£AK[¸¢[@˜ÎR~`×ǺIvõŒ¹6¤o!¥ýçŒI8»Çõþæ0È“d…TSà7ÍëåÁàÍÍG$ô-ÉØ›Ò ÂÀ"éÇÀ©ÂÀ =@gŸâ,tNñ.BÏâýé{ %"@»þ±MÀ,tíå>1;[i;« óœã¨Ì`5Š¥ùêÃÒŽp˜¹ÖÍW‘Nq+\ÌŠÜW9u³Åž™´WER·|ÌTš7IµN0aâÂL-¶Ï•žÎÒIÜ,«¨J‘-…”['‡í€µñV&Y+ÑÀâ0¸¯®‹,+ÆDÀð1Ú•YRƒTmq0»âmQÔ†n üv°ÃA;­rnÓ¦ß}]©)rª ¦ì?f!·Í›rH5„Ú×í»¸Mk¤zƒë­ÚÅš2;ã"W¡¾Ù·–½R½ô€H?Zú»\¡*!¥,a ÔrÐH rÔ„a%…šÍ˜`bp5küvËñ¾nŠX̜霬O§ÊŸGe‚\É›æV†e]&qªÔ…=yH£I£ó°ÑÃ,I(ÖRÜÔR/÷ µE5ª .®n‘x›!ç!Ýzì]šï§«î_B+ù ÅLpŽÌg35©À ¾~¶éf«jµ­NâÎõjí>9"Ư¢M‚»VÉC'ç*ÅBâß7¸ƒT­ë US%–=éÊðÛšð?DC)qu,›bSEå6's|CQTi|õÈúöµáÂÙ(W$ª”ÿÕ\±oOëmê> ¹ŠN)U€ÅÔœÓr»û/£¥6ì¨!ȵaòTŽÔªY³®“Ä‹z*J/o?tã¢M5Êýê{> C“&N€ñ¢N7¹SäÙñEÛàP=´êƒy9·ÉÈÕ8á; <à*N1.õ= J°[ïÓ 'ûØ Ñtê»J²ôÁh¹Â)S„ÜèÔÊÕ<õ°.ÖM 0•žN´x¤ålRëùPZ–™~™š.a”KçpëïoâÒ”Úúnòk©RK= lŒ_ƒµ² Íu>b1Ìѽ˺Fîó>E¢nÏá0ZÕ†S]œFþž¹EŒe”|?jŸi'|bNùe‘¯SxêœÈ”GM’'U+Kêær×Qê^p§Q_) Ô[x"ÂqÊ{Æ0Sí’_¿-§,G¹Ô0[g*þÚeÆçu7¨’uú8–=˜N§ÂI—¿n´·¥;( jç8WÍ{Ÿ#­ûš§…£’뛎qÝ'Ò¡Ì ©çšM¦E¦P?c ó whW}*ù¹>×$€ª§b¤ "C1*ÐÓÁóJÀ>Ox⟉ñžh³†V›’Ÿ#rö'}§Ð<…¡j¢¸ îw4IÐ"AðL‹Ô1tŸ¶H’ â¹ßÉÅÖrÔ½úÑü®(Mƒ¢TZû|¥´ÁèhÁB`qŠã£îMûl·)šÓ,­V£œ3ÌfϲxHÈs?ÅWxêCÚýæñÃ?OZM¼ð¯wšæNÊÃî‚`çàÁàRÜô‰Ní/œO•ú?¹TÀendstream endobj 1608 0 obj << /Type /Page /Contents 1609 0 R /Resources 1607 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1613 0 R >> endobj 1610 0 obj << /D [1608 0 R /XYZ 56.6929 794.5015 null] >> endobj 306 0 obj << /D [1608 0 R /XYZ 56.6929 769.5949 null] >> endobj 1611 0 obj << /D [1608 0 R /XYZ 56.6929 749.7178 null] >> endobj 310 0 obj << /D [1608 0 R /XYZ 56.6929 373.0201 null] >> endobj 1612 0 obj << /D [1608 0 R /XYZ 56.6929 347.4367 null] >> endobj 1607 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F42 1338 0 R /F22 1037 0 R /F61 1466 0 R >> /XObject << /Im2 1455 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1616 0 obj << /Length 2136 /Filter /FlateDecode >> stream xÚ¥koã6ò{~…Ñ+°6Ñ"©çâ¶@6›\·ÛnÒµ÷€C·(h›¶u‘%Ÿ$ÇIýÍp(YR”ìm†Ar†ç=â#~|ùÌ•±7 cù.÷GËÝ™;ÚîgÜîqêMN{×ÛùÙôZF£˜ÅFóu‹VÄÜ(â£ùê·ñå·ó«OGøîØcÇÜñÅ»N8çã‹—WïõîãŒ&×W“ÐÏ?ºH$\Ç8·'o?\ÎþÆ9mýâúî姉 ÇÿºOx4¾ùð`;û|{{c°óÉïóŸÎ®æÍ‹Ú¯æ®Äçüçì·ßÝÑ ÿÓ™Ëdù£#,\ÆãXŒvgž/™ïIYCÒ³ÙÙ¯ ÁÖ’¢/#æG"£àCbôcH!$“‡»®;~{HÒU’mè¥7{Íf?Ób4©¶Ú âò‚&¥YžYTžª")Q>À…hqáŽ#.Ý?7ĸDbŽ¥Ã½–:µ/Pù}²ÒA€²Ù–de¥Ò §zEUÒECùXVzG¨4Yªx4r á"h·,ˆ8¿¯ºô-•ª˜DãƒetY<î«Üâ—KêBU °­s|/¾ƾ/Ì {+¶ÜÚª]&;]ZÉ*`²®²"TÙ#M.o?ŸÓ¬Ì{øâºRÝ׊)·*Miº°^·N›Q8}ÅV#„žáô}V“O,gúAíö©¶×-Qeôa‹ŽÅôõoQÐÅÖO¼øå]`ÅAŠbd0^Ï`¤Ë“ß?A3/W4æ`¢e™:.‹YôçrHö›^æÙ:Ù M€’x <ü†å’_¸ô !³È“¼KÎqöwœ;`:™Úé7ÓCYLa1 ¼éÉœPSR O¼Md¢öÞ )iøtÃB¡×ÉÛi¾¯¦t%ò1ànNó†¶1À]×f£hÂY$UK©V뇲66!<+3”ˆ !µFW4iÄÑ–3Áó©Á]¬»_æ³í€-Ù›×eöQíH¡Š¹¾ô’Ù©;=ðtBÌ ¹Ý„PŠ™ô›!r]V$=É<Dv; èðØeÂó"¸Ïü8ôÛaÖû†0;Ë×Õ³_¾BëxµÑì½.Ê} œNÑqT4”pîØø2Bêi+}¯Sp¯-lbNkH®³«KZÛ(ýo½¬N¬l«jÿz:=“XŒzë üU/Yn¶oèyœwŸ×6ö¿÷“l,XˆUd:ÈcALI‘°w£zöá” ëNû„É@ó„.Þ~z@—ùMŸ+á &DöØêåêf×S^:2xJ ™ùaÀBzQm‘¤kyãã6YniÚJŸ%B|4D4II¾¸VKMKÌV8*:qŸÕ2­±ÛC˜ãÙ<˰-wè‚ I Y5£Ñ˜NÀÖw4Ë×4*f¿þœTZÒb¥*µP¥9#LéIó¥a ¦AR]§Ç÷ã“s BYÙ;ý6¯”¥ØX¿Ù…í=ˆÈð,"×›BíAÖZ²e®WÂí2Ž¡ºÉ›-ေ’f`A‡&…FMÎ(# ©7ÂØJÁ&:ãÅÍö4Í4}ÌölN£~fÿP9&Õ–ÂL§ð=nu/EÙá¤NæYns„ºWIª©*%LY'ݰ%7èK ñe•×¢Àåîq×Ì‚%xðTcF1¹†PI•¨4ù³Æ,ôºCíPš‹W'–,=g6ꞟˆÈéTëÞ\Ïm4n{=÷bòA™ÁgÜÏüJ~Áâ]v¨àwŠN›$Uóm¿ç¾€ªß÷O7›®èæãµ-Ý2ðYãø™1¼‡ä*£ Ûè2=ªG«à}žÔÛ«~½Ùh³›²U•Ô¥¹àë:Î Bheþ¤œã¢UÏaRÚ–;³eøL5GºÅÜK%Qß‹kuÝðÜT uê3Ò—6ƒ¿åEEÛ­±üÚè0d_Çù—8ÓË­- ¿s_X-¾#ü4|ß¾ò%6{â™.’¬&Z ÝÊ©ò; qkD™æU@§Í ×+¤rÑ­W¤ïS,“~p ­¸0}ŒA÷"à “Á•& (V+Ú ÞnÒ—oÝ@y–>ÄÆ~€A¨,Vw‡¥. ¡`íMARå¦2Ì^Em™ÂNRc–AØròK6@J3ÂJLÔ ™ƒÆíh/ÉMJ”̰ÛC¾ùaNý¡¬£û€m,†ªÑ[1ñÍ­±K“ìð`Û0kZûj[hµú+YÏÄm7R»Îó­™h͉~µŸû«™ø†V¨éÛ"ü¾ãE_iŠ Hsƒºshàž¡.iîßÖ(Å­k¨JppÉ1ûµ«…ë·•18Ùª{MމÖY°•²aUËçÏÉ$XûµLÔ~_N­™Ò9m’ÌÞMZx ƒË;BÃÆÛa´+l(zÎ2|ª°aQö&EbŸ ƽ²L™ú)îö U<Ò·…3B Ë*¥ïXæë¥gË-Ø‘ª½ (pª„â3]ÜTSãa½qM€ª>¹Î±˜¤°pðHm,¼g¥±óiP¹åÆõOQfÀ1J·z5Tðu»FÒ53èu(Fšaâ¤VœÉ> endobj 1620 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [91.7919 497.8313 243.224 509.8909] /Subtype/Link/A<> >> endobj 1617 0 obj << /D [1615 0 R /XYZ 85.0394 794.5015 null] >> endobj 314 0 obj << /D [1615 0 R /XYZ 85.0394 769.5949 null] >> endobj 1618 0 obj << /D [1615 0 R /XYZ 85.0394 749.626 null] >> endobj 318 0 obj << /D [1615 0 R /XYZ 85.0394 555.4869 null] >> endobj 1619 0 obj << /D [1615 0 R /XYZ 85.0394 529.6161 null] >> endobj 1614 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F11 1559 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1623 0 obj << /Length 1763 /Filter /FlateDecode >> stream xÚÝXYoÛF~ׯÚ>P€¹Ú‹W<8ŠÝ\µÝH)P$y (Ê"ÂCåa[ýõÝYR¤LiŠæ¡„½æÚofgɦ~lê¸Ä x0õIÊœi”Mèôæ~™0³ÆnÙýUÏW“ù¥ð§ \îNWÛ/ŸPßgÓÕæƒ% cd,¨uóf±ü‘±™Íj}¤]¼› Ïúãf5c¾uý挙Ùåû››k=»šÙ>§ÜZ¼<¿Y]¼Ãii8ž¿ø}Ƴί/pêÅՉˋó™'­ÕûwËÙ§ÕëÉŪ³¨o5£B™óçäÃ':Ý€ñ¯'”ˆÀw¦÷С„ŸféâH!Ú‘t²œüÖ1ìÍê­£^d”páò7JÞs£'‰ËZ¸ž‡nTîÚŽ*ÆÐI.E"¥½ªˆ8¿MòéªÙƎÚ•‡}]`?Œ¢8˰.JÍ4¿ä}5læ‘@pj N‡I­ÇUüPŸÍlA«œùV“ƒ³i}ä\¬Já¹`¿Úî÷Õ¼ØÇyU¥¸­UWÑhÒv=¢.ñ|Á 7%` %·V»¤Â÷IªY +¬ë8Û×8¬¬Vm’'u¦É_Ff½3ÄšVš7³^mÍVà $jàß#‚Spà;pŽ&®Óá§EB»1mÕ¶ x¾ª¶Mš4vÏp\ó‡ÖXT©¢"Æ#Ôù@· àÂ<8>óŒ[>˜ó½ “µQÝO#þ„}õÝ;µiÜq ,lNIËõåá:è3EM½ojEk¯è±¨(QíH£üÕ¢DÍ>óRÊã ö¯—Ëå[ìTMRǸÎñ±Ï¹€p÷#0]ÏÑu’ â:Ž¢¡=oªrÌ”Œw|ËŒøÇn—ØRPO+¨1³…^¹2ç¶)“üóüÕ•IŠ6Û¢Dâm’7-ÞêAìÎ@÷üâ‰7ñaéLðpµ*«YÀ-ƒï4É??Éypì5RŠ»d2 SŸµ‹Aá¦Â¬©L¬ ›8WÈÞ˜ÀÉO„<2{Ý$é±M‡˜^é=Üí)4Y—ayÀú ˆº]‹îB»gÆ,³@ç h£ÆÄ@^§†I‘·T/.u×ì ±Ü^ëDô:É•*E•p9¦"˜¹o7£³\©ŽÞ˜ÙÇ_¡â9JŠ`®åJ”¢†vE¥#UpÍVM£¿Õ¤²$Dñ`{«¤ÒRqx}0«6Z =¦"ÓÎ7 ³*-ª™ü¶3 œƒ0JмÂÁVçº]¥xDȵåm>9µ7*²,Ì7 c2Ãtx±ý„‰2Ú`KÈ`Œ±7KÉÔÙ& ŒI²‹Å³n£;Êì i#`m€6ÂZßÈL òÂ!>äŒVÞ÷¶­ÂÇ6·å3bzidÈáD?³—ŸnºÕGHUŒ%œN%¸ à’sû Çý–„³,Ò°Lª'ÃrqŽØEÿG ç»`®ƒÜCXF»ga¶qå×AO2âKÁþ3èµxsåäÕf§JßAªj½l1bÓåÈÖÑæ‹¬ŸèdaW¹E§1ã]é´Eïé€å·N2M;˜íÓ0É+Sb®‹¦Æ™®zP¼0£÷Eù‚C×ËÂ: gáìÂ;Ã9ÄFðy›œõ¨ÑŠ‘¨îi"¬,©²°Žvdì®;t{®‘êµR=ÖJ*É{õZj¦«}u•‘@œ±u|©¡Û£Ù @–Ö\1ÙMjö¯ã>U˜J_ý)8wo’;¨ð€œÑ·=fm÷ì°äîó¨žÓÏW†½ÃÆŠ-:Zeyß–ô¶õËå¯ãyð.×ÿú<À¾˜þÙÿÏSvUöDÄw:õ#þ|[ÇÆ}Qß×gí›È¼9ñ=4úš ¡Búý×Äcéê:½ÄÙ—¹Âz9|¡h¨ÅÕØS$…ëÞ':…µEÉR$AFÝGb¾ðr s6òˆó\xÄ1˜ÞTŒ^uü3ðõ©Îv,@uPšê)£PgÕÛBÁZ!©n>½`÷™¯ÝúêPÁËûÈIùŠW‡Ô˜ÎCŠÀ<¤E`y[À›½Qnq}"sy}¹2QÕÿ¤#}I$“®zÖ‚íìk¾éî|ßÿ¢cw íGýµfxÔ¾G$N'W¹yq}ui„‚Oé zâü.Áb$?¦¯;¨TwwÓØ+õ™iäûü„ý5ëøÁOÂ;Û÷ù¸é':)ÃzÉ0lß(T€Rên{dSûAì±Q}%Þendstream endobj 1622 0 obj << /Type /Page /Contents 1623 0 R /Resources 1621 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1613 0 R >> endobj 1624 0 obj << /D [1622 0 R /XYZ 56.6929 794.5015 null] >> endobj 322 0 obj << /D [1622 0 R /XYZ 56.6929 645.8859 null] >> endobj 1625 0 obj << /D [1622 0 R /XYZ 56.6929 615.3584 null] >> endobj 326 0 obj << /D [1622 0 R /XYZ 56.6929 448.9643 null] >> endobj 1626 0 obj << /D [1622 0 R /XYZ 56.6929 416.8727 null] >> endobj 330 0 obj << /D [1622 0 R /XYZ 56.6929 226.6729 null] >> endobj 1627 0 obj << /D [1622 0 R /XYZ 56.6929 197.3907 null] >> endobj 1621 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F22 1037 0 R /F21 1034 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1630 0 obj << /Length 2465 /Filter /FlateDecode >> stream xÚ¥koÛÈñ»…€pRÑܹd€~p_ãsꨖ|mJ¢lÖ©);nÑÿÞ™YŠ¢˜ÄA¡;;»œçÎcWbàÃO ¢ÀóU¬&Ö^à‹`°XŸøƒ[Xûë‰à=c·iÜÞõjvrú‹Š±‡2ÌV-Z‘çG‘Ì–‡¯ßžMfç×£± ü¡öFã ô‡go~ !†gW¯ÏßÐÒ›«)¿œŸŒÎn®ÏI_ÂgBð—“Ë×Ó? A[?ùÿúz¤ÌðÃd6Ñðýåàxuz3™¼·«³ÑçÙ¯'ç³F£¶ÖÂW¨Î'?ûƒ%(ÿë‰ï©8 0ñ=Çr°>Ñò­”Ãä'Ó“¿7[«öÓ>+*ò‚Hš3J1 ã v b/TRY;ZèÑXø~Ç 3kʲÌ+TˆÉ–OüìñTKåÕÅØ[9ŒiÈŠE¾[¦ÍÖY‘­“'bX¥5a˵eÅ /mÒmR§Œ¼càíôo/Ú\²â–%- AAOK-AT”ps¿¨„ß§O·iÑ£ž”"æÝNØÛ’ Áïc°¡êLOÆ¥Y¤`·( Âá&ɶ„zÌ껬 تËVc¹…2ž‰Ux(wžUuÔðé‹–ÔÈÂn¶<Êù¿ÒE]z±Ûnñ4§E?*yH²<™çi¯$:òŒ%§ÖÛò©Ï„¾ûFv„!–ëò!%ëi?ò"m"g=iw³ /èè%ŲGž@{@°#N]Þ§Eß 8Ômi€2›y8ÕiJt<’QH°«P™DT$Éx £áÍÕÅ?OßeÅî Íç»,_ZÑB÷V)áù@#˜öûkËÂz"Œ‡ÙŠ0IÅ4dLbQŸ|_ÞîˆÔ’°x²˜›=W@é“”!¢Ç#ÁF"|¹©³² ýCëc»*ëôåh¬u0¼Àˆ& %GF cåÁEŠ_Q¬ÀìÖOi…†§×' Ô–wÝ%í£ý,0"6 ꀨrÕYjb7Vóò![QHå–‹ÆÍÅÁgÎòŠR>f9¦ŸH ç)ä  :p´G@6òtÅŸíŠeŠ.*Ò%Tã«áM•v(Ž×4’3ÞÅfj JwŠ‹Ž4”?£ah¥yNy‘^EQq7Çm’T9Ú¡¤#ãù&”{ÎhËÉõûß.Þ@ æ°–P]ÂèÐÞiñ‘ ‹5¤ µ‡d›µÆj“.²Õ#ïx•ÎF{ß~©s<[¢]ÚhÕ=8*â}Á ¸àÝTX<éB^þVÁ -•_ÐiZAk°I‹éôÝxžT“ZÅîÐÂñÔ˜ûSÚ¸ÞaæÁu<#[šp!°ÛЪ•Û ‹:[óüÈ–¸»*i±ùŠå¡UΣÝp?(óy6ß‚C°TãtaŠÀœÍ‘—É2]¾$“èŽI,c¨“øi4Á¤é—M¹­ ~÷æ÷w¯®Ï®?ü>9›½ýË)ûSJ&§»j{ ¼_þôŸÎ®ÿö[ŸXiËjv‡YŽ4ˆ»a/QõÕ á…"T\Šd.{H+#\@‹YÂ%¥.C¾Î 6.à9D,Ú…1h{D5¶GlrYÓ>Ñ|E¾[÷Ò¬g Ú=Fê[ˆÀƒ(sÕS-…"‹Œ2‡N§Œm$9<÷Ët•ìòÚy}‘P¹€„ê³Ám˜Öé† ‡)Jþ¦HiUY…qúhó2B»}”@õò1ÜW¤V­–kkTƒáXD…ï]æŠ)"?™ãA¤K6Lƒ¼gìéÆÂT”±¢ˆ¶d¾$ë vDcéÖ½ Í(¸ m•ALRÐgç.Ó§«M=q—Ù®ŒKzd EÜ1™V&Œ\Y¬ó¡±R"–—m­ÖëdmfŠ ­b¦!MbÔ$[ÜÑæª.Ɇ,HV¬ÊíºE>™—»ºÃ•ëÑke+˜€£SæO8†\ÒÑ©¤~ÀyçÉ^2ÀÚpßÑþŠ¢ )C°mBp,úÂI/‚æµO$ü)UÖÉ–9uôÃKúʓʸðzÁ‘)Ť9,r õ7Ó£þZz¼<ÿ09¿îI‘½Ò~?-Nwè`-ãžZÈV(hÙ$XÀ`À‘jxèÓôΨöØã<)žˆ¶Y„‚äŸî*¢ï t_Cè[÷µÎ™úÞ} Úû@„AÛ?Ýôïű?ë…cÄûúMÚ$?Ôê¹ô–EU¥ Ôuµ-×p)Ió¢qà‰Hþ(Ñ*»-þ]öžqר8Öß!(Ž„üŠCBp^<'`ú¯w"öT`ô÷Ê5\2÷·c¾¯ÐúÂUjGþ1ŠåЦ ×Ô@.ÊGÆPþ£«½O7N»ƒS˜×øŠ Œ?æ´d;D ‹f)«« ®Òv~ˆ¢;n;âJƒôuDæX"˜{G°[[7­<¼åé¹ãÐù¡‡,¨•­fãûêgÏOT‡hQã9$¯Åä4î™<£yCÇp3Ï—ÚmÓ‹$u§+¡×”'ÄnõÃò»ˆïæ—ó¢Æü†;'W/û IoýÏ/i4PK,@ÖB©0`C,ò¤ªT4X7|Œ>Óìç½…~&L¶Ê}’1[ñM¶æˆ­üA¶ßvÒ«tUîÛ¬¦…C°ææ›}cQ%˜lJhÀÌc)ŠDQÙA¨ ­oèÙ !lrp¤7„âcê *ÛÂa—ʔ𤷓*õ»Ö4¶9ê±ú®Îò¬Æ “z¸,íË¥TVY|"VÂÆ:.r¬Ã¢‹uͱ‹ü>}€Ml9ú’qxÅ´ sŽ#•v&UçSøÂæô†hCÖsŠ‘·´^‘Ö?–ú*Óןð+nm¦—®ßiX?ç^‡Z†!·ú\GHÏ0^þÙ#UaÙ&E¹Ùf”PC×#V´h³>”õayÎäwö®Ž}Œ‚:¹ãdÀ³ ®‡XÞyvÏ, ì”sÇžFfÛÛô»¶[Ú'¼:±Õ&ó²fôf7ϳÁ”îéÔ %A–I`<)Ù<4¶Ñ'\mºìø¥Qº…4|9¨á&ßUNª¾“MiQgÈ3©4‚.Ò½Õ#f¯`‰ `Mäça³¢MÍÝdÉ{ÝÛy›,U`DM],¸½ñNÙ@8€PrŸV}ÞÚäÉ‚+H?y_û×GþUÓóß> endobj 1631 0 obj << /D [1629 0 R /XYZ 85.0394 794.5015 null] >> endobj 334 0 obj << /D [1629 0 R /XYZ 85.0394 769.5949 null] >> endobj 1632 0 obj << /D [1629 0 R /XYZ 85.0394 752.2728 null] >> endobj 338 0 obj << /D [1629 0 R /XYZ 85.0394 637.594 null] >> endobj 1633 0 obj << /D [1629 0 R /XYZ 85.0394 609.8643 null] >> endobj 1628 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1636 0 obj << /Length 2599 /Filter /FlateDecode >> stream xÚ¥Ymoã6þž_aà¨\¬¸z ¤»ÙÛ4×l.ζ¸vûA¶h[XYrM9iö×ß gHKŠö¥8øƒ†Ãáp8>3¤ý™?'"Ƀ|–摈=?ž­vgÞl}ÿ:óYÆ5Bn_ê‡û³—oÂl–‹< ’Ùýº§+^–ù³ûò7'¾/æ Âsn¯_-þæûs7ˆ=çƒ{¯îæaêü÷ö~îgλë+àqïâýíí;Ý{?w³À œWo/nï/ï¨;b¯žû¾ï\ܼº|M]¯oD¼¹¼˜§‘sÿþîr1ÿýþdzË{»¢þª}/ÄåüqöÛïÞ¬„Åÿxæ‰0ÏâÙ#4<áçy0ÛEq(â( §>[œýÇ*ìõê¡“^ô=„I0áÆ ˜rcœ‹$ BíÆ«õÜ ƒÌyjDŽô«bÇêöÜëÖÅ·¸yz+Yu7ÊÂËöA¢Ú4{hBdÓ§¬Ö(»–4¤éˆ æÔÅRÖz\b„Õ®¨ky°"Ì­>ý…vðÚ]Õuv®A¹k¢¯ר¤ÆšÖ±Ã–ïtsßÑkºl8}r0±§m¤@-4ksÜÁÔ¹—‰ÌÏc=ÏÊMÛÉó¹e‘óËVâÂá0^òÝ^6‹Å¿Ýe¡$.%ÌNç ûi/€à™‘¬} VW–Uw(OÔTÝÁªÜV«-*ÁÐêƒçR tŸbAL­þ—y;UZ‚$pš¢«$Ñlè lŤ ÙÆG@¢¥ø-¨ñþîŠc/Òl/’»â‰•4«úX²ò¦9 :¥ìŠ v°VÔ†¸;v$emÁ• ÖDè¦Ã7‘€£ô‚(šŽ,Âf§ˆ¸½ºŒrRŽ‘)ðS‘eI6€3>bu63"îz båÝþ€ç ò\/šÏ±:ŽKŒ·LƒñȺ0ðDœzÉÀºg@g¥¾b`›ð?Ú¤!½£·¥VÂòòMÔ Û’ˆ0ÉB˜Ði¥zøßçnâyÎþãJù>®lƒ‡Yî’¾¾‡‡Xsjú<íké~R§â–5ö}eÏïg´è¶üS3D#;2°xϘèI.êNèLÔOÑ ð‘ 0‚ T®%û ñ¿'ü%ñèÿ€Çµm †›¶qË m  {“1žhïÛå‚Þó ÿ{“~ ûK~ 5÷[%›)ðd–’™µTLÁ,ÇCÕ=ðt[°œ±Ì¤4`ôó” K<ÚZœOieYëÊ _J–¢dQä¸[ʃjw,¡Óoh2&00€'Âèdp'ía¡ÚF¡aÀjG=´Ï@  A;»Ö$EäJõ}W•NzÈÔ!`µ*yxà±Ú Ø^PDÑùBŒ–(L ò²&íT Èæÿ @l÷ƒnÝ åè¸p@ŽNÃHh§IJ+í<$ì’Ú=@«oSﬤ¡– 3 ±Hâ>í"œ¬ÝA¦TtN®x(zsC!2Áqe IX;- yÀ°ûK ÐàÓKÜašrâFasÐ@M„Àî%Â\'»nœQñ€–'ÜKí ‹ò¡hºb#I¢kG³DöÔOW%ŠÏÁ)juxÚwíæPì!2l˜e‘Ǫf@Y2â”°ÃÌyzž‰ õl¨ä)1Î,¼‹žçÄF®À)ºÓj"á~‘y~>ܹ¢W÷–‘¼^úŠ ÷=X |¶íZO‹\`9ŽÖf]>ÄžðÂàôØÌ]ß勽\™}Dl6•‰»¶yv‚v;[Õ×Õä™ö°øADÇ€Q=É,²$ùø:†½=pÇ|D‰1×WL²ˆn—(JÉ*· ñÈJr‚Và°~brÍX>ÇÔ°¢Ï Ùê9–EA â(Où¨6pI/'VëZ¹!ø'à ÜX_þpuózbÞ,Í“!„~?1sä‰$N vvm[«a‚éÕ«vR}e¿$m~Ú!” mÿ˜ÂjÀ¶Ì¸ƒ£ä¹ž ‡Ûûç×ôð®N†V/çˆa¶Ò®ÓTÎXg–~¬j&#_@•÷å‘®Ø?¿‘±Ù.ÝŠ¨—¦}A.»Olâ–r]ëŽ{tPÂDŠb»‡­?7¸ xZ,49ãE湪®Ÿ¨Óó LæEØø†kT|Š1FªÉOeV×£‚^Íú¹ˆªàÓ…iâY Ù§ófDLU-zÿ îå423E‡:†T±¬Á)’Úd´<–¡!yšx¼¨?%Š«X¨á©v>.!úŽÚ¶mǘ;ûãaß*©‹=(ŽiH.^Öž›n)„á±)àv^,ëÓ±Kyd÷À}VÈݾã]¥ލ7f[9üå;è(½_Ò÷»ï¾˜î¿åvJµ(¸LM€[ˆÄ‚Ì7”‡©€ªÎœ‰^@üfX‘WëQå(ûUfõŠ®K:È»-½`pq=ìÑxµ È “š#Ÿ‘G“„1H™Û Ò§÷FhìÚR¿­&œê7NuÈ3xƒôV?6QÐgê‰UË | …[RÅÜSÎc%8íDï‹nû™PüAaßJS—ÖÕR?ŽòƒôöyÆ ÄÇúÈ™ñ‘JœKªÎæ¬Â`Ûã·M9]ÿ„™ðÒ$;@)@wÇæT+Sv·ñÁ»v;¸—ãÙ¿ä±üÑÿL„Œ±H<ÂUtê`Ä"‹£¯a$àŠ÷Nª,Ÿ@¾ZQ¶@„KAü_MWÔgÅ=óä™;náQù’Þr<«ß|Y_È{ršiE—R™?PèuÀÍ=á‡Q0~é9tÚ×aæ;ýÃ×¶0Ë‚/ÿ3Æ6¡¯{u•"toW|0*pÂèÙšÌ?pÏõ?B’†Èendstream endobj 1635 0 obj << /Type /Page /Contents 1636 0 R /Resources 1634 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1613 0 R /Annots [ 1638 0 R ] >> endobj 1638 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [216.8905 689.1864 321.5668 701.2461] /Subtype /Link /A << /S /GoTo /D (man.dnssec-keyfromlabel) >> >> endobj 1637 0 obj << /D [1635 0 R /XYZ 56.6929 794.5015 null] >> endobj 342 0 obj << /D [1635 0 R /XYZ 56.6929 347.6172 null] >> endobj 1639 0 obj << /D [1635 0 R /XYZ 56.6929 316.2007 null] >> endobj 346 0 obj << /D [1635 0 R /XYZ 56.6929 121.5228 null] >> endobj 1640 0 obj << /D [1635 0 R /XYZ 56.6929 92.9157 null] >> endobj 1634 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F42 1338 0 R /F21 1034 0 R /F11 1559 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1645 0 obj << /Length 2848 /Filter /FlateDecode >> stream xÚ¥koãÆñ»…~Uir—Ϥ) ³}9§ŽÏ9»M“KP$m±G‘:’²Oùõ×R”LæììÌîÎì|øÕå ÿw'®£“8˜=ÁÀu¼$Q³õ‰h'ðµ6˜êäöä‡aÁÑ,±N)2бÄ*šÐ¤RSš 'ÔJ“&Ó,kÖ›ªìVEÂù¾µÜñwS¥YY?ð _ Ü\^3PÖ}s4×lŠºë*'«ïñ‹ëªª0pà–õGºl,>§pŽ¢{…:=}ãO®ƒÈI\ââ‘O›Mºù˜užwºíÚSd˜Ù†Æö<' E¤pšÓñ©héC¥€.B08^ïÔáõÌ„­”ãFALówtpíZU“¥}Ù <Ú³š{ÆöfúP@1h&³´f`YûcѶež¿ãoWô=ß k¿»¹¸¾½½:6=_ùN¬t8‹Tà„®÷§ŒO9IÇÓ¦g+Úã%ŸÛ•¯"'ö”¿ß™\ôÝõ>pQ?–íÜ‹­¦^uÏâ<¦miËÍùʉ"}xsé’Ô –îb—q;­m]³b`\§ë"çKsÍmE´Æ-YSnä« óÀx4ºöÁI8ÈËoYƒ·º®õ ÌD^Ü›mùèÌ÷á9!~=$f9‹ú¡¬‹î`}ÆýÖ™ØׇI©]øHì-›0êOlrDø²(F;üãæjqvÁð0÷öâýÅ?'üÐ>¼7+A5*Š­§²ªJ«®1PÕ<1ÈÞ@:/2ûï‚nšª3 0eYÑuG\oo¿7Ûô«fÛó€c`µíŽr $ Ìî 3+hbKÙjBU¼1˜%o @Î.J®x§WbÝMÏÀc™2ðì ü_æIð•I>2¢/¤èp9¸nõi+{æŒíe©m'dpʵcÒÜÞ¹8^‚)h7÷ëKŒáÚ ¬›Ýþ í 'ÖM^À!µ’¸Hx<œ¤ˆÀRf6!˃3¥P¤L`"(¢ºM‘•ˆ0´iÇDfÕ´ïÛr¹í…ã3NË9Bëc±û²c°J—EåL9Í; ‡À¤&Òxd•÷Œ%ÓR<^¥9r¹²´›dl ©'žJÒaûùªYþnÿÌ,•ý{÷ñëMYÛ]³m³â›Ó¢ÏNWÝP¾£"à8‘õäœp vkä±GIð‚ îm¦ÙVù”¥¤‚½çKZæaª&ºš‰¨ÀÆLâþC)ÂÀ‰í ­óRiåھ窶‚ /I:ÁÁuÇÚ‰Ý0|y-æsa- ÇQ®ŠY w8N•ƒÖïg‰ëD±¾ nÈ®ôãHAè{¤:Ï "eLdÁSYïé?RϺ`e}{¬+ØÅ÷à°¾ëÂÅkÒÕìh!ñ|_Ñ&é÷Z!ÄéåZÏÎq6Ó,lW&1Co|ïP¸˜ƒº\NÇ7¦ ÔJB/¿œc˜â!GÈýá› }1‡RâsÏ£!Œ{Ê­Óº.Z#ߎm‘o³âè.¶@ìVÙ ]šÛSQûq®0Äôé~qÝßmÇÕ€TÛÁÄrzMİìâY2àÃâ´ù>­Òž¡ÝBf³ôÜ£=yD!¾¹|¡6BñšV¥ ªæÁ§z1û@‚êv]_¬¦Ú<N†¹¶fõyºŸ¹¤ŸDÐH„z66ú¿æGè±A&3{ßðü5/?tMåÝàšÞÌóí‡jÜiå9‘vÙ5±IUºîq“¸ƒ²³„H]í¤AlÒ|_³þÜ@Mg2çQœs©Ä‰B8î@Ëêо¬ƒÑ²8Ú/Kdï¡d½[¨JN*ÒÆ‚è×—×çŒIÑ“©'VPc‡Å›§}z¸ÄRf8@n-!õNä̃2 ýhœ3´¸‡é¨mVŒÅ —iW8œ’¡² ~-!©:n80¥ã~~ÔŸËá3–"ÇSjz/’\%1„ñ$|ÞŽ¨$2·Ã{«òAܵ Söæp=vo8x°¸¹œl«¸o†JêX4ĉhÓ­Àw° Äñ«£ MA$½—!sqŸn«þ•¼ž5Œ}Éñ@6HÇ3µ°UMýÀ'½ ¨Ü°—§h…˜'Ó\]—T‚ÚÓ¨‘N¢Ï]àŠ$iFâ7t™‰µÜJ|J÷L/A<¦à>†«´¹vU^´Kó`ÒŸ1ÄžÒþ¼4D0ižûºä¾öÆ}ÖuŒWEt’*}d# ÇÅõ —èJik» Fp2`ñß7ﱊ¹nzz´“Xʨi”µÀ*•9jEeÕÛ$*ŒºífÓ´ÂĺGnú‰˜úò~÷5_µ— &Fᕨ¦$K·}³Þ—‘\} M™r€, ¾Ù*…¸Ü¾Xõ *¨{¡ÖšŒ?úáNþÚ6ñ3›;<ãüåõö-©9:ŽÕôï*Ð 91”æP¨'`c(5.ÝÎ`ßøÇB ? >—êÿ §”Óendstream endobj 1644 0 obj << /Type /Page /Contents 1645 0 R /Resources 1643 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1613 0 R >> endobj 1642 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (/usr/local/share/db2latex/xsl/figures/warning.pdf) /PTEX.PageNumber 1 /Matrix [1.00000000 0.00000000 0.00000000 1.00000000 0.00000000 0.00000000] /BBox [0.00000000 0.00000000 31.00000000 31.00000000] /Resources << /ProcSet [ /PDF ] >> /Length 557 /Filter [/FlateDecode] >> stream xÚm”In1 EOPw¨u€$ÅIg0²Êľÿ6¤¤êV5 oʯÅésÀóή¯ƒÖ×O²Î Ž¢‘ÿ¨#h8Çùø:„5?ùÆ [ÄIÚL’~”F Ø PÈùYÌÀ¹dˆÐzZ8å±Ýƒ²ÙËò‘–Œ€f¾Å(ÌÀE#@x˜oL Û¹[ƒ±ñðù ä 6\>RgÈbÏWÖ¹j[†› WŒÏ¢®{6;»²þFÃÇñ÷ø]š¨)Õ/Ô¬Mu;pk;Ì©Ëdh<åE–ñ¬AÏw³ð¬±±Nê¦ó¡Ä½t•‹ùD„™Â²]°Ä(‡;„ ·åްЭr²ÂÙÄLûˆ T¥Í¡èª‹ŠŽt’¹w_ =Î]ˆ‹=¦uSä÷—ä"ï±yl±‡µÃ-ËkHsŠöreOÚ³êvg›<7ºt,‡Ýe—;ãÒèЭ/I…B÷&ê(ýê³ö󻉨YÙ¹Ç,çkRÔšÚ'^ m" ^˜h±ÎW9AVªy­Â©/fýÆ"•œãûFy-Sng \Çdª¼˜©Æ¥†Í}B©•µŒÎ$âw1.¶&Øíþ²C¶O–ÃVç X×9g¹E{îÇ< •ãóP)!ÍZÜÅŸLÞª~ÑÔ'¯UâXLµüc“ÅXsЖõÚ¯½˜Ó’~òBL–§èªÆ¹O¦ºNZ_[Èü.øšŠû*]3QôçÇñ!Ö-žendstream endobj 1646 0 obj << /D [1644 0 R /XYZ 85.0394 794.5015 null] >> endobj 350 0 obj << /D [1644 0 R /XYZ 85.0394 343.1554 null] >> endobj 1647 0 obj << /D [1644 0 R /XYZ 85.0394 305.2253 null] >> endobj 1643 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F42 1338 0 R /F49 1358 0 R /F61 1466 0 R /F21 1034 0 R >> /XObject << /Im3 1642 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1650 0 obj << /Length 2108 /Filter /FlateDecode >> stream xÚµXÝsÛ6÷_¡ÉËQ3B| ›'%vZw§ûnú‘>@"es*‘ªHÅU;ýßo»¤H‰Msss£-€åb¿ðÛä$„ŸœD±ˆS•NljDÊh²Ü\„“GXûúB2Ϭešõ¹^?\¼|«“I*ÒXÅ“‡UOV"Â$‘“‡ì§À©ÄD„ÁÕíÓ™ŠÂàc…W?ÜÍßݼ™ßÞNSü@ ·ïçWó×·×4úñýÝõ=ðJ¦±Þ|3ÿîáú-:¿ú÷TJÌïÞ\_ÑÒÕÝ=o¯çSk‚‡}¸¾ŸþüðíÅõCgTßpj´è׋Ÿ~'ØÿíE(tšD“g„B¦©šl.L¤Ed´ngÖ÷ÿìöVý§£Ž”¡P:V#žTr"¥H£H \¥"ÖJ] ÎaoªòcªÇý®(Ùnð/X ²T/*ád¦¬ÐQšz!ó#¯'2׸…«s5ý/;éS™yF³ÏEóD”ãdo#+©`GÜ([ÿ>¢ŒEbcˆaÔÛ|Y`sžpøg9ô0ÞTÙmEº©ø#P CŽŠ!óóÚå¿.ë眓 †¿îa€ZÏ”RAó”ŸÊ´A«H.Å(û<‰±80Ø‚¶múÉ)ÝÚÐÕX‚AÉB\‰;ZÎë8 Ö•Ëržs Íí¦I°/›b“Óüâ@ódL´ÑEšœ«¤ ‘†‰wûuS` e¥H´6Ÿ?V„V&§'£¦}—®¤}¬Ô1ºÆÀ¦*ï."Åj˜Dýš:úÃ8<‚^â„ ÜzM+lªæ˜z€óèÉ$†-öÂ~nŸ[©a°4´l mÑT#2U,¤íN>‘y*Qµ<ÏE«¼w›Wøˆƒî>ÉaÝæ3èjÏ*+fzÊ4(Ó¸‚}Š1´1h>HAÄCï[¢W”@@=‰øõêdy‘× €î“+Ön±ÎÏ¥²ižþ š›ý®lñÙÛ×—¼\B¢CŸTD6•ŒùXS!c›|Au·GµÚ6EUv>TÁ-ªOLvàêUk]ךSmŠâ²]º}=¦¢ÒP9­ýÛ´0ª;pmUë”Êò•ƒãJƒOn½Ïh4TØH;ôÕÍjDŽt‡VŸóT×WDÆœ÷ÒŽç=¨Â®â¢ç ± Ï”FóJ’ßP-ØÃTÌ@ì2D*‘˜ã®Íض‘0:2=£©VøÁ”úh×oŹ ¸ÆÙ˜tô×i;Qv/s@ÙŒƒ£”q OàMY7¹ói#uð{URµ3”‰¡n}3\øL°Ù{¥€òÉLu¾u;@Üõæ{èÚ—f¨†Ò>ÌÙµÀ.5êê¯F ­žyëCµ'‚ê¬9m°†ýã5ÔðVH•ÕnB8Jƒ}í¡@‡2£Xd§µ‡Óóå…nY_bÉ’Á±Ï/ ¹« xß ®rÒ°dÖc烣…[þ2ËËŒTÂð5:Mµsø…LƒjEÿ>C@UÿQ±¯‡ø¿ÅTÂ9F TYÇÞ8Ûõ4¼ûþêý»ù͸i-8‡Øòè3 ýùœ@‚ÏLjúžÅQg•¯U“Ov¦h2 ˆ~5ŠhÜò¶¤xjwÞêÿoCZVƒ~Tõ£þjÁºã,%ß_¼øŒÆ$£9l™{‡g*5ôøRjØ$nRdž:h·Ê¯RНR÷½²ÔÝ‹®¨¿ûÛûå)¦Ç}‘¹r‰Y+8Ûå©ã,„5`rn°0ÅS®R8}L£ Ðq$oÒP¤¶ƒllWvÅâ%xìe[jÇ*‡…®ª+ÜãÔ´£ãv;L„4éÉÒ«X‚s €Àú˜b‰`4[å/ܲÀ ùÏ´çé£Rq!rqI«„š@ÅÕAçn¤ñ­ÐL%¦× $Ö蚨ý––/†´L˜òh[ªÁ¤ªf9ØäÑzÁ"¶®®½M —˜#Ýð®šÊ€‡Ž¿ñ~Ám}<îùžŒRË£„óÛÆÈú«{x|zÛƒ'¸—hm‡·Ì/F'ù_¢‡@”ÅúÅö‘±êzSR˜½¿‘à–Ô@¿p,.&ŠŽm³„4†YÏŸD¼ÐŠþ—4 nä=è ?Ç´ì‡CÞ•Ï‚—âXWîüG²—ïÝx^-Ýouœóïß~ )Ҹꆥãb¹Ì· }qå_Épv¿…ðä5†ÀiÎë½篆(h»+íè½€48 ¤0'c7"#°~ĺèÐÿýû9÷ÿw÷—íRÖ>9QÙmOÐó~Ñ]Vmä¹›Ó{È6ÿm,»#€P3¦'ðŠT—’QHße`®‚¶@…ì”ÇÍÆAkºç‹øþI‡ÅP$I‡¾‘J_Š{"·D›–ô\[‘¨ÐóÄ¿›rÛ ˆo’“Ç“/´‘’äÔÄ‘€ŽÈ“ɹ<ð˜ñkpo×"ò¯Þe5^5ôØ+jØ•÷ÿùÍöø² >ÔI¢ŽÏ±jäa›uBs_ßÜñk3ܘaãÙwPt$(¥Àg6µÏ¾çFý; ¦endstream endobj 1649 0 obj << /Type /Page /Contents 1650 0 R /Resources 1648 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1654 0 R >> endobj 1651 0 obj << /D [1649 0 R /XYZ 56.6929 794.5015 null] >> endobj 354 0 obj << /D [1649 0 R /XYZ 56.6929 769.5949 null] >> endobj 1652 0 obj << /D [1649 0 R /XYZ 56.6929 748.6716 null] >> endobj 358 0 obj << /D [1649 0 R /XYZ 56.6929 352.3173 null] >> endobj 1653 0 obj << /D [1649 0 R /XYZ 56.6929 319.8805 null] >> endobj 1648 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1657 0 obj << /Length 2811 /Filter /FlateDecode >> stream xÚ¥YIwã6¾ûWè0:Ï‚±põaÞsÚvâ¼Äíq«3™Iç@‰Å1E*\¬q~ýT¡Š”ØîÃØ€B¡Pˇ$fþÅ,W‰?‹Ÿ\³ÕöŒÏžaì‡3ayæŽi>äú~qvy§âYÂ’P†³Åz +f<ŽÅl‘ýî}øñúqqût>—÷|v>Bî]ßüz.„ð®>ÜÞÐÐÍÃ'"în¯Ï#ß[|~º…àâ æ e§Þ?þã§ÏŸÎUä-¨ãþ¾ßß?X¡Éù‹ŸÎnýV†ÛÁ¸?Ï~ÿƒÏ2ØõOgœ©$f{hp&’Dζg~ Xà+åzгOgÿèFÍÔ)ó*fA,£ ûI9e¿ a¡’ÊØo±Ñçs$^“nw…¥³:Õ5Ð`¼¡¾UºK—Ž¡ZÓ·>±§Û:ׯyùl'”ëªÞ¦m^•Ä”.«®%²u«ýÙéú¦ ì"×e{8òÒ2³óŠV×=OÞ6$ŸÖœ£éaÿàA–4›ivUÙà >÷Ìêð¥%Uâ-ÓÆìÇÖnÌõ ”Æ@ˆpz"½ŠF3½Ám¶z4¤®uÚv¤êªÃ‚ú¿Î¤(™Ôw;@e3»|[Mm”k`‘±ð@?$¸÷EJ¿©hÍ•ž§YVc@3”pyç=ÁͤJ zŒ¼¿ªR—éV§N?b±ä‘eü;qŒ¢'b‘;†ËÅo ÔƒTÛçí†t3{Ç®ƒ‚Ô6Zš]7ĉ.À~†‰“µàŸKï¡jѤ2޽Mµ×h=ئíi7ikL6aÀbšYÓ,ƒ$L eW•ùfØ€ÂEA£ß•Uûu.5uååªè2mYó’z¯»{¢ãìyøuÜÙè†a+P¢©(hCn«¤S0 ’µ¯º"«Ñ5N…éà0Ù0¤Æ `—OjÃPSm5QXº¦ÁuÚl Ð/¨¥Ù3³äòxwFbõšg&ýp(Ëר·Ö´XÙçØ¯½.ÎÜVŠ]d·òÓºÍW]‘Z…\Pï1Ó;]:(¥ñK1D©Û}U¿PcMJo©µßä«Í;…˜!Óó1cýªK@(®zS­º-ìÐB˜TŠ¢UI+ :n~þ7õl«¬+lçõã=«´¤Ñ¥YW¢’à™ÓD•~È"ˆd›^«ªL]^fÅ_—E.Ÿn¯o~¹HLÌ‘´s-³ `²Üú„ s Ž;MÝVh%v›Š(T#ÍKÄ(逺7:Í ”ý…sYè)èñæ‡RX­`'Çg%œGr†8‹Î¶o–’%qO•s'p>”hŽÁ±­ƒqÉãèà6/sÈX¶™°0È…šÃ¡(Â<6ÀЙF3”˜{Øì eâÁ˜Ôi`ÃfC‰ŽKËuÀÓûF^peQ”y)-müfo3ù !f^äå ͦÐ1‘ E¦=ÀÂg <‚âL†P^¡T, âËŸWWþt»]U·ÔÈËÉÒçÈN VÆ,Œ*-,3€Ù|Ö""¡×ô†RÇ@¬ºÚá qF½q3+€µ!&)¡Ëê ”ÁCf’ä>Á$㊉‘Ôƒ¢ª^º]æ éÞZÆ%)&oê닃5«DsZý”¾ ð)wÃû¶F¯Ïc¯+ËLËãUú Í[Óêí$ÂÝ<–ˆKõ>íOFè°[Æó@ÆÎƒÐŸÐǺíxê¨Jã' ®á¨£#OD.¼§»4¬ H" à$Yv¨­¬²@¥…_\#œ\ábò|4Ž]q9oòLSGÓG64èhÂÈ“‰ :÷©%Ò•w˜­÷S¶Õ«¶KŽ¢¨OèOÐaäý8®gà“ví¦ªs c˜…X_XÖÁ­…]a&8y#7]d¤úd#EM4UfM†!·KB5¤÷±ãŽñ®7/ÐÆ¼ïAÝ œ€P©_s½·­õÑ%ªw™b‘B‹”ÕàV;˜û•2èÂÎÕúøj ¢˜Å3_FPO¦’§ÁúyFÄÓà¬çŸ'œ¾€ÊE |‚ó,wEÕ&޵!f1RæäÎ1}CƒYteëktçÏ5lÊ—,T6€-úZT¤jýÌioÞÜû™Î#j|nçf@=ᩇùtåî³ÄþáQPÊÀy¨k@[á§o*Ðg®›ðM郕]ZCÞš´–•»øÈÆãNúÞ¤TSZ˜³TWù‹ ñÏR5|G^³Ó«“H7SIÔ‡9”Œù0–'cx|9²ZÞÕàcV?dœ½Ú_L\ŸÑ! ‹ã(1jýíãÓýøþò~¨Ÿ¼šlªò3’Àª€Öò9½^cÓÅö‹¸Ê–ñÕ•øJP tøl^V•O¯§Š8ÏË9™G¶pN˜‹,ÐG7ì¢7ÓÀâœ:¼Ím·‰Ì<Á+ï~m%Ї¶ƒóÌqgFJúRáÐ`5æ  ËÃ#xÂV§1‚ÏJU;ò(ZìÂ]÷ÚÍäCkÈT"}[¥\]­áïJ$’‰0fÈSöÅI<ôÝ›jÚ!í`OÓ!•d~€ CBN!„»q>ÐÕáÌx0©ýÁ„ÿ› ñOsaUœ.‘ônnGßÔŽÒ;r;PÚ5‘îË#%"ûž25‹|Ónm;u‹&‡,y#zP¼gFjèý§3aÅ}cx«ÈÔEbÌ*‚ÇÝ©ï}(§EÿÆîên6õŽ¡»±Üé¼Û™à']ÐEØÛïÙn¸+ZkQz-Å7òÈB ²õP2¶Øº*ŠjßûÂ>3£Ã¯¶5.÷DŒš*›Ü­s£ºÿLßÂ(gû„9Á͉ Jb¸ôÉð>2…‹å÷/ž§âðN†{âålü³%Ëà+LK²‘+ÃB0þÞ?¤â¯ð}`[6¨û¸x²Þ Œp¸ 1Œ¡g#°7j›KÄW~wÀ ' Þ#Çÿý›äá÷Z?b*ŽåWŠ-²X&‘SÊ\."0(!‡/‰L€óGÿxSýïš§»úv0Áendstream endobj 1656 0 obj << /Type /Page /Contents 1657 0 R /Resources 1655 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1654 0 R /Annots [ 1660 0 R ] >> endobj 1660 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [377.8384 425.145 428.6673 435.9294] /Subtype /Link /A << /S /GoTo /D (ipv6addresses) >> >> endobj 1658 0 obj << /D [1656 0 R /XYZ 85.0394 794.5015 null] >> endobj 362 0 obj << /D [1656 0 R /XYZ 85.0394 638.8505 null] >> endobj 1659 0 obj << /D [1656 0 R /XYZ 85.0394 603.3017 null] >> endobj 366 0 obj << /D [1656 0 R /XYZ 85.0394 410.9559 null] >> endobj 1661 0 obj << /D [1656 0 R /XYZ 85.0394 382.3762 null] >> endobj 370 0 obj << /D [1656 0 R /XYZ 85.0394 255.2626 null] >> endobj 1662 0 obj << /D [1656 0 R /XYZ 85.0394 226.6828 null] >> endobj 1655 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F42 1338 0 R /F11 1559 0 R /F21 1034 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1666 0 obj << /Length 69 /Filter /FlateDecode >> stream xÚ3T0BCS3=3K#KsK=SCS…ä\.…t œ;—!T‰©±ž©‰±1ƒEV.­knj©g`fA‚!ÂVŒendstream endobj 1665 0 obj << /Type /Page /Contents 1666 0 R /Resources 1664 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1654 0 R >> endobj 1667 0 obj << /D [1665 0 R /XYZ 56.6929 794.5015 null] >> endobj 1664 0 obj << /ProcSet [ /PDF ] >> endobj 1670 0 obj << /Length 1972 /Filter /FlateDecode >> stream xÚXM“Û6¾ûWø¨‰‘Ôç1é¶tÚLÞf{jz %z͉$:¦´îþû HÙ²å4³“@À Ø:?¶.³8Uº.ª4Ζ­ën•¬ŸAöëŠy4q–  ÒM&Ê8+y±Þ\yÿ´zû gkžÄyγõÓnzW^”q%ÒjýÔüý´—‡A6ýèTïÏ–îgU5œÏ‹/"Wêg‡|©ß+*ÂV9lÀpšîLðٵ쉭5Dù:yÑ×¹.&äaMk(%oÜ/õgÁn5ìÍËGëJʽNjM·Õ½<ÄD]ÈÛ ìYÈÓü¸óŠŸ;¯„/àJz¾Uo$¤´'úâ`õ2ûžŽ2(E*"Pgx{(µSÀi½l¯{D7Ej>ιù†˜Ûu倕œD=~Úl¥UnUpo0µi¡Á‘*úÂyz*·~¾[ä\šÀ%´˜@åÚÒo£í ûz ùŽVu$s1E‚\õ–ÁF¿’¡‰ìÆÖW°ÃV$.½‰ï´¦4‰y.Jßš¸oMNY9Ÿ”ySz¤¼þHO‚¼ÂD ¹QD|0ÎC ’«@Ww²V˜’,;¯µ¯vP)u£ `IÍ^skU„² 19»/ŠfŒ4ƒ} ûíé¨l³°MQL*îÕŒwVÒ•-fk“B²ÊJó¬Ýô,jk¦ÿ’$üy$=¾Q3¦DÜúËD3˜™.ý]p—±( ¯d8.ˆˆ„h–Ã4•2q…lxÆE5j'¡¸îR^ ('H*F‘ÍóŠ’+`c>œ´+^XÙɯŠxp:/× `KJÚÏïËCC³Æ6Ke+ë¯yÕeS#Æ—fIˆP ± 1Ìq ªâ,&lq³Û¢1ôŒVÞ lù¨›FþëRÙ%EÌKqN£¯‹ÛL¦,æEšEÝ+ÿbíË9•©ˆy–¦^û­ê·G—ŸzQBy2.求BÜ-‘ˆ+–cÞB`Îj‡FÛ¼<Ã?Ð0R¨úGSd™>P8šX"µ×‚´7DmÇáŽÎnÆiF@¯ØIÿ>î®C;ÒZãú«c¸A )i¢™Âfó,›…Óó ™Å{Öâi¬â²,*oÆO;?|ö˜ ÁõŠ7Á]¸ ûOÜâqYäÞBzpÐ~†ÀY¯t¸?œ' º7”3䊅)…îÉt˜úãÁø›Ày~™é«ÉeØ«åÙd“±8Móüû#J1ë{È‘>étE饈 ŽyÝ}Çܤ‹Þ«ZRíà ` ½RõF ý†ÆÃÝý‚xJºr +XRN6´7Ð(«Ÿ{Bœ¹»cØ·Q‡ÂïÚ*óÍ'‰:ÝëÇ%dž{‰ÃjØ L@Ñ_}ë€ Õo»3†:iKí6qÞ"Bà×ù®ÒBJ¿—·0ÛLÖ–ZìÕD†fî¢]–CßÊŠ9Ú‰’ßA»zm.Ðî¢UÔ¦ÒÛ†Éý䯰+¼Ã±” Ç½ÙkÑ T-Ò];MÝ|ÌÆÐí®ôã,W>5ߊÇ¿.j9¦7ÜÜ@b"vþºkú¥;‘=¨Zc>UsuO)¿°èHÔ¸@ƒ"‹,Œ,ræD­Nß]+°$ô8ŸÉªëë‹óP*š6~³š¤FžMXí¯è e•ãW4žýÐLÊ®‡Òéš~›$@ƒ"ŸÎ÷w«#«â¢ÈÊËYeõóÓô-1|!YŒß¾6Â?¿w~[ýýO²n@é·U‹ªÌÖ'x€q±‚;@·:¸$N»ú¼úßùÃexÛ&Å-—üüÙrvÊ€/èÁ)t\àWp‚_~„Œø°ù”^ojú>z»«ÿÚd±íendstream endobj 1669 0 obj << /Type /Page /Contents 1670 0 R /Resources 1668 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1654 0 R >> endobj 1671 0 obj << /D [1669 0 R /XYZ 85.0394 794.5015 null] >> endobj 374 0 obj << /D [1669 0 R /XYZ 85.0394 769.5949 null] >> endobj 1672 0 obj << /D [1669 0 R /XYZ 85.0394 576.7004 null] >> endobj 378 0 obj << /D [1669 0 R /XYZ 85.0394 576.7004 null] >> endobj 1673 0 obj << /D [1669 0 R /XYZ 85.0394 544.8207 null] >> endobj 382 0 obj << /D [1669 0 R /XYZ 85.0394 403.9445 null] >> endobj 1674 0 obj << /D [1669 0 R /XYZ 85.0394 368.2811 null] >> endobj 1668 0 obj << /Font << /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1677 0 obj << /Length 69 /Filter /FlateDecode >> stream xÚ3T0BCS3=3K#KsK=SCS…ä\.…t œ;—!T‰©±ž©‰±1ƒEV.­knj©g`fA‚!ÂVŒendstream endobj 1676 0 obj << /Type /Page /Contents 1677 0 R /Resources 1675 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1654 0 R >> endobj 1678 0 obj << /D [1676 0 R /XYZ 56.6929 794.5015 null] >> endobj 1675 0 obj << /ProcSet [ /PDF ] >> endobj 1681 0 obj << /Length 3224 /Filter /FlateDecode >> stream xÚÍË’ã¶ñ>_¡‹+šª%Œ7ÁÍiýØÄ>8޽7ÛUáHœk%R©O¾>Ýh€"%HÚd䪔Áf£»ÑO3?1s†qUèY^hf¸0³ÅæŽÏžàÝßîD€ÑF1£•‚‡ÄÛÌ(ÇŒ“ù,#ùêÃݗ菱Iά•föáq˜ËæŽJ³Ë_æ_¯Êm_íî3iøÜÞÿöá{úL³Üå?ã0…ayÁÿà«ï~ø†  j¾n›_9—Oû]Ù×mCƒ?UÕ®jUÀ(g+¬´¡ªr#Ç•õ¡YLÞ‹yCãuGíÃî^¸y[.×/4ÐÕ›z]îè¡o±5#´î¯Ðj1_µÏÕ'`5×ó7øÆÍûUåqUXN¨y¬ž _Cª Ô´)ª›7È8²*+L`µÛ/VíÌÜ í§ºzîØ}¦…èÃfŒ„ôˆy’1¼Æwë* êVí~½¤þs»ûzu¿"`âg^Ãr{×uCíaúÅSh¬Oæ âI0¶h7ÛuõZ~, œÆŠñPQKQÕ’ üê!ŽUµøHÝú1¼ZU/áeÙŒñˆi~´zÄ$aQWM¿_ÕHââ\û®nž¦ÜÏ ÌDZLkǪì÷4GFÚ}³¤nt~dl@›ƒ©É©åȹÆFEAÁšŽG`‰Yèxfq m@‹‰ öƒá@´ŒDK q·){‚"^§€ÝªZ¯Cw±«·=ÙªÛª²s&GgCëÜô»úá˦ÜTËÌ3™ >´mÐ4>²n•ðŒ¹ ³°Á Í”¶a²(ÓœI«H¨– 0 ÎÏø¡÷õ:¬å·´ø]Ú!I©Påûv½nŸƒ¼8¹hKjÖu×SÏ[>´UÄìŸö]ô¢_‘£ j÷}«Ž•e‘¢›T€úËv±Ç üë·HÿÝ·ÿ_Xz®gZHfy!Ñùÿ~÷Ëo|¶„Xñýgªpfö œ‰6wZ,繊#뻟ïþù?~é@!*V®ÎS@ßqÀºñ‹)ª,ò”)ëR¸bˆhå„/™RÊÌ4×Ljžûå+ëc )˜³ª8~†$+œsif³c6F™ ©3à&$¢M¤ÌÅÌàêŠâûªœ ‹MÂVsÉœÓ.|].—»ªëŽE¡¬fÕåV’ˆ¯BÙœ {,ðO‹Õ ‰Eάv·¤1b¼B¤æ—(Ðð ‘ÞâOWK‚’¼ˆâîh…–šnƒ>^hÁÐî£S­t•‹n/(îÑ4àË…G©¸ïvرø &!ç›çuöˆ–¯8ˆ÷Ï0q‹©¦³WL\9˜CquI·…†<5×êüj3³1Ê™ÖÈ*1%3©Ý]j˜ñvDFŒ×ˆt’I•Û)‘g´ÛZf©æ»{¨\ˆ}ØCGäÛ¦ µã,ñx~Ð_éxÌ%êí‰áƒ³NÜpýŒWD£rñŸ‹S5K¾×hØx“àÔ1wÈfNùÔP”†ÛÛñ9`¼Â§FÚ±œð¹ÝUõ N• 7Ä£³œªðôcV¸}ÅéíX¯±ZÀ÷ZyŽz™Š»Á¯F63 õ^»K°‹¹4Úšž:ãDÊ!!Þ©ÍÜ:èùjÆŒÙå)ã2ÔÍ<‚]H9 VèÁ"c"û†òήªN,ÔäLbГ@/wO3êü4Ú›àOi>R´c¼HÏÏÕâC¢©þ±zÁ*‘‹ =';$Ô*N± ÕH:ÀŽB×­l4¹ÏG¿8`¡¶)$Ħ+Ö€*È·º¾Ú]¯zÃà: ¼Zž‰YP2îC† œyÍÇlLé¿pÐ'ÒØbüò\Š_J@…eÏûuU(Æ9ÈüFð]* $¢Vt.r•©hí´7äyߢ™•ëÏV1ãlqÞÁn D×öV<ø.òl¸C­Õcž“®\GÁ´3GÙsÙ,¿L:xå˜`Ñç–XD¼ܺÖLCMñz·1fc”‰eæPÞq mó¡»ÝõWSv¶ÅÈ»ÃV1Ï;cù h49:‰[q=`¼Âµ®•zÊõû^¸áràj/+ì¼nëý²Â‡|Þú=ßDdNŸAo4V”3‘¦²HF}¼Èo c6F™ˆîT¦¹;Lå‘ÚØ‚¨â\^Œ·ÕÒl"^uŽ+E}ËJ\2¿È 6FÏó²Ý”usÉTÁòÂæØWDzˆ1£LE3 )ƒ9¢òÜ~·ŒãžÉϤ¶óß÷÷ÔØï2Âc×ïh«R›ùóªö 0ü\û½]ôûÆ06&u8|ÐtÄÍ7?üLãHÆ{Äxˆêr“¥¶ü·q{òW)u $¤k°bÑ_X_u=;¬Ç¯`}ÖÙ›çu)­ò®ÈÚ磌_œSW‰ÑÛäæŠºJøÀj-E8—Ü@¶d„+Cr7Úg4¾õ.d4„”|(òÓ¶%H}}Q0fc”‰ˆç@…r!NEô¹…Ìy ‹c_¿Þ¦Ç“¶€6—×TÈi0ž",b®áœÃ‹ ·ów#ŒÜÝ„ÄjQoÊõu‡÷ŸœCÐÆ3.%Ð+íw4R7}õ„Ù*×{ŸãÃ>9¾Œ4†ÞtÕ¶Ü•=ÁÛ°C›£àº”ŸûRб¿@#b]L§¸x$Ô%6u hgbÐR%™ZÓ• À}+и;•Rz€â6f«1¡àxNab&è@Ÿ@éÎá3TY]ÏÆzùÿ»³ ! Ê{íðHZe($Ö”ñ볇GàíÆ(/MH¸·oa*:C’5wâP…£ù»E»Å(„T•ñ6…p¤yó$ „â­m0¼áÍì­ÊOöܼÜ<ÔOûº¡¸qJ U½£®Ÿ‘€ÿy¢˜wô´ÙwÝC•º³¬;ÂNqS î㦢©Ýn)ânwu‰÷”*÷ùÞwßЗätt8õ¯¶tk~&y½h{ᯩi¡($áC2 `Aƒí’çMÝÓ/”7çóïzzW¨—<™ÍÓú…FH¶‹vnnIìùk5 B †‚lACÕ¥Às‡8йiGƒaàFƒ†Åjh´Ùoª]½ áz ìÖx\ ‰ h Ò…¿K„€”³gɵð·õ\¸é­/ð %¾üRâsùé<=€²½t}µ9¾Woœà ùTÑ]47ÿ{ûœ¬úFè ³Æ+~P™óñ]:|¬;j›–Ú®/›%][ÒÈ4†dÈ9Õ›Λ ÿ2“ãu‡eŠ˜± Ð'‚^–BÎûQ:ö<}@îËHýx²Ž`×uó1ÀÂ<É¥V/Ü—n¡ šý7çª%RÃÑ£tû Uê *“õmFÅ@ÂÀ—Uÿ\UM’åH¶Ÿ’$ã;H­_Lîž…ºBUSÆëŒM5\`k©}ˆÑÆQà|64Ê2^™¸ü™Û3y„¾¶;ãKBœ9 Â0Ð0=€½:гÆyÒX<Ÿ“w6 ‚~>œú¼K¥ïÂâÍð|8õЧ©»Âss3F„—…ÀÄ4^9ü F';@ÉÃi-œÈl•VLr-oÆæ€ð2›J[øüó¸ uõ}¤Þ¯ÜßÒ‚IiZ#Ó*ý>»j £{¤Ãÿ’2‹SÈtΔsçn p¨$è¬ס¨Ðxˆ“«ØhÈ~> endobj 1687 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [356.2946 363.7923 412.5133 376.6291] /Subtype /Link /A << /S /GoTo /D (address_match_lists) >> >> endobj 1682 0 obj << /D [1680 0 R /XYZ 85.0394 794.5015 null] >> endobj 386 0 obj << /D [1680 0 R /XYZ 85.0394 769.5949 null] >> endobj 1683 0 obj << /D [1680 0 R /XYZ 85.0394 576.7004 null] >> endobj 390 0 obj << /D [1680 0 R /XYZ 85.0394 479.565 null] >> endobj 1684 0 obj << /D [1680 0 R /XYZ 85.0394 441.8891 null] >> endobj 1685 0 obj << /D [1680 0 R /XYZ 85.0394 424.9629 null] >> endobj 1686 0 obj << /D [1680 0 R /XYZ 85.0394 413.0077 null] >> endobj 1679 0 obj << /Font << /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1691 0 obj << /Length 4423 /Filter /FlateDecode >> stream xÚÍ<]sã6’ïþ~;95ÂàÄíÞC6ëÉÍÞî$—øj6[u´DÛ¼‘D­HÇùõ×(R‚$g­«ºšJP£Ñèï-®9üׯ2륿v^3Ã…¹ž-¯øõ#Œ}%âœiš4ÎúÃÝÕûª¸öÌ[i¯ï° Æ‹B\ßÍÿ6±L°€À'ßýðéÃÇïÿë§ooœžÜ}üáÓÍT>ùðñÏ·Ôºýóí_n?Ýý o\ùÉwÿþíw·?ј@þðñÓ©ÇÓãÔŸn?Üþtûé»Û›¿ßýéêö®ßÌpÂ+ÜÉ?®þöw~=‡}ÿéŠ3å sý /œ ïåõòJÅŒV*õ,®~¾úÏà`4ü4G@­³Ò¨ë©•LY+/KKpX66•a…5foÕ©-˜ÏDI&”Qý™h98§™/ܵ3žY%U8’z½O”Â1£¼ßM{U$.Š=æõÃ(&°(<ªUW—ü Œk‰)àè‘aí¶Ú|©gU ,«õdÖÌ+l™Éº©Wuþ ÿãÏßýOA=_ÊÅ6Î{h6ÔèQã¹îžh¬Ùvæ‘ú»Mpû…s9 ñ1*ÍŠä¦YW›²£ßÁkûÒvÕ²¥—î©ìb÷v½n6ñѻә°}¶ÒÞ1/<œ/ñ¨~;ÛkàÊ(꙾ù éÅQI²„ÓxsZ’¤bÎÚâœ$¥i—“¤Ä’4D/œÑyI£çÅäãøtƒ_VÐŽ9UسÂϦ֖ÞN D ¸Ðg)åã´º%dõ²Fá £Lb'¯OA›íãõ>ʼ#AÚ0 Œ¸?Šp$]-µï«EóŒÍb"¸ÔÔÙ½¬ëY¹X¼Ð+‰zÛmê¡#":н½“ ˜Ð¾óׄ} Ëdqs?\­‚*n'e‹OC 5MÕkEÃm³¬h¬ˆ ®”ä ÀÒ»jS·Ÿiê’ÿþæ_H•àðì©Ü”€÷&¾ÂÏF‰¨!aظ¤¡p26è=x]/ÊYõÔ,æ!à³×‘»¹Э͒ÚOõãÓ4ž;Rqž£rãqÅ2Ù·ibñ†Y-Ôo™~qL±g™…<©X¬UÌ{˜~Z±ôÓ.¦X†+–zëMõP}jQŠÕ¢ÀB¬ÀØ6›ÏÔÙ®«Y)°Œ¶R{3¶]¬Ð:)–C)'Xû¼…zˆgH¤à ôwG4*çóœ:ýìÑï¤m ¼‚ }h‹´Ås ÕE Q¦]”íSÔ_®` RíXJ‚h¿¢­‘–èÂh…Fì‚5¢È…áæúî뮥V½ê§Wݲl?ƒâ)t1¹»ñ¤¸^ †Êh‹_I˜OsÊ©êb(ó@JjIoåê%Æ5ˆîqochÇßæì¼ ²¿%2J䨷a€û¹+Nz¦+íI±}®^ö÷ì3™ݼ·ªÞp:„˜q7@¹¡2áWϳ®Û>ÒÈæ8ÓN&~gY¯Œ H»ÜN{ˆg¶* '­ïuU.«¼Ò·J&%Db¥¡ÅLCZ§¢¨@#À–&^R–-8ýÑÝïxøBtE¤ó¼@÷}4'ÀòƸ½Ä…AB “àÙ·LÔ)“ÐV³í¦îø ™pëÛ`_¦Ô%eJ‚÷éÝéÔ€«¢•—ge*Í»œL ž©!~‹ºí^#Uà†jšZÈLJ™I³ªbdžžË†¸*#†xÔ\%3—!ŒR¬¿ñ—£Lñ iú`SÇ´Éë›Èÿ´‹i\¾†º#¿]G¿»—õ¬Y4«–ú£GR¤SÀíc³´š÷·ßP&9Š NÈЀ;/%C)s¹DµvE¿ô¤ÉnúÓ)!Ìá¡ý€IѽkVÓUõXvõäMË'JN!®¡ÑzÕU!A.Õ¬bxˆ…£ÜÄ..»´0 pêK‡¸çãÍ@y;é ‚Ó–š-¶-`áÖ-”Ÿ|DÏCIXk6«Ö]y¿@¥Mé\ZÖOõ>l7 É7Ô_å|™]ÌP¼H)ÚŠ³öû5fh먒ŸŸêYd®: E‡5úqÝ¥Ò·—×ÑÚBø$…;É`ºÏß‚7Òe÷t ¤!Êð@â~⛕t8B<ÄOpÉt!ÐÃ#Þ€ã¢ð¿-&ÿØ6¤‡  ÉA´.:v“·Œ­ÔƒgLêA+d_ðI¤ ®Ž<íݤÝ&e›Qñ{"ñ+˜‡öý2¤ß/_XWµÛù_û»± ½vø&φƒ¾”ž#]_0Û§œ‚“ä§ rÚr挣<}–ÓÄËñáâ)>bxÌ[ØçCPNÑY0†’KØ“MèaðË{{šÉþ½Üþ#¼3Û—¾`FìFü€DÊÄ 'vK*!À3~„¨r ¬«ˆH¼4JͺNw˜êØ ¥‡éR¬I†D<)Q ðÅ—ÔÂÁýè°$G;ùa´n&ƒ#“m ™Éç´$š™°äs“9Qç™,„?z¢Ú@œ#!|Öº`λ·gh{ˆÓ!ÈÃSÕ¨a@oô³Nj È{?ïp£âi椱‡¥Š.W…sâi¡¥{;'ˆÓ!È 'cz5¨š4-róœÛ3p†îót}úm 3p1Sš3·W%@Â$X®‹íµ‡xf¯ ô°¥Ñ^±¾tö€±ÀoT2’ZÈÃàã ¹$²8ƒÅ$¬X@ò=—¾O0e ®‘tæ!13P(„”XYpÈI$ˆÓ!È\NBrVîV>É4Úð¤À‡E×LªŸãe{Šy@߆"ÊÅöÜC<³geaÏÎúñžO2Ï |c‚&Ž?ËlT”“'åF;Á¸äör[ï!žÙºot‰~Íqcš,¶ÛSzË-Z{­A*šØ@ßRk5YP¢)D]šR»ÙÊžeêú 9YæÀ¢m`°aó`ofŽq:™c,a s¤i¯Ö,X0ƒà2T~pûãÊÏÈ4;ƒ·Âü¾eFe/PZiN·,çt³!W)PàŒJ{,]ˆ®~a©cs—Ç7Z[£»ØV„­9a1g°¤ÕÌ^R£¦VzŸRùÞÇ› |p3{G7Âv7ð5D©Þ‹0É+!X±“Q×óó1JÆãׇƒów­œcÏãÍj7AœAfÔ.˜-¶k·òYE–†qÈŪ`…ÿMQ{üűhI€~”…;-) @„ ³ÞÖ¿VÇ¢¥~âÅ¢¥!ÄÑÒCpÕ_-i%'VSŽ ÛÛU[?®‚³ o)cåtpRœ ŽÇÏÕË3å]çmF­H¬bU ¬·«”3:Ä NAìpk6hàõ‚›ˆI‘Í«‡r»È1*è®B«qµ’úÄXU|¤‚ +4U ¡Ú§ü\ÅÎt1+¼Ä⨕‡ švuÚßgrÌé"Qã߆€3ð`³ÚKùzp¤°4ÈÜX_Z[§5wÊqÜ5ì ŽÔ[,Û“j-à gզà ¼øÉú"ÉM¹¬º@ìB-ò0™$dÊÊŒ+æ`°­—ýÍ„¯Óÿi¶›U¹˜&Úß‘;ÔßÞ‰·ITA'‚pÑeHYÿðÖ§$ñ%ƵØÄœvmE…~©Æ €Á…+ÙÈeÕbÌÌ}°3alÙ„Ì‚ýe7ãŠI[uTÿÂ’1«ŠM,há“ÓcÞäïÝÓJ6§ ~˜øZVÁdÁ@ºÙò;F2¨ØZšû‹”z»š‡ú4ˆ1¾ÒœP$'ö”qò}ýHe›¿÷Ö¶õý¢ÂŸ`N ´uª@`®ìâ³NA…€í˜öŤ37“Ÿ«ÐS8^}]/ÊU‰Uº6ByÈ%—×妫g[ôàBUp=`ÅP%¤*=´#r·µ€“¤ë£èŒÊVÄä`£®¥]ëø|ºq:™ñé ÈY±[ù„ÒÆÂ«ïoÛP¹¶=¯@T‘¡ä Ï'rœ”xkNè=5§ð’ò@Êè¥D|·ËijC|Ú.Ácšá5R;º¦Š×6Cg³ÆsÝÝM - —à ½/Ô[Òk;w 8(ÔŸàýÜ®fó¯ý¿Ç"ÿ‘!–gÂõyܬ/Ú¸Þ1ý|†ÑCz+)&ŸëEsÿÒUmÎ}¶`Td5ð/@ly 1³Ø²z,#b ¤~<B­'¹H| _ácÝßzRÌùý¼âý>¢€A3*j†²&<1.eh~Ó¿§o&âœoúÿå¯8‡8ä Ku‹Á c»8ï¿X0þ>9Õ*épiURÑØLÛAc#uìé\im Çê8gÛn#9Ó’c;L‹Kq÷Ueü¹LcM¬í–Ušß&Më¾_ªMéãèxŸŒÊ”à²óQÎ ï •`ý~ÛÒg(~‡w vê+û-Äi©¦ø@À¬¢îçxï,íºð+—Èáp4vÓ´úè€ÛÌΩ:ä0Xx[üñy œP¦Ü±X/†4BCø¬aã/ä“ä.‹ôó.vYdñøe‘~¤†èÁF!²…U.†_ñ ‚¡Œ!õÁU“‹·xÁ´Q)¨¹¥„Ä¡bUœi+“îˆg±ï‘Ïiý ±¾wý2ÍÙ;$x5¸á㘩q>ʉ“¢7qÝf[¹‰¬”:HãcBf Ÿ°|(í‘"ðr¢\™œ|Ä~?+gɰP) ?V=xÏ¡š¿‹J-z7=¨‘Š$ÔŠVž¼¿$.2¸Â!Û>{˜ß4QÆ%Âä®Öæ]v'Ð@´ÿÿÞ´Á¦ú´þÇ–ó‚|ßy þäA>Là÷”˜áïç¾YÆÄédNÆÃm¬1’äÞfåfY™¸õ¼šfÊWA±a?)ì?Lèáå4È«FMŸ]Ä ÿQäRv¨×/žÓ]vcÓg¸ØªcOI¼pò.ë3xÇV]Ž:à̃BØóiÒi¼§weÑÍ`¢}Ïw'È„*Å›}팟:|È}ÿyd»(¿TÔEn-öuÛ{j…;;Ç5ß@§\ê Øîƒù³_àÃow{_àÿs¿ê³ýào3QJBX$üðËýƒ/ø%8Îcb/|æQä>óç½Ð¿ù ìþä‚vLƒO÷£ž0 H  Xxú£1¤äD˃?†3¤²2lêrè`_endstream endobj 1690 0 obj << /Type /Page /Contents 1691 0 R /Resources 1689 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1693 0 R >> endobj 1692 0 obj << /D [1690 0 R /XYZ 56.6929 794.5015 null] >> endobj 1689 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F22 1037 0 R /F21 1034 0 R /F49 1358 0 R /F11 1559 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1696 0 obj << /Length 3070 /Filter /FlateDecode >> stream xÚ¥ZÝsÛ8Ï_á>Õ¹YQ¤$ê:÷Ðt7;ýº6{h;]ÅfbMdɕ䤙»ûß HJ²e{»7~‚‚à”ù$€Ÿ¨ˆ"•“$•, x4™¯N‚É ôýzÂ-ÏÌ1Íú\Ï/Ož¼j’²4ãÉåuO–bR|r¹ø<}ñÛ³÷—çNgaLcv:‹â`úüâíK¢¤ôxñîí«‹_?}xvšÈéåÅ»·DþpþêüÃùÛçð ¢a<·ö xuñúœZç¯Ïßœ¿½üxúõò÷“óKoLß`´äûÉç¯Ádvÿ~0‘ªhr/ãiNV'2,’B8JqòñäŸ^`¯× s`$‹T˜Œx0äÎYEáÀ…QÊb ãB´šŸÎxÓg‹E­›†l|“µó%5_çMÛ ­Fb·&ÁdÆ,H’ž(/ìãCÙf?h” ÷ÊHé·êûV€ªÓY ãÿAÝîoºÐ+]Z¶§¨Á[9óæ‚äÏÇ$<%Æ5¾Y³-a|Ï4‡ó°Óµ:9æñ%ˆ‚|ý-sî5ŒO ]Þ´KËò2#a©ÕÐŒ[ý@<Ðø–/?Ù6/¾•ÙJˆÿÞg7Ñÿë'ÅGÖtæç G©ê-mh—ö¥þa™·yUR„d傟šìF[±#픫)E["¦+mÐ,L´A3œfÄDôu¯²:/èuÓèµÚŠž Ýêz•—ڞϽøyU¶FVUẪ©q"«Õ×èúNÛŽj­ë -l :D’N/—°¸JÁp}z“¥ESQksʧvŠá4/éÙ.õˆÏ•‚½Ã&7òÐ~]ÎÀµ»n”‚i”XNôú®4ž²(‘Üò4UÝšµß&$ …rš6kM<“½ÚK“¶qn}t¿Ìi¥8zµióvÓ:ã­•ÙpuC»º´¹ ñ@ªáî¢èÄšg6¤®´ ­jT×ôl—¶çº*Šê>/oþ¾/GQÄÂH©ÃOŸË¤M.{^J¡©DOÎ÷KÀ“m¥` ’Éa­žkWí`qxmÕ:ß\¼·¾8:¢LsñþNZÕŽý.vÛ}ÔM"fÍÇÜÔã:à&ÇuÜM‡´öÜ´­vÜM}µÛnZ““0iýèü”[®?ž<¦FYµfÃt¤G%ãc®êqp•ã:îªCZ{®ÚV;ڌL7gŒqÙË3Z6¢”ëµÍïWÝ&I={¤ä.÷ÜRÂÜžG 9L‰í´³ÏãÜÅepÄã}®ý÷\G=~Pkçñµ£¨õé‹Îí~fsq»³­Wë2åÖÊÜçíòÐÚ„¡d*‘‘;;æÅØÚ@²á°‹þìÚ¨€I!­MëÀÚ8®ãksHkom¶ÕޝM_­Ý ¥†xñ3k¡ËyQ5nŒË,Wu„Î=ð~Ä1€, b£î¼;X…°'4ÌÉ'B˜ÆMFó¢]^heô(t¶€³^ôy‘­2 Èž¸õ-uaªûãÑcLj¸µElÁtQ(Š} ál‚ÆgCÒ¾@ðÀ9Œ##1”²*5‘FPvÕ<+–UÓÚ2´ÊEÊ;†R· ¾Ù£)|±‰ÛG: “fö¦ê˜ÐÛæœí8Ê=[PmY[°iÜŒ+Ûw]mÜœr?Rm"”²ÐͼÎ×ìÝ$¸«LÃoæuëNÈ*Š1¸<ˆŽ­´ÈI‹]Vާ°¸›ÆWÙBoñ¹LâDÄЕ7Ôj° ›·ùœÆøšÅôU+ œ&ˆzƒ3b]åM 5ÁæPPÓ&/çzlµ=ßÔyk¡9ÌÛ?ic:±1ÝCíÒ£ö»¬ÈAH9íòÕ¦¥Zñ -=0Ò¨Ã{­ûÊlív2srŸ¾…? t4ŒýÊbia±n†#YâÙ䂯D^ØØØøDÑ.©(ÙÜXCû±´¨æ\+Ùcaô¯¥Fï*r1>³Û¯‡Á\ȘÄt¶U`Ã|h¢×> Rü= Ë&ÜÛ÷Æ ó…ùco>¦Lm!‚tm#£uIºŒÑXÛ჻åFÊB¯u¹hˆîØï—ÚÌÔ['ßúHyC”+mìGm $šâI. ±WÂãQ„¡€Ñ»©~ ,ªCFÊž5ÌÍÙ°€rz6¢(RLHpäñr›³Hp‡{·×Õ;lzéX&·À€ÙŠZ„,‰5– »lYHY˜Ù˵@^Ámâî<€ã~ÖA< \ΑX‰;ñ^¬tæE^Æžñ ]æÚŸeŠI›C‘‚•L»½@¯nß”½ùgÔö“êñ¥ˆ)Dº39°gíØug(9 bé4š<ƒš1¿«r¢*¡$ñ«½+aEi5£M>¥ gp`ÅÇÊqäRØH j?¹u·9ª %è‹qÛ$}ß7ºõF›$äÇ„©]aã[6 X¨"õWäͳùrì†R Eñ_–8>ÏT1(þÒŸ“ §HÙ\ChïÊ‹%ãJýä,ié%T I£á®Ú¬ öÏVò`¸EL‰áê“°¤ïû¬^tyyVxÿ—tqÇs¼ç&3ŒÐç½+À ·Ëª›­LXšÆi7LéÔ€fbW°Ç_Ð4÷Íx<ý˜¯ò"«bpÎÝäöÜu¨˜%©ø3·¶3Éã¸Û¾¯\%õÔ=¡ChÍ-Ô‡¦­Ïâî^‰=- ðÌ‹”Cáʼn¥ËS$\o‰\e=ôc; ç 'Ã]ôBsauB¶£†/“}µúc k¼#OÐ ±°"lthCYx@ÁqSæxÊC!ÑâWÀ”vȪ«a ¶ÒŠ,55üáI è鸞½x=TåÊÀ„\l48“ìIaxã^aÕA H©NbšfochqéH×öÃêʰR8ˆÀBK 8Í@2Ó B «n-6[¬rW6heÐßQJ²8öI§R‚ž2!€B|¹Ó¼´ŠÈ{@Yô>ÁúÈ8š>×6„ÍÔ®íÁHAº]]ï éf2s.Ò•^fwyåQ¼E.ØÕ­,¼X£…ð7bVfFfsÕhËk » ’ žnKËK'USÃbVEZ± 6”£aÕÇ剻bA Kè*[¸ïKV+∦ay[øØì[¬…=<Ä2¹kÛ’Í”ºšà|U9ÖÙj]h£%µõÕV"‰`©ò–³‰'¡|Š%™Ä/™(ÐPOÇÒ›—0R:óÐ¥·Òr*ˆUY¡©¶ÃwˆëŽ5‚ˉœwR³â¦ªÁ+zµ ”‡>7!I0ª¨ªÛÍšˆôéog^&¯òp7Ÿ…· “O- «Ütú©¯Axñä¯\wçÊYªNðÊI˜J…ìmÖ&9óÄ}Ábkã+˜u™+zxâî1µ%´û¦*8I«ù­Aá=vëØ„" ¶ó™û`'™RIºçîº"s·UW¾¶¿Ñ Þʸ‚Ö3÷.>˜w\ï¯ ‹Ó$ôŸŸÝÇçÕª+‰ú28ô½Ù~Ë”îÏ!°aR{CåÅÁKCâèRÉ•4@÷_‹-wÓ¿’xA¡3Ë!wß+K—Ÿ°'j«›5]w˜ÞÛäÎ÷7Óq⦭9~§ ›Mín}ceB¤ÀKóéåiŠÇé0 if O87u6Õ M¾Á…å¾Í¡¶?£ï½íÒ\Q@7ÝëA·¹n€ç=lÅV[bn§C!„göùË/g”—ªzôq©‹âÉZ×þõÍÙóõAD ÿ3ò ð±ôÿ§÷#L…ãŸlu¦‰›Z#a»ê Ãþ_’ü21{/·òÿâÙµêeåVendstream endobj 1695 0 obj << /Type /Page /Contents 1696 0 R /Resources 1694 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1693 0 R >> endobj 1697 0 obj << /D [1695 0 R /XYZ 85.0394 794.5015 null] >> endobj 394 0 obj << /D [1695 0 R /XYZ 85.0394 769.5949 null] >> endobj 1688 0 obj << /D [1695 0 R /XYZ 85.0394 752.0459 null] >> endobj 398 0 obj << /D [1695 0 R /XYZ 85.0394 752.0459 null] >> endobj 1698 0 obj << /D [1695 0 R /XYZ 85.0394 723.5337 null] >> endobj 402 0 obj << /D [1695 0 R /XYZ 85.0394 642.6584 null] >> endobj 1699 0 obj << /D [1695 0 R /XYZ 85.0394 613.9312 null] >> endobj 406 0 obj << /D [1695 0 R /XYZ 85.0394 133.1977 null] >> endobj 1700 0 obj << /D [1695 0 R /XYZ 85.0394 104.7573 null] >> endobj 1694 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F42 1338 0 R /F22 1037 0 R /F14 1060 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1703 0 obj << /Length 2000 /Filter /FlateDecode >> stream xÚÅ]sã6î=¿B3ûPy3$Eê£}Êf“\:·i›ÍεÓvæ‡kN–\KÞlî×@í(¹mÓ¹ÏX ˆ"âð‘NYZÈ"Ê Å4:Z¬xtkçÂáÌ=Ò<Äzs}pt–äQÁŠT¦ÑõÇ€VÎxž‹èúö—8e’Í€O¾¿<»8ÿpu<ËT|}ñýål.5Ï.þ~JÐùÕñ»wÇW³¹ÈµˆOþvüÃõé-¥ŽÆ›‹Ë·4SÐç ¢W§g§W§—'§³ß®¿;8½d åžD*²t¿1‹rÛ™)c€“‚âžÅ¥W4@ÆumzS»Å[SW+Ðø- Ý)xŠû;¿g!Aø™ˆò‹²!àÆ¡Ãµ¾˜’•ã m<ï’>ëvCweW?úµ ™êªqVÑ:C@øƒq—½ÚÖ}µ®îèž¿y¹só2(QÓö´rã0€ (‰áá’øÌ²‡Yó¹DuâH“qàôǶ®Ûûª¹£aåèD?•uuëéÓ Z„œ¥Üc<ß”NÀ€œ«ÑÝ‘7™Ñò7ó¬×GßLÇöP-El·ìm¨"Bï5ˆ€N 6%Ñc‚]_Õµ‹i(Üvhá~‡ô„tê)éÔS™«ñQzÑn6fáƒwß›ÕzЭƚÁS¢'\±\§ùÄa”æÝy?O”ò¢‰'Ú´ô­Ûæ‚íNjˆ l##ιCÜÒ°\Xo»ŽÆcèÂ2ÞåÑ} pª(¬ÂܲüäpÛÆu{7îÃ. l„œð¶‰xyH°)ËqÖGWM(h…ÁÆ^‰F­lÎÂ`)¸ –H‚å—¡'Ÿg$´Ì…´4Œ÷ÅÏnƒgBžíÞk­1÷;”id>™ÆªÝÞ-ÝÞ~—†»HyÏ0|&¨­7æSÕn»ÇÞ:ñ C—Ë Kú=¾C¯CGñ7CZs^S9«h·ƒ²ÏG³}é¿ùí` ¡»N\6¼ ˜J!¦q÷j},LPÈž¼Ù®n0†YÎÕ]ãN5´èwì’û¢€–:Ër9<4ÀRÉ8}$ÓŒ%BR¦ÿGà:UaÎÀlÈ)ŽA72¾²ÿ—ð/â‹–ñù¾®€ ÏÀʤ„Ê/+¬®¢ßA …P*±H!l¥µb'Ž.VIô¶£@LOxR¶b¦aÍYä °€¿LhE1êç™Ppûr&Â6¹(ªBè̪Z´5– 8ĘðÏo¿¢0 2nÎ ¼Ž‚ímÝV¬¡ŠñÒñóÙÑâl1×ÙÕŽ¾3iÏ6aÀ÷ȨÝ֘Ƶ²‹³’†ÿž í2Œ¨öÄ)|!d‚W‰pwÕÜ‚Ë@éK«½G£leŽÍXéZ±]E…foæ“©~Ê‹TZ0™yÚéËLL)ØþØ·z™cîz“–™ ›\B±D¥2ìr ƒ9ó· ]wãdª=pVù×Ïù¦\­ÊÍÙ5giV$Þû$¸™ë;TÐçqû!Mp²«:›7Å&øÚkòù4u¢1¦•Åï÷ðŒÇsY·:ŠÞ ÂO‚MãÚ§O½“ÝõØ3ÀËêÚ•î™ÚØ®{ƒTlŽ|·`> endobj 1704 0 obj << /D [1702 0 R /XYZ 56.6929 794.5015 null] >> endobj 410 0 obj << /D [1702 0 R /XYZ 56.6929 769.5949 null] >> endobj 1705 0 obj << /D [1702 0 R /XYZ 56.6929 749.9737 null] >> endobj 414 0 obj << /D [1702 0 R /XYZ 56.6929 670.1208 null] >> endobj 1706 0 obj << /D [1702 0 R /XYZ 56.6929 644.0935 null] >> endobj 418 0 obj << /D [1702 0 R /XYZ 56.6929 176.1924 null] >> endobj 1707 0 obj << /D [1702 0 R /XYZ 56.6929 144.3484 null] >> endobj 1708 0 obj << /D [1702 0 R /XYZ 56.6929 85.5791 null] >> endobj 1709 0 obj << /D [1702 0 R /XYZ 56.6929 73.6239 null] >> endobj 1701 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F42 1338 0 R /F22 1037 0 R /F61 1466 0 R >> /XObject << /Im3 1642 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1712 0 obj << /Length 2724 /Filter /FlateDecode >> stream xÚÍZÝsÛÆ×_Á·R3áõ¾ï>)¶ì*c;®¤L’L&! ¨hÕéôïîí)”"fÆÃö>p÷Û½ý„qø‰‘7Œ«D\¢™áÂŒ¦Ë3>šCßÛ3ÇLÚA“þ¨ïnÏþúFùQÂ+íèö®·–gÜ{1ºý4~õ÷‹·—×çiøØ²ó‰±|üÝÕ‡×DIèïÕÞ\½ýñúâÜéñíÕˆ|}ùæòúòëËó‰ðFÀ|WØ3áÍÕ»Kj½½¾xÿþâúü—ÛïÏ.o»³ôÏ+¸Âƒüûì§_øhÇþþŒ3•x3z€ÎD’ÈÑòLÅŒVª¥g7gÿèìõ†©Cøi©˜”‰M”fÞÂOx­J$K„‘Ã¯å£ ,š®÷¯Eó8¬›4Cí,5Â0eòWæ¤H:þJÑã¯z3rF0i• N§‚ ce,÷Lh‡ïÀA³ìgÎe™Õçe“q ŽËt™Íˆrõ‘Hél¶:~œÕqè2m¦‹¼œSw‘×Í7ÐL’ñ]µŠ‹M§4ú§UÙ„ùUØÂ$K ÀöZÎH:ªf‘­¨¹®³šíЉáŽyÇŨÈËPF~a]»#ñŒ%Û3ìg¼ÔYë1N:š€`¬ª¢~ ÷¦EÙB õq&Â"-ˬˆÝMEÿŸ²ãü§/qÄ"‹ïÝÚh™¶ÊÄ÷®ÊÙt`w.J Z7y‘7_Î…ã|ìô2Ðwù(OÊGá…°ÇøˆOB—Ób=ËŽ³1Œàáö™ó› ‹ƒÝMû´î,ªòÄçEõ)Eß"ÎP}£§ZÓ Ú÷„d?´/MMý³ì.]M=$;ÑkØ Iê&m²%XŒlëãqÚÀ䤭ñ0›kw„mÆ+æ¡¢­ x7ò0FÙªIó²‹MvX„èv,‡r˾';?éøŒqJZç‡Ð§cùÓ{ŧ½4ÆÂl­¡ï`oÊFO„4F>­']P÷ÌÑX \X.×eçòR#âÚfüŸg 5Ú8ÞX‡T ÆÑ¯8ìLºqÛXw®líáõ5_*­™V”F:ÄVíãÉZ­ÁúÌ&¿<Ϫ†h}uîÇa>=¿þpssùŠÚ¸àD{[ýŠÃG#93Ò³.FYÆwÑœ—àú?Ñ`…1×Cω€QCÎ(!gâ×û†Zë{ê¡üÐ&#JñúÍ+j.D¹6œ ›.Z˳ÕÙd%äú}ÍWP7Nµ7B2a9Ù›Ïyöðì+mG˜›È™§þŽN›y:iQ'–YáÅv†s&yÏïý£ÀáÜý õws*Ð6 ú?–zYÂ^$b FI:Ð!Û•‚GÅ-ó2]k›˜ýŒ |TrQ#yîIÕßîÉ­‚Ä».üÜ›IÁXÄv±z³ƒk)ÓEÙûÝlP—Áç&·¶Õ;_Z¬h[Óéºõ‡Amü³!ÏŽu;ë4ÛŠ´d6± ÒÊ0! 8ÆwcåÔ¢àœ‡ŠEXï¦ÝP,­Òå2ާ-š%Zè®ä1±´ÒÝzúoP´­ÖÛV·³„ûõ¯¡šñkˆBC"ag0%þ÷·¡ƒÁ4HŽö$è5ݼ|ãw1m5À±“î%á[QÚSð­JvY96©ë:Ÿo\‡ÿê/ËOU‘Oé‰PÅV°z8¬Œÿý ‘Ô–*DÔ‡À2Ö¹_ÅWÍ)H€VÞ66kßQзÜÚÈý*)øB˜Ë œRšI/ý6[«»ëÖž‚hÓž •¬êoaS‚/¢‹Jž»%”wÑCˆ¤‹Wïê.ûÌ·'=&BoñnÜUEQ=t™aœ·Ôå.1šYçE3ÉËow®š9çÀVÐZÞ«§©G rèÜsÕãЬ^=ó„Þ@<&e™TJì7jÂ( /’XÏ,‡R*‰bJ˜V+¾Göv­ˆ \TÉÏ´}ÔßÌKmšbËÈ fT‹sÉ1Ìd¼ՆB±aGàheõ4Ìz›9f`¼5æK¶3öbê–Bêc˜áæILŒWÓ´Àã?8§bÂÉñÕÇÏšH¤Ô‰d#i£Ú‰AWÁ W ”YóP­~£ŒVwé4”4â„r;p ãDï7 èkˆ—¨m•ÿs‘µu­7#i£ŠB?E‘ɸ­—Q÷²úœÍ°cÅžê°DûgÔÆ…Ùऻ¥¯A=’ØeEÏLæQ&×÷YͶKØ´9°£*›6›ÚuWôžgÄ·//“µø:ðÄŸ¥Dâ„ýÂ+<³^^á%ãZù öeÖÔO^Å]ЭèÛ†kO¤wJZÒ3‰uèYQI5R:‰E2%ð9Öér´µØ œÁNÎÉ ôfhë/Ò åžÜ t%º(ÑÐóè.ùžDS ‰ÒŽD{½G¢w‚òC¨j°ž¢s˃ +«7‚¬¬ ‚ŒÄN‘H50½+È¡+À} O¬Ñã›jžö¥Û‰´pññUBg¸º Ï"Ü“Oó9ŸeDHéï}öƒ33|™—qí¥[ x®ÿ¡EVΛE|!¨±¾äHEqQ;ŒÃïÆPE–ÔW¯ƒÌà(üóãiZgß ùºÖ1—˜-¥³EŠ9ñÚ¨(5ø†ewb™\Ø¿ÑÊ ˆi—¨Í·ÝË,”©ö/LìDó·A']q ¡ý´¥æàñ·û> ÍzŠâEºg£Ìž“ŸÞé±s#JnOÉ!ê–º¯0åÀWÖ0%I:I—(-ã‡J üð áÊÂðЩç!oD|›Uá»8hÖëûûj¾}ƒûJn>Ò§i\9–¸5%‘B]a‹T%tͳj¾Jïe…Ií§sÐŽÖ¬òiçÙ¾O'ÁBá÷Ž:òÑQô©ŸUn¾9C®¼—Ã`w<‰›B´µ°6!ûŸ™2{˜|Ô„œrã¥8ÕÿlÓñendstream endobj 1711 0 obj << /Type /Page /Contents 1712 0 R /Resources 1710 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1693 0 R >> endobj 1713 0 obj << /D [1711 0 R /XYZ 85.0394 794.5015 null] >> endobj 422 0 obj << /D [1711 0 R /XYZ 85.0394 433.214 null] >> endobj 1714 0 obj << /D [1711 0 R /XYZ 85.0394 408.8744 null] >> endobj 426 0 obj << /D [1711 0 R /XYZ 85.0394 340.1059 null] >> endobj 1715 0 obj << /D [1711 0 R /XYZ 85.0394 309.992 null] >> endobj 1716 0 obj << /D [1711 0 R /XYZ 85.0394 262.5419 null] >> endobj 1717 0 obj << /D [1711 0 R /XYZ 85.0394 250.5868 null] >> endobj 1710 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1720 0 obj << /Length 3074 /Filter /FlateDecode >> stream xÚ­ÙrÜÆñ_ÁòK–)/Œ™Áà°žhš’é²)E¤+ŠJ5 `I”p¬¬h:ñ¿§{ºÇ.h*¥s÷5}McÅ©ÿâT‡^˜Èä4JOûBŸ¦Õ‰zk¯NïY»Mëé®nO¾{©âÓÄKBžÞn'°bÏcqz›½[…žô΂¿ºx}ýòêÕooÏÏ¢`u{õúúl-µ¿zyõË%õ^½=ÿõ×ó·gkk±ºøéüÍíå[Z ÆW×?ÒLBÍ@ß^¾¼|{y}qyöþöç“ËÛ—)¿ÂWÈȧ“wïýÓ ØþùÄ÷TëÓøžHyZZy:PÊÍ”'7'ÿNVíÑEù ß“*” ”rI€:ñB%•àí}ÑS®Íš:§Þæ‘Ún—§Åö±¨ïhljjÏ/~¡N^æU^÷4h¶Ôö÷ fÛ´Õ÷() GLè‘ö’8ˆ€ ¤ä.oŠx—mhLöãviÞž™ÞlL—/"/–¾ƒû~”öb?¼a[äeFˆ?›rï NE·V€\k¶ˆ¼Dë˜eÇ{õ¶H< 2œ?†¨¤§ãPñ®¢ÎŠÔô9^A$V÷EzOÝù¾$ò"iC“]nÚ3¯Ü&0u 5•éÓ{ÐiÉÕùY"¯¢4›2ŸÁddÊ-I¤Í¾îÛGì~‹³¡¥]wES,¤EÏ{KÔFàQ€5 ’"3%°u_Ô &|^Åß5]oJìÁœŽ:íÓŽ£UÚd9Ì {DÛ#UÞ[rw*²§†i4;H¸˜W3ÇæfŸÄ×ÿ1GÔUþ˜ÉÁ¶¢Û‚ðä Æâ¹sò}³4uõ¾:˜ËšÊ5!%‹ËÆÅ:ïÁ"ó ûÞ‚úNK#‹ù)VÊ Ük hƒ’!Y­’šÑ\CíTíp‹U;\x(úû¢žEߪ"ÐC{¦ë[ëGpGe©³aœŸöMŸg4Wl¹í©MÏÄ 4Ä”v;“æÜB¬ò9žf¢o€$ky2T,¤÷¦5iŸ·šJ,WW[ZèÉ'BϵÖãEÁü¾ä ¼¿Øú½ÚÁÉ©Sæ&#ïÉ0Îo®áo„¥bÉrÈ6|zßåÙ¢NYÆŠÎJ/v’WÛ}YR/Ë»´-v=X-MTû®§Þ†7#tê¡fçÞÞW0%“V/7Õ®äCMµ3õ# ®M•ãn´>|µu$‘^Å+ך9#S÷0xTu5wrZ:P.°¨Qj°JÑ ꌷKʦ¾³¸‚M(UO]’ ö6 ÞÐAðDuF¤0W7¯×J„áZ 8×eÞ®¥[bÆ`+8bt.è1ü€ù9Ôt™(«évÜQÛß“_ÊiyÆPB Ñ óƒG{šaf`fç ï˜ÑnÏ2Ç“9Ь,Í/žÓ?_“¥ú!]5ŒIa‚õ¦jPšÃ,a¶É¡B¬@‹ˆ.7Ea«-iÅ&}ò ö áñ+Zžy/Øgå?#aðMÈ G}ZÐØÙeDzЮXöOÁ–ozdÒšâtx¨Z°0Q%;†=ŸixjG1îsQ§ÚfC . šú $$ž^Ï”òiä¨.•. c ]ÖbJçȵ–Ú)YÞx‡žÎ–D$—“ºYöê{A8$ucZêYöC—=A÷UÞ\½¡îÚŽl&ΕÇ”I…tCÐ ™”Ö««šç{ÐK#嘲|¡Ý×už®).…‰EÑA\ʻδƒnKë“S³·$JéÐ@oF$Œ'ùŒ(^@§©ËGêmÄl*£nÁ› ƒE/y×$P+_¬~jòÏ y˜¬Þ9À-#g«]ò{H—iD×=䤨­lIg*Z';„‰yV A]õ%ª¼f³wlE¨c®ãÍdõ°0gÊRãMÙ­ /÷)ÿ‚S g¦€A‘ìŽãzÈN <ÎŒò°¾à>?βiÆù‚%_‡ë×6³‰V/i³c¨óG,=î@®VP2VÓGßÂåšS[÷“è‹,9 ÷úz(¬¿I+¤'§!±OûœBQ@f›pj”‡"„`5¡…azêMÌ?bo°ª 删òz› 3¨ÀYix±þ¯,R@Gd=¹ƒ@&žïÃëo&S+qkÛ™MT’!Q‰†{ƒ Š£°†ó,=èmxù@$°2‰Žœ?²2Ä7ì´y ¶=('dàð8+*)@>ÐÊk™"ó™ÏÈÆjÄÙn†P´;úìowÈô ºîÎgáŠ÷7‹~¹Ë|m‰# •?:®kòé÷×5BßÓ*üv³˜T=µýçó7/–Ä8ÙŸmÎͦ6™y¯ƒÓ²<ìÿóüYÊA¯¨÷ÍáS/[S§E—6ß<ÇÇ×륹‡×ðs]Åû‰öCùÜþ&ð¼{JÍw¿4݇óú./óîY ›öŽO_Õ«Á‹œ†7]ŸW »©»¦í‹}Eðl•j ÆêIy"ÑPÊTgkáÛKƒ;kJ¶ 8cíUkªÊ´Ëš'/‰†—‡ƒ‚äüÛò„š ï°9gïhG1ðçvL–µ4øÊÓQ€Å0ðrJ[ç%:Y ˆ§ß¹›jûö8xÏ®‘kwóhS–̓ãb-$´H$Pl‚ö¡,0W² .ÝûÇüq‚m`‚áèÏ3¢È‹ü8|FFžçÍŽ äýûºøù6ý=÷ò¶¢^½¯69 ·y¨]w:}×6ûÝlz´ü.@ˆeª¹\“\П_ªàÁ—(ø9FÁº ²Å¬þõ[gî–î ùbþÖ˜œ}OéÈUfŽ¡¾'}åÂw7R§B’yZrÅLj™±1¶¤-ð:„ä¿äe[>ƒY›CË—ˆ ì8ÓY·As&«Šî¬5}ƒ¯K\wæˆ"xÃÁy:<4›ͰÈ^q!׉p‚x!føíç!ÿQ¡Dv¼6CŠÇFîpy,ñ†=û퀑ß¼¬AÂ.‘jë,]¸‰Å¼(æMû¾(mTAèô|CºkÆ—6à댉ê®B¢¥¸§MD:¼úáÁÃoÞ¦^ÿx}3]îöeÏz:ͤ|ªMŸÉS).<€ÏëI þ.Œ‡ïy¿ È;“XÈ©â"u£ÇšMœ`ÒÐðöâ »&ý˜÷ÔGŸ×T;ÚO“bàƒoÌD¿Û„žöÝw‰ÁT€Ùm¬l ¿ä3˜ãxù#Øz€¸ž‚¤/\3µÂI$FÌH¡1 ê%¼ñ¹bmäËEÁÙX¨'EèÀèîÿMÄgDhð¸aÍE`Cø²7‡¹²R\=ágŠ€‹â…w=Ö—ì‹#NVn|õæs@36I§™z–kMø$ ¤~ÂÀ O VÊìŠð…'âPµ`ˆë)ÈcÁ‚vx±zÄüW‚Uðœd›íB®" •/“¨P±kpìóŒÊ7`ÀmÑ}äòBÌv²/0!ݱg³ÞÅßQKê »Ü]Åø‚ÌÒ±‰÷9ÞåÁk nLû*<,lc… ã‹ tš£Š?]àŒIÓ|GŸt°‚YÓ*}9À‰-µTùÁr§ „ëhiáŒ$ÙšF«[ü°ÙÐ:94:EX&@I ™À‘×¥ªÆˆk=B®öTܶ߼Ý@ëèIm*U§PÊ(_­«ÞzðXSÁêÁ$ñ€ö¯5ð|êg5ƒå-ß¿ŸX†´ \'ô $÷Øì±ü‘8õÀT×V*±·_ü€ŸDžRCQøéô бž8pÈU#ˆqMjÝ=¼ ‡ûä ÿlg³Û˜ô#_ô¨¬üï$> endobj 1721 0 obj << /D [1719 0 R /XYZ 56.6929 794.5015 null] >> endobj 430 0 obj << /D [1719 0 R /XYZ 56.6929 367.6903 null] >> endobj 1722 0 obj << /D [1719 0 R /XYZ 56.6929 340.5075 null] >> endobj 434 0 obj << /D [1719 0 R /XYZ 56.6929 199.9311 null] >> endobj 1442 0 obj << /D [1719 0 R /XYZ 56.6929 169.7835 null] >> endobj 1718 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F64 1485 0 R /F54 1433 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1725 0 obj << /Length 3776 /Filter /FlateDecode >> stream xÚ­Zݓ۶¿¿BºŽÅà“â'DZÓË4Ž{¾Ì´“d2<‰’8–HU¤|¾vú¿w P¤„ûHíу@\.ûñÛø„ÁO¬Î˜tjbœÊ4ãz2ß^°É Æ~¸àaÎ,Nš g}wsñÍ[i'.s¹È'7Ë-›1kùäfñëôõ__½¿ys}9šMóìr¦s6ýîêÝ÷ÔãèïõÏïÞ^ýðËõ«K£¦7W?¿£îë7oß\¿y÷úÍåŒ[Íá}(<ðÂÛ«¿½¡Öׯ~úéÕõåï7?^¼¹é×2\/gò¯‹_g“,ûÇ –IgõäXÆ“í…Ò2ÓJÊØ³¹øpñ÷žà`Ô¿š’Ÿ–6ÓV˜„…H P»,—Bz^-iAuCÿ»fßQ«jé¿Ý•óê7ÆD¹xq:Çi9ž|hËÈPr6½Y—ÔW´]¹¯Úôô› ÅöÍ[5dNH™±\‚ðÌ(©=s¡‰£UèÌ“O³ çxÆ­Aa"­jwº¥JèLäÎÅöŒM™³Ö¦·tÖSœ IÒ~ 9SÂfB[3Þ0/üs±p›Yߢed8c2“¹€-æfÜe6ÚŒßiô´¸­6UwjÚ5ÔYµí!ŒÏ›í¶¨-=5ŸÊ}˜ºî'ÔÝþ’Ûi³ kØ2·1“åŽÙ¯Æ`Oðq•Õ0.q¸©Ú¤© ´Õõ>΂)Uaóé_x'ã;Új»Û„ݽzí‘eŒç|¬H¸kdÁ‰ö»ÞüîÝg½¢Ž¦ÞÜ¿ ~µ¾OhW4™»£ºŸJ[( ,‡}á:³‚ì—Š»§8’<—7p9X÷ñËÞç.Râæ™uZ…U”›r[Ö]ObVÚ$r—Iáø&‘ƒ‚˜¯)ƒžâ2t.?•AÒ,€ƒÌ '¿"“‘âL*úÉ!^Œ˜|È2òÌæy~tk VuCÏ‹’ Î@5ãô*¥È`+¬ßÇC]}N¹m‘É{·=r¸Â ®ÈÉD¡³ ¿_Þ]ýƒͶ¨jêm›ùDz£6®·¬Éô`ZºÉ¿ãÜ#2¢»¢[ÓP$æædÈñ½{ »EÂÄôÕ|ô„«Q,îdãÊÍ)hô,ZMk¾+ÐÑ5¾•r ˆŒrÃè“®Ì,cqÒ‹íý;7wu¹OP‘<Ë…{4Bƒ*.ãœÕ¾9ìÒ±Þ-NC4„g3}×tA:>^z)mCÏnStà–·-‰ì7¦Ù‡Cýó ÓàrPáFÎùC³)¼ÂKæó¸£Ðð!»mCü‡$œÔcXföÏÈúø¹£9áÃn·©ü##͈! ÚGsëŽ=Ï»f´O-‹o8£×6hW][n–$.† *zŠ·~–¢€„§»}µ-<ðPºu³¯þ] ´¢®m‰†\µ[|´äÿ¡»‹ï z›‡oajd"ë®G}‰X© ì Ž4WèQa˾šDг!É„ æ&$ÕO{68Á4 `úݺš¯IbèÁÅaôçiùV³Lg&Užé\åãN‰3‘ ¥ì$ÇŒEš/–QOp6 x."Î ‘’2ï¿û šÊTtTÞg(;}SPÈ=U tjìüÄ!Ò Ì¾Úr#Á'– ÈФzz¹\dR«‘},r… ¥ø# ðcÂʯ¶Úžàã«7ÀçˆÑjROGëmÖ‰w˜¸þ†þËÏåüàÃ<s\|¢7 æSàä_‚}(ˇŠ@9#0`±hl¿šPã:UþθzÓÏÂ¥þz]n)ò1}Wøˆgäôûºkê}=â}™{ïúûÙf[‰xÊŽx?+8õ³ž`Âk¦T®Ç<ƒ:ž~Õ™Ìj«Ÿ+±~þSß?£ë#:%í$™É ôì ykˆÙ–=!‡~Ö|œSÄxsFØšªFœRÙ+n›CGc ‡ˆïV‡ Âh,eLÐÝräjìªIÒ§^Ä×»¢{Û׋y °LyRL—ƒ_ !üX=䫇 Ï"ÀþûÚŒ·£f“ª½H‹QDúmWt>Û#ÒÞšárdx‘.ãG–k0…”cÌÂe!ä]µÙñ¶ _àéÿ ú[”Ëâ° ccOÀÕ.|& ðH8JGãM³»-æzs6Z«G*Òª)&ƒ4(ãø(=VõýU&\½ÿ”ÓØ¼9Ô]¹ØÑзßrðQ†óéUMS:_­À±yÑ–/9÷4‹MÛм»uYSß° ô™çú; ÐEª> vÖ/"f=Îeš³Y ö³&5½=„Æ¢)}&‡jºÖŧ’ZEJå¤{¢(1›Qz‘Ò4HÒ˜}†¢A¦'ÇŠ†ìu ]àÚ$ªQ,BÏ:,ãˆhñá˜Å*¢ý[KÒÅíñMr7+,œŽ’È~ž×ÝÁ#IÄãGwpZwg¸Iúˆ)´8Њü¦ì’ž%c1e"çÇ@ë@;>ÅrDX£‚ôúé3¨ÜÓ›sú¹€Õë¨qw>á1ì$?6lH×±N°/ÞªM‡~sux¾¹tbÚÐØœô³ èË¢âøÆÌ?³¹9É)—2$%²îZ8uÙ_Úé!ŠÝ u ¾q¬ ñÊg… YOgEâCÖÏ•fìâ¹R,Oœ$6öD3ó,ÅÉ%ê%HìÐ'‰Öa[7è‚F¨ðá « sC û¢n«'­£Œú©² †ÂöBË¢@Ãüè’O}гUø,9èñNÅË·Rn¼‹‹jUužu0ø0äºýÂÐÉ2J¥qŒœ53G£ÆÞãQ úPÕ󒊨]ÒE)ÈCuïywQ°µ*墺GMLø³lq` °ÞŸdâ×ú§CÊž!?!ßUÅ ¹íôÚ[ Î: ÑÚKú' á›–:@Ú3’•ƒ¬Ëòü<°­ÅkiQ  ˜ûÇž:Ž’ÑåIq”¤Œ¬«Õ:Ì.WôrI#ÞåJ7´ØpœÌrúâv>ý§˜‡03žÎKtómåµSRÁn>‰@#´Ç[Ô¢s¶°¡ÑB¦†–£!ð>—Î5iƽç g¬›ÃfAèò¨•Šé ¼àýzLëµ -"¥V€­d­î*8@_ Ì7w55úVËg^k×Äc×›a9¸qb3½ý›¶o‚¹cÅKd| ’c¹HÊça@ÈžøIm¢H×>žãJºÐטu̶°qðÑW£-BÙhgéd!µµzl±Ž&j€H¿˜8=d™}Ü|ÞkÞCÝxL-ä€ð‰"àÑ¿€ØIç=thÜùáᎌ».ÁÚÚêXJWÓUŽÂñ2¬[B,78pNn x7˜ÓÖ–Œ‹9—S™B=R!*ÙÈb"Va ÀÙ'â¤Ò=Âõµt)¨#¸ ¡¥:3­K*ÐÙþû#hü$óÀŸfÄË#fhòþ(¹×Z$\‡/“wxÄA=$ðÆ×à1p´(nã»>¦Fæ°&Å3…*7’èŠ?°.Âí¤AA>dÇËJûÐw·7²Ž®‰EÿŒ‡ÿ~ÒÇ*1Ki‹ª ,?sÌ.ñ€è‹žƒx»€þ1]Má…¤>Ñz¬ºà…KqZø6¥_XÊ]’&WÒ ×VÉÔvEƽ™R×L9–ó O¢ßE<Ñ"3NJ„xY®9‰o êËg Ê|sXÉ}°ðªà¾i§ÒZ†…»Ìòx"A\µ¬6%zŸ—)ŽXäDôœäÏàäû•¿Žy“ßä ¿x$r.žE3NOoÙ>GšcN¢u>©ë•{2dtïÐçírpŽƒEw2{×T‘Üz½ˆu<û…sFä_Èy`º¬C n|áÚ±æ;r  RËç°cÐôL‚k¦ËbŽAúÚÑÅHÛª†ô«G‹x\¾¤±óÄËFa·4ƒn˜xUÌ|ô‘ýÝ·œÌÀçÖœßí+¢8‘Я‡öØC¸…z}å;Cò«)¨ùsäà⺽È"8ÁV<ÞATr'"\Õ ºîOp„±àÝË=Ö¼ŒJûž„¥›`é2þ?þÆAuN”þÀú¶ÿã×1Üáýåquz³j`ÓÖ[šÙ?»/S Q7"=œLí?ðh½zBæø#$Æÿ¾|è8 Ïe¥Lİ^b_|ßúx§ FÅ':Á-À…Èr®pc€ 1¼žqàaö^.ª¿³}¾ªÿ¤0Àendstream endobj 1724 0 obj << /Type /Page /Contents 1725 0 R /Resources 1723 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1693 0 R /Annots [ 1727 0 R 1728 0 R ] >> endobj 1727 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [84.0431 612.4761 284.7281 624.5358] /Subtype /Link /A << /S /GoTo /D (rndc) >> >> endobj 1728 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [296.8623 612.4761 360.777 624.5358] /Subtype /Link /A << /S /GoTo /D (admin_tools) >> >> endobj 1726 0 obj << /D [1724 0 R /XYZ 85.0394 794.5015 null] >> endobj 438 0 obj << /D [1724 0 R /XYZ 85.0394 334.822 null] >> endobj 1729 0 obj << /D [1724 0 R /XYZ 85.0394 307.61 null] >> endobj 442 0 obj << /D [1724 0 R /XYZ 85.0394 267.0706 null] >> endobj 1730 0 obj << /D [1724 0 R /XYZ 85.0394 235.1802 null] >> endobj 446 0 obj << /D [1724 0 R /XYZ 85.0394 160.0266 null] >> endobj 1731 0 obj << /D [1724 0 R /XYZ 85.0394 129.8498 null] >> endobj 1723 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F42 1338 0 R /F21 1034 0 R /F49 1358 0 R /F14 1060 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1735 0 obj << /Length 2671 /Filter /FlateDecode >> stream xÚ¥]sÛ6òÝ¿BôLˆâƒ ÈËSš:9÷Ú¤ç¸si&CK°Å)Eª"¯í¿],@‘"ýqãñƒ€Åb±ßX,-þÄB§,Íe¾0yÂ4z±ÜœñŬ½?'Hñëûë³ïÞ©l‘³<•éâúv@+c<ËÄâzõ9J™dç@Go?~xwùþ׫7ç&‰®/?~8¥æÑ»ËŸ.hôþêÍÏ?¿¹:E¦EôöŸo~¹¾¸¢¥ÔÓøþòÃÉéç¢Wï.®.>¼½8ÿrýãÙÅu/ËP^Á òÇÙç/|±±<ãLå™^`™Ès¹Øœ%Z1( ÕÙ§³÷«në¬þgR¥rFR,„`¹Ör¤A³TIÕk0¥pΣßí= ø©+:»±uGÓìoœËºìʦ&HQ¯hðk[ÜYT&Öâ‹X&,ODâN¹^$1@’œ¥ 0Äž>%8Ú¨Äã´GÆ@ÑŠ³-M úi×Åî\d‘]ù¹]ÒÜïrbâà¶ÙÑ`ßZÊnM£ëO—ïiô×¼µöÔÖÊäLP;pzå9jww \ ÌÔãÇà d¦¡ÀSº(ø'»$í#G`åSniÀô:q3q•ë ¦ÔP„ ‚Þºµ×Û²ÙlÐ'€+””³LH½ˆ{çƒÝËuQ×¶"·y@§B(pe#%3J›'tÚãÇà Sy¦tG:¥ Y2á'5,Ñi2âg¢Õë).&Ô‚V)N@$›T¡â Ë•4ĎȘ<{4v'M„šÆŽäI´,j4Ëå~Gï9»J®£®Ù¤²ßœíÿv„”šÃðn¿+¼>ˆÊ#4ž|Y·åÊÊ™×LK„úVÚÃ\F€Üj¸>• r¸Ìuô/{ßÒ +{½ƒ¿%c¤ÌiL!gô òÆ$ê”;c˜‚ÀxJãyÂ'o‰:©7–~!ïŒÐQQU@á[I$^&‡ÖÙzE›4å/Og,Çœv¥ÑL R)X­Û5U;#…ÊX¦µ˜øÓfNšh­Oµ9ÐÂ*ÍÕ"Í %ä@ýñxèñHªÏŒfœçՆԧѰž`bJí˜#‘…;õ×§³6ü†ÛÊ_…_¦8 68ô9Á(–qùPJ€ãÇξ>vС°*I¹X¤©ËåùsêÀ̲l¾:‰ÁxHÑ©jÄXn˜H²üx.òW®æâÇ»‰ð Y@L´ Œ¤‰~¯›CMâ¥_Ò®¹âE¦Q]l¬Û)£Ò#´²j6Eé÷#öuùÇÞV÷4ƒUwåí}YßѦÑBˆÈ¥Œ.;SPÃà&Ðàv¶Óà„BÈq¤<¢`A¥y(ˆZ»ûfwsñÉr&­» F¹aYôIб¥D¤ò)z·.<ÄŸJÐf˜¯`_y×§L*•hoéÓSP‘S?• £ä¶Z/­ÇßÝríÓ ˆžâ+`¨«ª$–3C¬dY¼u<Œ˜†QYCB&œa}]|³´vcmM°^{a2WC"€¼ ŽÅž²53½—åà]Õ]³›0÷…ÂoÎP†²~ÙÅtöHLc‰lTˆéþ¤ijP9À–”ç’"}qh÷ã!Éil ¨†2¿G{8¸5(HTdÂ*Únç´Œc²kAÖní²Ä¬y."Û,l°P¶”ÝýwÅBbvé«G4( ‚*ªèXkå÷í·Ûf×ù{/2ˆùŒ .ÆN¸ÞËx³Ò3%†e’›>]MIjPN_38Jð:3¤à¡/[õ©ì„””É ±qûGÓ³ù’:}˜þ‰©l–3(-Ò¾$õ‘rBNÀÐ$ú„žòAz!úG›'ÙÇ¡\ T©l‹CÁ|.yt}žsÈð¬N—t‰£]£ãI­"ÿª¤ïF„§¢›{Û-h”/ìïvAr*7û !ÕûÍK±°àªi}LÒeÿtudK—Á`}KðxœYüÓÊRI8>rU8]û¯ð¾‚ðawlFÙp7s¡ä©‡ÆŸÑ¶œ B]zKàv~ o¥p“¥ý©Ïv§I *—KðÀg2OÅ‹“VO1’œ&-Г €z4ºI] š­‡Îô q¡nɶ¹õÜBãmá×}•?°ŽßʇW‡óV ü(q’€úf‹; E:.x)§b}ÁY´6NšX¸W‘Dd}é1èOa*7‰éûB¹ï UÍÝwéIoèý®€§ÿnƳNZ@=‘(þéÄ ×ß(4?Fß.L¾RÑ6 à÷Mž"„t[V}[tkÚÛ¤b¹8}ús¡¾h!)´4;Ò 1‹ã¿èg_Wå¦tFð¸‚F_æ®O¿-ÿk£¯xÁ 7õ,xó¶÷-hq8þz[,Ë nÁ¹´vu+»ÛͱôW­ªŽ"¼~„ ƒÅ* íu´„)¤Ój¤8µkìPìêÞÂé ì´„gû,sR5ß6£m+{³÷„’Û¹>ŸÎ”$¡b ©~*To†ieñȆÛõ® Ç-^}m³,Aî–š;Ûî;ZÛØnݬÚWôØÆ7…_é%rýg25Ìk8sùÄ£Ês¼µ=>­û‚âýãY„Ÿ+üˆÞÎâØ8qWÿôô eåŒëP0÷!9ó—bTÚkHûrï~[Ù¥÷Ûus ¿ÙûòaY6­ŸPaŠJlÑ“C…q¬)2ì*4ªrf’q›êcíº*I5õœh ”IÏó#^n (J²™†vEQ¢C••øž@B¿ …ÇÛµgÊû‡“ ˜t\Ú°Ðz½è<u‡¢CiE—·qgN3g’ºú³×Í\ÿ2Kž¥4Ÿ´À_4G™kÚ¥࡬ªÐ¤üÇÜ‹X Æs“í:SÊÉœe™9iߌ/•½-öUv a_©šy=º+ÞÃ(mO>£öµkÖ„zìÏcu3&Ÿ0+ÆÃi²FdjÑ\â÷·4÷߉q”¿~À1oÂd¢r¢¿âoã‚G xS•­ã—êÜ·z¥~`ŸùÀû áÅßñÿä€ðY&ç¿)œð„rþ'J¦â_à]'€)%ÙD¦ð¯S¡þ ãaãendstream endobj 1734 0 obj << /Type /Page /Contents 1735 0 R /Resources 1733 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1743 0 R /Annots [ 1738 0 R 1739 0 R 1740 0 R ] >> endobj 1738 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [378.2799 730.8852 428.5017 742.9449] /Subtype /Link /A << /S /GoTo /D (tsig) >> >> endobj 1739 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [112.234 719.5976 168.4527 730.9897] /Subtype /Link /A << /S /GoTo /D (controls_statement_definition_and_usage) >> >> endobj 1740 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [75.273 677.087 131.4917 689.1466] /Subtype /Link /A << /S /GoTo /D (controls_statement_definition_and_usage) >> >> endobj 1736 0 obj << /D [1734 0 R /XYZ 56.6929 794.5015 null] >> endobj 450 0 obj << /D [1734 0 R /XYZ 56.6929 769.5949 null] >> endobj 1737 0 obj << /D [1734 0 R /XYZ 56.6929 749.4437 null] >> endobj 454 0 obj << /D [1734 0 R /XYZ 56.6929 543.6821 null] >> endobj 1741 0 obj << /D [1734 0 R /XYZ 56.6929 516.3776 null] >> endobj 458 0 obj << /D [1734 0 R /XYZ 56.6929 259.6272 null] >> endobj 1742 0 obj << /D [1734 0 R /XYZ 56.6929 229.5133 null] >> endobj 1733 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F54 1433 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1746 0 obj << /Length 3913 /Filter /FlateDecode >> stream xÚ­]sã¶ñÝ¿ÂÓ—Ê3'†øâGïé’ú·Í%½ºítšL†’h‰µDª"iÛéï.v’2dûÚ=\€‹Åb¿‰Ë~â23Q¬r}™æ:2±0—ËÝE|¹†¾o/™»Aóñ¨¯o/¾z¯²Ë<Ê™\ÞÞpeQœeâòvõ÷Ù7ß½ûñöúãÕ\šx–DWs“ij¯o>ü– 9=¾ùáÃû›oÿüñÝUªg·7?| ðÇë÷ׯ?|s}5™ð½d g>xó‡kj}ûñÝ÷ß¿ûxõóíï.®oýZÆë±Â…üóâï?Ç—+Xöï.âH噹<ÂK‰<——» mTd´R²½øÓÅ=ÂQ¯ý4Ä?£²Èd2 0PÊM%J*ËÀª½š+¥gmWºª^Ó[¿ cfÅv‹5Û6ëµïÞ•m[¬Kþôp%²Y¹.ìsåµuW|¢vy°Í?©jzv›+1+©½lêŸâX®ûCÑU @È–¬þÈ=7ܱ*ïŠ~ÛáfGæBD¹1Ò.o¹)êºÜ¶ohÛš=>aÕõŠ 'ˆ§”^«;þçÂÆORjœè«÷zÌ[‘È(É3Ø';í|Mc&üwtÑ‹ˆˆÚÓz±},Z¦l_.+\}¹Š—áš‹TG‰Qær®š›Ü"E  H ÐqÏnÕÌzùqs(Ú2@ ðN¦ð&2‹ìÝ–?€½gJûnßwÔ^7e;efS—S.ï æW<æ…A‰3ÃmS€(Rk2÷–?6=¯«`¾íŠ{žÜ1pWÔLΰ‡»éçXÔe306Ë#aÀ¼Ì‘eÄØë‡ò€è’tÄË$ÑÃ=ª+ÞAèÞõmG}U½Üö«’À…ß‚–Ãðå¶èÛ’:»MÑ´-[‚7%Ð}`Ü^ïì r[.»4hE€»†Ç¡´žW“«Møìø‰f +ªK®§}f¶G±ì·ÅÞÛÇ–DÚwŲÚVÝã•bvò9)~0U7˜n¬nvIL±c®£`I²/«ª]2ÔŽ¹fvÓB”ˆÉÒÉOŽ5ÃMT°Û‰SÙl[íªŽ€D'À˜ÏmKØ{\ ‡·­n· €Çj˰T,—å¾+WÔ¿x<™`Ø €þ›Ø÷8[f{ª6 úZfQ.@áI%ªú® ›,ÊDîMlÄ’o­Ó(UFLEöl©HyÃkiáé%_ŠMB˜(Ó†g«‹¬< Ê1X*•xYÖ%Øú’gîªÏb²³Èy.aäºA%Ä7œ‚É©W_5Lï°UøÆ[…MÇbÒpD™Ê’)Æ£ÙgQ7ÝÔÆ :f¤~DÆF^àFãvS†ø„ž7v[W÷ 6OÙ$E”&ΓL Fž #Gž@³%¸õÔ ·eÝÜ.!OXó±!ChC@+Àð>Ñ10»JÆÖk†¢s´h+T *lņDL@°¢ò2_ï¼#z¨AÛÑ—E AÅ–õœ–q¤E’yù·aDPM„4IˆÙ*5žÙ*EŽUË®¥NMåhÇaVgRk3ñ|¼§¢ÌUf Í•ý´¨©wP1€Z›T0¿°îÒ8GÙ¦9³1øÓRO…yK´&,Ìeh¸p ÛVÆá ‚Ó­¥Â‘ =å²ÙY7h2ÅImƒ+´@áZÞWx³®öÜ„l%-vz¶Åƒ›¸,–þÖڙȳd\[³c² ÊÇ Ð¤tNÎ^@ÑŽ¤ JN’D:VNrüúžÊˆy’$)´ž±úÕ‡v¨!©5eu`¾"GÇ_²:Ò©r–ƒX‰³‘Lv…¨­B¡nbí¶Åò¾ßSÿ°_ØÓÜ œ°Ýƒ¢@,¡—ŒÓdªÇèËT*yb —þTr|…­#®Ô¶p_`J}šÎÞ[C àòXxf«mPÚ!h,7MCj'YŸäì¾,÷nš›4Û5FKCð§ jbôIØ;Õ Šp?Ÿn¤NiêÃQÜXÒÆ‚…Ìfÿ°Á¶å‹~í{Åp›oÁ“6”IÀN'i¬Xyj ªJdyž:tÈýÞXß €® Ì”@²˜æ‘¡yÀ')á—ý™ 5Eæ¼| ¼?á2L‡ä\BÓÇvAq~² øü‚ ¥¯äÜtEÀ&e ÝS´Ò@¦eÄ´¤fF|aêã—¨Ç|Êß®rûžæ$Ç H%Bù£³“ƒðN•{dÍÁÏ÷µuDA{Y’Ö¹S[P¼ Uç.úÇÎ~·°™ ´­£€§›—štÃà`Œ™K37e[ý+äÐÁï'ÆkO­g奶m–ÅHß±Bß:ŠŒNxó!"{˜Ç‘‰ó©“îCqb¥1E¢Ï¶i´Vœ#6‘ã(¼t/JÆ’8KaÁå§eY®Ú“«zU-yA09¡@§³ pÛcvjû&×=d0ÔZp&Í1ò[þrÍäSÕvLï¨Z0¬g¨Û ì>Vìae«3^ûlüœy'x^²ÄœJfw”'dLYËÉ ?!,XQ·K{XˆmÓzw ©(_=v, Iá…H]¢’ þ€˜pËíœÀ%5¸„!Ñ E*(#M“—Ãaü¢mx@ÆW%‘àcªæm× 0(CH—hç—\Î…¿ƒÐc8µ)a† ´`@P_Ñj)_H^ÉäTeíXU•WU, v(á±!‹]^¡=²bj\:€”é7C2Nz«H%Ù‰ƒɈp(!HÑ›í–ÄEÚj>!{Xª…/šþ‚³ki“xÔå‘°PªB{Q®ûí`nX¨lð2Ì,YTáû&$)˜Ë¤™yUà*s)& C£nh†]3žwUtgé4>É9)²Ç'ÊUg£¢˜’ ûÜp/i4úº«øË¶ÙqoÓwóæn¾ ®`Wb†Uµ;z%ÊvÀÝ–?80þÃU(Ѷçft´0Ó˜pÉȧ¦»âSµëw΀‘q£êê¤t°(7ÅCåëÇç ÎAŽs`kÐNK–c[´”×KÓ¸žëV'8YG¥c½hJE®Ý šdeRõ*-C6•ºö7@h.Ò¶AgÓuú,;‰Ñ÷üÂ9Ä/ø¿-‡¤Šr<~™é]…LÂA¿âO1ºú“oŠ´Ø’ñîmHFö‡ªîæ”±â¸Ç²}ò«4n(aMÆÎƒäþçm¸B¯`ŒÖÏûH“ùÊ×hüJ.Δ™ä¨Ì$§•p $Ç%$ÉAà¨æîlÉÚÈ^¡;šÝ8,\£èw\¢’¢Y3Éßs$¦¸¾ ÖÒbPP>8’i&N‹yƒ)†ôÖ&Çgþâ{ë&#Ÿ\ªµ+çÓÛ8™ý¾nŽ årxUr¢]ŒOB¦Û¥!uR^îËC® Ƨù×´jI!q°s‡P± T5Iåk±ìŠj6 Ú“{‰“¿U–:´"˜ÈìµÄ=¸þsļzIg7WfQúZ<Û}¿*zvAs Âc¨3VˆBö¬BšÇÏ‘d"!´“Û¾_îCXd”d:{ ‹‹–‡àf¡–浤à^Å{ízŽ¡‡~-¦»nŽÏ±x-’m³,¶¡$Z‚&±ü,<âÇcÆxä¢G}!<ú ­Ë|!z’<™õ«³áˆN|õÖ¢J_AÒ\& ËÛ6a£Ì)ÆRŸVS‡ÏáŽ[ÄÄÒÛŸnÀKÛï÷ÍK bFÎÕŒõa<£ ‡[‡i‹!J;£ÿéÁ¸+“‘Ûsþ=ó+äÚ;Ì{µeòÆGEÂñ)>7\m‡@97›œ3øC_4Ǻzì|-¸¦gØùâÉ¡Hš,'Z6õ]¨ú &QЉ FÌì‚ñˆÊ¦ƒ@ŸìÞ% ø ÚÇMeO —ÒÈãøÀºl™A-ßÔP^‡®e$Y”åé”MÏí‘L½5äc5{“ÂÕHYÆ›ñá…M'70ΰ8‰#Hx¥¼ËÈÁ#Q<½ Eêèëü ädTœ!òµk¹ìÆ‹“JÏtë¨Ö5g”\îÁ6ÓäÓ ÿÆý×+¬ŸÕ«æè¯s,7Uí˜á#C{>è…øôèp\ËÕSNÙÆõPù;[yÝOõìóêQR(gýñs`§³ÈÛųËÌŽÍážõf[ÝÃÓ BŸ­¿2‚ùuKèñ–¸âæ`-¾½*‰TÞ3^ðlåç‘`|³F»›¶&IO*”aÝŽ2NÛô˜ûCm‰Ýåi¦N Q‡¢Zopv™ÓæÀ5Pê‡+I·`pØÆÒ­¾eüObê,Yú™QŸ­(©Ù÷ƒ<ÁÎDÈ|\Hr =Bù¹-‹–›6óVNÈ0ºBbGÒh®«‡’×2Ôìlú›ä'¶ÖW®Z@×V/œ¨¿ i‰« l€ùåÁáóDb}‰äÑì7VŸk:q®i‚°‰È’ASŸw3&R©wƒú~â†]—U mïHtåaWռƣU(l•h^zºw„ïû¢E‹N¶WiŸN¨¾Ø¯7ö®€p§¦zrjjüÕ3:~Utá@/#葃Æ7*¨ÁÐÑ=‡n©XD"ÎäKiœŽ1+~>&ƒ$ÍäñPjXôgòkû«‹¾#êÈ"Õ°csŽFr Q^l¦Æd–*È€Ò,Ï' ‰ŽÅ¡†O¶`ARûzV.mGF*ý:aÒãÄÑUJÝÝÁ¦_§\ôÄ›L훀ÜP§Ï_“"Ê”ù³á2^¥Ž‰©–eøâÄ’jt؇„.˜ü ì~ï}»ÊÒ(WY6•l[Ԏݽ™ª@5øx^C­;vÇir•«7tlbËÿ5˜/Ä™—Hbå3ð37Àð’¼PĪ£Ôh'¨ç% ËìÒŒ¨HmœÉɶ«ÊÏü@ ÙÇ´ŒZÚŸ(Iõ‰»86ý–]ƒ->²Ýv†|ê\%𣥲zðn…övö-ѹûïÊDxi=p[=ö× ÿï»ñÃt´Éðµw¦(““3QÈ_ÍAb¤ÿWoN«ùútQþ~ýÓUý Æ¥:endstream endobj 1745 0 obj << /Type /Page /Contents 1746 0 R /Resources 1744 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1743 0 R >> endobj 1747 0 obj << /D [1745 0 R /XYZ 85.0394 794.5015 null] >> endobj 462 0 obj << /D [1745 0 R /XYZ 85.0394 724.8607 null] >> endobj 1748 0 obj << /D [1745 0 R /XYZ 85.0394 699.5291 null] >> endobj 1744 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F42 1338 0 R /F21 1034 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1751 0 obj << /Length 2618 /Filter /FlateDecode >> stream xÚÍ]sÛ6òÝ¿BÓ—Ð3&ü“§4g'î´iÏõ=õ:š‚$ÎQ¤JRQu7÷ßo» H‰vrs/7ìØïP.üÉEœIf‹4‹‚XÈxQl¯Äb °W’q|‡ä±¾¼z}§ô" ²$L«ÑY:ZËÅãò7/ ÂàNÞûŸ?ÝÝøÛûë4òïþt퇱ðîч‡w?ýôîáÚ—:–Þûï~y¼} PÂg|ÿé/´’ÑÏ3‡>ÜÞÝ>Ü~z{ýûãW·/c~¥PÈÈW¿ý.K`û‡+¨LÇ‹LD ³,\l¯¢Xq¤”[©®~½úëpàj·ÎÊOŠ TI8#À0œ`œ‰ •àãÆ €*G¨2 Â8Ëà|Äéú¥i[FŸfŒÂ”Ñ–¦ëË:ï˦F1e^QåûÎÐxY¶×R{¦è;XY÷†›¼®ME“¾á_íLûÅ´×>Èÿïìú¼^æö¸%!!u0kZÞÓÓ]ùôª”&ËŽ@ÃoÝ›zi–ÈÔÂt `É—2Èâ8´ì¬ìq:ôˆ-½ÃÆÔ´DäÁÀ‘‡c{6 µ×ÚÛ×uY¯i=ïø—~ð\¤nM4ïë%mÛѼ0]w+™8Q`þÌ·»ê‚Š¥yگק{è§hê¿ ®÷mî[öÄ”/ÔO0À—¢$Lî•'¦€†"¯yq¿ÛUG›kéý ìÊ/¼eL LËhß:S€c˜hõüÛ¤¬gNÞ¶YÐ^¤Bï~Eý9}d3,®«æ)G‹Ò ‹ÃÔ«Ì뤫Ä[³¥ô¤Ä.± 蟆b•ãí5¡LÄžXJ p(+LE“'Cà¼èAJÈŠÌXÄ¥09Q˜"…Î(Þuħäjq Wi £í-]8ëç=[†,”óÙ:ß’œy¶‚øþÏòÆSp/Ý:œ7¦"Ð*–¼ÓŸ;[Æ EÂ(`«*g’WMU5 hÂVN?»¦+{kp8Ca¯.0ƒôóغ#O¼”„ª0P‘ަ¶ÓÖË‚cP›f†þ( °¦ß†˜„5 »ÍbÐcÍÆzÐ,¼œã£5€Y¥Ž£ßØôéå6DâØò-7îÛÚp0lV¸wuCÁE«/ŠBi€‘ÐÌ’F¥‘B"›ˆ¨nž  ‡°ÑDa콫¬IgSÇÑÞ"]¾6ÍlÐ.òk= ­™·É¿ðjN?ƒÏd$Y뤚%ðM¹ÞÐæK\¾pMÁK£) ÏŽ‡‰ß-MŸ—‰X@Ðîwû5/¡F üÕâGO£ngŠru¤I>ZÃè\Ð|0imÙ¯¥”hϸF œÞÌ8ÜY²i" eñÙÞó™m!ÿ²¼†*Èä¹vW%fDúnÕ4ß½CL¬Åc.p¨ÝŸ=ùßogLNV"Bfb(\»§ÁÈlÔ |­Û_æ ‡Š!-aW`d´’×GôåÖðhÃ!ÂÁŽ’ñÑ /®—Öé0ܤ‰ÇyœK‘ÓM@Õ\Þµ—i5D¥£Éá²|€]¥`'»Bˆ»—ž ”]ê‚Ñò½,æ‚– ¤TC@wêãm}ƒÄ ž];­œ¾qÙ V!x‘êñ*ð  2í¶¬ ôap“Q@÷ièw×B€Ÿ­RîW3bÈ J)—tì^ßjyF:ЩŠuck³HB(¶Ù=§P «MŽ)—ü#W¶l 5(è Ì.‘ÓÁô[5ëµYs*Œ‘»8þï©ßæÇñ%£ðâÀBA-‰Äg¹.Ÿ!'…‘tÄtÇŸ ô2Hç9æ W€Ý>Yç‚+¼ ìkŸWT:fÅ=rœve]Ì–)© „L¿é •¼ê:°ù®3VF CH“TœÎ›•TI*=UM笛ö8CM’2Õ.rçGQD¡8Ë(<þØCÓd–7TÚ³™Ah!ªÓØn³3Œwø;€Ù{h[,?1˜¬ŽÆÖÔá÷`* 1 ÊÍ;h×P3.å`3'…Æp>–ÃDfä©ˈ¯o†î©fш4ˆ¡¤Ÿ‹”2Ç)˜¹XC÷¥?Ê’gZÞPe “hÂã3=¯ª¿f‡=NÇDäÇéµY—4²ÉDº$$±KÛ>q³|Ãq3"LAÑ=uQk«PÛ²r¡ÔÌ«C~ìhÕ*Ö,¹†Qm)¥œ•”êj*¼¨LÆ„eÚ7èʺª:åÁÜœI(=­LÐrDâ}4\2Ñ…L-lá¾S¿Š„oF¸H}5WQôBšU Ä.•Ä_Õ Èß7Î4c˯, ê¹:Êè?‹¦Ù&Ôþyò!Í *pdüFÄo sЉ¢•µ©M›W KÈz‹ã²0nÖNjîê¶Ç‘”5"8Áƒ}KËôF`–ƒ<¥)X-Nhº tzˆb[Ä'… û‡Æ0Ù×Cd™rÍ=É`E°Ê÷UO ³‘­! »M°Có‰´÷±9Ð2˜è‘våã@A¨£xê Ì×hT?wE[> Ëõùƒœ„Ø ±'[D`D¡P>°]/hð0zKðýñ†Ë·´Ës‘À_Má^¿„}šÄ—¹s’BèÀ¥hBÒÅ£Þ€õB.O£ÎkÆÀe $%aüBÃÀzüÌùö¢U8«^¿æ>Ã`”ÂÖovÅ€æaÍÍÅ‚ãU^”§‹¶bt-íy;WI»k›º:žÑ¡9u&øE£Ü!pg8sì´©Á­“f&:u5ÏÊmÔ }ƒØp›™Êͺ]QÃÁà ãšöÖ·ì­e ǥȹ,Ý%Ÿš£‘•½ãÒɬò)º *‘œ'˜`m 8ôc­^ÒÈ@§ë ÆWÙç)w½#Mö¼òW¯øöÝô‘r¾;=‘öö% …aq†Hg¤Å¾mMÝ_´´Tv|Õ^¸õ:7™Ëþùª!Uõ­–Ô¹àðjáfòÿåZcúÎå]Ê©ÞW“— m‹ õ¼ôM×9RýfðŸnP·“Y¿qÆên›aïfòÏ®ý–gýÂg—P@£ ŸS(§žg4È)ÐÍ-ÒP"¿ådÕøÜ&ßç¤43}6†ê(NQˆN2S#„A¬D:íéÉÄ6Ü*M¹r‡Û³æ æo ;ÓÚ¢ß6B趸£ìi…Ls„½Ü¦c˜{|úä \3eïºøpàk(ç3‘œ?V Ïrûí©è¨›Ú=Ðòà}ï í–[Ýøä”ãw ~Äò­âr´€®Ôš$lÐEMžêmj¸”8fv­]íVÖî-Ò¸·ÅéG´x”Hl5|œs¥ðÜ—Mø9r¦dv‚ÿù«çé“p”JëðåšL²>ú‚‹Å—ò‰ ¢B/<¹§—Lý-†ñ°endstream endobj 1750 0 obj << /Type /Page /Contents 1751 0 R /Resources 1749 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1743 0 R /Annots [ 1753 0 R ] >> endobj 1753 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [145.2796 423.0483 213.9516 432.4579] /Subtype /Link /A << /S /GoTo /D (the_category_phrase) >> >> endobj 1752 0 obj << /D [1750 0 R /XYZ 56.6929 794.5015 null] >> endobj 1749 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1757 0 obj << /Length 2817 /Filter /FlateDecode >> stream xÚÍZKsÛF¾ëW°r1Te"óÀà±>)Ž”U*–½ŽrÈfS)ˆЍ€CR¸©ü÷ížn€’òÚ®ré  1ÓÓóõsz('þä$6¾ÐI0‰’À7BšÉlu&&÷ðí»3Éc¦í iÔ7·g__éx’øI¨ÂÉí¢Ç+öEËÉíüïõ?/ÞÝ^¾?Ÿ*#¼Ð?ŸšPxß\ß|K”„þ½~{suýÝOï/ΣÀ»½~{Cä÷—W—ï/o^_žOel$ÌWÌáÀ„«ë.éé»÷oÞ\¼?ÿõöû³ËÛn/ýýJ¡q#œýò«˜ÌaÛߟ _'±™<‹ðe’¨Éê,0Ú7Ö-%?ûñì_ÃÞW7u ?£cßÄ*P©1Mâ‡ZiàU¹%WÙY³Éê-½mÎeìÙ´*‹êåùT‹Ð{\Ú‚¾ÕKKÿQ*@¾¾ úëÈ@ûq"Q>\aÚИ,Rú‰1Ї8FŽå¬\­ÒbN/yV¸•ŒW®ë¬ä峊þ7•;ÙŒ“hD·ÏÐð"Eº²sÓ#â˜ÐT¶â¡r;\mƈÔvÎ"ù9M¦:R¾’ ¸Ý2IµÝðR²·”R~,cÕjD j7q á2E)LäÍ–iqï$0±W—D$}¡°DùéúÛ—ôDX·´Øenïš{¢•M½nj"ßÛÂnxwðú¸Ìr;"= íq}øK_Õé¦Î ^½Y3| °TÜƒÏ ÞWÕYžÓãæfq€w‡JÄÆZ–¸“HÓj@gÕ,uŸæ w0”Xy× ú¶-z(¬åušð–®ë†”MüêeË‘ðBdc±c±jªº/³sJAùíæÁnèù1«—nÓ¢Ý,E1Ö 8äQJú*N’Ö¡îŸëPÀ±óxfcìÝóŒþÏj¢‚zŠ9#F»!h7ôJ|XXç&>kQû*0¨ÄÈO´Šo‹;0NIBg¿…͉F®e@=È©`o޼¬&ú Æ–ü|g‰KÞεAèÝ.æEZL½4¯í¹ô6ôÆá x6Y^O³‚'h Úa^.¥ô^õFFz×0t´,<À²ô°*çÙb˸µêÛEÚä<'/ïïÙ„wÇC×eVÔuy_n2[1ð<µ'kñeúÐ-ÔôÔ‡…Ó–”œB1ëIá+H‚BÀÒgÁÞ-7ieG ¸©ÀO8n0½u@üÙ½ÄÞÊ!$ï6:´ñª’>¸½àX$R*‹V‹$#’¹ŠH<âUZÔôT—ô©²<ú±•ȹá“Y,º&ø÷˜w'ÒØ-­ZI©”Å‹šhÈÏ™dB‘¾ò°h7,ôªµ‘q BÌ8«˜I¹ø ä‚òt7¾Ó'8ލ A & [ÙªJï-ËœcV\/Ñ®Àg{*×*H0ð"½)  éPJ—y&€ÑZ³ÉÆOÚ˜Õ_<Q«Ú¦èàÑD*iÖe4‘Ö¡‰ô”h£!í TAÜÊ @Äò1ˆ:€dQæyùØù!†ÓïòË.Ìfì‹X”üc$‚‹60F{{ E/,àË_ÚoÕ¶e¾]gÚ߯8eâÇq”¸å.Ð]Daô)zöÏtµÎ­ÃÊ,[¿¨èC•ni$¶Ž$R¹!Ûrƒ»ŠÉà^EÍlÚ¡)½R¢àÕ\Ì,‘æo ½ß­]ó²ÎëÔ³¢} †R q0w„‹i_ ïçóDAö~ÁimçýàÜéü¨þ(±uy 5°ÚþÖBñÛàÃ_NV¥ýDŠ`SX^¹A_õ§#ù«Wc[¬0|9°qRV,J6ÝcO£ÿ~5ȆV·SßAY‰ÙÈþFEÜ7Ù ö øÔžZu߉nVÙ!wŧJW4b"ÞE@ôÓbPÂ쇆Që©á¥ñ#wUp‹=ª¶62lc–ûà\̆6ÐÕŸ »™bzê‡\vö2äåÛÖ1ÇÃÈU/*Š`—Ûñ…Ü©i–§w9\LT18•¡ðp´=Îm5Ûd®VåQåbÀêðíÚî}£4è›UÊ¥.ÍÚòêeQ§Yáô¦ì¶0Rm­ÒmQØhæs;ÚÑ¢éL¿õ@ÔÎжò÷ût˜(˜h0’(Šäs:·üHD{‚ÿoV+Ö‚«CcK@óðâÇvÆÕ´Ûœ ¯Kîúr¿? µ™h©ý@À"Ç‹„$ð#´ÎæêÓ@G»¬è^9ÄŸ¨ü­èµ¦)á.O µl­ _°¼-Ê ç†r`øþ¸+tƒ½‹È.zàê3žVøvßlØ:‘ˆçù‘èxgm1V¿÷-'h£0T“>Ƨ7´(ã](~>Kš¡˜B¨|!¤:a *аÏå` VDþ3Ýùep´æÀÓÏ@¶ýÖ¬ùœÆ–sD¹=Ô>NûÊÕŸT¹:öE"’SÊ5Ž!ùyZ§wãGÉ¡zßt‰[Ó†Sp"H,èÂHtu¦ikDtÌyVãôôi7¨dK_î¶Gû0Ø×âj mßôúU=Èÿ- »g³tÖùA¤#Šî!ø©ÝZéóY¶3+Z…¾Ô&:¥h¨"Å宾<¥è‹õšÚLi¾‡ãÜYKtI¿K¬4¶ª«#Àö$þ8>/°2ðe,Ì)`¡4ŒÂˆËxN)'}½Ÿ{v];î6¥›ª;7u ³6fàðñÄ${ø)!þ H&ÂW‘8™dGI±}c«2èÚ÷‡þöæÇó©â”Œf5ˆôK¼Eмª™-ñ3uªq˜ 0Hàîbø?Xú–—åïͺ¢ïkJ£™KݶmµŠ‡Þ|1t”YžÑ‘¼ß`LwªÓü“hçN·ÔÞÇó Y2æò”caû'’Rž²êYqRóÿî‚~½I‹ fV{ý„~æhÛC¬v›=õ,–]~áÁK†¡¯Mr*ýˈAh†s³õ3€Œããðöäþ’á5‚SIWšÈOII—ùÏ*«›··×W?â~]ÎÊüx=©¾dðåArÒÿƒÐ:äÄêæIðÞ òãXÌýB¥/è§ÂÓ@™øX¶3â+?ŒôI[Ô/ø^©)Vx.½>Té©è:âiÏ-ÄË|äÄÅ3¨3 Ú+…Ç”y6Ez‡Eã_Òÿ¹…#ÁÊýÄ€–mo6÷ % {ixDijéÚýÇë¤ ¡«$<.3LøšTwó…_Rž‹mœã Aëi. àˆöÇ™}k.*(oÃöJØÇ&^â]pGUØ´3ÃP,Tû³ xªšÕ*u7|ðB·ÜŠÛñn`yO?6ˆ_«C>‘ö£¸Ãý #©Ø‡ø±áƒÍW¾FV$Ö±žËné ^›þ¥¤½–zgÝå™ù† iN`M7Ï:Ü•½@rWi8¸žã 7T;xŠ×1IÚôîiq‘Ñ+‡^²©‡§Ãq„ H‡ZËíŽ=‡ü8ÿ¬a8~$ãSQ8 @ÖuaëÇróûÉ qÃãøW–Î8GmO”Û] €“ c×:U±ýU–˜œDó¹¿Ûý@.ˆ|Çjüç]Z„~¬’Û|È A2òÊ£Tÿ7qxÛ¯§ï‚}¤ºß‘1ƒÞ®þ|¼¤endstream endobj 1756 0 obj << /Type /Page /Contents 1757 0 R /Resources 1755 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1743 0 R >> endobj 1758 0 obj << /D [1756 0 R /XYZ 85.0394 794.5015 null] >> endobj 466 0 obj << /D [1756 0 R /XYZ 85.0394 675.8841 null] >> endobj 1754 0 obj << /D [1756 0 R /XYZ 85.0394 651.1021 null] >> endobj 1759 0 obj << /D [1756 0 R /XYZ 85.0394 334.1307 null] >> endobj 1760 0 obj << /D [1756 0 R /XYZ 85.0394 322.1756 null] >> endobj 1755 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F42 1338 0 R /F21 1034 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1763 0 obj << /Length 2841 /Filter /FlateDecode >> stream xÚµ]oÛ8ò=¿ÂÀ=¬‚]©üH)oiâô²h“^’·»ŠÅ8BeÉkIq}¿þf8”%»rŒ"mT£áp8çKæ|©@%"™è$ "Æ£ÉlqÂ&sûpÂßùCª÷'ï®d° S²~ÎÃvŽØÎ¹¼íÇAûéñ¼ý‚Äå’,±: ¦¹Ž7T+Âãø~qÙÓ]<›Ù{3qä2¯ñgv-K³Ï=¡YH0î­ž´²Î¼&ótv* êÔM^¦îºÂÈîmèMZô&ÍúWÃ}rdÕ¨åÖÃà…–ë.÷»«pè=ö¦ÑE=õcº ü ò$uÈH×ëu`¾¦‹ea‚Yµ@uœAº(ùüÍÙèIíN¢¯oèyÿúõ~:6{(åÙɧéu_¢’nÄÙ˜ôN<’uoÒ!‰|’hÏïÉg-Ú:…/«º¡—eº²Ph3 Äi d]* 0tŽ®Kªc嚬2tW§‚å ìèyN)“ÎsZØz@œaÙqò•RÁýƒ`eEÚZ@ê¦äå˜&S ‹#sûXcªÔ'… p{rÖK| b‹Ã`ÄC›F A$$çÜ º{?š€ óš7&K?5Ù 0y$ý ¨‰x¬z;õÍjU­Žç`×åSµZt~´–>VmC`ŸƒqôD©C;si :ÀX¿ÎÁËTöó”æEK„‡sàÁÖ~\ $¯Ö„#‡J3€Hð#ÅY‡R`¨Ô,¯—i3{>^ž9BJðÀ mA!1R‚›sXn`öÅ4õÖïúûÚ¬^ºÈ±¨²¶ Ìôº›`Ãt—y§;èj7ÍveРãG9PÒÛÿs/ÈË•:R9†ŠÁ!IòUY ;Ÿ?É.ã–Š÷×vÔØT³ªøF±pίhv òº%P¬Å*ú–݌Ú˜ó#Š t¢©J,Àeûd»ÇÝÔGëße”8k‡ÊÚWRc­Q»­Kż…J³ªÄp:oWÖÁÕ4–—4èµQö¯‹[‹F¡ðFϪÓ§ç ÷7ô¤†B =কA­C±ኞ F¢bó\ÕîÖuj¡†C»"O°ÍÏêªhqC¯XMo;áÞhBÄ‚}Ï ïf4©%عëW¬†‹ ‘¹VS˜¹=M¿*‹ãœË-=$$dv’ÍN}­¸÷±š×4²vøBÑ¡çôÅdëblz2ñff´þ´.Ê£›ÿ\Þ~:Çœ‹#* ¶ÕU4£DP¹ò+¥ÇþF-ÍÿªÒŒ™Ž­Sœûmk@ˆbH×8®? †kåèíe±œá¡pçkºhÞ ˆM»"!! DlÚGÂlÅõ“Ž< w•¨³éj¶ä¡¼ÍîYXO¾+Kp3š2â@Äúˆ)Kl8„IÛóÐâg®n<îmjÌÔ +ƒ—•±ÈÙ)âÈNØ)QWDëêoå-‹4w´X»[ kÍA«¯Ùä ":`)#pÀT:&®„„ulI(deqÛÉÖøw}¯%8¼Äö'FŒüѸ>XäÝ]]€é8Bʃ|iYä©­$4õ&¨Ï/i±N75Á´rÓ®JÇMyW·wþØ–?MïðÛ…Ö´…½:_ä`²„´›ä”T'äàhMYN¦ÖâÌWÐMmCÑKíŠ~,c©YQhlCPïàÅn)Û2=6U•Q£ÁWZB’OT$Ɉj×d(†;¡· ¥½îÙÐrsCI?`¬áÁ³?:wöh¬ÜÔŠžÎá-+«hE6÷[ÀŽñNâšUå/é¶ :ÆxÞ€¡aûW9åJ×’DÀÕšô2KKlÇÖBnÈZ3µ ä”™w ëz´³óÞ¸‹ˆÆžÈA“…L0 J„ñ'kn€-ÁK“©Ö™: ;SŸ_TÒ´ÍUBù¼î¿15¤v)¿ÆYAÑah†ëÆ2¨õ›v+¾v=´=ˆ±õQè^Btm;7³l#˦3|§±O ±y¡f~\Y‘KºÚ™Ïš\ÎÔµ,†ßežà¿¬ê¼É_Ì~‹«~ÍVâP“0mZcß à“Z$Î=cCd̉KðHÇ;"€ÜuÄ«~ÄÀ¥]Ôˆ©Õ5â " !m7Em¡Ä´yA甇©†rîW9¿O²%œ-TÚº_©¡Q“ýæ:©Û~KÁèÎvÅ´©-&Ý ¶ù D.ÂX°»+0LwÅ×’yWxF…Ë¥mã=ÚŒúc2›°¿u#'‚R÷¤m‡¤Y|Ò¶pÛFc©@Ô’àU¾]µ Ž¡JÇ™1ï‹>À½¤Ežu}x_?çötb¾ý"èºûމ á}Ͳ‡µ%±˜uþz¼hïcÜk5û0ey[ôS+K ,”3ñë™Çcʬî>ÿ÷;_ ijGtë¶÷ofEõ9ùdM-.Hnû fs(YVE>ÛШMx-ëÎÂ@<±$â±^åÍ”dî°µ5']ß1òá“BÏùêÞfì;`Ì‚„©>ÛlÇ>J(Öàæ ')¤Æ2ˆxïšâb§uÔË¿­KSØÊbùÚïá1¾Í4  4ä?VAµÊØ6ؤ“ÿÍ?é;……ŒãA/VŒüt¤FV6ð÷?u 8,ì÷ÃÁ „‰o~ÖB*Ñ1lêÿþáôendstream endobj 1762 0 obj << /Type /Page /Contents 1763 0 R /Resources 1761 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1743 0 R >> endobj 1764 0 obj << /D [1762 0 R /XYZ 56.6929 794.5015 null] >> endobj 1761 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1767 0 obj << /Length 3078 /Filter /FlateDecode >> stream xÚÅZKsÜ6¾ëWLÕ^¨- Ú“âÈ^¥b%+k}q| HŒ†%9æÃå×§ ð1¢,{}X»l‚  4º¿þ_1øËW±ò™Hä*J¤¯W«lwÂV÷P÷ö„Û6k×h=mõÓíÉ«7"^%~áêv3Ñû,Žùê6ÿè½þ÷Åï·—7§ë@1/ôO×*dÞOW×?“$¡Çëß®ß\½ýïÍÅi$½Û«ß®I|sùæòæòúõåéšÇŠCÿÀjx¦Ã›«_/©ôöæâÝ»‹›ÓO·¿œ\Þk™®—3 ù|òñ[å°ì_N˜/’X­ðÂ|ž$Ájw"•ð•ÂIÊ“÷'ÿNjM×%ûIÆ}(±ZóИ+z~\ƒÁ¸¶È¥ðex<욋ȗ*‚M ØÇæ|²)Ø=B­"•ø¡„Ù•&íôº,vE‡‚.Á¤ ˜&R2‚q°éíVƒE%óÚ.mº3, o¯›¢Î‹Ì¼^ZåXàÞŒUZR‡ªîŠL·ôRo¨EçÔáHdæQT÷8t͹Ÿ(˜Ñ±›àÂKéÑvÍ)=îèÝU“´Ý×U‹š$£—²¾¿×¹­pkž™) |$‰]tQmêË03¶Q«¿€ºGR[TfþkæaÄçëè¶…W뾯›ÇSι‡ÞÌ8Ú¸µ3Ýé¶Mïi”feŸë‰ ¤·MÛ- ¾¤e¯I†˜YÛQMuâåõ.… šr•¬—ŒÍ¦f$‰ÙÙY›±{ѵºÜœ-m›þ3Óû¶7L¼ÃVWTnS‚ˆyhUÛoPŽÞ“º²wz‡v¢®5=©V›gNzpj s°BoÍ¡ ì"@2ø)¾ Ÿžr/³u· ”ufª0[i:6»´,—LŸë2}D— ‚Øë«®(©˜ÞÕ}GźÒTØUo‚!ƒo:0’ÛEª)¶]½oÁmÞÅÒ²Ë4{€¦ŒB d´#Ȳ´"á¶oœÌXecô2½à ·ˆ„‡m‘m¦vÑìf¢J¸«v-½ŠnK%œA 4ZXiÑ>ô¦Ø?á?Žkã‘÷á4&€2½UPTМf!ô*§ÚEúÂ.¸¸ÇŒvôÌõ]OEN´•¶Qe[o‹{ôVÈ.þÒ*oÌÞÈ)zÁÙ¥E•_мÇùâ;Mñs¯[œ5¶,ZÛßN‘zÑÓzôFM”5kÝ4uÓ.`•ŠýDÆÂbÕêeE i1 !ÉLsÉå'!c_ X­á'_MµOTºϧ<Æü0ˆÕ )/ä¡Ï#FæÊ ¼”í~­ïÑ«ià£Õ @¼ x‚ª!µ ¸}(ö{ té彦‚Á+ÓIïHr§“ 0]rÕ××ï,wÀßPœ/ ¢Ý<^Ù7øc[Ï ±ýÊæN¬öc;1nîÈz^¢QØ'bÑúßz¹‰ ‚| Ä*ˆ|Íé×&XèÇA­Ö*>WüÿqQI!Íö õä0C@JèG¬¬?‹Bâ².Ôžúl9X"¹¨ÕI`–2´ùR”©Ð<Žr€P›¦àÙîuV˜Üj’ÕšV9Q"— ¹"l¼7ŽŠò}ßìk`TçKw‹˜\[9p±±ê[[°|!ô¶õøP” ±ŠæØ5N ) 2«,ˆ*†Ž…ôeG•&ùŒrGò°Êå#ÄÍ,§T”dà †Ã^µErðÄ{7P,lAÄ4´ %£Q>»T#ƒÙÔ£8„L¾L¦éÇ$À§»­”¯“íRnzºÍ‚ûA82ùŠg¡Åp[óÈi›Cý$éQo*›Å‰°nŽ“ß tjÌ< £ˆÃÂæ£™FYëù(ïᨔ÷á j¾¸ú•¤…Ë,W[Ù¦.ËúþgL"b‰V‘ë—Dä<Žhù?B®XÞË‘±˜P¢›´(q,,#ó€™}x3Bb[ -°p8|ýgºÛ—ÚÏêÝ««ëW{HAjÇ7ùÙ9$R¶ŒÓ½º¥£AÞв®l©xÐß$Ԙ̾Ñ)Ä2„tçPÀÅnƒ«‡ƒð…¬Å^ƒ‹¥ÕcDbcÄÅ9½wÅÎgÀWmŸe°T|¤úùDùâÁºÑ€„´<Î`¦x#s}n[ðèóø ‡Ýçê¬úzÎÎ*XaÓ@aIÙ]šƒ’ý9?Kó;j¶4ŠàÅ/iI¥OÏ04k”L.‰™›Ý…E&I|7M˜,´nM²º4n ²(CëªS«"%Á±«"çª$£À„n–=;&¡‰hÛ‰”fº¥Kvš¸ ‡æ…9BóqIÜÂ(Ž€/†a#{¸ÆÃ5J§+iÁX*µëX»*«àiPa3ðXßìÏmÿA¡x,^ðWvSÀÇwœñ"ÚÃÑRÉı‘1b–ùi©dÀ{º"ãp|Txœq\!l4ÓiIHçEPáàý®I³m®½â1 {‹Ì£¾Ó:Ó”#!(K&±°8 G¢ì\ˆ/‘J¯‹0`®ŒÜªM@Äã‘vqäGPë9t½pÊAX”m†±¬ËœFq‹•.wH䄇ÂÀéuu¼!²vjç$«íw»´)þr'ª¢:Ò0EY”ct=¹;®Ü¸~$ÿ¯‹ð?¡ü8Tßsyåz<{È!>E(Æk ™Ó׈\JPÄ䌀}ãw3ʪßÝ™½Š,õŽ\j"M-Uu®ý‘³’L÷É]cò­þ~»^LéæƒLœ'OéÈ,–a*²ÞwUuKïê/¶hsŠkPŒ·€½8p4”¡w×m7²y È¿æ×ðföüÅætÌ7Æ‹M".ßsîz<ën*òUE/y‹ý$QŽZ!Åÿ6_ƒA_òùÏì1+ñðŒeÂF*Ù.sw3UMa>H •»º[üÔ3äqÅé¥X2~»˜-/„è“𥠙ŸÈ! òúxá'Æ3Q=ÝDá€f]T4‹ÁZšïÚâ3ƒáÁÑ—Ø!°BàaÚö döc\8P$,âÍоnÛ‚r}8ðvèFÀ  óMÜœà÷ _/ŸïÝ(ô´(<ÿâJ—O¦º¦§½vƒÒCe˜v!…B{Ç@š7£æå˲‰ ¾šUÌìÿ\ÔMÜùÇ"D2æGAˆŸŠŸ£W/üˆþÙüðO6Æß³HÀ8ÆÏ3[¸Ï€¨ -¢ð¬“¦?a1ßÖ¿ËcK)°¦ŠƒAÁdUendstream endobj 1766 0 obj << /Type /Page /Contents 1767 0 R /Resources 1765 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1743 0 R >> endobj 1768 0 obj << /D [1766 0 R /XYZ 85.0394 794.5015 null] >> endobj 470 0 obj << /D [1766 0 R /XYZ 85.0394 557.9661 null] >> endobj 1769 0 obj << /D [1766 0 R /XYZ 85.0394 530.3748 null] >> endobj 1770 0 obj << /D [1766 0 R /XYZ 85.0394 165.5827 null] >> endobj 1771 0 obj << /D [1766 0 R /XYZ 85.0394 153.6275 null] >> endobj 1765 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1774 0 obj << /Length 2520 /Filter /FlateDecode >> stream xÚÍkoÛ8ò{~…¿¬¹|K¼~JÛ¤—Å6í%éâ€\Q(–âkK©%'×;ì¿%˶»=„äp8rޔňßˬ“n;Í f4™ñÑæÞ‰€3n‘Æ}¬—×G?Ÿ©d䘳Ҏ®ïz´Æ“DŒ®³›È2ÉŽ^½»8;óáòä8ÖÑõù»‹ã±4<:;ÿõ”zo.OÞ¾=¹<‹ÄˆèÕßNÞ_Ÿ^Ò” 4^ž_¼&ˆ£fÑËÓ³ÓËÓ‹W§Ç¯9:½îÎÒ?¯à òùèæ#epì_Ž8S.1£'p&œ“£ù‘6Š­T ™]ý½#Ø›õK‡îOsÁ„4 n’3-Äî]i»†®TÌ!Ÿë›ŽwLÀ?‰ÖŒ;¾‰–=‘a˜NâQl³J*/’Ï‹/u^6x5?ŸÉ>:\Jlt { Þõ}·iUT.ç·ùû2ªîöy™/м¦AÓb.ŽEåu5{lñýN~.mVÈ~ë5N%7L)íÂÞY5O‹r€Åq‡8‚9c¤ÇÿwUælSØÚÄpÝŽß»¤ï»x¥¦@¹€ð#e)3ár,•a±Ο»)æyµiPD8J›u ‘í ¤ˆ™Œ•ÜgÊ1%yË=™áØrƒâÀ(õ‹šÚS8j*lmt›Ó˜‰½¼{~1§ÜºbÛHWÈèö µi‰­ŠŠò1ûZG*,KkBO×—³& ÝQ;«ªß—-å¡ Ä¨äþ‚ÔPͲ@)²´IoS¿9ŒþÉ ?yýñAžð¸‡ª=¾’ŒvLÛhW“trŸg»-ª¯ªß§þ›•üP‹âœY™ì‰dÖHÆÐÁk(A‘‹ÃlJiÙÙö½x¡Ep— ¸Õ²&ÐJ ¹ÇàE=Oj3ÒyBåxHT“jY6AÂÞSZÔ"ß‚N€CΊrJãUL5–Â¥±»¬„kõ晀¨ óT2ŽÞ•ä­ÇÂYÆu›\Ï皓֠_^y¡G¬Û[ÐáæUÆ+ko‘M´, ´4½Ĵ̆‚Vvóz;ˆ8Þ° ™;Ìœ¿zûžzÛ[°p 3ÏëA9Õéô™¨ÔWÎeCÇk¾†d»b§  Šo÷%ã$“ÆQq›f ðއÙWq ûhCØ.Ëü_Á¥ã¸ïsk¡ß«Èeã,ªPë ™ìˆ˜ïuà ])†7á# ¶á€Pìa˜ðh.ÅV¸ÞèZ”£KÓR›¯ÎQÅ9jOtß§ +Ó1K06N²]±[Á„eNË}[9­)Ve·‡8é³´˜-ƒD ØsÆ»IãPu¸ ^Á}ŸƒãÖç j/ø¶TPGqjX¤ ÷œMçz~¼ מGÅC„ˆíŒ@ïZœÎ—0øR€úøãWzGɽÃô¹ÝkÃ3úd]Ø :kÎÆíE@%ì“•”L@/«òVB÷éc˜LË/¡“ úÆ^F³Jä'•o³úîiË÷iàŸê55Ø5m²G©yÂL ±oä®(³;ÐØ¯TkiCÕeûÞ‡€D•–wŹ5Õf”„\{ÝÁÙ¶MüªIg”M¬Ê?Ê¿8º[gÑç2—Ó{,.»<Äw:¾—MQ•DâðÇC1}ïV‘þÝÿû=­ÄL+žWKó„njoÑ$!Á$qôúâêêôÁ|E“âƒìµ”ÑoÇŠHHw[¤ÚBagbŠ•a¬¶$®ãåáä¦Äq2H|â"a€÷®ggÅ|P ªúŒ¡ªÛA·l@.ÒR|j®’žWnëªÂ=žCaš Gš…m«rö…z÷éÃC^R¿ÊEƉcøfwX|:Iœ<£î==úQqõò¸ï)×Ä<ÞxÊü¶U-#Â:¦bðñcé˜6î?n=…Ê ’ê–1*î:‹Z»ÏöV%š9g(“8ñ/ˆ­+²&ÊòÛå”`³ü1ŸÕ&k#EMµ ð}1ÅüÔ4DÆ|E§öaq¡:ÀB ¦Q6÷UèÓ´kmŸASž•€ÝÕ鯦S_ÂÄ1ÌùœxÀ<»²%T;>cö½«ÓËcPÚßÎð('ç¿2*l.( Ô†ze>÷ðài9‚êåä>TSu ó×ïÞžœ_èêi„̡#4¥ÉÌ›tBósµ¯¬›L@¾QÂú,aù§IXwÖÃð‡rVüž·È¡“ÞV¡Ûê&¬åß |µÓq÷ùJ€] Îy4{Z乫&mò9}ÛÀOW‹t>O‡Š ' sI¢wÜNÇå4ÐðÊÍø*<—ý|¼¨é Qâk NŽ™JÚ4£^ç¸IÛ±/V”µä±ˆÈؤ*ïö°’’›®çr–ÿu(šJHôD¢Z{7=Îý{ñ¼2µOùk*uC³¢nòrŒ"¤¾)>ùÔØnªEÓÁqð1Ldõä¡›ÀA˜x1”¦Üü Ò¾a,¼ˆð/Úá€õ„‹üiÕû„8`U§ tç½Û¡„åÕ=¦nžŸ>çµÛ*³ª ²¤*cmÍxP²¼Øaƒ2;ž¨¼ ʽ6ø:÷EÓ9>2úÎôx‡ç ±9–ÄZì³µ„q×½ÇöŒMI©v‰¼MW¹9BÉ…C'TérUðùéŠÚtV·½I — )53{ÍSŽÿ °ñzº" ῤKJׯò|+QuœŸAî+•ð…;M-¦#ê\ö?lìq};—Û¤‰t•O·©3çb£dõBNG†ÉM&ð~–'£?QQ.½•h¶8ãÒ6k›”|òNŠÒ Tˆ6>"+óô un=@EsCÅÃlPk8$ÍZê}jc!¹·zSmjÚg¥7þ‰·\“5â¬Ë!Ý·AÄ*š{‡ðyŽD?€[·%¤ík÷Ê»‡|ÑùvùÞ¥çP÷*5$ÞôwÿÄbõû-‘{Jâ©ý0~.Âl<~ £¦ddôÖ™C*+õ_§õ’zendstream endobj 1773 0 obj << /Type /Page /Contents 1774 0 R /Resources 1772 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1780 0 R /Annots [ 1778 0 R 1779 0 R ] >> endobj 1778 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [491.4967 85.4256 511.2325 97.4853] /Subtype /Link /A << /S /GoTo /D (lwresd) >> >> endobj 1779 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [55.6967 73.4705 89.457 85.5301] /Subtype /Link /A << /S /GoTo /D (lwresd) >> >> endobj 1775 0 obj << /D [1773 0 R /XYZ 56.6929 794.5015 null] >> endobj 474 0 obj << /D [1773 0 R /XYZ 56.6929 298.8631 null] >> endobj 1776 0 obj << /D [1773 0 R /XYZ 56.6929 273.4765 null] >> endobj 478 0 obj << /D [1773 0 R /XYZ 56.6929 135.8577 null] >> endobj 1777 0 obj << /D [1773 0 R /XYZ 56.6929 104.6968 null] >> endobj 1772 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F22 1037 0 R /F21 1034 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1783 0 obj << /Length 1891 /Filter /FlateDecode >> stream xÚ¥Ërã6ò®¯Ð‘®Zr€àcsšÌxfÚ8³å4q¹h’Pá+dǻɿo R¤C;²]ªF¿»Ñ$Y‡ð#ë”!Ë¢u’E _õ*\ï`ïóŠ8 ò§TßoVï>±tYLãõf;á•aš’õ¦üæ}ø×û/›ó«3ŸòЋƒ3ŸÇ¡÷ýÅåGÄdøøðÓå§‹Ï?_½?K"osñÓ%¢¯Î?__~8?óIÊ œ§ŽÃ>]üû¡ÏWïüñýÕÙõæ‡Õùf´ej/ ™1ä·Õ·ëp]‚Ù?¬Â€e)_ßÃ" H–Ñu½Š8 xÄØ€©V_WÿNvíÑ%ÿq–<¥É‚)]r Ï‚˜Qf¸Ù c’ )Énô-M%•ß6ŽrÊ4b¥d T:×¢/¥‘§:QÈ_ eÜËo"ÔnqãâË]„˜¼,û3’zB)<y¿„<Ì›)»¶× 0÷ô>׸¡÷ÒÑËôh 11ÊÞíõ½0ÿÆœµÓ a$^û„çÔâTh«;Ñù„ze.jðÀÌSûöP•ˆÏ‹Btñxê·ƒPZánÛ@F±$ñ.¶HÒ´¸aÌ@Èjm˜ŽÎ*ÿa0é„&£‰¤ã{P¢|ÄÙÙ›Ó(àch8·°­¥Ö( òù‘怹—U…ЭÀ'Z*J\Y_À“Ð$áG'§´)>J‚Qrd,¡Ï§\”Å._H6ý“¥dcÞ­lJ…à l– Ì¥ÃT` gÄ;fƒÅ= <`ÆÀÆíŒUÓÉ$;Q/¿"ÐäµP>¦Z'É<]^ã;–zʰgñÔŒ;~8½º¶Q‰ @ ~…‹[GVÀ¾îÏRïP`¤gu³\‘•ªó¦±vÂv®—ã£iû:wÜÑ@B‚ôÃQ]ìe³x/g™õPF=ÓWCbs•‘ÈÈ@“ 2‚ùmÐÇìd,DÍÍv)¶ù¡ÒHƒÞ7ÐpÊT…9B3Ïö »7Šèù Sæ9ç ŽuŠ; òwDo™´ý(xf4^Jº—»“V>*¿éº$ÊÆôy_쪀‘€FQ´PQŠ "²µ,ïòjÄÛÌ2ëÊÉÀ3Žy›hw?DÓ<†îêèß ]¼ëmq¨Ûâh¼NL‡ 3ïB£îúþN–ÂY™ãÃÝ'µ[¬4£„fóÀ”mCGp n/ÁFìlCfØE׉¦ÚœõÛØ «\Ë;Gg Aéz¡))ÔËBN uæ6e«ÕRÛ6iF¼Î1÷)çó€çÏ{Ò˜ó¹ç€—,ÿFø¯â!®G¡ïQnïÏï–|êD0¥avtmt‚k? 36RËaÆÂဟU¾[*g𹙢tæò…þ õ̳h2×ÛkxyUµ÷nñr£¶"`]´µ ¬„FÀÖ u}0ã‹–]%¡ôáÖiÓ8ZUåwŽÙÛF8e±ñ€›5³º‡!ûQÞ§©3ýY±ã Ú.±qÞÁ‹y¥Z¿iµÜ>,°ã$H">óøbú„ÚWFºPÜ%MÛ™”8¡)}2768›KË=]S ½cãýö¸»ä&Ùˆ^rŠ-x®ƒ,Mì“ks”1ë# Â$ʆ :GùÔ¯p4ŽmLõT⟠,}š…Ï’xþB2úÛŒÉ-Ȗ̼ÏRëRäZçÅÞ/àÏ53 Þ]‹¸^š…Ýqx±P¶²'‹Úa–^>M¦§÷­ÒÇ.:¬ž=?“®D2}YN—7²S~'ZÙù/c0“ ]ù-Çáuúgéå¿Á›Œþï[Ñ¿\mlØ)•wÒè¡óÛ·ñ(zQBEIó®fù@ ÙåÕ vX>Ã|ccká—hQî§WæÍ15ÍJç§$”­++ñòH”‡º;ýèL¬ù^`áuÇ•(ú¦ÈW*®„2…oRàµòGs§¿ü|^í\g«vm/õ¾††p‚ µ¨MG‡;M®{>uÓö7M{J5N¿2 ,_(þôÞf÷ÚøŸ¬úÒb¸ãÍW݅Ϲá8¼ùãññË:Ì¡,MéòwaÂ%M³dPÊÉÍÌJÐéÇt˜Oæ‰5~€þ«Uÿ ÆPWendstream endobj 1782 0 obj << /Type /Page /Contents 1783 0 R /Resources 1781 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1780 0 R >> endobj 1784 0 obj << /D [1782 0 R /XYZ 85.0394 794.5015 null] >> endobj 482 0 obj << /D [1782 0 R /XYZ 85.0394 592.1738 null] >> endobj 1785 0 obj << /D [1782 0 R /XYZ 85.0394 567.8276 null] >> endobj 486 0 obj << /D [1782 0 R /XYZ 85.0394 499.0441 null] >> endobj 1786 0 obj << /D [1782 0 R /XYZ 85.0394 468.9236 null] >> endobj 490 0 obj << /D [1782 0 R /XYZ 85.0394 424.3652 null] >> endobj 1787 0 obj << /D [1782 0 R /XYZ 85.0394 396.9903 null] >> endobj 1781 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1790 0 obj << /Length 1169 /Filter /FlateDecode >> stream xÚ½Xßs›8~÷_Á£ý ކ˜éSšszé\ÓžÏ÷”Ëx±ÆB¢’ˆíöò¿Ÿ°ƒï u:@Bßî~Zí®d–úÙ†ç›~àÆU06=ËöŒ0XƳû0°‹o@ù¨õ~>øåÖøŽoÌãÖÄ´&Û˜GCßtÌ‘B°†7Ÿïoï>ü5»]‡ó»Ï÷#àxÖðöî÷©~ú0»þôéz6öij‡7¿]™OgzÈ/0ÞßÝÿª{ÝœMo§³éýÍtô8ÿ8˜Î+[êöÚ–›òuððh‘2ûãÀ2Ý`âkõb™v8F2{®é]·ì!ƒ?T€µÑÝÔVþlËt\ßi!pìÔœX¦o)¨+/0}×qw>Œ€oYÃoŒ" $”XH Ýg„è§t#¨ÑCÕ¼wúñ1'CilÛ <Ï©ÃÃL.ÝD,˜ê®- Æ”1=BB‰£m°< Ãn``H²´þ¼`©ÄŒž!?†+ð× ñmwåc$Ã%x&ê®tL2±ùâˆÜr±ÌdÄÖ=\B@"Œ¨=˜GÒÅ”ÀMáBYò„ø*$˜âÀ‘H¨‡IF$N !… êaeLJNÐØh“–Zt&P¨½£–lÏÐ’£0ãB¹fw9R^šÝg‹”“©ÀQÑqè¸ÖÈmŠìîÓ3¡¶XRÆHwÍó°"ÕàMÌÁ¨»»©1g ˆp#ŽhXzÈß–gµ¯¶^ØF— ð©ö9 B€(|"=ÂC1ýAY9ÌiuUfÝT#Œ­ ò´‡ÞC•Ø9Šm¦Rïª FßXQO’gÊó —¬ ³>z¤3h×Ô=É!ŸT^Ë÷:F픂4$ C”J•‚RÌQÔ# 3¾†<:$3 …Š1ò„í'ÒŒFVZ¿×MéÜéFQÁìCʸ¬úó—Çb aZ ä/Å@!ß4ÍR‘]ózq™ Ù*î‡+µü¥Ò¯»ßwR× òÒªÁîžI½¾‹<¼÷•Sú³6¥aSoóE,©,ü·¾â·I,hµ¹à7\"Em-í¹8œ=e6Ý;[ÍÎÍÊÕhÓa!nÖŠø™2ŽNmßVø†EQ–ªL2ÙõƒÂ­ÿà1Ù¼•°טDa ºD#=_å<ô̱ÜvC¥µºú‰6 þòóeâ'‚és_–Dÿ¯²=tË4k@ÑZ×÷¨}½_χ«Õ§V°‹ªsÈ‚à2¯¼žA€­|úa:'0AY±\6„jåÞ‚|yµ%‡TÄe¬¾ìÁAâb\T¸—g"KU%‹Þ%R .ÀG¬ÅJ¬z–PÂŽ+íòpspñ’ŸƒUØés aªY¡m®ï¾ðìqî F GìW§ŽúF—ç@2…S/Õ‚à»ÇS·m®gæWd-wcVUÆýðMÜþšr|eº“‰S]²9NË-e¡SnmíVÑ´•`ðe<¶RÊzþ‘MåeÞ±QÿC*°kendstream endobj 1789 0 obj << /Type /Page /Contents 1790 0 R /Resources 1788 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1780 0 R >> endobj 1791 0 obj << /D [1789 0 R /XYZ 56.6929 794.5015 null] >> endobj 1788 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1794 0 obj << /Length 1199 /Filter /FlateDecode >> stream xÚíYÝs£6÷_Á£ÝéРéS.uÒÜôrW×}r=ä F`'¾ÞýïÆ`cl7}h'AûÛý­v¥e4]ý!ÍbP'œj&§éˆi΢§kŸÕÚmï€ÍK úÖÛqïÍ ±4¹ m<¯`YP·,¤ÝIÿúç«ãáh0Óûfèý·w÷?å3<ÿwýáþæîö÷ÑÕÀ¤ýñ݇û|z4¼ކ÷×Ã@CJnî~æO·£«÷ï¯Fƒéø]o8.¹Tù"¤D¾ô&S]síw=n1íI tˆ8ÇÚ¢GŒ²™ñ{¿õ~-+«™h“ÿ± ³°Ùà@Š+Dº9å¦f2 ‚IæÁɺÞO¢5HœDb‰ø!Ÿ\‹x&£Y ÌÇÓ”¯R ‚œ1\°}_>•âu<ˆØ‹óù¿Še×U¸ñla'ÎÃÌ÷â$ŸÿÞú“o;Òç ¢*b cÇ8r¦ 3u©@W,Ý„2JêÀéLG<{%=÷\D´g¡qq /ˆ˜¾- ƒ|8ÙåO^8Û¦ÅKnì„år:˜^,XJ{Ëã&1&…˜@ž 5Ö,lD(Ìù²*‰c¹Œœ"SþЙ¾ûä…t–êÊGß2TdrH°É,4)¡êùR¡§² °PÎ&$&¦nÛz§ª¼²u…n¤N8“¢B7;¤›muWüfaÞì‘CAñíX<çûÐÊmĄԢ´ƒÛj¦S)áÆ¿ã½ 6:õÐmc³L£æð4öýÌMˆ wOu5úO„§ñxžžé¥˜…hJ@ÝbÒoU¡½/å«Wa°\|Q‹›obºv"¼ ÑÊö;b-ìgDvÏEo!€¼ ŽCÈerŽžë·3ãˆVfÔ¨¨œQN®:‚œGÑyc"á,£Ø[©ŠÑ÷DÐY>­¬[KÖ /¤@¨¸gáQ•oóÃ.¼ Ò\¨òDä(™K£}˜Iz&¸‘ 7GA.i{~šÐÓ¬3-ÊJ™Ø ´#{ïk™{Ï ¥JvãŽä¾Ê@œMª†®ÜåÙ~î{©Ìî yOœE!«–¢«ø&ÿæ2Rêîѯ|Ô O"ªygaëb~{c¡T7êâì´@øSãN«­lA×d-½´[„·(º«w#ƒÜ4æ«qÒå«£áÜ-ŠðµJíHeF^™Ö ÄÄä è´´Ý:©J‚^œ‡1ÖI $^Ü ŒD¦n¼öf`"jჅÕÁ éÒ^ dâÍ×À¾½Þ‡Ž ÜøØáŽZ¥æö»¶Ñ“ìJM“@B9?怶‰¹ÍòW=\8‚8kEfHEÂÞ‰€Ö»hû±9R­Á£¬Ê|Jr Šv+ýÎÔ&¢Ð¡{!JʇÃtcƉÞ<¬2û!¬}Õ{C`‡÷^-ï=Ï#àËÏ ö¾ŠŠð?UìªÙЧO³8N¡©!NL»Ø ík½ü<»Y¾ý%ªüµ,\öÁqµNtZ˜›£R–ÌTe†2W<€HÙ>Ò]ReÃ}ŸÕß xæendstream endobj 1793 0 obj << /Type /Page /Contents 1794 0 R /Resources 1792 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1780 0 R >> endobj 1795 0 obj << /D [1793 0 R /XYZ 85.0394 794.5015 null] >> endobj 1792 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1798 0 obj << /Length 1069 /Filter /FlateDecode >> stream xÚ­X[“¢8~÷Wð¨a¹ ÕON¯ÝëÔŽÝë¸O½–•†¨©À$ÁÕÙÿ>°µ¬˜óKÎèŠ_]±lÕv W¹sûª¥é–â…MY³§ŽžïAÅ&TÞõiÚùíÑtWumÃV¦‹–£jŽ£+Sÿµk«†Ú­ûð<~=ý=ôîúÝéèyÜC†¥uG³O“Á—/ƒI鎥wþ¼L‡“ì‘c|ÏVÜl8:>'Ãñð7›~î §{]Êúêš™*ò½ó:ÓÔþÜÑTÓu,å_˜hªîº†vú–©Z}Ó,V‚Î×Î_{ÀÒÓi¥ýtM5LÛ¨0`ß(ÐÑT[¨;ËUmÓ0w|í![Óº^ĉ ?H6KÿÍEL¼lzŸ ³T[`‰t]u-Ë(ÓûXâ[è4 ¢±^&{ßnáî3Ê–ˆ2IøÙ2KÂ7ÂkЯæò`Ùà@ƒÙ{¤­`I…¤žh‹ £8 ¢å6›ý— Ø÷Á/Ä<ÄÒ[Íà­ÿœÝ_:ˆË÷½M¡¤â\‰"î~€¶[9=ä׋OUU-ìP~^ À!AR6=Ðoó°·ªIlßBû#b'¤õƒ‰.xõ©ÜVúRnél2«c).üvaÆ"¿ˆöëÒEIG,^J?%·1i%OHâQ$EÃcJ„úf‘3Ú1øœEµ…y´¦~%F îœ|Oˆ-©%O3ÇHÄ´Ú*±3YÀ®¤aˇ¿d'‰äÛFú©M!¤ˆ!oæõ ž§“:…Wxñž&ì#ò¼¨Š©¤ÃZð(D8‘«gh\ÂÚå­¶`30|²¦…WÅX®æ ­yYö¼¥%Ø•)â8&>ÊkW‘hš 46B†ŠZ÷³å4K«´ÒÿÙð1ö ù ˜z{ ½†öÇüìçwN¿z徎O3a÷ §^Û(†ø¦›>¥3LÕMûë* x%¬HÈ MæG6^øä¼Ã2–,öƽ€µr°ZeÀK¸ kžl›ûö©ÓTS£ÊãÚ+wÍ€&¤È£ï¹àª !/bðj ¯V² œCÐ/ƒ„Ïà hð9X?‡¢‡€œ(ñãRªjÔéÕ'=­U#²‰¡Ud² û´ëL%NóÉ….8zz%÷>hÃkð„®…oá%¥mÃáSß‚p°Œ8•«0ÏPt0e‡!YlɼS·ïTóÎ0«kàûÞ£÷Šr\„($óòéz³ó’eÏçiËZ-Û‘Ê¥Ým¥ÃY=%,•ñªñ«.DLKMo1*®/à—3¼ù²äý&©Ê8ޱ¿1ŒŠ‹¤\¦TÏÒŪcôõG¡Œ®åœèTÜ·œ*õ €Ûõ(endstream endobj 1797 0 obj << /Type /Page /Contents 1798 0 R /Resources 1796 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1780 0 R >> endobj 1799 0 obj << /D [1797 0 R /XYZ 56.6929 794.5015 null] >> endobj 1796 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1802 0 obj << /Length 1394 /Filter /FlateDecode >> stream xÚ­]sÚ8ð_Á#™9©ò·=}J[ÒKçšöRú”f2 ©-9– ¡×þ÷[Y6ØàPB:~´Þï•V»²†>kz˜8‘; "{Äò†q6 Ã9ü{?°jÔ ¡6Ö›ÉàÕ…#ù¶?œÌZ¼BLÂÐN’›ÑÛ¿Ï?OÆ×gÈöÈÈÇgÈóÉèÍåÕ;‰ÌðöÓÕÅåû¯×çg;š\~º2àëñÅøz|õv|†¬Ð³€Þ®9¢š•â?˜êÙÊYl–G²)X¼,—%,/mEñ±žæs¿dgêXN;)pÈŒ§ Íd‘ѲÂuÚ$èR|#)Ùcù³ «ŸÍamõÈA;ÄÅY–—k¤ Ž‚fìhm y,EIãòdúR0…˜ Ó´&]3u'‹;!Ž@•&G[Ž®gwÏÒé+$)IQY¦ÏPèTmÖS­+˜’)„¨ÚZkTòŒÉeyÒK˜X#*Ô ¸Ñ$Ϊ٪ÿÕGÔ@ï`óÅ‹»”«ZÐ/34¡{Œá¸ Y!³µöõÍíë£UJ9ÝU¨—åQ£ãä¼`3&ï»õÆ,nûl;8²ˆÛ‰-JyÆËF)k§"œK–£¼ œ©ä¤øj#Š‚¦/f$dBKz—Ž]â1‘åâÅê€Q²x1š¦/µhÅE"W'IOåI‘®OÍ)÷¹B*¦M–|¦â<p‘Þäü¥LÌ¿ëì6þ`£RžŸd{Ô9*ÎD ‰Â²N]GVeu“lëŠç^á\Ïõ&…_Ï8î&o \¦<^H7†¬ïf<[Lu¹1çL˜åÏν›t€9Uª\Ë.f!ó %Bq@…ØU¯IJ“‰: x{¥‚mñSûµ—ýÆiU©öÀž>¿«öŒg¶B;À½ñªcyƒ1î¼ÝŽüsmXü1ukÚiÁèw”(âcü´w ñ'²T¿•ÚÑø^G­(/몚vlï¸û «_럯.lkã>è^@#à0¨/tÝ«Y>dÜd^B}¯Lkö¥„K>ƒd–ïØ7BlÁ5†P}ÁèÉWE笖Õn”tíàcߪ;¤É‚mjuSÐLE‘ȧÑ`Ÿ™œÇ«ñTK9Ç)¦C gËÜŒóTNu×¥ç[³`QJ=º£)« ”>Üz6]›Q·½ØL' ^“íÌhLóœÑ¢–Sía3‹Y}L=­¶ÕŒ>ÿŽï¨‚\ÕÚ·ó%”U•wõ? Ièá{Ñèrf€å¶—Ž˜!ÔÊi0l˜Çú!£Èú½g˜Bÿ´ãÙ¿€wäA”¬µÀi*ãïfºâú‚ÔŒÆ 3¸f¡1¿µã5€—ªÞ´ÄÇ¡…Ý#’°]¦õ¦[ñ45³*\0êpá½ç‚‰ZCßÃŽM¢þבµªÞ¾ã´æá¡AÒѺ¿EÝàìH¶\‚ßòŠÞ íËî¼+¸ð×µ£Žðó4•+íõÐeàžëêH¯8k~T®…Q-èf{„f{i(ó†¨îÒôTß9SèE`‹@36Ñ«›Ù‚V‚*fD®D›ÑÏ6އõ[K/È&½øIgûÞåØ C»ß«ŽÞev4Ji§z$> endobj 1803 0 obj << /D [1801 0 R /XYZ 85.0394 794.5015 null] >> endobj 494 0 obj << /D [1801 0 R /XYZ 85.0394 167.9316 null] >> endobj 1804 0 obj << /D [1801 0 R /XYZ 85.0394 136.1469 null] >> endobj 1800 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F21 1034 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1807 0 obj << /Length 3143 /Filter /FlateDecode >> stream xÚ½Z_sÛ6÷§Ðô%ôLˆ A‚í“í:9wÚ4çøîÚÎ%Q1'©ð]çæ¾ûíbŠ” '™ÎÜèàb±X»?ì.%~b¡–d2[¤YÌj±ÚžñÅè{s&,Oè˜Â)×åÝ٫ב^d,Kd²¸ÛLdiƵ‹»õoAÂ$; <¸úõíë›7ÿ¸½8Oãàîæ×·ç¡TqP°Ó“ Ò ¼ÙíÏ8×lDÄ™Ö\,­X$ÓìkàF²Lkí›p”NE$™+EL':ÛÏŒJÏõbÂø¸{ë@ v8!á8Ã!­!ÒÒ¾»fxªið¯û¢Þ÷X—Lù¨ØÚ£¬BḺ¢c!±«¦F%? ÖkI&À@FG¦”)˜ Óˆ0 ôvÆ”]Šf0¤¤! šm@S11Òˆì¿;æ¥æcÙß[ñŽ4wDåǰ1#_ÛÙùŒ7šV³ùºbŽYtÿâ"F\2ûÃÐ;¹±jC´;Ø[ÀÚ8+&c¨ùXVµ:@Ïêi:~cN6òÊîÎÚØïÖÚp›0Rí­ háyo·ˆmÔvgŸà!§ÅçäÐð5ÇGì)ÍP­©¹,æcóªjÇ&5ÜÝùÅ)&×Ó8#óÈÝx9Ð…‡WˆÝªuSóKÅØÈæir³xÝIÅpdñ·àŸC®Ü*“ÓÃ"ìäòrgOö Œ–’·Ë²oóÖjŠÆkQ\®ˆ_f0zQ7 =r¼‹q³d²<¨÷ÉfÃáÝ‹4±RºaÙ=µÑbM—92 ¸#›H˜ ¤^g@¸pÊôŽfÔí¨ ‚<Éìs¼é¢Táв¥fóhift:€âàuc»‹?sð Ä‘c‘Í8~T^óéKOoöÕ-š/éyiŸ&àÁÆÕ!¡©Ñi͘ƒžKßòº{ò šOÁPSL¦Õ ³Ø™*uœ°Ó8…Ûí¢‘ÄÉatÒÍîµ°p¨Í²ðñ;WÜ (ð\‹xÑQ ± ÀeÕnhÐ> á ±š{°µc‡Ž{ûÿžVOWá6@—‰–3†SaÏwßQã?fB7Íì^½" +±µŸ[RÙÛ†±¼„ó}Lrx®ŒYG=˜V÷ß|c&_þ5[ÜrKÅýÆçÅ‹î¤ÎâØVÜÎýà]†üºe\=· ñÝø©ÆNzíçŸçJ.«Ë@¿¼§Öèà5§Çt2ÃβºT0s©`6¦‚Ù$󃽶Rö÷.!7òå-Œé 'gšP3æ&kÚ«Þw®61D|Œ J"¥ƒÕÐÒ:j§2L×*“]¸{˜ˆãÓPŽA röNƦÁ{Ãø6ÒÔâÜÙMmÇ.‹‘·+»g÷eµŠ P)lÜM|~ïA½L2ÈèŽÁI¬>†ˆó’8K-ïK4ýxÓ¯ª"¯a…aYÃ<Œ©ÑTdš²S/ˆT–a]w]± óÕªØõañç®l½±y–1¥Õ·ŠËuîìÃúgPø‘a,²Âmþ'CØ÷¾H ÏâQüŒÜ®¥1Ï@qõ³òÈÛxò-òH\W~ö]t‰fÅïõ³aÖÚ—çB i7õç¢mº »&?¥*‚’N´‹Ï2ÐËyxö¶éMh;>ŒGbëÒ@_Z‚ è€4‚™; C⡳Á¿6CGŽ ,ÿà âé(ô4«žø£éÆüÈã˜ëÒbÍ; cøQ-Œ×§Q|LQ¼¢(~‡q*màÄ}àÁ`£¸K00Ÿl] àÔ¶ã„rÇZvÈrZp„>¸|$¥×´Ïw ÊeH²QéÐÚwßÄX÷hÅ[ÝËlÚ† {@ëÓÙ!…Mà~ûŒrÆNÒì„MaÅBÈï;§mþÑÄ‘0KQw¶IÜž.èäAñ`ÊÚfHoÝv»*<¸hoz¢š„J‹ _oËì’ ”–FÁ ÛcoˆÚѲ¬ôû'ꢘ&«»aâò£4ó+ìmUØdª´9’gërêµM—q§lRh¼„Fwí¹fıôr˜KÏÊÞ‚¥B$)@¬Ð'ÊÔÄN¹¨J-i-È}pL õPhŠ­ýŠq¹B³$pBÚ ä $ jVNMè"ÿ‡Æ¶1ñaÓÖœ£ë˜×fèwƒí¢EuîEñ‚}`žÜç¼L™µƒïîWK3íjɘ³=#öwô´%õôÄ:#-ƒ› 1ä>¾™0r¶4ž–à^’×SÙ ºFkòÊý1ûÙÁàðþÛ³QA ÈÓé=|¸,KSw±¿xIˈEi¢æ&C‹Cµ¢Xú¨±%Wz…$Ç2ªé'X¼o{S¾… ÎYŒg1¯Zy¶J€K;Î\EÐ7:<ÑN•€˜HÊ$y¨¦\§jä2_Ц܅'áJ@|GpPÏ*0ry4˜äl±s ÞO+ìÌÙ“‰²£Ý†>À,/¬Áû›¢¹yç«2h,•+g? bl_¥`SsWêŸ|YŒôħA‚ƒq>Ó-úÂ÷Ïù䃉„ØZr}P\¿4W«ž|¥”™v.¬³I-GŽ6Ô¦¢‡$úb§m*‡«6M­¾í‰ÁV¤L—&ªri¸éæ×Ár(«>,íl^ðÀ¨Qìõ‰¨+|Ugãò®ð|çAnÂs‘H´êl?,¨q;5ÇNøÍg.ר(?Æøy]é£!IJ“h¦Ï±;®/i¡!'M’l®E¾l†þ¹štA»dθß"aŸ-ÓÅÕÏÌ ÿ)P`ä±ø(L¸žÇ…,žžãçgwLžÙg{)%SJEóéék~”Ù-¸Þ–Ü"<ÁY®¨sØÇÔ¦\!k\ û‚>7ua¾¿ÊØ•uø®éq’ÙñlϺ–•›Ïf p q<$=¿Ìwmù`ÔÁ[óÇ·ïß__QûcñDQL ?Ö’ÅÌoš¡¦{75™öù"fs-çõô‚Æø|Z"BÂþÆÖü„£saÝäºOwÕ+åÂ*X…TSóÃFÝPg±¯mºc´û›KÎŽ± P¤ñà…n7ñvÓrvƒ¹Ê…){BŒL³ƒhò¥eY¯-F=³µÁ‡·ü V2›hVÛhëõŠá‰{h12´ׯu2þ¡+:, œ—(–ª±ˆãÇ ëÛ‘bøŸò±ÿ—ÿø³ÿW$#‘Ö'Ðó@'s;îÿÄÄL¾‹ÏCJÉ áÇØgÿ;t¼¨ÿܼ¤©endstream endobj 1806 0 obj << /Type /Page /Contents 1807 0 R /Resources 1805 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1810 0 R /Annots [ 1809 0 R ] >> endobj 1809 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [130.9538 140.67 187.1725 152.5702] /Subtype /Link /A << /S /GoTo /D (acl) >> >> endobj 1808 0 obj << /D [1806 0 R /XYZ 56.6929 794.5015 null] >> endobj 1805 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F54 1433 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1813 0 obj << /Length 3851 /Filter /FlateDecode >> stream xÚµZ_sܸ ÷§ð[åé-Ã?¢HNŸr‰“s¯—»&ît:×>È»²­É®ä¬´qüí ¤DÉÚõÝu:g)$!%Î9üçV3®\~n\Î4ú|½;ãçwÐ÷þLžUdZ¥\ß_Ÿ½z§ì¹c®Åùõm2—eÜZq~½ù5{óÃë_®/?^¬¤æYÁ.VºàÙ÷WÞÅÑÏ›Ÿ?¼»zÿ¯/Lž]_ýüÈ/ß]~¼üðæòb%¬0^†Ž xwõ·Kj½ÿøú§Ÿ^¼øÏõ_Ï.¯‡wIßWp…/òåì×ÿðó ¼ö_Ï8SÎêóGxàL8'Ïwg¹VLçJEÊöìÓÙ߇ “^?tI¹¶L˼8_©œÙæXÔ2g\ƒÖVF;V(©-K±¤åÈ…ZÞ•MyWmVŸ«§nµ©÷Õºo÷Oó—N3at2vIŽkA™"9(Dv*ɧ‡j]ÿ›sYu°Êfý}… “XÂfA4ßW7ôûx_¯ï{KÜpyöÉ,6é·4·jÙ‡þ}¹þLÍ  zxûáÓ§Ë7¨ˆó•ãL ná sZK//j lJ °Ê'2Mu[¶ýwôÔß×µâ/ÉÇvÿ¹nî¨Éë !2æ—å°ø·Æ¯wu‹ÔÙžŠ°õܳ4åÄ'®Tá`<Ê&p¡4*çYÓ‚ ”rÙºmP9w’cCݨOì=t¾ÖÕcï¦ ‰oÒP÷ 4dAù6¦¹ûjÿµÚSïc½Ýõ¦"Šß†8Mæ.IýyÎr•ÏÔßþ¶8¸0ak©½.·Û¨„KŠ 6ë0fß>¢÷t`z(û{2³”7XÀL©2×L*U¤lÐçLî1pH MlèÁ‡­ön_î0«<»jÈ#Z°™CãçmZzNÝnRsÔÒâ·H¤ÁDŽ"„V¡¸o³¦ª6ÕÝBgÝêí¡YãÆ•ÛºJ¸ìæPoû@jú st¡•„¸äæA"úõhÞwŽï!õ´7$\'Ü!r¡=8éê®ëʇCk_Þ<ó #˜*ô 2 \ BLB4X„Ê‹™×ÞE‘ýøñ{M­ ŒoÇ´½uÂ/r„ƒ (ï?}Z]ºzú6`.xàknñ,¦ÑäƒÐ|Ú‘ÖU=ÍY6›Àê¡M, –sžOM9hnâªéëct.É4rE§66@`‘y¬‘kðHÆž +=„(3ø(”rˆÏ@|¬ûû@nžˆ2eWöë{‚)@.‰ø°¯›uý0ˆÖ<ß»ÔmÈ8iަÖ㎧ 3å:n˜×Ü0×ûAµsㄱ&AŒÈ´ ÆÄ45 àv"‡7Mè‚í[öÞññi¾ãH£­ñ-B¹ØìÇñ§|û¾=l7Ô.ˆÍúzÑÍS“`‹ùr¨ºž ’ש1…šîš?´… =Œ}É!ÎõíºÝ‚CHç²7‡=MÞôÛ0¸m¨e³«ýMEc:êÓô“Èê™ëÀR~-ëmy³ xJdrs•-_„ÝÞrÝ\ è˜Ø²’‰©-ª‰ë² ®¿ê!ÉÈQ(š÷p7R‚™Ÿ@ñ;ê /"E£34í~þù´‡ø4Þ¿ªúõ«ÏûÍÆ8;?ç5+r‘'ð2aŠEžmÛ¨v|â#´G8Ó;«B›g-¨c_o6Uxè|„Àf§^> Mv‰"'H—Cû߬*†Wéôd§à1’="u:¨½w4ößRæA‹.Ű4Ä­!Ë{µ k©˜Ã$Ÿ˜Èئݕu³ gc˜á6B\Ø¿M‘]_8™µ$™?`°}é»ìá$ÓJÆ™’Ó"çšùBJª¹£ªTÚÅiv‡.Ø_¹íZjÝ X!tÕ·£¯ =Æíu¶§Ù,Dé$á0AûfGC~'¡‚CõtÈO¹Ž‡ükPߨ£IœÏú…µ#ÓÂÚ“8Ÿ[&”œ-Nn¨-àÛåÃ?¦7`ë€u„ΈÅuÔDÛVÚàqM„î¾tx¹&´îª¦B4»¡~ž—’lˆG³¸þñò_ ¶# ŒAø'¥ûø dʢ̓gMbÒz[C4Ƴ¦HÏúh:“ `^Ž*;-’cÜ‘©ú¶¾/›;19€­°Þ®|¢F»§å‚·Sl ÙŠˆ!©›ª«½z~¤E" ̵©B¾,<D2ˆUoÿ]Èä9gZšbê±´Ï΄5°å·Ù™±k²ÍÎÒA¡¢à|EáyÌ…f"w1o‰{QðàÍ·5ΈúôKåÐsnu,ýya h9eÒðt44F«äð1zR;!32œ)+Ü’–TÜ L)½–T1vM´¤LÐ’ŠU lѬȇ»\ÑîH-÷Õ7jlê;LÒ– B9´>©!p ÷Ç4¤ çSW~×v=½Ùºì|í={9‡Æš˅ʧÞH {.,. ø&@Jëèh°±pjG åŸ:"Å †|±ô(ÝI'[·››¶YUßjÀ@h˜ÈØnÆ©\¶­?‡7Š7±‹x¤O"¹ÐàgÊyÁ´Ñ¿¥./™³Ö.WåWÄ«dÆ…¨/,ÓB¹aݸßcwŽ)`¬Œ¦qrs´P®íPHp|Œ7’»ì©= †ãz@¡ÜE(†ôdøž¤ ãk¹¯#ªæð°ëKØxê7ÕGBêzh¶UÆ«Æ@J„eV³@÷`D”ö÷¡€—`ú…:^Êu- \£¯Þã.VòòÓKG¦…¥åóJžš®}MðÕdo† ºª¨V?TÛíλR<…ªsHº ”>ŽrnC€¡QÓ¨‰½!¤3º]\6É%å'¯ÇÀ4Ø‘Ü ˆdïÿƒøÒ 8n^F%v •81i æÞW#‹¶¡Ü”`íÐò:žm[n%Nñp¸ÙÖë0À§šHÜ×_Iu@ ª‚Ö-åz»pÐ+HjœœÝNŒ—Mš®3~ßõ¿Uº Ãè( ´ ×Éd XRû‹<Áøç<é~˜ç8îu‚3c…yÁë®^¹ù–öaùx[;ErÆÁñ±¯©¼mx9ú(Âb *ï¸ñ…Ã!ëj†Hd´ŽêÄbýd ~$²pt €Ú"ÂèMÝ!6îhH1…jŠëVû\è^«ø<.”cnjâ’Ï{ÃÝ#PoâÕµ,˜FLÕƒ¦ÚûÛK'üö'ª²ùšAÈCdøþÅÉ8» P~ HïÚ¯`9 D…÷ }èó{ºðýÎYnT 6G'á<æR%Pyéø#}ræ„Ë€FÒI(” CÙ„ë7DT6rê X6ñ¯r;~ʶTx¯šõ¶íâÕjL36íRh9´þÖúX €~á³Â”ëD\Gáí&æŽÇi®œ1Åi ®&ñ@ØQ3è¸Õ:=nu°jøí/D9Æï£¢hÜüéQ'ý_XËß×ÕÐá?)„ÖX”‡õìfTë`¦AADòÈ6Üô@Àœe“3´ëOß6nvÀ›mr³”eCñaî°QËJmÒåÿ éÚ 48%“dU %裆m “2›ÓŸËŽL'¾– L½#±¼Ãa×N­?0=`Z*T` =‘€Î8ž§èž<:àÁ8‘0œ|<‰:Îòá².t$hÑhé7ä[À>Ï·¦Møõùסd´T¥6Œç\/%\xi| âg€ÅôÛcBÇN1Š÷á.zÄ(…:bƒ hÁÅÔIÈ^3œÍäæ[ÍK,þ} A¢¥‚O¼š?òÕ9¸ ~*¾`Nð"ÅÿüEúø¹>~gí‘h«xÁ¬¸„BEâb%@™~¡ZejõË³š½†¬H[iÞê¿zaendstream endobj 1812 0 obj << /Type /Page /Contents 1813 0 R /Resources 1811 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1810 0 R >> endobj 1814 0 obj << /D [1812 0 R /XYZ 85.0394 794.5015 null] >> endobj 1811 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F40 1265 0 R /F49 1358 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1817 0 obj << /Length 3629 /Filter /FlateDecode >> stream xÚ¥Z_sÛ¸÷§ð[å™ $ANŸ|¶“úzqRÇ×içî(¶8¡HU¤’¸Ÿ¾»ØR”òPg2 `üö/%/ü“—q$Y˜]ê, b!ãËbs!._¡ïý…dž¥cZú\??_\¿SéedI˜\>¿xs¥HSyù\þ¾H‚0¸‚Äâöã㻇÷¿=Ý\éhñüðññjÆbñîá×{j½ºùðáæéj)ÓX.nÿvóéùþ‰ºžãç‡Ç;¢dô81éÓý»û§ûÇÛû«?Ÿ¹¸öâïW …ùÏÅïŠË¶ýË…T–Æ—ßàE2ËÂËÍE« Ž”r”úâóÅ?† ½^;töü¤B•„3†Þ¦2ˆ³,¾Ôq$*Tö_ÚÝ&ïi[í =ûµ¡ÆB„5·«Žž¥éŠ]µ2%“›é„!ˆ ‡u@êܽ^RãÉà_úŽÅ?žåÿlоjwQÇx$Qa¬’‘DGÇ8pýHŽ£ÙPŽà 2ÐRW¨ƒXO\1-}.ZRÎAßqካª)¿˜·nÉ·4Y_J‘Dç¸f$ð7-Cd©Öcž-P´Zló~ÝäûŽ€šÓë€" õ-=Û¯f·«JлyVûªî—UÃÌ»«t±ïz‹5`ÃÝòz»+™Â$0÷­Þð&ç¦$ÜP"p·(.JX2›¿9%‚,ƒ |“K• –'Œ¹\ªL"’)žZÅqhÙ˪+ö]Ç”¸ùcA)Yö€V(›®3ŲnÛ/y‡‡p,R*‚81È›rfRØœÒÓI¿æuUæV%ff ­€"œê“È¥éóªîpã2Z<¼µi­YÝÖ^¢)¢.6!Œ|É÷uOT°vÉh؉ˆâ”×¼¦£ŒÂ0HâLŽÒôÅ5¢:°},¾ÖéážNh\¢e ˜ü¬Æù\§5nàÂá|wmÛŸÖ8À‘Ìίï˜fÖ›ŒƒLÀåŽ }‹2_ߢ”ô ¨t-@4Î'vfJGÄr¿ÙvŽ\ìwUÿF¤W°Gê´ê äokÓ¥j:RË‚ÔW`¦²åÝ ª_ÏÀv©¢@ 1Q£]SdÄÝ)ÏÔ(Jå)ªŒWáð*Žðê94¯â^U$2Ó¾ÉΈ”ª I“ð‡˜³™f:þ&=®3˜t\„Ik{– 2'PFX¨ó" \32Œý@€J'c!,.• =\â⟽ëv¸ÄvÕ n°õm]kæt$@$óåôxþüðžZ¼czmSãÕ4f—[Lâë¼;ˆÁ wuÊ€©Á8ɃµT`óö¡ÆìQ„I:À§ÛoÁó€e=‡é>Ž˜Ndb1­bE˜VG6Xi͇êÛ`P]ÉÅ,¬£8àþšï®wûæÚÂ5)ÚÝ e‘ÔáXÄ?D,ÐGNàæ‚ÌD( ÂŽ}éóŸ]®Qè§Bi0 ¢#øG)¸^©FÃßqý@ŽãÙP¼•Y/ ² ´I¦m¾ë«b_ç;¢Ó•A‡3`‡U”PºPcêçuh=¸mBÔrÛÖU1w] Åà$»x7¦éÿâP‘ùØSÀ9ìÕm‘Ï!T©@dÂA§Ýºà5% RˆƦœã ±Ø´Ö¸¢¡\cˆÖóU»ïvéÅ‹Éû= bò”A…t-:NÎTŸë´A¸&ÕZ²)žÀ{i™¥ç¸f${¸Z!åXró™"ë† öõYDÎ(Ö aƒNä䀅L%’Sé&“R¢þF»ÍŒMŒe›áÂrè:¸Mx±7Ëü†‘…Ì’À§òBî9ŽŽ!,EÆ“Ž1–I !ÿ8¦3·ÈL“KÌë×c—N;->·øÀt¼úØ!¦˜&£åíF2 úµW¶Þà+]’íå!Á^Rz7‚.û†ËC²wy©‹^eà!Ò'Vú÷¦ã%ÎáËz“ËnK¸Ñ(ŽéCpHüÔÔÉ+\–µgé08ŒKÑE¥SžX†h„3‚’z6eŒ¥•à†ýäÑ 7åŠõíÓ; ċ8¬ÃLɱâjÉû-!É(ç$Xhä±Ó3òØíŒ*‹éØÍ.=Ÿ |l ±9[!S9Fø-ŠK p?פ´sÉ(¤ä‘KFùö±XàŒ¢Iº€GëÙѽúµÇŒƒ‘IÿQ,F±Ñì¨eýö·ª3x"s±ÈÄò„¶§¶‹y£3­<ƒ…j4Cd‚µÏü‹é¨iØQ½«±\Ön+Pi’Œ·]5øµÚÎ({¹rÝæüÁÍ}¬;Ä1³ü]¿ßrQm\ðÑ”ãow §í`êí?ž¾Û¯:8{ÓðäÄ„‹v'Íw«ÓDŸ·ÿ>×i0pÙðzgÀÝïL¹|E$¹€?ªóë\3Œ€b•$c ¬î¤G_>2§©ZÔ—¶þmk¨…¿!éþÌ@euúŠ'2›ªfZ™—CÍ'á º^I+h?¥áA–¼,+—ÕV)= ¹F]ÿ½Ô}ðÍéؽùè¶`Ù ×ÙŸOÑÇ‘¯‹sYY_F󆧿ӲŸ—cñøññç4ÌÀ›§:þÁןë Ì—Õù¶íAãkójõlÙbj1[ŒŸÖ¥:/ÅÀ5#Æ´Ê0Ëñ|…Qî¡Ï޶$˜‚9ÛÞ0 [Á#ºõ¹)^ÂXpK¬x’ç_ï:bÇ#îÛ-‘kóÕÔ<¼Å\ªc¼F¸/@„'­‚DN«ÖÇO“—ÜajëÃÍ|/ê}É÷:8'Š@I¹íÝg*8!+ÊR£CŒ‹/æ;¨"þ‚ê(ø\qï&/͸‡ƒ— D7ßÌ`ûlÏ='Iï|œÐb­Ÿ9v:9¿ÁÕÙH}:" ÛÁ—žcþ´-rÇe½yŠçfœ›Ñü‰MgÇ·ŽDÎÉ ¬Y‡£³ƒ$£e9°?8au˜~&4yü×ÝÇ7Ç¡óU|ø 0$·7îOج}ã×ß åý$ö,–>gAc#µÄ®©9¾ÆD¸kL($¥ÖPÁr@ß)jçM>x]Õ%ñFW=?;ê¡Rª¿åo<Á¶…[°I?¾Y8Záz³ÛT™ ׆Í<ä”öiñjÛE»±GÍC‹ot^Ðð7ÚÌÔ‚Z$¾¥í&ƒx“ŽËÆKT¼!&¾¡JJ@€„Ó…Üs‰¬UÙñ¸yJ/ò­ùNd'š>1ŠV£‚ ¼oòä´°†7„ÄF¹4ö¦{´iŽnˆ%™_‡NC[Óƒï•çi朆s% ®d(ywr($¹Ã…¦;\.žž¨6Ïí>˜hF(¶Ì÷ÁÃóõ­«d1cõâêTö{Át—ža{õæI™²”3˜dÔCüLé–U`[ÝKÝ×^Àý¾_·ôÛäB |¡¬I85ÊaHï[7ˆ'«^ˆ`UÁþÃ<­LSÇ„·nçY3É)ŒkÖ:{ b˜¹js:è:Ðø¦â(^ÜØé:Çk— ½Â ’­æávOÀ´â~ÁÔš Ë¥îÃl<-—ÈSßJóô3»:c¥9ºƒ÷ÊUsRJÒ1­X›âK7Gí˜ÜõC“m<ºªÆ/ÎýÛ8ž|[çt¬±véë/`27ƒ·ÜIÂZ㬶ïBV†UŽMvœúù¥ŠüÍäL¬ÿùìþïŸf~· ±JÓŸŒ'2áf½Ÿ™^~Š® ˆŒÃp‘„Çq0ÿºóxSÿ±QÙšendstream endobj 1816 0 obj << /Type /Page /Contents 1817 0 R /Resources 1815 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1810 0 R /Annots [ 1819 0 R 1820 0 R ] >> endobj 1819 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [222.5592 758.4766 286.2499 767.8862] /Subtype /Link /A << /S /GoTo /D (statsfile) >> >> endobj 1820 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [80.6033 600.1815 149.9876 612.2412] /Subtype /Link /A << /S /GoTo /D (dynamic_update_policies) >> >> endobj 1818 0 obj << /D [1816 0 R /XYZ 56.6929 794.5015 null] >> endobj 1815 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R /F49 1358 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1824 0 obj << /Length 3414 /Filter /FlateDecode >> stream xÚ¥Z_sܶ×§Ðô‰šñA `ÒéŒcË©“XN%¹L’êHéØðÈË‘'Ùíô»w ðÏO–{F\‹Åb±ûÃ.xñ)‡ÿñ©M—©:5©b “Óåú„ŸÞCß·'±çY¦Å˜ë››“ó7Òž¦,ÕBŸÞÜdYÆ­OoòŸ£WùãÍÅÕÙB$<Òìl‘h}óöò5µ¤ôxõþòÍÛo?\½<3*ºyûþ’š¯.Þ\\]\¾º8[Ä6‰a¼ðŽ xóö‡ ¢¾½zùîÝË«³_o¾;¹¸é×2^oÌ%.ä÷“Ÿå§9,û»Îdj“ÓGxá,NSqº>Q‰d‰’2´T'×'ÿèŽzÝÐ9û%Ò²Ä 3c@!FŒ9ÐJŸš$eZ é x]®Ë*ÛVŸÎR©è.«Ú‚ÈMÓ–ÝY•EK-ˬ&"Û–ën{Û¨YÓ[±ÞtN’Œê&ã~á ¯¢{±lÜ3÷ YGÏnUøÁÙº€Q15—õ¤[EyQ÷YW65nXaÇ,Má–ÔԸܥÿ4uAÔ㪨‰rBø}Wl=_÷iãË–žuÓñòò§³8Ž#ÖÏ”²Ø¦n¢Ë¦ÃaÊDm³öÔͯQ„Ò`$·Tj&y@ŒTwï^Y ÐJ»”<~B½¾À¿/|7?œ¥"úgßh]ã‡küëç¬óû݇ë‹ïBSz¹7+·D`©ÊÖëZPÉ{WÙ®íÀœÎߨ±W³ŒY¬”7þ×5çÑ8e˜ÜL…n›¦[ ÆXpPñqYíò"Hp¿äÅ_¾ödõГ»¶'×»¶Ø­Ãëÿ¾v3/ö¦&Ì ÎIØrÆ@[&M:Ržg1b¢‹g@*0á|yÙf·U±Èªûf[v«u»?l8³ æSóžÃù'1nf¬•^“ààÈD@´›bYþ¹(rjx}y}}ñŠè‘®ôÞùgí™o‹ªyüœD cð;•ªèÝ®ZОè„Yè3q‡®Ü€‚λ&ö‚®ÅŸ°äž ¬eZkㇴ]Öë¢îÐÇÓx•øRÁ"ŠU”2zO¡˜ú!q[¸juËÕœ‚HuïA*¾x+ä€RJyÈÅvÄcÏ¿l âÞ~¢'2šYrÃ#¾ÌRfŒHü2¢›É[¦†Ái²Li•uÁ™·[Y·ÅrG½ì‚$R€ ¹xBÆ\Ç1¤ç¯8oyyny"Ú0¥Sý´=׌S L%ñT‰HD"ÃA*¦a=¯¯Ï_ÓQEï¤01ãQÛRsÖùgíÇÝB¶A°2’/å{X‘°+]€E@ò“LwsU℥ƨ=gššvß™3*s¨Ð1Ä”#T‘< ¨"…_p{TêªÄ©f‰°é×Ð£Š›Å¹>¹¼Œsµw þTö”{ú%à"%p‘ÆŒÁÛƒp¤½päê…Ï€1±Çdòƒ,ŒÁÄ'scÀ&2Å\û Œ®!kï‡Ƹ™F“X­§ÿs£¸¯=VLŒsǘžË­¸naúEÕ4¿em™‡#A¸–OkÐsͨ0A uœ4zªÃ¿(QW+E÷bf—™ÁŒÊû[Ä™& ØP½òPºêç¡°â!«Ê<ë 4q¯p®•y² ¢¡Î(釔 èVMî…4ƒ G1¤ñr yyýýÅODE"Q=<ö8Ø5"š;œô@G°è¥.5Íp»+«nQú·¼¸Ë £ØÈÛE˜ÿiƒ€üÇy€AV*)‘Õ›Í[¢!;·{ø9Ä?R½UOSß¾.”Bž½_¾ùÈã¤3p<{ÿ ['ú‹¥„›d´}8qïeóÛ—@N¨ÃÎÔs›O¼âEãå—z Øü×·ä'JO,pãb)l¿€Àà zȨÜß-Á³íš>CngýÀÂ9!YWÓJD2«p Ü–uÎ@ü\6'ŒIûæë¹ìé4äýˆ´ùŒ‰ù‹T“œ5¬šÌ+ß­Ü:^gh€Ê`Û9¨ÅEΆº„ Šü©³„tQ1›Ê½"æ)GR_‡ªÃ‘zvp¤É ³Æ> ‚ð^\éè%‰_6›O$Sl¡0Âo£ë Ú@VÛAªï²pxõ¡‰šØHwöH¥/ð’×z\Àá-1CbL.Tw^—ßÜygå)“Ò̺„#žÆVEÖú€Ä€V!9@¢ø¸)IL‹J¦©;m0)‰ð–ÑA©=Ë‹ªoù<_N“ô—DîêÄÞå›ÇÒÞû{x');Ê ÷r¯ùëAzŒ{*ll,¥÷ÔýÛi ¾¥úaÄb<Ä¥úÓ>Œ ¬ºnÓ~u~þøøÈÊvÉšíýyÛT;w|žWçûBŠËR 2§î =סV»JC­þ6—ˆBemM ÎÙDl™‘‰œ #f*7è9˜žÄÒWŹl¬Bùu%ݬÊ#¦ãúr™<ÇO4KE<>IPªÃrœð®ÙÕx&A ÓHvòpè 㳪m ô˜ûÔ ÚÂ9‰4€{Ÿ{¿‹ë3¨~{Û½¼µE¶Ã”íÑ$üJ¤À½ž¾As¿Aê¹FÉÌËáÛbá.³¯‘¬a©æi5z®=&~‘ À==®ÑÃîÐ …‰Ve±¥«Ã%-5†«L Q[¢œñáé Š=™AÛ3â®éèJÔûÚm¼“çªÛœ¾Á:'² 1œ6 UÅ$ãO™Ò"øñ§bÎ×ád…3ÌŽ2~k(ãŸÁ08Ç’Ä>#šm<Í~-a T¶\‡œÿÔíc±m©Ã]$X‡Gµ·‘I£ñÕæBq>¿fÁ%­ˆ?_æÄ3‹v³öB–B–꺳8 ¹6w€rxAç¿Ík¼²©ÈaTB·út)_ß"1¾±õŒ½I”ö÷‚þ@‘Îvþã€õpíÓ[65TÈØét$Îôb;½¾ ÇÏf¶Épnu[w/±8†œbɼ'ÐÛ/_bfuÀ~ÕÙýqyphBŠ$÷¿šøÂtV~¤TÉ-¥½­FHš-ûŸ.Ìb!¤ZJÐoužÀÂ×X¸¼êZæØ1KÒÔ<=mÏ53ï44›¬ªsJâÀ‡ü±¿ô?ã¡V¬ÆÜM˲kgo¢ U±üJ`ð9JtP6Í×aÝqŒ+ÿUÇW}*ašË½4i@#ˆÀ“{ÑØ²wãŽá¨Dô¶£^—XjüÓ…;[hí¼”[/ÕÑÈ_Sϲ©ÿ½«—áÊ9ÉPq\Ò/Ê —¡/²ÙïRLaÌäJû5:dp‰ 8˜ 5x— ÑvÿÇQC®¢‘¾JÁÑ}žâ¾«nª§yÃG?WœŽC.h2{ÿù Ò_ÙÛ œB—½Ê<_UÔ÷ÝÊ7Ó'Iá±Dñ@XO$ÚAuŸÎ£TO¿ºmBÖtõæ•ÂÁŽý¸Ob¢1¸¼¿€ûÓ?ü~© “ÖùL/¹fVRx¥ÐÀZž-bPBŒÉbÐañã õ?<\ÕÿXl€Nendstream endobj 1823 0 obj << /Type /Page /Contents 1824 0 R /Resources 1822 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1810 0 R /Annots [ 1826 0 R ] >> endobj 1826 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [116.6985 278.2575 321.9289 288.4193] /Subtype/Link/A<> >> endobj 1825 0 obj << /D [1823 0 R /XYZ 85.0394 794.5015 null] >> endobj 1822 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F42 1338 0 R /F21 1034 0 R /F49 1358 0 R /F11 1559 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1829 0 obj << /Length 3510 /Filter /FlateDecode >> stream xÚ¥]sÛ6òÝ¿Â÷Ty¦B€ çÉIœœ{©“s|Ó¹iû@K”Å–"U‘²­ÞÜ¿]ì‚"%:ÎÝ93!°XËýÞ…äiÿ䩱Â:åN Is:[D§÷°öáD2Î4 MûXonO^½×é©Î*{z»è핊(Måéíüç‰JœÁÑäí§ë÷Wþqsq–ē۫O×gSe¢Éû«—4úpsñã7gS™9yû׋Ϸ—7´dy7W×ïâèñ̦7—ï/o.¯ß^žýzûÃÉåm÷-ýï•‘Æùãäç_£Ó9|ö'‘Ð.5§0‰„tN®Nb£…‰µòäËÉß» {«þÕQþÉH(mÕ•ê10•Â8gNã„ÕJ{^ÌçE[ÔUV–»³©Vn’á#lÎd:ÉòM“üê³7ŸÏœš\ÊŸuÅkEYÒè.§µ½Ÿµùœõ†í’QÖ„òK©'^ªéI+õC1gÔŒà«l½.ª{ÞV(`ÄTJáŒQþ«èŒ(>$ U¶Êúã"³ÇžÕ¢©Y×ÕœNÂM®§ïÞÝ<¿Ñ¶ép›]Û5ÅŸþ»aó·×?^6©yÈž<hžW§M¾ž3v_z…¬-¼…ÈY5ÙQ:Pk‡6œÕU›ÍÚ±caãD2ö,«@¹-IŸÛ?GÈ'|6ë|V,v \2òFõâ`‰?Æ‘b?ù‰×Šð r*ãXÄ*Q9dç¨jÀÄ©–Ñäø›“!f$.š4yÛfweXjéIÄÀà¡ÈiôŠõ¿¡I ª^¾p@U·c'ÕãÒcûw¦CõÆ•»¬)H¼ìÐ)[áe6[ŽÈS9'*éËsDŽÊ‰4ÖŒÔl×ëzÓ6lË@šÖáS³rä g…N`?Ö‚²È+xûø­…4QÌxo?kFFãó¼Í7«¢ÊùìÇeå—®DS`)®d œ,òYç'îv´Ò.‹†5"ÕÂéT˜KAûÌÚâ!gÁ]-5÷ì¯òù÷4/:ø"Û–-ËôÛoìú¶d-0_«Îàv¯Çx¤ÉŽ+‚ v‘ˆS°Õo’±Ú$æ%§Âª$=²Š/d¥_²‰²áut£ù|LÆNÈ8U}ã$c<¢ÉK`8ŸËFøÕ燘‰™ÏÙ…6yC‹{‚‰÷%€wÇó=-$èÔF‚.ªCñÒ¾àØ|Öù¢>ü×ê Œq’¦ÿƒ:¨µÀ©¡:\×›•ºRÊ ¨§'øîú Hªc;y¬«ïZ‡|lŽ E,Ñt^¯2d‚È ãˆMÖëGto£H  Vug†0»€?Zg£¢Õyó .FÞ7ùX =@G¶› Hˆ†ÅŠh¨Ï d8¡Ýn@ ˜wAм]òÚWT”EHk‚ŸËŸfåvž)q"0Ëéû)ØX]?6LÆ1T„Y†ÇñÑ F¤GY4-a‡ÐqË-²×S Q‡šot03Kæ Å}Å"˜ÓB± Ôs9ÙÑ­#Û0BÅ0šá#…ÿJ²ÄÑp¼4ˆa™µ­#oD¼w! ‚ Áj¼ #°Ú ,ïHV»'7 )ÆNÐÐopÞ#êà‘È(ýuб xG–ÎGV9«ÖFD6:ðÝhÖ~M=I¬Lç }\£Ø?êÍ2¶ŸyáöYÙ }[òŽéù+{ó0x8PæŠ/>¼"h“%¥£øÆ’wb?ëÇä­q¹§³´„û€<¬q“7;âH k¡ÜF_â#JαwðC¦Cõ2'ÁÒ=jÁmÈ•™çç#, ‡Ï UOüFw¬Ä¡-éóeWkD‡µ†ä|”Þ`ÎH8ƒä8ƒhÛ†¿á.dª *qj’!gþ¤ô¯Íó@ÇG²öHDI‚Æ&Ÿm7 ä4Óº*wci{*’È:F/¼ƒWÌáXv¡S¡¬ ‰ä.Kðd †bƒ%ÎÁÆ]L’]mÃG²›‡O©‡-™à½òЦTôÁ€}ƒÿ2\'èÛ|Sø¼Þ¤ÆK³c¬vJ?£r>r7#_kCÚÆ_PÕãj#= ÐÚ£/Š XomÔÝ&Ï~ŸBÆÖä³19IHË“ž˜”ŒHL8S, ÚM¿.¦DDÚ Ä„ûgŽgìÅ„S=0Bá dp åŽOÅí·b½^cÄ€qÀxÈÊbŽ=ÃëmR7’J ˆl–m©{„®ùåò-x;ŠÀ0_€ãÚÒᨠpÅ×þ}òÀ%Xª¯Òqž*«°'“|U+b‘¦Iàé/‘‰Øq$Aë&1I‹ƒK…¥wŸút¤ŽdìjZ•$¤Ãt¡¨fõªK^ѺT‚ë¼  ýtPÞÜ|¹úÐ «Ð.àú˜=Û—©cÙ€Gçûjc:µédÒneÄ}ƉHM-…Ö >!šÁ6‚“3édJ“ÑCF¯Ò×<„êDÚô•´ à•T<ÿ÷ëàK)¿Ö½RÉ#Øøüý{÷æüü•³á|ƒÈ:pÐ]1ڣƧógõß 1¢÷Ê_ø«^¿´ƒ$(ý-údóËçç ø;àÏÿ·_' EñÞ%”éègÓûƒf%¤,RÚS¨º… "7 iÚÇ¢Þ¢iÎvX,!pÓíÆtUS~Ö'AšH$ƽ@C‡5BÄÀŒÁ‘'qt@…w"Ú'¢ÍÞ‰À8ÀÈx5—X¸ÐòÊ>Õ ø¬mλ,F A¦À{)]WiU‹iï±ÏÆJ“†î[ÁädôàΪæ²ÉÚ­ó‘ó ´„\m_Ø7íhóŠ8%’Dª¡N„ FßÊ zÚ@yBÌ)ÁÚ¬®0ºßvu .SÕQ…EˆódøÅŒà$~Þ}k“éAA6Ÿ„7»L‹›ûSÜô4¢ÃŸö_8Öˆã}ñ³¿`ÓÈ+‡7ÇG$%˜¸x@Ò‘jvX/r´GU”Löáø8ˆü ·Á2f ?¬£Fû81ä]±Ì<󡾘Í(XÍ£PAÀ`½)@N´Šâç–¶üžï¼ØZ‚PZ·ïœ[¯°ßw9w5‡MŠª‚ì·‘Î)&Ò¾m¡€l! ÑEÉE›²"ÑÖä>€97©|ã¾Ù ÏÙ2«î}9 “ã²Õ…nµs{ ö3<2kYÿuv¥È ¶^pÉØÌÜŸqŸWù¾Á}€úð=NĈ«¾æÔN§¸½ëâ³¢ÉOl˜Ñ¤¬3ºaém 8òýͰßÞ±¢kíD yù S]e>]àEH;š´&V˜H›¡öŽçÝ€ âЙiÁŽÆÚ® 6Ú‚ Õ›Q{&VÁ3n²ÇñŒÓªo‰˜¸Wþšã0v,‡Z[µù>oÆî‰wå8òW ‰çËâÞ»v·—FèT »ñ>ñêÞÅI,R—êa`„ÍCF¦û^x qX;²éö:æwƒ¦Âoþþv4hÝúªKS¢§Æß,¶%Ã*‚„ \ò7þ4¼Ë™PD¥ `ÊzJjv+rî~!£¥}´ûß.ÿÙuWÇ\ªK>îwŸNù·òñü‹šï’?™/Þ`Þ0ì j‹’V8¿Û¿Ô¿'à2óñ F>Më”vé~Üâ—gÚù6©uh“ÚÄôØuéõK a`Œœê‘øƒ8c Åûm¶É@óîVçèç%…ãû¼á¯ÎÞ3v¦öê´o2Ýu¿±à^ÛÀàÅ&8{vV#ú†ùúÓíåùÙìxò†Ug¤r†Ê0Ñ{´~ÖÒƒ‘Oå7&××àDy/Iàý¯°JAÅA­òU½oòÅ6´$p-dÛ8žA"Qó1È<~Œƒï6¼¨œÁ‹€äè—O«ñø:4FàïÉFâOÔ]²üß?[Ûÿ¦Ò(çÔx ;  éïýOH8xú9† D©‰c:ÿòíø£þ,I…endstream endobj 1828 0 obj << /Type /Page /Contents 1829 0 R /Resources 1827 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1810 0 R /Annots [ 1831 0 R ] >> endobj 1831 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [406.7896 313.8441 476.0457 325.9037] /Subtype /Link /A << /S /GoTo /D (dynamic_update_policies) >> >> endobj 1830 0 obj << /D [1828 0 R /XYZ 56.6929 794.5015 null] >> endobj 1827 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F49 1358 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1834 0 obj << /Length 3736 /Filter /FlateDecode >> stream xÚ¥ZÝsã¶÷_á·È3'ß'OÎåœ^¦ñ¥wî´$´D[ìI¤"RvÜ¿¾»X$%JçkG¡°XìÇo—~âÒÆU®/³\3Ã…¹\l.øå#ü÷ã…4óH4R}wñír—9Ë­´—wƒ¹ãΉ˻寳·¹þåîÝÇ«¹4|fÙÕÜX>ûþýíÔ“Óãí‡Û›÷?þýãõU¦gwï?ÜR÷Çw7ï>¾»}ûîj.œ0^†N ¸yÿ×wÔúñãõÏ?_¼úýî§‹wwi/Ãý ®p#\üú;¿\¶ºàLåÎ\>à g"ÏååæBÅŒV*ö¬/>]ü-M8ø×’Ÿ6Ž©íåÜH渜2gÜ€Ðæ™Ìæy/d)¦„©PÈÿiêrÞvEWµ]µh7-tÎ$wòr8õ‰j‚9à@ƒG,¼ÀU¿½Ñù€4‰IÓ#ÅÃ~½&šÑtR±O‚ˆÞàé©Y·*©Ñ–»§rGíç &ð­E³^—‹_ä,í»ÿ.‹® VSI¢ ZjþÆ ß×ë² ïí¶\TWú¹„©Ö/“ý®.—aº‡+áf~£ ¤Œ)máL…`¹1Ò³ *ig>Ìl ¬Ãˆ9.KÜmÕ†æ ù…^ªú1HGŒ„-Y–g:ˆçð ýD]¹kË Éæ’I•†6»©é%³NðÌì5ò>1¹bʨxlUØ7žÛñ*2gœƒbô«LéfN©¨,ÈE9'Iki«¢¨É±lʺƒ3à´T³;¯1ÎÍ–åC±_wôRµSZiõL„•NI˜vÎ Ô2Ïf[œÍSµÄÓò+lªºÚx̓—¡ìðÝëŸË’ÚAª]U/Öû~ŠºØÞ‹zIÅ~ç—‚=’ „ß§«XGEZÏgõ~sêîð uÜï»ðOìËÝ 5»—mI­E³¯Q$K\ŒÃ"ËX..’mQ{…íO 9Û/ôÇ} ( 0(´üû©*¨{Z-D"Öbpâ4÷|±*꺜r<ŽÎd¯Ò~ú};m<\jO½«—‹~íÄìZƒouº?s%³ÙóªZ¬h9 l-÷›-ŒÒ†™ ôv¤œ°áMtž« oô/ëÐ^ÆɹpoB‘pÊP!rä™:V˜ïx7ÆBÓD fÈ8Ÿ}*ÃÒźmã„Rà@çmfX®­@ÿOÿí/©ñq0"ù|H/ŽfEv>û®š:Â<Gì@ŒV ç? [‰êKlÍFbñ§(fZs1Öü¯`Zƒ×^|~.¼E.©gÑl¶p÷Õºê^¨ë¹êVÔ*‹Ýº*ÃX_-ì´¥7!þI[9ê™u']'Of'ôñ¡ÛŒ™ÜF5i¶$dÏqñäAt–3)ÕcEÞv~S5`»0÷K9µ¾”%51g4 ¬åDIêfb–èãˆä»‰I4pû¬¬ tÀÚCÔvÖ’Û…®MYÔäá¥h'yÇÃÓg¡ŒXw³ë––ÓÇùö…@GüÍÄbàä´>/På<Äk¶Fç­G2Ž!'ö ÈΊÄÃtÄ!·ïÈ–)D–OU³oCàb<ªBzöì]b`½Ò$3 lR õ5›MØÒ\JÇ””%Á„ &‚û™ Î!7išuYÏôÁРŽXÝX™Ž:è‡T§}¢ò‡²ïš ˜ùb^ap~(`÷hÁ‡È°Œ4BŸç$QM°2¶ˆ¼Íˆ—Id/8à ï¬ýXU:m´¸¾ßn›{øŠ(Ÿ^È}øô†z’ Œcé–„¯Ëî¹Ù}¦—$©6B&°nÍØ»=¯Êú@ýÒÀ ƒËeX§-ƒ¦’ëïÿ1»ÙÑ“þÞ4Oå2ÄÙ»8yGq¥)õ–9 H¨Î “ÂR6ÔnÐb¡`B;ŽZo{ì¸~9Øê‡O–å²”p.ƒ 5û޼"þÛ,>—]ò0™KHåX¦D:ð3*|äî˸Œî$*ª’nÎÝ X–çVŸ_>QM¬?vû È,ËÆ ü+’à­P9æ£p°á°àuT0…÷xìyLf¡‘ f¹¦Z9vx‚?ï_¦(è¢CŽù± N×ËÀ)š\'øÚÑÞ„b­up²¹8YàjÒÉBŽ©˜‘2?têÓù¼Ö&âþV‚Ͼ™o†)Æ‚ÔrùM#äÀFbh~¯Íf“ôu]ÕåØþB‘ÓSm9ö†“ÛƒpÀ”æòk³–Ií‡LíÔÝY¯ü=ÑÝDÞVÅz¿=Òyu.Àa[4¯:Ž‘9èü;\vç€o´Ò~\—‚ #ò<œ$ç ?øNÒŠÂ'fœÓ=þ/¸/©ø."ø½POw¡{Ùx·Ú]Q·å.LQ,(´·qjêFAc´Y–^ÅBi‘è~8èA?ûœD¦ ûq&bg÷!}\…<$Ž÷·gðý­œ¿¶£1Ž«º äizDâGøà„­ JpP`Þp !ná_¾¦†“-+ºô+G÷1|¼±2Ð,:1¢±†,•˜€.ø wØãï` Ànï|mª[¶SƒÄ‚ˆ)ĺyN‰M3B‹ “U~õ€æ§óž®÷G º1Y€¿ºÞ·FØX,Bý`ä£R6= y;L·3ÀñÀGøãf@—õ¸¸ ¼ŠÁOz>õ"Le pÖM‡b˜°΄µ_ôʤ/cЉÍO·_E}Py—9¬‚%®‘·õ• 4±@ËKžX/±"+ôøÖâgLûû~†\k‚ŽæL_DA;|…"ÜÁê~ܯ‹0ê7)uÏ*OßÐs >)-¨8M0Ÿ:÷‡°æ*h²ÍüG&•÷}ðBáMí#9´B‚L/á; ›Å{ê›Êé„d^¾ ZhÆyÔ„òÏmÕçô°NÖ+–Ë*Ø®ÞÐ=Zº8•¹ÅïåØ 5}àÚÚɯhn çBï"ó¡Ê‡z¡áQ¯BÃ\U€±–¡÷…žƒÏ\Æ…©,cÒê/[F:›܈ºab:lá®[j&Ç í hUñˆÕÍ©Õ9SNÛÑê!6*gY–Öá·EÛ‚ß™²5äJÈ&r¨yâK‹ž/Í_ô¡hÍážÿ“ü·îavQRb" <µWÃŒI!xCqØñFŽv.†;ù1ØYÃökØ‚ ~c²µP…ò3’ŒNN†‰/Ï!±<õ½‘ÒŽ—Àß«Ìmž“£ÞðÞô…³cáÜË#*=£$š)¥²±’à´ÿÞ·!Ê,«k†í1p?’LÿÍBëQ™BHØ hí$³¬üІ~Û&°¤3õÑ0¦ÇÎÂLs ¦«y6U…à©ÿ¤ÜÁ ë)çNsÇÂ]žá}Î忎0 &À„~´ hœ©ù/úPRF¡È4Á`Wÿ¬§©’endstream endobj 1833 0 obj << /Type /Page /Contents 1834 0 R /Resources 1832 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1810 0 R /Annots [ 1836 0 R ] >> endobj 1836 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [331.6917 674.7706 395.3824 684.2001] /Subtype /Link /A << /S /GoTo /D (statsfile) >> >> endobj 1835 0 obj << /D [1833 0 R /XYZ 85.0394 794.5015 null] >> endobj 498 0 obj << /D [1833 0 R /XYZ 85.0394 616.1082 null] >> endobj 1475 0 obj << /D [1833 0 R /XYZ 85.0394 591.4059 null] >> endobj 1837 0 obj << /D [1833 0 R /XYZ 85.0394 95.0274 null] >> endobj 1838 0 obj << /D [1833 0 R /XYZ 85.0394 83.0722 null] >> endobj 1832 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F49 1358 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1841 0 obj << /Length 3315 /Filter /FlateDecode >> stream xÚÍZÝsÛ6÷_¡·J3!Ÿ$ð˜¦N΋Ó:îÜôz} %Êâ”&U‘²ãþõ·‹(R¤ä´ÍÍd<‚àXìço—â3|¦“8±ÂÎR«b͸ž-.Øìž½»àž& DQŸêÛÛ‹¼•ffc›ˆdv»î­ebf ŸÝ®~™'±ˆ°›¿ùpýöêÝO7¯©šß^}¸^DB³ùÛ«]ÒèÝÍë÷ï_ß,"n4Ÿ¿ùçën/oèQâ×øöêú;š±t9±èÍåÛË›Ëë7—‹_o¿¿¸¼íÎÒ?/gòûÅ/¿²Ù Žýý‹¥5zö7,æÖŠÙÃ…Ò2ÖJÊ0S^|¼ø±[°÷Ô½:%?Åa×Ô&³HªØÀþŸ³­Lml¸¶ÓÛ²YÄylµ>³½Ç`-? o —Š,œ@'À]ªRà3åz…è©×ÂPŠt–j‹D¦N½«"+÷[úC½Ê‘4JÏ«z÷•4½[p3Ï×ti6@Á¸œoòl×FwyÖž â©LGTUÝëçc¥ªTÄ6U³>ÿO$(|ÅaÉÿ‡”¥ŽSÁíAÊ|JÊÒÆ’Á(åªÆ#郃óGŠÿ2ÍVù:Û—- ù"RÂèùsÞ,"ôÀ"#ôKMJ¯Ç×—•ÿ’Ò2N“ļ =‘ÆRKådƒR‹@ªU_'ŸƒÈük“¢ê1ñΓDÅ5n!¼‚•Ö„]“V¯WZ ÄèD½ -&c¥¤“†ª¿`[§½°ÏÆ×ë…‰Ic aü¼°ËceR뤰͚¦xÌ?_ZŸ²úl|Å–•êØª„¿ ,à@ãàà‡Ñ_—Ùwì³ó¥„v? Öü=0Ä-D{üðX ›ô1Ø‹ Ë@ÞN-JÅ‚›i°cx¬­Õ³D b3äð×u›i7Dr@:×n¯ÞþLã­C2õ2 V÷4W4Š¡A¶F¢u¾lóÍÜ…àÛ7¡t¬l´í1ר()M'‹GØ—Ç)†a–™H9õ=QÔ§[mÀÑî¸Î~Ë£â÷}¾A4΀7tg7ï¨&v@À>†©d¸ýU2Ôã‹£ææ\­u9ÑózÛuEOó*»+àáAS<ìˬ%]Á}»É‰ª¾kê2wЇéï®?Ò€Né(Úç­zõãOP±nýyÁ9 øÑP´€XÀNe,˜>ÄeçÂùc¾#XÕ¹7”Þzî>0YW§•«Á˜/(·GuF¹Ê)7o—›è¾ÜçcÝŠ8PLÝ»£šØ| [ žõO‚»ß’sÐ`’λ9¯#¸L$L{Áà Á¹‹²ý4¸•‘Á­zŒÆNÀF“ °”þe¶oœÁd1ÀU“ïH—8YÓ5kÛüaÛA˜t;’IÀtl¤Úñ"¬ñÕQSïÝ`9˜]Öîºjh²héº*VÕ7~¼Éý+O›¼¢Ñ²®šv·0óýÒ[½ g€A¶Z(gÚpµ¬ÍhÔ@´"ÀM½Æ«g6·°tî,´_§öÔ8ˆ…O4@~ŠUNKøh˜ù ˜ù{xî§²ÊO:“ŽT´'FYÝŠóþÒ#:í.ˆê1&÷Í&ú£®ò&ª«¨ÙìÛUýTœ²²±€÷ÎñѸNšRèsòo§q)%)WJ@ŸÙCŒäŸÀhø¼¡»Õ>§7¯¼xtöo~¼zw{yóþøCÒ£Ú/¶ªý&˜äúTÎÎm‹ŠUdÕ³Ošyµê²%ŠŽFO»¢ÍtnÎÀ„ü¬/w;sçM”‡à³žÕÉqlà”ªÄ`Màþ/¤[#Rû‚…õ¨Î˜X Â7œ¢\E˲ȫv„÷8©‰äê<Ճà x:`üY¦I–qü”ùɬª‚øä-©-ŸýüöÌ€itt7áß$oƦnÅRrtGÖ¼¯ê.HÈT#d:zׂ©$ÆÌoì’ O¥1 üÈð–›"ÇÐÈ-#÷ÀA|U+\ïò£Ñ=„¼ Ké(Õ!´ ÍÙWb ܃ÔÙ™O©2 „2LÌ›m¾Ä}ÈrûTÓ É·Ù.ký4)eÒ5RÃñfûvUŸVõCVL¹¤U3{ä·Ól +!ÃÑPÛ[È¢ipÌÝz)$3)>%,ˆ~¬Nõ”ÂòÀ‘ÙòluÒ#%D!°åä¼Gö©N{dGåô^7mÔ´€Ðš¶XŽ=ƒŠ´ö<ÕCÏ…ð6dÁaÍ{yÑ`˜ñ F|}jü-Ï·>ærÊçpíÁ­ëõ‘`/ ñ°Ãjˆ{ü€YRŒ_* !£gí²%yø¤ˆ™àéШžŠvãCýu¨“ñÂMT£ìZÛZ‚± ý‚¶{Tg´¨Sô•þ£âõ­£»¬£cÅ@;é |tTcF;ò[mÍ'V©:†1ÍÉC3fM¬Sf»IÁçW-½ïÂ8<ÆÅ%ýÒAîPbÑÒÂí öÙ=”¹ÂM0‰ÝdtiwYÕ€@nèX-ë{2 ®r$lÂq¢8«ÃÐ0"‹„ÁUµ¤t€öáà*Lþ‡°ƒb˜Øw\©rg„´â¤–.A™~£Œ.Wb&Q7@ í‘&Ümk(óÁ§üêWë!ø%8ÿ\ïD vLb,S4è’tSïÛûúÐ4o€Z¶æÝï›|ªƒ@a¨ÐØîêGÀÒd¸ãx«6¨®ÿ>ö¢ æ2}¡íSö½ŽÊù^QYí|µ1޵ ;™Ï²ÐQMð0Ì/à(*M‡L\­'„g±©”|Fb7½Ä®S Ît¨Ñ`t6¶ M ꫆H|ÄÕ½8 +eIoÔUùLsPÑÑ`\5bo¹lyÄ® ñ[=tÈvS&Ç•éS-&ù°h„¾h”< ÍûJ—/Â"ÄMÓø÷}q¨¿qåñ½ó1Œ4e~ïz!Îô¥·Â{Wéõ@VøM,žòÉCAú=wɆzw]³/åÉní¾jÉ«uí»IÍÑ®‡#µo\»¨CŽwu»±‡ €·o¾@µ-:Ò®]³zÉKŸ«¶!°°?aÆÜ¤qÊ ª:kÆ}ªÓfÜQ ?sö·5*–P6žß6Ml;VXà0>Üv2_pCø·g†à±æÚô¾õS/'éâ 8ìʘ”lFjÛ}Ž@2pÖ&»Guà“.Øâ£p(.;š ˜#Úžt}£„zxŽzOù€¢/µ¸m¬…:‚q³I&çËMV3È0ÇÌ5ÍZÇ"Q R¥ŽSM¿8¢‡»û nú1%ÐGý&‚Êh]äëchi"o*æÇÜ@ÝM¿ñé/>þ²¨^àa¼šÇÞ*1”/žÂX/;â#¯0F¨·›îj§¡›*8×$ŠÂŸ®£DÕ~ãWwÃä(T"‡zÞ*i†ªt¹øÓÒÁq)Uè-ª.àøÐcTغ­Úƒ‚cIR-1xõã‡×4xïâºÊU0o&•ß®®{xØ®¡›îðG;±ñ"ÈʦŽNþ£ŽÒÚ{"å ØGÿ(Âæ†²æD4iú:$°Èµñ~ šH×Lq}Wë— žUô­ª7B|8ííDøb §:íÀ¤kƒâïê„:™ð7r†@’ږŲh'¸TilKÿ—7ÑñËQ¡;'ò¨×Ô)G`¥ô-(› „Ë-'É@”i×—:«fU+Ó«‹ËM IÖÿL­ô*|÷8ü¢-HÉeÊk ÍÞºK ߉`]©GC“ÅþС_v⌒ã÷8>0åöœ ã…D£»œ®®ýØy±ÇYø`Ú·8دH;^\>™Ho:ÖRaïɻؖ¢ÛáiS,74\bŸÅðk^¬ïvcšsÜâtÐó¨ º¤‘0ö´¸Häê˜EŒÚ"¡Ž ¼üTïË }áeŒ[9ÇdôÕØ®„Çí~WùW¨ÓìûOÖ¶÷ÉÚÌ ÿ´ðvßáYSBmºÅÕÓƒÓ.wY³‰Oý.VêXMœg³󹿙=ü Xá7̉¢ûˆ'd¾ßïà$£Ô“?Ä‘$ÃH€V2‡ú˜ÿËendstream endobj 1840 0 obj << /Type /Page /Contents 1841 0 R /Resources 1839 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1844 0 R /Annots [ 1843 0 R ] >> endobj 1843 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [154.2681 171.9458 203.5396 184.0055] /Subtype /Link /A << /S /GoTo /D (notify) >> >> endobj 1842 0 obj << /D [1840 0 R /XYZ 56.6929 794.5015 null] >> endobj 1839 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F49 1358 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1847 0 obj << /Length 3774 /Filter /FlateDecode >> stream xÚ­]sÛ6òÝ¿BoGÏ” $8}r'uçâôlw¦7m` ²x–D…¤âª¿þv±?$JN®7z,öXìÄf1üØLÉ(y2Ëò$’1“³b}Ïž`îÃs0¡ ‡P?<\¼y/Ô,ò”§³‡Å—Šb¥Øìaþ[ðöÇ«Ÿ®ï.C.ã .C™ÆÁ7·ïh$§æí§Û÷7~¹»ºÌ’àáæÓ- ß]¿¿¾»¾}{}2%¬çÉïoþyM½wW?^Ý]þñðÓÅõC'ËP^ äóÅoij9ˆýÓE‰\ÉÙ |ÄËs>[_$RD2¬.î/þÕ!ÌÚ¥Sû—HIž¤³P$‘JÇä.ÇQ,a×ÂLæQ*¸èv™³©]öP¸Ë›ª-û°­Â¦Ò‡2³DDLÆj6D|D¾ƒš ÏôY¢"&€¥7 ¤úæ}’Y²$G±7 Œ°q:Îȼ‚³‹JCbiŠgìæA»4nR¯Mcê/¦nh ÜPÛAÜÞS{wט–Vë']nšöðþÓu>Þ^}¼ŽÜêª^ëÕjÌÎÂ4ò8‹r)¹åS$çÁí§‡›÷ÿ¦>ðÔè'CeC-ÉÆllOmE#ÄtˆèX¨û{,ãnüÓÝ͇›[bô­ò²kvÛmÕ˜¹Ã_½¢Ê,Ðv“>ÐEÁâ±D¸© Ò ZPK Š,Ø­Úr­[7½ÖMkj¼t°]"–Á}µ6`šï –Õ‹ùBnDÓÊf¥¿8$–e@½*5À7§O+YO:u{¿7¸vCÀËr>7›±,dq‹!ÏŠÿ{ó§]­Û²Ú mæ4m‘e¨º¥©B7†ÆöÕŽ†^ªÝÊÁ¿h{ޙסl´=0<¤m š¶\­hôÀarº3qN“2c ´Ú¢ÀK:ã{«Òm%ô­`Ch{'Т∎¬¢3=)tòXfçíÓê´}ê P¨Ú»º8²M<‹R4gIwP´G¶Ip0IññIÛ”GRÅéYÛIJ(\9˜ïPß¹Óœ[µÎYðÎî,|Þ™zOÝú’©ÀÀ@Ó6E#n&8› ÁÓ)åh'ð¹}äÊqÛîê }ëáðÂÔµ6[0&¢Ãz {­‚¹Yh¸óôQ6š[ ™}ƒjYüºw†ý©Ú#&S÷+«mk öѼcK-ö^ÊvéøE§ YbJt`5Љ”hrXN±¶z×.«ºlAƒ18Ä! E±×E7ø1ßÕörA †Áê<Ü?Z”{‹]­vÈjD޽”%¶4'¨åÝýÂéÞ?œ6Yì6{~c°_ú–,SU6jAâ­£ öu5A%_x·VnS.†©H1Èo½_³êðV¦ãÝ|ð‘iïP1nr¨)‡X-‘é¤kóŠ6 ;iZ¸ˆÉå+¦euÆ´x¨¡ii(YyuªäyâÔõq„ Ù7Ú‹ùn’dßárÕk)en«Üß pb´f0‹Š–ÚR ®&ÐM˜WÌ)|’þÜ%&ðµK2Z e”Š4H‚’6ÍnMy¯e¥K¾¡}tx¬ñ†Ö¥%áV[Ù¶ÕųÍE¤s¡‰Øðjaæ!+†ÚSV-¿ŸÇIwyá€e»Ù6é¨:ƒӻͪ|66ÖE ŠZ/ÁV×-Øh´gP€ÓÆ*ѽޮ¬/´»p¸MVL¼âi b —Ò™8ÞüL¨ÒK²ƒ#Iü‘ÀLwÁ¡ß»²Ä Œ6»Çÿ¸uI˜ŒÓ-š©© ’`‰h]ºŒ"!tw÷O4.Íß ¸‡Ï—eY, Ö&È0ÔÓ¦âK‚7q`š{M¸yèS\Gã«.À /»øjCdÊ/N—`˱¨HZ6Ž \èý¥Ô}ÉæØù‚=ˆ²<Ë;'ž&ÜÍ·àqþšŠ·Ó r=é=IpÒ-&<·-ÓónquÚ-vPöN“)js칄„ “çiwPÄÇ^ÑVßÕ˜:ºÁ°ªÒ¢Å¶y5ÙVøV;¥îÊ!´¤p¶¿…·¯0ƒWÖvžÌÆF¡xÀÓÆA€6–‹}7>t˜øÝ;Lüê&ѱÎÒº3ÜûAí†ÎÑ¥íè%Ëq)Coö…n\6_¬v£Z­ Ÿ9Lø©>ν½Å‘=¬Y{T9Ƀ'Lu­¸†|é„®ÖW¿e–O£õÛ:ëÏdZ†ûøÇÈ\¸È̦¨æˆ*᎙ɳ(©˜ 7÷ï—P€2Å,ìŸÉÿž6…ŸR‘ÏH'ÒytD:‰GuB´AU‡´)»; <»±Gx!}›¸Ñ°_‰L‡ lâ¯zõ¢÷M÷ªXaÈ}v©Jܼó>ª¯¦ãjp_Nz+и›`|Îz«!Ôé3é ºCùsQ_HP…Tà,åê˜ôøL@¡T–§cÚ.åÎÕPWŰc§%çÄîY(ižQdªbzcFPϺ"hçe£W†>n~}7žÖÔ`RX»•® !x9øz.(KM`®’Š•cI¬qh»Ú ‹³ÎUŒ½Öøêµîu°ÚœKQð̲Üg(ÛºúRÎû;|‹‚*IGùI÷t}p¾<‡‰Áõ³äTt§ÉúÉÕ»CËààÃá‚ãä/Å$EÏ þሩC†l xˆþHß<Ð+LáÜÝ£˜àÑ”JÕ×îJÿCGxv%‰Ä‘ÏHD„®ôì–x W88Âu¶¦ËDŽnâkÓ16hJ}Ç,‰â,éè˜öø¥t‹ãCâݹ·}È×u9¸%Õbâ‚ߎy¢þ—x|ë@Ár±|(å9õòàçå=ÂúµWtA²Á!M^9ô ‡¸ÎëWŒAÍ  Îh˜‡¾L«JtBç¨wPäÇJ& é`còÿ%;âPÉ ü†Xý´’Å)À&c9Ïi™‡Eâc¼_­gŸeü•cï ^cãÛYUËàJfé+š6:óçPd+ѵÑmHõ”P7a³Õ…9R80JÉô,Ð1#uK!˜MÓ|Ä…‹j6¨³àE»A*°ñÄ=uˆ \¡§¨¡r1 ÖúÙ¸«¹IÜÿ›Ý?‡Zú,t]—ôÏÌ„ÿßXPþó„T—%óƒ8PıO 7W2°Ýþ&L=·B$)ý_tŽ{C¾–ºÖEèþg£RˆÔ¸&ÖRU;Kû?6ô7Mz±uhú# ý§‘>épm×Ö`¦Õî¿5–dÛÿgJ¹ÿ£ÂÜBå _ÆÝâU¥Ý;`°0øWµqÓøº°2Ž4½é¥ž…_no~uìR1ñÄ_°…ŒðÓŠw)üßþ{vÿßõ$‹ £ä§í…âyæ™ÂýO³KÐxÉù0‡ŠÐ…?'‡BI0ÅRñlBªÿq†endstream endobj 1846 0 obj << /Type /Page /Contents 1847 0 R /Resources 1845 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1844 0 R /Annots [ 1849 0 R 1850 0 R 1851 0 R 1852 0 R ] >> endobj 1849 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [293.8042 166.1882 355.0043 178.2478] /Subtype /Link /A << /S /GoTo /D (server_statement_definition_and_usage) >> >> endobj 1850 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [395.8905 166.1882 444.6373 178.2478] /Subtype /Link /A << /S /GoTo /D (incremental_zone_transfers) >> >> endobj 1851 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [309.3157 135.2823 370.5157 147.3419] /Subtype /Link /A << /S /GoTo /D (server_statement_definition_and_usage) >> >> endobj 1852 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [305.9683 104.3764 367.1684 116.436] /Subtype /Link /A << /S /GoTo /D (server_statement_definition_and_usage) >> >> endobj 1848 0 obj << /D [1846 0 R /XYZ 85.0394 794.5015 null] >> endobj 1845 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F49 1358 0 R /F61 1466 0 R /F40 1265 0 R /F14 1060 0 R >> /XObject << /Im2 1455 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1856 0 obj << /Length 3884 /Filter /FlateDecode >> stream xÚ¥]sã6î=¿ÂÞ™µ*’%=¦»Ù67·é^’Îu¦íƒbÓ±&²äZ²Ýܯ?€)ÊVÒÞ\ò IÄ7-f1ü‹Yª#]Èb–I”Æ"-·WñìÆ~¸Œ³pH‹ëûǫᄄ|VD…–zö¸ÖÊ£8ÏÅìqõë\G2ú+ÄóO?Ý}¹ýáçûëY2¼ýéîÃB¦ñüËí?o¨õÃýõׯ×÷"OÅüÓ×ßoîiHóßßÞ}&HAŸ7½¿ùrss÷éæÃïÿ¸ºyôg Ï+b…ùãê×ßãÙ Žý«8REžÎNЉ#Qr¶½JR¥‰RR_=\ýË/ŒÚ©“üq$•– ”2``.¢´(ÒY–‘VRYö›²‡C%z~2û"Ÿê=›ÆìËÞ¬°›ÎÛ†À%ïéÛîéûù§jlËå¦j 0TÅùü–Ñ™±Ð*>Ò÷©í7Ôúùîöjý&e‚ýî‹Hº•È"™9œ)nEŠ%‰ŠæŒ³k™L0‚݇³rçù޾EF–F*Å_Q¡a?u’(ÏÒäï®ðæ9dxÀ™-©"ÂÒ !¢"M%-`N5ÜEGB[úëÅN}*_ÝÀrivpÓ¹ky~ÃÈí®¯¬@»âIÕsÓÒ‚«èB D” ¡g™ÐÐÐÅRKH‹‹„VLi½Ãƒ•«U…$•õb½o·‹òÐoõgCKGsN LóHg`]Þ¥ÐcMÞ‰Ô–ùbLããÆtÀ?U$Ì¿Ž:˶é-ãÚŠØŒ#OfS+Ô(;iM_Ô8û…3¶ûª/ûêhèÖE.£8MSwëd;³?‚*ƒLÄóÓÆ4ذL ^5Ï4ðÇ:(„U-7Ô OðŒ¤‘UÙ—ÀãD+«ôáêñ|ÝÖu{ò«º»þzãö]Ybã±h~& ¼±å¦¬š.òXEÇ©Eú·]_ ÉÖ[–-ð홽B츗rìt¦gì–t))‚{ÚMÖ¥W`Æ¥ºIŪp:ÿ[œÆt[°äʬËCÝLðΨ7¶Ad!‹_ R1qOƲˆ°;gpyÚš¤bËã‡_r!"™¹J˜¬Â^qi, øŸ¶a™û-ŽåóÁoˆãUl 4@$;x¦g#¡8àïhç,ó€×ƒ@o;hÇ]ýJðSUóOf,‚Y˺¶H!~óù¡³|Cï À_A¡Ç±¦ØQdEÇ£ /ÎÏ™`[ƒî+ISr_ëÚ-vU(YÜhš5ˆHk7%ç‡feºj_>Õæ#ºD5ï¨k²€+¶3«BìØHÃ--ñú–fÏ8í‘ΩÉ8¾§iˎɫڛ 5 ÆD´¼Dŋҽô0êjk!¤˜ªsðú¯{â1{‰Ú1`ÛvUáýî?½Â "^rïF€«–^aWî{0VSh=¿®»¥"²òØV+ í®P£D’°Œ†þºÝOÉß].Ç 'd0Âò °ng,y<ìèë,-·; —X0pÉž¾D ìÚ®«@ lþÜ™¦ã!{UdHo¤'®Ái.]T×ÖGÖ·ÅsØj5{r«§ª3^õìwGp¬è®Ð«7g®ÿ\íYÙ§¬õ*aálåvgå]Æ k„æhq­"6Ë֚¦æÖÙ!àë/ôe±n4 ÎÚí³i»žÍúÈf+ey‘±Ñ^·mÄEKÐöK#ŸC8¬• /™l+µ¸‹eî{I ~px¬ÿ ¬#ˆÚ“3»æcÊ­£x­ãx.bún˪ö¤7¦Ÿ ](ˆéc¡¥_Î!:Û–umY»CØûd‘é0>щ\ó:_<¿†?rvØc•:g½ Q“3:sâ9È?äy :u8X,î…5Q$$¾ð=_€X‹ ß“©käÄ(~ziÚSÃ0s´ à(Ïh%„5§¯¼Œ7ÂÐiÚž•ŸÃ#¡TYĈüƒé{4LöÐî g>Ü0RË!€HÒ‡*£(8“‘Ê}¬Ò´S¢D2ÔPVU‡>§£ ØÒÁêCŒ‰p6Í nêeÀ5óÖ )l¬·ÐжJÒFY `ª­“±lÈ!”—œfK3D+Uï ‘8ßpÞzÊò¸P[© „Î *¤¢7•ìY²±qèü8~Çqö•‡ØK¢Mɇ"”&ªqØág©ù±2§ ¼ DàºïÍv×ã eJ&]j Z-`c¶~èR&DœD™Rï fœ>1>U(ï¼z n”7Ü™eµ~eqؚΚîÍò°ï(܃E&7…´)ƒ{ë- /KËlÜ’n`^È ©¥çëQŽÌ˲± Ú&¯uûÌö†å¾¡H:[0å³™’¥‡÷˜‘äQŽù]<™…Rª a®|ã2D í­c¹„P²¦ÀX† ›8%„q,‘X#£ÝzFjÜr¤– «%È1i&e:ŠìÌ‘º*œk_;T¡b4„’¸`‹ÂUDLJhŒA)AÒN}±p6Q«ÔÔæAšŠˆ{è˜ômÄì3#$bHŒ5Å(´þTP7¥…¸° ÙÉ„µo‚.ãh—ÑŒ°ñ«QÔEJ_'éæí¤Öºò;M¹e‡âiû[÷Ó,˜(T¼£± ÙñÑu´äY¼¦rõ=ô_ïçÚ“œÝû>¦igþ¤–=7®Ø¼ÔM&óhºÑ(ªÜÚn%ã üÀž·äØA+äÀôŰå°;•>A zmöû²¦‚×6GIXZÛò¶>ÁŽ˜w<º¦mn7!HœP*pe6v æŽ}JÓSß®â¼&6\ÖM¼ý$›?TÁa:“,Ñ’ø¡1¿y€˜Ãð`P7ÐÊ˳+òÉŸN™‚dÈ_°MfZ9k¢aã,”6kÁ–å>|ƒÈ‹cŠ“1Å ²vãÒ¦*!£¼€ö»FU½eT~þè¼ ¦9ªXëæ(ÿÄLRaz)giëžZpØ‘û…Ë>º]KN%笫p9<@|fÚš6 Üß|ùùáæsDp2|vâÆ%e9ëaZ°_œ²eÍë(Qƒ{ز™éH °9âýzÞ_Ô~yc‡øÇa°¶6Òj÷gÏ'™‡¡ÐÃ$-ÁN¾YÿUªÀjò~ý7Äz»þë±(±è—›Å¶ÜíÌj) PAyrH†À¨Yåéûtx¬ BFÞ;Ë"yà˜’ÛõDa¢„4Nß-,B(P(™9':Ö5PŒßÛoDŽω€šQÂL.A*ˆ=n¡W‚] HuE‰40CJÈ'ÕÙ;X;'ä±s(Eñ “.Ôj¸ð¾ àè˜åª p´’•«¯K’×Â+å©Ý¿:I;¥æ8RÒçÅìS;½­›‹Œ©/òÙ­1ðÇrÑc¯`)¶L„ãkn7¥ºt`4ÈŸ¾9“Ý4T=±D!ØŒXËß2%AÖMìÁi®9Û(ØñÙŽgð£ AÛ‘Q,&ØêÚ%æÅµr•Tes>+VÎ"¸#[uKòÔoqN‡^Q{$U*ö¢‡c(U<#ºçÆM¢Ü+.“b2¬v¨¬js» Óðc{2G )?Ny’"‹tâó!ð¾«I‡Áhã „„аb)Í‹º‹êì e=H“p„á*c"Ê6Ù•Ú†èÑ-5õ˜Áÿ²=ì!%yû1 ’û(Ï3ý¾1 ±Þ6¦Ë—Ü{Šˆ%üAÔ¼8&ÖTÅd0ò}B<Ö%ãÄ4b|БÂÚ¯äÀ%E¯'R —ݤ<‚œPX‚]. C‹ß™¡UзÄK»ŠÞp9j%]¸tfÀeVDI¡]Þ¼X˜w[¬+d?Ì(%£¢HÏ 8UËÒQ®ü¶?¾óñ—ëô‰†ÏløÁÚ¾n·ü‚‘ÌkzhO 6ºí DOIPí°k·ôݘzw¶›µ3Õ@Nø*’8»]¸\+dthöJ±¦š~œqŒ€çêHVÚ-[´4Â÷óÝá,ë šš< `:Kµ:èЃ%¢ö•ñxE:ëhÿ[«¾¦¦l7›º”ßíR§ÒWK·[WK £ Ûå“ “l–fgŒÊ½7Zh28Êoˆ~³KIT"‰’D¿[ãaÒ %ØâÒBJ¬_øzó;Ša3Ó4’BžÅ¡)£ Ô Âg† ðö¯ …&•GYž9ÁªÙ”a5*s±Ui¾Ù²” •åñlo““Qpò\·OT9ß;É ÑúfL–F…HŠ‘Z»Jw®!®ÔÅ(¼™  |#\ ž(P`(#fU¤2Ô¶²«è!J)A¡ôÙé**!¯8}1p$Sé[Ì™ 7[Jd2&—ÞÇ‘²5}=ýCÄØ1dÕ&ŸT-y³¬+W L§²8«%n>áÛY6Ç€£ìÙ~âùd¡]€ Ã%=ëeöYƒZ/!Ï'NÐY™ÚÐ%tC =~æËFgAÛ,¥ój0èxG—ßíê¿xá+݃y¸òyµÓ§tCÁëüü|…©èû ñÒÿìéioʗŪ»½œÒˆC”²šÄ3ZÌkh]ò:I^ÆÀkáü‘š_Ì_6Œ[þŒÜôŠ|vÍÐîðülìã2=CÄžáÏ CnÓ[´p¯T¼±…Ä¿žˆá™Ä#Š3áµSíeÀX¡jM–Ÿ—z2®îå@Ž4ûvÙÖ\—à‡ Ú>¯w–ý”û²œC/ø^~¥ç[³Ü”MÕÙ€‹ó Á %pˆ´‡Ž„IûÒ= ºZ¤:øÕ@Êþ;M(ZÏo¨Å÷ƒ—÷îgZA©xe6d"á]J¸Ë) ê¢V¡dPB…6GyÐâÊÄ…øþauGúZp)“³pB&.íƒÖPô‘ôû,»ëíTnxߘ¸&÷›–Qr0º”œ`yž?~@CɃi*çY§ã)NÇNЯÝ[9צ%‰È·è­_»B,?QÈâ™»¯ÿû—°ÃÏ„ÁY«<—Ó‰ÅMÈéàW½‘€߀—ˆ’s_¦[ücÚËCýiýÃwendstream endobj 1855 0 obj << /Type /Page /Contents 1856 0 R /Resources 1854 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1844 0 R >> endobj 1857 0 obj << /D [1855 0 R /XYZ 56.6929 794.5015 null] >> endobj 1854 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F14 1060 0 R /F21 1034 0 R /F49 1358 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1860 0 obj << /Length 3688 /Filter /FlateDecode >> stream xÚ­]sÛ8î=¿Âo'ÏTZ‘”(ñ1Û¦{Ù¹M{mvîaoYŽu•¥¬$ÇÍþú’ú°ìl¯—ÎÔ$‚ €(¶ á[¥q ­qÈâU¾¿ W0öÓ38¾EòÇX?Þ_ýð^¤+(Éåê~;¢•aš²Õýæ7ïí߯?Þß|Zû<=¬ýX†Þ·wï¢èç퇻÷·?ýúézDÞýí‡;ºyóéæîíÍÚgiÌ`>7ÎLxûjýôéú—_®?­¿ÿùêæÞíe¼_ ÜÈW¿ý®6°íŸ¯Â@¨4^¡L)¾Ú_E±âH ©®>_ýÓê©Kò‹EÄ)OÈùH€,„v$WI¬)¸Ð¼ß•ÝÚ÷öE¾Ëê²Ûc—yœ==Ue±¡NßÐ`vèwM[öY_>Ïà‹jͼj ¬›Ú?™Ã¼vÍR¯Èý»éPøiì]Óœ–­{jº²~DaÃŽ}ÆÇ\³ûñ9‚Q±×ﲞZÈ9þÖD^VUÍ·€P³æ¡íʦ&Pž™FÑêѦ.šCW½ð¡ ßG`»&‚×ð7¡fw`gäÙ¡+,_¦ÑísÑ:6C ƒv CeŽ¿ù®È¿PsÛ´Ô¸¦Ÿ9ZâiE"ÑÄ?7{d„%–{@=å†3‚†Ý4À52"PGàÒ =V‡b‘z€[W禛㛯OB3œÑ9id`jA€§ç‡Â¬»cÑŽõÇ¡èôºQ’TN¥9 s.ÏeF ÜQpâ  ŒÁIÉ$ زç3Hþ‹ —-x>‡…{ýwòª/4_~>ØØ³œóÁbÐ)äeFÖ'"hT¤¦¬ÜnàˬsnBK¤'Xb­Ø_ŠnAÄ, Ààœ×dÁ tYÎ-&\«üJB÷·m³÷7å;Û¢-êœ8h2¬ñ0¹ÄˆÃ9ád²a`% ù˜“2“WAª¸¸(>΂H ep²¯Ê8!¿/âÔù}VM†ÁAêâH}tsúFB(êÐiŸu½%ñ'x7),ÀËÞÖ¤¹\iÌÍ9$Æ:?ʱwëh$£bú{Õì H]•=‚qI†eõ-xc8` «Ð–™"û¤c‰ÚHy³r—‘(ÏrCš?¿ Ì$æ=©çî‚v˜9¬b¬ÊUÖ[8ýh“Ó¶ô;h¨&‰Z FIˆíj (†æ°#F˜nUÍ㣎® ]Ön”ØBÁým1TøOshkt¸\('t›8ä;j™Æ)‰0„ÈêGd¡t›T8ˆ†‡³/û^ßp‘‰<``ÓÁÁÿÙÞ¬ƒgn(a”‡0MúeòÜžfZ†Su«Ä,pI5Âx‹˜‚" uït !¢á°¥Ú™nC¿f¢³ MÓÒV€mŒR7/u¶/sBCzÚÿ Œ9JCŒÜ.µ;+é=€6ùKgu,7è±E(¼¬§_sÂn²§¢ît'2j&†½e©†ðÞ~üÕP¨ d_ì›ö…Ú9܇½akaÈz-cPXà &X\Ý ûƒM‚/Ù.ž”V£˜“bÙ!vèÞã^F?æ, ¥å¿h×Uј‰ÁTÖ:€kuOƒƒséné©1ëeëâÍ É\•–%±l”ˆ Î‘i=‰•! hOÊëÊ?õ@j|TöPD Ò­©AÊšbÅaâ@Ñ Â+ƒ£OF¼Ê‰PYAãF%0Ýj.·€ö¹=ÕÅ<£è‹ýSÓfméBe0±\{AìY OÙvCkÞ˜s¥Þ©¬]ü,Ä…³,åÕˆ`vùª4€ü0²—oÕ!Ÿ ’ˆ#Än)ƒ˜ÇÒÌ0vqJXH¸¥ÝꧤD<±Ý‚ ñ x(,%©‰M ¸%õq«Ô+€†¸:Uñ\T¦}ܕڻ+Ì…]±´?ðE"àЛžþ7 6 Ò„¦íé?˜³,jÔüÍ,ƒÊHïæaŸ æNè¼¼9äÒ.Ø´KâfA*ãè5qÇA"„ Ù´ŸÕEŽPyƘgbò[[[•nHÕˆÐót»æ €ä¤ ÒDIØ8ê [/Ípv:0DÞÃSe{z/!‘Iváq{ÎÑIëÚ²Ù˜sÔÉ‚¨¿ÕîOr ú" LP'V0wNÈy‚ñu¾g­34żÛíB*€UÇXFßI½Yò>€Ú @¤Ql–}O»¬ƒcd“êC ¦Ô0"O¬?I$^ef'öZ.Ðn¦ˆCRm}¾HäjѲÚdà1ÃÜÜ$8btyº?K”ÉëŒR—Ôç‡Ö‡½ˆv™Ë–wÅÄúœžž¦;!d@vñf鄌2¼’ëF!¸ÿ$Q¯˜òë‚)[,­€5(nî“=µep–F——wX ëO¶GXQN¦ [N1Ê\cº‚÷½€6v J¤Ü{w÷ùóÍ[ŸNS£ !óƒüúvwмY{Ü’C1:úIçp“zÈdˆ8GW{ªS"! O_Uª0PJÈñÑ‚ˆ@'X$gEã-Õx(¿ãòLí$ „tWà_Цe{W"f¯q†ƒ^Qý¥§z‘ê/Òå§ú®È8äçiѼh™¦1%å[î|–Ê §ÏqNýPq !v€¬Wœ ŠñîF—…‘×WìÒðk2§{øŸ{7'¢¢‚C͇ý*_®þX±mE᤭w;HA~¸ÝóÕ»ö´oËRöǤõ¾ääâŠa‹iÀÝb6oßhе½ç5Ç·zÔû8Ÿj4W¨õ5ƒ6@h`\³†œÆ£w?FµaüÅê5κ£÷uM«Ìj3«Ó$‡•A3Ѳy„Ï µ¶¬:®‘$rû¢´Ò-û4 wè÷Að×9sh7áW×ê¡;<=¡«À꼡a£h·£gÎ멎åz© [š”ù>söñí+&ÒFœ‰ ñ%y¨°äE·—k$Z*TúÅ×§²¥èlúæ}ƒ//°ðêi°ø˜¾{*ˆ¤œ2r›ÇtÁ<͆»Xàìºò±ÎzsÙt„DE}†aûBÚ C€Êf1¨Œ™y%ƒÑ!>lÙÇû ð Ìοù 9½¾N>=™Ñ´VíÞnν˜+t¼âòƒ9ÇGfa}iUè7 …Zˆ ùzô=©…<ªºpï CÝäøTe¶Rß÷Yþ¥;›1†ßxÑUt>+c]P[‹… ¢ÿ|ÁúÓ\S±øÆÑå•ÖÂÒ“#Åœ$…€e²ögÌS·/ôž8+„"®Žªæ•P õÊÑ3'­{â<ºwÿY kè!{ýìDêbjMX×­BéjˆÓ8 ¿²qEî±(g„ayódìOYªÿá@¾‰JÁNb΢RÍëè“Ô¿¨]‹V`ñX`£ø¦è‹vo°†¸#`âºáÇ~÷âP&„±ÌôˆÏI R 9ΞìG9gê¢âÕâ]’@Ž*_)ÃÎk¾EÒUJüüÎGMè–kðêòÊété… ütmû‘¦rþK˜³B=f ã-bΦo˼7#ÚóÂP¾ËÚ,7_“à«Üšy‡’8Àé^ê>ûJ@ý&óжÏJ³ò¦ÙSH"ÄP=.½GóäÀ|Ãi}°ÐQ–ý¡1” yòÑ–³/ð2úz´E|Æ/úcÓ~ÑŸò¦öΑã;GBÚf>üBr[37™-.}Ù+â?Ç]8áÐ]DßýÕïðIt”€‡IÏxIð3AÊUb™B1K…ÑmÌùø+è¢áŒæ›r_Ÿîê¿ðõlÁendstream endobj 1859 0 obj << /Type /Page /Contents 1860 0 R /Resources 1858 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1844 0 R >> endobj 1861 0 obj << /D [1859 0 R /XYZ 85.0394 794.5015 null] >> endobj 1858 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F49 1358 0 R /F61 1466 0 R /F62 1469 0 R >> /XObject << /Im2 1455 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1864 0 obj << /Length 3490 /Filter /FlateDecode >> stream xÚÅZ_sã6ϧð£3³æ‰¤(‰÷f“½´·Ùœã»ö¦íƒbˉfmɵä¤é§?€õÇ–Í´3·™YA H€à @KŽø“#‰È*;Šm(L Íh¾> FÐöéL²ÌÄ MºRßÍÎþv­“‘6RÑh¶ìŒ•ˆ Iäh¶øy %Îa„`|ùåöúæÓ¿§çq8žÝ|¹=Ÿ(Œ¯oþyEÔ§éÅçÏÓó‰LŒ_þãânv5¥¦ˆÇøîæö#q,=Ž :½º¾š^Ý^^ÿ:ûþìjÖÌ¥;_hœÈog?ÿŒ0íïÏ¡mbF/ði­­ÏB£… µöœÕÙýÙ¿š;­®ë ÿd ”ŽÔ€•ê80‘ÂXkF±±"ÒJ;îªô1ƒYÅÁ8ÝžËdœ¥à «ñu¹ÅéÁ ²3H€†È€fì½N«:ób]]Z ©lÌb”EV‘’úÉi“ãE¶Lw«š¸y5 *I„ ä1–i¾P$­ôŠœéòˆéJ‹ØÆ^´Z¥ÏÙÀ€Ê«£ä/´ü%ÝCŠ4©Ë’´¨^²­|4{`é ¬°” ° -×<ËŸ³áréXåšÞÈ` Ь~)·_éå—À&K¥„1‰es¶Yµ)‹jÈA¡ƒ¢bANî©kýcŽø'2ÂhòùcQn— ­më!ç eb‘hØ[°ÁrÅÌéŽø$ïVnÉ"=^:o{•=¦+â=•U]¤kQàçñ׈/ÇZ”@<o nɶìlxé8ä¦×—Ćeâž r“'J²R|].ò‰›VÐ_Ú_‚@ùE}xå ã†BJ€Î€WƒžKæOÙüë„fzèÚH €›_ít³Yåè a®.ñ©i=‘Q¾°Çç¸Kz^| ¦ øG7qd}þ‰ ÔÒ=@=Jäø¦&©tU•ܱ5C³¡3Ã-¼7¹ç(Z+Ü2Ƈ¤gñž5ãéG áøß±pø¼½ÿ@Äý— ¦>ÿÄ­!¶MÏÿ‡^ç£ãæãú¸ù¨8ÂùœË1M ßëò›¬êᎹ»žTájb¾Ok‡.'œÖÜàŸLIhÒ•¢³T$#T»å»Íd‹K´¨ö-;c ‡ËI©zG_hDC$îq‰FàÖIüéìh>ÈtQQÇöLØJ€@ª }ŽÍÉŽkeùE¾Ä–%C°àεðùñöþþê’ô=ÀnØÕDûÁikC¶'QU¶N‹°ºZaTfœý¶sQ\E„`mV©'A“ F: €ÕžDŠq­Ü.È rFqlß{djü¥~r» ­)«*X±öçtµËXigºû/h དæÄ"֑׌ai`$+¤lR¡÷œªC»ÄØ@„J%§wIWêø.i¤Ú]²þ}_±µ"1ArZ±PÜsWB’¶ô4óÖPFcÈäe3Úg.t`᳿1ˆÁd«ò…¸u¹aÁ%1xr@µN dÇ)ÐÒ:;vœâ`ka¥¶‡u¥Ob|<"!5/‹ ’s¾]i¶ ÐÇü ÈSÌŸs¤–Ïþ¾å¦,–¢È7ù¤K¦CÊ1Q>¸%3’vÃkÐÞÝA8¸»&â0æ„â›ÝÃ*¯øÌÄ^ž¶Dß•«œœ*Ç×[p’¿z”œßâ´7<<ßC@›;öl-YçÛÔ¢›µ½{“ó¨!DÐÛì§úžØŠ‘ ÝD‘1 IBÊâ逖wáö€_)L½`Uµ‹¶ØÁçd®»B®Éb(CnÚÚ90µÆ—qÜúè®/ãøp}âˆb^Eí¸c ýÙú÷Hi¸Òšç¿W›¥DŠ“àçKzÖÛ$4çÒ‚ž„ ÚàŸñR†ÎøÁÕnq¼ðYçuí¯9óåÞ5²[G$¡*ýæ.JÞ?ñ{~žòMÒZí6zxÍÎ5N557%à¶¡+q-âÀ¼Y›hH‘CLìO&7]©ãÉM#Õ-©'sw›¶ŸÛh%B Qä¤þFjÀ€~v‹0¶aß‚›å€­0*èû¯—€íŒ±ÎÄ>å|žV.jâ®5 baÒÿÎ$WÓQÉG¦+ ›ÃÕð Öœ%¦WÉ'|U ìËÛ‹ÏW÷T¥ŽDb݇ôÑhNpªåcÀK¤ôûJùc  b!ßÈ—[™€"™Ô·Ï'ñtJ³9Ð<€$ÝU}G:LÞ#X9Ù…Q”0Œ"ëa,£X{“~1Jú0‚nmâ‡XŠüÅiÛLXB%±°dä~¹üÆ’ŠB‘ÄqtM]©ãxj¤:ˆÊéìÜǤ(2{Oªo¤ô÷Ps HÓzüH«Fã Õa”»„q¯Ø 9¯>Pÿ””¯Ã&fÓÏDZ9·6î ó5=pÛ £á\OG<œ¼§¤?¾’’U„o¬dGêÄJz©ƒc°·Šû]8>­º‘ÐÝ¿À…R;髌 2I¨oJÄím;î¬P† è€¯81Ó¶Ù|õÝSz¸Œ ŸÃ!ís8¤;9¾î%6 Bæ±WÌøœÅý¼âÅoÒ;ŸÃPËPz×ϯº9XÞÔHôä`8ëê˜ñþRF‡0æ›~a‰Þ‚·´J(ÉÊIxw¥ŽÃ»‘r·Ù¶œå¤*ÓI]¯¯‰”0¡Ñ§ h¤,自2$È0{&p¨’¾«wNCyã pÓ]ý„7”P=£ó%~àñؼùnôýFE,wàý— bü¶Ë¶ô»4pél”¾øÂeý“8®@”>+Ž@wEFXËSwE] á,šT¿ØKõý”¸¯²9ßp¾£„çÛòýÀSP¸+“üaUBÎkdú§qב:;/5€»ÉE¸ÒmjÖhméÌ 91ª®C/îà†|„Û+ñب æNlmmv—kîÙëóKíð‹*C¹‡¿Áõ·"’ÍýHQ­¾@é7Wb3¤ZoÔo]©«ï¥ÜÅÝf‘Ö]&M¾V_3nÈ”#û†Ô€ }¬Crn‚=háµæÒÚð­.¯Í^ÃV÷3!ñK>™Ã¾šp½qy «›Ä?%‚,›^g‚WýÃýD<ä¬?gs3À)Q_³×¾á‹Œ~Áà{B…ñ6 ö>£{r7“ÝpäÆqè©Ü­ý„]{o@ï³"ÃË*º ÆÓéýÍ'>X›K³´ n»îŒ—‡¢¹*i/ë¾P Í‹t›¯^Ï%ÄÞôéö€\ú±pú´ÑhpE}sã.ÍÝÊè+ŒV…rÇíä] È»@wð%½é|‡/äÍ?w;Y°eo@ÈòÎwí.ŶàÄÜýî $ÙN‹Q8­ö“ÐúO,M‰úŒÉ¶À—öÚ ^ø†(^ËÐ6§ M¥7ôÇÛû®þKôtŠ›ãÈG¿Úˆpxk#?û?ýApûµtˆ¿ä'G¾ Ú³ Þù¸ )¡'w!„U0Jãà0äñ7Ň“ú­ÉQÆendstream endobj 1863 0 obj << /Type /Page /Contents 1864 0 R /Resources 1862 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1844 0 R >> endobj 1865 0 obj << /D [1863 0 R /XYZ 56.6929 794.5015 null] >> endobj 1862 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1868 0 obj << /Length 3775 /Filter /FlateDecode >> stream xÚ¥ÙrÛFò]_Á·PU‚9p­ŸGvo¯¬ÔV®ˆ%”@€!@ÉÌ×o÷tÏà (9µår±ÕÓ3ÓÓÓ÷@,ø'Iè*Õ‹8Õ~ˆp±Úœ‹{ûp&˜Æ³DÞê»Û³oß«d‘úi$£Åíz°VâI"·ùïËw?\|º½¼9÷d,#ÿÜ £`ùÝÕõ÷„IéçÝÏ×ï¯>ürsqëåíÕÏׄ¾¹|ysyýîòÜI(`¾äNLxõïK‚>Ü\üôÓÅÍùŸ·?ž]Þº³ Ï+…ùëì÷?ƒEÇþñ,ðUš„‹gø#ðEšÊÅæL‡ÊµRS}>û[p0j¦ÎÉ/T‰&2ž ”Š`-â0õ#%•`ÖÁt°ì Äòï¦.•m‹/ ÄËšçâ©Ø¡4Þà Z–k;¯l j¶]ÙÔ´ˆÅµEGˆ®AQ}û^’"ôÃTãA•šiÆL ? CKb6—È,oÄlËŸ?æ®äÀË}ÝìÎE²,ò·Ä;ÐòXF|ú#ëŠYxRÆ |¸¸$1œ«b’€Š…až ·à£]ŸÕ9¡úí»o‹œ ŽnUÆ<ð"EÝ•ÃIx;æNÂå-I9iíüMYÁ£Eq)«ˆUiåËDD,×¼nÛbå!|ÿ°‚÷÷Ì}xnæH(«f³¡c‚qT¥Y"´:áq0#õ¥’©™ñ_s‡* Y…T¨ !–p!©ΪFaÈç8íœÅ~ªdÒëJŒæXÁâê›}Ûцwýf¼oUdv¨{nxlÕ•O<ó±80«kÐ3 ­h4«î›]Ù=lh„¶Üz¤`,W§‰Ë’hZ¸zT•èeYÓ¯Q ¾¿þüñòW‚on@Dÿ¿'ÄsÒó  ¹NŒ… `îi4ô›Ú;¦±lƒ²ÅB.¯ÖŽ'5d¬µKܳÁSéÚ`äƒÀóC¹z ý@´î_{Ö÷ œŸ,AÝ0bSto¦³÷Áå˪"èŽõpà&¬t¯:8òÔ«~BÀ‰"^8ˆæ£yC*rÂb&Š9ªùÁ(“÷Ø>6uu˜r!Ré«$z… G5ÃÇÈ&ÒØWQR~"“ä+Ì>„•.dÍ(jtxe}OÖ¨têÃ’#[$ã–q¸ü#V–×7Ò<—†õ8dï % § ›SÁBÂÎ0zŠãc ¿‰‚'Seϸÿ O×ì;úƒ¶H: ýÍ$s@ç |@\£á tÀáªì²²ÎÑ!ªYOhðpoÆG¢»ÛwwAsp‚Ã܇‘T6’\MIq~Ó¯s¬üÔ,H•8Ia¦÷eÎ @=ãÔF®¯ õý –Ñ8ÞÚãåÅ:ÛW½Ó<æ5’(êð•| Å$, ðþÇ‹ íÇZGÿÈì%zšàD]tNÌÇv® C”‘|=C”3?Ü5÷áळãRxHN_töCªÓÎÞQ 4¤j²ÍË+!Îïž²êØßCr«W8qT3¬Œrí@ù:„»ñÂIX.‚~þ最ó/ø]5õA ï÷.~"Ö8»!Ó¡õËÙ¾k<:/MC›îàÿÛ¹{íÖ:µþºì˜GL¯àÜ©iË®ÙzŸzì(—“šý*düF-çÑ&É)›¼\e• Z“…kt^!¨º¡¼ÆŒÔÅ3aØ#ô=v—â\,kž’çv#“c W)¾”mG®–—ú†Ãahâ¡!×ÉÀ²2Œ6 쉛')nYŠ /§?Ðgã!&ª$C0#HÙaQ(2¡ª¡±Ýý‚€›NYroH?£RÓUÚ g»/jd'1á`ÂRpD•Ä#ŽŽtÛQ½ÂˆRÚO„ÐcN8WmB}ñ× ÂÑ¿ÆÀѺÃPPtp½ÅIYh@ PòeY8ªWX9^ YÁ}Á—kšp1ÅÀŒR9)‹b[ãŽÀߌm辦bÁ¾„¶±Äw`Å “– *iXÛü¿¨WBaÐÇ_t#›¬+щˆxê ‰1pÌÉdv%ï6µïŠ{:BSœD´‹“ø‡“ã¨'Ó]Js…°‘%"‹¯Ù¤wÁò¥ CRÙ¼,@¶ÊÍk¢XÌï/„‚ØÙësÁÔbi“ŽÁ¦tæÁ¶”TÄ6 ‚-7Ù»pb‰†²‰‚ÐzNÎètÀƒÔýÉ[äá-%Éäaë‡òþÁ¤t@:³/†L€ãI5Ê]Œ]`[VP _íÊÄ|¿z!vëDûBòåØ=¤:»²Òí^·Úz»b½+Ú‡£ ¢”Š_fÀQÍp0ºð¯ ôkÄÁíy 20ÍÓUC«d™°[4hô=´=¤Û·&ø òöÝ'0ÔáØ/ß3,pW-ý±ÎÊ ì'rùžº‚Û«8'!ä®[0Ï»²*»Ã¹ÂôXb×{‚ƒÂI¢tl)¯§«Rá¬àD‘§ýT«Äå«§4Bƒ[„Üâe…è‰^Ð&yøÕ~Wxë”5ÁG8¾”P‹¾Ä‡#:fdœÉE¾ ÆŒ\TUóŒ-5‰œ„bàPgò˜©Õ€ŒÆHìuf5øOvÈ){ßfC£æ¶ÍcgÁ/ÏŽ%Z}é¾ñ¼ÔÁ4)¢´ùüÂKÝp4ö5QR©!~yg’eö,ü è¾{f»F p &zµB.ï*œ¯SÊ™m³ Tv0I·]x×l9£Y,9€XGù.ãÒx*¼åâ^é}f˜´[®.¾t¼”P3òø ˆyE>W‰@&ÑW"®õÔe»ŽÓÈɺ^˜`WÕfF#LÖˆDXÍ™vód^´éa>¶®U ®JÅÚx%Àâ]Ä»b§Kã`KbÀwhㆺã èóÄ2¬nÈ(°OaqÒvç]x™>@9O7íbL_gæh9»«Òɘ-ˆ`J«lzˆ+¬ŠkóN¥À»›¦4<—&=wSâeÕ4í·DcÄTšl°(&ÞʨçŒ,e¥%kà@™€ªYAŠÆ3èµm깸Ú=4-»N'³Ó/u…íØîÌ-Ͼ͑?à3ZF¤eÛÚySLɹ‰6\Óg·¼mÜv<ÑèðÉ,_$16C_ÎòD§³|K„B"‹=j& )ü0é‹»:¢ãmÇÏØ‘†Jö¥g ‰„k¤ôi…ÁÑÕfSdø~³ÞW4b‚Yj @@ \àªÒ<$D±ÙvNËb./Ï»Ù|=×5‰ð¬¶°.w°ÃL×Ù•ÉrI­?ˆµœ-1aƒÃä<¨‘ýþ§”•Åø‹*}˜ÐMe8ôf;Ó2Æ? #ˆô6¢™ɘ5¹þ¦³t¬°Ã}`ï/möЍ’°ç:Ñ6ùIB›‘DÎGÉ"“°Ÿë¶Åwø®-ª5vø„v¯5GßÚÄÒÉÝ>0·tbžhËm±*QHT¸g¸“àGV€@ à©w‡žwjôh j®ÕØïæ´•ËÀ׌ôe3P½`ç–j`è¨S[Ç3\Þ‹[[¢™­G¶®ÀÚúpïÏNÆæÁÕjØÚÕ'BdyÎI{ëh"¡×Uá^W«K*&éjˆâV(Nì{0ìF;“#08ra Pó¾kª<Û½CËž|Ì2ØœšÐ|ÿ~D“‡Ìi0“2¤$®ÅdÈ•ä\ŽØÆÒÓÏ–>WñòÆ$Ä´@ÖÒó½â¤ÁíFR“Öȸ¯š»¬r£Gü‘gnyV3û m<‚2©Ñ®ÌscÛ}ÔƒøŒ~ž2¿FÜ0fž»±Ð˘aü+V”Ížð$ ¤²0[HeËÕž­áo:pKTäÍë;–&[óÇ<¦þŠôÄ»è+Ò3yäÃÁýhÉ™.HìÇøZŒâ*=Ó‚ËøÖ:â™v·ô#ü/`‘3˜!ñ÷ˆ87É,gá¼Â}çS½±‰ÌQ£NE ~o)Qè+)^{²Ô^O>ó:4YÓ˜;¤‘îYË :Ów!i¤X9~²4/20]i¾SÊQ…>~o:³[àžÚÿïÏZûo~A%T’œè€CÉá'2-SÈx, ú&äð3__Þ'==”û4öøTÿ/D8úendstream endobj 1867 0 obj << /Type /Page /Contents 1868 0 R /Resources 1866 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1844 0 R /Annots [ 1870 0 R 1871 0 R 1873 0 R ] >> endobj 1870 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [254.5198 547.3881 332.9349 559.4477] /Subtype /Link /A << /S /GoTo /D (man.dnssec-keygen) >> >> endobj 1871 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [353.5545 547.3881 431.9695 559.4477] /Subtype /Link /A << /S /GoTo /D (man.dnssec-settime) >> >> endobj 1873 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [367.5469 61.6747 428.747 73.5749] /Subtype /Link /A << /S /GoTo /D (zone_statement_grammar) >> >> endobj 1869 0 obj << /D [1867 0 R /XYZ 85.0394 794.5015 null] >> endobj 502 0 obj << /D [1867 0 R /XYZ 85.0394 300.4315 null] >> endobj 1872 0 obj << /D [1867 0 R /XYZ 85.0394 271.1095 null] >> endobj 1866 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F42 1338 0 R /F21 1034 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1877 0 obj << /Length 2787 /Filter /FlateDecode >> stream xÚÕZßsÛ¸~÷_¡·Ò3¿ Î=ù'õÍ“:îÓÝ=ÐsB‘>‘ŠëþõÝÅIQv¦I;íd&\-€ÅX|û°Xpø'Æ2›Él‘fš.Ìbµ=ã‹OPöîL„:ËXi9¬õÓíÙo•[d,³Ò.n7[ŽqçÄâvý[b™dç`'¯ß_¿½z÷÷›‹óT'·Wï¯Ï—ÒðäíÕ/—$½»¹øõ׋›ó¥pF$¯ÿzñáöò†Šl°ñÓÕõÒdô9aôæòíåÍåõëËó?n>»¼íÇ2¯à òçÙoðņýóg*sfñ?8Y&Û3m3Z©¨©Î>žý­78(õMgçOp&••3(ÅÜšŒY%U?Â2ÓÂ9OÞìójÙvùê3ôc±ûRìZ'X“k|˜3&õv† •²Iëž‹¤¥ß9È.)èǾ-Ö(™$o‡Õ[R6RVyÛ‘†·Í®£’®!ýc³û<´ßìë5ý~€®A•& wU± •5}Éb¾ºÏïʪìžÈÞz<ìî 3ŽR–#ý(«~bÐGü¶û‡ïþØ4;Š ùêÃÚ46hjúbw^¸oÚ`k ¾•uÁŽBL°T»°™`Jq"$¨ÒrXëtDôµpŒë~%—íaõ‡.•11ù¬ ±ÒŒ Ã0v ü7öáãC±*ç\¸lÚ„yQÚ&u¾JœOüæëu–Š,……Y aY¨<_­ 6i}0R–Ì›öñ…~Í0"–V2#´F·Ëë¡(±ÔGR—äøÉ¼ÿè9)Ë–´¸^/µX6Ž/ßîý¨A{W&‡P&÷4qkT_bÁ}¨ûÃ~JØõ'úÕÔÕI'¢¼ D¢“I¾÷9NóÔ5¶ „iõ[úb ¡¤M~¨2óÁ^Ú² £¢ŸeÊIpët²ðGEÒïÜð‚}bssâ³SnÃqiC󥞙 ûß©8`WÌ]*e¹A‰IÎÅ0%è.ñº©»]S½œúFZÒìé⨈!Žò*¯©ô.†xîvåªócÝ]Þ’(h.µ<»ú@ Їš"XþsÆKÜ Þ•§¶+¶Ö ÂúcQL¡Nà q„H©U¹Ì!ŠQáîÓ‚„›êõõ—Ãǰwl×ÃÄgGAÉÄ1ú‡\?4ÿ #xÞ‹ˆÿÆI¦å¼}[]^Ví8†ï›Çñžhª7O1³…2Z ä-Bã‰\{ŽeR«çsÙ°Öé\Ö×ò›¸ªšÇeÝtèá4‹ Å Ùó½÷µfºå1á˜Í¨ûQ“R$÷åêEé3BÐöÜõÞeíPâ'¾a¾Bw_†va5Ed•©Ç'¨ÑV€AåwÔýgS‡€òÔŸ¢CH‡|¯ëuéCÑ2#¥ždL8.æÈ$J[ j€Ësd=K³DÓå˜Ì¡’+” •·ùYÏ«6t}úkûy]“³ºàÛ±BIÆµŽ†½ßǽ|i£ÓP CQw˜Ÿa‚baQ\*…ù¸L3‘Ž3Hés7,Ò®\{?;Hųn¦’¥6‹^6¸¡Í “,¬=r©H l&øQc1ÿCÚ.ò p³¯ð· ­ïû£$qÒ¢½ ©À¾H1a#Ü ãe°H¯&ùo]lò}Òg9I²ÄäI§~dÅ Í)z=(UA¿¡FÛQžFŸÿÒF:!Š{å$ i F;ý< kF¡¾Ö!ì!ñìf@BSéìùÎûZ3½A(e\X5î~ŒB‡NÑ£n³…@@!GTÓ+ÛϤh|ÕuYç»'*zsý‘Š(½Bàβ˜ h†í™Ýd^¦ÉÉ1)¬¢Œh@»Î¶p!Æ»ÎóXæF ÂC|ç12`ÆuöD@2n!¤ã½ý8» z„ Î1ØS5ĂӾÇYŠ9d‚Øâù9ƒùx†:‚0aŠqãÔxŸ^múm6ÈèÿÆÆõ®‘ˆþ•q—NöfUŽºÇ”À f2A-3–ª¯ºAÁ8àιù ¦©`V[}Úµã`+ˆ±ÅØÔ2:t»´v¸ û9…`J™L!Ì5äÃ%QâëÁz«…_iÎŒ‚DKëõðU$·ð¿LŽ®–œÅDª€¼ÀÙïzñçB@fË2E•²ëa¼â‡«­\¼i`D‹á ‚áåв”a‹TÌ*J882•*Ñoás'k’xbHž–«|uBŒm;ÚgÞgEð!gÖšŒÐº’ጋßÇÄuŸ‹”rjÌ ¹¨¯5ÁÜ%ѽQ:’ àÝÐòq:еf…Œ‚-aáT9ò`œŽÔ!X5+g Ò饖ÒYQQÿ¾|BßbÃ0j—ðœ’I*O¾vê_$±óÍendstream endobj 1876 0 obj << /Type /Page /Contents 1877 0 R /Resources 1875 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1882 0 R /Annots [ 1881 0 R ] >> endobj 1881 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [455.0966 590.5841 511.2325 602.6437] /Subtype /Link /A << /S /GoTo /D (address_match_lists) >> >> endobj 1878 0 obj << /D [1876 0 R /XYZ 56.6929 794.5015 null] >> endobj 506 0 obj << /D [1876 0 R /XYZ 56.6929 769.5949 null] >> endobj 1879 0 obj << /D [1876 0 R /XYZ 56.6929 752.1525 null] >> endobj 510 0 obj << /D [1876 0 R /XYZ 56.6929 635.9912 null] >> endobj 1880 0 obj << /D [1876 0 R /XYZ 56.6929 612.7657 null] >> endobj 1875 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F62 1469 0 R /F61 1466 0 R >> /XObject << /Im2 1455 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1885 0 obj << /Length 3590 /Filter /FlateDecode >> stream xÚ¥ZÝoã6Ï_á·s€µŽ_"¥ö)M³mí¶MsÀm[‰…µ¥Ô’“æ÷¿ß g(S²ì´¸,¢†#r8ü͇–3ÿä,K¡s3s¹IR!ÓÙr{!fOÐ÷Í…džE`ZÄ\_Ý_üý£Îfy’[eg÷ÑXY"²LÎîW¿Ì¯¿½úñþæîr¡R1·Éå"µbþÕí§¯‰’Óãú‡Oo¿ùçÝÕ¥3óûÛ>ùîæãÍÝͧë›Ë…ÌR ß+áÄo¿»¡Ö7wWßuwùÛý?.nîûµÄë•BãB~¿øå71[Á²ÿq!géì^D"ó\Ͷ&ÕIj´”ÍÅÏ?õF½þÓ)ý™4KReìl‘ª$³NNkY$"­-œ‘‰ÕÆôZVrJË µ\l6Íëâ÷}¹{[,‹åº\4õxé2Iu®gñøGRô\b¨H ™áš„Êñós¹¬~B•-lƒpó×uµ\cÓÎ7ͲصX­v—2›—mKŒv¾,jê{ª^J"uûZîx GÿA³¥®n]Ù/0¡r;¿}¤Îºé¨³í¥Y}@mÀš@h‡!e’§©òBÓ`€™UùXì7½T-=»†ž^ÅÔô“RU^•ÌÚÔÌZ¿qã°N/Àh+•–‰4"Í£^Auٵ̫Ûp\–3gQ¯&†“y¢S§ãÑÖMÛM&’ÜXɜɑ‘0mž'NYu®1×i¸ö\¸îÊå~×VHMmbÔ;ó¦‰ù8µ21B顜j›œbuÆÔ‚v_PèrE/ˆ |n‹ÏÜM¬~E/LêÁá¿X‚÷Oë@¨¸«-w/å= ÙÚ‘|¼½‹V’Z=ï„*Gp¼±q¼ÙÖN²‘8“wD3¨'¦µ&QY€Ê‘Ÿ™˜//ær4ß¾EÕá„Õ#Q`âØró¦Þ½Vm9ja©…:`bjð³Â¤g§ön@ƒóÊ„A•ªX 4ä^ r“âW‘Š)¥…€ ÍØ¨¿¤¯z³ürJu(– k… äÐáJN[«I!¸¨ük¸ÎXkàš€ØThq2ÑÖdçeè¹&„˜¬³‰F÷4bh²ª-Zõ¡©£Ð‚½>´ø¾å²|îˆ86WèfsÅ ÃMÑ v¢Éô¸ðx²àŠ"8‘eþÙh2’ätTÙlŽ¢ J{ Bƒ,ëÎÃ!â:‡Àu€ÃþyUtå`Çt ;vvöžkbúRHª´QÃùG9FvÈ1\ðÝHí}· ¾™ü±Ý?l«ŽÚ_¿ÕŶZÃן~&*-2d ÍŽ¨Û¢íJnÿ»©=b0ÿ¸p€ð F ½Ë6g×Äp€÷UéS ¦r”ô¸ ûU&;òù§¦+‰Ú­‹®gl^«ú‰è‡¡ë¡ gt+¼Ha€½¶Ã¥B8úuû£_˜…ž‡ ¯êñìûØíµåV”„ÀäL ^ÐhŒOÆ©s÷4£Æ]„šžpŒšãq=jÊeWSr‰>’ÆŠ$S™Hs„Üžë=¬N´ËÈ@òq¤+ªÍiÛMø"—ú¼íÆ\§m·çÛîÄy-v+ÊXÎ:Æfçé¹&$(C¤‰Tñ²ŽÍØêÞŒ¡Ìš3Æ—ÞŒá…lGÌÚ3ÆoÆÐˆl*úlS¼°½æ _¦FîÛ[6n’ªùCIï¤8”kå….bÑ!UÐÁIPN§¥óÞÁ÷DqA£Éø4Àä±Â”M„4!“ÿ$…B@ ªÑš°ùß©ÜG'pð¹Ã>è*á<ÅÂ’§bÍb³7÷½ˆRXÚ‚t£\ždR¥Cå„å““1Œ+ïœLFJÊs¹ƒ‘¶˜°,´Èç÷—¹š7ÄSÖÅÆùú©‹ # fwߦô”Ãù)UzN‚ÖxN™U ¶ Ù/OªV÷Ç%À»$ü>¾y h-æ/Åfï3Íù#5A×õ„èRçऔûk[ì°®ä€mšW%֚ѰÑò¦FÅ@–%Í(÷¾Ýƒ>ßèeÙìk@ó3…£Õ~ÉàÐ4£ÎÓÇ`†$ÀȪz‰{›Ë pÌxnê¶z¨6U÷F ä¡G1eóáÚKpßpL!!6Dk×Í~³¢6ÜÑ(¯U·ÍÜnü°?s±¨t bö‰hçý¹lßå’9Ø6±ÊßKŒ0XnΧ 1×éT¡ç:xÓ»hßj€oK‘jxê‰2ù;2ô\B O}i¢´H‡Rܯ)UNçÍ3o´_ O´Ñ®÷ItÈOY‘Ð »‡F»mï ¸ƒ0X…¡ì ÅNçWðÇ| S,=±ä6ü€N~ tfFÑñW¥L]=PˆƒO6ÅC¹i‘Jï4¶›?Tu±{‹y0Vfùü[ÈrÞIeG œ¼˲٠ÛÔ€Ô~-{H9K…Ï¿*Ÿùô N‰k¤b\ Y}¿Ц ð‡Ò¶ @ÇòI8ŒÑñ·‡Þê©f˜³Û`wÞ Ù–a–]Ý{¥-x•âéÌW;,¼¼sÞ˜NÛA`:˜GÍc¹;>ïæ‰RÙÙ¹ÏñÜó®I”Èõ`òAŽlTò9lrŽl”=äÈHïsd|A¤á“w¦ô$`vË,¼4ë`¾sÍ\q‰ò¸æ¥Ó4±x/'bœ"€ÃÍ|Ñg€ªHŸcí0Ù •nØ”ÎРåLxFõ"T5=»õd!Qi8­è {ÏL¹“¡‚Øv€åmYûº ‘ý !­†æ²ðUBîˆÒ€¢vÕÊNKã²Daâ\ÎÛV–©’ÒI7L[Ï«/‡ÓïxÁƒ²a‹Z§‹gêW€FÔàjÅ)«U±fê=³¸ÎØmàÂ¥?l ÃX7›ã•BD¾3s`š˜y`µÚ$™Q£©G¥Jå“7xlª¶£VóÈãje8œQ«¤FŸé)Å-lqaREeM]9ÀËÁ–ýœ<ÂÞç‡ŠŽµH` šÍKÄ¥#¬-·f=*½K)ç ©ŸâZeM J¡„>¾ñó? ¤GãC—Dñˆ° ñ¡kx¾ûSø<> i0ãD8 Õ§M¯‚ß¹ SÐpμ“hÅ\§ÚsQ™_¨MGzQÀß`m&³ó"ô\2Œ!k­–C!†ÕÜ0¾®ðõáÿñäN“'·8áì¬L2Õ_‰-xÑÔ‹3uu… µÉãû”àùyCuú¿ˆ)ò$U.ëoQ§îð`§ûƒùi8¤‚Öt×8.BécÊbÙlŸwx’£ÁšÄÉ<;/AÏ5!Âðz4Oœr(à šÐ ò€ÍhÊ ZôÁQ*ÊUŸ~êØ¸éàóòE‡’^xþô¹ú éUB_sxLAzôLÓ:„R_OÃñÁfó«ëï¨ÊM?4°\¨‚羯ˆ¿N߀ÊT‚.E€o]lËÕTäÕ`W.¤uY®xêPämvŸ‰ÂÉ.´–€äºk| ¯z’gD©aéX~Ý_@I€’v.úê‘ú1À‡£<žw¯éêüŸ!’ž´¹›Ú  ¢èS”¬ØU-¥/¹#-Ò§ërù™ø<ÜŸ@c[tËu(ÌŽ«f[T|ÈÀ9ƺ Ä4Æ7ß”¶ì|‘[û<Æðåœgò;<ì Z"ÃB§Ò2›Hƒß‰ësÜÈ— ÑôXO8KY=ï‰ùP¤f# "Åk I˜?ÑÞbÉB»QfàÎM–Òe¥È9e wløzžÀ&V‘ý‘鸗r¾.™¯ ~þ' ~G±—²]dàÙ—ÿõßã+æóy6e¿YvŒK•¡ƒ¢Z*ôSY¥ôjÌ2XÚdg„Ć/d;øºÚC|Æ*@BgG_Èø7±õ W[*KtHºÌt¡ŠãÂIËY >‡.ËI©§±c"¨cI{æØç”m_ywÈæµö[ÌC¶C6·Ûïêruº¦º${Xµ¸ÂaA÷JJºð­Þ2½¤Ë-?iÜ5ˆeÍ)•f’«ñgtæWRQJ¦_Îe` ðâ­:ýÑ®g Ö6;ŠÜY¤lÑŠ¨I“ë,:7| ãr†&…ÏQ¼ZõÁêB]HÇAS#Ú˜D©jÐ «¨#3hxUj6ŠƒILì`Ö&½ÇõDXTfÄ>q¤1½ú¡dòZ¼MýðO‹$u6¤Àœ«à <øÕ¿>ÞñUIÍ]·LRÃíã{¢=ñÅÆoWèHêïMÖ¥G)ŧ!õ1£ØÓ—h#¸>×[˜wÀ!Y‡@”œú®NüåìDþ ÿy/þïè~½lý,cúb@XÈs„Âu:}¹ „аœHañ£/*ÕY’fÊM¬ê{ÿz¿endstream endobj 1884 0 obj << /Type /Page /Contents 1885 0 R /Resources 1883 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1882 0 R /Annots [ 1887 0 R 1888 0 R ] >> endobj 1887 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [213.0783 577.5139 261.825 588.2983] /Subtype /Link /A << /S /GoTo /D (dynamic_update_security) >> >> endobj 1888 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [398.1622 456.5567 446.9089 468.6164] /Subtype /Link /A << /S /GoTo /D (dynamic_update_security) >> >> endobj 1886 0 obj << /D [1884 0 R /XYZ 85.0394 794.5015 null] >> endobj 1883 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F49 1358 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1892 0 obj << /Length 2941 /Filter /FlateDecode >> stream xÚ­]sÛFîÝ¿B÷FÏX›ý"¹Lž\ŸÝº;9Ç7éLÓZ¢,N$Ò5)+nçþû ,EJt’Nk?p‰Åb,>—R ÿj'"Ét6I3+b©âÉl}$'÷0÷ã‘bœi@šö±~¸=zuaÜ$Y¢“Éí¢GË éœšÜΡÅ1PÑÙ»ë‹Ëÿ{szœÚèöòÝõñTÇ2º¸|{N£oN¯®NoާÊÅ*:ûéôýíù M%Lã‡Ëë$£Ç DoÎ/ÎoίÏλýùèü¶“¥/¯’ùýè×ßädbÿ|$…É\<Ù‹*Ëôd}dc#bkL€¬Ž>ý§#Ø›õKGõ§¤Ð&Ñ# Ôº§@§Dœeñ$3‘m¼o—Åã±rQq<5&‰òþˬôo³ÍºiójV4Ž£²¢éí²œ-Q°êí£€gcµîp‡*_sFë³c¬0&c¤m¹ZÕªnið@¬4ÅãSA·ËÀXÞð¨^ðs[ ÷k†³DiVûç¼yÜLÀR‘8å`¤DÇÚsRâ•F9>’èº*ðIJ½*:/ð­òûÀÔ}úÍ(xÁz®ZšnŸh9(²l— \ò A çÅ0ÑݦÝC›åe›¯Ê?ò¶¬«þ¾„„rÊ¡|•§¬]• >ÝŽÁc…’¤Mœü$cYˆ{,è,‰>im·Ûíq¦#Q|É׫BÌêõ«Sœ y5'úúøñ£Ç=ÿåôêýÛsqöîêÕ)üáVLx­x5ØÁ€kòs¶…‡ºj ϶‰ nhXœ· ²i¶'„mš‚¬WVö51BÚ,e;Äc}lÚsU™PÖ2ÚSñØx…#aT8ñQì³±cm›7?sš,«c@¶† ²5ˆJV:pQ8)¶X A¤Ã]•k02›h?Óà® g>Ÿ³þhoù½c‹Vޝ‹M» žï4^àg­)‹~ª·Hqð„–Îëu^ò–ìs8lŠY‰ü· bâó¼Í‰¨oÄL™ášØšáRkM[íM´…7QkÇpøŒà‰^G£ë'´üê—‚œ]Ÿ^ó¸hghž„ÁÆà|µÍŸ™ä2*h$+ H‘ Gýð53éMµ‚¡„º‘ÑlUúãuÞΖE‡Qòèôì­8È;J¤J%“$ŽEš¸ì…¥ 5’g;,p«' aÓß7Åãó´-×E½i÷YQ‰IâÌ×yé°F˜x]ÜØ,rsëãŸÌ¢|]o|@…±{ðD¾xЂ1y <„ó ŒÀ^1`yjm[¬Ú²ºçõ5Ú¾ì/gÄ>ÙÙbÁÅÚ©‹X£Ú²×^’K.êÎÑR-òrû¡“%)É…ày±È7«–ÖP@…Áº¬ÊõfM( šõÕ¥µu™z• d²¿ÓŒÒoÃÞëü ïÐÑ]2²e†)˜ÑMX|Bñâ¹èCÑ’r=å–¶k!ÙÔ#›@‘’¦&Äå±=XLú„? {'FºÑBJ/¢¨Ôó¼Êáå® >aˆñZŒT9àä"“ ¸“•"ÑqÚÕ£*1T™RÊè²j‹ÇEŽ¥Ó!ÿ´ƒÊÍÙžQ'XëÁ{LG„õcÛÐ Bó‘æ‘€lÞ0Ê«fKÐØÛaY0……×H½¦7Ÿ3pp¨õÃ8Nlò ÞòP!’:RäªlÚ¢šò™„¹_@±œXèÔ ®0¯éߤÂ%V w¥h­à]ŒÙæŸIPìVô¤Mò9!j9ÌÏ;ÄCUÆ ð£À)&YŒç{áÐ@™ áTOÀì»z-2çÜxG0í(Nû$}èðgŒ/ow#—>§ð˜80ZÐÐ?Çc ø-S%TÇC&ñ0GÎQ§"Ž]g :›Ë÷O–O©Wæ4r’8óµ`$d†Ð•©÷Íp°#¾íµAðRÞW³ç¾—]ÁS—`£U}ïÆÛü±ÂNõC,5{¶"…pçý^ÙKq½7_×üÌÃä Ðc¼ÛÝ3Ñ:¨öÕ¾l½¢‚†¸©  w¹ PNr&y™ïÊpЋ 'ûȱ¡'×K>ŽîQôÀfÒ”t!·„&b,ž`XM²ïqp-\ê&ôªÆ¡ŠbÖó]a+ƒîXì ßB˜[™“7Ÿ:èÀeì†|ïØ™&çÿ¤G,aé ½ýïÍXa»·’´‡#¥Pû—‚db„erðöJ%Ú‡ Å@ú ­=TìE•ß­|ze8¹KPÈõMÀøTâO5 ýVjw.ßÓÌÐÈp é $ õË(m’a¾@O­É£4i±}©­]ç³eYÃä^l™ »îó—,›µ½g¦äFÁ?ªzÄP¡ær™ýËv8ô¨®&éfàT!Xฮ^rÂ0“‡e(I=! °)¡Ö¸¾‰ßŽfyhƒeb¤RˆÝ[ eì —cwÄÚ7Y膂Å6B¼:Ï ôš°r‹lªÃG ›l—%D[îú´:­š¬kízZ(šºWL –œ¦û7DÕ¬^S}hÜ®¨Ò&Ò¾y0—K8ÄüƒG&dG€GFs{‡¿ÈõØL›Ý±éHN*„øÃïÍäa™Ï~´ø{ù#ÞÄFÁ=à•WÏ!½Pßö(û#—éÞtQλ š>•ªi³¯WY*…€c\21 âN&³¿]Át§}’‡ŒJ¡O¸´ÛùÅ2Kã=­2êŸc²£ø &Gh©²!“/•Y±È Óf…SÔïŸÎ° —Øoªï:Óé  Õ«„­­#X=Ƽ.Ø4È_t]VÁpÂ’‡ür>¹,” Âj¼æèûlSÏ>ì$i µä>4Œ{½³a[Ç*™³#R³LlÁ—® `´ Í3¨kMãeÎtŠªÞÜ3_§ï/sóà|¤Âã´œ!œôEoçe3ˆÏ„áùI¹õ¼Y]ÁêuCP¯€Þ\œÀØÌô3ø`.¶ \ŒkÈ\$¹aŽ•Hd -¥üÝÝ3ôù…è6ŸQ™6Ëí½SðûeG;b@¢S%ëÊ PR*JŒ! ¼–ÑI±0ë¡U²,Ëá½§Kw{ÞËü 3 ]DsRsr'bÃÁífD°]5²•(ZÏh rŠ%«&§…‘â{~ñ·ål³ÊéôŠŽf¾ç…A¾jjÂò?@†©Èè”>ôÀ }èáõþË ,ãozwïÀÜù÷ †­^ÏMå¸{š  °=öO3,‘Г yMíï=[ݬ"¦×–OËoš–žÓPcïÓ”ÜÝѶÞ6 Wˆ~w²‘0ï;®>²=1&×®æÚ; ½/—­#A–tWiß±©J†_Õúذ—¥º²]š¿ÐËúIîeùóæb§ÕÐ0ÿz ÷=¬Sv`My«=ì'¿¿‡ËRaðZt¼‡C~úW¯¬ùz ×-üZ§¥T¯çwîõëWF¿ßá{9#㮑32\üɘ9u®Pï}Ò†ë,€`qˆr0‰‹Ï4àsû!&1›ð…‡´tõGXÝFá›f½;ó÷=£ø› s5¢PâQe1«Oeþ³‡o8Úã ‘(€âdÉ_)x@EO¯&œá2èp_hjp2Ú ‹KºåçH*ÞÇ+¡¥pDßk¾™Áü½ÐH€¿Å¥u¸¥ù\|¥ìzÖ±VП*§’ä øœtôµ*ÿRÕU1°ß±ß@˜XàF¾þÈîóÀßþ}ÄîÇ#\Ü9=þi'®÷[e´™¾Gæt”ÚÃïkü‹C¡þ2—×ßendstream endobj 1891 0 obj << /Type /Page /Contents 1892 0 R /Resources 1890 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1882 0 R >> endobj 1893 0 obj << /D [1891 0 R /XYZ 56.6929 794.5015 null] >> endobj 514 0 obj << /D [1891 0 R /XYZ 56.6929 608.6007 null] >> endobj 1894 0 obj << /D [1891 0 R /XYZ 56.6929 582.9924 null] >> endobj 1890 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F40 1265 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1897 0 obj << /Length 3006 /Filter /FlateDecode >> stream xÚµZßsã¶~÷_¡·È#‹ß{OÎ/u¦q.®3ÓN’J‚lÎI¤"Rò];ýß»‹(R¢u¾K;~ ¹X‹Åî· ó ƒ?>±:e2W“,W©f\Oæë 6y€¶ï.xÐI¢RÒ×úöþâÏï¤äin„™Ü/{cÙ”YË'÷‹_¦oþzõþþúî2šMMz™hæßÞܾ%IN7?Þ¾»ùî绫ËLMïo~¼%ñÝõ»ë»ëÛ7×— ·šCFx¦Ã»›¿]ÓÛwwW?üpuwùÛý÷×÷ÝZúëåLâB~¿øå76YÀ²¿¿`©Ì­ž<ÁKyž‹ÉúBi™j%e”¬.þ~ñS7`¯ÕwóŸ–6ÕVd#|Ì:OÒ;×ÌMjÀŒ±éO;·ýDK¼Z,¶®ip‰0è Ä&‰ÈS•qâfy™HèÐ>:ziÜvï¶øÎ§‹Ú5Õ7-5|¨ê§#Ý¢jžH„5õ)èó÷kÚ²®^Ág¦§eä©\­:4»Ô0`¥*Ö;š4,¡ï ðC*…Îa-¸?RÒÔ»íÜ,8éÔÎÓ\ká{57/eL¸&4&¬Êèi¾»ävŠþó-Eµ —M½mIg׸ [Ö[zivóGjDƒJ¦'FgÓwQ!ˆƒ¶«ÂP5¹d7ï÷ý•ë©÷Ú@:e´$vÞÛ¢u#¾aq•üÄ7ÉÞŒ¸'Ó©É2|YopÓRÚˆÓ ”‚Ñ÷ųq&³TYˆfÒ+›‘¡ò4S:jüi̶”)…_™fEÓ‚›ðÎ!М¢sñ‰FMëuÙ¶nñ ¿¼¿°¢n1/¼C¤vóžZ{œeÄTÁ dxgìÍíÕÛ·'¢Y¹Ì³IÚ…ÙK D¤¹µv@’nĤ?ä):h.R1}˜­¼ºýçˆS…HM®z^å¨4I”f©ÚÓ„!eæè‰¡ï³ÒC O7*BÉØeM˜ÌçψE<Íry.R8KYnò³¡"óŒÇ(Æ È-Ež÷‚BrPظ…´®×¤°¹ÂÜÆj·ž¹0ÂÒGGT =72ɼ®@vô½ %÷Á çß”óÔl§»M« ‚àaÍ\Ø ›æR›áFâx›hyÙÔˆ8("0å°8H](;ÓûÇ`Â&,+#»0¼›=ÀMÑ’ä‹a¶²Š*cp#>¤…`ÑÈd¯’Ýb“àÄc¸`Yª¤’½¤^ÆíüSѶÌ;ètBu0Ó²?ŸI‚ÛKmn†xÎð3J›"÷PL¦H!*6?2ŸºóÕnQVÔHuúx7$¸ÑQ{Ä ¹Uªîërñ9Gæ RKEÏ{ <ÂLž ‡íüY• ©âìœÃ Ë8Húµ½‚°`ÖÝ–{·ŠÑH3…~¸ …ž ·,v«¶¡¯zIÏqGY•fšó—U~¸ÂìYñ<•:S#ã=[-µ2C½T^Ü_¨“0¡x*ÐC ¬O ¸^5pS €ÅV¡`—:ä›Äíê5Dd·³6ËGzé4Ï2Óïôšv‡g2=Ž‚cOœš§dªŒø[wÌåxÎSá鲄™qs®òhnùi¯„ŒD‹HÏò!ø¼|L¶ÈcÕƒ‡Wc gú Šœx1ưdj¥‰ñÊ ?tóøj¦å’D£ð¥Þ8 Ž»°½ù„jMMTÕêàd`Ça±/á¤öTTªØëa[¬×‰ÐVVÀM—F6Jüéž”$í¶„f·áÅ›-ëoÂ$B_ÀWìF_Õðâ6nlyZ¬HâwÃoÀÎÀÎÑð*’—~@“ƒ½Ž~«àÜRì‹rUÌVnl›rÈÐÌèÏoS&¬nLáCsÐæ€d^o#ŠÖlï6 T:‡`ƒ/8¯q÷2:C=•C8¶Ì¸Pgd¾’BÖé(™::ÕOÕ—Ç íˆú¤—Ç‹Ó#"|åPoéÍh-õkzÿÏëᎈñôúŠ1OϾ}ظ­[Àkà fº.>`\± ¥;x1B“ÙCq‡÷Y5»%ªbÏK8Ï­>‘|Eµà!ŒH‘Šún¾Û–í¨Y5½¢&H+L‰-†ZP.ÿåbÛÆU‹0w]Ñs_lËz„›"ó 䤃¨öZñél‡1æ A¢ Á ÍF1­{^¯×ÎsSÐ(C`ºmá™ |xª+Ç1q#­¢×°W¨€ŒŠñ¬$iNZÁa„›OÈ´ðÌɌߓ0ͪ©éͳӑœ¥ÄáÆ4ž{9M‘ƒüéÑU$ \šã¾¢ÆYª­k4ëÂgG|”µ@´Ùm75%›ËóŽGss°­g@˜Ì òUÝ´#7ÄN~Lf—+÷L‘P’}¸Èú†Ü^Â9¤ªa=Dg­šVî)¨D³=„@h®è£Øµõ*È<Ä ¨ÎBßb³Y•«]5z^úÏô×Ṫ‹E<&ŠÉ’½wÓÊÝÐÓUsà1ÅC¤â¾Áóèø6Vï% +2ñE$˜Ì|ž”a^>¨ûnž—„6°Œ&,‡bÞNN$<òSrœä@ùD– ói ϰôðÌ3]íÊÛçÿESW€a¡cYvù».ôŽÓñÑ÷ vÆë…páF ׃~F ±yái÷èD€ôŽóp<ýçÃV$8l¼“ð©»q‰kReâsa‹µ¥£‡”d îS__z,gˆ­(!/0FÚ¼¤gS¯ƒ$28Ð}" ÝÇb½ ̽CÒ°#ÂöóíÍ?0ÅEÀȆ>+€·ªnéò¹~å¼ÖÞØÏ¤¬`&¬½" ãçkë]œ‰äˆ8ýf[îç|Œ¢bŽ¢˜H ¶‡²¯+º¬ó‡é¢¢7$¾‚pÏøü‚‘ñσ ÔG(”BâX `~žî +t8¶«˜Rúø`¯|‘£[¤«-Ý"Þít-5អ ^{‹@SñNAÉÃø#ð¨[ÑÂ>n‡;ªˆázIðÖWtåƃ’HÃAkXDhªW;J„Ø3@bC’È_nUôÈ‹ ¤Åá‚bwkó@¢Ê5.µ¨‚¶Ç_xãoŸpeÁs8û2œˆŽÇÕ2]€‡yQ ï*›bé"€¥¬Žð Õï[À›>^øæj_R´V@ÚQàùÜf¼èÖÇ«_p§Ñ]ú¼xÔ—_kX €w|­1² bîã4ľ¾ú‹¼È»ß Y>…ƒÊ3àN޹ØÍ‰™<·xŸÁMwÁUÙçZfÕ«ñ8f;¼'·…9j2¥ÙmÂ, ’ùÁ¼À<élŠmÝ4H#<°©;¡<⬖ê8> endobj 1898 0 obj << /D [1896 0 R /XYZ 85.0394 794.5015 null] >> endobj 518 0 obj << /D [1896 0 R /XYZ 85.0394 769.5949 null] >> endobj 1899 0 obj << /D [1896 0 R /XYZ 85.0394 748.5275 null] >> endobj 1895 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1902 0 obj << /Length 2543 /Filter /FlateDecode >> stream xÚÝZÝsÛ¸÷_¡·R3HNŸr‰“ú¦g§Žn:íÝ=ÐesB‘ŠDÙçû뻋]P¤LÙi“N?Æ3æ\ì~»XÐV ?jbp™Î&I +•,Ögrr ïÞŸ)晦YŸëûùÙwïL:ÉDæ´›ÌW=Y©iª&óåÏ‘ZLA‚ŒÞ\]¾»xÿÓõëiGó‹«ËéL[½»øó9Qï¯_ÿøãëëéL¥VEoþôúÃüüš^9–ñýÅå[šÉèqBèõù»óëóË7çÓ_ç?œÏ;_úþ*iБÏg?ÿ*'Kpû‡3)L–ÚÉ ¤PY¦'ë³ØaccÂLuöñì/ÀÞ[¿t,~Ø&Œ´ê‹Ô*-²ÌÆãjåd–áb“–Eë$Èb2¬Š:l¯K­°V¶Wë‰R"ƒ9Ü_§…I”›$Öž;ÚßKŒ°çÌ„u±BF%…5,÷WÓ™SÑ~ëèÉ~€L™èd’€žÔh™Éç‰2Î2CL=ÚûzˆŸøîb­'oðhÒs*žõ%{§ÀðfªÀú®Ø<¿+¦³XÇQ¾\n‹Ý&ÚmŠEù‹”ºXÒÛ²¦g ì>N÷+ Qç |Þ[¶Œg»f¿j-²¾=.ÚÄ–W5›¶lXMÉvìwÁ€ÕÔȨÙÒà¦iïˆúéíâÌë%jÔIãɬÛMtó ðé4¶Ù¨,vSx¼ÂiÝ ‘ûÖ;é™7^¡Œx>ßl*\æß5uõÈì Íx[pâXä³qæ„ $¹z@Æ|dà»÷HOƒ9¼MÒh;…ø‚ÓÍšÆûzÃ2ï˪¸Å°átç8cì2¡Ó,ôáër ³Øf’ëP¾:óu"L¬¿¬’?ì}¹§aÅ©*bS%”I³ªˆ‹á,IÕ7­"NJÇÉ¿¡Šô%Ÿ®"¢ ϼÅ›*gü|M*#€‚PDbnz¢`È¢-Í,›‚ùë¦%b·ßôòÎÏm[Ö·0H2JN? ¥eÁtW¼pЕ `Ò ²ˆêÁ®Y`ÆÂ_EËYz*Cú›üu¸ùïÏ%à°‹ÿOyÅ© ‰!x‰q/³6y.qß2CâÌ iŒûöÒ—|:C¬„h‡ÞðcQPIΫ]3r†Æ ü3 û×nóz·Â_øóóùƒ4N+vŽ×òQx|Fg¤A<$[¹zét㥠§óéìèoð×aæÛgdž:ø…j¤™„ZÇq×Ì+'ìd¤ŒþÞÔõÛó©R*òTlw=¨q”“™‰D}¼q.ºËwD¬‹Å]^—»5±½Âç¦Ê}I» ã’h•/Ê©‚’ÙæmAS¿{Sa–4ªóuAÔ®ØÞŠ4o<­¥•<ÀºåvEÍ —Wó‹w#z òÛbÇm8”uáwE]Üû³î·èñ›wG³‹fóHAR¼Ê÷’š x…h-–¯ð¨O9‰|3PÒUG”G=)_a€q+–ÄÖôý5]~kÆÉôEãŸKÀ%îí³6º+ª “Þxõnß…ç)Ú@çþB€´÷ÝòU ´…ß=”UEÔç}¹ø„ùBËk -H¾å5>ðó oL~@Ծò©˜W KÞbëo±¿ µD­óG"n z®‹8ñP¢:¤Š|qÇ%²ŸdZÌ,‰M8²†éu”¸pI GФ ´¢¨Y= X$Yð9X”3\­ÎfÉ0ì²…¬‘["aÃê@D,‹U¾¯늞Ö`á3&zÍì G—Fóï‰úT<±‚)Õºa ÃÃG(aZ6ˆ ØŒv‘ãÕr¦}ª3Ñ è^ ¥¡ç sîÊÛºXþ]2ÙÞã«}E4æ=¯†=¢ÊÏJ½OGªÖËrS± û²x‡ëEýôZѳø ®ê‹²åS¥__…Ã*,ÙÒsÝ„´ÄÖÆåp¡J À]ç\£M€Á®< íÖ>âx—%ï­ô9D€a"´Ò)ø ’É~¢S¿qŒ„_)õ—&t ªg ö›ÏÛòÞoNñ3Q GS ðb1¾*?Õ¥€bˆÓ»—5œ}¥#¿3 E…Í (LÛrYæîSÓ@·2Ø¢¥fðшÍÞù4Aƒì±Ay“!mª‡©òWn6ØbÕ•%nS€õtøáF,]|l­ò{Oߺ!Ñ6#*S¡×]?¢ì*ÏF*"HŶÀû3l ¼ÞÕ/7c› ;ûe ƒ6:±v:NÇŒ7!IñZ• Ó<ä µH…¶Ã§í¡ZùÞrzм=ôÇ-h¯`S31h[‹õ¦å&”ÍêieÍ-iè¼|¡à"¶È©ç«€_ìSµ–"Mtú|ŸÚç:ݧv\T~›…6·wÖ–ëbVÖOšV ×éôy;˜gÄŒÜÕÖ)3´ã¢¾»…ÿ쇾 ¨þ}%5Ð>á‡Ëš¾íÀ목oéËPÌÇ,QôM ú‘V®Ëzß<Í QJ ‰_Rl×åŒ@•°Uì5äÞò‹P¡´d • šÈ;¸Dïh·‡â`/Êõ~Mƒû¼ÚCÉ:eµùcOj,Í‘Æg‘¤÷_mžGRŸë4’:®Q$•ËjIq"R¸Ý 2hçdöZ­ÒLh£^(V=¦Ó€ L§KÕ(ž 6åÏÛÑ1=5dX©RaŒZr“‘LFÊA¥’êP©€ö• ž#• úJ%ªh­¯T’P5Eôð®T’€åWq<ZN$P¿†Ð!ÿãÕ*|®³ÿë`dGe÷÷†¯þˆÞ÷d¸Þ¥©ÇÆ‘M‡ÀþŸ9  3ûãŸÂ¬ÖQ➦ \rŒÓ#Nýlªk$endstream endobj 1901 0 obj << /Type /Page /Contents 1902 0 R /Resources 1900 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1882 0 R >> endobj 1903 0 obj << /D [1901 0 R /XYZ 56.6929 794.5015 null] >> endobj 522 0 obj << /D [1901 0 R /XYZ 56.6929 456.3937 null] >> endobj 1476 0 obj << /D [1901 0 R /XYZ 56.6929 432.081 null] >> endobj 1900 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F61 1466 0 R /F62 1469 0 R /F21 1034 0 R >> /XObject << /Im2 1455 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1906 0 obj << /Length 3725 /Filter /FlateDecode >> stream xÚ­ksÛ6ò»…¾•ž‰P<’˜û”&NÏ7W'—¸ss×ö%Ñ'銔]÷×ß.vÁ—('™ÞhFÄc,ûÔBÂO-2+¤qñ"u±°RÙÅz!÷Ð÷ã…b˜eZ¡~¸½øþÉN¸D'‹Û»Á\™Y¦·›_¢7ýáöêãåR[%âriýp}ó–Z}Þ¼¿ywýãÏ__¦qt{ýþ†š?^½»úxuóæêr©2«`¼æÎ xwýÏ+*ýøñõO?½þxùÛí?.®n»½ ÷«¤Áü~ñËor±mÿãB ã2»x‚ŠÊ9½Ø_ÄÖZvŸ.þÕM8èõCçèÛLX'‹¥‰E–À³T–BZ Ú2µN$F›ŽÊZÍQ9@!•›âPæ»åïÇâð¼<äm1Ý·J¤Ð.±‹áä'(tP38è*±B§i6FâÓ.,€úF#>Å¡ÁŠŠžÊÝŽšÍzS®óÝî™ú<ÆÔ¹Ï›¶8Pó`¼ŽÚš¾¿J©« ÔÇ–Ë;jø³®úµT®ŽûÎÔX,­ƨ ¶©„³V{¤·„sæ¢õ6¯î‹ 0X¬“è*_o©½9†R@ŠÇ¦h¨”Óg_VÇ–gÊ÷õ±Bü²,ªï¨­Ýrg³ëV¤]^.…¿ãÙª¢}ªŸ©²Ê«ÍS¹i·Âo@Ž1¿½t:BÒ¨8Ú•ûT–‚¶ ({,àÛÍH°°‹Í+(jD`Ü`Êf2§g-š—{Ú–—*Zó„H¡ÒSA—*‹¾)ªH«]ÝÒl6zÌwÇb¼5R]©ýºÐ=‘뤃AgY¯i*tb¨Ú²®pßJEyEK•U[ÜÃaÀYpO‰ÛŠ7/‘Aÿ(÷Ç=Uˆ³" Ûï^*¿aj~pM±®«§Bì©àÙÔÈl2>ÜMq—w0Q‰ÇĨ4Ò’ê~B,tZ%‰¬Øº«ŸŠ†‡>ÔMS®vM@Ç×O™D^j°k2çß Zôi[T¡¹%ÀŽ»¦âŸ…?áfŒ‰J^“äVÅã6åhã5,qÈKàB*{I‡/`Õ³|&û×xV äk³)ñ©æÁÐn ŸÝ®¬î¹“x-ë8×EŸÞ¿¦±ç}š-58Ø 9ØÉš£G;ÚWsŒéÀ@ÅIümœ›4ðr¾kN7ÃÚˤF$YlÆ´¤ýy2¶\ò’éÏ®ôb Å›÷·×ïþCå}Ñ4ù½ß!w;„ ³,”ˆ(õžj«ºå‰:C+>µ Ñ ˆZ¸'F—-[b2‘‚~Ñú €Î¿4!3ÜÔðÅ©LÚK‹w@§«ÌžÊg`ö†Ë{¦Ô.(PE*‡yí•à`¬<ƒüdÍ$–Šã‘ꢽDâzÄÐÒ+(hítxmÀUëãŽÜµŸ†Í%Y²RJ•8±•~>c²^HŒYØ¡ÂÙP #~W}ÁN7-pŠHÝRG^=Sá¾|ô:úÚr_ 2K-Sû}65­HÖ-³ÑóËny½°kì‡]ÏhŸFd™˜'öË38Êûªf-ÑÛÃÓ“UÈΚo8Z%¡8úº¶®IGnhH =õmæö¤m"ÿø+9ÉXÙÀùú3ãž7´"ŽgW)Ñ x±3Ì)î]âî 5æüí½g¬AˆPs?}˜Fb–µÈ2õµ\Ÿ ©LðK^}_÷îg Ž*VP¯KboL´òq0"ǃêÊ;ÖPjŽõ¡-6l ¶Ïœe…V‚Zi—·`q#1}¢Nvð|‘sôøuÌ¡1¶ûCÁ Âça:K}™øƒÑ°b¡ï‹…–ëê)çÓÀXâàyQ7ήˆÝÄ|þ¡gF(æÈo@ÿfkur‰QaC_vÌ¥PÕw ýðËlÔÅ|?•kr¡›úŽ›þ}i-ðЦ~jhª*"zbBÛ…ŒÄÌîá8ÓÄÅ_Þ½þÒîÁ÷Me:T¹“µ¬°©SߪSãnÈ>çXoÅÞE {>”›MQ…x} ú<ðì½>…¡yS²'²zþJDƒº3uâÙf …J’ÎQiÁ9ÙûlÅÏ#Uä2ó²ã1:ïw !]›eYøpF‰Té‹Kw@§k¼X õ)uÝEXé|iM $ü–Õª>zñ… åܰ4pQ|uëÝ|(yg +†<\fѱª(@€QHªG)a`tŸ"1Z$&=—!‘!“ä‹AZâ ;f&<®ä „¹ƒ,ã4?œÄ¸È=¯Íˆø+Ò$Ùg8õ–@0ƒ< ĸy(|øÅã~Ù»Ç Ï#IÃ}Q­¹Ñd½ Ex£ÆHo<)Z朅(@OÈ:ÍGõ,Qe¿Ý¢,_ØÕùf,¬ƒ®µŸ0lxoh^rP,óDgõ‚ì¨1á11|’0à>Êìåå;¨™õÇò“ QÙ/A±ÄàX ké ÛA!¬‘ai BN"„^„°°bÈ¡!è"ÉdÓdbô)´ðg”9åü¢5m‚¾Åkðuøüï¦çÏÉgÌ9Qª ê9Ɇ´ û~ÆõF*,Á~Ñ9 6Ö@p­ô·ˆð.4faLü"€Îó`³`0_Õi2 <Þ4sÉ‹(t@§8Œï`”HSéFHpj]RAPésÕœ R²WäXáË%‡\è«[ò„˜ ±iÅ'\7`u ±/¨^=õFùEGf>œ Â"M»¯}jêè*Q‰­8èfQãxËnÈN®g'w†tƒû¤‚EÐsÚ¨š&{`äWÙ –;±cž˜:K1˜·,yK¸UoXŒ%ítBEo-ßP¥g¬…¢Û ìì¼xÕ[ ²µÀûŽ–àÈ.` Y(¥'va°¤b»€@u5ÁfxˆØA‡èQâ) '—A_KDÐÆvà#ê™&¿#3#—ÛkþæÔ=u9ýPr9}ñ™ÀØåĦ3.g qŒIÌ”f{“Ä]^äa{ â"nw´ÚüÞBÌÛÉ¥ÊÿË»ÕxÇŸ}A;€ÎkÇt5` ¾>½¢¶ Çtü2ÐË((› 'íWá0å# Wš…LK—¾ñwÑý¥ŠéÝ£ðBг Œ¯¼Y]â—µ-@Ó}6(“1•nß| pU¬1Å·>Jž‹DŸ i¦»¢¥¼RFÂͽã$ çš:ÍoÇRƒ|ÖH¿.0§¦‚»˜i2;Ì­@7hÝ@¯æ’ò|—”pöß@çN£Ÿß~ Œ¾_Ór>—6‚Of.÷ qïNú5apÈ8„ù6Ï ¬Ê5õ6 4£ ›º#¼†˜»Ü,(5Ã9=ÝÅò Õüi¯wðC3•‡˜h v Šõ°Hì¥csdbiÒu~-Æ|©5_‰K@Æß|îò5ùUëx½«›åÜÅ<Ý+ã5Âa™—ÃÆ‘Â‡Ž‚î¦5^ù{M 0#”h sæE~ Ö²âu¶<×xnƒs7›Q‰°*éoTwõÓ²“ü™Ô[*b©§É_\yНâ§¹›Wc@Þ€˜WVå$ðÙÊXøü¥`ÂïULÔ=WñY hk¿.1½G޲Œ™h¾/híðÂ¥m^ºb4âå.‰þÕjOËν&y‚òðt‡]¾ŠÖàÓM£ v$ø‚xÛ #Û‹uîÏ©lïcI G8ô°‡ Ðl2Ÿù)CµÞù‚šóY¦+ ¿•"JHÝ_æwGÀ<îFœMRŒOe»-«—RRq*R+™ýŽOWÖàê4`[æòËàU'6 çé3;L]paW`°>ú.„Õƒ¬w<äáöCú\ó®8q”„âÄ_ð9CøKoèLæŸfóoè@ɤ‰HRÀúì\4NÂ\\ #ÆS-vPÐB'É( Ö±+БãÔ¿eK%,‚4ºPÑ&àf $¸ÞFR¿¿\&*º…]&5`ùJ+aÑGƒÅ¿/€“bç]=9*ûÝöTð ß_ïõâm {Z ·f^§öûJÔÉ |—(ùe^½CŪ,½ûI\¤…ŠŠ”‡BÁ0»Ò{ÀЗîP¢K÷Äqþ¢!àn)Ú–¤/á÷6¾•ÄŠVOú*w—àç°j¾hónPŠŽÄúRËè3þ¡®¤NØ0v)DMp¾Ãƒþk¼1˜HÐlÙ?æükœ ^ªÀÎ%ˆ¢unž÷ªAR¡!&ý³O:£Ç–ÉéÓÏB]˜l0ÿÌËO:Åb”t¥˜ÆfŒF—Ði(J§G3±q"”ž¿G8«„Á> endobj 1907 0 obj << /D [1905 0 R /XYZ 85.0394 794.5015 null] >> endobj 1904 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F61 1466 0 R >> /XObject << /Im2 1455 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1910 0 obj << /Length 2928 /Filter /FlateDecode >> stream xÚÅZÝsÛ6÷_¡·£gBß.OiâäÜIœã<Ü´} EÊæDU‘²Î½¹ÿývñA‘¥8“Ì\;€Àb±Xìþv2›QøŸÍ”&Úr;ˬ$Š25›?œÑÙ̽;c&DiŸê盳ŸÞ 3³Äj®g7‹/C¨1lvSü–hÂÉ9p ÉëWo/ß}¾~užÉäæòÃÕyÊMÞ^¾¿ð½wׯ~ýõÕõyÊŒbÉë¼úxsqí§tàñóåÕ?b}s„éõÅÛ‹ë‹«×çÜürvqÓ¥^Fäϳßþ ³ŽýË%Â5ÛÁ%ÌZ>{8“J%…ˆ#˳OgÿìöfÝÒ)ýIeˆâRÏR!‰ý§µÌHÆeÊ-¸è´ÌÙ”–#j9_¶i»ÉW͢ܜ3“¤M½ÝÌËñé™°D1¸¿þ‚tT’ðž$LJ"-7CQ^­ÎS‘e(R¹Yåm‰Ÿ:é¤s“(Ê9/ýwµðm{ÈëU˜YVM[j…郳Œh·?¢…‘èã’E^-› ôª˜ØBrP¹”|Û”)ê áFÁŒÔƈUŠ‹`3™oÕxÛmÊ–Œ/Î0¢¬…{c‚dÆÊçØ­0Î Í´ÝÒYjÑRØã¼ü: ¼B7®²J£t©@(•êÛK§–ÅÌd„g†Ã¹)QÊz€¸ê)FiÉœeÁ¼àQáÎSÍ’ø—'m4±àÌ3 ~!¹b¸õìÏ#TZ+§ (çkÐA™Mês–lýDûNYØ)Êu¹ ƒÛu½òÞ×m5ð¾»²m«Õè13°MlÔß.œÂÝæs<Åÿ…jt-Þv~§”ošÖlÊÅ¦Ä Ã?·þPvPæ¿Jm 7ÖÌúñ}N&À{´…•î#Í÷A@Ê-1&ƒ¸Î5¾§Ã’¦‚pÁ²Óa©£:–ÒG}™ Œ Òßå02Eª a‘ ®Ô ¥yå,ö#~î#~õ#Ϙ‹LŽê>»È„™°?™¨! ,ôxd ŠIo ¬2ɇÑÉ >,3šõ¢“÷ Iázy&†¾q"S‹¡ˆ –?#:EQ öÌ}ÚŽúTÇí¨£:Ä¡Ó)^=hþ´0Õ„4CÒ`p†â|nÐLD c&…ã{“‚ɽI5~ºnM¹€3U¹kK·&0lÖå¼B8r³í}˜å"ß.Û° 0ìÐB0@gúKXÕ—Î -fÚ†K¯á€S¥¿ûªõmoKE§·„ÜšdÜêÀè Ž>±YF¤*ÐüN]8Õ¨~¢o|3¯Öy[ÝV˪}RvÜ á B(õ+ìQ°ÂHåÖV‹§cv‡¡_Û=}ewÆáš,xîéíGÚDSUšm%XäCµB›T&»ûjî² •,ëy¾ô£ƒ<¦ò¢ðf×4˜@0ã£4’Ö붪WùÃ7~~óѯY×›6ïªe`|[†v  šó äª}ÌŶqÁ]è,¹úpsùö_~ôäÈïʼDk‘Ü8£Ç‰žœr‹qÚM­×e¾ñýjåyúü ·Yæ±[nÑC¡nü[3aÁB8ã]úÚo¦¬X`q'"Nþ…ñ!à/l©F^7_æ[ô'!¤Ãl˜B`ªr(ˆ!5‹Žú¯w©7… Y Ë2=ÊïåJg•Û5-ÕC¹jÃgÙ† TÓ„+KH ­ŽLŸa†Zš®¶ŠgÌe@äŒK•lƒ ó<$t b •S·!!«áÆ6UQ”!§«] ©¤ÿ\‡ÈðWˆÑi{3ˆ¯~ÉmÞ8Å,ðÉ·Õj¾ÜûÄq*¤g€Jêçë‚Z©{zGþ» @<`Zó  ¨˜$(aà=ÑÄF›qIhÖ!.œ|â*1ZE“vʘä£y¯ûÐâK€ÿUüû2bò cÒÝv“#6øAY–G+X)8²ç?¤‚ͦ3®¿!¹Ž+ŽU°¶ h©¿RÁJfaˆ“?°‚P@rÍí¯`ûœOT°Xapn|Žó©^æ¡fskNa¾ëƒtÊ@³¬\=#E]z_çB§Ù®×èˆL'ŒÄ ?8Û}I‹;Àp·‰+|½A+Ô›×½75u(åà4êxUÖ¿åï3œÿ{U&€œJÈdOæ1ÕjMÕbP³@‰>ë‰GBO4!À ÅŠ‡Hð¾úRN>åAŽmØsÁt µ] ~áÑÇEì@F¹OQ]â¦ëÇÜ"–5«vH{ù4ãYí“ LE&pšiF¸‚ê …Xib½‰OßLH`¥Ô'LÈï#$L¾÷JÈ&š5‡ C›ýÃË£L·Å:Åôj*íÈ yÖÆvÇŸ( ìMÌKòǺ*¾ÆŒYBéù\žNJýMR¦\Ø#u,Æ/#Gòžæn ÝéÅW,’Üõ íRh°HÇžJê…{•!×Ѐvœk8lŒÀm¸9òr¸n{Ÿ·¾ç“^¤si Œøô{.ÿ€Öa!’ì§òÀhðà½=qy'@/!T$ŸÊƒ:DJ) uj"r~é'7w!b\÷›ˆôiÁ¡#òuQ¢œ‡ÈÂ{ׇ…% y>iÑÕW‰Æ…„KÃCÓmÿ¾ÞÒ”ü1¯–ùí2|FãLWc»ª6TLj—Ñäm,FËçëe ó¶Ñ‹ÓrŸ9NäEÎpåèò ‰ç˜t¤T`üÇ7›|uWú®à€¾«•ê¥ïÿ÷å04òcÔg+“è˃-‡-z~‹ÑUŒNá+BÞiXp漇¼3áÈwqÜã.Ž/Ü]ÔSi+_Ž¿z„À?”ÅT!¹¹Ññç”P‹òð,;¸2‹‡¼¾p>Aö÷ˆãN-Íß!sQ,êÉ\Ñ óÂÂ/<˜p0_™_¢QÉlW¤_äíÏaòªѹ žŠ6*0»Ì²ov("¥‰ª™Æ_fˆÉDöøÛc;wOí”y¤<‚õѵw¸G¼õC ,¤gª G¯Š*Jc}Ò™Ûg~_×÷CØÍA,ŒVÎßa.´ð†µ%”ÛÑ… ÐXz4ö= (ÒôB€ž+$¡uµ’;² U% >!G×s?'¸óï\5Œcb¤ñÜíIîA›=Öîy.H‡éÎÜÁMó2¬[ô·î'‹§©zç]PBˆtå¸Ôâp(÷Í༜8ÓÙ}<õVéÑ_ôÓ}$Z5;W5@~˜‚E¾l€±»²ísÕû•cEznÅžj ÑšðÑu?Bñn_¾÷/C*¸7´^cŽ.¿Ë«¾B1™\Õm ˜ Á|Q6•—(p ˆŠ]çØÉ—MíÉoÔ_œ¡0.¯W˰³»ŠIèŸîù¢¡PwwÎu$C—ÐÙw¤wî©Ç];öª!91œëÎL¹9Êìøœá^Ï· ÛøÔ¾]¹³c–y g1GÃÐmS¾ ×{_> ùxW —=Tú«©«¢,b¨IÁm>ÿ²óЉ'êÀGT_×MSÝ.ÃtSA^ÑU$]:±î „îÝß»69öç,)ðoP&ò*Ú=_|÷ŸºìÿHfŠX~:A 2¡{¶C NŠô£ÄgÅy’™£éâá¡þšÞøùendstream endobj 1909 0 obj << /Type /Page /Contents 1910 0 R /Resources 1908 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1914 0 R /Annots [ 1913 0 R ] >> endobj 1913 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [442.7768 242.6802 511.2325 254.7398] /Subtype /Link /A << /S /GoTo /D (query_address) >> >> endobj 1911 0 obj << /D [1909 0 R /XYZ 56.6929 794.5015 null] >> endobj 526 0 obj << /D [1909 0 R /XYZ 56.6929 304.9374 null] >> endobj 1912 0 obj << /D [1909 0 R /XYZ 56.6929 278.7995 null] >> endobj 1908 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F61 1466 0 R /F62 1469 0 R /F42 1338 0 R >> /XObject << /Im2 1455 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1917 0 obj << /Length 3443 /Filter /FlateDecode >> stream xÚ¥ZÝsÛ6÷_¡—›Ê3ß ¯Oi›äÒi“ží›{hû@I´Í‹Dª"Çýëo»à‡D)ñÜx<À%v]üö’3r–ÚDèÌÌ|f+¤­¶WböïÞ^I¦YD¢Åêû»«¿¿Ñé,K2§Üìî~0Wšˆ4•³»õoóþùê×»×7× eÅÜ%× ëÄüûw螺Œ?|xÿæÝÛß¼ºöf~÷îÃ{¾yýæõÍë÷?¼¾^ÈÔJø^ñ g>xóîç×Ôz{óê—_^Ý\ÿq÷ÓÕë»n-ÃõJ¡q!^ýö‡˜­aÙ?]‰Dg©=AG$2ËÔl{e¬N¬Ñ:Žl®n¯þÕM8x>Ú?«ÓĦÊOl ’Sh³Äi¥Ã⚥K`£¤bþaWìó¶¬h™·ÏM[ly·Š¦>ìWõ~.·eÛàú‹p³…r‰Ò„ùïñ•Λbÿ©Ø_/`C¿ihèÐäü¶¾Çg6ßæÕ3ÓGÖÐÞ_ËtØccUð÷«¼¢Æ’gÙ PÅ”¨…žß®òM±¦7ŸòÍ!~–ÓtÜÙlê'¢ÊæO ¬œWÔivŪ¼ƽ€U⺤L2kÉðŽEB–Šh€¿qnþ¦Þ㨜ŸóínS|Ë»5Ô‰Ô:‘t!¬òíÄŽ‚zTê#IX4òZ2ÏCƒâc«¬`ËrîÀŽN°*Ñ>ó‘ðÚ™*3ÁÖª$U"eÒ¶¦iyW¨“VMKE=îK÷P>äËç¶H&¤“8#dÜZX*Öã„PÆ'¤f¡H ‚f[Ô­¶ƒo©ÛÀ®C lO#m°GhlóÏåö°¥Nþ)/7ùrÃïòm}¨Ú)‘•“IêŒaÖÅ}~Ø´‚j“diê˜ähŽøó¦ÑXέ§œÉÊ*ÝB8ÑNûñÝ×ÕáY³­¨E³C#ž¶ð:LŠƒm¾çã!álÅÑGë¢YíË][Ö<ݤ Á‹ÄjoyiMùWq ƒP+õ©š¹ÌºXó5@¨pÃÒi\t3.†Sžbœ¶ôã{ÆAD°Ù )•a£ÓŽV‘‰Ä8áG« —û‡5n8ÜÑOÈ82“y‘ÿm±ê7Þ%òX£}¢¤ÉFÒœø‚Žê 2œÎ†2$ltpô¥·Œ.K„ÏÒ#¹Ö`}ˆ™ä# [ƒ vkÀîÚ8Ú;èvhíSèÄ/ :#‡=5ÚȳʷEäÀ– £»0C ¡ ˜oæ·u¤ë¡7 ¸éTÍ×uõ ÂW*çÍa·«÷-7a.l ‡gpNH`‚|Øè€ß ;ÿPñ‡Õ#·ˆ`‘‘&À& >åû*lPè”› ͽä)˦9dÇö€ßÄr pì'‚ 4K>üè&’“xE$päÌ)pCÞLÛT$Z ©Î‡UðVõ¾˜B©$àšúçŽj‚õÈCBÄQÒﻈk=Ô#¢4ÝÂ3§ÇªîâÄÂÃvÇ@y×ã#¡}Ü×)f )cS÷E÷`À-™î¬^l'Ñ:{Y/Cªóz騂dy›Oëˆ J¸Ì¹£š`=Ö‹ODñèˆ7íg&zù\jÍd"HɤŶÞ?S»ßwPæâ·`çiÕóéõI½ià ,z¹Þ€‘Fáu“£+P‰OÓ°;¤tM½xT¡ÐžýºÌ`á–âeäiìüÝ=ñf ?‚ø¥´ÙA(©j~ȽÊ[þd8wɼ‹Ïˆ¦,Oǃ×uÑ¿EàõQY+ƒ>¶î!Æ Ô)D,%B#޲âKàæíaÏ­M‘âY»éûe:€=Ù ¦' >x-u~|ÛU®(=O0:øUaÄ.šV½ÐN±‡£vÛs±y¦>˜ÝýÜéyÎ49=žr¦ ^ñ³ äwч 9Ÿ€!iT³Xƒ%¨ö™šg<o$[!þÍæËš¶a§ùIùD›!‚‭°ðfŸ— ¿$b7öìvàÙ]<¯Ðb”ƹ®‹s9%Œ|ëšé·y0h.ŸéÂàØÚû„>× ¹• Ú˜VF"_ ÆcÆÎ8a¬;"ë‡Ñåóѧ㠕i{’‰(Rq¯³ˆu‹U¾z,u€ÅCÜ«eÆäyµžÊÞÒ$3&&‚ûbuØ7å§bÁ˜“Bˆ,­ÂjSÕd¢®!´iÌdú(}%’gÝ’I3./º¥!Õy·ÔQ¡¿ ¡6Esâ•,ͤþ2ãŽj‚óÈ+‰4Iõ˜1·~˜úyuØ.)Öôd/ðŒ"†N?ë£Rψ9ç#Á~¼ ´Vuj#ì¨Z@)å<ظí…èÌRÂÁôY^C¡cþr)k¶èÝ yúB´alšè4ó_Pë€ê‚Z#U@£6_}œ7l’yë.³î¨&x«¾ËÆÌ§ÃÀ `“i#*œKªIÉW¿`ú„§œÔ.8¸ÇØ~ÇÕ•z\%%xöXi ì +¹|¬†TçUGJùù>¬z±©“GÌIEEvYŒŽjBŽq-Ò%ÞÁÐH €u¦ûP)ãP Ç–M½)Úâ;,‹š} _ç«U± ™kèUk~ýPq<ÆoBQTÞGš”VõvêX–›²íÕtÞqp´Àª<ÇYÖÓ#¥e¢…ºîÿÂyK:ë¼Á¡X«’‚6£ì²ó°ÉÙ¤îÕ ØSòspmqÞ–Ç—mi@uÁ–"Õ¹U›‘Ê\– £šáØŒ ^IÇ2Ü1LØ4|tˆ )±E–"h±èÔ!ÛV4Åi…Ò;pž¨å¼TÛ‹ô_XØé¼£ÚJd™O«{2±Ä··£ú‚§³QpgözaS1ÿO¨£4„ÉgvâJ%glv”Ëî¸ø†A-šºÑ4Â%ÎÂiÝaÜœj®ªá`p»ÃÏêͺhZÜçU“¯bP #ᘠÉ;‰±Ãi&´–ü:?´õ`a<ÀÙ+œmý)”ÄUæÙƒƒ+ßky qPàLƒ?£útÃu‘†T†uã}G3žrX„çŠG™JÄ_ÐÅL d$}R ÌòMSSk[À>Æ»°M•¦cE*‚œ¡ÜÌÄÂaéð¤ÐZv.3FPÕìv”Q/þ ×@ዼ)›³¨¦ŒJ„ïsÕ†TçQ­£ÂÅ=ÖM»€°®-0„f€r lY"•V—…è¨&¤›Ç‹_ãÆb¼ÃíqiDxçç)êÌ«ÁIiˆ„¬}´ê‰ˆãÄž¸6zÛ/Þ@b±/iBOù°ã;Rx~g›Píà}Ý’e8Ú"¸ £Ä;Ë-Ì‹Ê/ñS2Ë‘úô²F‡Tç5ÚQ³ÞAf;ҧͯR{Y„ŽjB†±£‚4^dÙXˆ»XtT0m¯$h£Ûù])3®õýy¨Û‡ŠÇ56ˆòª¨\}#xâÕr­°®?vÍtå×é#¬fl´zP³†­ËxÌ7÷<ÆÏÕñ°¿h+JÆäÆ “}ÇDØÛîŽYˆ©Ë7 á£Ð}!™|_¬rª«ÀÜäÜ‘å`'(äÖ\Ö ×|¹ £9 Üçåž—V²…+­[S=öaµ&í³=h£æÂΘxM¸=F-íß}§=?–›:€'êO¶Éâ·¾ó&í¾;S2T×J¸“úÎùŽ÷pp³Q ‡W”ór¸a¸0f;€ÔøìèÔ¯‹mwÞÄsÁ‡}ÂSÙ>nš"%ï#E৆!ÆŠ_³@)lb1õ‰2beU„ÔÁ‡0テ#ÝAÃnÚý@Þpáá(TkÊa¡stÖpˆeúÇõ ÃWì8¾×Da;ù&‹n¸YÌ}¬(ãXÿ/¢$Á#˜yU<MYA^CDG?upY<ÕЪꖈã³.¥â)CN…ïé^ølyÑs™H<Çî^|* «¬è73$ÏÇŸEü™ !ÖEîv|;yl$¯0 •AÅM}ßRo¨^#)“41êÁ&!Ò5]¤+c=Zø‹Ÿý`¦ñ,xR¬ÃæiLW;5à˱Ó®aÔ`ã'¶syÅýhƒÎÅü† P ×–. †æéüxGñC¾-víâÈhÎ ®˜c³M!>I³` š¸ò2VéÄÏ&Ú‚ìœÅ¥Ç?ëAG€à)ßæÍI¥ØbE`9Lø º²À6€×éb$¼°ñ²ÅdYWPÅ¢ #Wï;0üåÖ~žÂ½G§ˆ¥¹Ä… T|fâoÔ¨§v<Œ©µG®çë„…ÌKvÊJÎýÚPÛ"8çÀ?kàÿþ%bÿ3MãA»©:“ Ð $>Q(Ü㯠A5 %ȰøÕ/ªû5ãéªþ,û¥¬endstream endobj 1916 0 obj << /Type /Page /Contents 1917 0 R /Resources 1915 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1914 0 R /Annots [ 1920 0 R 1922 0 R ] >> endobj 1920 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [389.4645 693.3598 438.2112 705.4194] /Subtype /Link /A << /S /GoTo /D (configuration_file_elements) >> >> endobj 1922 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [375.4723 305.1386 432.5882 317.1983] /Subtype /Link /A << /S /GoTo /D (journal) >> >> endobj 1918 0 obj << /D [1916 0 R /XYZ 85.0394 794.5015 null] >> endobj 530 0 obj << /D [1916 0 R /XYZ 85.0394 769.5949 null] >> endobj 1919 0 obj << /D [1916 0 R /XYZ 85.0394 749.4437 null] >> endobj 534 0 obj << /D [1916 0 R /XYZ 85.0394 437.7451 null] >> endobj 1921 0 obj << /D [1916 0 R /XYZ 85.0394 413.774 null] >> endobj 1915 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1925 0 obj << /Length 3502 /Filter /FlateDecode >> stream xÚÍZÝsÛÆ×_ÁGjÆDî ‡CÛéŒãʉ2‰“*jûä"A Ð"hYùë³{»w<€,·IÇ3æaïkoo?~»'9ðOÎr›ÙR•³¢4Y.d>[nÏÄìú¾:“D&ËRͶg&×Yn´”ÍÙg &½~ê”üLî²\ ’Ô™²ROKYf…”0¨02SF¨(e%§¤F¡”ûån±Ü4uÛïÇ'†Sf…°j–.{²y5±»Jv—ÂeÖùpûë»ä^Úù¶úØl[úhÛ›úžÚÝš~÷н髶î{¢ÛÔ¾~ó»¶­—}Óµ<ª¿«úÐò{ó}}ÿ!,ÿÐl6Ôª–Ëz×g(…ÙB¨ˆp:™•y.^AGVõº^è£ñrûâ­IkU–;“ƒ„p¢‚Æ Rd¥VŽÇd'úÆ—jÁ&J]”Ïß|:ê難pG¾õÅD!Ý|ñþPß?¾¢CÁm,&ûÇ\*]fÆYù<›qÔŸ©H”1™±…2 rߣä(AR9ß%Pš¶é›jCÔÕæÀôŸE.¶Ð :MIýU»¢Þ£¶‰¨mþÞ%Üœ³°1ßÆïµ§vu”™ÏÂDâ ‚<˜€m–àf=ÛÒF¶¡¹¿ë›µiÑŸ…Ðà<‰t×=PcKŠ -ÔÖÆ3"sð´[^¨ié—4ý=‡&^Èp0é6šØÅ;÷Õ¯5³ëï"ò·ï6`wáx‰^±ZBðǼ,ÕürM$Ú ûBXAuÜy<|Ô—u½ ³š}"ýWJ‡¦é0¤}RéL©äHéäLó°­ÃnUˆ'|†yZÕÕ†-BÂäþŽo<Ä)•Ÿ´Cq´]»`‰í ²³²óß:¯Çº`…Ñ1þ)ØÑ¶§ãÕ£hÁezÑj¾1˜{[“·£«×ñ¾p÷°ãº'/aÇ–¼ú«áÝ’Åàº,™S#Äü¾jpU$ú»EZ½=ªz¼ûLòzLO×à‰-¸á¾M÷@‘5;PS±C ú†prèQUجyswWí™9¿Ä¶jZR†±ªZò«);¹žªY™)q“Qy¤tN¤ž”ÉpüÌ5û83ÿ–é|ÜÏY*Ø­££Ñq–çmšmÃKuÇ<&š™a3Óm"îBoˆ~0€=˜ßÁk¶+ÁU;9^b­b•FÅú éJHÃ~øœ Z“:'"6Ê‘ˆ*¼ˆ‘ˆØ*(t$"ÆÏ°@ÛÑüÃÎË I7ÝŃÍÎÏâùUKC›í®Û×<âæq┠Ţ‘ʇò¼`&ÍÆHÀn/å§pj.òÌI¸°gqj:êiœGáŽëº_Œ×áØ8UѰA!Ê繈£&Ø\¬¶Y‘iÀ…f§ðQÙ¡í•~G˜( ø¾ª'? ŸG5vlŠN3<ÄeZ¶êÐð( ¾E!p‘ÃæjäúOИ÷¯ ;²W=Â]ø½é–¿²'í«.™¨ŒaÝ|Uõõ{Æ€znê¶®|tÒ.Âć Bô;A“AÈ„ßA öí!‰6%C$±vù ÒÛî~[m6Ôá}aD J]{äÄC¼Ô‘BAI>Å{6?ÉCÍQÃŽØ ¨…ÇwSŽ?…0Þ[Á²[†}—ü#$KœÚÏ`‹·ùÓ|S‚‘j$ñb³–BfV–©Y#œÈ³Ri5p›ÿòK+Ä.Ë£?Grªï^â@{€4È{wüòúƒ %,°÷€Imlù€>y&èM€ÎÁŽÇahåŠÃ8.Ò/&bj‚’U ðɘA’W' †Zƒ>>!zðm÷õty:x¨"s†èáã)ïK¡}}‹ÒDÈ%@#u$0"®ŽW‡8ÁŽ2W¸ /tNÀ‚$QοÄ·„þ¢0sŒO²˜?Ðm;³ñIèè ‚×Ð#çïœÝÚ£÷$ø…wNâ)–%(–šºjÖkŽ‚`™عá: lfÆ+zCPÆ`{à·±”6ð#Èg³Û°5}Aƒ)ÕÄm›9]¨Ï¾m— Y–8†NŠ7«×(‚5®‚w¨B¾ÇY"*H´R“¹¼+ý~Gp.CJ‰·©ŒY Rô¹pýH&¬» ¢ßS¹—3übþkýø@!cJ$Êhîñl«{H!N% l¹J@±Q5B‚謋4ÖU³™ZGg¥ŒÖƧlÚU³³éè0Á¤4‘Š@D·FŒ`åÃ]³¼#} ) vŒh½*£W ÚûC‡0(¸§ñ7 Œ­Î‘)ZÔ*ŒêyS„|HI³&6Ç çU»OÒ“8}ÂÓýxquPþŸoѨ__~›‘}FõRJ“I'ŠOÜèà&X5%¤Ä¢”/JjÔñ®Ÿ€xc$ZdV 90¢P̹V¿ƒœÆÅœÆsš".Ðò¼˜ÓXÎiB‘"O*Ò9W¤a~„HÜ…Þ˜ÓØÓØcNcÑnÕžÓ%œ~º „3 ;x®'lαâÀþ€VÄÙAûxXœŽ‰`b«ÃvçÝ´½û(°à ÙmÑ('J'¶È´.M,íjɳºÄIƒª: qCJÃÇ3m"ÿM»ÜVÙˆ—µÖ™´'µ¾YÍÙªÛ GÚ`âGÇ#ëÊ;@:R À„\{OW7Ç §‘UOC練åM]ó‚»jïó:ì'Ÿ9Fɉz vX74Õàô±pæÕ¿=àWz¸ði<#ñFØSÓ|Ê,KQ7z Tb9_Ò~×õõŸÀ—Í{úÒ p°„¤ÐL`7‚ ¬vÌíòÑ›ðE> x zTž§ŒÇJÐÿŒMëqL}ìðZb“ ´½žÃ/^·ÇAôyTuüèxpE?1'Ã6Ëž‡zÿcÅÀÿXsÜš> endobj 1926 0 obj << /D [1924 0 R /XYZ 56.6929 794.5015 null] >> endobj 1923 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F11 1559 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1929 0 obj << /Length 3563 /Filter /FlateDecode >> stream xÚÍZKsãÆ¾ëWèªjcxŧõFë(e¯7Zº|°}‰¡„,Ð(®üëÓ¯@ ”]I)• =ïž™î¯CuÁŸºÎâ02¹½NsÆ‘Š¯×Û«èúÚ¾½RÒ'ð‚i¯o–W_½7Ùuæ‰N®—›É\Ye™º^–?/ÞýýíÇåíýM ãh‘„7AœD‹oî>ükrþ¼ûáÃû»o¼{“ÚÅòî‡\}ûþöþöûۛ@e±‚ñZf¸0àýÝw·L}{ÿöûïßÞßüºüÇÕírØËt¿*2¸‘ß®~þ5º.aÛÿ¸ŠB“gñõ Q¨ò\_o¯llÂØãkê«OWÿ&œ´Òйó‹MÆ™NgPëɪh›\§q&F:À}Õ¹ö¤ì¢XµOI³(¸æ­ícõðˆ_nè÷7*[¸î±­Ë7P§Ô¹–SÓåâ,4&JI\hãúõ£ë‚£‚ÎퟀäqS63ê\[V s¼lyX»’9Ù´{n鋞«dJ¸2¸Fg‹»ï"ûê«­k½LY¸üu ­ mà(• ó8Ö´r_µÐ&+iív‡œ¤ñbåêöÈ-ðx NN)µ/O)»|Jiæ*SÿÁ)eyOO ®š5¯\t®„C0™Y,aó/×MÓPg _“eƒßm_»b_l»™%c£0ÊQS§çÔîचŽõb]4L¬]P}Ëߢüסë¥îQºÑ¢®w{™‡o—zTÃÔõúP¸XH÷y˜jË|üÅч¶w…m«¶í2ƒLuMý,ì<U]¬jaäˆ×DÔˆ"~ÐêPÕÂø±êgNU'i˜f Z|¬ë¶ù%ŠôÃa/³ƒˆ$®ÁÕ:òºÚVýÌQ+…Iœ$2O{S/°.#ÁI2•Ùyl•NÁ´CƒšÁÖ¡×e¡˜² R@§Ø|•‡¡× úLâ8ÍO¹øäz8~“$¦ÂB -AÖ˜ éA¢|nŠmµæ‚èdõ{Õ´e£¡ÿ×í)€õ)~oØNºe-¹fû )ÎL¼˜é0ÏS¸{ {|)Eƀ몴ôª«®w¢Áômóff^›„Iy_·_ï‚u]°¼œÜ桵‘g¡yŽð ]7ݸô.wàr»å4J‡±ŽÎÂovßL‚øùÐ2šB /ˆÑ5‚™V$ n·CçßÛÆ1ÕïÁ;ÚÆ‘ã—ˆ» £ã‡£»™0ºƒ†(¯Ø±ÒsZ›†¹ÑþHh‘x\8ª¶‡-¼³mÒùõÀÞ(سpaf] .Æoò1ØÄˬ\|‘•í¸²çWVˆ©‰ñ³ý™k×u~I -xMTFt>‰ï‹ >CÓ€Ï4왉•ð.žhKZŒU3îŽ$&Ö1žèÞæÐxìOwÎ:<RYW}ï-‚Ûà4ˆÆ¼éàïO7qŒ‘R{ìÂKØlrÀñ(Ê_Çæi¯ËØ<ôBþáxƒ5„4.€PÖ½@æØ„QnÒ××zÍ0 ÏrxQ«SH®ÍFé2Ü­8\–ƒ5êׇA ¶“cu¥[ ШÅÏ'ñYÚ_:®¢¢º¬[=÷9û‰G™…¤Âf!@üœxî4¸{´è$”E’å}M$hY&%¡†±?V(Ÿ’‚&²áèõ%ñ8ÔoécE˜HÒ¾Ç ×ìT–2a%º¢_vÕàü@yçã1/Óçþ3Ëüªà<šÈ†¿…|¿»ÿ‘‰IŸ®G—øáYJ-}&ÕãuÑ:*Tâ$B²hZ©p_Ö`!)ÕˆžïÒûìž²?Á™|Ѝւ«d½u:4t޳v ä4Í3ß“ΆÃZ5Á”Î}¯“+÷p—' ŒãM”úû€òL™lZþ²GF$abU¨l_£™Ï\ ´S¯dÄŽoì&ã J»åÖÞO©p®µ¦h–JZ[4%b(ÊgI+e©˜ ¤ŠQ)ˆ {F‚ZÚ(NJĶ@ÅEŠÜ\éÝ€ÿÁ/,+`檒×/“až ë¼-€Îlý£EÄv;ã\nh:-¾]}ÍÖ=¿Üç8JmôpÛŽ¼S€Ô Õß`΋i/çHZw¾3ØÅƒO¾ Ïe‚kÏ0~”e¯ñÙÜ\¢=†3±`m˜Gøc@gUÄ+øÚ­(ß*Š¢ÅGˆ§ÚKp²%e´Šî3ï0&…ºKh¥€H²$~­¦½.£ÕЋ)5çÞƒJXx™‹€ð1<}•…¡× §p•†6Ë“S&–¢Çz1pÁ%©0¶õ3W¶«®­ Úå¢Î¬9OU{èÆœ!ež²Ñ{DúØ(éI,$ &¿ÌJñwÉ©<‰mnÙ!egܬ{±–HòûÄÜ vB”ŸûÄ×Ü}?^ãYâß¼ÀâÐCL̹7\0çOC舺W4Ń릌ñó} ¢<úûâBøÈú¢Û0YÈT“¼4„íî·Çw/Â/^«á¼x&–*Ë–WÏØÏ’nªÛæäø²ÅnÐ)â¹öÏH<íó)3á$|Ú¹uµyæ”ÆÉ{ø4z¥ç œcç“ ¶i_hïè,ã¦Ç$VžÍ.©¿2`ÜUòê?éõŠúû^’_ß÷+Wô¯èü)ë< ½f˜8Mä(ðãbuÊç"£1BµC0µpÍh ¸š“NXhúE³vÜÔžvÜÆÉ(å,=Öฎë¶Åþ3¥.¡º˜Ë“†¢Ñ ²èßÍ>GCd”ÆÙY†£ Ç0“fÞIIó)¸Aýˆ1¤›¹÷ÄÒÉs)üè$âòDŸa̽+º¶á,;¶6è!ÍÃaÌNË_ÅÕe1û`„I%emĿɑ%%ÇDI46 °tÌ€¥±üd•ŒË°ŽÔàÔ62úÂÜ ÿ¬:rГJГr˜©IÝ ^òir" 3»™üÜÅùŸˆ<ð“C-o$íz}¸ ‰ÞÕCü½ØŒÀ¿,ù_ÿ,müÍžAÌ2=¯L˜:Í4EÂn5C˜ÐÓŸé…௛à£=ßÔðÓ¶—»ú7úLoóendstream endobj 1928 0 obj << /Type /Page /Contents 1929 0 R /Resources 1927 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1914 0 R >> endobj 1930 0 obj << /D [1928 0 R /XYZ 85.0394 794.5015 null] >> endobj 538 0 obj << /D [1928 0 R /XYZ 85.0394 237.1294 null] >> endobj 1931 0 obj << /D [1928 0 R /XYZ 85.0394 212.1866 null] >> endobj 1927 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R /F49 1358 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1934 0 obj << /Length 2739 /Filter /FlateDecode >> stream xÚ­]sÛ8î=¿B÷¦ÌÔ*¿ôÁéS¶M»Ù¹M÷ÒÜÜÃî>(6íh*K©$7õìì?€ eÊVÒí´ÓI‚ € >h1øÇ£4K2-t”k•¤Œ§Ñr{Æ¢ ̽;ãŽfá‰!ÕO·g/ßÊ"Ò‰ÎDÝ®^EŠ‚G·«ßã,É9p`ñë÷×o¯Þý÷æâ–ûsÎyœœ„ZÏ2¸r™ÊÒçƒ^HõtЩPí~uû¡ZöÏD=•d…þŠ#ÕŒ“¨'!ØåìHŒër‹‡ÎŠÑy-< ‡ãÜÎÜ9êºÝl¬‡üT„ã:…´"|¼zBãÓÇ2™žÄ8UH M¸£gðÀ©Èó£ûä c 9óñâ\\³®ãV`\Ã/Å5„‚¸fLâòƸfÝÓ8gø†_æ\¹i½ÿ ;õì;'öÄÁ,©Öi”É"á’Š˜¯å~¼oPÊó¹âOŽÀ²gxÑ:¼èWLY-¼tPædpï:œmžˆ¼Q&T¢§û8Aš)n=R£Ê9ÁûóEÆã[ø_Ä'5Q‘%ê¡(-X’g¹­N¢Ox‘ÒZQ[U&°ˆ—W[½iA¡(ÔÉ1^„œ­RÙÄÉ…„BI O ÎݵjÑò"ÞŸ 7¨¶µÙpþ•C4ôu•!@úääU¦H#EØöûNK‚¤™†úqq(û¾Ï—¦ÀÅ×"a µf‹|‘Íq$|éôÖFäö¡…«°Ÿ‰à¸ &\~7Há ÈP‚¢>$†žÐwÆ& D›O»²†© B§â€ˆ QúˆÈå}ÛöƱ(éÓØX‰³Jn¯:â0]ï µ¦D» V WZAׄ±üfÊâÞcu¡y\Á* žOÙÛ¬a’䯛ÎS:âÊÓ«%¤ô=M-kTlðóŽ~èM½†h–©±”<Îô ¼&sWrxúx”J˜Ð:úÖåÝ~Pß•“®lföçTXÄÓúrEÕÒBAúâi®ŽêÚÎôýL¬dDeø'î-ý¬s[~‹€á©o w>îi“W9,ïO’:‰„‚ý‡I72|^<ˆL‰‡ZŸ<=Bž'¹ÜAc+Áœj+ç†CïpƒŸÃo†ÎŽÃþÁ,«²¦Á¡ÈZ¤9/K°Š/ZÔP=Ô´–nN˜Úû ²v[•}_mã„qAí;”ÍÒ$ä%y–ÈŒS'¹n›Ec6¥ » —g|!:o0<#º¤±gIÈ»²÷Ël .l½_u„zhûŠ œ°F,ÝLAE*^ci›‘±ÄÌ“pºŽÝ’<Ç‚U?×-Ø{ ]­ö r7à ¢Ü\1J‘±€þ¾ílS3á¨h2<Ö|ã1 ‘TnçÁ6.(æŠ:/0=P{ÍïŠJ‰Ò\ Î[ŒÛåbóÒAܬ˜ Ë5Gq8íô¥b ÇVV4œòÌY®V´¦wÔN ˜rޤÉ7Gšk]ï+´CXw®we0×·4¾ Úû2pcßäú¸oò¾õÙcá Ú·­[f¾”X´¼ (¡Žò0‡†Ži=M ‹ ’ø_Vi¨4>TM|—³—Å«9›ü‹C% _ 5;û1š—<{E‰œ,ô7­YÌîH“§eD(¾ï×yhiìÒ1õ™€<¼ýÀ€3úº‡o[{ã°û_·¾™F l¦ñ{ÏrK°Ä±Åöf·eÿ‘–ˆ4Mð(° ™½<Ö” Ø*KJ¥ ìpOÓ$2æËÒ<¸7 Ä ‚h/¨¢'œ 8*+¨$p*&z1­¨¾¯ÇÝïÚÊñ>ØÜ¿b̽ڔÞá[×pAY“Œ¤ÁiŽÍÞøðE]™wQwïNúà?ϸ¶ýÔ-UhžWÁôï'9÷| 6€üšÿèý²;ÖêÙNðoí pÅQ1¾“ó\%œ+ùD—Áç<K‰$e Ùhâ€'ËEqè2€¹úaMœg¼9Ÿ6qºHr|AÀ %Y6úÕ*›ÔFŽÏÓ2xÂÊàût"lýÕÊ)­â·iH[×÷yúZª3ý-}áóþ:•LrN>ÿt_Èe‘(Íø¤/”¾/ôwº‡Òåû>ŒÆW[Eâ Uì2øCÛôCΔ4|sýÆ®«Cp[îir Ëh{|˜]r Q¦z¨§´; ,'Øek¿«žbؼ¹±¯IDµn»-½kÂlù-üf{I”S+¿ܳ•Rî= '©³Eh|ÂØ¥Dœ‘¨ƒÄ‘ëv]CcÊ!:¿_‰ødVÅvwýœ-I`¡}ö_(HAs8NÂ:½@œ™d€úÜíúÙ 7†€ùGjP¸HS‰ºäX´c|ä2)K´T§í«ýy¢9¾†‚+èŠup%··æº N7ÁcíH¾èOßjO¸¢,ÌÒÄ_u"P‘&šúÁ'oÆ#ÑWÄ8æå O?çdÎ@še]6ò®Z“ál»rtÐuìêUHWv]Ùl‚Ó³:•sBcÇFEhØÜO]ç„åEžù'ÿ{'‹Êã]O רêC!o?ŠÐ¾ŽÀætã™:¢ LįmBìâÖ1sÅüñVXaC+ò3…®+y1çß” Y)í% 4lO(úM€njÛ”ÊMÙ—ûÇÒ·®¾Zö2[”ÿù… /éøôÛ2 Îã+—ÁàëÍꩊÑ`*l_xÙœ¿Ý/zså‘Ä<ë·l¬C¾û—ïCfRy"‹BÌ߀#™ð`‚_ñ(qäâ7 „q!NF‚p"¡€8Uêÿ"ó“endstream endobj 1933 0 obj << /Type /Page /Contents 1934 0 R /Resources 1932 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1914 0 R /Annots [ 1938 0 R ] >> endobj 1938 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [213.6732 85.4256 286.8984 97.4853] /Subtype /Link /A << /S /GoTo /D (rrset_ordering) >> >> endobj 1935 0 obj << /D [1933 0 R /XYZ 56.6929 794.5015 null] >> endobj 542 0 obj << /D [1933 0 R /XYZ 56.6929 545.3099 null] >> endobj 1936 0 obj << /D [1933 0 R /XYZ 56.6929 521.1123 null] >> endobj 546 0 obj << /D [1933 0 R /XYZ 56.6929 152.8992 null] >> endobj 1937 0 obj << /D [1933 0 R /XYZ 56.6929 131.1723 null] >> endobj 1932 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F61 1466 0 R /F42 1338 0 R /F62 1469 0 R >> /XObject << /Im2 1455 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1941 0 obj << /Length 2587 /Filter /FlateDecode >> stream xÚÅZÝoÛ8Ï_á·S€š¿$ }Êö’n»i7ë{ÚÝÅ–c¡¶”ZrÒ ¸ÿýf8¤LÉrlŠ‚Cr8þ8š:|Ã?>1šÅ2S“4SLÇ\O曓xrsO¸ã™z¦iÈõÓìäìRšIƲD$“Ù2eXl ŸÌF~>ÿ<»¸9 G ;ê$Ž~ººþ7dÔ|øt}yõñ?7ç§©ŠfWŸ®iøæâòâæâúÃÅé”Ía½pŽ,¸¼úõ‚¨7ç¿ýv~sú÷ì—“‹Yw–ð¼<–x¯'þOpì_Nb&3£'ЉÏ21Ùœ(-™VRú‘õÉ'¿wƒY»t ?- ÓF¤# 1 ÎX"…´Îó NdÒè¶ ö¾Ø.ëí¦XP·´ÓIÔ®Ü|SlŠ-âò²$ºÍÏ\;Yó|]Uû¯†zùb±=å&*špV"Žf«²ñK×ODË×]éx¤ºú+ŽÅÝn[Vwƒ]ª|SàMSÎY¦µ°g#U›wteUÝ‘¯×D HMPÊ ŠÅ‰h¶²²K`ÉÂD)`¶ÕÛv]6­c A—p#`\ž±ÍÛb{NeGÅ:nŠ‚:·Åº~„ްfQ›Á³ã \шpë&Ë'±\‡)9ØOjÒI*$K¸2¯1IÁ2c̸AN;‰ÓP$Y[¨Ÿä ÓIª÷;£š›¼¯”TŠÉÅ*é%¾¤¤J™1ï+yä*yÊd"¹¼ZÐí”U[lïÉX[wceK—X<ljâ ^s_ÌK´ç9ã“5;°d8‹—׳áve?Є[k=4´•¥N©¶¾¯×õÝÓˆöJ²X"†ˆ²µýÎaMrx?Bf,V Œ4K4ì`ÒäönBÄMà:þi¸àÐ!ÊEÕþ(æmY»C£KCââаcf¸é©tà=Ó zÈB5ðK/–]ä`³tõ=k¸Ù5!6€²|öº8œÌ¸~•ãà²ó0›]ãå·M±^’ɨ¤ÅJ÷M=¹Lº hyT|»_—ó²Q'QLëó>„Å2 1(É2–âv?úyv§¡ÈÃÏ“›”e`éØŽúVbtövJv_PR@,à)XqOÉc>rtžøcÙ®è®êª Ë7aÚÇšˆbm #&xSŽ,#z-EÀägtü¸*çNô&"âÖ­$»ÑÕg²"®\õ(ˆÕ?%dv™Îp™mËC=¾ XÎ?üJ„Ì–²ç‚6ÇÆDUÑ´5Z¤1ÓRëšâËpÀ,$U™|ƒˆá$NC‘crëýÎÇÃZ ¸%ßPI/ñ%%SÍD ¡ª§ä1“T ø38% öÆ–ÔÖû!e½ÎûY²<å‘5Cè`2‡í|UÌ¿Ðõ‚Ò±bI ‰Š³/JÜ󻼬švˆ5õÎZÕÜõ+¤Tª·âë®Ø>¹«ÚÒev95t-–,€e½«£‰Þ§ w; áH„êH%úê ƒÅ(\áÔAæUî˜n ›eõ)øµ$**û‹…ÃWuÑŪdŒÐ…4¸EàÜö6iÆ¥è?F2`çpCárxvQ>ow9nÀ9|Æå¦lˇ‚º{OÂå¼¥a§9u:9=|`¢ XƒÆ]Ó­­©… qÞost}Õ?w9^¾È\©ÐÜ×UãFP<¶›úa0Ò-º-îʪ¢*B™÷æC¡˜Ä2ºò„1_Ýc›Sc?´¾ðG§…÷æX“H…«½èÑnÜBg«1Yµ¤nÞÀ©ÓD ù^ rÏ;ž’>ŠÕç=nœ1V;I¸fjŸwf^â49VH€Ó€GÇöL!3e²7ÔÑ |IEH®Ušš¾ŠÇË­„qpcºhïh,Æ,æB¾*·×P s{|Ìà>}µ¶a ìF†Ü3$áPÏ©QÇ)§ózæMSÞU¶ØOÈÇB³€SæÖuÚÁj±Oi¤çÂQZE­ãàï¦(/ê1mʪÜì6c{–N0~ó~÷ú¸ßÐqÏŒ•¾ ‰WxkƸ ˆe½†êÝJ”&…”;ßܯ‹wøÊ!”'âÂèPÚª¾{瘥ÕÚ ±Cõ†zÝ*dÂÍH½°žUmƒ2P®`°ôc‰oHÝ혿 OްfÚçyËbëž^25ÔÙlņS¨¶XRK¨Â̺¦j׎‚[« Ø ƒ¹ª¹ýbß… âº.¾µÄ·±ç@–@K,ˆ!÷uµí,¦cßW66¤lìŸ`€gXgÆÏ„¢)§:jž8»Æ| Õ>‘‘·{Ý4èE 'ÒØ8œ‘݌ی:ÖúGî¦ÂÐ)y„m)mñfU?VDÞ‚<Ê:¤@ÇBUÞZËè÷Î0`˜À&ôrjœ…InÑ´Ò­ñ„šc'ñÇ•:õ6 Tp0Û¯ U$‡&¯éqÊ%):틵‰†öñPïà µ‘U/„êψ9íÑÒÙ-ÝûŒ÷C óêŠFœbY·»r»ûbi„E¤i¡ñá¾$Oz0å’ÂDWöí+qSiÔ”›roiÐ>Zh¯œî)=*X‚éÁ;YbC,ɵåŒøÅ“H±Œ}sZܹ>.£š/Р+YPV—Ù+® ˜ô8"éSÄ.C‘å6½Aªp¤{j”Ù^FZ ² ì†ùkš„ÇÀY:†•XS»¯¼ ¦³¤ÅÈu¹äSÙݽîni‹_h& aV ûÄ:ÎR+Lά¸AC´“ðUŒÐƒN ‹¥¸‡09¬}ûÇqO¦¥OõœNáïã·ÝcìÎñl>'Žæs‰f©–ꥬi˜=ãM¾?Ë<l:™±¿ÐšáŸUŒüjÿÝ®?ü×û?mÁŸýŒG~ŒpóYê•BÍ ;Jˆð¯Y¦ŸÕðPÝ_€žêAÉÅ,endstream endobj 1940 0 obj << /Type /Page /Contents 1941 0 R /Resources 1939 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1914 0 R /Annots [ 1943 0 R ] >> endobj 1943 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [238.0484 707.854 311.8142 719.9136] /Subtype /Link /A << /S /GoTo /D (topology) >> >> endobj 1942 0 obj << /D [1940 0 R /XYZ 85.0394 794.5015 null] >> endobj 1939 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1946 0 obj << /Length 2926 /Filter /FlateDecode >> stream xÚÅ]sÛ¸ñÝ¿B“'©!ø$‰Ë““Ø©o­N§“Ë-Ñ6ç(R'Rq|þ÷.° Š”ìÔ×édbAÀb±»ØoˆM(üc‘Hs=‰µ$Š25Y®OèäÖ>ž03÷@óêÝâä͹H&šèˆG“Åm€+!4IØd±ú<'3À@§ï?]ž_|üûÕé,–ÓÅŧËÙœ+:=¿øé G¯Nþùôj6g‰bÓ÷=ýeqv…K‘ÃñîâòÎhü8€ôêìüìêìòýÙìËâÇ“³EËKÈ/£Â0òûÉç/t²¶<¡DèDMà %Lk>YŸH%ˆ’Bø™âäúäo-Â`Õn•£„‹ˆ³1*M"ÁE+@&A.”kWuÖ —Ÿ¶«l›—w†I@ÅTt2ç’hɤEòû¬„=‘š®wE“oŠÌ|‹¦ÛK¦Ù²²Ÿ«ARœ !šÝ¶ÌV¸œ—¸’:ŒiY?d[·ÖàÚ:}ĉ‡fWg·»çš ç–36­Ê_)åw»ðÈæ>C@G"¦Õ­Û€zƒaœ1¢•â–ñM‘.-áRáöd)˜B õ¦*ë TLÐdº€5”gx5L0ÂU”~ƒv»…K˜WFþ#ÂW”¨îaë&m²uV6xä&Û®ó¦FB–-ÿi“W%BX>á³¥²•ƒ¹k»o2& °#F®c/´H{ =)~ ßúx¹NHŒN¯3Ÿu…£f\nI æ!•—EµmмnF„&$¡0±'³×û,xDC‹Á¨â„ZSÂÅíÝWíµðópÚ^ïø^CÇu¶t÷bZ¢Фc¢-z4 ¼@ õ%l†‚W*$衎$\)@ ÛÅÓrLô¡€ËI´ÕÕp8)J’x^‡$2Nžã9—$ãÎpîÎCŒCGŽŒDq¬ºƒí¥o²åˆbpN$UÞšò/c•ÃA§dôÐMßVEQ=Ô? ´"¸S tÂÂc>/‹´®ñ %Ã"1†¹ƒZ¨P`Œ  #±¼+‹z©ÄZŒó¥Y8×s#2fˆ,Óu6&2 T:N¾ h>7›l„mðl,â^Oŵ֠î±|×pŸkCéýù«UµNór`Ø”‘ˆ õç1Þb|‚qA%‰(¤Æ_q® XîsÞEÏî9áÆNß0žGoOìE…&táG(=-+ó™8[±S9u74öœ+ÍV¯a&q‘ÝlXe·)Ä·¥õ^ Xcì/èôòŸã®!ÒÒ³A—8â4h4´ÉÚ³ìâAÚtH[r€¶XÉÛ vŒ¶è8mV9ƒƒ@Þ0E¢~Ó'ׇ[ç¹æ‹÷Ž¿r.ǧ ( ¤½HÔ_FÈ–À™ð6dÑ BªhZ7 &õo0f.ï%¨ˆûáhái+²»´Àá×´Øe­“ÞŽ—$€A‰§uB`¬ÛôÊe«? œÕ„ÁŸId)سr}!Óx/×ÿïvyBL*n=Ó p\nèwìûMÏÔ\¸(gâ+SDš(E¡8‰Ü­õùñr(ÐH¡¦¡@¯zõ€¤A= Ù~=Ë6Ÿ”^#$LÛqþq€¨ÀaÓ:ý£*³±ŒÞì*2²ÝRÅD2HwÁ¼LÖæV!F%ÝñÏGéw¾¾²³H%ÇïOÅP*Ž5Ü6-!J}çõ©Pêm.ß^Ÿ¢m9PWkƒí¨¯=`çe"ê¤.c(^hü(ýŽÃRç ¿ý„Õ@Ø×£º-—E¾üŸIÝaڕ«9Žn<ìð.ömã•…®Mbj^kÃ<(4-)®"~È›û½BÒ¸|øeezSdsç4æ¶àuáÀT¤_®òiÚôIÁTeY­7¹­*µÉ Ö™ ]ÂVߥ›·§rËeÞä6Tº_î²-wCxß¹‡¼(pr6Ëû1±´±Ò¸Tö.žöï£ý£…}ÒáJõ2Eít¿k&ý?"‹41$Ÿ®Ëaa=;¨kyœ€Ù å_,¢u­ïnA¹ñ[àÕœW[”rö-]o ãoÎå^/‹An Ý–°÷2(þËÞ¹ÏO{7ïSuq‰Ÿ¶À±£SüÀÌŒ^ÝWuC%4øÎg¡o|;¦ešó[—#õ Cóø÷Ûñ¦<1·e`œf›NYº«3ßu{ ›_Ø•±»ØæUØA³<šÑéÁ>_Ô6òœÌÐÉ`jîS×É»O¿:T]N)ûµea>oÛá›Z‘È4&{9¦aÍ‘âG½»5ÔZdT$T^èï~Ç^ˆhŸb@æ+búÚÖ ;±Fu‚KæËöË@3˜ –„D îñø/6]À_>¼N80žpóä‘D6Ù›ü>a„J­cËk';ñæbÍ'*àh0åÏCÌ–©(Tx˜œs€J°ª¹€ –Ì< ˜TÇŒ¶Y‘¥Æ]š/&s0Ÿ˜™‘µ’Rwýê(4&)T‘n­j[вfœvÝ”aJ’˜µ¥~Ðï7ç­ªÌfÍÇ êÝfc\µ)wpÆf]ÆÑÍ £ÉVÞÕšFàˆÑPÃÌcŒI‘"=½1ä=âìÇà16dœTWç¹ÃŒ#û—øœ£Ý‹žšÐà,ü&Œ:ÈìàK“¯³!6½º}tåû~j¦˜xÂ<བྷjÆÿ–ø‰¾f©Kg³[ƒ™ã—ü“¹»aÞÉ ‡; -èeFiÌ_iPšïÈÛŽ»ŒÐÎ#¢i1d‰&’jÞ{1TîÅp1cïJw=gÇ@sÁM0PžðÏ—4¡ŽÐâ¡ -$Wó¦)/`ò.áèÁhäà^>š€£î|5®ôiK›r·¾Á¦whLT &M±”.q·¹¬6GÄ Û¯I^®ò¥}¸so‡çWymŠ'‡Õ`3¢gSezi‹{_™vܧfÜìËO‹±Þ¬¤ 4Kö}ƒ’kpA«lEL·3šÅ¡–á0©cBpŸÔAN;Ö᤽^!pŨËZòr×d5m£t¹ÚËÖé·|½[ÍÁcäÄ1áZxrX2NO6ÀrÄÿŒ¦ y¢”õ“®Ÿ¼²Ú7V÷´‰¯´ Öâ…½4ÿm€ÖP©7ᣬô>F.¯¯ÏÞãxÌWí+¯šÞ¦yáªq÷´Ç$êàª{“×r¿1{ù|¬"iå[¹lÒ ¤Óú61ó÷ã^soR7ámÁ”h …Ü÷póÛAÊ× /hD·¿UðˆÁ,j¿3-GÉ"‡¼”Ñ‚8bÇTtäÈJ)ý6/-›cŽŠqÞE¨£‡·@ÃÓ{jÌ¡l1){xüb¦Á™†r¶»Ú-m›CNˬy¨¶¿áb³MÛ‚h‰ëhVÜ„ñ%™Ùd[(!.mÛ…kß”å~×,1Ï_2|ÌåÂü:d…#«&ð‰zƒéìÜ÷?vh@ÑšÌ>´9aÌmK«vsŽü’—íº?ËËÃ/Êêè«ELÕ2¢ tòd»ø¹¿-ê²i…Å¿=šl%ÕýN üó_Ìχ€(>MäмÜÏ“†Lý/^™endstream endobj 1945 0 obj << /Type /Page /Contents 1946 0 R /Resources 1944 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1952 0 R /Annots [ 1948 0 R ] >> endobj 1948 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [325.3322 706.9749 398.9856 719.0345] /Subtype /Link /A << /S /GoTo /D (the_sortlist_statement) >> >> endobj 1947 0 obj << /D [1945 0 R /XYZ 56.6929 794.5015 null] >> endobj 550 0 obj << /D [1945 0 R /XYZ 56.6929 769.5949 null] >> endobj 1424 0 obj << /D [1945 0 R /XYZ 56.6929 749.9737 null] >> endobj 1949 0 obj << /D [1945 0 R /XYZ 56.6929 624.285 null] >> endobj 1950 0 obj << /D [1945 0 R /XYZ 56.6929 612.3298 null] >> endobj 554 0 obj << /D [1945 0 R /XYZ 56.6929 204.3723 null] >> endobj 1951 0 obj << /D [1945 0 R /XYZ 56.6929 179.2767 null] >> endobj 1944 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F54 1433 0 R /F42 1338 0 R /F61 1466 0 R /F62 1469 0 R >> /XObject << /Im2 1455 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1955 0 obj << /Length 3426 /Filter /FlateDecode >> stream xÚ½ZÝsÜ6÷_±o'ÏT ?DJ|t§ç^›ôl÷fnÚ>È»²W“]É‘´vÜ¿þÔJ»Z§Ì\<~$þÐÊ…€?¹ÈM"´K™K#¤Y,·gbñc?œI¦‰Q<¦úþöìÍ{/\⬲‹ÛûÑZy"ò\.nW¿EoÿyñËíåõy¬Œˆlr+¢ï¯>¼£GÅÛÞ_ýðëõÅy–F·W?P÷õåûËëËo/Ïc™ ó¯pbÂû«Ÿ.©öÃõÅÏ?_\ŸÿqûãÙåíp–ñy¥ÐxÏg¿ý!+8ög"Ñ.7‹ghˆD:§Û³ÔèĤZ‡žÍÙÍÙ¿‡G£~êœüŒÎ“«lF€J(ÔS»ÈŒK¬VÚ ðv]≲hUÞ»M'‚yr4XR¥°NØ_âzY,×eÜ÷&ocóÄè!òª#’tLûçiÆRäB̬£U’¦Î0UW.›zÕ¯¿ #4U×Í®í -“Îs•8‘ª¿Ç¹dòeQ×MO»”_–e¹¢zÆò*^˜›¢^áb‹XK›càJ¤„•Œòëv]À¿7T§#,ùò:º#Ú“<°ƒ(»f³ë«¦ž†®ê‘¤¹,»î¤žYÄ(ïG´£ ð¤N¯Eó¬ÅÕ0cºT¸Ç#M¬Êõ5ƒA ÒÀ0¼óÆ)<.iÿ‡‘4ŒPy%FÆÇóØÊèþWÑå‘h`Q w¸0ižä©–¸ùâóB&"uNÕ¨îO»—‚ïxsµU‹w œi1>VX9/íÏeåäÅ#æ80&É-ÊÃ,o7å^w\쨩dŸjîèºS—Cfõb,Ðo»#Ã’<Ðxï8~‚b08ˆÊ’eú5cˆ¤Æ¾nÊ‘w慎«jUõ/±7ýÐ:ºûÌ$Yž«Åhùc£ˆŽ™˜Ø4`5³à^޹¸y,—ÕïB(ÿèeÁȲ½YƒNoÖ²Á„`¸¡>ž~ÅžHo¤¨ý¼.k"y÷áææò-õ±ë"v4^ìúf[ôUL¶)I®´™Ú¦%¼Ñøp‹ ¶¬W×£;èãñ„ãK8^—œ·¥m=;ðòqcUb@['Üá` úG«!ì·ì÷A­üòÈ< ÊY|†+ü‚¡è™õæQðl `ø½1°§5—ê·AÏEÈàŽbµ£;ÖÍ3U6Mý@µ»ò¾ ¼`ÛóúBuzc©ÆÃ‡¸ó;úƒÒbTÒð0t-­Ž®îiÔG¿xÎÑ#¦Wàj“§êôZ›°9ŒÞ1ÕÁæDæƒòMJòaVÑ•DŒ‡ä3z¶ý®$_ßK'tL0ˆ™©ªY‡/h½¡h JÖyÃLø¡`Á¨Å¦á™7/+0”Q±_¼UÛçjX°Ÿ.5a–v¤ÒÇÃè²€~ŒÑÞe \ÎlijËçãö4K”Ìr~§õ\Ô.SˆÂdp}ø<°ÞCõT!X±Ž¶Ée|Ã1Âaš2á­”MoµqYD£Ñ|FèÛÇwÐðqï\ : )h©—²h;RFЩ]6…®Ï0X+öøcðrË“ÌÙqE©)®©«ªÑ‡$cM;q £â~@eE†Â›t¥9¼Gú†J ý ‚·Kµ±Â{ÒÀÅr×RÝn–ƒÐ‚àV¸È 8Ÿ°©¶Õ•(¶Í®f··áDÄrÓ,?qNâSù|îTt #5Èè8=#]¢Œù–“.Àœƀ?øÎˆd³ î<ŸVD‡›²èzîëJðÿ=°`` ÚP§Öb‡<ºùxA={›Omâ Bû°R%H¦PR‚uϲl*RPþèàÆï6Søe‹ðìùTQa>7úz<mÕì8„÷ÊKúx+ÁìháM?“êÔ$i&¾“Ž©N;rU¸FVé¸nVåqljm¢sm_ga šáaboÀÖ¯ Þ‘»GAÈà“ɱ‰#êþþ€ø¥I uÝÁ]óôò ¸LµW ð×ߤOAÏç]Q÷ayö÷€…Á¾œ•I*swhw&I¼?IÛ¡ö\õëÉP]>S|È]þ÷\J%Ôó•ðt,2Q¥“CžSÎf_e–8­²Sê#¡ÀNÕW`4¢zFêFÁ°Î`)‡ÙåÙë| T3ŒLÎìd¢ò){$)ã¯AáƒÏ¾Ëºñ¦º4AÝ£I¥ÇνŸêm“ ï+[À•Osas”Q"hì7F„1”r€½N§H"ð!pÖÁtì×ÿ'À2 ¤VÀæðÅ|_`¹¡’Ù×ñ5¦:¯ê_ýËcy„,ã öuª&§µ):jÊÂZàUT<¶Õ!Á¦Ñõ»‹spØn}f•º<«žÒ((︽ë¼e‚ß>P³÷L€‘=°ÑóFú0!Šî#߸ǚ Îq"E} ©cgÃ; ÑŽNgpà³ Cª,ᘞx‘š©q…›I·KƒoŠdŽÓ X¾(‹¶Ø–ämË놊™ ©ìmóD‹° “†1H/´Ätü² –c*Ú}XÄ\¯Èå]ðg½¤›ázr7\‡×Cã{·|ù9û#Ž=ŠàSBÿÝËŒ†/ìî¨i­æ¾Äé$ÏL¸#ú;Ãò‰6£ú¦ÎçèP%gžL 4Ñ ¾?gaEb3eN&Ø1Tp´¤L°*BÝK »õ1’ÐA»ë9¢µºVO% 7L¾.˜îÎ;Z8´l0}Ç¡n‚Gao;—O»cªªî$±¹ëÂѼk—U¸ß–¿ÜŒ °2\L[¯–4c¤Á*Š7UÇlm:6x˜¥Â4oîgOƒ ô xàgÙè#‚ú˜ M&ÿL¬ÐÁeðâE.1J­«nMæéàü$AŸ¤ý(q_-w›¢e”hð®÷© ×>•/þ­ú޾®QªAŽöò Â"V§÷I}E×5ËŠs R3'8 ¨á>¾Bw/ݽÔS[‚÷„ÛmX‚w¦“ú™/a&~þ jp ùä ¸±]/!Òiç%¦´ERµzSlšζ¥¹'à!%øLf˜Šø°9$O&°ðÙ©§fªvOnIw*?åóÇà ˆÓ6 ™2ì' Ž}«;<ÖPé…ái¨=|÷}>ûŒ½! ¡íôH¼PÿœBѳIðwb3Ú(†`ë›޶ÿ­^š%µk^­ñ¸rY` EœÀ10¡Æ?ÏK$ðÿ’jøIÛñ©þ t%endstream endobj 1954 0 obj << /Type /Page /Contents 1955 0 R /Resources 1953 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1952 0 R /Annots [ 1957 0 R ] >> endobj 1957 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [315.1789 493.6951 363.5077 505.7548] /Subtype /Link /A << /S /GoTo /D (dynamic_update) >> >> endobj 1956 0 obj << /D [1954 0 R /XYZ 85.0394 794.5015 null] >> endobj 1953 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R /F49 1358 0 R /F61 1466 0 R /F64 1485 0 R >> /XObject << /Im2 1455 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1960 0 obj << /Length 3696 /Filter /FlateDecode >> stream xÚµZKsÛF¾ëWèHU™“y˜Ú““ȉSÇk+»‡$ˆ„D¬A€!)ʯßîé€@)[[[.™=3yôtýÔ¥„êÒ%"ñÚ_¦Þ '•»Üì/äå=Œ}w¡˜g™Öc®¯o.¾zg²K/|¢“Ë›»Ñ\™Y¦.o¶¿¬¡ÅÌ WßüôáÝûï~þôö*µ«›÷?}¸Zk'WïÞÿýš¨ï>½ýñÇ·Ÿ®Ö*sjõÍ÷o?Þ\¢¡„çøúý‡o©ÇÓÏ™I?]¿»þtýá›ë«ßn~¸¸¾Î2>¯’òûÅ/¿ÉË-û‡ )ŒÏÜå#4¤PÞëËý…uF8kLì©.>_üc˜p4]”Ÿ’B›D/Pë‘3%œ÷î2u^$F› À¢ìvÅŽeÍê„ÊVë?›ºxƒ]vèz(‹Ç+¯W¡Û­šð„^ÝWÍm^UOWJ©ÑÈlu³+Ú‚&l]ÙÔ-5ò0<äU¹%ò®áåÛ*àá¼ÞÒm×ßRnªååyج6U¾?à%€$ÖJ ïœÇ‚CÑU}þé-´úý´;꤉†ÑîøDÍ®Ü-“ ÿÆÛC±)•Rü,œ¥/Z1lËTº,lã22…CVUóXÖ÷ØLVÛâ.ï«®¥ÁüpD“Àµ©Ñµ)ã„Í”‡¹qÊ}Y¯p8÷ÉOL.Z §­âŒ”´L[lšz 2|¾†ËDâœK伺„Ôq XÌëÙ2AkãœH­±ñvÈj•NZÞcQ|i¡­–¶e¥µ““ÃÛTâ…µYÆì7.,ž{¸òç+¥°’=É8à…•R)¤LRfWZúd¶5ð zvPñ 4”H•J.“Ì —9cäÄ´s‘«¸‚oëvÝoë¶ü³˜¯›YªüËË\ 룴™3zºÏEPuÀ`EÆq¹ï÷Ô›oŠcW¶hQؾþöÃg¢~þö#ñßöwh¢wˆU8ލ²¦ßÛ§.„ÕY0Z| ®¢ ¦ÝT“õOÏHÝ‘ªZ+´3éGùæKؼN‰MQ>Ó‡‚“f-°ã¾Û5Dz˻20´ÅŽÆÏãNO󴀯‚ž sZ¡?¶Ã ¿÷űDxY›Ì¯þ‰ ÌØ ƒ=DŸð&tJ/Â"Ê%q+ KjhœÛMߵ嶠F·+¹û˜×÷¡3Y=–UE·ÌÖ–UQwa¡•oÿÝ·]¸Jœ¢‰S1s]ðFÛŽ:ÂêD>‚3 × tÙ‘±¬—‡p„atÃD–l~xÌó¸¬}¶êÛ>¯LYöyÛÔ4D~ ˆ¶è:DîhÖ©*1ŒÏìlŽO©PÖFÔwÓç´|ÝÔëÓy ?žÈpŸÜÌÌGòº}$=óÙÀvÈ[†a…ñH"ýT|ÝŽÔ·¿Gw˜úÕ-µ¿5µÑË‘XÁË=ƒÙwyÇìU³ùBäÝ1¿ßƒaø±Ýx„ܯ‚0ÇÏÄÍC_°ögOÖ‰š½ Ð÷|k]ˆa‚›Îk¢Ð€a¦ixú_;8éókÕ™p)[tOu¾/¶ ·iŒ89Ù )Ôh­“ņ ׫£eï›® n +Ñ/úNd^øÈ€Š“‰Hj@Œ1Ì GÑBH€'Ïy3dÐȳ;u‘`׉e¸sòmÙÌ6 à ÛYX}^¿Ù-]SϦ“l°÷8Štæfùæ3&¢´Al/» Ô3ƒÍÀGa’€[K„‚BgÒ¾v—ତ‰‘#.€!ù}€ ¶ E‡Š;5ªðæÄùÊá0¨Çá4¼W×]_½aóĈ-³zjž¨Fù¸8|\èéò`¢Hâ5âoñ¨.yMdÝñ3¬pÞ6AlÀX7Ì×ö‡Csäú_A oïºøTQR }——UÏB=}Ë97QvæÚGÑ úÕñÑ0Eª=‰táFS'¼Ì^¿Pð‰fz¡0逰¸XðMÐ9Ü£\ { è=w}×GÏŠ›f¿ïër“¯éî4d_*³fæh)ï1ÚF}Šoebý˜y‚J þ¨Ñlaæ˜P-?±B&Îü…ókãgç·°p¸ òš¶¯ÇØzâ6‘½ ® Ìá”]Ÿã)©‰pž&ƒósUÞȵ@ä$Я/Yÿ÷Íc1ÂDëêøKP‚°Áû ý-ýž,‹Ú${¤è˜HEX ::èg‚§8á©Íæ ‡ñ”°mÉqŸŠÄ¾v7ëÈ6㾕܇&KŽ‘¸ÅȰz¢¡Š<ã=mYÎŽ ÃZ"*ÛÁô(¼„6ûª7”n÷uW†]¨Ú^©UÝÒ4 è¾ä™|ÏX<`1»‚ã’wõ”=ý«1$4‰O˜;vì•6;P'Ò;y¦–fêß)ÌË’Q ˜¹©”`0J È>¤ HÝ>-z+|6ìæ…È ³ƒÏ9Åå0-«·4"ÝJÙ¤‚0bèÊœ·AœÐWódñǦ(¶ËQ©Ö°K%õXœâHi®ÔÓëzAúƃ1ë a0žÙ€UTØKr‡Ô…#Q/!}JGã®D¡{³kÚàÁRÆè˱BB]¾ØWÓïûö+ø/¡qptù¡í«œÒ `À¨ˆ ¼ãÉ !Jhóûp\Ðß[nÃF:¢-Hw¡#Z9ìÊyˆà0Jb±ñãÍÏŸâ¨PÑäƱ°—])…·é_âÆ<ÔÀ/±Î' È4jû̪É[/g/brú Á L¥‚¡éä ¹·%úñœ‡o¾ùËy80jÅæÌ ôã„íŒưKgö?<æ:ï‡.²@Àè#î°*Ö`À{P¦¹;6òÝÔ¾¼‰kawl¥Ð`²ÏÃ{¯6¸Ú@[#š÷hT?üÅWwcÎ66œd€ŸPZxtãMÒàñþ’ˆO£S ü¯œêù¼¤lÎbaG‰§ÿl?™„˜Ä˜—e;p½¶‹g³l´ÄFÏF¥ •€3ƒƒ…ÙÉ•Ad/‡¿+þèÌ¢,o¥‰‰kOV'BÙduîÊ -¬%œ¶1óGŸÖöŽmy–# ‚”;ã@£?L²¶:b$W¿÷E2¾äEÞàQ¡o´ÞƒÉÆF§² g$%\æ£Ã:æ ‚R©ðFg£´Ðú]IškãÖ@ÁéÝ9’¤÷a<%ä^XÚ( úÔ+·” “ïOi,Ò=¸<šÅ`’”Y~çe¹Hh±*PGÎ`O·ü×{ç9£L„óé¤NºŽ•`;³”jÓì `Ú €/E"µ¢‚¦z3TÂï¶ß¢ZLµ3,‘¼^·7„yÃ$6WƒßCÌj¨ô>d‘zÜ…¨«¶ôCH¥0MzÃ8bÚ–ƒÄ«©y²ˆ|¼Ä’híE&‡Ðêœ$BëAû‚ûƒ)«&ßÛÅ·ä‚Ù¡ òB>cd¢†¨î‰¦mö%ï¹mö|Þ6pžT+i6«qnvÅæKx‹`¢‘¾!cí«-õ†¬C‡KP:wSV¬I z$k ƒ¬µ9©éT€PÂòÙ«Tz0qº—ðq $Ü<ý!‡0hÓc-”ŸKÕXÊ¡Îκ‘À²ºgIæÇ¼ñûï…u‰›%C •ÛBõ ú$TØîâ·5ËÈ©^„/-…±*{~þ4Så¼f2§V~ØÃp!–•ÿìvTÇÒÒý×ûáMô-S·¼ôµ°;p)c†pß%‰^úÎÇûU›ï™ â§ UñPTÔ^wùá­">1ùŽÇ{:©?‡Ê§ÂIi^73ŸÊˆH›¦Æî!å2’÷,]¸PŒÕÛªmÞ,º)/”Ó'{=, ÖKŸÎ;¬ÁgžT GÎèYåÐ…±¹ä´€ê!±ˆAñ¾Ø7ñ#©‡2Þ =@ðþ&äÝ.¾Œ“…¢Y ÄÃeÿâëYNý±QD±§d>|cÓñÀ™»of´9}Ï´@Ï?iÒB&v$LZ!¯N`Ñ!6I¹$‹£›P¡Ä·q5&Ëí¶àþ†sbÇ Çø0?kœ~2þþB]ÀÔ¼-ùÍÕ437U¿¥whøfçÌGdi:hï_”„+2‰º<¾mNßjð[¡uÂi5øL¤Qp¦TdZ|a Àð}Ñ5Hba'Œ ˜3rÃe´G,E:@ëÄÏ㙹¥ò›k´Ô3_yâ‡yfñ{)øã¹ÿç/@OŸÇÚD/ç³=á‘F_³ ˆzÍú£½Z+Ø”^eÉó,–?"}~¨ÿŠ;\endstream endobj 1959 0 obj << /Type /Page /Contents 1960 0 R /Resources 1958 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1952 0 R /Annots [ 1962 0 R ] >> endobj 1962 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [324.9335 220.4785 381.8296 232.5381] /Subtype /Link /A << /S /GoTo /D (zonefile_format) >> >> endobj 1961 0 obj << /D [1959 0 R /XYZ 56.6929 794.5015 null] >> endobj 1958 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1966 0 obj << /Length 3666 /Filter /FlateDecode >> stream xÚ¥]sÛ6òÝ¿Âo'ÏT<|`ûä¦IëN›´ŽïkÚ>ÐlñJ‘ªHÚqýíbˆ”);7xB`±vý†ø9ƒüÜêŒÉB›Bešq}¾Úž±ó{ûöŒœeDZޱ¾¾9ûû;iÏ‹¬ÈE~~s7ZËfÌZ~~³þeñæ»ËŸnÞ^_,…f‹<»Xêœ-¾¾zÿ A ú¼ùðþÝÕ·ÿ¸¾¼0jqsõá=¯ß¾{{ýöý›·Kn5‡ù"¬pb»«ÞRëÛë˼¼¾øíæû³·7‰—1¿œIdä³_~cçk`ûû3–ÉÂêóGè°Œ…8ßž)-3­¤ŒúìãÙÏiÁѨŸ:w~JÛL •Ÿ/¥ÊlkÌž2˘†S[]d¹2²às§±ð”·å§åÞ­†}WµÍrívýæ˜sn?‡ /ÿŒˆ„5C…QÁ­Êr¥ù”Œ®ï.–RêE¿qØPHYµ¶m†í­ÛS»½£oí\Ýr„í/¸]Dvâ‚eO­’FiÆÎí·Uß»u‹8ÍSØ¥qxÀÐ[È!Ï ­…§·¯¶°Ž(äâqSÕ¾©Û?T«ª¹§‘’ #’œ?·ºàœ/@(•â‹k×µõÃt¦\4å6¬¼-ŸD‹ý1T‘­Ûö÷4wØðÙH!òĦ̔ë5-×u_®²ÈÔjCͪ¡o?ìC눆n =° ²iá6÷Ø1ž¿z±pýê«°ø]X/ñž±ÝÞE Öa«U·ösŸVέ»)?d9úMÕ‘.?”õàw…6íã ]ˆoÆ©=ÊGSzÁ~Ù¬ÇÓñ8æG0RZ/þù-ÊåÕoâ~kwWu?]ÞdÏ LÐbÐr0‚F½¬êc¬Óªž°ž«:²\¹î™²Û<³:7/“‘°fè˜({Á3 6aBéºy¸P¶¤ëM2m/€PÁu”=Ý€#ñ~ŒÁ¤&и ëv® CQM¡yPS¯ßHÃ:Õ°\K ‚&ª«[\ÝÑÀ¶MÖ% y±s°;\I|B)E¬W§·òÍ*¬4J¿r³S„׋B‰2¹œS’‘´J&?'‚™Xô-ѰP ­ ìÂ_j®ÚmYù}¡Ó h8µ _…P€‚Ñ€ ÆõÏFd8h|óþ#ázÛ¶'ðŸhiJ8Û³æ>¹í.¨ÝÍßFSÕ°®À ”hVðø«Z«O«­€GØ¿¬¶#¬Ô6b!`D«»'pÍ5H÷±¶*–²/ïž°f¶Ÿh«ÒY!X>ÝŸNĘQ€¢ÕJr jÕ6kï;¬ÝëKC`¼½?€:R|hyµ†aâ`[p?å½Wj¹k÷.éƒ7ŽWd‹1AñŠ S‘+XJàÁ`Ä4…_ÑÖÿÊ4Óð§n >KTdF(1bZðœe]úå¨ òþÃÍÕ»ÿP{Äúä©ýfMHÏŽÇe‘Ãn*n@YO‚[×ÑÝz!8)mfŒ6ÀÒ ®*ko⟖ž\š2¾le¡ 3NеÎyÆÑ„¿(Öc¬Ób°’7êÊ¥û´Æ›~ÙUºÞ¨x™Œ„5CÇŒ7SBè’‹|ä„ sýñfé#0‰¦›…À@·UßP>VþZ‹àŠà[®V\û[Äñ×XB”j]ö˱3SS ¢ŸóÌy†&À~ZRxÓQûàd #5~rè+VäÔBjÃbžq„%=ÂΟŽ$Žz¨,Œ”»UܬîÂ-ßkÖcDåÃD ÒŸ Kä–@¦3](þŠް^Àˆ…»îöîBÑçùŽɘâåÖÌÖ¡ò0&{ÿ‹îŸQ¬ÏTŠ@‚BHÁ‚ƒ˜`M@²èuËÕ&A~J‚ÆÀ}´ ÊöAYzêM»ïëhПÛÈ2.˜ ã÷õŒ‘2cݬUØ¢îBV° ¤lÂÞž`2×JfVÉb*ñ#wÍLœ:4ô@´wØÞš3³?\mÄ Ì]}pS\/\Ó {rB~1¯£,FŸòGv¨˧ŽÀ›24ˆ'lºGÚ `eU—·µ;é8üQ©©ýÉ´–ÑHÅïèL5ƒ”ÓˆhÍwnU¡óîÁ† QXë¨~_Ýß»=Q8zsó5¼u DÏ2€¢x@snÈ“à!Þ)Û˜Œ¢QBjÂô(¤€ RSþ3e.…SÝÞÕåÊ}‰¶ÎF«'r/õð‰'Í íE£\ ›ô› ~ÝÒ@“Ø„Fdš^äáëšU;4=Y2¯$\G!ybö shWà´aEF‚î#ÀåLðú‘”»µÏçÍØN#ütMÔ'Ú‹<pQŒª8ÀÃÄ6tá¤`e¼KXN‡–HÛ€¨7³óg|ÔŒUî*´ÛµÏ‹cee=¬(ÑD|9øL(Ìëz:a€–)± b{4õàk°7ò5Ø]•CG‘:ÖÑþ&à»®:ÔÆµ§EÇÈM'ß6Ã߈6ic!Ž<ÒÜ\d&Oš+æT¢N“£)ˆ¶!(S\NMÃ%–¥À˜´;È:@.š²&Ý µÃE[rœLO€ŒÖ GPó]]ÝW·U]õO1›òRö%¡\Øc á¦ëúÀ"Ûqµ×"²fö¾BÚf,>$…Ž‘£?8Ü$è!ÑVöÁ¼ÃÉåV™©úÉ3’®ÏˆqtÐü“s4â¹m0’Æhpoþj7YAL$‡â(ilL!â,p„Or#Û¡ëh ýÚ•q¨«>ÍjÎAÍ0‰n‚Fʤ‘!Ãõƒa¸ûWÔò•1üöáÛ5ëgÝ43Ôrõº›.¸ŒXQõåXɱð¸þ/±=ÚyØ=’8zã&cþUȉn-…â íÊåà“ó}UÏŒ‚ð×D=+>KÏŽÎcÉ!Î2–ƒ’EÆ9£¢>ðþ.±Å×CU÷KÃû¼,DHX³õ5qböœ¸tˆí´‘‡4BÚÃZÒòè\ªµW[m·oãêÝÝP"„-÷MÛõÕŠ'D  ßÐRÃý†f”O…qù"8ÀnoØ y%" Íz¾Šîà ;7¬Ûeß³\ûâÎ\0#A³uº«Ûª™;8 aÀ²ÈÐ.} ŽÎL$ûæ»ËgÄR†µkU—zCš»q]à"²,í¸æÜ•ûžZô^`ý)BwtbÐ{¨Ü# £Kêœ;õ$ Æ™ÁÈŸÆö÷çÔ¸ž{ã?Ïž­JÅÒUA¯XB?/)¸I.&äÌÖ+T<_ (>AÈ££Ÿ¹E%2Åùg\£Q,BTŠ«û¼Q Á]ù: BéöHXŨD‡ÐpiŸA¡à µ’…ݯÞÏÐÇÁZ%’ñ ÿØv=-}_··ÞoL}HÞ¥™µz¦öt?ì£. I®ßL…ð"6C¤ÍA»òxŒàµÛGªçÌÙDÉD+–"Ç7–xg"˜{ܺÜíÐÖcÓ×`Š¡ñG!eXâvè #Ø,1.2tl+ ë‰p°B¶¯Ök×|9wä–gàwcÌÊ~³æ"7ºH¬Ì˜w¥9¤üâ(¢Hïs²Çc£Ë(“™âÓÌ,W¢˜œvã—§L¿…LGé(¿‡È݇ ÂŒÎõ¤²XÐbììòL™âp&sbä(]­°ù ¨­åugé‹Û'$ùPŸ3‰V«‚N!OÎÇ9ÂéÎd؅ٻàW üS¿0Í¦Êø~"4_<µ5KãóÛS§'3M;_P{èã¡fµ ¡·™!ÙÆ>U_ùbžùh^òóeV«˜zݸqˆ&OÄSàÇ¡MhÒ hÌ5GgV†ðÃ}ÚÕÕª u㸣t]Ÿ6sœ áö3,1çE$öPцàróî¨H½ª+»“Å:ÜæúåbÝët±.aùStI½'¾Ã0¡^Þ8aÍì<µúBGˆA&[‡dÁ&HM"4ÅŽØÞ´C½kɮݽz¨Jj„O¬A˜ðÒ=^Ó¿Ú?¹ É´L1R ';{üÉ Ó)ä÷µÜåi7~¡UÉÝüûfÎASê±yƒ, ¬>~p9é{â™”àD’\ô¾…64n:Þw"E̽s†^º2ì¤XÚ>H(’÷ƒV¸G£pC#óÅGL¹ïž‚š›È2 kŽ®"ì~;rÄ$âa™O]W°nAӦ娩¦'^—Ok¡*òWmÆX/haÄBZ7EÙœ–Ì‹LB˜ÿâÆifãib¡2Q¨£I óü@‚ïõœ´ÛQ s3ÕB#-Ì©¢˜*yø­ÁxÍSZÁŒ2yŒ"A§ÔÎ[æS%ÄMæ•Ò4Ð&«åT>Ka®>©x’áÓ®ü¿Ïb-Í«DAó:‚ûÒÆê’_ ‚)MÃø#,ÁŒp½€OPâì|”Ekü%=ŽÙLYuôRÐþ‡9Ê{=ü˜È,î]IÂ(;”ãnhVñÍŸÅ‚†ÂZpµ-½8`gØïÚ΋dÂÏrø Š2DÁ×G,ø“%ˆƒÃË6@G¿¦‚uæ~€…o Åâ>¤ø;êú=á[6O+ª8±"œ‹˜°á‰0Vý@¡8áã3Exð(0°ÚS+™ _ô}Ù¼l +ô‘ŒÓ:hß¾šs8à=u ò“]£§SìÈMü5k,”ÔþŒrÆä°@ÿå_k’xe °bÞxIº¬(L$ ™´æbÉ1þõjƆåOê˜) !¦¶ÂÌpõ?•mÿendstream endobj 1965 0 obj << /Type /Page /Contents 1966 0 R /Resources 1964 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1952 0 R /Annots [ 1969 0 R ] >> endobj 1969 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [84.0431 276.105 145.9475 288.1647] /Subtype /Link /A << /S /GoTo /D (view_statement_grammar) >> >> endobj 1967 0 obj << /D [1965 0 R /XYZ 85.0394 794.5015 null] >> endobj 558 0 obj << /D [1965 0 R /XYZ 85.0394 348.3088 null] >> endobj 1968 0 obj << /D [1965 0 R /XYZ 85.0394 323.366 null] >> endobj 1964 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F40 1265 0 R /F49 1358 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1973 0 obj << /Length 2339 /Filter /FlateDecode >> stream xÚ¥š]sÛ¸†ïý+tWj&â_$Ñ^yc;ÕÎFImµ³ÓÍ^0s"“Z‘²ëþúð"DÃ@8‚àËóâÁǨ˜ÌøÌD§’ÊY&y,"f›Ç‹dö ž}¸ Z³0¢…­úy}ñÓ Ëg2–)Mgë{+V'yNfëíïQÓx’èý§ÕÍòÃ?o/çÖËO«ù‚Š$ºYþz¥·—?^ÞÎ$$zÿ÷ËÏëë[|”ê?/WWX#ñòFÐÛë›ëÛëÕûëùë_.®×'›—$LüyñûÉl Ø¿\$1“¹˜=ÃM)éìñ‚  Θ©Ù]Ü]üãÐzÚ¿êê?.òXPžÎŒÇ9ø»{™Ä! Ê„ŒSFÙ©—)qõ²Q©^nËÃSy˜“ܪÂ,zè@ð¨mú!ª¯§àê®ÄàJòß>x_«ÆáîÓ%Öµ¶ºÃ«ÞšþºÕM½{QCƒ•Ò~°ZmX oîUz¹uE§[‰ÛJEɸبL£¯%^13ôá·X³k6F&°åªV§(U4鮿9m{P®›îG2(,??¥Xê§,Š-\|¦â0¥•?ì4ßêr«–šBË;RUÇ@Ó1íÎ:ôfl¼8E‚Ò®iö_‹Íw¼;o–ªè»Îýê±þ^7Ïõ«7ãSsà „Ð³TE)Ó;–*]§ÒÞôk®Û–ÜcU—x[Ý«+ïÏŸÔNjêNåj‡öÅö+ÊÿTm×b¹ Kßé£zÒ/ªŽÇ©k’ Å­Ë2…±|Æe±]¨ôçêoKƒgfè”m g¿C¡¶6}¶»T÷”0#Aa£!ºÒhñZ;ƒF†’Ù60«ö¯méìýµ½Íñ€µ~eWµº¤Ž3/=ªö¯o}Å çXþ¯V[ÕÑÀÖh½|ȤV,Õê/ l”#Ó â‘œúMèµéÙfšÃ†/¥87%I¼\-.¯®nãËÛÏsI£Ë·À¹TgsIüà¶êmð“*î5=¿2u‚Ÿ™öçúãð|{’”à-•Þ¨‚ð>Ó~lꆷMI6 >…–'Œà-•Þ¨‚ð>Ó~lꆷM!SL‚ï?„“À¯T¶ÊoTAxŸé?6uÃÛ¦ðÅ> Žß"˲¼¥òÀUÞg:ÀMÝð¶)M¦Á'Y,RÈô¶ÊoTAxŸé?6uÃÛ¦ð½7žå2V'F/»%z݈Bä>ÇøØÑÉm;§ë$lhµ`2Äm©<àF$÷™ècS7»mJÙ4xõ»2MyÞVyà*ï3àǦnxÛ”òiðLà"~xKå7ª ¼Ït€›ºámSH{“àáD ’$çm•Þ¨‚ð>Ó~lꆷMé´³•2æyÈó¶êmø“*ï5=Á¿2uŸ™Òig; Ax˜õ–ȃ®EArã>rts[ŽtÚ©Ž¦,æ) äy[å7ª ¹Ït@›ºÙmS:íTG¹ˆ9—,o©<ðF„÷™ðcS7¼mʦê(,ÎÒÐŒ·Tx£ ÂûLø±©Þ6eÓNu4LAY ÏÛ*¼Qá}¦üØÔ o›’½üqz"!_$÷ÓÛª·éOª½×ôDÿÊÔIfšª¿&øñŸoHÆÔ_ Ø‘]‹‚äÇ|äèæ¶S1 [ˆ˜å¡[å7ª ¹Ït@›ºÙmÓ4ϲ˜e4èm•Þ¨‚ð>Ó~lꆷMÓl<‘12èm•Þ¨‚ð>Ó~lꆷMUª›Ÿ˜ñ4 À[*¼Qá}¦üØÔ o›¦r|Ù‚±@ª³Do£QˆÜçx;:¹mÇ,™„ ™‘ÑÀÏóƒæmh­ 1{ìNÈ#;'±e-˜ ¼ê¯à-€ÿõ¿xþßlgÿº‰8#]Ú¤h¬?¬˜->ó¹Jú”FyþŠ ”¥Ôõ?H§9Kendstream endobj 1972 0 obj << /Type /Page /Contents 1973 0 R /Resources 1971 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1952 0 R >> endobj 1974 0 obj << /D [1972 0 R /XYZ 56.6929 794.5015 null] >> endobj 562 0 obj << /D [1972 0 R /XYZ 56.6929 684.304 null] >> endobj 1975 0 obj << /D [1972 0 R /XYZ 56.6929 656.7743 null] >> endobj 1971 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F14 1060 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1978 0 obj << /Length 1335 /Filter /FlateDecode >> stream xÚ¥šÍrÛ6F÷z .¥…P\üc©Ø²«L㸪²J²j¦Ý4‹®úú…"ƒú÷Óñx¬ÈG<>„¼"E“._4%¯´ÍnŠÙ)¯ÉO¿_ééÏò»ç½1Û m‘zwZýôdÓ”U&L§?`[Ié”h:}û¼~øy÷zÚ7[ãõ:¨ÍÖ½~wxy¼<“/?>¾<ž?w›èÖ§ÃÇ—ËÓÇýÓþ¸yØo¶”<•×›·-,¼àéðËþòèù¸ûðawÜ|=½_íOs ö’¶ç¿WŸ¿êé[É~¿ÒÊæä§Ê?´¢œÍô}å¼UÞY[ŸùkõÛê×yƒðÛ/íí¿™ÙZ§R(Ûà÷²Ï*Xcç½Lör.“-•:ïå/šb›JÚ•¹8áöî¬3u¯5´¤ËcnµÑ”¨Õáe»{|<ªÝñu“Íz·¸Ó)tòbò+%çsVÈoµý|ÔF;–olù‘ƒ“_)9Ÿ³B~«íç£6º±üâJ”¤Å“_)9Ÿ³B~«íç£6ú¡üB9añ#µœ?Sb>k½æßi»ù7ÚÆòCR&zდ_)9Ÿ³B~«íç£6Ʊ|¯•ÖNXüH1ù•’ó9+ä·Ú~>jcË·¤¢5IȊɯ”œÏY!¿ÕöóQóX>Yå‚4]!ÅäWJÎç¬ßjûù¨Mz(ßçr¨Ìšø|¤–ógJÌg­×ü;m7ÿF›h,¿*3%añ#ÅäWJÎç¬ßjûù¨McSŸ÷I•òbò+%çsVÈoµý|Ô¦±©Ï»òÎ iñÅäWJÎç¬ßjûù¨McSŸ7çÕR\|>PL~¥ä|Î ù­¶ŸÚ46õymU²VZü@1ù•’ó9+ä·Ú~>jÓØÔçÊ„© åø ‰íœòšÞ:»åèLcóž Q™¬…e“^)¹³B|«í×£6Í{Îe¥)[!(&¿Rr>g…üVÛÏGm›÷œÕ*:á„ÿÉíŒÒg¿œylÒsd”‹A¸Ä“^)¹³B|«í×£6Mzå[í…eÔrþL‰ù¬õš§íæßhóؤg£WÙZáRL~¥ä|Î ù­¶ŸÚ<6éYU8oϊɯ”œÏY!¿ÕöóQ›Ç&½²×”Í$œì‘bò+%çsVÈoµý|Ôæ±IÏšr¬ ,-~ ˜üJÉùœò[m?µylÒ³Ú¨ä’p‰)&¿Rr>g…üVÛÏGm›÷Ly[äc?RËù3%æ³Ökþ¶›£Ícóž AYí…‰)&¿Rr>g…üVÛÏGm›÷ŒKå?RL~¥ä|Î ù­¶ŸÚsûP¿É*+\ã@Šé¯”ÜÏY¡¿ÕöûQKzlî3DÊe’–?PL¥ä~Î ý­¶ßZÒcƒ_y›¤ŒÑÂU¤–ûgJìg­×þ;m·ÿFKzlò£Xdeï ý@1ý•’û9+ô·Ú~?jÏ/ê÷A……«H1ý•’û9+ô·Ú~?jIÍ~d“r:Hë(¦¿Rr?g…þVÛïG-é±áL9_XáôSÿÉñŒÚg?œ¤Çæ¾ó™"+­| ˜öJÉñœê[m?µ¤Ç¿d•ÏF¸àÐr}…ÄxNymoÝttžŸ»£¯Êû%é~~e¸»ù?˜ÿp/чwòo„ ÷ñg!‘¼Â¡Îcëü å›TöÞüÿOÔÁu¨lZúLŽ-Ǩdr¬Ôå2í¦î½1ø ÃR¨ìöÕµQ¾ñ|2±Sõ/:ôi9endstream endobj 1977 0 obj << /Type /Page /Contents 1978 0 R /Resources 1976 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1952 0 R >> endobj 1979 0 obj << /D [1977 0 R /XYZ 85.0394 794.5015 null] >> endobj 1976 0 obj << /Font << /F38 1122 0 R /F14 1060 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1982 0 obj << /Length 1881 /Filter /FlateDecode >> stream xÚ½š]oÛ6†ïý+Œ^É@ÍòC”ÄíÊiœÎÅšfivÕöB±•Æ€#»–“,ûõ#MRü}=åir3û|9SŽ“‹ÙŸSÝúp=ùôir=“‚“äý“«›éµ^•™1Îf—çºGè_G½ž^L¯§—ï§£ï7Ó›ÖúÌ”ÈÏÁ×ïx¸Ú1Qðá³\ÀˆA‡ƒ”3ÄSÆlÏjðeðW; X»ßÔW¿63f)*$?Re.PÆ(k«LRPåœÈ•™4°)Uåo˜ä]Õ\ŽG :„ý‚ÚÐk(¥ZÄ…à‡PBˆ¬!F³ËñäüüM®¯F‚&“£5OåÔsšGìA*`oSQûÔÙw¡~{%„ö³§ å„Åö=Hìm*j‚:û.Ôo¡„°~ö˜£œ³,bR{›ŠÚ‡ Î¾ õÛC(!i/û¬È‘¼â„åA踻 ÅÔCÄÖ¼KôŠC"!¼Ÿw&PÁÒÈ]¦æ6UA{ê—‡PB²~öœ "OEĤö6µA}ê·‡PBò~öŒ!A8‹ØƒTÀÞ¦¢ö!¨³ïBýöJHÑÏ^ž)‚ó"bR{›ŠÚ‡ Î¾ õÛC(!¢—=9rİ=L·oS1û ´µõÚ@ Åýì Œ0Ë"Ï90°·©¨}êì»P¿=„Úï)gá<'{ ØÛTÔ>uö]¨ßB í÷”ÇSùd@òȦö6µA}ê·‡PBû=åq*ﱋÜM(ª :óÑ/ˆ„ö{¾ãXÞDyÀƒ©€¹MEÕCPçÞ…úå!”Ð~Oy©Àˆ²"²Ûaê¸}›ŠÙ¡­ý+¨×þJh¿§¼4§ˆæ"òœS{›ŠÚ‡ Î¾ õÛC(¡ýžòRž"FDä^S{›ŠÚ‡ Î¾ õÛCho–!–áÈ]¦Þ6õAwê÷†Pµ×O6—OÂ)Æ‘7y˜ ˜ÛTÔ<uæ]¨ßB©ÜýD¾äl/Ï4ív ¸›PT=@tæ¢_å#޼àÓ“½YAQZľÃÔqó6SB[÷WP¯üT]áä»­¼ã^€,Eœ’ÈËßÉ{f§û§’OÆ‘ÛLüm*ê‚:ÿ.Ôï¡”sN®-P†iäQ¦U°©hBPW….Ô_•oy¿ôov•Å+F0ÊÒØgo˜ Ț¢ A]źPÅ ”ü£ò²œ±Oå0u¼bm*V± ´­Ø+¨·bСsu³ÙûÓÓ*§(§±»,L*`SÑ „ ®]¨¿zŽ.”íi沑g±æ00·©¨yêÌ»P¿9„hÚǨÀ1u ˜›PT<@tÞ¢_E?kŠQ!_B"Ú 𶩨xêÌ»P¿:„Nú¹cŠŠ"ö½¦î6uA{êw‡Ð³£îr¸ œeÃ1É‘àB_§›ÝËhL Oþ]×U£šiRnG¤H*ÝßT»]y»2KåNGv÷¦ãiY=ëÖªzªVf€z¡ûÖõÊ _n6º)·]»M“»Ó«æ«²1]³K¤çËFñ:QyfÌÛ+S,‰ú}í3S`Èê… k¶Þ¹t«Üu‚FHMC ÌÝz«Õ?åÃfUý¦lÞ]¤ôðtÊQwz$Hª¿Š˜ÉŒ÷åkl†qò½ù]qprŒ}cÌTDfTÜráqD’fYÿÐKZCe Ú–²c[Ö?*Óž«}²_»Ðöpy«v_îHÍýúqe2åJgÊ…:NOîË'Ó+ä˜é°‡eÌÏs€ÙªíOõT㱩äQ%ß>’Y­{6Ûr¾[Î+½´»_šMä©Z•[³ NVõ»Vû\5n÷ys誎yÙ˜Öórw¯[eý¢[?å´ídn«½N,*HàÇœ–õݶlvÛQ‘<Îwí>Ëåþª¶ªXzAZ²Q—•é[Öú·º±ÛläŽ.çU£N±œ%_Öº_Ïnt'«c7/M«)çÛý‰<_–+Ï$ž+8¿ºªûCC±ö]œnÍÙ²¨6«õ‹=1÷Hu.Þ—u½¿¦Â3KUôÅœZëÒlR>—¦\ÖàVÇÊ(Wtôý‰#õ—cž›•ü1{ê—ÿˆ ~§F¬(޼uæ´¿é¹?ÈCòE‰¯ÒјÈIÑDàWND}gϨGê?¹S¹"endstream endobj 1981 0 obj << /Type /Page /Contents 1982 0 R /Resources 1980 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1984 0 R >> endobj 1983 0 obj << /D [1981 0 R /XYZ 56.6929 794.5015 null] >> endobj 1980 0 obj << /Font << /F38 1122 0 R /F14 1060 0 R /F22 1037 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1987 0 obj << /Length 3242 /Filter /FlateDecode >> stream xÚ¥ZKsã6¾ûWè¶RÕ€$Ž“Œ'q*ëÉzœÊ!ɦ(›µ©ˆ”=ίßntƒ™–'›šª!  Ñýõ ²ZHø§™R;³HV*»(vrqsß_(¦‰Q4¦úööâ›:[8á’8YÜnF{eBf™ZÜ®[~÷ÃûŸo/oVQlå2«È&rùíÕõqôùîÓõÇ«ï¹y¿JÍòöêÓ5 ß\~¼¼¹¼þîr©Ì*Xó¯,øxõÓ%µ¾¿yÿï¿¿YýqûãÅåm—ñ}•Ôx‘?/~ûC.Öpí/¤Ð.³‹'èH¡œ‹» cµ°Fë0²½ø|ñŸ~ÃѬ_:'¿ž&2™ˆìñ5ǪX8gÍü±´›¦æÌ^´NÂ^Ü +¦[ êM’X¤ÔÇ ¥„³6Fý:)R³©ÖBâ¨÷ì °‰QH§¤°:Æ=ŧU”¨å-ü//OÕ[”G’e© ^ü¹PBç4ÑŒÚþ¦ƒüÀ7W»xñ¡û,FW ûF£ý5¬ŠS!Q ©LEf%]éö¡¥ÙòPæ[l¹å>?”uG£myXEZ.W±]–‡–F7+jDÞ=”-ïñ×JÙeS—LÖ>4Ç효ÖU›ß­b¹Ü2m¾ÝR£Üí»g" ëiâX¯Ë5á &¡W0ßsšÙñZèá8ì™zÓ[ !–NÌòc^ã, l5M7·6y‡S)¬«Z" _º[f–þÆÇjÛEUMSá¶#Ž[bhr?ÅÊ©X”OU/®z*GàzÇ­&h²;â•ì²^aåá°R˜k§ôë²ÜAWõ pjʲço fãR‘èD/ÆvôÏL€u‰[Dƒ{ùgŽ#2Âe \QlD'ñ¼Ã—`àÀ”èTØL›Á#¨‡ßS¡†¼:#Ç#HðDBÊ‘)“,Æû¾8½§š9>›¯q"uÖMÏÿ¼/‹j€ÒÚ-ŸòŽZÌo×ù®äy"låû}™ó<ª¿^娔ÌCu¹¦‘ÏŸÞ§ŠÆyrÓðF mlþ…°ÆàºÚxhGÚ‰ œÛá5Y,„0tø¶x£ß¥ŒËõ;Æê¾E Üÿ_¼€î‡-6hÝñȱ-×/ôm!*ºØØó S½ŠžjEÑÔ]^t/QáD¿u|O5sþÖˆXž2У}¡NàȳØ`˜ÅcØ‹½¢9NyX S,prÓðF½Ç3=,Œ2=,þqhž8ö¿‹ßc0oüïÿƒ›¼ƒÕªþÎzímù i"œ4æ<=Õ ,dJd™M§\\ÒÉ^^%ðõÁ8 æAZAQl_¨( ñâ[[—›ü¸íéóxNÚç=üig„+Èœ(E9#ìÕa*¼&_)„þRØVÄF&çyè©f˜˜ [‚*7åâC/X­À‚ÖÕcµ>údúA¾Ðìå+ ÉÆFòÕ6XŒòE":`í×ê èxÙì»ÙÔÔ-òšÜQâ¥ÀnjÝÔÌFFEêÛÕ> £«vÈ%å¼c `8u2!i N=%_ŽõŠJ„Ê ~‘R.߯×U匯ÏeуXåÅCUßê°9ä@1ì¡~HPµ¤j´6bo‡“lW¾Ã¤3˶!’° W{y•AAgš³öÜ/Ÿá%†˜•¦ŽÉx¹g¨¦Sªº+ÌsB]CCÕnïuØ<òUº@Aªm÷MÝòdbò£).VFH ©ËDs»¼.JJš› :׾̄‡èpÙòWò0‡²xôÚ€¡^|¸¢`mø¤l©ÉæÌ‰îèú„È!íq0ç=±øãšCÇn.Ïõ™hœr¬ÆX×GÌÂ$†1Jû¡Ca%p@ÄyÝ>•QVÒð]¹mž€å'Òåݱ£ v«'&3$k}jÒ8B&,·ha÷µ÷¼°c·}^)¥|M*íòŠÏ"Ïn±Èíªâ¸Í@7cw„AÜЯ™ÄŸÔv@‘d6@ÆHœíº!¾©i|›‡d´94»è5¿£¤‰Ñ!Á]gÂZ,å‚oª›¹m¬°6»/ílŸÀïàòkïï ämEòqAŒ@YDì…ä¼%l½Ìrö @Ýl欇—¸ôM«¡–!4³GqÖ{ª "&2¶S3 ¥ºìHó“$¤'!UíQ0 ÝòØ:ïòYp~¢Ä->Vͱ¥&nëG0öü>LÏ Ii)œ‰õWD¡XËx…`K¶DhUü%]ýy¬Ø-Ñèîèc%¶š!»Äýgš!{÷›2ãØ=ÏÙš/×Ë"R‰*”^-fODTè¡®¶/bLM­3éÊ a†@k·û„C#ÎþqJ{„Œ›@™PÜôDþò~þò~ø¾ 2Æws>©ëµ0ÑV"¬SñW(+±Š©†4À¿¯!]ºã·áSïŽ_F_w' 2û̸)£zó„—$F}Ö‹(aiÏz% vd WüfLo–ŽópÙ7m[Ýõ/– ß©¥½ðBtÂf§Ö}ÜïCª²­vÕ‰‘÷¸µ'z÷6ªÞ|d½wÏáe`^ª±…ªNë$(-ÿ±dÛê¯9¹¦ŠR›ö¡»@d§_O§FIEû!Cƒ– ‘USô…þ®ªÉ>Í(þÓíÔg$–2&›&L>Ëàsûüeš"ÙÀ''¿®,¸üî!š3’æØÍT¤©Î¾®ÔÊúRëåFŸ«$Ä¿â¹ØVÅÜ>™°p&gÒ‘€ïI΄CôŒ)C¦ IÀ—ã´'y§§r»ŽÐz|hç:ÄOz… βžû=¹ÎÃǧN tŸ7¡èc½ü¡y*1ƒTÄ—ÉIlÉŽ3˜i~ñÞß`É lŸ8z+m7ìYruh9sš0^ýƇ “ÑlÑ8wã<AF¥NÈ:b§—-=Vºv&¡Î …ï}Õ€-nÜÿXeékà°lvZ>˜ÆîéÅe½-Û–ÝLø1½;³ofy‡,‰šÃš~&8Á¬É ¦ì“2|7hÐÇJ&®UJ5ŽJøw' ?´áè¯"A`ÑZ/&ðÁ‘Þ)*_qk›>Vi€ómØÌ©ž÷Œãp—Éõ1®n=äý:´ü{tU·ÔËéÓîr²¨tYwwd@|i‰=“cÈV•³ð¥ºÃï·%S"”¿æ`Pè¶ §põ7Þüé¡‚ÌaÉxÖIÆxjZ!‡™î!‡¡—·âa6¼ [nš-T¥ý~á ç¼ö¸Ûå!†¸ØìCáõÊ3ÁLàw-•Nÿž»~õ½W)X¢­:ÿÞ;¦zý½·§šÍs¦¿±d"I!…9{|O5sþ´dÒ˜¿eS®æ¬Þ …ïî$”gPøLêd Á×Cœ{»J™<Úµ÷í>Ôô áGdê<æ}%]µsºNþôèÞÎôÌ[zÎÔ#JŸWóˆèu-¢‘’‹m s}ù nõBßr ÙÚ96z¢—|L€-¥H ¡ž0Bò‡V±Í'%ÌŽƒªËéG€¡b„Q¨‘•51xß;pkš ‡M~9…ïO7¿ÐâM¾½Ç´áaGå þÍ$U'é:øçYE‹LšéÓæ¼T_h?Y¬ÂJˆ)ÇÎÿp;P1D‚t <@a0‘ÔŸ®¹ÚÐ,% 8(–Ø }ÒýªYC†ç©¯\cj‡ œ:ááW¿¦(Ž>Ή×þJ[ 4ƒÙÿ Ð?þ[©á/L*t–ÅóxÓ”»40…wqj)`"¿ > endobj 1988 0 obj << /D [1986 0 R /XYZ 85.0394 794.5015 null] >> endobj 566 0 obj << /D [1986 0 R /XYZ 85.0394 489.6987 null] >> endobj 1401 0 obj << /D [1986 0 R /XYZ 85.0394 463.7183 null] >> endobj 1985 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F61 1466 0 R /F21 1034 0 R >> /XObject << /Im2 1455 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1991 0 obj << /Length 3564 /Filter /FlateDecode >> stream xÚ­]sã¶ñÝ¿BÓ—È3ø Hæú1ÎÅN末Ïm’<Ðd³¦HE¤Nv:ýïÝÅ.(’¢Î—ÞçàX,û ‰Ib™À¤2Ä©¢PD“ùê$œÜÃØw'‚çÌü¤YwÖ7·'¯.U2IƒÔH3¹]vp%A˜$br»øijœ†púæÇëË«ïþqs~ëéíÕ×§3…ÓË«.¨÷ÝÍùÛ·ç7§3‘Dbúæ¯çïn/nhÈ0Žo®®¿%HJͤ7—7×o.N¹ýþäâ¶=K÷¼"Tx_O~ú%œ,àØßŸ„J“h²ƒ0i*'«© ÒJyHqòþäï-ÂΨ[:Æ?%A$µNª@*£Æ¹,‚X˜kHÉ–ËRŒqÙÏB.¯²§Y6ÏævVç¿Ùá©…LƒX&fÒE}@@;k„Ù¡@(Äa: áöÁžÎT¨–|µ]ÑG¶ª¶eCýjÉìªÚ£9|@ÑÝ2[¯‹œø‚×Ù&kø Ò]/ÂÛ…{®J¼„ÞièšÍ¤×¸ói*§Žödá »Ì€Dú€’W—º'´€PI!7¢æ-MêKv¤J&<'à]훉 ‡ AI@ "PƒÖÊ öŒW‚YªÊÆ–LÏe^4v“—÷#;ÂIexRíð}S"Fû†ÍÚIAõ!_8õ€>) ewy‘7Ïôá”ÚŸÃPân4·Ú6þöú=uX¨ÖUYÂxº¤-V´Ä>Áê2+ëH,xÅN—å%žÈ­™Û ~]]ó¼v‚R°8ö §`Ð’(ÀPVÖ;'|¬í¼É«o:I§ï×vžãáæY’·9ELÀ‚44ž16:â¿a9#],¼*Ñ„ŸÃ(hê¹ b¨×¡Ï± @«¬qzý‚Î=ØrD°%È]C ¡ElxÒP" DbÌÄHЕŠOñ|2H“$÷{³㬋Òy‹} ˆ£h¿39,<áHÆñ‰ô_"œ¯ÑàÒzDyÝŒè,(l*UÄ wbÍuh/$xë°µ: [>ÏXÈáÆg|Y¶Ùhˆ¸¯PÕšµBƒ™¹BOB–ýliá\€zZßo®Ïß^P׉ ´ßîA‡@'ñÐ’Bçg)uVäY•ÙÊÒÖ¨Uy`§–ñ~Qgc·¶Kƒ8æ¿êí]ÝäͶ± ˜߯[‹!vyK#¦‹­%ó)†OÄz ŸNÈœN XuT‘L$aó]á6G -”è o0"qGizL#£×ñi"L»ÇšŒÌL«$€ø:XY ໊’éîÁú8B)ã®Ì±® A+9jê’/ß v‰½JÅ.rpƒÔÀ,ªUæ"6EæÜµ¥íâ=úŒˆÂDu¸;T&WªI”DŽ•ùlõo1κ(Õ_3M K;ícê2J½úÛ®ÀÓ×.AI¦W}&€'bd=ªÅàeG•ÂÅCþ)R˜êØÓá. ¹Ú;JÔ¸ îP.c0bºvŒ ×Íl¹0`d'Y‹—E45b2Üf•‹Ú…ò‹P)赉Éhb4[´üŽù'%3iß>ds¤×-™”ûŒH)ÈÑkIš©9o@À>:¯Ú6 xhŒ0ÂdúCþhwymÏhM>\ëtÙAÏ×0+cŒ{Ùïï}8LkC†6: ™~B"Œ>bR´ "eôÿeRdì£Û/À(rJb|ž`(Š~ý˜R0µOÙ ò¦Ï¢%u“»`ÍŒ›s  æÕŠ}…afÁÜžˆâb µUÀ9eŸ=¿ã¼ y ·­ØêÚÌO™A¢Lì&îv»€‰ôƒx˜°ucØ}zzêO ë #‰+]z³Ý”îÈÜ=SKÙ_¸ç[i0°ÏÇÂ6o Q;h9ëAÐ RgW—ÙéèˆA3–•|p7ËmñÚÛ1Yˆu±ªgâ£}>P5 щ„dSÇ!L5Ÿ¢µg]”#ÊIˆ‹€1í4w‡‹1%Іò)f±lóû’+olEq°ƒÑf`M1²K\ ›n!… +PÊìž?\8ÖNÃ4ÌÅc '-Øq%N\Ç{d¸(PYÝFH0ôæmXl¯E^Ï9ò›aðGE ø¸³G"W€[œyÉ`•Qóþâæ4Цÿ¼Ä ûùÕµÈTG=ӡˣŸOÄ 3/r8×Àuq-ÙÉôxB€` ltNü„–Êe–4¼)±Œïr.ÌàxÖ4Ùü±>ãô7(©Ý=äXƒÁuYÙ f8qFu)?{ -I°xŒã>8†¸“«Û©,øns,qàúªÎjšS¬™>Z^†Å8º‹k²JªïkZ1¾«wüÝ-‰áÊ mšLŸ«í†zÕÎÓa›]µyd¨§w´àçÃäȇýX÷èJèêл’»;2ÆáDÌ/†4WÛ;‚ÝÑ9wµ/¤WŒ©žoò5WÄçÕ¶X´Å÷²S}' §Ž"¯hº-[Q)Dpýõi_rµÌŠ¢ÚqmÏ?„Ñ^<Ü—whïmCó0Vs™IgÐj'ÍTuEhY-%—Z¦¤¨æí4+#= „Ì€ò«†àwŒÉÕu]ü0vk¥«ªÎD2™¨XøUÁé6˜ÁíHø~o- ¸Scg­ñÈné‡,/²»‚G lšfýõ«WëjÓdEÍWÜûWó¼É\9k¾\ý%_üI(0ó: \›&dÛ…Öºÿ8tPm?x Ð<Ģ顋F'¾÷·½ÿñ f݇îç/î>v°O:T/¾JD !Ÿj9ÈÑØªŽ™öK§³*íf’˜H/ ‚N2šÜ|·yµ"³¸ n7o}à¼I{7FyÇŽ’©ŽMÃÙ[*½«”4R¥¾bcìSÐ=鎀$2 àÿ+©Ù‡Ò) ³ÊïøÈe½Ëç\V{[â¼f2ݶþz$8dw´ “¸õ?Ôt {M ÿRÓ-÷tWü¡ÃÊ?ø%¯ÇìbowÎÀ? Óa¦¬ h„,¼²œí(©Ý?G‘Eñ¿ ÛÔ §Æ9 ìôrFGÂà“Ån+ ¯¸·]÷I!‰p®ûtV’©vòN Rú³1V¶²°?¿k#Ð/…ïãºqV/jëÇ#)òGë…/ÿóäŒCÎû&^®€¸à¿žaÇ?õ©ÞSŸI’éû¼œÛÁlŠjÝáâ§Dwá`ûè竑ÉݞÛy{ôT â¸S˜ìnÛ/¦à¸-Çlÿ]À؆ÍÙÈ€?â5Kÿ¼ç ±k¦`ópSÅæ´;­:Ád”óšÆPбͨ)ì}ÞäÀ^Ú1›°Ž‚1ïåú(Û»½ÌZcDí¬±Œß{$»ŸrªÏæ¿bJ?"ðu? ~\Ôå'ˆ:|ˆÂùr¥¢Ë•ª[µ–ÒP'ç8ÀפÐëO•ž¡÷wUçKª#%%%£@Æm¹ï…z¿ tdLÿ…%K&­Ãùç Äjø»š…c1ÀuÕ´¦ÈE­:í¨ ÕÔSÿƒç¡â€¯™’¢~Uz4¶k7²öFÓŰø«‘+ž»ÌæM«¤vÿë› ­PîH…Ü'®ö¹o¿„Kºâîf4Îv Øw—ÆŸã÷*[¯ÉÊD<æ£~ì!>¯‡œªÂ<—ÎÁh?‹)/ m.·0íüà#ö5èPš ãë*wés¬ÙÐêîïnL¢ñÝyäp>Ø1`Λ-_˜IIþÚù1Ë‚ ü®à’_üîÙ\±Ý¬+z“‰Õ´Þº_E þš–ñz¬xÜmïïù5ÇDÓóšÒ}á áwàÄq<÷£ô›¡#ÙŸ'8VT·÷\ÃNû¤C?7ñ*L§üûM2ã$Ö€ƒÕ¹K–ܲ Aý^Fû‰¨Þ¼YmÉ Æô+97ß6íÖ»ËÞ`O¡¢J ïI¿¯ûA$Äñø+Æ‘Ü#œøKþìKîIªã@%É‘hÚÿ0Êõ@ÀƳw‹QršÊƒ3Á ÐÈ¡þ7Ôíœendstream endobj 1990 0 obj << /Type /Page /Contents 1991 0 R /Resources 1989 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1984 0 R /Annots [ 1994 0 R ] >> endobj 1994 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [63.4454 359.5711 382.2499 370.3854] /Subtype/Link/A<> >> endobj 1992 0 obj << /D [1990 0 R /XYZ 56.6929 794.5015 null] >> endobj 570 0 obj << /D [1990 0 R /XYZ 56.6929 689.0365 null] >> endobj 1993 0 obj << /D [1990 0 R /XYZ 56.6929 660.9665 null] >> endobj 1989 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F11 1559 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1997 0 obj << /Length 3779 /Filter /FlateDecode >> stream xÚ¥Z[s›È~÷¯ð#®ŠfaØ<É—ìñÖÆñ:>åS{y@IThÈv~ýéžîá"aïž:I% ===·¯¯È;wá¯wÂU±ƾ\/8O·gîùú~:ó˜gf™fC®Ëdz>©è<±–úüq5 7мóÇåïÎÕ¿æ÷73¸Ž³@»ÎåíÝ5Qbz\}¹ûtûÓ¿æ¡ï<Þ~¹#òÃͧ›‡›»«›‹™Œ—,áŸn¹¡ÖOóÏŸç>þ|vóØíe¸_ÏU¸‘¿Î~ÿÓ=_¶>s…Š£àü^\áű<ßžù¯”¥g_Ï~ízÍЩó T$‚H†(åÔ±ÐJ*s€Í&»˜)7t¶Én——k|‰œ¼&b‘­ó&ß& 3U{ê/«†Ïy³ÉK"v¢®ï¾ j=)rþÒß_x‘“-òr ó x’¦IÒoĶmk¼Ûôû¼x¥×ËÙ!U“¥M¶ÄÓ‡#˜yžˆƒ@šý$0^†.-F†žÛ*ò4iòª´=–§­³úˆ›–ޤO¸Wl$ÔS$fêuFÔ:o²Ø œMõœ²=BÅP´“óÛä• ¿ÌW(äוi{B¢7ñ ¶Ç“q쪺ÎE6¹ç~‹¸Ñ)À³*Ó ¯B+¸Šœ;qö¢Éöæ¶‘°Ê’¦¥ÛABèXN^Î!_Âa³@¼l™%Ãs“;jÕm [Úð J°ËöfeIA„¬<ä$¶Üfeó·â‰6FÚmÖ›_g%H)ÌÔæë´j÷ÉÚ¬ª;>x¶û’Z9,]ºtÚ²Èj–öZµ nÏð7ÈâëvHï¸7ÉI%OWlöÔL7UžZÄ•Kš´Ç A|âêÌzïG’|p•ðR-yÕÖf;ðЦ&/ð€Al£’ú³hêß&%s)PÒª<J ~­<šÊ¾™}âX’ ÄJe{Š/+Büvj7uµ5;eb[t¶1ªÔ†ZFŸðÙïIiçSÞ+30Tf[Р•@ƒøÓÊ<—5acM’—Ý0{y£x»vß'µkY0<¿Mé®]úFÁ/y¿•¡~ ¢öà?¼²ë‚—ÎêŒÌHØ}²^©ý[U2õ7pǮ={Þƒç‚ÝÑ|r<Ÿ @>? ècbzäeZ´ËŒ=`ÂŽ0ßæèqÈKeé&)ózK}xYƃV`Þ_;H >J³¹"/jûþj³º±³̪5œõP2ðl“½½æ³I$íX’T<½p, 0œ°2¿5Î8CQÚØM9‡<{&’íJ¶……®uQ-’‚ùvF8-Bí{cPZc þÐ8ò‹½‡•—'·*G*c7e::·òÊNVÒÊcé Ð!*˜°¿ló`3®ƒ d^&{æ$5ê†LvhF•ï9uf”Ù—h"Õh’L Ðù}nnˆeµßbœ^–xNÈD-—˜“DsËÂrßÖ-ù$$.²š»Íð»Slöyj{6•Á#tÒüõ”AŸLØFÇ„þyM¯Eþm 1d&~3¸Ì’g(žèùÞ ‘’ˆ« i¡ðCÉýE•&¬bÄSQ~ bZXOˆЃ–0ÃÇ µÂ;­Œa7nàc¨ù”ºÂ÷âðÑAíFúH1 Nm¨\·»]µçÈ}ÛM¾+8 ïà =‹&¨G“€ç@|›¼€“úžqèžíWˆ+0¡ëÔ±O–ù ‡ð„‘L:.#5FyˆV¾¤åàY^‰ 8%ãü k¨ÀÔßÙ?èµöÈ#í.ëzí¹—õè€b0AÄŒhi»§yʆztžç¡THÏT̽…dÊ,‚L£™žràìÑì#Éøz¢¢ßA’’ü^Ò;­e»]ØqĬúÍÍnÈ9M赆]S ¥¤+âP©-¸0Ýñ´>¢ž’°37«b-\¥õ±ÏMJ›oØLã(-{¤qÝîm.šÎ¿2‰ï¤ü”ØïQ[ÉF´|a=™V”nâ:¸b»a‚ÔŲ⤠Dyç>¬#Š@‘' NÌ4rQ½Ä›¨—t\Ưßÿ6»úåöæÎ¨Þ B„£xA„Fîo–ÐqM¬ax·žVäëG‹0‰Ò‘½ >Mue(Kê_¼r— åHZpøCuAÏÙ…•i‘ƒÞ™2p®Ì ±Ú•ÈênÝ 1€]éÐ?JëºhÈW= ðŨN—y ö‹ÖÍ*ÎбU=—F+¡‰aUMÃ{ÎÑTu»èbF3x5©•tiíY­Ü}ŸÑ!ÌòÝ„N±ˆü°ÓaÊAy` —¬Æ…xµcm¬F¡Öièhƒ³|m£DJ•Ë•$ÑéqüÆl£+xÇ ð¼ßàr}à8ø'l3ŽâWjï&3Çe®TA–YÓ©ùñðÔ”P±´Nr·ÏVùK‘•ëf#.}q©Ä¥—žø»Ã—2žÉεςÐÖ"}×n Aõ­ mÛ Qh6js1Z 6 ,Gà»Ñxs‹¬yÎLÁ$ŠÌ?£k@ð®°¤ìKåÌM%(+*Þ@kñÚd5zç8t.}ÛP¶!¹Ñɺô˜B+3"2zîúæù.}ê1¦<²™–Yšo^Ì!)Z¦ìßÌÈŠ,©Ù;ÔùºÌM “‹A®ÙÊ8UëÒqåQL¨Çfþön6¿¾~ó‡{´®óI¯òôÅÌ‹Oò2C²ˆÄ—Άà Îa8èa‚£†Ú58|,ïšT@óܰ”º ¹,ª_A“½° F ÆS~˜¹ #¡L¡œ-ƒåÁì)O¡xÒâ)O¾xRâIЧ¢ žðBW÷Ú¨s“˜ˆŠ/ "xÿAñáÉ£W“fP€¯dy|*M)“o·{¢,Á5DÜ@“½Ø|ÐN<TÒã?aûä¹|8žæ’]ÞÔÔ2(ó­kò¾lQ†~”õc4Üì…±™Ýå"‘®tr=6ø¡ù'Ì/"ÐchšrCÈÇÀºíxCŠs4+‚fE@««J`H¦’Q‘–]¨¦»Â~{½»r#xb…<7?—ùjÒ†¯²>ÞÆO]M²‡x´bêdùÀÀaÇ&{¡{«4mw¹ý“±HY!¨¨§àL(ôGÔÿ<|ðk YEóçwh‰½¤ÙnòS¬ÖT"B:6 “gÊŠž)ÆáiÛPX „ï´ÃŠÞFËá(@æk)’”>WD”bŸHˆ • 1Ä÷ïbJ1‡V‘Í·û‚!Jnx)˪]™]uÁ˜È€èÇ퉼uŽMkÕG–m¹fóNjbvPU““z.ùÙ1óØÏ’7!?‹m¾·AÐ{TxáŠ.yA|—Ñ›a¿T±.á»aÿëí°¿ã£øõnþùæ$Ô—ðU¾?mÇ51ï(ÔW¦¤05/ÄŠQF%}d裱(:üqÐ╺(Q6MC¯qQt\”F¹àá¬é²œÆ~ µ 44v®ì!aE`ø;­íNêª8˜eò‡Eì¡~æË³Ž9ÖѨ¸€¾ PL‘Zûµý–bˆ+˜Ð«=Qhv'Ú‰µ‹£þ¼îçž0|ŽˆIûåÆ= õIYª£˜h˜cPÿ& =@£Ä:×»€r½ èŽËæ±É+ZÒ÷õûóv\-ôñxfL1 {üAà†ñ¶e9N9|—SA—²xÎi„ÉeðþPëäBƒ L0l~÷õ =‚D0í\÷mPÄÑ{:ƒpöÆñ€D¾ÕÁg×£š†©£R탢6û™a\aW5Š“‡™*ÇÚ§™ªÄÃöt<ÈT§ãÂMþ°ü9 @öé‚´÷8àz€–Ëðîëõ¤]ÕJ¸Z«÷'ï¸&f—P"áú`GÓÛ©é«Vòª«6bÛÇþ ÄMm³ìƒ«üª³ýGó×½A}%ììË3ŸÀbãeG@á9€<ÇõÂ1¨(zѼm%ë^²î%㯠ˆrÅûƒ´¦7ØÞ„¸yIGÓ†#¹‚XïØ9üýHwì™,ÂŽ ìúÓPÖZ„Qì\ÖKckOá¬=Æ]Îj†ac†]®ÞbƒÊŠ8;—S°òq{q 1º‰Cz„¸~‡hZ†±©" !ñwY¡>ª>sX3? kÈr™b'Czû«f_¨=)Ÿ¦›,ýfMM²Æ1ÌÚ#þÈýÓšj‚ÅÓ[ ˜Þ6–©·®HI¡dïMÛ1Î;­ÀÖy[ '¦ËUÞPýñ­÷DÞÉøB–[Ó#­É6R˜6*.záÅEW ?pãÐ'¶¬ö,ð.+ÌTd!­¢‘Ñ‹†Uãh"ÕýäKEÖ´E½YŒìçBÅ¿9ƒ'Š&ü–¼Ý.½Ùæ%lr¶¬šzª~мÀ~^C&þýe ËX«¤-xN[ÆR¶Œ5õ£L…q¸šÂüc ý¿°ÙÿšÕÇr‘°É8´‹Â]Æ mX„þ€üP³{ÿxSÝ>Owõ_Ë4!endstream endobj 1996 0 obj << /Type /Page /Contents 1997 0 R /Resources 1995 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1984 0 R >> endobj 1998 0 obj << /D [1996 0 R /XYZ 85.0394 794.5015 null] >> endobj 574 0 obj << /D [1996 0 R /XYZ 85.0394 639.4252 null] >> endobj 1999 0 obj << /D [1996 0 R /XYZ 85.0394 614.3827 null] >> endobj 1995 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F14 1060 0 R /F49 1358 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2002 0 obj << /Length 3496 /Filter /FlateDecode >> stream xÚ¥]sÛ¸ñÝ¿Bo¥o"– ~t¦Ší¤¾IlŸí´ÞÝ-Ñ'’¨©øœ_ß]ì)’™NÇã!¸XíûýÅ,€?1S±ga6K²ÈWP³åö,˜½ÀÜÇ3Á8sƒ4w±Þ?žýõƒLg™ŸÅa<{|vh¥~¦bö¸úÕ‹ýÐ? wq{óáúã—ûÅyy×·7çóPÞ‡ëOW4úx¿øüyq>©ÞÅ?wW÷43÷×7—Éè1BôþêÃÕýÕÍÅÕùï?Ÿ]=Ú½¸ûÄüqöëïÁlÛþù,ðe–ªÙ+¼¾È²p¶=‹”ôU$¥lÎÎ~±YýÓAù‰Àe0ŽSá«,S³De~,C©¸-wó]=_UM›Ÿ„®Ì?Œ£ø nYÓö=šŠžÅŸËÍqUàž›â[±¡áªÚæå®ö‘Álž†¾HD4›‹ÄÏRiÒkü}šz‹Ã ç"õŠz_íjžÔ €çr],¿+zÉ_xÃ/›ÍØ÷Õ¦\2éïÕ®¨ßÁ8K½º"Xóʃê@ÏmEDNNð%̢ͯò ž ½Ñv(üL©Pï°9”//ýWžÅÞ’Ë”—Ó«»d0È(н÷Å2?ê ÀüåÍÃ)bÍ$ìRíüë¡lšbÇóK³Úr÷BXZ}8ÕÐû¶ÒB‡@vÏ–¨¡ònh‹°G^ ,6ŽUïW4_ì–-ßPjˆ™/›²Úì·@U³ié×f Hdœ®=‡BúA”¶ÎËë‡ÅûOW—Cfû`ô‘8ÕÀDýíwŽ‹x*²\Wu±%ÄJzçYà‘öjš®„K$›ãÌOtA’N§f‚²ÖG¿A9·Y[µš„ZŸµ]. Z=“RTîz8ÏÕfS½Úy^KqøÛØÑ§‰ŸNŸÓ…ÎWÒ … ü>§èˆ4œàd0¦8™Ó¬åt±®ªºèí¿ïvVl­MÊí;9AGaù~_äÖãoAêæô熚~Ê„íïÀ®;g÷:µ×$ò#„Œ_íÑ^ýQ…¡í‰8þά µ,äŽknŠe«¼I–V.Ë;ÒÍsÁ¦~ñéúêæñ\)o~}×:¿Ü,>_uA}”›‡ËS¤›‹f}ÚUaNsˆ[¿~*eøñ;Xâ7X( 9.þ)–­ø'YZñ»,ÛJ"vd'”•FÌPz{WKB±ÓÀŒ³1Tû €·y»fBV^½…`]ÔŒ³Ë· ?îVD"n Cè{¸ºŠ9ö@}ë(„MfÑ\ÄÁšÐ‘ÁBîÑ¸Ž¦X¶:šdiuä²4:rì݆SÓ~G¯ûž[œŽúåµlÖ½ù ð*Ì!ÇTðàûs\Ôô3!~äÖ„¨ î[‹zŠe+êI–VÔ.K#ê vÏ xcIÆB°f²_¹b"Ȧؽ4ëwdÞ]´bÒ&Pªx‚µ¸n¥ñµ[®[¹d¬[uœ…cùjÅ9¤IÊÃÈÏ8„;Iù¿Ö…NÈ¢.ã”W_-á—œÁ%^õLs9½v3oœ(ëÎL“šbÅ„+Bá©jó­  >}p޲­Ä»0 ä4³ÒüwL4çµÚðÚ?4N²ÒäVœ ¯¡ñ:¯i°«ZàS¡¥‘ªnNj€ œìm?m³hœÕ…m¢‡p]Ä| ¿„“bD0˜ØÞEõðXå§ÅÓÓ~ÁúºŠ¿¿ûÐWñ©  ªÁ¨ÄÙ€óÝ š·}ÁÚ2W.cô |,ö ýÀlMŤue~"­mMî¬9S>ïþÌXÈ|È lá$1J¡ŠÂÿªüV®Žù†àX‡–(ž¹ "o¡7hzG&ä!@+·4Ôt ˆƒ'ž†âmE:3F’Ð 1sÊ0×z3€Pü™o÷›b°èz]—›Âˆg(ûŒm¶†¼¸›W»ÍPÖA±Ÿ¨˜­Õá’õ¹¬¶[ýc å½)>O9‹(ð•L"¦¸Ü”Å®ÁDn€w¼¥Éxð%Sé• ±Yîè©… Ëé-À5ÃD›!›Ä3Ÿq‰òãT —åñ™ tÙ/&ަ¼@Íá¤Ù+Îúµy'®V¯;ÃÊqÌ^æ9œm ?"žEq ‚в‘F!Í]¬Ó>‰ÂKgÞØáZ<<<þãþKŸ¹¥Jý€»Å`ïªVgÒeOýŸ$EsnŠM©sŽ$k; wàYï‹e‰áUt€ôÄ9=Ìñ3¯kªÚÐiõR4–Ú@¥•WÆÊTjûïó}^×ÍúpHϧ•™ò®™¾nÜÔ´ Û'€èäÇA’ …#Û«r qWqîõtRò7¦/`ÏuÓžãFŽ6S‹E¾âÒþ- £}õ• ¯+HÔµÉöxëXùÅõ%·NŸ6Õòk=n¯XÈt,´öê`MØ«ÁÒÝžûÛ»>Ó4öU$ÓL ÒSW·$„ –ÑaJVŠ;H 6ùò+j§U¦Hë*LŠKFӮϜæ¬ëD­ëD=×QL)âüÝ0«*ž^UT~Ì#ˆ%̺¶Nk¦N28ƒ¾Q_1+‰¢tZ}.Ö¸ú,–Vßíåâ< ñ†#ô§G,7bš¿ÅX@÷ȃ´/¢î (¢ÆÒ+¶û憵Ž|0ÐY6´a¤Å¯Nõ«®çâÔéàá/ôFS”5Ÿð!6Ü-ÁiLöÉ R?ÒmR7vXs õo y-Î5W[vvÍd°ãƒRËr­¾Lgû[ifØ&ÝfÂ[¡n5²]*_áa“Ú Mjƒ^Rk~$Ìzî…+9.×L—éÿäsÄ_V[Ìc%{¡$¦ßaág|G_>ÓÓˆŠgwöâß5‘´-% j)þ0 1+ä¦ë¯ô¢]›.•ñumxRß°ýl`…ƒYë(Åò‚ÆÎ7Ø&ð‡R‰Gcûãao¯=;b›l[•*«R'7¼t³ÿåeü"ùÛÊlZ/&ÍßýÅ4 $heóÖËWêâð Äv7Õh^èæi$¨#OЍQèôöÚMx £><óîïCó{ÑmëÁûiãØ%C›k!ºF(µö`ðÄ€ 6v(W«‚á܃ÂEdÔ=Ó½ú•Ÿ%ªm™ñçRšœs¸Ë§ aOâì¹bŽ3!zWÌP¶dÞ‚‘^ò]ù=ç\3Á®ÙHBel┾0ækóÄ\ƒT |JÒnÓ`‹Ž¾íÐö b Ù€Œ†nõ:¬u’ü²nz¸Öз–e½íÆH>9ç_6O’º¨eSÛ>Ý”ÑFT!2_ÄÙºs.ÖxLµX(×ÿ¼:I²3á˜VNr5H\;íÞ¨d—k{Æà‘µ®6+Ó½´*GÏßê¶£´êw®ØM˜Ô4L¡8´‡‘=dr§¨é¦pcßhøºFÑGšù¡rZÒ¸6 RÿC£nj“ágr’­E:åÛMm £ ¢¸Ã˜*Á¢¨é“©RGÀ8Õ¶í3ÛÝA,·ŒNCEé N®ø¹3=|Ñ D,ˆyåKÝæ|ãò^úaÐk½VÇ žÛ2ƒØ¨¯ù"ôC½€•Ï¡£[:;‘vÅ0ÝFn„k+ÓtÊ:Úè¶“JR–”Ìúå_DÎŽ3–]NE6" ò‘ ûóQôµ X¼Ñ_«é›¼0lø»2qòÑÎÓu“jï€zß'!ŽÝ¸P öL8Ÿý1o‚ºÂbï’_;ÔG®ï¥òñkÓË…VæÿýQkû@”ø2MGZ°½5¡Üt}Hþåü.:Ÿ XTèe§{º©ÿ“Ð'endstream endobj 2001 0 obj << /Type /Page /Contents 2002 0 R /Resources 2000 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1984 0 R >> endobj 2003 0 obj << /D [2001 0 R /XYZ 56.6929 794.5015 null] >> endobj 2004 0 obj << /D [2001 0 R /XYZ 56.6929 702.974 null] >> endobj 2005 0 obj << /D [2001 0 R /XYZ 56.6929 684.9906 null] >> endobj 2006 0 obj << /D [2001 0 R /XYZ 56.6929 667.0072 null] >> endobj 2007 0 obj << /D [2001 0 R /XYZ 56.6929 637.0686 null] >> endobj 2008 0 obj << /D [2001 0 R /XYZ 56.6929 619.0852 null] >> endobj 2000 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2011 0 obj << /Length 3218 /Filter /FlateDecode >> stream xÚ¥ksã¶ñ»…'ÓrçÈI‘Éd¦:?îœÜÙŽ­t:Mó!‹ŠÔ‘”}N'ÿ½û2}MÚd.‹Åb߀¬Ž=øWÇ¡ëé$8ž'z*<^m¼ã˜{w¤„ƱDÎêíòèë 'nùÑñr=à»^«ãeöóìôýâfy~{âø¡7‹Ü'Œ¼ÙÛË«3Æ$ü9½¾º¸|÷ÓíâdÌ–—×WŒ¾=¿8¿=¿:=?qT*Xï ‡W\\~8gèÝíâãÇÅíÉ/ËïΗÝY†çUžÆƒ|:úùï8ƒcä¹:‰Ãã'x®Jÿx{„Ú ­-¦8º;ú±c8˜¥¥Sú u솱?ŸP ï¨<€ƒèx&n¤}M ü­*MgJ¢Y³©öE†p8Kw;“ÖŒÿ—çùuÓ¾9q´7ŸÝ›Uºo “µóÌDOyQ0®Z·¦ddYµ Ü }Q=<˜ŒqùZ¶âá&ؘšQ»úDÅ3³2™)W†çÛ:‡µ"RÞ æáøŽRn†>e]íËŒí#2»/ ä¹^¾3Wsw®´?íBä ©XŸjÊ!-Êpƒ³¸»[¾¿ýé Ërv{}#àòôƹ.‹g^ýãìúãâòʯÏ'‰?[âÿ‡¢ë@»ÊO’/ËÞQM?tÄ®RÊK_=šºÎ3T¹ïMÛ C`gVUͶivU™åå£w†°ŽØ­¢oF6r|pO‰F¶ÚUE¾z>f¯)š‡.¸ô1Òêu#uT”5®%³j›æå¡*Rn”@ }Q„ŽjB†QàE‘Íýx,…QÃR¤<˜’nþÉ€è‡à±VeI[ÉÒU+€LP\…žM€žØ:FBÃ÷ƒU™nÍPˆœÜÌe#ÆpR­!G+H¾^<§¼Eþ-3³N÷&?Ұ½"…Âå0ªÊ†ÇÎx—še<ÎKæò§w-J0Ñ@ cªòî<8ØíŠœ’ *.†H?ðý´7uNzFä&meUó+ëªn¾Ú³'Oå—&¯PÞ †ôz·gß)ø*ób2[2k˜uð`•ÊJˆØ¤%ç@ðæ¤üi ¢ "œ÷G¼ ny :Ìá†Á¼mõ˜›§©CrÐkÏB˜>'­\? CX„´5ª«ÉÃzÇUe%ˆû°Ò²lU ëƒÞ‚(½A2‡•z¶6i»·–EV<áÏ€x½/&!Иú‘ò(?–ü¹±Ê‡µ 0Âë¾²Çˈ2µ”d¥Tàú^[p—Qí[¡ÕàÓ%o/Nðf*Q1£VEµÏ,•û†¥Äܸ}™)LÛ±m N°Ÿ"é×dD‚ä¦~ÊY°ªÊS×PÅÂL˜õ1-ö6Û‡6«`>·¦.Á¥$a<æM~_ÈdŸ*PåT‘GmIÁ \¹Ý¦ƒ±(8iày³{ôŽ$¤Š@Ç¢@cž $´]tÓÀF7’±—!º¾gWw<Åk Ø›Vذ2yK­ ©5A`°°cyw~:¥Ã­iÓ,m1€ Èc8»þÎÀ˜u3Oj€SVŒž¿Ìæ@Øg4 HÓ¼HÙ0·¶|G¢{6 LQp×MJ²ä9˜”Ñ’?RãÙ'ŽÇA¤‚ƒ”‚›RF^’÷B‰_˜ ÛBnÇÔ‡cJ}Ü —.õá€Êdl[Ù(¾)È ’ÜES/s—7êûÚ¤¿:YÙ4fÅZz6ÍTî‚Æ<‡>È]:ög—Ö)÷ÏñÌÁ:ÛRŽæ´ÎMƒ‘¡»ÒÕY÷ 2HX²¢Z}ÈåÁr#,z°thF®Ù"øÈÈ,¿Äð®Ím.àÝ!Uj³j›ƒü°îš 9i· `n†ˆ§:o¹ÿ9êG]M¯ €ðÓéõ <Ì$WH^ÀñŽÀË(ò†Q¥ëCÆ0‡G.ƒŸ¥gÂÙ)X¢lËFÛë(UžX•{]Ôukƒ™]”f™¨¥aDÞ6¦X ,B6û5Ò`UZá–o&[ ê^¤hÃwWçå*ßQJˆ± à±»yfPÄBÈp;Ë,’î#Jú&«v!+Eæªx4zvÌÞWOæ‘î<×=«žšÛ@‰8£,l²ñ¹8èXH­}Ɇ q€ýQ\µ°†ôÒ%@v H{ÿ“‚+ ~e«}#Huîù6ïE´Ë‹œŽ3`¥)÷ÀP˜° ¤\p' Õ®‚[RÚVXãMñ h®ª‚dGÀî‰(QCmfÄwÊiäšüN$;qtjôà´M%¾‘h-(ŽJ=ìSa>-ŸxHUNÌÆ•ÖRšHù3ªPZG¢ÂÊ.ucÝ›uÕ5y¸²|f ·eh£¯a&éÚìÅ•Ñ{M8{k%¢7W(·áÃ/^¹IÑVP7š¢zBäÚ·(¢-è°›dK¡}ìÑ(¢´W$;à–“m DšUÕA“?”9EZ ªÍ·†²LLYf¢íŽ´«C(K\„>¡G8OiÞ:Ü‚KÆïÈÆ›êÈU”I$ m%ÐØ9È*­«m8Ñý1u×ñ ~ì>„²yž`jxQʨ²*ï Ì.u —(¬^àd"øèˆüšœ{ýS)eܵ¡¬Ò§œâëÖ§F¹°î\Ôëûoàp´Uk„e%]'€biÛ1GMx"ì¯üs®ÖóÙÕÉ$¬Pg"<`­”H&ýÓÍm* nÓg^œ™aFsº0P-Þ0Ñþy3Úá‹ ÈC¦n’ru <î!õÈ ¢²}Íy:ðÆU‰)»*³GËb˜ÇjvÙ2}J÷ $cÒÐÓäÐØ@b{ï~#{K@ŒtñŠ»x¤ß—Ô{}¡ô§úÇðµþqž¸óHÙ+3åŒPvøî¹_ ÃÁÃjhûøð°)FŒ¨AkO„+a¡È~GHùJŸÌnoï.ß 9^•Âþ©ˆbÍŠ>rQûÊø ~a0|,þ©‘ymÓ%PvmgàÛçfÏà  “„C³_mJsw~{âÿý‚ž_/?0–*/RÙ×l”Cp÷fÊgGM¬<ËÂVö.\Él–£g7éjï ™žÖJ3~¬ËòfUuwh®ß\ô¶ö°=輫P §Æt¢Sæ6Õ‡‹Ùò*j4|Ÿz__ا¶UF%‰:_ZÀsãÊ|üŒæsc„߯´<½æ“l-¯ÅÊŠà‹ÊÎX£æ‘kà+bQø~ÿ¢t˜JÉ»(L˜„‹è·‰’¡"ßæÜL!ºâoÊŸmú9ßî·< Gd®4]ˆ¾dy*h†Õ ç´m1üQäús/]y/®„¬ü.y Ï@­0Ê[¡¶…˜Ÿ×ƒÄUóÚ_É#p8é#öõÆ|N·p©G®ö ló‡xbwY”ø=¸66à™f‹ (=žÝ×n‚?‚¶®%’kÓÈófÿæ·Ì}uŸfXU¿ú–Ç¿;¡[grƒÔþÔ ü[‡ZÜ ‘Däöy'3ÛÊ-’®óÂ.`ü×GI h1¹·'h€Ì·¿ÿù“ÊÏ3¯•_='ÎÙùBL\þBAŠ[«÷SÉßN¥c˜¾»^0݇ëÓŇ÷×wK—ÇØŒfÎö¡vÅܺ,NauUÂ}#ßPæ´—1ào¨øâÞ*Ðnø26ÊoÌ­ ¥¶êAjÑ£´x=­Æ ƒ¿j0GòZÌ•Zs<-3u^a]´q¹G bîò"OR5ÕSiqra›º<}æ‰+Ò”ö`ü&¥PÕ ^‚89‹ý™ptË\»QGÄü¯„ Ýd>Ž•;t@xwrWÚéÙÕ‘Æû _FG~·Ù6Q®O?S“há+"3d‰ƒ,×g‹åâ¥$*™»~Dñ‡ôðRÈîIÈ®`f2ø2¿?-äðù1ÍF‚D(ÈB´¦<ÿo â~ƒÚdyM}m$Oàä‹üy‚Äb$¢Ò:“›îdDa‹]Ÿç©oüo¾Q!5êt©æŽL{è;¼ã0tî?œYeC­µ'ÖËô±v#?¡÷!wýƒËþèž^œ ­ê×±>£ëÝoÎ.mšvSïÝ×þpC‡.þµÅį½ðŸlöÿQGÿ/ÁÜÕqüÚOô^äÆ~2·Bá!“NBøÃ?rqÁ]´sªû×§úøåDxendstream endobj 2010 0 obj << /Type /Page /Contents 2011 0 R /Resources 2009 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 1984 0 R >> endobj 2012 0 obj << /D [2010 0 R /XYZ 85.0394 794.5015 null] >> endobj 2009 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2015 0 obj << /Length 2828 /Filter /FlateDecode >> stream xÚ¥]oÛ8ò=¿Â/(‡J©oî!›&Ý,ÚlšxqÀíîƒ,Ó±PYRE9iúëo†3’%›i÷°Z‘Ãáp¾gH‹…bÅ^œÉl‘d¡ù"Z»3ñkïÏ㸒;Åúiyöö:H™—Å2^,7Z©ç§©X,׿;±'½s à;—¿Þ^ß¼ÿíþâ< åͯ·ç®Œ|çúæÃÞß_|üxqîŠ4ÎåÏwË«{ZŠ™ÆO7·ï’Ñç¢÷W×W÷W·—Wç.9»Z޲Lå~€‚|9ûýO±±9ó½ K£Å3L|Od™\ìÎÂ(ð¢0Huöpöi$8Y5[­ú¾'ƒXZJ›ÃÄ‹“„ø¯s7ö}§Së²SEO³¯Þê[S+oÝìò²öŠfGð¾ymÝ{Ì»µª=õ5ßµ•2[@7À +86Íiÿ4ÀÈË’$^/ ƒÐÀ-çxÐåíÅG£äÍ üÄl{•Ü)7žAuE–x2˸Aä¥qM•psGß¶©ÊâePLÑtkÍòoó~?we¯h’WÕÕmSkÅèES÷ OY?ÒüÂB²¬é+dò6U&¼,ŠF…Ô×Bµýˆìùð'æ¤Ùš%X¤®ýæ–íL™àþ0öl;é‰Ó­þÑV\hs­ûm·ÉÈÀËÐá'Ú¼}xG»ŒŠêõýž–-LÕzêfxx­×u¾SÌÎw¤"†©÷í¤ P¢àý(—Qªu3ÉNeYUyñ¹*u$Íóœà×ÍŽ]âÝíû@Uªº×6Æ„†³/B5J—¡Eéë®i½¿bñÿ‹År›¦+Ô%škâÈõ·î·¼}š ~žU–—w6éDLÂAB=–îÄp½/Z·©««ªfl_þ¥ýßM`”Af‰ÏÍüÑ}{-§©ÙeŠnÖRâõþî¿`@‘:E^Ó ßœÃÿ“§q®U÷¤:·ª»íòºPPÍd–9Wy±eMý‡ïËÇ}‡ûÕš 4!³1 I“}x_ö%o ¨±ì1hÊ 36¯7dIf¤o¶ $_¯Ë¾lê¼¢ù:ïóU®¿jšÏûVÓ¦•ú†ÞJŸ/{Õ½†QÂVJ­Ÿ+ë=à\7|2[ï Ì‚t f<I±„wz.{T±°Ò—%•¨ß N¤£È€qØe*‚†í󹬱6 °ÙèÈP°Òwåã£êÒŸÐÕÞ2¤W!3ç !št;ΊWpv~c“Êbð4@­à§oz´L™?‰„—Ê݈Ì_ðÇŒ‰[GcN‘ù]îÊ*ïhbŒ€;F7 +FuCß#„Í`ñ@c+[ˆ%YÂ4~Øò“sÌçÀ(_ƒ>r,øˆ³S»ý̬â G¼dt @û6⨢TËLN˜fhj×f%´?©fW>n1#¤ÀM±-Õ+9çåük¹Ûïh‚R*í¶ ®†ÊkŽ„Í ˆ;W;§¡ôÿ1˜ Ãú`P]èGFu©˜ØetìtôgÍ´acÔMD5AÓIÁhPNÄÕF9ðâ€fƒ`¸Í"“ÌÚ¨$y÷@–ÑXbFFâÈŸJ<K¨D2I)=*ž!eäÄ®°W5V,%rž F˜ ú™-…ߣ®.:9L0EXªÔ#DìŽ"æc'H˜pKÂBN .¯Õè ¾Üu=ª56*EŠ¡ÃCÊËH`½f>´)µ2K¯œþj’œ ÿð%šMÛYÛ7*3#ŒÙxš¸†dL+}÷B!>+5˜f„Kx9™QF¯zRÕ˹Â^ (0L>Np ù¿^+®¾›†+æQ° è¨ Ò¦ÇÎ ×hNr‚“œä1=Z=-ÞÓ#Q¦E“Õ~BËb ÅíE¬…àU›¤c zo:Û4£N —w¼6 ¸ÊW4c–T‰-ÙPäaðóÂn sðU¦ó¬V4Y‘W<ëzª9Óª¼wmÝ ZW3Ï€I÷‡blÚ<74O&ßùÏv(õmnen¦¶Wýë)æU5~§'ŒMõ„ÝW š‰w |K È‚Q5Tf3ÛS𩿆òQðE¨ì™+€7Ýa½o>Ñ`ºÚC|OÐt±…ôo‚:î˜>ÖÕݪ¬sNµHŽo/Ó|™±8™_$lqos¾uæ¼ÖÔø¶7Daž¦›¢ ›F*ïŒ"_V!nK¬ñŠO©÷»Ý^Nr@}To†ŽÚ´û0¤~ÙÜ̃Â8S9ÁæeÇ÷“*ъ觑Ãx"L¨+‰ðbñM[NÄÛI¤7KŽ t'GXyÞ–ï"¬ÙÉ%P«G“„¬O)fÌõzzï;. 8*Ëäž>4`\ã§^c‚Á1šÁ)wLF73oj“ï«^Oß|GDô%ëh¾Ç›œ†à“·À²VÒ£W’ JŽì½y’xŒ‡æˆå°ô DŽ ʼn!ÛÐ×Ü”ƒ:‘¼Ú+‚Mz"˜‰éáà£.AXlš`rdÌ-ÜÂ0%‚ûİa¹e²£±‘ (§nz~©‡¡œ;ï È“)bg7yv‰1íA¦Áî‰{õ0pŽnš£n†‘CO0DŽϛP=U} 2/ eüCÝà ‡fš_)^å¤6:@Ã^"âÌÒnaD†áP R$Á`žb0¦˜Œ{N€ÍSLqõϨ÷B„*×z¾ç¸³PÉ_­zæ¸ohècø(d£Õ«99e?8nÇÆ;wš¯´;\~€ ÷“7,¬³J08”~¡’fõ=X]L18`mÐLÝ÷ ŸœˆFLT—xyÀ;±G꽨,•‰+&„šµD¡6f]. cWMñ™×WýxzÕ¨G`¹¡9u·1=T€)ÿjØg¤öÈGI¿mÇ«üJ{*U?ö[¦ÛlN¸SSþ´…Á©ÏZª—É–g é%WeûºmG|¹Ä’%ÓÐ ²!1WqF'“!·püÚcÉ·Ò“a:94þÛ‡F1%ÉW~Ì à ¶Ÿ^á»Åßþ¡÷ð+x%Måø®´ý†Ë<¡8“­ñ'’À½ƒÀ”t²øD¦á·âS¡þŠUf|endstream endobj 2014 0 obj << /Type /Page /Contents 2015 0 R /Resources 2013 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2018 0 R >> endobj 2016 0 obj << /D [2014 0 R /XYZ 56.6929 794.5015 null] >> endobj 578 0 obj << /D [2014 0 R /XYZ 56.6929 349.9692 null] >> endobj 2017 0 obj << /D [2014 0 R /XYZ 56.6929 322.1097 null] >> endobj 2013 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F22 1037 0 R /F21 1034 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2021 0 obj << /Length 4614 /Filter /FlateDecode >> stream xÚ¥[[sÛ¸~÷¯ð[åNÄ xëmƛػé¬ÔÖ¶;Óí-Ñ6'©);î¯ï¹%ªNv“I⎃sùΤOüÕ§i¨0³§IfƒHéèt¹>Q§P÷ý‰–6s×hî·únqòö2LO³ ‹M|º¸÷ÆJ•¦út±ú÷ìÝçŸ7gs©YœÍ£X;ûpýžK2NÞ}¼¾üðýO7çg‰->|¼æâ›‹Ë‹›‹ëwgsFúáH‡Ë?^pîû›ó««ó›³ÿ,þ~r±è÷âïW«7òëÉ¿ÿ£NW°í¿Ÿ¨ ÌÒèô>T ³Ìœ®Ol‘ CWRÜžü£Ы¥®Sô‹Â4ˆR“LИ)FY‡&$žWÕÙ>fuSÏ‹õ¦{ÁO3ÛžétV´›¦n‹–[Ü7[Îäœ<åUy¦g+þZ5뼬e¬|]pî©_ñ2šGÎkéÁS,J¥¬{ÙÜŒzâ§ë órþ(WEÝ•Ë\–£ÂaEæZYÚÞcþ„í3^tfgU¹.;.i7ŲüE)S¬¸î¹ìq ›öè¦Md6Ezã[G•ù¦ Í[ØO¿Gq­t§ÆJOÜÒª¸Ïw•¬@ñ¼D× À[#n¸1±Jθó68ÖõÇ÷Ì øß¹Ð)s„=æÆ$pÚ*Óe8Ø0•ƒ ¢|ãÁ®8˧ú>¢LÆ}àcXUE+ý›{NÝÛÎvÀpvØÄi88¨êe- g7Åh1ÄC°–îQÚwÉeË*‡ÉGçÍú ŸÉdÑÖÑáùâ÷ÝËÄ鯲:”#ª›UÞ察liœMœëáaDq˜};÷dIÄ Öý$ÈÖZ PºíZÜ•åÓÃíåõ —„Q 2–ìêUœ^+áŠ4 t;sÅc:XLsNʧ¢æ¬°fàc^´1¸ £™+¿þùýÇ«ó×üUl©]³mß`A& ƉúãƒO‡±ÇÜç/’¹oB !½Î1h䳤ið—h!(lòEèô5: ù³á¤€¹ïò¶˜bK$©6¿•kâ1×ðÞË–w=;>Š…h¦`8B03#ajRãQ:Ë»._~nùc×±êÙmáðš5çQÑ㙆)q‡Œ’Ù2¯¹öNcÊWù¢x”²þƒ´Ûmk.KðT¡Õ=W ÑÚ¢“V §J6–ÚbûTle™Ýc.=Š/ é»)ÖX³ÌÄ +Ї²+×y‡Ì8jGÖ™6Î@X–\›·œÞ3Qו:ð •ûàûmý~v†2Áή£ÃÎÒØ©¨Ÿ'– ê>ä01[Öó©=:㟪ƒ“S¬Ç ]ªHÝÏ~.ÀpБèY¾ëqý³²u‡0»‰ ÇE+=ûîEs?˜¯!#Xžf­93ƒš•í^Ÿ–¨‹¹Ü«:T5{¸ò›@¿ L:UÄÚ!Fá ›ˆ™RR²TSpJVŽ3 µ Xªþ>æ›$*ÈÂØi/Ø>lýõ5&Yi§GEÝ…@¥²±Œ^‘… Mä1‰±=“@9 "–•õSS‘»¥?½ÿÄ¥cÁÚ 5ºgþ} Ö‡ï¶ÙQÁ²à–ùj%â”Gxé†L4ÖÒñ÷ËØpK°x]{Ü`‚§¸k%CÖR @Ã00" CÎ+©9þÈ9©‹î¹Ù~æÞ‰é}ÙÁ4 +Ûðh€Ù[.zú4ÀoŸ4¯Oä#“ A%˜jÒï­-Yvé,zSe¯*lŒI¨¹+õ™³û>?ök8õáàŸ*L ²ºxìÍö([oñl],A—íÚ­'—2<Ću‹†Œò„<'Ü»JK G2Â`PŸs²¬J6~Ðàù±i¥·GZ®#mw۳Ď'Æ9A›™†³Û¢#†œ@.qØ$vJ¡­ÊÍ”êÈ‚4É\#b ˜Ê¸©"Uv²BQˆdÁ‡è Äc6Xæ;æGÐ [Q&ÎDB–ä” ·Ç¦T@ÓGºWMr>Øjåé$®¥µf{oÏÀS¨—‚4DjñÙ0%ó[: žÕª-ÿ;ij99¾]í–Îy¸ï7S/_δÖ3rJìÐ¥m8EPÞ;”"d¡¨Ð’@¸ttµ¿€ðâámŠfýù¹¢uþ¹àz͹] *t›/ÉØM07‡a´S&ÈZà¶”äÜh3{ßÜrµ(âàˆ›'ö63h 2XXïðÄq`rÐ`¦;ÐqEQs¡â2¦|k…¶œ‚s® ûÆUD$(Rü¹jˆPP72ƒ#¦‚aÀ¥ T†XZ‡°äÐŽ}ŸÖ xW>ZtÌ­vRD: Ò-k/È9ËñFJñ5lñÊà¬.<}$8Õç\áˆYFvz¦9qˆy‘Àý™&­®á ëÏõ‰xŽ–‹‡‚à Ÿd4Ò?Éxj.r3C¶þYßt,~\âÏŠ±G¥f·ð¡ÕaoYUY/«ÝJà>wß\\þt{ñõ»“C;»±l³ŒµÌ”Ö©ú ,I9DpÔ•ÍÐÚ3eޜÑZ-€¼s©© [תãY^‡æ}‡qÄå Ör#¨Å!ÝÅÅŸ8ð~`¶‰ Çüˆ%%d=Àj(ê£Ði¿ø¢Þäo†Hƒ()úBZ¬Ì ÷#¼„ûÖ=¤ÀOؼ«I¿a †ö~WU„<²Þ´2„³)C…lŸ/­„|lÆ \i¹Û¶´?¯âÏ-²a’˜Í v¹#³†-[ìX2ú)0Š×Ä,2Q&¨†›N™¤=Ê'ì$ZŒº£öPs¨^n9ûߦ¦“…¬s©¡ ìÛ‹w\Ì)dØËOÌxçnÆ3Òv2©é'%ÇMÀ“‘ãOI­l±·Ñ³=’Î1è4% {X˜²ÀB£\š4g?ñŠ` ÖãŒw¥£fëføÒè¦. Õ{ z ×PwŃ*ô$·ât¯dÊCö™ž¡-àˆW²|døhÁŸßr³ö(¸ÓY(•¼nuU˜&>¸ƒ9ô›ÁNð‰C¡ÄíÙdͽèÛÚÅ"J€Z¦&,©Ñ°@»‡ aìJ rc7 ú¢uÝ­-ÛÔŒ§gÞ» ÛF'êoØ<ÔDpNr÷ÂGÌVY^fò »Íq°P®¥0‹Ž1eÄ3¦ü¶oY|YÆçÜ Θ.[#9Æ_7í¼]æU1XŒ'f/`mH·c²øc&1äúiÃõ'AhŒÙ³FÇÜþP‘ÕnÐ7ÓFAdâä÷D^õïNŒISé™÷ÆÒ€Ïä" :¯'M­õOF.Ó¼°·û& 1ôM|'Ö)9 ±Æ[x_2I!9ßm‡`,Ö ¨”qê±€”Æau±ó/úmêoàªîƒ€d5ïv¶•PM_>•cY¼ût¦MFÎ.#ך+˜û h¤§¹hdPú`/÷Taìæ×zx!¥{ô §ó‰ƒûÝ%¯ UÎø÷ý¤‰Y¬ì2¸Èø> ”†òokჯ•·í¯Sp–+,\ov´ì­C(Öa6ô‡+–lò.ã]³^ïj0pþË$º˜É=dú#¤²·Ê+8uwuu€y–2 ¯‹Ž.7©BÔ §Â¤ó̬ÉXcaÿÝ1ðbÁ¡Ïl¯?S=!?ó¾ñ˜@€w‹µl.¡+š‰ mÀé;TÏSÉiœ8Åu8¬¸jøÁ²èT1dªæ.¯¦'(”T§NÛ3,2Ž`quïON¡=Žþ„YËðˆþÊJC•ìÞÓËV:â€M‰Aƒ&CPO{!ò„) ¬“Ë©Ôa9…7Ôж8Ç:°e>E¡ xd¿j`Iiü}ÀÌùº!¾S™ ”ɵ3^]áÑ`˜,±P¾X@k4 r3 «µ õ¶‘H#Ñhú ¥ø‚Ϥ\ÔÑó#gl1Gl÷ã˜G0ŸN‚ ¡ƒE4ÁÜ-|^¤AšöOŠ–Æa÷î&o¬<8«ÂXDŒ)ûù\Ö+©ã½k’`ê]÷w ú(”5œØoBNq§½Ý£™µq m¯«~#T OŽÀZÏoÍà9¸•QøãYò¨! ƒLí?di õ' ÑI/é–<Ôþ»,Œpvü ï§²-ï*©!OÓG)x*i€³³v=e8NdÖIÿ[ Ø6ÿT»_j~t9êñuÐFá–3± ¥sá°G¿…Üc}Ë%Re÷ž \FÅáþ|¨Ú—ø ±\Ó¢t˜†µþC{l¤Ñâ Ñ’z8‡Þútñ_«ôòÛsè‡ðABA›)éÁK«Ì|£ke†ç”î†>ñYÃXÕsþ"‹ò"íSsÌÎ5a”½~…f³Ñå;Oó˜K0Œ  XY ÃÏ“4P6HÒ0õhà) b•í Ò«ô‰L²i÷ègÙ>Ò].¿s,×¹Çiy+ͬ_ËuÑú| r†q1Çä™ „XÔi+lxWÈ]…ŠAÉV2K(V:¶¢ˆ n;ã aAp™Ðù–YX‰0¨=±QáþU2¾[%oëäa'y}—eQn:“ÇæKzô)Ü Z³âJ X›?H1›NÕ[’µê¸áö<5¼:’[²Û«ú,ÚöKû½ë[¹jú´¸‘ܹ»|â‹5`?øãßÿ¹Ç=­´“”È€ج٠Bo\À[pœÞÂq¥ Ö¢P§^*ÑU¥¢œìÀÀ¹18¬ÛXäm,²îM'¨¢‚ï\é2½Ä©èå|ó–!sîRø#Ù«Ÿ%³ø™^uË—ÜΤŸ.9sH‰ˆ9Ó²›Òñn;„íœêÅ1WŸ&ä;…lg®˜W õåNxBzU`£þI6Ð kø ÿ:Ë̬¸ãþòÞ鹕…D½Õìwµ)0@Ëï{¬Æß[¸X $vÎBÉû8޲XX“M’=˜ÜkÛ4͇%±<¢Kf?,®~ämj½÷»§nŸ™2AbûÀ܇«ï'F1*ÓЩº¿MBP¡‘Y]þÐò²xyüî>7 µS·Ý€³u–:ƒpþ5æ)Q´y)óµ  Q}Ò¤bÒÄ=Kœ…œgÓØ=QöÞD@†¡S¿ £È3ñ ø'G÷»/4ü˜ÊòMS3ýS 0bj²Ä- ‰‘%gs ‹0þï§8¢pþÉîoªÿÍÑá®þKñL&endstream endobj 2020 0 obj << /Type /Page /Contents 2021 0 R /Resources 2019 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2018 0 R >> endobj 2022 0 obj << /D [2020 0 R /XYZ 85.0394 794.5015 null] >> endobj 2019 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F11 1559 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2025 0 obj << /Length 2584 /Filter /FlateDecode >> stream xÚ½]sܸíÝ¿båN¤¿$jú”Kœ47='çlž|™Œ,q×j´Òž>ììµýï R+Ùtb'mg–AÉ*†Y‰$J2š­ÒŒG"&bUìNâÕæ^Ÿ‹:¤pŽõóúä§WL®²(Kh²Zof´dKIVëò2H"…8xñöüÕ›×.žŸ¦Ø[}  Š(‚¹®4&ãA>ñÈXÐ6D6€¤WÝêX ½ª7Æ$H°¾Vý:Xüëv¬Kœp[•U_ —¥*t¥6íÄ7 Ú¹Û˜Í6¢{Õ”½O«v4ƒBë„ ìòÏFµz¼~ñ ÚFCºCp`þ÷y×[t+¹†"é?FÕý3 xüzÏÔ`åƒÂQ]íªaÚug£+;_¶rIø…Hè¹FÚ™,'ñ¤ £ŒñoÎh4QÌ""šòÚ`jùRíÆ~ôÕŸ¬­Lÿoȯj;{}d”pmN8ÙÝàp¾3Bò¦´S¨½Ìñ'ëÕ Êþ÷ÊâÜVõ|”Ì|”IQíÙZ #4<†FÄž{t""ÉijÑQ)!$Š@ê>Ë‹kØ™²Ü®;à°jð5¢V#z®Çÿ+5Ü*eyŒÿ(? ¤\§²˜ØsXRk”*-Á|¿7 já@{µå%7ÓÚ¦›Ã‘ÑJõóidÕã ͸»2¶#9ž³¼wlÒÙz¡ªsÚ€³w‹z~S‚œ0+L—j“õ€(•¥BãgqTp»Ó âל|9v5ªUj—¬K»ÍwÎ"›<Ø¢6nѧì2ˆF›Ï<6Cá$ÜÙLÕ|ÃfÒHžXôßc…¤2q 0‚EnÎ=µf k)Rïc}LCÝAKãnÆhpÖ°‡awOËÚ‡BtŸûìrÉ$s쀺mÑ|eP·Û-jMó€×\ 2J¥H–æ¿k›jhmpQ_öyÓ»ãIÌC“†hé0€û¯ív8.®ÛªpjãÈNËA5C•×w£ÒrÔ˜'ž}è}Ê ÊR§PAØ6Ƈ€ÔAõ JÜ ß4 #w<ÅöxÛc}_ä;5¨Î ªCV;ÚEy1ØëP•hÃûý´½Ø¶Ã4˜€TÇJ‹æ}±¼î'Šæ*Õ9‰M([L€[_vP5E=–naÕs-‚ š9[¼ê/;ÜÖoc*\¼Õ'ë!G²+‹ó[wø 9ÑDdBÃPAæTô6½ºP¡5é !Ð/ãÁñ~1¶—ÛƒºSŒökxWï9Û•“æÐræðëçÍ¡3…½¯«$Ó˨”_U)sôÀ Ö§„ÀA;!<Šƒ 44¿÷ ÑI=PXMÀìA}ÍŸê’B |‘p¼í«\9¶XÓßj e>ßœnšJtRG#zÕþS^–ÝåOûNmª/µj>âÄ?Í9RŠƒ¢`qŠ—ˆqÕnLJàÄŸÚîSÓâç_ñï£ïJ°‹÷]{S•*¬¾lº'Ð sºèSiP ˆ­åÒèu2õ}¢¨²ùnUêµáXîñö4 —Z<’BÓëO&±@ç}?Ää®M¿1ûV‡úÂËí1èDG߇€pë(þË1Ý,¼Ÿ–å¦_ú³:ôÎ[à“³£?…m]&êÈvµçÆ/»šI!êÐTg QÊ™0„þb¦D”¥©XÍàGA.÷m7Lή?¬‡_–}±Ÿ&ôÇG¾uë!b@í1„7É\†ä¾ ™Žp& h^ù]’Õ þß“ÆLg ™÷›V—þ;ÈDYJùCGüŽ epß<àº3æ¿­þãYþ_ùÏ$Çòn!ÄÎn©};¡™W}×—í5‹R7dœx¬Êmè5+ÇÏ"βÄkGÑ,ÁV³„E"å>Í:¢^Õ>ÕŽ!/ ‚S‘“%<]—zÀÏŸ.ˆW—ôÇuù„ã|’.i ¤ÞS{}jÞÂ}ÛÖwnçG÷åúP—ÛÓIŒû2¾ªúæ&¯¤bÖÆ—’Á}äÉ9cÝ‹(—é1×”ßÎ5_*Ý„Õ5£îO.jÆ}¾õñw’е·´!2Jdìê>ËÀ}Z4‹’4£³*ÄñC†¼™2>‹k¨ P*4%ü› üç}ß•­?àÛ´ºpÿ°âص¦‰iÐ@™‰3–Il1CÒ¼Ù,VbçÈðô×BM‚f‹Í´UÈ¥.-ïGÓ¸aD÷W‹J¯U¥ît2ÓjÑ*gÔlÀtuÙlMW€9žzDs¤ŠVóiÚ=¦ÛÁƒ·X…3ÛäÖƒ]kJìùÎ’™¬A“ªsðçû}-/æÔ´µ-åÚ„½ûZ?µµ-ènYÄ-ŠF&®òÔú/£¢m6¾.;›ŠT[Á먒 *ï7`ýõ]&ù·Ì鎔xÌ0e¶ƒ¶(Ƈ¹CÁSݹÝ#¤V7ª¶ø›ÓÝq}Ûªaô7jHmZK¾ÒUŒ¥œû:µDDD0WÛÞTêÖç\<’BÞ“JÛLš¡u?@?d2‹dœÞ‰<ï“Æ”y´'RóØ’WØí’íϧö]@‚™»ôwÏŽÇ‘LÅcrro{|PÈסÒýö·Ûk[wÐAÖ†%J‰X ¥k(¥ú˜C—’‘¿¶çƒ>ós¨û¤¤_¤¶> endobj 2026 0 obj << /D [2024 0 R /XYZ 56.6929 794.5015 null] >> endobj 582 0 obj << /D [2024 0 R /XYZ 56.6929 585.5141 null] >> endobj 2027 0 obj << /D [2024 0 R /XYZ 56.6929 559.3376 null] >> endobj 586 0 obj << /D [2024 0 R /XYZ 56.6929 223.3725 null] >> endobj 1853 0 obj << /D [2024 0 R /XYZ 56.6929 191.4217 null] >> endobj 2023 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2030 0 obj << /Length 4419 /Filter /FlateDecode >> stream xÚÅ[[w㸑~÷¯ð£|N‹Á…¸0yêÌtÏ:gÓ3ÛídwO’J¢mnK¢"Röx~ýV¡ àETÛ½yØã…[¡P—¯X^ ø“×ÞdBùµ+òÌi®×»+qýu?]In³Œ–ÃV¼»úÝGí¯‹¬°Ê^ßÝÆò™ð^^ßmþ¶øáßÞÿr÷áóÍR±°ÙÍÒX±øãí§‰RÐÏ?úxûÓ_>¿¿qùâîöçODþüáã‡Ï>ýðáf)½‘Ð_ñ:|¼ý÷Túéóû?ÿùýç›ÜýéêÃ]ZËp½Rh\È?¯þöq½eÿéJdºðæú>D&‹B]ï®r£3“k)Û«/Wÿ‘Ô†®sò3ÚgÆ+7#@¥æhŠÌj¥ƒï+\4•ƒ¦JdyÓ‰ÐæplžêMµ¬½?rãḦ·Fqãõ¶<µÕÍR»b±©ºê¸«oäb_µDz~¬ºÇêHP‚_l›u¹%Z[Ÿ äþîf™K±(×]½ Ê²¥ö»²íäâ¹Þrÿãô‹ª=À¤Í~ÓÖÝ#°Ç ¤2!5ˆLʬ0À<²^ï×Ô{Wí»À°‹ßš}E¥îXîÛûÀ»0¸=Ó¹ÁCýiÿæÎ-nïã0ÏÙÌìšö"s®àx‘Ÿo–̳"×± Ï<]x‘.Læ”*Æ2ê… œf±+§«Š(‡0PЗ ·AUO±Ç¡iÛzµ­2ÚH\’ÃÂpœÙ…)í@¯EÎ\…É Jº_˜‚áKbO'¶[þlø÷±¢i‡ûEüŸ¦‹Ô¼H ì—$$•™T6)’œS$ÜD%i­ÞAïŽ °hä³`BÒS¹=q±áæÝ¬…Jg2#MñFu™5:ÚssèêfO£×û~â ®ž™#ý>l›ZC …®-}¬Àl¿ò0LÓß°d´Î¤E·>T4`ôŸ%ýlªûò´-Ç.šú,·àÉ.{&Yd¹×ÑÙÉ\..ÛdE¯Ñ3)¯¢g nIyÙ»%¬dYÈè–62`Uôn Û…UA£’Û²Q+_DåñjhÞÔkÖê`[sQ˜±ÔÈ)gÇzl÷dm;®$m6Ñ!m¬Øf²æÚõ-Ó[¶LËÚzvï†òº¨­PÛÜ÷<Ìx&PÀ\A8ë¶ykδF¯Ù}çRg ]=6;âK™¨ÃÊ’%é0Ò’CEÔa(†ú ÃR2¥¤Ï¤­à‚Õâ¶#ê®|áVÛ¶áA™òjÊ’•9ŒQeÂ@¹ß „5¨Æýd€ œ¸“ï’© WGæÄÊ¥6ù¾hZ($1`“#ý²° ³±NÃÇ}¬ïK™ž5ÕÛÿúˆLç“>€\-ÔâµôÁcBõ†«IͰÝéphŽ\ÛÌKZyêš]ÙÕ`šÛª¼'?¥U„9˜÷= ‘Qñ. ×Fºë…;+ÛÀrA~= ™ @¡ P€ý)òP¦ö­êÔëG*ï‡+,Ò šl¨~Я!¥Mœ¾éþ¥<Æ.¨J› Õ¬¢Üû~ÆsD‹Ea¾‰–©ÕÈÀÚÇæ´E.-°»}._Z*?7ǯhÖ¯h‡Ób=ï`‹K±Ì« 0®ys,Ë(5F©ÍF “'òº»qE1 ¼®šÃN[Üé¯aAž,WÉp&µ#è$M3—›º-©©»…’(Þ'‡RE^Ük›ØjÕ ”E{ìP&ÝB=ÔVRïx²†k“æÁGMàC²¥ã|¿–;Ä͑ǚ9"_……ûžùS鵜EÍ¿«ÓÃà ýÀ%ÖDz}¬Ú±Z7Çã_œWlÊŽa/J,œÁøè­¿?ø\Æ@Tmösê¯òÌåISF#ý7héé TR"Ô˜Î-I,s’ Ê®«v‡Ž»5ôË“¸Å‡?}á”dmÝìv§=8½à¡)B²çÍ$Rª3rú#Ü|„h³aÝÅ–½÷ ψϺL(™GŽA›[\ÚÀî«›„é§J&‰›´…­+¬ÕӃΠËtíAÿ!ƒYW1…⇹­ƒÄ ‰·îwäm%è·‹+ðŽð‚Ýý©;%©'´²­J@ázõ®~#Æs¦ˆ<Â6}S[ùÈ|‚Dу1ý–ãG„i‚¡ÖWm[>pãÁ„c=P™Ì“5}-—0CÇÀÕ~†zä‚ã4âòjzú–­%ɯP"â@U”Š>È‘ݘb­Ê5ŽØZÈèµpøxØÝjf!Fl¬ç8T Š3Qõë¾yžž[ CÞ sàäâ,äú¦4¦\ð5Œ\IgÛ:æ4É×Îl¿3™6¹zmûEVÚŽ14LçοÑ„S6™C~Åi[/äôÌ-1ž±Iïù€Ê‘4”æl=Phà"‚dò$Ù<^Ù mÅèC-¶jè¡1 5tèAýHÞ‚« 8æ}bø‹¹NCÎ%º7PÝ}WwœvÍ×j?M‚0Óºtª`³B¼Ù±è¬8“§ì´ƒç;ò™3jT½«»ÙÄÄÇË©X”™—á|}¢ ”ú ݧýèÌ|¾èž"óÍ–×Û-í7ÀG×4¦¿/òRðø=Åg¿2Ž• ù¡ìÖñþ‰—0Z5žNÑÑ?Þ=¢»Â_K€•2zo‹|ñß\CVërO…€ï_èƒjÃ…t°*‡ÄÏÅó(„  %mÇà«iéæÄ>ÉUÜ‹d© ûe@nÝÜñmê52 òB ng‡ñÂL|ßdNeÂ+=P„)!…A¿Ú£çM¸mÎ/,Ô˜ü 3&"P‹"z;ŸÏi°ì)ÏAt‘ä?€ã8Eˆa|[.2mCh(ܪšRÎä‰ïÝßîó‘ƒßÔÊmÒ‰xWåŹ>¸H °?íVt›-ù¢. ÿuŸL­Þ¯šS°&'Ò¥£_:ŽÉá$#ùc·ñ9#´ •ƒœ—2Αç.þ%¸.åó‰V\ÖÂO¯zn¬ˆ£@;¾©uÅ„r]rB1yšW,¥Äà>!ñ¼<°:Ïj™Ë3À;ÅH#è˜,ŠB¾ñàTåõµz¹pºm„={¯“ŒŽbª‹”rÎRu–÷¼Â$ÓWP À«Îâ*ãaÿ —}Ã;(•ÞûùWPË4âr8$=qçV`ÕZË~æ`,s[ªÌ÷Û´©pÕûà:rvù¥û*-^›‰¦Bè›üÔm  ä÷'a<™1–(VàÔ¨8øÈ ¤£9&~`¯ ¦rñÂr\SáóàYYj¿v8Vv>.²ñ¥Š¬ãÑrfθ±&“R˜9{Ù½ÆÁt,–ƒ¤Ùù”OîÊ-åpH{_¾`aôfËÛ±ÿrJ,þ“¢CàÔƒŸth~£Ó¡á7f]Œ¹Ñ› Jn`c¶gÉ (ÝdNƒÇ û²?CÑ&]4V0ø}¨öÕ± ÇîøyjI &¾ÁƒN¨Ç4à(¡OŸñ+À­P8ªý&6BÅlFC=,]Zíïçòõñ«˜pX?Ôûrð¡7o¸Õ9q:G5ýÓºš±þدRvõ°u«˜">ÆÁP>xà<{Ùø3ÁÜþT!:sÏP8Dç˜]޶©%nß{Á)•Rs@ 3Žõ\ª é›V…íJ]ËtV=3îòÉÎ íñxÖ¹³ÛõÜôXì6ž-˜Åí/O9‘×’å.Ü ›l6œLñ˜”YXÎ,Ìà=š,^NNÄÈÝŠ<=ó4£gžyÄçÂÄCÀ|ò¶ÓLßvú”·£ |ª¶Qm–9xþ ¿ ŒFëEÊxÜü|ÜKÍ¥&³&eßoÛòeê52Çèàƒ£?T8~÷ôÀÒ¶<®_t|C€ B÷LM^ ©ÉSXì{aYÊ@:f”ùnÓYá¢0Þ°žÄºëó[‚]ÚC.ä'yó¦êÊzÛ¾‹f<}`µ©Úõ±œöÌ^¨H€3߇¯‘:“¿j¤Æéÿƒ‘*™®èÊf¬s!2åµ»–9¬{9¤æËAûó°}6ê7Ѓ~Þ#sgüX€V«!?gà!5z…‹éXÃóV|³€Ïßêw¥Nç­¸¶Ë›i §^÷¸)¥8¿ÎfVLâ¿ÉךèkíE_kÞèkCé¾á#:é\æEn¦©^G¼¸t´×Ægהпé…öüÃì`€ƒÇþSO‹OýÉ®]N. ºòj/]’+.zZg2U¤we¯n²ÎD:\Ç=À§u:“§u ƒŒý“3þvø:³Œ£hß¾ù܇û^ò·x?é ó}úf$XGVf—Âïâl&´ToLeµMOþÙošS!„ý¦9Á€&O ßpÀ‹«s:EÕdM:u„S@›þ‰EÄHîø¡ÖÑ®„.k M†Ö¤ù!V¬¸Á¹øÀ¹™C.Úöw$Z»˜xhz­€¿#T¡íÀ€ô_2 cÙ€°K€*ÚÆjwaÐUÌe¨bñî3yÉ×wÕØq(ÇÉVU> endobj 2032 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [116.0003 242.9625 166.1092 255.0222] /Subtype /Link /A << /S /GoTo /D (tsig) >> >> endobj 2033 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [399.2874 146.2613 467.9594 158.321] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj 2031 0 obj << /D [2029 0 R /XYZ 85.0394 794.5015 null] >> endobj 2028 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2036 0 obj << /Length 4095 /Filter /FlateDecode >> stream xÚ­[Y“ÛÆ~ß_Á·pS"4ޱR©’eI^'Vi]•*ÛåÂ’Ø]D$Àகã¿ç›é™!.’ë(ÅÌÑÓèéž>ä3†ŸÅI”h¡g©VQÌx<[n.Øìso/¸ƒYx Eêëë‹çod6Ó‘ND2»¾íàÊ"–e|v½úqžD"º6õ—wo®Þþðáåeªæ×Wyw¹1›¿¹úókj½ýðòûï_~¸\ð,æóWß¾|ýúM%Ç×WᄀM#H?¼~óúÃëw¯^_þ|ýÝÅëë°—î~9“f#ÿ¸øñg6[aÛß]°Hê,ž=¢Ã"®µ˜m.T,£XIéGÖ/þvfíÒIþq ™ˆ  1ÅÀXG‰Ò2ðú¾0›(ï€rIÉà70»âû¢iUS®p¯AÊ x¹Î÷M>%É|U´ÅnSVEcúéüñ¾hï‹M¢Eu½Ì×€…|¾{ À—ë5Áä«•kÐÌ»WßÐÀëoÞ}¤V½m˺¢ù¶¦±Ý%ÏæD~cH2®³Ù‚óHDZ°D7EÕ’híBó´Ô¡Ñ–ȇDrŽ• M՘ؕ«¢™â Š£Lrþdª4‰pS8bòv@ÌCY<ºwïÜÓoíuñP¬#Ú¦`q$Yš`ŸY„³ÍOK[°LHmÊvŠR%  ;V}a£6:n*MÇY&I£E’6 z|¼º¦†4Z‡=+'¯8çÇÊÚZ±Zv$:ÊèOOêtH¤?‰j ë8È0'e-`†$WOe`KÞ5ð[Q'žQp¢6¯ÞÑÔá|K/jKä»|S¬d“¦ù ¿Cß°Ór„§I¤35`‰?ÚUíŽ^³ßnë]k_€îÍçÁ‰$¾o궯.t|«Õ›.#á2/\„Û?Ð^»ZºoÁÌ…Lqˆµ^ÄsÆ@Q›·eÓ–Ëf±¼Ï«ªX»=~ÄD± šÿv—o6ùŽÐ«®È€]@›²˜“ø¼è_–±<´ûò#A@-µ~b1scÛ_À•uþM(8Œ~ª`Úy”*©,Šß»)ƒ{?L§Õî-F^÷¡ó³“;¶ -' Ì×ëúÑï ÌŠlW4Í/›¼]Þÿ²ÆÎÝÄÚ]ôÌ£åÓûŽ¢èEŸË®´OÍ^²ÒO” Bì7 ù›â'ÆDUÎX8¤?4ù]1¡°}éµ i&½¿œ"fŒ7K"–ª´³ÆÑ)¹€þ´ұohdYo6ûª\æD:\Ëü°S`”Å7xµó¬ˆÜå '8Œ,ÎäÐDîš¾.Þç´\â\ô';§~YÝÖ»M~àv};°Œ×ØÑú£Ôs]Æ6É8é± F¾¬Ú¢Z¹9Ë<-0 iËâ×òf]ôçY# Í~Ý–[2d4†¶Vu[/kËmûV‡ðÞ-»Ý·{Ø3 dþí«qt¹ßXÕ®1b^W¾õíõõ{Ó’îb´tÏ`‹ág|~ÕÒ¸7e80fÔÙ|´\X‹–&ä†;¦‹­n˵µíè=–í=µÖåͯ›µ ä¹uAXø÷¦®Sо4§JY³–¯{ãù§ª~¬h"oh˜ fŒ T©åà„FÉ ÚͳߪRœq9¥RÊrÑ,&Ö°TÉÛ–Ô$žÃ¥:jË[)KoöåÚ fÕNÂ`B°%ù@wüǦwùîó%‡.>s~tﵨrÕ‰~ X>.bóÛ¼\û1+'»˜ž©ú¸ö¼¬¦x ‰g±5ÒcžÂ´éŒ‡€¯®Zz—!FhoƒL'sU[ïŽîõ«÷Ôoêå'k6Ð6¤¨ÊêŽ`r7LÌÂ@³-–¥1ÒÅj‚d¡d8>P.·ÃLÂC0ËÂ;FÙÓSR0fÙt¶]””]u)“1D¯S~x³¡Ð™1S˜ö¦ßÚÆ§³ ÅÚ,ò1 TŒÜ3M³ÿ Æ3,Pq ÷œ¤}Øèfš! 6Z!%R†ryO*¥035ˆ£–öÄgY°LÏ}ÿêýƒ¢kªh$¡–%ÀF@ц»©:ÊX0?ˆU”`!4ëK0.º(ÇŒÅéˆ2޼>€b¬Œ4Sž³p¸ã€,M$’¸Q|9´§ˆX:6YÞ•Í' < ‡­Þƒ÷ÆïÈY”2ö7ô¤ã (/«ÌX·Õ’œ•“çAV/œmE„3™ üM «³4Ú˜æ4v†RÂþYבŽqGϺrÌZ{knéI ŠŽ~×iñH*ÌJ25¿¾ÔpÛ4OVÑ[:Hé:{ˆ :¯q>ÂeÖÖÌ«ÉhÓô¸%ä–2z†3©Tg_|ZÆEåø´r©áxxzxóéÓ žœ9­B¥ÞM}õÕ”“rGƒ@"Ÿé€-eß^Ýúœ”žÚ`ÕùÜŽù}6„ÉX–‚lëŸ}EæàÈ}¤ G^žN¨÷¢‡‰]K$*aÚ)i|TIãH§i2ë@YŒDð¹÷M1Eòø`iñ,åÇýKšF+dŠ5^ì‹Ý‹C¸èbœð.03œ¦vÂÁBâ5Iw ”‘’ ÷B„ŒÎzŸ¼…þo[êØDEBÉ·>X1ôèe9èb é‚u :enwå’L!ÆlõDú‚“ÅnLX¾žNL”i©Ý(3ŸÐŸ4JS÷êq6=PóW]i_[^o"dÃ_˾mímOgn{—|¾¦¾ËK©³5e¦–v¨ÓùMN§ 36¬ÑÇâ{ÁX”Šà¦\•aärµ€•“™ëCæÿÅ.×c\tQN¸\mr~´˜!ÓAF1'¢.õÿ#2`‘¶F3¡ˆÉÒX•@X'ÉBH°†G'ǹ#Ï3=¬k¹‹L5öÙT@ ˆX‚ÊV3ǯ±!R¬ô TD^Þ¾ˆw¢ê;v³·”¸lÜœM¼L£rP¤¬–M’¦¢ÑW î*­ôÎ6/Ý ±Å¦lË»HP±,ú¥˜ÓÅV篶®²Ý•H©×”ÉNæ™ï:¡óP=­~[FG*βqFßåΙóO71ÇΗ„»Í”O«ywðŸÆ röA©¨ïó)zE&'™_ÃØÚG÷TI•L«™ÌòçTºÂœ­8aø!ß•õÞ- òZã˜R¦5wnlU€ì•õ`f¦®EÛøá ûµ]ÅPÑõ™¥Ç•"Ü’M4urßÐE×s‡xþPìÄsA î¼»‹ÎýขPͪI;«Sp"ãÇD(2ãØT<àÅ †cƨ~f1Ä|Z„r\ ã°Ž'å ÎjŒí”Ù^G ‡Áî5i’÷,¡@:õ_I¥qWϬÄ\]êâ'SÅì|¯[qðI»&ܲšÐ(ã>4”M:B)ÕŒ¸¸z[W«®Ò{K0ˆŠízqtU»ßU4“Ó°©JmÝûÐB‡ û¶ÞW«CýêÔÅñëkøTT‹ÚÞ©IsOzÓmÓ/ä´¾ÌÓ¯Þgɤ»Å@p5hO†r)o&ÙQ£&´ŒDj>^ˆˆ?¯~Å¢»dB#F˜ÏiÄs³Ýý¨°3t'$¿,ôPc²z c;¦ ¨s”j•ôO½¹Vð_qÍæûm[šïLÛú^ÓXçöÛ}H}ªàò/3eÖ™‹‰g“–LGqª[2„PL0è·’Q'ú¼ÜüŠEwÉ„ÜF˜ÏËØ1*¾JúÖ³OâРy¨1Y}ƒ6ÂvLn†˜ûX»#-wW—Düðq»²!Sø2¯©×VºþŽòÒÔT „G…Å’(aÇ•Œ›{PeTAò(5_ œÍ—üŠEwÉD¾4Â|VXÿ¬«b¤c2Uðú†™ÁŒ)êçMLGÝX&:b2„‘fïÇÓ8bi"Ž1\!N‘ZЧ3<¬8Ãð1æÃÝãf† ¾Nš†ûŽ¡§Ù8L\ (ó¥–J¦ã€µè‚Å1ÆödµmõîÙ*gšûVÎ+áNËŒ'Q®<žgi$e’6~*¾ö+ÆLèÇ×#̧« æ¶rp¥ï„¶)6# ç 2Z¤¬œ!wÕ|:QP‹.ØXhcl'…–t„ÚêÝgÉ&¯Ãìž,„ hÊã.ÇxÎ8ìñ¤Ëq+Æû¸œ!æ³V¬Í›OÍXíá°–B€:#…1¶'«Ž¡.È`áÍØKqS×õÜù/ûš ¯}†t»_‡ÓÛ~ÕOž” M¥Ï~ëfZ7E÷;ôÜ}Ã^:¸ï>Ò_GºuBu$¸Œ^)}T£,¡ù¯@š"LÎÇ–aÁ¢³bBŸ‡xóßÔ­0×0D=²Fq‰‘2K¸žTÒzFY[raI ¥_ŽP©†§¾‚232Ó™.ãr`óמ£e\°)æz†ƒ.ŸùøÅaÁT ·õ´lž?ð#a¿ÔX¯TŸºaHâa†õC’¦™°fáÖ±çû8_†6Î?òÇ*GæßPt³ð©øÿéêð4]4ÕÉÿS9šl6zøY„ËÅ{$²> endobj 2040 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [188.094 261.9031 321.5934 272.7174] /Subtype/Link/A<> >> endobj 2041 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [349.561 261.9031 500.9931 272.7174] /Subtype/Link/A<> >> endobj 2042 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [353.8228 206.2321 511.2325 218.2917] /Subtype/Link/A<> >> endobj 2043 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [55.6967 195.5223 69.6444 206.3366] /Subtype/Link/A<> >> endobj 2044 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [283.6482 195.5223 453.0131 206.3366] /Subtype/Link/A<> >> endobj 2045 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [292.2758 153.0518 503.4838 163.8661] /Subtype/Link/A<> >> endobj 2046 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [263.0245 139.8513 474.2325 151.9109] /Subtype/Link/A<> >> endobj 2047 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [170.0458 128.5637 375.2762 139.9557] /Subtype/Link/A<> >> endobj 2048 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [467.3969 128.5637 511.2325 139.9557] /Subtype/Link/A<> >> endobj 2049 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [55.6967 116.6085 207.1288 128.0006] /Subtype/Link/A<> >> endobj 2050 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [386.3404 116.6085 511.2325 128.0006] /Subtype/Link/A<> >> endobj 2051 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [55.6967 103.9858 117.465 116.0454] /Subtype/Link/A<> >> endobj 2052 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [261.4892 103.9858 466.7196 116.0454] /Subtype/Link/A<> >> endobj 2053 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [320.7803 74.3472 478.19 85.5301] /Subtype/Link/A<> >> endobj 2054 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [179.1557 61.5153 396.3412 73.5749] /Subtype/Link/A<> >> endobj 2037 0 obj << /D [2035 0 R /XYZ 56.6929 794.5015 null] >> endobj 590 0 obj << /D [2035 0 R /XYZ 56.6929 685.7406 null] >> endobj 2038 0 obj << /D [2035 0 R /XYZ 56.6929 660.4794 null] >> endobj 594 0 obj << /D [2035 0 R /XYZ 56.6929 565.702 null] >> endobj 2039 0 obj << /D [2035 0 R /XYZ 56.6929 534.6664 null] >> endobj 2034 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R /F11 1559 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2057 0 obj << /Length 3036 /Filter /FlateDecode >> stream xÚµZÝsãÆ ÷_¡·Ò3Í]îò#étƹøRçã’ÚNg:—{ $ZbM‘ªHYq:ýß ,°üÖÉ™¦w—X,Àþ¬,fü³H»ž«Y+W{BÏ–Û o¶†oß\æ™[¦y—ë«Ç‹ë÷~4‹Ý8Áìñ©#+r½(³ÇÕGçÝ_o~z¼½¿œKí9{9×ç|u÷ák‰éñîÇïï¾ùùþæ2TÎãÝhøþöýíýí‡w·—sió%K81áýÝ÷·D}sóÃ7÷—Ÿ¿½¸}löÒݯð|ÜÈ¿.>~òf+Øö·žëÇ‘žáÅsEËÙöBißÕÊ÷íH~ñpñ·F`ç«™:e?íG®Žd8a@)§ ¨c7ð¥o ¸¿‘“.ËâÏ“ëÃ>©³²¸œû¾vêl›þâiq…»¼~/DG–ðå )5$?ÌBé»aDg}Ñ̘w§Œ}1–|ÞuR=€KRGžh8L3Ì4VªŸe†²>—d¼0îœÔí¤ lR ౞N*.¯ƒ¹‚¿>ÁsˆŒØ‹(áa %À£çyN½?Tuºš?§¯ÕM°ZºM‹šË¨}²Ý&{’Û³>ˆûËרГ€ìÁ 1Z=}«zŸkb+Ûnõst—ÿK#ÖëÇðÇ1ßï—k]×ýô‰Œ=©û¾ñ\þÜ"—n‘«õ`äŠPÐ^nÌj~è0†…›`^–åž7µ+‹•É)8lÚ$LÌôšgä1¤ õF€ZÓyžCì˜cÛøpˆ’ôU àÍ+Õ%=Ó_ay"‰uMSVyZñžŒàyÜ$ÌÙ‰|J‰šÚ8äDjçRN•P$¢Ï½ØyȶYžìóWúJ ¹6(Pu€ž¶N¹žŒÞl¨ûlyUV4<Þý¥[ÛÁ ÖÂXž6þ­& ò¾»ý‡-¨†Íþý}•ÖÃèoMú'ïÁ†Ècfã›`ˆÏGý&ƒôdài¿Ýj"&Š?FLG"BˆB¤¦Ñí!¯³]žÒ§“··ÏÒ ó‚$I–›fn… ‘˜C.¶ÉÉH0v^:¼4\$ÛôŠlB¡ÊA ˜é'k\ÏWÚ"S].Ëœ‡’|©l³5ïŠQLÚ$ÄW äÞ@Ñ ùhǧvcïÝàêÜ›Ix.µÁ ¼¡åvÉ2µúÔÉÂ’EzÌ3s\p&j1‘1–É~Ÿaå×ÁËú°·@ÖÆ+¢Ýº(›\Ñ…¿ÚF9…!òŠÁ¯0nqp›¼öƒ¯ÚåÇãag—«YV'àÍìÒˆÈ&lý7†$á’C’R)O:1@ÄR6` .wDäéKš žw2B®„žzŒ´• æxšÐ*H#,¬ìIìâÊXõ ÇK–/céðé¿{¢áŒµ5ÅSW}š;‹²ÞÐÈ.ç2›Ù¤¯Œ4Êêq?`:&dµÊ°bû1¸Å9Ù+ •Ï&“ÖdÒšL¶&“}ÉY…WÆ0-Å+ Ê™wM*û\ qb}É{–d2š"(ºªËöF£é#Ç*Ü*k“€œøaÜÞzv&Bí²ÎŠ$o'’i¼ÀÕ!4=Óø•ê@äêj*… ¨"¢àü&©ƒÁ&AºÉ|ð$°AÊ=Wïh”9Áxµ…ì½1· £?tÕÅgÈYÎ]MÃ5“¼*»{[–~KyYN÷³y¬à)هŦã%—¡m}Fyá«Ì¦‡fÛèmÓ½L“ŠE*Ê~0•ÓeÛQÓítÀ×´ÍÒŠ¥n¡†Ýf¿±˜¦/¡lØrý7„¶Mè4À½D;híáÂb¤tOýYôø·@¿xM¹û?ÿÉQû÷XP3ûQ$§kÀ´éûØX)ܶðð—?-!+uþË Äü'5þ•šÿni¼­ÿ‡Q°endstream endobj 2056 0 obj << /Type /Page /Contents 2057 0 R /Resources 2055 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2018 0 R /Annots [ 2059 0 R 2060 0 R 2061 0 R 2062 0 R 2063 0 R 2064 0 R 2067 0 R ] >> endobj 2059 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [192.2695 755.8266 409.455 767.8862] /Subtype/Link/A<> >> endobj 2060 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [114.4067 744.539 325.6147 755.9311] /Subtype/Link/A<> >> endobj 2061 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [412.653 744.539 539.579 755.9311] /Subtype/Link/A<> >> endobj 2062 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [84.0431 732.5838 151.7891 743.9759] /Subtype/Link/A<> >> endobj 2063 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [332.5774 732.5838 531.8302 743.9759] /Subtype/Link/A<> >> endobj 2064 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [224.5893 719.9611 435.7973 732.0207] /Subtype/Link/A<> >> endobj 2067 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [461.1985 537.7852 510.2452 549.8448] /Subtype /Link /A << /S /GoTo /D (DNSSEC) >> >> endobj 2058 0 obj << /D [2056 0 R /XYZ 85.0394 794.5015 null] >> endobj 598 0 obj << /D [2056 0 R /XYZ 85.0394 693.9252 null] >> endobj 2065 0 obj << /D [2056 0 R /XYZ 85.0394 665.6028 null] >> endobj 602 0 obj << /D [2056 0 R /XYZ 85.0394 587.0463 null] >> endobj 2066 0 obj << /D [2056 0 R /XYZ 85.0394 556.5821 null] >> endobj 606 0 obj << /D [2056 0 R /XYZ 85.0394 351.6215 null] >> endobj 2068 0 obj << /D [2056 0 R /XYZ 85.0394 321.3167 null] >> endobj 610 0 obj << /D [2056 0 R /XYZ 85.0394 242.7602 null] >> endobj 1591 0 obj << /D [2056 0 R /XYZ 85.0394 212.296 null] >> endobj 2055 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F11 1559 0 R /F42 1338 0 R /F21 1034 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2071 0 obj << /Length 3394 /Filter /FlateDecode >> stream xÚ¥ZÝsܶ×_¡ÇÓŒÅÍ“cK®ÓÆIee:Çã¡î(‹<yR”Nÿ÷îb<’¢,Å{ ¸Ä‹ýüí’êXÂO['œ×þ8õ‰°RÙãÕæH†goŽÏYÆIËá¬ï/Žþrf²c/¼Óîøâj°V&d–©ã‹õ‡…ZœÀ rñê§wgoßürþò$Mozw²ÔV.ÎÞþã”FoÎ_þøãËó“¥Ê¬Z¼úÛËŸ/NÏé‘ã5¾ûî5Q<]Yôüôìôüôݫӓ?^ôgžWIƒùrôá£<^ñ8’ÂøÌßÁÊ{}¼9J¬61&Rª£÷Gÿì< •Ÿ’B§g¨õœ­ÎhøÕ`¢R‹ã„M^矋õò¦¸oyîpQçE’dOn»¼+6EÝ, ÈsÕÔ]^Ö-Ýåt©Ê–7Wtí® „=ˆÔÐõ’Ÿ0/à.KyÕÔŸéÁ]Ù]Ó¨¬¯šÝ&ïʦæý.›}‡,/3)Ò,ÉŽ—p4o­Ì^7w NPlØ_§†÷GR¾;QÙ‚ÉÈ / º–uÙ•yUþQ¬ilØlÊfGä<Ò¶÷½L‚Mi…ôYoPHƒv –M )(¥Òhä|¶ïö½¥ÀWEÞ-Q6ù= òª öF ñÓ`Y–-ËN- „ÛE|íxÅ`í zPT妬Át"—Ý5étjÄÚ—}I”›vç‚eX•…¹¯šº…©dqxdô»ünN ýì`¡t6§? ŠÚn‹|×ÒM §ªÀ á&¥`€3æb•É„õ22ÐíÀ gB`bRÏ“ùTëò ErUì‚q§`<:ãȃ-I­-êUÁæ›,›Är¸øG™.Ú¬qMD E‚Ø[)íyøK†æqׄýÖ3Ω|*4ƲoôNC17:œâËŠéeË,Þ]󣼋#50œs Zjg„4™» S{=¯>HÞ˜gjÏ sˆK(¿²Þ´xð$¸Oò –:Éa5¢ïarÅS¯‹{æ¨÷]¸a¿hné/jq(ÍfF Z{¡“htu¾)Öø¹šg:Mm609 ³H&A(¬G°/—ŠÌºdl_,mðtOr…ëœ\+¬ýa5IÿÐ-Ã.-]9aan¢=Q‹¨xŽÁ%œM#€hØe&›*8ž×qÒ_ÉÍ(‘bîæ])чS2¥d¾ºü¦`RÐ="‹&gÑp÷ñätÓËV'ˆª¼Ëvwù%DnÂxy½¦Èc×Ñ—xöŠ€¶n‚QY„*eÝuÜ ;šUѶb.ÚT^@Þ h˜Q,˜“uÎ -oF¸F /]nЦa\—“ þ.½ˆ›_€5#;Ÿ9½ñc0¹™ˆ”*‘9ûmÞ eTŠ«_Ýêº`>»(•×ïÞÿýôß4>?o †tFÄVÆcÍšÓÛŠ°’Ë^îHƒ0ø£©y”o‹ß_ì"í|Ì!Ü›sOÈO‡ ‘ÞaÐn‹UBÛù3ì߸ç×.¢8ɪá–À2bEQê-l¡ò „•ö FweUÑè’)cè›úáÁÒ˜ë`p°‚4ë›%YoÈ&Tÿ”EN( Œ’Ò˜-SÏ¡@dJ@ ŒÍ8yݵ!,Øv/‹iê“ ¥„`ž!̈­LLõ+Ñÿ ;BÀXýæ¹±[ Pê¬+.¡zI‹¥()ôvãd=¬³5+Uy3 ”Vy÷mÕî šΧÓâl*‘™H•JÇ6õÈNð´V#¦Žp"ª«ùRwÍ–µ »âÿ_ÍÁM+¡ðN¾ m"øhxkDÂ1Ð10¹-™Îb1ädÊŽåmÀu.º£vèˆ€éªØ€q%tõ¾”‡ nØ‘`4¨@p¦Ž‚3F8¦çq­¶ãÄ@ P"G€ëBYQEVóª*æÚ “nÑ0N‰Ë²žs%¡ÎS™?t˜ð¿V4QµÆ*ÎÃtAw!UÂuu×ÜÛM]ü—ä&ªÅ~‹isͽä¿s8”l÷4‘ºeA…=“ã2áì¦\¡Sª°Ñ ʱÄJKtŠ“8 ]h¤ìÊ® ǃ rºüÖìwuÎ!¡¿˜ëØThe瀴ø­®æ¤­¡¤×^z9.ôrØË02-ÒdRénðknq5£V—öˆÑtB÷-¶æšÐ`×¾§l›¶-/ûy˜‹ïˆ5:—r?Íúi+²Í-êa«í:µgÓÑ£c’ìÑ.'ç¶ kµ=Øú=Ý4+ðQö^c#éJMºeªíâ=ÂOíÓ¯UÚ(І{±d.QhHœQR†a¾ï|e±¢[ÊŽY6â4tÜ Aýj¬÷ôna¹¤ µ§öx¥°YãÒ±¦ª¦¹ÉÛr=×ÞÌÀNl_öŠN‚¢`'R”OQT&œTÏQ”ù*¾³Æ>£®ò:( øš* x(Š_‚hÈÊŒCæÃtÐX4iÄ@¥îP(à%$úœ‡!Vö2XW·¢lW¢Ù}~΋—ÚÔp§Ë& Ø Ó†œDê¸ÿ€5î%)  pñžÒû…ðd`ªôŸÁ*„8ð ˆ} ¨ï [j—û²Š]¶º×ûȇ˜F?+T¹1úíÛÚ”1ª¿Ý®\¯c«oüúcÒ;ƒ¢6ñѵ |Y2\˜Q@vel¯ž¸d/¡+,b3aR[õ¸·¦ÿ¾CÛ€q’Ñyàíýð…\¼Ùå›M¾›‡µ:ap9ZÁñZŸB“•f,v°íØŒ?¬ª¼m?ÒüÿÌe$ðŽÕõrU•ÀIç…K¾^ï@³ŸÂŒOôÉÒÿûÝã묋¶ ¯r›úÛSƒÅv ž¶¼-–T„áüû¢ýÔì>a9·³¬|ˆ‡¢ÖwDB|üÊЉ?õ ‹é–³&þ§†ë[LÒ,À=e¯ ´=ôͦžú/-D¡›œ˜ÆÅ|à÷BkcPØ~&'P%Î}£-Wq–ª5¸l›»bwµ.ä²"6‡oÒˆqfüÉÑÇH®ïk8(‘»ñªÜí²˜þw·Ô#qÜZM|ýî= ¾ì Qnò8–ÿ˜[R?Öuÿ Áb[ ºKßÝ]3 -¹7”·çH4‹·Ýøá6ßAzÙS2¸$œ4¾ Ä顜.ê®ß®ÝV%¯E'BZÑí·mlq^æ&îqßò·’?¿ÜKäNç¾êÊmÕ÷+PœôÞnîC/°kü:kæ³,ÙÛôÿýØá ¹$Åoô׿ïbžð°ƒÚ„‚—?'àIVCâRR?8Tüìá©þ¤amendstream endobj 2070 0 obj << /Type /Page /Contents 2071 0 R /Resources 2069 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2074 0 R >> endobj 2072 0 obj << /D [2070 0 R /XYZ 56.6929 794.5015 null] >> endobj 614 0 obj << /D [2070 0 R /XYZ 56.6929 300.23 null] >> endobj 1970 0 obj << /D [2070 0 R /XYZ 56.6929 273.2182 null] >> endobj 618 0 obj << /D [2070 0 R /XYZ 56.6929 138.5892 null] >> endobj 2073 0 obj << /D [2070 0 R /XYZ 56.6929 105.8031 null] >> endobj 2069 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R /F40 1265 0 R /F49 1358 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2077 0 obj << /Length 2732 /Filter /FlateDecode >> stream xÚ­ZYsÛF~ׯ`ùe¡*ƸÖO²#;JÅŠWÑîVm’Z(“C€”µ[ùïÛ=݃ƒJrâr¹Ðs §¯(fü³,#•ëYšë0ŽD<+×'Ñ쬽?¼gî6ÍÇ»Þ\Ÿ¼z§²Yæ‰Lf×˯,Œ²LÌ®¿o¿?ûx}~u:—q$áé 6ªTÉYªâ0•ÿlÌq>fé[ªdtð#XKÂL§é·“±çø„Œà ½7òÖRÀo.FXsαÄQ¬%Q˜À!ÏÀA}„àº"ÏôpXã<¸@™” ê¦#¢Ý˜²ÂÌn/a&ÖÁMÓù ˆP„ÌÄDÈã O ^&yê @÷Ô$p ”é Ç'TËñ•¾D-̲حX“®¡§åSÕŸÈ€àºPKÄâ8X ,<ì1 +ƒ•D©$¸¨ûµŠGÈŸtågdoG¶òñ© õ7Í x¦õT¨U$µSë8þëeøŠì3Qá]µ¬\W|6ž£æ*dc€M¬øÙÜûNU“X;øÝÝVÏàl¬‰š}µÀ€HT€àÂÚ”·E]µk.›-­SäÀŒ+àH[?ÃbkV¦tsn£íGr€+hÏh+w)ÈÈI:#uÃÂŒ"·ø9wÚM’¬¿5ånÛV{3oêÕ½½Ðf®¤@¸É4qö‘©3uK$5I2ËÊÎÀøˆñÔï;p;¿¸$¯™£‹ËÊáÍ.QóÕokã†Eø{d\ÅÁµ­¡*{æÂly¸¤g_”&„f?ƒÕ':Qbn>hD[â[ñ³­>ÕÖaàÔŽ¦~•2EJÛÎ&úÎ葱h‚MÔoi›ÕA`«e,㲩;ó¥ëUµÖ‚–.TQtô\.PÈm_1ÆÖP`fÕgþãÖHdêLÆÐ¶?¹I(&Y" ÄAzÒ”DùOc;w龑G#Fèn­’Í“f" ¾PâIE’è‡WdËv†ÃÌE=²,!gV7+C;lšô«‘v*GªÇj¤ÀKê ú6>!® ÞhàY âÍ=ÁJ$¿X£E'%“„þ †E*¢rŸ¸ -Ü{h©fJX8áÌÊVµYñ,JÙbù…KÄîÂ¥!,RÖÎÁ¢è bÂÉŒ¯O0ñ OQ–~v}*°gæ6ᢪÑ4«™/Åd|É †Vö·u±Bšfm ë–!.–7"^k~‡ífålïŠvÎt»Mè„#øCQ£bEù%V.¼`bCÏØHVõ°Ñl„"Ö.öOÿ¢’ÒƒmàÍETõET´á ]ׂ¨>ÆpŸO”@›¥òé4÷ X/‡uvްÚÖ®÷I ‡ÀÝllæ¹ G în­Ñ€R Õ ˜‚”¹­lúÀ  R™‹J˜§Á¿{fu3l˜÷¶äÉbµ3DVÌÜ:ïåèCÂá¾zŠÓ!ÏzŒ ?ÝÇø#îMCéK\¹f±´ódn{zÒƒPÔ[Ëà ð’j#…+nÀ™sûÄm±74°ªòÞI?b¥áwýêÎc÷áˇx~Eéµ~MA´\¹:&YdŽjÛ3ZjÊY˜ºä¹foÛ˵q\]"ðk¢$Þæ´|V`FâA›ÀuPe; =M#ÿ:cüÖc+K$2 à¦Ôòü 2¼8á‚EôtoÅO^)ôxùârº vk³`¾—Mǧ»"—ðíÄVÏÝëûAèõÎv0(4#…?(8ÉBÞá‹äTÞVƒ(°3,qqér7é€\ &Êf½©Vf1w.àˇµÞìmÍãÇ?Ó[úóÁü°¦õ\ø8zFfÔ:÷õ‹À—Du &ÀjèÚO4B’‹œ$«É±Vî'q(xnøÔ‡/QeC·‰§ºÅ]×ÀÞ2³ oni¹$S€èî"'±E.œpêâ2$⬾÷¶j:„ àŒesÇXp·Ìû[ÈØXÈy’uðø¦¦k=K4ZY™½YÑ–äÑ&Ñ›x·åoY¸J–&º÷<ïn«#cáZê4Lc9Mg¶;Ì"*±ðÜÛŽ(ú°‡(¶†ÏÆÈL‡ õ’¾ÔR±ÌŽe ‘JÈ@ù³jG”ç™§zon{r%l†ƒGbž¸h<®¥QDƒ,jf`¾@ÛTV÷nÁ?ÏSϵíÙ5€}™}bo]·Ùå±Ô\¸z¨'¨ñ+Yrä`Nn˜šJ¸ëº‚øð~•ŠBçâk.PÉ®R@¦Òxyg¬ïÍØ•3 §=nYÐ夯íî7íO4¹Ì¹ ,†Ûè]Ë÷ŽÃ{ Ü›¡·úszþÝóq´Va”éµ)Ù%€¼®ÙAãÿYc©n—ñÁE÷Õ+Úrmƒ©ö¶Ù­Dó IüKŠ%oÕ¦»k¶Ÿ‡ÒñðÛJ‘ QìC€ÜøïUöš&þxÝ×h† N¤û¸åOO8ØR¬¼f»¯J`ŒN„ôHå˜NäÂbúŠ1Ÿ†‰÷Ý›ö@Ru\Ò‚j*OnBðY¡oy‰¡ >QÜÔ¡’šåj·°Ý¾=þL`Ú)ÿ©Ç —ëZ¯ªß#Içöûqxiá¨×>æËjuÀ|îä 7/^s<û0ú‡QŒ€3Šw³}Zgßêm?÷,ö|†ƒÿîéÜùˆ÷6[³¯š]; ÁëŒã±õäHÐL¡xe–öÏUÏg¨‰Âω‰ºùê˜vÛªìœí¾ePpgÝGõÉÖô»(Àn4þ~u,0ÄsCæa–¥¼þ³á<1 Œþâ±ÀGï°Æàùýügù×ÃOItª,“þB(h|•‚.€…BÉ@Ð\Æ2•㟄P3Ôü£>ÔªÿÉÅCµþÝð4endstream endobj 2076 0 obj << /Type /Page /Contents 2077 0 R /Resources 2075 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2074 0 R >> endobj 2078 0 obj << /D [2076 0 R /XYZ 85.0394 794.5015 null] >> endobj 2075 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2081 0 obj << /Length 1250 /Filter /FlateDecode >> stream xÚ½X[s›8~÷¯àÑÞ© ˜ÉSšuºélÓ®ë}Êz<„£ *‰ÚIÝÿ¾b{œÌŽÇèòé;Gç&!Ô?d8.t}Ë7< 9F˜Lc%û> P5Ôƒ@sÔûùàݵ=1|è»–kÌãÖš“ 2æÑÝÐ…IsxõùöúæÃŸ³Ë‘7Îo>ߎ€å˜Ãë›ß§úíÃìòÓ§ËÙ ‰ƒ†W¿]~™OgºË­0ÞßÜþª[|ý8:›^OgÓÛ«éh1ÿ8˜Îw²4åE¦­ù6¸[˜F$Åþ80¡íOc-?Lˆ|ß2ÒÁر¡3¶íº%|ü±lô–Sê™Ð²]ëˆ-d }DZZt|èÚ–½Ó åI­˜¦9|¦Ö"~À)ÎD¥<¤iÀ”¼ï®ÇVc[LØ.ôàçíw9;f4‰ejÃYX{~ŸP_ˆ4gÃ2isR¿ya,Òõä¼ÐITfW‚$tÕ°;³zo]3IŸ¢…x=’ i/¤–dͬöB/UÜÛ\fO"Z:.€}!д^ D8 ªI² YÄû" 8 ú[e^ÜËÂãPM§Þ{šlÅŽËðîó„Iòq#lKäzÐödÍôƶSÂüRv9Ð÷<×h´ïÃÒÙ¤Êôȳ¡ýOòà»ÛäïòŸ8Ð6%‚æ?~Éß1íoÈßGКXÞÑÝU'ÀåAGVÇ$¬Œ*.’va(­¶ÛZò wØ]NV@«$’‰ühéZI¢?­FáÊ&-M–˜Qm{ºqE=Q°îP' ío=AdÙôIBíh+C6ñà¡ ng‡È׃”L„<<ö@‡<úB´X¨SWD­Æy Êãx—ÓK!¦>|5Ž™Û:;niwIéYB”ƒiËè_h?c¦ÎP*r!’ss:ÇLVÀÕ¤X<Ш&²òŽc[dd£”ÝqwÊÀ±£tro€¾à°Û´~^œº5²¨®zŽÜñ˜»kœWß(í¯ÛÆ2£L&Öþ²È:rÛVqRÄ·cÉ…Á—ñ Çò¬!2ÇBÕ·R‡Rý`‹L¦endstream endobj 2080 0 obj << /Type /Page /Contents 2081 0 R /Resources 2079 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2074 0 R >> endobj 2082 0 obj << /D [2080 0 R /XYZ 56.6929 794.5015 null] >> endobj 622 0 obj << /D [2080 0 R /XYZ 56.6929 769.5949 null] >> endobj 1874 0 obj << /D [2080 0 R /XYZ 56.6929 748.6299 null] >> endobj 2079 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F42 1338 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2085 0 obj << /Length 1243 /Filter /FlateDecode >> stream xÚÅXms£6þî_ÁǸ3R‘Äëܧ\ꤹéå®®ûÉõx^@’“øÎýïlp $½ ¤Gû¬vW«Eš.HsL¨×Ðl×€¦ŽLÍK&ºv#¿]LP5Ôƒ@sÔûÅäçsâh.t-li‹°å@Ýq¶ð—'g¿ž~^ÌæS€MýÄ‚S`ZúÉûË«_ÔW=Î>]_^ü9?ÚÆÉâòÓ•z=ŸÏ泫³Ù ÇDr>®z&œ_þ6S­‹ùéǧóéjña2[ì¹4ù"D¾L–+]ó%í×1µÙÑ!r]¬%Ã$Ð4©ßÄ“?&¿ï_Ë©]ú3‰MÛ 4p—MZ“R_YL¥ëekÒ¤ê.½˜r¾RoQ è¬BÐ5M\ˆmVÍà1½Þ•#õö˜¥@ã˜=€”‰(ÜÖ¸êƒïççë„ ïvG\¨÷ÿ¼SÏU=ý² òWaâLÀÒ7†9Myäo¬MæS€å4÷£ôæÍÄöSί^ a~µß馮Z R!ÿª·S”¹dt“îG£‹U«x·wîøz» øšåë” PG%®|ÜÛ‚¥ñvLë˜Q_âp ù=+r›ä:ȇÃÈÿ&€`Gµ$RÝô„´IáeR·¡Tïíxb4æ¬å„ËŒå•9DÙºèT^¿ô¹—í?U˨šÀ¥vxðvûy…é•â Ó„²ñ‘T«w±ï¥‹£Ü+5J6VËk©w !\uÙ?èQQ6YDH~à/-Ý…4ŠwÒÒY욢ó7Ûäií!£åyÕ|À£¯5)ÙZó,ð†¨BE¾Âïwa”s1ŠE…#͹eì˶A¿Ðsªõ¥Ö‚ ÃÑc˜ƒkÊ_¶ßåì0g ð£Pž>AêÕf<&¸–0"ÉÀ+ OàˆÏ HØaÂüÇ14,ˆáÄбŸ•šÙMÃÑÔy6Ê[ë<D¾ "õáÿj ¶C‘P/’ˆ’·©!R ©yÈ™weYÁcG^Ô67e‡à¶ `¯–~Ój’Ì2Xêó‘ gt|V‘m®÷VÛTS_ûù¨q”õTÂåá5Ð(3y§|Ôv!Á¶)‘ m³ú©üdB×¶-­ñþàX/ŽæµßÉ ‘hú9"î­&ë)׆Ø*/[ß“Ö ÄÄv{2GFmD­Öè!a¼9 b{nKOH<»#ˆlݾ¥¶ mݱFæ»ýGE—Í.4ˆkuRÝðôîÙç®bà ߳lHllô©ÊüŸ|Ï&®û¼øÏ{ÞÁ¿§Ñ"A\Vq:v²¨Í.¨©IäUA=ÜÄqëà(²—àèžöWÞÒ¼ÚF~$¶ÝŠ‰ê¬Ÿ)nQ‘^Þ8ý:áy²7QŠ'òúÌ_t"7¡…«‘ >tLÞNSdæ[]ÝËäâÅ)Êp®%‘)"!]åDù¯|uñòPÙ5dPp¼¯Kâf]’è$ÄEµPQ¤›S™Èb7«¹I!Àgã˜Õ¾ú”Ö¿;GíÚendstream endobj 2084 0 obj << /Type /Page /Contents 2085 0 R /Resources 2083 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2074 0 R >> endobj 2086 0 obj << /D [2084 0 R /XYZ 85.0394 794.5015 null] >> endobj 2083 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2089 0 obj << /Length 1081 /Filter /FlateDecode >> stream xÚÍX[sÚ8~çWøvFŠ.–/“§4K²éli—Ò'–a[$žúVI4¥!ÿ}elŒ˜pKwwÆò‘õé|ß9²Ž… ¤Ø`´\â¶kB†03ü¸ƒŒ;ÝwÝÁå3`ý¨?õnÔ9»¢ŽáB×"–1šÕ°ˆ£`ܵ =€º—W7×_†=ÛìŽn>z€0Ô½ºù³_´®‡>\ {; w/ÿ¸ø4ê‹.«Äxw3ø½°¸Åe è°Õö—ýÞdô¾ÓU\ê|1¢9‘oñ¦ý¾ƒ uf<è±ë#BfRº¶DÏ¿*ÀZïjh«~AB-Ò" Ij:ZHCÙÌ…%t%à¸,„ºq˜Á•XƼ°%óø–‹¢}^\&9a=+ÀºŒ‘„÷ãTˆ¯|‚Pp_¥bQ˜2OÝO/æíÃq}¸7W))¹_¢(}XÆ^˜(ý_¦³ÙN„I&Èð. “»Â¶àršŠi’î£Ã"•¨d<…rÀ#~ç©0M@šD‹”k¨ïßsÿ+È9ÉÂð7bèÁÉræ…ÑR5\Ûð3ÄÕå쬸RU4nâ,â1OੳTóÛ×Ä[%:ø6çëeóXÚƒ@p)§±§üûiÊ’×ÓJÖ0uDÞ öؽ’9¡ͳz{šfy"í4o”{Û’~'ƒâe‘³ThU7Ê(þC-…—¿Å²]ª4I…V5Ø åÌ–³PHu ²‘ë—e6Í“¡´e©P•=¿)s|H?«:ò›Ic~ac>í­™Àw«ÎÁzÉÁµ!Ñe^ÉÁÜÂÁÜpXù`ÛÐFŽõ,D§# 2âÒ-Û‹E‡ ªË\Ûý—£C ‰^Tû’Ø!B0Ä6²ŒC¡åXä#dRhZíä`k)ˆóêH¥÷W©B_[žòn=Ézß73]µÜŸú…s8þÿ}iö‘ò¼êÅ­U¯yjÕ‹_T½:g|ÐRü’_]üJ.¾ë”/!øîÚç„J¦œ«V7çÉ;6ÞOö'qðÂûE_7m'$TW)”¶gè9ùɧ'›£%Ó†ÔqHu0BHËÉRéSήv±ž|2{º´"6ébd½ µ>yÉê{§ïhendstream endobj 2088 0 obj << /Type /Page /Contents 2089 0 R /Resources 2087 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2074 0 R >> endobj 2090 0 obj << /D [2088 0 R /XYZ 56.6929 794.5015 null] >> endobj 2087 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2093 0 obj << /Length 2016 /Filter /FlateDecode >> stream xÚ¥XÝ“Û6÷_áé“<1¤¨ÏÉÓ&ÝÍmç²ÍmÜ—¦;;\‹^ëN–\‰^ǽô/@òG´½ä2~‚ ü‚S?1ÍÆeO³"f Ét±žðé#̽'z¡ðXêõ|òòJæÓ‚i”NçË#]9ãy.¦óòcðæïç—·³0Jx²Y˜¤-áØ?M8“EžLw0àLE4]OâD²$–Òsêɇɿ…G³vé˜ÿ™³$²ÆÑ‘ÏYÙ4K –ÊHZšýFÏ”ó`Ùv;Õ•¯ðP 9‚IY©'"4ø'¼mêýçeÕõF‚ø¯ès÷¿õè®§ñéãf«Í½*ËÎñ6mg>îÜDÙ/6ÃîNögŒyCìçÏq»Ä±]¥®õ£2UÛ„x2bîußv÷M;r¼0’¬ÀHŸœòÏÁ‡~¹´óôìw†E­úþÎ;*<©ÓeÕé…Ò²ªXoºªyô?àµêîp]1Y+s­ÑŸÌçNí>¯Õ曂«êºÝ…¿ou·?‰.ÆT÷ý=ì²XÝ×Uoþ60Ñ©ŸBô_hLMœf»~ÐÝW„DŒ†$> R÷Zë¯ Œ8 Ìt^}<¾Ù–WUMøTéݾ¸/¯"1ØK4*èÈX%£J&w¦REü`”ÑkÝþ¨ã¡?b¨PBíÄÛé×a§ù¬€¤Üèþ¼ú Á2Æê ”ͯª¿*l‘œ–ßÿk‘7ãcÏîOë8¨r¤Ç©ªp8R( ÎÒXÏÔöX‚³ò|ó”Áe–YRv;W‹g1ËD‘Ã(6_¡gÁ©½îž0§^)¨ÍQ^ŠÆN—¥ífOT»$!ãU”ʸPOˆæXP§Å°vU]õ ÇÒ_=Ô.ꦥ鍊‰V>8ÁÅJ5º¤U ”-D v,pöcN²¸[îíÍ*ã±/ãĉ ßœ ÷A/œáœ5'(FȲBÐê;† øP¦Z+Û¬3l£íºp(äI<¨ÞºHµ4žë;؟쉀‚X^@aä@¦ûKCF¢(Ü1Á#ÖÇãY” Ö¿üûäƒ*“:ñÝJ»ûåKÍR€â8>(Ñ ïBï tƒ‡Wv ¤o- :QD€Àvw×QÏ qkH`lóïx™P†€Ü¦Ñ»Ö+kîp÷X°ßC6¯ûñ®e¥|óÿdÿw@ª¯Û]íèjIß}»uËv|]rN4EËUŠ¥/.¨LñÏ‘²r…Ï´°€’ÇlæŽ?0Ž;÷ï{ Äø$Î8¾b|dÅØ‚|x¾÷?‡¿g¡Á†Þ/^§:™”¼¥à¤’Þ‚gðxO°©:úKPÅdø>þÂUþoL§áèXÔS endstream endobj 2092 0 obj << /Type /Page /Contents 2093 0 R /Resources 2091 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2074 0 R >> endobj 2094 0 obj << /D [2092 0 R /XYZ 85.0394 794.5015 null] >> endobj 626 0 obj << /D [2092 0 R /XYZ 85.0394 481.4332 null] >> endobj 2095 0 obj << /D [2092 0 R /XYZ 85.0394 451.3193 null] >> endobj 630 0 obj << /D [2092 0 R /XYZ 85.0394 451.3193 null] >> endobj 2096 0 obj << /D [2092 0 R /XYZ 85.0394 426.9079 null] >> endobj 2097 0 obj << /D [2092 0 R /XYZ 85.0394 426.9079 null] >> endobj 2098 0 obj << /D [2092 0 R /XYZ 85.0394 414.9528 null] >> endobj 2091 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F21 1034 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2101 0 obj << /Length 3290 /Filter /FlateDecode >> stream xÚ¥ËrÛFò®¯àª2á™Á`ìž[JœÚ(YY¹l’ÃElH€!@ÉÊ×o¿I0•-[åB£§çÕïnPÏüéYêbW˜b–6N•NgåæJÍžaìÛ+-4ó@4S}óxõþ.ÉgE\8ãfËÑZy¬ò\Ï¿D.6ñ5¬ ¢?Þß}úö燛ëÌFŸ~¼¿ž›TEwŸþuËз7?üpóp=×yª£ßÝüôxûÀCNÖøæÓýGÆü¸°èÃíÝíÃíý‡Ûëß¿¿º}î2¾¯V ^ä«_~S³\ûû+'EžÎ^áEź(ÌlseÓ$Nm’ÌúêóÕ¿‡G£4uŠÖäqê €L^Ä©¶öò¾¼‡‚}4.‰•N²“}繎ËP:ÊÆEPŠ5#¡h£âšei»Ä$$•®ß?!kÞß™1±ËãÌ܉n€—IÆ´¹è϶©Ww2Voêµßñpß2ÒËØÚ¿T‡‰ï,¢êKYm{¦èW^ ºgÂݵΣj»®KßW²GÛ¬ßð¬pª¹Öq‘¦†Ž×¯`õÄÑýg|æ2¹lé¹èx°]ò ç×ïújÇ(¾bë°~qÌC}´.ú,|<=’àñ•Ž|˜j”Šš¶,¿w½oL±à­ßõ<†ç@ ï?ÿs@½1n´ú°è²òý~Œï¶UYÿª”)ÏÊJb›á}Ò±‘Õ›íºÚÀý}_·MAHAŸ“$‰Wµ¬¿ïü³œPx•¹1à<•uÇœ&•NÀNƒP6 0 " Yˆ4Õ+pTÅçýŽ”ª¿¤sÇYû*øÑí·Ûv×w“bƽsÇ>‚ |ÎÒÉÓµ¬§ÃîÕ¿]k­ñ²œõ“ÊŽÙ÷9Çê"ÈpýÎ7ݲÚu²Ór´þ Xó)a“¶qèhÊõž˜ƒx¶8P¯qøÌƒáà’ÞÚ “ˆ7|¹ª×¢ cH‰€Füª ®j‚q,è$SѦòd™¢yxpÄF@u-ê#B¥Ý£Q…漓ée»_/|®hðCÈhB½Öý*Ð5󩃈.U™Ìñ­LéªcY¾áÁpyˆàÑiF°À“æ! ”é‘À æ°àX! hR–n»¢e³©¿  "Ø·pãí4,dÄ/|<ñ :Â×K|]Žè!V(º­¼ª'Õ}¤À‰Bk•¥–¬1cMT£pÌÇøs€ ~ ,3ìf˜ù‡ GŒ%B+ß1Àbš8¢è§²‡{¥#›§uxND~½æq qvÈTeÇxæ˜òèŒ0 g„¿îÚ)©rd¡H'oÅ›c_'þW ŠˆH¾Sª†;¥êìNU>DG9:@'%ˆâ¤ÊCœÄ1!öü`‹Rlãø‘—ŽTHWTHƒºv½Gÿ:Ìš8G_—EÏõ z-†9„sââö -ÇR|`†R—{JûðbNÀ£ݾ_µ»“†—*Ð0'­íŽã¼ƒÈë1ßÀ€`Ó@Àð º%Ðp|DhÐ|¡{öÊ0e»«_$µ€)UÿÚî~ç—}7ŸNp}碇»ºÐ9¿ŒÂ®`ðƃ$2xžêcÅñ¹!?pnPÇÎé<|ŸJ«¸næxˆØï¶~"†I Q[K §ÔÊå,°â€çwP"ñŸÈT»Æ¯™JXJ„¥N‚IÅá?lvœÐËš¬e0\xaÃMUˆI±ŽÅ§•™Ímœ»ÄÍÆõÌWÖHV%@àRÈ]R«”볿»h˜r©ð2Pú&wÓ…W`‘Û™- kÒ@ÅÞUÎ/”_P:—d£ò+·GS‘OC”«æP…åœ`#Ò‡é<ÏóQN"^ jÙ®×í+ÀW_&ÍK7ÌÙþÉOfÃÒCì+”®óƒ«ã÷©X!²A¥éJÃÄ”|M¢è`p«…!ÔZ(<#C C˜Õ ¨T›èuEïPJìw9K¤Ä“㳩J°|™½MH6Ïâ*MÆ®Y”26X<1<ÇLwBq j—Jðl$„“Î5±Äʲ¤ÃC²Ö™ŠSw"kX «ÕÁeÀ,v,ž⌄ä”®çø ó·L-¨öOëºdy4i÷””A92r±híC·¬)‚qÒ“¸Š©``›¶2É¢#Ù  >2â‰J@´\T±Ó"Ò–<¿Š¿ý‹ZÅ ±#ÇÐ8ã®ÔqÅè-ÇšUýĽš×ðZSU#Êg†Óm[n‹0E`€n'v÷óçÛ“lý\7%µU pG‰º‰xìáÖu?uÈ[]ö_5~ØÄ—¤S Xÿ;…£¢íڽђñŽwð~ïŒ íÓêÝ;¦Õv܆ìËÒó<‡®tt^ÜÔ§]ÔåÔ±DbÂuÔ©pßW›-v73¸(Hrž¶)¥ liÕK©·6è¶ž+`Ù ¶Ð±ùoU¢"LHK1Oâ—mí"øì%?ï|ÄO7??~7YIÞzvn' ÄI[šÞ5‰)‚5Q¿]yð¡„z®š Œ=Ђ3Ÿ*©ˆƒkGøØµJ €nä–R°3§/4ÝÅ `œXe²~¨4ÄÃT¹üÿXt˜r©ÐÖ-¸É Ÿ^ˆuI:36ïÌ™P»{õ»ÅD0Ȳ8Spç!ù·¶ˆ~ÁSä"QÞ8Ào”­Z*ö¬•F¾SùnÏt‘£5IëGéoX¨@»ØÙ m£Óâc )å¯7ñ1ƒ²Ñºq®r~w“ÄÙœ¾:ðd!ÚEýÛv*g¾åPÁÈÜËüMòØeyø¶Uz9>°§—»¸ÈO¬Ÿ±9ÈEAHÛ2gEšvé&€Ýó<ÏiâûÐ8Ú/IãÌØüø>'ZøI ‰ãÛÞIïUò!ë‚ßÈo·dñØ`ib1':6Á.Ç7ÏAši…K!…އ͖¼Ù[»gàÕóGöFºe¬ú`y&Óöäëè*¢äæÆCÌ>T^¡£\BŠü|ÔSò§jå_êÃä¡åüŒ…~ûä×S–g²é©BMñ£€RBßec›ö$qãtßrê-í «A 1û²ö<ìà(F‘]×säÁÉ}Kä‰(*­75?Þà€,NŒôKM)#ÌÂv¡7¥IOûž¿­²Ü"·¥t9µ _nôî ™èÔ»€”ž×Èíµä+ˆ!õ@@¾>¶aç0é³:æ‰'â$Y†îçHÿ/·<ÇyÄWæ&ø[¨!$åh"y>õ‹ø/Lþêß¿~d³8És3äBÇÞN¨òÉ£¯lô[žXÃÆóŸ@¯t 15Ò*?ûá@Åb £[ý—¡ƒendstream endobj 2100 0 obj << /Type /Page /Contents 2101 0 R /Resources 2099 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2103 0 R >> endobj 2102 0 obj << /D [2100 0 R /XYZ 56.6929 794.5015 null] >> endobj 2099 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F22 1037 0 R /F21 1034 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2106 0 obj << /Length 3187 /Filter /FlateDecode >> stream xÚ­ZYsÜ6~ׯ˜ÊK¨”ÁÅÞÚY–m¥bÉ+ikS‰ó@Íp$ÆrBr¤hýv£9)›õÊel\>¾î%fþ‰Y3®Œž¥F³˜‹x¶XñÙô½?nÌÜšG½¹9úþÊf†™D&³›Õh­Œñ,³›å/Ñ釓O7gWÇsó(aÇó8áÑ›ó‹·D1ô8½¼xwþþŸW'Ç©ŽnÎ//ˆ|uöîìêìâôìx.²XÀ|éVxf»óϨõþêäãÇ“«ã_o~8:»Î2>¯à òûÑ/¿òÙŽýÃgÊdñì^8ÆÈÙúHÇŠÅZ)O©Ž®þ1,8êµSCòÓ2cqb ’‘J¤ÏoK[pØÖ5SÁR%ö6 Á*™ÍBIL6¨DË‘J„6ЛÀycÃ%•ÕÉ}Y÷(˜ïßÉñà$c©–¸;º¹/@’BDe]öe^ÑKWôÔhVø”Q{,²¨iµÎ×…Ø>mç–pÏnS,ÊÏœËbI„mWÖw´PN”ÏRjËŸ}ûwSHaÈ.0g&Ž¥åð_÷EÃLÔ¯ÆíêÚ}Þöµ·›WÐqTöŽÐÝÞÜñIŒ•‘ÑЯ—ÔÎCsìéŒ\%I”Û qg%™ÄŽ ¬›®§–]¶Xµ{¯JßcÅ“FÕ‰ZNìà%*N£ó•ëoèé¿cœÅŒòQ¤)xN5%e´jZêYTyç_¼¢§ù“BÛ‰X’jqf³Þ”U±œ—5–Å*ßV}Xdp4•ásw`|¬KXUÁ‰­¢Sä®èÜ\à«¥fŸ×Ô:¿p³ò‡‚((|Þn˪Gæü8V;·ã¶ÄB1)fcü*'×\A78ï\f 3Rÿ…ýŒgqCsÃ”ŽŸÃ •2%„LH™Vm±,ÛbÂŽŒ³Ä¤ÚaÇ$F 5±µ0ž ¢ƒ‘,‰l½ (ÒôC¹tCòº{$$ú}[´¥_ñ‘€ÈucgÏC*\[ “Îi‹®©¶}ÙÔD{l¶ÕrÒ†ißK7äâ§·—OÐ|ðí¶ ä&ôÛ¶.–èx\E—uõâü,VnÎDJ±ö~;?„g·Ýlš¶·B‚ë\@(‹Çc##æt!ÆÊK ˜Sìt‘WUó8Gy=ô§,K7t>‚«ß´Õc.Á .¦°a•îà$Ö·%„ƒFÊÅ=5UYÔÞqº¢ xfçšN¿AˆGSRÀ`ƒV£ö}ÞQƒö‡#vVPHz{q}}vŠíØ£)™ÆÒÍùÌcþöòïž‚(™'›]ü4¤Á vGß4µ?NéZÞÕ¤6{ÚšZµY·½íú²÷ˆ"+«ŠZÍb±m1¯a!¬¾AµÃ*)ç+JŒAS÷Îb‘èãØÚY.¹–4bߪª‚ c´Œ6 ¥4‰"¹°/ ´tî`KêÉ—K§+PÔkrÚ):ƒ×¦E’×~c·Ž™ISÀuˆ$|;¾wŒè€Qôh#aÏzŒUFN/HSÀ‹© |À#-9d<{lƒ*b™ÊÿÛðC-2Jø¡_¯O'Œ›Lü7q¸Û“áˆAGT*çHµŽˆëM^—Ý=½ yvÔDÚÖK›¤À+;»vp/d–ÐpÞ‚Ímçh]¹.+0Ç€4“¡ Tæó|¥Ý½Áá‘ç™`2ã{Ëž|®´œœqÊ:ˆ$VŽuT~c¡æØRxõD©€¶Ù‰ÒCÞ wöéËò©Oh9ø̲YÞ’pÇ §·ÅØ‘WïÀyÕØzÃbZï@Ò¸Øt¶.IÇÅÞ×»šÔÄ,ÑBý…%ýŒgkRܦ\ÇÏÔ¤"a*3 œ†crà óª¸Ë1ž7®èÚè\@nb†k-JÐe䟮;Á³¨Wƒ WQ®=û»Yb×çýÖ-fïgpñzÕV´ÇY´]ô>»}æêçraãB»cXÍjŒt¯¨ëâìÆûä;—Wï1ü1ê;©ŸˆL…]êÉ]=‡|µ(` {b.CA*Þ—è4*þØTåÂÆ uyKÔr=¦îÄâzÝ“b È·°O[öODïÀ5ÜàÌ>H¾ ÞžõÄync™€|Ë>aÔPÞ0"“f±µl 7ÄB©³Ù º°‰ZÆ>ËÈ“iTñ‡•½ ÕúêîwY54¼Ûâ.å~È­Š|µï£{¦}pÙôg6mÀ cå³T*„]u‰Ï‚Ê0 XDVÔ»R›^vaC0PVtõ²¦I«ñ]ÊÜï8aôÑ%Q‡å; ëÚ—û ˆ‰¹¿ ¶1LI„mI‰”ô"u¶w3j\.Ô‡ñóñ Óx°® MÓÏ2s¤R •€Öxƒƒ‹ýaT€±ºWŠ‹Zaðë u‡Ö»¯ú¹æØ >þÚñ?Mòl, êÍ0žMDy(Rƒ¥IQÉšI‡5ë¿ã@AÀ (~’Þ`@åÇé.8à<`¤2f™Vf÷¡CrÏo;jÓ:¶Öù5š Z äçîýÖ X5xÃFàÄmÒŠÏœö¶ÜB ·—Yû]Ô,ý®W||ýn1_ºÑ‡Ð¡Rð7)üǨഩÏË0Ì oîð®WúD&T·.B·½: !Æ¢W„¢Øy<… %'Ø®éŽTð!ï®Ì ø߇r÷Ñ!æ>óè!ï\ß:ÿÍE› ­<ÐtÅ‹2ëT jš<ö¢¹/º² ¥‡ ¬Ì(ŸC8ÍáaéžþÎ š–iºPtc0XûðüzQ.Ü%ãtáíãùÍ·nÉOÔñ›+¥ut‚׈9VÞP÷S(‹±×— ]{v÷ù(í˜Ç3?âN43f m4¿µy/FÀ‡¼-›× A>Aá³î¨g™C¡„‚Ƭ²ˆnk/{qºÜ´ÔË£;:Çvã‡oÚMË­L¥(Ìéz65Q+á¾@åKñôèêÒ—‚'éùÃuÈ4Ó˜ÿò©=º»Ø§º©ŸÖ{&G¶à/€Üü‰EÔ>ÿÎbT64ÃHÜ7kúx=v7xžÞçMþ„ éGNÔO.hžûîÑ7‹¦¢®Å8ñ±+Õ4”¼ër p‘rD-tô3Ý…@ªˆÓ2÷é—̓_¸|3ýò7)7ú  Af°+2O?œ\† $ƒ*8;PèÓÅ\ 2ã HA˜Àb#`WØ®|.-&w_ù¡¢m%1S2¹ÝˆùnÈó1ÆÙ}L½CA¸¿©Ð€}ØÆ Ûc6žZkÂt’Mv¾}9¡Æ²èm¹Ù}A <”¨I‡ 9ù´ã¿ ŒP™ÿŠw˜§af¥T2:â YÚ0úÅÃî¯I‡]쎅ʇÒO0:”Ƽ(ïaÌË,ì­Lμ5€]j¥‚Ûñ™¢¯þ³’ÝßÜ@¬UY&Ÿáœk¦pî¹BÖ7à(xÕ>þCe¶š:c¬Ò2ˆúƒýŒUý_endstream endobj 2105 0 obj << /Type /Page /Contents 2106 0 R /Resources 2104 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2103 0 R /Annots [ 2108 0 R 2111 0 R ] >> endobj 2108 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [280.2146 312.7082 375.7455 325.4454] /Subtype /Link /A << /S /GoTo /D (root_delegation_only) >> >> endobj 2111 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [312.6233 61.5153 381.2953 73.5749] /Subtype /Link /A << /S /GoTo /D (access_control) >> >> endobj 2107 0 obj << /D [2105 0 R /XYZ 85.0394 794.5015 null] >> endobj 634 0 obj << /D [2105 0 R /XYZ 85.0394 267.599 null] >> endobj 2109 0 obj << /D [2105 0 R /XYZ 85.0394 241.5759 null] >> endobj 638 0 obj << /D [2105 0 R /XYZ 85.0394 118.8577 null] >> endobj 2110 0 obj << /D [2105 0 R /XYZ 85.0394 93.2529 null] >> endobj 2104 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F22 1037 0 R /F21 1034 0 R /F64 1485 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2115 0 obj << /Length 3112 /Filter /FlateDecode >> stream xÚµ[Ksã6¾ûWø(W­¼ÇIâ™uj3“õ8‡­$Z¢mÕH¢BÒãxý6" ôT´•š?öøÐ °ir‰á?r)$’†šKe8˜ˆËÕî_>½Äc–=h9D}wñÝ{¦/ 2’ÊË»‡,°ÖäònýÛB"Š®@^üðéãû›¿Þ¾»R|qwóéãÕ’ ¼xó¯k×úpûîçŸßÝ^-‰dñÃ?ßýrw}ënI/ãû›?ºã~N½½~}{ýñ‡ë«?î~º¸¾ ¾ ý%˜YGþ¼øí|¹·ºÀˆ-._à#b ½Ü]pÁàŒõ=Û‹Ïÿw»G§Æ åF’!"¡19Ê)B¤8AŒIF™’©QîQv”‹í¶zYþù\Ö¯c ¡3>x`Jy@Mh§í„(„‰d±úÏe鯽}òuÙ¬êÍ¡ÝT{×Q=XÃF¾F¹&œi iF•Çnöc?©fK¢"?ÝÍúñÒ5nüŒÇ©\çñêè›å8‘ˆM‚ñDðÍ}@Í’J³† „ážFð?X…’Ïpm€Êp­G¦iY%Ó@¨DFi×PDtcژĜnÞ‘rE‘RRždƒ5c¸á‘«ÆüŒÓ©Ü·3N$éÜèÔœ!‰´,ã¤Æ°D…É3nˆ:͸€:ÎT[û桬SÆTCRÊê¨ "ÆQ´[pNÆ ý)—à½2ì4ã0FJp¹šc\Ÿq:•ûvÆI…8ã,?ú5gH"-Ï8‘Ðb&Æ QÆõ¨ãL=ÖE[¦ &ÃbÈj¨ õ1ß Âi¥býo&âÛÑ‹1Û(Ò˜“ÓÕ@æÃ<æ\Fíñ3.§rßÎ6IƒÍÙ±¨CRiy¶Aav”gÛ•a[²Ý -Õv³šØ¿AÚWÂäÕÔ„þ˜nVºb±Ÿåjó;Æ´lÜøîçwJùçÍî°õ$„9z®¯ˆ^øë_;Ã-Ê]{!0ŠïpGäñBN‡ÔÏ#‡rA¬Çϸ–ʤÕ´‚ ‡È›〚3$‘–¥•0’+Ÿ bCÔiZÔxù/ªú¥¨×›ýcB0E ÀY(kH@MXLI˜…¡[ÿŸx6rhâ˜"Œ>Û8¦ "r:C€Ÿq?•ûæØÆ¥AT“Ÿ‡€š3$‘–'!„BÍØLl¢2$ìQnΚj¹¯ÚÍCÙ°€}.¤¾¬ò€šÐO9F‰öOûí+Œ:5‹]Yì+Ï[w½™¢›U "ˆcÍÑê$!#TÏÊMã$0Ç_K×rºFûÔßþoµ/mPÄlq÷äaMÙºßYY¬ž6û²é.üý—ÍÖÛíÂïª ª g ”q¥©·ðÇŸ-Èc¤0·é<´»ûñÓÝÍûÿL¸É4 <éÏ?»²iŠÇÒzàý³ çúóÏõ¹ëÌÚ÷<ܯuÓb ë{Ü#¶›¦-×®½/v¾·)ë¯eíüŽ®à ¹Ø„êÍ®p/ Z{뽯îmÔ®55H"ð§Þh8œõn@×aûܸV±u›_|Çzíæ¡iÊÆ=ׄºv˜—Mû4A1 ».*äñH-ñ"†5,xÿÎþÓjñΛWÕ­kí oÞ}9²åŠ,À70 ‚ØóÏpî;#—”óE Ì›0— „o²„4¸¹ƒ1rÚÊþ ˜ÔýÚ÷t뺼ȮÓó¬qwÜC¼ÛÀ¥sÚvx&81– Ú ä]Šçmëz»Å‚!ǤwnHŒÍTFÆ#r÷ùæÀ[|)_]£_ªhç¾ë²#m£Y·½]ÏÇX£Ò%J œ3E8æ¡Ðý‰°«ß<îf˜ü×£º®ñ!btÅmÊÒ&LØ7¡ô­Sl•ÇÈç µÜb£µB\‹B/\»à¦}¾w-»ê¿e¼;núI„‹M3Ú@”»Cûêš6xœÌl6j¬D>³ Q§3[@YÿVOåêËÒ«&ݳ  rFy@Mh÷ì°¤l¤þÎE^QÕ&Ûì[»ËÛãc[oV­¿ãbžOвWYí´”­ë/ök×h^÷mñ—»ÛÅpûPY·ÅÆ«]W;׿.|7Þš}ˆÅ VàT, “ »„¶ÝSpj¿«ü ›ºº†7ÿPí›7H…k×óÐuU;wåüƒÆ¾l_ªúKWCÐŽ_¶;ðË^|-êM0`µª:IÝîÒɪ:Op,|²P0–¯›Ý¥4‹÷U=±ÌT·rú­…÷}b¹sDHXïݲð :«AüÑj…ý oš©-TôYã¡Øl§vȰC0dZN›Ni×›mñuêm‚}£K…8ƒå}xíýÔkYÊåtdùÍQl§ËO=† )™xâº3í®Üw{Ž>&MLšDÏagÖNÙCP4_§#fFÈ\$ 2‘¨G#ÑbáB`W܃&G|ÁÜÖ_H¬ù<ïE‡öw@I®O¿ƒ§Bƒ5ŒG>æÞQõøwS¹§Îq$y™@!¬+:3ì5cH*-{ŽcŠ!ÎIžbÐi†õ ã5‡‡ôו=UVo¥Šc†§:Ò{Nzyë“c2DÉ3ü2v“H†féåáyW©ß@.‰¸Ôù‰ ¼‰¬<³8ƒ¡Â3ÑkˆÊp«G§N¸ëUQ¯§ê‰“¼ú4¡~\Mdš²XÿyÞM¥^¤ÕDbÁéj"Œ¡± `àC¶šèñ3N§rßN6¥WŒå? æ I¤åùÖUAgØ0®9ÌqŽ ‹—õ¦MßGÙP fe4÷DsL3Œ¨–l¨úœ$‹³ŒÀa.ó•ÃILôÀÉlýУ³þŽe~¿àŽ&,7â“7a$)Ë,ª)’ÚÌD²!ê4»jh6÷Û©×ìDÛ©¡yõ5¡?>2„5±gÍ—G7ÆuC†´1&S76©’ÈÓlÝÐãg|Nå¾i’ ­ÄÌÜÔŒ!©´<ßE|îÕú”a›ug²¶/j–MU,Ûv›3Š,«=€Rõ1ÙTªHÿy¸6áŘmA ™ˆÆa%P1t4Ò<<ïr"õ‚FJ“øš±b,+Ï3˜M¢õ\\ 2LëQƒú´‹ _š/ ט‚¤™±  &LˆØÆÁWG6œ'Ny2R¯ªg¾Áa àãЉlõÚÁgœN¤¾™oNWÎNùÁ¨;RiYÊClÅ,ϸè4ázU·Þ7M¹ê ½»j~ƒ#ìK&o@¥ÄoÂRÇ&œ‡nÓŽŒô‰„ÈNb[¹ºšã›Gç}Ë<Á¶„kö+¤È {åMHdå‰)Wê¹·øCT†j=j0Eðó¥|µ!¡²%ã1Ý$dff̨ ;"ÂIƒì[ÅÈŽó¤Ó“Þ$ïZl‘\~ïÁ4ÈU„Dçh×ãg|Oå¾=Ð ËBSvjÆTZžŒ@V3ô;‚2ì󠮞W¿.ÛÕaY—uÙ<¥{¸îÛ@šÕ@©úx'¡­e¤ÿ<¤›ðb¼‡SHi‘ÙÂÁ¡MÂyàAv çáy©ßpZ€-:;î4cÅXVžfÎïZÎ…¹*C´Õ†¢-î‹&I¤6ù0ÆóŠ{Єâ8¨Ø20W±æîÛÂ‡î …¾ÄLW/s]®žˆºû•ë½÷(_Ïä¾zl!M[Õ®>sÜ—äà¾Ø}2û’Ÿ}æøÈCe?'‹$¤L‡† 4. GsWœßq¿4 ¿øR"h¡ÊÕ§ìï¾-냫`º_¨^þfá~lYÛµº1ÀËÓ¦-›C±*—ër»Ùmü£jÑk±EtÁ©÷nØÊjÝËÙ².÷ífékøÞîÈÏðI¨Q>D@ã8Q]7Lä?Üç7]¹ØöußËØFó|ß”>ƒw¬ô¸ð-)\Ц›ãîFx|¶•ºÞŒ*oŽ¿}_ÆõZâCÏhÔ©+R¿y})üWáÛŽ•‘Õ8V5‹¾|âÏ͘@öoÄ&üóþ·ÿíøwz\!¦5^¦#›ì¸ þ¬X€Øò~ÛgûY !8 VQ&é„Wÿ42ï‘endstream endobj 2114 0 obj << /Type /Page /Contents 2115 0 R /Resources 2113 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2103 0 R /Annots [ 2117 0 R 2118 0 R 2119 0 R 2120 0 R 2121 0 R 2122 0 R 2123 0 R 2124 0 R 2125 0 R 2126 0 R 2127 0 R 2128 0 R 2129 0 R 2130 0 R 2131 0 R 2132 0 R ] >> endobj 2117 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [282.0654 737.5313 350.7374 749.5909] /Subtype /Link /A << /S /GoTo /D (access_control) >> >> endobj 2118 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [311.9531 707.2808 380.6251 719.3404] /Subtype /Link /A << /S /GoTo /D (access_control) >> >> endobj 2119 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [299.7586 677.0302 368.4306 689.0899] /Subtype /Link /A << /S /GoTo /D (access_control) >> >> endobj 2120 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [292.0084 646.7797 360.6804 658.8394] /Subtype /Link /A << /S /GoTo /D (access_control) >> >> endobj 2121 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [330.7921 616.5292 399.4641 628.5889] /Subtype /Link /A << /S /GoTo /D (dynamic_update_policies) >> >> endobj 2122 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [401.5962 586.2787 470.2682 598.3384] /Subtype /Link /A << /S /GoTo /D (access_control) >> >> endobj 2123 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [257.6971 399.8859 326.3691 411.9455] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj 2124 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [258.7928 369.6354 327.4648 381.695] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj 2125 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [310.7975 339.3849 379.4695 351.4445] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj 2126 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [308.6055 309.1343 377.2775 321.194] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj 2127 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [294.1999 278.8838 362.8719 290.9435] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj 2128 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [303.0862 248.6333 371.7582 260.693] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj 2129 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [332.9347 218.3828 401.6067 230.4425] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj 2130 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [359.5147 188.1323 420.7148 200.192] /Subtype /Link /A << /S /GoTo /D (options) >> >> endobj 2131 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [386.0748 157.8818 454.7468 169.9414] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj 2132 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [301.97 127.6313 370.642 139.6909] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj 2116 0 obj << /D [2114 0 R /XYZ 56.6929 794.5015 null] >> endobj 2113 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2135 0 obj << /Length 3127 /Filter /FlateDecode >> stream xÚµ[[sÛ6~÷¯Ðô¥òL…wà1M®;ۤ븳;Óö–(› EjE*®óë{p£xÛi:@àÎ9Àw®Á«þá•â(¡š­¤fˆ'˜¯¶‡«dõeß]aÙЦ‹úæþêë7T­4Ò‚ˆÕý¾Ó–B‰Rxu¿ûyýú_¯~¼¿¹»Þž¬ºÞp‘¬¿¹}û­ËÑîçõ»·on¿ûéîÕµdëûÛwo]öÝÍ››»›·¯o®7Xq õ‰oa¦Â›Û߸Ôww¯~øáÕÝõ¯÷ß_ÝÜ·¶tíÅ 5†üÿêç_“ÕÌþþ*AT+¾z†a­ÉêpÅ8EœQrŠ«÷Wÿiì”ÚªSýÇ©B\9Ñ„t:'fb%¹F‚j;ðþ)‹^ï²}z.÷‘ׯ²¯ß0Ý©/¢8‘ ÔTüâôÐ|áP=)D#¥¤ö¨¯L{4Œ´¬¿¼Æëڥ˴É?zñy¹9d‡êôâ>O×X­³Ýæ¡H·6û š¦MúÖŒM$XÛö’¶Àê,È©£èj£ ô±« ÆHsN¬ŠMú!sƒšZ1çCV65²UÀ*D4w½õ®yÊN –²õÇ´8”R_1sǪ®ó‡"sEùÞ妻]ÞäU™.ÿ¢«)Ý #N¾µ§ô£Ï~ȲÒåyù!۹ܼl*—Ûš´\[Ulnz<¹“ðaŠùÝW§gç¼;¿¹Z?AÌqUÓrç@us~p©Oàñµ ÆD¯o÷¾4óxhs<“ óQÌóó%«'8Œ%Ò”¨ÎDŠ€»”^Ù`Ø'p$ª¢pž2†˜âƒHŸuå#Oð>¢Ò&„¦Ô‡Ã|ï}TËC˜l›HƒÛöØ5ûrôŒr“3I¶íÓ¦n#ã!’"Ì…ÙW !ù’§¶øM·Â˜­ãvV§ªj6 œ%*(!{HÛ¢&ôèGŒakQGåZ FØ‚£vQóŽÚ¢ŒDÇùݨû F\bÜ¢&$÷( 6r«¹žèw–7”òõ!K˼|ÜŸ ?Óï]¾Ÿç¹çº)zJk—•ºŸŽÏú…ƒ9·nìz€Ù00žM€rH&",éÂh‡ˆ"…%ö »îq2·é¹Î¼¬VÅ¢ª>Àœäô®\á>ͽc¦sߘe‘Æ#_ L{‡Ì¡q¦Ð"(|Ìš¦­RV.3-ëg· 2CŠõóS^Lwþ8ë J’SÝLõ‚]‡^x®Î…—ŸEõìur9eu:˜užÉ Ýam«\ÞCæ;CØÉ6Xžòl7ïŒ "¨\p€*âÕqÓ¿C  )P.*:€&D÷<€ÂjˆèÊþ©¶ñK×E0άLOù.ó¹O>aíRÕÞ‹êÁö5äõiÌ'ÚÏHP˜ûŠ6’Äl lF}̶¹÷ ƒ]ž"uŸ~~ieJÞÇT¢°¯’DO‘ND.N PH†™Í’AlÀL´žáaég›ŽiŽë9i×®¸5XU~º¬ÆËÝ ¬í:³Ø´ Ï©½€ë'H€¯Gh™øDœ–T„–e×®¿ï­6»YEgñ öÙQñ-jB~?:þ"]_ÿ^kb—XsÛ&Å,ILŽÛÙš”r†ÁæÓÒjÿâ>lŸ›Ò2=d.Ë©S‰­Ô¯” ¶¨]É/ O~«Î'ØóóT~È6S Êø‹kÒ¢&Té‘NAÌH¤êëòùX7gÑ@ ØþS)#ìS 1­HÏèý~Áüq»s”#þq3½ƒÎÑqhQ ŠŒ[‹³Ce l1:Ìähå»bšà\è˜-f¤DŸ{æìÃtþE‹Ïs³eÈ<ŠD¢H„y ›98¿XåGG ¶ùç9ÇÌM¥±¾o1Q†-EÙ«Øê…˜×EÍ3®EÍGˆêÜŒH§b‚‹¸*-jB—>ñ4z gO™ˆz]“FаîÃBÏ“OkÄ¥à=³cô ø…·ûç)«²4´ Æ¨­8 9AŒê^@zÐ|¨˜¤ FB‹¸-h¬HŸ€æl_ö5ù‡&Ý®=ÃØ§,êY„~ :Lò®ÉQöyxÜøQ«{ ’XFG `â: [Š€:J-…¿*B½€r‡™9í“ èÆi\n‹šÜ¿n—†‘¢/ùópí¢ÿpˆ?!æ¯Û¹@‰äªgbìº=àŒ·û®Û¡?ùR¯·¨EÆ­E†5L°ó‹¬šçW]†Ç\_¦/SG]šj݂Ʋ‡]š$¢'üs2ìbÂ@2Wˆšµòl'á4êè `·wÔê,Éøx5É€LD»½-¨1l+N1aîõäBë¢"$ ¨Î5Õ¦®Ò1Í`7Ãߢ&ä÷‰¦`Ã@p_ϳn™1 †HŽPM˜Ç„ºgi”k¿`ó¸Ý?Ò`o/Ì@´ó[Ô’"£Öâ|£fÖ…Ãå(Â62âŽç‡ÙÄŒ µ²1¡-h,µ®ÌRZõÄÞšž–,«CJ}N™í*ä´'ö~N}f^6öäÕ|q Ùþ.ÌßÒ3wOÎŒu…¹¬2iaµŒÁ6«­þ1;Ù Úmzio\]çeºñçË ¨cÃY÷:ý|¹º"îÞÎü~ûöýû›×.mÚ°:§‡‡>»·FÄ>nxq©ËÕ(1té.Ôs—-ÕÁ}íòúƒ}žŠCB¦öeUà®V‰3pÿrQ&½(=ñ†3ø?¸ÛíßÔuc„®YúJ‰Èâ Ëhž¾ް7uÃV7ùvü°6åÄFĤ· ±ø¹™`OÕ•»Ÿx|¦Á­©úkOÏÌ;cוZ„Ƕ6mŸœÙÔ‡,;úò`pê‹òro^„xòjá™­Ep'í^±YAʹÜmêk> endobj 2137 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [259.4835 683.3704 328.1555 695.4301] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj 2138 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [172.152 623.0288 267.6829 634.8294] /Subtype /Link /A << /S /GoTo /D (root_delegation_only) >> >> endobj 2139 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [352.4539 369.6354 426.1073 381.695] /Subtype /Link /A << /S /GoTo /D (server_resource_limits) >> >> endobj 2140 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [387.5019 339.3849 456.1739 351.4445] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj 2141 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [381.9629 309.1343 450.6349 321.194] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj 2142 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [398.5803 278.8838 467.2523 290.9435] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj 2143 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [393.0412 248.6333 461.7132 260.693] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj 2144 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [255.0796 218.3828 323.7516 230.4425] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj 2145 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [311.5276 188.1323 385.1809 200.192] /Subtype /Link /A << /S /GoTo /D (tuning) >> >> endobj 2146 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [315.9507 157.8818 384.6227 169.9414] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj 2136 0 obj << /D [2134 0 R /XYZ 85.0394 794.5015 null] >> endobj 2133 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F49 1358 0 R /F21 1034 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2149 0 obj << /Length 2820 /Filter /FlateDecode >> stream xÚÅZ[wÛ6~÷¯Ð£|N„âN"onêdÓ³M²Ž÷©é-Qw%Ò%»î¯ß\(Þ:§îÙö䆃™Á7ƒ´ØŒÂÿl¦4ц›Yb$Q”©ÙrwAg÷0÷á‚y™EZ´¥~¼½øá½Hg†ÍõìvÝÒ•š¦lv»úu® '— Îß}þôþã‡ß\]&r~ûñó§ËWtþþã?¯]ïÃÍÕ/¿\Ý\.XªØüÝ?®¾Ü^߸)íuüøñÓOnĸæŒÒ›ë÷×7ןÞ]_þvûóÅõmãKÛ_F:òûů¿ÑÙ Üþù‚aR5{‚J˜1|¶»J%…#Û‹¯ÿj¶fí«cñ“*%ŠK ‘ä$U­Ñ(3’0B‰dDËÔ4Qæl,ÊA £\çûÇ|ÉÒù"[­öy]çußu&`„¦³¶þÔˆ¼eš$ ,ëØñ¹Ü>äj¾Ë³²(ï×Ç->ëùºÚ»‰úŠå¢>ïÜÌŸU™×°¿’éùí¦¨˜kõ¸jíF>~q-ú‹Ž;Ÿ­È¡rSO›b¹qC¿ó}áb‘V„)®ÀYFŒRÜ…pS·+–Éü.wm—¸ªÔó¢t#n©åq_y{¨®¶ÇCQy1ç-t›Ü)@/ÁIAÍüÊM•A8ß=ž]×»)u[ƒ ôª‡ÓOÅvëzEyÈ÷e¶…À£s4xåÒoY•ß(å÷Gg¥Ëgt²‡ü×ûôÕ'ŽO¸§â°ñ2u]-‹ì¯Üóýöèß¾r5á¿ ö3““ iy¢Ì¨yþG¶{Øæo@œBl×8*çß8—~†,«>:q ¶=gVn4ó³™k_—lÞ@ Ç0ø®çüÂ3œP(NÌ¿]zuœRövu—¾}˸ݘ:¤X,`dp²—,%Z™^‰¥e/—’„( µÃ½ä¶ùMo«ÖÕv[=AF5!e½;/Ù„}îG8 dÛ‚…:ÍSÑݯÖft5u0Á¶33¢á›W®9E}¬#oYLao¸-½ ö°v»ÉkˆHDÈÙʶ«Ú f!!ð¡2|>Ö.ìa)9é€$ô¯”Ù.÷ªŽå 6Ù‰oì´[…Ç| Љq™àV¼–KLI%¦ÂH4VÉžlß{•CªÝHæ,uÏ®k‹v0—žžž. Ÿ“AŠ¡ä¼qÍz7?¹öfmÇâRh9n’Ã"öв8`Íó¦_B¢ƒŠÙUú‚EØ÷Bw™Q¹¶•ÇþµBEêb† ¸€?pU" MdüPn ?“ƒP/÷VúÇ1Ó$ÚD—o„†ëwcÎHÊRÞ1ÀÅXSû,:À&:g1΄³Xú³G]K-À q‡NàYŒ#«j—aUı0ì¦ý ‡?€%lK“>Ê3‹²tž-CÇ";™gÇæÚh­Í?˜ úìƒ]Zʤç̄ܣ¢© 0l…nÀnjë¨hŸë¶ úʵH=¬y«ÅÀ»|„kà!y9rVhF¸€šëÊ>Ú²©kB.e#•ç+¯Õ&´>?¸nåGkúàÜå\…˜YÂç·X ¼Ð.ûoÄ ¯ >>@™Øʶn¤—¦v+GË,íòú¸\‚ÿ8,”6FbŽÝÝѲ¬|çÎKe®©w[øh¹Ÿ §"ì‹û0‰Š»b]ª RP@Aæ—,ê7c»h7 Œïò’2?ø¢‰Õ±C•‡ slíÚÌ5]DRÏIØQE¥ejói [Q‡vY çÞtE|Äe†ÑÆÅTCÊ<äË©€¥r0a#§]ÚŒPJ‰J¸r™¦žõ ªávÃ)ð8çf×ÑS<Ѱ€`ßðžã¨g8-Gÿ“/Á“;G~L ¸†qÙ…cC¢NT(;4Ù¾öQ#­Èi™ñlÓ†­óPqÖ±uNCúÀPÃÖyCÒ˜é’3NGø99{yÃÏaÈòsîù9<{~ÎC.ÀPw{¹Ï´QzæéGÚ"â’QKÄE’Œq·€‡vHÄq4ó³™ÓÒE|’zŽ=g=öØVQ¹³Þ½ÃG0dÙo„œSN¸Vê»­\ÜÿÌœiI ™€J1AÍ{Ñ|!=?½Ío‰6‡'‘ê6Ñæ mlˆ6>t"ÏŽhcÏWO´q œ(툶ßøénOXsц¢caî–mX6d"΃’‘èJËMÒcÙܤîdJËÆ®K~“ÄY6¾ë³Ö„ïÐAŠ­¥Ø(ã(65'‘¶= ±¶²]*=r£êžØ–»ëÞ]FŠHÂd ÔBò󙇂Ž ÏŽD÷ÃŒ_ÚgÒ^”J׳ôedFÉþ7ª¨­"í»ªýq£Zƒkr´Ÿ:ÚÖœ½ ¸&$:_ZBç¯AȪ¸_+뵿PÖÕq¿"K¢’dˆFjÄŠîW_ùÖ³âu€wÆ—>ö(‰Š<š`¬¬ãn {A~Âñ¡ÞsØKF«0×*¾Ô”!mQè?"éizm©óÐk¤Îl×âQ1>ÉÔ„Ôˆ!}Æ'LÒ5äoCŸw§Ïú$áLÈ(ëK¹`'XŸ•Ÿð}¨÷Å””E¹ŠoB#5aÈP[€øË¡“ ¶¤" R¸b¶=,^RÿT,ÆTÜFjÄ’.%‘†§]S^çžq¨AE5<‚A¸A1™v|ŽbÐËOx?Ôû”°‡RÄ·¡‘š0d¨-ŽA¸3“² ¶¤" R‘-+„ J—„RÔ–FjĘîÇ–”8’ºÖü­0¯†Æà©A¢V¶¶¡H òê}9p·„ŠøN4R† µE‘hájêÓKKè<ƒ.w¬óÅKË!"‡Càb–4BCSºW`@+Å¡–-¯sOx4¸KÂXª#a€ œ m¯£÷`/÷ õ唀&¢›dâ6ô5EÑI#øD<ɜǞ—±?¨ÅúùØlj|Ý 2X·ÿ[cÑ^øuŠÝÀü‘?/3‘œ7Ô ?™ÁU#õ¶¯óå e”"‹w#5¡¯iUá°"øcä‘ÕàŸÿëÊ_þÍóéá2!"MÏÓžMhwë÷Û„Á‹/øOÅ>gŒS….4ñêÍ‹@Öendstream endobj 2148 0 obj << /Type /Page /Contents 2149 0 R /Resources 2147 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2103 0 R /Annots [ 2151 0 R 2152 0 R 2153 0 R 2154 0 R 2155 0 R 2156 0 R 2157 0 R 2158 0 R 2159 0 R 2160 0 R ] >> endobj 2151 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [352.879 330.9624 426.5323 343.022] /Subtype /Link /A << /S /GoTo /D (tuning) >> >> endobj 2152 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [334.0699 301.0238 407.7232 313.0834] /Subtype /Link /A << /S /GoTo /D (tuning) >> >> endobj 2153 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [373.9 271.0852 447.5533 283.1449] /Subtype /Link /A << /S /GoTo /D (tuning) >> >> endobj 2154 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [319.6839 241.1467 393.3372 253.2063] /Subtype /Link /A << /S /GoTo /D (tuning) >> >> endobj 2155 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [307.1508 211.2081 375.8228 223.2677] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj 2156 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [334.8268 181.2695 403.4988 193.3292] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj 2157 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [337.0185 151.331 405.6905 163.3906] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj 2158 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [364.6945 121.3924 433.3665 133.4521] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj 2159 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [374.6372 91.4538 443.3092 103.5135] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj 2160 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [292.0276 61.5153 360.6996 73.5749] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj 2150 0 obj << /D [2148 0 R /XYZ 56.6929 794.5015 null] >> endobj 2147 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2163 0 obj << /Length 3363 /Filter /FlateDecode >> stream xÚ­Ûr£FöÝ_¡·ÈUí+4Ù§ÉŒ';©'ëq*[›É–°ÅF=Þ¯ßsú&¸*S.—šæt÷¹ßº"ðGWJÆ„gb•f"–„ÊÕæpAVðî‡ ja"õ¡¾¿½øÛ{®VYœ%,YÝÞ÷öR1QŠ®n·¿­ßþãÍÏ·W7—“dÄ—‘LÈúû×ïÌLf~Þ~¼~ÿá‡_nÞ\¦b}ûáãµ™¾¹zusuýöê2¢JRXÏìg¼ÿðÏ+3úáæÍO?½¹¹üýöÇ‹«[OKŸ^J8òçÅo¿“ÕÈþñ‚ÄB.àºû$Íù<¿Àƒñ¾B"¹N!G6’ÀdÂø¼0<Ô"ãÝŒ>F‰ëÏD’ëºó’É;#”ÑX—€3E‡O)xÉ^+‘…qK¥ÌJä·]ÑLŽÿdâÀòj;±Í&uÂm÷ùS1µ‹y t¨Í®./íEs¸ºAíìS^îó»½Ï»Axþ_]ÙѾx*ö1p‘žµo¾S¹`ß=¨ûvPHÇŠ𺅪›—‘= gŒˆùã=ÔÄù=Kg‡¯“¶ŒÈœpMÏÛ/c±P '}æì×Á/Ð<Þ÷LÎ2½4N2žÎ³ÞC-¡1Úm>š+š.E“ÔŒ¶9(mÇ®Ž¶UÛ›‘®¥¦$Uó‡{¨‰Ó]@ºõTLyMš(Py&ÒH4©Î $Ì8M^'‘”f¯‘ˆâò" $’x‰$=&x‰˜TBgÝbàCMø“VN8Ê çL°•'W;X£c P𙀸Zé€.™M}غÞlŽ–•}åN¿?v6'Õ•‰'ÔþnëÂî‡uRDBJ´ õC:Óy@˜À~`k yÄ$J)V®Rª5V­ß]F"…ÜËPÁ™OEøz‡¥ MFŠÊ¼E–»œÂä‹0™Ïóùf™MÛÙYÓy3ùb’c4~d.<<—ZÓatç“3£ß(3£1ѹÉ.¯\ÆVYom(F²mÛÏœò`6Ùî‹¶õ•–9qWt;_OÊ î°ŒŽ2œÐ`Ââ =Þ©alÏkØZ_Ê3 A²)_ê±Z7˜ Ôºæ)·Lqn äuå8r÷2eïh ÊÛ¤ -÷Èo<‘Q ξZו O¦aR|{*gïóã¾ ²jøD )!Ꮏaúf$„m‘).cŸ0Sýqª¶$: pž­íúPçk;¥ t-ßG&[ ¥ÚÕÛqƒ!ûÅ<j°A˜â8 ñ°EöjÇEÎjSÑfWäáƒ.òp ‹<èÒÎt¦K»aÝëJ£Ã_é mX`wó|XEØ9£I:ôÄ®146s4‘yOt ãmóéx¸+g%ƒ%Ÿ>¾ ʦ˱÷C½ºá×K(GM¨…ÜÚ&ÐIO™aö¤ÌðfºëJPJßuT½”.['˲÷è¸ÏéSK•FÇò°ñ|€yËW˜½+N§™ñdÁJ±A½èôœ‰1?Çô"ßì,{ñâäœl¼³35ì€ÕFaÝZR™Q%€n™)Áêˆó¼„ÅǪü‚HM³’YÒãeâx K­†d=Êz:•yÍ¬Ž†8›_·YklÐLa<á ŠÕC.“ÏMf®Åƒ_®?üG#ãf‡T Ó®Ô!Žc‡.,-`¾7’Ï·/fâÁ>wR·¯+3ªíLñçÑm©“f{ÜábÇÑÝ­9û{Þ•NW6yë£ ¤-û·Ðªç <ëÛY.úv}¨ó¾ÝC™NÀ¾¬L; ~Ô&ΠVJÎ÷P„mb§2`ðÁºö+bY£Uæ—É› 1‚³žóàJúf]º†ìõnoRLµþ̘¸;Í+“­*—­*P~#3 Ž!ú5&O8™›Gtö¸çS®p¬|{ &mêó¥í~¤Ù Z4yÕÞÍ©k™Eã`ÆZ_rÊPaîTžá›mÙþaæMjS¹yö¨ÀÔSÑ´öz‰ªâîÛ¨C41º«×BÎTl5­ÊÖgøÚö}âÉU§MÍé®GSUugãZ*Ö¾¯é,简,½¬Í ,[”ìÀzlü:oAØO œ· ÔŒ9(LàÔ2:]S…öƒÍj¥æO÷PÇ¢eJhxþ_»fqùòŠa Jc*=ËB!b< s®ƒfÁízî³:¾dØæóŒ÷PKxŒv›MÄŠ>Ë–T­5£jêtŠ‰ï¾ˆ q<˜Ph\ºÄ ˜™EÂCM`ÁM”„€‡ Ðø:{gˆÞ+И¤rFñd«Œäζn øÝ£]Ï*Þèc]E¹$µ€Èx·YÍ£Y’s R¯y}¨óšç¡Œ°¾D¢®ÛÃhÎæO÷PLJN.ÅZ* ÏÿZ*R1ìêex£+gœ¸*U@謗³ð $÷}íUr 9?ã|žój Ñnóº&h,R¾¤k=¨]sPÁ­ÀæØ€¨ê¨¬Ìxˆ #4fPõÍ£â¡&pé“Ï0™ pù:Áu–¢Q7 ƒ¼8«„‚ó˜dDDÏÝÐ8øòÇû¾:ØŠ óÂæåà¡–ívöbT áp¤§Øi׈%S1äñ”²~çZAHÁ/¶ƒãŸë}¹)'+ ‚ƒXQaÜ­ý¦Z$ú›jøiu£¯=”ϵ™Î÷Ъo$Ì„©Ý[ó ;°ðû‰~W^Òµî¯ÀÄf_šÞ:>=ƒAS>ì:;W›ƒ‹㤙ô-.|0½‚¶ž 3ræ/5¾uwÝÃZ?Ÿžþ‹üXŒ8‡ª?°Š©¬‘ÅŠøÑô¥Yø‰–mz<¢l&¿ö‘1»Û+Ó´ :ßíc¡¯„üeÀ™¯Ô¹Äžï”¢Â¿å×_þ‚ýôy¿@ýTìŒã%"æ<£)$R ,ñ*­÷I u1~ãRK>nLÖÿãN±Xendstream endobj 2162 0 obj << /Type /Page /Contents 2163 0 R /Resources 2161 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2103 0 R /Annots [ 2165 0 R 2166 0 R 2167 0 R 2168 0 R 2169 0 R 2170 0 R 2171 0 R 2172 0 R 2173 0 R 2174 0 R ] >> endobj 2165 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [348.05 736.6188 416.722 748.6785] /Subtype /Link /A << /S /GoTo /D (zone_transfers) >> >> endobj 2166 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [488.512 705.4559 561.5676 717.5155] /Subtype /Link /A << /S /GoTo /D (tuning) >> >> endobj 2167 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [397.3443 674.2929 467.1586 686.3526] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj 2168 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [321.49 631.1748 382.69 643.2345] /Subtype /Link /A << /S /GoTo /D (options) >> >> endobj 2169 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [357.6499 525.7308 436.0651 537.7905] /Subtype /Link /A << /S /GoTo /D (man.dnssec-keygen) >> >> endobj 2170 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [455.3558 525.7308 533.7708 537.7905] /Subtype /Link /A << /S /GoTo /D (man.dnssec-settime) >> >> endobj 2171 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [317.0267 231.1567 385.6987 243.2163] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj 2172 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [356.8967 199.9937 430.5501 212.0534] /Subtype /Link /A << /S /GoTo /D (tuning) >> >> endobj 2173 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [313.7195 168.8308 374.9196 180.8904] /Subtype /Link /A << /S /GoTo /D (options) >> >> endobj 2174 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [432.0945 137.6679 500.7665 149.7275] /Subtype /Link /A << /S /GoTo /D (boolean_options) >> >> endobj 2164 0 obj << /D [2162 0 R /XYZ 85.0394 794.5015 null] >> endobj 642 0 obj << /D [2162 0 R /XYZ 85.0394 120.4889 null] >> endobj 1477 0 obj << /D [2162 0 R /XYZ 85.0394 93.8339 null] >> endobj 2161 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F49 1358 0 R /F64 1485 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2177 0 obj << /Length 3492 /Filter /FlateDecode >> stream xÚµ]sÛÆñ]¿B“—R3â‡;‡æ¥Š#;J;µÔÉt’< HD  JVÚþ÷îÞîáƒ%%nÇcÝ÷ÞÞ~ï‚ò4€ò4ŠEœ†éi’j2:]®O‚Ó;X{{"yÏÜošw}usòê2§©Hã0>½¹À2"0FžÞd?ÍbŠ3€Ì^¿÷æêíß?\œ%zvsõþÝÙ<Œ‚Ù›«¿^Rï퇋￿øp6—&’³×ß\üpsù–b†ñÕÕ»¯i&¥æÐ—o.?\¾{}yöËÍ·'—7Ý[†ï•‡üzòÓ/ÁiÏþö$*5Ñé !Ó4<]ŸèH‰H+ågʓ듿u«îè$ýd B‡ Ã)F©ˆU¨oV9>¶ÊÁV™ŠDE·Ø²¬æ»Mf[¿w6VB%RóæeiwM~6WA2{¨·ê¶+žkìÚ¯ÚGêXÞSTØÆ³ÍöLšY~_Ô;^¹Ï·MQW<ªo©En ê^µÔÞmmÕò¶»â>¯¨»,‹çùÓ¹QÀšXŸÎ¥i…m‡²v“o×Eƒ·Ñ¸­©å绾­©Cˆ.k×f4‡Ø6UîÅØ+ƒ_ZÖ·/fy‹L­PGJ—8?8œ‡qÒK0šM'm8“ÇDó -• O'/WÓDKÉ»#þðzÓ‚ìáó Æ$;@,Y)izÛª¨înw%IVqÁ6­£lGØNlb9ûq¶ÑéšLŒ0AdíáÄÓÀƒ$~ùËRż»iaó˜‡B“¼™ÄûÎIIн–†`†w»­mÉ:Ãd¾%Ë´¥!=ÛãL¨iúb¿&ãXN£ï4.ZäDEe€&[¬ÁÛì $Óv=2" ¤ú“&é^IèE"Q³ü“EQohžÍƒê7ßÒœ¥!Ûƒ/IËûõνc™Ó6›eü®†6|GU·,R¡)Æ2#‘¢Ce~o‘ÓN¯“n0ÿâà‰9ÏrrRÙ!ÓT­åË i’ÐKsï( :¶Â9ã­ˆa+móP´Ë•³0ªy&ùOÖë5*î„ †”¢Û#ˆ‚<¥Ð1D#*ë¥-¿œx À âÔGÎצ³k‡(˜¢’ ¦2üe¥<ΨIãÈ "ä;Í”5H"jí%ý^6›rzäÍ¡S€z—ƒ’oê/e=¸‘c0ÀøcþÈÛœ„Φ´Kw;‰? I™Ÿ5C mÀÈŽ’ A.@1ž$ƒÀSäö G—Ga·«¥÷;’#¹¹’Êyͯi:Ëoí®t–- ûÝ„õ &­ñ3I…’¡W÷vûj»«^9¿bâDíÞ2Š„–IÈgÏ{L-´ÙScJ¸7*écU%ZnægU'vó,«Ѽ#v(²—²bË»z ê°¦¡‡ôÍ÷¯ç×ß\„QŒA[Ï»¶ƒárèÞÛr—ó‰ÎÙ!øý_”ù8À í`äpàP^U*‚È[Y¦á°fnLˆ²©Xw„<©EjäHGÇC€&h÷?“¶R/%ú&u ÇTô*H1Cs> ¦0zi!*1œ¬€‰‰u<6Àœ'gKÔw&¢ªÈˆ$hÙ;Dd’¨Û·i:®­fsÈÊÞy2_%ØOÖ| ö%Ž‚hœú¼çÜÍ!惗1¹`«h9 vèÕ¹W|Ì{98Â[Gkb-:ÆVþ›Èê˜Û” b¯Oõp„bÙ>nrýÔORï—Ñë#Êþ,£â@Ï[Dd“w Pœpô°oŠ5„ hcÝ&¥§PÈê³¥”Þ’QŸ„ :UMíínË2aL_¡½}”žú4ë;\úÍ‚é”y3x%L>`êz/§>5™0ÞtÒÙ]_éÐfX €i— —Xµn[3 tëI·n<šv&íÒ›ZKÌ…5öhûPH86*û<ê´•ÏA¯Çp¨Í,ËN±G•ˆ©ŠbŒ‘˜¬t¼«Q`e— *N]˜sÞ0ÔÉh3k§G‘•: …êêÄír3oòòvÊ$J¡Bés€iX!dc‘ß·µ> ,!f—´sU?ä÷ôŽÇ_H‹«Ìúºlÿ.¬$ó–5Ä#Îvâê+j8ÉDÚ}ò©C"”’ñ˜yŒrMš9·kÚŸ¬YM3Æ ¼Ñžl§CÑ4!`Y¶´©—d§à0ciI¶ìhá•‚£wõvmÑ¡8§sìÖ±ºŒ.¹Ý[âämpÿ¨¾w,&Ãø ‚·Œzè-ŠÎÜ }9H;ï‰ý÷DÃÆÅ´Üšå˜í»ËP/ÿä#)93ŒW,0Ìs‡d°´K?ý• ¶YÙ^1Ñœ7¶çGµ\é¡ àÈ}ÂÐA¿<«‡`ùxÃçî %kг͸gn#ÂëîÙš¢j»àì’><å(:ñFO_'Q1>d“F ÂݦeÀá¬Êïê¶ðŽ µ1oWuF} { νß^_ÏQ¾8‘öåè‚@>X4l7Ùe€C¥SD7JéÕÓ”=«d;˷ ªDÕ Í€§¯–ÅÆ–4¤Q‚2&D.pî}EÓÖ§öéè#N"â4ð©ýðØí_0ÜY½¶EõÅTJ@&šÆ£úNÈ"ï9´¨RCå“ÓŽ‡Ða_k¿±³5Ò}kém ×¥´ÐF'{•*ŠîC~q²¬‹dZü2S®×Ö4ùõ»ëiP1HÙÆV —ÄS8ÏG8|Æn&ñILƒ•§((înYïÊ¶Øø­ÃO*SŸ-&i Q´Œ»"ìÄ¡¤< îØià'6ë}¹¥Æ…‡ó_w¶y|’>Sã°ˉ«¸Üü4Ä ‚FžL•š@0ìÊs·‹è¨ßU"é¡ó X±€Ðü×Í1@Z £•|) Âi·à§O”U á2ñ à¥Ò¨¯®Œ k±Hu (>7‰„J:&O+Ð[ÇÚ¼@$lLâ=Aà’P6Jö>ÁŒýü0žøñ,}ª2úˆ;ø 6¶\}šiËõ‘ïek‹âÜ'+ëê®KG'CÇ#ê`D”tdí¢ái[#U|hkrÌØ‘ŠZ*Nå•F‹0ìâÎ#Å6ü¿Á8.eøc‰N Ÿ’üƒbã5U ׉0a¼©i¢§éßË#Dáã>ÿaÏÛ™§¨=×I"Ù‹Ê?ÇâŒ*¹¿Ûâ<ï9;#EòräžH³^„¤'“¬ˆü”¯À=Oú®¦5aœ5¤ZÆ£ŸjómeˣphïWX2ï À8'øAð%?ÃRÚˆ$Hö~†õÇNy<°ÌÄFè(t.XÜõ'Æ æÝ›æX“*•t?òÑSr 4”."#ý„…ן†ÊKñå'»l眿*üð›¯-fXÞŠ Äÿ.-Ä•.ÔÂAWµÀ•uTÂßqÊ_¾o/ò®ré3*“/¥¯ ƒòhÛl«6¯|õtèÙýS‡½›>æ1 ìèœØ0M —ŽÀãË(<àÃçñ¥HÆüÄE"•~F\t$¢˜9ó¤­ÉÌ ò±²¤¯ô ¿–úO ²99ó`-5£ùTxÞGÃõíù8: óÏ iŒtýO%hÀšÏc·‘„1Hþ4 ôÔEá?î³–ÚÿfL±2&|ú§*r™(eð[!áâù¢½?"¥>ø=­ÿi+C¼ê¿ìoendstream endobj 2176 0 obj << /Type /Page /Contents 2177 0 R /Resources 2175 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2181 0 R >> endobj 2178 0 obj << /D [2176 0 R /XYZ 56.6929 794.5015 null] >> endobj 2179 0 obj << /D [2176 0 R /XYZ 56.6929 190.1977 null] >> endobj 2180 0 obj << /D [2176 0 R /XYZ 56.6929 178.2425 null] >> endobj 2175 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R /F54 1433 0 R /F49 1358 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2184 0 obj << /Length 2620 /Filter /FlateDecode >> stream xÚÕZKs㸾ûW胔Zaðx‹wÆ3ñfÇãxÚÃf”D˜‘D­IwòëÓ)H¢,9vª6å*l€xt_w”pøoW™¸L3Ã…L—g|ðÚ>œ‰ØgÜv§½¾¿={ó^ùAÆ2+íàö.Ë3î½ÜÎ~¾ýëùõíÅÍh, Z6ˇß_^½#IFÅÛOWï/?üãæ|äôðöòÓ‰o.Þ_Ü\\½½…7Þ—q„/¼¿üñ‚jnÎ?~<¿ýzûÃÙÅm·—t¿‚+ÜÈog¿üÊ3Øögœ©Ì›Á#LfÕ2/Wß©„¿O‹uCmÍ–ÓŒ§T6ÌWqŒb•O4G§‡]=Ô0‚Ô&èËœ Øäj0~8ëÑŸsÌ:iNÕŸaFêl_8Ú Ëåâ)׋¸œ€ö¨= ƒÈ6[H+›yõÐçXV³òŸœËiÞ”ÕŠmo”´ýs@&vn‚‰°ÖZ!hdö]Û3bÇ蔞"ÊÛÍ#ìïYZ>$öÁµ‹ÙöDÕ²l€l×ßipx΂ûH½ÄË<Òž)ðïP3Ì[cž1dûÆagƒk =ŸvfÖ–‰Ö[̦ùýìoÖg ëÕ±€cÆ™] (ëÉÛ@ næ_Åyl1„ï®~¢J\#Q HŠß×ùª„!Ó2˜ ªË„uÛ%œ)-78SZuÞ3´D©[©;©ƒ¿ ΄g™ôˆnzæ}ˆÿš/ʹnáyw|‡JºÕ'ð˜úeàÙà±ì+Wc5¬Wƒ£æñpK.©XÜXÁmì)2»±'¶=±t‹íd-E{¢°³'Ê·F8à§§Õª—œ¹¦€e¿ƒ²“¢cG9ƒ÷ʦÏ/Á¸ÎÔ6E0[SòñèÚku”xBe{ăõ–qýåçUІ®–œ<$wGÞ‚ðä!Âøzb¯5b©#c°‘øµ¼¦ò€ã“ãÍIŠÑ¨ù]ÅX£7ŠÙ•Π7u]ˆëÇD6Ì*…ݶ-ª1Æy-†­ÓXVuCˆHw‹m‡!†ùbQ=F}:_AéȾßH².îû0ýˆ×äû|›“wçŠS‘bŸy¬Ð°Ð{Ô6EK@Ûfì´S—¢ŽRÙaÉaEÕI=¬A˜ÊWÜ@¥¹ìO0,8Û2ã‘0&„yâœõº˜†d¢mTûöÎ %ä Éœw‚ãý¹×äÃs£1{áDK‚”áyôÆyÝ÷eýd"f{™Ê4¯‹ÃŽ9ñx¯•'H?gÈöÃ~èç6ÒÇnGžß"_"K—%^‘> .ÿÀaH:ÉŽ±GfLj+ö<3ýÿSH´×‘9:!s¤”SÙ›»asŽdÌÝdºŠtˆŽzv·u4‘.Þ=Ú^>Áñ2frС ²1““t¯ƒÏ-Ÿúho”}-sªÜ¾½¦J Ø)p%ñ“-V\o}’K…H^¯ ßðpGü]Ò¡]á9©lʼéº]^S™Ïf„ܺ&A¹ \ؼ }¯z3ÎówïnØùÍõ(“Ãóx³Š(½¼¶i“ÎÂg½Î§EvÀþÎ÷—x Š¢Þ|óØ©] Íœ±v %gÒèì”IH©éö¤÷G°g™Å+„ÓqJoì]+vË ßr·Ò&@]§Ú»°|­ŒHî oÒôuæ*¨±x݈æÌ(Ùòýw!’Ã9¼ØS *ÄZa%óÄü6?Â×¾UÛݨ!Þ\.åà]›¤ûjG§C‡}Ùôk¹4¼“Ðáð+8\ôeƒ¿‹QÁãúžQÝM9¿ýšÖU]—“œN0|¡1Še½®èލ'[Ÿô'¶a¥—8pa†û®<‡×h‡Ä6/´7 ‹{ðpãÍ/l^†FéÀB<ƒ53^f¯à;5çÌI‹™+èA—Ý»?⃖‡/þÙÑæ7YŽ8ÞË”°(®™R™Ào§09! øF#ᘜü‹ ÔøZïšÔ€I þ¼¥"ÙØæ@kendstream endobj 2183 0 obj << /Type /Page /Contents 2184 0 R /Resources 2182 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2181 0 R >> endobj 2185 0 obj << /D [2183 0 R /XYZ 85.0394 794.5015 null] >> endobj 2182 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F22 1037 0 R /F21 1034 0 R /F54 1433 0 R /F61 1466 0 R >> /XObject << /Im2 1455 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2188 0 obj << /Length 2648 /Filter /FlateDecode >> stream xÚ¥ÛrÛ¶òÝ_Áé5c"¸¼$O®ãä¸m”Ùs:mh²8IE¤ìøœé¿w R”LçRgÌÅXì}ð8ü OG,JeêÅiÈ4ÚË«îÝÂÜÛáÖý¢`¼êÇë“oTâ¥,dä]/G´Æ“Dx×Åï~Ä$›Ÿ¿¹|ûëâl‡þõåûù,šûo.¹ èíâìÝ»³Å,‰þù¿Î>\_,h*r4~¼œ¿&LJŸ'ˆ..Þ\,.æç³?¯:¹¸dË+¸BA>üþ'÷ û§ÎTšh4•^ujÅt¨TYŸ\ü{ 8šµ[§ôrÁ„ÔÊ D¤YÌ#ùô¹t‡s(TÊ$×úèÜ@ð” øç‘LXœj5X%”#«¡Y˜Ä^¬S)©È*]­Y/Q?/ÞÈñ†˜³T*äWž­×Íý,P`‘neàv7¡6Û™H|óçò³[ÔКCãݦÈ:ß<Ð\V?âúüyS×&ïʦF†àè@–j--K{JSÁÚ0ql„iÏ jÓÝ7Û„n¶„|bWÞl‰évÓÔEYßÒü击dE0ÅDávµÌñ¾*[p¶(ôé«ü²îL]˜‚°¨üf¤@\0¿"rˆß×ó³w4µX´¦kw‚ ø €Ê :ôhâeC€X¼3ÛÖ!:Âv"‰X(¸ôbÁˆ’o‰)Cp¥PLGðCt…ü{¼»ßqìÜ={A¤‹ã(œ|u0 xw*1פ^”Æ vi«£ùÈ­u ãJδ’¡së÷³ Âé?J"P^¡Íµ´1í}òãaš*Z3‚­°{%XÄ‹ËJz¯ÉKEtƒ1a+S$Fñ'!œÃP{ä ®ylù½ì0*ëk}deš­éÊÜë¦6MÛ–73Éýµ! ú~ÁÓ›å”Oë)qB¡ˆ@ .qØÎ„ö¹MˆÞ’êÄsf‰Ÿojt*žèÈ öôyŽ(c0O"T«’ýó“-d¦ÀÏ< VÆ…úÁ‡-“©cUHDôåIн„HEË™ÏÙÖÙú«ù›Ò”’ $‡Äß¡k(™RVjÝî±÷ÅJUê6×Y¹æñ*dœØ­²)(ÌÒl‰·å© ì‹Ë8fnnЙ©ššMÁ5òêÔ¯€©RkrЏ¼©ª] aÖÙJ¨û²[Ñ¢®ßIÔ Fuãd»1y0•ÀK¬–˜Âc‰5ƒ¾HÊêY‡#=ƒã¤\;5—…©»²{˜°‡†L!¥p -ýuq: DˆI­ AR Ò¶Ë.»Ýf•Rh´4Ë€ >¢¿œpEô„8:T·mÓ5y²EœûØY;ã ÞU7(Âh«À›‡Î´§dðCŠ$ÐÐiö‹ j¶…ÙžœƒÕÉâv(¬],è,1¥¨µ©oQöivˆã/ýØö¤€«ò¶KYïÖëì]•u†e'Ún úݳ9‡¬?Åã7°½„hvÛ|’t±[h4¾“³úË”œÝÃÆ|'­ŸÍÃó„üùâ7‚ºæ£q^åÌøÝbÔɳ&4€ô·£­è Ž© ¿› ¯w‘£ä(4Ðû¼k‹a×›>Dõb³.MK“§‘­É.7:*‡÷60?n H0¸ûwÙzç@Ê j¯ô+%^’ö[¼ÙŸ".Äkbºl |SR0§l›Ð¾x³‰´‹bGXÒQv+¬‹°z…C«ÛݾºqÛ6è+¸ òÇЃLæjA9l|ºMu™ËŠeÿm7Þ:† Qšxã^ñ™ý義ýöÎ÷Ä<>z ùg»†ëVt#Ð\ãuMŽßP½¥Àºa‹¶úçÑÍðñc” ¸®öåJ4•äYkC±/9-XÂ%ä¨!žê0à¶ÊÚ/"ZíZgTëQˇƒVv ‰æ!ø´ËÖ{_ê8ªšx"µ­AªôõoÇL…š®º—ä’£/Ò3!:—ûúxóâ7/mYÂñÈÁQ~¾oý憛 Üæ+ãfHq‡Ç˜Ï¹Ùt„^,®.ßž<¿rÀÕû³uqîÕíF”šîËg)÷Ý1 tçržÒË"C'hU*Ž¡–¯wôȃ3ØnÍ£®Ë" k‚öï%MR')`»= ƒ¤€v¢àʺأÔéTà»6[ª< «€Kcû(ÄY‰E9¦ÀLL<òçMçæ\–€ÕÐ;D*ñ3H=•eLÑý‘UVô[Âfmzr$žJ\nÏ]¶mÝl ÍZIµÏI}ÎLYÊ)üè)ÊúËq{WÄ [(HÅÐйûZ–¯ú›[ÙvCÇwÈ ;lÂ&.¯“ Ó$ÞžeÂô î–à ïvë®Ü¬w¥.Àò†ÔL‡1Ñøi;…î·Ãˆ¶[p/ lÜF±¿k­Jbec&þ×Ôn y2¬¹qÚ¿tל:§'Ä„74ãÀGE¬ô4e*ôœHùï—©d”é Þ—Ö t¹Kƒ¢\âÁg¡Q”–@ç¹Òû-æH õ~‘¸WP²éÓtsè0êÎQ¶^ _g·þ/nÎêöü©ð#îr…€ã èÈ·Ð×0Êg[XVTd诚{ª® ‘šê´ ;›´MJ[n³›µ#éŽKÇ#ö#’ ¾{e#5{¿Ïí‹… éÙºîKÓ±·mXÖ1õ\³XF} sŽ˜€ÛlèÞ‹0½ä7wÀ…Ív1e—g0Ñæ%i÷Ö‡' ¬.7†*ò¸N"R Ü[%”et´"Öïyvyвà^,zñožöG‰ºO3}9u…×ýnqW6»víj2·ÜRÏÚo´œ¦ÒGKî_|Î*°èÔ“4?œS¯A"F¶õ7lýß2M¯Go]¶CÐjºDòÉ+ÿzÕ»xOcoTœ7Ä!Ëñ—ãôýµ©ÊZ`òÕä¯/åÚ-úÁÑú7VÜüð꩟ؠ= •S¿ˆq¯Ïgÿþ¶ÿq2Œ™Jù•vÐ1…‚~LdN>@W ´Œ¥/DôH,X"!³NÉõ7Õ©\Lendstream endobj 2187 0 obj << /Type /Page /Contents 2188 0 R /Resources 2186 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2181 0 R >> endobj 2189 0 obj << /D [2187 0 R /XYZ 56.6929 794.5015 null] >> endobj 646 0 obj << /D [2187 0 R /XYZ 56.6929 244.3019 null] >> endobj 2190 0 obj << /D [2187 0 R /XYZ 56.6929 218.9933 null] >> endobj 2186 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F22 1037 0 R /F61 1466 0 R /F21 1034 0 R /F54 1433 0 R >> /XObject << /Im2 1455 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2193 0 obj << /Length 2624 /Filter /FlateDecode >> stream xÚÅYÝÛ6ß¿Â6P±â‡>Ø>¥Én›¢ØôÒëƒ,s׺“%W’w³)îï ‡”%[ç.) ¬©áp8œþ8CòY|–F,”ZÍ­Xòh–ï®ÂÙ=ô}ÅOà™‚!×w««¯od:ÓLÇ"ž­î²R¦)Ÿ­6¿Í_þðâçÕõrˆ(œÇlDq8ÿîõí+¢húyùæöæõ÷¿,_,5_½~sKäåõÍõòúöåõ"àREH'âÝ›ÛkbºyýÓõâ÷ÕW׫^åá²x(Qß?®~û=œm`u?^…Lê4š=ÂGȸÖb¶»R‘d‘’ÒSÊ«·WÿèzíÐ)3E2eQ*’ ;)1°S¦•NfI¤Y,…´†úÏ·¸ˆY $Ó¨rÀ9ÓQ$†á±©…y\qÎÍûÎ4UVÒן–yRÐ.ëòm—…©ºÖsÛŸ¬zú–ZÓ“}¨+ã'ËvûÒ°¼Þ]œ¯¨‚£–EEZ~ÂJO;ù óë14'ê©Yš¦–åEåXøÐâ1†C¬CÎEÉ„IÕóÕû®¨+ ²<«ªº£v³àéÜÜ™†>»š~3ú¡åÚŽmæF­“RWÿ Cq ¢–Yçe•jNGdGeö'CA`Ê7'O˜–}Ö SFà ¢X»ÅYwž[@DL€ÇÔv ÚBeÈDÌ·E¾¥æ¡5-¶¸Uuj²”ñ$½lqØ21n«‘Åq†]öD kwœ æ$ „*5j˜¼qM;´uŠÝö¨%™÷¹!éÖj\K¦ÒTƒ¯¾›ZŠ`* ½Šwuó˜5›‰¥(Ž$òKΪ̈́,.h=–ešvJÄ4‡&±êÅQžÂÕÖXCÄñ`Ñq„¡ÒÙ¸ªKꥵCcm¶ÙCQ7Ä‹wãÀ¬¨Šêž¬«´˜Ÿ:šCä‘•í˜ÌP–ê4oÐúï­ Qv`«^ÿËä~Wt­)﬉{À¡¦üŽi5/̓)©™åeK-4…a÷`¥ä<+Ëú1øã`š§çÜêFŽÜ5YÕÂ~µ3‘˜jC AØ<ßj@Ü0Ÿ-‡¿´.h|èUÌhG㇕¨­éú•@qd_ð9Á?Zíˆ3ø[å/¼5ù‡µÔÜT¾òÜoÇkç>æÝHk$˜íôЧ#‰MEËÄýc´Qß PÈ™0kGÀOJ·{ØŽu_—Eþtªø3ˆýwèïÏ~xW›q Lš_ׄF¨|(ÕE4”š…¢?HúÕ[q\º±@¶@¨ˆ%`àSÄ’œ id|!¤ ïúµÜåñ éw“=þeÈâ„k?”q7xµÐáüioœìöŬҴõ¡ñ«\š¼n6Þ••3ͯÛÓÝð‹÷*àïî™4DA^Ç•ÕcµEãËHÀ.ÍR”ÒÎ{kè{S>Ǻn¸Ñ32Jçwô½£þåÍK"CB¤œió¦XÛSzÌP :¢Z¨bFŸ´p”œ;n»x$¸yT—KÂI;N±ÓMlÞïK81pnŽiÚJr97™Í€V¸>Ü-Ñ:™¿-ld!•´…ûöˆÃ[ì±Ã/-~É"C>˜s\¤W—(b¹tSÁçįW©ê DF³™BâÞßf´˜éôy^ݾe}øXÁ_V¶µœ—‡ ®ü|a¼BˆrWÙxí#v:4/Û <íÀ‰õ.C½±]e;´F˜ mÐR_æXêAߤr~MŽsDjm³1;fV õà C ¨E °Ë|¼‹cÚ”ÔAcí¸Ínßщͦü³²¢¸›vrø˜\…Ãɉ-kÛ:/2ëVüv™!öÐÏ>kº"?àž´ßÎnв!¬0ßíëÖ ðó·F‚\ú‚ ĺ,¹¢tøtǸ]fó¨P;j¼Ð ·ÑNå¡·µ&%à—’`h´Å}e g“#Ù ¶Löt±“õ|ïìešËs¬Ÿ¯‹D*èmZë6Õ[¸Ðj¯¿M›&†æD, |ðÒ‚ÛA@ú¤b±‚Oæm n°§ý`äîPvìK¢Z[ g$ìM³+:Ú±ðI™*Yñ®øà³8ä<4èÂÖMÖsºJö«©•xÜo÷&/îžNK:wèǬ¬Y;f2ç8{èšÂ# :±i;FÞxkÌé%†T‚ñ˜'3‘ÄL ȵóëlîgÔXîzþ`8ÀÞ?Œæ3¹¸Þ·&?V˜1CÆå©NŠK– ¡F:Ý„ô\4Q0À4kâÑ´2‚#>Œ>Õ=ÿ%Îä>k uªSBÖÇÍÇMÑs]Ðä\•}6cTPl ÍÓqÊ»:^BUt£3Lt²a¾ãa²?Xܱ?8ƾ9]"‡ÄRE x[CqÞO¸H“*eI˜œ\¤ýo£¼"ƒ½ù¬4.Y®éGŒEý¢!9K“äp»f ±A¢bå®+¿§ 8E ¹Mï ú±0Úša¢ÐçËå8O¿«% £àO!EŽ!_êûy6@kÃñ›ïÙ>]¤ñ¼Y!”uœÈKfAQHY{Yú"ˆUa!µsŒuHM• TÔ<ÖEGYy0Ôtp ¥}ŽC]žÇŠF*ß]ä“Àî±TÒa=:µO÷ ð{ç#ŽXàó¬zt”JRÃä¿éG<ë(§Š/Å?c‘N©N]­~«(º˜OÀžÅÎp\òyPŽhxc'Ä:# UFH²þ*7DöÄŒ>¥pV­÷v×!_5å/Úœ‡ª°()IÅßÜUmìɯ|}ä±í›b—5VbøéŠ{h­e”ÉÖ;9,ÅPíA:m¨I™!¹Î^@²&ÄÆ †ÃÏm7@q8/k› Å6I%!^nEµ™JYì´ŸpÜÕCÌ)\ÞÒnëC¹'%›¢Í3— ~$ª‡áòy!ø·Â—pdËøüðˆ³$¡“4/¡N€°–J9üÑCüIø£ø“öø£OŠ,ì˨ƒﺫóº$Ê]¶Ãx{têþ- í²þ2æäLŠýˆÇ¦øR8D ê‹zŒ &E¤/yL@4Å áÐò½â¿xÁ+W-¦bª8ê&ë2Ø‹î9©\¤¶-ÊRÿfàPË–aðK‡ ¶ð¦ÄߎLbQ[ï "£úÁsоª°eÜG¼70Ë—òÞñùòÿ‘ÆñX3™ Q”2‘(=L™ÏRgÆ€ê0p‰h:>ü[oµ\>Ñçcw5¾ô÷Èþ¾ÆÞ¨¨p(Ný+Ogo 'žÇ e<òÏUnO"ŸÑµß<÷i¤”SUB8»˜Ý~êCõñ±°W¦©x¦ ”š{¥p9œ'‹€G"ÃzÆA‰àçóòÇ¿vŸ/ë/fåwendstream endobj 2192 0 obj << /Type /Page /Contents 2193 0 R /Resources 2191 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2181 0 R /Annots [ 2197 0 R 2198 0 R ] >> endobj 2197 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [341.1654 273.1229 414.8187 285.1826] /Subtype /Link /A << /S /GoTo /D (the_sortlist_statement) >> >> endobj 2198 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [434.6742 273.1229 508.3275 285.1826] /Subtype /Link /A << /S /GoTo /D (rrset_ordering) >> >> endobj 2194 0 obj << /D [2192 0 R /XYZ 85.0394 794.5015 null] >> endobj 650 0 obj << /D [2192 0 R /XYZ 85.0394 486.0634 null] >> endobj 2195 0 obj << /D [2192 0 R /XYZ 85.0394 451.3277 null] >> endobj 654 0 obj << /D [2192 0 R /XYZ 85.0394 451.3277 null] >> endobj 1370 0 obj << /D [2192 0 R /XYZ 85.0394 421.4719 null] >> endobj 658 0 obj << /D [2192 0 R /XYZ 85.0394 364.814 null] >> endobj 2196 0 obj << /D [2192 0 R /XYZ 85.0394 342.5028 null] >> endobj 2199 0 obj << /D [2192 0 R /XYZ 85.0394 256.1865 null] >> endobj 2200 0 obj << /D [2192 0 R /XYZ 85.0394 244.2313 null] >> endobj 2191 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F22 1037 0 R /F21 1034 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2203 0 obj << /Length 3004 /Filter /FlateDecode >> stream xÚÕ[[Sã8~çWäÑTM4ºK®}¢!tg†è©Ý™“puˆÙØéËþú=GGN vOCoe›ª¶.G²ô£s³"þÄÀXfS™\ª™á &÷{|p }o÷D¤6DÃ6Õ›«½Ÿ•¤,µÒ®nZsyƽƒ«éï‰eŠíà <ù×Ùéh( OŽÇ'PJ™¾;8¿]P‡¤oƧGÔ’ÒãðìôxüöÃÅÁ¾ÓÉÕøì”š/FÇ£‹ÑéáhÿÏ«_öFW«%··%¸Âõþ{ï÷?ù` »ûe3•z3ø ÎDšÊÁýž6Š­TÓ2Û»ÜûûjÂVoúLš &¤Qƒ¡ÒÌÃû¿åµJ{æ¸Ûxí÷jVÂC©X*¸Þ¾Ça®X¤jcª¡à)ð0_æ¤HWÌ—²Å|! ÓÞ œLZåóö‡Öi‹O%UrWV5•²ét±/|’W²\¦ÉxN=õ]N…ñ)='³¬ª~‚²ÐYTÔJOdTUrx]ĹÇçϼäcà4K‘°'A\âQ^MÅu>%‰*æQ²Ž©¶)^Ú8¦E »maò2œ‘£ NM³:ñ¦lö³uðRg­ïatL¥‰uðo¨µè'K`¬³M ÞŸ÷¶¾Öº^¶×Gø€#Þó¦lFl…ÏzÇR.T|ð„wXbV‚èoO$WAœ±o’Eà®s| ”k¬>d‹ºÈfO& ¢?¸á‘°ZÞ`לË/Ð,âˆù4N7ß~Šù´ y'uQâ1µ\—ñŽ#æÙ},}¾Ë‰«â‘"®­¦Zy³1ÁÚê±W½¸0þ(ö¸¤¢lï $ @‚çM¹œOKž&£/ù¢¸Ïçu6‹MmÙê"Ž&Ù„‚ô€ÇVÙl3ýe‚ô(›?@+[ )ïÑÊÖ¥Ì(µòñåÑ8ÛÒó䤜dÄu0\iÒh¤ †iVg×Y•Ss•/>å‹ ½RÐ95,ë»rQÔECNŠY WV-#Ѥ=®Ú®nÊúviRƒø’{•iyŸ¡ fdİñó]VSi±ï“å å=ÒƒùJÔó<äÁ„Áó¦ÂÙ¬üÜÌ’ÏŸ³9Ó²˜ßFcZ®î`¾õTY¯»,H‹'¯kAÔkZãa4×=ºË¤°4m ÉÎÑé寣Ö‹ ùQÆ¢üæ(BXkˆ±2<§‘¼º+—³)•¯sz>,¯AéÝå±9ë¡£KâÆ“¹Û< ~Ht©ݼ¦úÊy¾‡mp^Ëþü/À@À«R­{xè5eãùGØ@ømrX‚-)昛¶VyM-Á+€gÀÙËgpòHÞpËÁSƒg‹›¡ùëvn~/£Z¼®£ðª&Ì€ÂЊRŒ‚%p ö80jt±¯\r&,µzCcî a‚)Ÿµå,”j9ÓÑ|é½`Tè“n ±y‡t·Äæe¢øCMœò)xh²OMBh¬òQºc¤Rž\ÖeÌ=`.2 ƒGð“'Tþˆ!mpóZ¦ ;¢d?ŽªŠÛUŒ4/6’»õÍp»¨÷¨"®:"Ü6 ;)k $\7³„zÖ(³Š)­”fQ"gD¤&¹Ëª;*á©ÀgF ±)ð0ô­¹:òp5ʬxˆeäáV~­ñõEÌk¡²Ã“2Š cMó üs`6D#t%!r—Éh±9/‹&Žl¹ù Lv D¯¶;žUZ0ÉE¥UÃ9Oªhôa¬=3¾õA”O_P± Ýßû½ÏqÝ‘gn¯t—•)“ÚöéJIæ•\!jõ:¢Vÿ/m-u—ŽÉ´ÇZ*ˆn½s6ú6œa‹Häá»Ó´š]ì:Ü0¥LOz^ÏRƒ«·çgHym“Ë•ƒ[m8a·³òºIÿ<”U‘U®ËåC®óbFÀ®£WqrvØhk©;œð‘^0-MO¢ABäZG‰†wãÓã3€TxùäÇ‹˜Báðüè:œXd6P܈¥€$ôdTÅÛ-è§ë_ž¡'œi |Aæ§½Ó6ÖÒ¦L;ÞcФSŒùqçÜ‘¼ ·ƒ-tõ<(̲.'åì™wÝJ„?êQ#Á¹JxÆ­Åï²ÐkAïQ¦Ò &¸ ë4>¿Ò§tƒè§bJ^íÊu½Ïë»2:¡1çž)xÀ1ßf`¦*ômWÍ÷àÙ.ÂE¬!üÑ}ÁÍ+Íe³Z(ìpèÁ³:í =¤r0Ÿ ?¾<:…#“ QÐñs?eÌŒ¤/2¯º©\»]“ã¡BúÍ«¡í±`÷MöNw8¿)¼7X÷øvR(*—‰pp¢õ¨ÌcHýÁ£‰ø°"¾Ð׊ø°N_kTˆÔ±SÌàì$ª†¼è¸±çñ¶˜“OóÀéþUhy!u6¥–`¥ˆŒ4MÞz]àýJ©|r½¬ŸËBUu1‹ª7Z?(Å,”.Çoñ.Ç›Z½NmµúÞdÖî¨ASÚ•õlóm‡?¦ P»Þ©O8Ü•!O÷×ì­P›ßÑ%œÿðÏ7™ `ì—É]6¿ ??‹`¡ù\ácúǸÕw µþ Hº$ë1I'ï`Fk—;¬|¨ÕÔªžÔÀ«ÝÜ{x¢ÀM0©P«ï¬Þ¯nKŸÒ…¹€;T>e³e‰nšÆµüœÆáÚÓ¼þ\.>ngAÛÝùÆÑ:Ý‘Qm£°Ã …ÐàªÅ, Þ5)ÊŒ¸7yµŠºÿ?yÕa‡Ý|Á%ãiÏ!¾¶…È•xuû7u%Ç]ðDV~¥”)º—ÔZÌoÂí+®Ö ’¥ôJhÞÙHºîélE÷qÙ;ìß;Ï`g=cª˜“)]Õ?Êâ…çíÒl·FšCeCrAîÖì„ œ _fl‰ZãÏ{:ʵ•–fk™T²ÇJ@lèÁE›~ÿõŽuÉû¬ˆ~Ñ›òKTïŠ Ø“.Al½ñe›ÐœƒXt•¡¦Ïþ0‰zAûÖŸA=þL;¦¼ß¢­*ðÀp*Ĭõ“.ˆK™žƒòF:‰qÅ“ßo‰Ä›jq†Ö®þ jÙN6endstream endobj 2202 0 obj << /Type /Page /Contents 2203 0 R /Resources 2201 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2181 0 R >> endobj 2204 0 obj << /D [2202 0 R /XYZ 56.6929 794.5015 null] >> endobj 2205 0 obj << /D [2202 0 R /XYZ 56.6929 769.5949 null] >> endobj 2206 0 obj << /D [2202 0 R /XYZ 56.6929 769.5949 null] >> endobj 2201 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2209 0 obj << /Length 2810 /Filter /FlateDecode >> stream xÚí[Ksã6¾ûWè¶TU„Å`íÉ™±gœÌÈ^ÙÙÝ$Z¢mVdQ);Þ_¿ÝhP¢K´Ër­[:  ‚ ñõëk=?Ñó†q•êžK53\˜Þøö€÷®áܧÇ šAƒö¨ï/þz¬|/e©•¶wqÕšË3î½è]L~N>|><»8õÒðIJþÀXž|2üH=)5N‡Ç'Ÿ~öN.NN‡Ô=::> ?õBi#a§ø÷éðˆŸ|9êÿzñÃÁÑÅê‘ÛË\áóþ~ðó¯¼7ÕýpÀ™J½éÝÃg"Meïö@ÅŒVªé™œü}5aël¸ô9˜4LH£zå™6Æo¾-Ý‚Ãm£(KyzWXµƒ™Bo,ã ® —²½ÐŠy¥LÏ™”Y%UÀþ+€l<×É׬˜Xóª.fY]”3R ž|.ªº\ãlÊž¢¨Fg­ìµoþ¶)í™〥Å»ÄHkÆSnº0ÒŽYçÈ>¿÷–KÙÂè¸\Üg‹¾ðÉ$_ A¾©Ö#ì3RJ2¡ŒêBJÁ²¤H ©OhM´úP*—ó× D·ÖûŽ„‘žË.„¤ÂeyBèdx|Ú‡8`} ¤“ÙU¹¸.·•Öíöî™”óx!,±ß¤`kDFù,»Í_c3ëÛî °loÍk¦l®ØŽu’)“v¡cÓ”yc5¡ó- #’“I>«‹_8—y(A@ʰQÉ-ÁRþÇø&›]çtFEB}“Ó“ÆÎ¨ó¾¨oHŠÓ;¸,j’çÁmó«! ¡½PXÌiÈlŒs{‘ÜeÓeá†OËûoïyRTÔ}™×u¾€“‚ޝÊ)ŽšÄ³ÔÒÃÂe7eUSÚIåUx ¾6]|ºÌæve@ Ñ„ ©Åe¸œ  ™ˆ$Ãéïžt)0›í­­É·YÇ»z£µœi®»¢¸µŠ¥)§(>:6Â¥x2$äŽlY߀Öt8/‹Yý(÷m‚¸/’R™Šm¶žuW> ±7ÝÊîþ4esÅfH•e:Õ]ˆ üÒPÔž Í2^&ŸËé½A;ò— ûè©Ð9,'9I-o_ÄQÒ'§Ð_ÊqVÓ>æõ³^K®r_.~#eœQf®Ëq9}¡—X§åý­yÖïë å}—þ¤G¦®£þ¾~9 ”¦<,n ¹ˆR~ð„Ø´îºÛä-v ŽÌxÕUBXa™pœJˆáùáD çmrHˆÌòzmfU¾¸+ÆMóªjE'†±b“íÁýì|[¾ÇäÈrÎÀ²:ó?×LŠ˜gßAˆÈÒk| jßf#©q–9á»´I%“&ÉéŠ18\„œ¯Ü*1}¾‹]‘/€„ÖhÈd•tzˆ¡ ró(ø©l7Ñr„öúv¡0õ’¿ÆÎ›+6«BO]—Q‚ñ1¥SÕphùæ§ !S1?aûqx§/‘öáa]R[åã%qÆéCsÁ ¹Î㸛¬&i4Š—GE)Û¢Žò~†:Ö²aЍ.> ödÔŒóEQŸ\I 1‰©RÆYÊš„ü¢ªŸÎ÷ˆ€’þ§œá"Œ…çœÐZÝÓÚ@¨­æ˜ý• &T¨?2ï Rà<`õÜCD,€Òå³åm¾€ëçrF}—Ëš„` ðrµzè—·óevs²i0‡•ù<ŸU˜¡ž>L z¹,ƒ©„GΩ«I`(“^¤hÎòd<-ãЙÅi.FZÞ¯‚©<·ÚU,0ÂlIgm'{›ã¾+«‡ÉEG(ÐP¬x-Ý:œõS™Ž¿Á°¶ 6†û8$ذͧÓ(µ€ð„’`×J ßßã›Í+ÑÚQ!ãð÷È—Wî²bš]Nã!> ¶Ëê¥a¿CÕk ÷¸”Ó<FbºJ9 µAªd,å~úòb€M0È"BÛ´YD©œg¿/#´ãr†A7ï(ðÚϲ+ÊmRæÜ«¦l®Ø8Öù†HCù:GÁaøí¢?0Z¨èÚ§X}ãÔ‡&ˆíã I£›,ÆQ0)dH(C¢ô|†ÿó )÷奺ÉZ˨ì žÖ ñ纘ᚱ—4õ7: {ϧٸ¹(ì½BK´>NóL¢Z…ÀFi¶ÕGkc|›y¿kQ Y¡»‚ŒÒ‚I.(Èœž Ï>ýxô¯þÀ ×h§¨oÊéäqÌi]#„ØiÚ´ÇŽŠ9®»ªJ%S&µ%Ë»ƪw’”Ö«]æp@\b@“šÎy¶¨I*¯â°…Ah^v L±¥jf_€|Ì·ì”n·ìí•{ñ»J 4@ïRGP 1—ê.®¤¸aÐRÙtö øøu³|WLÂ.¶wÉm6ŸCpŠG—y}Ÿç3: Ü@ðR’B( ß䛨7™Ä¸XåÛ¬šÎ°#¬Ú¬œöªw«œ:´†y¯ºô‚iih[ft”#Ûo”'“¦CáTJ ì9tÄ%¡“¶É\óÖÐÉÖ6™sÉ2ôÖa³~Š[ÈkÙKß*á·i«Ã>k âêTW¸“Æ1 Þ±îŸ|‚ü /ù@430"Ñ.5´—IU\ϲzÙìšduø þxçO;“à*Ú¾íÓ^Í®@‡×é’[&x§‡(¨B¹¦ð5ê+—\ —x0ÁrYçƒú&~£rïÕI.‘Õ’¥l³klÃëèŠDâ°(!—Ä6pÉ0*£Mh”ñR ®›51)H¯c¤  Ù0¾D)2F䶺õV%œz)¾ñ̵ëyçW Ž¿*µm÷Ç5æ»zïý–!ZÑùŠHsø ¢œÑø4m9£Ã=”Xå üı«ñD”‰è¹¸÷ä XÑðÍɬ¡æJ˜'Ô\ ¢æx& ì ¤ºVQâ;|5)â¾ ¨ê"ìIÀ˜%>Ñ3LžÌ´ ³âç?Ëè ØÕšÖ7ìuÒ¼ÚWb³Ñ´Õ±+«y>$´¢#»ø°‚y0²šÓC¬!l<ù>lju­ê@SC"¾¢6£!TS>:±úЂêȺ_N9 ñØn ñÛ)j{­{œW…”@oDWŒÇ R BPÉÙ1:²j;²æ>ÁM\ÔÊçùl¶@>+§ÅøäãT 1ÎrÜûkñ(ì~ƒB¶y§âº¸Ë£Ïäë/’Ö,ê%oeà[t×eË‹Ô×]_ÊÀÆ"›=õIþU ÕY¬²P \–!Æá&êjÛõ·æ× ®rd³åZŒó¸]‹A®]«Í~óÏÏc0ŒŸCo¯5œßòML ‚=v2€ÁrÑöR˜NËõÎ?ãWÈ3Ÿ‚&Ä6o“ûìŽÃ®t<ÞÄ3óåå´¨nètF}ëQñª› j<õ[þð—Šz1ÎÎ¶Ô ×ùb¾øó&NnÛoô6ÌqkÕI‹¤'eÂzñÜßx¯së¥JXÿ1C;¦ü¦o-× RYç éC¤Àj ¦™ÖŸ1€û158ÓO¡2 ,ÝK×ÌÐZÖ—Ú«endstream endobj 2208 0 obj << /Type /Page /Contents 2209 0 R /Resources 2207 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2181 0 R >> endobj 2210 0 obj << /D [2208 0 R /XYZ 85.0394 794.5015 null] >> endobj 2207 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2213 0 obj << /Length 3344 /Filter /FlateDecode >> stream xÚÍZKsã6¾ûWøºjÌàÙÓÄcgœL<³¶RIm’EÂ3©¤=ίßntƒ¢dÊžlœÚ”«L ñjöókPâ8€?q'~¢¤:NUäLj‹ÕQp¼€±oŽÏ9u“Ndz¾ž}yfÇÊW‰LŽg·£½2?È2q<+ö?ôO`‡ÀûÏû«ó“SÞÅå;h‰0Š¥wööõ‡Ùù5 $<õëË«7DQô8{uqùÍׯOÒÈ›]¾¿"òõùÅùõùÕÙùɯ³oÎgËã×Aˆüþ~ôó¯Áq o÷íQà‡*‹ï¡øB)y¼:ŠâУ0t”úèæè߯£Q»tJLQ |!ãø‘‡O¥8•›2ôò¹{è©”/àH>Šü@[ÉK9’¼±eéq+? eh%?{wóúä4R*õf'*ð6ycÖí¦CÑEÞ»üAo¨y£‹~SuØ‹½3 ¯«~ Yä&êkcڢʻªm@Gp„÷F›bSÍu‰²?N#_ű–5ƒªa5]œ±~0}]Eq ÒRÀýèÿšÜÂ(óC0Á-;Ÿ¿¥[qX¡ôE‡Ï¨"ŒýT Eªøi†† Ô„ôô§Žä’Î<]´öY”¬F’µ“I^8~BŠ#öþÚ+ïKQ¼¨%ÌÌùŒAÁi’dVŠ?\¾±RŒ½kmôæN—OHa´ýËJáem)È|)ŸójØ&"a!\]¼·–aò9bØîÿ–B¢_BhxZ ‰R~'‰áêæÃ9øC%c9Xÿy[™®ÝTE^ÌøÈ°—$Yä‡"JŸ‘L–ú*ö¸¾/I#á½mëÒPÈÈéc>µž‹1i ï°ôFl½”ô(”G/™4“òp=©“4öU”\ùñ»žLCï²¹m7+›ñ{ù¼í;jÞ/«b‰ÍÄ»×uMÄM{ÏSÝÝ·›4m³*´yu8Qš·³Šb…Ý|?ûp"¤ò^Q¿[æÝŽ*Ëv•;­™~‰Ýüû‰æ¥r­›ð’ ?RÑ3 Œ¥)‘’ÄO2±gq QaMùÕè¦c=†Yèµ·ôüÉÇ©ØÔ…¼,y™Ñ(Ñ4PÞù§µÞT+܇d:­Æg·Èžrªí»¾”F¶`õ9ô‹kÒ ÝC¿ÿÛ*LjH”BËHý ÝEÍгL3Ðf"M@ý8󲕀"#"ÁÏ–š$|ÛÖu{_5 ”ò—Q0Z™@) ²NÃ%E£‚iÞÎ Rù2}Ð<´–-T3mo…žpì¡D¥@kê6]ý@¤»¼®öL¤s/ðæêæ«} Ü!ÆH%…ü)4ø[²? :}ò´ÇIêÃ.„.¡ü˜lõ~Ùtzn|Ø»F§¼TÆž%ñŸWnÅaYÈ êÕçʼ8ŽýX¥„„ÎÞB¼S¸Î–yk@˜1RióD’zï^c­œdök‹¶&JA† 5^IsmŠï/gD°æ 2Oh¬ªò¤˜'¢à5Û¿5wz½±û Þ¹!RÕj,‡TEýu¿Y·Fã+ÈÀ›c¾E2m8±^|axkœ”Èç}Uw§C†D|¸q>7JìHø£m0;Û¶öþ+;¢OA­¡â {¬„çUSNDTøi(xî&9Rö_3 ¿Õ&#%! >g’Bá;S¹û0T"À~ÞjS‰¢Í"/Gq§ÙžüÀ‰:¥¾Óu»¶š†îüž`’_j~ CþMÝa#| &Ûäx$3ï²Ã+ éU†®.ÈÒµD1Ë!hÛ‰cqœ±ŽÝ囪íy'ó`N§¬¯Ó+NeÞåóÜ öê77º wë׎°ÞTÚ\fi8o˜–žxsȼFz{)ëúá )(~žˆ ó'òÐ…Q X°!„ €ô7°Ùä+&’Áàm§&­ÖuUT|Ã0ó69دèΓШ›ØŽ#¢~ €Ø[ç›Îmî–ó©××>5.ZÞYÊáXÍg®òæa×Ɉoô@Š‚hKYlÏÝ4ymÃ4 "sÔêÈ4ͳ¡¨ËÜ,‰b`BæõE×3(6àõK^::y6ª«ˆÅ’*˜y}Í›À[Ö·ÔiÚÒBðHDV#ŽF`)d+¡ì½ÆËäHZQ"mtˆ=˜€7œ'Âûdc ô—:/m’€I¿qÐ=¬-ÏQHh‘Û³Ù;4+A\^ñaEÛHkø¨Or 9VŠÄ¡Û‹dÒ .ù¼ÖSz$Ó@¯Gæ®ßÐ]8þ{ÍüìÔ‰øvÙƒ—Ö¥:`;ŒM#ܹ&Áb(så?°—ú*MG̬tNºÓ˜Œ8e“@(Èž®KêX‡‚ÑœgW+ž^W«ª#¢ Åð\¶÷<ÖÒ)”Y‚šÇ~‘óÜ9oóQ¯y—ªÙ9©È‹¥ K?Í–Ž :uBe«í¦i77^¯Ñƒf“ ’ún  kÎ;MC˜¨E 0èøØv´ŽÇxó¼6¼J¢$"$ 0š(‹ptî&é:Þ²&—¬á­[ NŽw4È©œewQ‘e _0Ë™£‘Þ« ½Ø˜jÑXæ€j9QÑv¼„H^ÐF+Åñ—îD­{Œ–œ·Û„Nn@.ª°ª­ÉÁU~\VÓ~b–ô‘#ȵ¡–5 lÌ5=Lf¤6|"ëêí(?‹]”‹Yä§ðøƒØm‡c¨Á{YÍ á>Ú‡C£`MA!ØUšgZ‡„§«e&c€ÞXdÒŒTL¿XhÃЄœŸZÚð 4!Ó—m_3ò™ó0!éÒŒô¸–¥ì%9 IÐÄïBz/@I;ËÖt>Ý|]òÚœï›Åd'‡•йByw`°k,M0»E™;L±%BãÑ"’iÙ„î‚'âU1ÐmÃÌŒÕȰW5C$/ˆTöÎß¤Ê Ñ¾¯öð¢QW}¸²Ë¸{¢y^|äi ë*¸QÙ®n¹ËëþÑ5Çn§Ã†g™ìQØ¢âÎåC ì¤"Ù„ÓÎ8Ï&ë„âŠ|³©¨ˆdX›Ð=%޵«9ú-ï"†]ºyàc:”«[ØðNÃ'¬B(aü)wãQ;}â6†Cãïýè:¦áù/RFë–€7¶w•Ó´sàþðEŽÏ¥¡¡M`> }™$ÃÇqá˨¶‚/„Àƒ½-‡±ý´Þhc†JÕålÔÀã²ö–±ü‰„Ô¤äHСöèfÔ¾¼¢Ä„½(é0¡’<êŒE!º*>êŽO°|)¹…·§ùã[ôäÀa%vùêMÏXô0“–‰ð±¬K»4Q8+ Æ’:Ì?dÆ{r@ á… êWLÏéÁ˜5ݵå§ÃH5Ž€› "‡:÷²¡%ìJÊ!sC=Â]UîJWéý¦½š2oŒ„îî¡ÖÜ„UçêØÐ ¡?p‰ ijÀs•C ãù»,_عϹ¡ÙöaÝ8 G Ì"÷îPf %â]Þͦ x‚"xO+ZP™©—¤jÛÞúÄÞª5öÚ'c jd)ðÀójZ¿¤; Rk"ÕUC×H€EjÀcýbIÈkÕô."Á2œj¨9:ÔÖ‚ëÍk>¶7oq wWº˜fÍn¼MÔ8à† 9ÂíIÈ¡/tfÚ“±%½@E³7ʵçäJ[ bã’GrÚÇíBV¼Ä[ÞWÝr4 ë¼ùˆâåpn:prÅ[ÞëWüc=í¹À8×{1Ð/"ë¶> endobj 2214 0 obj << /D [2212 0 R /XYZ 56.6929 794.5015 null] >> endobj 2215 0 obj << /D [2212 0 R /XYZ 56.6929 588.2748 null] >> endobj 2216 0 obj << /D [2212 0 R /XYZ 56.6929 576.3197 null] >> endobj 662 0 obj << /D [2212 0 R /XYZ 56.6929 273.0442 null] >> endobj 2217 0 obj << /D [2212 0 R /XYZ 56.6929 248.2769 null] >> endobj 2211 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F40 1265 0 R /F42 1338 0 R /F21 1034 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2221 0 obj << /Length 2889 /Filter /FlateDecode >> stream xÚÍZÝsÛ6÷_¡Gy&ÂáĽ¹‰Ós§qsŠ{“¹¶´D[œJ¢O¤âú¿¿]ì’¢dÊv[÷.ñL‹]à·‹ý¥FþÔ(sBšhG!Zá¤r£ÙêDŽnaìÛÅ4“–hÒ§úæêäoïM6Š"zíGW7=^™Y¦FWóŸÆoÿqöñê|z:ÑN޽88/Çß\\¾£žH·?\¾¿øöÇéÙi°ã«‹.©{zþþ|z~ùöüt¢Œufñï.ωèýÅ÷ç§¿\}wr~Õ-¹¿-% ®÷?'?ý"GsØÝw'R˜˜¹Ñ=¼H¡bÔ£Õ‰uF8kLÛ³<ùtòÏŽao4M‚ÉÊÂtMŒ™/k¼Þk·/öÍjW"G¥Dtî‰Ð< ¼¸ÙÎØg¸+aA£ |„AuÊ·º§|e‚Èœ‹£à”ÐÞ„¤ý‹OâüÝ 3o29þðùtLÐc%¡GÊñ¿Î/ϧg¢#;P£J FÖ—ýçöƒÈioÿ„ŒA«8Œ¶Qh«a3& #A"ô’³Ï ÇñèIzU<Ô«â¡ÞgÏYŒÂ8cû'<€ÝœF1Ò™ˆ–¤#Ó“ù[ PdJùç,E9¢2 0pO`Ðãþõbàcýóg¬Ca­!ãèŸ ˆ–}T4 ¢ÃQTúò¾Þ3ã³ ¢TæËð°+›…¸oíñ0ÇAè±%vñÿëT€#b#]ð"2ì‡æG!ÚH/2à \­¶;œµHe¼Õ°#W}µ(Àè´I>Ûh;žNkêXä_x(_óÐ;Jeð¿3ª‹YSVkz¹_”³‘Ϊu]Ö ³ªn˜ *?¹.êZoW×ņÚ7ÕrYÝs¢º~èM2ãyµÊK^È:_)®ö³‚n7˜?åóùæTe㢮9ëšrc[·$ô¨›|=Ïñœz.>áqSmVyCí¦¢'l´Iëê±4šö‡írÝ›uѰdž¼*o,¨.Š¿Y¥½ˆè\ˆt‡ìe',þ¡ÿWÙd»)ÈáƒÌûH Àû» „2‘LöógñýÛOâÃÅ'•p’Ýøâ’'8fÞ© ðÏÚÇNЃó'Ø—ýg`|íø¸CÈ9áb8µÓ¨3@ÈE¡2ËÅV 5Þ!…½8äqLzÒ^ “ß^ßl›ìATiiŸ ³°,´®¨¬Ÿv@éyµbç*Q+‡' h0|Я0}¢ß_˜>óŠÉßs`ìvçå ®â¦ Å¬ÙÍ–9{[à®:{vSbmë„R’6Žå¸†Ú\‚u½+ëÙ¶®S„ëKÄ`™¼k1«6óz`éà`´Ñ*2â3Œ„^çE=Û”×)ÆyCnþ f};¿‹ýu±ùRlxNÝT´#+ׇ(ìÂxÎty7·,¸+^ècõTÛÔ˜4J½3â>¯Ó:ãÛŸMq}/ÜÒ=?Ô¹QI ð¸Ë7M9ÛBpà÷²@ØLðÁso iêuµEuÙr¹-¿<Ø$hc@¢ÖÏÒIN8K^Ä¶ÞæKˆJ <Œqãkb “+näËûüö;A ˆ ’Ÿªn@‚/ccà, úëBÉ xeàBݘ `G³(׿RWOé–átJ¯¸N|ÏÛ'O|¸K6=wy¹¡Nb©OÞ䨵ä­À(A‚-@à 2'JHÊÀVIýËâKžŽŠµ(h»BÔ¬ƒ¤oNùñ;'8R%e@ <@‰ÚÌ—ønÒvhd_ÕБ'x.Šå³y¨›bUó È—Våš§ß/Šv¨`À§| ×:«þ¦—”ç‚ ?uæÝAK¦”€„VR¯¡d/QTK˜K°Óͽ%}Á³å,ñJ϶$%R«¾CÍÊŸ¥Ô­„¤L”Ô’ï/‰ÚUÒãnSV›²aáI_4: ëÎ`làì9EOZôõxYßßgMãMKÈ J);¼OߥþЕvOÍ> endobj 2222 0 obj << /D [2220 0 R /XYZ 85.0394 794.5015 null] >> endobj 2223 0 obj << /D [2220 0 R /XYZ 85.0394 769.5949 null] >> endobj 2224 0 obj << /D [2220 0 R /XYZ 85.0394 769.5949 null] >> endobj 2225 0 obj << /D [2220 0 R /XYZ 85.0394 591.8614 null] >> endobj 2226 0 obj << /D [2220 0 R /XYZ 85.0394 579.9063 null] >> endobj 666 0 obj << /D [2220 0 R /XYZ 85.0394 492.1929 null] >> endobj 2227 0 obj << /D [2220 0 R /XYZ 85.0394 467.8533 null] >> endobj 2228 0 obj << /D [2220 0 R /XYZ 85.0394 267.9987 null] >> endobj 2229 0 obj << /D [2220 0 R /XYZ 85.0394 256.0435 null] >> endobj 670 0 obj << /D [2220 0 R /XYZ 85.0394 119.6628 null] >> endobj 2230 0 obj << /D [2220 0 R /XYZ 85.0394 92.1624 null] >> endobj 2219 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F22 1037 0 R /F21 1034 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2233 0 obj << /Length 2784 /Filter /FlateDecode >> stream xÚÍZÝoÜ8Ï_1û൪È‹Ãa³MÒ›E7饳ØÃöúàŒŒ={šæþú#EÉ_ñ¤Ýk=¨9EIÔ)E,8ü‹0bQ"“Eœ,ä"\¬·'|qm¯O„•ñ?”úyuòòRéEÂ’HF‹ÕÝ@—f\k±Xeh)v ¸÷ÇõÕÅ©/Cî].ß%TJïÕ?ÎÞ®.n¨!²¢?/¯Î‰“ÐçÕõÕåòõo7g§qà­–×Wľ¹¸¼¸¹¸zuqúaõËÉŪ›òpY‚+œïÇ“÷ø"ƒÕýr™Jt¸x€œ‰$‘‹íI*J9NyòîäŸÂA«é:k&Á™T‘œ±“”sv )©Œ²¢Y§ûS¡½,ÏÀ JpoµÉiwuYÖEuO?ÛÌmkû¸Ë"ë;ú®Voˆ •Vp}ØÓϪ-‰uhòŒ¨¢²=è󟺲½þ͹,s65±†U«Àz¾ÆÆ*Q,æñÄÆÿ[/7¾ðƒ˜iÉãã3 ~tYÒõ«òÝšü(*ÐG60‘,Ññ"V€‹GfÿÞ]Ÿú€áv-ðÊ´i‘RÆ„y™Ñ2t»˜ÃtENÑ£uªü>m‹OVn®7 w˜‘Ðjãú­ëª5\— µmêÜ·E²$ ™BS.kRz5Œ¸'²É÷Ÿò½éyEYÇΉ¬j¿9¬7~VoSZK ùտί=[^-ˆK`kvuÕ@qÜÍ€‚ÃÍvK@{¬l,EóìÜ`›~.¶+ÝÛÎ;öD ÍŇæâÖ´ÜSôÙÔ‡}ãàrµÁI?xÞ‹D/†pø6„!–×1©@÷s¡é‰J×ã(hcÉb¥å³ ´f2NcÙLœ¤Vdd%µå)CH¢ \“M±1méÛ’tìµõŽ8y Ãé¡‚jFkßæ¸c–FÊÀ<Ƚ‡A;êq gù]z(ÛIÔë‘–m¤»±gÌCÑÂî·£`×ìòuÓ\O5yû *öþ¶-œ¢"øž¨4 1ÖÏ£" ˜”›:KÐGâXyàK@Ê%„ŠˆMj¨”>d<üÝÐ—Â™ÄØ*#º‰ð£¨&’77/€´)ÜÈ6áØ}œ;Ž }f.Ìñ>Ìña˜ãv-6dØèQ<·ñdÒä{n|ŸWü‡¨HÓ± €1ãñ8Áy’èšX !ò#)˜ yò|¢qÅaÂ3ÜE•ЉÄMorbâ ~}*ÖTæAúmíokÈ$1ÒùnΣ4ª)î+:¾Ò 6 ÎaK 3:ÆR€< –f$QæwFV™mAξ¸ß@Ô󻤸ôuI)ªÞíê¦hsb÷™F§ËJ+ï!}$¢¿TäVu_¤@û¡9¤¥)O°÷¾hý¹œ°Í+f2˜éq©8æ“ø¡º„Ž{b› oá)§ð”_Øeœ`’)« >˜c ìQ—t#ú7#DD?ÙxiQß 4³$c ((Ø´;VƒJvy¾všÂØk6vvÀµ³nJ ^üí\û`ˆuNÍcH“äænls–¶)1Õ‹¶‰tìj”ád¨øÔÎ?§Éþ`[ > ˜Š#¢0”˜]BWy[þÅ®´h1@L<‘˜Å}iV@˜ÁàqãmR+¹íRO’'TÀœ$®¡¥"ïÒ¤‘ÃÀL Üs‘.sxo¥ÙºÞ~ ùüÇJèJèPDú/,¡ÝJ¾>£q=Žå’,ŒDÔ¥ÁLÞ` h²à×7Ë×Ë«S?Š{cgèbøLB†jú±¾mú6!Ó=t¿£E$gÂç-GµH¹ „ ƒ-Ð(8ãHÜÕ5ÀŒ·Ì`Ìïe™ÿ›T&¤¢/¤ª Æ T¾‚˜IûW] Ø‹$ Žz‹VLGúÏ`Ãõ˜µ»Y•æiï°\"=È#8ŽbÀ· a DÇÕ § £@  xL¨À8”Ó\Z «†ÿ¥÷äŽtò ›Ê¤ Œ‚ñ I h³ÖÞ†ñr¹•‹óV´,Ê)ö‡šÍ¢"1¼†Ç0>–Ü^ƒ®\nòg˜H(ܪ\œ ¹¡Jˆ£:„Ô™äJ8mlêXT}êhˆüÜŠÈŠ¤{Ût‡M”ûso·¯OEè}*ètGVŸÔ½¤µG•›´ +T>)PëÊÔÒl)c¢Pä•–ŸÕô­êÖù²H—|˜SáºC)#OÁÙi*Ü\°qÝB>Eô¡Iïs\žoÝ/÷£‘€è'fn‡gÎ:(£ñ°‹5å{ð- ýY§­ãšš(ËØÄöhè»Ï±’øt uÅDg×·,šÖ\S]ÛÅßÕÓ¨%àãP ½éÛCA˜Dª@>|Œ}^I9¸¯U„NN^°‡]AÚ‚ðº¿Îø£»­¿,JK{ººk¾\Ò«ÖPW‚©÷D[UºB"´5; Ü“IiÜò¢-\ªŽ%払Ù'ÓJ]o._Cpeª+$()¡æpÛäî]šnó¼"*ÿ ¹>½‰`íùûgõ\þÕ-adn æn§ÉË»ñÅðºL›Æ•ÓY¾Ã1+wKH·à|&÷|úp2?üöÐXe·ùø©¦›w“º m3—þ*àX”SôáØß ÀðqæUŸ/¾Xíßô'?šB{¨›Ì ç=ø{¬‰•ÿ/…CK,údQî꿇Mendstream endobj 2232 0 obj << /Type /Page /Contents 2233 0 R /Resources 2231 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2218 0 R >> endobj 2234 0 obj << /D [2232 0 R /XYZ 56.6929 794.5015 null] >> endobj 2235 0 obj << /D [2232 0 R /XYZ 56.6929 756.8229 null] >> endobj 2236 0 obj << /D [2232 0 R /XYZ 56.6929 744.8677 null] >> endobj 674 0 obj << /D [2232 0 R /XYZ 56.6929 576.1531 null] >> endobj 2237 0 obj << /D [2232 0 R /XYZ 56.6929 546.1637 null] >> endobj 2238 0 obj << /D [2232 0 R /XYZ 56.6929 456.8705 null] >> endobj 2239 0 obj << /D [2232 0 R /XYZ 56.6929 444.9153 null] >> endobj 678 0 obj << /D [2232 0 R /XYZ 56.6929 262.033 null] >> endobj 2240 0 obj << /D [2232 0 R /XYZ 56.6929 239.2457 null] >> endobj 682 0 obj << /D [2232 0 R /XYZ 56.6929 175.7981 null] >> endobj 2241 0 obj << /D [2232 0 R /XYZ 56.6929 149.7409 null] >> endobj 686 0 obj << /D [2232 0 R /XYZ 56.6929 105.3857 null] >> endobj 2242 0 obj << /D [2232 0 R /XYZ 56.6929 82.1181 null] >> endobj 2231 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F42 1338 0 R /F21 1034 0 R /F40 1265 0 R /F61 1466 0 R /F62 1469 0 R /F11 1559 0 R /F54 1433 0 R >> /XObject << /Im2 1455 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2245 0 obj << /Length 2355 /Filter /FlateDecode >> stream xÚµYÝo9Ï_á‡Fÿ<7OÏb™ð(egq’òè—«É%ô¹¸™¼¾zóÛôü,ÓÑìêfBÃÓñëñt<¹ŸÅBéD‚åDüçf2&¦×W×ã³?g¿žŒg;•C³W¨ï§“òѬûõ„3UäÉè~p&ŠBŽV':Q,ÑJù‘úäýÉ¿vƒY»tÈM‰ÊY’ËlÀOR ù))Xª¤²~:½™^½¹š !À.v1%u{ _kºíQwoˆX4«²Z#-£u¹2~ºìˆz¬êš¨[C\åÃY/ÌÂq6ô-×ODlן¶e]ýÁ¹$mÎD™yc¿‹A }¸7nß’Vþ·Y»í+§% Ù´Ú5н)±¬Hi-"Ñ¥Ý(‰È­£ 7ÜÒ·´ÓiT­êj^uÎ_¡{…ÈX®µrë9VˆÇ‚ÿß߈C‡®ÏX¦óÜ1XÛâLæZe£ „¥Y&ži’9Jгx'1EÚ ê©&!Št!“ýΨ£=þcK¥b…àÚò÷§YK}Œ±(LX†¡J ð„/›ºn;¶Û'wl›²ª«õýZ4° Œ™F³{w˜óí†Îv=x~gy–É¡óë©kž³LŠƒx¢Pá½ ç.ȹÏd Ú3ÂG~¹4Ì ðFú} 1„ô|¥5ún»B»i›¥ûúßNõuãÊÛ¶©·aÁK•1®sÀeÅ—<íi§œGæK ‰bؼYY IÏW>|€³áÀy19‹0›ýöüj¿OÜ>6Š÷÷ó:›OÛêsYïl‡ë|°¶g㟿}w=f7o)íTIûšôDë„%"#Ëð¦H˜‹Ðº™?õÓ«ÉÅõo—î긬6fÞUŸÍ°™2aÂÊ{ÿ´îÊ/?l¬p×Ô'×n˘è0…÷÷x³¬ÀW»tíç †>Ù>ˆRÀ%Ž¡ÙTw°Çr@³6‹BS@[S÷.°¯®VrtÙ€A£À&/8%[£Ò^I¨0´B‘dÔôõÅäEýQT–A-MQ6eˆ³ÁfŽbÀ (Îmöà@{ßlëqb³cÓvÍÆ¸ÑrÙÛ‰ÒaÚC%$¨Ü‡wìrØOô‚5ˆýžÍ`)\¡þªÒŠÔ3 °€ºëÔÞ 8ˆpß¶¢ÚéfM<÷Æö!v\ “À:Ù²XaÞ@—uÛ¸ý]ÞyåúmsA*q-²Êl‘tÅn¾¥Á[€T¢š%}A½•[;³wÎI »Âø¡uÛѹmÍ‚d—޽¤Ïœ)ðªŒû5#õ]…î‘Y-7ÍŠ(LH`0ýDdé˜P–)»íÆœÁžnÒB|ÑŽ#$Ñ´4Xx¹úcÙ8“0ïû÷æP2»â;;ҨYÔ¦ú¨6Í®ÿºº…W~n]øl[˜e¹­»¸ëêÓœI­ÅsËÒÖ‘°®5®üM(õÞ…¯€p:ÒÙ¾ ¬ŒÿUȨ!ú½g)lVÁxlDi`iƒˆv{ÛBÛB{Á9hÐL–ÚB7‰è¸¶µî7»Æ— þ;n]ÖU0ƒ”pMŸSsÕ3Y›r}çbÇRhhÉáÊ\ Š­ñåe°õ }¶?êž×é¨ÅA•š4¾”Ð@`Ù´ß3¸)c//Æ@KÜU‰¡ºÀÞ¿ò½-[‹úö¹®òÅÅøKgÖ- ÉÏøš”…§oÆ“ñô]:ûÿwj»Ê©·Ëq0§P½såó'8›ú¾ª¶$˹|nr g˜$Q2iÃV—íF²`Ðašv¤ rîuîžœ›A5œ7äÿ_’þ=UÁTVôëõëã“dY’ª0ÀebÛ¢lY-ÓhîJØÎÐxIŸÖl*ãÙD…/q¶ÍÖ¶€Ç8Ò©óÁÅëú‰¨4 À²´±¿—Ô­HŒ)ç÷nUHÞº¥ö¡¾$N ?>Œå~ì­îßu•f"Ý•GsÜL¥)Õiæ|†#è3üšê£'¢ïÌur¼6kq˜^¦‘²% Lù 'iðÓ¶"¢·OüðÐ` e%no‰x%u¸š¬Ö•RÞžõ S›»ë”ȵóMuû ™¡ L¦šÞ(`ÊÏóËË);Ÿ¾Cgž{y~6üÈÕ ÛðAZ}¨&$ 䞾̹œ¹‡0K"þAŸÉ{úÒÛØéîqìY¢ ! òôèÁí”ña„ -zé“_¸0ä‚«Ä7­z ùMAâ[‚×ßWŽo¨†ëF+%†þVÄGþÞÿá¿Lí Q|Ésv¶á#4 ®k¯•5]âi"3þIŽA7©âwúЮÝß· û~xÑ#endstream endobj 2244 0 obj << /Type /Page /Contents 2245 0 R /Resources 2243 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2218 0 R >> endobj 2246 0 obj << /D [2244 0 R /XYZ 85.0394 794.5015 null] >> endobj 690 0 obj << /D [2244 0 R /XYZ 85.0394 606.2532 null] >> endobj 2247 0 obj << /D [2244 0 R /XYZ 85.0394 579.9813 null] >> endobj 694 0 obj << /D [2244 0 R /XYZ 85.0394 357.4916 null] >> endobj 2248 0 obj << /D [2244 0 R /XYZ 85.0394 335.0205 null] >> endobj 698 0 obj << /D [2244 0 R /XYZ 85.0394 253.3724 null] >> endobj 2249 0 obj << /D [2244 0 R /XYZ 85.0394 226.0165 null] >> endobj 2243 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F11 1559 0 R /F42 1338 0 R /F54 1433 0 R /F61 1466 0 R /F62 1469 0 R >> /XObject << /Im2 1455 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2252 0 obj << /Length 2882 /Filter /FlateDecode >> stream xÚÝZÝoÛ8Ï_a,œÄZ~IïÍÛu»Y´i/õ‹kû [´-œ,y-¹Ùô¯¿!‡”d‡qÓk~ E‘Ãápæ72øÑQœD‰bj$•ˆbBãÑr{AFkx÷ꂺ9?i2œõËüâç—<©H%,ÍWZiDÒ”Žæù‡qñè (ñ¿ÞÞή&,&ã—7¯¡G¹ˆÙøÅoÓwóÙ¾HÜÔ_nnÅ…Í‹··/o^ýónz%Åx~óö‡ïf/gw³Û³«Oóß/fóŽåá±(á†ß?/>|"£N÷û‰¸JãÑ=<ˆ*ÅFÛ ó(œû‘òâýÅ?:‚ƒ·viPL”DŒ', 'ÁBrŠU”pÆ­œXD"³3‹nn'Ó_½‹¦wï¦ „Àño§ofØÅy¡™ àcBi¤â˜Y¢Q¦L>s7?ó‰ý~~Ɇƒm˜ŠÒT*»Í+]é}Öj¸+3lÝšN2®W80u¯«;oþÀvEÓ±^Ö¶Íà§Éø¶öôÚö þÖ I˜:.Ö·Á¦#Ù¹›[4GÌüyr9NoÚ}Q­í6ñxî‰ÛŽü}Q–!q.4j£¡°ÛYzðt¿ÑöSèìsÐuÌ™UÈô,sÐîì‘ë¥n;9‹3r¾|{wóêæolöÇôͻ׳à½_¾šÝÎî¦s¹¸^ìþööý|r‰ý©{10ÝËc:ô蘋4íOÛè§°ÊP)ÎRKÙ‹@ÿy(>g¥®œ¸Ú:,\+íZ»7:LhЧ¡¬; ‰%¼Ð³ï¹r%;¿% I0¼ðÙ[òó[òç/<¿%=‡"(6ˆždòXà Ï_âfë) '%j$R±D¨çà:W<’Džàú·Êó§áq”&qü4¸Ž-×õ+ŽIMü™&B¤°X‰Îi0:Pv€_•Ê‘@E%è3öYµÖ£’%Mì¬ùÆZU’Ž—Y…‹XÐÖ•íHchïkì¬êý¶ù;€¡0ȘíÛIÓÖ;·jm?þsÓê΄o<©Ûä#!lß´!50»À$AÑðò®M—êÇÓЋÀ@[cKÍîDÂTðÀ–£á˜† ˆ·G͇¦Å1+ÙÕMÑŸuÈ ŠªÕk½wµÐí½öO°é ý#‰ ûÈ ð Ðx4ÌQ‚Ã)noèUuëIb[fÿa/ï>²Ê;˜z÷È&„„‹§ Tc ?ß§’Fù9Dpàf—êhvKžÒs&âˆ&ƒà(¨ç‚àÁоÜ4ÏÔr#å\7Ë}±Ðö‘¢šñú¾2"5cU¶õƒ«“Yv4õÁv–_Ÿ#8ÕèžinÒgAÄ“sZ=˜‰\~µ.½áÓHH‘¸#]B8 ƒŒžåuiÆÑ]WFáÜÓÃvQ— >Üí¦¨°oÎúxo* T—<Ã2§‰9Nìæ`È„DQi5>`WfKˆ†Œ$&ŒÁ½RAmjñ`"+RŽ‹ÖDŒ``"€ƒ6¶£øx~¥Ø¸Æñ5Æ)†qeŸÌùލՇvw°P!ÝC}ÀוÆO"xHsÝËl§ûÅ…sHo†%i d †)ãiÙòßM™5\JÅp)3L¼ä«qPõ”zâ×–ÕXGë(@Œ%‘¤,=!FO‰‰3Jv´›IÉ„´ñcRàÁ!â¬Â‚Xü„mö€Ò¨wmQWYYºgkBЮ@›ë{s?vô•‡&°è•/a[ç…ñ-“@î7Årcº`·ëí0š6tÀÖA-WÖw˜çÆÙ[\ÒMëtRM#jÉ­ Óeî¶)òvƒ]ƒøW±È£¶ û 0 ©çSÉ©¨Ä¸d#?,í¹a‚1 ó. \/•Œ õʲ Š\qš 0¢Ô«).ö`’"`£b»Õy€UºAþ's dèÑ‘Ìár¬b3Áž°¡¢˜Æç4BFÜpBÖ„ ˆ‚«`ü˜Æ‘Ž4tõ”Žû ýŸ¶·÷áÚ\ѧOÊ öNbéV®Ÿa&ìxi! „¢ÿʶ»R_XJÀíñ;Ÿ<•xî©À9_óë<*âüÌ Žn 9,Ü•3pÑJPy|å-¨Lk47MÇŒ`;°œÔ[t–‡=ª¶IÛÌ€p°!Ádµ êÍÉ çm¥[¹ 6¹^Û¬Äë¾ì»€É}ÑÈÒd—å¹Å÷„ôfËêB\âÍ×tMeŠCØ75¾åsV”Ù¢Ôn¶u8ÍÆÂØíL×Ìé¸Ã½bH[€ê\z¸$"©d½¹Òk¼NLDEO,°^¶V \>¹¥ V^êÀŽqsu¼#ä3j¼ííEÎÓ§vÆ>¯a!ˆ‹Î€Á66Î"É;;û#kÐoÞŒ…™Sv;¼ë%˜°ƒ2`Õßæ}U,ì-ž‘e Ð~óÃU„Óôù¸ ¹õˆ©T=׫¯pSÚ1Ñ·<1ÃGǶȣ\¥ ²´\¯2kGæ¡÷æYš¼)pSˆL¹únœõºF®I(Äò”~¦*L$á,a?à tÿZ´ÊRæ¯sÇÄ%\ ”lÑÔå¡ÕÎÞ7‰ÔI„ÚÕî†ØÜ (C'HW —26dÈäpµUîë†6(V M²‚ùÄÄÖcðýGšqS*~jîß™B-wXŒc¶i{ ÷²íS|a^+|.Z|¾ÇÒ"44¸î3Ä6¸25 2 e?d\©OˆÍMpTg6€ƒ±c(‚Wy±¶<À»Ìev™#¥w–™ÍKÀp]‚ €t³žú ï⡇0õ×jYrÝœÈßRt 8n…±a0dzgñxYowY[,вhm+ü9á¥Îöea“Q6ƒ`¸ Å TÊ(U˜_†â)Ê#“þ÷:evhZ¼c&ºÜu]_0²ŽQ„ÐU^ø€"¢q|ž%œÁ|FO> endobj 2253 0 obj << /D [2251 0 R /XYZ 56.6929 794.5015 null] >> endobj 2254 0 obj << /D [2251 0 R /XYZ 56.6929 496.6186 null] >> endobj 2255 0 obj << /D [2251 0 R /XYZ 56.6929 484.6634 null] >> endobj 2250 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F22 1037 0 R /F21 1034 0 R /F14 1060 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2258 0 obj << /Length 3351 /Filter /FlateDecode >> stream xÚÝZÝoÛF÷_¡Ã½È@ÅÛrI¢OiâôRàœÖöá×öa%Q6ŠTEÊŽû×ßÌÎ슔(%iüP†Áá~ÎÎüæc‡’r’%‘Ðy=”‹‡áF–¹*×öžypÚNI£ið…)ùBZÏÖźqÀIƒÒ€BPÌm[|K:“FG™ÑC9E¡i°ý-ìÆÎ+¶A·34Î Ò 4¡B ¶¿%«pAÒwæ}CàZK»7nì (I"•g¹—"ˆñ‘ø—#âÔ+Àé±8wõíâ[<±Ù{½XXöZóâ¾d¯ÖÛG<‘‹Êu¤3©†rùmWlK][­›–á[®×Ų´]g–`£({ë\“ŒÉ õt³}’eÇnw„„bSƒµÅì´h*ù¬Cà%"Š©?évŒðc€£‘u$š Ì“øí-³÷^1{/=->näå‚^D€fw Mg["í®k@ÒåÂV€42`ˆÐB8ÝžxµAè$¢\ÝÁj¨$|ñŠCÚ·µ 7çAýl§6ú„8!±Á¼$ pAÇI:šñòÇÍT¤Dæç4´VgÚn燢ÙÉÀA“Øô7æ @Y2Íxf|.çðZÆ€©W¦‚ð$+¸î ´z3_u>` bÜáÈGo ?ß4i³©žCèC÷Cvð¿Åa.‘Qz…ŽU,D@¼èY>ÐÎ[í…ä@앉t]Ë–H+YÒÍ’ƒ#Jüv&Ý~›mË/맜ɊÅòØ)¶dµÐ‚Pjˆdvö&ËüðÏËä|O´¦æ Í3Ï‚Ûë™'ØÐ«Ê¥»)dQ´-É ^‡‚ ¶ö¡ÙUK¢ïñ\‰!¿•ø 4¡–(ÒŠKI²´÷ËqÂyu’Xgp2g<¡l½`^ ?¸?¨™ÓQn}Þ3L ©»P_(I©#úÞ–5çy*ƒD/Ñé¾×M‡g”=3' ‚8?W ìææ ¬àšÎ;Å9„•Žò‹5ÆZ×EwŒÅCÙAÀÙQï,x± ÁB_E:¸cfq&ϳ$£XhÏÓ>úÀZ¢¿VI“B†ÝŒy>-¢Ô„ç,1ʲñ|Fw(zmŸÁ®©é©ìØoénŽCkZ‚ƒ‡“£SBÔNnd4~¡£Â—¶ü«¯À- m©«á!tg@ÊVJ¯ÃB ÔÚS/˜ÓÌ·ö†€défªé“å=BTr<À=²^Ž]½‚fìî2Ÿ/Tô⬞|7ª©]²é&´å’û-=ðQq± ˆ¥šþ硬Æ2x¸‘F© –s2‘JJ3 b«%ª.º§fû¹~†.Å.| ›,—tƙʇâ°M¹tãP_Ð&+Jx ê|¨A¸5ô¤ËR¥¶<·Á«7%ünÓÐÚ¶å¼"©ádVù (±-«Q¯ßË {þ•¡ñ**(rï}Í´µkOy¥¢Ç¥bdB½j•Oï.s5å…a;8 ͱôða<ÝV·=‹ÒÝüQ¡Ú IËITÄYˆ^§Òë\eɧÒëÞ2ûë!DZs2‹ä±¹8H}×ö‡ ˹GP¥‹vña·á¬eÅ7æE®0¥Ø|dj9HºÐ4b0Ú]g=¿.FŽ ä'ä¡Áôîî|q„°ƒx¦«:Õ¹bHÙ«s¡Þ"¸$(Hq¥+æ:W¿¦‡å‘²åSµ­,2iN¥2_’TR IpœðßRkÕP1JñýWb}˯îÚËšÎÄ19¥Ø =T¯iϼZ[<²;sÁA¯ìÂwÒý:À¶ÜF7h~°ãÅ ç»±‘trèFÉhÀª÷Œº;‹qE+è óhËŠÑ1Hïe½¨vK?ÖeR#£Í®væ·å.õT„rÎñnÎààÉ’‡5ÜàÙ#‡[¶°Úq5³dxöj àÁô*zCU%¡ÞÕÃ"àýWŽ8yo Øðd¬©/±­Âï›-Dä¥y”ö­šªjžÂ=î–¸ÝJÓy’‡’Q*’äóJÓ8Ö +Óh’g 2N)âÓûÓ<K1I3ôÁR3>xó4Jsˆ¡è=HWU¤u,áÊY£69©Á‘ݿ튖ŠÛ}‰i ;H™Oxõõ<‡%gý5¹†”(‚ zÈ5á'ͧõn=§Â#WÚRg‡þHðöæú–º}ÍÔÏu­88Ka½‡ÿãë÷o®Žð¹<¸Òļ 4*Z¤f2ÛÝø‹`R`–fô'0)sSüùjˆÉŸ¸Šx’½ ^ ’g™ì3í ©S ‰4BŸ{Hâ[¨‹â‹ _H8ØÀñ†¿ãuÏ›â _L (‚6 ©K¾àD~Æ (*ÂRêPTp­OeN¿ëî›Ï†bƒ¯cyÅóL{(˜vP„Ü1@i„¢{†ÅBí¡ˆ]ŠHCQ(&Ê8(ÕºëR¢Ò^MÚx(¨Ùekî+*6󗸦ââ}4øq*é#ýÆç!eñ„w•ÓVðr ø“9dýrYd\Ùê¼$Y{\[ÿÝðÖèî ãÑÛë¥|óyþƒAôùïq ÊÁ]Žov6AdÏOkÓÏƬï)x±€)g@ùbBø ƒRÂåRÄé'@©ãHƆ~^ñ¿ðyÁ9Œ¢¶áËùç ³·á‹!óì!2û‡ Ó i<ïùW!„K“rE¸[w1ó¢=q4¬#âU訄ўúTÓžÁó‹‰î¯›jÈ ‹OáYäQ¦áü.¸ú¸ø¹îïñRÙÆy¾„û|÷! °îA86‰w®ØQ»(‚! ع‹þz±Xpeþ”~L£Sŵt×àÓ |;N+fèf£ŸÒþXvñrÿÓ_Š4Jró%ÈSN@?Åê#Hë,òeª£$…˜è~®é&»Ÿ7ßq!â¦-Δ!z{|%×{èŸåÛ#À7åÙy²Ï³sCy6´ñ \Û†:—@ã“hì:ú¨C­Á!«réu*„3XÍäXQlB »Ð8°Ý6,œØÖ…fÉ¢Ç6Üýï$zì Š¨/“tÃÿ\ùЍ €¶CIþ²ý@?EÓûB:$súå´.šª¢BjDßU{׳qÇý¹îôåŒøÅÜiXQ€SÈŒûf"c9öcc~OüÕ?mÞÿØ;N#e§J¡$¦s‰Q×ByK•\ÎdÒûU0ó# LÌ~ŒeÏ¿æzÇú?õnq7endstream endobj 2257 0 obj << /Type /Page /Contents 2258 0 R /Resources 2256 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2218 0 R >> endobj 2259 0 obj << /D [2257 0 R /XYZ 85.0394 794.5015 null] >> endobj 702 0 obj << /D [2257 0 R /XYZ 85.0394 769.5949 null] >> endobj 1963 0 obj << /D [2257 0 R /XYZ 85.0394 752.4085 null] >> endobj 706 0 obj << /D [2257 0 R /XYZ 85.0394 458.4919 null] >> endobj 2260 0 obj << /D [2257 0 R /XYZ 85.0394 426.3863 null] >> endobj 2261 0 obj << /D [2257 0 R /XYZ 85.0394 364.0592 null] >> endobj 2262 0 obj << /D [2257 0 R /XYZ 85.0394 352.104 null] >> endobj 2256 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2265 0 obj << /Length 2796 /Filter /FlateDecode >> stream xÚÍZOsÛ¶¿ûSèHO"I€è;9Žº'±•÷M”H[l(R)9î§ï. (™ŽœØo&ÍL .‹Åoÿ‚²qø'F±bÊH3Ò&b1ñh¶8â£[˜{w$ÏØ3û\o&G¿œ‡ÉÈ0£¤Mnz²Æ“DŒ&Ùb; ©×»Að ¤NX”@ÀŒ5"£èƒùHU’ =ã2hÖÓÆºŒë|Šà2]äD¹ÎW›|åÆ=ã{áž³º,óÐ.N«ÌIž×w —^Æ?uå$ßÔŽt7/fsZÚÎÝdÓÛvžº}ºÙtÝÎëUÑÞyÌÝ<¯ˆ§ÐQ ÜÈ„jŒ›ØÚQ€L)ÇnO‹ ññÙÖ´ï…E ÙË/¹Ï‡¤ ÍL(lj¬Læy“» úÃ>ÛÂÙ”‚ű:të®hçDˆŠÒ±7 6E~G“˜¢ À‹48… wa¼p²›Úºê’6¹S‹,ƒ=‰4ì©ÉƒzQ´äðB6ï Èò›t]¶=iF¬³«…‹Ò  ä冪‡¾ÌÖ+z­ÚòI°Ã]Msë GBy“ÎPO|okb½E«Z™3˜Û™t.‰ƒ­iÀl*’ÁûÊÍ—ï¶öK–eJ4“u›‹´òÜl½XZ¤Tb·—Ê8 €ð™sYºq³ÌgˆÛÓ{· ¸º¾€ð×Byßßdì„>ôÓØ0¿bVWÈy»^Áʺ¢½ê%ŽÑ…UŒÆ!MêvnãlÐÀ“,³¨Û¼¼'&¹˜ÒÖÆ„ba¬<ÔálЏ° >änhy6O«*/iÒ½%?A3ùy3¬ ”-UoM¾£}ìéP­[$ä8A–CE ³9á3y“çµWJ@ÇÃC…©æV·#\ u“}þo”ÏeK7¤oRÍö‡*Ó¾6BX£u¤Žë€¥Ù|HˆëÁ¥-ÍaÈ„èµÀPCÇ‚sîh¶ô(íkàþA÷“Õ Çš-ŒÞdg LºÄ‡39….ÐÈC‘FÔ.öt×kÛú]’Ô) ­È ÷34šå­‰ÜzevÖ@|V;2 ëQ§G•þ³×†æ_!O•ß!ä³”úPbÞò<–™±Œ:ìpc‚뮜ùb¶¿Ç©wž§Õ±0ÄëU ù̈”}‘¡™]/)&.šÚ±rØwV»Ð:+Òé“Ò –Ö¶õ,‡Ç1²P¨#1݉­×”ôz=”‰G@¢ËoÚEÝ Õ+׋Šf¬ïßtÃd:í"Ò3`½¹_Lë’˜+›qdµŸQtW.üÆð…ð÷3œ$!Û©slœ¡0´*U^æÂÐPµYt5wí1Ý™Œëƒaºéß&“DÙ‘3®—ÅŒ&¾¥1Áª¸;ô,—õ ¾Þ›Üiâ.ü`º¤”fÓ“öî6Ç!t6ëé®hj×0wZ65Q|æÒ®iî‹Ú9šÛ~YK]Óuk·P½¥…ãÍêÙu§Ã²¶w{štå4%â2äv‹:³-ýÌ%ŒCÊ8˜æ­­F8&H³tZ”ï1Òñr(Lp’e.¶¹ 8!]ÛØƒá"½§!A2éÙ §Œ(…ÛžN‡#r~ÜFòàöÞc… ÙjQd™EMê.hpœuUÆpž»ÜÞž¤ Z÷)³.^ · m‡h-Z¢z·¡EžÓ]Û%4vTÙ-ÙpÌûÔƒHWÝ|zÇÍ.§Hö{p×ý7®/Z.K¨SWË&òý[ƒèíÓ:¢~úí߉”`:„»‹ä’iižôÅ0 Y¤äw~1ZÔû|í}÷éß@=¼{ß@ýÆÂp¸û†ÛωïK˜€ú6&bÐûÄt‡tùUEFZS:³yzˆMô[J,6¬|Ò˜6Jdoïçqã*Œ_ðÿ!¥X‚²»û­B(‘,âqhºÊÿ^ÃÕhAYÑa\}úB˜ÍCä¾:\| öÈå+¡±e–C$fL"‚KH3¿uœ¸Œ|”gP†Ä†Æ™`?Ø`¼z¡åú;²ÇÍÕâ™_à÷̾¤¹" g åsÅ ‹L¼c-õ}ÖR?¹µz8¼”µ¼B/˜~BÎŒI+ŒXœDÊ[ë,«~ØFWUvo×go/¯±³à¶_ïAêMö(¤[e_*]ýº0ŒGÒ€Tâ«&ò@½I3„å¿ö" Õñ‡Á]WÍz¹¬WÝ/(Ö}ô‡ÂÚ}øx"â½Ã¼,ä/êÄ\3žh}rÁ™ÒQW!&×ï~g»ú{ìéøó"iàšÊ¥Ö$Lã/ÂâÉVÿP.èiúó™@; Ö·áLÓ š°m&x–cÕ&-‹lûydë©þcLó-îMq[¥­û€ü8ðt¦èç^ &á¿o¯#–ð$éòÁéüsWÇqàëA#Ø5û=Á÷¸qOÑŸMüQHÈ®J²$v¿.¬ÛùÇÕýUþ\F’(®>=¡¥;qk7ÂM¾ußj¯b­¡ˆmò­ÛbcVä; ÿeÿFâqзçy.æxøHÚ6: £¡êøè =žúG[Ûñï’D~ûwÇ0f( ¡íý(ÌÂñ¸êˆ¿Í©à,2„[°“Ð;Õ¿»Ë¤¢endstream endobj 2264 0 obj << /Type /Page /Contents 2265 0 R /Resources 2263 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2272 0 R /Annots [ 2267 0 R ] >> endobj 2267 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [55.6967 609.4655 116.8967 620.8575] /Subtype /Link /A << /S /GoTo /D (statschannels) >> >> endobj 2266 0 obj << /D [2264 0 R /XYZ 56.6929 794.5015 null] >> endobj 710 0 obj << /D [2264 0 R /XYZ 56.6929 595.2764 null] >> endobj 1821 0 obj << /D [2264 0 R /XYZ 56.6929 572.2976 null] >> endobj 714 0 obj << /D [2264 0 R /XYZ 56.6929 369.4161 null] >> endobj 2268 0 obj << /D [2264 0 R /XYZ 56.6929 344.8374 null] >> endobj 718 0 obj << /D [2264 0 R /XYZ 56.6929 237.3939 null] >> endobj 2269 0 obj << /D [2264 0 R /XYZ 56.6929 215.0827 null] >> endobj 2270 0 obj << /D [2264 0 R /XYZ 56.6929 215.0827 null] >> endobj 2271 0 obj << /D [2264 0 R /XYZ 56.6929 203.1275 null] >> endobj 2263 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F49 1358 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2275 0 obj << /Length 3012 /Filter /FlateDecode >> stream xÚÍ[IsÛ8¾ûWè(WEìËÜ’ØîqW·ÈÎTª—-Ñ {$Q!©8î_? )H¢D)V§T®2@¬Þ @¤‡áô´@˜ÞS†#‰è¦g¸÷ ê~:#¡Í n4ˆ[½¹?û×Ó=ƒŒ¤²wÿ¥ÖšôîÇ¿÷ßþçõ»ûËáù€ Ü—è| $¾¹ð%Æ'ooo®®ú0|}®xÿþúöÆ/¯.‡—7o/ÏÆh ýy4Bè{wo;…žw÷×oïÎÿ¼ÿùìò¾Y@¼H‚™¥þËÙïâÞÖúóFÌhÑ{‚Œˆ1´7=ã‚!Á«K&gwgZ×µ 4Î5`EUoÀ4âBèíÓú)0L²„ #Äú¬ƒWØ!æB5»@I´ @’ô”0H2ÊÜ. ÓÑûây˜þu>à‚ÐþðÃð½E úÒ¨/Ñh¤pÝkQ”Ù×Ôýe‘YZúâœè~úW:ªÒ1Z\0†g¢“ú²µsΖ0ä np489GØ`Ñ'WH*å™úãcá°”‚ÀòãÕ°ÌßòYÀ±*’Yù˜1€mYmDöÉBË("L°h™@Šã`ú0'Uê9URèBI7ºϳdš<€ 7Æ áõ¤ó“†—B3i¼”!%¥"]ÎóY à€`ý»×³r=à;ËtVí."êdÃQÚ%ñ0†&D6ÜŸ÷b1wíÁ“÷çÆr›î×="ö;Ð%±§Š§̨4z7 Ò¤…ä  —7wø`ö{ʪÏ>gûÿÆðìeLçq±$ÇÃRsÄï°îR+d0aKæ¼»þéPºîû Qw²Ü¨(bÂtˆ·T.Iƒ ðf„î‡ñbDå±ES|ÈæÔ=¶ IÁßgºK®%CÆ`o¿Áͼ[ŒFi¹‡]y_;”̘Z/.&NSrŒûÙÌ×$>)ý°‹I(ž•OàDÛ1ºÿ9+}Ïišx»5ìeg¬>;·€9_öÙgŸ>g#·‡4ÐP-ŠYéëŸÜÜ^‡·Cÿ+ð0B`h_­Îê¹k’&eD ÕwN Íê!/ûÃ!ò…~67Ê‹å<ãPXå!…Uxpãí `' 6£Ürë. š–+ØŒòŬª½ÒüѧsOÅ×,_ŽÿšBHÏÊÕvQD·ƒå#vzþƒÊƒP$4“,O$" Óšå_/ªÏ{¹Rï7c¨šåm‰ey›&0^^dUR5ÑWÌî[öÄŸ¶vÆIª»´3戒 ?ðMžˆôïn’câ=Ë_|´¨cn»ÙyZ±1dÝ£x¡$RDwD ÂPD…i”ù0…HµH&‡hsÎ× ¶%N›75aPW²¢È…aµ„ªu5ئÒóU·+E…¸–"Xl_ ÏP€Øã¤ ãÝxÙö.9âhXë!LX÷ØÂ1ƒÃN;\Q!5bÜÈFT¿E™V‡È&Uë² %N6!]ße³Æƒ¢`}!7Ë} Ñ‚ÚxÅ31›Œå -+¹´••zpØû:ÛºLØb®Yg%;²e›®²’-V²EGö€;j{½âG|7¯Eûø2ÆøçÌ‚ i£:Ì‚`ä™7fáîrhõƯ΅迾þ Ð¬ÃU’MŽfì$0UëÊ ŒÌºŒ+8ÞBV«Ê·¿¾¾¾à`…ïCì,aëv–; 5õØÈ› ¹ÍЂ8Õ׸lQ„1¬e£Çù4Y7 çqªÉ³©ÑœªIåB!"e‡š‡ ªæK'Ì]Äänkí¡øÕÓøýœÂ\ÇÉ¢ôìÂ|Dl3eZ|u©-Ì}:O‹Ç¼˜Æ¬VÒb]ç1ÓÏ]˱Œc?ÿ1C™›µ.ôŽ ^sUÑÛv›LëGþN¦-âu¬s­@cþã¸6b‰cYgaR]9Ö=ÚÙ–]q‡'h¯<•QѸXÌ'ÙÈ]Å0ÊD‡°-•¦9¬?¼Lͪ6ŸTU:{›bÛä>]2kèó°¨|fœ•ƒ6îåÁóÇO¸Ñ§é·¬¬²Ù'ÿeŽÎIÿÙyßÓæq6S&Ó»~ï–¯ÚvžÕ+ ŽñæXŠšþõ…+ƒØ ÕÕó<õµ‰•$[;š$eÊ&~šdüìëRG¶ÍzŽÍÛW„Ù«°4Í”j9åñui»H)UØÈq³ÿ-Rò¨š–”Ù±Az¼lÂ´à µG•½˜¯_&(KÙª%'‡\úÛ< † R`ÚvË”6žñE‘ÏçûÜRE—üLE—üö”¿ÍÆx¨Zu+¼4¡Z‘Û'i5é7Ën~:Fû³ÅôÁ ˆÛ9[¶8û™߉D4B½§2%×'ôò(¨¬IÉ:A²™ H+eOaEþ«\<”ö&yVMžÛäØK¹ƒ„‰PÀÀK“„êÔÁg3õÊmޮܦѶ`¹Ò–uáôÙ€ÐåÙvÐ¥?Ó²xÎ'à y·{yZM·ZJˆs%5µhN2Xq9˜‡Õ«¨–Så¦ß ™Ë–c‚4%µ5ž&ßûNC0G†š: Ïç•}ºËÞ¿”©Õ¾F… ¥ã´Ù¼Ž¬©DJX¹ZñœoE¡[ò/ªu}Á‡F¢†¸Û>_Y|êùÌ0zûÓ´Ä6…ws܈Ç$qBÁ¡1z…¤ÍGHu«BV´ñÆh–äﲸà‘-@fÁ:  o\ãà­*Šþ bû2½nØÑÌÅüÒŽ«8 Ó¸ 0í9È¢H»­À-ìœÕ£RÔ>“²ÿèºûݶþµí6ýèáü¨ÜrK0R’תåq+uƒ¦eûgÌí0½¿Ê ¶fÉ ¶Þ·cl pÂ@ ݿɫôß°,eéÍÊ69&¤ï=£zÆük6®m €'Ͼ¶1šÉèO‰†|Õ(ŸÎ“*{È&­ŽXV=ûhÜ«h—ûðlýÄÐÆcõ*m¬„),¦˜&“I!ñÉ4¯ ˜ýrÁVÚ:õ§¢¶JÕ‹.ýW¹p8ä’²Í\Ø;'IjF²7aá©áæ¶‚ïD±®¾vÓ@ ’T‰¥w²u4p H“’ëñ_b]}!úOùbâŒà1)s_ø ù²lV…²Êk7!b]jðlM¼é¯Ü9X½€ ÃÊ®Gµ¹%á†*›å•Ï<¤>u.¤S‡9ƒà!ƒ`Ãõu’V…™o6/’QëvVÙ(Ý®î"Ur,mwìSJbŸê Ú¡î¸ïʾìme~¹°7ì{8½îE`}ù÷ÆÛÌ`E¬ÀNÒcJOõÌ—h ÍTÇ¥6Ñ)ÍéÊ;Ì/WO{v¾¸XëÁHFTž,’ #Ê)ï@R1ðoW´–óïDrå½Ñ¾Pz2Oú"‚¨Vq-‘*€ŒGàŽûÝïl}¡ `¼xF´ž,žöH…QÒ'‡2¢U„ç~*³Ì”dDÛÉâÁSÒtàÇ”Áü?~/3–{2_DØ©¾Z%”"NI—½†8cÍ#ðÞ$ãwEZ¤_^‚`ü¤ß—„ÓÜ< þsmœ²2k”Á2ÈÙ±ÑúN–!fâRvYyÂÌ[ù¡ÿýO WLÑÊa•-xx»ÑèÙI6ͪrªÅ§ŠªÑHÒeð1Eöø¤Æôn’}¦ÕÆÏ5"øTµ…–HÙaù¡-áÁ‰¾ûm˜>Y•ðs• øù$=¯ûù^ÞýˆÛ¡Œè<”Ë_ vþúpIWø]2ì} Vb¤¨Ä¿~dˆ{´ï¯$ÃïF™{—δfíg ƒy CùžPeßDPEWð@]°Á;¾¹_Àòšªfˆh]ÿeÄ/endstream endobj 2274 0 obj << /Type /Page /Contents 2275 0 R /Resources 2273 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2272 0 R /Annots [ 2277 0 R ] >> endobj 2277 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [333.4761 313.4854 413.3061 325.545] /Subtype /Link /A << /S /GoTo /D (clients-per-query) >> >> endobj 2276 0 obj << /D [2274 0 R /XYZ 85.0394 794.5015 null] >> endobj 2273 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2281 0 obj << /Length 2423 /Filter /FlateDecode >> stream xÚÍ›[sÚH€ßý+x[Qµôôýòè±!ÃÔÄN€JíÌ<( Çš€ä€°×ÿ~O«%Ô`@(•«ŒútŸþtºÏEˆt0ü‘ŽHj:Êp$0éâ w¾ÀµwW¤hÓ+õüV?O®~0Ý1ÈH*;“¯/°Ö¤3™ýHÄQzÀÁÏû[ÓíQƒñ¤«xpmÿM†ãÉðfÜí£ipóËõ‡IäZIOÐ)ÄoîïÃwÿÜß¹Ó£þ ?êßÝô»M~½êO6ð'I0³Ú»úã/Ü™Á\½Âˆ-:/ð#b í,®¸`HpÆÊ3ó«ñÕÇM‡ÞÕ\t4ÊR‚uzŒ# ÃûÞ6VqÍ( IFÙ1%ûS‰átƒ˜ ÚíŒqðß4‰÷aœdQ&ÓâÄ8 ³x•ÅÓUÁ1]Cƒåj—Áø×QX"cBŒqV;ľOªTwz„ #=¬“ÃÐWqXJlwÕÛLª'@˜(¾A̱‡˜·Bu$X±Ä<'<~]|Nçݞ䆷ÑjºŒŸ²8MvÁq¡'Æ WCœ§¶Ä`5•$ÈEIh†°O¯/_¡5¾X(ƒ° Î¿Ãú†ñyzµÙú$äÔ×xa!Â’nákb}ÍñyzµŸ HQã|¡*ËŸ–ãõt­VµøªšB¶ “ÕC´|ƒ°ô#¶Çhv¨§i›—33ÿão,8CDCˆ[„ñü‚8 »£,=%/Ųªiý%"­¯„Ü¿G 4ħÕÍÜ8n9^7ãJBïÂ+›±¢l6ŠVéü¹¼§VÊ$ì”I¸!Ô2ÆO*-‚ÉpI›AÛ+ô#ÊdåŒzœsˆÓ5Ý_%“Á*Q7“K®ß–ÉlÕV4‹óŒò£å3a™öí}Þt,7 ùÓ·ˆŠƒ@’2¹ !&‘°–ÐGˆ¹_­'BÊ`lÝ›ûLŸ¢Â;á*zÄ6’˜~2Áòà>¶§§éb‘¢®¿påj¾»¾ýÁ,03ûôèÑÑ­ˆÔ]‹WîJè¾z ÜyëWí…–^ã$zqߪ˜=QNi?…íÌãEœ…žû.>m2ß쮤 yÉaûòïÜyÆð#×/ÑÆäâ¸}-Íà*ûšØzA¼ˆÒuÖh'ÌœÌ1nžFíõÆö±•±3<ÎM1Ä[–ïæëhA m˪ùð`<~]5zçÖT«D Èçl¿å6'Ïé×cžÅ×½½ž…@$c¯ñ,Ú ŽõbÙ±¼,bOù#†Ç˜šÌ™p@¥Å#>Í»œj¼GWXÂ-/•Æ欎+SH2,v-÷d®ò‚\=[Ì•RûžQM,D¨@Ò¾ˆc1ýžg–áüÚåÖõ\oïÆãþ£öÎã™  úQžŠ-I !cuNŸ0¤ ˜Ûyÿõ<†‡/T1tÚ]4…¤ Ò(—rì C-!7duÞ Cs)¶ÞE_š@TÜlATELjÏ'y†þ¹³qbSJ¯°îí‹xën€7µó`ýHVÑCïA”ø•BZp¹…ÿ´íõ˜ ×m¦•fçZ¯Ä=û&ÛûÖ!îÔ’=õÇê­O®ÓÞ¶@•­ W±]YXÞûš 0b½àò‰ Š„ê7œ  e’–=x³ú?ÆŠñÂendstream endobj 2280 0 obj << /Type /Page /Contents 2281 0 R /Resources 2279 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2272 0 R >> endobj 2282 0 obj << /D [2280 0 R /XYZ 56.6929 794.5015 null] >> endobj 722 0 obj << /D [2280 0 R /XYZ 56.6929 744.4469 null] >> endobj 2283 0 obj << /D [2280 0 R /XYZ 56.6929 719.3263 null] >> endobj 2284 0 obj << /D [2280 0 R /XYZ 56.6929 719.3263 null] >> endobj 2285 0 obj << /D [2280 0 R /XYZ 56.6929 707.3711 null] >> endobj 726 0 obj << /D [2280 0 R /XYZ 56.6929 494.3077 null] >> endobj 2286 0 obj << /D [2280 0 R /XYZ 56.6929 469.1871 null] >> endobj 2287 0 obj << /D [2280 0 R /XYZ 56.6929 469.1871 null] >> endobj 2288 0 obj << /D [2280 0 R /XYZ 56.6929 457.2319 null] >> endobj 2279 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F40 1265 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2291 0 obj << /Length 3226 /Filter /FlateDecode >> stream xÚÍ[Yo#7~÷¯Ð£ŒM3¼ìb‰ÇN sØ °‹$m©'nDV+jÉÎüûT‘ìË¢${¬1‚FÝl²Èªúê"i6¢ð¬"T892NE™MïNèèwøöý ‹}²¦SÖïõÝääÛ aGŽ8Íõhò©GËj-Mf¿ŒÏ~xóar~ušqEÇšœfJÓñw—ïÞ†~ÎÞ¿»¸üþç«7§FŽ'—ïß…æ«ó‹ó«ówgç§™s–ÃxÙ£Ç^OpPy=¹<»>ýmòãÉù¤e Ï$£WÿçÉ/¿ÑÑ xýñ„á¬=À %Ì9>º;‘J%…hZæ'×'[‚½¯~hJhRZ7£Œ I¨3|÷¼a óÆGF QN«GófŽ‚dG™Ö”H*E«Îzzp &¥ÙÈ(G´àÂëáãêóÕ©RãÉd±@ùÀÞìƒÕ‚Œ¨ï}±:ev\ü¹)ÓÏ f'Æëüf^„Çj¿rì;U›Å,öX•ËøTÞuxü•*zu* L|ê踆w©| T`’UYÔWÓgŒ§÷ë8ϧ·qµ}¹$Rca±i†RëØ¥^ÓòWJ9.KÀª×·>¸ñ´Z^ëeµ˜•‹ßÃ÷O0ÆÆ<¦Æ—‹0 à‚3áˆ¥Ö ×]‡‘8‡4Èé6JÊÀ”ú<ôA+”$F:P£PÄpæž[Nœµ6 Ú¬¥˜õInãG(CŒ0®›WÈB–0kÔðM‚IM˜•r7–m”>" ÅCw±+9'\Ù#²ÛR<À®äŠpiäÝ»»–X¥ÍÝ`,Rïóùf¦µ·døN(F ·BO-ÅPLn€ÓÊ„41†6~£¬ƒ‘stá8Xyt"|¼ØÜÝ+|fÞ­a[tkáåᶪ‹ð½ï ÃÇ<øšðrS¬Šb‘rzàÒ¤5{„+ çÐÅ1ZÛ#7RÌú$SÂ5„3TkÓ Wˆž¿Ìù1Äß#/É|0Høn Á7:ðtÓù¦.ï‹>çv4DKÊv{£‰3p ±Œé—{œ†bÖ'™ð8žúó¦Û.*¢ã=î‹¿¶¸¿+çó².¦³ rf‚ÊñEµ ßÚÐä þSi…¦ü„äP©ð Dî‹Eã4<ÄßY!sQ¤\…j£wû: © …95¬\Š|¹¯k(f}’ _'Œ“¬›WH“¾Nu,¬«ÀôMdž‚XJãÉml˜çõ:È•i…Ùk2Ýb±^A®$¬×·Õf>ÃgèA[0òeL6 s;äuR¾`z]ÜIÉW@þy‡¶†8ÊÄä)f}’)ùBæΰ›ÙÇ’¥ YÛæ”L$3à KÈé¼HîŠ|,3g…N9Xˆo­ƒåÊ„¼ÚZ‹ÑÁbûÐÁâÇÖÁâgÈÌòyhG•c“7ü½‡9¶uñ('ÝÖ‡‚&=Ò£/k-ŬO2áT(ƒho»íŠëÀÀ èbè>!“ÙéÊŒ.\hf]Ét°ƒ1æEôEƒZE1°AC­îWn[œ šX޽µ€,#VpÛJhÊKå aÆo€¥*#ò4c”BZMÿ(Ö¡^½üö},\×ùº¬×å´ŽE0”RëbU'´„šœZpf 9æ"9|¨{äð}Úóo­ àKãØgáu‰¦åIôè®?/‹l–SÞØlŸN"?Ì‚;mbïÏo?È' x({X/ºAÇo/?ÜK n©¬ZYáTGV?‡¬ÞEœ”ˆÂØ¡uOÎÒËö%‘éчŽû— 9‘j¢8tÖÏ¡ªŸDõçEùWŠ* EÛ¾(°_Æ!Ö¼­îòrˆû"! ‘ñ¼hÕ,¤ØŸáâˆG®e*SÔŠ.bK:H‰@=B((š8î¨àÐ?ßÝTsL8¿í òqÖ± ,>êOò²…£ˆÜCí@ÜÞíÑ-’͈²Àõ L%Y m²•¥ÄZ%ö›¦ùÓÜiàï—EjßPOsÜÅN×?c=Ö³™N‹ºþ´™ÏÛíAIT ezD‹ CËHbá òår‹c:´ÔiÜgEÓª:K„å gOñÒ †£àevÁª¯¯—aà1¬äQa¥!µ‚€•ô¥¹zmT]€?>ˆ,ì´‰aëw7ލ‡Y؇†ÆP]ÖFta§]Ø©Œ<ºðk ]ü€®žÚŽ…®ÆtŽèÀ¥tDË¡KaI#ÍkÂëlŽeîÓ½¨wŠCf{”ÒãöX‘ä+DU OŠswH)’FÝ«Úüwåbö6Ê {t|SƳ§.3«÷¨¬'‹²Ê@ŽJCys@eP»1%_5øŸU‹Å U6Åtý ­õÄq\­×ûAý ?”²IfÁWÖÚAE½´LQcMXÖ·Må’ÈÝvê¬'ŒcéL(bµRÏ ÙŒØ©3aPNæ`Ä¢x (_Seo¦XM~©)!½©)!ƹ'â- ›ËÅ´ºkߦ­¾Ã{{p_¯Ów bŠÎ¤O¢NÙ8déðÞ´‡,‰G5)|ð)´§S&¦ ÝtZv;UéÍ®E#žôö ³áãPî•q¨›8ºÎAá«ùݘîƒåeüº˜†Hn-;ä‡ ÷$ÂXõú >è˧Z˜Nkl°­zOäÔ1_˘4<€5•Ç7ù¿4!ÿÇ_[|èãß·þwnn†»ý¸lÓö>M·œàÁ~-Üöq,Ü~…ÚT@`t†ªM…D±WMz®‹Åì|µ:ˆÛóp#ªÂÝFa„ßéF¶;†ØVxë Ÿ \]åÖx`jiS¤Â§®H5²»h•¬Kýí«º-L·9‘À+wÍÎ÷ušΉdª‘Z·Ò¶QC„fm·“G š¶ª°{ÚÓü±ÊÛ¯àX¹åP"©Ci¹ È7ׯ‰Ð«bzÿ\„rŠçTíž6mÎÛ§Ey_„ âÅØøñÓùfVÄ·¢£žØŸ ù¿‰€ðáx@½ˆÇÎá':þ"öF÷´ð=w¸ž8KÇÍç¸7Ö/Ï~úsÛf©áõâIþûž˜¾îåCŸ~ û5öð™ÿ\ ®‰Ö¡z‘.ÇÝÉÙþ#]©Sªw¢«â‰îYu·¥ß”órÕóP®c´ÓýkÑŒCµ®Ø¶“Š…hÐ^y²„3L6Ã:ؘa6 姪FÍùà4XpÖ;@¯ëÛ<ö{(ÚÛgЫ;KòËä=4Š^S«ý^S€*9ïøArù`ªy]Å¥n–ËjîÃìš”â¤ü“º8i@}[=,Ú¢šsH#Á9ŠGçùMußì•¢LüE+FÇ?ý#±­ó±æÜì¦ÚÄãµ &Z5»Ý9jð‡gUK _.‹|µuÔV?ZÐã›î”PeÁ*ŽI›¾Î;eý^»m íå=ôÅÃìê›küëXOÁ ¸Ø;yÛ+1ûàUÃWnìpúIÞEíÞ:hI÷Á¡µ,x½)¦ù¦N¦ÀÎowëƒðRº/ 9«Š¸„8«ç³jÐÞœEqŸ›Täѹ ¹Èƪ>U«xuRâ%LEÝ0 =ä+¿a˜X¤ÆƒÁ&.§/—Ažî4{VÚaZÎvcü‚vaWræz½ö`®éå1÷æÛhcà÷5•û§m{%æ  Êr¨/Ìp☠(:L%›ÆÜ×oe{ ²u"Þ€øö±»¯F!{ð¥àNaBÎñ.Í^Yö:íeÓÉKòòã–)¸>,ìöÍØvÚžrxõ¤mñzsWˆWqgç€#ï»à_é$X¢£ƒÞOýc îÏ£°œ°–§…#@†B8Ö,Ê_€æàE˜âPè÷þ$ 24"²p ix/’ËM‚­¿â*u:endstream endobj 2290 0 obj << /Type /Page /Contents 2291 0 R /Resources 2289 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2272 0 R >> endobj 2292 0 obj << /D [2290 0 R /XYZ 85.0394 794.5015 null] >> endobj 730 0 obj << /D [2290 0 R /XYZ 85.0394 615.1118 null] >> endobj 2293 0 obj << /D [2290 0 R /XYZ 85.0394 589.9912 null] >> endobj 2294 0 obj << /D [2290 0 R /XYZ 85.0394 533.5628 null] >> endobj 2295 0 obj << /D [2290 0 R /XYZ 85.0394 521.6076 null] >> endobj 734 0 obj << /D [2290 0 R /XYZ 85.0394 236.6167 null] >> endobj 2299 0 obj << /D [2290 0 R /XYZ 85.0394 208.2484 null] >> endobj 2289 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F11 1559 0 R /F40 1265 0 R /F68 2298 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2302 0 obj << /Length 445 /Filter /FlateDecode >> stream xÚ¥SMs›0½ëWè¶Z}!§ä`»X=¥98˜6žI 5xú÷+"p¨COÄ®Þ~¼§Ræ¤Jƒ¶ÜÒÔJP -_ £?ýÞÁ“Œ dŠºuäÓRjÁj®©û1Ée€ƒÔí" bŸE·ùê³®X´uq*£›þãò­ËÛ8±Öðhñåfã²" ô$0x†ðÅzµÌï¾C‚õ*¸‹l™Ùj‘ÅîždîB`J™è»ÿEÝ{®÷„°FÑßÞ`€ÖrúJ¤ ¤£ç…lÉ×KÂÉî[èœhRP\jš Æ×Ÿ—!Eô TYЂ‹‹´ç¤Q½´ÅºéÚk®FCnè4߇ª#h¦*ŸTµ ¬•øwU÷|hƒÞe}>vÕ)£óXwá§=7M}êª}0Ÿªrwn«¾Ý+n¨-(ƒ©o­ÏÿvÚ5í…û˜Aà ìëêºl¹;Åh¢*X»§úò.4Ÿaõ£èÚendstream endobj 2301 0 obj << /Type /Page /Contents 2302 0 R /Resources 2300 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2272 0 R >> endobj 2303 0 obj << /D [2301 0 R /XYZ 56.6929 794.5015 null] >> endobj 2300 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2306 0 obj << /Length 1299 /Filter /FlateDecode >> stream xÚ•WKsÛ6¾ëWp|’g"‚ú”8M›L¦“6î)ɦ ‰Š`H(ŽÓÉ/ P”͸õh4\,ß¾K¨û±¤„Š2Mò2%’2™TûM¶îÝo dR)ˆL…p‹™·+) " ž'«)È‹ëÅÅ+ÎNI–q™\oF]YžÎRž\¯?,¯vª³º?_qI—ùù§ë7¸-%y‘3ØF §9\Øðâõ/QºÄÇ{]úÚÞáêÊ´C½Ö½²µ£F<–‘f<àeI –y¼œ°ó£”.ŸW•†Æö¦ÁÅÛz°Š'%)3ž$Á‰sÇÅíBd¸ýœK€B8R.?RIŸ_½Ü“áKåEuX¬×¸ŒX{e«’ÍÅî”Eæ9 Q©‰A‡W‡…U»FF[WŸ[µª6¦ÄÁ¦6 Œ‘RJÌUÝŽñ<Á PÁ¸“Õ4ævÕ[oîf"&]àÓ<ÂÏfàRRÈììËA÷³XÒ¥”?jeÚ´œ^Èò?àFÄë¡ô†z5öûF¼y‹Œ.Óÿ yÓ¨êóÎ4z)u‚œ=-¾"V)tfîzñ¤2l¯ÚaãÚø¡*!Iʲ£*ßQÚVñâë )R/õ÷P·['™¹¦t‚”·"оæ°Ÿ;õU#õ‘RÞú’±eåâÈ–ÇVžùŠoéòvvûÎñ:â@A;¨A÷°;O½#™XÞÖvg6À4ëfØ>Ó=ÐŒà{Àu”³¬Ýâ ÈF‡ù¸Hí[Tè~ ÍŸ¯ßás24ô@¢v )ŽÍ×0¤XÖ>¦*¥“Tñ’ð1S[cÖaËZ«¹b¤(sÄ! £Ã8$‘—aüÈtªNÆ#Xg§£Q( qÎ1êä|•±ÒMÓ}m}‰€àÃÍâáfOßÜaѹÞdYÊb~˜÷À¥N h§z[Çd`y@.t’Øa¸¿êÖ"cèŒñ¥²é}b­ÛZ5§i›êJǼKúÒ¼ÇãÀoµÖunЭ¶ªn{¿t¦!™Éöï:Žs®#VpCSû®Ñ§6íÌ-¾¥FM§û&œ­ªë" Ùý%”ÐÌ‘H </.\Â(œÑ hx‚)ðt8H@­‘<»1ÛÃÐj;œ!Ï: në¦Aê¦1Õç¹6‹*ÿzuÅJVàbè„55ƒÙV¯}8×ÙgAß®†³ÈzxL[eö{ÓBt¼—C«ÛjÌÆW¬·3LN± U=ŒQÀå?^8ÍÝà¦ù©”øßEqé¾d¸“e%w ÷¿àé%nçnn£”¸œs„MA`˹kÏb<òJàÈÌ.ÉpjzñcTÂ)MŸX•›ö1†®èW«»f̦ÝÕC, »‹<=ب¼×*D¦§¯½ÃþF÷÷ÓÁOÓ­ˆÙðoÄÿŽa,0~ÌFÛtøy:Él|}b3!³Fý„=ý^šZMÿ‰Ilö‹æ uü ™"ŽÅý¨Mru/8|¶Æ„ç~7mPuæqÍyöH¨Ã'Ì]öíÕàNñY7uôãl1…$¤ó¡Ú»S·óoñëõx׊7(øhr÷±™Ûs/¿,>|¢ÉÚ ½YP"ÊB&·nA +KžìÇ‹ršÅûÅŸÇ‹]Ô.Š‚¯u'ßwÔ]­DÉ¢Q~˜¸SIžóéu¸#VïÒû^ȇný ¬¶³±endstream endobj 2305 0 obj << /Type /Page /Contents 2306 0 R /Resources 2304 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2272 0 R >> endobj 2307 0 obj << /D [2305 0 R /XYZ 85.0394 794.5015 null] >> endobj 738 0 obj << /D [2305 0 R /XYZ 85.0394 769.5949 null] >> endobj 2308 0 obj << /D [2305 0 R /XYZ 85.0394 571.259 null] >> endobj 742 0 obj << /D [2305 0 R /XYZ 85.0394 571.259 null] >> endobj 2309 0 obj << /D [2305 0 R /XYZ 85.0394 538.9404 null] >> endobj 2304 0 obj << /Font << /F21 1034 0 R /F22 1037 0 R /F40 1265 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2312 0 obj << /Length 3293 /Filter /FlateDecode >> stream xÚ¥ZKsÛF¾ëWð¶`•axíM‰åD{°½6U»©$€H¬A€@1̯ßîéž! A‘«R.ƒF£g¦§_7(ü‹0ò£T¦‹8Õ~ˆp‘﯂Åžýt%˜ge™Vc®ÖW7ïU²Hý4’Ñbý8’•øA’ˆÅºøÕ‹}é/_ÿëæ}Œxeà‡RxäùñçÏ?®‰k"Q'¾‰d¶Ûïæ$E¾TB3Ï—»õÃý»QBÀ¢´ŠÜ”·ŸÖwŸ—+°Æ%ì1ð~¸‡ %¥Ë—»>߯¡»?~ørÿîîóí2ÖÞúîpž«»µÓÔX›"P¨¦oW¿þ, Pê¿®_¥I¸8ÁMà‹4•‹ý••j¥,¥¾úrõo'pôÔ¼:{:" Dræx¤œ;ž0õ#ÊG=¬wU¿\)¡¼¬®Û»¥H¼2?v}õTé۱쪒Ÿ·xÕÞ°ã§}Ù=•ÍÛížîK{úªà›cS—ýËÉÚ†H»ŒŸmʲ¡©ÄöTµÇ¥ðúúLä¢êWx  Š•~†Òì+ÛÔeÁ†'ÅBh_iP¨µð;û\®DÀñ訳¦` (‡cU°œ±6AŒL}4ßGX¦LBïáÃýq±Júk¸KµW DEm#ß¡íû ÖHÔ¡%j·L@5DccjŲ3Z†žX¿ˆ}\Yu¾#Ý·C9·fùa[æ²yªˆ½Ù—Í@sü„Á±¯š-/ NÏêpäKAä'Ú¹on‡oŸ˜›7ñe¤ÌþxlòŽÚ0›I7gs„+•¦¾¤že(óêñlÖ¤tÌ¥ï7)5«d<[,|!Á³­†™YñÄbäÑía ém7³up¢$Š~³ÉöóŠü4u±¢KHëj :ÏšoWÖU{2ðö‰7ןû¡ÜÓý£Ît·9Ç¡Îr§²#‰×Ÿ‘NE kQQlu*Ü–{0òMû¯ÉØO»*ßñ°ªkÕÕ¾b¯0šÇA‘í³­· ªGvºØ˜`õtÍ[»Ï}Õ³ƒ×…@(ZÛmÓÂDø¢¼c_>q%Zxe6) ÐCãð€Öö> áÌ&Ìiâ=F,ä`¯ŠY’¶›B¶©j£dCméê]ÚjC¾ÇØÛXH×ÉΈâörÚ•–«w惇ŒC?MD2 s>$|K›×Ggïs°9J%ÑÔx~.­(‘z”ÛR³¼–dûCÍÁ÷&ÎãM]5LÆ“7”6ãgì[ ¶b9Ùܾ¤ÕT«ïØW¦ö|Ù ¯gjå2°ònž²îæµx‡+“ز‚7+ynovGl˳A-Lõ<¨A¢”àG? ȯåD{q c–c\hb%2ÿd‹OG¯­ì{|’´ßcßÝÔmžÕ7ý¦jxëHô sqLèúBGÂEzÊØ£D;\*8ó¯m\ËGàÓ#§Æùô^`Ô=†–@Œõ¸a-#“C }Î`¢ØO¤oÚ ˜r¹öEÒFé¨iœîÔv_‰ÂAöPv”ðYÕØ•CÖ U~¬3^iQ1 ÚîL,ŸÜØs®g–#I1g`­GùQêiêy͆M%IœŽÚq,½3 >“Ñ('á¨)ÑpdlÓe9ÐàÈ 5ã4øBaæ­]Æ£ªÉëcQrb.!mœ‡gÕd”UqÆ~:%¹“IîÚ{oA¯Ù¹ÝËÄmPØ?0¦¦)À¿Ê¬ŒÏd& =Uå CóœŠÅI*¾'DÒÃØ†ÍŠç#̞ŇD¶sSfƒÁoA ™ì;Óaâý‚‹Â#Àç| ˆŽÀ¼ÜÒ5+þwì‡gó=eõ±ìÝlI"Œ*Q8Ua¯Þ‚ޝåhôÒybئŒ¬FÀzÙr_*¨ÆÉˆƒâ  $QÚ¡*V¤ˆ9w¯O¢g!.ËóöØpà0>Cù¯ê}‹Â B‹háÞ% †S5ìG”YWW„~ ŠéY)š-¨hH×44¾aðÊùPA¬¬ÏVœÓLµ aõ©°ËofŽžØ%>g„? ‰ÃUõ+‡ÊðMp¬ –uÕ@?dÃxåMÛYph¸!^'aô,í2ŠZ¸Â“ø¦Ë¨J• ˆñ x‚f{"ŠuDEiâýÜžÐù±²GÕ&1ñCÙf€ßà=g™]aíT* د©n¢sê>;7ë11ÐršfÒåÁYO³íŸ;Á´Ò "lº½)ʧ›?Ë®ÃÊS×G™‹01™‹êÀU(ž=0!D¥ß¦ÆÂêv;皘ƒø[lé=ƒŠ5=–Y9ƒ¡ÚÏyi¢ÐK¥+ÀfàØ”òE% TêpídÂè{\*µŽG剉 ÑÍ7/?†RBÊK<;B8“›á ¢ÀÆÐãà %aP‚ÝR¾Ëšmié&€:„GÓí1õ’é¬qß2åÙàª4<ÍÞ6@ƒ ÂXé牢ûËò"CÕTµ§¹ÓQÒOe¤^쇫2ÖOºÓ¿`Yk°Ÿ»¢-ëÁUÁ-·o,‹m_ÔÝ8–Ù|réJ:þ®¨ šk>*¨üRùÝGšH¢ÍvÁˆ!Ä„i½.‹Þ @íSQ—²Ôl¡Â7)Gn Ø@Å`ðJ€ “K~`iA-(?T®:ü Lxkø_zwÏõƒXÆPÃë¡ÙÊâÛBøNSE<£±ÙèE†ps¿—‹w-lg1Ú‘•» 6Š&œP‰aö’£"ÚQ;|¤-…vOˆÂfM‚nBZ}&“8ØëÇ–ÞÓ,U„.î Å´ZE€î±Ì7L—ZßÑòÁö®©‹Pñª- ÔL˜Á¦dÌ@ÖQJ=oÌ.%$4ô§˜°4^¡Â+¦(ÇïD7]Ù¼¨|(™ó`jðŠžîMû %ìX¸ñUt)C@BˆØˆÄŸ[PcsÑpš2`:6Ô¿gûèe@ã¿´ñÿžgŽÝ)oå:wšt»-Ÿ ÀUqŽSœáÞÁ”ªœÂÊáȆÒö½¹åøfçû–ƒ»iö·“¦¿ô +ß4ýY¾ùHåtÍçƒ]{¬ Ûò§WáÄá°kæ0]H<­xª)·‘êÀ2¾pË—OÊ‚å駈¦>Ïa°“k©â’F{EË÷;*¤ÀÞMW H›¬§HQlOµ­¢”wÿ‰YQ>íù%ª·”åÔÞ®¥ŠÉ~ùÅCÊ1iîšý‹YWŽUS“î•©';£Š^6PÓ@†P”..Šý%åï?ˆnÚ¬aòêÇ€Ø×qj±–ùŒ´â£ž-O“Äű?¹wœpõ‡`\…Ü)Gò¾vmÁË`hœ¶ €iyyY£áî[b±¦g3>^ä*‚ªeb ,'qF‹ã‡w¨Ý»'ùW‰[V™õ•)bBúvsmÁBônë¾e·ƒ[jfE²)qYÒ>ƒZ¬›3üœºÙfdN‹=m.?œ žmA7Lí]%Z7ÕÈ44C3ë²@0»¾¦±ÃwÊ}WÑã=Ò#úÊ2#ŠwÃï›FAˆ_û¹†€—ÀëĶ©à¹#@=ŸgêœË¤Ü™F© Âì×"pÓ#ßP Cgžù¸ó¾59Ù˜Oo0PÌ¡/ë!vcˆÃ´_f}ÓºÛš<àx±u_šö¶‘DÊYÝlXzÞC»í²ÃÎöðqv„4ØzJ´á9öeÖÌëM æµqŸåì~gÚ6îûDOLXH¬¿ÜÿÄŸ^mM+c²‘~-¦¦‘¯µ+ËÞŽ©©pny'ÇtAT“þhA°>¢}-Ï4hÀÁq…·G§¤e†¶S„E-¤þH>ëéÎØ–­qlm4Ê4ý˜orLÙó‡©Û ÔX=•°>!„í8›ÄæÍLÅ8-ˆ”í’šV‡¶®òó|û"ŒÝ·Y§-ã<Ø\ª½âõ2+ôñ‡3¿È\=ó·ÿqÁy@[’È¿þi¯Év›ù·,>KjõI#€–±ô„’/6eCòrWÿ÷€7›endstream endobj 2311 0 obj << /Type /Page /Contents 2312 0 R /Resources 2310 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2320 0 R >> endobj 2313 0 obj << /D [2311 0 R /XYZ 56.6929 794.5015 null] >> endobj 746 0 obj << /D [2311 0 R /XYZ 56.6929 730.0613 null] >> endobj 2317 0 obj << /D [2311 0 R /XYZ 56.6929 694.6148 null] >> endobj 750 0 obj << /D [2311 0 R /XYZ 56.6929 556.3845 null] >> endobj 2318 0 obj << /D [2311 0 R /XYZ 56.6929 529.3116 null] >> endobj 754 0 obj << /D [2311 0 R /XYZ 56.6929 413.847 null] >> endobj 2319 0 obj << /D [2311 0 R /XYZ 56.6929 385.8516 null] >> endobj 758 0 obj << /D [2311 0 R /XYZ 56.6929 226.4875 null] >> endobj 1889 0 obj << /D [2311 0 R /XYZ 56.6929 193.9525 null] >> endobj 2310 0 obj << /Font << /F38 1122 0 R /F70 2316 0 R /F22 1037 0 R /F21 1034 0 R /F40 1265 0 R /F42 1338 0 R /F54 1433 0 R /F49 1358 0 R /F61 1466 0 R /F62 1469 0 R >> /XObject << /Im2 1455 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2323 0 obj << /Length 547 /Filter /FlateDecode >> stream xÚ¥TM›0½ó+|©vý‰}Ì&iËJMÓ„=¬V{ àMP ¤l´ûëk2N‚¶ôT!ļñ›¿ñ†¨}R’P¡C4Ò!‘”I”í<Š6ví«Ç_H¸ÏºK¼Ï_„BšèˆG(yéåR„*ÅP’?ù“oãE2[˜KêH€eDý»x>†Ïj6yXÆÉ# Éù*žÎ–ã`úIlQ€CE•.Ãôq>þO€ÿ°˜uö!ÛsrïÍ’«¾XFE§â·÷ôLQn5ß{”­$:Y@ Óš£JAd(ÄÅSz+ïç5aoõ:Ô<)‘ŠºÇùP÷¤&‘àâܽU½3¦ÈoŠÖ4`fÛºnœ»­»¯ô³OZ–`äoUº+2‹ßðqŸ§­ÉaaÚõóÌHÛ¬¢‚46Çu^ïRðÚ”•‹ÌMi66‘«½MÛwí¶š1cDKÉÏ\¡`§BŸKXؘ}z€T½×•±'+hä'Û¢æ)} cþ' CjËð·õ—æÕ”·X°²ºjm½¢Ú8|(Ú®æÔvµÙ¬Ô•r¹•/ÜBž¦|Ó4Æqê—!ûãº,2˜»“YƒáF;ù%X9¼šC 2ƪºu!eYŸÀtNÎqn\ò¯Ù’t90‰öuûþﹿýB{%•âÃ#-hH„Ð첩®_Lˆ3ÉG¼ÿ°×‘¼?ªº^ž¿eýN0"uendstream endobj 2322 0 obj << /Type /Page /Contents 2323 0 R /Resources 2321 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2320 0 R >> endobj 2324 0 obj << /D [2322 0 R /XYZ 85.0394 794.5015 null] >> endobj 2321 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2327 0 obj << /Length 69 /Filter /FlateDecode >> stream xÚ3T0BCS3=3K#KsK=SCS…ä\.…t œ;—!T‰©±ž©‰±1ƒEV.­knj©g`fA‚!ÂVŒendstream endobj 2326 0 obj << /Type /Page /Contents 2327 0 R /Resources 2325 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2320 0 R >> endobj 2328 0 obj << /D [2326 0 R /XYZ 56.6929 794.5015 null] >> endobj 2325 0 obj << /ProcSet [ /PDF ] >> endobj 2331 0 obj << /Length 2024 /Filter /FlateDecode >> stream xÚ¥Û’ë¶íÝ_á·hgb-)‰º$¦Íž&Ùt’ždw¦Óæä–d[=’èèbwóõP–m¥éLw âN!ʵ€¹N•/Â,Z'Yä+!Õ:oVb½Ú×+É<‘ }…!,¨¦¾Jƒd½™+ùòuõøU ×ðã8Pë×Ýd+NR? £lýZüä=ôq(»‡M „—>üüú-‰E~’&ŘP~’‰Ô ¼>H)½ÎŒÛºìÆ U»ŸÄdä‡Q°XúI,ÈNêˇBxO¦iLKßwÔ4ýEô3¥œ‚œOdêL*ž‡O”òzRÒš€³é>‚7ŸÓê`Îäš­=ÓÏ!‚ýØ•´2£“>è+µçδû/س`ùYÄì„'‹dD9€¦0’Þ¶ì‚zSC…›ÄÕ`&ì ƒeU ÌÒÓu­/œº-ÈMË^ΨUßeïàk݃þÈ^»™zå©l=1¶)u?…%·o¸5ÜÌsØL_ö@7A’xãc¯6ûý„D¿jT‚”m¹3¤õ¾û 9–»“IØAsª fÓ„ï 9˜3Úì¨ÚÍÙø ®jÁnñAʇG$:m¶åõ¥ÝàØ—/†n–v )Á„Ó¥…u߆–äÒ<Ýæzÿͨkæ½cÎû¿Q4‘ðƒ8t9¸Œoó®lÀ‰êÎ0Tp»ŸÐ“©—²«tMð÷c³…_Nåj, ­½š¥ãò€¥n­4Aœyz Pþ5bÆßð¤Þ‡ Hˆ¼y#˵Ÿ°@¡VB(ƒÒ&P¬¼?¡6Ìk3´Ks¬'™&† ›"îvÚôm’s²¨ˆmsÉô%%´MdtòScÈ›jõðÖ!øå`+³‘Pÿ€¿ï¾{÷îÇ}Bü-Ïuyꤕ ÐÎU]ÔØú™nª~¸àଗ‹&CŽA(#ê€Ñô'Q¤‘Xµ;»qàÄGFÖp([÷Æ€!Rn:âÎoì†ØM,ËÔ?–Ýš,£½|duí@\è) rJ`©ú¥Î5±=¨l^P6ù”½¥ù’Æb–¢jžÆ°àž»ÚÍ RE•s†Š)_2:œÌû•ëª^³Âm‰aCÔx,\.‡©÷¼#:¥ Ù¥…ãä„.åÙ¾+'{}­O%á@ÃÉñU=ýÖæìPàmK2,¬faP VfŒîqH"ïÓ©€YŲ}Î`С‡¡lŽÃb½qG¤È\ |ÍææøÆmwwÓÂ0Ìþ¤0¡¦Tø2ÝR©s€i—él—È`èWÓ €.ŽÅ\Ç©>Mê(¾ÖKpn8áÒmûIh¸-Õ2«À†»Âl²9–k1.ŒýõmóÅ“nlÏ—@&¤[¢Ë6ÍC¿ñDÑEA„@FI”†q”áƒP"øHÊ„…¼ÕX‚O€.Ým`tqÃÉ5'Ý c×4Ø_îod°ñC4µ_ ÷¢-"W®¸ N‡H² ˆ¶<†Í‹è’fH¾rŸ\KlîNXóŧœ›™ã9 73é¬[FUÃ5ó¶d[‡É”Ùâm7;~žöºjÿ·$ääï‡ÒMÌO7óô×%gé7e}üâ÷§ ʶ ¡ ¬µÒAê½¼A½Ù.¤'Óö¦ª±¡5æÓóËg ¹aÓ;jè]ú€>ÓT PSQI4[fÉñJiAÑ ì¨sªr–Ò{ ¦µØq-ç—Ïß¿[Š0í"öÞ}óô!×#{¸"E¿ÂÑÖrÔ0˜×=ÁèòòøÑØÍ"aòÓMe']Õz[׃Ã8Û¥Î3¤ºjóz,Ê~A/îjár¥Ú‰¢@è®Ø}§›3/‚¨öm…ómNY ìEÕçf¤˜ÁÒ¶‹p1æŽBq`è ¡‹³NÆÛÑÉTp® Û™­T.‰yÕ¹/\ìèZÙH!ÀŸ'ê¶…£Ë]Î#Š6Åqh Êùn'4ßᬠî™ÿÚ+wÄŽ¶”p¶¨®¿hlÉ ón.+÷‘A~Ñ`ŒY7ö=èÇIËÞ¯Š¹xÕä¹çüÀt> ¿&ÿš|ú–åç )g- TùJÅ 8ƒ>üYVy^aÂ(ƒ¥k~¢Rz©!êǵƒþzyµ™63 ûhÍ[ç^´Þ@Ìg3·÷·þ@;÷3™f×þܼMLw>\íýNúðÇ…>/áæÈdÆ1r?U}5L_>t*X4x´›0M}™Èè:·Ïå–çªLŽaáT”òU"ëLd×—Ê„ŸŠà÷e’ØÌEîOå^³)†áøÙããù|öùT]Y>rö=ÞåMB^A¯}¼9¨‰ëÞ¯«xÜkûoG…oâj@§j×\† ?íø·N»‡ÄPùø,¹à±˜ò€øË꧟ź¦oW³T­Ï°¾Ì²`ݬ.©W/«.›wÖà&õ!]‚ËëæU¡bB8v ·%CÓ‹ ’`Öe2önÞG·»šÞQï·õÃü¡€endstream endobj 2330 0 obj << /Type /Page /Contents 2331 0 R /Resources 2329 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2320 0 R /Annots [ 2338 0 R 2339 0 R ] >> endobj 2338 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [348.3486 128.9523 463.9152 141.0119] /Subtype/Link/A<> >> endobj 2339 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [147.3629 116.9971 364.5484 129.0567] /Subtype/Link/A<> >> endobj 2332 0 obj << /D [2330 0 R /XYZ 85.0394 794.5015 null] >> endobj 762 0 obj << /D [2330 0 R /XYZ 85.0394 769.5949 null] >> endobj 2333 0 obj << /D [2330 0 R /XYZ 85.0394 576.7004 null] >> endobj 766 0 obj << /D [2330 0 R /XYZ 85.0394 576.7004 null] >> endobj 2334 0 obj << /D [2330 0 R /XYZ 85.0394 548.3785 null] >> endobj 770 0 obj << /D [2330 0 R /XYZ 85.0394 548.3785 null] >> endobj 2335 0 obj << /D [2330 0 R /XYZ 85.0394 518.5228 null] >> endobj 774 0 obj << /D [2330 0 R /XYZ 85.0394 460.6968 null] >> endobj 2336 0 obj << /D [2330 0 R /XYZ 85.0394 425.0333 null] >> endobj 778 0 obj << /D [2330 0 R /XYZ 85.0394 260.2468 null] >> endobj 2337 0 obj << /D [2330 0 R /XYZ 85.0394 224.698 null] >> endobj 2329 0 obj << /Font << /F21 1034 0 R /F22 1037 0 R /F11 1559 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2342 0 obj << /Length 69 /Filter /FlateDecode >> stream xÚ3T0BCS3=3K#KsK=SCS…ä\.…t œ;—!T‰©±ž©‰±1ƒEV.­knj©g`fA‚!ÂVŒendstream endobj 2341 0 obj << /Type /Page /Contents 2342 0 R /Resources 2340 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2320 0 R >> endobj 2343 0 obj << /D [2341 0 R /XYZ 56.6929 794.5015 null] >> endobj 2340 0 obj << /ProcSet [ /PDF ] >> endobj 2346 0 obj << /Length 1928 /Filter /FlateDecode >> stream xÚ­XKÛ6¾ûWèE*.)ŠzE$»-¶M6ií¶‡4­$ÛBdÉÕ#Núë;ÔmËv€>˜œrÈ™o›Sø±y$å±?cŸÊÄ<ÝÍè|¼ŸfLÉø‚ás“ ®+xDDä…s×Þäåjv÷£Çæ%Aà‰ùjmtaDŸ±ù*{ï¼Øïó*+>/\OPçÅâÃêg\ç“0 ™\GAG@hä‹aÅoy™'mŽ žê.oÍ"æîžZø„ ?D5„-\F)Z> ×uƒƒ—O÷8úcÁsò¦-ê )1a”p÷?ªd$B«ä ¸¯U¥U×ÔYŸvr'\êÍc^ Vz‚ðЋ‡•«m¡•Õi¿Ë«gm¿Û%Mñ>rºMªž´E•æ§7Àó~'UJ%,"ž QˆG¾u)˜ 'ɲfÁ"'o[¹·”è¶9Ú<훢û‚’EÛöZ$ËÛ´)žó §E…"¯þxp=Ê—y‘øváú°±M P<©²QÞœV›N;È{4ŠÈ•»pÏÜ…Ë)?» Hà]``Ý$Í]€cߦÃ]@D[¸QH}dá¹a`óY¸B„Îc§Q¶õÔþ¢Ôû¬Ý—(/æMQ÷ІGßèê?é»m WHºâSnÖÊ=.sDÜ0í¶‰ÂÑ!iõFݰ¹„¦¼­½ù)ˆ®^cxONƒ3Ãx–á…"àØ†—¬ ÉÆ¸œÅYQAßBæX._Ã}{"AÐM™|ð—¼Ó(éìÊÕì ggÖKëݾÌ;e{³¹‘8Ý6k’ƒ2é|«|ÓÕŠÔ?—EšH/‘K9r_ ÙWçOå”ûúP•u’}M>²˜:eé®Ãñ'Ìk-Îê5þã­å(Æ¿¶^w‡}‰”4©p”‡ä‹Zÿ¬˜ëº—VØž ýx2/S&k‰<Ù÷Rdö°2Õ„”Ä © @ˆ%ÙçzôËX~Ì ×^2”ß¶ÉùÎòÛ®Ûwww8HѦ¤n6w™²k{wz8Á¡¾ð˜Ÿî¬*©ó™â|7y &Ü’Ð"e2«ë‹P? ñ žÖ®òÂÐùR÷rËI2é 8…1i!‘—(^QAÜ%*eÀ²ä¹î;äåIºÅ*Š(„qÀH?S¥6­3ÍJ´®=.seÈe®¨„G±Š)Èoг”Ä"’þ\ é\¥"­Þç ¼Ú¨Ô÷¥íò]ûµ!ÅUH-Mf’›üX|ÆÞÂÆ€nbld,„¾~"G' >çJÚݾêTƒ¡˜*` Ím¥ 0ÐUß œ¡ˆ¡¬7ŘJàÿí»rqÏ´þ3}„JžT.šð¨¬:Aè¼zýøð´’Ý€»üýåÓÃJ’#U¨PD—! Ë«HÒ®h‡¼“gòá랦íK¼”À kµ]­`zR­F˜áSX~Z­¼¯¨Væ9S8îe˜2N é÷nàÔ’ºT-u©×´ZP=U;U[írŸ§…ìXSõyèÝk•´“N=˜MÕ¢c®ÁÇþ?>-—«`Œ á¿T|ú_tÌåü "¨w£XB—Ý¢…nzåšÊÑ)§:'}bë|Â\mÛl_w9„~Rêúû©/+hÇŸËüø±ÛmA½Ü¥‹ÒtÞÖw€I/Èïä’­ÃÀÛåFcn ]¶µºiëk*G[Ÿêœ´µ­ó2n£Rcg·mk•„Õ¿Ø2³é¢¬NnLl8LPÓÌ©ðÆg\±Vþµuú1Wû˜ÊÓ:…‡ÓX@Áa[,˜3 f{<°{á·3MŠê²®?öûÿ¡ÓxìˆýƧ±/.Æ*D~ìžð%5ÏH`þ={ÿÎ3úyF #1?À„CöÚÍÆ¯æH)gËÙ¯HôC£èBVätøFÀô¡¤½á¹*¼Ð›øF埳P_çϯõ/d¥Ï”endstream endobj 2345 0 obj << /Type /Page /Contents 2346 0 R /Resources 2344 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2320 0 R /Annots [ 2352 0 R ] >> endobj 2352 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [359.9931 327.982 535.3356 340.0417] /Subtype/Link/A<> >> endobj 2347 0 obj << /D [2345 0 R /XYZ 85.0394 794.5015 null] >> endobj 782 0 obj << /D [2345 0 R /XYZ 85.0394 769.5949 null] >> endobj 2348 0 obj << /D [2345 0 R /XYZ 85.0394 582.26 null] >> endobj 786 0 obj << /D [2345 0 R /XYZ 85.0394 582.26 null] >> endobj 2349 0 obj << /D [2345 0 R /XYZ 85.0394 547.3594 null] >> endobj 790 0 obj << /D [2345 0 R /XYZ 85.0394 547.3594 null] >> endobj 2350 0 obj << /D [2345 0 R /XYZ 85.0394 520.037 null] >> endobj 794 0 obj << /D [2345 0 R /XYZ 85.0394 374.5703 null] >> endobj 2351 0 obj << /D [2345 0 R /XYZ 85.0394 349.7991 null] >> endobj 798 0 obj << /D [2345 0 R /XYZ 85.0394 289.1937 null] >> endobj 2353 0 obj << /D [2345 0 R /XYZ 85.0394 261.4577 null] >> endobj 2344 0 obj << /Font << /F21 1034 0 R /F22 1037 0 R /F11 1559 0 R /F42 1338 0 R /F14 1060 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2356 0 obj << /Length 1444 /Filter /FlateDecode >> stream xÚ¥WKÛ6¾ûWèE*.I‰zEMâ´Noâu‚I²D[ÂÊ¢£Çªþ÷Š”V¶´ë…$ÇóâÌ|Ã10üˆÁ\ä40¼ÀA fD‡6öðßï3¢y¬ŽÉr½ÚÌnÞÚ¾ À¥®±Ù tùû>16ñó4 Ø\/Þ/nïs‹2l®î6‹{µ}{·V›WËÕµû¼Xß/ïVê ‚‘m}pæ–K\bÞ~ø°X½Yþ¥þ½•Úñ¤öo›w³Å¦¿ÆðªÛòßg_¾a#†¿›ÀgFŒHPã0s˜˜cÛ%›ÝÏ>ö ÿ¶¢S¡ëy,ÛA>Ø¿` צv`â ìøÓ…t\2À_1ñ.¯ê>âSc¨nd´c¥t`Ô'ˆ;7ºÌËz7'>XÇ4Jy^Í-›2³âe•æ{uhž«Ý1,ÊžÊÅ5|N̲ ÷\Ã, O!uóH´k\j}i•hZoš‹æÕDYXjþJ¨uˇ+XŠ,0ˆ‚E £í"~¬xü3T‡ÍªH÷{^´NSוNS׃*ûøi¹^(Ú.L³ZYWua¹«Qjâè*-'’ó̲ޖü{ QÌ &'EŒÂ(á1T·Í|s“¤Zn‡bÚÄ=â´Œ20+,¤¹Z_^X°kùc©–`óËzn{æF1üäàÀ÷¾I•PÄèuî ‹:(À® UÌ!Øí¡  $ Ï\ñF£™‡U]ðò9ô¹C®/ã`Èõ<z®k8xÑhƒ‘ÑIœ]‰œ£‹ÓÓÒÉIÂ|ÿBÐØ$Þµ  ¸^ZÇu5h/} Ú¥Ñé  ~:ÆaÕ•g•èDâpL³Ëª ãX!¥,y©H;€R»ù­ïî6sÆLë~±–«|7Ðj±™{ŽùƒiquZ^Õ{]Èé?Ï'„1†˜Ë®$dÈõ|Bz®k yÑhŸ‘ÑÉ„œ½­¡_iVé£Ì†ÃÌ’¼(Õ¡JÂJí} N‡°xhûPónžÖÛ¯˜aŽö²×`ßÜfaôˆ¬h3 k$rùˆìëÌ MlSìt-_±?†YO5¼³£D%pà+œ¶\õrØB§-Ò®ÐÂüÔ„§9!ÄœnŠÄ¦ä›¢§ki‘k#b§Ö÷éŽkUä`¥Ëò*6-$ˆmòVž8J™”ow °ÑC0É9IÑÚ·Ö¯ÔF¾„’e«¥c^ñâæm༭5c“f™bÍ…&u2[¾}@¡3lKÃiÓIXvìí[ŒJ(ã¡|’&Ò×ãÙUËAäURjø2ˆ“ Åkû(r¿^â„P†&;GB Ûz"S?ÝîÏ'ÐôÖP¤E3LÐX³t ©ªcùËÍMÓ4Þ\$ŠýM,š<a\Þ”bW5aÁ-9ŸÂ<Š¢R‡£ÈÒètsé¿ãÈs]záÿåDÙq}> ÖX›ôù·ÉJ¶a¯R/JÙ×¥¼êAåçoÙ]Eý_êXÉÀÌ~þvÓV"¬ºË OujM†Ù--ÕÛ§¶‘ÀÚ¶ XáƒÈ@‘žˆÈ°¾á(@Ë6ãÏŽm.%x\úäC#êL[ÈÒ~î´#˜ý|ªV[.Ÿ˜Ëû×rC{‚r\ÑZ·}í¶¯T¦y­\ÈÀu¸¢|¯¡·U'EG®K¡ÆËH³é’jï+çT?0ݽý1-Sí‚li±ÈÛ¶Z*úQŽÛg÷R_iÐßÇpƒÏ.ÏÂ æ øs @$r¼†¶NÀJŒÁ6ÒÛam5¸¡ˆÚ1>ÇÎýº@QÏ5væ,cmC¹<Ç÷u°ÐsƒàK~ N¸„{DþïÓ§ Äñíûtz¸ðIúýô >øê&ŒzÔ$¶?º°PZÌøVÿq´ÛKendstream endobj 2355 0 obj << /Type /Page /Contents 2356 0 R /Resources 2354 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2365 0 R /Annots [ 2362 0 R 2364 0 R ] >> endobj 2362 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [124.9841 469.0432 450.7624 479.8575] /Subtype/Link/A<> >> endobj 2364 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [74.1651 385.0808 231.5748 395.2426] /Subtype/Link/A<> >> endobj 2357 0 obj << /D [2355 0 R /XYZ 56.6929 794.5015 null] >> endobj 802 0 obj << /D [2355 0 R /XYZ 56.6929 718.7434 null] >> endobj 2358 0 obj << /D [2355 0 R /XYZ 56.6929 693.3876 null] >> endobj 806 0 obj << /D [2355 0 R /XYZ 56.6929 660.3252 null] >> endobj 2359 0 obj << /D [2355 0 R /XYZ 56.6929 630.3707 null] >> endobj 810 0 obj << /D [2355 0 R /XYZ 56.6929 597.6231 null] >> endobj 2360 0 obj << /D [2355 0 R /XYZ 56.6929 570.3186 null] >> endobj 814 0 obj << /D [2355 0 R /XYZ 56.6929 525.6159 null] >> endobj 2361 0 obj << /D [2355 0 R /XYZ 56.6929 501.2763 null] >> endobj 818 0 obj << /D [2355 0 R /XYZ 56.6929 454.8541 null] >> endobj 2363 0 obj << /D [2355 0 R /XYZ 56.6929 429.2691 null] >> endobj 2354 0 obj << /Font << /F38 1122 0 R /F14 1060 0 R /F22 1037 0 R /F21 1034 0 R /F11 1559 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2368 0 obj << /Length 2680 /Filter /FlateDecode >> stream xÚ}ÙrÛ8òÝ_¡·ÐU#†§Hî›-çp2Ny-g§j'ó‘„ ¯ð°¢ùú틤äál¹\ºÑ@ß݀܅î"mÇO‚E”vè¸á"-®œÅp®\Y„¾¾“ì2ôc;Œ½h±<ßäöùêí{Ï]x޽Zyáây7žµŠ";¢Åsö»uS׺ÌÌÏë¥:ÖíõÏŸ˜,°£8r‘Ì#"Û‹âSÈÒÆè?š¶«šO*v̓»/¨2Òû/wãAn`ûÁÊ“ƒV¡í1³vk»×K×qk£ÓÎT¥Ðx‹ÄNVÞJH|ÇŽW!³–w‡ªßà?`ðÍó`Ë­oŽã¥FåaÜöÚµôÞ”¥)÷ !ÎÉïªB™’Ç_T!ÐÍ©ít!$iÚ7  QD?¶†õnËAGÓ½æ«î·¹I‰6 "¢P®k'aè‘TOïר·ÀJ<ç‰r+­øXœù¢ûí[¥>2¤¸àQµ Ìt›6fK<œx0ðìóˆ!>r $qì1HŒ‰ß¾^úžc½'VªbÜ%n*&HDü‡Äà…¤.Ûïéñ:ñ¬›Rw`ù${… ƒ“šEU· 5pkþfêô¦ÅIhÝ—n` v½Õ)Ù ÇJ(tÛ‘ä8A½áWÿ¬uc ]vbî†Ã2ý¢óª&G¡-˜±´h±¢ëZG-^3Ãõ±1]§‰§•XÙØUÛ¹ À™çˆLÊî :†Uf0ΆµìŒ€¨Á±ÆÌGVV¥=2ÚÊŠÁ¦¯®+TËi›¾zÑãòÈÚªŽ˜ñ"Цdˆ3 †Xõ0ötª ÂH" €®ã btƒ©aŒø„#¾]®«2Õ5 0V Þ«Ôä¦3ºE2ÙaÄžoÒ;ß~Fù|Ø}QçúÌ }OŽÄÁ¦Ö)é—g2DŒF…Y|n° ò!pL ÂAÛ^yÖ2¨¯‡““d—<ŸãzÌðæ‚ñVÒþ”¡kÛ›sØ$±Ïá²òÌ9+¢Ý´O&Ó…è/b—œˆaÔêæD‹’Kb¥À&ç´ˆÔýICàÂ’£3_#kØÓß’s8Ù‰¿ªG§ cë¡J¿«ZwäÌ-Ã0EÌ9â­¼Š¿POÞ­ðŒÉ®ªÛ¥ç0 PéÁ”ºåuy&fAb‹¢+œ_Kb·¦;Éî;^°©zXÓÈ™k•à®4êðz_¼Ù‚Ô,笪Áã‘&H€¦íL×wbDÌÊ_7ëåýæžs,®a¯‡Áæéž—qÆ]‹2Öqˆ/c΢­ÏÙÀZ#Ùtl·ür¿Æƒl^qßÑëÄfD Ôí»¤¬Ÿ<TŒá臿ÕÍwëφÂ3.ú8ƒO½Dè`'Ã*@H­À5öZ¶&/Cðèe8i«JFjGrúÖ·r¬šó¢=ç¾¾i—í ß}£²žS¤ãA÷™¤FÀ‘³À—Î2nâ¹Ç%ᤠœõeF5^ÊÒÝTõ/NÜ0ÁÞé²­47Ù‹“¦ðI·šSf„<òÎBó'žs“AE…fsŠ*ö‘»¡q`/™É.ÿ¹v!3£ 8/EÒçE1w£é¢jê رí3nÊ®ˆ@/èàŸ˜Ø€gñ°®Šºg?0÷Šrî+AòáÌÂ;ÖzóôAb €Yfô÷ÓÈj5 EÄ^lM7‘Sšƒ”gtÓð L‚‘k=( A@?¢0SÜz1#ŸÌ~Ÿ£P«HB€›ªÜƒÏ”<û/ôܼ P™fÉVÈ ;(“Tø:\^»z=YœÓn§Uù`Û¤…ˆz IåÐ\™±’zÁ£ªu¢Úudzb ñÊyq, YUêËäÿ¤òúÀõ*ê­Îsaê³~™/äw}™«š˜t)hð"dö¦cFëÝÞÔX*yÉZ:žÑ­5”Òê¤%ã2Ô…’ ÏMµ;]³Ðcä=Ï…òÁ|׌}èû¶¢O¦`àm^U2än Ž$›ôÎ×ýÊZyñL°¾)±èó"[Hܪ\¿mõô‘ËMûÇäCúÜ OÄÑgñõ¼}uýþæûŽ¿•éçž×ÍæÍÁgëeJž0 ìD·!Þש¿šr%Ì„ Mí:A˜×ä< ’Ë€H^DBY±¬Ž¶¨ÕiL©vFg»HBzãfÎ÷#( p5? y@Hù»dŒâõj8⑞µÑ>g3ìmp\ÃõQáSNR±@§¾sz•ó? !wx\ Ûnþ6CÊŠCëñ`rÝä誥×Чj«ÔZ¼²Þå ô&§LËo•ˆíËÙž²¥0ÄýoÁõàWSàý*Ï a=,iÝ¡Ê3F?*z¼Ù!Bþ¾§ €µD5jØô¦ä¶ÀŸ{°ÃXÒ |4‚ø¨ðF!¿‘ýKÆKŽx+”h¡»«û«>šù¹>4øV™ø7-ßú½Îy|”ÛÙX»§ —95¡«d0¤lJøñcÍá<æ ¬… [[P¢¶¾£—óôV{pÔV·èÞjˆ¿/n‹þäæê25µÊç¼›˜ŒDu¹jÀa›5sNö£y½!iB(àËÑÊÐi ¡ÛW–æ\%ª-Ó|Äk9 ú Ïйçâ²jàÑS8= TÍzz!^2™ÊN¼tˆš¹Ëùî²+r¦ÃI,/2}PR_!8£ÿW)¡¶Oûx‰•0ŒË8 ^UCXAGf£kð²-uN0õÇáœ;ddÅðBýY5ç»âES3ޤD õ H–ç²a[ËʋǕÜHâËÝö`¿Y7ÏOòs®¹‹ˆ?o'®Þ=¿S ¿>ø¡¿eÌü’ÿr \ýþ‡³È`ѧ+Çö¡ó\aâØ`oQ\M?Š0$¿Ú\ý{úQd8mD¶ÇÞô“ÈùÏ.lßOÜ)”ÐõÁfnHeh”z`bù¼–jüñåïbýtªó'endstream endobj 2367 0 obj << /Type /Page /Contents 2368 0 R /Resources 2366 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2365 0 R >> endobj 2369 0 obj << /D [2367 0 R /XYZ 85.0394 794.5015 null] >> endobj 822 0 obj << /D [2367 0 R /XYZ 85.0394 769.5949 null] >> endobj 2370 0 obj << /D [2367 0 R /XYZ 85.0394 573.7247 null] >> endobj 826 0 obj << /D [2367 0 R /XYZ 85.0394 573.7247 null] >> endobj 2371 0 obj << /D [2367 0 R /XYZ 85.0394 543.2172 null] >> endobj 2366 0 obj << /Font << /F21 1034 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2374 0 obj << /Length 531 /Filter /FlateDecode >> stream xÚ¥TKs›0¾ó+tÄ3µªttj§!Û9´“æ@,¹aŠìŒÿ}$\’¸¹t<í[û}»‚"?ŠDˆCÉ$Šd€¡m÷A¿À÷Õ£.f:MÇQW©÷ùšÇHb²¥»Q­“8¦(U÷þ¦xˆ¿Y|I“Õr2¥TF‘?[¯Ëyò}2e‚@âÏœz—,®­x“lÒ ýÕÝ„Gþk\9gz³°Â|¹±Âl9w%Ò[o‘ž‘ŒÑRÂ;¼û‚€¾õæ2è‚©” í½@p,ÎKám¼oç‚#oŸz‘=J0ã!»@c—臜qK_2à9êºÉMÙX-€#~V*«ÇöÈêŽ*m³ë”Ÿ„°mžÅɦ(]Ù mÖj´sJü¥qùJå-Ü’VWú¨ SíuÙZCÞ¸*¦n)G|;…0u,…`=*S˜ãsR„%gñ˜ ÎßtÅÿÙÔ¿­«ïÎ}¦´õU¦iòÇB[{kTv²âãÉ´OÎ×T@¯©›§¼² Ð:ྺ§”­©+SgKͧι)¼)ù ¶} mn™/tãÆèI÷ÃÚ™ºmÎÓëÏò°×}š98O^ªü˜«CV4ø_ÎîÖòÂ>ÂßMâ¿·ÿï‡!ˆ0cöñb»ž^¯µ„‡ˆùt M‹˜OòÔð‚Þ£zY!Oendstream endobj 2373 0 obj << /Type /Page /Contents 2374 0 R /Resources 2372 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2365 0 R >> endobj 2375 0 obj << /D [2373 0 R /XYZ 56.6929 794.5015 null] >> endobj 2372 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2378 0 obj << /Length 2465 /Filter /FlateDecode >> stream xÚ­Y[së¸ ~ϯð[™cF¼èæÓé̹å4ÛéÎiâ}ØÝ™ÊmkbK^QJNö× H]¥Û‡&â@à#Ò|À?_$! dªqªXðp‘Ÿ®‚Åæ¾^qG£BÉB%%tffW¡LX˜ˆx±3ù¸¹º¹|!E"\lv½¬(ŽYp±Ø¿,?œÏº*Êï×+ËO׿m~ uŠÅIÌq]2b)Ù_u¥›ìH >ÿø@{½Ó®rMÝ»jW7§¬-ëªgÉ“*Že²ˆ;–Ÿ¿^ñ €ußž"âE£Ñ†º¿aðþàËG±HY‰È1”œ©@(ËбIbËæš'KÏ*I– Ð<Éj[¶4SºjËkÒ¡G;!Ú²ju³ËòžQUЄѭ¡V½sœ&¤ñòùPæ×Ôƒ|Kh»uÑåºðrh®=hÜ*nŽs–†!¹Œl§Ë¶¦/È)e›µšú&ÏŽÙöèzw¨J¥[ê‘°®-«=»^É4^nƒB@;íz¾ûr¶‚¦Ý(’í»&Ϩ`ä©mAÂ.PùŸª2ÏL;ãBð_,{ºwh‚LLbÈ3ä·ið g%ãò©2Ø›âKÛD;H .y?£e"˜L¤pÂ?T/o))N””‘´J¢´©’8b¡ƒÂ½>èl ù&J™÷0`7\̨ÇáìJ gœäþ³;¶oš1e*æòÿ¡!™W,ŒyìíË-ßAo@‘ŠÔòï=ˆd ãøåËB›¼)·®‡x¶Óûc½Å‚ƒ¶3BQšü OÚɸµºÙ© +‡XƒÛå 6á$Þß~"&ñ»¹Ãô«ê«SãL¯v>ŒÕÁ[+ˆá¢žY 2 Ça»1›ËCy]™ÒÏÛ³„tsž‡àIkäÏýHÕÑQ¦3IA÷~ŸA`<cd¼)S0È9žÐt[Š@=ÁÏk ÓC.ù…%mc.<@f ’Ä-éaõ?‰‹%ýÜZFxU¹”M‡cÏlzB¦ƒera@˜œÐŽ”†Hi¦~ šÙ¾Ð·%Îɲ; å:;ÙÙE ØL´wß®¹H­‰`˜L ÌrN«ýáøb“]׃й® ãD׃ 3Ð4ª‹ Áx*Sg5písÝ<ÎÅ’0ò!ÑèÜ&ó•‚+ܯɹÅ&«öxl%äô§ê‘í‹€Ž#†˜Rº…c[Oõ+ÑQh1/OM§0åt€È•¼6† U Ø“O#×ÀŠ8Ù #²–¹á5¼ml Yåp„ÄÊ0 1n›Éĸðb§±ÛiìUO.Íçʈ‘r%”h£ì1ãè‹Sc½d¶ýìË'íF܆޻ÓåF1j½{3Rmõ±öÆZ ¦Õ F¢¬=ØÍ!Í!«¦Ô§,?”fŠ™IV ã©_ Ÿgçl‹e ž³0rA2îc¬3cØc[}^À`r©¿—T…q¯™mµÔqUkð£3ЏU[횦´atíœK¬bµ¤ÒuW¬3¶²qÖ‡ §=´±ôH†¡çì…™¡ï§cfÌ‘p][Û}®O™çv߇3è`4ùt÷ùÃÈ;ÇÇFšA˜òÕ¤Z~ÛÜOwBç…,ê"£(g.¸¢saUnÁÊ6+ÚqÊÇ.zYÎܶ®òèØ038’Ö} }{U°s®qÐO]¦€o 6n ¹Q/¶Ð» JJê BÞ;úV»Éš—kz`=&˳{y9—¹/Q¦×¹I)u*÷WUëúѵÊG½î/Œ£Š$’,‘Ò׿"øºØ&kßt´vÈ~·Þ鄯ÅVŠ™”¶êù8 Mn‹ée †Ë‘9ëÜ¢(·~0DVïZRSLÌà"{úRÄ Ù-YB)6tLlÁ?¨F®u'œ…šæüÍ¢e ÙÖÉ:dOšÈÊ*?vT ­t¨›v5çˆC=í/°v7»ònbŸÐ—=)ÃXQwhçõÑuhâQÿ÷zý:Ôp²9 ¬âo¸­g€Fж´…Î†(ßZezSîâÙdniNõâ«‚œÑ^––¹Ï9[@:£ Ÿ í‘°­¾®¬úŠôœìç 1¸‚„î¹B¸çа·²Þ7Ùùð2„Ä^­‡n¦ðªÜ묀ýž0@Šß½aÀõ2í…ô¯"÷┿-7ñ±¦>a€=ÀuǼý@" Ôö[x˜âXÀ-±¨óÎs„ë ‚qrm¤ÆO 0ìÊÛ¶˜Ðˆé¹è›È£•Üù|4oÞQkxi€ù3 ®4k*œs:œ³ÆI³xqŒfÒTo")Bw©…Æ`"ìMLdGŒÆŒLm{%‡/œ½CE! »UÝÚKn(C—lp]›a6Gý ·Ï’ÑÇ'Ï®ßv {§¨lb€.ÞÜšÙÂ}03œð/Õª'Ýô1ysbûH½[ªyrBpw_6·.ù¦þr‘&£,óßù?´C/Y~u÷‘3Mÿ‡¯ÈŸš”&ß8²þPÖ[ •£ƒ j?•®X½Ý|sG²]Ï¥û]{^ßܨéi.•˜ìÿ’Ó[ˆ‰Y¬’ÉÓÎXÿS† þ02£NÐgV˜üýê—ß‚ED?\a“pñ €ñ4‹ÓÕ𠯮þ5ìÌK[©˜É$Ãï+“÷8R¦Ü+…Šs…)<±X~¼ûñ3#e”X}S—»êÉy½­ÿÙÍendstream endobj 2377 0 obj << /Type /Page /Contents 2378 0 R /Resources 2376 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2365 0 R /Annots [ 2382 0 R 2383 0 R ] >> endobj 2382 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [282.146 101.0883 446.0314 113.1479] /Subtype/Link/A<> >> endobj 2383 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [91.7919 62.7606 237.2464 72.9224] /Subtype/Link/A<> >> endobj 2379 0 obj << /D [2377 0 R /XYZ 85.0394 794.5015 null] >> endobj 830 0 obj << /D [2377 0 R /XYZ 85.0394 769.5949 null] >> endobj 2380 0 obj << /D [2377 0 R /XYZ 85.0394 579.1401 null] >> endobj 834 0 obj << /D [2377 0 R /XYZ 85.0394 579.1401 null] >> endobj 1663 0 obj << /D [2377 0 R /XYZ 85.0394 540.7142 null] >> endobj 838 0 obj << /D [2377 0 R /XYZ 85.0394 244.5601 null] >> endobj 2381 0 obj << /D [2377 0 R /XYZ 85.0394 206.1735 null] >> endobj 842 0 obj << /D [2377 0 R /XYZ 85.0394 206.1735 null] >> endobj 1371 0 obj << /D [2377 0 R /XYZ 85.0394 177.2481 null] >> endobj 2376 0 obj << /Font << /F21 1034 0 R /F22 1037 0 R /F40 1265 0 R /F54 1433 0 R /F11 1559 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2386 0 obj << /Length 2755 /Filter /FlateDecode >> stream xÚµZIwã6¾ûWè(½7f°p=Ê’¬¸»-;’2™L'¶Ä–ùš"‘r·óë§@,)œždžÆRÄ'ÖW¨ !øÃ#ÏwüˆD£ rao´;Þ Ñæ–7XÈÜJ¡[]ên{óÃ= G‘ùÄm?kk… C<Úî?Žgq&°ß=Ü}xxZ®§Ï?þ:¹%ÿ†<4]Íygóór¹Øl¢»^Lç«%ˆà‰b2ž>?/Vó‡ñé[¡ñr±Z¬§øà|µ‘ß/Ö‹ÕlÁ»«û§õãt¸ãíÃÓjòûöÝÍb«ÞO×F”½Ü7G£=¨âÝ rhz£¯ÐAŽ"2:Þ¸u<—R9’Ýln~R j³õ£FbäêƒR aס.LêZõ"‡„©µºN>'ç$ß%%{þv"Ï«A£[ê9^èsáMçûø¼/û^ÜÂ<vòu)þ;‰|%Å?®ïg Q÷÷.2&4ävh%uí" “ÀñHÐÆžÇ8͹¬â#hŠÛ!0¡ôwªÄ8¨ˆ7îã]š¥UªT«¿%ãùA¿aüƒ?ò<Á$;ÿäÿøØc±ûŸ’꜖BjU¼&ÇOÉ™÷pN/!!rÜÀ Ѥ,„H)ÏBˆ Z#¤‹m&DÇ$äáxÊ’c’Wq•y‡–Í)Ù¥¿!Dv|öš‚‰Cû&nxçodÈ'Ž‹P4À&eaHJI†¢À¶clÈA]h3A:ôcœf—*Í ª—DøYÉÍ[Y%GÓVñÀ›zm2fBõÏñÔ¾?$bü]œ_âó›Ò»ï˜ÜÚ-!®….–îÖk?Ÿ‹SQ&ÒNÂŽï»îsš”…9)¥öVÙö– Z£®‹m¦NÇ~Èwç Ç|ûÿ]ä‚°íc<>ÇyùYZ·äÅLy.v°ºmú}O/U,†¦—Ã¥¬$q‘ß»a¼bb ¨]—êW»’ÒÔî÷«Ý ݨý Û¨ööTè%Ù½ÄyZy÷s!tü\sRO•ô/•îÂê±âs—¬¬u0F¿Õ‡ Àæà$ð­rŒ€W\ò½¤üt–nï`øP7òƒº”…q)Õ0b ã6hñ.¶™q{–Ågm‹‰£*ºL ÃY†wD¡íM·vTƒÿ¿»”/¼µÈþ”Qí’½ý7Dàbp4´õ4) RJAQh!­ÑÅ6¡c¯’hôUº´x÷¢ò éñ ?]’sOºM#Ÿ˜ÃÐ4ßó ÷U&pq=°{Qj{ÕîF‘CéÇÓ¥úÕ®¤”ÚýÀbÿVèFíWØFµ·°ߪ$/UpQ©ìD&¥{V‚/ ‡êBÛTð`'¨ÿ¿Çœ~ÃwCì/òФ, H)baÀ­1ÐÅ63 c¯Šü–§[Éù˜æ2S çÁ¥vÉ>åö»ëõ=žCšÍvŽ¿2Ba…½YõQ¿ê}êàШøu)‹ê¥”R}èZ’`+´¦ú.¶Yõ:ö&I0ÓõÆï“7ÞhÒßx'2/ꃲ äUª²1äœ/h° ²Ý<,{ö!ÔA¡§{(x¨ÙÐiíŸÄøò²?BØ.y2@h8ž‹™E\V·<Þ«õ[ñ>‹¿ÈÝF[ jµ;a$¿L"2N² ¼oÅqj7)âAõÛÝzîÐöÔ¤,6"¥”DYlÄ­ÙHÛl#:vËF@ÜFXØ.«øS––/¬‚²yËíû…8¾\¯ûœf9nä‡í};”0v{ Ü$§J;ƒ°„=HMý§&e!HJiÙ"˜ Z#¨‹m&HÇnÎp“?.‰tfÊ® [™i-=äquáÌ– W|ߢ:¸•};AŽAIô& ²y¡!«Kõ“¥¤$Y¡ Ÿ,+tCÖ¶‘¬6ì&¡ô냡&Љ*J±×\ðGdÆ:¼F3ºYì@„Åm’¬N®}˜gç&ø?pܪKY¸‘RŠß ­Ð7]l37:ö2É!­fŠ NTZ1_øÐ;¿¦»„OM³CS/G>Ǥñ”Ðçž$ [-Ó¦úZ|SCƒÑ¿ÜlxpCí f‹²Pâynç4j#Øÿ5ÎMyé’YÉá4ãÇ2oõ{ˆÙr¿—é§âUŸy×2²Þ2¾Š¶² ü1Î21÷´« Ýú¨ùH3ò†^û¦)OÚêã¤ï:è¤Ö¦!°jMÊbÕRJY5!6«¶AkVÝÅ6[µŽýïk“Åä:)‹ìUêys9ŠsuUgn3S˜ö=ðü¡oöü³"?+¦çÉ®íLp¯3:ìÓµëRýjWRJí!¥ýj·B7j¿Â6ª½…½}á¾ ÝÂo€Ò;ÎÞÊ´ä=¦iöŸŸ¦AC¦A[œ¦AKÆÖÖã€ÙÝSOϪëU^}IsÍÈ ±–“P%)s.öeA$Ri±¨ð:üÍ€K·ŸKt@é•…I!$‰t‘•H ®ÆcØL£\ûéáG!쩊{Ä ƒ6ñø áÚÙ|­cöKÉÒæžÁxbºP¯èÉ knØóSþ,Ô<Ý E}£⳨¯ØyŒË2‘®›‰ ȭͽ¡#¯´ÊÄ|Jàõ[õ!2pϧKYl@JiF`¹è³BkVÐÅ6›ŽÍœ&ÏÛX@)cvW°PRwê°M¡åû™ŠøÍá°ž:m2^V`öõƒ«¥lÔ‹ø6¥Sh&BÍØè£W¦Àçâ,\!´˜oHçù¯Ù;{GHu©~[PRš-Xªº±…+l£-´°ÅUUì vTô±ØwŽÐC"R9éãÙOR˜[o’è ›Òcð#B7ÒÏ´"Ì(X´í!Ô„îÖÙ裗f!ü»X¹e2œÿ=fq•¿È i÷Fú ”tVß4@BË# Z”§ÓOÅ¥ê/t>€è3CȆ!"f¨IYÌPJ©›TÏj†6hÍ »Øf3Ô±§“[¸š-±ž°ÍOËØ@M™6#Òa62+Îúaj=öË„ 1”6zoŸdbõyrÊŠ7ù|MBýŠÏÕWNâ ˜BÖP_ q^f/|’šm•6Ëø•ÿàÜTà(¢½N'%yx ›Ô„ú¹–BÕ–[YnÃtØH´<+ŽG~ØŠå«áØ\p:‹sÉeøn…‰Íåp€2¬.ƒ`ü>ýf¾+§DX÷3ÔO¾ÈûË1–÷¬ìĵ.ò`µçVÎÄàL ®V^F®Û"¸UxÎãüÏôÐçeÓ,Sw¼ßg `[” ˜B#cùl…Ë4_O„–« ¨öÉJÕüÁJƒºIΩ¼Y]šÂjZD$Uº3¥–àƒ=÷ú&V]»öåìjö{?‡`wÊæü)÷ÿ—?ÕÎhð„ု¿©¾ï_ÍFK‚nŸ]ÈŽAÉdŒ]rõRòSÓë·ú›Ê íendstream endobj 2385 0 obj << /Type /Page /Contents 2386 0 R /Resources 2384 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2365 0 R >> endobj 2387 0 obj << /D [2385 0 R /XYZ 56.6929 794.5015 null] >> endobj 2388 0 obj << /D [2385 0 R /XYZ 56.6929 748.2159 null] >> endobj 2389 0 obj << /D [2385 0 R /XYZ 56.6929 748.2159 null] >> endobj 2390 0 obj << /D [2385 0 R /XYZ 56.6929 716.4106 null] >> endobj 2391 0 obj << /D [2385 0 R /XYZ 56.6929 716.4106 null] >> endobj 2392 0 obj << /D [2385 0 R /XYZ 56.6929 716.4106 null] >> endobj 2393 0 obj << /D [2385 0 R /XYZ 56.6929 710.5059 null] >> endobj 2394 0 obj << /D [2385 0 R /XYZ 56.6929 695.7413 null] >> endobj 2395 0 obj << /D [2385 0 R /XYZ 56.6929 692.431 null] >> endobj 2396 0 obj << /D [2385 0 R /XYZ 56.6929 677.6664 null] >> endobj 2397 0 obj << /D [2385 0 R /XYZ 56.6929 674.3561 null] >> endobj 2398 0 obj << /D [2385 0 R /XYZ 56.6929 616.655 null] >> endobj 1490 0 obj << /D [2385 0 R /XYZ 56.6929 616.655 null] >> endobj 2399 0 obj << /D [2385 0 R /XYZ 56.6929 616.655 null] >> endobj 2400 0 obj << /D [2385 0 R /XYZ 56.6929 613.6196 null] >> endobj 2401 0 obj << /D [2385 0 R /XYZ 56.6929 598.855 null] >> endobj 2402 0 obj << /D [2385 0 R /XYZ 56.6929 595.5446 null] >> endobj 2403 0 obj << /D [2385 0 R /XYZ 56.6929 580.78 null] >> endobj 2404 0 obj << /D [2385 0 R /XYZ 56.6929 577.4697 null] >> endobj 2405 0 obj << /D [2385 0 R /XYZ 56.6929 550.7499 null] >> endobj 2406 0 obj << /D [2385 0 R /XYZ 56.6929 547.4396 null] >> endobj 2407 0 obj << /D [2385 0 R /XYZ 56.6929 532.675 null] >> endobj 2408 0 obj << /D [2385 0 R /XYZ 56.6929 529.3646 null] >> endobj 2409 0 obj << /D [2385 0 R /XYZ 56.6929 514.6599 null] >> endobj 2410 0 obj << /D [2385 0 R /XYZ 56.6929 511.2897 null] >> endobj 2411 0 obj << /D [2385 0 R /XYZ 56.6929 496.5251 null] >> endobj 2412 0 obj << /D [2385 0 R /XYZ 56.6929 493.2148 null] >> endobj 2413 0 obj << /D [2385 0 R /XYZ 56.6929 478.4502 null] >> endobj 2414 0 obj << /D [2385 0 R /XYZ 56.6929 475.1398 null] >> endobj 2415 0 obj << /D [2385 0 R /XYZ 56.6929 448.4201 null] >> endobj 2416 0 obj << /D [2385 0 R /XYZ 56.6929 445.1097 null] >> endobj 2417 0 obj << /D [2385 0 R /XYZ 56.6929 430.3451 null] >> endobj 2418 0 obj << /D [2385 0 R /XYZ 56.6929 427.0348 null] >> endobj 2419 0 obj << /D [2385 0 R /XYZ 56.6929 412.2702 null] >> endobj 2420 0 obj << /D [2385 0 R /XYZ 56.6929 408.9599 null] >> endobj 2421 0 obj << /D [2385 0 R /XYZ 56.6929 394.1953 null] >> endobj 2422 0 obj << /D [2385 0 R /XYZ 56.6929 390.8849 null] >> endobj 2423 0 obj << /D [2385 0 R /XYZ 56.6929 321.1331 null] >> endobj 2424 0 obj << /D [2385 0 R /XYZ 56.6929 321.1331 null] >> endobj 2425 0 obj << /D [2385 0 R /XYZ 56.6929 321.1331 null] >> endobj 2426 0 obj << /D [2385 0 R /XYZ 56.6929 318.1932 null] >> endobj 2427 0 obj << /D [2385 0 R /XYZ 56.6929 303.4885 null] >> endobj 2428 0 obj << /D [2385 0 R /XYZ 56.6929 300.1183 null] >> endobj 2429 0 obj << /D [2385 0 R /XYZ 56.6929 276.0486 null] >> endobj 2430 0 obj << /D [2385 0 R /XYZ 56.6929 270.0882 null] >> endobj 2431 0 obj << /D [2385 0 R /XYZ 56.6929 244.6437 null] >> endobj 2432 0 obj << /D [2385 0 R /XYZ 56.6929 240.0581 null] >> endobj 2433 0 obj << /D [2385 0 R /XYZ 56.6929 213.3384 null] >> endobj 2434 0 obj << /D [2385 0 R /XYZ 56.6929 210.028 null] >> endobj 2435 0 obj << /D [2385 0 R /XYZ 56.6929 140.3717 null] >> endobj 2436 0 obj << /D [2385 0 R /XYZ 56.6929 140.3717 null] >> endobj 2437 0 obj << /D [2385 0 R /XYZ 56.6929 140.3717 null] >> endobj 2438 0 obj << /D [2385 0 R /XYZ 56.6929 137.3363 null] >> endobj 2439 0 obj << /D [2385 0 R /XYZ 56.6929 111.8918 null] >> endobj 2440 0 obj << /D [2385 0 R /XYZ 56.6929 107.3062 null] >> endobj 2441 0 obj << /D [2385 0 R /XYZ 56.6929 80.5865 null] >> endobj 2442 0 obj << /D [2385 0 R /XYZ 56.6929 77.2761 null] >> endobj 2384 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2445 0 obj << /Length 3080 /Filter /FlateDecode >> stream xÚµšKsÛ8€ïþ:RU>´¥ÈÊØŠFr²“š™-Ñ1+é©$þ÷Û iœÝ­-L ´ˆ¯»Ñh’L0ü‘Iè!Ì"wD.ò0ñ&ûÓž|…¾å‘23%43¥®®~yÏÂI„"Ÿú“‡'c®á0$“‡ÃN¼Ù,ÖóÕïÓõ°sƒ¦3cg¹X/¶ñhœ¯wâb»x¿Ø.Ö7 q»Z¿ÿ¸½§ë<¬>®§~H(Ì@ù>v®W×w«Ëm¼¹ý"ü‰=¯çâf÷i¹\ìs5w<_­— B¦=|¸Z<èç3×€`Æîï«?þ“,Ň+ŒXz“pƒ‰":9]¹CžË˜j9^í®~Ó½õо5Õ23æ¢Ð‡9ì+ïEÈg”é•§´oå•_ù?¶ïo\¸uŸ—x…%sÒ7ªµÔ[Ý.6tÏCaÀ¼¶ò›ât*rXz9÷Yù˜>'ß³âræ-¡M²¼¬D·À¿]Òs––Bä©8‹ÖÕæ»/®âÃá<…®´,A ª³ Ô§l$€ßÏÂ;E=çË”â ùSŠsV>gU"”$ùA´?p#“2²ü”f︂ÉLÏ9#EžGë©ï“WaUcÉŸ «Dž`Ñ`õ˜ «Ç|DˆÕã¶i k°O¥I¦ûâ|×Ó;¯/â¹úŒÓaž tífbJ ›‰–RfBHȆÍĪº1“7ºûͤ¥|þà‹Î”0g»• éŸÓ<«²"ïƒM° Öó°y|y?¨ ÉœÅ÷´6˜çä\ÕĹ“]±üŸœ’oSâ¥ØÊŽOÇã)És9¯4æl¦„Fjþûbÿ-yI+°)i.úWµÌåã¾*Ó³ ñ£AʰJQE#” ) e%¥)Ø·P¶©6(wuP6•ë¿ÞÅeûÜ8œ¶7ô¢¦Q¨Aþ‰ÿ÷@)Ë¿ŠÁ‰Ï&{oŠcz<&rL„; ‚(ðü`„!e¡¤4ˆ0°°©6@tu€0•ÇÜšç>Mrf©/Ã,´-~¾¨à*V:ïŠ}ÂýOH¬r>éßÉdGõœŠ‹yqJ2Ù¹NN²u÷ZV驇+ÃyÌ'WFꡞ 6ŒR¶5^Ÿ§žçd?³Túœž¦ås"¢¿ë˜ÅJšÅ<Ûƒ¨È¥À‡$¿$çWmþ°aày~8²]›RÃPRÊ0(ö¨Å0lª Ãèê0 S9#žpTFÜ: ó†Ú<øÅî%ÝgO¯µiðûš9—ll„7OR<=Ïöi‰ú¶i! Icg€˜d>ry9>žW™æBAÍŽ÷h#à7†ÔÕg‹M[ihY„«ˆAâjÇjJ cÕR+ñ-Û«Uuƒõî~¬-埄/ÃRH`p±Ê«ôœ§•¸Äy!²ö³ÇK%ÅïW¿/¶âò¦ —c—Çâ19Šk#7“ã’—®¼ÇíݹÄe þ|¢ãLºµkA<ûýsV ¸m8Ì× S'l„¯!e᫤ ¾¡…¯MµÁ·«{€¯©œï¢Ç‹ŒÈ̯ݲÀù”gœ”hìlµÐ²:¤y•ñü*=—¢é"£>SáÚt8g:œ3k8g(=f†óHlÄ|²$ÏÒ£˜B„ch¼G*„Ë¡í,;MŽGøY ö%O5é`˜4 <ÙH eJYH+)Mš2l!mSmîê m*ÿ5•V¾ø¹Nò¯r%æé1ýª¶äΑBlíp!€ÊƒvOzOKkgW*Š«Ö>ÙM †1¸àŒùv ¦Ô0-¥1À~?ŒÁªºÁðFw?†–òù.ÏþëâKÙÉ-v«¥lÊòîÂ+Oâ9°ð$>@x’.]Užèn™ÌEQà·Í%¢ERVÇä[*›Yíê‡w*;žÿ¬‘EÃÈBÌ©‘iJY))Y`AfSm ëê@f*ßîâ_îçì.ÂÆ"ÓŠ@aãWœÿ/¶JQØx£ÀVØøõ6?B‹‚ùñÙ n.6¹ñ»†›,CÈ™º…&¬sƒ‘8hJYh*)ƒ¦edzª6hvuÐ4•ïªâ\ïT$bÎMzÛ¤ ¼nD"·†Èûjˆ¼AAä"¿R¹ÄDÊ "Ãùøx‘5{ ¢©MŒ_|”ÂËËátÔVf8zæÔ&ØþG¾K1"^4R2¥,´•”A;²Ð¶©6hwuÐ6•sÚ‰ØëB‘Üxd¨Ouê2»Mëè… ²ý™l‘Ñ74¢o¤£ohDßhÌŽÐn«þÊðµ,Ào…_Ÿ¼qc5“$NÆÝ˜…ðCbçj cUB U×’ËØô6P»Šû™ššçi•ìŸÓó1Š#¼Q†èa ˘ëýŸ·Jˆß(`ÁHyÈ”²pQRLZªVÕ™®î4¦ò:· T¹.µXh™dè”F€wH ø±Lg¡ÊS§”UÑ*IŠ®Ý–×g>yr ´<.5[˜È(4…!Ï( ÝIÁE™©P«&l…ÚÇâ{ýr@Àûôñ< æDI1.Õ2— på‘lÉ”²˜€’Ò&Ïb6Õ† tu˜€©üu]—{cÙu™_ªgØv«Wѵ)2^C}œê:Þ¬‡©“à‰‰Åaò]Të¡-¶»ôbˆ>«ØQò áã‘â)eA©¤Jh°…Y›jeW÷JS9O|w·ñŒˆòxBeêK)å¢EžfàJ”o‰ªéR£¦KtM—4®G6Ïè`ót CêxL[)0¯ìñ˜W©“W XNÑâ @É PȬèH6dJ ÕR Pj©æYU7@ßèîÚRw_—oõ»CÊßvŽýwYYÉ©ȸ]¥ã qËó©Ÿii¼EßÜ)ƒi±0ÚÛ¬á¨UìŸßTnìÔ|Š"ä:¦”…š’ÒÔ¼ÈR2°ª6¨uuP3•‹ k‰âÏ*ÍËúuæŒEXT\áyyy)ΕZmDã÷ô\Šª:4ú}Uظ±™“zΉÏÅI$xël½½d൉lý¬ëéÐõk™åI^É.q8†fU ÓÚÚ1¶¸de™õÕ†4Í(¤Áx${2¥, •”ÚRh°ª6@wu€6•ߪõ›HårŸòoyñ#ïºîÀëÏÆ¥ãµ¼÷£FŽIÛcé„ËKY%Oes¦|»-²þ麗FÛ0èÐU/]ãÒï s¢©G˜RÃеTó&ÃЭªèot÷Co)× ²È÷Åá ýuZý(ÎßšN·høÖïü(ãQì–xûÙ¼i}™ ,âåœÕÉ&>Ù!L‘º­)eÁ¤¤L¶­ÓªÚÀÔÕ=€ÉT¾Mÿ¾db¯;¥¹ÚõVÙ¼ãw·…Þ8gjñ^ŽÙÞ¨³7E_¼û3@Që5WýÕÂ99¤Õtæò$# )e¡¢¤4/²9MµA¥«{€Š©|üô¿«Î—}%"eÚYzãÝGÏöyȘÛ^ýÒ=6@˜ŸÎýß…â#ˆ#)Š)eá ¤ô¡ËÎeUmpèêà`*¿9&eyÔIáj=‹çó-Š·"ÀÄÿd½=,ê|£s«ê.Ù!OU$ZÊÆƒº¬—¿(ªîÇðÖ¼ðï§6üòº GŽw†Ð03%¤‘…Ô’UÚô6ĺŠû™šWñµÚ2xù"Ý?çŽê‹§qr꾉ú”g_Òn6‹ß»éPzÝM§+cIËŽŸ^I§¼öOª*!F8ôF>C6„†Q)¡¦¤B-El›ÞUWq?*S³qn¨Bœ9»)qT”s£N$Wñ:W7p\Èé9ú’<}˜'1˜±>`Ãpó€ ÍÆ›wJ¡ëºê•çâcÉÙ¿jO;³ä¤>kÔJZukí¨OñSMKÆCü[èžÕÇ:+ýŸ?Ë6Þƒˆ…C_g1ì"ÆOoòGÕ%z—MÁh@ë•úÂ> endobj 2446 0 obj << /D [2444 0 R /XYZ 85.0394 794.5015 null] >> endobj 2447 0 obj << /D [2444 0 R /XYZ 85.0394 769.5949 null] >> endobj 2448 0 obj << /D [2444 0 R /XYZ 85.0394 771.5874 null] >> endobj 2449 0 obj << /D [2444 0 R /XYZ 85.0394 701.2317 null] >> endobj 2450 0 obj << /D [2444 0 R /XYZ 85.0394 701.2317 null] >> endobj 2451 0 obj << /D [2444 0 R /XYZ 85.0394 701.2317 null] >> endobj 2452 0 obj << /D [2444 0 R /XYZ 85.0394 698.1335 null] >> endobj 2453 0 obj << /D [2444 0 R /XYZ 85.0394 674.0638 null] >> endobj 2454 0 obj << /D [2444 0 R /XYZ 85.0394 667.9451 null] >> endobj 2455 0 obj << /D [2444 0 R /XYZ 85.0394 653.1805 null] >> endobj 2456 0 obj << /D [2444 0 R /XYZ 85.0394 649.7118 null] >> endobj 2457 0 obj << /D [2444 0 R /XYZ 85.0394 622.9921 null] >> endobj 2458 0 obj << /D [2444 0 R /XYZ 85.0394 619.5234 null] >> endobj 2459 0 obj << /D [2444 0 R /XYZ 85.0394 595.4537 null] >> endobj 2460 0 obj << /D [2444 0 R /XYZ 85.0394 589.3349 null] >> endobj 2461 0 obj << /D [2444 0 R /XYZ 85.0394 562.6152 null] >> endobj 2462 0 obj << /D [2444 0 R /XYZ 85.0394 559.1465 null] >> endobj 2463 0 obj << /D [2444 0 R /XYZ 85.0394 532.4267 null] >> endobj 2464 0 obj << /D [2444 0 R /XYZ 85.0394 528.958 null] >> endobj 2465 0 obj << /D [2444 0 R /XYZ 85.0394 514.2533 null] >> endobj 2466 0 obj << /D [2444 0 R /XYZ 85.0394 510.7248 null] >> endobj 2467 0 obj << /D [2444 0 R /XYZ 85.0394 496.02 null] >> endobj 2468 0 obj << /D [2444 0 R /XYZ 85.0394 492.4915 null] >> endobj 2469 0 obj << /D [2444 0 R /XYZ 85.0394 468.4218 null] >> endobj 2470 0 obj << /D [2444 0 R /XYZ 85.0394 462.303 null] >> endobj 2471 0 obj << /D [2444 0 R /XYZ 85.0394 436.8585 null] >> endobj 2472 0 obj << /D [2444 0 R /XYZ 85.0394 432.1146 null] >> endobj 2473 0 obj << /D [2444 0 R /XYZ 85.0394 408.0449 null] >> endobj 2474 0 obj << /D [2444 0 R /XYZ 85.0394 401.9262 null] >> endobj 2475 0 obj << /D [2444 0 R /XYZ 85.0394 387.2214 null] >> endobj 2476 0 obj << /D [2444 0 R /XYZ 85.0394 383.6929 null] >> endobj 2477 0 obj << /D [2444 0 R /XYZ 85.0394 356.9731 null] >> endobj 2478 0 obj << /D [2444 0 R /XYZ 85.0394 353.5044 null] >> endobj 2479 0 obj << /D [2444 0 R /XYZ 85.0394 326.7847 null] >> endobj 2480 0 obj << /D [2444 0 R /XYZ 85.0394 323.316 null] >> endobj 2481 0 obj << /D [2444 0 R /XYZ 85.0394 299.2463 null] >> endobj 2482 0 obj << /D [2444 0 R /XYZ 85.0394 293.1275 null] >> endobj 2483 0 obj << /D [2444 0 R /XYZ 85.0394 278.4228 null] >> endobj 2484 0 obj << /D [2444 0 R /XYZ 85.0394 274.8943 null] >> endobj 2485 0 obj << /D [2444 0 R /XYZ 85.0394 249.4498 null] >> endobj 2486 0 obj << /D [2444 0 R /XYZ 85.0394 244.7058 null] >> endobj 2487 0 obj << /D [2444 0 R /XYZ 85.0394 189.2701 null] >> endobj 2488 0 obj << /D [2444 0 R /XYZ 85.0394 189.2701 null] >> endobj 2489 0 obj << /D [2444 0 R /XYZ 85.0394 189.2701 null] >> endobj 2490 0 obj << /D [2444 0 R /XYZ 85.0394 183.2071 null] >> endobj 2491 0 obj << /D [2444 0 R /XYZ 85.0394 168.4425 null] >> endobj 2492 0 obj << /D [2444 0 R /XYZ 85.0394 164.9738 null] >> endobj 2493 0 obj << /D [2444 0 R /XYZ 85.0394 150.2691 null] >> endobj 2494 0 obj << /D [2444 0 R /XYZ 85.0394 146.7405 null] >> endobj 2495 0 obj << /D [2444 0 R /XYZ 85.0394 132.0358 null] >> endobj 2496 0 obj << /D [2444 0 R /XYZ 85.0394 128.5073 null] >> endobj 2497 0 obj << /D [2444 0 R /XYZ 85.0394 113.8025 null] >> endobj 2498 0 obj << /D [2444 0 R /XYZ 85.0394 110.274 null] >> endobj 2499 0 obj << /D [2444 0 R /XYZ 85.0394 95.5094 null] >> endobj 2500 0 obj << /D [2444 0 R /XYZ 85.0394 92.0407 null] >> endobj 2443 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F40 1265 0 R /F21 1034 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2503 0 obj << /Length 2586 /Filter /FlateDecode >> stream xÚ¥Z[w£8~ϯð£}N›ÕqÙ7'vÒîM;Y'=3{zúØŠÃY ^Àééùõ[Bd rïìÉCTèƒúªJU…ñÁ±À bÂØ÷Âl´Ù_¡ÑÖî®°’™j¡©-uý|õ·[b/H0z~µöŠ<Exô¼ý:¾ñˆ7Ðøzy}¿|¸[Ï?þk2% G ÍVs9xúrw·xz^¨áz1›/Ww ‚'A„Éxöø¸XÍ—¿Éå±)Bã»Åj±žÝËÉùêIß|»X/V7 9\®nÖŸg“Ð?/V“oÏŸ®Ïæýl`DÅËýçêë74Ú‚*>]!Æ}‡òp“ÑþÊgÔc>¥z&»zºú§ÙÐZmníÕ)F¡éQ*Á#Œ½˜1r¢U{%´ÑªyÓ‡/“:-òjð­(†§¸À«‘‘@úX•2ýëúöE¿u11!ðâ,t™.ª,TLB‘ÐFû$Íåk'Û}š§U ï^”•œ+ZU4ãÝ1ÝrOQk›º°¸ˆé AŒ=DÑ…ˆfK sa¤ 1&Ã\8¡[.ΰ{¹8ÁîåÂÄ€$SÞ‘oÿ*#3/ˆ"rÊÈ\“‘”¶gÜò—rIùà "/b(º@ˆ%å DKiBÂÈAˆ Ú"¤‹ÝOˆ}¦û›2­y™*çx-”©®‹¢Vá$Ù+yâå;/«ÞFà€QpJõ¢ás’çi¾ë}â6¿L§¤|Ào41ä!¾ÀR+ä I ŽŽ9p-Š:Àý YÀ_*¥íâµã6³,M*^uˆZñú{Qþ»e(Ýð~Š‚È I7véSäc²O³Z»œáh­–^T¦»·z€ŸPCžäSBc1H)¦>ñàA¤.s0¹\™aú'W`ö)¬n0E`aìE_Hl©aÒ”a="l˜u'tKûv/ï'Ø3xñ ?O0Æ@À.kÔ„ {‚Æüåï“)õÉxYUÇÆ`¥1¸g‰£ÕyitËÅ|¨úËÕ¸*Õý ¼–£ƒ ·u±)²¾KIì!Û†ËÙµÜ× ­“MüTZ†´óy’Â+j+LT@&¡AOg~èAxõVÈAºÒœS?vDc®Ey¸Ÿq ¸ã2@RÖRH}åÍ´œbãÙᥓ8ÂŒ(K–óÕ¬©=zŽH ˜1Ã_pS}ap›d5$§ ïûF <ø¦‹¯û$o–#E³xE³™šÐ$Uͳ¬0D7 ›7C÷pBÄàhg”\ˆì¶”ƒp-e1ŽŒ» -Ê»ØýœÛØ‚Pé`üÍX,ŸBt}ªK0½&æ€$I‰È‰DÒ*ÄšÀ/Öz‚¨X×Ö#DLíZDÃim{°‚–p±E¸Ü«á[¬|Ö|ëMNø¾Î’|óÆë¿À·Q(.ä¶Ô0ßFÊâÛ‘;¡[¾Ï°{ù>Á~<æ?6Å–‹èÍÂ&ȇt| ÙUÕð-Æþ˜ç £FT†u˜ý’§âV9)|˜í; Ƴcý¯á´yçrJAq¥úÚbŽßE+¼™}“Œ(:ÄXTcIU«ý¶[¹XU½.EAåZýp¨ M”;|”»o›Ž·X”i„ì˜é»O¢ ðH†y„ê J§ _òl)ZÊð#—ù -»Øý<ÚØ&›[>¾: ÇF™äU›Þ}Ó¸_R³4çýßðÇö±f'ÓóciüÔ\hG[¾IÒµ«=ñCme@?ÐgØ‹ o:mƒ?¼TEÆkÞACÛ2¾‡À¯ ÞÅðŠ©˜Ñ¯(Ì€)` g(ØŠÛl©aS0RVõä8Э)œa÷šÂ ¶4Œm«FMè„ÿw¼Ø•Éá \4“3÷ŽÔ2 ^ÄXl7Dqó qãm"¿7ò,S+Í7Eòæí˜ýÉÕì“’ÌxZçÜ|g¤XQ ks%ÕÆ¶ÈÓ*ÉÑø']˜ÿ¡tÓ° ÎnK9ÖR&å BG}ì„¶îb÷3lc_§¹9²î“®Kåôì”í-&Tãc ˆý¸ÿ»×M™|•‘­Çݱª ñ HðèfÁ&A µß BGùìÂm)è÷2`K‹0D›Z$2Ïq]ˆÿvM “*$Õuª‰ÝNNìôWüHûì²æùQØyíMÁ$PÚu_K¶¢S¶ÚmÕ™©n> endobj 2504 0 obj << /D [2502 0 R /XYZ 56.6929 794.5015 null] >> endobj 2505 0 obj << /D [2502 0 R /XYZ 56.6929 748.4854 null] >> endobj 2506 0 obj << /D [2502 0 R /XYZ 56.6929 748.4854 null] >> endobj 2507 0 obj << /D [2502 0 R /XYZ 56.6929 748.4854 null] >> endobj 2508 0 obj << /D [2502 0 R /XYZ 56.6929 743.3452 null] >> endobj 2509 0 obj << /D [2502 0 R /XYZ 56.6929 728.6405 null] >> endobj 2510 0 obj << /D [2502 0 R /XYZ 56.6929 723.1655 null] >> endobj 2511 0 obj << /D [2502 0 R /XYZ 56.6929 708.4607 null] >> endobj 2512 0 obj << /D [2502 0 R /XYZ 56.6929 702.9857 null] >> endobj 2513 0 obj << /D [2502 0 R /XYZ 56.6929 688.2211 null] >> endobj 2514 0 obj << /D [2502 0 R /XYZ 56.6929 682.8059 null] >> endobj 2515 0 obj << /D [2502 0 R /XYZ 56.6929 668.0414 null] >> endobj 2516 0 obj << /D [2502 0 R /XYZ 56.6929 662.6262 null] >> endobj 2517 0 obj << /D [2502 0 R /XYZ 56.6929 599.7666 null] >> endobj 2518 0 obj << /D [2502 0 R /XYZ 56.6929 599.7666 null] >> endobj 2519 0 obj << /D [2502 0 R /XYZ 56.6929 599.7666 null] >> endobj 2520 0 obj << /D [2502 0 R /XYZ 56.6929 591.7571 null] >> endobj 2521 0 obj << /D [2502 0 R /XYZ 56.6929 565.0374 null] >> endobj 2522 0 obj << /D [2502 0 R /XYZ 56.6929 559.6222 null] >> endobj 2523 0 obj << /D [2502 0 R /XYZ 56.6929 534.1777 null] >> endobj 2524 0 obj << /D [2502 0 R /XYZ 56.6929 527.4872 null] >> endobj 2525 0 obj << /D [2502 0 R /XYZ 56.6929 502.0427 null] >> endobj 2526 0 obj << /D [2502 0 R /XYZ 56.6929 495.3523 null] >> endobj 2527 0 obj << /D [2502 0 R /XYZ 56.6929 420.5376 null] >> endobj 2528 0 obj << /D [2502 0 R /XYZ 56.6929 420.5376 null] >> endobj 2529 0 obj << /D [2502 0 R /XYZ 56.6929 420.5376 null] >> endobj 2530 0 obj << /D [2502 0 R /XYZ 56.6929 412.5281 null] >> endobj 2531 0 obj << /D [2502 0 R /XYZ 56.6929 388.4584 null] >> endobj 2532 0 obj << /D [2502 0 R /XYZ 56.6929 380.3932 null] >> endobj 2533 0 obj << /D [2502 0 R /XYZ 56.6929 365.6884 null] >> endobj 2534 0 obj << /D [2502 0 R /XYZ 56.6929 360.2134 null] >> endobj 2535 0 obj << /D [2502 0 R /XYZ 56.6929 345.4488 null] >> endobj 2536 0 obj << /D [2502 0 R /XYZ 56.6929 340.0336 null] >> endobj 2537 0 obj << /D [2502 0 R /XYZ 56.6929 325.269 null] >> endobj 2538 0 obj << /D [2502 0 R /XYZ 56.6929 319.8539 null] >> endobj 2539 0 obj << /D [2502 0 R /XYZ 56.6929 295.7842 null] >> endobj 2540 0 obj << /D [2502 0 R /XYZ 56.6929 287.7189 null] >> endobj 2541 0 obj << /D [2502 0 R /XYZ 56.6929 272.9543 null] >> endobj 2542 0 obj << /D [2502 0 R /XYZ 56.6929 267.5392 null] >> endobj 2543 0 obj << /D [2502 0 R /XYZ 56.6929 252.7746 null] >> endobj 2544 0 obj << /D [2502 0 R /XYZ 56.6929 247.3594 null] >> endobj 2545 0 obj << /D [2502 0 R /XYZ 56.6929 223.2897 null] >> endobj 2546 0 obj << /D [2502 0 R /XYZ 56.6929 215.2245 null] >> endobj 2547 0 obj << /D [2502 0 R /XYZ 56.6929 149.4956 null] >> endobj 2548 0 obj << /D [2502 0 R /XYZ 56.6929 149.4956 null] >> endobj 2549 0 obj << /D [2502 0 R /XYZ 56.6929 149.4956 null] >> endobj 2550 0 obj << /D [2502 0 R /XYZ 56.6929 144.3554 null] >> endobj 2551 0 obj << /D [2502 0 R /XYZ 56.6929 120.2857 null] >> endobj 2552 0 obj << /D [2502 0 R /XYZ 56.6929 112.2205 null] >> endobj 2553 0 obj << /D [2502 0 R /XYZ 56.6929 97.4559 null] >> endobj 2554 0 obj << /D [2502 0 R /XYZ 56.6929 92.0407 null] >> endobj 2501 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2558 0 obj << /Length 2171 /Filter /FlateDecode >> stream xÚ¥Y[sâ8~ϯàmMÕ¢ÕŲå}#déN“,djf¶»ã€+Æf°I7óë÷èb#ƒm¦v‹ër.Òùt.d€áG‚#Ìwà.â˜ðA´½Áƒ5Ì=ÜC3ªˆF6ÕíËÍ?î™(ð¨7xy³d „… ƒ—ÕWgüü”›\Ñ_"E=9ËÊ¥Ô¹Ešñ×a@8MAR™«HF™3Ï?âík¼×¡¬âoD2Š1î»Á5Ð,ªÐ*ªhî­OµÚ¹îÐlå¹öS¥á>ù†1²¬¾ÿɳÊëʰ<´ù%>Â>M¿š¿zŒ$E»"¤J!ž¸‚ˆEÕƒHEU#âº}­Oµ…ȹîDlåÉ6)µ@®.7Ò /£|ë±üM™9×ù<ý],â"×é)2S‹8Ê÷+Ý–·XT•å9D°†À§î "É"CŸü%,Šø¨ÇTÅ –„ŒŽ¼1‘ÓMâÈv²Jæ¹—ÑNL9äAJÅ•rÏ¦êÆ´¦ª1õx¦½ªO˜^ènÇ´¡|¯bé>Y¢Ý‡ùD£_åÌÇ*ÜÅY™€ÉzYÍ…e¨[êÊ01ú¯IÙ"È÷¹o…ELtXžfXÔcLh<¢‡Ãj{ÈVE!§F±Ú@±§•Ÿ²nLe¬uÉHOD=ˆ" О\×§×ÂóLqœ–æIœÆk+ʤUB%µ¥ÆI]m©G´GVÔI Ìq]AšAóÉÍNºL©|ï/ â2äbq¥´©z0©¨jPü^/ëSm¡r®»[ù# OvO?*cÜåÛöš¤u†{Ë÷•Ùþš-ÎÆ X<¯—íkI ’|ש“Û±Çí‡rä‚ ¯€cQõ€SQYàôÜšzU[àœëîÇV^×énUÊV]§C[e1Ù0…!ôÁØ™©ãG†Ãø‘kßÒ ?ÍÊýQ7Ÿó$+O\Ëéó‰í> ×-@3¸öR"Nw3ëÑFX¬Üósž¾ë[´ì}2£Ëh“ËÆ™P¸«²®v½Gª9Äŵ …MÕ}djªúȈ¾J¨WõéÈ\èn?2 åµéù½AÝüâŸ% 4®æ’nÞ ZLÆCÎé›c=tŸï·ak*õ¨|÷r›îÝäø°>åXçd#AÃ%œÆ¡æÃž’. épDàþáÌ2›ÅFÒd¾•m%5†ÄìBü!®’`q ^qA[W}³Ia¬“am$è¨v~XoF+É£äûwUJþU¶P—zN–-ò«ŠO9ßÔ<ÍÖIÇ{ÃnŒïšÌ­}X>6˜ÝÄúm 7ÝȬQ0ÂQ·Jßwb(B³HúÕƽz^ÄÐØiöJéL¾^©Á¢ ×q¡ÛºøòœUü§ùNîVäÄ™mwi,ûùÞH¯í%£ð S….Ð|'ËK£:onCW šsVnŽ `¡¡ú2§ºñ$a*Ï’¨‚‚¯Êÿ£¦*6ù!5£J«l¼ÆúûÇ!×o¬@¨òŒE‰r•}”ÆÌ{“§>Õƒ6¾Ð=d)˜ÙÐGQ¾µá³ ³DI'Øy=ê¯>ÐX%E”†ÉVeQ5–5‰!>Bè|£Ô•g®Ð]µ\øjóµ&- $éô”6"46á‡êOš¼Å,O÷Ôi…o‘üÔmž•à ç½ZâMWΖšs{ÅÐYÅÖ«vm2ÙV|fâÕ°‚ÄT¡zÓ(Zƒ¾ Ì…'QÕ+^2ì¼æ+ngóÉI® õªWËÅ( Õ]ä-ÞK7ê|r§Có+w0›ê2› êsq¦Ò éN$½ZO‰äBm{"i¨Õ‰sãWسMe¯Úƒˆ*˜òç9<¤šiœÂ­ëφ$îÜí“è]E? xL’‹¸PqîŽûd½Q©e@|8Ôòòl^’#­â÷Iÿˆ"ß à¦eÑ}Ä·Ý(ìOTÕ' ¡×³Œ_âÌw¹Š%bïÆÿÔ3O[@Ašš·|Ê¥®³K]]ŒŒá^%p’‹ÎšŽªüë¨-\êÿû*«xñ]wé–±€T‹R&q98§>Õh«}ˆÀ"FÏîù®ê¿¹.·õ_Û)­Óendstream endobj 2557 0 obj << /Type /Page /Contents 2558 0 R /Resources 2556 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2555 0 R >> endobj 2559 0 obj << /D [2557 0 R /XYZ 85.0394 794.5015 null] >> endobj 2560 0 obj << /D [2557 0 R /XYZ 85.0394 749.4437 null] >> endobj 2561 0 obj << /D [2557 0 R /XYZ 85.0394 749.4437 null] >> endobj 2562 0 obj << /D [2557 0 R /XYZ 85.0394 749.4437 null] >> endobj 2563 0 obj << /D [2557 0 R /XYZ 85.0394 746.6461 null] >> endobj 2564 0 obj << /D [2557 0 R /XYZ 85.0394 722.5763 null] >> endobj 2565 0 obj << /D [2557 0 R /XYZ 85.0394 716.7581 null] >> endobj 2566 0 obj << /D [2557 0 R /XYZ 85.0394 701.9936 null] >> endobj 2567 0 obj << /D [2557 0 R /XYZ 85.0394 698.8254 null] >> endobj 2568 0 obj << /D [2557 0 R /XYZ 85.0394 684.1207 null] >> endobj 2569 0 obj << /D [2557 0 R /XYZ 85.0394 680.8926 null] >> endobj 2570 0 obj << /D [2557 0 R /XYZ 85.0394 656.8229 null] >> endobj 2571 0 obj << /D [2557 0 R /XYZ 85.0394 651.0047 null] >> endobj 2572 0 obj << /D [2557 0 R /XYZ 85.0394 636.3 null] >> endobj 2573 0 obj << /D [2557 0 R /XYZ 85.0394 633.072 null] >> endobj 2574 0 obj << /D [2557 0 R /XYZ 85.0394 609.0023 null] >> endobj 2575 0 obj << /D [2557 0 R /XYZ 85.0394 603.184 null] >> endobj 2576 0 obj << /D [2557 0 R /XYZ 85.0394 579.1143 null] >> endobj 2577 0 obj << /D [2557 0 R /XYZ 85.0394 573.2961 null] >> endobj 2578 0 obj << /D [2557 0 R /XYZ 85.0394 558.5914 null] >> endobj 2579 0 obj << /D [2557 0 R /XYZ 85.0394 555.3634 null] >> endobj 2580 0 obj << /D [2557 0 R /XYZ 85.0394 540.5988 null] >> endobj 2581 0 obj << /D [2557 0 R /XYZ 85.0394 537.4306 null] >> endobj 2582 0 obj << /D [2557 0 R /XYZ 85.0394 510.7109 null] >> endobj 2583 0 obj << /D [2557 0 R /XYZ 85.0394 507.5427 null] >> endobj 846 0 obj << /D [2557 0 R /XYZ 85.0394 477.5928 null] >> endobj 2584 0 obj << /D [2557 0 R /XYZ 85.0394 453.2532 null] >> endobj 850 0 obj << /D [2557 0 R /XYZ 85.0394 369.7201 null] >> endobj 2585 0 obj << /D [2557 0 R /XYZ 85.0394 345.3805 null] >> endobj 2586 0 obj << /D [2557 0 R /XYZ 85.0394 310.6805 null] >> endobj 2587 0 obj << /D [2557 0 R /XYZ 85.0394 310.6805 null] >> endobj 2588 0 obj << /D [2557 0 R /XYZ 85.0394 310.6805 null] >> endobj 2589 0 obj << /D [2557 0 R /XYZ 85.0394 310.6805 null] >> endobj 2556 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F40 1265 0 R /F14 1060 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2592 0 obj << /Length 69 /Filter /FlateDecode >> stream xÚ3T0BCS3=3K#KsK=SCS…ä\.…t œ;—!T‰©±ž©‰±1ƒEV.­knj©g`fA‚!ÂVŒendstream endobj 2591 0 obj << /Type /Page /Contents 2592 0 R /Resources 2590 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2555 0 R >> endobj 2593 0 obj << /D [2591 0 R /XYZ 56.6929 794.5015 null] >> endobj 2590 0 obj << /ProcSet [ /PDF ] >> endobj 2596 0 obj << /Length 2160 /Filter /FlateDecode >> stream xÚËrã6ìî¯ð¡3UfÖ )Q¯ÞÒnÛI§³³MÒÓÙÈ’«‡Sÿ}’eGI:µAA<)—þr™F¾3µL2åGBFË|·Ë ÌýºL£¢ÐTÂ`fv…©¥A²\M™üø°¸þ%Ë@øqDˇõ¸Wœ¤~œÅáò¡øâÝì÷¦*ì?W« ÞÇ«o¿Ñ:å'i"q€=b_°Wüxûé#Qg¼èÓ=¿ÛÇF7GÜ÷û}Ýt#C©üPÅ3ŒC?˲È1üèË«•Bü?ÖÁ2ó³8ˆ™s¡¨©ãü°µ-°ÎBï`šÖÖ ê5}i;„2ú| eþAÞ-‚„´ó°UgšJ—4*DÖðd[Ó·Ûên€Ì‘ \óÆ¿Êë[S0æ8ÛæJ¦^±Úë¦c¤ÞïK›ëoñ°x<)ý,Šw¼]íÖÓ@DžÑ­-QCBy_E$žŸë²$,H´#Üé tNÄ•öJzã™c+úvNÈ¡¨ó~gªøKPYäÝ2‘. Û9»­jÆ{ïô_ ­ÃÁ¥®HðRw¨DÞ|¾=ã “p¢À7ïbRu%ÛEßÚjó`8+tL‚'w†Ã½cPla.­ë²¬ŸîzÚ­ý¥\üü0:ààV*Mü(вY'ˆVS*ç£RMì70 '¼P_…L.7•BÁ"•¼½ëHõrÛ3·‘`Ÿoûà”‘e^ež†ÌI |m€@ó!'ÅÙÒ¢mEÁxW}iÀNT”°/"zøjúlífk‚Ks0%`G!4¹¯EÅ,Ñ5×:g‰ÁúfL©Ò;œ¥ÇWY—=Z,ZLyh<%БÂÀë]µ:gÆ™gÛm ÒôAµy_ê†Æ­i Ø\%Êc¾º*ˆWq lNdý¾-‚nBpŽ;³Ñäþhr¯Š&áKÑ•ÀE“-Æ–Fº8è*§ÆËBÄÔŒ‡ù–‰&À“ßÿüẴ…¦³;šª ¢\ç[¤“ŒnöLhÉá ¯Ÿ<è$Žk§DÄ«|K×ZÕ=O“Ƙ¾ ¸×¼0„d)ßsÂÑ>ÈDï»à<ðbÏyœìéü/ ô?гnïîÉÁÂümµ®›ÝpK€¼3„¸æ)ÞÛÎì0`Ó¸äL*¥ôà£Dz·Mûb4óœø1º»ºiÔ -xÌj΄);8©ÒìdÆ$¯«5Í|"@« 36Dž2ŽÈ°MÖ(—OÚ½É-.͉øáhÓ7ƒf.X¯1!’?‰ÔÑk¤ë^1î½ÎŸô†­ï¡5—I´˜7vϱ#â=ÏIª–NlH>ç"¥ÙW,=̤¯À-ß6õ)Õë¶>R½kìoîz²öÛΚûÙ¶7νSP¢;@ «+õÀø ˜1†ÙXŽY fín_,S\–DÛ%q„%ÖP­ð}·+Î @·ƒŠ‹“~ê­ûÊÅý–7ؘN«9[( NˆF@n$ ǰ$Åe¸Á”¦ÊÓcõ–œù^Y! 0i²o™Š4\)L¯ôó“!`»#Àøäe.ÁºG0ÛY÷„&à:ðàtRõ¥Cq¸‘‚ƒÒè"· éšÖ’ƒ‚J9„2úLÊ1r2’œŒP‚1ÏD"à€è¹›foÏ3Ü#Ž&©òâœä|„Ä7SÀÌ üuw×þzQ{"ÖUÜ[Sш£¡œÚK%À°Æòö}5kVcL3ÅÛ ˆ|Mâ;`BõF ¨Þoí: —Û΂é¶7¨Ä8ÂÊÝ4ýØe À¬ð¤çºyÂaLiÐ\\Ð`°Pdp€µNM Wn5oÂF Pö}KÀ©Ï;c«tû4gu­K±þ©ÕæÖÐŽ‚"Dƒ""ÒdèxÇž÷scówo[Û™W:ÚÈ2. ~ýô'È„ªžÐÄ‚€¬(*CàD@AX§#ø>öÖ93, ãÜÐ!Nl äµt#r¨ˆ%Ù~Z®9îØšŽzáçT°ù‡akF’k³U;*ïêiÏz¿¸ú9Ì ˆh,·>ÌÜš)d™SäuÚéêÞkbù«g”-•ðÓ8R¼òäPª+Á•ÔC3cer宯œÂÀã; R8Jæ‹g‡`ù©Jä¹]ÓÕ(ª[”Œèu@̨—Zñ{§ ¢›¼ßýôN 㞬ˆÚÉ«ÎË"Ä“á„.ñ•¡GÞ«ãDw;pš¹Ë‰þ['%÷Óçwü²¡ù­dïp¶£ûÃäß‹/ßIJ¢ß³4Z>ÃÜ*Ë‚ånqzè&L¹¸_ü1×¾'~˜¦Á|IBé—*¡ðäR%`ìQÓ÷D_‚«ÏêòTãƒúËcý Q@endstream endobj 2595 0 obj << /Type /Page /Contents 2596 0 R /Resources 2594 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2555 0 R >> endobj 2597 0 obj << /D [2595 0 R /XYZ 85.0394 794.5015 null] >> endobj 854 0 obj << /D [2595 0 R /XYZ 85.0394 769.5949 null] >> endobj 2598 0 obj << /D [2595 0 R /XYZ 85.0394 576.2232 null] >> endobj 858 0 obj << /D [2595 0 R /XYZ 85.0394 576.2232 null] >> endobj 2599 0 obj << /D [2595 0 R /XYZ 85.0394 543.993 null] >> endobj 862 0 obj << /D [2595 0 R /XYZ 85.0394 294.9358 null] >> endobj 2600 0 obj << /D [2595 0 R /XYZ 85.0394 267.3765 null] >> endobj 866 0 obj << /D [2595 0 R /XYZ 85.0394 200.5197 null] >> endobj 2601 0 obj << /D [2595 0 R /XYZ 85.0394 170.3103 null] >> endobj 2594 0 obj << /Font << /F21 1034 0 R /F22 1037 0 R /F14 1060 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2604 0 obj << /Length 2579 /Filter /FlateDecode >> stream xÚ¥YK“Û¸¾Ï¯Ð!N•‰Áƒ/ìÍ^Û©ÙlœÉŒ’Ú”×J„$f)RKR#ëß§ R¤Di’M¹Êl 4úõu#fþ‰Y±HK=‹uÀB.ÂÙr{Çgk˜ûóp<~Çä¹>Ìï>«d¦™Žd4›¯{%Œ'‰˜Í³¯ÞG&Ø=ìÀ½_>Þû2䞦ÏÇ//Düüøáùý󽊽ÑÀË?žžþfæ÷~$ÂØ{ÿôôéËÇÇ_ÜJÜ’ÿá-¿Íºû4ïõÚ@p…Êý~÷õŸe`ŠŸî8S: gøÁ™ÐZζwA¨X(Õw/wï7ÌÚ¥“6œIÉ £J1‚é0”#«†šEJªÞªêÞŒðX6mZi›W%ªöð9¯ð™¯4 EÛ•ƒÂ¢eFß"_<˜ï»ªnq)2÷¢OÌÛô7CTN²HŒ<#XËÄ®œoò /#ï¿¥ºÅö®ÓúH?ªÅ¿Í²%úWÎeaìâÐÛ—™©i¼Ý"²¼¾‰ ªn}³3ËšŒdzE¿Â‡¼Ýø¤¬âq;·¬J\»ÞÓ¾îH;Ê"ÖȾŒc8gÈ3³J÷Eûý¯¢Ðûôôüéóã/hÓE^fXÄ;àN/-3Z¶1)©d·èT…ªqâN cçªÂÐXUX¸ ·(¹PuJ¼\ûÌX<¸4V;Ò6àá™¶09eÝN'…!5ãXyÏUÕÒ6»:Í ³v»b\à·¬ê-DÑö'¹¿ïŸš°4 \è‰AèL'’ÍòP¬bÆ_UH)jáVØ]튴¥/™‰jGĹ#`ÈÅ5NVgËštkH° -è¡Y,bÊÁù½–,x!bSˆhÝÌbŸ‘Ç c©êP‘îvE¾¤¤§Uk“=ù0¹´ò.AB& e:“œPátÙAŒ>üìº7R8ùý‚QXíª¦u2Y^NX>Q,JôH ë9À;¿ãñeDœ/p€÷—ÒZÁâ½YOš‡gÓ´u¾D=›kðÇ\·KÜË¢±çâT4ØËñ¹Ðö‰¼-´cº:6š`¡ÖáXèûšB²l!‡„:8B¼-•DRÙTÃo‰©ˆD³ß¡S-tÀÏUUA‘ „+–î÷†¤V¶(ðÅæ-²]ýfMŸQTâÀ2uÄÂIÀ¨ž¬5iC.]<jFhrÍ›ó}̵÷¸¢)À"$ï–Ž ¿ûÆ\ƒí‘N2‰:duÂtØpÖgØšM`¾Kt9$)q³ ¼QŠ%Jw°vØ€‘À) ß Þâl^®i‚R†ûTH†Í ü0¯¦$¬²Õ¾-¤æ;ìq«xêC…±\cÞ¹ø'ØweëXÌ.­ÓÖÇ®´x¶÷Òî=@U_åPÓ]óæû¦Lá«Îç×µõÎ|­@TMôªH×Í;¢{Ç`ãk´™ óí­Æq""Þß@Ç['üßûà+x¤bèùCè~oâÑë:õ\oáÑM¡=]Ä£‘P£ ô–Enlš·­²}áÆm?‹ÁÌ>>¿ÐHŸ,8:Â"šÇv ¿„YÀãâŸFá÷òéGšxM‹€vSi¹ÜTuCüd#ÒvM8O?›cÓš­È37~º·u=®ßäË ÍOlµMËtíÊÓ,Ó­Y{6-dâ¥Ù6/sè¬ÓöT“qWWGÕ]°uç zÜ ¼ƒÝ+€¦sÀš…ŒÄtb]YÌK÷. ‡ídC¼Öj¥Û©ã¢](§¼¢ìñ¯f”m&ußΰ!×õ ë¹Þʰ›Bû »:™a#¡_lxJé¹Ç “ívòq0Ÿ'aàú£Ó.j›= +óDC¥c–„Q·€^'íô|2¾iÀœÍ`øºpQT-päü–©1'&¸"—ÅÑíýšæ……PêªbÎt ’³¶ª?âm;¼†Xl(Gðª?DtìJ3³Ø¯Oevš+³ªm˜¾°Â¸æQtya Ý…uÞ!~V6dXûës^˜é—4³0Rƒ«Lbg²q7w†nhÊf.ŒâaÓì`eØs_¢EÒ=B¥HÉo0iëש¹Ý+£–˜.’0z.ad°‘ݨ’xuQ„|vAÊ’ô=V¶ÓP®nâà2Ý¥‹¼ÈÛ#ýF„§&Ÿ6‚„…¼¿)ÜïH3èº÷ 2 ¾5‡Ê{éÞ–öÕÊݸU(,¾£üÜi„=´î 83ŒÏbÕ^™„övÖäÕ«Et%ù©ÿzì¸p ®8O +>‰Û½×Ѳžeo7n¨¢J‘éý…îYófúú1TÍ¢Hé—6Žcó$ê߀üÀæ¼MÓ„÷]¦LÈ¢8©{$ Š·©ó-´“ö x(S“®¯b"Ì”NXò(Zù0†Å©skÈoÝ1GÁ»Mík+X ZƵ“g¡ÆVûöô„ ¿à [”N®¼Ø@ö8˜s*\Þu%À ¡´ÅÚÚ¸ÛüfŽÍÔã¦fRòî9´i!z¶¶…Ç#uEÔ€òlú¥îaS5îàÎVî¡/bA˳÷ãfâÉÓ!çõ©²§*ÃãaG\ÕSÌS<Ýõ¯hÇar .%¸½¼˜‹«Ü#˜VÑLàWrÛÄÒ\½žñ<(É»?ä¿,É»âA^̲ík”j&Åùi2è·¿è z®7NðÚ‘@ŒA8…È´PPf_‡¦jš m…x…\Q{±ôÝûaŸöfE{©0 ·¡a÷@zôtˆ×€n t÷?ÞcPïŸÝ]î #®f4buG‚ØVîN!(rUš8‹¢:ô¢HÀ6.êܬ¦ [fšeïN~î‚2¡é’c`¨ë÷½á'ÜÏ{ýߣ<µµAÌT’Èé8:;ê9ø£+ ؇ùPÆÒAr¡T÷wÎK­þ³Âøendstream endobj 2603 0 obj << /Type /Page /Contents 2604 0 R /Resources 2602 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2555 0 R /Annots [ 2609 0 R ] >> endobj 2609 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [344.9397 142.7828 406.1397 154.1749] /Subtype /Link /A << /S /GoTo /D (trusted-keys) >> >> endobj 2605 0 obj << /D [2603 0 R /XYZ 56.6929 794.5015 null] >> endobj 870 0 obj << /D [2603 0 R /XYZ 56.6929 769.5949 null] >> endobj 2606 0 obj << /D [2603 0 R /XYZ 56.6929 751.5714 null] >> endobj 874 0 obj << /D [2603 0 R /XYZ 56.6929 588.0121 null] >> endobj 2607 0 obj << /D [2603 0 R /XYZ 56.6929 559.805 null] >> endobj 878 0 obj << /D [2603 0 R /XYZ 56.6929 252.161 null] >> endobj 2608 0 obj << /D [2603 0 R /XYZ 56.6929 225.1993 null] >> endobj 882 0 obj << /D [2603 0 R /XYZ 56.6929 124.408 null] >> endobj 2610 0 obj << /D [2603 0 R /XYZ 56.6929 93.9095 null] >> endobj 2602 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F42 1338 0 R /F22 1037 0 R /F14 1060 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2613 0 obj << /Length 2171 /Filter /FlateDecode >> stream xÚ­Y_sÛ6÷§Ðôåä™Å~K&î››Ôç¸Óvœ<0mq"‘ª@Yö}ú[pA˜H©wödAÀbw±Øýí.Ä&þ±I¦FNR#‰¢LMf«3:y€µž1O“tDIŸêýíÙO?‹lbˆÑ\Onï{¼2B³ŒMnçwÓw××—Ÿ>\ýqžpE§Èy¢(¾¿úôgŒ_øôÿºzóîæ\¤Ó?qâóo×׿¶·ç‰f*&̱Ñÿ7›¯·¿œ]Þ†óõmÀ¨p‡ûëìî+ÌÁ¿œQ"L¦&;øB 3†OVgR ¢¤ÝÌòìóÙ¿ÃÞj»uȦJdDe<0*gCFU†hÁEkTgMØyÂ(Óæ«õ²¸8O£ÓkK7çÇÍöŽ6…­—Å¿m›rY6ÏÎ ”÷„Ò É Š»j`ƒS[Ts‹C'FÊé_ÛbóŒ3õ}oELÊÇ¢B¢*_8ù…*:FÖMYWùwÝÜàló¼.`óßêh·]³ò ¥¼˜ã®Í9˦Ål»±À·Óz㎜ÊéH“Wžx½)«Æºó»3FŒR¼=q³p›ÁYŸÝ. „žæçsüº,mƒí±`ææÆ‚s ªÑj03Ë+¿gikÏeæwí±{Ì—åŸ{û[T{QÛ¦õjwò„IJ(<¶À¯xPܬ÷®eô°]àyHŒÜ~-@R!†ÑØ%}ªqàTN©¤A5nn\Xí‹g<#2Õü¸ü@5 @ß–L"Uªb Úˆ½F50ÌZ}ü„Ó ë~¡†16%èV·Ýʼ¸Ï1@áKi÷ö½ë$Qk3A„>aë@sÄÒHãNy—xΗõ¦l+ïðwIáGÉwüü^<{€t“äm6öC#5$©8¦t 9Ð:rõL’Œeº¯v¸fÎÑÌ>øŒ{·Ð&Y7-qàPÙÑzüòtí´œ*»C&>bR‚Ìü\ûÄT<µˆñ£¿ÉÚcÅ çÜ×Ëe½CÄÄàã埱 yvNrÉNö aÑ’µ%œy7ííwÓeü‡£«OøÙÉrc®RO† ?žžžÒk²'’‰Œ:‚Û?´: ” iªè$'Lgþ@uœÏ¹ÏÞéüÂGüüþaHãQ¶\›éªÈ[ S§wÞàd³hCF­›¸Ån"ÇÿÔUñ¿ï çé`Á–Þ(îv‹ž ˆ¼c[Õ»Ê3ìq±.û·hk—U³ñ|×5ä{Gãê ‡":›þ¾h“"l†¨:<©WeÓÅ76·‹œá—]¹\â蛿³­í¿=G5 A’IÀTÁŽƒPŸj†U{E^ýy½ÊËê"˜Ü} ±è2]Ÿû«’màxBa&SÀ)¡b‡K–B½KSö†ZvOi hJ2±–®$påÀ><–%Íñ T¢#ˆ†zÂ-ö pB`(IWG­óM ¼nr¿†)oÕ–8.g`ñKEãQGÒ—ºz† .hЅܨ-pÓéåSâᜂž:§Îû]Iç†}(攲‹ù·ìâ‚q!Ç"C¤œ*Óã‘ѧŒ@uÄÏ\2dî3|›y†'TdLÃ*ËbG¼Œz1M³ãÆ T¢£:MA H˜ŠEWxcW×såOÚwaŠÄÕÚ¾ ¾ÔúQNß-ÊÙ⥾+‹.Ño7VãÈ) !Q3öpü£GuÄ?:*g€~É=ä˜àŽh@p\"KÂÜ“Œˆ‡ã—ñ¾+“öJcÌÚýs%Ò@?¢œ„CûÓ{;àÑÛA’Ûçjö?½ (5õõÙ®Þ|õWËh±©«zk—ãiás¹*—¹;Wè\cos#'F@*Ý6H•Ïfź±HšãœïÃaÔz¢ã^ÛÚÅ{-,s²3§õüºO\éA)L: \ú16qÚ§÷Ñ@¿›\<5P=³õ¹¾Î?;Ž'e Zq‘êXÓÁw=á^?yvÜ>j@n\´¤îi”År_õ®þöÖzL¸P3'ú†>ÕWè¨Ú¡TÀuX¡#±¯ì<Ç:ºþBAò•|I1–¦ÄÐL7N û'Yf²XrÞýJ`›øÂ÷‹Ywߢơ­­æÞ'мë^~{˜A{íG(]«‡åH íy^>ùöôð Ð]ŒŽ_çv»é?› ”x«§@QÍEeÉÓS ûR@}<üöžÛ«£|ùQW¦Dd©4¨$BÖ)åNÁ¤îªÞÿ–€ÙDr}Ðȇ:õ_ÙÎ.ïendstream endobj 2612 0 obj << /Type /Page /Contents 2613 0 R /Resources 2611 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2555 0 R >> endobj 2614 0 obj << /D [2612 0 R /XYZ 85.0394 794.5015 null] >> endobj 886 0 obj << /D [2612 0 R /XYZ 85.0394 769.5949 null] >> endobj 2615 0 obj << /D [2612 0 R /XYZ 85.0394 749.8211 null] >> endobj 890 0 obj << /D [2612 0 R /XYZ 85.0394 323.3339 null] >> endobj 2616 0 obj << /D [2612 0 R /XYZ 85.0394 298.074 null] >> endobj 2611 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2619 0 obj << /Length 2680 /Filter /FlateDecode >> stream xÚ­]sÛ8î=¿Âoë̬Y‘Ôµoé6·“»n®Igî¦íƒbÓ±®¶äšrrÞ_AÊÔ‡íÎöÚiEâ‹i>‰à/Ÿ$)Ks‘O²^½ù›T“œå©H'Ë€—b‘R|ò¸ø4}Ç8»ÑôíÝûw×3‘DÓœïÞ?Ðàïwo?Ü|¸–Ùôßxøxÿ‡<^ÏRždÓ›ûûÛ÷ïîþå¾D–Ñ_fùåñ÷«ÛÇv}¡x$qqß®>}‰& PÅïW“¹J&¯ð1žçb²¹ŠÉ’XJY_=\ý³e`í§£:å2#J|L©IÎR)d«Ô”Éë@ ¦Øl×z¶ÓßöÚ4¿\Ï$¦-Û”ˆë)§Ù•)æMYW˜¯K]5¨˜]³GÀ3%2æ]ƒô|jtµ084ŸÂÔ» ›ºƒ1[=/?G‘Ð ‚½{Ñ»ë,žþLEå0Û]Y5ÆqYi쮹šj³­+£‰ìµlV„Û”U¹)Öô²µ”õ\SVÏ Õ´/jmªŸÜ ,݉hp͸JÎYž$®búYˆØ4û'zsbÔk1 f‘§Ó²!´iê­¡!I.DO ‚ÕÕÜaý—ÏÚ.YHÐá3—_2@–ÄjÓ›¡«J‘M_W;âW^ƒòÌCÖK½ÛÚ:k' ×ø­÷AÏ ªuY}Ž’è×÷7ÿ¸¥W¢äàU'p³*½Öûõ‚hhÖoû’„_îwNVxAÿ)µ!rëAÕx¦š0ûuo´Ò¼ÒòÑÚ‘œÞ9©kËxÄ´¯µ•`a~v‘°* öM¹.›½€ƒ8páŸôxq^îËû5N¶\)–f‘pÞEù<]\Ún<{vJÕIž3•¤ê¼ªCªÓªn©ìBG]\%OÓ¤3íy¶gxAD•aš‰»"¢_£O÷Ý@¦xŸ×MK52sÇ DƲ<ÉzS»½ýî÷Küæ%uY£¥og ô|¿3å‹î¤¢«éùº*ç«?:tÝ †æ´ƒ¤ Ò(¹à ÕñT¨‚0‰ô£Lzaæ–jdê~æqÖ›»ÕÆ¢Þ¥³…ÆŽ–õnTkÃdç0Áý$»q*ãnø\”n‹€-\VËØÝgI @a†M»ŸÌë…¾\>ÚTÊdJÏ·J|#D¸:èyWlª&Ä|¥ç_ H UËQ$Ë…vDVh èȸ'½*^ÊÚWIšÙÚ§iН:”-±ŽA² ORÖ„Á®µTøÓy±^Ã71ãú޹t¥*’X;#èâ©"‰@ñµ«El—ÿÐZ'ø»¸ÆJ©z+ñîîa¡Xüs€UO[k7û]…Å:=3²Bf[³éÝ’(­8XT†ÍëjIb…´výßÒ4n*2*’k$©HÛ5 ºÙ]«éÞZ Õ|Uû:WfÙq²}53×BïÖ[tË,éÔîy-×kÙ^ÀŒ{Òã*ßEÑŒó AâÈûf:0xg«£7£– %H§Ë¢\{ZÓ 1ê„·7wýT–Å,Vé$N#öÍ~x³süf!ÃaÊË2gq~œÖúÕû‡Û_?~¸}wƒúyÄÿ\q݆Í;¿gèªíHáWZ;…ûžÕbÚš˜eJ\,‰!«Ç^:ÆiÒM¤û-¢O7Ò‹0/ç®q°Ä>ÚŽ·;Êxß×T§1xâ\omß‘R»0lí¬0n'‚ñ¼Þl(—#­q :¸Ùº¬u/y ȾƒGlElBþÝæÈ ozü=ⓘA÷ DkÙ€1_¨Ó¨Ê$;æt³ª_]æmtû_„ûßá‘­MùÊ6€ˆ ÐÖO&ʵ|ˆémX:ºÞj+ãô5´o,X”Ñmë<ð’‡îô©¦ǵr˜@ ÇÐŒÐ!%H³HJî¦üψP‚eiûvT¯u£›>h„è@˜ë¾Ò”©(ú?v_Bå,M÷|ÅR®øZ*Û}¹hE4 <v&ÿ±ÆÀ1¼ hÎAié:Þ»pµWçõã‰F¦ív1J-»óÞ`°çÜ"ï7€°<ØÆli ã^@#¨íòöÈ «Ât¿8U»¹?ÕÈŸuå8A©Ð@L'dŽÄG 44ªvÞK¥¢j‹\ù*€O챓ÌòiUï6PDó¤ JÙCa†.7v*í'-uìwpLk´„>M#Øï#é$Ån:Q1Õ¢1¬³­Œ¡¤Y›š@V.x„04² ¹â£¢qì„€‘]-)&¬ç=qáègPû+åþ‘·Ú‹y˜âMø™h-Ы½ Í¼§‚\HÆ3*!Îy@u&È=• ò¯$ÃW}pÕeOhƒÅóóx¢ ºÝ=IÑáÆ‘<Üý†'9ÊB ¶ÞåÔ$#Ò`íN>-|å­=€(8”Ÿ‰UN'0Hv\¨}]¢[7ô•u„¥¡†PE‹²Äô¡«§ ¯¥2Ù¿m—j½ÀŒrÎOÛš+¨ÐD$ÎÛ:¤:më–ÊÚzë«)÷¥)›a;–ÉE$ÏKÑRˆÑÍ›ŠåQ¸&gp‘䮕Õíy¶j¢¶¡wé!G%ævë®+ÌDˆ¡Üw–ÝœŽor›\£¸æKJåéÒhœ¥ÑŒÉHð®­½ é™ö”¢hQ}bÊ‚ÚíúOýÓÆ¿âBöY]H!ÕòTÖ…\Û±kO³ÇA ÚÅ;"üPeÐr¼ /(„ÅiÚøDm sÆc¡Î+ª¥™¹{õÕˆywf[$®:肎 Û»½Á!aPØ#¢ñ·y¥»/ îY¸k‚q´7ÚÝØÝ|ëMq ÷N¡JqÚuï'ï†/ßÚMËZ– ¨N‡Gäý2§wä983=wºÿà¦æ»NEshy&χC@t:<‘ †?ij¬¿FF9dÉ,ËÏNß çïø´ yÑ ðxþ\tpí ÅNr%£9y¹“0).]í´4g.vˆÅ>Ý{‰B]Š^ëÅ¿£õ¨>b9TçÄoiòw ÇŒ,àaôVhx:n½Õ»Â$X?Ü–îÂÖµŒ Û%q€p‹lq›½w}™ÁvÆNýC& D1¢øç¢ý‡«qüq n”J¨ z2¡FƒŸ00‹œÝãy|"21åI4ôM÷{áªþô°ÂØendstream endobj 2618 0 obj << /Type /Page /Contents 2619 0 R /Resources 2617 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2624 0 R >> endobj 2620 0 obj << /D [2618 0 R /XYZ 56.6929 794.5015 null] >> endobj 894 0 obj << /D [2618 0 R /XYZ 56.6929 769.5949 null] >> endobj 2621 0 obj << /D [2618 0 R /XYZ 56.6929 749.768 null] >> endobj 898 0 obj << /D [2618 0 R /XYZ 56.6929 549.9391 null] >> endobj 2622 0 obj << /D [2618 0 R /XYZ 56.6929 524.2635 null] >> endobj 902 0 obj << /D [2618 0 R /XYZ 56.6929 422.5891 null] >> endobj 2623 0 obj << /D [2618 0 R /XYZ 56.6929 396.9135 null] >> endobj 2617 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F14 1060 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2627 0 obj << /Length 2461 /Filter /FlateDecode >> stream xÚå]sÛ8î=¿Â³sòlÅòS"»Oéµ{“½6—fgv§Íƒb)±¦²åZv>ö×@ŠäØIïr7÷pÍL ƒ €PbÂáOL¬a\9=Éf† 3™-Žøäæþv$M‰Ò!ÕÛó£×?+;qÌe2›œ_ xYÆ­“óòsr|zúþû“ß§©4_ðI ¦øåˆ3嬙ÜÂ΄sr²8ÒF1£•Š˜æèÓÑ?z†ƒY¿tŸMµ±ÌHMRc˜2™ÛoyθK¦¹rLh –—bŸå#Zþ‹”z»*‹ME¨@Ü®úB[¦¹È&Ã=IÒSíED »²Òeù´ªfõÕý4U2K6óŠ”( Z/à É]â1+›¢ûU=+úQÝ‹UÈÛ«ƒœoÛmS"˜'MÛNEò5ü¨¿Z´É²XTh8Å´‚ÓH…`ÎéÅ??ÿ•lxvB{ž½;žæÜ þ;F&ìcelb„û.Ï’9gô~ÏâàŠe<Ëó¢ux0®³zˆêŒ;–ƒÏ´×þjâ8Ëø`Î($?ZäêŽÞdZø£çÌ( ’{Š­>feò~×2ÀS -S†9›û™|›ƵsŠˆ°×õÁñúd!'ïZÐh2P*2N‡œ½RÙ0`„ÌÏ5`4³6W^ä“%x·Éj=<)f›zVM…I^ZäIUƒ­‰$-hlýo—¤¿À•ÛnCXï΀íÐý¿p.½Kƒ%‘UG³³b9&oW›º]ÍOè :x5à·Ë²Z§ÞOùØA›ûzy n™)pìKßK”Ü#V'ëv»©—‘l` Ôª«.ün‰¨.«åƇ©ÇÎy±Z­ÛUXCéˆ;2Er3•&AØ“.ËÑbü‰lãÎ>Î#·’ŽYaÝXn¬Œ›ê‚0©5ËsgÆÉí£/‰»GVè¥Æfìñd=¤:ÜD÷T¸oZ>j]4\ú™-#Ñž-‡æpŽiiv¶\O±ÒßI}1cŸYV—ÛkßÉ{Ô¢-+Fîz J\PÇTé-Gð£(¸­ãQn+‚*Èb÷;G½¡1dª nƒŽ< ‘±œƒ¢OÆ€ê‰ÃˆTþ0n†bÖeÏl‰öl9: ËÀÛv¶„ÜI:]0Xç²íêÍýø&j©7ôVn׋"˜µiÃMº€ „tÔ…“:ïÏgëÄx&ƒf1,Ý6›Úgd²5°:dza5ƒÜ Ÿ6ýê°é{*oú§ò €HÍ33ÞþEù¤çøŒ¬ÐU°ÜìÈŠi;]) TB=m£H´gßÑ+W¦ WÔj¼q׿r G½’„Â÷4üöF8AVÜ 0Bk»î¨uƒ™/Üp48”c ¢ ‡ì ¦\'øN«Gáp»v´ŠòÁ`•ϵ:amÕø®¥ ^&×±.׺LðqÇ3hÏvÊ !2›DµN¸Î—å—ã~âµ=Aü£*à ù†Jã*N÷Kƒî…bË×<DSµï!¡¬® ˆ·E³ !CÏ¿ÁŸ8˜ÊÂñì™T6¤z"ž"å•=÷²ð/h*mû²8ŠŸ‘Qðg¸QÆBÒ½ü8Ú‘Äê§ÓSíÙyIÐ^Yëìxç‚Ä‚Žg9¨]nÀ¿è5fqSÇg7ï‘0>ø!žh„@ ;½Ë÷p.éÃÈ?×Y›ÜΫðF×.ê¯@ýºy©ÛË4Ô/p ZÙqL•…çèz߃ñÎBúÏ0f!¼pc%mòÞâz¾3Y¸r²XŒøE‹IcIG“ ØÞ5ai4±ŠmܵK±ÜÀF1Ýg¡{¤7p[ø—Tiäeµ¦»P÷5‰ìÚ? váßMwYÅ!ŠUuG¨r2ƒJº6bÂמ®…Ǿ]Òc¿_Nw󞥟·^'È9Båx4LxƒÀˆs···S'“aht1ÿÌ+w .\DZ¦MxxoíO¦Ia¼&Ž÷ùqÔ½©¨+ߣLïù’Ž_°u’1àºjYvô!$|\é§B.†™oÛjí߈‡_h`ﮢù‡†𔬑u»óÞD c¾û`¯G&ÅY ¿=Þä_¹wÊ^<ПvÊ£YÑ4ôñ*ôƒeÙ?\„ãy¨’ée:Ì\mV3þõ{w³PÉŒ¿ê(ÃðßžäÇûÏ'/þ”øð„¬s¦¬=E×L)'¢PhG‰N™ËáwR7‚JO}4Ê2ce¾G­púW“endstream endobj 2626 0 obj << /Type /Page /Contents 2627 0 R /Resources 2625 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2624 0 R >> endobj 2628 0 obj << /D [2626 0 R /XYZ 85.0394 794.5015 null] >> endobj 906 0 obj << /D [2626 0 R /XYZ 85.0394 392.8463 null] >> endobj 2629 0 obj << /D [2626 0 R /XYZ 85.0394 364.3909 null] >> endobj 2625 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F61 1466 0 R /F42 1338 0 R >> /XObject << /Im2 1455 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2632 0 obj << /Length 505 /Filter /FlateDecode >> stream xÚ¥SMoœ0½ó+|4RpýwµIµQ´¥»Tj•äà€wƒÄW4é¿Á†f{i…„=ã™7~Ï3`ýÀ*@(|Ä1á - Núì³ClŒ7y˨uâ|ºbH4Éq!E$Ù-Ü ‚\€áz»Û¸å ³lv³¹Ù®÷«½ËBøÃ8ßâøËèH\/ <„«8¾Üm¶ßmæ‰ÿò>¹v.“™ßR‚Ù@î§s{A¦¥¸v0b"âàY!((Ÿ3Ä}Æ&Oᜯ3àâtL=«)Áˆ²€ž•@œÓwªrFÙ¬jèzknò‡V¶¿ ͽ:ªVU©ê–‹.úHøÄAVÎaÖG³öùè‰às›÷yuºÐ–O´_µ.‰ 2a¹M«j³ë¶”…I¼£Ô/eõ$‹a÷'¼(Æ çª³øê%UMo¦;˜ÕéS©ªÞ=*™ékŒGwÓBu“ÁqW—jà;0œ¥Ó ÇÒZ]º4»fdRÿÊ3µt¨¾·fª—y¡2c©—¦•ìóºêt!raܲ²ç,›Â"ɦ)òtŒ}WëÔʲCk:ÆÑÐ)gZÏ]ðß ù6Á~ˆXÑ·^£gØÞiPp1az6óbýª„ÓBýÿ@jjê¬^á ;endstream endobj 2631 0 obj << /Type /Page /Contents 2632 0 R /Resources 2630 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2624 0 R >> endobj 2633 0 obj << /D [2631 0 R /XYZ 56.6929 794.5015 null] >> endobj 910 0 obj << /D [2631 0 R /XYZ 56.6929 769.5949 null] >> endobj 2634 0 obj << /D [2631 0 R /XYZ 56.6929 749.4437 null] >> endobj 2630 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2637 0 obj << /Length 2090 /Filter /FlateDecode >> stream xÚµ]oÛ8ò=¿ÂÀ݃¬X~ˆµOÛm³×,Ðt÷šÃ=¤yPlÚ*Kª$'5÷ßwÈ!eÉ‘×8,brf8œïŠ-(ü±…–„Š,Y¤YB$er±Ü]ÑÅpÿ¸bž&‘‚ÈDØÌ`c)4‘š§‹xÌäçû«7¿p¶à”(Ååâ~=Ü¥Ò”Ðlq¿zˆÞ6©VÅ÷ë˜KÝ\?ÞÿЧ’ê”ÙSnH‰R¹ójŸ—HßäÓ gXBD¢¸?£$QTjw憰ë˜QJ£U±±ô–@¤D(…bÜå;ãùðEF2Å•g#d¶Tö°»÷ ç)®Þß}ÆEY×_÷ ®÷}Qýá(#™”A°„®*óùPÕMW8®nî›*J˜‹&L&31gwrr™œqЦ´göº# ç“d¬apÉ@5è©ÀZ?u¦}6í£ßÆO¨ÜzdÁhJd¦$Ükç«Uk:ï•É] ¸NótÏå O!‰V2°\–ù,Cž­Óì”áú"ÃuQšjpùTÈ”hNÓSž_ÿÀm2²cxÝ,ôAC ~¡’®ê]^TÐÕºnwy_Ô ²hÓ^3Õi”y¢q9n¿P*Ì÷â©4îëºD ð l{Ó"§ 0¯6H‰m ð.½+yG®cAÓè¶G(\oåêÚs¡t™D6¶8  D¬V°à¶£vM™<¸ßçU÷×hÞûcNVOƒë~ßVf…è5ª²;a†ZXjaÛ¡Ù,úÈ® üag 0+PYÂîcÝõ¡÷Õr¶ŠAÙUqÍ¢®oó¾vÂxß™™`ÀBeCó90  H_#Õ܃_»m][Ñ=ŠÑ °»QOf™[)º^ãoÑ{lˆœ9@®è@h°B~zÆ3¡Î{èhA ‡©)˜„…†ÛZfnš±‡Ýï¾oö½F£Oà›öõäc#´óKc#ø»ÍŸ?b·Z﫥͉¼îoV3¶šH™þ¹Á’%"´Aâë´HˆÎ2 :f$MSÌø·e¿­÷›íÌU ô-Ä%×r¨”žÆ&®<ªlŽ—åÁW)ú-–õnÖË¢2ˆÃ”Øìw¦ê;ë:ÉÁ¹H—]TÛ¼ó Ü?åýÒ³ÜÕ+ÏÊùÙþBZc©qP ”PšLÃ~(!˜1ù ‹G2r(ÔDB"u½¯Çµ»c¥â¥qµEEoö¹·Æe·¥ÛnjtlÄq›Äƒ\4ÙãU¬ æLF7­-‹–^%ÑËÖT¸²åäu“O3˜J¼#ãí|TI­”'A¥+Øð»)žMeÕ—"úWU_ ÂMÞ–…KØØòkEÿÁnS¬n\ÉèçÛ»÷H‘y®»’tÏ7ÕëÙœ€‡Fê³}I¦¨²¬_Ðjqb_YK¦É¿Û—}Ñ”fœÝÝ4“Ÿ<²èº½ñY>Š —ÄžÄ;×3“Ác£d›aIû\ß 9\Z®â®ˆkìÊÒ5fYØ \â>´=áÆuš@U|m@N3O~É€8žæ¥(K/XÂä6¹O@'©Sß †]¡eÑaXZ-«™XdRÆY˜Pߘ~ùSuùJ™†7ãbï˺ZÏÈ=¹}á¾õÕ¼ò®ÜwùSðµ·•[»iÛæ~×ïý¡w;w×ûj5gRˆá]ÈK&MÄ@ãMê$šF àìQø ¸²^†O[èîÞHOi&¦!öo¬\£ê<…&}ñÕiñ+•pâX{:È€ÙK44©/Fãzjàê§3¼<÷â»Ñ~ƒa`¹~áÒöÂ휄Ƃ ægÝÛ¹)XJÁ«Ÿj5µ”› •öÅ-…'g×ù! Î íŒ'kp抡۵ˆZ™uE¤C¼n&LR­š] E³ÐòŸ‹|.g@…T†ø÷ÿ|øôñæ¿o0l—3,µ J+6J %¢ûmÐÙX=4H¤Àˆp^rŒ {È÷\ž%$aü¤éºÚvšJyÓ@“X…ÒjíuDž/¤cN>Zgkë=NÑ*º½³¿iÝUôîþâ÷‡³…³Ch µ ÌÜøV~(O=;uÊ[í•æÙ”¸ O¡á;”Cï¿)p´48ú+f¾¢À{Mj\¾EL¼D³ûq÷4r ögð/Ïu~.&ß·|Ì­g}8ޏ°ŸAÞÇK‚Vö½ß©z~&a ™ ª~»(ÚpñHq„/QX[ó{1j?™xq„«·w¡‚fx(À° £F*§³‚%|÷!ÐC8úiË8RÚ.Ó ÑÜ…À®›ðpQb—(&†ñøcÃñ±Ÿ¡g¾&ÐámÈoWt±¢_¯(™–‹ØP²Œ/vWÇïÙ)¯>_ý>ú0áo‹AexGñã×ì±ýa †72øÈ eÍÁ¤¸Ž™ä)C(ó%ÿ–œj5|7­Öµ ñ¤endstream endobj 2636 0 obj << /Type /Page /Contents 2637 0 R /Resources 2635 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2624 0 R >> endobj 2638 0 obj << /D [2636 0 R /XYZ 85.0394 794.5015 null] >> endobj 914 0 obj << /D [2636 0 R /XYZ 85.0394 769.5949 null] >> endobj 2639 0 obj << /D [2636 0 R /XYZ 85.0394 573.0107 null] >> endobj 918 0 obj << /D [2636 0 R /XYZ 85.0394 573.0107 null] >> endobj 2640 0 obj << /D [2636 0 R /XYZ 85.0394 538.4209 null] >> endobj 2641 0 obj << /D [2636 0 R /XYZ 85.0394 504.6118 null] >> endobj 2642 0 obj << /D [2636 0 R /XYZ 85.0394 432.7569 null] >> endobj 2643 0 obj << /D [2636 0 R /XYZ 85.0394 303.3232 null] >> endobj 2635 0 obj << /Font << /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F54 1433 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2646 0 obj << /Length 3051 /Filter /FlateDecode >> stream xÚ¥Zmoã6þž_a ÎÖ¬ø"ŠÜ—í¦Ûô%Í]²¸Úý [Š#D–\KNûõ7CeÉ–í+"Šq†g†3CóI|k¦­°“Ä*G<ž,VÑd cŸ.8ÑÌѬOõááâë酪XfµÐ“‡ÇÞ\†EÆðÉCöÛôšqv 3DÓ7Ÿ.gBÇ‘˜^ÝÝ]ß~¼ùÞãH€ Ц?_Ý~¾úÉ÷Ý]Z ût}ùåᇋë‡N˜¾À<’(É¿}‰&ÈýÃEĤ5ñä^"Æ­“Õ…Š%‹•”¡§¼¸¿øG7aoÔ}: ˜ZŒ ø„sfãX ˆ-ÓRHÁýÍÏw?]ûu}¾‡EášàKÑÃ.šÀ0K£Ý'Wžº}[‹´ô/EõR/Ò¶¨+ÿ^?Ò<¼7@¢Gnž¬XŽ0ã SRÅDSÖõsã§,‹çü½ÿ@õ?˜q®˜Š»7°~‘t³Ï4ìÜß›|ó’oüK•®rßñóö³˜Ù$Ña.¿â×'øž›©ç?ØqÎÎõDk ;Û!O4ëS¹ RvDE;*dMÂï±µ‚űQ§Ù¢C¶ƒÛ„ÅÒ&C¶‚n¥'€K$–€Ã®zãŸ7w~$Í2NCßÀÞû6lö¶µïûc›oÞ.9çS05iíôá)p_¤•§Ó÷îÝñ~QG¸D’Õm›g3D6vUE¨!ÁPCòE±B†UO«º%õ•ƺ5boJïÀOSOŸvD²¨ËºšeyY¬ `<œV–;ý×SNÔ¤h¶ëuY½SÅXõ6FÂ& d ;MØWÙŽ–ç[êä\nWyÕ’‘’%¥þñT7-nÍ»1S§s¥ÿ„©,uù’Ÿö)%ΤК絧ôïn÷‹jyü Zw¢@?üfŠvÓò¡½ß€ÖI@ î+2úÒ‚ï!~85â‡Ïµ©_Š,ÏFÁ‹‘<È.£Þ¢®šmÙ6#þ ¤2àÕ‰ðë¼]|½q03øèqdf3­¸¢¾¹œ)O ‚Çi´Þ×ãÞâëm•y ¥½ÒpŒôª Îðìî˜n' ·õðâmÁöÅÎö¡¶,´zò€±¨H» Å‘¼p]»~ÜMˆ”0’Æ„•ÏÔì –4ëÍÈ4\0n:µžéó³¬ÑÆiåi§Ýð⑘n›€V‹.€ÐU0_̇N©®Ê7 T¼ˆCºï…†‡‹zCDëºÊ¼áø&­ gƒàªhúZ”¥˜ç|úÛ(ñ@C_Uûç¶Içe~TˆÝD -c6 ¸ô§Ù)˜uT H\gû ‹äúƒúê½±²îtn¸>ÁyBÃ^ðuIŸ?z3^íMràyöÅtö>Óq°ûL 0oˆ°Z!©C ZN×r Ã3˜4 "÷@ÿ±-|#ó½¿ ‘` ²™Û»ì¸¢çÏ¿Rãþæµàüac'¬Õ ‚†px‰®…f†wÚ‡w–¼<ÓŠÄ~IË"ë/†<¦f ê¡·@Vdé7¤u£1€‚Ä[yV@ÕµÇ#¨µy>H02üODN;·Î7àãWƒ0 µ}»&—U“;J)Ϻ³#ÖIÕËþf‚`Y@O&€„š~¹{¸ùåöþ˜ )1u6­éS…¼óЄ:ªÝÙÜg©á4´ÜœfˆFXöáÕÐL$²üÜû ä½¶>ó8ÄÁèÝzT'T»°b€S,w° Ï²€þ_‰eq¢ÌiúTÇè¨s¯¥Z Òfllƒ<~û #™/ûòX0‘(uZÄŽjDÆEÂÁ&àt yŸcè¯B¾†–ß;Áp³`|ãi:w_Bcçêȸ¸äÐMq üu—¬#>DÅL ™ÝjÛ¨s’4õ¯äJ÷e$‡ Yž2ñ~ŠA+'UÞºù.¨Çàê/ï¬òöµÞ<‡x·–.òO J¤qN°E÷‡Mb°ñOìyÿÿ»Ð?ž^ \`íB:˜ƒâYè_¥o¾Ë×ø´YC.ÿ{ w²á€?2¢½”x½ÎC” !ǯ<²¼¯¯:biì_G°OhH€ÞÉu8 $xànCü·s³8XŽ!ä¯"Òg¼PŸê„*g„‹1#Äz"ï2Ó2õê2¨?á9.ÔiÁш`Ë‹`y ™³<*Hé ÑE5±— uEŠîa<ËSH¡ÇLJI0•ä`Eûé¿`FÆ!‚ñ‘¤¡·ßøFMihàŸÁ.‚—ïïýÓÔØ‘7Eùöð”nü\ðÛ喙°IpCÍíþoŸÒº©òvìÜoŽzq0 ÄøŒõ©Ž+PGåèqD,Ó¦«~<åA°lAà ,ñ¤XhD¬½j‡Ðn Äú¶‹'ÌnÍtUg¡l<\ŽeJI{®Fq• \)nNœúGY8ÇYïñ±‡6l‡¸;oZú “¤¦"ÒÂ0°KG™;6 ±,^|Åà ¤%Yb߃y?ž•ÌâM„'B“1ñô: à”EElŠP•оr«j>x=~|¬« hpºOõ¶Ì|ÿœú¼&.ÓªøONC®¢ùnŽÆg‰Ðõêü¸võœ7ê:œsM‡DáaδñC»šNRl³Lðb%>[ÈŒ• 4ÛÆŸº«3,u¼WA^Ô«UZe3£¿¡ð¸) ÃDgL±Gu•3Åâ ¢tnÏžfˆFX"Jg"dO–Q—“˜´ü%ß`„‰T/‡–7TñDd±ßë74êyS—yKoÿüî[nŒ³hvsûà_²z•Õ; È~ §ÂÐïê–ð¬êÀ°Z¢ŸvcUàë÷cÂ%Ìa°‹¿t¸"CA¾µi7]¤P¦ó¼ÜÕŸŠPáþ=Š#Y˜DA“SnÖ¯oW5M—¶m¾Z·'ŠCÜhp7âŒfô©ŽkFGå4ãùl¨ýœ¿9j¼P’ËÓ²uT#Â Ì 2PÅE2”î¾XV¾ÙA‹/AW ùp·³ƒNr¿ îÁ;û·¾3M‚3MÈ™ºï½'s‘O ³ø^ÁÕ'°1¾8¯òMÚæ¡>.ÁUʽn'"x¼¦XÎ@@ø Å Š Cp\tñ>}X'(ËëÄm®TqôµhŸFœ€\OŸvp6*iˆæVKd@…SÙù†Š§“ÞU˜°åL, ªO‹F1®õž-UyîÎGC<Ÿ«ú•zCÈ ü¦AOŠå]×(—õ¸ ”Ž7´ šmž{˜  Öœ¹ 5ð•ïúpsûñ]ø4|ž™KdÜ$ožÿî'O<ÉzSÀ~…Š)ï¬g tË"kºd¶ÊÆ®Š,{‰<{3!ÖÝV 2aQ*ÔŸ«‘[ Hb¬íJm¸ÅÙ± #…’$¶]pÌ?q ì,?ãŸzT'üS rþiuprA¢~še a9Ȳ$ÖãÔåuEwß*_ÕáJaÛ¤KêÎòùv¹9 ˆ±˜(ÉÓxôˆŽÃˆë³Þ:dœ{? PÖœ*Ð µ÷ƒ•Ø¡P÷î"F ÊǰAù˜ë«ý3õª®f £U–†º>öúô[Σõ§Ú]ñ¢+<¸›Öûr$Ü#w™^»?+Ä׳Xúý€ûr½»ÿ7ŒaX8ö¿V±² :-Ð…NÆ·Ü팴yÓúžÔ?è¶Ãö®6‘œ órúä¢T7gNŒÀñ„Yn{eøL%%%²oE8H@¹¯!ø®°ìk'lWóÞuúØÏ—$ÓrTƒ¢®¢üÿ´i÷Ã-•0pÎG.žödrÉ8{¿Ë ò³;u‰u¾DLy> endobj 2647 0 obj << /D [2645 0 R /XYZ 56.6929 794.5015 null] >> endobj 2648 0 obj << /D [2645 0 R /XYZ 56.6929 752.1413 null] >> endobj 2649 0 obj << /D [2645 0 R /XYZ 56.6929 470.7332 null] >> endobj 2644 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F49 1358 0 R /F54 1433 0 R /F64 1485 0 R /F11 1559 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2652 0 obj << /Length 3629 /Filter /FlateDecode >> stream xÚ­Ùrã6òÝ_¡·•+#Ip¶òàÔL¦¼‡Ç;µÙšÌ-Rk(R){´_¿Ýh€— )©Ýr•Mô¾A>cðÇg: ˜LÔ,NT2Ζ›+6{†µWÜÂ,ÐbõããÕ÷?I=K‚$Ñìq5ØKLk>{Ì>Ïoîïßß½»ýõz!B6\/BÆæÿ¼¹ûåæ4wˆù͇÷ð…LG°ˆÍßÝ~¸þòø·«÷1C‚9“HÉïWŸ¿°YtÿíŠ2ÑáìXÀ“DÌ6W*”A¨¤t3åÕÃÕÏ݆ƒUóªO*ÔA(T4[ pÈ´_L,`!°½ˆ ’Ř÷‰ÉA¡˜¿#£ßÿ©$çNB Ì€Té&ŸJƒ hΆèr@ºÄ›-¢ a뜎)«7iQÑØbFmM¿¿ïóÝášs>‡£“œÁ{ECKîwßä«}9~-+š¶¨ž÷E³¶ ëœTJ†ALèQ ·0«Ý5×ózC»Ö°íކ©YxÞoòªm‚#í²GsЮ.stæ”-9äÖsÈI‚-Ùía{|ÆÌ)ÕY¢: cªÆg,ø(‘EG«¹MÞÔ{3XšÙÐÎ.k󛤡Ӭ𓄙±h9¿m `™Vñd±¤ÕV^ҲȆoÓ†vk5]Ë5 Áb³ßnë]›Û׌>Âô·wïPl pª …a0A’"nây–¯Ò}Ù҃à C‹;Š!Ìü&„ºÁo“˜ï«2oìZ§«j$bpLZ8£]|óh*WAÄÁ›H½m‹º¢-Zä³, ›ˆ¨¶«UV,ÓÖ2‘ÒÏK~Íç»Æ.•uýu¿µ\ßdKÀ†âh,šÿÔ•‘6 Ù¥U³2fkwj±=5mÑ€¬+}X:ÐR³Í—ÅêvLó)Mƒ0&ûz½¢µ›_úÐÔ¿Ö¹ÅA¸4ð·$4hœiI‹ŽBÝSˆü0Ç…™ßXÈnaoøå ›€¼¡¡£½ A†g)Ô¼É[Z÷;ºÄd,'¦yìuXkTû4Üo¨œ‰ßV»î<;Ip¿Qèœ\@¤‘ÊòØ#x°²á£Óƒù×¢,i~Y´1Ë'Í®Óê9o¬É€«ÒÂÌH16i6qñ­‹+Œ *Ÿ¬6ù®H­›¯ö›'çx]ìmó>ÞÐàÈÙÀÜkÚx޼ÄäXXyù$IG@OøúHB˜ £è¼³Böö”±ý—)ÊDB@. t@”Cæ ÉÒqén›zµ ÀÔH¸”“å­ÉÎ\õ§Ž±{AÛÃep÷Ÿ&@·wÃ4S©¶xÉK—JS„†ò3áI86R². `?#¹°G™Ó: mPÈ8·oŒ›ÂaU<=•9-ãɤ­©2 84ãúí}Ü|¢’–\]ˆcÌžö-6¹EŸ–MMS~Sgãã\~SWP…RfÌõN†­³.Ëóaku:luP†¼ƒ¿R—½Ê|^oÒåÛ/_óªîÛ&_îòvJ¨À3Îê€<„ŽÌ€N`uDéCñl\¬4zZ˜NÑž<Î?>Ü~ É×¢]Ó)7L=ƒÚ÷ÁŠÁ]£ÛR–»^Gêu¨.™pnÎ Âs¬ ¬2LtïÁ¾+à:ärb椃BÛ©*pÆ.ÅQàÿáŒ.#TOi“GŠ&ójYgÆÂ`¡Y[ãËh÷7Ï­OT<‚žh'*ÔŸŸŽK}Š'm%ÒÕ¦3Cs=ÉîQN€Ÿ(Ÿëœý毘È$]MKËu],)oéý‰ÇÍÂ2Å›,ôv 1–ÅãØ§Æ »ÔŠwar_f/QhâÏnUŸg³( bkz³0ú?mfO 2úXi=öò€À/–‹ol£kç;!pj|@°kÈÅEòm/ïvåS\HœU×Ä8¥·ÃžœkB&iKElP–ýfR´ôê z¸’ ÄäªÝ¨ ļ7†ìš¡°uiNåÓÝÇÇ÷o©Ñóo qõžšu½/3Û2@|*˜a³5N¤£kñõDÿ':îÿÀž”àà¥.²sxP£¨ËÜ\Pò ‰GhÞ¸®Î2í1¾ßƒB®èÓ ]Ž¹Î¸zhž;h…b’&cŸDÙù¨÷O©™ÕTg`?c³!!ÁCY˜FB 2Wš1í|¡ÌÓmÑæßZS}„®; ë›ô@«Ov«—¢)L:4Ü…XƒA½o·{‹bÐc†÷· f?Ü4 < ªzÒIéèhk“CšBi “*ìÜä¶F:L,޶ŒÕÜõPšu^–}ÖÞ‰vi”’,‚4ógRÛ÷ç_ÞºCÐtóúÇûÇÛwž¬8Á.—²íâi?D(Á² *&Óƒ£\¦ºþL™ž ̹,§Œ’ÚW^רÃ3-`Ü`…[® ?¦gÛÌÒó×Ô¾ìÚ\®o S¶J·;tµ ×®¿…ÓFúöXârqð?®Ef™ékV4Û2=ä™Ñ©hþP›Ki›¤5¢^#®íhÍâpÓpô2}¶šX´ÍPýe²¬­óÓsP€7TÍ6þ,oóÝÆG/´-,/HÀ]ÿsª²iÕ¼º^Ñsn}ñ;L¿îZH憥q¾»G?ÔØ¶Øäõ¾¼i=ƒ³¦Ý¥mþ\äT€šú}JGÛ×^¨g΃rÛAÇöo† k×Âá¶]ÍÉ“p“*¾ömFøÙÚÞcžxc[îíæ eÖ0‡6ïí^@Ì´Kؾ»Ôœ¤RÆd`Vˀ†°uk£E|¬EH¨ëêp!_–ÄdР$Ýdʺ@ðŠOvb" \9Ð %LÀ1aá¿þH¤vŽ ª}¾BIÒ]‘P—EÍ«ü™î6`{‹hËӊʘ5új¨Àg"²|}´W}6’Ÿ½BZò‰š7tœ’+L÷TB+Cþv> L¯–×nàÔÐ8v°‹¹ç6­½-¬Ó—é‹Xkût¼ c¡Ë ¾#6² mij æ‰>eCÄ?â]1D‰àÓ6?Ò‡ñ‰Rà Ÿžl¯³HÉÎeýyFpÄòðc†¸lJŒRPš<Ïûzß@…!A¿MwGš®sºÙ–¹/E–߃ ¹Üã»eæË-y xwsêâ5HÊä†NßLŒæ!£¡u‚€ Q £pâå—ÙªLŸÿÈu ÝzçÃûpr]L뮟ó·§Úˆˆ”ŒÏ·-†P¦ OÛ¢ƒ2L~®ê/iê˜uÔCLY…>¼ƒ:Æ>6îJˆXñ1z{½Óªº:Ø[ù•«VÆ]Ô˜ì:¤–ìº*'«•ðÒ 0uI¦=БZ i~‰žÁ<èõ yp?P/r]ñ’:Mñ—LRFá»{ÞÖŸ×Q cv¡6„:-¶ª—[–hiy$» K&/ÐAS0IKðŽ*“ðŽR7Ì›¢ù符Õ¥0°™Ý|r¹?Lh6Ï6™¢›ˆ~ÈÌ·eÿIK¬w@]u«ì§ðkâ à³ØÉ)Ex¥'°3·u\IÐ}áË•!Ô™SsPƒS;ë?Î"ïÕý»_ßGè0ÅáßÍiáÀœ ûùB#sR8¸yG¿˜u½KšÊÒ6¥ð Rm …Œ¶}Ï"aKF\| ÑLÞ‚šì%ßÙÉzÞîw69Sø™•žÄá×unÕ¬¹½·ÝþòH;üï¥á–ÙÍú|î˜MºÒæ¶éÎâ1RLìÕ †T½¦Ûqp˜žƒrm‰®'×Iéè;>c+ÃúWºÞ„uk§?% èù :˜ÓŽÉÂôn©<Ž"R¼ˆÅÙÁL‘NŠ•’E>Âúà8wâs]&Ìðʲû¶Ñ™.{>8´,A6‰ß zÈd]'çþÔµÿR3©µðs,™ ¤L¸# 9¯ Þ ¿·¡í SI€_.îÕ”«Pê Ô"ö°õ_g) endstream endobj 2651 0 obj << /Type /Page /Contents 2652 0 R /Resources 2650 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2624 0 R >> endobj 2653 0 obj << /D [2651 0 R /XYZ 85.0394 794.5015 null] >> endobj 2654 0 obj << /D [2651 0 R /XYZ 85.0394 385.1749 null] >> endobj 2650 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F64 1485 0 R /F22 1037 0 R /F54 1433 0 R /F42 1338 0 R /F49 1358 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2657 0 obj << /Length 2972 /Filter /FlateDecode >> stream xÚ¥ZYsÛ8~÷¯pվȵ1B­ÊC2öLÍ•dמ=Æñ%B2k(R#Röh~ý6Ј]Ù­TŠØD7úøº2½Œà½ Iò8¿LsNDDÅåj{]nàÝwÔÐ\[¢kŸêÃýÅÛoYv™“<‰“Ëûµ·WF¢,£—÷åÃâ–Pr;D‹›ï¿»ºŽÅ‹÷Ÿ?ß~¼ùþß0A-~~ÿñ—÷?áÚç«Ⱦ»½»z¼ÿáâöÞ ã L#¦$ùýâá1º,Aî."ÂòL\¾À$"4ÏãËíŒΘ]©/î.þî6ôÞêO§ÀEFDÌP#I”ÄÓj¢$¥ˆR‘,Ì©‰çSj²TJM}hÚÇ¢é^äþôÄ4Ž ç »ô·1wTcîqìq§qJxœ¦!û›ªÛÕÅuÿP¶8hÚ%¾~ÄYÿ$q`äÕãN®úªmpÒ® >öW4[È]}¼¢”.ÀÚŒF‹{»K)×Å¡6œªÎðhÎæeOFî`tžÒˆÄ{Í0ÕŒa,Õ`˜CÿÔî«þ8² (‘¥9çï¨Æ„¶á‚°$⡃m¸µ ·¶ám¸µ ‘õt0ËÑ<ÍçÌ¥Æ<Ü77æáÆ<Ü7Ÿ5O’æDPúŠy|ªóæqTÎ a"IçpTc Bû€¤ /à}ßËíNé'‰Q/ õô¢µ*a°j›^6}‡4Ú °º•]Wld‡³—§jõ„ÆP5p+Ke.Œ}àÅ`˜€}@pŽœ¤ ÀìšR’ ’ögÂ'ŽÛÝy‹²„d Ë_±¨G5cQK¥-º<¬»êOùîÃȘ4!<ɲyÞŽjÌü)áÌBîwRë&µ —.~¹ùŒc'œ€Ê8k„¿t¡$V£dQ”ÏrßW*2]ºªÙàðöæã]d¶oÕéÞ~+¸'Rœ¤*qÆp%Ë$ ¤†<ÄRK°<ö²SþÀ¨…S³ø£Ú¶8)š‚QAx*òÐ#¶UchÓ\¡Ã¡vMxöO•Y Î óÁ7a’Á„YoJDø@²n§àçYz“§‹ª_ÔÇõÐwU)ÖÀSú£šÌÆzÜšRâ1#{<¬=;“ŽLŽ*Û“ ŠÝ¿Ýí«¢—af äRŸƒ/ìmê+ÌJÜg/U]ãhU:d?euý~ûc˜ß–Ò¦ÏæÖ|ªó±æ¨z®Êu]lÎV³Ì‡ªcÄ}ºêØc°eÔd5 4Á “ý#Ž0aðÍ >¿D"Z=ÉÕoW™FÛbYËÞP\YVfŸª9Ùm`¬Í#ƒŽF¯A§!:‹‡¯:¹Ö> ¶j1¤ Yg0#ÊaëNîœâ<àîö?uUãZÉFJÛtò<ì –“„òW©O5ã –jp…ºèº³°;Ë{€ÝóiØ ¸ÿoõç7?½¿3¡õò$>!¢›Þ@®G‹ê]µúYž×o”‘<Žé+úõ¨fôk©ýnË‘v#h©({…³£³µå„çü„÷½´v³©±Èà¶"a¾²`+÷šCôT}Ø[Ô8_µÛ-•}y²à÷î`_–@W­noGqÔ¡ó#GÌqÔ;K ‹TG¦¥/«ÍD"¤))µ4.ÏqF€™ 8ðð·Ý©ìªG{*ž¥f9䊺ºK·-¶E”áõ-Z¡¶†Zƒç¬Óq8pœòWj)Ÿê¼Ó9ªÁéPÎq\3N¸jægÙ;ª1ÿÐÎ ð0`ð¼“p JO F몱 ¸jN¾FOûªFR&`sd9D¨³ÌÛÃ£š±‡¥ì±?î0‡LæÛYæC¾qŸÎ·{ߌ›˜TÍ„³†ZUÖPO”s³/vÐ’ Ý—(Še]vH Ì¢ž6»)ŠfUq*r†&Ò{ºhà$”P3Oª†-X/^“CÓÈ•ªËu\Â67JÍUpÒ‚Š@Ü Y|ú|?%Î$~#<ŒòwQ–•‚Þ¢ž¹<>)Û°e;ã qÆHÊ^‹1Ÿê¼/8*í e»-ªæ]×fLÅšˆ cœÍKà¨Æ"œ\0¦„Q‘„2è6™Ù‹D5P¡”®n ÔÔuÕY’Ÿ*Ñ:Aß;ÔfŒ›º…¢‚ä9ÏL$ú'?—§`l ߨ[Œ|µµFÙÔÝO¥³Oi^©Š‰ÒÿšA)˜2–À¾¬ P,É×)—TwMЉîÿõWÜÿJp(U7_½•ýêí^vmýL@më 6¹ w͆:hf®ºÔA@=ËÚð -C=˘ 'U­è ToC]á-Å2æ‰óÜAã‹'b‚X Isv¢=ìuLŸ,]^‡ÙôÔœª8''^¹kð©f‚ÊR9€•€°ïþòx¶-™e?´%#þÓmI ÀòɵÎê¶ð€½¨ã^*LI O×=ŠÅKÕ?©ªjJsYˆ¥Àš ÃñPBÁ$ò7ã ë „Šn{]q*‹FT€„4ƒf8@T' Š8¼|T.i.uâ žI-ñÕPƒ¼\Zwùx'1HÄ3j¯i•Ѧ€@4vˆ±ªÁA;ÃJCOfKÈ­Ü.–H` s&‚ÇV JS0\àÊÃ]ªíï:Ù‡^ôu½7M9±x¥×ó©Î;¹£ œ\Ý®N{zÂIœå|^G5"ôô$‡¾;ÊB)Ì+³W™|±=týõR^{ØðÚ(ÞT3—¡0è첈~íU+G½û ÀWotL¨ÛVÈà7ðn[ÔoÐÈYJ’”Æ¡Ÿäêvß6`)´ «^W °&›U[B¸tøÆû5èW+¹ëñ¦&K¼ÀR„H¢™ÙωËêp¦ÈÒ…-€Ôs±£®ª!Lê#~½4<«MÓ6_8NuHÆ ßØ‹M|þj|µ,ü_7еϻ-ËÇÃæÝÖ£šq[K¸m#7m_a‡|ê¸iBb(pç¥pTc1BÇÍ(¾ùDŽ[›T¡3{«Â^óãšÁ  X_j¼âO3eÜÀ¶Í³`ó~çä¡o› „Àù[å4…ÐL^¹Töˆfþ6Á¦‚ÿðâB>üMÇÚãj £'Q¦þêcFG4%°W3%¡(.¡²˜ZÍÂÈVj¬r¦©ÚTýȧÖv­º”'šRšK(êƒqÖ?®€=¦E]qvÅј”ñˆpÊ“04ë¶(]ç1–Z`Ê…-±çŸ(D¡ÀO3[ˆžt¿€hE‰Àg"[_L¥\AEˆ6S.i‚g¢~JKÄIÖ Z§!_†Þí×ü énˆú3© Ïÿ&Fþï¿ÆþÖ š –+ëNdÒ¿–ÿñO…0¾þ̯Tã•Æ è¨Æ‘‘Jï‰SýùÆendstream endobj 2656 0 obj << /Type /Page /Contents 2657 0 R /Resources 2655 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2659 0 R >> endobj 2658 0 obj << /D [2656 0 R /XYZ 56.6929 794.5015 null] >> endobj 2655 0 obj << /Font << /F38 1122 0 R /F49 1358 0 R /F22 1037 0 R /F54 1433 0 R /F21 1034 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2662 0 obj << /Length 3118 /Filter /FlateDecode >> stream xÚ¥Ërܸñ®¯˜#§¼‚‰'Ƀrdoi³q´–œlÊñRË#rvȱVùút£ 9|¨R)•Š ÐD7úÝá«þø*Õ,–™Z%™b:æzµy:‹W°öów0çè¼õþöìíG™®2–aV·÷½½R§)_Ý_£‹ëëŸ.¯~_Ÿ GØú\Çqô·‹O_.~¥¹ëu&¢‹Ÿ?ÜÀ«Ñ± Ž`&Ž.¯~^»ýåìÃm ¦O0%RòÇÙ×oñªº9‹™ÌR½z†—˜ñ,«§3¥%ÓJJ?³=»9û-lØ[µŸN1@é”i¡Ìê\ –êlšK1‹5œú®]\ýÊhúÖo_”÷ùaÛÑ&U먘!+ñd¥D0lu.á\‰Fp–iMÆéIE¹>?V›Gâþø´»à€¨ÐÖ+Á==ëfÿ”oiÜv‡»>xÛlÃæwåcþ£jöxºYÕ1&~MuúPóª ‚êTEYwÕýËH}Œ`‰J—±{ 1ö¡ò˜„%"“Cô7Í3HÃÈèkƒzaTT44A’ƒ‰`¾ÑÉW×´–…ãhK 9Z+®ìš}ç6:<ÝY¥³ä~×Ãn·­Êb°1lX·ÏlÕBÅ© z!,ÅÏ%ø©•ýàÞ~ÔªwN¥Áe¼±ìâ÷ Ø!3p©œ;0r´­Õ`x–u~·- Ðv#xtuO³´ŸÞƒ‚шˆvßåÞ#á ÿ8”mW?Á\êTWjÙ3œZb;¯!.¤Še2Ñ'Öaå60„¶9Xl÷> ùOçHI4ÖFœhúvsܰg$7û±Ý´ù:[œ|àd·hG\³L õŠõ ìÈCíèŒ~>J-"?F©öé(5@…˜}$‚$¢Û¯ÓèPorÒ+ˆíQUÓÒ—ËkšpÒÙ5u[¶´VÕ 'yAëV ±wYà?«úfž«î‘`nÿr½æ"†Û…÷/4í4 NðØ vªŸÕ-0–T Çû–÷Cê®Ü£ž£̈T'ŠÅJÈe‘ö¡æE ‚H¿—å®ÙÉϸÆEìÁ5ްO»Æú¿f°D®œÁrIŒÄ™¶Ù|/;[êìò]Ù=—ô¢"°yËgûB^@ˆµ‡¶¤ùÊí±ÏÇž@ÀÔÜ‚BÁÛ}èQ—Ï ’Äm=Q‰ãûÆYr™ûPºmšï‡FsÔoÄÁ)¹hk]§°+MÁ#eÞw¾©›¾NxkÀZ´Ôv^‰¤`\Á—ËJÔƒZP"”è Tm«zìL ’×f€0Ô£D²$6Ù‚ë}U;•yŠ¢¥Émõ½¤‘Õ3ÜüýÉôèHð™Ó|ô]Óº/íIÏíQí;Únî°“×ÀÑãá)¯ÏI… Ðlâl^œâᓘG›æé ’”Ô%1šÔçƒºà Æ0U&ø¾sG‡)R;œž‰æÐG"TN¯-(߀4»¼s O°·.l` »|ß’Û<‰p¤©¼¯©’)ν¦ÕÄ6ó„)©c´ŽÒÕõi6àÝé}ñ’RãÂç*ŠCW2²)‘&?‰«T0é~Á/?òíÁÍS 8g!ÿÇ¢¶hàõÐVÀ5 ´— jÇt¶hh¨nÇz È(è•;ðÛ²Û¼ÝÛ’ˆÁÙ¡çž…6…¸·'Ü¡² ²üÕÕtI:G8GªÈ´%Nã¨Å™Ê­ìÖÖK$êH Ëàt”RÑ'PB¾Ld…—Ï6I…I¿w/·ÛÖ]¹ß¹ÜÇ&­á6¢é-ÄØ%­ÔG,”1ÃÜsµÝÒÔݤ›iK¸y´û§ÊÅ[Ø´/uIŠæ)‡<_$x·¶óŸô!§¢.gÚâ:QÖ¤Ìd^•›ýÔ>…ï7"b^Û¨p]–ã;Þ;P2ÿƒb¥L™,uT÷{BÀL‰X 9þf–J9˰gë‹™GÇÀÚ¹cðÔ=¨Wí¡BòÞb¶/´ˆúØážì p_Õ›í¡(çZg֎ʼ«Ë~—Ä–­¾SÖ¼.BDÍé¹îËšs>ŸàÉhKÌ+ ”>Ô<TÇGu˜ª±‡*a„}ºJ ÿ'µ#8ºcë¿aº ÜùtŽ7¨ÆÆI‡ ÇE¢–³Ž”ñXø—wàáwÛ×F'xÚ8QxJJä‡î±Ùc¦D==˜"¹E(w· E=÷­õ߹ͱî›ÝÌ,…Ê0 và:‚*ƒ§Y0º+Ã*ÖÖÏÁôaGÏÐ(ªv·Í_h6ìc“à£2F‚òýWÏ ÷Uú1o§Ý· wʼnИƒoQZ`6Ωþ W:†H½ÇÆœ`lÆÉ<~â}÷ܹͧ!]üþñ3#`Wwò~ÝÉ׿V»Š ‰ù–Å]Ó=žv¯Ñ'½¯¾÷šÑ°vV ÀPùkZЇš×‚uԂݦ)Êw”žêd”F§r™„5¦a¨ gFffH„Mð…‰£¯®3Õ¹–Ö7ä’·L¼ú²A(µùCIËD>-X¹™ °È]¹©ÐGY'+ö”Ø{€ºîÖo|ÔáZ xß!ÍPæ>²ÿöåÃç5äàÿ¢WTØ5u^ŠPe‚¿ÒkèC-HÑC)þ±ÉN–¦B/#PcÌ'µ‡ò›ê`Ç ½¢ñ ¡e ‹ßNìƒb6‡ãdÕ ïX\êí¡÷/ƒîÐOó›ù‡Øú‡Ú±,1¯UjAê(Ìa0Ïd‹ØCf0Â> Ð{‘àÝŠ‰¿SÁA‰Þ®dhµo-¦ÛþŶ.ðz%@Z~ÃÐy[Ø'w°® oÇVÆ÷»Ã¾¶7R‘ÕÍ7OÛ€$ï¦'Ò± xâ­êlŽ/^¿\¶èZI³ Á gqb^±Ï>Ô¼B¨ ûâ~›?ÌÆÚEäÇX;Â>kè]°i_ê¦~y:¶eÇ “Á!ãp‡eÉ.7¼âg‡ g‰ 7Yó\¿ÿ¯Ü¼ô¡¸ê¡¦È²r$VËØÔý‰ÁQ5O†øoñ7̓mÊ”»ì7˜rCãšçðn[TG}¾¤'† —À!(uø¢l]Ý[P惰w¶-ƒª>A×/‚Îá4``6ù|ä&ZÛKƒî^œ ‚Su2iƒØoá"\‚gÄ]°ñ‰jÊi“hõZ 3Æ7è’Ü&~Yfk;¤0\Y~Pc$ó7ØŒÑiô¹Ç¬Ø¹‚’£y‚zcC»â¤÷ö&ÕÕ~šXLÞêš³Ã[]ÉTbt¸rhgËÐ%‘¦ÙI dØÄØô¦Ûç›rº"µñÝŒ^ˆ£úÎ;µþmÙ¡]tIÂDbø+¿>9-üøÄYò÷x5øîv¶¼„öØ>Å;Ýî#†tY à \'ÃØF,\¬¨&]6/ùñB“^í…(•Y8Ôr47Ñ'Ö ´^y‰ßNH2ªýz¸béOÐËo¤Ž†J°ä/Øuµ÷4cô õ10';ùùÊ›pËzªU•O{©¤ô>ÄMyš@UýNNˆ·Pzw•ÿ}ËRÆWšá/É&´ ^yKü¿°vü9žJ˜„tvZŸ€§Lâ ¢# 9Áu²†H ½¿úäúPã@Äùµ:=•ãÔ©H&Žõ_ýÀkendstream endobj 2661 0 obj << /Type /Page /Contents 2662 0 R /Resources 2660 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2659 0 R >> endobj 2663 0 obj << /D [2661 0 R /XYZ 85.0394 794.5015 null] >> endobj 2660 0 obj << /Font << /F38 1122 0 R /F49 1358 0 R /F22 1037 0 R /F54 1433 0 R /F42 1338 0 R /F21 1034 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2666 0 obj << /Length 3267 /Filter /FlateDecode >> stream xÚ­ZmÛ6þ¾¿ÂÀ}¨UñEo¸4ÙËmï.ØënÑÒ|ÐZt,D–\KÞÍö×ß ‡¤(K² ô²@D‘#Îp8œyfh¶á-¢8ˆ3ž-’LQÈ¢Åzw.>ÃØû+fhV–håS}ÿpõÝßEºÈ‚,æñâaãÍ•aš²ÅCñqy°àf—ïnß_¯x…|ùæîîæÃ»Û_à= Âpùï7~zó/껻΀ìýÍýõ§‡®nœ0¾À,(ÉoW?…‹äþá* D–F‹gx –e|±»’‘")„í©®î¯þã&ôFõ§S QD\Æ  d,œQ Æ€(‘aeÌiIfSZ2D¨¤o?ÖͧÃaÝìvªîÚÓ53"Š“…7ñˆ»#±çÜcÏ@JÛæ³@e7Ÿ?Wêz%`§º­n°eQ¶û*¡ÞfCϽ:\³t¹Òÿ«u£Ÿ¹èÏËz0LqìöÇŽÚ¿†Q¸5¥úšïö•zoiºÜwy½B-,Vq$¶eÅXE×ë¼ÈµÈ\,¿(”’Kà “îò®ljÉÍÆÞ}¸ÿçÍ©{(} Òh;áòAK ä…ÚäǪ#ú²¥Îº1]CûCYwSsÒ°¿§°Qf¤÷c]©¶%ƒß§²*ke^›Â´JC¯»òI£ó`Œ.N£ N¥8o™>Õ¼i:*g›­ÊëíÈ.9¤ŒÅyæŽjÌ}h™< $O’!ûŸZÔ — P83Úì9¶êµ´áʉÊYõ@U¶ê×0äµ*hàñeöKó ¢uâ³hv9Ú²ž§4»Œ»AÃ0Š]ú«p¾²8Š@ÚbUÛTOÙ´Hã ÉD<4êuSoh¢ZxÈ™iðДcõ‹±ZÁŒÕb÷@‘SgI¤ÀH+° –V<É9 ëË‚P2’ò›ºhºö`ÉåFsjv뙄âdù3K„3ÎS.¼5öG¸0\&5Ÿ·%®KDÑr§ýô=*z6Oêp(‹BÕ¦ÿ…XEÒ7²Ti”¥†×·z5"‰ ¢”†¬P:ìàp¶45n>ÑzhG#p9ÜÏ:ßá–H¾|.« [BËŠ=ñ`ÞÈ[ þ*7Ö=Ú‚v :òÚ|³UõÚrØ*å`hx`Ð]ê üÑ1¯ª¢Ž.“$ð›w6°ÎDÄ—œGuÆÙXªÞÙl›C7ò5 Œ1NÓó¼Õ˜ù‰¯a$3ä~GæüTZß›Ó6¿µ=uû zNäòôÜ9“õ |š ¡»¶Ã©ˆ¾0K~l,KܜوÒäϲó;áSÍï„£òwâyÆõ[´qV€“Œ$˜% îÈ.I äý}çeÌöÓ@q§ÎPÖŸ­’ñ«¢„cG=tÚZضv^È ŸOuFÖª×pùy½Í[5Ò¯è{£óìÕ˜ÿP¿èÎRžx«¯8OÝß¼Åv²‘ê¼;’nhD,ë-Àûê·£ ‚- ågjh÷SèÙ—•ö(Ðû\v[j­Þap²T’—q6Xê%Lσ,…c>‰èWnÆ j‘Q0%CµÜß¾û7÷7óÁ ¶É„]°êŒEX*Ï"º¯ÿÿ>ÍŸ¹sxgîT‚é3çKp¯tpI(ˆÀã¾!CÐÞo!¼ve‡¡#&qø‚oÀŒ¨Õ쀿·ÿ®;¯èí)¯Ž *‰Á¨0Ñ £j¹ ØŠ‡3Y€C€Â"ý <öd™Oesl©Ç˜ê¾© JF6ãGUÕÇÇZu¯ó¢8|·?¨MùudKX„NyV G4chIY°(MrÃrG^Ó“0¶Þj¤Aí{-*µ­a› ¶¨ v¯Ö¥v9fæÛ;ÃÖInµ5È>K‚kÅÃò†êž›Ã»úKœöëüVq„`ÀöÊ£:³Y–ÊíV·ÞÏⳜ{<0b=¼u}RØ UHSŸ‘­Obëáí‘çÖÊK™© Á"úÄ\+ €D¯ æŸ)aÎ’hX@l©ñÓ»;SÇK‚4‹NÊS®øœH4®1"•`¶1³q¼üº9¼þ0HSÀ"1dö𤥙œLZÀAèRSï€oêyH¶¦d4‘Æ$^ÞŸuÉx†õ|}®ð—¿ÿH/ȽTvQÕsþbÚÇÖêR$B±´ŸrÆryœŒÃ"ÏZ®O5o¹ŽJ[nüõÃ)ß t*.°54c®'F+À¸1d{¯:S $]cUê»|'Üo«‰Üm,’6S8HHÐl‘Ɩ \[TSHL쀹û-72˜+_Fô~ÿ¦6ÂÖÞí;'§!í&^1ð³aÌøðX<ÌàÕÔ–§mèê¯nºmnàÉ™L~9(0MÖù¼PׯՃ°ÌVµp­6žº.ßöSżÕò¿P§ð©ÎX­¥êým³/šçz|'Úâ";ÏÝQÙŸ®D CØšÿŸ ê:_nRZ–õE,–ŽŠX̱¨½wµExÉésXÐJ¯HwB6\úÑäò'e/–é²—v* Ë4Œ’¡!Y€îÕ´it¦49Y ÃÔ„‡pŠ8Ã,*Îþt-Ì͸ò§œ‚àõœÿP-ŒCåüÒ…¸O5ocŽª·1H;Ô,€?Ë»ð#æÓ~À}p#ž%K„‚uÓE8vnÍh¡*õÙ^9Á>ר Fú•÷Alr] Ûh™ào¾Õ¨Ÿž¼À6ÂÓÒÁ)H~Íéb^¸²JõdîóI0bôÈ…õ¦8êTݤ2.oÍ/žKˆèÔñeÓPÕ°g²Q‡C^™_x{Ž?°L½="³ÓøƒˆmîšÂŠ9ø±m©]äU>±”—»ë[º¤¨d¢ ¥ƒƒû^Ä:da¨Tƒ•Ä»¾5Ñéo>;—ðW61ô SWp…Š ²Ý¨u×ÚÒ¦—ŽY—]iK“^œ×#{ÅâÛï-F˜ûWSÓ-ÍT‹º…h; s3Ä[â•·ZÕG¾%÷5P#³;𨲘%©Ý±rwSÝd:Ý#Ü‘äý²ÍÆè[ÊÇ$Oâ ØÀ#:óC&CDx¥Z—ccÛ'b§|§ó0Ÿ±A´Ö[b£>îµfËÖƒ€²,]cžÚ² é’nô:öÈœ­SßOrýÓ0ÀìO‹t*/Nä³Â›MEðV€;’2Å“7¼!‚¥ÑE¾YoºæÎ€mûÎs ÕÚÈHk½¿S¸yuZ¢µº÷Àl×®; ŒúÛ‰‹`ÌýP@ “åþpaèŸþ¥`ÿ;H -+äœÈ„ZýþöÃ;ZBa.«;y½bÞt±(Ñ0à2¥ñªþƼ4$endstream endobj 2665 0 obj << /Type /Page /Contents 2666 0 R /Resources 2664 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2659 0 R >> endobj 2667 0 obj << /D [2665 0 R /XYZ 56.6929 794.5015 null] >> endobj 2664 0 obj << /Font << /F38 1122 0 R /F49 1358 0 R /F22 1037 0 R /F42 1338 0 R /F54 1433 0 R /F21 1034 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2670 0 obj << /Length 2894 /Filter /FlateDecode >> stream xÚ¥YmoÛ8þž_aà8­X¾êeûmÒnvÓ4Û¤À-Ú~P$9*K®%'Íî¿ß ‡”%[iö°-Z‘Ã!9œ—g†´˜qø+f±a\%z%š.Ì,[ñÙŒ½=Ž'ðLÁë監WoTÛZ3Î`±•÷„Ájg ¼tìšÍã±b¾gŒÈNúP|Û:ÎÖO¼›8kVë²*œ XÏ´­àt{d±HB4‡둈Â?ƒ>’%qOcOЯ —< XiGU´ÛÙìùÛ׿œ\Ÿ±tPpÊ´¤EŸÆ«!×ÓxÕsÙàüT7_º®*ó ÒšÅ¬öý{®ÃÍÇÞ¨ˆôÐŒw?-Ûu•>’¥>å 5(䬑íðê‘›AãæÆ%œtjÛZoʺ³X6â£ÃÓÚ•`Tõ¬v\?Юçêµ{Ÿ¨V†,Ž¥ùñÆ=×áÎcÕ*Áâøh뀷ÒN­Ø°jÅøjݼ¾¢iRi1ÿ¶-6V“vNºrË´Åæ¾Ø´˜Ïc˜¸,[¢§UWlê´ólV¾S‡E@®´€¯LÅ=P’ÿeë©Ü'ƒMK¨¢¥`F(ãQ…Š“µµps_æI ÒìëCJÐî°"íÊÛ²*;:x,ç8Ÿ¥Ô÷þOý¶Kk?»_Ù2•›n›Vn]¨l[v8Æú4ÑàB³„Ãù2m eìw/Ž#=¿9¿º8£µ~ÿxöáJ©C½6JÃŒ"<%‘u<ÿùüò[ÉsÃK'tšç¥Ë)Â@a¡ÆÖ§ó)®l­¢¸öò‘#}YLd?ÁÄ6÷‰5XLÌõ^x›vX›àX ‹9ž»Í¥±±äÕ‘pU nJ·,ݲ±A ¤^'HÏR'ým±“¾*Ñ“‘J¹ é¶|±+>ÔŽ³èú=HA"dÓþ(邬*½k_ºâÇŠê¼™t ø#†éº¢P£ˆØÊ ´Ã•U8/ð̇1»rñ´Ï¡¢”+<öЦ€½Û®¨T€mË×® èÉ©“§¬óŸbQÉþ8vÈ‹\8‰Éççn@ñ°…í¼h³My[äN£2»Ðb¬Ñô¶¹/ Eâ--mQÝ–­µô¬Ýa<­éò6,¬¤¾vEÞÞ68lmƒý”ŠvÓ:KªÑqú­ëcEY¸ÉÛµ›gÝLzó‚¢¼y¡4ð‚îq]ìùHV¥í¾ßØÓM;ÏÆ©Ëçí²ÙVù¸nK½«[Öf -:Q’7žßÝUÍ->¢@"j¿½'„^.ë­ $½ g'yÉ€ÉJßd¨óÆmÍîV…vKeä†8Þ64Ã/ãƒS 7ˆ×mANê‘äÐ Š‹CÀ…šn6HvqyACä0‚¸´!6 nו£ Ië4èB“9]­m›f %øôÈ%¹|RD8n0u$¯K­]ð÷ r€q72X+žŸX׆޾0îÍ©õÀÍ€Ž£øžëާ!_Æ ãBêaù‘­ò©òƒ3iBϸƒw'rêqëÎp°Ù”yN×,Èî*a2„ûÂ(¼n]€¤ïú›eæÂ¤pÎo=ø h¶õÊ_ŠßSÌö?Mœì à(IŸÛƒóù‹oj<<<°²ÍX³q#6ž±|§¯ƒ˜ ꎘQùv¹ºù¶™®Upó8¡í!ÌÐ\Pê@k¢1ŠqÎãgoÑ‘òwÖÌ.,iM_z ÀÖ‚ÊÂõÜ=uèoÐqIÇú®Ò¯ž²¤0s]DÕíºý ”obÊ<@=¹üƒÞL¸ñä=f+ÄþþŒª÷EmÂBµ÷´á}¨ ¿V>Ubd†º”Ò>Mb©^„ƶ& ÚÀ¤Ø¥ †q·†mhÚbW¹p²”ËëáFþnÕöLÄ\‚¯¯§™/%Ây_›äý{Pë¦v·R2#øÞëäúõù9]μ¾üjÙÔ-œ\€ç<§«$äÞÇ(Áצ]Q=Òvp üï\A–-ÓMšrh°¨³&ïïÅTJèï£ rHׇ[—J`!9"ïÞó.bD˜8w†X±/ñ@°¹5ŒñEŸôžDíÆ}zA1¿#Òh½5ž»ƒ¼ŽkÛ`‚ÅÝšåDûˆÍö91W¥Mî½HðÝnjbmÀ²‹Ñª‰s3™Ͻ­ìMZú ʳ:·út:·›…aü'厺 ªS(&A9÷×ïä~j÷Jí‡þ÷‘qNºLÈgñK+í-fF«Û'à–CÝ¥£nµòæüÂ?ôé§úìÏ>›¢mª{¾˜ºÿý?¿¼wößW $ÝdS"ð1Ò_Ÿ¹çÆ“‹ë÷ÏCü²i;[0ê^“.r$Æb^·m‘áIwE=¤Cò¡öB(Åt¯¾o^ ®ÌTe³Èô|쩟“ÁGñ7à‰uÞëá/ÿÔ¼û!]còŠåô˼âl“/ .Lr##é_lA]%AˆàJïŸÊàÓl,£‰cý?Ä endstream endobj 2669 0 obj << /Type /Page /Contents 2670 0 R /Resources 2668 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2659 0 R >> endobj 2671 0 obj << /D [2669 0 R /XYZ 85.0394 794.5015 null] >> endobj 2672 0 obj << /D [2669 0 R /XYZ 85.0394 562.3301 null] >> endobj 2673 0 obj << /D [2669 0 R /XYZ 85.0394 273.571 null] >> endobj 2674 0 obj << /D [2669 0 R /XYZ 85.0394 163.7629 null] >> endobj 2675 0 obj << /D [2669 0 R /XYZ 85.0394 83.4407 null] >> endobj 2668 0 obj << /Font << /F38 1122 0 R /F49 1358 0 R /F22 1037 0 R /F42 1338 0 R /F21 1034 0 R /F54 1433 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2678 0 obj << /Length 3219 /Filter /FlateDecode >> stream xÚ¥ËrÛFò®¯à‘ª2áyáuTl'a*+k%:Ù-ÛŠ(ƒM€T)_¿ÝÓ3ƒÁ¥w#Ðh zzúÝ ò ƒ> £ JE:‰S„Œ‡“Õî†MžáÙ/7Ü®™¹E³îªŸ7o–É$ ÒHD“ŦC+ X’ðÉbýyú!Á-P`Ó_?>-ng"Œ›Þ=<|¸?ÿÞ3X+›þãîþÓÝï„{¸MÅôî—O·_¿Ý|Xxnºs&‘•ï7Ÿ¿²Éÿí†2MÂÉ Ü°€§©˜ìnT(ƒPIé0ÅÍÓÍ?=ÁÎSóê¨8 „ŒÄˆŸp¤a(z2Ó ’Büôés X,:òb8iG\˜U‹­>ÜòdªIY÷fonªe¶,^ ÓT»¬´¨ïG}°`µoòª¬»+°¨©"a·U"à’…NA·3Î@üÛªnð\!Ã@ÅQlVÜg;}ý4PiJŠ6o›Í¿ôþþ‰€¢ª¾÷›¼È›×–µVz¸q¤q¬ ɧײÚ×y=4Ƀ8‰$[LÀ©FTÆQ‚R/è3ˆ9д[FJŒX´_Õ4}žeïÖEy¨/§¯µ¢ƒ…ªC‡Ë8P‰R°9RXY]Ó²Þv Î$Iì"Oð~„ ¨'‰ÂÐ.-×Us‘^œ >^'xÜ-ÁÏ)‚v„P|H±¹J±yÝë1er¦†ôþ¼Jï%Ë›‹ô¤§‡Ö<“)È!sŸySƒ‡Ÿg»‘]ú mŠìylΑœIAy(òPkX¨Do"\­'}ø:æ ³X" ¹s $ï?<½{œ?,æïýKã‰sçÛ ‘À3Î5ƒ˜8ÍèRç»}¡N¼Ÿš›ê@À^Þåå3ÝG€\BD17„uôKx'+ KíXë5AME×UU‚(ÚET÷ŸÏ,Ÿë5ÅźÖ5©×¨§Ý¬„ D”LOùJ[Hê Ø“‘œþ¹Õ%aËŠ®nŸ;]‚/Ù\)˜v×’ñô9?éò͈* ËL…ÎŽ.©BL†Îá÷‡ÜoÑ¥ÞV(w»Ì„wØ·Ú2wëW<…#“@bÌ¿`V"Ÿ‹¼ìe–ö¨ˆ2â:K=×óâ Ä{–RŒÏ ÎÂŽu Éj« XW»,GÉsng Aþ…ŠÖ,í 4.4„{cc±±1D¬²’€¬¨ïenÛ¦ÑëÙZ¯r°BÂÍNŠwlŠÅ·o¯ª¢*gV¶t¼žd׺ÈwyƒüI!á¡°Kø `¤œâÙñÉË6_miù*«õˆñXJ¤W (äÚ˜˜Ñ\¾Ò6k½ÉŽECHë¹t“Ñb=CÞ%j„Ï#@úœhÌDÀEU*L¬]g¤87¿LíX‹À IÄÖQ_Û±ZÂ8!ÂR÷ªÎ¬¢ Î"ÉЪì#Œ&†fWófÁæâ»ööqÖŒèL¦aÀÂäŠÒfJBå az ¤mu,Ög•\^ÖΜwnlñ·µ®ì˜2]œuì"¯a©ÑŒ±LÞêfõö ëª8“7#üÃ!#Å]Ž lŽ•"‰ñ #WÒŽl ¥|Y2ËFö€rU)¿°Aò€ ïF){*{Rýý˜Ÿ²ÂXÈNMc²•ÜCëÌivºÊQ—;³úntn –Û\\ñe$aì6h|uÿÍEíó"ßYÖVº»ÿ÷-‡ˆæ”4#•&}¥Pî“\^†Š@“Â12{7& °ó˜«0¤qD¸b†KŒ i&$¿Ö Z惰&§Dñݾ±ÌWxÓu^ï‹ìµ=‘ž>Þ@þ½ªÌum¹³‘MNÿªJ=V‚àÀÄcW_Hu1œÅG¯ µh;˪ãÙʼžM8{ßëJ¡¦Ù±|Ÿ7Ye¡\ø [¯F4ñ€ÌáI°†$³ØÚ·‘8½Mq­¥§úô(|b¾øÂ˜(C&˜]ìKXëạPmÓØMŠ6§ÙMutî²qËG3:ƒ#Ö©5.Æ‘4vVâú®¡ •ÍTrU·Pã®°’’Â>!‡CLFSà"€žw˧¯tg$ ×N/×7!΂Õ}Öò‰Ë-*0pÜÜreJÜf©éJ•s—aŸ±÷«®ójm<¸j'ÎÕà»mVÕ¥¶*"î hóau4ÀJw±^áXECa´pŠóuÆ€˜‹Íó{;€@>/}€1š*ûÂôaYÕ†<Çfl&’PzëR2›Ûb4Õ‘ ê‹0ŒùÕÀ› ß½PgÆ—¢£ "ÈÎêÖã©"ä®(«ÆÚhÔ„ £+ùˆð³|ÓJM! ][EÏ/•™ïYà¦ãq'OÚ,! à³Èd‰ŽIL3*žn3ŒFB%`„F6€³ó¨S¾6 y3.ÊVß^2nñt'{jKê')AÍ$ƒ®®GNŸòêXŒM9xœá aÆÕ!CÙ*’Wô¡¸¯p¼(aßú%oV[:§´i3J(eó‚µ^ŸŸÛJâ­t§{:g-ÁR|ÿE….³eኵSëÌ:€Õç«Ì¸ŸÕ7±^@qº«Öš c)p­u¡Wä*Â¸Š¹^¨… ù‚o»nVŒ³-xÔ¯…ŒF]è2l@ ­ÇŠ¡ŠßT]õÉHøBÚw.H7£‹ÉÜtŽCVÖS g‡nÁÈ(X°èJjïÜÙnSˆ„v3Êé` I ÚÊgà––G€LoO¶ƒ¡Ù3üÊû'´rˆà‹GÂPU)‡Ý) Î*Dbd½{{W r¾¡+øß27YïÀæ·cž£1úfòRY.ÂЩÅÔ892eùS’NÖ{féGÛ Œd?ž÷\Ø:V>Æ(èO²aµŽ³¥z¯W9V9~Âd |Ôk†aGZtƒ Ÿ&QØÞ#¦?‹"궉³C.B-#0ˆ‚ùý‚nÜ(ÄLµìëmýeë÷ LdÜ—[nÛŽÇŸßñœé¿¥b—]7qt9¹{¤o,ÿƒä XêÝÒM¦‡%—ŒÃ³šKIlݪQ®ž”3¤)¨gfÙv™)nG)Èà0'¸´D\[;¨àÃ@Iqµ€—~ ÕÔH¯±[Ut¿´[C;\C¾#•¯éY¶„NùؘÊ;åNjSÁäØýpPätr‡|DmÀkFM€²53@BkŠf&€†þ¬¡eÐ41äFûü0T,Âÿ·ÏC1ÐDWØ’Ó%ßЖfŠ:”šÉPª±~œ´‹Ä&ªÄÕµ)N`?i¾=Ù‡&nh£_(Ü'ÖZj‹$ˆE¦¥fy>$taÛ,Ä”í.wÍv&¼‰„"\kM{ØŠ©n?ÚÂu{lP;_É :nþPÇNÎmÀµ¸8ÚH‹ÿîh›a%Î';à]øÛ“Ý’‹é§÷8bS.74‡\ׄ°~&L—=Ú¶0pKäv¼¶YùLþ&¬ z¼z)Tü¼ä<^ˆPáYõ2òÁ)¸ðx÷“Øp†)¢ö{J¹ÎW`øö°ÛêÅ}ƒâ°lØýÛo·©œ6ùn´Z‚ò6Iyu^"Ù#Q’ý^»¨’Úp[q0ìjë¸eeQÏÚPò¼¸¸~©dbó ¾×i.žã3òLX@„‹vÜ’šoÆ&É1H?æi?€^VB‚:í~ÔB¯(õsÖúˆs¥¿è(Õ›ëyæ;£µ>ó€°Â&Z—`¹óËOÏgî«rf=÷ÝÍÉæ¯ïÇ[lw­ƒHç.ñ°’µ]zÊ­Ó\¨ÝÓ(ˆcÿyv¸`ýç¥{˜$Ó'7(¥ rËN›ÂÁ9 O߸ðøžôÙ1CºžJ@ÓÂU” {ª:÷ùT0î~:ÀØt‰iQ&ê1§'ƽùH_F(òãäúÀUF¾ù2íŠù°¤\›ú¡> endobj 2679 0 obj << /D [2677 0 R /XYZ 56.6929 794.5015 null] >> endobj 2680 0 obj << /D [2677 0 R /XYZ 56.6929 752.1468 null] >> endobj 922 0 obj << /D [2677 0 R /XYZ 56.6929 713.3996 null] >> endobj 2681 0 obj << /D [2677 0 R /XYZ 56.6929 680.4742 null] >> endobj 2682 0 obj << /D [2677 0 R /XYZ 56.6929 644.9975 null] >> endobj 2683 0 obj << /D [2677 0 R /XYZ 56.6929 579.3371 null] >> endobj 2684 0 obj << /D [2677 0 R /XYZ 56.6929 507.6082 null] >> endobj 2676 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F54 1433 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2687 0 obj << /Length 2956 /Filter /FlateDecode >> stream xÚÍZQoÛ8~ϯp«1+‘¢DpÀ¥[d¯ÍæÖiwÝ>È–l •%×’’fýÍpHÚV˜&‹{¹äAÔˆ‡3¿¡†ð*ÉB‘ŧi3Fòt±9 OWðìÝIdúLl§Éa¯×·'¯Þ uš±,áÉéíò@—b¡RÑémñ9¸¸¹™^_^ý~6á2 ¦ìl"Ã0øpqýñâ=ÉnÎ2\¼›Îð6ÕvKÂàrú~:ûrûóÉôÖYthu 4çÛÉç/áiÆÿ|2‘)yz7!‹²ŒŸnNb)˜Œ…°’údvòo§ðà©~Õç)“Ч7pîsƒÌX"¸Ðn˜?œMDš›ükÕ¬¨Ý´Ídw© \ »®º+Iüm(wUÙÑMÞÐPaP~ß–‹Þ½Û·t5ï—îí¼éîË]wÜ«_·O{¿Î{RŸ“"Ý×õz¦>‰"–IÉõ<¨Û²Üíòº£õÃAðÚöërGÍ&ß”ÔêÊݘÜ®”e‚+­ë5ø„gqP”Ë|¨ûs쾌|)#XŽK€/À,zÓéÐáœ3Pc; Îõ~¼¼¡Æýºl°%œûQj<¡ÇQp».Iu|¨:J2&x"ŒîÉ­gø(fì©éÒnûªmhÍÚRõdÀ€ë€‚œ.·oŒ‹¶ip[c©¶†IÁTf™… ¼Bë("Xƒ5.]˜Ï£ˆ<–ÆÎPe4ö¹¯êšúÌÍ[ùз›¼¯zÙÍë5˜SÔaÙîH¼=ªŸÐ†á·¡ra+XÒ‰àqÐ ‹5‰róæŸmSú«ßAü.mýÊðâ÷·¿Â5"‰§ìúqL¥ZÁË«˜ nW1ö¯b"#>^Å4Òs‡Q0ëÇšœˆäù 7¼ÎÐÛ6èkž†&(@tus“H// µO¶í®g˜ü‘B Ù9&ÿÇsL(°…âˆÞÉqØ™#²ìgî'—ZÆÊfã¤"ay¢ÆnP*¨:º‚±¶AQBé@mlذ¦¢ìa[2KƇc¥ ÓPZ¿@7Ÿó–ª(3¹1gnÆÉ›²Æ }»jª?ÉÂGFüñ< Þ\_|˜ž“øzvnD¤Œó4;F’Ù/º#fWïLë_ÓÿœEQèÛ(À$4OÊ~xÊà7BU5-])œ&ªß%Ÿò ƒý«ú# yYøBƒ±É³Q¥±…ãléQô:u4tnìË·[í¹v»«ò¾4ÎÈ‹žù£/MÍ’N`ÿ¡*Uû ÔL‡ŽuÛ~í¨ƒÆI”i—âþÎé™ÞÊQöáwºÚÕÔ×¢3ZçCOý«¥±Ã瀫ÅÒaÚ §‘Šå{ÜçÆà‡ÆŒl±’SdĈŽÜc¶‘ÐÖ×M^˜íЀ€Â†ôLPHãìô%LÈâXÚ„Ñû™' ¥Ka 1T˜Ó¥h{ظ&ÄÛ&7æ²êNEAvuYiÍ^´5²¢¬«ME½gÐ*ÊR–†\'Ï6_TƒÓ,}:ã0¶Ùo\ fb›ä[hÜÜþJ‘o1'a«¿ZÒÓü‘JHlµ¦Ï$5µ´ÿàº@šØ`;¶ŒB]Ÿï ïÄ;‘ÜØ× ›9lÕÚ; p° á˜$š¡ÉàÌô eS3Ã[ólô86—m]·÷ã÷‰Q³3ÒÎʾhŒt|¢d+FdÒ“ýðˆ‹X&©Bªñ$±ÇTÛjézŸk$€¥¿ vZ¤­'¸%‡@cn4éë ™êZÏM˜I†ÕÚ ãÍH}–&±Í“ÉoþüçJÚÀ¼óî—ÙNÍýSj’cÁ€ÃðoÂÀXe’½À¶G›°°¬ÙCC"Ø$“ìǹ4‰”„i2 EZ"îÅ%zŒ:PÚ¥@l bo?èNšN$_£OÊ ï±V(*CÎå_ÑJP&‚ÚÀÆF ¶€3kµÉ ¢ý¼ª¦ÂOp'œš®4u%H:ì4ßXO[9æ ¶L2 õ£(Á* êc5òüž^%† ¤š^ùÐ2Q,J’ôùj;BEh‰ÊË%¦Ík¨»’è@jSS%–á–w Œ@÷Éé~Ÿ«H|O£Ìd=t2YýˆŽUëFNŎ°…,1ïX+SCé½08³_w¶¤vøvˆbˆß„r:éFïãO€ãšŠûâÞù?™w6ù÷j3lèBg(-ÖîŽqcke‡Lnúª·nz11ç!ã±Ûå&$“ #L@ÎЗuíÃȰÌGãð8b2[µMë­ ¦â4=(_pXØ c€Î8éè¶–µGÏ ø.¿÷$BÚb p}\Ž¸ÏƒÕ¼¸\M”ÜWýÚ¼`È6&”:έÙô×3)ƒOo±Ê¿¸zX#Sø“è~]a®×²E‡K‹®<ޝ¦Ýmì.ÚõÃüH{[ßÙ€˜—ëü®jÍQÃ_©É£$uñ°ñï@ÕQYt@'L•vp¥áîhv›rÓÚrrèò•å|X­aN"òUçp,™$w˜´CÆUxL’©Ä±Ös¦"5î Mñ¨áL¤.žÝŽ}Ì3&dj5A¼ð2äŒ)e]Ç §‡’'´}a}¸<Ÿž]ôàÏE®Oá<T—ËçøpÄ”tCÛµ…Ú­¯.F­ô#©ÖB ù½ê™3Ä%Ï Õ`e'À’TR¬^]^Ó‹³77¿èôòùA„Cý•ÅQLo-=sU€(¡zvªRç]•E¸Kh0‡L›UÝ“@…d$ˆÐê¿ÉÑùymŽàQ•qe” ™34xÒ [xh‡Ÿ ê\W_ËC“à:ìêÖy:Òš™8C“)d|'¶T™rpQ«Ož97&ç]‹ BÀìJ,ú}l =ý·¸0ulÇ}õဎI ¸PªMH›|÷áH”ÿ«ÏÄiœªÔŸt޹ À{""¾M¼¼š]¼~?õk,YÇöl¦lîè\¼m6%b:á.‡È×xÂ$! 5ÑDçiŸkŸëÍçá)Ä ¾T钤ơxFv&ÇiG:ÞÿÝVi?4ŒÑ+ƒ­‚«¿‚Ô»3 M÷ÜF,NC·´÷¼½z?y‚a„¯¯Ê~ñj§Yƒ_úF5ϦSšßÅûÙ/Ï#xQ­L#„ÉóýG¬…ûC3†Z(qcÂ>ËU¦•L™8›œ!¿¨ïl¶ UP ë×þã,4Fí},Ôo1á<¥Á4ð´qØŽ¶9`ïU‘ï7࡯jäè/ðÓCÓn»ª'›>ôqÀE$|_D"d\båêýh²P*lì5<Î,û±ÔvÚO?7~þ'Ûs;‰]+q­Ü{Š(`‘²ýÑÇbÝî&˪ö!O"Y*…­ÀÞ¹ïœàˆæááÖéUB)¬b·¯;•‹gU.êÜ«PÓ9—iN¡BÝBÄ©ô¨kàøõË5W®µq­­g4DœØñZD¬¿=5ˆñíYwìGxÌ2üî?Ò×?«oÿýå%ú¾¿(|úbÆ“±Kq.¶v|±í¿‚Ε?ë@°ÝuÑ ›1öå©ßB€<®÷¤bèÒÿþÄþ§ qÊöx!BÀH‘EÖ(œQ”ÿŒ$Oyðúêú’p Š 0brgå~lñxZÿ-Âéendstream endobj 2686 0 obj << /Type /Page /Contents 2687 0 R /Resources 2685 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2659 0 R >> endobj 2688 0 obj << /D [2686 0 R /XYZ 85.0394 794.5015 null] >> endobj 2689 0 obj << /D [2686 0 R /XYZ 85.0394 436.7863 null] >> endobj 2690 0 obj << /D [2686 0 R /XYZ 85.0394 329.3485 null] >> endobj 2691 0 obj << /D [2686 0 R /XYZ 85.0394 269.7313 null] >> endobj 926 0 obj << /D [2686 0 R /XYZ 85.0394 233.2856 null] >> endobj 2692 0 obj << /D [2686 0 R /XYZ 85.0394 201.18 null] >> endobj 2693 0 obj << /D [2686 0 R /XYZ 85.0394 166.5231 null] >> endobj 2694 0 obj << /D [2686 0 R /XYZ 85.0394 103.9841 null] >> endobj 2685 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R /F54 1433 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2697 0 obj << /Length 2854 /Filter /FlateDecode >> stream xÚ¥]sã¶ñÝ¿ÂOzæ„ÃIàòRçìdÜÞ9nì¤é$÷@‹”Å E*"eÇýõÝÅühû:ÏÅXì÷®Nœrø§qÂ+íij5‹¹ˆO—›~úkߟ³H‹1Ö·w'ï¿SæÔ2›Èäôn5:Ë0nŒ8½Ë.™bgp..?Yý|¶qóèüææòúâêœsÀ,ΣÏç×?"Ø âŸy{öåî'—w=EcªWHÎ'¿~á§9ÿΔ5ñéL8ÖÊÓ͉Ž‹µRRÜžü«?p´ê¶ÎqA§†im J3÷Ïa `‡ŒáœyF – ‘#cË%UÏH-ç°‘yQ=ž-`ѯ‹õ—CŽ(8Ù$ê4ÕœÅr^Ž_KÛèˆWh X‡´=¾L›L žþÚFG¼B[À: í}±{n¶cìËÙBÈæ@õûï$"˜c‰rµe<&U¾¸¼ýøãÕÍÝÕ×=òp9àJ¸?v¸–°Æ$JÉT* `#Òo<æÍ&+kPxD—uWvÏ8Ž£OMóû~Kð¿Ñçg´‡¬*ó¬+›6 B-[ZÏèÓ5ME «fG ¶¨ó²~ ÉÅõ--ãÛË"l®s<ú=ŽºuA »3a¢¢ÝW]ûŸö¯Yô<ƒGí[Ú L[ǃ6ÛøQYwÅ®Î*šù³›ê±Ø„è§§ñðªy(—¥‘ƒ-°BiÏâ.Ìg¡8³V¥‹Í´&e–§  b¢O3‚U . ‚}*+x˜’ÒqžF]Cß ?*j·Å²üsYøõÚ±†öìv8¨–Ã-Šœö©þÜUÑ-×~S¸ÓóΟ뤀â6œØvávÀʾñRõO™Hµ[£– ›€à–Õ>/üÌ)l5»ò¡tòDðÁ r–v&„ˆÞøxµûûQên@(éÜÔ½ «¦ªš'¼>ÿ|ICÔü^P-×`G­?9€áÓW oƒu¸CnÿyùŸž4Xº¸¥/)!úØÕ?nÙ¸oîOC‚ñ /Î]nFPG ›­t»3ÆÒMˆ‰‘˜ÛË4~좣¼êhoÞíô}ä¢ê”H£m±ƒ781Q –§œ‰è± Hon{<­”Žî÷~s[nöhMKSRØp_¬³Ç E0¾¿-Öp< E´ßÐ+2 -Ñcqù°§»s‚®è4ž=#³‰?;Øû”‘ `‘õ{±·÷[t¦i F»ÊÀo¡tMPÿvÛÔ­Ó…ÄD0ÂV“Ó484@»ß—U·p’LG¢‚ñHšx\½\7»––H´©·„¸Ëš¦£Ù›º Œ¿I©þãý{´0MÜI3R'Å2ººýˆÑS†À IÖ–¹ÇtŠPév\ ·çààÐXÙ.)ùC ô0qôãXûq/±¯Ûïj'Y€Ü?ÏøT•@žÅ!‡âoøR-mðà½hðÔ¢„ÇîˆòÕ¾ªžÉe)N_Y5«9$G‘TôT ÂVd28hË ¨R]­8æÎWYY98™‡n«¬!5~³—7íÚ/u;ÕÚ$¹ÓÜꃭ;Ûî»oæ Ããˆ"y´%ýZmKË̯ÜûÝ.[Ò•Ü_)@éÞ/£o‹e¶o‹¹øªãÚ˜7D(Y"EÀi Oˆgvˆ÷Õ3á™'¥ø³Ï ¼ˆ#¼ /Úí¼ì%èT’X3µ‰™Ô¦gÎ^ƒ’Ó"~SÏmˆ/€'çq!ʺXþîAkåŽô‰š!iÔ§UæÈ½ÀZéï)êÇ’„So îµ}Z ÈU³tO‡—̈žXÒ’ÜdÏ4 îÆ^̘vy§ôÔìº5ÅÞY7ùS]‘®ð„xƒ_7ǸVåq,á!»aFŸ>—YÒœRÜíešýnN—xÂŒÒɺ‡Rh’Z9zE†‰^çdÁƒ§EÊzFÁ¢29|^M7M e ç"èö{ȨÞï\VÊ‚ŸÌ©¦º¡m5ïÆ,V§!Å„È-cVƒ¬ð‹Á²…‚ÆAÑqœå¹×£–R¢xp„¸Õìë|Ž§Â•©R¿ÉS“$–uN£Q2¦}2‡d/&]7m÷"±L„L‡?ªͤ0éT•W!±¿ºyÔïhøáƒèC|¿˜Pü™Q߯ ´/%W¥R ‘͆¢&«ÒÅWöÁö`Ñ]€ß-úÏvŒWÐÊCùXÔ³Ú«-SüMí•Lj>e5ÛghîBO¿s!0& U °O Lj®äP£SÁb üh)úž…/Vº„{{õùæÓ%±þ§Ûóï/gvPðž{—ó¼-—¡ª+ëGP˜`ެ斣ÑIõ&µˆƒebNã½_Uþ^|˜±ex»CàñLùæÚæ†òX8‚3÷/bpBi2U¼Þq8êPùŽ…4Ô¯¶5ÆXÔÖ°3mkˆ‡×ZÉâØèׯ HÇ×N^lS+›N¯uQÁ„‚’ ïêäôÔ ©úôhp aõâÞ!Ä[ 3êEÌI¬îÖávŸÏX tÆ'†|È ·—%o: ²RÕ\N=RÁlƒ*¬¬‹©!Y6Ö½¡™Ÿ£[òñ}(=ʲ©šzjWnJª¶G§ÂËRi½ClJå£Ýo·UZ±'Ñ À4ÒÛ  ‡*Û#NüÀØ RÔ,ÛQ4#ôë(šÙèÂA¤Ž¿"b‹þz;!§XgÝa¦p_¬šÞír @ÏTx¹€žybr ·ŽÞ˜Z`žðTŒóà€â,µqr˜Bg]èP•mpZeWV…..øv“æ†X<.d'5ùà~€š¥)ͦqY‚ÉšÏÞ¨f‚ÜBHØ&“Ÿƒ „’.8V ˆ ê³·4]½é«°©BàÙeK­%_H¯Æ¥q¢ŽêjÚéºBœRc3jÅᄼ™‘½7úw8κ€F#z°«ÊëŠM3·8nVÃñÇœ’F1Йä-ôœÒÁ“’8a³›Ëw%¦7æEòö)}–„éÍ&ä^%VPž[:µž»™Ø^Scù‡…üAúˆu>õ…`Í÷6 âkvCaEÍlD„J¶È®#,ßx…Ñ}JWÕ'àœíÄÂ¥‰¸’ïY"Ä´óðbÂÍ£ÇWä/> ĆxÚYƒV¡;j磌Û5Á¦Ô"hšq¥Ï_™[Ï%1"I˜åV¿žÄŒ±^Nbz¬Ðœ?¼Ôp–p¥^¿4 _:aº‰$:ÉôÒàç{Öæá˜8äc ÜC$.{¿}™W*fF«ø ^°^áUÀrÎÈ祳¼zíÒW‡—Îój|i –¶¤N0v§žÈ‰ÁÈQãš“ÔìÒ}É’ê¾»~(û–/n€&¥õóë¡éŽSÿýü‹@`sA.E·Õ;¿v¬M´ì£eŒÚwÀ0:<š½GOÀCCÍÏ%3ÂÒÄÌÏv=—9 a‡}›>ÍÅlöÉùŸÎy ¹˜6âÿ)œÇ3ÔŸèN޳Þ=dÞ4Îǿԅöïl1‰ ¦“8ž•?¸ŸN_ü1ôŸQaÞþ—èþ/ƒN™2FÎÃMî§„«ë â$cpñâ* ƒ2F"‘Çî€3© 3:~ÕÿÕ4káendstream endobj 2696 0 obj << /Type /Page /Contents 2697 0 R /Resources 2695 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2702 0 R >> endobj 2698 0 obj << /D [2696 0 R /XYZ 56.6929 794.5015 null] >> endobj 2699 0 obj << /D [2696 0 R /XYZ 56.6929 674.5835 null] >> endobj 2700 0 obj << /D [2696 0 R /XYZ 56.6929 377.0003 null] >> endobj 2701 0 obj << /D [2696 0 R /XYZ 56.6929 77.061 null] >> endobj 2695 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F21 1034 0 R /F22 1037 0 R /F49 1358 0 R /F54 1433 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2705 0 obj << /Length 3853 /Filter /FlateDecode >> stream xÚ¥koã¸ñ{~E€~¨ƒ]sù”¨ëH÷qM‹ô²í¸ëÅRamÉgÉɦ¿¾3œ¡,ٲݢ‘Ã19ΛT—þÔ¥wBšÌ^¦™N*w¹X]ÈËGûþB1Î<"͇Xørñî“ñ—™È\~yÌå…ô^]~)~š]ßÞ~üüáæŸWsíä죸š;)g½þü÷ë¿ìö*Ó³ëï?Þa7 HÑ9ûðñ/8ø«}ùÓÅÇ/=ECª•4HÎ/?ýK^@üŸ.¤0™w—/БBe™¾\]Xg„³ÆDÈòâîâoý„ƒÑðÓ).Xç…Ó6¹œ+|sLòJ é`ïóÔe"1Úô¼ÒjŠW y5Ïq£ï>%v€©¤H}æ`vDÉëÅS³™?TËrŸ)*QÂy˜j¸ò}=Öz¸l’—˜dLáݺ\T?K©Ëöj®23ËñcgŠèas¥ü¬YQïå©Z<R×(Œ—yAПïî>¾§‘nsågÛ¶ã¹Ã^[©Ù—§’~P”ùvÉ8UK,³CÚÒB‡Ó D¿+»Å»ûª.âÂñ%ÎOfÀ %2çtÀúZ¾ò\#>h#2%-Oõh1.nJ…ÀWϪz±ÜeAЗª{"øn> XFŸ¼.hdÑÔ]^Õ-w[Ç1Øú•šáî©ÿÐl ¹€brÓøßM]RëgéäÏZ[ÿ £â„LϤÃLq‡#nÜܽ'íŒÇƒíeÓ|ÍÛª(©ûœ/«"益¦>­HD±|¾RJÍDÕ.DH~ŒtÑaHXNÃ)–ý3·òòŽZECߺaÀ*ï÷VI; ößl>—9<'¹âIóUÉ+æ$—Ô©k¢·,~s57*,Õò ˆ É$þΩ¥Þ"¯iü¾ì÷XJ–°y.7›ª(Jf×¶­êGjòYì‰qæ„RZ±è½fþîóõ_?N©K„ö>cL üp2 Ä'.Êñ› ðêØl hO’D‹Ó¬ñ„[Ö­pFgãcûÜtåw°/g?>áþT<Pó°KK N‚zñ8°Mvä-54˜*3„Ö—¨*J­ m…]*YÖ1 Ý”‘Љ榌ºÊëü±,æG¬@j`qÜvyW®ÊºkãЉ’šÖõ´À†/F)Êi?VÃáJÚe3нº«®PÖ–ËWÒ-O“€y ú‚8-Z)ðž¤êÉéÃ{ÄŽ2Œ?¸`Æ:W¼ÐN"åg h™Ï"ªºêª|9u€gl<Ò—0k¾¿‹BP3èÙŸÞÓÄŠZøs>¦JïY*Úòõ4 3åÈ\  Ý®×ÍVSbe•§Îˆ•2íÀKµ\ÒÔ¼†C[ÞŸ„Ð çØ UÀs™ßçm?^€g‚ýû× ÁcC¸¡!Y4=Å©FŠ,3QM@8l’p®H3[•yÍM: lUô-Ák•j7«¤oÑë)ûâ5V½êí|î÷‰H%!KOM ûÜ| ,‘†üV?Ò,—q­éUjQ~éw,"Y&|–ìùv:1´´÷ì¡êrQ¶m¾yeܰM^à MÙb¥a{^êÿa{*M¢¢ôÓ·å¡WÝw£‘½c9Õ™€m§§åTAS÷La3Ǧ‰L…5Î`‡XÇØ+°÷S,ØäÌÅ`,/Š pþ x5^¤iêOÓÖcM7âƒ5¤Õ#êîÊ`F½ã°m³ ‚µ};»¹%8RD±å_ :Œ~ù˶ ƒ°†víF» Îf‡ÛÞ£ ·F VYVXœ|E1!´îyåœ>Al&©µ³ JHuc<ˆúS0÷cµ ·QÇ-œm÷k h°[—ÝK³ùJ0Uåæ!_”<ذ¡ÀxN‚œ ‰Øe Ý"B¾û.Ĥ°¹TÍ®kž!Dù’zãÀ>Úl¶Yù+îy¨í³‚^§®|½.뢲‚_Ѩ¡$'5+Êço§¼¿H­ªè:œÂ!H)âqÿþÜ,MGÔŽËŸÉ/‡XÇÕ³Ç ê¹˜Î/!/ˆaÊb™O('}Êyš²k‚´‘r‚‹RVª1m¤œF§,Ð`Ã&‘š!ªá‘ì6†B?‹5«fï·B¨»eò›€r,gÇs¹ùÌB ýŠá}Áà)m¼N¥ö´ž[éQÝX)AsL²Ojȳ‹Ø²ç Ài” µóN².Qgi€uB"V¤â¬_–ÏåòPeý$e=ÖicA‚åi Ghûb¦ìõ¬}¹X½PÚ Ey¿}¤!"’Л)¯ï¬0(ª{{Ú!æði60áÒQ½g†H½y a7¬¸ÉëG†“…׃z B%CÄ]gö¦ëˈFå°ï¼OÆ"…SY’ñ§³†öþ&‘2p0žéìC„J·!?íI›H<°Æës³FþE™¸/ͪ¤©WMŸnâÌÝ7-å-SòÄ€xbvwbÃÐçwmÙ§§À‡Tï§wey*Ï6F¸´­Þ¬Îzê·3YÈŽ”ésìÿv"Öû©$œ¦1½×xó|tJÄë÷À9{ yAþ¨É¡Äˆ¡ŠÎûÅ@BÒ’e{Ô°XçÀi€©?iX†XÇ K ËÓþ’™ÖÚ3KF¤‰%G•LXíö–üPµëeþº' #R¤VÚ³¢nÁý1ÒS¹\ǘ?dñk¶ÝzÛíŽ;4ÊoUwœÑpþ )ç=À:Áèˆ]0Z‰$µöô’ibÉ£‘8—Ž—¼©Ûr±íµ>ÍÀ%¡,‰oêgEÕæ÷Ë`%D$¦ÐëÓ&ÀÛ¥M<Ú9,D¡>ùbÙ—r—#"¤ã5²YÑÄù©¨ÓµÁo¤[h¼ÿlŠ2Bg`ÂFå>ÔK GÚðÝ®ÛXmZ£— SˆPoÊõ[ˆaËÍspïãZÒ¼þWu¨¶ ¡0ÞÍfÕ#õl€öŽ ¡6Â"¦)Ҳ߉ø˜ª’kÉe·ÝÔÔ¯jN.°ƒ¡–@µg"0”:©9íT¹N£CÒgu&3Ö ²dœ³«V%µ@aB#á²b މޤ 2ùðcž¤ü–ÃÊñ†‚P(„–{ñns\ ˆ^•õ0k_“kI]½Ý%÷ÓŒpi§|³˜¬Þð :"‹P¿?bŒK1Ç5§MÃë¸i豂iX˜†The’ÓKF¤‰%G!•Ä:äÅ£5?ÖQç5«‚ƒ×ëÙû¨£ÖÒ`ÙÑés,``IÄ ,YŸw1;øÕÑx÷$e»x÷´©xwDÚèFÎH²ŠŸ²¡ªæ²b>íYEÜ0:Ymƒ¸_[•ì‘ò.ëàÔ~|»ô# ›ÁÂäó ÊP@Ó¸ (’ xØáë½8ïÔ”ÇzI¬¼ÄSÑ{·vAG)Æ^‰Pv/٠Ξ.Ä÷…L )w‡õîŒÓKc°µº¯·Xõ&ļÿÍ 1Å»ù×u ËSàÈ•šaé$Â1{ˆƒè€×x—⟊JŽ—Èó©p„ØåÀ.­ñË‘ø  ……™ºÅÿ8¯ïoâ}AÖÑî}Uµ!€\s„Sò8Z‚Ñ ¸9j}¾{K`[ï÷žççÑBfý•À±pe4y¸Çmx&¦ËÖ¯ž¿¡I¬é•nÛ5+8iz^œ0±øØR/äÚš5€@œó˜é=9„úÕ×ÉĘ–A4Äk“a÷ʈc¯¼ø˜wB×eüß/ÀwÜm l;vy ¹Œ0&S‘¨°Ä€V9ä Çw`T!‚"æ··üÎx|€Nlë?Û³^endstream endobj 2704 0 obj << /Type /Page /Contents 2705 0 R /Resources 2703 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2702 0 R >> endobj 2706 0 obj << /D [2704 0 R /XYZ 85.0394 794.5015 null] >> endobj 2703 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F64 1485 0 R /F22 1037 0 R /F42 1338 0 R /F40 1265 0 R /F54 1433 0 R /F11 1559 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2709 0 obj << /Length 2923 /Filter /FlateDecode >> stream xÚÍZQoã6~ϯ𣃫U’%±À=¤»Ùb‹m6ݸ‡;ìîƒl˱Yr-9AþýÍpHŠ’%¸+?ˆ9äÌðãGÊ|ÆàÇg2b%Ô,QQ —³õþŠÍ¡î—+ntViáký¼¼úñC˜ÎT bÏ–[¯¯4`iÊgËÍ×ùm×Л¿¿ýt­Äü× !Éæ7÷÷·wï?þßècóßnîþ¸ùD²{Ô¿ùåöáúûò׫ۥ‘?jÎBΟW_¿³Ùÿë B•ÊÙ ¼°€+%fû«H†ŒÂÐJÊ«‡«ß]‡^­n:êÎÆbÄ ‘ðÜò@*%g‰TAŠP»ÚÕ"ÛlŽAvî³–bvª6ù‘ŠzÀXøx7_(š$ÙÔû¬¨‚³¸ò á<ž%< )£‰8ÒÂ×Òa|,­Žt MÆQ O/›´J#&ýÆPLBÞ7ù¡Ö®^ƒç)èþ CÄQdƒ¾ÉËç‘Ì"ˆ¸´Jhta]•¯Æåóós4éÓ8M‚4 “Ë>õµ¦}ê´´Oã)Ÿ^4é|znŗ=“ÿ[ŸÆ³â²~ ㎃0b0P€A÷ôû·_®¥œÿ‹Z¾_~ü|÷02J6[í·F™ªÄŒò ']?\Å¢ó é¼:íW´è’y½%™ -:´E]™&/»b½#•l‹ýmóuKUf½¦ó—Ì´4¨q*[kЪmŠæPf¯ùæ|W„Y¨UT¤ÐÔûœ$묡XÁ¬Íœzâ Â˜f“N‡†^<³l~È8ùF‡ ËMű¤ý&ÓÓã‰óúL{€ÄEC2ðbÕß}X³2Ú½>å¯/”g’“ÿóu¾™hq(O¦ó¦x4æ¾1É(²½M"dqÆ©MÀ¿_Bâ'±Q€n8àºPjþ@^+Þ²»…™ñ‘&‚VœU„‹ â¨r“6#çË]®×‹æ{&ç+#xk^©† ‚¦=âr>s›§ S›ÔU=2uÂÊ‘¿:¡ï*ÌZÓ½±c˳JïT(ÕɯG¡·#x.2óú M¤Öó%'Kapœ[¿ÐêÌŠ'xmþœ•'½‰òö\¹†Â²xÊIL6Š}^ŸZª/ª6?B/0œH%èæWªØeÏÆ˜çcÉÃã IĘä¡ylþ®Ç6âÎ4 â4¶êa²KëDO?b,ˆ9šý¥øÓÔ6#ChÉ™¸¼ÍøZÄ ÔÈ6ã´ô,¿Võ÷õf[fCÛ1%ŠÃËÆÖ¹õ~ò‰$ˆD’ôÍ¿««–ð·Ä@Ë4§T ;kꕆŠ!Ô¼{O‚õ._?¯ àgÄjƒk›tW…iŠOŒM¡ÓMââ®Lõêul߃}ˆ©8¹¼ñq( éåB o¹+š.€ÿö⯗˜†zù‡i„›ãöT’ ¼PQɸçSjvuÝÒ¶ƒJ~¤,<6¶sNÉÛ¬('9u$áü'ê2ØùZÓ`ç´:°+aã9Ã:Àþ‰ÃEÛNëÜøëxÁQ¶o½u"ò°ND’R#Š-ÿ£r%Ô¾ûtóðàZUT:0Ù oiÑmÏ!S´-éÞókX™^Iø^˜¡ ­ŸQ€ZLNJ=¤é ÀÃ/ǰSºB£ä"ضåYüXH^6ë”Îìö£ÇT©¨ox<•zÁƒí>•zÁSæj Ëå'צ¢’:ELg¡ƒü1¡Ã¾s7xÑqSjÚ0/8Ý©!ñ€ÑLF-L€ªðè žákMÇÍi¹ÀÛc¶Î'yÆEãÏ8³>Î3zæ—xKR?>–š>ˆáŽ%aMä-q°²E îâ\Ò.î5Bœk¨a#b^e{S¢&¬£;$!}Ægž‘@hÙ‡gA*RÞà4ʧQÄ Êk°U¡ÍBGàxß@ózx®³ãñÕä"HOí ¡sÖÉœ÷@Fà¯:a+<+?ÁÄbXa Õº<Ñ1Û½™ãŒ>ÁêÑ€MÃR@L2Ülãî 4ez'IsZ59h cñ½Û°cb”(ÜÖeY¿ìÝÝÍo·Í ;«˜7-ÐÉ¢Ù™zª]ï2í_ÙÖ48^ãý^;F˜4AÌ´¤ÍÛ]õÙ°wä¦;“w¡œÓ†òç©xøÎJJš`UKcð…Ò2D°_úé‘ÞJ I¥Ñ0Í8Õh^Ü5”óo@ü%‚ïTcÖµ[7x¬!ø–¾–¡ÒÃ3@4pGóÚ´ùþ¥Øä†²ç+=H)Ý eìÈ?§‡½:•Òv;<'i ³gûÅfŒ§K€ve‰½ÀÐçb¬Ð»ÉàÍiÝ?t@f™eã"9è£'èãdujûÝÄþ=Îo<¡Ã©§4;ˆ¾™1ŽÅãXÊZ¤Zæù’—%ÝYLà·ˆE ó¸ˆß¾Ö4~;-‡ßûËø}Ñx‡ßgÖÇñ»g¾‡ßÀgö/Ù£yéð:J»n@Þ27’ŒÄ?õÝ<¾ö*i¤†' =&î‹ÖyñlÛÿ%Àí]›Z–ìˆV¸ñBukÓÄ7JOCþ}Ü>kïwßJÐÝ)â°z7Ë¥äfF°d0©£$ÊÃ$fǤ”]ëX´k1׆3zÒáÍoç ˆE‡lý”·%PÛC”K£@Ûš‹"G³‘³`·Óô Û"y‡ÅÔ²»TõÐ +ì ¡hf¨Õkzê¦îKíiì.SLquÎ"H2)p†}šƒišú« gˆ”Å“hÎÙ>w u°9å@NÃuŽÙÔ»ìf= !¨+¿ñÍÊך4§åíù2 ]4ÞÚ™õq@ë™ïZ5⻇i1s˜ÆæÍ®~i¼¥{0§·Z €PÍÓ7¶ìËŒž¾qaútžë>æ–` ÉöEecÙ„4¼ØgóbeEã!޽=À»_ó?oö^-[2·"£_$ŒKDH8$D‡PNßnC‡„½©åP´8„Õ¦MH‚!¿™+ ˆ8G ±"l¤?l³©š&_¿ A!OÎé=zÅí·kü@á*î «ìäxjnÍ=9Þ}‹æÉ$¿¹Jß Tœ§ñPAŸö p€@ž9B ¦ƒêÿ)X¿—ÈSšÆ«äà󱼊ºd¸»‰Z¿ˆòMßw<+ mÈöó¬Y½t Œw¨KK)ºKoaÛ½úRcÀAz@Põ ÂV¼ª­Iü(3ý•]¡xƒÔv:Ó0:Ý]`½ß^œ_†Qá_Q.v:C˃on*>}Ó>ö÷|Õ]âø$ÆhRºƒÝ3šH‹å? ˜uE0õ¯ Pâ]ñ˜+˜û€ÿ_ÿc¨ûST”€ßÒ‰KžÁ˜Ð©?¼{O3QË{@d.E"æ<ŽÎËüëè|Vÿboz endstream endobj 2708 0 obj << /Type /Page /Contents 2709 0 R /Resources 2707 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2702 0 R >> endobj 2710 0 obj << /D [2708 0 R /XYZ 56.6929 794.5015 null] >> endobj 2711 0 obj << /D [2708 0 R /XYZ 56.6929 643.3859 null] >> endobj 2707 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F22 1037 0 R /F21 1034 0 R /F49 1358 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2714 0 obj << /Length 2820 /Filter /FlateDecode >> stream xÚ­ZÝsÛ8Ï_áGe«ü–ôЇî6ÝÉ^·í5¹íݤ}Pl%ÖT–¼–lî¯?€ ©ËÎÍÝNgJ‚~èðƒ|–ê˜ÉLÍ’LÅšq=[¬ÏØìÞýrÆÏÜ3Íû\?Ýœ½~/ÓYgF˜ÙÍ}OV³4å³›åmôöóçËï®þy>šE—ñù\3ýööã?Þ~ ÚçóLDo¹¼Æib™$²½»ü€/?ÿ~óëÙåM°¨o5gÍùãìö;›-Áø_ÏX,³TÏž`Âbžeb¶>SZÆZIé)ÕÙõÙ߃ÀÞ[ûéÔ.(ÆZ(3›k§F'Ó{Åb¦aíóD¦±‘: {¥²©½ò\¸W¯nëæûv»hÖë¢ÞµãUóDÅ “|Ö}`@à:´@ˆž<Éb“*=4á÷»yx¨Šó¹„Ø­ì–e»©òg¢6÷4nŠí9O£¹ý¿X4v\Ò»° ûyYäˆýn³ßÑó7¦Ù=|l9‹?óõ¦*.`–¦Ñj¿Îë9îÄln²lÕ°DgZ k0©Î—ùšŒþô£x¦‡²¡ë|W65ò»Uâã»×»ü=­oÁþ'9‹nVN沸Ï÷•û¶liÜ54n¶eí^Û|ç7$>ðfç2&“q"Òì´_õ¹ŽûUà ~µØ>oÀâ±Oi'™HO+\‡Ú‡>‘‘$ŠÕ|J)çJ÷| ¨Ö§`$;¶ùfU.ˆïc¢¨–-1XW‚Žðúògâ!ÂG&éø¬Ì¦Þ9_ š4ÚÑäZ "Zàîö]Ë©…Ó:ÊIMöu],Š¶Í·ÏD°®ã²¸Û?ÐãºiÑ)Dg(Róª\z—„ù}^V{Ý:EµÓHÔuóXÖN$¼vÂóž¿ÜÑXä-Å ó« .Á%çDYyµEáÖ»‚ži bß Œæ£76D|d£ ˆM»ÃÄ—;ÿ‰?:'êëªpzšu¹ÛËÀþLän›LÏ uŒƒ¥ÑÝáGÒ8mRGínK›Äo°õ·NËwœaGô"üÄ}k:D€çEÞ#Ñ„*øáÒ-nÝv)À—·ƒMþHBü`·ÄÙ9µºÇ€¼¡\hï`É®ë8žpÒŒyOz\'ðÄs<Ùm÷ààc8Q*N9,à¤îÀu¨|' ?3z¨ýgf»©M…&ÑÓª€íÞÒýÇ\h‘¶çi„†ÛìREdÔôdáܺÎr†G—îðuùÀÀIÙ’pÛÙ\fqªÙ(muÑ¢]R´Á:œY뎞®6Pe©ì…*¤ÏuütW8]°®Üݾùúýà„5ڜָ !'˜É†\£rØ%£ª±ñ¬D´*þœ͆0Œw¥FÍ)É–µKø• s :DkÚEŸÒáôúx±Ú×?’ìÄë÷ZõÌ—RÅ‚I ‹F»¿Ë`…)”ƽ_¬Þ\=£˜‰¡üQC¼Î»bë* ,ŒžV…ÃÄCý†Ç"KøIõ*á™cð… EϾ^Ú=Ó<Úo†sHÕ…dï“kpórãK-̤Ȧ¨f:4g`¡Nÿ«º±~5a'’k¿8 Yªî̳¼²’Þ°e-ò}[„ýt¾A Î͈FfÝ솛qçÛ:¯ÄBÒUõ_UŠÚ¸€Î÷Âmà–F¥Æ 4'T _•µS³n–ÅP|V>ÇáÖÈÓ$}.z\'àÂs¸€8 )à¼Ø šסê!PÈ$Né¾.s9eu8óhQ¡ÃZA>7½D€Œ¬½Zò5L6à)ó±J5s¯”$\©ç¾˜%%c¼/nØÚ#Ú1ý´8—RØbðP²Ñ\¨¾èGR¡¥Jqƒ³¡“çÞihxpˆ°9ê>ʘX¤ì…Þ¤ÏuÜ}W°¾sîcÙæ¤þ.Û0m|ví›I}¶§ÃÌ`R Çí~±¢™ÝC“E_¾\_ýrA4WDrÎ#G¡r®?½ÐI/l®ÂOhx,¶w­CA‰Ý!ßÃ*NÔAƒTåCz~*w+ªK©‘uËRõºR¨FµÃ1 w8ªuA"ó/ŠÜî<ô¼@k\•Ó´…²Ê+Fƒ]1ì*¥QãrŸ/À'vùÎCh ø·É·-•ú! QÚ¢àƒÀ˜™O‚Ë¢zœ!bŵ?º8 ,î—:õ>׉hð\!–uÛ‹£úIå]§~ }ºS¨¿ª—å6Üzv¯®ÆÐÙ›^]DëûDŸˆ˜Ä¹´9r2BÈXé¹ÇO¶ÓŒNÆ^‘·‚üÎ[ à8’ÅðÒYÞ61Ȱ”'þõ´ÛQ?)Eü¾®Êî ¬çp‹•ʤ_Eù0±®âLIïƒ.æ­*k-¨Z6…OK¬÷¡Â˹Ìc='ÂM̵I|ÁÓõG¤£;ÆÔµë©ï­ÿØSe„pK^öϾ´µÊP\šž0HË™†°»í(Â}ËÚÞ̘Sw7D ÷vR=åÏö…éÛ],1K8ZŒEÆþí Οʪ‹ÐQ³Xì·$ ζhÛ©î»Ýo6®ôm ×€ßûµ}Û–*¿órÚ-”êPg;)/›UWBo›I'€žZJé`ºpàY,uÒ“µœŒ8iï·}Ws¥b1”n/t }®ã(¸ºb –yûæË§O7‡=(7)KN[¸MžØ`Œš0@BÑGBápEàe/æZš@Ô=B×Ë+¢ vÔM=¯šæGÞ–ËÂgzÑÅš‘=Ÿ½ PJ™î†õZí:µÒ¥º¶¹ B»)¥íkÚqݓÏ9M‡· y½Xã%*²­Œð­ Ÿjex芺ж d—ŒO)éYÃíÅWl/æ&’?n­Äß„6»èüwSÛ­´Å‹ìHZ•¶6Ýô¯kKµJÃݾ¬vóÒÝÀâ5Ök¶ÑÕ=‘í¾Þ?‡»W÷íoIüÚÙÔ[­½Âõ[êlÜawŽ217¡ŸçÓÁ³Ô·kWå‡ËƒÑµÒ]LËaëÖ3(ûÑm|+Y#/ëpŒãºý9"áq‚?$„>×q\]1T=Þ¾y÷á÷ãQ'õw­ÁÓ­ÁÀ‚> hÝCí®üaìP&!°á9Ä=MÏyÔ uü­Ó‡µva­|X'ã°Ö¾‚:¨þ)\|¬k]þþMr?¡’”^TêQèCÜÜøz¡ïnº­x°J3ü}^` ™`¼  ØþJØ… LSÖËvS¡ð€tÌÿ\ ¯ƒ|ìANí¥,³žC8ëA€‚ªòÊiîC@ïÛ @2Á!è±pOÒ˜+m^÷L)Õw2¸ð—É2·~a°÷œeù¶æ Zï!žÀRfŒýíLê”.dÞ_}¸¼žX:âJ2øu±[¼¾+ëe *Bõ%XœáeàØmS=Æ`ìý”l¨úúò’Ì~ûáúÓÄÎM€*S ÷‰DÓ.‘˜ñ°ÇóÓÆú_Þÿ¬˜TSõ`ŽVzt74¨êcÀô¡ ý×R’¤^¤:Aš%êÔ³HC«ùâÒâcá¥(þYÆ´³à ÿ÷_t࢒X¦©˜Î’a‰qoÎ>‡¦[$"úéêã;ò¤,æ`Äü³¯Jêu*’‰eýþŠÃƒendstream endobj 2713 0 obj << /Type /Page /Contents 2714 0 R /Resources 2712 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2702 0 R >> endobj 2715 0 obj << /D [2713 0 R /XYZ 85.0394 794.5015 null] >> endobj 2716 0 obj << /D [2713 0 R /XYZ 85.0394 181.8996 null] >> endobj 2717 0 obj << /D [2713 0 R /XYZ 85.0394 86.1024 null] >> endobj 2712 0 obj << /Font << /F38 1122 0 R /F49 1358 0 R /F22 1037 0 R /F54 1433 0 R /F42 1338 0 R /F21 1034 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2720 0 obj << /Length 1524 /Filter /FlateDecode >> stream xÚíXKsÛ6¾ëWðj&Bñ&Ø›#)‰ÇvC%ÓNœ+Q2'éŠtZ÷×wA€4øÔ‰{ìxÆÅâÃî·‹ˆ‡áxB"ÒÐ BŽ&Â[íGØÛÂØ›±2“ZhâJ½ZŽ~zÍ”¢PRé-7Ž.…°RÄ[®¿øsÄÑ4`vEóédúv>}?‹ÆEý‹››ùÕlñëxBiÅØÿpqõéâÒôÝŒC{3Æ_—ïFóeƒËÅN0Ó þ}ùн5láÝ#*áý ‘0¤Þ~ÄC‚3V÷ìFÑè—F¡3ZM´Áˆ2IŒA‰G8b]kˆQÐÚ°q ;\gE‘¬&«»dõm]è­þ “HP¡*Ù«xŸè~PL+k) 0•ÑØÑSYì–ÒÀ´.Ì1½i¯“]²Ë4ÏÌ÷*ÏŠ´(“lõh;´ª4Ûš¯2ÏwÈ€ý Ak!bRÑc–߃¢®“A’Ìô3 •À±8 ‘ÞÄUQœÓö5RCÖ‘`ù/“ÙàÎtBÀ÷׫Vó}œfF®µ HI!¬Ø×Zåf@e[t“î’}”¡P“·£o}Vß:Ýáû¸¼P̤(ºŠgç›C¾ÿ–<žT¯’ |ßRÿwž%G €%RŒ¨çÀQq‚µ”C€ÎžŽP€ ˆ¾ýO£€ÎaBá°hr ÖÄè&‘ å(ÄR¶sÉlM?.n–‹ë«fR+Bˆ+m±ï'Ì€#J¥²0¿'‡ôcš@6¬~y—膂Òâ]º6*+ÃÕ0[v«t_jéÏf’ Ì"¨«Äí…]èßú$Øh0º¾´]©Íû±ù)î“•1ÈÚthWý›„]ù§(Û`åL!I;Ñ®T}†ö#º‘ÒëÖq&]ú†ÀD&;aæÂ áÔV`Ý“°j¡X.¡BÀQ¤ kLÜfí WJõ²@K«æ4•õÒ¨sÜ󸃙&lfÆ*êRàF]UW=Í!^›¯Mõ™ïty—¦_ëÝÙ™enFu_¶n-À4•ßÏsU7<ƒ‚ ì`·Oý,/_>‹…Š·él±ë²â.iJ£ú,…›)v»šÃf†ùØAŒÕ$~¸o“Ý]£,ÇòPf¬#tœ°µPÅ×Ý _á° z‹Š`¤†‚ä¬F¨«E@8¥„„ï›êŒ©ó56ÖØüØ”c>Ú^1}if~mö¤í4¢;vnÆ£v@aN•ŸŽ‰ŸAÉW²ÌfYêTžƒ "C,8¥±¦’I~ Hhhâ¼(LûÞr'+«ë‰ò_W˱ÀOþŠ÷÷»D‡›ª¸Ðò+k-h`Ðx2|ôÈÛ…’œ[Åh•ïõ§Y­²…i.¢é‹æ&àn®Y§fÿKËò"ùyà€”š]˜×ì¸ 'Í]`÷}LñQZ¬P~°%¿ƒóh¨pŒ8 Ä™Xq¤NK-UEËz ZÀ*ìXÕÓŠ"Ç*<°‘€ØŠJà&ˆicÔp½h¥{iªúÞQ!‚{¦t6Ó? ôÁx]ýžfñáÑ8 ˜B°ÿ©¨ÝSvLŠBçxrÃp •Á™óØ•:á±ZªòØlÈcúFœ®&[nŽHINÃl¤p¶ÌWn.ÞúŸº­{­èûPU™Vþ¨û•r 6Ó¹vÏçö¦]¿ Ë·) »®1•®.mV±20²M²#ƒÔ¿:9Ãç+Æ‹OË·×σ\derÈ’Ò¬=ÂI±·.›æY‘Êôaÿ´ÞÓ“ èá rûØ":-9Tÿñ6yþkK­¨óÜR%Ùºny(ÜòÄ-tÚóÿÇN}sä­ îi|¸zÅåŸýöôà7H¦³&mŸW‹«™ÙœA°ðäF¿w PŸHÙÏMö-­¿«êøîlendstream endobj 2719 0 obj << /Type /Page /Contents 2720 0 R /Resources 2718 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2702 0 R >> endobj 2721 0 obj << /D [2719 0 R /XYZ 56.6929 794.5015 null] >> endobj 930 0 obj << /D [2719 0 R /XYZ 56.6929 769.5949 null] >> endobj 2722 0 obj << /D [2719 0 R /XYZ 56.6929 747.6859 null] >> endobj 2723 0 obj << /D [2719 0 R /XYZ 56.6929 711.1601 null] >> endobj 2724 0 obj << /D [2719 0 R /XYZ 56.6929 642.0618 null] >> endobj 2725 0 obj << /D [2719 0 R /XYZ 56.6929 547.69 null] >> endobj 2726 0 obj << /D [2719 0 R /XYZ 56.6929 469.5583 null] >> endobj 2727 0 obj << /D [2719 0 R /XYZ 56.6929 262.0807 null] >> endobj 2728 0 obj << /D [2719 0 R /XYZ 56.6929 195.9042 null] >> endobj 934 0 obj << /D [2719 0 R /XYZ 56.6929 154.7681 null] >> endobj 2729 0 obj << /D [2719 0 R /XYZ 56.6929 117.2358 null] >> endobj 2730 0 obj << /D [2719 0 R /XYZ 56.6929 84.2678 null] >> endobj 2718 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F54 1433 0 R /F64 1485 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2733 0 obj << /Length 3190 /Filter /FlateDecode >> stream xÚå]sÛFîÝ¿Âo‘g*v?¸K²}J·“¶—äbßõnÚ¤oé·lº£C–ôÜ0|sìGð:ßwNXW ý†ÓÃÚk5râ€âeÅ6!+½ÞÌ8…QÇÞëœbZD%‘M…&@áÖ¤‹n_®É4ÅWWËXJ´HC82ƒN20ñ)X1Òq@E:ã¾í*Îl—÷ë­Ó3’’ÙNÆCXîUã¤YçMÃ’ˆEN{MC–Än›Ž-Ó:EI|à •ÉE]uh¯L¸ƒ"ä®l@«½'p¾‘Iö? +Á±z¦íÖÛ²8Öž–œÐçÌÕA¿ #ª¨Œ@d-äb\ÕÕ:ï«¶aH¾î«OC@Õ AÞÄî@”ð‹². ¬%¦ñX/n²UÂçÒ*u@ˆ—aΨ»Ïë(¼ƒ5LÔäHèu¯×Ç©®Y—n;µø ŠüЀá˜óÙJðî@•nf•7§HA¢Ñ ù2õ«µ¸ßVë-.5øþ±fè:?v%-Ù×tpå.þ–‹ ™¤ëA4Z’¯êója»*œîéy“W5ßÎŽˆwÕݶ'¤SÎ7 cœÌ¥üœïöu‰¶… R±QH`eÍq·«±µõ'<¬‹å(q÷Ç#yŠùø¹@n¡Ò5Ã@®”féU<‰èJ¥Ñ5 ÄFZs’…W]R¬4FdÒv_ÕÌaU䵕 …߬&¼Ï¿°¤P H¾’¼-«”‚<Ö×ç O8ˆ?:ÜŲ lŸ¼ÉëÓ—²ÀHÂ`x~Óö%\â.ñí–B¤Æ”¿m ZÓÅTá´‡ž2–bŸD’¦>QŽ1" â7¼­—ƒo¾ò‡&˜K{JSù1ãzl‹AAÓ¯w‚s l°n›½‘ ˆðÜ;.–¾T·äÂ-ì"L,s…¡ð!yo]-xó gä6)ŽE¤D–>ÝK ©|‹÷°— T¸¯ïšì¨k‚¾Òds=ÓP6iôÖ>-\ š‘nTV™$‚ªd,ÝM‰ÙZ_Ò¶ÌRÇDr84#¢ØÍD6Æ\®J¸ò*‚B/^•›üXÓ©‹;£½ÎÙº'Ì}{øèÜÆ’H¨æ¢GÍ'²(IùŒùTO˜ÏS9ómfÌ |ª§½äÈr­Öúi¹ÕŒ`#ËA_jelÇ’½Æšç\ AÕ;w»"¯…»2Œ¼vpµ 7ñ!Õún3oG(²”K5$e}¡ TÈ·.¿E¾ñ™[M×þ®tU.èšc>o Ï‚i}§Xn„/¡¢‰2¼ç£(tŽ%ÚBʇX-’+‚ñ9¸–ë{ôHdmx?NН@ŠvÉX,MbÍŒT‰Dø^Ü7ùc›Æ‘AùÈpÆŠY¤¤ lŠgÙ´{,;–·¥_J¥¸(éô†ò?@V|´ÍI¡*v>›d­¶™Äeèòw¤ ìA¹^O ŠMüôí=~9=‘ÓH={7¥2a…É «ãéýÄiI dO ˆJ66…u"G¢¹GYégWníº4øåB W-ýBYµþHKª)`šhć&Ê^½øÙU4mž·yÈçxp¥ˆ{¨¿{,™"¡ädÆ4mîáæ6sÃ,œ5ÅsJžèƈHË0ßáZ ø®˜?Ôº-wº_q¥àý)ïºã®,Æë*xÞÁß_ªF—R¨âø(%+À……>éè–®Óœ9 ÆÄè@·ü}s©ù¯˜9ÍU4eLüíÊuÛ.4Ú`Cà;ÐëǦrÖ”óøe_äêÄÁ§(hÔ°œw9nÞàÏß`W/^쪄ô­¨Ln´ßjŠÇ¾ìXý/¶/¸h¹æß¶ÇCÀSl‘Ÿò~м/Ë»k§è]ÛôÛ€?Mѧ2?tFœúY£õÓ!eHõxL TÃh=®×âÈÚØGâ]þ¹Úw£iì(ºX Iò´jFÊQ|IDël,%Õm4|ä ÷ñ˜ã;ü®uìÜE¡âô­p„RÞTš瓃9äªäᣠ ¹œÑ3=Ž1÷TN˜$$ezÙXDqÌ2É ‘r®Ð0–Z‰dCW­ªºêOpÆØÑHბFO-¿rzO²Ä¾›áï:;@à¡5õ: ‹íÒîHƒ-ÉNvÚãÝ–`t§Êóyn´8¬ñ|‹`4ô’ãnŒ@÷U¿%#!ã´ URuuï¶x¬g;pS¬âÏsxÏbág„]•›6? “ьǩDÞxZúÝ9öÍîçNƒïùzïßC|#&`¬~ï¶š9†ÝÊ{Ä©ÖϨÃ\$ßïkê*¾5©÷4*ä‡)+Œ 'c3È8©>çýT‘k¦~" ºg©æ$+ÆPIyŠá!àœ÷@ä;J ðìHªySåHJÓ$ü $uã+$š&Äú’êÇf…‚Ä1RñÀ$3\)ãšZ„a-›ó°ÀǦ.;FÍ×ùÒB±i„¯|«8麡™guŽáª,ywŠÍn“– ®ßœ˜Œo<¨…Â[ÑBóßPÒ$Ê ¾ûOEãi”Æ2›Œ»Ç ¢«+¾\^­ÎJ¹ëô.ú[.ûéMÃZ÷PÓ)ÏoÎÔG_&VÓ¦„õã§BsµƒŒudlüL;2¤z¼vTÃm\;HP³Ñ)|l”HaŸ–1PÍ9vPÙ 8’’j‡Á`?ñºÅQºŸ´¯Åþ‰Íx7ùb3÷âã óÙÊHÎÓÄÄ—Žÿ¨t€#‰M6[;h9© «ŸkYœ»þjàœǵƒæÆL‹qíðIí ´¯μ¨R€g¿G˜÷_ÉEA ¼¥<q„³ßÉx ZçkW«áw—Û} R dÀgØý¯_B¹’÷- Oå®V ñå®9#$\~8ЖéÚš7s sy— [úå/ÏÈyP8Ìd‰AZOÔ¤ŒpŸÈ|‘¨qá¥Òþà:ñ=ð[Þ uù+žû®j˜-glþn«Ý–Ü÷¹(–6¡z‚öü©'ìÿO=ñçlDÃ@*Šç;<¾Fü×ÿˆvþ—»8‰ -«ùx݈ôB¡Z¥M®ð\„ï^¿yEG‚º„X¾‹§§ ÿÍöðXÿžZ':endstream endobj 2732 0 obj << /Type /Page /Contents 2733 0 R /Resources 2731 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2702 0 R >> endobj 2734 0 obj << /D [2732 0 R /XYZ 85.0394 794.5015 null] >> endobj 2735 0 obj << /D [2732 0 R /XYZ 85.0394 749.1928 null] >> endobj 2736 0 obj << /D [2732 0 R /XYZ 85.0394 677.5759 null] >> endobj 2737 0 obj << /D [2732 0 R /XYZ 85.0394 470.4175 null] >> endobj 2731 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F42 1338 0 R /F54 1433 0 R /F22 1037 0 R /F64 1485 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2740 0 obj << /Length 2122 /Filter /FlateDecode >> stream xÚµYÝs£8Ï_á·ÁUc­$€Û§l’ÙÍf6ÉÅž«»Ë1²MCÎàÉyþúëÖŒJ]å¶Ô´úó×-ÂFþØHH"cÂ8 ‚21š¯Ïèh {¿ž1Ë3qL“6×/³³Ÿ>ùÑ(&±är4[´dE„FÍÒ¯Þ‘d ¨wy;^]L.§Ÿîþ¸¹ú×xˆÆÞùýýÕíåõ?Ç.(ð7¥Þç·_Î?›µûq̽ó_¯¦ãÇÙïgW³F³¶öŒú¨Öξ>ÒQ Fü~F‰Gbô ?(aqÌGë³@øD¾ïVò³éÙß­]ýê 7%Ü—|Àœ·Ü1"âXŒBés_»c¶Ê*0*”^ùRgetè¹µuR¤I]nvfy[䪲[õJ¡õ?} Úg0É õ¥ÍPúdax:z°€„,5,«Ä |RÊž¾­Tj)ÍJõ¢æÙbg³ö½,”Yø7¥Eº>àcˆ½!Ÿì®©H¤’þ‹›1‹b2›ƒ·y$" (¡! l#ÆW#æåªXb³AŸµÛÜWþš'…!ô±‘íW†Ï<¡”EZéÞ¸líæ‰Vl©ìú¶È0;;'gk{4ŸIšê:Ó´=e»@9¾ÿý„<ô½ëìÃ`8ȆrÝÖª²þý°úàpßîƒ{7ÍnÚßµ¥¢7_û›¯J=7»ë²¿½.‹zÕìïúÛ;•l*r¬{HÀÑ0ŒÃÓÝ£Íu¼{4\º{<÷„þNãð#ÓÀ‘ùÚ@õ޼+òKW56äÍôÆ®a“N–êg›÷Ë¢tŠ¿ÿt|€E ƒézIQ”u·ì8‡Á)ê°49ÌçQ,üL¾•»Í!‡PGÂ#ÀÐPìtxÚ\ÇÃÓpí•ê„湘E§tLGvF9 CŸu ÏŸ1<7ÿ¿ð<¿#<>€+äáiqãÒJÍf/}/bn@ž—ë—,WfþÀ ì%1æv¦/¸¿èê§5m¸TíN_!ÜÞBÖÕuŠ—ÄJœztû0­é6¥Û8ìèNÖÍD©;Ù¤mÚalàR3ßÝ*ž²"ûc̳Iñ¥I€˜kyÒœß@8¶íXƒÅF6Â%3Ù:½º2ïžžÞ h};vÄdûr£3;­ðÖáÐnQÙî¦ÕBçt¹†ÿ¹Ùı½ÒlD!Z±ó/³ßîÞ6à;q¡l1MwU­Ö6žeQ•›:Û®÷ÇÄÇû¡=.$ ¸û1ž0J;Fkƒ]ûôCˆm´»…xëæ31¸Ý·œÛqŸ½qÊ|ý°ôÔ<Ì ز¨ê²ÌßöÜtW”/Œ«½šÍÂn¯·&¶’b` 8¦žD†¶]n rÈÐpõ|aý€µÿuòÍ$:€Á2`î$_}G‰ˆ Tö¸h¨|@°Ð<šBOËu28 û‚DRˆ¾ìÙ€Ä.«ýjr¨*`Ù^œžqJ óã ;üû€SÇ„ÁOÿŽi‹8ž ×ñ™T?V£÷›´ø¡¸Þ¼éû4Û¨¹þw(TDrÁúBó·…þ`ŠT 5 WĘPLÀNÐçyRU½ŠÞ—†A_ÜâMq.#ûêÁÝ”Ñy秤[?„†…÷ÁÚ€ž!Y¾§6Z"NÔ†ã:ž«Æ ÿx|»1\^M/®ïg×w·Íð`Ðé‚ýÙ0‡Ÿå¶~Ùê[+öžÌ¥w©rµt 6¦0è[.7ŸH/§zмö Vi>ëÌ•á2«s3T§û7ܘ¯&öÜTá> endobj 2741 0 obj << /D [2739 0 R /XYZ 56.6929 794.5015 null] >> endobj 2742 0 obj << /D [2739 0 R /XYZ 56.6929 489.2412 null] >> endobj 2743 0 obj << /D [2739 0 R /XYZ 56.6929 418.8986 null] >> endobj 938 0 obj << /D [2739 0 R /XYZ 56.6929 374.8677 null] >> endobj 2744 0 obj << /D [2739 0 R /XYZ 56.6929 336.0641 null] >> endobj 2745 0 obj << /D [2739 0 R /XYZ 56.6929 301.8248 null] >> endobj 2746 0 obj << /D [2739 0 R /XYZ 56.6929 228.5603 null] >> endobj 2747 0 obj << /D [2739 0 R /XYZ 56.6929 97.1314 null] >> endobj 2738 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F42 1338 0 R /F21 1034 0 R /F64 1485 0 R /F54 1433 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2751 0 obj << /Length 2530 /Filter /FlateDecode >> stream xÚ¥ZKsã6¾ûW¨rY¹b!x’ÄÜä׬cÇ;Rf³yh‰²YC‰^‘²3©ýñÛxŠAj²[>?¢Ýî¯!“†?2JÂLòQ,9˜ˆÑb}‚GOðîý ±˜‰Mš¨óùÉ×,I$#æ«Æ\ ÂIBFóå¯ãéÃÃÕýåÍϧ*ðø NÆãÓûŸ¦wfìáTÒñôýÕìtBâKE áñåýlvu1¹œ]úøáöê_§¿Ï<¹š{ÍšÚÌ”Zÿ>ùõwÉèáz/Û|£3•ÞƒÐæ¯vvz»”©± À“ =½ée ,Ž ŽÈ&ª?¦÷±äA‘ž%wE†XrKdÓ @!+SK†8ü=rB€îp©øG1$"5ÛÕÏÓwW¦”r$9´9úÀTiÍRÉøq—šŠR–¤ù£µ4–˜J.h«·$û6®ÕU‘4ö=Úm£ùAßÍþžBe¡Þ˜“”û¹}B!ûŠã5eÊ¢(ßì"ªœ8NäJòN´ïßÊ]±lÓø¼ªvÙ2Ô$ú¼=ý5×o_ìÁ¹ÄüÙ÷ë ¢ºU0·U¹Î ò‰#ÿ’}ƒâMÍN!™a•úÖÊËêjtÕ·ÂŽ˜ ›’«éå4žÆü<¹ÄçÓ$ŠitŽ/(§ÓDLÏ“óóKz“òkNàu2ü‡Ü…¸šâsÉûþH½úá>°Û°ßÿ÷ÿìÿ‚Lj% ï[†Õá¯$N)¥?‰ä©:àŽéøüæþÒøzPbòÐY•ÿ'ƒî²þ zèêendstream endobj 2750 0 obj << /Type /Page /Contents 2751 0 R /Resources 2749 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2748 0 R >> endobj 2752 0 obj << /D [2750 0 R /XYZ 85.0394 794.5015 null] >> endobj 2753 0 obj << /D [2750 0 R /XYZ 85.0394 752.4085 null] >> endobj 2754 0 obj << /D [2750 0 R /XYZ 85.0394 160.8368 null] >> endobj 2749 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F64 1485 0 R /F42 1338 0 R /F49 1358 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2757 0 obj << /Length 1860 /Filter /FlateDecode >> stream xÚåÛrÛ6ö]_¡GjZ"¸‘U[iÝ$Ž×V;»ãæ)›S‰tEÊ®÷ë÷€ H v¶—·:3œûlJá›&)I 7Se$I(K¦«í„Nïáìû s0±ЇPß-'ïÞ =5Ĥ<.×\šP­Ùt™ßF ¢È 0Ðèüòæfq_|ºú|=*Z~Xüg3Í¤ŠæWW‹Ëó‹ÏbžP¸7(>Í/šĽ«™áÑüûÅÍìËòÇÉbÙs7”€QaYûmrû…NsäÇ %Âèdú ”0cøt;‘‰ ‰Âïl&7“õ§ÝÕ F%\¤< ΦŒ“$|¤“ÄTpÑéäýÅG” ù@tsM47¶|(@vÁ¢_‹—_(å÷¹Ê*»àÑÛÈ‹¦¼¯Š¿î^ð·\ÇE™U[ZT«¬-ë YCŒèD&À‹eáCä›,˾)í_€i£ˆ‘2uêÝñõ~³An;f,*ð³Ê¶E€­ˆVZè[°i,™"©Rz£~Ñ¿¼+ç):%L¥Ú!Ìt§û¢*vYÛé >;Áo^5M±ŠüBªá?æð˜bNIv ®Â¦hqÝ[ ֜ݪt´ïö寮w3¦£z‹_Vi§aiB’Äk$/wŪ­w!QÁq!ö„ƒüö€´[4í®¬î¤!’Kw ňØ¥$BÏGVåo1-’¦Þ)@«kq‚·IÏ0q£Š…¡$…K±pM$èÙ|Ƹ‰~^ÌmZX¾K¼»0ï4´M±CýïðËzGùä 2gPÎåȨµ7`½¯r{ê>E¹>RÿˆîïeÓ6AyéXЛůÌ?Þ|þzÊû¯õ!ý¡Íÿ­«bpŒö£#§ƒµÞ‚ß]\ž[$42ø3Ï·eB@ aÈÓèºX:‹jå‚ÿSVí!â³M€s–*"¤Pï­§LHLx€ë÷gHG¤‰»•JþatR öUt$€¢’Ða–’(±0ÊR2¡&¤Xòämÿ÷0#·˜ÿ´üªèWÝþ¢j‹]åÓÒÍKÓ[—…Îꪩwm¹ßÈB„Ë´wCCÉWq(Õ”ö²Ü>Âe—q-´ÐP4¥î /ÃÁn¡8IRņ¾zÀä#Máê¢;À5ô]·`×èc«ºûÍ›P"-~·bg—ø†b7u—/GQç¢s›UÙ}‘ÿ_áùRÕ $ö£¦ª¨Ò©˜r%‰aÐ%šˆƒñøKÁœ]ƒ1ʳ¾¿è¡ÂšMÁr·ñ”(‘CäàÇ6}ˢ–„Dœ0ùÅcýÀ é_§‰ï"ÚvªkÐ8®Ñ]}]uû]½^Ûr{Šª¥J„¶8t %MeHªúæëÇX§N ±ƒ›c»Ó,òbSxJì5J0u)Ã=_Q„Ø ¡¶Üzñ×>]`týÈŒ1†ƒ%Å -àG5>.„޶EVYdÂø·"Ýç\»é­´í2îµKGYžãS—A}Û­Êm woë'„ÐÃ0Rêç Ø¼¾FsÁvíH5«‡"ßo°êa¿\‡2V?â·»™ŽöîcÂ}ˆû7 ¦ÅŒí  2À8›(«‚¼öÆ -„}˜ ´m´w¿üþyx­ùái3Ô:ž¯ ŒŽ@8¾’05&\ñˆ)z"”C=•êýS–endstream endobj 2756 0 obj << /Type /Page /Contents 2757 0 R /Resources 2755 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2748 0 R >> endobj 2758 0 obj << /D [2756 0 R /XYZ 56.6929 794.5015 null] >> endobj 2759 0 obj << /D [2756 0 R /XYZ 56.6929 751.1673 null] >> endobj 2760 0 obj << /D [2756 0 R /XYZ 56.6929 645.84 null] >> endobj 2761 0 obj << /D [2756 0 R /XYZ 56.6929 573.0473 null] >> endobj 2762 0 obj << /D [2756 0 R /XYZ 56.6929 488.2994 null] >> endobj 942 0 obj << /D [2756 0 R /XYZ 56.6929 442.566 null] >> endobj 2763 0 obj << /D [2756 0 R /XYZ 56.6929 403.0147 null] >> endobj 2764 0 obj << /D [2756 0 R /XYZ 56.6929 368.0278 null] >> endobj 2765 0 obj << /D [2756 0 R /XYZ 56.6929 292.3132 null] >> endobj 2766 0 obj << /D [2756 0 R /XYZ 56.6929 177.9956 null] >> endobj 2755 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F40 1265 0 R /F54 1433 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2769 0 obj << /Length 2454 /Filter /FlateDecode >> stream xÚ¥Ûvã¶ñÝ_¡“SgWX@ oÎÚ»«ìúRKi›&y EÊâY‘tEÊŽûõ`Š”))9µ8†sÇ\ : ៎” a¤ù(ÖœˆŠÑ¢8 G°÷ùŒ:œ‰Gšt±~œŸ}ø©‘&Z29š/;´ •¢£yúkpqwwus9ý×xÂD\‘ñD„ap}qóóÅ7\»k\|¾š'TQRlÐd\ÞÌfW'Óë»Ûûqó¯W¿ŒŸÿtv5o¥ëj@ÃȈöŸ³_G)(òÓYH"­Äè^BBµf£âŒ‹ˆE~e}6;û{K°³k?²ˆˆŠÅ&atD)ÑB°žM„&2b‘µÉíÝ|z{3{£IHBf‹Y6ålØiÒÅòŒ|á± ßÉÒ°üðIò&È¥"Ä Æ2_geRdû¢QÎŒMäqÙZ¬áX‡%8™Æu_ºWe!£à·0dkUšým<‰"äeÝdIŠëÕŸ‰y°àiû°Î¸ô={íR0ú¼7  š•[K6cª‚Çm‘• ÈkÜiQ öH«"ÉË-c›Ñ$b¥AiïlPÁ Å• ù¿¨, ˆ¾ÁU”í=n¼¬òÅ ÁER"ð!¢•†Õ¥}­ t!ïÙSkBeÌ:ND¬žÕYD´9 ˆ', u0u£ÚÀ´Õ­¶²Ö]‡¦‚ÚmÅARI$bÆ¡ø+½o%)ÑÄ<ä&Ö£¾óÓF‘¼"`ÍϪț&K‰ý8„À(‘ŠíGÓ倯hBžQR‡c­œêÌÉÐTd#Á-½V?L~ Kc¢#H;Í 5£¹‡pPš4 B^ŠNxÀ[}u“”)F»CÌ˧mCåÉ%QŒžÈ=]¬Ã¹§Å²¹çë@î¡i…vVHóM¶hªÍë›ä#db) ×b H·šQ¬úÒͲ¦Þ³ˆc Œ"9ÓáÓÚ.:$ðx;jhù¬–Žãê<Í» ³8:á†Ö7x,ë†oCn Diá#¶iÖo<@9Q2Çåj±ëyN¦âJõ%CDŒ£M fËd»nðe>ÿæ¶+|nk‡¶¬6þÃÜ‘°Þ0À‹=Sʲ¨Êçl Ã-—žn‚Èÿ¦Û°ðý=AÀ¤Ëžˆ-£¼Æ¤j†Lù”…=P^i°N¨“l—ý©p‘ÔBN=`ùG^7yùˆËNYø¨Ú®S‡š|w¸OîdfiV.2ã›øñßûrµ!Ô£:˜·÷ Ò¶"š%wNÀÀ…Ž’Ü¡”&}Ÿ(*¨KQ=ûœ‘Î΂+ËXO ]¬Ãi¡Å²iaµÏÚZÎù –i€e¯Ðj™ØcyUøJ¾­“G—" ˆÐö*GlµTÆü„IvHG,â¬Až‡ódÄcïÿuöœ½Í”à[syT¬é­\½XŠ(aBöä*TÙÃöñC^­X­Å•„Á%yQl™.s“è]Ì—¸So«ã|óAõ—Õz]½XÙ© L¡£q€6,ØŽúQê­%kúº?¬¯aóüjœµ”þó¢B0 Î_Z(m¡•‡¬Næë"÷K®ç§¾ÐIºZPgzx.ª:w”;ÆH‚Õ×,Ù8¡~ E˜fFΰzšc‚~RA$ŒOVÕvƒ/iòZ[ƒ—ËjÓÓu–8"ö^ª^a ì¶[&¦÷7áÂtp±Ä+"»mk‚ÂÆ¤ÿÆ1µ³L²1‹Ä~v·CAçb$/ëmš¥ý!vàŽáaë:²²júÄÜ„ÑgkÈ';Wˆ #u<´ºX‡C«Å²¡u9Zæ*8þ3‘«Öê¸x-Ö€|ýÈ‚€R”öt‘ÅüÕ".²LE0–c¬¬.ƹÿ¾Â§u|”fëÌ^xAxÐ6|, >Ž“­4j€®ó2@¥£¼®ÊÇlã‚ ‹íW¿RF,Ú²0Ý¿²s3O’—´·)ˆùTÕ¹½†1ÙÜ¥»Ôp“Ò £SG=Æa—{Þ§é·«?ÑÚ]>´w› ¯ØåðàÒÌ4Åvb§ õš@'Ãj“R Û™ ÐL©c?=~-á¼K’ä]nþDÖ Ô¢l7‘ZV-óåÏ1 º*øKì=îJÁèJeŸ¹»‰›Æ@¡ŸiZÁˆËHûÓ²ûy%Ü5`™Ç¬Ì6IãcÇ,-¡K^L€ ˜ QÆ©Ãí»'Üóêìê )]|›Ýžöî0¿÷=aŒcM(w¶Ñlaï*7$LkŸm~œÞ\"íÄI¡CÉëtöÅø>[ºëèjqé:)·Ézè¦X*¤”íUñ[ ÆõuôþÓG¤(BJèq˜)¹ í¯Cö'±6¿nu |ñóüËíýiËN͈Pú+òÙkÝd…óýǪ¬«M“o‹C¿âE‚˜ŸÞÒpØŠøÿ·ûA“Ç$RêÀÐ…œD‘¦^(£éØ\5Ǭëi¨6$šÜñ}­ÚŸ ߪõ?à «endstream endobj 2768 0 obj << /Type /Page /Contents 2769 0 R /Resources 2767 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2748 0 R >> endobj 2770 0 obj << /D [2768 0 R /XYZ 85.0394 794.5015 null] >> endobj 2771 0 obj << /D [2768 0 R /XYZ 85.0394 751.843 null] >> endobj 2772 0 obj << /D [2768 0 R /XYZ 85.0394 439.6462 null] >> endobj 2773 0 obj << /D [2768 0 R /XYZ 85.0394 227.9148 null] >> endobj 2774 0 obj << /D [2768 0 R /XYZ 85.0394 150.1021 null] >> endobj 2775 0 obj << /D [2768 0 R /XYZ 85.0394 84.2446 null] >> endobj 2767 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F64 1485 0 R /F22 1037 0 R /F42 1338 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2778 0 obj << /Length 2599 /Filter /FlateDecode >> stream xÚµYÝsÛ¸÷_¡™¾È3!ŸüÈ›cë_Ç|½ë$y€(ÊfM‘ªHÙuÿú.°¿ [7mo:{·øtP™$ÑüìúzquqùûiÀ$)0ù糫_Ï>aßõiÊægïËÓ7¿œ,n:冠„kÍþyòí™­a¿œ§‰œ=Bƒ„4MÙl{"$¥àÜõ”'Ë“¿v£fª× ”„ŒGÌcFgT„\ÀàÐ$2 Y3gØ8®«¦É³à>Úìëm©Vy©÷‹\†Bh»Â„+µÍu?Hg{KCI´ôPØ)MæN ±ßwÆb¤Ð H/·y•ïU[Ô¶Ûº.튰¦R2»$Â$M³äò©ªwMÑLÂi'ŸEš ­Çˆ6Â$˜ù ‡1¥Ñ,Š0Ìr×Ô"0w`÷$Å@åq(!`]=¹sÂd%ðGIi¹¾üÊü(Pˆ!8Ür«ò¶ÞíÝÖ#8SG–³zæ:Va­Úü§z³iòÖ#6’`.¦b3Xµ8Lœ× ó4ÌÉJÕ4ÉrI’L_ü9ú.ŽŠÍ«Û¢Ê:¬“¸9*qSª[ß¾E(â„Må½ï¨Käñ¶þ+^—¥RC¬»¬¨Ú|ÿ |á+ÀÅŒÄSá÷õñ¸öÅ>ÏÚzÿä‹bFLÒ©øOGݶ>mi¦œ= ²ê¨¸ ²}ÚåÜ×ÿçÀÕð‡œƒuµ ±ó,Æ(qvûº­³úe>CНÎÉ[«“‡Çu ˆKŸiÙ¿ÛÆæéä=•Wæ^ 7ø§Së¨'ëD® "øøŒU}.eÆð!%Q4N‹åù×Ëë›Ë/Wݤqë3[¼P L²~ é*.µØÄ7·Y:WøÁ¼ÄN{¤ê ~¿ÂJÇÞÞ©)S1䛿UVT·~‰õê€H7€† mNFs²ýÓ®­o÷jwWdhS§üè\Ü)#eýˆß\ÏŽç @Y‘ÙÆ¶>¥óõ¡´ÍïD’ËÏð¡!öÜÜ١ݾx{èFä´Ží®‘ÎT…ÄÊv³àßÔ{ìêŠ$­Hq[YsÄÖŒÑüßuegÃéRH©¿ÅÆq#pÖF‹ãùcÞíZ ?Y]=ä•®¿T‰=ýªÐÀ}h>œ \cÇêÉWŒ@ä:ôì£ bÅOQ:&îÔ¼±‰˜¯VÛö.Ÿ¨°…Å÷…S³h¬ºÃPл„rÇ„ƒ•a¼ÏbJk Ž|ƒU§ªÖ¶ü4«êž¬=([ÂöÑêÞ1»Rey7µ;$p1Ö…7w>€:”r‘ ˆÇH, yäxL gáÂLXkÀ·ÙåY¡cΘ8L]ÝOÑßnq»0ZBqÌI ::ÛCÓZJµÙrvóž†BmC64Âp†±G8€w65I5H­#töî.…5î*ïLî fþ›ÁƒyÏok¶¬ç òõÚÈå.WÏkÿŽK¯ëªñhT⸎¤ÒW•£ŒÂ% J„Wµë¸<êâ b†Á-p¤Þ2/= N0ku Æ@iº:%M\P‡olåÝÁ’õÆ—Þ v’B¼põ`“Ë¡®f³ábWN|Õ¯c¾_—gŸ/ä›ádÁZñ8€eùáŒêóLØübyMÉü ДMWσLFvÛ’2Û^œŸ¿ÿ²¼9ÅÜÎXœÃìk˜ó|˜kâ_:Vž`…ÿÚ¦”h›66îUmÈ÷Y™r,EÕäUS´Åƒ].µ•âd^Õú›,oº(S„HfˆnÍÙ­ÍÚy‹²ÄnãøÚTc«'ìYçu([+èPAnop¤õÂiêêà€{ƒ (Jº;^½³ï“]6"¸q2õ¢ÛŸ ‘) x,- «©alX6³oM­,óÁ m®ƒ‚(‘¦¸ôƒ$†:”¾ºK øAÜAÑ;®$1!a¿½GuŸ=Àm… “¢fÞ¸ädŠ-aƒÐ€¦u³A[uwyvŸÛd¸qQ 9c§ÚbU”Eû䦶wH+†º"gŒ/Hµ)‰Àsô-hu¥ô | °è1‘DÆèÜ®ð£3—27AÃÚÚˆ/¶»2ßB39Fbl³»^gy6 ðÀÁöß!‰k›t¦gÎn ¶ÏÞ♾ø`M|hkÈ›E¦ÊÒÚ ®?ͤ¼îíë!\݆/e+ÆE˜pH5¯f«!×ËÙªãêãr¸$¦4¥ÉëK:&Ï’£ÊȘÓñ’¿"ž1ÕLr œ S;µ*—rì…(CÃ×ÕVòö/ŠÌ”Ò¹ØAQÏDz¨M`¢ë³¨f”²„AÑ‘Úý°·)ÔX¯æÿÚ•EV´#Ñ=j:·÷Å4tñõfp†úÀ÷M§+A†¯Eࣇ¦,R‰ž!×ËÑÓq™èYøj E˜äÏ^ÇF…ȆBüuÕ:.n#%)$IÇÊ-;ü›ºiµ]ž ´¸‚&ÝYÊ1ü†É3Içï.¯.Bd,y(ÊI •@}ÙåÕrù ×Ï—¡ÚÝPR48»]½7ù4M]ÜŸõ²mÕR·©D_…÷X(ý1±»ÏJ5e%õ%øô^¸Ö¿ÎRœàÉ„o¯'4¬' Ý_Û3Ç»†k¯Uø™šYdÔŸ{ ÝØá¾ûs2¸Cc[¯½è wr8ë"¥Ö?úAñɪÐcý »ÐšªTk”Ö ôÀ@õ'ÖyŒå TàÌÀr™3iîØš½sÖHaLÌ.ªºx„œjs¨)t‡C}ph>üUå¶wбګ½ƒ›ÑO×”…ê~{Zy½ó Œ—ƒÄpÚ“c€1àz0—ŒÒpýe2žþú1Ô+•P1꾪—còè5 Fúùm¤ØË`1ø ««ƒÔä®j¹¤}€zŽ5~±˜÷’$Ü‹)PñZL*ÖBI-@ZhÊÙ`¥ºB½!oº@õjW’n—ñÊ®¯ö«¢µQ¦8œ‰m wQ$Öm2Cí¡":”jÝÃdÍ£ùe‹Ý[õ„ü˜óRùy–¯1¶ííCZ-¡Y_j†+“¸`@¿Zè½G¼Y–õã@žç¨*—®ËºrODÍØÓ=Ö¾õ¼§Q˜ õÖ/=ªŽðŸN÷Ü Cýë°ç î=äþºÿÉ4ãIÂü§i¢“ÖÝÆ+˜6,\ ý+;‹ÙœÆì9䨲Ÿïê?94ûÓendstream endobj 2777 0 obj << /Type /Page /Contents 2778 0 R /Resources 2776 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2748 0 R >> endobj 2779 0 obj << /D [2777 0 R /XYZ 56.6929 794.5015 null] >> endobj 946 0 obj << /D [2777 0 R /XYZ 56.6929 769.5949 null] >> endobj 1641 0 obj << /D [2777 0 R /XYZ 56.6929 744.4739 null] >> endobj 2780 0 obj << /D [2777 0 R /XYZ 56.6929 712.5891 null] >> endobj 2781 0 obj << /D [2777 0 R /XYZ 56.6929 647.0402 null] >> endobj 2782 0 obj << /D [2777 0 R /XYZ 56.6929 539.5575 null] >> endobj 2783 0 obj << /D [2777 0 R /XYZ 56.6929 410.6422 null] >> endobj 2776 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F54 1433 0 R /F64 1485 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2786 0 obj << /Length 3410 /Filter /FlateDecode >> stream xÚÅËrã¸ñî¯pU¡«,.;•Ã̬ç±3cOlO’Íîh ¶S¤V¤ìõ~}ºÑ Š”(9©R.Fh4ú Écò85¡ÐYtœdQh„4ÇÅâHßÁØû#É834b½¹>úîN³0‹U||};X+ EšÊãëùÏÁë¯_ÏÎøø“™2"8 OfFˆàËëóo¯?ìëI¦‚×ïÏ®NfÒ¤i H)¢Å"øáüêêìíìÓÙOï./¾|~ýæìóɯ×?]÷Ä  …FÊ~;úùWq<‡süx$B¥æø :"”Y¦ŽG‘Ñ¡‰´öêèêè¯ý‚ƒQ7uŠ!F§¡IU2Á¥‘ÚQ|œ˜,ŒµÒŽ#¿·55Ë‚7ÏÀVd([êެ˪#ÐSÙݰλòÑôë§·W’’ÚõrÙ¬ºS`§È‚îÞ¸Êol5^7ß™ß.?ò2ݪ¬ïxBM0^, n›Õ"ïùÀ™”afŒrÇùE©hùP´R~Ãß½‹†ÐI‹4Iˆû`ŸŸšÕœðFœŠd˜FZ2Þ_ÃDŒî9ÑŒð˜Wk;±ŒÊÂ4M2ÆúùÕE&LEªþ?½ ÃðWd\•ŽƒOn÷™ó! ð½¨ÖsKÈØ5¶ÆÞ®q¸/‹{.ç¶îÊ_„P–gãmá áÕÁi3¾©W_^b¹•››Ù¢óKgº_Æ·–ˆlÇ`-T×óÍj˲žµÍÚ¦°ÿéª9/ Š×¿uK4 êõ³M¸^ü¤?ÔŸ[6$Ï©Q4Ž…ØÊkjÜ0 ¹éò²¶s00ZŠàúžá¬,Ø|*«j<©íè–ìœú%/ÚùÙM=›—íu;VåcÞY¾jº#†ý ’0Ë@,ðoM„FäiAXÑÔHoKù„8K!B°?^ý=SÂk0‘™WFwÕîI›8蚦âmÖ­³šLpgk»‚Í ¤€àt.žHœCð OËo*>T×dÝzEjÔ–ˆGÁÞÀµR Š\ByW;ºJ²f¬¸¹D ËÆqKg9›uç'X™Æh-à¡H0~y½Î«Š§ƒ[&(ŸGÁ1Óà¼éì÷'³H˜àKþÀ”'þ„i/¸#ÁEû\¶mKÇ4ì;As“Ê– @MMN ýL@Îua·öhm±^•£åóÇÄéÎN™ñæ–•/›^wØn ‚Ýz5(Yý÷é>ï¨õܬ[3zCßyã½m†Ë-<·5^Ãn·÷ºµyÇd„;Aè„$Ö üFDÓQ #͆XäÃåDTÓc!·f5©W‹de}¨ë …qrçÌ.4íª¥(jèx1W}µ {'l¿0èþ¼I'ÛñVa™”Qš%3ÂEË%±D±í÷Yì7" µÔúS1À:`*<–#¼˜rí"T >LxQÅÝñëÊ„X¿8LY5AÚˆSZ„2rLÛÇzŽ’åi/®e©–Šc‚ÓKäl‚¢«á,ò$ÐhÁ¼TŒ}Ÿ?Úž Ú>®ð+"'œÈ¦.AXÝ0Q›ÜX¯Pf‘Ü*¸•N9UsLuMŸÇùPÜ×|¯ DqB- Âk¿ ôXNn'! ãT{9¸­ò»1ik¸¯ƒtõX„Ä@é0–Q<¦ì 표•cct1Z¸¼Lçw4èLë{3H ܉ lÅQßGÈ›0‰úcÁ‚»M"Ž65fJC<ÈÚþSÕrG‹Óx,ù0øtõÉgÏ»8…ÎUŸ"Š}æhÆ%,œ _žýíâÓÙ~‘Q`‡²8{AdXDÆc9‘y¿fÄalLrxK4±å8Ì 4ÉxË÷G0è3 0ÃZw㔋TÎWµìJ6ì0ãÞöe×WN¼vÍxŸp5³¯[·5{½÷¦4–W#ýÂM ±ößTånê~ç¦Ð7E/lé‘&¶ÞT–…‘2[[~]•u׎î Ìíªóp±ÈWÏÛÙ®ò¸Ýb)ËÝzaû…!¹Þ ÷$‰J©ä¿ ÷ ö•©òÙìþŠáˆ™x!db¸!ånèÓ”Ö¡1¾š:/W¶€¸ðyÇê,Ž×cMP7R;“„:IÇÔ n·îÈ!“çH }sˆþàíY_BÛ\©WJ|ÙåiUv­÷ß…ŽÐ@¼t¬wá±Ü]<ìÕ–C[n´egËImn9¶kÎû`cì}˜i€wï£Wˆ‰˜éÞiMLÛÏA$¤ÑK`à ÇrüübÁ¨ëªÝ`" Ó81‡éê±& ²ÌBLÇ”‘$kå]>48s¤ÎõõgnèëjrØ Ò¬›XòTVX¸ÇG.l•¼ŽG 2 ª$#¸öëæôéc h_^†Ôp5ò!‰ýF%GpL¡Ò­„gïb.VM 裸ØY_`]=dª|6…X-ážÀŸ .ÚNŒ!H¨Îc¡„Š4*݃\*ƒu Ú½YµWp\(gx^qj<¦‘œàÌŒ‰dîò’²Ò„ëð»„8®Ê :S܃½ñ&—h’̶ü½l; §Ì‡…Iœ jþÀ¸œ¡vnëÂâÕd ÊŸï+ˆ0©¡ÑªÞ;Ç­‘˜ðEiAØíÓÆÕÔ3¨RÜ'Ÿ5Vü&ã0†öÅI:Ë¢yô¦C›=frjX>V‡ÍÂk¿Y豜YX¾h–«¦kЦÚ[G>Hܦ޼KÝdyDÛŸjHI˜$7ÄEal’Eˆ”G×ÃJ2d½œ'|{EöFrúÔëÅåÕnl÷d=Áh®¢ eÌ`q* ÃY2‘ŒfcÔÕm–f¦.×<¯ÎÞú Œ]p©Æ—•Á_Å:qšy aTFc½SÇaˆ·Éø¥¤¹»|÷–ÊhëÔ§k'+©k÷VÔ¬ö;3‰"'Ô Áók¿ÔöXNj¯^”Z¼÷}Îì ]g¶Kؤ3Q6ˆÒ”ž—SŽ´R®×9ÞÒ×þ¾¬ÊÂ¥=iºá(u³!÷†2½Dè$ïyK|ò8åç¶ê®€í~qJ¯r-äÁ~ˆžÎÓÀ¿ŽLû/—(ï‹TÂ'{ 9òpt`‘wÎì糟[>h¹'¡ø€;ªPªÐâQã_PÛ'j0YIOVÌd%ž¬˜ÉJvŸñ}mr´qÜoóƱ߃«€Øz÷Nå_ó4.ÁŽccæ\ìIŒ™sq¼ÙgII°(ëõ¤Zöá=³zL‰K :» rº“°jDZ¿<š?ÐtP™F/C‡X4Ýc9Mï&k`RŸLN>qÊ4‰‰ÓÕcM¶]\Óˆ²a)Tù´JI~1VœCoFÄ@e'¹ FÄãCíÆR˜ñ›¥âô ¶¦gÆÁÖ¯¿]x{qþàvJ ó‹ d cPxƒ¿a,ÄÖ$Î/üÜôªWÜMÄÅÂw¸Y¸aËptkWíPEã‚çþíj8š¯a¼îóyç¼ËÝÏ“øanÓCú±Y{ ìV®ž—¾Xåž´ö½ì›P«j¾œ¯ú„ãdýqÚ«é¨ÿ•Weín b¡’(>DS³CÔ¸è/Ceâ!QSu{³¾»ë+ Ž¦pßÏ"µ £é§qìåêþÉ俢Qj”î‰11íÔ:“ž(<ŸL4þìS%Š ‰G5"f_£íSõ¿»Ü=Ö¿A {endstream endobj 2785 0 obj << /Type /Page /Contents 2786 0 R /Resources 2784 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2748 0 R >> endobj 2787 0 obj << /D [2785 0 R /XYZ 85.0394 794.5015 null] >> endobj 2784 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F42 1338 0 R /F54 1433 0 R /F21 1034 0 R /F64 1485 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2790 0 obj << /Length 3025 /Filter /FlateDecode >> stream xÚ­Z_sã6ϧð›iÍŠ¤¨?Ó§l“ݦݤ¹Mîz;md[Ž5•¥Ô’7›~ú–lÙÉÜÝîi@ðG„"Gü—#‰(Ué(NCaiFóõY0z„±g’y¦ŽiÚåz÷pöÝ{ŒR‘F*=,;²$‰=,~›\‰Dœƒ„`ry{õÃôç«Ïï?ýróñâÝÕÇó©4IM.îî®n/¯ÿ}>U&€)0!&7·ÿ¼øH´»óTM.>\ÝŸÿñðÓÙÕƒ7®»h´ì¯³ßþF XÇOgÐibFÏð#2MÕh}-L¨µ£”g÷gÿð;£vêCB“£Â\£…Že8ì6)b))¥:ÞmJ¹Íq¡Û¦ÿÚ_h‹8’zÔv Ò1 ¨T•±qݞʻMQµ ¹ûK¾iŠº¢Eµ¬7묂8p?¯1–ˆb•¼âˆ× G8.눗GØŸô•Ži@eÏ0:ØSyQ–õ38BšA‹}5ù3!âïA Ê¼!j[q–Sû˜Wù&kó ç_òŠŠ%OX1§—w}I#Ïõ¶\i^—e±È™^´+"·«¬%Z½$JÆÒó¯EÓÕ#zk$¥¢VÔÚ_T'¥œ|‹»ª`W±•dvÐÒ–º(yrPœoˆf­ÅÎ,G5¶»9— Ì«ÿÌpfµ Á5&xX ëhX^Uòä&[²:ôòl&Kj_ê-d$ž'n»¿˜G‚˪qKì°¸öÀ­ZÙUo¶6˜|zÿu „Iêµ›óXZú•UóU½¡þ:ƒÓW@ʉ@›€½WöT༠›wl¾Ôåð øD¢iîÞ¶åhªB‘l“ŽDU2øáúæúö‰øåîáú—Û{žÜ.¬RÇ1Aö‡jc3™#"TZ@"!ÿúD®k%Ù½‡!²:tÀið3ü»¹¹¼¤ëõÇonîï ^/iÐË¡-{Ü® J@™åEÕôw†ðÈÅYÔŒ¿c'b@˜Ž¬ `£¥‘‚‰{³áeµ´*ïöÆ—MΓ—–¿^ï­ÝyÇ›Üëá Ó{gʼ®àx9ÀÁš¤®0Òlç«Óz‹f˜ËÃŒµ]F“žÃIɉ`2ÍÖŠÅØóÕî5 ŽáDO¬T8¯kêêÉøÙ÷¾·r=»&œ½. ´T¤†õÅýUHv=´ózý´%ŸWÁÓ^òlÃFaXähg\+§}J&:2ÔQátUo7ôc‘½4ÖŰËU½¡ã ež=QÏ*ÃSÅ|ëºjW,´¯Ý’¼¾àˆºŽ¨ç<ÿÓ©ïX‚ü®î@óº¨À+È£ƒ„có”ÏÛâK^RàL…a:ùõÜÀÒZ‰žMc ÿ´¿Á,†6#ú›Sìf¤½Í€_v3`´É®‹†õ=`êTÓHxùúTó¢µH þ %#úBÊ nw§"”¿ ÐÚ~K=éÁd\žÇ)7Žº ac|40Z‹XG¯äU]®ãé„ç²éÄSø¹ã„å%©ŒÏ²à¿«—ÖÙ{æI Êø´}žkÀÀn —:Zé¾÷¹ÍÁRw¥$)í„%ÙŒ ÚçUaƒ fD¡Û~nvM팅(a’$>¾.×qôy.‹¾ëô¥"Jtôð)!Ušž6Ïs Ø×O,b §êÈàÓ.¢A‡Á§|@qàër@ S¸ù5Mš1¿Ã j6Ni@œi'a•ÚÐ2¤‚1½¦õ]G#ŒÝžá({K|SVaá±*Êþè‚c/ãè•ØÖå:.ÇeÑu9Û°ä¿í¾† O›ç¹ìë‡6)€-îÈy+½%©Ãy+¾8ÑsJù¼µËE™+t 7¿¦ÖnLZäeN·µ¤ON•+†9Mö%› Èå]V˜»Q[ÖÕc¾ñ7w PÜÏæÞ§8Öá³ÓÅ»uöÒ ‰XI:"€kjŽó©nжÞtÊt¼<Ÿí{ žK¾4„> endobj 2791 0 obj << /D [2789 0 R /XYZ 56.6929 794.5015 null] >> endobj 2792 0 obj << /D [2789 0 R /XYZ 56.6929 642.2566 null] >> endobj 2793 0 obj << /D [2789 0 R /XYZ 56.6929 132.5674 null] >> endobj 2788 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F64 1485 0 R /F42 1338 0 R /F14 1060 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2797 0 obj << /Length 2293 /Filter /FlateDecode >> stream xÚµYÝsÛ8Ï_á™»y6Rù)Š^ÛI½i“\äÞÜMÚÅ–mMm)k)é¤ý_Šd3uîn¶;³I@üÁÿáAÂ#D%É"Ž0,vgh°†µË3lyBÇv¹~ŸŸ}¸ É@F2&ñ`¾êÈJ"”$x0_Þ£ÛÛéõdö¯aH8 ¦Ñ0äŸG×_FŸÌÜíP’`t9M‡!– —À$[Œ‚ÉušNÇáÕôß—Óëá·ùgÓy«VWuŒ¨Òéϳûoh° þ8Ciƒ0@–’ vgŒÓˆ3JÝÌö,=ûG+°³ª?õ¹¢å )‹’düÚa\F1%´uf‡I  8.å°¯‹CS1bðƒ®¼£][®ãmél‹Ð,îo[¨jߤËLIDEÚ«6gÖlrC|Ï_ Q,ó²)¾"Dò½™ùŠ8ª,½ªªæq_” LâÈnƒ;Û„\D$á¬H"A!ÄÔv˲®óE›¬öÕn›=ä[ŠRÀ±°*.öCœyÖäZ×8h~TŠRn›×çj”?ŠfcÊlgxEðÕùK3ªJ+ÁX+mB¾4³u£µ5¦ç`Â!"á4º*á_ô[–e¿i/ëO €À’0ˆ ç&_”CM$(b"ÅšX•MV”‡gñøô°-¯ç‚1ÎÍ0+—=1€Áoi Æ>ƒ=Ú`ÆAa"N¨c¿ïécm'ÃqǸÜóMîÓRF‚´ÎŒÞpP $’–Éœô0¤(îh§F™úª°˜1”C˜¨YTúwiæšMÖX!Yiˆ‡Üù^‡‚š…¨¨:òãàgUÚí»ª¨ŒXv§fûbD©Q«& ;Bþ>»»XÅ $¡¢ú2™ïÖ 8z—wÒ a]Ë~áZ+$0u®}ûÄA*Á,9t/Ã]÷2ˆ³íºÚƒ»°~̺, Ÿ® Ûe­*{B‚ m5ÌWÏEõd?‡d‚Ï_Ì’Mäº*UÎÒ˜Âõ«8§Â²Êí÷eÕ‡‰6¼:ÛdÏ6×y™ï³­Øm–6jóý®¨ë¢*_ËT+d¥ÜJ¡Ü$ĈL§öFŸÒ߀"c(Êýz¨hHÔ)ãs‹u±.Uøt–ÍÁ¡nN€B@Ú˜ù}v=Q1#i~FË]QP¡²Æ„— îòUnL-¹™úœ•O™¯¢b¢˜ wÞ> x$° –áîbl$2D™GÃQB)y¯8¬ZÜíÕ8ýƶ^JÅ\Êþ¡~¹›™HH׫g¹ÏVMQ¸ÉJpëã÷E1DWˆ©òª×jªä:§zÏ?l™zq0ú2ÿxsw:fp}ì˼±*¿Ô¶¶nŽ!Ì«}S<í^÷ee±‹;F"I¹Ig€H€– ©^H¹Ì§üŒj×p»½¡˜ŒàÆ#Ó:‘a(Ã.|“CMQYö¦ª¶¿Ìƒ3Ò—²z¬! N ŒÂ•B9(J¼n w+Ð^ÐÅŒê »"ŽÑÃf-—Çü{fÆÎzØID\Æ.FÚzç)®€%9}sRj‘Ï6«kßE¡œy(zrÒ1ïјŠž›—ë¢ôy»ÏÖJ\”¸ÚfkŸá,b[­¼¶RBÆú‡s^¶û­=ûA¼BçæÀ€Mo¸=<‘ ð–ÇGÞÞ´ÔìäAþO~/NzIÁóý³»ÓÞçW§C¤ØZ«ö/~OÄ„ã¾û¦ÐW%IØß‡Ÿ<[(ªy5šÆ§9PøIr¨ù÷–ºýkÜýxÒ5ûª©Õáî?[êî¯Qzï«Vpе“è°‡®¨Ú-óç7ñ£J›¾§xûŽ 8\‡âê“âÂA-ÆàÝnNÊ|ã"è‡b+ïù¤¼mþœoß*ÊGaûÏ–úi©ò¡ô±e4¢œ°>‚˜LÓñÝìv>»¹ö<$´€Ë‡kŽa].x¿æénº uj¥A4 )ZÌT5,T·ëÑÃ(³Ÿ/sÕ®”º[„aQš_ƒš p+Ú/ÊåÁšBÔÐ3ÅL3×Ü{±lTÁ‘Ô•¡œ5fdÌSOµ]³'Pótvi(eÝ|(‘Ê’:[œ§RèO -Æ5¼ÖhÚì]›ß®½0,ì—Æ& HÂ8¸ˆAët™«FÜõ­ªéUCÁÍ«üÅl¬Ÿ7,†îl¬ß¤,¯ÞXDRtПxy "‘ åyà˜¸JQ­`§ÛW ^B?Å$hc÷ÐsÚ¨îW‹j·Ó± [€‘jp©i›Õ-$7[èG­˜ÙYMîžêÆRY³ØÈ×¶hªZÙK Ê©üŠÀo"Æþþ§ÿfƒ¥ØeŽGi(Ž(\®ýDлÊÀDZ’˜L‚‰»tôyµž‰¤GØŽ&éèÜ0]ƒQ´¿¨§‡û’ðX/K;†Ì=ï—€Óñøò&¡\*~à Ⱥ…ï3©½Ú.Ò„Á"ü_%+(uá–UUý +œ{’îQçr mÒ óÎH„&}ꩪ8)VªþšJb(‘óíª†½€"ÁÇÏ£qh½ç†ÎE1!ìpÆø©3fû ´«Ž<ªÌ‡˜ƒšZÛ M´5!s÷¥,2Ç¢T˺hŠç> endobj 2798 0 obj << /D [2796 0 R /XYZ 85.0394 794.5015 null] >> endobj 2799 0 obj << /D [2796 0 R /XYZ 85.0394 622.1918 null] >> endobj 2800 0 obj << /D [2796 0 R /XYZ 85.0394 546.3397 null] >> endobj 950 0 obj << /D [2796 0 R /XYZ 85.0394 506.7876 null] >> endobj 1563 0 obj << /D [2796 0 R /XYZ 85.0394 469.9509 null] >> endobj 2801 0 obj << /D [2796 0 R /XYZ 85.0394 437.6785 null] >> endobj 2802 0 obj << /D [2796 0 R /XYZ 85.0394 370.8598 null] >> endobj 2803 0 obj << /D [2796 0 R /XYZ 85.0394 262.107 null] >> endobj 2804 0 obj << /D [2796 0 R /XYZ 85.0394 143.6132 null] >> endobj 2795 0 obj << /Font << /F38 1122 0 R /F14 1060 0 R /F42 1338 0 R /F22 1037 0 R /F21 1034 0 R /F40 1265 0 R /F54 1433 0 R /F64 1485 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2807 0 obj << /Length 3386 /Filter /FlateDecode >> stream xÚ¥ËrÛ8òî¯PÕF®Š8xð…™“ÇQO&Ž7òìî¼”[¬P¤V¤ìq¾~»Ñ Š”(ù°•rØèÐoHŽü“£(b£Ì(1a ë 1z„±÷’q&iÒÅúéþâûw:™ÀÄ*Ý?tÖJ‘¦rt¿üc< Lp +ˆñÛÛÙlz=ù8ýíýôör"M™ñÕÝÝôöíÍ.'*€ ¨BŒ?]Ýþzõ õÝ]5¾z?]þuÿóÅô¾e«ËºyúïʼnÑvðó…4P=CCÒ5Z_„‘¢PkßS\Ì.þÙ.ØuSBŠ@éX œ…R³He’ȱVÚÅÍl)IÇe…_3ΊÇj›7«5uç5u×»ÈÿB]ʱ]¾Î47+[Ú—ÙÕìÕ$Üç¼(¨{né»«í’Ææ/Ô³´Ù®hx¡]Yغ¦XOõûwa—wš 2…#×M8½ýÉ0HTš0Jµiòª<ÞÅgŽ&:ƒP‹h4‘20Q¤Ü$·E·¿PÄã¦ë$?¯òÅŠÀEV[‚nApt»o‡æöМqhß: a©º±Ùd)N£ñŸ"pðÇÛöƒ$’gwˆ‰Qpg]JÑ8+[€¿ûÅ&Ì :Cö ½gºdõf•5uEš|͹k†ïbe_ÝMCã¡ÚroµÞdM>Ï‹¼yñS›Aî8é¸ÀM¤\4rs[5–nNþÜÇÆs=´>¤ÃN’D_ýµgôYÃÑdMµ}!Ô†%>_o »¶es nÅ„ÎÓÑ™]u–…¶—2[ØÞ¤å½s’°âÒâ…k)ÆïüaÜÏnÞóÁ~øtu=ùô6¢–[¾{&¥”ãàô©h­Æ N%„;}ûá uø5±i–­©Ÿ%К•ã½Ú=®:ó`<’Š&d»¦Zí-²¢x!œÚ6~¶%¤É}ãd]Á˜ÒVHƒ#)ƒDÊx‡:ÐBž0i„3é ‘A“ÆÝ#9™“ÎÄaWgdšH³Î|µ/uþÍò%ÁŒ†Z곌µHÇœõ”´4”*é±6ku«&© ƒ Ü­çvKpõ@ßyÞ0š3C Ø^š!q, “ЀXù•«*_ØþJˆë·k-íēׯüú~‘½¢“¥ÐA*µì‹7n¢ÎÁ…ƒ<àÁ´ÞÕ¨N:ÏÑa0h›gë<`8IC€ô %” Ü:¯ý6@Iu§FƒlQ¬³òEMÖÈ};ä¤J‰ $7 ´¡01j·l‰ƒÑf—žL¢<ijþëÉ@ƒvxl5äX î&ˆ•3ÑØaÿμì¼b‰ZÕ!‚³B–H‘©Ëñ4dwˆÃŽYÞs ɶ¼d3MG¢Ý7Üÿ´(rÐÝÛïÝöÉx6V˪üމ•ÖþfåmÙ&ÛfkÛ€dÃaš2'·J¥$£Œ*•Àâ¨'ØWV D g¼iÎó;~‹:òúîê¼|$0ãu)ôà>¿#'oÚ3t€ućðu÷;p ^}ÙQiâoUi©«ÎKÇ6H¸´“òHü>ûø]íü¡$ ib­l¼†§çþˆ ;7mi·Ycym玃‘P‚}M!šähäÌAÛÝ·ú³CÁJ­|H†Û P ÁùUÏö‰ã )¦»0-I't?ÚÐìákÿÞù"oÐ+a»ñ0Ÿc -ND’*B‹lÚH2b›/’P˜AŽviaòýDѳæBh-:¢£Ùø"Vƒ%üfßÐ!ªTC¸Ÿ$}¡iµòD ¡_Ïù|8ÃÈoîØÙ>á‘#¼H©Î»ä.ÖiŸÜb9VËWr‰–âe3à•ã ©9Ï\‹5À]ïx`T¡úìõ³Š)q@õ\¢_Vy"sÔùÐÃEC×úcGlF`è)+vûiÒ"“VÔº§pÀz‡Ñº³°¬Í8:xÎTÿ|;¥Ô|Š”c4€ù'AAªÙ“= £R[²TÊH_èr&dúÛ÷€Ôdü{CX>Ïî Í‘‚ïôöþæþ7ÝóÙÁºY]W‹œl¶Y}%£ŽUåvºgaO{Àÿ:›~ÁͪîΉj¬˜j|@5n©ÆÒc‚žlèÑ€_ñóý‡.¥ý±Ô P[ ÔL¸5Рd!Hm9˜FÔy“?YvÌoɲ°{u>¾|ÛÝœ‹Ø!˜ý¹P<Œ¢@iHÏ*~ë´â·Xû ¶K"cÀûŸ%é‘HvU"0ѲOòWJÐ%翊RÌÉ"ÛdóÂuSbé1½[d$êôz¡“^ÔƒçÂÚ‰›¿¢4\µEì¥>Ù¦æÊ§æÒy ×|ЭÕæ|ªw&&ßžûƒ¶KÊp¥³QòÒ5ùhyiÑ÷‹ô nƒœÈ4ç¹\¯Á¦Ã> ÓÐø¼Ü‘ƒ||@l‰€Šb—EKnC°Éíéõõ{4ìÿ!‡^C¸}3hur¤ìGuÂ(üÏ£ûpt€…½ªù:ƒ‚“z Ó4ˆâXŸ×ƒ.Öi=h±œ\éA(¡Ãó$=ÒÉ®$*i˜öI^”]RÈ‘ª¥ýª@^ÔkqA|«b9©›—~¤º•w6óh%«]㧸U!%²M¶Ìš eC˜ñOL¬­ð‘+ë¨@ ðŒÈ—-˺¶‹ ®<xTÐŽ$=pX\n“XÏE±[Zjp#óßÕÔ· QÈX9¡gIjî&Ìóû¡îº©hò’Úä):¢ñf›?ñrq÷È´–>~ÆyiDYºsJÝ2+²‡/i·Nú'8òš¾ÏÖi®&?¿ÙÍÁ6ð&± áÕ…M/drhÈ6 ö[ZÄãœQ§¾ÔÔÛó¥î¼n×Èê2>à”a> ca € q–ä50ÈÞÍEYðýéæöíç¢b%" $}E”TílXÜ–†aÍz·ÙÐÑ‚Ö-õi¡0nÕé+6¢ƒuÆFx,Çøb(HÆÒ~›‚- \3qJžgÌ# 0Ö;'0:ésvS.Q®Üñ„Ú †ƒ,à$PmMÔ}—4¸¨Ê&Ë)/íÍ¢p €ÌJÁØ«ìÉöðÔAއ+â9äÏÜôQ‘Cl®ò+|T JW½ò6©onû¥Ø³¹’JL µ|%dêbƒˉÁôÕ\É–àÏ2%BÁ•e­Åà­/ &5(p¹~¦Ä*Iç¸}Ù4Õã6Û¬|áhExùÜóÄ>j…Óå+x^ùâT¶Áè¦uÑÈcê(êþMø©q¶ ªÉ›ñ|—»Ì;5ÞÆôycËÙìjÜ}¼žýCºÐµR·Í¦Úº—(c¼u¼å>Ö†–ãÚøýBGÝlI þS©póuQK‰¯DFV>_Ú²Ù"–:¸®°ç tÉ\pp§ ¤ Œ»§Ã£}oG [ ŸwytøïÀÕ`-ÅnŸ\õ, &$;¼œIáÝVŽé\­º¦¾ìòS@vÛ8¦¡½WµÞ³þBÃèÏà0c[¢4Lhæ„™O­Ày7„Þ^Ö€÷ñ׊*x¢UßÇ´C{á@> endobj 2808 0 obj << /D [2806 0 R /XYZ 56.6929 794.5015 null] >> endobj 2805 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F42 1338 0 R /F21 1034 0 R /F64 1485 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2811 0 obj << /Length 3078 /Filter /FlateDecode >> stream xÚ¥Évã6òî¯Ð­é™+—™“ÓíîtwÇvfy™h ¶ù"‘ŠHÚq¾~ ¨J”<ïÍÓ`¡P(jCAbÆá'f¹a\z–š.Ìl±>ã³ût&gæ1Ö7·gï>ª|V°"•éìö>¢•3žçbv»ü%¹øúõòêÃçÏ¥áÉ%;ŸΓ/®~¾øa_Ï ™\|º¼9Ÿ‹"7 -åɇ«››Ë÷óï/ÿýéòêü×ÛïÎ.o¶bÖWާßÏ~ù•Ï–°ƒïÎ8S@mö œ‰¢³õ™6Š­T€¬ÎnÎ~F£~ê”(´É™‘:ÍMÆ ‘åÓãŒÀ @QnM I}¦4f=LQ¦n¶UMÀ›¶Û:ùbú®:Sf,L_‹¤}Yß5«?&CJ ŽQªRÚni·Û é(,:¡ÃC‡" tÏZ¦|`f@£kId†Z Tž\ ü {ƒZɆ`"•zæ[°áf‚œ3™‰blÍÁÉI-’G®´óv¶FÐ}Ó×K†„ ›²Å´L :IwI¨ºª\!°­ì“Å.0×6üOïÍ_ß xmËšV+2ÉÉh¥@»~XÙ©ü¥ëVÂx¹ºt~•Á h~]ÞU5BA}Öåªê^øf•Î1˜¤Ý@ö‡]â©:Yèú~ž<íÀõË•4énŠ[­ÚKY‡ËW¸•†Ü¢«Úû2ºàîâÛ'¬•ï¼rõбŽ;áË;áíD&Q0H° YêßÒ>f®v!äiæ¬ îÆåÅ —fÌÞÍÆ.*w³÷~™ ’:—IÛô^ ü±Â€×h‘Ý,ìM§oG»™€¹ñé·#ô‘tCË&¬ãr7LöþT-iz9áa$ ¢!÷zÒzòŠœeîZ9ÖòÁ¦÷}Pg”e»ä4 ÜÌï}é‚Ï\òä+™QjPÝ"º˜Â”‘xÜîi'„WíaÝ5˜a,i¤†xǦ6« Ë9ϧôco;s•¹è›ï¹îv|ªáæÊURû´Ûð<ñâ Íâ±tqÉ›&à¡s‹-€½©»Ü² ÷c˲#¢þr í­ŽU©jPŠr9fÅq9‘L‘Ü{!StVî6é)|`²;uS1Ì Ê’Na9!JÙBÓ®-e7x’è±ò³éi°…ÔcµÃÜžºe &ò¼8ívb¬ãngÀònçæÕ Œó‰Ç*>'ùÚU|›¬øŒ8{Oµ†Îë ûŒßX[ÅRóF GÝ·ýc³ª¾¶Ð!ÇÆATº9\Ù4ºéèÜÐM°œa¼¥RÐê¡ÙB¹öß)UÚ·Suž8  $/‹=Ÿ­ä![)B:”‘¤ÐbA"/0 Àºì|QðÝü¨ìPðÑdApŸWúT¿—˜JmÏPLЋû³ ëó|ê‚øÔħ›Ó.Á- I-¬iá9Ú‰®íȬa[QZ8;b!-þ¦"–&2¢ æ¹®ê~¿6A—•1'ÞÒÁ?‚§y{P-'ÕŽëáŠÓhùrüú'óO‘v1Öq0`yÐN¹Èo!§Rõ­­ºÇÃÌCÁµG¤§™°&¸×0rÆ3YŒÙÛË8¡ù:Â8G TTÌÈ™i1Ö©E¿¥»¥¡¶U7AOÜŽëðh°é·›¦µã¬p×-˜Jù+å‚넾,¯/·Sú"™6*„ÏíÖû¸}mQŠ©WY°&xi W07Ö9T²Š„î‰q:6@ÍpÉœü³ŸÜ`K ExLˆÈŽn {IÜuA*:=Êa²)tݺo;$}GKØ KW®¿{wÈ©ä ZÆSVì)Ùî œ¶ ®_Ee3øð×!h‡òtžD´o)`)ñ@ã?—ºõ(µ‹’èÜÑÒÍ\÷«å2ÐÇ8¦“ƒ§Œ'÷áy¬Šÿ\uäFo>r5>Žå=š,ÁËè<õ“n‡ qY“‘ÝÂ,ÞÃ¥áßþxñ~þz£…?|ëèÓs]Cj3Ä€p—ÄŠÑØ¡¿ú‚' ÓÉ+×Èë¸qXÞ8»Ék¤&Üe&-S8Ïkôi¾¬ ÆF–éN¤٘³ÏQ¦,C•‚ŽWR2´á'MKHÉT>T‰Ž–L™àfdXRRJK»÷ˆÑÒ?ß~ûþËÕG÷Ï…·ºúr$Œ`†",å|ïŠuõ%Ìõuè4T°Ó¸‚MïOÐÆ‹±Èõ 9«{»%d¯n2¼”A§¼«°ø–=Œ×>­ /Ǽ””Ì/:ýÎEF3ÐŽÝÖ‹í˦ éKW×xΙεxEã#¬°¼Æ?Mß`”Πfe]u_çA9dÎù$gÖkãh$˜4阵©?UØ»þáapNž³ãïühá?`N<óïN¼ò’Ø?ÊýÎL²ìäzçp½‘¸`.pñz_]I™ä! Òdðªk*ÉùBj’#> júÿAh÷G(W9æ× ̹ŒC¦ÜæD–»Þd2ùæóÕÜø[`bþUïïÊ@Îbr™Mlë¿)ç> endobj 2812 0 obj << /D [2810 0 R /XYZ 85.0394 794.5015 null] >> endobj 2809 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F64 1485 0 R /F22 1037 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2815 0 obj << /Length 3205 /Filter /FlateDecode >> stream xÚ­ZKsã6¾ûWè°U’+C|€•“;'g6v*;•É’(‹‰ôŠ”ç×o¿@%ÏÖ®} 4Æ×4¥F!ü«QœI¦³QšEAªx4ß\„£G{w¡„fꈦ>Õ7_}gì( ²D'£‡¥ÇË¡µjô°ø}rdÁ%p'×w÷÷7ßN¼ùøîæîrª2g“«nî®oÿu9ÕqÄ@†“÷Ww¿^ýÄ}.3=¹zwsùÇÃ7X¾è*4(Ó¿/~ÿ#-`?\„F/ð*ËôhsÅ&ˆ#c\ÏúâþâŸCo”¦ªB…6‰Ð…V#¥‚,ŽuOq$FRÆÃíûÛ»w¼¯Ÿ?<Üþ|G»‚¹ÚÓc8šê(È"Ѥë¼-˜“Æ“y^a#šÌ î(þzÚ^*;)š¦XðPYñP»še½Ýä-~„¿÷ﯯy¤Þö{¿ÿþýûûû€o—<ØñÉi¥Çݦ¨Zî™eÕàPænó óKÙ®d?Æ_Œ±‘ÈšÐ1 -«&eË#¥l²¬Úb+ÛjyWÀFsÙ]½ÄñeSÈä%Ñ×›ƒ½;ít"·å¦€ ›L¾s¢Ìë깨ʢš$’ž”KivóÕùu˃í3è—õz]¿ì*™Ì^ñ™NêªàŽzÉ,&t4;bû) õ_tÖ08~_ª ¤£ÉxS“º´™Œ_ºÖ¢k­\‹ö„³7¥ë‚U*^FÖKû»P¢zxÎëÍÓŽuT¥L{-ò­õ)ŒÃErV@5pð|Nvb’˜:š®êÝ–_ùkC*†S~¬êmY=òÀºÈŸ¸E‹Á2Jè6uÕ®„iuêêÖ O,ç±z)Š?Ýòž$HïÚ ¾MmÊ ´‚4&´ÔS1oËçbýz©”š¦¢(›üvÃÖZ`‰šÍR‚Ö?`aÇ‘%ýÀ)tYï0àF›àºhd½tŽ5—¿žÖå¼lׯÜ%ðfø—œûàRq»·"ðP³‚Ïš Ü—ÜÚ57ÆàyÌmBõÁZз1Žüµ R¥’QÅA¨Su¿2ÑÔ§rîõ8ÔtT(ýô;Ó$ò(a{6‹Á§ nü«zIÊ>O™(0‘JÏË×Q èûpe²½~OÀû¢¥³ åðmÆ'A]uÅÏ—UINsîù³xå÷ÒÍ®ù9&O»ÙºlV •ýp·ÈßpR ñvÙâñ0E‚PéæÈ¢ˆiœ©6Ñ¡_¯ÑÆ´D"p™Õ|½[°Yj BÚ9bM"È2Ôx<ªºí3Û5Žíž ø aÝ¢ÿ×ËÊ›- E¯P99–rLßñ³~jËZ8®Ø‰â4`³‚(ƒ!vÀ¡±(–ùnÝò [ŸeÿI#5ÛçL$©ÿ$ËN!P9˶.¹ÕU‘ÒG¼•³lî-ÛÔÇ>äh&|¤ç 0úNnÅç "c‰Ç„‘.ÒÛ´$"ójqЇ„ÀXÂ9æ`‘c{}‘5x݌Σϧ:¾ŽŠÐw;€>¸ÚZ“|øt t–¯£¯Ÿ[¥äܺ/ €Ï8§ ŸðAŸOÅFéæ×¦þ ?%¾oÞÎßmòWß%nò²:Á€eì(Ÿê¦lë-_˜´«ú…®Œpc ðª~ y&ƒD‰><Ÿê4ò:*B^9è×”Žò\Ä?‚Bïø8+[G5 \vʉ“¾t»ÄÕn’x81I’½˜Dµ¤+yÂ7þ„ó[©S˜8åÌ ºÝ•)tYXâŠg0õh WIì'V4° %|s¨Õà6»Áq¢®£~Ê·9W7°û•Ÿ¹­‹œgàÆÉr sÃÕ¸h_Å 3ÞI䤎d‹ÜÍ99>Xº)±Ó­¾k{Lú[?:&hÕÕ˜T˜¤ ]͆Ty3Ån±¯Ë¶qĂąÙ6öÁ¶¹oVà#d/œ »Ž¯ñ„–9§CÉ>˜_ãÊX¸tÌW å4è§}@”s[Á>‰®J²6xö‹¤Xløbá»›«:ⲬÀ!z‰›J‚² 9ëG °M‰úÐ]±úÐ/±ú0ï/‹yþþ„‚ŽQ NS§Äˆðe4läª1|ÅW&ƒ®9Ÿ‰àÆ({´R>†÷B tÜÛìæó¢iÈTaŽžˆkXm»_Îùˬ+æúíác½Ã€v<_á-¨†ŠüµùZ {(ÈKéj~åA™ãï‚ †ƒš»¢t*–oÆD]>æ—Ñ©ª 䌻ëqÿsq~yÕuì½r¯Ü¸‰7u§ø¨ºŽƒã×1-œ¸Ò:5_Æ" —Ö©oåZõaWhOì±ýÇ=§±Úà¹ï¶“lÒÑñU¿…W¾å¥«]'û*:4»Ú5¸öø±W­FŠÕêôk×h%’ök×½? ¤ƒýy©AW½æ¯^½/fôÑ+L0ŒGÏ#®½»¹»ùå ËÜ7×ÌäÇ›ŸñÙì7< ·ÌžJClWqwg©i FöØQû<“,H#W<Æ‚<æjT-Ìœõ.wë½óÔ6e#±XAímÎ]Më>ydüÈ]‚±¿Ó±‘/‚6!´3%BüXÁ_ðEžç_”ø7 tfánÞÕú¸‚šu¥ž)ÜÛ›ƒ{FÓBtg›“3<íZI:êž¹Ëú` äõý2I·Sh/ÝçãÄÐ9”•»fÃ1[.àøÜ«²0°q¨Ï©ö©(ÙR~~—*ÈÉ_üUz¸h ü”ÕçuDÇ‹öÒ½"Ëâþ¢xšG¨“ Ý‘—Í)õU9æA§•ê SéŸô}ª3ŠrTo*êÜ¢{E.:¬(Qüž° eâSŠª zlËyï²ÿ"ìÁ•ŒÑŸ™¯ë-8ÃÍiõÆàl,Üϫף:£^Gõ¦zÏ-ºWïá¢Ãêõ=åKŒLj“7‘¸÷.±Â+£3üe]·äñŠ xeüÊé‹îgoyç4„I™nŸ|IŒo_jNP¬uá2}>‚æ#IÊ,—ò|$µ¢˜«:’BðŽ€}[0䫤pý9á«ù¨v° ,ÏY†} ‘²Íñ÷…iJíöê÷.Óx?;JaT<)ììY¾BbF§]ôGæ÷äáüï•MtêNÕò`VÅ”iuê;¡)p‹YºÈÆÇŠ×ÀÄ“ßr|¤ø‹#~‡Œ ‘yíâöIù™`LÃ]2BüDSlùÜCºa×ÿÄ}å–/ ýJAŠ…sú¬ÐpTзgòÛ»©f°_k“þUóÛŸ~½¾q1épgEû”ûœjÁI†©rYÌ™®ZEöP½‘òÕyÎqÚÝøæLG`M?Oˆ­æŸØ`={.ëL›ÞÁôW«mêŠ ”.³”é ;'¢.d¾ûL;÷©m¢ú [åÏ…ŸK¬}ïŸKnóTl7eÓ¸KßÇ/!f°”vYëÿü“³} ˆÒÀX{¢8t nó›Û;I‡!¡……§¢Kpüø=[¥ö¸Œ&?[;ÞÕ&ÂŽendstream endobj 2814 0 obj << /Type /Page /Contents 2815 0 R /Resources 2813 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2794 0 R >> endobj 2816 0 obj << /D [2814 0 R /XYZ 56.6929 794.5015 null] >> endobj 2817 0 obj << /D [2814 0 R /XYZ 56.6929 752.4085 null] >> endobj 2818 0 obj << /D [2814 0 R /XYZ 56.6929 238.4558 null] >> endobj 2813 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F64 1485 0 R /F42 1338 0 R /F14 1060 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2821 0 obj << /Length 1680 /Filter /FlateDecode >> stream xÚ¥X[sÚ8~çWðÓZÕÝò¾Ñ„¶i›ËÚél›‚xŠí,6I³¿~,ÉØD½Lf‚$Ÿëw.2écø#}%f ïÇ GÑŸg=Ü_Á³÷=âh"Oµ©ÞN{oÞ1ÕOP"©ìO—-^ a¥Hºø>]]/NϾ #*ð`Œ†‘Àxp>ºø2úlÏ®† ŒÞ'È$œs "ØÐI<8½˜LÆ'Ñõøëå§ñðfú±7ž6zµu'˜¥þì}¿Áý˜ð±‡K”è?Â#’$´Ÿõ¸`HpÆüɺ7éýÞ0l=­_ ùB0…„¢qÀ”†œ!$eµ3ÞÕ±âÍ;Þ¦¥1ŒpM„~ê'KÔaHc$9¨l‰fù"Ä#‰…ôŒî7éìÒf‚ !OøcºÖå0b±Ì6C¢Úlä`¥s½ ûlYlì¢|Ê2]mÒ¹Ýê|¾yº¯Ò"·¯ÍÖ«b“Vw™ãYnçwŽ»;ùp>:‰Œbýˆ€ù„ŠV%BÐZ§óSñÚâC?èÜ®ª»b»ºókm÷ÛÛµÑìW졳¼ÞÚÇÞ´šíŸ[ Yë¼BÎA¤ß(°ÏDL Å!ÒFñ·ÑùÕçqÀ•@H¢’&5áÔ ¹ŒXï ÉÀj3ûKݦ•ÙÄ'#{jÕ„“ÚËæÄÚ'‹"›¥¹ xÒ 8A8&ÜRÿše÷kæEÐT  æiw÷2H]¯‹Ç4_Y‘À"³î„gÅv½°ç·Ž<-Ë­^üÐ)¢R"E¹‚€*D‘µ¼E^–z•+O U šÙßÚõÁ­ý¹GùÇåÅØ®Ž›ˆ»2§$;k`ã­±8É+ûSªkÀºXîa "“…LÞû©¥$z…1{E%‘øe}ÏLþ`S“'˜{s_7ݽsÄ1#.œ]÷‚ËÀl©ç6˜¥—¨­@_ ž— F_¥Øx x ÊR•­^–'ûl•`I‚b.H·Jì ?\ðƒŠ‡¥ò¥1”òQCÔIýÉxl£?ú<¹|¹¸@”é*ÿ«Èõ,°‚Ä…ãv“PH%Â+õöìâÔJJœÀE–æ) rVÕ%Ž®õRÛØåsÊóY¾­ƒNW –”MÂ?W€£Dæ®ßXŽT°$ÀDMþ5;ÅÅgÇ÷Ùèù‹ìÂf‰‰+‰»}™~¸¼~9²gy¥7¹võbòTVÚ48³9)ò²ØTé6ÛÉ…¦Î¥ï%Cú ËÇÌ70ë`¨f,ýPü¬a[÷°;V¼¦½˜eú€f ª9 ŒšU­ÕJc§¬×º)ev¤rx³ÍÈT¼¼S íøµë¢/÷ÉÉS^Ü—i¹?«Ar4Œ0­LúSaœA1ÂfʨšžºxhêòDmç8ǘ&ò=ºÛÜøåƒ5 $·R‡3d‚gÁ´†d·¤Tì VÃðk³ú`Ýí‹t£çÝOö‚#ID7LǦ&RøÚ¬óUšëÇ.YÃqÙ¬®o\µ¼B€U·Ú–éZS †¸C­é át<9¹>»šž]^X¸pîra¿ƒÅˆ±¦ÿ¸¶0 (-`%ÙVú±¶¥™yG²A©+÷ŠMÙNà`SAºTh“9~¤žaÍÁBιŽÍ6u/ØBtp9 µTê^?òFt»X»·Ò/×nL™¥›îHÒÌ´ÍìnÇœ¼‚A±`šlÏ‹ÇVuXìxBÿdþ½¬ƒ8yvsYI„€Û aÇS·MeoL$» •‘Ýí‹„[\_é‰"Û‚™‚›’Ó9Î|5Ü–³•s`¦Ëݦ™$õ¯ÔÞ‚>pC¢‹|Ò¢:âOUûĕ٩XÌÜèBU¥­®¶¦G•k¨Úu hŽUW»‰M°6ú@{V¥ú(uæñ.ïßèÂØî\ÞªÂþÚ³2]èƒa€– ŽG¡Et8ž¨ŽÁæ.)¢æžLž§y.¯ƒÊQÂdGÞh ³‡sܬîkx¯ôݾã@뫬xÐ{¯ÂUúŒ‡Þ?è[èe \uÔµ;šÃžu4µcBà&0KÅl¿wM%¢1—Çtjhž)µU B¶• aZßnW«&µNèÐ*¨¤æ³R@'ÜÔÜÿýõj÷™ŽCZ*EÃæÁ%Ï´ â•2ö‘nõ1m_BÌg8]ñ}«šO`ÏÍúËØºendstream endobj 2820 0 obj << /Type /Page /Contents 2821 0 R /Resources 2819 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2794 0 R >> endobj 2822 0 obj << /D [2820 0 R /XYZ 85.0394 794.5015 null] >> endobj 2823 0 obj << /D [2820 0 R /XYZ 85.0394 704.5976 null] >> endobj 2824 0 obj << /D [2820 0 R /XYZ 85.0394 558.8408 null] >> endobj 2825 0 obj << /D [2820 0 R /XYZ 85.0394 497.7352 null] >> endobj 954 0 obj << /D [2820 0 R /XYZ 85.0394 460.1226 null] >> endobj 2826 0 obj << /D [2820 0 R /XYZ 85.0394 427.6955 null] >> endobj 2827 0 obj << /D [2820 0 R /XYZ 85.0394 392.7171 null] >> endobj 2828 0 obj << /D [2820 0 R /XYZ 85.0394 328.6896 null] >> endobj 2829 0 obj << /D [2820 0 R /XYZ 85.0394 258.5937 null] >> endobj 2830 0 obj << /D [2820 0 R /XYZ 85.0394 185.533 null] >> endobj 2819 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F42 1338 0 R /F21 1034 0 R /F49 1358 0 R /F40 1265 0 R /F54 1433 0 R /F64 1485 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2833 0 obj << /Length 2267 /Filter /FlateDecode >> stream xÚµ]sÛ¸ñÝ¿B3}¨îÛê±Î÷[µ²SÛ¼¾$Ùtýl¿±­ì÷ÐÈ¿Yèy+âóý¾P«|YH£÷IDS”±8±bÐBüËâgbúóíÝ…Tc¿Ëƒ*Z >«vk¡{YÎçïíàþÝõü/„À@àis¸$Óý¾ª[-‹pOi-7ù¡hÝÈH-üya¢iÁ{-ü…R¾ÿ¶jÑ£ô zØšS`Ÿ ÇÔˆ¯Ö²lOJdpìÒ~OrÂÀÙÀí6ׇ¢bºò¸ëZ=¹ÕÜ~ÆÐ+«•,d·Um'ü7`˜mdý¤Vn°«ÖQHüƒ6NÄqv`„8;0‚ôŒ³ƒž²vÐP !¥…ÖôBOô£]þ‚c ÊLd©½!²;#§dP2£ñTµ½3Ö@`›Œ½Ãu®ºÏcTmFK'çÐxF7Õ¬¶3…ZÖy}´ƒ¦‹…µË!*·€ö-¼>ytrŒ³¹$¡Å„“×sIë|.é°L.Ù¼Hª eYœ½ÎÒ#XöSD’¡,IÉåÛÊhÍx& =Y?ת•ס’L¯sˆûÆf¸ü§ˆg u)n]6\Eµ|ª¾I‡>à x:lcbàf8YКÓi)ŸíÌ7y´À>Wµ…ä“É$©ÅÎíP›µp”òÂÆH¾vûåTcòÀpK¬¶:˜tE¥Ê b:ïÊ‹Ç $ÜîܰtŽc%àöæŒ_Z ´.z[8þYŸŠSh’Ñ×}ªuÞ§:,ãS‹šbÆ_gé‘,G5É ¼°4õH#ÎÚüñŒÒ:wô×fŸ>¾›Yx©ñF:`ypÀÚ厲jdž0ë bôعÀÜ!F1¡˜de˜ÙP™ÏœWïç>ŽÍýžHú!Œe©ócf¡ÙÈqocFÇL¸àp—$ðŽÝz§Jpa/huÈ´G+Wî@òò±Ä=M’Ä‘ À‘Ⱥà|x{m)BMô8A”ÇÄa‡õGE P:ÔßÕo‹||ø¾ânËVÖ¥·íüØ´rçÊ—ëªlàòW‡Ý‰-GŒ'ÔÑáp”8¡]U<†JÝÙ¦U;éoI‰¤¶¸¼Ëw2,ÃP‹âM={¤NTyÞëÕΖïd›¯óÖ]>oS7¶ Èi{@½Øëպ屬öjÆaÎ id ›€í¡2Ì‚õ8”i‚š:õÕ´Ó'ar§´Óa…4•€>G›¯zgªfÎ?])ª–+ðx§‚!KŽÚù`Gô}€(OL u7O[È‘ F³1¹ûï’3Ê7Õf£3ÑK²I —ãc²W²PAÇ&ÀWÑ¡é?ü±o Ù›CvûÕ^ñ,Å(!xtÅŽ>u˜O ÅNEæû·êŽÛPÂ,cÖ³ïžèÔŽ(ÑEÈUÈðE•aĨn{áf6¿~¸½_Ü~¼ Tn]¶¥¡@}™AЄúëÃ×V¦oÈtÒÒŸ´I¡ WOy+í‚I€ðšÙ¤ ) ÓÆn2s°ÁgL Ÿ2¦ÆÍïAA¯'–~ë6¤ÛÈdÐmø ^™NÃÃs€ å‘Ô!øˆþS4þ4nÿ È4ÄX àÏ:”„÷>™Cj1"qç Õ^¿¹4ú9ŒòéÂØ¨÷Ì#Ó3JµYJ;µtˆÐ[¬íÚòê1D†H/8OUå«2èªÇ1-— ×–ÞÛUÿ ê®,MÄ054Õ¦ ¿€¬%Ô%;ÛäŸAF—½j†—¾‘=, ÕlåúôbE3›|Q»­Åz¸ÑêiP-ø“ôÐZq¤e»B]smÞb[[AÑͰ.õ1˜îøÜ HÒø)kV;¯Ü×Ûfµì6؉UµÛÙÆºå620¬½_Z•B½Àb–Œ¬z6ÿ$2âڨݾ8Z^{÷ È|ÿȰ³‚™± Äšš&ˆf1Æþ°öZÅ­í½îUùZ1Ö´{õ¢Âùí§1=m2W¡©> endobj 2834 0 obj << /D [2832 0 R /XYZ 56.6929 794.5015 null] >> endobj 2835 0 obj << /D [2832 0 R /XYZ 56.6929 531.5835 null] >> endobj 2836 0 obj << /D [2832 0 R /XYZ 56.6929 464.7783 null] >> endobj 958 0 obj << /D [2832 0 R /XYZ 56.6929 423.2053 null] >> endobj 1564 0 obj << /D [2832 0 R /XYZ 56.6929 389.039 null] >> endobj 2837 0 obj << /D [2832 0 R /XYZ 56.6929 352.3213 null] >> endobj 2838 0 obj << /D [2832 0 R /XYZ 56.6929 282.5943 null] >> endobj 2839 0 obj << /D [2832 0 R /XYZ 56.6929 194.8436 null] >> endobj 2831 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F64 1485 0 R /F40 1265 0 R /F42 1338 0 R /F54 1433 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2843 0 obj << /Length 3022 /Filter /FlateDecode >> stream xÚµ]sÛ6òÝ¿B3÷`z.b ‚àÇ£[»­›8ñEºëuš>P$qB‘:‘²ãþú[`(StÒ›‹'Cp±Xìö›ðÇ&©ðžE“$‹|01)¶Ád s?]0™¤©‹õýüâ»y:Éü,ãÉ|åÐJý MÙd¾üÝ»~x¸}s÷ï«i(ïÖ¿šŠ ðî¯ßÿóú®²Ð»þévv5eg! 1¦ðâÀ»y?›Ýþ0ÝÎçw÷·W̹¸[Æ\æYÀWÿ¹øý`²~¹|ž¥bò/ϲ,œl/"Á}qn ÕÅìâ– 3«—)CðÔi˜ h#dà<"ì©Cd~ÌC®Õñáa~÷áýì…$ÐX†~ÂE2lBšºXfã3,µïtuºeú¡âjtKƒ4°eèl™%~ÈxÜßòÇfÅR¯`æ,õòZ=ï°[æÁšÂpÞ«åtÕì·y‡ïŸå3"<•ÝAuƒ­ìr ”#ôS„²Z¶à6`Cï×+!÷”Ñ5w·Bv½T 4özÌ«ƒlqœ# Äiw²(µW.•n’Lm\i”ХмÝaQ)ƒV.ð•zI”‹®|´\ Lë´ÄòäUÛ`xÕš€'jM 0èË®f´ìgBTA| 6¢\¬ó!ÊbéõY9˜ ²ÈÌ‘,÷²èšýó)oL„°ãxœ9‹5À{°™H|ž¤}îf²kOôìàÙÑ,iPYãóiS›tty(·¨$Q;zc2H¹1>ãÁÆÍà`˜Á`i3¼2óÓLp²C×U/,À"?1ΗÅ`¬g–ùi”¦}ÎÐ<Œ(®Á`)Wù¡êðe>GÓ >-¡A2 K"›aTƒR4õ£ÜcDTàÚÐÍñÅÉÛÛßpüñ£,z,Ú€¬:¨S3Óþq-·»wRA wRÑŠBãŸM-)ÄR&SXí1¢i€–!::QP@Œ•N–6r#¨ÄðͼC ny¤zŒg@('x^Qü]>ãLŽpRÆ@ÎøøÑá’"ö®Ê ˆ[˜920,òVöd‹=ù¥l1kª7+éSs¨ jj‰¯Ë?:…´B.%L׆òŒBylµc'îT7Ä®å[Eâ ëê(Nq}L%Jœ¹<Ôx‹k•¼q³Q(Ñ`dÝ[½tDÖ.˜}¸¶+}©jÅìh2™ÞfH–}Ô?‡>K~ƒ"(õ£85qjF‹ˆPjðä2aìG#Ôé¶y41²¤¼´Ò3Ív °bqt&V ž¨Ê.•.ÖùXi±t¬Ü¼¨ª¡†Œ¢W¶4H[öªêÌBq²åíÖhãÐækÒÀŽ­}Á²àÝy ´:á+†‹5¢ƒ¥uò¯:‰¡;K’ñ- ÒÀ–=o ô–Yˇ=DLòˆØ-J:cy €³Šˆ’ÄÿLÇábW„ÅÒŠxN¤ x…ߘJQ’³æ»]Uù¢Â¢oÙÁO¹€b‰%~ÆC4ݯˆ¹ìû»÷78Ò‰ž‹C©£< ©ƒÑ‡¬g³wøòðö‡ÙßS­0t‡$GUx(^²ÌdEÀ£ŒAošëÌÈ €¶Û£§ÀøSF»ÏE˘%LæiJÚº;*‘ØûÃóÈ'¼‘õ˜ª™0ƒº€p—ûò‘fs|œZ@Í…¬ä>ïtó0 WýÑþ±,èeÛ,§CµÌAgeŒìÀ!í 8 °pÙAÐjTCRL+k5á°þŒÓŸ€2cY+o˜âÊ))9Lu÷¡ÀzЭ±†ÓúI³—wÔ˜èËwêè¶)lÁ`{ åbŸ›FÇéo)î–9u7àŠy%ùôè¾½qq®È¦ÏÕ‘ñÈOà¼)–çw÷wïBbÎuÙÉ pqÄ"½èÆ´Ä‚¼zcs ¿˜—j߈ŠNq¬í­Lþÿîïonp«ä#ôçŸïïg3'±žŒŽtÐ¥Ö‡-]$¨Â\¹r¦ã% •ù—¿4w%˜^Ri^vnª[¹'±lßÓdNÒ…a~eËX§~re?¹ûÇ»X_â¡VU3T—².L'R®èŠåPlÆ÷-]sÕTUó¤yg±·PŽÅ¯ÑÇÚ=€l =h²Êé¾h[Ãä%T~žÖ4X—ۇܻ|²£¥mÌHˤVoK¢ÛfZʼn+#Õóh¶»ê°JZö,ó=1¥ŽïR*>k9Ø7 RÇa4Ý4‡=¾,óçV«¬¼®Š´0QÉ|‡#½E…·mênCDû»kÝ/8³CêIÊÏf{‡…oÆXæŸzó¶¬A+G„梄Š]•½½ä ªþí, çøp ¬É˜ææzÆ€wm x:ÆPК(IpW}¬ö›« ÎjK‚vU—i´›¾/P°KÕ¦\ÒÎû!^ÖP áì_ž-“Â(òãèÌw[&¹XçË$‹¥Ë¤‡WË$%ÖwÍJkì´VŠC?N_ãÏb 0Ø«•b(,ãLô9¤ Ó-̵?džŸ¦å‡É!xGfJš,°¥Ç‚ˆè{Òv£ îLÛMÔM‰ÊÐP-\¯:º2[B*}f mª .Å^ÈÅÐ}¾{“ZÖEuXšÄg®ülýC˜Zp VíHïbtãÔ†-œzÓ÷žw­@U²ÐŽ»–ƒ5âZK»Öõ«·°cžù\°tœ=‹5À_ß³2ŸsÎú Ò-  ¦ôéFʳ¸ˆŒgõ°ð"NàÅ™žið¹ ºf×_bÈ'ä@HD9ÙK9PÊ(Óפ‰."¤ ;)‚¿Öl+ÿ½„ÅÒ&÷ë¼—X,í%‡½$Xø5nÂýÄ%9ì%ˆ4À^ßIR?I ìõø#'II«j@N’bøQOã$.š2¥Z>E}+c/ Ð8ÄÜöØ|Öž’@(1ž’šPc6O‰Xø‚<3ž’GOIý4ÌN>&B.äùzmŒŸ·î÷Ãj"î^DšoŽVÖÙ^Òø«îÇ2þ¿òÂÅq?ƒ¥ÝïnÀý2HW¼¿Âû?Jb>ΞÅà¯ïÂD’ô$ÿã&HÀÀ|ß%ÿˆñ?‹>Ô2ô?5Óà¢!PÉOŸž”ùT.Æm»lvÔ‚‡è›Á šy;´¾(|ÁXòÍQëÍIÞ+ÿoù/I|è,^ùé üL‚´_Ý …5õã’äë’_šeé(oé%s§©j/ÖãŽjªÐ”Å!75•êi”ÎÂÐÖT.VU0(ÍúŸÚ°h)+‰yÌNšÞ½p[&‡é]²oHßÈáY5õZîmÌÀ ûíÂ7„' qª±1an›?»‘p›—õö«+bîš¶ÔŸkU?Bîº.TóPËûª:÷3#'&«À^jüÏ?A:þØ*J tHÏ„@ Å3f˜R*e)»R¹“ÐÜ ‚p”€‰éCt*•ýÓK±þ qN¢endstream endobj 2842 0 obj << /Type /Page /Contents 2843 0 R /Resources 2841 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2840 0 R >> endobj 2844 0 obj << /D [2842 0 R /XYZ 85.0394 794.5015 null] >> endobj 2845 0 obj << /D [2842 0 R /XYZ 85.0394 752.4085 null] >> endobj 2846 0 obj << /D [2842 0 R /XYZ 85.0394 352.0299 null] >> endobj 2841 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F64 1485 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2849 0 obj << /Length 2501 /Filter /FlateDecode >> stream xÚ­Y[sÛº~÷¯Ð›é‹@${ž|'õi"»¶3í4É-Q6O(R©8ʯï. H ²¶“™\.öòaoùˆÁ?>R:Ô©HGq*CŸMGlôßÞqË3vLã>×ïwGgï¢d”†©zt7ïÉJB–$|t7û\„\„' ‚o'··oÆ·—ï'ÿºš\œŒy"xœ___LÞ^þód,~`f,øx>ùtþh×'©Îß_Üž|½ûãè⮳¬o=gšõï£Ï_ÙhNüqÄÂ(MÔè ^XÈÓTŒGRE¡’Qä(åÑíÑß;½¯f« ©’P ©¦|÷bÆÃ˜s`Š%Uœ¤f‚û0s\ˆÙØ8zöNË'ça’*°Ì°,Wù,ŸæMS¯NÆðú–ovÑá`¨PbÔ·`ÏNÇä±Sôµë(30ô6/ói‹‡$ƒ ÊØaÞçhRž‹é#ÑÚÇœ–K÷yQ=mQÏŠ/Œ‰|f÷eI_îs¢d½ç?–e1-¬âf=µ@Ä2€è‰„ î@ 1'<ÔDéàKø‰fWÙ"?…Í: ²ò¡^íã¼ÇASüì>Uhˆ«7K4@« ž[ŠñËÕ O‚ÞQ ‘œƒÅbÝ´´1ÿqƒlÚ–z_d­ÁÄȪ+mO¼•ä`B˜s…Òk x.Áô|1ÚŠïY[Ô¾GÁ,kíTƒÏ–X£‚†n´â‚N9îíÖ&o‰ÐÖ"(ª_Pha=¢Ãé°´§Éé4á¨y°\ßÃÁ[H ¿]´p-œlÅOh+Z'¦o)28)ÝÖWÔ¾nB†®û2“dêdVÇ­­˜®lE»ÊÞN›¦H£´ ²É #˜ ë6ÒÀm¢ÝçxÀv—«“Ó¡Òóž0¦uå-3ßóU“—§Ø4TP`™âÌ–)nË nç ÒlU6´Ÿ`‘`€ÅÅ "rÖí倨–ôñÛú‹"­Nª¿ ót ” ‚VÙr…–½ ;A0µ©HA_‘°ù‰ØöAá„Û¸‘DF!wí¾Ñ;ök|·ýl‰Ðo8½}YUƒBKt¹‹(™„0(mmÒÛ½žá9õ^¹Pt‚»µø7ZCžŠÆBG³ÆvÇÏܨ«wÀ‹Œ’s„(¦}Ä•‹¤A+„}s€¬AÇ”ºÈf!2gFôÃz‘W-}2˜G8R•eýdÂ,¢êÔºÚÊ6+ R~m´alþÈ­ŒãͱQ¬ƒãEÝ-ŸŽ­5dzŽöèVpL(ű”öJ€ÔeI°á@nmG&ÇG_6y¶j¬¸E]µîå)Ï¿¹5ž]>ÖkËTô•iÞP‘-©Á䄤r™ú²æ'x 0‡­í)gôèÃwj“éÑ„7vü3|VV…hFÞ4èÊùjo˜2 ˜rMÈÜà›¹vùw4!Ý\ì}òìì›& —ÉÜÈìpš/C!XbYê¥RP]¶!M÷ö®i§êì¶èCÖÒÈOSôEÊÈ ,¶“~žÓ“Ò4eV e*ÐK(0Y¦šžE5ÃÖiw¸ |pà¡àU4ØoËÃ_<8D¬ LI˜Ä°‡Y—©ãŒ%Wa*¥ÚrИXSrÙ ~1ä§ âæsX’ük¯±Pªg€‘שŽ´±:¨‰³Â5võõü*yPÕ`˜}V“€pá.´n~Ý)‚ï{ý:¿ 7EÜá¥G$2X¤R¾À«½æ9¼3«•&¯•O;H溋 ·^_¥NÄÀ×¾ÎY1?ÐÒH}‡?.î7¸¬´½Ý¤R_’+§]›ô•†H‡R2¹- æW:[+wL‡¶Ÿèîœü3‚1Ô¼bÒ@å‹ 2âüÃí•G°6€¾ûW_˜b üÇ­np(ªŸP]zŸÉ;Ö?Ž˜…"M]èý~9yKBRkÎ †‚¢iá®ëâ&ŸÓÌœWS äǬZg><¸†Î µKWŸ01%]0Þ¼{CãÜ#Oòî¹üY|£D†q*’¾çŸîþzuó°š²§Á*·¡s»iÚ|a;ü›º‚{N[¬[µ2„°r$ µŽE÷cùɘ3¶wnnd˜Ø;Ú$óÎwhTS¥‡ó “cŒúý‡Vô›¼½Ôtß‘»›êÚº.}±a(nªzÙÍî(Á ’èê.ïOê¬f¶xv”é‹0s ãÜ(Óqy½Ç$ü<ξºÕ”+Vp)©WP%C-ºP턾íVñ07Ä*râóꡨ|5ihE'1÷HÄ+7”{¦†¥<¯fãíµbØã¡<‰nê„Ï_Dn]Ëu;ž¥O,¹&wÅ>t«Çnõ7ª&*Éåü·í·xÙmXÐzUB¸^¬Awq1ĺÉW…«Ž¯9Æò師YQ½^âÇÿ»ÄâE‰ýŸ_a—¯iÌܦ|³!Ô—hïàÿôžô= s×pý³ÀaÚ‡‚†Ù_¼hqSgc:ÿÃfcÓ|¯üÔ/'ܪxø•C»zu D8c–ì%Ãu·Z~=ô—]P„ŽõôÖõ¢ÿù¯¾Û?pCŒEI"ü7Ñ›v&Ÿƒâñµ„þ­D,žˆý›;ŒMtþ}¯þw=ãendstream endobj 2848 0 obj << /Type /Page /Contents 2849 0 R /Resources 2847 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2840 0 R >> endobj 2850 0 obj << /D [2848 0 R /XYZ 56.6929 794.5015 null] >> endobj 2851 0 obj << /D [2848 0 R /XYZ 56.6929 501.1626 null] >> endobj 2852 0 obj << /D [2848 0 R /XYZ 56.6929 344.6475 null] >> endobj 2853 0 obj << /D [2848 0 R /XYZ 56.6929 284.0149 null] >> endobj 962 0 obj << /D [2848 0 R /XYZ 56.6929 246.7311 null] >> endobj 2854 0 obj << /D [2848 0 R /XYZ 56.6929 210.8905 null] >> endobj 2855 0 obj << /D [2848 0 R /XYZ 56.6929 179.6142 null] >> endobj 2856 0 obj << /D [2848 0 R /XYZ 56.6929 116.0598 null] >> endobj 2847 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F64 1485 0 R /F22 1037 0 R /F42 1338 0 R /F40 1265 0 R /F54 1433 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2859 0 obj << /Length 3224 /Filter /FlateDecode >> stream xÚ¥ZK“Û6¾Ï¯PÕîSe"x|äæx&Þ‰±×šd³q| $ŽÄ2EjEjÆ“_¿Ýh€"%HÊÖ–M ÑèÇ׀ĄÃOLR͸ʢI’ELs¡'óõŸ,¡ïí•°<¡c ‡\?<\}÷£J'ËbOc¥Œ§©˜<,>¯?~¼½¿¹ûí:”š·ì:Ôœ?¿¾ÿåõ{¢}¼Îdðúííô:© 0 ‰|1nî§ÓÛ7áôîíýïîo¯¿<ütuûÐK6”^p…býçêó>YÀ"~ºâLe©ž<à g"Ëäd}iÅt¤”£TWÓ«özͧ>mh•2ÊÄ£ŽHÔ!8´£x’èŒÅJ*£ŽÏá§/×a *ønq9ßý¨£ÁG0?¨æ7ÜÛ¼^4ëEñDœ£áuÄb®…åìö­Ö3|¬Y¢•¶µ]¾í®\¾ñ3–$:=ÿÁ3ªÒ,µµë*Ïp"a™’GÃu}k×·žÜ÷íEâð•OÄ7`^Ôm[Ìö\Ö8¯ý`¸†$aJF‰S0¶dâ(Èñ¡Œ¸Z”Á]G¤eQ£R Ëxñ†:À÷ˆôéÄ¢m¯EóÆ<nlbTÁÆ›Ån^Œ§EA ;ÚS±ma¨£y$å:¹GºíV V™¥NêHÇÁѲ±Û–ݵ^,¡Ë»]KÀ°†¶(ªbi7Üt<’„kêî'èå¢Ñ¬¡þÁ5ïVyGô²}Š"x^ðá–x:'Ï|UV‹½¸-QsR˜Y$¯Î,€zMh¶ô¬›&ôR¶ô\`¹ë’„„÷Ù =izhê‹¶¨çãå³!ñÑ}^GLB°¶Æ¦ÜÇÆ ü+KËöç²²£?º9‹|¾¢–S 4i}ž¡¸Ä !Æ®ñÁxÅô(çqÆ5$WÄ¡Àf¼Û2…C.“¢FþåògÏ…ó†ùá”™b ¥:;¥còL9Ô`%2=žò×k†UlËG»¯yUQÃy§Õ!*˜¹ÝlvR7QÌt–Åt3à:£Çet3§ Œ£QÌgR cçUÞ¶‡‚ cB§éyÉz.h£$£¼D\Œe›nŠy‰æX´Î(ÊZ£‘mä =Sož^…Š˜E<Ò:à:£PÇeúæÈØ4 °,;?¥còL9ÎÆœi%äxÎ7ÍzAqVVeö¦b¬›Eñ=@N%‚·Öâ¨Ã(Dm£@z’o$X)ÑPÁu¾ö¥--X$z,çB Î_ÖVŽÅ¢ìLÚP‹»Æ#V*Yše./ÚBÁE¡\œƒ¨_[<Å~hpáq8Ï,ë¥ ¯½I½:»¶‡ð¦Z¶Ï¦Æ½…#‘ ˆÂ©ê/ €ÉYæ°ÒI€OjÐçYr6ðžËøÂ1À02íPÞ¢Üó®Ù¾E ÍYÅÈYá“G¸‘Ñj€þ"RcéÞ7Í×ýÛT¦ÇÓC“òdD·'ÞpűŽ|.3*Š ‹¨tä ÖÊÚ3®¸Í…O‘‡Ö<Âó§íà:ì`ÀuÆ—±ƒ›£@3ðÃäü”ŽÉ3åQÙ¡’ñ”vÝfèM¥IÐÔ†º[ƒ.ˆÄ1š%Z÷²A…#g¾ëš5Ê9dãê]çu¾,,ëìÅã Ê„„gñÿè nc \DR%CÀ›@Ë€ïW4!bóW¶Q ãf€aB…(5!PŽ C£3†O¯&ÚŒÇÃÁƒ»Gêm×PÛ¦‹jø‚x؇#ÅâT¹¢#œzIBî<â[ñ->!*.p‘Ja²~wûo¯œve5›—ªmìPuHª‘àé±Báf%X²ƒú«ˆDQ¡xd'hwUG«RŸ} =Ï1ápÌ,¡¬i÷FÏÎ ×lËeYç}D•Äá˜Ïe·òØ €B'Âyþßïîß¼ÿåæÖçÉ’éDêޓͨ+£J”acò¤­Y%“½‘•Àª È°YÈf£y³žíË‹½ŒA ïé…¨êÝæÏ¾ 8ʳ¯|Á•ei_ê»ÁÖùæ/ 6ªpZιÅËõn=sét·Y丯'ƒ‚²3;uÌÕ»!×é`×s™ÅÜ^LzE –Re< Œå¼h=—G¶1NNX’Â~„û"¨NuªÁ¦‚7«¨(íE“­p£`EŽ·xîÐt7ÔK¸„t€2ß¾lºf¹Í7«rN¤fãÎ_Ül;S(¢,-±äôÚΛ–*}¶Æ•3dSk]3¤cP9@_6ž±¾ O¡t(:ÐKš?ÜÝßPËÔßðœíʪ£¦ñ Óú°)êéô=½||÷fú7e{ÓìŒf›m÷Ê4¸‘ÅcáÆ¾‘ö\’â)Æ–P$´ÿ2Ú|·B`ËŽô Ê\ùÎÊEQwûS€BkzîåTÜÙiÛà ™Q CÒb[>ÙÞœ‡Ûˆ=óyQáNµ*ë‰ðô˜ˆ2þùTÎí T¡Oü]eŽx2a÷OZh”à6O·H¢}ÀTÄFhdè·;¢¿P7¦0Pf ˜L>¤/C«dÈJh–ReGìýf¦„b¶nt“w«µåÞ8ú£šæ©ìqUζùÖqï€ÖxŸJ[N  ð¸òpo'ÛLK"™žoC®Óá­ç2ámé9!I³øÂ”ŽÉ3åÁ Iš$SªR@f7Szã@IÆÙ±×ž=aÓÉa³?ôä70Ö2¾ˆ÷3–€/žÅû ‹¸Œ÷¡*áI4ÂûùEÁí·²µ°VufÉ)øžakVذ Ê“1ÆNF¯›'DB§¬V§3y!)¹ÎXã2VóΗÓý‘ã™BP2•Åñyáz.tãR0a*IÇÒ½3I„gVG›¦-Q’ï)›³¥GˑӤ¥½0’‰ <…ˆGÐ$7 SþÝçQ‚aP òFÁ2h ‚Æ}€·£P –Eêà*â( A–$ k öÆã‘ãI+Ì•Èy+r¶‚žËXÁ׋Ðóù¡ˆ`¢ÏËÕsyãØŒ¥T#É®!“‚0-*)Ʊ j`áŠyŽèrP0 ¹Øl{r^¿ôÃ*_š:L*‡ån±¼i¯s;…©E„3F ä2ÅK›; ÇK»Ó§ÆxD"3‘]Øó×™=w\fÏ+ÏžgLHíŠÆÚt¾1FÃ0)ÀÄó’õ\ÑÆ!dƒ­˶O,ý}•nÞc½ü+ÑðÄPËÚ2õg‘H5nÛ"G¡ÁU³öBgW¦M<·£·æFÎV¥Øgµaú nŒ«oèÖÖ¸ŒÇ:»ÌÁ¦‘œ² Ð"n†\glÂq›øÙ &ÜÕÀëü›½KE …2XÎYÑz.lã³l)?Ë6- >çÊê ªj¥\ïÖD}xxOT×{¾ÁM'ôÚkK¬j^×/D³Ÿª`U.éÑ|מ“j ŠÓ{p°WÇ!)“î ÚÎPô²6§`HsGPP8‚aœf€i GȘ‚ >ÉNðFwAwô>’4…Ä+RqQДEI D.ãÈ 1çuè Qlƒ ’xÙPD0/¶8H÷B yÛ‹6°¢,¼,ÚÎÕ´m9«l7í4J{\"$gIv”WÉgâýÞj½?ÚOlEf8èº6ÆÊóqW'ye|­›gj=S¡ }´²ª²±ÁÔšóÜÞP=2ߊ¤ƒª©íê€:XòØ?hZ³âq_%ƒyŒ¯‘¦]aȱè²|³ÂHͭԪœ3us™ÑwµM…WÔem ZÅ·M¹ŸY/ã÷GqæS¢Ìóùª ˆ¤ƒßí¥º“ÎS‘íå~³”L\©(c[‡#mŸZwÕì*Ë;³ßÏ›sëÒ*Æöâfb¯Ù$äô¾Î;¨6ê¥ï„žk–ª$Ù;GˆÆú]$ÁC1ï]Ä{•E}õ1ÞæÝ©”føo.O„äý üÿý§±ýÿã–Bru)ŽwPY¡Pz‘ªkÄí‰t‡.›€áÇèpUý?ÏŽ—õ_Ñß´Ëendstream endobj 2858 0 obj << /Type /Page /Contents 2859 0 R /Resources 2857 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2840 0 R >> endobj 2860 0 obj << /D [2858 0 R /XYZ 85.0394 794.5015 null] >> endobj 2861 0 obj << /D [2858 0 R /XYZ 85.0394 692.2159 null] >> endobj 2862 0 obj << /D [2858 0 R /XYZ 85.0394 606.7748 null] >> endobj 2857 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F54 1433 0 R /F21 1034 0 R /F22 1037 0 R /F64 1485 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2865 0 obj << /Length 3727 /Filter /FlateDecode >> stream xÚÅZM{Û6¾ûWøéI~±ø"tOi“vÓnÜlìnÛm{ %*b+‘ªHÅqýÎ`IQv¶{Xû p8ƒÁ;€¼ð//S›X¯üeæM’ ™^.¶âò¼ûúB2Ï<2Íû\_Ü^|ö•v—>ñVÙËÛU¯/—çäåíòçÙËDªä º³×77/¿œß¼úúúßß]¿¼šK§d6{þæÍËë¯~¼š«T?0 1{ýüúûçÿ Ú›+¯fÏ¿~ysõëí7/o;ÉúÒK¡Q¬?.~þU\.aß\ˆD{—^ÞÃH¤÷êr{aR¤FëHÙ\Ü\ü³ë°÷6|:© )¥­šP‡Q=u8™¤Þ§—Yê«•êXÔÕ gñÙWªÏ«tâ¥002 ŒOg¿ˆT\×mñ9´»CKKÿg] (Bž,½L2)íe&m"2+Ï,1Íû\a¥”œ2ÜÈ´ÒV¬ék—œ´Ò´ù¾·å¶K'•M2ù¨xׄ|ƒµÐÖ«?YýfW,ÊÕèI˜ ÒÐm‡–žåÕ’ß¡€¡u¿.ª¿ž½+ªbß0ïÛ·°=©¹¿’nV,êð»lˆPoùÓ÷ù¦\‚­*°U2NäXäUd¥EN ’Ã5.À2‹=0*3 àï]SoA|•Îj~KblÀ¬ßDÁùÀ°ZÈÙóŠ˜ûŸZ—#/µ‚|ÀZVËvÏ‚ç ”»Ÿ~ªÃö.ŠVrÿ?Áßë×/æaFb8•ÿûë×77hÚ ’ÖÕßà1•3%à/IPCPeL´Y²™4Ÿ›ôóøêû[ìKjÓîÎf¯ó"hÑ®q`·ˆ“°—ž×PKÈNJÈKvUâX%.¨¤Ó‡c}¸Ù§×ϰáÁlÊÅzøÉ5ý4`Õ’i« D½¥'²0h,{’®jùM\?={µ"RUOÀl4€W?¹ÙF;ĪD- Ùà д|F¶¨³ '³Ã$Qm†¢u­mYjJúYׇ=µ¨ÛšÚùfSßSsUóûŦ^üNÍæ÷â>ÀYx*¹GÀTØHgÎj€§Ô˜Ç®Ïuá:®€pÅ4ÂeÎG„+ªå4¾ÁÒÀúÉÇ…ë¸&¤à›Xuðv ^‡oÒ Z"l¾a+à[x [„oþ¾á#ã6Oð ‰Å‡]I/°‰Ùs~qÆ•j­ký#…8 ƒ` s©Á"V!¥zh‘?z¸–ªÎ%ŽìÜT\™áªC&¤EdÂ'SÄ ¤»á,W3ÏšY"®FQ&À0æÍ@0¯I{á ’T˜èŒ fIJì%ìz¬õ±‚¬h‡<@ÉŸåÕ}V|(›–ö#@èlâˆqNv´<úÕ?¢å°hš^Z4 Yúp0t_6Ë'6ë”S†<2±â©Ø±ÏuÞ)w\Á)¿z*ñ nlÎQïIæç I†<çQù:® Ç')Â97”ð–Îvì1ðöl3>V@}Ó!¤‘wF"%Fá`ÉÏÞÔMC×jŽ5Ä׳…“hÓ@ˆ ¢.0¾o‹-þN]òI*;Å¡?c|E?6µ³a©°®×û>¿?×9¦W®›G¸èFÝ‚K²‰’ã²"v¼Íwç…w.;ž§@ÿ"ÖÚљLjArh»} q~¹y`rk+ø„u55ƒ©Ã/¦Ð7äÒòòÖrA1ÆB\ņÉ5‘LQßkîqyØî(y†'0˜3ƒÈºŠ¶ÃM" ×pY驳3‘u¥¬ ¼#Òa·d4Å÷tS&£)Šì8è}É ±h»šv°=²hìª)ˆ3˜³ÀºaÉwê†ö².š©°¦ªÛX8ÿ=^q8,8mŠª)F—pžG…óÕ¬æ<è@@-|¢ÚÔçzt"WßžÊ~Ã7/Qù¸dׄhà ÈfS3”í‡ît—’Ü ƒÍÉvegKFdɾ>Ð9‘=9 ÷›rU`\NqÂ%¢GG_:ªpJÓb·y;8ËéªãttC» M„…0o`)Ç©d~ ãÉÍ0*¯ŠéDKÕÞQÐíbîßòüŸíd¸éÔ&îáô†û„-ƒ[!İ0‹$ßá! }w&½ÂocX3u1A«c²¥Ÿm+Ñ•Ãym|EÅ$E'S`L™ ¨©éßUÁÝ£#dZçï‹aÏwüLl½sÑ ‹‘ßÕD$ tŸOŒÄûáÞTÂg ‰SÚìŽÓ’¡Ïº¸6bÞ×$yx‘3':wÅWM«%^|¢ûaRrzAWGé—oHÅ…PȈÀÕÛòÏâx9”Flƒ`Ÿ.Mœ?^'hÇ;[]ìïl5l2ù’L9bã;{9X¨®R¿ï øAÿgn&ë4ÁëÄP#º+¶ÿó­åãmÑûÙbÜH&Ôݯ®_Ð,Aaàù‰Rª25“Μb;ß|>Õa7¡6endstream endobj 2864 0 obj << /Type /Page /Contents 2865 0 R /Resources 2863 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2840 0 R >> endobj 2866 0 obj << /D [2864 0 R /XYZ 56.6929 794.5015 null] >> endobj 2863 0 obj << /Font << /F38 1122 0 R /F42 1338 0 R /F22 1037 0 R /F21 1034 0 R /F64 1485 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2869 0 obj << /Length 3288 /Filter /FlateDecode >> stream xÚ½]sã¶ñÝ¿Bo•g"†ø"ˆÞôá;™Ë¥Žc;Ó6´DYìQ¤"Rö¹¿¾»X€%RN¦3?»‹ý^ÀlÛ¥*Š…‘3md¤b¦fËíE<{‚µo/˜ƒYx EõÕÃŗ߈tf"“ðdö°p¥Qœ¦lö°úeþþööúæêÃ?/\Åóëèr¡âxþ÷÷7?½ÿžæn/ Ÿ¿ÿöúþrÁRÎ41ŽpI<¿º¹¿¿þzqÿáÛ›Ÿ¸¹¾üíị뇎³{ dë÷‹_~‹g+8Äwq$Lªf/ðGÌ>Û^H%"%…ð3åÅýÅÂ`Õn“†i¤R®GÄÁy ÃX&3­L”.¬8î‹§*kûK–Îs8¿4ó²Xçm±u_ÿ.Ú6ßã8geSÓlë~›ÚÃåŸÛ¼jiü˜Wù¯qÌÛ†¾Ÿ³²Xem½ožjå¶çûç|ï _Ý䎸ÉVEõDSõÁa^fËMŽR‡£/‹ŒRÜž#ÿ¼+öY[ÔÕ¨E1/¢t&Q±¦™2³xŸaÅçÕaûH´a­^ÓäݨÖÍ­êê/-M[ì^D°”µôÛn²&Ûº%'9˜[ÛõÖm)Kš¶Ghºý!Ú—€F÷˜“e–yÓÐhYWOyƒÇ¥ïv“¹6öôâ¡ðá»Êó•ÛTÓ/±J_nÜÞ–~·uÓ–¯ž‚cÂ5¶GN\ Žb¾¦c°E­õ¸; EEËÆØC¡0ß#É/¿IdhÛ,J7± `VEVsÆR°Êó¬uP#¼ ¼IèH§àkæþ±ÉQZÏ_öEKö ý4àlVø:™ÿ§®ršµj€ß_9—ûìh¢Þ÷ Ûl×/¬ëý6kÑÐS‡mžMÞÃ75ùôÒÍ‘Hz`·TTý~4>øˆR¡ÔÐ7à„ó~î(ÂD³Ë—z¼=¬8 ØEr´K-çè1ð«øaS4´ìÁÇòeë A¦߇†VÄ|·/¶Ù¾°v ëÚ3…þ@€û]ÝäM´Ø”‰& ‹¤NÅy ¡¦M´ƒ²&Z½i¢ÕrwhN,”'QÊü,gÔkC Šñk÷¦@ìB*Ò¡Ò«ÉNb8¤EŠBµà¨3¢‘ó¯^ie•¯³C‰F)Ø•ÃÚc …#Û´ÙÞ*¬q6Ï0áh•·d d‘p•zƒ¤DþõíO“Á'ai$´yC±=н: «Ö›1µb¦×>ðÔÙ‚LA>zÌ ãH'`ç8ì€NY õËci™$Pœìþ‡÷8H:WÄI¯c;- êçZ¿ÛG*\ÄHÊÖ)”FuÓebhè#s‰ÌJh Ê…QQ“a<ÁPô)Ï)ªÑ¦ðp‚ª‰½·`Äp†ýÅÉ#ÃSé7Ö¢Zîó-%$H-íT‡5É)Vf"¡´°ªâ3&¾)¤qdâÔ¸ 'Ê Y˜Dê™Ò*âÚ$ãî¡!Ø©‘úŠ®ƒ쀊AQùűºÄë =ÅŽ[K7.œv²¦9lûß^u8<_Sšƒ ¯cž¾¡ºêŒî<”UÞoÐïíDqÁ4†P·ŸåÏð7P!jN$bÈ Õ¡ÐqW<ͨXÔN|8 &iì•€€à%m–Çæ6PáT·Ç8vGë}ÁÑSmh뙂Cc© ÅÃIÁÑæŸ§ªC É‚c!Y2Ù¶>M9Õ±©»À´ÕŠxZ;`PÁebÖÝl4Ý3jÞqÍ 0å=.À»‘ƒ‰8‰’Tó YÊrâDÐ&¨$öÀgŽ|R™ úŽ hÄÖ)*Aì±Ëè§3¬2E›‘¢à‹ z¡×˼¡ä„‹xσkxc´¯¬€Ár_ìÚæ| 5Qq“Dà4&8¿ï‹GŽo¢4ÕiwüSt „©Baúî{™ŽKY Φ˜´±ÒC´»™@,¡7S’‡\‚k‚ê˜L†ýŽÓœí®Ûº¿°c¾ ç>öÁÈöôðûXTÙþ•À:ï Úf>ßg»ÂõÜeÝ]¹1ÔÒÈÙ)©¼P1 ¯Æ}É¡Ã"øDôp¬?,#¥ ÷D›°ƒ n!ü)c?UÕÀ–ñ®‘®ÌÀümæð^‡)ÀÍ81ˆ¢×_1à(ºYƒÉú±)¶Å˜œŒÏ)ïñt  –™#û衺¶ØÎ¾XV½ÒÄ1«#Á@É(QÜü!]ø¸öyuW¢@np>gÎþd§D&G7@]z ëÒß;ú$œ g_ÃÙ2Ï F±Ï¶ô»)ž6ùþÝQ.vQx˜ÆÙdnÊD/ÃÏææj:7wP67ïŽII)ß éFH†Z2&’\‘ü …ŒÌwM~XÕ‹=¼NFÍWY›Ñ⋽rÄ9Ì¡etÉf}û.Åœ.Ýp’~å|5-u\˜¸½õAwÍå­{p0tÙŒK®å@x§wº¿fq¤øqÇïÙçš[ö±îÓÚ1Å5äÁ»Ð€möJkW°xhòõJ‡’>_ÜE+ïOῦDÚÐ ]¦òn£¿¼‡)ÈÆ”¦vŽæðòÔ^Qnå) —ŶhóÕ´)B¿¤Á­Þ0ÅêŒ)z(kŠ·“¦xŽdoŠ'$GM1$yU4”ÝÑûvuãKt½{e€ ãÂ2 %ò¦¥f30±Ô° š„pD…1!Î#Ä9DH£¼jœM6´lÒ-Qí0t™hðÝê©¶í/ÁÝ¡qôƒgü,NÖÒ½&¬Uu5f„æ¹þd{Œ„ó”kÞ_þÃìÇû4ù)“~½dŒ¡òD¹ƒ ½à$>U<¤ÇË=^šÊºš  Ë]‡^Þ6MfI¥…mgF…D»ǣ—©¾Ûê©«¾šS@Ñ;m¸ÆÏÌ»ÞxšOÅ®évú´Ñ›Ô˜ÇqHv2•Éy ¡¦=®ƒ²÷ã‰ÇA%® Ê;KÒ>̲(zHò.ßÖÏ8»GZ'”ðu1öV@/íˆF*×ë–øpèn¶l‹gzÁ›¥‘ˆwOËÀ VSeÙ§Nƒ¨›Ñkhž‹úД¯‹þKt\®¼@`è¾ýjææŠÊv8¤w° .[l>9!y²ÞžúÕÍýÇëÑ®¡õŽÙêÆÒ4˜Rì)Œß„‚^ÑQ0Þve¶ôK/`²´+£‰*¡;‚Xœ*  E_mâ¦ÒáÕ Óœ =Ù`±_X5²PTcg´Åž<Õ¾÷-"MÄ|Q"i½¢Ï Fø3bKŽY Jæ.c4)Ëú¥éßnw:Mœ²à{ú¢:¸u?ëÞœ¬“\âÞ¾+ËzW䣉ÕöÃÜ÷Ö\’¬pÆ+'ïîš¼ÅG(ÛLbK_9¼Ÿ–`Õ‰ '>ö=1Ý]­k—÷›Ñî3bJyl« Œyi-ÞJåµÖ‘áÜ£¶/g<49:Æ±É Lo2A¾Mñí O°¹gGýM¯]ÎÉã9ï=ÆÞãÁX™×5Ç“»ûøÙfîÌ£3xöÛý 3÷&ÁEßá¯!õUŽ ý£U6wý(üÒÅ4 d"ñV…óëKöGÌZFæ.ÍÜ9ޝn&“ãxã£ÔùdBM'‹ÊÚÙÝI²€vWsž¤!9LPJ Ƈ4ÿÙbGâv/p$^ÄÔIúDnôÜÏ5P.cyn?ÚzÌ_cè ¥6gýÕYGwƒØòÏË|×:r-Íue¥­øS®œtDm³:özì/g<¯‹í:Œí ÊÙýÇ…]¦G ·—¾ˆÒ_He|++óâ‡u^9/T¬¾W‹ýM-b=u^œœ?éÚÏ¿**缂‰·—÷ª>t}ÄñÿžÁÔÏ]=yßµuλ»Þ=›q´¸³¡ÿù¿óúD”:éTG…”†y¦P8,U— ¦°ŠùêÃÍ•¿>I,nO^Ǻñ;=Öïe+rendstream endobj 2868 0 obj << /Type /Page /Contents 2869 0 R /Resources 2867 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2840 0 R >> endobj 2870 0 obj << /D [2868 0 R /XYZ 85.0394 794.5015 null] >> endobj 2867 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F21 1034 0 R /F64 1485 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2873 0 obj << /Length 3148 /Filter /FlateDecode >> stream xÚ­ksã6î{~…¿Õ™‰¹|èÅÞ§m7ÝI·—ÝkÒéݵý Èr¬[[r-9Ùô×@€zØ’÷Ú½ÉL‘ âE€²šIøS³0‘ÕvÛ@„R…³l{!g0÷öB1ÎÂ#-úXßÜ_¼úÎ$3+l¤£ÙýªG+2IÔì~ùËüZ(-.„œ¿¹½»»þvqwóöößïo¯/*Ñ*ž¿þðáúöÍÍ?/:”€ÈRÎÿþúö§×?ÐØ‡K«ç¯ß^ß]þvÿýÅõ}+Y_z% ŠõûÅ/¿ÉÙ6ñý…Æ&áì^¤PÖêÙö"cüÈæâîâ-ÁÞ¬[:¦ LD¨ƒh¶0H€ÿ¸Î”ˆ•¤8´"2Ú´:ÓjLg u¶ØãF_}=L˜OLÄcŸ–Ëj»ÌŸŽ5¢4ì+âYŸí‰p-ÖˆtºÇSéP¨0Jw·Ë³âW)u^_.ŒTóf# çuuØ_ªdžå4Q­èIÒ–y]ƒqƒ(œß¬+s—ïÓ¦(™ÐKÝä[šZVžOY54½s\ª§bÉËSÒWЗ݄ »™Ic¯@Y¯ ÌþIzP†¡î©” ”`¬&Ž™Nµ–À=ÿýP<¥›¼D™”ù"˯àÅ„¼/7ºJ›†– ÔƒXR§/jÿ˜¿0÷C/i¤(Á)ÒåP”*ýn(ë°ÞªMÎïq+˜HÜ&Ó ½€õùˆ.• E¨@-¤K¶ÂrD•!d ¥¼‡å²ÈÒõ‡ä›uÚ4´#Ž8;²Hëê°áá÷,Nr'H°O›œÏ:}¬é¬Ób¹¬s’^£HH†¥GaÙ×U¬„Œ“#–wÛtzHây]<¢k| K A€­÷—Éü55+¾/¿’V­¼»/˺γ’ø£*óKű#e}ÌñÌÉ*Ùßryœ‹à¦ó]UMµ!¬:7cÕ±­Ú¦Í 5/¸h 5 ½‡ÜÅ„óØB¾¼¢ˆv¥Ê»M¶9,sï_˜!i¸!À1¤©“ÚqÎÜí pQÑÆL"’P‘1~^çHH»øÖÚ°à>WÕ¡tÂi;/šš°šbKâÂ6oR eœñËòO) `ã›ÛŒÆt™Çix]=3³†æÛÀД ð‰ÁüÓ,«(¤Ã 9‡ºk•³ª6›ê¹w^¶ÉkNש3šâe’‹§|€ÈÔÒ>ÎA£Õ¾h^è­zÂt8`èx’ü×ÇQ>A%4ÿ„¢CÆcQ›¸D3‰¡µÏûN#0‰D˜HÛñA=áI¬c<[éÙZàž5ámÖ<äÎOªs´U,9$b>Ð@ßQJÍÑZq4w@ÁÔv‡‡MQ¯wàpyDˆ} èHpX,5†ó k¢££mbJý!:‰þºúû¦ÔŸt|Zõ÷ôó•w,Ô (EÅñ ¶ðaÍ(d€~ªð3'9a—ÖÍÕ)³áª¾1¦Ë´¨A´úö(œQ Çjh¹ZÑÖ´ „1¨M DcýÙÀëÏrf‚Ò¢:ýÙ€¶ L/ðz32ð`l¦Ó×Ìÿ*CI'Ç#ûWÜ!jµê-aëNz.J ÄÔ‘‘9zÙÍÀŸ±•4B†6ø[õ(œ±•Çò¶‚ž‹E”­³ã©ë©jý]zÇY§g‰þ~ AO°Ó†›dtG¼««RŸgGÓa{Ûñ’ƃÓkpÀKûWXŠÐîü^·gH»n"¿Ü´A$…¶±ùë¦íS˜6m‹åMk IÏ :>z­x˜z «¼ÅqìP¶! Ðæn¯\æ›<fxbI•5‚SLÑ…°EmãHQ1etìÇ4)Þa3ÑÛ÷÷Óqx”ýqþ?ëªoþ£œ€ô|•Vú*V3Oö‚ÚÖ€ËíúXÓý@‹åúû‘[¥Eß5ÍæX¬$Æ:?9/–G«ïjÐ*ÈHê¡XƒëmŒ«VáqÿÎðtE£ñ$BT¦=/ógys{÷îú_“u|UÉÄ‹í®Ú7ž@Qzâd^¸>AêTao(Ä[úÐK,¸b(æ ê3°r‚‚4R|Uj¾ü kÔ1c™Ø;u¨{· !;v¨»Y§ œ¡Æ×u2PqS.Nûîýkê‡Å»_{>ÕŽ27ÂE=Z“?–´˜ÎÉhþL@Üýñ0$‘ úã‘ÖÜ$"V±ûQÇz|gÅÚ$”+O¿Ìr[“|jrlÓ ¾8µ#ÐsxëÙÚúê. ¢^ßèwlfX™º¦RÙÄ%-|R'‰P–Öä]=qÃCtd%ótSW| õUêPVžNî·áV ^JfJ=a¾È?5]¾á¨WPw,Cîéǽ|æ&Žú.ÿ„Z—îd¹›y^®Ç ¬Û#A‘=6ÉW”)¸aÚùnMðs±ÙôÀT¨žÀ…)<};¸Ó|{ÕËß0äºcxRÞ Zµ¸ŒÑY=”^3#®=’;蘖¸ wá‰cœ®ÚvŸ2šß”„ÉÉkwÁˆ “­#–Ò[V• L‘1ÖCÞˆ">ˆðlL ‘í]ÁÁ¡jÝ}{‰t‡A¸ ‚²´$À]J'Pt>cÍ ©…VÑE„_c°ÖT\Ê&ʉøK9„¦Ù™Q~ù¹<ƬF’* %®c‹¥nEOO@fÐRèyŇ„ûˆûtŸnñ^¯ÃÂ@µ:Æã˜¨’š‘«ùôvÖH—Hþ©ÛYÆþÛ¥udAÂáGþp“haULd¨îsAHž‡ ×mî=o::±àTqü™èìa‰Nå¢ói¬¦VÂqÀÛß@Î?©ª-hHCswV04"Ø @’ E Þ@²»¼©:—eþpx|lê›T™‚¾0Vò3Ÿ%úXÓ*k±œÊ>$4ÌÆ*9ÏÒ#°¤xc£†,ß—.õ@yKýäÿI/lË#„ü‘ÚO˜çØ‚A8J{©  W¸ãua _câpµ-šŽKÚÐÇA×ä½^e8GD"]ãƒûÀfŽ:V¼‚¢Ú|p_Xl‹Mº?½? bBï¥õ0†á»ûX¬œŠpùK^ÿm¬ ×VÄ‘™@÷IÂ÷ |ÁxÊ9 Á$í·üú8öíÍH°oû=\¸[²)× Œ°ÁøÍnÏ5{Xg\Óc9×ücÒ5ϱì\ó„å¨köYÞ´?z“™¿»{‡€ûÒjÒGtm˜o=q’^Ó}u!?‚g×pî›ÝŒ±ÁÝLf)xuËsAìÝ1kèSXGÅøÈ¹t³™öÓ£ÂÙµk!w]I4ÿÏ¡fˆ¿¦õú7€]üáo ”í{<ÌøgçñH£êhú†ª0ê>\U³€3>ûˆOKËjÔÙ¥q衳'Qçì(Ò˜³/ )‰Ôð8ÿ?x}b…6ÊœwúÒ´Ï{$çòfìƒÝ'Ö‡znNªr GœMg…ò8§B î„"aâ@ „z›—øó ‰Û[zúÂ'îªPå<sïŠÀcñ”óì:ÿD+ò2«–λaw„E§ æ¯iz™ÖLÝŽTöUbÈ©ÂcmFCd+éO~ºéG¢™ßƒ+ÿ ¥®¸ !AKö¤ß ÿ¡ô÷“é¦ þèÿöà¸jz$ývßT}…À*nË-1õ- üUÕˆÙåÌËÿÅ?Þê~§ÄÂ$ÉDs$ªí››Û7´ +À™ÍâCp¹P¡Žõ ƒÓ“à{‘ÙÕnš±Éendstream endobj 2872 0 obj << /Type /Page /Contents 2873 0 R /Resources 2871 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2875 0 R >> endobj 2874 0 obj << /D [2872 0 R /XYZ 56.6929 794.5015 null] >> endobj 2871 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F64 1485 0 R /F22 1037 0 R /F42 1338 0 R /F54 1433 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2878 0 obj << /Length 2011 /Filter /FlateDecode >> stream xÚ­XYwâ6~çWðÒS8Uí¶™ ӦɤÓå´}pÀŸ‚Æ4ýõ½×’Œ Óíð€,_Ý廫̆~l˜)B…‘ÃÔH¢(SÃÅv@‡wðî«s4‰'JúT¯æƒ/߈lhˆÑ\端ŒÐ,cÃùòçÑäæfz}yõã8኎¦dœ(JGï&×'oíÞÍØðÑä«é )¥)1tšŽ.¯g³éëäû釫7?3˜Î;½úº3*P©ß?ÿJ‡K0á›%Âdjø”0cøp;J%…ð;›Álð]ǰ÷¶=ÃBªŒ(.õ0’dxD£„*@ I•!ZpÑ!ÆY 1O…ˆ%_£¡_¾Ñ²GÉÐĘ#E¹+ò]YWÍ1$ ´3œóa_î‰vUD=Þª1TèP¿ÖEe=wWT­"Õ}ÎÝþ5øLØåb—Õ…]ï›Â.vë²±«m^=ÛÕÁ&p½`t4_;êe±Ê÷›#s%'áà0OyJŒHÕ'Ó£:ãOÕ:fr,ÒhôJz^¤'Šˆ À¦ ²Æ„"ÖF„XCÂänßc [-Öv·)vv±kQ„—ïoæc–ޜۿP*rÇ«v§òÍæ„éž*uû¿laµ´o—µÝ¨ê] fH 3’)°›1b”²å §œasÖÑUS,ö–ÆÇÁ¦¸ó!‚ì)°6$F·¬?6œ.À`Ußã·ûT.Z4X¯h9f#R ›m2ðø SÚ¸|K&K: ýÄ}NGæÄìªÆëQØEˆ>í¡ÏFõ _­ì k?,œ/N`‚ì‚€ÝÈÉFÞXH°ÕÞ{ÂÈA”&I3É9‚·úî›.mQËS ¤ \§ÌC°! ‰”Ê£ÔA,k—ßõ²\=Ÿ¯vù´.k»¼·&?–õ¾Ù¸Ãë|i’ð ‘þb%Њe¸9_ úT/W‚Ž Mý³® p!ß'˜C3)ÎËî¨"ÂÃ8TÄÈ¡@zW ʺÚ˜SÛê:åÖ=7å]U,_FS’™ì ®Ou=O…úÿV<ŸÀÅOËô¼LO‘RM4ÏD(tv_,l(jÝ,A™Æ®šu½ß,íº…þ!£ÜN RhngíˆalZ*]­ìVUsÏ»R†LPô^±ÄÞ˜¶îjÙ¦![§nÙ«æ´ ‚¥i˜ÐÅù¶¬Zu…¯#Üàõíô'»yZq ßÙ—V®è_Ý aTZÃ` ¨Gw°öWõ¾r¢s¿Ú>É^`ãß-Ö6Xf|ùè› "xá[ÂQhC°<+7,Kgâ®~x3ÆFÝ‘Ãa?†8X{áÜÝïCèoГ¸ò¡ê1_ .a>ÒPY%#LIÙj<ýqòîæí4R/Á4h,Ê(ÝËc-AØfS?Y4´‚TÞn-ˆðå7vy¨Ó¦î0´ršIW…1 î7& tFD¦•£õ&ŠÝÚ ßy¥.g»Àtm¾·/-åís‡IdH2ã{²j 'Àâζ£#}І¨ œŽíùÛž%ä è—_°”Ëû,^¸½*y;S Îà„ê¨S]›Åz'ú0Yû&8o»*þ·³ .n‹ÖE( BKHøÑüܱy«í¾éŽ;¾U 1Ä8=ÊçmÞÀHÜ ¶Ð·kE#íDª4÷¸ß’ó ¢³ŽÜÚÝèTVõ"?ŒO›ºþ­9L)±©I™1å²Á)ôT´MáÊÖ‰FÓ0Åu)~œØQŠ›R6µ?šï®$Q!C\/ggÆÏ…R|E(·÷õî« -1êKÉÖ7bï“0úRMRÙîâï.æ4ÓÀ§È& ©Ê¸ô¯½|6N4Xî’ +…ÍhÜaö¿¶ÿýp°§Âi÷~aB†EØböB.ÆHC¶ÄαÂþY¼@ö'ú«°à³Q~[?Âàëžœœ‹òÆƺšx Щà4%Ìt³üÂÆ”ºæ¨ã†¾#iE’4š~="ó‚k“;ÖÞ|»<ðºñ,wc@"t åM°Y«ýÊ5ßjá£×÷Ïüx0lv`ê¶ë¢ºHŽ+˜èŒÎœÆU¾… fÏU¬Ùp¸AtÍÆÚB\jÂåIh!B{Ã;×⃿‚&¾bاæ†Z»örßß`¯÷5ä`”YûÑAúÑšuIKæ¦8|¸Â¼iöÛãà¶YpMÌ—o^[Ž’ áˆp©Ø?g§%û$»ø +$'ÐÞeèŽÉÇù×ï?|zнª ŪÂEúì›­«p¯ëª[î·¹’©;÷k"¨û††Çp <„écñ€—:NŠ dŽýЉ×L0"„"ı±5—óÔ®ìÇçãb‰´X˺Ѩ½Y×›—¾N Eð“räBK;ˆÿó—ëÃ'z d/]á&¶æ•BXæ2ÅSÞ|Â@‰äF[¥D†ƒH1ë/†š¬endstream endobj 2877 0 obj << /Type /Page /Contents 2878 0 R /Resources 2876 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2875 0 R >> endobj 2879 0 obj << /D [2877 0 R /XYZ 85.0394 794.5015 null] >> endobj 2880 0 obj << /D [2877 0 R /XYZ 85.0394 547.852 null] >> endobj 2881 0 obj << /D [2877 0 R /XYZ 85.0394 268.5474 null] >> endobj 2882 0 obj << /D [2877 0 R /XYZ 85.0394 199.7975 null] >> endobj 966 0 obj << /D [2877 0 R /XYZ 85.0394 156.8733 null] >> endobj 2883 0 obj << /D [2877 0 R /XYZ 85.0394 118.5556 null] >> endobj 2884 0 obj << /D [2877 0 R /XYZ 85.0394 84.8024 null] >> endobj 2876 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F64 1485 0 R /F22 1037 0 R /F42 1338 0 R /F49 1358 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2887 0 obj << /Length 2714 /Filter /FlateDecode >> stream xÚ­Z_sÛ8ϧð̽83Ë¿’8÷ÔmÝl»i.Îuo§íƒb3±¦¶äµä¤î§? iÉ–¹›<!À8lDáTJRÍõ(Ó’(ÊÔh¶º £Gûõ‚y™$%]©_î.^¿ùHòtt÷Й+'4ÏÙènþe:†D*ÓD(!ÏCEW* Ø1TD)»n€…´ ‰ìºŠé”äŒËóŠ¡Åxo9Ø€Y_³éÚÌöÖuxÜØiæÈúá@È:–œ4§ÔD¦ê%sv¤Î˜3H9sN†ÌÉH®Ð÷1±«£’Àu•ŸW-J èÖ·(Œ Åúʶèl³[·õã¦X/ʲÊóç^H·5>·M85Ï SùØ_¯—嬸_¢Ý[2’ À΄eD ž9%þ@ù\¹º~‡”ÃxÞoËe‹ä3~¤>­M5~Ä—›o§ÿ` ^47ÛK6^¯ëMkuÑöfš›‡b»lý›ÓZ‡ý£i7eõˆôWÎåúû¬aÌR~¦g°ÃÂí‚öñ¢œ›ªÝQXØÀç^OxñNv´‡®Ç³ ;ß”O~´ÀÇ¡ìÈlf–fS´É€ž®nc6OåÌ¿¬êy2¤þÖ:'‘šy?Ƽ£Î–ãý`YèKUEë”¶Ñ v £ú‡¿REÁ˜©©l4$øeâL# PÞ¢xtVOaL7CÀÅP].0†Žü>8¬œ³MýÛ gYÞoŠÍ_šx<è?•6 ¬òvçÉ>0Nb /’|Ç’®Ôi,‰RK®°rÏ\¤'’¡ ˆ’èL×/J (Ø)l ÷5¼[¸xp7¸UhéÜbymtZ⦖iMïbQQ9¾©›¦„HA!œ¬A¹âÇÉ —)ÉRʽ-¬Zó£µÏܲ­T‡ÍƧ:Ž~%¸þWIìn¤ý"›âùÔa, y”<% .ùÞ1¼C Òj\¯Û²®¼õ¦\›Ò¥J–]µ¦š»8…7IJt|oðØ`ÆÄ|W+‡"º“hiÌÈüMí§CpÒÞ_îóíj_¤è°A÷L&0#˸C2x­ê*±Ž@fˆ ;2««R%D^Û®çE벃pƒÑ˜_ÎÃ2s³¶†¨Z° Ü€èY†Qh%Àø©C`øû(o怙×á6¬jŸõ­ŠïQVÛ™›ÆTg¢ÝU²·µÏ9šÓ@A)¡\å/EGê P)õpÒ!d&ê›~Ò!ˆ¦0ËYÕ¢Ô€ný¤#· ë+w×MÈ\)÷æ`Ž × ÿ‰Œ&2}Þ]©Óþ‹RÎO/ú/‘½Ò*xsV± 4 Xßyœ ÙÓljÚÃTqnî·x†í¥j;m2 •„zÁ`Q挹PÆëóábi÷ç "G‹õzœd€ÖÝÅn M ‹ TÌB¢7"unîw`)ÜÒȃ¹MëòãÌçÇ¢³¾É®"E5t;› &¿îž‚òêŸþ 뽓R¤|OÅzï- ïwø´@Ûqp‚³Dò`ÎjÔÁ4뺚{&"¯-™ÃV[®·mfÚ‰ò£<”(‘‘έž­IÎÁ½Û=ôôz‡ ؾóæ»^vK!Û9ÛZÕ²›× wˆ:’Ò<;Þ»R§Ï{”r–øy꼟]2ž÷ã%‡Î{oɫǪÅ%à¡?"@|˜~@"†.Ð{R6$Âö€¥æ¦5›•Oÿü|°9øÔ—@Ù°µÏJ3›ø9¦­rÚCˆ3§Ý/!÷ŠíN˜ã0óûâÂQ&CÈpæªî;|Ø„Ÿêï.} Zc–ID ±ÇH;ƒ¯¯…‡PK ‰÷šp<²:t9ulÕmÚ×jÞÏô%ùé]`I¨Šø„‘Ä}[ ‹Ù)."œkìÿÚ:¶xð¶«Ú¡ô;.¥°×€0ßM8œ9|bç‡éxKât®»„Ùfˆ›õ«˜ÿ«ý·™òËs6~6È©ñv Uýk[ÆÎJ-—… oî¬Ó©ösvbÅ{›uï9a®¥)š6¬ïÇŽhÐ÷ÝpâñÖ²Ñ+äà¾M´4¶I*8ÖEvC  5.ö‡覅ªÌÎ$F~âP>bì|!,Û îï\’–·Ãg1»Æ.@^qÎæ–¯éÆ•–Õ‰u'qÉÆ‹Ð‡(«Ùr;7ÍáÇ=óáBÿ´› A 5¡'îëa_…w«Ãû:4ªÖÛͺnLã+žpIÒ¡K’ö:^¿1ÈÓ¡Ê —äÏáKRJ(¿z—¤O[®Cɉü¿_†Œ+BÕ waGèôU„¯5¾¾;¬…8IÓLŸ]7ȯÛÝ L©Ô¼·n,b»Åe¯1\‹–šáÞúýª­RÑÿYh:™à—o>N? xcø¼à>ÛçʱኑD;Ÿæ¹ýU"D‰oÆÃJÚ/8·wuÓ†þ3°nMÄò™ßÐïEµ-–C1˜æ„§ièT)zç,ü*rûÞÿ¾&©óIF Ëg'Ã.ÔIŠØßû¼O£±ÿç+Øÿÿ„̈Ès>H:X™Øò*¹‘— S¶gÅòüø,ùM8ÞÕɲTìendstream endobj 2886 0 obj << /Type /Page /Contents 2887 0 R /Resources 2885 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2875 0 R >> endobj 2888 0 obj << /D [2886 0 R /XYZ 56.6929 794.5015 null] >> endobj 2889 0 obj << /D [2886 0 R /XYZ 56.6929 749.4437 null] >> endobj 2890 0 obj << /D [2886 0 R /XYZ 56.6929 680.7174 null] >> endobj 2891 0 obj << /D [2886 0 R /XYZ 56.6929 609.0262 null] >> endobj 2892 0 obj << /D [2886 0 R /XYZ 56.6929 83.0386 null] >> endobj 2885 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F42 1338 0 R /F54 1433 0 R /F22 1037 0 R /F64 1485 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2895 0 obj << /Length 2258 /Filter /FlateDecode >> stream xÚ¥YIsÛÆ¾ëWð¨ÊÏŠ%—WЬ$Ê"+SïUÙ>€ (Â&‹ÿútÏä’땜ôt÷ôòM÷ˆM(ü±I¬‰œD‰$Š25É6gtrß~9c–fꈦCªŸfgoñ$!IÈÃÉl9àÇl2[|.no¯nÞ]ÿï|Ê ®ÈùTQüyqóÏÅfíö<áÁÅ/WwçS1!ˆI¤ ipsñçÕ»éå¯W—¿_¾¿ùùüÓì·³«Y¯ÙP{FªõõìÃ':YÀ!~;£D$±š<„–$|²9“J%…p+ë³»³¿z†ƒ¯z«ÏJÄDÅ<ò˜ƒ³ c$QŠì¡ .Œ=þ™ýúþo<óõèdÊCÂe¤É®Ë6¯Ë¼5&º{nÚ|Ó˜ÉeU6UÝÝÆr¡’rËF ÂEj>hK°+›—é&_L³Už}ɪr‰›‘Z(TAjê 9¢Ìb™hª}FZ«œGf¤?›!|þH)¿ïê´-ªÒRÂÊ:7ãæ¹lÓ'KŒ ‹òÞÌÚªZïη3*jŒá%ŒÆwÏeµmŠf?2Bp¯)°}1æó$ƒ3q%aì zJ¨ŠÑßÚË’{‚¾§òZ(û˜®>¹ÑC?úÜZs\PhÇÓ„p¦uD¾‹¢Î³¶ªŸ éH%Iȳ”–ë²X稌“±í¥=õ£oŸ|v†`$–TíýîêîòïëÛÙõû›~×±öÜ^`Åm‚ÅVgM A. ÚUŽ!o`¢X0ïZ³ZVí>]¾I˶ÈKZ- AêQ“Óˆ0.C+×ì¡vBGN¹ýPFæ:”ÏY#\)ÌŒ6¬qÔÌ'˜‘K’H°ãÔ˜Ù„Ê6­LÁx–v -áV—U¦Y:_pš×õ9‹ƒªÖGæQ®+ÌÜóX´+C•®×fɨԘIQfëná$ÌŸíj çI\/Íæ²îµD–E³Í³?ä‹7žp”\Põ‘û6o³·Æý—inÎ äHœ„œð0T–WaP?O-Öà!ðw‘/Ón 'ÑÂÜÎ)‹I ™d`®jóá¤"ZEB0¥­'\"@É^Æ©SÑ©f¥ùmrpwÚæf¦]o} oó§V»£¹ËV†(m<ÆeqD"ÙëT—‹Œ|ÉŸ=j) 1¹HÇópƒa"ͼ(Ȭñq.wa)­®©9¬QÓx™…$”ä#/§][m 2K :¼ˆ³ù³Çp}Üq¾žÆ 7`ìœÉ)%Þ›{ òvI„óÄx ÖWšÜ w!“MjÕÎÒ®É}ØÂ8R½[ph¨ÚÊ0]¦ÅÚ%IDdBù,ŽGl]ù'I?ä¥Y.–…B@„³×ÛŽÃÜeèÓÆð†ˆÌò¦YvkâK—%ß)Ä)•¥ös, "aÏgÖ*ûk=‚Ÿ{àzþ´]YÑB<1Æ‚7l)˜-Â"m~«ê¬UŸÃ6òŠââ½¾çîªN[IÈ¢ätù0¤rEâaùÐS¡Üéj_$šóý¤HGä9´}’‰eÏHäm]”¶ØÔW*º&½wuZ·Ù¤µEX}Má * Îz­¥ 4üë ¨NXÇQiëXŒ‡…Rè«"_™4ÔÉv@yR¹žÊ£Ý7D±X©w¹2ˆ¢+š`ÎznG-Dù˺1ä†PVö'k*Ëo*=²7¹™#¦Y[S¨ŠNÚr@tÜ”Že”.í+ù¨³à‚—%'÷D‡’GéˈpÁG¢õÓ"Q`žs¹ˆM, ‡å°pøÜ.¢Ýs;è÷X›» æ‘`¯ô«®\²Ñß”Kk} ±lUÀ×â)ˆb!>îªz{¸*⻬!ØI!.H¨<šB®O„®Dx£™ö øÿh÷ï0è„^/ ŠÎN˜S gqr>…¶1âÁO×7ïL$Cë JLoåþ©ú4ë_¶endstream endobj 2894 0 obj << /Type /Page /Contents 2895 0 R /Resources 2893 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2875 0 R >> endobj 2896 0 obj << /D [2894 0 R /XYZ 85.0394 794.5015 null] >> endobj 2897 0 obj << /D [2894 0 R /XYZ 85.0394 751.9917 null] >> endobj 970 0 obj << /D [2894 0 R /XYZ 85.0394 712.1384 null] >> endobj 2898 0 obj << /D [2894 0 R /XYZ 85.0394 678.7272 null] >> endobj 2899 0 obj << /D [2894 0 R /XYZ 85.0394 642.7648 null] >> endobj 2900 0 obj << /D [2894 0 R /XYZ 85.0394 575.5126 null] >> endobj 2901 0 obj << /D [2894 0 R /XYZ 85.0394 514.1471 null] >> endobj 2902 0 obj << /D [2894 0 R /XYZ 85.0394 371.2194 null] >> endobj 2893 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F54 1433 0 R /F64 1485 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2905 0 obj << /Length 1903 /Filter /FlateDecode >> stream xÚåYYsÛ6~ׯÐ#5S¢¸xàQµÕÖ©c»¶Òvšæ)‹ ‡„쨿¾‹ƒEQVµÓ™Žg,Xìña± ,ÈÃ{>òã@päaâù`쇱4nCäv©¾›¾ýž…c„Oýñ|Ùá"†d<ß:3D<4Ø¹š¾ž»g?ÎÎ~úýúj6qI@(q¦77³«ó‹ß&.õ0Ð1ÆÎëéÕ›é¥é»™êL˜ÝMÞÍ_fóV³®ö3¥Ö‡ÑÛwxƒ¯F1zãgøÀˆAÇùˆ{ yœ±¦'Ý~nvFõÔA4F”ùtJÆ„ áytO ŸQ¦ñ¸ÍßÜ^»~™*œéåc™ž¿…]ê#L¹™XDy»‹U²x¿(‹¥@;BŠ &aM_MHè$r]µ‘æ7ù˜JÓªe$×v´\š_b~Rû™TšOYY²çÄð5_q"“…LâF€m`ËR®’ê9­ÔZ×AÇmÔuY€¼ÀçZë»ÙÌLž^Þ]Ø8ÊØÃ!ü#ߘ©¤þ*‹¤3¬ùqÜáG8CŒnAûîâêÜ0V8O‹´–U$ËÊtÝ&K B±°8¼ŽŠu” ¨KüQß÷-ûa |x"Übúfþãõíq. ™TEbWônSË$·kuVuYÉtoÅrĸO-®WÀo÷)ìHŒ÷ðS“5óP›BS_ÉÝ |è칬b´»¬Í[7~×´Vmë϶õ¡m=µ­…Àã‰S¬c.²¨®íöè*«†°T-ÇåGpÐ÷%9îù÷Ù‰]æßɵ€=ˆ¸ìn™Ïeýêhÿ·ôZœØÞì(¿—²`Ð?WQ—dÖ?W]=W}nnüå±ýC°ü'bùüÄ‹ÿ<¸×£ÿ«Óã§dþzŒv—á…8â1ˆ°©ƒÎb{qêQ¡3Qçvx>»;»½¸™_\_}V•¦¹;÷«4q´/E©ïëÌ‘+}ÕåN½)dôÑtÚ¢ wR¸è?TöÌl½ÆÍhsgföÎŒ&.£Ä¹¦ó1©T(ߤqQ][=¸Õv2"Bi£·¶sÀ:—S yDô.^q™(æ!wžWIaZYÅæ¦3Bc¨QÆ™¯ÒÚŒåÑûdH%xêàtU:}@EãAë:Y®3#w©+ÐèÔ@²Eú ªÖ†ûDÑÛ2˜šTjüÁ51’úqÞß^ëj[–X%¹-³²´Å³mqÄç’ê)©&ïTvÜŽÀׇŽAûÖ Qâ7{Ø€ bÒ<Í"m=qd9 ö~H¹øt”ÁhL›p¥Š>aèܯ¥‘§k *Êž£Õ!^ç¶i\ÆèuQG&…lJ;ߪÿ˜,Øá$*8ëúSµ2ªBɰ×Ö“özÓ™OÅh‡Ö}”33ãT¦eeÙfBQf1"´5šÉãc–*÷Ьd•.$¬ÒP™,yJ²ÚtßoÌoœ,£u&?ªVC×Õ€FBÍRè45¸®eåZ>*T]•f™iÝ'æ¼;6­¨¶¿…ý]HU¬Ômƒ²jµÐ³3›Ù÷›— @ RxG‚ÃH¶-~º¦Î¯:(Ö¹®šfóµ»ÐÑ–6̸†Ý_>¢<$»!Æâ¬¶Nƒ³jçëÚÖF#ÙŒFM×½ÝkQÝÄÕÊíöÉUY7[²«¢Ù¾í†BÉ“À?†C<ämB°±d]EÊáºuÐÕcLÕ#„ØMZ×:_í?˜Ø«œ'òò}¬KÕ¼oìßÇZ*%×û"a±°ŽˆlˆDv¡ à^„=‘³"ºÏÚ‰ûõÃZtÈrˆ‚‚û/Û½¥9lµ¥Ñ6¯Ùü‚°Öâ¾°!{;Ân È­×éÆºŽ]çyTmz2êÉç "pLƒÐ#^†¤Ct“†Hƒòá(/ÉkQÙ“7KWÞÏë´yÑ'MÝrû/^‹v¨,l$G‡!Æ©—À5q»¿úÁqû¶ ·_†tØâžN½§*D@°{Ã'.ñh@"ðþbÛGË}«þ!ÜEcendstream endobj 2904 0 obj << /Type /Page /Contents 2905 0 R /Resources 2903 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2875 0 R >> endobj 2906 0 obj << /D [2904 0 R /XYZ 56.6929 794.5015 null] >> endobj 2907 0 obj << /D [2904 0 R /XYZ 56.6929 752.0628 null] >> endobj 2908 0 obj << /D [2904 0 R /XYZ 56.6929 688.4621 null] >> endobj 2909 0 obj << /D [2904 0 R /XYZ 56.6929 624.8614 null] >> endobj 974 0 obj << /D [2904 0 R /XYZ 56.6929 585.5151 null] >> endobj 2910 0 obj << /D [2904 0 R /XYZ 56.6929 552.3266 null] >> endobj 2911 0 obj << /D [2904 0 R /XYZ 56.6929 516.5868 null] >> endobj 2912 0 obj << /D [2904 0 R /XYZ 56.6929 450.0643 null] >> endobj 2913 0 obj << /D [2904 0 R /XYZ 56.6929 299.0276 null] >> endobj 2914 0 obj << /D [2904 0 R /XYZ 56.6929 156.9811 null] >> endobj 2903 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F40 1265 0 R /F42 1338 0 R /F54 1433 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2917 0 obj << /Length 3230 /Filter /FlateDecode >> stream xÚÍZÝsã¶÷_¡Gyæ„ß@3}p.NziÎu{n›i’Z¢,^%Q©ó]ÿú.¾H){Ò‡œgŽ °»¿]ì.ˆgüá™â(£šÍ¤fˆg˜Ï–»«löcß]aO³D‹˜ê뇫?|KÕL#-ˆ˜=¬£¹ʔ³‡ÕOó›ûûÛ»oÞýx½ <›ß¢ëϲùû›»Üüàúî¯5™ß|wûáz%&ˆ07t"›ßݼ¿ýfñöÏ·oÿòï¿ÞÝ^ÿòðýÕíCËYÌ=Ψaë׫Ÿ~Éf+ØÄ÷W¢ZñÙ3¼dkMf»+Æ)âŒÒг½úpõ·vÂhÔþ4% Æ℉قê°Í¤È2”q[HS‘¬Á)‘*#²Å§á>5EJ <‹';[2%–$Ñ’ %å`Éûc¹oœ:šM៊c]V{÷R­»Q`n° =b,Àˆ™mŸïŠÕb¹)–ÿùoµ?ˆ™P äK±§?¯±šWOÇ|çVÉ÷+×(>— :Óº—­Ì44¨¸ €ˆjBÊ*àã™0’±é%QbÉžœËþ’ÿÚFҌϷU¾*÷OæEÌs×g¥h[?gÙoܨ[‘¯Ü›SÐ|¬NÇ}¾u/åÚ?G­›Ì‹fjþø‰ðk¸£J?Aížy]Ÿ@½~ÍÊu>z"σ˜½Ï0EDƒi.0FšsbwÛ®*ö+­Å~UxÕ?—Íf€Èº9ÉX8±X¤˜K„¥’Oèã~›¡H/á‰Æ`%GŠŽ¹Â«˜jV-•…Õ÷Ž)Áb4 ¡(÷<­Ëmaå1` 3bÜ’˜æ­¥J0ד“Æé>w æ±ð=¡k/‚`LÜá ^Öμwš§òSX±C5¼”ÞÕ”MëŠe¹þ2·cçÌ›·Êõ~çÇö•—mf3*V^C?ÂÞÝ™ÿ½¦ü´Þ5Œ[Vfœ””QM(#PYe”IË)—°«VçV…!N‘œMóÕR%ë©ÜKÆ…ìsv_×Õ OªºYër¯Î¢(cs8|‹§cÙ|qöä4ˆçJÏ﫺.·žÒì£vT¹³½ÄqL¤@Zë€C£¨õi»µ K¸EhÊŽ lU¬óÓ¶1võ&1=cÞi:˜}a¸·1²Š÷/d8ñSÓ.fgÌ·­–ùûƒÓkm.É/Ò ³ˆ];Ý%~5bTû™x$õhD¹Œ'ÞƒFÇØ$pê·ÄÖD`Ÿpni ˜Y˜¹0v˜yï±:Ô*šKòr¥jÄíe`cŽè¼qXzÿ£ëq8ZVö¹ªãÎuqt´æ 7Ý7îµ:úWø—šÄQ,=Væ7å~Ï]„gg:5‹j½hã…7Ûă€a–cÆÚ`Ò;ª1ÙÐ’¨¡ºÇÔX¦$µÚo½× 3í÷?Æg]$'¦lÊå&·"³ÎµòÞ1ìÛ¼´ ïÂè´ š/@Ñ¡ú‰ ê‡Ö‡¿_s>ÿ§{9ÇÑ= ˜ŸVîyã•ïö8›ÄÍa(: À‹Ã€™é £ÀAú;Â@+¬ß ˆêÅ@€ W @xð„‹ùªØOyã³=>¿ûàž‰òþî| À­g0Êw;TœOâú:T˜·H0"ä~Ü¢ÂÃA"*3Þ‡C àŸaƒi:׸±|[W®ÕÚ´½@ëi{ò³ä«•c¶öDçVå>Ì`F滼1p£UÝN ©tSÖ…=D@½}<žÅi›r»º€oŽ$“øUøÆ“øvÿ?CÛ›Öà "ÊjWÔk$¥&A$®fäùõTº†O.œžºŒàÍpÚ²e7ä­L-;ÅñSà;–ž0DGÄA_Ö&Õ›ÌX&_1Dc—¢ ¬~}øBDý®Ê:·!$¡tîh^H*¥ ÷ñÔ¸ÎcÚ^°×âø\ÖþN¸fB—ÁE^§â: ¡½”ožÅuÓn |„zeör7ï r›òP0 –ê}±"¦šÅ^ì‹ñKc@Hê˜Â}¥Ôgæï‚ÿ‘ŠjŒ¤âz:‡Š©Æs¨–ÊæPë‹Õ HdÀÖ†Y¤ ©²iÎZªký„–C«eŸ·tBëùÏhãâ‚w¨]6ÕͲ×ñ| 2–õŒ»)>7“Èկȧ‚`%ÎÖŽùóØäa¬º4ª-—¦¸F”ª˜é]~˜ˆ•T—JcT€ñ%ìuDÐóDyߦJ)Q&éèD8ldН–蜱>ð$gÆ{œµ¸£˜‡óž·¸3mƒ»Þ D-‡“ …2ÓŽª(ö„Ï¿…ƒ1¡5p(‚³—WÒÁ¥f„u€ Ôeí–]U…oÙzŽi,óSí_ ›V&Ííyæ|ï-­X‹Xƒ‹ô&rÚo‹PC å¹Õiw¨GoYí›bßÔÉ£42FÆ#c4ùá¨1j8LD{Õð[̰³E[ªÑMTãnKéu¶•·‘«‚ÅN¡¸î˜<ø³öbhæÑ›ËÅ/™6X ÂúÑÐk,7]þ\ŠWxyŸ¦%pJ!¿ä´?íŸîF&f1Îhâ x‚AÎUiâeFBhmZ6Rƒgîå>?~qíöpm×8æ‡råš]=ÛüðKj3¢7sY]êüÎL.b/9RÃ:u&¥²Ä:xêÎSØhL†@Ku…Îîv,Ö:J »v#^€ÐåœÑÍÅs5vè¼sT¥_)³øÌºý<²«ùC{™ûeÃjÝ%€éýâz±^&l¯'“áíb·±a/ÓÉWý+„»~´ß üT|“ávÇäÕFHÓ\ï¶ÈkO¬ ¬ŸélÊ'ˆ”¿,æ=Ï€¥Ñ³–ƨ/Ü\ÄTã§mKeÛÿ¤[¥[a'«å$ƒ³‚Oóˆ|õkå)"Œ…Zy °]Lâ(Û‰ —ò§JBÏ   û‹Eª¼›1]Ñáì:Öy¹=d:ŒDàÜ–`;QAÞÔnº©‚6BÃÚÄðØåŸËÝiç^ÅqW¶1t<<üàî\††s‡Ð(÷6N†Ù£ -Ëæ76úÄú¼n}þ£€nùvçsÃÖ—ÛVéÙý”›J‡= È¡]qÙ×s¹51¡><ŽÃ…!¶à=~Ä1ù±¸ÆóecC{šáùƒ[ÆÃ³.w%Ðló£{óœê62IZCG“`L n[i[xý”Æ5· {uðá¨adŸønÂ2ÍÚÚ’µ9û:=³”üb†ˆ%˜¾ä,"¦·ˆ–ÊZÄO­º8–ù6•$*Ø4k-U‚·aš(æ}æÜ·XCre=­QµQ«éÉÝÃAkw•fzâPÜ !à·.î3ÁK&`—ŸgStôu厫¥_ÄÉ"LÁ=üm³Ü~¿ §8:Û€ ÂúA©=Ty»qâóÒv8Ñ»Zëi÷ÓI6¾ÙðE>ÅgS{ „%BðuªÃÈáXîòcŠÖë¶œ\ÔMû•Êát ¿-йŽoª9~]8Â.9_¥ÍçGtßÑ8¼‘E÷ûº9Ù4º’æûÒ)®Z¢s¶úØyeX÷øzkðè>…±à3ŸÄ˜‡‡6£‰ohwå¿¢q6øŸÒù[óÅ1rÓÄ_ÞÐ~yc®¨¯Á"À¢€PEòbQ ÑÞòaÑò.;Q™!–Iz^´øM1r¨ôÂ&iRûÙ,¬÷›¿Ûî>QgQ¥HG435qˆi=S†q¬A:˜Iæ_¿»û&$õ˜Xܳá®8/«ˆLlëƒM-endstream endobj 2916 0 obj << /Type /Page /Contents 2917 0 R /Resources 2915 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2875 0 R >> endobj 2918 0 obj << /D [2916 0 R /XYZ 85.0394 794.5015 null] >> endobj 2915 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F64 1485 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2921 0 obj << /Length 2743 /Filter /FlateDecode >> stream xÚÍZÍw£F¿û¯Ða轨ӟÐ}tl9qvÆãµ4IÞfrÀx+#Pç¯ßªîÈ›™Ã>hŠ¢»ººêWˆM(üØD…$4ÜL"#‰¢LMVÛ :ù Ͼ¿`žgV3ÍÚ\ß-/¾½zbˆ y8Y>µæÒ„jÍ&Ëä×`N˜"S˜‚w—ïç׳«æWÿü÷‡»ùtÆ"ÆYpy?¿»¾ýe:ãŠ?0S¼¿¼ûxùÎÑ—ßÏÓß–?^Ì—dmé(Öï¿þF' lâÇ J„Ñjò7”0cød{!• J QS6‹‹5¶žÚWû´!•&ŠËp2’hX¿_gŒDŒS¤ Î8ëÓYÍ…:›å¸ÑooBÙâdŒh£@2˲-’ôX†it8i¯x"WÍÔ#o­f""#s$×â9]eO¯p(B/ë´š²`îÜýÝÂ]wS¦ƒtUØkR"‘åºØoÇð˜:Új®þ“zbUxÆ4u„ìɪuêŒÝÌŽ'‰»-Ë´“T÷EYfÏ*»oZ¥vÔ?ãÔšJ0b”âvŸŸ8—Oq¶Á«©­#•?ˆOTÑ$}Š÷›Êëìüt!ʼn ‚û—òx›&³U±}Î6é_Ežö¬‚Ź>,þé™Wn´©™@Þ—x—È-Øš2_Ap<¹±5è‘ò–v˜›=ΓžÙ¹",Tª%ö9/véÐ Ãk 'pà}.bàUŒsÌ׈cÖ\Ö1‹~Ç2’^¨'8QÔÒ±l --¤f\¸†«Gº¶"§DKÐDG¼Ÿ§‘ vY  ì ÁˆžzÞWŽZù=ÈŽ±…DGœ÷ìáhaÍiÔœÀ |&¸}ê™’—(#ÏO Ûfž1+ûæ¢D²¨6“YŸ·±Ú´3r·Ù—ZÔ" ’Ê LÑ!Bâ( ¿‘å–·ÜNŒÉŒGìÀ¨.@lqŠªØ½ŽyN©)ûÛ.?hÞaAÊÀÌ£æÝæ6ï†Ë*v×cÞ€ÿZ„ca‡®C=.VÍÔ#VGŠð2‡ŽXW7 iHPÓ0è‹2cE\¹Ç‡XdwW6Ø!.WAž<¥Ž!¯ÜãÇWw½¾[,æWŽõqï¶f­Àªlo n^1ý}÷–9Ëéyg¹3(&HbümÛ¬D|ªsˆapWÇ0ÄÏÁÞ†ñˆŽ/E¤’µ[ö…IŒfâ)áiD9‡ûUD¦ñù7â¾<낚3~q`q Ïd½¢ì}°gÁjD*«×Í©_¦2zLªšçTª.üðFD±ɘ6ˆxhiÔKbiÅÓѳd¿}¶.Dpô‰R¾IÁü$7ÎüÀ–Öó•ŽsØ{ „ñ°m‚ûÍ  "¥`ƒVƒKõZM»³i­²K7q•ý1d7RBXQÛn ç!aòÈ—k& @n?*vÛ¸rc48dé)å>«b«&ÏëÏVGÅ òÒ,ÿìhñ¾*`&„ Ä$=úkì'KŸã]\ùÉÊÕ.{¶!)RÁ‡Ü«ZÀ¢Â”wB»[XƒÒ¾ÅjfêaÒéÈQ»bAì¶E jH]ïÔf3“zΓ;¯Uë}écêlæ Vëƒi’U^ÌïšZI}Ľé ÍÎØ[³N QŠò&þ£ˆ<2AR¤~”à‘Vñ¾L-Î_Ý õq`Uyî}VïÇ™ÝÇ“œKEÁhUäD[‹˜0¸­ü›²h‰b °¶szN>…Êù#­¡ÓçÛ4έñÆFŠzÔ!¹ó™ˆ=]Ëè#G3s•þY b'è¤(Ï6×0z6\>_TÌŽÊÕ³§rõ³¹|V!ÀQ¥xÝeñ0U*øÉÝt ¤Õɤ ¥ã±©åáý+lt7>Äs¼óñÜòƒ© e<üZñ<$\ ùÆxÂA7€yÍVð^hž‰ˆÁ¤:­¤¿FE§¨†´é\E׿±ÎšËZgÕ›ò2®j%$Ùpsý“ŠRcšqá®éº„ŒWó®xWkOÐ…5ýÅ›TDé0ì“÷¸ÔÂ2OÕ"“Ô¦Í8ÊòÕfŸ¤î&r¶Á£ô €óyý–çäÃâó"XVø§.«pã&eÆ›V€LŸÃdȺ˜—]¸ÛM5 ²?z\ŒÝ¥Ì¶Ù&ÞmäÈRM?¥ù¡ Þ•«fê‘«ƒ|šPé®\ù˜qȇ×Eš'ØÈÃñ}±ÉV¯n|³Õ½;ÏŽ€°¸¿q`€„“2 ‰éŸfI8´9ƒ]¨,÷©» ÂjmAâÜ t3sÁ¬jÌêi¡y×L–¿,kûèâtoôÑFϾ{!‘šý­Ê‹sHAõ—×J½u'†ë¯Ý“œ©‘ZL#¶î™¬©¿ô™:6åÏÃh |c’5L§¢uAÔ¸ ¡-ÛjH/ÊøÄÖ z‚3qÉ[èiç´è‰£n²‡‚?%”màƒm\Vé®ÍäÆÿ¸½»z÷ñzîîŽ؃eˆ”#7@õvìzXmó÷øè“Àâ(}<,Òô³VŸ#ã$yÊ8…£å¦00ðÔ§4¨ô!gÐ,E'g¢3vÙæ6̆ËZæõñ’¡G1b|Éš©gÉöî"A J»K^C¡à”çËÕ‡ìUêÔçEn›G­Ü}ðãÍKüêÇ`R€TÉX÷*"„_¿ý(¤&ÁÆOêÀ4rPžÉžÓÏ}¢Àx|í –!‘d£BÕ<§B7Y„R²#UÓdÁš¿xÙÏ]xcs~¸®|a"_ô Žuî½Ír<[ûj¶IV¾éŒ%b$up7ÎåH‡Ü ˆ7¶ÿàpüJ_uÒíÆF$÷.ë]ºï> endobj 2922 0 obj << /D [2920 0 R /XYZ 56.6929 794.5015 null] >> endobj 2923 0 obj << /D [2920 0 R /XYZ 56.6929 215.6625 null] >> endobj 2924 0 obj << /D [2920 0 R /XYZ 56.6929 149.9396 null] >> endobj 2925 0 obj << /D [2920 0 R /XYZ 56.6929 84.2166 null] >> endobj 2919 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F64 1485 0 R /F22 1037 0 R /F42 1338 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2929 0 obj << /Length 2498 /Filter /FlateDecode >> stream xÚÝZKsÛ8¾ûW¨*‡•«L„8zbgʳÇ9»[•ä@S”Ä Ejø°ãùõÛxФ )[»{ÙòM°Ùh4>ôKƳþðŒ3RÍ!b6˶ál ï~½À†'°LÁë—Ç‹·ï)Ÿ $bÏWY…œãÙãòËüúááöþæîŸ—aáü], ç®ï?_ÿ®ç.™_ÿz»€G*h L8–|q8¿¿þp{sùíñ·‹ÛG§ÏPgR©Ì_¾…³%¨þÛEˆ¨àlö!ÂBÙö"b±ˆR;S^,.þæÞªO}6`”#ÆIâ1Á3!Ådd&á QV[º p[¯Òm¾”[¹a8¿gGýÝQ?¼W <Œ®N–f›ü˜ ™îÀãl¶ã„}îÍíâݧ»‡Ç»÷î£Q 1„&"®ð0RÀU¢Ð:;pàĤyª‡$­"¢¯p[M Yxs¿€ë 1’h~I8ߥlõª^é±ÛA¿ÜÝßhJèaYHÿõÔ«Û¯fVÍ%æóÚ¬v·x‡4õ¾n4±­GnîƒÙÍÈúEµª›mª…ʨfG¥ˆ$`W6à™©Oïßµš‚ëG¯2­–nŽ!š1‡Pf‚î?6¹ZG€Ïõw€ùü¥è6ußé7©R~Ýoóªk¯<§g(Obs>GOr‘$´°})ÊRË×¶IÍÒf¿‚Ï*íK£¸¯aHÖ}ãLÄçrÆ‹Vœ„Hœy›wÙ[¥’Ò£(Ž©…÷•>§ˆaˆêdrPCm¥…_5QTEW¤¥ÉSÒ.öš^I`Hâ>oмE?‘¼|Twhq2šÌ…D¢sÆãéÉËfx‡é‰ã’ëÑtIA¥N.i™ú®OK·õYÙ·ÅsŽŽ¡€& EtC®ã(p\{Å}(8¹¤CÁá’>Œ–¢ þߣ ú?BA#‚ù9 ¸N Àr)ÅM)J‘jÌü•ÈP=ƒ?%pº'õs\GöŠc†àGJÐx²ÊÅ ?Z,äÆ 8³Ùv*s ÁL: ¢Ã@$ßš@¤è¢?/ÃäVÙÄðsÔ®|XÃPý0‘-“6ÄÒv¨ŽÆY›? SrÈGxÍe?¢¾ "Ê Pj{‹1ùÜmÒNR‘ pe.e‘f^®ƒÝËI»{ù10tEÕç­ùЬöR7ß5Cº‚‚~"Õ¤cŠÞ¤­Þ®ÝÁ¨hÈ6iµ–I ¥±t­&¤t¥«|€ì^m@gøzªÏ5!ÕŽ©vuÛOÞL‚Љ0Œý¥ÃÈäáÄeî¦:ÔŠšQ£€z²9©ÍxåKØ ç(Lb|xô'p̉"ë¹ZHçJ“‰<å651ãS[—}gfwi·‘°;ê]H" ùiï2ä:î]—ò.KŸwÁˆ Fý ‰±w!pqÏéç¸< ޽K!„¤‘† Õˆæ$%±Lóm]ý¥5OR=Mj U ÍÓÀ‰Ô=øX£…o[ÀeŽX2¿‘Ÿ¬ì•FMšÉ['tõˆ'UÇax8Ÿª‹ÄåÃOy`2b,Ï-SÚNœ«sÔÜé§Úñ´„ik+™k[é4:3 vkÒb/iŒâˆÅg 8à:AË¥ xムlÆ&½«ø ¼ 1§5s\ÕFà£@ Jƺ-vyVH'¡ŽY$Ê{Á`4R´öâTp]$ÃLß*w)ßÕz,–PǫבµÒ*ËõS½ò@‡@9„C"ÎA'd¸ÒK¹¾ý2;L@ªQOVE =`:adþ¸±%2–íãM¼?YƒºÜíðZ1ˆô\PO£q¬$$œ,ƾd«ª;›g¥[È—GQˆ!»åpO£pÈu…ŽK¡ðö¬#œô9½Žð¤~{Gx¨ ×Ž44mˆ×énW™Ì¨eÁKŽC˜æ „þ¶óòeoo“"ȱo ›.Že²Ñ¼îºzݤ»M‘éwõ.×!³U«ñyÛg£ˆÉ 'ð> endobj 2930 0 obj << /D [2928 0 R /XYZ 85.0394 794.5015 null] >> endobj 978 0 obj << /D [2928 0 R /XYZ 85.0394 769.5949 null] >> endobj 2931 0 obj << /D [2928 0 R /XYZ 85.0394 747.8192 null] >> endobj 2932 0 obj << /D [2928 0 R /XYZ 85.0394 711.7108 null] >> endobj 2933 0 obj << /D [2928 0 R /XYZ 85.0394 643.9803 null] >> endobj 2934 0 obj << /D [2928 0 R /XYZ 85.0394 546.271 null] >> endobj 2935 0 obj << /D [2928 0 R /XYZ 85.0394 438.6313 null] >> endobj 2927 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F54 1433 0 R /F64 1485 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2938 0 obj << /Length 3023 /Filter /FlateDecode >> stream xÚÅZmoã6þž_aà>œ Ô\¾J"îHws‹Ý\î6ÅhûA‘™X]Yr-y³¹_3R–mÙÙb·¸ˆ)r4gæyH­˜pø_LLÂ+í$µš.̤X]ðÉ#Œ½½Af…æC©oï.^ýCeËl"“ÉÝÃ@WÆx–‰ÉÝâ§é › >½¹|wõf6—ʪdzy{{uóæúGx6¤@„óé»Ë›.¿§¾Û™•ÓË·Wïg¿Ü}wqu×Û3´Yp…ÆüvñÓ/|²Ó¿»àLÙÌLžà3a­œ¬.´QÌh¥bOuñþâ_½ÂÁ¨uÌÚdÌH€7ã©JÆ=%X*¥Z0-SÛ{JŠ1OE)ôÔü.ôÕ?=†¥)Ï@;Š4ë®lêCž1%aUÃILë¥Fl“Ã…bJðd߸÷®kgsaù´[:j,ÜC¾­:zX¹U³y¦vÑÔûÈäöWÂÓëíf3ÙÔÕ]õ| ¯©cW»]¯›MçCÔ.[r’:Ii Kƒ.òÌí6u^‘äÞâtÊ2ÉÓ ø JÀÖÊŒe&E f‘~ðiYK°:ÕÓ"ß¶®Å¶"s±³¬Ã,¾;®GVy?º =t31m¨yÞ¼^çm‹«Ã7Ëšzò͆ºšêjŸÛέækï²æc¹ wtœ ­çûVçUÕ9ù “èa[a³(„j’¥L™ì|8„NGsòÁ¼ fÍ’DÛàý‡*<4Ê&¨猊2ÇFí…1çLj«÷¬º›Am7à¥ÁÍþ·÷¦ïÛ¶°uÔ\¸ûíãcY?’ÔÏœ«üÙ€’Û¦mËû*ˆ†1zÈ)ÂGâT&–¥ƒ@s©´,ËR; ÒE ºWÓmò⤚ìsµl\Ñl#j”aYbÌçêiËÿŽ£˜\&¾šDp½™C@†›T…÷WE÷éä$Qv êØônéZGÉ+¤½i×M½ ¾® ¿Ë týþõaTBi‡O Ó\fŸƒ8’Yïý1¼™G…ó¡Æã–&e¾Ùnb\×»«wGfŠI)¾¦…QãK&f “*꞉o®¾ýáíð¹´O|X¸¶Ø”÷.ø¿¬i#õ^òj…ÆÅ˜úkÙ¯ KÙòï#»žDeú]?Uç4Ô ùó…n u¦ÒE)_êê±R'XfM Å?ëm{Të2¦ÓDž7, ¶_íÓ&5û–½¦hÏ»±b¤pÉ:=´ð0ûì.ƒÔS³ù€À¦aоÀº'´Ï$?pÔ“/>æuGU¬áï XC¹®‚ÐëÛÚÀþ®ƒ@Ýt4Ö®]QBôH·…go;x™'½uu¾rcl®,ä‘V‡_VÞP±;ÜØÀbµ~áÛWeíB÷24êíêÞ» ­É~êY‡âä†:r_d Qì6¿Óì4G'Q;he${ý@=ePZ†Ù¶uîñeÀî.0\ŰÂõ«€¶_üâ*¾¡fN?- _ÞˆûNj&ã¹Z÷±Ìö«]œÌFc©Òç³q(u:{)Ÿë³¹åQ2J¦mö‚]QhÄ®a¼A´éÔØõ} \.’²&øò·­Û”.ÆHÙ¢y‡ìIîRq'ug^‡Möyå÷v˜WûÁѳz_œÛI¾‡Ÿ“[š@6 õ“JÙÒ(å·ô¨t&šAËÎO…F¦ÜƒË´0bÊÿÌ€eoÊ.8¥g÷Ð Ñ»±¦ÝveÑö\b Ë Ÿ¸mm·h¶c§àtf’(cÁ}*»#‡g‚kÍÄÃÓÆšÏ{•ù3ù ¸‡Â‘B‰L’3‡izƒ®ÐŒo0‡hœ˜aÏ­’C·÷åéa´\¦™„ðçR\÷ÍÀ3&Ñ‚°%cHÿs6Oùy"§WGžI˜MóëT2nŸzòÛ6V[«HhÐökÝùÀw¼º^ÉÉ›V4.*(ž5ûE%Ãð~ œ&:3Lð‚?u,)Òþ$‹mêKà´Xúƒ¯cx¶tmGODQÓé·×7oèK 7S|úq&ÍÔU `G˜†p«žé%*Ï)0ýU3&¼·ØGº´¡ƒh6-–yýH‡Î,T3ðó°í¶Gí«\,´E«†“™Í&Ãxø²S;‰¢?ß]Ø|YÌã™ à”‰Lž¯aZBì ™ž¯a½”¯aï_&‰«üÓ¼mŠGåNH(˜ É/x¢Ôˆ}{ 8Ò€-{^VUó4Ʊ8Ë”/P,¥!GEÌQÏRéBcM¿±@î]¬‰Q/Öj¼šR‘³¢”ë<&ÉwË0Y`øð1¯¶¾?ñ ‡]šÛ„Zþ~ÛçvN'R eØÙ="Õ¹•¿ý±Óûmé±1CÞÓ-©s™ðP45ëãvoa²þ ±6KBzB7À9çôš—„_ºòii<Îý»Ù~–Rï&¡«/  ŠÍÇ2ºÛÖÀçþVÑåÄ£C-'E¥é:û*¸"€T*õïÈúþ•SÈ"•ì0É È¢ ²”Ö* ú²€ÂTÆpºô˜òoÿ÷Æ£Ìuß–Ó·§°FÂtZ$6` þ…s¢Ð°}kÔ¬j>ƒ5JÁ‘/ãÉkl¶Ãh·Ëf[-¨ía~·uí ×¶9žç$ ÷×x R ¹Ç#xZå¿¢û²ó¯àB¥-‚‡¹æš’2 Œ žøžƒ|v*Ù›½YÍÒÕ$ˆëÀ‘eîÉôtõ°­¨çÞù [ókÀÞç¥Z•xì±ßòÓ}šª ‡ ´ª5œW«rUv!ÝqW¥…Š|½pä±êÙ_(â(¥: \Þ^3꽞‰iGMtI˜gãÂÆ„[×…©;ŒXù´D?iž# ± Tª°cXE ?Øá¾Ûä‰%ôìÆýú¸Á{YõÚÛ"źk6áíp™wTü¦@†!ié'Ç»t©–KØìrÓÔ+–FI0ø¡öä婦n5ÐMŸ pÒix¡ŸcãA¶ÆÃØñ0æA@4ãþÁÔ)Èß4ß ZUÛ` S%ï¨/l: Ý—„mµrEÓRÇÐ|¦½†þ&Ds^!)ôzè§*»®rc–úmuhçjõuŽ-G=WHpEÌ:G=1yˆ­ìñ†T1ßì˜ ìÕ% À’ú[åÖQ}¡ÜmƒÍ*XCÛÊxÌS–i€—ýðññåIh_® vmdªÝVLÃ÷ª?gÙéS¾§þßô–XðÕYzÚKyzÚÐSËœÂN.Ê+ºðÕiœ ËD©á´Çä4JX·d°@ca…{潦;§Æß_ÈdœGâ±’vÌÞƒIÀ\gQ2 h½áK¢/Ó~.Ÿ<ËåjEÔ *ºVÃì!FµÅRåž@Ü‚¡÷ïzGƒçxu†Ú}€ ×ð\ÔGúbqÈ&é:ræ${ ƈI¿ }³ŠéLÛß‘ñSä-å,å<{» b™üc©›à«‹úúÔm¨ù uƒÃ‰³=æ6¸%°É€¹¥¹¥XËBO¤ L~ zi ,ÁÑñ¥²ieüÀ2ߎr¡Áý™ŽŒúk¹*HÊ‹år²f Qîb9|Ï£;ýõƧ=P•J_W¡'# ÝýËé¢qmý玺] `V„ï­+¶þé?-ÔáÓBÓ†7ÂAê/ÈçxôÂ!yBL¼oÄIœqžÆ+9ZëÏN‡ðGŒ8 ÊŠÑ> endobj 2939 0 obj << /D [2937 0 R /XYZ 56.6929 794.5015 null] >> endobj 2936 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F64 1485 0 R /F22 1037 0 R /F54 1433 0 R /F42 1338 0 R /F61 1466 0 R /F62 1469 0 R >> /XObject << /Im2 1455 0 R /Im3 1642 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2942 0 obj << /Length 2582 /Filter /FlateDecode >> stream xÚµYßsÛ¸~÷_¡™>”š‰pøM²}ò]œÔ7‰ã&vÛ™»{ EÈæD"u"'ÿ}w±MJ´ÜkÚñŒ .‹ÅbñíHÌ8ü‰YfW¹ž¥¹f† 3[nÎøì¾½=Ag•C­oÎ~x£²YÎr+íìf5°•1žebvSþ’œ___\½¾ü×|! O.Ø|a8OÞŸ_Ýž¿#Ùõ<—ÉùÛ‹OðªreAIXÔ³<¹:ñzþÛÍÏg7½?CŸWèÌïg¿üÆg%¸þóg*ÏÌì^8y.g›3m3Z©(YŸ}:û{opðÕwŠ63RÛÙÂ@ ò,ŸŽgÜÀÌ©‚¸pˆKŒ”S‘ŠZ©Å-Nô‡7V4xfr0ŽZWmçj·kC"À;•j9Ž{ä]¯5ážjSƘ±·­#ÍÈÁŒ¥yj&=<0kˤUAõ±Ù}v;Xsn“îa7Y⊲ ‚Ÿ&!s$[5A»ª—ͦªïéíöõ55¶Åò³ëZêØ„N®X>P«(K¤m:áP––}!ˑޯËèk•ÔM‡ ™´[·¬~å\ºòU˜Õp-SH)æTWNÌ\)¦ËøX­×4ƲX/÷ë¢s4RAÒÒ­Šý:Œþ¥XïÉû¦Ÿ|í·z¿¹óÑa³Šv:·ìb—Ÿ®oÛ¿Ì B!H‚¥@pÈ2 þ…@ÐÎE-#°ß+lÉD’€Ör¡{•6èuI2ò $½g ôžÁsàYèNºeõ¥*£øî[†¾õÃúˆ´Ô~¨î¢ñIUz(¡q)ýZèáZðñr/ê‰õši+b¦>Á½;çsÆj]G"Ÿ¨ (èuèO\9Ô ® ‹œË«ØßÕSQ0›fqóE™˜Š *›â[œ {)l=Ê-\–²BiÎ,ãpá ¶)(çÖQËOøµïöAX7ô ‘IuÂŽð<€¦µˆ¿©8¬C­ç‘µ×òÙO!+ Qnâï[·;UÉY¦Íi¿¢Ò„_£eÁïÀ±O®ÛWöÜgÒ1ºjÉR§NØ––e"Ï‚R±ê|^I€ÉíÚu•ð¾ÝÁþZ»{†l¶nWtUScž)P·÷h™KZÝвcî3ÒwŽ)sOßÚfùÞ sá=dôîa©)`e´Îóq:<‚,Ù6»®=J€N–CéµÂ0eåTñUæIH6]ñ=X¦2#ž7F9 Í¾ËØØ"ú·ÐÀ|ò4•Ãè§‹)g˜•:Y.™P‚«ÁŠ«…WäÌ(©ÃŠ~˜/¬Hnà¿L.Žbƒ1‘&›Èk‰›Í~Ÿ Æ!ÚŠ´m?Û§0xÁ—9{ÝÀ”fÃYEË‹¡i?-;ÜrÂÀ 3¤9ã\ir–_i›¼«ê¹àÉþk¨v˜¹2WÙì¸zŽP8P:Ø-™öXŠÏsÉÓ¤vë?Ï!“‚βØwÕºê¾ÑûÆ-‹«vƒ¯©‡o—»fK­k36v Ê\ )[|X·0œ0IH_Íâ>Q<ùºtÛŽÞÉC›'O> ´™Àr¡R&•Ž@}WÕå¯Üp ÿÄDL4ÄDˆ˜!~`¹ ÇØ·’\ØbýÔ€×Aµ.©áKõjd;ÆŽ÷ê˜X‚¾sm³ß-¾¥°Ù7@ e€(¹­W‡8Þ¾‚³þYÀÀˆKÕRç+ê`•àƒZn"BÓðÌÆj·Ÿ nP.#k¶nd³©Á?;™"^òt<»GÌÒ†÷—SæÉc_vGYk,°¹\¿œµ*“1·«`’Øãæ™§q(=H`ú(€DF èÊ+î0½°‘êù„ (–ç‹íÎ)šy%Ќٛàblš§I ÔÀQY ¸ _ªfß’òÁxAZb-Þ;£vSƒ™ñH¯Ç›„>y9Q|ß¹®¨jŸ¶hÁ—³i\ë+é©g<8˜ÆzTc Ê2«àt2Äðï¬ *›9œPOËï«[PQ~„¸³”§êU‚j”J–¥'™R¯å7՗øä hrhìhĨ41äpÍ ²Yš ùÑaÑ\Ò* 'H¿u=…ì©2ç H¾¯U÷,“ÔZÀÖ±ö4“jˆOÔòñùÇQ|,,IO•&†Õ•:ËÇCþ—ñ¹ÛWëÐ$l_ý¡¥1\¤/Dp u"‚QËGðëç,2öæÎìn±Œ8¾æÅ@t¯×šðo|ÍêÉÈ¿wMâS]A­•'ÁÍf‚ Ãéߦ:ôüðúÝÚ8ɪEõ½Ã’­¾=Ý àêWî/Íž%Ê Jœ–RüOˆršIËÿ†Ï‘d 0`2%^"ÉÆŒ‹ŒPâŸS,Y0“ÊÈÎ=?þèÿ_yÆ|Ù·eòöYÞ¬ R8oæ,ZW¶ŸáÍêoš>Á›•‚‡ôÇiÜxj¤LÚ³lo<‡n;z£ò _2á œ¸ÄÓ &>õV÷Pk¾ÔPQÙ¢›6”þxyõšZ9=Jªùs¨ðn'Eº8¨»„&i–l TÿF/þvž;·ñ埬MO$â÷QXÕô,è±Úwû]od·D0Ÿ«Úäú®4ý?ÔìQæCB Î ó#^J ˜Ö@ðW—o¯Îß}šÀŽT–™pÏ~‰”ÀÍ=TíáÐïHÐòÿ•^w_ÈØðcûÐì}™!«PxzîéJH†ëXx.›º£ÖÔ‡ð ¾ nÝêÒ_'îH8šÊž|íêr9u§@È ôäÚ±G˜ÄmçŠòÙú% 1T®N—¯ÒóÕ+*…ÅøÛíõñ=‘ap–±'핎G9.`í‡Ã¾i|З¡„ªD73ë¾^Õ Z“WnÂ"Ìä qhTÔ ‘º¼ºÁ"hn.>¾?Š]ª™R° OzÒkM¸2Š^š3%`7}yˆ—‘eóXŸp5ÍdŠè-rHÇ< ¨ì†AoûRƒÞºº¤‹1O±¾…¯ÝC$fOÛGo¦½ðí*(íëÒáϵ£4?„ ØÿÈ¥ $ùéÃ՛˷·Ï1è7—®^„Œ›xÌ-'LÛæyöÒ/j³·€ èéýžOn*AÉÚŸé4U#uMC ºšüJ_» ,]»ÜUw±O¥p\SÉ ÀðcÍGÍpÏé†V¶OŽÐàOŸ]á’σâàŠ£ÿõSA KD§O>~_Ôûb=ugo3¤Šö¹³jÜq !enxŸ(ßýãèÓ¯¿){nëA€a‹æ":åAÊ ž÷e*‡!‚£S‹k}8+£°„ËtbZÿ>_9òendstream endobj 2941 0 obj << /Type /Page /Contents 2942 0 R /Resources 2940 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2926 0 R >> endobj 2943 0 obj << /D [2941 0 R /XYZ 85.0394 794.5015 null] >> endobj 2944 0 obj << /D [2941 0 R /XYZ 85.0394 248.5924 null] >> endobj 2945 0 obj << /D [2941 0 R /XYZ 85.0394 96.7907 null] >> endobj 2940 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F64 1485 0 R /F22 1037 0 R /F54 1433 0 R /F42 1338 0 R /F61 1466 0 R /F62 1469 0 R /F40 1265 0 R >> /XObject << /Im2 1455 0 R /Im3 1642 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2948 0 obj << /Length 1806 /Filter /FlateDecode >> stream xÚ½XKoÛ8¾ûWø¨˧$ÓÆí&HÓlâ ´=(«kK^INšýõ;|éa+I],|9‡óøfh2Çð#s¡HR9%G1϶3<¿‡µ3âxBϹÞ-go?°d.‘Œh4_®²„“„Ì—ù×`HŒN@®N?-΋Ï_n®N/¯oί–'!q$‚ÓëëÅÕÙù'!¶?ÆÁ§Ó«/§—–v}"ipúqq{ò}y1[,;å† ˜iÍþš}ýŽç9Üãb†“‰˜?Â#"%og\0$8cž²™ÝÎ~ïVÍÖIƒŒ(‹è„E(™²ˆ(b”‹”éVåúÀLÌ ÎÅÎ5\E¹VuÑ6úú4h×ÊîàÂ"Nxävì·ióç”\ ‘Âq}ÃØn”•œÕ'$ TÚUi)Û*wkZ ð;[ÎjÛkìR+¡líÂβeªiÀŒDÁùÊ®Øc›ƒsÁ†p÷äta‚b&ýŸ5FR²Øq½Ñó ‚° ñ<$I!¨YlöÙLxjMü¨öu™n,Ñéøf’¥2Ú½­,ó:}P–’í›ÖÆ;Uo‹¦úÓ£EGòuÅûë4ëj¿qjÜ)«F£ZKP?w›"+ÚÍ“¥e°îB“ÕÅ®µ¡R ˆÆÑØ"ûƺÛK·iÓºu$‘[b™ÃÅk^aˆ'Üô(.¼ÈNè„![â$™‡L" zšmÎ/'’¢‚h @`œÎQ˘L†r9‘¡žIùVµÙ[s)”UåêðpÈ8ÄD¿xzÇttüÈD´d¢Ãã—6³p«Uºß8G€&:6ï÷u—ªØE+zÖ<4ó‚¿_¶Ï€ëy.c¡‡´~[ïKk%g«]‘*B1@¬àòeM:®cUFÆ¢X Â"6ÖeÚ\ƒh ‹üÈZÇÁÇÄ9ããà»],ìÖÓËÛÏ.Ÿñ@# Êë µÜ7ÞCA“8€:Ä&òcñ(¢Ô<]Kq Cqü¿'~A¸…ÚÔ³µÊþÔ© ‹G¢+ÂñòßU©—ë2Ïi›G üM>) ùc„]9¾TH4ÚóèÅÞ_Y_Iç²|[”EÓB¾Tµ%ݨ•rÅ*sAó)-÷€ýÇæ Q‚hùÊóLÔx¦QÔœ~YþöùfBæ8\ÎËVÕ¥r{ûÔ´jÛØÉ{($UÝûm,GŒGÔ‰áQ"d×ag1tLÖ® íꢴÀÀ‘¤Âl¸®iíÀ²ÐPÈÕDzlQûëˆÚûvÔWS˜§ÖPéÊÐUü<½Û8æUUo§ ‹½A›†OeµkŠæ^@XxÀ r@‹%§Ð…À©éª^Á¡ ‚t;®g d®"ø0Œtu1÷Iè­3LžuLg‹Û÷7ç×ËóÏW…xQÏi4r³¤pwU¸š¾ÖûZÓªŽ\­ì7}ÑÕ}OÙ»=}ÝûÈv&^)(D·ò…—ϸì›G=q-§ž$Aº‡> Šb–nt¤×GÍ¥&L6—$¢+Ék] G‹Þ^kUº3Öiy?©Ð6Í•%ë†Jó'^dv¢ ØøK ¬Ð=d1›Ö2¤”"!d×ÇÚwUÙìw9\p É©î{IßðhĹŒt©Ô"€ÌFݬ2ßÜÒTª;c=Jó¼°M†žiôÔß\mÔ€ºr¼C xL4º£oIczñ®(ÓÚé£C!m 8t³©‹òÞ.¹0Ï]kûhäûWi»d˜ÛãÃt=²éq=OÔ»ôñ $ëÛ~ªTm‹f(ÕôÈ^hºj=Wê6®÷m^=:y¦Á7«Óf­_ELïž,͵-o !ø_#!‹Ý›Wz€Ô3“ ±MÈâûâÁ`P:ßè‰÷ÃÙÕ`ÄHs$xÄŽlŠx¼tZŽ¢eaXá¦(•O…û¢4@žEëÖ¡†sHrý±„ªî ÏõGweérª§doÌ RŒá6¹TJŽPÅpšg¶NŒ ÷¼s³ˆ»¨ü?zÝ©ÿؘ@ú±‰F wFú×ÿ¿õÿ6ò±$¡ÓÁÌ@…XxÍõŒ’‡Èèø‘ìþÃ;¾Õ?SÓCÿendstream endobj 2947 0 obj << /Type /Page /Contents 2948 0 R /Resources 2946 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2926 0 R >> endobj 2949 0 obj << /D [2947 0 R /XYZ 56.6929 794.5015 null] >> endobj 2950 0 obj << /D [2947 0 R /XYZ 56.6929 688.8814 null] >> endobj 2951 0 obj << /D [2947 0 R /XYZ 56.6929 580.117 null] >> endobj 2952 0 obj << /D [2947 0 R /XYZ 56.6929 502.4221 null] >> endobj 982 0 obj << /D [2947 0 R /XYZ 56.6929 461.5895 null] >> endobj 2953 0 obj << /D [2947 0 R /XYZ 56.6929 424.1905 null] >> endobj 2954 0 obj << /D [2947 0 R /XYZ 56.6929 391.3558 null] >> endobj 2955 0 obj << /D [2947 0 R /XYZ 56.6929 322.6942 null] >> endobj 2956 0 obj << /D [2947 0 R /XYZ 56.6929 259.9194 null] >> endobj 2957 0 obj << /D [2947 0 R /XYZ 56.6929 84.2201 null] >> endobj 2946 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F49 1358 0 R /F40 1265 0 R /F54 1433 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2960 0 obj << /Length 1368 /Filter /FlateDecode >> stream xÚ­X[s›F~ׯàQž ۽’7GR§Ž¢ZJ§3¶¨X[Œ¹¨ìh¦?¾vÁ€W·îxÆ–÷ç|ç²Ãq¤@˜ÜñŽ&ÂÙ¦ìÜóObtÜVÉík}ØL~ùȤ À£ž³¹ëaI„¥$Î&ºžž¯V‹åüâ3— <] 3W`<ýz¾ü~~©×VgžZ¬Ï\âsL@‰ÈZÏÃÓåù×Åܽºš}^Ì~]\Ýn¾L›Î²¾õ³Ú¬¿&׷؉À‰/ŒX …ó7‘  N:á‚!ÁkW’Ézò[Ø{Ú¼jcC0‰„¤¾…JBP ð!ä1Ê4ß7Ÿ¿5Ž€:í±‡—JD8ÖzY©™*5GëcQª´Ð7³<+òCW©]9bÜ£‡ûà„/œšL éY˜ªÈ=¶;µ}P‡úåZ›ùH á7ÚKP±ÛÆ’¾¤V tFä´k,»¡Ô×Ò¹¾Ǭ hy y—!΢ø1Žª0Ñ÷óåZ º*òJo£ú«Û¼¹FÅ3Ï´×P÷c×Ç,ßq1΀A!ÜÈó…5Ö( ‚ƒl- Œ°uFô š<àÔRVŸÂŽtíîn[)×®ÁæÏH„ˆ³ÀƒíkŒüßÇ™ÖìÈ’l¤Õ:È}'U4ë¤M'­nm´ºaX!½óÅzvu±Ú\|[voLjKŽ2ÍoÃt?0‘ñ¥1VL>W‰1ž½HfPk€gÛ0˳:½ô2tØNQˆéÅ^d  _ˆÍÎY~@?ˆTÍ}¦¢&ë$“/pþJ*†¹þ²ò q’ ãÔpІª f•=dùSf Kw~¤áª¦zcÕŒcsÂÌåÏ›kofsÊD«¼³€pHÂ[ŒÍO‰©;¢Õ&ü.÷W¯ã÷½=¶¶IXïLujxã¸7¯˜FÝ$ÔcXªñó4SiÞÅ €ÐXÊøQAG&„L‘õà“0\ ˜ ‡cÅba&Ëõ7Ã>}ò]}œiu(·pà ¢üE˜ð8L-¿}8ñ ¸F·9}o°ÀþÛìèJqÚñ´#dQí£šÜÿ>;¶£q~óâíhìëVeœÄåñù˜î©Oß0ñõN|­ÒÐm=cEÝ´5ï¤KÛÑ sÉÛòL䪥úh€¤ìA‡x¯…¿õÎæÁm2¼=Ú¶§ ÚÍc×»4ܾ¿}Pu°ÔûBmð…biq½¶ÔÛ,;ÀÔQ²=;4_°Å]œØz¤¶äŒŒ]--ØÃ9¸ŒSUwšWCV?…¬¢ýiTøêóý®Ýu¨‡× ­‡X'Q_Dúꧨhy©G(G´mÎ!ø7ó~?0×î£ý“ÁH¿·R¾:KnO}´ƒyõ—¶¥ÎpWÛoþ þí:“ò¹d‡£'†&ÈÒU{JhMD@O?\,çº Á F¸+>öªûUà¥[ÿ->‡endstream endobj 2959 0 obj << /Type /Page /Contents 2960 0 R /Resources 2958 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2926 0 R >> endobj 2961 0 obj << /D [2959 0 R /XYZ 85.0394 794.5015 null] >> endobj 2962 0 obj << /D [2959 0 R /XYZ 85.0394 751.3873 null] >> endobj 986 0 obj << /D [2959 0 R /XYZ 85.0394 707.2228 null] >> endobj 2963 0 obj << /D [2959 0 R /XYZ 85.0394 671.9183 null] >> endobj 2964 0 obj << /D [2959 0 R /XYZ 85.0394 634.0626 null] >> endobj 2965 0 obj << /D [2959 0 R /XYZ 85.0394 560.6059 null] >> endobj 2966 0 obj << /D [2959 0 R /XYZ 85.0394 493.0359 null] >> endobj 2967 0 obj << /D [2959 0 R /XYZ 85.0394 298.039 null] >> endobj 990 0 obj << /D [2959 0 R /XYZ 85.0394 254.542 null] >> endobj 2968 0 obj << /D [2959 0 R /XYZ 85.0394 215.1269 null] >> endobj 2969 0 obj << /D [2959 0 R /XYZ 85.0394 180.7142 null] >> endobj 2970 0 obj << /D [2959 0 R /XYZ 85.0394 107.2575 null] >> endobj 2958 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F54 1433 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2973 0 obj << /Length 3336 /Filter /FlateDecode >> stream xÚ¥ÙrãFîÝ_¡·•+£ž>Ø<öÍ;'Ç+µ›Mò@‰´ÅŠD*"eÇIåßh yH”Ö—ó‹÷_™x’ˆ$ÔádþØ;+2ŽÕdžý<½*—p„œÞ=üx}uÓùÍåLëÀ„Ó«ûû›»ëÛÿÀ³•€ ˜RN?]ÝýxõÁî/=½úxópùëü›‹›yËVŸu% òôûÅÏ¿ÊI7øæB “ÄvòxHôdsX#l`Œ‡¬/.þÕØÛu¯ŽŠBI¡M¨Gd¡ÕD)‘X«°‰6N×7~¸½Ÿß~‡·qïtò“¸°ˆ#©rYï·YÚ䌩{˜F!¼ˆE}93:šîë<ÃUA¶ÝRNßîün84 @"a!¶.ÖOղÆ^à”Ø?øöž1³Œý»&\Š=Ì%lÙ´ì¬1ö¸0FXîþŽÆz=æL¤¬¯]­‡KöXõ‰vªéOسT{ ÊͽŸU3 ²ò†œee=C>ååˆC ‹Ù%8pó 7Œúvˆä]q¡Ÿö;i>îÒ'g}b„#жŌ˜ Åp> Gqä- î‰é " .Ø­UmrŸ½Ž¨ ­'2ì ·ãS”JµµÝì··OÙâý=gý²m>CÊíXv R±`Ðj¸Ó/¨;Œm›“`o@¤«àa³o¨sp>¤ŒQbƒ¡å,×`eÏùX>È*dAcÚßîkW&”} ’ñîu{‰‰÷i—nW¯—J©¶æpJhT>®.ÆŸC:ʈ/¿;(q€*œÏ„•' ­ÅÞu-•©›ªK §Øg’ßÞüDÏyrÄ}ÒâB÷϶]q¡Š3›+—\WÛ>¢É£>t(ã^Þ [ùBìû6ß-r2•šöØ\¥–®±:1˜ù!Kdi›å¯Ÿ‰hº2ޱŸSCd[®| 'ÿl;€Pžp![‡ÆÇÙÓ˜õC hŸ÷°ÁHŸ˜Í+ŽóU9ãf\Jȃf¼î]cÒ"gZròœîºq­<(;¨öëëãß—Ö‚3×Ù#@K)ú[ß²ô#I0ƒÖèDl[GlS &l| {3œY ¡b° ð`(",É÷n€s–ÒZ,w™ìd ™DoôH#$ûR‰”Q|@ò:_ìq¼¡Étq<øŽ½ðÉf—.i$¢±ëz¬vÎ;H4IѾƒÅ¾A%G#¨¶ÛÔýn¹I3^¹ŠÁˆÆ¬ ½èΖU¯ØråÚ5=yÑn ôy¡cT÷`'AdìºïaѽÇrº¿>Ò},ŒLÌy’i„ä@÷FhL”’7€.}ãàÌ€ÆFY~úú2‘óÆõ{Xg®ï±ú骆ž+û1dŸÇb²5‚Œ2çyk±F˜„()¥£!wnŠ¢ã˜'|¸ŽüœŽJÆØ÷q[;hX;Үϵàj¼!ñ¼Ò¡5½²I_ oÁ$ ~¯y©@WÿœJ“”€w 2h¢/¸Ðx­êPùNJµ-rO«<¦B¥¡9 •ï@sP¿Ïà¶'t‡~{°^‚Šw>ZkÀÁ*jÛ‹Ñd(g±²Coc/†°®Ùm½?sÑÓ§ç»Û|Y<ºïÏ5:@¨ø=`8qCH;hs8hsoúïq×G× y&çIz¤’3ãÄ< ù]ñh®"àÏS1øâËHåÇŰ]çnzÛL7¯õp.‚Xm¬‘LG )+ê:H—«ø¼‘ ÕÑÖœ˜Ö±ÑCÑœHôçL@†ç,#ÜòÞˆÄ}XÄ™þ0ÆC ¯2¥ØŽó8dWdЊ¡;`šDÓUYæKߌÜñþ3œÖ~rS ìiyƒFÌ} Ú¡œe#è±Ú» `E9Ö‘h NÚ17\:ˆ ÐT½ßíKã½‡î³Æ™Ò‰\@´5IØ‹–&h£¥aÃy˜ëp«7<7C+¥9~„ ¨&t¬}¿U<Ò‰iÉ”XÈÚ•ìî#i;ˆEh¿þò7WÈÏ+ÿål|„7H(I{s [³mµ.–¯ãÝk»‘ÙÈ] “øKÏ#v­„Å©M Ziú‚œâ[¾Ñ¡$Bn•¼Á¨+µBþ^ÒÖ)}[¦gêwé¤ñ‹Ø´ÎöyIH÷æa'«2¢ÀÎÖ>ÖéÀÚb9¿{³–_çÏùQøMbèM @œeÌ#06piD`¡Ôpö7ùk]==QTvAŽAþ’ËÃ?y@ônäUŸí(ÎæÙi©ËHDIøF:ëc‘ºÇrRß¾)õmµkŽ„®EÄoðå‘Fø|Àæ29àëXæŽÁWìö÷£ÿc†e?ºþìá\ÓîÔ5÷t²ü1ݯ›¡‚ RMA˪óšé!VŒGrz¹?5Ô9G¯éÑéôéÝï œÚ©„3!”öÓuQ3ÃB|‘î€_ÞÞ]ÏÚnIÀãOªøÞáwNGæu‹ .¡­¹ÄæôÄ ‹[5àþ4¤nªŠ_MM& D¨Ú†æÜ‡ -¤Õº Ùœ{C¡‚ð ÷>äl\“Ÿ1‚‰„2n#îüÍ ã©@ëVãc Ù#ÿï¿mëþ†/€".Žõ¸Åð„Ü£öI‰€FÒÌîPÕ‘žª$>vþû¸ã[ýËF%ûendstream endobj 2972 0 obj << /Type /Page /Contents 2973 0 R /Resources 2971 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2977 0 R >> endobj 2974 0 obj << /D [2972 0 R /XYZ 56.6929 794.5015 null] >> endobj 2975 0 obj << /D [2972 0 R /XYZ 56.6929 752.112 null] >> endobj 2976 0 obj << /D [2972 0 R /XYZ 56.6929 410.2539 null] >> endobj 2971 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F64 1485 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2980 0 obj << /Length 3462 /Filter /FlateDecode >> stream xÚÅ]sÛÆñ]¿Bo¥fLøpwø8·Ó¥V2NYµ¥&m’EÔÁ mù×w÷v_„úæþâå·*½4‰e|y¿àJ‘¦áåýò—ÙõÝÝÍíë7?_Íe$f7ÁÕ<böãõíÃõ´vweäìú»›÷0•ZÅ„‹ÅìöýÃÝëë«DÏîo®~»ÿþâæ¾#kHz(ÒôûÅ/¿‰Ë%Üàû (“F—Ÿ`"¡‘—Õ…ŽTi¥ÜÊæâýÅ?:„ƒ]û©:JƒHêøré@Æaêg˜D ˜'ZR™¤c˜ } sPȰù/úòÛX M§*äqXîöE»/‹fÊ’ˆÒ&M/‡çQ×AyÈ“ƒCÃÈ:ᘾûu‚2Ñl{¨ÅžÆõŠ~^ßá ží¯ÂtFD‚(µŽúï–Å*;lZš” Á+†zȾCýâj®D2«·›'>iËh»eÖò˜NûýP4ŒöS¹ÙâELÁ™ Ro&Ф½K•-‹àH¯Xx±‰£â伄‡P§%ÜAY ¿óH8T¡dï³í²®–ÅÇc ‡Aª@vg©ë <ä%©ᘾŸÖÄ|d®ˆfmM¿õ¢ÍÊ-Ž5Ó·-”.2ÜÊ ×üU½+öY[niÚ<5mQÑÇ˺hhu[·4Ø‘´?–Kþ<#é!µ*ŒGÆñè%°ç%BÀ£«ÍU,ƒ4kf‰“;ª÷¨PVYÊ٦ض4\e^ ¶IE— UVUœ4õÁR™ó&ê<þö¼ yÉ¿ЧEÙO–¼³ÝÚÀw3©Lä“þä^(±8I²Ùyù«’|ÜÚ„Œë9]Hóʎ4Q/‘Ñvš¯³}–·hϸJì`H^Ãc6Œ'¯·¨ åU8C ãK‚>ÏZƋʃ+ FvhŠ%­”[Јl9¦¦#”9o™wÝÆzjº}¶ÁI4i oÁR#mÃX(Kg¡œv•Ûe™ƒƒiè¨vµtÎD¬°gÅJ›Íº>lxyÁTâ•m؃ ¶._½kËzKUÙS÷…b¨B³ÒŒU·—õ’g *w(œµe…¾ö”3 “ òŒ3@qfÊ:³Ö®B9–#aõ¡=òd ­9•çIë <´<„(“‚ˆ#MI°øsY*š A4ÊP©ìb ®b .äßefQ¬jç"q^2¨•.àËõ¾µRO„é©èÝI«fJ6Ý0‚üH×›Lm‰^V…böoŽŠ$qK¬d\VdY6Ù¢Óõ@UjöD>e‰pGq¤Ï+Ëê´²tPVYî§GšÞ9¤ò9Ôà xtäݾÜ2Ç['‡MI²•äw`åÍõí5šüXoÞC‚yÿNMòº‡„žvKõÓºnT¥Êø<'ôÃvYì›¶®ùËÅ;¤! }ÀêØÙѶa5=v]Z  0ðàšk!æ­Cí:‡2}-SFÉùèNñ•GÙʆ‹‘f!gÞîr˜ìP Ö PÑ Žu˜€§ŽÃG’®™yY¢£Ê9Q¯1äuµ(·Î >•íº§Õs¸N@_;^ÏïNnF‡}؇Ë@ñ€ðò¶][AMêC¢TÅD)üB ג åM0üJ¢ûÝÝüŒÿpBËŸ)CM J>Dƒ%D ƒ%N(XÂ0¡Ô}ˆ¤úÂ.³ÐHÛ0ŸiCü&JaÑeì6ߌË÷ Y f˜]…`+úzdž×·;!kî-øÛ]¶§„AˆŽ+°Ì š˜=ÜþýöíO·“ƒhìîÅø*J‘ ‡#ƒ T˜¸$ì/ €Ð¢S§}‹,ÿÐl²fíÁ šìT寤y>Œ­ –ʸöc“"HÑÿýAlÍ.Ë :@m þ(:H–[/yPîGZÿŸÉ[Ÿ¨7AE<․*ûå3’õOG&A™è|pBŽ”õ9_Y…d¥}å*›‚º E|ž¼ÊC߈³qÄ4nD Y4$çöÛB_F]¡ÿd»73tó{ð.èé…tŸèAÑ/¹è‡EEÓAŽ#Bª$å¨ • 1ƒŠ“¤t[ÚÒ¤‚t¼X’cA&è³GžlE˜+ZD“Á1̶Gº¦Œ­ç„_jzÀ`Ôô8¥>X£8~F}PgÔÇAYõ9êº?s¤ò9Ê­Ò M’É‘åøú¿YÀå?[ZÂÙ:v-€¤ÙVò‰¾y¢-Ö•ž4F*˜Ä¨¯H‰tƒ:9ÃilôXX)§È@_A²’gFäuðV£dCf$RO…-!“£ [¦P‚þXU±ùÞÆöp@ŸhµO‘p¹®iuCËŒÐÒ ûXùµ´d»0°”Ñ”®óq¬Äl´Ìדg #&¡ÁÛ­kh…JVOàdA ªY‡éGóU±ï ÈR8)Ë8kóõØxz¦‹#¦ òö¸3:•š@žjØv&5„:mR”5©™$Ñ"IÎ逦/&¨çÎZ›Ôº ]#F5¬®Àí~(`‘è°-ÉØŠú˜ ìÃ-S=éulžÐ¥Rд$Ð%µfEƒÁ|C¬i\lózi ˜4ë¬/P´Øë¼lŠE „rÙª€‡”ÒRŸ¢…ý¨¦Þà`Ëvàh%Û<Ö{¨Jª?ãÜV5%Sœ¯ë2wMQH£ÕÄe;ïë)#ìžÇúçÕ2òÉ9Áö¹“ó * é“”CLÀËÐ×}TAbº¬÷«Qa½wŒ,Ž‚$êÞ‹¾YŸD¦ŸC¦&ÈTª¿• {ŸbL4¦X£P>‹Õ&’öIÂc1ðjOÚl§uTw9„‹EôhƒACöÅÄe÷é.1Ïõ” â0TÉ¸á …æL~Øp¸}{ó o¯)7+äg }¢ï‘Ê@Já4ÅyôiÛäÝËT׸”ôÒ¡°Ë˜×‡}öH¥:æâyv ´+ÖÇ^?ë½ÈÀv»Mé 2^ÍèÒûŠ!DÚ$"LÆÞoSÚ'Âİ…?*ûÌ#SA ìä›"ÛÓR[|nQcLÊíy\¤ô)#‚\6%å5°è°pÒÉÌ¡µO¸8(.`g×`¯!ÄŠ’¶ëý˜’Œ¦pr[ïùP÷ÒB””Û¹¯ƒï/®»µxšè0ÎIôìO¬´ÍºØlúÆ`‡,£ˆ1²‚Ì xIÄþæöîáž>ýöí»¯ñþÞ“Q24J¬çrÙ? à³%’¦î ‡ÿŽ7‰‚È8s\•›âTøÅ‹tå¾å8 wv»SêÝd63Å/k0½NâÌ&cxÏYÞÚ—éÐðË4¬Z¤‡œØiNž í[—ìN h}_Ó»œt§74ë*%C*©ìê²*· 0øÀú‘¿Ûö»º±¯íˆÞ`½ÆdCØä¬(©;‰ãîýÃ’ˆ¯ÒÙ!GCo|ªgé€Ü„s~—¶ƒ‰X$Eåë"ÿÀieV]v#ìã!X¤Û^M¶¿#±‡hlû á”hˆ±±ƒ0-K"“qÐ+€CfiíûÏ}·Â<#Vž~¿Œõ¤ßß(Úö»w€í–[íø3·ÃczEŵ’?Í y%ظŒ˜Ÿ)pÀŒP‘pŒÀÕáq^F³`ˆªhù¬m°ëŸs˜úv¨Qƒ¿¨PÓ¿¨`º —£ðÛò¼°}­ ª¶Ÿ2ˆûã ®';lÿ)òÖZaÒŒ»,¸è3Š[ÃM¿¢á΀‘®²rÓ×±ƒ@y5>º&q¯ûI2yûƒM@ß qÛª*ü~ÁôܽÄÙ=ýVý« |죚1Yÿ‚0_Šc<ñO¢eÇ©qoȈd³©?yï±2‘ £²…jÜ^T «[“Ý'rzw’4nðßf ´iÁ6ð€m >M÷ÈFof‰:¶!íRwVA¦ŸPj8Õܪlø1 MG7u19íÜ8ÃkZYl²íºx“¦.]€Z3…ç´Ï–Æí')¡h‰]e`[Gž¬߉º;tö€Ú¦FÍ„Ú,ÏÕaC¢±P.Pº•gb¦}L÷Êëz0ìQ°3ÀaŸb ^c©Zæ<¹}¶ù2~Cî’ .ÉìA¶µù…׺î×ý\Õ5)è=¦™´.{É팪ȶ$Õéó¡»Îª¶*ÿêÔŸª(À¿ßóôD—òüÏ&Øÿ9$dæ*M¥¿Éj ” QÈÀv5# šþÍ›Û×t)„@ÄüNOoA¹¥2ñ\뿳woþendstream endobj 2979 0 obj << /Type /Page /Contents 2980 0 R /Resources 2978 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2977 0 R >> endobj 2981 0 obj << /D [2979 0 R /XYZ 85.0394 794.5015 null] >> endobj 2982 0 obj << /D [2979 0 R /XYZ 85.0394 230.8802 null] >> endobj 2978 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F64 1485 0 R /F22 1037 0 R /F42 1338 0 R /F11 1559 0 R /F54 1433 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2985 0 obj << /Length 3475 /Filter /FlateDecode >> stream xÚÍ[ÝoÜ6÷_á·®,ËOI¼{r‘4Hqus±‹àúAÞ•m¡»’»’øþú›á—Ä]Jë6=Ü!@–"Gäp>~3CÊì”Â?vª2’i®Os-‰¢L®¶'ôôÆÞŸ0G³ôDË1ÕwW'ß~/ŠSMtƳӫ»Ñ\¡EÁN¯Ö׋w„irSÐÅÅåÏßžŸårqõîlɹÙâüãÇwo?ü žb ¤tñãùÅÏçÿ°}Ï4_œ¿wyvsõÃÉ»«ÀÖ˜uFòôûÉõ =]Ã~8¡DèB~† 0;b¼½Ã_=®ÚÕê·B`Zœƒ>#!ü»m*”—ÌWø*×ÙâÇ‹óÑAµZüJ)¯6kÛk`gÿPö¶ßþ¦³½—?ÛN·lk~×vÐnGA„M_ß½ø©Üš~_Ø<úïÚ]jQ’0êwf]%¡ž)µ“?ê—+Ï4ÌKÐ’‹æi{kÝP-Ú&±€œ L¼Æ<3ð(&½u|~¨¬ˆöÖþ„Ë{ÂØŸ°ç¾êm̦'¨p¹øpg»Ð¬ÃV¬æ‹œÐL{æ6Ho«Umtfnzwt±®îʧMoÞ^\Ú†—¦3†¿JÄÓ?uÕšÀ¸Ãʬ`¤PE6¨cªi@ T¸ÑM»*7–r½ÞU]7 ¦‚@–Éy~U‚!¾ JæyÌ‘CSžS‹¦ ìiG»º¹·ƒV=Ðg7™@QŽŒÜÙž@˜€?)Ø¡¦7j2VÖ1]+—a˜¸Ò261¤LZ eâ(œH¦_£ ¤¡(,ãPPºÀ°Y6vaÛu~`mÖ¤‘fõÐvUc{o_lŸÅW\êk›Â¡%ã9Q:‹e1 GÚcÈÊ0G su_· Ç‹í¹­ì/zmÙ*8sc‡awÕnÝØ•ûÖÍo‚·¯ì3²ˆ± ÓL°«i‡!×ãüÛugµo7¡ï ’XÉÙ¶‹ èš]Wß7?À'a‚e„Ê# hf ÂÒøhÆ–Çð@£r¢™Å=ÉÁ‛p ²­~$…î…H—I™¬Ê=¸µ¤·îy[®£_€Äl3‚AJm„1ÆdN NóD(v2vsk/èÑÔiPÒgDCfq¥P8¨cã2ñ¤ÐGÑtÍx–½N$pH5QÂeÌ<ööa]A†²­­.ÓÂÆ8Ó2Ξ¦µ¿Ï¡}[ÆfÛìMå ÉÍc¨¶œ2BÕ^¯›Ç§~Ò]ä,‡¬ÖaÆTÓ.¨ XmJHMsÒmx®ç¹T 6œ‡BÅñaÜǤ““ÙŠáÍ•Q—%Ñ´¹2!ˆÖÊÛ«Ý⡵`¬Ë‹,Ê!_Ÿ;WwI&2’+åñÃE‚¯ï‰SÊG‰qq$¥SÍ(ßSáŠ}¿ñêªÅ\f_ñâ3eó x¢ñ^)oP·D j÷e%6Aco½uÝÆ áwS?›éÊŠP«úb¥‹éoÝû1q5uÈ•_ë¹Ü<%ñ´CHo& Oþx 70åjS•»‰-¹4KCm¾ŸÉƒ6&M@j µ‡:0ÇTÓ&¨pÑß*çs×Ûrõ·ë^Ð;œV€qìªþÀ6 <_€x–µ@•à-²¨m„v#梘Ê4u1[&¦b#ÄTÓëcª!níï­{¾ºüð~‰Ù â¶yÕæ“vâ¤ È bªð>¤‚o RÙÛ „SuZ¶WÆ–õÌ01ã9â×ár["óæ„êHGÙ¼(¢ÂBËhilLT*µ C]Õw{q …ak ’›ûvW÷[ûX» ©êß1M,†×÷D:~2âRC,j¼—åv­&“‘ltäÒ¹òÚˆìw)i8ËöÎЂЪ ÕEHÉÛíÖT&-… ¹†Cï²q\a$MŸÈîE‚h¾MíóÎçºL jF%ÃÃ2É®$R†“¯v—˜ö\d!ž,ûóñDBhå°#`2¢šO…+ÞwP³Ô÷ûë‚ogy&æ×õD‰uÇ[Ôœd JÆhÝŸ;§€÷——Kts§®Öé3T$A5Ö.›¸z¨»øˆê¯"ƒ)|£©l¼B§IY½…Duy\ц…&5­> [×úˆö¢å9"ÃÊf=¡>FAæœòÙ…ÑáÊÑö)¨OXÇK[õIéÄ Õâ—3¥ÖíçÎŽpJ©çíj#7è6©5tŽô.í15ö:½'éÍé]Úƒ ô>ž õ¾ e2¥l¯–™´ (| á‹­eûß1 H&ˆÒfgmbL5m ¹ÙUåÆÕø×¶½o ²?.xıûNtQéÛ›e˜ñ¿Œ„1ó‹ñ9qa\‘’'J¬) ¤)X.ãeí›Ã•¥HeŒsRÐP²&E,¨Ÿ‘ê¯q˜ñp³qBBñLˆC§2 ùÃNÊþÁœ/ ô>s"&üÅt…lÒf ‰ê&ý$8ÔT>ÛÝ*âo… ’Ë"ýê™»“Pâ%ãpö“æwÄÏÄ©úþQXùìû&Þµ%MŸœ °…¬àGʼ1ÕŒ{*Üæõã®ÚU¿ß¸]~Y·Û²v0cÛËTÙÏ©)èå ¦ À”ÎLöòèÈ«/µ9OÅögÈrÝÁ”ã¼?ËZ”7¶=íß )¨óC0©]™KÎõ펩¦µ¨µûòzíÂd¹–óŒªg±vÉ2šÇ¬Mh÷PàxñË•x¼!ƒ™—÷X¯¿REJ_ ú_gMà€kšs½×ZÖôUN¤à:®=ü Y¨!Ðà€ 6mŠBÁÃŽòcª3ðT)'ßíºª?´ÊÍáÕÍÀòqÚjÉòyvU‚ß8¢DsÁb†ÿZ×Û‡ƒÏ¦V!wêäÒöœûÌË#9¼Ù½I]I® £ûõéüñ£¿MÆj2‘h"T.ÿùЖ˜UBÀ”ÙŸ:m·u߇£Ñö=¯núj×T=šü`þ§íLàƒ°²G¾ÁSÍø„§JAãWû„ÐÊϲ¨üîû„È‹¶‰àY¸Q@N*ýmøö©sÚ7h1ç"´ú¿ñüè‹R5ï #¢iÿðD_ï–®ìKBø†|:xÁãèó¸®]Àà˜ó«äq-ZFÁƒekéÔŒ)¯ÚáBçòöÕƒû(ºL„‡{GY·ìj{‘;"éíiôܵ»­K¤ù¨qî¡ÜÙ2ïñÇ\òo“(9–7Ù×:bF$-Ža>°¢½`Âenˆ ÐðíÆ7DÅ„û¸pH»‡mßÖæD…`¾†€^#@ÓSÚ£lƒþOŸð*0SÒbf6—{3V“Ú]ÃÂ/¼i U})W½ýFƒ.¶eo¬@ûƒr­g&1HbÏе;4¿èîµ6y(N†îëç*¥o!ñˆ_å_«p…¥;ûà glBáæ`¿Ö‰Lùæ$’Š çÅ»´\³£Î›Ó;â[|Þ!ê6ö¡v¿îÆÂ|ãÔ¬Ëð%#U_̆Ï&ã‡xeoÏÊ^Ý&:Œ·C¯·ß8sÄ*>*Ø'÷é4þw> ø…&0‹yÀM¾'2€o?oüuö溞¿ï77 ð¿ÐÿÚÁÿÍÁ‘›€jŸ Àö¹¢ÃDa–ð3pçñVÞV›j¸öóõþkê…n(ý“é…‚œáÕµèaíß–ÜiÉc½'Ó Hýòà}SžžÎ“9Ët~ÔyF™X%ØÞÇ7Ð…ßÉ"â ÁB‹n"iü‚%®Þ÷—á0|‘mÛgwú.ݼ@wµy‘} PfA dz2ñÕÐ3¹Dj"‰Ó4|’ôºœÓÏÞ´.êž7õèª(^š޹ ŸU$ÄO‰ä±ø‘ñû¦uƒoüYÂ:N:”¹ôn?û-ÛoìÁ#`Öm½©û—3N¦þÆ*]üÈ„3ÒpyøÕ1ü‰Ä?U(&* =žP(ß}¸xk÷„…4ËœUaJâ=ÄJ:^˜îê?íWsœendstream endobj 2984 0 obj << /Type /Page /Contents 2985 0 R /Resources 2983 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2977 0 R >> endobj 2986 0 obj << /D [2984 0 R /XYZ 56.6929 794.5015 null] >> endobj 2983 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F54 1433 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2989 0 obj << /Length 2102 /Filter /FlateDecode >> stream xÚ­YQoã8~ﯰ/ 0QeI¶å—²ÓÌ »3Eo›ö0;®­4Æ8v'vÚéýú£Dʵ'½Å. T´D“ÔGŠ"`Âá/˜èq™¨Iœ(ò œdÛ >y€µñÌ=Ó¼ÏõóêâòƒÔ“„%‘ˆ&«uO–f\ë`²Ê¿L··Ë›«ë?fsòé’Íæ!çÓÏ‹›ßŸpîv–ˆéâãò…’0‰å‹øôæî÷Û«Å,VÓÕröuõËÅrÕ™Õ7=àÒÚôýâËW>Éa¿\p&NžáƒÀDL¶*”,TRú™òâîâßÀÞª{u j MæÀ̵Ç‹3Âþç± ˜ ’W¼D0†—ç²x}Ù?æik¾"6iž#‘×Û´¨æUº58Ѷ%_²2mâo_i„¤Œ±CÐ$—LŠ$šôM;Ú@Ç5²ÑÛäšÉ€'Ã-,ò¼#’`šâP™g$v³@OMSï‘™þlV»1ǹç¢Ý Õnˆ­y4Yñ'çÂävW—BÕ3Eð„i¥lÀÚ`áqL{ƒ˜%Rhây7"f®DÄAÀ’0ŽÕa<"P &c‘À´³ ‚Y†±$ë—AB²$àÞú#·ùˆŠ’„_Ôù°ës»ŽËjl6õó¡Rp,“:NÎkí¸FÔ°“ºÞ«¢y,Ó/qD¾"Ûï0*ª'¶¦iÒóž´œfuÕÂq(ª\Mˉz} èÅàÿïû¢)ZCʬ·'ŽfûQ†E•™W©€ SBŠaˆ@„´xôSå§=Æ,ˆå‰£ÏuƃžËyÐ`ô =±(Ðê¼ÖŽkDíЃ “$ê½½ eŸ %Ÿ¡û`‚ÜYÒÅtµ)è ?Z×<¥eÇßÖ4_µf‡n¶Ù‡û2­¾!Y•9 µˆç¡|êר=žóæBêlÈ.‘Žâóz;®Å°…`Q¤‡Š{§¥7Ù·äI,Â$bZÆo`Ñç:EÇåò™¹ß?C!™<¯¶ãÑ;Œ;Í4ñPñj–ðé~W!5Μˆ˜ÓHDíQò=®3Hx.kГÙ5Øq„…³^WÜqh†…d1`0T} g„NŽ·Â=Tûíý[!#[Ò½q£ô¹ÎÀṬMS>磅Ïkí¸FÔã‚3•Èd¨·‡Eê“„ÏÌîz°ù©Þn!ý7 Ó¹™ è'ˆê+ç¤:h÷"ªêÒÕ&¯ ³-²ºô¨§˜û^UAküIÍGxЇ ‹ƒ÷†ƒ·»[Ö€ÊvÈUŒ;\þ±ø|û êåã2‚»ÍÈö°r.Ló#Ý>–n?ZÀ~Êúܽï&©8pm  cSaR5xYލVŠAZóµUVïËUÜT°o ͸ì3EÕ˜]‹sˆ ¹)MK¯ŒÔ‹À1¬iOk÷ToIƒ¿©3¥l,!žØ”,süq8ýo]¹ËIGÓ›º-ðÂALÚzЦŠêqO5IQá”I³ Q(¨Hið)%9»´(»ºÅßd°`o2¤šúPyŠÜ¸Å½;VÖÕýòã0´G¬é®×´ñYÓw /ÐY>‹í 'ÓÜÌÝå³…ºr æ›®=Ç>ùÙuMDvŠsu¼³c÷§Ù<‚N±q¯{F7þ Y¼½–öÑcéºÌ7uÓ²·íÂb Àa®ûrF˜çqI:Rœ{¡nb[` Î(ñµÚñéu@1íú¨êef[1+ÚGq/¹@píêèníBöñ43W‘ 9ñT=Mâ¨#³K¢Q0ì‚Ë‹#›¾¾íšY:Ð~=¬Õ 0:±V¤ˆµåËÜ-õC³×6ÂÜÆG6eæÀ7Ã/H¬VôÑáOrr†+œÖ¼ÙàŸŒÌÇÙ™ïÄþ{xz*²oö´ Pü«Q9&ã0,ßß,>/)êê­9òÜß ÒÕ¹N«K„yÑbQbÓ˜iÛ=Ê6ùù¼a—kj7&ûæßè%ä.·Ùf®ÿPÑ‹#×¼y|}ôÇÔž9§É~I‡’™E߯¬TÓk—‹“ðÙh{بK º—nõaºÕÓ5\’X oâAÑ]¾…}ÔÆÏÕôªùu)KÑ †‘xÅ]i8‚- Žþ(*ø¶MÛ¶¬Ù¸8A~êyc¬Ÿµÿp£»<ëšyÝ©ÌÒ m·t]A.‹ÌKÅ’K{Ø@<”[ó¦…»Î^§#žÚÍ[wGtWÃøÛ‡÷H\*¤Èv RU ¶û†–Ð2 ªÄÞÐèbˆÚ9Ü‘GÉ)ŠüÇ9kÍšÆ¾Ðæ@*<†´MZxÞœÜÞÈÎ]”‘-ô¬3,…AfSyäS9Ì^ÝÜÝ-ß#]§CÈ"”!Rö Ú1-]ÝhE8³šáò&}2$ã·»ëï:¿.ÿC*²àƪ‰Ãƒ³ÉlBþ?*â×Tu8 T÷Z'眓k4T2Òßx&«òÒ´Ùå’Kù'¿Zµ: :Ò<>«¾c:Ò?ltÀ€(ýTM÷*²"‡ú®X¿øFxîËöD]vòã“ôŸ¦<Ïi ˆÇáô”î.wûêÒÚ_6pùÃMÀ¾™—C#„‚vÚÚsVt<‡f ?¦*JÚ—¯v4¦=ül2€h‹”5mX·Ö1uxe¥å¼®JâÜÖ¹9õó„´¶Œ6ý¼‹è¿ýÓÅëO4*fRkqê{½bR&7Ê#8IA(b1ýùúæ 7”0è­åüVî*”š…ZÄ#Ûú¹jëendstream endobj 2988 0 obj << /Type /Page /Contents 2989 0 R /Resources 2987 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2977 0 R >> endobj 2990 0 obj << /D [2988 0 R /XYZ 85.0394 794.5015 null] >> endobj 2991 0 obj << /D [2988 0 R /XYZ 85.0394 474.8861 null] >> endobj 2992 0 obj << /D [2988 0 R /XYZ 85.0394 125.4418 null] >> endobj 2987 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F54 1433 0 R /F42 1338 0 R /F49 1358 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2995 0 obj << /Length 2358 /Filter /FlateDecode >> stream xÚíY[oÛ:~ϯðÛ:85Ë«D>¦MÚ“³§i¶v ´}P$ÙjK®%%È¿ß!‡”%[qºhÂÛh8~s£Ù„›¨ˆD†›Il$Q”©Iº9£“¬½?cžfˆf}ª7‹³×b"MË/M¨Öl²È¾L¯§äXÐ駛˷ç3.µ‘Ó‹ÛÛ«›ËëÿÀXQ  J§.n>_üs·ç†O/Þ_ÍÏ¿-þ:»ZtâôEfTXY~œ}ùF'Hþ×%Âh5y„%Ì>ÙœI%ˆ’B„™õÙüì_ÃÞªûtLRi¢¸Œ@‚HjÆõÄHÌÐÄ’jø^OÒŒé)PY=ýÓóõ;&û„ÄÄq¼-Á œ$1š OP&›|„ Ä0*=Ñê%.ä¦bòÇ#VKÁ~Vœ]RfÕf„PDGJ½$P˜|ÏŸ!À©&Œ+6é+úè::ªãû༯!&H‘^È]Rç³H"ó2­²¢\á¨Zbû燋·³— GVN×IwçLOó¤É3œ¸ó YY×y:ÂU^~¥ŠjøÇÈÀ=ŒbF‰2€ÓXëQÀZ ú?ÖNam»+àÞŽð&8¡BÉÓWÒQßÉo"&”Ezx)Þ˜éãÍŽ,Þl»Ç›9¼ÙÎovâÎ/œÀˆÄ&Œ£·2͘ïÇ8yŽI†Þ{~u…нø{þÑköŽBáÔ b!üÓ;ëàž‚IE~>¼Ö˜ëp­¯F*¢´Š=AÇNPÿFv0ú;Ùi©~#;ˆi¿U:%~Aºèˆì'ØÍcÎKdîÜ$€P9K«rÙǤÛ `ŠŽšÀí€1Â÷Íç÷óaP»¸ÏíÙøtqΦóë÷8@wnØ´¨q­,kË,)›µ_¬›ÊÏ#QQbÛ«Ç ûu¾MvÖ«¸ÑWJù:‡å’)lvÀ–M‚’êüG ¾ Çyw`¡¬Ûmæ²i[c`²»Þ;×eØWàå|V¼.îvÉÎG£%Hî:ES‡Àõ´mªÕ.ÙÞ©uÛD/@’W8ž;›$„»û¤\åžUéy·M‹zÁ1ö×9ø¸ºwq’…‹“œp#y—5‚£îÊ, ‡w®¤ŽÉM‚ŽîÖãÕº_9±çb—ëÕùî!÷Je7NÊjmS¬‹æé'P6*«m —w5Ø„ŽÄDp­ P=4H ý“A¾Ïƒ< òÕþèhðËìO¡_HÔC­«v—æ³$Ëvy]{oÐßC i¸+$ÿ8§#œ‡Aךz±š-‹u>Â6R$VB²ýþ"[0ÏçxʘhNãCžõ‹<=Ž9Šˆp.Ù!ÇíÇ™ˆ`C90ÁmµkFcÂ$ÿèzÿîzO#›p—²Ë^ÆeÀW¤Y<±†âF©Ÿ©–8¤DZ×J³Žã¬ÏÒar çœD1Uû­ˆE6¢Æµ"*!­6ëkFsËR0>4ÃË«ùÛO×·‹ë7ÝWÏúüàUS3N“zÝଇ¤Ê9X×éü¢.±M°ñ.zR±œë¢åôºñ -p¨ó,ïq>–šKÊ ª—™i @Ü–gšøí¿ÏôPd.dÁLΰöo®o.1sp(JQ>ÄòЙC ÓÓëåˆðŠBσðÏi\¡ƒÂ1 é¡úBêcÑÜãtY…ÀˆØp“ë¢ô‘µÚº@…Ó.¸A›8iWí&/Ãö ~Ù~Ùxú›úÞ*†ívqÁÒ²[¢FbI¸ QP‚ QaJ»µ†ê>/g}9;òä!)ÖÉÝ:±6È@]ø58 9 AIŸT9œuµ“²-‹ò ØZÄÊ+Üöœ¤"Ž< íTˆ™¶_u½›ÅÛ[¤Ë)ó´) Í©Jк¤1|YbIc)÷ªqŸ·°SÙ8!2=/äy rš«¢Il¨6 S±*“p8HJ1½.‘µ Ti»CвÁ¾€Qþ†íב|Ã’FA¡}¯Õ³RCt¯xÎFØJŒéü ÃjÄ— GÌ9åef <ë¼áFDÚÜc€Ód½ªv ÂU;5Oöb©î—vɦÙ.A´KpY[`~ç‘׬ïdýÌêŠYÝ<9[×üðÒ &äÐÁ;‡ÎÞÑéP@=P7¸êWzô>îhÞ™)žx¼ylmUam„ÊéÅz=<ë\ÂÞoÕh0ÖAuÙrçÂlò_æ>eÞ´µ§¼ ,óð,Ù?—%Ì”DTボtâW“•ÀpÖçxü #`U™¨·±ÏUPвzôeMS¿ÞmH"b¨}Tù·lbB†íßtð0<)WÚúqÕvɬùŠÒ „bšåM¾Û`h„éûêçqÝ1j’´ñ“÷ž,”F¢WñŠ,ÓýGL-ìrð*Þõøc L£‹fÝ#iá‘·]ûÅÖóåzë£ËñæÏ=›2“z§+ª>"‚TT•Ý7”QQ?Ï1µQÏ—Q} ™‚hKyZÄŽjDÆAÞ§bÂ•Š‡B~®ó‘BS"e¤N{Ö:†¤¬{JJ\”f!àî{ Ï4ÇË‹§ÄÈóð ë¹NÏ«: 8°$k1Uµ–C }€Ql×ÝsCÝ$eš×ýüȯm-þ›. ¦›¬×h Öx›æèMÿ®r)FßȯoäARS‘gÒÓ…#ÙëÂ?uŒaÊ^Á_@èžæy|z‡Ît ÒUöL)>€¦°åZlNIÖщ6€%˜j¤Àôd¥-\"jž{'p€iË"™ïr#¿Èö/m®o‘Þøž.öŸg¹K>^U蔳 åë¼I_[N¬¼c¦3x'!Ïýx)±¿8ލ™vžï—ØÜÿp+­Ak>~c2¹‡S[:<³[ûÄâ`±œòcT[˜Á¡Oõ_¬[jÐendstream endobj 2994 0 obj << /Type /Page /Contents 2995 0 R /Resources 2993 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2977 0 R >> endobj 2996 0 obj << /D [2994 0 R /XYZ 56.6929 794.5015 null] >> endobj 2997 0 obj << /D [2994 0 R /XYZ 56.6929 665.948 null] >> endobj 2998 0 obj << /D [2994 0 R /XYZ 56.6929 591.0187 null] >> endobj 994 0 obj << /D [2994 0 R /XYZ 56.6929 540.1525 null] >> endobj 1441 0 obj << /D [2994 0 R /XYZ 56.6929 507.1552 null] >> endobj 2999 0 obj << /D [2994 0 R /XYZ 56.6929 471.6066 null] >> endobj 3000 0 obj << /D [2994 0 R /XYZ 56.6929 405.7105 null] >> endobj 3001 0 obj << /D [2994 0 R /XYZ 56.6929 333.746 null] >> endobj 3002 0 obj << /D [2994 0 R /XYZ 56.6929 138.0509 null] >> endobj 2993 0 obj << /Font << /F38 1122 0 R /F49 1358 0 R /F14 1060 0 R /F22 1037 0 R /F21 1034 0 R /F40 1265 0 R /F42 1338 0 R /F54 1433 0 R /F64 1485 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3005 0 obj << /Length 3331 /Filter /FlateDecode >> stream xÚÕZ[ÛÆ~ß_!¬¬ñÜI:OŽíÇ©×MÇ”HI¬)R)¯7Eÿ{Ï™¯Úu“ @¡gçr®ß9#¶ ðc‹X*¹ˆIej±9\ÑÅƾ»bŽfå‰V}ªon®ž|+âEBÍõâfÛ›+&4ŽÙâ&{¿|öæÍË×/^ýãzÅ]¾$×+Eéò‡g¯ß=û«í{sðå³ï^¾…W'ˆ8E:M—{ýâùõ‡›ï¯^Þ„íô·Ì¨À½üzõþ]d°óï¯(I¬·ðB K¾8\I%ˆ’BøžòêíÕOaÂÞ¨ùtŽRÅDq©+,P*šg%TÁÁW‘¶À7QœÍ1ÊS!£Vñ O¾Õ²Gɉ;3$ó»Õ¶(ó1G˜”$Rª7áÜæÕÌîxM™Hèh¸½wMn÷§û‹II>³¿Ñ¤ 8#£Ä¦ ÈšËe»Ï±!ðKÛó ¥¼tEÕ´yšÙzk;Ý'r™åÛô\¶íbrpV̓حö$o7ONU¶!¸ÌtoQD"kG š'([ÞøuÜÖp;3Kêˆ$Òý•j±M"‘Œcà;#‰RÜܳ àz3¿çÛ¢,aY-×¹}ž›<³­¶¶Ïô ̨Úb“¶†F/7õáVYcÇ~a™g†NŸò“mÛnp*aqDÌmkSWÛbwIÈ:" “ÊÑfuî6RÕ­g #RGÂ3źˆüsÑ´dbæÎ–t,Å"¹ßàúT— .Pƒkæ Ž.˜?‚cÓØÜ#LhyÿÖÕtoCš0EÃÍu+x,@µe°¸9œ$N°Ð¨ÒƒkÕ'ûL³ìtÍâeÞ8ZcIýo‚2@ûv_lö¶yHÛÍ>w¥SÒ¦½;XƒW0á´ +++v ìg*šZúî|JÛ¢†/Ẽ틘-·µ?ü@ŽŒ€_¢Á”fø¡CF¢³åˆªå«­´ªíBþ؇4}çã±,ÐÄðÍn‰ÙÃ`‡³,Û[Uþøz%™òl¹¯›Ö’¢áúÎv9ÓPN˜é¿ód«À\Š›2ƒ·mÃYxZÎB£>"ÓûÒŽm;â)¹€'Å,äÐQgòCQáìÁMCÛ¹*h­]ºªËöÌQƒùæÜÝcÍŽÈóñÁèy¬OíÄ”A]bðX÷mÊÓL75ˆ9\AÌÑÃ]½ÍQeŒ<;ό©íóæùÛð{ûž±xt‚±¼4‘Ô{è.hö”á›W¯_ØVòÈmÁ)ß]Õ'Q;InöiUåe·¹Çîsˆw—«’€•÷K¶OuY´ÊÈö×ñ’€ü¤”,é‰f–ìs/Iˆäj´äOç"w¼9ÔYþ̘jšîœ’·ùgGaÝk{>U¹ã;ÚýÀbû¦ÝÙ ÆÅáOEÕúIòÏ›üèn!Ї)ízÎ78q¦n8?Y9ž®#¹¼,*ðÈJÅñ¢êQÝ#*OeDõ÷‰¨ ºQˆn÷.é‰f–ØeX$Ã%_VéÚ»"àñºön³¬w»¢Ú]f‚W¢̦5«0ãô£­n£zxˆ"›úʄĚñû¨f87¥è&ÕpÕwFxš;ËFËÇIï§ã½rÍÔŸÇK?áôTC´ øQƒFÌñr’fb°GØZ«=Œ?½ÚÃ$2.]p_æ‹Ð¥ØŸ¨daÆ8#4„EöÅ|ñáìpFX…Ç^{…¨ê[ljõÝF¥Gn¿·`lF ×!Ûj÷ëCª’(͆ µ±ðZ©eZîê|vp¯6Ð+ðôÜ{ >}gÛÈIôÎ@‘Ù€  Ö5QVËCpÔòSZYÀ`ÊXá¼Ùä¸V‚[¬‹½€u§ "E˜æ÷ŽâÀƒ¿æ ?ûÃú&\õfœª‡£y¤Âºõ`7Æh‹}mp<…H{Ì7šHž=žÑ….1Èý¥lã5ÎÓž ̧^ê¶T`ä‡]©}˜Š6<ˆÇ6ÊŸ6a€¯BB_¶õhé€v}Â)g?¶êŵj«M¥Íð£æ½ËâÔ0‹“.¡T€Dlά’&˜ñ¤® SžÇ¸;­l§KÿB}feë'ðaHiWÍITGÝ¥4~O6w¤ÃáF éåëÚT=hâwDc7Mf'Œ†¤Å´ia„‘fŸÚófv´3bGàÓbKü‚~W”ÁMÔn* ù‘°WžÉ†‡a>³¡îÙ$Á¥ôE6Ä¢ÑW6ûú\f#t¸­û(1Í}úÉuíò*?¥eÁ†¬ÁUðoŽ:Ó4$T Ø#—ˆ4&%Iù9žíù?üðìõ‹·3Ö\àQ ŒÝˆZ+šQ;äæç‡ôöÔ¸V©Šþ«ôÖ#çu`²‡ÚÅŸ®AÐU…f7³&E(*›_´&†›úìŽkõiwFÕ¶^ 3 > ø:m“’çg î°¼›åÊeNSŸ^Àœ¡`ɸOeü¶Lfp 2åÝ,û­®ò,# Ôó¡#̉2}?3E EWð+M33`¢•úÒi>ùíÜf¯PÛ?|˜ƒöŸE@]¶DêÏ ,‡éîå} š2b œS¦‡Ü–aõ‰ÛpÃeÓ/fêkÌUé°/„n“I|v ×0Ðq³/®!bYåäVUJ=sW ‹´ó'¿ž Elï|IŠQœ.°/-ËúvUå·+Üw3cK1#œ±ÙÀá¨íMYDXånÃÀT²qD¤ IÄÝìZV´QWNÔqb®f å ‰¢ø¢L!Uäw ѰWRð‰Õ{°Ù %s!;:@/V(m·‘iŸÎ©tM‚$Û²†i™°Š„·6À˜e-t-ªôT Âáµ›ùX¦›Üm`ö²dÌ 6'È©¹ #d§Jç o|çÀ-Ú›š(œ4µ÷¡ß`x6üØ2s½n+Û +àD „>k]wArÒ¹¦}ÚìgŽ9t¤úm;1{DX^‹%–y\ØžÁîŠÈD³ÉÒãR ŽÔàv ;âætwlëÝ)=š±#f3hð®íjö¯z£dte ŒÉ3ºŒUø‹<ì¶`E¸ ;ìqCÒ:Ø„£)!—?#dœq€d5•ñCùD]®¥¬ãRÎï|ĈÐTŠnýp½„ÓCïÚõ”ušÙ³®Œ'é6¯BtÆ0Nbp¡,×·%W.mjËRí­SuÞJz=C<÷àä°/¤tÛúZbÚÇoæÜ$ Mc"Ê™ˆ¯B{,çܰR 9Ô{ÕA^S‚÷AÂÓ1Çèphše£ h/ÖË@à…cáÓõü³Ù8…ÃÜýb P+”Úz´Ä ¤{:³ `+ ©ñ¯='ò—™1€Ø­4¥7楿aÓñè_öÙÞÉ!m@^_ÛssjZ_õ>%Ùú+Gðï¯Í%½n/ƒ=ÿBuYPŸ ëSºùh3SÎ<®=«M]ú+‹ës5+)-0½úÁA`i6T4é.<¼—M=£e mž„‹yËS+ºò‚¾i”<ñ~O3ã3"T$&³êKZŒ7’BEýè2‡™–DêDßûT—r ²W~e§CïW›2O«YhIÑ,NþÏóS¼bçò~æª)w‡qÐ#'2dÌ[÷ÿÔ>œVséQ0÷îûBE„»<(Ë-?V&í‚ï4Eí‡ h¼»è‡ƒK¾½>;ÀN¥Ïßz¾þS‘Ω60§žèöe Œ`Ir)½Í k²ñͲ¼÷ë.ð|¨\ñÈõ˜*#ïÝ2$q‡B¬vÏÿ•*­û`… xУ½”¬gzäȬWµíîOCÔ8Eëó Ëùg}>U¦È¨Üœ…;@ZÝ_f^ÜÍwÜâ}n!-øÎ§l÷î¿ €Öða’ÛVëÌ_Þøòçk¬»ÄÇæy‡¯T¤¾€y%Dƒ, ó§±/¶”Ž­µ6s[Ä.—磼³Ï=pÑmyjþCÁäðh¶U¸ê­SIáx%0à‰ ˆÈû_ÀºšÀ86°+²%'?Ôž×øDI ‚cþ0øA•çæ¤V îN\;ÁEÝѰ†^¾™µÍPBAŨ܄~Y×ÑÔjp›ÛN#§¶*iL˜ãâ2¦tn`ô·K1d+µÒCŒÕÅÜ•ÿ¡7ú½ŽäyC=‰à?2gB ÅÇ?üÇÏî­2""Ž/•Y¨$B$Ìo 7Ω¸^1Å#Þÿsa°‰Õ9¹U‰©˜G3Çú¬Æµendstream endobj 3004 0 obj << /Type /Page /Contents 3005 0 R /Resources 3003 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 2977 0 R >> endobj 3006 0 obj << /D [3004 0 R /XYZ 85.0394 794.5015 null] >> endobj 3007 0 obj << /D [3004 0 R /XYZ 85.0394 425.1186 null] >> endobj 3003 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F64 1485 0 R /F22 1037 0 R /F54 1433 0 R /F42 1338 0 R /F49 1358 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3010 0 obj << /Length 3310 /Filter /FlateDecode >> stream xÚÝZÝoã6Ï_á·:Àš?$Џ§m7[lﺷMR ÅÞ>Èm«•%×’“MÑ?þf8¤,Ù²]´÷ÒCàhD ‡äp>~‰O"øã“8a‰f¢bqÄãÉbsMVðì›îyfiÖçúêñæË·2f‘L—=Y)‹Ò”OóÓ;&"v "¢éýû7_ß΄Jš¾þðáîý›w?Â}pDÑô»×ïxý/jûpkÄôõ7w·Ÿ¿½¹{ì¦ÓŸ2$Îå×›Ÿ¢I3ÿö&bÒ¤ñän"Ɠ͊%‹•”¡¥¼y¸ù¾Ø{꺎©@Å)‹…J&3©X ã+Š3Í90騰D Ù)J™1E.TT¾ßlóùí,=|œeeùûl‘-Öö÷Ùouÿ³|þûlžåŸ< ªåË·‰êÉB3®R“A‰O…}&fƱ¦¡4KE¤=÷§c=K©avFMú‹9YrÇuºf!zƒI%X‚£ ý};ã&š¶kKDcwOvw;ÓjúECMNžþOG¹]fû²’ScVå_Ö;\Àd&Î"Áajœ3Ç „: "I¦mí¯8"¹›„Hb‰Ò·.Aà¯ÙÚE,6§Tp¦+c=}·¤¶ª><#ªhNº¿Â3…Mî "2ÛÝòtÚ›™ÍÝ©[ùƒµn•Ñpu8E·¿‚÷TÎ&£4ñû‹²f~Ä+†¶ 9l ñÖÛ¶¨+òÃÂ_I @|õîý¢ ]^盢*šv—µNgÐto—–R-|·ï²jŸ•ÌmÚ±G{·ÑQÌ”HÓ+¾Õãºà[ ׳,÷ÍúxÔ4aq¥—G L§£Ôg8‹hŒúGuV×Wß‘}c“³ovN+‰Ž—qrY+}®óZé¸:­TÙÆŽ„èË0ÞL S÷¼gǃŽ »¢Ÿ3Dg%¯ŽÜY‹óŒnºƒ`|C{¾n±‰E€5\´À>×y 츜‚ñýfÏc¬!hBX1‚¬„Á4Ì0fFëšeº:#c€šqüGŬy8gÍ!µútbÏB(%±¼¬ÔŽëT«{°øH%ÉP­{€?nãÁ2ö[0 oáÆÁ1¸ftÉ_À²‹Ý zýÀ^8|MU}xDTáá+£Ud»¶M)¬—Ž&ä.qÀ!’ü›†&íX"ôôq]¶²¬Ÿ=½qÀ†h›“ËÅ3ñ:wÂb`ËíðIv¨ªÞm@ò Ý‘–r/åe ÷uÊ’"hOR*ž¾k©1+›š¨E¶oÜ*¤¤uV­è&u¯€ø¹Þï*·"‘v»µ^ÔÜ36/€îò %<õr ¬¸iÑ›büä^ƒâ/­ÝŸVã#FÛÚͶõáä¹p°ã†N{¶„õù8ò¼.J{d¼Á ¢õ‚| üÍV¬›Nʤ$ô†P›FGž& 8÷cB ØUù" ˜=ì˜%ªãçãZ”ÀN\ɬ}® q-páˆë¬lÃár{šÒxÄ”áâòø×é†) Ö"Îà¡­ñ˜‡Ú#ñ‹Í¼öìŸs*š)J÷va«–X:³Å¾äO$Ž6r¿ZSÃÁà¦3$èSû±Þýøöž¨àï.JHÉRu޾UV5ºR“Ížœ±GŠšÈÔ#y0u ÉÔ]¢åz:ßûîd¶Ø{î;Ѭ˒¤JÓ|ü0½$ÝìàŸ‡Ñ¨ÃóÚÁƒ>sP1>.š1·óɺÍv-E:é¢-%’þ¶Æ)¬eW³íˆ•ÃÆÇ‘ VNÑRΧŽK82©¤‡ëòÉ2bÆÈàn_xÉ[ÒÐÂa l(|¼ CÓâZPX·¶Åu/Š]ÑÕ~†¬B¡Ä4ȇ %·ÐÎÂ6D!J?Gë¼§%¯¬´’ªµ×!-êͶ´mtèÕEµb~RQÊ„âOıô$Ž5è®#qL€äÈ\‹cJpˆw×­}®óq¬ãÂË:˱/Í’L›Tþ¡ÙYdvQdv¢Ïqd6Pè[Û.0nB| z€ùî¾&Ú)ÛQT‹Bü"‘ôéuµ¼ ‡ˆ¼ §\´õ.„ú1FÑ qŸ”® ‡¸HêDƒæç¢];#Ý)¦ØQóv?/‹EFU,|¶µ»¢F\ˆ•´ Õ¦V¶½!.b¤/ú!ërуZþy÷µßß7¶E<££éUYü2v†ñœKjˆÊŪs.ÉâXã„Ù*Ð׺~¶ÂáLæZBp1:åB\)[aÃ-Ÿö2ªk#ÅÍpp—s iîu"+,["ûîÇ£ÖÅÎ "„Ä0ùÁöÕ‚FÝ@'l{@ln&¾ÑûÚbcÇð˜Û‘Á¸¡3/ܤ_÷Þ¨< €°6P£¥Q„cQrY¶oëY^5]Œì Ä!­:Wö:Ñ¡JŠôÜ·Qøqë‘ j¦ H{Ixoá7^Ží2Ñl…švkö ~lõ„cV-c1V5JÂãP פá~QW˜¦W{— ænשÃaA;¸#*”¨éâÒ›Ÿžþ<üPƒ¶A&_&¯åvMeåÙ±p+þP­Ù£üÀ·©»Ò:%,¨¾lºzôŸBÿ§Ys˜ž{š`°ïºœÍœ€J™‰¢+™³Ïu>sv\ÈË—±’g€4øÿSÞä‚Áa…_VfÇuªÍaÞäšE†«¡:ïmcC%ëý¿ß½ýÉ›`ÅlÊþõ Ρç7?Q—t|eó{\6?pùÍße {<®IY,¯ ëyNG"ÿÂ?×r8ìƒmÿÀûÜÎ÷«àXïCî¼óºÐ×ÈC.†ëôâªBŽc¯b±WOê‚£¥&WNê}® [¸pÄ_÷v÷RÖ«±£RÄ$çÁî?Ö>up5HmÌ(õç±ò6Ó‰Õíz‰AqyZ€¨À¨øâ:;®Ó…­21®ô®Â·tNF?Ák^4‡F§ "A!+wÒÝÒ[à·¡Ë<[üÒ;8C ž’üÍ‹²h bb •ˆFˆ "ð&óuB°ÝX@x$NJ·ý‚S¯Òø³FxD•m%x¹ßPå¢gÇ-¬"T¦üâ(kôÌ?¼xíêä~‹Î¥ªïƒ>”³ éðnþ¼›¿uŠÏ}£ïl?o1'·£pºÉÏ€)‘@~2x ®« ø‡ïµZ»Bœêg:CU!´~ŠÙZKY’ÈÀ‰U Ê–cg攩DË.ªK“F`Ëy°ÕA#²5@*ÖØ VÜFiŽûs õ Š˜$ÑýS>xµ‚)V—0´ß-¨x²|9ÌjPK€D(£¾æ]äp^lós0Dˆ¾’ôÙṎ¯ÞmÆ•q™þ%åxèj :i.†€ïŒâ†ïéÎFj.9(Ø\AT}®ó‘ºãr¹ÄâÄŠÕIìŒ ŒpyeäŽëtè£Ìj˜2êhì{‹P_û×wBõñ»?úâÓî£|CXù.¡sB>lroA^íN|Hä5]ݹ Š ‡îö3 q ^FÔ†nìSx•šXáù%~ÆÎøH­³'÷9ö5_¬Ý #ü!9Âué+¯ÔCRu^îËr,žÍtç5;ZÍhÉQËÎJ©¶ê§N‡™h3™–YW\ÀÛj¿™‡ùÕ~þ}vš[÷^Æ+G@Sâ¨R„ìòTù1šªlÈD!ÅØÏÙ¡ÙñmêÜU`CM$œ´›.Åœ¢TÿÌïäY÷Ò€¯4¥/´s`ºðÍŽgò¾µß5>꾪¸4îáMÅñÀã/*ú#Ó7iB¿¢'Ê)Jê.ÉW„©Ù˜ëõ]+Õ«”£XX³?ÊR–Áá‚2hÕ«î{’«3õïý=_M×çu±Xûª›ŽYœpº$8˜Ê“« E‡œ.ñ³µ®OŽfŒMsëfŠ$‘°H–@/„lkÚ!Tå$ަŒ­Eµ(÷¹F{[D†àBØè¾l€ë«–sAõŠÙ¹/EáЉŸwŽ ü¼§ýå¯H_Éâ·ti*ÆMîhN¨ëÞu ìVÎ>(1&©S·‹˜‰YÕ ¶Í¾endstream endobj 3009 0 obj << /Type /Page /Contents 3010 0 R /Resources 3008 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 3012 0 R >> endobj 3011 0 obj << /D [3009 0 R /XYZ 56.6929 794.5015 null] >> endobj 3008 0 obj << /Font << /F38 1122 0 R /F49 1358 0 R /F64 1485 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R /F14 1060 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3015 0 obj << /Length 3682 /Filter /FlateDecode >> stream xÚÝZÝsÛ6÷_á·Ò3ŠoíSÚ$½ôÚL.vgî¦ÉÌÑ"mq*‘ªHÅõÍýñ·‹ R¢ìvî-ÉxK`±Øß.(.9ü—…a\9}™;Í ær¹¹à—÷0öÃ…4‹H´S}wsñõU\:欴—7w£¹ Æ‹B\ÞT¿f/ß¿ýîÕÛ^-¤áÙkvµ0œg?¿|÷ËËŸ¨ïý•“ÙË^_ã.œ"É‘ÎòìûWß_}ºùñâõMbg̲à yùýâ×Oü²Î¼àL¹Â\>ÀgÂ9y¹¹ÐF1£•Š=ë‹ë‹¤ G£þÕ9U0SÈ|FRŽd 8´µ½ÌcVIåe°»EV·Ãúñj¡„ÉÊåÐ|®±m³»nGÃ*ôÜÃXK}U·)›ö<(™•mE½«î›²}¤wV%Íg²Ûš^¶Ù¶ìû:¼©<+ÝvKÈ—å¾ïvwÔ‰¬€Ð¿~£Ç[ã— !˜3FúMÝÕÃrU÷‹m½[ü§kÃa€%áE¤ï¶CÓµì#7âäD9ãô%9ËL1«„h1¦ò ÝœF*õÝ®îWÄ¢Õ#r³Bò<ðxØÇdNéXQä.ý:3a.Ïm X®Aò3Ó(à kÌŸæsS?Ì1£˜Cµ'¢OŸŽ…)µeZég¤™¨NÅ99BiÓ˜žÈóN¾Ú¯k2`/5ßBmê¶l—¡Ãk76¼vc#hw|Ó[ÀzE®žÖ…1Õy]HT¤ ë®¬Ž—àr‡·Ÿ\7Q.<õŽº°rºòZÙï}Ùµ9—÷û]‰fAØ…ê­=J©?/& ¬¥~FL#ª'Ä©¦b:¶DJ|QÙ6Ö>-ÌDu*Í©Åh–{Ÿˆs|öÝ$ÌäróÌ!¨ž8äHE‡<ìʶ¿«w3¢µ†åFé/é ­fÊZ÷´@Õ©D§mSºS‘~8ˆôìa÷k®§¾óŽBóæèµMÙq®¾Þ}†v®3¯*àeh\-À;;àÁ³ðÃ8WQ@ƒÁVÓÓop?W"äÑIÞéè1t1ök`ü2çEpÓ®›¶^ôÍ}Û´÷3$™+£ë‹ºðkà{q]ØWïý >tÓ È™ TM¿,=çU]}‹ \æÝPÃŽv$É-ãNe‚ZH®VL6:++üº8–ˆömäŸH‹Œ`ç²Ûl×õP¿ÀG_Ù™eöЬ×Dr;aå¾nkñ‡fXQ«zÜQÂ_¬[0Ò X©Â1žÆ€< œË“NdLuÞ‰$*d¢= §¼ úøäª‰êtÙi8`ØJL—½ÆeáÜ‹ &*ÏÖM?P—× ø-?—Ít¢¼Z€¼¡±®i ­‡‡n÷= hÙݕ˺§y“ÃÀrU¶÷uŠ ÉÈC «nä ”T}Z,¼½§;²•¦ }Ü®Ž`ÆnxUg#i4Z Ç@!¦ ýP6ƒçàn²`sNV'ë »^øÖçr=ÃI!·&ºÔ¡ÙŒüϬ– HÊŒ|&T©žÐ²H嵬^îºn€²?ÎFÇòÜãáic3±b üOB…€ÜÅ ežÞP¢:ÝÑ4TpÈ0.¦[zµßlḜ^Ã%¿ÕÓl|¿k†Gz¢ áåà_ìè½0§>"I ÒEý8,ôÛzÙ ‰÷;ÐrëCxqŠY]S…Ãè‚*ÖvôK‚Æ–w‰ès¾ˆ+ížÆ Ž•¶ôŽ1LÉLJXXÀêê¬îé\2ù¬î©Îë^¢òºvFá¦Øç‹H²ÀÚ†~Z”‰êT–S­WŠi¬™L„ùëxž6¸É^½»¾~ý=uþV?öÔ Šƒª± ep²àd#­Áy¨§jH‡–C· ]¹á}]R1ˆRN€Â ²L9K,`ö0ó üýg&dÀï¥ßÀm‘}÷öÝ+êrôó²‚Àñ ‰Á´D¤âKIËðÚÏe»/×XSa|È:ýÄD2² çQÅhí&D–”Ô˜#Cßîo×Í2¦§Êa¼k:oÒZdb徦1˜lC-&]꣞•wgІ£þûëQûǾqn‰ññK'„aú0…fàfÁíŒ>àìè¥ÊýÐm`wKбc"<[‡\-À°ñT x C÷6°Ä‡â…çãfE(Ñ"JÜPF´Ìïû —}DŽå@ãgTOƒ6i= ²¿¨Ú\ëŒæP¨­Æ®ÉOtÐÚ?MF¢Åu»™ªŸÓ`º:ÆIU÷0X$˜qÀr4‘ 2•è |¥þfæšFfT·<–C,úŒ¾#¥U……䇋éÙÏ÷`g.éAA¡znÃÈ¡"ó!ÿb¬ÈoÜwUm¹i–ôZʨ…>库}”R¿:ÐÙ/Û °= ¾ïÀ®šºG¢Sw0Ñg²Ä_ÀO}¾à(¦nºI­Aæë>a K™càŸ')Ÿ`X&‹k×VK"ÇÚ†÷Û³>ЉôÊÙØ­´e°ÝgÊ}cªó±;QÅØíñ±‡xHÔ\P²€Íÿ†žåº.ç !¦E.^¿©¾.×÷@šÕf&Ì:¸IDë›NïÛ>ð—nÁŒÕ¶Ü•êð|Îp’+¦b<ñäyîæð´x–i½ò‡ùÅ¡õif©\@êþ%Uùr˵Xý´ª%ªS]›½çQJ²ÏÉ÷ü*åëüG›]¨.!nºÏ¡Bª ý„²¥sø0ÏH//Éš«P{¸‹Sª8TW„ÍhˆFõaÚ}?-ytí}·˜ó=5â¶´­©nÝÓ˜ÇS{ë`´ ½£½¨ …2Gê“*‚Þ´=©&QðÔÀotb"«¨Ë;L«âÆu q* éS_Jg„;œ¶ž{N!bt¼[…áSÉÞ·ó0±`En£ÇAÄ"ÙbôÆXŸrÌ “Ë`sÉ;Ó6tp½ Ø!§6“ÅsV(0D:H2‡°Sf«fgJêüX-(2úÒ þ¬öp4CY•·t!¼¼_P³i+'©Z!²‡UC™€H _ŒáªÈ kßb×a¿F’Rá⡞JÙ.„ÊÅïùŒfO°á‹£[—ÄOŠ·6^Cg2ÓÛ:Õ`–AC„1쿚;ߣPL'¬ŠÑŽña¤¦w­X¨É£~Pm¬˜:|.ãœíý:ty‹ oÅc‚M˜ˆŠlø*jáÑ"f¥ár˜Ù”„0†0UÛÓMM³|ª:JCΨ4ÈÊ8Qâ¾÷µ;©©€-}x».©³Ы`O“Ò …Â8ŠÊ‡ß(‘½mi¬†È^ïhxYöu|µõWøR¥²ou˜"ÌÕ»GGþ-ÕéÆ> E[ ™hØÓÄaM­†Ç<5ð( Y•},ÍŠÇz8Ü,Ìbì5擤P¤öš=Ö^„ìϨo1>igG'íò Й9SˆáVÑ BbÒÓ¤|ð~°EìÁ?DE[(é'D¾x§< ;›@&´ñD‘ÏývÛíðDSUÀó29ŒMygÓoPqUX³ A™S@æOg¢ƒ)˜åÅŸ¿E)˜Ñn|‡êšó"{?–A1V>àéÈ”U0åx­‚hÊtY"sˆ?ÅQm98úe\Â{HzöÛ¤Ow>¼ü™ÆNè¡7jú7`hB¢®®Â„H£åX›áª¼÷5÷Ü€åF¤†é+Tár=„¾&ðб§K¯Î޼í÷“@#„ð—UénAòdú˜Dyk"ÓÙçr½4¤’ÇÝÉÑég2c© ð6ª½˜ËçÇ8°F oƒÐsRAXôúo/X2°âÍì· ‹¥Ú£DRp>L RØ!hžÂ/.9[¦‚dDò¤zô„îùk—Ý ¢èGuØpLå1Y`:Wnê&“¨Ò%Qãƒ0¡æ?î8Ï‹·˜M››œcVXwRüœ`é©à…éO`h1[f”L›\ý©é' àM!üÚÎ%”Ï3Üί+´ÆÏÚ’Þ¤Ì&¦ÃáÆ¥þòµ4ûqî|$ýaÖôéÔñ½ NÁÎ}®ð[»ÙJüëú¿¿?|ÿ®s¦Šâ̧²Šk¦”‘)“äpàp°¹L7|> endobj 3016 0 obj << /D [3014 0 R /XYZ 85.0394 794.5015 null] >> endobj 3013 0 obj << /Font << /F38 1122 0 R /F22 1037 0 R /F42 1338 0 R /F49 1358 0 R /F64 1485 0 R /F21 1034 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3019 0 obj << /Length 3175 /Filter /FlateDecode >> stream xÚÝ]sã¶ñÝ¿Bo‘gN> âñ’»¤Nç»Ót’{ %Êb"U‘²ã›þøîb~H”œ6éxÆ `±ØoHÌ8ü‰™IX⤛Y§™áÂÌ–Û+>{„±o¯DÀYD¤Åë«û«/¿QéÌ1—Èdv¿¬•2ž¦bv¿úeþžIήa >ÿéöÝ×× ©S§ço?|xûîægèH€Áùü‡··}û=Á>\;9ûíû»ë÷ß]½¿ïÈ’,¸BZþyõËG>[åß]q¦\jfÏÐáL8'gÛ+m3Z©)¯î®þÒ-8õS§X MÊŒÔ 0C1«œ˜f”`V@²š3›HÝ1J»)FE,dTÓfms|Ö4a&åél¸ÞÉ®étW)»:ÁLÑ®»¶z¾/Ú˜ž¤ó&ß?åûЂЦ-– õÛ:|7ù4¯œË2‡«T‰†ŽáwyÞO“Ab@”’ ‹|ï@Ë-h¥0exãX¢LfÔ»¶¨+Ú¢¨Ž¨ûêæöµ}Þ®¶EU4 \v¶Àk…-„`ÎéWl÷Y[ïIÊ×À ‘Îój™臬:d%ƒ³‰© WŸ8Ë\ D_”!Öyùè°"{'â$3&Õ—·H§ÛŽÄ2£œoû®hveöç Ðp-æž ß­×ô%ž ÅD ¤@:7¿­Û0Ôn²ö»:l¼°uK™ùçºÊÃêEµ,+ê™8 Ám¾¯²rB ”vp‚4ŠÇCQ­¾üúOb¤Að’$ x¸' …æ–%Ú$c¡Èª]?ÑU¾Îe;ABâ˜NRVf_ÞÜNlQp­ÒNDËzB|«Xw;’pCߪ3²Š¾ùo»²Xê§Ôõɪ˺BÍz<К+vVˆ³ýš ÷HD8 ‘×»ëEvþ—ÅîãñÞBp¦7ïNv1Xô•f´ýß^ñ KŠ'y}áæÛìSQ=Vsˆ¬Ç^V½Ð.s¼4Xn²ê¥;Ûl•Ç=èš·z©²m±¤ÑÃn•µí "ÜüüÍO$†J±Ô¢¿IaG2ÞÔî¤@éy“=å+‚£ö_BÛfM‹:'•žR@…`F’V4êÕлm=¿Y“ë‘'Ši®”dx±›s¸™:PІöivù²@R`¯Sý1L2ap¬Ã®¬8sNEýý"¬¼#Ž/ó&œ±\)šÀ×D2Ë3–øÚöjˆŸßo¢¦eeY?7ÇÊ,ïvõ:[G#hàr‚ò=oòjÊ ‚ÅÆŠ×N ìNut•›l5z»+smØE Û³p^çÕÏ›²4q)éAžÇ³5õ”µ Lw4¢ûjµ$ôMÖY¼‘-å,Il„³&Ť~¸Ä^¶)C¬óF¥ÃòVå¥ZF«²,ó¬úzDk¢ ¤>$*=²ûG»HÇÒÔº€4µŒaÎÚ(}Ë2kš‰e”–ó{—y*òç)bsäÒÇ'fS&° ç~‘ÁÖ)‡ÇžÉr8<Ä#ßyKÛ;c'¡ €äðúôÂé`mh`íc*fÔïl!‚rÞzy¹pOÒqq›yK%moÓ ÝÅœFs´TØaþ*¥&¡ÀÁbЈí™†š³„¾@'ý*ݱú Ãô0×+’o‘-ÙÖOÞ” iª6ÌÆÓòxJÊ—Æt„ êŒQïÒ£Qƨ ܺ‘ ȤP¯èàë‚F,ºšìù¼Ö5áÿCëD$ô"K;¬SžŽµNXÆØéSßWÙƒ—4¡ƒsFqÁÉ ¯LØ]“úŒR‚à>Ðñ´O®I"Œ{I C)ÂÂ#Ù#M~B¼åÆ2J©Œ"‰Äƈè õ8]àÜ •#p‹ü,—١‰Hñ ³QDªVÖèGÈá8=-[ê­Šæj´uÈ#ŒYŒõ¬ ˆÊeÅÀNYÞߎdko‚°Iæˆ(m²€Öùg ,¬œ¿]cgfô ІøÞ/™=“þÛdH„舘 ü¹ðæð†ñ[Ö`¬Ã^9}éèkà6ÑDr18GOÏðÞî‡ÓQ>fLE4œ}‹ª\üF÷±Xïëíb™ t ³Æ¬º™ˆ'|ñHØã¶‹Ü)BÎÄT™”iî’I1MBâ¦10åíL9´‰yˆò }<œPL‡ƒÄ=˜¨ð—-AûP‹ã=ƒ &ZÌÄ|î¹@º§ú4o€s5œ…¬Ÿ¸äpobDúCR¬œ`悽Þ›þ”>-¢yÈ©btXq?,º?,®÷yþy²‚á"^ 5˜DåxrÙU ±Î»ª+Tx–ù¹2ÛÅ]»2ÛÉ®“e¶Ñ®7Õ2p:É~WL +×ĤááðøØÝd™?åñÆÂU{i:Ã5…4¢û»Èµ!Öy®uX#®]tíDíq^/%Ó:Q—‰ë°N©ç”Ò2-­“w—·Í$W¯Ûñ*ocÊ6]NyÊÊCR* –©øo2*{¢$U=àëXK&’Ô½¦%JA¼`_Ó’!Ö…ûŽXþ¾›âq±ÊÑuMÜz’2©uLY?åè ¦<ÖL)e/cŠ)1ŒýÉ8;‘/‘£HÄeftX§Ü8*ÍifÕcv¼#NÀ\î£.éæÅ“÷.¹ÿóû¿ãcÅ¢Ê불UŽœ¡Æ "©¡äÂÇåR£/š‡˜†WuZXï£x ˜!œ=. ívåËX’}1} áÙËté ÷w7ßR Hm.Öµ!Sƒ•ëË¢6Ä:/jV'j%¸¯³Á‹[÷Á“½§K‚£Í¿Ç}2u1‰å¾ÓÌ¥áKy—ëø äÁ–‡}x%hK ^ô”ß0+äÁC‚€UŸøTBõz Ë„IT/ÁŠy¶ÜÐ&^Ÿ@.A¸´L!ØÎc´Ä·ê(½.‰èiêvóŸHQà…·ŸÔǬæŒ~tBwVà ¡ÄkEè!Ö‹XÞÌde¡+1eE¥£V„ü+t×ëQ¹É—Ÿº9â| Ê VC»æ‘cÙ¦¶àS¸=gà·ÌÈ/r¤Ã:eÉXh 'µJ¦cžP®‰Q¥J0cêzÖ—§¥RñôØ$]AX/ûT¾]¯ÃK›L(%Çâöîöîîý×T éoÄÛAAÏF§z!$[WUÓäË%lê‘@¤ ÒX˜ìk4Už¯BᦠóK|þl»Ó{f±ÄȨ–/“é‹„ÃveqàÝÄ2°ŠRÑ·g‡¸×Q!=ã˜N ù%Q˼癜ߴQ»ƒÐAs¡ðbuT¢î²ñ3:(YV§—upˆu^;¬Xê4à ’¬ô逸¯ÕyÌÿ¤\tR-‚X‚Cdq™ŸÖ)CÇ¢¡ã\¤cކwZ_B‰µKcÇŠ#QC±í߀L¬— 5ÐD¶û,U…‡Xz ØŒY·r™ϛ›ŸÒÒ÷9 ˜X}¡Ä˜;zl™ÆÛÖMõ/yå ­ט¨ËlzÄQë3Qø’‚µñI›µàý´øØmÏw„Õ«¼ ˆ@1–†6§›J¸Ña·«÷¨ÃØëË|Ð e¡7“u!X™–M£`¤I\Z>Ü„og‘S3‡˜¬òÌÔ’@~â7”ë …l‹qÂñ2I€¡±Íªì1$¿Ø'ÃxLiQ•ÝsR"÷æ(°èó;ðG«CC‰PÖ¢O—øKHçŠ} ‹m,¯ãx·èç˜\{ÇÓ‘¶åÔ ry‹é)ä>†*´ßßüps濾ÿîo~¼½›0åŸ_ÀÕ’žÞ^ô!ð5-ø£Èù*|Ÿ³h ¼8>+¿HüÍ Œ4›¬Ì°Ÿ‡²CK}:14²©']PgËMÒ§u'‘ˆ.€)O5ø8žþž_^ás.šé©ß]-âz‹Á‚ä@Æa®ójÓn[/*S±ÐLv¯ÂÏE»©áà‡†Òþ˜}y–wÁlß“Âo„ gH¸;Îö!i‹Õµœ®-JÈV“=F[Ö‡r5®·ác]IÈûÎü¸ ëîjòUwrù‡øÖÿ°BP•¦gBÆ#šáÇUp Ç S‹,¨‘VÎ%ONà Ž#'NõoèóXendstream endobj 3018 0 obj << /Type /Page /Contents 3019 0 R /Resources 3017 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 3012 0 R >> endobj 3020 0 obj << /D [3018 0 R /XYZ 56.6929 794.5015 null] >> endobj 3021 0 obj << /D [3018 0 R /XYZ 56.6929 102.8456 null] >> endobj 3017 0 obj << /Font << /F38 1122 0 R /F49 1358 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R /F64 1485 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3024 0 obj << /Length 2677 /Filter /FlateDecode >> stream xÚ¥Y_oÜ6÷§XàNn³ I‘™{r·qÑ8¹Øhú ïjm¡ZÉ·ÒÚõ·¿©•dm’â`ÀKÉápþüfH‰‡?±°šñÔ©EæÓ\èÅj{Âw0öˉs–qÒr8ë§›“×?§vá˜3Ò,n6^–qkÅâfý{röñãÅÕÛËÿœ.¥æÉ;]jΓ÷gWŸÏ~#ÚÇS'“³_.®¡+Uf`’ìô›__ÿ¬Õ€êË”F±ó§«·çìüÃÕÏ8õä⦗wx&ÁSö¿'¿ÿÁk8Ú¯'œ¥ÎêÅt8ÎÉÅöDé”i•¦‘R\Ÿü»g8õKçt¤SË´•ÙŒ’¤XÁœÖr¤%í˜IeêÏr}qAÊ8ûíú]ÊÁÑùF™s™ôÓwõzÅVM½ùÂ5×ðO¼¢å8°Ä»¢Æ1;«óm±ž%βNƒÉ^$Å"I+ç ^²ÆO—Woi¡ 'Yo˺l»]Þ5;"}*6ÅîTؤ¨W‘Þçõ>¯fN,ŒeÒØ«r©4ÇIn±L3¦…2ärŸoÞ}øô5-’k^Ö]±«‹Ž$¹~n»bÛR缩Ûfוûía_ÅRedà£$3&³žúkPNS‚q¥T8Ao³9ŽË8w™j– p#\rÆ Œ§Ç€HHõ,ßáLm˜´Ö ¾H™Ü„Z°ð çònf*›šˆH©ŠYGŽ#…_?×ÍC[¶Ó@4M)œE (gÄ\àVjTÒ,òpÆ5 ÉrÈÂÕH#1¦úYG~8ŸàíÅõù§Ë7—®Ž(|à7_ÕxƤã6hTIw_`cFÝ8Ôí'l V¢¸ƒ`à*)Ï®4³·äLe1!ŠSÀÒ~gŠOÜÎ#Ÿm±{„¸Œv>D›Š÷]Y•Ýó©‚pi„Lnîé\| ¹Hîó@ÌQ4Ð|pJ/–½ÚA¬¶Ü–UŽ›I8œÚd¿êö„ DÍëu~®»ü/jwÍŒ]„âÌ*|À²9Ã@Ääöp€­“ë.‡˜/ê® [媚¶ð¨¤¬‰z»ËWE;‘pÀx…þSÙÝG-pf$H2ÒBqæPñÛкjjG¥*9¯ò}‹Ü%¤DÜgy"¡H‹½´¾SµM˜Ös ë{áÂ.7‘á¾Eìõ“VÍ9¹ºç*J7ÁÓðx Šƒvÿð Y¬ßô£–-—Î K<¯7 Á“×?í‡×ãŠüøãÌ’×Dëú-PåØh6ô[•u1Çís]þõ’Ý?¾“ÛKí[Û!ƉT6ÙîW÷Ørèÿ’»û¼žÙÍi–Úìoxµ=xuÊ]°/lÃ÷ ~ÔîžL^õ†–ç5Ík¢ÚɬW4ƒüA¥¸ã €BÚ ©›Gçôógñ<™Ç欉Gš‰Ì‚}øGy_jI)渌uã@"€Txy‰çĪì±#5VÁ(ÈPFÞëb“ï«n4ðRk°„•a:í@»•A‚MSUÍ“GèÝ>Ó/á84êP@þš)Å'ºo<¶¬×dæ¶%º¸ ŸÿQèT$^ÜLy`”i„x½oÚŽZOeUQë6¬Üt„±û¢|üå#þ!½@;r½+ã‚<òØ÷bß탅€±”'Xô=)ϦôCÊŒÙLÚ‰Ñ=_r5Žq©ÍÔˆÒ†ó¹¡ê(]0"¢r\°Š%«X ¤?Ý—Cžå4R¢ƒNùæsçq‚‰¬¯Ÿç÷,ɕƒœKa…©¥;ÅçÊòä7íýrsA¸E¥‡½ËõÌî)ܪ´ÓÃZɸäÊǼríO D_*™¨AØ–*X$aæ¢D dÄo¬|œ É&ÌJ(EÆ2®³o©Çp•Ní (lĬv¬Ì²¾›¸;ËÞ"Ç`$…»#ÖÅDƒ£+‘‚–¼|VD?¦9—å1’mˆdÛG²¥Ôˆ”|º[k¢îaJ h€‹†}‚BT3 ‚ 466“â ›06ËŽ„¦xQV“ÐÄÒcF3™ÂŒø"6¹ «GkÀê°&ñ|}«l¨ I¢.V‘ÞÐï”<ÖØ@ ãn›.° a­ 2°^"5Lñ‰Gø˜âGb ®à‹ Žœ^Bàª\ʈÄ3¦—>¼(¶`$ÎèSLˆ- b‹bKʤ§‘4)zØý.Q†²ƒL¸û”AÆœF|pÍÇf `š¹}´dÂè1by^ÒT¾ÉÊ×@C… ‚_v¥õo.Hð•*4.?>*£‘H&Loè~¸ “¥MцpвŒf=@äB½QÅKìL}y¶éEùœq”`‚×·pÙÂ=ݪCVyj¼ëW±öŽUw,‘‡µ5uK¸wî×E(¼ópoèvèïž•­lÁèùb¹F°ãKø°Ã¨DBxfð,BjýâzŠQ«”t_Pºbø‘A1 KèƒKvš¶-o«°(¸Î›¹ À,áú’d>/Cîvi_«½š+@˜µB€28º_ ¨9¤“8‡Â£˜‹B²ÌY9(5eÕ$c]'‡å»•LóéÕi»Çr[š”0Žšd]£‚Eä/¬ð›Ó]£ÌȸÀ¿!8¤áJÈè¥æ&R ϰUï··Þ/‘Õ›í„KœB(}‚ôóš°ÁåfîÝ`öÒ+RÆ wߣi6qÓ /%Ueø‹UéQ‡ªî8aŒžDŽ­Û0)àò«Û®ÈCÇk<ñ~—ÂÐFÃøÛwš\äÞlãÝÈäpoŠO‚ðR‚*ó? jEcþ†¬)Ü¿Òõî·¾Vsç”i ø—±ºýf ±š9Ñ«4>AŽYb-Üû÷wå ž2«û[@Çg€ºo‘™4Ù„‚iµœÔI·áãA°ÔàAÇ»ì&<)¥Ð )» ŸBvÁ%Ãì‚S&>¢ùßÈ#G2;‡»”’_¿kà×g_¾Q(Ž®yç_(°íß¡ÌçÞMBÃͳOH d%LL9H%ðÀšôC(Rxàͬ%\ F#1<ºc£{jâ5‘eFM:>›ÌdQ~&bÍ«»f§Ùο£kÝ?l ®¾¾‹ï!ÐÜS¨ÖEZÏØw¼©»” Þ'‰cŠI(àÃ$ªè2t¼¡váâ³ß…/Z]õLƒM[ïÞŸ/5™sc |ÿVãD™à‡¶¹Ýp˜[ÿî>È).‰Ûõ»³i‚ÇSÒä E$js`ª¼žWÚ¯…ZåØ×S¨*ñ“çÌWÞHù¿¿¬>-«Œ¥ÖÊÃGÓQYÅñû‡Q(TžäÙ)Ö}pÆÁ·G0)K—_œªÿ<ûòXÿæÜõendstream endobj 3023 0 obj << /Type /Page /Contents 3024 0 R /Resources 3022 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 3012 0 R >> endobj 3025 0 obj << /D [3023 0 R /XYZ 85.0394 794.5015 null] >> endobj 3026 0 obj << /D [3023 0 R /XYZ 85.0394 752.0715 null] >> endobj 3027 0 obj << /D [3023 0 R /XYZ 85.0394 688.5597 null] >> endobj 998 0 obj << /D [3023 0 R /XYZ 85.0394 649.2752 null] >> endobj 3028 0 obj << /D [3023 0 R /XYZ 85.0394 616.1568 null] >> endobj 3029 0 obj << /D [3023 0 R /XYZ 85.0394 580.4012 null] >> endobj 3030 0 obj << /D [3023 0 R /XYZ 85.0394 513.9676 null] >> endobj 3031 0 obj << /D [3023 0 R /XYZ 85.0394 453.4207 null] >> endobj 3022 0 obj << /Font << /F38 1122 0 R /F54 1433 0 R /F21 1034 0 R /F22 1037 0 R /F40 1265 0 R /F49 1358 0 R /F42 1338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3034 0 obj << /Length 1919 /Filter /FlateDecode >> stream xÚ¥XKsÛ6¾ëWh|©ÄF0ndB,¡‹,….æ!t@q¡ƒÿAè`=õìýµ‡Iía}I.V´œ‚aQßl:6☌ 36ú¬Xj{ƬÉ[’\7énWÅ ‘¶Î4¢+Š«Ö[¾é( JÀKaAÃÞ i›¾O‹2ís4”*­o}®ß¶]^µ¾¼ÉóƒªrúöäÕÅ÷§ž9_ìJ‰Ë0GM«› “˜ .LÊ¢ÎÛæ<]¬váëM^bÉ€t°Þ-÷æy½ŽSï%aIdŒcçšÎ¿¹A»@WïØ_.0Aô^X²|™nÊnÞæë÷P’æBÙ,ÒrÕ´Ý7c57lÁÌ‚âÀƒ¿0'þù&²èS/L+¦8ĉè>¸Ã;úQ½8K.¢Çßmí/Û·Ûsõó/ßm~øöÛÏ0ü ~Íw (˜Ò1åë™+ú¡p(ÀEWÍûœhùwPFª&¼@±zð”Žh”’%ÆÏ´-Ê’ä:ª|Š‘PPÉÍû›ï¬ò\ƒ«‰äß8€J3?A\TɆ²(€ÛKzÝ=ô@P71·û'á/©Ç]†ëÙ*“ˆq„&Œ#Œ‡*0pÖN$‘|À17:_;õ0%>€J‰D‘±ÚÑôv#íÊKËòß•ÔèN‹z,åI¥Ò½i±ž!òD ”p½Y{è‰D¤”~=l8òb Zîë~äâO:ØÍD»Á ¹Š,<îðêv4-ê oÞ’ô£™v½ªQxÝGÎ mK#·5§qh! çˆ0ÈI7uàèÜn¾×àBè ܸ©}'àô’Gªƒ„ja† ?ðŽ8°gž<Ðþ¿QüÙr$f¡'æ/¤‡˜ÍñÝWrøÒÜÍë8a‰èÓ!%rý«45Íb@÷–Œ8ŽJ†r!¯Äx wBB‚ÿ½!ýÛ… øvK .’©DóõAôE’žŠ D…î~o„vCÁ`TCþzx?rž.F@¶†ÈF}cá:”ïB"è¼Á Ïüµ‡\vXò%·L$ô=Óï‘{p}NàêÆ"äY— ;cX¤÷†ÒÇ0t eÖÏI•jœ†`pÅ7>cb_¹Uâé\•·DÁΈqP*QŒ/²1µø¿…<ïòÚ‹m†âcl@>5¶YxQ“pæûe³Ùt®ppŸ¨Xy6oÎDÎb2-¹éœiÙ§ 9p &ÏFÃJ3ò1÷àòºÛ}ÔÔ1SI"ÿû«œ· ãàÛY8 ¨+ x~G% ­—3É“;N…Ïw½ú]Òˆendstream endobj 3033 0 obj << /Type /Page /Contents 3034 0 R /Resources 3032 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 3012 0 R >> endobj 3035 0 obj << /D [3033 0 R /XYZ 56.6929 794.5015 null] >> endobj 3036 0 obj << /D [3033 0 R /XYZ 56.6929 644.6065 null] >> endobj 3032 0 obj << /Font << /F38 1122 0 R /F54 1433 0 R /F22 1037 0 R /F21 1034 0 R /F42 1338 0 R /F49 1358 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3039 0 obj << /Length 2452 /Filter /FlateDecode >> stream xÚ¥Y[oã¶~ϯ𣠬YÞEž7w“æ¤èf÷ÄÙƒìîƒ"+±PYr-9iúëÏð&K6§(D5g†ß|C‘ †?2Qa¦ù$Õ LÄ$__àɼ»¾ ^f„fC©Ÿï/~ú…©‰FZR9¹èR+E&÷ËoÉüË—«ÛË›ÿMgTàä MgãäÓüöëü77öeªi2¿¾ZLgD󔃥FNâäîöòãìãçÛ_®¯n§?ºïÍšN036ýqñíž,a¿^`Ä´“xÀˆhM'ë .œ±0R],.þÓ+¼µ?¹B0…„¢iÄ”LAZ:r†ÐH2ʬ3n矮ܢWwSXêábŸÍo®¿ÞÍ3îo>ÛÕ‚N:ð/ž€(R˜Q«ì~ULgŒÈ¤ÎÖöN$m±}.¶nt½k;w÷àßæMýcú´ÛN‰JŠ¥{Û5îšåy±éœä¶^æn~SyW6uëÅ꥓ ¿sÊòæ©.ÿòu+?ãïÅ«i7E^šÉìemh–Ôû –d~h×͇ë&i&5c³# IRâ%Í|Uñ&¤:ÙµeýdæfÁeõ.«Üýc[]VV-òÖ6„ž¥§ng,®üƘÿ¶ø|>÷M|Ç+øG>¸_š±™ ÄSQ¾[ÂófY˜qâÆkñеiŠDJ…wí?sÄñˆTˆJ)ûlˆ8eÆ8¬’4 3ÿzÿïÏwç½rSwŶ.|d¯-ºõøéÕl»r·ÞOËã2Ä‚S@]éô0ÆxìÔ°c™@‚¨Ô!šÁž¸aÀ”>\½kÏwJÓ}ØÜE sR8¹lBn6Mõf ¹Y¯u³iËö°PÀ~% ›ÃŠ1æ1\'`:î£õ#, žÍ,ävf@ü t¼p ý6Ë~„»¹[Ì;ÈF ¬È/YõÔlËnµŽ@”+¨—!Ÿz­­2%EÈlptkÀúX%'HqFUæïQùXVC媿û=¢ÜTxcè‚Iê>ßÞ3Éæ¬ÝØ}\k8žíY}[¨Íú„+Æå ×ÚžÕš-—Û¢mß¿ðî¬Ê|µmšnYncv¡òÈÎ]4P’#­ ‘r[qL$æV¸×@®I…áßåÕâãÝÍ—-"o—†!b “dˆbʽ i ƒ’JR@t4ÂK˜Òvlá ¥P{OQ"SSŒxÊd€¦ÉMçgÎül†¬™+xpéî2?uÖÛø\Ô¥+àf¸2 ö>û_bf®/€3‹Ù3[Ä?`–Q-O0 fà…±÷Ñ®”S5¢]N³e‹T O/´!”[W0ÛMS/ w‚§¨Ðú<Çaq¸™,¢L#EÝãT¬4C­4Èô ©u&GY „§y ”h)÷ðê´®À\äÂc*T=Ï|Øêu ¼/1d†ƒ=&òœûœáÂå l§*Ùù±(n´îØ-B!¢z9ËbnÁ@5EÈ€fã÷wäßèn-Ù€ÝÆ dW¥ iLÈ0‘âa&ì)=Ì#PïòÈènÊ¥·aå—]…rÄó„PB¤éÈï€{@F>ưѤqLm–âl47w@`p÷»2[9LE¯¹êš§¾5ÍcœA¬gT޹Ñg‹ž‹£Ú3 =– X¾M†R¡å=æ?½Ô>¯†Sj†Sôí)ƒPdÊ¡³´BŒh1žòÒâ`Ï®kÖ°}òH8`Kª”Ë3x FP:@¡am0ø 0v¿*[7]î`-éðZ†‰ä#P} oô]ûB¦8TîxS ¬‘÷¹ýSÑåñÔMå w¶ûŒ|YÝÏÑš ¤E±ž´´¯­Ù=owœ Z%±Ù‹©`¦ñ)€/^V†›;×tÙ±ðòaWVéÙÜc¦Ú“¢¤ôÞñ^§ÁW{m#O4Å’’3¡§ˆ“ùNX+VzXbû™"½w_ã— ûzÛí6È”jOr"ôS)áŠAÚ§\©#r¯lZöFöp…ybšaLk›­XØlµ£Ù®êÜCÞ¬×Õ@ ‡‚U•{ÓÂ&›’Âû,p&ì~¬`U5/ñ*o(¾âZœ„À:„ËÖoÙ®6SÞ'PΠÇc·E0’P9çç"Çn=ˆÜ蜤jòpÞ±jZоêÂ]Ýø³ÝÖâµ}8Âk;Ð'J¡ŸžAF Hl;ßÝ®®ã~ʇ [ë4^ÊS ¨¬ïmTZ'Ž9¤;æHOd»#mÎIÄÄ «a°@¡¥' ßSZ3…Ÿ{éNß6³ÒÛî¶ò¦Êòž€ÁýyÒÞÖ4QØB¯­äÁV8I™èùw|¦Žè4¢§‚jöÂSцӉƒÌ(þ,ÛΑëÑyšŠáv V¥½_ÏñHÀ1ÚË>…¨9ºÒ)tóhæuƒÄɺqÞuƒE•=4¦õqÇ Ôîï:§%tLK÷âá5¶¿ ‰Kõ¨u¦¨>¢* ÉcË*ˆ:›ÿØ•þÐÚÄDÒ°Ž?³õ¦ ( L…ô9æX…Sm¸3ÊÍÕžaÃÕžÃ2ÐléÅí„ë¦ÐoÆUòÚìœ@»jvU/l©wÄ@¢é¾”œïN…î+´I¼f×y[£4ª{“Â/"= ðFŸ;È7Ë(ü †ÃÛ7‘<…•rèÚ3]!U}éé÷$§G{’ÿýìÏüæ[ú¼È!#Ñ)v ›ƒ¦’¼MnB§¹m²þöÇwr||¤ŽÞ #‚Bõý-Ëz¡cÓF.ÐÛöš¶è‰–qᛘäÆw5‰ooܾþâ~qsíîLQ7ûÀ²•ØOUÏY @RyÙ|Õ”y˜3s‘ù—ã8«u–ÏÖKaö/õ¾ûJM¿2.Üí* G÷VžêG„<aŠôbá æ“"#Ø}6s'Õ1ŸAÚ<˜‰N}md@Ú‹ ÷mØ?þ¹ÿâÊÍÁ¢ñÐ3Ì¡Mrä2ž£Ê8¤NJ‡0 ›}ᇫê?g/ëÿ¦‘wÀendstream endobj 3038 0 obj << /Type /Page /Contents 3039 0 R /Resources 3037 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 3012 0 R >> endobj 3040 0 obj << /D [3038 0 R /XYZ 85.0394 794.5015 null] >> endobj 3041 0 obj << /D [3038 0 R /XYZ 85.0394 752.1334 null] >> endobj 3042 0 obj << /D [3038 0 R /XYZ 85.0394 665.3468 null] >> endobj 3043 0 obj << /D [3038 0 R /XYZ 85.0394 602.4706 null] >> endobj 1002 0 obj << /D [3038 0 R /XYZ 85.0394 563.6277 null] >> endobj 3044 0 obj << /D [3038 0 R /XYZ 85.0394 527.1024 null] >> endobj 3045 0 obj << /D [3038 0 R /XYZ 85.0394 495.1416 null] >> endobj 3046 0 obj << /D [3038 0 R /XYZ 85.0394 429.3435 null] >> endobj 3047 0 obj << /D [3038 0 R /XYZ 85.0394 345.5218 null] >> endobj 3048 0 obj << /D [3038 0 R /XYZ 85.0394 246.78 null] >> endobj 3037 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F40 1265 0 R /F54 1433 0 R /F64 1485 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3051 0 obj << /Length 2401 /Filter /FlateDecode >> stream xÚ¥Y[oÛÆ~÷¯Ð#T›½_pžÜÄÉI‘8>±hû@K”ED"]’ŠáþúÎÞ(’ZI=( ˜Kr´;;óÍ73K2ÃðGfB"i¨™)ÑÀDÌ–»+<{‚w®HYD¡ÅPê燫7d$•³‡õ`.°Ödö°ú-»A”¢9L³¯·ïÞ.Þ~¹}ÿáæv¾ †+ž]ßÝÝܾûøë|AaÄ8û|}ûíú“v774»þps?ÿãá—«›‡^­¡ê3«ÓŸW¿ýg+ØÁ/W1£Åìn0"ÆÐÙîŠ †g,>Ù^Ý_ý¯ŸpðÖý4e .4”K0Š@X 6AŠRÌ Î„ê FIÊ`QÊlñh7úæ½äIB64s"ߋ׶ü«˜„ Ó6®z¤[/•PŽŽ–ˆªÆÚÝ?ËòwŒiÑΌӬÛ~à4r£z=y•ïaXuå2ïʺòÏ`~P†e×Z÷k™}Þ·]xXÄk÷RA’„Y«•B퀹)þC­ÝÚ`žÙ‚1¤ sûFFêv±*Öù~Ûy€•­¿:uí`“·?²{BG¸ ΕF Fõ ¥N# —rX¦€ey=ÖåöX#%•8¯[/•PnŒ†×í¾µÅÊ[ç¥ì6Ó9•G›“1¥tPy‘:Þ•`‘úÙãÃMYXÀ­_ýM^æÛ®hª¼ ÛÖYön]7~%>ZI3Äb5Õj‰,5â iŠU<í|ÉQŠ\pþ@êŒó£”3Ófº¤”uaÉ(”Xr¸;EVz²ä]SV]‚«Û™•K2óH»3S!£¤§Z;pª¹‘÷ã@ÆšÞ¦dg „€ÍÀÙæ kìSÛÑc˜(÷—ù¶\ùáªÞåeuÐ!懈«)C´¤Hh·ÐùW ‰r"í÷°J†M/å`ó|6Ï6Ú&zЏÑôŠB ½†&0 qe&zS¹ `°ƒe !ﲫÙr“WU±õoœ¢nô²)\§ˆŸbŒ`wg¾J8†qd˜ŠRÛ²íŠ*¨b9<¨‹/ÇXuÖnÕz—X–0(ëð‰U)™:È2œƒ%Ç"ŠðˆJrº\ïÆ§n¢.`i uKQÊa©I`É ©™Œ»ÇÕ»dq@%"‚²óÚõR õF$ÜC“cýƘÜÒ"kë½óÛ²ð]‰W¯­—Yå]îŸzïÃò@ÑUO^Ä#ÔN $U7å_Ž£À‰’²ìc˜3 ÈMñÇÞ· Æ'„Ó¾ê@*)•£NI²ªîü£g¶åªðòTiA44 &8àͪøñ&ì+‘Ã@Tâ¾àiü¬ÅŸûhׯS”Ëâ'{6íôëa"C‹Ú—ŽÑáêW®Š¶õ»&òJ@‰5Úväo`ÌÇÚgëÀÖeõ¼ïPb—Ú6G”Œ`z&öÈe@7A²=™—ŽÓQH@9M¾„ÏÞŠ` Ùø«pžGtaJ\.뛆æêq8; Y#º":S—¼à~ïk[xRV€‹|å{ÛÆªÇùÇyùþÃ'-jÕ|ëeÀŸû"aGÊ5‚÷ƒJÞz ŘŠÈX?—ÕÊæäÑn“w~Õ‰áó¡ß?…^\*Í&¨ßÔûm¨ÕCƵ{?Ih²­f†'´¡ÔiB륡µ{|µjœ“½ÎYݽαrÉ^g¤Ý¸¦¢”dïü«œKƒm8— d<̉º”¡6×ZNó¢Ý1£]¿OÑöiŸ¢ÝÍ0cºßœÎ˜KD ûÿ2¦'S›&ì1È?ªÞÆ=ö®Ÿóå÷Ð+Œ, ²EþÈi4á*F/TøC©3hŒR]2½*¢Ï–›¦®»UÙ—ø†‰4ç•ë¥ÚàH9FÓ±z¡õ6&¶Þ0:Ñz ±g[o‚¨’|ÚzÛ)k=´ÞpcÓÔÞYË®n›³ˆaÂÉeÄEhz)·[?u3×Ù>h–w8®;ËS D^å«Eè) бÑzrÚSÚ½y^fϯÔÉ&ç; N­èåKӬנíׂý䟾ö 2ƒEö¼S𠵟^¤<>ï[HŒÓpÇñWbd †%ôg¥í™ì0÷—6ß=o“|Ncfk»rº}Ñ\O`íVpG"Ø6M(Yžk¨Ê}ƒ9Í|ØoÅüj{”¦Þ¶)ÊÐ*ÙÉ.’˜ †Dz†+@i!T\°í Ãù«Õ¹ { ›ñδ‘aïÊ*fPJl]7)ì€1»ˆ 0x0/t×óav8i_c .zâ"r†¬eùt‚ÄQñ(Úð(Ìîonü2ןî¿\Ž5;ùïX` ÿHT0"ƾƒn¯i¿> endobj 3052 0 obj << /D [3050 0 R /XYZ 56.6929 794.5015 null] >> endobj 3053 0 obj << /D [3050 0 R /XYZ 56.6929 299.7468 null] >> endobj 3054 0 obj << /D [3050 0 R /XYZ 56.6929 156.2522 null] >> endobj 3055 0 obj << /D [3050 0 R /XYZ 56.6929 85.3024 null] >> endobj 3049 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F64 1485 0 R /F22 1037 0 R /F42 1338 0 R /F49 1358 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3059 0 obj << /Length 2935 /Filter /FlateDecode >> stream xÚµZ[oÛ8~ϯð£Ô,ï"§Oi§è`7Íl²ØÚ>(– #K®%'M1?~yHERh·ØÙELQGä¹~ç’²…la¡ÂÊEf%Q”©Åz{FwðîÝ 4«H´Sý|}öòWa–XÍõâúvt–!Ô¶¸.>.__^¾½xóþßç+®èò-9_)J—}ñÏ×ýËsË—¯ß½½:_1«".¦Ë7o.®V¿|¸øõÝÛ‹óÏ׿½½Ø³Î¨p<}9ûø™. à·3J„5jñ”0kùb{&• J w곫³ß‡Goý§)U(aˆ2ô›¼G²€ˆe‡/@®°¾?t%’Vášë«÷ï<`¯˜¤/¬™šôÓTÍ$0€åõÆ}nä9ïu/Ý–Š·ÁËuÞàâ¦ÄWpkñ–‘Ø+¿æÛ]]úmØ_tåú0hž %Õ?쉻‡]¤„üTyÕÀ£÷&¿Š7¹+CJKÖoÊ”95ÔD í›b0#ç°Y Z·Û­ó Ÿ„Ö›¼iÊš NdËŒ ¸•‡4÷¯M”¿?‹4h¼Kpã²-Óѹ¾ã¬Pvˆ§×LD4È£Å}û+ÑN°u|°Û•ëꥼ,":c¿ O²ÂC]5ᤇMµÞàæCU×ÓSõÇ2:3pWYdÏ âu8„U{R{|=¼xªcKpOÁèò} oÚùAU(F¾˜]”·9øó@ÿ‘¥DkËfæHØBfÄp½(:ƒ4D›¥¼Ap9xƒà"í GM&øB \ROÞ $GYÝU#5ºG_R¹kšÜF¾Cïò¦Š7îsÚ»;ÄÂ˽ì˯}ø® ôUÓõç EZ;Êhy@uI Ÿ[Þ!˜¤:ÜÂ9¤*8Ûy€dœ X* —4cÓ!8¤Œ¢ ͬ>‰æTl%e¼"qäEÊY¤zðt,vexè;”`€0· öWU³®Å@r°˜`m7¤ã‰îPÜÕ®­«uÊ5|dL`µëv[6½kH¸Z~¢Š^oÐêtßyaûÛª†üä÷Âúß#ˆ Î.¥Aæ)·„¦„>‡Nw¼O þò¨FÏÔ#©w#n3ˆD°@PVö{C¤»Lâr¤Ç” IÀGŸÀ¾¤íÄE|.80™úžCH¢ *¨ú®¬oñXïÐ~1DNHon3ÇŸ2Ë7>ɹ%,P/ÃäívŽ„ \5°1„‚ÿfU§ràp&cÎø œÂa__­K±¨›*¬¼¯#šcY+²© œ@܆$, ˆbçâ¸{,¦˜w€Ï©‡ûï¼Â^%²”@ËkÇÀ;;;fÙWk†é¨(IÛÔ([S–Å I€qëU/·í`hØ,ëü¦Ý\ÿ5PäÓLLCù¸Ž3žöåPþ„)ë)Gˆ›7ë2¤µê6¥× o=´ §°RB-ÈÍHtì°ñ÷&¤ÌÙauë¹j·ø”YÞúó!ùØúd%Ϲ„Ä ù´”ÿà«ø«g³’Ð šeqXr¼gSÅÑÆóžq r÷ÆQOD’«Rýá˜9&¡âÙw¸¨ì Á@ 5jÊßÕPÆ8ˈX Áâ‰-Üoñë~;ñ¾€U6©¦¨^¾v“¬ûòÀMh×›¶ZÇ;CûâØf›¯WÛB9ÿ“ ÑÙÁ—´æ³´Õmræ3¡ERx˜ï(=ÛF: ÊB¥‹øPàª3lRÜ«¡¢sˆ`f|6™¶ˆ`vX® #½ˆ+íó®\A˜•MWõÕ}Œ´¡ô*ÉO ‰¿Æ-pk‡9“}Åmþ8 ¦v[õP‘‘cÎΡÀ§”ªÓÎ>¦:îì•wöÍüJ ±(åw®ŒD‰+'ˆl‰tƒÉ•—ûªé» Xt›vŠïî©~ÿ8mÚ‰]¢ÎÑ@wWÓtÇU ›pÛiÕ¨N¨.RyÕý‘ Àv«ÄóAÏ%T!YfNó6P%˜› „š–M¹› „`2Ôÿ,üL…Ém9=OhB%Dù6›¾Šã‰xBÀ EÃ`Àí?Å<¤»(f ³ÒŒspº‹RÔåj=.³P¨€v†(M °Wî\ó±IN¿˜æGS¯™2‰Í†‰NÓîÇ@ Élì9âŒëÄ)è½È[¼u¸µ£¯°lh UçÐE°,˜ƒŽKEZ±ÀqcÖÑ+ìÑyà%Ç£»r—ï±j„MÀþ²ŽíkF$Sv —·m]·¾ RÛDøE®a1ŽOÜñ~6&AÕ8q3¨“Èy‘BöãBÛ™p$´Kº’2‚`D[]è:Þ‰þ‹àÿ°Úº> Ag…˜¹×&¿/g8¹t›÷S˜ hvŸ×U€¨aö!m@±×U]Ÿ¨¡ù)÷] *ª;è&ÂÃæq10‡À]¹¯Úâ8ø1¥C4? ~cªãà7Py·ÿr,oœ¼rÈϯLåÉ•®_MÔµ‚@¨¨.ê•«¼C\ºbþ©C\I¥–¿ªÒYÕ(â WßHšaÊÂ]층Á¬àðV徯ñ~å×]7yßú¼84q$¾"³&¶ßHíݺ{…© `œ M°o·e×9˜Îë:äΪ@Ø®‡ò=Ñ@ˆ(%³ÿbÆxÜåÐI@îÓ.7¢:ár‘Ê»Ü>‘o¡6äkú§IÆ…JZZcNs7P%Ø›ÖåàŸ†²)ÓŒ«TÁ¥ºûÞu‰Û‚2p‹4Љ帋 ¿Æt8 ’€™Ògd(ó¿ù„ìÊ^.üðÓ½ D €5~ŒYÓý¡BÎF&Ø’¹é,ý>× œ¶Ç-,[Û{p$ÜÈSy’¡°š_åýË W"ú€TÓh,ü«÷m- ¦Ïî~8¢ÂNV«8{æ£-Œ5ê^zø„_¼¹PG£]e4sŒíÂö¦ÅUàNÕì=IHiÜ_Ó9›¸ð™ M WF}t“V néCÓi°_còÐn޵Ï×}é;{´(÷øë¬Ã`]&d½|R¾+ ¡ã·SáÑÑœ}w¨C ¢Ù0©ÇiB™¸º‰ÏÛÇ[‚àTÿ(¤Ãp݃ Ѐ=É?ëICà½z*Št™q5Ì šÂ ÑEã½è܆ðÎÛ0 Ñ™3¯ß´‡ºx>Ë ÇþS†Pn¬” :L1þòØxú)Pi cŽ$FÀ_"Ôú)'Tüç]<ãËŸß_¼A‰ Ì&V—r.Õð¿>ž‹õ¸îÎmendstream endobj 3058 0 obj << /Type /Page /Contents 3059 0 R /Resources 3057 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 3056 0 R >> endobj 3060 0 obj << /D [3058 0 R /XYZ 85.0394 794.5015 null] >> endobj 1006 0 obj << /D [3058 0 R /XYZ 85.0394 769.5949 null] >> endobj 3061 0 obj << /D [3058 0 R /XYZ 85.0394 744.3535 null] >> endobj 3062 0 obj << /D [3058 0 R /XYZ 85.0394 712.0918 null] >> endobj 3063 0 obj << /D [3058 0 R /XYZ 85.0394 645.3077 null] >> endobj 3064 0 obj << /D [3058 0 R /XYZ 85.0394 553.7309 null] >> endobj 3065 0 obj << /D [3058 0 R /XYZ 85.0394 338.0546 null] >> endobj 3057 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F54 1433 0 R /F64 1485 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3068 0 obj << /Length 1532 /Filter /FlateDecode >> stream xÚÅXKÓH¾çWøèH¤é·»÷˜À‚ ÒJÀÁÄÎL´‰†ðë©ê¶Û1«]´ÊÁíêêr=¿ª (üX 4Ñ–Û ²’(ÊT°Úhp{/G¬â™ÔL“6׳åèé aK¬æ:X®[² ¡Æ°`™¼g„K24œÞ,Æ–‡ÓùôÍl<áÌF2œ.³ùÕõŸð®(0'¥á›éüÝôµ§ù3/g·ãËW£Ù²Q«­:£uú{ôþ# °àÕˆa à…f-v#©QRˆš²ÝŽþh¶vÝÑ!WHeˆâRƒSa’±a‡11L‘°Dh*‡q6ä°š 6)ÐЧ/´lq2J¸¿SÇ’Å»´ï K‰Òí/^èU3 èÅ[_³Š¦YW¯TQ¯YÇA‹jÅ’$+&«<[ߥYÅÛ–«±ÆðŠ9϶§1c,$ š'ÿ2ÍÒC\¦ã‰:I(åwG mò ‰Q˜~‰wûmÅQæžo·ùƒ_&'pÏfå÷û¤~'_{bì_‹Mv·u~ &"ÏA× cÄ*Å‚÷yQ¢«!)µÂå=~4²—Î`Lª£vœ‚þp†Š3²f-Ó/¥—^Üç…_Þ;›`áÌĽ´bŠ3ÿ<îÇ,LÀ –°ªÜçÛÍêä×ëüPɨÕ/öéjƒ~M¯–jgÚ„EŒpÕ¸‚u2®g×ÄPÈsoÃ= Ek©ÿ.>p.ñ0>‘œ¨ò´G¯JA½W‘3I×ñq[z¦¿Ò“§º»Õ¦¨ø0Çpߥ΀ÜH"µÐ½bé«.ˆeÚžÉ)ÃÂy^¦µq9`J‘n×Η5BDJwÓ¦6NQ®â,ËQ•á§Šv,Òä " À$\UTÿ!XT6ÃŒ;Ršƒ>Ü%Dνïâ“_$›õ˜™püÁõ_ó]O²w+ìWiÍ­‚8ÏÂn¾wU†¦Ñ®I€ÇNx¢~õ°)ïý ?ä\-y¼"¢Œªë~òu P8R*[CƒÓ„\ ~«Z.1=޽m®ïcoÃÕV­½‘±u¡~ͳKìeÐ0¸y\¯ši@¯öj""ɺzýØ«¡]Yö=앦½Z `/ÏØ«¹% ÖØ Ë3öÂË{Ùa/2ûzñ· z%LÐG; çQ¡…ö—ÆC#¶ÐÊ~i¡EœEÉÎâÒá,.\½á^Z1!ÎâÓÛâ×5ºâÚ¡«;Y+ü8ºÂä@"ÊX/™.aUD¬‡ªÕG<ð˜ˆKY¤˜PbqüäáVHÚ Ñ,'7[í‘úx ‹,žr’|o²³¤Š+¾&;¤¼´TH#K¤`i…4(H(»…H ½… 6¿˜ŠL.]°qBl­ˆ"9,¤u'ng3¯ÂôõíÛù€´Ü@¸¡Ž]">&Xñ kó‰?}NpÜQý$OôfÒ¶ ‘€P˜Ú†g×ó+ÔVš%»M¶)J¨t—Î@ºI±•@ I}{Ò›8;ÆÛ!iC¸Öº âs„dpsPªëœé»åïoo~ì•ë¬LYZúöT”é®ð/Ïó¬È忏;Wóx%Gö.#0+Q˜4ãÃ>®GdÀf…ãšO ÈÄ cÊëÔpj@ÁEUªâ¬Øz´€×ë…ÆIâZi¥ºCUO°X凊gŸg‰/{u¾7ã] ù˜öï”åûbSô›•€þh´`Ì"0 ^XÍ\„ï°m®“uª«î° WÇk—ˆ·/¸9Š*6{ôxk n=g]¶„|§±º­î¥ÜÕìöùÍõbyýv>ÐTzy×Õ¶“ 2Â;R­Ct.ZEÝÚ~Ôq KõzñYV YRŸø¬}/F²ÃbÚ Ÿv(5Ü©ùdzuuCZ)Ìnäw2õyÇh­õÅÀZŸI©K,ëMÏ{ÿ Ð4L¿h†þˆ€Ûþ{0P2´Qñ_ÿIqþ3b)ð6=8Fötê…ƒÀL+& ÄBÅ#rÆ/gmüËRåÒªo¼³|œendstream endobj 3067 0 obj << /Type /Page /Contents 3068 0 R /Resources 3066 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 3056 0 R >> endobj 3069 0 obj << /D [3067 0 R /XYZ 56.6929 794.5015 null] >> endobj 3070 0 obj << /D [3067 0 R /XYZ 56.6929 572.1915 null] >> endobj 3071 0 obj << /D [3067 0 R /XYZ 56.6929 500.8791 null] >> endobj 1010 0 obj << /D [3067 0 R /XYZ 56.6929 456.1743 null] >> endobj 3072 0 obj << /D [3067 0 R /XYZ 56.6929 417.1894 null] >> endobj 3073 0 obj << /D [3067 0 R /XYZ 56.6929 382.5396 null] >> endobj 3074 0 obj << /D [3067 0 R /XYZ 56.6929 308.3053 null] >> endobj 3075 0 obj << /D [3067 0 R /XYZ 56.6929 239.9577 null] >> endobj 3076 0 obj << /D [3067 0 R /XYZ 56.6929 156.6902 null] >> endobj 3077 0 obj << /D [3067 0 R /XYZ 56.6929 85.3777 null] >> endobj 3066 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F64 1485 0 R /F22 1037 0 R /F54 1433 0 R /F42 1338 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3080 0 obj << /Length 1203 /Filter /FlateDecode >> stream xÚ­WMsâ8½ó+|„ª±V–,™„ÍdjBØ@ª¶*“ƒ"¸ÛŒm&ËþúmY²±À¡R;[9IOêÖë×­6ñ0üOr„Yxa Ž ÷–é{¯°v3 ã7 ¿‹ú¼üö;“^„"A…·XwÎ’KI¼Åêi8žÍ&ÓëÛ?G>åx8A#Ÿc<¼OÇßÌÜlÑáøf2‡!l“¢\ãÞL¦ãéõýÝèyñu0Y´>uý&˜i‡~ žž±·÷¿0b‘äÞ 0"QD½tp†xÀX3³Ì´vVë­}eyOþ¨ŸÉR¡¤Ðøáæñn2]ÌÏ ›Í€@ Ì/§IÕÔ¡ó4iQÚr“âDÍ2âì,-ºžAj# ¾ìZ‹êñ­«U%/”PAçn5çZ.Û¸Ž Už²r6uK‹7³£ÒO0ˆDGôçIM$…òÍDOò;®A•) -ì;æxm´“ËÔØ­r3ŒAÌO›0Ö—x·SÙJ;Üã Є¥ˆ>æ‹´00YçK «hq7a@ÈVšPлÂ" Î\VuAX ª­§šÁ….[mQ=fÒ0h†ÂªcwÑ\ÛánÖ·Œ5ƒÄ&ö_É69T&^»Oè»BaC\°Ë v@ïØ€ŒÐ´ÍÛá°H¡µ`$ºh¸[v8¤b >ÇôÂå騢†°†šNM>ëL 6ù~»r‹õ[‘T•ÊzË¢ˆ†ÐFº Ædb¶Ž¿Íïû›!ó&šª¡]ÑiÊt&Ú`ÆæŒ›íêGJóãâËýÃ%«ÂÖªJ™~3µ½y÷•¸Ê³2/ªdŸí»CmO ,ˆhúBaû¤\ú›4^ú:ïwÿ¹=<;è¤K¬§•õöËÝøÊf„:”n4¡´¯f¾]5åOU” ÜÓ͸ϷÓëÿ£ƒÐð_éÛ.tãðµN,í§}c„„`Í›o_sõF·š„Cã´,@ï|¢0ŽôwE»¸eè—?_ŽßhAˆ˜”ïTP†u‘ˆH㔾 % äÇiHMôê8FðU…˜? NoÕ~_ë_(Udoendstream endobj 3079 0 obj << /Type /Page /Contents 3080 0 R /Resources 3078 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 3056 0 R >> endobj 3081 0 obj << /D [3079 0 R /XYZ 85.0394 794.5015 null] >> endobj 1014 0 obj << /D [3079 0 R /XYZ 85.0394 769.5949 null] >> endobj 3082 0 obj << /D [3079 0 R /XYZ 85.0394 743.9119 null] >> endobj 3083 0 obj << /D [3079 0 R /XYZ 85.0394 710.2666 null] >> endobj 3084 0 obj << /D [3079 0 R /XYZ 85.0394 638.9488 null] >> endobj 3085 0 obj << /D [3079 0 R /XYZ 85.0394 573.5178 null] >> endobj 3086 0 obj << /D [3079 0 R /XYZ 85.0394 493.1666 null] >> endobj 3087 0 obj << /D [3079 0 R /XYZ 85.0394 337.618 null] >> endobj 3088 0 obj << /D [3079 0 R /XYZ 85.0394 269.222 null] >> endobj 1018 0 obj << /D [3079 0 R /XYZ 85.0394 226.5437 null] >> endobj 3089 0 obj << /D [3079 0 R /XYZ 85.0394 188.4488 null] >> endobj 3090 0 obj << /D [3079 0 R /XYZ 85.0394 154.6889 null] >> endobj 3091 0 obj << /D [3079 0 R /XYZ 85.0394 83.3711 null] >> endobj 3078 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F42 1338 0 R /F54 1433 0 R /F64 1485 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3094 0 obj << /Length 1942 /Filter /FlateDecode >> stream xÚ¥X[“Ú¸~çWðvÌVÐÑÅ×Gv†dÈÙ9ÙÚSIµ}?ÑB&2éG‰Ï.‚~¶éñþ æÞõ„•:¡á¹Ô¯ó޿ߪ¸Ÿ°$”a¾<Ó3Ç¢?_|öÆLFl*¸7ïÔÃhö0J)åÇÓûÉ08H‚çÞ‡ÑôÓè7â=éÞgƒ¯ó÷½ñ¼µéÜnÁôgïóWÞ_€ùï{œ©$úp&’Dö7=?P,ð•rœ¢7ëý·Ux6k–vúAp&U(;!E_–¼ðD°PIe›¼£‰oúh;¬ólǃ´ž€ƒôn bOC<ÃÄ+ªr C7ë´t”^ä+]7VT—«fM4ýBpÖv*-VÕ.oÂ[oˆó…?ˆ P†>ÑÏÇÆd ËjG„EN³¯±®Úƒ²Õšx„Œ¹8ò*k q¤XíŠKÒ®¸Y¯bŸ˜tc31‹Z˜¢.i*%Q¨<"Î]†ó‡¼(h9+ š;ƒ"Ík‚N›ûô¤˜®d8—ž„¤ñwRž¬ÁÀ rîdI“¬à*ÌÏ./+Ë¡é?÷y[‰ÀË-ʼi–|Ñxz¤ží¢í./ÍÙ‚W{+ë îfn$WsgM UELE’:hÞ>=Mæÿ#w§³Éýøi„Ž-Íìç=ͬ==fWî*2ÎÑÄ£Û):5£zìD Nâÿ-dðZ7Æõº‚íJ½@/ ØÑ8 &ÒšLhÌ-†÷]W7e•`¯DÔ–j¦©²ª° Þð… ®:¤j÷ ‹CDtá᢭¹ä«’Øiy<¤-R*˜°ãÌ¢2uKLá%n»„ÎÆsûÝ ¤¡‰UÞÓÛ;š”‚ûíz]í¾÷EJÿ?ÔÚ‰¨moPйŸéºž-—޲'<úJ“žgtšezÛ¤m‡ñìr³-ý½Ù¥D¶°†‰\í‹ëš©óUiºÄv‰ £´É–ÖúJõr_f¶3ÂÕ Éá Oþ£ZP¶Æ´vôÛì#‰ûüõ¼§öå»l±ÉK€"ˆqe»©'½´r™Y3?¤å>-:RX@Ë0t·Û› |–ÄBYmÔh¢}«Ï ÚAW¬ëüP>óu £Oó‡O?/ü Ñ®t 7;ÖÞÔG”¡êòýæ´­Ï”:·ûpõËðô– ‡Gb i­ dÛ¼S î¹iºÑ¯X/ŸHÆÔõ*Œ%úˆ(woÐȼZ‰tûý )eµ…«æúͪ ƒŠC]Z˜t½1˜+Œ\÷”EB„Ž“ óþôeÇC¼•º<®9AàŸ/€¾Þª6ê´€P…ü¢ ¢Ž…¥š¦Õ&ÍËÎ|q/sû¯'Í•½— í]»ÞØÅ SJÁ}^Ò×N¹»™Ï)½²€¬¬\JŸÚä'ò—´¨]/¼mºƒ”‚Óצ­Sö=ƒR™ÛÎÜ»ðÝ·˜î¾ÙZgß,˶Cw‚‹›à%-ò…y’˜·Öò&í›ÚôEíÎbê ݵÿW…èÏ3vôôîÓ‡ñt~û7‹M¸0`JòäÇIy&äþ¹ÍI'Ô&ÚÕŽ‘d<¼~¸£“¹ÝñÂý/I¸üÛðÛ?¼nOõß/¼endstream endobj 3093 0 obj << /Type /Page /Contents 3094 0 R /Resources 3092 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 3056 0 R >> endobj 3095 0 obj << /D [3093 0 R /XYZ 56.6929 794.5015 null] >> endobj 3096 0 obj << /D [3093 0 R /XYZ 56.6929 752.0914 null] >> endobj 3097 0 obj << /D [3093 0 R /XYZ 56.6929 555.924 null] >> endobj 3098 0 obj << /D [3093 0 R /XYZ 56.6929 468.7059 null] >> endobj 3099 0 obj << /D [3093 0 R /XYZ 56.6929 405.3981 null] >> endobj 1022 0 obj << /D [3093 0 R /XYZ 56.6929 366.2553 null] >> endobj 3100 0 obj << /D [3093 0 R /XYZ 56.6929 333.1561 null] >> endobj 3101 0 obj << /D [3093 0 R /XYZ 56.6929 297.5057 null] >> endobj 3102 0 obj << /D [3093 0 R /XYZ 56.6929 231.276 null] >> endobj 3103 0 obj << /D [3093 0 R /XYZ 56.6929 170.9331 null] >> endobj 3104 0 obj << /D [3093 0 R /XYZ 56.6929 95.6701 null] >> endobj 3092 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F40 1265 0 R /F42 1338 0 R /F54 1433 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3107 0 obj << /Length 824 /Filter /FlateDecode >> stream xÚ¥UMOã0½çWä˜JÄëÏÄÖž”/Aai‘Vb9„&¥‘ššdÿ~DZÒà°ªÔŒíç™7Ï36q1üˆ+ÂLq7T L„»Ìì>ÁÚ©C,Æï@þu¸p~œ0é*¤¸‹ÕÀ—DXJâ.’{/º¹™ÎŽÏO|*°7E_`ì]E³»èÒÌÝLõ¢Óé†$d @4Ô¸{³ùôˆEó³ÉÃâ™.zNCÞ3MèŹÀnô/Œ˜’Â}…FD)êæ ÎX7³qæÎ¯Þá`µÝ:¦ Ê×ILÇÅ HÞ9ARïbQ2&V‡ÒbÅ›§r›Õë|?]B’!–îÐé‡Ð=j$6Ä&Œ#)€ÎNðôWÂ+šü1Ýj›{Y‘d˸Ί'³V¯S³°Ž«µ™ê)Éqν£f»é¥E½yÛÛUÝTÕug†«r«¥p}Ê‘ÂΑ %m·Õ1ñ–^V™ïü,òÉØ”y¯ël¹Þ]¶ é¸zøøf¾-CmtÉk›ü„/ ½eYTéKcÒ+(åDÿí:x<µÕTéªÙûo¼iÒ6Ü¥aZD'ÙvB½Ö®´·>59DEjßVX C…°¯Ëpˆú¼ {”&”ÕéNòþX‡š'ü&v ¾[‡ ‘PîE_´å"ô•v¹²Â$I¦™Å+Y–§U§žÝg« ¬j]6›ÄØvõ9Ý‚àyš|®+´9ùN×ê ];”Î,)ó8+>hJ`–üë¸=j$ðަÐ)Rªp7r¯©¥`ôs;[—»i­@m^}Ó­\ŸÁ#àÆõ™@„à õ?ŸNÍÎèr~m¶q<`…MsÂ[øáùìØà•Ý–äY‘U5”]× ·é*µ7ÉÒÒºŠ‹Þ°ÚI:ˆAq´ûƒ]BÀíÉ‘ñ(ˆ#þàZ¤\‹×ޏÚÓ!º[œ]ߎxÜༀ+ÒÚ°˜¿UušÛ2>‚¶ƒ«1kòÏÞ<ÈÇ«÷ ÿû=|ôyˆ˜”t¼Üæˆ1E:R:9JÄÄ'‚†txÐðL#æßðý¬ƒGUÒp$­YKûendstream endobj 3106 0 obj << /Type /Page /Contents 3107 0 R /Resources 3105 0 R /MediaBox [0 0 595.2756 841.8898] /Parent 3056 0 R >> endobj 3108 0 obj << /D [3106 0 R /XYZ 85.0394 794.5015 null] >> endobj 3109 0 obj << /D [3106 0 R /XYZ 85.0394 615.679 null] >> endobj 3110 0 obj << /D [3106 0 R /XYZ 85.0394 555.6269 null] >> endobj 3105 0 obj << /Font << /F38 1122 0 R /F21 1034 0 R /F22 1037 0 R /F40 1265 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2278 0 obj [1026 0 R /Fit] endobj 2112 0 obj [1026 0 R /Fit] endobj 1732 0 obj [1026 0 R /Fit] endobj 3111 0 obj << /Type /Encoding /Differences [ 0 /.notdef 1/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash/ogonek/ring 10/.notdef 11/breve/minus 13/.notdef 14/Zcaron/zcaron/caron/dotlessi/dotlessj/ff/ffi/ffl/notequal/infinity/lessequal/greaterequal/partialdiff/summation/product/pi/grave/quotesingle/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde 127/.notdef 128/Euro/integral/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl/circumflex/perthousand/Scaron/guilsinglleft/OE/Omega/radical/approxequal 144/.notdef 147/quotedblleft/quotedblright/bullet/endash/emdash/tilde/trademark/scaron/guilsinglright/oe/Delta/lozenge/Ydieresis 160/.notdef 161/exclamdown/cent/sterling/currency/yen/brokenbar/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis] >> endobj 2315 0 obj << /Length1 1628 /Length2 8040 /Length3 532 /Length 8905 /Filter /FlateDecode >> stream xÚíte\Ôí¶6Ò ˆtÃÐÝÝÝÝ¡Ä0 00Ì ÝÝÝÝ’‚R"‚´t ÒÈ‹>ïÞûüž³?³?½¿w¾Ìÿ^×Z׺î7¶‡Œ5Ü ¬‡¹rðpr‹ t´P(ÐWç…C­fL9g0ЇÉ]Á¢#°5@ ðòxDDD0rp'/gˆ­+€ù‘ƒ…ý_–ß.+¯ ‘.[€ññà …;9‚a®ÿã@=0àjØ@ `€œ–¶‰Š¦€YIÓ †P€¶›¨C@`˜ ˜`w@ÿ:@p˜5ä÷Õ\8¹d\@€‹y {‚ÀN¿!v€ØÙââòø €¸l0×ǸÂêfý[À£ÝþG“3üÑÃñ{$Ó†»¸º€œ!N®€Ç¬ÚòŠétµºþÎíy„p›GOk8Èí÷•þ`4¨+s¸‚=]粬!.NP ×cîG2'gÈn.˜í¿°œÁ¶@gk(ØÅ呿‘ûwuþuOÀ¹=ÐÉ êõ'þÇëŸ ®.`¨ '&ïcNëcn[ “ë÷¨¨Àlàî¿ìÖnNÿÀÜÁÎ Äü{fXE­á0¨ÀlƒÉ¥ w}L `þŸu™ó?×äÿ@‹ÿ# þ´÷×Ü¿÷è¿,ñÿvŸÿN­è…jÁ‚ÿxcê€ßÌs:B ^ÿÎýïžFà¿4þ;Wàc!d`¶Íàáäæù €¸(B<ÁÖÚWÀ}¬Ô»Ìì …ÀÀýSL7÷ß0};Èö»ôA`˜õßå?6éx.9m%m¶ÿöªrèA§Ë‚GPè¯íÇ9pÕ÷rþo:# ¸õ?¿ùdeáž^7Ïãú=*áðû7¹ÿñüë¬tu†x^psr?Fr~ÿsÿÎýOÀìo4 0Üú÷äè¹aÖÃöOÃoäæìüØã?ûÿxýœÿŒ=ì a.ÌÁAb¡ö™9Y® Ä£ò/z{xœ*Þè—ÖÁ»2#×Dj,ïêÃ8›ÇEµyÍî;Ýoª²n öA™ºÓÁß‹(üèX>ã.3v±ms™W`gÅúϨ¯"› rn­êèš—ß¡RŽwð9£_²Ò¹Ð_8=óe4%v>oFÀk(Ù?`LÙ½¼`êú4ð±ûåÃ&9[~ƒ˜;26cLà«|r)Sƒj…×Íl(ßÛ b¬Å7ÎßÊçÏVð™h9Žù,¢I‚°RÊ• e®äß·RÆ%=²ìÙ êt›œ(†Ì%³LÇî)®Ž>1Ù¥‘„µ…^Ñ2¼éˆO£Ý %õ‰>•pjÕr{2–ÂwÍ<–g¬™-j—!3cäáakIè,AŒ$ÁLˆÇÆ‹J¯³nöùU»Ïm›Þ‰D3 ~"ÅVöè=”Žòíí`õ§ï3t;k‡–Bf?õ[¼„Y®¤¾ša£„+gl’ft]ÎB‚²w3ë‹,£ªˆôkêyô’­úÅ>¡ï„móW¯µrÅý¼0Ï”dË#»§BЏÝUJàžuÕñÆIÍôaòÔã·×¸§ ™ žL¦€Ädô<­cË-8àÒ—£t‰Äº4ú£|©D„¡¹šŒ]¸ãÏßE¯¡>ÓR·9xyôöŽ[Ìï`º~ͲûDœ¨'ˆº5e[-0GMÓ=KÊÊJþ&â&’PøS¤8ëãin,õ 2PU«r`ZÅÄí¢v8Q—ÁèÍ ×ë¯oã»o[2ÝO2Ó¾Ðm/Ÿß×Y¿üìvV¹"_=5Ó›é¶è áaÖ™7þv|g “y×&"YæЖ(¾+ÐMoûÁ|°>›à¦± vZÎI ÏW´Ä%^‘›üˆ¯­Ú]Ö%½ZÆÁ_Ï@ÄRdçÒÄ9è©‚†õ‘kãC¾¥HzõOlnÕžÝÍà™>{óbÙ7U^|ä-)G? 8òÞ¼x“mì¾%ÿjã=!•š[žž;[#ÆŠ™ éJ©/A%Ñv–µû`éióöíØœÇŒP~^z•çQ•7˜¿\扯â ÈÛ.|âùúÁèéᙪ9 x°¶`÷V¶v™öÉÝçñ–%®¨eßùbU€|;0}õd¯ºGŠŸ¡*ºS{…Oi,ÚŸ‹í–0M¾U_jL¬@qª?Ôªuo›`ö@è­Åû-€›-0Múp_ðà*Kþ*š´ll´8ðc©ïÑJ+cCôcr÷®4$G¡ŒÕ<;i¨Wi Ùªµ‡ý^gµ£¾ÕN!Î*{¶£ô…ÆW5'xs ^ÅÍ&o`Cð¸OïŠPÑ©4e¼BÃ9jÝ’N7t’2_M´Ô¢äÔ¸/\ä_‰¢{\”ñw“Ï‘qú\®û7«X­”ƒÞAÁ¥}Æ ¸È÷»Œq„z`²\F棖ûEœ!~õT¦¾\Ž'4/ýCîe– 7,î9tãÒ¾Â1 ¦’·IM^y/¢˜kIm;˜¨½}O«•oÐHâ•¡Ç6—]í7ôh`† J­TÂcweófœkÔ­—ÕRÐÓ(9%Ö¯c Ó·_Ü€¡èüêr_7ýGmÔ&œÐ‰lÞÆŽ Kê#TðÖ†§øñÞ ¿šûDE&ñžËœ^QH¶!’Þ»¸>àáÉà̹ç$ÚxþF`Š×Í4IŽ@N@ÒÖ>_9²J¾ÃEúOêá˜/kIÉu~~¦r–æw0§øF¼Öë!ÅÞÍ<-Ñ:yLj]óC&üwÏö䟃!•“®²h!¶‘6òÕÝýOÒÑéÃVwc1Ì{õX/MHÕ¼“øÍT(¯m­)5~Þ÷ú?É6nðýYº³`æj¶]`.Ò’·Ã‹imzdëøjXJ[”˜OX8wâê^ÞÔGÓö†^& ÌèWZGÅï] ðÍ}Ù ¦L5«ûrkÎw¯C3íñTS‡n‡a†’Í|­ïDÔR”ˆŸÆþÚgòý·¯0,‚…þ«dñ6›ô@‡Úò ‹6~ƒ uÿ'¢µ?s_¯Ð‡öÿŠ˜'u BêH—‚?ý $OíœàÅ€DÈåìØµö„÷¥½O%©4žñ­¢¯‘ÔðQ±¡8M”¬|â ãhƒÂ!ãëaž!ÉÇ86e}YÐ7IÏWë]¶Ž`…ÏÜ&ÂcD×rZ‹î”…µöíòj—«§ÐŒô6ZÑóÉÎõ»§ ÉDd߯çxãT  4ã¥éÐ|ùw%h± V–¾tf°‹ðÃ/ùäanЇhµ•]ªU•²ÆfÑhª¥Hm9Ôaêëô¦É’T›À…á/‰¡øOõ£èî.êš;{?W›¥~#ÂÝGÂÚM†ÑÐuEh 7m[E†lûÌì’ãÍcT±ˆU,ͧ˜¤÷Ö„½wú°aV.¯4žg®r ¯R«©*˜"‚¶±ºž¾<«0ÛÍÊõòÂh„Û‚†½z«Ã÷îîÛ²±žˆ©Ë_>)FMÁ¿EIÕú®´ËRÉs¡bÌo™ç-:ƒÒìXÖS¢ªÈœ‡(2³Ü{Y¥1³$Ê&?ÎIX>µWÑЃšÍçnPÊÉLÇ@¼¦‡2—­eýS¬+‹†^WD£gu¦í÷ùBü]8¸ïOÔ5mVl³Õé”VË(¼ÛmN^nml ÷’ s ÊõÙ±…- ™x³àiΛ*µ a1ןáu«+@Nñsâ),#Gu-/JÕ¥[òmš¬»º_ä>TÂåg?âD"gCó5®™,ý’ «gº%q\Éw&áÙ¤Û‡ø=rM±‰©þAÓǯ{Êò¾fņWÛ²%§›s¶J¡üêí;7¥ÒÂ"¡äÉU’wlQ-OfÌÚSá\Ð*¡BI:àà¬e’,Ï—¨xF)f‘ý\0l±÷„½Ý…ÇvãûÁ‚„@>:ûY´ÈÃ÷µ[e|&.$UÎ;M“íj¹ª_¸=*Þ äSó«—M¾¾rµøds‚ïP‚Ò*’÷Öåß `2¬„ šêÁT^£„J’¢¶¦ž¦Ÿ+õ¦ÐÛc8ÎÍ(¢•ÉÆOûX™rZu"Â&U =oöE±êPy*2ßî"VåÖTú•¼Ðc&úø¼-ÿ{ÄAÊ+jV•f³þ¥œÃš°8ãö©Ÿ· \b,>ÆÜ—(hwÌ©¹û†}ÞwW#3?¸šn/fƒ´ÛÇœ¥Ÿ— ˆ¯¼ø–HÕ‹ ÷S+AL—£vÊÑQ†¿«l0v^£žÁJIL”½}ÓÎß>ÏØ&é(üôãIßv0Ûu îò'+¢gôô÷Fvˆû§BôYO ­g©qq¯Ë+ä(ÖGb›‚±›Ì¿xê!±ùÒ‹§G >C{(©¼Ê°nwð,K ?EÚ7þBq&‚´”jɸˆ·?è¦ú-ŸCØüƒ%¥uXcýøââBïÅ ´;ÁµÜ3höŬ ¶÷Ét(‡„šœì :î´cØ¢>:ƒ‚¯úò‚#ÑǤ_VItSÏ$ëŽ`ø~"ÔܲÜr$ŒU–Y7÷“ø?¢ê¹iâ¯ÉqÅõãÏØISª5ñ4Â…èÑb“EÝêÑÑn›p³ú†-.ä‰ìošå•Hû~B»ÎÂî‚T§Z§Ï_)©OqÓzèß÷>ë˜Ê;­dpI¡rr1ÛA öÝPî2Pw]¶u¢èúä»(£ý/޾ªˆ§þßÜ¿~&æ[1¸Aé-KžÚEО5JÃ÷.føzßwi°h“bLñB³ß6ˆ^ñ*£–—qº'À°´TÈ8‰ÂWÏõ—„ãŽly&V¬AÕ²Kò^ˆâ½þÅY;/Vwúí}<÷Gc…R“#]›gùDÏ råV¥k¿½p¾Õ¼¥}ÃvGšAÐg•†7PöвS ÃÐÙ²¶©HÈ  9^©;¢Ìœp»Ãm%{r7E•€ÏŒµÂE±…ʨ*o,„ó QÞúʭ䦀(ô$íªy{Çgk9©‘5Â1ª0Û˜F3ŒÛ!s0¸4XàŠú#r¥Æ2á\8nqå°Ãs}䮀„s–è5)q…i¹C9ad¼¿`u ^<‰2@´ÄR­×$âÆ³—xº>áÈïž¡wdª‡}Té†×ÎÂËõ€Èøt\1Ü~‚9 ÿ½8ia D9©ì"Ð!gÑßqÝ ùA“ׯøŠ‰§j_dI*¡ »]‚ÄÙªAÓ8ﯙÎd@Iî?_ɽŽbÎJÊ8&1ß’bçy·ÌJü®J_ƒ|¡iïÂC®¡L;¡Æ–=x8"ÆÝù\šGd'—®®ðÖ/B¿ÝÞpRÆ'µsñX'MÂÁd;ŸäÕEûtGmý«†g¾ ¿¨öùWí},¾Ï†Ä›tÓk„fªõžÑ »›&oô/L¿ÇGìü²•âBZmÎOw݉Úñ¼>–¶ü^ÝvšÉŽHk6Œ´­¶DM0¦›}Öda'¨šßo·é˾xWp¼311ïçdϘ9óÅ­Ô§?¯jò>*§¨¦‰Ð:’-+X}7¿$ÏL\œö¦nD™ðì¡ÉX˜vWŠñ=mç¡|'M}„ç‹çÄ_’øÏ£÷rci%Åës܃ ¨ÄÏ,n±±ˆ" 5Ù½6ìÉ6úQèÒõmެöó–à+q®Æ¾ùÃ$ô|Òî]¾öÒñÕäË&æèñ²€Õ„KfVº”DfƒŒåZóbúä`#öZ·<Ò_Ç÷-¦ªÏôª _˜lg˜¨Î>«ŠTÂ70¡ðW~—ÛC!_ŽÎr¦x‰|„ŠúNx‡<7M–/&×gaÅj[²Ë±‹4—À¤ÀÖO–|¾1_JSw{ðÐıDÃP~ÜFY­Yy³]ˆ:¬aÔ_|žjÓM+ý­‚0@îhÅtÙl¿Êgšê…µAbDå·Ôw¿þ}ûYÕ×iîBÕ*jòýZö˦ÏN’FéT/Hn±úÁÖ“4ÑOEìØœz~Ÿ Þ88‡á ‹w|q£ªšîFªãÆÇ TT>/5—䬽%‰”dðqÚnCÃ%Î4ÃXDmeß:#ƒU¹Ø•l1~à 4±GL§%ÕëEЈ®ìÒ\;ãÛ8Å+§êJZdº×d¡K©¡ZÅIŽf3zV#W•c[Û¡*_-߈¯Þ­—¶5k ª€º—,ìd¿»Ìë÷S/úò¢×Ž Nâ)uóÒY~ ]ßjÑ×Ù˜fšuž²K,tÊ÷“\'gy¿÷5­<TÏ4CUMà£Ægÿ3Q£8Nð²Ã‰ËzN5\/MØr®]SÝé}pæ§VD@™:]¬ÔË7>1ÌÈéC•'ÛEÆŒ!…Ù7aVì:ASQ×µ{|ãÇj9YÈ4Ö|m Î·*_íw4ø!D1 ñX¿Ù¤X•³ç t‡Í=žÝbóÆÃwî6ß"£“˵?”JËOP2RÐ oQo+†â1)©w†¦ÜèådîI½ÈZ¿VÍ­(e÷åû È"QÔüFØs(úF$'‘qL ®/¶!õÔ ¤HvkÖ‰Œh¼È‰¬ê؉á¶o?Ùa:Šÿ±qêcŒ° gã!_QÇ~ÏWê¡1üaœ¯UÝGmã§Yñmn%ìRãr9÷¬ß0qˆ5†/‚E…(êÚ“†,W‚˜$Ù½ï¶åçLxËÎÔ|ú奕£w†Z|ÂV€ãž÷,éOd ÞyŠGÝ ŽÎ¨Ý3lÍ4©¿Î\×T2Zª½Ag—.7Ù#ÏPæï™v¼eŦQLÞ»±Oþ¼Ô\’ ¬ÿĵJÅñ¾(š3Ç].Å*,MÎ>ÛBx(ÃSÃó|D³uû‚Þ¡ï†{:Ò‘Á¨2G9¡Cê{É•<|?ÒK áéá@F)Ø,êw÷ó?È ¸¢Ëa„Çh%Ù±o^Œñ{‹6™Ý @¥-«ä%Å~jÉwXjz1îi´·î¬%uÕ3^¿±g¸`d+ÎK[ŽDe—„]âò†YèÖýÇ?Ï>£³HjË,èkѸÍhÔ8Š” ™v_Å [ªJÖ®²9m=·âú?\‹k>¼à¬‡¤*³Ñ³ž,Y ê<‹ý¹uÓ Z/ZV$S·é#ƒmNOš¨5M@¿§rãÝ0Hõ7¬&7[àçŽAØñêOõƧÈêÚ5±pE6~d»Ž^.x¨T1¬µ¤$£Í7¿ÿ4òÆêüj§‹G1¬èípoóÌ3³QýÐZ:œNÍÆéç,0½‹ЇZg‹ðâ£à)‹Q©¯³‹X""œÛÆ0ÏÁ¾äBvFA‚)Y9(ÎYÖý…ì¬S…|¸Ôü¾“qbæÇN.LÔX§…_ï‚¿œ%%½¥åŒìé|°D>W²7}C–Í#—ZR¸­$º`bÛGο…a¿9gÝS%\”Á/œîñhC|?s§ Ø…šg¯ÎÙÈ)ª¬m}ÐvÖËk†Ÿ.bÉ&O üõí+uqfº`Îa‡„°£â,I§ã¯½/‘˜÷ÇÝ›Á¤'P6ߢH‚Ú?÷›½šÙ¹˜Žà9¦ŠmHr7:pMRYŸ#£ 'æW¥¿ðKCß|-¡mWÝ躖ná²¶Ë0–«ÞÐ3äÛÙ=j’¸Ë-,n–³e±€¢üb½iÙ;‘˜Hâ°l<)žL.ßÐYÖÿ°Ú·)wL=(‚Œ£± L|)=å'ÀÆ-Å@²öò¾µ<ÃNrä³6îµEôʃ3±d¶kÓ»¬ÿ‹%ôµøü·(kD~ô(¬_yñ‡Í; ¯åä²fùOî{&*‰äyÒ¯9ÛB±T¨d>è.òY[a-³ZyÏ•px9ÝØÜ>穾„»*|,4°ç Žð=Ï añŽ©{ZwLVqžCÅo, H;ç_7Gg[åGx d½DŽ…*~ÂJSÛ/ *ûÎÔF‹µëújQ‹jw Ý]_-Òq;Œ,1t³õ2ߥÆíËòê{:Ö§Ùo$<×ð¬žôôJ©Àëóüλì„b›F=ÍçåcT”u;ÐuË›÷#³»Z1q“ÒYÖgHŠ^fiyv|‰¢,PkŠA±¢FH£s^…EËRôƇnQWEÛt%Ú·y3™{æÈŒõFbKã<%Æ)â"-L+{墒zS'“#é²ÊòZÃ+•÷U­Á׎#Ç©ÃCcæHŸ,êä;÷=íÏô .óYäg:¯jÔn¹¶Æô×êS:c¤¬UºW¹Þ/Ëf¹ŠšcO¥ÛøŒM¯lD‰Á¦9²ú:­ÈùÈßÛ˜ìÑËr6½õx§ç±2ú]úS¹‘ p7O¼,j1îöÐËÚ{ž$ªS7O–xYŽróæs÷â»ì(è˜Ýš‹ÏD‚@§­Y#žC²L%¯íáž›1A•ø©3¾~M+ÖAîDí>¤¶¯cãµã-Nˆ¥”ûÚÔß ÄÖtzâ"¹tãØ'>(˜“”hSðÕœM]ˆÎÛ…0ìŽ ñâSPÓKD³—dOj nÌó®|KHtÞ‘Ñ+㢟S'÷@6„iõ“¨C,÷ág3B½žpÖáΡÄêφÖÑn‰Ü;ɦc“ _7T,Q1çTiHøBÕWL8­¡¾  ,œ²£.±ß u2†)¶=–Oš ¹ÿêÚ´­Ùê², Aq¨¿râ^T!1í¢ëç2)áN\§‹¬‚)æÄËR…Ëbž÷ž6Cb5ü´çêÞ›Ô;ð¶¹mH“üÅL¸^Ȭü¤Ý¸Ê {>«m@Ë›ðzéN‹›´×»ÔÌÃBÿ]¬—š@)õp[jÊâá…6ë¶¡²BSHQø×¨.öØ«N÷Ž`ðG¿§zŽ^n)?ìû±«892ÉÿxÈÌÄ÷Ù%¼­Ø3ÕÎZJðô]\ÿ^¸Äé„SXA㣅¸r}[(â0Ò@¥elöÉmi¶ö­EWÕ9úQѲ´ˆC¶Û¯µAñ=°g>MF{Q’= †*Ëk¨+™×Øõµk¤i@ïħÕW:x<›ó"Í}<=<²šC½Q¤4Æð÷i©UµSöA-ÒiMÛk×qnñÔÆèO“¦R<)D¾€÷/ÇT#î¡ÍM© Æ$ÖžåÔ3³Ð¿Á¢\ç{Uª÷Þ<UW=ˆ$®&<ƒªZ€0óØÒgÒR*¹ÉÒO¦1‘'£ùŽŠj*5wË-·‰ûùT j4ÝióÍu``òh߯µ“K…ݻʔÑk‡‡A›”ôÈÔDôìtk¯ö2ÅÛö÷ú—¨§$ÌöZ¥ï@Î^ùÝêõ^E~§”Üúí¨u4߉<*ôޱ§¸KJßùy/žn•C*}…ÃåLgI£J·8jŽ[“Þ³ ”ØT7%JÈOïä,Á!ØžÈ+ÌÁ¯f—ÉȘs‡h`Úq¢O”1£<ƒ3(©dØOfBOŸ º'"p=Q£B¿âäpJ}ÝØü™ŸZ®¤!p{òëÈa}÷qÑ¥³äƒ£DKXôžòxÇ(žÏÑã ©¨“{ÏçÉšj¿dqX·ã·ŸP¦Üv£ä£Ï€³i¬¾AÕ;³@øyŠ*œoLœOœÕøë…ú¾›ºxOÛÝËc -@YšUʳªø;žBiäMÖð.•\rž;ùU´¾Rø'î…ç)眄š˜ …@ƒi/_ A®ÉéÙêr«0áFx<×Er;¾zÇ´UÏšøSÂö²Ù„.¥mô÷Œhâæ¨É2Ø’ç/{I;õŠjÑm÷¬ *s"}Y ;Ò‰¢ú{YÌÝÇí]p¶Òݯ€޶Xo³êÙ}U¹ôZø: hÁ‚)8f÷EµÔëÛDäµsüð¢ qTMŠ:ù‘ɸX!±l®ûÔ”Ëû ΄,ñº17ýbŸgûŸ&fܽ×Y'jeAt ]ôÛïwV^þ%ÑåµÛR¼”tμ‡Ël¥¿é˜¦j¹„‚øÏ¸3èm>YjŸÖCƒÕ¸ÄžÄÈÊjbÆn“ªŒUý©?ô‹ïðu«ÈÃWøìý#ë,M€¾ߥJBQlމâXè-ebtxÃ]€s<—ÿ¢:XÝQ…¸w¶²-N;N¾?Vl¤‘vG‰…,Å%ë9êçöË'bìη9|1.…±!]¹¶DšÏó=RԌݬ¤Iˆg‰=Åh_ìŸ5rÿ/˜ÿŸàÿ  tv…;0ÿ|°õŒendstream endobj 2316 0 obj << /Type /Font /Subtype /Type1 /Encoding 3111 0 R /FirstChar 67 /LastChar 85 /Widths 3112 0 R /BaseFont /CEPGEP+URWPalladioL-Bold-Slant_167 /FontDescriptor 2314 0 R >> endobj 2314 0 obj << /Ascent 708 /CapHeight 672 /Descent -266 /FontName /CEPGEP+URWPalladioL-Bold-Slant_167 /ItalicAngle -9 /StemV 123 /XHeight 471 /FontBBox [-152 -301 1000 935] /Flags 4 /CharSet (/C/D/E/H/I/O/R/S/T/U) /FontFile 2315 0 R >> endobj 3112 0 obj [722 833 611 0 0 833 389 0 0 0 0 0 833 0 0 722 611 667 778 ] endobj 2297 0 obj << /Length1 1630 /Length2 6133 /Length3 532 /Length 6981 /Filter /FlateDecode >> stream xÚíVuTÔí¶VA!¤†”ºQº¤»{€!f€J¤SJº !¤‘RBpé–NI%‰‹~÷;ßYß=ÝsþºëÎZ3ë÷îgïg?;~ïFZu-Ik¸%DCrpsr‰€t4õÔ--¬¡pe)¸£µ"ÒÂtñ¥]!H(&c„ˆ€ô Ö ˆˆ‡Ä-,, `Iý\¡¶vHó  û_–_. K¯?‘›HÔbºyp‡8 0ä Åÿ:P !í ¨#$­¦n ¨*b–WÕÉC`×›"ÔÝ,¡V e¨†€°€là® Ç? +8Ìú«4ç —$dB8C¬ 7aO+ˆó/ˆä qu‚"7Ï (dëjCÞô AaVŽnÖ¿ÜØmà¿9»Âo<œn°2u8‰°r…:#A7YÕeäþЉ´³@þÊ€ÞÀ ¸Í§5ÜÊíWI¿±ši…!@Hˆ'òW.KÈŠpv´ðºÉ}Cæì ý-à …Ùþ¥€ä ±µpµv„ 747Ü¿ºóW ªÞÂÙÙÑëw4ü·×?4@‘ˆ£ '€›ç&§ò&·-ÿZE˜ ÄÍõ‡ÝÚÍùOÌâú»AÌ¿v†åF„…5æè²†ØÀªpäMJóÿnÊœÿ¹!ÿFüðd¼ÿÞpÿ>£z‰ÿÝ÷ùïÔrnŽŽªNßA ?ï2è×EúuÓ@­þGŒ…ÔÑë_EýÝSò‡Ô_dÇþà–„ÙÞÌ„C˜Sø+!õ„X«C‘Vv  Ç›ný¶ëÀ¬!®ŽPäfª¿ âàæâú¦mµr€ýj?ÿfýwí7ƒú­,¯¬©¯kÈö¯o×ß¾ê7[€Ôör†€þ;‘ž Üú‡_LRRpO7· ˆƒ÷F7— /H˜—ßç_dýMÄý×YÅé õqqrqqƒn~ÿüþu2ù,Ì nýko´0ë›Uû‡álåæêz3áßoÿMáž/=â ±LOÀ­DƒíS3ÒUä9=ý2F:¸1zBœ‹k´_çûWÀÛýRÃ…ËÌ/*C8kE®š¼Æ·/W•X×z;È·'Cöò¨|èYÞçÍ3½d[ ›ã§}Õ‹òÞS^À4àÒ][ê×Ð4-º¸|Ç늽ÊâOïžïOÊpâLàk•òöÕƒÂÚ[ÄUÛ_™6OOwõ}ìén?¼û~•’-û£¨;&>S¤¿K6åSCRÙò·ª·ãòŽXXðð+yÏ—×ro1XçFèÅR61žêDžeâ§Á ×^‰mùkT³ïT ¥ØÜ KCvá)µKö±éû¬l´¾úï.ú¹üA¢IὬ}‹xp—ÆÌ:…x÷dlt×VEæ¹®ëºB4ߢé:°h`M$z¯=Ä*óù ?7l &?QäÔ…ÚvÆ<=yÊÙûÃ㎣²=÷'ºçä ÄAŸßÊ}gw‡U¸'b%6—=\5Æ„¶O€X)Ô| 6*˜Ö}ØŒôDVs§Up ˆíbëÞ­×…+Ïo_MX`êÁWÉC.Âß6¼|í½ÏÊ)¥2ÉP0–b®G+kGõýZŠÿåÆ~+`çÑáËé#™~KˆjîβÍ5—‚ ÿ3zë5½ó-o'‰ŸžoJ| öñ Õê…k¯Hî÷’ô¿/üž“â«7Rîõî°F˧€NÚ´…”QOÆYÃÃöLN߯e‡··Q&8LëÀ…cÙ Õˆ€éëèqo£F‚®ºqG’*¦²óà‚‹¥"ýbmÍHàv{(Ž?ªÍü-ë&wU¼m_A±FÀͼX[ÝuÞ80+l8]ò)áß½WMœ½RY.þä© Èóqº:Âo£ù¶ãí•MÑJôßY$‡‡Œ’`$íŠN î÷Þ×ó¨‡caíó )¹ óSçãa¼&ßi·õã¬P2ó§Ð„]¬ûãð#l3oñ{´„îªÌ ÁºqÙhiµGH‡:!F[ ŠcÙX±¯Á,þÙñ°“ŠÊP)½±×3 gwµy—Þ)¥åB¸*!œˆ—ÕëLwÑÔëe5íÕÄÆú¦d„’ÅÙ5jY®yr!Þ8RÖwòd€éî¨h:³ìç” Œ”´¹©¦úa!ǼÆêëÝSY·ÊhHçú—J§=\½ WšbN,8‘T‚Y³0©ÝZH;V$Ìëü›HÙñÙÞ¦eÊgTr>R‡>Ó£*X¿l WTh‚ˆsÝÍötº·)tÊ`D"ŒN€d÷¶kÅŸ×Ë)~>;ûHé¬\ýÉò%Œæuj Û²!>2M¤ |N¸»OŒÀ¸Å~Hª´+ˆ#Å"QÒ µl’9’kСA}S÷†né^W©]+žSüÁèû³,>VsIì)Í’©^ cFièr}Ú]ÜAƒŒ±9“"³ºÓÜö1x«ßiëÍ‚5ÃèÕp:¯©+Œ*‚_øˆ'û´”eÞW1qáÊã»NÞ`Ðß 'é »Îk+ñKÚ+ŸQÉ8¤¿'u l(-V;K!ªÆ¹áK‰IúäUW‹ÇtΜ%6QK(ŒžJAÿÝëáæ…\™F{3dk*ƒA¸Äg5’òœA±ë¥ÙgwA•,Ï\÷3jT¢÷Åɪ™œüRÅy÷wF#«(Ùá²Zá”Y„FÞì¼\>LÉÈäAÝ ŸËi6ô¸ý•dèEͤ„ o€8qørŒ0m+êñûƒkŠ a6u÷} ÓÁÙ&Qûó©„rìî:?†:è ù£ÜÛõŒÚGa¾Tµ ˵µ;¥¬W~òn+–lO­4 o¥ø!=ËMS¸âØ(kb¡,D ZÆ8T'p—.ø;2S•cf‘¦>dÇvË%·*­7 }Åçj£&ã—6Y”«Dd¥×VÑà›lh`2爙0#·êZ=4í%牵7h%Å Y$Zü¬ˆv±?‘©‡É=áមð;Ïcc„—÷:IêÖá°5ž’”ö×yÇUµD2>ÃÙ}ÐŽvk2š>2òQ× ›yôASLPkQ¡âZõ>×_À ZŒvR¸pdÎ& QºÒàî¯E¦âx|E&ù'Ar0Ëèh" ’çÏvÙý½Ï»ÓçêßV¤0²iRÂyO„jßÌé&šH¹£(Âμ4™ V1-S8`_3D ÝËúÅ7BëbØ r¨Ãt©aÊÓêØº0‰¼•5ï´ñïâ¨Î)9É@[gbL¦')Ä?Ê„ãÐ÷*éT“꟱Eê+ãIõ_â‚R§—«·>noߢiŒ!L½<©35¢$2MIÝs™ôäu¢¨bâ8 ûVÇÌšDT£ä¶"Q TFÉ…Cóuø9dcÝI¥Z’f@A »<¶ÚL9’00#†ô}à…ê¬ëè¾>€à)†fbˆù†7sÑ¿×ÀÅ}ä׊³ÒgÍ¿?FІæNP˜ké÷2è´à2|Ö§™¥£[¶WDMåtè3?èù:28¢È;Xf1S§³EŠ$´×å0Ä0d—5ŤÐ4|ybæ)OÄ|˜léË@Èu±}µ\"üSÀd5ŒÃkùp ü3ʇ×Î +˜^p€&9I‘òÝÂcJ-Ù.Eâ.ÂÄSL”„Ä`4œÚÁ¤7\N>frÖi¼ÝÏPüTì,1êÈ@^'èMuèï\ ékJj§^ æü12Ït¦ˆLVéøŠ>iÜ猆ž=ZƒÎÈVO(Îʾu™÷ѶÏÐÔfh=}̹öm{âý”2¶£ÆI±»põ-¾¹+ýZC—±­ËôKo¹‰nÞ”×|ßòË?mztÖ9ÖåçÄe/°¦Õ•äÂúö*~”2è½ÞQšKþ´$Ï*§ú·æøšÿ]íùu¢@ñÁâ°ÆÈzúçîߥnK~£ÒwRdˆµU ”kx±saóÝÒ÷ÁÜ÷Kk ]ö¾ô3 ·/*ÉmÌKgƒwõÇ–ˆýIô‰ù¤ŽòŒ¿Ù=a£ïe€üvû# }Llb9_ÚEƒˆÓFHRòæ›=ë­GýTùH:ñ9ˆe¬ù6PÃ%BÒ§4ž£Ò.n+¿ƒª°ÿ9ÌèÙïc‚4Ã_gÇÓ¶ú‰s+>傹»˜‡¬9,Épª½è!׉·ïhuF ÒiU2Æâ-A6L;iY­"Û ±+hô3…RÝOïi¦¹Í —Š‹ä©ˆÏHžn5÷ò”JDýÉ›³¯pôÝÞó4ÇÃøJ~t‰•|§›19äÚ¸N±)¸}> ˜5.¶5Œ¥¿þ“ <ö¨õëGš±×1{!•Ųê3‚A-üMÉcÂ[ ×%Üû/¾¶°½9oØPO;fiv±}½•@ÜJ#(G9j>2š?¤Æ ñ?~ªÑWåïBç¡ÛµO±B¥™Ÿ†ñúÃ&e“v”3†­ÉÞ&™<)ïÈxbý'.¼Ï\Ì_³Ÿ±‡Ý'0þààõªckêUPe¤cne„žÁVó“pÜ Ê½ö>ÄÐ ½c–î3Ó5¬´0ÏÚEdÊŒƒH(‘©,ðÉôä‚Nnád¥,_½ù°/ä ecŽ¡ñ³b2•ßÃÄœ¯ît¸âËA".0mÕjÛ;÷$èÓ#Ó“]Q;Ò­vü‘‡¦ýO ¢Â{'ˆÈ‚1N ;$F_Õ~@Ü©Jw“+gfCš§¸Aëßå~üv»s=í,€–ƒÔÊ‚ü À† ÈÃñôß[Ƥ7œàÀfIŸŠ¿iÍPŽêb FDt¨%Sc<ØCÞ±‰¤_¥}#툎~áß\°ÕÃjC¾35𮾌ŠãÖEf˜ä÷q}ÔUp¬$Ú¿•×çyD*û*ݷ÷î@òQŒÞ7¬â¢¾yçã,£êìª%É0®š¹î³È6¸½}ˆŸ^½÷s®Ã´ÔøÛܪ{‚€79»#¼¸ùߣf²sË©W½ørÄ(€Db^Ð*A|üÙÀøä¹ª“ÐzÜÙ™N>uêתͲ, ¤Õè/‡üî¥IM€©*õO ÀgÆC”kìþ‡•—•ß×±GJ«€ŸVp+;çÔñG—ó±Ð¶"u¢»}e/—¤ÜbÎò7žÖ®Œ•0ð¥ëŠ[Fv7íXëÕ5Ì›ì¬É„Ac_ü¯ƒò{LEÊgL®ç'õÇlÒé'‹½6I Þž {Ÿ¯¬iëdºOIi옂-i©Š“b«U«B굦 HìK¹cÈŒƒ´úúipÏÈêµE[ªOâáÏx’"‹V)úÌZWïŸÖ‡ƒéüL¯Pã}<ÇY:{ˆÚ%~Ëõ( cΧçƒþCN…ˆ§tO&Žç„V™(7íuq›]©&Ä=5Þ¬£éÖZìržOÔ¯énuÏ)§†£9‚¨¢ß–Eä@Šz?»a`Yû äÄ Vnœþ˜`~i·R‘öÁc\Æ—ïî§%DJ^Ÿ£h˜Ö„ýΨڦ·.Jú«ùt…F^ÈòcXþ3OQ¡d϶0§,÷”Še&uùÙ¾ˆï‡OÄY˼zõ¹Wô,i9d•0nçvKîhQ"K•Q¾Zø@0M¨âÒ¤xÑRõ†‚›ÇŽ$J­´çwR0ˆ+Û6UÕ¾/שM”B®±XÆçÅÚ«'ªM]D›„]ÊQÈî]Ä-ucIg|ÇZÙdŽg>ÂŽï|ê™5È(ü…ëù®êè –ÄмÂNЕë4P“÷ÞÏîèÖ ‡8—‰$—ØBt¹úÑBCšÛöç™yxWûãz×±ÛýD0ϛȘÅñÅ„oJXOWi öì»×.çä_MàSgDd]ÞíR–}Áõ÷ã¶ÂŠ”È[¤«Ý†\~‘_ZÞ}ÕRë\à=cÆmï¢æŸH4Òn˜ ®/™Ë[ßlÏ¢œ\mÓŒ]Ë; 1ÐBVû \±–·´åµ‚µ¯ÊN*I"/ïm?áIÂÙNr©ä —ë?>}7›ùâžàÙZ˜æñ`kËG.¯–*O˃åé]®$£lì©VÌú‚§«/]´~è µW,=ÖÞDÞýQ C96­DñtÏeŘ'”V[ĶtûPðôÝûîú@ò$Æ.ƯúÅœï}ù½Ï *[7›#lUÊ[“|öÄcÃÅšgêDE2_¡ÃMÕ^}üÆkOÛŒäCã±åSPΟZc¯\ð̸™ð '-ÖÄ®1švÆeÐË“=û’Òk÷Óc½æÁ×í%ƒ‰á½: °C¹Ø\Ð`]“˘ˤ¦¸Xºr©·! îη¯Œ_‰_Tó¾ Ÿó/°Kê¼-œ [—¿çÃq-øz~Ii‡³®>ëGGÈF¶Üšqˆ‹¢À¤^Ý µºÜzœòŽLy*Ø!$ëȯ²È¿Äøý9Àõ—x»Ë+Jé.Õ­”÷yKr¬àKñnD$ïÇÇûùSޏ+¹ºfS4æHõ¿ÞzyàÂ*/ç%Šâ×»Í ÏØõæãmº'7]ìå±ÅöK)ØÑÁ@£b…î\çÑÄÝÊ‚×[g“©»U©«ÅÖ¡’v'¯ÔíÌ¥ºiMD?3AqÑgœ‡ ÊŸ¼ίªóÑÓ3NoTšv [YAóOL®·´MHËJ°ý‡ãĬí«å Ä\]NG”¤;F¸<D†ŽR›æ.MÃ>ÂW5ßÏI“1øi^{Ñz·ö´·‰¾¯½bÅ=YV6S$øqr,påÑr·¦s<Ýþº•l+¢dÙôú~«ÉR1xøà`äÛÔ€²K[å.Nµ;ãUûŒ2ó¾jÂÓ’D€Ì»«™Ï5o~"Çý'…|¤0i"í.>_0'BT¦ž¹{Ñ`IíJÓ(`ÌW¾­ÇaKPÓŒSÃ$(L÷8k•·ýAcc·òd3–âm¸L>b@”©k?OÙ#ün*3oÄHóÉÐàCíúd“GW;¯y‡™¬.÷Ì¡@Ðñ}“à¤Ô-´ý^½R¸'EæòÑ¡wuº>ó<5{Ž´€KÃ7®Ì[NŠpÓèªÉš•Q•Ýk|}kÑçc(?72•­ã»9 Òí¸FúïšyË«mn£°MWÑl‡ög2w™SçäSCþ¹A¡‰&вÈkª|3Ø`ê‡ÄcïÑ+Ó\ºŽ’3®óø‚ÿVŽ W$ÜÉÂÕð_^yÆendstream endobj 2298 0 obj << /Type /Font /Subtype /Type1 /Encoding 3111 0 R /FirstChar 66 /LastChar 78 /Widths 3113 0 R /BaseFont /GLRXVZ+URWPalladioL-BoldItal /FontDescriptor 2296 0 R >> endobj 2296 0 obj << /Ascent 728 /CapHeight 669 /Descent -256 /FontName /GLRXVZ+URWPalladioL-BoldItal /ItalicAngle -9.9 /StemV 114 /XHeight 469 /FontBBox [-170 -300 1073 935] /Flags 4 /CharSet (/B/D/I/N) /FontFile 2297 0 R >> endobj 3113 0 obj [667 0 778 0 0 0 0 389 0 0 0 0 778 ] endobj 1558 0 obj << /Length1 771 /Length2 1151 /Length3 532 /Length 1711 /Filter /FlateDecode >> stream xÚíRiTSבª¡¬2©¤j=,Œy5„„! £ soÈ-ɽôrID¨¤*Ë"6ºd¥Âª"P”Zb^'Ò*Â#,ŸEªVEÀ©¬««ôgûë­wΟ³¿ý½¿óMs‹”1D¶ÆP‚Áar„ P*•pØ€<³Ù-‡å‚¡ArŽ@àVkÕ€»°ùBÞ !O¡@,]#©*xÒ'I| ÒÀ8¢£@*'T°†¬¡« S 0¡g‘Z ÖNÞÈká Ï„!&…â À8A)¬IMT‰þÒ¦¿MeÂx) xLɤR$„¡j=€`%…‘Ý`RË?!kzñ`­Z!×L–Ÿrê/y¹Qëg`št-ã@ŠA0ŽN§ÆÂoÄIaÑj¦g%„\(Dhª ÎJ&{åÉFt0‰ PÊÕð£Ðt%¤S:X¢ð‰(Äó÷¯JFÊ”ˆÒ§Ã€ý{*æü“&áˆ$°™l6‡$’ûí)iZ31ªÀ M\žã¸\O!‡ˆŒx ›‚uÖ‘ŠYL#È+€t&(1œ2ù¯^lÀRÃ“è€ X©“³Gº7‰ýõi˜.›±‚ \ÙŠ½ÒðyìÜ?Z‡Qbj|HƒÞÆJ„ô†u°‚b¾)|¶|¼÷Ô¶ÚÙ¬ŠáÄä—ÊÛÛÞÓØ~׼ؒÞäùàG÷§w2ÏÙÖ‡ßãð«¨#E3koÞxù8/mcg¿ÙîKÈ}¨”’T~:|óß;ÅW&î‡`Õ˜¹æÒüÄ}O_™©m·{ÒnÙ†r©Íu£ï‹9lºN9ÐIáìO[lŽ+¬– g/ôºSaVïûºãüZšÃ¤¿Ìì¦ ÝŒïöH rKCc%Ñ£ ŽV:)j¨}Cj¨ÖpCÛºVz¡ÐÒ°¦À)­¡‹ë[ÂIoÚC[›2þ’öë’3Ÿ$=Þ÷ìµÚú@‘ífåz|F¬§÷~ÿLÏaz›j{õ3“[¼\õÅ]BäÚg·ÊЮù·ÿ@N˘Ä ®ç»Ü8ò™»™K¹'×ì­ø—tç×ͦ݉b• þ"úá@Õß/¶ös“ƒúRÎDÝô¼T×x¾:ȹ®pf’©98¸zIól¬w0`¾›ŸóBŸ¹¢DKPí4_èÑßWÍqâMŒ/:&ô:ÐóÂgè‡ÒhSÓÈa¯Ey¶C›¤ídÞZžíý‹Í¹°º}—wÝ Ó÷ó–í…¢rkö¦« «Ý¦Ñ?ÌÙsTÐðcS‘sö‰¨ù;e9^ ê=Â6>]No§­¿\÷ˆp(Ž|^•ÂÄãýÏ´¶¡8j9>žÉ=óÑzžObê«¿ÃkÖdïÚøàÑÍ•‹¶¯§ízÔtñ§¥y¯·Œö†híÅÍ fôîQãíïûÁàæ³µî¾q_-õk¥ÖŸÿÏØª5 ®£2*›­Ž÷,²˜ A-Uš:äb¹ Oõ0»š¤ÎßJž¸¢¦–tö`‚vèå‰êÒVž¥wÕI/7"|¬JˆÊ–JN©—[͸=sìq©«å)¾éÀÕP~cÅNÈÿVeäºÑÊ ß;ÝÚ|çË#E?^!UJ_'Èö¤ÌWféu]󲚻Ë8Tè[N”ý9÷‹S†¦MVóðI$ôµªcÛ5ç+¡1öÎæXŽûìH\gÍ»¹E«©ÔOPÃÒú1ݾúÐ2Kÿ‘³¢ß/4Ýñˆq-—¾²Ž©ê°.O<Ä:5)š »/T•Ø£ÄË¢ í·’7¯–Ö7ße·sP•SÒ=·°eÖ›~ty´,SVùå:¿sü‚̘³Á¼~ÿ9ߺ/.VPrbqÍÔ»âÞМgþß½½c4ºäqìcQás‹ªï´wE‰dør—èfÛnZ]·º¹¦¬p·tn­ÓúwBu\^uðÝÕQÒÁû¤}œºŒxñ*áär—¯õ)Åœ ÃÃÖð,=ÜŠÙGô59µû3óóEeÝ×wލ’;¯•çÿ„FË©íÕûæp¢óY~í³ðÅ›Y÷>¸ÿé7)5üÁ±óâÖ¤«½Ÿ®ÙÁaNbÑ“ŠrbUožyÓ¬ÈCÕÔºöß\”ÿøŸ( PÃrœÀ4r<òÎéŒ|endstream endobj 1559 0 obj << /Type /Font /Subtype /Type1 /Encoding 3114 0 R /FirstChar 60 /LastChar 62 /Widths 3115 0 R /BaseFont /ALNIAG+CMMI10 /FontDescriptor 1557 0 R >> endobj 1557 0 obj << /Ascent 694 /CapHeight 683 /Descent -194 /FontName /ALNIAG+CMMI10 /ItalicAngle -14.04 /StemV 72 /XHeight 431 /FontBBox [-32 -250 1048 750] /Flags 4 /CharSet (/less/greater) /FontFile 1558 0 R >> endobj 3115 0 obj [778 0 778 ] endobj 3114 0 obj << /Type /Encoding /Differences [ 0 /.notdef 60/less 61/.notdef 62/greater 63/.notdef] >> endobj 1547 0 obj << /Length1 1199 /Length2 2269 /Length3 544 /Length 3058 /Filter /FlateDecode >> stream xÚíWiVkŒ5À 'ûcS»DƒK nÑLbP¢#ƒ™Á•DgƒÑ„?ÈH6)8,.ùïÀ?wH @dàÒà#ùÉ›Aê·½‰Ã‚Âo,‹ÅØÅ÷Çj'|¸&ƒñÓÝ‘g;[7 ÍåúÿáiaÁ„iµq†F€¶Ž‘€ÃÁ}ëëþÊúCïZ,Y $èïZ±?)íT&`ü­%XËïm…‚,6<«ji´5€ò;29P?ÇÈ«…'þà–¯àËÙ¯9l¸tú’2¨o’°&l`;°¨ ¾8‹Ê@äÿˆ"Aôˆeâ~ut¿]ˆ¿é~…¿±›3htÐÆé|3Bl(¤ ÙÿÛì|—›²tAA“ -^q8D÷ æâ‘ › Ê2(¿$µf™ˆAˆxDI,ÊÃ"Læ²X°NK'Ç~ßS!¸D ÉÈ>&y󾀺}sgÌå´ŸßÕm3pùÊUÔC¦ÒùFÑü­Ž2§äôЦ² ¬·ýMj¼W:¬äKʳN5 4¶hB¯—Hç·K–}>»Å¿öýT×$¶M6ó Lná+ˈvï”*gæ"BÌ” :lÚÓÛUØÝbl/) oe˜^ÓÊï~:á±Áa­ê´àOâúqew91cbëEÞ¨Ò$‡È­K,»=öu@Ý…dë@3È<»‘,LQ¾]W´¥=oÏ”LÓ¾/B}ÉžØjáJ!×™·ÖÄ7¼· ¿Èeð¹oz½ÖàPvz¬‰ÔÐZm„íå«¥ãè1Œ¿nug¦‰ÜÜJJ*ºÖªH2´y5Qìf4ð~ǺðcãÛ´¾&VKhc¨ ·ï›]ñLŽw[ýa`£Véš’{Øÿ̤ý΃Çòó#™/öN? Nun ¿Õ7"Csr|ŸÏ×<ö`ç·Ð‚ËŠQVgkŤu¶|ñõÐóxez!§ÔìVæZçK›É›ù·VIÕÛTÝÙ PZ(‰³`ôG­ }ä[EäÀ*o`ßc˜õ)¾Õ‰’´…2wW6XÏz5÷ÝÚosâ(ó¬&Þq²H÷•C<ñ4Uo+Óº»ƒzÀeÈa¸o}„¼ÎYÉìFm©0­u ]«‹”eÇòD5®zÖ*Í„ñ*þzºÿ¨¹~7GîáL½š†j2úÍáâÔ\*>뙇º×ÇÒýk/neðÖ^§‡©X+?â¾0›Q_'V/†|õos™!þñdŠO©¸|ߟ*9 Ú@ÄÆË/û™fz7ÎÛ}Ðг¿é7ÛSÇþ"{?v5:B¡¨_D Ec *Òûß~LˆŒ÷Z·bû1e$Thôv¬)A+àÑÁÊÎ=y»†ÊqR¼‰œßž­>­›/k›Ž3ûO¦ØÐý°·½Ò²w!ëBˆ¾Gâ,ö Þ»ýºµ%Ú¢0´ äqÀ÷Ìe=#ì-/º©t+aLë/ƒì<±Xé ZNt²Ñbã½óæeaù½Ý—×eÈòe‚Z”YMÊ»ú+Ã|CRÌ„#Ûf榙œ*áØ©tH¯*º _‚*½ä÷Ôã<ÿÜüCÉBšezat—h±¾«'9R6¡¦!¡¼«ï–FÞˆ{xÍsæêX¶'`§xÄÓêK%™>Äêï—­ç˜Ä«‡åco”‹o•9º…§øÊ¶U”µ2?™t´Ÿ½ŸíC²ÒÞ3êbjr½Í¾[xû¥Ö€aíž0‡ ¬J‘ɰ°Ç9AC@T^<ÌS]ë«glÛ2°¢af38]T%Þæ¸…Î…ëvx¬ô‹ êk6½¹f~¦u<ÝÒžw°æv ªž0q¥`ýiSƒÇ»ûGÁÜQSo¾­ÉÏfüÙT…Ü(ÿBÞîý9cÉ‘Ë覩ÝeñþÔÜ£¨æf¾4EJègÁ?ÆN:¾ü|î#ß,>›y+wûálÕ­ÙØƒ*{Ž^µö쉮F‚–\Ãßò[l>êqs+6°ÿ2=×¹ýs{Çe±žwšnmNw±êS]&ìÏÊsi§MÌ:ŽS>" "«¼ÔïÌ¿+ B·­hf%Ú¼)úòÉz$-?ñjá®ß€bÄ4Õ¯9§Æ¾Y"Ã!FRÝЙr˜¿oÚ¤k°Ú”lU¶Î½k’—‚þ\T$-±µçØ 6¢!ئrÑLU`çõàd³ŠÙvË®M#* ©§¬@ŠaV«3v¨Um+Ã/(Õ…ä‡ß„7¬BåÊóö¦óläùÆž6ŸP#Whé“rž”sù<¢[®}<ãh¦ zx³•ìcSŒŽÒã £’JoÒÔžÔO|Å8yÎú8‰è— ó\!Üw\:`Ö³û1ÿ=>HG¬Ý}¥=KÏØ?hÏlú'Þ>ç1ûQ¢Ž·P;}Eг.ÆÍ;÷s}&2û]õ^…‡ò;_?q¯‘·z®,5Y)q·Ši þ³€ÎÝ£ãªÆP7Q :ŽcäÊYÁ'S ¿0…Ÿ\´¼Ž'½ñB‚¥Q¯zgnW¼uŽ—rt]VªÇ°Öý)e^$§8øa§§áêé9D¢AmÊîJÕæ›Þ ›²úŠÙQÁÆÄ0'!OÛ ƒP÷gÈ6Ùgò~{Õ¶o0¿x%ý¼OÖUá²n¡(i~©‹——S÷;-Í”Ü+Ý‹qsP#Y»=:-~o* ûöÂu>ñPy²ë¿çu œ~ƒRדòQ¨nKTLHcIyt÷^W¿O."ñsØSܺOïåö°2ÒÖTĤÙf§(†ÒtëÊûþHƒ¡Ô•%œŒ;×>׸fĪJ%\|t<~}oé¹’_suÞ]`Èw2OI „Ÿ¬ÜÞΊ~u,­GØ»›”KzVqKÏ`\ÄX>v> endobj 1546 0 obj << /Ascent 712 /CapHeight 712 /Descent -213 /FontName /QMHGVB+NimbusSanL-ReguItal /ItalicAngle -12 /StemV 88 /XHeight 523 /FontBBox [-178 -284 1108 953] /Flags 4 /CharSet (/a/c/n) /FontFile 1547 0 R >> endobj 3116 0 obj [556 0 500 0 0 0 0 0 0 0 0 0 0 556 ] endobj 1484 0 obj << /Length1 1624 /Length2 11571 /Length3 532 /Length 12434 /Filter /FlateDecode >> stream xÚíxePœë¶&î.A»,¸»KphÜi<¸»»»;Á]ÜÝ î A‡½Ïœ{n¹¿æÞ_SÓUÝõ½ëYëYú®ª¯©È”Õ˜DLíA’öv`&6fV>€¢¥­±‹³‚½<“¨½©’±%àø„DE%æ‚-ííÄ`@ d ™ØÙl¼¼¼HT1{'Ks 0€VCU‹Žñ_’¿TÆÿDÞ--ÍíÔï® {[øâÿÚP €-@3K@LIY[FQ @+¥¨Ùœ€6e—÷TLò–& ;gÀÌÞ `óÀÄÞÎÔò¯Ôœ™ß¹Dœ@€³ÈÄòÝ änrø b8€œl-ߟ–Îs' ø½`{€¥‰‹é_¼ËÍìÿÈÁÉþ]Ãö{'S¶w;›8Y:€ï^•Å%ÿ'ØþË·³å; °7{×4µ7qù+¥¿±wšw ´´s€Aîà¿|ƒ¦–Î6@wßïdN–‡áâligþ¯N s “© ÈÙùæû¯êü+OÀÊèà`ãñ·µýßZÿƒ%ØdcÆŒÄÆþîÓüîÛÜÒ‰å¯a‘±3³°±þCnêâðOÌäôwhÿšº÷ €¦öv6S‹¢=øÝ%€öÿ®ËÌÿsMþhñÿHƒÿGÚûßkî¿÷è?]âÿî}þwjIE íûücÉÞ·Œ=@ðמüµh]@ÿ‡ ÐÖÒÆã¿°úwE-Ð?"ý‹ìß10ð½"væï-abcgfý‡ØÒYÒÒdªl 6±˜mÞ«õ·\ÃÎädcizïêß}7beý7LÝÂÒÄÚî¯òú²3ý÷Øßõwä,¢*2:šJ ÿÕný[Sù}Àê Àÿv£¥`oú‡¿xDEíÝ^L\l&vn'+€‡›Íû¿ðø7 Û¿Î @°“¥;@—•™•• ðþûÏï¿NúÿF#agboú×̨v¦ïcö‚¿`'§÷îþ}óß“þçùïÜA&H+‹ö&Ÿƒ¬Ò2ÓÁux¹ßÇÅuû{Ù ¿;”6ªøÕØ÷ø¦…móV=×37Mò½¶y,œ8¼ìÉÒï÷~°¡éI]ä{SÐõ`nPwp3ì°”¢¦ŸjEy]ÎËoÁèp±jî¨”<Ã}œìàpB¸üMçGáZà‡Cyï€æc’Ú‹Û‰ÑUWxrJxôûžfpäÇ÷¡ž_°}{D 9±ˆTŸ]aP©#ýsˆ„t4*½Â)%FÆ0‘õE&É×¼P}Â]y!I×8Uòî0gÊIljRâ#¶±á1ôF•h»‡¥‰n!(·1€:~ _ÅBÃæ\N¯{{WÂÔ¤%ð„£#7Ë/sè|S, PéP9;}æû´+¶%¼ålбŸÿ4‘|­­æ ’Äp ¹,З ŸÑPn1‚Œw HH¥— :9hßâ냿»£×Ý0ÅÌ Igÿ’ÎÖü¥-ÊñòY±¬$åe*À÷-éK{X£–ËçmÁj¯PÜù§#ÑñKÄcF=t{m¾ 0$O9±7‹è™ïc¥î𤼴_d.½c¦|•û‹_—9Â4¤D ‡Õ ‘ðdiCGÏGÔÈC-ãhWvwmŒ#œÖµC\Q3•½qÅyñàŠ­)âòH™þkYóì‹&nî¦öªõÀ*5õJ„Î f âÃæF¬ßT$ÄK_4z‘îÍÒ¡_š’â£ËË%5A¦ð‘©®á—š_UT“7Çl΃įʬõIÆÌ•Ók[׿Œ×ãt?=iB ÉjŸ­@šÛgw͉n6è3™ÇÃ]óŒ“K½`€EÄÔ^“’Ø&¯{™w0¯y­Ae_Ž”?[| ±GùPÁÉÄQµ¸¿â¯<á.ϼ‘Ÿ<Ãe͈}Ç_ÜéýÙXšî‰Ù¨hh‚`{.ŸÜå«·ï‰ Y%NoëÒë­‰Vû޵ðvÏV‚|L¸ÇžV•…*+¯·˜¢{ !†ÑX¯ˆž^ó/€¹ûhICä¼êNj-§ûn§'HÁoÝ ±Z­9_[Õ¹“ÄþðKì„´žô ÿ°Š†”¶ÓC½¢D¬òNe© ¤B¾áeÉGNÉú «\O”^õÍé¼ÃÉ7z¸rŧq?‘-rÍÕr"T2 ÕIyêq%zf R@Õж‰ƒh,TÞ¬ÎÖ 1µkïíjl¼Šà”%9¬BY…¹ ̃7•t·ï'0®{kh A<ò·ÿ*ªØÜ>…)ŸÊ7^+_VzËuØ¥Œ?vÕ“¯qdõàH2„¥ÑZÂÞÛA'ÛÇ0¾}²å«œ ù~>Èf£,J¨0¥.þ‘™©L*é2܆0!ýð Û ^j=q߇~_/H1¬òq¨ ‚”O…bÀ,©[Ukey¸¹¹m§üÅ£e°Áд·½áë3S2ø„Ñ);²ÏúÑl6uï:Ëö×7>}”%ÇIî|åäÆxã Á§ÞKïÅ\¼ÛB”V RTJt-S ´x-_9Šq9Ö8±•& '2ú&0h)5ñdô´¹„Ü@,çc6œÏ£çr5ð§¶#ã õDƒ6‹,XèNý葸Q¼ˆI±©È>ëE7€„v»¢-1‘°¤b¬VÓ®E?½XeÊ‘•ôŸˆöTp ®Ò´–»ÀlYk[xeîGÿuîy]Šë[ä]ü“ÛžŒ† wÞG;òàGzªÃìê)¼ÛŒëT梕®¹ÚܪƒÈ â®^ÀãÂî¶Œ«~¦eòŸ*Ê™õõÓôÑ='-^&ßkñ ¾n!Àr~ú®ÐàE9¯G@¨ÛúNlQÞ}¿Ë݃Å*‹Êã,ŸxX™'ùȥƃbØÊ»Le(ÿÊÊ6æWmp+ý´‹eè+p÷uS¢?Ú¸1÷È”G ²f¡²Í:‹gt£9¹Ëˆ‘WášîìULÇå)•˜6RôÓ‚Nóz–wjñ4Æ¥¶Óô:¹0“ÅéAþÉb@¦ÜøkܵR”æ& &²‚àRð™ëF†ñ`êb[/Ÿ„æõ³ 7‰·.kžšš Û!’Ö®¾È(ÿÑ÷Ÿu¢ÈqÄIó±ó2d8=Ç”Ñ3ÃS‚¸$SÚk%¼­™?î 7ÈÓ­4帉úÕõì©õx3Æùe¨ÞÙ2sìÔ.ŽtoWˆæ+h—C¦ŸÍQÐj!×E1{ö=ñ©K.Ÿà±B¯?ý‘^ yY4ýAXØo›ö§L Kªô.ò?÷WͶ?šðFvˆA¸ç»åA\}ù¹Öh‹,®¾Wñµš›}î4û·”'>úÍâƒëÂ.œ\+‰‰el÷œø놉8U#'$iGñ¨w_k0WGA‘?µÈ²›}³ƒ‰îköÓ¡Qy˜EUÓúsúu„Ù ~MÞ—‰#G]KËãoÝ_“Îë*bZ P]çß—ƒz€•]¾bü¢ÉIJâ:d>ßZKã—læ?U"ùã娆æÿr‘-ugeÛü¾‡aÞD—<]Ï/µáßÎϧ9CIE{Ê¥Ú¤œø}yèÔ Rq 0rù1 ÎYëcÞzßרܼ”Ü"¤aI¨ÂÜ­Ø”KˆÈ·qÇ©\’Df'C©6¹ê<«‘ðŸÝ w{k~y‰!Õw;žÁ”–cnúE;^§ø¦òÍYM1–iÿЀx®§%^•´Žuµ?Æ ¾+.»ÑˆMôAZ½Ý†C©Sy‘2[ÊÿIùÊ^¿ÜOҧȳ…ˆ‹´<Ïsjí&ºO¬ø]WV1n놤žcŽåNuY°x^è‚ú¤©ÑÛ´ƒšÑ÷”&¨/_ßä‰ó]>1ñ5‚¬¥jþP‹µ=#|’û‰>ÖGZi¹ÙªUb±”˹-#¨£ŸwYõ±é@‰ÎÀ“y.‹‘Á—JPBÇúdí.Vt_ z³Ì|šdwP£+<° +C¦¹ÛEŸ*MÏôÚ‹Ë¿PF¤=}é=ÍåÞËû´ïgÀû¸ïÆ>ì=/ܵF$|Mó\‘¹0­ŽÚ_1•·Ù¯[q#×’¾ÔŠÌú#mÙ±I›#ûÁLÅJ±Ñ³Û¸ÙÙ×ë.»ÚOuP0ž(Pò¥¿hõÇVzocû÷T§5‘ÑLñ‘‚[ˆ87Áö, `³›‹9ñ„É_±f¶:뽟ÝRðozžHb‚r]–2P|âÂ^6£-ŽÖ¯ö]䃋d…½Wp+ÃÞ:w+TÍ}/EVLÄó .äÅ~ÖP‚¬ÅÏÎB÷y&±#Ð¥™Ç5ª' ö‚×#»(5[ò¥C•‹V¢—R̹1?>æ'¯üb†–äeÖpÜ9Dê+°WXúN^o”d˜Ø~ù}ì×L¹î‡–yW~b¥æšGÛ´0ŽÔ³Òjh]ˇ?øª;E9׆%.å3ÙÒPö–‰r*ã™·¬~ˆo‘ÓÜ,q;%•QÊ–XÍOnDX‚ue5çµà*ÊÚtF¦oÆÎ¿îú²Xù›ù×}ðZ9! )Óšy,HäUP¹’õ‡½×O÷aaÀ§&hl>²,o ÚIá ýȨ3C•ÍÍÎwy* ‡WÚsçÏȰ²r]Éá„æh\áTRÓ!pÌfM#­ã¿ DZ¾†ÛØxºböÚbÕŲ,ÝJÃ(Ùµ¨­[n‰ì³çbµ”Ød»apäó >nï*NtY¹šÆ P ¤šC5rõ€¢7ÍRˆõ'w˜~H˯²S¯F¼r}ežjè Êÿ|ÊË…oû»„ì§ë£¢±çŽ'Ž swÐÃ/.æ´Ï9jׄ/F¯ú? 0¥WT´¶³¨\_ŒÕHÌC²€þ… yXÚ9xMËþˆ¢dæ<\×%ß‹ ®’-º2ºççíá·È® æÇ2§ ƒ‰¥¨Øµ[l‚…é0…ÉÂ/pn#n£wKåk~Åçi}î;LG¸mô¦ùå+è£i¹LUÑbW#@’áo¡º0 Òƒ³ˆ·çìÖ}C:ïf’òDRmrẺ‹\uK½$šéšï[Üh¶E ´œ¥œ.@Ý´†5n¾C»ññÞ ÂÚŽQ„ÎöÒ-†ŠG£R:‹ŠæÑãѺ°s5lk»©D”9åÎðvP/ººÌE•Â_Î~ಓ ?tøŠï]–{›6:¸“Êåè#LA‡òÐçé-èàÑvéƒÏéënø?•å J³%1+.J<ˆÉó˜-ìyãÜj¨}Ÿ‰ÆmÉ·ª«Oøòbd›XüלãeIéÜípJ¾sÇ%Ì”ï§d»ví=§¯)œ>òì^÷œ¸ø”šÛR<£Å]qjîP?ñîž ð¶½\â®’âÂN̹ixØ,<Þ€¯e;Q“ë¿—¯åÄÒK»%ÑÊÆWÙ ‘m Ôgd—…à»â eA­vÁ{f{13tÄæj»§g‰wé35”þÈ´’ó³‰2ü¦'Ì“…UËž? ´¼gRÚ!Š•2O×2rÚ6É–“|ºÇ1bàU¸¨Ýooˆø"ŒsÉ÷ûÞ›5 ´¤$ÆM«slœÃ‚N}zfî€C-˜ŠõP51ZõZ®Lûµ¡Ã`²6&®ãxÚš,Ïw¯m1ظÐ2ÞÚ’4K¤Œ}ïR#mRÝê˜ÏÑg]Ç4òk¼WNKaä¹x¬®6“"p¦žØe¶ôÁà/›¯Žâ²Š‘®™Ô·É/7Ô ôU<‚ŠBc »4ñC0>©ºšXlN?)Y Vq‹'­b"ÿ5‰Œ9ÅZjb"aéühgÂb$£NkíµoùÅ>𮳠åݽp¬’+çd…ØÀÁÌ %Gµ,ÒrþvJƒ†>’L s_³tú‚„´‚ŸÛµúD̺{¹¿ž‚eõpú \%¥8a@Š(-›}àTòdt3•¿c渜›¤utäŸôtµ¼Dü‰X2£r¶*ÝòW }RMDU•°÷`É3ÆÊâtÒFYudn¢ø6-ÇþÜ€mvm&ÖÔÄgúm´0<.ÂWúS€‘÷ºØJ»ØÌ°ñŬÜÊ­|\#soà)¢îÔGʆ¢ÔT#¢ƒK"M!”Ò¸­S*a2 øz‰¬‘1ÑÄ—UŸ¢bG«§¢C¾ö#Þ£jŸ¨žRl˜È¦$?za2‡cÛ•,—·z ·3‚7NÏ…’„2öýïûú¿“¨nšàò‚’;®Mîv%1Ê£p¶ªh:¯Ø¢äÔÑId}×6éD>©Ç.4<(~Ûcî•ä¼2B0Ü?ú`öEW‰´Ô}n.µSöŽË˜l+ì&_?…` ïtB\XOÈ\7O¢l9c(Ò €„øÝeOÍCy f-WP¨A–鬂À´šmeöÖfxýÍ#–¾gðF-1!MO¾‘²â+ÇðZEUŽþzeÆGm,òB¡IŽ:p+ìV.7«Üw¶Ág²öù1oð‡ Y8nEºêöY›)…E "ÿbì¢>á÷¥Oú :¥k&¯Åà±Yë^‰ ÓÌİ–øŠ¡&<˜Š¯hÁʇåûB¶­#ÙxWgƬÈI3:e¡é“ ʹ¬7ƒÕIár1¶ÖI0G6iÇBºY#;¿¦~"}„µõkÞ÷/ËÇ+G覭%’ÜùgÀ*3CÛC’½f‰5YJ<œ½?Ÿ·ùÅŸro‹hÑ”~ ÿTŠŠûŒçn¤ª†÷Ë´LH'¬Úz•ØbäT#X¨W%I¥ Ü›A5Ô„€yå“n¥xM) ˜ïþDbÔˆgžÎ/:KÝéyIói)¿Y­âA8ƒ hޱïH÷Ê]5\.Tg·Ø5"4‹m«¨´Ù@T‘* iXÁí õèW:E³ŠÖ 365Cû®„t0´ìt@ÑOª“‡wáÐúô‘Ö¿ý4ü<ùbÈnS1èLdUèe…mˆ£b{à_zªYŸÅ1¡¶®»ÖA(¢i-#ù'Yˆ§IƹÁrquP1•°'ص$lY<ö–±hÜ~äX™d=Où|U.÷XÎO›…ܺßCÌå¸$¼X™ãá߸„øÓù½ŸMÍ ë°ûzse¾‰ÉÇK†¨6Œ¯ÜáªÃ0»Ü_uÜW#<ðQE]c u¬ÈGvÆgs·&Àëè›°‘­,Û9rž¼Hͤ˜™¢x¡Ç êµ=¡† yÜPÀˆÍ`c/ž¶ñ¸#,™ ¦Dwê,‹Ñ&¡>9èÙ¡äùVž7_'›'µ²Ó¼ˆàÑÙ|¨ë"¾_˜~{A½šbÊÔmãϦKi•×›f^¬=}HÉüÆ4 Óy­„aºÈ'+3ÓÛ7{—ç!f³}Jr©tm k–1‘Îá·%BŸ}SÈÿ“þ28.,ÓÚæƒÇR]¢ßƒqZ^ø¥>ü¥’OC@—–39Í|è*¹â©\ÀR`­‡˜Rd«—Ù21¸q•¿8­‰$Ô©D}¾wC\…à+gQ•¯œ[ÀIZ¨·ÒÎäsÀó K?³0¸Dºë¦-5ÖT[u—srz®!ŽnVâ&»5Å'3—ì%À¹ð, þÚ8`” áJºp¢l7X¬¾.™"þ"´šYï4è«_9øŒâL+¢€šKGUoäž3 WÔß{mU™ô‘ÿÉsò-=€Ì.Ó¸ßèæ˜º&âg^ãy3‚3Y¶ƒ’oÅ¢®_{ë§%'4ç,¶™H_§ž«èLü'¿À?ëR$‹Ò%ÁÓ¢b=’*«Ú«V}…?ⱬ x­Ÿ¨Û\DŠbw;ŸFÛ w‡ùQÜ¿s¸kñ—Fi<)ø&n vêVʉˆKøéñpo@K¹T:©='õ©¡‰7þ#w¨ÿ+²¯ÀaލVögçÓ‡C+îFw¶ <€ƒ…¾ãÖâX"¶k†Ü'9ÕéGθ*¢Ã+=p„ãøý…>g Ö©ÒÌ—ãõJwsñwäÍ›ˆ÷iárãze†«•‡Ø¥ž+bKkñν¬*Pi‡¬`ÊŸ~ž „9¥tÜø0ç@“6¦¸_â- ÀeI¥%ݦããâZ¿×,V\ýéäÕI<|É5mNL5UÂ}ÜÚ€e)“GÛ[@}ѪRTÜðÐu5³¸÷èÑ®•¦Q ð—H2!ܶ,ŸqItkàí›iÇË*Bnes¸¬5;ÓwºWD—o 2båYìã†{K× ¨:þ¯ý°«P„koÞUó̓iük4¦3b.æAêÅ q-ôƒKÏ‚aªÊ'h¥]j"acP0þÌ£%³ñP~døy#2ÕCÂûyFõ-Ê1}Èg¨ý.ã77ÛÊ%ÆdäÀØ e¨‰ÚÚÆÆÆúÈfØmÛwJ>/=#꽊*ê Ú0n'ÕlŽraza.XÂ['’xöóƒoë'_dc†Òs«¬µ{³ÿLy} " èºÀO2´ŒTTáFVÔbÙþ Æ(7Ì$™þºXY}·£!Ãï7ïa$hâŸÇ¦_ªx®½¸w¤÷6í–’ë;ùƒÝ‰¡”±à©N—Ó›¢\S€ñ» ÿË9l¦,!Šê9„*,t篰(³¡Ò´²Vãµ;&‹Àò΋z·_yz„Gj¡E;ÒŸ’byBUèºnãí^Bƒã¸FE75÷|g5#ÒÖÖ|Ÿ2†îžÆ½Ù®ú0J•Ì‚…eɳ2ý;^¦Ë.+)2õËŽÎóusqö<:¢+ϼ[5¡/ЇYâ`º¡èò`mŠu¥¬f ]btªN‹ŠEŠ.rc‹Ñ¦¡Øì×ýönǽG|ì¾FŒòûøªÂÔ‚-'“ ? M8R-j©Ó\úç%k;²NÅ÷€Ñ Qÿ•¹„‰™25ÚœS²Ï8f¼JYF‚B’¹?ɽ#jF-óÿHLýÖk$IÆud­ ®´t¤^ÿ0y¿5Ÿó4Ĩñ…àŠ’IÇŠÖ N”)1¬Ù÷1¡ßº(ŽTX¯hzƒa7KÕºs¬Ït~é[y:ê[m°nÎÛTÎÐå'QUЦ ^%WõÏñˆíÆì4Á®Lu¹"ô<ŽŸ}ãÑ­ôæö8š+|µ©¸ÎŽóžÁ20ÒçÒv ¼ƒ'ƒ¸õ“±¨T r ÊŠ¦ë(¼%/sí–4ÞŽðXÀDn"¯ ¥:NÃuEp4ÊéÑØòQ ù5 ·|vjpðtÁ>,5dÖ*S®S¿n)*scWÁ¾¥›Kk<âÞlÉ3Ž'_?é9°7xq;ìÅ™0œIEÒä>ó~Lª6‚”0 Gò3Í Ê}¥ªÁ€EŒŸ »Ô|ŠÛpø6j¿ùƒ/OºÖ  0:Ú@f”tDO²ô6Õ,’Œº˜C…¾~ô:„@Jà2 ÒËϦÚÅÿH_æQ4ãÄ*öÙ:bÀ°uˆ¡«ÇxmÛ݆ù.´dQøÈ…SÅ h±>ëÛܵ·Ô%3C\#¹BnãÈC¦Œæo\n;J©=ZÉ|+"†È䃺ôS1Ü“ú<Å,Ri‡?¿“kTº·ï’ O)›‰£ ‚ŠVtö«µ&;›Z:£µqÚE‚=|á7ÈÑë‹3ËI—áÄ´ »¹G´ß¡ðo@Sž€0›þ“øqæeÆ%‹½šØ/³ï5UJÙµ 8’i7Þëù蓾÷‰>çG+O¡"]ßÕÜú¼º¢ýÕÁ5§¥UrÂTx´þ 6k-éÉßdž/¸¶PeFËtNVª¬Rx+º™ßÙºÅ{ì4µXd61‘>'¦¬Ìì:*.#íTˆ—Bø¼…ÈDægõ8u½Ácîk:²ILõ pÚž+ꉴӞ#3)yk0 agŽ“å}g„Wâg©KÔDö=n¬¸ü9§Ý-‘e/ÒØt¡» $ŒCÊâØö!ʪ|†ž²ÎÍVý g5tÓ±šÖ' ïCúÝ!êö‘Yv·v–{+è,õŠU!ƒÌÁª‡¸ãé2)lúgäQ,Ò†}¨³Zý}4¶ÇǬšÒ”oÞ„ëìÝ g<å!ËQ5Æ& ˜—¨³[:§EmrØo;XÌ¢} +y§µ ·‡Öwg8‡Ç=)tr8È"Ñ©½ÔÓ Ö0ÛP)Bm‚Dtpª) Z¢µÝžÑ£ç 0ìžîcQ,³tËÐgÀX‰>ÛG¼}’à=+bM o/S?½ ê? l_ÖNÈàT†aE)YNè:€±vÑòk)Ÿ1ah(0ÌcÁ2óµ(Äõ3ìEBNî…`þˆèûOù/`cZ1çØ5³§(Ř~VãfV Mgä¡`>u=æëç¡ÂòêÎ Øäx -¨Ì¡à‚»ºÇuù/@½jZŸÞ¢´Œî‚=>%¸(´(•Öí]E«šÎƒ²Ù°íËZ˜WÖØ‹yz !îE·9‚óîrüŒkÍïŽ#“ wmdÍvÏëÃ!BwGý¢5šáú9ÙI!ÿÔÛày5Ù[–úÕaÑÜþTB#Œø™†õ‘ô íSL§yÏr®A¯±¼ÜµØG¤Ýaˆ;}Ñ‚Ëg©(n˜rl7¥°zil¥]fèléL0â]Ónâ®–ú´*Õ¯.ØBÍåôÆôJ$&Ô‚ÔóÀ!;té¾sÖ ?¸ÈUʨjPå¹Gº¬±ð?q)ììê_hËwÖILé|Qw|ÉD¼–ÒbàË䪷 “î-¹·ñ× `Ÿü Ï-T•Ò'kÏ!¬„²1{ÃæÌñ{7 ísmÉÂ\1EõFS*á" —µ>×>Mš&V»„^Ú;e¥=‚È'iZåb†k– dË`ñŠÛÌõ+Óƒ† Ðxž¹Z¥`?ÑÔŒš(D ÂÅVŒ²å ±yê Y¸ÄQ–W)Qó¨7ùý¥#ëaí\[êY‡ Q“å ãO=„[W %í"dÛ›{½ <1d¾Ñ/“ë…³= Ï&JDߎoŸÀ…Å1A³m‘‘ ÈÝ2ÀËìuàç@W[k¬@ÔÏ»’X˜É_ŒêOAç%OIìì[UØmyz*Q£ìè82sÛ¼x¥L`ÕÖ-•­°@qWÇÀû8Cqœûƒ?Ë¢ÓÎo=Îé(²=$YHÈ£~«+-74A _áÏ·{×åkvÝ]2T2èÎ/Ä„>jmƒ^RÑHúAÝ„èßuxÛ½§¿…àyÝ?™jt÷döa"eÕ».…ûÆe1x‡.#T+‹¯¸á\„ƒu¿Ðf6·*%È ùÂ67_ÂêIAS0âzÛ•¦÷ŸŠýq_V‚"ïÐÕv ŸÞX¢Ó›dʰÖFûoÛììc|;F;Ö¤æDž7ÈÙª³+EÇhÝ4¥ƒ?šc¯qÐQ…i¡¤`æO}OÜžºl)àOV Ò‰,?£>ù×–5sñ6Ùr5 W1ÇÇ»<èñ™©95w »#³y |‰1Üí%>lš›ìÝ*ìÔDà@ÿv¥´Ædï´Éa¢‰üâ&…qâgàb ßÇŒèÀª§(Žû)ª¼ýIvj…öгž?x'{}4¤²=ÑÏ­úPZ¤ŽsRÞìÊúBTo¨ˆhÎÐ#ŽÙÞâaŠàØ”^ŒZ®TòªŦÝÐ^ ~Æz<³J‹ RdpN@þ#9ƒ#=Èéè'S 7Ëî–Ë…ñBÀ>Ül ¹)ûÝá¶ 7áÃÒ¥3ö-ºØ[t.ã` !’×Ê ßÏù¦ÜÑ«ÂlÌa{Û,]õŽCp6¼%™óW8 ãò*¼+`¼½Ç‹ð)5oÈmžá檣\¨™ï‡,k“ii¼Ãšõ½8cxÕ‘&Êof6ml¡_;•޳‡< Mć¦Z+¿ G„6Œ:oú)[—±pé”IáÏÊÁáí ±˜47ô(xË’uë²"œü¹x­q*,$Ý–mcê¢(sLb·Àe–l3ÏÌʼnvFž§eå›&±Æ8~ÄmÅfµRÏc­ò·µÂ??T‡/Þn­¿,Ú¯à> ¶¨J‰œ˜?2T ï>0÷DXùogù©¨áf8*;`‘K8z»˜c¶AêÅÜŠ/ûvÉ7 a„/üFqEÈ[%÷y¯sé«»²‹¥™‹E ‚ùô&ŸU泪å…àñ”}¼©ÛgrÎ/6¡é އYXkÙò¿y»%'nBL“Ž DŠì„ŠŒ—À{žm9Œ©7ïvCRðUìW5°¦6 $gS±SWi¦ôrñ¼ ¾êßÓ$§”’œ|;w‰C¬ž>in·’ ž mÇïNcÔÂJ\º1§=+4O ËÈl›ì >mD ©ýÐPÀmyçOôC½Å•Ê®8 u^ˆÍŸVÆ‚ìŒæÌc!^G[P™ì™§”S´ÔÙtgFšŒÑøŠÿ\l!´#e)ûݨ§Ž†zT~2щÀMçØ";¨Hªü25AcÖèGWnÜþr]20ßì+â©lkHÇÞ‚æ Osâ#cÖôxºÏz$nßã‡BISÁ~ƒÝÓø!…žö.Ћ§«gøR~½Ëdú¡nзãšÜs-D»W%›Z Ú)M_Z·ð’rOjÖý¥°Þ‰ ÷yåΕ \ô¨ƒœŸ1ò­Ž7ÚI#‰®dL³‘ÇÙ±‚4ÿDúòk¾ñM¨_‰?ÔÏŽ®Ü~ßGc‡Ò+bÊ@~Àæ¼~;-"ØÂñÈR²7×6ýꇇ/îRuêà3Œ1üË€dàòAR€Z¹ËŒŽXVg‡’BEï"!íw|{jåa †œ×²ùÚ’äׯ¢KHàI|ûî&;¾þRÈXá¹Sà‡ºGKëCïqö§øÌñ3º·ÑÙŸZ†ªávÊOU^Ûª(ÖÄÛÖ¡oÎãÑcG e±ß®­ Èi’F–DIë-Ò^@béÇÞŽàÙ€ÈÕõ†(ªÉD‘œƒ²ðv0Ìñ>æð$;6_Ô÷™µ H†zÛ q¯þ&3” õX~ÂW¸Úá‡2ÙåÙ~FâYPWE‰aʾušÈÇS˜ƒLêÝr4Χ<Ozp‚$N­1~Òý*Œ=Çc†(kù3¹œñrsY§lM¹ðø´‡®úæåŽažÆo $NUqêäî ‘’p=ëj÷%ˆ6ÃÏI-I=Øß®2Í*èr¿;ºw`É”ÿbX¬TLñK¡ÖvGô,]ÿ .fvØ&\8ûÜœ8Þ\ü‹e¶ó°¼¡˜ˆäàŸµæƒçûœ½ K(Mµ96DÐÏ—Ê“FÞ¾þCº7û߀!EÁ"›-çÔB I^` dåwHt„ÃLÚ·ƒNjd2ç{ªžmn LWªí_í`,²SÀö*ÊG.ïeitY`à.4rf˜¢©Ál•.²O^LÐô önw©µ§™hicíÆi+xxè'œK9Y©%„n¢7Ùm>û§N²wÚ)c5“¡¶¹ (Ë_£š I7~]YˆÐå†Ü.4ó4âbݲ3m6»‚óš™öllž«á7Ô²“ŸSµ7B’ j®ÚñFS ”>VXd‰«SŠªRâ¯+„ó¥n@vm‰2Š 2ãõù_Nd1·;áMW[<èD/$œù¿f—ƶ™ël‰Wå}`»¶Ì¢ó;›Ã[ÂU£§Ñ}™d?hjOFŒ½i 1$•¸‡yêbÏ–Á`jÃjÛç’4Ží|+iË ÈNi{)qþ¢,9ÔdÏmYÒé/·Rý¾ƒ¯AT.7¿©q$ ƒ|Ue±)xé3m}hf–×­“2CÍíqè+N”œõ(÷EÆ'jQ5BÉw|Z-Be–àÁlCŒÇÅG‚ ¶Wý“+G ê|Ö“ DŸ¯Ãì*ë„R×äµ£c$:/2bÞ]l&Šp…¦¨¬)éCaR Á·ßÚ„ Á©SÍ@ ¬m°„‰*ÖÈØFÌGQ+1’ùЛ®àa!±"̽»q0Éî=ùϸª”Šöçòmòé?Òµµëítû ÎñfZÉò!&v¡ÉåtW¿Ç€ëž<ίg5¯—ÔVH=w’íÉ¿ Ž•™¼x®üE™j3¨u†ù·éÊ^ 8ðޤÏ&}»¡'RP'Êûæ›×0Ô™°Žø32{êv`¾¹‘eRÒ—ñ <•£ÄÞî'XùBDÞ±ŸÆ)Ÿ†f´ðKä::¨ 0Sy32D»àóMýÏw±)¬ SË"_‡¹\–$Pj¯³‰‹_íÚ4ömecÏ”.ºqBñÍ2”l×NpÏÖ’…âúÆÏ´T›¿‡Þ87,°5Ò°鎫îÓ.6_{Õ ˜+?ä‹·òš%n¤)«¿yÌ |¬ÐFÛ-ž†XC£ª×Df]ã Û‡¶ýd!a 'Am¹Í7ä¬SÄc±³˜:ƒ¿W‘ùZ~l?¶Ë@‡WUG§­ÊÅ¡¡öõëkvÒõQ]PC&ÌOc÷ÕÃ($<éÙŽ^ÃM¤\4ôìzFÉ­e´­zßm™“$¤¦ù‘gÍiá‘QÖ®÷vÛiçn©žìßþô=‰%Éi]†e’Ð]µ<nw vz’ oÙL_eG$´u QaêÛ^?ˆTuÅ¥‡³V¿Ë¬½)s8ÍÌðE´~¶bu‘àr1øY±sZÊÔ¦f ðŽk‘ÚA1€«7³rxk“ r±`JÊ*ºŠªë›Á¢£J›íþáeÀÃj´ jÝ‹ÆýxØxe²1µrr 9øun{BÂ;e?ÚsÉì`ÕêùmØÕ&ì *òÞYQ5oònxzmäŸ#"žm¶^þr1rVÛ}vgǺ=vÙ÷ •_/‹&9 ¾á×í•[ d|€±Õ/ôë~œ^30i\þà\BÅâýÖF¥i.UáND××|Ø—L$–nј_໣'qy˜E5Uu’Ïb}6‡HýÄhâj\JÖ/#ˆÜ™ f¤L±`ª½—v Zk~²}]D´ªëq‚­à‹O¡lW3%j;J`ÊÏ™ i, ÉQTߺ^Ô+Ü\ªž0fÉDñØ3)××W‹]‡Ÿ¥äeuNk¸ýƒcy­¥YKdÌŸ1UЪ„gB=—«—Æò’³°Ï„m(NVs3·f;ôÆžŒ2ç; Åî<…º·Î5êR®í8ÔÝXnð·?,7»*îT3ÃT|[fýo~þ?Áÿ&6  ØÞèdô¿ ãmendstream endobj 1485 0 obj << /Type /Font /Subtype /Type1 /Encoding 3111 0 R /FirstChar 35 /LastChar 122 /Widths 3117 0 R /BaseFont /BQIZVO+NimbusMonL-BoldObli /FontDescriptor 1483 0 R >> endobj 1483 0 obj << /Ascent 624 /CapHeight 552 /Descent -126 /FontName /BQIZVO+NimbusMonL-BoldObli /ItalicAngle -12 /StemV 103 /XHeight 439 /FontBBox [-61 -278 840 871] /Flags 4 /CharSet (/numbersign/hyphen/period/slash/colon/A/C/D/E/I/K/L/N/P/R/S/T/Y/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/r/s/t/u/v/w/x/y/z) /FontFile 1484 0 R >> endobj 3117 0 obj [600 0 0 0 0 0 0 0 0 0 600 600 600 0 0 0 0 0 0 0 0 0 0 600 0 0 0 0 0 0 600 0 600 600 600 0 0 0 600 0 600 600 0 600 0 600 0 600 600 600 0 0 0 0 600 0 600 0 600 0 0 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 ] endobj 1468 0 obj << /Length1 1608 /Length2 7997 /Length3 532 /Length 8843 /Filter /FlateDecode >> stream xÚítuTÔíÖ6)’ÒCƒt«Ò#-ÒÌCÌÀÌP")J7RÒHwwHI·tKˇ>ï9ç]Ïwþzßó×·¾YkÖúí¸¯}í}íûfejóHƒ``É#ÀËÿ  q°pFh›CÕxd`ö À½S—•U6GB`P9s$ø@ È-‚‚§OŸâ²daŽîpˆµ À¡«¥ÏÉÅÅý/Ïû?"÷'k(€íþÃlstC‘÷ÿãƒÚ`0iXAìÁYMà+e E‡¢†.@ ÃÍí@g {ˆ%@ b †"Àœ+`ÿ—°„AAß­!xﱤsÂl ¹?v³;þqÁpqÿ € Öps(ò~Hµ´wý&pï·‚ý!ä‡Ýg8ÜÇîÁ€0a ‡8"÷Ur ñDÚ˜#×F@îØÕ}&féü»¥?±{˜û(ÒE`7äïZ`‚p´7w¿¯}æ‡ü¡áŒ€@­ÿÅ€[›ÃAö`âæû÷tþÕ'à¿uoîèhïþç4ìOÖ?9@°½/®€à}MKä}mk—ï÷¢(C­`þ¿ü gÇÄ\Àð?âø½3œ÷$ÌA0¨½;¶ÂåÓ€!ïK8þg*óþçDþHüø?"ïÿNÜ¿kôß.ñÿö>ÿZÁÙÞ^ÃÜá~þz`÷/  øýÆü_¹æ{÷“ý÷D}ð_ ÿˆ2Òü~ ÒPë{)øyùÿrB 70AZÚ¬Ìíïgôǯ áö(ø^Ë?cðˆˆü-¦c±´ƒþºèÓ?!0ôwæ÷òüáͧ4|%­Íõ÷×ôOð^u¤Ž»ã=±ÿêCú§ñCFæðàðñ‹Ý_6~!ÀSá§žÿ¦Þ ÙêæH8Ä ðú¾i~?­ÿ×ÿ_–ñß`ä¡–0Ðï=ÑFšCA÷«õOÇï°¥3~¯èŸÛ~ßò?ì?K»-qg&a–âþ¶‰)IÈ2ÊŒ®¹×m-è]Žy_t>eù”Àš½ƒ—žšÝ”ðV=ûUë>±íx»¦òx½§…ž½9¼ŸIëÉÌÙšõpž­^ŒkÝÏ$ iG?Üãà›Ú"†¡(¿ÞúòÀK-“Ü›tCõBpìƒsNf—,2–ŸŽ„^– Qä Ä•($eÙÛ;l1?βwôvwu6a¶®Ñp¥Gá°Š»`°…ù8¥Ó¼0Ô-ôˆ°Èˆé(‰m lÕ嚟>¢¨Znâ|ùlùÝc§\ ÷õóPº6™ÝCËÌiqÓìôúž¨ûN³zg•Ä"H»vj5ùÂ+²MYeßgeþRn õYíáÀg¾•2áÄí¾A»Ô§]ùÇ«éêË̇yÛ}²y¯F¾¾OP­(ʼnV$Ó‹GX¸.û¾`/ÜŠA»°«‹Éöö·òò–øµ6¼5šë’/©bâ;#(ðBV ^÷9’g‡Ð†ŠÙ¥MçÊt”û—ןœ¸äN®Òõˆ¨/ú<í\ö C¦<€À‡ÊÔä|^-‘*``àz¨kCÚ+táÌћ̅fSùLÒ/Ý[|Ú²_+ ј‚%0§­Cç¹ùQ· ~H¥¾ÏJ—’……º2ƒañKÑùð³W‘¾· Ò’¡^DgÀ”ì™úøõ¥ü‹s”°lŽHl}ÉþéYÑ“ÏoBð8~Æ¥s‰«Ïºå‹GÇ„?’ä?^h©®–^Å• Å nîÄ”«Õ,ºM{³”ÍèåÍíõ¼43Hà`üØëÕQcC!cRÍ(ê"©6%Ѻó0ïóu3ú€Ú^ ¯¶é{ª¤ÇhµÆbûqG/ ÖØà.ñ°jš«ÀT“ø4£Ú¢ÝšN•gf˜'¾3©™–MÏ6/¦^øÀа™Ó•aW8+þò™/_–»8K¹+ŒŒré*õ—h¼ ì<Õ@®BD-Û[­šöÆäë},„rX‡už-• ãzŸXú07Kû¡ÓÂgbÔÈ‹µûÌL«{!éúb 1“öUÄÆ0ÿ3B^ ÷ºÙÏ0ÿŽ#® GPOƬ¹ Mÿ0‘Wee@yGS!þŒ¹öÈ"-Iå®{)™g×fË–_mÔm†âÍPª$bn³YÇêפT´p|_NÓ„|ê߀ú|èa#‡Ž¤q²r*±b‹¬ûnªyhÊk«¼ÍÒD]}eyS'³§Ë·-“Þúhc4b¶=ó‡VíÎR ¤"$‚B_Û¼8CV– ðóøe‡.-S‘çÒƒ ðE*¬/\ÙÈ 5€íeí»4BïÇ·F±[MäŽø=æXÎz9†CÅŸäa¥ïWKòÆ3c,ÖRYT;Ò+P%_U*ebŸ¸ô›y??ص v4b$4lå*ô ^qÆæê~üzgqb‡¾ýVÅ*âe| Û Æ–î$Ó]ب’  =ýüB¢×¡2_'ÁŸÀif æ`{•pä»ÃMâgåw®æ gªöZ%“L+R‘=J_`•5ÔüÊÍEÔ¾µ´-¹6Ó•†°bÓ8³v*Üö`9 Í©½å£Ç)NÈ2d‚1íÄ&ÁƒS®Çr)*˜Zd‹‘QC!‹sÑjFÒÖëÂ5zFëÜX‚¯H›Aø{uFÕJ§¬ŠÞø.eç0œñ7¿t|õiÆ·07è†%.¦¦ÀñÞfÃ~ß'ÒêÌLM\£OfgeåÕò]\æí)M ¸(-&wJáÆ¨Êñ­…ŠÙ$=VÄ¿²>ôÒÿÙÛss›öò;žžQÍ>ú¼L"þòñé6ö_r‹ygmf7©ä¢¹C³ÊO]Ê1ÉcO;z¸±õ«M5¿½˜XÞGYí!z–S¤w Ðø¶-%HëÝ#j†¯°qjÄ^,.:ûT]Ÿ Çåãû©M‡– ÿ_ë«þe‡|Yvƒ•$¥Í«ëìt-¬Ü ñ¦aC‰ãÆÃè¢Õ“Ú‹`uò›dov‹ÝRs©ó…7ЀÃP/ Çó™Cµ¦c>]'¦¸:ÏéÁ9ó⛵زêXÌä7¹õ+±6”¾²†|I¹–nÎïLDæ+1cvG|8?ÆÐÀÚ<_Da`(g×9o’= À=îÖ õ'ZÍh¸Ùh·ÍÅåS{ÀžÈå02LÊÉʺGó¨ñeLFTª@±C³¨|«&}- ¬¥gæNàJ‘›ÐH&[þMÒ1ë—­›æ¶È;fe‡`?Óñ·ý *I¯¼LóÆ1Sç]š¥E­h¼/@)~ œ0*u•RÕ”:Ô>{íܸêyoíço¤iÀ^7›ÝÇÓö(¢_¹©”(!•9”4³š(àÅÜ d”„Y#å\hþò“iŸáZtÃùmÜô×(·2CƸ…c)lîOÚÕ†8i¿ù '2vÉ+ å?(Ö¥9@*c%‚&¾¶óTÜÆn;©k½ æ< gz }R¥`æ·cLÜ".GâB¢hïê×ü°8±hN|èvMó¹2>\`:ë‰Uïs‘*Ç××fSÊY•ÞXuÉ•ŒØÌ+ÂWQ7gÜ›@’.“?f®3 <~®Vé}Fª¹¦CnðN¤ð™ùõó ù@ñ]“ðBm ’èZÛÎR«;öNX Žú‰¤—¨SÐ õwÌq‘•1ºyœ%y•‡ƒgXLMaRBʌҿí(ñ¯/7ilR½VÚØLB?‚<~Y5PÃ"ÝäM¢$°ˆ†0kÖ_±ñ—ðÀ$šXj‘zZ»W¸­6ž¨µžÙÌ„׬ÙÅÅß<ô¢—ÊX®!>eM¹;Ó5dïúmu{xûÆJØ~#ˆp`‡b_ûmxQ§Ìv^Ë«ñ‹º†Etºq.%hc%d!ƒ0V¸^¼—²¯Kà¸J5‰“µ÷!S­Yà™ýàðfE£Ê!Då9ÇN+—fs´}¥€v4ü=¬Â]ùë Ü¥ædDþduÚç/=·µùžÁ\6ßõqÞFÎÇei‡dQ(;ï×7pVžÌ7"Í©ÞEÞ“zHÅP@Vn5`N¼cxÎw&´œDŒsQÃ;£¹ÆùçSž­¤Qåg ±dØfûÑ¥œ˜!Ýa'žõÙ†tïÞÏ·yEîäÕ…ïC„<ü.›‰ØÎ/ûü;"Ò}2(M¼¸‹(Pñí ¤ƒ‹ömM–Sص¯¶'ÙÒÕÛp¿9#Ð NüvÜ‘pãgÎÍ\)µ–mx=6œÊ½ðÊ’ßëÎhö-3ë]4]㜖uv -X¿"­–«ñ—fhÔ ˆ¬ç*nvtÆÙ²i‘º>ßIöEn¶ÎU1{W·øU‹¿¬—ˆüÇ@½PLBòúõÁïoFýŠèl_nP")Ÿ ?_=¾^•ù"§>­îøtµë  ‰Šæ¶Ž‰œÚò i±ö_Èi¿™1ª?mv°ÑœÁVis?Ûé“ç¡4í%«èëÆ0 ùÖ¦¦€î|ù¢þh9£Æ©¿8KçmcuCÛuéGý7EØ3ˆœ´© lÕutá ”âŸ8ŽoàÕ3¿¢+’~ñJœp^ìf…ŒÍÃÈ<žkí8ètG®l_Æf¦:7`VWJ{y§¸1QVùa!ö‚gØøf$O?RL àtkKMUÝIm¯ýB'jŠ $^«RÆíA9¡-ôk*J¡8ug(0Ý|šEÿRìv"”¿|¼-Û*žVq$3VðškÁÖ‘ïó}M4…ZŸÝù¤'àe"9‡G%Uc‚êyÜ´SíöÜ»]ßGÓ('yUÛèËve‹›Ìi"G8¡Ñ=XM7zÄß–}mc:5rª ÿÎÐæU;¹£lçˆ ŒªgKoÑÍWç°µ×Ø@ј0uN¯?šm*.EôÁ{w¸½«õ®µƒX2’˜HK¹¿'Ô EÈêQ©žföª’˜œ(üÄÞUOúaÒò#®+êj3׎åñ–Ì Êˆ7,…Ün•‚â ,‹çE«¤+·öñ0‹QÆ)ì±ÄëytM5 ¾S(ídUpXååEóóB¶˜Kߥ~Y.ò.>“c'ØN ãT²´.ï‡=ì>ÈÏ;Ù^º.MŽÈu}}<èm>8MžlPZâ{2Öá„RÚ[Ó·Nëç®ZømÚW•Û¦ËFƒÜaD!ð¶ÄnMcxƒØÉÜ]N-ÚôõÓÖÐ_L2 ’¨†­Ï¤Ñ¬xä²pÌ` ¢Š¡&„Û‡ø6uòqESH×<äP·$A䙺¾wü•g…²«ì’‚Øg”KA8XõIk[`ö'¿}VShy3áol0ÏöÎëPû’Ÿ¿ßç "h|%OeÌèß g´% “6–ћݻ b ÐÁì”oBýü¸È?U ìÖ ªÊã.p>A¶'…¤£H>žóêÍ÷Íè †’{5ú£( á]–…p.nTÂÅá Ä8[ýìómÿ*DÙ´!RGyÞŽëÏñó4h[¹±kïbT2R'A籊Çg¼PX!ŒJWŸGš“ã ªu“WÔí\õ`Ü®¸ >ûÌ%hèÛ»¥ö)¢ÎhãÞÜQú‡cÍoÃOl¡7’‡XgGV­…%È®þ(ÜÛÐ^ÉU ÑZ7sªó¤0«Il§VâQ‚5ú.sK Ôq%ìYû‘j¾DÔméOÞL‹wõ”.F^ÔÐçÚ­7“õ˵7Ë‘ÑÂ9éëÉA õãßÂ<£†bÃ×Û‡vfId˜lÜÊ5Hcý˜“—_<씮ǙbÎÑd 2JÂ&ç~A>œ,:Û‡ÝwGúˆ=W!Ê)‡§ä¸æ§'ãÒ‡0U½›E€7|Ècê ï`Z=ö*G·ê3°eãÈ>ŒA«R UÕ–0›|5%£ÜÙcO`ÍTHHdOÕ×xëz %dŠl½µ)k7q­žå5Úé|*ÍãÃD€otœ°ŽâÅh ÜB†¡CÓÀÍBbe¥Í‡aAÐÃû:À¿UÙ$„1u!Ò“¾8Ð4>V–e©õºŸ•Õ 4K¤Þ<Éø»€‹Õ>’qS æô‘Pû<|sɘ숻íÔÙ&y·=xU?òT[ôS–tž­ä¡eïégœçµ'Ãx±±¦·£ÜŽ;Z4?¨(J; !q ½9CjE¿®ûÀéãOz»v¢ìJC9»üõ×vOŽlaùÒ+/v(À¾ oÄ(Ê-×eî‡W ÃEÒ« ZPwæFBÕRë'gÚ/™7 Þ‰y+§/év2ê*~Í Ò:íbT“oñ“ÑÕ?eJ³œC=8µYLvÞ{íÖ/³NMFk*|®Ÿœ7HaY>®Ìœ™B);´¡ÓÛþüo™`¤0g„¼ý Léƒ}¶¤˜}³LØ÷èR²xª:4WÏvV¡Ñr'4ÙEóu²sè1D¢•Aîr)Eüá0Ù_öùðIø… å°JƒdGÂà“Åü;>¯”©;¾QT© þuGeÖ§ C·ÙýœT¯S¡ì[lÊê¦ê±‹C¸.a¾aúzøØQDl ÏBß©e““x$„ÓeüØßÈøÑL¡©uBß>Ìpõªâc.èyè]Î 7ív×Ýd\^ÂÑK¾o@ãQç|Ñ–ª$i#K§ÕÃÊ&¿¢Œ¸ ÿVÚŸ6³ˆù", …HiÙÝW‚› ìE§ Nçá.tûcïë¼³–6!úŽ»2•²pÇhÄ3€<óœÍËØÝ4ÆŽ!2~BL?]:œõ ÍϨÓÀ9Û0Š6cÓOsïÞT;»BØ€[Û·Elҹ̞¡oQ¢DJˆºO¶)9QÔÛEä»óԂøV~D+b|µ¾i((«-„X.|pxÎÅ& ZØFï=á124 }[F ‡HÕîðÏê”Q|D8îÄR+™à»û$TÒ§ÿz”£-{ùGª¯ Þ PIq@Xõ§ [n¹gŒ$!½^Ô—U·å-”äðÔ‡ 7ùÞ½¤A™Yþå„HœKb«Ya~.ˆ÷¤õÛ ÖUy—H[òüüÈ-J=Î}4ÃË&¦‡‰çP×:¨’ß÷AŽÈ”Ἂ¯pe<‹ÿ«þ¢µÚKIùgÙ]8¸ÎßæÁ3M‚éF8=²ÖA»Oåv_£Wgàâÿ°%.HòFßÛ€‚õ7ÑýŒÝ ¥–_xÑ¡ænÖVNÞ t¿·¡´Ë)Êz³e®·GkŸÏÒ5`é«%<±H@åÓœj ,D?RP¿Ö%Oˆ21T –óÓ {G7ä·ñö0>ÛÛÕW½‹Ÿü­?©3=âˆö¨•Ð)Á†2åEá;BúÏotz²ÖèÈåp¹dŠÎVbØ©~ŠnkðÖŠ$Ѧ½ÑN[NÂV¼`š2áŘ(ÑéàÏú޼V7 ž¦jzN“¢G½#ßIz@C"ɽiQô™È ;Þs#V×§=ÂÙ(” Ñý6þS@•Z(´—øQÓO ]à1úµ¹ÕòÜrÌžYš¤2ÃÚS1 hðÁ±Ò*—¬ûüüQŽ*úð@JG¬¦)œ$j(Ç ðò> Üïȶ»ƒnÊÇZh7áðGj¹¿K¨1V¥OäšV¾å4À©šoTÜFÞ¿¾„×Uœ– :P±èöTÏL3ç\O^É?ùE= ĉ¼õâÜïÒ2ç^®ÝèîQòáï¸C‹jlÜâÉUm }L>Ð7ýJÓFF=óç‰\Ô¼*j¯‚ÅcÎm£+ªè¾÷è¸Ù—kï¾)DÁ9*UA{øã'‰9·¸ ÅmQm_PÐêÜðQ¶©Ý“ø¥‡^'ú#?l_Îð½7ØxÅb¶÷VCѳŸøÁZJ¹ë팙íÂ<FêVòntµVÿDÄ‚J—/«6Ãu74,@nÓrÜC’Ò çòŽ6,ÝpÑ·a F*˜âu cšÀ/0Ã3.w®†bä‹N8mÀÚ¼˜Z_0 ó=fŽX#5*¤ë˜V˜©ë“j)´‹{³Y¸ž”»kÚ.eñÿ]´¾ŸÎ™ÓÕ¯ê ]G­™å¡S±Gšº“”Cß«º¡£àoV½-ñ¸ÈWÈ…N0.¹Ûg¦iÈ ÐŸbCmäuæBy±Í–eÙ%ÃcNJx‹xžÞ˜ðlD_Bžägž”÷•mµ ¼ïCúq_¾e|r#-9P…DFvM ·yŸÇÕ”¥Çº/µâ ó¾ßóÎ>_Ÿ½õÕ%xËÅ+1Â1Rg/=pH  ˆÀó ¸ô'á.Xï«àƒM[æw0Ñsš„ èSëAÆþÉÂyPIIúŒžd…u ]?Õ@T:#\C²½“ÙÝÖk¢…]NÊO%ÎM2a÷xÐDŽے»Ç_ο‡ŽT†8Öà.%Æœ¿ïî©Ö` Õ)¬ÍîîÒaü‘¦ütá9þõ#37sìîåv¯`GÆ·Ka/×é†pu¢4œÈÐhÎc"ÒÆ˜–Ãßyɾî;µžbª'ÅaÉêM<ƒAØ1㿺Ý\vÒU4é*tVÈÂé+E¤ Œ 2„¢´Òbc†§€Ò`o‚2‘)âËà†wu«¤×¯Êb×ðZ´¸ “¯É<«ëÒG©ë^¢²æÐ[>¯åù:Õd’3€ÙÛ>òxžÒÌÂ]ÿ|®{ï*¬¥žT1í{H_ïÕÔüª²ŠµO…üƒ'ºŒZLhAТP!É€/:À·ÅÆ!7ÀEêœî¦hê–s ${°ìÓ*M[7Œqw÷d)Ùwûoâ@I©a­À¸{L´¼Ø!3bÎÆʈKÞ¾íÄ÷i˜G?„"#ÔãW˜*žLŸ e‹Ô““"±WBâ싉çåaŽÆª6;¡Xœ¾xS%·Å ˜Ìþ!γ)Ö‘-!„Ñ*¦ºû¦?–NÜœ¬³ˆÊˆw«å*ˆ!˜¯”ŸÝ´²(ÔŠýÓ5Î’—wÈ{À+àYjÕ¹™–×E CþtíŽAbfSUáQÇÉ·ì-¬Þ¹I v”/_?àNtwжÙùð× +Rh[´z×’£,1Vh¿"û~2ö"6¿(êê ä°Îig¨H«øÕ÷IŸIeyÿïÌ íM ¬‡O&Â?|£ÚÌá’²—rDl75¸"SX•’ºoNµÏ«†©ÆŠ6 }¨b Ô×µªhIjg‹1û4yGÆí<0)lJ3†¥ª_Põ[£%{:I/Bòbøù¸DÓo›% “Pâµ\àç8;çjþbö~ƒšzÇ_ÄŒ9.{Ôõ …“¤Áä9ÓÔó;hoé SGuâ€WÓK„+9š4tÇ }ëɾÍeSÄ=âö ûgÂA—ZwNL;<¡kPãªÛ=Åнý¯C=b7ß¶U¨ÌbY½L¥aÕ.¨Înr Þ®b *ÄŸé²µÂÔo¤>°«Ã›ÇÑG ÑèíãM6ê0WÙzGÒ ƒ˜Än”g æ*œKì4Ń‚×\ˆæÑmUeωé<€7¶i½À |Fú%o§mäÑ3µãy™vYP–j Vge‰¥lxo48”ºÒL¹²ÏhCPnb¡{{éç5È÷Ù£¹+ki5BÑml×V™ûCòíd'A·Ã0@¤=èò]ï³°M¹²¦/¤É¸]Àÿ¿üáþ€ÿ',íÁæp$ÌÁn‡ûCÿ!üendstream endobj 1469 0 obj << /Type /Font /Subtype /Type1 /Encoding 3111 0 R /FirstChar 36 /LastChar 121 /Widths 3118 0 R /BaseFont /JPZYAS+NimbusSanL-Bold /FontDescriptor 1467 0 R >> endobj 1467 0 obj << /Ascent 722 /CapHeight 722 /Descent -217 /FontName /JPZYAS+NimbusSanL-Bold /ItalicAngle 0 /StemV 141 /XHeight 532 /FontBBox [-173 -307 1003 949] /Flags 4 /CharSet (/dollar/hyphen/semicolon/C/D/E/F/G/I/L/N/O/R/T/U/Y/a/c/d/e/f/g/h/i/l/m/n/o/p/q/r/s/t/u/v/w/y) /FontFile 1468 0 R >> endobj 3118 0 obj [556 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 722 722 667 611 778 0 278 0 0 611 0 722 778 0 0 722 0 611 722 0 0 0 667 0 0 0 0 0 0 0 556 0 556 611 556 333 611 611 278 0 0 278 889 611 611 611 611 389 556 333 611 556 778 0 556 ] endobj 1465 0 obj << /Length1 1166 /Length2 8998 /Length3 544 /Length 9813 /Filter /FlateDecode >> stream xÚízUX\]¶-’àn ^wwwwwHQ@/ · îwwww×àA‚w‚.÷éî{ºÏ}ºo÷»{?ìµÆ˜{Ì9Çšû«—¢¦PÓd·pø’q°‡2³³° TÀv]œ5Í하5@V.€WÛ…šZ µýýJHB@æP°ƒ½”9ô•ײv(›Clv66>nö×5ç? 5ØÎÁ ‚‚ ¶`ûWJÊèb²‡jº8:Ú‚A gä,°|­ì?³$= `+k(€N[C—ž‘‘é_;???à£Ç?€Èle y]¸‚lÿÊô*! ²A^‹¶ø+VÍÒ\Ú ý«]5ê(ÀÊêhizÅXœ-YìAPVú×B¥í-$ìþpFùË3)0|mʃõß}³±wp³÷úØloñ·–,\YµíÁN. y©ÿ ~…Pþ…Y n66~6È rZ³þ•RËÃô7’ý/ØÜÞÂÇËÑÁ`inë ò[‚^(^Îæ® âòñú߉ÿ¾CagX€PÀGÕë1üKýYþ}¯l…€Ý†l,ll춿_ÔÂÁÞÖã_á*æv «¦¾¼œ²ã¿÷þÏ( ‡WIfv^.3÷뤼*òssþ»â?½ø‡CÕÌÁÿU'Û¿$åí-üoçÕÇ´ä ‚8¿Î&€îocLøïú*P0 û×è±q³½NÍëƒý©ÿÆÿƒõï9d\lmÿæ Ýßí¼úá Pü刭9ä?ÂÍíÀ¶ÿà ÿ¨ úûôÿt䡿¶` ¸½•í?m;Ë€ÝAj`(Ðúïãò—-þö‚ÔœÁ}Éfvnöã´¬Á@{³óëYüÙ[ü[Ji{ ƒØÞ   }JsˆÅ?¿h  òjÏßèõÝì-Á¯‚@î Êò‚P0ðSm`û]µ8±óî$göÍ‹ 9J¤-ì6 \¯Ê{›b®œß|‰RjcÖ"•†ðÊð°Á1ÄÒ‘¼n6ü,ˆ8¸A8pr¡DÇ,uB*hçHtÓl}D±ï¿eHz ÊQ”ÝèS‹HNàh;àû‘Þìí;©"“•åU «î/Ðó<øŸªÊÙúª |é”bûäò U¡«qæžVÁµñø·¢Çl~¡_Ûï{°, ´öü#±~ ¯@çDǃui›åCõˆc·§±ã*Ó@ ¼qÑz¯!b¹ÑÆ!~ 8Ò³ŠC˜´Ý4\)D‰ù|×µ4ˆ*®­áˆy¾£ôA·Þªb~^톬OÁ3~³NY»;Ü¢>Ê”|Æž ÅJè§WÓ­vÇ¥®xìvßppC«Ïj‡»û¸bO ;·ûœUqß¡c†&îË\/¨Ž\ð OMCÆU¶êgx†«håN+d,OÛúÔ°KO«×ýb{\Öè#׾ȧ4Mø.+2{C4Ë º®:W”—¯æ÷¯¬ñ’¥û¾r7ûª¥còò¶ÈeaHd•Q¬ÿ—¿ïŒdb?g‚'ì`õF5÷³W3Ë,Ïôm/Œ\Õ’€Nœ‘']rýGÇz±XY¼çP°—ˆþïŽùÜÒ)K6jݲŸ…ÜpyHÄölžš ™”ÑÉvJÁŸËk³s'ZÉŽó!á‹¿n”ªRÁJ[­MöC?¤ ç¶Ÿ„Ev…›C¿óÌ ë4¬ÇcpŒ\¤—ç³ÔiÏ+’ íÎ7ü¬UéL£þÝØ€V p7ºÀm°¥}¸$ 5w- ˜N·YtÞe½¸á1Ô°vøv¸oáÉñQfIÅ[´m¢î\ÖÛ#NègW¾¼ñåg¾žbÇ*üEÿßýð%ù.¾‚{IÎfw‰ê¢]ió‘¸ù&5‘ Únˆ4MH,Jœ÷R™v wY— *ÍÏžtŸþDæ'‡Ÿü™îÓ-qûlZw¬‘ßzpƒüƧ¡ìŽž)çÞ^~#íKÌýËCØÌB@Ð[¯ßMú¬Î‹pì„l”Ó̡θ®ØJ$ð0l¨™ì /•i¡IúIFØRCw40Ó­%´e=|Ôd[S2†Üø%=5ÔL¥ÕS´|c{ƒÏb3Õ7ÓƒÚ×ÙfŒ–³pšö7„®ÆÕu˜*¼§£´i^šNÊ@ÝC"™Òû×§¨ìžÚvĤ/.Ç#Â?’er8}Däê!¡°O<Ñ4ˆ’æZ.ôÒS&/—Å£Aýð.JïY%®Ü̳_p•qg£  ËÈÕÉÌæºšaÜQ niAJ¿ÃthÊ£(ÒÈs—”5y‡wÒ¹¿K±üûèXéèˆz áüƒOHs"î™àˆ[Ž ÕEø ^7V( •­äœr†B!t+±ÅDg*v—fäÇ{Ì6Ùx¨E¨Óòf5–& öÜ{RpSŒÄd+Å’Ó€áJ„m%wFpÙ‰iW[wDé‹ul™sÚë­'ˆþ!9¥ióÝ„8A뾦 Gw”®õ’/áŸÈÁBd‡sŒº Ìûc:ËÕ þÄl›—P°nâËÕmÏÆ-i½lÿJ׫f •uç·=+DíOÓ-©0®–Na®ì úÚãÏÆJ1]TGËøÀl?˜Ã¬²^š®‘Œ\Ì<0Ø'4&ËPóë1„¼ƒÎ£&ÖJå ÐÀü° 2gŸ¶ép®À™¿ÝC²Õ÷µÆJ¬RèxŸÍ¥—ïæè‡' ³SGìbÞgägÀ$¸<»C‘ÀnÞ²L‚`²ú¾Yͳ_õBÛÅÝúŒ—øºë[­°½çía¶Ãé7F÷rDƒÎK¤/È¿-ök[¹–±®“Ã~D‰±†¹È•Åö¤uM¹M¨)'”¯Ì{ù¤ðÍj½Ñq``|¬nyÏUMþ5f`g8eµä` 7>W.wcƒ+M¿ æ+ ï‹× )ùež&pþûÈñ‚ˆ0Œj}¼RFðÍ8yµí¢3.Ýiw·^$.u6Ù‘Ö†žAqõÓð Þ•óú¯Jpq/—g›{Iõ£j°Å›¢Óoæf…"Q}H´qÒn\­{ï~Ò{:J[—Ôá{¨ñ^È–çRшÈnä49k|÷Q½Q*擲ú¥*˜º°¤z|½XZ•¢vq°þñ,ò#Ý@5¿ˆ,;0,Þ¢ÕBf¾ã+¾ý¸Šÿ÷©(‡ÚÜ•'°•y[g鬩æš~‚º¢rd`!ßD9(e[M‰!–ȯÎÞ¤yHîI2;õ—:½8Z>ˆ`¡Çá(†TtG‰åG/]KF[ŸýþÚOªÉ:ÃÌÉô16¼ä„¡rŸÃ¼ `—8—eËg’KÎà`DòMY=˰‹áA ÆòÃ|Þ<<ò/òõèz§w~ví‘ R4,*^í¶')dˆR¸8w­´£#ì8ÈK,HƉ´W[·¸oìÚ†5älÍ¢Yß™HÌu·1ïÚ*RiϧýŒTº<ò~¨Xp^ñ,Í·«q¤e©…Úvâc®²’OÏ7iÿXWb¹Ülª²ÊŒáb‘ȉ­ÖÞ¤š iüZÁµrš±-L'ðaÁ¯MåR‚^Öý-’ƒøÓÅ8k®»å_ÑQ&Tg@¥“Á%³.ÒªÚAõŵ7Íj¬ J©T64#©÷µ<7ߧׄŽZÄïõ£L5Wi¥˜//4Åÿ4«%²531Jƒ-¯z Î ¡pír׉t£/V ö’ºñ^«*IÖ×8Í=^¬ZuY¶Î\‚i]ã”Iܸe×ĨùïúÄê^–®¢`µâvK´êÛ}®›2³b›üʧ³ªwë•0±È°0Ò#—;¿'íˆJÓ¬]ÙFbÉß…ÖPrÅ[³ Üô]RHaÚsFnãË!‘ŒÆ S†‰÷÷Ûá¤EÌþ00Zu!0ߤRÔeæÄ«øü¶Âýˆ…jvâ5¨Å(%À¼Èùm¹Ëm¢"Sˆ}Û¸ãÚ#èêÆsZWMq2-øè‰¨¹l~•µºÔÒªî~öÞWñnuq쥗Úx§böœþ#wç¤dà/¥7XøšY×Ì— õ?/vã.§ä09ÍFÞôRŸj!j©tÃ-*ÒòìТ>gáXÚ-U5냷Ô9¨¾-W Fº#Q©›$kaîzYDqÅ2‰Îº bìÊIÑñ0Cöætyyjî‰ NñßJÃi½ßæ<ñŽê4Åð­¢”]°­8ؽ2TùB Ïpij˜©ÓàÂw-ö¨Š ߸\K_‚zq¬uNé|©¡`æ_T·úÖòt" tOöÆhfûŠÔG¥Îë´.PFæVS±Â\|^ÇàsætqùfIJ†öKdË]Ï«rÏ%n"¦j³È½äoƒVvÚµ C‚/“ˆ´¾„ª]K÷]Ï_ö‘„>ˆY  ®ŠW­MZˆ¤£ó¥ñ`ŠDŸ"8K®Á4í ö ñ„ Ч©"ÊßTÙqcüªåøbý¹Öñ<ýNŒ§Ü!òŠ¡ÁmoYh5#b ¡èR€7n\Õ–¾1®°\È`}¾!-.¶àänXŸòÄ1© \(“…Ö/löó£|÷޵dðëóú’4]Ë““øúbj’Õ$‡Ýüi¹ßÙàÅÓŸ¾º-\]×ôp)ÐUºuþ÷ÄR·yŒW;R½E5²¤a gÛ{ÊÖ—Íjä»söØ[ÂÚ¡–‰Ìì(õõø• æ,UÖ ö@Î{„+­½)¯¿ÃdY_t:.iÙå‡gGŸ5\\¨ú uärJЬëùäM …ðˆ!„Ân IêwH8§Ÿ]Å’ñw-çYZ⌎¶Ès¥zÚ±ÌK!?Ĺ·OhÿÙ­74ôƒ»Jó],'QŸc=4¹1õ8f£«+´‘Q:¼°8xà¯> ÔQAÍ9<`©OtÜžrý È›(W…k¼2¥”µQäØÈôîT€}à %)22ƾy;Î#LHçš©ê\Ûe„å²åFdƒ•„IG4j§JÛÎO¹™Ür-IE-ºø@‘Ö£¾i²%ŠJ e÷o/>óß´3ë+šÙá‹V Ô{Ì­VxæÔ/‚'ýÎÄü¿ä¦ß4H›)de¯É×—ÈÆnd:‹O]oFáMº‹2º¤k‘uf$“p˜? Ð\I¡3à"ÎH—ùÐB·y¬»„ô*á «VóoýZ…‘ {zÁ›ßÖ5·y…ßÔ&ÏþbˆõÊzO?S<Ï·Å„µ 6z%F),ÐcFF©…y÷ÌËë­<âwç*£²ª,ý2¥¹w™ª'äŸSöÃÆÐú@bý]Æ6ÄI:úñg2ù#æ-Êpºœ)ìÍç¢)WFaŪ0ñÑê™ÆhµÌŒÊ¬§Ôš2 I:)k„˜Va“Ôôücó¨Öi¼­%! ‹/¿ßÚwDI 9G8PDNÁ•Åî¨na ý9 yQëí4øÅ—šÌAÙq@Oó‚®°—)×ü„,|ùLë»GSµïg/!ÚÙQl>ìsÄûV\p…Ö¥/DÐpuf¹¨Uf‹˜¼ò¦Ú:²rŒèœ¸âA?­Ê«À™åžƒá”E\‹–;©]¯ÆŸü'-i¿sßRƒ„»&„¥]Ë>ìp¦ìhÚê$£ˆ;×Ð}ŸÞóüù7U{5ª?ð¶Ï-®Š¼÷k¨®e¥°OÍõ(«ÐJO&´`uV ´.•x6mŒ6ÊF2O»YêÐÒ‰A“*Ò;ø~bîÍî[¡Ð6@šŸ †•Ué S\Ô÷õ™°Qô‚ˆFP›ÉÌñÚˆøòg¯]÷áÛÕ_˜ÊïöPÌ¿ðÇ—;J\»eéq1<ð}Ÿ‰7ŠI©šØÜË:¹œkÔª–! öñQ9ýó(怦:dßJª¶@z–$ÂÊf()ˆ/¯ÀÙÑÝ·1ß°û‰p‚–ÍsÄQü=Ø‹qyZž™Mw Æj4b ‡ëßáT¾¸WÓÕ׺Á¡ó‹ÒC&ë-ÜüKiêtFkL~ Öã&mluØóŒ®øo«*¬ÇØeâÕŠcÒbF(i’x¥KÒ.8fRÊ¡°Šfv+V±)‘Ôybòè@˜>R˜yÑJT´3hΠ|W¤R jíCXSªþ0Ũj”nZ(­\iÒ?35¿ÙmT©TЦ‘?©³èÆk³c|ž"/1$fXâºzéUôXÓÔ/ìŽL*Œà«=á°‡¡œ)¡%²á04>Ì]9,±;Z¶%áñ¿]ñrkt¸Å¢’|¬ázÿ‡ª‰}SàùW¯ø¥”rAÿ[ÇíR!’ Ë‹õMïZ´À ¬ýa\â9MV  ÅH ôUG¸~/+@hé¥ €0dÈM_ê½KÔjë©j$„!KÒW¸ §Æ‹@½’¤ßË‚§º$7¦““z°òSçÅk‚ÜÝÁ¾Óüa¹2×Wëk¿-Gãœ*ù¶à:’˜¾µf÷(Š\K.3Xº½ZÆlå‘aôr'G†d÷·º«Ð9>´qÊ)¶¿„Ç•»®($Y6¼½ÍmÀŒ aŸ|v## ›¨?ß»SØ ˆç:9°YnS]K¹‹mýÈîiÄ‘}-ËÕÜ+˜â “„jŠêîÜðÁÓȆ¤£r ßÜ_y_ÄŒÕz„aøa6Á$ïhøhîdžöN¢Éãb¤ünpÂç‘J’9% kO’Œ.ç>ëÐj•´†ë•ŠFù)%þªHèaðVA´÷ªÐøh_Æjq+±Û`I¦(*‹ÐÁð§VT¦ºWÿ}ÀžúŸKú±®ë½ +‡÷pÍ~ôM鹊ôøùßGõ¶>QVFj¢õ$¦.„z¨ÛN}œ~¯Üÿa\æù\25„¦nAgÿ·XGWópåå÷€cžÆ•Oó0äVôÞˆ®O])Ä5 üî)–9NÏXDéÞdgâ‘ýô>Ž>×b¶8‹¿ËHÏЗ¾6¿w4u&ÉgŠ˜ª 6œx{{ß6Üp[ܤ.4ÂéO{b°ã¹§ÌÔ·cïoœ?fŽßw;dÚék†œê矞XTk^Êû¯má!“ÿºFsÎ|ð´tÓ¥4L§Så3“*‘üéÞ¯ û8¦]pk7ÿ±aMäg…ÅÛ0ozhò库znj­ÜX^—ÍN‰’Ç…û»#ܧù¤•ê6]™f({.’d™c\› HäR»qNÀÅ[÷–ûÈ(…¾ùƒÉé#F¶i­6M0%_8{—NlïrÚ]!ñšmó:‹§¹;¨ -Á<}V_d*¹î2iºtGøþ’CY73ñNó7™ È.ú[Ê7·’Ñ*ÛÉ­‚Þê¨LŠjIO ÏåÅ¢åZý­EÞ\ÔøëýÊz¯©‡[rØMØPr&~zÝà {ªú`…ÜvÞ7ªá¾lv¶í1Sèp8{OÍ—¼UîÚµXË×ñIEÉý$úÅ®‚Cm o,uWÔ­œƒ}ŽmIBí¤Ï&?*¤yñÞE6{û_ÝJæ%¿ÈÜ|ЪR§{±2Rä úU$û©jÛlŸö¨(˜ÞàëœNS0OvÖ;ˆ©{ºH¡Ê¥þ•ýËá— õ$&¸O8`\Ÿˆˆh0å"ýïmB¿·¿Ÿ¼Œ°£ó'½Y>Û-#Æ0sgîŠÏ=öË©š:¼ß§{:Ë›3ïÓ4IròJÌ£Œ@ïéAœÔùä‡Ï@tz³õKËÉ$ gç½s)”yòñécMnVÕTòáÕÉPܼ Òc0‚úB†"î{½Br Úƒ¯à ÓV¶ƒŒšÁ±TcSp‘!OèUÛ Öwßêðeõ¬=½‰ËrF7¦¾ÀȾÉHg|¾©=êãŒW«÷aØÐ½J9w7ÄÑDŒØâ"Äå…¤óÚÇ=ZÀkù b©|Õ»v­Ø’¾M·Dìw&¡Ëä Áñ\ÿS¶M ®»Éû2uã,j @ŸòËÂ_~DY C¨rRE¯ÁÌŸ÷¶¹ì%Í5Â[õ±'¥YªÜãŽÚ%{?xŸbé{ý‘éAI|oOz§‰·?f]-X¶1‰/‹ß>ú³\ó¯2o2ãŠò|‚›š¡I p“)RCÀ2>´½3ú\×–QkRb _lŒs"ÉŽ~á€Ë+*‰ækó;úE—2ЄÕYM9~;׬÷åûV©›Hn ‰¾M†uÛ× Np~Gþï 6þ*•}c¥=Fd¾xLúì|(>´¦É)¿°õI£ˆÆ)ýw°^ml¶«¼ãÃE R ̺©_ôŸx×ìÁ+$Ì ŠlC¶F…Ò@m¾Üƒ8%™ð £ò,É ;øÔŽøý“(NØÈ¸+tR׃æªdtccƒ090•HP±±T5ñùW–†šîͧ;{Ÿ !¦7ˆFÍ)õ·ÇSðÆ,RZ¶^Dª¡VT*ªÛež'ì“yndôõ¯•¨†ÕUºcxn²g %ÍgÇJXJZï ±\é]`kݛђÎ`AüUjU_#`=¼ÿ^*·´×,N§Ä/î¾ìã5òÆ•>k7áûp½kAHæõáÝ.ÕUÞ9têc»UÍEò(ˆAôvüD\xuvHç6õx2o˜ßvDù‹2Z›IS÷r“/Hºä ¡Aw…­ñåÌT–ïDfì–Šš³VÊß"±ütÌî:³%bÁ€³tVg"Ó@‚ð-ܪ¯M6?‹g6 ·fzãè­qTSæ%ß~•§öI>M!fÆéëNÕùÖ tF4û©”zœ^k– "‰bY*\Ã×÷!î]Žx¸mZ]®Ê­šÊi§òÝG`·‚C/Ô`øYŽYC¡©G ¬OîsDuZ×Ü÷BÏÖ‘E÷9„× Ln¹iQ|´ùHT%虄´æÞK¼_DŠÀŸßß8íGãR^­h|-muE×nyW ¿§Ëвð,–H 3È÷ç×23Öü~»Ý¹Ò‚š¬ÄO/>Êæ_·“¦*8Eº:JóÄæÐ”$ß|Ýy»õiwC¸öKwnNP³¨¢º¾O×óÃövv¥A¡z$Êr‰ºeÎcêoöôÑH¡±” fÙETRæ]$•è¨H1?¢ˆòu¥à´ö¸šo‚†ÆµâËŸ.«{Âû-fE‹h½O.2°Ía“|…ð!A–1zÓUüŸ'ÚËj¢@år¢+(C(v–nB¬ ´z~ζæà‘ù,îS²ËÚÜk÷xô¥¹v‡E•Lçm°Mü1Á–½Œ3èðÑ‹;º3úœË 5p[TÙ|Ë^+«Ñ$çþ Ms­‘,Æ5˵tŰ:‹nƬٮAH`ŠUWÖ/ó}ß‚@ ÔhUþs¡ô½¾|îRÕiŠî9B˜ù°Söއü²G}v iª‰å‹É¥xk$ÌHIœÊÎξÒÍÎ6¿rX½¶êSÒ !nŒ(—ïH³Ò€¶Óó%âÊž›Y*vÖ¢çY[­ZLÇo¼ÏYí@)LüÃóôazLÃÆÒ†¸õ èNg߸ÏPüS5¿@œˆ4žLðpp;,‡é1×±QWT=kIùƒô¼ ›ßÚ}˜´fÞo‘k l1÷Å<÷Èø`ˆ¯,Ë2›N˜ïª¹ÜÛß5ÜâO*5ždˤÚ5_eàÞ\ ] \j™“—)G*e|ÃÁzþÓìY;ÉU?²ô6µõnBúMæí˜bµÇM×ÃûA5ñ•›»>)™f–ôoŠ1Ç“,Í™|à6ûîRÍüÆÎ¬ƒXo)ûU[8`]Ò„mVHV7¢­•žß2Ãî ñʦ€a¶’‹Èq؛ݺ/÷ SêAŸÄ¿È5$ì ÷L~T­×ìvLé$ʘåX>o3m þ+ÀßÞ z?º7·žÀXµ=¾ñ·Ò“?ˆ“)õ‘î¿éµþt2: Ù¸öxñÝ5Ôûø¢ ÇË„¼Ýj¯ ?0hE½÷¢HnÇB0?ëN'ÆsÞÈ’rÿU§—Yò";f÷=%P4é­4LÐ%Ìøvè£Û^êöœ(œúcMN¥%¿~™×hNÍš$4°y¹kÜTçs]cÎ>ÛÄ/g†Ÿ[Y´þÚ½ƒÊ€”n(˺jw‚xîqý¾XgWrL«^¨†2‚{Ý0g†Ð®€krcã ïÕÛeuuÜÉVcDw§«®á/èá’Ú¡¦«Ü$ªTv)…+:Íõõ—O­«©âÇF¤vZI¦’lÿ—ÊÿøBh 2‡@ìÌ!6(^3Ôò×ÿúPþJËe‰endstream endobj 1466 0 obj << /Type /Font /Subtype /Type1 /Encoding 3111 0 R /FirstChar 2 /LastChar 151 /Widths 3119 0 R /BaseFont /SYIHMB+NimbusSanL-Regu /FontDescriptor 1464 0 R >> endobj 1464 0 obj << /Ascent 712 /CapHeight 712 /Descent -213 /FontName /SYIHMB+NimbusSanL-Regu /ItalicAngle 0 /StemV 85 /XHeight 523 /FontBBox [-174 -285 1001 953] /Flags 4 /CharSet (/fi/quoteright/parenleft/parenright/comma/hyphen/period/slash/zero/one/two/three/five/seven/eight/nine/semicolon/A/B/C/D/E/F/G/H/I/J/L/M/N/O/P/R/S/T/U/W/Y/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/quotedblright/endash/emdash) /FontFile 1465 0 R >> endobj 3119 0 obj [500 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 0 0 0 0 222 333 333 0 0 278 333 278 278 556 556 556 556 0 556 0 556 556 556 0 278 0 0 0 0 0 667 667 722 722 667 611 778 722 278 500 0 556 833 722 778 667 0 722 667 611 722 0 944 0 667 0 0 0 0 0 0 222 556 556 500 556 556 278 556 556 222 222 500 222 833 556 556 556 556 333 500 278 556 500 722 500 500 500 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 333 0 556 1000 ] endobj 1432 0 obj << /Length1 1630 /Length2 12198 /Length3 532 /Length 13075 /Filter /FlateDecode >> stream xÚíueTœí’-îîNãîîNÐ ÁÝ¡±†Æàî‚[ ¸$¸Cp‚»{pw¸|ß™™3ëÜù53¿îº½V÷zŸÚU»ªž]o5 …ê' ™¥,ÈÑ•…ƒ•]ðè`ææ¢ rTbQ·´vS1³Þ$)°¥©+ä(mêj)ж´H[š89H4)“hmã  ×T×f`bbþ§å/€™×¿#ï‘.@kGíûƒ»¥=ÈÉÁÒÑõâ¿øÉÒàjc °Ú[¤TTuå?~Ðø¨ ø`éh 6µ¨º½·bPš[:ºX2¬@`€ý?s£ð¯Ö\Xß¹$\¦'Ksà{˜¥§¹¥Ó_3ÀÉìtqy]Ö`SG×÷;p€Žæönðn·ý]ôîáðŽ½“©‚\\]ÌÁ@'WÀ{VUiÙÔéjcêúWnà; Y½{Z€ÌÝþjéoìæu5:º\-=]ÿÊef °º8Ù›z½ç~'sÿ.ÃÍèhýÏ ˜`KkS°…½¥‹Ë;Í;÷_·óÏ>ÿ©{S''{¯¿£A{ýG @WK{+V$Î÷œæ®ï¹­ŽHl ‹¼£ÀÁþ»…›Ó¿cî–à¿/ˆþ¯™ax/ÂÔähï°°´Bbûr}O  ÿï©Ìú¿'òÿ‚Äÿ+ÿ¯Èû?÷_5úO/ñÿô}þWjY7{û¦ïð%xß2 €à¯=co üµkœÝ,ÿ¯0S ½×ø¯ŽÚ–ÿ(ößøþ–w5}¿ GëwaX88YÙÿaºÈ=--T®æ6+Sû÷;ûÛ®éha ¶:Z¾kû÷µ¾±³ÿ ¦a4·süKž@–ŽÿZþ»\Ϧ®­­'£Âô_mØ¿=Uß'ÁUÃËÉðoi´•Aÿqø‹GRä ðaáå°prñøø¸ü~ÿEÆ¿i8þyV6u=úì¬ìì€÷ßÿþódø/42Žæ ‹¿&ç“«©£Åû°ý‡á/ØÜ ~×øï÷ÿ½é?ÿ=ö––ž–æH‹s s¡ÛŒ¬L×üÜQiýž.èP§Òz¢‚À*Pg@FĆÀw“çêPÖ†qÁ×f¯Ù?N/; Œ»ƒ]xöti–§ù$~T ݘ«´­|L»AlF¥¨™GÚ1>g3Jë0z¼ìZ»›£jêF%Ïp¤ã­\`„³;†@*÷‚@ê['4óôºxÜ6Œ¬šÂ?G´Éw·t}C¿ú;/`»wˆ™râi„ÜaPi£sˆÅô4¿ûD2mCÕî’Çu'åòšbYÊ>¤†à}Θ)ÏSsÐÔ¸äõoËñýªÈ]’Ú®¾Pbt“m‹ÛšE qUíÝ·E“çCb‹sþÞï€I|w¼LY¦ìAŒÚ/ýMek ÿ&»êæ%ëźܵ¿u;Ú0‘`[º,9ð ŸXQÍmœoßò»™›/Ëðb‹Æf–®~è@/ù—Í@Hm´ÍÝuÏŸ>²è=(ÐÞš¶W0Br¤}i3ÖDH‡S²À~@kÕk¾TúsIJÅm¬cä’L÷Ä¥«ªÚ@*|Ó8¡Ë¤OÁ ¶™f‚yø_eš×¼¥©Å[˲•X6”,¾ !ø`€·§«Ssw–]<¦ŒiøCø®ë¿aacK ›‡&*ÔhRÏ»Ÿ«µ®GÖvzq‰1dìJfdÔkSÜ2ìXu'´9 Æc¾HÁ(;,#}┸ZBœÃfÇÿ"‡0u·w诩yÄ\8)ZM–XÛíµ¿Ü‡ œÛ¾*hÐ>ŸŸB„½êEÄžà=A¥#¿]÷}ˆº7€“ æoξ{ûIb+jæ„@‡)0ã\­ÇséiÃû{‰Ê¸M9¬Z^¼‡é4(„Þ¥s§>âw¼Wg‘¨qg/â7‹ãKúÙyyZ€âL~alâTJ$T¿Éa ”bew…£ K³Ë DØœp­6>;µ²b'kO/¬ÎÒAÒ°Èػƕ¾{ú8ñPƒK»8OäJ…ͨµÒSÊ s&8faOœ‰ß•ôÄŸîàaòEæ‡Ô„“ ~{÷c¬]¬JQÑÖw ªe‰E^»Ô@XQˆ”°^ÄZªKt‘‚êô$)¢?sî°ûƒ¾¦]ÁÉÃî?HmPëa¦Ëèh)ØÐgùšò›B|¯½"Wub¿:O »2)Pfæ*.—ÖŒ>[°ìÊ-~Äâž’ˆhÜ™6šTQ:V†]êxö/dÐu¡Õ½ ¥ƒÄÁ狪KSW'!d='\N€.u×gÆ/I:?¯~%nw¢çrÌ'¤ÞçMS}Þ®Û0a6Mhh5û&¨ô¸^àë!9u;êý›õÔ6¿,†šßzáé„ä%?>bTÐåûφc£LqØêÉØGºSïi,5{ÒGÛ!ä_MüxÞ«³ÎLUçLH,FŽÉ£…Ƚ[i.³Û lÌ/ÃëQM®5Ú~+còq(m+‘Én¹ ±Í]¾"¡Ó9Ò9…;z9W96°ÐTe•(.jqŠÏÉ,ÉÚMˆ8ß—–£ˆÍaôü‘uàJ”Rµò˜Ô=zMÕ/mɳb>¶ÝŸgå aúùöÍ(û¦ùGx¤˵ ñ¶ŵDº¾˜]~Ë ISd²1aI:<;‡Y?…Œµdœ¼W¶ üâHh2Ua»(¤‘eE3ö)'™ùú’Ö ]ëû3î%#/'–£ÓÄ%âã@Éã ;Û—`TÛÒ¹NHc Œ«ü*"ˆÊ¦^8„D€$ŒÑñJ|Ùü’Në„»)°-9¯j³õM¼ZSÑH$ÃT?%“§žôÉÕžô«øYž.ÝF¹Ôz®0ð;g}éÓ¬m (Lœð4£§þïi°²²4Üg8½'ÇqÕç¹²5 9ˆ~;?ÈM ¢B˜?•/Þ¡Ħe]czR~¿ð@ÌÜ:ÜØ 0ôù/¹c¸ðGy »~DŽ„Ø“ŽÌ鹿ùz¼•¤>ÙÔ@W×d9Œ?y•ŸJ˜Þ‡‹‚TäÆþøí Ï ‡,¦PýR¾èÚid^µŠ+—^2³m¤}P¿ÉúGŒŽžG¿‹‘…Fc©Êqâa©½XD`*ô‹¸Ñîð튆³•מT…§¬),‰Ú¶Pƒ9Äâ]ÅÆ!“Ÿ?è¢Á*:m_¡´h9¢6K˜=Þ ¢»¶@§š O=P±`&Ä6ÕXââà´ºh‰ÎÓCÇÑÏ¿/¹õƒRçþٻʦ“A`ä}PÀLMŸD»ö5 qþ‹¹ g.sDž>½È²!¼XsNWò<,„töYDŸÈ¹G¡•”XXS8Mz ”R» „IËØ²&ç"Qb?Ûð¡_=ìI™ý3ïõ´¤7éÅèc™ @yÚˆ½X²,.aµpÚBS˜411ÖW áCç4Þî?Ž¤óœ¶›L‘ ‰œÈ£òÎE‰CT­Ÿ¸¸ ZÆ»¼æ’dÈØZ|”Ö&\6…#*ºè]ß÷£áÄ—Ü&d¤Q£XÅåýnŒ0gFâ›Ö¹r&Ò(ØžóK(3ÍcFU325N„/FÉEá¬úÓ´;+Î(¬ð?©<ûhï0´²šbÛe/J^E«V dDóPçžØF&G Èrˆíeõ†ž¯çÓ$Œˆªð÷‘«– ›„@ÂÁƒê1Iƒ”z Ê JŽqÄ«0æ´îîaö>RÈÔõ²Ó±º&è¹m„“$<Ùh ­Umí̧Ü\¥æ¦ó²ž«¡ÏQ*±räeþ/ËV ‹Í”ÜðCœîVBƒM$ëq®O°¾‚­ÏÆóâšé< úÔiÜí\šêáþl¦§KÎÓñžŒ#Q 1F(3튨ÎàSJ°øÚáùÂ0J<ÖÐY¤¨îÏ¥"zK7Å©ŠCÓ§ÁÇd·›ÌQœ©Ñ]¼:öµ²xÖó=Æîš½Øs—´ûh2ßIìWôø~è/·¶ë8À‰ž E&w«šÒVùs2´{¾ôz†ÖlÔg|ë…‚SÞ”ÖQ&ÄóçëEóF|ÓÃz;È­øsýïÁ>—?p Û‰'ÍÕ¢5—¾à‰¸p S¾2Ìö%Q‘÷Gãw_îÓŠ¨«í‡âRAsƒ]C¸›ÓPly±¢h“ã/%¤w`õ~ëß׆úœ# ñ§šÖÀH"½/}o—ˆ9ŽÕANÿÓ úʉk9nµRf‹³D_ûÇ ¡>E–“¢^ˆÄ ð5cx󹈥O—Rn.?¡eßÑâ§Ò¤€¡qm¸8¡S™Ø¹!>¿À# д°þ¨&¯¾>Œ¥±·P½qQµ^èº"‘ÉèbUwS†˜?"Þ¥"ë8mžlá-ô×±õååŽÉ3‰T;ߢ‡L¥ ÎGº uaÙ I(ǃ ÖžCJ‘²—G„ÐM"&ï‰4<ë#`üDöY÷­áWúœfV MÖîÐl=xU 9ì—©Zk1œCè¶9VñO¼°q£Œ°I´hï ?Åyªé·8úúN?P…™ãKG;G¡3¶¤×åKÀÅåè F6f¦Ç¡=ÐWHmãÿÙºU$Ȱ˜^Á›!ïÜòu/’Jr§‰Ì–Ч¹‹a`¤Õ´e±Y ÈKÒú'ÿhJ­mBú2Å,äÎ÷ÇmŽÌù‰¦°9•þÈÜØ%Ë’Bƒ.Ôuù^Èt ßWWËÝèÎUÒﲕTc»¾¢þ¡íy¹ñé */Xþ*tBtBYv äJÄl¿ò#ô.f²Ækâ”ñfcC%€6)ê‘´öXÉ™¨àW›X½—@.ÎËä² „5Õšß¡Âx3­|.0Þü‘\Úb“"·¥ßõ”xï¯Ïâ­œ0Á >?ø…Â>¸6×&©­a¾ÿã•ޏôMBD:ãîHù¸·A³ i¬¨ŸKUì=\žýk\dóhYúÃÇo;gh+ÖR¯‘M^£ ÛaHi61›ƒ£P'&iÓ jÎ:‚ÓU¬ªºKØ;uÅe˜R)`kG€î´nwÄýÜÍÜ\Àc> ¨2]/{¢¦¨øáÙE¡ãΊR üÑwm}RN¾žJÓ$Ãîž§Ò²8D< 6µêƒªg‰C4YÏÜ…ñü$mÁ]2]XT Æ…õŠÞÝäèø ¹pƒ|3Áo³4øÓþ9ïyã*(ö~ûÞûEÂ]:|›YU"ú+JºRôU7.æ.D9 Ë«¶›r…îè\ªä”Tê~¨öÄRsé†ËK@SbÉí¢cl”UB„ÞÖ€÷gíUgyÏmõëiÈf›8÷½Ò–ãÜ&wê–"™àë^r©’ßÒŸtQUú$~Þ£Z;_¨2$°¯d:xïÊÐç, À nhm‘˜¾›ŒmQWéà$Ê«Ÿ¯ô8˜jŒµPÞ¾xlÃAÄ¥Œˆ®²¯±3yøòŽ˜+õ£ÂHωP´±?QD¹Ý ´v&ã5îI:2˜jüØ/ÓÆûž¿ÃÓÎ&\•4©…ŒŒõe¶X°Pƒš¯‚É®a­ VSfgw-4ð‘ä E„Üž‚›†¨÷QÀ§aˆYnk\Ï=­:Ÿ,)õøöBºLßö ›‡ìb”Ð3†’(€&ä2±kvwr/F—Õ aN‰×jêg!rÕ§(YBî5 “lœ+”^ÆIQçJÁÜøÔ›x#êèXX“„”I¬®hÉ©‘aäBA*åqk½Ô3/ èi5—#nšpþ”O¸ §ÖiãOÄÒ‘‡sªA-\×.v! rÛݨ½É§ÕW(+íhRzÄM }qàú—3Q¢H-T:iüc\8¼¶I.è‚»gàž§=Æuƒ@¿a}îÜ4Ѱ.Ïy g*ÿÈÕ=\ °+,B4Úfð{5á#“Re_‘›S1Ù‡ú„iëÜ>|§¦6=«ªÌp9DuTà¸Ñ}b²ïT·-¸k¤èÔg‹AúÃ76Œ­Çp§Þ¨ÿŒÞl<Œ¦7y>G–QØ…Æ£Ö&sÞK4ßD‘9Çâs¡uˆÿmùU&©‚t,Á—¥‰„b½±ªÆ\ÙHH%2ÓJƹÍ=O°î—áö¹¹2›~ ÎßíÌHß,+'Ï‘¦ÅT^ Ð΄lÒ~_EÞìá)•¬w¦Ð»2;òç1̪,G͉Ò#ý¹ºjfšÓº*9áµpm‡êÈ}ÎÓwtS(`‚žZ¶Õò¼_r²¨ª}døm fÔW’ e=]¬¸À½iÓ€x˜êÕûxžÍkúåýN’îær3àéUd:~£ü ÙE £UôýPí÷÷@d(Æ,ÝÕa _’¶›&Æ(x¼¹(;YK¢Œm ¤gÓÁýl‘â[z*Vi\£ l†È%{#¥w¶%Œ‚•W^#ÃÓ„ŠãsõµÈ¾P7Õ¢Ó>§Š§õ#¾EÜ9i1W´i´Þ¥ljÃæ–’mؘu‘Ö¶^méàôsMæÛrªy‰Öå¬lƲ0¡ á¬:&~–« s£'âæAeþ‚êž²-ÓÌÆdèÖ²ó©µâ ƒv5ß9ŸKæ»P¶k´Å'N.¦À»tìWÛWBÌEß-=Ј|»‡c‡–¾b}¶+~õwè7@ÿ{´åÜ>rÔ¹Ööf%6>õˆYgv¼=³¬~˜‘'„¹ Vº67xVT~'/ck«Q Í/ÕuÙA¬øÜÑ:ûR'0çÂý©×ç Î"ÓþC=¡ðJþݸÚ-žV÷8¡ƒþ¢Ð‰’7¢ªØ©;RLà÷¢‘Z‹ÏÈÞÞJÆuÙœ68ù±}\ý­ÃǼöˆ¶{úZÛx þÆà^•qåç%Š„ã]в :̈wÔ¨ô›WšÌM6ËhðÀxë¸æ7ª+ãk¤ [þÎz.=¦¯:>*å/}Ú76clË›š$†Û¯þiEÍ0¶k ± Ü)mÝ“Ä';©Ûp4OïugE…bœg¥W1û[«fZºtñèhm¸d}-#¤¼®ÇÉ•¿Þ¾ÜÂvB~+~íÓŇÇä-lä:ÂØ˜¤زëû0A_暈Ìoå4ýšåUN”½ÅbGõÁt%qpß;I2×7v ‚ãñ¦]«æÏ¿é92®U(~D€ýáù¼±éŽ0ü!¡7£ÒÝOK£x»À‚^¨Èa,ü8“e®à&M£[xp0©Ãtž~Õ¬oãhDÀ’ŒÄÒ› …OÁ¸~%§@²|D‘ð¨€où¥(AÛŒ¥¢¥­ C~(·Óêí^'OŽ=÷—¦® Ùú½7ýYE„Íæ’™‹OO?·¢q #rþÂÏ­±A[]P‡ªÝ¦;?J˸¦Iq¥ Ô'¶æŸ, {´X³VäïJ½g)ùîrÕä:¦’uê h¯Vwž^Ä7Éß8åp©+ö`ûr`G. f9¶Ið¼kPÜÆ“ÙOMÖú–w]¬£´Ï Xò¬w ¯2Ωìfvƒ^=$M†Ú:ô%›á¨LļKO†ðàx,ˆQê&:.`€ºÙ§ŠÊ™€õ#ªÞƒ½ŠEzd’f9ÁK09UDJ?ú»ûùF‡º¹‚áàzÖµŸ?ªLIF/u†ó&êà}âS;¢é^S@M~ä‹§©I¢ eÚl²¡˜Úˆ”pöžþÑDë‚ç"Ä€Ò}ri&­„~à“”nª*À¯ó8G|°cf @tï:Úolÿª¸uƒ¯ ø†ï0w:\E-ó;áâ×÷OAçw-©)$æ"ÏFßñ²œ ?—áI¹8Ö%-«f?Ž)¦[ž5å@MÛáÐ1CÐLæë‚8û EÝÍ\J†Ô*,/y™?ɺdñŸ%–‘²›µ’“½+…ô4c§äï'u—¹Š¾åwXK9·!Næøçsf°xv^¹£ê¹£¯öÍÓ xu="T6j`?ƒØh¡9#ÍŸ“ZNFçm÷:²@c=\7—sí$4[BK•×K£òi~ ™mÎzã„5có® º´Š¿m€uùf®Âùüqµ‡™²ßþÉ0FHÙ@ ƒøW‚nõ–SĺUÜNÙîøè ðÐz·åö¾ã¬ kËRPd_¥­Ù«LhO}Î3” "Î,ªQTÒ’J#»ó-G1ÕØY}¾æ>»5ZŠòì²øÜÏy..ÇñÜ+}{ØŸ„ÄSÝ|ñ;¢)¿RJéîl~Hðߊ8w8âKØ V˹BÛFIܵ<\åÑÙ]M=톮 -w’¹ŒO¸öW»ªþÖ:GÓ±Iô!ÒvkÖ%[d{fÙÔ¦1à#VyYtãìk"aZ³¥ï<ê„k¶žµ¦:q ‚eÕä,ê¨ý¨4œx9 ŸaâˆÓýLîÖõùzÍqqp“y(ÀB¹+T½.º> ¡…qõ\VŸ£ýè­8‹¡î9 ª¢³¥Æ<d ]å“0Ð\ü«OåHØôì#(ùÚÅÃî»S˜Ša;Ô™DfrÂážûñ­´N>2d뜟Mz¹?5ƒ››š1I÷U锂ƒ«½©ÆüÓCèBb‚²×žp½˜Î'Ó‡”¯ º*Õ]),ò"ô«B›'œ1’¤àX¼þðY7ã[¾zªê¬¡´ :%yÝ-t#ä¾ËpÙl Ú ËÇLÄcÃÑd§¤§¥^g¢ì)ˆÐQ¬‹=ì8æ$°3´DÁ[5—Ô×9¬ûñËYÊ'‹$±]h.äº,3mÙ¡o´¾6IÞL½»ùž[ ;j{o˜jdž;3Ý!ÈtÅoòwãÓ×ÌøŸhÚ°“\­ ™ü“ç#9E®cìËlÏ넾Eù8¿sÑ­…üq…y”®n&NrÕúBø¡ððŠI¤½“˜Ál’EfNf¬§PF×l&È}¬×"Úwðòñ˜{Äý,]ÈnWvGµ‘›ÌÜ0>¥ñëqˆŸD¸aŠ·y¦9éç}¯Ö&—Ê:`ٱ%dž¬úƯ‰dY?5Ë¥@¢+ëUÂ4¾Å}ªH\ñ„¦OTJT)sk×– ‡É™ŸŠ mÆZùÉÏ‚†b•¿ˆ|®z9ر0SùVJJVÙ›ÿþP>x„ý±tÖˆ7`‘äÛ™¡:þ;>âfá£Q8¾õ/™Ë®‰ ¯Z³"ú_áÒ:¬ÇiÆø[8™•&¼¥bì@Ô,Ð/ŠüWë2’³Æ'çucñ]Ä™Ê&g³Ì·NÅ–ÍC"P ´\\õ(€kúºEã(3Å!S)Ö‘“HWʰz3Ô!5•±’ÅJ|_‹¾ ý_1&DÕw&Æ_Ñ;ÏÙQЃêOË^½ÓV­õÏiNp‘öºÞ‚©IÅÅÀûpÈäã]½¹]ë{É×O—±žrRH¤AdÓ›™dv6Ë ‚ZßV‘.2p%a´æ'ýðÊ®p¸¸.=9̦5M"ì)üY¬<ûa"¤lïÆhíy?݆cóβFÚݾ˜¥–ÎC’®ƒífg9¯¤Ë=Ô&’œè3([¡¡ÂŽeÃåŸu=SÚÁLuj·|Fæ_:4/z‡+ðtö¹\ëcXFc…ðû“»&StKgt¨^øý5xèý¨eìlQÈ{ÛSо(;³—)%S®·_ ´ŽOšƒEíŒwD(HXÞ( Ò¹}±ûkKýÇúl”×¹*[ ºe¡‚=~ˆ%sì4#cõí âÍXé2\:ùÞ`ëé'‡ù±ðg›æàù)"ú§Ó”JÉÎÖ«ì(µók|ãºØ*?W-¹$ mgnþDRÍ—µà­!QÅó‘ [Ьv"È^5ÂúÒŽëÕƒ¥Fœ\&±¢À]ÝŠŒòÓljM;o¿.*ÏèÊÄYYž¤¤»mÕIð9|#+»lvOûû,Œ[8ºV¡M‚×?ÇóEd¯Ü ýã¶#Ošx†Gœ+`¤uÇ]§q©WZš·Ôl쯧ôu¾gAUúéC¹ìc5ê'œå^Ù_ÀBÊåJ ÛÕÚDކ~,“™Y#·ÉØ»¶qdì#NzšªºCXAˆÊmj÷´×—2ãUjaŒ‹6Écãçñô‘®Öaˆ“oí‚:¸œÅ| zdO±LÇ‚L˜¤vÜYÚç+Ÿ#6ßX­Oÿ„ÛeÜo± ¿ùÆWŒ"Wqyx¤MõžŸ {ÅÓ¹ÁGù]>ÿ¹&ê9“‚ ŒÀRùøQytÀOû@É/€¶6XºîI 4pîrŒ‹ W”" #%¹ü`ù‘ŸT Y‘¢{ôù]^}æ k2³# ¸Xñ—<ªûå9Í^{e„¶©óx2¾è„q †Wü]gÈÒjY­ *g)‹±öHpãë2^ñÊÇe³/ýƼ•S}FÁG¹Qiÿºç4SÉz\ÛÉÏ7{B1ÃÌViPS@iÁûQL0z¡wµ‹†ÊmN†µSÞ÷L#YOmøHkSf}S'C—È£mºŸëÞªD°lĵU_;ì#·Öˆ°¸œ#ÚËJ·Åá!Qß N.‡Æþ°ašlN[,?œº©î¹Í.°d"ÍQ]Ï·xøJàJl݃K;.èÙ1uÛqRIJpz=‰mJÜÜ|.Õé"°!#(‰rQÖ~ƒ&†° ½æ, ÊnDýG;RÚõw~œ|ÎGqƲuÛ„(•æ‡âˆQÿÙ£¤s)´×ßkü‚§=ÅKÐÛ}‚¾Aú`¿ÿô4YŸÜ¾ƒfvfSß ™š/›Â^bE-•hƒhÏ@ã# "…‰ÝPçß £æiüÔ·1_Ø ~[ž×fj6 ÉX•YTh3XÂ)ïÀº»g’x‹h”àCáôœwÉmtªæÊ·ìÖ*÷ð5Bé*œŽÅn&±7Ý×g¹Sz‹E"†EZ¦ õ1;X.é–ϘmìUb~¬îê6¯ÔÉÊãIE'b”ÛÖò¯TæJ…ÎJ˜ ;+åÖÃD®ížÒãÃèâÝœN7SJYnj)=m"‘ÄH’ô]’™6¬4¡Äûüi7pÂ:Y>‚‘àÖœ TÁï%VÅ–f³ÐŒ5W¬éÉ™à?Uº‚lÖ1<¥¥ê*:uúh&–8}ùègº²Ü5Üñ<Ž„ç{éðý‰GL j¸™–.­õ#N>|)°Š—H†mT!Ü –è*œ„ˆGàŽ5·g_¥épnjî´b“hgmdŸµ@ã!i·ì¿Œtl"˜Ò'%>{ì¥|¨õ1}Üÿi¿S[Úš’ ¢šÜæÏ3¨›I6ù®LÖ’RWå"Å.qÆs$#ÆÿÚZ$È8D8wœD”Ï#³7Œ0úœ‡å‰Çkùíyº†U-|Y Æ_–Bìs ^ºh{hz¢gÀ„¸(” ¬níéÄÅ^¢ä§›± ]³0pãùᨿ:|0™k{}H0Qô”¡\ó&^ÝÖ!Š`Û4pCÍg0"“cl7V*“²ÇMÍBr[v‚ uì<#“®ô31x'‰ûÐÈ2î9õë›6Ÿß0o'~ ­Þêj’Ùs9³¥SK®õÐòpaÒ“üA*avæ³dÛ`ärLÌìNi';}ô´ä·œ—Œæè«0£Ü[ûϧý*ö1tãdn.(à¤=öŸIðäånBõXƒb#2˜rÈBÐ̾Eh¬ÊYEõGSÚv²k üì/áïÂÚЛºñ”w•I¤tñ¿:ÜòtKÉyè¡ÿ1–á@Æ‘ÏE2ðòm~lÇ·ùá ƒ¢8ü6ßþ~¾•þÏêß®.•'ÎïHu ¾‚ÉéßÌ8Ø?M;Ð.aâZï,BIìüù+Ý0g6×Yƒ-|Ä0H³ù—“ã7_Ã;ßíœH¿íÂÁ+ 5y´vØ•]g˜ò&Nwš@F<)èï~VûSv¬ò·rÏYx.FBë( û’â\ÇV’F§KbOXæŸÙp¹¹‘R²çŠÚé¹Ná.ºM¨Mœ°v ˆM#Fì(º—„H9Ei:ã ¨î0Έ#œ ™ŸQÅ8Û§¥Ï«œTMð ÀɉI!®ƒé¦wîC|7# ƒ,á¤38оñ´.sßùMÚ ð÷œÒÓ8Ñ?úDÕ$‡È³+ê%M»H(ˆB(Šüö §Ö¯Ê)Çd‡…Cž;yêÙD>‰¥êÞR8ööElºœ•Ëü,¤†G­¡í¤’²w6k©™ê÷†Üeµa$íÍé!iE²¹´ ÍÓþdç­`WÓgÌ‘G¯jMnóh*µŠÛ ɧ’ƒ!Gñ6ˆ#p Ÿ£uóUTËk~£é¾*-Yx 6©m€ ºáP¤Î§]ñ#2 ‚±G±p*PÍæIrkh+kVË@>ÚjÞ$Êt?~n 9U:AŒ“0% $Àr“ÀÎ]Ðcé™¶û3Ìî¶)Úro$YÕu:‚Ò«S m «žŸiþCl»wi̪6±îÇlUúÅÄ!ýàí}©5ƒr% Ç‘ä<%RÆîê¹ k·  EX˜Ë#“°5SH…o¡{|özzpoºÎ%å Á*ûB}lÀáíKÊCQuÜF²r¾’‰(‚oHÚÉ\ḷìñ«vE–¾ª—ÒgmiX‚(µ±0æô>«¯-ç(°œéßH‘ì†VmÂôÞ`¾–¤ý>BÈ~ÿK[5¶QÛ‘r´—q›9Ð÷#×EˆµÀWQA!j8ê‚ä®ß§J콤Â'JóÈ]þts‘qSœdx†ºmN†þ'æÏ7eœíèÛ&x*:œ %1¢f„'‚íÂf”y\QÊ9ˆžBf¶£ò MOíNâ \]ܘ>LÏÐ:sl…ŒøÂŒCyhs1ø^ÛúÏnµ)jþ!pqò!ÎV°¢¯Ì€­Dr–©Ê‡ ,ŽÌU1 Ô–põ©ˆ|‡†VZ¯£Õ‹öu;¤PÙý$.¨¦/ü”±‘gÐ×\ÏžYmXý†Ÿã °µ>©Á`F³¡TdÒÉw潚üZž¢ýÝpX ¢spàãyåæŒÍ÷~±†õkdÜÄsÞSÌô6—æ"öV3CZ€Î þìý]ìX'EBàø /Õ~>Ïgq"óÕ§t~U̶½5¢IáwSõDÕ£õaÐ8’#Øwyúªýˆê@†ÛylF·—»|U1_¢ÄÓAÌVo{ÕÂÞ“ ½­¡{Þˆ±í•jGûž›cû!:‚6ëÉ'$`1oµ.–#ƒZô´5¾#èûtXme?l³y3?ZD$· ÁÓS»Á¡lÌO·Žf]Vç§DÇÉS“²9ÿ,^­Z&Cß ¢Ÿv=È\_ôˆÌ ;,…øOåö?‘†])ŠƒøÆâZ%“×H%÷«òWjOüìdÈcäyžAÐì9c€™!áàU3ÆkoMùwǩÅc~5*xþöw;Ê(ÏÁ½&eKuïc﬎Pvv”¢µ¢[ŸVßO?U&ÇÆ2ÇÇ[}u@—)©ûñ•‚N ™–D¾£DÐ#fjæK÷+a§µHCò; oœ^Œ»SMËYp˜0·Ccÿ~þ?Áÿæö–¦`Wƒ)ØéÿJ¦ ýendstream endobj 1433 0 obj << /Type /Font /Subtype /Type1 /Encoding 3111 0 R /FirstChar 34 /LastChar 122 /Widths 3120 0 R /BaseFont /RWWZEO+NimbusMonL-ReguObli /FontDescriptor 1431 0 R >> endobj 1431 0 obj << /Ascent 625 /CapHeight 557 /Descent -147 /FontName /RWWZEO+NimbusMonL-ReguObli /ItalicAngle -12 /StemV 43 /XHeight 426 /FontBBox [-61 -237 774 811] /Flags 4 /CharSet (/quotedbl/numbersign/parenleft/parenright/plus/hyphen/period/slash/zero/four/six/colon/equal/B/C/D/E/F/I/K/L/N/O/R/S/T/W/Y/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z) /FontFile 1432 0 R >> endobj 3120 0 obj [600 600 0 0 0 0 600 600 0 600 0 600 600 600 600 0 0 0 600 0 600 0 0 0 600 0 0 600 0 0 0 0 600 600 600 600 600 0 0 600 0 600 600 0 600 600 0 0 600 600 600 0 0 600 0 600 0 600 0 600 0 0 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ] endobj 1357 0 obj << /Length1 1606 /Length2 18012 /Length3 532 /Length 18926 /Filter /FlateDecode >> stream xÚ¬·stf_Ó&ÛîðŽmÛ¶íÜqrǶmÛÝŽÕ1:¶íŽÓ±¯Ï33ï¬ç›¿fÞ?ÎZgWվꪺjïu%©Š:£¨È (rtcdebá(Ù8˜¹»*‚Å@ö€¿FNJJq ©› ÈQÂÔ ÈÐZ$€æ66+///%@ääíbceí ÑTÓ¦¥§gø/Ë?!3ïÿéù»ÓÕÆÊ@õ÷Åhrr:ºý…ø¿Þ¨ܬK{ @\YEWVI@#­¤ :]Lí*îfö6æs £+` rØÿ{09ZØüSš+Ó_,QW€)ÀÕ hnówÐËèô‹àtq°quýû°qX¹˜:ºýí`ãhnïnñ¿vKп9¹€þF8üõýS¹º¹š»Ø8¹þfU‘ú7O7kS·r»Úüu@–#-@æîÿ”ô/ß_˜¿^7SGW€ÐËíŸ\f@€…«“½©÷ßÜÁœ\lþEÃÝÕÆÑê¿0\€V¦.ö@W׿0±ÿéÎÕ øßª7ur²÷þ×nп¢þ7W ½%+Ûßœæns[Ù8"0ÿ3(²Ž– +Ë¿íîNÿÓçtùWƒhþ™Ú¿$L-@ŽöÞ  %³ÈíoJÍÿÊLÿ}"ÿ7Hüß"ð‹¼ÿoâþ§FÿÛ!þ=Ïÿ -åno¯dêðwþ}ÁþÞ0 €àŸ;æÿkê`cïýˆþÏ@mà¿þŸ@dÝLÿ¶AÔÑê¯,L,ÿ6Ú¸JÙx-TlÜÌ­–¦ö{ô/»¦£ÐÅÞÆøW˵ÀÈÊÂò> ks;ÇšÎùoÐÑâ?™ÿ•ç_¼™u¤t´¤èÿó6ýW”Ê_ÕÝ4¼þûu(‚,þ×â 11À—‘ƒÀÈÆÍàâaðp³úÿ²ý †õ¿ÖЦn.6^ý¿%³°þ«ðÿñü×Êð?`$ÍAÿL‰º›©£ÅßÁú_†Üæî..õü×Yÿ[ðÿ\ÿkÄ@/ 9ÂêÈœ?Ì6+7Û­·phBBÿW/+äP¸Ó×F²’ PO`VÔï“·Úp¦¦)¾6ïÅS§÷}9ºƒ‘^{êž àE1¡?9m_ ú&U7ýA³ÑWäì?Úq¾— ÛPz\,Z»ªjFo0DSì.p—´Aä%AXN(æ™ ‰ØhM`u¥§¨R¨F‡‡{®¡ûö è á)ù= ©bƒœ „õ4øFÓ-æŒMØãˆüa±ê’å¹ÃáZbâßü1äé{s¬L¤Ž8 R"u?³sñ éKí ÂHéøÜdIÕEzSÝñŽ%zé.wjL¸ÆŽv,èU”…ƒd¹T7/ëŸßWî†Ðô/°óuMLf<‚5 ¬+ä2Zé=/MëÄI“ÆKQèmÎLíºÆƒÍ»»/›·*ƒ ñ&gvŸÛâID©Õ)zöá·¿ÍëîPm*‚y&ïŠNiMÏÁ‡°PÉ΃ø{qµ`mºÃF~u“€îÃ'³…aµš}°Éž9a}LCSऒö–÷ÕÀW€‰omT&ÚwH'ÊòoiaLÎ9~Ç‚PÍZ.+õCê…«Ýеz0Öú ö6m>¦/¦?‡ÚËHü„Ž`?"`‰·´µŠ}ù¯JüîÐR'-Ï&&ÈîÔe1Æ“áÓÝê)Ì¡7:É#ƒ¨cþÄh ÂÛ¦) WÚrÊso'}×øè_´ÏÎö¾¯ªý¦´vm1ë¥AxgŽì…÷Γ!¦=]?²ƒ(l{åÍ™Y­)pa0±8p•W×t’uxd&þÿñ„‡}Æ*TEÝ 9 ÛqÉïÃ2»b/X—­ššî.$i'òÛøåÑ=âLß{ÖyÙkMd«A`V¢âòØ1«jv‰bSêZ/„XZCŒžíí´ôØzÆ &™·øâv¼wÝ!îÎHµ¦8=T¼HD ‰ÕìªÕ‘^B çœþ?P߆0CÍ0yž1—S F²~<5ˆ LÛ#9i˜ß”í¼g˜–¬Æo{†Ö,À[úMIãþ„EäÃê@Ñ Q2Ù3äS71{‚“éªÚæ_­Ååý}…/bk¾_£9œµC½¼)4¾a,€v9R>cÜ|G’?ßN‰ +â2³¤ð\ÂpBŒ½¢áQ¦*GѪŒ!bj}GàÈì›z˜û(ØŸ >K·7ú%'Ú õ-‘  á#ã7´ƒê“YÛÙ´“öà§g¯Ï ùÜS›.ùÁ D×~žSµmðÜHºGHû6<î}×:`ƒvµÁÊud¯??]Ô}šçòçåk{4ÏÕW;p¢ÂMË_ ê²x›pžÖgßR¿^Œ;¤÷ë·ú—´õ¬Öf:IøÛçjôh¾~ôfZÌaçÑÂÊ[ƒ'sÌåèv(5ˆñ»v<úEc$•X°À?þÂG0¢Ÿï/<ÒÜã~Õ½ŒnP ÁNqªTHC5ÎT2®Å¬r1Ü•Ô 2Lÿ„žFò“ÛüT\B•ÃÈ´v¹Ï5ï)“$†0ù¸êvà:=V€ò77%CCnjš­L”ã±8®BåU8j V .ø¹¾¤]ˆO-ÿzëƵ7{D˜ŠN¢N€œ€c0)µ&aa “­Ó‚Ir73å ¦EEÆ ¸¬_7{ÿw¸LHY$½rª“52´Q(&ó ßF6Wãb>] ©ÊøG›…¾J[&½RžÁvWú=3¯Þà‚Ͼ2óp`Á±5y/ V@Bã¶D…>*l~f°Èí­Œ8ÝY„Rô&8›LíkCÔ¶+%dß."˜Æ–Õcîäà8m^§_p‹-^Šè9néß{žëûUÑÊ鮨A“ïB ¡ßåOpÝÞ»Hêe¯%!ƒSõC0n®ib~JàÛ‘$Â2è­å©ØIQ- ‹û[ßÌ)ñUØ;@*úÑ|S|»Lþ1‹¸Ï= ­Œ‹©}WZÛŠŽ•ïÜ(¯ZÙ%𻑃Êq'çš3ÖŸVÕ¡®!ØÿˆÁ|ásÒéLoòr‰hõµÕ©¡‹?P/#¦×nJìtn„7íW^È)?wv‹ä“ž#BÏ1r,8Ë ,9âIŒ]Ùé׈ñK2: ÉþÚâÁoÏ$‹¼ý†"fQbL]ÝÀ es¿†/ÞD“" 5:ëwRùe)‡^S&jáIúƱð&ŽÿâíI8SFùj·ä‹UÂK’}ì×݃!4q¤,ô½ÜûŠkæWéO©·ãSSÞ²‡$H±_gˆ×CüZ¸[‘·W7 utzþ«ÕP?l ðzL&°ûég°†}úйåŒ!–ÂŽÎok?~~:Ÿè"ï űÀ-ü˜~âá¼Vb_{•æOÄÓªÁ9¼r˯\ûm„—¹ÈÖ‡A‹îY2» ¹}Œ3)Æp£`uÑ{±¢‚œ?÷Z'–±n‰öFìÇ|/üÅN|»‰ D¶”ÏF®Q!2;»Nþqúׇ0®í^È(D-~ÄÐÉ~Žû\“Kå+¸€Ü8®z^­CAP‹¨°a#^²MÝ:q‰×!葲%Y‰AUgw ý¿òcD†¼¿±½¡ù§t¤†`cüeݨý$ 8IÐL¤ÑÁg³g𯲳ÇúÀvwXŒõ5D¬ÀÄsôŒ«òu½uá”AÀèú~¯ÖÑó É½Ç†ƒ·qç]6zW9xîµmƒO'=²8ª¢“<7‘ßG´çü²!äqò$þ_êwr› íxå× ½E—b¨å¬ßHÉOÙÕØ…zò[G"¤NDXûkÞ±šÞá¸pŠ™ñºÚ‹Bµš.ýÙh¸õ x g±åø HÂ’|ÓKÞfYòÝç®,eÄbíN‡©ûóÑt¿Ô ^Ç·Húc<¹°Ñ?%rw3¼{$nä|M)]ØEf'©7M€PÏÐ*êˆHûdÙù…?ý̸iF­Š1¾<Ó.«JÆ3œ%b(ÀYßKM)›íô»pYPQ‡ËyshÝñ ö$tçáÃ$¤'ÉoÔ,_#µÁ·Ó!½†Á  w/Ë‚5åºöX¸Ì[CêP3‰0 B¨ÂÖqKøkPQ„t$•­±VÏ@Â~z÷N‡OÄrÆ]‡¦ÑñüÄ@I*1ØUµ3¼ÿSC­çñ£!Q¸¯Fá…ÉÏÙœU0’Äô¥Ãýâ³OÑ.eÀ–¼ßÁƒ¤ˆ¾D=Ó ÉA|¾Ð°Õù@¬7Û¡¡?ׂ1&Z©×«Ã%©iàÊÄ•íxÏfòÁߪ$‚U怩F>cZÿ%Âo1íÇW˰úù$¢ g~-Ä6Ý(æ/šb’¨Êià]¾4Í!kçg‘R×ÇÐ ›RÜèü9,ù›“XÒƒÙåÔQT^fúb!µ”Zð‘©ð0JÏzD†Žjð|"}H韟 M5…h‹)Âo%°\¡½@Dc‹ßCÄ]ýÇàXÆ>’—‘|³H1½ ¡ñ÷ï.øµûAzû†&ÔåFbüämEù|M?`±Tó©øsÌÍ/1E@v#'w¯ßËDç ¾„ºœ”JVŸÀl$spöCMæÌ°e²4 ñ¢9ä`ÇÆÌö|H—þÌ©£n‘óTÊ'RCè-ÿH=t}|¥1ìòeO+ØT¸æ<šh™ÔÅ4NVe½NKÀ•szæ#å"¼³èÑãñ@ÒÑOfMa’±¥·›€µuB(¨¤§4\; 0~1¡/‰š­­Î%mýªå_Œ·®dl1ïÀpŒšíÕœ4^j2p:zû ½Õlk°QÞ¹›  +eÌ“VH„ûìVÝu“8j¼öÓ5]|Ò²YS}~züf"nùô'M¼j ºXažï1óÉå—á/ÿiymêT¹ÔÚÀk7btŠ1Zê•åê€ýb`4ЏúÚPe:MØ5?5˦‚øÒ {”AnN Ù;tžŒÎ³Ÿ÷LXJÕ^¥@ÁÍYh%ÔzUnsöw#BÿJɽ7=@ï’Ù‰»X5L—ßâ%ón…³XªÛ$ꕌ*ø¾ é3½õ9¿Öœ/=8îÓ%Ìø­©zM‰†˜`1„ÜsV(옮ILW“ÂrßHFÈy„gø;L)‹?MÒ|û»0Š˜öQŸ±bçÕêºPçÐE¦ì¸¯ƒtôÅGÎLU¶!Í5ql_üZö~’ 1PÔè{rå1F'È4¶´¿ÝÀô¤i+­Ûx@"pQ‰F<ù¢z”þÙtr!¯ÞD]ø r~8ÜNþŽÝ\(8Uï«qe¦Nk|ƒ‹ þzµk@õÊ\¼^þúõ.ÄÅ>ho¸ÐÛêœie»*Ö㺨°ª7° –4”ðæiwç’£`%Øxò@4®µªÅ¥®VCÆÿø¬÷cæ±"½0Ð0æXÿÊ_ËØ-l¦‹‚Ûò²Ø9Šb´cÁ!Ña‹%_­þÌ{‰•#-D› ÷ùuËÙ}½£ÌgHa[ìí¡“ Ñìá:Ϊ<%󌩷-P)µÐr. ÁÄîW÷—QžÙÚÙŽÌ6®[üoÎêå·áuï«…pÃ:iö?µCo¢³žQ,Ý®´il¡¼ÅçOκ'`O4Ü”*&®†nlgFõ6—\°’näæìŸYú—Ojä8¿[ÔÍÌŒaB>%T@rdÉ »Ã¸{Ùf·ææ¥¸w_t[lär`1hý<Ù$Šà+ƒŸéWúù|I,—d*Ð1ÇØ?DBð‹ïp,oðNω2ÔYV!ýµó„õÏSP™B³ÈŸc($>çÍw‚³ÛŒ?Ãåvk^Õ±ø¿„½=ëWœ>af¤¢*Ø5Ð(%ïú]ûN¹Í¢ÁoWxm–ò?_ƒDÙº¼sŠÃT?Ö:wÎ%ŽˆØÉÁÚ¤¥L¿ŒZtâbQú°j½{Y)Åx”5DëñÜ-ܦʴ9ê½ Åi¤È™q‰ãÚÕþÜFÀvV}432§ud3b`+€Ç­¾B¸…«6Ä5“´àt½§Ú¨îãúHâ8p…”õ梒«_V÷ +7²øÉ™¹5Égzç7 ý<¸PÇîÇá3Êþ€^Š€ú±hnd±ñó,f¤x-2þ~¾¿Ø‰µ$áyÁ^Ê).]!k]Î1*-kRÞ<Î ËÓ±f¹ç3ô÷$v׋­(¬Ý몗\õ  ÛÝÛ¶ä=ï„ý34Œ¼ß·&ÍÝÖlÛ…Îi.žp?Êa~¯û~ã«Müsø/¿®TÚ]gHû J@V~™4x=qAÃFXma_ãfû—.¥ ‚Yî*ë°¥hÅ ìb~ª½ÞWC;Þ|¯²;½cU%÷SûÙ²à$Ö`gàë±eN²oÊ‚ÓX?‰ÁÚG‡scš¢Íéwü’äýRú› Aè ­KöLÆ[J˜óÈ.Á=tdÇUƒ«æX· ~¤ˆÁâFÕå#~ˆÓ"R+ÿÕ1>$g¨ØÏa·Y$!ß é¾6>ìEŸG•Xýùa!î½P§—£¢jé”l²a u)¿ÁÐmÌ98ùRdö´Örb~¯ «*½$ËÉ E* “ :‹l ÁÊ pêüHåhîI›õû¹ذʔn<,„ÕÝ»Ê 9Ï:ÒüÛçÑÁ¶8_¢Îm㑪¦ýRo’ Ù˜À¦hüQ0˜¨÷Ù‰Ö7«§c‹pÀ†…¿XNUë.s¦¦†ÁUâ7õœ(]E)Ó‚˜Ð[QÀ5ïWZ«Tž,FÆc–vÊ—¨HChüñ-ÙŒÙ0ó÷©¤ßSˆ9gÄÈWι†AÞÔ¬µ]_À}ÜU¤á>ߺÂÆCË"æçÞb¯ÆnìU}NŒ9çH¤³3Ö¨]šFÐ%.B³Ó ±m/Æ „x’ÐW´V(ט|ø]ZGÓ—¨ïøE¢œ´W…´]Gúªîš[~ƒWøvW#Í.d“ºX +Wç°Bl‚ÔtP80tnuNŠr“Æ‘‘ad¡ç¦V÷˜÷ÑÉY “»vsýH6f¼¤kÈ)¿W»,Ìã.%«ÎÆ¡I?dßw#uHåæïõ°µ”¡~ù@¹ø&‘ 8$€ýôNü!×9Ax…:dšqd⛋ÅS Ëê¡ ¨¢âô}`+k6ÑîÒ<Û’Ã÷o©pYÔËuéZ*nuô‚Hv¹B¾ÁIV܆dØ*gæfÅ{ Ó6ulW*J¥º;NEMòŒîë—b?}Þ»Á³/8‚~nq"T_Öþ#4QX°³UðôºyŠ$x2jw,úŽá¸B ¾w,ÓÑcçØäüHvú¾Q<Œ¡# ¬îS¤áÞðêþýžÕó}& ¯ÖÁŽ—Ç…û-=6ŸMÒNïPÆúÍöbµ6ý,‘îâC.Oñ+ZÍ…’m1Íð,/WfÌÁ!Okž½€ÆŒ²ÌLÃrßá>í`65Z{eöðÊãTôA’´tMgÂW²ÄFýžœë~ŽÒ1Q'îMíeâí—Ýñn¢Ýó©qôx·ÏRõ[Ï(;+rݹBln€ ToÑlŸˆ¹°{¹bû5¢Z)q¢8 ô PÌ{C»Sx'[;êV«®‘ñG¤úv³{©Øö´¨x[ò­Æ4ÈbÿAx‡‰óŠ”\ŠŽ ó6wo•?Uq‚ØíX±TW.¶F›ÊõÂïs=ª,ÕÉÒþDõÞʆü¥èïô{½%g‘˜¿b¿M-‡äo;zy´7R.³Ïf.&.f¬ß¤:ÂðE,4ˆc‚®é=¾#ÏTŠÛã…ªXµÞd!ÿ—‹m›¢ûº(»¬¨‚ÌÖÕ“¥OoỠʆÒU‡³e||èR±—=ÅucS!Óq9­ŸŽÉ7:F2L{Çt<ÐW©E6_ìjâêú9 )|æÛ”H¦=7†^|}„âœ4¼E˜ÂdkqbÆ: «ñŸÉ‡‡’M~0®2g§ÂËÃ6;F&G[†È6Гbë_/²=ÛoíݪðRgËØsñ^_¡‹z(Ÿû¦ÿ÷jÌ:&Șü‹y´fÌß:bkä½|aov%{ŸN\B¡çUw© ·…wùpRôHñ°…<Y—óMå’*£{䂪]¤ò¸‘:ÅÕ.œáPñ`v˼u{x¼ŒOÈn[9¸¥Ø\¸W~U'´ž-‰ÍѲ Ò<òN¸ -Äq¡¥©GvÉvWÏÅR®mJ}‹†¨<¯øAЍñÝICm*ŠÃQIÙÈÕoŸ; ¼ks-s’?úçU3oü§‘Þj¨ š SÞƒVMz¢¶CÊDÛOÉOmè¦6£JsĹ´¦éX'rsÊ®*è*ø—Î1ú‹ _ô–cÔ²ñ7§ctÌ+u)ÌvzwÐà„“Èž=N QŽg°7M…Âí3Ð;°çÍAmóÍš±_h.¿¨gan[ƒ4BÖ € ‡çæïÎ<˜Oν.†¼(ÊÓ®é"½OYF¾ ¿ÿÒ}”Ú]/å¨Îœˆ7 4&ÕiÜ*ÀýM¡ÓÄùËz¨0_µCLŸìªé;S¸Ð"óØJ [ ËFB“úHÒŸ¨Ãk2*t'‘çHEÛM\?'™-5@F¨G¦´8~Š”%®\ÃËCË~©—¥¹Ç/½tÐBMˆö8Ò{†%Va®ÆFX &äôÂÓû3þÃO_×4 ?ç.V|©‘ ÖÇ£šrýˆÑ¤,åÌ`^5„òyÊê86GÍÿ ¨NÛ:›wˆg®%:Ϊ‹Ð³Îo}ÒqQ½\šAÿ¶0sùcN3/×ÕëWÃ+„ăºœR¨NO­ƒ˜ñÜæ' €Ë+¬0`hGSrQ.­´ªæk¸ß)ÝÒa6»Gp½o¢¡œŒÖ¸h¡àž‰«6îétƒKíBÕ·Ãækœ±ð©LÕ¤ÎJKZVp4SÍПDGëR0ò1dZ¨"PNª(bûS+~Í'îÇÙÑ‚•ÊViïyöVÿ³;9ݪEͲøV<™ ôêÜS±úÿÅT5J=íVC¦é¡Y‚¢*> æ "­B*ç€AýŒ»õRêq4 §’´Ü Ì?XößÂ}Ð1ì¾–|d~uEu.Á¤Ä§H¸ÛS¹+”å|MÚ솄D7»­™ÊªÙct\D_»gþ YŸ V{4*à3÷4÷)Oa v#<«¸I·«=­{î¶êè´ßÔÅPÕA ÿ&âgɶÈ$œx‹”€Ê”áOŽøØÀ;Ü%«†'Êø½»bû%G\hšÆfèMŸ°˜“ãøS+´f£óÀ‘Ëx¡\ ‘˜¾…©–¿=Z2œ¸µÄC¿"» VæÔ§ÀzeÞá_1¾Î¦tN9álQwJð*a#΋~ÞvQÇK¿»ÿVuwŽ3UOãç1T|!ÓaeL"– ¬§ÄßK@1’(éਢò2uù~?Êu:; § æxýaˆ1+²Y2iI˜z•VÚì;Ìõ‰ žQë) H¤¤¨wð<¥¶•{€½”Lä¶»å1Œy?Åæö9cª÷ÁL‹¢pMya…ö¢ @œŠÉƺKj^'¢Æþ„C5_Œ]ùn–’La²&Ö¦½x‰¢OEAB<‚oÍ·ykå©© Ú[Úº­c¬s|ØÂ‰c Wæ’XTÝ?øD›„t³×Áþ€ ¬Å ²YÙàö(Ð-¯²»2.¼ 2ìЃõÄ%{×p+u"{™å¶)Z«fá– ¾Jf¹àª»l=uÉÌŵ—~¬RGApÞaT>;Bª{c‰šFÜçx3$1Pµßù\“X„¸ÖþX™’ *"\È ;ž£5¯Ë=İ׺¾IáûFt`IB'­X¸+Dº™<ÒK*~ç£ê $Áª "S3`éÚ¬ð÷îNB#õ/\'ûQׯeP5\g‘”·Ó‰ïÚòŽšk ZsÙGÍDùHµþE¦öÀ0uÚV ‹{‚q‹7;—ööEY2 µ_™]l©åðÔ¤N!R„{+òÈAJçR|5ÙwHIgeâs»5 JžÁ©ÂR£jŒP¸ù¦ƒ“ÉN§[$ä¬×Ç–ïYøU ¨Zq»ÙÆß«ðaj‘€QšÁó*V£KrUbNÂF;¬$‘ŸÕX†šB?G g®wø¾R3]ëy5¸’AÃ÷ôÝœÙ×ðá¥sx|—®ï¸Ñ‹+šeM@1-á¼ÈšÄj„c›ôŠÏ“ÃA™õŽV&0ßsžOÔHØÁ°>tÊÕMP¥š¾/ª‘÷âÖU¥° ˆ$pPgôdL¿§ÿe°¾mÓ9µö Iä€qæN'mÞLÙŸµzs°Ì¤Lå@©A%S ¶0nKOp¬pkH­r—ßÜG%kê¬õ9‡jÈ´¢He@œ¥~.П$"á}¦ÕV¢éUñôœ†‰Vw¨ñ 7€êØ‹´àrªdzWvë¹ç›þƒ Öîqð7ÐnŽ4» ‘/Í¥F3„ßÝìîQ{‚ÅÈÌ·ìÒqYkòž®GÉí4²ÈŒo3s²“혒wÆSR ³å>Žl=yÌ,¶ûØþû—’¡yp˯’t6ˆW‹¤©Ì2˜<$ŸŠcáùW¼ }Eã?òÈY,®ì!-:Ôb/‰¼%¨À¸6ùÌs,(¿%õ¥»wé#…ý²4bz'° ´7aù†à;îÅC4hìrë,%:?‹C0²-TìJu±wL’…Éî$«µ5¦ ‹ôðŒ‰6z¼Ç„%™}¿AUä­:&¶Îà0¼‰n§àé<Ãoðm4`6ç„ó™UxG>ÚFh¹•‘È?Vp5']Úž` ,•q~ýÜÉÊÄŒ£ö„F[5tÈntY‚¨X<$ÐG_¬··°{(6QMè)¹Ué,eBi5ÿ¥õ —(rÁ×;ú€­ ëÙ¸|ÞƒöÕ<²¥Üc¼Wä°Eáº%\í3©im3APáµÅ%-ÞþðS#7û鑎Ó,‹Êh3~º2ò yÛ.æáþÞÖä“Û0Êàþaë2O5¶˜>×,vÝëêC¾Çû4-’m¡>¨ŽÏ9œ€E´S‡„µ-»¯PÍ´³‘’È?{]`²>ëÒþ ÒZèM†$hT˜sò$Íoü{™ÇèÆ|HlLIŠ!-™^©í¼ñâ2R[|ñÆ‘}”¢?äñ܈$paó§á‹°­ü=}×E&­Ð,„Ô)ËðÈ5;+höç¾hæè½\óèæöNýyôT®S…]¹"£©$¥ã¯CÑÊ´ŽÎZhµÎÕâWùîf7ÊÀúÒK‚ÍD@IÛX‹‚}c!­˜eúЦ» `Û9‰S7uç~M6¦¢äNÈ4Eb÷IÝÊ{Ž[bÃ!+9kÎHÍŒtÿô*Ñ%ì…Äå+ã•(¬9) ¤Û޳aúCÏgÆé¬½ÍŒ„“„J] ä©K,œÞ†whAŒ™?ðƒ,I2…§kí%,»ý5ŽÐ„ê—¹(ýÏç†ü*)®mÆÚ¼>¬£\éĆêÅïöE.Ya7Ö‡/}<ót› ×<¬Ò=­ð4˜Ä£mRìèï¼<Žò„)ûUþt¬Æ{ˆK R)>êi)â2L)ñ‰ÅàÈõß~DíÈF–=ÍhÄ:äõô^Âb¤ù•UËGŸ®'¨éÞš_nÐ6p؉( _1âN¸_ì“ÕQã€$œ:Á¢XÄUyi°ê Q¾oGöx]-3ê¨'8‘êæ8œ kgû¦óœ†u\?ÔcÍ›’Lfo¯“Æ8°v›Z©dwòOÞ¥ÚÙg.ç i´½öO‘S 3ú^]°Oº“¬U»{y–Gvˆƒ¹¢Þu¶t+¿òݘ‰¨Ô÷¨û›?Ͻà&3­qÏ´)k†÷hV?­íQƒP]Óøô¯¸®<øF1L…ËâFÉ™Œ.pÀÜ'J=µöTD8§!ø4J¨Ndû)Ô:³ÖL7|:µ÷%j‡òäLBÛÂù 6@E]0‚.¾. ­.PÖoE¢bØö@AµªüüÃýB€èôqFKTm10Ï—)Î)†R òããd^¥±?ï5ðHŒÌÜÕnë¯Í3î˜S{wæT&™P2ňþÜ`æºrDqâ‚X5ŽçÆæË®2ÃöÑÆÏ…«í ÑèòûrÓl9£²¹•å˜T#+=j©¥X¯2oi7sº ¦”U0n›tŽw,´O8gñŒ=òårí_õu†.LjvpRH s› 4ެ¯˜éHFXÉò|m.zà´ºmÓL¨-["÷ác Ív¥…Âètñ5í‚.)nd‚ĉWœ&Š£F²Ž v¿¤9x£E¾«Wv£îÄÜœ‚‚ô“VëÀ¸! R‚‘(ÍH@†ø³º«àX`qPþ"º!q×,3P!aå“r"O_â“"š™Ä xÊw ¹¾Î‚g䊀ʘÐ^½“â‰. T{(,ik)cœ'x‡q`„zÆ[÷<ê}ÄeËÛ¶C|¾Ë˜ç§ŽrI‹Q¤>ÅX1‰TŽM*“Có!–ÇíÚ«ØnÓ^ ™LÌAt¼’a&M Ü”át^RÔnèŒ#÷… 3ö¶l‘ÓçºÙÛМ5¤oß9à Œç†çä•„ ú³ø Ù>•ÖüU‚ÛA7ñzO´‹… Ný2Ìsݺ¿-ÊàKWÓ{Âð”m¥[[ݶgx%8ú¤fÔ®~A’Å?c”‰òêÊÿ!£ÁßUqg®’E¦q+}ɲ€ÂŒøF/}ZxM¯Äv *dG³N_‹£œDÔ„ô}ôˆåÞÎ/“Í7ëš ,8ö„a%S:ûa¿zÌâPÓÍœ l¾½¬a=ª0§ìßp«:ˆâ!U"#Ë+ªÕ¯•ìÏàÅ`G_Ï ¶‡¹ãr ·pBœºVýã㿾tBtñš&qƒ'k= …¦Î2wEF±¾³~ý !÷½è €yTaº¢&|«‚7ý½"qpimÒ£ÇåË€Ð=í bÂ,¸Ì}Âw)oá.EÒœU1Ç/åChE0åûSKR𦔰Ŷ…Ï­_Ù«’iժмZ;ÀÂzGÙº‰€gø$²ßá@:DE§Ûù—¼@¸’ÝÍbJKg q)ÙËï¬õü»)TJá– dÃE.éâäxÌ]SÒFå…‚K·–Î4‰7ý0ª 6©eå "洧壬áÁ¤#•‰§ˆ–‹ýÑ-ðË÷`æzŒHîŸGÚÍûÔŒ&UÂÒô:v«¿zpÇÖHImÔßÉêkŸ®æ”Æâ^qN¯)¦s!ROJ‡J£9²;=¬Ç%}¹ží„‚{ŽÂ·º<ÞQXZ'úûÎNM}ÁͰ/¿D"G3!ügz¯ëO$Âe ߦÌ`†³ð.Üv?¶®¿Pê óˆ x%…up¾œŽèë ß4b8KT×@Áƒñé‡ý Pt¿”’çÏ4 6DÊâr‡LUê}—ÿQóp×±µ1RæAk?'hbûWÐßµéìPŠÜ²jŠPxF U~ÉBÆ ñ™º¦fwzmZ ³]Ô›Ù[B;^6 TÔ’5¤šh ýæ•¡¥íÏJ†ÑîOŒš¹a“4:‰Jš; '<×^pµ¾«ìx§` | o޾<`‘þ¥ÕU.[ÚHȱꉥ™À Q;‰Ôð*{Dó-¾sÙ§v›lŸÌ (.GÖ?=Yz×¥¬§ÂË.´^Fhn@ MK7ÂÆõ¥\` b\Xj·3g;ÞÐî)±¯æ—ªÇŒ‚,¬š¨,&èÝ03Âðü§àÏN¡‡²£»à~ðÛks«ëíÉ¥"ù¼RÊ|b<ò€…‘što1™Òf‚Ô³EÌNר †Œ¢'‚9ïcd±Úºr º5î¡SÆc)EžRütœ¼‚>$’þÔ‡m·h"Üe‹Œ§ðîöPÕýîcìsÕÖ›±oË j,sÍÒ„#}%6¡… a¢öÄ@ÁëÊ¡‡#€Œ‚«m¶ô29ÃÉW¥‚9ëŽ5°”ðÏÖb<ßÃRœl"ÊýÍc'uÑ":LÕËð3—ŠX¢þ‹¤ƒ2–0„Å.¹šŽ”ekÂ{d^–ôB[£¯w»V-•HÆ2X¨À+B_%®W}ƒµó#Ë©IÍB•-µ¥4§ €ˆ;MP¹¤É£Ùx"ÿFs¨Ž`G!·# ¸ÈØç±öÎ;޹Î|‰`èÊÞˆ?NA {ÔL_÷UÁÚ˜AÜäXRسM¹ä™íü3t‹YÁÓ”²²ø°.JËNìZÒþ­ +3œÐiçúÜçÞ·a}¥Sfù„ añH´R}öf¯bÜõl^%òÒÿ‚ų’«•LÀr_%ÿ© Ö|½D8^ Ä6â«Í$·ÐwZÍwÝ@å™t%$íëúóF…ÿÜó‡ªÎöT› —zäÐiJéOÐMýßÚïðE­Ã,«ºz¹>¼îß-W¾—Öeö¤ñH¾*hüi?[Ÿ8„½ò_KqW'y«\M ÙhB%g:ɾ˜`MåîâypÆ0ZxK1·µ Àä\ŠWC»ë–: F ×ì”Ûýø¾È£ö£Ó¸V5o.ßn[®Ü^Z4†4Ü^(FŒ+—kò2Þ7 ž%ò2«!ì6+†! Vmp§7cÁµ$)I…Ô;C^ü¥TÊ‘¥Ë_dãTuócˆ‡žÑ»Iö$jKÐö†X«¥ëi ˜TåðoPò ‚ûžÆ‡'¨ä *¢ckoú‰CXŒåØË-­‰dð÷´`ˆq2Ρ­8Ùš­,ï×-Ó/€¦öà¯È:!g¸Ñ‘èß¹X æÉ C8èãµg›ã²dÙJg 7ff+”Ò¾ç·|ÐÇ8O5¤©˜Í¼:uÑ|Öç¹0šç³×Wਾm¹À{=ã§ b.sÍÓ×TàÝXL³’ÏbÊ`jN:¡oÎô»ÏþjÌÙZôë}\˜èoÓÓµP+&-Ûe‡;²ó‘¦»Ô|YX €JÙ õ>:) ë»ÚQTꬿânŸÐ„^C ð` ¨¯3Yýt4³špØݵw§V•Û À!?ëÊZbò§°·ëö~ú9 ¦ãb>©L¹‡<î/Ôöu"„»¹ø@ çÚI[™–T‘_5$qDÛ(˜iŽÜ(ú{“®¿s‹?ºªõÇñÒÓÓ†iÒ1º·¦I ?á¬ËÎp(±L‹0qz¢×·×d, ŽîˆÞ£X£¾ëoø-™BÊé³"6dèUÇH%p£ †Md ¨¾××ݘüYk–ßÔ{Þš³T7X]:>6ßëðÆ¦¶Ybv¡¸ê8‡¿™¾ Þ?3î"JtÖ¬Q§Y<÷SÁÞ¬.­-¹¼?‰S(„¶‘-=z2cLRÜ0µ3ÇÍeW_å¹+ ðm“žÔ '#m{ë '`PÛu›Ê dø6X%ñÊõL‚+^Ä ªP£6§vÊ#Ñ ÀëÅÜiž ʾÈÍPGcCägeLÛip7³8˜:…Hs¨ –§(2\ô+r–À@ë.õ@=Ÿ ÿrTn¨É•†0ð®Œ`CowÙDZ@TòØèôFià åõ»gŸœmw&R]!/}g«<„Ò¦«öûÑŒö÷øì=Të®) bÃr4ó]'Ò ¥C¦5,xâÄK)öÖwØx¹ ½g{7†ì}’f6xê!èdî±3?x1iEv›G¶ZÊïµ°dΜ [PQø¼$7ïR¡&HW”âG_QcãLÇæÙš}:þýÿâ«ýÉÖ V䂟 »°?õ¥ ïý;UÀFb2’»²‹v‡$âJ6‡ÄU£Êé:¨ßb@‰ó›µ3ôæg/GîÒ°«oûº¬´}hÙÏetÖ#Bš Z“{©¬Ò ^AÎR\l#¥*@A=îCeútF€÷\âJï’-! ØìÇÞQa8@ÏØ~ÝH«‚»ŽGz– ´B&Úb7¦¿éÁl*\TN/-Eûh—Â6òÂ2ñbV¿,ÛÀq¨e@oøèô+(6œx³@Èóhmޏ1õø¨Ò4Lsò9p“äèœìh®8°. ¤Ï¿1¦ƒfµXj¤pùœœµ“‡¿Â—dP/NýK'÷S˜~€y/NêkvUÒ˜ „xò$uGW”@SŠ—˜•¶ Õ’ƒ/Ÿ=TѱéÛÜã¿ ð˜8Ý5RA•ºªâ?eËà ŸñŒô‘£‘€)6 eBúå˜Àü$[Úmžˆ½.Û:$Ó¤©ÂPH÷‹·7O7Èd|'~RHkãF\"«ú1Øèxüx½ËŒÕ®7@¿¢cõhäȵo</ÁbðÔNj‘ïæ¯µ£ÑS¨ƒ>#‰íå«o!,’¹Ç_«¼ø·ªñ+1.ÒëÈ4êÆäÎ’†šiè`~ºø…£ˆûXte n3{Ù{tïEDð`â>)Û¬ëo¿O1m ðYÔÿ’¢Žä!ìqø=Úšut®Ð›ç´ ®’³xµî_Áâ“ Ž¬ $*†àâÇÓš.³Sª_ÒÜPæô¼‹ !¦ªÃðœ$N¨ ø4ÆòA±*ðÛYŠ–w{HVü½ò°<÷ÒЇx‘,]Å-åfWD"ZôƒÔ¬do±e\RÄ^íø{AEq‘E±4ÂýÚNo,s«I¡}7¥õR`U…®!§!v߈­u%êi܉W2Ó‹®œpÊN|âØ—=Š×¢¶Ÿ*cè›Ñi zí`ƒ³ÒqÆÜgé´ö͹énå,ô¿UÌr%!0›A` ™sE›‘‚¥Ÿ,Ó3òƵñdYrÖæÑg…žâÄuE¦>ɘRcâeÀ.eS¤]F2"ÓoíãÙPé2Á{-j2¹ì¨+˜ÎÄòã`6ÕîZâ?ÌQRE«÷‡†ÿÔYæâ¨ˆâ±êDLã%Ÿ›^Ž.~ÓKvFFÓÁye"õ”çÏgHTk¹BœÜï‰Z—·ÆÃvbáµrTžø!jÈJѶ¾«=ô¾åB[IC fm]+Ýb"¢D.%Þåt™¼õ¢Ž šËjxÉesñÚ{$§ÎgË{»·x²N9Ae/­4oËaÒkÄMþùÍGíêñú…¹Œñ½›ît•hiùÖ¿yü$RútY×D^2÷6®•&X¢_+diR¶Yú™70Êè•5V`«jnŠŽq¤ä•5®i”üÆQ2ER‹JV¨ƒŒ›WÑ¡®À[±A¯¤i³ýiÃÞŠ®»_Ì W,f\½üƒRñgfŒª^†«F³î«äîN’ q¡÷aaìí< éLCÁ~\¾v삜ö]iÇþýÜU„‹53}dž¼…öʧ$¥²‚ÂËÎ{%æÎ®.üÌtùëö hËØòƀɚvyâóèOªK>ÓõY’¿!UäÅ*çIåšÐ®^· [ž1«·Ê¢¥3qœ=/Ê—’¦M ضÂcCØË‘ØfUß\ß¾Œp”„07ëˆßß_‚»B;f)ËèºÂfØa­Aª—5 ©Iœ±SÝ” —p'w—‡š AÛ#íšìˆÂ–ßâyaÿînc¨ ¨¤ûÑ)_Tnûâ4ÀÄëoŸŸFjZ¤l4i‡Z¦ÞFoÅäÓbþJ·÷ûz 72àð¥Ð`ár)’¬IÜk“ß¾ëjá1t S%âN[Ôó5ê³ÈE†êXiþSšá¤pÕ2ÏQ3ÑA¿®,[TúðíME£*SyÚ•N»Çñu<ãŠ2ÚI~ePôMé*§—«*Sã;¥võµðWLÙä¯N­Žø-–˜Gmª’Úh8ºñZ]ñœ±)2j{h’›nU?úK6øÃg³pãüÕÍÄ,73@×$#ó#dIT8âñ}f¼Ýp5BÛ;ËDw?Î ¿Ãú˜Z›¨ë¹Vs_¾å5LZ{UMàÈ»áÌéq¸B@Q8…àŽºáŠû¬:&„« QRП-‘mëOŽÚVFX´G{+»å°É6ôÏe¡›€éûl{²-ØÎí0Jß`[D'ÏPû.ÂsSq#0 Æ8ópvö lDÄ6mcvÚ•ÒÙ×_¤ùõ)æÇS4*ÕcÒÇûð;:¶¤…É·*EÅÅ瓺§D$›£˜èª S{áYí•"²d$_÷QòÃ` ­šZ6š—Ø9#Ž é®ÓÏÅã7L~ÆUŒShœ˜3lA!gyÍ5AIeAl/Uj¼ ½lßJY0š5‡7MpnŸ\Õ [ÑÑR¨;Ä¢gÜ´û¦¤F)N\=ü C6çŸÂÙ+ïðiØâövX{$á|M—?+ƒÃw"Yµ¤ ">Ôe Ãeõ»eõtÊ~geIuŠpñ Ìs+E€Eœ‰‘@_ôðo²UÃol¥“æ’!7£À~î£àˆ¸]¼.\*N~(Éô}$ž)_¼#­ÄÖÆ&w3(»0Ë7S9µd sP~Y^^-ôLÇÀ‹Ìh`­å¢#m¯ ¹´MÉq=;Ô(ˆî("8`Eõº?°Š®gÚtÔGy¹«®=°þÍ<À?üµŸ‹†Ž2:iW¢¦´¯EÆñ®„)²nëÔZÜœˆ£¤—îR+Ò6Þ´T³Kšv[À¹ g|–›; +¿|êkFFQR'é¼_pàn‰©f™'WdôÍšY|²öš¨­h' A ¥Öð)@ŽE\9sÃv–øÜ»!¬ö ÒñØŸ•-p¡ö€©Í´¾pÀQDõ9KOÁ³ [ •–JõO¿`‡Øé¦Àʼn2çVÖØüÆéH»„ÅÛ–ˆµª·Oˆ¶ =zŸœÌA¡úwψBI¥³·MsÙj<®…m3ßÑwÜLó&¢þ{¢^»ž©2åUƪn±­oÎðV&^ÎghEÉ™·èºfí*;a¿Æ¿üXŽ?ò*…áýHæ“!Á±=䪱ҫ®úÆè?þ8öo¤W(çú”ðÕu5œœkWdª`€ÿNÞʸ÷Q—yôÀ¤ß¥}¤wÏUÅJxz5Å}™[Ò¦ÁBüÍÝ^þê•ÃC'Kó´[#ƒ¤Ê•OÞlÈÆ½ÔJâ¼_DIëê{îöv?âøHjŒ·úñl€÷ËÍ>Ï›QÁ®á|ÃámÛMlߥ+Ñ¡Úékp´¥“ mïìÀs6=Ûß¼]­ 8½d“¶$iZ䛓9 3sûˆêJSy;õ‘¡Te„;4Î;Kaß§ÒHïCʳâ“©÷7Î×¾Ýe?æ¦àѲXž”YVÉ-˳û×tg²‰½æpèC½üH¼Sy¤ÖrýkéC1é #øXˆüаÿ¯9ïg`L4Òä6G†dÉ=Ç"g®¹säÚæhäœk®I’1e®9rßÅd(r&Ì]r¤"‹ÜÇQÑû!ÞÿÞßû|€Z¹*¬PÇü,¨åuAžaxбñûç¿ÚŒ£oaãO'AôוÆü©7ë)…×'DЯ š$$®à;Z=5^ž: èúþ®.of¼?|•C63­û©¢3zVÇ>ªÊ¡¼ÔN zž€(óúÎͨ˜3ÏÉ{D Õ¢H8GmnlYÿ8oS…Uj;Üч¸¯'Z=a¯7%÷Zý-]ù¹ÜùËÒB¬À§`Ì9­ÁË'2€C^ÜÞUFJ|CH&«æ¡¹–}꯵µko¶ÐiW«À6×£0Ûs{„rwVÂêäböØÅt>…þ¾·øù Ÿ¥ÜkD¶ï ǼÁ'ú<ïÜ­nê8–‘bri…ò÷¶_héÝ"/Þu`‹9ÂoB}Fo[µŸì Þ#é¹×ž³€i%,$ÑžKþal99,“3i³5è{ÞZŽn3DÇ"w´›tÿ§âŒÜ¾E?\ÒÔç±JÉuö¤ã„¢n,Ø+R5#M ÞŠÇå—ò.ÉšÕ_º/8(¸óϳ{rOž”۪Й`¨Ô†)Gíñcfã2Jp¾¤õ‘éIøŒh»Ð@[èÕì±_Á`›Ò%lœ‚"ñƒîäô^¡ô5•g61Ø=ד{ 2-¦³‹«Æôà ºµ/·l=d^Ërž˜ÐþüÕ·ë+‘¼ÿQNyPjU‡€×¢ìŠÂA{ˆEš_\ÂnnÈÃhΈÕë…Äon¥é16ã}Q:›Mû——MñNÙ&?vaÞ*“c×Å=‚ÕoÝŒo»Y^:‡ýžô­ZàŸ¼,ª%\ ͦð ÛL>æÝplu™k¤gJŽÒ V ÃO"Óä=ˆô¡?¾eÑÏn"#ÉÚ@sV»‚¿+CÑÃ;&¶Â&8ÃÅÙÆK¾g¯ Æáá!²ÇðÕ¹ÀF1~og­Öô#“ Åý½5®8 bùQ–ðn™Ï¯ ^;¿ú(\D,ø‹¿š*u#u.9-.z©Üõ:ûÙ³A¥B-IK,‚qÇ€7=ЉÅó$Ö«½”0sÀ°ö›õ “dUæì„[åwcÍF®),ÁrÐiuêé©|ýb™†×Þ‹”Ãì½xËýñ6ñ˜t¦K‘² .½Zõ‡ü“úÁà^ÿ•º¡ÝÖæÅNe+9ªè2î(éÄ’G×Ì©EµñÈàÆ$>~Ã@QQ¶¤ÍÓ´ëïÖNó¨ôyÞV{´1Kå䧘9š¬È˜ßûi!*Z‚víÏÎúø5wå Àäx2y¿QwœsÁˆxÐmzŠP û;LÃåsY3Í>ÎAuŒQ_e óHÂÔ¸@,¯ÿ ŽÆðü,´b#RÊœ‚eGϬÒ÷øOQvc’7"Ó]yï%h^ô ôò2úE ,@(gáòý#45€?nSköüækí|‰z¢¸ã@öÕ8#!ļ~‰? ¼»òN·GrJSØ7¥Lú^]ŒT¤µó—dY_;tG ÏW‹êû sj¦Ú]¡÷tÚ›0ƒ»u TJÂfÛm_SäÁÎø7]’Ú£‹ðþ–d¬Ìö}ºÖþ>òiN ¨)Ç>×ïÝ¢—/T-ÎZ´%¬`¡”ûŸè’"ìq„™Ó´C'T»ÎÎb'}sFÉß9·T-wô輻A`¯_®éõîŒvÖ­nȪtøTê#_èK™Éí>ÎV¸PM¾¹iÀ÷oî¹j‡¹'s~`×x¬Kæòúy5Qz¸™K̈×Mß’wqNä Lékù°c¹G]¸eµ bŸç®âb”zïÅs®2Ý6µÜ+KÚ½§NT%KûÄ¡í4óÛfhõÜQÈ)Þ.JTàltâ®ÅdÕ.w¢`G¿ŒÃGú¶´Ø…Ý Át)&1#ˆèÕ“HQöærÒÝ R†¨¡“o]–öâèŠe¡¾ ]ªQãwX‡oL9*=êþ¸¹<üüv1OÖߢ ØF¾ü׋®ËW˜Fn_æq7…Ôqë9°Ñž¼—Ú±uÏ’˜Ÿ.(¯ÊЩ>"®ù p‘@ÀõgcZÙÈV±Ë¤oµI–¬Ù¯Ïælso¡Çøct[°º¸cA”U¨ùÉ^¿â8JÏúžŽÔ«¼+ôµb@àwŸJ€½Iz]æ!G\€s"JòL+«3ìo±ø= Äd­Åy@ ÌÑV„ÿÑ;¬ é}yð Vü¸—™«7wÉF²Ü‡mS‡6éJ_CFÜ|ïëŸúTW’éKÒáI®°²˜Û4”Iï¤V)æêãN¿¾´ŸºÂõÒmóÛ£þg°p•‡?¥eÙb<}ÑEðó(“Ë8ˆ¬ü_âøð?xbîÜÆ†ÞÆpüh‹LTendstream endobj 1358 0 obj << /Type /Font /Subtype /Type1 /Encoding 3111 0 R /FirstChar 34 /LastChar 125 /Widths 3121 0 R /BaseFont /XFXVGL+NimbusMonL-Bold /FontDescriptor 1356 0 R >> endobj 1356 0 obj << /Ascent 624 /CapHeight 552 /Descent -126 /FontName /XFXVGL+NimbusMonL-Bold /ItalicAngle 0 /StemV 101 /XHeight 439 /FontBBox [-43 -278 681 871] /Flags 4 /CharSet (/quotedbl/numbersign/quoteright/parenleft/parenright/plus/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/equal/at/A/B/C/D/E/F/G/H/I/K/L/M/N/O/R/S/T/V/W/Z/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright) /FontFile 1357 0 R >> endobj 3121 0 obj [600 600 0 0 0 600 600 600 0 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 0 0 600 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 0 0 600 600 600 0 600 600 0 0 600 600 0 600 0 0 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ] endobj 1337 0 obj << /Length1 1612 /Length2 18918 /Length3 532 /Length 19829 /Filter /FlateDecode >> stream xÚ¬¶eTœÝÖ%ŠCpw),¸www÷ wNpww÷àÜÝÝÝÝnÞsºûëqnß?}¿5Ƴ—Ì5ךkïQ”¤Jª Âfö&@ {;Ff€ÈÖÄÕYÞÞNŽAhá økd‡§¤u»€ìíÄŒ]€<M @ h `e°pssÃSDí<@–.juM::úÿ²ü0ñüŸž¿™Î ;À׿n@{[ Ë_ˆÿëDU àb ˜ƒl€QE%miIµ¤‚:@ht2¶(¹šØ€Lr S 3`nï°ù÷`jogú§5gÆ¿XÂÎc€³Ðô7 èa tøÇEp:Ù‚œÿ~@Î 'c;—¿3p±€ìLm\Íþ!ð×nnÿ/BNö#lÿúþ‚)Ù;»8›:\«*‰Iü›§‹¥±Ë?µAÝ{ó¿‘fö¦®ÿ´ô/ß_˜¿^c3ÀèáòO- À äì`cìù·ö_0'пh¸:ƒì,þ‹=À haìdftvþ óûŸéüWŸ€ÿ­{cÏeÛÿ+êq¹8mÌáYXÿÖ4uù[ÛdÏôÏ¢HÛ™ÛX˜ÿm7suøŸ>7 Ó¿DýÏÎÐü%alfogã 0šÃ3)Ø»ü-  þ¿S™ñ¿Oäÿ‰ÿ[þo‘÷ÿŸ¸ÿ©Ñÿv‰ÿÿÞçÿ„–pµ±Q0¶ý»ÿ~`_{€àŸ7ÆÆØéÿnl ²ñü?$üg &ðß$ÿ?p¤]ŒÿCØÎ⯠̌Ìÿ6‚œ%@@3%‹©%ÀÜØæï¤þeW·3:Ù€ì€ý×0 ,ÌÌÿáS³™ZÛý3zö»€vfÿIþ¯Hÿ¢Î$¦,!-£M÷Ÿoê¿¢”þjï¢æéð—ØÿhEÞÞìþÁ±÷x3ü½ ¬ß8 r±°|ÿ?Tû Ëå]œ@Ý¿-3³ü«ñÿñû¯“þÀˆÛ™Ú›ý³+ª.Ævf×ëþq›º:9ýUõ_7þoÃÿóü¯E=€¦ðË ö¦¼ÁVi™é.u8¹cbº½Ý,!¥ jEþ5ö]~ia[Ü•Foµ!Œ<¿=çOÞ÷dh÷‡º±m¨ºR€ù„ßÉiz ÐÖ¿¶qÒí2”"¥ŸjFy_ÎÉmBép0kìo)«”¼ÁM´}s‚»|¤ñ'w+ðǤxp@ö5Mý‹ÕŽÚ†^Wxrú5ñèñêÏðà@×5tÏ]NìJ^7(¤¯‘þŽ9‚:ê•Þá40éMˆ×­—$šÞy”ø¶r/Jù+v­roIÐé­‚|‰òNR-{UZØW3‘|‰ÜÓ¹Ÿ«®”âÎ8|M„ãA½7SÖA“™°?‰î!®¨{üëlkh_zsg'•ÛKº7ÃìQ23 †»V!‹¶88Szé-ŠÈZßʲÃìb“ÿ<Ìišð·uO[מʙåê;Õeâ*1žü =Æ:nâ(4n¼ë—jºÒQ•"/>Uöló½ˆtë% ˆ/÷€{`‰ÔÒE¨N»cj,Uoo–›U{Lê,þòÛ’`>8[œÂ—;1Œ"ŽÛd6k$T÷ó¤ï0ÃcÃ=­ò8Àëø‡ël2ø©ÙB ÿ-NE>…°­VQ?SÛ׊Û_ZßjcxÊSH£k‹_G–‘'²Âøøc±£ ~´½ Àë5ر3ìä=Í’ù9õC[¿êŽX? Cz!‹YÀGóµgàÝzŽD7 8’(GD¹‚Hñ%.fjM ýÈ#§:Ð YœƒN o‰ÓûFp=)I%ú&Ç.½Ù™£J©³k´ ¾< ý6K†#„Rcxü¸ ÙÀ[‹ Ó´ä'¥ÆÈÆtŠ(¤"ßž6¤}ºb#›¬]uŒ'ÙßšÌüå;ƒw÷ùÁm±Um•Ý“ðI¯Ó!mü,Žæ4FØBÝ`Kÿ±4û m¡[SPk<¶)óÒ ƒq-†)åÔ\ †µp¤ –Þ•4âϵ[Š•€M—EäÇCÊ%£ŽíAT-o|Ø–yfEézÒîeFN ‡Š~ë—|ÄÒ°¥î¯jQÕ_@X¼R¶x»Ûq0W}á¢fÞ’¦žN8ª°ÃÍŽ›5tšµí3¹(›+M©^Ú÷sžD‹êèî³’ú‡üè/Q²“_h¯>v|xÓˆ}\ 9—T cå»{*m‡¹p(D¥zB\¨=ì{9Å ¶Ù8Ñݳ"&”×·ß—4^v†¬ð!Åj‚M°ñP¿–wêYgäM_DrWÕE´ýf?ÈLöö1;ÊlÊ’ÙD,俼S¾ìý:Êû‡@X9ðEþcGBÉ:PŽrùUn xJÅxQí½…jûk2Æê¹”ygZn™E0±¹¬"rõ%°#žØèÍÐOà…¨³qEÎûДv`æPᥧÜàÉù¼ ¶Ÿm}ÆOà}LZÝÂ:|,'˜Hõ•ù½g{ã[CcÖ­–ç®3Ê”_!qI¹1Ãl–›wløeû"-ð–·v:!”UËñžêG¬ç!E²ºZ™tÿÍýwÏ%ÿmVçÇ"òyìÄæçÇrü८\Q‰Ï¾ó`¸4Æ)Þ°7¹ÕÉ.#³r.±cHVXÏëg/Ö=É.æµfø¸~ë’Pæþ©AåhèK•H…fŬDû‹I/îsÓ¶#ÒïàwƒÈ¤÷³ó@OÑÐKÍD7èÃ8MfÎÆg8eÇÊ)dôvˆÌǘìÅrD éÙ'в¯•ñâ lL¨¿ýÈ­‹^æPc$°I’}£]‹¥â ªÒ¼FÙR÷eàBIÔb ©Έžáòú޷‹³ªÊHÆA¦ô»{ÿYw˜Š+¹¨ª¶ DÇùgÚƒ€Á³Uô9qS±½?×Bx«õ¿ñ ¿kJMÄÙ™ðÄWÊ\²t—¼ÑŒƒ½°Õ¦’”pSÿpgrIô¿ ùªZ‡ä+%V õŽó‰ì«£®˜s•WDéôö *îD‚ I0ÿñùB–«œD‹×jA+jGŒ;Ó¹8&ˆé1Ýú“çŠÏù^3¡™¶"íÁ:š·eWÕ6^#—ÎBõ¨,^Øsõ®‰¢3|«´{ëõšÕ4¼:ªEßn‚¢!!×ܹ~ńﶵÝû-aÿà¥.jýÈóøʺžQQ9½‡¹š‡Œ‡4®Ow@›ÜÇ0¦wÞò¼«\M(ÓC…åP"×j GU½þìØ ·kÒ³[ІrÆ{è—~UŒª@a{K­ ázÑ…cÈß?æÚÝz´éÖ+i€hO/%—QÈÍËÒÝÍžHtNã²ú¡P˜@þ“‹i”ø‡:=»(-;%ç—kÁ§µÔ}Q[²“•L¡q«nód01ÙLÑåB7éoU`;N÷0×ràjnv’;Ýn÷i•ŠÅYý‡w’>½XeL0}rá'Œvªz ‰u¦brº{T×9úF†8ðË×RC°LŸa¿øŒt¡kÏa£LO1Ga î~¡‘  n.ÁŸ`¿6á Ç»•öAWÏhÒgMv×þ°e}Ò}õBWš2jËŸD]÷æ%IRèI¼è'Ešôh_-– ½’¾¯Î•k¦z>xžiwµÑ~µcx Úˆ«•šà<‚®†m!X"™¿Bþ¨«À²²±€ìê&[ûQ­"wÓÅ~©›‡;¶×¦Dà¹|öÁ>¿ü°y–úN¦ªôLÍÔ)ø³Ê‰_x®¸Ÿœ.ü´ãۂ̳ëÓxªÿÆQ:+Ú>³ )Ĩ‘‡+F¨?¹ñ¤¤fX´^R¼G'Ϭ_U¨}Œ•€;ÔK軈¹Ù&KzMÏ8J@}gTÙ%¹( õª*J ð¥)½?—Ä$úï):p.„ÌHÃ`Ɔ–í"–ñŽNÔÂIª\x¶'kƒeFbR´ëyf=whoŒºÓ²èŠÕ–Dð"~VWn îMŸp!Cð÷° ¿Þ‚Ã}Ï1ΪrÅLM# DÏhÿ”ž±j¡Lò\¢dBpïФäö,×eeÔ-¨¾‘Þqº˜Â0x{ûë35HŠuîD#·&9!„é¼oyŒÜâ!ƒU§"*p÷@®ãMéɯ墤C%˜”{lwN5ÁöM<8ëDL!¬!»x¼—,ûÝXÄì¸=‚”ðfßyÑ!ì×v•,LI?_ ­Íç›ë=%„³SýúhÀtÅFŽm"ºÜÝ„I‰/5rîl 3üjX¡Ïñ0I9ò©|)S-1!¿¸R*¸/‘‘7÷ñ=KìõÇ^A0ÀµŠýömÕ[+V$@ÒÁÛ“ ˆ¤þÕ…:õ5‚ž,ßE4J Ëª«ÄR_:ÇPÛ|óŒ0HÍ‘ä[7r Û&i;IÖ›Cr-ß¾­»@Š/qÆ–ûÎ6LøÄV“P_ìYҰR'ÂÇT%íýR{=¼{µÓËò ¬%’„ud+úÓ¾ß+U4ÉKîÀÇYC44—R'ìð58¿G—³‰“@-ΊÁÒÛ…«:r>‘O¯•p¯»µWþN–Ò;⟟¼G¿ò¤sf„p•@Æ‘ÎÏ…)¢e‚ KNÏvýQs¸k¤èŠªá$™›¸Œgë.‹1ìXÿÓÌ3@¶-V•vØ¥áß¡ü”ªA´½P„ú½p4ëªpç¹H?SOšð¡]øÊüÛAk»%Ögwrˆç|Ÿê=­FߊP3߬æYŽ!ÖÒ.(o-z•Ö¤jk:\Žë'ç¬* eVf Øø(³n…ó`¡»LŸÕÂvs8È-7†²HŠÊmUøfnmo1K±xí[J{ϛѕTË0<8i*_×/³bY»ïIý‰P¡ö5,4‰ßWÓwkõÄCóÂ܈ë[9œ†H.áê;pÂ϶¡gˆ•Ú†PìYÍoJÔav QßFݘª-1²7¹óH%ÿCEzÌ¢º"®F _ZCÓ9 šiOóÐôz7Ânè8zU­Úœ{/–7ðåT™|;ŒÈF¬­«ãýA'I\ÅwÐÝ–eõ õ&R^'0ÇŽçå]â—å äåöù¥&}b³î*R%K×V´IGgdµT,ø™Î¾½_XY»¿`6‹bÚ|üÓe0mêr€vøñ]%…?ªzÖiõ£½aÛqß§W‰¬@€+Ò—~† ¡½ÿ3ʤ%i Öý‹Úq²¯Y¿ž#wÔA“–bþ¢›WT@¶Mj0ôí–lbX`=<ž+vÕ4¿ûi¯?4 ±¼[¤áÏmÁ—?(‡g¬¼Ó™iÔÆ.çH¨œP±é„„Ôª¸±LÈ/& ûë²L•k§âÛ‹¾þø»E~]˜ïýÇÀ wÉ·O…Á%ß:=6(¤³‚wžlB)L¼]Qëg;Cæb0¤8c;vFy×bïŒÉSJ•W½Š>aW<Á Þ7ìÒ ²äˆfã½ï}7 Ó+>nÁtKX‹@ƒÞÕÏ+K-”¹aOç¼Z£ò"ýNTXvè¾Óø>Š&Pö"rS¨ÐÚŸÖ49fÔ² s7Œo‚Âls•˜}Oé’Ó”§ï×¶x)Õx'!ó®X––)ˆóšÑ0ÝÏwRsʩϱìl9üH˜I2™"¿_2øÒ$3:px“ewxF {ÄÅ®,Ùø;K¡Û9ÙÛX©eóÐûˆA’Ô1U± Ð ·L¹í³7ã!ÀÐÁ|ž>ªÔMÈÑ`·ù·'Ó5sÞï‘w°ü£5¡†ó·#ò8Šæ7£ò­kƒ°;·{Ú%’ÓZ1N–7mc…IÞñ’Q†X¡u#P!†7S½ç·âÅ­j¦_ƒ¡ý½ÒµØ%DN+zÓ’}4˜€XWŒû]oæ‘]D]t™l¬ Øj³8F¥LfÎÙlw6§ëcðÃñ¯µ$-5×Ì(î´ÄÁãÄô¨Œ‡_§…l{ŒÐ}n£>¾6¸kV“zkdô”‹‹wðI3¿ò8SÄËR`Br#Ã&º4¾=¡þxqâdm/Â0ŠÃ¹ùæd!j}оzu?ºðu·izý#¥rzV¾‚—ê!H¹iBÒ”„0(óÊ4w¿#ךBz¶Ój(O˜é}JîgúÔ–5g•h}›÷YÆß½'1x„Ìž'ðöBçKH?6#s>ÝeÄÛé£ywüFxçgHQ-ëÄ„ZÓN ¤úLÆ…{ø]w˜£ÕA‹ÇÛÂT“öïY2%‚Oý:{Τœ·ù¹mf%Ii ¨_Ðʾâ\¬_;‡÷¾”|#@ªF¤œq®#oËbæSI•˜µ–˜Ã-ˆ¸o+ݪQoôT@7×d-‰ŽTX‘§Âòy)ÁÝ!t+1Èô&?)ûà%]Nij¡)[RúŸ±ù–VìdíCÊåMÐöîØ©´Wp&Y¹ü“/ÿ$ Ã-|÷æè‘€˜Ä-OjB$ü‰Â£W Ux.. «"²ßÐ(ã÷\j›¯1fµ4a¹þ+ò„¿, yç­~Øâù`Ùá¶„ç3Mœ:áÜiÁu´L18*½‡hB0øÝu”ã†Ï»5Ù*¼£ ?j»€$éø‹ùï‚ÀpQ¹<ÂÓ¥Cï¹æ—sål{ÔTB”¥Ú w¦héRs¿4á&æ}¼™˜NÜt-÷sjôÓD…„¹"¯ÔD0x›Ìwõ`è9G[Nºxw×"ws—Õ×Ù¥†ùã°Y…ug…TïŠNCbÀ˜óÑîZg#Ï^ª-Ýu4ìfÂÃ7ËODΉYoüÍoV¶NZ¿Ã2'iþ YíW‚†Ý §çtÖXå1Ûé–±}G_û†¡ñçdÊÃÏ™6LéFgY‚eQ®Òé i•Á6(tÛ»Z=GÌRxwfþóä(“°-jdJTèS(<ŒöQz_´)ÿG0Õès+?Ä„ë#(½¢8ªË›Ýg6‘„Mš2 N¼ ãŰÕ9IµƒÍEƒ¹ŠVΓ×êX‚(¡<Ì1å×;“5s‹!—–3ß 9ÈÛ:gWoV‡Z|ß§Èv´€1r/#J *?ŒK(âî N»$Û#ˆ&:tõœù±–”–ÄnùJ×ÜÒë«Ô¦ŽÀ`ÆW؈4ï¶5¤Y‰á]É÷Ïú$Õ£¾‡u=WL@¤)B(Û€ÛëþÖ4øt¸¹8oži–¥ÎÅ$3.Øø÷2šz¿Æ(†R¦"è/#(©<¼šjï¢d}Ö†n“{ŽËËÖÖðyBúN€­~Y ó‘wÂ33¨º…j˜"iQÖ}(­‡|Rb–+{ý€ù6b‡º´ë„ʹV Í-¤œêYa¾÷H7¹éÇ1½zWõêÄѬx»!Õøöêåøö‘ÄœlÂ0Fì,e„:¬þ„Nˆ ÅB”qHÛ¦}Þ#ÀäËì”ú3=¾Ç¼Úµ¢QÞDm£Žœ4wý,)Ö½™1®¼¹up~«ÊO¤*âÊØ8Á9yZ“΂ 2ÚRb*AI9»´ä¤~Ño¹!æ[^ž­Õçø8u’.ý²Ä"Jé—«rœ® em‹ÆŽÄPÃÁ›g[¨;"­HTlï›`R¬ŸÝ¿kh>ÄùWTD_º|*§-“XÀÝ~Xü™%Õò™”“ÎôK¿ãQwË /(ðõ°&›f­s¾×9² ÉýZŠ@¸-Ü?Ibõ7ÊÞ |«4 Æ´…­²Öø•—«Yü;%¦Ý´ûNŒà]‰Öš9m0ëzšÈ®É‚—G®¿>õ½´.[ùé'GkúF·_á~(~þÒTpZ{HýÏØ@ò4Юբ¿"¾6ÖÌ&ž_èpx Wùë ÆÑ•š°J]èBePÛÍÛ¨¯T_]v—Â'_ªƒeg; Ñ+ÃfP­\Zá!ŽZæt'³˜^LE ƒÆF¾øoÜXfTÎslÓ)¿ L'»4Ò†í;Ví&:’ò$é® ôæø¢ê üÝJ Q>ÊI±Íº£ÄÜ÷fŠ›Òwë+Üó±H‘Œ?ˆ'ܦT˜ÔV³F#Õjpi5’LÒhN‘ÚACõg#ž¥©}E7^å òæØo?G …?§Ãi¯³•&¯‡®I'$½{È •9&ù¢Ü1Ä/^%Õø´—:Èé'?–@NdŽ2†Èßùvѱò6ªÚ’gâb+LËá{¬«±ç'GsÓÍhñâ`W[$,AØCh%Ô¯˜À¼:JIx` Œ\œ “µPîû¶Ô­þ~ôJwÀÑîé,ÜmüÚ¿íZ§ ¦{Ol©®U[.$\’#}6¡d»Ç7…¢‘±÷ÙKûÄâHö­‚¼5]±®·¥:] î®ðçb¢Ü&G÷Eï,Di8#YQ½œ•œIï à$'5/k¡àw…l®Y‰Ý ë÷õ««—àN»lôÅÏá—*ðŒÄÒ| ¨ÂLǯ¼>|5CUR^²Û+ò9Ðôn4®5ÝSK2) SyвÖ"Èði˜mFY²;{2n–ò{beMÛœËlƒ[»©²ßlÔÎ_Æè¬šªÅÛܼ,ô_àMˆ© ÿ¤VÕøxÿCƒ©~Ò´•”âÒ'ié`Ÿ{¦C(XÂ)!@¢ãF/-QHW=^í±ód½´Á"÷úƒc-Èl»z¿fNX”ÙÏKí©V²3í&•òÜ&}¸vv§+ˆš6¾à½ŠÒÖoë¨ÿ:PÅÆÑ§qY›Fx£žël°õÖîOùdÊåè²[ÿ«útn¿©.TpP?”ýs‰Ãúr)>Hñ¾êÌ‘\/M×HžÓG{<ÓŒ<—6a3©_æúaÝA$-ÝðáS*¦ægbœöô!þ°BL%#xä>Å-«uNßV“®¬ó»1G¿u™ƒF‡:ê˜I?Æ“õ òI_9LÅœ—º££×ï2£`ïÑŽ³ à(Â"óâÊââ¥â¯$è·AOL?†›—ô­$,Шϭœäg‚tê½˜ÊÆ@«œáYÐàÆ{•â ›* –®Â›ïõäë!á’ö 8|BÛañµlùòw Å eO²‰{|Ué‘ ’0N˜°à&ª+û¼½É\§Žð"ñO¥@O³èœ~*X˜}[Á4|¥í‡z‰§_w46ƒì=ØïZu‡ ¤7ḭ́—°zÒÄëßlrÕÔOd6 „Ý7RÚc#É?—ê<:süíâ•lgØ?ÁĵvO®„ší?ÿxâlóÊgoGXçÖ¥‚^;Z) 7læX êû½˜Ãù.z>ŒÈ*Ÿ(dc-ê™äÃË ŒÕ΄¥ f心Áüö­ß¼µýÃ­ÈÜ ŽÜ¿SB¿’(è “ì½&Ýèô;„M;ã`Ó <ÖÅ4}Áߣ‡ÌõÎZÄHÝ%"[9¢ÜÍm ý¢ –%«'S ÔD=èfrž:IâvÛAp¹DçóQ!âÞ™0³6‘,5¦§’6"ß%:ú/ÛG˜«KïãHÒ7ÓQj‰RJYÈ8 ¬w?Ö ”ü–¤l„t¾rÿÄJÄ^9(Kpà©lДHkVà”嚟B‘´µV»™Ózœ‚|)ì{ ü‚09nÞO#qzÀñ‹TØu¡/)…2ßšo˜"Gþ†x˜Rš0»ä\ˆuvØDà—¯è~д×ÅúG„/Ý+™± ‚Ö9=>òL4€‰ßÑ#-™éDWÎÍ>Ф© Ïž !†'wĬñ áB .—ùöOõÞ,,³Šãr ¿AâÔH|®CÍ.¹nÍ16"aóÆÙS8awY!½{ìbù Ì|[¯fvƺk@#2Ýá{kdÏãµQs¸ Ûº55Ö5a«F=Þ¿ŸòÝPÖ—£MÕ!ôƒ?ÖX3½…O!ù_wvCó²1h~ÿJ°¶¸SägÜÂ+º*ï%:{šÍª'r(E%$ÅwþÞ}xnƒ»ùˆ3øâ›§M¢¨ÊÐIj¿éÇêýå‡5yHdõ²ç^úÑsŽýßø¼TêâÀ<— ’ÃüŒÑLMñòúò ÑÍ”›ÑYò×aýSx5+LëØQuì=FõqÃÀæ­R ½ÚÞLU¦wÛ¼ñMöÑâ´§;‰aÓÒ@˜¦X]Ü*u¼“#ŽÇ{ºCÍIå3ïñ÷ÜE·£j¢]4KÔÝ´oó×Ð fS'CUº|îX‹±ùйÀe­Ü×(a rÁsÊÁ±&4UlVð^0|Ù¯ Ò*‘z^®de/švæÔ{ø´¼T+Q¢koESM¾‡1yìHG›ÿfb§G0Ë"¯ò°OÐ*mQ•sÑ&eÚi<ä¬Ò£¦t2âŒ}0h·7ˆ±>£B?Y䥒ºò§x“QC›‰êêzÀå(*Ì©|–24œ®ÖõM®jea/1ÚA|bô¬Îs*R@Ða1aoÁaéÞ'×½/–‚Þ|z6&±‰.åܶºo¢Qr¶ Z %5+'£¾múˆ×aiu5ç+j¥¨@1?ª¡mÈØöS«¼¦éá[m1’Ž8ú+]ƒÄ¥Ò[9™ÙX[9M¾)¬Þ¼z$¹÷f%•—1j:üå'ïìhr"R„amE‘¿¯>ÚœjÍ8*ž5‹âàÛ,•«‚ˆì R‚z-G™|¨¢Ì¾2î‰àæGàhÏ%4ìž#ÝѨÏÇè 1do»XXØÙƒDÑWAq„EH}Â×[O¯Å_ˆ.µ£– ®y¢Òس]E6ñ—qÙy—TSX„n0«_ãjœpïïYüØ÷L›w˜ æÂù›†5:?•rºevåk¡aÝŠ I„Fäð¯èÊÇ!œŒ.‘Lñ2¥Ï0ñUFÓöFu5ìaÆû‹îò ÏÏÓ¡ô{q¯|©S©¥/æ0¯mÕ³˜Ïf½[64 È}çúµY ’ÔEVÛ$*­ý¹¶WGû•»“![/ÔŸmáËÀãKC|¿»OÞh¼¸ ŸåôéxN|ËÔËH-‘ œq©äuEóo+|ÈG¼WÅ£A+ùÝÄnSG§¨­Í¾Ÿk¼·½ë‡Fp±Ó,ìÃøáÍÂ¥.<_jÏJÖØû‡Xº~¶ópEZh7Í\‰Î) »>|~Å]Z´ëvm Æð¨IË4ïÞîn>Wèdͬz3 Íi[˜%<²Å–úð7a3Qˆá3Œ ù±R¹›iÕ¦2yÓz±¾ÏP{àK±úÉj¢õ…LÙRTê†që_å°ŒñŽ™>W§¶Q…è}½[ãnï´'™ËH=ks•þžðë\Œ‚¡Ð‘rÌéž`àƒø V”øÓÂÇ/Ca´í¡—xvÄï âdÅçÕÅFH®KlçMàZ º},c®6qa+Àí fuýÖÄ•Q¤ÜÕ†ñ nh’×ßÅoßÝg xZÍ8Ò>­DÜ™‚ç{JÝ>zNl‰–òM̱°;MLVü¼GõåŠÑcâ›Y*ø.—I܆”Éþ’¥2kÇ›V(…K·Ò ʉ;¦^ /Ós$ýM½'ŒÌA¬-cU²~YÞ„µ~Ý¿Fê{È_ å_×@.Z­$ÑößE_ù*š!’Ë™cõ–p隀Á«“–¢Í ÕÜ­yýØÐ˪Mt×Ådàýä§×>§ÕY4·ðjSâMÀ¬f‹Âæ{Qì|$dÚJmâ“…¤ þAèôHm¯|[À@#_ìã<éÎýyj0_1ÆP»UÙÏÒ%ÂQÍGžyõ¤‡ežCn|ã«|ÖZŠ}‹Dµmo¾6Ý<(ãÓx MŒžœV*5û£ÞI# iK_ê©¶r.ØA ùõg!e&S» :£çèÒqÿíjžoCãëCjOQÑ”o:¦…^NómºÒd‹VætI‹¸¤j±ãf}á¯ÑüÙ³_›uÁ-îWtï¨*à/ ‰ï²ûÄjD-Ö´at©ÓŽî]*ŸC" A𨒕pdŽ4ë¬y©Hò^®†Tüﷺ΀SÄKÉ3}•S¶Å¨!²yû|'yûµÄåý·(f6Íåé´8\záxít_ ’óðYí|è†ï)\ƒ– Uzhn”õ’±F«ÝõFhrL¦‡6eu¿—£%=m¬üÞñ9lxîØØj.«C*g@2^ºo'-çú€µçGx õ“’~$#Ó ºðmÄ.¬Tዯ©èUÐXô‡NÎzãúMJ ,­àÉ]«ò6æò®z²¯Mt-îè[¹0S ÕÏõ°~RЖõâ©e‡Â¨`îô«á„ö௓§æoPÐÁ`ŸS¡uyØuçöw˪Xðm©¯Þš¬à, «Ç”ƒÛj¡·ÊI÷Òž®˜•°R R]§L¹ûwØ“x#xæÄ¡¥Èª÷8X\ðéцRò/ó‘.}Ey Îz„“”Òr-J}ò–{K*6«ZxV‚6:5"åß(m—ƲªëmîÎWq¸Ê“¤—1Õ y¾ÆÁd‚Ÿû‘µ¾'Qnî~Šò3‰æ)•@+ë8e \|)úJN=qCeIÅ ×DêͲùÈ@qØìü4ÀI#¯o=éüÙ)R9iI#Ò¶‚Uéî¸à…Æ©'3ø aÅÒB-‡ÿ²Ô%6n¸?_CpLC;iœ~³¨À9ߤZär1J6³&Þ½%{4Þ7c·Ù•°¼óÚ oË~¦c÷Þ*ô[K¨à×ì¡èÜ$~|”aº&ñÈv{kù‰ÃH ÈÛâÆ;ó2ði†ÊŸXæ)ï¡nÓ¯EØl¸½möÙî¿ôeñ‹X Z4øhKjž¾’/8ôì¸ònÉòPUÓê0~Þ¥ÿ&ê‹~¾F4ò$[èQšá~:,´4@×il眗Dqd^#!OÊ#8š/€ö#æõ¬¨õÛði€Šú4{˜[ëôK~žÇ¢ÁõW{ô³¯*=ÑŒ?˜üqÃHkã©AÝø£æ¤“PÓ¤ùËÏÊ‹Á* u3áIýùÉÃ]g ¢¨2NÒšdkÇlÛÁŒÞoàóÖd#ÌÅ$­x´‡`äÂuóKè7·(’ ÿ¡üòöC…}]A)AùàIóýµ· Vû7ŸÓj%‹µ–¨Bܯ@%”èŠ:îI•ò­=î‘Ô9Ürµá ê¨*gˆxæ…ˆ7HJȸÕƒ³Ù Çèý’»~1«/×úGí)HÃ"Uî0QŒ@‚[ü©Ûù¥ýÁ®Ü¶ÓÉRWüÃɆ_Ç@Bk\’iX'U°?º¥k2Ö´p7&ÿ.¢Ü¶åÈMX;eö“¢oÛ2È–gÝ %ûi­0/ˆQ¥ìEÞ ;EÞí Y¢l·ˆ&H×F ~ÛðÛòÔ[ £( i’™ýÖˆ­×äj_ç‡s‡¡œø¥ëÅ"$-FT¦×/òsãHêTÄÞpW:¾­K°—¯ââãýteLâ <Û娗‡Awù±M6&p µC Ÿƒ*ŒeD-@HP˜Qز߶­ÿ{ ­­?–>=£Ù~$eºd Š00…ü×gÙ±B`–š>åÐð ÿÔ¥DAü¼l UõÀ] qGØbÚŠÆêÞÀŸ×fçQûŽF¨]E¿!t—9f!§8ý*.îƒ:¤b1“áîJ6âqÇ)•P—ANV°d{!áS?ž˜œ£ /5W³åš [RÈa;ü¾U¿a£ÅNY¯ H8ú)ö_ŸáaTÁÝ;Æ¢Ís÷í“qüèÏ¢5¿ÛÐ@îÑåf9'w‰-jÖL¦)ÉÐW©ßÞé_‘ dï^ãŠüŸí, „i×ËúöŸÂ¢ªž3b|8}X²«­c2¼¤Òw[noGD÷¤€¬0Rzó,ÎÂW7¥X$›Búbu`¿ÿÔ ]s¦lä@AD£Òªœ ÕÁ–ŸšŒ…¦rsúé°ôkwF+sBwþÆš÷ˆ8Á AAH·ù¬ˆcÿm,E‹4o:¸®Kl?¿ò$J€Û-§1ñ±TφQqÇ«¢Q—9©!T0TkgÀŠ,q½³µIÚ´ ü—žŸ‡4sض_S§Ç‹ ï@>2¼õ®±?=šU²rúZú±#z{¿žt‡¹þNs_±II"TÑÔNôŒÎAenHEÛqu¡C–XžZAFN–ñè¬7Í~A v‰ ¥)qõÍm—Ôï.ú­ñXx[d£E¹•3¿¬¿£¨Žñ$èÓ_'Í”,„2ÏGãRØ:<•±ÄJ‡6i¥Ìö˜,Ç.‡{ÕúÑÅÒ"CqJ"ˆlã`z‚.ƒðüÚæ_ˆiœîÁÑýl…`CPPkÖÌ÷~ćõÈ}âµ1ñKº+GÂ\Ú²·5ÂQ`Ž—ØŸlŒ>¦ÆÒÍ6&® *P»p¾»°¹‚t±Ï . áêªøy •Ƹ:J|a1š˜›¿î19êzžÅÜ&LŸú‡çå¸tudzÒ8†Ì5XZG”H¢ÊZж‰Åé«þó*¢µývÛý Çó8œu6#Š—ó§Ïß5Æ:À Ø%qÚÊ·Œˆ LÏyÌì<¡‹9M8 ß\sz.bÁ&ÆÙô^¦²ÇçDÀp)q` (}ñ„ÓÍ=9Yÿù£5œQª¿ZÀlÔ„û¤È©žõ¾ùj‚ißùÚ¹P~`å3ëT¬c•j‚*nñ6­"“¿0T7ü^ÓïÚ&ȃ`F‘¨AÿT 3»„˜$?‰J¸öÅ«ÝQþžp´N•òÐ+Xd¾o£š“CvØ9¿ÙÓÀ?ÃJŽK'ñ[Pì~U³.·34ŽrPu,•C<w”Lí0¡7r“îæ;(Ç%²%b†%wä«x£ ÉÛøìmáP~&ž†»ªòòbh ÝËïË ·Ä2E.œ€ÍuN¢fxŽcȧ=´@j„•¦r 4ƒ®ùRqîÄ®—ÂPÕÁa*ýº}œ]ÆKàôF ûI‘ OPe¶ª  )ÿçkt£—‰DŠšÓŠ´´·„±{„§eE+w½«N( e"Y._.³{s…bvÈñÂwÐúAá/àwŸiIãÜ6ƒÖ7ç"a:ž‚i½­šÜ$ôŠ’0šý%)zË?Ñ!Ûp:£Ò?ÖÌ…•l º&ŠWîaê¨2)Ö×yPu/|KÏÝõHüäæúÇ"gm{y×j¹ážz²LÅ«åÏóý:Õš0ôMT¤õÛ%ÄT¹›4Š‘l¯±Ñ}†³TÕq‹G>‘7¨ž!ït–rÞ‰­5¼÷$™™§‹#zZÞ<)Úz/…ǬþÜyÆ1 â÷ åoÄ—]l)Hüã*_g²ïॾù‹Ø>¢¶V;_ ‰òî’ΪBg^ÿ—eóÀÊpEù”û:ÉÒûeÌìËþè™m8²t€6û´]þ–WEh6B[©uíRŽŠ>oZ‘O¶úDþ];I»ýsÏ©•„´9ÙçFG·zhˆMÂ…K ÷ë]ÅŽæ?aÒ¬†Ñú›5Hþåï9¡vÜŒ¥½n)Þ¥:•t¯7–ª¾ü%>yůASÓbxEÆ÷îœBšÆ×¢ Ñ`]Ïë aSí(‹ÓÒœwz´»õšØ#uT"KÉÀ6:$Î:›Ðfi?šú{0NÄr)ߘkª{Ì÷ûKeRí_Õ-jK ;UÙ¿b´`]#—¾w¬Múå|F<°žZ³d” S’k+Â]‰GE§zætwq³Àæ¡ÐCéç\K/§Ö0ÿŒö– S."¯7ë•;/aA ñzü^ ÑÒˆ€?7;eöÏ®ooö1ԽᷟkÆ|o±Žy[¤‹¤8¯ûEÅ%Þ[þ÷¿ÌYx˜M 5ñ×êÔHE£½kæ–Qˆ† êìŠ'D]OmSù$‘íuÈ:LYüœtˆÒÀ–¦Ih¹ï°/f4¨ÀglãA á’Ÿ­­å;BÌ€êÍT ¯•i=Â~(ï[U”C—O»yˆÈrl®¥Ú¶ûfžyçä¨*×OK˜;’H©¡ÉÐI>d‡z(øõhëIëSÇ÷A™ÔŽEÙËÏî_ÒšÉ,®¸ÙzkXŒ¬cߦ{1瞤ýÙkå^;[ó¶7’c»\Lœ'¡Jcª:xäŽOˆþ+®žn¼¿—Â{ÑcS]´ïþÌ7ì}Î)Ô‰óÝ}ˆÆ{C­ÓÉenO1"OëAz‚ÖÎÆzÑø„r¹Yãi‘/œÚOöN9ò ¡`‘¾úÙöP-ÔzèUã¯ØÅn{©ô*L¶n“é,‰„ ÷~2PÅ&]E©õÕ%·"b¢>u±‘5åÖJ§ò¸i·!.Þýúû‚ùHQòÆØPøzm%eÊ þÎ!ANsÐL’Írl ?Ùy‡Ã$4­MgÖ:LF±QÞ°XqgÕY v‘o$ðS^F4§!@Û~Yxr™Ãúœ_¿ecyú@Mòs¤ÆŸÃ$Cÿ±\¡·R š°ìje£O1 >ÆÉÇ‚QÈp0‹P+Ì$ÐŒñT@ÜK­¯N9•äh& Â-ÒÁÊZ‚ÇsøÎ˜3V¼ÕÄû€HK5îÊ¿"gJ¨KÙ]°½:Öî–äû{Ëaö"»Aj{Õƒú¹›¨ïëÇQ,´7dµBŠfªøºç…ªO&^øþ„ã*Ö=£\/:ìŠ XûY$ µö‚ÞŸPotÛa,pBÇþdÔÙ²þ)/^Úeºlš‰b|kk±YÀõm>?ÄÇ‹SBêÆU§æyôܲqEBÞWwU9´\+Åÿ(C a¶±vmøº´ï\vZíßa¥«B)%UlÖñÖ}ô³ŸÂ3ø,|ñ‘òÈ’›p9îì "¢¨CznÎ {Q ò4¾öXœ+ó_ˆ,#n¢òî9ä-ãn—²:¥6!¬½ûvü?íšW?Ž@k•ÚAí¥ˆÕ ´6µ+©MÍÄŽR[iíP£Ô5jU­ÔÞ{Ï5‹U;Ô(uŸîý÷íþîy?çœ ¾ØÄÂj­ƒ(èãECI¡Ma†p¢ã<æåÖïQ×NvìG´.w`v¤`¬}žMø  ÅÓÝ:]¤ŸcЇ¿¢¸äÙ–¢ QÛ’Øß |” 4ŸK(°÷¶¤›Šñ_üžàB8EÉ­IgòŽÙµ5ô7¶_´Ò׊ûuŠÈ`QË]ÿH_aOÁ^ÕÏúASˆG†‘˜ÆN,ý˜œ½<º%kCÜà"ÙÚ”¶Qbºw¢ÕyÜŠ&Š}RÙL%J}k’šgP¥'˜ç Ýï_íèÙY/ ¥*ªÌAŠ®"„ï…ýˆ‰½æ[‹,å$t<úøZ%Œìj_܉GÍ·¯žÆÔíÃe—hºÝŒõ(:üJPžÈ[eZ°àîÿɯv…®Ý#sŠ} ÉÞ®³É{ãn÷¬fAëN:\®¢}‘¦~(¸_ª—"piùÜ'gxä½Z‹Ž|ýAîgKô£¸dae9–óÉÍk[ž|Ø ‰iA=ÓOEw@énŸZM?|IihÄ,É8ÉÆ”“ÚÜ s9^bXzpôbÛRóÔsçHñþ–T+wVyb+Žš;×r¯Aà=æÉÕ­Ø{ì&# o˜hÌj³;G™‘÷ ú¢÷ŒvÁÖ´ ¸ï>Jåw¿Îço$NóÝõ8±ÅSS‹‚t.¥0ºbÏ‘º¢±d·v-æ€KÀ;Já´‘ëP‹Aø»Å"Áßè%äð¸HHO_}=Ê+¥Më°{oÜQà Æª¿™a=–%eôýÖª ¢w?]IäîT4 7ݾ´h33ÏVêÞ&ñæT3Õµ,Ù M±õ5j²5 E‹/6DËÆ} êch`jò†VIÄÎàT@¾\R²(ègÿÝ>‡s†Íìe>‹¿’Â{nnî¼EªV‡ð+]àn½liV%› mÃN —›¤x…¿ZlÌIN 2:î’Òm>çú¯Ú¬4Ú*P ÄI’s,R¥ÁÃ]€$öÓÈ'[¢mƯÞjŠg¢Ô2í­(}î ×,f¯•YIãÝÃ:娵ôÅ®bT,y«†xr åNUðrÁŸ fDc‡·Ðj‘rK{Ãú !ð«\í61¡ÅcñïK®„‘ÀÑ—R¦>½(!zÐ?€lË­•pP ¾Í2ãôjQß9ú˜@!EËø¢DýÍÜ–¬&´¨ë9E3Âë5!‘‰e1¶!µ‹²y<²`j4é_>ÆÄW¥D'àftX=UÖÿ|ÛÅPUlý¬­Gð÷«Ûÿ®‚þ]§šzñrž*¸¡"TI‘E¨h—´”àÝ¢‘Ý´hg. ×4vð/9ŽÑÙ±¤‹lð)œ ÉЙ½b\œÓ×G~Èó™¦9š“ˆ¡®v3ƒ½¬$=šÿ­·lÆ(4­i0©ûÓÜ^5°Ùï1w8;[Å-bÂ0Pc}íþ˸ý„>l#Mé㬹Ëzôá ó)ÔÁböZ%åóAôPû)ß(ú®[ÁúŒ»b˜SÃùÖžV)àu©wAµÞh”'&Ÿã+¯£±M¢ÜBê ¿õÁ/ÕÀ¼ÉöfaZª<ßæ%V¬ž´ëb8ŠA×+O4°’Äm¯Ðó‚¨÷ŽÈLÚ•ËÅím&m%qßAë9DZ¸Ð¥þ™±öl˜Ã}eSŒhÕsdçºqƒ„™Ç(:üNåÊš\~yõ¾<¤ÙEXëng*r†óqS‘M×w¼-­o ÜÏÉMLvšÂ%Ÿê,ž˜Õ]nOHä7åÓSì&ï(“FÙ*Œ§›wHm䙼bˆ ëð8ÿ²çÏË£ 'k³ç›1­L8_A…>áŠvp1¬ªu­iÔ9AÅ÷Rœ„’ ОÂÈÀn“µ:)?|Ü= º­HlOÉ~M·QúŸJnÆýâôŠ"Çe^51¡ôÛ•¥ôˆD†Ó^¥{÷ùvCâaAýü!Ñô×VW‰.)>O'ØûU˧w±eÔõ«_ýÔ=²Í¬…é½8íË”ºYÚô-%ž)¹õ?‹2å#Äq­1Õ»SÀЊ­Nåä›ì¤Ê h/ÀS…ïSµ$‡_Mãºï„иŽJ.ðoÉÄ.Ç‘H-ûd~bÒö„ê¯WÏL­çQúqõ­ÄÊ]’Y] óQU)h/ *gé§A·@ØÑ÷ Q=Ù£á½Zø*>ä1XÕUßU©w4ÚMúabœ¿=)¦\›¨ù@áE&À[D{Ÿ[têE1×x½ M¡„£ÉãB¤&vIA{}ɨüØ?òXcçR&YØÜ„*3cµ,;S˜©fKnLXӌȊeL§KSü,‘Ó.ýï)•òýX©"pnüÁúþµ¾îÛžU1¨ÙVv¥~UŸXÐßs$gúaÄ9Ò³¤Çnï¿ã½Hú1™ÐÈžùº)ïæãÙ=d†Ôõš³¹~~,Ä!OΔ¯ ¡ÃJúbŒ…’Y›Ÿ8gƒÄh5•.ı.ׯ‡Å2F™1˜$’«©š2yx°6Ãò7%ë~t @Ü&)HÊûh?HuÕgOÀ^(¦!ÚéX]ÐäWL.C{_zÑäÅ@Þ#›(ÈôE˜O¼ê ÓD€cßä Ú!}±~#Ý®S²N[€­ùáãjR”^bÿçnx)\æI% á’ë†)†°sµ‰,(³÷zÌS‘)åãø§I²%?õÇ:.©M9ø˜² xaPÊe6éÔvàHÒ#ޭȶ{›Ciq{a î_æ7KbËͤ\Þâ?MÃòõ¬Î±Iž9ˆSïfâúó’Í¢qÖcU…D”R&ºP8ÐÌÉq‘púÛS¦™¾ì­§Ó@K¹¥í2y4,à nzñ~†ŠùÝB‡âw¡8²X7Õ…VËÆ¶ê ÿ/HñÛ‡8ž4ŸŒ[½‰;[ ]άT ¼HŠ¢oŒRUÚ÷q§X ‘ôö}‘÷S·‡¨õ`Yœød2¦ÐyÔ¾õ\¼Ã1?a#ò£uÄT!šÃZG=Q’›ü×Î]ÐÖc›9/±§dÒœ…i¬¬ õZ§¯‘6’4Lv+åÆË È/¾{Vsü¡æ;¥5Þ‹ÉÙ“÷°KqÐ@-Âú¥˜UJð¹;ÑÓn ïŽéU/"%ó<ÄÝ{ŸÉÖéFq+£¿ ªÎòêžëÍxì¯÷ŸQg›a+q%²½[ƒFe$™Mí%¸³År@]CÆ"pI“:%?0F»X¸_¥fÌN1¶Î®HŒ¹\Y2¾{Íï!"¹´èÊ­6fB®“»Åõè¤ÑO0–0¿Hú^˜4WíagUv;Ö—FñIôüzçõYˆØýÂè`²ËÁ¬€óÈ5è”CPWžà¾2‰ssFHâzS汕˳ŒÍ¤ }<.ëÙiµD{ä\Ì£º9! özד!î0в÷V;Ö&Ké¯(MœV}îüøQècL“ÈÒÎ3ïAT‹ëêןÌ&Ê'g®çÅVÆ´FÚÞùÊy¢tc¬óºøÒ-yfgA‘zTz¼ì®øŽ-:y@ƒ¥±ÿ\¸"•?PVÏWÕE†È3Ê lDK\$UÔw¬>rß©Dè%<»ÕìÚW”åv\ÏÓŒ ø¿€§Jœ‹ê¸RdÉ¢‹È7Ûv:î.íÜñQ;–/±˜¡ŸƒåDá¢'·]°çew7¾QÅ A}Ü[®L¼«#²GŽ_aâÍ¿KH¤ŸŸ‰‚h ¼ª»,_&½òîoy£pB7vKŽ£¬NhÄO1û_¦¾¶®rD™91Üð)ÍÞºsùTAÍöæ÷Ý¥éëc5?Í‚ÒÚ.îçþy;4Ûú/¡üà"€ps°óòñxeç…¤üqq=endstream endobj 1338 0 obj << /Type /Font /Subtype /Type1 /Encoding 3111 0 R /FirstChar 33 /LastChar 125 /Widths 3122 0 R /BaseFont /DQFIJY+NimbusMonL-Regu /FontDescriptor 1336 0 R >> endobj 1336 0 obj << /Ascent 625 /CapHeight 557 /Descent -147 /FontName /DQFIJY+NimbusMonL-Regu /ItalicAngle 0 /StemV 41 /XHeight 426 /FontBBox [-12 -237 650 811] /Flags 4 /CharSet (/exclam/quotedbl/numbersign/dollar/percent/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/underscore/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright) /FontFile 1337 0 R >> endobj 3122 0 obj [600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ] endobj 1264 0 obj << /Length1 1620 /Length2 20276 /Length3 532 /Length 21185 /Filter /FlateDecode >> stream xÚ¬ºeTÛo—.Œ»» ww-w+.‚KpwwwwŠSÜÝÝŠ»Cq(Ò·ÿçygæ¬9çÓ9ó!Y¿{˵åÚûN²V¨)”Õ˜ÄÌìM€Röv`&6fV~€†ª–²±±È^žIllø+æB¢¦–pƒAöv’Æ` ?@ hšØÙl|||HÔ {'…%@ûƒŽñ¿$ÿ˜L<þCó×Ódaøü÷Áhcï` ´ÿ…ø¿vT`K ÀdH()ëÈ(Jh¥5Ò@; Óß"”]Ll@¦y)ÐÎH0·wØüû0µ·3ýSš3ó_,1g€1ÀÙh úët7:ü£b8lAÎΟ g€…“±øoÀö©‹Ù? ü•›Ûÿ+!'û¿¶uÁ”íÁΦN 0àoTeI©ç ¶4ÿÛôW °7ÿkifoêòOIÿÒý…ù«ƒìœ` ;øŸX&@€ÈÙÁÆØãoì¿`N ¥áâ ²³ø¯ N@ c'3 ³ó_˜¿Øÿtç¿êü/Õ;8ØxüËÛþ_Vÿ™ì ´1gFbcÿÓü7¶È‰åŸQ‘±3·°±þ[næâð:W Ó¿DûÏÌÐýMÂØÌÞÎÆ`4GbQ´ÿ  ý¿c™ùŽäÿŠÿGþ¡÷ÿÜÿÎÑÿ²Äÿ¯ûüß¡¥\llmÿrüÇüsÉ€Lÿ7sc[ÇÿÉá¿[jÿ¥*ÐÂÅÆØé¿«ÿ /fgñ—&>f®KAÎR w ™2lj 07¶ùÛ«É5ìÌ€N6 ;à_NÿÕN+ëÓ©[‚L­íþi>׿U@;³ÿžþ_šþ•<‹’Š”˜œ4Ãÿ~¯þËNù/ÿ`u àÿ¢¥`oöŸ‡PÄÅíÝ^Ll<¬&V®¿k÷wñø8Ù|þÿÄö_gc°È ËÊÌÊÊøûþ¯ÿ:éÿ7˜/v¦öfÿLŒØØÎìïý§àµ©‹“Ó_nÿµ÷‹þó¿Ætš"­-Û› [¥ge€ëðó†'%uû{Ù ‡CÊÕ‹ ýkì{üÒÃwøªŒÞjC˜›¦ù?Ú<–ÎÞdéG{ñlhzRW$>Tt}…˜›Ÿ;xY ÊP3ε¢½®å·a¾q³jîNª¨”¾Á‘Nwp8!\?ÑùS¹úã|zt@ó5MkˆÃíÄh‚Àª+:;ÿœtòôH3862<ÔsÛw@̇H-à ƒú9Êß1—Xä›Få—êæç­IõQl¤îÑ=A‹7ÑœvªbІ·’ïåÀOíØý¡†ÀaœÄ´¨Ö¾Š u“ö¯É¥Ñ‹_̸Ø­Äm÷=æ£þ–<[- m³œXGm[ÐÀÏWŽØì»öÚµ²N¹Ôïcu»ù~w¹.ÄÄáPaÝÒ©î+Tçó^þtÕÄ?ÒeKA]$›@¼Íë&)Ŭdn”!fHý Êh$† ×2IÕÊq¥Ð|úÂ@ Î<"1:’ý‚’·j0ø {ŽÌwJ‰vyÄ[s¬m\ôƒ!;þaÃ÷S2 Âq˳OsBb¨\òÈØìðÍøeXq—w5¡FbF¤}NÐôêx?”÷Ûaÿ”u–‡Yc2ÌŽÍ:û!}•º ík'µ¬Xò= ñ”^…9I¼YcO7À£ý™$<Áøc÷®ñ dI¸¡8Þ…ö(j[+·¾yùŽKyXà`§±ñcó'{™zEEû94ÈË3ý”üGŸ<[¼Þ¤ÉtLk ƒLËë¢Ê!7_ÎqùjëŠVU©d&ÀY·Ó©ÍõEãU$¤ ËÖ§ï·µøŸà¶[ ‚P¶üs/IM 7ÃùžF/Ë…X¡èšªó)XI– áxD¿Ÿ‹œ-ÙFæŠÔ¢]Í­ª"‹@'ú¬<«ÊZ³Ó­‘á«i>Ì$økÍÚ#4R{×Ö2YÊŒÔY‚CÇ Ìià+>Úãæ_Eû™:6?šÜÏBͤP„Y °cˆÄD/éØfí5~'jiÒ´pó{±¨öŸO@ˆ°YVŸ­÷ƒ›Œ0䨋<¹vb­åµ/åF™ò‰vóèßQJ§°¤¤ÃGj)+~øu9Q:šÚZC ä'®«\ibŽmê†Ý¾çK ~ÇÀ±ø©@èºs¸"d–…Ê_ ÎÜxÓô©¡Ø¨€ÎÉgH }y“ÆÂwÔýÕ€ÚV—¿m\žÑ.K¾Ú[Æ“µ†EggßÓ8¾øS 4$>^L˜mÞ0v†ò¼g¦®ý@`kËœ*³ÕÔÅZònHQ÷Ï î±b€W´+ü0‹| aº¿Æ`ú‹Mógª/«z<²¸çŒ®´Ì`­uÆi?Ñ!­S˜joú5“þhñGlEÚ›ˆêO‚O)Ö΂‘&´ST·ÁÆ¿N0)…»nwü¼aºRð¯4Û8ÙàÓÝ–ÍÐýmλ5{x’?{ÇJI]qгY<‹¹Ôêúë8”êeYÒâãô€R”_ýÝ{"B¡¤ gGRM¡¤\³©î5ú}Ä'_@n™9J<›òr3ܯ»ODg½ö˜‰ûƶ5Ác˜x{×D“a·Xâ{0Ž¥Ö‚GÃQÿ®ßÊ_2ÄÌ·PÄ@AK•ƒ™?­uøî'z»›¬èúƒ:È&ù6àGÊ| ¹®lf.ê¥6up?:N+ç4ÓÌ@*þGB°Ëëì…ùS¯²‚T}ñ¢Åˆ®D¥ÕÅÓÆ=ðÕ댖¡ÃêÇ#Ýš¸<—Ü@ÿš„¾æ[©§›øƒ¿„Tßg1®]-Í&¡ø=Õ¾í—ì{m*$<ñ—å{vm’f&?ê<èü]þX‡;åi¥\H$O¦œ;½âwÞξ<'ç³Ú8¢“²X‰ÝØäaî ‚‡áSØ&ÏгõBØÐ ||~½/QA›G"š>òÕCB¹I%­3»Pæè&AnÁTúÏ’>ïfNéªp¦ªçü)»óVÓ!© Û~JÉE¦¤x`j²Ër#(ÈÚi‘F¶»† Kàs±TjìÇ`¼#'•õð‹¾>GŸdM§í©•búMp‚\N:†¤éçär E^ÞË\CvþjsFÆËú— ™]‹\ä¬"¥°,Äë鬄-¢ÏCæ¯Ü‘•œó"y‰€ã¡2ÃÏð"­H¼¹ØJõÌ‹eéÓ:”¸GŠÃC¼çFê]¯Ð—ìÃà ^îÚ¸¤ 68‰Ð®*¢ã^È>“’€ÒFòóLeÚ“/¦—ÑXŠVGg¢išÜèøêuÙ]uBBÁ’þb¥[Œü› ÒÁcyÄ7çM©ÂA³$«3ŒNè~ì$†±§èYi›«©íQ`ÝQ§‰û8ù"¡÷Œý(C&Í2è[J› ®a0ÃÒZ6AO*O}m€¢Ðª¶²—eÍDk¯F¨·¿ôèT±å|:S¡#mÅ8D8êJgjy6aÌSUŒ¶îþ[{Äó)~iîò–­tDÄïµÀß[ïšc_{€?j-l‚PV+¹y)¥yjj®O©òìßUJ]ÜE rŒ¸;W5îÃ3;&)Srö#„aÂüâÆëÿž.“¾íäQ",€í¤€¬]ØÊx©—Óòg®ÙþÓ¬;X×€ˆCß(?ˆN¡A¾ò{ñš¥ÅŸã§T7*±(ÌJø &ƒ=SŸˆù®¬ ,|ò7.`×â7[wõfgoÛ»T†”¦¦¹Px«ºÒçï=eŒÈŽ]—NÐcÁ¢[’nÏ®ÊñÇ•‡9þ¬–F[ø, "oz Åomóß¿‚´ŠÏí¦£uÅ+Æ Î1xÀ&uäŸT§n§Dn¿…rζݫ‹‡Aç~¶ P5e¬"׊´•ƒž+»åźYÖ×Ü Q¡§‚¶Ã'c=gaÏ¿§¸«y{ÑÉ>7Ãý È"ÐzNäKFÓüœ6¿\°w¬úšdÛ†F“®CÙ£çuçô}¡—Z˜%*\tñå#†VÊ|ÒŒdTþ3ƒfF1w”€©ô ÐTk„!ÛxæœZ¢ñýÛwÖè5ïRþMé´gåkÛŠª1FÆáŸ£øWµÃ‡ üÒg_paÅüeâ…E¸Ã¿-j ¾ [jŠFX-4*L¨´Ô‡™\Ó3X‹±îdQpî_OueyÎzøP]AÃkî*”ÍŽ¯@\ nî¶±râPx& *+ù‘†ÏœS5OÇbîÊéµÛÄö4ÃHËÓ=œ XkñcŒÍ 6ôýiè¥=ù@h¡²À›å?Æß–Ö¡xà”áD, 7LŒØŸŠZÝßÝ3ãU|:£>W§.Ì@)¢óß+™¿f˜R:8G†Î S£Õ èm·£t;„§Ù¼ÜºDö’¤7[~ÚYWyˆG²|2NeÄ],ø:­ÈàzÂsß±>í(¤Û©õe-yTýc÷´ìç 6bdä 'éLŠÄ· Ž QúÕ—ìÕ—-ã §=p(t/‰ýð¸E‡$#êmŸ,»A=,Y.Äf¬ ƒ2/ܵöéì|”Š$2¤dz©~ ig|`fâákíD8&à냂s3ù¢r‚Hב\‹÷Ý!Â\t€†Tº³š³UE¸gŸswêÃ͉i4B"Wøn©¯ÁòØèÅ&§î×)—ƒ-¹¥/N¤ru:Gs/Rå+?\)*¤cgU7¡Ô>µd7S=]ükVÝHìöž@NÕOeé«nK{T¸ ¿_ú Õ ìîôu:ÒdêyÒ>úýEíŽ|d G#•²’¤0ðÕô¨«å¤¤ò¡%R£ò~5^7Yj>Ú'] 8Ë E2ëÇ‹Z{_*8õ0 ÆÙ½¡–DÀ!n‹ÓZ;ÏLE¾Ù'ëËdö5Èc™ K² :Y›R¸|xWÔb»fl²« ÜJÖ³Y &U‡Fpc_Þãò^t»U§øÄÕP`§¡ú .nŽA)ÈåXëÞÕ™ºV9GY%Û ºÜ'%•…ÓÛù]bwr5Å«~Ca†ã†…±`4„ÊÉ6‘Ý.¤MY¼d?wi"h˜[¸fòíU+JE¹‘A*ð4¹X>@‰vÞÈG ‹J Þ@náŽ|XDeÜñèÓq\§"GcØYÛÛB’I¨èbд$éY^¶E;ÍÇ/i:‘ñ¶{–íž '>ôM®nØÛ¿ÚÂXkZÜš»?n0ºq3tø'F%|¹ô­zAzI݆ezlæbšÉ-óëŒNÖ;¯BçÇ”üXV«JÁ3IÅ«?î±EÏÓÚ +)í­tâÕøgVÒQ²4'6¨49^=¡àƒÓI×I™¶eÕ?) ³ÿ¦Ú6›Ãžlóà½ÛÁªšÃ[¨ßã.»]‰P.qkÒ|×i‘'|DŒìÔ>”‡åv_éÒ­ÛTÕ´,,ù4<׆qýÏ×l!BÈÚ}'¦S©£¡xŒoo±ûvO!ÈÁ;Znf¢e `M{ÑÃéŽNø˜Š'¢v'!õ2ÚVX»ñãrŽˆ<´) “½£36Ê|G~áçÇ~—KÌ¢ca•âAÒ|h¥òIínÈyöú<›î^ÇR"LÝÞæO'›óG.°Êê\pÌÌ Ò±/»ã²óuW2~ìèf.ÊzafSñ};†å7¡o¦œëÂ\¡FU,Ë¡£ùë˵ÖÍ­_Ó‡z²obIX{·³ˆO‡ž»û?Lên­c&£!ÉÇRÍV©,XìÛý™“‰®l+ãÅ]•èšç,SŸw3*^Nšc7lßp¬¼¢°ãÈ©eÝÎÀýç[0k5‡Nñá¿Åÿ((ªFáû€o5ùœì^B}ÿ°ŽÍS—­9ts@ð/Ø•i 6å|ÁOf•ãpUù¾ îj# |W¯‚xµh€#lÚø·Å9ñÞo'ó<;c Ž´ŸQĪA0Ú»m´— í¬qRRh¢h~¼m)µÞj,ò€´Ë©€íD :q{¤*»+ŒÒÍOÅ7§jûö®öÜ®û­vj¦{g'…t²PLuté§«±¾Æ8qD÷¶|ËÈÓ¸µŸg9›DÐéB< ñUÆyÊ c*¡HÓjIzr&aÁÊœ»æÈÖ­þ–36r*c©Œ»èfݢׯß}ˆÞ ºu„¢HxÑb§<<6J#+õrŽZ<ðý9 ²bÞ9/Oß¿âÐüèŽfÛ3IE.øËEyfX­%uAÍ÷A#™“³~‹8d´TMÀÍIYoÇÔ Â´MãÚÏB;äšóÒS.~J|ÿvѼ[ÎSTýÚîŒO 8zÞËZB…‘8#jô£µ¬ 4·. ÀcãÖ¶¶üž•ìpø°Vd‡>k,þ\ç@ð÷"P!V`[YAŽù½Ë4zmjL¦‚/âAÒlØöùvYà× ©f¸ÃT3¼Gs€µ/E~ a³)6¡òúly¼NÑQ2ð0úI`Z€ ^NH`?&¯É3dÐ7&"âæ\BÏä]†öÐè®9Ÿ’Ñ!Ìx²(©ÉSu$*àvÉÿjÈð«’`œÃGm‡^EéâöÍiVžÇ̘‚¨qÄ0i*&جñä¤ÛµçZƒ`Óõ:VÔóÁÎ[h}×Î8xòöZù´Ú &7ÉÚeÏŸÿ‰%^O(÷eâÑpaC쀦&v}Þ4£n’­9 Áwé}W¯4½}ƒµÜþ®ÝZI xˆ¬¦^ÝôDtYï÷&ÎÛm§ o}ŠÚIDo—(AÊ–Ö9ÝŠï•^Ö|¸€Ma öï:’¬ß—ñJ¡7šiÍsxu}ú¶ªHUà€,ú•+ÏÄýµèþ,8k5';“VjM—¨'QðK`K#*×IÄmCqꌚÆÃÌlßJá–U§}Ǿò$§ ¹i1-c K”ULƒU¢žNŸ²Ü~SAQ©,Ä×O‡£Ì$®i\¯¡•PÐZSFjTºrf5šÙØFG”Ñ™ô5¸u(Ç3òû­Gª§ ý-î–eçñ!Tz¨/$y¥'>á=Å :¡€TC‚e, ðpÈ=kÇÔ‹‹îz,ÇšIÌu|/õìµÛ­ÓÀ'Š/è²¶Z$Ä«¤V9ýi\t¿fgïUžš®–@R¯¬ŸžxR,ê-„DH5 ü€g)k.¨d&V]ÁîA¡µv&¦;6ašoyÿüVó°cc\ƒ A2øÖË.—¦yú²þ4|å]¦“È=q°ÜÅÛ2‰ Es$/ØðñÇô×<¾Çs£LÚ½@¹¦^Åä†Fšd.*‰°³š¬8ÿ][\rd¥_±gÿ®0þã”+-çÅêIdú“{ÕF dÇ«nÑÞ£¦Õ!˜'¢„7øòAm†‘Ù?ãS^Ÿá”D“—†fèN(n`’|Ö3¯¬µX7Ã0΢´ë9ÑÅ Œ¬aœ† Lü—‹ëZ,Ÿ?=£~’¿ðâ¦a¤ªS»¿Å©mNíÒ'Rš(,&¾½n…ª:?¯ìíb‡ÁW%èÆ÷#()†«mÛàJ“•иJÔÞR°b¯Ü™Xä\³¶WéP\ŽÃÕ¤MBMŽr\BÛÀ_¼_D ç¾ÿŠºj#/ðG7tshã‚“ÎbC‘u­ç´g‘?„ª¢ŠYXd’güèg„'X üœ ª,r@’h 6‰<–€_×§í}_Ö= ‘þQU˜í”TßÊ0d‘x‰( “Þ“ =ÒqþdÇÓÛ «!õ2cnKŸÑ@?zÿ°?Y›¢tñ7õBÕv¼imä—ƒ-LiNÁ_u±ÅÉ »]'=IÖOå½þü 4ÚK;Âa&žáôâij”ü  Î™_œšFÉ©¸‡œÖX`Ö•s?5®¨+í/—ˆ‚ë´ÒÃ3BK“c|a}#.0GXä¬ù§õ¼Ì©à!ì½b¦?vÊοoDž—UÊ}óßNœÿ¹¬©rök ¶ì¾AÈkˆ4ѦÜÄ4ým ý)½…Yî=Uí†ò¡¹ÙÞ–y³¯lÄîÉÛ GG] Y*iB~B$ßf&øÞû…þèU­ï S‹Ú„"©Î y’p ÁøÐ°¶qýë3,-Ô1ò£igšç§…F˜+Q?¹ÁœGuüÔT¼6é&.—¥ Ot²![¿yZÙ%n–j¢k†j¢Áxƒ ‚J74ñL~ ù¥,}L^úyòé Uüã¥=“NãJŽw¥c>œ>avºÛïJT;MìÒá¼D ÛÄ×_åàDßÀ:KÏÒЮkÉß½m|討åªå¬þšnáKðŽG4HÒF쌽TÆå6H†H÷Û™á£1¨î8ÂKe l M òg½Ümˆ4×Ã|C#ÛŠO©åù#¤øžàO†²,zDïthñéû¸j‰0y\S:’ÄE¹S>«uƒ(‚AÛ…NJ1ܾ\³ü¹×ÛŽoQRE(ÞÃBa`Ö*Ä^_@k«cqƒy‹]_žá8ª,ˆ ãrf{Ä;¦ÍéL˜?/+>}?q“¬KÙÅxƒBr¡®ka”b"oÊ^ÞCDó´[UêÖz‡ïtÝiI ïsÑý-Ã+í±NGAðÀm±’‹?úþRf÷ì×^JÝŒçÏÉSEI¯â Èst›d\¡r¼\CÊOPK!…u eMTnÉ…R\lË6ÑÛù±Ê@¿G›íÜÇénø=w7¾ÓÆ Ñ’©®kW4'‘ÁÿG<)í3Ç–â—úïOÈ·WEÄbg.éµXf°ñkvx ÿBl[p©úÝb1BîÜKµó8$ÎxÓ ÒåPL+¦T§Žì÷¦W?0:àõÂw WÚmo(_9rIˆ|Íoâ3Ûé›uºÛ ŸìÍõþZ†Ž2çü%ùGú·C‰Áóç%cc…j©$þu„â*^Fâ‰ÑH…Fó»îéFIÝXûl÷žÊ¬B\¶cìV”Y~ÃûWAör€Èf v æÈ•ËmÎSOûºng´¾Å=UË]§=£M³¯q™Û¤µM|¥»g&_ 2‹¿[>Ô~íþStÌu†3~ôK\Òú1ýÛ¢x\­kÊ@!¡- Ä–V/[‘/MèFíO¤–+>Ã8úa‘^ˆ¯«(ËFã“Åü¯&_°ò] NóI¿‚I§¸'LÂÕ«çããv\݈ JÊe+%s‰´ˆ{X㲑+Æbo•ÇåfýÇ'LÓ¸ øâ[_+Æ,eÎ( ùô…„ôN`|•S ÛòÛîv¡ëEFîý¼vrchì9uºªºùaúôq$,Ö{×öÜÌ,œÞÞ²?bœ<¶ŸqÃ9Iõ‡ên¥Ý-ÛFÅñÂÜôbBcoš£°3»:>fDT#ŒH¥…ZÚ"/£*Ýd(r.þ<ÊÌòX`¯õ`Ët¥bÃR{÷Rk“ü=ÞaºTºf°˜&ü¨¾z3‚y|/šA?§Ùîv?3.¡ÿs°*a€m~Ù¥å ü,mô±TqU ké¯Á$)O“)æN؉¥h}8S°“÷‹Ž·è#‡ÃÖ º½Ôœ¹¢ÇšíÙ6êÖ1z×Z5øJl^½jÍœwâû¾ƒ”‡¬ü|F†ö“SQ,§ ÚÃqøÃɶyGóæîGõ¼½‡Ž1ägÅùþKyú¡å "s-Bµ°Ç$,¿bÖÕydÙ@Ž¡¤ú‘ŵ‡jI®òNÆHm‚j’Aeq•"éš«d?¬Ïö˜Å;7“Ï˴ί­k¨4O\ã7Ù_­EªÌ v¹.~ºöu Ö‚{ 3ví2+Éê3E†0|Ÿ‹Wçíì÷ÑÜGL®ÞV;ž¹ŸÃpâICŠ8 råì59#°ÙdôLضCÅØ¦ø¥E/aI«àÍÃTh쵚%"†i³öôÙe>`)'S­æÆÞ’YSí¸3>4«~$i™¹®VÅ+[´äWL‹seï‚/]¸lb…TÙ~û¢„àÅRÆ@cwûÉÙÍ|aÁæX|Ñ{N¯˜•xî܃±¨Ý RŒû™pB,4±Ðqæi˜•÷-Z.¶÷ä‡ãý1Þ¯Ã@ òìãïùk9íäEO_üøÞv#¨GÚål›ò}™y/¥#|a˜¼Igµ–Ž¥‰ù óî#î¹ß²BJ*ô0¦Ðc¬”™ Ÿº¸ %‚o;ª vkH¢ß…е/¦Œw—Ï¿ŒTHÀÕå‘I r]S*ŸéKÝO\ðK½´lcÊ”aÝI¾õ%¥}„øÔöÒ† šŠr0ô¤µVGYÕgÉ u—8Mh¥˜xÇʈT¡ÌÝ*ˆ U=Ø»bÙHšðØ”6ª¥¿a5}ªL¯Œüº=‚¼½c3|6ù¶nÉ7oû/â€A®¿ÜJ¸Ü¬È¯1vJÔœ7-¥'±]üSN>÷á¶š„'®<«zNzëꥲ|d”øå¼¥UœjšüU{ñ°´5%êÚØzŒ'ÙëU£÷þO#^κ³—?…$Rao…JK¡+…d÷¡jŸ—Q}‰ñu§W­²>1ÀP”¦ÁVJ-’[:Afo.Ë_kfù¶tâôîË•ƒêÜÍ)µ”E ŽÃ“"›Ï†_eÝs[ãº1íYé§Ãëà%ß¿ ¢Jš—ñÍã…†Å_ âÍ5£_F¶Å]£·Ÿ2…¨&˜©Î KÍ;7ÈÞì_¥QÉG©Ã)ÛM¹À¢¿¾—1ÚãåÙ"©øyWè°V"ððr·~¥OIÍôÉ›‚c2–}áEmJìÐ&­„ò?» …’>/“dr { uó÷Xù¹ÜtDè3m*Ïñ.~&B0¶‰É àe»hÈ‹Á—¼ L‰ö$ä©äŽ´toÊTS9¨p‰Èˆô;á”Zü@iV±—i}À{X›°æ¯k–‘ækz$m Âí ½ã?" CÐZéÕ€Ý*QùÃîï(“L|"k+„^êucÕ‰I·Wß}}€ïƒŠÅ†Tq©^2×F„ ÐP¿¨Gή1I½=8©Rö3vú e-Æ•‡yBÔ«Bßž¨ÊŸ(êÌDo=f(XÐ-+ù£];$’–ŽeY¶+SUýgþÌ0½oü6†¸—ôP‡ÃµjkÖk“{öêo™âxÚeXž<qª›¯SÁ«‰­Ïç;¯…Ã`Æ~ù©Ùކ„dõ®«\.ó¹»-ª#ØÌK þ§ãnÚ'싪ÛĈ#ž”Úõc ¯5èŠ ¼I-‚ƒ¸†F%Úze<"ÊóZÚÙçÂÁ¾‹€9~·PJû¬¢1ë"šØ‚qC͉ <™"iX ´èý ÁñŸ£¼ëužE,½þœ†í%Ã<³þµ]J--[”¾0±“ǤÔÀ÷O­jP5’œ•ˆUÚ:Å5ßàuTE~nœCí^–{E²È?§œ~¯w¯…ñ;ð'Õßø#ç©§ªD˜Ù fŽ~vïš§à¶é·J}±­I’­!‰ VZ¯Â ðTiê‚Û|Oë“¶FRäM\¾kd=C÷Ó²êØ‡ (W¯#è?¥ã¿z@ÕÌ`XP#'Žo“d *¯A—‚yŸÙÓ®–£F.,D°FY ÍÈk€Ó:޶Âï ž?ìºK#Gæ% Á”T&«Á<¶’…®ÉWê·Êè‹aÎÄTKC÷œƒãÔ¹+ª¦ö~m¢>–ÙtAwøèÐÓy(åö„~,9RE‹mAŠ›Y•šMÌGÃ…ªD¥<8߉h­{Rw|¶$ôûzæ’Ð餌Ën$Àl•å—{òòYœBiÂ8_wŒáA dy¥¯ ºÞªQ§6p¦ÈZi\–§§ÄÔ0ì¹'7—ÁˆúÂ[ôß($rŸ.MLóIë=S¼„ì×}·¸Q¨Þ¸ž£c: äÄ_z{(Ë2ß|È Þ¦û Eú®á³xÂ`/8ǵ5Ð"þ˜¸ªQFËÅ:d «Ÿïáèy@úø‰l£À/ ÿ`̺¹¨Ùs>LÌ%®_ˆÜœ½kñB“ø(…wüX€ÑÖŒ $RM÷B« W¼óÆã1»0Rh]ãƒÛÊz~®V|‘´‚AHÛKðHwI³=”&÷ Ý;Î{n×ÝNÑâ³"Ù2dXs T¦F83m#ÕzÖ,–ë%áÏy˜=ö¶¶ªeÀ’³sñ+é“sï)~i¯ƒÍ?#ÌÈ܈MWèò‹Ê¡Ä‘.þ ß¼Jª9–ÒÎzî•üfÿc—e Ça$v8ýûLün0b ípÑM¿¶épÈbß„îÁauyå~à|ë\†CÄ^÷éºô>µpˆa§Ï;ë3žh?„ŒqV€V4ZÑ@Ù'¨í¶F½X¦-¤Ÿ—‘‚'åãÈY€|Î ÞH2®Y®²§((`»²4–ñjz$þSÄâý0zIp‹“wõšð®?Ë/¨ðƒÂâް©N$ë?±·én¿± Æ/Ãr;xik¾áüp&Þi T`Ìѵ鹩€VåEØ!IÁš—œI·~¢ ½³PÕªf72t\üY+&´°V•(kD{ƒãS¢ÐbE¾BïÏS€Šw½ká•)Í7ì9XÙOZ¤¶9çl¤§ÎûC_ n¦j”@·iegœtÌÊi4à(ypè±ð´zK€CKÍH¿Â³ì0$§JvI 3½øö9Ã6:aæ9ÈÍs®îÏÒhŸ<ç€i$ƒR7^ëiÁþ•U”:©aÕ@JBãûgø´²´´=€óÃq®Ön޽0ŒjâRB“á ŠÁH€AÛ7`Ẻ·$›Y]x¢xéâ/vÍã•wEÚ³ H†¾½-b]6K¶I$åN¡3¥a ÿ³¿8§uT͘ž^ºÄí§ lpžìb“äÕa½þmÌU›Èhˆ 56¼ü?þ(ÕE°ö:2ýÛåëû¹*7É»‡û;Íæã­‹BÓšã)÷åux÷çº#,µçÍÍëqO¶Æ üÃv>xê_2-›iD—9°g&*£Á)•NZú%h‰ ½ã—Qò“Á¨•ÙCäÙ¡ø¬÷R¬F9ŽŠš©ÍþÊ”ŸHçßyDÞqAav7õ¢–¤Jô°ÂäwÈÊPÊØry+ëöîåÞý ¬¸¦%&I”;ú̽lB–ˆŽ÷8·¶¾’>¬ac—HµïÎÄ/Yêõš°$í¡¶îvþœ&j®çW8½«Ä¸ô i‚/KÉ3·|´úªã‰JÊ"±n %ÚIаÔ®Èî“9¼ñÇ#¹u¢4[²Ï±×ྨ>»á»Ê|;#ò¶ŒJé*¿‡ì¤o”cˆ!k?yœŸ$‰ôÅùaÖƒ»‘?¸åÞ¼Y[ÑXP‰ã*ƒwt´^‹ÅÐèyµ»ÏÕ~ix‡ºÀí*~U£ÎC­ý ÝCFhìS’çg¤ØX! 1&Æ ŠH~Í­Ü´÷¢?AJ‘µêòrÚ-ìƒfêOºQÔoó冎®¬ñ`t÷[qÈlÎ,`>Ú+ÒÌŒ§ ͪ—D@Õ¢lÛÖs"mãªÛif5 Û&ù—)ÖEAfË)Ÿè~€Çw–&µS6ÜÇÀ¤kÇZ|gÓ £¾€ 2’t²:,F.\úÔáùXÇÒ^_ÙrÜHoøìæØÖBŸ¹x›ÇüÚ+Iõø“ǘ@T´Á¾Nþ„¼m»=;|@€ŒKQa=qØ>úÆ—ª€ä†{gîÇÁït ª7/òœÙõÀóϾ4±·ÝÏf¶ B¹\–7”NuéÂy¥Ó!°®»þo“Ej5³Óz´Ä9B µ1©„óJ“f(íVµYÝø4éð½ÕסúBI+oº&ñY9€§Uç‚D¼z šÿÞï2ŒT"é†\•ÊÚN\ø/,ƒÔz"n2ƒ¸ˆ`‹Xcw{ÛÇ©Œ£ÁÔNó¡ oûþ¾ý ††lt”~Òèì®MöIŒ+½A×jôw+ýõIaÏÈ‘I}~ŒxQÚ!ç8 ‘lm:ÏŠD%ÁrŽM´Òd†ã¼w±÷.}cG?öݧÝyަò‘¡U¶ñÕA½ëÝË¿¿™ q«Ihõ„Y:z¯À(Ká­b€Nì×à;]Aˆ¡U†H×#ÁDÚ/ø|ÒLGš/wKBaQ¦ƒ.¾L„ýd›àEuÍ2êžZêtBâ÷ ræøº«êóøëÝ(jŽÙ$ìä'˜ï²”ÜÀôP>íÉyÞ¥ l”¼öU\è'#È8Á|Bþ]Ñõ 9iÞÛÎUF¬[ìk«Ññ˜J]âL·Å…ʾ»U7€¨‰g\aX]°˜(lšs¡JĞء­gÍoäQÏì/ž?Ÿ?ÉT…3d• =’w•0‡ýæ @¹•~A|?L¯FŒoü¡„ ?å_Š{³eˆ¶<‘”À&ð5;5ZÕ²îô{[v©\´/=D‚ŒûÃ%Ãóë.ž€dÅvM*þ_N˜Ö×Úf¿y&sµ ñß|@åù*R:H®ü˜3 J‘• pk´ÏE cŸ7ÝÊ$ï¹&–Tœ•ÄâÄ5ué‡ÇEE¼=p~¾n^äbòáÏpˆÚk=Q(ÝÑ/PXáLP›;tc¸æãu™S* %-ýÛ8L'pÊéäjŠHÆZ”^WOj@:‰ó¤S/Œ*\B‹Šá…“£ÊÛhžpÁF<8{²{&o¥o²ºéÒñiËfE¼§"/áé‹]·4VJ`§0A+ÙÐÖ›fbzâØ“ “g5w{È‘ŸÙÁ&°‡þÓ"±œmÝŠY¨æ][—Hq;xº}p?áÏø}´£{ñùa CN.‚j2qìf®d [AHôªœ @‚¶xËMëzßæ©Qþ`?Í_†ªŠéBx»ðË§Š¾oà®d× ‚æMY,†IÕ½’æâf±5¼¯Q'CMˇP™Ûü>ñìø ¼æ¯Ø†ãz$Nö/Ü ì¤åh[ ¹un"c  ~ÆW!~ýnþtÏ-é´è!­l@mcšµCKš¾©of}ü‹†œœâaR\ÛnÿPp‚zœ¼O*Å~h—ŒÕbŒéëSÆdèÉØYM•1J·,ß©¬°UKÏþ½ªÒ"¨¶!Ç´Ô6æ±¹½ÈPü5 Øvï=hƒš¯çÑú` ηÆú·&Ä©Sý(æ«8Ýæõ2 ƒa-ÙcµÉPûANMEMìIŠ-§à Er¾´:§–=—&3© üþdõ± •À‘w>÷±’c%à"é$¸ìªC¯qlJ•fM—#ÌRN:èÒ/ÂOV8Ë Mÿ£ªÏÌ4x8OÞgªþ^•©„OÏä°æJöØ;ûÅöRõà[ùh¥à!œr‰òFóì4§Ίs$®¦ŒÚѲAA3uèÙα/ ã"WøcþÞOæûø[4§Ö ×r¿(6¸Ôèü© ¾UõœÎll‚u–õ,žÍra‡jÚ¸­T `„W.Íêö!ºídnÛußPÒß­§\àS‰m>^¶Djž¥Êz‹ç½Ë:¥<9À^¬ù¤?S¯$ÌÑæ™B½Èá“ëô¼nU«æ¹Š¢ÖbÀÆ»3»:TDP¶b9!_¶ôq ¢hÊÇCø^ÕL¾=ãyLðßës[|}B=Ænçòã0K˜’ÿäï8ŸÌ!ùfþɵ!é;B•ÁàY¿nMó¨ü…G¦XŒu¯>¯Ü)ü™pHm%Ê.`K0w`#ǧ)89ͺåMþÄßAjƒ™¢†H馤öÓÖÒ²™ÃÁ÷®×³\ŸÆz7ñ1–>g‰[ß³&ß$ÕæòÉB¦ nÖ; ®³örjŽ{¤ÀŒš*\°@$ûÒjHAÇ _ Á‘¯›ÞlènFˆ™À+íeúíȸæn/Ó¬ÁÖN—Î[]>?ƒŒ¸º_í" 'ýFjÛ\YŒ?iNïd–H~à ‚õiÔÆé×KàÒL VZ„´—ÅGáÆêÑ*–bâJc´æ®·7ÁáÊ}¯Ša)+îÍ 84õ÷A«½"r7™ønpÉ%+º4kÖýb~Ï™ù­]©tÓß$)l’rD’¸Òä€6Îcúb属y ƨÔp‡D‡$¡(<êîÁÉwxk«ÊÒÌé4ºnªj û—ôNˆ8£C2J2£=#iº$à"³@KH-®Á1ÐZß‚›k"p†kLœ¸ ¹A@1¥~œŠªErâýPÈ€Þ¤”åPÆ—‡c#'¬¯"q2 òxó±wê©Û‡Öá /BBIIwwÛ}hー‰Zo×6R¼vUGr”«³gr¬±Ù#yÙ¦xÀs¸«ÐNTÞÑ´É-cõ—ähm`šÉ×–ÜDNŬÈL6×þ Vîã䮟ˆZÌ~Æc±:B-DzÈCy™7Uù›{Ÿ*‚=Ç“Šo0ðê7ʰ𡿠û„VMówØÅ¡B]œ±¥}òk]‰Uö.MKn?÷ –}0ÐHɬ•5ˆkz5RmB,µÝ£ãÀJ ¤o"1 …á_uÃ5Y)¶½·úRÎè]Žÿþã}ÍÐÔëхŒҒîDÓÉ4Wk-e:JnÜèCxä'ý]ß´oÿB}^4 “tzæuA^kÿÁ ÊZiQTcv>}¥.aí#;ëô1‚.\É+‰û^ÚƒW”Ô¨åòüo’—îﱤS..5Çec€u*hZÛðI¹ÅàfêõENáè~ƹ$ò(#^¢Žòsä¦ÛѨ,>äÆÏ…ó­ßùqæƒ ïL4Q€ÏÇÄMrÖnŠ`i¶hñHTÝ^g¯ow–ÓËЈØg[˼ؙ…#e?ªƒ³ÅØUñhI©°}¹¾æ¾o4Š&ê[K±ÝP®ŠnÀá1 “S·jå[óf9X7ý¾ùku3 èG²6áç›[çWiŒ‹¨²–«ká÷͉?Ñï÷Ôì–”%J&×+pêapïEgð{„,­dyÁ²K”óÇ%q°Ù¹hؘ€z_ÖЩ¹Xh˜¥£d?¤¿ß”"J'’®Øœ¿€ö’™iàC¥'mðÛ4¤ÝÊÔ8sþX³‹÷wäoEÕªúϬ._|”~V÷¡ýìÓbäÞ§æø@¥óÈ®˜ÙŸÈ*­µí„†jU4nÚQ-ÓO&p~z‹aøÖFàù²J“E¥so(£2<‘#Ù &¨RgüŽEÀ¶Y%ä!‰A‘=Å/A»ÜÄó<5¯SS4¯§€ïám9‚(Ñ7.ƒ•X’ýRt²!&ŸW]uŸ”[‰fŠ;ñU٭뵩bq;’iæ«?lìÉIË¿h¾rÆï‘:ù‡àªxS|J´we)Ö–DOGãìùZW˜2[È ›H3 e¦K¥_ÂëîÒFöå ëd¦èÌ.uFò…ŒñcèNíÚ‰¦Ø,i^¬n_Y¤Š!ƒ!ÅÛ~ªÔ@#H1Úë{á`ÒW†×åüMJ›·ÆP…?ãÆEAû迨ñùšºZ,ÿ¾3jê´ÝŠÃD,‚gy¢¯ù²öeo¹¶£$1¼÷+Å >8ù}âŒv>ÚìÆ <àÜûCTÉü€9Ÿsx±©°Œ\Þào7àã}&uµ¯¿ïÅàãÎûM†¢R<÷Ö êˆY%oe>“À:íœbfA¥znÎÍ,Á//· QÑ= LôÛJ§†‚OTkÚMΛ:ÒaW½°„‹;‰¢Æ1ùæ3âXɼS›‹Ðû0Œš,Ù„6Ão5Üã´^³ò >•Rš©’@)äª%-™ ~r~îx× U­ŒYØ1+&Ô›…%I‘\ [Gš#䜀ŒÄæÊÉ0¬oœ¬Ö›*Lg‚HWÒ‹¨êLräÄréõã z&Ù&¬!RíßV0ëŒÎ†æÃšàôcVŽJTJÁÊwiÚD¹rÆøCÚÀz8B¨ÑÀIéý&èëïÜ‚mˆW¨~F&fª8§vvŸM“$)\é  ’2ÞËþšé‡²=8e—Sò%Iq8 ³öIZ1»‡zg{<îžœ<Êkn×ЀPº NüXçŒÆòìQ6§À!h·EôD=nû3ÓzP8³úV>ð§öôoîE[ñ*ÆrETÆ£%ÏIïð æŽfêê¼À£¬D5]c…ÃŸÆ Ã9Å‚vžÞ_Ûc7IPµJ!à3ã‚9…;q|×"µ—u|q >ŸœcľEÞõ?cŸQotçr Óôç?,¼„ÍWuœÍÔUùØ`ç?k­±#ðÁŽfFĨ¼4½yùT[ó¡HTÿÜ-tð¡¸Ù÷/.ò;›2q8‘T]3»%U­œy'¿-E¢-|»÷»Gg‚+£•àmº£€§·„I_.Ýòµ°«;®GÎȆΨF¤öþU=Ê6…ËoÞ èÖ>®ÿ‘~‘M-ÐcÆŒ©ïÔôQ0Øi‹¿5q4¢z×>MíXÆzø®cñ»A2µæMÌp]úD¿Gà'’VèEbÎryOÔ®ù1Ͷ}-³x“ÇBÍãDîa›Óo hÆ`:«1¸¡Ò²ÛDì?ßãp,×l´]”’2W †_([¥¸1:ô8‘(šÔ<cgà­LÆÍx Ø¼\œôvgj±¿,0NµÿDjƒmòÁ1ƒ©8|Çù%:. Fèƒl—1jØ:mãXñ¥wñ€B±I…øy}xøÑäA¢ú®×Ï·1މB*ðt˜¸ó=àBøñ"aÈc‚ÁÂ/\}G¿ºáTR S6ýþSÈ%èó±ÛVªïzb¬Œ%â¹R¶mHÚ°Q/¥­Š*~ø€¨ìQÂΠQΔÛ8Óƒf=Ê5Ú[¼ÿÉ,±.î"ªFÍÔ„ oÈ4°{­¥Ð~xÔÙ½Ò4×$¯¯f;}‡!ýÿÚ©ë8ÆãêtwÌ0=Æä™<ŽM›î¾“³Ãi¦»»™Ãén¦™înÓ3Lçóý¾¿=¯çó¼üˆdÖ™3;ó?Õ{÷Æý‚,=O†Ù)¤"ï¾Ä…ƒŠMɈ£Qk#ä;¹åóµ¨-M}u£Íh©«oÌn n>ÅS åNÏ`‘3¿Ï~Ûö—pû—k›ñ ÅT¡£‘å;n‰ì;0§²Œ_Ï_¦U4‚y,ÿ„ч¾+|›Ã¤©3H6éÏŠÞð̆H‰ Ï•fˆ*‘ ÿ(˜’’¼}&Il ˜¤JŽÑ“~šçRåAþõ•à*œÒ„o­F¸Ú@röÔ,uö9_>#¹9J³£BT ²´iSGS稪Vü·¶I)pž2—pM™{žeõRoJ4t9ÞR†äó£k§cÓðËÍF ðØ]|÷ï¿ìypëÀ¤YƤO‹ó°*Šü–†u”6¨guÐq‡FÒ½CZ0> ŽŸ®ê Ç‹ÅPýhñ 9îíÜ:w‡MUl>ú"sWoxDç§±´câLÑÜ*¹Ôkžá[:§ÿãK‡¸uµÕE–~¨È­^ÄÆ«¿°‡Î†w­Ï‘­QêŽG~ý”& ]¹£@_ïìk¢Œ¾’ÌÐDN¶[(-V0\?«X~øŠ[éR¡Œ‘¬iAøüº ®Ølbkf•J÷q±‹íÉ%ÂÄÅfä2ÔÖÜÖ‰¨SX¢r ¶Ì@ ®Ï;}N&ÅÊý »úÝå½ãòÜè¡­¦ :â}¬‚Ã%é¦Áüá„´”¨fÎá%}ši¸ùÕXjpWTiÇ ³+’ÚMB÷×XS°Š:ÆÔÒññ ‚8&Ï›­7$)W¶.­_úÈHßN×MZ ‰.ºÇNÂÖ;€+w£+íÊÖФå‹ìS•wŒƒŒHÈ“£ÖÜÝ4½Þ|… àO;‹\¥€•©-¨,Õ­Ïn¢äšLvì¢Ã*“¿%@}â»ê¡kãÅ—OÕá•ÎwçV!΃„²WqZæÞ'CìCØ_6†$, foFƒ|µ{·ßb-‰öXU¥‰T„3ðè9Üś暰ypUè¢YŠ«c ‡yžßF'IÔ?¢PH6“F ˜ýƒuÑ3Q¹i`ÕÄ’?1&¿`«?t­xÖÑ`Ó°þ“Ý 1ò„MÖaꬋ權ûªuÏ“8ÌjŽD (ä>_úïIÚÜÌËwXR¬é;-.¶ž3ŒÖ“Ì(½T¡VÉ‹¶Pž Ç7·h};¦³f-ë¨)À}”jµÓª…ž¯l¢VE¼ä´1_%E¦â—ÐGÕ46oEbq­`Î0g‚˜Ú"M-Ϊ‡à‹úlÄç^!Mœ‘·yàWú»Èµ…v¢ñh+°¶tn1˜$>ÑÒ+ª#/¤0ê6ÎòL[Ô¡¼l¥9Þ %ð rj¸ É—¬œ´î¨{ëÆA{&h0²«ôŽþšÒ€P?\'ÅãÚõdE±Vê?¶Í‘cÈð^ãáÌÂuþbim–1è)è£I39¢ûi›“„ Ø@¢ý+óØcª™•§_¥ä ±ºßñ$습SÚ¿ï7Î0üñ¯Áìâ’¨0`ãÅöx*‘†ýikôo^œÜ=ã)sJ„¼,KLbÉN’ƒ‚ÌÃèv*ãA”ž(sc#Ô'p´˜%y‡‘°E³/»yXïyÔÓì7¯ÇùJð˜3¾vqH½¶%*O´Ó –ó8I3(WUù©ålXÕ¨ÛD'²7ñqDñ@Ì í;÷s…¾ß‚¨ð%%*ÞWÕ7·&†WWØÃT½,4<ýëæ¦R›þ|‘ƒK§žd?¤ÜÐ}× „ÈÈyÓ±Gøš¨XéEõcé²µ³ ÜX^lÞ±Öè1Çœ»sVt0؃“Á?Ù0®üËÂ-ñ¢º2ëðøêœ ‰aªß°AV'"mÃG—!Ox( Âk÷pºGœ€Ë¯ªÜQ¶mø†Ý0kÁšµ¥è¯×åÉ ¼ßÿòHÜ£)pb+½B_À§Ëÿî¢äÛžçÓ@BÜ|Ì¡DTv¾G(†Û‚™Âщ¡³‹ç)ÊâðDÍ/2z“KÊý6ÁnIwTø‚G­F[kM‰´d³å(=k㊥(€ÇYTé6_$¾£}@å¬ÂÁ]`f©»Žî;u¤fÒ)Oçe’Cªü¤_…÷|ð·ž5—ù—øÃÀ¶ùï“tÂóxô¶|ë =,‹K?Ä©;¡TÁA›U¯Ç0ð<ÿIÚéq(¾ïŒš æ”ñn¾'ì…HzVÔ<°8Ä/kõ÷g0˜¿¹ÎyŸÿéèNIT4Ìéb’èÆ÷¼‘mõ‡~ü@OÚÚÌ'öÙº¾Šéâ1 1ÂTö` ‹Ëú'3m­Ä!\q̱ú.*f@ï@”„”!—ÜQ ¦ìù £›ndÓâÕ•êñÂëþv£ˆC}Ôr>µpT²ÐqõÙ”œ€ê"´ßYñ1ŠýË»;QMW¡<ø…}2£L÷^„ê :ŠÑÄ=äÀc]²Û yó¯kòË~aúèXqé¸$(zÕ¨å(Ÿ¦®ðCþÚÙŸýÙèVwe?Òf=+¸oIþŽÜ*%ä@Ý{LÊ7Êø@/#8ì&Ý[‘hÞ²·L5Ý-E}&WYû–è=¹(Zw'tŸåSäjJÀ¶-­RâcB…yVì˜è¨HnÅ_YnU*§âÆ–äÔ`©ªOäÝ,žëðEH*(ù>^p#½w8~ÕHÒ|La¥°þª”ð”ôšš½—';¼mœÓÄаìû¾gYò ò§åý&|aA¥MYöÅš¿±Õ`”Àë7ÜV¦a+4&£ÎŒ“‰QÔ#½¸rúÙYSvá±­ y,ì­+gPFÜcÞä‚=[¶úxÊ€>4ã‰C# ÈÔñÑ YL«Žª{>8†B®ÁíOWõÕ¶žÙÖ±Áû¯Ëü6‚*-òâ"æi»ùhûDFjÕÙ²½Õ÷ßk²Bå¾Cò¨G,öÉ]çY8B9ìØµ´êC`^ôâë;½fµ=’Ñχ4¼ºZ#]ºptÙ¸eº¸iˆÍÚj„>UÂl#ŒLw^dÊÄS3:'åùÐ1VmhËߢå•zjLµ“ ï%5¤€­¹‚sÉÅãq%™Î—¥ïBÝh-M(CæQ›'$gT]~ˆv5lNc7*¼™?í-ŽœJÀ¹×_pqšüÕ_¨Óu°CƒnÈý±~ˆVåÖ?ëdØ[ ü§D¡íß[β˜(À«ÒãËkOŒß´‡x˜5ìê  ÙÃxÚ7:ñkFÕÂäÉþhŽrüÕ:*‚´w‚ÎÏQë’¾Á¨ÒÎxBï^Ÿ€{ AÚØè”›×WÖ²¼(1-“hð=¼1·æ.­ÄLú’檎Žw&áúÛX§‹øù(¿ã1µá7þ=ä(ûÊ TÇfÂäí¬¿µ1‹­u&)@õ„®“Ç­¿GH•Ùhš3RõüJÍéÆ7,ýñŒªˆt÷³@6Ñåáp+xH²ñ+/Êýg° ÷LŸ^ŽãpÞÔ¾¿ûùá!^ýlŸ'Å}—qŽ Wé'¼÷0àuçæÛîsrL´2øv4AüN ƒñåôBWö°6Þ %˜\)²¾ë[Htwfï=<˜ÿDcãªí‘s‰àäPÐrõE}ó‘q¯‰|þ¦ªøùПß÷1AÇ8°Mòº·Wôø˜"î-ê%±™WÞ rÞhŸMˆ©…ë38Ùœ.FG¤¨íh»îä–Ê‹‚ÉÀ1· ô›¾5÷…r„”„rU%¶[5TÀ vuñi xµÀ"ƒõä—Z%9aËå:3ÝóçRä­+pwëè{ã¾U ^œD†Ò‡9t…û qHøáÉŒ#–.l!y`ŸíàJt—_ ²ÏœÅÿùÇšuE鬱þ:Ú ã^Ê·ç>g,š‘Äìi&^u{ët§´uɃÛ+EÞ s0{^ÚÞ÷Њ?c"^¡~mFáLÈñð¤&>¡|ïæ•·ÛØý»è›UÈänô¬ûõˆÃé#ØÔ0T~hÿE\4O`tÒ»~g'õÈѦ£˜Œ–”Ó“6—è’KbTQjpL)%›kÒïÌu¢ÐÙ'‘5ñ½;æÁà‚•*i/d_qÙ=c/ ýû/ìsU[ó¶nò€»ûCÓÒÛ²ýÖ¥ÜJ V!Ò²¸t‰ÆˆýjÂI¹•õ(ÀRç£éYå”(‘.„UõÀÆ´Œÿ‹ûêÅL֖ТH^PG#zæ™ÀÓjã» •oùcµ¤‘b7Œ'´ÄSnôVã¸u( àªíZ*wKš#ì'ûÛ´Š€íža—=ßýtëHùÏßåòê…´·©¥Ÿáª‡uQÌ5ߺqk¸@ÐI%ók«c§²‚¥,äÖ|«lËK™4w†Œ¦~ª ZirÎ?>¶ÑÞ÷üJoŠ÷~¨Ì wé—cšë++cV;Á"Su²$`³tB™5‹ÁàV1`Ú ƒ¢¦ë(¦‘!šõòÇ<ÙÙŒöv‚žV§H`ޜԈG êáÿ-ü¤¶é›µQ­íº"6tÁY8î¦ÎáÔÃM%U>£  Un$4Ï¿»K²/óê=¤JVófËÕÂøó9†û5v~rVa1}êq:OM1ÇoWLlà<Ç"–(Þ y2WfreD­|{ÄQE¡á`|I¹™\tóq²6¿¨OÞ“Ÿ0ºîWD M³»‚‹bñŒKKv£¤ÅW,ÎÅÔ£SÕ·™ëŽ&è<ÚvP+‚ÿ(x^,@l¡WórÚ”)qfX½¦ù ©|yûÃÐÁÀijáý©ÿÝváWòÞÁ€¶OWÀÉ¿‘ÖLê»zŒWÏcƒ6zÀÀšV(;°Š‘~mQàÈÉê@Ìï». @‰Ú‡›Î€æÿt ªOð®Ýúxôq AÐe¾·,P* ÑNÞ'õÒ»>ÎD=`ø‹ÖwñØ|»§'zš´i޹·ÿƒ¡[ïûnšPšóŠñºÚ·‡]LÇð°uÙë¬eŸöLq JpsÁF[ 2³BÿðªíÜHuøAPÝ,#!òs73 f þùwä‘;gS¾Oµ¼†9 u~’¦$oü›$”äTŸè9üU|xþÌìŸË0nü·-[¹ê+Âí ’iû‘^’þù^©s¹þb,î¸õôPÉSibÄi!_.º°"羚h˜×86hùf¼L¥Qæ67i®ôƒ¯÷êá°lŒoãXh½ÆÕQºÚ2ïÆ—¤Lè4ßš«þºRö¥¼µSo´œ5I¬B¥êÊtð }µS àÛØ,½M @Чþ>ê<[–4¨ç¼lÎ*_Ò‚ê |š°xBñ»• ‹š8/åÙ }J‚*é+ÅÓ¹ÚãeüZü_6U¸“•…烸þŽžK¯ª¡¢ÇPwÚ|¢ýU ×±Žü0Z,Uñsê'è;µóbÅh"b²VÅÁ* ØM†;¿”ðÆ‚¶0a°°lPŸŠHr}ITMº§¥Wk]DSnHµµH*ÊÓ¡:œjCNqúú]&8oB]¾¤¨ÇÝ—Ðn7= ¼«ÿF·Ç0X£d(Êêµ6Rã`ÜNÄɳl‰Ùxcá¼¹Å?°¯ùSŽ'y†·ý ”Nð‘J£ÃPtû<üáÆbá½(×$]:òrn&°ÕEx6”±&Ô=ž)F]é6«b‰`ÌÏ•ôE¥Ä°*éh½–t@L ØQ¾Ì¹ˆ}lKЬý÷B¦Ûy4pËÇÉ4àìOÔi· ‹â¿:ñþÿîÿ€ÿ Àò ÔÜÙæ`îlû¬ìAendstream endobj 1265 0 obj << /Type /Font /Subtype /Type1 /Encoding 3111 0 R /FirstChar 2 /LastChar 151 /Widths 3123 0 R /BaseFont /OQFAKG+URWPalladioL-Ital /FontDescriptor 1263 0 R >> endobj 1263 0 obj << /Ascent 722 /CapHeight 693 /Descent -261 /FontName /OQFAKG+URWPalladioL-Ital /ItalicAngle -9.5 /StemV 78 /XHeight 482 /FontBBox [-170 -305 1010 941] /Flags 4 /CharSet (/fi/fl/numbersign/parenleft/parenright/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/A/B/C/D/E/F/G/H/I/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/a/b/c/d/e/f/g/h/i/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/emdash) /FontFile 1264 0 R >> endobj 3123 0 obj [528 545 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 500 0 0 0 0 333 333 0 0 250 333 250 296 500 500 500 500 500 500 500 500 500 500 250 0 0 0 0 0 0 722 611 667 778 611 556 722 778 333 0 667 556 944 778 778 611 778 667 556 611 778 722 944 722 667 667 0 0 0 0 0 0 444 463 407 500 389 278 500 500 278 0 444 278 778 556 444 500 463 389 389 333 556 500 722 500 500 444 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 1000 ] endobj 1121 0 obj << /Length1 1630 /Length2 16214 /Length3 532 /Length 17112 /Filter /FlateDecode >> stream xÚ¬¹eTœm“-Œ»kðÆÝ‚{pwׯ¥qwwwBpwwwwn‚÷/Ïûž™9kÎùu¾ùÕ÷U»jW]µë®^½š’TI•QÄÌÁÄ\ÒÁÄÈÊÄÂPWÑT2¶µ56:È1ª8Øþš9()ÅœÍA@{qc9@ÓÜ nn `c°òòò"PÄ=–V Í_Zzz†ÿ²üã0ñüäo¤ ÐÒ@õ÷ÁÍÜÖÁÑÎÜô—âÿ9PÕܲ2XmÍbŠJÚ2 R)u€”¹½¹³±-@ÉÕÄh ššÛ»˜Ó,œ¶ÿ>LìÍ€ÿ\Í…é/—ˆ Ààâhn üfîajîøÄp4w¶º¸ü}]–ÎÆö ¿=9€ö¦¶®fÿð×náð¯‚þzØýÅþ’)9¸€\LŽ À߬Jâ’ÿ®de ú'· ð/ p°øëiæ`êúÏ•þ…ý¥ù‹‚Œö.¹èŸ\&æ3 ‹£­±çßÜÉÿ*ÃÕhoù_0œÍ-ÍlÍ]\þÒüåþ§;ÿuOÀÿv{cGG[ÏE;üËë?k‚\Ìm-˜XÙþæ4ýÍm ´G`þgTdì-¬,ÿ¶›¹:þæfîü¯Ñü33´‹06s°·õ˜™[ 0+8€þ¦Ðü¿©Ìô?'òÿ€Äÿ#ÿÈûÿOÜÿ®Ñÿöÿÿ}Ÿÿ;µ¤«­­‚±ù¿‚ÿ±cr€–Œýÿáml´õü¿ùÿwOMóù¥‘ÿm…ˆ½å_9y™8xXxÿ ]$æfJ@©ÀÂØöo¯þeW·73w¶Ú›ÿÕô_í0²²°ü7LÍ hjcÿOó9ÿ ™Û›ý÷úÿÊô¯ê™5Ô44DEéÿ½Ê¨jûw¾ Y¹¸ÿ¡ôw@jžŽæ€ÿ•NSÞÁì?ÿð‰Š:x¼Y¹¸Œl<ì_@6V/»ïÿ%÷¿ˆXÿë,o rztY˜XXXÿ’þóÉòOîÿ4ôÿ„½©ƒÙ?³£ 2¶7û;nÿiø6uuvþ«ò¿6ÀßëÿÇù_ƒonîanа¾â`Êb‘ ªÃÍ™×èc… u,mT+* ¨qèõψØå­4z« ejšáûh÷\>s|?üFw4Ö‡cKÝ›f~ùЗœ¶¿ý'U'7ýQ³A)ræ¹fŒ÷Õ’Ü”‹ÆÑÞ”²ŠAÉ ÑL'»3ÜÕ#m¹[aŃ#ŠŸizC<¬úQt©Æ7áh,rç"ò k{µß8t¯O/;¥ºˆof±ú%¬”&íxÕ)FáöW“ñ¹äÀ õ HU¡¯DRË…WéÆù£]ëjA°Ò\ù*2̘Hƒc»c.7Û¢9ØÉîá!F†–¡ÍÕgélr¯¸’jU ®NÁÓ SÌTœ±Hi~|ŒÕwÛk¶qš‡~¹6c¶³#Å'X‡óæ…~kÝ|aÌÙjXÕ•lbñm6 ŠEÙ§ß5À:éÒYÁïPýߊj¨·×})“Þ‹¤Ð/¼h2«2ºc#}?è\¨a—îŽÿ’¿ÿ[CìB>+Üâ²Õ4k:àJV¾³/?㉤Ÿ0r$±—gF”·ž9Ë&LJuª¯k^3?×ê:d‚Á„$ì¨wWê]%*²1œ!ü18¯«|ö …s~ÄÉéÑ pcž¼-VÁuM/lTœ³wb?†^¯Zs?[Ü%ÁJ8´™ÝÆÖ.çWÊB#ûc5ÛbM#0Ûë˜Þ*giIK‰¸k‡„ƒe:o«1{rúË$Švß/£Ç´-â¼!Ä’DÅüÖT¦劗ïœý¾úfÓ!Ql£øz¡¶ããŠ-㵡²Áî8}uM#Eë}:ÛÀ£>Éôpå"º¥b¸)ã9« ‡ØRŠÿ>7@ÿyXõCu\.è ŒºÌQé¶™°6\Ç­êÔ’BZTt9äæ®¢%Ès3)#÷¥ûûÓÄ_J£ö •úŒ>kš´"ú(ߵ쬆ÿþ7Ö!ˆAÎv†8¼\L-E©»>æLk9­ûwÙX@è[šIË fó¤ZyuÌLt5åæ B›ñwO)ã—–C¾’âì·Ÿ¾³W°Ïì [š‹ÅC|”IÙj‘Ñåͱ,#7Ùò5D;q0QÑ℺$G›xú4oYµÚ13È@dL¨ÊGü’ðœ;ŒQîÞò—ÕBÕÄ’Üâ)EM_©™ˆúzwÊp^‹”·Þmùn|a„¨=$RWƒúåË®fç±k¨CRÃKxlþŽ,H˜ò3ñý÷V(Íôn:sþ]'-£’¶\ýPkaIÊõ2PŒNã¬?×Èe? ZºÜŽ•'BûÆ$ªÞÇãf׿¼0 4È5Z×ð¸³g»ÊXJ1#$jÓ«5e?2Å%I¦SàÆb­Û«.ò^*Wí4ÜXý"÷Ð*µ£d9àF–$uY»Ï?‹³éìSxïaµY-¢¡€Ñ_{â©b]Ø}*‘¸§lþm-õ Ÿ¸,š=ǦqÔm'}ã’½ÈJ/W–‚ÑqÒkÐÀ xöJzÜRç¾R´I¥-¦n‘û iK¨xH6ušxÖésƒ7)Øë2~v ¬™fAù)KŸyHè„)Ô’D…,Ü/oÝEI[«t5ÉGsÉ»Ì~ÄÞîYL"â¶F,cð`Kñ3]õ³9udÏ£Cs´Ì!¨°>³“ÑÙLÙÓí0g€;ärž5EfªÌw§HD®nVdü/rp2˜©±dš¡Ïù¡ ´ì LcÓÒk„}xãM‡øATᳶǦšC ²ž­P£™5ðHL5È‘>gF¬•Ê9@PºMþåG-*£?ɦ±]¨ß$ ÙÂH<ðïôÕu=l²é‡M'8C÷Ñ6 `…«p•·9 SÐAÜ?ä…C+ÙBý°Ž%«5’k#4f%ã–Eòž`KR C”x£n©2^ çË„MçÈwS†q终y,˜6Ñ4ßÖÙÚÃI+®‘ïÒhâ%ÿô+cDzA` Ï!ø?(²*é0n²G¡¡æÒëQXNŠJ5ûºîŽÚ ñ$hÓäïc¡Ê¢ÑYÉÝ`¸q'uÿЪ/‚Ý´mÑøD“ ¯²v~¹°ùLÊ{BÝŒ¡øÃ6²–íìÑŽ&Í').Ý瘃‹¦#‚¦2̃ëŽâq'rôÛø]éºHô‚åóƒ'Î:­MØ,Cz) m>¸Zk¶Ó]«>ø:,ÙÀ%ÿšÅ) ©‚©%AØy´¼=€¬NX¦ÄvÙù'a-ŠSR¼èó6†o¡( †‹4ZQÒ&Æ“€'x_!Bå4 œQdÓžˆo¥j›*÷ú*yèõA®È›ŠØùÞ*9Ö¤û¸·ÂÃmÈŒ¿Åû ×táú9ÂÌ¿×jŒîuÊOà7¬ä'½£[»÷HsHs¢4xÅÈé ývÞh÷»&N™3ï²,ä¯òàÞ¼«»PøÛÖ……Ì\!nÊ—Iž‘Ýù™,dsa‹™2,ÉÜïéÏé›_Ôn8Zr烹ªv{ˆW1óLN¡¦‹JD¼¥"eéUMäãëj“µB‹ND·ó›^ÖåÓܦÙv‰çxD‹ú)MènÁ Œ;Õ×`xÞý¤ŒAhàI%Üú áG`¦‡SØÉň,ø,^‡QXÒ<5µ[OtÂ×{ù…Žö„F×Ï+N•W¾¤Tær U Œ€´q^¾tÆ^?Ø|%uÂŽ¯B_µ÷Åás-™^±`Ö¹Ðü|ñ.ù½„õœÏ¡-eýËÅÌ…£×ïO©èOÕRÁ]k¯þ)¿ÒÃú çøbU'þ÷˜ÀÁ±CŽÊ|Øo‹VÀ,÷QYáŽeƒTÅ€4ù`hõhÃÌ"ÎÕ ¾•Qÿfí2FZ Ys“^É2ç1›èŒ}´x•oøLÅ~êú¼Sr6Ã,f“Å$ÖÁ~¸!’Åu£Ã¾¹fu[¨½$|8GŠ XP&k©:Ä0[gIJõ„ç)C‘ ŒÄ«é3TûÂü‘ë8‹( Ù‚.àu6s v>ñ±=ei™t„à cþ9^O ÎbÔSfü….’ ËžŸÜxªÄ®»~dÿ|°ƒÝ{ú볩P¤ˆC{TÃÂb ~3˜˜ Ô¶q-ÖTkþWBµRè1 œ^Å}÷b"áŸÙ÷?'q ‰–Å/F?®ÊD¨%·ŽÐrm‡6ÓÃȈWw[ ØÊ.K.¼€–X¸¢¶ei—ùy¦ ÚI‰sÁÙÛ èFCëšˉ°Áº¬Âì§4{ô_ju5§qWb¡â:‚F®¹‘ £MQùžÑéÄ›—\Jo£c ÚSAЧÏñ`K¡ˆC%oÝ«ü°¢’N½`ž¾VDÚº‘´^álmÌb'OŠ žQS‚sxCþíº7pážÄ!Jà wF‘›UíG7íoY{º³ÕãbžÕ\Û."{Š~ï!x¹Î+~SÆeT•±ZЯÆ7 «ˆbÉ4‡\·L0xi_Ö\kµ¦äf´5¾~Œ"%î}…|ë ›ˆu61j&všQÌ/‚·bénx;Á8G̾ Xþ®qp…rÆm`‘ /Iï¨ë‚‘;ýR¨•å)’Ô`m ^f©>¬OÛÎ3[~½›ÍÄŠÜ?ëŠu×ö”.|Ðñb8‰àÿ´sÏ6Q‚"jWŽB‰ x¯°&ù.±óh|-ö¤² K¶ÉÉ6 N¿È¿ð.·ÐøSýAH×ú¤ÅÌÞ°—‘,ŠeV®D’R¹ÏÎ_ƒ¢‡):?¨\)Ì/ ásÆ#ûÝaØü¾C-(^Ÿ¼,•}3Ûð–VG¼:Žˆpöø ‡~fê"¡€«ËöDñqšû„\ãL={,Y6èsÓö&ÿRžéã ÎvøüÆ’ ©—2[<Â]*ŽUÍö~Fº*Äe¤A¬­âÒÐ{q÷¡Tjá¯r*DQ–Ðn8Ö±üÇ×^êî5 ¢Ú]KM¬dŒt¬êür–Ò›8»(B:ó1OCò£P^xž¶¼ƒ z¨V5]ª»r ‰&$_׉<%@v©Ç1‰4~å¢få¶_±Eû´½ó*`,ÇÂÍ“)‡D7^[#¨eNÄî]›Ä|ccÌ.g‰æRuõ~êP„¨ö­þ²øwâ¯Ú ¬9ˆÆo Dà{éøk JPÔ箫¾<àØ¡{ÒŽƒ£H ˆš9Û¾>,v§ßÚˆ37ïegiZØÃÎ’~92ïc¾q`¼„¹WËmÞ/ŸªÈ"Ëùtþù¡Î T¼ 1¨3(K$/U@ÔTÊ.5,6f!-ÌxFhÌÁó‚NnrÚzë¦wÇOïaóNô%0I[—Áƒ½ìê¯záíZpiøélò"`+Wüü‡Îù½(ü-]X7om_ìæž?Óo 褭c.Þ¥Ž: ÷tƒS3ÿ䤽0÷Ov¤u™g&¦qìI,Ù5Svú™¨ÿoxˆð9±¦Í¯1cüù.Ðe ' }Òß”ïˆ"Þˆæ#ÉoæW›Ÿî¦³ÄHM‚˜7/ —f2"ÏðGb iú_Câפ,øAµw˜1¹BÒ¦"S?‡EÿÑ0L‹²½ÜDCö2ÆÀ-ƒ€x¥!š™'O’¨O<—Ý®ÒaoõÒµwÏÔÖ¤;àkKˆêzäoqm‡šÒkï4³ã¥d··6@TS$T·ã²­×j2HÇ‘#úûƒ‡âi]¼¾_ØÑš#Tf£~:¹÷ 3²+þÓ ÃˆC5¢)„Yÿ^.»x·Që(Aä‡òIaèdFìß;ÓpÖÇÂ÷=r†m΢j{#¶VœNC°ÏB¼è‘÷ë—†£Z†V!’ÒòŠâYõ¤‹D¡T™ëœ7(8Ö&ÃÞ(ü‡*t]¯jTê_è¨Ôu/ýñNU:¦#ûPüLçß öÔ¬3§ C5«8N»,rÃ_=^U¢AºÊ7NåÆ4l[ÚÙrcw˜›%Ðo»ÆÕžÙú9ªR¤wã{EÕ[»\©_½zøtÏÎn• ‰ÚtP¶³ãh´¼OÄHççí".ëµ6¾ÚöW5ÔÞ‡ºd¨¦èmüq$:Yø ŸáG®o4± ÖQÓo$øµì;ÑbV!ûykAžÔ^¶ª¡/©ƒÁ7ÙÈS÷ƒœÔdíMèSAˆ2xî^vΨÊXdºo{g@½ËZǃ¤ÃMp¦|€…¤}øí«š%%™ŽŒt@¶²‚Ñ|¢^¦VÊ0CNãr§S=ËÀµjX(s'·ŸÃ,> fym¾{<õ(w/v•Úé`ö­AºhJ½ È’ ¹˜%AÇ©OOûØ+VÄ‹~{Hйl…¥mß,+?(òÖÜþòHaöjZ|êÕCJpL¹áïæw”­~½ØØÓ< ælSŒNà Ëù}ì3½ÿÚ»~¾-ÇÓ]–Í ÑÙÜôW3>Çz¶P\üõº"kw5·D (ÙüՅ'•±²ò±—gÊ1HðḶ Ýœœò*ãN_RÓýÈõ´Ùž®Svt¤/wpõL;AÔÑ8—šåÄx{K³íeS”Áñ9UMe›ŽˆÍ×ßÉ¥al‘Âèi×N~¾Î3±ÙpYbdÕŽðéa/å…8•H þÐeý%‚BÒØdÎö¬/~.¯mŒ“Óø5­ÝÑ„ßÓIÆk´í0ùX,ãHKKÙ©qä6ç¡•ø;~¿Éo Šœç”÷-mzË9é‹.òÕºû+Ó·œª7ÆÔ¹ D´!úÅA±´âë9œ¶a¤<Ïë­á_í°Á‚L=€@°ù¶NM¹•íô™gFNó®äìS!à{ù²gâA}*ßZ¬¾"L;¡!&{SºGÚõvÿáIt˜h<Êo`Ð W•˜÷¨º=áp¬ ]3#"ŒBŸtª”‚¥‡˜QðëÿDŸ°Xüù§—K`!6ïH©/ôyþËZ»ùc¥ÏÇÖ™„ÚÝ"ØÑ6Ølšä–ãNdn>‘W¨f4Ý…ÊðB÷=Iâ¹²ÞDŠ¡éóñL—eMåu/÷r5ÒÄØù?¶ßíž;> #ØŸ#J¬ïíýwÅ\á0NJ]þî\wL‰ËW) á«jû콪:‚ÄŒq˾t/eÖ’Ÿn…‡þàObë·¶tóÅ@Ý—†v9p%Z§ P4n¦khÛ%ý®äÇ=v±¯l8E45)ÂcŸfÕ‡³QùâïsÊ9 YbÜ„ƒlï^ë)ý—$ÕŽþ9%AÊf|(—À»‚††î^müu¹ƒŸŽC©¢p°°ð(3ïû{TªÓýᓘï,îÍÔ}»ŸÇ4¼ékv× Ð·5™\Å«ñNKå'®ÌhüMÁüúîVµü~¦@Œ1ÙYЯx¹éœI¶ä¹O¹˜ N‡6õqéà/ð¸7^–@€OÜslDåÓîjßËVS!V6U%áÇÔaDšò“£u»7Z3c‚8p€È3˜£Iº¾œˆ²#>‘¿ŒRý­Š˜–—œ-¤®ÐáZhOÑŒfuð4± wCóÀ:t²YÆ àé nرn¢YoIêŸ1Â4׋bƒ¤ôŽe&€Ü[;˜ ¤ÕŸüf$tÅùçS‚cMFÕkÔ•uDI/ç»i¯‹Í4z6Dù>º÷ÌvÿÙrè€}n,$Ôf:û6þâDÇ5[* ð[«ùLìâªXÈÏÌRTU…>  Ý#nñ ¶yO^éF½#ï{‰}xDqŸÚl¯tØv¥6"“µÂ ¦.}àwÄ êˆá³o£ÉɧɑD³¬ÛðY[¿[-‰æ¥˜t·ÀŒh,Ì"" õÅ‘¢³¦ƒíD)ª­ÂãX䯯Ð÷²'JA¿Ó€vðºæØ0Æxu·‘烢n6ŸÊìk¦Œg¾Söz¤Ó/•ïèÔ@2Uw¦‘J =œ?®ýüÈZ<ÞOÝ;¶= eöõ‹±ÙmÉâ¬<1ô°óÍŸ©/¢P{Ž“àoQÙ¶æ¥+¬Ü£éœç0ÆëTtSc›p;†;€¢P5¡L6ñTŠŽP6R\!E޹]|ß´±öÛ-û!Ð._‹7«¯„§XqZX«ƒ&RýýŠja `xä`° ¨§l¶q¬g.bòM{ÉÏDB=îôz†Ð/»a#³]õ«Ð©fô u' П/L$ý2.ŽmØ“ÏMQ_\¤ÊeᇆKÝ îùmœhntG* ßön7\¸¾\³ú¶}”òŠTGid%Ó~‘уõ­8ô³‰¯ÃúF¬Ú¸3’ÛC<š3kè[!Þ‘A߉´òñö”ý}Ùˆèñk}¼Raº·â¾\ü XƒÂé¨;ÖÑ8üš°2+±M7°9F±妧C)J§ÃSEÂÏäŽÈ koµ½:ÙfDkx6›Â³éd°©Cʺݥ‹¼qÞÜ'/vr£™lï®VnbÌßè}ZªÈ}A™à¶7àç1Û`…ñD1‹ÍÂ#å‹ÐÊW3â?ù‘_È1ãTiiš×—uRŽáŠÄBT•Âa•T˜4¦ßË !ôÿCÓ’G um§‡"DÑľºAb*m¾ao°ªLü%úwd¬•…Â7’‹P?PyX€L0_„ _… Q×G×züù²žxZ5„3&° S&áŠT›D«HÎÓMn@gl"º7÷qÔEÔÓÔ´´¥!e†j³7·_ßÛ* «4èÑ?jú9‘`¸âQ[è)µF¬j,>.¡ÿžByù˜únŸ‚)L©uwŽ6 f (ëI0r/*•6#ˆ,º¨YCYæÉ§àIfðcWζ{À`Œ" ίí+¸6¶qÔ…Æ*zcÑêZ ô, keFüŸÒùß×Щ?Ÿ•4oJ¬1½8â%1¯ Vå81BÖ ^†D51ÓK˜œ½;ÐOÓfk…-$=ÛBÆk^è®ß+c稲8Èœ$çdôšX¼"»²0;•Š;dBÌßעؒ¿½^t…R—rïû½§Yºn†ŠetdÔÖŒ+Á” -{ðð6·M¬Á‚>Úši±|óºqóòÑ95¥ãfaòþLÏpúŽLNïvù1ˆjf (Ƙ@·%|â9?ñÓZ,ñÀ¾ófWüˆDQLÝ(ˆèÊ~ÌAe6ÐbHLSºFV„®¦·Cýã„z¯;þ¾Øp¢1bêînßÑð ÿº£T7._\äîà±rÖ‚*Á,ËAÞŽ²b5< ‡¯ýç³:^Rµ§H Îì9:Fw(2Ý!RkË÷"*3wÀôE\Ä$lÏãéd_™JKGÔ†Ej \Äíuvü÷<ž~â¥èÆÆ²U*€?›–ß\\8 …îçVÉ»tÐæhG_%éVŠÏ‹ÀGOõRÛ6ßNtÔ£C©–'l§ÚV’ø d§'¬ö ¬Âõ=¹»+¢Ûžß›-°6Ç´mQ@hbQîÀ@¾<˜õJšBHçJÑ#ëµmVi¸×0®*YEáœÛ yÚ ÙÕU|eœ=DÝYW®œ]þF±‡S0±Ä£ šð $ædL½“†¾Evêömeæ)Àÿ½²/¤kg âF×@åà øþŸ¹<B[æ<ñä‡O Ðea½o¡3ËÈŽa!¼lÔNUšoqP©Y7+*ÎלãkiBÇuü ŸŽ¹o½% 4ñÆÚBypsá 4ô4%ÉaqúH`äï-QùT$ÌFÂÖ&Ï¡Þá´·çÅýWQemÎH50öϹõ²òsáPwÕO&d0WŸ½Ýí¤7H¶Xå͜ʕd¢»ÌE]HxÎó•ê#Ü]á*M1Hs}¨¼D°óôŠämgvX¾T ÒÇ™¼ïw±w9=rž„%É÷¿´á …ˆÛaçE„Ì|ÔÝîÄOÜå!ƒî8$á[¢ôbIe©93«•ìƒUëÔ8Ÿà% !U ÒRÓAšx®PöÔ™JØkóÇ×ng"¼Ð+7tF|…;þí|PvùçÆg/CD?Aæ`CFF9€”’Ò󮋇ùã9#H…Kà{p”¦§ó×XzƒÐhÃÆ§ ×´;{ØÉ…OÅY“óç"÷ ãÊÅF_ÕXƒÖw_¡ØKèJVDËXcïEhÛ‹Ô— –ÙR¡pŠÔ€V§éêÆÎ~'%œjeö¯´!ç˜ö: cf f(æ’"äËèÁØ\ûÖôùiÁ<„îvÔÏ:¥•F²,ÎÒ$£ÞzvbsÓÚqÂQ V-/°í-2vŃäƒHì£ ß¬«&ÍÀµÓ©ê^; çÞÇóó~ì/ŒŸ ðþh¿ÂÞ Á†ž^tW÷´]þ¿À·Õw2tIW1‹*íàNk-ûÈȯÃîoÕ8çâ•<ÿfZÑÛu1¤u“&LÑßÂZ*4|Qdù ˆêó½ë½Sý0z'D%4•cŠHÆ#Gmqu ÜFu7â¨pq³ì~zS•>¦…¶˜¢¥‡EíØ^þ®Hj×-Þˆ-11e ±%ɾYö^‰Á†ÚÍÝïx௰éý"ûcÑ®žêön=F8^£GônW?&L1wñWþ“—¾Í؆ŸÏêÆ€#§R·¼ÚR룸þæ EÚªVMo·Œ$yg@;”¦ñ4] „逵PØWJ]¥0îNÚ”}0ý?ÜwüÄ "¯RÊ*×Qú(­À4ö³)FO›’ ‚äêàþ(ÇÀN-ÅBÁÚc·}2«Õëé¢~ÒR¯ÛûÇDã]ÛÁ›75ÑâÛ?}’^¸Ã/T89B"j':up·ýÁÀËuŠwX¨ôN,[œZÕz¡jð^[éÐÒÊB¬ ?ùéˆ&µ_8èè¯\¿T~+¯þzF¹­õ ã+¹6sÕétäïøë÷’ç6é¢MLqý/V‰{k˜ÖtᎭ 5Â3r;þªOé‹-ò°Yüeå‰4Š\uÔ®¾O½ÜlMÀ¢€rº%bABõ΢8ò1âGÝð+kLiyûƒ7õ;3»à%h#üï[)ÍápµÄsÙHObgÐô»Ñ޹?§Çe×ĵ{ ì«þ&ÄqKZÖ¦ ¿ðÒ;qÛª47·‘)<´ 2‰Ç-Ò¸6,éó}›‰Êá]Â?…®ù6Çœb„5ÂxÀ ž^èvíÙœþÉ ã…~È’Õ*Epב~솳ŸP§Í!ðœÚ ^*ŽÒ¹\ÝMÙàvu¸2ÈL].ÍàE´”NDJösö–êä*\Ðqeùšß±œ²ƒ¯êrýrxÍ!¸ï%ծΟÖòÄͱœ·qšZ%ªæé»V7äÌ¿%þ_ÿVš*Ý\„ÊÒ$ǬÇ™Va ÖÃVáÙàYú#gXõÜ¿Œ²ÕÞ·èêµÁ),|d œ¢Û¶†ñ;îìSJh"¬t§?ßyiKYLÚ´pØŠG?'â{âÁ:ì&~&¨*Ir‰OŽŠÜô«þaÀäOÀÝ 0ØÔ››Uñ@t°'Âÿ}û¨ÃšA0IùúL{—p.ðZ¦{xyYOÛ–©Äï´+Ü sHuOŒ¨ÎU G£–@¬Èo`ñý"qà‘±îø•¢†>MÅ€žQg¯¦ün(Nß_äz[ òô:ÕK œ­²S—|vîc50ð>rá*˜RLZr§±æ¨F÷ÓËÅRè¯%ùdÏÌnw°GA𤒀\êÌp½{ë;îÿ©£1ö§¤Z…(Œ£ŸâÓlXzøÓ£g®éË7âE–$M@Ã²ŠŒ!‘ø„~!Óm¡.YAuõdOÉP)$0+17`´¦>‹Sºšà`Ù|ÃùõZ+iÌ%‰Õ-Ž­Lf„1®Á]L?穎ý²ødµ§jÄaš›ý ’«+}W¸½C…÷ .ìñHÖ¯b sú =l!î‚0Q­ %— ̤¥¥®.©Q0cÑ…2¡ùÄr*Û>ŸÙ8ðrõÜôÎGùÓ%'§Â5æ+)Éñ;wF$ö’/=Ô=†1Ñ¡*^À½”»ÑœäJû¢œ%uÅ,ºs+§ItO¸’ýôí^êÓqVÆ/õø­˜¸èc è¬æ²ao¼¸=¦ªò^y#et…Ëõêj‡sKÆÝ{%&é³ ˜P ÅFU1ÂäÿÈ8Lˇ™§”ÁW‚e¾Sî3_×ÐR…%«~Þ¶‡ª­R¹¼0Ö¡|!GZ¬7™D¡ÂmlÉ« û¬ÅÚ›å'û!ªXÌ Æ¥Ð‡Ÿ$Ûn¬ßi¶cNÖT{·d­ìD§Xw¿§ÄšU ~pÌßíÛ/“8&[•+2uµ@H‘‚,Ì݆¡÷µîKôÎFT@·UNÑ-ÕšÁ%«(aš Ú#ú‰TƒKc´³çó|*”n=¥K~e~Ï“ —[«R^i52)úIí 8Ž?œðí•(Hù%‚¶§q‹©[&H…U½3È’PǃjÞX¡(ìÁõJ[Ú(y4\9{1¯€kÒ‰X)×'Ùʱiüƒ²{æxŠH.ž?–… Ý®CÚS‹|¦iŸÎ+—^Pcª(¿œ($&:W§||RÏä|ó­„Ñgx^­ˆI4¿,]…ѧ <‘å ãÜ5u@܉Ü Š4õõ펛ƒ¯ÑEÿ5qKÁ’æû„wQU›Õó”aRG³o¶ÊŠr„ý·û–lŠ…Q`ÜwÈWáp·Š|SŒü›ølu1…Šc5|–b¿ÂϰùRôð"TM·Út|zgßn‚$ØŠr}7¸ì»ÖUTæT^½ ¸ÐHxÔš™1‡3ß?1_%‘Õ áŠšB|Î~ãn‰"”‘ŸÀ4gqÙŒ:€âd[­Ömì`r î~%³€8Áj·ÌÓ¥í©ªf‰¾„ö§Ï‰óçô$zƒ1ޤPP9*'+p9øx3T.Œh“öJ™¿Âõæbo¸ó¾4¯íò¯ý ~µbàÜÄÆÅëºÁJ‡£î2ƒ=Ý™vÁ6­}‹Róƒ¥ÁõIbSŸI¬éÈ"²ÿX´€Z£°×=¡ g)+ö•mò&®¹át3À¨Ã(t½—Ú/R¤‹+T ’M´5c»¸ m›R¨fÚùp äÖ>'µ­’ý¹R3rÚ+‘GGN’ïêÖÁÇ 9pÚÏ‹ãñ¤HúÏú3Ë«¤:_ˆ=o2C£ãwÄ%œòîÂ(ÙN²™`ì^ªäfÓÜ`¸{ÑD±u÷P¡Íy¶ÕÒÌ­Ló^æÍ&eâ¿yµË-g)ž¾Ë¼åDb 0NRgäÁª”).¯=°[äåKä}÷䥾ÕfMÎå­6KÙ•ßÛiVÎØ¬Ð@Mp-çF<ë’ãKõ##¨æªf|•vÓ¸èSy‘ÏzÊíÚèæø®-ßìŒ`9î3yÉeŒ¢¡rã6éôÒÈâ&êêÙxY½#‹…4.'!â“߸•ËÏç×}¾ àÒmÆh²G:­v5ß¾>¹è¬I¤R¬ó%í®I2"m)pŸ†¬)LJ-sE¤wBÆ\ûàx¼uÁ ìàà)†ý®?w-þÄÛóS*‡Û×wün>òîº佇1©úìIn\@Áû‚#–ÊI£óþmü€Êå^MåQ5Û†ì+fÌÉ)sm%$¥®2AÁ*r¾¯i`ƒÿë÷/Éf×(’eŽpý ’EbŠøÒò÷³órrx¿Ùî…Ía"”æ$çÆ:O[½D—ÏMmî”ó¯åŽŒlº7›ßÔÁ¬„dp‰e=ãvÏA6ä“Ûc4ªÙ ž)ÊÏÓŒMëU—)Å#ãùp¥)~Øß‡gºte © wuÃ^-Ù†œ3m6vxÐ.ú»Cd&ÏÌ ]ˆ %"ë»­µ 4-ÎøYmº¬<ÄÕàÈVTøEʦl'‡U3ž,3îÔ€K6:á…Á ز0ÒöuXêçùpƒ$ó¶žÅûšR™=?ì¿3OZ0œ‡‹œ$%fÅ5•.," ÅÕIKfL&Ýd«ÒÛ¶ Ò*Ñz>~|åÄ!á“;Tÿ¼°wc8 Ÿ(*mBÊp‘77cq²¯„#eµˆ½eñ”æ¦KN84e þ&mÕõ­1Û™P·£SÓ<òÊVµ}÷Zê§@ÞMë€<€¬åË&ûqÝA_ÁXRz½–¬X;w3ª¹BË?#,d?¥®‹#{œhï1»D‰LÄшÔ]Lª0‹G€~8îK‹žo H]¤äë®ü²þ“’Bö¾w€Ö:8Y2Ÿo¸È£Ç}ÜÕV%$Á½ôK”t³ 15^@$N5k›¿W²àéîJXɺÝh‡ŒqÇ^èð ^—ÛÁîHú¸5<ºL~_ÜOùoÝ#ãP ÷C(oqZo~„Øq}·wy™søÈDûXp¡E²Y‡NDƒh®kÛþÂΦ@ÈË¿_Ÿ¿ô²çH¿Ëî|‘¥ ãP[µ!^OƒÆÆrá1ÔÑ­vÏ ´ßïŠedì°ÊC²Ö'Ó˜„çÀè¯u9Ôd89»} ©œoXÑdÇŽÜÐPSŠ7íÀ…¨><¤PÈ1|¹7ßVyŲ½ééá%ÏÚ”òÇ'Y¤Ôñ;˜8¥N¢Äï µ#®]«¸Hggªþ¢Ó‘‰Ü|tÿH°M)¦R¥ ¶N­ÆÝªíšòƒ‰R í{ø¹éL€¹ÎĶçüDG‡„*ç(¤áP£ðâë-î犌ã )@Å(?¾c~¾âhà,RýÝFî½3ˆ¼m–æq5<,0~öK[XÔ­PI¦ÛÏó\­b£ß~À!&{@Ý÷¼‰N–Þ&H€ÚÔµ©Ì22Ï”)IÑB\È¥=qÎ\‰æç´Ñà¥ß ¢b‘óøìå÷§iŽN-¸D&ˆ5)ßã­ó3.ÿdn# Îs!V •ãrMLñ<'šP¾ÔŸ@¸WYÒ‘wçÿò¾Òç–Ö–V.wÚº7qËw ¾y2obW}ËÐë£ ~W·Àg¸sbj„ȳBMt èi(\­ùê“í&×ÙzzÁð4#C®­x@åHCK‚[ÐÚ¤[Þ#Ç©rÖ{°“ÈÕ84S’cmáË“áôÚ¤È*§6MM*sËY$:_Îñ¤C“Ø“›Ó¬ªc¾ìi'õs1z³vØhæ:¬—µ¼ÙùÆLå†Ò–³i]¨W@†–M˶ڧ‰I܉U¡€G‡• ª'>Ûf4C¸MvtrZnàyTÉZÕ$KËýaGåEìÝ¿krÀ‡~fµŽúî„ÙGé¦éåGa5ÜÓ1ƒÌZ[\ U¶…\Ðר·ü¥ÀæêÛ‚Rèmà>ñº4ëµ÷VyG~ü½m4ø0QÍÏ<5&6,Å*Ô" €öºàÏ`]M$¥¹¼$ûË«>Sîy i¢§£ !㺲”ÐÙmPžY1áÈU—¬h…øƒß'p¿X²0«Åû×N¿”UVÀzÔvƒÜšýâ„å®ðÕæjæ–Ä9Þr`òٷ…Zî¢ôÃ5†Q¯„ÿÖež&Zç:€âÜ3ùO7î•r+B«(ô]gþÒ¦ÈÑH=Fˆez u±!DÓÆQfl³C%q§Kõ¯ÏÖZ®^®¹Nˆ;–¤ßÀ¨ZÕS¡…ÄñÎ_\‘닼‹óDo®Fø>¦R°ÝÍj‘~É÷¯[÷oìÄæò n?[Œá)m’@©—‘Œ1´bÖ9Í­n8-MŠÝšá_jÂå­êÀ:BÝ{8J4 4q†ea: ý>F‘-¼ªø¬Oð…àŽóMA1bÒvBŽ0{«i~n"É(ãUeAqò`Z(سRl8ì|–½v:øŸ”‚'Š’^ÄÏlÇ7…·}¡…4íKœç:©ú,X…¥­­¡bt‡~Wî¥öÕcE«ÃÝS‹†=@å ´Ê׿åóÞ=hj3áRe*ý¸ Cà ê8ÎÉ]Özá·}6ù\ø*ø1B%[3DŽGV.C#•kÔî F’)Ò›¹zäýWݱAKyIZùþr…ùÆ3cÍÄæÚH–V*›ñ ŸH¡ó5q¤Ã·i±‚”p³×S“š¡¬p£“ ¿ EûÙc¡ó,ßlÁ5Á²È¬íŽÏl©-fͿ궘SOpø¼5Sy˃øú¶(û .3Ÿ– §ï¢Uí,?H-ýÖÒzÆ¥¨>#uQ4ŸÕÃJE,°NN•SONãó‚©;0ãb°^‰Uåª<& ²Nåð I[•ƫ纴ÉQì\ïåºÞïñ8+ìNH‰\¶¥S‰)½0@ÌJ,yßÙ ?3FçÐi®“© X%Ž…¾‡¸ÝëÄìk|ßâðmbØ|¶®¶LïÄì†Ùû¸ä¡›¿å4žUt§Í-Ú'ÏxñwÓƒhÜ£¬N¦ú€·$:–©<©?æÌ"7{•åQιv – YRÀ¯Téœ'Ob­²)7_ùÖÊ$ùÐGDËky—Ý·¢ÉŠ†Ý¡í¸ sx¸ ìqŽ#cßê©Ê±•góf©õÏ)mé¼³_«´`—¦„j?ùÁ“³Û)„„)F'ÏÔJL%%›«Éw‚¦¤‰¡g¸ ¢̪Bé±¢W>"BYÉ:VS=e=X|ùÁ±¨Þw ö¼Ž”ò°=èäÚD¢z*•(J":“–ÝæÜ\ÒËâ¦òUàñ+º¡îîñ,XbAeL¼Ásg]ÔPŠûÕ!‘I´+SdDÞÀð®¼b–ŠÇêqüÆŽ·ß0º¯¬÷Y®M»®¡J±˜|‡à6RBÃðšÍØøæU÷¹¨E— 9Ò­êÿ„l™– ÅÚÎÔƒ™­GÝê™ "âX[zq3H³Üé[‹ãq»©¦-ÚÞ,ÈŒ3:I{r¼â:Ü?#©+²÷%g² X6F~“K0'Òöé½0r=ŸËH“¢“éÞiŒúR7a´Böj»å¸’CêOm‹FE „m&V”'TKõœ 焉p')ósó1ì¯z£ùß²›ÔÕŽÙÍd•¾JãàõgûP²öÎÁùiÑr ¿*,‰Hç[`öR{w…ÝÆ¸5¹¾ŠÇŸÉz¼ÃWDgãX°+>BÃ]‹BámƒéIÜ_<©œ+V§UžÌGT Æ‚(ø‡Þv9N{ Óü Óúš"ýSz×âת 2\Ö´ÝõØŽHhKÌ´¥sšùíio=¶ïÇ·‡¾Ü⪧–AL!¾ëø ãt¾tblkMÀé¹7AÑ|e·šáfa$|”?²Å0ËvœÁ×°(Õ‚î)=í†þ ±T1ß<” î³ PÔÚƒÞzçäu™»Óƶ»]÷so›w~ª°äƒ]ÛG…,¡ñó!XúÆ‘ŽÝo-*d~}áóÖö2 §Cv¿*ìiëÕÎøˆIXrg]é‡ ³Yèîã`"ùÞW×·sÔ¿A^nÒÕùIÖÇZˆ‹ÕúMºpnc1à€ôC…M¯³ùmlU”Ø—Xz ­ìS;ÒÁ’½yXžMÈð›’]h|¹ ˆü¬a^6ÕévH£ÊšÈØDuöGÑwdp7™õñàéÖd“ó?¢Ñ>;ô¥:žu ôÍáS>3ÞÒ÷“ÉU·ák&½þ½e|‘ÝÛZuFÒ0  ¬±üÕ¸¢ iÑ$Œ.ÞoŠárò"~ÖùôÕ³zUF•=GÉÝ©‚~éRÜ×h4ÖÀeiâw±žRü/dRÁŒTkÍ#wƒ0&§šžh,Gë±Ãñ°`¿pLsî'úm¯=±çɱe—~–¯#\‡zó,ªÊÃã•ì9»^Bü¹“ÿC=u°cDk þD8œ/'V¶4¥? a¶d»Ø\ñQ­mÓõ:F,ÇÇÔ²\ñÎ<šr9oâ\è‰ñÓ­b]Å»¦f;Uˆ#e2S> xV¥˜ÃŽ­ˆ†ê§—jŠP™­¸¡.!‘#È÷©voÔ`ÒSº’ûþž}°S‰Ô&|ÚÊ=Ê4#æÌ—î–Á2$!ù¯Õ³ƒ’(Z3ítU•âz«.V}e¼¬œh>d$zH¤†5ç6ã§üL5‡êC º/Jd~:¦¼ífIu„ÌuüŸðc%Õî¹£s ñ‚O>»9‹=l¶ÖÓ+#°HÒI-÷@?JP1ih¾ &îÉô]“¿|Xä´Úăvú²†(á“¡´5CzC¢4ú1.XÐ̓§ KK¦Œiúºz#Ò.âöG]‚'×Ô¯¿Ò_X‹_°þx4‚ðÅ˳#¤ä"«P¹–j –Ñ–BYíˆ87ŒÀz" IOÒxásØlŸ±›Épk7KðA ç/ɇHùM¸ž6 T S!õ\¶ZãÒJ)¡#¢:sÌæÀŽ_îR·è¢#Ô¦Bò:~‚3LѸ‰dR” ÙZ˜QÅ‘ÀOäw‡ˆoJ]¬ |*L1qB')ÇL²$Î. c¤Á}2´äêâqzE¸iÜ(€ËÀkD[ˆ„gÑŒŽ²ÞÝ‹ÏY…Ê4寖|îVO.Îß¶,ïOñBϽ×õžldX|ÀVlË„ Ñ2âÖÓà NDè{òBláy„VT›3Ò„E/uà÷ú\¿·ºÜgì7±ËÑ"Ý¿"³ ¡>²¿(C‹ãžeŸ›PRòFWŸ«"ÃÐ¥¤YXíùñÄXY6è êOqÚô¡9U¤ $Ö=6Ððü|Hò‹°s%nS,{¨üˆ&õÊ’—8$²cå’6¿p[Žx7íj£\k@?®ð¶ "Ü<4s=3Ña½BÚ_Z¼–âç0h^×IÓ¡gÀDFÌû"O,v}V%t ïæûüH¦¼¯¸Êi¹ò¢ŒÞf4ðAÖÕð î[ù×%£©!¿Ñôør{&ÿö§õ 'QºµÝ‰’s$ Vº<3ÿiúü`+zв±ƒõ¤âBy¿e5m¨á^[ÄyaS©aŠ€()ÞŸíÆÜ=7w3ÔV³Md& ðÑÈå’½Teöä´þe¢QŽh¬õ äØîαÿ”øg´>»6¹”¼g´(>\PóÔkºßo†‘vÝ8‹¥‡HZR¯±˜(rÔs•Ì7R¶s×»LíªøŠæüz!ÁÈ U[–Õ²69§QŽƒ.[¿’6çÏhüS—Wse®÷±dßbfïyîI‡dÁFbNþ%ÕgÔÆGœ¢,bœrü(šÙÂ%+'‹ Òl£g"îuªrC`Wro¦1€5ÇCÈ…çpû¶šÍÄ]sG¹ÑOnäàrqœìZI=…M}…)äCQÊ~ ê!µŸ¾Dz9·%eÞ!­û©ÆÁ”,Ý,>׿¿âb‰lGûrs RøV0' uV·ƒÔ) É ²;^%!#úㆹå"à÷È“µ‚i4Í p#Öo·¤_Œä%±!¥Óæ`…(`¢ix¸ü={Pìr {[£3þÝɶ*\ÔvµvÈÆe~0{zŠJ"É®Ñc µÄÀ‹í_~ …U¢÷íýwõœÅ6o¸JÚè¨OÊÿ7E®Õ?ÿm]~»úàD¾?œñ޹,à¾$ôƒc2‹™‹ã鏿ߋM|&ìšp{³×Ó\Ì «e •Œ¤·Æý:®s”CrªÞr±[G^…_x[´?ÒØæå'®Öܬž ¥Škv5‰GlŸ뽺>QÄè5ó†…¼~šÒÙŽÝ  ÙvnÂ|*ÑÐaòÝ¥ÉÿÞ^á=tønÚÖ•_ÎïxPðdòùCß•b­RæwWbgÖJ?~årοþC¬[BýädƯ{ñ h§úÍwÓ‰Ï'}2~Ñ]Ø6å°âÙŒ9û ²&ÜÔîNÖñûö¡î±`luî‹)G2O=ßùEßCùä”Õùù[ ¹ÓÏ™wŸ˜sìÇÆâ@•»¯M·åöMXvºóEÿÿu9~Û¤k²¹¶…ê¼ ª?yÉg“º”òÌÜ{ç;OÛ«YŸ$3iÕæ#ÛÏn•8²oväóŽ7¯ã}ËÏëÕýÜá?÷þ¹ësÿ„æÕäÈ©Ù÷pö.Õ`¹fýO©a›K<­ÛNîêè=|ˆuÖïD©â¹µßýÝ^Ú(šDªM?T¹CÂxÝ;)ñ´g¥ÙENÓ/Û¾}õ%×ÊÛJ®Q†…É9©‰E%ù¹‰EÙ\ãP[endstream endobj 1122 0 obj << /Type /Font /Subtype /Type1 /Encoding 3111 0 R /FirstChar 35 /LastChar 90 /Widths 3124 0 R /BaseFont /VTVVBB+URWPalladioL-Roma-Slant_167 /FontDescriptor 1120 0 R >> endobj 1120 0 obj << /Ascent 715 /CapHeight 680 /Descent -282 /FontName /VTVVBB+URWPalladioL-Roma-Slant_167 /ItalicAngle -9 /StemV 84 /XHeight 469 /FontBBox [-166 -283 1021 943] /Flags 4 /CharSet (/numbersign/parenleft/parenright/comma/hyphen/period/zero/one/two/three/four/five/six/seven/eight/nine/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/X/Y/Z) /FontFile 1121 0 R >> endobj 3124 0 obj [500 0 0 0 0 333 333 0 0 250 333 250 0 500 500 500 500 500 500 500 500 500 500 0 0 0 0 0 0 0 778 611 709 774 611 556 763 832 337 333 726 611 946 831 786 604 786 668 525 613 778 722 0 667 667 667 ] endobj 1059 0 obj << /Length1 862 /Length2 1251 /Length3 532 /Length 1861 /Filter /FlateDecode >> stream xÚíUkTgnõJÀ+Å€€¸ æ2@ ŠrGE*C2!$“(— A@0¨P¹TZ)­`åb°¢àY#BAn¬\uÝôØ¥?wíÙ™?ó>Ïó½ß3Ïûó™™xúœXHì‚DÒg7ŸÃ ‰dœ™™3 C"."؉`ÚÛƒ€“8©ÙŽF!Ó¨v83À “¢Ü`ްpþbAd8ña”Ë„€$âÀ|¬â>“ ‹¤DÀ‰Ç¼VoX£0‹ˆA€ÅeŠ€ 8˜+À‘1l°[‚Yâ°÷TŒ 1S€fò ³ÈB<)À‚Ù8’;‚ícNþ¦–7wóxî¡ýbJâ!>—'}§@øabŒn FË¥¾ð’97˜Åó—³ Äã2Á< €6D²5u‰à ]¸˜åÉ19â áE°–[Áâ[4Br÷Ýïµo·Õ»¹.’žW : ƒòõb ~¨±”P®ð'Édbïû¯€e›í0W P¨¶„¢‡ ¬¢Q À°` K0Ç$¢aK,šh€ ¸…±‚Ö‰ÉE™<˜¹05Ñ»DPR–9üˆLÁ0bÂ<˜ýGØú¼4ô¸-†Cè˘¡B$ä,ÂŽNG$QŠ=@°·Å~m;;jô¿ ™b…¢Å³‰Åÿ¾fs±‘Á°fâzº¦CbHnURyÌî wø„¤õªµBÝ£ÙäW“ÇeEûPÏ{™‹JFŠ”×NÊñ¡ ý}L‡ÓºèUƒt÷´¯¦Šu/]K-,óËŒ£6»}ðÒ„TÙª7Væ# yø¡3ùß( ièãsßnÙÚ3µ%¶Uç{ŸMÜ_uæðó’:¹vW¨»ã~sÆ«-÷vTŠ›øÚŒ¬†sr”„³iﺻ§äqÿ#ƒï¾ö ¨Æ¥{@.o4Ò›‡NÜ£h™Ê:íŒÌ¿:ôš±²lµ°Øbƒ°ørÜh­ï8Xy«£|¨K?šØ`¤êå_‡qä8ûJ˦õ²Z½îês2y¯Ž±fŸ23ROa"«rÙgµg2ÒÒ=ܽüökÄmÊM ðx¡V÷¾,^ŠœÛ6º)~ÔWÄ8Ùòj`ÜjR8æ£M»ÜYâ—lh.…/×;ÚLçk:•[«b(ì¶[t¿K:9IYœÈÉ”óÿ0};ðûÄ÷ë C?EYŽk ·÷fMÇ»œ*å¼PzÔ:T•›{ìÇì»C"pލ,±M¹êþ–u`Ç‘½)Æá±™ÇÂGM<5t=ÊdW´ããùjŽë&Ê|FWèxhö?+S‚#êçžéઞÍÛvM|ª}%ß{øô¶ŸÔKqËwÕX§ªnx›qèE;]?ç³Ð¿éÎø©_‡çÎRŸPyÈzåWpç5H~àÿþ—Á’‰ðµy×o˯ˉ.„–ñ–¾Û…¶TÅñGÊ7GÅõ·Ìe$åÊÁø³™,ÿ’\ßK?ª=¤Ì«*‹'• ݵsÉÂù0è¾¢òsÚÊ~î2Vî0QQâOûÒgﯱTû”ÓË¿Ÿ&½Mèz©QÛ"1*õ¥W&ONkµ¼Ýì™Ù6è1 '›µ²¤SªV‰÷6€Tû}†Ûv±g/þ&±o^3æ«Hˆ²×ñnpÆY~ªóìç{M;ßpòžŸÐˆJ–Òñ kü¨V¨ÔgŒÂhäå£ÄÚ‚Ô‹¿ºï(P&'ÍElʼÑP¾ãP.£É§ù‘݉u3¯,TßfTzš®4.ê/®è[†ŠÔùýŸD[KûÝÂõ #4æø—…ñõíážý³âìúœølwùÕHrÆÓ¤È¯ÅF§ _ÔuEصŽ4j­®¸û×Çãk¦ï݇Sê d£®ªQš½º÷:\JGt[ækX;›ïŒ8† :]×ñZ5ž—i G|sÓ4§mÖ% &Ùic]ù[õ ×dí!±yþø°Æ9üS꣙Í^¶c“Y4§¼Æ£ ¾âipÔ“¿‰<¦ö_>òKo³¾ª¶öØ™ŽÎ$ßWÓÙ6IòYåäúím]„“;²<ž0NõžÕ蛕k­L,‹aµ‡ÔÙ ±‡ÅÝÑYÞ=2NþêÀžœröG:äÿðÁý¿ÁÿDìê†P‡ÐPÜ¿{—þeendstream endobj 1060 0 obj << /Type /Font /Subtype /Type1 /Encoding 3125 0 R /FirstChar 13 /LastChar 110 /Widths 3126 0 R /BaseFont /NWKQJE+CMSY10 /FontDescriptor 1058 0 R >> endobj 1058 0 obj << /Ascent 750 /CapHeight 683 /Descent -194 /FontName /NWKQJE+CMSY10 /ItalicAngle -14.035 /StemV 85 /XHeight 431 /FontBBox [-29 -960 1116 775] /Flags 4 /CharSet (/circlecopyrt/bullet/braceleft/braceright/bar/backslash) /FontFile 1059 0 R >> endobj 3126 0 obj [1000 0 500 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 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 500 0 0 278 0 0 0 500 ] endobj 3125 0 obj << /Type /Encoding /Differences [ 0 /.notdef 13/circlecopyrt 14/.notdef 15/bullet 16/.notdef 102/braceleft/braceright 104/.notdef 106/bar 107/.notdef 110/backslash 111/.notdef] >> endobj 1036 0 obj << /Length1 1616 /Length2 25791 /Length3 532 /Length 26677 /Filter /FlateDecode >> stream xÚ¬ºc”¥[°%š•¨´í™•¶mÛ¶JÛ¶mÛ¶mTÚ¶­Wçܾ}{Üî_ýúÇã[±f̈¹VŒ-b9Ej~#[c[Gjz:€²‚ªœ¾••¾‘¹­µ‚­µ>௙Š˜XÐÞXßÑÜÖFHßј jl2600èÙÙÙ¡ˆ‚¶vnöæ¦f޲¿ä””Tÿeù'`àöŸž¿;ÌMm$œ­lí¬mÿBü_oT468šLÌ­Œ‚²rêâ2¢2Qe€¨±±½¾@ÎÉÀÊÜ enhlã`L0±µXýÇ`hkcdþOi4±øú;cCó¿ÛŒ] íþqQìŒí­Íþ>̦öú6Ž{àh 0·1´r2ú‡À_»‰í¿„ììmÿFXÿõý“³upt0´7·süÍ*'$ò<ÍôÿÉí`þ× °5ùidkèôOIÿúþÂüõ:ê›Û8]ÿÉe` 02w°³Òwû›û/˜½ù¿4œÌmLÿ‹ÀÞØTßÞÈÊØÁá/Ì_ìºó_uþ—êõíì¬ÜþÝmûoÔÿä`îè`leBEÏð7§¡ãßܦæ6P´ÿq[=ÝØœìþÓçllÿoƒÈþ93äIèÙÚX¹ŒŒM helÿ¦ýß©LóÿNäÿÿ?øÿ‰¼ÿÿÄýïý/—øÿï}þïÐ"NVV2úÖÆÿnüçŒHþ26ÿ[´¾µ¹•Ûÿ)þ¿GªÿÉÿ#Œ¸£þßVðÛ˜þ•ƒŽ†î?Œæ"æ®ÆFr掆f}«¿}ú×®lcdloencüWÏ[  ¦§£ûo>%3sCK›Ïü.c£ÿÎý¯Dÿ2§ÕPå—P“§üßgê¿qrµwTr³ûKí”"mkô?ÿ غ<¨éYXÔ lŒ¯=€‰Ñëÿñ_ úÿZKë;Ú›»4ÿ–MGÿoñÿãõ_+íÿ#lchkôÏiQtÔ·1ú{Àþ§á·¡“½ý_]ÿ½ó‹þÏõ¿GÝØØÕØjõ­!g EjFšc-zÎð¤f/=Èp]IƒRa¾oµmOjè{…ÞGMMã4ÇW›ÛÒ™ÝçÅáh/šiO²ñUŽy_>â&I+å¡?­N lÚ¹j¤Çõ¢Ô6¨ Êá‚NñÇOÜéF{ˆëgr_"ç|_”_OvpÞ†)õ1¨@Hµgç$ 'ÏO¤ƒc#ÃC=·`}Ø”Ù1ĜΠ°$¾¿³±y5”Ë…+[TZ÷z4Y ¼EÖ>%d±‚2šž—G|FÊ“¯,Ƹ~Žûgø}ÑïS«oÕõpZMjqÅ'oÏ¢„Ü„7›=©L­D·¢Uo⽉ޠ|«G»Ž¹nc¼<é©2cYŠýиÛÉæ¡÷U+²Äi‘a FwF\Ö¬n·2QËR]BlõtMƒšªÎR°ï²®Yâku®O~¤è&)Ø£|ÖužÛ¨¶2š7ÍYÖ#·ž2„Æé‡rBb§x/Õn1¨Ó‡7ê—5Åü醽ZÌuЧ>U€:(’韠}Ü…Õ¤[«^Ä OŸEO¢ˆîdi•©]Q¡nÅb$j iRœU¾»s„q`ñ‚À-¾BιÙ8¤'+>_œ»^;X¢\”ËD™!æ¨jL˜ðÆê¡5‘U©/yûóÕŒb]1c9{—*‚Ò!(!NHèÀW-†éS¾×²àJ”½9©/ømX8aÃq=lÓìu88°é–Á¢Š{ ½<È9Yú _`ÛÀTøÁ‡={;¢Ÿ*páa !T!Ï~xÙe3¿ì±B §Í׿ˆZ£d¬àW´‚G„˜{Æ÷")µªTW±2„b­Aù‚š-ZYgž&Î70>ØU1,t’µS›g¸Qše.Áì-ªÉáuγá3Ñ €eoäSç ŽƒLaL Á©÷žê=Ç"làeBÇÉæ´$á4.•¿å1÷yiM†3Œ`iYÉþj« ’ pAsí­m.\íÕØ2?ìI ‘¿Å¥˜?M8Õ“^Œ®2:ÜÞ¦þ‚OÌÛu`Ê© ×ÿSf?ʬø’¿†ÚõN³íeÖ ‘®K’SË]ËîÞ±B½„M6µ2c;L=~pÅžóš¨û¿¿áZD¯?RìU–ZS$«t˜°& Z]À @ŒÈ?qí.ìL›V»!˜ú`}dÙ.RÿTmãøTè„¢XSQÁ„AÖ©{˜gX{ ¬¿‹ˆ ½*ï,äðšë‡4övö—ï>„@{ѾBru™†þR¬6A¨Ÿ!уF”>BU Úð€PWÙ£{¿~{p‚)+˜‘s(ÎlÐ õî—86ƒëãfPÕÄ€ûÞbUÈ?ûÕþ~åS'ŒV k¾cÔ°Ö] 2‰zn•‚ú·š„w±yààœ÷žÕ¥:OÅ[ouÈ„ìgélÞækÇHøÎòȪ{ºÔì]ç «úƒU*H›VC–÷Þ€sxÆ‚8Þ¯" ‚&9IhDeSÃÝ6nõT”[Eð‡¢3ý—(&®ìß4E¢Sô'—\¹!’u\S j޳°4?’Ê=5T¿Ê"9ò"äP(V©+òŠXçö0PôÊG%%ÐŽ8`<8”ŠVw)ÏeÖ‹¨ F Ëæ#,^øèfËDFrtu(³î]/ pëë˜8 JÒ캳¾k0+°QÏ–¸A9ÎHÒ’Êå ¹2/Ån 0¥*´ ¸@a´{ÙIùœïDUˇ!ÈËuö•]S_óãEÕÖKú§ ÷H·WsûæïýiB¤°"A¡{¯P üYœiiæ±B]0Z3:cžm–Üq>MÔ-e†&˜Ô¤í$D²4ÔŠ„ÉŸyë¸üŒ2ú5ÅñçÛµm* S:5nXÜ´ÆuBÕðòú'æ¿Ú2ªPIE¹Æ¹ˆ–‚57“zEM2^ËfƒÔ ðŽ1\óç}šÚ|¼=Ó±ÒiSÌq4ÅñʦFµ)Â7AíÝy”(žö·Q\µÆ dÍí5Í7~ËúÔ¦j£wÉJf”DPOb®)¤mÚŽŒU'‹Q“ÜùCo?ÖÀ½§fµý„ $ˆ“ã(©vi÷%šR [H™gÖM³”¡°D7Ô ÇÓ=BS4ccñf3|V’~©j‡ÖN’o2=£vš®÷F´»DB%«ñÆA Q™a•’ß+þéÃÓ1\LjþøŸj5†qƒœÆbû¬âEßÚ¬ÿ2¨ÓE[{s…+Að3\æ ù-†û[Œ¶e !ëÁxoA0EÜ.9Š­ÜÄ»5¥ŠHLšc,#z>´Ø‘Ó˜‡Ñ€¾Ð*C“@±6e3!– JQ^§{íÀè‡"ÃB Á«v5ió9MÔѽ™çûü»·¶Þ[ï‹~^F‰Þ{Ë VLæ&½öXªi? ‚»âÌÓ½I½‹:µÊòë5è­Ÿé·ŒqíU¦òkdÛñ¾VÜÐ=Lg8p(Ì ‹Ä•0ot“KŸcdoã8èÝ;JÓßù3=&S3âú–÷EL1Š®³”5±MõËK—W»ÖñåMÕ•×Î@Å7aO?Ùå¹HBJ„rFh]SŲ&Ê‚z¤1h\œPDfÆ(ÃTf‡Þ~Ž98i-~0|±EfBçñ§1û5[æÞ‚RäZí¶ê•4˜XJ„õ:ïº\?Ÿo™¤q2”…¢Ò}ñ”À›vQÒAƒ* ­@͸VõYCHŒÌfe‹^ â=˜…öÙ¶^³|ÑÆ^’´æ<8X=ØèœBmH:¼E ÎГ<$þÕæ¶ïP|e¬Ö’Ù‡*?2^ܪLE_N¯>F!ÆšÁr¤J¢ÿäX/Hf¥†‘n3&ñd‘/¢Eò) éaÁÊÝ „´«o÷X­€2¥y¶4ð (á¦zëý§¸yM•‡„æ=X8lôüE ¼Ð'‰`gв4Ä£P>öÙgÀd|rÀ™Ñëe`•j 23önIªJÜœSÕgÇ™úBÐ.†«9üËO° Á^íGSå÷‹—%N‰Åˆ7å ¾:÷q¢ §Gõ¼CÅÓG?µ§06H<ðüÉ&† F&»N&´!5Øoh;w‘„=¥xì¨ÝËT±À­áÁ—ka ¨¾­ Ä›'Ïë¡Æ¯Cv9Rä€JÈ2£|MÒè Š}§áShá ì©w¬†^ÕYïI˜N)öÈ:*Ÿ¤Ã’æSP¬”®·ÅxÆutÉkIrsbòÀ­¹qüK9!0—V®‘<´Ï ‡Øž_ 'uºk|sQ \^,(‘9M~)å©¶`cvy¸ÍÓº X_êQšº–­÷üïùÈà·Ð‘¦z±¯ÜžÈ%Rnœìèƒç‚ì)Ît¡¬³åB«~É¥–ÍTkòÝÈ zKÅÿ‚B$pYä¦ÖÜ :Ú×Dèˆ%dyÙRt,)U$g}÷œˆ–Ù–Ttg–Vü^‡ðV í5T&KAÊSu°’ZwND-æq³œ×¼øÖAùÑ0}¶vé:nöT&úœ‘í„G4¬tŸ}ó@"ð@`t¸w™Dvfž!¿ˆ›`µgÉ㼸^³á•Ú¯¥È›|õõY³'äTë¶Ñ¦¡¸Îß¾³9nx:%%ø\¿ÓWø«½\|PçÚʶþäuⱓ·X¨3«ÁḃU~¨Cçê¥U:…õTµ¹ñ&Ÿ¿y<ÌÍÂo¯”Uˆ¯ÔR@Jß–ÿ—wÀxú„š$»„áŒÂ÷ÉÔ¤ÚÅ˶f‹×‚’Zsv³¥‘HÔeƒ¸GÔ»T‹ìJ/- `ú¾Çb×8\í€ƳøœxU¥#R)²âhÑCNª¢·á0M³üc¢”5¹jΊUI¡Oôu–geÏj½õ7r›§×fÂò¾ŸŸ÷î˜ó!X8•ÂjFÏÁ ™Z¥=KÝP{‘£Ìô’¼Ë[„š0Äzo7„µíi–6K2²~W±ùŸ€çZln51 ˜±0%œ2Ãzö>†9H#?Þ)Ë3M™h}!Ù¨z¿æŒþ±÷‹cÊI]¥¦\þ«',ó¦hçùðÞë¹Þ"H'O]®¹+îÐDx#-ÉÚ¾Ü:'5¯©jzr2*+Ú=ÚCãì-uáåùß§Gäˆðp}’Ö*"ÑêÉŸ£ÖuGRþª#¼/M–43/?¶Œ:Ý5¯¹VXgÜ©ò¯lX…– $µmwó|âêTël»šÞdÂfµR•ÇáBx:ÇaÉ>€ûZ§%*7ç-Ì_:¡n§@HcÒZlÑZå¾F:ë]RÛÊ,[D¾`îeå­Ã­º7rÈ-ŠD’”we#PÙã–É&^ö*›mNJ¶þŒîkÍÕfjmÏ“‹y ²‡eöO9ÇAÀø£(² NF¢@Q TZá-¢`ë‰aRyŸÏÅœ‘Q¶>“Au]A¬›ÙÌÚÐÁŒ¨¹³G'|jñ=0ÈŒI*àkÛSz•ËÇ…ô{¢ËØ£¿uA‘R“)µ0(©D¨O¼“™×uºAòU4àêÈ3fÙÉ( 0è ’Û¾O0¡O¥<9Þõ$ÜäÿÊŽÌž«¡óǼVVʨ›5<…4>=LL%û½øœGç &iX7ÿ+Ʋ>>•uÒ‹ bK=®YB³Õ´…Þ­‰žÉTáGsÿ¤1_ h&m^+¢žüyÂà 'ca=„˜‰-F؛Nj?öFGFŽ3#y¥å;yÉñÏlå¹>{,`Ïá¤É´¤W»¹ˆ®ó;ô_Wápkà¤QE|Qðºñ"¹õ¹{ªÓcµ)SòªÚ'ãoÓ¿StœgQmÖÈjëׄɈbXò ]Õ ía n]¹©íQ˜êÌi¦£‚§`%_ƒ]‹RA¦Ľ.鋳 ÆwÅZž˜Ná0“èRêìêÚ—7HzAA]žÇüCkÎ*HºšÈÌýê|ÂzÑW2?s¿Úø¡8ñLk™”Wm¯fD`^hAXFfN¶.|$ØÍ9FçᵃzWop–hH›ƒ†þÈ—{?Ý×w$¤°Y:€n¤BÆÂ%ã‚Ù\gáþ˜&Ý1¦`øVý~€g«qyMÇð1ó6§±(‹kQEÀÛ'ó\í_1ED€õ‹%¶˜ne.¦˜b'ns‹É¹†ç ×™~Ÿ¢`jöí#-f lí>B©]â¿ÈÄéÿ’¯‹rŠHdq‚BúÉ•îq i‚è}ý+‚@áÙ‰€ieÙnÖ`7 œº³4ê]Ëu&ÈeÁ„qË„ÛîFº²‰“ow8ñ#¤JmË«ìû²XK9{Žìé[…Û¶«N€ðmñ «V¸L¢×4` XWÞ-œ!p ~“ ï¥'Õ*Õn¡0øÞµ7_8 ³Ð¥á%̃«ìÉüïpZwÓ†û$Àä½"hŸØÝF–áè†`oMb•—äj’=ûÀW›v7ø#©¿nk ùµØþ¨;›ÉÅVA ByýóÇ!ª‡ÚS¢´Ì«òð{1“Ó <{;¬e5ŸÇ°lïËV}*ÃÇÇ£jµÓlé>ú¹Lžú®|XÎõn˨ZGŽPfð¯û–E§?Œ<†RºÑH+ h¢Et»NÈ8‘ƒ!϶}›Î“ rçw«Ú‹'Z #ÙA°¡ëû’–˜âL,ÀK^±Ìv*çóž—ícuô­ÁlÀ rϪâI0óIdb—%ðÅÛò=(~®‡ÄÂwªŠüšköÐV»XÁÖ9 ŒÛöŽ#½zœµÄTeËE2¦•ÊV#%ô”Z3lWcáãR"Ž›otm1À6 hRÆï¼8;°ý^þ/JÌ“¯!”ÑeÁ©e8,tI—r\áÒîZà t¹7 £¢/Xß¡«nû¡òG©¡O®Â Ë‚ìÙæ¥!J`@Ÿ—†«÷&q2»Ê¢–7¤Áµý0 ëù‰Ówï›uÜÚÌ9˜,#¼¸(^Å1$uâ)Õ5uO®¥ªü®¯·ù¡Ã,Œa]œ¾DØÀnüT(¤}á(PΛì#ŽAµïÙ¬4ÖØ GŽeyXÇôV—­óˆÜey=L’AQÑÂñïµ›ÜAzpØA·å~,vIͲwˆMìµíZ³¯Já~8›£V0„8¯èºüJ5Y®†ÖDùíâk ‰QÌîHï£=öŠÁ¶ :ïÏu'#¯srC<&\áÔ%~:ÔÃòxN¬ô#æ~òÏΆò$î¸$Ë{¼Y‡†W©ð­öïæk0ºxtÈ&é ÜšµéW-os×û‹ŽŠECë¸Rï$q°"¥d„áqÒvÞð-EõyOî‰{” ì!:õ‡–£`glà(Ƚ—ó·3‰‚Ññ ê îÚ‚»+Ê3Ò»_V>`Ôç¬êÒ¸ž¶?¢5Õ?ޤeŠfÔÐ`Ê™Kªâ”ü²eûåÒÔÖ`iPˆšß¹jÛ‹¯PƳÈK°>+q%ùc[ ‰Š3¾#“]Þðô“{¡Ïþv^æ|öté²¼àÂ$Ô2õ‘Èò BÑÇz FQ“0™E˜ýVJŸDO²‚Š˜äOÔ×ÐYr t®ã Ðè¦ÒÕPã×Ðä9Á”h«ïêO‚Ó܌ќôPKüxY2—óÕ^õažY£Ã´ dcSmiæp’ß`g¢×*½ûò²BW¦¯(> JΔ³ûIJG¾‡L’ÉGÍþz2OÒ£¬?Bƒ}YCÆøe¥#¨™Å†Îâá÷ÈÎÚç…O?’NÁŒ§5LU¡©è8ö°Ó>—~P6ÀÉ#¼üÖ‚~ÕðÐ%Û3)©Ô*X¶°þ­ˆ/•ëȆV·°:‰ŸÇb©ÛÆÓtM·Ÿ¦+‚©aÙîȵ 3‡¹‹*úŠèÿº÷kÜ(Ú‘lžñ¬ŸË búìM«mZÏp¯Û=L>ÕI½žäZškÒ÷ݧÝ¡¯NM|ÄÓ’´V-Q튟0ßrDU+±ÓŒE×ä™ÝlÁÒУ5ݶ>iJ&Ì=­ªè5ÂÇ5e ´†Wdÿ‹Ò ‡ßs§MÝ#¸´˜09áʃòí~©7^]³ïÊJ¨Æxþ«™‘ž‡ÙÅßQ4ħOû4‹wÜ%9âêÎKÒ]†ÓÃÇfb‡¬×,gFçXéé80‡Zù¶Q^¢áðÅ?§ÇM ÒöظIA)¾ÀÈ$yeåÃÒ8–ÃÞé­Ô fl¾k—!Ifcpz°„COÄÆj°£@4Uÿ,-ßúê&r”ÀÑè#ú<7›\¡?zlõ£|©EÀkS‹l€h•I‘æ>™uL ‹®®˜,aÊxnï#ûs·[ʺÝÂI!oR®Œ•!8ç‰âõvˆ÷ñó÷†éÈBxïÑÑ#¹I—D»g˜°×+8š(ЛЃ³o"¥¿<6(ÒálR“ƒÃ¸êÜp/éÄßò0úUÍIh²ý¤m…lòTeñyÖN wr[âð½:mÔªÛvN{²ï©s ëmÚ RF‰EÚ˜¦ŸGGã5c²nÀ•úPbSÌRV;•'—•4Tv–gTøÛJQhxI¢šy"Ä0@2Ÿýuæl2gs9ÛÙ«6ˆ>OCZmëÁv;QíÍpR‡²†½Ý ˆfÅåç¤Þšeh·‡ Çªû°ze]íÀ¢e¤e¤bÕ£ãi¤MQÈ»——~#v‰hçj€Ë–ßM‡wWÿŒ»8é ?³à˨®éˆ5Æ®\ÂÜ)AaF…¥¡ ^ii­ª$Á‚ª.v³°jt°âKÁg§"z»BKÚm¯”¬ØN&O0ŽuQÝDZy%;ù"Í"göL–)Üi‰æcS|o´¨oáf%½Kå‘€ÕÉöI4ª|Öe½ƒMNæž´0VH“bÆT¨—uÔ&Fôgûñ5T8óí-ÆY< )ÍùuÍ@ŠwRjé”{P¨äš9 Ã¶’°ƒUÞ‰^¥.®™ÜY®lï–XD4‰ÊLO¯Öµ›á½0šAé™]?J^TÃ/HIDΨ0ßx„SùOñ(QÞ[Ô÷âʸÈo£Ÿ¼E4íå\õëÄp¤+¥Z¨T~ÚGRl>mžHḨhqÊ*iæÚ$]Œž:-Èl<±ž¸MãÆ{)t–4AY$ v{”•â=í@ytž€|Ï.¢0‡ßµyÂÎcjêúe™ÍË ÕÂp|eUÅq 'Ù›˜„M'Õ‰-ýÚ™"»½å3:dµt“çpï±*f<ì?ãÓ'½ñsI¿e ŒI ËEd¾Wläq '¯ó”îzN›—Æ ã~ÚC\… =AE5e)^†ÇY¸a‘7רÕ]_¤8¡FA¦'ã‚Úççb%Ùh© w@‡øfݦäçú\©×´È'cfþ؉î–rJC–ŲñhŸÓàŠUˆ#Zy7Ö5S;O¿:­Œ9€¸^éñ¬Î8™g*òÐ’°³™`o!õ©}SŒŠ㑈…ÿ¬³X>#Š‘fW›eâQjƒ!KÝ ,¢Φ$PkùF³’ó/z“ø="p׺ÙþYŸ¨ˆ âÎvâ âÜŠ»2 ;>{)¬‘VÌ-‰(`u…8m7kLÎzž\i;Ä•=("2#¶À(s'Êöet #3r‘÷TJæÅFçÚ¹à\SÖ\컬àqMýƒ²Qì¿_M¡ùJ§Û2Æm•L,ž0æë±~ÚF¦ÖJº[Ä<-ï‘+ò¨#D*Cµ¼DOÝO4Ú ¡{þ˜P¢[<–s‚aOÝøLzŠŠNÈökcÒZ5Í ÏŒÈHp 9à9÷~Oô±¹¿<öŠuUUÓ`E3nch¿ƒ¢–gFøžfå”_J&5‚ÿÇó[¸R“„07¯ÈànÄ-Ïì.9ÿÀ{͈šŸºipôSÃMxš©¡(9óÇ!Ém“Úï×n8[âØÈLwSA1¸‡ú£(Î*JPé«2ŠeÀ‰"ÀÖZ ”_Ýf(Gø¹<9À/ðâí‚9ã§Ö´“ÍV.R nɲ†_ýʪÄî÷¶…ïªHñy¦ý##tÝF¬.­ÇddÝ9xäAÙ‰M×è9“ó¸—`fV¨Š¦¬%ìÒÉØlCó«.)µ~wŸBŠ–O…(º»u\*‡¢É±CN,ÂÏkWýHá>zo4aqË ž3,éÐúç™HxœË¼w-6‘]8pËbÁíÕü’Y–[d“£$´5f0ìy豸_JÈdIÙ$ÏúëÔÑBI´¯I8KƒhíûÃ+m!ò ñÞ9ÉÿšXŸÖ)Þ“ÑÀêOQg$Ún`½åV”ù×–%šÏR°RÙ¢t´öÑO_z)ѹK[¾¤&ëQÍ!ØH}'õ¶ûôý;ÅÎÐu!V"i ëx™6ŒrƒÃ9>29œ¢ËÊ~ÉÞ±M†¨#b£UÍ•BnÞÝÝ"¬[2[JKZ9™¼WJéäu~ÝÍ'fíΙg«GüèJŽÌ!}ZnmgpwE›!3OvùÇBDZ–;7§fŠ•¤P÷³,@àC/ÍûçëåïÅÔTeÄ=GÂe!ž«?h¨@Ñußg¤,?æNÈÁÓÍÄö*SU1@mHSn~17ŠG­•Ý%_…>!H›Ìb\*þºyyÕ~vÅÃÊT:FÓáA`BÛÚ-”]Mø`­Ä i„Å¡úpg\ì¥"¿©ÉÒ÷¸I×pTbºh²‹_ Œûµ¡»º½ ö¬ë¿“ò¶éåÞwà§õ¨WŠSß‹Ø+˜Í ÕÈÖk³?Ÿ½÷5”X'!qn¿ÙìfÝ7ˆg3»‚0"oÛmerO¨V²òöë ÝëÝÅÛmIœÚuÛ^¨‘Wk)!9Ë´ÿpÓ;hÔ†Žâf~€Éoâ¸ÚÉê ¢K-ZhNÏ Ûë0Ðf•…’ïÂ’­áî‚õŒºŸ"õfªx—wPÎ.tÜK€!…p@î()¼ ’+2Á@ËÂwŒ×3N<ˆ¤Ûl=ŽTfPòïñ‰’+¿¤vw„#\ô&³ôu ÄciëUß ·0±½f6«÷.=yÈZN¯ù Ö˜?j ÈËËÌÙŸZáJþup{=3Gwß"û Hçàw»X+.ëÆò§ª²Ç§TBu¼ÉÄMÃ2¦Øt 9?eGùEu 8JÀŠ/{agíuĪE !—¬nѰ<ð cSçÝš2%1¨‰Ó·”³jMI†<Û7¶ú ç—#?imïÇ9ŠkZ6æÇÃ7ù"÷¾À»TºôM•¬k›ÅG\¸+1Ï×¶²­Ô6tSgΕ ñAèzSmÖÇ^K±Õ?éúe-…såŸÁY+Fš|?ç.¶|6|™9¦¥õžœäg ®ŸBz¼ê|Y[ó‰î$eä¹Ýð";CÖã8ÁÛâjyG.ÒGÊ´ .#: øR…¨W­@\‚?‹xÅk› ½>Rg‹åÀ ˆ×^Á)îA}»è3h8$Ì«ýV3P}„Ê'•—ðú –ùø_Ýí­I!l 2sFw™‰ôÞ¹JúUiâWe£&î7—£ÖúYkŠÖ;^dÃ+Ž­’ `)J?Té¤8€²¼‡ º°ÑTÜ»¥w‹å¹å´*C|=I⦓`iJ­äæÑê- [ʆ»ç ×êâ ’ñ»Êñµ–a&l¨1¨ýK¶ ¡Ò9°m+јÎÔƒØw·û‰HF¢K ]ë:ëýãÏÖn‘êT³‰¿ÀÏ`Š[g¥gzPιL ƒGòŸª+?cô­„ÉYëðKľãƒt7tÆ¢lXåûK J¦{ûáša òåŸÐzü9¼âl‡2†õ[}OAyËýD¢¥8¨ëy÷êþ z|Sh::JC“b®º6Ep£KÁ¹ºçgªì½Çõפ‰ Çéι û]¼ç¡úfžTºÒ-±;ë—,Gs‘¥¡¢­$wsn |-ù .•F³›»[·€S|)¸Žš¸”4M!}cQµÖW"Œ™þ´ÂùÇh¼3Tã÷ã ÷†›©œU³Güö<†„\D‘0¼jÚd…ûÆÏ~Ìâ’þ£¡Ê:ÚAxöüÁöú H­zìSÎ{¤U&þ=Zº ¤§ßÆáÖN;ó´ íާ1ŒÞ¤˜Í8­NåàTQ¶Ç¢“0Š–pgÆ[>ÖúôÓ#bÜZ…L"°DºMô¸»+mèqМ_”Ÿã™Jšº¢ ·ÌXT¤¹¹âeXÄ«„íÑ´{´—×iL.>'ƒÙ<+ LÇä,®;[b¾]NÆ1ÅÄÜœ¤+Ð0Œ s,õÏÿ=jô+ÍZÖn¨8ø·4š_KE'ùH¿\00†¸TÞ·ªãŠE‰öJ¹bm [pÆâÚƒüâ—Ü®²î¼eÚ{kï +¯;½3?xÝõÌü%½¦üM§¥AΞ]+Ž3¾¥‡OÞ:Ž·Ü[©³W6Ã5ëÔ)÷°eܦ6óˆˆè(ý齿ØUmÇa}Ô†IÕ²ªµñ4£W­4ˆ\Ô‘ô±~†Æ„$æs¬±~»$&Òl‚=^­ÏÆ1ßJT"Î>æf„~|ëö¢~ˆshÿüÁ¬ÁdÌ-’žå°‚êœ ñŽ Ý&Ù N1xækÄuÍÛ¡²$ˆ+¡dþ£2W¸À][ÍWƤ˜z©ª¦éY‡’5YÍ™v|3¯Ðyã—nY *‚‚ŽvÚ8¡UÝC‘dR67Þq[Ý{·³>È‚žÏyÑb‡¢Ž ~ƒLs r÷™œÑµN0-+ØÅ÷“Ü↉*+¬“>M‘D‹ °IT÷L¸]éW׸oçÿ½|ÆôR®äy¦Y‹J£Nf^%€Aò(ι}9”ß ÐÉèD{Êð̪iUè¾À1[&rþ’Uì‡kÑñ~À‡˜êHÕ–àÈ]®ãq3ì ôX”÷k³½=ÔÛ¾øÑ‡\þ¹Þëè–{éÍÔÒ+òsR2Q­‘G¼¢´Ž•™dFù×å­_T2Œ­îâ;_´µ*‰O('TÆ»1äôÁ@ÕÕRþ»œÒæÇݺÁo>ÙŽeã˧2b6á¥ÅôqëŽ$Ý tïK‹üMƒîwQ‰Ë`Zߢä‰í`TÃäÊŒœI$b1l¯ º7!cK-H6¢íX‰d¦² c6)Š£l¬ ÅW&ER÷# ]›xw)¯3ÛF‡l*êì(è ÁR¯öYÄAqP©Lq-p¯òo˘Z‰`<ņíá„hãD³Õ¡ˆ¼* Ÿ‹È˜mA³:ÚB™X˜ÛÞÔ_ë1Ý?¿–ØH¹æcW(=À̛Ù½ÖdÒ“EsfãËMM価¨÷gwÈRu±™“‰/†^ÃàÏòóyÅ*;?_=kn8@³”µÆþÄPq_Љ|Ï\H+¬˜!û¶£o_/z%h¿¹t]É©85”ªÕP]¶¢b/°@f%ÀVÙ(œ³ Üá%ìzFÓã·‰TLIBÖ‰ÁZû Ãpå N ÖX4•K)–'ÒÑ# ʇ(¬¹Þøzâ@TŠžV`™Í_Ržau•>„ä5ó}JfkAªí…áUÓ䨿?ûMs;ö""–‹‹w1IüÛlèz•ÐÈÿ¡Ðï.¢§]xË+–>ôuÂ4 lùj¡ô@x÷¬$œýržA*zKoPÝ\z“KcG’ <˜ìۥ܎ª•Ô±çÖ™ýiç_ÒÈ­ŽÑxN“ÔAKVÈ j Õ3ލ„r.¢‡C0‚wK@Ÿ“`>Ú]ÜNêœØXîØs>ÔªÓr»ë[³þB5QË i´EüÜ5uì/9w øÇS¾á¬E]`–åTÃI÷-Càx0œZRû°/ÆjE¤üÒ¹ÿ“ÆaIN™12¦òäC–³O¦;Êÿ#½F=2tú.OÛ¹M%¾_Ä‹&÷Øû-öý”hÁ~Øê¾_y[ÉÔh®ýàn0枊>ÃükD2aÝRGý×Ã"&@GÏîñ»0T¸·ä»j›‘n‘[8܆Ms¨j]÷’?H¦õF:Ê…þ^¯žÒV5í×~­ y¼ŽŸ¢¹.@  É¼.xiz6haüì ¦Ÿ¡J@y˜(ågîuÝÁš a=ξÓ"iÛKü%@̻قƒ†ÈO(4S:1b0ébQ‘?Ô²á›Ò»ZûA´PÍDUÜbRæúA¿àß—­f½k†Ç9Ÿ58^!ýûö.Ÿ;•y|„ÅYWþiûƒ~üÙ3|†œ¡P˜ü¤1]Á?Þò¤+ÊESÄ Öt¶z~Ä·—ɶ¶¾[ïa-›þb8ŠÇ S"ÔÅãÏ` fxE ®‚³ kA/ (Ä›iðZûµ ƥ̾Ê2@¤Ä4¼óOÐfó˜?`B•eÞ¢|hùNé¡Éð¬0°¹±‰¼·¹Ú­'×’IzîÚʱØhÇÚ&4ƒŽ ˆœôN xÐÖA7ûï}Á=RJo"¾áºÃøvø³bg¦Ü¼ÃæX£ñˆu®‘é–Ì0x®@•ß.Õ÷c˜VºO«°@¸{rè-ç=ºg¼¨  Ò¥aŠBW?Ó;ä¨ê <ž ‚õŽD À—¾!A,ÂÆ#-¿én±º%VÔO]é¶¶%4W€^Òë-c3i’©æåosÖ *p÷œ(¨èþx:Ú‰‘#±;*ÓQð6j{ iËMÂÚ¡^åáÔE$}9ÿZN0E”LycŒþ9ª#-ðͱGLUÅhoJOT¾ZRç¥O!äJÍýÔÓÓƒB¾°‚CAçÆd±_€xÒÿ•kð² úëO…0ÌRô;!×±dÃWÒlâ·l†›‰5Í\ÇÌ7áÜ÷þEóžS)MbÀ…&»kd[4â›ôp½;–:°‘z¡Ç3Ôù½ÅŽÙNiôS ÚAÎïY•Öòq“UÁä¤0+ååâÕeßघv7¯Fy³²û¯§ÖSáS©‚uדîË ˜ 'U¹iÄÜÂC*Š”ëÚëÕZŽé=i´ššÐ¸/=/¯Ý¦9˜¨¿ÏêåüÂŽÑAji¦ùf¥õ÷ÚYÀÔ;ñbn–c?0ƒŒjMTH„,À±miY¨ )´ÎeÏ2¿¬¨4Mþ•‰—šg„#rN–Ñ 2ÓË¥Cg*‹¼6 A‰\åD}vsª  į+yI©£®£$ž6·k‚8&åœÆ2¬8­¤Ç¿®«à }’*èûdH¸PÁc&lŸä´ô¦W)°å»fÏ‘„±w‘#õÛ 2 Ýôϧ%‘” z>èL{D)¾¡gÎ"Þ¬¯3† ”†îoÞƒÊå›ã§oàöàÔE™ÜuÈJÌÇÔe½ü¡—_/@&[õÁ;*¦û*÷&„n(ò(oq,ˆÂ0e,U`Ÿè±þ¼ŒØ’±Þ:üØr>ÐŒÖç·/ûÔHCEÍ;9Ø6A&ÿ Eø6Øì|• ŽÎLk¹TU§™xõ5ÃÂæ´Zd£¹XI¬º¶êgz•(×Ç÷—H`f³U…V'‘ ¤*"`'ê?ôS3݉úÒ’î[6ú°ÏÊ)»ÕÏ~K—-–§àè‚ ¤)Z½=Gëa÷—F‘æí®;mg®AùÅ[­òþ^g ÿý”ÛÚÿ=Òdc ۛ˿Å+•©r4ölÆÕõ˜Û â-"Ñ0°«¡ksh¡ÎQÓGúî`º™cW8GJ $©»Ô{‹ Gl…Ì,z¹)Kž<àI•ye@­Q¿ÌÑab ×=xŽ{-P|/à‹î²èÍÂò]ͨ;†×öàQ¸6‰H£Ç5§(3gcçT2°"“ÿñ*¾.)!@#–MSØöúrD:5sŸ!¿ß0’¬ø¸q›ºæ7Pá&å(ÓEàkʼpÚV'ÂÐ Õ¿ë2KtA¼ýnìÇ¡ ¬¡´êZ‰%dCQ2‡è* (¤´y^øÚ 3ë ]åˆÞ%^§š_Éó\`Ù„°Ä¬<˜ªbÛñ 3H|§d}Ú,ûU¸¼|{Lš]å7ôb¦J ("|Öͼ¼¨eC;‹ºêRO;]óšÅct¶m`ËÍØÃmȾjÛ?k(£µQaÔ¤ê7‡ÜlÑ›$Ð*ó˜pk>~åt¨:кk§Ýê(¤I¢E^ؘ>I² E²”Æè%§;KÃ9¥7Ì:J÷ß_›m© D)r×^ ê8Œ1…Z“‡ÙDa€£Âúßb‚ã„°ù:m Iu™ôkи½†ìÒ¬(Mr1ä2#j®‡„zW8 þ¤]ß\-°1ô¡@mü¥ßÄÿüºAêPè0»œ$èŸJfЍ“e èxÏy< ¨ãq˜â¥'.ÿ_~1iWQC¢fL ”׎k0|Íæ)@ÉÕ“Tý‹“±ÿh‚–»V §°i]¡úV¼{’ x6HwPºó6\ü©p¡‹{b­£B‡zG×U$éÅŸ=YkÊ g¬Šõ~þŸÿŸeÅ_‚mÊãÏÇ}6êNDvßshƒˆ¸_É6jÈ8CÆõKq'þ¤›U*¼XOÕ„×­¿^Ò$í™NÞú•ò<ÒVö ÄöRLQ¨‘i ÎIÑ-,ÎÝ8Ÿñ? ·{çöxe¯*Õ6i —“tßÇrï )¶? ‘dU7²…ÌC{ŸŸ?¥x½1æjËãt¥'È­[‚ ‰òUÑ©½Ó•çz”¹1LúÙVú§ÁݽwÒˆŽ]Z‰¬hèT9•)ÕãÑ(£ A w· „»lý†XÑ,ÏTïÊ2¸çSŸÂÜ:E®Â•!8UqÅ]ö"¼ë² û{$Û ÷áã³6pþ 9àB)}‚a‚~ûýKȰw`$qÕ-¾šó±“õ;’×ÂÂW\¸D²(ç·D41NCCQmYæø—:yLd²‹öÚ·-ÛZØ·(Œò4Œ .þbü&áà›%xéud þ3ÇŠT†wóòïòA h» {‹N•ã³î•˜FˆÁŒXu.Ãä çív”è}–u ` ¥¨Ó¬W)p†=_–ORx³aµx~‰Rd­hÜaqº“5K+<7–œj£ëoÊ-;þ«~ºÑµ£„ƒ—”U‚]ÜZÍ»š„–MWË\f¯nM¥üýƒÑ­Ö¼ê Å7¦ ›(‰¡0ú m;Ç áD_ÜdnÛ,؇Ǘê Åu+9s\tÒDBõéôÖ«œýñp)Ÿ€Dàåy«¢4 × i7ƒ¯{%[ œ2@2Æ<53ùhëmu‰y¬ýfâ¶q!æØ„Ø?xw)^Ç ÌÞ P´3ï3z¹œF¨ît˜c. Er,YS8ü-¬–XœL |¤¤n`9‘t£ÄÝáé@|j@ƒ¬¤xNït)þíŽuñ\ŠùÓ— 8ò2ŸÈmšÍù«M%ÆäV›’"Ëi¿T¯Ò„¨ÐPc®±Ãv|˜×ûXÒ :€  òÏEõŸ{þp“ms¾‚wŸîn‰2è>]½,Æ^D`O­¶4ļëµìÐ~šœ:Ý‘ŽNÈkÆy( î~·bò¯™•¡tac0s$êàNŒYÇÐìn8$Þdô’;"m»I§†`.2‚*ëº~ê=¢¬z zΜA¿ïy²ÎçÓœ„÷̼±¼SœÍâ]'ƒ$/5îܬÞ?—(îÂRMÓ¦˜êǽö÷ýFG$AÏ9£:¦*Ø\móëð‘¶OoÁˆ3žúÑɉû:ïgS²½?$÷–ý eáH„‘Þ¤Îܙđ¿Y8CÇp‚‘¤¯.W³(õÑ´ü¥°ê;0O”ΡaŒJ5ö¾ŸW<"›j²  –Š£8«Ç–œ~Ú®¬c(ÝÊTA)aø ÀnŸÌR_<š'@ £ò Ö’7¥À]SYæYs·E6§LÚçü¬×)ã4L²é¿ïœ^~ÛµÇ& "¡&Žè µ5ÏT¼|¤ Ý&ÉÖäýÕœNŸÕ'L¼Jó²È"Ñ‚¸=`ülXæMæX%ÿ+´ù¼l€< u&hÓ£žfõò]òäž{_»õ 3 vÖ4š£ïeWædCVÚ¢äÕ†ŒÈ팯ýLm :Œ¥<ñÈ>î0{ÆMKyÀûظQ„Ú—ƒœÉûgêV¿øp 8…N® nßàS½Ãæ>üܱ€}ŽÓD>§FØúªF­Ûx…m‡:(©¯¿(ãûƒ×6Sv›…|_4´Eg^Uþ¤”F! 9"ÎòB,4c^Í(ÎXÕXCÃnøZÒᨽ2û¾§0¨V kjb;åÝÑ 6hUÄ—o"v¬(#©ì²£ýð´²Lõt¸·ô |:ËÆ·Ð÷7QûV¢Z.EJv+}èÛÙñ³·Ïë$4D£V‚yw„ UäN„xAž7¹b•hÃj‰›°Ú…EÍ,¸Ð<áãòуßGì±âú[30Åñw,×x[Ìá0ö¯Z&-¦xÇ _2¿p›ß±ù]¢¨¬•)8æÜ@kL,㇌/è 9ô(0Œû‡ÔC¾?Vñ$®­‡[Õ‡DùP6>[ðóÞûqÆùTH[:c†ÚÀè!Íý×`؇¬5)qi+n¤†Åï¼¼=$õ§Se>Q¯æÃ Í ç¬Ï»õ@¥JQlW®˜6ö4Â{ë…˜D¤D_¶¥qnEµyµawao´9D_F‡D¼S(éb]©kiA#‡2 hgÊ`œ±´;êâ¿Í©Ì‰*nbeª¢†RøÇȼ8z'~f2{u_ÃQ/Ó€|×i¨! ˜L½õXÂqb]ÿˆ_ãâËTžé­L£5ó¹Qp Y,£œŠºšÄ`Uý¨gVô.('NÒ§‡Ö.Ö…†_4 ù¶˜Ðã°Å§HZ¥ÅòØ@hùI^ËÕËx¯`OÑO.Žjóp‚á=Hw|gÄÿHzÒüDŽ ôQy宕”mZZ–-àâAÒâ>Çté9÷sÔv§ˆš³K/Ãn®0Møö'{^¥X|¨W‚r¥g4sbVƒœ­±¯%_øÿÚ-§íJ@ÙÆ¶“kŶmul;+VÇèØ¶mÛê8éØéØèØ8ûí~À};ãÔÌ—£j¾ÎFÕ<É $ *Ó®ð§üHWaï¥Q;¶ y‚»S?¼ËžN|V²aȯÊFáp)Ÿ}ã¨H„ ·ïyïȼ—,%ü£} !§/Ú+/Üz¾œaƒ\‚ðý±•Û«äüÄà V¬k"Eª×°[(´]6‡ (npáÐtsàÈô€Rè‚ E0ª¬}›¡Pk-cðqŪ ðc\ç;#Õa¥p×ö3/–#äEžU‘õ•`oÌ…‡ùž?I5ŸžºÌìN­Éªÿ½ù³™¾ã²=|®žeä.Ùù™tr—7ÔÄůc9¾ßÝðq\ò­q+ª™ "Q¬* Bqá¡è½Cg© óTƒX°„{ðYÔUmQæÄljüÿnbaDœOà'õÆ™¶¸0i [ïX¾>{®L{=®¸ÎÉB÷êKûÝRöÁú‹Û[Îî$ÕoØy3&‚pÙy¼'¥€¾dqkOå'u å%ÈÏÛ:(±ütÐ5£»ùùŸ^3'D`åK›šêkÐo‰ÿ¶óB³¾|Ñ…û÷UE´ûÅM%ªhöÖÌ9â ç'w±ß]· Ó-Ú뚯$ËôVc:£NÜcCDôæÌÙŸ…Ž›ñ+•mèçXe€ÒÀs¼EÞU8DBaí)ö’´¹TUhnˆ _&"UÔüר“GHX¸Ý9Ö…?ÛHË·ø®Jß%§ÓjpŽÎ i‡u<ÿç7T©ö‘Û9âüù|‹Hõ]q]g`¯…<¥ÏúrƒkÏÜ0Ë]>Ç 7ï)Ùbú†ýP%äuÞßZ„¸Wü¨ô¾êâò }sUýK.°õV̹Сú0M'ó*_÷l¤‡‡ E’vÕ7uUîO?¤ô1¹øj U­çsµ -xß~·h(¼\˜.\ñud/o}h?äÌW ÏžñxOÝáH>)hÆ(I?^$ˆ!øeå°­·p³s”@çïØ.5šü5~Íç}”c©ï[Ê|âqD#f’…x~~lÈÊ™âòÛ Üá‹·­³Y*è•:ogáEEÛ¯ Ìâ” ›MíQBiÛZ*ɉ܉D,VÖnçB>÷5}¨ÙÍ›Hç¬ÈbÉõ(N¹žÏj~$æ'2mòprŸÑ ë`Pº ó„áex|Þ|‘í)e$ئ„is…ú¡hAÐë“©jÀ‡”S[m'`‚jQ8gÇ/bE¬¿jÛr•‚Þ¡ÿcEI܆.€±nð”Úv{÷6êrÕ„AÏÐ>xü«TR…-^ŠÕ·žT»°&ãZøW3Á•”ý”Þ3Ьs ¡Ý9o?ûÚþ¡äïV³ &¬&€s³¿Õ§E霨NlÅ’àQÿ%Xœ €äÕñ $CÊd+}"ì«LÄå}sßøDëì|CÀJ9ÚbCO¯…s&@7Ø`#ô¯ŠíPÐ¥S•Vœ~nœ|a¦+õP × "$šB}'Äq¡Ôª²ú‡ ðÁ[Å¿u–Ot8X§ª…r§ûûí¯gwfdº½‘ñ!¡×ND_ý²§ðÈ;-ŠcŒz¨™w2?9<†DÜGvð n ©˜~Ž»)ž!oƒCkNâÅ«-Kqcé<ÑÍm˜Æµ1ŸY;ÛÙC´Làg¾6M$_ñ¹'Œk-øÐ×í¶“³–C=ÀâiLVÕrÌìT7ïɲâòDùüÆ-kfàYNC1íúl;^yµµaŽÎȸM$^Ñs—Jʃ ­iùµ.öÆ/ ¹–hn‹ª¶ªû™]½‰ë“a*¯â¼¶Í/æ%¢ßüÉ'ªJKºåØ+¶¸§³ê°`Ådònä¶1égx#ÉQC~OLÿƒGúÈ\ðÇ:£eÙÇG©]/±ÿ[§oÜ ŸìâžÁ§‹’[ ®ª°€åLIšT3D_Ë‘áŒr5MbÁ©XGIçÐÎÆžl¡[sH¨Ì˜³© VÌ\l^Ò²GpöÓËÿE-G”:&}‚ÃãJf‰íBÒÏRBu¦ÕLÿhðzoÇ[ÙݘºÿÅQPùN8§NÙ‚1Ñ}gÛNÔCÔçg‡Úú÷¦^ )Û»\¦˜ òÐêv¤òµïÿ“Z¼87f½8+ ¡”c'D­ Dt[ž~;Nd› YÔ Yäú»\¯½_¼²'σýôž“æ_,õˆЇnÿf@Ù=ÀìØã){±ì i³—¥ªFÏMTäiÿÅà[ å`€X[MA‹f@yŸ¥›ï$Û»ÄÌ&ƒc œNšâ|Š1³VšÊÒDjp#«ºS€Û>׬¶–í—¨œ õŸxAnRÿ§€Ž&*ÌPÕÖÈ]@˜Š©PtæGŠ ¢"*3ŠcZn]ãS EnêHö'îéÅË|¨ßô ê ®ÔàgÏ0fâ:×Ê·­ÈšøßñyºÃA#G§•Á ŽF¼¥ìQ ø³v›OÈÀˆÐí«’¼n2ÏØ1½¡^·råL1r›1) A} —bð祺m@/>®³œT“sª*++óà”Áró»¿ ’!È…­~¶U*ëj60—ñGóß ÕµN¢c–dHóþsˆ~ž›‘ëm‡UÝ€…¼† |ç5ã´RMtÉ+áw—>S$ÑÕÁ×14¾UB`Æ€’êi\d3ÉXu— Ñ¢" 43e(Ú aŠ:ÝÕu,Œõ¢à…oé*RÍÍ+Ç呆.LY©§!GlâcG÷r£­kj$ ±£¢A«*…7(QZÇ‚|CU²øÝcx²ÂeØ•³'i¨¯–é÷s=à«´pEzÚFùHâ`°:éÌ}1ÒÊE¹MÀY¸@§¸Ø]ir9Ïz„ݦtØÙ«cΠØ˜{5ÛèØøà°ÖŸ‹À¤ñJç$½‹%\ˆ£Ip.—ó§l‰ùñc Á,îŸ{/ -ë¹’\ìïRGò»Û\Ä}&­ OòcNs3wñRãzúzoìí~þñßß#*[kKá×Ó@¹,ûŠL¼ŒŽŸSÞÊt½ÁFA6b}Š8|¼ÙEÔü 7+ ÜæÝ¦šSËnkoõ”ê"¹ŒkÒìv-…Ô’òÔQŽUa¥ ‰»Úòo߯-‘€Çð¶äXùæ¨R´3ÈsvlÚÌ—x.ÒlP¤u-B³EìE仕hUQtW®dÊvuËÙ`SfΞŒÇ­ìÞï%Éžqd&± ™øhRu È2#tdûÞ‰å<ÄÑnõõE9Œ^âyn3Ä{uào~°¦¨•‡jN”ðß<¿srMÃo—\Õ¢Ú`Àòªs§•,bá.BíãÍ b(ŒÐñ•DíÜÞ,½Zpç V¸E>³Å*–ù‡Óu8µ^Ujë@Óz/H«¸íÜXÿtM릾HL'·‡: ,ÍÛd*Àߘwþñ”[¹ÝÀØ[Y9ü±—8GRrVDWª*g:ÝbºÎzÜ£TÔC`½>žeÒ8?Uûù&d$Q †C‚tyˆ³û6Jã à°#âAOµÐ"±˜Ôu@Q:K´xh:|n¶;J­yp“ÆÃÊÿË­ÓgùÛ‹6âÃm wú œ#0“ôŽ Þ¯®ûVNƈñ¾ZT½ЇDBH¹·2Ÿã¿Ékõ›É_n¾ØXI&À.«oôö;U?ÿ~$©xËÄ 0Ç3Iâ9&´Ü‚¯¯¹j`i™c¦¢aSسŸÙ›ˆ†¿Ei]ú³ kva“ìÁé/þÞ< |Y“³ Ñ€Ø¨Óeø‰ø‘°Ap—ê1ÌZ…D—Ѻ(P©‹_ëD°žÞLÃÒ´Jã·áu”Ŧ¾M’®ÈjæßçÐ…ÆËÙÒ;g@É'¼?—[’ÎéÓ[6ÐŒzpó"½¥~Nv‘‘®úe)b3p]s,`L•m¡+ø²lñtø“á‡çýd«Ü‚ÄY˜ ‹1ÀÎhS»ïy, ¥¶X¾%ˆ`2j)s‚°N,u»ê!³±ö ‹m÷ÏpÕB {­lR±¿ÜO¿¢×Ô͆d3³¬ ¹4ÐUðŒL 8a®|…Æ6ܾ0#„蕯tkÒR>hFb•¤ÛEç;MUÅÉo¿aì#xîÙ,«hŸŽÔ¦Ã!ñ3ÆëKyâ+6š DzŠÖth48ý¡2¨x4b¯ SL )·¡þ…¨¢ópHT¯‚Z¢·¯9µ%ÓÊW¯îºÏo.Ô÷ʼ”bpgRE¦–žíxÙ‹_òjCP­¶½ó(Iš¢˜ª;EŽÞç“ä1² ¤00½4Dy›Èü2Ó¢¬a%|û>#5µ™_·ªDkîE¡"—ˆ5àz5·®¡h"#‡&5wUc®°¶ºJ`§øT‹šé±3‹²Ð¡äôà>Né¢X™î]üÂ!®ˆ%6þŠ¢‰,sÿ-ÔKˆÛ„¦I…^2vZ™ïÄCG‰B¦ÃCZÐß+5¿lÞèbMX»@k0aÔu‘ÿjãÅ®ûe(¶;\”  nïÈ$óÞè˜qù+O¯\Œ¯½Î%}åÊZbESqä§›ðyª®§Z×€3^DB¢.õÊæ/ ‡¾+3`©ä£É„4ÞVDÝŒý4ªÖîPvžBÜ“õµÓo{ß]¡š’p^Deèé1Qs6 ]†>ÕÉ'lÛCïNB^ÿ[•u•Œ²&Ÿ‡á׉GîÓè%ºJa}ؽzXK'ؤ{&2ç¹÷•ëjº²Ü «wshî"Ë©ÆmiÁÁÜ;Ð Jù°’&+YR f²Oƒâ³ˆh€ÝwSJ¢Æ×ˆÒ"»iÉ}só¡°L;‡ÆB2:ÿV]ºmÕ ]ó#`׸³°kÍg”Z¦æ² ÅYÜ!T+ ¢É›¬<3¬¡?ÀKý¯äæâæŠûøH(ÂéÆ ¨Ë“–}>©ïác€:èªs ‹.lB%±½ ¦’¿û0%Q$»–:ä¹…P\W/etCÌ:ÈB½üƒp–ØQ²Q1Í4 ÇÁ3€¦P†êøøc¾£Â×}JPž’ZÀÊ<{5@ ÓB…lTå>󗯱ÅiA*„î>`ìøaDÒ-^ƒ‚˜žPÝpTý;uö׃á3ý轂(æ¸E' |·¿ë¦°¹‰»¼´! í‡ ¾ú³q[·¾B‘sõ\ÈE[ȹcð€!T2ˆ3'ö#ëZ^g7–Ö††.›('x}‚h‹Ì½½ŠÝän T‹Ê¦C€3@Áø.ëãïÖå£ÍϨ\=¢VVÚí™xt0Æq©Õˆ=Ylóç‰Ë¦ƒk¯ãtÊâ°Ì¯/º±Äg.µÐE ÕL¥ô´²µé•~›8xîÈØÜÒù.àÒ"§¸‹áH"^æ7•XïŒàå…aËúì‰î$–ŸD›âþn»NÝ F»¡á=Î35ê¤QÉN¶•ÍŸDXt»¥æh8µ†u“Y³ú³ô g í¶ß&º{•diQ½tç÷_ëÎÓÆ¾ƒv€X—dE2LoÏ·qäó¦VéøAd÷ÍTÁWŒ+–c5Žú>JÓY×éÓ¾Ÿ7à”o+nʧU¶Ú0ñ†æÇŸoõ?WŽýÆ! oùæ7Ê Qßá‡AO2]–‡˜kÇS&HqÍ¿IR²vyi¦¥ô†²ìó”Mvj¦*WKq;ÕP0X=#J[ºµÕÃqùH.´Y.HúlÍõ©Õ¾&b – ;vA}€"MÜäñQbMQ6TÀ(ö!]`N[ ÜAî!™äë»oŽU¹ÿ ­»a7•‘¹°}VèKÝÚ153® s›ÞŒ|m†Ôö¤§_ õ_sp²ÉQbZî¹Æ ŸÞ¡Àm+ Å¢ÍPÓ¬Ói¹¹[ÁÒ›R2¨•ŸŠæ°””hÿåÄy‡4Ѓž [kk sC 0ò;޶y­sžØØÄâ—”&UÇÓ‡LùkXDåR%õÇ­b‘JµP„܆TÆ­)«…Ðz:±’GjwÓ-2ð[‰«§U½ÅSÙL5µ=ÔˆñšX\æÉ™m~C5ÚÜïR’ÿú+ˬ¯àåþË÷²† ‰Í[¦ôÖü«\ˆfáfؼGm¬Âæ—–BÝ= ã§ÅÜf|·jœÑ ½ÛpÛéT—…’¶jØúwåÊB ×”” ÏLÿ¥˜Qy¶¶Åä{C†±ÆFÖÈŒ¤'í®LsRU Ïà´À³¿éu:<¼] ¾ ½u×"áB€K=‹º”¨ÁLwû êÞBç^¦Ï8ßaη3S-]s ÌJµ¾QU&ï·¬œcSd ºùtD6ð\&¸œÝ©NõO)î0bãQLö?2ú2ˆRH”q×å_ÇJ‚Ýt¨! q¥ä JNõ?=í¯æ Ø©‡'Ã|ùÍ™–i$ú¿ÐÏCó£•8Py½‹Þ0ÁÒ´çi:˜k•|¼°gº<Î`*¹Ý¶‡…RÊÙïGÛ£§ˆcÑ—"Ó'Û"„¨q:ŸJ%2©û úHínüåȱ{ÄÞÓ ÂÎïÉ#Kfä’W2(0-5×#ãÎ ÚQÃ2ÊîU4üŽLË\üº Œ,M*v_‘‹]ÉŸ±©ªÚ"ö^ÔBµD!íºàWvo@‚ã[àÔ‹\ÊzÞë•éŠ|²~Æ®·qÛ¡<ÍJ…ž|í_bhb)-‡›u•sYQƒ§LÆlOâÓ¦µŒ–@Q£ÒrÜ8±š›PœôêÏœÉ÷yŸ¯ù¸@É”Y„÷(»ë§ò{éu¡ßƒpï’‚«úá)ý§N«è•O¸„8ðv•?&ª’Ô¤‰#é[wê’ ¤_ä]ÀÊýR2õÛ! ŸôÚŽ`æ\õ’Vú¿¢ ¹P·¥¸™Ã¦s )&¥^¦ê8¹r‡™c6²å™#4ZK.F:#µV=–^Mê0¹ ÷È üYo—OˆNÙ‹PÔÕÏt{+UÈtNP‚N&ù¬FΆ·h™ƒ›‰UeœGQÙ „‹]z-Á((¢ÆÎZT²e×tWáRò/6|RÌ*xç«íïpô5V+‚Gý¿ÚèÆg:ú_X“K²†3õuaØïTYt.då¹øÌŠVÕ…XJz~½ºãî«É%Tö¯ÙØ+1 Ï—ãùN`¬Z³ëBï§YÝ[¦Ì)â–8ï4â¶Ó ƒ)c¶}‰‡_K„¼Å.igwqíõãퟛ¡¥8ö¢4u)òž:åÿÎÂ8© >I½,r›oºvãÙ ‹ãÞaÎ {øêܰ üeüÝß}½”7þ´D®WV1îÕôítš‘ú3²2ßw”nOž!%¯i¦¥˜4Ðr×ý²©í~DKCnRøé÷ù~`šòÏ­±Eê ê»ˆ”–8*á¥G;TqË':ìÉRNã¿1°ñxJ5Y‚—%ràÀ› ¯>X©Z•²Z¹´ú5†Ò¼gI¹#ó‘÷™J“Y`ê”úfñÅ^·(Ù¼Kq¬n¹ùßà›­°]Y[ZÃõ.¾œhЊªœúš-X·‡š ̧±QBð¯“OëL¨ç¿9P  _߸ÅDœ¤ùä ÉÜýw©üËm­¤xÆrÖ VÅ;Ôœhÿ¦‹(¢ÐŒœÃDA6{”ù¤Åuikr‚ÔƒàÁÕí©Kßx–*Š_ƒ… ‡ùÝR®G”'ìœXħÝ3©TqÔ8¡i˜õ¯¬~’{¶ü&Æ“J©Áqê,d,Ö“CåŒÈôâZÒ~€)œP‰‰8bÊ»WùhÛjà9³V'YŽÍŠð|+ÔŠ^n1êýâˆGx§‡~ÃÛòD=T?šÆ£ç×p¼Óƒ( æšOŒ©›Õ“Óý$\¶\=šS1‘•Êãö_|{‹H¹-­1ƒ¶ÎePn„ÈN-fBñ}ÉþÈÈ‚NlgÊ:”V€½¿Ð¡D¿`§·,ç6oa0f ÀOm’]”„ñò ujWÃçDLÛ…šÃŠK¨~3mîÔk:»œþ £Ÿøs ‡˜BrC˜FŽÓW»îA) žgœ¢u4éIm,ÂÇ‚€·¨ë¯á€x2v'"P©ŠÉËï|àñ÷Çž¡ÔÑ”d_ȤlWˆReSÅÕ«Ó¾n^ïrøSžàšsg˲Ý(Q†»ê[åÏ:Q w´•ñüž¼Ù¨TÙ‡ otìæRûrèþ'ß ´¼ â_Zñ‰ ¨ejü @¿F­kÀׂ»íoŠô#K„ç³ê}ଠkTwšálaáy±ÇP—pvF¦»iÊ–î/Í&'Ì®ºevýÙå¶P/öFaUJЀæ–^þ>w׋t€É\üþ‘MšQiÁnjq>¸šl×ÚUÖ«ý-6Sê—4œ„«†“ýPµŠ,Tiç…ãÙ !¹Ä~½ ¯sN%k•‡‹…t;&[ÆÒ­<µÒ¤„GÄ4éMV”~eÝûë+·WàyPy¡0kz={à˼Ð`gËkCYÎßžšÜ99mÔU'Îû¯ÀÙžïØÑÆU/ÜUOO7gVW©G·²8§¦‰4HÍrûþŒÙαVHÒM«¬Y êcû4Öpùãý0÷¸ÇRíHùûXÖeDEÁ P´?äŸjBL×>òì !†ÒŽ8©¬Ü^¦C•3‰õèI©[EÙ¬ó&0„ë´y zH¢*Ïv V%¿ ©fb—[LÀ“RÁ?ïZÜI¾Ÿ>VO÷³ð G¬çæªtj¤>:,t­½ép˜‰ ÆUêûÖÀ­E½c®‰o¥áâPp\;%¦œ¡'3“Á[2.«QJѨEi*ɰ€D³ýõë}ä sc`wŠ “ó×*Y"a(bLø µÑ±î”þæo.¯&zot‡R+ð€#f¾ F<ë¯ç£ê!ƒÐróáç¨ì¥‰¡'Òõú͉6u³Jœ»n¸ ¯õ™KÿØý¹ïtÕ'”Kê%›ã}xÜô:¿©…ØZ²ënä-´—@Í«jÒ€´ƒ-dļúÄF2Æ]¨!­uÛEå“õølaB_¶ ÑÎTSþý›·çt"ü 0NÓóq‰p¤& ÿ@€Ý?â[+/ÝZ+ˆ•H£{*õ°Pûigü÷Ôp”ÂÑò8ŒƒlȘ=Æc—´(|ö´BÝRP(ÿï lV âõUmHBÎ ”^¾ô;¾à¶'¢î1Ïâ· è²ãrèŠ3ä@sÖGL|ÍZ0ã8û ™›è¢×Ç‚CÈ{¥,sÑýøÍepµø·å d*óú˜5%m «ûìˆiêý±¿á‚p˜U —_ZUz5…³5?ZTU/wØ-«Óû7¡î9V¯st­÷RtdFèsÙz¶$À`m.5<ÃBÅÚÙ5)݆+)ðQ2lÁp’ R{aE„Ó‹Þ?Á0DÔ!°dy’ (ø`w]OÒØJ“`¾XI|‰kÎOum½ï©!ïÙ±5™éŽ ×°Ÿ?Kº†rÀ×½¨¦ÙßIlT–ƒÞš—Ü1!MÞ~Å©Œ?C’h âHúÛ¥R1H۱ы¯€o¸x‚± ­mo¼£‚Oç‡ü92Êã`¥Û„+#œÆH“6´ˆ©· øl¡-1Zç±…š¢_•ò^bs‡Ø¢»dCYõx}Ÿè¢Œ[Ú~P´ ç-®qãàz¿iñèK/·%pi¶î¦‡®”Øû/uv‘„Ôc¿9&èEµrÃ7¬Ñzçþqƒ¤È#ðúV¨¸ÊGfÐøõÇÅLˆGV éò*$”VOJµ|"p»¼¯zHÑ™tÇ1‚â»ìKd™½DtEíBaûyº »Dø4ñ5¥ ”7˜ßµ¾ÜænÄœ„÷=+£€|F§µÂÔœÊçÐîÍþtà,çISÈ!UÁ”sÂËk×& Û_37'rJÓ4›&Š+J‘óDD´eÂÇ™œØ»·=×:y>¯4Túâ%úzÑ9£&Qd³Ò(d ™ÆÔË×\‡…4 8$>H.èÊãv}›CDÆ“ ÉðbŸ.•yž´Ë›´pýïNQáâüo ­áFÅÔ¡©²•_@¡ ÕEƒxBžÁ Ha€J ÈÃ:.IkŠë2\-¦ÜÆU™=»¨¶s¨¸/ ]íL{ë´"™f·\½ÉaTÕÃÆÍŠÚý³³AJĆ ê¸îaî"Ó2ŠÂžÅÙN¯òÕ1QzúªÇ4›¯‚ÑY"z°+“f± }yå‹çߩճzÕÆy­,R¯f®ŸžÑŒSì:,*\Tlb‚A›ÐÐ yØE”.ü=I(µXàYê¿-{Nü ËJA#Í'ttÑbÕÞý¦·ßømàþëÞqZŽ ŸÉyÙRÆÂX/!5 RT9Äj¤?ÏöÉÅf”Šôziz°•+m]VëpŠK"«÷噤í"Š_æj¼? ‹}HB8Cß$Ðëá+A ¼Ü‘DÐÝ‚ðå'ÑbÊ÷å 2ǹžÁ3þÝ*rí"g!XŒ^²’ð?üä›!#øjQX™{ƒ@gû\÷É=›=O^ð©}–ÇÝÄ-ÄY³àÁM/¶NJ~*oÞdʦ„ݲæwÕ2oxjf©—¯±ôp¡÷b6äð˜iò~FA"£ $µ)–p‡‡Æe˜>?Nƒ÷ª)Eà#g‚hUôO¦¦Û k&n]Û _ÝÏm,¸Rh=°ID  `ý}Ds –IzÑc#ä`[sC5iSÈ|wφ²âè0ì©´~CF÷3\9½Á¤Ýì'öÃu9ziò˱üáÿÿ+f 7G{;„ÿüëžvendstream endobj 1037 0 obj << /Type /Font /Subtype /Type1 /Encoding 3111 0 R /FirstChar 2 /LastChar 216 /Widths 3127 0 R /BaseFont /ZWAJXQ+URWPalladioL-Roma /FontDescriptor 1035 0 R >> endobj 1035 0 obj << /Ascent 715 /CapHeight 680 /Descent -282 /FontName /ZWAJXQ+URWPalladioL-Roma /ItalicAngle 0 /StemV 84 /XHeight 469 /FontBBox [-166 -283 1021 943] /Flags 4 /CharSet (/fi/fl/exclam/numbersign/dollar/percent/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/equal/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/bracketright/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/circumflex/quotedblleft/quotedblright/endash/emdash/Oslash) /FontFile 1036 0 R >> endobj 3127 0 obj [605 608 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 278 0 500 500 840 778 278 333 333 389 606 250 333 250 606 500 500 500 500 500 500 500 500 500 500 250 250 0 606 0 444 747 778 611 709 774 611 556 763 832 337 333 726 611 946 831 786 604 786 668 525 613 778 722 1000 667 667 667 333 0 333 0 0 278 500 553 444 611 479 333 556 582 291 234 556 291 883 582 546 601 560 395 424 326 603 565 834 516 556 500 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 0 0 0 500 500 0 500 1000 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 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 833 ] endobj 1033 0 obj << /Length1 1614 /Length2 25133 /Length3 532 /Length 26022 /Filter /FlateDecode >> stream xÚ¬zcteß³mì¤cã„ÛIǶmÛ¶mÛ¶m;ÛîØN^ÿþWoÜ÷>½w?ì1öªª5kVÍZkœ3Æ&%”S¤á7²50±µq¢a ¥ç(+¨Êé[Yé™ÛJÑØZþšY`HIŒõÌmm„ôŒ9ªÆF!cC##€ƒƒ† hkçî`njæ ÿ‹AAEEý_–Bîÿáù»ÓÑÜÔ@ö÷ÅÅØÊÖÎÚØÆé/ÄÿóFEcc€“™1ÀÄÜÊ (+§..# •QˆÛ;è[äœ ¬Ì Ræ†Æ6ŽÆ[€Õ¿-†¶6Fæÿ”æHû‹ß p´364ÿ»ÍØÍÐØî5ÀÎØÁÚÜÑñï;ÀÜ`ê oãô·N¶sC+g£üµ›Øþ‹ƒíß뿾¿`r¶ŽNކævN€¿Yå„Dþ§“™¾Ó?¹Íÿº¶&#l ÿ)é_¾¿0½Núæ6Ž'c7§rŒÌí¬ôÝÿæþ fç`þ/ÎŽæ6¦ÿÅ€à`lªï`deìèøæ/ö?Ýù¯:ÿ[õúvvVîÿÚmû¯¨ÿä`îähleB ÃÀø7§¡Óßܦæ60tÿŒŠ¸‰-€þßìFÎvÿás1vøWƒÈÿ™Š¿$ôlm¬ÜFÆ&0t2¶NSÈÿßT¦ýŸù@âÿÿGäýÿ÷¿kô¿âÿßóüß¡Eœ­¬dô­ÿµ ðw @ ðÏ%óë[›[¹ÿßÂÿ{¤ªñ¿qü¿¡ˆ;éÿm¿é_1èiéÿÍhî(bîfl$gîdh0Ñ·úÛ¥Ù•mŒŒ¬ÌmŒÿªù¯Fhèéÿ›OÉÌÜÐÒæŸ¶³ü›ËØÆè¿Sÿ+пˆÓII*‹óSýŸ7ê¿âäþ*ï¤än÷—Ú¿W"mkôŸ‹PlÝž4 ,Œ&z†¿î/&ïÿKÆ1ü×ZZßÉÁÜ  ù·ì¿;ÿ)þߟÿZiÿ7aC[£fEÑI߯èïxý§á·¡³ƒÃ_Uÿuâÿýë º±±›±!ÌÚ²­!WEZfºSFîÈ”æ@èH°]i£RQ_m¯oZØ.G¥ÞGm0mÓ çW»ûÒ»ÏC Ê£±>t«Ÿ½)ÆWù¸ÞÄýH[dlTGt:¥ðéçªQž×‹R;`¬ô*G{Sò :%x3LP×Ï~Ä.~¨$Ov>†© ±h]ˆM@Èu…ÎÉOŸŸ~Ž ÷Þ‚÷âPåÄB“r¹€Á“EúÙçàðj(WW5Q_µçFq<´å,•2©ËÚMM{n@òÂ%ƒˆZ;á\%ÆÎð¸¦[P«œ×(4Øáë°ò¤kÌ\~â¾\Žþ4KÆ nz!"mìŒI&: ÂòŒ¸ýe×0Äë <ÈtžA>­ “Ái–Ê¿¨êêjª‡æð ô92#‰üžö¼}‡Ã{»âͯ&p”8Ü£Œ©O+[ðý–±ŠÑ«ÔÅaËX…®êñÍÀ¥Ñ!]-½Ü$ûE*<[áë´óC¬Ôžç%sÿ،ӴÚ|½ðrt¥êº2Ń!®a€µU+»i}ÎÎ+ˆl··;´È½¨@IXï\`>½‹x¡­MMMŒn‡3GlÞ#GAú54lV¾M0˜¾„lÙÈ‚¸ºóSõDœ©jã ]ÕzKLï{›jšËMZò ñaÀÖÃg‘Ö¼ó}Ù¶PÅÜâ@š§Õ‚n'&¹üªÚþ}À‡ž k;O±‡o{÷)K/AŒi¿ÎXm<ê[}±Ím -ªS¡¾*ß¶àâØŠœDoqßN1 s-):E)¨™c혛8$Ü0ÝA«4iŽGJÅ#¼+½D¤ ÈÂaÀâ …N@ãS¹;Nsâå].MöH£fc†šË[Œý,t7¾¤s¶¢ U=ô¶¶0Öv(–júq*œ‘ËXÑmùñûô²ë"[NvJ¹Ûe¹ÇRcæ~`/‘C³YĽó•ð…‰E_üehÛ9ÖÞ£ ¹b¹›q·ë#=$N½ïoœs3‘r_¡ý”›³ŠÊ¼ÌHË#ºä¶©1‘E§#|è¨ÞÑ’…Ú„Qx§¹rE憂 Ê ÎŽQ—ÎÙZt»Îf¦ ì„)ƒ5 úç/éB/XÅÓS~ÃE^—Ûmduýj8.=É Öl©;Ùf|VîEÍØ;F®g]Öò('y?v¨3¬ùž¤×%íl+"mmËé©„”MPÿž§ÔÙÖ|pV(|~÷ šjÒøÛ…óø4ûÙ¦w1-”õ%žÞÎõ{)™œ‰=Ϩ4ªÀäzïÕB1g–nǬÌØB¸º0èU†÷“o¥97‰fT4ëò\—eK[ÈeâG ëhëFxS>Sÿk H¼Õb¼…ƒ,ÊJí.Ki"Ù¾ ó{¢ðµ²hô×R(椾ô4·ç0r¹ä£fè6¡V5=F½˜Uµj)×zbF(‡¯\ƒtõiê¾´ …¹ óN–Cœª~Ôcb™òÔ­ï6“‚ È𞟘š?ªÂ{†<¡†qšðcC$DЉKÜ™…í9 Z<¶¡Ï¤Ñ*‹Áz§ÈEá y¶À€¥ Ž€ 1­A⬛ž®öÐU¢U@~j%‚}«¸"I´ž®[¤Nªy)Ïw!Tû¦ $Gøä öÕZëùq-#:ëóÆ2š©ÉxR–F÷ècw`?Z¯âH—ÿ’P^ÏwÀ—Cn˜§ÝˆÛër:ˆÃe›©9z÷~#(#Ro¨€¿£úmÙ8ï-‚T£Å×ûÔðQÍÁhoz9ÌÑ+œ#uöqT2 …œ'r[ÓÅ7'ÈórÑd5çÓsY:Ê…¤fsRìÃZUF¯øj™Œ™»„'¢ËQÍLY89}lyñÎ[÷ÆA‚Œo[¤ÊAöÚ|píª7|7=ƒ±QÒ= ëwéæ#Nî>ó9MZµ™ø©è_C@ÜDý°Ö•¬ýmŒKŠ{D\ùƒ¦oµõt§@*&häAhs§iMðd;§u©£¸_=ñáÇÛ°¹ðEöZ¸LÃÃ&&k3gK|ã7&_/Ù¹ˆ)j¶e‘.ÇJt›Ñ›‰EtÕKûhØã­Àö§ 7®ªDÌ͇4àÌ`º¯î0îÜ“LSz%ew½`œ›°IoLvmÖ¡d|Ôë"Jæ)KþÃêõ XO›Ôl"Ý›·5`ó{Žu~[à?†*ü¹‚½®_׳EfLôù1éBX ÛÞ§mƒRX¾3eôod<­?ç4.êlE´A,j ÌH!ä[‰K:º•ù2šÃ£àwh¿\ùÃ?gW¡bÝ‹ BËØùá²Ú¢ªiÀT:9ï–6ùb: LÔ|¥s ä4R‘ÓRF²4Ì”5¦§N}?—g´çº÷‚É´_‡5VM×3§àõĘäñÝw~Ü©úå â#°{Ûˆà PR J“jŽâ4@®•®ÆXEmçî-åÉq8£Œ¶üjtØ¥üDž»$Ë“2äví›Ôkd@b¤T`Õ…d캭øâ>¯³5“,nÀCÿiÌ[êŒÇ¬™¥‹9ÉL¸qú;3ŸµÝÅ`E^T»¬¥XAÉáëuX1Lðû‘Lå¨Ò(”ýã×\å­*rØÍçâ¨jqé#Å5~7ÐiJ?Z“°ÊÄŽ=߯1òß„Ÿ›FÜüŸ¿ÎŸ`Qwb19+÷ Õm»iÇÄÓ÷a·K‚ΤÍ8ÆΗîKÛv¦¬´êÍé \Ôè)Ñ'ë d8¯ (ŒY°\ ?”ðn/­ëßýÞV|ÕDK/ÐðëåÔç ”2íÉóìnA еÐùÚ•8Å"AJúx,Âyð­‚Yþ‚\–– Г¾›‡@xk-„°ÇȱŒºÈçF°°jÑæ,lÂÆœ ¸mLWê¦v$ÔQ›²£uïq¬Olﳜ³9&/3Y™3Êv]ȰGåèãæulnع¿Š&imã_ƒyû(pÒO²§Ø ÍPÞA«xO\¶Ý޾— "{¹y#œžPº=÷ÕI³á¾²¸Q E‹ ’‰~ qÇÈ1ÙY^A6ÛWŠ˜mé–E“h´í=E3ÿöesM¶Iey”/ÃëæDYû‰ffü}l}Œ-K¯Qïnù˜Òà@a*¸Æ†eÑ;j̹Ó3é1BŒSÉã?É&ǯU†÷Hsf¿Þ¢²[Ä9Žú©:ÔðRýîàì{Z¼Ø‘î-ÇL䤑s¥FA–¸ó]wÇ3⬞xå!ƒóÆÏÙæªÅîŸ| ÇØÜ$8J¯`ÄÏÞ¢Kuz¾9=‡ŸB©ùì‰räÉ„a6¦•0¥©GÆèâ†E©>{T *»yH@Lí•ÖšC;¨WËró*_`†>嵃MÖùqŸïñBÅ£G `ôî-Ø^ø#_õIÃ@ª"¯µº`BÌ?Ž6 ÉõmÛË'<ôó+æ¢Õ†ß¼#¥¢¶Ræ˜YäîG Šw¼×é‚ô¹ÈP5*x]è/™DfÑ#¦æ"òÃåÅ/{ÙÊ?0즇”™=$ Ë}±?õO›Ai %Üí‚06?é±àNr”Ò7:õ ®™K»^€7„S™Ø2 ½<½—Ó*ø-Gûn‡±¢D8glÒ oqÝÜ­ãÕš®,CГ¾ŽdâÊ¢Ñ%>WCd€(ã¹€˜'F©”"Ú–D>i»­k;Ÿÿ6þ\3l%7ŒäCT»׻Œßø –z€û8 H£‚£ÎcOtE|‡6¼îjõCo{¹#ÂJg·_áN‰LÊ’¯»C÷%:àÚú{ßHIíÙÓúÊ©úmA $.P2&*æÄjWÖᓸp€ fÊQóþùÅP8ñçaÔͲŒÝn}l»+Y9ôO“@þrÕ­%Õññ¬P‡Ž÷º©ÔŸRû, ÇìºÏ7‚N·™N¸x¦¡@R?7_¯ÓŒIeeØY™ÙÞz4]„´#F›š}ÇZŠz@ºª/$+‘O7÷í2æÏÁÓÌè@;5ü0(·.ifÐ3s„-2E,qùœâ|ÑË_-Ô9bEª’œaVZnv)Ý’Kb‡žìà¿Y}:DÛ…ð³ûËpZÃ¥†M”¼Ý+ñTAÁY.aË7Æu/ð$J›#Ñwð~ÛïF˜læÈh,äØM|N š}Jd˜æ™.£ö»Ë/Ž8¼ÜI{lóŒžhvœ‘(Éyv4éõÂu&·;¢¾ÏEÔþŠ(Pøøw·fó›ØÎ)ŽüøL†53™3ìÛÑíų±lØÂ*~I;tH´`κ|­í¹ad/†²ÑÚÆ²eýýºµŽÒÿ"v[fïhÙjìuW 7÷é~ý*Dbý’ZÈ€ÆyG<aÐååõ6Qê±Ø3ŽPF?¤ŠJØg¾ëúÐX㌮nÕ¤LË’í[ Æ)>É”%swЍWð«f¥ÊÛý•ùb’÷iäÁEs®²b'É"ûsí çHu?Á¨^TáhIôvÌ †¾SOªSÐbv¨ÑìU›hòÒ¬Ú`ÑíTn,r¹}á(»¹9ºÕº`±:é}EjUo$uŸÆË›ÅöúçÉ0ð½×rø.'ÓÝ]•2BLTÚܳZ¥ÆP(ª8}r‹P^)§ Î>~si=StåLW\¬¼Î^ * ~Oîv¸7мn¤µ‹ZJ9ðÒÓµÐZ*‘ƒ™¸Xµ ¾ Ñb6±ó ¨h‹@‘a­EÚ>¶»÷!xn¾r¨|ƒËa*¨¹m¦å¥:X+iÁþªÀÕYŒ¬Ú0–7yILj|@Řçm”¸?K1paãVè¬p`³M÷½pÉZÅÀ%±Ot]ô¸#\Rõ´½ƒlF0T ÿRÐ@Öçm/¨£ê<5²ÎÅp :ÁKÁÏ0Š’_üèw€³àK”œí£ÉÂi•ûP¹/àDz^Á1ñ%©¥m•µ«2¬“¸ïÏ ,ú‘ý]xÌdZ™Ã¬R…³c†d°Ãx¶Â(=, xƒYðÀBc¤û×2†^~×?^i@OGsOûÏ"«x¶è´ƒ‡à%T<ŒÖ(EU Iм]±Ë0=¡Ut˜BÁ´C Ÿ†Œžêž²x8HA÷äÓ7 ؆“ã.±œ1üŽ(…Á-#ò+MHíÆ/7}ÐPN ‰ñ8%N„%p—&I7¤¬´»b‰\5d'ÑVÙÉ£×ç½!TDƒVcFãMû¾I[pl4ZÔÕˆÝæ„ùäHwÉè×?¥bûpuÖ›o¢Fõh_*€}•µÑ¨Œ¢GÇòƒ»Ÿ´ˆ2jˆðŸ{{“צ Ù-ë¨Fêi»ÀÝ ÈUê «—ò¦Ùy–nœoÉ)´IL®œá®Í>¶ ²lbLûCxˆK×ÖÐæµJÓ;v}úÂߊÐÎÄ­„ í}Óeïɱ^øñ ln¶pÜn&)s˜òËÏSí…Ðè µì¦VØÎ°ÌQÕS‹è %´nºj lhÖ¿çrS"±q]NNKpu…˜äбH,•bÛM‡‚)Ç—x™Ê¦®á^`®¯ÅÛŒÆ.åì- ÇýâŽ>5òTÔ QÊøî‘Jƒ,×B^hîšY8ŒÝVº}9V·cáÄšªÿþÛJ¢èè˜]'7:_B]Ãá¤z ÄZk¯NÍ}~ýµ4·º<üº?i‡šåüÞÅóâvà Jš%™Lô¡ÅïÊgTè¸iô…e—fj}‡ÏÖ,¨x«ø•ÑN¢ç-B\ ¥ýÇ=1¤J²ó™JqI ˆÎœóCQpÔu.áè AÅ{Åí ‘ÞPôüƒˆQ¬Í · UêäLAùñã%w¦Xá«´,xS`²z:è“?§Í$E'Ëo? >± ñ® Po=mïq;sÝÁ¹KØ š­rkæ³]ˆ9Fô9óøÒø:!^u22GS»‚‘@[º¦°ÛÚïAOi|úR´nãPÁ2Œ ¿d«>¹Ux†Ë|KZdýI…Oørµ¿¢*„Û-Ÿé¯Ü$§ƒ°4æÀµ^Óäi׆3hºc²Lâ–h}õ¬áW>oQ / |^BØ9ÿþhýaº{ow:é‘y‚Ù°hîoUÞEÖέa:Ý0ãŒTÉt¶ç¹²/®r»êoøˆ ÒŒØ6¹žž&¶Ètòç"Öró·€f:²xÜyÛÏß¡à¡véº6îÇÃÇ•zgw‰PZÍbÈ›„¨ò­ –‚‰y·ØÀñÆÔFÄIUŠ»^·Y€°Ý0ß‚BK‘§ú®rt?¨¸Ã‹2Cûø !R–OWBL6žÃQä>çÜq¸„5ă/Ís¦¥Û$Oª97­™l.DpýÛ£ rnN­Æ¦© _s*äý6¦x<Ô“YGHƒ(.Ôfl#ú“M΂ öûļžn=ÎÒòïKÓÉãúTlûîT` wíã $Ú±šñtÓô»…ÖÀмKd½ºbÓñ…™…ií€f‡äøÕEèýÍ÷‘9dªàŸ“ìXŠuq!Ñ46egriUêôJš†9ó¶d –s ¿œ-}piÏxûÛ©ÎëÇ—ì;ïíà#?ûðo³˜ÇK”@ç¢0j´ÈH>wBç54n¸ò²vJηß'€Š|¼@VÒ¢ ×Y U]÷z™o Э¤\ <ʓ͖ýÙ=ô«”VÑ×g~£ã‘Þ¡¿l|ÝÁðk–EDÜ /ÕÇ0ñÆ}£4…Ò Å„]ñªCÿhÿ{¥\»…]³‰Õ"à5Òn®àˆMw€e×\w—n@ýä¯Í£¡â˜_å÷Edç*¿DõBURMe°}b*Ž Ÿî :4Á¡ß™a€ B cƒ<áÊœRµjŠ“V(’aÜ”¡·-óG·kb€7­å»ÈVlôù¨”Yá7v\ÑÏN°WOk+ö½t ŒXÍg\Låµ9&‚LG¢·Ý«ºB:`Õ|v¯t « =ªcŸ*Ö2DÐê §×ëñŸ@|\ŠplziÑž¿æOx¢ÜNJ¶æ°La/se—Ü·udhˆÀ˜l”½9|›¤7±W0Ô¿¤fËPˆ,ÃûF%ıQ[LÔjÉР,¬Aõ8ßê¸ rÛ~j,PŽç'G©ÒIRɬem·;ƒ9;µÄüˆxá]ǘb kuÉ».¤bk\nsør>i9T„Ø523œ¸Žû¡Å±Í/£eê¹ U§A .æNp^¹}à•§èPÈn“[=ÝÎüÜíb¸cÜ3ÄSy÷í¯HYnò·ç#'“¢^¦1TþêÊpÒõÆ‘A1q)ãZ^rÕ‚²Zó—²6»Ïk½U ¤VµzÐÖ÷Р_|Ó7T£pä#/wƒ¾á,…C ^˺ч]ÓØ±#Ñ™x¾;ÀÂA½Q8ú9”A.2´ …{¶—bÅ¿Ã䂸,—¢mÌ-„2B …'7Ç_¯{ák*ég玺ólýÆ0°p6E×RoÑ¥º{tÉèÌ!­G]OŽvÚßÃ/Ÿz´>>ä€Ò&\—‡gK7'(œoìånÎé°&èò•è5Ü´DI…E•ìu¯O$‹ž¼y°=–¼N¾j?% >GF‡¼JF}ëEÑÕ%‘ÂE¼› Ç­„úTaÀxe•K@b¢ç œßÚÉæ\Ò[ƒ&/ùc:’0VÛ–Âi¨rƒÑ8(%¿QŠ«`>°WØZ;2ö·¼ùèT”eX××=%”õw$ªÈ÷ «ý¶Åë‰Ü¨;¼§H>ågXJ04ž‘™Ž¥Huô '¯Z€b·`%°p§K1æÃ>ÈãT5ÿoºHÎï¡Ýð4Š˜å¾q¦Ôh=giøbcD±t ß/limD¦§D¨_iG÷¥‘Á9ii†Z/Š«;2‚ØJ§•|w¿ÉlYN¤€ŸÆÆƒ‘.ð)áÖ8ü¤ë¦::“ä„ڇΖ>Á`¹w/¹M­†Z%¶µgzVܾ“ŠÒ‡¿¾!‡Zd¼ ÔÏ}VgL  ç8¿>†ëªç|9ê7‚ÑKëLþí[ç2ãµL"/þ0Ý¿6×®=mÔyÙµOVþ—¥‰pþ–RsÝzC »ˆ2ÓbS.®Óø·¿¦˜ µ¬“ê™kΞ;;•†)¸²Ø«'§©œofƬ”ü–v ÑûrŒ'ÿyµªêr“­‹·+]8Ép­ û G˜keÃNÙ(Ü™1&éäcÖ X0ã—ôðîb€ )žií¹¡)ü Û%³ùÑÈÉl ‡¶f ŽxÎp×úŠàBY!²*W‚ >DhÕ¾Üt”T£|â«Ò©gËàšó”·ý%-å=úyÔ$Ç }ötü¿<¦a'…™#¼‚x«Äª÷)ƒÎÛtö ̹=Íõ—dý¯ë÷¥@锚’^ÛuúæàÈšXô™®Zï⣇„êÔ"[ä‹ß‘RlKÃŽŠ«b.Ɖ=®«ˆ7¦aKײ—±,ç¶[¿‹މ@Šp3“*œ–ÖeÑb ¤HØš©KBäDï¿â Ý}µRIi/Š'Ø$Mò•,? x¢ .X Îô¬ ‹}büã…‰s??û]¼/K:ÛþÓÞ:u |kþX*`ù¡$ …è3½ßð¯^ç>†úXB{»‘¢¶¡Å<–0 ¨ð‰ á3Î%qLÖʇ9FkyA“š¸˜>ÚRS&óÅ`‚˜TÞ†Â"µGªª±åXˆ6÷À󠶦 é‘,F—VhŽ«†Ï?`Ä8×>¸•BQ-üg/¦‹6 ¤‹‡Kh+¬©úÁ\€Öp#¬Ø/§;AÝ <1­'¨sÇ}‹|?WVS/NÞ•œÊäˆ+ÊAÑýµ¾–üV>’}tFtuâʬ‰ø “'F\y.*’Ï´LnCA ÃÇ%k É›ŒÀL†`úI‚¨ôE¯·³ŽCX1L›À³áéñ6‚Ö¬á^§øž]ÿl œ©xw{“…нärñ“îû´)7äZí´KÁxô½drÒ D2Ûuè­Ë%Y{Ío§ ó’[þš_ômªÚëmµ‰j·Ãó¸B{¸=é7ãgk(?ÿðôÁ(+ØòW«ïÆôÃHñ_ æøõ»UÃÛ¡«TÅä:BÉ!'r‰Ž` ÚAðq~ïßß‚cÿÊÚ»`Ž­‹—² +gº‚›xÆÂ僦„$׸dpd4E¦ê™Ó´í‡»l6‡lÑ»œ…‰Šn8Η®ßJŠ—ÖŸ‚èÑYh‚…`²œHÂà¶êvꙦ/qp ª½ <]¡§ÌOÉ|oò€vð’w%™IÝûÌ@øJ„„p†î<š1n_äæún˜×>'²~1 ì&†‹³§iT£G7ÏàÝd*D$¢.Gx~C&{6ýÅe MsŽb÷Óî…Ruú¬¡f©µè×ðÒEï‘s†Ùv˜kµ¹R÷‹ §N¸> ‰é³Ö <-E'|hxd`Gtj+Br;s¥÷2$¹*Ó8‹ÑŠ»bcgͻ쮜&ñ<ó`·ÁÉF‚}XõEw j&µŠ$rÛšUÌWÌÉ*­ûîâ%Ie¦án|%6Ú\@JM!³â+#£\ŽB$lÅquÿLÜe’áÒ~ý¸Àe¡VÒ~¸W¯~‡Lƒ€ ÄëèÞìÓ{ ‡o±”ä®8×oè €§'™ÀUõ…ʹ/Y°pîDPUºôÅJ÷BmeoH+¥_͈¦ìŸû1ýɸ]ÆKv2o¶ o ¼ß¿‹(ìè` b Dk¿ý hÎô‚V0ÓÿÜXJazué?#£ÏJÅC‰ü4fž›.úš©í!‰nTPùí_¼7+ÇËGê+&·BV¸$õ…"ã±I–W,ç:Jÿüv°­F?¡n²ÁV-bt.V{Û²O”³Ps:€zñ¬bÅ|Z©©)"‡¾u؈í{J}vežëpíVÚçüj™B¢Õ\ÖÑ.’`þ” èð÷üG°áhQ/Um+‹\“—n±w:"IѸ'Ù0ãúfÈÞ )ær3ÍLJoñ·ßÑLÖ÷…¯N­n&j»4i0¥Ð1|õ¸ ÎÖSñ"ØàæÁn?U=+tðÈÙ1•s'8EŽQ¬TÓæ Ãþ–xO4þÂãã?'zyBˆüå›uï°;Šwvdèú:Ȱ(ÜlMÐ@¾˜MT|÷Ü„Ÿ›,ÐÑ|ÌiÈ 5Y|@b}¼‚¸€â0Â#y¦†A†4†Ñ§ÐWƒ‰#RAõ r!ò†fÉ!ÏÊ\ûžÉ#  §«?3˜¥v/rZkaOèâ‘Nó>ÁZB]sç[?%­€ж…ï‹ðŒ?Hh=ïÇòIf4 ð˜íQTãhØê¤)>Úo}o=0m˜eúMëùѺI¢ !À°éfǤR¦ Þ"5·ßÓpñÜ_d~1yF=¹"[DN£$ôƒâ»#6øÖ7‰nGîI¢¯ŒüK>4)ÿ©D£wXSfëy¤¢Bî“¿ãY€Rõ¢vXÐe5 €¯û„+,ÛÂù“Á(¾Þ§<Œs’‘[ïEÃY|$OҲąÅx“¼}ol ’ ©±8:Á­‰ïAwà’‘ãÚ¬3ÁJŒ'à7UþÊйE)+„\owKŸ£='” òó Œ/ý‚½1ðD´k“ÈÙì΢]TÇ›o= ¤ždx6˜qƒ„¯Å89ihYŽ.)s#CúÕÖÐw®é X2á|fÊmH‡¥[–íDã"ѯ‚ªÁ£Ôèúr¶§úÞ^+í“‘ºTÔ_˾î’ƾec7dóš.ôÍ"S”S1ˆI„Ž{nf@'|Ó¦ªhD"ÉguíÍdoØÐâüIšKÑNÏX¿ËÑiíÕý„%qÐmŸHr_U»•¡qÚ`ö¼ÃŸ–álS¥DWÇäÁWÝw¶:Q2†9ªº‹²ïUµf+ÿ„~ÛøG±ÛQ}Ê]DñûVá™ö¤ˆ j!ÿ°RÀ«2¥ÐìÂÎÖQh™zOå3—´¾ötH¤Ð_Âô¸s]s”&"!­ß\_±ýÒÅ^•ÍÞç¡*¦‰Ù«_xÅô'gâ%cÌâèœÿâœÏ› Çš\·ƒHú{tY5¿ÊÕÄ65Ê’ ”4¯àštæ-wc(›¢üÈ6 c>Ë…™ª^P,67l7æ£ÇÞwÜÍñÈâ”þ°ä´¥ü›¿ùnTBŸJù׈yÁK Ê-ßo‘^áZÉSHÇ:¸! ‰î8i;̼»ÁJÖ `ºÍ}ªÓý]ƒT6ÜÝ¿<ëš=½(ºÝÚèì^DÂuŽÕÑá Â+N7šTÓC쟔˜QqêÝrc|}~½Ù_:J®å*†wç£&Ntïù(¯%¤¶².&‰3E6s`—WRA :‡§žoxÀÑ%ráæ9ኲ6Õ©‚\ÏꫵRµ°ªŽî$i¸ºtû}åòcM|ƒBäà†&®È%ý íª;ýåÞ U·ÙR$h³v<ì£h >3êíØŠŒŒGÄ Ê÷ínhXÇ:.×7’÷ç7EÆMLÈ’…e¡%Ïã-‡<£' '‹¨§øžS¼~±÷¦3x \#ʶZFa‹~ˆÓØ*&+åì¥*X™í°?âŸdçøž°Å.!—$²Hï‰SáMlt5ÒÇ© T|›¤äLè/)ÑB0{Á/…>fÅé|¿Á°ñ¯çïŽúMp+M¹]$âC îHE°ý)É>72cÔ­‡i,s¯=¡Q÷Á:Ö°ª%Űúá4p4)¾àÖhq(”¨Ô{Gn´z3¾G¸–¬¨ê‰w¡(ˆa! â$˸‚&%–J\²Ñ{¨¥L2ÞN…¨*+F¹Wh¼²"Þ/&ùzÔ„(µÐ±þÙDLÕ>wO¶ÿFz'ín¥a1G| #ö*› oôóº ŠÖKe‚cí‘æÞ"Ÿr® Oòì>ýœçèÎkÖƒ1 ºÀëò£î -/i.ú A±¥¹žß[®y67á]Ç‘½k.SH¢Ž…ùpHY4žýŠê6CÄTµíE•FÅdz\à“*=°OÊ®Uä=ÈŽq![ ­‡R¾7Yß ~Lõ\)qŠy|¨ú3Ç]‚ÓðIÁô$‡òʽ¹|% Îuõªg€èNnµ:b£ðƒ¢4Ÿ¾f ˆÎ™›¶h,W¼o¬æqm¾•BŠ4l+âS,¾ú”Ä«½^[ƒÛcó§tŒ(“† 4¢Þ|™Ý Å ÊŽsí„h¬Ê¬¡x0×^¢^„(Ÿ'JSŠç,ÍXt͈eÚËÀŒ%X@Á¼z 4ÐRJ »¥~Ɇ³„71¼%Ï8ð1í· ³™Ñ±€Ý@ås!¡©1öS œc¨îů»ëVVSCÊ$c°&äµ!?„,\¬3%ë»PÈË3¼‡’5Ãòø:?yW§j‘xy`Á`À·å ~®9O}¶ïÇIdýtÆÂìF]þ÷/EõqH‰ôÙ.Jyx’ßaÝY Õ}W¬;µ´˜tÙ½<(Qjä¿mFk~€ $$åþÙ¡¢½p¡ у»ùóq†:îªF‚ç<F€Oÿ˜šèÍ“Sém"eÕ ¬‰øã”kcȵ¿ý6QØ3^\ÍP˜»¼F•Ï3{åΜx‰3b žrq«à§WáA?%9²r>вÌ4‡í×G'ZëÒtÏÜC3¹¸žäܺ~žåZéêˆÓª!K'¬üÒÿE5ZgÓPQ?ãíœW8Ìኀ®÷ž¦–j™®dÊ].‹¬±tmMs¹»BÖDmѰ›Òm":{·Ê‘Ýd ‘“w\R‚±6XÒ¿è¹Ëç!lËr3 +9Gh0L  .R1&ç\äS!ù_¥±c/Eýd->Ãߗײ¢“«vVé“=™Î¦!ØÄuËàmôÓ…=ònÿ´ÁGá–¹>õi¾‰SoÆtƒ‹?BÏ^wÝø›Îš·GU^W0äõ𯔤¢ÎÙ> JêQQ W#‘åOµŸ<^œÂÞ÷åÊË„³Z¢Œ®Îíæ>õÔ‹¤ß,æ¿Ó;ô'«§[Vü„»ŸÝ!…5(˜Ä…›Tó¿­úÊ*1²r·Ô$úÑg¼dÓˆB°¿±È· TzžêúÚ¬Óp_3ÁN²Ÿ ßåTÏ78)^nàpØa'«5G{þÊr¯ $Ýø‚×i$‘“È „Ö™à‚²HðR/öóìq­$¸` t{úôŒtx,Ö#㘻º¹²ù‘Uè%dA@nÎF&­ÃÍw&\(Oˆ½n zÚª ›?04ï·¨(HZ‹¼>¡w™Ú† ôlcÔzèCxÀ®ŸüNšÕ ÑÒóXÝ2ý%µã»òýÏ#¯¼=«°«ÓÑýªðFh¡äVç¶âm©üµ7—ÑA̖ĘIB×¥}b´ø·$u¼{„,Î.~µóÀÔUÔn)ïØAXìØm…ùaÂÕ5t—†=ZŸÇ0ÀUQ5õ9•`B˜l1{ö#K×e³„ ñ¯Òð÷ÌökÕ¿™Y«ó[cì×ÍzƒÜ ‹<ð´ ‚ ¢FÐMtãäbk¿I:D㈺¶ÓÛ–Ï“BεߗDF¿ö³Z6LÐ?¬ÂûtOÆc`+·úp×M x¡¿ƒÌÁ½2Øc`Ön<°Jb½EWÏ£‹øRóW` ýÈ|¿d½ûNb)nFÃø†ûxŒ1¯%^×/ ø@hjòŸÆÓcMµ­‰ïk{7ñÜSï#ƒÏô šÜUSH+ܦ¿ŽBKÞüYE£z–VA.V—Ô‘‹,ÑË<k@k‹ùs!¢·#Hù£Ü‚ŽÔ¯¾eŠ-0ÂÈAXá­Qe5—Ÿ»×$nA6½ÎÀ1ÕÐTPA5Û0ðÆì¥Þ¿øl{ú̘”ÿ7#ž]]u»"flVfX+«ñML3àpÅuØãÊ© ˆ÷OkÍN‹ÈæÆAÐéze$‡Kl!×É£.õ]ÉÞ’Âol† ³Ùû;ŸE ªàu¢m|½=µ¬YâÁ=ó` Íi`÷â‹Â4ƒ³ÎR8öµžNq ö¼t]£TltùBé˜i:òtQ ‚…‰WÁ©‡Ý?0ÓnPî:v¶–ÓÇõœ1i^Â8ì`´qï qµ@ý¹•`)ŠBºùíˆ,ŠûÄU·5gü+8+bu+”¿ÔW£Kt#£J7Mí£k@'IM$„fî².ëôóka9`K¾ß¯SË9K^ q?}ÄÆåü¨G­G꾌‹`Ñï„¸Ì½Š Êp›…²³’$LB*;ôRžN°÷r£\ù×'Ãs´Jé˜"jD–¶¤JØ¥ü°xšY|"7±š Ö ê‡«µ¯ß@ðŸTèBN’XA#æšNh×1“3\ãýŸ‚¿«Ü,z*ý’~.Œ“˜Òòû ¯ÀXs:ªÒ¸—Mî¥?ñ~¢ÚÕ49‡‘ùmÿGßßPàWFD ª~ ñÎ×­‚VcZho€'£D!ürö‰îµM޽†ˆÆ8L#r~ÌÚBÈï¼< Ÿ$¤² ÌòÜš„;ý¶=bý4ßÞr¢3?––Æ:Ê¢ª FËcö’ÛÎ[›<®„‚3 ØÎ­žˆ|çî¶gvS-<Ÿ¾T?ç—C<év¯O—#ß\^bÕ÷›‹9–nM¡{;Í:ãˆçáðkEI*žN[鬿µ¦¹»ÀŽù9š‘iXÏÈ‘Sº Nx!5åZÒÒóß±¬“Ð _2®H7¾$K÷qO«@e¬õE½¨Å Ù¥•1’øÑ;Ÿ´V0«¸3gù²3½uÄo5ßíËuúá<Ùóª¨êÐ n‹§—²^“ùÖÎ[ãçñ%kýfœ«/ùýs®óP6†Olkäõ¢.8öàXyvÚ\ú’¡+Fê~áBXBý«-,’Ô[¾åƒÉGZn¯ ðõW¢š0T)L• I²»¡eò…+Î9äï­f¥üsÔŠÿØgÈùX€4•„Z.y’C+ i|'d'±_gLšsJ8QmFEŠ÷¨Ç“°:8$8/ƒ'ÞS³‹!: À?ªÁ#cäûçøhn+~k÷ÓiÞFÛž¨ŽÉgÔÀygi,zÌ;7²—“<Èã+"}Š!k¬{ã$±ß6 îM%Qè â¦.±^j•H:•·øGKøÍ†AÔí7Ÿ¶×*$œøxX%ÖÌÇò–—‰vN4Jî"ëР­užH´VZÓÙxî^Ó6XSª.WH-)BÚ;ëöCÐþ§iÿõãËì z>ÛÔ}ÏÌç0¤d‹×èÓ¸©9p‡¾ó0ÄÎî›áBíXM?v°>q›ó_ãø:r3ê½Ñ´­ƒ!(ì³%äçîÀ”<Åk˯"eŠÎ•ñgP$‘•#ÓŠêXݧd¡=lÆ=œÐÖÂÀ}g·äŸo}µ~ò,eˆïB½BNQkCOnHg¡™†,@O {†ŸùuÛøÒÑcÆAvUñáRÀ ö~ Ú¢ÃGå{Ù!<Ù9Pž…a¦úGèxúA¹& ¢b‰Êòtÿ­/¸>œß{¯œÁ¥M¸|ž7Ð/¤»]jˆ$l÷ŠûŒSþÔÐçñ¯¼¥Ž>ÕY˜þH>†ÞœC"´W±ÏÃÕ2ѳ__.è謪æ†c> ±pº&C™Žñ›%r ž·;zAÍl7 ŽL¨«dáòÔ¸.1l(Ûœéem5ªq]`‚iD(/~ú aTKkÚr'³ß?Ÿ%ñæݪ@µŽÃW@\╊Ý5ù4P!Æ©,ähÖeb“ãÉ/_½dtZÔ´Ÿë>‚ŸÕÔŽyºŸ>Wœ-wïWžcKù÷ç¬e5·Z‚üЇ»AÊ€Ve"1· ›`SÉÁ<îC¦¼~öæ®aÿP¤)ø{ S dÛk†gÅãZ§Nm®e]ð<ö% a§U´ä6ôU¬ƒŠLш3žˆá“§¨Q;jdöµPdŽ©‹Ø¶X vö…I2džg#ž«U}Ð#uç“+ܘ—_==;¨‘ ™´“h ”Êyàó swö_2j¸w(²^‘^í¦âX°®­À;qòë—Ü zð@Y…)+GðÒk­VÔz¥A-ŠímÁ6ú#…åkŽzLêUùœ’%NS¡è©z"XÙvŸwðæ‘sr8䀬ûn¨üײ>@)ΘøÎZZàjú'½w*fˆ*ã Vì‘.Å%´BàKXC."pEî^\q ï‘D–†ÕºKR0k åÄPõ¨mâ$¾cþŒdñ/bÇ­!Ë,†½ëè.¨Ðdúzä̱‘ÇvÀ ·áú®ãI’b\ãúi±Êæc¯TÛë»é;:5&õëOg‘zwƒZU®™²Ôß«­3ŵDµþPÙgdï+ÃÄ+©ï#Fw+ü‹çÃ^zl¬7õ¾×Ó˜‚7Û+sb ÒÑcP“õ‡™£¥d0WĚߊÞ-Ó[#Ú›VÎzz¸üf`Ä¥Kë@ö.§Šï)¯Õàmt“šîéWÉ~š¼4|4ÉÿjßœÖ*šmÛžl»v¶mL¶½³mÎζ]“9¹&ÛöÔ9çÎÝÿýëÖåº[G0FÙ‹ë¹%Þ,EB6P7\:-IÉŒìFm1{I]ˆˆ¿áèO}K$"wSBžKíÝCX*Œu7B0¥™ópÍÔq°zMŠ‚.×xnÍ姬>t¾pW-æodÙ3´éTCqÖ茈ţfœOÎÁ*c—çü*4yåÆ7 õ‘jª.lCy î©A‡xKÛ– °ù¹GÈÖè~ØÆZÌeÍ[øšg5«!ýµ3ÇÿáÍp£‹ÔàÜBh‹@—d²-QpÀ7âçiß’"îp‹Œ‰~¦Òh©›D­—Üß#rF•þ1ýÞvä³kã '6™t²w‡Ü.Òy[A'©@@E³Ú,ÂàµU­agz–e Å ß¿*ÆY¦TèÂôwôîPò½=ƒŠA®ˆgs°{:ç`>Øž1 4ã 5kcdÇ´É–Œ A)\µÚ¹r‡þ9Ó§ Áq¼*Ÿy¾”ã}(ìVoÄ­\V^Râ%ä9Ýo¼Ž4–)re¦m·“L1ų!§‡C]¹-‘wGÚ•ìy-TýghÚp‰0ص%H&|GNaÍÁ»ý{ô¾¤ZÈ uW»Ðf«õ‡sð#îä÷œ] Xòç×4dNÌ(a>÷(ûŒ(þZØCÂ#&Im+¡jlòo)ZOB ™C¾ç­YsKêð’óV6“3ß²EócH¼Æµ4R³Ù¨YktÎë ûð”_¹8dÔø¦Y%i+j)¥0yxv‰]ÉÀšWŠb­zñ[ÌÒ¤ª®†*Ÿ æ÷§ ¶bg´¿.Œ‰Ú !úò ÉXçuO7,|sb£Øi²ÞŠCÚëÁèRÁ$÷BúC÷RvÇÐÅ §–Þæ·é"2¤"©™x¢¸ƒ$RH ¨Ö~¢~瑼rcÇwiâŒÝàcI…²‡¿­nç²CxX6iáš³²žºÓŽÿbá|#à¾ÑaÁp£æ½Ó¨²Çw¸ãÇžÐmù ÝLÔ!ª¢™§þ¹Cæ]ƒI«T,]“ aýÛǨ±LÞnPf\³ò‡SÈ÷”M³G“xŠpv,Ž?è´Í‘ªÈð”x̨.•½Z8'èçÞÐt´K˘î=àôÒ`4Âj{„±AðA4¸Càëk»ù§³JáŸs0u–¿úÚ¹Nñï©ïÑf.YJ|-Þ÷*Šá%× ˆ6^’uT•,4:ãíx” útÁç”kR÷aæRò–†Õ2[þ ÌSO“/=B„}¼¡š ‘Ÿ+8.²­ò.ÍWÍ–ÃLB¯±IêVíË©Iu°¹æíô©FyA(O[É‹«½^_쩇Y½6êJv ­÷ÞY 4r;U¤âE܆6"Ǭû̳²t™žÎM¨ `'ì~’ÇWÇ6¥ík¯zš~§ÞÞQ#ætÒ´”C>¹©Ó8Äl<%ÍÀõé2¬]{åm« ï¦\¤H£°&4ów®H_r°RßÉ3Ç|å_T³¤¼+|D1sñÅùCâ ‹ñ ¢81sö(HÃ*ßæÁ‚q>cë¨åe,Ó€ã۬ܭMmÈž)8zˆ­yC¿&/I§^H©ÝøÁú5A8|ùŸæþÊñ‡û/f〦Y÷JÈ9Q(±-¤2¾RË÷Ø”DèŸt¿|…·»Qã k—âå=Í=Â}X(K^êpŽ37wÂko5€v&2[°=øDÛy ÒvƒN-½ØHNršFŒFÓóˆ þ ÉøvoÓ=Ò¤˜fd™%R¨º>W-Y:8zÊêqøà¾m-3Þ…±(ΈSá³|ð^ÄÂH1@æ|ô%Þ—Px(0SÔQ)yª™}Gí¢V ü·=XÅÂU¥fÿ.šL´$«’_€]=Q´éÑyoò­³tK &ùYHxÆGT‡h”K„RKÈ8LÁ’¦ßÖË$˜€“.'•מe.’7¹ÚÌlÄ (=ÍÃ*¡kÃØÏ©úèV@ F$M2%XtÞË×á ŒÙ>¡ÕÁÒÆPÓ  ÷5|µˆãQ‘>Ž ®ˆlõ•þ.“%Î[ ÎgÌS~ÑN€ òç4ó­3½•i%눘WÖÏÒ Áû“ŸP. ï\èYx„‹‡Ëv¢<â/…ïêf\“J§m-µªR€ûêéÚùYéá̺ú+óujxwUv>+g—4t’ØNv;çžJ[p•P0„Õv]$î:€h~»ÃPç3:“"N9b~¼¥† €6cAßC4a¯³¶Ü¦å2Ñ«µJŠÉIr¯Egî.Œ†=¤2îxñòŒåijBQ×¹}⽇Œ hæ ë¢N¼ÉÆŒ'Tåg9E½ÎÑÚ±I_Ò?x7®ö>; GœÃè71þ#G«d8¨‰ºˆpê¾ÈìñUз“ìð™:Ý ðžÒ15¦,ŽºÀ ê!E+¢5A¹äo±;µ(uÙB4Þ>«¡‹Ôñ Ú½ií’ÄàË–2å…A–ñ¾q ûOwc„ s%1JðNŒ[Ùg6’|Ê_DgüC_Eß÷ÞlóâüÈ6©Ë/ ´lTü­ú ~KbË:„±o\ÉYྜ@r–ªy:¾wŒÌëjØtu‘ C/{ìvá—_+#ÜPxß$–#æ| ÐñT…·ºý6¸±&#iefúé2ÇWÎ>tÀJ΢+ ·MŽ˜˜Д’Þ×ì™æ¢`Û«¯² é–ìl¾»*7Érôa¹zŠ÷nRõS ‚Í>Fãä2ŽÚ9c`1|Lué3{¡^•Ë­2#ë~ùKágÅ#è@2I´T9ÛÞúð&måšÂ[ì¥Ï%ÎÈá!FÈSø²EÆøú|ŠK8ǵRû7÷eb¿õ(Có|ãg«ØadÁ f‹:F,µ^œ>Ù̆Ԅ*ü¬ <î{n}VYëg‚£4÷—ØÙS¯b޹ô=eRì¤ N¬+Mâ"Ëý_Ch¦q=8˜+‡óÂÜŒyÎð÷Ìò^Ù]™q  ÂEk”MÔRÙ¨C\-¢?ª¶0M;JÏ,vºÝwoXÓ…ÀÎÊÕëJ]ˆÞûˆ|Ÿ}ânZâÌàA6¡:s("*ÑCµ] ô9l²¿'Q@ÞµÅè¾ÒœPGØì@¨»óÚªäZT/µ¤‡9€ÖˆéMÙÿ-Šf¤·V-a'bT°heŒÿì¬^8”2 믌‡³<9¢‘L¯®Äí¼ª,k„.³…P-pØ!A,Qœ?(D¯‘мIm æh¼‘¤Úéãªã3iEÿª!Ð/jµí ÚØD‡ûr`Ή)ú¯§¶·(€Ù ËÕ6Ì.ƒG#l/¸°'-X°o:’ºîNiÿÜsø0Ó-»Çþ»üÅ=]=Ÿ!bút9Ô.Õ%§‹H¾|£ÞÁìm«-&N™g„Ÿ‡Ô gUüF× 'ŽùÍšãTÓ1Àá ÿ ©e÷¢P‰‘@ºeNÇÜ=òëêï¥zßœnÝÆWMZg‹»À[þûœIAkd ö¨¹e÷ÕâÌêó©j>’ø Í=Nå2T/JžûêmÑó8² Ðjíd#­Š‚«é6#ªÈÛ8 Äþ௠‡ˆ)TûeO06KëßYÞ8ˆ6£‡ˆmˆu•iw|[þ7¯ ʯWßrCi³ÅS<ÐîR6GdôL‚o‘÷¸O–™»ïÕ!ÏrVè™Ä„AMß2¯a>&;Ü¥®â2ÐjÿÝ=¿ño¾øaÇÅ"Þ>4u%÷WuºåÿÒd±® áßþ˜³¡äî%óO©Áè©.™æýzóZç¦)Pš¼fù%ŒÊë˜Ú$’È[TUÇËë:à³MЮ{»ƒPÛ™áÉß·ßDcÌUTàÐs•¥5oØl’õ„ÅTäÚŸw•u‘ I8na\p“çm)/ÒÕÙÓ­læÅ`!l—¦7|1 ¯—%—øt¶io‹rYž‡a{럤’4?¸Í>Õ~!µ" ­º9õJÖ)&|ò*Álh±DDÐK~L9Uµ¶.g..<©–ò< 5ïNwtX§­¥(îOɱGmÖ€Û_Zºw}9@Z¤vÀÜÔ•±åÂ@UƒUq$!-¥½×üÊe¿=„PýPŠ…ZÆ¿„¢ÅM•O|st„ 5ää/B%\L¸4– YûµJC™Fw^5ðì¯òýÍä•Ü`¬Ö'‰&NtÇcF‚‹J«²FÂûqÙ_ô€ì¥Z`7¦«¥Î-JgîSÝ‚çHwäŒÑš;ô€Àª‰FîðS4È0&¯æEä§úžÈþÑ P‰KÎkLñn ³Äý‡=舙Ùï×.DÛŠLèZÖtÝI[èüêR·µSa72{-X¤Ìêã·ÖQÒÇb ß?¯ÿK¶-~ŒÐ`F Åv¼ÃÙ’Á¸ª²UøâȹíÜEÝîÈîr‘9*}ލÅÙÎÒS÷«’º¤McšªE9ƒùOòÓ/ÎEƒ´¤ŒKŠ]b ¼\xQTÊl&£\ØYþoÀÀž¢¦ ø`z“§…ÛßSnUº¢ZL³wbpú_x ²¸")h…Ʊ_þ‚#››\Í’¡ÿ]ñx@Ì ó•”ýðb¤nÜ¿-*NO3ùƒ “9„u<æ‹Lü=pkí†zvÙNßl 2 Äõêý/aÍb)ðÊÔaá"„,Š]G‹ü™ž f·šXKD¹@‚VøÖ*¼nùaúS øõÝ·…IÇ|ß&Yž>^ÀÔ6«_r ° Ö± 3Q–UÕ™Db n ëΛ.–ÆÒ{ÆÝjÍè å‡}&X;[™ü$Ú°IºÅ©6³M‰úx)>D½äú{¨IðaŒEÇ´¡ØU»ÑjÚxV_ÕðªTtl4§1Œ*ºe4¬ŸžK)þ£Ó[íˆå`û'!û¿1kòzsTV0äÒ›gmšû& åw¢òýÇÚñ­¯|º¾öL¡–‘NgžcÊ®½½¼ìC¼,žßÒA2fu¬ìÇ[“@´ä{Xç˜3¬û é9g“ú©ñ  <ëyßâhÌ>”×ò(ý[FÍwýÓj§JùÙÍ-3vî4Ù˜ëøÞ‡Þ¨±Óy“F¯¥S ñØ9ýq”:êúHJ³ŽnöœN8bà× ýRÑ*ÂÊ£_4 Þ¥™ >FØ1!ŒÙ¤Lÿê±ãž¡Fjs´¯kc€H 5ÅÜÖøµN•ÁŠh`ÓJ;Ø×“dËA‹£’‹Œ­ëHÀâ©#QŒ±ú½Ÿæ 7Š5[•–)N=UTÛ]ÒË…¢³æ‚èè‹ îgxoN™cƒü½lYÁz CávQ+àTüZD3?[šå>øaCªP|ºŒë)äÏÖ²B%wû™-ºÖøT(X@ÂßDô a³&~U~o7ĪêUÏW¶Ëjõ]­²lþî4 Z•ª/>(fÜà`jn®ÂP(î,‰F7Þ´Cu„<žÂd®c\Ö{\°<,º 7³ÇqfNÔ4ÌþJÙtOdmß3ßèÝaöÅ™øx ÏSó×;ícõ÷€ÜGùBÖ¹ …9¤}‹'ïY›ÏU2¿ ¹¡\ðö7h¯žmhÕK}=œ‡É‡(ß '~cÝl³ÊJ½úÆEf´¡Yuž›¬M£¯ßŒ't,9È¿¥Võ3P2A)¢Ò»wœŽ’ ZÊTOFMÇ7T‚Ôå! ¹Ó¦bU!1€ÇlL§Š1#á7,ʤKõ¦—~M†!å>/¾ƒ×©N4æê§%ÞÌ©–“ÖºMžœl\Šÿ©våG|ŽÃIÑœ¸Ë¤U±ßÀÏÍ7$°¾ d+SªCèsT-i[PÍ’ax)ž8²§e„Ü ˜)“ÁѲٔ‚üÍ,T×I$R¡Ší{FÕ°‡€’ÓÓlº“ZŸ‡S¤®•UŽV o°Ê||w•Rž$&© s[ e`½~nL§éÏUäqA¨·†Ýçé;”(@ºpt@1¿€ogsç弎ÿY"˜ŽkªºŸ)·L…ÌlC§üÂ-èúäxC=”CüÁ¼žÕÊlf9‡¯ŽÅ·Ó¨èL—ôÙ“úÏ|ž×Xw…н-Áê‡|NOS„˜x‹I•o`¹Yû](b®¥§ãZ^yò&“»ÎN-žÇhåƒi¥ƒ—„Þ°­áíö9#ÉðäZ€¼PM¼Ôhö&ÊíÞÕ÷ùXÞõ@å¤î¦Áúœ†3øšiŒy£A¨Îõ” ü¾.‚«-þ)dws*2 þ [†Å«›”Ϥ[KÓ%Ì¢ë¿Û¥øg­ÞJ¡1Êt× ´Å§8˜Bz×F|\£Px}Éãφ~;¤œW -”£õÁ)Ýc£èGS+iµ4LQŒUž,} †ç÷Š…j=6)KëÞ1Ýx¤7ÝqíAo,=“Šð˜6_Ló»ÿÑû˜û 5º#Iv×,:wœÅê´½¹Kªm6icĤ’t¦§¸;`h÷]ýÉÁ"]AT¦É8äËs^³s4#hÎÀ2H“Õ(Ò÷4n`ˆ.o}2¯Ý$ÝM•¡óØ·¶™~’jrž¹<9¶ÏÑŽ÷/ÁA~-êrh‡æ÷ 3êÊ:ê3rŠ ¼OXÄ ­"y×A…§ÆgÆ•Ðé3ÖŒÇǃÛ@S¦·‡ B˜#›”è:g‰\sÇSÑ\™ö²Ï’š)D~±L¶ xâ¯ð)Ôn´À.ð-™gUé•eéÓ•¨Ú=©›nmjLÙÏ%nÞSuÃ#OiÉRóßKf«®ìdÅéà¿ò °³%@ÙŠ€36¶&êg0&êUpa²ÚÒ?¬^b“4‡ú?Î6ò!düqº±4PÃ<º uŽĄÃÒµ) %ºP‹Œ0¯hWC…è4Çx²\ëé’UÚ l|ÄÍõ±x¦ë×{¿pKV Á:Éþüf„BºЙR5z/ äÛ^׈/ m/6ЧìIJƒg6òŠÈà‡ÿ*øóšÞÉLïZÚ¬‚+i–²¯/NøŠI¹‹Î>†tÅÈ“&Éà_, vÙ ²™ÖîæúT(QBpù®°Ðå*æ4û¯ fÁ:%·¹ùY|J‹-÷,Á®!¹-r?e§Î-jݳ»>†²Æ ˜T¦+0Ú‘u z“Úì³£l²œLÿaœçc+û‰—»Qñ±Ö¸]Æa üÜׂv-¯Ô‹Ã­à3aÕè %ˆD-¿ÙMm±ËŠ5‘õ¯KURþÙäSŸb9¬å°ÅlRî$Vý1¾Yx$@§MŶTÔª(Âq ö„¯H!LD÷V…D²j hþ&aE| »áéAHÛÄ÷:·½Yå #h<†ôy Ñ"ñ2ª!T`hZßXÏLÒ‰.ç%Ye›*0s3Ôèw"ÅØç /˜°º×8#Üìz"ÿµñ9>i‚› ö[*ãõ†õˆmaû¯ßŒk!SäˆûŠÕët¡t•UÙܬŒLUà¾HâOF¯"ÞR–¸‚—Ë'‡Ûß²™síQg+LNmKt5¨È˰™ÊŒV¢<ÎyC '¾µÏÑQ¢òXÒYª–_B‚xabùøMÓ)H”ÇXdöœ+¤€HÜìC(©ýœ:•´W?^ÛÆñg_¸Œ|Úöù,‚¶Ó'•ïà $ É’˜bœ‹úIYñÝeÛ åÝÖË¿‚[ÈPÖiOwñÞm™®?{ÞMîËÌ*=ÊýºOp§:ITf¨>vÈZv [ ]v¾pu ¸c„r­›!²úËO^¹Å73,=dÚ{H[bÏâ˜[coêöÞ£ÖPºØHÞ87ÍÓ!\Ðv:-n—À%ò\°nðá&=Ì?o¢ l ×TÎuˆE4æ ÿ1áP?6EÛï>YÝ7–‹º¡M/J0ÔžƒØ¢24h?¯7liâòò»² L=R±~-Ü…ãK—JìŸþËÌ£Ûèܼn¯w)Ma&æ½(cF£$Ò™Ùê“©}ÊÒyÀä oÄ:é¦úKýŸq±ú‘í>ïõáÍA1§¨QjÚ¿z÷‡4‘P;INŠ{¬žhDÌ)•«ç×âûd ´eµ¥ÿXûj¾ˆ¿Ñk>63Ò¼ÌSX3ëÎKsÌD\dp}"cXZ¯¯få6Wÿªý´ÎÍÅ<’=§þÚÿ+ÑÛì•'õÓRî\ í^c*Ü>¼ Ku£óšd²Â%~§ÜªH4 GMÝ;LÉŒ¶vIä Oí¹cÇù[òž©Ò4ƒ`AD54½-ëâÃLŠl¸®àäFrñªî5¯íQeÅ}Óy[éÆ¿1ëf–LÜë6’ޏ߶²»žŸØæK&Wœº˜.š®QWR¹OšPôÏ# 7ßåß22úû H5EoGZz:ã¶ÔÌêå¶1ÅAÌÁzô5d”¸,çùu`Ú¨Sw¶ØE_Åa+ø`龩s2øX‚ï|CûÛΦˆÚ¦>ö¨ãa‡¤U+Ðí§›4HÕùc凟â=]²Ù&]' JŸÀÙjÛ—ÕïA5ÔßÔLä„•+«aìuR©ÿìàoN ñ–8©U¸½#k˜f˜ ¶âü"Ãa¶Ùú5 ï¿ñNÙŒ6ź>³+øÝõ.Y~²&Ä«‰h ïÆæ½ÏLÖB®M‰>áDn©Èuþòhw¹ƒþÎÓgƒ!¡5ŠÈ Á†«¯áг…0ŸûÄ3’\ÄåÝùj¥OðáËâaÃà|ª5’°Ôa}ŽeFïŽÃ ¯›•½ö‡Ô ÿOBÓAo5V‘ÇãHx‰/D8,öïì6°Ró4Êmñ²KbÇ_¢s:|;beÅ”MA´^<;?ÃÔîÚ˹ûÏ·gJÑ#½±ž‡È µ™ŠÎ×ÉÔ,T&ÑA77yj¥Ð7Úr²kÓÏv؆ù[Ý*ðíIHDõƒ¾æ[3ðWïZ9ÉÓr=oTØwWpxÄØñi†À!še£’qB"Îdëb#且ºê‚+Á}ØßØóÁ»]¬ÿOþ+ø˜Û[šºº;9˜ºÚ!ügï1endstream endobj 1034 0 obj << /Type /Font /Subtype /Type1 /Encoding 3111 0 R /FirstChar 2 /LastChar 151 /Widths 3128 0 R /BaseFont /LJCUIA+URWPalladioL-Bold /FontDescriptor 1032 0 R >> endobj 1032 0 obj << /Ascent 708 /CapHeight 672 /Descent -266 /FontName /LJCUIA+URWPalladioL-Bold /ItalicAngle 0 /StemV 123 /XHeight 471 /FontBBox [-152 -301 1000 935] /Flags 4 /CharSet (/fi/fl/exclam/numbersign/dollar/percent/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/equal/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/quotedblright/endash/emdash) /FontFile 1033 0 R >> endobj 3128 0 obj [611 611 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 278 0 500 500 889 0 278 333 333 444 606 250 333 250 296 500 500 500 500 500 500 500 500 500 500 250 250 0 606 0 444 747 778 667 722 833 611 556 833 833 389 389 778 611 1000 833 833 611 833 722 611 667 778 778 1000 667 667 667 333 0 333 0 0 0 500 611 444 611 500 389 556 611 333 333 611 333 889 611 556 611 611 389 444 333 611 556 833 500 556 500 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 500 0 500 1000 ] endobj 1038 0 obj << /Type /Pages /Count 6 /Parent 3129 0 R /Kids [1026 0 R 1055 0 R 1062 0 R 1117 0 R 1181 0 R 1244 0 R] >> endobj 1346 0 obj << /Type /Pages /Count 6 /Parent 3129 0 R /Kids [1305 0 R 1348 0 R 1360 0 R 1373 0 R 1384 0 R 1391 0 R] >> endobj 1407 0 obj << /Type /Pages /Count 6 /Parent 3129 0 R /Kids [1403 0 R 1409 0 R 1417 0 R 1426 0 R 1436 0 R 1444 0 R] >> endobj 1454 0 obj << /Type /Pages /Count 6 /Parent 3129 0 R /Kids [1451 0 R 1457 0 R 1479 0 R 1492 0 R 1497 0 R 1502 0 R] >> endobj 1515 0 obj << /Type /Pages /Count 6 /Parent 3129 0 R /Kids [1507 0 R 1517 0 R 1526 0 R 1533 0 R 1539 0 R 1543 0 R] >> endobj 1562 0 obj << /Type /Pages /Count 6 /Parent 3129 0 R /Kids [1552 0 R 1566 0 R 1573 0 R 1583 0 R 1593 0 R 1600 0 R] >> endobj 1613 0 obj << /Type /Pages /Count 6 /Parent 3130 0 R /Kids [1608 0 R 1615 0 R 1622 0 R 1629 0 R 1635 0 R 1644 0 R] >> endobj 1654 0 obj << /Type /Pages /Count 6 /Parent 3130 0 R /Kids [1649 0 R 1656 0 R 1665 0 R 1669 0 R 1676 0 R 1680 0 R] >> endobj 1693 0 obj << /Type /Pages /Count 6 /Parent 3130 0 R /Kids [1690 0 R 1695 0 R 1702 0 R 1711 0 R 1719 0 R 1724 0 R] >> endobj 1743 0 obj << /Type /Pages /Count 6 /Parent 3130 0 R /Kids [1734 0 R 1745 0 R 1750 0 R 1756 0 R 1762 0 R 1766 0 R] >> endobj 1780 0 obj << /Type /Pages /Count 6 /Parent 3130 0 R /Kids [1773 0 R 1782 0 R 1789 0 R 1793 0 R 1797 0 R 1801 0 R] >> endobj 1810 0 obj << /Type /Pages /Count 6 /Parent 3130 0 R /Kids [1806 0 R 1812 0 R 1816 0 R 1823 0 R 1828 0 R 1833 0 R] >> endobj 1844 0 obj << /Type /Pages /Count 6 /Parent 3131 0 R /Kids [1840 0 R 1846 0 R 1855 0 R 1859 0 R 1863 0 R 1867 0 R] >> endobj 1882 0 obj << /Type /Pages /Count 6 /Parent 3131 0 R /Kids [1876 0 R 1884 0 R 1891 0 R 1896 0 R 1901 0 R 1905 0 R] >> endobj 1914 0 obj << /Type /Pages /Count 6 /Parent 3131 0 R /Kids [1909 0 R 1916 0 R 1924 0 R 1928 0 R 1933 0 R 1940 0 R] >> endobj 1952 0 obj << /Type /Pages /Count 6 /Parent 3131 0 R /Kids [1945 0 R 1954 0 R 1959 0 R 1965 0 R 1972 0 R 1977 0 R] >> endobj 1984 0 obj << /Type /Pages /Count 6 /Parent 3131 0 R /Kids [1981 0 R 1986 0 R 1990 0 R 1996 0 R 2001 0 R 2010 0 R] >> endobj 2018 0 obj << /Type /Pages /Count 6 /Parent 3131 0 R /Kids [2014 0 R 2020 0 R 2024 0 R 2029 0 R 2035 0 R 2056 0 R] >> endobj 2074 0 obj << /Type /Pages /Count 6 /Parent 3132 0 R /Kids [2070 0 R 2076 0 R 2080 0 R 2084 0 R 2088 0 R 2092 0 R] >> endobj 2103 0 obj << /Type /Pages /Count 6 /Parent 3132 0 R /Kids [2100 0 R 2105 0 R 2114 0 R 2134 0 R 2148 0 R 2162 0 R] >> endobj 2181 0 obj << /Type /Pages /Count 6 /Parent 3132 0 R /Kids [2176 0 R 2183 0 R 2187 0 R 2192 0 R 2202 0 R 2208 0 R] >> endobj 2218 0 obj << /Type /Pages /Count 6 /Parent 3132 0 R /Kids [2212 0 R 2220 0 R 2232 0 R 2244 0 R 2251 0 R 2257 0 R] >> endobj 2272 0 obj << /Type /Pages /Count 6 /Parent 3132 0 R /Kids [2264 0 R 2274 0 R 2280 0 R 2290 0 R 2301 0 R 2305 0 R] >> endobj 2320 0 obj << /Type /Pages /Count 6 /Parent 3132 0 R /Kids [2311 0 R 2322 0 R 2326 0 R 2330 0 R 2341 0 R 2345 0 R] >> endobj 2365 0 obj << /Type /Pages /Count 6 /Parent 3133 0 R /Kids [2355 0 R 2367 0 R 2373 0 R 2377 0 R 2385 0 R 2444 0 R] >> endobj 2555 0 obj << /Type /Pages /Count 6 /Parent 3133 0 R /Kids [2502 0 R 2557 0 R 2591 0 R 2595 0 R 2603 0 R 2612 0 R] >> endobj 2624 0 obj << /Type /Pages /Count 6 /Parent 3133 0 R /Kids [2618 0 R 2626 0 R 2631 0 R 2636 0 R 2645 0 R 2651 0 R] >> endobj 2659 0 obj << /Type /Pages /Count 6 /Parent 3133 0 R /Kids [2656 0 R 2661 0 R 2665 0 R 2669 0 R 2677 0 R 2686 0 R] >> endobj 2702 0 obj << /Type /Pages /Count 6 /Parent 3133 0 R /Kids [2696 0 R 2704 0 R 2708 0 R 2713 0 R 2719 0 R 2732 0 R] >> endobj 2748 0 obj << /Type /Pages /Count 6 /Parent 3133 0 R /Kids [2739 0 R 2750 0 R 2756 0 R 2768 0 R 2777 0 R 2785 0 R] >> endobj 2794 0 obj << /Type /Pages /Count 6 /Parent 3134 0 R /Kids [2789 0 R 2796 0 R 2806 0 R 2810 0 R 2814 0 R 2820 0 R] >> endobj 2840 0 obj << /Type /Pages /Count 6 /Parent 3134 0 R /Kids [2832 0 R 2842 0 R 2848 0 R 2858 0 R 2864 0 R 2868 0 R] >> endobj 2875 0 obj << /Type /Pages /Count 6 /Parent 3134 0 R /Kids [2872 0 R 2877 0 R 2886 0 R 2894 0 R 2904 0 R 2916 0 R] >> endobj 2926 0 obj << /Type /Pages /Count 6 /Parent 3134 0 R /Kids [2920 0 R 2928 0 R 2937 0 R 2941 0 R 2947 0 R 2959 0 R] >> endobj 2977 0 obj << /Type /Pages /Count 6 /Parent 3134 0 R /Kids [2972 0 R 2979 0 R 2984 0 R 2988 0 R 2994 0 R 3004 0 R] >> endobj 3012 0 obj << /Type /Pages /Count 6 /Parent 3134 0 R /Kids [3009 0 R 3014 0 R 3018 0 R 3023 0 R 3033 0 R 3038 0 R] >> endobj 3056 0 obj << /Type /Pages /Count 6 /Parent 3135 0 R /Kids [3050 0 R 3058 0 R 3067 0 R 3079 0 R 3093 0 R 3106 0 R] >> endobj 3129 0 obj << /Type /Pages /Count 36 /Parent 3136 0 R /Kids [1038 0 R 1346 0 R 1407 0 R 1454 0 R 1515 0 R 1562 0 R] >> endobj 3130 0 obj << /Type /Pages /Count 36 /Parent 3136 0 R /Kids [1613 0 R 1654 0 R 1693 0 R 1743 0 R 1780 0 R 1810 0 R] >> endobj 3131 0 obj << /Type /Pages /Count 36 /Parent 3136 0 R /Kids [1844 0 R 1882 0 R 1914 0 R 1952 0 R 1984 0 R 2018 0 R] >> endobj 3132 0 obj << /Type /Pages /Count 36 /Parent 3136 0 R /Kids [2074 0 R 2103 0 R 2181 0 R 2218 0 R 2272 0 R 2320 0 R] >> endobj 3133 0 obj << /Type /Pages /Count 36 /Parent 3136 0 R /Kids [2365 0 R 2555 0 R 2624 0 R 2659 0 R 2702 0 R 2748 0 R] >> endobj 3134 0 obj << /Type /Pages /Count 36 /Parent 3136 0 R /Kids [2794 0 R 2840 0 R 2875 0 R 2926 0 R 2977 0 R 3012 0 R] >> endobj 3135 0 obj << /Type /Pages /Count 6 /Parent 3137 0 R /Kids [3056 0 R] >> endobj 3136 0 obj << /Type /Pages /Count 216 /Parent 3138 0 R /Kids [3129 0 R 3130 0 R 3131 0 R 3132 0 R 3133 0 R 3134 0 R] >> endobj 3137 0 obj << /Type /Pages /Count 6 /Parent 3138 0 R /Kids [3135 0 R] >> endobj 3138 0 obj << /Type /Pages /Count 222 /Kids [3136 0 R 3137 0 R] >> endobj 3139 0 obj << /Type /Outlines /First 7 0 R /Last 915 0 R /Count 13 >> endobj 1023 0 obj << /Title 1024 0 R /A 1021 0 R /Parent 915 0 R /Prev 1019 0 R >> endobj 1019 0 obj << /Title 1020 0 R /A 1017 0 R /Parent 915 0 R /Prev 1015 0 R /Next 1023 0 R >> endobj 1015 0 obj << /Title 1016 0 R /A 1013 0 R /Parent 915 0 R /Prev 1011 0 R /Next 1019 0 R >> endobj 1011 0 obj << /Title 1012 0 R /A 1009 0 R /Parent 915 0 R /Prev 1007 0 R /Next 1015 0 R >> endobj 1007 0 obj << /Title 1008 0 R /A 1005 0 R /Parent 915 0 R /Prev 1003 0 R /Next 1011 0 R >> endobj 1003 0 obj << /Title 1004 0 R /A 1001 0 R /Parent 915 0 R /Prev 999 0 R /Next 1007 0 R >> endobj 999 0 obj << /Title 1000 0 R /A 997 0 R /Parent 915 0 R /Prev 995 0 R /Next 1003 0 R >> endobj 995 0 obj << /Title 996 0 R /A 993 0 R /Parent 915 0 R /Prev 991 0 R /Next 999 0 R >> endobj 991 0 obj << /Title 992 0 R /A 989 0 R /Parent 915 0 R /Prev 987 0 R /Next 995 0 R >> endobj 987 0 obj << /Title 988 0 R /A 985 0 R /Parent 915 0 R /Prev 983 0 R /Next 991 0 R >> endobj 983 0 obj << /Title 984 0 R /A 981 0 R /Parent 915 0 R /Prev 979 0 R /Next 987 0 R >> endobj 979 0 obj << /Title 980 0 R /A 977 0 R /Parent 915 0 R /Prev 975 0 R /Next 983 0 R >> endobj 975 0 obj << /Title 976 0 R /A 973 0 R /Parent 915 0 R /Prev 971 0 R /Next 979 0 R >> endobj 971 0 obj << /Title 972 0 R /A 969 0 R /Parent 915 0 R /Prev 967 0 R /Next 975 0 R >> endobj 967 0 obj << /Title 968 0 R /A 965 0 R /Parent 915 0 R /Prev 963 0 R /Next 971 0 R >> endobj 963 0 obj << /Title 964 0 R /A 961 0 R /Parent 915 0 R /Prev 959 0 R /Next 967 0 R >> endobj 959 0 obj << /Title 960 0 R /A 957 0 R /Parent 915 0 R /Prev 955 0 R /Next 963 0 R >> endobj 955 0 obj << /Title 956 0 R /A 953 0 R /Parent 915 0 R /Prev 951 0 R /Next 959 0 R >> endobj 951 0 obj << /Title 952 0 R /A 949 0 R /Parent 915 0 R /Prev 947 0 R /Next 955 0 R >> endobj 947 0 obj << /Title 948 0 R /A 945 0 R /Parent 915 0 R /Prev 943 0 R /Next 951 0 R >> endobj 943 0 obj << /Title 944 0 R /A 941 0 R /Parent 915 0 R /Prev 939 0 R /Next 947 0 R >> endobj 939 0 obj << /Title 940 0 R /A 937 0 R /Parent 915 0 R /Prev 935 0 R /Next 943 0 R >> endobj 935 0 obj << /Title 936 0 R /A 933 0 R /Parent 915 0 R /Prev 931 0 R /Next 939 0 R >> endobj 931 0 obj << /Title 932 0 R /A 929 0 R /Parent 915 0 R /Prev 927 0 R /Next 935 0 R >> endobj 927 0 obj << /Title 928 0 R /A 925 0 R /Parent 915 0 R /Prev 923 0 R /Next 931 0 R >> endobj 923 0 obj << /Title 924 0 R /A 921 0 R /Parent 915 0 R /Prev 919 0 R /Next 927 0 R >> endobj 919 0 obj << /Title 920 0 R /A 917 0 R /Parent 915 0 R /Next 923 0 R >> endobj 915 0 obj << /Title 916 0 R /A 913 0 R /Parent 3139 0 R /Prev 855 0 R /First 919 0 R /Last 1023 0 R /Count -27 >> endobj 911 0 obj << /Title 912 0 R /A 909 0 R /Parent 859 0 R /Prev 883 0 R >> endobj 907 0 obj << /Title 908 0 R /A 905 0 R /Parent 883 0 R /Prev 903 0 R >> endobj 903 0 obj << /Title 904 0 R /A 901 0 R /Parent 883 0 R /Prev 899 0 R /Next 907 0 R >> endobj 899 0 obj << /Title 900 0 R /A 897 0 R /Parent 883 0 R /Prev 895 0 R /Next 903 0 R >> endobj 895 0 obj << /Title 896 0 R /A 893 0 R /Parent 883 0 R /Prev 891 0 R /Next 899 0 R >> endobj 891 0 obj << /Title 892 0 R /A 889 0 R /Parent 883 0 R /Prev 887 0 R /Next 895 0 R >> endobj 887 0 obj << /Title 888 0 R /A 885 0 R /Parent 883 0 R /Next 891 0 R >> endobj 883 0 obj << /Title 884 0 R /A 881 0 R /Parent 859 0 R /Prev 879 0 R /Next 911 0 R /First 887 0 R /Last 907 0 R /Count -6 >> endobj 879 0 obj << /Title 880 0 R /A 877 0 R /Parent 859 0 R /Prev 875 0 R /Next 883 0 R >> endobj 875 0 obj << /Title 876 0 R /A 873 0 R /Parent 859 0 R /Prev 871 0 R /Next 879 0 R >> endobj 871 0 obj << /Title 872 0 R /A 869 0 R /Parent 859 0 R /Prev 867 0 R /Next 875 0 R >> endobj 867 0 obj << /Title 868 0 R /A 865 0 R /Parent 859 0 R /Prev 863 0 R /Next 871 0 R >> endobj 863 0 obj << /Title 864 0 R /A 861 0 R /Parent 859 0 R /Next 867 0 R >> endobj 859 0 obj << /Title 860 0 R /A 857 0 R /Parent 855 0 R /First 863 0 R /Last 911 0 R /Count -7 >> endobj 855 0 obj << /Title 856 0 R /A 853 0 R /Parent 3139 0 R /Prev 831 0 R /Next 915 0 R /First 859 0 R /Last 859 0 R /Count -1 >> endobj 851 0 obj << /Title 852 0 R /A 849 0 R /Parent 839 0 R /Prev 847 0 R >> endobj 847 0 obj << /Title 848 0 R /A 845 0 R /Parent 839 0 R /Prev 843 0 R /Next 851 0 R >> endobj 843 0 obj << /Title 844 0 R /A 841 0 R /Parent 839 0 R /Next 847 0 R >> endobj 839 0 obj << /Title 840 0 R /A 837 0 R /Parent 831 0 R /Prev 835 0 R /First 843 0 R /Last 851 0 R /Count -3 >> endobj 835 0 obj << /Title 836 0 R /A 833 0 R /Parent 831 0 R /Next 839 0 R >> endobj 831 0 obj << /Title 832 0 R /A 829 0 R /Parent 3139 0 R /Prev 823 0 R /Next 855 0 R /First 835 0 R /Last 839 0 R /Count -2 >> endobj 827 0 obj << /Title 828 0 R /A 825 0 R /Parent 823 0 R >> endobj 823 0 obj << /Title 824 0 R /A 821 0 R /Parent 3139 0 R /Prev 783 0 R /Next 831 0 R /First 827 0 R /Last 827 0 R /Count -1 >> endobj 819 0 obj << /Title 820 0 R /A 817 0 R /Parent 787 0 R /Prev 815 0 R >> endobj 815 0 obj << /Title 816 0 R /A 813 0 R /Parent 787 0 R /Prev 811 0 R /Next 819 0 R >> endobj 811 0 obj << /Title 812 0 R /A 809 0 R /Parent 787 0 R /Prev 807 0 R /Next 815 0 R >> endobj 807 0 obj << /Title 808 0 R /A 805 0 R /Parent 787 0 R /Prev 803 0 R /Next 811 0 R >> endobj 803 0 obj << /Title 804 0 R /A 801 0 R /Parent 787 0 R /Prev 799 0 R /Next 807 0 R >> endobj 799 0 obj << /Title 800 0 R /A 797 0 R /Parent 787 0 R /Prev 795 0 R /Next 803 0 R >> endobj 795 0 obj << /Title 796 0 R /A 793 0 R /Parent 787 0 R /Prev 791 0 R /Next 799 0 R >> endobj 791 0 obj << /Title 792 0 R /A 789 0 R /Parent 787 0 R /Next 795 0 R >> endobj 787 0 obj << /Title 788 0 R /A 785 0 R /Parent 783 0 R /First 791 0 R /Last 819 0 R /Count -8 >> endobj 783 0 obj << /Title 784 0 R /A 781 0 R /Parent 3139 0 R /Prev 763 0 R /Next 823 0 R /First 787 0 R /Last 787 0 R /Count -1 >> endobj 779 0 obj << /Title 780 0 R /A 777 0 R /Parent 763 0 R /Prev 775 0 R >> endobj 775 0 obj << /Title 776 0 R /A 773 0 R /Parent 763 0 R /Prev 767 0 R /Next 779 0 R >> endobj 771 0 obj << /Title 772 0 R /A 769 0 R /Parent 767 0 R >> endobj 767 0 obj << /Title 768 0 R /A 765 0 R /Parent 763 0 R /Next 775 0 R /First 771 0 R /Last 771 0 R /Count -1 >> endobj 763 0 obj << /Title 764 0 R /A 761 0 R /Parent 3139 0 R /Prev 739 0 R /Next 783 0 R /First 767 0 R /Last 779 0 R /Count -3 >> endobj 759 0 obj << /Title 760 0 R /A 757 0 R /Parent 739 0 R /Prev 747 0 R >> endobj 755 0 obj << /Title 756 0 R /A 753 0 R /Parent 747 0 R /Prev 751 0 R >> endobj 751 0 obj << /Title 752 0 R /A 749 0 R /Parent 747 0 R /Next 755 0 R >> endobj 747 0 obj << /Title 748 0 R /A 745 0 R /Parent 739 0 R /Prev 743 0 R /Next 759 0 R /First 751 0 R /Last 755 0 R /Count -2 >> endobj 743 0 obj << /Title 744 0 R /A 741 0 R /Parent 739 0 R /Next 747 0 R >> endobj 739 0 obj << /Title 740 0 R /A 737 0 R /Parent 3139 0 R /Prev 387 0 R /Next 763 0 R /First 743 0 R /Last 759 0 R /Count -3 >> endobj 735 0 obj << /Title 736 0 R /A 733 0 R /Parent 715 0 R /Prev 731 0 R >> endobj 731 0 obj << /Title 732 0 R /A 729 0 R /Parent 715 0 R /Prev 727 0 R /Next 735 0 R >> endobj 727 0 obj << /Title 728 0 R /A 725 0 R /Parent 715 0 R /Prev 723 0 R /Next 731 0 R >> endobj 723 0 obj << /Title 724 0 R /A 721 0 R /Parent 715 0 R /Prev 719 0 R /Next 727 0 R >> endobj 719 0 obj << /Title 720 0 R /A 717 0 R /Parent 715 0 R /Next 723 0 R >> endobj 715 0 obj << /Title 716 0 R /A 713 0 R /Parent 707 0 R /Prev 711 0 R /First 719 0 R /Last 735 0 R /Count -5 >> endobj 711 0 obj << /Title 712 0 R /A 709 0 R /Parent 707 0 R /Next 715 0 R >> endobj 707 0 obj << /Title 708 0 R /A 705 0 R /Parent 387 0 R /Prev 651 0 R /First 711 0 R /Last 715 0 R /Count -2 >> endobj 703 0 obj << /Title 704 0 R /A 701 0 R /Parent 651 0 R /Prev 699 0 R >> endobj 699 0 obj << /Title 700 0 R /A 697 0 R /Parent 651 0 R /Prev 679 0 R /Next 703 0 R >> endobj 695 0 obj << /Title 696 0 R /A 693 0 R /Parent 679 0 R /Prev 691 0 R >> endobj 691 0 obj << /Title 692 0 R /A 689 0 R /Parent 679 0 R /Prev 687 0 R /Next 695 0 R >> endobj 687 0 obj << /Title 688 0 R /A 685 0 R /Parent 679 0 R /Prev 683 0 R /Next 691 0 R >> endobj 683 0 obj << /Title 684 0 R /A 681 0 R /Parent 679 0 R /Next 687 0 R >> endobj 679 0 obj << /Title 680 0 R /A 677 0 R /Parent 651 0 R /Prev 675 0 R /Next 699 0 R /First 683 0 R /Last 695 0 R /Count -4 >> endobj 675 0 obj << /Title 676 0 R /A 673 0 R /Parent 651 0 R /Prev 671 0 R /Next 679 0 R >> endobj 671 0 obj << /Title 672 0 R /A 669 0 R /Parent 651 0 R /Prev 667 0 R /Next 675 0 R >> endobj 667 0 obj << /Title 668 0 R /A 665 0 R /Parent 651 0 R /Prev 655 0 R /Next 671 0 R >> endobj 663 0 obj << /Title 664 0 R /A 661 0 R /Parent 655 0 R /Prev 659 0 R >> endobj 659 0 obj << /Title 660 0 R /A 657 0 R /Parent 655 0 R /Next 663 0 R >> endobj 655 0 obj << /Title 656 0 R /A 653 0 R /Parent 651 0 R /Next 667 0 R /First 659 0 R /Last 663 0 R /Count -2 >> endobj 651 0 obj << /Title 652 0 R /A 649 0 R /Parent 387 0 R /Prev 419 0 R /Next 707 0 R /First 655 0 R /Last 703 0 R /Count -7 >> endobj 647 0 obj << /Title 648 0 R /A 645 0 R /Parent 627 0 R /Prev 643 0 R >> endobj 643 0 obj << /Title 644 0 R /A 641 0 R /Parent 627 0 R /Prev 639 0 R /Next 647 0 R >> endobj 639 0 obj << /Title 640 0 R /A 637 0 R /Parent 627 0 R /Prev 635 0 R /Next 643 0 R >> endobj 635 0 obj << /Title 636 0 R /A 633 0 R /Parent 627 0 R /Prev 631 0 R /Next 639 0 R >> endobj 631 0 obj << /Title 632 0 R /A 629 0 R /Parent 627 0 R /Next 635 0 R >> endobj 627 0 obj << /Title 628 0 R /A 625 0 R /Parent 419 0 R /Prev 623 0 R /First 631 0 R /Last 647 0 R /Count -5 >> endobj 623 0 obj << /Title 624 0 R /A 621 0 R /Parent 419 0 R /Prev 619 0 R /Next 627 0 R >> endobj 619 0 obj << /Title 620 0 R /A 617 0 R /Parent 419 0 R /Prev 615 0 R /Next 623 0 R >> endobj 615 0 obj << /Title 616 0 R /A 613 0 R /Parent 419 0 R /Prev 611 0 R /Next 619 0 R >> endobj 611 0 obj << /Title 612 0 R /A 609 0 R /Parent 419 0 R /Prev 607 0 R /Next 615 0 R >> endobj 607 0 obj << /Title 608 0 R /A 605 0 R /Parent 419 0 R /Prev 603 0 R /Next 611 0 R >> endobj 603 0 obj << /Title 604 0 R /A 601 0 R /Parent 419 0 R /Prev 599 0 R /Next 607 0 R >> endobj 599 0 obj << /Title 600 0 R /A 597 0 R /Parent 419 0 R /Prev 595 0 R /Next 603 0 R >> endobj 595 0 obj << /Title 596 0 R /A 593 0 R /Parent 419 0 R /Prev 591 0 R /Next 599 0 R >> endobj 591 0 obj << /Title 592 0 R /A 589 0 R /Parent 419 0 R /Prev 587 0 R /Next 595 0 R >> endobj 587 0 obj << /Title 588 0 R /A 585 0 R /Parent 419 0 R /Prev 583 0 R /Next 591 0 R >> endobj 583 0 obj << /Title 584 0 R /A 581 0 R /Parent 419 0 R /Prev 495 0 R /Next 587 0 R >> endobj 579 0 obj << /Title 580 0 R /A 577 0 R /Parent 495 0 R /Prev 575 0 R >> endobj 575 0 obj << /Title 576 0 R /A 573 0 R /Parent 495 0 R /Prev 571 0 R /Next 579 0 R >> endobj 571 0 obj << /Title 572 0 R /A 569 0 R /Parent 495 0 R /Prev 567 0 R /Next 575 0 R >> endobj 567 0 obj << /Title 568 0 R /A 565 0 R /Parent 495 0 R /Prev 563 0 R /Next 571 0 R >> endobj 563 0 obj << /Title 564 0 R /A 561 0 R /Parent 495 0 R /Prev 559 0 R /Next 567 0 R >> endobj 559 0 obj << /Title 560 0 R /A 557 0 R /Parent 495 0 R /Prev 555 0 R /Next 563 0 R >> endobj 555 0 obj << /Title 556 0 R /A 553 0 R /Parent 495 0 R /Prev 551 0 R /Next 559 0 R >> endobj 551 0 obj << /Title 552 0 R /A 549 0 R /Parent 495 0 R /Prev 547 0 R /Next 555 0 R >> endobj 547 0 obj << /Title 548 0 R /A 545 0 R /Parent 495 0 R /Prev 543 0 R /Next 551 0 R >> endobj 543 0 obj << /Title 544 0 R /A 541 0 R /Parent 495 0 R /Prev 539 0 R /Next 547 0 R >> endobj 539 0 obj << /Title 540 0 R /A 537 0 R /Parent 495 0 R /Prev 535 0 R /Next 543 0 R >> endobj 535 0 obj << /Title 536 0 R /A 533 0 R /Parent 495 0 R /Prev 531 0 R /Next 539 0 R >> endobj 531 0 obj << /Title 532 0 R /A 529 0 R /Parent 495 0 R /Prev 527 0 R /Next 535 0 R >> endobj 527 0 obj << /Title 528 0 R /A 525 0 R /Parent 495 0 R /Prev 523 0 R /Next 531 0 R >> endobj 523 0 obj << /Title 524 0 R /A 521 0 R /Parent 495 0 R /Prev 519 0 R /Next 527 0 R >> endobj 519 0 obj << /Title 520 0 R /A 517 0 R /Parent 495 0 R /Prev 515 0 R /Next 523 0 R >> endobj 515 0 obj << /Title 516 0 R /A 513 0 R /Parent 495 0 R /Prev 511 0 R /Next 519 0 R >> endobj 511 0 obj << /Title 512 0 R /A 509 0 R /Parent 495 0 R /Prev 507 0 R /Next 515 0 R >> endobj 507 0 obj << /Title 508 0 R /A 505 0 R /Parent 495 0 R /Prev 503 0 R /Next 511 0 R >> endobj 503 0 obj << /Title 504 0 R /A 501 0 R /Parent 495 0 R /Prev 499 0 R /Next 507 0 R >> endobj 499 0 obj << /Title 500 0 R /A 497 0 R /Parent 495 0 R /Next 503 0 R >> endobj 495 0 obj << /Title 496 0 R /A 493 0 R /Parent 419 0 R /Prev 491 0 R /Next 583 0 R /First 499 0 R /Last 579 0 R /Count -21 >> endobj 491 0 obj << /Title 492 0 R /A 489 0 R /Parent 419 0 R /Prev 487 0 R /Next 495 0 R >> endobj 487 0 obj << /Title 488 0 R /A 485 0 R /Parent 419 0 R /Prev 483 0 R /Next 491 0 R >> endobj 483 0 obj << /Title 484 0 R /A 481 0 R /Parent 419 0 R /Prev 479 0 R /Next 487 0 R >> endobj 479 0 obj << /Title 480 0 R /A 477 0 R /Parent 419 0 R /Prev 475 0 R /Next 483 0 R >> endobj 475 0 obj << /Title 476 0 R /A 473 0 R /Parent 419 0 R /Prev 459 0 R /Next 479 0 R >> endobj 471 0 obj << /Title 472 0 R /A 469 0 R /Parent 459 0 R /Prev 467 0 R >> endobj 467 0 obj << /Title 468 0 R /A 465 0 R /Parent 459 0 R /Prev 463 0 R /Next 471 0 R >> endobj 463 0 obj << /Title 464 0 R /A 461 0 R /Parent 459 0 R /Next 467 0 R >> endobj 459 0 obj << /Title 460 0 R /A 457 0 R /Parent 419 0 R /Prev 455 0 R /Next 475 0 R /First 463 0 R /Last 471 0 R /Count -3 >> endobj 455 0 obj << /Title 456 0 R /A 453 0 R /Parent 419 0 R /Prev 451 0 R /Next 459 0 R >> endobj 451 0 obj << /Title 452 0 R /A 449 0 R /Parent 419 0 R /Prev 447 0 R /Next 455 0 R >> endobj 447 0 obj << /Title 448 0 R /A 445 0 R /Parent 419 0 R /Prev 443 0 R /Next 451 0 R >> endobj 443 0 obj << /Title 444 0 R /A 441 0 R /Parent 419 0 R /Prev 439 0 R /Next 447 0 R >> endobj 439 0 obj << /Title 440 0 R /A 437 0 R /Parent 419 0 R /Prev 435 0 R /Next 443 0 R >> endobj 435 0 obj << /Title 436 0 R /A 433 0 R /Parent 419 0 R /Prev 431 0 R /Next 439 0 R >> endobj 431 0 obj << /Title 432 0 R /A 429 0 R /Parent 419 0 R /Prev 427 0 R /Next 435 0 R >> endobj 427 0 obj << /Title 428 0 R /A 425 0 R /Parent 419 0 R /Prev 423 0 R /Next 431 0 R >> endobj 423 0 obj << /Title 424 0 R /A 421 0 R /Parent 419 0 R /Next 427 0 R >> endobj 419 0 obj << /Title 420 0 R /A 417 0 R /Parent 387 0 R /Prev 391 0 R /Next 651 0 R /First 423 0 R /Last 627 0 R /Count -28 >> endobj 415 0 obj << /Title 416 0 R /A 413 0 R /Parent 407 0 R /Prev 411 0 R >> endobj 411 0 obj << /Title 412 0 R /A 409 0 R /Parent 407 0 R /Next 415 0 R >> endobj 407 0 obj << /Title 408 0 R /A 405 0 R /Parent 391 0 R /Prev 395 0 R /First 411 0 R /Last 415 0 R /Count -2 >> endobj 403 0 obj << /Title 404 0 R /A 401 0 R /Parent 395 0 R /Prev 399 0 R >> endobj 399 0 obj << /Title 400 0 R /A 397 0 R /Parent 395 0 R /Next 403 0 R >> endobj 395 0 obj << /Title 396 0 R /A 393 0 R /Parent 391 0 R /Next 407 0 R /First 399 0 R /Last 403 0 R /Count -2 >> endobj 391 0 obj << /Title 392 0 R /A 389 0 R /Parent 387 0 R /Next 419 0 R /First 395 0 R /Last 407 0 R /Count -2 >> endobj 387 0 obj << /Title 388 0 R /A 385 0 R /Parent 3139 0 R /Prev 375 0 R /Next 739 0 R /First 391 0 R /Last 707 0 R /Count -4 >> endobj 383 0 obj << /Title 384 0 R /A 381 0 R /Parent 375 0 R /Prev 379 0 R >> endobj 379 0 obj << /Title 380 0 R /A 377 0 R /Parent 375 0 R /Next 383 0 R >> endobj 375 0 obj << /Title 376 0 R /A 373 0 R /Parent 3139 0 R /Prev 131 0 R /Next 387 0 R /First 379 0 R /Last 383 0 R /Count -2 >> endobj 371 0 obj << /Title 372 0 R /A 369 0 R /Parent 363 0 R /Prev 367 0 R >> endobj 367 0 obj << /Title 368 0 R /A 365 0 R /Parent 363 0 R /Next 371 0 R >> endobj 363 0 obj << /Title 364 0 R /A 361 0 R /Parent 131 0 R /Prev 351 0 R /First 367 0 R /Last 371 0 R /Count -2 >> endobj 359 0 obj << /Title 360 0 R /A 357 0 R /Parent 351 0 R /Prev 355 0 R >> endobj 355 0 obj << /Title 356 0 R /A 353 0 R /Parent 351 0 R /Next 359 0 R >> endobj 351 0 obj << /Title 352 0 R /A 349 0 R /Parent 131 0 R /Prev 287 0 R /Next 363 0 R /First 355 0 R /Last 359 0 R /Count -2 >> endobj 347 0 obj << /Title 348 0 R /A 345 0 R /Parent 287 0 R /Prev 343 0 R >> endobj 343 0 obj << /Title 344 0 R /A 341 0 R /Parent 287 0 R /Prev 339 0 R /Next 347 0 R >> endobj 339 0 obj << /Title 340 0 R /A 337 0 R /Parent 287 0 R /Prev 335 0 R /Next 343 0 R >> endobj 335 0 obj << /Title 336 0 R /A 333 0 R /Parent 287 0 R /Prev 303 0 R /Next 339 0 R >> endobj 331 0 obj << /Title 332 0 R /A 329 0 R /Parent 303 0 R /Prev 327 0 R >> endobj 327 0 obj << /Title 328 0 R /A 325 0 R /Parent 303 0 R /Prev 323 0 R /Next 331 0 R >> endobj 323 0 obj << /Title 324 0 R /A 321 0 R /Parent 303 0 R /Prev 319 0 R /Next 327 0 R >> endobj 319 0 obj << /Title 320 0 R /A 317 0 R /Parent 303 0 R /Prev 315 0 R /Next 323 0 R >> endobj 315 0 obj << /Title 316 0 R /A 313 0 R /Parent 303 0 R /Prev 311 0 R /Next 319 0 R >> endobj 311 0 obj << /Title 312 0 R /A 309 0 R /Parent 303 0 R /Prev 307 0 R /Next 315 0 R >> endobj 307 0 obj << /Title 308 0 R /A 305 0 R /Parent 303 0 R /Next 311 0 R >> endobj 303 0 obj << /Title 304 0 R /A 301 0 R /Parent 287 0 R /Prev 295 0 R /Next 335 0 R /First 307 0 R /Last 331 0 R /Count -7 >> endobj 299 0 obj << /Title 300 0 R /A 297 0 R /Parent 295 0 R >> endobj 295 0 obj << /Title 296 0 R /A 293 0 R /Parent 287 0 R /Prev 291 0 R /Next 303 0 R /First 299 0 R /Last 299 0 R /Count -1 >> endobj 291 0 obj << /Title 292 0 R /A 289 0 R /Parent 287 0 R /Next 295 0 R >> endobj 287 0 obj << /Title 288 0 R /A 285 0 R /Parent 131 0 R /Prev 275 0 R /Next 351 0 R /First 291 0 R /Last 347 0 R /Count -7 >> endobj 283 0 obj << /Title 284 0 R /A 281 0 R /Parent 275 0 R /Prev 279 0 R >> endobj 279 0 obj << /Title 280 0 R /A 277 0 R /Parent 275 0 R /Next 283 0 R >> endobj 275 0 obj << /Title 276 0 R /A 273 0 R /Parent 131 0 R /Prev 219 0 R /Next 287 0 R /First 279 0 R /Last 283 0 R /Count -2 >> endobj 271 0 obj << /Title 272 0 R /A 269 0 R /Parent 219 0 R /Prev 267 0 R >> endobj 267 0 obj << /Title 268 0 R /A 265 0 R /Parent 219 0 R /Prev 263 0 R /Next 271 0 R >> endobj 263 0 obj << /Title 264 0 R /A 261 0 R /Parent 219 0 R /Prev 259 0 R /Next 267 0 R >> endobj 259 0 obj << /Title 260 0 R /A 257 0 R /Parent 219 0 R /Prev 255 0 R /Next 263 0 R >> endobj 255 0 obj << /Title 256 0 R /A 253 0 R /Parent 219 0 R /Prev 251 0 R /Next 259 0 R >> endobj 251 0 obj << /Title 252 0 R /A 249 0 R /Parent 219 0 R /Prev 247 0 R /Next 255 0 R >> endobj 247 0 obj << /Title 248 0 R /A 245 0 R /Parent 219 0 R /Prev 243 0 R /Next 251 0 R >> endobj 243 0 obj << /Title 244 0 R /A 241 0 R /Parent 219 0 R /Prev 239 0 R /Next 247 0 R >> endobj 239 0 obj << /Title 240 0 R /A 237 0 R /Parent 219 0 R /Prev 235 0 R /Next 243 0 R >> endobj 235 0 obj << /Title 236 0 R /A 233 0 R /Parent 219 0 R /Prev 231 0 R /Next 239 0 R >> endobj 231 0 obj << /Title 232 0 R /A 229 0 R /Parent 219 0 R /Prev 227 0 R /Next 235 0 R >> endobj 227 0 obj << /Title 228 0 R /A 225 0 R /Parent 219 0 R /Prev 223 0 R /Next 231 0 R >> endobj 223 0 obj << /Title 224 0 R /A 221 0 R /Parent 219 0 R /Next 227 0 R >> endobj 219 0 obj << /Title 220 0 R /A 217 0 R /Parent 131 0 R /Prev 203 0 R /Next 275 0 R /First 223 0 R /Last 271 0 R /Count -13 >> endobj 215 0 obj << /Title 216 0 R /A 213 0 R /Parent 203 0 R /Prev 211 0 R >> endobj 211 0 obj << /Title 212 0 R /A 209 0 R /Parent 203 0 R /Prev 207 0 R /Next 215 0 R >> endobj 207 0 obj << /Title 208 0 R /A 205 0 R /Parent 203 0 R /Next 211 0 R >> endobj 203 0 obj << /Title 204 0 R /A 201 0 R /Parent 131 0 R /Prev 199 0 R /Next 219 0 R /First 207 0 R /Last 215 0 R /Count -3 >> endobj 199 0 obj << /Title 200 0 R /A 197 0 R /Parent 131 0 R /Prev 195 0 R /Next 203 0 R >> endobj 195 0 obj << /Title 196 0 R /A 193 0 R /Parent 131 0 R /Prev 159 0 R /Next 199 0 R >> endobj 191 0 obj << /Title 192 0 R /A 189 0 R /Parent 159 0 R /Prev 187 0 R >> endobj 187 0 obj << /Title 188 0 R /A 185 0 R /Parent 159 0 R /Prev 183 0 R /Next 191 0 R >> endobj 183 0 obj << /Title 184 0 R /A 181 0 R /Parent 159 0 R /Prev 179 0 R /Next 187 0 R >> endobj 179 0 obj << /Title 180 0 R /A 177 0 R /Parent 159 0 R /Prev 175 0 R /Next 183 0 R >> endobj 175 0 obj << /Title 176 0 R /A 173 0 R /Parent 159 0 R /Prev 163 0 R /Next 179 0 R >> endobj 171 0 obj << /Title 172 0 R /A 169 0 R /Parent 163 0 R /Prev 167 0 R >> endobj 167 0 obj << /Title 168 0 R /A 165 0 R /Parent 163 0 R /Next 171 0 R >> endobj 163 0 obj << /Title 164 0 R /A 161 0 R /Parent 159 0 R /Next 175 0 R /First 167 0 R /Last 171 0 R /Count -2 >> endobj 159 0 obj << /Title 160 0 R /A 157 0 R /Parent 131 0 R /Prev 151 0 R /Next 195 0 R /First 163 0 R /Last 191 0 R /Count -6 >> endobj 155 0 obj << /Title 156 0 R /A 153 0 R /Parent 151 0 R >> endobj 151 0 obj << /Title 152 0 R /A 149 0 R /Parent 131 0 R /Prev 147 0 R /Next 159 0 R /First 155 0 R /Last 155 0 R /Count -1 >> endobj 147 0 obj << /Title 148 0 R /A 145 0 R /Parent 131 0 R /Prev 139 0 R /Next 151 0 R >> endobj 143 0 obj << /Title 144 0 R /A 141 0 R /Parent 139 0 R >> endobj 139 0 obj << /Title 140 0 R /A 137 0 R /Parent 131 0 R /Prev 135 0 R /Next 147 0 R /First 143 0 R /Last 143 0 R /Count -1 >> endobj 135 0 obj << /Title 136 0 R /A 133 0 R /Parent 131 0 R /Next 139 0 R >> endobj 131 0 obj << /Title 132 0 R /A 129 0 R /Parent 3139 0 R /Prev 91 0 R /Next 375 0 R /First 135 0 R /Last 363 0 R /Count -13 >> endobj 127 0 obj << /Title 128 0 R /A 125 0 R /Parent 111 0 R /Prev 115 0 R >> endobj 123 0 obj << /Title 124 0 R /A 121 0 R /Parent 115 0 R /Prev 119 0 R >> endobj 119 0 obj << /Title 120 0 R /A 117 0 R /Parent 115 0 R /Next 123 0 R >> endobj 115 0 obj << /Title 116 0 R /A 113 0 R /Parent 111 0 R /Next 127 0 R /First 119 0 R /Last 123 0 R /Count -2 >> endobj 111 0 obj << /Title 112 0 R /A 109 0 R /Parent 91 0 R /Prev 107 0 R /First 115 0 R /Last 127 0 R /Count -2 >> endobj 107 0 obj << /Title 108 0 R /A 105 0 R /Parent 91 0 R /Prev 95 0 R /Next 111 0 R >> endobj 103 0 obj << /Title 104 0 R /A 101 0 R /Parent 95 0 R /Prev 99 0 R >> endobj 99 0 obj << /Title 100 0 R /A 97 0 R /Parent 95 0 R /Next 103 0 R >> endobj 95 0 obj << /Title 96 0 R /A 93 0 R /Parent 91 0 R /Next 107 0 R /First 99 0 R /Last 103 0 R /Count -2 >> endobj 91 0 obj << /Title 92 0 R /A 89 0 R /Parent 3139 0 R /Prev 67 0 R /Next 131 0 R /First 95 0 R /Last 111 0 R /Count -3 >> endobj 87 0 obj << /Title 88 0 R /A 85 0 R /Parent 67 0 R /Prev 83 0 R >> endobj 83 0 obj << /Title 84 0 R /A 81 0 R /Parent 67 0 R /Prev 79 0 R /Next 87 0 R >> endobj 79 0 obj << /Title 80 0 R /A 77 0 R /Parent 67 0 R /Prev 75 0 R /Next 83 0 R >> endobj 75 0 obj << /Title 76 0 R /A 73 0 R /Parent 67 0 R /Prev 71 0 R /Next 79 0 R >> endobj 71 0 obj << /Title 72 0 R /A 69 0 R /Parent 67 0 R /Next 75 0 R >> endobj 67 0 obj << /Title 68 0 R /A 65 0 R /Parent 3139 0 R /Prev 7 0 R /Next 91 0 R /First 71 0 R /Last 87 0 R /Count -5 >> endobj 63 0 obj << /Title 64 0 R /A 61 0 R /Parent 23 0 R /Prev 55 0 R >> endobj 59 0 obj << /Title 60 0 R /A 57 0 R /Parent 55 0 R >> endobj 55 0 obj << /Title 56 0 R /A 53 0 R /Parent 23 0 R /Prev 39 0 R /Next 63 0 R /First 59 0 R /Last 59 0 R /Count -1 >> endobj 51 0 obj << /Title 52 0 R /A 49 0 R /Parent 39 0 R /Prev 47 0 R >> endobj 47 0 obj << /Title 48 0 R /A 45 0 R /Parent 39 0 R /Prev 43 0 R /Next 51 0 R >> endobj 43 0 obj << /Title 44 0 R /A 41 0 R /Parent 39 0 R /Next 47 0 R >> endobj 39 0 obj << /Title 40 0 R /A 37 0 R /Parent 23 0 R /Prev 35 0 R /Next 55 0 R /First 43 0 R /Last 51 0 R /Count -3 >> endobj 35 0 obj << /Title 36 0 R /A 33 0 R /Parent 23 0 R /Prev 31 0 R /Next 39 0 R >> endobj 31 0 obj << /Title 32 0 R /A 29 0 R /Parent 23 0 R /Prev 27 0 R /Next 35 0 R >> endobj 27 0 obj << /Title 28 0 R /A 25 0 R /Parent 23 0 R /Next 31 0 R >> endobj 23 0 obj << /Title 24 0 R /A 21 0 R /Parent 7 0 R /Prev 19 0 R /First 27 0 R /Last 63 0 R /Count -6 >> endobj 19 0 obj << /Title 20 0 R /A 17 0 R /Parent 7 0 R /Prev 15 0 R /Next 23 0 R >> endobj 15 0 obj << /Title 16 0 R /A 13 0 R /Parent 7 0 R /Prev 11 0 R /Next 19 0 R >> endobj 11 0 obj << /Title 12 0 R /A 9 0 R /Parent 7 0 R /Next 15 0 R >> endobj 7 0 obj << /Title 8 0 R /A 5 0 R /Parent 3139 0 R /Next 67 0 R /First 11 0 R /Last 23 0 R /Count -4 >> endobj 3140 0 obj << /Names [(Access_Control_Lists) 2309 0 R (Bv9ARM.ch01) 1350 0 R (Bv9ARM.ch02) 1394 0 R (Bv9ARM.ch03) 1412 0 R (Bv9ARM.ch04) 1460 0 R (Bv9ARM.ch05) 1672 0 R (Bv9ARM.ch06) 1683 0 R (Bv9ARM.ch07) 2308 0 R (Bv9ARM.ch08) 2333 0 R (Bv9ARM.ch09) 2348 0 R (Bv9ARM.ch10) 2370 0 R (Bv9ARM.ch11) 2380 0 R (Bv9ARM.ch12) 2598 0 R (Bv9ARM.ch13) 2639 0 R (Configuration_File_Grammar) 1707 0 R (DNSSEC) 1530 0 R (Doc-Start) 1031 0 R (Item.1) 2004 0 R (Item.2) 2005 0 R (Item.3) 2006 0 R (Item.4) 2007 0 R (Item.5) 2008 0 R (Setting_TTLs) 2230 0 R (acache) 1401 0 R (access_control) 1880 0 R (acl) 1715 0 R (address_match_lists) 1688 0 R (admin_tools) 1434 0 R (appendix.A) 782 0 R (appendix.B) 822 0 R (appendix.C) 830 0 R (appendix.D) 854 0 R (appendix.E) 914 0 R (bibliography) 2381 0 R (bind9.library) 2599 0 R (boolean_options) 1475 0 R (builtin) 1968 0 R (chapter*.1) 1065 0 R (chapter.1) 6 0 R (chapter.2) 66 0 R (chapter.3) 90 0 R (chapter.4) 130 0 R (chapter.5) 374 0 R (chapter.6) 386 0 R (chapter.7) 738 0 R (chapter.8) 762 0 R (cite.RFC1033) 2508 0 R (cite.RFC1034) 2393 0 R (cite.RFC1035) 2395 0 R (cite.RFC1101) 2490 0 R (cite.RFC1123) 2492 0 R (cite.RFC1183) 2452 0 R (cite.RFC1464) 2530 0 R (cite.RFC1535) 2438 0 R (cite.RFC1536) 2440 0 R (cite.RFC1537) 2510 0 R (cite.RFC1591) 2494 0 R (cite.RFC1706) 2454 0 R (cite.RFC1712) 2550 0 R (cite.RFC1713) 2532 0 R (cite.RFC1794) 2534 0 R (cite.RFC1876) 2456 0 R (cite.RFC1912) 2512 0 R (cite.RFC1982) 2442 0 R (cite.RFC1995) 2400 0 R (cite.RFC1996) 2402 0 R (cite.RFC2010) 2514 0 R (cite.RFC2052) 2458 0 R (cite.RFC2065) 2563 0 R (cite.RFC2136) 2404 0 R (cite.RFC2137) 2565 0 R (cite.RFC2163) 2460 0 R (cite.RFC2168) 2462 0 R (cite.RFC2181) 2406 0 R (cite.RFC2219) 2516 0 R (cite.RFC2230) 2464 0 R (cite.RFC2240) 2536 0 R (cite.RFC2308) 2408 0 R (cite.RFC2317) 2496 0 R (cite.RFC2345) 2538 0 R (cite.RFC2352) 2540 0 R (cite.RFC2535) 2567 0 R (cite.RFC2536) 2466 0 R (cite.RFC2537) 2468 0 R (cite.RFC2538) 2470 0 R (cite.RFC2539) 2472 0 R (cite.RFC2540) 2474 0 R (cite.RFC2671) 2410 0 R (cite.RFC2672) 2412 0 R (cite.RFC2673) 2552 0 R (cite.RFC2782) 2476 0 R (cite.RFC2825) 2520 0 R (cite.RFC2826) 2498 0 R (cite.RFC2845) 2414 0 R (cite.RFC2874) 2554 0 R (cite.RFC2915) 2478 0 R (cite.RFC2929) 2500 0 R (cite.RFC2930) 2416 0 R (cite.RFC2931) 2418 0 R (cite.RFC3007) 2420 0 R (cite.RFC3008) 2569 0 R (cite.RFC3071) 2542 0 R (cite.RFC3090) 2571 0 R (cite.RFC3110) 2480 0 R (cite.RFC3123) 2482 0 R (cite.RFC3225) 2426 0 R (cite.RFC3258) 2544 0 R (cite.RFC3445) 2573 0 R (cite.RFC3490) 2522 0 R (cite.RFC3491) 2524 0 R (cite.RFC3492) 2526 0 R (cite.RFC3596) 2484 0 R (cite.RFC3597) 2486 0 R (cite.RFC3645) 2422 0 R (cite.RFC3655) 2575 0 R (cite.RFC3658) 2577 0 R (cite.RFC3755) 2579 0 R (cite.RFC3757) 2581 0 R (cite.RFC3833) 2428 0 R (cite.RFC3845) 2583 0 R (cite.RFC3901) 2546 0 R (cite.RFC4033) 2430 0 R (cite.RFC4034) 2432 0 R (cite.RFC4035) 2434 0 R (cite.RFC4074) 2448 0 R (cite.RFC974) 2397 0 R (cite.id2517543) 2588 0 R (clients-per-query) 2278 0 R (configuration_file_elements) 1684 0 R (controls_statement_definition_and_usage) 1442 0 R (diagnostic_tools) 1382 0 R (dlz-info) 1647 0 R (dnssec.dynamic.zones) 1549 0 R (dynamic_update) 1470 0 R (dynamic_update_policies) 1477 0 R (dynamic_update_security) 1889 0 R (empty) 1975 0 R (end_of_life) 2361 0 R (historical_dns_information) 2371 0 R (id2466586) 1351 0 R (id2466611) 1352 0 R (id2466682) 1353 0 R (id2466692) 1354 0 R (id2467437) 1362 0 R (id2467714) 1759 0 R (id2467888) 1364 0 R (id2467909) 1365 0 R (id2467943) 1366 0 R (id2468027) 1369 0 R (id2468104) 1376 0 R (id2470380) 1379 0 R (id2470410) 1380 0 R (id2470432) 1381 0 R (id2470461) 1387 0 R (id2470497) 1388 0 R (id2470592) 1389 0 R (id2470626) 1395 0 R (id2470721) 1396 0 R (id2470733) 1397 0 R (id2470759) 1400 0 R (id2470770) 1406 0 R (id2470802) 1414 0 R (id2470818) 1415 0 R (id2470840) 1420 0 R (id2470857) 1421 0 R (id2471262) 1429 0 R (id2471268) 1430 0 R (id2472337) 1447 0 R (id2472348) 1448 0 R (id2472928) 1489 0 R (id2472946) 1495 0 R (id2473379) 1510 0 R (id2473396) 1511 0 R (id2473434) 1512 0 R (id2473452) 1513 0 R (id2473463) 1514 0 R (id2473499) 1520 0 R (id2473557) 1521 0 R (id2473674) 1523 0 R (id2473688) 1524 0 R (id2473737) 1529 0 R (id2473874) 1531 0 R (id2474021) 1536 0 R (id2474170) 1537 0 R (id2474458) 1550 0 R (id2474700) 1555 0 R (id2474737) 1556 0 R (id2474916) 1569 0 R (id2475090) 1570 0 R (id2475102) 1571 0 R (id2475136) 1576 0 R (id2475230) 1577 0 R (id2475240) 1578 0 R (id2475250) 1579 0 R (id2475262) 1580 0 R (id2475300) 1581 0 R (id2475309) 1586 0 R (id2475347) 1588 0 R (id2475369) 1590 0 R (id2475476) 1597 0 R (id2475622) 1598 0 R (id2475770) 1603 0 R (id2475836) 1606 0 R (id2475874) 1611 0 R (id2476001) 1612 0 R (id2476138) 1618 0 R (id2476187) 1619 0 R (id2476410) 1625 0 R (id2476442) 1626 0 R (id2476478) 1627 0 R (id2476528) 1632 0 R (id2476564) 1633 0 R (id2476918) 1639 0 R (id2476966) 1640 0 R (id2477268) 1652 0 R (id2477341) 1653 0 R (id2477385) 1659 0 R (id2477515) 1661 0 R (id2477537) 1662 0 R (id2477570) 1673 0 R (id2477717) 1685 0 R (id2478841) 1698 0 R (id2478869) 1699 0 R (id2479006) 1700 0 R (id2479021) 1705 0 R (id2479120) 1706 0 R (id2479262) 1708 0 R (id2479803) 1714 0 R (id2479840) 1716 0 R (id2480046) 1722 0 R (id2480474) 1729 0 R (id2480491) 1730 0 R (id2480515) 1731 0 R (id2480538) 1737 0 R (id2480629) 1741 0 R (id2480755) 1742 0 R (id2480807) 1748 0 R (id2482526) 1769 0 R (id2482657) 1770 0 R (id2483046) 1776 0 R (id2483130) 1777 0 R (id2483194) 1785 0 R (id2483243) 1786 0 R (id2483265) 1787 0 R (id2487531) 1837 0 R (id2489838) 1872 0 R (id2489965) 1879 0 R (id2490708) 1894 0 R (id2491910) 1912 0 R (id2492038) 1919 0 R (id2492824) 1931 0 R (id2493258) 1949 0 R (id2495500) 1993 0 R (id2495763) 1999 0 R (id2496472) 2017 0 R (id2497896) 2039 0 R (id2498313) 2066 0 R (id2498428) 2068 0 R (id2498795) 2073 0 R (id2500808) 2095 0 R (id2500816) 2096 0 R (id2500821) 2097 0 R (id2501355) 2109 0 R (id2501525) 2110 0 R (id2503717) 2179 0 R (id2504378) 2190 0 R (id2504508) 2195 0 R (id2504526) 2196 0 R (id2504547) 2199 0 R (id2504784) 2205 0 R (id2506777) 2215 0 R (id2506905) 2217 0 R (id2506926) 2223 0 R (id2507289) 2225 0 R (id2507426) 2227 0 R (id2507512) 2228 0 R (id2507916) 2235 0 R (id2508041) 2237 0 R (id2508056) 2238 0 R (id2508168) 2240 0 R (id2508259) 2241 0 R (id2508275) 2242 0 R (id2508336) 2247 0 R (id2508405) 2248 0 R (id2508441) 2249 0 R (id2508585) 2254 0 R (id2509137) 2261 0 R (id2509640) 2269 0 R (id2509645) 2270 0 R (id2511209) 2283 0 R (id2511216) 2284 0 R (id2511660) 2286 0 R (id2511666) 2287 0 R (id2512614) 2293 0 R (id2512714) 2294 0 R (id2513124) 2299 0 R (id2513283) 2317 0 R (id2513364) 2318 0 R (id2513492) 2319 0 R (id2513572) 2334 0 R (id2513577) 2335 0 R (id2513725) 2336 0 R (id2513742) 2337 0 R (id2513805) 2349 0 R (id2514576) 2389 0 R (id2514578) 2391 0 R (id2514586) 2396 0 R (id2514610) 2392 0 R (id2514633) 2394 0 R (id2514669) 2405 0 R (id2514696) 2407 0 R (id2514722) 2399 0 R (id2514746) 2401 0 R (id2514770) 2403 0 R (id2514825) 2409 0 R (id2514852) 2411 0 R (id2514878) 2413 0 R (id2514940) 2415 0 R (id2514970) 2417 0 R (id2515000) 2419 0 R (id2515027) 2421 0 R (id2515101) 2424 0 R (id2515109) 2425 0 R (id2515136) 2427 0 R (id2515172) 2429 0 R (id2515237) 2431 0 R (id2515302) 2433 0 R (id2515367) 2436 0 R (id2515376) 2437 0 R (id2515401) 2439 0 R (id2515469) 2441 0 R (id2515505) 2447 0 R (id2515545) 2450 0 R (id2515550) 2451 0 R (id2515608) 2453 0 R (id2515645) 2461 0 R (id2515681) 2455 0 R (id2515735) 2457 0 R (id2515773) 2459 0 R (id2515799) 2463 0 R (id2515825) 2465 0 R (id2515851) 2467 0 R (id2515878) 2469 0 R (id2515917) 2471 0 R (id2515947) 2473 0 R (id2515977) 2475 0 R (id2516020) 2477 0 R (id2516121) 2479 0 R (id2516148) 2481 0 R (id2516171) 2483 0 R (id2516229) 2485 0 R (id2516253) 2488 0 R (id2516261) 2489 0 R (id2516286) 2491 0 R (id2516309) 2493 0 R (id2516332) 2495 0 R (id2516378) 2497 0 R (id2516402) 2499 0 R (id2516452) 2506 0 R (id2516459) 2507 0 R (id2516483) 2509 0 R (id2516509) 2511 0 R (id2516536) 2513 0 R (id2516572) 2515 0 R (id2516613) 2518 0 R (id2516618) 2519 0 R (id2516650) 2521 0 R (id2516696) 2523 0 R (id2516731) 2525 0 R (id2516758) 2528 0 R (id2516776) 2529 0 R (id2516798) 2531 0 R (id2516824) 2533 0 R (id2516850) 2535 0 R (id2516873) 2537 0 R (id2516919) 2539 0 R (id2516942) 2541 0 R (id2516969) 2543 0 R (id2516995) 2545 0 R (id2517032) 2548 0 R (id2517038) 2549 0 R (id2517096) 2551 0 R (id2517123) 2553 0 R (id2517159) 2561 0 R (id2517171) 2562 0 R (id2517210) 2564 0 R (id2517237) 2566 0 R (id2517267) 2568 0 R (id2517292) 2570 0 R (id2517319) 2572 0 R (id2517355) 2574 0 R (id2517392) 2576 0 R (id2517418) 2578 0 R (id2517445) 2580 0 R (id2517490) 2582 0 R (id2517531) 2585 0 R (id2517541) 2587 0 R (id2517543) 2589 0 R (id2517707) 2600 0 R (id2517717) 2601 0 R (id2517741) 2606 0 R (id2517909) 2607 0 R (id2517986) 2608 0 R (id2518012) 2610 0 R (id2518021) 2615 0 R (id2518112) 2616 0 R (id2518165) 2621 0 R (id2518297) 2622 0 R (id2518312) 2623 0 R (id2518512) 2629 0 R (id2518576) 2634 0 R (incremental_zone_transfers) 1486 0 R (internet_drafts) 2584 0 R (ipv6addresses) 1663 0 R (journal) 1482 0 R (lwresd) 1674 0 R (man.arpaname) 3072 0 R (man.ddns-confgen) 3061 0 R (man.delv) 2692 0 R (man.dig) 2640 0 R (man.dnssec-checkds) 2722 0 R (man.dnssec-coverage) 2729 0 R (man.dnssec-dsfromkey) 2744 0 R (man.dnssec-importkey) 2763 0 R (man.dnssec-keyfromlabel) 1641 0 R (man.dnssec-keygen) 1563 0 R (man.dnssec-revoke) 2826 0 R (man.dnssec-settime) 1564 0 R (man.dnssec-signzone) 2854 0 R (man.dnssec-verify) 2883 0 R (man.genrandom) 3082 0 R (man.host) 2681 0 R (man.isc-hmac-fixup) 3089 0 R (man.named) 2931 0 R (man.named-checkconf) 2898 0 R (man.named-checkzone) 2910 0 R (man.named-journalprint) 2953 0 R (man.named-rrchecker) 2963 0 R (man.nsec3hash) 3100 0 R (man.nsupdate) 2968 0 R (man.rndc) 1441 0 R (man.rndc-confgen) 3044 0 R (man.rndc.conf) 3028 0 R (managed-keys) 1591 0 R (notify) 1461 0 R (options) 1804 0 R (page.1) 1030 0 R (page.10) 1438 0 R (page.100) 2037 0 R (page.101) 2058 0 R (page.102) 2072 0 R (page.103) 2078 0 R (page.104) 2082 0 R (page.105) 2086 0 R (page.106) 2090 0 R (page.107) 2094 0 R (page.108) 2102 0 R (page.109) 2107 0 R (page.11) 1446 0 R (page.110) 2116 0 R (page.111) 2136 0 R (page.112) 2150 0 R (page.113) 2164 0 R (page.114) 2178 0 R (page.115) 2185 0 R (page.116) 2189 0 R (page.117) 2194 0 R (page.118) 2204 0 R (page.119) 2210 0 R (page.12) 1453 0 R (page.120) 2214 0 R (page.121) 2222 0 R (page.122) 2234 0 R (page.123) 2246 0 R (page.124) 2253 0 R (page.125) 2259 0 R (page.126) 2266 0 R (page.127) 2276 0 R (page.128) 2282 0 R (page.129) 2292 0 R (page.13) 1459 0 R (page.130) 2303 0 R (page.131) 2307 0 R (page.132) 2313 0 R (page.133) 2324 0 R (page.134) 2328 0 R (page.135) 2332 0 R (page.136) 2343 0 R (page.137) 2347 0 R (page.138) 2357 0 R (page.139) 2369 0 R (page.14) 1481 0 R (page.140) 2375 0 R (page.141) 2379 0 R (page.142) 2387 0 R (page.143) 2446 0 R (page.144) 2504 0 R (page.145) 2559 0 R (page.146) 2593 0 R (page.147) 2597 0 R (page.148) 2605 0 R (page.149) 2614 0 R (page.15) 1494 0 R (page.150) 2620 0 R (page.151) 2628 0 R (page.152) 2633 0 R (page.153) 2638 0 R (page.154) 2647 0 R (page.155) 2653 0 R (page.156) 2658 0 R (page.157) 2663 0 R (page.158) 2667 0 R (page.159) 2671 0 R (page.16) 1499 0 R (page.160) 2679 0 R (page.161) 2688 0 R (page.162) 2698 0 R (page.163) 2706 0 R (page.164) 2710 0 R (page.165) 2715 0 R (page.166) 2721 0 R (page.167) 2734 0 R (page.168) 2741 0 R (page.169) 2752 0 R (page.17) 1504 0 R (page.170) 2758 0 R (page.171) 2770 0 R (page.172) 2779 0 R (page.173) 2787 0 R (page.174) 2791 0 R (page.175) 2798 0 R (page.176) 2808 0 R (page.177) 2812 0 R (page.178) 2816 0 R (page.179) 2822 0 R (page.18) 1509 0 R (page.180) 2834 0 R (page.181) 2844 0 R (page.182) 2850 0 R (page.183) 2860 0 R (page.184) 2866 0 R (page.185) 2870 0 R (page.186) 2874 0 R (page.187) 2879 0 R (page.188) 2888 0 R (page.189) 2896 0 R (page.19) 1519 0 R (page.190) 2906 0 R (page.191) 2918 0 R (page.192) 2922 0 R (page.193) 2930 0 R (page.194) 2939 0 R (page.195) 2943 0 R (page.196) 2949 0 R (page.197) 2961 0 R (page.198) 2974 0 R (page.199) 2981 0 R (page.2) 1057 0 R (page.20) 1528 0 R (page.200) 2986 0 R (page.201) 2990 0 R (page.202) 2996 0 R (page.203) 3006 0 R (page.204) 3011 0 R (page.205) 3016 0 R (page.206) 3020 0 R (page.207) 3025 0 R (page.208) 3035 0 R (page.209) 3040 0 R (page.21) 1535 0 R (page.210) 3052 0 R (page.211) 3060 0 R (page.212) 3069 0 R (page.213) 3081 0 R (page.214) 3095 0 R (page.215) 3108 0 R (page.22) 1541 0 R (page.23) 1545 0 R (page.24) 1554 0 R (page.25) 1568 0 R (page.26) 1575 0 R (page.27) 1585 0 R (page.28) 1595 0 R (page.29) 1602 0 R (page.3) 1375 0 R (page.30) 1610 0 R (page.31) 1617 0 R (page.32) 1624 0 R (page.33) 1631 0 R (page.34) 1637 0 R (page.35) 1646 0 R (page.36) 1651 0 R (page.37) 1658 0 R (page.38) 1667 0 R (page.39) 1671 0 R (page.4) 1386 0 R (page.40) 1678 0 R (page.41) 1682 0 R (page.42) 1692 0 R (page.43) 1697 0 R (page.44) 1704 0 R (page.45) 1713 0 R (page.46) 1721 0 R (page.47) 1726 0 R (page.48) 1736 0 R (page.49) 1747 0 R (page.5) 1393 0 R (page.50) 1752 0 R (page.51) 1758 0 R (page.52) 1764 0 R (page.53) 1768 0 R (page.54) 1775 0 R (page.55) 1784 0 R (page.56) 1791 0 R (page.57) 1795 0 R (page.58) 1799 0 R (page.59) 1803 0 R (page.6) 1405 0 R (page.60) 1808 0 R (page.61) 1814 0 R (page.62) 1818 0 R (page.63) 1825 0 R (page.64) 1830 0 R (page.65) 1835 0 R (page.66) 1842 0 R (page.67) 1848 0 R (page.68) 1857 0 R (page.69) 1861 0 R (page.7) 1411 0 R (page.70) 1865 0 R (page.71) 1869 0 R (page.72) 1878 0 R (page.73) 1886 0 R (page.74) 1893 0 R (page.75) 1898 0 R (page.76) 1903 0 R (page.77) 1907 0 R (page.78) 1911 0 R (page.79) 1918 0 R (page.8) 1419 0 R (page.80) 1926 0 R (page.81) 1930 0 R (page.82) 1935 0 R (page.83) 1942 0 R (page.84) 1947 0 R (page.85) 1956 0 R (page.86) 1961 0 R (page.87) 1967 0 R (page.88) 1974 0 R (page.89) 1979 0 R (page.9) 1428 0 R (page.90) 1983 0 R (page.91) 1988 0 R (page.92) 1992 0 R (page.93) 1998 0 R (page.94) 2003 0 R (page.95) 2012 0 R (page.96) 2016 0 R (page.97) 2022 0 R (page.98) 2026 0 R (page.99) 2031 0 R (page.i) 1064 0 R (page.ii) 1119 0 R (page.iii) 1183 0 R (page.iv) 1246 0 R (page.v) 1307 0 R (pkcs11) 1596 0 R (proposed_standards) 1490 0 R (query_address) 1899 0 R (relnotes_bugs) 2360 0 R (relnotes_changes) 2359 0 R (relnotes_download) 2351 0 R (relnotes_features) 2358 0 R (relnotes_intro) 2350 0 R (relnotes_security) 2353 0 R (relnotes_thanks) 2363 0 R (rfc5011.support) 1587 0 R (rfcs) 1371 0 R (rndc) 1732 0 R (root_delegation_only) 2112 0 R (rrset_ordering) 1424 0 R (sample_configuration) 1413 0 R (section*.10) 2517 0 R (section*.100) 2855 0 R (section*.101) 2856 0 R (section*.102) 2861 0 R (section*.103) 2862 0 R (section*.104) 2880 0 R (section*.105) 2881 0 R (section*.106) 2882 0 R (section*.107) 2884 0 R (section*.108) 2889 0 R (section*.109) 2890 0 R (section*.11) 2527 0 R (section*.110) 2891 0 R (section*.111) 2892 0 R (section*.112) 2897 0 R (section*.113) 2899 0 R (section*.114) 2900 0 R (section*.115) 2901 0 R (section*.116) 2902 0 R (section*.117) 2907 0 R (section*.118) 2908 0 R (section*.119) 2909 0 R (section*.12) 2547 0 R (section*.120) 2911 0 R (section*.121) 2912 0 R (section*.122) 2913 0 R (section*.123) 2914 0 R (section*.124) 2923 0 R (section*.125) 2924 0 R (section*.126) 2925 0 R (section*.127) 2932 0 R (section*.128) 2933 0 R (section*.129) 2934 0 R (section*.13) 2560 0 R (section*.130) 2935 0 R (section*.131) 2944 0 R (section*.132) 2945 0 R (section*.133) 2950 0 R (section*.134) 2951 0 R (section*.135) 2952 0 R (section*.136) 2954 0 R (section*.137) 2955 0 R (section*.138) 2956 0 R (section*.139) 2957 0 R (section*.14) 2586 0 R (section*.140) 2962 0 R (section*.141) 2964 0 R (section*.142) 2965 0 R (section*.143) 2966 0 R (section*.144) 2967 0 R (section*.145) 2969 0 R (section*.146) 2970 0 R (section*.147) 2975 0 R (section*.148) 2976 0 R (section*.149) 2982 0 R (section*.15) 2641 0 R (section*.150) 2991 0 R (section*.151) 2992 0 R (section*.152) 2997 0 R (section*.153) 2998 0 R (section*.154) 2999 0 R (section*.155) 3000 0 R (section*.156) 3001 0 R (section*.157) 3002 0 R (section*.158) 3007 0 R (section*.159) 3021 0 R (section*.16) 2642 0 R (section*.160) 3026 0 R (section*.161) 3027 0 R (section*.162) 3029 0 R (section*.163) 3030 0 R (section*.164) 3031 0 R (section*.165) 3036 0 R (section*.166) 3041 0 R (section*.167) 3042 0 R (section*.168) 3043 0 R (section*.169) 3045 0 R (section*.17) 2643 0 R (section*.170) 3046 0 R (section*.171) 3047 0 R (section*.172) 3048 0 R (section*.173) 3053 0 R (section*.174) 3054 0 R (section*.175) 3055 0 R (section*.176) 3062 0 R (section*.177) 3063 0 R (section*.178) 3064 0 R (section*.179) 3065 0 R (section*.18) 2648 0 R (section*.180) 3070 0 R (section*.181) 3071 0 R (section*.182) 3073 0 R (section*.183) 3074 0 R (section*.184) 3075 0 R (section*.185) 3076 0 R (section*.186) 3077 0 R (section*.187) 3083 0 R (section*.188) 3084 0 R (section*.189) 3085 0 R (section*.19) 2649 0 R (section*.190) 3086 0 R (section*.191) 3087 0 R (section*.192) 3088 0 R (section*.193) 3090 0 R (section*.194) 3091 0 R (section*.195) 3096 0 R (section*.196) 3097 0 R (section*.197) 3098 0 R (section*.198) 3099 0 R (section*.199) 3101 0 R (section*.2) 2388 0 R (section*.20) 2654 0 R (section*.200) 3102 0 R (section*.201) 3103 0 R (section*.202) 3104 0 R (section*.203) 3109 0 R (section*.204) 3110 0 R (section*.21) 2672 0 R (section*.22) 2673 0 R (section*.23) 2674 0 R (section*.24) 2675 0 R (section*.25) 2680 0 R (section*.26) 2682 0 R (section*.27) 2683 0 R (section*.28) 2684 0 R (section*.29) 2689 0 R (section*.3) 2390 0 R (section*.30) 2690 0 R (section*.31) 2691 0 R (section*.32) 2693 0 R (section*.33) 2694 0 R (section*.34) 2699 0 R (section*.35) 2700 0 R (section*.36) 2701 0 R (section*.37) 2711 0 R (section*.38) 2716 0 R (section*.39) 2717 0 R (section*.4) 2398 0 R (section*.40) 2723 0 R (section*.41) 2724 0 R (section*.42) 2725 0 R (section*.43) 2726 0 R (section*.44) 2727 0 R (section*.45) 2728 0 R (section*.46) 2730 0 R (section*.47) 2735 0 R (section*.48) 2736 0 R (section*.49) 2737 0 R (section*.5) 2423 0 R (section*.50) 2742 0 R (section*.51) 2743 0 R (section*.52) 2745 0 R (section*.53) 2746 0 R (section*.54) 2747 0 R (section*.55) 2753 0 R (section*.56) 2754 0 R (section*.57) 2759 0 R (section*.58) 2760 0 R (section*.59) 2761 0 R (section*.6) 2435 0 R (section*.60) 2762 0 R (section*.61) 2764 0 R (section*.62) 2765 0 R (section*.63) 2766 0 R (section*.64) 2771 0 R (section*.65) 2772 0 R (section*.66) 2773 0 R (section*.67) 2774 0 R (section*.68) 2775 0 R (section*.69) 2780 0 R (section*.7) 2449 0 R (section*.70) 2781 0 R (section*.71) 2782 0 R (section*.72) 2783 0 R (section*.73) 2792 0 R (section*.74) 2793 0 R (section*.75) 2799 0 R (section*.76) 2800 0 R (section*.77) 2801 0 R (section*.78) 2802 0 R (section*.79) 2803 0 R (section*.8) 2487 0 R (section*.80) 2804 0 R (section*.81) 2817 0 R (section*.82) 2818 0 R (section*.83) 2823 0 R (section*.84) 2824 0 R (section*.85) 2825 0 R (section*.86) 2827 0 R (section*.87) 2828 0 R (section*.88) 2829 0 R (section*.89) 2830 0 R (section*.9) 2505 0 R (section*.90) 2835 0 R (section*.91) 2836 0 R (section*.92) 2837 0 R (section*.93) 2838 0 R (section*.94) 2839 0 R (section*.95) 2845 0 R (section*.96) 2846 0 R (section*.97) 2851 0 R (section*.98) 2852 0 R (section*.99) 2853 0 R (section.1.1) 10 0 R (section.1.2) 14 0 R (section.1.3) 18 0 R (section.1.4) 22 0 R (section.2.1) 70 0 R (section.2.2) 74 0 R (section.2.3) 78 0 R (section.2.4) 82 0 R (section.2.5) 86 0 R (section.3.1) 94 0 R (section.3.2) 106 0 R (section.3.3) 110 0 R (section.4.1) 134 0 R (section.4.10) 274 0 R (section.4.11) 286 0 R (section.4.12) 350 0 R (section.4.13) 362 0 R (section.4.2) 138 0 R (section.4.3) 146 0 R (section.4.4) 150 0 R (section.4.5) 158 0 R (section.4.6) 194 0 R (section.4.7) 198 0 R (section.4.8) 202 0 R (section.4.9) 218 0 R (section.5.1) 378 0 R (section.5.2) 382 0 R (section.6.1) 390 0 R (section.6.2) 418 0 R (section.6.3) 650 0 R (section.6.4) 706 0 R (section.7.1) 742 0 R (section.7.2) 746 0 R (section.7.3) 758 0 R (section.8.1) 766 0 R (section.8.2) 774 0 R (section.8.3) 778 0 R (section.A.1) 786 0 R (section.B.1) 826 0 R (section.C.1) 834 0 R (section.C.2) 838 0 R (section.D.1) 858 0 R (section.E.1) 918 0 R (section.E.10) 954 0 R (section.E.11) 958 0 R (section.E.12) 962 0 R (section.E.13) 966 0 R (section.E.14) 970 0 R (section.E.15) 974 0 R (section.E.16) 978 0 R (section.E.17) 982 0 R (section.E.18) 986 0 R (section.E.19) 990 0 R (section.E.2) 922 0 R (section.E.20) 994 0 R (section.E.21) 998 0 R (section.E.22) 1002 0 R (section.E.23) 1006 0 R (section.E.24) 1010 0 R (section.E.25) 1014 0 R (section.E.26) 1018 0 R (section.E.27) 1022 0 R (section.E.3) 926 0 R (section.E.4) 930 0 R (section.E.5) 934 0 R (section.E.6) 938 0 R (section.E.7) 942 0 R (section.E.8) 946 0 R (section.E.9) 950 0 R (server_resource_limits) 1921 0 R (server_statement_definition_and_usage) 1853 0 R (server_statement_grammar) 2027 0 R (statistics) 2260 0 R (statistics_counters) 2268 0 R (statschannels) 2038 0 R (statsfile) 1821 0 R (subsection.1.4.1) 26 0 R (subsection.1.4.2) 30 0 R (subsection.1.4.3) 34 0 R (subsection.1.4.4) 38 0 R (subsection.1.4.5) 54 0 R (subsection.1.4.6) 62 0 R (subsection.3.1.1) 98 0 R (subsection.3.1.2) 102 0 R (subsection.3.3.1) 114 0 R (subsection.3.3.2) 126 0 R (subsection.4.10.1) 278 0 R (subsection.4.10.2) 282 0 R (subsection.4.11.1) 290 0 R (subsection.4.11.2) 294 0 R (subsection.4.11.3) 302 0 R (subsection.4.11.4) 334 0 R (subsection.4.11.5) 338 0 R (subsection.4.11.6) 342 0 R (subsection.4.11.7) 346 0 R (subsection.4.12.1) 354 0 R (subsection.4.12.2) 358 0 R (subsection.4.13.1) 366 0 R (subsection.4.13.2) 370 0 R (subsection.4.2.1) 142 0 R (subsection.4.4.1) 154 0 R (subsection.4.5.1) 162 0 R (subsection.4.5.2) 174 0 R (subsection.4.5.3) 178 0 R (subsection.4.5.4) 182 0 R (subsection.4.5.5) 186 0 R (subsection.4.5.6) 190 0 R (subsection.4.8.1) 206 0 R (subsection.4.8.2) 210 0 R (subsection.4.8.3) 214 0 R (subsection.4.9.1) 222 0 R (subsection.4.9.10) 258 0 R (subsection.4.9.11) 262 0 R (subsection.4.9.12) 266 0 R (subsection.4.9.13) 270 0 R (subsection.4.9.2) 226 0 R (subsection.4.9.3) 230 0 R (subsection.4.9.4) 234 0 R (subsection.4.9.5) 238 0 R (subsection.4.9.6) 242 0 R (subsection.4.9.7) 246 0 R (subsection.4.9.8) 250 0 R (subsection.4.9.9) 254 0 R (subsection.6.1.1) 394 0 R (subsection.6.1.2) 406 0 R (subsection.6.2.1) 422 0 R (subsection.6.2.10) 458 0 R (subsection.6.2.11) 474 0 R (subsection.6.2.12) 478 0 R (subsection.6.2.13) 482 0 R (subsection.6.2.14) 486 0 R (subsection.6.2.15) 490 0 R (subsection.6.2.16) 494 0 R (subsection.6.2.17) 582 0 R (subsection.6.2.18) 586 0 R (subsection.6.2.19) 590 0 R (subsection.6.2.2) 426 0 R (subsection.6.2.20) 594 0 R (subsection.6.2.21) 598 0 R (subsection.6.2.22) 602 0 R (subsection.6.2.23) 606 0 R (subsection.6.2.24) 610 0 R (subsection.6.2.25) 614 0 R (subsection.6.2.26) 618 0 R (subsection.6.2.27) 622 0 R (subsection.6.2.28) 626 0 R (subsection.6.2.3) 430 0 R (subsection.6.2.4) 434 0 R (subsection.6.2.5) 438 0 R (subsection.6.2.6) 442 0 R (subsection.6.2.7) 446 0 R (subsection.6.2.8) 450 0 R (subsection.6.2.9) 454 0 R (subsection.6.3.1) 654 0 R (subsection.6.3.2) 666 0 R (subsection.6.3.3) 670 0 R (subsection.6.3.4) 674 0 R (subsection.6.3.5) 678 0 R (subsection.6.3.6) 698 0 R (subsection.6.3.7) 702 0 R (subsection.6.4.1) 714 0 R (subsection.7.2.1) 750 0 R (subsection.7.2.2) 754 0 R (subsection.8.1.1) 770 0 R (subsection.A.1.1) 790 0 R (subsection.A.1.2) 794 0 R (subsection.A.1.3) 798 0 R (subsection.A.1.4) 802 0 R (subsection.A.1.5) 806 0 R (subsection.A.1.6) 810 0 R (subsection.A.1.7) 814 0 R (subsection.A.1.8) 818 0 R (subsection.C.2.1) 842 0 R (subsection.C.2.2) 846 0 R (subsection.C.2.3) 850 0 R (subsection.D.1.1) 862 0 R (subsection.D.1.2) 866 0 R (subsection.D.1.3) 870 0 R (subsection.D.1.4) 874 0 R (subsection.D.1.5) 878 0 R (subsection.D.1.6) 882 0 R (subsection.D.1.7) 910 0 R (subsubsection.1.4.4.1) 42 0 R (subsubsection.1.4.4.2) 46 0 R (subsubsection.1.4.4.3) 50 0 R (subsubsection.1.4.5.1) 58 0 R (subsubsection.3.3.1.1) 118 0 R (subsubsection.3.3.1.2) 122 0 R (subsubsection.4.11.2.1) 298 0 R (subsubsection.4.11.3.1) 306 0 R (subsubsection.4.11.3.2) 310 0 R (subsubsection.4.11.3.3) 314 0 R (subsubsection.4.11.3.4) 318 0 R (subsubsection.4.11.3.5) 322 0 R (subsubsection.4.11.3.6) 326 0 R (subsubsection.4.11.3.7) 330 0 R (subsubsection.4.5.1.1) 166 0 R (subsubsection.4.5.1.2) 170 0 R (subsubsection.6.1.1.1) 398 0 R (subsubsection.6.1.1.2) 402 0 R (subsubsection.6.1.2.1) 410 0 R (subsubsection.6.1.2.2) 414 0 R (subsubsection.6.2.10.1) 462 0 R (subsubsection.6.2.10.2) 466 0 R (subsubsection.6.2.10.3) 470 0 R (subsubsection.6.2.16.1) 498 0 R (subsubsection.6.2.16.10) 534 0 R (subsubsection.6.2.16.11) 538 0 R (subsubsection.6.2.16.12) 542 0 R (subsubsection.6.2.16.13) 546 0 R (subsubsection.6.2.16.14) 550 0 R (subsubsection.6.2.16.15) 554 0 R (subsubsection.6.2.16.16) 558 0 R (subsubsection.6.2.16.17) 562 0 R (subsubsection.6.2.16.18) 566 0 R (subsubsection.6.2.16.19) 570 0 R (subsubsection.6.2.16.2) 502 0 R (subsubsection.6.2.16.20) 574 0 R (subsubsection.6.2.16.21) 578 0 R (subsubsection.6.2.16.3) 506 0 R (subsubsection.6.2.16.4) 510 0 R (subsubsection.6.2.16.5) 514 0 R (subsubsection.6.2.16.6) 518 0 R (subsubsection.6.2.16.7) 522 0 R (subsubsection.6.2.16.8) 526 0 R (subsubsection.6.2.16.9) 530 0 R (subsubsection.6.2.28.1) 630 0 R (subsubsection.6.2.28.2) 634 0 R (subsubsection.6.2.28.3) 638 0 R (subsubsection.6.2.28.4) 642 0 R (subsubsection.6.2.28.5) 646 0 R (subsubsection.6.3.1.1) 658 0 R (subsubsection.6.3.1.2) 662 0 R (subsubsection.6.3.5.1) 682 0 R (subsubsection.6.3.5.2) 686 0 R (subsubsection.6.3.5.3) 690 0 R (subsubsection.6.3.5.4) 694 0 R (subsubsection.6.4.0.1) 710 0 R (subsubsection.6.4.1.1) 718 0 R (subsubsection.6.4.1.2) 722 0 R (subsubsection.6.4.1.3) 726 0 R (subsubsection.6.4.1.4) 730 0 R (subsubsection.6.4.1.5) 734 0 R (subsubsection.D.1.6.1) 886 0 R (subsubsection.D.1.6.2) 890 0 R (subsubsection.D.1.6.3) 894 0 R (subsubsection.D.1.6.4) 898 0 R (subsubsection.D.1.6.5) 902 0 R (subsubsection.D.1.6.6) 906 0 R (table.1.1) 1355 0 R (table.1.2) 1363 0 R (table.3.1) 1422 0 R (table.3.2) 1449 0 R (table.6.1) 1686 0 R (table.6.10) 2200 0 R (table.6.11) 2206 0 R (table.6.12) 2216 0 R (table.6.13) 2224 0 R (table.6.14) 2226 0 R (table.6.15) 2229 0 R (table.6.16) 2236 0 R (table.6.17) 2239 0 R (table.6.18) 2255 0 R (table.6.19) 2262 0 R (table.6.2) 1709 0 R (table.6.20) 2271 0 R (table.6.21) 2285 0 R (table.6.22) 2288 0 R (table.6.23) 2295 0 R (table.6.3) 1717 0 R (table.6.4) 1760 0 R (table.6.5) 1771 0 R (table.6.6) 1838 0 R (table.6.7) 1950 0 R (table.6.8) 2098 0 R (table.6.9) 2180 0 R (the_category_phrase) 1754 0 R (the_sortlist_statement) 1937 0 R (topology) 1936 0 R (trusted-keys) 2065 0 R (tsig) 1505 0 R (tuning) 1951 0 R (types_of_resource_records_and_when_to_use_them) 1370 0 R (view_statement_grammar) 1970 0 R (zone_statement_grammar) 1874 0 R (zone_transfers) 1476 0 R (zonefile_format) 1963 0 R] /Limits [(Access_Control_Lists) (zonefile_format)] >> endobj 3141 0 obj << /Kids [3140 0 R] >> endobj 3142 0 obj << /Dests 3141 0 R >> endobj 3143 0 obj << /Type /Catalog /Pages 3138 0 R /Outlines 3139 0 R /Names 3142 0 R /PageMode /UseOutlines /OpenAction 1025 0 R >> endobj 3144 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfeTeX-1.21a)/Keywords() /CreationDate (D:20160228232821Z) /PTEX.Fullbanner (This is pdfeTeX, Version 3.141592-1.21a-2.2 (Web2C 7.5.4) kpathsea version 3.5.4) >> endobj xref 0 3145 0000000001 65535 f 0000000002 00000 f 0000000003 00000 f 0000000004 00000 f 0000000000 00000 f 0000000009 00000 n 0000356564 00000 n 0001339982 00000 n 0000000054 00000 n 0000000086 00000 n 0000356691 00000 n 0001339910 00000 n 0000000133 00000 n 0000000173 00000 n 0000356819 00000 n 0001339824 00000 n 0000000221 00000 n 0000000273 00000 n 0000356947 00000 n 0001339738 00000 n 0000000321 00000 n 0000000377 00000 n 0000361245 00000 n 0001339628 00000 n 0000000425 00000 n 0000000478 00000 n 0000361372 00000 n 0001339554 00000 n 0000000531 00000 n 0000000572 00000 n 0000361500 00000 n 0001339467 00000 n 0000000625 00000 n 0000000674 00000 n 0000361627 00000 n 0001339380 00000 n 0000000727 00000 n 0000000757 00000 n 0000365941 00000 n 0001339256 00000 n 0000000810 00000 n 0000000861 00000 n 0000366069 00000 n 0001339182 00000 n 0000000919 00000 n 0000000964 00000 n 0000366197 00000 n 0001339095 00000 n 0000001022 00000 n 0000001062 00000 n 0000366325 00000 n 0001339021 00000 n 0000001120 00000 n 0000001162 00000 n 0000369324 00000 n 0001338897 00000 n 0000001215 00000 n 0000001260 00000 n 0000369452 00000 n 0001338836 00000 n 0000001318 00000 n 0000001355 00000 n 0000369580 00000 n 0001338762 00000 n 0000001408 00000 n 0000001463 00000 n 0000372590 00000 n 0001338637 00000 n 0000001509 00000 n 0000001556 00000 n 0000372718 00000 n 0001338563 00000 n 0000001604 00000 n 0000001648 00000 n 0000372846 00000 n 0001338476 00000 n 0000001696 00000 n 0000001735 00000 n 0000372974 00000 n 0001338389 00000 n 0000001783 00000 n 0000001825 00000 n 0000373101 00000 n 0001338302 00000 n 0000001873 00000 n 0000001936 00000 n 0000374189 00000 n 0001338228 00000 n 0000001984 00000 n 0000002034 00000 n 0000375915 00000 n 0001338100 00000 n 0000002080 00000 n 0000002126 00000 n 0000376042 00000 n 0001337987 00000 n 0000002174 00000 n 0000002218 00000 n 0000376170 00000 n 0001337911 00000 n 0000002271 00000 n 0000002323 00000 n 0000376298 00000 n 0001337834 00000 n 0000002377 00000 n 0000002436 00000 n 0000378763 00000 n 0001337743 00000 n 0000002485 00000 n 0000002523 00000 n 0000382122 00000 n 0001337626 00000 n 0000002572 00000 n 0000002618 00000 n 0000382250 00000 n 0001337508 00000 n 0000002672 00000 n 0000002739 00000 n 0000382378 00000 n 0001337429 00000 n 0000002798 00000 n 0000002842 00000 n 0000382507 00000 n 0001337350 00000 n 0000002901 00000 n 0000002949 00000 n 0000389598 00000 n 0001337271 00000 n 0000003003 00000 n 0000003036 00000 n 0000395257 00000 n 0001337138 00000 n 0000003083 00000 n 0000003126 00000 n 0000395386 00000 n 0001337059 00000 n 0000003175 00000 n 0000003205 00000 n 0000395515 00000 n 0001336927 00000 n 0000003254 00000 n 0000003292 00000 n 0000400050 00000 n 0001336862 00000 n 0000003346 00000 n 0000003388 00000 n 0000400179 00000 n 0001336769 00000 n 0000003437 00000 n 0000003496 00000 n 0000400308 00000 n 0001336637 00000 n 0000003545 00000 n 0000003578 00000 n 0000404048 00000 n 0001336572 00000 n 0000003632 00000 n 0000003681 00000 n 0000407234 00000 n 0001336440 00000 n 0000003730 00000 n 0000003758 00000 n 0000410191 00000 n 0001336322 00000 n 0000003812 00000 n 0000003881 00000 n 0000410320 00000 n 0001336243 00000 n 0000003940 00000 n 0000003988 00000 n 0000410449 00000 n 0001336164 00000 n 0000004047 00000 n 0000004092 00000 n 0000410578 00000 n 0001336071 00000 n 0000004146 00000 n 0000004214 00000 n 0000410707 00000 n 0001335978 00000 n 0000004268 00000 n 0000004338 00000 n 0000414186 00000 n 0001335885 00000 n 0000004392 00000 n 0000004455 00000 n 0000414315 00000 n 0001335792 00000 n 0000004509 00000 n 0000004564 00000 n 0000414444 00000 n 0001335713 00000 n 0000004618 00000 n 0000004650 00000 n 0000414573 00000 n 0001335620 00000 n 0000004699 00000 n 0000004727 00000 n 0000418442 00000 n 0001335527 00000 n 0000004776 00000 n 0000004808 00000 n 0000418571 00000 n 0001335395 00000 n 0000004857 00000 n 0000004887 00000 n 0000418699 00000 n 0001335316 00000 n 0000004941 00000 n 0000004982 00000 n 0000422619 00000 n 0001335223 00000 n 0000005036 00000 n 0000005078 00000 n 0000422747 00000 n 0001335144 00000 n 0000005132 00000 n 0000005177 00000 n 0000427918 00000 n 0001335011 00000 n 0000005226 00000 n 0000005294 00000 n 0000428047 00000 n 0001334932 00000 n 0000005348 00000 n 0000005408 00000 n 0000432043 00000 n 0001334839 00000 n 0000005462 00000 n 0000005513 00000 n 0000432172 00000 n 0001334746 00000 n 0000005567 00000 n 0000005621 00000 n 0000435269 00000 n 0001334653 00000 n 0000005675 00000 n 0000005721 00000 n 0000435398 00000 n 0001334560 00000 n 0000005775 00000 n 0000005817 00000 n 0000435527 00000 n 0001334467 00000 n 0000005871 00000 n 0000005922 00000 n 0000438448 00000 n 0001334374 00000 n 0000005976 00000 n 0000006025 00000 n 0000438577 00000 n 0001334281 00000 n 0000006079 00000 n 0000006136 00000 n 0000438706 00000 n 0001334188 00000 n 0000006190 00000 n 0000006245 00000 n 0000438834 00000 n 0001334095 00000 n 0000006300 00000 n 0000006356 00000 n 0000438962 00000 n 0001334002 00000 n 0000006411 00000 n 0000006472 00000 n 0000439090 00000 n 0001333909 00000 n 0000006527 00000 n 0000006573 00000 n 0000442928 00000 n 0001333830 00000 n 0000006628 00000 n 0000006671 00000 n 0000443057 00000 n 0001333698 00000 n 0000006721 00000 n 0000006777 00000 n 0000443186 00000 n 0001333619 00000 n 0000006832 00000 n 0000006878 00000 n 0000443314 00000 n 0001333540 00000 n 0000006933 00000 n 0000006980 00000 n 0000446695 00000 n 0001333408 00000 n 0000007030 00000 n 0000007086 00000 n 0000446824 00000 n 0001333329 00000 n 0000007141 00000 n 0000007181 00000 n 0000446953 00000 n 0001333197 00000 n 0000007236 00000 n 0000007280 00000 n 0000451211 00000 n 0001333132 00000 n 0000007340 00000 n 0000007387 00000 n 0000451340 00000 n 0001333000 00000 n 0000007442 00000 n 0000007493 00000 n 0000454007 00000 n 0001332921 00000 n 0000007553 00000 n 0000007598 00000 n 0000454136 00000 n 0001332828 00000 n 0000007658 00000 n 0000007731 00000 n 0000457029 00000 n 0001332735 00000 n 0000007791 00000 n 0000007864 00000 n 0000457157 00000 n 0001332642 00000 n 0000007924 00000 n 0000007981 00000 n 0000459451 00000 n 0001332549 00000 n 0000008041 00000 n 0000008118 00000 n 0000459580 00000 n 0001332456 00000 n 0000008178 00000 n 0000008255 00000 n 0000459709 00000 n 0001332377 00000 n 0000008315 00000 n 0000008374 00000 n 0000462691 00000 n 0001332284 00000 n 0000008429 00000 n 0000008472 00000 n 0000462820 00000 n 0001332191 00000 n 0000008527 00000 n 0000008567 00000 n 0000466127 00000 n 0001332098 00000 n 0000008622 00000 n 0000008690 00000 n 0000466256 00000 n 0001332019 00000 n 0000008745 00000 n 0000008816 00000 n 0000470560 00000 n 0001331887 00000 n 0000008866 00000 n 0000008925 00000 n 0000473242 00000 n 0001331808 00000 n 0000008980 00000 n 0000009022 00000 n 0000473371 00000 n 0001331729 00000 n 0000009077 00000 n 0000009121 00000 n 0000476894 00000 n 0001331611 00000 n 0000009171 00000 n 0000009218 00000 n 0000477023 00000 n 0001331532 00000 n 0000009273 00000 n 0000009334 00000 n 0000477152 00000 n 0001331453 00000 n 0000009389 00000 n 0000009459 00000 n 0000480052 00000 n 0001331320 00000 n 0000009506 00000 n 0000009559 00000 n 0000480181 00000 n 0001331241 00000 n 0000009608 00000 n 0000009664 00000 n 0000480310 00000 n 0001331162 00000 n 0000009713 00000 n 0000009762 00000 n 0000484608 00000 n 0001331029 00000 n 0000009809 00000 n 0000009861 00000 n 0000484737 00000 n 0001330911 00000 n 0000009910 00000 n 0000009961 00000 n 0000493278 00000 n 0001330793 00000 n 0000010015 00000 n 0000010060 00000 n 0000493407 00000 n 0001330714 00000 n 0000010119 00000 n 0000010153 00000 n 0000493536 00000 n 0001330635 00000 n 0000010212 00000 n 0000010260 00000 n 0000493665 00000 n 0001330517 00000 n 0000010314 00000 n 0000010354 00000 n 0000496210 00000 n 0001330438 00000 n 0000010413 00000 n 0000010447 00000 n 0000496339 00000 n 0001330359 00000 n 0000010506 00000 n 0000010554 00000 n 0000496468 00000 n 0001330226 00000 n 0000010603 00000 n 0000010653 00000 n 0000499880 00000 n 0001330147 00000 n 0000010707 00000 n 0000010754 00000 n 0000500008 00000 n 0001330054 00000 n 0000010808 00000 n 0000010868 00000 n 0000503728 00000 n 0001329961 00000 n 0000010922 00000 n 0000010974 00000 n 0000503857 00000 n 0001329868 00000 n 0000011028 00000 n 0000011093 00000 n 0000508517 00000 n 0001329775 00000 n 0000011147 00000 n 0000011198 00000 n 0000508643 00000 n 0001329682 00000 n 0000011252 00000 n 0000011316 00000 n 0000508772 00000 n 0001329589 00000 n 0000011370 00000 n 0000011417 00000 n 0000512549 00000 n 0001329496 00000 n 0000011471 00000 n 0000011531 00000 n 0000512678 00000 n 0001329403 00000 n 0000011585 00000 n 0000011636 00000 n 0000512807 00000 n 0001329271 00000 n 0000011691 00000 n 0000011756 00000 n 0000517251 00000 n 0001329192 00000 n 0000011816 00000 n 0000011863 00000 n 0000523793 00000 n 0001329099 00000 n 0000011923 00000 n 0000011971 00000 n 0000530747 00000 n 0001329020 00000 n 0000012031 00000 n 0000012085 00000 n 0000534245 00000 n 0001328927 00000 n 0000012140 00000 n 0000012190 00000 n 0000534374 00000 n 0001328834 00000 n 0000012245 00000 n 0000012308 00000 n 0000536782 00000 n 0001328741 00000 n 0000012363 00000 n 0000012415 00000 n 0000536911 00000 n 0001328648 00000 n 0000012470 00000 n 0000012535 00000 n 0000537040 00000 n 0001328555 00000 n 0000012590 00000 n 0000012642 00000 n 0000543510 00000 n 0001328422 00000 n 0000012697 00000 n 0000012762 00000 n 0000568453 00000 n 0001328343 00000 n 0000012822 00000 n 0000012866 00000 n 0000594622 00000 n 0001328250 00000 n 0000012926 00000 n 0000012965 00000 n 0000598114 00000 n 0001328157 00000 n 0000013025 00000 n 0000013072 00000 n 0000598243 00000 n 0001328064 00000 n 0000013132 00000 n 0000013175 00000 n 0000606107 00000 n 0001327971 00000 n 0000013235 00000 n 0000013274 00000 n 0000609644 00000 n 0001327878 00000 n 0000013334 00000 n 0000013376 00000 n 0000612704 00000 n 0001327785 00000 n 0000013436 00000 n 0000013479 00000 n 0000620529 00000 n 0001327692 00000 n 0000013539 00000 n 0000013582 00000 n 0000624906 00000 n 0001327599 00000 n 0000013642 00000 n 0000013703 00000 n 0000625035 00000 n 0001327506 00000 n 0000013764 00000 n 0000013816 00000 n 0000633032 00000 n 0001327413 00000 n 0000013877 00000 n 0000013930 00000 n 0000636483 00000 n 0001327320 00000 n 0000013991 00000 n 0000014029 00000 n 0000636612 00000 n 0001327227 00000 n 0000014090 00000 n 0000014142 00000 n 0000643454 00000 n 0001327134 00000 n 0000014203 00000 n 0000014247 00000 n 0000643712 00000 n 0001327041 00000 n 0000014308 00000 n 0000014344 00000 n 0000656491 00000 n 0001326948 00000 n 0000014405 00000 n 0000014468 00000 n 0000659374 00000 n 0001326855 00000 n 0000014529 00000 n 0000014579 00000 n 0000667124 00000 n 0001326762 00000 n 0000014640 00000 n 0000014696 00000 n 0000671460 00000 n 0001326669 00000 n 0000014757 00000 n 0000014804 00000 n 0000675770 00000 n 0001326576 00000 n 0000014865 00000 n 0000014933 00000 n 0000686929 00000 n 0001326497 00000 n 0000014994 00000 n 0000015046 00000 n 0000695046 00000 n 0001326404 00000 n 0000015101 00000 n 0000015152 00000 n 0000695175 00000 n 0001326311 00000 n 0000015207 00000 n 0000015271 00000 n 0000707811 00000 n 0001326218 00000 n 0000015326 00000 n 0000015390 00000 n 0000707940 00000 n 0001326125 00000 n 0000015445 00000 n 0000015522 00000 n 0000712852 00000 n 0001326032 00000 n 0000015577 00000 n 0000015634 00000 n 0000712981 00000 n 0001325939 00000 n 0000015689 00000 n 0000015759 00000 n 0000713110 00000 n 0001325846 00000 n 0000015814 00000 n 0000015871 00000 n 0000713239 00000 n 0001325753 00000 n 0000015926 00000 n 0000015996 00000 n 0000717163 00000 n 0001325660 00000 n 0000016051 00000 n 0000016100 00000 n 0000717290 00000 n 0001325567 00000 n 0000016155 00000 n 0000016217 00000 n 0000722205 00000 n 0001325474 00000 n 0000016272 00000 n 0000016321 00000 n 0000727810 00000 n 0001325356 00000 n 0000016376 00000 n 0000016438 00000 n 0000727939 00000 n 0001325277 00000 n 0000016498 00000 n 0000016537 00000 n 0000735809 00000 n 0001325184 00000 n 0000016597 00000 n 0000016631 00000 n 0000735937 00000 n 0001325091 00000 n 0000016691 00000 n 0000016732 00000 n 0000757920 00000 n 0001324998 00000 n 0000016792 00000 n 0000016844 00000 n 0000768215 00000 n 0001324919 00000 n 0000016904 00000 n 0000016947 00000 n 0000771775 00000 n 0001324787 00000 n 0000016996 00000 n 0000017029 00000 n 0000771904 00000 n 0001324669 00000 n 0000017083 00000 n 0000017155 00000 n 0000772033 00000 n 0001324590 00000 n 0000017214 00000 n 0000017258 00000 n 0000782831 00000 n 0001324511 00000 n 0000017317 00000 n 0000017370 00000 n 0000786511 00000 n 0001324418 00000 n 0000017424 00000 n 0000017474 00000 n 0000786770 00000 n 0001324325 00000 n 0000017528 00000 n 0000017566 00000 n 0000790214 00000 n 0001324232 00000 n 0000017620 00000 n 0000017669 00000 n 0000790473 00000 n 0001324100 00000 n 0000017723 00000 n 0000017775 00000 n 0000790601 00000 n 0001324021 00000 n 0000017834 00000 n 0000017879 00000 n 0000790730 00000 n 0001323928 00000 n 0000017938 00000 n 0000017990 00000 n 0000793700 00000 n 0001323835 00000 n 0000018049 00000 n 0000018102 00000 n 0000793829 00000 n 0001323756 00000 n 0000018161 00000 n 0000018210 00000 n 0000793958 00000 n 0001323663 00000 n 0000018264 00000 n 0000018344 00000 n 0000801325 00000 n 0001323584 00000 n 0000018398 00000 n 0000018447 00000 n 0000801454 00000 n 0001323466 00000 n 0000018496 00000 n 0000018536 00000 n 0000805091 00000 n 0001323387 00000 n 0000018595 00000 n 0000018642 00000 n 0000805220 00000 n 0001323269 00000 n 0000018696 00000 n 0000018741 00000 n 0000805349 00000 n 0001323190 00000 n 0000018800 00000 n 0000018859 00000 n 0000812004 00000 n 0001323097 00000 n 0000018918 00000 n 0000018982 00000 n 0000812263 00000 n 0001323004 00000 n 0000019041 00000 n 0000019097 00000 n 0000816136 00000 n 0001322911 00000 n 0000019156 00000 n 0000019214 00000 n 0000816395 00000 n 0001322832 00000 n 0000019273 00000 n 0000019335 00000 n 0000819058 00000 n 0001322699 00000 n 0000019382 00000 n 0000019434 00000 n 0000819186 00000 n 0001322620 00000 n 0000019483 00000 n 0000019527 00000 n 0000822995 00000 n 0001322488 00000 n 0000019576 00000 n 0000019617 00000 n 0000823124 00000 n 0001322409 00000 n 0000019671 00000 n 0000019719 00000 n 0000823253 00000 n 0001322330 00000 n 0000019773 00000 n 0000019824 00000 n 0000823381 00000 n 0001322251 00000 n 0000019873 00000 n 0000019920 00000 n 0000827716 00000 n 0001322118 00000 n 0000019967 00000 n 0000020004 00000 n 0000827845 00000 n 0001322000 00000 n 0000020053 00000 n 0000020092 00000 n 0000827974 00000 n 0001321935 00000 n 0000020146 00000 n 0000020224 00000 n 0000828103 00000 n 0001321842 00000 n 0000020273 00000 n 0000020340 00000 n 0000828232 00000 n 0001321763 00000 n 0000020389 00000 n 0000020434 00000 n 0000831261 00000 n 0001321630 00000 n 0000020482 00000 n 0000020517 00000 n 0000831388 00000 n 0001321526 00000 n 0000020566 00000 n 0000020630 00000 n 0000831515 00000 n 0001321447 00000 n 0000020684 00000 n 0000020722 00000 n 0000831643 00000 n 0001321354 00000 n 0000020776 00000 n 0000020810 00000 n 0000831772 00000 n 0001321261 00000 n 0000020864 00000 n 0000020904 00000 n 0000834162 00000 n 0001321168 00000 n 0000020958 00000 n 0000020996 00000 n 0000834291 00000 n 0001321075 00000 n 0000021050 00000 n 0000021091 00000 n 0000834420 00000 n 0001320982 00000 n 0000021145 00000 n 0000021180 00000 n 0000834549 00000 n 0001320889 00000 n 0000021234 00000 n 0000021271 00000 n 0000834678 00000 n 0001320810 00000 n 0000021325 00000 n 0000021360 00000 n 0000837903 00000 n 0001320677 00000 n 0000021408 00000 n 0000021465 00000 n 0000838032 00000 n 0001320612 00000 n 0000021514 00000 n 0000021545 00000 n 0000842260 00000 n 0001320479 00000 n 0000021593 00000 n 0000021648 00000 n 0000842389 00000 n 0001320400 00000 n 0000021697 00000 n 0000021744 00000 n 0000842518 00000 n 0001320282 00000 n 0000021793 00000 n 0000021855 00000 n 0000842647 00000 n 0001320203 00000 n 0000021909 00000 n 0000021964 00000 n 0000866881 00000 n 0001320110 00000 n 0000022018 00000 n 0000022059 00000 n 0000867010 00000 n 0001320031 00000 n 0000022113 00000 n 0000022165 00000 n 0000870344 00000 n 0001319898 00000 n 0000022213 00000 n 0000022261 00000 n 0000870473 00000 n 0001319794 00000 n 0000022310 00000 n 0000022360 00000 n 0000870601 00000 n 0001319715 00000 n 0000022414 00000 n 0000022452 00000 n 0000870730 00000 n 0001319622 00000 n 0000022506 00000 n 0000022543 00000 n 0000874007 00000 n 0001319529 00000 n 0000022597 00000 n 0000022635 00000 n 0000874136 00000 n 0001319436 00000 n 0000022689 00000 n 0000022741 00000 n 0000874264 00000 n 0001319343 00000 n 0000022795 00000 n 0000022838 00000 n 0000874392 00000 n 0001319211 00000 n 0000022892 00000 n 0000022937 00000 n 0000877092 00000 n 0001319132 00000 n 0000022996 00000 n 0000023062 00000 n 0000877221 00000 n 0001319039 00000 n 0000023121 00000 n 0000023209 00000 n 0000880417 00000 n 0001318946 00000 n 0000023268 00000 n 0000023343 00000 n 0000880545 00000 n 0001318853 00000 n 0000023402 00000 n 0000023487 00000 n 0000880674 00000 n 0001318760 00000 n 0000023546 00000 n 0000023627 00000 n 0000883652 00000 n 0001318681 00000 n 0000023686 00000 n 0000023770 00000 n 0000884717 00000 n 0001318602 00000 n 0000023824 00000 n 0000023868 00000 n 0000887310 00000 n 0001318481 00000 n 0000023916 00000 n 0000023950 00000 n 0000887439 00000 n 0001318402 00000 n 0000023999 00000 n 0000024026 00000 n 0000913371 00000 n 0001318309 00000 n 0000024075 00000 n 0000024103 00000 n 0000917248 00000 n 0001318216 00000 n 0000024152 00000 n 0000024180 00000 n 0000933988 00000 n 0001318123 00000 n 0000024229 00000 n 0000024267 00000 n 0000934505 00000 n 0001318030 00000 n 0000024316 00000 n 0000024355 00000 n 0000941167 00000 n 0001317937 00000 n 0000024404 00000 n 0000024444 00000 n 0000947100 00000 n 0001317844 00000 n 0000024493 00000 n 0000024533 00000 n 0000953631 00000 n 0001317751 00000 n 0000024582 00000 n 0000024625 00000 n 0000964256 00000 n 0001317658 00000 n 0000024674 00000 n 0000024711 00000 n 0000977982 00000 n 0001317565 00000 n 0000024761 00000 n 0000024799 00000 n 0000981211 00000 n 0001317472 00000 n 0000024849 00000 n 0000024888 00000 n 0000988214 00000 n 0001317379 00000 n 0000024938 00000 n 0000024978 00000 n 0001006261 00000 n 0001317286 00000 n 0000025028 00000 n 0000025066 00000 n 0001012610 00000 n 0001317193 00000 n 0000025116 00000 n 0000025156 00000 n 0001015513 00000 n 0001317100 00000 n 0000025206 00000 n 0000025246 00000 n 0001025801 00000 n 0001317007 00000 n 0000025296 00000 n 0000025326 00000 n 0001035327 00000 n 0001316914 00000 n 0000025376 00000 n 0000025419 00000 n 0001037578 00000 n 0001316821 00000 n 0000025469 00000 n 0000025509 00000 n 0001037966 00000 n 0001316728 00000 n 0000025559 00000 n 0000025592 00000 n 0001055476 00000 n 0001316635 00000 n 0000025642 00000 n 0000025671 00000 n 0001074449 00000 n 0001316540 00000 n 0000025721 00000 n 0000025756 00000 n 0001080250 00000 n 0001316443 00000 n 0000025807 00000 n 0000025845 00000 n 0001087028 00000 n 0001316345 00000 n 0000025896 00000 n 0000025934 00000 n 0001089496 00000 n 0001316247 00000 n 0000025985 00000 n 0000026019 00000 n 0001091583 00000 n 0001316149 00000 n 0000026070 00000 n 0000026105 00000 n 0001092101 00000 n 0001316051 00000 n 0000026156 00000 n 0000026196 00000 n 0001094977 00000 n 0001315968 00000 n 0000026247 00000 n 0000026282 00000 n 0000026696 00000 n 0000026822 00000 n 0000291658 00000 n 0000026337 00000 n 0000291528 00000 n 0000291593 00000 n 0001309088 00000 n 0001282767 00000 n 0001308912 00000 n 0001281517 00000 n 0001254541 00000 n 0001281341 00000 n 0001310149 00000 n 0000028137 00000 n 0000028331 00000 n 0000028413 00000 n 0000028452 00000 n 0000028536 00000 n 0000028661 00000 n 0000028927 00000 n 0000029287 00000 n 0000029320 00000 n 0000029415 00000 n 0000030449 00000 n 0000041586 00000 n 0000107177 00000 n 0000172768 00000 n 0000238359 00000 n 0000293126 00000 n 0000292935 00000 n 0000291775 00000 n 0000293061 00000 n 0001253854 00000 n 0001251706 00000 n 0001253688 00000 n 0000305006 00000 n 0000296243 00000 n 0000293214 00000 n 0000304876 00000 n 0000304941 00000 n 0000296831 00000 n 0000296986 00000 n 0000297144 00000 n 0000297302 00000 n 0000297460 00000 n 0000297618 00000 n 0000297781 00000 n 0000297944 00000 n 0000298106 00000 n 0000298269 00000 n 0000298437 00000 n 0000298605 00000 n 0000298771 00000 n 0000298934 00000 n 0000299101 00000 n 0000299264 00000 n 0000299419 00000 n 0000299577 00000 n 0000299735 00000 n 0000299892 00000 n 0000300049 00000 n 0000300207 00000 n 0000300363 00000 n 0000300521 00000 n 0000300684 00000 n 0000300847 00000 n 0000301005 00000 n 0000301161 00000 n 0000301323 00000 n 0000301491 00000 n 0000301659 00000 n 0000301822 00000 n 0000301978 00000 n 0000302136 00000 n 0000302294 00000 n 0000302457 00000 n 0000302615 00000 n 0000302773 00000 n 0000302936 00000 n 0000303094 00000 n 0000303257 00000 n 0000303425 00000 n 0000303593 00000 n 0000303756 00000 n 0000303919 00000 n 0000304082 00000 n 0000304245 00000 n 0000304408 00000 n 0000304564 00000 n 0000304720 00000 n 0000318540 00000 n 0000308462 00000 n 0000305094 00000 n 0000318475 00000 n 0001251118 00000 n 0001233697 00000 n 0001250932 00000 n 0000309113 00000 n 0000309277 00000 n 0000309441 00000 n 0000309604 00000 n 0000309763 00000 n 0000309927 00000 n 0000310090 00000 n 0000310254 00000 n 0000310418 00000 n 0000310582 00000 n 0000310746 00000 n 0000310910 00000 n 0000311074 00000 n 0000311238 00000 n 0000311403 00000 n 0000311568 00000 n 0000311733 00000 n 0000311898 00000 n 0000312058 00000 n 0000312223 00000 n 0000312387 00000 n 0000312547 00000 n 0000312712 00000 n 0000312876 00000 n 0000313046 00000 n 0000313211 00000 n 0000313380 00000 n 0000313549 00000 n 0000313719 00000 n 0000313889 00000 n 0000314058 00000 n 0000314228 00000 n 0000314398 00000 n 0000314563 00000 n 0000314728 00000 n 0000314893 00000 n 0000315058 00000 n 0000315218 00000 n 0000315383 00000 n 0000315548 00000 n 0000315708 00000 n 0000315873 00000 n 0000316038 00000 n 0000316195 00000 n 0000316354 00000 n 0000316513 00000 n 0000316670 00000 n 0000316829 00000 n 0000316993 00000 n 0000317162 00000 n 0000317331 00000 n 0000317495 00000 n 0000317664 00000 n 0000317833 00000 n 0000317990 00000 n 0000318152 00000 n 0000318313 00000 n 0000332609 00000 n 0000322067 00000 n 0000318642 00000 n 0000332544 00000 n 0000322736 00000 n 0000322899 00000 n 0000323062 00000 n 0000323225 00000 n 0000323388 00000 n 0000323551 00000 n 0000323713 00000 n 0000323877 00000 n 0000324046 00000 n 0000324215 00000 n 0000324383 00000 n 0000324547 00000 n 0000324711 00000 n 0000324874 00000 n 0000325038 00000 n 0000325202 00000 n 0000325366 00000 n 0000325535 00000 n 0000325704 00000 n 0000325872 00000 n 0000326041 00000 n 0000326210 00000 n 0000326379 00000 n 0000326548 00000 n 0000326717 00000 n 0000326886 00000 n 0000327056 00000 n 0000327226 00000 n 0000327395 00000 n 0000327565 00000 n 0000327734 00000 n 0000327904 00000 n 0000328074 00000 n 0000328244 00000 n 0000328414 00000 n 0000328584 00000 n 0000328753 00000 n 0000328923 00000 n 0000329087 00000 n 0000329250 00000 n 0000329414 00000 n 0000329577 00000 n 0000329741 00000 n 0000329905 00000 n 0000330069 00000 n 0000330233 00000 n 0000330397 00000 n 0000330561 00000 n 0000330724 00000 n 0000330888 00000 n 0000331056 00000 n 0000331225 00000 n 0000331394 00000 n 0000331563 00000 n 0000331732 00000 n 0000331890 00000 n 0000332053 00000 n 0000332219 00000 n 0000332384 00000 n 0000345589 00000 n 0000336160 00000 n 0000332711 00000 n 0000345524 00000 n 0000336784 00000 n 0000336947 00000 n 0000337110 00000 n 0000337273 00000 n 0000337441 00000 n 0000337609 00000 n 0000337777 00000 n 0000337945 00000 n 0000338108 00000 n 0000338271 00000 n 0000338429 00000 n 0000338597 00000 n 0000338760 00000 n 0000338928 00000 n 0000339096 00000 n 0000339264 00000 n 0001232793 00000 n 0001211309 00000 n 0001232617 00000 n 0000339432 00000 n 0000339600 00000 n 0000339756 00000 n 0000339914 00000 n 0000340072 00000 n 0000340235 00000 n 0000340398 00000 n 0000340556 00000 n 0000340712 00000 n 0000340870 00000 n 0000341033 00000 n 0000341191 00000 n 0000341349 00000 n 0000341506 00000 n 0000341664 00000 n 0000341827 00000 n 0000341990 00000 n 0000342153 00000 n 0000342316 00000 n 0000342479 00000 n 0000342642 00000 n 0000342805 00000 n 0000342968 00000 n 0000343125 00000 n 0000343283 00000 n 0000343439 00000 n 0000343597 00000 n 0000343754 00000 n 0000343917 00000 n 0000344080 00000 n 0000344243 00000 n 0000344399 00000 n 0000344556 00000 n 0000344716 00000 n 0000344878 00000 n 0000345041 00000 n 0000345202 00000 n 0000345363 00000 n 0000354038 00000 n 0000347916 00000 n 0000345705 00000 n 0000353973 00000 n 0000348369 00000 n 0000348537 00000 n 0000348705 00000 n 0000348872 00000 n 0000349040 00000 n 0000349207 00000 n 0000349375 00000 n 0000349538 00000 n 0000349695 00000 n 0000349853 00000 n 0000350011 00000 n 0000350169 00000 n 0000350327 00000 n 0000350484 00000 n 0000350642 00000 n 0000350800 00000 n 0000350958 00000 n 0000351116 00000 n 0000351275 00000 n 0000351433 00000 n 0000351592 00000 n 0000351751 00000 n 0000351910 00000 n 0000352068 00000 n 0000352227 00000 n 0000352384 00000 n 0000352543 00000 n 0000352702 00000 n 0001210330 00000 n 0001190203 00000 n 0001210155 00000 n 0000352861 00000 n 0000353020 00000 n 0000353179 00000 n 0000353338 00000 n 0000353497 00000 n 0000353656 00000 n 0000353815 00000 n 0001310274 00000 n 0000357205 00000 n 0000356438 00000 n 0000354154 00000 n 0000356626 00000 n 0000356754 00000 n 0000356882 00000 n 0000357010 00000 n 0000357075 00000 n 0000357140 00000 n 0001189349 00000 n 0001170125 00000 n 0001189174 00000 n 0000361754 00000 n 0000360615 00000 n 0000357335 00000 n 0000361115 00000 n 0000361180 00000 n 0000361307 00000 n 0000361435 00000 n 0000361563 00000 n 0000360771 00000 n 0000360965 00000 n 0000361689 00000 n 0000771968 00000 n 0000842711 00000 n 0000366453 00000 n 0000365395 00000 n 0000361884 00000 n 0000365876 00000 n 0000366004 00000 n 0000365551 00000 n 0000365714 00000 n 0000366132 00000 n 0000366260 00000 n 0000366388 00000 n 0000382442 00000 n 0000369708 00000 n 0000369133 00000 n 0000366583 00000 n 0000369259 00000 n 0000369387 00000 n 0000369515 00000 n 0000369643 00000 n 0000373229 00000 n 0000372063 00000 n 0000369824 00000 n 0000372525 00000 n 0000372653 00000 n 0000372781 00000 n 0000372909 00000 n 0000373037 00000 n 0000372219 00000 n 0000372372 00000 n 0000373164 00000 n 0000667188 00000 n 0000374317 00000 n 0000373998 00000 n 0000373317 00000 n 0000374124 00000 n 0000374252 00000 n 0001310399 00000 n 0000376427 00000 n 0000375724 00000 n 0000374419 00000 n 0000375850 00000 n 0000375978 00000 n 0000376105 00000 n 0000376233 00000 n 0000376362 00000 n 0000379022 00000 n 0000378392 00000 n 0000376529 00000 n 0000378698 00000 n 0000378827 00000 n 0000378892 00000 n 0000378957 00000 n 0000378539 00000 n 0000643518 00000 n 0000382636 00000 n 0000381931 00000 n 0000379138 00000 n 0000382057 00000 n 0000382186 00000 n 0000382313 00000 n 0001169403 00000 n 0001156026 00000 n 0001169224 00000 n 0000382571 00000 n 0000387591 00000 n 0000387030 00000 n 0000382766 00000 n 0000387526 00000 n 0000387186 00000 n 0000387340 00000 n 0001055540 00000 n 0000503921 00000 n 0000389856 00000 n 0000389407 00000 n 0000387749 00000 n 0000389533 00000 n 0000389662 00000 n 0000389727 00000 n 0000389791 00000 n 0000390327 00000 n 0000390136 00000 n 0000389986 00000 n 0000390262 00000 n 0001310524 00000 n 0000393054 00000 n 0000395644 00000 n 0000392889 00000 n 0000390369 00000 n 0000395192 00000 n 0000395321 00000 n 0000395450 00000 n 0000394697 00000 n 0000394859 00000 n 0001155116 00000 n 0001145007 00000 n 0001154942 00000 n 0001144439 00000 n 0001135299 00000 n 0001144264 00000 n 0000395579 00000 n 0000395021 00000 n 0000394526 00000 n 0000394584 00000 n 0000394674 00000 n 0000568517 00000 n 0000612768 00000 n 0000757984 00000 n 0000400437 00000 n 0000399502 00000 n 0000395817 00000 n 0000399985 00000 n 0000400114 00000 n 0001134661 00000 n 0001121925 00000 n 0001134482 00000 n 0000400243 00000 n 0000399658 00000 n 0000399823 00000 n 0000400372 00000 n 0000846660 00000 n 0000404177 00000 n 0000403857 00000 n 0000400595 00000 n 0000403983 00000 n 0000404112 00000 n 0000405771 00000 n 0000405391 00000 n 0000404321 00000 n 0000405706 00000 n 0000405538 00000 n 0000407362 00000 n 0000407043 00000 n 0000405873 00000 n 0000407169 00000 n 0000407298 00000 n 0000410836 00000 n 0000410000 00000 n 0000407478 00000 n 0000410126 00000 n 0000410255 00000 n 0000410384 00000 n 0000410513 00000 n 0000410642 00000 n 0000410771 00000 n 0001310649 00000 n 0000414701 00000 n 0000413804 00000 n 0000410980 00000 n 0000414121 00000 n 0000414250 00000 n 0000414379 00000 n 0000413951 00000 n 0000414508 00000 n 0000414637 00000 n 0000418828 00000 n 0000418251 00000 n 0000414845 00000 n 0000418377 00000 n 0000418506 00000 n 0000418634 00000 n 0000418763 00000 n 0000422876 00000 n 0000422428 00000 n 0000418972 00000 n 0000422554 00000 n 0000422683 00000 n 0000422811 00000 n 0000424890 00000 n 0000424699 00000 n 0000423006 00000 n 0000424825 00000 n 0000428176 00000 n 0000427727 00000 n 0000424992 00000 n 0000427853 00000 n 0001121650 00000 n 0001118291 00000 n 0001121471 00000 n 0000427982 00000 n 0000428111 00000 n 0000432301 00000 n 0000431493 00000 n 0000428349 00000 n 0000431978 00000 n 0000432107 00000 n 0000432236 00000 n 0001117936 00000 n 0001115939 00000 n 0001117771 00000 n 0000431649 00000 n 0000431813 00000 n 0001310774 00000 n 0000964320 00000 n 0000981275 00000 n 0000435655 00000 n 0000435078 00000 n 0000432431 00000 n 0000435204 00000 n 0000435333 00000 n 0000435462 00000 n 0000435591 00000 n 0000439218 00000 n 0000438257 00000 n 0000435771 00000 n 0000438383 00000 n 0000438512 00000 n 0000438641 00000 n 0000438770 00000 n 0000438897 00000 n 0000439026 00000 n 0000439154 00000 n 0000443443 00000 n 0000442556 00000 n 0000439348 00000 n 0000442863 00000 n 0000442992 00000 n 0000443121 00000 n 0000443250 00000 n 0000442703 00000 n 0000443378 00000 n 0000713303 00000 n 0000447082 00000 n 0000446504 00000 n 0000443559 00000 n 0000446630 00000 n 0000446759 00000 n 0000446888 00000 n 0000447017 00000 n 0000451469 00000 n 0000450621 00000 n 0000447226 00000 n 0000451146 00000 n 0000451275 00000 n 0000450777 00000 n 0000450968 00000 n 0000451404 00000 n 0000454265 00000 n 0000453816 00000 n 0000451670 00000 n 0000453942 00000 n 0000454071 00000 n 0000454200 00000 n 0001310899 00000 n 0000457286 00000 n 0000456641 00000 n 0000454424 00000 n 0000456964 00000 n 0000457093 00000 n 0000457221 00000 n 0000456788 00000 n 0000459838 00000 n 0000459260 00000 n 0000457416 00000 n 0000459386 00000 n 0000459515 00000 n 0000459644 00000 n 0000459773 00000 n 0000462948 00000 n 0000462500 00000 n 0000459954 00000 n 0000462626 00000 n 0000462755 00000 n 0000462883 00000 n 0000466384 00000 n 0000465744 00000 n 0000463064 00000 n 0000466062 00000 n 0000465891 00000 n 0000466191 00000 n 0000466320 00000 n 0000953695 00000 n 0000469569 00000 n 0000470689 00000 n 0000469443 00000 n 0000466514 00000 n 0000470495 00000 n 0000470624 00000 n 0000473500 00000 n 0000473051 00000 n 0000470862 00000 n 0000473177 00000 n 0000473306 00000 n 0000473435 00000 n 0001311024 00000 n 0000477281 00000 n 0000476522 00000 n 0000473630 00000 n 0000476829 00000 n 0000476958 00000 n 0000476669 00000 n 0000477087 00000 n 0000477216 00000 n 0000842453 00000 n 0000477766 00000 n 0000477575 00000 n 0000477425 00000 n 0000477701 00000 n 0000480439 00000 n 0000479861 00000 n 0000477808 00000 n 0000479987 00000 n 0000480116 00000 n 0000480245 00000 n 0000480374 00000 n 0000480882 00000 n 0000480691 00000 n 0000480541 00000 n 0000480817 00000 n 0000484995 00000 n 0000484229 00000 n 0000480924 00000 n 0000484543 00000 n 0000484672 00000 n 0000484800 00000 n 0000484865 00000 n 0000484930 00000 n 0000484376 00000 n 0000493342 00000 n 0000489792 00000 n 0000489601 00000 n 0000485097 00000 n 0000489727 00000 n 0001311149 00000 n 0000493794 00000 n 0000493087 00000 n 0000489936 00000 n 0000493213 00000 n 0000493471 00000 n 0000493600 00000 n 0000493729 00000 n 0000496725 00000 n 0000496019 00000 n 0000493938 00000 n 0000496145 00000 n 0000496274 00000 n 0000496403 00000 n 0000496532 00000 n 0000496597 00000 n 0000496661 00000 n 0000500266 00000 n 0000499689 00000 n 0000496884 00000 n 0000499815 00000 n 0000499943 00000 n 0000500072 00000 n 0000500136 00000 n 0000500201 00000 n 0000503986 00000 n 0000503537 00000 n 0000500382 00000 n 0000503663 00000 n 0000503792 00000 n 0000508901 00000 n 0000507987 00000 n 0000504130 00000 n 0000508452 00000 n 0000508143 00000 n 0000508294 00000 n 0000508580 00000 n 0000508707 00000 n 0000508836 00000 n 0001096918 00000 n 0000512936 00000 n 0000511797 00000 n 0000509045 00000 n 0000512484 00000 n 0000512613 00000 n 0000511962 00000 n 0000512114 00000 n 0000512300 00000 n 0000512742 00000 n 0000512871 00000 n 0001311274 00000 n 0000517380 00000 n 0000517060 00000 n 0000513066 00000 n 0000517186 00000 n 0000517315 00000 n 0000520588 00000 n 0000520209 00000 n 0000517510 00000 n 0000520523 00000 n 0000520356 00000 n 0000523857 00000 n 0000524052 00000 n 0000523602 00000 n 0000520704 00000 n 0000523728 00000 n 0000523922 00000 n 0000523987 00000 n 0000527281 00000 n 0000527090 00000 n 0000524168 00000 n 0000527216 00000 n 0000531006 00000 n 0000530556 00000 n 0000527397 00000 n 0000530682 00000 n 0000530811 00000 n 0000530876 00000 n 0000530941 00000 n 0000534503 00000 n 0000533723 00000 n 0000531122 00000 n 0000534180 00000 n 0000534309 00000 n 0000534438 00000 n 0000533879 00000 n 0000534031 00000 n 0001311399 00000 n 0000537169 00000 n 0000536591 00000 n 0000534619 00000 n 0000536717 00000 n 0000536846 00000 n 0000536975 00000 n 0000537104 00000 n 0000538726 00000 n 0000538535 00000 n 0000537285 00000 n 0000538661 00000 n 0000540299 00000 n 0000540108 00000 n 0000538828 00000 n 0000540234 00000 n 0000541742 00000 n 0000541551 00000 n 0000540401 00000 n 0000541677 00000 n 0000543639 00000 n 0000543319 00000 n 0000541844 00000 n 0000543445 00000 n 0000543574 00000 n 0000547340 00000 n 0000546979 00000 n 0000543755 00000 n 0000547275 00000 n 0000547126 00000 n 0001311524 00000 n 0000551593 00000 n 0000551402 00000 n 0000547470 00000 n 0000551528 00000 n 0000555995 00000 n 0000555447 00000 n 0000551737 00000 n 0000555930 00000 n 0000555603 00000 n 0000555760 00000 n 0000805155 00000 n 0000560019 00000 n 0000559620 00000 n 0000556125 00000 n 0000559954 00000 n 0000559767 00000 n 0000564137 00000 n 0000563754 00000 n 0000560163 00000 n 0000564072 00000 n 0000563901 00000 n 0000568710 00000 n 0000568084 00000 n 0000564267 00000 n 0000568388 00000 n 0000568231 00000 n 0000568582 00000 n 0000568646 00000 n 0000572588 00000 n 0000572222 00000 n 0000568826 00000 n 0000572523 00000 n 0000572369 00000 n 0001311649 00000 n 0000577540 00000 n 0000576573 00000 n 0000572718 00000 n 0000577475 00000 n 0000576747 00000 n 0000576932 00000 n 0000577106 00000 n 0000577291 00000 n 0000695239 00000 n 0000581883 00000 n 0000581692 00000 n 0000577727 00000 n 0000581818 00000 n 0000585987 00000 n 0000585796 00000 n 0000582027 00000 n 0000585922 00000 n 0000589922 00000 n 0000589731 00000 n 0000586160 00000 n 0000589857 00000 n 0000594751 00000 n 0000593894 00000 n 0000590038 00000 n 0000594557 00000 n 0000594059 00000 n 0000594224 00000 n 0000594686 00000 n 0000594390 00000 n 0000722269 00000 n 0000598372 00000 n 0000597735 00000 n 0000594867 00000 n 0000598049 00000 n 0000598178 00000 n 0000598307 00000 n 0000597882 00000 n 0001311774 00000 n 0000602764 00000 n 0000602202 00000 n 0000598531 00000 n 0000602699 00000 n 0000602358 00000 n 0000602528 00000 n 0000823445 00000 n 0000606236 00000 n 0000605916 00000 n 0000602894 00000 n 0000606042 00000 n 0000606171 00000 n 0000609773 00000 n 0000609453 00000 n 0000606366 00000 n 0000609579 00000 n 0000609708 00000 n 0000612832 00000 n 0000612513 00000 n 0000609889 00000 n 0000612639 00000 n 0000616988 00000 n 0000616797 00000 n 0000612991 00000 n 0000616923 00000 n 0000620658 00000 n 0000620156 00000 n 0000617147 00000 n 0000620464 00000 n 0000620593 00000 n 0000620303 00000 n 0001311899 00000 n 0000625163 00000 n 0000624355 00000 n 0000620831 00000 n 0000624841 00000 n 0000624970 00000 n 0000624511 00000 n 0000625099 00000 n 0000624686 00000 n 0000629053 00000 n 0000628862 00000 n 0000625279 00000 n 0000628988 00000 n 0000633161 00000 n 0000632841 00000 n 0000629197 00000 n 0000632967 00000 n 0000633096 00000 n 0000636741 00000 n 0000636111 00000 n 0000633291 00000 n 0000636418 00000 n 0000636547 00000 n 0000636676 00000 n 0000636258 00000 n 0000639949 00000 n 0000639582 00000 n 0000636914 00000 n 0000639884 00000 n 0000639729 00000 n 0000643841 00000 n 0000643072 00000 n 0000640065 00000 n 0000643389 00000 n 0000643219 00000 n 0000643583 00000 n 0000643647 00000 n 0000643776 00000 n 0001312024 00000 n 0000647909 00000 n 0000647535 00000 n 0000644028 00000 n 0000647844 00000 n 0000647682 00000 n 0000652248 00000 n 0000651873 00000 n 0000648096 00000 n 0000652183 00000 n 0000652020 00000 n 0000801389 00000 n 0000656619 00000 n 0000656111 00000 n 0000652364 00000 n 0000656426 00000 n 0000656555 00000 n 0000656258 00000 n 0000717225 00000 n 0000659502 00000 n 0000659183 00000 n 0000656763 00000 n 0000659309 00000 n 0000659437 00000 n 0000661239 00000 n 0000661048 00000 n 0000659632 00000 n 0000661174 00000 n 0000663494 00000 n 0000663303 00000 n 0000661341 00000 n 0000663429 00000 n 0001312149 00000 n 0000667253 00000 n 0000666933 00000 n 0000663610 00000 n 0000667059 00000 n 0000671589 00000 n 0000671043 00000 n 0000667398 00000 n 0000671395 00000 n 0000671524 00000 n 0000671190 00000 n 0000675899 00000 n 0000675579 00000 n 0000671719 00000 n 0000675705 00000 n 0000675834 00000 n 0000680121 00000 n 0000679606 00000 n 0000676029 00000 n 0000679732 00000 n 0000679797 00000 n 0000679861 00000 n 0000679926 00000 n 0000679991 00000 n 0000680056 00000 n 0000683713 00000 n 0000683522 00000 n 0000680223 00000 n 0000683648 00000 n 0000687058 00000 n 0000686738 00000 n 0000683829 00000 n 0000686864 00000 n 0000686993 00000 n 0001312274 00000 n 0000692074 00000 n 0000691883 00000 n 0000687188 00000 n 0000692009 00000 n 0000695304 00000 n 0000694855 00000 n 0000692190 00000 n 0000694981 00000 n 0000695110 00000 n 0000700454 00000 n 0000699920 00000 n 0000695420 00000 n 0000700389 00000 n 0000700076 00000 n 0000700228 00000 n 0000708068 00000 n 0000704732 00000 n 0000700556 00000 n 0000707746 00000 n 0000707875 00000 n 0000708003 00000 n 0000705005 00000 n 0000705179 00000 n 0000705356 00000 n 0000705537 00000 n 0000705716 00000 n 0000705897 00000 n 0000706085 00000 n 0000706273 00000 n 0000706460 00000 n 0000706645 00000 n 0000706829 00000 n 0000707014 00000 n 0000707197 00000 n 0000707384 00000 n 0000707559 00000 n 0000713367 00000 n 0000711315 00000 n 0000708198 00000 n 0000712787 00000 n 0000711516 00000 n 0000711704 00000 n 0000711891 00000 n 0000712074 00000 n 0000712259 00000 n 0000712445 00000 n 0000712916 00000 n 0000713045 00000 n 0000712633 00000 n 0000713174 00000 n 0000717419 00000 n 0000716972 00000 n 0000713497 00000 n 0000717098 00000 n 0000717354 00000 n 0001312399 00000 n 0000720567 00000 n 0000720376 00000 n 0000717563 00000 n 0000720502 00000 n 0000722334 00000 n 0000722014 00000 n 0000720683 00000 n 0000722140 00000 n 0000723965 00000 n 0000723774 00000 n 0000722450 00000 n 0000723900 00000 n 0000725420 00000 n 0000725229 00000 n 0000724067 00000 n 0000725355 00000 n 0000728198 00000 n 0000727619 00000 n 0000725522 00000 n 0000727745 00000 n 0000727874 00000 n 0000728003 00000 n 0000728068 00000 n 0000728133 00000 n 0000731876 00000 n 0000731685 00000 n 0000728314 00000 n 0000731811 00000 n 0001312524 00000 n 0000736065 00000 n 0000735260 00000 n 0000731992 00000 n 0000735744 00000 n 0000735416 00000 n 0000735872 00000 n 0000736001 00000 n 0000735584 00000 n 0001096884 00000 n 0000742331 00000 n 0000739388 00000 n 0000736195 00000 n 0000742266 00000 n 0000739670 00000 n 0000739832 00000 n 0000739994 00000 n 0000740156 00000 n 0000740318 00000 n 0000740489 00000 n 0000740651 00000 n 0000740814 00000 n 0000740976 00000 n 0000741139 00000 n 0000741301 00000 n 0000741464 00000 n 0000741626 00000 n 0000741789 00000 n 0000741943 00000 n 0000742106 00000 n 0000747572 00000 n 0000745655 00000 n 0000742447 00000 n 0000747507 00000 n 0000745883 00000 n 0000746046 00000 n 0000746213 00000 n 0000746382 00000 n 0000746544 00000 n 0000746705 00000 n 0000746867 00000 n 0000747028 00000 n 0000747191 00000 n 0000747344 00000 n 0000752475 00000 n 0000750603 00000 n 0000747702 00000 n 0000752410 00000 n 0000750831 00000 n 0000750983 00000 n 0000751137 00000 n 0000751288 00000 n 0000751442 00000 n 0000751604 00000 n 0000751766 00000 n 0000751927 00000 n 0000752089 00000 n 0000752250 00000 n 0000758048 00000 n 0000756035 00000 n 0000752591 00000 n 0000757855 00000 n 0000756263 00000 n 0000756422 00000 n 0000756575 00000 n 0000756738 00000 n 0000756889 00000 n 0000757054 00000 n 0000757220 00000 n 0000757383 00000 n 0000757537 00000 n 0000757692 00000 n 0000762086 00000 n 0000761765 00000 n 0000758192 00000 n 0000761891 00000 n 0000761956 00000 n 0000762021 00000 n 0001312649 00000 n 0000765122 00000 n 0000764931 00000 n 0000762230 00000 n 0000765057 00000 n 0000768344 00000 n 0000768024 00000 n 0000765295 00000 n 0000768150 00000 n 0000768279 00000 n 0000772291 00000 n 0000771222 00000 n 0000768517 00000 n 0000771710 00000 n 0000771839 00000 n 0000772096 00000 n 0000771378 00000 n 0000771548 00000 n 0000772161 00000 n 0000772226 00000 n 0000775827 00000 n 0000775506 00000 n 0000772421 00000 n 0000775632 00000 n 0000775697 00000 n 0000775762 00000 n 0000778997 00000 n 0000778806 00000 n 0000775915 00000 n 0000778932 00000 n 0000782960 00000 n 0000782510 00000 n 0000779085 00000 n 0000782636 00000 n 0000782701 00000 n 0000782766 00000 n 0000782895 00000 n 0001312774 00000 n 0000786898 00000 n 0000786060 00000 n 0000783090 00000 n 0000786186 00000 n 0000786251 00000 n 0000786316 00000 n 0000786381 00000 n 0000786446 00000 n 0000786575 00000 n 0000786640 00000 n 0000786705 00000 n 0000786834 00000 n 0000790858 00000 n 0000789893 00000 n 0000787028 00000 n 0000790019 00000 n 0000790084 00000 n 0000790149 00000 n 0000790278 00000 n 0000790343 00000 n 0000790408 00000 n 0000790536 00000 n 0000790665 00000 n 0000790794 00000 n 0000794087 00000 n 0000793509 00000 n 0000791073 00000 n 0000793635 00000 n 0000793764 00000 n 0000793893 00000 n 0000794022 00000 n 0000797572 00000 n 0000797251 00000 n 0000794288 00000 n 0000797377 00000 n 0000797442 00000 n 0000797507 00000 n 0000801712 00000 n 0000801134 00000 n 0000797702 00000 n 0000801260 00000 n 0000801518 00000 n 0000801583 00000 n 0000801648 00000 n 0000805608 00000 n 0000804719 00000 n 0000801842 00000 n 0000805026 00000 n 0000804866 00000 n 0000805284 00000 n 0000805413 00000 n 0000805478 00000 n 0000805543 00000 n 0001312899 00000 n 0000809207 00000 n 0000808831 00000 n 0000805738 00000 n 0000809142 00000 n 0000808978 00000 n 0001096850 00000 n 0000812522 00000 n 0000811813 00000 n 0000809309 00000 n 0000811939 00000 n 0000812068 00000 n 0000812133 00000 n 0000812198 00000 n 0000812327 00000 n 0000812392 00000 n 0000812457 00000 n 0000816524 00000 n 0000815945 00000 n 0000812638 00000 n 0000816071 00000 n 0000816200 00000 n 0000816265 00000 n 0000816330 00000 n 0001115658 00000 n 0001108375 00000 n 0001115478 00000 n 0000816459 00000 n 0000817385 00000 n 0000817194 00000 n 0000816668 00000 n 0000817320 00000 n 0000819314 00000 n 0000818867 00000 n 0000817487 00000 n 0000818993 00000 n 0000819122 00000 n 0000819249 00000 n 0000823510 00000 n 0000822804 00000 n 0000819430 00000 n 0000822930 00000 n 0001108054 00000 n 0001098841 00000 n 0001107868 00000 n 0000823059 00000 n 0000823188 00000 n 0000823316 00000 n 0001313024 00000 n 0000824558 00000 n 0000824367 00000 n 0000823739 00000 n 0000824493 00000 n 0000824987 00000 n 0000824796 00000 n 0000824646 00000 n 0000824922 00000 n 0000828360 00000 n 0000827134 00000 n 0000825029 00000 n 0000827651 00000 n 0000827780 00000 n 0000827909 00000 n 0000828038 00000 n 0000828167 00000 n 0000828296 00000 n 0000827290 00000 n 0000827462 00000 n 0000828817 00000 n 0000828626 00000 n 0000828476 00000 n 0000828752 00000 n 0000831901 00000 n 0000830868 00000 n 0000828859 00000 n 0000831196 00000 n 0000831325 00000 n 0000831450 00000 n 0000831579 00000 n 0000831707 00000 n 0000831015 00000 n 0000831836 00000 n 0000834807 00000 n 0000833556 00000 n 0000832031 00000 n 0000834097 00000 n 0000834226 00000 n 0000834355 00000 n 0000834484 00000 n 0000834613 00000 n 0000833712 00000 n 0000834742 00000 n 0000833919 00000 n 0001313149 00000 n 0000838161 00000 n 0000837712 00000 n 0000834951 00000 n 0000837838 00000 n 0000837967 00000 n 0000838096 00000 n 0000839052 00000 n 0000838861 00000 n 0000838249 00000 n 0000838987 00000 n 0000842776 00000 n 0000841686 00000 n 0000839140 00000 n 0000842195 00000 n 0000842324 00000 n 0000842582 00000 n 0000841842 00000 n 0000842021 00000 n 0000849576 00000 n 0000845756 00000 n 0000842920 00000 n 0000845882 00000 n 0000845947 00000 n 0000846012 00000 n 0000846077 00000 n 0000846142 00000 n 0000846207 00000 n 0000846272 00000 n 0000846337 00000 n 0000846402 00000 n 0000846466 00000 n 0000846531 00000 n 0000846596 00000 n 0000846724 00000 n 0000846788 00000 n 0000846853 00000 n 0000846917 00000 n 0000846982 00000 n 0000847045 00000 n 0000847110 00000 n 0000847175 00000 n 0000847240 00000 n 0000847304 00000 n 0000847369 00000 n 0000847434 00000 n 0000847499 00000 n 0000847564 00000 n 0000847629 00000 n 0000847694 00000 n 0000847759 00000 n 0000847824 00000 n 0000847889 00000 n 0000847954 00000 n 0000848019 00000 n 0000848084 00000 n 0000848149 00000 n 0000848214 00000 n 0000848279 00000 n 0000848344 00000 n 0000848409 00000 n 0000848474 00000 n 0000848539 00000 n 0000848604 00000 n 0000848669 00000 n 0000848734 00000 n 0000848799 00000 n 0000848864 00000 n 0000848929 00000 n 0000848994 00000 n 0000849058 00000 n 0000849123 00000 n 0000849188 00000 n 0000849253 00000 n 0000849318 00000 n 0000849383 00000 n 0000849448 00000 n 0000849512 00000 n 0000856546 00000 n 0000852853 00000 n 0000849692 00000 n 0000852979 00000 n 0000853044 00000 n 0000853109 00000 n 0000853174 00000 n 0000853239 00000 n 0000853304 00000 n 0000853369 00000 n 0000853434 00000 n 0000853499 00000 n 0000853564 00000 n 0000853629 00000 n 0000853694 00000 n 0000853759 00000 n 0000853824 00000 n 0000853889 00000 n 0000853954 00000 n 0000854019 00000 n 0000854084 00000 n 0000854149 00000 n 0000854213 00000 n 0000854278 00000 n 0000854343 00000 n 0000854406 00000 n 0000854471 00000 n 0000854536 00000 n 0000854600 00000 n 0000854665 00000 n 0000854730 00000 n 0000854795 00000 n 0000854860 00000 n 0000854925 00000 n 0000854990 00000 n 0000855055 00000 n 0000855120 00000 n 0000855185 00000 n 0000855249 00000 n 0000855314 00000 n 0000855379 00000 n 0000855444 00000 n 0000855509 00000 n 0000855574 00000 n 0000855639 00000 n 0000855704 00000 n 0000855769 00000 n 0000855834 00000 n 0000855899 00000 n 0000855964 00000 n 0000856029 00000 n 0000856094 00000 n 0000856159 00000 n 0000856224 00000 n 0000856289 00000 n 0000856354 00000 n 0000856418 00000 n 0000856482 00000 n 0000862767 00000 n 0000859329 00000 n 0000856662 00000 n 0000859455 00000 n 0000859520 00000 n 0000859585 00000 n 0000859650 00000 n 0000859715 00000 n 0000859780 00000 n 0000859845 00000 n 0000859910 00000 n 0000859975 00000 n 0000860040 00000 n 0000860105 00000 n 0000860170 00000 n 0000860235 00000 n 0000860300 00000 n 0000860365 00000 n 0000860430 00000 n 0000860495 00000 n 0000860560 00000 n 0000860625 00000 n 0000860690 00000 n 0000860755 00000 n 0000860820 00000 n 0000860885 00000 n 0000860950 00000 n 0000861015 00000 n 0000861080 00000 n 0000861145 00000 n 0000861210 00000 n 0000861275 00000 n 0000861340 00000 n 0000861405 00000 n 0000861470 00000 n 0000861535 00000 n 0000861600 00000 n 0000861664 00000 n 0000861729 00000 n 0000861794 00000 n 0000861859 00000 n 0000861924 00000 n 0000861989 00000 n 0000862054 00000 n 0000862119 00000 n 0000862184 00000 n 0000862249 00000 n 0000862314 00000 n 0000862379 00000 n 0000862444 00000 n 0000862509 00000 n 0000862574 00000 n 0000862639 00000 n 0000862703 00000 n 0001313274 00000 n 0000867399 00000 n 0000865135 00000 n 0000862883 00000 n 0000865261 00000 n 0000865326 00000 n 0000865391 00000 n 0000865456 00000 n 0000865521 00000 n 0000865586 00000 n 0000865651 00000 n 0000865716 00000 n 0000865781 00000 n 0000865846 00000 n 0000865911 00000 n 0000865976 00000 n 0000866041 00000 n 0000866106 00000 n 0000866168 00000 n 0000866232 00000 n 0000866297 00000 n 0000866361 00000 n 0000866426 00000 n 0000866491 00000 n 0000866556 00000 n 0000866621 00000 n 0000866686 00000 n 0000866751 00000 n 0000866816 00000 n 0000866945 00000 n 0000867074 00000 n 0000867139 00000 n 0000867204 00000 n 0000867269 00000 n 0000867334 00000 n 0000867870 00000 n 0000867679 00000 n 0000867529 00000 n 0000867805 00000 n 0000870859 00000 n 0000870153 00000 n 0000867912 00000 n 0000870279 00000 n 0000870408 00000 n 0000870537 00000 n 0000870665 00000 n 0000870794 00000 n 0000874519 00000 n 0000873635 00000 n 0000870975 00000 n 0000873942 00000 n 0000874071 00000 n 0000874200 00000 n 0000874327 00000 n 0000873782 00000 n 0000874455 00000 n 0000877349 00000 n 0000876901 00000 n 0000874649 00000 n 0000877027 00000 n 0000877156 00000 n 0000877285 00000 n 0000880803 00000 n 0000880226 00000 n 0000877465 00000 n 0000880352 00000 n 0000880481 00000 n 0000880609 00000 n 0000880738 00000 n 0001313399 00000 n 0000883781 00000 n 0000883461 00000 n 0000880919 00000 n 0000883587 00000 n 0000883716 00000 n 0000884846 00000 n 0000884526 00000 n 0000883940 00000 n 0000884652 00000 n 0000884781 00000 n 0000887763 00000 n 0000887119 00000 n 0000884948 00000 n 0000887245 00000 n 0000887374 00000 n 0000887503 00000 n 0000887568 00000 n 0000887633 00000 n 0000887698 00000 n 0000891332 00000 n 0000891011 00000 n 0000887879 00000 n 0000891137 00000 n 0000891202 00000 n 0000891267 00000 n 0000895470 00000 n 0000895214 00000 n 0000891504 00000 n 0000895340 00000 n 0000895405 00000 n 0000898872 00000 n 0000898681 00000 n 0000895628 00000 n 0000898807 00000 n 0001313524 00000 n 0000902406 00000 n 0000902215 00000 n 0000899016 00000 n 0000902341 00000 n 0000906089 00000 n 0000905898 00000 n 0000902550 00000 n 0000906024 00000 n 0000909657 00000 n 0000909208 00000 n 0000906233 00000 n 0000909334 00000 n 0000909399 00000 n 0000909464 00000 n 0000909528 00000 n 0000909593 00000 n 0000913695 00000 n 0000913115 00000 n 0000909815 00000 n 0000913241 00000 n 0000913306 00000 n 0000913435 00000 n 0000913500 00000 n 0000913565 00000 n 0000913630 00000 n 0000917505 00000 n 0000916862 00000 n 0000913825 00000 n 0000916988 00000 n 0000917053 00000 n 0000917118 00000 n 0000917183 00000 n 0000917312 00000 n 0000917375 00000 n 0000917440 00000 n 0000920968 00000 n 0000920584 00000 n 0000917649 00000 n 0000920710 00000 n 0000920775 00000 n 0000920840 00000 n 0000920905 00000 n 0001313649 00000 n 0000925251 00000 n 0000925060 00000 n 0000921126 00000 n 0000925186 00000 n 0000928683 00000 n 0000928427 00000 n 0000925423 00000 n 0000928553 00000 n 0000928618 00000 n 0000932034 00000 n 0000931714 00000 n 0000928813 00000 n 0000931840 00000 n 0000931905 00000 n 0000931970 00000 n 0000934698 00000 n 0000933797 00000 n 0000932192 00000 n 0000933923 00000 n 0000934052 00000 n 0000934117 00000 n 0000934182 00000 n 0000934247 00000 n 0000934310 00000 n 0000934375 00000 n 0000934440 00000 n 0000934569 00000 n 0000934634 00000 n 0000938499 00000 n 0000938113 00000 n 0000934842 00000 n 0000938239 00000 n 0000938304 00000 n 0000938369 00000 n 0000938434 00000 n 0000941490 00000 n 0000940846 00000 n 0000938643 00000 n 0000940972 00000 n 0000941037 00000 n 0000941102 00000 n 0000941231 00000 n 0000941296 00000 n 0000941361 00000 n 0000941426 00000 n 0001313774 00000 n 0000944566 00000 n 0000944245 00000 n 0000941634 00000 n 0000944371 00000 n 0000944436 00000 n 0000944501 00000 n 0000947423 00000 n 0000946651 00000 n 0000944710 00000 n 0000946777 00000 n 0000946842 00000 n 0000946907 00000 n 0000946970 00000 n 0000947035 00000 n 0000947163 00000 n 0000947228 00000 n 0000947293 00000 n 0000947358 00000 n 0000950616 00000 n 0000950102 00000 n 0000947567 00000 n 0000950228 00000 n 0000950293 00000 n 0000950357 00000 n 0000950422 00000 n 0000950487 00000 n 0000950552 00000 n 0000954020 00000 n 0000953440 00000 n 0000950760 00000 n 0000953566 00000 n 0000953760 00000 n 0000953825 00000 n 0000953890 00000 n 0000953955 00000 n 0000957846 00000 n 0000957655 00000 n 0000954164 00000 n 0000957781 00000 n 0000961417 00000 n 0000961096 00000 n 0000957990 00000 n 0000961222 00000 n 0000961287 00000 n 0000961352 00000 n 0001313899 00000 n 0000964644 00000 n 0000963935 00000 n 0000961561 00000 n 0000964061 00000 n 0000964126 00000 n 0000964191 00000 n 0000964385 00000 n 0000964450 00000 n 0000964515 00000 n 0000964579 00000 n 0000968474 00000 n 0000968283 00000 n 0000964816 00000 n 0000968409 00000 n 0000971954 00000 n 0000971763 00000 n 0000968604 00000 n 0000971889 00000 n 0000975691 00000 n 0000975370 00000 n 0000972084 00000 n 0000975496 00000 n 0000975561 00000 n 0000975626 00000 n 0000978370 00000 n 0000977596 00000 n 0000975835 00000 n 0000977722 00000 n 0000977787 00000 n 0000977852 00000 n 0000977917 00000 n 0000978046 00000 n 0000978111 00000 n 0000978176 00000 n 0000978241 00000 n 0000978306 00000 n 0000981534 00000 n 0000980890 00000 n 0000978542 00000 n 0000981016 00000 n 0000981081 00000 n 0000981146 00000 n 0000981339 00000 n 0000981404 00000 n 0000981469 00000 n 0001314024 00000 n 0000985116 00000 n 0000984795 00000 n 0000981692 00000 n 0000984921 00000 n 0000984986 00000 n 0000985051 00000 n 0000988473 00000 n 0000987828 00000 n 0000985246 00000 n 0000987954 00000 n 0000988019 00000 n 0000988084 00000 n 0000988149 00000 n 0000988278 00000 n 0000988343 00000 n 0000988408 00000 n 0000992257 00000 n 0000991936 00000 n 0000988631 00000 n 0000992062 00000 n 0000992127 00000 n 0000992192 00000 n 0000996400 00000 n 0000996209 00000 n 0000992401 00000 n 0000996335 00000 n 0001000090 00000 n 0000999899 00000 n 0000996530 00000 n 0001000025 00000 n 0001003640 00000 n 0001003449 00000 n 0001000220 00000 n 0001003575 00000 n 0001314149 00000 n 0001006454 00000 n 0001005876 00000 n 0001003784 00000 n 0001006002 00000 n 0001006067 00000 n 0001006131 00000 n 0001006196 00000 n 0001006325 00000 n 0001006390 00000 n 0001009857 00000 n 0001009407 00000 n 0001006612 00000 n 0001009533 00000 n 0001009598 00000 n 0001009663 00000 n 0001009728 00000 n 0001009793 00000 n 0001012999 00000 n 0001012354 00000 n 0001010015 00000 n 0001012480 00000 n 0001012545 00000 n 0001012674 00000 n 0001012739 00000 n 0001012804 00000 n 0001012869 00000 n 0001012934 00000 n 0001015902 00000 n 0001015127 00000 n 0001013143 00000 n 0001015253 00000 n 0001015318 00000 n 0001015383 00000 n 0001015448 00000 n 0001015577 00000 n 0001015642 00000 n 0001015707 00000 n 0001015772 00000 n 0001015837 00000 n 0001019548 00000 n 0001019357 00000 n 0001016046 00000 n 0001019483 00000 n 0001022887 00000 n 0001022502 00000 n 0001019678 00000 n 0001022628 00000 n 0001022693 00000 n 0001022758 00000 n 0001022823 00000 n 0001314274 00000 n 0001026189 00000 n 0001025610 00000 n 0001023031 00000 n 0001025736 00000 n 0001025865 00000 n 0001025930 00000 n 0001025995 00000 n 0001026060 00000 n 0001026124 00000 n 0001029628 00000 n 0001029437 00000 n 0001026333 00000 n 0001029563 00000 n 0001032826 00000 n 0001032506 00000 n 0001029843 00000 n 0001032632 00000 n 0001032697 00000 n 0001032762 00000 n 0001035715 00000 n 0001034942 00000 n 0001033055 00000 n 0001035068 00000 n 0001035133 00000 n 0001035198 00000 n 0001035262 00000 n 0001035391 00000 n 0001035456 00000 n 0001035521 00000 n 0001035586 00000 n 0001035651 00000 n 0001038224 00000 n 0001037322 00000 n 0001035873 00000 n 0001037448 00000 n 0001037513 00000 n 0001037642 00000 n 0001037707 00000 n 0001037772 00000 n 0001037837 00000 n 0001037902 00000 n 0001038029 00000 n 0001038094 00000 n 0001038159 00000 n 0001042105 00000 n 0001041785 00000 n 0001038368 00000 n 0001041911 00000 n 0001041976 00000 n 0001042040 00000 n 0001314399 00000 n 0001046034 00000 n 0001045778 00000 n 0001042235 00000 n 0001045904 00000 n 0001045969 00000 n 0001049939 00000 n 0001049748 00000 n 0001046192 00000 n 0001049874 00000 n 0001052573 00000 n 0001052252 00000 n 0001050069 00000 n 0001052378 00000 n 0001052443 00000 n 0001052508 00000 n 0001055864 00000 n 0001055156 00000 n 0001052717 00000 n 0001055282 00000 n 0001055347 00000 n 0001055411 00000 n 0001055605 00000 n 0001055670 00000 n 0001055735 00000 n 0001055799 00000 n 0001059718 00000 n 0001059462 00000 n 0001056050 00000 n 0001059588 00000 n 0001059653 00000 n 0001063458 00000 n 0001063267 00000 n 0001059876 00000 n 0001063393 00000 n 0001314524 00000 n 0001067570 00000 n 0001067379 00000 n 0001063616 00000 n 0001067505 00000 n 0001071226 00000 n 0001070970 00000 n 0001067714 00000 n 0001071096 00000 n 0001071161 00000 n 0001074773 00000 n 0001074128 00000 n 0001071370 00000 n 0001074254 00000 n 0001074319 00000 n 0001074384 00000 n 0001074513 00000 n 0001074578 00000 n 0001074643 00000 n 0001074708 00000 n 0001077187 00000 n 0001076931 00000 n 0001074931 00000 n 0001077057 00000 n 0001077122 00000 n 0001080638 00000 n 0001079864 00000 n 0001077331 00000 n 0001079990 00000 n 0001080055 00000 n 0001080120 00000 n 0001080185 00000 n 0001080315 00000 n 0001080380 00000 n 0001080445 00000 n 0001080510 00000 n 0001080575 00000 n 0001083663 00000 n 0001083278 00000 n 0001080796 00000 n 0001083404 00000 n 0001083469 00000 n 0001083534 00000 n 0001083599 00000 n 0001314649 00000 n 0001087418 00000 n 0001086837 00000 n 0001083821 00000 n 0001086963 00000 n 0001087093 00000 n 0001087158 00000 n 0001087223 00000 n 0001087288 00000 n 0001087353 00000 n 0001089950 00000 n 0001089175 00000 n 0001087562 00000 n 0001089301 00000 n 0001089366 00000 n 0001089431 00000 n 0001089561 00000 n 0001089626 00000 n 0001089691 00000 n 0001089756 00000 n 0001089821 00000 n 0001089886 00000 n 0001092360 00000 n 0001091392 00000 n 0001090108 00000 n 0001091518 00000 n 0001091648 00000 n 0001091713 00000 n 0001091778 00000 n 0001091843 00000 n 0001091908 00000 n 0001091973 00000 n 0001092037 00000 n 0001092166 00000 n 0001092231 00000 n 0001092296 00000 n 0001095365 00000 n 0001094527 00000 n 0001092504 00000 n 0001094653 00000 n 0001094718 00000 n 0001094783 00000 n 0001094847 00000 n 0001094912 00000 n 0001095042 00000 n 0001095107 00000 n 0001095172 00000 n 0001095236 00000 n 0001095301 00000 n 0001096734 00000 n 0001096414 00000 n 0001095509 00000 n 0001096540 00000 n 0001096605 00000 n 0001096669 00000 n 0001096952 00000 n 0001108296 00000 n 0001115884 00000 n 0001118183 00000 n 0001118152 00000 n 0001121870 00000 n 0001135012 00000 n 0001144740 00000 n 0001155568 00000 n 0001169814 00000 n 0001189850 00000 n 0001210922 00000 n 0001233233 00000 n 0001251491 00000 n 0001254343 00000 n 0001254113 00000 n 0001282130 00000 n 0001309651 00000 n 0001314774 00000 n 0001314900 00000 n 0001315026 00000 n 0001315152 00000 n 0001315278 00000 n 0001315404 00000 n 0001315530 00000 n 0001315610 00000 n 0001315737 00000 n 0001315817 00000 n 0001315891 00000 n 0001340092 00000 n 0001367355 00000 n 0001367396 00000 n 0001367436 00000 n 0001367571 00000 n trailer << /Size 3145 /Root 3143 0 R /Info 3144 0 R /ID [<45D16F473C46F0E35F950E8B39C6FBFB> <45D16F473C46F0E35F950E8B39C6FBFB>] >> startxref 1367829 %%EOF bind9-9.10.3.dfsg.P4/doc/arm/dnssec.xml0000644000470500017500000003260612664710322016725 0ustar lamontlamont DNSSEC, Dynamic Zones, and Automatic Signing As of BIND 9.7.0 it is possible to change a dynamic zone from insecure to signed and back again. A secure zone can use either NSEC or NSEC3 chains. Converting from insecure to secure Changing a zone from insecure to secure can be done in two ways: using a dynamic DNS update, or the auto-dnssec zone option. For either method, you need to configure named so that it can see the K* files which contain the public and private parts of the keys that will be used to sign the zone. These files will have been generated by dnssec-keygen. You can do this by placing them in the key-directory, as specified in named.conf: zone example.net { type master; update-policy local; file "dynamic/example.net/example.net"; key-directory "dynamic/example.net"; }; If one KSK and one ZSK DNSKEY key have been generated, this configuration will cause all records in the zone to be signed with the ZSK, and the DNSKEY RRset to be signed with the KSK as well. An NSEC chain will be generated as part of the initial signing process. Dynamic DNS update method To insert the keys via dynamic update: % nsupdate > ttl 3600 > update add example.net DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8= > update add example.net DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk= > send While the update request will complete almost immediately, the zone will not be completely signed until named has had time to walk the zone and generate the NSEC and RRSIG records. The NSEC record at the apex will be added last, to signal that there is a complete NSEC chain. If you wish to sign using NSEC3 instead of NSEC, you should add an NSEC3PARAM record to the initial update request. If you wish the NSEC3 chain to have the OPTOUT bit set, set it in the flags field of the NSEC3PARAM record. % nsupdate > ttl 3600 > update add example.net DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8= > update add example.net DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk= > update add example.net NSEC3PARAM 1 1 100 1234567890 > send Again, this update request will complete almost immediately; however, the record won't show up until named has had a chance to build/remove the relevant chain. A private type record will be created to record the state of the operation (see below for more details), and will be removed once the operation completes. While the initial signing and NSEC/NSEC3 chain generation is happening, other updates are possible as well. Fully automatic zone signing To enable automatic signing, add the auto-dnssec option to the zone statement in named.conf. auto-dnssec has two possible arguments: allow or maintain. With auto-dnssec allow, named can search the key directory for keys matching the zone, insert them into the zone, and use them to sign the zone. It will do so only when it receives an rndc sign <zonename>. auto-dnssec maintain includes the above functionality, but will also automatically adjust the zone's DNSKEY records on schedule according to the keys' timing metadata. (See and for more information.) named will periodically search the key directory for keys matching the zone, and if the keys' metadata indicates that any change should be made the zone, such as adding, removing, or revoking a key, then that action will be carried out. By default, the key directory is checked for changes every 60 minutes; this period can be adjusted with the , up to a maximum of 24 hours. The rndc loadkeys forces named to check for key updates immediately. If keys are present in the key directory the first time the zone is loaded, the zone will be signed immediately, without waiting for an rndc sign or rndc loadkeys command. (Those commands can still be used when there are unscheduled key changes, however.) When new keys are added to a zone, the TTL is set to match that of any existing DNSKEY RRset. If there is no existing DNSKEY RRset, then the TTL will be set to the TTL specified when the key was created (using the dnssec-keygen -L option), if any, or to the SOA TTL. If you wish the zone to be signed using NSEC3 instead of NSEC, submit an NSEC3PARAM record via dynamic update prior to the scheduled publication and activation of the keys. If you wish the NSEC3 chain to have the OPTOUT bit set, set it in the flags field of the NSEC3PARAM record. The NSEC3PARAM record will not appear in the zone immediately, but it will be stored for later reference. When the zone is signed and the NSEC3 chain is completed, the NSEC3PARAM record will appear in the zone. Using the auto-dnssec option requires the zone to be configured to allow dynamic updates, by adding an allow-update or update-policy statement to the zone configuration. If this has not been done, the configuration will fail. Private-type records The state of the signing process is signaled by private-type records (with a default type value of 65534). When signing is complete, these records will have a nonzero value for the final octet (for those records which have a nonzero initial octet). The private type record format: If the first octet is non-zero then the record indicates that the zone needs to be signed with the key matching the record, or that all signatures that match the record should be removed. algorithm (octet 1) key id in network order (octet 2 and 3) removal flag (octet 4) complete flag (octet 5) Only records flagged as "complete" can be removed via dynamic update. Attempts to remove other private type records will be silently ignored. If the first octet is zero (this is a reserved algorithm number that should never appear in a DNSKEY record) then the record indicates changes to the NSEC3 chains are in progress. The rest of the record contains an NSEC3PARAM record. The flag field tells what operation to perform based on the flag bits. 0x01 OPTOUT 0x80 CREATE 0x40 REMOVE 0x20 NONSEC DNSKEY rollovers As with insecure-to-secure conversions, rolling DNSSEC keys can be done in two ways: using a dynamic DNS update, or the auto-dnssec zone option. Dynamic DNS update method To perform key rollovers via dynamic update, you need to add the K* files for the new keys so that named can find them. You can then add the new DNSKEY RRs via dynamic update. named will then cause the zone to be signed with the new keys. When the signing is complete the private type records will be updated so that the last octet is non zero. If this is for a KSK you need to inform the parent and any trust anchor repositories of the new KSK. You should then wait for the maximum TTL in the zone before removing the old DNSKEY. If it is a KSK that is being updated, you also need to wait for the DS RRset in the parent to be updated and its TTL to expire. This ensures that all clients will be able to verify at least one signature when you remove the old DNSKEY. The old DNSKEY can be removed via UPDATE. Take care to specify the correct key. named will clean out any signatures generated by the old key after the update completes. Automatic key rollovers When a new key reaches its activation date (as set by dnssec-keygen or dnssec-settime), if the auto-dnssec zone option is set to maintain, named will automatically carry out the key rollover. If the key's algorithm has not previously been used to sign the zone, then the zone will be fully signed as quickly as possible. However, if the new key is replacing an existing key of the same algorithm, then the zone will be re-signed incrementally, with signatures from the old key being replaced with signatures from the new key as their signature validity periods expire. By default, this rollover completes in 30 days, after which it will be safe to remove the old key from the DNSKEY RRset. NSEC3PARAM rollovers via UPDATE Add the new NSEC3PARAM record via dynamic update. When the new NSEC3 chain has been generated, the NSEC3PARAM flag field will be zero. At this point you can remove the old NSEC3PARAM record. The old chain will be removed after the update request completes. Converting from NSEC to NSEC3 To do this, you just need to add an NSEC3PARAM record. When the conversion is complete, the NSEC chain will have been removed and the NSEC3PARAM record will have a zero flag field. The NSEC3 chain will be generated before the NSEC chain is destroyed. Converting from NSEC3 to NSEC To do this, use nsupdate to remove all NSEC3PARAM records with a zero flag field. The NSEC chain will be generated before the NSEC3 chain is removed. Converting from secure to insecure To convert a signed zone to unsigned using dynamic DNS, delete all the DNSKEY records from the zone apex using nsupdate. All signatures, NSEC or NSEC3 chains, and associated NSEC3PARAM records will be removed automatically. This will take place after the update request completes. This requires the dnssec-secure-to-insecure option to be set to yes in named.conf. In addition, if the auto-dnssec maintain zone statement is used, it should be removed or changed to allow instead (or it will re-sign). Periodic re-signing In any secure zone which supports dynamic updates, named will periodically re-sign RRsets which have not been re-signed as a result of some update action. The signature lifetimes will be adjusted so as to spread the re-sign load over time rather than all at once. NSEC3 and OPTOUT named only supports creating new NSEC3 chains where all the NSEC3 records in the zone have the same OPTOUT state. named supports UPDATES to zones where the NSEC3 records in the chain have mixed OPTOUT state. named does not support changing the OPTOUT state of an individual NSEC3 record, the entire chain needs to be changed if the OPTOUT state of an individual NSEC3 needs to be changed. bind9-9.10.3.dfsg.P4/doc/arm/Bv9ARM.ch06.html0000644000470500017500000230274512664710322017357 0ustar lamontlamont Chapter 6. BIND 9 Configuration Reference

Chapter 6. BIND 9 Configuration Reference

BIND 9 configuration is broadly similar to BIND 8; however, there are a few new areas of configuration, such as views. BIND 8 configuration files should work with few alterations in BIND 9, although more complex configurations should be reviewed to check if they can be more efficiently implemented using the new features found in BIND 9.

BIND 4 configuration files can be converted to the new format using the shell script contrib/named-bootconf/named-bootconf.sh.

Configuration File Elements

Following is a list of elements used throughout the BIND configuration file documentation:

acl_name

The name of an address_match_list as defined by the acl statement.

address_match_list

A list of one or more ip_addr, ip_prefix, key_id, or acl_name elements, see the section called “Address Match Lists”.

masters_list

A named list of one or more ip_addr with optional key_id and/or ip_port. A masters_list may include other masters_lists.

domain_name

A quoted string which will be used as a DNS name, for example "my.test.domain".

namelist

A list of one or more domain_name elements.

dotted_decimal

One to four integers valued 0 through 255 separated by dots (`.'), such as 123, 45.67 or 89.123.45.67.

ip4_addr

An IPv4 address with exactly four elements in dotted_decimal notation.

ip6_addr

An IPv6 address, such as 2001:db8::1234. IPv6 scoped addresses that have ambiguity on their scope zones must be disambiguated by an appropriate zone ID with the percent character (`%') as delimiter. It is strongly recommended to use string zone names rather than numeric identifiers, in order to be robust against system configuration changes. However, since there is no standard mapping for such names and identifier values, currently only interface names as link identifiers are supported, assuming one-to-one mapping between interfaces and links. For example, a link-local address fe80::1 on the link attached to the interface ne0 can be specified as fe80::1%ne0. Note that on most systems link-local addresses always have the ambiguity, and need to be disambiguated.

ip_addr

An ip4_addr or ip6_addr.

ip_dscp

A number between 0 and 63, used to select a differentiated services code point (DSCP) value for use with outgoing traffic on operating systems that support DSCP.

ip_port

An IP port number. The number is limited to 0 through 65535, with values below 1024 typically restricted to use by processes running as root. In some cases, an asterisk (`*') character can be used as a placeholder to select a random high-numbered port.

ip_prefix

An IP network specified as an ip_addr, followed by a slash (`/') and then the number of bits in the netmask. Trailing zeros in a ip_addr may omitted. For example, 127/8 is the network 127.0.0.0 with netmask 255.0.0.0 and 1.2.3.0/28 is network 1.2.3.0 with netmask 255.255.255.240.

When specifying a prefix involving a IPv6 scoped address the scope may be omitted. In that case the prefix will match packets from any scope.

key_id

A domain_name representing the name of a shared key, to be used for transaction security.

key_list

A list of one or more key_ids, separated by semicolons and ending with a semicolon.

number

A non-negative 32-bit integer (i.e., a number between 0 and 4294967295, inclusive). Its acceptable value might further be limited by the context in which it is used.

path_name

A quoted string which will be used as a pathname, such as zones/master/my.test.domain.

port_list

A list of an ip_port or a port range. A port range is specified in the form of range followed by two ip_ports, port_low and port_high, which represents port numbers from port_low through port_high, inclusive. port_low must not be larger than port_high. For example, range 1024 65535 represents ports from 1024 through 65535. In either case an asterisk (`*') character is not allowed as a valid ip_port.

size_spec

A 64-bit unsigned integer, or the keywords unlimited or default.

Integers may take values 0 <= value <= 18446744073709551615, though certain parameters (such as max-journal-size) may use a more limited range within these extremes. In most cases, setting a value to 0 does not literally mean zero; it means "undefined" or "as big as possible", depending on the context. See the explanations of particular parameters that use size_spec for details on how they interpret its use.

Numeric values can optionally be followed by a scaling factor: K or k for kilobytes, M or m for megabytes, and G or g for gigabytes, which scale by 1024, 1024*1024, and 1024*1024*1024 respectively.

unlimited generally means "as big as possible", and is usually the best way to safely set a very large number.

default uses the limit that was in force when the server was started.

yes_or_no

Either yes or no. The words true and false are also accepted, as are the numbers 1 and 0.

dialup_option

One of yes, no, notify, notify-passive, refresh or passive. When used in a zone, notify-passive, refresh, and passive are restricted to slave and stub zones.

Address Match Lists

Syntax

address_match_list = address_match_list_element ;
  [ address_match_list_element; ... ]
address_match_list_element = [ ! ] (ip_address [/length] |
   key key_id | acl_name | { address_match_list } )

Definition and Usage

Address match lists are primarily used to determine access control for various server operations. They are also used in the listen-on and sortlist statements. The elements which constitute an address match list can be any of the following:

  • an IP address (IPv4 or IPv6)
  • an IP prefix (in `/' notation)
  • a key ID, as defined by the key statement
  • the name of an address match list defined with the acl statement
  • a nested address match list enclosed in braces

Elements can be negated with a leading exclamation mark (`!'), and the match list names "any", "none", "localhost", and "localnets" are predefined. More information on those names can be found in the description of the acl statement.

The addition of the key clause made the name of this syntactic element something of a misnomer, since security keys can be used to validate access without regard to a host or network address. Nonetheless, the term "address match list" is still used throughout the documentation.

When a given IP address or prefix is compared to an address match list, the comparison takes place in approximately O(1) time. However, key comparisons require that the list of keys be traversed until a matching key is found, and therefore may be somewhat slower.

The interpretation of a match depends on whether the list is being used for access control, defining listen-on ports, or in a sortlist, and whether the element was negated.

When used as an access control list, a non-negated match allows access and a negated match denies access. If there is no match, access is denied. The clauses allow-notify, allow-recursion, allow-recursion-on, allow-query, allow-query-on, allow-query-cache, allow-query-cache-on, allow-transfer, allow-update, allow-update-forwarding, and blackhole all use address match lists. Similarly, the listen-on option will cause the server to refuse queries on any of the machine's addresses which do not match the list.

Order of insertion is significant. If more than one element in an ACL is found to match a given IP address or prefix, preference will be given to the one that came first in the ACL definition. Because of this first-match behavior, an element that defines a subset of another element in the list should come before the broader element, regardless of whether either is negated. For example, in 1.2.3/24; ! 1.2.3.13; the 1.2.3.13 element is completely useless because the algorithm will match any lookup for 1.2.3.13 to the 1.2.3/24 element. Using ! 1.2.3.13; 1.2.3/24 fixes that problem by having 1.2.3.13 blocked by the negation, but all other 1.2.3.* hosts fall through.

Comment Syntax

The BIND 9 comment syntax allows for comments to appear anywhere that whitespace may appear in a BIND configuration file. To appeal to programmers of all kinds, they can be written in the C, C++, or shell/perl style.

Syntax

/* This is a BIND comment as in C */

// This is a BIND comment as in C++

# This is a BIND comment as in common UNIX shells
# and perl

Definition and Usage

Comments may appear anywhere that whitespace may appear in a BIND configuration file.

C-style comments start with the two characters /* (slash, star) and end with */ (star, slash). Because they are completely delimited with these characters, they can be used to comment only a portion of a line or to span multiple lines.

C-style comments cannot be nested. For example, the following is not valid because the entire comment ends with the first */:

/* This is the start of a comment.
   This is still part of the comment.
/* This is an incorrect attempt at nesting a comment. */
   This is no longer in any comment. */

C++-style comments start with the two characters // (slash, slash) and continue to the end of the physical line. They cannot be continued across multiple physical lines; to have one logical comment span multiple lines, each line must use the // pair. For example:

// This is the start of a comment.  The next line
// is a new comment, even though it is logically
// part of the previous comment.

Shell-style (or perl-style, if you prefer) comments start with the character # (number sign) and continue to the end of the physical line, as in C++ comments. For example:

# This is the start of a comment.  The next line
# is a new comment, even though it is logically
# part of the previous comment.

Warning

You cannot use the semicolon (`;') character to start a comment such as you would in a zone file. The semicolon indicates the end of a configuration statement.

Configuration File Grammar

A BIND 9 configuration consists of statements and comments. Statements end with a semicolon. Statements and comments are the only elements that can appear without enclosing braces. Many statements contain a block of sub-statements, which are also terminated with a semicolon.

The following statements are supported:

acl

defines a named IP address matching list, for access control and other uses.

controls

declares control channels to be used by the rndc utility.

include

includes a file.

key

specifies key information for use in authentication and authorization using TSIG.

logging

specifies what the server logs, and where the log messages are sent.

lwres

configures named to also act as a light-weight resolver daemon (lwresd).

masters

defines a named masters list for inclusion in stub and slave zones' masters or also-notify lists.

options

controls global server configuration options and sets defaults for other statements.

server

sets certain configuration options on a per-server basis.

statistics-channels

declares communication channels to get access to named statistics.

trusted-keys

defines trusted DNSSEC keys.

managed-keys

lists DNSSEC keys to be kept up to date using RFC 5011 trust anchor maintenance.

view

defines a view.

zone

defines a zone.

The logging and options statements may only occur once per configuration.

acl Statement Grammar

acl acl-name {
    address_match_list
};

acl Statement Definition and Usage

The acl statement assigns a symbolic name to an address match list. It gets its name from a primary use of address match lists: Access Control Lists (ACLs).

The following ACLs are built-in:

any

Matches all hosts.

none

Matches no hosts.

localhost

Matches the IPv4 and IPv6 addresses of all network interfaces on the system. When addresses are added or removed, the localhost ACL element is updated to reflect the changes.

localnets

Matches any host on an IPv4 or IPv6 network for which the system has an interface. When addresses are added or removed, the localnets ACL element is updated to reflect the changes. Some systems do not provide a way to determine the prefix lengths of local IPv6 addresses. In such a case, localnets only matches the local IPv6 addresses, just like localhost.

When BIND 9 is built with GeoIP support, ACLs can also be used for geographic access restrictions. This is done by specifying an ACL element of the form: geoip [db database] field value

The field indicates which field to search for a match. Available fields are "country", "region", "city", "continent", "postal" (postal code), "metro" (metro code), "area" (area code), "tz" (timezone), "isp", "org", "asnum", "domain" and "netspeed".

value is the value to search for within the database. A string may be quoted if it contains spaces or other special characters. If this is an "asnum" search, then the leading "ASNNNN" string can be used, otherwise the full description must be used (e.g. "ASNNNN Example Company Name"). If this is a "country" search and the string is two characters long, then it must be a standard ISO-3166-1 two-letter country code, and if it is three characters long then it must be an ISO-3166-1 three-letter country code; otherwise it is the full name of the country. Similarly, if this is a "region" search and the string is two characters long, then it must be a standard two-letter state or province abbreviation; otherwise it is the full name of the state or province.

The database field indicates which GeoIP database to search for a match. In most cases this is unnecessary, because most search fields can only be found in a single database. However, searches for country can be answered from the "city", "region", or "country" databases, and searches for region (i.e., state or province) can be answered from the "city" or "region" databases. For these search types, specifying a database will force the query to be answered from that database and no other. If database is not specified, then these queries will be answered from the "city", database if it is installed, or the "region" database if it is installed, or the "country" database, in that order.

Some example GeoIP ACLs:

geoip country US;
geoip country JAP;
geoip db country country Canada;
geoip db region region WA;
geoip city "San Francisco";
geoip region Oklahoma;
geoip postal 95062;
geoip tz "America/Los_Angeles";
geoip org "Internet Systems Consortium";

controls Statement Grammar

controls {
   [ inet ( ip_addr | * ) [ port ip_port ]
                allow {  address_match_list  }
                keys { key_list }; ]
   [ inet ...; ]
   [ unix path perm number owner number group number
     keys { key_list }; ]
   [ unix ...; ]
};

controls Statement Definition and Usage

The controls statement declares control channels to be used by system administrators to control the operation of the name server. These control channels are used by the rndc utility to send commands to and retrieve non-DNS results from a name server.

An inet control channel is a TCP socket listening at the specified ip_port on the specified ip_addr, which can be an IPv4 or IPv6 address. An ip_addr of * (asterisk) is interpreted as the IPv4 wildcard address; connections will be accepted on any of the system's IPv4 addresses. To listen on the IPv6 wildcard address, use an ip_addr of ::. If you will only use rndc on the local host, using the loopback address (127.0.0.1 or ::1) is recommended for maximum security.

If no port is specified, port 953 is used. The asterisk "*" cannot be used for ip_port.

The ability to issue commands over the control channel is restricted by the allow and keys clauses. Connections to the control channel are permitted based on the address_match_list. This is for simple IP address based filtering only; any key_id elements of the address_match_list are ignored.

A unix control channel is a UNIX domain socket listening at the specified path in the file system. Access to the socket is specified by the perm, owner and group clauses. Note on some platforms (SunOS and Solaris) the permissions (perm) are applied to the parent directory as the permissions on the socket itself are ignored.

The primary authorization mechanism of the command channel is the key_list, which contains a list of key_ids. Each key_id in the key_list is authorized to execute commands over the control channel. See Remote Name Daemon Control application in the section called “Administrative Tools”) for information about configuring keys in rndc.

If no controls statement is present, named will set up a default control channel listening on the loopback address 127.0.0.1 and its IPv6 counterpart ::1. In this case, and also when the controls statement is present but does not have a keys clause, named will attempt to load the command channel key from the file rndc.key in /etc (or whatever sysconfdir was specified as when BIND was built). To create a rndc.key file, run rndc-confgen -a.

The rndc.key feature was created to ease the transition of systems from BIND 8, which did not have digital signatures on its command channel messages and thus did not have a keys clause. It makes it possible to use an existing BIND 8 configuration file in BIND 9 unchanged, and still have rndc work the same way ndc worked in BIND 8, simply by executing the command rndc-confgen -a after BIND 9 is installed.

Since the rndc.key feature is only intended to allow the backward-compatible usage of BIND 8 configuration files, this feature does not have a high degree of configurability. You cannot easily change the key name or the size of the secret, so you should make a rndc.conf with your own key if you wish to change those things. The rndc.key file also has its permissions set such that only the owner of the file (the user that named is running as) can access it. If you desire greater flexibility in allowing other users to access rndc commands, then you need to create a rndc.conf file and make it group readable by a group that contains the users who should have access.

To disable the command channel, use an empty controls statement: controls { };.

include Statement Grammar

include filename;

include Statement Definition and Usage

The include statement inserts the specified file at the point where the include statement is encountered. The include statement facilitates the administration of configuration files by permitting the reading or writing of some things but not others. For example, the statement could include private keys that are readable only by the name server.

key Statement Grammar

key key_id {
    algorithm algorithm_id;
    secret secret_string;
};

key Statement Definition and Usage

The key statement defines a shared secret key for use with TSIG (see the section called “TSIG”) or the command channel (see the section called “controls Statement Definition and Usage”).

The key statement can occur at the top level of the configuration file or inside a view statement. Keys defined in top-level key statements can be used in all views. Keys intended for use in a controls statement (see the section called “controls Statement Definition and Usage”) must be defined at the top level.

The key_id, also known as the key name, is a domain name uniquely identifying the key. It can be used in a server statement to cause requests sent to that server to be signed with this key, or in address match lists to verify that incoming requests have been signed with a key matching this name, algorithm, and secret.

The algorithm_id is a string that specifies a security/authentication algorithm. Named supports hmac-md5, hmac-sha1, hmac-sha224, hmac-sha256, hmac-sha384 and hmac-sha512 TSIG authentication. Truncated hashes are supported by appending the minimum number of required bits preceded by a dash, e.g. hmac-sha1-80. The secret_string is the secret to be used by the algorithm, and is treated as a base-64 encoded string.

logging Statement Grammar

logging {
   [ channel channel_name {
     ( file path_name
         [ versions ( number | unlimited ) ]
         [ size size_spec ]
       | syslog syslog_facility
       | stderr
       | null );
     [ severity (critical | error | warning | notice |
                 info | debug [ level ] | dynamic ); ]
     [ print-category yes or no; ]
     [ print-severity yes or no; ]
     [ print-time yes or no; ]
   }; ]
   [ category category_name {
     channel_name ; [ channel_name ; ... ]
   }; ]
   ...
};

logging Statement Definition and Usage

The logging statement configures a wide variety of logging options for the name server. Its channel phrase associates output methods, format options and severity levels with a name that can then be used with the category phrase to select how various classes of messages are logged.

Only one logging statement is used to define as many channels and categories as are wanted. If there is no logging statement, the logging configuration will be:

logging {
     category default { default_syslog; default_debug; };
     category unmatched { null; };
};

In BIND 9, the logging configuration is only established when the entire configuration file has been parsed. In BIND 8, it was established as soon as the logging statement was parsed. When the server is starting up, all logging messages regarding syntax errors in the configuration file go to the default channels, or to standard error if the "-g" option was specified.

The channel Phrase

All log output goes to one or more channels; you can make as many of them as you want.

Every channel definition must include a destination clause that says whether messages selected for the channel go to a file, to a particular syslog facility, to the standard error stream, or are discarded. It can optionally also limit the message severity level that will be accepted by the channel (the default is info), and whether to include a named-generated time stamp, the category name and/or severity level (the default is not to include any).

The null destination clause causes all messages sent to the channel to be discarded; in that case, other options for the channel are meaningless.

The file destination clause directs the channel to a disk file. It can include limitations both on how large the file is allowed to become, and how many versions of the file will be saved each time the file is opened.

If you use the versions log file option, then named will retain that many backup versions of the file by renaming them when opening. For example, if you choose to keep three old versions of the file lamers.log, then just before it is opened lamers.log.1 is renamed to lamers.log.2, lamers.log.0 is renamed to lamers.log.1, and lamers.log is renamed to lamers.log.0. You can say versions unlimited to not limit the number of versions. If a size option is associated with the log file, then renaming is only done when the file being opened exceeds the indicated size. No backup versions are kept by default; any existing log file is simply appended.

The size option for files is used to limit log growth. If the file ever exceeds the size, then named will stop writing to the file unless it has a versions option associated with it. If backup versions are kept, the files are rolled as described above and a new one begun. If there is no versions option, no more data will be written to the log until some out-of-band mechanism removes or truncates the log to less than the maximum size. The default behavior is not to limit the size of the file.

Example usage of the size and versions options:

channel an_example_channel {
    file "example.log" versions 3 size 20m;
    print-time yes;
    print-category yes;
};

The syslog destination clause directs the channel to the system log. Its argument is a syslog facility as described in the syslog man page. Known facilities are kern, user, mail, daemon, auth, syslog, lpr, news, uucp, cron, authpriv, ftp, local0, local1, local2, local3, local4, local5, local6 and local7, however not all facilities are supported on all operating systems. How syslog will handle messages sent to this facility is described in the syslog.conf man page. If you have a system which uses a very old version of syslog that only uses two arguments to the openlog() function, then this clause is silently ignored.

On Windows machines syslog messages are directed to the EventViewer.

The severity clause works like syslog's "priorities", except that they can also be used if you are writing straight to a file rather than using syslog. Messages which are not at least of the severity level given will not be selected for the channel; messages of higher severity levels will be accepted.

If you are using syslog, then the syslog.conf priorities will also determine what eventually passes through. For example, defining a channel facility and severity as daemon and debug but only logging daemon.warning via syslog.conf will cause messages of severity info and notice to be dropped. If the situation were reversed, with named writing messages of only warning or higher, then syslogd would print all messages it received from the channel.

The stderr destination clause directs the channel to the server's standard error stream. This is intended for use when the server is running as a foreground process, for example when debugging a configuration.

The server can supply extensive debugging information when it is in debugging mode. If the server's global debug level is greater than zero, then debugging mode will be active. The global debug level is set either by starting the named server with the -d flag followed by a positive integer, or by running rndc trace. The global debug level can be set to zero, and debugging mode turned off, by running rndc notrace. All debugging messages in the server have a debug level, and higher debug levels give more detailed output. Channels that specify a specific debug severity, for example:

channel specific_debug_level {
    file "foo";
    severity debug 3;
};

will get debugging output of level 3 or less any time the server is in debugging mode, regardless of the global debugging level. Channels with dynamic severity use the server's global debug level to determine what messages to print.

If print-time has been turned on, then the date and time will be logged. print-time may be specified for a syslog channel, but is usually pointless since syslog also logs the date and time. If print-category is requested, then the category of the message will be logged as well. Finally, if print-severity is on, then the severity level of the message will be logged. The print- options may be used in any combination, and will always be printed in the following order: time, category, severity. Here is an example where all three print- options are on:

28-Feb-2000 15:05:32.863 general: notice: running

There are four predefined channels that are used for named's default logging as follows. How they are used is described in the section called “The category Phrase”.

channel default_syslog {
    // send to syslog's daemon facility
    syslog daemon;
    // only send priority info and higher
    severity info;

channel default_debug {
    // write to named.run in the working directory
    // Note: stderr is used instead of "named.run" if
    // the server is started with the '-f' option.
    file "named.run";
    // log at the server's current debug level
    severity dynamic;
};

channel default_stderr {
    // writes to stderr
    stderr;
    // only send priority info and higher
    severity info;
};

channel null {
   // toss anything sent to this channel
   null;
};

The default_debug channel has the special property that it only produces output when the server's debug level is nonzero. It normally writes to a file called named.run in the server's working directory.

For security reasons, when the "-u" command line option is used, the named.run file is created only after named has changed to the new UID, and any debug output generated while named is starting up and still running as root is discarded. If you need to capture this output, you must run the server with the "-g" option and redirect standard error to a file.

Once a channel is defined, it cannot be redefined. Thus you cannot alter the built-in channels directly, but you can modify the default logging by pointing categories at channels you have defined.

The category Phrase

There are many categories, so you can send the logs you want to see wherever you want, without seeing logs you don't want. If you don't specify a list of channels for a category, then log messages in that category will be sent to the default category instead. If you don't specify a default category, the following "default default" is used:

category default { default_syslog; default_debug; };

As an example, let's say you want to log security events to a file, but you also want keep the default logging behavior. You'd specify the following:

channel my_security_channel {
    file "my_security_file";
    severity info;
};
category security {
    my_security_channel;
    default_syslog;
    default_debug;
};

To discard all messages in a category, specify the null channel:

category xfer-out { null; };
category notify { null; };

Following are the available categories and brief descriptions of the types of log information they contain. More categories may be added in future BIND releases.

default

The default category defines the logging options for those categories where no specific configuration has been defined.

general

The catch-all. Many things still aren't classified into categories, and they all end up here.

database

Messages relating to the databases used internally by the name server to store zone and cache data.

security

Approval and denial of requests.

config

Configuration file parsing and processing.

resolver

DNS resolution, such as the recursive lookups performed on behalf of clients by a caching name server.

xfer-in

Zone transfers the server is receiving.

xfer-out

Zone transfers the server is sending.

notify

The NOTIFY protocol.

client

Processing of client requests.

unmatched

Messages that named was unable to determine the class of or for which there was no matching view. A one line summary is also logged to the client category. This category is best sent to a file or stderr, by default it is sent to the null channel.

network

Network operations.

update

Dynamic updates.

update-security

Approval and denial of update requests.

queries

Specify where queries should be logged to.

At startup, specifying the category queries will also enable query logging unless querylog option has been specified.

The query log entry reports the client's IP address and port number, and the query name, class and type. Next it reports whether the Recursion Desired flag was set (+ if set, - if not set), if the query was signed (S), EDNS was in use (E), if TCP was used (T), if DO (DNSSEC Ok) was set (D), or if CD (Checking Disabled) was set (C). After this the destination address the query was sent to is reported.

client 127.0.0.1#62536 (www.example.com): query: www.example.com IN AAAA +SE

client ::1#62537 (www.example.net): query: www.example.net IN AAAA -SE

(The first part of this log message, showing the client address/port number and query name, is repeated in all subsequent log messages related to the same query.)

query-errors

Information about queries that resulted in some failure.

dispatch

Dispatching of incoming packets to the server modules where they are to be processed.

dnssec

DNSSEC and TSIG protocol processing.

lame-servers

Lame servers. These are misconfigurations in remote servers, discovered by BIND 9 when trying to query those servers during resolution.

delegation-only

Delegation only. Logs queries that have been forced to NXDOMAIN as the result of a delegation-only zone or a delegation-only in a forward, hint or stub zone declaration.

edns-disabled

Log queries that have been forced to use plain DNS due to timeouts. This is often due to the remote servers not being RFC 1034 compliant (not always returning FORMERR or similar to EDNS queries and other extensions to the DNS when they are not understood). In other words, this is targeted at servers that fail to respond to DNS queries that they don't understand.

Note: the log message can also be due to packet loss. Before reporting servers for non-RFC 1034 compliance they should be re-tested to determine the nature of the non-compliance. This testing should prevent or reduce the number of false-positive reports.

Note: eventually named will have to stop treating such timeouts as due to RFC 1034 non compliance and start treating it as plain packet loss. Falsely classifying packet loss as due to RFC 1034 non compliance impacts on DNSSEC validation which requires EDNS for the DNSSEC records to be returned.

RPZ

Information about errors in response policy zone files, rewritten responses, and at the highest debug levels, mere rewriting attempts.

rate-limit

The start, periodic, and final notices of the rate limiting of a stream of responses are logged at info severity in this category. These messages include a hash value of the domain name of the response and the name itself, except when there is insufficient memory to record the name for the final notice The final notice is normally delayed until about one minute after rate limit stops. A lack of memory can hurry the final notice, in which case it starts with an asterisk (*). Various internal events are logged at debug 1 level and higher.

Rate limiting of individual requests is logged in the query-errors category.

cname

Logs nameservers that are skipped due to them being a CNAME rather than A / AAAA records.

The query-errors Category

The query-errors category is specifically intended for debugging purposes: To identify why and how specific queries result in responses which indicate an error. Messages of this category are therefore only logged with debug levels.

At the debug levels of 1 or higher, each response with the rcode of SERVFAIL is logged as follows:

client 127.0.0.1#61502: query failed (SERVFAIL) for www.example.com/IN/AAAA at query.c:3880

This means an error resulting in SERVFAIL was detected at line 3880 of source file query.c. Log messages of this level will particularly help identify the cause of SERVFAIL for an authoritative server.

At the debug levels of 2 or higher, detailed context information of recursive resolutions that resulted in SERVFAIL is logged. The log message will look like as follows:

fetch completed at resolver.c:2970 for www.example.com/A
in 30.000183: timed out/success [domain:example.com,
referral:2,restart:7,qrysent:8,timeout:5,lame:0,neterr:0,
badresp:1,adberr:0,findfail:0,valfail:0]
            

The first part before the colon shows that a recursive resolution for AAAA records of www.example.com completed in 30.000183 seconds and the final result that led to the SERVFAIL was determined at line 2970 of source file resolver.c.

The following part shows the detected final result and the latest result of DNSSEC validation. The latter is always success when no validation attempt is made. In this example, this query resulted in SERVFAIL probably because all name servers are down or unreachable, leading to a timeout in 30 seconds. DNSSEC validation was probably not attempted.

The last part enclosed in square brackets shows statistics information collected for this particular resolution attempt. The domain field shows the deepest zone that the resolver reached; it is the zone where the error was finally detected. The meaning of the other fields is summarized in the following table.

referral

The number of referrals the resolver received throughout the resolution process. In the above example this is 2, which are most likely com and example.com.

restart

The number of cycles that the resolver tried remote servers at the domain zone. In each cycle the resolver sends one query (possibly resending it, depending on the response) to each known name server of the domain zone.

qrysent

The number of queries the resolver sent at the domain zone.

timeout

The number of timeouts since the resolver received the last response.

lame

The number of lame servers the resolver detected at the domain zone. A server is detected to be lame either by an invalid response or as a result of lookup in BIND9's address database (ADB), where lame servers are cached.

neterr

The number of erroneous results that the resolver encountered in sending queries at the domain zone. One common case is the remote server is unreachable and the resolver receives an ICMP unreachable error message.

badresp

The number of unexpected responses (other than lame) to queries sent by the resolver at the domain zone.

adberr

Failures in finding remote server addresses of the domain zone in the ADB. One common case of this is that the remote server's name does not have any address records.

findfail

Failures of resolving remote server addresses. This is a total number of failures throughout the resolution process.

valfail

Failures of DNSSEC validation. Validation failures are counted throughout the resolution process (not limited to the domain zone), but should only happen in domain.

At the debug levels of 3 or higher, the same messages as those at the debug 1 level are logged for other errors than SERVFAIL. Note that negative responses such as NXDOMAIN are not regarded as errors here.

At the debug levels of 4 or higher, the same messages as those at the debug 2 level are logged for other errors than SERVFAIL. Unlike the above case of level 3, messages are logged for negative responses. This is because any unexpected results can be difficult to debug in the recursion case.

lwres Statement Grammar

This is the grammar of the lwres statement in the named.conf file:

lwres {
    [ listen-on { ip_addr [port ip_port] [dscp ip_dscp] ;
    [ ip_addr [port ip_port] [dscp ip_dscp] ; ... ] }; ]
    [ view view_name; ]
    [ search { domain_name ; [ domain_name ; ... ] }; ]
    [ ndots number; ]
};

lwres Statement Definition and Usage

The lwres statement configures the name server to also act as a lightweight resolver server. (See the section called “Running a Resolver Daemon”.) There may be multiple lwres statements configuring lightweight resolver servers with different properties.

The listen-on statement specifies a list of IPv4 addresses (and ports) that this instance of a lightweight resolver daemon should accept requests on. If no port is specified, port 921 is used. If this statement is omitted, requests will be accepted on 127.0.0.1, port 921.

The view statement binds this instance of a lightweight resolver daemon to a view in the DNS namespace, so that the response will be constructed in the same manner as a normal DNS query matching this view. If this statement is omitted, the default view is used, and if there is no default view, an error is triggered.

The search statement is equivalent to the search statement in /etc/resolv.conf. It provides a list of domains which are appended to relative names in queries.

The ndots statement is equivalent to the ndots statement in /etc/resolv.conf. It indicates the minimum number of dots in a relative domain name that should result in an exact match lookup before search path elements are appended.

masters Statement Grammar

masters name [port ip_port] [dscp ip_dscp] { ( masters_list |
      ip_addr [port ip_port] [key key] ) ; [...] };

masters Statement Definition and Usage

masters lists allow for a common set of masters to be easily used by multiple stub and slave zones in their masters or also-notify lists.

options Statement Grammar

This is the grammar of the options statement in the named.conf file:

options {
    [ attach-cache cache_name; ]
    [ version version_string; ]
    [ hostname hostname_string; ]
    [ server-id server_id_string; ]
    [ directory path_name; ]
    [ geoip-directory path_name; ]
    [ key-directory path_name; ]
    [ managed-keys-directory path_name; ]
    [ named-xfer path_name; ]
    [ tkey-gssapi-keytab path_name; ]
    [ tkey-gssapi-credential principal; ]
    [ tkey-domain domainname; ]
    [ tkey-dhkey key_name key_tag; ]
    [ cache-file path_name; ]
    [ dump-file path_name; ]
    [ bindkeys-file path_name; ]
    [ secroots-file path_name; ]
    [ session-keyfile path_name; ]
    [ session-keyname key_name; ]
    [ session-keyalg algorithm_id; ]
    [ memstatistics yes_or_no; ]
    [ memstatistics-file path_name; ]
    [ pid-file path_name; ]
    [ recursing-file path_name; ]
    [ statistics-file path_name; ]
    [ zone-statistics full | terse | none; ]
    [ auth-nxdomain yes_or_no; ]
    [ deallocate-on-exit yes_or_no; ]
    [ dialup dialup_option; ]
    [ fake-iquery yes_or_no; ]
    [ fetch-glue yes_or_no; ]
    [ flush-zones-on-shutdown yes_or_no; ]
    [ has-old-clients yes_or_no; ]
    [ host-statistics yes_or_no; ]
    [ host-statistics-max number; ]
    [ minimal-responses yes_or_no; ]
    [ multiple-cnames yes_or_no; ]
    [ notify yes_or_no | explicit | master-only; ]
    [ recursion yes_or_no; ]
    [ request-sit yes_or_no; ]
    [ request-nsid yes_or_no; ]
    [ rfc2308-type1 yes_or_no; ]
    [ use-id-pool yes_or_no; ]
    [ maintain-ixfr-base yes_or_no; ]
    [ ixfr-from-differences (yes_or_no | master | slave); ]
    [ dnssec-enable yes_or_no; ]
    [ dnssec-validation (yes_or_no | auto); ]
    [ dnssec-lookaside ( auto |
                        no |
                        domain trust-anchor domain ); ]
    [ dnssec-must-be-secure domain yes_or_no; ]
    [ dnssec-accept-expired yes_or_no; ]
    [ forward ( only | first ); ]
    [ forwarders { [ ip_addr [port ip_port] [dscp ip_dscp] ; ... ] }; ]
    [ dual-stack-servers [port ip_port] [dscp ip_dscp] {
        ( domain_name [port ip_port] [dscp ip_dscp] |
          ip_addr [port ip_port] [dscp ip_dscp]) ;
        ... }; ]
    [ check-names ( master | slave | response )
        ( warn | fail | ignore ); ]
    [ check-dup-records ( warn | fail | ignore ); ]
    [ check-mx ( warn | fail | ignore ); ]
    [ check-wildcard yes_or_no; ]
    [ check-integrity yes_or_no; ]
    [ check-mx-cname ( warn | fail | ignore ); ]
    [ check-srv-cname ( warn | fail | ignore ); ]
    [ check-sibling yes_or_no; ]
    [ check-spf ( warn | ignore ); ]
    [ allow-new-zones { yes_or_no }; ]
    [ allow-notify { address_match_list }; ]
    [ allow-query { address_match_list }; ]
    [ allow-query-on { address_match_list }; ]
    [ allow-query-cache { address_match_list }; ]
    [ allow-query-cache-on { address_match_list }; ]
    [ allow-transfer { address_match_list }; ]
    [ allow-recursion { address_match_list }; ]
    [ allow-recursion-on { address_match_list }; ]
    [ allow-update { address_match_list }; ]
    [ allow-update-forwarding { address_match_list }; ]
    [ update-check-ksk yes_or_no; ]
    [ dnssec-update-mode ( maintain | no-resign ); ]
    [ dnssec-dnskey-kskonly yes_or_no; ]
    [ dnssec-loadkeys-interval number; ]
    [ dnssec-secure-to-insecure yes_or_no ;]
    [ try-tcp-refresh yes_or_no; ]
    [ allow-v6-synthesis { address_match_list }; ]
    [ blackhole { address_match_list }; ]
    [ no-case-compress { address_match_list }; ]
    [ use-v4-udp-ports { port_list }; ]
    [ avoid-v4-udp-ports { port_list }; ]
    [ use-v6-udp-ports { port_list }; ]
    [ avoid-v6-udp-ports { port_list }; ]
    [ listen-on [ port ip_port ] [dscp ip_dscp] { address_match_list }; ]
    [ listen-on-v6 [ port ip_port] [dscp ip_dscp]
{ address_match_list }; ]
    [ query-source ( ( ip4_addr | * )
        [ port ( ip_port | * ) ]
        [ dscp ip_dscp] |
        [ address ( ip4_addr | * ) ]
        [ port ( ip_port | * ) ] )
        [ dscp ip_dscp] ; ]
    [ query-source-v6 ( ( ip6_addr | * )
        [ port ( ip_port | * ) ]
        [ dscp ip_dscp] |
        [ address ( ip6_addr | * ) ]
        [ port ( ip_port | * ) ] )
        [ dscp ip_dscp] ; ]
    [ use-queryport-pool yes_or_no; ]
    [ queryport-pool-ports number; ]
    [ queryport-pool-updateinterval number; ]
    [ max-transfer-time-in number; ]
    [ max-transfer-time-out number; ]
    [ max-transfer-idle-in number; ]
    [ max-transfer-idle-out number; ]
    [ reserved-sockets number; ]
    [ recursive-clients number; ]
    [ tcp-clients number; ]
    [ clients-per-query number ; ]
    [ max-clients-per-query number ; ]
    [ fetches-per-server number [(drop | fail)]; ]
    [ fetch-quota-params number fixedpoint fixedpoint fixedpoint ; ]
    [ fetches-per-zonenumber [(drop | fail)]; ]
    [ serial-query-rate number; ]
    [ serial-queries number; ]
    [ tcp-listen-queue number; ]
    [ transfer-format ( one-answer | many-answers ); ]
    [ transfers-in  number; ]
    [ transfers-out number; ]
    [ transfers-per-ns number; ]
    [ transfer-source (ip4_addr | *) [port ip_port] [dscp ip_dscp] ; ]
    [ transfer-source-v6 (ip6_addr | *) [port ip_port] [dscp ip_dscp] ; ]
    [ alt-transfer-source (ip4_addr | *) [port ip_port] [dscp ip_dscp] ; ]
    [ alt-transfer-source-v6 (ip6_addr | *) [port ip_port] [dscp ip_dscp] ; ]
    [ use-alt-transfer-source yes_or_no; ]
    [ notify-delay seconds ; ]
    [ notify-source (ip4_addr | *) [port ip_port] [dscp ip_dscp] ; ]
    [ notify-source-v6 (ip6_addr | *) [port ip_port] [dscp ip_dscp] ; ]
    [ notify-to-soa yes_or_no ; ]
    [ also-notify { ip_addr
                    [port ip_port] [dscp ip_dscp] [key keyname] ;
                    [ ip_addr [port ip_port] [dscp ip_dscp] [key keyname] ; ... ] }; ]
    [ max-ixfr-log-size number; ]
    [ max-journal-size size_spec; ]
    [ coresize size_spec ; ]
    [ datasize size_spec ; ]
    [ files size_spec ; ]
    [ stacksize size_spec ; ]
    [ cleaning-interval number; ]
    [ heartbeat-interval number; ]
    [ interface-interval number; ]
    [ statistics-interval number; ]
    [ topology { address_match_list }];
    [ sortlist { address_match_list }];
    [ rrset-order { order_spec ; [ order_spec ; ... ] ] };
    [ lame-ttl number; ]
    [ max-ncache-ttl number; ]
    [ max-cache-ttl number; ]
    [ max-zone-ttl number ; ]
    [ sig-validity-interval number [number] ; ]
    [ sig-signing-nodes number ; ]
    [ sig-signing-signatures number ; ]
    [ sig-signing-type number ; ]
    [ min-roots number; ]
    [ use-ixfr yes_or_no ; ]
    [ provide-ixfr yes_or_no; ]
    [ request-ixfr yes_or_no; ]
    [ treat-cr-as-space yes_or_no ; ]
    [ min-refresh-time number ; ]
    [ max-refresh-time number ; ]
    [ min-retry-time number ; ]
    [ max-retry-time number ; ]
    [ port ip_port; ]
    [ dscp ip_dscp] ;
    [ additional-from-auth yes_or_no ; ]
    [ additional-from-cache yes_or_no ; ]
    [ random-device path_name ; ]
    [ max-cache-size size_spec ; ]
    [ match-mapped-addresses yes_or_no; ]
    [ filter-aaaa-on-v4 ( yes_or_no | break-dnssec ); ]
    [ filter-aaaa-on-v6 ( yes_or_no | break-dnssec ); ]
    [ filter-aaaa { address_match_list }; ]
    [ dns64 ipv6-prefix {
        [ clients { address_match_list }; ]
        [ mapped { address_match_list }; ]
        [ exclude { address_match_list }; ]
        [ suffix IPv6-address; ]
        [ recursive-only yes_or_no; ]
        [ break-dnssec yes_or_no; ]
    }; ];
    [ dns64-server name ]
    [ dns64-contact name ]
    [ preferred-glue ( A | AAAA | NONE ); ]
    [ edns-udp-size number; ]
    [ max-udp-size number; ]
    [ max-rsa-exponent-size number; ]
    [ root-delegation-only [ exclude { namelist } ] ; ]
    [ querylog yes_or_no ; ]
    [ disable-algorithms domain { algorithm;
                                [ algorithm; ] }; ]
    [ disable-ds-digests domain { digest_type;
                                [ digest_type; ] }; ]
    [ acache-enable yes_or_no ; ]
    [ acache-cleaning-interval number; ]
    [ max-acache-size size_spec ; ]
    [ max-recursion-depth number ; ]
    [ max-recursion-queries number ; ]
    [ masterfile-format
            (text|raw|map) ; ]
    [ empty-server name ; ]
    [ empty-contact name ; ]
    [ empty-zones-enable yes_or_no ; ]
    [ disable-empty-zone zone_name ; ]
    [ zero-no-soa-ttl yes_or_no ; ]
    [ zero-no-soa-ttl-cache yes_or_no ; ]
    [ resolver-query-timeout number ; ]
    [ deny-answer-addresses { address_match_list } [ except-from { namelist } ];]
    [ deny-answer-aliases { namelist } [ except-from { namelist } ];]
    [ prefetch number [number] ; ]

    [ rate-limit {
        [ responses-per-second number ; ]
        [ referrals-per-second number ; ]
        [ nodata-per-second number ; ]
        [ nxdomains-per-second number ; ]
        [ errors-per-second number ; ]
        [ all-per-second number ; ]
        [ window number ; ]
        [ log-only yes_or_no ; ]
        [ qps-scale number ; ]
        [ ipv4-prefix-length number ; ]
        [ ipv6-prefix-length number ; ]
        [ slip number ; ]
        [ exempt-clients  { address_match_list } ; ]
        [ max-table-size number ; ]
        [ min-table-size number ; ]
    } ; ]
    [ response-policy {
        zone zone_name
        [ policy (given | disabled | passthru | drop |
                  nxdomain | nodata | cname domain) ]
        [ recursive-only yes_or_no ]
        [ max-policy-ttl number ]
        ; [...]
    } [ recursive-only yes_or_no ]
      [ max-policy-ttl number ]
      [ break-dnssec yes_or_no ]
      [ min-ns-dots number ]
      [ qname-wait-recurse yes_or_no ]
    ; ]
};

options Statement Definition and Usage

The options statement sets up global options to be used by BIND. This statement may appear only once in a configuration file. If there is no options statement, an options block with each option set to its default will be used.

attach-cache

Allows multiple views to share a single cache database. Each view has its own cache database by default, but if multiple views have the same operational policy for name resolution and caching, those views can share a single cache to save memory and possibly improve resolution efficiency by using this option.

The attach-cache option may also be specified in view statements, in which case it overrides the global attach-cache option.

The cache_name specifies the cache to be shared. When the named server configures views which are supposed to share a cache, it creates a cache with the specified name for the first view of these sharing views. The rest of the views will simply refer to the already created cache.

One common configuration to share a cache would be to allow all views to share a single cache. This can be done by specifying the attach-cache as a global option with an arbitrary name.

Another possible operation is to allow a subset of all views to share a cache while the others to retain their own caches. For example, if there are three views A, B, and C, and only A and B should share a cache, specify the attach-cache option as a view A (or B)'s option, referring to the other view name:

  view "A" {
    // this view has its own cache
    ...
  };
  view "B" {
    // this view refers to A's cache
    attach-cache "A";
  };
  view "C" {
    // this view has its own cache
    ...
  };

Views that share a cache must have the same policy on configurable parameters that may affect caching. The current implementation requires the following configurable options be consistent among these views: check-names, cleaning-interval, dnssec-accept-expired, dnssec-validation, max-cache-ttl, max-ncache-ttl, max-cache-size, and zero-no-soa-ttl.

Note that there may be other parameters that may cause confusion if they are inconsistent for different views that share a single cache. For example, if these views define different sets of forwarders that can return different answers for the same question, sharing the answer does not make sense or could even be harmful. It is administrator's responsibility to ensure configuration differences in different views do not cause disruption with a shared cache.

directory

The working directory of the server. Any non-absolute pathnames in the configuration file will be taken as relative to this directory. The default location for most server output files (e.g. named.run) is this directory. If a directory is not specified, the working directory defaults to `.', the directory from which the server was started. The directory specified should be an absolute path.

geoip-directory

Specifies the directory containing GeoIP .dat database files for GeoIP initialization. By default, this option is unset and the GeoIP support will use libGeoIP's built-in directory. (For details, see the section called “acl Statement Definition and Usage” about the geoip ACL.)

key-directory

When performing dynamic update of secure zones, the directory where the public and private DNSSEC key files should be found, if different than the current working directory. (Note that this option has no effect on the paths for files containing non-DNSSEC keys such as bind.keys, rndc.key or session.key.)

managed-keys-directory

Specifies the directory in which to store the files that track managed DNSSEC keys. By default, this is the working directory.

If named is not configured to use views, then managed keys for the server will be tracked in a single file called managed-keys.bind. Otherwise, managed keys will be tracked in separate files, one file per view; each file name will be the SHA256 hash of the view name, followed by the extension .mkeys.

named-xfer

This option is obsolete. It was used in BIND 8 to specify the pathname to the named-xfer program. In BIND 9, no separate named-xfer program is needed; its functionality is built into the name server.

tkey-gssapi-keytab

The KRB5 keytab file to use for GSS-TSIG updates. If this option is set and tkey-gssapi-credential is not set, then updates will be allowed with any key matching a principal in the specified keytab.

tkey-gssapi-credential

The security credential with which the server should authenticate keys requested by the GSS-TSIG protocol. Currently only Kerberos 5 authentication is available and the credential is a Kerberos principal which the server can acquire through the default system key file, normally /etc/krb5.keytab. The location keytab file can be overridden using the tkey-gssapi-keytab option. Normally this principal is of the form "DNS/server.domain". To use GSS-TSIG, tkey-domain must also be set if a specific keytab is not set with tkey-gssapi-keytab.

tkey-domain

The domain appended to the names of all shared keys generated with TKEY. When a client requests a TKEY exchange, it may or may not specify the desired name for the key. If present, the name of the shared key will be client specified part + tkey-domain. Otherwise, the name of the shared key will be random hex digits + tkey-domain. In most cases, the domainname should be the server's domain name, or an otherwise non-existent subdomain like "_tkey.domainname". If you are using GSS-TSIG, this variable must be defined, unless you specify a specific keytab using tkey-gssapi-keytab.

tkey-dhkey

The Diffie-Hellman key used by the server to generate shared keys with clients using the Diffie-Hellman mode of TKEY. The server must be able to load the public and private keys from files in the working directory. In most cases, the keyname should be the server's host name.

cache-file

This is for testing only. Do not use.

dump-file

The pathname of the file the server dumps the database to when instructed to do so with rndc dumpdb. If not specified, the default is named_dump.db.

memstatistics-file

The pathname of the file the server writes memory usage statistics to on exit. If not specified, the default is named.memstats.

pid-file

The pathname of the file the server writes its process ID in. If not specified, the default is /var/run/named/named.pid. The PID file is used by programs that want to send signals to the running name server. Specifying pid-file none disables the use of a PID file — no file will be written and any existing one will be removed. Note that none is a keyword, not a filename, and therefore is not enclosed in double quotes.

recursing-file

The pathname of the file the server dumps the queries that are currently recursing when instructed to do so with rndc recursing. If not specified, the default is named.recursing.

statistics-file

The pathname of the file the server appends statistics to when instructed to do so using rndc stats. If not specified, the default is named.stats in the server's current directory. The format of the file is described in the section called “The Statistics File”.

bindkeys-file

The pathname of a file to override the built-in trusted keys provided by named. See the discussion of dnssec-lookaside and dnssec-validation for details. If not specified, the default is /etc/bind.keys.

secroots-file

The pathname of the file the server dumps security roots to when instructed to do so with rndc secroots. If not specified, the default is named.secroots.

session-keyfile

The pathname of the file into which to write a TSIG session key generated by named for use by nsupdate -l. If not specified, the default is /var/run/named/session.key. (See the section called “Dynamic Update Policies”, and in particular the discussion of the update-policy statement's local option for more information about this feature.)

session-keyname

The key name to use for the TSIG session key. If not specified, the default is "local-ddns".

session-keyalg

The algorithm to use for the TSIG session key. Valid values are hmac-sha1, hmac-sha224, hmac-sha256, hmac-sha384, hmac-sha512 and hmac-md5. If not specified, the default is hmac-sha256.

port

The UDP/TCP port number the server uses for receiving and sending DNS protocol traffic. The default is 53. This option is mainly intended for server testing; a server using a port other than 53 will not be able to communicate with the global DNS.

dscp

The global Differentiated Services Code Point (DSCP) value to classify outgoing DNS traffic on operating systems that support DSCP. Valid values are 0 through 63. It is not configured by default.

random-device

The source of entropy to be used by the server. Entropy is primarily needed for DNSSEC operations, such as TKEY transactions and dynamic update of signed zones. This options specifies the device (or file) from which to read entropy. If this is a file, operations requiring entropy will fail when the file has been exhausted. If not specified, the default value is /dev/random (or equivalent) when present, and none otherwise. The random-device option takes effect during the initial configuration load at server startup time and is ignored on subsequent reloads.

preferred-glue

If specified, the listed type (A or AAAA) will be emitted before other glue in the additional section of a query response. The default is not to prefer any type (NONE).

root-delegation-only

Turn on enforcement of delegation-only in TLDs (top level domains) and root zones with an optional exclude list.

DS queries are expected to be made to and be answered by delegation only zones. Such queries and responses are treated as an exception to delegation-only processing and are not converted to NXDOMAIN responses provided a CNAME is not discovered at the query name.

If a delegation only zone server also serves a child zone it is not always possible to determine whether an answer comes from the delegation only zone or the child zone. SOA NS and DNSKEY records are apex only records and a matching response that contains these records or DS is treated as coming from a child zone. RRSIG records are also examined to see if they are signed by a child zone or not. The authority section is also examined to see if there is evidence that the answer is from the child zone. Answers that are determined to be from a child zone are not converted to NXDOMAIN responses. Despite all these checks there is still a possibility of false negatives when a child zone is being served.

Similarly false positives can arise from empty nodes (no records at the name) in the delegation only zone when the query type is not ANY.

Note some TLDs are not delegation only (e.g. "DE", "LV", "US" and "MUSEUM"). This list is not exhaustive.

options {
        root-delegation-only exclude { "de"; "lv"; "us"; "museum"; };
};
disable-algorithms

Disable the specified DNSSEC algorithms at and below the specified name. Multiple disable-algorithms statements are allowed. Only the best match disable-algorithms clause will be used to determine which algorithms are used.

If all supported algorithms are disabled, the zones covered by the disable-algorithms will be treated as insecure.

disable-ds-digests

Disable the specified DS/DLV digest types at and below the specified name. Multiple disable-ds-digests statements are allowed. Only the best match disable-ds-digests clause will be used to determine which digest types are used.

If all supported digest types are disabled, the zones covered by the disable-ds-digests will be treated as insecure.

dnssec-lookaside

When set, dnssec-lookaside provides the validator with an alternate method to validate DNSKEY records at the top of a zone. When a DNSKEY is at or below a domain specified by the deepest dnssec-lookaside, and the normal DNSSEC validation has left the key untrusted, the trust-anchor will be appended to the key name and a DLV record will be looked up to see if it can validate the key. If the DLV record validates a DNSKEY (similarly to the way a DS record does) the DNSKEY RRset is deemed to be trusted.

If dnssec-lookaside is set to auto, then built-in default values for the DLV domain and trust anchor will be used, along with a built-in key for validation.

If dnssec-lookaside is set to no, then dnssec-lookaside is not used.

The default DLV key is stored in the file bind.keys; named will load that key at startup if dnssec-lookaside is set to auto. A copy of the file is installed along with BIND 9, and is current as of the release date. If the DLV key expires, a new copy of bind.keys can be downloaded from https://www.isc.org/solutions/dlv/.

(To prevent problems if bind.keys is not found, the current key is also compiled in to named. Relying on this is not recommended, however, as it requires named to be recompiled with a new key when the DLV key expires.)

NOTE: named only loads certain specific keys from bind.keys: those for the DLV zone and for the DNS root zone. The file cannot be used to store keys for other zones.

dnssec-must-be-secure

Specify hierarchies which must be or may not be secure (signed and validated). If yes, then named will only accept answers if they are secure. If no, then normal DNSSEC validation applies allowing for insecure answers to be accepted. The specified domain must be under a trusted-keys or managed-keys statement, or dnssec-lookaside must be active.

dns64

This directive instructs named to return mapped IPv4 addresses to AAAA queries when there are no AAAA records. It is intended to be used in conjunction with a NAT64. Each dns64 defines one DNS64 prefix. Multiple DNS64 prefixes can be defined.

Compatible IPv6 prefixes have lengths of 32, 40, 48, 56, 64 and 96 as per RFC 6052.

Additionally a reverse IP6.ARPA zone will be created for the prefix to provide a mapping from the IP6.ARPA names to the corresponding IN-ADDR.ARPA names using synthesized CNAMEs. dns64-server and dns64-contact can be used to specify the name of the server and contact for the zones. These are settable at the view / options level. These are not settable on a per-prefix basis.

Each dns64 supports an optional clients ACL that determines which clients are affected by this directive. If not defined, it defaults to any;.

Each dns64 supports an optional mapped ACL that selects which IPv4 addresses are to be mapped in the corresponding A RRset. If not defined it defaults to any;.

Normally, DNS64 won't apply to a domain name that owns one or more AAAA records; these records will simply be returned. The optional exclude ACL allows specification of a list of IPv6 addresses that will be ignored if they appear in a domain name's AAAA records, and DNS64 will be applied to any A records the domain name owns. If not defined, exclude defaults to none.

A optional suffix can also be defined to set the bits trailing the mapped IPv4 address bits. By default these bits are set to ::. The bits matching the prefix and mapped IPv4 address must be zero.

If recursive-only is set to yes the DNS64 synthesis will only happen for recursive queries. The default is no.

If break-dnssec is set to yes the DNS64 synthesis will happen even if the result, if validated, would cause a DNSSEC validation failure. If this option is set to no (the default), the DO is set on the incoming query, and there are RRSIGs on the applicable records, then synthesis will not happen.

        acl rfc1918 { 10/8; 192.168/16; 172.16/12; };

        dns64 64:FF9B::/96 {
                clients { any; };
                mapped { !rfc1918; any; };
                exclude { 64:FF9B::/96; ::ffff:0000:0000/96; };
                suffix ::;
        };
dnssec-update-mode

If this option is set to its default value of maintain in a zone of type master which is DNSSEC-signed and configured to allow dynamic updates (see the section called “Dynamic Update Policies”), and if named has access to the private signing key(s) for the zone, then named will automatically sign all new or changed records and maintain signatures for the zone by regenerating RRSIG records whenever they approach their expiration date.

If the option is changed to no-resign, then named will sign all new or changed records, but scheduled maintenance of signatures is disabled.

With either of these settings, named will reject updates to a DNSSEC-signed zone when the signing keys are inactive or unavailable to named. (A planned third option, external, will disable all automatic signing and allow DNSSEC data to be submitted into a zone via dynamic update; this is not yet implemented.)

max-zone-ttl

Specifies a maximum permissible TTL value. When loading a zone file using a masterfile-format of text or raw, any record encountered with a TTL higher than max-zone-ttl will cause the zone to be rejected.

This is useful in DNSSEC-signed zones because when rolling to a new DNSKEY, the old key needs to remain available until RRSIG records have expired from caches. Themax-zone-ttl option guarantees that the largest TTL in the zone will be no higher the set value.

(NOTE: Because map-format files load directly into memory, this option cannot be used with them.)

zone-statistics

If full, the server will collect statistical data on all zones (unless specifically turned off on a per-zone basis by specifying zone-statistics terse or zone-statistics none in the zone statement). The default is terse, providing minimal statistics on zones (including name and current serial number, but not query type counters).

These statistics may be accessed via the statistics-channel or using rndc stats, which will dump them to the file listed in the statistics-file. See also the section called “The Statistics File”.

For backward compatibility with earlier versions of BIND 9, the zone-statistics option can also accept yes or no; yes has the same meaning as full. As of BIND 9.10, no has the same meaning as none; previously, it was the same as terse.

Boolean Options

automatic-interface-scan

If yes and supported by the OS, automatically rescan network interfaces when the interface addresses are added or removed. The default is yes.

Currently the OS needs to support routing sockets for automatic-interface-scan to be supported.

allow-new-zones

If yes, then zones can be added at runtime via rndc addzone or deleted via rndc delzone. The default is no.

auth-nxdomain

If yes, then the AA bit is always set on NXDOMAIN responses, even if the server is not actually authoritative. The default is no; this is a change from BIND 8. If you are using very old DNS software, you may need to set it to yes.

deallocate-on-exit

This option was used in BIND 8 to enable checking for memory leaks on exit. BIND 9 ignores the option and always performs the checks.

memstatistics

Write memory statistics to the file specified by memstatistics-file at exit. The default is no unless '-m record' is specified on the command line in which case it is yes.

dialup

If yes, then the server treats all zones as if they are doing zone transfers across a dial-on-demand dialup link, which can be brought up by traffic originating from this server. This has different effects according to zone type and concentrates the zone maintenance so that it all happens in a short interval, once every heartbeat-interval and hopefully during the one call. It also suppresses some of the normal zone maintenance traffic. The default is no.

The dialup option may also be specified in the view and zone statements, in which case it overrides the global dialup option.

If the zone is a master zone, then the server will send out a NOTIFY request to all the slaves (default). This should trigger the zone serial number check in the slave (providing it supports NOTIFY) allowing the slave to verify the zone while the connection is active. The set of servers to which NOTIFY is sent can be controlled by notify and also-notify.

If the zone is a slave or stub zone, then the server will suppress the regular "zone up to date" (refresh) queries and only perform them when the heartbeat-interval expires in addition to sending NOTIFY requests.

Finer control can be achieved by using notify which only sends NOTIFY messages, notify-passive which sends NOTIFY messages and suppresses the normal refresh queries, refresh which suppresses normal refresh processing and sends refresh queries when the heartbeat-interval expires, and passive which just disables normal refresh processing.

dialup mode

normal refresh

heart-beat refresh

heart-beat notify

no (default)

yes

no

no

yes

no

yes

yes

notify

yes

no

yes

refresh

no

yes

no

passive

no

no

no

notify-passive

no

no

yes

Note that normal NOTIFY processing is not affected by dialup.

fake-iquery

In BIND 8, this option enabled simulating the obsolete DNS query type IQUERY. BIND 9 never does IQUERY simulation.

fetch-glue

This option is obsolete. In BIND 8, fetch-glue yes caused the server to attempt to fetch glue resource records it didn't have when constructing the additional data section of a response. This is now considered a bad idea and BIND 9 never does it.

flush-zones-on-shutdown

When the nameserver exits due receiving SIGTERM, flush or do not flush any pending zone writes. The default is flush-zones-on-shutdown no.

has-old-clients

This option was incorrectly implemented in BIND 8, and is ignored by BIND 9. To achieve the intended effect of has-old-clients yes, specify the two separate options auth-nxdomain yes and rfc2308-type1 no instead.

host-statistics

In BIND 8, this enables keeping of statistics for every host that the name server interacts with. Not implemented in BIND 9.

maintain-ixfr-base

This option is obsolete. It was used in BIND 8 to determine whether a transaction log was kept for Incremental Zone Transfer. BIND 9 maintains a transaction log whenever possible. If you need to disable outgoing incremental zone transfers, use provide-ixfr no.

minimal-responses

If yes, then when generating responses the server will only add records to the authority and additional data sections when they are required (e.g. delegations, negative responses). This may improve the performance of the server. The default is no.

multiple-cnames

This option was used in BIND 8 to allow a domain name to have multiple CNAME records in violation of the DNS standards. BIND 9.2 onwards always strictly enforces the CNAME rules both in master files and dynamic updates.

notify

If yes (the default), DNS NOTIFY messages are sent when a zone the server is authoritative for changes, see the section called “Notify”. The messages are sent to the servers listed in the zone's NS records (except the master server identified in the SOA MNAME field), and to any servers listed in the also-notify option.

If master-only, notifies are only sent for master zones. If explicit, notifies are sent only to servers explicitly listed using also-notify. If no, no notifies are sent.

The notify option may also be specified in the zone statement, in which case it overrides the options notify statement. It would only be necessary to turn off this option if it caused slaves to crash.

notify-to-soa

If yes do not check the nameservers in the NS RRset against the SOA MNAME. Normally a NOTIFY message is not sent to the SOA MNAME (SOA ORIGIN) as it is supposed to contain the name of the ultimate master. Sometimes, however, a slave is listed as the SOA MNAME in hidden master configurations and in that case you would want the ultimate master to still send NOTIFY messages to all the nameservers listed in the NS RRset.

recursion

If yes, and a DNS query requests recursion, then the server will attempt to do all the work required to answer the query. If recursion is off and the server does not already know the answer, it will return a referral response. The default is yes. Note that setting recursion no does not prevent clients from getting data from the server's cache; it only prevents new data from being cached as an effect of client queries. Caching may still occur as an effect the server's internal operation, such as NOTIFY address lookups. See also fetch-glue above.

request-nsid

If yes, then an empty EDNS(0) NSID (Name Server Identifier) option is sent with all queries to authoritative name servers during iterative resolution. If the authoritative server returns an NSID option in its response, then its contents are logged in the resolver category at level info. The default is no.

request-sit

If yes, then a SIT (Source Identity Token) EDNS option is sent along with the query. If the resolver has previously talked to the server, the SIT returned in the previous transaction is sent. This is used by the server to determine whether the resolver has talked to it before. A resolver sending the correct SIT is assumed not to be an off-path attacker sending a spoofed-source query; the query is therefore unlikely to be part of a reflection/amplification attack, so resolvers sending a correct SIT option are not subject to response rate limiting (RRL). Resolvers which do not send a correct SIT option may be limited to receiving smaller responses via the nosit-udp-size option.

sit-secret

If set, this is a shared secret used for generating and verifying Source Identity Token EDNS options within a anycast cluster. If not set the system will generate a random secret at startup. The shared secret is encoded as a hex string and needs to be 128 bits for AES128, 160 bits for SHA1 and 256 bits for SHA256.

rfc2308-type1

Setting this to yes will cause the server to send NS records along with the SOA record for negative answers. The default is no.

Note

Not yet implemented in BIND 9.

use-id-pool

This option is obsolete. BIND 9 always allocates query IDs from a pool.

use-ixfr

This option is obsolete. If you need to disable IXFR to a particular server or servers, see the information on the provide-ixfr option in the section called “server Statement Definition and Usage”. See also the section called “Incremental Zone Transfers (IXFR)”.

provide-ixfr

See the description of provide-ixfr in the section called “server Statement Definition and Usage”.

request-ixfr

See the description of request-ixfr in the section called “server Statement Definition and Usage”.

treat-cr-as-space

This option was used in BIND 8 to make the server treat carriage return ("\r") characters the same way as a space or tab character, to facilitate loading of zone files on a UNIX system that were generated on an NT or DOS machine. In BIND 9, both UNIX "\n" and NT/DOS "\r\n" newlines are always accepted, and the option is ignored.

additional-from-auth, additional-from-cache

These options control the behavior of an authoritative server when answering queries which have additional data, or when following CNAME and DNAME chains.

When both of these options are set to yes (the default) and a query is being answered from authoritative data (a zone configured into the server), the additional data section of the reply will be filled in using data from other authoritative zones and from the cache. In some situations this is undesirable, such as when there is concern over the correctness of the cache, or in servers where slave zones may be added and modified by untrusted third parties. Also, avoiding the search for this additional data will speed up server operations at the possible expense of additional queries to resolve what would otherwise be provided in the additional section.

For example, if a query asks for an MX record for host foo.example.com, and the record found is "MX 10 mail.example.net", normally the address records (A and AAAA) for mail.example.net will be provided as well, if known, even though they are not in the example.com zone. Setting these options to no disables this behavior and makes the server only search for additional data in the zone it answers from.

These options are intended for use in authoritative-only servers, or in authoritative-only views. Attempts to set them to no without also specifying recursion no will cause the server to ignore the options and log a warning message.

Specifying additional-from-cache no actually disables the use of the cache not only for additional data lookups but also when looking up the answer. This is usually the desired behavior in an authoritative-only server where the correctness of the cached data is an issue.

When a name server is non-recursively queried for a name that is not below the apex of any served zone, it normally answers with an "upwards referral" to the root servers or the servers of some other known parent of the query name. Since the data in an upwards referral comes from the cache, the server will not be able to provide upwards referrals when additional-from-cache no has been specified. Instead, it will respond to such queries with REFUSED. This should not cause any problems since upwards referrals are not required for the resolution process.

match-mapped-addresses

If yes, then an IPv4-mapped IPv6 address will match any address match list entries that match the corresponding IPv4 address.

This option was introduced to work around a kernel quirk in some operating systems that causes IPv4 TCP connections, such as zone transfers, to be accepted on an IPv6 socket using mapped addresses. This caused address match lists designed for IPv4 to fail to match. However, named now solves this problem internally. The use of this option is discouraged.

filter-aaaa-on-v4

This option is only available when BIND 9 is compiled with the --enable-filter-aaaa option on the "configure" command line. It is intended to help the transition from IPv4 to IPv6 by not giving IPv6 addresses to DNS clients unless they have connections to the IPv6 Internet. This is not recommended unless absolutely necessary. The default is no. The filter-aaaa-on-v4 option may also be specified in view statements to override the global filter-aaaa-on-v4 option.

If yes, the DNS client is at an IPv4 address, in filter-aaaa, and if the response does not include DNSSEC signatures, then all AAAA records are deleted from the response. This filtering applies to all responses and not only authoritative responses.

If break-dnssec, then AAAA records are deleted even when DNSSEC is enabled. As suggested by the name, this makes the response not verify, because the DNSSEC protocol is designed detect deletions.

This mechanism can erroneously cause other servers to not give AAAA records to their clients. A recursing server with both IPv6 and IPv4 network connections that queries an authoritative server using this mechanism via IPv4 will be denied AAAA records even if its client is using IPv6.

This mechanism is applied to authoritative as well as non-authoritative records. A client using IPv4 that is not allowed recursion can erroneously be given AAAA records because the server is not allowed to check for A records.

Some AAAA records are given to IPv4 clients in glue records. IPv4 clients that are servers can then erroneously answer requests for AAAA records received via IPv4.

filter-aaaa-on-v6

Identical to filter-aaaa-on-v4, except it filters AAAA responses to queries from IPv6 clients instead of IPv4 clients. To filter all responses, set both options to yes.

ixfr-from-differences

When yes and the server loads a new version of a master zone from its zone file or receives a new version of a slave file via zone transfer, it will compare the new version to the previous one and calculate a set of differences. The differences are then logged in the zone's journal file such that the changes can be transmitted to downstream slaves as an incremental zone transfer.

By allowing incremental zone transfers to be used for non-dynamic zones, this option saves bandwidth at the expense of increased CPU and memory consumption at the master. In particular, if the new version of a zone is completely different from the previous one, the set of differences will be of a size comparable to the combined size of the old and new zone version, and the server will need to temporarily allocate memory to hold this complete difference set.

ixfr-from-differences also accepts master and slave at the view and options levels which causes ixfr-from-differences to be enabled for all master or slave zones respectively. It is off by default.

multi-master

This should be set when you have multiple masters for a zone and the addresses refer to different machines. If yes, named will not log when the serial number on the master is less than what named currently has. The default is no.

dnssec-enable

This indicates whether DNSSEC-related resource records are to be returned by named. If set to no, named will not return DNSSEC-related resource records unless specifically queried for. The default is yes.

dnssec-validation

Enable DNSSEC validation in named. Note dnssec-enable also needs to be set to yes to be effective. If set to no, DNSSEC validation is disabled. If set to auto, DNSSEC validation is enabled, and a default trust-anchor for the DNS root zone is used. If set to yes, DNSSEC validation is enabled, but a trust anchor must be manually configured using a trusted-keys or managed-keys statement. The default is yes.

Note

Whenever the resolver sends out queries to an EDNS-compliant server, it always sets the DO bit indicating it can support DNSSEC responses even if dnssec-validation is off.

dnssec-accept-expired

Accept expired signatures when verifying DNSSEC signatures. The default is no. Setting this option to yes leaves named vulnerable to replay attacks.

querylog

Specify whether query logging should be started when named starts. If querylog is not specified, then the query logging is determined by the presence of the logging category queries.

check-names

This option is used to restrict the character set and syntax of certain domain names in master files and/or DNS responses received from the network. The default varies according to usage area. For master zones the default is fail. For slave zones the default is warn. For answers received from the network (response) the default is ignore.

The rules for legal hostnames and mail domains are derived from RFC 952 and RFC 821 as modified by RFC 1123.

check-names applies to the owner names of A, AAAA and MX records. It also applies to the domain names in the RDATA of NS, SOA, MX, and SRV records. It also applies to the RDATA of PTR records where the owner name indicated that it is a reverse lookup of a hostname (the owner name ends in IN-ADDR.ARPA, IP6.ARPA, or IP6.INT).

check-dup-records

Check master zones for records that are treated as different by DNSSEC but are semantically equal in plain DNS. The default is to warn. Other possible values are fail and ignore.

check-mx

Check whether the MX record appears to refer to a IP address. The default is to warn. Other possible values are fail and ignore.

check-wildcard

This option is used to check for non-terminal wildcards. The use of non-terminal wildcards is almost always as a result of a failure to understand the wildcard matching algorithm (RFC 1034). This option affects master zones. The default (yes) is to check for non-terminal wildcards and issue a warning.

check-integrity

Perform post load zone integrity checks on master zones. This checks that MX and SRV records refer to address (A or AAAA) records and that glue address records exist for delegated zones. For MX and SRV records only in-zone hostnames are checked (for out-of-zone hostnames use named-checkzone). For NS records only names below top of zone are checked (for out-of-zone names and glue consistency checks use named-checkzone). The default is yes.

The use of the SPF record for publishing Sender Policy Framework is deprecated as the migration from using TXT records to SPF records was abandoned. Enabling this option also checks that a TXT Sender Policy Framework record exists (starts with "v=spf1") if there is an SPF record. Warnings are emitted if the TXT record does not exist and can be suppressed with check-spf.

check-mx-cname

If check-integrity is set then fail, warn or ignore MX records that refer to CNAMES. The default is to warn.

check-srv-cname

If check-integrity is set then fail, warn or ignore SRV records that refer to CNAMES. The default is to warn.

check-sibling

When performing integrity checks, also check that sibling glue exists. The default is yes.

check-spf

If check-integrity is set then check that there is a TXT Sender Policy Framework record present (starts with "v=spf1") if there is an SPF record present. The default is warn.

zero-no-soa-ttl

When returning authoritative negative responses to SOA queries set the TTL of the SOA record returned in the authority section to zero. The default is yes.

zero-no-soa-ttl-cache

When caching a negative response to a SOA query set the TTL to zero. The default is no.

update-check-ksk

When set to the default value of yes, check the KSK bit in each key to determine how the key should be used when generating RRSIGs for a secure zone.

Ordinarily, zone-signing keys (that is, keys without the KSK bit set) are used to sign the entire zone, while key-signing keys (keys with the KSK bit set) are only used to sign the DNSKEY RRset at the zone apex. However, if this option is set to no, then the KSK bit is ignored; KSKs are treated as if they were ZSKs and are used to sign the entire zone. This is similar to the dnssec-signzone -z command line option.

When this option is set to yes, there must be at least two active keys for every algorithm represented in the DNSKEY RRset: at least one KSK and one ZSK per algorithm. If there is any algorithm for which this requirement is not met, this option will be ignored for that algorithm.

dnssec-dnskey-kskonly

When this option and update-check-ksk are both set to yes, only key-signing keys (that is, keys with the KSK bit set) will be used to sign the DNSKEY RRset at the zone apex. Zone-signing keys (keys without the KSK bit set) will be used to sign the remainder of the zone, but not the DNSKEY RRset. This is similar to the dnssec-signzone -x command line option.

The default is no. If update-check-ksk is set to no, this option is ignored.

dnssec-loadkeys-interval

When a zone is configured with auto-dnssec maintain; its key repository must be checked periodically to see if any new keys have been added or any existing keys' timing metadata has been updated (see dnssec-keygen(8) and dnssec-settime(8)). The dnssec-loadkeys-interval option sets the frequency of automatic repository checks, in minutes. The default is 60 (1 hour), the minimum is 1 (1 minute), and the maximum is 1440 (24 hours); any higher value is silently reduced.

try-tcp-refresh

Try to refresh the zone using TCP if UDP queries fail. For BIND 8 compatibility, the default is yes.

dnssec-secure-to-insecure

Allow a dynamic zone to transition from secure to insecure (i.e., signed to unsigned) by deleting all of the DNSKEY records. The default is no. If set to yes, and if the DNSKEY RRset at the zone apex is deleted, all RRSIG and NSEC records will be removed from the zone as well.

If the zone uses NSEC3, then it is also necessary to delete the NSEC3PARAM RRset from the zone apex; this will cause the removal of all corresponding NSEC3 records. (It is expected that this requirement will be eliminated in a future release.)

Note that if a zone has been configured with auto-dnssec maintain and the private keys remain accessible in the key repository, then the zone will be automatically signed again the next time named is started.

Forwarding

The forwarding facility can be used to create a large site-wide cache on a few servers, reducing traffic over links to external name servers. It can also be used to allow queries by servers that do not have direct access to the Internet, but wish to look up exterior names anyway. Forwarding occurs only on those queries for which the server is not authoritative and does not have the answer in its cache.

forward

This option is only meaningful if the forwarders list is not empty. A value of first, the default, causes the server to query the forwarders first — and if that doesn't answer the question, the server will then look for the answer itself. If only is specified, the server will only query the forwarders.

forwarders

Specifies the IP addresses to be used for forwarding. The default is the empty list (no forwarding).

Forwarding can also be configured on a per-domain basis, allowing for the global forwarding options to be overridden in a variety of ways. You can set particular domains to use different forwarders, or have a different forward only/first behavior, or not forward at all, see the section called “zone Statement Grammar”.

Dual-stack Servers

Dual-stack servers are used as servers of last resort to work around problems in reachability due the lack of support for either IPv4 or IPv6 on the host machine.

dual-stack-servers

Specifies host names or addresses of machines with access to both IPv4 and IPv6 transports. If a hostname is used, the server must be able to resolve the name using only the transport it has. If the machine is dual stacked, then the dual-stack-servers have no effect unless access to a transport has been disabled on the command line (e.g. named -4).

Access Control

Access to the server can be restricted based on the IP address of the requesting system. See the section called “Address Match Lists” for details on how to specify IP address lists.

allow-notify

Specifies which hosts are allowed to notify this server, a slave, of zone changes in addition to the zone masters. allow-notify may also be specified in the zone statement, in which case it overrides the options allow-notify statement. It is only meaningful for a slave zone. If not specified, the default is to process notify messages only from a zone's master.

allow-query

Specifies which hosts are allowed to ask ordinary DNS questions. allow-query may also be specified in the zone statement, in which case it overrides the options allow-query statement. If not specified, the default is to allow queries from all hosts.

Note

allow-query-cache is now used to specify access to the cache.

allow-query-on

Specifies which local addresses can accept ordinary DNS questions. This makes it possible, for instance, to allow queries on internal-facing interfaces but disallow them on external-facing ones, without necessarily knowing the internal network's addresses.

Note that allow-query-on is only checked for queries that are permitted by allow-query. A query must be allowed by both ACLs, or it will be refused.

allow-query-on may also be specified in the zone statement, in which case it overrides the options allow-query-on statement.

If not specified, the default is to allow queries on all addresses.

Note

allow-query-cache is used to specify access to the cache.

allow-query-cache

Specifies which hosts are allowed to get answers from the cache. If allow-query-cache is not set then allow-recursion is used if set, otherwise allow-query is used if set unless recursion no; is set in which case none; is used, otherwise the default (localnets; localhost;) is used.

allow-query-cache-on

Specifies which local addresses can give answers from the cache. If not specified, the default is to allow cache queries on any address, localnets and localhost.

allow-recursion

Specifies which hosts are allowed to make recursive queries through this server. If allow-recursion is not set then allow-query-cache is used if set, otherwise allow-query is used if set, otherwise the default (localnets; localhost;) is used.

allow-recursion-on

Specifies which local addresses can accept recursive queries. If not specified, the default is to allow recursive queries on all addresses.

allow-update

Specifies which hosts are allowed to submit Dynamic DNS updates for master zones. The default is to deny updates from all hosts. Note that allowing updates based on the requestor's IP address is insecure; see the section called “Dynamic Update Security” for details.

allow-update-forwarding

Specifies which hosts are allowed to submit Dynamic DNS updates to slave zones to be forwarded to the master. The default is { none; }, which means that no update forwarding will be performed. To enable update forwarding, specify allow-update-forwarding { any; };. Specifying values other than { none; } or { any; } is usually counterproductive, since the responsibility for update access control should rest with the master server, not the slaves.

Note that enabling the update forwarding feature on a slave server may expose master servers relying on insecure IP address based access control to attacks; see the section called “Dynamic Update Security” for more details.

allow-v6-synthesis

This option was introduced for the smooth transition from AAAA to A6 and from "nibble labels" to binary labels. However, since both A6 and binary labels were then deprecated, this option was also deprecated. It is now ignored with some warning messages.

allow-transfer

Specifies which hosts are allowed to receive zone transfers from the server. allow-transfer may also be specified in the zone statement, in which case it overrides the options allow-transfer statement. If not specified, the default is to allow transfers to all hosts.

blackhole

Specifies a list of addresses that the server will not accept queries from or use to resolve a query. Queries from these addresses will not be responded to. The default is none.

filter-aaaa

Specifies a list of addresses to which filter-aaaa-on-v4 is applies. The default is any.

no-case-compress

Specifies a list of addresses which require responses to use case-insensitive compression. This ACL can be used when named needs to work with clients that do not comply with the requirement in RFC 1034 to use case-insensitive name comparisons when checking for matching domain names.

If left undefined, the ACL defaults to none: case-insensitive compression will be used for all clients. If the ACL is defined and matches a client, then case will be ignored when compressing domain names in DNS responses sent to that client.

This can result in slightly smaller responses: if a response contains the names "example.com" and "example.COM", case-insensitive compression would treat the second one as a duplicate. It also ensures that the case of the query name exactly matches the case of the owner names of returned records, rather than matching the case of the records entered in the zone file. This allows responses to exactly match the query, which is required by some clients due to incorrect use of case-sensitive comparisons.

Case-insensitive compression is always used in AXFR and IXFR responses, regardless of whether the client matches this ACL.

There are circumstances in which named will not preserve the case of owner names of records: if a zone file defines records of different types with the same name, but the capitalization of the name is different (e.g., "www.example.com/A" and "WWW.EXAMPLE.COM/AAAA"), then all responses for that name will use the first version of the name that was used in the zone file. This limitation may be addressed in a future release. However, domain names specified in the rdata of resource records (i.e., records of type NS, MX, CNAME, etc) will always have their case preserved unless the client matches this ACL.

resolver-query-timeout

The amount of time the resolver will spend attempting to resolve a recursive query before failing. The default and minimum is 10 and the maximum is 30. Setting it to 0 will result in the default being used.

Interfaces

The interfaces and ports that the server will answer queries from may be specified using the listen-on option. listen-on takes an optional port and an address_match_list of IPv4 addresses. (IPv6 addresses are ignored, with a logged warning.) The server will listen on all interfaces allowed by the address match list. If a port is not specified, port 53 will be used.

Multiple listen-on statements are allowed. For example,

listen-on { 5.6.7.8; };
listen-on port 1234 { !1.2.3.4; 1.2/16; };

will enable the name server on port 53 for the IP address 5.6.7.8, and on port 1234 of an address on the machine in net 1.2 that is not 1.2.3.4.

If no listen-on is specified, the server will listen on port 53 on all IPv4 interfaces.

The listen-on-v6 option is used to specify the interfaces and the ports on which the server will listen for incoming queries sent using IPv6. If not specified, the server will listen on port 53 on all IPv6 interfaces.

When

{ any; }

is specified as the address_match_list for the listen-on-v6 option, the server does not bind a separate socket to each IPv6 interface address as it does for IPv4 if the operating system has enough API support for IPv6 (specifically if it conforms to RFC 3493 and RFC 3542). Instead, it listens on the IPv6 wildcard address. If the system only has incomplete API support for IPv6, however, the behavior is the same as that for IPv4.

A list of particular IPv6 addresses can also be specified, in which case the server listens on a separate socket for each specified address, regardless of whether the desired API is supported by the system. IPv4 addresses specified in listen-on-v6 will be ignored, with a logged warning.

Multiple listen-on-v6 options can be used. For example,

listen-on-v6 { any; };
listen-on-v6 port 1234 { !2001:db8::/32; any; };

will enable the name server on port 53 for any IPv6 addresses (with a single wildcard socket), and on port 1234 of IPv6 addresses that is not in the prefix 2001:db8::/32 (with separate sockets for each matched address.)

To make the server not listen on any IPv6 address, use

listen-on-v6 { none; };

Query Address

If the server doesn't know the answer to a question, it will query other name servers. query-source specifies the address and port used for such queries. For queries sent over IPv6, there is a separate query-source-v6 option. If address is * (asterisk) or is omitted, a wildcard IP address (INADDR_ANY) will be used.

If port is * or is omitted, a random port number from a pre-configured range is picked up and will be used for each query. The port range(s) is that specified in the use-v4-udp-ports (for IPv4) and use-v6-udp-ports (for IPv6) options, excluding the ranges specified in the avoid-v4-udp-ports and avoid-v6-udp-ports options, respectively.

The defaults of the query-source and query-source-v6 options are:

query-source address * port *;
query-source-v6 address * port *;

If use-v4-udp-ports or use-v6-udp-ports is unspecified, named will check if the operating system provides a programming interface to retrieve the system's default range for ephemeral ports. If such an interface is available, named will use the corresponding system default range; otherwise, it will use its own defaults:

use-v4-udp-ports { range 1024 65535; };
use-v6-udp-ports { range 1024 65535; };

Note: make sure the ranges be sufficiently large for security. A desirable size depends on various parameters, but we generally recommend it contain at least 16384 ports (14 bits of entropy). Note also that the system's default range when used may be too small for this purpose, and that the range may even be changed while named is running; the new range will automatically be applied when named is reloaded. It is encouraged to configure use-v4-udp-ports and use-v6-udp-ports explicitly so that the ranges are sufficiently large and are reasonably independent from the ranges used by other applications.

Note: the operational configuration where named runs may prohibit the use of some ports. For example, UNIX systems will not allow named running without a root privilege to use ports less than 1024. If such ports are included in the specified (or detected) set of query ports, the corresponding query attempts will fail, resulting in resolution failures or delay. It is therefore important to configure the set of ports that can be safely used in the expected operational environment.

The defaults of the avoid-v4-udp-ports and avoid-v6-udp-ports options are:

avoid-v4-udp-ports {};
avoid-v6-udp-ports {};

Note: BIND 9.5.0 introduced the use-queryport-pool option to support a pool of such random ports, but this option is now obsolete because reusing the same ports in the pool may not be sufficiently secure. For the same reason, it is generally strongly discouraged to specify a particular port for the query-source or query-source-v6 options; it implicitly disables the use of randomized port numbers.

use-queryport-pool

This option is obsolete.

queryport-pool-ports

This option is obsolete.

queryport-pool-updateinterval

This option is obsolete.

Note

The address specified in the query-source option is used for both UDP and TCP queries, but the port applies only to UDP queries. TCP queries always use a random unprivileged port.

Note

Solaris 2.5.1 and earlier does not support setting the source address for TCP sockets.

Note

See also transfer-source and notify-source.

Zone Transfers

BIND has mechanisms in place to facilitate zone transfers and set limits on the amount of load that transfers place on the system. The following options apply to zone transfers.

also-notify

Defines a global list of IP addresses of name servers that are also sent NOTIFY messages whenever a fresh copy of the zone is loaded, in addition to the servers listed in the zone's NS records. This helps to ensure that copies of the zones will quickly converge on stealth servers. Optionally, a port may be specified with each also-notify address to send the notify messages to a port other than the default of 53. An optional TSIG key can also be specified with each address to cause the notify messages to be signed; this can be useful when sending notifies to multiple views. In place of explicit addresses, one or more named masters lists can be used.

If an also-notify list is given in a zone statement, it will override the options also-notify statement. When a zone notify statement is set to no, the IP addresses in the global also-notify list will not be sent NOTIFY messages for that zone. The default is the empty list (no global notification list).

max-transfer-time-in

Inbound zone transfers running longer than this many minutes will be terminated. The default is 120 minutes (2 hours). The maximum value is 28 days (40320 minutes).

max-transfer-idle-in

Inbound zone transfers making no progress in this many minutes will be terminated. The default is 60 minutes (1 hour). The maximum value is 28 days (40320 minutes).

max-transfer-time-out

Outbound zone transfers running longer than this many minutes will be terminated. The default is 120 minutes (2 hours). The maximum value is 28 days (40320 minutes).

max-transfer-idle-out

Outbound zone transfers making no progress in this many minutes will be terminated. The default is 60 minutes (1 hour). The maximum value is 28 days (40320 minutes).

serial-query-rate

Slave servers will periodically query master servers to find out if zone serial numbers have changed. Each such query uses a minute amount of the slave server's network bandwidth. To limit the amount of bandwidth used, BIND 9 limits the rate at which queries are sent. The value of the serial-query-rate option, an integer, is the maximum number of queries sent per second. The default is 20 per second. The lowest possible rate is one per second; when set to zero, it will be silently raised to one.

In addition to controlling the rate SOA refresh queries are issued at, serial-query-rate also controls the rate at which NOTIFY messages are sent from both master and slave zones.

serial-queries

In BIND 8, the serial-queries option set the maximum number of concurrent serial number queries allowed to be outstanding at any given time. BIND 9 does not limit the number of outstanding serial queries and ignores the serial-queries option. Instead, it limits the rate at which the queries are sent as defined using the serial-query-rate option.

transfer-format

Zone transfers can be sent using two different formats, one-answer and many-answers. The transfer-format option is used on the master server to determine which format it sends. one-answer uses one DNS message per resource record transferred. many-answers packs as many resource records as possible into a message. many-answers is more efficient, but is only supported by relatively new slave servers, such as BIND 9, BIND 8.x and BIND 4.9.5 onwards. The many-answers format is also supported by recent Microsoft Windows nameservers. The default is many-answers. transfer-format may be overridden on a per-server basis by using the server statement.

transfers-in

The maximum number of inbound zone transfers that can be running concurrently. The default value is 10. Increasing transfers-in may speed up the convergence of slave zones, but it also may increase the load on the local system.

transfers-out

The maximum number of outbound zone transfers that can be running concurrently. Zone transfer requests in excess of the limit will be refused. The default value is 10.

transfers-per-ns

The maximum number of inbound zone transfers that can be concurrently transferring from a given remote name server. The default value is 2. Increasing transfers-per-ns may speed up the convergence of slave zones, but it also may increase the load on the remote name server. transfers-per-ns may be overridden on a per-server basis by using the transfers phrase of the server statement.

transfer-source

transfer-source determines which local address will be bound to IPv4 TCP connections used to fetch zones transferred inbound by the server. It also determines the source IPv4 address, and optionally the UDP port, used for the refresh queries and forwarded dynamic updates. If not set, it defaults to a system controlled value which will usually be the address of the interface "closest to" the remote end. This address must appear in the remote end's allow-transfer option for the zone being transferred, if one is specified. This statement sets the transfer-source for all zones, but can be overridden on a per-view or per-zone basis by including a transfer-source statement within the view or zone block in the configuration file.

Note

Solaris 2.5.1 and earlier does not support setting the source address for TCP sockets.

transfer-source-v6

The same as transfer-source, except zone transfers are performed using IPv6.

alt-transfer-source

An alternate transfer source if the one listed in transfer-source fails and use-alt-transfer-source is set.

Note

If you do not wish the alternate transfer source to be used, you should set use-alt-transfer-source appropriately and you should not depend upon getting an answer back to the first refresh query.
alt-transfer-source-v6

An alternate transfer source if the one listed in transfer-source-v6 fails and use-alt-transfer-source is set.

use-alt-transfer-source

Use the alternate transfer sources or not. If views are specified this defaults to no otherwise it defaults to yes (for BIND 8 compatibility).

notify-source

notify-source determines which local source address, and optionally UDP port, will be used to send NOTIFY messages. This address must appear in the slave server's masters zone clause or in an allow-notify clause. This statement sets the notify-source for all zones, but can be overridden on a per-zone or per-view basis by including a notify-source statement within the zone or view block in the configuration file.

Note

Solaris 2.5.1 and earlier does not support setting the source address for TCP sockets.

notify-source-v6

Like notify-source, but applies to notify messages sent to IPv6 addresses.

UDP Port Lists

use-v4-udp-ports, avoid-v4-udp-ports, use-v6-udp-ports, and avoid-v6-udp-ports specify a list of IPv4 and IPv6 UDP ports that will be used or not used as source ports for UDP messages. See the section called “Query Address” about how the available ports are determined. For example, with the following configuration

use-v6-udp-ports { range 32768 65535; };
avoid-v6-udp-ports { 40000; range 50000 60000; };

UDP ports of IPv6 messages sent from named will be in one of the following ranges: 32768 to 39999, 40001 to 49999, and 60001 to 65535.

avoid-v4-udp-ports and avoid-v6-udp-ports can be used to prevent named from choosing as its random source port a port that is blocked by your firewall or a port that is used by other applications; if a query went out with a source port blocked by a firewall, the answer would not get by the firewall and the name server would have to query again. Note: the desired range can also be represented only with use-v4-udp-ports and use-v6-udp-ports, and the avoid- options are redundant in that sense; they are provided for backward compatibility and to possibly simplify the port specification.

Operating System Resource Limits

The server's usage of many system resources can be limited. Scaled values are allowed when specifying resource limits. For example, 1G can be used instead of 1073741824 to specify a limit of one gigabyte. unlimited requests unlimited use, or the maximum available amount. default uses the limit that was in force when the server was started. See the description of size_spec in the section called “Configuration File Elements”.

The following options set operating system resource limits for the name server process. Some operating systems don't support some or any of the limits. On such systems, a warning will be issued if the unsupported limit is used.

coresize

The maximum size of a core dump. The default is default.

datasize

The maximum amount of data memory the server may use. The default is default. This is a hard limit on server memory usage. If the server attempts to allocate memory in excess of this limit, the allocation will fail, which may in turn leave the server unable to perform DNS service. Therefore, this option is rarely useful as a way of limiting the amount of memory used by the server, but it can be used to raise an operating system data size limit that is too small by default. If you wish to limit the amount of memory used by the server, use the max-cache-size and recursive-clients options instead.

files

The maximum number of files the server may have open concurrently. The default is unlimited.

stacksize

The maximum amount of stack memory the server may use. The default is default.

Server Resource Limits

The following options set limits on the server's resource consumption that are enforced internally by the server rather than the operating system.

max-ixfr-log-size

This option is obsolete; it is accepted and ignored for BIND 8 compatibility. The option max-journal-size performs a similar function in BIND 9.

max-journal-size

Sets a maximum size for each journal file (see the section called “The journal file”). When the journal file approaches the specified size, some of the oldest transactions in the journal will be automatically removed. The largest permitted value is 2 gigabytes. The default is unlimited, which also means 2 gigabytes. This may also be set on a per-zone basis.

host-statistics-max

In BIND 8, specifies the maximum number of host statistics entries to be kept. Not implemented in BIND 9.

recursive-clients

The maximum number ("hard quota") of simultaneous recursive lookups the server will perform on behalf of clients. The default is 1000. Because each recursing client uses a fair bit of memory (on the order of 20 kilobytes), the value of the recursive-clients option may have to be decreased on hosts with limited memory.

recursive-clients defines a "hard quota" limit for pending recursive clients: when more clients than this are pending, new incoming requests will not be accepted, and for each incoming request a previous pending request will also be dropped.

A "soft quota" is also set. When this lower quota is exceeded, incoming requests are accepted, but for each one, a pending request will be dropped. If recursive-clients is greater than 1000, the soft quota is set to recursive-clients minus 100; otherwise it is set to 90% of recursive-clients.

tcp-clients

The maximum number of simultaneous client TCP connections that the server will accept. The default is 100.

clients-per-query, max-clients-per-query

These set the initial value (minimum) and maximum number of recursive simultaneous clients for any given query (<qname,qtype,qclass>) that the server will accept before dropping additional clients. named will attempt to self tune this value and changes will be logged. The default values are 10 and 100.

This value should reflect how many queries come in for a given name in the time it takes to resolve that name. If the number of queries exceed this value, named will assume that it is dealing with a non-responsive zone and will drop additional queries. If it gets a response after dropping queries, it will raise the estimate. The estimate will then be lowered in 20 minutes if it has remained unchanged.

If clients-per-query is set to zero, then there is no limit on the number of clients per query and no queries will be dropped.

If max-clients-per-query is set to zero, then there is no upper bound other than imposed by recursive-clients.

fetches-per-zone

The maximum number of simultaneous iterative queries to any one domain that the server will permit before blocking new queries for data in or beneath that zone. This value should reflect how many fetches would normally be sent to any one zone in the time it would take to resolve them. It should be smaller than recursive-clients.

When many clients simultaneously query for the same name and type, the clients will all be attached to the same fetch, up to the max-clients-per-query limit, and only one iterative query will be sent. However, when clients are simultaneously querying for different names or types, multiple queries will be sent and max-clients-per-query is not effective as a limit.

Optionally, this value may be followed by the keyword drop or fail, indicating whether queries which exceed the fetch quota for a zone will be dropped with no response, or answered with SERVFAIL. The default is drop.

If fetches-per-zone is set to zero, then there is no limit on the number of fetches per query and no queries will be dropped. The default is zero.

The current list of active fetches can be dumped by running rndc recursing. The list includes the number of active fetches for each domain and the number of queries that have been passed or dropped as a result of the fetches-per-zone limit. (Note: these counters are not cumulative over time; whenever the number of active fetches for a domain drops to zero, the counter for that domain is deleted, and the next time a fetch is sent to that domain, it is recreated with the counters set to zero.)

(Note: This option is only available when BIND is built with configure --enable-fetchlimit.)

fetches-per-server

The maximum number of simultaneous iterative queries that the server will allow to be sent to a single upstream name server before blocking additional queries. This value should reflect how many fetches would normally be sent to any one server in the time it would take to resolve them. It should be smaller than recursive-clients.

Optionally, this value may be followed by the keyword drop or fail, indicating whether queries will be dropped with no response, or answered with SERVFAIL, when all of the servers authoritative for a zone are found to have exceeded the per-server quota. The default is fail.

If fetches-per-server is set to zero, then there is no limit on the number of fetches per query and no queries will be dropped. The default is zero.

The fetches-per-server quota is dynamically adjusted in response to detected congestion. As queries are sent to a server and are either answered or time out, an exponentially weighted moving average is calculated of the ratio of timeouts to responses. If the current average timeout ratio rises above a "high" threshold, then fetches-per-server is reduced for that server. If the timeout ratio drops below a "low" threshold, then fetches-per-server is increased. The fetch-quota-params options can be used to adjust the parameters for this calculation.

(Note: This option is only available when BIND is built with configure --enable-fetchlimit.)

fetch-quota-params

Sets the parameters to use for dynamic resizing of the fetches-per-server quota in response to detected congestion.

The first argument is an integer value indicating how frequently to recalculate the moving average of the ratio of timeouts to responses for each server. The default is 100, meaning we recalculate the average ratio after every 100 queries have either been answered or timed out.

The remaining three arguments represent the "low" threshold (defaulting to a timeout ratio of 0.1), the "high" threshold (defaulting to a timeout ratio of 0.3), and the discount rate for the moving average (defaulting to 0.7). A higher discount rate causes recent events to weigh more heavily when calculating the moving average; a lower discount rate causes past events to weigh more heavily, smoothing out short-term blips in the timeout ratio. These arguments are all fixed-point numbers with precision of 1/100: at most two places after the decimal point are significant.

(Note: This option is only available when BIND is built with configure --enable-fetchlimit.)

reserved-sockets

The number of file descriptors reserved for TCP, stdio, etc. This needs to be big enough to cover the number of interfaces named listens on, tcp-clients as well as to provide room for outgoing TCP queries and incoming zone transfers. The default is 512. The minimum value is 128 and the maximum value is 128 less than maxsockets (-S). This option may be removed in the future.

This option has little effect on Windows.

max-cache-size

The maximum amount of memory to use for the server's cache, in bytes. When the amount of data in the cache reaches this limit, the server will cause records to expire prematurely based on an LRU based strategy so that the limit is not exceeded. The keyword unlimited, or the value 0, will place no limit on cache size; records will be purged from the cache only when their TTLs expire. Any positive values less than 2MB will be ignored and reset to 2MB. In a server with multiple views, the limit applies separately to the cache of each view. The default is unlimited.

tcp-listen-queue

The listen queue depth. The default and minimum is 10. If the kernel supports the accept filter "dataready" this also controls how many TCP connections that will be queued in kernel space waiting for some data before being passed to accept. Nonzero values less than 10 will be silently raised. A value of 0 may also be used; on most platforms this sets the listen queue length to a system-defined default value.

Periodic Task Intervals

cleaning-interval

This interval is effectively obsolete. Previously, the server would remove expired resource records from the cache every cleaning-interval minutes. BIND 9 now manages cache memory in a more sophisticated manner and does not rely on the periodic cleaning any more. Specifying this option therefore has no effect on the server's behavior.

heartbeat-interval

The server will perform zone maintenance tasks for all zones marked as dialup whenever this interval expires. The default is 60 minutes. Reasonable values are up to 1 day (1440 minutes). The maximum value is 28 days (40320 minutes). If set to 0, no zone maintenance for these zones will occur.

interface-interval

The server will scan the network interface list every interface-interval minutes. The default is 60 minutes. The maximum value is 28 days (40320 minutes). If set to 0, interface scanning will only occur when the configuration file is loaded. After the scan, the server will begin listening for queries on any newly discovered interfaces (provided they are allowed by the listen-on configuration), and will stop listening on interfaces that have gone away.

statistics-interval

Name server statistics will be logged every statistics-interval minutes. The default is 60. The maximum value is 28 days (40320 minutes). If set to 0, no statistics will be logged.

Note

Not yet implemented in BIND 9.

Topology

All other things being equal, when the server chooses a name server to query from a list of name servers, it prefers the one that is topologically closest to itself. The topology statement takes an address_match_list and interprets it in a special way. Each top-level list element is assigned a distance. Non-negated elements get a distance based on their position in the list, where the closer the match is to the start of the list, the shorter the distance is between it and the server. A negated match will be assigned the maximum distance from the server. If there is no match, the address will get a distance which is further than any non-negated list element, and closer than any negated element. For example,

topology {
    10/8;
    !1.2.3/24;
    { 1.2/16; 3/8; };
};

will prefer servers on network 10 the most, followed by hosts on network 1.2.0.0 (netmask 255.255.0.0) and network 3, with the exception of hosts on network 1.2.3 (netmask 255.255.255.0), which is preferred least of all.

The default topology is

    topology { localhost; localnets; };

Note

The topology option is not implemented in BIND 9.

The sortlist Statement

The response to a DNS query may consist of multiple resource records (RRs) forming a resource records set (RRset). The name server will normally return the RRs within the RRset in an indeterminate order (but see the rrset-order statement in the section called “RRset Ordering”). The client resolver code should rearrange the RRs as appropriate, that is, using any addresses on the local net in preference to other addresses. However, not all resolvers can do this or are correctly configured. When a client is using a local server, the sorting can be performed in the server, based on the client's address. This only requires configuring the name servers, not all the clients.

The sortlist statement (see below) takes an address_match_list and interprets it even more specifically than the topology statement does (the section called “Topology”). Each top level statement in the sortlist must itself be an explicit address_match_list with one or two elements. The first element (which may be an IP address, an IP prefix, an ACL name or a nested address_match_list) of each top level list is checked against the source address of the query until a match is found.

Once the source address of the query has been matched, if the top level statement contains only one element, the actual primitive element that matched the source address is used to select the address in the response to move to the beginning of the response. If the statement is a list of two elements, then the second element is treated the same as the address_match_list in a topology statement. Each top level element is assigned a distance and the address in the response with the minimum distance is moved to the beginning of the response.

In the following example, any queries received from any of the addresses of the host itself will get responses preferring addresses on any of the locally connected networks. Next most preferred are addresses on the 192.168.1/24 network, and after that either the 192.168.2/24 or 192.168.3/24 network with no preference shown between these two networks. Queries received from a host on the 192.168.1/24 network will prefer other addresses on that network to the 192.168.2/24 and 192.168.3/24 networks. Queries received from a host on the 192.168.4/24 or the 192.168.5/24 network will only prefer other addresses on their directly connected networks.

sortlist {
    // IF the local host
    // THEN first fit on the following nets
    { localhost;
        { localnets;
            192.168.1/24;
            { 192.168.2/24; 192.168.3/24; }; }; };
    // IF on class C 192.168.1 THEN use .1, or .2 or .3
    { 192.168.1/24;
        { 192.168.1/24;
            { 192.168.2/24; 192.168.3/24; }; }; };
    // IF on class C 192.168.2 THEN use .2, or .1 or .3
    { 192.168.2/24;
        { 192.168.2/24;
            { 192.168.1/24; 192.168.3/24; }; }; };
    // IF on class C 192.168.3 THEN use .3, or .1 or .2
    { 192.168.3/24;
        { 192.168.3/24;
            { 192.168.1/24; 192.168.2/24; }; }; };
    // IF .4 or .5 THEN prefer that net
    { { 192.168.4/24; 192.168.5/24; };
    };
};

The following example will give reasonable behavior for the local host and hosts on directly connected networks. It is similar to the behavior of the address sort in BIND 4.9.x. Responses sent to queries from the local host will favor any of the directly connected networks. Responses sent to queries from any other hosts on a directly connected network will prefer addresses on that same network. Responses to other queries will not be sorted.

sortlist {
           { localhost; localnets; };
           { localnets; };
};

RRset Ordering

When multiple records are returned in an answer it may be useful to configure the order of the records placed into the response. The rrset-order statement permits configuration of the ordering of the records in a multiple record response. See also the sortlist statement, the section called “The sortlist Statement”.

An order_spec is defined as follows:

[class class_name] [type type_name] [name "domain_name"] order ordering

If no class is specified, the default is ANY. If no type is specified, the default is ANY. If no name is specified, the default is "*" (asterisk).

The legal values for ordering are:

fixed

Records are returned in the order they are defined in the zone file.

random

Records are returned in some random order.

cyclic

Records are returned in a cyclic round-robin order.

If BIND is configured with the "--enable-fixed-rrset" option at compile time, then the initial ordering of the RRset will match the one specified in the zone file.

For example:

rrset-order {
   class IN type A name "host.example.com" order random;
   order cyclic;
};

will cause any responses for type A records in class IN that have "host.example.com" as a suffix, to always be returned in random order. All other records are returned in cyclic order.

If multiple rrset-order statements appear, they are not combined — the last one applies.

By default, all records are returned in random order.

Note

In this release of BIND 9, the rrset-order statement does not support "fixed" ordering by default. Fixed ordering can be enabled at compile time by specifying "--enable-fixed-rrset" on the "configure" command line.

Tuning

lame-ttl

Sets the number of seconds to cache a lame server indication. 0 disables caching. (This is NOT recommended.) The default is 600 (10 minutes) and the maximum value is 1800 (30 minutes).

Lame-ttl also controls the amount of time DNSSEC validation failures are cached. There is a minimum of 30 seconds applied to bad cache entries if the lame-ttl is set to less than 30 seconds.

max-ncache-ttl

To reduce network traffic and increase performance, the server stores negative answers. max-ncache-ttl is used to set a maximum retention time for these answers in the server in seconds. The default max-ncache-ttl is 10800 seconds (3 hours). max-ncache-ttl cannot exceed 7 days and will be silently truncated to 7 days if set to a greater value.

max-cache-ttl

Sets the maximum time for which the server will cache ordinary (positive) answers. The default is one week (7 days). A value of zero may cause all queries to return SERVFAIL, because of lost caches of intermediate RRsets (such as NS and glue AAAA/A records) in the resolution process.

min-roots

The minimum number of root servers that is required for a request for the root servers to be accepted. The default is 2.

Note

Not implemented in BIND 9.

sig-validity-interval

Specifies the number of days into the future when DNSSEC signatures automatically generated as a result of dynamic updates (the section called “Dynamic Update”) will expire. There is an optional second field which specifies how long before expiry that the signatures will be regenerated. If not specified, the signatures will be regenerated at 1/4 of base interval. The second field is specified in days if the base interval is greater than 7 days otherwise it is specified in hours. The default base interval is 30 days giving a re-signing interval of 7 1/2 days. The maximum values are 10 years (3660 days).

The signature inception time is unconditionally set to one hour before the current time to allow for a limited amount of clock skew.

The sig-validity-interval should be, at least, several multiples of the SOA expire interval to allow for reasonable interaction between the various timer and expiry dates.

sig-signing-nodes

Specify the maximum number of nodes to be examined in each quantum when signing a zone with a new DNSKEY. The default is 100.

sig-signing-signatures

Specify a threshold number of signatures that will terminate processing a quantum when signing a zone with a new DNSKEY. The default is 10.

sig-signing-type

Specify a private RDATA type to be used when generating signing state records. The default is 65534.

It is expected that this parameter may be removed in a future version once there is a standard type.

Signing state records are used to internally by named to track the current state of a zone-signing process, i.e., whether it is still active or has been completed. The records can be inspected using the command rndc signing -list zone. Once named has finished signing a zone with a particular key, the signing state record associated with that key can be removed from the zone by running rndc signing -clear keyid/algorithm zone. To clear all of the completed signing state records for a zone, use rndc signing -clear all zone.

min-refresh-time, max-refresh-time, min-retry-time, max-retry-time

These options control the server's behavior on refreshing a zone (querying for SOA changes) or retrying failed transfers. Usually the SOA values for the zone are used, but these values are set by the master, giving slave server administrators little control over their contents.

These options allow the administrator to set a minimum and maximum refresh and retry time either per-zone, per-view, or globally. These options are valid for slave and stub zones, and clamp the SOA refresh and retry times to the specified values.

The following defaults apply. min-refresh-time 300 seconds, max-refresh-time 2419200 seconds (4 weeks), min-retry-time 500 seconds, and max-retry-time 1209600 seconds (2 weeks).

edns-udp-size

Sets the maximum advertised EDNS UDP buffer size in bytes, to control the size of packets received from authoritative servers in response to recursive queries. Valid values are 512 to 4096 (values outside this range will be silently adjusted to the nearest value within it). The default value is 4096.

The usual reason for setting edns-udp-size to a non-default value is to get UDP answers to pass through broken firewalls that block fragmented packets and/or block UDP DNS packets that are greater than 512 bytes.

When named first queries a remote server, it will advertise a UDP buffer size of 512, as this has the greatest chance of success on the first try.

If the initial response times out, named will try again with plain DNS, and if that is successful, it will be taken as evidence that the server does not support EDNS. After enough failures using EDNS and successes using plain DNS, named will default to plain DNS for future communications with that server. (Periodically, named will send an EDNS query to see if the situation has improved.)

However, if the initial query is successful with EDNS advertising a buffer size of 512, then named will advertise progressively larger buffer sizes on successive queries, until responses begin timing out or edns-udp-size is reached.

The default buffer sizes used by named are 512, 1232, 1432, and 4096, but never exceeding edns-udp-size. (The values 1232 and 1432 are chosen to allow for an IPv4/IPv6 encapsulated UDP message to be sent without fragmentation at the minimum MTU sizes for Ethernet and IPv6 networks.)

max-udp-size

Sets the maximum EDNS UDP message size named will send in bytes. Valid values are 512 to 4096 (values outside this range will be silently adjusted to the nearest value within it). The default value is 4096.

This value applies to responses sent by a server; to set the advertised buffer size in queries, see edns-udp-size.

The usual reason for setting max-udp-size to a non-default value is to get UDP answers to pass through broken firewalls that block fragmented packets and/or block UDP packets that are greater than 512 bytes. This is independent of the advertised receive buffer (edns-udp-size).

Setting this to a low value will encourage additional TCP traffic to the nameserver.

masterfile-format

Specifies the file format of zone files (see the section called “Additional File Formats”). The default value is text, which is the standard textual representation, except for slave zones, in which the default value is raw. Files in other formats than text are typically expected to be generated by the named-compilezone tool, or dumped by named.

Note that when a zone file in a different format than text is loaded, named may omit some of the checks which would be performed for a file in the text format. In particular, check-names checks do not apply for the raw format. This means a zone file in the raw format must be generated with the same check level as that specified in the named configuration file. Also, map format files are loaded directly into memory via memory mapping, with only minimal checking.

This statement sets the masterfile-format for all zones, but can be overridden on a per-zone or per-view basis by including a masterfile-format statement within the zone or view block in the configuration file.

max-recursion-depth

Sets the maximum number of levels of recursion that are permitted at any one time while servicing a recursive query. Resolving a name may require looking up a name server address, which in turn requires resolving another name, etc; if the number of indirections exceeds this value, the recursive query is terminated and returns SERVFAIL. The default is 7.

max-recursion-queries

Sets the maximum number of iterative queries that may be sent while servicing a recursive query. If more queries are sent, the recursive query is terminated and returns SERVFAIL. Queries to look up top level comains such as "com" and "net" and the DNS root zone are exempt from this limitation. The default is 75.

notify-delay

The delay, in seconds, between sending sets of notify messages for a zone. The default is five (5) seconds.

The overall rate that NOTIFY messages are sent for all zones is controlled by serial-query-rate.

max-rsa-exponent-size

The maximum RSA exponent size, in bits, that will be accepted when validating. Valid values are 35 to 4096 bits. The default zero (0) is also accepted and is equivalent to 4096.

prefetch

When a query is received for cached data which is to expire shortly, named can refresh the data from the authoritative server immediately, ensuring that the cache always has an answer available.

The prefetch specifies the "trigger" TTL value at which prefetch of the current query will take place: when a cache record with a lower TTL value is encountered during query processing, it will be refreshed. Valid trigger TTL values are 1 to 10 seconds. Values larger than 10 seconds will be silently reduced to 10. Setting a trigger TTL to zero (0) causes prefetch to be disabled. The default trigger TTL is 2.

An optional second argument specifies the "eligibility" TTL: the smallest original TTL value that will be accepted for a record to be eligible for prefetching. The eligibility TTL must be at least six seconds longer than the trigger TTL; if it isn't, named will silently adjust it upward. The default eligibility TTL is 9.

Built-in server information zones

The server provides some helpful diagnostic information through a number of built-in zones under the pseudo-top-level-domain bind in the CHAOS class. These zones are part of a built-in view (see the section called “view Statement Grammar”) of class CHAOS which is separate from the default view of class IN. Most global configuration options (allow-query, etc) will apply to this view, but some are locally overridden: notify, recursion and allow-new-zones are always set to no, and rate-limit is set to allow three responses per second.

If you need to disable these zones, use the options below, or hide the built-in CHAOS view by defining an explicit view of class CHAOS that matches all clients.

version

The version the server should report via a query of the name version.bind with type TXT, class CHAOS. The default is the real version number of this server. Specifying version none disables processing of the queries.

hostname

The hostname the server should report via a query of the name hostname.bind with type TXT, class CHAOS. This defaults to the hostname of the machine hosting the name server as found by the gethostname() function. The primary purpose of such queries is to identify which of a group of anycast servers is actually answering your queries. Specifying hostname none; disables processing of the queries.

server-id

The ID the server should report when receiving a Name Server Identifier (NSID) query, or a query of the name ID.SERVER with type TXT, class CHAOS. The primary purpose of such queries is to identify which of a group of anycast servers is actually answering your queries. Specifying server-id none; disables processing of the queries. Specifying server-id hostname; will cause named to use the hostname as found by the gethostname() function. The default server-id is none.

Built-in Empty Zones

Named has some built-in empty zones (SOA and NS records only). These are for zones that should normally be answered locally and which queries should not be sent to the Internet's root servers. The official servers which cover these namespaces return NXDOMAIN responses to these queries. In particular, these cover the reverse namespaces for addresses from RFC 1918, RFC 4193, RFC 5737 and RFC 6598. They also include the reverse namespace for IPv6 local address (locally assigned), IPv6 link local addresses, the IPv6 loopback address and the IPv6 unknown address.

Named will attempt to determine if a built-in zone already exists or is active (covered by a forward-only forwarding declaration) and will not create an empty zone in that case.

The current list of empty zones is:

  • 10.IN-ADDR.ARPA
  • 16.172.IN-ADDR.ARPA
  • 17.172.IN-ADDR.ARPA
  • 18.172.IN-ADDR.ARPA
  • 19.172.IN-ADDR.ARPA
  • 20.172.IN-ADDR.ARPA
  • 21.172.IN-ADDR.ARPA
  • 22.172.IN-ADDR.ARPA
  • 23.172.IN-ADDR.ARPA
  • 24.172.IN-ADDR.ARPA
  • 25.172.IN-ADDR.ARPA
  • 26.172.IN-ADDR.ARPA
  • 27.172.IN-ADDR.ARPA
  • 28.172.IN-ADDR.ARPA
  • 29.172.IN-ADDR.ARPA
  • 30.172.IN-ADDR.ARPA
  • 31.172.IN-ADDR.ARPA
  • 168.192.IN-ADDR.ARPA
  • 64.100.IN-ADDR.ARPA
  • 65.100.IN-ADDR.ARPA
  • 66.100.IN-ADDR.ARPA
  • 67.100.IN-ADDR.ARPA
  • 68.100.IN-ADDR.ARPA
  • 69.100.IN-ADDR.ARPA
  • 70.100.IN-ADDR.ARPA
  • 71.100.IN-ADDR.ARPA
  • 72.100.IN-ADDR.ARPA
  • 73.100.IN-ADDR.ARPA
  • 74.100.IN-ADDR.ARPA
  • 75.100.IN-ADDR.ARPA
  • 76.100.IN-ADDR.ARPA
  • 77.100.IN-ADDR.ARPA
  • 78.100.IN-ADDR.ARPA
  • 79.100.IN-ADDR.ARPA
  • 80.100.IN-ADDR.ARPA
  • 81.100.IN-ADDR.ARPA
  • 82.100.IN-ADDR.ARPA
  • 83.100.IN-ADDR.ARPA
  • 84.100.IN-ADDR.ARPA
  • 85.100.IN-ADDR.ARPA
  • 86.100.IN-ADDR.ARPA
  • 87.100.IN-ADDR.ARPA
  • 88.100.IN-ADDR.ARPA
  • 89.100.IN-ADDR.ARPA
  • 90.100.IN-ADDR.ARPA
  • 91.100.IN-ADDR.ARPA
  • 92.100.IN-ADDR.ARPA
  • 93.100.IN-ADDR.ARPA
  • 94.100.IN-ADDR.ARPA
  • 95.100.IN-ADDR.ARPA
  • 96.100.IN-ADDR.ARPA
  • 97.100.IN-ADDR.ARPA
  • 98.100.IN-ADDR.ARPA
  • 99.100.IN-ADDR.ARPA
  • 100.100.IN-ADDR.ARPA
  • 101.100.IN-ADDR.ARPA
  • 102.100.IN-ADDR.ARPA
  • 103.100.IN-ADDR.ARPA
  • 104.100.IN-ADDR.ARPA
  • 105.100.IN-ADDR.ARPA
  • 106.100.IN-ADDR.ARPA
  • 107.100.IN-ADDR.ARPA
  • 108.100.IN-ADDR.ARPA
  • 109.100.IN-ADDR.ARPA
  • 110.100.IN-ADDR.ARPA
  • 111.100.IN-ADDR.ARPA
  • 112.100.IN-ADDR.ARPA
  • 113.100.IN-ADDR.ARPA
  • 114.100.IN-ADDR.ARPA
  • 115.100.IN-ADDR.ARPA
  • 116.100.IN-ADDR.ARPA
  • 117.100.IN-ADDR.ARPA
  • 118.100.IN-ADDR.ARPA
  • 119.100.IN-ADDR.ARPA
  • 120.100.IN-ADDR.ARPA
  • 121.100.IN-ADDR.ARPA
  • 122.100.IN-ADDR.ARPA
  • 123.100.IN-ADDR.ARPA
  • 124.100.IN-ADDR.ARPA
  • 125.100.IN-ADDR.ARPA
  • 126.100.IN-ADDR.ARPA
  • 127.100.IN-ADDR.ARPA
  • 0.IN-ADDR.ARPA
  • 127.IN-ADDR.ARPA
  • 254.169.IN-ADDR.ARPA
  • 2.0.192.IN-ADDR.ARPA
  • 100.51.198.IN-ADDR.ARPA
  • 113.0.203.IN-ADDR.ARPA
  • 255.255.255.255.IN-ADDR.ARPA
  • 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
  • 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
  • 8.B.D.0.1.0.0.2.IP6.ARPA
  • D.F.IP6.ARPA
  • 8.E.F.IP6.ARPA
  • 9.E.F.IP6.ARPA
  • A.E.F.IP6.ARPA
  • B.E.F.IP6.ARPA

Empty zones are settable at the view level and only apply to views of class IN. Disabled empty zones are only inherited from options if there are no disabled empty zones specified at the view level. To override the options list of disabled zones, you can disable the root zone at the view level, for example:

            disable-empty-zone ".";

If you are using the address ranges covered here, you should already have reverse zones covering the addresses you use. In practice this appears to not be the case with many queries being made to the infrastructure servers for names in these spaces. So many in fact that sacrificial servers were needed to be deployed to channel the query load away from the infrastructure servers.

Note

The real parent servers for these zones should disable all empty zone under the parent zone they serve. For the real root servers, this is all built-in empty zones. This will enable them to return referrals to deeper in the tree.
empty-server

Specify what server name will appear in the returned SOA record for empty zones. If none is specified, then the zone's name will be used.

empty-contact

Specify what contact name will appear in the returned SOA record for empty zones. If none is specified, then "." will be used.

empty-zones-enable

Enable or disable all empty zones. By default, they are enabled.

disable-empty-zone

Disable individual empty zones. By default, none are disabled. This option can be specified multiple times.

Additional Section Caching

The additional section cache, also called acache, is an internal cache to improve the response performance of BIND 9. When additional section caching is enabled, BIND 9 will cache an internal short-cut to the additional section content for each answer RR. Note that acache is an internal caching mechanism of BIND 9, and is not related to the DNS caching server function.

Additional section caching does not change the response content (except the RRsets ordering of the additional section, see below), but can improve the response performance significantly. It is particularly effective when BIND 9 acts as an authoritative server for a zone that has many delegations with many glue RRs.

In order to obtain the maximum performance improvement from additional section caching, setting additional-from-cache to no is recommended, since the current implementation of acache does not short-cut of additional section information from the DNS cache data.

One obvious disadvantage of acache is that it requires much more memory for the internal cached data. Thus, if the response performance does not matter and memory consumption is much more critical, the acache mechanism can be disabled by setting acache-enable to no. It is also possible to specify the upper limit of memory consumption for acache by using max-acache-size.

Additional section caching also has a minor effect on the RRset ordering in the additional section. Without acache, cyclic order is effective for the additional section as well as the answer and authority sections. However, additional section caching fixes the ordering when it first caches an RRset for the additional section, and the same ordering will be kept in succeeding responses, regardless of the setting of rrset-order. The effect of this should be minor, however, since an RRset in the additional section typically only contains a small number of RRs (and in many cases it only contains a single RR), in which case the ordering does not matter much.

The following is a summary of options related to acache.

acache-enable

If yes, additional section caching is enabled. The default value is no.

acache-cleaning-interval

The server will remove stale cache entries, based on an LRU based algorithm, every acache-cleaning-interval minutes. The default is 60 minutes. If set to 0, no periodic cleaning will occur.

max-acache-size

The maximum amount of memory in bytes to use for the server's acache. When the amount of data in the acache reaches this limit, the server will clean more aggressively so that the limit is not exceeded. In a server with multiple views, the limit applies separately to the acache of each view. The default is 16M.

Content Filtering

BIND 9 provides the ability to filter out DNS responses from external DNS servers containing certain types of data in the answer section. Specifically, it can reject address (A or AAAA) records if the corresponding IPv4 or IPv6 addresses match the given address_match_list of the deny-answer-addresses option. It can also reject CNAME or DNAME records if the "alias" name (i.e., the CNAME alias or the substituted query name due to DNAME) matches the given namelist of the deny-answer-aliases option, where "match" means the alias name is a subdomain of one of the name_list elements. If the optional namelist is specified with except-from, records whose query name matches the list will be accepted regardless of the filter setting. Likewise, if the alias name is a subdomain of the corresponding zone, the deny-answer-aliases filter will not apply; for example, even if "example.com" is specified for deny-answer-aliases,

www.example.com. CNAME xxx.example.com.

returned by an "example.com" server will be accepted.

In the address_match_list of the deny-answer-addresses option, only ip_addr and ip_prefix are meaningful; any key_id will be silently ignored.

If a response message is rejected due to the filtering, the entire message is discarded without being cached, and a SERVFAIL error will be returned to the client.

This filtering is intended to prevent "DNS rebinding attacks," in which an attacker, in response to a query for a domain name the attacker controls, returns an IP address within your own network or an alias name within your own domain. A naive web browser or script could then serve as an unintended proxy, allowing the attacker to get access to an internal node of your local network that couldn't be externally accessed otherwise. See the paper available at http://portal.acm.org/citation.cfm?id=1315245.1315298 for more details about the attacks.

For example, if you own a domain named "example.net" and your internal network uses an IPv4 prefix 192.0.2.0/24, you might specify the following rules:

deny-answer-addresses { 192.0.2.0/24; } except-from { "example.net"; };
deny-answer-aliases { "example.net"; };

If an external attacker lets a web browser in your local network look up an IPv4 address of "attacker.example.com", the attacker's DNS server would return a response like this:

attacker.example.com. A 192.0.2.1

in the answer section. Since the rdata of this record (the IPv4 address) matches the specified prefix 192.0.2.0/24, this response will be ignored.

On the other hand, if the browser looks up a legitimate internal web server "www.example.net" and the following response is returned to the BIND 9 server

www.example.net. A 192.0.2.2

it will be accepted since the owner name "www.example.net" matches the except-from element, "example.net".

Note that this is not really an attack on the DNS per se. In fact, there is nothing wrong for an "external" name to be mapped to your "internal" IP address or domain name from the DNS point of view. It might actually be provided for a legitimate purpose, such as for debugging. As long as the mapping is provided by the correct owner, it is not possible or does not make sense to detect whether the intent of the mapping is legitimate or not within the DNS. The "rebinding" attack must primarily be protected at the application that uses the DNS. For a large site, however, it may be difficult to protect all possible applications at once. This filtering feature is provided only to help such an operational environment; it is generally discouraged to turn it on unless you are very sure you have no other choice and the attack is a real threat for your applications.

Care should be particularly taken if you want to use this option for addresses within 127.0.0.0/8. These addresses are obviously "internal", but many applications conventionally rely on a DNS mapping from some name to such an address. Filtering out DNS records containing this address spuriously can break such applications.

Response Policy Zone (RPZ) Rewriting

BIND 9 includes a limited mechanism to modify DNS responses for requests analogous to email anti-spam DNS blacklists. Responses can be changed to deny the existence of domains (NXDOMAIN), deny the existence of IP addresses for domains (NODATA), or contain other IP addresses or data.

Response policy zones are named in the response-policy option for the view or among the global options if there is no response-policy option for the view. Response policy zones are ordinary DNS zones containing RRsets that can be queried normally if allowed. It is usually best to restrict those queries with something like allow-query { localhost; };.

A response-policy option can support multiple policy zones. To maximize performance, a radix tree is used to quickly identify response policy zones containing triggers that match the current query. This imposes an upper limit of 32 on the number of policy zones in a single response-policy option; more than that is a configuration error.

Five policy triggers can be encoded in RPZ records.

RPZ-CLIENT-IP

IP records are triggered by the IP address of the DNS client. Client IP address triggers are encoded in records that have owner names that are subdomains of rpz-client-ip relativized to the policy zone origin name and encode an address or address block. IPv4 addresses are represented as prefixlength.B4.B3.B2.B1.rpz-client-ip. The IPv4 prefix length must be between 1 and 32. All four bytes, B4, B3, B2, and B1, must be present. B4 is the decimal value of the least significant byte of the IPv4 address as in IN-ADDR.ARPA.

IPv6 addresses are encoded in a format similar to the standard IPv6 text representation, prefixlength.W8.W7.W6.W5.W4.W3.W2.W1.rpz-client-ip. Each of W8,...,W1 is a one to four digit hexadecimal number representing 16 bits of the IPv6 address as in the standard text representation of IPv6 addresses, but reversed as in IP6.ARPA. (Note that this representation of IPv6 address is different from IP6.ARPA where each hex digit occupies a label.) All 8 words must be present except when one set of consecutive zero words is replaced with .zz. analogous to double colons (::) in standard IPv6 text encodings. The IPv6 prefix length must be between 1 and 128.

QNAME

QNAME policy records are triggered by query names of requests and targets of CNAME records resolved to generate the response. The owner name of a QNAME policy record is the query name relativized to the policy zone.

RPZ-IP

IP triggers are IP addresses in an A or AAAA record in the ANSWER section of a response. They are encoded like client-IP triggers except as subdomains of rpz-ip.

RPZ-NSDNAME

NSDNAME triggers match names of authoritative servers for the query name, a parent of the query name, a CNAME for query name, or a parent of a CNAME. They are encoded as subdomains of rpz-nsdname relativized to the RPZ origin name. NSIP triggers match IP addresses in A and AAAA RRsets for domains that can be checked against NSDNAME policy records.

RPZ-NSIP

NSIP triggers are encoded like IP triggers except as subdomains of rpz-nsip. NSDNAME and NSIP triggers are checked only for names with at least min-ns-dots dots. The default value of min-ns-dots is 1 to exclude top level domains.

The query response is checked against all response policy zones, so two or more policy records can be triggered by a response. Because DNS responses are rewritten according to at most one policy record, a single record encoding an action (other than DISABLED actions) must be chosen. Triggers or the records that encode them are chosen for the rewriting in the following order:

  1. Choose the triggered record in the zone that appears first in the response-policy option.
  2. Prefer CLIENT-IP to QNAME to IP to NSDNAME to NSIP triggers in a single zone.
  3. Among NSDNAME triggers, prefer the trigger that matches the smallest name under the DNSSEC ordering.
  4. Among IP or NSIP triggers, prefer the trigger with the longest prefix.
  5. Among triggers with the same prefix length, prefer the IP or NSIP trigger that matches the smallest IP address.

When the processing of a response is restarted to resolve DNAME or CNAME records and a policy record set has not been triggered, all response policy zones are again consulted for the DNAME or CNAME names and addresses.

RPZ record sets are any types of DNS record except DNAME or DNSSEC that encode actions or responses to individual queries. Any of the policies can be used with any of the triggers. For example, while the TCP-only policy is commonly used with client-IP triggers, it cn be used with any type of trigger to force the use of TCP for responses with owner names in a zone.

PASSTHRU

The whitelist policy is specified by a CNAME whose target is rpz-passthru. It causes the response to not be rewritten and is most often used to "poke holes" in policies for CIDR blocks.

DROP

The blacklist policy is specified by a CNAME whose target is rpz-drop. It causes the response to be discarded. Nothing is sent to the DNS client.

TCP-Only

The "slip" policy is specified by a CNAME whose target is rpz-tcp-only. It changes UDP responses to short, truncated DNS responses that require the DNS client to try again with TCP. It is used to mitigate distributed DNS reflection attacks.

NXDOMAIN

The domain undefined response is encoded by a CNAME whose target is the root domain (.)

NODATA

The empty set of resource records is specified by CNAME whose target is the wildcard top-level domain (*.). It rewrites the response to NODATA or ANCOUNT=1.

Local Data

A set of ordinary DNS records can be used to answer queries. Queries for record types not the set are answered with NODATA.

A special form of local data is a CNAME whose target is a wildcard such as *.example.com. It is used as if were an ordinary CNAME after the astrisk (*) has been replaced with the query name. The purpose for this special form is query logging in the walled garden's authority DNS server.

All of the actions specified in all of the individual records in a policy zone can be overridden with a policy clause in the response-policy option. An organization using a policy zone provided by another organization might use this mechanism to redirect domains to its own walled garden.

GIVEN

The placeholder policy says "do not override but perform the action specified in the zone."

DISABLED

The testing override policy causes policy zone records to do nothing but log what they would have done if the policy zone were not disabled. The response to the DNS query will be written (or not) according to any triggered policy records that are not disabled. Disabled policy zones should appear first, because they will often not be logged if a higher precedence trigger is found first.

PASSTHRU, DROP, TCP-Only, NXDOMAIN, NODATA

override with the corresponding per-record policy.

CNAME domain

causes all RPZ policy records to act as if they were "cname domain" records.

By default, the actions encoded in a response policy zone are applied only to queries that ask for recursion (RD=1). That default can be changed for a single policy zone or all response policy zones in a view with a recursive-only no clause. This feature is useful for serving the same zone files both inside and outside an RFC 1918 cloud and using RPZ to delete answers that would otherwise contain RFC 1918 values on the externally visible name server or view.

Also by default, RPZ actions are applied only to DNS requests that either do not request DNSSEC metadata (DO=0) or when no DNSSEC records are available for request name in the original zone (not the response policy zone). This default can be changed for all response policy zones in a view with a break-dnssec yes clause. In that case, RPZ actions are applied regardless of DNSSEC. The name of the clause option reflects the fact that results rewritten by RPZ actions cannot verify.

No DNS records are needed for a QNAME or Client-IP trigger. The name or IP address itself is sufficient, so in principle the query name need not be recursively resolved. However, not resolving the requested name can leak the fact that response policy rewriting is in use and that the name is listed in a policy zone to operators of servers for listed names. To prevent that information leak, by default any recursion needed for a request is done before any policy triggers are considered. Because listed domains often have slow authoritative servers, this default behavior can cost significant time. The qname-wait-recurse no option overrides that default behavior when recursion cannot change a non-error response. The option does not affect QNAME or client-IP triggers in policy zones listed after other zones containing IP, NSIP and NSDNAME triggers, because those may depend on the A, AAAA, and NS records that would be found during recursive resolution. It also does not affect DNSSEC requests (DO=1) unless break-dnssec yes is in use, because the response would depend on whether or not RRSIG records were found during resolution. Using this option can cause error responses such as SERVFAIL to appear to be rewritten, since no recursion is being done to discover problems at the authoritative server.

The TTL of a record modified by RPZ policies is set from the TTL of the relevant record in policy zone. It is then limited to a maximum value. The max-policy-ttl clause changes that maximum from its default of 5.

For example, you might use this option statement

    response-policy { zone "badlist"; };

and this zone statement

    zone "badlist" {type master; file "master/badlist"; allow-query {none;}; };

with this zone file

$TTL 1H
@                       SOA LOCALHOST. named-mgr.example.com (1 1h 15m 30d 2h)
                        NS  LOCALHOST.

; QNAME policy records.  There are no periods (.) after the owner names.
nxdomain.domain.com     CNAME   .               ; NXDOMAIN policy
*.nxdomain.domain.com   CNAME   .               ; NXDOMAIN policy
nodata.domain.com       CNAME   *.              ; NODATA policy
*.nodata.domain.com     CNAME   *.              ; NODATA policy
bad.domain.com          A       10.0.0.1        ; redirect to a walled garden
                        AAAA    2001:2::1
bzone.domain.com        CNAME   garden.example.com.

; do not rewrite (PASSTHRU) OK.DOMAIN.COM
ok.domain.com           CNAME   rpz-passthru.

; redirect x.bzone.domain.com to x.bzone.domain.com.garden.example.com
*.bzone.domain.com      CNAME   *.garden.example.com.


; IP policy records that rewrite all responses containing A records in 127/8
;       except 127.0.0.1
8.0.0.0.127.rpz-ip      CNAME   .
32.1.0.0.127.rpz-ip     CNAME   rpz-passthru.

; NSDNAME and NSIP policy records
ns.domain.com.rpz-nsdname   CNAME   .
48.zz.2.2001.rpz-nsip       CNAME   .

; blacklist and whitelist some DNS clients
112.zz.2001.rpz-client-ip    CNAME   rpz-drop.
8.0.0.0.127.rpz-client-ip    CNAME   rpz-drop.

; force some DNS clients and responses in the example.com zone to TCP
16.0.0.1.10.rpz-client-ip   CNAME   rpz-tcp-only.
example.com                 CNAME   rpz-tcp-only.
*.example.com               CNAME   rpz-tcp-only.

RPZ can affect server performance. Each configured response policy zone requires the server to perform one to four additional database lookups before a query can be answered. For example, a DNS server with four policy zones, each with all four kinds of response triggers, QNAME, IP, NSIP, and NSDNAME, requires a total of 17 times as many database lookups as a similar DNS server with no response policy zones. A BIND9 server with adequate memory and one response policy zone with QNAME and IP triggers might achieve a maximum queries-per-second rate about 20% lower. A server with four response policy zones with QNAME and IP triggers might have a maximum QPS rate about 50% lower.

Responses rewritten by RPZ are counted in the RPZRewrites statistics.

Response Rate Limiting

Excessive almost identical UDP responses can be controlled by configuring a rate-limit clause in an options or view statement. This mechanism keeps authoritative BIND 9 from being used in amplifying reflection denial of service (DoS) attacks. Short truncated (TC=1) responses can be sent to provide rate-limited responses to legitimate clients within a range of forged, attacked IP addresses. Legitimate clients react to dropped or truncated response by retrying with UDP or with TCP respectively.

This mechanism is intended for authoritative DNS servers. It can be used on recursive servers but can slow applications such as SMTP servers (mail receivers) and HTTP clients (web browsers) that repeatedly request the same domains. When possible, closing "open" recursive servers is better.

Response rate limiting uses a "credit" or "token bucket" scheme. Each combination of identical response and client has a conceptual account that earns a specified number of credits every second. A prospective response debits its account by one. Responses are dropped or truncated while the account is negative. Responses are tracked within a rolling window of time which defaults to 15 seconds, but can be configured with the window option to any value from 1 to 3600 seconds (1 hour). The account cannot become more positive than the per-second limit or more negative than window times the per-second limit. When the specified number of credits for a class of responses is set to 0, those responses are not rate limited.

The notions of "identical response" and "DNS client" for rate limiting are not simplistic. All responses to an address block are counted as if to a single client. The prefix lengths of addresses blocks are specified with ipv4-prefix-length (default 24) and ipv6-prefix-length (default 56).

All non-empty responses for a valid domain name (qname) and record type (qtype) are identical and have a limit specified with responses-per-second (default 0 or no limit). All empty (NODATA) responses for a valid domain, regardless of query type, are identical. Responses in the NODATA class are limited by nodata-per-second (default responses-per-second). Requests for any and all undefined subdomains of a given valid domain result in NXDOMAIN errors, and are identical regardless of query type. They are limited by nxdomains-per-second (default base responses-per-second). This controls some attacks using random names, but can be relaxed or turned off (set to 0) on servers that expect many legitimate NXDOMAIN responses, such as from anti-spam blacklists. Referrals or delegations to the server of a given domain are identical and are limited by referrals-per-second (default responses-per-second).

Responses generated from local wildcards are counted and limited as if they were for the parent domain name. This controls flooding using random.wild.example.com.

All requests that result in DNS errors other than NXDOMAIN, such as SERVFAIL and FORMERR, are identical regardless of requested name (qname) or record type (qtype). This controls attacks using invalid requests or distant, broken authoritative servers. By default the limit on errors is the same as the responses-per-second value, but it can be set separately with errors-per-second.

Many attacks using DNS involve UDP requests with forged source addresses. Rate limiting prevents the use of BIND 9 to flood a network with responses to requests with forged source addresses, but could let a third party block responses to legitimate requests. There is a mechanism that can answer some legitimate requests from a client whose address is being forged in a flood. Setting slip to 2 (its default) causes every other UDP request to be answered with a small truncated (TC=1) response. The small size and reduced frequency, and so lack of amplification, of "slipped" responses make them unattractive for reflection DoS attacks. slip must be between 0 and 10. A value of 0 does not "slip": no truncated responses are sent due to rate limiting, all responses are dropped. A value of 1 causes every response to slip; values between 2 and 10 cause every n'th response to slip. Some error responses including REFUSED and SERVFAIL cannot be replaced with truncated responses and are instead leaked at the slip rate.

(NOTE: Dropped responses from an authoritative server may reduce the difficulty of a third party successfully forging a response to a recursive resolver. The best security against forged responses is for authoritative operators to sign their zones using DNSSEC and for resolver operators to validate the responses. When this is not an option, operators who are more concerned with response integrity than with flood mitigation may consider setting slip to 1, causing all rate-limited responses to be truncated rather than dropped. This reduces the effectiveness of rate-limiting against reflection attacks.)

When the approximate query per second rate exceeds the qps-scale value, then the responses-per-second, errors-per-second, nxdomains-per-second and all-per-second values are reduced by the ratio of the current rate to the qps-scale value. This feature can tighten defenses during attacks. For example, with qps-scale 250; responses-per-second 20; and a total query rate of 1000 queries/second for all queries from all DNS clients including via TCP, then the effective responses/second limit changes to (250/1000)*20 or 5. Responses sent via TCP are not limited but are counted to compute the query per second rate.

Communities of DNS clients can be given their own parameters or no rate limiting by putting rate-limit statements in view statements instead of the global option statement. A rate-limit statement in a view replaces, rather than supplementing, a rate-limit statement among the main options. DNS clients within a view can be exempted from rate limits with the exempt-clients clause.

UDP responses of all kinds can be limited with the all-per-second phrase. This rate limiting is unlike the rate limiting provided by responses-per-second, errors-per-second, and nxdomains-per-second on a DNS server which are often invisible to the victim of a DNS reflection attack. Unless the forged requests of the attack are the same as the legitimate requests of the victim, the victim's requests are not affected. Responses affected by an all-per-second limit are always dropped; the slip value has no effect. An all-per-second limit should be at least 4 times as large as the other limits, because single DNS clients often send bursts of legitimate requests. For example, the receipt of a single mail message can prompt requests from an SMTP server for NS, PTR, A, and AAAA records as the incoming SMTP/TCP/IP connection is considered. The SMTP server can need additional NS, A, AAAA, MX, TXT, and SPF records as it considers the STMP Mail From command. Web browsers often repeatedly resolve the same names that are repeated in HTML <IMG> tags in a page. All-per-second is similar to the rate limiting offered by firewalls but often inferior. Attacks that justify ignoring the contents of DNS responses are likely to be attacks on the DNS server itself. They usually should be discarded before the DNS server spends resources making TCP connections or parsing DNS requests, but that rate limiting must be done before the DNS server sees the requests.

The maximum size of the table used to track requests and rate limit responses is set with max-table-size. Each entry in the table is between 40 and 80 bytes. The table needs approximately as many entries as the number of requests received per second. The default is 20,000. To reduce the cold start of growing the table, min-table-size (default 500) can set the minimum table size. Enable rate-limit category logging to monitor expansions of the table and inform choices for the initial and maximum table size.

Use log-only yes to test rate limiting parameters without actually dropping any requests.

Responses dropped by rate limits are included in the RateDropped and QryDropped statistics. Responses that truncated by rate limits are included in RateSlipped and RespTruncated.

server Statement Grammar

server ip_addr[/prefixlen] {
    [ bogus yes_or_no ; ]
    [ provide-ixfr yes_or_no ; ]
    [ request-ixfr yes_or_no ; ]
    [ request-nsid yes_or_no ; ]
    [ request-sit yes_or_no ; ]
    [ edns yes_or_no ; ]
    [ edns-udp-size number ; ]
    [ nosit-udp-size number ; ]
    [ max-udp-size number ; ]
    [ transfers number ; ]
    [ transfer-format ( one-answer | many-answers ) ; ]]
    [ keys { key_id }; ]
    [ transfer-source (ip4_addr | *) [port ip_port] [dscp ip_dscp] ; ]
    [ transfer-source-v6 (ip6_addr | *) [port ip_port] [dscp ip_dscp] ; ]
    [ notify-source (ip4_addr | *) [port ip_port] [dscp ip_dscp] ; ]
    [ notify-source-v6 (ip6_addr | *) [port ip_port] [dscp ip_dscp] ; ]
    [ query-source [ address ( ip_addr | * ) ]
                  [ port ( ip_port | * ) ] [dscp ip_dscp] ; ]
    [ query-source-v6 [ address ( ip_addr | * ) ]
                     [ port ( ip_port | * ) ] [dscp ip_dscp] ; ]
    [ use-queryport-pool yes_or_no; ]
    [ queryport-pool-ports number; ]
    [ queryport-pool-updateinterval number; ]
};

server Statement Definition and Usage

The server statement defines characteristics to be associated with a remote name server. If a prefix length is specified, then a range of servers is covered. Only the most specific server clause applies regardless of the order in named.conf.

The server statement can occur at the top level of the configuration file or inside a view statement. If a view statement contains one or more server statements, only those apply to the view and any top-level ones are ignored. If a view contains no server statements, any top-level server statements are used as defaults.

If you discover that a remote server is giving out bad data, marking it as bogus will prevent further queries to it. The default value of bogus is no.

The provide-ixfr clause determines whether the local server, acting as master, will respond with an incremental zone transfer when the given remote server, a slave, requests it. If set to yes, incremental transfer will be provided whenever possible. If set to no, all transfers to the remote server will be non-incremental. If not set, the value of the provide-ixfr option in the view or global options block is used as a default.

The request-ixfr clause determines whether the local server, acting as a slave, will request incremental zone transfers from the given remote server, a master. If not set, the value of the request-ixfr option in the view or global options block is used as a default. It may also be set in the zone block and, if set there, it will override the global or view setting for that zone.

IXFR requests to servers that do not support IXFR will automatically fall back to AXFR. Therefore, there is no need to manually list which servers support IXFR and which ones do not; the global default of yes should always work. The purpose of the provide-ixfr and request-ixfr clauses is to make it possible to disable the use of IXFR even when both master and slave claim to support it, for example if one of the servers is buggy and crashes or corrupts data when IXFR is used.

The edns clause determines whether the local server will attempt to use EDNS when communicating with the remote server. The default is yes.

The edns-udp-size option sets the EDNS UDP size that is advertised by named when querying the remote server. Valid values are 512 to 4096 bytes (values outside this range will be silently adjusted to the nearest value within it). This option is useful when you wish to advertise a different value to this server than the value you advertise globally, for example, when there is a firewall at the remote site that is blocking large replies. (Note: Currently, this sets a single UDP size for all packets sent to the server; named will not deviate from this value. This differs from the behavior of edns-udp-size in options or view statements, where it specifies a maximum value. The server statement behavior may be brought into conformance with the options/view behavior in future releases.)

The max-udp-size option sets the maximum EDNS UDP message size named will send. Valid values are 512 to 4096 bytes (values outside this range will be silently adjusted). This option is useful when you know that there is a firewall that is blocking large replies from named.

The nosit-udp-size option sets the maximum size of UDP responses that will be sent to queries without a valid source identity token. The command max-udp-size option may further limit the response size.

The server supports two zone transfer methods. The first, one-answer, uses one DNS message per resource record transferred. many-answers packs as many resource records as possible into a message. many-answers is more efficient, but is only known to be understood by BIND 9, BIND 8.x, and patched versions of BIND 4.9.5. You can specify which method to use for a server with the transfer-format option. If transfer-format is not specified, the transfer-format specified by the options statement will be used.

transfers is used to limit the number of concurrent inbound zone transfers from the specified server. If no transfers clause is specified, the limit is set according to the transfers-per-ns option.

The keys clause identifies a key_id defined by the key statement, to be used for transaction security (TSIG, the section called “TSIG”) when talking to the remote server. When a request is sent to the remote server, a request signature will be generated using the key specified here and appended to the message. A request originating from the remote server is not required to be signed by this key.

Only a single key per server is currently supported.

The transfer-source and transfer-source-v6 clauses specify the IPv4 and IPv6 source address to be used for zone transfer with the remote server, respectively. For an IPv4 remote server, only transfer-source can be specified. Similarly, for an IPv6 remote server, only transfer-source-v6 can be specified. For more details, see the description of transfer-source and transfer-source-v6 in the section called “Zone Transfers”.

The notify-source and notify-source-v6 clauses specify the IPv4 and IPv6 source address to be used for notify messages sent to remote servers, respectively. For an IPv4 remote server, only notify-source can be specified. Similarly, for an IPv6 remote server, only notify-source-v6 can be specified.

The query-source and query-source-v6 clauses specify the IPv4 and IPv6 source address to be used for queries sent to remote servers, respectively. For an IPv4 remote server, only query-source can be specified. Similarly, for an IPv6 remote server, only query-source-v6 can be specified.

The request-nsid clause determines whether the local server will add a NSID EDNS option to requests sent to the server. This overrides request-nsid set at the view or option level.

The request-sit clause determines whether the local server will add a SIT EDNS option to requests sent to the server. This overrides request-sit set at the view or option level. Named may determine that SIT is not supported by the remote server and not add a SIT EDNS option to requests.

statistics-channels Statement Grammar

statistics-channels {
   [ inet ( ip_addr | * ) [ port ip_port ]
   [ allow {  address_match_list  } ]; ]
   [ inet ...; ]
};

statistics-channels Statement Definition and Usage

The statistics-channels statement declares communication channels to be used by system administrators to get access to statistics information of the name server.

This statement intends to be flexible to support multiple communication protocols in the future, but currently only HTTP access is supported. It requires that BIND 9 be compiled with libxml2 and/or json-c (also known as libjson0); the statistics-channels statement is still accepted even if it is built without the library, but any HTTP access will fail with an error.

An inet control channel is a TCP socket listening at the specified ip_port on the specified ip_addr, which can be an IPv4 or IPv6 address. An ip_addr of * (asterisk) is interpreted as the IPv4 wildcard address; connections will be accepted on any of the system's IPv4 addresses. To listen on the IPv6 wildcard address, use an ip_addr of ::.

If no port is specified, port 80 is used for HTTP channels. The asterisk "*" cannot be used for ip_port.

The attempt of opening a statistics channel is restricted by the optional allow clause. Connections to the statistics channel are permitted based on the address_match_list. If no allow clause is present, named accepts connection attempts from any address; since the statistics may contain sensitive internal information, it is highly recommended to restrict the source of connection requests appropriately.

If no statistics-channels statement is present, named will not open any communication channels.

The statistics are available in various formats and views depending on the URI used to access them. For example, if the statistics channel is configured to listen on 127.0.0.1 port 8888, then the statistics are accessible in XML format at http://127.0.0.1:8888/ or http://127.0.0.1:8888/xml. A CSS file is included which can format the XML statistics into tables when viewed with a stylesheet-capable browser, and into charts and graphs using the Google Charts API when using a javascript-capable browser.

Applications that depend on a particular XML schema can request http://127.0.0.1:8888/xml/v2 for version 2 of the statistics XML schema or http://127.0.0.1:8888/xml/v3 for version 3. If the requested schema is supported by the server, then it will respond; if not, it will return a "page not found" error.

Broken-out subsets of the statistics can be viewed at http://127.0.0.1:8888/xml/v3/status (server uptime and last reconfiguration time), http://127.0.0.1:8888/xml/v3/server (server and resolver statistics), http://127.0.0.1:8888/xml/v3/zones (zone statistics), http://127.0.0.1:8888/xml/v3/net (network status and socket statistics), http://127.0.0.1:8888/xml/v3/mem (memory manager statistics), http://127.0.0.1:8888/xml/v3/tasks (task manager statistics).

The full set of statistics can also be read in JSON format at http://127.0.0.1:8888/json, with the broken-out subsets at http://127.0.0.1:8888/json/v1/status (server uptime and last reconfiguration time), http://127.0.0.1:8888/json/v1/server (server and resolver statistics), http://127.0.0.1:8888/json/v1/zones (zone statistics), http://127.0.0.1:8888/json/v1/net (network status and socket statistics), http://127.0.0.1:8888/json/v1/mem (memory manager statistics), http://127.0.0.1:8888/json/v1/tasks (task manager statistics).

trusted-keys Statement Grammar

trusted-keys {
    string number number number string ;
    [ string number number number string ; [...]]
};

trusted-keys Statement Definition and Usage

The trusted-keys statement defines DNSSEC security roots. DNSSEC is described in the section called “DNSSEC”. A security root is defined when the public key for a non-authoritative zone is known, but cannot be securely obtained through DNS, either because it is the DNS root zone or because its parent zone is unsigned. Once a key has been configured as a trusted key, it is treated as if it had been validated and proven secure. The resolver attempts DNSSEC validation on all DNS data in subdomains of a security root.

All keys (and corresponding zones) listed in trusted-keys are deemed to exist regardless of what parent zones say. Similarly for all keys listed in trusted-keys only those keys are used to validate the DNSKEY RRset. The parent's DS RRset will not be used.

The trusted-keys statement can contain multiple key entries, each consisting of the key's domain name, flags, protocol, algorithm, and the Base-64 representation of the key data. Spaces, tabs, newlines and carriage returns are ignored in the key data, so the configuration may be split up into multiple lines.

trusted-keys may be set at the top level of named.conf or within a view. If it is set in both places, they are additive: keys defined at the top level are inherited by all views, but keys defined in a view are only used within that view.

managed-keys Statement Grammar

managed-keys {
    name initial-key flags protocol algorithm key-data ;
    [ name initial-key flags protocol algorithm key-data ; [...]]
};

managed-keys Statement Definition and Usage

The managed-keys statement, like trusted-keys, defines DNSSEC security roots. The difference is that managed-keys can be kept up to date automatically, without intervention from the resolver operator.

Suppose, for example, that a zone's key-signing key was compromised, and the zone owner had to revoke and replace the key. A resolver which had the old key in a trusted-keys statement would be unable to validate this zone any longer; it would reply with a SERVFAIL response code. This would continue until the resolver operator had updated the trusted-keys statement with the new key.

If, however, the zone were listed in a managed-keys statement instead, then the zone owner could add a "stand-by" key to the zone in advance. named would store the stand-by key, and when the original key was revoked, named would be able to transition smoothly to the new key. It would also recognize that the old key had been revoked, and cease using that key to validate answers, minimizing the damage that the compromised key could do.

A managed-keys statement contains a list of the keys to be managed, along with information about how the keys are to be initialized for the first time. The only initialization method currently supported (as of BIND 9.7.0) is initial-key. This means the managed-keys statement must contain a copy of the initializing key. (Future releases may allow keys to be initialized by other methods, eliminating this requirement.)

Consequently, a managed-keys statement appears similar to a trusted-keys, differing in the presence of the second field, containing the keyword initial-key. The difference is, whereas the keys listed in a trusted-keys continue to be trusted until they are removed from named.conf, an initializing key listed in a managed-keys statement is only trusted once: for as long as it takes to load the managed key database and start the RFC 5011 key maintenance process.

The first time named runs with a managed key configured in named.conf, it fetches the DNSKEY RRset directly from the zone apex, and validates it using the key specified in the managed-keys statement. If the DNSKEY RRset is validly signed, then it is used as the basis for a new managed keys database.

From that point on, whenever named runs, it sees the managed-keys statement, checks to make sure RFC 5011 key maintenance has already been initialized for the specified domain, and if so, it simply moves on. The key specified in the managed-keys is not used to validate answers; it has been superseded by the key or keys stored in the managed keys database.

The next time named runs after a name has been removed from the managed-keys statement, the corresponding zone will be removed from the managed keys database, and RFC 5011 key maintenance will no longer be used for that domain.

named only maintains a single managed keys database; consequently, unlike trusted-keys, managed-keys may only be set at the top level of named.conf, not within a view.

In the current implementation, the managed keys database is stored as a master-format zone file called managed-keys.bind. When the key database is changed, the zone is updated. As with any other dynamic zone, changes will be written into a journal file, managed-keys.bind.jnl. They are committed to the master file as soon as possible afterward; in the case of the managed key database, this will usually occur within 30 seconds. So, whenever named is using automatic key maintenance, those two files can be expected to exist in the working directory. (For this reason among others, the working directory should be always be writable by named.)

If the dnssec-validation option is set to auto, named will automatically initialize a managed key for the root zone. Similarly, if the dnssec-lookaside option is set to auto, named will automatically initialize a managed key for the zone dlv.isc.org. In both cases, the key that is used to initialize the key maintenance process is built into named, and can be overridden from bindkeys-file.

view Statement Grammar

view view_name
      [class] {
      match-clients { address_match_list };
      match-destinations { address_match_list };
      match-recursive-only yes_or_no ;
      [ view_option; ...]
      [ zone_statement; ...]
};

view Statement Definition and Usage

The view statement is a powerful feature of BIND 9 that lets a name server answer a DNS query differently depending on who is asking. It is particularly useful for implementing split DNS setups without having to run multiple servers.

Each view statement defines a view of the DNS namespace that will be seen by a subset of clients. A client matches a view if its source IP address matches the address_match_list of the view's match-clients clause and its destination IP address matches the address_match_list of the view's match-destinations clause. If not specified, both match-clients and match-destinations default to matching all addresses. In addition to checking IP addresses match-clients and match-destinations can also take keys which provide an mechanism for the client to select the view. A view can also be specified as match-recursive-only, which means that only recursive requests from matching clients will match that view. The order of the view statements is significant — a client request will be resolved in the context of the first view that it matches.

Zones defined within a view statement will only be accessible to clients that match the view. By defining a zone of the same name in multiple views, different zone data can be given to different clients, for example, "internal" and "external" clients in a split DNS setup.

Many of the options given in the options statement can also be used within a view statement, and then apply only when resolving queries with that view. When no view-specific value is given, the value in the options statement is used as a default. Also, zone options can have default values specified in the view statement; these view-specific defaults take precedence over those in the options statement.

Views are class specific. If no class is given, class IN is assumed. Note that all non-IN views must contain a hint zone, since only the IN class has compiled-in default hints.

If there are no view statements in the config file, a default view that matches any client is automatically created in class IN. Any zone statements specified on the top level of the configuration file are considered to be part of this default view, and the options statement will apply to the default view. If any explicit view statements are present, all zone statements must occur inside view statements.

Here is an example of a typical split DNS setup implemented using view statements:

view "internal" {
      // This should match our internal networks.
      match-clients { 10.0.0.0/8; };

      // Provide recursive service to internal
      // clients only.
      recursion yes;

      // Provide a complete view of the example.com
      // zone including addresses of internal hosts.
      zone "example.com" {
            type master;
            file "example-internal.db";
      };
};

view "external" {
      // Match all clients not matched by the
      // previous view.
      match-clients { any; };

      // Refuse recursive service to external clients.
      recursion no;

      // Provide a restricted view of the example.com
      // zone containing only publicly accessible hosts.
      zone "example.com" {
           type master;
           file "example-external.db";
      };
};

zone Statement Grammar

zone zone_name [class] {
    type master;
    [ allow-query { address_match_list }; ]
    [ allow-query-on { address_match_list }; ]
    [ allow-transfer { address_match_list }; ]
    [ allow-update { address_match_list }; ]
    [ update-check-ksk yes_or_no; ]
    [ dnssec-dnskey-kskonly yes_or_no; ]
    [ dnssec-loadkeys-interval number; ]
    [ update-policy local | { update_policy_rule [...] }; ]
    [ also-notify { ip_addr [port ip_port] [dscp ip_dscp] ;
                  [ ip_addr [port ip_port] [dscp ip_dscp] ; ... ] }; ]
    [ check-names (warn|fail|ignore) ; ]
    [ check-mx (warn|fail|ignore) ; ]
    [ check-wildcard yes_or_no; ]
    [ check-spf ( warn | ignore ); ]
    [ check-integrity yes_or_no ; ]
    [ dialup dialup_option ; ]
    [ file string ; ]
    [ masterfile-format (text|raw|map) ; ]
    [ journal string ; ]
    [ max-journal-size size_spec; ]
    [ forward (only|first) ; ]
    [ forwarders { [ ip_addr [port ip_port] [dscp ip_dscp] ; ... ] }; ]
    [ ixfr-base string ; ]
    [ ixfr-from-differences yes_or_no; ]
    [ ixfr-tmp-file string ; ]
    [ request-ixfr yes_or_no ; ]
    [ maintain-ixfr-base yes_or_no ; ]
    [ max-ixfr-log-size number ; ]
    [ max-transfer-idle-out number ; ]
    [ max-transfer-time-out number ; ]
    [ notify yes_or_no | explicit | master-only ; ]
    [ notify-delay seconds ; ]
    [ notify-to-soa yes_or_no; ]
    [ pubkey number number number string ; ]
    [ notify-source (ip4_addr | *) [port ip_port] [dscp ip_dscp] ; ]
    [ notify-source-v6 (ip6_addr | *) [port ip_port] [dscp ip_dscp] ; ]
    [ zone-statistics full | terse | none; ]
    [ sig-validity-interval number [number] ; ]
    [ sig-signing-nodes number ; ]
    [ sig-signing-signatures number ; ]
    [ sig-signing-type number ; ]
    [ database string ; ]
    [ min-refresh-time number ; ]
    [ max-refresh-time number ; ]
    [ min-retry-time number ; ]
    [ max-retry-time number ; ]
    [ key-directory path_name; ]
    [ auto-dnssec allow|maintain|off; ]
    [ inline-signing yes_or_no; ]
    [ zero-no-soa-ttl yes_or_no ; ]
    [ serial-update-method increment|unixtime; ]
    [ max-zone-ttl number ; ]
};

zone zone_name [class] {
    type slave;
    [ allow-notify { address_match_list }; ]
    [ allow-query { address_match_list }; ]
    [ allow-query-on { address_match_list }; ]
    [ allow-transfer { address_match_list }; ]
    [ allow-update-forwarding { address_match_list }; ]
    [ dnssec-update-mode ( maintain | no-resign ); ]
    [ update-check-ksk yes_or_no; ]
    [ dnssec-dnskey-kskonly yes_or_no; ]
    [ dnssec-loadkeys-interval number; ]
    [ dnssec-secure-to-insecure yes_or_no ; ]
    [ try-tcp-refresh yes_or_no; ]
    [ also-notify [port ip_port] [dscp ip_dscp] { ( masters_list | ip_addr
                              [port ip_port]
                              [dscp ip_dscp]
                              [key key] ) ; [...] }; ]
    [ check-names (warn|fail|ignore) ; ]
    [ dialup dialup_option ; ]
    [ file string ; ]
    [ masterfile-format (text|raw|map) ; ]
    [ journal string ; ]
    [ max-journal-size size_spec; ]
    [ forward (only|first) ; ]
    [ forwarders { [ ip_addr [port ip_port] [dscp ip_dscp] ; ... ] }; ]
    [ ixfr-base string ; ]
    [ ixfr-from-differences yes_or_no; ]
    [ ixfr-tmp-file string ; ]
    [ maintain-ixfr-base yes_or_no ; ]
    [ masters [port ip_port] [dscp ip_dscp] { ( masters_list | ip_addr
                              [port ip_port]
                              [dscp ip_dscp]
                              [key key] ) ; [...] }; ]
    [ max-ixfr-log-size number ; ]
    [ max-transfer-idle-in number ; ]
    [ max-transfer-idle-out number ; ]
    [ max-transfer-time-in number ; ]
    [ max-transfer-time-out number ; ]
    [ notify yes_or_no | explicit | master-only ; ]
    [ notify-delay seconds ; ]
    [ notify-to-soa yes_or_no; ]
    [ pubkey number number number string ; ]
    [ transfer-source (ip4_addr | *) [port ip_port] [dscp ip_dscp] ; ]
    [ transfer-source-v6 (ip6_addr | *) [port ip_port] [dscp ip_dscp] ; ]
    [ alt-transfer-source (ip4_addr | *) [port ip_port] [dscp ip_dscp] ; ]
    [ alt-transfer-source-v6 (ip6_addr | *)
                             [port ip_port]
                             [dscp ip_dscp] ; ]
    [ use-alt-transfer-source yes_or_no; ]
    [ notify-source (ip4_addr | *) [port ip_port] [dscp ip_dscp] ; ]
    [ notify-source-v6 (ip6_addr | *) [port ip_port] [dscp ip_dscp] ; ]
    [ zone-statistics full | terse | none; ]
    [ sig-validity-interval number [number] ; ]
    [ sig-signing-nodes number ; ]
    [ sig-signing-signatures number ; ]
    [ sig-signing-type number ; ]
    [ database string ; ]
    [ min-refresh-time number ; ]
    [ max-refresh-time number ; ]
    [ min-retry-time number ; ]
    [ max-retry-time number ; ]
    [ key-directory path_name; ]
    [ auto-dnssec allow|maintain|off; ]
    [ inline-signing yes_or_no; ]
    [ multi-master yes_or_no ; ]
    [ zero-no-soa-ttl yes_or_no ; ]
};

zone zone_name [class] {
    type hint;
    file string ;
    [ delegation-only yes_or_no ; ]
    [ check-names (warn|fail|ignore) ; ] // Not Implemented.
};

zone zone_name [class] {
    type stub;
    [ allow-query { address_match_list }; ]
    [ allow-query-on { address_match_list }; ]
    [ check-names (warn|fail|ignore) ; ]
    [ dialup dialup_option ; ]
    [ delegation-only yes_or_no ; ]
    [ file string ; ]
    [ masterfile-format (text|raw|map) ; ]
    [ forward (only|first) ; ]
    [ forwarders { [ ip_addr [port ip_port] [dscp ip_dscp] ; ... ] }; ]
    [ masters [port ip_port] [dscp ip_dscp] { ( masters_list | ip_addr
                              [port ip_port]
                              [dscp ip_dscp]
                              [key key] ) ; [...] }; ]
    [ max-transfer-idle-in number ; ]
    [ max-transfer-time-in number ; ]
    [ pubkey number number number string ; ]
    [ transfer-source (ip4_addr | *) [port ip_port] [dscp ip_dscp] ; ]
    [ transfer-source-v6 (ip6_addr | *)
                         [port ip_port] [dscp ip_dscp] ; ]
    [ alt-transfer-source (ip4_addr | *) [port ip_port] [dscp ip_dscp] ; ]
    [ alt-transfer-source-v6 (ip6_addr | *)
                            [port ip_port] [dscp ip_dscp] ; ]
    [ use-alt-transfer-source yes_or_no; ]
    [ zone-statistics yes_or_no ; ]
    [ database string ; ]
    [ min-refresh-time number ; ]
    [ max-refresh-time number ; ]
    [ min-retry-time number ; ]
    [ max-retry-time number ; ]
    [ multi-master yes_or_no ; ]
};

zone zone_name [class] {
    type static-stub;
    [ allow-query { address_match_list }; ]
    [ server-addresses { [ ip_addr ; ... ] }; ]
    [ server-names { [ namelist ] }; ]
    [ zone-statistics yes_or_no ; ]
};

zone zone_name [class] {
    type forward;
    [ forward (only|first) ; ]
    [ forwarders { [ ip_addr [port ip_port] [dscp ip_dscp] ; ... ] }; ]
    [ delegation-only yes_or_no ; ]
};

zone "." [class] {
    type redirect;
    file string ;
    [ masterfile-format (text|raw|map) ; ]
    [ allow-query { address_match_list }; ]
    [ max-zone-ttl number ; ]
};

zone zone_name [class] {
    type delegation-only;
};

zone zone_name [class] {
    [ in-view string ; ]
};

zone Statement Definition and Usage

Zone Types

master

The server has a master copy of the data for the zone and will be able to provide authoritative answers for it.

slave

A slave zone is a replica of a master zone. The masters list specifies one or more IP addresses of master servers that the slave contacts to update its copy of the zone. Masters list elements can also be names of other masters lists. By default, transfers are made from port 53 on the servers; this can be changed for all servers by specifying a port number before the list of IP addresses, or on a per-server basis after the IP address. Authentication to the master can also be done with per-server TSIG keys. If a file is specified, then the replica will be written to this file whenever the zone is changed, and reloaded from this file on a server restart. Use of a file is recommended, since it often speeds server startup and eliminates a needless waste of bandwidth. Note that for large numbers (in the tens or hundreds of thousands) of zones per server, it is best to use a two-level naming scheme for zone filenames. For example, a slave server for the zone example.com might place the zone contents into a file called ex/example.com where ex/ is just the first two letters of the zone name. (Most operating systems behave very slowly if you put 100000 files into a single directory.)

stub

A stub zone is similar to a slave zone, except that it replicates only the NS records of a master zone instead of the entire zone. Stub zones are not a standard part of the DNS; they are a feature specific to the BIND implementation.

Stub zones can be used to eliminate the need for glue NS record in a parent zone at the expense of maintaining a stub zone entry and a set of name server addresses in named.conf. This usage is not recommended for new configurations, and BIND 9 supports it only in a limited way. In BIND 4/8, zone transfers of a parent zone included the NS records from stub children of that zone. This meant that, in some cases, users could get away with configuring child stubs only in the master server for the parent zone. BIND 9 never mixes together zone data from different zones in this way. Therefore, if a BIND 9 master serving a parent zone has child stub zones configured, all the slave servers for the parent zone also need to have the same child stub zones configured.

Stub zones can also be used as a way of forcing the resolution of a given domain to use a particular set of authoritative servers. For example, the caching name servers on a private network using RFC1918 addressing may be configured with stub zones for 10.in-addr.arpa to use a set of internal name servers as the authoritative servers for that domain.

static-stub

A static-stub zone is similar to a stub zone with the following exceptions: the zone data is statically configured, rather than transferred from a master server; when recursion is necessary for a query that matches a static-stub zone, the locally configured data (nameserver names and glue addresses) is always used even if different authoritative information is cached.

Zone data is configured via the server-addresses and server-names zone options.

The zone data is maintained in the form of NS and (if necessary) glue A or AAAA RRs internally, which can be seen by dumping zone databases by rndc dumpdb -all. The configured RRs are considered local configuration parameters rather than public data. Non recursive queries (i.e., those with the RD bit off) to a static-stub zone are therefore prohibited and will be responded with REFUSED.

Since the data is statically configured, no zone maintenance action takes place for a static-stub zone. For example, there is no periodic refresh attempt, and an incoming notify message will be rejected with an rcode of NOTAUTH.

Each static-stub zone is configured with internally generated NS and (if necessary) glue A or AAAA RRs

forward

A "forward zone" is a way to configure forwarding on a per-domain basis. A zone statement of type forward can contain a forward and/or forwarders statement, which will apply to queries within the domain given by the zone name. If no forwarders statement is present or an empty list for forwarders is given, then no forwarding will be done for the domain, canceling the effects of any forwarders in the options statement. Thus if you want to use this type of zone to change the behavior of the global forward option (that is, "forward first" to, then "forward only", or vice versa, but want to use the same servers as set globally) you need to re-specify the global forwarders.

hint

The initial set of root name servers is specified using a "hint zone". When the server starts up, it uses the root hints to find a root name server and get the most recent list of root name servers. If no hint zone is specified for class IN, the server uses a compiled-in default set of root servers hints. Classes other than IN have no built-in defaults hints.

redirect

Redirect zones are used to provide answers to queries when normal resolution would result in NXDOMAIN being returned. Only one redirect zone is supported per view. allow-query can be used to restrict which clients see these answers.

If the client has requested DNSSEC records (DO=1) and the NXDOMAIN response is signed then no substitution will occur.

To redirect all NXDOMAIN responses to 100.100.100.2 and 2001:ffff:ffff::100.100.100.2, one would configure a type redirect zone named ".", with the zone file containing wildcard records that point to the desired addresses: "*. IN A 100.100.100.2" and "*. IN AAAA 2001:ffff:ffff::100.100.100.2".

To redirect all Spanish names (under .ES) one would use similar entries but with the names "*.ES." instead of "*.". To redirect all commercial Spanish names (under COM.ES) one would use wildcard entries called "*.COM.ES.".

Note that the redirect zone supports all possible types; it is not limited to A and AAAA records.

Because redirect zones are not referenced directly by name, they are not kept in the zone lookup table with normal master and slave zones. Consequently, it is not currently possible to use rndc reload zonename to reload a redirect zone. However, when using rndc reload without specifying a zone name, redirect zones will be reloaded along with other zones.

delegation-only

This is used to enforce the delegation-only status of infrastructure zones (e.g. COM, NET, ORG). Any answer that is received without an explicit or implicit delegation in the authority section will be treated as NXDOMAIN. This does not apply to the zone apex. This should not be applied to leaf zones.

delegation-only has no effect on answers received from forwarders.

See caveats in root-delegation-only.

Class

The zone's name may optionally be followed by a class. If a class is not specified, class IN (for Internet), is assumed. This is correct for the vast majority of cases.

The hesiod class is named for an information service from MIT's Project Athena. It is used to share information about various systems databases, such as users, groups, printers and so on. The keyword HS is a synonym for hesiod.

Another MIT development is Chaosnet, a LAN protocol created in the mid-1970s. Zone data for it can be specified with the CHAOS class.

Zone Options

allow-notify

See the description of allow-notify in the section called “Access Control”.

allow-query

See the description of allow-query in the section called “Access Control”.

allow-query-on

See the description of allow-query-on in the section called “Access Control”.

allow-transfer

See the description of allow-transfer in the section called “Access Control”.

allow-update

See the description of allow-update in the section called “Access Control”.

update-policy

Specifies a "Simple Secure Update" policy. See the section called “Dynamic Update Policies”.

allow-update-forwarding

See the description of allow-update-forwarding in the section called “Access Control”.

also-notify

Only meaningful if notify is active for this zone. The set of machines that will receive a DNS NOTIFY message for this zone is made up of all the listed name servers (other than the primary master) for the zone plus any IP addresses specified with also-notify. A port may be specified with each also-notify address to send the notify messages to a port other than the default of 53. A TSIG key may also be specified to cause the NOTIFY to be signed by the given key. also-notify is not meaningful for stub zones. The default is the empty list.

check-names

This option is used to restrict the character set and syntax of certain domain names in master files and/or DNS responses received from the network. The default varies according to zone type. For master zones the default is fail. For slave zones the default is warn. It is not implemented for hint zones.

check-mx

See the description of check-mx in the section called “Boolean Options”.

check-spf

See the description of check-spf in the section called “Boolean Options”.

check-wildcard

See the description of check-wildcard in the section called “Boolean Options”.

check-integrity

See the description of check-integrity in the section called “Boolean Options”.

check-sibling

See the description of check-sibling in the section called “Boolean Options”.

zero-no-soa-ttl

See the description of zero-no-soa-ttl in the section called “Boolean Options”.

update-check-ksk

See the description of update-check-ksk in the section called “Boolean Options”.

dnssec-update-mode

See the description of dnssec-update-mode in the section called “options Statement Definition and Usage”.

dnssec-dnskey-kskonly

See the description of dnssec-dnskey-kskonly in the section called “Boolean Options”.

try-tcp-refresh

See the description of try-tcp-refresh in the section called “Boolean Options”.

database

Specify the type of database to be used for storing the zone data. The string following the database keyword is interpreted as a list of whitespace-delimited words. The first word identifies the database type, and any subsequent words are passed as arguments to the database to be interpreted in a way specific to the database type.

The default is "rbt", BIND 9's native in-memory red-black-tree database. This database does not take arguments.

Other values are possible if additional database drivers have been linked into the server. Some sample drivers are included with the distribution but none are linked in by default.

dialup

See the description of dialup in the section called “Boolean Options”.

delegation-only

The flag only applies to forward, hint and stub zones. If set to yes, then the zone will also be treated as if it is also a delegation-only type zone.

See caveats in root-delegation-only.

forward

Only meaningful if the zone has a forwarders list. The only value causes the lookup to fail after trying the forwarders and getting no answer, while first would allow a normal lookup to be tried.

forwarders

Used to override the list of global forwarders. If it is not specified in a zone of type forward, no forwarding is done for the zone and the global options are not used.

ixfr-base

Was used in BIND 8 to specify the name of the transaction log (journal) file for dynamic update and IXFR. BIND 9 ignores the option and constructs the name of the journal file by appending ".jnl" to the name of the zone file.

ixfr-tmp-file

Was an undocumented option in BIND 8. Ignored in BIND 9.

journal

Allow the default journal's filename to be overridden. The default is the zone's filename with ".jnl" appended. This is applicable to master and slave zones.

max-journal-size

See the description of max-journal-size in the section called “Server Resource Limits”.

max-transfer-time-in

See the description of max-transfer-time-in in the section called “Zone Transfers”.

max-transfer-idle-in

See the description of max-transfer-idle-in in the section called “Zone Transfers”.

max-transfer-time-out

See the description of max-transfer-time-out in the section called “Zone Transfers”.

max-transfer-idle-out

See the description of max-transfer-idle-out in the section called “Zone Transfers”.

notify

See the description of notify in the section called “Boolean Options”.

notify-delay

See the description of notify-delay in the section called “Tuning”.

notify-to-soa

See the description of notify-to-soa in the section called “Boolean Options”.

pubkey

In BIND 8, this option was intended for specifying a public zone key for verification of signatures in DNSSEC signed zones when they are loaded from disk. BIND 9 does not verify signatures on load and ignores the option.

zone-statistics

If yes, the server will keep statistical information for this zone, which can be dumped to the statistics-file defined in the server options.

server-addresses

Only meaningful for static-stub zones. This is a list of IP addresses to which queries should be sent in recursive resolution for the zone. A non empty list for this option will internally configure the apex NS RR with associated glue A or AAAA RRs.

For example, if "example.com" is configured as a static-stub zone with 192.0.2.1 and 2001:db8::1234 in a server-addresses option, the following RRs will be internally configured.

example.com. NS example.com.
example.com. A 192.0.2.1
example.com. AAAA 2001:db8::1234

These records are internally used to resolve names under the static-stub zone. For instance, if the server receives a query for "www.example.com" with the RD bit on, the server will initiate recursive resolution and send queries to 192.0.2.1 and/or 2001:db8::1234.

server-names

Only meaningful for static-stub zones. This is a list of domain names of nameservers that act as authoritative servers of the static-stub zone. These names will be resolved to IP addresses when named needs to send queries to these servers. To make this supplemental resolution successful, these names must not be a subdomain of the origin name of static-stub zone. That is, when "example.net" is the origin of a static-stub zone, "ns.example" and "master.example.com" can be specified in the server-names option, but "ns.example.net" cannot, and will be rejected by the configuration parser.

A non empty list for this option will internally configure the apex NS RR with the specified names. For example, if "example.com" is configured as a static-stub zone with "ns1.example.net" and "ns2.example.net" in a server-names option, the following RRs will be internally configured.

example.com. NS ns1.example.net.
example.com. NS ns2.example.net.

These records are internally used to resolve names under the static-stub zone. For instance, if the server receives a query for "www.example.com" with the RD bit on, the server initiate recursive resolution, resolve "ns1.example.net" and/or "ns2.example.net" to IP addresses, and then send queries to (one or more of) these addresses.

sig-validity-interval

See the description of sig-validity-interval in the section called “Tuning”.

sig-signing-nodes

See the description of sig-signing-nodes in the section called “Tuning”.

sig-signing-signatures

See the description of sig-signing-signatures in the section called “Tuning”.

sig-signing-type

See the description of sig-signing-type in the section called “Tuning”.

transfer-source

See the description of transfer-source in the section called “Zone Transfers”.

transfer-source-v6

See the description of transfer-source-v6 in the section called “Zone Transfers”.

alt-transfer-source

See the description of alt-transfer-source in the section called “Zone Transfers”.

alt-transfer-source-v6

See the description of alt-transfer-source-v6 in the section called “Zone Transfers”.

use-alt-transfer-source

See the description of use-alt-transfer-source in the section called “Zone Transfers”.

notify-source

See the description of notify-source in the section called “Zone Transfers”.

notify-source-v6

See the description of notify-source-v6 in the section called “Zone Transfers”.

min-refresh-time, max-refresh-time, min-retry-time, max-retry-time

See the description in the section called “Tuning”.

ixfr-from-differences

See the description of ixfr-from-differences in the section called “Boolean Options”. (Note that the ixfr-from-differences master and slave choices are not available at the zone level.)

key-directory

See the description of key-directory in the section called “options Statement Definition and Usage”.

auto-dnssec

Zones configured for dynamic DNS may also use this option to allow varying levels of automatic DNSSEC key management. There are three possible settings:

auto-dnssec allow; permits keys to be updated and the zone fully re-signed whenever the user issues the command rndc sign zonename.

auto-dnssec maintain; includes the above, but also automatically adjusts the zone's DNSSEC keys on schedule, according to the keys' timing metadata (see dnssec-keygen(8) and dnssec-settime(8)). The command rndc sign zonename causes named to load keys from the key repository and sign the zone with all keys that are active. rndc loadkeys zonename causes named to load keys from the key repository and schedule key maintenance events to occur in the future, but it does not sign the full zone immediately. Note: once keys have been loaded for a zone the first time, the repository will be searched for changes periodically, regardless of whether rndc loadkeys is used. The recheck interval is defined by dnssec-loadkeys-interval.)

The default setting is auto-dnssec off.

serial-update-method

Zones configured for dynamic DNS may use this option to set the update method that will be used for the zone serial number in the SOA record.

With the default setting of serial-update-method increment;, the SOA serial number will be incremented by one each time the zone is updated.

When set to serial-update-method unixtime;, the SOA serial number will be set to the number of seconds since the UNIX epoch, unless the serial number is already greater than or equal to that value, in which case it is simply incremented by one.

inline-signing

If yes, this enables "bump in the wire" signing of a zone, where a unsigned zone is transferred in or loaded from disk and a signed version of the zone is served, with possibly, a different serial number. This behaviour is disabled by default.

multi-master

See the description of multi-master in the section called “Boolean Options”.

masterfile-format

See the description of masterfile-format in the section called “Tuning”.

max-zone-ttl

See the description of max-zone-ttl in the section called “options Statement Definition and Usage”.

dnssec-secure-to-insecure

See the description of dnssec-secure-to-insecure in the section called “Boolean Options”.

Dynamic Update Policies

BIND 9 supports two alternative methods of granting clients the right to perform dynamic updates to a zone, configured by the allow-update and update-policy option, respectively.

The allow-update clause works the same way as in previous versions of BIND. It grants given clients the permission to update any record of any name in the zone.

The update-policy clause allows more fine-grained control over what updates are allowed. A set of rules is specified, where each rule either grants or denies permissions for one or more names to be updated by one or more identities. If the dynamic update request message is signed (that is, it includes either a TSIG or SIG(0) record), the identity of the signer can be determined.

Rules are specified in the update-policy zone option, and are only meaningful for master zones. When the update-policy statement is present, it is a configuration error for the allow-update statement to be present. The update-policy statement only examines the signer of a message; the source address is not relevant.

There is a pre-defined update-policy rule which can be switched on with the command update-policy local;. Switching on this rule in a zone causes named to generate a TSIG session key and place it in a file, and to allow that key to update the zone. (By default, the file is /var/run/named/session.key, the key name is "local-ddns" and the key algorithm is HMAC-SHA256, but these values are configurable with the session-keyfile, session-keyname and session-keyalg options, respectively).

A client running on the local system, and with appropriate permissions, may read that file and use the key to sign update requests. The zone's update policy will be set to allow that key to change any record within the zone. Assuming the key name is "local-ddns", this policy is equivalent to:

update-policy { grant local-ddns zonesub any; };
            

The command nsupdate -l sends update requests to localhost, and signs them using the session key.

Other rule definitions look like this:

( grant | deny ) identity nametype [ name ] [ types ]

Each rule grants or denies privileges. Once a message has successfully matched a rule, the operation is immediately granted or denied and no further rules are examined. A rule is matched when the signer matches the identity field, the name matches the name field in accordance with the nametype field, and the type matches the types specified in the type field.

No signer is required for tcp-self or 6to4-self however the standard reverse mapping / prefix conversion must match the identity field.

The identity field specifies a name or a wildcard name. Normally, this is the name of the TSIG or SIG(0) key used to sign the update request. When a TKEY exchange has been used to create a shared secret, the identity of the shared secret is the same as the identity of the key used to authenticate the TKEY exchange. TKEY is also the negotiation method used by GSS-TSIG, which establishes an identity that is the Kerberos principal of the client, such as "user@host.domain". When the identity field specifies a wildcard name, it is subject to DNS wildcard expansion, so the rule will apply to multiple identities. The identity field must contain a fully-qualified domain name.

For nametypes krb5-self, ms-self, krb5-subdomain, and ms-subdomain the identity field specifies the Windows or Kerberos realm of the machine belongs to.

The nametype field has 13 values: name, subdomain, wildcard, self, selfsub, selfwild, krb5-self, ms-self, krb5-subdomain, ms-subdomain, tcp-self, 6to4-self, zonesub, and external.

name

Exact-match semantics. This rule matches when the name being updated is identical to the contents of the name field.

subdomain

This rule matches when the name being updated is a subdomain of, or identical to, the contents of the name field.

zonesub

This rule is similar to subdomain, except that it matches when the name being updated is a subdomain of the zone in which the update-policy statement appears. This obviates the need to type the zone name twice, and enables the use of a standard update-policy statement in multiple zones without modification.

When this rule is used, the name field is omitted.

wildcard

The name field is subject to DNS wildcard expansion, and this rule matches when the name being updated name is a valid expansion of the wildcard.

self

This rule matches when the name being updated matches the contents of the identity field. The name field is ignored, but should be the same as the identity field. The self nametype is most useful when allowing using one key per name to update, where the key has the same name as the name to be updated. The identity would be specified as * (an asterisk) in this case.

selfsub

This rule is similar to self except that subdomains of self can also be updated.

selfwild

This rule is similar to self except that only subdomains of self can be updated.

ms-self

This rule takes a Windows machine principal (machine$@REALM) for machine in REALM and and converts it machine.realm allowing the machine to update machine.realm. The REALM to be matched is specified in the identity field.

ms-subdomain

This rule takes a Windows machine principal (machine$@REALM) for machine in REALM and converts it to machine.realm allowing the machine to update subdomains of machine.realm. The REALM to be matched is specified in the identity field.

krb5-self

This rule takes a Kerberos machine principal (host/machine@REALM) for machine in REALM and and converts it machine.realm allowing the machine to update machine.realm. The REALM to be matched is specified in the identity field.

krb5-subdomain

This rule takes a Kerberos machine principal (host/machine@REALM) for machine in REALM and converts it to machine.realm allowing the machine to update subdomains of machine.realm. The REALM to be matched is specified in the identity field.

tcp-self

Allow updates that have been sent via TCP and for which the standard mapping from the initiating IP address into the IN-ADDR.ARPA and IP6.ARPA namespaces match the name to be updated.

Note

It is theoretically possible to spoof these TCP sessions.

6to4-self

Allow the 6to4 prefix to be update by any TCP connection from the 6to4 network or from the corresponding IPv4 address. This is intended to allow NS or DNAME RRsets to be added to the reverse tree.

Note

It is theoretically possible to spoof these TCP sessions.

external

This rule allows named to defer the decision of whether to allow a given update to an external daemon.

The method of communicating with the daemon is specified in the identity field, the format of which is "local:path", where path is the location of a UNIX-domain socket. (Currently, "local" is the only supported mechanism.)

Requests to the external daemon are sent over the UNIX-domain socket as datagrams with the following format:

   Protocol version number (4 bytes, network byte order, currently 1)
   Request length (4 bytes, network byte order)
   Signer (null-terminated string)
   Name (null-terminated string)
   TCP source address (null-terminated string)
   Rdata type (null-terminated string)
   Key (null-terminated string)
   TKEY token length (4 bytes, network byte order)
   TKEY token (remainder of packet)

The daemon replies with a four-byte value in network byte order, containing either 0 or 1; 0 indicates that the specified update is not permitted, and 1 indicates that it is.

In all cases, the name field must specify a fully-qualified domain name.

If no types are explicitly specified, this rule matches all types except RRSIG, NS, SOA, NSEC and NSEC3. Types may be specified by name, including "ANY" (ANY matches all types except NSEC and NSEC3, which can never be updated). Note that when an attempt is made to delete all records associated with a name, the rules are checked for each existing record type.

Multiple views

When multiple views are in use, a zone may be referenced by more than one of them. Often, the views will contain different zones with the same name, allowing different clients to receive different answers for the same queries. At times, however, it is desirable for multiple views to contain identical zones. The in-view zone option provides an efficient way to do this: it allows a view to reference a zone that was defined in a previously configured view. Example:

view internal {
    match-clients { 10/8; };

    zone example.com {
        type master;
        file "example-external.db";
    };
};

view external {
    match-clients { any; };

    zone example.com {
        in-view internal;
    };
};
            

An in-view option cannot refer to a view that is configured later in the configuration file.

A zone statement which uses the in-view option may not use any other options with the exception of forward and forwarders. (These options control the behavior of the containing view, rather than changing the zone object itself.)

Zone level acls (e.g. allow-query, allow-transfer) and other configuration details of the zone are all set in the view the referenced zone is defined in. Care need to be taken to ensure that acls are wide enough for all views referencing the zone.

An in-view zone cannot be used as a response policy zone.

An in-view zone is not intended to reference a forward zone.

Zone File

Types of Resource Records and When to Use Them

This section, largely borrowed from RFC 1034, describes the concept of a Resource Record (RR) and explains when each is used. Since the publication of RFC 1034, several new RRs have been identified and implemented in the DNS. These are also included.

Resource Records

A domain name identifies a node. Each node has a set of resource information, which may be empty. The set of resource information associated with a particular name is composed of separate RRs. The order of RRs in a set is not significant and need not be preserved by name servers, resolvers, or other parts of the DNS. However, sorting of multiple RRs is permitted for optimization purposes, for example, to specify that a particular nearby server be tried first. See the section called “The sortlist Statement” and the section called “RRset Ordering”.

The components of a Resource Record are:

owner name

The domain name where the RR is found.

type

An encoded 16-bit value that specifies the type of the resource record.

TTL

The time-to-live of the RR. This field is a 32-bit integer in units of seconds, and is primarily used by resolvers when they cache RRs. The TTL describes how long a RR can be cached before it should be discarded.

class

An encoded 16-bit value that identifies a protocol family or instance of a protocol.

RDATA

The resource data. The format of the data is type (and sometimes class) specific.

The following are types of valid RRs:

A

A host address. In the IN class, this is a 32-bit IP address. Described in RFC 1035.

AAAA

IPv6 address. Described in RFC 1886.

A6

IPv6 address. This can be a partial address (a suffix) and an indirection to the name where the rest of the address (the prefix) can be found. Experimental. Described in RFC 2874.

AFSDB

Location of AFS database servers. Experimental. Described in RFC 1183.

APL

Address prefix list. Experimental. Described in RFC 3123.

ATMA

ATM Address.

CAA

Identifies which Certificate Authorities can issue certificates for this domain and what rules they need to follow when doing so. Defined in RFC 6844.

CDNSKEY

Identifies which DNSKEY records should be published as DS records in the parent zone.

CDS

Contains the set of DS records that should be published by the parent zone.

CERT

Holds a digital certificate. Described in RFC 2538.

CNAME

Identifies the canonical name of an alias. Described in RFC 1035.

DHCID

Is used for identifying which DHCP client is associated with this name. Described in RFC 4701.

DLV

A DNS Look-aside Validation record which contains the records that are used as trust anchors for zones in a DLV namespace. Described in RFC 4431.

DNAME

Replaces the domain name specified with another name to be looked up, effectively aliasing an entire subtree of the domain name space rather than a single record as in the case of the CNAME RR. Described in RFC 2672.

DNSKEY

Stores a public key associated with a signed DNS zone. Described in RFC 4034.

DS

Stores the hash of a public key associated with a signed DNS zone. Described in RFC 4034.

EID

End Point Identifier.

EUI48

A 48-bit EUI address. Described in RFC 7043.

EUI64

A 64-bit EUI address. Described in RFC 7043.

GID

Reserved.

GPOS

Specifies the global position. Superseded by LOC.

HINFO

Identifies the CPU and OS used by a host. Described in RFC 1035.

HIP

Host Identity Protocol Address. Described in RFC 5205.

IPSECKEY

Provides a method for storing IPsec keying material in DNS. Described in RFC 4025.

ISDN

Representation of ISDN addresses. Experimental. Described in RFC 1183.

KEY

Stores a public key associated with a DNS name. Used in original DNSSEC; replaced by DNSKEY in DNSSECbis, but still used with SIG(0). Described in RFCs 2535 and 2931.

KX

Identifies a key exchanger for this DNS name. Described in RFC 2230.

L32

Holds 32-bit Locator values for Identifier-Locator Network Protocol. Described in RFC 6742.

L64

Holds 64-bit Locator values for Identifier-Locator Network Protocol. Described in RFC 6742.

LOC

For storing GPS info. Described in RFC 1876. Experimental.

LP

Identifier-Locator Network Protocol. Described in RFC 6742.

MB

Mail Box. Historical.

MD

Mail Destination. Historical.

MF

Mail Forwarder. Historical.

MG

Mail Group. Historical.

MINFO

Mail Information.

MR

Mail Rename. Historical.

MX

Identifies a mail exchange for the domain with a 16-bit preference value (lower is better) followed by the host name of the mail exchange. Described in RFC 974, RFC 1035.

NAPTR

Name authority pointer. Described in RFC 2915.

NID

Holds values for Node Identifiers in Identifier-Locator Network Protocol. Described in RFC 6742.

NIMLOC

Nimrod Locator.

NSAP

A network service access point. Described in RFC 1706.

NSAP-PTR

Historical.

NS

The authoritative name server for the domain. Described in RFC 1035.

NSEC

Used in DNSSECbis to securely indicate that RRs with an owner name in a certain name interval do not exist in a zone and indicate what RR types are present for an existing name. Described in RFC 4034.

NSEC3

Used in DNSSECbis to securely indicate that RRs with an owner name in a certain name interval do not exist in a zone and indicate what RR types are present for an existing name. NSEC3 differs from NSEC in that it prevents zone enumeration but is more computationally expensive on both the server and the client than NSEC. Described in RFC 5155.

NSEC3PARAM

Used in DNSSECbis to tell the authoritative server which NSEC3 chains are available to use. Described in RFC 5155.

NULL

This is an opaque container.

NXT

Used in DNSSEC to securely indicate that RRs with an owner name in a certain name interval do not exist in a zone and indicate what RR types are present for an existing name. Used in original DNSSEC; replaced by NSEC in DNSSECbis. Described in RFC 2535.

OPENPGPKEY

Used to hold an OPENPGPKEY.

PTR

A pointer to another part of the domain name space. Described in RFC 1035.

PX

Provides mappings between RFC 822 and X.400 addresses. Described in RFC 2163.

RP

Information on persons responsible for the domain. Experimental. Described in RFC 1183.

RRSIG

Contains DNSSECbis signature data. Described in RFC 4034.

RT

Route-through binding for hosts that do not have their own direct wide area network addresses. Experimental. Described in RFC 1183.

SIG

Contains DNSSEC signature data. Used in original DNSSEC; replaced by RRSIG in DNSSECbis, but still used for SIG(0). Described in RFCs 2535 and 2931.

SOA

Identifies the start of a zone of authority. Described in RFC 1035.

SPF

Contains the Sender Policy Framework information for a given email domain. Described in RFC 4408.

SRV

Information about well known network services (replaces WKS). Described in RFC 2782.

SSHFP

Provides a way to securely publish a secure shell key's fingerprint. Described in RFC 4255.

TLSA

Transport Layer Security Certificate Association. Described in RFC 6698.

TXT

Text records. Described in RFC 1035.

UID

Reserved.

UINFO

Reserved.

UNSPEC

Reserved. Historical.

URI

Holds a URI. Described in RFC 7553.

WKS

Information about which well known network services, such as SMTP, that a domain supports. Historical.

X25

Representation of X.25 network addresses. Experimental. Described in RFC 1183.

The following classes of resource records are currently valid in the DNS:

IN

The Internet.

CH

Chaosnet, a LAN protocol created at MIT in the mid-1970s. Rarely used for its historical purpose, but reused for BIND's built-in server information zones, e.g., version.bind.

HS

Hesiod, an information service developed by MIT's Project Athena. It is used to share information about various systems databases, such as users, groups, printers and so on.

The owner name is often implicit, rather than forming an integral part of the RR. For example, many name servers internally form tree or hash structures for the name space, and chain RRs off nodes. The remaining RR parts are the fixed header (type, class, TTL) which is consistent for all RRs, and a variable part (RDATA) that fits the needs of the resource being described.

The meaning of the TTL field is a time limit on how long an RR can be kept in a cache. This limit does not apply to authoritative data in zones; it is also timed out, but by the refreshing policies for the zone. The TTL is assigned by the administrator for the zone where the data originates. While short TTLs can be used to minimize caching, and a zero TTL prohibits caching, the realities of Internet performance suggest that these times should be on the order of days for the typical host. If a change can be anticipated, the TTL can be reduced prior to the change to minimize inconsistency during the change, and then increased back to its former value following the change.

The data in the RDATA section of RRs is carried as a combination of binary strings and domain names. The domain names are frequently used as "pointers" to other data in the DNS.

Textual expression of RRs

RRs are represented in binary form in the packets of the DNS protocol, and are usually represented in highly encoded form when stored in a name server or resolver. In the examples provided in RFC 1034, a style similar to that used in master files was employed in order to show the contents of RRs. In this format, most RRs are shown on a single line, although continuation lines are possible using parentheses.

The start of the line gives the owner of the RR. If a line begins with a blank, then the owner is assumed to be the same as that of the previous RR. Blank lines are often included for readability.

Following the owner, we list the TTL, type, and class of the RR. Class and type use the mnemonics defined above, and TTL is an integer before the type field. In order to avoid ambiguity in parsing, type and class mnemonics are disjoint, TTLs are integers, and the type mnemonic is always last. The IN class and TTL values are often omitted from examples in the interests of clarity.

The resource data or RDATA section of the RR are given using knowledge of the typical representation for the data.

For example, we might show the RRs carried in a message as:

ISI.EDU.

MX

10 VENERA.ISI.EDU.

MX

10 VAXA.ISI.EDU

VENERA.ISI.EDU

A

128.9.0.32

A

10.1.0.52

VAXA.ISI.EDU

A

10.2.0.27

A

128.9.0.33

The MX RRs have an RDATA section which consists of a 16-bit number followed by a domain name. The address RRs use a standard IP address format to contain a 32-bit internet address.

The above example shows six RRs, with two RRs at each of three domain names.

Similarly we might see:

XX.LCS.MIT.EDU.

IN A

10.0.0.44

 

CH A

MIT.EDU. 2420

This example shows two addresses for XX.LCS.MIT.EDU, each of a different class.

Discussion of MX Records

As described above, domain servers store information as a series of resource records, each of which contains a particular piece of information about a given domain name (which is usually, but not always, a host). The simplest way to think of a RR is as a typed pair of data, a domain name matched with a relevant datum, and stored with some additional type information to help systems determine when the RR is relevant.

MX records are used to control delivery of email. The data specified in the record is a priority and a domain name. The priority controls the order in which email delivery is attempted, with the lowest number first. If two priorities are the same, a server is chosen randomly. If no servers at a given priority are responding, the mail transport agent will fall back to the next largest priority. Priority numbers do not have any absolute meaning — they are relevant only respective to other MX records for that domain name. The domain name given is the machine to which the mail will be delivered. It must have an associated address record (A or AAAA) — CNAME is not sufficient.

For a given domain, if there is both a CNAME record and an MX record, the MX record is in error, and will be ignored. Instead, the mail will be delivered to the server specified in the MX record pointed to by the CNAME. For example:

example.com.

IN

MX

10

mail.example.com.

IN

MX

10

mail2.example.com.

IN

MX

20

mail.backup.org.

mail.example.com.

IN

A

10.0.0.1

mail2.example.com.

IN

A

10.0.0.2

Mail delivery will be attempted to mail.example.com and mail2.example.com (in any order), and if neither of those succeed, delivery to mail.backup.org will be attempted.

Setting TTLs

The time-to-live of the RR field is a 32-bit integer represented in units of seconds, and is primarily used by resolvers when they cache RRs. The TTL describes how long a RR can be cached before it should be discarded. The following three types of TTL are currently used in a zone file.

SOA

The last field in the SOA is the negative caching TTL. This controls how long other servers will cache no-such-domain (NXDOMAIN) responses from you.

The maximum time for negative caching is 3 hours (3h).

$TTL

The $TTL directive at the top of the zone file (before the SOA) gives a default TTL for every RR without a specific TTL set.

RR TTLs

Each RR can have a TTL as the second field in the RR, which will control how long other servers can cache it.

All of these TTLs default to units of seconds, though units can be explicitly specified, for example, 1h30m.

Inverse Mapping in IPv4

Reverse name resolution (that is, translation from IP address to name) is achieved by means of the in-addr.arpa domain and PTR records. Entries in the in-addr.arpa domain are made in least-to-most significant order, read left to right. This is the opposite order to the way IP addresses are usually written. Thus, a machine with an IP address of 10.1.2.3 would have a corresponding in-addr.arpa name of 3.2.1.10.in-addr.arpa. This name should have a PTR resource record whose data field is the name of the machine or, optionally, multiple PTR records if the machine has more than one name. For example, in the [example.com] domain:

$ORIGIN

2.1.10.in-addr.arpa

3

IN PTR foo.example.com.

Note

The $ORIGIN lines in the examples are for providing context to the examples only — they do not necessarily appear in the actual usage. They are only used here to indicate that the example is relative to the listed origin.

Other Zone File Directives

The Master File Format was initially defined in RFC 1035 and has subsequently been extended. While the Master File Format itself is class independent all records in a Master File must be of the same class.

Master File Directives include $ORIGIN, $INCLUDE, and $TTL.

The @ (at-sign)

When used in the label (or name) field, the asperand or at-sign (@) symbol represents the current origin. At the start of the zone file, it is the <zone_name> (followed by trailing dot).

The $ORIGIN Directive

Syntax: $ORIGIN domain-name [comment]

$ORIGIN sets the domain name that will be appended to any unqualified records. When a zone is first read in there is an implicit $ORIGIN <zone_name>. (followed by trailing dot). The current $ORIGIN is appended to the domain specified in the $ORIGIN argument if it is not absolute.

$ORIGIN example.com.
WWW     CNAME   MAIN-SERVER

is equivalent to

WWW.EXAMPLE.COM. CNAME MAIN-SERVER.EXAMPLE.COM.

The $INCLUDE Directive

Syntax: $INCLUDE filename [ origin ] [ comment ]

Read and process the file filename as if it were included into the file at this point. If origin is specified the file is processed with $ORIGIN set to that value, otherwise the current $ORIGIN is used.

The origin and the current domain name revert to the values they had prior to the $INCLUDE once the file has been read.

Note

RFC 1035 specifies that the current origin should be restored after an $INCLUDE, but it is silent on whether the current domain name should also be restored. BIND 9 restores both of them. This could be construed as a deviation from RFC 1035, a feature, or both.

The $TTL Directive

Syntax: $TTL default-ttl [ comment ]

Set the default Time To Live (TTL) for subsequent records with undefined TTLs. Valid TTLs are of the range 0-2147483647 seconds.

$TTL is defined in RFC 2308.

BIND Master File Extension: the $GENERATE Directive

Syntax: $GENERATE range lhs [ttl] [class] type rhs [comment]

$GENERATE is used to create a series of resource records that only differ from each other by an iterator. $GENERATE can be used to easily generate the sets of records required to support sub /24 reverse delegations described in RFC 2317: Classless IN-ADDR.ARPA delegation.

$ORIGIN 0.0.192.IN-ADDR.ARPA.
$GENERATE 1-2 @ NS SERVER$.EXAMPLE.
$GENERATE 1-127 $ CNAME $.0

is equivalent to

0.0.0.192.IN-ADDR.ARPA. NS SERVER1.EXAMPLE.
0.0.0.192.IN-ADDR.ARPA. NS SERVER2.EXAMPLE.
1.0.0.192.IN-ADDR.ARPA. CNAME 1.0.0.0.192.IN-ADDR.ARPA.
2.0.0.192.IN-ADDR.ARPA. CNAME 2.0.0.0.192.IN-ADDR.ARPA.
...
127.0.0.192.IN-ADDR.ARPA. CNAME 127.0.0.0.192.IN-ADDR.ARPA.

Generate a set of A and MX records. Note the MX's right hand side is a quoted string. The quotes will be stripped when the right hand side is processed.

$ORIGIN EXAMPLE.
$GENERATE 1-127 HOST-$ A 1.2.3.$
$GENERATE 1-127 HOST-$ MX "0 ."

is equivalent to

HOST-1.EXAMPLE.   A  1.2.3.1
HOST-1.EXAMPLE.   MX 0 .
HOST-2.EXAMPLE.   A  1.2.3.2
HOST-2.EXAMPLE.   MX 0 .
HOST-3.EXAMPLE.   A  1.2.3.3
HOST-3.EXAMPLE.   MX 0 .
...
HOST-127.EXAMPLE. A  1.2.3.127
HOST-127.EXAMPLE. MX 0 .

range

This can be one of two forms: start-stop or start-stop/step. If the first form is used, then step is set to 1. start, stop and step must be positive integers between 0 and (2^31)-1. start must not be larger than stop.

lhs

This describes the owner name of the resource records to be created. Any single $ (dollar sign) symbols within the lhs string are replaced by the iterator value. To get a $ in the output, you need to escape the $ using a backslash \, e.g. \$. The $ may optionally be followed by modifiers which change the offset from the iterator, field width and base. Modifiers are introduced by a { (left brace) immediately following the $ as ${offset[,width[,base]]}. For example, ${-20,3,d} subtracts 20 from the current value, prints the result as a decimal in a zero-padded field of width 3. Available output forms are decimal (d), octal (o), hexadecimal (x or X for uppercase) and nibble (n or N\ for uppercase). The default modifier is ${0,0,d}. If the lhs is not absolute, the current $ORIGIN is appended to the name.

In nibble mode the value will be treated as if it was a reversed hexadecimal string with each hexadecimal digit as a separate label. The width field includes the label separator.

For compatibility with earlier versions, $$ is still recognized as indicating a literal $ in the output.

ttl

Specifies the time-to-live of the generated records. If not specified this will be inherited using the normal TTL inheritance rules.

class and ttl can be entered in either order.

class

Specifies the class of the generated records. This must match the zone class if it is specified.

class and ttl can be entered in either order.

type

Any valid type.

rhs

rhs, optionally, quoted string.

The $GENERATE directive is a BIND extension and not part of the standard zone file format.

BIND 8 does not support the optional TTL and CLASS fields.

Additional File Formats

In addition to the standard textual format, BIND 9 supports the ability to read or dump to zone files in other formats.

The raw format is a binary representation of zone data in a manner similar to that used in zone transfers. Since it does not require parsing text, load time is significantly reduced.

An even faster alternative is the map format, which is an image of a BIND 9 in-memory zone database; it is capable of being loaded directly into memory via the mmap() function; the zone can begin serving queries almost immediately.

For a primary server, a zone file in raw or map format is expected to be generated from a textual zone file by the named-compilezone command. For a secondary server or for a dynamic zone, it is automatically generated (if this format is specified by the masterfile-format option) when named dumps the zone contents after zone transfer or when applying prior updates.

If a zone file in a binary format needs manual modification, it first must be converted to a textual form by the named-compilezone command. All necessary modification should go to the text file, which should then be converted to the binary form by the named-compilezone command again.

Note that map format is extremely architecture-specific. A map file cannot be used on a system with different pointer size, endianness or data alignment than the system on which it was generated, and should in general be used only inside a single system. While raw format uses network byte order and avoids architecture-dependent data alignment so that it is as portable as possible, it is also primarily expected to be used inside the same single system. To export a zone file in either raw or map format, or make a portable backup of such a file, conversion to text format is recommended.

BIND9 Statistics

BIND 9 maintains lots of statistics information and provides several interfaces for users to get access to the statistics. The available statistics include all statistics counters that were available in BIND 8 and are meaningful in BIND 9, and other information that is considered useful.

The statistics information is categorized into the following sections.

Incoming Requests

The number of incoming DNS requests for each OPCODE.

Incoming Queries

The number of incoming queries for each RR type.

Outgoing Queries

The number of outgoing queries for each RR type sent from the internal resolver. Maintained per view.

Name Server Statistics

Statistics counters about incoming request processing.

Zone Maintenance Statistics

Statistics counters regarding zone maintenance operations such as zone transfers.

Resolver Statistics

Statistics counters about name resolution performed in the internal resolver. Maintained per view.

Cache DB RRsets

The number of RRsets per RR type and nonexistent names stored in the cache database. If the exclamation mark (!) is printed for a RR type, it means that particular type of RRset is known to be nonexistent (this is also known as "NXRRSET"). If a hash mark (#) is present then the RRset is marked for garbage collection. Maintained per view.

Socket I/O Statistics

Statistics counters about network related events.

A subset of Name Server Statistics is collected and shown per zone for which the server has the authority when zone-statistics is set to yes. These statistics counters are shown with their zone and view names. In some cases the view names are omitted for the default view.

There are currently two user interfaces to get access to the statistics. One is in the plain text format dumped to the file specified by the statistics-file configuration option. The other is remotely accessible via a statistics channel when the statistics-channels statement is specified in the configuration file (see the section called “statistics-channels Statement Grammar”.)

The Statistics File

The text format statistics dump begins with a line, like:

+++ Statistics Dump +++ (973798949)

The number in parentheses is a standard Unix-style timestamp, measured as seconds since January 1, 1970. Following that line is a set of statistics information, which is categorized as described above. Each section begins with a line, like:

++ Name Server Statistics ++

Each section consists of lines, each containing the statistics counter value followed by its textual description. See below for available counters. For brevity, counters that have a value of 0 are not shown in the statistics file.

The statistics dump ends with the line where the number is identical to the number in the beginning line; for example:

--- Statistics Dump --- (973798949)

Statistics Counters

The following tables summarize statistics counters that BIND 9 provides. For each row of the tables, the leftmost column is the abbreviated symbol name of that counter. These symbols are shown in the statistics information accessed via an HTTP statistics channel. The rightmost column gives the description of the counter, which is also shown in the statistics file (but, in this document, possibly with slight modification for better readability). Additional notes may also be provided in this column. When a middle column exists between these two columns, it gives the corresponding counter name of the BIND 8 statistics, if applicable.

Name Server Statistics Counters

Symbol

BIND8 Symbol

Description

Requestv4

RQ

IPv4 requests received. Note: this also counts non query requests.

Requestv6

RQ

IPv6 requests received. Note: this also counts non query requests.

ReqEdns0

Requests with EDNS(0) received.

ReqBadEDNSVer

Requests with unsupported EDNS version received.

ReqTSIG

Requests with TSIG received.

ReqSIG0

Requests with SIG(0) received.

ReqBadSIG

Requests with invalid (TSIG or SIG(0)) signature.

ReqTCP

RTCP

TCP requests received.

AuthQryRej

RUQ

Authoritative (non recursive) queries rejected.

RecQryRej

RURQ

Recursive queries rejected.

XfrRej

RUXFR

Zone transfer requests rejected.

UpdateRej

RUUpd

Dynamic update requests rejected.

Response

SAns

Responses sent.

RespTruncated

Truncated responses sent.

RespEDNS0

Responses with EDNS(0) sent.

RespTSIG

Responses with TSIG sent.

RespSIG0

Responses with SIG(0) sent.

QrySuccess

Queries resulted in a successful answer. This means the query which returns a NOERROR response with at least one answer RR. This corresponds to the success counter of previous versions of BIND 9.

QryAuthAns

Queries resulted in authoritative answer.

QryNoauthAns

SNaAns

Queries resulted in non authoritative answer.

QryReferral

Queries resulted in referral answer. This corresponds to the referral counter of previous versions of BIND 9.

QryNxrrset

Queries resulted in NOERROR responses with no data. This corresponds to the nxrrset counter of previous versions of BIND 9.

QrySERVFAIL

SFail

Queries resulted in SERVFAIL.

QryFORMERR

SFErr

Queries resulted in FORMERR.

QryNXDOMAIN

SNXD

Queries resulted in NXDOMAIN. This corresponds to the nxdomain counter of previous versions of BIND 9.

QryRecursion

RFwdQ

Queries which caused the server to perform recursion in order to find the final answer. This corresponds to the recursion counter of previous versions of BIND 9.

QryDuplicate

RDupQ

Queries which the server attempted to recurse but discovered an existing query with the same IP address, port, query ID, name, type and class already being processed. This corresponds to the duplicate counter of previous versions of BIND 9.

QryDropped

Recursive queries for which the server discovered an excessive number of existing recursive queries for the same name, type and class and were subsequently dropped. This is the number of dropped queries due to the reason explained with the clients-per-query and max-clients-per-query options (see the description about clients-per-query.) This corresponds to the dropped counter of previous versions of BIND 9.

QryFailure

Other query failures. This corresponds to the failure counter of previous versions of BIND 9. Note: this counter is provided mainly for backward compatibility with the previous versions. Normally a more fine-grained counters such as AuthQryRej and RecQryRej that would also fall into this counter are provided, and so this counter would not be of much interest in practice.

XfrReqDone

Requested zone transfers completed.

UpdateReqFwd

Update requests forwarded.

UpdateRespFwd

Update responses forwarded.

UpdateFwdFail

Dynamic update forward failed.

UpdateDone

Dynamic updates completed.

UpdateFail

Dynamic updates failed.

UpdateBadPrereq

Dynamic updates rejected due to prerequisite failure.

RateDropped

Responses dropped by rate limits.

RateSlipped

Responses truncated by rate limits.

RPZRewrites

Response policy zone rewrites.

Zone Maintenance Statistics Counters

Symbol

Description

NotifyOutv4

IPv4 notifies sent.

NotifyOutv6

IPv6 notifies sent.

NotifyInv4

IPv4 notifies received.

NotifyInv6

IPv6 notifies received.

NotifyRej

Incoming notifies rejected.

SOAOutv4

IPv4 SOA queries sent.

SOAOutv6

IPv6 SOA queries sent.

AXFRReqv4

IPv4 AXFR requested.

AXFRReqv6

IPv6 AXFR requested.

IXFRReqv4

IPv4 IXFR requested.

IXFRReqv6

IPv6 IXFR requested.

XfrSuccess

Zone transfer requests succeeded.

XfrFail

Zone transfer requests failed.

Resolver Statistics Counters

Symbol

BIND8 Symbol

Description

Queryv4

SFwdQ

IPv4 queries sent.

Queryv6

SFwdQ

IPv6 queries sent.

Responsev4

RR

IPv4 responses received.

Responsev6

RR

IPv6 responses received.

NXDOMAIN

RNXD

NXDOMAIN received.

SERVFAIL

RFail

SERVFAIL received.

FORMERR

RFErr

FORMERR received.

OtherError

RErr

Other errors received.

EDNS0Fail

EDNS(0) query failures.

Mismatch

RDupR

Mismatch responses received. The DNS ID, response's source address, and/or the response's source port does not match what was expected. (The port must be 53 or as defined by the port option.) This may be an indication of a cache poisoning attempt.

Truncated

Truncated responses received.

Lame

RLame

Lame delegations received.

Retry

SDupQ

Query retries performed.

QueryAbort

Queries aborted due to quota control.

QuerySockFail

Failures in opening query sockets. One common reason for such failures is a failure of opening a new socket due to a limitation on file descriptors.

QueryTimeout

Query timeouts.

GlueFetchv4

SSysQ

IPv4 NS address fetches invoked.

GlueFetchv6

SSysQ

IPv6 NS address fetches invoked.

GlueFetchv4Fail

IPv4 NS address fetch failed.

GlueFetchv6Fail

IPv6 NS address fetch failed.

ValAttempt

DNSSEC validation attempted.

ValOk

DNSSEC validation succeeded.

ValNegOk

DNSSEC validation on negative information succeeded.

ValFail

DNSSEC validation failed.

QryRTTnn

Frequency table on round trip times (RTTs) of queries. Each nn specifies the corresponding frequency. In the sequence of nn_1, nn_2, ..., nn_m, the value of nn_i is the number of queries whose RTTs are between nn_(i-1) (inclusive) and nn_i (exclusive) milliseconds. For the sake of convenience we define nn_0 to be 0. The last entry should be represented as nn_m+, which means the number of queries whose RTTs are equal to or over nn_m milliseconds.

Socket I/O Statistics Counters

Socket I/O statistics counters are defined per socket types, which are UDP4 (UDP/IPv4), UDP6 (UDP/IPv6), TCP4 (TCP/IPv4), TCP6 (TCP/IPv6), Unix (Unix Domain), and FDwatch (sockets opened outside the socket module). In the following table <TYPE> represents a socket type. Not all counters are available for all socket types; exceptions are noted in the description field.

Symbol

Description

<TYPE>Open

Sockets opened successfully. This counter is not applicable to the FDwatch type.

<TYPE>OpenFail

Failures of opening sockets. This counter is not applicable to the FDwatch type.

<TYPE>Close

Sockets closed.

<TYPE>BindFail

Failures of binding sockets.

<TYPE>ConnFail

Failures of connecting sockets.

<TYPE>Conn

Connections established successfully.

<TYPE>AcceptFail

Failures of accepting incoming connection requests. This counter is not applicable to the UDP and FDwatch types.

<TYPE>Accept

Incoming connections successfully accepted. This counter is not applicable to the UDP and FDwatch types.

<TYPE>SendErr

Errors in socket send operations. This counter corresponds to SErr counter of BIND 8.

<TYPE>RecvErr

Errors in socket receive operations. This includes errors of send operations on a connected UDP socket notified by an ICMP error message.

Compatibility with BIND 8 Counters

Most statistics counters that were available in BIND 8 are also supported in BIND 9 as shown in the above tables. Here are notes about other counters that do not appear in these tables.

RFwdR,SFwdR

These counters are not supported because BIND 9 does not adopt the notion of forwarding as BIND 8 did.

RAXFR

This counter is accessible in the Incoming Queries section.

RIQ

This counter is accessible in the Incoming Requests section.

ROpts

This counter is not supported because BIND 9 does not care about IP options in the first place.

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/man.dnssec-keygen.html0000644000470500017500000005523312664710322021124 0ustar lamontlamont dnssec-keygen

Name

dnssec-keygen — DNSSEC key generation tool

Synopsis

dnssec-keygen [-a algorithm] [-b keysize] [-n nametype] [-3] [-A date/offset] [-C] [-c class] [-D date/offset] [-E engine] [-f flag] [-G] [-g generator] [-h] [-I date/offset] [-i interval] [-K directory] [-L ttl] [-k] [-P date/offset] [-p protocol] [-q] [-R date/offset] [-r randomdev] [-S key] [-s strength] [-t type] [-v level] [-V] [-z] {name}

DESCRIPTION

dnssec-keygen generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034. It can also generate keys for use with TSIG (Transaction Signatures) as defined in RFC 2845, or TKEY (Transaction Key) as defined in RFC 2930.

The name of the key is specified on the command line. For DNSSEC keys, this must match the name of the zone for which the key is being generated.

OPTIONS

-a algorithm

Selects the cryptographic algorithm. For DNSSEC keys, the value of algorithm must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512, ECCGOST, ECDSAP256SHA256 or ECDSAP384SHA384. For TSIG/TKEY, the value must be DH (Diffie Hellman), HMAC-MD5, HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512. These values are case insensitive.

If no algorithm is specified, then RSASHA1 will be used by default, unless the -3 option is specified, in which case NSEC3RSASHA1 will be used instead. (If -3 is used and an algorithm is specified, that algorithm will be checked for compatibility with NSEC3.)

Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended. For TSIG, HMAC-MD5 is mandatory.

Note 2: DH, HMAC-MD5, and HMAC-SHA1 through HMAC-SHA512 automatically set the -T KEY option.

-b keysize

Specifies the number of bits in the key. The choice of key size depends on the algorithm used. RSA keys must be between 512 and 2048 bits. Diffie Hellman keys must be between 128 and 4096 bits. DSA keys must be between 512 and 1024 bits and an exact multiple of 64. HMAC keys must be between 1 and 512 bits. Elliptic curve algorithms don't need this parameter.

The key size does not need to be specified if using a default algorithm. The default key size is 1024 bits for zone signing keys (ZSK's) and 2048 bits for key signing keys (KSK's, generated with -f KSK). However, if an algorithm is explicitly specified with the -a, then there is no default key size, and the -b must be used.

-n nametype

Specifies the owner type of the key. The value of nametype must either be ZONE (for a DNSSEC zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with a host (KEY)), USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). These values are case insensitive. Defaults to ZONE for DNSKEY generation.

-3

Use an NSEC3-capable algorithm to generate a DNSSEC key. If this option is used and no algorithm is explicitly set on the command line, NSEC3RSASHA1 will be used by default. Note that RSASHA256, RSASHA512, ECCGOST, ECDSAP256SHA256 and ECDSAP384SHA384 algorithms are NSEC3-capable.

-C

Compatibility mode: generates an old-style key, without any metadata. By default, dnssec-keygen will include the key's creation date in the metadata stored with the private key, and other dates may be set there as well (publication date, activation date, etc). Keys that include this data may be incompatible with older versions of BIND; the -C option suppresses them.

-c class

Indicates that the DNS record containing the key should have the specified class. If not specified, class IN is used.

-E engine

Specifies the cryptographic hardware to use, when applicable.

When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (--enable-native-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "--with-pkcs11".

-f flag

Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flags are KSK (Key Signing Key) and REVOKE.

-G

Generate a key, but do not publish it or sign with it. This option is incompatible with -P and -A.

-g generator

If generating a Diffie Hellman key, use this generator. Allowed values are 2 and 5. If no generator is specified, a known prime from RFC 2539 will be used if possible; otherwise the default is 2.

-h

Prints a short summary of the options and arguments to dnssec-keygen.

-K directory

Sets the directory in which the key files are to be written.

-k

Deprecated in favor of -T KEY.

-L ttl

Sets the default TTL to use for this key when it is converted into a DNSKEY RR. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence. If this value is not set and there is no existing DNSKEY RRset, the TTL will default to the SOA TTL. Setting the default TTL to 0 or none is the same as leaving it unset.

-p protocol

Sets the protocol value for the generated key. The protocol is a number between 0 and 255. The default is 3 (DNSSEC). Other possible values for this argument are listed in RFC 2535 and its successors.

-q

Quiet mode: Suppresses unnecessary output, including progress indication. Without this option, when dnssec-keygen is run interactively to generate an RSA or DSA key pair, it will print a string of symbols to stderr indicating the progress of the key generation. A '.' indicates that a random number has been found which passed an initial sieve test; '+' means a number has passed a single round of the Miller-Rabin primality test; a space means that the number has passed all the tests and is a satisfactory key.

-r randomdev

Specifies the source of randomness. If the operating system does not provide a /dev/random or equivalent device, the default source of randomness is keyboard input. randomdev specifies the name of a character device or file containing random data to be used instead of the default. The special value keyboard indicates that keyboard input should be used.

-S key

Create a new key which is an explicit successor to an existing key. The name, algorithm, size, and type of the key will be set to match the existing key. The activation date of the new key will be set to the inactivation date of the existing one. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days.

-s strength

Specifies the strength value of the key. The strength is a number between 0 and 15, and currently has no defined purpose in DNSSEC.

-T rrtype

Specifies the resource record type to use for the key. rrtype must be either DNSKEY or KEY. The default is DNSKEY when using a DNSSEC algorithm, but it can be overridden to KEY for use with SIG(0).

Using any TSIG algorithm (HMAC-* or DH) forces this option to KEY.

-t type

Indicates the use of the key. type must be one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default is AUTHCONF. AUTH refers to the ability to authenticate data, and CONF the ability to encrypt data.

-v level

Sets the debugging level.

-V

Prints version information.

TIMING OPTIONS

Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24-hour days, ignoring leap years), months (defined as 30 24-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To explicitly prevent a date from being set, use 'none' or 'never'.

-P date/offset

Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it. If not set, and if the -G option has not been used, the default is "now".

-A date/offset

Sets the date on which the key is to be activated. After that date, the key will be included in the zone and used to sign it. If not set, and if the -G option has not been used, the default is "now". If set, if and -P is not set, then the publication date will be set to the activation date minus the prepublication interval.

-R date/offset

Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it.

-I date/offset

Sets the date on which the key is to be retired. After that date, the key will still be included in the zone, but it will not be used to sign it.

-D date/offset

Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.)

-i interval

Sets the prepublication interval for a key. If set, then the publication and activation dates must be separated by at least this much time. If the activation date is specified but the publication date isn't, then the publication date will default to this much time before the activation date; conversely, if the publication date is specified but activation date isn't, then activation will be set to this much time after publication.

If the key is being created as an explicit successor to another key, then the default prepublication interval is 30 days; otherwise it is zero.

As with date offsets, if the argument is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the interval is measured in years, months, weeks, days, hours, or minutes, respectively. Without a suffix, the interval is measured in seconds.

GENERATED KEYS

When dnssec-keygen completes successfully, it prints a string of the form Knnnn.+aaa+iiiii to the standard output. This is an identification string for the key it has generated.

  • nnnn is the key name.

  • aaa is the numeric representation of the algorithm.

  • iiiii is the key identifier (or footprint).

dnssec-keygen creates two files, with names based on the printed string. Knnnn.+aaa+iiiii.key contains the public key, and Knnnn.+aaa+iiiii.private contains the private key.

The .key file contains a DNS KEY record that can be inserted into a zone file (directly or with a $INCLUDE statement).

The .private file contains algorithm-specific fields. For obvious security reasons, this file does not have general read permission.

Both .key and .private files are generated for symmetric encryption algorithms such as HMAC-MD5, even though the public and private key are equivalent.

EXAMPLE

To generate a 768-bit DSA key for the domain example.com, the following command would be issued:

dnssec-keygen -a DSA -b 768 -n ZONE example.com

The command would print a string of the form:

Kexample.com.+003+26160

In this example, dnssec-keygen creates the files Kexample.com.+003+26160.key and Kexample.com.+003+26160.private.

SEE ALSO

dnssec-signzone(8), BIND 9 Administrator Reference Manual, RFC 2539, RFC 2845, RFC 4034.

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/man.dnssec-keyfromlabel.html0000644000470500017500000004636112664710322022320 0ustar lamontlamont dnssec-keyfromlabel

Name

dnssec-keyfromlabel — DNSSEC key generation tool

Synopsis

dnssec-keyfromlabel {-l label} [-3] [-a algorithm] [-A date/offset] [-c class] [-D date/offset] [-E engine] [-f flag] [-G] [-I date/offset] [-i interval] [-k] [-K directory] [-L ttl] [-n nametype] [-P date/offset] [-p protocol] [-R date/offset] [-S key] [-t type] [-v level] [-V] [-y] {name}

DESCRIPTION

dnssec-keyfromlabel generates a key pair of files that referencing a key object stored in a cryptographic hardware service module (HSM). The private key file can be used for DNSSEC signing of zone data as if it were a conventional signing key created by dnssec-keygen, but the key material is stored within the HSM, and the actual signing takes place there.

The name of the key is specified on the command line. This must match the name of the zone for which the key is being generated.

OPTIONS

-a algorithm

Selects the cryptographic algorithm. The value of algorithm must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512, ECCGOST, ECDSAP256SHA256 or ECDSAP384SHA384. These values are case insensitive.

If no algorithm is specified, then RSASHA1 will be used by default, unless the -3 option is specified, in which case NSEC3RSASHA1 will be used instead. (If -3 is used and an algorithm is specified, that algorithm will be checked for compatibility with NSEC3.)

Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended.

Note 2: DH automatically sets the -k flag.

-3

Use an NSEC3-capable algorithm to generate a DNSSEC key. If this option is used and no algorithm is explicitly set on the command line, NSEC3RSASHA1 will be used by default.

-E engine

Specifies the cryptographic hardware to use.

When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (--enable-native-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "--with-pkcs11".

-l label

Specifies the label for a key pair in the crypto hardware.

When BIND 9 is built with OpenSSL-based PKCS#11 support, the label is an arbitrary string that identifies a particular key. It may be preceded by an optional OpenSSL engine name, followed by a colon, as in "pkcs11:keylabel".

When BIND 9 is built with native PKCS#11 support, the label is a PKCS#11 URI string in the format "pkcs11:keyword=value[;keyword=value;...]" Keywords include "token", which identifies the HSM; "object", which identifies the key; and "pin-source", which identifies a file from which the HSM's PIN code can be obtained. The label will be stored in the on-disk "private" file.

If the label contains a pin-source field, tools using the generated key files will be able to use the HSM for signing and other operations without any need for an operator to manually enter a PIN. Note: Making the HSM's PIN accessible in this manner may reduce the security advantage of using an HSM; be sure this is what you want to do before making use of this feature.

-n nametype

Specifies the owner type of the key. The value of nametype must either be ZONE (for a DNSSEC zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with a host (KEY)), USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). These values are case insensitive.

-C

Compatibility mode: generates an old-style key, without any metadata. By default, dnssec-keyfromlabel will include the key's creation date in the metadata stored with the private key, and other dates may be set there as well (publication date, activation date, etc). Keys that include this data may be incompatible with older versions of BIND; the -C option suppresses them.

-c class

Indicates that the DNS record containing the key should have the specified class. If not specified, class IN is used.

-f flag

Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flags are KSK (Key Signing Key) and REVOKE.

-G

Generate a key, but do not publish it or sign with it. This option is incompatible with -P and -A.

-h

Prints a short summary of the options and arguments to dnssec-keyfromlabel.

-K directory

Sets the directory in which the key files are to be written.

-k

Generate KEY records rather than DNSKEY records.

-L ttl

Sets the default TTL to use for this key when it is converted into a DNSKEY RR. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence. Setting the default TTL to 0 or none removes it.

-p protocol

Sets the protocol value for the key. The protocol is a number between 0 and 255. The default is 3 (DNSSEC). Other possible values for this argument are listed in RFC 2535 and its successors.

-S key

Generate a key as an explicit successor to an existing key. The name, algorithm, size, and type of the key will be set to match the predecessor. The activation date of the new key will be set to the inactivation date of the existing one. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days.

-t type

Indicates the use of the key. type must be one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default is AUTHCONF. AUTH refers to the ability to authenticate data, and CONF the ability to encrypt data.

-v level

Sets the debugging level.

-V

Prints version information.

-y

Allows DNSSEC key files to be generated even if the key ID would collide with that of an existing key, in the event of either key being revoked. (This is only safe to use if you are sure you won't be using RFC 5011 trust anchor maintenance with either of the keys involved.)

TIMING OPTIONS

Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24-hour days, ignoring leap years), months (defined as 30 24-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To explicitly prevent a date from being set, use 'none' or 'never'.

-P date/offset

Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it. If not set, and if the -G option has not been used, the default is "now".

-A date/offset

Sets the date on which the key is to be activated. After that date, the key will be included in the zone and used to sign it. If not set, and if the -G option has not been used, the default is "now".

-R date/offset

Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it.

-I date/offset

Sets the date on which the key is to be retired. After that date, the key will still be included in the zone, but it will not be used to sign it.

-D date/offset

Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.)

-i interval

Sets the prepublication interval for a key. If set, then the publication and activation dates must be separated by at least this much time. If the activation date is specified but the publication date isn't, then the publication date will default to this much time before the activation date; conversely, if the publication date is specified but activation date isn't, then activation will be set to this much time after publication.

If the key is being created as an explicit successor to another key, then the default prepublication interval is 30 days; otherwise it is zero.

As with date offsets, if the argument is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the interval is measured in years, months, weeks, days, hours, or minutes, respectively. Without a suffix, the interval is measured in seconds.

GENERATED KEY FILES

When dnssec-keyfromlabel completes successfully, it prints a string of the form Knnnn.+aaa+iiiii to the standard output. This is an identification string for the key files it has generated.

  • nnnn is the key name.

  • aaa is the numeric representation of the algorithm.

  • iiiii is the key identifier (or footprint).

dnssec-keyfromlabel creates two files, with names based on the printed string. Knnnn.+aaa+iiiii.key contains the public key, and Knnnn.+aaa+iiiii.private contains the private key.

The .key file contains a DNS KEY record that can be inserted into a zone file (directly or with a $INCLUDE statement).

The .private file contains algorithm-specific fields. For obvious security reasons, this file does not have general read permission.

SEE ALSO

dnssec-keygen(8), dnssec-signzone(8), BIND 9 Administrator Reference Manual, RFC 4034, The PKCS#11 URI Scheme (draft-pechanec-pkcs11uri-13).

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/man.genrandom.html0000644000470500017500000001075112664710322020333 0ustar lamontlamont genrandom

Name

genrandom — generate a file containing random data

Synopsis

genrandom [-n number] {size} {filename}

DESCRIPTION

genrandom generates a file or a set of files containing a specified quantity of pseudo-random data, which can be used as a source of entropy for other commands on systems with no random device.

ARGUMENTS

-n number

In place of generating one file, generates number (from 2 to 9) files, appending number to the name.

size

The size of the file, in kilobytes, to generate.

filename

The file name into which random data should be written.

SEE ALSO

rand(3), arc4random(3)

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/man.dnssec-signzone.html0000644000470500017500000007266012664710322021501 0ustar lamontlamont dnssec-signzone

Name

dnssec-signzone — DNSSEC zone signing tool

Synopsis

dnssec-signzone [-a] [-c class] [-d directory] [-D] [-E engine] [-e end-time] [-f output-file] [-g] [-h] [-K directory] [-k key] [-L serial] [-l domain] [-M domain] [-i interval] [-I input-format] [-j jitter] [-N soa-serial-format] [-o origin] [-O output-format] [-P] [-p] [-R] [-r randomdev] [-S] [-s start-time] [-T ttl] [-t] [-u] [-v level] [-V] [-X extended end-time] [-x] [-z] [-3 salt] [-H iterations] [-A] {zonefile} [key...]

DESCRIPTION

dnssec-signzone signs a zone. It generates NSEC and RRSIG records and produces a signed version of the zone. The security status of delegations from the signed zone (that is, whether the child zones are secure or not) is determined by the presence or absence of a keyset file for each child zone.

OPTIONS

-a

Verify all generated signatures.

-c class

Specifies the DNS class of the zone.

-C

Compatibility mode: Generate a keyset-zonename file in addition to dsset-zonename when signing a zone, for use by older versions of dnssec-signzone.

-d directory

Look for dsset- or keyset- files in directory.

-D

Output only those record types automatically managed by dnssec-signzone, i.e. RRSIG, NSEC, NSEC3 and NSEC3PARAM records. If smart signing (-S) is used, DNSKEY records are also included. The resulting file can be included in the original zone file with $INCLUDE. This option cannot be combined with -O raw, -O map, or serial number updating.

-E engine

When applicable, specifies the hardware to use for cryptographic operations, such as a secure key store used for signing.

When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (--enable-native-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "--with-pkcs11".

-g

Generate DS records for child zones from dsset- or keyset- file. Existing DS records will be removed.

-K directory

Key repository: Specify a directory to search for DNSSEC keys. If not specified, defaults to the current directory.

-k key

Treat specified key as a key signing key ignoring any key flags. This option may be specified multiple times.

-l domain

Generate a DLV set in addition to the key (DNSKEY) and DS sets. The domain is appended to the name of the records.

-M maxttl

Sets the maximum TTL for the signed zone. Any TTL higher than maxttl in the input zone will be reduced to maxttl in the output. This provides certainty as to the largest possible TTL in the signed zone, which is useful to know when rolling keys because it is the longest possible time before signatures that have been retrieved by resolvers will expire from resolver caches. Zones that are signed with this option should be configured to use a matching max-zone-ttl in named.conf. (Note: This option is incompatible with -D, because it modifies non-DNSSEC data in the output zone.)

-s start-time

Specify the date and time when the generated RRSIG records become valid. This can be either an absolute or relative time. An absolute start time is indicated by a number in YYYYMMDDHHMMSS notation; 20000530144500 denotes 14:45:00 UTC on May 30th, 2000. A relative start time is indicated by +N, which is N seconds from the current time. If no start-time is specified, the current time minus 1 hour (to allow for clock skew) is used.

-e end-time

Specify the date and time when the generated RRSIG records expire. As with start-time, an absolute time is indicated in YYYYMMDDHHMMSS notation. A time relative to the start time is indicated with +N, which is N seconds from the start time. A time relative to the current time is indicated with now+N. If no end-time is specified, 30 days from the start time is used as a default. end-time must be later than start-time.

-X extended end-time

Specify the date and time when the generated RRSIG records for the DNSKEY RRset will expire. This is to be used in cases when the DNSKEY signatures need to persist longer than signatures on other records; e.g., when the private component of the KSK is kept offline and the KSK signature is to be refreshed manually.

As with start-time, an absolute time is indicated in YYYYMMDDHHMMSS notation. A time relative to the start time is indicated with +N, which is N seconds from the start time. A time relative to the current time is indicated with now+N. If no extended end-time is specified, the value of end-time is used as the default. (end-time, in turn, defaults to 30 days from the start time.) extended end-time must be later than start-time.

-f output-file

The name of the output file containing the signed zone. The default is to append .signed to the input filename. If output-file is set to "-", then the signed zone is written to the standard output, with a default output format of "full".

-h

Prints a short summary of the options and arguments to dnssec-signzone.

-V

Prints version information.

-i interval

When a previously-signed zone is passed as input, records may be resigned. The interval option specifies the cycle interval as an offset from the current time (in seconds). If a RRSIG record expires after the cycle interval, it is retained. Otherwise, it is considered to be expiring soon, and it will be replaced.

The default cycle interval is one quarter of the difference between the signature end and start times. So if neither end-time or start-time are specified, dnssec-signzone generates signatures that are valid for 30 days, with a cycle interval of 7.5 days. Therefore, if any existing RRSIG records are due to expire in less than 7.5 days, they would be replaced.

-I input-format

The format of the input zone file. Possible formats are "text" (default), "raw", and "map". This option is primarily intended to be used for dynamic signed zones so that the dumped zone file in a non-text format containing updates can be signed directly. The use of this option does not make much sense for non-dynamic zones.

-j jitter

When signing a zone with a fixed signature lifetime, all RRSIG records issued at the time of signing expires simultaneously. If the zone is incrementally signed, i.e. a previously-signed zone is passed as input to the signer, all expired signatures have to be regenerated at about the same time. The jitter option specifies a jitter window that will be used to randomize the signature expire time, thus spreading incremental signature regeneration over time.

Signature lifetime jitter also to some extent benefits validators and servers by spreading out cache expiration, i.e. if large numbers of RRSIGs don't expire at the same time from all caches there will be less congestion than if all validators need to refetch at mostly the same time.

-L serial

When writing a signed zone to "raw" or "map" format, set the "source serial" value in the header to the specified serial number. (This is expected to be used primarily for testing purposes.)

-n ncpus

Specifies the number of threads to use. By default, one thread is started for each detected CPU.

-N soa-serial-format

The SOA serial number format of the signed zone. Possible formats are "keep" (default), "increment" and "unixtime".

"keep"

Do not modify the SOA serial number.

"increment"

Increment the SOA serial number using RFC 1982 arithmetics.

"unixtime"

Set the SOA serial number to the number of seconds since epoch.

-o origin

The zone origin. If not specified, the name of the zone file is assumed to be the origin.

-O output-format

The format of the output file containing the signed zone. Possible formats are "text" (default), which is the standard textual representation of the zone; "full", which is text output in a format suitable for processing by external scripts; and "map", "raw", and "raw=N", which store the zone in binary formats for rapid loading by named. "raw=N" specifies the format version of the raw zone file: if N is 0, the raw file can be read by any version of named; if N is 1, the file can be read by release 9.9.0 or higher; the default is 1.

-p

Use pseudo-random data when signing the zone. This is faster, but less secure, than using real random data. This option may be useful when signing large zones or when the entropy source is limited.

-P

Disable post sign verification tests.

The post sign verification test ensures that for each algorithm in use there is at least one non revoked self signed KSK key, that all revoked KSK keys are self signed, and that all records in the zone are signed by the algorithm. This option skips these tests.

-Q

Remove signatures from keys that are no longer active.

Normally, when a previously-signed zone is passed as input to the signer, and a DNSKEY record has been removed and replaced with a new one, signatures from the old key that are still within their validity period are retained. This allows the zone to continue to validate with cached copies of the old DNSKEY RRset. The -Q forces dnssec-signzone to remove signatures from keys that are no longer active. This enables ZSK rollover using the procedure described in RFC 4641, section 4.2.1.1 ("Pre-Publish Key Rollover").

-R

Remove signatures from keys that are no longer published.

This option is similar to -Q, except it forces dnssec-signzone to signatures from keys that are no longer published. This enables ZSK rollover using the procedure described in RFC 4641, section 4.2.1.2 ("Double Signature Zone Signing Key Rollover").

-r randomdev

Specifies the source of randomness. If the operating system does not provide a /dev/random or equivalent device, the default source of randomness is keyboard input. randomdev specifies the name of a character device or file containing random data to be used instead of the default. The special value keyboard indicates that keyboard input should be used.

-S

Smart signing: Instructs dnssec-signzone to search the key repository for keys that match the zone being signed, and to include them in the zone if appropriate.

When a key is found, its timing metadata is examined to determine how it should be used, according to the following rules. Each successive rule takes priority over the prior ones:

If no timing metadata has been set for the key, the key is published in the zone and used to sign the zone.

If the key's publication date is set and is in the past, the key is published in the zone.

If the key's activation date is set and in the past, the key is published (regardless of publication date) and used to sign the zone.

If the key's revocation date is set and in the past, and the key is published, then the key is revoked, and the revoked key is used to sign the zone.

If either of the key's unpublication or deletion dates are set and in the past, the key is NOT published or used to sign the zone, regardless of any other metadata.

-T ttl

Specifies a TTL to be used for new DNSKEY records imported into the zone from the key repository. If not specified, the default is the TTL value from the zone's SOA record. This option is ignored when signing without -S, since DNSKEY records are not imported from the key repository in that case. It is also ignored if there are any pre-existing DNSKEY records at the zone apex, in which case new records' TTL values will be set to match them, or if any of the imported DNSKEY records had a default TTL value. In the event of a a conflict between TTL values in imported keys, the shortest one is used.

-t

Print statistics at completion.

-u

Update NSEC/NSEC3 chain when re-signing a previously signed zone. With this option, a zone signed with NSEC can be switched to NSEC3, or a zone signed with NSEC3 can be switch to NSEC or to NSEC3 with different parameters. Without this option, dnssec-signzone will retain the existing chain when re-signing.

-v level

Sets the debugging level.

-x

Only sign the DNSKEY RRset with key-signing keys, and omit signatures from zone-signing keys. (This is similar to the dnssec-dnskey-kskonly yes; zone option in named.)

-z

Ignore KSK flag on key when determining what to sign. This causes KSK-flagged keys to sign all records, not just the DNSKEY RRset. (This is similar to the update-check-ksk no; zone option in named.)

-3 salt

Generate an NSEC3 chain with the given hex encoded salt. A dash (salt) can be used to indicate that no salt is to be used when generating the NSEC3 chain.

-H iterations

When generating an NSEC3 chain, use this many iterations. The default is 10.

-A

When generating an NSEC3 chain set the OPTOUT flag on all NSEC3 records and do not generate NSEC3 records for insecure delegations.

Using this option twice (i.e., -AA) turns the OPTOUT flag off for all records. This is useful when using the -u option to modify an NSEC3 chain which previously had OPTOUT set.

zonefile

The file containing the zone to be signed.

key

Specify which keys should be used to sign the zone. If no keys are specified, then the zone will be examined for DNSKEY records at the zone apex. If these are found and there are matching private keys, in the current directory, then these will be used for signing.

EXAMPLE

The following command signs the example.com zone with the DSA key generated by dnssec-keygen (Kexample.com.+003+17247). Because the -S option is not being used, the zone's keys must be in the master file (db.example.com). This invocation looks for dsset files, in the current directory, so that DS records can be imported from them (-g).

% dnssec-signzone -g -o example.com db.example.com \
Kexample.com.+003+17247
db.example.com.signed
%

In the above example, dnssec-signzone creates the file db.example.com.signed. This file should be referenced in a zone statement in a named.conf file.

This example re-signs a previously signed zone with default parameters. The private keys are assumed to be in the current directory.

% cp db.example.com.signed db.example.com
% dnssec-signzone -o example.com db.example.com
db.example.com.signed
%

SEE ALSO

dnssec-keygen(8), BIND 9 Administrator Reference Manual, RFC 4033, RFC 4641.

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/notes.html0000644000470500017500000001366712664710322016750 0ustar lamontlamont

Release Notes for BIND Version 9.10.3-P4

Introduction

This document summarizes changes since BIND 9.10.3:

BIND 9.10.3-P4 addresses the security issues described in CVE-2016-1285, CVE-2016-1286 and CVE-2016-2088.

BIND 9.10.3-P3 addresses the security issues described in CVE-2015-8704 and CVE-2015-8705. It also fixes a serious regression in authoritative server selection that was introduced in BIND 9.10.3.

BIND 9.10.3-P2 addresses the security issues described in CVE-2015-3193 (OpenSSL), CVE-2015-8000 and CVE-2015-8461.

BIND 9.10.3-P1 was incomplete and was withdrawn prior to publication.

Download

The latest versions of BIND 9 software can always be found at http://www.isc.org/downloads/. There you will find additional information about each release, source code, and pre-compiled versions for Microsoft Windows operating systems.

Security Fixes

  • Duplicate EDNS COOKIE options in a response could trigger an assertion failure. This flaw is disclosed in CVE-2016-2088. [RT #41809]

  • The resolver could abort with an assertion failure due to improper DNAME handling when parsing fetch reply messages. This flaw is disclosed in CVE-2016-1286. [RT #41753]

  • Malformed control messages can trigger assertions in named and rndc. This flaw is disclosed in CVE-2016-1285. [RT #41666]

  • Certain errors that could be encountered when printing out or logging an OPT record containing a CLIENT-SUBNET option could be mishandled, resulting in an assertion failure. This flaw is disclosed in CVE-2015-8705. [RT #41397]

  • Specific APL data could trigger an INSIST. This flaw is disclosed in CVE-2015-8704. [RT #41396]

  • Named is potentially vulnerable to the OpenSSL vulnerability described in CVE-2015-3193.

  • Incorrect reference counting could result in an INSIST failure if a socket error occurred while performing a lookup. This flaw is disclosed in CVE-2015-8461. [RT#40945]

  • Insufficient testing when parsing a message allowed records with an incorrect class to be be accepted, triggering a REQUIRE failure when those records were subsequently cached. This flaw is disclosed in CVE-2015-8000. [RT #40987]

New Features

  • None.

Feature Changes

  • Updated the compiled in addresses for H.ROOT-SERVERS.NET.

Bug Fixes

  • Authoritative servers that were marked as bogus (e.g. blackholed in configuration or with invalid addresses) were being queried anyway. [RT #41321]

End of Life

The end of life for BIND 9.10 is yet to be determined but will not be before BIND 9.12.0 has been released for 6 months. https://www.isc.org/downloads/software-support-policy/

Thank You

Thank you to everyone who assisted us in making this release possible. If you would like to contribute to ISC to assist us in continuing to make quality open source software, please visit our donations page at http://www.isc.org/donate/.

bind9-9.10.3.dfsg.P4/doc/arm/isc-logo.pdf0000644000470500017500000106236712664710322017143 0ustar lamontlamont%PDF-1.5 %âãÏÓ 1 0 obj <>/OCGs[16 0 R 38 0 R 60 0 R 82 0 R]>>/Type/Catalog>> endobj 93 0 obj <>stream application/pdf ISC_logo_only_RGB Adobe Illustrator CS3 2010-03-03T12:03:19-08:00 2010-04-12T11:34:01-07:00 2010-04-12T11:34:01-07:00 256 100 JPEG /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAZAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8AimFDsVdirsVdirsVbAJN BuT0GKvQfLn5R3ctkNY81Xa6Boy0YmYhZ3B3oqt9ivblv/knFKZP5/8Ay98sAweUNBS+uk2/St+C SSP2lDVkofbh8sVSPUvzn/MG9Y8dQWzjP+6raKNQPkzB3/4bFCXRfmb5+ikMi65dFiakMwdf+BYE YqyCx/O7X3i+qeYbG012xf8AvY5oljc/LiPT/wCExSipPJ3kXzpE0/ky6/RmsBS8mh3horUFT6TE t+BI9lxV5xqel6jpd9LY6hbvbXcJpJDIKEeB9wexGxxQhcVdirsVdirsVdirsVTGx8ueYL+0kvLL Tbm5tIq+pPFE7oKdfiUEbd8VS7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FUXpel6hqt9FYaf A9zdznjHEgqT4n2A6knpir1SOx8pfldbJcaj6etec3UNDaqaxW1RUMa/Z/1iOR/ZAFTil5x5l82a 95kvTd6tctMwr6UI+GKMHsidB+s98UJPirsVdirsVXwzTQTJNBI0U0bBo5EJVlYbgqRuCMVepaPr +k/mJp6eXvM7pbeY4146RrfEAyN2ilpTc+HRu1G6qXnWu6FqehapPpmpReldQGjDqrA7qynurDoc UJfirsVdirsVdirLfy98nwa9fT3epyG38v6Un1jU7mtPhAJEakd2oenb3piqeXv53a/DqsQ0GKKw 8v2hVLfTBFHR4kP7bcSylh/IRT36lSln5raRY2+uW2s6anDTPMFsmoQKBQK8g/eLt7kMfnihhOKu xV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxVNfLnmbWPLl+1/pMwguWiaFmKq44PQnZgR1UHFUvurq5u riS5uZWmuJmLyyyEszMepJOKqWKuxV2KuxV2KuxVtHZGDoSrqQVYGhBHQg4q9ZtZI/zO8pNaTU/x pokfK3lJAN3AOzE9+x8Gof2jil5O6PG7RyKUdCVdGFCCNiCDihbirsVdiq+KKSaVIolLyyMFRFFS WY0AA98VelfmFLH5U8qab5Fs2Au5VW916RD9qVt1jJ8Kj7lXxxS8yxQ9H8xx/XvyZ8s35+KXT7ue zY9wsjOw/CNMUvOMUOxVP/LvkXzX5hIOl6fJLATQ3L/u4R4/vHopp4DfFWbw/krpumosvmrzJbWJ pU20FGcj/JaQqfujOWY8M5/SCXHz6vFh+uQj8VddP/IvTvhMV/rBH7RZ1/UbUZmQ7MzHnQdTl9pN JHkZS9w/XTjrv5RoCkflN2RvtF3+IfI82P45cOyJ/wA4OIfavF0hL7FrN+SN+SkmkXums23rROzA e9PVk/4hkJdlZRyILdj9qNMTuJR+A/Whrn8n9J1WJ5/JmvRX5UcvqN1SOYL/AKwC7/60aj3zBy4J 4/qFO502uw5x+7kJff8ALm851XSNT0m9ex1K2ktLqP7UUgoadiOxB7EbZU5SDxV2KuxV2KuxV2Ku xV2KuxV2KuxV2KuxV2Kpl5d12+0HWbXVrJqT2rhuJ6OvRkb2Zag4qzX82tCsLhbHzroq/wC4rXFD XAA/u7mh5cqdC1DX/KVsUvOMUOxV2KvQfyZ0O2ufME+u39F03y/CbuZzuPUoTH/wIVn+YGKsQ8x6 1ca5rt9q1xtJeStJx68V6In+xUBcVS3FU2PmjWD5aHlz1V/RYn+s+nxHLnTpy6074qr+VfJXmHzR dehpVsWjUgTXT/DDHX+d/H2FT7Yq9Jh8uflt5GFdVYeY9eXrbAAwxt4MhJQf7Op/yczNPocmXflH vdRr+28Gm2J4p9w/T3Jbrv5qeaNSBhtZBpdmBxSC1+Fgo2AMn2v+BoM3OHs7FDmOI+f6nkNZ7Qan NsDwR8v18/uYg8jyOzyMXdjVmY1JJ7knM8CnSEkmytwodirsVVIJ57eZJoJGimjPJJEJVlPiCNxk SARRZQmYmwaIeg6Vrmk+erJPLfmwKNRoRpWsKAsgkOwVj4n7m/1qHNHruz+EccOXUPa9i9vHIRiz fV0l3+R8/v8Afz4vmoerdirsVXxQyzSLFCjSSuaIiAsxPgAMVZRpf5WeftSAaDR5okO/O5424p40 lKMfoGKsih/IPzSEEl/f2FlGevOR2Ydz0QL0/wArG0r/APlTGmJ8M/nDTYpB1SqH9cq/qxVo/kxp z0W384abLJ/LVRt9EjYqpTfkL5t4GSyvLC+j7elK4J/4JOP/AA2Nqx7VPyw8+aYC1xo07oNy9uBc Cg7/ALkuQPnihjEkckTtHIpR1NGRgQQfcHFVuKuxV2KuxV6j+U97b67o2r+QtRf93exNcaYzf7rm TdqfIhXp7N44peaXlpcWV3PZ3KGO4tpGimjPVXQlWH0EYoUcVdir1XUx/hT8mbOyH7vUvNEvrzdm 9Cgbr4cBGCP8o4peVYodir0fyV+VsU9kPMPm6b9GaCgDxxMeEs4O491Vu1Pibt45OEJTNRFlqz54 YomczwxCa+YvzJke0Gj+WIBo+ixDgnpAJK4+a/YB703Pc5vtL2bGG895fY8N2n7RZMtxxeiHf1P6 mDEkmp3J6nNm827CrsVdirsVdirsVbVmVgykhgagjYgjAoNMbzi32JOPLnlHzD5jufQ0izefiaSz fZiT/XdqKPl1xVnf/Kv/ACB5UUSedNZ+uagBU6RYE1r4MRR9+xPDFKyX85LHSka38neXrXTIjUfW ZlDysOxYJx3/ANZ2xVi2qfmX561NibjWbhFP+67dvq608KRcK/Tihjk0887mSaRpZD1dyWP3nFVP FXYqqQzzwOJIZGikHR0JU/eMVZDpf5k+etMI+razcso6JO31haeAEwen0YqyeP8AOO31ONbfzf5f s9WiAp9YjX05l9xy5b/6pXFK8eTPy1807+VdYbSdRf7GlajXiSeio5q33M/yxVh3mbyP5m8tS8dV s2jhJol0nxwt8pBtX2ND7YoSHFXYqj9B1i50bWrLVLc/vbOVZQOnIA/Ep9mWoOKs3/OvSLdNbs/M Vj8Wn6/bpcI46eoqrX/gkZG+dcUvOcUJp5W0V9b8xadpS1pdzpHIR1EdayN/sUBOKsu/O/WUvfOJ 06CgtdIhS2jRfshyOb0+XIL/ALHFLz3FD1byZ5I0ny7pkfmzzmnxN8WlaQw+N2G6u6Hv4Kdh1bwy 7BglllUXD12ux6aHHM+4dSlHmvzfq3mS+NxevwgQn6vaIf3cY9vFvFj+rbOm02mjijQ5975x2h2l k1U+KfLoOg/HekeZLgOxV2KuxV2KuxV2KuxV2Ksq0f8ALXRtB0+PXPzAufqkLb22jRms8xG9H47/ AOxXp3YdM4p9jQPmX83NVu7b9FeXIV0DREHGOG2ASZl/ynWnGvgv0k4qwFmZmLMSWJqSdyScUNYq 7FXYq7FXYq7FXYq7FXYqzTyv+avmPRozZXhXWdHccJbC9/eDh0Ko7civyNV9sVT248leUPOlvJf+ R5xY6qql7jy/ckLXufSJJoK+5X/VxS821DT77TryWzvoHtrqE8ZIZAVYH5H8MUIfFXqdiT5m/JW7 tT8d/wCV5/Wi8fq5q258Ajv/AMCMUvLMUPTvyK0+BNZ1PzDdClroto7l/BpAan6I0fFLzrU7+bUN Rur+f++u5nnk7/FIxY/rxQ9G/Lrylp2l6b/jfzOlLKE10ixYDlcS78X4nqKj4P8Agug3tw4ZZJcM XF1mshp8ZnPl957kp8zeZNR8w6pJf3rddoYQfgijrsi/xPfOp0+COKPCHzPXa6epyGc/gO4dyU5e 4bsVdiqvHY3sqGSO3kdAKl1RiAPmBkTMDqzjimRYB+SiyspKsCGGxB2OFgRTWFXYqrQ2d3OCYIJJ QOpRGb9QyJkBzLOOKUuQJUmVkYqwKsOoIocNsCK5tYVSrWtc1XWr+S/1S5e5upOrudgOyqBsqjwG cU+xIHFXYq7FXYq7FXYq7FXYq7FXYq7FXYqrWl3dWdzHdWsrwXMLBopo2KurDuCNxir1DS/M3l78 wbOLQ/NpSy19Bw03XUAXmeySjYb+HQ9uJ6qWA+afKuseWdUfTtTi4SD4opV3jlStA6N3H4jvihl/ 5G6jEnme50W4+K01q1kgePszopcf8JzH04pYHq+nS6bqt5p0397ZzSQOfExsVr+GKHpenf7gPyKv bv7Nz5huTDGx68OXplf+AhkP04pY1+WnkyPzDq0lzqB9LQdMX19SmOwKipEdf8qhr7V70wgEmhzY TmIxMpGgE187+bJPMGpgwr6OlWg9LTrUCgWMbcio2DNT6BQds6jR6UYY1/Eeb5n2t2lLVZb/AIB9 I/T7yh/JKq3m7R1YAqbuIEHcfaGT1f8AdS9zV2WL1OP+sH0Xd2lp9Um/cx/3bfsjwPtnKxkbG76d kxx4TsOT5aVWZgqgliaADcknOyfIgLe/+Svy50fQ7GGa7t0udWZQ000gDiNiPsRg1A49K9T+Gczq 9dPISAai+j9l9i4sEAZASydSenkEwv8A8wfJ1hftYXWpIl1G3GRAkjqrdKM6KyCnep2yqGiyyjxC Ozk5e2NLjnwSmOL4/fVIrXfLOheYbMxX0CTB1/c3KgeolRsySDf+ByGHUTxG4lu1ehw6mFTAPcev wL5z1zSZ9I1e702c8pLWRo+Y2DAfZb/ZLQ51WHIJwEh1fMNVpzhyyxnnEvVvyy/LnTk02DWtXgW5 ubpRJawSjkkcZ+yxU7MzD4t+gp3zS9oa6XEYQNAc3sewuxYDGMuUcUpbgHkB+1mOsecvKugzJaah epbS8QVgVHche1ViVuPtXMHFpcuQXEW7vU9p6fTnhnIRPdRP3BW1HR/L/mbTFNzFHd21xGGguFA5 qGFQ0b9VO+RhlyYZbbEM82mwarH6gJRI2P6i+efNGgzaDrt1pcrc/Qb93J05xsOSN/wJ3986jT5h kgJDq+aa/SHT5pYz0+7owfORfV3Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXqnlDzJp3nTSF8l +a5ALwCmh6s28iyAbRsxpU7UFT8Q2+1TFLEILXUvJfnm0XUE9KfTbqKSQj7LxBgSynurpXFCb/nZ pYsfP13IopHfxRXSeHxLwY/S8ZOKp/8AmtaXMGm+TvJdkhe6SBWeBerTOFiQ/S4kxSv84S23ljy/ aeR9McF0C3Gt3CberO4DcD7dD8gvvm67L03+UPw/W8b7Tdo/5CJ85foH6fkwTN28cnnkf/lMNG/5 i4v+JDMbV/3UvcXP7K/xrH/XD6QvP95J/wDjG3/ETnKR5h9RyfSfc+YdDeJNb095iBEtzC0hboFE gJr9GdfmB4DXcXybSEDLAnlxD731HnHPrj5j8z6RqGk65d2l+jLMJGdXNaSIzEiRSeobOv0+WM4A xfJ9fpp4c0oz538/Nn+gfnJY6dotlYXFhNNLawpC0quoDcBxB336DNZm7LlOZkCNy9Jo/aWGLFGE okmIr5MJ806vF5l81TX9vE0C3rQosbEMwKosXbb9nNjp8XhYuE71boNfqRqtQZxFcVfcA+kIYY4Y UhjHGONQiKOyqKAZyZNm31GMREADkHzR5vvpL7zRqty7cudzIqnr8CMUQfQqjOt00OHHEeT5X2ll OTUTkf5x/UPsel/l9+YXlbS/KlnYapf+jdwGQGMxTPRWkZl+JEYdG8c1Ot0WSeUyiNj7nqux+2dP i00YZJ1IX0l3+QYb+aOuaLrXmKK90mf6xB9VSOWTg6fvFd6ikiqfslcz+z8M8eOpCjbou3tXiz5x PEbHCO8b2e/4PLM5l9IdirsVdirsVdirsVdirsVTLSfLev6w/HS9PuLzsWijZlH+s1OI+k4qzHTv yK89XSh7lbbT06t9YmBIHyiEv4nFKOP5P+W7PbVvOthbOOsK+mWr7cpVP/C4qtfyJ+U0QPqec+XH Y8EVt+m3ENX6MVW/4B/K2ZVFv51WN23BljUClO4Jjp9JxVa35KveAny95k03ViASEVwjED2jM4+8 4qxTXvI/m/y43q6jp80EcZBW7j+OIGux9SMsq+1SDihnkxX8y/IrXFAfOHl5P3lPtXMHXt1LUNP8 sduWKUV5jsP8Rn8ttRoHN6Ira9Y9/SMbP+qTFU/1D6tD508w+db9Q9v5fij0/Skbo9y0YZ/+Babj 9JPbLcGE5JiI6uJrtUNPilkPQfb0eR3l3cXl3Nd3LmS4ndpJXPdmNSc66MREADkHyrJklORlLck2 o5Jgnnkf/lMNG/5i4v8AiQzG1f8AdS9xc/sr/Gsf9cPpC8/3kn/4xt/xE5ykeYfUcn0n3PlPO0fH 3tv5dfmXZahawaTq0oh1OICOKeQ0ScDZfiPSTxB6/hnPa7QGJMo/T9z3vYvbkMkRjymsg2v+d+37 2Z635e0fXLX6tqdstwgrwY7OhPdHHxLmvw554zcTTvNVo8Wojw5I3+j3PHvOn5T3+jRyX+lu17py VaRCP30SjuQNnUdyPu75vdJ2lHJ6ZbS+x4ntT2engBnj9UPtH6/xswvSP+OtZf8AGeL/AImM2GX6 T7nRab+8j/WH3vqbONfXXyzq/wDx1r3/AIzy/wDEznZYvpHufItT/eS/rH70JljS7FWOZxT7E7FX Yq7FXYq7FVyI8jrHGpd3IVEUVJJ2AAGKs70X8odbmtf0j5guIfLulihM14QJSD4RkrQ+zkH2xVMh rf5QeV/h0vTZfM1+m31q8+GCvsrLx6/8V/7LFKX6r+dvna8T0bKSDSrYDisVpEKhew5ScyP9jTFD DtR13WtTYtqN/cXhO/7+V5PuDE4qgcVdirsVbVmVgykhgagjYgjFWX+XfzW846KRGbw6hY/Zks72 syFehUM3xrt4Gntir0byU3lnWtYi8yeUE/RWtW+2saAWAimt5DSQxfZXbZlIovIDkFrXFL0ODyrZ QHT1iNIdOvZ762joKL9YSYMg9g9wSPCgwK80/OHUobaS28vWh/dq8l/e+81w7OAflyY/IjN72Th2 Mz7g8V7U6y5Rwjpuf0fjzeaZuXkXYqnnkf8A5TDRv+YuL/iQzG1f91L3Fz+yv8ax/wBcPpC8/wB5 J/8AjG3/ABE5ykeYfUcn0n3Plmzs7q9uo7W1jM1xMeMUS9WPgM7KUhEWeT5FixSySEYi5FOZPIXn GKNpJNJnVEBZ2IFAAKk9cxxrMR/iDnS7I1QFnHJN/J/5pa1ojx218zX+mCimNzWWNf8Aitz4fynb 5ZRquzoZNx6ZOb2b2/lwERn68f2j3H9H3PdLK8tr6zhvLZxJbXCLJE47qwqM5ycDEkHmH0HFljkg JR3jIW8E85aRa6J+YDQwAJaGeG4jQdFWQhmUDwDVp7Z0ulynJgs86IfOu09NHBraj9PED830FnMP pL5b1uNo9av42+0lzMp+YkIzssRuA9wfI9UKyzH9I/enflv8uvMHmHTjf2DQCASNF+9dlbkoBOwV vHMbProYpcMrtz9F2Lm1MOOHDV1uf2ILzR5R1Xy1cQQaiYi9wheP0mLCgNN6hcs0+pjlBMejRr+z smlkBOt+5gOcm+puxV2KuxV2Ksp8nfl3rfmblcpxsdIhqbnVLj4YVC7txrTmR37DuRirJJfOPk3y YptfJloupasAVm1+8XkAeh9FdvwoP9bFLA9b8w63rl2brVryS7m34mQ/CoPZEFFUeyjFCXYq7FXY q7FXYq7FXYq7FUbo2saho2p2+pafKYbu2YPGw6HxVh3VhsR4Yq+tPLuvWut6BZ6zDRIbqISMCfsM NpFJ/wAhgR9GBSafOnmXV21jX77UidrmZmjr1EY+GMfQgAzsNPi4ICPcHyfXajxs0sn84/Z0+xLM ucV2Kp55H/5TDRv+YuL/AIkMxtX/AHUvcXP7K/xrH/XD6QvP95J/+Mbf8ROcpHmH1HJ9J9z5n8ra hHp3mTTL2U8YYLmNpW8E5AOf+BrnW6iHFjkB1D5VoMwxZ4TPISF+7q+mZY47i3eNviimQqSO6sKb ZyINF9WlESjXQvA7v8pvOkN+1tDZi4h5UjulkjCMtdmPJgy/IjOmj2lhMbJryfOcns9qoz4RGx32 Ke3eW9KfSdBsdNdxJJawqkjjoWpVqe1emc7nycczLvL32i05w4Y4zziHhf5n6pBqHnO9kt2DRQcL cOO7RLR/ueozpOz8ZjhF9d3z7t3OMmqkY8ht8v2vcvLGtQ61oNnqMbBjNGvrAfsygUkU/Js5zUYj jmYvoGg1Qz4YzHUb+/q8s8+flj5hm8xXV/pFt9btL6QzEK6KySPu4YOV6tUgjNzo+0MYxiMjRDyH a3YWeWeU8Q4ozN9NiefN6P5D8vz6D5ZtdPuSPrQ5SXAU1AeRieIP+SKDNVrMwyZDIcnqOydGdPp4 wl9XM/F5P+cOqxXvm4wRMGWwhS3cjcepVnbf25gH5Zuuy8Zjis9TbxvtJqBk1ND+AV8ef6U7/wCs d/8Al2/6fM5x9Ed/1jv/AMu3/T5irv8ArHf/AJdv+nzFXf8AWO//AC7f9PmKtj/oXev/AB7f9PeK s18yf4F/wzb/AKX9P/Dnweh6Hq/VqU/d/wC83w8f5a7YFYT/ANY7/wDLt/0+YVd/1jv/AMu3/T5i rv8ArHf/AJdv+nzFXf8AWO//AC7f9PmKu/6x3/5dv+nzFXf9Y7/8u3/T5irv+sd/+Xb/AKfMVd/1 jv8A8u3/AE+Yq7/rHf8A5dv+nzFXf9Y7/wDLt/0+Yq7/AKx3/wCXb/p8xVnflr/B3+Fn/QXH/D9J uXD1eNN/Vpz+Px6YY3Yrm15eHgPF9Nb+5in/ACA3/ij/AKes2v8Ahnn9jy/+tH9H/ZO/5Ab/AMUf 9PWP+Gef2L/rR/R/2Tv+QG/8Uf8AT1j/AIZ5/Yv+tH9H/ZIzRv8AlT/6VtP0Z6P6Q9VfqnH6xX1K /DTl8PXxyGX81wnivh68m/TfyZ4kfDrjvb6ubP5fT9J/U/u+J5/Km+awc3pJVW/J5p/yA3/ij/p6 zbf4Z5/Y8p/rR/R/2T0HR/qH6Ltv0fX6j6Y+rcudfT/Z/vPipTpXtmsy8XEeLm9LpuDw48H0Vtz5 fHdGZW3qV16X1Wb1uXpcG9Thy5caGvHh8Vafy7+GGN2KYZK4TfKvxy3ebn/lR1d/Qr/0dZtv8M8/ seX/ANaP6P8AsmV+TP8AB/1a4/wxT6tzHr8PW9P1KdvV25U609q9swtV4tjxOfwdx2Z+V4T+X+m9 /qq/iyLMV2bj0xV5rcf8qU9eT6x6Xr829bn9b5c6/FyrvWvXNtH85W3L4PLT/kmzxVfX63//2Q== uuid:9EF2320A284E11DFACBCF5F943788E24 uuid:6e7acc0d-a5db-48fe-a148-3d0ba888c54f uuid:dd936053-2ab1-11de-bf43-000d93c1f82e 1 False False 51.000000 66.000000 Picas Cyan Magenta Yellow Black Default Swatch Group 0 White RGB PROCESS 255 255 255 Black RGB PROCESS 39 37 37 Yellow RGB PROCESS 255 242 45 Lime RGB PROCESS 189 213 118 Night Blue RGB PROCESS 31 113 184 ISC logo blue PROCESS 100.000000 RGB 0 168 204 PANTONE 425 U PROCESS 100.000000 RGB 94 96 98 Document Adobe PDF library 8.00 endstream endobj 2 0 obj <> endobj 16 0 obj <> endobj 38 0 obj <> endobj 60 0 obj <> endobj 82 0 obj <> endobj 83 0 obj [/View/Design] endobj 84 0 obj <>>> endobj 61 0 obj [/View/Design] endobj 62 0 obj <>>> endobj 39 0 obj [/View/Design] endobj 40 0 obj <>>> endobj 17 0 obj [/View/Design] endobj 18 0 obj <>>> endobj 81 0 obj [82 0 R] endobj 5 0 obj <>/ArtBox[247.087 367.565 365.086 412.583]/MediaBox[0.0 0.0 612.0 792.0]/Thumb 92 0 R/TrimBox[0.0 0.0 612.0 792.0]/Resources<>/Properties<>/ExtGState<>>>/Type/Page/LastModified(D:20100412113400-07'00')>> endobj 88 0 obj <>stream H‰tUIŽ$7 ¼ç+ôb‹‹¶«Û†OcàƒP°}©`ÜÿÁLU7Ð6 ÈT¤$.Aëå·×òòåµ–Ÿ~~-Ç£–±¬tµrãâŸ??Ê÷ãåõ÷Zîo¥ŠÏgçsF)owlÿŠí¿ßŽEKÅO‹õ!ÝZq¼[oQîßî|;ÂÅ`¸–ÇáK¦GQ—¹ð²²$h¿ûñ×ñõƒ=¯KZôUà_*Oƒ·!ˬè‰Ï7ŸÒ*WYL¢›D‡m‰æ°zá[“˜Šnâ>?|°%6Kø ›Øiê?ÃÒš)0*¾ßƒ2!} j´rS…[2 1Z“ÞGA¨u£r•~îωãÞeTä²އ¦1'ïÇIŒ‚HGGŠ`´kf ò¸—wa±FÚFBA[c)L‡4SzZŠÓ¼ÄÓSF¬äDZÊІ9ù¸> Hº¡ J‚xi†þOá@½-M†xôÉ‚î³_¨OC8³Ä:JXl 0$‡(•vàª~FC¬žm†¢Ëj£4QzÐŒT³«´$Ù‚±³ ¬‘î5Þ[š¸FÚ3föòùˆÏAk€¥ûl0,¥·'XIo Ïy*æ#Až‡?+E#;™J¹–ºp”UQ–§Â< F ‘åReBC[¬ÐWçz %A2×¹NôØV𑿠BqÕ•l9uš× ^D5 ™]ÀS—÷ã‚H¯X4¾¢oÆØ ŒÉÆÞõcUÑrΣe©úx"E]æ†`¦Øº:AcÁѶÓ}¸oüxbˆ Òétž^‚fO„€PÈúÄÙt“ÍÚ16 Ì‹<{a˜ïºõ4ÖØ(®)tAtR÷´[bvL·>³o [Õ³ü˜“ÓÓ–²\AYŸ`IõÌõ„ˆ‰sz£“$Œ‰ýÁ˜˜IO !=§ ¨Œø†vGc £I#/'~<1‚ÀÔRPy±´ýl1½Ͷw1 чd }¡þa#fßËþÚF¯ÞƒÇY}ïAô Ë9b :žÎÞF" ‹>64”~0IGD˜Ë ذ$ÙtMâ¯%Z½Gð¾¥Úñ§aÑÌ‘ I¼ ý—/øýzü+À0hu endstream endobj 92 0 obj <>stream 8;Z][]*Z8,$q8Pq<-a,+atR/Xlf;Og>R'7AkC?`UH+a:[!:Wd2gY.%C?Yr]87.+,n j3C.,APLcVQ0Wa_MIB(XjL_"klFg6$$NL0W09-&5e4ja+~> endstream endobj 85 0 obj <> endobj 86 0 obj [/ICCBased 87 0 R] endobj 87 0 obj <>stream H‰b``2ptqre``ÈÍ+) rwRˆˆŒR`?ÏÀÆÀ̉ÉÅŽ> v^~^*øvD_Ö™…)p%•é?@l”’ZœÌÀÀhdg——ÅçÙ"IÙ`ö»($ÈÈ>dó¥CØW@ì$û ˆ]ôý¤>Ìfâ›aË€Ø%© {œó *‹2Ó3J ---Sò“R‚+‹KRs‹<ó’ó‹ ò‹KRS€j!îAˆBPˆi5Zh’èo‚Öç@pø2ŠAˆ!@riQ”ÉÈdL˜0cŽƒÿR–?1“^†: üSbj† ú ûæÀÆOý endstream endobj 90 0 obj [/Indexed/DeviceRGB 255 91 0 R] endobj 91 0 obj <>stream 8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn 6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 72 0 obj <> endobj 73 0 obj <> endobj 74 0 obj <>stream %!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 13.0 %%AI8_CreatorVersion: 13.0.2 %%For: (Brian Reid) () %%Title: (ISC_logo_only_RGB.ai) %%CreationDate: 4/12/10 11:34 AM %%BoundingBox: 247 367 366 413 %%HiResBoundingBox: 247.0869 367.5654 365.0859 412.583 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 9.0 %AI12_BuildNumber: 434 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0.658824 0.8 (ISC logo blue) %%+ 0.372549 0.376471 0.384314 (PANTONE 425 U) %%+ 0 0 0 ([Registration]) %AI3_TemplateBox: 306.5 395.5 306.5 395.5 %AI3_TileBox: 18 33.1201 594 786.96 %AI3_DocumentPreview: None %AI5_ArtSize: 612 792 %AI5_RulerUnits: 3 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 0 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI9_OpenToView: -381 793 0.92 1268 743 26 0 0 117 75 0 0 1 1 1 0 1 %AI5_OpenViewLayers: 7 %%PageOrigin:0 0 %AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 75 0 obj <>stream %%BoundingBox: 247 367 366 413 %%HiResBoundingBox: 247.0869 367.5654 365.0859 412.583 %AI7_Thumbnail: 128 52 8 %%BeginData: 10932 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C45FD1F52285252A8FD04FFFD05A8FFFFFFA87DFD4F52285252522852 %525228525252285252522852525228525252285252522852277DA8FFFFA8 %7D7D525227FD04527DA8FFFFA85252275252522852525228525252285252 %522852525228525252285252522852525228525252285252522852525228 %52525228525252285252522852525228525252285252522852525228FD21 %52A8FFFF7D7D525227FD0752275252A8FFFF7DFD215227FD2A522E522752 %2E5227522E5227522E5227522E5227522E5227522E5227527DFFFFA85252 %27522E5227522E5227522E5227522752A8FF7D5227522E5227522E522752 %2E5227522E5227522E5227522E5227522E522752277D7D7D275227522E52 %27522E5227522E5227522E5227522E5227522E5227522E5227522E522752 %2E5227FD1A52277DA8FFA87D2EFD11522E527DFFA853FD1D52A8FFFFFF7D %28FD285228525252285252522852525228525252285252522852277DFFFF %7D522752525228525252285252522852525228525252275252FFA8522752 %285252522852525228525252285252522852525228525252277DFFA852A8 %FF5227525252285252522852525228525252285252522852525228525252 %285252522852525228FD1852277DFFFFFD1B52FFA8FD1A527DFFA8275252 %FF7DFD265227522E5227522E5227522E5227522E5227522E522752277DFF %FF525227522E5227522E5227522E5227522E5227522E5227522E52275252 %FFA852275227522E5227522E5227522E5227522E5227522E522752A8A827 %522E527DA9275227522E5227522E5227522E5227522E5227522E52275227 %5227522E5227522E5227522EFD17527DFFA8FD1E527DFFA8FD17527DFFFD %0452287DFFFD155228FD075228FD08522852525228525252285252522852 %5252285252522852527D2752525228525252285252522852525228525252 %2852525228525252285252527DFF7D522852525228525252285252522852 %525228FD0452FF7D5228FD0452FF52522852525228525252285252522752 %2752527DA1A8A8FFCACFA8CAA17D5252275228FD3C52A8FFFD145228A8FF %53FD0652FFA82EFD0C527D7DCAFD04FFAFAF85AF85AFAFFFFFFFA87DFD05 %522E5227522E5227522E5227522E5227522E5227522E5227522E5227522E %5227522E5227522E5227522E5227522E5227522E5227522E5227522752A8 %FF275227522E5227522E5227522E5227522E522752FFA827522E5227522E %FF7D522E5227522E522752275252A8FFFFAFAF603CFD041413FD04143C60 %AFFFFF535227FD3A52277DFFA827FD11527DFFFD0852A8FFFD0952A8CFFF %FFAF3C3D1414141A141A141A141A141A14141461AFFFA8FD045228525252 %285252522852525228525252285252522852525228525252285252522852 %5252285252522852525228525252285252522852525227A8FF5227525252 %2852525228525252285252522EFFA85227525252285228A87D5252522852 %27527DFFFFAF603CFD07141A1414141A1414141AFD041460FFA8FD3D52FF %A8FD10527DFF7DFD0F527DFFFFA9611414141A141A141A141A141A141A14 %1A141A141A141A14143CFFA827522E5227522E5227522E5227522E522752 %2E5227522E5227522E5227522E5227522E5227522E5227522E5227522E52 %27522E5227522E5227522E527DFF525227522E5227522E5227522E522752 %A8FF27522E5227522E5227522852275252A8FFFF3C1413FD191436FFFD3C %5259FFA828FD0E52FF7DFD0D527DFFFF8B1414141A141A141A141A141A14 %1A141A141A141A141A141A141A141A141460285252522852525228525252 %285252522852525228525252275227522752275227525252285252522852 %52522852525228525252285252522852525227A8FF7D2752525228525252 %2852525227A8FF52275252522852525228522752A8FFA93CFD05141A1414 %141A1414141A1414141A1414141A1414141A1414141A1414FD1552285252 %7D527D597D527DFD065227FD1852FFA8FD0D52FFFFFD0A52277DFFFF601A %141A141A141A141A141A141A141A141A141A141A141A141A141A141A141A %141A142E5227522E5227522E5227522E5227522752527D7DA8A8FD09FFA8 %FFA8A87D532852275227522E5227522E5227522E5227522E5227522E527D %FF525227522E5227522E52275252FF7D522E5227522E522752277DFFFF36 %FD2314FD0E527D7DFD07FFA8A87DA87DA87DFD04A8FD05FFA87DFD15527D %FFA827FD0A52A8FF7DFD0952A8FFAF1414141A141A141A141A141A141A14 %1A141A141A141A141A141A141A141A141A141A141A145252285252522852 %525227527DA8FFFFFFA87D7D52522752275227522752275227522752527D %A8FFFFFFA87E52522752525228525252285252522852525227A8FF522752 %5252285252522752FFA8275252522852525227A8FF85FD05141A1414141A %1414141A1414141A1414141A1414141A1414141A1414141A1414141AFD07 %52275253A8FFFFFFA8FD045227FD0F522EFD04527D7DFFFFFFA87DFD1052 %7DFF7DFD0A52FF7DFD0852A8FF8B1414141A141A141A141A141A141A141A %141A141A141A141A141A141A141A141A141A141A141A1427522E52275227 %7DA8FFFFA85252275227522E5227522E5227522E5227522E5227522E5227 %522E52275227527DFFFFFF7D52275227522E5227522E5227522752A8A827 %5227522E52275227A8FF5227522752525227A8FF6113FD2714FD0652A8FF %FF7D7D28FD22527DA8FFFF7DFD0C5227A8FF7DFD0852A8FFFD06522EA8FF %61141A141A141A141A141A141A141A141A141A141A141A141A141A141A14 %1A141A141A141A141A141A14285227527DFFFF7D52522752285252522852 %525228525252285252522852525228525252285252522852525228522752 %52FFFFA8525228522852525228FD0452FF7D5228525252285252FF7D5252 %52285227A8FF611414141A1414141A1414141A1414141A1414141A141414 %1A1414141A1414141A1414141A1414141A141452277DFFFFA87D28FD2952 %287DFFFF7EFD0B52A8FFFD065227A8FF7D2752525227A8FF8B141A141A14 %1A141A141A141A141A141A141A141A141A141A141A141A141A141A141A14 %1A141A141A141A1428A8FFFF525227522E5227522E5227522E5227522E52 %27522E5227522E5227522E5227522E5227522E5227522E5227522E522752 %7DFFA87D275227522E522752277EFF52275227522852A8FF52522752277D %FF8BFD121413FD0F1413FD0914FFFFA8FD3352FFFFA8FD0952FF7DFD0652 %FFA8FD04527DFFAF141A141A141A141A141A141A141A141A141A14613C3C %141A141A141A141A141A141A143D3C3C141A141A141A14FF7D2752525228 %525252285252522852525228525252285252522852525228525252285252 %522852525228525252285252522852525227A8FFA8FD045228525252A8A8 %27522852277DFF7D27522752A8FFFD051461A9AF848B1414141A141436AF %AFFFFFFFAFAF36FD04141A14141461A9FFAFFFAFAF601A1414141A7D2EFD %3552277DFFFFFD0752A8FFFD05527DFFFD04527DFF3C14141A141484FFFF %FFAF1A141A141A85FD09FF841A141A141A14AFFD08FF841A141A1427522E %5227522E5227522E5227522E5227522E5227522E5227522E5227522E5227 %522E5227522E5227522E5227522E5227522E5227522E52277DA8FF52522E %5227527DFF52522E5227FFA852275252FF60FD061485FFFFFFAFFD041460 %FD0BFF36FD0414AFFD0AFF60141414FD3A5253FFFF7DFD04527DFFA85252 %527DFFA8285252FFAF1A141A141A141A84FFFFFFAF3D141A14FD05FF603D %60FD04FFAF141A1461FD04FFA96136AFFD04FF141A142852525228525252 %285252522852525228525252285252522852525228525252285252522852 %52522852525228525252285252522852525228522752A8FF5252285252FF %A8FD0452FF7D5227A8FF3C141AFD051485FFFFFFAF14141460FD04FF3614 %141460FFFFFFA91A141484FFFFFFA91A141414FD04FF611414FD3D52A8FF %FD0452A8FF525228A8FF7D277DFF8B141A141A141A141A85FFFFFFAF1A14 %1A60FD04FF3C141A1461FD04FF141A14FD04FF8B141A141AAFFFFFFF601A %142E5227522E5227522E5227522E5227522E5227522E5227522E5227522E %5227522E5227522E5227522E5227522E5227522E5227522E5227522E5227 %522752A8FF5252277DFF7D2752A8FF2752A8FFFD08141385FFFFFFAF1414 %1361FD04FF36FD04148584856014133CFD04FF60FD0414FD04FF851314FD %3D52287DFFFF525252FF7D5252FFA8527DFF3C1A141A141A141A141A85FF %FFFFAF1A141A60FD04FFAF141A141A141A141A141A3CFD04FF61141A141A %3C616061361A145252285252522852525228525252285252522852525228 %525252285252522852525228525252285252522852525228525252275252 %522752525228525252277DFF7E2752FFA82753FF7E27FFA914141A141414 %1A1414148BFFFFFFAF1414143CAFFD04FFAFFD091461FD04FF3614141AFD %07141AFD2B522852285227FD075227FD075227A8FF7D27FFA8527DFF7D7D %FF3D141A141A141A141A141484FFFFFFA91A141A1485FD06FF603C141A14 %1A14143CFD04FF61141A141A141A141A141A1427522E5227522E5227522E %5227522E5227522E5227522E5227522E5227522E5227522E522752275227 %FD04527D7DA8A8FFA8FFA8FFA8A87D7D52522752275227FFA8527DFF277D %FF52A8AF13FD0A1485FFFFFFAFFD0414138BFD06FFA860FD05143CFD04FF %36FD0B14FD2852A8A8FD07FFA8FFA8FFA8FD06FFA87D5227527DFF7D7DFF %7DA8FF7DFF3C1A141A141A141A141A141A84FFFFFFAF3D141A141A148BFD %07FF8B141A141A3CFD04FF61141A141A141A141A141A1428525252285252 %522852525228525252285252522852525228525252285252522752275252 %A8A8FFFFFFA8A87D7DFD065227FD04527D7DA8FFFFA87D2752A8FF52FF7D %A8A8CAA914141A1414141A1414141A1485FFFFFFAFFD071460A8FD06FF8B %1414143CFD04FF36FD04141A1414141A1414FD2252A8FD04FF7D7D525228 %5227FD0B52275252527DFFFFFF5253FFA8A8A8FFA8FF61141A141A141A14 %1A141A141A85FFFFFFAF1A141A141A141A141A60FD06FF85141A3CFD04FF %61141A141A141A141A141A142E5227522E5227522E5227522E5227522E52 %27522E5227522E5227522752277DA8FFFFA859522752275227522E522752 %2E5227522E5227522E5227522752277DA8FF7DA8FFFFA8FFFFAFFD0C1413 %85FFFFFFAFFD061413FD0414AFFD04FFA9141360FD04FF36FD051413FD05 %14FD1D527DFFFFFF7D7DFD1E52A8FFA8FD05FF601A141A141A141A141A14 %1A141A85FFFFFFAF1A141A143D363D141A141A14FD05FF3C1A3CFD04FF61 %141A141A60AF85AF601A1452522852525228525252285252522852525228 %52525228525252277DFFFFA87D2E52275252522852525228525252285252 %52285252522852525228525252285228527DFD06FF3C141A1414141A1414 %141A1414148BFFFFFFAF141414AFFFFFAF8BFD04143CFD04FF3C143CFD04 %FF60FD04148BFFFFFFAF1414FD1752285259FFFFA9525227FD2352A8FD04 %FFAF141A141A141A141A141A141A141484FFFFFFA91A141484FFFFFFA91A %141A1461FD04FF3C1414FD04FF8B141A141AA9FFFFFF85141427522E5227 %522E5227522E5227522E5227522E52275227527DFFA87D27522E5227522E %5227522E5227522E5227522E5227522E5227522E5227522E5227522E5227 %522752A8FFFFFF60FD0E1485FFFFFFAF14141485FD04FFFD041436FD04FF %3C141484FFFFFFA8FD0414FD04FF611414FD16527DFFFF7D5228FD275227 %A8FFFFFF3D141A141A141A141A141A141A141A84FFFFFFAF3D141460FD04 %FFAF363C3CFD05FF141A1461FD04FF853C148BFD04FF3C1A142752275227 %52275227522752275227522752275227A8FFA82852275227522752275227 %522752275227522752275227522752275227522752275227522752275227 %52275252FFFFAFFD0F1485FFFFFFAFFD0414A8FD05FFAFFD05FF36FD0414 %AFFD0AFF841414147D527D527D527D527D527D527D527D527D527D52A8FF %FF527D527D527D527D527D527D527D527D527D527D527D527D527D527D52 %7D527D527D527D527D527D527D527D527DA8FF853C363D3C3C363D3C3C36 %3D3C3C363D85FFFFFFAF3D363D3685FD0AFFAF3C363D3C3C60FD0AFF6136 %3D3CFD16FFA8FD49FFAFFD11FFAFFD09FFAFFFFFFF %%EndData endstream endobj 76 0 obj <>stream %AI12_CompressedDataxœì½ëŽ]Iv&öçÒ?tM*î—¶1@æÉLY%5º[ @±¨ÇE²Áª’Ü~zÇZëûVìs2Y]7Æ@ç“™+÷‰;"ÖýöÿÓ¯ûâöËÿüöE~nNñçOo_óñÓ¯nzó×_}õí×ß|Ð/~óË›¸îZ7Ýþõø7þÃÛO_¿ûøáWú§—iýñQ>ý‹»Oï^¸ùÍÛw_þòæ¿\àß½ûæ«·ëýÛó_}üýÇ/>~øê_üæ¯î^¾~÷K>xtÿú›u[ù˘þ2†›•ËÍí߬î>~ûáËw~÷ñÿþÕM*ý&7ù×nJÌëÏÿû»ß¼ýúúž—a´)7¾¬­–õC]:×GÒË:äc÷ß|ûþí‡o~ýéã›·_}þøÕÇO_ÿêæüÇ5û¿yýûõ—×7ÿçÛ¯¾úøï7w_½~óÖË×/ß}õv½çû×ßÜLY‘Û¿Žé‹»oß}õåß~ûþŸß®(¹8¡#þý×k¨5ªü,àþÅ_¿_ß¾ýæ›5Ûõ~õZWL¯ˆÿÃM°~÷úÓïß~³ŽÂǯ¾ýFæøÓÚšW¯ÿøV¶7Úþîo?üîã?èü^ä×lòZÀ™nbj㦗|“š='ö›^ñȨŌd C÷µÐ¿^{ûwŸÞýþ݇_abý‹¿úôî˽ß=Ý û¦o°vwÿ›üg“\ïûÍ7o?`ÒëœÿæpnÂË¿ùízâÇ/ÏßË‚-¨²¶÷Ã:Kë°ØßügýËúø·°Ùëï_¬½ùõ§wdÌÓßê_Æ¿þêÛõ§¿úôñÛ?üõ‡ùxú…„_¿þæ_&¼ýðå× ± f¿ÞØ'ôÕ»{k°…ÛøåwŽ÷»O¯ß¬ÇÞüÝ?ÿ··o¾Y`ÿôÛoß}óöOôÛ7²LŸnî>}ûõ¿Þüîãǯ|~—òi¬P¹ÿŒgüZ?ðáï>ØJ?}n¸~ÒÂŒÿáž²îþüÖÿGýüú«¯ÞýþÓë?üë»7Ï=à™¿û“ìo?àa Ç?½ÝŸ×_ùÿ÷8–|ÿÏ¿z÷õû}_¿þôÍ»7_½ýí¿þæíû?=ÚýÛYœí°l }øðoo¿úø‡Ã$òú×7ÿåõ§?|×вMÿòî× CŸ÷2~|ÿaÚ7¿ý××x«Óýæ_õÎß~cüÕë¯?Ý(܇ò³Îï¢g—$É`>hýbÆ#é{ñâ;hb¿¹ûpøó_}zýå»Em—@ó÷>¼~ÿöË›ßôËÓSТñõæîËÓ?þ·Sˆëú¿N?ç`ÿ øƒ_øôŸ×JÝ=ÜÝßïîînïæ]¿kwõ®Üå»xnnïoïnooçºúm»-·ù6݆ù8æyÞMù³Í%–Ì4à ãq<œÆyÜc´±ä¿‘Öúc¿_×¹ßõ¹®Ñ{¯ë*=õØc{lëºowm=§Ö×ÕZYW>µÜR -ÔÇú°®óºÖ$ëm]£ËµŠÜ¹®¼®¸®PCy\×úÎëº/ë•Ê­^£ŒÓv=¸èg ¿®È+?îËVê׃^ûçõÿ9œ£~—+žÓº"þOç¼.þl¿Ë=ñä€xñgûý;þœ×ñ¹t=ìç“þÚüª×5”¿w\ã ¤ŸÐþÄËÿtxÌŵV*¬µº¯ëj¸tçﮉë×^g\üzðëQ®ÓýãCÀq%¿²_Wõ«®î×8= ¿æáº=\w×ù꺿¼NëÛ羟¿ôT­cÞןëØß­õ»_ó|ìa!EêyÒº0A¾ÆBšÛ…<çµ”ýq„±–²Ð >äkŽÛÓ¾³®ôÃx\Hj¦™ŠÖuµ…|‚œsáôÂ÷…Æ÷úÞ·a]q¡w^W¹]صq=ñvœnÇÂùº»=¯K6M–çñ.¬+®+­+¯KÐLPs½È¢$ýnÍäNŸ²hËí}ïÎ'Ûñ 4"ê?û¡+Upâ>ïëáp=/¡‡+^\I®“ý·®|u•«ëú«=¹”˜ì?¿Æ³×üìu{}ž€îþÔµVªÜüÅwŸ„ .ЬÿùÕ}QQûn×¢“úWÆw»Òºì{2È ?$ÿ³\—|ý@ôß…«®¹éñYï++q»Níý"#1Æ¥ÁǶØÏŒ·ëÀÝÇÇõ>)åu$Zê mn×ɾ_æ1ÇœrYG£ç±ä.ß/ž°Ö*–¼Î‡°“¹¿œÌG=kIM[»-[v^tèq­w\œ¬¬Ó"ø.ؾp˜^ËO É ÅÁ½‹"öBjÅhÁfÁdÃbÁ`ÅÞ…·IqVðu(š.Ô<)NVÅÆ©x´ÓÕ¸ e‚ˆ‚ÓB >’b ½À± j›7 >]ü!‘X Ù^ô[ä½Òwà¾Ò}ãB«„?§¨z)bŸÖ·µÌë{º_[s¿6íü¸®‡5ÊYÿõ^w~ •ZK~E–·¸cV²BC†õ¸”dž«â"-¡pE½‚]NÏùåì`/.X.rrŸ~±äd[\n_ÑVšÜË‹‹\ˆ_\.¶]ó°äã„uçÚcýít PÕ È3mïuÄ[¡ëí²G²?ÁwæNWßV^ä’,òËI×û(iŽƒ¬™TÚ|Tyó ‰s¨ÄY!sFH÷*wÞÎyZ<¬CôÌ +¢ ŸëµDú¼U鳫üYT*>@½…ÚTÍ"ƒžU|Tô¬BèT!´ãyÂéÿôÕŸ¿NW€ñ=®ù]×ɼý^×ÝŸºNJÍž\G梤ÿQH¦aÃ:“ OùýApv}?ëÿü~qa}¿Õÿù]þ¿=­ÿ¦^ßåêz5¥ÒòÝø7t|—ÿ“þŸÖe_‹êŸô?ü‚ïÁ0ÖpGÙÀ½^g|?‹HsñýNä"û~Â/óp-þjRÜP9NdÙù´(}­E鈠•Ð aàSu–¶¸CÎ"ˆj-Šð÷¦­œt/eã»k)‹é‹ ‹~Ò(z…r£…‹/­gªø"_²£ÿºê´˜Ù­H‚‹±õõHÑu„ÕÅõ;‰’ÝàÈâÛrËc-mõNºD²4\ ‘1 a×Q¢Ý>¬OÉ& Ù{e±e1Xa¯÷‹µ¦5í¾^㼤÷°^±(FÜ)/>ºä¨“2ÑGe Â>§2ÏÇ5»¼0¸/l^‰¢¢:IQ=c¨úpsQv¤Â3XÔf]Æ$„±=ÚQTf'ÏHÊþ2ÝzШúÉÕ©£*uT¤¶ ¥üáBsÚ:“ëJ'W” ¹^tÔ„Žz«5`ƒFŒ=.VyZßT ×˸ê"Àz:TÍ ¢AUÄ—¡¶Ó5¨m¨®ñDÛ8觃²AE㬢Žé®WP/®S»µ ÂÖœ|g±ã{?¸ÍuZn€->ž‹® ~òÕ¦Fj:¨¬Æ%£üé|òtÉ(:Ÿ<]2Êçù¤Ò=±ÓDØiîÕJsIï²RºpRÓÌýb(b”™JãZ©Gæ²6árÄQ’%úîº\Y]š“K¶,Ûj±wn°*#阩jè»g}o¨­?­Ö×Uò~Öíþ’b~’÷“·ëJ½“Ú“î•^ÏEîÚ"æi1¬Ç…Šg!̧¥Ì·E—…"›aju3Ñb»^¢ÅÜEÉ%ØgŒÎø¢p“.*ÌÕñãi¡gRšŸ•úw1(G¼Ð¾¨BPÖ!êNU†Ò•6‹zVrô¨³‘ç”Óz/JB&{Ü)ÙvUж0%êÈ:¬ དྷ†Åh©F'ÕŽL?\ƒàª¥\ £y7^({O!û ¢Á»¾ùgQ8Ò— ùÚ`P-\¹ÌP/»šLżw%3AÍü¬aét°,=oW:Z•& JÛœdÆ$3%©!é;Ò£Û ìGf:£U"A¾M-GÅǪ̂B£iÉâl–Ò÷¡”žWóëhÙBlö+®h×Ih龄Ãà:š]sº=ûuw¸ö×<)ë²køÕWóktŽbyöKeµ“ýw«8lZÙÖ2 ?§`•˧Šå…Ry©RÊ£2y¾ÒÛ·"9\w‡y:*ð_²Qˆ5ÁõøGˆ>6¾}5xÕáO`jxÞ âŸNâÎO¥‡*>üŽ  qçK¤FX }HHÇ¢=£å›tSÃÍB)à·§¿øâÇp÷õ)¼\îLIn+5Ì¡?Ì,Ì`±€)Ÿ”iŽuëút®/ëÂÌ›Ú_."[|?ÃP6#Þ’ü¤³"?­7H]~X:Özó1ì¥j}Ùâ8Lè§Ž¤ó‰ˆ˜)²ŒÙ¢G^.z²Æ”ˆ›ÅbzVˆ¼¾}¼”—³äÃL~Â:YL_^þ +YbÔ•N±¶¹·Ý6y¾~º§ñÓ†Y3¹»w_(}šßÏ͹Ü3žNÞÄõ:;í+ªaÖd…9aªv†ÅS¤„½¹ªN=TF¸SýÁÔùOÌ :`=«)Ô$„´T̪ÒÁbK ¹…|ðÙ ©×`Û˜'• xXq6fRãa& ‡‘‹T2 y¹ù8xZ_ËjN©ànÆßné59ÃGµX2»à /ÃÀBJ?øQÌ“"¾”³òAõ¨œ„ÊÇJÄŸ"y„ÿ…JÁ5ª²?8Â?‹ò'˜Ý.ð^•ƒò âŸá1ÔOja*°HÀÉiÀý’,„ (ð˜ ó‚ì&[˜m iOÐ`Bª@Ù–Ò-iæg•C`pj>4Gj9¨Ä8P ÒŠM-(†Ñ RŒ†ëài5L½ƒsÜ(ÇÃõ ÿ59¡·¯]Ð¥%§i_·¢rçD„ÅܵÚ²éK„ÄÈk©½—äæHtêA=’Ÿ~^„H¯ÓMºüú,¦HÖ“ëô¹?\Ѹï}~øGþãü¡(nþxàèù€Þàé'øÑÁ½‰àõÎ~DpCnêÿÆßvŸ½Ä¦lÞ¼:‚Ï‚?øüÖV©¯ÂpRmáÈô“+¯‚àÅí„~Š«$pRQ€!ÝÑü(¢?ѯƒ/½!z?Û‡bè­2º£˜ ¨~ìñ á³;iíOO0þîB’ø,Ú‘ÿôy쿸ž¢ÿñ:Óg¨Âó×5­ø,Íxzýè¯Ó÷¸ç»‰ÑÕuúa·ÿ¨/Qüg4ý‡¯®t¸2²­—UcNhÃ4Œ¹…ó(²MK iFÕ¨©ÜžàK¤Ð’°Á ¡h´g>êL\1j6%ï4€ãAýMé´è˜‰)awj¾°¢¤.¨¢¡CqE¤’%XIµ”²ÈÔЀŽ[%N§ö 4)Ã9ÕS„øÐ†dµ,˜½3[¾ÒEîúš4øµ-*}™.R©s«†E ÒI ƒíjˆ;[ sií`u°¼òߦq´ÂšÖ‹|²t¹ ̨èdë•5v»^îá¨5÷‹e¾ØëX‚m³‹éœÔ({ðÀ 5†6ÙÄ(… gKS7”ÝÝ!XL«‹Òxš˜²“?.S?>Ÿöñá8§gãq¾#"ç³9É9ýð˜œË¬š‹œ%…œ•cbÏs‚ÍOH9]ç|gôæhp«E&?"ê‹‚Ô¥:¶¶8u¨¶HuªÚI§f“Óé«£he= W6Ý-^Ù¤Ï'7$¬+Ë¢s->÷ZÄšˆÓ}"bDÂë"oÐräî5G.)ù3Ï’xŒÕø w’ÀH’9©Ÿ­ìk)«(+uíî+ñ¸²L{Ö%¤Ë°^þÎcqåMí°®M¨k-n×v=ªõSÂ÷ïî4t_÷‡š3×Ѭë˜ÞÞß/|Jë0u¸"ç…æ]&z=>gŸÞ¶Mé¤|Ö´ ~£C%ˆô¯EýÄâ1DqD‡¼pr DpÞ>ãǾŽy9z¯Ý›¥Cþ©mØ>ÄkCjŽ*/?¨¤|§2ò¸¯ád1ö&[ bíˆ'+ëÀÊEþ*b˜!„*¼¬Ÿ‰Lû±C!Tn}Jo襪è…q%â.J¸ŸÄœUh¨ýdnùåÌ©gôS‡Ò%ó³ñd$Ùyð%‡Ië÷0ž‘)Ú0?IÂLϪ¥«@5¦׋ÿËáÿç‘/sŽãÖN.öÿLå>þ;9ÔŽ±ë;uúÚ…vAhM/âî,ÞFbm¢º°*œð[°dlM÷ ñM¢JšFµä¼“ vgOD¶Pº~‘‡4¹*á’aàâK‹þŽ'J–ü>+qȰªêšÚßî½c½‘iuÏ\«“:˜lu‹›õ%EuõÏtOWºCŠÒƒ¦&EMGZäKס9øá±Oý1@‡¡~ãિEéuÖŸà¥gÔŸ®‚dd«Ç²¥þ+žìdø®K4ÔwHv:Ý^ÖVx®¾B‡ƒo*»cºÓƒ:ú©NÙJ‚ÔCŽÓ­»ø‘Ô´š˜Ît«¢¥, =t"üUHÈŸÉi~šÕ¼…ÝËdò«ìæÓ“Lòí WðÎr~šçìÂðéVs‘î|‹ŸÊÆ[>Þaë’O»îñëÁ¾£Øw$;cٟij[¶×g¤lÞ×és Ò?V4>}.AúÇæ}ž‘"¡V¶ªÖµ”-ÂEd É“E☬‚2,‘[R¦¬|iŽŒ'X$YèÒ*I»¤½(ÅæƒmÒ‹1Å÷îôŒ}ò»-”´Q²FÑ…R¬”;û÷ÒFùy åµ}Ò¬“—RcûEèbvª–çv¼¿¾×-²$÷q“¾(M|âå°Ä î‡<·ÆõôO…Ÿ8ÎO“vò³ÒN~Ξ6žØÒ¶%m@cØV«~aÛö¬õ™ÓÁ÷Ü üËzÐ.xÂÁ(s–,ÿ>jT`ñx@Ú±¢ªp»ÜÉC '4Ú³‚FsAãž%FhEÚŸÕ~@ëØh=¨VäCÉ©ò˜(4UµbGm<ŸP¢ŒÖ‚¸Hâý-³¸œz] jñ‹£„ºäÓ“†F•œ¦Ê¥¬°¤%T8?€tG¤:Zšã@ÆÀ.ó˜]ó™Èp ëé¨ùè1>Xµ¢‰®íµ?V©"Í »²ãI ª4§^K¨VÒqÞÞ]H§ÛŠúŒ õôœUØ›ÉÀ.éGáí(¾™ðv¯ÇúNú<Ä~µ£Íe„Ó…ÙÅÌ-óÊÜâ5ž-úËí-´¹œ=¿x½íÉ /r=ý"†¦'cÜ£×éPÙð TÄô3SÛ¢J⦑V•4QãÃÍ4Ñ¥|Ý/\L<ÉÀ³ª ª€žÔ¥©(ð (M8ëùoRZhDºE ìŒê×g}ñ®Eä´àµÅ¼ÑšÔÁàÅ…¬8…ß5Y!8)QüíNO¸ðè’ÒI#ÉîÁ‰ÇZ1)íË`~WÇc£<ý)’ñCm”§?M4~Í8}ÆÓit¸¸?wðÙ+¯Óůé³WþŽë¢.äéâ×Ï”>d/?½úåu:ürñe¨ËÔÏva[¸NüüEŠž-ýLìïS¦H3±O‡8 gk}ÏRE^¬èô¹jE—:&j,UH%‡£Rè¥C hî6-I¡9_–uÌ‚?ÛV %ÁEYg& íѱ”I…ÞÆj4ôUçŽøŸa,Ó?ùfï14úÑôFT}yY8 ö)ü¾Æíá§[”°åO˽Ã_Ë!˜Éª¥Ûu¾ª:bÚ1£ä{—˜cæ«eÏ;Fõhù´Îvyft‘wtâ¶Òoû<ýÎÛ,o¾eé{N‰ùœ se9„]ËŽÂö1Mš³öb“nÊx™^Üíaëðq€«ì©]Ì©-Å.¸,yƒ¬³‹©-õ$¸Î½×êUŸZSãªË¨#& 0(ib€ÒÒ~·(Kåö{ §Ö)øÌâ軵ürެØ/Skx·^TwXÎbÑwkée·‘×½i}LqÑêØ rê6µ®¶ùT¥-¼Ç=Ù»­;cŠèÆî«ëw{þR.pÎê|9„è½y‰ro],*é’¯{×7àBC  ÚëÐ.í¯CÅQ–Db0‡X1×Å>}Õ*lrH ¸¨`³‡åVuj[o30­lÇ àNpËeØÂˆ^ôðŵÍæP梛6±µœe(–¶N€í¢¦K¸¶q¸á%ÄÕU*îØ€¹ØYXÀŽ+>ØÇ×ó?–2_ŠH‘u)pEÇ`4<ËëãK9®×Iâ´ólÄ©é6–øRƒc”-ñÆ&µZ©¸SOÍ ¬ ÉÍ(Ã\dXï­ë a¢äEkŸ ™k8ÀÏèkm\Áf³Ï¯—Õ#[ãËÑBpýŽIëUÜ«dÛ€aá#&[r0V›ª,A:Öµ ™¤¸ RØÖFñ“fPè…ÒK}Õȵ£c¾5“G,U‰@é÷kw®åà|×A)DÛßmás·©­U’LAVç•Mü¡ÀѺâ˜ë8>?ãÀÙœL• ÖjÄÚ¤hÇSÌZi«Cטä–×ì|ù_°uY´Y]ˆåüéJñ߀,Û œpj…vÌÁ{׸Èz9Œz=Jcà((e6` a0 †áÎ%ƒ'”Îñ(Á÷æEÏm ȼî\hË—mmPÖYÁ«’ˆÕa|d È7‹*‡ZÁfKî.Äâid±q£ IJ¥ý4Ü»”%°tRºEÖù¨EÜZæÄ²„±aÏÊœå… à›ùêýó ã)SôEÛ^a^yg³CÓªu˜6 ¥XƒL,°‹QÎ/ª„Úaer0¼i퀻z>m€…-±b”cpa´5ãÛM$*ŠE¥vÿ|nv<6D£tM>5°Üäû­;I[41úÖt—ÖR-@LÍ Ý¦lLä©p²™{»±H#ÉXöZã`â}[Ç¿¶+ª±n•Ÿ% ]wæH¤M¹iÛ:½=R¬­ãÞ’¤ñZøù'É ñý[SFfó>˜ÍÏÕâcrI2NÐbÖ΂›œ¼‰šðÝW· —±-‹,˜@×¢Ï4›’ž`¾Ä  ‚‹IR §¡fÅä³,uŠ¿M[ü³u 9áÖÐ+¥Ìj„¨K3u ´BÿùñY(à-"ãÖ%6w|èÞ—8•:&u%ËšŒŸuo4å¢ ®:;ˆ²b$ÒÙƒnû%p  (À*£lPe5ê ÃdhYZÁœWÐaÕ»—ˆ%ªÅ‚Ån0S6=Å4¢U·­=±ÙÁJ-n‘Íó& •e-C¢IQ-Q4@ÄAëáóâ+ܽƥ|‹t•ÕtD‘?£rž<FEy $ô&/:01˜PÕL>®”ÖY޳¸â•,‡à#(BÒi°l±–²írô#dJ•8^=?È+7õ®Í‡¤69qµÉšj!6|—a)ÈG“ÉL^âC„¤ç¦%W!Gcü¯ž}f±HGWÖé~–÷´ª)Ya‹†b1’£¤÷ÂB&‚V´„ïqkܬ”FÀMÌ<ÔT¤`0ÿÁÓ `g­¤Œ.YnÑ&6¥‰JbÔê´BØžbˆ:%BÄä‡`ª%À!'MçÐ??D†×[)A>y¾ÌëïOóæ¿¼ùÇÿrñ“úÑ>|yáEû“εvå\û¡î5’ÜbœD—GÔßjdàWàEŽÖYÉͽi6ÈgÀ‡AÄÏöŸ¾=Å›{¸Ûè@ËÌIÌô­¹µv¤GVÆ÷TëhdÞ6Êf€vß—Ø`¯‡«@‹«C‹K¾€•þ¶ntÎØ±œ63ÁÖ]B—^ÇlعÉb¢ï0'µ>’0B¢Ø7ÌôŸÅPk Zÿ²8Œ(Æ- f”…ª5<ñ`3OË¢u9As)‘žƒƒ®VëÑ›;¾ÌBQª0n3-²ˆ°C`v³QY2n˼w˜y¹“UmT[Á"Z5' ÜÞ>ŸÜ~8ܾQ’æú`YMöY° ÄY¨-´õ >O Å}£â^‰¤B`Åš¢ ˜ëÀ] o4¶NÓ ë<`º¥.%hšý—Âõºó%Vh`-bíÅC\‡äzØ)QúÛÅ.©bFUÂÜEËëÅ?Mñm±«’(<Õ9#ùvnµPÊRñÞ¨¸#%MZ)÷ã¢/ÌŠ r1§ì8yg¥…£OÌi^À:ÜE+Õ’L®Ï÷HËK˰ØW1Ñh® ~®R i7÷òˆW¬PÖFe/àþа§Å–éþ‚îÂöVçÁ½™+Íå¥ÐrTaê¦ÙH¬Y4÷ ¸Ð>C_ŠqZ³MŽÀ€w’“ö†Ÿ‡ƒ¶92`ë¦ü\ LÚÁmQ]T›7°=ÓrµÀ•r IK@è}Æåàïc" ˆYuàÞ¬¬Kï…‹K€û?ܽ„ßh9†M¦õØ@5[¥IU:»»¢ÔGu z³¦èK¦Ç’a’Á¶‹F Tœª3ü”BokI¸ª’œj °œ\êéà)Eb°ºKð° +w¥ûäRå·7Ð9Lß`¦®¶sl‹úŠÓo‹è:ͶPœ¼Åÿõ’.ïÍz»¸ç:´‚¹D.÷³ôu¨52*,­ÑöËfÐg…T3]/[úæœià -Åê‘„A!5HwtS*˜†˜¸hg¨‰ö¹4a&(î!°aÅÙ®|JÃÇ& ÈlZâ½My‰ ‚KW D- Œ$®‹­†¨Ðj;öBMÐëņŰe«%înU8›ØÓDó{C¤jqŽƒþ[³ø ,Lc‹Eµ# pë‹ÂáUÛQðbꘕóø.f²l³Šb¼}ƒ¢ú`Ú\?eó.àÒ³³Í8f3h6ªÊ0n-¡Æ )81¨jg™& ;}î TIšþHs·XqQiQÕs¨òu5¿XáÒÞ±É ºv{3¼ "ò†Ùn‘g ‘NF«Xîqë€8°øK•ô[û|ÍÔçRx:ÛmÄB £–Î8 ofrKjjrqçb– °‘>x]˜mÅæl³ÓX!;ÅDþm-S°Úœy¯ðØy¯ [|^À¥)Àš#&¿d;³fGʽê`&&(ÁWA{ŠšÁdÅȦ‚¦âÁ0.ÅÌElBe ªû¿Õé5ÈÙÁÅ‚¯les Q’F]X¯³~]ÂvAì™.s¦ÕœSÏe ûaK™“Fsa H¤t4lÆ»PÖÆPlÇAº+Usf3Ê‹1¹õú\²™SgŸ$¿7’x`I\3’óÒs-c*0*¤ÁØ<ámµaý"\±Â›Rƽêô3`œan©‘¨‘Úî­î7Sÿ¾G‡@Lzªíˆ>ù_üåí§oîß½ùæÝǯ?ýñæW ô‹’îˈ¿¼ùËß~óé݇ßßüâîîöÍ›oßÿæã7¯åÞ_Þü/ëÎÿuý[úØ=4ü ®D6Ä ö.QØ3ྪÆe §k¤aJÕ-CiEºØ xSD„HÍ‘DÁ}.¢D5=þq¬õ& ÊW˜æ:˜»Êdjwù?× ý§¿‡•rIŠÓPåï÷´ªGFHF¨%þ½B:Rª¬¾dJÀ÷QGÁKÈ  Ôã€{iÅà4§N4 ¡ H´2#ž %x´DìàøZƒµÛêäT-j"¸€§› EÍÁßC,™øs…œñydÈ`½‘T—xðì&üŒ;<ĆcDP¼Ùîwš¦C)¸Áb¹Èà¹pÂæÜÔ"›Lw–òÛý¨Qåro þ#”K̈hÂá ݘ&;õHo°—Ô\ ( ÒO€R‚Çmv4 äã¥ÊGÒ0r=ß@%£;Á’n$“=\tTŠŒ®Ï¸˜NœÍ\c°l$TýÙŒA%;j>øNP7—øî‰­‚ñ‹)¼gH—Û·%±Ïê00¸@D옊§PàqÔÐXÚUÔŠo¤Y2jÉ™Ÿ°¬±Û Ë4™ ê”Î[¡=ËÌà°;.´Öˆ³ÀcœBÒTĦ\Šä]Cé 9(–)P‚š€'•Oáw\ç8æ\±1Áý§Ƴj+o W¹Á,C”„‡EÚça8Ö³gëš-ïˬ†âqîØ[&'Ìà =±ÑceZ3SC1%è ‚xÔl``Q`àk‰Æ­Ê  lÓ³N™ÝRQyX$’Мfbw‡ü¨Ž¾µuL²“°Â7ôÿA?ï4SàÎÆSª~á=L™0ÜÊ ™Ý)$×€¤Àañ;ÿÐLC®pêT$‰YYC¼ÌUÖt-¿æþRš#vF1A²ŸÅƒ'Œˆ¡³ÎDìÀᛪ^_'÷-Þ|­VËþYBúsQé£k9XuÙí^ÿ}yj?—úgIðLtÎKŒˆERúê*û)uÔ.Ó;ŸÂö§?`R?S~g¤¦náÜ”¼£ßÔY«ÑÝXÍMl΢f¦ÈlpØ?p ¦ #›GÀ@ÛÒ}9j,>Jm€âAñKèlF7ÅñˆSÉÄ3ËÜÙ+€ÝS¢$h'Ó‡–#ãndÄ@h¬owpžŒà¦ÙPóäÜß|ï¨8÷:“ãÄŠ“¨Ý\|\5¸Ù¸6%ø» ½m-Dp÷`«f;•Õ™óê9ùò"¨Phc7Ç©…#~áÈAc—¥" >/vz(Sé¼W=Pp/Â|Ü<‹BN-2@gø8 À7¢sè?=`f‰Â ãû"‰âÒyÓ@äò•ëµP¢_Œ;xDÆè×Hkq©‘; ÅCLÈ9s+’ÅVég„oÜ!¨óµ›;l4 œ~È:¬D†&`Eqˆ¹KÖ”€8L4³jeðu¾:‚=mpiÀs$!j²ŽNÍØ)ÚËáO¾c‡Šï¬£»Ÿ/VßÈâo«©Lbн<59I t!`¯Í˜{¤QNˆ)`§«¼z«€'íø*`½¸æA"Lm Ø:±i¤Hà(Æù±ôG7ŒÊûÂðVÚ@:ólyDSÇ wˆ-”úS\q 9-ZK6¦1?aM™ xy¸÷¡¿ZÄ÷o'~5MA1Ï”áºú<:>ïaÔ ¼ÞF ¾K~j‘Œ÷`Ù ½.ÆËŠ{¥h H¶#&~FHà N}=þQsj¢fDõ ³’q\¦UöE.‰{ Ö̉1qOHÕ_¹7O4,8 ]àí¦7ì“PÔäñG`’;Á¢Ä,è³ÉŒÐ*Ñâ‘í1%vѡ̽›æÝ7àú‰‘YPpžînœæ0ÓKŽ¢î›B[Jˆª£1‚!_ökܘ3š<Òº[_"¦jÁ½}0ŒÊ⟙O”„ïd„,­…ÄaÕ£Wèò¡°úƒ¤VeÏ™¶fЩû•I`WãòêæC g™¬°¢ùb‰#3¾XŒ¼K¦»{v’¨„»Œ}‚ bí&0Íg€ñôqj-AµnàÅ‹á…G"w‡¨eXÇM͈LŠh‹fÀ˜'SÜse0B2kÀFfhžÅ¸­™O&ÀÂÍÖOõÕÝÌhÖ-ÕÁt1î1y0"$a¸·g5ŸÖT¡„x¯îŠÜ0ƒÁP÷ä¸ f¡I$€ð4M4ÄÒi ”:Éä¼L÷_¡õ£»–-}“ÝÒÕQ·©­{be°4…ãÄ4 ž>™r©ÃAŒnÈ .AR=±uîøâC¶+cÔ-AëA…­dÂ̟e­å,ÙÊ'àÂ(µ&‘«¯¼'MdÕ!"%¾^Çͳãž÷Á•Õú'žÇär±$ØFËä49¤yárØM“š‡Ò.UúŽ€g$q†µ{;DéÒásÄ绨{ÉÓ­*S5nȦ€¸Û§óÚÞýÊÉ–Ÿe2ŽÐ’Ü,Z‘ó4¤5ÉPhF±§#©‘^+Ätõ\’Ö€Šé‚T!pñÕ\l2¡:•#’‚¶/}Hb>+gLà˜8Ãû@ÒUîæzy†Ö`^éUÑüȨÌ}z%*ugå™Vð<™}/ â¶n Ñ” +£%ûõSDëôå–‘ä¢>J¼Scîýp(Êb iÓåß@‚ÑQ–ÚB³eTwƒŽl96ƒbв8µM*—¬¦Rè¨N–[¢©J\@vÔœ³É`àƒT V°3[eU2Ÿ/jkñZ3þ¤Tà±PÚ „W”ºJ¾þE2~h″Q²¯àX(æñÐ$÷x´4ŒÌ*'šÓp#Î`vqbdF·Ë²$$–åCF‘j(—Û½cÁ@ì ÄS¢&Žô;Ú6aMŠÓ±‡è´Ï_ûÃ}E=Yfe Ñt:naú¾€+Ëõt¿5uf•ùiOàD=IÏÐWå m'Ya•÷26}à!¡µ?«ïlÏaú±´œè8}sx.93 ³E…0:PI:ciRáÛ3As¾-©NJ+&ƒÇj$ÞÁ¨\Y=DœI¬J'þ¶XLc~q]üY÷Pó¢Y^¨!<å‹ ±Þ!DϦ2øyY6áQÁj0[¬±d“wJqÒ¼ÇÝYÌwh$„´J\£!¿¤ê™}úÃ3 ¾êíà]ºoĨ€êg¦§ÃIå$¡ ³Û´¦ ‹-füϬd§.rKÁ˜\òV½Ó ’öº›Z›%SÐe-ϸÈ®fD«FæfŸ‘!–N**…¸v¬²QX'ºÊ¦¯6Õh*PC€Á+ÎôºKŸA¦ð¶\ÁO&Ó h#×3@ d‘¬sãë2b0mé3QÐ,?Çž„¬R¸‹Á¼PJLLC`òBºé° ,l­§¾A߆ Dºm\BD˜ø:…eMɾ¸QhæÜÑPSÚ½–ðÓÞ§ÛÍy¦§Àë¬Ëë1ð°²*ò¤^2gÚéL° qçfqÑTº²0·ˆ+*°Km•@ bù©›l ¨ªì­à¢ŠR…ªrt"XÖ$ËýqR‡q§Ñ]é]2Ùx7³ñÛd†Øá 4äŸ_j]m2ýE56¥§”s'zÀ %ù½^ä(ºL-4Öꬪ%Ѥ;¥ÇÅÕ>”+|B¤…ˆ#ç§M·†€&¼–ê¨,ô)å=c½ @MæHXñ—¾V‡fѤ]ïÔé=Á~éTíTH*A¥[;àÀÄrmÙKÀ‰h.k©Ø=„àZéÉ G«m•Tæ×Õtëq¿&CæªmmZòt\>0€SˆB‹Æ²Ž Kꆑ•Ep‚ÚiÌ;QοÓ0 s?LÅ­ØÉªf¿'º€Y-/jŠú ¶ûdy"‰;™N}~þq¬þ<¼"Z«§0@psót‘¬3.3Ë` Ðz0Îø|IŒ.ˆÓÌ«:@ã Hµ}:½%Ìš–>øžà8 ®¾öÙ3-Õ˜ `¼³y5‚:`ãZ\©Gâ©ÕÏmÞ³ÃZÖnfó»Éñ|O°S@ù¤$xŒùÒG'ÀƬÝ]‹Rð3}K€ªûé¨ût\Ìfõ=‹E•7Ã8w^ŠÔÇn¬;ÄØãîÅþ£ùóóã²âRñäx±Ñ!'…/5‡-óú¾Ð œåç%SË'ãž}ñ›.Uv¸ø´HFãFâÄ©› ÌLú"0—~ÀDZUí:x1äÕã‰èm©Ï 6•÷Ó‘0€1fæÁ+êxæ(QÌmóêùÇaC⎡8Öìp CnóØ ARºqæ<ÉFE$›^ëÕL€gŸÏîÍ«YJò{Bû*0Ú?ÃÿÔžÕ>‰£j Ä\à`,òP«U€µDµ2÷sàΩ † Õ=ß k¤(ºxå½ÊéôÓ¤õ÷©«wÕ@ê¿47ÈÃʤEÜãé öÔ®FæÔضDÔíΑ· Ý[”¢G¯M ³áÔXWmzêJu'Ú£:B Ó¡™…ÌÖu!¾Ïè…UÊj>±ÉbÉÕr &dÌ­J2…È€ðáv×xlQã[>Üÿ$ÞÛñÝ„waör?œs½:õX_U|‰-9: ¯–½`st—†ÞÍ”¸:vB :NFAh4dßtõ¸ƒ¨à]L´jE©*f`­MQa«íÌlå ÛÑXûtÜÍ’ ô-gá™Å2 J~ZW]GV`nO£2¦LÂÚhIÒ‚ò½ƒi`…RIN½x]ªN;ƒ;›·Ì¸ºuƒ^L€3‹h £r¥¨®ï<\4ìØS½…ØCJš¾œ1@u¹À*@Ôs™~6ŸÎà¸h4 ÄÇ#ØQì¨AÆœ<÷ÊO>~¸×²•Ÿ<žRfd f ¸b€ €'y,Ía5zå¯iÞ°À½©3k7—Ù·ÆäŸ¿z'‘µ cXïŸ{“ DŽ ·4ö&@”ÔÄeÆ+¥¾ô̰ÜXX,X%7k€`U‚Xž‘Àƒ-Å dÊàÁ£8åÞÆjtïÉ Ãã Ycèɧçcüð ›WjÊÁ(ÃDK§2¢`²ØÀbñÌzˆŸzovìòÕ\6ð eMÛî4IÝZñ\¼Ø*2(òe§S4GC"±YZæ™döö`”¬`ç§Y²=€1è}WžNŒö4%*Öh@­Z`T¤c5 S¤IÒK$0{Ó%wõH7*ˆ¤Í,²/¬´Çõqß‹Ôm¯\™Nw—Ü[Y—‡Â ŒŠzjÍûÒ¼vl5ÆpÜjQ¶Œ©îX@´Þ’ò»õU{é-ÿPA³3ÎKŸ?½ßTÝœ\nn7M…±À:ÑêgYS}cÊð6Õ’½_qÔH^5–ˆîà'{ pËÃãWv¾4¼qâwÚÎA’­EÜAÛÆœîBX}~z€Î~²®Î†Ÿ,GÍ·–‚‘Ä\ú ÐÛ÷DúèlˆíÕÉÒ-Qê¹Ãi3KÞÐQR4KÓ¡n+ ”02™‚6%ѯÕ`î=Ó±mÝ c”ÄŠï:@ç¨W3Ø© aööÎL`Øq7Êm@¸Ù4½aÐOGé[ºx„mœ¿Ó•‘`õíÛ=r«ï\•xÈÐØÁO¦»;c2¨Z|À{‚'‘•1¡Ò«cT •n™°/V)`L¥_œ6lzFÉC;kv§'+•ÀêÅð²Mb»Ùá8-ÚHž¾Â>×ÔªüX'—BÄ8EvscÝÏS,Ŀɽ=‘ºÑöQ]á2³/:…”ff.:üR_MYšÓ°_Küæè.þvvÊRI/'‚ ï…éB@|lŽmÞ,f—к݌‚áa^âÇ÷é+ðÝ$áƒC¨á⽃É>X‚' ª¢.Ýç§F;xó(ã«Q7ìb—zm EŽ¥Š7ãá Ñ·+[äƒÑð 'y"ïÎtØû›Zy@ý~bc·ÇSÏZ‘©¾±Cè!¥>Ov1#;êé°Hõ%Ç ¦¯f~yP‡7<Û÷Âo¥;ŒêUûç~1vô“Öf·¶Ý,±zSÚ¡Ï‘¸};Idýˆì½ÿ$“l0öàù`7Êäýå<Ô³¢,íq:ÏgàÞD¹ÞqÜWÖ¸¦UIýîäcý¢»ézDOõ2‰Íñ½ï¤÷nr-£ai)¦0x2\%Z¾|™#Ñ®,q7¼á«rʳvv]§‘££á<©±»±«íhÃîþ¢~°’tmûˆ ¨SÑ€L›o&‘VÍx?Þº ”œë``YPi¯ûL¿Ôú Àb/¡îedw8¶ ?ÕYóvh±H8™ù#qY^î²$)géâ5o„YK]:4DÜýPBb£š„Àš+"ËÍÈ÷Í¥$ÈŒ²âN¿‡õÂÀÁÊ!‘_B¥`ÆlÖÌÍ5’7D„mE5½ÂF5ù`á î¾Ùë+eP,&²3°kG–Ãô]?š-Ó’·+`b¢C®êV’"¹×Â$cE4­ƒV*ò—Q<=i<~’ÒXY;x5„±Û»%‡pzGÚ4ÙÁgKŽ‹ŠseŸÄ€2†4yMfÐÛ®f8Ø)Ÿi­·{awÛâh(óklù2;;¿[ °ûuÓ+@du6½Éë.w=ºç3 ó6tHs êÁ¢­yº'„åc]éydk¸×YkkH©ÒÈSÛRÛý•Š+¿”gpÙ #åã|›J©¹HÑUÞ^̉u7ÑÎp`K¥f´â!˜êÝdœñ-×HÅÃêL+2ƒÆþp;éSŠN’µ2Yuœme„Rv¾í_©‡$‡éq–RMÊ‚À^ª ¡Ðr¥ì¥:IÖ™¢$Ê$+©H•8Y(ŽÓ³~Tˆ$c–rN HÍÂF^<¼¬.ª-ezE4¨ÒÖ?©ý´íÍ`÷€îVë™]Šì^§Þ–úI’‡erÑߎÔ Ô·4^ƒ°¾vs³°TnJ ‡‹kVo'ÚŒŸÚçŤCF#âL¨’¹¦@ 25B§/õ…v$dóÁî‘;“ÕMµ3[‹˜`áck–{uF¡ýÜi)°\«¾H0È]熓.ªOžäîZŠ\a4ltTS õ¬~lœ(w+Ãy0Ù /{›ßmXRðÞn³3*.q"aè§Íùiª»ÍjTp÷èÕT)ný<…ˆzWZˆ"“%u齌,èV„Ѐ##?m ›‹ ìË AÌ ~‡Ìú†æŸVnà8wµÔH¡y {PÁ[mSJö `d«r»¬~¦¦àgª2´JíÅ<¬C$åÕ`'ÞÙ| &&1á½}ÿÓ~—tT™uâ²UfÚ6)+4«Mð 4wKæhýJíA“Í:U@åÍŒü¯°ÙYÎLÛ H½}=ÜÏÃ.U_fÿ{º·ˆ>00ÜÞl_«öÑ‚Z¼Ÿ2{¯9|Q4La½1ÿÆT!\Q*ZöÈ k‚®oÅŒÛÞjGF¡#YƒÕŒÃ+‘• h1Ó{¬~äÎÆ¨YJaÑIqk` +ÏdÃ&v?>´ •j4ìec©}`E€ò`ÿRº]‹‡w×Ajöài£0m×™ðÂì1A•¥Ü¥ †×@SK†}žD“…Ѭ K ÜñâbÖt)›©âÀt(#²×Ú—¢,’½ Ⱦ9ÅÄ ŽÛ§o„rÊÃ&‘.ð]ÃnqT÷¬¨S Èà v(Ë n„œ'-vEŒÊs„ó¹Ek›7`…RigJ ÷‹]Y÷6h7ŠªùC6ª=˜ö¨Ôܲ·˜ÇšhŒ{ãÐöÎRŠO Ô½{‘ És¸“á-*€Ÿ¥]¤{cˬ"íc#œwƒ)Òx/ë#BÖ+@0¾ƒˆÓ‹€©né1Y ¼ ªaX‚Øèê•Ò¼™¥Ê–ÌcC+²ÚAT͇<4-ŒëÕËþ %l;¡iRëÖ¡ÈÜUˆü@ÛèKDò€æzHÉëÂN˜º36€ä&€™F6ƒS¹ä12ª%÷h‰Bׯ‚‰ö°DU,†M1»iL/&ñ:Œ^Ÿž­AíÞ“2p6Û ´Éî%=›Pî…o×ñu4°0 ñVê»O{Cg`¹ ÔÕd÷‹;Msª1¦êŦ×3Œfí´vU¸ [ÖèV{Ïîôü$gÆbÁƒ¯XîŽ ÒV ˜<‘½{0$?Ь1##dÝhÕ_.5rZ»K@‰!Ìöi–¯ŒÐBÔ®’±U“Õ\Cñ¢xÓó óG4>¬Ó0C'ƒØÜ3`)9r{[`éÂì ½¶GóÖfjŒuߤЄz:Ù (G7ÔªiÔ%ÔÊ–ŒÍ³%9‚4^\½ˆ¡2úk»T²¾e/¬†ˆb ¹°Hó Ïð“:0‘½›rꬶA6w½áÞã6–]‰ ú˜"e¦~ØèQ«'äª#JçA²7`EÓÔW†Yz'—‰V_z.' ¤ èY¦o2PÍS•Öt²-†ÛÎÀvUH^¨‘—¨݉'áìmz½š‚$ßf–Y¨Ä"÷Îz…;­YûÀyv¨Ø{«#Wæ;…¢ÍéM…3ÑicƒM™™ÔÕ!½G÷ŒL‹V}ÎÝMç< ³p´)„)Å8×\¸”#5˜ÊUÝ ½›B¯ÓP|Z¼Ã@1z&Ù."+½ô˜iyýlm—ÇÍ>ì¥t4¼±ûcŃv¾Pÿ#,£©Wt+ñ‰Fç÷Òï|XÕä !¥)`Þiƒ¬Ý /Žröíh{þ´€êe$Ö åP×oÔ«9\ dŸ¯ëg¥èíÈ×][¨Ü˜èù´®ß MÅ›{, Í:¾µj¬1ų=øy´î®UL,΋Â>á¢éÕÜ/@~, ‚ “½òg•FÖ` ÖFñÑ %]>v½ÍŠ®RÓ‹ÅuéøQËNÕÄ–¬‡¾³»3#úíŒÝP>"Û:p{>¨Å‚èÙ¦Öoéf‡BŽlõ4Ùp2_ïçWY©Ó{:f½@b2ÝÅš*c:ÛÁkF$ãN£³U`HD7«XÁ[zƒzn—6%¸`JÃÅr,cÔ½¹™M½¨]b"¶™´Üo‰S@ÄGÚºL¬z)z‚'å³c¸sõéìÂ*%ˆbæ!`á‰êÌØD¢€2Á(Ð+€©ŽE à ‰¥¶ܽ&tÅ\ƒwžê»sÀ´°;’nëz1µvX™^¼¸E‹ lŸt7J¢ÑdÛ´ŽÆž*<fâ’ÂÒØavÐ@¬¼{ŸÑ®sÒMàk`áÂþ²ìy6MSâ2ŽAÒи^×¶`P§¨Å VÇr%ž%¯÷²FT…Vn™îëWáö ›+LÔ F©lM`â^Fž¼W)¸óàj.ÇHê]⪢ëP÷:îšânI‰ý¬ÑYN𞹕=;‘›JeXa¬-CÞ¹÷1vkHtÒ©”‡$oƒjÇDFÓ•5ÿ Të¸Ñ|¦ö" Ä–‘q³×¢Ø*ÇeŽ8úã齬2!·ê³ÜÕ¤¡Ÿg{ˆzQŽÝE›öžç†yÐ6{Co‹å>ÜÍ+Ùàèí1Læl‘:\÷’tr/”PCt–nÏ“Çë¢.é"£Çbˆ´<ÔÁóšSbso—‚6V—ŽI^“6£k^‡7PùÑ`´¨.7ò]d­êƒ2v'Î>? é `µ§¸q¯Û‘Ö:–;;æGˆ,ò°î¤–·lJz’g“ (ý+€GbdoH3Ü3ÐÎÅÖ.ö8î謊K:%s b§¶.@°b¡S[k xŽÓˆ>€s€àåè>Çk›®™o¬§ÄoõúTAã! \»Ñf£y;˜L"\nöª>Àžå B%‰^€L–F€èÈd¿‹»×|Zí—e}Ûäî:†5·äoñBš !íPÏ‚ØvÎi Ì+€7:OvžÛUƒÖ¸7ƒd¡י€ …DfÓTôÊ1FŽ$‰ å˜Ûæ `ïƒÚ¼_-LufU'Z5Qzœ·v§*àaUȬ Óp2-zûúÛ®wv1éâÅЃw9`%¿¯Þh±Uî‹^h¢xÀĶ´‚{f¢£ª× úP[" û6´ãµã8>¹wºv•&þ×+½ülËÞf%Âó¦@Š•{w'íé vço­6‰ä¦a9á&&KÞG£Òͺ6M5Zja›HD/±‡Ôf—ZÚÞû IdáPB²íðŒ°ë‰ˆ»œµ%ô±/žOž8$µùyö/Üâw‹‡vÞ»ÒK£eŽ7jËÓeÄîè¬È«DêÔ~©jÈÂnýAM² •tN[pÖ°.!µ£^âK Y´Tv¨¶#ÆÂ.€žÝR¼Mzvh0‡Ÿ®ƒP©‡—µ6»”ÝÝØ//9éñgåBO¢ããú`jít µTo¸´º2IJN©¼1¿£•ÃÃ6ñ±ÊS ƒLP7ñéÖ_¢®w Ûù—0r'¥Í(ú£RCÌ&ÅhJáX–\‚í&(6VuÓ¹AzlRm2ÎÌû„[_p“½ˆŽ]è¤=¤e˜µ`ø¸ 7µè%Âd•MVî<ö ¯æËݤ4 ÷Ýö…)¼Vþ’[°l¬!Ù`Ö©ÏîE[ñ:!^(ÚÀU%£–@%Ä»LµàmŸ¶2[YáÔöqØFáá¨l]׺Ú/&*J/`A+ÁnE¡_X³ÌByPmDêo1Ï’ « mkP¨Yêó¶9èˆ ­Ùõ‚q®î2]ñÁà° §ž|xpj>Д‰"æ5»1¢¡«zó©O6 ü®)òJSÐϰ«v…cµ´±BÌ™”±€iº7mø2ÀL$`‡¥IÜvd¬0¡˜:KéMÀ®|³à™TDê´ 0É¿VO èâcPêLð½ÂF&­‰i’uÁ”IƒY.q&{Âï–^Ò÷!éa—Ói–’l¯•š:j{²°’GyŸñˆrŽ2êIäB£naÿ|ÎÎÛ²wcÕ ^ŠaŸ/Žc`«güûÒakÑc˜*ÛÁZ)ÓLÚÀºÌZ‘(¯JÕÖÀä›­I7±@˜¡ÚpÔ-ÑÅÀÊ3ù°·æe ‚Å—ñó,?<_» åÁýùÏ®x:¥hj÷êTÑ‹x Ð}@)S «;ût«uçÆMvöÉÒâ8@J¬§@7E°Z1×VdcUfj¤C%üÚÜ_´«bÈ)vqÅLžV1ò“Õ)#ª–Ãèûc¿§µÅÞºËF×êùÉÜj8óƒC¤;¼ã-ŽäyÀõÂI™¼âY¡Ïk—›°‹à,Ý&@Y6âIy5’N†—$¯A^³—šÙAB¥½—êùá;,A-! ô^ˆé¾l z yìôÁN¬5YÖj1tð·•*ÀVÄÜÜKHâa-² #l÷=ÔBköùè}r¢å„à^äÝhò Ã{Ô7êÏßüzÀÓ-“BË.|,oéܪ"pÐY@æë-ÂR!1ÆX©’³µL-‡B$4Öⱥіӹe¢PW§zÉ#IÐÞ|³Rö¥‘Ô4oRV*-[m€ÎZŒ5ó 5yÍ¡p<Ëâŵ­¾`™@–ñÔFǵ^ËõÚl™ŘI"K[Xo Â1.s*áÈíýùn›b×ïÀlÞÃÀ¶Ì»4†ÚZxØ”B Ò㌤ ÚåÓVk‹ÔÃm(³ÑWNÙQì¢ò$¶˜GÆ/E&­Õ¥lpW²%:QÉÞ-c µÕÔ¾W€—ëQ °T¸‘M­Ð¢t¾1;@Áìü=-wÒ€}qé“óª¦AÐ~\ŠÌaSxðbTåEÊîp<[KfÛ¼âJa}}‰è&§À‰YÀ½zUÈlÝmÂèh[÷°ÓÌ(åçöë6«Wm¯;õ'µ3*©%Xqiˆ‰=šœJ?lXòbˆR'£Ôz jì^Ó“ùŸ^ÌÂÍH`d_™Áb”f‚¡³‹åú •C:é7«#É»fRžè û5Ñ+™=XHÖÊyPA“yW ÛHÎv‰ÜŠ|E°ÃÑ‹z`îsN^^ZV%0ä-{ÛYw¢¢æöc¶™R"óÚdº—Ϭ»¤Ët† ¢!• ÜçM¼T/˜qñõèµÏ¬öUª+Á³1 •‚Dòšê"i°–IÀƒÀ0 œ½p†R°,aŽË¦¯ÁKÓ—âu‘‚™ ˆVgòn­ìqÃÞHÙì]‚ǃÊ}™r€b?ž'­š<`@FÞ…ÍX -v8ãÀb?Ý4EAÇ*ì~Î(ߦh#ª#Á±ÒIÏXO‚FYÆ—Œêð—RNÉJ§±–6nòv•Û³W"êh˜Ï,;% ßEçëþÝpôþ—pŒj°¶ÏÆ­»>Q¤ÄC Kʤ%zœ¨™öùè}v  a¢Ó…ƒZžädB;r€èQ8t7–tt B¹(¬ë`,Àé”ÈÊ“r\R-Æsæ©é ÜæK v0÷WR@)® /"@3ÛuÊn½öõó3H¨©lqzÎ\“MÇÀ`£ÉÖnÀVÒÁ‡¨p~>x©IîwôVÑBb È,æx¨[=f6¾t©x—E‚1ï‚ÍÊà9–›-ÁKm ¡ûdy Þ{ 윦ίèE°=øqûòô¶ÉìQ¯žÛ{Õ›ƒ‰ýÑK{åéô/z§³L×+˜çQ˜sù&Oöt *çÏ‚YB¤±Èg èlÁ‚c0ÑRíˆcF|pÑ/OöO Áœ¤&š‡¶r’‡§ý Ïy0YV0o Á5’“íæap‹ È’B×ù޵–Ï'ªõ‡JµÝ­œú”¥u¾µ<ÜŠÌÈnÀm{dlc‚¤  7ôÏæ~teÃÉôù z;®Žf:© çö¸¯‰,ÇŒjB<_aדe‰'™­WÈ„`d•ý”©§Ë¾l ‘»ª…è†(Ùòìä.äÁnU*# îv>„¢ê! qj·XÉ»˜+Z«©!Ñì„¶XÛÁܼM»€‡Wx• ìW3 0™Lé`/!­d‚)NdëYaÁêɵ®ˆu=T¦§*6ØÐ¬œêv˜£í.OJ´ diãù!P1söÔ¸hiiüüŽ7Wg°½Xö±Á;_çÂaa—÷_w2X9œ‹}L!𢺓Tš¤lŠœÝv´/ådnÃ[—wÍèrKž¬„ \`,qžƒ'8FºLÓÀâÁ¦™vÚ¡Ônð{Scle¤4<3š•§Ý*!# 0G÷ÓîdFh<øÓ8Ȫ]S?Ôw.à®i—Ä ‡0ÀÔ<º$š÷Ý€»Ât€©5Ip?Å©êBôÍŒØ8ÆØþÔÝå%ìûÁ ˆb÷Z‚ÃA&Ë}Þv‚ž†§Þ¸Â‘¤¨’?¼ìõ÷ìˆÝã\·…žÖ5tD à‹,töTŠr mt: 9A(3,4®˜† †®‰'X>ïù†¬%/¹P‡=¥\Љ?©{4s231_ŸòFbYâÿž¦ø´¸@ïMÉR ü `Ò†dÖTOæ ©£ô@A‰­ì*~j^^ ܘZõb(Ñ Nè½)PÆôßÕÓNƒ sIr# e 7,pÙ¢—+UoR¹{I0’k!6>Ë’ ²{;µ^홋;=§JëÄòùÃE<æ7¤íÊŽÕÝlÈGæç϶ uPz+˜%”ªkJö°pUrJœªWNò*@çh“ c*f`7l"3÷–QóBÅÝ@»BÞ3t-™ ÈŽ5ÌIÊFšŠ»È2ö‰mïD]U;t!Êìô¨ùåæªMù'µk̦ì§h÷K›oE¯Ó|xƒc´f*^‹ã@LŠåûÚÙ€vgt•¨õÝs‡âp<ø…S9UØ9^Ç%£×(¸Ï5â–oÅl—üKå óRN—lä^ Þy˜GMmX:jøu2Sñ’òÁ Ø*FjÃMHö,2¦a¥ä…¢“égÚ>øðåxY¤Cªýƒ¡%—Ò!²>%/t›¬tæ}ø²Æ”â¶SÚm4â¸F8¼˜ÃÉ»r§xÈv¼Ó¦ $“®ñJ³ O)¦)ÀÊ$KöÚNÁ ¥CöL ¥œX­;ÅCÏ×äóiÝn—wú_­Pˆ™[¼Înœ^Ú)[ÑE@À°{d7·i™ÏøG4ós]^ Ü 6g˜ŠÞÛL€ =l,Y7« ØœpÛêÕêP–.Uwî«i¼ø¸Ùk1åÛªB…®F&ÂL,ÝS£SsÊw,+ššËsÜ&Œ(¯4<«UEùà•>ëf¥“‡—"óži‹yWþr?–®#‹$2“\¸W<ÈtfvÃ#2êìR@ _Ë}7,žÂܬ£s-5S>TZGOM>(oÅ'kš#çÈË”…Ž·ÚaæÝ„|¾@òè”,Xªï– ÙS#†Yî‰ »š¹–NO\+æ>¥èR?TëOÑ#ø/Žì±,¨¯kp¦&•·{ŠQ²è‡Ú×­’æBtf@¤èJN7!'EOËØíÅŠhZ¥—SbñÐ9L&³<¤Æèì†f¬2¦'„`v‰Øå¥UNð"¬-³Ò¡žÇ§EÆ0ÊûÆ]v [A Pã]¿®8giÝrÛñ°VHK§DNËä’±«šÊ{yUS¬¬|¼²÷3Ú =mÇ㵋·c,WS4‰©bô.¢¨äç;€Ñ:?­°€½Ð5€çbðQÙMViœÞôI%>öM§e&%/ï;ô ]cmÈøÙеnjìýµíK§g§ïÁ‘Þ#%vw–Bhž€‘Ò¡ ãte®&GYr¦ÀèazïD³^6E9Ø»›g´¼H^|KÛú–-H3¸oºñRˆFaÛ¹îæìløV=dPð­ñ>‚Ûä6ö¨ÙEf¬¬và‰áIkœM,"¨“É–7p j Ö¸[$¬°•B.­²8.oo ¥Ó°„ gVž"ï½zæìÙÕÍ&ÅkQî&õ2Ô ™Û”'†SkŽf¿]EFLö¹:WßìÆ×[&¾N7Öm )‘k`®ˆäÞïݪŠÅ Ð° „Çp’uV@KØñ¦¥cÛç+]œ1ìæT•!»q +%š"Bl€F #^ľuÚ¼âÎ×cr6”(®÷ȪŠe×& àɨrZݦ+ªP g$ -¼9x·÷d$oÝ%Ї+žö:ÔHބ˶Ț71+Q!pT–ׇiUL§·¿Ð€{.xš™Qø4*ÏC,±Ü."øÔc›MÏÃJì#|ix~[bt¿ì‚è„ÌdH>‡ÉRS5±£ƒœz&ªDºå"Rë ˆ˜[9t^þRòGY"BÖžÞi Ì«“zo¸ H(éÑ’´x¿¦$ï¡v}Zɵ Ôµ*3 ³ù¡Vz:H&¡Ò¤ü<;¦O3àÚÊ”ƒ…J;²ã";atãyÚo’û°- žìÍâ:öêUµàúN±,½cë¡*YªælÞX³GÆeã™»e±ú‹¹`ÂX+ÀF]Ksä ÈF¾ÃòDÎ`·Ý¬ipöU¨×­@*¬ã eIº§³!ßÕ]‘b$sr§;1%3Õ·<û³Ð[SøuJÌïb®ç±Ö“,ZÙnj­ƒRô¢k·6¼çìÍϵESç¢VO!ôŽÊA23±*üϽ2[@©ôqWwP ê"ÔYÒ%ÐÒ7mûˆ‹7˜ÃN%bËë-°áR<ÄVj™ ’?è Íkc‹¾é ¼åA^ÔÖÈ9‚±P jP‡É°{´ÄøïLò³c2dgуTûû&ž98ºžkð ð nÂè—æÞFU 4oC½5®†µË–ÕùЕ™‘sLTÂsínNé»pOf¶æ‰5- ÂÉ:0™ÑN²0‘ëæ ”1xú|KŒUÝ&²$‚vi’j™a=zd+6äN"½!ÿ/oo»kÉ’‡=Á}‡þ#€4Ü£ÊïLéÙömÈA™„!ƒ&)ÑÀã!½½w¬±²Nï¬KÁº4ô¬©“»*++s}DÄ‚ìDÕfp:“—YrEŠ.“ûûT2q™ðÿc‹êáŽÙ©DU“ª6(é ÓëÊd,q{ÔºZ5q¥Ž¤RT#½p¹Z¨ÓvÒî?u9Œ\b;šzˆÛâ¨!o3"Ïe=xcf8áÉ·…PïØ_(“ˆ¥ÃK1æØÚCK®z¡;\kT_ )tŽ…¥!ö+•¢@íG¸…sèãæ*‹ÆÐû-å+$S瘝놭éãVPÇOüXl±8Çï´—lU¬ûñiÉÝï4Sm8íß&ÇïS¢A“jžIˆ9±º¥Y®» œ/_Ã![4%?œ²éëï_~+/VFž¨Ù‹OoÆpbúp]s·¾~-©Ø'!é¾n~«¶³ÏMx‹Øy7YÞyž±›VtGdºQýäú]·n)æ¶ÔïáÜÖÕóŠn =ïã îp.­»cÙVUôn„d5t£Õѧ÷U¢¡ŽW”øûþ.VD±ÍI;ºI7/3Ôðj%œ@¤EÈæ±}ð =YL ɶ…´¯Û= Ò2R”ÔØ”X¯E.~» ˆA¯˜ôޏ ÌaUK ©ŠÁÈžJÍé¿ß8€€Ž-Ñ‘B m/iœz¯†Žõ2ÕÂ{ëP¼wh–YÀÌÝ5Ítˆ£ñeŽŸû©ƒ­õÞõÖ>Kmsÿ¹E`õíš÷® tc’±³ ¡®åqe¬¥ÛŸ÷uyÛÝ~ÅâR[÷Ý–ºF3ž£'Žïpqvg— Þ6§T=šM›“¿•Ô¼Ky p©ÉT¾$pÈ¢“®áa%Œµ¢YìÌ›ÕÕl¾ßû3[ksÝWÏê,¯ìP¿ä(bÿêW€ë­Ý ¤­záµê´Ñ7í®ôOË"Õ±ߎΎ߈"¢]þÅŽ8v‹Eu©¶€§jn‰tz»,2övn›8Õ½výÑ”5*¯h‘WXl2a3˜ú·ó¸ßo+{Þš9WêCfÚäÛÌèÙÔÍÃô\›öÉí$CÑ­ëRvv4éU…´X~YОߌ‚~‹MÈÄú= Á?Ý<ûx÷=B¹|Èe¨ÚÓ¶®fM¼Gâ~DQËnÉHô$€î%Ë8³¯¯ˆ¯­Õyº’ú~cºã{Éô‘?hï•Õ.ý¿ !I3–è·Ö]ÄAÄŒ’fÄ0ãy¥a`:}9Íð²€sú ²BEQöµèïv!$"Ù´¿î(>l|nJ[hÍ—ƒ¢ƒHEé±ìÖæ[êPu”q—E¬Á̺?N¦¹ƒùYæá±RÄŒü|fha`êþÏßÅ=ýôoß6êâCÓ`õß™£‘¹’v0’ ·[»‚¼R…OܳþÅTÞŒ1”ÆYgÚýào ’¾‰:ë§4ލÊÅ»‹ªZYäÝh±{jÛ’­AÓ™€H,‡¤¹Y¸Ç ž¾i +š¡wÏÄ©â}x–Zx‚$t êFïS{;¸K ™Ü橇šõY5ßidËD#Yþ]¹uº£2¿’)wb^Fô¦¼ ¨#&5E#Ý ÿFÆú­Wòn„K#³œ¢I‡Z¦ZõHAµí˜>5Á(¬Z§âÂõðf8ý/#¯ÚÍØ@1ä–=K !à|:'ÞÌTà¦FÞw¯mÊ’ßiLÑõVÏÒ(Èáý›} .5,Ãñ ß~‘Y¿+êÍ5Îu)”­‘ŒöªúóÍ ê¸C{tXJ»ë%ÈóeÓZZ0/ÀZÌrk%?XŠðGöyÇ´”`Š ×-Uy^tÙá©B7æ•"l[‚9Œèݼ± 9^û[.º¶Ï%4'…ðSL( ¯Îh€x iת†oH " æSøƒg`%šxm‚¯Æ×ðƒÊ «I»¤[¦âöcWWóz±ùpå^Åó†UYä’Í •tk/×Õ®Ô¤h_ƒqãƒU§Y-N n+:Ú[ÞHˆåØo’¦%…ÖHúGI!>׃½y›d®´%“I ×Õϼ’‚·ÕC¢ ;´g™‚ëp]Z¢j]†Y(ê+-‹².ÚMJwÀ¯™Sî6)´Ðv)÷î±[}æ8rp¼d‘W‡EÄ3­WÂÍ[ô5ófXVÀW¬ú¹5¯OñãHqOÑ" ßWÕI`Œ}‹®²êD yò lFÆû C®Öá>‘š…Êl¡žß¶ð‚Ü*½­ÂÚ_¸»ó;äê·Œ”±jl–’›·¤‡“ºùÝËd*óרlJ˱Îïbx ˜ ÑS)ïdüÐ7³EöA Ö>¸Ú™CZk„Ï1|)i\ŨsWßêTûš!ÿ1cO™[êi3ûçÍ+¬óþ­®Û·/N=ôÍ–2oæ¬~ã|ˉÞTÌwUU¬b®@:¨˜‚kWçµÛª†_W×#l,R4xÄ¥\+à‡x¬# õŒ+ίÏ»Áýµ÷ÌÕqÚs;ƒÛBw­Gau·îð…¤ò«Dx¹Kè—`Œ æî¶ ³ƒÒ?evëÐù˜nJ`#ø+Ò-µ‡£ºnÁ™/å¦ê!ñ°á[öSj^zЬbé}'Üën…·ס6Ÿ`¿øòâ·¬ìF&‘…Ðl5v€_ž€ùñ˧I¼¶Â;VÇÐM…¼Ì ºÃt”‹n`—ÅvO“›jׯÔûÁôz=Y ÜŽW+QÐ!$-f;ëÔ–› )°KP ÛÄôªëÕ=#vRqÌ{€ µ¡Sêê‚LHk©gÝŒƒØ­,PdžÖ9B2â¥`Õ»²šÒé΋¼´göMúhD»sÇmg¢Šs×£ÙÞ!³üÍqׯJ-B¹y Ø&Ĥ¥¦Š[AèáCľ,œÝXå<Œ(Cˆ+Ò¸!µVnPÄØÔ€ƒÑ[‘ή›I0‚PKèñL©h×%šÞŒH¯ˆÀ¦póÉÑ*˨ÓqxíÔ?‘=ºÇ•~­ê$=ZçÕ0¼~÷’¶–™ê¤fNS™*º '†¿ðÂMÈí·zÅfݽo/­Jê†Lœun‰|w©1Àvù/ ^yi”«J©-Ñ>7+¹¬àvwwil2Š×] øÆŸÊ!…³ÄdÀ}ðWVHÄ p\ù¹± Œj•‡£Í»lñ’î΃wúÃ`y@B=Šáe§üAˆl‚ÃJý¤Ý’í7èló²”tžfÔeä4àa»x¾bîÖÝž½9;RoFÒCÍ×¹0®£(±­²5TØïiÑAº¦ ÏÔßm-ËœÁñDËø%ÕßI|4GpSoMÐjfû/N(OP·]­S€vIÞV?˜ÂÌ"Rõm‘%t±[!ìǺEô ÍÁ¡¹Ù ‘̼¢7´¯²òj/xk+zºÇçTo!’¢mˆ1öj©±Ó}åêÜmývRý¿Á˜oÊÿŸ¸ßZ4£—$3yÑU$½ÖBöµ›è‰ÍÁºûöÒh”HN‹n˜¸–)u4X ñÈÅc½ÁÒp¿#®vhHp‰ÕKÏ¥ŽHõÆ»«õFG÷B>‚*—ÕÉnÌÜéª;šò¡«7J ¦¸ò+ýLê×Ê NRRI*K¿sÅù\]?ÊHK·zõœ!ÚX¼/¥ÜV·ï¸B6¦úö§Ð@$ÙŪî}víöÝ‹·Õµ®âé[*[;ùr 8þêaZÚ9šv¤œµ:›I¨â2rÈZVi ÍÆ÷ÐU1m´™Þ4ïxŸ4y .™æk»…K»Eæ¶"ü†›Üßú—¨‚}72fAÆ/À¯-ä(Ûï‚Ó–Kån#r„ y?ʯ:s¬Q¸†•èW¿µG kíêÑòKޱ!›­ Q.C „ÑÕ¢»rë·ªÒî/tkŸÒ\XЯUmD¢µ \ß‹hh‘Ű.$ˆ¶žŸhhþ1·3¥T®½ä h;Â#4e—>B¤³ß$ÚQ ?UúŽ€¨r‡Âµì1oØ å »¨šþ$­Ã ‰ žòHV‚šÃ9Ó1@–÷ó…TÅTNTKkÆËfË psŸõáÍ jÂ)'Eî-àþy€îk7*‡¼7mF?ê~“ h+dn+nE“êí:µÇ8ëö Ó›é!+ cÔ7ÅІQéêMi+ÒÕÝo0`Âñ\ò‘Êΰ i}¯[\c¹»@rô»²‡FSr ¦„žVܤÆ-߬Ï/#1Ûþtc;µ#² æCüÿ 4¬h9­9NLWU¼sk¯#…‘h{[³óÞm—õS·n#Zzà‚HáÆ2 xÕïïeУ|J¶E‚Oc¶8ïjتŠgJî· ˆ`ë¦ÞĸwÒ©ŸjCô]’3%¿2]‘WP†œ¹`ìÔrH]iÑÏ*T8ì´Õ5 =a%uq'Ô读—Ì-L™m¹£Õ–ŸS=M~:Ön¥ÛÞoM@Œññ!sH ¤[ôg‰V£[v-véî´ØË[”›1ÔYÍøí|[@uü¥Ê'D –Ð6ög4K]«Þ5˜ê”˥ƒP±`ªÞâ0˜kĬÐ@…ârú8«ïw@/"­[ÿIwÖ eÒź‰BWj1¿}Ž%o ¥Ù£]ôB¶\øÛ¯}»H—BF<òÛ˜áJŒ€¨Cü#iߊ {[3Ðç7 ®ÙT.+Í(¹"-’¥’•²¾½Õtf¦é¢¡Õrt t1h“*JªM¦„›y«œ§пá8 ÿ±­ TFš‚ý†jпŒÈ§W$) žša)"-O-ȼS³æ(|?Í’w*—«ÂH¥|ÅÜÃ%AÿZ#AžŽ©ü÷­ª—ÇVn¼ÉQg/~ºA¯Èéx5G&î†CŸýnæ¯Ëáà0¦[7 –NÃröQô/êÀe Ÿš¯!sî—Êñ£¨S•¨FÉ–’àî¨RlÛ[BÂÔî.qšS °{ä½ßØ÷¸cÇû¹¬tKqÇâö]¡¤gjÓ‹;Ÿ}6n¼è |ªñ7Þè"³wš» èlÆi£&ï7¦;Cr)C?µ«£tXƒ¯¥qud%ßÇààH ÝâÔtì’»v:«ùLßσèÖW€—.ÿ môgóOƒì‰a'p#¥#&7µ{%@°B$›ñ}½Pô‰MŸ<-”>7W0 "KúR‹Ì ²[ïaí§aù)Õ|kºaÜšGÖ¬!X +‘µ²n檯–Öù~[9£•Äreíe0³Øj"“ƒ§OøÔîS–RzéÞ|ô<À âÏnÝù~š‚ÏD™ð¤[ƒ9‚Úèqs—B³ò7§I…©uI„`С°¶×Ký$~ºòÎR‹·;S«‹¾»[½%ù£&rE޹FEÂp7Õ9}ýú­½ü‘µÙ§aÝ¢»Ý)DÑüe…‚÷,ë#˜èWdÊ"„!úy¾; [•ÀgC.MH@²v&ë ¼%àskè!ãi­íEÌûŠ€3ÚCý4µ=¡4Ók#Lm5ö:˜-†@V—½ˆA‘¶Þ&6Z(J½òÞ)7±û€w^epwÑÈÎÄÊ­™ø7›‚5¿²á ÄæûèÑÞFþ Yug0ÒÚî`sëy|±«¡w«Ô‹BìfV^å",Ä[G³ÓéáÙôfÄÑQööÐDD´'Ê¡¶c­ç¿Ÿùït±mͼ}â`Ï'õÜv¯eêK˜1+W©n¼Öñ ý7ýyd wPk M”âûïÿˆ72CUÕz#‘¿ Õ‹ " !ŠMh7(®¬¢·e/Yò«Æô>þüN·Þ\_h9)ݪ8úÖ+¹Š~ym>!ŒÑ[twük÷®S’ìAÖ¢FÃjéó~º5P4¥ãºÁM)6”fðwZÕ»¶yÅüûqˆïñ6˜>DzBJZoƒ(À­BÕR°Â¯ÝýõЬüòhö[ÜEUð’Ùwô¨.íV ØŠtrtt‰Ô™‰U¿UUQƒ‘÷Ø“öÓÀš5ï{çzt±)¥Á¨lo:&âe§ E·¤vµ)š4 0]!|z°¿gnHÀ”áË¥œºònÖj›Æ€PhóÇâ7H ÀǪïâítgåöÄBhÏPR•nÓw^½·žB)'kN+·©ìöìÞ Þ5tB¦%d€StýiêNæB)´P¦Ô¿z`ßow—ÜA²½kè9únV:oýapµaÃ`6¥L™ËZÜÌ›Ežœõ–…AúéǾÅ]ìãÓ.ùøõŸk銫ƒ¦–ê3§ïãêõµ ñDZ|Ð,Pàp„ªå/Žèë†\d„¦Ç£À{ë€?ö¹Šs¼ÍE&YÛÚ&‘&RŸ+–x»Ç,škæÍ™9*äïƒè}#UYßÎ:c³$¾Áx€N2t2Y©'Øûìê9Žóý<¶~4ZQ'Jç둤w™?Ó“pE¦#0hó&z!òMS¥3âüÚ&¡Šð›™¶R"n Åjpï·Ëç‹Ho]U¸E½bk{çnÚX·Ë’‹ùg{+Ñ æ¥DOŒ•ñ>½Œ%zwm­ß1ɱ.­KoiLòà-ÇÀ*™ 1yp6R]Æ’¾¡õ…ÔcLv3õ¼Œ“mƼußRc˜1ƒÓx9ÈW:±U)Æ Ž1ˆnôŠžOFŽI°ˆ=›ŒÁ•½….›×wÌ)¶¬¨&n&JÎÌÓ}<Ù‚x»wª…¦ßT çd%_q‡ß× ­dV×çˆý}7KŸã¶ï¤hy3‡ dì®§0v¦ ¢3±­ã“µñš#šl]¡¢2Ç-*‡·uk¸,J Ì32TÂÑMm#戺®õ˜×=Ô¨äÆ-Ÿ믳12°MRʰ°võ¤Íb¶PسáºQJf ¦:Ý07õÖ9¹1ѼIÍEÈõÖnëüÌ ®J.°¤qÓTŸ¨îîá,·~Á¢ä³H² ·È ˜ó§†ÃßµB‹özAß&*ë¨æœ3 ûº5 Á7Ò¢p`f 4-d ƒ3S€Ø¡&}:û`Q!ÆèV/⊚y QÜÖˆž}yïŠ (~¯}¦F«^­û±Øa(:zýúnïçà‡¶Ë¦´®’\8ÆÄ\H#JÆwÝD»Víø„±QÓýÇNâ¿çfáÔR?·2oía­¶ÜAiï9ùš‘=¯Þ‡ÕT ¹Ðé”X‡,ŸŠ~;¦„ø=¤}Ër¼ðËØûŒL‹ö†ÑÙ‰Ã7HI¬Â<µù³ì=:™ÛžËaŒîÏ‘~{¿[¹|Ív¨ÔO!g|ˆlt®@™¹òt²??Ū:Õ¸ØÔ†Ð~‹ Ç·Ûú·«ky£-ݯº£RÊ7‰P8Ë!Óü>Èö·v¥ñbäÿJ¥b:)ž~¢°.Ô¶x=þȹnRéMµÍµ Š%Œ¹ˆœ±§ÎðBBðn¬².êwÛþ3G ³Õ˜ÝL"íºÂM^â‡ÀVu»Ì¡Á\H;ñ9S¾dUGÖ1hwŒÀ*Tó–ðîȬz¯ªf…¸«H¹ÍÌ~ (û%®†EõÕµÛz\ž¤ð¿Ïžÿ­hìq]AN]ùSOc‰,c‘N5j7´èwŽë {=CìG\m¨¾¼–‚)µ ÝÎe²Óœ°Ýw]·7<çÔm ¾$îŒ}JlþJÁ:»¸v3˜+«§Šw›TkUao®`Ä\Î*:~|–‘"œîÃÕ€ÜÜNà»ÌC@,#Ü}…½Ûái\n–MŸ¶+7x¬Q^¡FnÃÛxǺÝÇùöÔ?ì¶XðƒØ“€†™åÐÔ,ÐøûÍi_„AÛÀòAó¢‡û”ù €!$sÝ;oœž: -ê4….mÖÒ±´£^ÖwB,u 7o™?FŸ+ا–íÔ—8†»÷ÓƒL®tÆ*5Z¹¢¡µ ÍCöë†jzdþÓ0]úZûu»9ðÌI–9Dq”Õ‚GzpN7í·Ñ™Tóû[t™^fgEÜ’\«³S§ÇüX;)îf¬ò˜Þ‡Ý-ÂÊusyV»ùÜWt: ãf |OvwãeT®+”§ßî[ÜÇOó¬ûpª¥-*ÖÀ8U(\ÆÓ>¾ÿÓƒ^ëß3:"O&y§˜†r»'ËöavRŠi÷ªÙ*ƈ‚ŒAø¿‡ÖOõÜ3¡Y¹_³Þà"-•fè9ÝÚ) ~z™¥«íªi 2†°T†7AXǸ¿ß<$Š*¼þ♚%ZŸ£:«§f$™€ì–-æ1›èÊÓd“£—±F+œ¾–ŒW¨Ko#˜©Ïœ£ðÚFeVÇ“7P£¥‚Ýiã¥×à!U¥©áOå´ªZX&SÄh1À.F°]–›úmJ¿þj¨*”ö.‹yQ½ó.ž›B¾wöP‚NÒGÖ†M©²¥ÿdsmèâ{©þ^÷_<ÌwÍåRBùü}heTÕ ûjÑöì“PC3 i¶”"EPÓ5i´bQL-×g±„ƒ²PÝïûítg+ŠÛˆëöê[R[Fºy3”E˜–ªVk°áç *Û{~§y·±f÷$Z–Ù úýÆâŽyéüøõßJ¡'ºí\Ëß´—OCÞ&fm ! ažbÈHöy®[·H+Ð=<Í<ÜGÈ®™±uê»ÿûh÷'þÚb±2G.U褗QéIbä×™]YÞ×÷p¨OÇǸœ½ßÜÑ®–ZðRJ¢7:nfc&ÑÍWàOhÆ}´ñ0*-ívè_Ô JN[ur8 ‰F©hn$µjjŠß®~c6jèY6ét?ö­}Y·ÆÖfÈ?äyÅòñ@äeÜJTò[Cn1òÉa¸f¾iÀ%•Y‰éyÌ´Š0sž‰¿ÿå¯~Y_þìÏ¿üõÿùð¯ñÿËüÿóþö/ÿøÿÏúßÿ§?ýÝÿàÆ¿ü»ÿøødþ³¿úÃ~ÿñwû¥ÿù/×—¿xý÷¯ÿË/ÿøúÏõ%}¹ì?ý__ÿã}ýãÿ~™þË—úåûòýûëËßâÚûË×1_.„vÈGY3Åפ¾œJ¿¾°~ÿlÙãáx0ǰ{û7¿@†-žÍ-€kYööÚÝ­Å8@¼ýßÛïZ5µáØÈâƒf;;Ülªâcvéµ|Ìhé#7Ö:yåë-\5³æ}€ÞùSž•µZH©˜±e÷#Ìl*Íf;rcf4wüøX ÿâ?üË¿øãŸþ§øñ§øÏøýÿë—õ2ý™E˯3õÏ¿üËÿãOü‡?üÇ/ö—ù?~üãÇ¿ýÏú=.ýó/ÿãëÂýú¯=„uÇë|¶â˜)3¿>¨I3vj·-=œ‰Ú˜í65<¡ÝŒ×àæ qy3îÇHÀ-Ð×ÊŸÍ£0ÿû׋»´¼â[Ò ?Ýÿo87ÐñÒ )£sjò펽øhÆòòy©Äf´Rª]½ÙÍû–½šæ£B5•ƤQ?ßÀoúÞ-™â«Q€Þû¸ôŽ=t#Pž~i¿M~Íø|ÀžüÙh«×ßð¨ï¶Ó[70(?¨Ì+'øön3ÄãóÄâÚ«ë%ä®›ù£|"ƒýžžþÿ™5WÔÌ£jb­¹°Ùæ^å8.̶ ªoOÓ0 êóüʟכ¨ý3?ŠÖÃöuÈöåø ,3eV Fi̶æååe7šdÆÒ]Ý2 ž.4óËês§íø­^ý‹ª[¡Ñ 3›–µ™=Ñù26Mä¼öþÞ¼ _G‡¶ò®1‰B†–1}Ôµ8*ö³Üi,ÞMÎÆµ¯ÅÌÆß·»2mV³µÂ¿Ï øâÑú[keú ˜ŠÏšÚµt>ä×FÃiíR¾Ìóå¦äB3ÒÖnä–ãJ•ÆŒ8Îg¥¹@†™÷ï¿üq\×j¶<—“{ý,B…Íl6éqú°À.µ80.¾-ÈDTMÀç5ô›-O8sèûŸ)zà/'÷f¤°Üf-Ñ^6¥^Oþ7v)r]{»57ã˜ýóg6ÄAéÍY‡:ò­q\«N›ÑT¡Ìøúv' DT3Ö~éE€æàôàò»‘³KX¸ô´jXf×fîw(D¦ÁÇ­p»ÍØ/ÞVöøÃ¯$SÃÌ.5‹h,Ú©V-õËq¾ÓwiËÐç|\3¿ücί1RÝhê¼nœqsO×Vá´»Æyá›™1=Ãw×ÝìÔ åj°t¹ÅmùVq÷w§ó©4€¾ª—¹ ’çã `Œ«Óü†[9”‹.Žmû€ïåX O——–j*Å1lsCê Pe_’Ž`usi‹ÇëÕf¬=ÇôŽNcïZ§µ¶=·}üòn\1€7O{‹ë…»ñÊÜI‘è¡—j2º¶#KíFÍ™qµÊg¼íe®^.áµ¾k%kľôcW§1·¢ÛÊ\!nnaž+®SŸðµ+v¡<ý0y™_næ fÝÁ+äÝ–µï`ÄÂ¥Xßm×.ä$9®®k‡{W˜ÞÓ¯ÕÏ_¥òÍ8êŇK;Hßuþùz5mmèÒâÆÖ:ðB Ç+ Ö*ôÆâf^S¼Ž;]íö?Âö»\¯ò“5ã¥Y5Yû}ߌwÐb²LÓUϵÆOËðy\± ×ÔÑSº/Ãz[Çlƒè÷¥õÂÝÁײbðËØ‘ñÒpÉŸJÝoŸ n´2%àKé¾íSì08¦Äû„TMåÓ»*‡;¿‹€f¶Æßn¶Öâf4­7ZÔŒVq§[or<ù6.M®¼ÅÎ4æ5nžq À#ßxÙ0M×(äM­&cÓÁf‚ÿ9Ö³fv\œ-´€*ôLZÖæœÑßîê0šnÝkÞÙ…éC¹±m¯©ë²•5ùc³šÓ£‘öüÇP±ÿw¼v¡žÎî›KFbêÒö6=dȆ³«o?–üŠ}Tù¨3®ŒSq[ÈјqÉm9¯‹náë-VN͎ǺÙtés±%ûã—‡Kc>ÿþá^Oõ8šYti÷K3V´Û¥nÜN ûßg?­ÌldL:"Å3 'ó Ia´f~³7eðJÝÉI©1€áìigµ8)“æ/!!ÐÕZµÅRܘ·.6£‰:ùwQÂÃê£(‘C”¡qcƒ.^öB½ç‡FU¨ò õ•Ç(SOÀ­fžÓ7\ëN½ø[׎ xºa²(Ämfže“Z7š¸†åù\žsciʺ&×9€KŒ›‘;«Í ³.K;+òKKn–+¾Ó,7Çš¬úÄ^ÃÁØco³Åuij.å¸mʼժlÚôÈFœ.?~y¼öaÔ‡;8Þíñ¹Žs@8²¿råó»#¾¸%íÍh§â7æþ˜,ÇÃËèþûŠÔ$šõ•í—íÇ.æ$ª‘w°D‘šðÕ²šƒéaÀÒݼ1ï‡lFùöD¥ºQ…åŠñ@îör¡0Ÿ˜+R}‘žJ¤ÿÖK P›.³ðÖYÇÏ3¤{ù°)ñ§®Ö{L¢!ùd—&¼e#FyÍì¿ãµå’S#7a§{ á=~m¾wæl)Ç6Mƒ8¦kx€{íl@ cìÂWsÐSFåo~³lMª.TÍØ‹™MÛØŠRùŠ@»²Ü8£v†ì} O險#çè¨W+0SŠ“ÍcT ½+V”ucNáÇôØ„z„¿Íôü†…ðùßQ­wˆ,U™#ØŸÝ àÛõÞUéŽ?}0Ûßÿw„òwšô:àä½¶1ÿů;³ºí Ä%ÀðÒÃswXÞËpèCÖai”&ˆ“Y–àFñ¤q¦$¿=2XY>€Õð6/#€#–¾l&D=i¤‹cÉLŠB¯›—Ò(¾#bsó]»»‘•igï‡næîsÛLøÕov)“)/`dˆÁÚISå[`ÅöëFÔÎËXp¢ØùÚ†«›À˜TÙ‚q9 àeFn7:"îe*Žêy)êíÆî[ ´}™T.&u…©îð †åMÏv$Óªnd]ÂŒ‚Ĺ¹/à^‡ÙÜsï×¾'@,þîé–ÕF‚ióº=§ªoú2fö†u!°UÑáÿd€Î¾×wÔšýú^\v`¾Œme7fW‚2co—z.óß{Qô9LËV‹µõjˆIb™ï‹h´M3³Ð‹kýÈhRÍÇèvRÀÆL$îjLNa™Óo :-ί}…øØé;RŠVוæÄ½Œ&áo´0»Ô&F c™±òT»ä•iðX‚Ùdoì,Ìt#×5Zyr Uk×Ýh.‹x­NΖ#ª}€Ë\!ëËl–ýT¶Xåõfû{z2=»Î¹?‚ Ø çagϵÌu}kï3æ C9ÄÌ®`ÆRÌèÉO|7Ú*±Å9–æšíCK!ËÃH#§x‚zùŽc †z<±ƒÍüŠñ4ßLæAEÙ«»fôäT”‘]ÒV­6só(w0’o“=UÌÈ"Êm?@7< 6wcð¬, @îØS;¾\ýëî¡ iæî1xƒ&(ÊFCF™Õ7=ñ2šË¥¬žiæº8[¨ªh€Ò|+Gת+#³ ëšÙÙ{fdÙÛQÖâ罦m:ø©2[ `ŸoÛÆbóÆä¸jq/·¢‚00µ™þiÛ°½¸Å¼nʼnüJ3Û}Ûëzy¬×N«°CÁ×^—ùæ¾4W|‰À®W®îáÉ<ÿ±Äí4¾45O¼2µ^öø)‡q=ÑoÓÕ–öcG¢Àh3çF•ãÑ„gMîòËÃP3N_[‹¼\7:È >öBrÃÜ:øÉi\ø<Ë·óå¿A‡Àiè¡S«>DëÚéçßáò7äFC4šñ¹ÄDÐ[„2fÌûÞ¸‘Ît»Pìôóø·‚R]È—–õ²“—û&ŒYûy8NoZq<º-mo¦Z|ZÑÒ Å¶uœ_NíõA=Æ€“`Å_ð{3.—Ž.)£qTAÝÏâWP.En¼Šî?ÅÇQ~á¡.CÇl‰Eásl:r*^Þ‡Ìјû‘}+šÀ¸ªÁ2™>@õ—äOÖŒˆ†ÄKw«‰)'IIïðöÉ-ôdè(š±hX&ÛÝÒ”n«ˆ.Ðk»œK+îÎv7ÆmM{L+VÑPš«åtX¯aóu¬Wx[Éw¸ì±¦æ€„ú<;`óuù)SˆŽ´—àu¨—Í^²Vaòƒ—.ÿèÑa5é-2EƒeЧ{°Ù»Wÿ cÊ„2$ y¤æáj/cbg`3Úêñ+Ëv͇'-ð[ÖÍÔŒÚJŠbÄ‘Ûm²K“c›[üV!åÆ>p5ÜWy‹->#–_Ñ $ƨÂ2Ä?V~½x„.˃Ì£G5ü‡G.oßéÇ/ŸôáÓØ$ŽÊqëyئ¶´Ãæ÷°Q7Õãö{ÞªÛúù8ŸOÇÊé:ŸU‡cíx>–ǃõx?×Ç£ýÁ 8: 'ßâÁ ypXŽÎÍÁ zp™’Êt07yW×U¹4-UîïÕ0¬fôT¾­‹®1™>„±Å_·ª“° غBg˜ëä¡Ô3Ï ö½ðkKSðyÜ¥;úqï8'ΔÃéópR=œj‡óïá¬<ž«Çøá´~8Ùß}€áè[½ƒÃòó6›ñ Lì³ø‡'°ÍŽk½v:ü#¢̾„Ô<÷Ù·—üñËã‚8.‡evZ‘§¥{ZãçáüÕ<Ä$‡øå!ÒyˆŠÔ1ÖzŒËŽ1Ü1Ú;F†Ç(òo#Óc {Œv#ãc}Œ·±ù1Ž?FüçäÀCáqxÈN3ÇœÇc~ä˜K9f]Žš)ô)²9ù¬å¤/3½Ú.•ý;ÙÂö÷RuvsóÖ¤…}¶ þvé%š1ÅßÏeïé,ÔaL¾›‘àâÞ\ñËÿžb6ž¢òtÿhYX„¾·´ðóí Ù¸ðF[ñL.]k¿×«ø cè@Û5Óу×Yê…± }Þk8øJÏõ|Þ\`*j²§~TÀEð«Èke™ÐKéÏ2„µïÉ‘8f¾ é0°JŠ•Aà­,ÿŽð„W¦±©Ò5::P.ºF3;V3OcfŸ¡—± ÔáŒðz¤Õq[FN4㨞•Í*¹¼æ x™N£^AŸ:ÕpÿÎU€‘°,<¿ãR€œ86l€yݶûûî¨:O&Zäö2Ž`5ô짪mæ€ËôÎ'P^ÿeä¹Ú5'óâÎ4nÆãµC¦©Ïs6›­´nâ^8€â™a“¿¾Uý˜sÆø«•¡š:µ:–®0µ›Ù¹Ýžº–/õÐê Ü`/s€­ðn¸âPR ÿ6ŒË1ÓîOáüç%g¾‹«û2&X¼¤*¸€dñ+-ÇîðÉ};ÎþÝO^ƒû9ë@@é $l6 ¶üïÙ “ïK„{?åpWË'Öøúvx÷Ë‹7>Hԅ׺΢­9£É•˜Ã"tð“ƒÇ$ÅÂ̓?†å­yÉ,ͽ¼¯ò…™>S,z!>¥&¿¯¹âè¸v’ÚDU—¾Žç$Çûßgò'ðb|ã„‚Œbkˆƒ5…Y“ŸíB¢àÒNP6J¼Òâ!E¦ów’.Ò<61câ繆ŸÓU=|–«ìÚvɇá'Ô§/dÒÌ47ó‡,ó¦ˆm/שë-vQ‹ã±Ž(djD¯s 2¸SS¾Q4¨ð÷Ì_2,•Šñ„~âR±Œ‚ÐÕ>A*^³©º ~Øã2d@‰¸YsœüPœ2Œ'XÜ ÚÒ›"hâx.à+×OâÝØi]sÈž¨ïñóÿR8" :k·Æ®èâMB¤\z«ÌgO%"†ùˆûIõ÷VœóÅ)¸}qȬiFÈwÃËñ•6©ˆÊ Ïl †ZmU ƒÛù“xxøbì A¿/2'àEXÞÅ¿ƒDÊÛbFÝÀ%NŽØ[å•MIë³P™¨-gÈ7ÕTÓFWL½¼—!øJÚÇ_ ð_6ÕRß\R ôñП€Ý°ÈYˆû)Ç h<ø÷Âäd¤àg:/îå01¢¸æ»GA§jf6&ç6¦¿î.¤êVÂÈP½¿´i{£$3dc¬oÝ\š‹Î`œ]›+1€ý&G¬XùYhý<=µÉùwâÓÞ´†îÆà¨†Çñ†È³xî„`|È·ùwŒØ(éQ©;ñÕÐò“9Šá‰¯˜žzàk¯m¤{ÉU*‚‹% "œ>¯p§ãHõÍCAdãiL–‚‰È†ãNǸñµ×v‰§5ʘ¯ÍqC³…ÖwÝJÂ¥º±™G ‚ÞvÛ‘‘"u!êœhõ>Ü MÝŠÛÃj­8ælÅì¹(ɲœ_%ñ™«>Dfã§ØúÜ´|Å‚ý±¬N€ïÛâq¨–†v­rˆË]e7*Ó¶\Ýd-ÀÓN"àž<³V´^›îÖa•Ö“ÝãÀ{þŒTIMµ¢öè»Ì+JMKÉV#‚x2‘MÒ:Ä sµ‰¶ñËVUý§‘k¼ÉFG7¯XÃý;ÏËåª%óšOÞA©·Å¥Q-É Ñ3`H®üû2nDœÖ¨:u²(c¼C ù=zÍKs0Ör‘7ÈÁ3v/UH0–á!uà᡽.ï8Áy£yŒ|KX&)IãD¼­Õù…O—@ˆ]Šî yzƒ>lÕn@|hÿ<`[ÊLf•ö`¾’ÒR.&2ã­ž‚LÝ—“ˆ<`«],#˜Ëƒ¢.vAOãøä‹±½™š½—F^T¢/¶]G^Ô%%l3n‹©¾+X6¯¯Í¡Ô ÕIº‰½Ëw 4Ð8ç€ö¼‹:8dìöæ-Q#‹–ÐiUg”×[ñŇ ®õ’¾ yçùü1´4§¯iþ³XRp:†Ür&=Eö*y¦ÀÙA¯~Dۜҫ牾´¹¸ Mùa–Èûïs$ ıi3R°×ï”`ï¸"4ïŠj°˜ù £…¤û#JË9Yn,}pýï¨u'-²ö—eåó$ ,‘þÖÀ>ñ—BUÄ™^…Û˜XfÞìž_« óû•³Êˆê}"íXãwšÀ¢CÞl¾‹![ì/Fv7³5}1³5>t£º“ß$ k±äQ"·KëÓÅÐé¾Uü½•¶1Õ Œë³Ò´‡!^:Ç¥d–õ­Ô5PÝHœÊÚ>i³»x..†Ð®[ÉEŸP55`¡Àq§t9ÑùSn¤B3]Iˆ`N®@LÏìûST~˜=ÉW—<Ͻ®jwÙ ßîƒ&†JLWd>(kUãnSµRsµ‹Rt5‹j°îÐù& ÈÚn)¡cî‘F©J.Ü:çðj—~ŒôE|##k€×tje³èw«±`’ï85¸Ÿm„c|ƒWl¹'=à<™ÓU‡90vy‹/ŒS)Y;¿}€îÛ;)=ûîØŒ¡çÆÇ㌌?B# ÔCÉŒµë%x ­Ïü½–%u%[[~ÿ·jîŠs´`ÃRΩîàvÞVabh…vÒ`zöÀ¯$ܺ‘G«è~n ½Å‘—| ×CêyÆÑ6|½´­€Ø4‹ ¾hÙIR²Ú¾^¼ÐýÊ$  ~q厕'¶õþÔÔ¨ó®ÈEàÀÛšÎ=újqüê…`¥‹ ïIDm#¨¹–`Ðl1Õ #12˜«Ù4Ù5°|ÅS‘¡à\Uæ3We-®Ôù8Ý.MÊ[ˆß^Ò­4¡ó–+)ïÖZ!“ “)bK—+JÝKõP­€äwµ3<†Ep#Ÿ5# +TÛ[^QÕ_~€É–0“r  ’Yòš&¡Fî ¹Ü‘êWò:+Å6†ÎÒy¹+˜›èê8é#4ÍU‰?Ë'»/‰´] Ú¿¡Œ˜DzQqÝ)ÇžI°=7K_ÀêþRg¤¯KË*Ê5ÆžÚòV§xÉt¦g• ÔW8ØÔX¤£©@‹+(ÿiÈ÷3ãã— :0Öežµ÷§åŽcQ "Ù¤bÞNÞ”aãrú–AŽ8tM˜¨ŸÁ؇0Šs9³”hfU_!”îâóè-[­BaÙ$€ì(”¹(~²yLÂW›Š¸¢0b+þÁT;©ë0×.-¥žÃÈóдÁµiÝ”U¬«.ŸÌÚµú‰âîÇuczá%œB´¦­:¤Bh•†‹1ù•{Rø4 7³´³‚?½Nrh§˜BÍzÍéïI»òã°.ÕkÈm[Ÿ¬'„©ý]ŠÖ.ªQVwÅü©\àÌ%WÙÞ—êMËpx”íFb à 'î¯ öEp~åpºwxqc"jª‡¦€ gÂÔ<äò?OQNµåhKY¨%&?MS¯óB“õŠÝRà k½è¸Â%k¶öŒ÷[ɰNR“f!^ =3ÙÃ&_÷v„þ÷=2!=ɫ߽òÔ:í¶,ndü=€y«),ƬJ˜­©ÀŠ[-U*{õµƒ9–Éo_Ø*n¨˜fj<©ýo‹J=f¦TÊ*WYÈ-±%`M_®¥IíTJ,’´ÀÍ/N_V.S2êÖc>ÔÌ! g2ÜnœÒ„#H¶@»¢fÌreì¶wõá B³¢~Øï?ûbðÅ&-¿ðõ&¡5ô Rfm*³å„›= #óÌv³÷„¸•½6ÿûOXFÓ`w”ã2T”m]̦¼Ž¾jÿûÐmLY;tBuè./{XÖP/+JÎÀiÌ•8³ÂuöBK7ÆrYTÓê®7b\BM9{6F–ábuˆ¢¡<&© #ô>1,™­… ³ÍHÕe`X‰b2é–L «r5Öc:J”O€Xëâµôñ >"`mK{µ wsiÜ/™Û˜ÄVg—ÐLšPHî¹É7VXäõÝ;6Õc&WöømpÈX–%6Ë[½ÓÚÉN"ÎІèò$a¼jj3´]èÍÌZ nÖk-v-O¶»0i‡x¤­ùü¶Æ (X\ƒM ¨AÄÉ£VÀd%§K0®±°ì‰eášÄ—±|Ê_/%‡0)b¯.⼂¸!1ø©E! €³´g$‡Kº‘•ôµiߪ×h©Ào€úw/³èÁHdMŒN"SYdÑlà?2¼^ù¶ ÷OfY¥çºˆtF*•Ób«Ý X‰uiR!5Ž”çÐOש3  DW.Äìñ 4Ju©z'ý1QY'h+¹x›ú„}îÞ]vhÑWCB'wã‚ðŒÍ—Qu~¹í“ƒ×Rã KDŒšw`ä'Ît£²®}gU4¦™gU‘!yiÒ¨›tŸã$©¡Ó²’æœåËãÓ˜žtó Ê´$²´ éÌlAö$ŒÐöjjd˜äâ±.Fõ 1ÉG¥ð¥Ý|€ê‰M7»ãh„BšªJ`†õf6µZ‡ÿû®K i_äm#?"Ô²©pPÍï¶%kÒ–ëÅ2ØÈd‡G)píW cÓ ¦éky~ Fëú¡!œst£•› ®%—ªÌÔ®!xã ×Ïͩܤê\§z¸È99œçƒ×û`4ÇÀ¨Ùt‡×÷!Ä2IÁZó.ÒÏ$Á#¡ðH=<`~æ^üwˆs´êS+ÉÚ6úA³À‡ ¤ø¡:– Ek¯íÀ(hÁ¸6p^hîÉMÚ1ÔIrðÒ ÍàÜ6ƒò[¦µoÀ÷Ö$è‚ûÀ¨²VwR‡ÿôtåo/õ{ [WwÚŠç‰ä+h`Í+ȾOÞ2ÌW嵪a5¢ddeÂŒrWQs¡áNæßWlSa ®WÀv)ƒ·e˜÷Ýfák€‹D1D›Ð¢îÙzmôô+q[^½‡±y½×úƒ‘þ¶ýMà¼IÉÚ¸¾<¥Èb(0ìíf‚ vÄ€c* YÒÈ@ÑŸHƒ­6Ñ™pøAê2ÎÙJu¾Öú©B âìdö Çž†0W(x¦@WÐsÝ}G‘} ‰òcPæH‚e0<&¤d„÷Ø©ÛâÐ W#çß’‰à ü-œëzíS.îâ ¸þR¶¡ýé~Ã$Re ,d°v/"Ù„ë% Cò`ðG zåFò’QÇ^‹Æ+ký¦Œdä ŒûùÓz׌ÄíNOTùUiÒ>·§‡Ã;®bQ½¯­îƒ¿çt/_þ[Ú«–îè ì¾vîw¨_‹™“ܬLo‰å®¦x/ÓzÙëï™»~ÅK†cEá3Pˆ÷ŸÊ8ô[ÎÊ|ݤkkf´Àf$–Þ¶ðÓA°5Íì˜ô÷“óeí±òåË‘é!Ëiæ xõZ~3_Wx¦T¹8YÛW²þv…wÀj]KÜ(?‘¯ ¸¸ºáõ«|Dä Onf,œÄY•ÖöìtOÂùšÄÛ=ƒôÕBñáiRœA›¦àÇ7nt¼¯ž¤ðw@: Ò!ž‚ÆBÞh÷¢,!Ìž$©AT m¤(zŠU¤Ì#òNÒUO‡´~ ¾ ¶B5¿£qñ[Ë•hsˆT¡ãuúR8‹@à/©À¬Ç’d^ÐGàá‡ÎbÛs³É[E:¯¹*v¾EÖ9[7°ÈêFË(OÇŒTm4—¢[öÓø‡r‡^E0³Cb€à÷Ê Œ걦³®½L1Ï]¢W¹÷‘(kŸ´†F @š¹NØ(aüÁܩ䟋X0‚m‘E„+Š[†‰‹ÎRE´ŒKTÐUädàXD¸ªëݚѼE 9òÜï€âè|“‹F«]x¢šÅ@“ýM;MJÑH;ýÛ”UhæVEbxÅ ¼ò&uˆ¾ü_œÑÆÆà£W ûR\·vr’o|š‚ªºaß=6‹¢3ÎÑêó¨±fB“NB´ÀIº+¸´ X4 2…/%jÛó.>Ö˜†˜²ïæA0…7kŠÞ·(ŒM<-+ׯ lQ[*hëOl³é”Y„(+³Ç"—îu‰†Š9d`®Ñ´ª3>¢†áÒ¯˜,¢ Êóê@3¹Ë±qž¡Zj}Žåjɳgœ½.ÕøL±sðöÝ|.²`J›³ ùÚ–ipãºä•ÎYBQÖkp´i‚´„K±‰Pq4ì“BpQúÍÉ lI®J“r™@¼V”jÉÓù>õ8ðõË ’8x*—éƒèÑÓÚ%E½/ùÊ&aLÏËa¤>ÀŒ}ë"× URFUÂÞ¹‘uÜiÊ·~ô¾Çïü‘`‡$z]œµ1ÊfàYCÏß6NÔ>섯údLe á‹Mõ…Þ]pýÚ²ýl*ÖCC9'W`tùNÄ?XUfÙk°ØÌªô¼¬½uÈWH©‚PR³º9]ÙÅ]ºVÃ^6<)ÕcKçsfž½f[•¶qkƒûó,Û#1swìE7(ÂPÖ¹8&× ÍxmÚS}sƒþ‹©çÐX…ö(:Mæ}'*Åó¸Œ6ÉkP£ð\ÒÏW°ÃõÑ«O¹Í©ª›Z?`GÜC“Æ&o~‰ÊÁpmnP óÂègMXQ H‚5¹&‹¢+Ùc@« éTjëÕMøHHæÂ9%F²^xÇŒô¹Q-ÙÛ˜6¹A ¢´P¦'ΦIJ×CÒ1Îeq½ðèM¥™¡'#©ÈÈ{K¬&ád!D!Ð1u©öær‰à uàпÍK$óâ;0 7渴›.ŒØCrÔRѱ€JÀy…ŸÙãx‚쇃Õ6®ñˆ¸4Rp‰LÃð”ÆÏ]õJ uþîi.-µÚlŠ…ñj—§mc§Âq!LÉ7‘ ,´åXsxT¤ Õæå`¦Õž”àÉ®›Z¯h¤JõWƒ§1ß:B·rÖ¢lë`2Ô^#{loVÄ~ƒÆ¿ÇKí•Q[J'ϯû ·†^­U¥¾òÅ4bè •ç¤[jXTGô¨(l‚mÐGž/#«ÈgÐGj#'WµÑzÚäàEÿ1&ãF ¬zµTC‹¢,…Á'Ù7îŠ}ÄðžK¡ ãò0Îâ•Ê·X§è¦–—q¨-P¡5 ´Ôv“Žƒ°ÂIøMüU£Q.àYt‰×‰t*°\î¹øßïC‡©]Ù¼Y®Ÿ¥UèáNòÙòãßÿºKtE„#ôyÃ%nÿNõ­07Y@ù¶ÏÇ,'À^|#Áüûgl^\*å ¨y ]} šÄEç7 Ί1“&§dó?-Ë´èK°êk_“Îe%È›g¡Ãؾ¾äé‚`@ï—#‹``O þ¦ƒ{³e13Φ7#ˆÝÆÕùiå=@ÆæÐ?yLç+Òvdèð®£gÖ(÷©!ˆñ¯3ø,bt7q Wùm: …h&û@ÎJUêQuáQ¤ç…¢»f`—¬Áß’ÿŒö2#"N‚ì¬?ìRÄ@Ûa˜PE²¼%é±uXóEÜÛÐ_•l™@ÞÿöŸ[W˜ËÝÌtÐÆaÙ^EqêbÎubwÆ&• ücÍj܆ê/©Ë«þn¤ŽQ˜dZ»Š‹‰¯­á3¸(™T?Ià½è’c=gcн‡À3";Òá]¼)©-·@€o*hnñá›y§˜I:BY~(_ˆÏC¥ŸY£vëûóP]@@a3fŽ*'wÆ~e xmc0;s«W±3̺hË.gwE! ÈÛýçJf(ŽËOßÀÖu…™ðD~ðOÅlGÓ¨¡;§ãf¤w$ŸIkbȃriò‰`3*ç#©Mîr¿½\ß„I=,A xæÝ8z'2ß#ïïÈ<² OÌÃ#KñÌg|à>y’GFåûòÈÔrp|ݳ÷|ä xÅä#_ùÈl~`AŸÓGnõûÈÙ>²»ÏLð#küÌ/?SѬõ~û‰ dÍŸøõg*þ™µÿÀï?juúJGÕ‚£¾ÁQ ᨛpTXxTc8+7œ4ŽzG툳ÈÄYŽâ¨\qиxÐÃ8jgU69ÞÄ;Ž*OŠ Gõ‘M’ƒ~ÉQéä,ŠrÔO9è¬<(²Õ[N2/Š0ïÚ1G™'=š£vÍQåæA稞sÔÙyÐäyÐï9*ýUNB'¡¡GM¢ƒ~ÑQéèQé$ tPZzPe:*8½+==hBõ£ŽJSªTG«£ÖÕƒ.ÖQC먶õ Ìuñ:ª}=(ƒUÄzcÚd:fGųu´£’ÚQsíAŸí¨åvT}{Tˆ;¨ÉtçÎug5»£îÝ£FÞQOï ¼÷ Ò÷ èwÐþ{Ð (ÇUfOr´gåÚ£ÊíY÷A;÷¨³{Tä}Pï-BÐ šç§hm%/•=À­q–ÅÃ@Ê“æå. î€i;’@~ÃÒ¾Cu«P¸EPÝItXàñeXº®y-å×òÅ|Ìú:ͲûÎù ùÈ%9²N*ïT–ãåóÀ¤9snNìœ#çÈø9²ƒŽL¢#çèŸt¦28Oü¨#—êȺz`hÙ\GÞ×GìD';òÎ8j':Û‘÷öÀ‘{àÓ™w'–Þ‘Ñwæþ=ðO”Â#÷ð‘§xà4>±OLÉ3©òȾ<25#k¬N"šŠëÜû]qar‡xÆœä7öòÓù}¢OyÖGFö‘»ýÀó~à„Ùã'¢ù‘“~"¯?ðÜœø#{þidåŸéû'¦ÿ“*ÀQ?à¤5pÖ%8*<¨<(#4ôŽÚ G‡Ň£:ÄQGâAsâAŸâ dñ zñ¤qÔÒ8ën5:ŽjGå£JÈIOäA{ä¬SrT4yP?9 ¥UÔWŽJ-'I—õ—ƒNÌQOæA{æ¤SsT´yÒ¾9¨äõtµwŽ:=EŸgõŸƒPÐAQèQ}è TtÔ4zÐ?:j%U•˜P)ÑÓ*y c$WTÜŽ5ä;ÀE²7T¬°’ÏAñ¤Í‹ku| ÏeK†šwMî:l+ô¨Bõ XuÔ¶:ê`³”µŽ*\Š]Gm¯£؃fØQ]ì]‡ì¨XvÖ6;Ë =(¦µÕŽ:lOšmGu·“ÜQ5î¨/÷ E÷ [wT¸{PÃ;*ç5öôøÚ}G•¿EÀ“xàQeðA‘ðA½ð¨sxÒD<ê'ž•Ï¢Œ9œú©~˜Ó¨ýz‚FËO2‘þ×E=Õñ/‰W^£e½l÷³ž-ê—ï2™ŠšOê›g΃¦çQÿó¨ú *zT =I•>ªš¾  •RUUO¬ïJ­GM׳úëƒNìQSö¨?û Tû¤jû®€{ÔÊ}ÐÕ}Ðà=¨õ>(û>¨õ‚–>ªuŠÏšÆGýã£Pò£¦òQ~ù¨Ó|Òt>ê?•¢U¥_ŽNa¾?$Í+ŽØAAì Iry ˜É80r ¢XcŠÉà r[¹„™„· À ˆÑTÓÎï§Oá_ÿ'­žâèÝcu•WJ¤´Á8ÕGræ|)­ ¸xßš]01¬(¯6[WÕ­K­©nj k+2©$Ó0Jà¦nB¸­tj×ààSIÊ!¼Bý0š4Zµ?ÀļcÓ¸û‹ÉÉ–ªŒ7ÉKñpzˤmÊTi"ÀH‰wT&Ð;¦g `9[¤&Vâd­…Ñ&扙Ƭì¼ul5c¼×>ÚŒ;Ð!Ú¼H#3[¡t`ÆÉt×ÎNMÃM6.£’b”ÆJ—‡ÏVÒÚ¼a¾º|)9ÀQPfì}´ Uj‚˱¿|vÅP´»âlójíTt4=enÀT)Ã:GåÕláž»‹†LëXmJêgÙ¾¥/cËÀ..9ÁÛþš×u^LoF–ÞFí’-á{Á:w:‰I™ä¿E*)ʸ–p]JâI$k”#z îKxxYuS×f.êÚúÚ¨­uÉe5ѯ¬s¤ï¥W–[`V[”†ÍèàÕEDÑì ™nÅÒI^ü€¯èŠ!æËù©Y¾Éì„×åNº˜3ð‚3|T.Xü”ªÛpg­ÆifV¿Ìõu(Œdƒ'½® «ÆÉ–Ÿ‚åíoæò˜å«£ò ‹ÞžíÖc­sHHHMÑåàrê²Mf/Á²Ü?•)ûž#®—ûœ6€0Óe£O®]l2²# + e„KyEÊç¬*õ—ö‰´#‚í»”âÌ)3ƒŽLyxÛum¨\+¥\õP|¯/#Á¸r5%‡¶~PRSUƒš%Je)¤‘(ºb=S5Êõ¦"F]KY…”—åõ¾ZÎë5—|Yò€Ù7˜+Näœ#ù{mb™Õøøi„_®¼Ÿæ*§ˆg¶›šC¯Â*ˆÂ]çëw’ÐbAÄÐgñôƒÄ“—1×AɺTfd‡´½lY}u¤X“â›ÖDÚ±c2Õÿûªöµ¸û+éÒ׷ĉZÕé—1­Å9¹1‘‹¸Ô-`‘@1…‘\éé«'އ4÷v™ 0G}ÀÌ“¬gž:I¨Û—Ü´ü,ÍM—èÒçþ²í÷džӖ;÷BeöTyúV›Ìu(Oo>·¶¥„$ÀÕ[ge˜{¾¸‰0zœ{6Qun$2·±ÃŒ* eÕx׫ÅI’ÂÑBM„ïõÚ‘a–~j Þ÷•…8nI “4(Yåî*Ô6*8C'Lái a‰‘¹2Dæ¾RÔú’+iòsMJ.ä t¾äȘ]Á~iÄ‘¨ØdV?$©¤†ÊÖŒúx Q‚|Íðê’Z#&á4…L†E`5/7ö(d¢Dʼn…²k«ÍZöä’šI§M¹˜šoX×Bÿh­ƒ©šs}q̱ë•VfóåµC%ÜV'¡Z+Nùz-š®'šqÈ5©ÐÊ©ºD©·ÒlÕ]_@[ŠaØE…˜¤ì9ŽãvI¯–HÒzK1ÂLMC\K…•K®y øt]_×j]7K°Y\*Ï©B|„<¤,KõÇ®ú3èÇ4ªröi\Ê{6Ðýû¶½\ ¥äÛÌ–yê²ÝpJ.öM™ôg€ËË+Qç2ËåÿXùµb!F·\–©w¿ðl±šºðú¶­`õ*K ,½KnJð´g‘qT]6AËÊïDå䱬Hž®: ðÓï¿?^~¹6 œ×ªÄ®î¨ÉéáñÆ+4»ðȘ\õz‰`øó¡úC|D÷)·çË»Å^¥Cœ2j’U`Ê;õ;JɾÃ|µJo_6 °TÊ;æ­7=ļ«ñÕEün‰‰ƒ±;ö%ï¢nµ®Ü£„Ö¼“›úÑ#qä1ŒÂ#ñV}€0™N”ºýToB#ø>ø>ƒ?¿¡¯T½,¤jæìƒfIg5í̦»ÙD^²ÃÏ‹\ŒîQé§S£ˆâ¥•l0Ç|uêV6I¢š\«4É@]+a¥7yXÄ?ÞWºi'rØÁpíÎ,°8ð«Îë6‘~É íÞ Y ö82ËÅd’zµŸÀH(ëò4„•î]θÐ5GÕ 8ÊêÈ €e/ÊF) 9ºDÌÍq 5Æ¥‰ï~J¿h´(ów6ÜûƉAd*á?¬3Vã’vp ­ÆÈ7›¤°«6 Q<9‡ut³£†ö07–ô÷¯OI³åj»«,ÁAûßÞáaGFˆ‚oÅW¸¿è!õÇQö;7´«W)¥J@ JW¢ àZ Ñeõ3EÖ%Å ÁÜ ¤f;¼‰P6¶‡„êþ”ݧ¤š'éAo=£¨p«ìèÚꈎa «Â¥ªéP—^Ä­†Ô¦å^'ŸVHÿ¶E÷Š„ sxšè!ÍîN|“&Z|Ÿ(CÅLŒa·;m–ðuØØÅiè|N®œ’‡û{@æ/KÔ;z%¬æ‘|+æ$þ˜%û¿`;­ÉEn`  {€á×òÒ"± ØÈ¨À¶vIïpI/ËQ v[T?­Â:bVz(Ò)…YÁ'à¿¿ëBs ÚÆ¢êsK¿iªúïÒ«'}Ö³–ëI÷õ û ${T=ëÓ>hÙ>èÞrjºGåÝ£FïƒöïQ%øAQøM{ø¨Qü g|Ô>>ª$?(*?¨/ušOšÎGýç³RôƒªôƒõQ«zKZëoS¬à8‘±ÏJ"×»ãtØ¥zD?Ð?À:ýÙWú7x‰F’Z!Œ&²Iv¬ ”âat? ZdxáÏ)SÄ8UcºÏÜI1{ÉuP¯Íܼ" J²7Éhû·BhsyÁô¸À^º®É—¼< ]†¢XÚÊæ.¹vÅ”vöi°ªù} ó<—¾ÛÚ£ x”Òæµ¹Ê§•«-»i*ˆk3“1µl!‹•Ãx znY,7†¾³™½ZÐ\ªQÆ‹FÖsÍèŽP¥x² h"‚1‹32_>ît 83:ÍÅPX6RVµyû«+­ÖO»ž«,îEv¤ZÍ-…hfꬮ(W%`\Î?6cÈ+Xa×$ÇçÆÎ’åÿL©o7†ô$€êL4SwØTBÄ$H‰ê O¨zìRÝ8@#a\v­WÔsÙï.Ôcs¬ f¿ôº6ç*ñWî(V,PüWi¶|©¦ì!-emmõ ‰L,¡-ª©rñ×J8/n€x×\’Ź˜?¸2¨°ˆÚvI"1•_Åü³ ³9ÇvHݘ„ÓÚ1]è\¿}_ï©ä>+»ó‹É`xj<¢ùõn[ùüž_«É’É®0l[Cí&Oª%Î*| ¡Mš3 `¬RÎä®·T2Þ뺵+$³*¬k¿!3ég³ÕkéÀg•CN¢š!W·4»ÝÀ88@Ðák÷~;ß´Ê—®%áFBìnÀf¢Á–éÀ¨À4EiÜ£õæé£OOw@›N@M,sÓ&T\çÎ1}‰ªÊRft2ce[…o|ºu•Ð=ŸCx%øx].*¦d¼¿„¡\@-qLÈuìDz`Bô¿ì§‚M5ìÚËfœ £D­Š2™E u¢k Æ[±¢:Oã÷ø‡¼?Ç @þjÅqGÈb^ÂèÖ²µž§øÄ0.9V9ôÞëV™Í¡ÈS£zúxä݃£#ñàt”£+óàö]¤“3ut»ž´£+÷àö½9ˆGGòpä¥dÿTb êZTá'{0~>ÑÓêóa‰}üò¸ ÷§%þK|ºþ\{ì“âÎÑú¦F_$XŽXµW‹ótSZÍÀzøFÞ\ÿ÷ùã—Çþ¸=¼m%ß´•ðHË,CHû<)Çëâ›…cæF/5N”àÑ«UãñÏÙØÞÅ}VÒ4³gBÝ0mïI_6s3àYÉú.ÅiY ÈJànú2õ¹"ƒá ÈjX]þ}À¡÷5y©N ¶>r£Èê.ŸPnºWXqS”æ€Æ;Ù¨˜§öÕ|{Q}ÌZ:­ÅµE®$ß§ð7í¬5¿!΄áníÑåój × Hîˆá'°Ã×\Ä ?ñµ »E¢-G¿7ꘗ2bóšACåÐX8žØ(<,­#š¿ÏÀ ­ñ†•p´F|¨´xúÁ`]%`M Y+KX¡ ˜¡|¦5o-ü±ÎùZâYqÀ`<à5ÎÐŽwÈ-òßœó/j#U•ЪrlÖ;£ªZGyÏ ”}Þ QTB´Ör®Ùp„—uñc,x5Ñ/ åÝç® ’ƒeêdž'5ªFfzÞhd¿Rt8–'Ž…Œ2cÿvD}üòè¯=»ÃÎûk»ôq?ÿ¼÷ÿà9¦-mÚ”]…W>®ÝLÅ1†É{ê|Ó#CƒÕ$DŒ”C0Bð?uÊOäóÙýù”›åwÿƒæå˜‡ÚB¾Y:©›údœbR[Aµ·§·Ñ=8PHaw`š¢z1ÆèÂY"'˜Í4qßÄÔûV¸Ëå~W“‹áÈtëâ×nú)dyoŽÐ[Ðô>Ó`ˆhö,Ýî§üusŸ)KcãWC­ùtÆýÚyx<9O§ìNFdàk´›'Çf†_Õ îþ¦+Š p5#3i%àßïSðÏ"ªö~Ø}üò+ãñ}B6¾£ xÉ'h¥ÀØõÓßSe§†¦Œ”9qo÷K´»T]¬/× IV1€`'m }€Íoòýp­‘ìyðÞû·ŽÜ4»wú|?ôè~è4þЕü¡ƒù©Õù¹)ú¡ú±ÓúSSöCÿöc§÷Ç®ð‡òÇ^ó}é=ìÝîg,uJ›ù ¨EJ3Œ,É[½Ñ ‘¬ø;»ß, rÞÙÍ(@þ¾±ÓiJÏöºÌrY ׸RŒx†°¡ß-Ž\<Áž+/–,Wì`öº8¸&Y]âjŠÕž50¿ìj@¹ë’`û°„q_€µÅJŽÞ"ñ¶Ãrר.I¾ØÚâÆr9êTë(K˜›>ñFCY×.C^H©ÛßCÅZJúç!~¾-6Âu¦XeŸV´:…™Šõ0{Cü95‘¾¹ôqÿ´œv‹7ßþƒföÐ3søö<çad3Ð:µü H:bè¿Ba¾L'G|ý5tçzBŒÑ¥x5ê M=¿ÊxƒêN¸Ó嘋Äi0*Öiŵt>i[˜áQ Žf·e ðŠ^e®Ü™f ä»rÏPð#jü€/Ä¢"±‡˜í-¾;"¡»ÚZØF,(4©ä@ôQÚ'Ž´Bì믉¿…b’²GùÙìùEGÞQQÒò)‹ˆqv»À•… Ù7WmaY?XF·Ç¥ Iݸ³}©Û.™êx‰÷ Æñ-…úH Lãû$žfºÅ"¡dÜÍŠsÈ7Ѱ=šÀLíE–³ŒÜð`~“¨óaË–YÙíBÏ!ÄÝ@îë3˜î »û ×½Ì8]?MŒ—A2ý o!=6Ó̾;«) ídñ½OÝ)Ðg Á3)ðÂ=Њ£€;&ó`+A·„˜´Ìh¹GÚ¨ Kv‹$ùa;¥RLbß´VŠŸ¦–øwÐ=S€tT"3äxYÜõÞáôœ+D ›sŽ>h–{W¡e²R¯`ƒû^KÎQ¹RÜ&‹&QòÜŒëàp3›Ôc·ÁÛÎ1À¼9òb¾ÙºñÚ±ßáðœÃIôŠ-q÷A3ó&Õ˜¯&C.¿hz¸¯&X.ݱEöGôõ• ì“L )È0Ê_¥$§€KR+Ê¡GfHÕò+5–ÃpD¹ÿ} Ðåzc_]ÉÝ»ì™X˜o+èJ—‚ªŽæiŒþ; ¾YnÃM[¼S¸Bô¸«Rµ ]2˜¥mwû)èÓ'®ýIµd Q½ˆ¡'5U‡™µT ö¹ í,Ž€j~0þ®¶Äþ ßxÄÙ€^¯þác§¢ì¬Ã„MUÀò±‚><âúj"ÿl›lì “/P7†07<„iìǨ¶ÚÕ…£ÊÛ»µ}‚YzÑ ØíaÝahÞОs(Z­)î>`7XýÇS%cqpÎhÀÑvGs¼Aö¹ƒ:ô/£„kœØèSKo½:µÿWÐ-"}åµÚ¬yh “@§X¯%,ñ˜_:>,/{«×Öñ#>}é+f.9JèCsLG—íWõ–˜‰ „·ìeœÄ5d¹Slý»¥â5a3•÷–Æ4îj† aNj–9­›£"øòÚ.u’º¥Í¹,L†„ÂÞW¼Ókw͆ysø™ GjØ9‚f´]©$µùÃÌ ö°PjŸÌªéK»¼Ñ(\d!b|QO™µ±Ì E·[Àîßå¼ÇEeXE—­Õ,!Å5h{‘PµfZ«Ò‡ Åß%Ø‘)Öm«ZáV4®¶q½oV cKêF/pïÜqQOÇbš|IlÔcg¢`Õnfñ¾O°ëŸ!³´¶Xj«P½«?žñΉÃ}ÃìÚ]žñ½G$ð#jxx]ÓTÝ#Y3Ú±„êªá®‹¤1l£ü¶ï ˼;ø¸º¦ $ÁŽÄXwpýð¼”›Ó”*ÃCˈ6AÇyÞá»R²Þ:¹Œ8Vö5%£.Éü+ÂÛ·—pÊ!¿åÊ?hfn yõÎlýÐ^…D51Àðõæôµ©­ÅWS'JĦ´Ð;AîY4©Ì‚ LšJu÷¼sÀÜ–€· nñj€~K2¾å€-_|Ì,Ÿ²ÐÓÅ©½ @æ:¡¼¦¨‹÷±^ðT[8V!~®X¼¥±ï€%„bùl•Ÿ/$´QknÈkãÿzÍ%j ÐeBÒ› wѪ™WG)¬“lÖQbë(Æõ Üuùz;J‡TÆäÈŽÒe2gA´gñ´w¡µ“$Ûƒ|ÛYêí ÷ ÷ 4w”¤{¯;HÝEñôÎb{GY¾ ¿£ÜßQð,"xÈ>HÅ„¢‹GyÆ£”ãQöñ(ù &ù þQñ®¾X«K'ñTéhîkœ/ìxÅw`ˆ—áO ’3ÜäQøì(’v”S{^pWUÛFY‘˜Ï×3Üàë34ábx<0Sd‚‚B‘±ã %7"6Cµ›BýÔ¥Ö¾— È0²ªl%ïpÝvÅaì™ÃªY»mq‰×JÖ÷œsò!?oð ß>«x@Ë †¥¯2E©rß|K['ðŸ ð‡3Æ™ÎpkÚl)š¡m¸\Dï#mb$Uúq»7k’”½)®üÙtMÃ"cȼXº3ÎKB–ÚãH!eýX%C½õ‡-xÔÙ²{¤3’§ Ý8BÛ˜„‚¾\!œN?Þa2áo.bg³b³Ý¤Ü¯TÛbÒXÛ3ìl½løèPIo0y»H«Ër[‘"¸\~yØüN›äÆzÞz[ôq;O·…Gª™i•Îö)-hÒ€Mo7bŸÃÖ!lWSPøiñ¤¾Q¡êR”V´&”þûUt|Xt¨Ë!2'\É*X‹…•~] ?‹Õ\qÞ$8… ‘ >äD—&ÐRƒ>ÀsÔœ!§mŒK`Aƒ˜”ïpµ6 Ò ¸ ½”8.j™zI”_Îmt°H‰Ð±Ñ…%N–ºº¹?…À–„4ªÄVEÀl”XŽä¦qè6ˆõ*zæH#zÄiçwÛØ0ËôøÄ ÀNì´UÓ2•²·Ÿº!~¤í³EY“ôwÈÛ1tDpH˜¥|Ó;ê5õ°:±0[*B+-çuû}v¸7$éˆÓ«Aàs3iÂ&àDdß—©´½êwUçMF7V”ö©c.‘Â`¤<µ•ž.þ”Qc yjîÍøH¯_B\IÀ×¥Ò¶ 0z‰ì‡i"WS/±z¿h`hf®\Z‹Í¾úM;Iö)Á)éá!À9ð¾Îå"gì4¿$Ý6s×I–søáàÆìmZëØ2>ÉeŠ©I\^ÎK ÞGh¶›TH¸§PL™6ê&Á#íPŠ›¬ÆÏážC‘â¥c«RìÙR^Ô^ZW`Í–ÄŸ'w½á"`nñÃó²~Üe£Dž–«L5ú€ãàiTþž¸ÿÁóŒHíûµÑÆíôÿäà?„çxá[ãsÄrˆnÞm‡ªøÎð ?d®P^Í d¿eÇ2÷Ô‚æØ®æÔØæ¡ α_Ω¯Îc Vž+Á n´âº?ýˆ•ÔÖ›YHg3‡°á> Fô§˜çh7¤bº<‡ä‰Ä‚ãCé“'ötÏõ« uÖ®˜Ïú}ùMMèkPÊ !Ku·)ɸGÌà_ø€D|@-ŽG,ä#nr»˜b¤Yt8^T·l¼„ð9 #›ŠœÂbÔª–¬@jWr¸öç#¾ä MÜøú8о,¯¦]H=k[2å+è\EÒß8/ˆ'»ªz'˜+4h[ÔAûÈDÿ2íSÅó«‹‚kcz«ôkH¶Ã´xëÆÎE@1$S¥¨3¥ãvM¥¸pÿ[°@KÄ’a‚¶ÔPÞ·NoÎå±}IÂlõrâ>œM†•‡ÍtÍëÒÙlwt«ËŠŽpC;ï^†˜¯”né<´Å#"TŠm幈ۚí¥( ÅSq¡a¿Ö“¤èá—Ãï&ãeìYk%N‹×Ç'>®‰~V9¾jžæí†ÀAiF ö+4ò¥u‰@i«ž¦©ïÑXñRG ccÚ•¯  Hã’2¸Ij†o‰ùŠKG”ô ÅêõwœÌ·v‹ùNÓÕ!*¡¨•±EÚpD¦OŠÒã&u’†zQÕÝ,>õ€ßvZR$µÞÀa©"n_ á‹«Ü/H§ª.!8îcþ°˜7QþLEHT†u¥uݽý€ %î&3™ŠÚÔÔ áÍæ[>ÀN2TCÝÑV$²&d“u¡œRZ‰ZWŠž£ÖlÈ…6_7«¶† å»²¿‚“nòQaù]ù·‘4Ù‘Å–•¤92í¸z´¸­^áñºZaÂ\¹çuw9hôÊòÕCVµn<ö×^$£Â~Øk £—–¡qîÐOÐrȤDsn+KZøÔuµ®KbÞŽ=fD C Ïwm%å×ýV|Tù×ýÞ–0Ø uD nÂ%gVÅücu$C¼|(¯U‡æÛÇ”š€h €ä°ºaž¦=No¶ß-òBŒqlGë©GwT.†Ô­· ~êrðƒOnnËk¾æèQÝ ‹½´²Pñi÷Þ½Ê!üf(N¥ed(÷•½Abå–Þö8'Àh¶¿òhæÖn.BøŽñ–ÜUeAˆ«£RÝFM´Jâ¥þ>ÇûW¸Ðr´l¬—·Þó÷n_Í”ö4A—4ß’Pì«{P~>•ë-'r %·›3 ¯ÚmIn‹UÄÝØzäZ®µ5BI¹1D4.^U0“Àùê"£m·“th‹å¸uGâäíN¯³u™Ópñfð0LýTq‰ögè¤2È †*UÙ×Òrsr\Jºåü:ö¿Vó…çr€BI!°5=êðüT,ÓÍ4!æ,Гƒ£™2S GhsS•ÍKµ…N(T©7â]ï1@ >ëý—KsWœ%¿Úg—º[‰ÞhÒT…ï¢ùj·„ee`œ[Šƒ úÊ—¼G&‰MNÓñ¿Vé’ëÕ6tï)\–Øl–+ÒL&y 70ºQ¯ÿ—½w]Ž+¹ÎDŸ€ï€?Š°ç ¨÷Lwœe;‚÷ߨx 0LXO0ä" ’Æù +©ƒ”‰arÅ c”®±’Ú±–2LYI.qqž>1ç¨è°¤ÑWvºJèºqGÙø'xî£T0¤ùAµ…qfïãÃï©/¼ꆤ”_‹szg);é;‹d'éF¥øSÔè.Ó|Ë7ù9§Oa…8AgsI\VÆB.nAÀ¢Üˆ»ùWøý Uk˜Ôµ’6L¦•­¤ ­¤« Û†IpĹµÔºqÞ0eo˜Ü·’¨p)æ£uˆ¨À2²>ƒ”}¥DD$T{ùpÒ@]=+ö¨2;8ie¡´¬ZiŽbüî3b²}D¤ºdäöÁ±Ý¤Î¾¢VådóZ¥ NÐì&¡brè® ÈÉ/Þô߆]ÅÅÏ#<Õ­”uu²)œPÝ86s •i@gÇh ¶Z1)Ut`ݨ8ÍiÈ3œ8Q³ ã ^S^쥑áëOºCB‡„Q=¢‹yØèNƒ3–Ä) ‹)©ì¼XN\#‡ti/ª æHO.¢zð€Y(Xy£Ýñ&i'«öFÅà Üa®î0¯w˜¼’-¼›W<Ì@ç*¯ä53 ‡™ÒkYÕ£ ìa®öJ^÷nø0O|%§©ó­ÉLeà”Â)M‰^jÞ·…ÉIS%Û~&`¶‚†Œu§”N” äÄ™ïÂkB¥è2kvðè*– ¨7&øOè'‚üÁ2XzáÔ%èñ æf™9»$Ó=±ÈÕ$†Šì¡"5ÉݪZ•ÄZEœ2¢Âd Àši–…4áü=Ķâ!¯ñjšÕ0%k7yk=ÑKÂazj’Ô3à¡ 7a–­xœKÊG1(D¨z<Èh|‰Ì¬bW;Än¸I§ÅW8îí4U-¡ÆÌÎ7ÁÉ=¢ÜÄC1“D"óÌ2› .˜ iÁøzÁæ¶Àq§Í$nÀßĉ#Áþ}kîAîù:™î˜vwLÑ« g Jõ/î•ø^‰öXþˆS!—™ë¬ðþ`-‹Α üÑúiΫp…GzÀ9=d§^ÏŠePs-‡y™v"±¢qé‚ô`XõñÎ*±÷î`ïoT\ ê`kÍH®dϪÕCÐy”Áš„@Š{I$ÃúMS¦Iº³Åì”äÐ ´AõicIÔŠØ¢öiFi õÉ•1è=ÈùÙ`Õˆ#ç'Ä_DÁ|ð} ’¡éGÀû vy4V%)ª©v>ÊFyÃŒ„µì…•L‡ANÄJþÄ0×b˜•1ÈàØ¥UM€}°’µbeL0½´% 5pÂYÄù½„š+䛚ÎJÏ!ýç(t5E`˜N0Ê;¦(dC§·™.:/Ò÷Ôãøž$‰ABÅ0õb5M£ë":38™ ˃P§pç#ŽàÉ;ì³7*ŽÂ¾‘œ¡ø»,ÝNX­EÈ(×jõ?†­|…Ó“³Îälš©GB#ažRäÇVZ?U×6D*[i )Œc^ƒRA×›8i wLz@b! !LÆRW¡‘ÐižYÊÐèŸÀЦ¹3À§Zeõ\ŽAÞÇJ†È0›dÈ<äpï²ÏzDÏÁ†z£bP,„A™Sꑦ/©˜-,>ɵ¨oøªÀG«ÞÖŒ$¿%ár–ÍodZZpçDñ°MHš=~>¤n=_gyòÁ®àÀ˜ñ¸|‡>ĬÑí+Hø!j~ˆ¯_Áâ¯àö‡ÿ•l”ökV ²yð6 «h´Ôvx†oT-Gš© 'ñkœ31Øš,F¡7Mv{8Ié¡N`""Òpt ¨·Cd,¹äéü¤N/ů{óåû7 ÷vq;)Œžø˜èèF§Â"g,›©=%#duF9I OMïjò«sÆ“ÎF9°¥ºÈ Êÿ2ÍN÷ L/Sµ+m šhõ8à ¥©-`5U·S3œk097à–_FÑö]¦”@ì¼”…›]êÞß;ñŨ²)Î#çPpÖ@¯ŒJÌ~© 4%juÒ•s†ú‚Ôߥ«›s§8ó¥þÈ䌃ÐYЛPm4‚‰>Î\¨—U…3#z×ä ¬,‘ ZoºlKÃA]b yÙ˜ü$kOž4¨ ÁмÙ„W?ÁÕ,CÒªA™ÈêýæÍ{d’Qÿœ«Ð$ihòóe’u-pûb»½¡E”ÀXP3º ™O߀,³_XÝPØb2ªGÕ5ùûû²½VW#ØJé:PÍÂÃ5D:ØÆˆ‡3o•úœ!") Uƒéªœ¬ÎØ€ùÓ ò‹¹"„Šƒ1¦-WÛÍT¬TU»@ý£`ß™Õ~œUhFüå É&Ó8É7Üu¡Ù¢ò k'D¦çEÅ= ü“ÅÞ8°w.€= >LHŸfÀž3î’d5GgªãÉ8Ü(,?;•o .7„Ö Ax«€½¸o\… à…C â*hqpB!Wa“ˆåŒ9nAžc8è tt3RÇØÕ˜ë»žm‡Üøîê;¯ˆ‡`ã,y¼w£G ê!àz Í^q!ßCpø |:_§¯@Ù‡°÷@~L?Þ!úÀ×ù*6l"[œq9„JfN]L´ç+)dÃl³AVÚjþÚn®Û0+n%n˜k7ÌÊ[Éàfû óWr‡ù†ÃÌÄ•,Æ•ŒÇÌÈ•ÊQ¾å03s-‹s˜ñ9N ]É"ÝM8f¦®d±3^G©±+Y´£„ÛafîJï0ãw˜¼’G<Ì9d'¯d2¯d=ó£Ws©‡õj•mUpvbÕœ¦ÊþÞœ„ª§lèlêëœæGB,N35|’2C2OÅ@ÓlƒcÔ‹bîª0¡æ²(e0«uF∀«3Ú ÊK 啪ˆÄ ðœéª§ œ;S±d"^Ÿ£(É”Í+™ DBqŒ$õŽfp4ˤy »nT\Š”@¿s¤9`$lê&ìgŽ"5ô²Y‘.–ÏéôH prˆñ àB³>ÙÏʾ ð,§&¤šõ¼5„Á8]C4‚©â&ä¡ÍÔ2ój „d­Ò—°í½3îÿ4£Ý½3nÁd' ›rEWªÆÐ½•‹~µå½º^,I:jUŠˆ“Ì{X˜5?د'õY‡ç€Å;P¯L y@“à­´0ú%®=«šWÔoágžhÕevgo0ÅÞÂ…ÔI:lêW„â…¾/Ò»)÷eB´¾5©,3Š„7Ô‚Cl3YÅ+FËB³ÁøÏè] _©‚)Ðn4ÿ‚1ÜbjÐ&@µªqÆ“Øt¡x¨7²$$ÍïLÁ¨¶•·‡’@o`Д¢s Eô†«ˆçìB¨AFÂ"rÊLóÓ'as·G6ŽV6 K{h¹»1 h´´t®¨c`w£QF$ùЖ±áÈòTN´™ÀŸ+¾£ä<ÊоX-›äæL)Ì»U‡gÓժǡ< —Ã8¹¶+L×$ô ¨‘#Â,àpêAÊ0ˆ·†0Â;¤ÁÐC“ƪpÿê8¹´¥CÊ rÑjõ WŽ8Ù£ÈÝd—WÃZ”앃¦Ñ–½ÚíM.V9–ͬˆ Ö%}%uI‘I×€|ÓôšÝŒ¬ÑN º€×Q„TC×ÍÜ69¡ÀX²p0 •C‹ø@.È5€ê¤ X!%< , `ŒT7XX¸ZŸ¯’bþÔ¬‰,´’MiAÇ=W” J® (ñ´Ú½U|XÃ)øÉ.N)ÔÞåŸ2U­“Z$Ç!BJ*­S¨~ÐÁ8%á ÿACÄ€ŒÌÝì*lþѵ’¤CÜ%.»Qqµ|Ç \ÕX˜Oò7$ž1A,‚u0Š8 $X§+!Øá«ñÆalrÅ\‰x–Eþ¡²–q6=’ìÅøžÌûQ’þ0›%ó?Wd.9ÄXXJcup„Ù€áÖm5Î&Œ¬$äÕNñ˜æàEAõ'±²'Tg‰†Ir…ε®ç¤ô L4p×ÌÐd$Ö #, 7Q|ÎuÝænHˆ7 Ïû»y—äK}—pH¸N38¤$®ÇWéƒûÊvn­á&n×Á¾k,‡kŒˆ#îÄžÅËÜÖ–Çxc…¢cHç1¤þ‘„¬ŠŒÉG†4%;”&hik¦Â‘üÁ ™Ô-l/•& ‘ù¬›]íUfÏs8@Uºr¬¬@£³jç\ÕðÝdŽA ßÉÌŽf…ºfHs3$ÄY!Ïí¬Pò é{йë’QݶŒ´j@lîyήÁ»Ãu£Á׫Ôj…«jÈk5dÀ“ehµ†ü[+\]C^¯Ø [™ü3 \¼ŸLç±IV/â+Y ̽PW‚ÏØÒˆÀ[:É”}ÊUÃR­ÕXiSÀ’(FL†Å“€!!¶C’t%x›QA8Yf¹ Õ1ßuWˆ4í†È”2ÊÊ8ÆÚ)ÊvRLÜhÁ sÉØ€“¤t]ê ÐôkЇ–…Kz•llHL6¤0Ðíúvòðo4.3ÈÙf÷ &€nîRFܨøÑ)#†v`ØÙá°¬£Òß['(ý=$CЦ¬$zS üjô{e±§#BíéÃÊÏjÿ R¤‘¡Ý¤Ò0ÝLÈ$Ó´4x²RŬSÁéÊö…å¦YìÍñ°J´¶ÛZm°q±A½±•Úd+ŭÏVª£ SmG9¹ÃôÝb¹Ž\å•kÅØ•¥ée‰#Jz ç°ÈŸFqô,„×"|Ö²$ôdÉl—ßtb‚j§‘Ê–ŽÐá¬ÀŸaéXÙ±‚דÞgóo‘0£¸_©4wF’¥efÂrá~ñêÕͤ—Cå@©foyÙI0/ø}tÍ¢˜=½«÷#Õ\Hú\˜æ Ài¥¸¯L“)³Ð£j{Eq"®.À©Q,l%mH¿«4£esõð a³E\äVb±‚9Y8¡·ÊlÏ)øBEíêzÓUœ¬œ"—fƒvƧŠàH3 –·Œ¦Y$˜!$ÔÀõ@@ª¼á<¨6X-A^c ´ÑI$²Éª €©‚vwÀÄ0CN”çˆÅIVŒ=Î1¦^5 ‘!ÙȈ˜dHb²Bw2bF’¨¬Ð­ ©YVh\„/«„#nŠ!‰Åáŧ ÁÙYk œ®ËÁ ^Yí+;c¸‡†û-ۉŶÙ[}¾wµwÆ` öÛˆ™cëj¸Ñqj*v´ò"ti޼ Š[\£–ÑP +ÖÉ-UV‡õXWj·ë¼+ÂîT}¡îúh5ÔĬ\Wz.o vƒH•|Öú¤`<{ÉcÔ-)üFÆ‹^ðï¹]v.¢áµr»­Ü„Ã;så~ݽ‹‡·öÚ ?V†ZÃPÃj#C½e ãü¼ŠèîWFTg¸"†kg¸Î†·Ë¯TGVRÖ\—gÖjòûjå›÷.S& —Œæ]F”¨ìHªOm…:‚òR徑/L z Iºtõ(v/+éU­¡ªÓ g@¹Z6 (‚_äÄVä¾$=³¥ó±_Uɳ7 PP„¨ô‘‘DÞA®éhßÈ¥ŒL3Š)Þ5æèœø—ßî8ož­ÎÉpöVg: c ‰Q6¼è)£TÌÚD çteöw¾Ôž|ACN”1{Ê ÓÊ•eDß²ÊôòÁjñyú½ùQ‘ Cù½§+tМ™ä4-áIB…'®l©µí7ܨ£M=<ÖŽŠñ©2¬?¬$ÿ0YMä  ŠKÃÝV X"ˆ‰ Æù{3FÔ#Ž"3ÓÈ~*ÆÍ@¬F ÐYa52 ­p%­ð*Æ+_?UEóÑo jgî»qw/ܨXÓ¿i!DðdR·,£ÄEž2ÇHåv‰âo‘ÍìôsDAËfvøý¶É<7̼¦3l¹’ðP¬%UOH©æ$¢O¤éG“ñ“R‘À ÆÛù:óÔKÕˆÎjÌ|5\Oƒ•·Ê3ä•2Ь°Õ¨Ê‹[ iIÎ2x8žŒrtœ/ˆª%ND9õ ‡pöªXš1ÏRºßL·Ó ’_¬;•…r.Ã]Â^Dcr ¡!åaŬ̞.ù€ÓTŠªx*F8S)“]óAè8•÷ƒWSã)1zD‘ªGj\Ôºo:€Éê“Yÿ}2‹Ý@¸u’X¨ˆq£5€›ø2.ø‚ÅÂ=U‹U’UD³Œ¸šâ=U©Hiµjº0ðê%-ü ;Ĥ³Õ+a ‘N­S­Y )¯Vè±vwÖp®n×ÁΫ§ÅðdžA;çÕÏ{«ÐQðrä"hÝŠQ§µ È0BiàøFÑ‘óµHÊ(ä²JûCØ;$ö]%©…G4ÄCÊâ1¹ñ ²[D[ÙM&Bg³Íl"ä#»r]¥ºèA pïN“’¯ÎªD%ÍÊN¥¨=°Âê<2+¡Ç=M¢2GÁIÉdWWô0×'•U5ð½¡ïÕ „š­M¡Ed÷°5 ~™r>ÐÊÀF‹âhaÒx»V²–’åoÎnGŠ+AI´<¤Ýu< ÃžDìFìot’y’"Í“$ã™ìˆy™þ NeÐÀ%C)1k»lepTL;Ñe9%LôÂÝtÎ$\}cŠª¼ ÷š@©é}…3ZL1Ê&ú2ËU*D œ'ź3ìœ+oVgŠ‘P¨R•Îê“ÂÂ]2Ò*·È‰¬ya—C,òœ©‘JÖ5Ô(Íä’ÑìÍÅ *¬ýŸÿo:å—Î%¯õY'8ÆhH!ÚjNAgæsfåш0¶ ªÉl3=9eAJ ¶\žéó1…Ïù*ÛÏhH!4. =¬½E¸%30âæ’xí~ÉïWÊj p‹uO†um‚’Çä—<+š”1à<ãã]‘2”ÉŠˆ'ä¥;…z®U<GVQ_©¸>*Î>¬â¾SñŸܰ¼Çuû(¿ UW?¹{›¥àÇŒŸW£¤ÌŒlJõhÐý¯$bLè ¥€]HØÀ½3àa(ÖÀdÜ jëó `œ%Œ ’² ¶E[Òz‰}Sú¬ÚVÌP˜a)cŒˆgÎiÆñyU?\apÌ›À×L˜4Ìà0çÂѰ¬šV!2ëy9 ïÙ =F5—“4;Ð!: a’,'_.G¼Ê²V s˜KaW$Ôl\î+gÃüSpï3;¢‘sp‘ëˆEWçã CäLV%zm¦Vž¶ºÕƒOº‹*¼ìÏP>ý\ó®£m›ýF¥C²ô!­úÏNÁþ Pæ»TÉâtB Q%ZRï(9!dÖMñê—€A 'øEUÁ‘Å4ÍÅBžS’|7Ñ˸n¨T¦…ëÀèÑ…zDp¸.#/¸RÒx¢·šú2h0%YÖˆ Ütƒ²žhàÀ²ž |7Œ‚lÈWr\êö*"-Žñ× W bÖM¹±§™Þ-¡;¥{©•©õB¿"­U°x%¦•tŒD<*‹®4@|EóËÝà"·ÄTV¡Í»xË\­à-W*öjûns8°CdîaH ±RµhPáh¥ÒJݤa¥a5¦•ÊMÑæT¹19'Ô2ð_S€§¨¯Õ™£_Úˆ-+/ñEe˜á°Fàæ]ÈéN™³J¢Š§­Ze–o[)õ6, 7, ·RlnX˜nXÂn¥Üݰ4Þ°ˆÞªÃcàºQ¦*ž…6y"Ð<ʺIBå’iAYƒa¼²eHèB³Äª UøjC@š½­ø ^é@³ðä‹uXç>›É€¿Ñò ±ŠÓ¯LÞ$Ôt~vºD0(í™…m2 V§= À¨`ßÞëa¿•R?YÀ]|Ò úwXLiXtiXžÉðÈ#¯ñ®Ü”¬‹t û;Ä Å+èã!Ryˆi~1w>‚å$ýñ°¼÷<»WªŸ}³iFu 4¿çÑa£Û‘îåÿóÙtFÚøÙÄÿùÓOÏøÿ{õ,/ØüâWÿV¿ùç7¯~}÷îí÷¸¸¿¿º{#Â__ýùú͆øþóÍ›‹›«Wg,=Sñ?öFÕÿû§¿ö¦ÿLgnÙƒÿÑÿø?]ô׳xöÛ³ÿýÿMg¯èégG?}mJX­3 sšE/—"'1Ä—óïv%øÙîÆïéƒ72”èƒÓÿe˜Éþ#IÁäÄNbg…XNú‡ZNÚ ÐBôSõ â¦Àúªy‚ôˆ_ZxÙ¿Ú9§/«RCÁ=cîƒðƒÕK´ö¥Š'Iâ7j)„.T¾ÂªF‚´ËL«d–‰_ú…¾.¦„ú&¸Sî°$’Q«™e¡>IþÁu×:µ¿zÿq«‘j ëOÚWc$qš2ÚsYõVâ3»Y1 \Ö¸l@4{‡*7!/œ lÃs+Ñ>ЇUíSŽoA²×ÉafU|‹þPÓùu:=ôz¬<Åôä4éØ ¨ƒX“ö£iŽ!-ÓÂjk  >ôà…u-×0ÃHH® · =ß*Ò¼CM™ÝàO`ÙþœYŠšÑRžª-²­wa~H•ö oSÖ!['¢óH*eRlŠ Ê±|»v¤0ÿí‘ Òó®)â÷5Ƴa0=™ŒxúFÅJëHã‹–Ú/îÂ:;ÀßÓ1){Ä3ÑÆ? ¡¬Ž]Éy’ýÞ ¿=­õlÒ£R¶¥ªó\F¦¬q´rªQ™“AU,%’X&†#qÈaqˈy#e©hªaà æ…™-Á£ämE €w!©‹ÚÛ¬{(ØÕÙûZÁBU/ldâìãG†… d `Õ¡7º˜Äš6FbU’СWXQ4µa#¡E*¨‡Diñ€‚èù*–$vvß™|3@NH<_ßSSnˆ¥V bŽÞj›¢ }´!Da³Ñ­ «ú ©×´4:Þ‚œÚrbÌ_|kÑÌ+µ™ºÃXMNJÕ,žÅ²™°l *ŠÑ³ÉȶB´P«÷RQl·èYYU`Ђ²ÔyÛI§:“—’žïýÞ5œ/-x4Eótf¡ì¼î×°ëm‹ŽE‡ýÊåå³Í¦Õ0±À"ñA´eogµ·nl½NúÁtš¡êH8Cëâ)Ø«q‘±¹½–ïÂ~p§ÅþBТ¿lC4еì¶X"Ô­å†%±¢>hIøbÏ Dx^QÜ×}Ì'Bñ[ :à)B½R, S´èšðfB×É4ÂèìÙasÌÁ(ͤWYĤ1,]©±¤ÉãÊ3’ÞÔo`(g¾w,Qì(Áê|ê”­[àŽ%hXTMw®GKuQ*´b‹½Mˆ˜ÓZê[MYŒåA_qjRdÒGq¥( ŽüÕw”ÄH‰Öç-튵¨ù‹ôk¥ kÄu6™i^T6_÷òÂïµÆë¶Rί¥_¡zÐ$SÑW¡ ×$JÕŽ;ÚcÂíPQþˆýš²Ü‘~Ê Ìû ›Žhq•hMâT ‚oÁá¡ä‘ ³µ%±ÓêÒ2¢'­[ÝDJÖ@n#Œ ¡‰G€’HÞt‚ $Ö¬X®:[ôM¥àkiº U_wÂÉ„ßs¬‰Åw)Õ!ºRbã’è #öp £0?Û9B“% «¡þ­! MÓ³a¾“ܶrh%[íZyGÚ­ ˜ØyY‰Ÿ‹© ¨zŽ…N¬V¥%™­‚¨™@“£=HU˜ü¢³l0¼Tq_PIÐ/u,dÆö¶fý"íŒØ¾MMæu [ endstream endobj 77 0 obj <>stream ~òÐ~Œ<¤Ã‹$>“ÚÚ€rHG{Ö =‡ž.i¦©õˆÀ‘ØCël)â$Šfä¹¹ÕùÂc” Ð8=«Ù[Ôªº¢è’@£‹ÉªVH)¢l–’5PÅw°Ùú±¸Oæ*<¬oèlI8‹[†Ÿ0N¨"CˆûœÝòRÏø¥‹Í;·í&»çÊÂÖ™ƒÀ|Ëä CñÙì˙մ7]õàÓ¡—%3sƒä;ÑÕÓʦ=˘‰TM¨š*tè «Vh"Þs‡Y0Úð* ¢Œ«eg ”;W¤,Ä´©´ ¨!;]»xÂØ¢³¡Å¬ ƒ^™„Îëxh¶o¹(V$GU„@ss G ‡…14§ÇI$ϺԒ~ÃÉ}Hò¯Y¤^¯Œ»¹¬A`$í’.4™C9—èÙ ³Sɯ×'=‰ÇÏÎ ÄNuÔFH[èÕW´–$‘÷M¥#-üyê^c¡¤U­¿öbܯ—Úáhg±xÀŠ›ÉS¯wD4÷†ƒÍúžÓOU½q6áîuVÞh·˜JÊ¿€k ›yÕUì½­æ‚Òg'¸ò|ÍÄ€ã)Ùu”SзEEÃLzzi_'\r[¯Ÿ÷•&ÜcýbñÁ2s{} •¹à”çÕùr܈~—\)ʘW:—Ï^)‹Aö±ÀI`—â;ÊŽæ¢m³°y(ÞTÈm‚KÅlœ‚¬äüÕ4BAòÌqEÉ7¥6'÷;©0<GžaøEÕóGœqÞcµâfsÆvÊ6”nqH#〗vÌ™¢K>bɹ ¢ÅËâŽúÕSE Ž‘00& ã&kÀK«hŸ—”¥s­¦b¡1E2¹¥'oNs?öº·H§}©ÒÙ Ì'úìÍ´r²P<ÁL†LÎÞAÅ1ѯ·ô cgýäܤéb°Óšy ¼å‘°˜ÕmÕpæÚpwˆ°z(äSž0'“éÑ'äò£˜õ +[8 t§š_ °ûJ:@§.&µ˜Óˈ'±Ù¤ e'£bÎ%¾+í[eØÐÆÜ8Y|J_¦Ë¢@ã"#X-³Fmn^Æ66°tê8——é“(Äb€‡J:Nq U%£É¥ÓJÄ\Ÿ*l|¿8Ä4u…¶§&úÒ, ²0ïÚÙ— ʰˆO/Ê៧ 0bK˜’öÐAKg<—EÂMÉç…A™]x/6ô TœGÈ¥– Ö);\Ѓè1ê¨U'ÝsÄui³5gJ¹ê„¨¼¦Ê[æä<öM¯¦b´h l‡’X'€“r_ª0LˆgÛ‰šˆÌ¢,–¢œó³ÏBc4òìì\f×:ÚåÛºT‰©¼U3wŽº=¨]/µÉ Ò)êS“wkBç¡"ÏU-H¬gD0")â05·‘}Àl1‚°$¬Íf£k¥ Î=-¯Í½šÐ¨Ô¸ªÂ#´#á„PI¤áÎå©W¶s ´¡/P¡J¬ïeöƒé¶õ8øÈ! Œí´‹VäñÀç(/l̳!&Z=;Ùµ„*e5®6\€D|k' nµD,}H…¼» (8â£øµ¦=r`Rwm[ Hð숰jhÊPCéY‹3ƒŠ£EØP˜ÀFH ²&ñÃFµB×À¼»˜*‚aÜΰU×ÄΓ‰Õb~2¢7bRj@Ÿ ’R'ø^Í¡—%ªÌ~hY7ZG’€Óó$šÑKâ_¹Se‘(˜D0J1@Ø| yþ},9M ‹…ü« %ÜUÑC•÷”H‡ÖúfˆsE“¼ùâ쀔ŠG²¼µB¹ákŠˆ#sù[Xt¡ŸoìèàG1VÔû êH>ÜàŒÕ×™«‰€O@XåÚ;¼ñ{®Ê)ê%¹A_êÄÕù¢e ¸=‚UÙø¿¨8áì­¨âBb4^z1H;XY©]6“ÚU“ YWáBcg<Úl‡œªeqágP{—…ç¢RÝóÑÏ|DXmž$\Sÿ2Öá.‚AŸ.BbÝpÙ)(›ÈÁ3´¦XBÅ‚3»å^I²"+y Gœæ¤²ÍfËÎ) #¨€Ò¯JdñF¥s„©P\饊'ót§lªâvsÛÑaù³¥ƒÆ¡À°âñ 3 U;rðãqeSû³º¯*7 ЃZáNôÒðná¿ÕQ]6MÁéú¡Íav9dLBÙ´9:5è³û*ô²eå‰,¶ b5kŸ9æ*Â9Dƒpe†(`2.÷<—Bœ;th® ‹ÕûÅQ8ÓR}SH”°†³MÈõôRÛÄ0ˆ<}*;r&«€ÖÿÊØï­©0D öªƒÂKâ í*;áBFdœ²fv'3KtËvµ탧„܈(Õë©”‚ÙÊzQû¾ sÛ†…±8`ǪýL¿7°‘îH8ÃÒæòOô¬7­=Vp¬+kßéZ®˜i'1ÈyÇûbnÙÅOO¦jçy5••¼Ã¢oùªOFˆŒÜs@¼0¿¯æ/FßZ úšd¯R7š4Жˆ¯„rể=6"ÄâÖ¡â÷5"„â žÒÒÛÖÜÌö[:Âd¨* à±Ð`ŒÈ9¢zî‹`o‰4`É|{jKÇY¨X³ièÔñÂ4×`¼0ða}'5ž¥Ó IìVŒHë›ÍÄà%Â%\\ „Îvv²H³~¨âà·´°îü@ÛäVì¤Ùd›tÈ&}o1¸Š©®½½ šM Ämè@æõ váØæf3Õâét¨Î²iVZÏð…v€qMui•…$:­|U@¨¹­Ä9[”ê Ð*™"½,˜Yae©o$_Áj~Rb³‹A,”þ‘š´Ê9±1"êŸÅ Õ Qå—*–d¶_9×h'Í='ahˆä.hY FáJ uy©Ñ€èUp”qp( Ø N*Þî°AP´»n„âÉw‰´.ÃBAõ`€Ì`üÁéËšÇ%ɧS-RèºHhX+þÌ3lꈧùbÚtV·05Pq­môΕ %E8[CÅ9´ê º5çëQQù¹cØÁlåÅêö a ¯Á[¤@t“ùuY—“r²O`dÌQµ ëÂbdíVuÀúŒ:!5˜.í—{xŸ– ÌÇz¢RØE]-,|ú}ZfžGz6C«EfUB7û2 ú ¿`|ò2z©ÚI1o±YoÄúa˜$ãFAªzgíjÞ¶ 4¤>˜zÞæº¥…ãpjsÇz3t½30-A·ÈV}³‚«à}¶ †¯]= VBYqÞú(WMb rD£T"¡fÉD‹¯¯ #Ž2û*TCèw=>øV´k»‡Ò"£©# ãCÍãYœtsþÍ\c Tk뱤NÝ€^é±68VMáßÔwob[”[‹çöl*ƒgKY´«BóÏm*×Ãg/[·´óït³´š1ŒaÌ:3C¼°_˜DNÖË/ǨÍHµ F-¯ÞÏîbP¼ÄÓpÌJ˜@ÂÙZY½[íêp˜ <£ÀP§NPJòbS€­áBJa¾ŸAúµÕ®¾èî'`Ì+jº1…¼ƒZ׿ª%5ásš‘šI-ÀëÓhàf>@‹«IfBd w®ó Ó£Ë íÆš"¶\·Y#xzŸ‰ŽúàpqA ÍôŰWõ1B—Qȵtr¤ACyÄ~d!ùj*1éûMôü„W÷HàÓ3ˆÊ¨ÅX’æ`T”ÛL„s`ì²y² wè€mŸŒ—‘ÊÛš„­NœùÝâºTÜÜ vbJÅ<®Ý >üh'‘%rf‡MÅÔX­KsÎTúøó×%b%ÍŒrGIy‰ÇÌVŽq˜(8xj=ûºª&cîe¥VßÐ:*uénà ïX L”¬|ÙÀ°U²ìÖ0EZŠ;cn50N‰ãËz• Q¬.Cu’xR`oTv.®Þâ-±ÅÈ€á{–ßÓ‡]Êù”",–Äg?1 Y:í¥¼HÓžW²Bz’[äi ‚ˆŸš}ƒ[„xyL ˜-¿ø^^k=±O°üKce–F§ú¤uÜ"»!:"¡*ð¥#žav;¨œV°q’hW-° O"cÊ/"¨Þæ0d 7˜÷º Ö.h®Çm (,3 ³”^6ãm‹b*))<[\bAª k°('3ÈOK—cŽË+ TKæ‰(”Z™×  ´v´°ÔàÐàbAŠÉ•SÄbÒs]Y13*‹°AdµÜ”Ñ­,2L¤qT㉨)ül£Q®h'+ÆÊŒÅ,—š LI6ÒßžË\B~ÎM¬F-Ošö„>9gL(ñÓœæšcíò󰸹“>8»*`e³p#G //פ%ú¶e¯Ä¸0'g8qs:¼¼ùôef4!îŠl"æqAÿ“G¤•õòY½9ç£?-"‡·½«,»YÅšWÁŽè,Íka¨6Ãc•ý‚~Œîk-Y´ä1¢ Õ€m{h ϰü>ÚÊ2fïâ-ìäPÚ‚ØÙþ˜dÒW&ÜlÀ3hADØn.{`áãbÚY²œÐ2UÛYJ‚³Ú#Lp[Âæü g…y›Õ©Íܨ–÷kq¢A5ÑÎ4C†½#Ukà}6péqͲPZGZïìrÒíB¼Ç‘œÑíLmƒušÊTFÞ²€]„6>ƒ|”=‚Õù ý”SH`?çn%= ©ôŠ-Ý‚^Ê6-Ž^ªügöÀl 3­0ˆÕ`I…i‰­BF a|°E[#”ÕÌiU‹ÐÔ`PQ®'8!+–|Ê`£_Z¦ýÜ*8Ë4YJ*ÂPrVÈ‚ŒÐuÚ>%k?ÊnkyÒ|ò¹ÐfY¤à"XJö²žÆ3¦45¡^“0$ =;O ¬º .¯¥©¦T{"tÁ“±ƒîøYá „ÉèÉVw\óT'Ï™Á,þyZ’¦eRiØÅ¢X”Ä×'OÆKõ$pèV9że–Böe$ø2¶ÜGêW"–uWLwTÏ®eFa½„ØN…b¨_®‰Œ³ÆêcÎèwo®žÝ×ÍýØjý(·Û.ºN'x«òç­,ÞjøêD”‹inÜúÚ»Ææór0àïà kæx+ð8rñG\ÜMy#s@jZ‘¿T“²áæo ŒægÍÓTqi*/"Œ»=xa]ÓŠß8Ð5 0p¶$}ʼXÂÜk· w‰¦ð!ºà¥ŸÑ²/UÕZÐLós.ç.%uŠŽIå™ t3ÇK¶$ð¨¤B\ˆI£ñÑ”oªA£Ž“´(øPf/Šçœ+ÀàðJ ßáJiЊRµ^ ª‹¨6[z2?Í´hš ‘Íi5 òœËç&g&ß™¸«NXCœ(WKH|çsU¼’` "¸›‹áLãäD↩!]ó¥J]vn–ªLO/*9¡ŽØ™\*JZ…}I¿ÇÉ’+S´Ìh¶œ©…#5[BY\`Ô󌄎rØŠP WÕˆtÔ¬Ô™Ò­h~ÔlÜQ²&Ϲ,#ìHnBu×ÒØÒ@’Ê ô&õ&ä9Ï7JŒª;L “üÒL‰˜“þI¦_MºMÎÁú´t ÒSä}i`™•"`z2᪱Œ!#h’Ô«°íxÈɬ¯ Æø¹¢ß,~©â¤±Òøõ©lÓ°‹âø»ÂìÀº/Ÿ`2‡R±OÁëd5½)£ÕÙ¥E¶š±¨œJ£6gךŒEŒ.9- ¤ObËÙd¥íÃÄK•(”°>PŽwþ¢æliñ èž›C³ŠÈ W%€›Ùá‚‚‘sÙ×)ª’‘©.F„ðÇŒ„¢úÄ%Ðts±(c4e¬ áÊŽ‹AoTi˜u FÍ¿ÄÓ Ps«œIû £³‚x3rY»‰Š5*|, tOµE°%ø¹©6å3~½,ïQÕ²,¨¬Áà`\:àº\"³¶Î í Ê„ú¶8qÚ¡îjN›ŽÊÜÊ–6÷ŒJJè!˜ÀÉ•Þ44œ¤¸‰}”íŸÏ'C«Ýsú¬í´j4Q ­"ŒÉ.ÓdsSQS5Ÿ—*E„)Z$¥Ï€„É‚>¥H$_.î¼ød8/µ6·ë š»[ž—¦£ÔVùB¯íƒ˜±fî7ˆq( âšpÅPDÅí” 1™'§4”w¬KôÒÌ—²± »jqADaë${cÄu’(†ìaX¥$Íе™Ëe#í⡳åúì AuqªFØLƒÓÉK šÊnF8Õ"‘²;ôÕ.B „ˆ5ñ©RÙ“XÌÀéFY“»éÕ/´k+|¨$±:.˜Vuy<*€‰î|=›’åí×`_!I(]~,9³Ñ³Gç3r¼a3m*Œˆ²Ê’Ä×Ó/Î ↡ൟ+Šòÿ!ïúC~Ö;lH½»—ÜÌø©SšÚŒyS¶ÁhIú»§Ë|ìô›^wçFàØAX8™Í(ÑvçäÞwìPd¢Øìgt 9†IB"„ ‘XŒÝ޽ÜâçýµÆÀHøÍïnßüáîúÍýõ›?ŸŸ‹˜‰¹—ÿðìw?п¸Iþéë?þë¿\¿îÍ<û¥ýyöOÏ~ù§ß¾üÝí«+úó7×—÷×·o.î~zß?|uö»yý¦ÿÓyïÖÝõ·ïî¯ÞþãÙöË_ÝÝ]l=qùýõëWwWoèßýÙ/ÿíÍýüoô¿îúáŠþí¦_üãÙ/¿îͽùóæ?^¼~'ü´ò±Óýµ?q?Ž®ç{¸ç{„žÿêß¾ùÕ뾿øÆ=8‚ëWžùìcpÓóÿ×ëW÷ß?<}ì8ÇðýÕõŸ¿¿xxî³âöÛÿsuyÿëÛwo^õþýúvmÑÏCúŽ¡ÿ|s}ÿöáqm<üß÷ñœl÷ïî¾}p*î®Þ¾{½Ç×ÅsŸýëÒ(Þ½¾zsyõàXä7-æq¼¹ýúþúþrí4˜Gñ–ûë×W{,·?û˜üƒƒyóîæ÷—÷?î3–峟ÿ2íªîƒ£ùöâíÕ¿Ü]ýßw}9î¡l=¾ÏÙ±Òu÷ž®?xØ]ýÇC[hîó{æýO¯ë7kKp©ÐCŸ}A}}ûîîòê_ï.~øþúrì3ŽGÆjÇæ¾ßþpuwq{÷ðæ'm/¼¸½ùáöíõý>[áSt€•‰ßýËß\}wöÕÉ`:L[S<L'ƒéd0 ¦õQ|wwѵè׿»½~{2™ƒy\“éáü ™L»ïNÓ‘_'‹éd1}Ø^8YL‡®ˆsÿtm¦½ú~¼VÓ¯¯~¼zýõ÷¯nÿú¤ƒMñ °öÇÛNOǼøöõ»µsì ™rK³7âéÞÑkáoï_ýæêÇë êÉ>6ÅòéG»ªÿõâÝÛ·×o~½¾ÒŽQq½ýî»·W÷ïéôÚ{mò'¼/^í¡§¼z Ee®ï¡¦¼úÛ#nßßó>xB÷íW—¿·Öã'´k_“6A˜¶ËÛ×·wÿô×ï×ÍåñÓë=œgúØé$ú0mñáéï‹ïÝë‹»·oÞÞ_¼Ùcyíþâ{ëŸÿöÃ훫×ü‹Ï>®‡±oßÝ}wqyõõåÅ^›fã駤埻©ÿÏ“5÷Ó>?R{ÿÜï5õÿõpïÿëµ€?Ü^¿¹¹—üinW_ëyòRoÅ“FrìföÑúô÷ýG«‡ü={óeS¿¾¾ÿÃÅõª&ô„võþÛáhwô¥{XMøËšGaÑuz滾f=-»îŽÒªûKØ£ëá8»¾ÇžýËclÙ‹»ëûïo®î÷دwÙÓ±,?ÀM¾ÿ±ûHŸî·Ww¾¢¹ûÕ/jö?]Nx’õsìI?ZÓÃ]?R÷Ò¯þí›··¯}wuõ_GŽKâNX’ÿ˜‡=^Goèïá´;Öóá‹ø¸çç&ß]¼º~·Ç>ÂsŸ}¯®__ì‡~R6Ûooï~øþöõíŸÖOŽGóÿ²‚öÈ 8Öét Ž¡Ó1D{øaäñŸCO…¿OvÕ‘Dç?'²ó‘ö쓃G~»Çáôûõá1ï~Ýã¬9Ö {Êâ~ÿ`7‹ûa¸ãÊâ~x‡Ÿ²¸?㡵ÿÂ.ãE¸ìñNWÞ'èûÃÓþvOð8PãŸyÿþpdëÅ÷oÞ\½þúêõÕå^¶òî/>ÜëáXãk÷vKüæúí¯/.¯n®ÞÜÿö⇧tU} Ô­ÂÓñt:žÆÇÓI}zÂÇÓ >ާÓñ4<ž–aŽo~ÎXÿÓ9¥NU×O;dßRþ.wÈã>í¿ãò‡ë¿]½þÃ닟¾yÂécŸ·êÅç& ˜ÎÒÃ@1éã¿ïƒ[<ú”2wæ¾òÓ™KýOgý¿_õ¿ûÿÿUÿ‡³§¤s{œ!N„{‘)ÜÜ®R$<Bˆë7¯®¾»~³^‰q¹¦~¸º¸ÿÍ>{cñè#|•ÅÅ{Æò˜o ’‹Çó$(.Rþnø-ŽEoùvŸêªGÐÞkGk |ÈN–ü1mëKTŠþý»‡Ë÷ýöþÐhÏÑ&ïwNë_íØóü,åÔqc´Pvõí¾þ ãöh÷÷Ã~¼¿¬E´]§gޱëk»eÙu÷]xÿe Å´ìz8ήï±eÿò;öâîúþû›«û=ô‰¿¿;íé¸Ý?ì:a½SÄòï bÉó@1K?}µßœœ¢”§(å)J¹}Lœ¢”Ÿó«œ¢”G¥ü’ˆøOQʇ,Äcô›½³ó¥|tç)JyLÛúÕõwß½Ûƒçüèwö¾9ÚÍý´“Ó\½}w÷]W¿Þ“FxãéÏ>œŸ®^¿¾ýëƒcz}ýçïïû¿Ÿ_3äãÚ~þò÷üJá`ôPxqû¦›áoö8¾v~ð”ÜI²h¿úóÝÕÕ›¯úqrõU7?¯ÿ|ûÕ×·¯¯î¿º»zõÕíÝÅ›U÷òSò3Ê#žüL'?ÓÉÏtò3üLe îälúÜ·{}8vñ_×7ïî×j[-?üì‹+?<Š«×ýÿØÏѱxôѼ¿¹f½ø%íšÇHüFtô—ºsŸÐ²~ûÃÕe?´ï¾DøÓöWìQF_këq÷`í=®þÛ]-ùqÍ¿8Êq=%S·Å?ƒwééø.ÔS!¾ ud° ãä»8ù.N¾‹“ïâä»8ù.N¾‹­±œ|Çgä½~müÂÐ'×Ë`'׋ôák5O¾—SÎîgþ&GëI:¥ä?þæ~}}ÿ‡‹ëUWÖÚÙ{ÃØŽwW!ÄðO8¤ðcMÅßcÖ5®ŸRñOwÙ¾wÙ@-óaúÝÑ^h{k§»ìQº~¬wÙ‰Væt—Ù]ötÂû_ƒ'J™½:ðH/ÿ"(e¾þþâÕí_O0VÇ´Å'ótŽ™/#­ù‹H ~˜­é”üŒï¾{{uO¾»zµßÊ:úmò´!«—²{õpµD~滾v!-»þ·GÜÆ¿çýð÷¡{ÄÞÿ¢”ðcùŸ*’ò>ÁÉ::;èÜ¥_<¸÷¸ãÚ«ï{\A{„¾Ïöçæ3uqzøüõúÕ>¨2}ìó!ì1†ï¯öhÙs'OÀ‘o'OÀºÂð¹Á›'OÀi¡'OÀ±íút={týä 8žKñä 8Žïpò|‚œ<X¤÷û ,ŽÖ=YAãy¹|ØÇpôÊÝc8Úuyùsâ]>7gûÝÅåýÅëßÝ^ï‘À ¿zhhû³ç<}}¹æ‹ZÚ¡ôØ\¿Þ‡pbãáÏï½zIùæÝÍïûüqŸÁ,Ÿýü ÐçÓÁ|{ñöê_î®þﻫ7—{XC[?¥3{ŸÙøîîöfk‹Ÿz„Ïù0)üýí§Åí#tþDærd.'*”õor¢B9Q¡ìŒæK¢BÙç²ÿ»aBù$“ÿxw÷í»×}zŸžÛìÉó$ìcЫQø÷Lpòµý_DNµåA¯9†Úò¿‘y*-ÿÂ1Ǫ¤<|càcíeìþâЯ{ëŸÿöÃ훫×ü‹“Nù4tÊ'¦±œ–“Âò*,_ëùyÒXWcùBзV,ýHõ¯“Ã÷ñ7÷Þåê~gïíñ=Þ]ý…àÃV þ²I_tž9B“ð/k,»îŽsÖר|–]ÇÙõ=öì_cË^Ü]ßsµ½ýé.;ÝeŸD½;ÚûlïrºÊ¥ëÇz•íq ëU¶G×OWټʞŽõT…ë8¾Ã'¸üžÀìº<¡Oÿ /ÁRE¿ˆ±'²•B¡§bC?ÓXN•ÇuÿkÿéÛ÷àžÐIü·ÊÑÄîlÒÿŒþ2Ƀä¿ö8 ðÜgèÍEoêaî»kÍ€z}{÷Û÷ èwþ—•nõE¨a'â€cÚ ¿ÿ³?‘Ûãsó9=¬Cmþù)ÿóoerqÒÒÿ/‚õ#¦#‚íoíytj×ÿÊ®Љu´ÃíQLù¤Ò~ÞUõ§ï®îþåúî pø|Š›ãéÄ1ï/¾ÝcäGí¬÷g{¶y˜ÜÓµñðãÑï¼{sùïOèTøVÒór6}©ké_Oké³®%÷åK¿~,ˆ›”ûwoÞ~·úñ¬iê»ø—¿ ½éCÓ(ŽÖuðAêìÑI'ïÁãoqFPýêõëO°¹ŸŽEñçÜ —÷sáò>ÅË?¨âÈ/~õonúæŸß¼²Ê#$J$ùæw·oþЛ`Ò„sÿúêÏ×o–ÿðìw?hüO_ÿtóííëgÿð«»‹o¯ÞþßÞ¥gÓÙ¯úÿô×gïúÿ÷ûgÓóX¦TëÙô<Å45ú£ú|ëþŸþGœBóž$xÆû“;ûÓųñ§Ÿúÿñ?úÿ§‹þzÏ~{ö¿ÿ¿éì½ïߟ—ÚrIhg5OôWëM·©·ÛZ$q{^û Iæž×X³È|ˆ‘…á¹›B"a}îZˆg/´Y×R qz^Zig$ ÏK–úˆz[gÿ‹Ÿ-Ï»$ʳS^_VR©Ò¯§ª/«.ó“åy*>ðËZÿ™kÒ@~JáG{|LÒhÎÑi£!'OBÿ<Ç)Ÿ]jgcªýÙÔÚóÔGÆíOôÞ’°w ÏB÷<5ÏÂò<'µþ¥¦Êâú<†’´©æ&/SÑÎd_>ûލýgnò:‹.{þ Ô®wŽžwþ¹Ï)£±l ýóVMs2ÉòÜó¦¬FžnsªIúàK¡O[k{ýÄ Ï'—?¯“~Ü¢¼*ö/Î3Û_boÿülŸfêxOÏKi.ʼnÐ;ß´)x/=pSÃ$º>_HìúÇñü²>19†,3ëšö¶ôÎx¦–Š4Pûx¼+"î‹×‰08Yá¹—^íÎ6>CÀBr^–ߊ}(a!Vav…Áóƒð¨˜†)MÖ@àO6Åþ•æRÐîFŸæjñN¾dŸ™›þ!rJú²˜|ˆšúbLº>r’…Û§!FŒl sãB¬²}ÞKm ô)”…Û7-^£2¹}å³å|±°m /› ûiñìô<÷żÕj_Ôñ­”¾\Ë䤷­dy–6os;¾õÅôSßOÈæe•Æ©ïTþ”%ôö\‘‰ä㊄幫1Ë—H>‹°ÚÁæå,ã/Q’‚}M‰To5¶ /«Sÿ¾ü%J”êNu¼ÿJÆþëBWBÕ´2•)Ó3å7ïôÜÑGÝXå½³-V¿½#z³…îr÷ôô3Åmî³>]A‡µÜ“¹=/¾%Y¸Ag‹n£¤½ö#îl8Ý/ä;ä¾[ ò…síËõFÅE?{n—(‰|I",.V#Ï, ©+ürêÝuz;ôs^ûåSÒó¶¿2j¿ú”F¹rbß$úû>)èõTû²âwõëÉÉ•Så௘é+Ê ÒúYR¹ÝœíÀìG'OAnÒÒòp—Eлm×€×OÐåió¾èÒ©¾y³ô•Õu·y õ75~ùò¾êSÒÏ…¼}·å¾\¦¬—+okö£6áŠršì~(ÚIÿí]×´~C õ''ZXüÒBG9È>U¾ø$«©6™çeÛóºÅq©Ÿw9Hy—q]íÛºzU è¨îBߟ c’…SsÜkׇíŠÎZ6UƒöV_Û:Eýß_²´ß’¤Jpw[n¼÷\–#7ÉÒûUJÒ%’SÕ½çú-5á»…0ñ>£«MwN—ðϧ*+˜ÛäSþR§ËWyïUj¼Ž6Ël‰RûŠ‘Éî‰^¤¨L,¦S»NEoÒ–Hû )àÛOî1=À+µê÷>Ÿ=&Vad%´ K“˦³Ò©nÂK\WÙ…Ígûù‘ùôK¤¸Ê ²õ³µßŒzP.Å)öãƒwWøÛÒÓ™í:?spª1§,Óúù§"çZMW¢«§ªæàµ_©_"²:i+MŽç;Ñ·%¥/È>oX\YÕûI•ëì±6iÇW={GYŸâc•Nµ¸~&ÑûNö•§ ÅÅ Ú 0Ul»¸ZªÇœùô÷CaˆMVq?Tûm®çŸ8—:Uý¢Œò*OlƒÂºu«V_±7X ¡ù ¤îÉ*îçjÊQÄ—8ÝÒ ãÒ”Ö@ÿF ¡¬â~^7¿õ,Ùb¡N}'²°o.?éQšÓ4s}驾í³ç}’+'VìŸ5¦­9htqêÕûtóËZ?¡§Ü‚Ìkî?`¡7ÛÀË -]SEÛõýÑÌV—§«í©5(û‹–F?Q¸cýàî/Ô£Û{Ö(«ÍMï®ÐŠ,÷K_,·¤ÏöSB—¡­‰„xUŒ+rl4×7³«¶ŽÅöì÷II.aÅW1h»â½ÛÚdçæ–ƒ|^¨b’O#úL0°úÙλƒ÷'}Æ϶ż›_n‰û¬.¨éüÄG„êÁzHå¢g Ýc/ÔÂR€ì”*wJ_^¾D=äXñFsjz¤óªö¾]œ2: Ë–„A6Còy' ·/ÛܯqWµh»Òžy}÷‹Ê¡ýª<…]è •™íÍ&>wú‘ßµ¬¬‹#¾*û°Ô8ê°«ˆrv÷sÁ«¶ÑÜ)dR—õÙ~éð¼ô^EÖé›#u z™ìJ·=÷À÷å“E‹éŠeâÞ6OZlÑ=Îû² ­TìÆÉ9ÝL*©é·åc®õ{9÷³WÞÕWŠûïk ô û;ä÷$nYÅ1³MNÂn&ó°hû@æ3ëž]îŽØÏ_ôIU!I&€DYñ©Ñ _DÙ˜h#òûûÙÛ×½ª]…à¾Ò=“›ÖGYñ]¥í“ ÉÂ' ÐàõZïûŒ÷gf}ïÞT ²ë-Þˆ]8AåìŠSï-Y0¤.ø0qÉÉ2éÂ~$÷wŸÉ`»õéDXh'Ë'è#›ØÑÅêC¡ÏÕ;TE¨çtó¡kw¼ŒI3¡d5,Ù¬¾=MD¿¥—¾)ø@¤©ëÂþµHq‘#f‚ÑÍ“~'ñstXð* ežô9 Ö|Ç$î±¾83ß5höGmVÏ£Lª+,­+Èý^«2‹¾6§«»‰Ï,“!ƒ ¬V>!òâèk¢Ø‹Ð…¦B±ìXH'² ·}ÜäåÛôÓµŸ‰ABš¢n{¹*hÉ,|qAž`q•á’З Šó”2ΨÊ>Núnfé£î ã¶ó çJk¦l÷-O÷ ¨Û­o– SÙpiÄÄöH,ëó/TíÌbâ÷á–Xœê©ÉH÷m­¯²×±™ýè*6¯ú$‹Gßeu&™ 9Ï]ÄšW›OÄÝ~ÒïÅbU.ØIï÷r'±;%y]|'½€—ET\ˆw…Å„¢÷²0Ek >eiyƳ·wž×q_SÙë2O!µÑéMÕÖÄ]ÕŰpÉ_"›¹Ûää+úñt1^qýGº•Hér“Óκ  ÌŒ)ëBbŸªî)‹ Ü…jTõöÃ$ß›\¢ ÷f'Ý¥z#²ã³«ÛŒüßM_EŒ|¸àÉNéæaQm¸áþ!oƒ:šHóžøÛÐlê¸HoI—!íߪ⦈ƒÖ»ªZ>)éÓ”e`AmØ~$NoàI€:½|Q9æ<Úeñ” îw·ºYÕ·‹ˆûüp¡Ú-Þ÷BßUüq"œ~Üß î“~ÛéDJvÇH\¢I.jÏô²à+NEÆ7 Ò…4Ñ”D½C&ñV÷¹áWÈf¤ ýR§Læ¶ Å8ïSÛímµL]è«—{•Š´êĦéÍ'Þ¸…nVï`?$¹Ö’(/ÔýMŠœéͬµ:1rÈÑšÒÑ‹ ˳Nò2ÒôÄf@—†Cp8ŽèÃfL“S‹6d‰êWbã¼Èú¿c úiEžŠKÝaâc¥KL~_'ç è‘Èîjêrð¦vöïE%¥O]1±j€ˆ„!Éžgrz½-i$¶ìØoÄ÷Lêûži^b“SÖ“?n* !7àÉ1å­gû—u²b“yõ{Õ\?dz¾P/——«™¯ 1`&:ox‘gßÜD†¼¨ãý#»®£‹?HotqyñgMôe‚|Ή>¿ë¨#GÞ$^¼–dYûä­'¦¾4ÕŒæ;¥H‘oU¿`›¸º6¦ áiö-´ÍgKõ¦­ê‰ï$V¡=ð¸2¼è¢]ìžÃYÔ¿¡ìÇ~Ó¡@ڸ܃âÒsj2Í϶$³¢B¶5â©&š·—ºJŠ88I³˜ä´ *{ŒHˆ[X±¨¸f>Ç—Â~@xΆëHBR4¶RðqúÑw£Â¬ß¡k“!é8(À祆xhuõ™÷8DuXä'!iËj7&(Æ•Ðb²+y°¯³Á’©²|ÅFÓ7õoÐ&µòù–QI‘º_ŠºX©Y]Ü´Œ(H€û™ž•H ´:YÜ‘î[Z…#£$ ýž:ÃDymTµ=y:§‘£Iï|vȦ8ºH˜’s‘®÷¡,ãMQìB,Xº\‚S) ¼ä۵X÷ßúAÑÐM0515 '®gi¨ «Ú±RIÖ¬“ƒÔ† ú'ÞòŽVéH(ÑaºE\æK—ðAzPäcJv½ÑÒˆ|k÷õ÷6]Yµ$µÝµÑ**™Úˆ©Ê"hU¬ô˜h¹égÐC–Ü®ø†¯mÛ¥¾É¥¢C%³9ˆS©/ætNNÔ«Æš|“lBr׋“¥¯õ~/DyÒÉ^ a…ƒ"ɤj^êªJ%è^™è"a¿™k7ÕÃ÷DÂ>óò´  8«‘„õÁá짯6£Ã‘ÙïÃØt «úßçóy¬E÷…3–NgYÿAÌBy¿‡2LÎ~=mà$Ç íõ:ìnA½P]?³˜±“ÌòŽMýÙ1•û´Ïb·?à6P÷]²1 aCû„ Öi¡p˜úY’騽»zŒtw‚~É!{ …Ú÷¥‹›x#*b´ª\褴E‡H ]q/ÔI’Ä%C›Hϼ)ÀGÞWgÔÐùdåÄ!ˆ À+y1 ÅÞsr¡OÕ¼Þn³Ý)ä ì>ûÏg¿øæ—¿º»ß@>þâ›?ý¿ýý·wýÐN7ü⤉OÒ¹CfÅ~3yú ™tù˜Ù/¾ù®ÿ—béÜ]“~›ƒ@Lø4€Æ¤‰`cÖÀ^À1yú è^xxL>ÎùЄÏr¤‰›8 Ô„îD³&>І&ö£ÉÓÁÑÐÄ€4û¸» )ý¸‡Á¤¸‰ƒ€RÒ‰ƒiÒľØ4yú tš|˜CðiówÙ>ÝØ„}’¯røIZ8§& ‚T“öŪÉÓ Õð5>¯&_tÂG®ù&!9µEnæ(ÙþA<’»ŽüÿµxznÆÛÓu~Z1,;/|¡}z·¼{GH6ù‡ƒ°lÜÄah6ibÏ&òƒmÒĘ6LÝÇ£Ú¤…ƒpmÜÄaÈ6nâ l·pºMvÚAø6œø Üä ?ãfºìÇ£ÜL¥øxœ›]~tþƒu“8í&Ëå¼ÜG#Þì*Û ó&¯;õ†I;÷&Ÿô ä›,¬ƒ°o°3@¿‰åxþMšØSõ 7q Nš8'9 Ë ·ýކƒ±~N:q"Nš8'³|*N¾õA¸8nâ0d7q6Ž[8' „ã&CÈIa三ÃPrò9ÂÉɺ:)'Mì‹•“½°'ZM€—Ã@ÌIaæì ùxÔN²ÆÍ½°ÛúäÔÙÆÎÁ}zz×Âø9ó}<‚Mä"1Lò÷O†¡«Òg'úëªÝ,ÿÐïøªÿ 7$âd2© /²h´òƒÀuЀ×Á…rÀNôáC vШw@vf|<ÌŽ›íÄÐÝj'­ì ¶“§÷…ÛÉÓîæ Ür'ºƒíØ™/¼Ã>z‡øñà;™ÌƒàwXŸðÄësι@xâ¾:†·å ñä‚ã!¦q Oš8’‡»ôãAyˆ yø‡ ybsΓ&çI ô¤‰ƒ z¢¬ÒCÀô¤‰ƒ€zX@õlÙíÂõ þXÀž ð Èž4qhOZ8¶g³ó‘À½ycÀ{ò‡À÷¤…ƒ|bÿá+ü Ÿ4qŒOfâ ¶ÓGCùà”ùh0ÖÚp>iâ @Ÿ4q¤O8ÔgwÍÇÃú0ûlïŽÀ}åÇÃûp‹|<ÀÏ|*ñƒg缪Àüd¦ ç×ÎþáÏþô?û_ÿmö7)±Ì]Åä»7¯ÎÞ~ñÃÕÙ süý÷þÔWý¿ýÿýéÿéÿ‹Ÿu¸¸¿¿º{óûw÷¯¯ß\ýËíÝ×?Ü]ütu·xÞ^n,xÂ_7`´ûõëwWg¿½½ûáûÛ N;åaj;+ÛGÿù0¦º~<±AYsßt®IêJTÿ‹sßgòl ¤cfr*ËBFˆ˜Ô$ V$æ0,‰9>+BÇñ:fÑdHèÃ(hË‘ý€Ràz_¼OHäüágûÙQTÈqÞùIi ‘ÊZD졯°)†Å˶…Üê MÔ ¡hÇRž’y…íè~ëš±Ú¯q’’pJàÉìdñHs„3LtIЉB¸’_nB^"ñ,.)áY9JIÈ`-}RÀDŽînpLP»‚“éâdÉ‹]¼>몘|Ûò8Bû½\Ì$MUŒTríÊW$ìY˜Ú®0¶h#È 7g Ö#@:ü(+pŠUãi@7]s4‚OUA¡c¬›“BWD Xf&èºÕ'ë'Íne÷Œ«¼‰ÈT="!'gçÀêR$Ð/¯óZäa°hrô µJxÁ8¨À 2§Q«B¨Ñªø½…wdº®c[º—§-Ìð#Ž^©©ÆF³H‘XÖ*†Àz«¨áU¼¢*,ËèBF”œ³ï–3ˆÙ>kFF¸ÄÆîzV”ŠÊÄ]ÈÑÐmaLàe¡P› œÕM-*g&Îì@Y>‰6ÐäeYÀ®<\¶jD˜T'iâÔFž¶@+YLæËk³‘ÅMg‘dJŸÄdÛzK¾¦À—‹n!Vaõö¬bý åÓôJ•~UXøþñú²*¡vé,A\þˆg[ ³Z„ ý«ÍPˆŒæe-„JOéòˆxW×€ãb͈°[2ig!-żƒ6…½)±¦6…ÙÕE$tÂË£X_“6:k4 V‹—¬eûσ­¸a«QUØ 5U%²XÄuøB3§©èNHâ'H™W®¢²˜L~½”'Š!ºôЙØxû¬Ü3yZX$ÈrÎÿÉÉñPE³9çÀ?;ÔùêiI3õY-›7Ðy"çÇ?Nzlm°ººšä–‹HO§ƒSñ$+ˆÔE‰j2>²%õú4ô/©.äþ÷*V[Ƴ¶©ž O|§`@Ëï£%"Ü}"D©d’=ì¾!XÆü~/Ÿ]0|°MÈ÷í 0ƒ>(ö•¬ƒJ/”RFÔRo ù{m §9[¨ë8Eýà­-«vJ¤¢e°A&Á³˜p0üì$Ò.Œ’)(B—åMêø}ñl[¬^©Ùž#!ǧE¨¨üä©ÌÔ(wq÷™—xijˆÚ¤(©sFGLeÒ}Àê8+²6,.¢˜ÕÞQ§€þ½²‘T' $UYéYàÿÂÊ‘)v0ÑŒì(¾h¶Þ…NÂC”3¤†>A±›%™Óå ú ¾:ߨ+yÎ!uF1 –Œni`)NMð/‘ÂörsDss”½‰)Fk¤‚þ:6ÙêNÀÇï½Cf…lƒä—wœñéø¾JEšùOÁ¤܈6ªï¼™–ÜMŠ‘ ’£!ýçûŽ5Š–Õ‰EÈÀ¦:oø‚„‘ ‹zMÝYH½.WzÙÇPBá1SCÖMYÈZRn­I=#P`¥˜= 袨ˆA€"ŒMÐÍQRYÑ@hU“`Ùu'ɱÕÁ¸ÔsvVÂGhVó4s1€šÅˆÅ‡†œKr-MŒû#¸Ž¦ó8UŸ¸P™Àα ÙJ]Øœø›2âÀÔr>-ï_(‹œ¤'• U¡ª#TR„ܽCq­†êPQª@’[¥ŽýéBU;̓Qw£bÇÇ$‰q×î€?=[* $V§º¨ hÀ„A¼ ³ªhÿ»ÏÎB_ë®ÐP€¦O¾UºÝ)ûyTÿ,¼ÔÁÞųœ%]eΕÁŽ´(/‰¬nAóÏê¥wq!Þ~–Ñk"”Xƒ Ñ€‚ø7Ÿ…‹ÌBöØÀ÷AF¶èß©lµJ™¥^»Å§3 ’¾ðÛB,jÿÞºîšÚdÿöÓ²ÕíèâØœƒ™uŒj_u1bYø"t¤þ¹².ccÇúXÌžÉMá¼02eÊ»Y¶ýæ'ç™*ÐK–£×aÂ>SØÔlí“© ( ¶‰›xõ› °^óDbÃ,…ÿ£ëz$.Û%äIÞî}\ì¬Ë­æ çÙWï7¿•¹LwÚÍÏgçŒÄ<7Muk‹Ä‹g›Ïê×z­b¾d7>"%¸2G1–Oj<9˜²dÅN[Œ6ƒ7ûAHÈw†IÐèÈægˆf*/Ðh2¦ "“P 5ò±ôÓ³Í&¼dümö@£K÷ ¹ë»¾¬·™Ÿ£É„MêÚ‡Õ…ìø–¬õZvp@8.»e±ÙéBÅÖ”Æ}ö™xs¾&K–XLÌ$±*ÌF6˜b~–®V .ºáÖÆÙ|V7Ù¦P‡!†0|vØê°6fBñ;#È9íü|ÛïF2Ñù á\7¿¹CA<º)!ÃséÛŽMªðųå“¡­ÅΞc@‹õKÖ™×Ζ*Ä›#Úb:4ˆ´µY6_ö€Ë¥í6Àì7Û=Xç¾²ðÅæD»‹zS(éí&D³Øz»òp±ß±U¼¹üTøã³í>,ž…6·³0 öýrkYgÁînvÌ¢v³Ô„/¶z«í¾§UlR¥SÚ>¦l¸£5!Z]pn.ÛígtÍ[çã²yê“X³¸ÿaà5(bŒËVã\šfù,ÑwXªÓ,t‚Ì] ÃöE9E nîÆ Þå^ så‡Åõ î"y²”V·>âüd•ˆÛåæº8K(mgÎ&òXãæ#[~N.~î® ÖšhÇ U)ƪW\0>[ ÿÉâ: “xê*`(Ó>ì%.ô^é^ô",(©¥!ÜJÈ mM~ßW<; –jÑâÙY¯]UCð.¿Vq·§‹2Âq~ÖOp…‘Ð¥¤O²oíÎâ¢é¹Âtºf¡›kÛ,&Ì;0Bm §V!ìSè­¢„ã/›$cM¸ÕƒY¼è^¶!ÜŠüÉê°EC'€Ous)Îhœ…b0Í–¾‡v·…܃wžÅÔÌè¦pw°ó¦Ý|rb°ÂÅ`çVYŸ}Pd¥…!%t¾apÍî9ÏÜÁ„”£ ¾‚…‹Àõ$’ÅÐÿÊì"ˆ®ëì" —©p±{•Ì9©ÄWÅ­*³Œì>%7¼pĈ!`àDPQÝ™$öL<°áíg›øw)5«C1T&nÐ¥Tý…‡‘¨šú ·e샔·AFlø 9aBD2– ÚR,€þ’Ÿ;%t#qžÙCªç809.ážÝµ*ÜöâF„^H›Œ> þ@„!Ä´ð _>Û³ësè2¡ÆØ“Ü¡;°µô9z´0Ðsу !b1´«îåsÆ)0yéˆÎÀ@'…úŠ#:+ž‰EÈ9,ëBV¤…ª±Ø¥fÌB’±FÀ¾7ˆéÑ—Iu¬ —ÆF<`äj»ªfE,ÌÎxi×úßAøøû”K~ÞâóPb¢¸BÉ^ËE+=ĸXvâ¸]Š[±$Fñdn 9ì3 ÑÀðYøùç…ßwK“í !¯šT€¶OÙHéO ÀôÖœ{rÞ+b{ÃyŸ‘’L/Èg›Q‚¥ç?–=ùl[ŠHÑFà@Œ ™)$ö-èI”DÅ«ÒÈ€Q áVä@ìo £å .vÄ.Ÿm‹‹ËÂEèa)ôVø¡gÀ×D˜S^ Ñb"Þ²¼iEKHgÐXƒ$ë¢ùYM™_†T¼DÐ~Ò@E•€åòÙY¨´HÛB¾déÐø+Ix¹€‰’6¹?AÈpSH1Uç,RbG)Ò®Ìõ2‹Æ'–F–’)?[´‰’&œ¦Ž§,Z"¦P|sÂy’&I ÔÔè†ÜYï½qBIúm"B¾I1õ¡YÀi)æ ȶÈØ„Õa"à”2ï{bHFFÊ@K¡.·"VdÈhjñÝ¢˜¢¤’Ǧ‘α͘šE’1!n3R—B‚²Xtd ¶­yKêšé.ExJ/7?©)B’ÂÌø$Ò0/ž¬r_>Ûøèo ­YXgq7M¨‚–ÞXtD/¦ù«óú¤ô‚í]>Û«sg±J³˜Ó†B.uã̉ÃN÷mè ‡“D{·ˆ7…NÐЇ"1=4 擊²2„HiqØŽ…tñ¢|óFM,ҥР+Æf·TˆôX¬Þ8·S ¸§má¬xÍߋӃJÚÜ5”ªt=‘àœ”:¤cÊNXŠ-xº*ÄŠ„QS¿Tˆ$Ý€ÄjsHV¢¯„^Ò’eøVa°ßÎbÂn £¦,Z]B§c‘›R˜—}…t_øº%Ô¤}4 `w{DóA³ë…ØKHú³äØŒãIfS£”‹KmÀ[´8 J‰„’ÍÔ[Óf\š™ÐQu~”Ù~_j°¸ªK1 ÙâYõÉ“ Ó`´E›¢Íêµ¢hsÓÈ´yØH˜7ýŒÒ@|ž6<µ«–l¸„Ï9AE¨¤Hȸ«.eECG§¸ü…q_c™–Iå$Žª¸Rƪ BJé®à©f(7°ñ,ûŒ^ªXù»á5¡ÓH`0ŒO ‰?D¡kD»ó³ì_’v«òl,â@ƒ(úfÕt©ü×`è§eèN„ý±Í'Œf±ºw*“VM›>NuÌÁ½Ù€:bÆ=XL"Ñï´Ý)·(! wº%Ä$ªp{n-$L““„/-¦<Ä'œ3– 5sþ¡‚¯;_C œJ™{0‹5¾EBIëÝb\[ëŸÑü—‹¯0‡§H(é(sp†Ëbn³£ô¥J5‰Ì\ª‹ 2f ×KUùº@nˆy‡n m//…´Yä mîûo'Ä|¨ Hòñ2ͧŸ&š6ÇHÈ®äÍÈÀòY=·^.( ,ϲSBõÕ£QA•Y '¯&‹ÍÞú峿U_±êUÇÉ;s:ò‰¾ùì|#Ìg¼^Û7Ê$܉ˣŸ¹A¼+[Â* f›WŠðœ‡¼ÓÀâNb¥æK1BÔî4á1‰èžœäÞÞn`q[ç9Óú‹PÉY›› P-nkJý)°œŸÝÔðdžãò›Ê 24gY–tПm‹£:æ6„¦2ÍB¬½ØiÀ4©•VÀmC Ü,ŒJÞ¼PÄ’\J—ªŸ!{) øùÒ,Z¨³õQ gSíhžçKžx+”|à7ƒšã›Z2žuFÿº!dt2ØÒÿÏ·Œ‡Ö’Ûê– a¸ŸÑŒCa0`SÌüÛB‚CÂË0NÎ25³¥¥†ÒÖl/í'³ú!üqˆT»ì|ÃÞ\Xp”“ g6äl°.lH³äa.žoØ»jXÂŽ†xøìlÚng3ØR—&óº ^ÅòVSei´Ûšg26C¿âɸ<’mÛ0¿õÖ“ÉNÔ)B6a ßrE,œ!ó¨2²f•éžcL”³\8NŠp,n|/Ê£ `ž…ya½lˆSɻϚŸÈ68„Û~¢¡£)QdGæ“· )qªÔmOW¿ë¶¾6ìNŽÓo»àf¡1äÍž6ubwÎè…co½ ¡Þ:`6ý˜C`öˆ[¾‡Ðð1Š|Œ7ÓW@ì³{{àó^4 •Ff—ù¥zÂ5¹ÿâ~jËUu۳ߟ„;8üK& 0û”öP4 VÍ žÞ¦!¾.5JÑmÁt¶ÀAv= •êš³à%Q1•K Ÿ‚9ÑÑš•u [ò ]3Bo¹é$l 'å-Õ©m½ÌŠ,…;¹ b ó’câãe¤fbéÄlGÁæùZD¶6„slmn`C ßÓ0Gc78‡¹NáÓËo[2³3”Š¿v¤Â$Ío.$*Cš&i0Gb¡y KñùFÜt UrÐy)#ÙÔ\î…¢|ló¾9ß úZ\‡rê&¯RN•9_K”YIªÉà“FˆY„šß·ˆö”lœ8zlHúU([‹ QðInØ2šmÂÔ„¸õÅf[ýIŸåk“Å1&´;‡Î›rmП’ˆÑL{V8ÿcqÚ"6µ!tfî!Œã‹0û¤ÓÖñMjް+Bˆ8nãü_<«w…ƒ—L´±sÎÙbÐìÆ DªZÑ3Óž¿/ Ìwà†wà.~A0ý¡Ö&gôó™ËiH‚²&ú9ØOQBBL®$‚¨óÔÑߨXÃÑËIQ•PBUÁ¦BëÒ¦˜òuLN³HWàO¸=S\P ³š"¢]“†y˜jÙiÒ¹]¶„ªÙHN=9œ=:i5‘ePHƒ—Tá؆˜éy¥AÄl ñ*¾ØêAœò½XjàÍÝjŽ#†P¬péÌ¢ øFJ–"߈ójHÝ"€ß6±'­Í#ÈHáýÿI{wK’]Iô ò¶|€:ˆ§G„œƒ+•:9+u‹wý÷w‘4#¾2»0Z–•/†‡‡?è|©Gݹ¡;Ý,X©s`5Ù×kÕ]¤Aöƒ=Ðç&ËD½Aë4­¦M[ž&´îFe¶??f8©J3ÖÁGát5çLTó@b3;À~mV?ò_½S™îÜ{*#`ªè…ß“¥õÎsÎxz9®ÕÓþ|Þô¶ÜLísꙤ»òkuvÚ]:Ø®ªbÕ}Um Ô#Ⱦ¦ñ+o©Í«mŸÁ%7äà œyDx¢~Ü™£Bqó‹ìôù¦T5VxMeÅ#ÏŽÛàñüƒúš°ÝǶ̌Ï%@H/ˆ6ú¡š[=Ô'Ï4ŒY@G†ïd®Þ¹c)èÔ3è×Μ¿èþ™Œ^f£YÈÛ˜¬îÙ(òýGرœ=ú¨¬ìçžzôF¿ \3Ò¶PTã˜=8Á•¯N¸lÚô-èV¦bÝô>þù1Ã7xešTKªƒ@xT]ʤº.pA*Ï|¼Á ™¨WAñ¶WäUÆÄâÄ.p€Úh¦ßÁ¥é z¹Í  ¸ÅiÖ`¤4yÂ}Ní;ˆd…"ÊÎö›NƒAO}WNaÎF »½ˆ_‘°dóx?CU ŒXœF$ÏJ3V1gYí3òÔ4„aŠóø{­YÅ®4‹l¼i­*åMWD§D”Ì VäË빌½©(ÛÁƒŸÓï óåW ^ŽPwðïéÎÄ86YÙ= •7&D¢}âç^=«_XŽä½@Õ¾_í5EÏLO è¥kîÚïʪ%ÿß…›Å?ÈÄhs؈wℱ¨ª%¨íîäKKuwD¬ÐÉ=®ËßêYi”„•>¾DvI=äÝ~ôù1ÃYÃDÁäõÏJƒeKí·ÂÇ+MPÔņ!²ìRƈ~1è®BŸÔÓŒ5>¬ËõgêrçõV®¢¾†€=­“K˜W~Ì"x}v¦ÑÛ,€c¿kN9#NGði­[{Ô¤”ˆÊçoZ i¶jÊ5=â\3àÚ©àý”´XÑ'ÙSyŒÎ+ÁVȨÏ»õö p'ÓŽi[éXÖ=ðPùÂKcF©UãrÎWµZD®c÷àžP°øЭ¬Ÿ®M1¾ÊôX~„ÓP+ ì¶õ(€ó+´¶åÈìHóÎ\pP`níùüôlÐ/–¯ ó e‚J^„NæÖ–4÷ûú§á­‡eÛER ¤[œH2:‘r ´m:o{m´hA—o ú>úôT©ü´éÍ’vj+ zK¾„`¢ÔÑ¿/˜ª«€åx³úœØ’~áö’ÄsÛwÏ€ªû68{«àü#ú(€Ô<,cn[ -ø/U‚¹ê.(]D•±T;Tó³÷["IiC´ËÿñÑt'Â3HÃ~ýÞòõ&75UÝÚÿ¶‡WPUÝTòÄ àå<Ÿ~…hÊ£Øð­ôQò®]Áè'*)ó5¾>f8¯;¯Œ4mw]ùtÂì/èÚW,fxÇ»úü=vÐÑPøÛ›DOéš~4äéè—ÿÑ–Œ ûʇ‹ëB‚p ¦¹ÇMbpð7v|T35kXЮ H°Œd:Û [[‚bìVp£h-i$“!,Ke%'I–ˆ»¤•­`‰Ä*).ŸYsü?ËÈIC¡„‹ç²M áFôjÆQf ¿bnž3ªLù»é$¼‘iq)o$L/æ|\O³eXêk£Ø_XëñÐó0–“‘^N°¼suJ•¬¢f¾É(QaÒ¦Ò6,-áI`P+N,Û·ØËerÖÃReÈfôXjçã”ë`«µ–žÌ6 ø¶m½Bmœ§MVœeèR©¶¬éËima§Òäécþ…‡q> Î1Hû—,к;‹=¨ŽÉ âøR50ºI œ›¬ü¾üuTrç¦]°àóÀ…ªzçç_ýXõ²_¯©øÇô¸ElW9“²`™åÞÓú gì§AÐó¾t‹elf…ÃC0ßÕ*,ß)1e*„C}§àce…h*[' ‘¼+`£¬¥QQ.Ԡßpʉ[q€Mi¾®¥”Û)0@æ>Ã\úë;µZwÁŒòùgÐgoQU¨©øo—Œ_~!ªTs¹yèåIÚ~Öå à|yjmëîÃH§ÖÒow_½zua¹‰fG.Â#Ƀ Î{RÚt”AÌ»ªbö@o>y-åm†=@˜¦^r´-c¢šT¹}i[yÛ¶nñQùHœ.˯ ÷©šHþÚà¼f)Èø!5·,ïzÍ:3‚Wn/iÍgò|y+åD–(‚zæ–®òÌËñ;ôSÐãWÊ{íR¢áÉa¿õ¼×Wx¹l¾#ªˆý5V$o¾ìH0¼lÿpD~}Ìð@¡šºB©´”©æ`­«™¸BKǪŒ‚áूSM…T¾@–% I3ºEC‚€ßoð·"Ò™› iK5ÝO!5Z•Z·¥;&b¸þó1ãê±c•V!Ýš<ýÀ¶¥}ŠÔŸˆò5UùŽoþúè£Ð:V O°ÿ¼µe¾Gë­€F€³.ôššâòu¡ƒMWì"()޶ÔjéP·ÿ§E†»×*QøŸ°^6–Iéc=âB¯2y»P0_÷íÒóÖ) ~ü°s k$³:YP„l¤(WZ¶…ÂT|È \ˆ\ Ê.g@¦kìßœ’sÅ?‹ÐÙHfF&KüJºÆ!g[rÜdf„xµÍç’ªDÅG·¶®vüÌ„‰R<Hû®dQ¨-ØŒð19%tÜÊëFI =ê#u^Ø#Öcò QSÑ$½:޲lÉËÔΈU²d\À‘ö«‘E)Vkë+8H¨Ö,£R aBB%¤]£”C˜j<ÆÔ¶¨­Š‚ªé;Õ¬É%1v»u}™"î_¥â’ìŒ3ÊŒ©ÿX“Fš€õžåædÖ8øï·Þ¦Ü^áÛ×­” i[Ÿ\±XåÚz,V¹J‡P^AÁ ó¹òqì"þÌó øçšmëûý1·Î>Ôjh =ßÍÛÝáÜiêaé×G¡å»²Ê"ðˆDñ»¹Ë•F¯Bh¬jÑͲ6¥³Cåf ¥P›Zy»eûÓíÚ Ý“ŸµƒÏ¼×ÞÿM:ZÝÂ+Üi,,ã©ÇM±òáJ=Ÿ­-ñF®ðaÒVAÞß-^p£ëQ¦pŽ òúݤ:ÈÞVDzí`½—œÚÅ"Øz€ðM±¸Ô‘Ë+uô@á$ÌS0• «Àp(HðÁkÛêAáÙo¹R?µ-0Mt«ÓçÇܱl›yšbA(nÄÎùw…e¬™¸¤­(_6Æ=àšÞï®ú¨V˜TŒªk¾6º™½Y7ó..FÍN=Ks‹µ¥›??æ¶tÕŠ¦'R+¤ºLµ>w:;X¾Qlái¤€‚“¯4ãÊÕZ=?¥†_KqHr9V+c™-) `º™H#HË‹[̇Ú6‰Ä0]œ ³\[hÿ¥Ùàâ&÷P¬re‰²„Àä»…²îˆÐrÈïáá €ÞÆâ©ÿƒ¶$f(oˆðí•¥•!È¡øð•éL­h mQ ,~B‘ U‰òpIfÇH Q/!$åÞ¾ˆH¯úš~ÿz*˜j¤³2=‹~@Cå…Ô‹éwÿ¼£Jb Uf¥ô½_ íJþK¯7 MþÙ—¿å+Ý+/°œ+ùÉAc6Yû>! ªÖO`³U¹u¦•Ü…ª¥Îœûˆ_íx1Ïô²_óñB¸ h Î‚Ó ÙÛH¶™Va„Ûάj`Îί>àÅw##[„9òr $ýb1î%«%GÉb‚ˆÑâ3l üŒàWßÀ´mn**µÈ­HQm€lh[¤?`ƒ üÂÖcœë0Aäºóúß ÷D,°Æ¦(,@EÇ(ªz-q³~%[]ƒÇº¿·}@õV Y—瘷žoÛ ëSm=½EÕ"jïrèLÔâ%’\%UËcºÓ:¦¶[ñåUËMÊåa[fÝ6P\ƒÔiîÁÆZÂEûl±ÌzË=²{æì© ‰€ƒÅÝk I~ɯReö6"ã§·1z¼Aòõîcˆ‚ßís‘¿lúŠ/˜Z‡¼À¿ÚpIyòj›¬œ\#%‘ãKø—pûüú­Œ½-8¹>Uª€Õ?§Wè/!2’ê.EÄ:±z*œätd7Êš-ä5 ²1©ES¬bRáFA°æ}}ÌðŠhyXQuOëñt8)úꄃ´ZJ¹&}˜*HgˆôÕ–æWêBÒ»*Ÿ"iäȼ?OÎW–û%Lz:‘Ê/%ýc ³p†’àð@^z1 ²¶Ú/e$·iHBD!¯³Ì¡5\kZ:uA|ÃjŠ*7¿“ç²Q›²mQu6Qwþ ¶%@¤²å% ‹þþ HŠY”(¡€‚¿m‹š‚Ì*ž^7¾Ù]^Ô*©T£Ú²0¦70k˜v"Ú±­ðä¾N›wµ ^ÏOü>8¨ Í@Ùå¤ Od;À’<’' ÅVÛåœX-Û±XZ„e£xðž×wy$€”ò¥0Ï{oh‹ªbåcàŒ¤“ƒ³$ùgÍ8?‚xc‘§rè±Ó´Ã{€‘OþVsû=NÊÊ•q¾¯´4äKa»ò4©'Ò"[a»r%äR‡=ç5­õ±#[37‹O8—å‚îto+kìÄ×5LÞ‘%ܬeÞ¼-Á{Òæ°{ÝŠif êÍ•‡¶UH48ò*¥Ž^©$5p?—rÜ~mïÜ‚òŠê= I³@µ‹oÍ/1ýé.š¶ÃT*‹BêþîI¯ÜìɤÌÏ(=°¯mŸz€ÉÑ­—:g~)µ °”f¯Xg›ó³ÑTzæÃXÈ=oé¾j¯b¢ ›¦/Å5¯ù±ƒ4P[Ö=D¾M]9ÒÔjàkö>ÓàBó iä÷Ö{Hƒ¥·ÿÞ 2»vƒ¥¶Æ—‚êkÑ—ƒ—wØý^7Ìóânbfp}Û}´*ÑÀ¬dà"Vp]—2xRQȽ«BŽ;Ο“ De?áe–S à­˜Saÿè_XJØ’ÏŸîóT"èRQ`b²À¨€º¦¤‰•»ÿ`HéA®(så.oÝz©t™IUF¤çŽ#§¯;î ýp¡Ÿ{öñ$ùœ˜ð¨É$“×-bè@ËìAP)YǶ4"­»ÛŸŠ«³G‡b':'³#EpÔyoïA…Ç犩G‹Ä9¶½m{¸}Ú \=°WÀúƬ-ûÁlsæ>±ó‘Á賈Ùæs¤më9 ¿fÅ׃»äó *Çl.a“@I»ãA|*( à½j2ýè:@Žô )eóDè°ƒTÉäô`ãuP 4+Hö´& ŽE[¿wú!~s÷/K‡ Tܸ¡ÇƒÊ +l¶n–èÁ¾§Æ:˜W!k»Ýlû$K÷“R©ÚŸ+Âé{‘[ÎØ¨ÍÒ»pû+p}ÒܩуûN~@TÇ ’Œx…ô}±­KÝFþÞíIÑ4‡0bÆCš\ZÄãA—<ÿÜ.y_û¨/ n“W ùïzã{å&…;ƒOݪfW:¥‡‰Æ"[·ÉŒÏ³7ê<ØÑƒ'Lºfð´qͪ9®ƒp 'ìõ‡íYùmìÊî°~‡¨&9^Ó›½¥~·è, U剥cPe’ð¿úü& ÿšUËϱz.àåZp–ùy;h¬£´s+€í€_°:ĤPmk7Òx²ü4o¸Ç¶ßm¾°(êÝ_“jžŸOâ ÷u_?9,-´ë¶£*xÙ]óõ‰¿Ø­;ع rC²{”GaNÕVnÚËl¦S ‚œ[™­ -[-‘8Ób?—ÒK¯O5P©µj¦/¸‚9;†I¸nYÆG%%¸å¤’Ky(þ®Ç)纇—6£§¶}ªÆEõÀAŽ!‡Flc9Þ*àâêì  ë?‚Nœ––-^0æF(þ?n’ €ÓC ýa8×mn ¾Ñ‘.ºZ3«ù¬y$Ùëž”{Ã)mƒíÚh*—{˜3îî5clϤd=PÛx/³fÁ’鵘ýNµŽŒ<³Z¦çõb%¸Èò–ZÄ%¨Ò ¾÷;k¨„e½Jg» Ì6kCiNýg°l¬òq¥m}Ú2žçn²š•ðz›†e ®¯%æD“‰[Û¦…º@ÙÍëI(:Ïàü­Zô Â>ƒbýÿ¡-_¶I­¸.”ÛáÍ’^4QÉh‹€×i=ny/ZhãF’rŒ›ÃFXzø #öÚ{.¤ÃCX ;¡™Õ1³Záõ¦Þ®wR3Ø}"4ˆ*…®_`jèqP˜¤.ÆACìcŠÇ‚蔬«öÕ·Ãm ›ÛªÀkŠèÊ"n¼˜®:žÀØèµåÌd‚ó§¸M3 #Àf˜ 5£ˆì¥áÎq†9¶^èAÍÓ8ËÇ>E‹ÂöJçê.²hžuƒºðσ–û¶wÅí,Q‚̾"«oìtÝZÓJ“‰ØÇ>®•Ð@.PyW]Ìf$Cº+Âb¸žÐ. \WÚî. Áó”Ú%|™kLóœ¨xw_=SˆÛŸÏSùªRÖ{êòVÌÝéKÙà\µL·ÑN×ð†òôê|'L´1ZpuX,x¼[# ¨ ºKåy`ñæž$ãûÍNtNeéV3Y`öw˜yOÚ…e3‘nµ10’û{ÌZõÀ¡‹[·¸:N³Ñé8¶*â2r<¨Ub¬(ŒyG9@¬9õZf=’28˜Ça Ë35~o‡ýŽ3•£e7F÷l‚bÄ^!Ó7;þ>Hž½-ïvNh›ãÊè1¯§ú¿B‘¼rëµ+ÏÆt]…öß‘[ Þ”¼çW0cTâòÚÁµ›œH²~eœ(晫0dÂÍ`ôîR·Hþ¸:7:Àð×<3zMŽ!5«#H18gŒsƒª]ü^áäsÿ°”ËÌ6SM6ST;¤Òq¿éÒ™aàÍÄ䩊ӗ”œªâgy »dÐ “¹½¾«9cN!óå¶êÕYþž¿ OŒÃ¥îü}¤Š8†»oõñ0é³°ú%  ÍEõ°À­f¾àº—±¥ñÓÀýDÑZ&/”«U-‡šD‘4þ+mr\ˆ7©{^¦Ði©ÒŠ€ïõ)‘²3µ-P¤Â{Ø{ž>¹ª–²ƒ¶&€I|ía?€Ôv&S/1,6ù%vöy…‚Æt«FŸXñE™ÕGì?_Ö&€$åÞÒW¼gÏ»_Ù9µÃé,&&D&üù“õ\ GGfo ¸KQ ÷È\ð”±Äé‚(Oz”‘˲ ‡ö™ ¼»\”T\å9¿šAs  ³¸·Ë7v–™\Ó¾Q}ZDº¬ëYЄÁÖ•÷áû|-+<«¾»ÿù³Ö–UË1pÆÞ ró±¶k–á^ÓIE` ó¥ôà¼jlã½)¸Þßà ¯Æ;EF˜üI®‹'ÕI+|é©}ŽeíÂƒŽ“òÑÿÔ4XòýIiœG‰¡¹1Ÿß÷êw~ èžt&ÿù“òÕæÌ…'K#ûà.ÄÚ‡ˆÃÁé‘3ĵ‚ð<<5ïx.îôÇŸ+•!kz¤ÁwÇGi‹`q{™cðôŸáŒÊ9ÑxêÒXÓ¶hd,Y°‘×3Û9E2(t”éß-&#ý½ŸÈ¡0_ÇŠäa¾Á×ÈdËP猚A÷8e×âÖdm¯šþ;CAXpÉÖOUXWÅ¿/Ç g~5”k_vÖP’AŸž_pbÌÜèS::¦øÌÕC7éT\=Ãg‰Á,Dx&%¯[­©•-_o8ꦙY?¹·î'Û¦fY~Ö'H¶f·2๷߂ Çä»ñ£­Q %w†¸.›:³X—Û*—¯­gIJcq2”Wí%b»\ï÷ƒ–n㤀ãɰ¦t+g” ÌÔýz¯ @É ÆœÍžÝê0Ìiî7{n[n°œ6Äx•ëoCL÷‘W\}@]ú½µàªG§"»œ¿î»ª’§§òijkÏÊ®=uâúa½ÈãûƒäÊJS¨rÓCâ!Íü=Ïÿ+ýЭ³äx|Y)K¿ þçJ à fMC½W¹hò%¹ß "P–¼[¼Ùš§Ý9p+åÛpí$·þýÁÃ<ÕR7ö–:uyl×CcHH!îm×t¼Ó^ºGTå·cð)‡ðŽû¥)86³ <¤gÅŸ5M—07Äõðxä…)öŒˆk¬Ÿøî뙞µ·pç/Cä-Œ=Cžßœss¦ËxöÜ]<ŸÐA¿JÕ˜¸eÛ}/‡gAÏ®=£8höU—‚ö¸ßŒ pYòŠfÖ‡.3Z¶FTq«Pû7Sµc§1¨Õʹæµ\¬Ï³ÄÊëwë¼¥5öŠXÔ%œyÄ­~[~v¾ï•,wÒ3µïÕ_å*_¨˜yðÉЊîÓ+¹#VAt ׎uTPÙ<ï³DñÂ?'¸.t L‡d*âÝ!©ð}QµxIÂ¥X" 6Œ¬=rÜðVBkF¬«ªG‘²ùö|î5­¯8gô­–4|̽&á¥v;xÚ ˜Á D˜iœKÄFK¹*åÇë÷×z•¶ß:€žI>\àÂGƒŸçâ6q>ŒbH ³”…Gò†lcDJÕ“¦jm gþ®lg§æ : ŠâÃÎ##&.†œ°Ò¾¿|°³n/ým­ƒï>ÃL¸Uï5† dí¿ºº­VÝP'ï•v#Ö¤´a€íÐRƒòâÉÁ½ÀÅcF6jKzB¶ÙÕôåÛí’ËÁ ®ó÷*Õwœÿúß9{"¨ðˆyÍÍA÷V [æO8V¤4fdæ 3‰%?Þ÷^¹ÅÎáãðy¦}:Lüž °>$®¹Y×ìîO¤Ìެåmvÿ( màH÷“¿”ƒG97—L%)T|0S®°Ë«F™i¸ývŸ9·¡¢±·’0›ÙÉÌÇ` X$ VÂ@—0Ñõ¯€nž%¸]¬QWUd¯²:P*ò]ûKS[%:µM]öù®s* Vn7"U[žDUnìvÖF„¶‡nÄÚ—ÏY”p•“š``sŸú¯ ­$ÜzÎvæÒŸ–T°Ë,7BËödäá•+Yº¬¯‡J~mÔ=ìF›&Gƒ—º“£ø§H€,)oT@~:ðçf/Mzö){¢UÑõšÈ­­U+½qa£Š‘UÛ{à{Ö LøGðH[ 0CïåavKEýeVˆïTY#Þ#ßïƒm¯ÙVß‚îí¤Ô“—Œg#ÆâŒVñºUbžñÕ!@a:ªò¼ä\_Ø~¦¨é*HßTÛ›.³š<Á¿Õä%œ¼J×3ß,(L-^4¥$»€,/‘öΘº2þåQ®‡ Ÿ'Üa«r'Ð_ZKþ[,÷×ÇŒ^˜° rä‚ÿ?h‰Z¢vï¨ÊË?eØ®"äL¸óŽV½n2ˆâæ²·–^ð(+,;¹<ìÐ \g‰<¬|À¯¿iû­Ô¯äÎnŽcÍÒÚQ ]N3+cîÑý8¬Šá]@õ–Nû’ÊC–=€\á¥(©Dr‚Ÿ3̸½ª$mìˈخêÚM%‡I[ímö@qÍ $™t2v‘\®7eqùi>§©ŒÿýÑç=ZÿžZc2ýƺE ÙgKϹm~QXÐ ÷®ƒ„émݤj”5Zûa%Íäæ;í _È;j s8Ävöõ1ÃLíÈ£bãPI°@m£æØ6ßQîÝÂÛ`’w50Ï‹r£ÁyeÑà.™SYÈ krý¸Œ pGõ?Za”pή‡0ïî/Ýà‰X®e Ô/ kð¾×}dÏjÊ™@÷ ü•W—µ”›Î¡ †³ÆÃK²èf•ÃhmKx ™…‹÷a «æ|*˜9Ÿ zÎç×$àÊà $SÕ8ù$S#ìÜ–žÉñdÇ· &V\Éi`f`\©®…qÖ-Ľ+­ŸÎý¼º½ öy[!cÈF}!£ÈFh‹»†se¿Ô÷ÙFæÛCêQFüÄ f­wyÕ%S;‹x–‹ã+ߊnÞ0®•DÐ^̯º!rÏ@/£Bmö¾vì´ÄéZ”»5}ž3k°t·íp¦hA '+Êw'itT+ vÁ¾®r´Z1wdîo¬Áh¥ÎÏ ×!:{Þ|žkr [|Eìÿùsk•°/P…ÛŒ¼hÂÞnÀ®±&7×ûy?+VÛ‚$ 6® Nz×$9„¥4æÞ­jë7ªè¤ Gè[Óe@û^Fàë`†¥ Y.~ËÅ‘ñÜך |ƒ/enbq}M«s¤Áͦa„»˜·™ùz=ÝçžÓ;¯}Ú õ m·t$¾68ºX±Á}½írâ~.%e‹=Òá½¦ÍæBd[¬Ïs᩺!¹ó65cÌëy¨.„QÄ4@ÇtV“ ÑNU¾°¯x@¼vI­dhª•Â;É–á©LùA.°ånr•Ÿzãu_îßHaäfâ÷>‡ip4.PgêS&òª¤÷iàmfæÕãÆ/á±ö]ù’*ƒRò~'Ü·ÔÅxž3ŸÀøJË 30F.êËdN'ÏbÊ%Ùý(¶§;2žC&Ìôý*˜JŽ?Rv·CµÞ ‡êçÇ û±Ú_¶ŒÑj¤ 7òÒm1>KXL¬ªe¸Þ„HAºÕˆ'®$8«·æÞ]š$ØdÖtˆa‰`èí=}œÉ22Êìˆ(£hh;HŒá!–>†,’F«ÔÎL×·øÃÁÙ’÷]#ÎÀ*süÈà}KS;øø`êTÇ5^”{…eÞX0OĸGK²¦=RâÃÂ*Ï ½Kºp†$.1™h~Š RÌ`¼“ƒŠBHn¢¿ƒ“ÌJU"9H,ÜdâEL"Ôa£h`A’þ–%¯ìׂhn„#¿@®Ó 7>l)O|  ™Ë‘=jÀ;s7Ž\·-P".+åPb3áb $.shåùÀ†¹gôÁSŒ5» àe *Ëøaš•±Q a ^?3~ºÆ`rÚœFhÚÚ´°BVÝ¿Ç@Þ±5‰lük;çáJšƒ®Î‡3JÉ0{ùÐŽ×5ƒZÄn9j)M£w^ß i‚…ËÞ3Ùb-²šäæ1ÿä“ Iî;XAËÀfñI2'AǬ’` !¿{Ökâæé R‰)à= Ÿg©+a˜#êF4vùÊLb“AGîÃf¨R%Æz‹ÚÞ1z3‡ù–wàõµ…®{·>1‰éjß2èE´_›’€øg¾fRÛ —ˆÜEœ øvH¨Ÿq.á R˜‘úYk`™±¢©°žØð … ™ ®ÜŽÿ&½<‰ _;ç’®ï‹ Þ¦üÐ÷^”„’×0~?H޹‹Ã9Vë «+ ˆ¯ ›9ŒTøë£Ã#Ù5ë“zø4Vû,»SBÖöä`“AÀ¿+®Ìbm©G3yË€˜ÁÌ•¨‰Ñz m3Ù¢ÚyoÈ=Yà–­Á°¦¿KáÈY˜0 ›­ŠÅu ¼+gŒžŒüžFÒÁÊ£±bM™9£€÷'pŸ™m`°ÜY63õHMcñKì•èý°èSQ4@¦Ìœbˆ²:7ásaÊ“¹p4÷e¤/pÞIyFT]€g÷«“yS•Ìu‘¦¥¡næ‰ÉMÈ«ÈÄOÍZ†•)n!à@5UϾ#3Ï‘[¬­“¥ß1›ŒníB³ðÁ†ÊšÞ”oU(-ô*i¯Ò ¨¬¬Gµ½ I¾¸Â‰_3Øä' Û‚É–/z1lJJÀ-ó‹nFLìÂ8QZE–ÏМ¡Ÿ@f¡ª^Óà|˜‚·yd˜\{…CX/Dc[*lKÂÁPy)`~Ô·VZ>JÂÁÚL9™‹ËçjQ3s@Kµu¢Òp&7ÄR!¸yÍ2…ýº‚±Ú®‹,Å(éã˜8½ñNlmŸŒë¯ ²ã9**­Ð|¥ˆJ^E~I$H‚ÓJèmÝšMVÆ«"0Ýp&“E(îšm/¨Ä+aÔû‘ ÌM¾çŒÙ¹’?8ë¥j!2™ó{ DeÞ,kf;’K ¢ ³U²DÛ yì 9"Qãz}ûHd·0¸ód±›ã$Hƒe_Hîë/`húÁ µZÌ瘒ÃûÈçÖ ¼Á•]®DMÅ ÙˆšÊò m·xóf“’Ì,µ ;wW³™>g¦Ýï UÛ¨J‹PDƒéWËÁí*v<“ˆÑQ{š|X09w#[ÙRMjöüÁ0Ãöâ dæÒ)ÖÕT°±5Èäzç1Ê•£ì“ŠJtÙ?€ÂýøS%WNt5Þžü›Jý¨„´Kþà¢Q\¸A#£²(©Ù· ?ó$ àœÀ žïù?) ‚eܹðDE3Ãå'óhy‘=[âÂïÉ[åY_Ì ’lt]„xéÈÃ}ŽÌjBõz†¿Ú7ÌР¬›ã‹Ë}2ÕŽ,‹aL“êN.@÷tåòÅêa9Gf\"Já–Éå¤QÏ]ñ• ƒÊå/p…ÑIÞkÄeðkz×z_2nÎcbÝ¥æÜ2n¥/¾>:ÜòøxZ( £µ¤†õà¢«î½²Ì ¼&%9¹5ÅVîbäwµY¿î„ÕŸT Ò`msõÁÖk»»¶Š}.ÿÂ)Ùƒ ¨Ì(Ë#n©¼H’ pY÷ØÍ‚×JŠÜ™®ÕR$ü`Wô›ñµÒ,ƒCpžÞk(v”Ê"*¾¬ußêµ]¬·#~XMìÓ€«sMwLïÖ²nuH¢@¤mÇ< ŒïìX¯³3DLCxÏììŸ.F{c`褊2R½Ö Bm¼êψH6ÌD~öX´ñý¬}¾ØïR[à˜˜Vnc¢õ÷¼X×Ûª.q܈ÛpšõdÔ4‚wÏ|"dÛ …nã2¼UáOò´§Ï#ªNS;͈R´òTÕ%§;Ã"?K R]Å8îsOcp-´uªgövÜ{ 5½kV©³p×(ëJøW<|Øÿ|E_²(=³`³Æ<é@Dí&³]Á£62ÀÝÌ›W9~–Ý£¨,®l¥á(Ø »àÙ5[Nlü÷9g_0Z„?Èà×þñ`„úsÞk„QƶŲf¹› Œ÷R¤$'Ò LKB– ³²ý,uwXH F¦òKå¡UQ±Å•ÿ´zD7ŠýöY38Æ-„=(ãfiu|Ù°U*–%3Ñü^>–ÜõpfG÷qu©šjK¹Î ½å+ ›²Ç6x}D7-:Õ.Q\Ç×å‹À`V=Eg¡̳Ìèh“ùú;PêKx³ |" wÒ-Š>•Ðñ-˜àò8"|W>ÆÁ| {…ÚŸÁ»|ÝaÊå^ɼkÞmXóNO’€–ں̖¯h›7qš\W8]ÛnJð3äpÛ¹yaÚ ÝŽéÆ•o6P‹^¿Oò²<‘=Žè扌v¸VSç÷* V×ÖT•Lͮʀ¢Øe¿ó¼>“}$ËRö 3‚€2ç‘Ì­·^ ;Iq×b—%à×Ç gÁͬüª¥9³!Ëx²a1x}R±º17ö²àÖ4ØÊ)ß6PœÓQ Ö~NnÀÚrPœ4?¢_pí÷©—ÕÔÚ"Ó²ƒk|"neAã¥P×2à†jy­uqªðëc†Gm«óVyÈÙQãŠp ¦õðDð7%Kví¥kxÐò÷qÔ[¿˜V_Ÿk-6½Â,Ï#J¿D$MÐâ»Uþà×Ç 'cÎŒKKÛ¢zùß‚ïrŒXÁf·r X¯”c^¦VÆô„ÔäŠ-”Á Ò7êìb^”=©Qépuð›Ç`a ·tm’ΰU…gŒ›öç£(|>߃,´i-‘™ÁÙ?ýþȘmy¾]ñÇ=u`LÿÏé÷w­²öYY*»Eïv¸Òý áÇäxÁPÝÓ?oØrW¬U¡ÏÊXäAócÿ’P„ÜÌ>±xÌKl;(Fc±B1‰GYm†eÃöÍ›ùö#;Ö›î çÉiò‘ü&Cö† ª0ØM/ÑÛ—NøÈ[‚EêÄåÑä]ÛÂÂÊhÁ×ü#0Ùø^)5B}N›¢Énk?ë0Þ+ö-›#[• ã’M²,'YcKxÉÚÛÀã¤wÚBˆbhì@M¡èÓÅ~1Ì2œþ)ó“ÉêKÞ¦.#0Ôø0ìÀæc$9¼@÷Ç œðëœ_3ȵ±å:#:ãóݹsBÀ¡1 ñ DmS‹)”™g’»î,6.Uz¾¬;ãI ”Ìtéõè38;᤹¢{¦ÆÚ?âždúåuõ¼€¬³–‚jaÜ÷>º2kéÓ Á¬…æà¶RÀEû~œ2;) žýòboO2X±#3ÝÆfº¤ÞÍy„¯@=âºhËW†îÃ’0Š[J@Ë8äY9P›'ŽÅ‡ä¦gT7lGGæäùÉß#¯Ò¢F:hQs»? «Å‘°ð—õ1 ÞFfZ ÿ9#¾¸š×ªIÊX=Æšš$õ¸5c2mŸ EТíþÉ€k¤ÈðŽù¦J£dÆVûN»,GÏ'œ\Ü~q2þ¥Š³ 8> »,F:5Y–v­‹:¿­žW|-õ¿§"Kôæ €q]¶>Q‘eÀ¼µÜžê~¡~¨Í` yσòsð$™n’·C5?¡écwj193Ï H%héØ4ñÔŒcÛߘ²¸+š9˜dÕXñºWè³·Wð™~AÀ·Âx‰P%-ÅW™ÂršA¾‚MÁöÉíñ´OÖˆåòos!i*бąˆÛ ”ƒá€¼Ò³l •Õ Xù|=}‘^ȧ®x¸¼rãA¿ªÒ™íÖ^ÒÓÝ~Ë5a×”YžMÝ‹Žgž¹i·‹/B.‹"¡ëõâ‘¥óýºÀdîŽæ1˜1š%zc®tÞéj0ÿ]0³¸ë5.ôÖq¸éá=þ‚¯;I½éÝu0)5^šd˜çóÈÄîÁèë Ì«è—ïtÓFK~-õÝ68ùŽˆ¿ÕïX(ÍïhûZ„ÒØ,xxzq¯+_¤ìµù{„¬ØWâ‚=¶óêÉC“Z¬{NÍ· EeÔB:ÁÙÞ Ô‡ö#»‘Y2>%OÌ9F›BóÛÇp¬«œKE¬eŸ—YÅÜžxr+¨ŠÌÅ$!Å=d ]ól4q&Œ‡­ô(Ó‰TÄ^}ÔÃîÈdú¥ìGÚƒd¤°ˆ ËŠ¬Q Úapj,Œ”ØŒ¢YjA$FaµD”ÕÞ_Îé„PC‹A$­ð?­Áv’Ù¯žØÊ…jM»»€êj®¨-£(ŠYëÞ’ö¯FÀD½ôÕüx3ßKÀúÜ?û,°¾`\$Ã3l]Ÿ> w+3b/d- ôP{[îÑé30gáMõðÞ’3רÔÂz[u PdLû -¸Ï ·IdjXpÊß{-B¬£Û^¯œ…ãf8j˜ÝÊxÒ\HÎ…n0rØljcöïzy ºxRjíÆþ¬“{$¸Pòàü–—ÖÌbȵ¸n°Ï kpCב¤2µ¬+i‹+Ö}$9ºï s¨Ÿ|€ìáäçØKFYÁ†¾áܧ8¾íp ÉÄ/ú‰y"T2÷ò¤4nÙ'™RnäûÃQ.ȾJœók‰Èñ:Pï¡L)µ6,7ðuœý ÆÂý6 ÀÏ`@oàAƒåC‚<¥f¯ÿ.]i?3Øræ?ñÐÔ§t-¸îòÙ‚{ò’(3ÈÈǯ·yué:Žº@zÍÔ¾çéïk¶YqÄy"¶¶7¼ã/~XÆË…Á²æP‘®– |j $?SQSøØ“Ô5ªEhÔzÝsZԺݑN¹ëy&…Ó QH¼iî Û±"eySrÖï>X©“„(;0¼á Ië©;HCþ)¡wRbRÀuðmÏR¬#8âæŸ²‚/ïc¸$]Оù¥™S'mjê€ÛŽÖ!0zÁ6Ïê@pF,õ}Ötéþ’Þžz‰#I؈;XZÉ‹Jø—›îœÐ(È¿s'e¢²&«M²aÑþKºP&•‡r&EÏWqÿóCzZ†Y 2™[Í‘qÈÁ àœƒIük0¦’imü=öBÃNb¸Úóùü9,æRÀÆž¢´â<4Së ©›ƒ4Ì—ýTýZë@\åžJA¬‚p-çÈ`=[bèÑÛe 뉸iÎì¤îuФ¥ö°oÁzÀ¤Šq óÖJó|2·,ðÐ<ÊãÑC) s:,ÌÑJ‚ í3îÑ@_r™ä%ô5E¯(Œ8hÉ€(FRÇ„¿¦ÒÑŠ‘Ek MÏæwçß@+Ë7jûýÃjCÜŽ… ý(è%åN’„0l-?nr—~sÔw^ÖŒ^1g÷CVë|­$4Ák1òœ*Ëš†"kz1ÍîdªÄŽcÞ0¯G쪡5Ãá­øZ[1‡%SËæFJJ(.¶d}Z3úÂZF¥ö€˜(‰[Q€¾é»TFH[”¦v-ǹæªÙ‹ïheñ¯)v1@%ÛPÓ‹=½ƒ•5D\æ¨ZI{j#+0£gÑËj ÚÙ^ŸÍFõ“×”þð;HxB7{¬¢Ñyƒ[¬‚`@³Wê0¼A‚ÊUO Æb‚Ÿ0žcÿ›¶¸¹õ–²¯e¼µe·7m ðóc†‘}÷àô ^²¡¿ÂkMïËü^ ^¤‹ío†y—cz«Sjw¹zÁŸ/ Î]úD îüþu8}T¯uèÎŽpF¸Ã¨¥õx‰µ±IÛäPï°<¬@äëöGÉ+œp˜·×=“_J¤¨^’ {Pm½c|DkVï1n‰=^bOæ¬=88\žA®3GÇ6)²‡È‡geÚ´Ó”Å>b ÔЛKX‚-Ê™N0´Kž¨ëʪjsƒž ÛhxœÃu¯6°Jª7pϲY"àÂ]ÓM"oû±}5I&Q…ñqÏLî # ®Þ,Hn 9%~=ëëc†Që­KM°zp…•,zp’oÐι(+¬ ôàŒÐü’J)œþ‘Ô‚±·x€_GÔÉÙ)p¦?töM•:ªxo‹üæAi ‹µü‚ÐYõ¶ŠÔ¥{ĬtžQ¥:@Ö)Cþl¨Ps²d¶Qo#ÛΠ;Ùƒh›R7KTð]À·=ÀåOÁ¨S¿/± q†§¬a¼:Y°£'ÆO±=Ó dÕa€ï¿—¶‚»­ƒ -m½âÞ´³`€‚"€éð R@¸Rno›êSýÊðõ1ÃnÙ ðÈÛ€ #ÈÞ"ѹ eA€dwÞJ}X*¡à#ðÒÙX`e·º gÖ10c†k€F®ý¬`nã_,,eà‚ÂOH €;yôIIÖ@&Pš™%¸¿Ì„‘w3߀ÍgIæÍÒÕÑÀÖƒoÛò½šÔêß»(€ÌðOÖ¹òªÊìK¼J-Ê~nÒ2ÜIïÿ$)“´Ej|´¼¹2vÆ8X"poû$«QÏ'ÿ¹ƒ€L}ì¾MmAíÝ[Þ¡<¹"ïVÀeHÛ?&¹W´G[”Á~è÷V\)â$í!è WQÃH*@˜ y9h®0ë(HfF–m6ëhDy=¦PÅí9dæÛÆúçdÉsDrÁ“\#ò‹‹SkË”S‘»G$×'äÒŠ~¤£ü'pT J V´æ¤iáÒvO×­€[Øèøf3ÌR¤nþàW”ì&9?™GxEjÒƒ‚÷¬ k`½¬ƒìAÙ÷¥m=L^q ó+,m)µ“T ˜†f7T k WY_a`õÞ-wÆv{R­7Ó| ºÔ¯fî•ù@"@üY3WüÙÓI³§-{PmYZDzû-¸D¬Í×Ç _à1’‡50ª„&Ȍԫ'ù_ž…å› »óŠÇ+ÊxßH7oqÆ7pË”¼g#»Ò]QJÏFgÌ}G¸Qp‡•bJxE@•’g3"œ<ÚvMª™@TŒÂóMª€Õƒ-³ üm[y¯i ¾ÞQÚ(R l=@ •¾nÎ ý¶9ßøm§¥h%ÎN®Dl<‚Õ.½D€9wtnôKÆ[uÀHÐY\‡‡W)Zó¬ÚƒËÁ®"ȪýdÄ‹ÚE"«×%™«è5BsâûÃÂÓþ,ƒÊ"/þsÛËV\˜ºd^¸Ö:9ǶŸsw0}„ _0ö5(,¾Ã~ìN¸#÷ó;•+T5|i³7z`"ßl·g€âl]qY³¸Ë‚©O#hÅj¶… Ü•lô6.ìJ€Î¶(Þɨ™Œ¼“QÑØ5ø\ &ü ŸCõ »_{è+ÛŠ+t°À;X—m¤T˜sæÏ‘m“!< ¯¥ÀGYÅða}-ý×d]¤åo3êÖm8@p3XÀC¸üÍÊùRõ…à^±O?ý ª×åz&P¥:[ÒçG‡oÖêú,©²Ž;Œ5ßAì]jî¦Öv»¶§mÇ >ˆð5ìÙ†óϵ%F%@®÷/üüûÖVü³m±ùÔŠðõç0XæÁ¥gÜœªÏr]o#ˆ–”[0B, ãDiú(Ñ4: µ¦ƒP€ôÍDYÒ‡¥b¥Ýø×ÔÛÑ_϶“†¢´n•Š<—ùag$V÷ï×ýb#‚ >§)꣟áÃþ«OzŠ˜å­ª®ÿf<ˆÎ¯¸üüÑg"Ð{›Û[&³ÿõ¤ ’Ô.½ÖáþÌ“W4 áoÛÞáµîsà×ôZ[~WNwÞ(œWÊ.wÝÞÿúhK¼næõµÄ¸Pª;¶·uE/Ïvoc…¼Ú[o÷‡L­i0øÚÎuzØž±y(ØzPrW:JklÕêÒÀ›±ý oÁê¤KicÀü|@Ñf4ž@#“ŒÖFöyË¢•Ÿ¦%UÍ\9ài>›AÚ„Iîëc†Ïe›†k'SM®né“á*KŸ€"@ÁAr<Zél}Z€ÿþ»¶“Üo{ðõw½åÃÈ9§–ÑÖ–¦ÕÖ–c¨+Ju6à&²0¾¨Ø…Û'¸÷mú,e”–ŸÃ|ý5umÿ˜:…ÖLë³µ¶¤Ásï¦ñ&‚÷& Œó­#HBº€Ÿ_cžr­J l=ø¦­dJ­•€–üqŒ«3C–­¼W#øF¾>fÌýºÛw‚ŸoèJW4²§_Qø­+“ê“’íèb‘8}Ôd1nHM@×?Ju-P^9Ù›$‹úiÔY(ÓãŽb}ËÛ(RQ„²ëm ÷n}®KÐïN»¯W¢[îþŬXtö€žÑ©â0ý ¬Gº%TÇòaùÅ~¥ùq¬ŽÆØž©å4®¯À–ù Ë ö Ÿ]× ¯ó”=>=¯Á ovñäÍ :­ [„6¹Ò+[”Œ p ÜÞŸNÇ}Fødô`„ß¼¦'Á~3™Úr`XÖWG[ýî ~ÓÖÌÍÖpÒCz[Θt¥ÚpMÎÙÎÊí_ûéJ“‰a÷ÍB(#¯¹K·–Ø¢ÀÈW¡h†9©HyŸ\­V ç|ß‹ Ï" à×´„Z[‚{Ôù˜A¯˜ £OöÌ-ôÑé4 Ü¥V4ˆ|¿Ìó%s[†´È£4¨GV1A"AX3XAEòfÁ$ŸQÀ#‹Öi\TiCµYÉШ{#`Í­œ#9¯ƒ^@î¯iÒ]e4©9#j`®¨¹4ž”ÛNDv¬ž|m9cýí"¥Œî.wÐP÷½åÊÃIXoV¡Ôy€¶3¸1Ó¢Ãù°Á8?Ÿ]IDßÇë[ð*sÔ?´Eoû¬8Oº‹|{ýÛ ÈyÐ^¡æ—¼ní|Ò­Û *œ^Ó¾ìÁ]Ì•*À¬¹ãímŸ:9 güûü˜'( ûÔ8Ê’ÁÓ¨½ Ó”«¶"µZú„û|pÌf“I*—@¾\ ÒVÁ”šÚiŸ ‹‚2 tÑ9˜Çÿ ¿µ%ؤØzPŽ`·ì{^ûè^ +œ¡¥ ¶MÀ½pÙ} Ö~´3Àµõ M¤VyÓ`碀õÈblk¹¶û! Я ú ®7+Gõ¶f· Ä£>?ºÜÚRÿôúëM·ßö0='{:AÞåÎ#à4²_÷øÅÚW(°}…gÇÔ[Ÿ”ˆ×¥h½‚±&@ó±ZÌöýë¿þׇ/3ËÅqõÐíõµOÃŽýõ×xý1^êÁz#vÛzt‘1Ô3Œ<€ƒt” Øupßðýö´[-0s8<*6ê ;!æyÒ¿€ûò‚V°Ë©ZXÊÞ Qç¹` .±¡töN— æ_˹9(€ôÝùa<ˆLôGeY+üÓÀV.øœ–K°Ç•í޹ུ Àˆí¸fKîäeOAÎb šAÊàAðZêñ@ã eOQ¥Éva”Ó±ðÓ`±ç~ÍñÉѪãjmÉSÐBr®ˆçÀ“,5ž›˜ŸnK W‹H¹“jlË0r/)§\‡Qñ¹~ÒÉ)·–2äì‘ôÅèÑd[NzÁ3,£”pÖ6Bm„μ¤rÌõˆH›Øn””®ÃŒå»XáÎ@”Ò¶PÖH\70™BÍù[®QƒØÌF Å'3(¯p3zä:’ëÔJ‚^ÿ[¬PóW¨z:6Õƒªfc‘E1?õéÆ s GTŒñCÙO¾Âˆÿމt’ÈÁh/ŸŒ–Å®íD#Kz™ŒQs-«»ÆvhU‘¶‹ñŒwò/‘ƒÖÀâÊTË©m `=óp#FñH"»;ª›QÀ@‘˜;I’­F$˜±,;qsa`¼øM®ª„ûìÉ¥vgQ Y s‚!`*4²“yœÕZ©cÁjN2“ó×àð²Ý"p§¨‰bQÊJå¡ ¾êªØ³"íË0ð•YÌÉs¡ ™Ÿ6ñó…úú½FôY´=Pˆ¬h–D¨R:ÉóÁu7 øVjÑZ=¬…ë0ª<ÌÚöRrã`N0ò ¾°cU‹ÎBa"ÈA_¡@¥µ²ºP^Œ+jGtöNb[Ažm!Ý^:ÝAj¸:ÕÌ)61£(“ ]¹¶ÀLb®O¬Ã¸R:ßöˆáà@ýÇš„d•Š…Œì‚1µ£D‘:Ýûñz ¿/¾ÛUžæÜH˜ÚQÊÆê®¬[KF,FÐAöàõßË# 1ay]v«ª'J·Œúb¿ÞzøGƤkZë±ÁdtmDD&ÁÏ¿iû øö¨¹\)”ºì±ã™@üžÓõè„Ëâ £žÜKÀs­Óaß;0’Áidå[ ³ÚŸ{zƒšÉhə̶à¼j§«{â°_) 8¤ê\*i›ÌLÒÕ˯ŸÓ\¸ŒvlËQ-lÝj€©(ïet‰õò}ñ×Yõ^ÆÈ/}ƒ@j¹vn#àº70jž,îc¿w.±xÖ>2âŸP_¾PðRõ5x‡³¿€±æap²hï]Õ LÀV\el-¥&*˜YüõuWZжÆûRÁíj^Ë2rX]'j5sk²Zy]ð×ç·ˆN”C¶˜¸ŒÊv6SΟJ»`±MS”¢YQVÌ‘Á„m6ÏÀ'ÜxˆÑÜ2‘,ÈîY:9^áaY1Ââ*`g ÿ‚Ð71ÇÖõ¤Š7ËeÎB°·ƒ …(y@,Þ1q´ ìWÄ=y´N_4éªBÀÁÏhÑ”°Ydul¦Q_aüY’ƒÔv”eÛ+^:j³ÙgBÖ’¥èLGeVæŸNÒUÑHËÉ­„Ê΂åbÑxLýV©Ü%t6ú°bä F¯ÝU‚±=îäñ°3î¸û!8Ÿ†·\ (î6‹ºßYE\@δq&r‚{Ìo™]µ@´¶,&™ö#‹ª-Öm˜E,h¿ÏZÎã>ßÚb7—*àjq¿æ=HABÑÓçÊ\€-‚$fs§MÈÓ ÊZó»È%ùÇž·Wn) àÃ;Ë«WNØé#°mèÉ—‘¯xƒ©¨³âµ/NZ>ÙÌð•ÆŽ•,š ¥.…¢Mg,ZrÆìj3f$\âÕ©˜œHPËî¹G ƒ†NÅ#©8…QÏåä@|ü{¬ût¨í¬È£òócn‹z¡ž[âyÓžNvIPªÅE2M1u» {Té&ࢢñÓWkÁ°ˆîÇÁMn#Hàçt¬-J0[‰*vfRiíÜfçNƒÑÏ:Èae÷o$©¯IVx*˜©åÆQ ¬[ ¦’ÝÕ׎¿3Iàæç™Wm\-}ö:ËÚÀó𠦎¬àX.1W¤\éî Úƒ¼”w%[áT,ê¬Güü˜ÇVp`DG®AlçúÉBU¦XÔ€{ÂC€ÏΫn*Ôhú,øª‡áªÓA”Žol¹"@t€¼þ*XôÃéªü•[*Õ­N)_Ü`VSoà’Æ_Ê ,MøÐ!ÎRãj]e@/P‰fmÛ˜îòXqíXwi®äFZ[Aî’ºm´“NAßÑS7é&éèÜå·\óY½'Õáä˜Ü F ›æA§ ^à ž±ÑŲFˆ/Ê™ÇYÜÉëHí,rƒ…ÙQÛãòŽrÆ”"waËÈá“*')ÕãÎSq%`hrë@[Py:¸x‡×‰ç2ð+Ãà óéÆ:(1 {pf’Iù«ô@ÁûXgÐ.×ý¦]™;ð8ø°sÁÀ¤ÎûìA÷é 3£ê‡ÉX©únªÊ¸k ¤v¥,~ÿaFÇ YOõ ¹@µ¯§d³IÇpõn¤´+rgý΂ªõ»£¼òªß¹Ò7Ô¾Yk$(£ âJúw¢=<æ@pQjƒåCð…1ô‹DÁ^¹ŒŠ¾žíó,G~„‚ÁÓÚæmçGyK ¨‡¥€z­F„Ð$€A+: ¤míÍ”ä­pƒ1©¶ŽŒúi‘B9çCÊbÜB“jñ1ëµ Yt¦Ö¯Õl±4'Éæ’RÁä¾õ `PÖëÃ^;˵ßS·î¨†Ì1 ËÖ 06×?&ëÈÈbGc †/ă§ðÉï°Äá{ádvF™X" .[V™8¡,AadnöyÔkç¯Ãm¹: ®$–vá®/kè¼,œ†±õ¾~Mòؘ²Á¹¾ÖVGì ¼x.æóŸ"ÌÍÄå–YØãÖ%Ãë¾K»QÁϳÌÌQ¸ä£ÌU)Û;¶çangl;ƒÇ-FìôëF缬eû Ò¨Ek ¬rb_q¦v™‹cÍ&Ázƒ¤“ÄVg¹~Ãä,Z‚BÎ&/'̞ܛG&¨Õ<&È•4‚ßψ]G(hŸ¹2vô`Ü5%`EèiÚ`-èó>™¬/n¾g°|ŽLîBC€ój¬Ó³FÜo"±døúÿs«ª¯®€°¡‚Œú%ó])Àk©õ!PpÝ÷<"ª‚"Š+áX7øÌཛྷכ«½óàÛ €›QlÐÓ{ö‹;2¶(‚œGœ{´¶3Á6€ãœŽªÕ<üÉÙ[°ÆÉ,{/IdqªåÆÉ‰ü…78jΟâRä,¶nõÙ s|„£ÊõøW,[®«D@vÜe?¶i`°¾0^7•ù# ʺ-#´jšGW˜[&;Âêª-ˆ‹™,*+³ókZ 2i¯ã9dîõ`Û«/ð\0½¯‘„Ô8'Œ™©ß†Ž2¢²³Ç·o$i>È[|G‹ˆYgMy‡aïü5=e¾4£GÀOüúu|FÅA„'äÄÂà¯mœIj–yððÃg¦7ƒÖ¶+IqÂg»Ž÷¿Á™TZ`m0 ¼ž!¹*¹êQoÖÀ庛T ®¢Ôž°ôÑóš¶³ù%'ùƒv³ùí:]sfîú ÀÓÞ BHÇØI”½¨Û”n,ƒs¹ß¥®,êi±Ëzõe³ô€kôÈËb!~BÈ;e3ÛŒŠ4¦L“Jص(àÜãDØ£¦"¤Ž8¾PNR· §ŸŸ¿Ùƒóff%Oá½Ùv¿Î·øò¦ö¶Žp›ˆ÷†äÐÑ«Û ×KßN-!nYOgÚB‡›{{ÉÚ®Ñõ•ÍkEß³j²™qMjŒ¥ÃÝë1 ØQÛϳ€¯ÔáoÛ ŽnR[ª·ÔÄdÝ­i—‘E¦ãrmh›é–K&À4ß r*gÞ±»­°nŽJßë\¦µ]”–ýAJ}fÛ58ó\²‘,|S½sG7gØÝ{ nÉQ”ÚU|œÔ¹#/‡¼sC.ô»–ßagþöµYßó“·ý¹fl¹NÁx½ÔA‰íÈ“ç*¶0ôºNW 3Æ'çÙ.½>²|Æ•aþV`¸S ”³Ž,îzü`˜b“ª-Qî…¶Km÷--?û ð½€@·‰å p&=(:ìÂAÛ@~µöÉ›ÉõÞ&í1™¿j§nöÆÍÓChnjʉ®GRª€vÃ’?7š-²¼ŒÎå2jÕ¶sü@Í`£‘…6’:r“–Z6²“Ñt›TQÞ×û[òYU¤H'È¢&R™”jSž¥3?$¨/CUmë]@ù –©±IÕV­`nê? øöa´µÉ+¨¹Ñ^÷xÞÇ0­éIÿR+ܾ֯÷u¥’ÃÍlu¬$„”ˆ‹Æ×4Êö/mË!.-Õ§/7B:¶‚[¿6<ÌŸ3Lotéüh »)§¥xOd•‹zƒküîî—‹€ØÑÀ ì°ÑŠäV£`φ)ú ‡0ÏÕ¼Uµ „ºÞkü‚tà4°â2j—gÕ7= Ê¡/GŽD4ôۦ߂ ç[}.90ëÃÊf¨,Ù e´k3¬x™œYÂÒõi HíãQ­(b‡ÓºÅˆf0 Æ?¬o ¯û¸F/è¸ô†•% Í‹®û†çŠ0‡ýȬiT²¥»±Ê§€Ê9yÐý6aúúè[©¹7;Y‚}!k¤b'Ù¿Ëe»×‘#È7¨è ù.£2eyYì"7K†*X!œ¹™6Oríp*“qQ™k\Ò’^GÃÙŠfsÛ¢À‘FÿÜJZÝUØC~üd›y âÅȹ›”h5ܸëQ;V6¦Ü"%vO¿­¸óõu·âí¨ñÊèÁZ]€Á;#I{a_’¨’â8wÑP{œDvjÛ ¶¬=®U”9©µ¥®žºqµÐg¿= êh!ÃnÜh+‚Ô”º”µÐÿâË`´M•·Y¦ÀÔîÞSZô·Ìz‹'R~„ JWPJ0{oǹûÕªÃN÷H¦@›òÁv€ñÿÇZÆÈ6õü|¾/ëMNÕðbƒ \óYdd©¨~YµÕÕZõ™ü sP h;ŠŠïVk7¯¤+µ¬„‘;I•FZ)ÛŒ÷€wøòíూ79uä"4?àö Y‚ì¥ $?±P‡„¼+¯2:&9%}C=Ê]P?ÏŒ”Þ2³WÊ/)DeþöÒö, ÆhŠLª ¯Ñ•é/GZt—›¼ô–Á3gF>æ£Âñ•¤Òƒô[ISù­ZO‡‘kÓÁ¦Ç&õIGÆiJ¶O…n4Œ÷ÍGq 84Ò_JfR3‘ËÃ$±ˆNÍ@ØÞkÏ7Ĥ1‚ «ÐT™ÄVkrY0´Ç+|Ò%{vHÝÅßÌdûúhÑá÷²z[3r^LA©?Ùä…0Å.^Éø|Ø/¦d†^Œà¬`“.e¡“»Œœ" gÛ0#rOãÖ²ÙÌ,€¹]/ðØ‹'áu§‚Ü Ï†¹2^œDN´°<ò²Pð`Ñ<‘(!©} 2€µR"%ÔUG63cz´­@\­ö`®èj2ZW_áÒ†.à$ÿC0!8¼êÉt•{cV§¾äR ·•Á7Ãö m¸3 7@~ ÈñAn®%§s€)ÓGêe}×Ræžðè¼,ÅcuGÞúš!Ïu$™€õ*‹ªw\k¤ìáD?|Ò'uSóÑ;¿cþ?Ë¿þ×G‹Ïe>òŸ€¹Ð¤ž½Þž9ÌÄß#â;|$3\ƃfÏ 9ÑËä̃\wR|xtl¥7ð•´êu:^…‰šÔÑöf(/“^[êòŽð$‡GV$Úƒ#ÆÁ=Kô<÷Að®œÁ‰|[–*68rà¼^Øo§äé ›v·>Ñ”9Â’þ]åaÖÌ/ü> az[Öh{uöÜ!Àí =½Rù ¸|IéâŸ+“Ò ›æ€MdX‚9I‹kÃS±°;“—®‡±þ½Æ¹þ#Ësl ÉØ… Üóͦ|~ü¿ÿõ¿q/ËõóÿÄ9Ï´Î#9îÌAqðDcI–â‚Ò|kƒ9Ä8{~ÄFA#rx)X;YôMKv’Úà( ¬}7ct×Ë0Š&€Ñ}×ËøÝ!3´ ¥þŸ.·µ O¯ã\ßÁLÝÿA@é‘ò ùÃ~ýüº"àgÇ)a­· ÅHðß3,½eÇXݪ3MÖ¾.¥þðÉÛôرáÕ©*SIz  ¼nr˜i[dêxUW?UKÅ–ø)ÏjÆOçz)Ã" sÌT³`&SÓï$ó«tÁŠ€“­áÐÖ¥þŸoû0÷6Áz/,ýùu¼Û®ôp§iÇ7[•mcÿW¥àkycœåNü ØíŸ ø®u?ö"‘,p‹ÃþÆ–ˆbK‚º¨8H°î»é8ݹåEК ™¸Ñëåý³Sñ•À³€oA¿|ÁÚRc‘ºà€‡Ýabü¥Wíè9[Ýhp*‡i.bÛ_z[È!å„QÛàýIs¥V¾i)‡ã‰¨ÈÉÜó‚½Hé/5w\KÓ&îüt÷Yñ(„_Úå¹ÞÿšÁ |ìeXyû-YXaÏmIeÖZ:8oŠk]'‹ÍµA%R̈´¶u#œÚÏÉvkìZ¬Å“ök¶œìפÇú¥nb–ê -ÑÙø{Ñàþ8À3xŸ÷ ·T‡Éi'k ;pîØŠûǽÔ5À»¸¥¦ n4RëäÆp¾§co4 vêNít,uyÙï7_àçÔƒäqRÛÓòßQÐW66MÝZ‚À°ìÁÀ&{²´dì¬a¤¹Ë IŸç\S³!¼òj!ûf#¼²QKUäª0C Û¨j+z|‹n•<ª„çó߯!]*Øž¾>fØUþ?&¤Ý€©Ù䥿ž±?¢ßÉ(”‚˜4Tª‹Z+h‰æ ¸m9¶M@UÉúUîÐ>]jj,éxMôzÂñGŸo„Ûñóxf5§:“^ðŠZHÛÝÀôkœælo[à2‘&šLp]q9† æôî¯_F_7/ß‚Z®šjz£BÓO¿Ç|!È@ãѶ ÿÌjŸz#‰~ýþheÂ|qj÷·ª¾Ê'¨aÍWÕï²,gÍ ÌÍ뮜šÔŠfO¶GîÚ“g€{ü Ž;yǡ¤¨F½í· »pò.\#®ëý¨n‡ÔtôñD¬øÜ2š'G;ªyʳ"KÒLÕ@þçM±Èøújk:Ïäj&8ŸžàœìcpTz "ZΛ¼n­ûrÑêxÉü²d¶óœ–miµËvµìZÛEjÎy9OûA*ÌA®ÚI@Áò°³[µ˜Û+ärìm¿a¶œàëm Ìn)(¯Ö}Ý@˜ fìm)²Í¶yÀÞ¦}M™Êyv›OP›OéÈr,•’-' ‹‘5Zv(ï}Ÿ·n_ ¡úsëÀMéÕt9°#çµÌ{—É­z¹WcZŸqyÖ£Zrh—‘²«ûÅ…¿/øZ÷ùâÒ@>à¬×-IÀ´‡wл5ï§Ò¶Fº®N¥­Ä@MèËB®·á“ø¡ÿ3f¥ /”íMä¤à÷—¶µéÕíU6½V ¦%.µ¿?æÖ¤P™Ý@®½—Ùû€E4,Ðëd z`~”‘+6{@¸õ@oûÚR.ö*×áöÅ´Pl–œG]5-”!§ ÈcBÛ*˜=PÐßëó" u‹# “ ‘½½#©m:¤…©U{P8«=”Õ§Yˆ8ˆ#\ó ŽªxQŸQÊEØzPox½[ÿî‡uoû-È/ÁÏ7¤l`¹ôØ8~1)ÚV¿Øþ¤36A|ÆI]`Ûß] P;YÙ%ezäÜWC¬:í8Vù¨É#¢K/íëÄÍ–µ/\xaJ¿–`P£¯­ _‚Y¸ƒ ùß´U©Û¶]ß±‚sWRðÛ7óAœ¼M½-®ò}Àke£xò¦²¨´¾î­á›5Ú ãTº*|S'¨ƒóVõí¼ýaåøÒûz[9¹Q¼-ÓÿL[{[þÐ6 aáŸnèjã®­ªµ+y]™yWŠÊ2ým£LC_v9ÝnÙ­>ÜòV%à .ÿI£&ÜW£ wÍìH“ÃN¿—‚ùÁ ¼5•µæ¬È%ªS.×ç]`¬Ø#{Gúsu-®A°Rkñ †5„´±D’d/i¶prµLºOÁ¢Ž(H©ÉŽÐ«1Uð™(Oå„£žôKp-.¤¼R¢¾UPè¤B)œ¤¦Ym¢?U%ÍøyòO–ö^ô²¡æÿòž'ëgÔ…¢‚xäòÑ~îà¿n›¼»D¼ÁxXFÉõÇÒn"Cl E;ÈûSx3ø…·þ߀ß$Æ€bî ¤hä \Ô÷Û‡€p'ôàù¦’«eé¹h ß7?ß|Ó¶õ Àº^ˈÕMºõV¤²e{…šºIËÈxò<"Î…®O@Dš•ëX³-b×ÄZ&Ô²VœVXIô?|ÀèAFÚ‰ÑÖâQ-£ŒƒEé¨nކÂnÝ0s^ü…– ùL—†„@~¥ÕÛRož{² WSqçHK8‰ØQPZê ü  Z–C) ëÔ#Uì™úkLaWäP#.ó²2^V‰ÈŸÀ‘é— ÎJS51dÂØVLM Yr51šÔifS7ˆ¶º8áËô¾kp¾rn—aRÞK–\ÍÁö õäaõˆxSîá œû–‚nFýëcîM®òÈO®fÔ熪 oÔ½ MrìÖk ¿˜ZÊÚîMw´l};+ u0+K鱂ó. à.TKYRâ°äQU'Xž uÒ}s¨Ê³¿9~ëìÔSº°´§·|™“*>]Õ‰Œ§¡š¿Ïèª)¿ßÔÑsb/ –Ô%…iÌ ,íIø»U@²gÿ i}Ûƒ,„ØöÔ ¸j·ÄóBØ@Q©N=.®fÐJmSƒGÈÖ—–+ª«ç-QÁ¼%*(·ÄT˜U;O÷´sªîd»4h‘ͼ¶Ôåñ~µKƒEäß×Û­C‚› ܪ:lÝ~7-/K¢·& ºei ¨â¡Zµ/iʤj_Ý/Xe3@TZe½ùÕö›g!¾«? C0_{ö¬z.à–eÿä]Iø~·6X°u’V±-ê4þj/€üŠì­¨Þn,¢¦scpoNÄûf8[~„Œ~è 'bmëcðûcnCCº ä²È%†kšÄà (•"s1ò3RRŒX+r9=j?áô˜6: ¾k Wˆ€1çßGœ^”bØx€}~Ì-y?ìÇÖ;=—Ô2`ÔÖ/"ó”h×–¬‡™;têCUÓö}@ûïkaIK€ó·km äì‘¿KùîÖÖg{ÛÌ þç£`Íöº£k2H•3£Um}eô7«E(Ÿz cüÜÛ5’Kú›­Á[úï~v cݧ5´˜Enï ¶Õ ®{ZöêÑiq,©V7«ÝÖ*&t?´Å½Kâ…¥%¬ŽÓÝ@œ_uGëwËR.¯ SPXš&7‹Oü#èVýÉÔ!z  xù ä&Õ”éºÍ‰.\·9Qçë>©†S¹{–áT4©eú]@*ÞuÑHs Íò°Ì-3¯ä¼¶èæJ›U#kšfôJSà¢Kªu)éR~Y\ÁòïH©èRÒ먤ÿÕ{[TÞ¬ü;R“I§‡:(»º¶Mg¸Tìâ+„€Ìç­×•tàúbR‘N óR³¤nEZhx© ³ŠY\ê]]’Xµ’·LÑ«šÄ°â÷,?œðÞ+Ü%¡YÎ1¬qÉEÞ?B:7ô#¤'¥WÒÆæõMym~E~ñrUÕÝjk´²æ\ùÓd&7©,®>²Ó&“¶|@açÔã¦zPú¤–xw•¿‡M²Xçó+c¥=èHu.÷ö$l1ýçfnLCùô4ˆ6¬÷r2²ê¡DÖÝQ@(ŸsÛ<ìsÛ¤€É:§zgµ 5·ãv«.«ŸÜÀE*Àÿ]ÛInõö(DåÉÃC{[gZÓÓK9im LíªÀöº%·nÛeŒTÝ»ºµƒÀd–ÛvÀkµôZãü Ð1ÿ˜NvÑéK øôMœr©rXQ¥‡ê|6/5•Ì„šMýªÚR%/]ŒŠþ_ÝJJ¡cÂöyÚzO¦S(ï_Óï¯ÿ®¾BmŒ´/ì0îÿÉëÕšBdÓ¼Üà8ÇTIT{ŸƒÊןg‘Ü>j¼¶Ïc›¬òœTà Î[ËV®$µ¬AB5o2" 6C¹§Ô^¨¦¤ A7´òQm!TÇZÛóR¤ ¯Žy d)Ö+4}ݵ̬¶ÍG{+=˜^–ÇOyXh²ûÖé+Eá9©3EU«<'U)HU6Ò+ÚŽj ¥‰>¯šQjÞª5%VÕ4-µµ*bVʦfl®TìVß|‡ï‘»øû¢ŠA ÿJylºÄ+KÉk Eè0" :(= ˆG}~|Û±?¦7˨íXúîºÜt|õ7“¶¨úÝ¥ò#L+øÛ¶ß‚ 1Üôœ©âÜ@Îq§©–/˹¬Þ°¬! GÕ´Â*È[.u£R@\ÔfOgÅs·¶ß‚r,?6Úþþ˜ûÀÐm¹–-5á_‹¡7¹oˆ§N±ªÌR—Ò6~Øaèû“ëz eÓáÚøýѶ@H–VÝæÚ2¬/-«H??bl¤Î0çÄ|q“©¢ ÌµÝ!Lܵd¹|;YßÖûrùF@zªµ¥8æUnºÅuq§_]· ñ«ëîаmú¿û>"c%õ²P£JÍ¢ŽìÁ' $áY@¾‚¶ô€ƒèA’ÌT½T•:µjÀ¶rÿW0oÐ Žt –bwšmvëwåÓ>翚µå4:ÕëÉ_ÃÞr^Y ©ì"§9Ñ®Ù`.´ „¬ËþHšÝ2Áða]*l´@tÃB·•ˆÐ²t ôÇ!¤ù<ƒ~uYuP¬*¿à„óï Ê-—â9’¿¸œð Ÿ$bÃT@ú/OãNÍ(2¸? R@Áù éò>‡’¯Â­ÚÇ =ü* CôÊ 1ðm÷¶î¨æÔÀà RÍžeémz×;ï:Aú¶éònméo=(pÝ%ž†j Äc^Ä=Wøü˜Ûzþø˜['tIo+Їk):–1P§4gP6¶& Öhpel"¨†è£XõŸsÇIˆK«(i»H<9 VļW‘O²9UìÁOˆ²¹»MÌ‚ôÑWD.Ì ¼ªàQæÍ0Ââ÷ì­› ÑHž:‚ñÂE'm+/ìuß™mß‘ç}Á”…tµzK ˆ"_’ïf`ø•ü!£ÀoK˜ëpš²Œhû†A1m|[\†ïɯ°“½,Qe‹‹‘ÙaOåÇü„} ÄËê^J£Û÷`‹2R8 i7¬ø‘—M#%lqÍ.ÀÛþžŒé©”¨¦ruª%CB†Õæ¾e5/¤Š(ÑGÔF'›Ã >Îu Jª¥š=(8îé ‘ÐÞÂpŸ˜¼&rãþþçpDé ¡òt¸g:ßAº»áƒE5ƒA™\šÉ¢ì ­-í0bÇ(W·ÉaÏûß/uwìj"5O(ܲ~´¼®ô  9"µ¬Fí¾®mó¾ž1A¤ÝGoËbqZe–cŠôQ›En4«IYs^›Í¦$¤ 19â$þ‚݇A*GW—GÀ2æ’ýùÑÍ9¦+#,sñ;ˆ´}vëó£·mF"D}÷ A‘=x7=¥€z]ÙzY€´}}Û–Æ/|&tÒÐ&6žú8b5)›^›µõÉe~ýÖœqûÔüJ³`™[Ê,™KDAšGšµRÖM­†¶ô¹H%Úª–3Œ \xܧÚÞËØÏŒ÷ÒÐQÉ€è02 \YÞ®ƒ\Ö Ñ~ªtCxÞï”p#=–Ä>^¦øÌÐÑ£NÒ³º7€þ:™óz¯Ž‹iSžÑOJ7hž*’= Dñ©•¯’N)tB×.ý¢§'[Átš—~×ìVgÀY™Îø…JÔ¹\ bªñ‹–Ž)þñ-†höÌ*ŒuÏkyQjE©º¿iûÇGW~3£^ÛŠž­ ;—¿&íVà:Í-¼vaa½V) ;@ý¼a¸©›®uóº†ût«’[‚Þ)åBðC[^‹åcé­V^¿®eMª_öþúhk¯…ûSñ6èµ:©¶ArbëXm¬Lnƒê›]ñ\s¬q3,úk°®×ÖAù*‰­r“üZ/Æ" îÕèïàƒ•[ïÛ ,©IëýcÛoÁéQ¼ÆÃ ÐÛî(D–Äâ½¥×™íYs¥,jˆè J‰¹ˆwÙ¬ ¢R¥‚G‡¡q¨€*'jEæê“g98H%õ±3ËMgZÖC—]V<Ñé-r-i¹àËëÖõ¾Ê»ô–YùF–XUr‘Ũrçì=Èõ¬=PÒ-> àdŒè¯Ë¶R¾¯Æ@Š ª©+¨ ßRÿóÖ6¿Ø?‚Þƒ÷Þf Á¾X}[oÉ9Ãé‘•,µm–kÔAD¹Æù“gmHÝþPK³K5…û¸óØÛ¨[Ú?.ë{Êüž3cU3ÊVð‰ó>C¹XK¶i!Üq'ã¶­Âfw]Ãõ­¼–è¼Wg«):ÛßT Ôê¸î~sûN€Ã̺¹:],#Ë¥ÕLnm ¼®{Òmì0»Îc>. ·Eóèd‚_½þŽ÷9=,ëËÔ°—Ù‘ú Ô˜*t,_‘mgÐ+Q@Áò°’ú ˆ¾RE”žu‘úxN®Çj"AÉ`¸Ç¬rKÅÈÁ.gqÒר¦¶YÈ[ ÒÖ†ðjÖuU5\AÔ"§€‚%–©@Ô"×µp~…&€Ýº˜Û¥Þu%Èëá¸}X=÷q½…cýÔö[°õ—ªÝ.×¢Â`ifÃ}9óZ3$‹ÊÏRQ=^l£Z~¾?ì®@X1;ˆÜóT>°„n™r;¦d…²¯OPö”í[–Ñ’ú(ð‰»i\C‡Y šÉ «we‡u˜9o} fá:ºÔ0Pd¦r¸ã¨l˸ÞÏ+ü}Dyg[µ·fËw,ÚF<“5‹†a9ò{&ŒÒ‘p`*Ï}¢°3øÜ.Æ™…u³4÷½Â×µ.“ài:1Ø‹ªÑ3Ûªá$[¾ ÷`V\¤dx›Ã»ƒæ•]Ê CƒÏuŒ·¶¨šÜ[ÞÇ]”…KÛ›À0u%Øí)·ƒ+™–ÍÀ=KCeü™Á,G’68Ç5†µnxu»ëN#Ûþ0Ì£ Î=hm \Q¥~=¥€’;˜1¡=8—óy{ÐM©Ãj‰"à‘pcµ»8Êú1Ôm¬¯“õ¾8ë—°Z]‡R®|¯Ï{Û5ŸÚ£Þ{ǤmÄàýÞ¼Êþ(€ êUÏà¾^U¡9lÄ6^÷–,ªÁŸaKFJÚ6§yHëjÂ}Êì®Ý ­º5 v÷_ßzÌþ”Žîrp+róåFiù,ðœ2w¸YyaHyXs÷æön´„û™ðx_Wþ>„‰Î˜ü¼ÀÓ’Ž¾Þžïz~¸_w§AÈ–ý4x9.¶´_ªùV%ôáÕ–=ÀùN±½äžÓ5XÕüº¾˜Ý~¯ÛyÁ×ÓM^/%y[ë—’²Z²ù>ÛŸêj(¶²¸„Ò¨E˜m—Œ$b¼ ˜‘~il/ìaÓÊ@ œ!^ñÓAĤ€oÛ~+uêÁ×G‡_w¥qÞÿú¾ÒÙƒÇ,šÍ–!ãRF‹ºcCsîí×ÛþðÌͯP&ù ?€n:¢qÑPڶ̘ø‡(±2b¶TìÒA—aSª‚eÓjri’K,lZ}´¤²xo+fÌol›j‡-»žÌoéAlÛpK´mZWkd¿£ï, L“2•Åè[“-cGVbuÆ6Ò"ß[fYú¾Æ²š¤‚Y¾S»÷üœƒk»w¶6UæñÜoý—'e&}¿4¬‘`Ð8ÐoÚŠï¡ZüD^zÚä)P<%5¬Íȯp~C »¥öéç„ù¤T5/KÊÄ^Ÿ:‹jdÿêÞuç’å¸{‚~‡þc@’ÝTÞ/6üCúd4nc Ë:VÃ0r‹ÖÈ8Mò øö®ˆX+"kïý‘òi‡Ô9±ëËʪÊKäŠ+Þm€ˆïñ¾Ž8…“Vïpš½·AÛ=º­ÂøöáñZŸIN›½w‹·:Aë›ÙޏÙ͸#Çr/üXû¢Çz·Â•ìAjZׂKý½cSˆ‡…‘ïàåµaômél@/1ò?m¦il[¬ýÇG³ÑŸ®+¶ÂØ(έ46¤x,_:ÂÉ9£º7óÑUz>GŸÎ;÷§ß=}m£pÿk: ç•aã6íÐóŸ3þ}ùeÓŠ¦žê:¤mÆ´ªý¢Ô§-!òÐŽ%.ZÅ•l KDì±—­†QGås|Æ»ñœ.íi,• ` \ŽpjˆO$\FÍÚx4¶Ì™©e6@sDŸ/£Eñ<:Lù¶?.–-qÞÔ¼‚Ø£qRcß>²d£n€bÍt0ÅX¬^¡ð.ÌëIö|7 ÂÞ¬êÝm×iÿ§1”9ä8𔀽E?ßb€B¼³TÕS¼½ø§˜ÛVVöýZ#š-?Ët¥ñ±ÛµadˆûfŒxú­]½ö3ÌÙ²“õf$4;5ð´æf@ÀŒDó2o+.:]ar®<nq6¨QìG£Íl@cjÖ褫Õ="ÓÇ­_³dI² ‹qZ|óÑx-yåc`åÖÀõ!4e]Ðr ~˜±Ž^î`»7 Æ™;N="–¤Õ6’†gÉu—QÓß# ÍÂŒ •GªÏF>.ŒÏ ~¯Ý3[R×eÔ´þn[õX=¼mÆ¢Ž0ôuÑuh^ë-Û ?͈މQ“:Î(òݸ<£wJuï3»ÆFºÄ$s7¿iLèQxLRÿ^òÿlØæb(3Í3òh«¯7gÔF:ßÐ@² `„k—j&¥3XjÆeÆ3zš=‚zï­^{71\1£>ˆâE±C¦H¨¬ÇCº±,Î0´\Û»¾ÚóqÃxí,€/E¾ÚÒ!”nLQIØ„Z‡a"ÏÕmnf_¶qÿ}x4#â~7"6/ÆuØ?ŽkIûüfd«’8Qõ­œD1›ÀÀA¸_ zÁ½U§"ˆ9=Ò^oàdˆíÞ8æAtkiÉÇ#8ã]ã¶ø¢U6 ñãÍLdá]ã­aö©|Á(¹ßJoO ׆1åúhÜüíé¤K%ﮩŠÎô÷?7BÎc×ßܘEQà$äðö¼6(9÷í6m¥BaÉUa$R0j[O׆Ñ[½ü‡©XÑ{=¢ÏóÍ>=€"º+Qè3ÌwãÑêiœ#ϧ€ÁÜov3Žl+Œo¯M¦öuÂ=·:©FG²t[úáéZ¦¢] `ŸnØÒ Mwpꂯ׼Â-î:^v „]_¯¥rG'¯;â™ÍÑøÍ×F£7#ïÿР¹ûµ4Ûê´Ï—bw„ _Yø:îIëÁÞŠ§35ýïEž”°ì¢iׇ/á‹BéqܽÕDïQÎ,ÎêF;ÖßåÂŽkCÌïSÌ×'ä>Ë™QØÅ…C6ð×!d²QñÖë Ÿ­†°˜ã.XÃdÔÑuñÚ£ÕÄ ¸Ûep؃v|èö $é¦+hVèŠDvèrçÆ;üyH þzÈ |KµâC‹\Ì ²ã.«õŽ‘H¯ë&=7pô€×ºjѽW8ºw \bÔÂ8§LTÀÒ®IEA› JSŸÿÐå ß_Œ=BgMíófÄËŒ·º£ðbÍÆññ7£è7a¯@{ÏÞ: x(]Ãð̾›¡8ãùnÆc qÇ0ŒYàÂQÇ<nv3²[0¾}x4³úП6zQ÷{ŠÌËnñaâQ3ûpCC÷8u êÜHáuçN5~â`Ý·ÇSª"~ºšÂ >8‹'‘¨Œuß:|öSÐøðïCOœY§?ÉA–ã sœÚâJ?³G5cvžXœ§wx…áMr~SE^ñ›HÎ ¥åšìI”åwÉ]lצW®¹* õ-gjÍ7a;id§\ïF|(›oäf16è`‰±W‹j4É–Ih@©4úN.³¥z]ç“ë›Ø÷ku"üZ3V™äÊéb-Ûñë2'ÑÊüh6«‹1òf¢òeëÙÈטö×eÖ“®š{·p³Æ€ÄXeLÿðtmÅP¿¯}âÙ˜:ažË¬Ý0ßà4S½ £õÖßÁýZ§ÉH<§3½ŽvÅÁ5Qð£Âü(ãá}ÁÈG yضvo »<Ìu«nÍì}{è?Ì÷>u£Å=^ÙRá2šÑMš¯±ñVt ¹fï/ìlÚ.×6 p`ú"äfnR}ÇŒM1š£: a|Ãx×]Ù˜-´‰Üc¡°´j‘û¶,ü¨Ä”Âú!ws†‡pµL²2&è«7£v hhWÍ%®µLí‡L*]Y,.¬u\‹ŽÝ¦÷i<¯Ü®éf©éƒ˜F<—Ôé7­òŰèØeVí1^›–òªåÍêÉé2öksQ^¸¿nkàÚ´vm÷k/cQºµ²–Ša¸×­®ù~ÛÇG¸N™HJÂ>FQôI‚U¨ vö¿šPôýY±Ì›±ã\].šsh›ø ºèI„öŽ.×.J|íË8+½×Ûµj6ãÔH‹Leܯìçôø\ÇŒ›ÝŒ|ØËõ#F¯…ù~³›‘ïàš<îLï`xðý˜IrúmF¬Dl ̾”Iñ#ÄaÙ»ß W²vìXöâ%ÊA»?U¼€/3ô\ ãÅ­Æ0D¦âùñip³ÇÜ/üxܳét‰›Ù·‰0»×i¬Nî¸õÁˆ¯p40 >èW~¥³ ˜ém÷:ÚÀ -®ý ¸ê8<6†ì¹/ŸFÝØÙvm[²é}€ Äð¸9 ñÊâ£_«j‹3ƯîëÌ;×NÐ|nWNWA9V¥Ûµ\·Í(¾îcתš4]çt|õ¼Ü(ìŒ6‹P‡òã_‡ÃÕŧÌ3®4ÛÒ|©û__®™&lWž6¨kßl®Ò³QDÕšŒHvÙòý9¯;ï=àkÆ_ í5õÛs_¶¡j ¼ÎþúÚ)Æã'ê×V±ù*ù1/#äon¾_nÊ,#ç2NŸ<ýO©S¨Šç÷±Û»mB×Ò³R GUc¼»73'ëÍÎîífœÏ3céåi¢æãq£mzJfÔD’»½!݇јÞ7V/Oüüdv-¤ÖØ[1N“Š£+žà›¹­‡Ç½–A-6ó®ñ:©-oà}ýéfa<ˆŸüìíqm¶q º¸òö.£ö§ñ›Í˜L=™ì]SØü FW+̺í7cÇ¡;–%Ù–ã,çËÝÙªï†÷b\‹#æç»rž<}G>OGW9ÿý‡ÿâßÿå_ýöwó/_÷/¿þÕ?þöÿëËôÿíõ?ñûëä¿×_×먎É&vI˜é@\h›¼ót=1éÊJ×&ôÄέF$ŸÏöñÃóÕ’(ã ûâÀ¾ö‡¬kE!J£Ñþ‹´•úÑ‘\¸›lP ¤]-”ªíNƒ:Ÿ:Á” û˜tÓ\,‚žq“b•:­$¹5Q ä´©æ“M»ì2Ä®šÄs'ÒP MXQL¨8qž“Ï[?xUb¼’MT!wÛv¯Àí­FÖõ4`ÌÉ×å®!³àúå^Ôƒ³ðÇ'©5ñrJ¿3ùŠ7oâaaù?¬†…p#úyG­/é2®Å+-“КÀÊÄXà\_Fø“jìóɨíF}& ­[×-©.Æ2éR]o£V·L4Ñ JåèðÂûP`ZˆPG|±M° ‰“Ò¤t–g‚«™‹ÍlÙ~RÁV¥âƒlbZA7Û‡¸ec[Ɖ L×üG41ö*GÊg´«!$'ƺa\HRzµã²‰ø!î7ýžÔĈ•]8q-ZØR&š.²Í„ PŒy˜ç:òqM={ÃÐ,*™öâÆ5Ó,µì2z¤:ŒÝj²‰bký:y£Ò-X „¹R鳊´˜~Ò¶%IYÐÚ„—1 ®ÎËhóÃaX4Ò;’î~ð«_dʿ̩Ê¿ç _fë¿Ìë¡`M¼£ðR[àI‡€M¼P-x©oðB ÁšxG9á¥ÆÂƒÛ7ñR½áê¿øá¥ÊÆûÚ__4ñB½ã뇰‰gµ‘—º$Ï&hâO)ž¼’F±„+6ðRqå¥6Ë“Ž ›xGõå…>̃’ x©9óR›æAÇ&x©zóBçIK‡M4™ì6Q~hç~5[Ùþ€×•0®ãÐ%O®àʦu¡¯^â+-6ïD©çfPŒ.YfG 9阺ڭ§–w#˜bœ¿y˜ØâŒ»^øÀ’±5ÒÀ¬dÞâµå–69UóÑBYË/ž¼øòæ©â‡úÏÊ|ÑDFRlº ’×ìF;VÔÈ^ENçs´A]¯Z uôVêó©Ýq=6±ÄÇ‚>™¢"Ý– †ì*.LièŠ Ù±Ž&òæ''Ò‘Vs^ôñ¦k•kî”-P@©=ç°»í¸ö‡óÚÃþù°—m”ñl«¯û°ûââÙx±¢,w嵡lâ*оÔu¡@6AéÎÎQ%¸PÁµž,•WæócÌN­>r?ÔHÂË+ðvÑÌ›}=Þ$•UGõ&Fá«L=ÔÜ7õGUÝÿèE¢Ø?yHrÍŠêt¬ õfU-l;¾ãø+bÜëÙ¸“µ›È{a/;*S¶œ¸AO¹ƒµ’›‡NȈ¢D÷N,í,SGÚç:lઠ/ë+<Ôb`/+7¼Sãá¡D4ñ¢zÄË:O5)ØÄŸ¨`q–º¸Å`/+h¼¬µñT—ƒM¼SÅãe½§Ú lâe%‘—5Gžê“X/«™¼S÷ä©FŠ5ñ²¢Ê;µWžê´°‰—U]^Öy¨M€¯"•eU#•ÑÔ3còJܺب1P9¼Í®E§àbsÄ8X‚yÙçUãkMØk¶ú8÷+-O½hÎSÑ6ñ¢ÄÏ‹b@/ Yï”zYè©x›x§ÔÑË¢H”Ø„${µ¥Œêmr0« Oê÷B©F`V©¸l‚>Åð©q4GQ_k:«ô=ÊkN°÷°l²¬al168‚îoË~Ñ&òrÎÒf”âZ¤L@MÀe;V‰Qœ•ñ¹æk÷®oˆïh¶ŒIÜÏö 1ŽÁh½®oÞÄ*QBP.ÅØ#ë/Š8E/øC2†çý†7#ocôâú óhûÑè½…¬¾Ž+ÙDüpÜð4Ρ!›»q¤Ò&†ž„”æ`üU1^»®×ö¸òúv#EùaÏ:Ž>?ý°ÞU|3ʲ¢ƒÇ•ÓòÈžº'LÁÍ‹/o ghU/î ’j5\º1ú+£k¬†@̶Dü]$öfœÙjk(š(B(PZ“ÄF,i^Œ¥àݬW$u†d^]÷ÙÄà2',ߤÌW1*Êm4áÍéæJË$³_ˆÊV7UŒ-™êز>¦“…¥¯ ‹¤'6q}Ô‡‚€—ñ:RQÍ êë:.XËÆñÍ¢ø&s6ûÂÕ«f,ž,¶X„Z~À¥ÑúC¯¼Ö¢jœaL‹F?é˹nh€PÜE ãmd`y“ådè0–­pø Õð$Û<Í ãXg¶Ó¸ëžö*~F“ˆæ&‹ß˜Ñ\S»:Û›(Fž0ã8†Õµlâ¨àòlYírF¹áe^³w•çÍ^~H“/\56zHïRcYx:Ï£‰–&aÐM´ZÚTqß…v%<Õ`ÌÇ'Òù5bÔuÆÀ`“)£ä@™Q ØG׎ÊÊÄÛ4þ‰ªŒÃÞ;,¥âƒð%N}öòžëøÆkP=­XoG ~ 2þõc»\Ù°ð£>u¯§Ù×xGsS8¬ó…R ÎejlTlh_í½7tÝn2RæÄ8QQºÇ\8½—y<àå0 4éͨG«øxü!1dK »ØOz?_ÅÕDö×Ü+ 6Ÿ/p0M3?šX„¡”bú9~­ºÅc­íåW7õa;W¢†Ù—,ÍÆÊC®/ ×è,‡}­ÏM8 *ZZÒøÐ•c3B*P}ñ«UöÆ~0Õ25æÍ«­D‹5¤¤FEøxÃaÒÌzC£+ˆmæŽz|*PjÆeB/¢Šhéela C€ž†S‡hU³:j,WêÁ7FqJ mãµ€l3¢^òek%·°}õ ¦p»6l&‘u·Ná1¿âZf'¤ í¬K„mVΊ¥®ºŽ̈9÷žq˜ÿÕ›ˆŸ}öéÝ÷+!+cªšNà„ëÊX’ÆÕÿÂjÒ³s˜²ü±¸ZENþ€&ìý¨q¸1«Ç+Æy¼7WQ 6µ5"Ÿ½ÛjŽ›™Ç;;‹æz/’ݰ[d•MèÒ(Æä¢RjÔÀ×ñ xBäÕ~ñC¦w“MÛZóõ O2L5úÄÿã=ÕÔÁÜŠÏ(2,FôYÏ÷Fáj¦w]„å„%vÓKÞ’Q˜Ï!…‚£ü X/†$G¨omÍÆPŸ‰ê[ñyî»,—‹ xe2`õ›ÎЙ-.pޏB¯áÛnšªG$òPËG2”•i|´ÙгGc²d”Ó˜¨ýø*9SÇ” ‰cêP[#šÀD Ù±M¯«ÑsŽÅ‚W†GÐ’ ª,bßg»®Û!WjÆi\y,D³BNÃ]Ö2W1 £›ˆ1'u°Æ´?ÓÝM½lÆŽE&?X–ºk‡ÑdZdÃŒsßzÑ ÚžvN“ü0‹O©­Ðc*uÏÃx´M³fœO}¹WṟªCG&v¦aÊ¡O#ÆË݃êÒ_nÛ.õqžöcá—ÌÝ»V° Ó·Lîóºªñ ]г ïÖ®nØO9:U-3ãåÃàÊÜÒ8š0N¨v¯À«TÊI3cMžÉö6³¢ ²ùnh!Ý÷ŒÓÄØDü Ø1ü£Iý9¨ÚWBÛ(zQ!öâJHbDì>´êÄK[Е‘½¿o¯ç«ófôyÄH½¼#L/?\ß’wª2cÕ®K9‹J7¾b$zwS~ÈͯVÄX8Ž©Q'™(MYñoÂXGòÃÀètÿVŒœ§7c¤dé&H#?§þs¸ä9ãÐ7wóKµ¼²•DÙ9“)%É2ªÙv–c-üʨ“W»LØØjLTIÓ›EÙvwÉIh"ÉAlˆϗx¨§Ö[ ÅB ã‹Ñ„T°§›ä‚`ãÖËÅÊÈvÉ¿Ïþƒ.ÿ¡hF«0s( nAšS‚¾Ÿ¢]Œîœ?£"ÄhIdj4úÜìØû¤¸Œ2œµm ¨‰Lo1*ËŒ¨S.]ëÝýï´È¡9=K#k¢òWmâ½ ž.w¶Ò4f¬Š÷Y‹ØÊ ôŸE놅FÔrpoäPz³PšQf°_‡B[eÓ@æØV¾µ`y)þÃ' ÖmcuÝ£Û+‡‘Ïгóxuƒ e%éà~¥Ù‹f~©þ0pò|~è6{6Ñë"Æë¤t6º˜dpËöýÙÑ@¨øÃ' ^,8¹-ndÛÙT~ÓÏþÿBtðèÙ˜[qµÓ¼=:ß^Bª´~-TŒÛXнy•p»ÐcDŽ-¤,ƒ«ÍʸEÖI&¡üZÕy¾Ïö#ðHn^FÍ­yߨ™KÏM„^d° ½H„«î#¼2˜ 5„f¤E(Kœ1òƒnA!È gXîÎ)ðŒC„pW’F)™‘ø4§ ˆ’®A<¹ï´BSÑðMì´Ÿ½íh†2´‚FMÝÁfȲi¼Á¢9”B6ºføg€€Ì&2¤1ü‡G#%voF(>7AMà I‚ÈYÊ-Îp¶4*Â&äEÎrs…ÀTŒ¦& „i’nÞpHýikqY–4#’³¼NwÅa?(æQWøÅ‹Âć`Ծ剆M8CT‚HtuîðeìHì¸gÉÁíä¤É),êÆ«“­F²Ô)Ö ²ÏGRÆóŸýT3)¾1©vn‚ z"ýÌIâ×ö‘Nö8ªvÈëh‰MÀ¡¹šp-<ÇùÝÕÏ4ߨ®.ËÁjºÆÞålÑxpc„CQæiúrŸ”³o™¶2„8ۃȕ³Á&$K{ðêúËXÐð•‘û,FCöeh¦œæ$çB´í‚øÉ$oÍØ6³Zs£éQyFÛ»~@Îà^«â~µ„ìwçªÄQ@Å×W†Ä6SN—òï+§™ÕPÍÇMáPÝâUÈæ50sÔŒ-Wœ€cÚJãÅ‚åÑDÎþC÷L~ÅÈÌ%OI’±Î^h¶yü€ö UリP³75ÁuŒ²……dr]Éz§2¨$4›QsS>1«‹¡¦œEÖ +𱬉Ó©_Ó ÆÃ5ÊØÑ€ë‡Z{(­F/•·)ƪÞ4bi{ñjÍѰC½ábBÔžW8®þ`þ–üЦ_½ùtÇ»@ˆBö–\<4GC$ÀOÑ–*…{’õ¦QmÏŠ3»VÕJ [J3ÌITSZ &ët=Òd^O´píIlºdO3JvÔÕÙîµCPxŸo"ž=kò:dÙN“bDÕÍ.㺞ɚDAmzùÕÙ5à½fÙ4Íó ÆÙBj~qŠi|k…[b\ð J?Ÿ"YìbĶ2‡äd|9G§1è/úƒE©å–¡œuz46ow̳×ÍOPá‘2m*Y GxN™Š’áË‘©9lÝÀP ¯˜qf7nkÊ·&ü”UcñBÃÙkÑ¿êEÍÇÏÆ£ o7üô?ru{Õî{ïb²¢êf¬@.Vòº{øqøé"HÛ)ˆ=ü~Íð¾*.3<}qªÚ>žC³PìR¥Æƒ±Ä†ê»#yç£ ÍW7›B0oÈ…¾÷^Ì"…øõƒ§.?zê½ Êj›b’£cÆ w™WÉ„–]qÜ)y¥ƒU¢3¡6ŠÛË ÑqeÌHá÷áb ‡H¼*°&BÑþ&¨O=üIÀ!½?½yEQùâ)Gm†8•ê}Ñ<À ünÄ™únÔ•4šHiÖã‡O¨.Kpà0rÌß›âAdü€™.µ“Óæ©|WYµ¡Ø0` Q·¡ø*=&S¢îF–GÈF'`ÃÙJM´Sœ;óVDn¸L! ˆ Dœ£µŸ7rHéGŸ?©XÈ2rý0X BÎ~q}CÏëüÐ2ªí¤ÇšlBˆÍ ƒh ųZ6x >“Bc•ãûÈÌ’Ê „‡³¬óðC}¦-ív̯ÞB1ö3£ÃˆXŸœÑYû¡‰l暪±º±M7:f¡Uý¡ ´½Khß­…©žr®øÜ :Ãû—Ùi®¢, X¨Å8*ª¢ˆJÝÊ0¢ª ›Pó¶ZFñø:l&Fƒ 4d0x3"·ó€dДòpü@ið¤Ïã§XŒÓ?™à¡!µÇÿûå⌦ÞUÆÅæ®Ì¬É@‰Îl6!ծ̛–/öÊ?ôV/£¦'„1ZXÆ/NíPãj‡½r¢ Í:=šÈ ±.Tö½¹<íÚŽ ˜9? y%¨òƒ éAÏE*MÇNl”ú8Œg”ën¯FµQ¡ÊU`ôižP¤Æ~¨oÉ8òv×UL‹¶k™éFå>‹Q£$llzH²Q†Ä8ÛDÈ B¢ßi+Ð=à§̈QzxðnD¦ÃÝØ‚‹rþ 飙W#ðòI5¯,aç¨[ M¸tÖYgA„[y¨Þ ’©€Á¶EåÐ •ú2¼ÃÚ*t þkסÜY40jÂÜ*ÄØiä./Fc§‰+NûAÝ Ñõ®,&F×R\®B ‘¥®?l\Í•[ŒVShFC1ŽnÇé¯Ê{ƒ±±]ž¸±®E…Ú²l”ãÅUâ¡EEÌ ð$õ%šˆ®áÿ|5KªFpmbdbWw‰nbF =6a‚qg½7‘­µuEpd³Ç|&ï(fitåd]QÝ\7~ñ%g,§DÝmɰ* õe™›eoFÝuzq5ÏתmË"…Ô7ìycjµ„š-A!MhùOKæ W³Æ9uDz’/(!M0±"jËÆP ºQpþ±‰J¢²;'$×*ãF«ô½O©y°@b¬–!kgbl*,aaˆ·&ÆZ%#61ÆÔtW bœ‰±>6;ä4éÉ‘y3^¾r3ãN™]«Ù²LïzQ­! ãÊUv5tSwÍ–ãÊ»jYkßh— IŸŸ~ñF›$‘(¸ÅïÅbAÏi†MÓ³`£aþ4Ø>©ü)j¢jm"”jµ^ßBo•?ÜËÂÕŸTÃuAkYÝR6qþðòê1Ó³qÝ›€>¬2Xab²is{)Z­=&¶1NÜ…2$×0<ÔzUí*?© ®ŽÃSvø®ÊW…6ØÛñƒG§&#h2ªGœ©8*<Òò¦¬0–º жÔGD)œåædÕÍt4ÑŠ„.‚ «Ä@4¿Jˆk!R¬Y rŒYªIŒ–Ž*FS¨(×¢6]ÃØ‚ˆœ¸J'´ðÄØSFá5? TKÿgœïÊèß^üà:ê/ןÔÙãÜ; 3i{Åq¿K¾'›Àc¢Œ¬º{Çé»P$ÚÏœÝ3¦Mt"ÍéD´A.v…Î^½hÄ2ûü.ÞâEIth뎦o×Úõ-bIŠ yxfu{º©†£ÚDÒœºÀЂMîþùns°~ñ˜,÷/ozèÔÙãS3Mòoïýð¬Þö¯ù÷¹‰š)^ú-~(Z®¡&gjËv¬®'Fã¡(Ó!ÂBÒDmø!á$)å·"ÚÕ«Ho œŠØ‡8 ÑH­ru÷*óÕ6Ðå—Ïq¼LÑohÔŠ˜ë·°+Œ£vT‡£+@¬€ˆ c£¼Û©!² ˜¥ÆRÅc¢{šŒ1såÁa¢{š±춤l]ì`´ÉòŠ ±É8{ó"y#E.ž62™¼azåv·É^0é±k÷n+‘Zo« ðÑo8zrBBN¬ð¡5Å]VßO(Aжý0quÛ™¹$¦saÆÆ&@Z¾Þ~XÝ;Á²àÈà}~Œãþ;ƒoñCîüadgáç‚ì…¾&óöf¹Â‘û-#nd‚ÝMv±g”<¨ÍŒ8×Uuœ90`ìM? ¼èó—ÛGÃ`­Íøh׳9‚z±¥&F2f' P‹ñÈ›—d«ƒ´Ýýõ&°:‹>i^Ò4)ÁG¹Ü!°ó†ÓôŃ>p& |ó$y”:#âÛèz0¶Å¢è‡Jž´mj„‚LMˆýkÈF?)ŠŠ 1¬qÀÒ*ÿ>pC÷Æ·©‘£]^„O).öÇ?ûóÿð¿^ÿ”?þÍ 7çeûZò±öÈô-þûå¼ÖíG¬øˆxyy¿¸öìÃǾö|ÖJ¹>B è¼zd¨ÎþÒ£FâôÓ&ò&‰À8ôïPÂY@ÎDN !{ñåIš¶P¨ëúøEí 1äVÇÇÛý¤…žÖÇ—8zøŒ[}óšÅ€ä 15\Œ–ÿxD=hüMx~¿š ”ŒY¾ÆÎ¸Ê<¡ßâ‡<2ïGåÓ8{s”£P`õT^½ý \q3*&`ùù(Ñûa¡4òBßühlk†9 ¡X®¹Ö™è^åÝZ*(Ž%WƒR"Í*ÑM‹ždo÷¡Gƒç)Úvâ7}óÀLýº:~™Ú¥(Ëó$©ø ô aG2‚n·ó’¼O}8:¨¹W GCÕ€úöâ­ýeÆËGÁ±“ñ÷…òEâ³óêDU}Ô‘ÓðZlöý¢{{ÓƒE k/×ùüçWxÒèüæ?˜b˜é˜‚ó9ÈÛßÁµú£Š§«CBÔ_¹¬}ÓØ¨@úB)” Ö“4ý·ø¡»=à ÉýÌæo»&Z¦wcPB®5 ?8¯–Pc§æý |éâ_¼Ss*}üË¿ýÕï>þÙ_ýmN¿þúÛo~ýû_ýÓÇÿøþñ7¿üøí×ÿôË?ÿø_]Wý7ׯÿÿÿåõ?zmþŸþñw¿ûåoõï~ÿ»ÿåW¿üïýÛ¿ûÍoÿñ¿üíq½ïÿÒö¿ÿï~õO÷‡oÿǯÄ¿ÿõ/ÿù_~ËŸ½ýã·ßüóoåÖþ!}ü«ë¿ÿðŸ>üþCþøW¿¹þùo®ÿþ»’¥»ÄƒV‰°1¤^ôå À!âmSÖ#©5SÄõVåY+8ø‡¼ZÉRnúúÏ?üáú—{ýÃÿu™þÓÇöñüø¿ýïéã?Éÿg”§7lD~U‘þö`NÌЃrÇaÀ5«ÊXºÑÊho2shÖzb,3ãhB8ø…›ó†ni³aÖ}ófË!8Y@©Ž{‰Ø$Ää£_4¾}¸=ÍÚn<ñÑD¼šãf‡{{ýv?K‘pûÚöŸ¬ÿ±úßêâïbéqßðqž–艴«:e?Ë}xi†\Î()Åã=óÙˆž0Sy2Ÿ}ûQKï0ý¤Ôrpxx3{ì,•[‘MÇúpù)šJìùñu#?þ‰Ús/?9—Ú§!Â’WêõÐ{¦*ž†õç§b¼š,ÏëíñybÆèö8m_Îï§ÁŽäÃàþüôÃ1^Mšç·Íõú?Û¥úßüVî÷öãïÿãÕèmµþ Y°ÿ¿X««À4¢|r°úsÓ]Û9“&ë¶-ä0Iaì|ýp»Z5U¬GND ·Wíw¶Yz­ë~¥ø<¬DFúžªé«â^¿ðÅ\<¿’ Yë¦ü0«ÜU¦–ªn·r0Êý%«Ï¿k·º€Ÿ¡Mä¦fˆ—ý1™5sT:5[4ÉE¶å&¦b//½X98Kal•HÃÔû­êvSd¼·Ú² E³U/4d*o×}¯ƒ”©ü%iƭè 6Pé;®ÝÇͨòy¡h Ð,À7 ó©jÃ4cQ+IDüf3í±f¹ÄúEÂOrp* õÉôϪ)<¢Š#ø‰z6°¢£*ixÚ:D[…ùW÷4â"©9¾Â”ŽAÊë.ºM4ÇJ‹pì;4œˆþ•E=4µµ qlÞ¯­ò×âô`> ÇžÖ‚ZÇ×;'å^hTÆRIU@rÓÒŸ´ÿǵÃÅØ¢QÉ‚b…e>Ê~ì€Ð¡Ü%Ü›=^ö ªPÚýÚG«‡ñìA˜ÞjÊ–ïÏU„2Zöã;(¬ƒ±\Á È’¶‘à6­0É¡€§´³†‰$7kL[ëpk¥Öt›ê"¹”F[ $ÍJ‡ãÚkz“‚ºZ¥¬ía܆˜s)YÔróг¸Tò¦QaN‘êMŒâC<Ë„§è”g_/¯Õ‘©<Í,vÅ zGʹ¼í ¥$‚ÿ©:Æ>~a½<Ót7¤žÏ$©‰¥>³Qgž_NØX3Tä{€:J^ìµwÏ”CN«y:s¤z¿v)ó¼ÝZ=ŒgNs÷ü+­µa²D‹Ú¦’Ìï²­P"þfNÑ€l&å‡pØÝx¬$§yzU“”í+BvT_®ø7)üdiÕ™‚’PÅ#b;{†‹”=š¬u¤9M~6 s&P ÑR4îdÊ‚§+i©ƒ2‚Õ]qº÷׊¢IGJ•ÌÍXÖÀ•šuiú`²¸TBiÒEwBuÖRTIÂüŒ0ËHd¡ `ñ$åË÷µFú2H2=®•µÂV¸£Í0Þq`n­Ê{2cè_q`\&`q^»M9L,ϧºMøûQP ]\gÛgâïfL‹U¡¼ÌÙ¤L˜œLZñ“¥µf±#«hл*]n¥%G6íÃho l9¯U9Á"Ît‡ÕÓ°hVe¨ìŽà4'T{ÜÈoxœÇk¾‹Ê8wbû% / â»,J"LYù*‰ïâäž@ºRn¨þ½äçN¥nÐ9…1§ *fO¢‰ÈT¨ý#£HÌÒÁ ¶“¬ûVG=# [ül&wJ΂fkíY”&{öñß1øÀ ÛÄ%'DSì]-†ø,^¥·ä †¸ùì²WU`×z0,PZ“Ny}7/ì%ñ «×­Ð  F?؆Fß®U E2,„Ò -[‰Ðð~Eô׈bˆ¨<Þë‹uAhÜš:®—Ú[ɬëxÏ*}ñŠ–È¤”=cf身O©½S«!Ikà•O7C/¶ž[\ð9³Y%“׆Œ95ToÂK‰ýÐ2ïmñ\¤•_afbµîpe"YRC+ç°>…JÊò`u81‡¸[å8¼ÝŠ2#aG9u&«`æÚ3Æ KÞH¨ÃNk“‹:6÷ð¦/F ²ÈO}|}3RÖ$Yé…u:²—wENú쇦3,I=¡ÔwM{ æjˆ¼=ßî úÑýSTÛT¿}0GjÏŒ—©;èçæŸYÕ#•ÈGq •›«NÙÔo¾äØvöM¶¼¼ú¡ÜAWDœçoHÈ Í'L“…ÓÔöÌ\Kôæ4ûÉœoYäÍŸ›¦×ºð<ƒ\qùßôFs¦ç¹¨'¬‡~ž kS_LÓ`%AwMÈFH«ãϋ҈‚¤*»Ra6éñ‰RL/㤨RœD­R«ï¥&ÐÍÄýÇF¾«h¾vxïªý«¢Š~¥A$kïKDØ×+2 ÂHþòúvŸûA]„‡~çË臖AÝõ±VpÞû¡Þfêýàíд³ endstream endobj 78 0 obj <>stream ¨¥xø¯£Êq ý@Ç«T”©<:%`B{â›Ëš´\VGš<É·ÃxÕÑ]QÆLÃ`Ú §\³sñÀ.9k¬é¨B_>p&ÐêPêK:æ’o°¾¼¾ßÇÅSÝ$á¸ð};/7ã*,w£pŽ\—a XkÄqü­âºÌ^è}ƒ€YeeIȧŸ æjÚ¿Z´ÊN¸R“Çàa¿£šŠˆT¥$› ºº®u"ö/•?|x¹°~~w~¾ÝS?¸£¼¿û-`ŸßYë^,T?¼»¨=ßíßvÑoïî¸Ï»ó¯÷òÏïnÄÏ·ûáOD0ÿâ÷N™xŠ ñ‡ŸâŸÿ¼¸#¿#2Ä ìwĆ”Ãúó£Cöçß²¾+BÄ>|GŒÈ˜¼ß%rvóÏ‘¦ýó#EÖÂwÅŠ¬‰ïŠiß/²¾'bd-|WÌè¡?'jdïò»âFÃêçDŽ8(¾#vdM|WôÈféwÅ8ÑvÉ^æ÷Ĭ ßE²¾+Žôð~N$‰,ïˆ%‘lùÑ$òy¾#žÄùŽˆ’5ñ]1%'&ýü¨ïˆ+‘»ú‘%§ÖþÜØ’ó[~tÉXÂß_òLÉŸar:ØÏ1Yße²7ñ]q&kâ{"Mî;ÿÜXßåÏ6ÙC|W¼I›xqbbÀwÄœ"SíúýöŸ þFRßÏE¿­߃³…Ÿ€û+z…RÚß…S²íï@*­‰ïÂ*¹µZyK2¹Ç«‚sûó#VÜ-~ÌŠ}øùa;n1߸ûÿCú¿ùí/ù«õ›ßüøË#V©°8ðÿf«h°›¢ RHœ¼&ËKV´éœåõݹ޾ ®›'åFB‡TE(¥´+6Ü˨¢e¦åUvÉÉŸ ºšte H±„  w[Ý16-4¥eåéÜUK‹+¿v 5Ó‘ª?ì`ª¨Gi&“)2FVµ[êŒ[I8sQðrõ©NÜ»±™„ï×wsñ¼Õz·¼¶É@O_‘E¶õ´‡2„ó¯uÚ©ªÖf \XV$©‰0MAÍEKöS»äõòÚå æ‚…$Šˆ£U-¶2¬jžExíŽh@PìÊzyÙ´åNã:zfÕIH,pÑ2©}€âVkÇK—fY¶!d'Õœív7}`sÇÃè ãïVñ¼¯ÄÇ=Œr¸_ùÑ!<Âym÷š÷`5[‚ÂÈqó|­fÙ›q„±ðƒËÌðL‰»º¯ìmònIÕ ¼Äã+¬á»âDÇÕŒ¢€VZ°V5™ B°øºí¼®•‚Ô¨­>b¦}/Ò¡’/>î˜ìíðÁ!®=Çì>¾Â<‡2ÇÁœlUªÑð%z_U«·ÅWàd*þ¸ñEÀ”Æá­¶³Ÿ"¢ÃO>Ý8£§Ù¨Ô£_,YÃåMI¹TùÇz9]]3®‘»‡X$¿¡XðoS4¯¦ì<›L›N ]Ò>oòô‚r1/®¾%hx5LfUµ“a–;M$MËÏl.ZsÞ&š€d畬‡™ )Õ™õÖ¤,:Öâ©Bí«.Õ&š£“;‡à;µà(ÃVEµÚ±¹Y&£5P¨™²²KhbùF4E«ÄÙ€¤°E²SúWÄ„P7ôSpq“«¾Fÿä‰Ï*‚פ*Ë›a9žjõom€ó‘U¾Äƒgnþåá#ˆK•X‘@_­-l”V¯a³ ê‰h@é¾4£*œ¼x킼±ÎS/¤5)>¡gô•±«Ù%Ò&]¥X™í\2Üé?CϬ²¸$©#(ý¼^µdìä9DbG‚­òͤ\Èe’žr ôäYkMŠpBïÈZ«ÌRœE<Bc|`S¾#ÝËPyò E=dê€M?X_ží0FÏ…Xr5UÚ\nTÚäv­`¢Öa­VˆN$¨¤K´Þ2×lÓv454&àj-·A¾1Y…å×»n©³]IÏ3¡gž 9 ‘ª™Ö-ª“ÝÛ¶ ߬-wYÎÏ{ùîßV²¯ŽÔÏøQ#\¢§Ecæ5Ìüsp)'vÅÈã3fõ>£˜‘¥XÊjØ!•¼Ñ£CÈù+Xªx¦/Þu:„„õXޝ!u-4 –—ÿýØ–¯>͇³¿·"k›>qjq¸!•8YÛ4ñ°ej)Xû-Ü… ¾îÕFM±âwžÞ)//N-È43e0Ômó_E< Ž3ËùØ2¤¸€yžU”*–@yÙÌñ~þoÿ¯e˜NJÍl ¶‰_^¡ÆµXľ²´‚¸¶Åâm’¦_mZAT–ˆÛjƒõ¤P7YOëRQÄ2‰¼ë*¨6ëWYZ¦HýHXH›—[+á׋ç`µº‘+Þ>ðKè¢)*Ö†3‰b-jn–ˆÖ‡®¿kr™ÃfY´· *j)£µx-°Z}¡C_œª}maÝJNuÔ£ÂdOÆ\ÂÃ4ñ!9(pµ“imº<*•¿ÈÊE™–¾,Pco@k-™ø»è“ø^4Ê?PExc\[í†nÒ„2ið^påW PûZäð M×R†u°x½ù°¹šòr2h¦…hÕάW‰¿_ËÔ“ ƒAåÁ×ñ²Eöé ÊÌÄSI¯±@ˆ ÆÞý0’*Ü|âßÙ·×R”+_êÃÀÁN¶ÛEÌHsƒy²$´î]PèP!i¨¨Ù<Ç‘Ì{4Ç{š0°…Û ~+~³‰‰õ}AVa†í³CΦî«îËp”Ú|"ñ›‰×w–œëÝvÏ19c©.g‡=˜=T•SF¶¬WN3óÜ&ÝäÍêè;@lqÑS…²¤õÞ\u`»—h©“î«ÊýüoN-7ò”Ü^+Ü~ƒ7_M©MÅÎå7YñMÙˆråLÞÛ£ëžâ"ˆ&U&H^ðñ«É[é±s°öK³:uZ$Ñwx‰\L {W#VÓ̒ΊVå¾bÝæÒO4u „™¶U l] $æÛÊæØÐ/ãá9Ò#Ýøç—H@£Sj\*!Ê8¡ìáwsq"@aBæ|6uŸLë~!€Ë{-\B\ŽeÁê]†îéØÃº½úç‘uÄTƒëYH \JÙ\yÀ!œ3D½xš`Þ-GšEkéÀµ½úC*JNÈ+íIýR€s@\¿‚G¶ÀY¹Q¹(VÇ]ulÛv.’±>3Êiq|eE¦Œ‘DT7^ÅÀ‚K£v†• w©Ë]àkãÝpQLAí:èʰÕdª¥æž•QÜNpæ¶ÃƒR'u<;áö5Š 2}åQ˜w™º \ØBežH?‘oŠy››§o„9ª¥ eÅNCœø_^äÏ>ÂUŽ\±<8‘G·—}Éø¼Bë1VEHðžÔsRj€*‘Ëö}õ¶am¢Sß|Òµ—š˜æ%,f>£·%3ñÙ5 nÜ+Gâ¥Ëñjw´À«î7`Ÿi![º2°¤¨Û"ÆÅ‰§‡6ÑY•J~ȉDÚÔWæ ¾;»ÖŠGˆ1ÍSðò†Ù„Út('tm`­’ª Øó$vÎ"šÆÑ1ÒÝâÊ6@².Øûb±±ò;+Óóöj½³N¼\_®£/Ö\'G}Žk…NkÐ+°ÊQº”cN O`4ÐÊouQÊîȉE;l}ù.xÂOZL„-¡ 64(þÞjÝé³}ºFé0ùÁH®iy³ Ý{k·6ñä¸gêØ,q0”PÚ¹ÒAŒjOGE^Q%J3³à 8"g¢Í&¬¬Š£;Ž[bÜQg¹d§,,<,vë^$Bâ´VÈùa†Èá¢,ü0ë&þÑ’/#¤§_œ/ÈýŽS¶Eè¿çœm¡áï:iÛ«øž³¶Ónri÷òKe;Ñ\\ÓH̸O¶É5Ñer*&Á$U Q'FjRöŒÓSk9ÖÍ}}=£,ýtBXï&Lþéõ¹ÌÖ›W§¸—ç½WgC r»Lî+/…?$HlÊú6HSo5R™_®4á× iú˜D²ç;t¨D°yˆÓY`u’ùœÈ¡§ T’½­N¨ù½’g-ï¹*öÂ_:6¯\ Wî’ ß—ÎÕK7ì…ËfM¼pð^»‚Ï„ßì?wb‚Þöí×?ýò·ÿò«¾‘~(+âù‚6ůWÅ’ø“£ÅÃ/þ9j][åq5X$dPWô+8·IH—ÛÏ8PŒú˜½f½;}×j??}°9â«BìÅ T­Yëò O¤Ì+¿H®¨‰*íb“…ä'œÜj«4SX–DeþÈ]ÜÒ/8§–I&ã.^ǶõŠkµ.ËO¸vØz¯¬Îʳv3í.g àkP¥\þÒ`Óuä'ºñ‰,Ä>m“4©ÄaûãblˆÄ…?¶½œ ’Eõ~µÕfQb#صâ£RBòšºŽdÝT+šG -T­mñ¡ yEùR™H¾”€o±Z‚ϓޣ–n°íøŽ|Ûi¤B…‹Þˆ£±:ýu€ ò^»iÂNÃò¿«VW®…ªùò“2Ù¯¡ú¾6Á½ãʶaT`b VTÕJ5.£™O[ _e»*Ä«fiÛËm¹"œÒJÚÑ®¢ÀCá‹ š29íŒ4œ%®eóGÓ~Â[Å7 »œpÈzQ׬øËig5è5s²ÊwF[tÝj‡à潎 IãþBÖ biÃ4å?)x5p¯¡Â‹?aà®Öê'B8Ûš?¹ à!þ\íX·Y£]¸±Ø€ºíT?á¤)éO0ÐP@p2äH ÌZ»3]!ógdö€Dš Ûøbù©Úi¹QtZyú„›Ÿ€ºé ²{é¾WSµ&QûÖ"‡¨q X<"HÉË/"k²ëòò\?¢ õå OÉ ÙšÁÅY]'ZŠ=ÓkÕcÈ™-ª«yÈÙJq_sJîóÇÙT?óì9Ñf¤˜m.Ø2ûä¸ýXFöÉ0ÔTaÕæÖ>ÌH§¯(—¤nŽÅÝÔ“Æ`JVâ'\[´*å0â’¤#£Žðd*VF«1í¯õ“ØëæZØ3rµ¨ÐŽÃ‡dÚX¤CäiHVNoÈ"|ɳºÎ™’´oJÛÊOÙÍFµ$ í£Vm7^WM(8 AB, Ï^·±Ù57e|FŽÄl`ŠžR:’r«xü4vN’+}ÅÚª–6°ÂÕœ”ü—õ²»…¾àZÅk쨅’ bÄ*Ú¬ŠýO¼6o át!ïË*Åiм-3.h’«ÞªË(zÅŠ]PHWR¦T*[áÂ.!7ëU–­ÛV÷' ¾‘c©ÓD³B ¿€§|5À`ù'²—[»ÃžÑÂñH(¬×KJÙ':ì¬])Õì}0Bs,ý¡Äš†Ú¨97[µí72“xJÚlfpEØmlÓ=¨ Ê«O +ÂtÁ&ˆøúFaì „z9éÞ]&žê“·¦µìë½Ü,[]L¼E&52š–¿Üìf$wÁ™Ì§ªÆo²)²,S½=MŠÑÅNÊXù…Sôg˜áJ|×Ê' y½O«©m'ù €A#Ú‰b¯LjÊ%=óÈk೫1«SãÊðáÀ®U£Nt5ZM177–’GH–>™Ëb‰¥Æ¾ï6_ß°*ͱP©´‡Ïh–l F tY‘;°?`çƒUC[ÌØ×†Ï«øW[”|€«àÏÉPOhÜŒàžjêñ ”1W@ibä®2S%Ïe“ì:‡eèZ³5„³9þZ_вé„çdí Ö . ª 2üQƒZª»;\àÀ(%Îö,ådíÔY‹²ÑbœA[€ÓI³/•]¯NÈÆh( šÅùÁ^ôcf+ŽþɲÝlBÐHÇtÑóZ™IIúj¾ .8²!EÅFë'0K¬¨°€Í Y«­¼r5> ßÕÃ×&rDw؆ŸÁj;­pÞQÀ¸Zõrꨥ•a&d& 2†y5Ï™g%Œ]Ee*]\„$P+kˆ=C²o»raX«ð2úÝšðÅÌ•Å*R¶I›ÔÒc“_¬Ò{ĺª™?dEùå%ðgÿßüË¿ûÁ?þÙß ð×?þòWÿtõÿÃÿò‡ß ø³¿~÷¢¿ý›ãøŸ$ "›®HrKRÛQhxIÎQrPH°‹0„–¿4î^56Ÿ‘Qk9ø¨Žff–¿–µÿIs®¹ã5ç&Þ£H÷f'Ћ9q'Í¥x¦M¡Í›’ú..§ù•ƒbWæ?ÊP›ïïV0D<=ÇÙö>¦Ôm¢üÙ zñܶýbÙšf,¨à¢*íÞ-³‚¹Îõ°B]F»=¨Ù*Dš1“u½C­æ«fÄqô}Oòáé+«1#x©ŽÂ¿Í ASålgLFÇØT¦Ûô>¥éÞ˜Ö§23Ò®Õs£#Q'ÿºZ¥°…`ȶ`8ûš _HÜÔM á¢0,R)Éñ¯¾BŠÎŽUE”ïÊ/Ðít ã䎤U­ß0ô#ÃÜ]%¦%Þ™C§Ò1d7¨Ãë¯[Z‹Þ&«Ñ FTÂRc£¢A¨˜‹¹¶E³mµ€aØ5(jÁŠíÑœ9Ôå4°SÐ* $ªVƒíh7ç(MVAV˜ÍO^Èë±y@WìZÿÃ=RpÆŽ¯PÆQ9a[MmKN¤gSy‚2°×kyrW±ËtŪ‘>T°Âò¡Wò5/+1hûßy8Î-Ek)tV'ë‚ó•Ö™±Q[S“8:š•âTc£´dÕˆŒþnSò \å´éWô(‹|°N'Õef°>)ý–44IBª‰¬ô<é3²Âåbý#M»²m¤…_vdž™µ^!ý2:éɸÝfDôAÝÐðÖ¬X£xkka\(y®ð€ósÍ7Ë.U¸žZñ|{iDM±4×'þ/h3ÛÀsd2ûX»qØ2BW ±ñàvaÞåjŽGHÊé×°‰6ÏBèË“«guOMË—© ¥{NHÐ}ç ®»#UC£Ÿ¹NÉÃüÔíU”/åäÉ?Þ\øfõ„ >÷€kª°ö"Ev4U h7m§\^ΆÀ’8 Èò-†üß!ÙñEÌ ö*b!ŸWÙúv·ÌY¯X4<’kã¿«µB¢Õ‘áZÎîz®8i) iÍ4¶fÈ‚§5ËÅŸø8ì’˜ÌE¼3qû–²¡­jÒd2ÆxI7év^IGÇ´¨69>Ý š‰hÛøñ“Ì\–Î6‹Sgâ·gž)þoI °¤óBéW3²r‚IF0Ü0¬Ì¨† ÚàJ˜ºÓx ¤£`oøÚCñÌJÝ…,^!‡ƒÄ¨ÌXK.5bHQ™IÊb¸’wGNFª}ÕZ,:hK áÕdk“-üĹÊ|›qW/ú\^7 ²êº9û§Y¬]iˆ˜É’I™xtôt$!rM¬ÐŒŽŠÑc(ºa¿} y«¹ ,¢ ˆ?ÈPë“ YáH£\VuôÉè¡ØM»Å`ì<»o¾~1r+ÙP6Y_ˆÔÌ>H!ÂAT3HÝî†FŠëÓ8zêf‡ø=$« Š;å3Ÿ-Ø 7prj©kÑêF»ÓH©ùí©×b<ÓDÙ¥Ä]_Œy&°ét«à`²ºÅà‰Œ™lϪb4¦oXƒF^à×®Y<ñ¬3™ÓÙïÙjËëYC׎ßbH¬½kù\ Ç•”½¤_5Lëø„kÑ\§ bpšmº<½Â^·æÛ­üŸ3yðd0#ucg,£4ÓØ&•«ØòªNËæ%iüh1œ’÷‚(F©ûà¡Äšè)êgœð¯Æ'hܧ‘ï`B#YfzP&Â^ð¼[¼FVMPs£H嫆E+‚Ýj&u /ÂÚ×ÒW<äg»¡fG¡ˆ°qÆ,* ´ÆâÆÅÃh=ÓÍvÈge{¡§ý8Ý-iJ{@DŠ7Jó„$"ËFƒcv`«Ø2m”âò»¹2„i5Î…øéQl8ä·­d·¡h g'g—*††}qÛÊAhmîJ^Ò™ Èœ=,†Š”å½n+@,JF-FbͱB©ùœüªi…yõyÈKaΚžmÿ0ˆvMZ–å¹DŽÇpϲŒÙ£cYÝ„o0+ÝŠÔÜœ n`;4ÚP¬z±wë)9ÛyÒèìYL“ËŒ×S!Ý_£|5?ÛfŸ¼ÍŽð!Ò‡"ù.Û°gth;…`gFÄX¹@ÕùÄØÌm_¯yC„leò†š9¯2fZ[ÀH9oŠxœéþL±±H6ã¨d„k¥H@/¥2cÁ¹CÍFSsò˜·íW†›Ú&V6¤n¬ ö&ì—H =¢׵^IbQ['BY}¿³N<5CݤbQ#N¯Šú¹¶všÈ¯ÂWjÆŽ/_Ô¥¸T”š‘VE3Þ^gŠíÄÞN‡N ‹Œ0q!gļ§…Zä¤dn®|DcwMeà¡¥LÍ&®5מj«šëà^Bu0ÌÏ'EØ™Ÿ’¿º†V_À§÷*ÃUc­Ã‡a³ü<1sE+žñ–]jWŒFéãB¢•š-4¦Ì>ƒŸ%Q|¨#h¤ÆB<ÖËĨ٠ ¥­5\ºë8eq¥7v«oŽý ­phu,K Jc|«g]h´ä5ʪCà3`ñÞ7‘S:‰j´§麊Y½8&è{¹Úý² µ*»@3×÷+6;D hÜìâÉ•[³xáºnJÕdq¹Ù=˜YHfàÀ_‚\ä$ ÂÃÒàtH×¾JJA¡È…J‚|‹ôP° R´6Ù.Z¹ù;±é Ñ04eë`\[”ŸpmApTC¸^¶ (S1±ˆÀ¼A{ÊÚš¡ ì[«P\°¼1y\2Ű ˆ$Âè·Ã°0Kï­²Ú–þ¥FO¥Î^yøš(œ"ÄЧ±7H Mµ0"*!=/-”y;Ê l—AQc-;=aFŠŽR+7èºÎ Ñt/[ÂÖ3J†j™ÛbwDçU:Ëq=};ŸqÂ#©C½@&—¥mšQPÃ;çö×Ìh»ÖH’öÄ·[N™®°'id–]«¼ÝMöæðo<‚{¿ü_vmbCò)“Üð^—];‘åUh”} ÉA6èò?ÕrÖ´ÂôG‚+#PX±!òí´÷†K]ñH6 %[ت©ý$+&ê3ÓU3…˜$±¶âž(+†òòœm\Y _l7±™Ÿ‘Ùb㈙“vvTp4ƒ˜;,Ë‚O p(rvD¤vŽÃ@Y3â* ûÐGƒdÊäv•B¬¡ÚVs.$äܱÖÇðÁyËpC×)§!.*YźzWï:7d#}Eסè$ÿd+”àÉ\L¡q ú”úÉN-nøjFè+… ­MÕ˜ ±nU¢`Ö»øš•©è¡yËÚ@ç"0íPlÆ}œð±Ä.d“Ùú¤›‘¡£^O€ì¥aþ+{F€e)ÛTÃ4Væî·'M¤þíÂMºW3⤲ !f¢Ú:žtJñ«…z!…‰ÿ<\~‹4Éûö1 €‰´)~ÃQ´¾@Ö"÷ÛnæR¦*æiض{Ÿþ Iö¬tÒU¶ÓÐmQþÈP´Â#ª1ŠKÊDo»Äʪ˜0úÐ*ôäÄH”DÍ{šFÌpxWl #$)£ù{â®Eï]•ÃXý;B“K«Ðȸ‘˜Ažœô´d““8‘w"xfÜÍW¡aKž˜Gg( ¦4ƒ&+W9|Å2nk\«‹/(Àeàl1٩ͶgõÔž€T1kCQðÕâàTUY3º²‡äD×M¨ ÒÑ·16¤¦†%æø!ö%FÂ<“´]KÍŒS€Ÿ/íæØ›-àÎn™p ETIÙ¬‘áY&É »ûý7§2ÑøO`ß3«Ù’`VÊé)å+ü¤àiÊü¢Ì5_Øx˜锽¯ÓXF ¿@MíDÊ2õÚ®×Òéˆb T£‹)ápÌ:Ë£àD³±tš‘ I'î.èòŒ ×$E>‡Âð¢7m°j,ÈŸ&ÀkäØ øLÿW̠Ή±v™Þ<ÊpdlÖáÉòÃó=ô8X˜Æ¬DG Qã"ç¦9V<HË˃Š,üdäkÏòÐX½ßc‡Ø~â)ØDmÛ@²s‘°LÅ ŽØ‹«Ûp!D)ŸcTéˆk4ÇSuÀ¾t:¿hâxVšñGldWUËì%M¾VïÝ.!ÇBVÓ7³æŽžÁHÃ9«ÀœBÙlK9–IˆŒ9+ÎéÊo—;¹¯Q)F!|6âœÀ]µ…eËžáP(ÜP´ÃÈ]/þrºk× f¾ñÙ Ê[°;³ o!%1æ…, ÿ9+ )š—eßüÉ#´Ã’æÕ,¢™qš²rº– '!¯N— ¢¤ÉôþÌ(ƒï £ zòâ¡52ðÀ»V=µÎDhG- øü¶äFÙ() „#Ð ð¸;h¶,QÅ_ é¬åuuÊ ÁFZ-þZ!T%ÇÜÕfmµàÚÙœ^dÕ‡Ã~Jì6£ÅÙˆ»bF’‡@û8ÝTœwkò¯]¾QaR@²Oåìž9Š87ŒØzr¶—Øy-Aááy*ÝØ,0&ò!r=@F­ ©Øè0260RÖŒ8ž«qÇBy…ã`[†™h‹[=-¥”HÏT ¢íd„TЇ»²<õ:É›²u*Uä™DÊ&…±Ð«‰|Ì’ Ü®h%8®’àV 8qØùÙ Y`="œ¹œ2Ø3×éaz+€o’s0C™dYr–¶f ×ɦ9HYC­"1p#_v1ñ¥XzÈ–â gå)—›RröU§¦»33¢‡Šõ•Ô‚-åÞ•7sî±Un2>«Oe©[eN”‚ØÕº§%娾é+Þ’¾~Qm÷ø&YNʼn˪qê‰CB%¾ƒ…ÒÀ›"ÊžÙáÍ>phZ®µ”jâ9„7‡©I‹Ç,wÁÖLk›Íòœçv°?¹Š÷ÂÑ—ð&<Ÿ€.âK«¢ì–&2e•Rä+RV;ëÕHÖ^p.#ëŸËˆ*Ê]d÷‘Ã/î±¹lj\íp¹‰»núìpêŒý*ëÒø÷àûˆD‘$|&î hoš„ž1†Åø'â?ánúô6-Y(ã °5B²Ó–æ£Je•æ×v«³iP³|ÁÏ8×*/Àç`NTÊç<É~èl9µ+<ÂÊ[«NkMt¨ƒûSÀœÎ7¬Ó¹FÈR`8mœ$ãOáî*ÆMBV Z«¶M©Wcr×ÁùÌŒ}`[‚T$q²\EFH'“•ºyB‰œkûÉ’Ù™¾®i"W..+êˆ- ãÙËwøb« êþ„|¯ßU,Ÿ—¯’Fb¦:qöôËh™›L@§ºò;B!™µ¼ÄÁÌØ±ªbOÂz]DŒ8ó¶ –UÏ ýn¤6Á1)©7- ¿À &Hµ+“8½äH:€Æj‰A†ýrÏn…œ81ceíÜž K!‡³/,SŒÌ÷ƒ•'gz{¢Fnµ8«Á—e²äˆ4*T—؃Êt>5£ÂÕrD37B ©a_ÑRpÔj n0=öÖaë2‡:—“PuèÙ’´*Ù¡¾VfÔnUã*œGÓ_á rrõ³ªjØšRÛþ‘ñ„DmSã.L]Îä¬r±Þ†~8иˆ¤^7(»ÜF¶2Àù ¡j1¿!2`ä½£ä]$×±(ŒA㣄=ø Éã)ÎîUô±à„„Î8«ý&‰d¡îyzÛŠ§åYºº¼¼wÄ ®-A2rÇjhK`kËŸ‰È*A÷'rÑmvZ£|…Ý*“ÃhQ{5®êˆj¤cFÛI¤]1šK¿Áå,8ÊS¨WIÃÄT)ù§(ãF¥iÝì?•\–¹Àœ“|WÖSô¼E®jÌBMq9-Ä·_vƒcjFAD¿ò @ŠiLÐJ …¸ÇŠ‚F&¿®F&¸©däÁâØjkÀš™ ÁL‰vr Ë?›ÄÏžl–(BÂDùq5Vê .“ƒß«Šñ‰x@¾qbFtI5šžÃ¥¶âØÃ…ßËz(äËv§äÞR–7v€—¥ Qò=.ì:bF›È x ‘JÉoÑFá³ê^b=h<@*Læµ.Æ¢¾Gð㦡aÞ8#’æÏw8Œqh“9žb47e·ƒS)fO^E=¥Oú„ÍÃõ:Æ{ÓÈ;p„lvæß3b¸ýœ”]_ЈÓëX&Ô<áÓkEÃÁ:-×(v´'ÔÙ1åêJ"F(3 sb„–z¶yL¤3VmÒlÒfŽ¥Ö¹ë$…áXW< Þª|Ɔ”py*¤ßH_QYWŒ ±„É7:Ü$¼åìR«¢.e#CtjZ'tæ0„œŠŽëÉe ÎiÃY.,ƒ‘‰®b”÷"§Bœv󡥯5hÜüˆ×ü¨\ŠU4õ“2…°ÇÊb:k/’X+âäÅz°çѬ3™/X c@úœröpž–AÉNÑ+ Ù@*±êF-À»<¶G$­‚©ÛŒ"k L}–*ñÅ¿Ÿp°Ù÷W/b¡H˜9ÚâlÕL$ìŠÊÉJ½ÊÿÓz3¨@“¥œ…€›]@NùIYò¥H­¢œ™¼DâÌ\ÍS`dÙv!5:L˜½þ@2ž\¤ ‰/'{é²ÄÇùAµ‚ñZ@Ô\FM´y%ÚÈžraC­Þi§CM©&GV+}reÀaTÇÏ&”p!gV=YPò®% q ̤ärÿÅ28“ëØúNž ¤rj‰ìGGªQ?L·~]F§m¢œƒ§pW§ÿi+ç/6Tx)–Çg¢’Ñ–Éï®Ô{#K\)°h¹*jU±9×ѵ'ÔØn¥k"W£Õ¯ƒ dÈÀzºxw•¸bs†žV8â¬f$ƒ²p—4ªä@Ì!;«AÌ@PЧ kH}áË@Ñ\=Hä— £«¿ ùäb„sÁL‘ù1;óHõs6‘ ¥ÆI '˜|&‹£j»çAá„ 5óT¶¦ á4u– +s „ÖŽ}Ö6‘G›N‡š~ÉF1qMèRJ\)ûñ‚ÂÅɹi{Ð!YY&6C±%&ì$1ÆS«ðs7(š6ë"[¢’PL#9±$¹®6ürÇvMEw'¦ž(³ÕWÎiE¤Ô88¶¥ýŠ[ —R[ìô/,»²Â#ЬaFÄ “ì äÐ'†Ùr c¦ˆ¢–Æ`ˆ!k­P¦Lóuznd·f”m3£'K=äffüO*ö(d8ì%.(´û€w«³Ê¢&;™§](Û®àhœGMr6FÅD‚jŽÂ¨ï•Í4#âøܤX¡²œì¶ÃZ”ØùqPHœ¬£- f‘TôM\³P¦³S¦³J’º\œ­ ¼œ™,R¢•  gžʘ/0M4'®EhÎŒ…ŠD¹lÇgÈJ[v¸G«öµ R%ž§ð¯;9õÄËèNv^!#Ùy8:3ËáQÖÀ2%9‡<DU>–i“«Ê<é ÂÁ#† ´7\‹œ13z|ßyæãÀ©F/Æ–à gó:Cõ]ýhÇ×Bsq„2à8Ü^* ç–{¹-êo#µÅ^ ³}‰%Nëw²«iâW~ÿÎT®Ï„chœAÓ¨ fDц4Öæì5™ßcoÎ}óš‡rgRÄjT8²V3®\U0#ª¨­zL ß K rßü (ÁŒ^M„2ŠÀŸ54åÅ\‘áC±Ð±­¢–}P§Cª¦ÜhÆÅØ6 >™™êÃ…aÙ288‹ïÝð5B 8‰ã©e™H‰‹;’dÕ86z°ãô#Ÿ;lj‘.Œ•P¢ôÁõ“™°6CÎ<ŸVO”~ÖÐ \}X¾è?9 W‚ö²`M§Ñ…æ%à>"áùΛäÁZýŒ £Î¾Ä¼Ã æµÀÔØäêñÅQc'Å ­*­á‘Ñ­™FJªj!—ImwK̽÷C›}A„}XvëW †Yñ›úvõ´b×Î(µbi@·kéµXmäê"ƒæŠŒ´#!³a{•K5Žû…Ï«øC0ËRöÁ’ ‘\ePü qQÄŒs¯Jô›8ºìT9ZYÍ„JM)q#5@*݃%£>·ÖÈ#Š1Ê“m­,1$•!W¯B£œ®‘‘rÌrP¨—ØÞˆb'ÿ7so»kÉr‰=Á}‡ûGÀxŒ¦«ò;ø‡t`Ãc´aCjsDe°ÉL¶À·Ÿ±"VÖé¾2Œg` ¢šk×É]»>2WÆŠAëÚ[ 1l© á”ù»å †³%¤iWî`4áÌ$_v„ÄO°ñ4;בe05ÅÉP}‡Àiñk§î˜V™Ë̪ŧ@d*Æ­"{1Z kjŠágNã^2ÍàÇÚw'¶¨ f“öX¡RǰŒ}ŒvMŒë9h3~ ‚ÏG VNŒêµ`°rË#ÑðQ$Û(F5.2 üþNÄN ï$ÉQ|lú2´³¦‡c‰>Éh;zåFQÇëàV)Þ²ÒÞ4ïFËëßRˆö°ŽÓºòCÿYÌJã8ƯUÝš¾} )`ä¬>¥ŸXäà¸Ý28v¬`àôã«°ƒðüMdž頌4ÀÈ?Ç{£1éÇ%zX\­*¢˜’ÜkSÞƒŠÑqÚÌ6jåõjBжä^+ËsT¦:<‡&sŸø²ÝôS‹44~Wµ®Ú`cêÀÐCæõn±b´+þ;qÌwýiÕí±ã@pˆÖÍÛ"?§ÚUe4!W¯àë2+Yä÷Hÿ­Z6£²m䋎 ƒ¾qéEUP“' dYC3œbø"]6®·bö(j0™)-.Ñ^'Ùx`¥~fÄÙÔÚº\ÝXuJÔ ¼ÖC|€ÆÎ–Í?“\µ´/Eü†~nO³‡}Ñí¥í®á¾ix ¦ ¹1îýp ×< §L)Æï@–9,œÃoûMhÓ± ./Çè‡-‡{1Sü̩Ʃà‹NA.¿¯°\œÝ©ϧ;»Mº‹ü’^×ñV¿¤6žïºàw±>¯cµ|&Ÿy_^A„d7Å«t4òK`Ýñzœú'Îy®­t¢¸cwøYa¥K®x¯l½bù¦—ßL¿;µ z¶Ñf¬%¾o·áo=Û Þ©SÍAéWªÛ„¬ÂÞ³ÏÔ$pþ1žgÚõ+µ‹ZÌŽoš‘Œã´ òÖ°$X¬ho‹Å Ój  »œ_k?~–ñwÊ¡ÝQ ðl»®n`X¿wÜi*>"AóB¤ô”ÄŠ¢E¤d}qû)ÅâÜ ƒk¦-µ’F¸ÃŨ=õ½jd]†6˜‘zWÇȪe‰Îg"Þp]t<“Þìz‰UßVò·Uñ©ÝG–a ßf6.˜?/ëMu+ø0KI¯afŸ½-Öå™%Ü„ /-Ì\A'EƬÇN+þYuØæ~®‘fÅq±4-hcpfãBTJì",Rã¨Û% Š \'8îÜ…þ!ü)2wÌjt^É$=Íà•ÛaòГ^"mövé蓤’ ú°].êë!~sHë©GsÅ{ÇÎyzS‰;m€µloïf’ØvªÇä‡íì%—hn²áý÷~%3¶âF^–½£ÏVŠ\Ñ+͈zŒÓ²šŒÖ¡–9K—"]¥Ç,46äjË’ÄGç iYÒ¶£Aœé—D±µÕ‰TmæR¥j)x¿hÐÏö‘ûdö°ë º‘>ŸHà¤ã>ҰʤSµë⸵¡´®k†Ên<çjÂ=Aúh9FlÞ#̬aŒp‹äÅ•xнÌðc×®häUtð]pÎq¿‘C QÏì=g¥÷‹a¢iÖD,"Wë!OZ±);Øk9hÔ¶!±q8p[ç 4-¾í(>YI04‡Ž”Ji.}4KuÑÞ~ú>,'ÄÀ³‡’9•ªià2²ÑñN³ŽC)‰00víÏŠ^K(Xloù27Ÿ®6luÏÄè3M*Ä0:ØšæÈMo£7Øj¨\!K\µ~ÝÑÉÿ&ÄUU „Õ.„>8E`[¨HÄÞïº]bVaï'H·[jà·Õ{#hc‹cø(ùÊŸ›æ"º\4bX6ù÷Ø¿;Q—îÏo×’|¨ê%×ñ»É" °·ŸîNo±Ì±¬«ú@§…¢òE"ÿW´¡­P8ovZSQv»µSvâÛk¸¯”Ý¡]pè>±qYöÊÍQ­ca±Žýg›“Å5¬qÕ¢ƒôJSFØà¾ =–¯~‘jóˆ‡hÒuðîÚmvBZæ5±Äo*J¶×~̳²¤½NkÒ²Y\\®…€x+ávŸ$‚su>YÐ…»4<8-§\;´/µÛbËQ ‚Ñ&I rÊX¥ªë,¬‚‡}‰ $+˜ÎÈ5-$ÇoUÔà8ê^vFVi]uî§[(ãL£e=­Àà¨6Ïb¦óGXþÖM™RŽ–,®43ŸKÐ%1(-¬“­jgЖSÞóô%ˆµ?ÂY¥R½5“1lÝT­(§i;Â}=Â1G·,*ò´å”M§1Ý-Í¡‡’„)™¢ŸÛ£ ¢F GÓa»)]‹p÷c`¨½§‘Ö¯±]=ïº ÑÅZVè-q{þ¬êXdöå'Â-ÃñÎ#(H¾úo\0¼´52`í\­8¦l‚ˆàû~ T*º‡ðÍ™‰ÞŽg~BÖÆ¿@ÂÉÀ™e°Ûzºõaá˜H‰T¼»l‰Ë`kpKÜ7U ¼¥FY©Ô7ŒG!˜0˜Í\”¼s÷>fîów.% .=òe8Ê3;çr¤›WÑHÄŽ5«ÕuµRÆáð f½¤+% .ªKMÀ¤W]-¢ážá˜ÌFQÏv”Gb{5t‰´wÂÌU޾TžëíZœË”,ºåŽþö~{™&ç~: f( )=Ï@¯2ù‘ÝW _Ó,ëÊòÈ:çUO¶|E?Î Æ5@ñsn‡c=G9o7UxœO ¬¼®¦E7«|s«¼îºŸéÛÝÍáŒà5´÷ÂÅõHùæ Xõf,º ¦î eï€Þ˪‰ÆÜ‰Í˜'i)N#T×í %aVÑäm~•æ"]N<’¨½©n°OyæwÉ¿äö¨I÷x‘qÅŽ~ÚÂlÔµ#ÝŽ5ôe&4MÍ̼¶ÕDýn®§uÑ!¶¹PDÑ´(®ÓÁƒp@Ÿ¤CH¹½ucD_Ñ.èõh'ð—Và–Ïa]bÝò‰‘ÚïeðÏ.ã™åõÿo¶ZjñOk NsÒî€Dõl·zð³ŽõUá>ÿ¾F›³.ËÕD2¯pp(­)ζ]Žº`eËÁ>˜uÚícÌ–úª4=ñ·[Rq·é%Æ©@}š@…b"`¿<*Ê’™‚ƒY$+mYÇ  9`P®7Ò·}Sa̦öó<Õ2H{¥Øn+©JqÈ­,^'6HHóÓ£P˨¾ª%ª1ˆÝV+FxØËðJÛ¼ºÊŸÁê\©n÷<ª¡íJÈ5Y+ˆ @›‘öÇ÷_zá“,vÜ5yÄTàM°o¤/Y™,wÛy™owî"^Ixz Ò!tòfÔº&;LfŒí²°š…º ¬f †·pjÛÐ?a¥ _õïGlÚ amd«{vø`§(í®y[ÕþFô)ÁFµÑPÓ¶ú ´©YMÙ÷¶,帕Ëú ŒwˆaéÈ´™ÁÛ‡ 6ï­K « Å0rù"UëÅvÌ[ !§eMjwžƒð¶$GØgØSUçHæô#‹rÇÞå]Ó»”÷‰í¶¬‡{¨uÖS%‚&¸3\Œcæú´ o韀 Þ"–Õóï¹Ñ'#žÁ. Y^VûÖ¾BïØëQÄÀ§ᾓX×kênwâ§Þ·ýæIdó÷]ø³Öݪ þ}ˆD&ýàd¹¯u:x<5mñÆÇò "ö•,ÉËíR¡1aÍïz_˜ Õ.b43‘o:Ò’zòVŽ%yÅIÚ%”ÖU˜¿r2Ô²dÄ;ö‡G€dVÚëf!sÁÜâ0£ >²_šöÀG"h«õFNµ¯îêfft+‹åHŒ¦ÃN7íxc€šl TUKá,ÙúÑ£FÿM; W°{°°õçåž¾ 㨳S†(I͙‘̰³¼Ú½ãµù¬œ¹=šL#8‡»‰ñ¬Yå}5áX;ÙKµiŽ%Õ—mƒKŸpn¨óߺÀòσi]¾³a5†UÔž»R xZc’'+.ÃŒÎÛÙQÝîad˜`c60ª2Go$Âø¦›k—Ìû Ö%Ü3b>‹.%?üS§Ƶ ‚ò£Jjw>ps§•æo¦½òÜññ‹L=¼ÓÙƒºš)J6Ò;‰À?åB ˆ|Ú*âÖÂEܼ[ç`НÉì²FT©r€nY>+ââå)®Èeû |S—F,m§-:~_¤Œe”G=*hº¦™ˆRÍ•D¢Ýï:{§='(ÙÇ£º{Ê8Ε'ÕU0*è:×N@èNK+ÈA8sÛ3‘]¤ïºƒjÚã‰;H/*ý²ÔÅÜ ê‘ºå½“×»S{„\Y)ޤ)!(šÒb¤‘y—{g06âw™vªûü±Û4¿T€›;uÛwVE_‘œdP±Ÿ± dðÖ‘LÉŒëEVÌ \,RxÌZ¸Õ/œi ‚ ’H~‡<•¶òX;¦LËÝ {Êø6šÔY2OX‡ê˜¢Ë^Ú²¶Øwùøl›à©ís`³~¸¦¸qµ'º<  !,rP±ÄqÕ¯ÌçH€ÊxxOÙ,3\¢m$§Äa‹r-oXkú,!¬k˜æ<ƒQÄyvÉã€u :ÙC¸]†Da£«W¸j¤k] Zï®æ¤-"õáÔm;ê§ Öìç†î—ôºug¯‘8U`$SœÍV«ÉÂÐkÂ+.1˜¼lWÁ`ÔÑëxÓšrêPxxߨhÆ›Üänð€³ÝéÆh‚òÂAI5îlMUöp=žcC°ð a?"2쿘—»Äÿ®ôeaÃ’+‘º‘?êTÇÃâgÈ‘#†ĖV€¼ï&{kÏ|v-m•KÆóLLp©ÎÈ_%Žb_Ifoqr fñ+=¸ ÒéißGÖÔšei ;÷ ÝÆ÷£jéûêJw?ôöný|Ç*Çʨ¨qᑆìki½"¥Ï:û9¨2ûö³D¬äÇ·). ÕUÚ6¤VÈ`¢ók‚ëYël]nä<-QÙwqéua_wœASþK[;´ÖeÄçJ¤ÔÖ•­ñná¾y#¨å U%çÒ_öé—ÈïAMõMî k^O·”ipó#¦ 9'?¿|¾ ñ#Pr)Á‰î&œ1¯Še"Øìæø1\MÂ÷ZvgÙ¨É0— wcI?»]Bvéìu_ƒÃFAm–Ð:s/—g/ ´»»\í‚AÛjœã|¡¦ —ëí$¬¿éÉ’t>ÄŸÃeˆ÷u˜[)ïxüV+—® Vø¾šî·r¿ñ :Wœ,n ” ìxûð`„µ—x«©½S~A zìl<㪒ÚÛ;âØÀÛ»õ«#h•Ó¨a½x•‰Wª(¾¶7#7|€[ƒfE»/)ŒfÏ©qaîòR… `µ‹Ñ[^D3þŒ×lHi1-*¸Wn…®Ï‘¸f6EziãqGAK§ÖÀ†=?H7áV͹tWM•ób²âØÒì3¶nÞ‡v:ŸÄ£ì‚K]FïWja×xrbŠÄ£^„xÒ HÏìLPL W<±BëîÆÈ)Òä8}B—ÎÉÛî^híQÝF8ì¢Ö–©×‡Ì¬w1(P‰áTŽÛH„KÖèb‹…[¾Ì´UL¬RЏía'ÉpngoÓ8Øx(0¨½Y‹]­ÿ^ú3€ ÕmÕW2º›˜¹F^fwž–ã>²ºQ²…£·ì=ºÎÂՓøiRïÉï\qŠ6MgJj$w’Y)ü``ó<0Ús!#·PŠ½Ç¸f«ÃtÚ¹3{¹Ïéf#Ì Â4UOþŸ8m5±âg®Õ¬`?gO€Óz¨+óQ“1)ãw¥Z}*®Î9¯ëA7ÀybSRÀú”àÙLÆ>rã+¨–5è3çfX[tóTû“ûE ~¬À”ŸBJûÙ¸§À½EÎOÜdÔÛ(-Oì›6)BßÞˆvÿ`k†dgz\¯èÇ6Ö¨4vOù“Iú¬m­5rÛÚ¥ÝGÝ+n;eq«wñ»æ¥,¾ìpYîþɦyΣI)Ù07©'ÁCĸu2÷t7sÝ^rAIt X`¤êÏ™‚0+&Iý\aó-[ðs»ýÒ\-˜Õ:C` ±¨Öñqx½A¿V”žÙfÆ» ß!r}•KÜ€gÞ¹ÀCÇn )šƒúÄòo.?õÿýó¥D¶4W6z¤^| &惲`”àÈ)ÃÈ£€†îÖ–wS ‚-Bý:³Í!˳ÿ^æöóþ$ÜGò¡0}@LÓ³™¹å3Jìèm6½påBn1Èï`}+ˆ$RA³F¹gè>Vœš!B zuK°ˆPŒ)¯ÃAXŒÅzv‰;‹J% ñЬ&Qa_‚+™q&¶ó,EÖd+HÐô¼‰ ?`/Ä"\êÈ|â¾+8@Q·UcÝÊÚEጰ2—׆°h.mùz2èªÖAPú`ÄWIÓf÷ç\ªmW¿“9;±ß*ÏGQ$Õ˜ñÅ[£¹ eù?¶»Þj”fCàI†ÃQ›bÍ~  ; ùîâé¹çûQå†ÃC¯DG}RÃΖf¾k}0o¶&2€•[«üaãö[Øþ¨ö³ ~´0ìÔèÙüÏàhž&wµ¶ÔÆâ):r 7óX Í~jkÕ>I­iK‹²ÞmdÑœ~üÔËí£Óþ( T.ÙÊšpçÙªRÜÇ ­Q3û×J¦&É–Ç8›ûúÐÂO¨dÅ9Q6¢#ý`›W²9µ*x Š  É½Lló›„–vYjK¿’Å”Ù^xfö’î]°­¤Ô”ï‰D.ó<+Œk«À¢,T/î£{ª¥FÖõ,ç»Hϰr•ÑjÔbv[½ ×WÜžÏÊÛo‰ í|œ¥–•AkéŒñi–yÛê«U¿YÉÝöêüúÄ ›åwì7L,V…Nëf ×y«Q3ô«‹9½ öd–jat®3÷Qâ_tl“æÒ’™bQ¼ /ëŠa¯'ú¬1¬ù›Û®Ì{šeܧçû))£ˆš;v/Á¯U‘?«Z„–3·•Vú¸~uÔ YÇ“;|aÅP&—=÷tVÉP¢ð)@¤SÚðFó$-åÑSÎ=¥¿¦š Ú§òÞaû›/äÉ¥ÉÖ¬ªB=ÚSЄ•‘ª‹÷®Mù14íO]ΦuåR ‚Ù#À÷úͨùe2û­ýçgówWXÔ4“žvY] ;’º˜—-U܉«•lƘÑÈA³ŸW0›ôXoƒ ÄëýÛ)x§åù¼…ö¶:<¯‰lŽ`¾‚+3Ú)ë0OŠ¿3åÄNž*«é¾Ñ:B…È(yˆ·xwèJî¦ô}\1-ëTBÙºÒ†³@‰‹)ç{ÎâCÓZÀÛ´:ïå>oS`:“e¸µ¥÷)ÚÔê'7Ù¾†g?êä ¯@q·]"ŽE¶Oć“9ˆpƶ¦,s?lhsÂàºÏ:Ð,6ºÜ~% ©ž7ó5»½ëI—Õì [i ‰h¢j Q¿ÃUƶìÁ؇ÛB9íòú0EO+φè•lߣû‚·Ví£O{$ñ/d@4 ¼^„K}Œl×W>!Þ[ ±å:J h‰/vëC$I±'ËñL ë`1˜ÝÀ7?œlÜyµº( •xeœl5aÔ%g#hîäKäƒ$yGióÍÙZ÷ƒÜœ•ä—T,G©†âûAEGÊ)d‰®F¾x ¿Ã=IÁ¼ lû0 P^.脹ž]á·d›¯¨÷û "å+î”âÔ—½³"g^NëÜ€9M±r×!F½b•ÝϼÝ~2^4ÄYE¼"™ü¤ú>æÂ°ë$Ž©zÜŽ÷)áMÑ'v IŒ+UJ€žÁQNGz(´²ÁVK!9(ñd_‡W²²Ùw®g}gIæ:Íß;§Í;V`«Ÿl6Þ5@r}J]`¶HÔ‹È6<é@tY€Y [w¿Ï¬(ÜÙR‚à²X"{<ÀåYW(`ïÚ'S—Q­¬½…,tÛuvïkgØ=ýE©Oà… cI~ÝÏzÂẌ́Ĕƒ»µ×àiY£í²Œ¾4€Á¶ýø]Åé® óp#%•bÙ³;,ÃhÛ~ßÑ’G>ð›ïPH!›¯xBeó5WÌWî6¯ùèÁÅÆ?Ù`û\µ+É‚Äiö’óL쬟üúâNO&‚ž—Ùg(ºåÍØB=¦Kã›LºÎÂ1¢zËfòzM`˜Û]¼mJ õOý0È餘“š‚y%DR)hœÿ! ¢Î”D7CA=ÛÃÌZþ(‹2سȌ`wÙ^ôÅpg¾œ`Ú‘Q<êBÀ·–[¦R/°&‡´ÇÞû`a—~@9°—{}û™jb6=r ¯_ÀNê«éOßÇUQ¾=_†úB´Ãë²*b†Z×6%‚­ÝyýÏ_»9®ÛbÐŽ‹Î4mx×_µa—œÁN^ii¬ù¥¸©ýJ„§=SRîºÛ?ø¦›Ý¹ §_e€†A-#lzô;Êq¦¼m™þ¹Ð³†5ŠE~¼Õ̳ý:ÍØxëè‹\Å;Q¿+Ö2áE½\ÿ2„%Ö€çb«ß3»òUoIAfS·wœL!\+;{VKêt¼‰\F2ÍœêÑJáå,ªˆ^Îü¾ –ñæ·7§c-]sJáluïÞJV'°6«¶:#êéqL•ùåBòŠ÷0%Zvj È‘ò³!ZÝ/Ù(uÉ­<Ÿ-c™~‰ÛS(ÇÌÚ³°Ý,BZ)à{Ó?­Zdò)¯”-­6º‹´¤hÇküÍÇJæO³’¡•u„HµÉ?}*wÊÔxNŒÚרf›1‚šk€6›T¯FSÝýzZUÐ4?Ö©qZwPy¯%¨r‡¯Î M~o^þ¹÷³‘WíµKò ±J¯ø© >ŽaI½<¤âº¶åNV«Qâ’PÍhI0¿‡>TUËråù¬}GU·+TY$“Ú“‰uE"õMǶyO‡[¶è彄0ž+c¸}=¹+9Êc=îʯKÇ•óeØnw36º~wÂÞ:F¹³?iôœ)ïÓ2ÕÒŽ­SWËÔS–côï/£.Œ \÷ƒÑ=š…àtÈq$/Ë)8’Z 1ºü Òå( ÚŽ‘’4ØO3H3~)ŒØ5Ë#T¨~ZMÎÌÌ·†ëÿ»ð¤VS#eÊø2ÕíÜˬÃ:é/¯ŒSj% ,«¬u%‚­{ªÈxo)ËS:ä¨;WŸÕ™ü¸[ð ¸6Ò²]ݺ¬ÍNá´g_GêÊa€mµ‘m]ß³¶ƒ.9Mu;ŸCp¾‹"[1•ûÎ.ŸÍ™+@\ÎÂNžg5§ç£ÕSdA$ëèÇгTÏÅ•zÅ™Jâ zrH{f|xnƒ©¹Ùóú¸O_Òý!ûƒðrÁý©’CòÓ0!vzdÙF.!#r-‡“vs]éƒ1…³²IÍqz€ÜáÞ a[£ÛwÁa9„«³û•Я˼#z¬n¯Cr3#û×CºŸÂ™f´ ä40Ý‹UΜ³TÉ›QÏÔ©F;¶LÅÅS„•òÌälàËR÷)×ßþºg“ Ï`ä/óžcœRõ´O*ƒ)quv=|4»Nlyl‹ç¶<‚ÃÇLêqV6b?F]©ó1ŽªŽœg9p'ÏÊmËc‚¥£ƒ's©Ò‚ØïŠÂ8Üâ$ݯÖJ¾ö°Ð)ƒ6¶åj ­ˆõ,‘z=\Ù>-æ†<"Ö åMÿ°:³îK¢XÙÀ2ÃJ,µ>.Ëå—¸& c ¾æÍ~v,¼Ân@b~:¶C1üy Ï¿t3¸Ó…á>ökwú5¸¨óè¢Æ/Í3(«]gn»Z§š|J×OiB„¯<öàx·Ê%+ûÖŽŸÏ–4ƒ¾=Ö¶ÝÇ]Òu#¯AÉŠ¥î¶Ï@‚7<['—^eeͪ`ñ ¢à8õ²õ$ØÌjf³'‘Èîà¶Ô+ìme¸Ë kKD$ÕJîL üõÍgø~ª0ßÛç$qò­½á›3y¦3.SRÊò¶\­»šœi„U\[6F°K"keÅ”»™ËïæII.yåüAõ—ÔvÚëkÞâ‚>ƒ’Ö ‰gs‰•½v_Ã`C´Ù˜ÍE…GOàJð³v˜s $¾dØÑW¶9î'}T¦ÝÞɪW1|-£K`ˆÚWÂZá×Co¹Ÿ\U;ñOÄEvvû¾þÞAƒBOuÍÞ’(·ŽeX“v-oËu²^ኌˌ€,ªsp£*´v%þRxf  <“õyÁ™ü÷ÃðY~CB3­ °Ñ4šy<ç^'¥›n(C† Ö‹/{ÈÇwy937hfÌqï¢E!yYLNÜ€(o¦awrªÕE9N‰ê’*)+ÈͳpƒÛ“A’ž¦ sÐŒGgi·ß³¸™Â²‰ò¸ãäÇ‹õÿ#3ç×í‘Ò€l»uûoü7 Ù~8î°ÿÑÔy£¬RÔÚ·½¯žšxÅ^&ÚÊSgvLÂyý I|{ìyaƒ-8`ªQEÖí1ãP'¨‹ÇÞ¼ô35 a®­²)?W;äuÉä`³e…«bx9(ÔobÚ…LP‡ðøØ-ÚœÉÓ#ÔŠ}·¡È}Iºç:,?‡°$áæ±¤G‘Hݨrôù¦«+ªÄ:ezj‹r‚œ=ó³Û/èRfAódå=>ȼÚ[)÷\ǯÚÕ\üI²Âc`…mK‰n8>ÿÛNÏô+)Ýn,_®°™B¬ØQwKZ¯/ªzuÅ)À´1²[ùò¶QvhO©íí¤€ØAÛ±df¯ðöO’XQ{iM•FÈôݶy÷~ÑxþÑJO>ìÁø*–Õ×wÙÕÒd9Å÷•5\$õï@¡ìÐ7ºI0ø³Âã2É8ÝŒ%%µ‚ Úzöî^5y£ö\éZ¾ÔhÉKšñ”y'L*Ħ©O¥Çž¹è£{nœ"ÇÍ&ŠôN±í”´gf“ò6Ûw¯zÌ—]G¹bŠcå=ÆÛ¤MR1.)nº0<å¨-×wŽ ²sq‡÷áC™¬ˆZ²×ΕïjÏ´a$ÇQÌé¹p ­²é‡³#2Õ9sË;å½öY9¸c°L]²‡-Þ´ò.«ÞO(…i<Ôo[ Ïžú:Ýíi˜‰érdsé;àt„5™½bª¦yéÅÜu›1(_]DOÆJ,aG§Ë$žöltÀ6šu£3ˆAÍèlŠÒ$P¤ÔmÇUˆä˜w¤8Eâ ú öè]ü¢4V)ûxø¶!b¡€tšZÒŒ[UlØÛtUBêº|3úçìÇ/Ëþª‚ñ±DgÙ(à#4îG©D•dÐfÖÑ ö)Û k`JHbrWz™À"±ñá6.?ããÎ R_ÆÂ‡<(¿é.èõWŠ<ò˶‚ÄolÜŽæÕ¾[Ç4„õ™ÃîÀú1êF9 ôBp2ËÞ¥xIÂ/„–ZPÌcC„ü´´SfÐ&½iü1+/#2ü#ˆ¼Õ)ˆc—ÌËjÏöôÎnÙ~s*Ç6¬£˜W¦³6¨H#‡ôŒ'*±/pÌx5z€_Gï¨0} ÕØÀné|×Wj3[ŠçÁnFöçáëƒ'Ï+¾Tê"ìCŠA¬ÙÅF‚Œ¹²› QðÙ—Æm÷Þ!©Ì RÈ«nÏ‘ðÙ©XÍÒo_ióvÅvoÔ|N—›ÚqÜD²® ÐS§7lmßø1⥴q®Š•4 þÌ>?¢>è÷Èýb+lJÏ),!iL É~áäÇÞ·µh=%´skÜm…”}%L4R¹Ayb#ˆe;òâêÆ9‡#‡–ù{—úü:5^"¿.6ðâGDéAövðH&ïÚè "î§„û:fŠxï®Qµ¹Â ‰a¼ Ÿµ=Q“/)'clO„~jÁ«‘‡Ù¤ön¬†ØPƒÅÛõ+¦ÁžW6a+1TŒìžˆmù¬¢£9š§VJ¤%Z«˜¿¦!WD¦Œïxj¥aþfì0¢u—œÍoaaü’ãò½BF¬ÍJ‹të®Y)îÖ›Õͯ<ÒÕM4 ¥âûž²fæsk§¬¯k—ÃŽÝo:öŽÂl¦œb«¦WhÖx5¿xÓøÎa?ö ›ÛÙâùÓÅe´ïÇþüoþæ¯ßßÿôõoÿðÇßàXíàÿ¢fÐ-|`4 Ÿeûí‚'J%/­bn{îäµDGË.¶Ø_V‰ “„›]WèÿÅãºúYöxÕ4Iá0™d‘{Ûƒ@âAX¸÷8l&ØXº¯ò ¶DOÒH ñ}Òö) µïKaœ«™åkßËoá2]["¥¨Jô”ª6;¤kgÊz(Å2¬$O izxê´Æ¦™“d}Ȥj΀PI–8c–‰pÉ8rÈÔÚ%’ëÞÝá¤Ô¦å¨×áÊªÔ ð»›†Ü¢ùËZK^2Yb\s-(QlЫ˜ÑùàF´ÛýIóûwãiÁ][í|?‹XÁN±Wo/8>†èR?‰A““v l.¼Á~²È©*®@RâˆkèCªVB‘%ué݆¬Ñ]Ù³!,ž,ÄF{´\e:¼Ü¨"\ Z³!DË'ƒæG²{jn‡·U]J´ªŽc0Â`d¥Wì.Þ¼c"ÍÍò'îî‹Ö§µbòŽ`*Εg°’t_…@­ñh)c0Ÿ·T2ü¶‚\ââ!ë)aO¾Hy›0Lc'áBà5¹½ Y"c0Ü )mgR$a(|Ù?Qés¨©@Ox½•à:©œj»˜áÄ&AÒÖbáì±´Ä/èf¼¸idõZ2ئQ©+tñÀ׬·5®ù|£C r¹íš1s¨Ö… ÒÑê<]d»~íQÝZÙM?Ž0ÛãÞJ*Ëùt¼×z—€E}šeNƒ];¥‡p| 4ñ•¸D‘ÜMûË#²´/賨Ñ^«äòmÌ·‚Ååuf&ipyÜØÎ%M¢ÚÙI†-¦ÌÍÖ‚Kµº£6å’¸ ]Ü»‰ÍsD?’»¹&¸b+µ¯ùy¬_—S(àÄ kN¡nk¦t²§X°BÐY˜Tš#%¹£ˆû\Z‘ÍzÞ‘³ѱBnÀ^âkŠ,.Z¡Ü‘¡‡b¶fE:DXpãÌ–ç%îÀâÛn`Z[Yë,qfÛ\jÌ{ÁWD&@C—.ú½ŒTÍ4:ãwÅB8ÕöóMdžÚš@kwÅäPÐþ‡`•Qr\•Èfq·-sçXØŽ*ÔaMÎL$#φ˜P ¡3)€ûJ|Áæö  ÅZ†uB’o;]šfÉJ/ƒ—RÃc¸±Ó[c qÒ^!¦ñ™êÚ›Êô‘x÷zÓó¨ŽE„à “"D¬*‡M‰Œ²8‚§N –]ÚÔ¡Ñ{˜¬ÎŒÞIõB-y Çžá=ºeQKPs yx<œêí†,%¦·w=ˆmζe©…k-&­V¯åŠÍOpÓ˜S¨ÃqMD'cÅä* ªÌ¼®cùÈ(j9AŠäDl&¨R®;gŸèøf°ø$íöã±Úí±”kHîªÓ:'ÊD•ÔÆ^äÉ:S§Ùô­?‚^.ˆ­ÇNäNÇk¥™³Ú™n_vöSìMåmgzØ¡;ââëhÙ3jO€;j8ïšþí¤?:¥!!POƒ=ƒNþQ‘̰»zqèüfÛ&w¼B$ªêk£ ´Š¸9–å±ûÀ2¯>\í:´{–ÛׇcÞ†1ø²RwD>û.”EÜk¤7âꦡH¤Æ cƒèàÛOGA±§ï'`šÀ»×ÌVt¬íÍ'îÏß•´ˆò«Ú¶¼B»2××^̰޼Mú5¬8•;ƒw{ãIàã±ÊÔ÷d¤uZ¯ï˜_#Ë܆ Áùu±h§&æ}ìBöƒ2|i«¡úN¸ Ë\f·ºQg°I–˜ó»e+¬_i*Iö…îœAý?Á·Ÿ¾ÇwǦ¥ ’jÓî®eàÖÔ,4ç2¸‘öDê6U«`áaP];e0ΠÇÛöñØjz.JcŽÿ¢|,Í¡Þl\½é©ß;uDç^%ú­ YŽòðòC8šžÇÞž ibtg›¶fƒ0Ú»QÞ oÑi¤WÔˆêïí‘Ai€(øö“Ã×pxØJû”Kwº W ŒI‘½`§Û•oÕÛ=w!xõú Jt´=EêSEDxôÊ3Õ;AWмªÏäS“>àB`#ƒñ$;ø&œ[/#rÁ–Ž>òPÅ#©]/J¬±og0…<«[T,!ÇNUÚLDH˜™‚o?9å³Ç±É ¤áPõNXìž©¦>?ìWæ÷ÛÞ˜™æV 1%’o[¶Í§üž³ÒÇ’Ó%µTOÜ÷ï˜ù¦rì$/sOšIxÃ6b±ÃÌ0›ØAS¬³>Žm <Mz{Mï ½Cœ˜bº|ù\7ê&Lºân^XÏKc ´¶öK¤6mC” ¥ñ}L^|WÌÍñ]ª°ŠÞMw{-¶:²:#ÁIûN{ß¾mD‹—òX›r·»St'Á*ÈXؼèUÞ¨Èl»ïÈ™õÿaMd'‹ZúÄð0:Ílëš2½Âf8€QvI mÓ‘|UX4@ì[[î{˜‹l„"µIŸ¯ÖTBX3$F«v•ÝVªñƒlÝm\“§ÄPå^ÎŽ•,ilÝ6>pIì˜7#8—ïÂHi*¹·ïØJ?>Wå®Ð¡Š ø„ªëñ…”‹%nŽ1ÀdµãVÖÊ`‚r˜÷œ7?Âêð\Ù¼Mã¥5rN¸ìs5Ô>V7´)£¶[UC›ÚÙ=Úô##b¹‚AÒBPÏ‚±öŒù@&±?8{´Vڣ蹤JÈàÙëbûrJ¹RæYvâ«0¤X´¬/ždŠ·Ÿ~1llÔ5æ–Ù4òZQ7dÃòk qÏ[%xË!bÜàh!IH2¹€ÍhŸTíwÒ²Åí ´]ÈÛ£y=o\–¯c—ñ4”*Î:Úÿú*iÕõsµÃc²Ôõ¥Ö‚OŒAC¬ÚÆ=íi/‡gé§AÒ÷\ÔÈe'Íì ª‚öÓÝPhŠ®²Œ»úâh‹üE­@f[;î€Sf¢qtœ/‚"¦€"w`ÞfJ?[Út}_;ÁmÞS’B¶]ñxÅ| TÌém2¿Ñ óñ!bçg¡©J—ÇfS]d¾âÌÒÊwì»PÔ6f è TÙ(­^nøšÁ1I*"SCîaK´N{¨,6ïífwã¾Ï´ò}xÞº êÏá¬~7  R#Mjºîðt1»Å¸Ã¸•ÊU8è6—¢)ljûÿ¦çQm´óX¼m9¥Ì#_Äæ¼[NEÿùÛQ|UQÀ¶y¤(žAÝåϸÅe®™æöûJ¡Z$á!û~ p-²*Ã2Fxé%yq²5g0ˆ¼ôHU]”Oøò®§éAìf yŠêZ¢½¹<¬0,ñ}L„—õòÄ'Äaxéjù¦W-ü½4”A©RÛþ\có4Œ ’ë.åIéQþæ ïáÈëò8V@Ú`Lç&°I³,K鿦ó-©[N¶Æ7­KE}Ê»9èÒôÚÆjæ %À÷‚=‡òC¿ ú)£qðM3»y!=e øå £ftÀ–+nâz¤á ¤ëÒµRtÑ{ˆ†F‘À!(~¨‚iC~ø…™œÀÔâ1„éû•Éøî>Û¹ùFÝUÖ+U³×•2wCÍAWÛZBPÌEÀò8«p™%5pÔ£u þA·wÙ°®i•,n¯l»¨x0ÎE…%&ƒ¤Æ¦>K¸€–䨱R-G,ÌÆÚ¶ŽÐ?R¥ ù­š ƒÕܰê Ó¹">µÃ.p4»þ¬âµŠÁ¢épåÖÍaƒø°ŽH9.]l³™Úl×–ïÐâcøX7]‰ïi2ˆ ›(N79‘û»lº•‚‘Ã1jH"èg$ìQr[Bß…¼ Õ}mi’v§+¶ú"fàVM_Œî4OŠV2t²X¸6û¹ ŽçF$ë:6ÿ}ˆ·~O0Éà"ss4”C;üéÙ>±®¤šʉ.sÜ¡$êLI21l~æV–+3s5Í+häXÃÃ{z±Dh1W³#BÖ|P½99º{Â{ráUPU?}‡ŸŸÇ¶GÓSúT*­à}®ÁH,Ñ’¬ë¶å<ü‚u÷%(ì~î¨pÝ8Ó®ÎE³®J¾0í¦‚#š'€(°­Û¶P¾3õQõBX õ ÇHq£-­enD©ãXhÚñžA[GK¹ &9CY)PX ãÖAÃ÷î¸{{gMýØž OY'p¸BWÌqr=×c N­ëË›“­t…ÏÀ‡c‘ƒG?î”6‘ƒWy íˆè‚³ÝiÕf*¼†ÖA Î¥Ó"8oΙÖ³&@‰ÖédÞ½fìIŸÊÚÙ:g=éÈoÅ™»Í‡ALÏæ¸=Ã`7ÑMñÊÇv©žT>A+Ê ¼ƒ³Fâ¸)cÏ©ºª· ±oïÒ³{æ„ò¿pÊAà¦â‘N¹Tÿª?m?à¦ÍOñPvûUaêJÆVO° š:¢24Žø:2~f¶i=Ôêu¨l#Ù’_<‚Øg«þ°ï%µœt·g"^ÀåàÒÞq<º…ç+&+½)·¾yœ×Ríøê,Ì–J÷xS˜HŮܪT;÷¸-zLã䱂 ²žs¹… êNGSuNYÍÒ¦úŠ"<—«jîm`q[\åJÝË©ª©ùŸ˜ØÎ³ Í*T û¥èUÐiÂâ½B7çî®ÙeZŽhÇ{ è(¡:`â¹ß§þT½#"¨^B«¥è$75®ù¼@¸CïkäÆy¹'×Ù.¾,Z5©ÐP¼`¾“†ˆà*þ*'jˆ T»³ë k]è’c{ÛaP Á¸žÔiðÇóJ;N™ Œzº)wb¨5`à,±G :%ÊuS,b/ö@ûÆÿ{Wa’Ûè—•báŠ5Ÿ݇q´.YU¾†dñÅÓZÙcA¾)²a–4^ªbhº¹¤¯=€ðRR'ÔÝšÑ?’ùþp¯Ã`WÏ."’ le–Ѥ]Œ°k€d¨VLU¿!ë´iÂ:Éæjf°Q.I$҆ŠáÜ^7¾3æmÛÕüÐóç/Õ"‰Y±&j, W‚¾EÞ-à´èt1‘ðeÓ$ÛÛ-#ñe}ûlµ«¿’{ÛcšÊîóË…¥2ºwõL=hDEá›öß"Ä‚#êýwÉUN*îTïÉÚ·½Én´t§à!T&¶»®¬¾‚è †©ôO³SSLá¢#Íœ‘zÚ9³Y©(X/|£§nù¶ («ƒn7ÞI Æ“€Ùñ³aqIGôI u»\J$çЄXÙx`© V¾³Š¼^›bËnR“¡Ö "ÅÚVM€„s)ê"Aþ³QF=7ÛÝzªã˜ ’ù¬@Cuâ[ôÙ‘³­v’¦ÏÊ,Þ©¦‚·ë×´Lô¸ÂÎáìpoÿ ½T\êÄlÙ[|Å…4NÇ#",Žê•ý\@‡о’$Y•à 9k¯t§XȱFã´D•B0J­È¬‹õ}(û6u³§n˜Ðߦ°8rû zÂÔJnú BH¤³¸ý•,è`ÇýùÁP¡-ŽÔ™°âhn¶*¡±~Mgô£¬,náYÖ =û6²JÅ=¢QÇGФ&†›7[Ê¢Æ0çîç4SÒšïzDÕĈͯD ¡«£]MÏ *ðÔ;-dcŽâp7yWíEóˆðíd7LñÝýª“8®¦wÞÆªÊ@@SçÝÁ¼Ãýóc¥ÑHt9ŠV ^ª>Ѓ¸ý®¹J"d$ÚDqû4ˆNµÀFPä{ ˜ªh5ÅDúôlV˜Ç·ÁÛ]{×á”ÞÉÁngº+.4Òª[òéq‡@`MJç5. Úí+©¾3é,.‹¾0hÄ6ì; ¸ª¶½/ O‘”<ä&$¸pí8Îàrî°®Û‚1}TAàõʽœT9è…×å€ǾÖ1A7[æk&ˆz…5—ñR%`”wXnÝU š\agÛ•J¿úPŠWª&®ÃXÝI‘t±!µ õÓ†%äŠ0€éŒ½*G½O?óA–ó‡Ú]™ÀðTïuõfÁÁ7çnrÓvÜAÓ#«ñêb)€%=˜weêÓ^5M.–Ì5b€’Õz³Š¿«ÖKÏàyìå–>㇙y­%Z –`³AK¸ßi]ƒÛí#  áàÛOþ²’Çvc­ê ,Óc€µB¶ï‡êÁÚ¡cÃOÃðÕ°OúNI¥õðEX|·•’èÝ©GdsÚUOÜl‡gk›éý8Túø—²Ä9Ýkï ÑZ•®ŸÇBv¢êåN3«‘Á ÛQãtÚa’Ý+\tÚ˜“ƕ؟V©ˆùû¥8Ìh5PYjQEm“11а$Xœ&_óƒ%{Xš?—#5½*h˜Ð¢VŽUÏ·êßOÞXÆ|ý¯˜ÝΑx°«iK¤àÞ±-rÐ/KñûPt1µÝÖˆ2Ì9íŽÈàã0±æK€{™-༿ J æÑÎC¸õþݱÃîˆó(•ϔئtÕ½ó=ÿ³g¹¸HÕ‹±xÝ;q£ÅýˆÜÜW-›­%V>´8T3#ÌVøz¿ÄÅ-‚H´®’1_Àó›Õ>޼¬.5ËÁ®0]’Üÿm¹Ý¡œkló ‘6Ê*YxØmã¡Y:¼ÜŒ'¹úðrÁ9 ±z¥‰˜Šøù—GG_SÖ뾃G_ ÞD}+ƒýö¯À+õxt^®âQ¤üuS¿*¬ª ÎVb?4Ž›ÚMN;ÄYdFdÙx&n»›Ž‘~˜W¢‘#jàq`‰zØ98ë—•~®fm¨Û_Ÿ„{VÄ=í$ŒY׳¦öâ"Œyö[·¿É$°™]†£'[†mx׈]“ã;wè·](XA«"ZqتB Éâ©^ÒÉ£=8 ܇,N¹,µ‡4@N‹å…hU«y $ >’‚™*TŽ èÖ<­DÁø û'ÐZ ÂÊN°ÚÄÞeHI^×`Ly=[pZÞÃJÍ1×ïªÇçr&B*ìÍó²x;·Þ”=جª¹»ö0‹g¶ëSó8óÁêiÈØ¡'Áö¨$› Us«‡†nRŠœUŸÖÈ©y{Ÿ„k ú)R­È„¨ 5"ú«ÚC¢¥†ŸŽîÕte3Ï~·aK¸¤§ìï,ùоžÑ“êÁ`уÌ& gÉêi¬äl²Zýw´¤í# jù(tM5¨ä r5—ºþÙ#ßÄ^xÎó%ÛÇpBMÀ]é›÷aÔH­ŽôÕì÷÷û9³£‘äÕåîæÔ-[͈yëýwG{Ä‹îÎð¨Ñ±MŠ–å:Ümö½K%(ßÁÚ¯VrÓ¿Ö±ê¾#‹^û’ñààròûb45‰(y?½/,ÉÈç,f‰ÒõÖ…‚¶Ý_¾b7mçoãr¦'ÞéaOØ7™à:Œ©#˜î_Àû»Ã.=Qÿ¢)o'ž­`3i…›š8ƒ‘¤Çb/'ƒ³¤t=–†‡lôJ´¹>Áa6ÙæY_ÁvpiñÖïRÅ¥dý”{Çêåq·s \V-¹­’÷àNzÌJQð)+aÚÔ)PòM1‹Ëº«çÕÎö.$N=ÇG 5”ÎMêœÆ .“®-§j|vT§ßnFì'83 AŠ›ÊN‹;-×¢îd>­sð»Rާe4Ïí…ó˜nWް3R¦ø#ùIiM ™×ô>%½÷¸ÐsÿʯB~)L² ’’L*ô´ÎHÆ¿ºô1Lô²4‰ú]Aï܆În‡+t îD¸ô(Ó³ð¤$J:¢È”ůîVÈ)$=ïO pÍX3´î§|w%ú9Î<ûì³ å`½ÝS„™fÀÔ*‘ÀØÐŸf N¸=3ëÙÌ)maN¾1oe»²]D<Ü8Ž-.=÷ü÷$%Gl]žý•(’Íå=À†¾+kÛrr6¦Ó¢íEÕË\÷ˆ¸öS«ƒñmö›=72áà"®ìÉG¶ú1uúï/×–Mbê¡úœ´Có5•©ÅãSé6‚§ké5¹Jͱ'~²ÊC0×JCl·Úþ­‡ÍQ~e>šäÉ¿ºÉ,ì?ý¾8_Ó~…Ì77­ŸçÂÒ#¬¿2_ôe)”À÷¬ ,N×/÷ÉÎWMOíP#å㬾5MDÐö Ìå"Ä6ˆv(öçÕD0’¾šëd̃³èC«¼bpuôßÏ¡©˜Ø³SveF+Ëÿ÷AãF„…η€Ÿ$´@kâÔü‡ ìÖC⇀léfeÁó£àsðM»ÕÊÙ/]!@… ®ågjîü‡Qçå刳‹RY”álzö,/8*̳çÒ5ÏÞ²»½‹Šõ×ÁRo5ÌÏ“I—v‡´u¿éØ#ÆoèÇ&.HÑq»ï<¿ ´8h[ SNÌcGNF¢-ä¸ê+P;U 05ΤEAìüˆT‰Fø\œåó²þû|¨¬•âö3jŸ _蛇Á½­ rÑo†Ÿ³$ew—]kX(¦þnwwÒÿ ¹U-aCŽ<†‰Éè¶}¶ãJ×L±Å þ3#øuf9ò0äs^ÔTe¨!–ÁŸ±0Ÿ°o>P§$7rœÐ.ããã…àòµb{ž)ñó^‰líiî´žzÞ¯aº ©qm)Ò­jUÍßÊtg„曀-›:¬ôS§©·'”×Cq§æ%IY†ã»Â kH1‚NŒ´û ü†íìHÛ¹zMÁßFe%{œecXW–ö÷!Š^©5Ä3ØàtcíÛ>¤ëÎä8N“€)•ªàp»|je  Öelîˆ(˜ÉG2¢Bi›Ž DRmú¾[ûPoµ`ª•ä]¨=—Ž?YÄÑ7tÞ·¾›ƒó´º¸RÁËöB1AIR¿wˆ1Ú³òéQ$’9u]m‰˜`†/6ƒ†ö¬G{Ë*‚ƳµaŠ ¼SôG6Ã&>i>Ü’6Ž‰Ïø*KƒyÃû?ëüÀü+±ûÚow1¨ëƒÁÚsyŽg²1ÜÃÌý¢Çýš/#ÜÿÎìh¨;P/·Ã9ƒý”$m{q[á‚ÇFzø¨¬çÆøX¿³Ôie&:±ˆÎÔíp›7‚ R§n×ë"cI ÐïºÜŒÒ…å”Ç“LbiW¸ÔIMfÂÝê?†ÎôH‰žáéc•¶²Ps‚ÙáÛÊ£Y_¦>+Ø,hb†ÃjÉî.1M;kr'I˜5åÏu‰Á|F ’0{¯Ž­åò˜_ÐR]²Äræ30|VÜ¿Àd.!žlÌ:*#åaÚŒðèß[ݳ8Kb„…#Ê^sPj…ê¥63t· =ø 5{"R·ºÃ‘r‚Å;ôÔø~µÃâµ°ÎRu<Ö8]fLåQ®aЛ%´ůÝ@7ö9·g¾ƒðÅÎW´÷íýÓ¸ åþ­äµRð ÖÃÊ8Ç=A©ç®mZŒc*û̃XŸrd–vÊúJ=âv /5>ƒ;ÄDZÊÈçé%$ª9ïGÐg |˜áâ-èiƒÉ)µ$·ôzN©(Ûm¡¥n´â¨>væuÙO=è…®ôÖºSxý2þ¶¦}„¼ý¶Jýã¸×l 6˦¬Û^¤ìÉþ»ãòsEÑHÁuÄwµp*hüaßþAc[ËÂR 4_ã:BÞ—û‰©aëü)Ë%W2°ô x¿NçïN”kwKÙ»2sAÏ.ýõŽë PÓ{m+yUŠA8©bñ5a0éæít†™Y"GÑßF™iá„KŒt$p¹’^C¾ó¥ !Ö/mNFvßQíÕ,¥*W= Þ§Ä5(ÆSœôxGðñ´§,æ Û âà?‚‘IŒ4`ГeImÓ4ƒ\j[nÜt4DŠw5{ùZ~Õò r»×§±wè­ ÿìÔ´ºûžnH¿SÂim¹}ØnTpä\>ÏI &FºãÊià!’°_iœb/qY9F/óc ØòꆴS‰í MÛo¶cÅ‹‹îsT~¼^»ø_Ñ®ûÿåsý»ÿþõÿúO¯ÿ€›÷ë?ÿs) ð°õþ«¿]³dÓù–ëW}°Ó]x¥ w­æiBÁ¼Ø/qt½E½¿ypÑsÊØ¦çpŒ–~<«ø`ŠüWÑ#Ví;7͵›@ ÂÊMo ÑŒ$ ÉOZ²tqÝ3PmtÀ`¿°<Ç] Ùø ž« þ ö‚1DTâ*ÀÚ¡/c¡ý-‡À3ˆcMI¯èl:vé!8ä’Ç+IJ 0…ëð¥Ë­YûÄ«NØŒG7ÔR&ǾCÜÁ[†Lã’oѯ56}Íg|`Õª:´z#¸•^W´OžE5í+†êcÇV ¯†Ã´òweŸ‚ÁÝ:W¨+îº}m±AcÐÛ/Þ§LÓ÷¼Õ!c9(%µ›:TxhöEêýå<+¾pØ2nàÅ»:C{æ[þÀ:ÄfâViºplº£ñÚÇLÄÞó~Ħ™ß¥QžÿæÛD‰&ë’×^’ ¿è as×[Q—‚\}÷-„2`‹£ô·‡É§:7=Pãh˜Dðîãƒ)ið)Çv€gÓ ‡]‡èNîñA—lY§gd ýÞ\ñöï yˆ¦ÕRÄç…é|Œ€o=.ê^‚\3iç<15*Á(—R.|* J9°I8¸»Ù0üiÆ¥öM=0ô Œc Òpêí ^iYrˆÃn†JE~ ¶Ä¶­!Î÷÷ü-‡3~p©?§ÄÄS“eçØ;ØiØBßtåÌ¿˜Äë6JqÛJH¯$Dnfìô‘÷X/U‹¤l¼X,{¦S#Î"èp{¸S/Ïâ"2„®iáø×Í¿}ô•ÁðÕ䑽çÕ›Èc5ÄeE&P(ˆÑ¢ófŸD”T¶UÏI”ÊRÉVåI TÑü¾Óí‰ÁhFe°ÇRëÝf4)æï m˜8Ö¦ÈÊãF×O&2ùñú»"(2˖έ¯Ã²ó $Õ´Ý"éÙ㋎†“@ìã§›}²Ìg"dØo²ÈËÇK]t(aÑòX^šã”ëy@iÊ9u°µ°`»ÃIÊäÝCDöE„¡eÆÁ¿­`QŠGðµù,:3Ý}¤V=O÷1ëÜõùšÜwÌV[8A U5\ÁmÏ!òÕæ]û!ü5I¾ºÂ·½•9BÉñ]ŠGŽ[ä`øÅæø¼[\Ãlæ-‡ˆÎxb-1·¿†ÄÞ¥hã¡ËSÔ‘ÁÒ 0½ôW>ÓµM‘å.ó”qߪß¼­¬rÇž>‚^a$$§§¥^ªZñ¼c .;ž²xÞ‚6‚ÅÚÚ¡¾ç¬að‚v•Ú‡¦›8‰š†AÎC]ÛC¤Î¾0¶VBÁì¼›^[q´@z4eÊÁÐXE³'vìßÎÑ…0=º×‚*„3­Â~‘Õ¼æ<€Í ¾^OßAb•—†¦T9±1ȇÊAV¡"åøbÅ/ÇJË.\ L²F£®ýÂî´DP=¾­½PYÒÕ·€j2ñj¨ô5*¶žÞwzèÖêæ™-Æ„¯|IðØw®¸F!HS‚½ò²V¾¯ór%d°õAËCð•DÊ–ÀüYîD‚^ÉšÁº»†•ßæöZì«^CçÇ'tmèḗ–Wàs~l%ý† <(ý6ÏI° mžr3=žŠp޽¾ZÏÜ š3‡#¨ÉÁî.,[*/‚}t?üŽja "±ÞªtDP«‚š4ÚÇç ³xѽ9“÷‘z½º—svH_Ôz~ ?ÇmdJÚ3x/»äÞ]; ¥å›ùî¼>½ëömI* õ,²(x†à$K]rÇR†gá{*k4ÌY¡E–ù`ðA(o­‰ )T—P™:‹m~>º<‘!fŠvRùs>÷ÊŽçÉò£#·šbü:Ÿ.[c½&ŸË·Ð ?™^~9buÏ­:p9Ü…9ƒ·úíÜpõQOs3ð„õlp¦–Í'íAÜc;Ãâ$÷ sZU.ÀÓz©!•€zšVÕ“0¡@sÛµJÎŽØ5ÙÉbàÐëÖ‘ôÆ=Û´UÜ¿K¼àì¦%¾„¾Ü ŽPWxgðvhݾ…øÎ.v‹Ìª…Š{½íÜÒÎVúRGºÚWc„fQ%z`Î\¹ˆÑØ?CpDm_ø_VÙ#*žÕÖfd×úìª=fµO‚f¡Õ¨ÓG°F®ÉöÜ3ï`0,ÉÀdåóù@|¨äÆrÿI­LæÏèL߬f>6—)1×jˆ÷Ë£MSƯ,+·UV*V{ßÂny‹çe½×C_¢Ã{­¢;kYÄ̰U–íl¥¨Àþ }â/©PA¡(oµj¾·Í7´Ûàÿ·ÇØM¤?/ùÖÇ&Ü}¡_ò·¸Ñ`Åöù\Õe¢þµ–× 2hëÿuÎy³º]ãöE½³'K]Ûñ¹ée™ŽíéÀ^•i'Â68yì÷ÛMA[ D9Ká¸‡Ž–Þæ&ï+ü'3¯ö»Ý H{¢Ï9'ˆO»‰áÓLu±š[ØÊ€}!zàIÜÐÝÖ…-R ”Œ Ds0K«Çµ °|Z¤ò~­ŒÕ-Ùz^ä3Â7ФéuAJ’ÖÁU–‚Å ¸ƒ~›ýªœ‰z#‚ò«¢”P³ÆØy™©$+Öšú:¯‡ë>Û¢=îiEØ#¬t§–3m ûJ,å±ñ´Wâ gœyŠÞû´¢´ªÞŽ–íL2s0ÂM+U_ ëÄPW*n̆ÅO¡ÃÀð tß0W›´f×`Òø£^Ó)1°„¸Ä€\q£ëÝ«5UÆv?'¥º<ÄzôtŽ‘š&véÁ3Šàè›díÎC¤ &ÚxŽÒ‰<±(Õx¹–d{ài¢± -×ÕÝã6¶{çúrКZ+­ÝÙPw¨+çòQŸ=8Òï+6Ñ_ò²I ¥KwósžÉèLµú²q'%ÕÔ| ꯋT+6˜¸Æã>ðÁ=4 Ô´Þx%йårŠþ׃Ë{þ|t÷Â*3$!Ùp¡Hü—œ7¾>Ÿ2ÞJ µÄ®Z# P×OÝ”Ûåq[@7~ù•3ŠÁÒ¶†Ns“kÁ¥ºYá¶§‡˜{éíp{ȽBkzöj3¬ÇÜŒ¢»/Ý=|^ïŽ_O±+iùe¯´Ð³‹îìÒ®.DÐ,Ms•üh€4aiØô°ËN !£ø_ç¹½ò:­¡ÁIÀeï·&FëÂà&Iþ¤…Å{Þ¤+ì(ñA°èðP´K)k‡\±w*Þ˜é8ì·0ZÈC!ØC¾U)x¬ª½Ûzæ+‘0G- ÑB63Ž&š«ÔNx<8¬V¦¸%¬ñ z¡Ñ·ÿ-Ë Þ·HÉx–…_-¯–iʇÎÇúŽ_¨.’•­d½<¤*-ðÝ‹UŒíÐ÷žga•;õ´{uubŠ‘æ_x Q{¨hiˆ^u 8¿àŸ]Yu\Ùú5rÙÆó1̦e"ZÕ¢±©;KÌŠ¶PwSˆ›W¸=ô@û—Oâ¶3´Y‘îTO¤Šòôi.˦Ão91¶D«ÞÑrYgΚÃFh(ºÎŠÅ$üö]ïûH8iDÅ:‚´·ãSB߯ët—<-{/Ó™¼êjhÊæ¾MŠjjÎå ö;¸ b{cˆÙå_aû)¬—Õi£ð J$k5!0}ùšËj*m ;Æ’@ßrÙm©Pé†CX õfg&M^ôîé<Æcˆ"÷§yZz{4{oz8Ÿ!z)ðÁÎÅßmz#i¥?˜œÜv>2éEp[?2×þ4œJÇ=DIsF£LÜ¡7~¦ð8ƒ»<‚oçö…&ËÇ£å:N¸bÀ×ò¦q™í½åóbÑÆõ`)Bf!öéôš‡¼³õyø“¸°K®Dân024ìj|oi8/ÿ£„ÚŽ[A§Arö]—Õñü÷E¶êW$dz³wà÷wúSH«©R'c¿îmÛkÇ b ªEAMŠç8‰2Uôz?ø#¦ËVù}Ó€Ó)e,šQ¸ŠKêÄ[Ne4UZ,7JI³©jCnEp]û1Ä5‡JTö¥¦³®í‰,d‹EOžçE.2ž:ƒûGÅIâ¾] …“ïÜ:Û¾ÙZª\vWWd;Ï÷RLóî!­<ãð¶Ây©ÈåVÖAóPŸ…Éæ©„…/»Ïä[¬/Ž¡õÞYj±Ì{¡\ÑúúÇ MÂOl³ˆ6™NšMRø@&P;tO#è’öΗ¬oÛ:¾ôâ-‡qí(9rùèÂû;û{¶ïBõee  ƒ*>pJ‹£#ØÊ=c ¯‘XMòØ!cÔ‚äWB`]Cˆ=V2i éœU#ÔxGw5wÁW¾Ej† ŽcXyÖ@§ãßÑ­ï¡ña{5:p§>l¿‚Þ¬Gkçî­m±ýqk-7Ž£]u£–\6:–GN‘øÕå\¦gñcJö®0Ãë¢â°å)‚šÖ¡b-•Ó3Ânw|@_e¼5xl§÷ ‰´8E5´…N"-ÄÄ0}°˜ž5@×JÁG΀»œÈL’ä]_ùÀ‰¨§t;ÕºG{œ„,øÀ™ê2ŒD"Uñó)·CÚ¦Îù<‹á/d û§çÆÏ‹7~)‹¾ƒœÒõ|Ö(SF°…為Ã94b׌›lÙ`X©« O‘^ÁîîÝVÖ´òù¼5¶þØ€µK:v‰êIéý1Âkmz®ÜÃ…œ%®pIü¶7‹áM}þÖj| *žîjžiÁ×&S1!mŸEµ.þÏ9£¨ï5zq=B …t ¨b=ZûDEE#¨(!Ò•~G1tÆ#Û³;PÓ:m#ãg ;ú¾«h*¼méG'Ç$Ïàƒ+r°Ä¤ªÝ/5r6Õ…À”ÕER{fY¯^§4ô7Eh}Î`‹‰ ÁP½CЫN¢-W8–¨° ^)g÷`ÞÖ“e}R½_¦?ó1™dqz¾ºäH_Ã>À-/í²”ó]_`]lóޏx5lh é7<ZA™ ýmMz!wjÓà°»ßùñ<…€ ©Ó¤,‰:+/¥P„E-ü œÒî:½xTåÔ¥ÝV^JBp+dšž?µO6›÷‘e½ÞÔìè7š—féÈÙû‡_Á´™H¨ót§ÍwïçyyÉÆ×òÞS¯.;zwW‹ŸÛa ‚²†0,l#¸¶ƒÏæá‘}ÙN?Ý -pà£ü®(ùbÃÞ>ô÷Ä~ÜØÊà­­5]ú4Dˆs+z}ðA_ú@×ùÙ-yQoéµôø!ÍxŒä2H\ M P †Šë¾?²Ø¡at£¹ùMKCp5Þ͇‡1A¸ ôçïhÍ-úIYÆsxi\zÜüÂ[úxAh¤å?ô龋1(ã†>¸Ú‘ÔÛå>Q6œw4=¶9÷KsOåÄD:§4•³Ê>½é—E‘‡`»a¢-aU§©v»éèåÙ"#î%Å+qâCÕÅ¥n$H/Þê \g×jŽ¿Ûl,Ëíç¾<ꦻe…š_U‹uÅÓ§!Ft¶^ÖGF°Q‹¥×ÇÕ„@MXÏ­ëtyß*늟õ ÷ô™“R÷Ct‡^zî}èðxw°u©ãÁfõ×’XK?âƒ4} YÖBçnΦ<ðÑ{ÍÄæh¡ÌY¦|æÆCpoyö=8C/£kŸÝ¨îxäf3g“º¶­žØùò:ùx¬LÿZîªÙe{?Öffx˜'Õ2º”S—D"ƒdILûc>Ò$Sê6 Ç'BðnEâo¦ïô¿þ´I¯Ÿÿ»óû?þü¯þúßÜ×Ïïøúÿð§ßÿÃÏÿPþú‡øíCûô¯þþïþÛ×ðØûûÍÿøÛúýÿú§?þîÿÛÿñÿôoÿã?ýæÏ¿ý§Çñ[ª¨…±ÿþøý?üÛ?ý÷øþûßüö?üãïùWÿÓ?þ‡ÿëŸóçÿæ§ëç¿~ýßßýóOú Z©—ÄNoþïßýæøÛŸ.úè§îp-CÒ½ (ò:öW”Lµ†ªËþú§Ê©×Ïÿóëÿ÷+ôÏ?·Ÿÿ—Ÿÿwýüøâ¿µ„½ö1’Yú*!]¡ÍhM  ë¡êNÉé+Q¢X¡Þk»ð*Õ#߀bK®ÃÈBÀ.ÙŒ)3Mt/ 2ï’&2ôãî*úáÿ³-9J$3ºJg“‡Àmöq">?w‹-÷ÅþUÓ¢ éEÀ.Š÷›¥¢ƒ8¤“ø]È‚xò8ß9m’íßöMZѾ8ç:<‚(X¿f-ß][lŒ5%_!À‰¤¦7ìÇ›ûöÓ¿ÿUîýÏyÞ~“;b˦\QÞüš¼NÒùLõ¶Â‹>++}ëþ”_•”m@¼²‡Ô·Ëhß{éY¸åqÌÙj8sÞ–d—ªÂÜj|~|0óƒÔí] "³Ô–iÁžçs~ÐÛ°ìÈ>,%xé©–7£Ûlw›ï‘Æð¸wzäzZ} H¹ÎÙÕhqMvÄ0c†]Ñ®m˜ DžÌeežÇlK­¡ßƒ×è{·yþL¡óA ¯$| R6 •ÛçÑÝô:ºþÂY/Ãd߸ŸÊ/õûˆJãkwj׫?^mVŽûüñþ .ßQ¯Œž÷¿ìÇ_,â´P?>¸îúñÁ#‘e(‹é­üðSA©@*Á´Ào#úø·šýˆøUŸ,³Ö² àC6 z“]ˆ‹å·¦ Uô‡QPóÀRù@ÊÚ+X¶q¹¬Æ(!B91 Šz)3!6Ê I³PŽ6ÄÕ: S¸1Bq” (þ^1¼…°ÑXì’ÉÎRʹ"èTÛ’ßíl¼ÄÝíïöø«U*X«ÿ»VŠˆÒn0W‚hA®2伓Жrã„'AÛj1Àš@SÄPo­*oÆ|z½ª}—¡ØL'¥â¦ÈÍRèH)ƒ¬Ì7¢.€—ÎöÊ L븉bœ¨ê5k³>[z¸á;ä§fˆ våCeÅC‚JnŒÏ2¤¨8'‘hè +²3Þ}jl°!TšbÙ\쨘P¨«è˜×Ì^1QB ÛPºY0ñ!>9‹šÎEÅʸٕ†X¾ê3ÍYAȱÊ(èn×™9eÍð¸Td¿=vÎî¡_¦‰‡M¦B3 ·%{»œâlHh&jt¤¶‚º}ü}Éúh”K@ ¡ ÄÅàp±Á£™ÈßgsI8kðµ») ç:0dÐÄãV-­%éZ⺣¿ŽŠBͲ<ðr¢¾³vA oêSUé*™Ê;&[ÍúSoüÄhAâwB1Ë3sS—Š4 _z°49îQô;Tõ[!ÄGܯŸÆÉè&”ΜD]tZ)θNÆË¢9 åJU#·WÍ7&< s#t#U qþíü´mÔW°»ýÍÀxѲ !›&ïdòf¼‘ÓfƒpOU©M–îp¶+ÿ» ë!l«6‘åÜÑoR*P¸¹•hŒÀåyB{×f„£æª’ŒœLÓ®Zh°¸¾ _0f1Ý1i'c á P9áÙGÀ—&jz|}ÅVÚ/»=—¨U̼<ä™B©¨¬J7*ñH¢¤·;J&Ÿ£¿Ä3”âÀÂLÇÑÊPk `z€Ý**>¹Q {Ò<`Ÿû¸†è/~‚ð[ÿ+&0KèaNâ¬@†Ì©r ÑLd vº­® ÆS5i“mâª#ÍZÏU»½Ö ±²±bw·/dlJE0…rÆ:?ÂÅâö3/¿¢ãRLŸ¯ª¦àå&j!a|’z½:Yp-C‚šKµRÓk™^â<À8u¨+Ëf£Ëó¸:`ü‰³V^{WÖ‘»Ð0d¬oDTO4,“¥ù¦oÒUchÒšìÞ-ÝÃQf¸(–÷§Xœ*›I^ˆ9rcÇÊŒÈöu³¿WÕsú_*ºJÿSƒ Å`ô÷ÂtIF»y#°-øf•‘µªB€r3‹S mÚ®åïÁ*Ë;>±´ÂXÀ ;Ô!Šïä_âÅpJ“ßWÉØ»¨¹”Œî«5W¦ñbu†¬.ÉZ¬­]„*LVbjÀ—WÅ3…Ô=¾²"JÚè $¡‰[µ@Û¥×1‹ª;pB»EcWÜXì€[ûnv·Nôm ¬wéÃMRr”7Ç4~FÝÓVUì"Õ!EÏô*Ynñ-U‘›À°\|Í8›'ŽéáƒîX\z\›ƒ"€ Öµ˜X6‘æ±ùWkÄ‚ÆÍ |O&„¬¢Œ°ÌŽ0¸p¸þ¦a=Å„›ÕÙðQ;(2D®|Ä©å¦0…S\[³ ICÖA!2ÉuEºn<8ßäO<H-º×,…Ë'•¿J²áà¡HâÔ~¹£Í\"è% r/wnO¼˜ñ™õI°„ÉåОâ•q/Ö–‘eòª=n'4BÂËE˜{´´t¹hˆW!×ÉIuûkvÿE®¿‹eÜK‡ñ„ŸF]¯YDÿ¶­÷Ý­_dÄïÈ¿B5˜j•sºr…êÉ@°…§’R³œœ,½!z­dÞé‚ëθwÉ&žØø,ß®½t\hÆ€Œ ªæ9Ÿ"ÖÌ`ÒãÀ–­kº*^Ï.*ÞÅ¡0Ž)‹ Õœ=®»x.\!A¿Õ*GÀÄ0‰À7]ÉÌÖ9”«T…š¡r]`¯aÖ±W~2årŠcÍÄÓPÚ@åï]ñ½PEl “ªœVɬÎ*eôM"§Â7AdÁh˜‡ËãBsˆ÷Ž6"e ØÑ·£4gU±‡Ç7›“>ÉÚøy#¢S–ŸMƒa×ÝHt1äùÖ"#+¬Eó1IµÔ‹Ö:h³ž˜ PM1Ý(¿ø·B CJ˜Z ”­V7Ó€JyÇxºÌŒ*@¼É­ŸÓîö¯LíH ^uPgp}þšfž¤ŒÅ@ãå›â ³‘ˆ#VÂh‡u>7Wl¸¸R’å ƒ d€>TÄÑh9U¤ Ÿ*^s«0ôrÍQËšS—¦©eñCBœ¦A›¼e34ȧ«E ÐU͓֫r.„Ù% ÂhÍÍüõïØø5½_4+jŠÜäMâèAy=š§àQQÊt-ˆ—Išt±«0åˆ^xà²ØùQJ^?<Í&¬Â²jªÉfÓCInd}ˆÉ¶%UÈàPÊÆˆ‹a1;yX£øE¡…Þ­÷aý5¸±3èÞ«ÃS³-Q7/¦Á äÌ®¨ß)} š"᡼’ÕpàÁ<®îK1aÙ6oç!M¦CÁŽ#jV> !mÀRýLŒ)¾F䥨¥Mû4ÐÓè)r`Kê¤É}Qîr/ æ¸TvË<|+´nð#ŠV_,YÆjÃjSÀg‚4{³ï‘P%¦À7¨ÚÊQ¯”lŒÖXogwCwv•¯`œ™}üüåb_k–Æ v‰žØÚ¼‰nË"zÄG(pü–m%B).¤ï£a²’F“Ì>S<>U%;f]jŽ„Ó³Ð½1—IçƒMT€´cx»ôí²^±Ð-w3ÕÙ—ñóøüØNkÊ﫵µcs'Ú;}°l·ÈñâÄÜÕÄG*¨£3À\°óxp40õ—l ‹pÇ»i.ÞY.Eú»]ïvøj3"»:9DQ:gÕBì³ÁRõŒêb‚Àâ)®éÍe;§qît{»d©mÕ‡ƒÈGŸš%Ýïf¦³@úÆ—»»ýƒé&XžUö=µrÕø%°@eó%Þ3lXp0:æ,BÞ+”Ô`’@¾s pI¶…p|+º¯†"k^RdømƒGÀ•×výn·UÇõ­œµ)ì^Õß*Ó²!8ŽƒI^à~Œ‹…á9W”É[1,t6sä$”ÜÚ:êN¸³šf™b¯¤ –B’ „k¸­–àSrD[“-Ú2¶Õ„£³•A+¤îQŒM|jóK ]-jÙ—ÍU´»}qÁ fddo{³4j™YSÞÔ lm–F!º³á·kÍÒˆj%×䣚À[2¿î UØu«oBŸÅòº¼J ZÕC\B…fB†":¡¤s]9éÌÍ×}í'©@‚ R7Á5’"*R¹Ó¤PWp—è¥CïÉÛbÎhðJwÍ®»T;%$#8æ•Lª*to¶9•‘‚."ý¶ƒ/ACÌMŸøˆÕÓªwê´Ö‰^Æ…ð/Ù‘¾V£'¹9ýFõlàøš„J8Ê_‹b½4ÍL"7š¡;´±41w­þ4ëÍ6¹ê—hìBÕÚ«¡¸yÆû‚º$)ipFM+¶£u+·³µÑºi1ŒÅé ö5/›­À´ Ù6u9   nÔ,´Œô4ÕÚRª±1— @ѧ\ ¥ØÞ¦;¿-- ÝÚ¬KhÌð/8°µYµŠÛɵ¶6k£ØÆ¬;±zÆè@›˜ÁϪ» ¬™MÈ´î2cÔ n3á¼$sR‰» nùr€¡¦˜ ©ïCü‡ñ–èo‹žWYˆD¥“P‘“kñå몡#Ͼ\V6äU—ÇÃéB(Ó„Q+? ¼ºn‚ãôá)¹.ÁÉÈ«ÃA Bº,ANÙ;«‘ZÎÐió2èÈÔ<å'#f´{Ȉ·<›s³åð7ZåRM"ÀMÝ·k,/–- B¿MIÏ[L|·»’>Á°ãÉ@ Œýïe:‰1Ýh÷`Žeñ¶ àUcP/…¶‚kIBà Þhõ„÷´e…,œ otCŒÒ ¹–Éõ¡Ð¶.æ ¶¤´$ñX^D4°8o öDiS„`Å>¨Æ”åŸ<„ÌJƒˆWuˆõÃÔòaü½<Ýb*Ï #»ôöX«ÆÉc–Ì$ݪÅàm\6jN›%šmÙóZІ–{òÖ„?ÕíwþÞÒb´µW·»ýßpÊ» "Ny´ØQ3?™©àaúE5ÕÉÙRšS7-8¢ëV“«_xQúõ…WÏÎmQ?=7OQ˜¤D~¯åÈL°¾K׀ذԋÖÁ€—I!tÕ4jñÌS!fm]8aË?ɦ¿hž`1¨®ÙÚ X÷­´Y_X‰§þ]— ›o€ˆ/‹Ø|}ÓÍ ž á›ÕMWª~y^Þàmq0Ó'ÈêY-?­&ž$¬sÁß7%z²©ñ÷ˆªIX½Ô(ž3Y½0°˜>CG¼öMâžRåÒà*ô0…¢h½yo‹<àT ñüs0¾ª<¶‰YYõ í”ÎV¿Hm*ü@|±v%¦[Cø 7[͉fE QÏsÁ£œ‰`áKœöJyH%n‰#©mJ“%!8´9Ò®\¼s £‹ÐÓYR|>©‰Øóc¶†¨"#†Uš0zãõoÞ7c¹PÄ(ƒp.*̇‹öœ²‚WpVXET~£¬Ää3z«\´x!KùJ•Õ¨ägU¨¢§G P…뀖8W7Î%úúbbª4ÆÈY…‹*O¡Ôöø‚@WívAVƒ>Á^/EèAÓVE R =Ú@:ó=r³·3‡/ñk§òjup½F+Ÿ6§ìem:g´XvT€-÷§)z3¹¥>XåðGr-‹‘8ˆ­Òíj-O3šZÓ §3²œ(ïÔ ²tÔc:+‘Jvþ6wjÝ»íUi{Nê%+¸±˜m´ûdRt<•ÕîŠC†""HÄN W‹qägõ®á…ãÖlÕØŠÞ£Æˆ¢n+ÑnFDd:ÐúÎsÐz‚j)ïp±IÀ›Ñ 3Á.¢«¢é§ËÞÒ•Õ–²11Ug ê{q Ü®~xºÑPT, 4P94(¨öÃ.ÊÌâ—Z¦€<}á5gwÕC%²$0u¢ aãÃßݺÐ6ñ¥*þïrÍêÿ\Ãå§÷c€/«Àó¨Õaeb‹Ú³ïJ'kCñ·ÊÂ2QyEñ&"mAä;PüÍTÛúk”uqI¦×Ö‡E¡Að̃fÕÚAÀšúB<d.dÄ« úU8¬†›™QG‘ t;UPš«t æÁÄn\=Ä ‰eÕE-ä uíQÃÌbàªþÑž¢ ÖØ¡D¹Ñ0 •„4Ž›îoá{4¿²›0×xS™Ù]ÉZ¸kåãP„Óæ›ÎN7jÑÔ$§×ǪeS)Àu¢"® Šòó*ãElè{p¤‚ŒÆÝ±¥Q,f4À]û+í­VUÞ®öÀx+~ìx­Æéñ‡Šm¯†Ž[\yÇ`¦PñæâGѷܫΊ}8Ÿ]³¡TRËþ¡s¤95FœklbŒ/Ãëæe{ÕFµçFû¸˜C‡˜­·NÈÒ=ÊŽ4 Ip#˜ÄRªHÜÑpA8쎎?}&Ìì„_rNqy:A.öïWå9¨ƒÎ£û W» ®TFiª¾neê”<´@Ëxð&ûô×&‚Ú…›^¬ Šm}…x¿´ÏZ©ý%þསõÚµ0š-•½©ÃëGbËž>=2â¸úRߣ°–J‚r"ü ÔÑh›âx+$íäu$#UãÄ3XÀOn ëô”isY=a%t.ª¤G@ÔÞæ˜“•Þ2Å ’Ä!!Ç.­C—gǩ˲YÒ(4elÇYã‘_®mW5=¤à•ÂÅ´„¢nk”m×V|…,ÚH‡8¢×HP‡Dñ×äP®ãä6W.Az›ã^Qƒ4&ºfŠ’ô6ÊØ7¦Ž‚ I&AÑ"¶A ½¨,`ˆs2B“—xˆLt]ªCJxÒ*ƒ€ë¨—ã°öBâÐ, 9˜¿‹ƒÏžÒ8sí{å>Ø9Ä´S2¢0ÒëÐÈB´8sQ=ÌjB¾­(Ó«ÐÁP €ÖPI5ìXT½ÒУ$­ÓpŠ™5–=ä¨ÉàH'}+W”Áœj™ØÜí-€ëdØk¦ƒ¹Ê0稛>ÓìMh.ɾ³oÊb ! q"ͧÈuêS¾„€þ…÷Ú§‹!šR¥hÇæ^A¶Óx£,^“A@ÒÃÔ®ºîÔ®íD¢{O(xA6ÈÄ)›#HSé,˜:êhÈ­s&dÇ:”=•Åã¬!Á6‘ᥣ„3ô VHש0.é6ÄÉøãÙµå3xÆQ_¼Iû%“Ôbº…l’ŒO&E°3§AðŸJÕ[K}´5këó ¼5Šˆb2wP³\d[‚±2ou;_5Ža¢©±. aòàXIJgÅ¥ŽzÆvN• zèY^lÔ˜C™¹ðY Q± [­%,¸Æ& !*ÚÆ=VåHIƒ ÎËIïƒqôW±H¤mÊ•P8©tí€Úå¯ÙA—_ÎIY:âÄ1PPRu  3©Éè}Ôi£Üä ÛJaóè˜Þk1Äil¬DƇsÑŒTŒíœI 2$PA9“{\¹*‰ŒàYU·vX>ƒLxåm©;Ì’X2®Àß„bÊ”¾÷ð|Ä "äLn2¾j®ÊÑd 'ÉdiTH 7eibV›#ÓF›¢"„2„ýºn—ð#G¶ßÜú¼qééî䙢š¸”oMSqÑ Œö`±:»FŠX ª5üÚ…Ž`G3¼Ì8KóäΫ©^· LNr##0)9K¬³Ü„KØ8 8™“¥)-—î©ñé¡AÆ{F¬:ÎÖ.Q”Ú¯!|¡8m4_uerƒ:†ÞÒä«ñ” oÄ»J÷JRÄost „D´HÙ $6Á&òFª’kñBÃ}ìhLy£SgÞÜbvàI\Ùnº~Чµ ™ªMÙ9‰Ž¤ÝH%ôbªvÖg¤IÛ±EeUd.-`;¢T0p#§9¦hcpº·GõùI»€Fýš“æzx×'_CÜP:Μpl°láèÐ _Ì”w™u|M¸H’øâÚê£">»¼ð$æ­Ÿax†š@) ÏY™È/”ëJ5 ·o ëA›¢ä§]ŠGÐfµ£c„h³ÝRP½ê·É\û8Ö1«„˯ƒ~ DƒoD}Íc©öP.¶Ûp~S:°*£¹tÏ%Ü:‘íÛó5óM&„CmB¡ÿÞèÈ '&„ÊŽµûfÂRM³íeN#T@Ý!ÒM8¸`§"…@Eáø2gjFÚ"ižRžI­QEDÊY’ØM²¢¿ÅDÃÖzÅAYY¶+3)xD‚¦`òš^ 3…Aߘf£!¸#€ÌÎJ8ºÅÈIaA0ÍÁ¨öe„PVÕô)^…¢£‚zزRÆX.ðjUq’ C8u=Ø”‹ÂHÅÕI›Ä&*†`Q¶á pGÕ¯)jŒœAPQwúUÕ¥á •^Ø‚/Ž:lR²Ð’²²=;:p‚njTáB‚IV\tåqyiTraòbx ºxÅJ÷Ë•—òÍiV›í³Ò°c8 ™Šª|1›Å”>‹Ä¬ŽØÌn(q¤>Ö®ð$ëTXÐC͆¤42˜Lº ­ ªÊ‘ÕA6ðõgXÒnQ<šKÑ1¿ˆá+dWðøé*“I÷z ¦)œ"€p¼ÉI?"+U8¯k…œSc²sÚ™–ñjf +gÄêš*ÑIÇä·dÍKq»Ð±ÚÝ×Raw ïœ:4+Ü$m9uô¨v cvvì=¥ô¬ã•+Ÿ‰ˆ²¢G‹{GeßUÂAùÒ8˜­$Yµ´X-¥Â}¨õÐÂCãh%v \Ò CÁ‘®Y§ïTàRaý¼ç´¢_¼bN44#Q×$¶3N¹µ}ãäcðƒ>båKÛÞ_ôØ2\ñÎÔRNì!Xiô`ÏTõÂLM¶Ö{n¹“‹ ÝmæZÐ’+‡÷FÇøÄÆA»î+ä¶Fl}RàÄß]ð3qu º·4½ÚB|Ðqç­OÑwT"9oŒ±”»¡váp‹Ö3Ê·n›KVT^‘—}d¿™ïŒÇBqgñ}é¸ïuȨ:³[Ü9®F  ÐUnMnœN6;—¸Ã9„7˜$­ñ®qpµÐ˜ê²"–܆Ô43³Gý±ŠÞ Û›| €ÂEeudíÉé&2ð-ópf¤7"n}ÛqeKËÇ øŽ¯ËfO˜\ƒ; R"ŠÏúüØš‘Æ>¸3s±4ÇÈéÆ·Ê Ù0Õõí’#v€/ÆU Þtà׆äÐŒ™Óɺ¢£¿%($CÜ84‚Y¦¨Cƒ›WE¾Þ€¾A˜D‘<ì ÷³èþ¢›…P'"K­ QpÄs•-µ¢üeˆ ‘6§§¸X+kÚÞycå©J™¤fC$Á[NlDh²äQ”Y̸ȧM‰2ÙŒ«{cMNÿ —‘q¢Dœ¤fYDòá8=Á¨¨Ýƒ÷U2±U‘¸hUl;[0 «!ùû@)'³ÿª1Q& –ªîSüÆÄ0õÙãͲƒ#$¶¬¿Ì}`BÈŒ->ã.<øjÎàj£/`·VƒÓ¯P|0„ "©ƒ«.wÆíuÐîNcá–$Ç¡ÏBÝ£„;Æsî1£Ã¸IªÅQ[—’ ½ ÿ°«•ÛD~~ u/7Žëyg*ÙdÚŽ5#âc š:šÄêTeȱ‰¶!Ç”\4ÚêXÅø†q_Û÷6B´qä æd™‚ïkÅ€sJ_²qèÚsG6O!6Û©°k°=~éÐÝrˆÅíÍÇbjsžsåîMøôù+ONêwè!­ñH³ùwTÆÓ7&1 6/yoæz€Æ-çeö¬C4á¹#À©%ȼ>f[„ÀÊí¤R¾2#l"ÚαiÙYkÜiQs &ƒu2K®kJêÉÆèðЬ‹tSó "±ê›WÎ8XéÄÉe׃5‘‡+;t†d¤p‡p¡Wü&£§`·JÊ«í1TýEbãIõ°5zÇ m‡™. Ífxø¨a.®Æ×”YW'³UF!n&šWÍÊ3c²Ë´?•kU¥©u°!ªÀ5fPWDøZ”tL#¾h,H˜x³¶­,Fmë#}Ê’ ¥ÒWÙ!êнW{{žvQKìT¨0S†“ªT(q+^JÜèáà±7J•ªìÔ pJÓ§E/B à”’‹M0e³rª®ŽG}Í©;­ f:Iå’)(ue)Œ@ 6W±d+œ)Ř]]K°}'EÑÜf(êÐr>Æ¥Æ4-n…÷°xXœÚWÇp“vÝÑø ]™"˜†A?(/¢Ô^ð=ãTVîУ¤ƒÿ«zѵÆ7O0-O£”*f¯G r“æSQTˆíÀíéÐ{gÅž¦j¬.®xðÚ( ¦ÏöfKi_Òå:|ŠßHµ*_”4&%• ¨K¶ ‘²9ê=ü,}šTíàÔ)d—Þ` ó]ÄôÕÁWU5æM¸ FÒ—Ú{šFX­ñ‚}åh ¦¶^S[Û°·›+CEÃ.qöp°|ãšÛ鯥Q½ˆtMªé ú)TØW;ˆ×W¯w<Ú¸6wD°Žkå§4ƶý×üáŽbcô\T'–ñK!D°!¤Ü¯jUý=mŒ \þ%¾HŽfÎßR× •;v,ðïôý5ðí(þ³šÅG[ƒGyÃÐ2pì šögMgS·ÈµƒÊpT@4XJž0Ï:äÁ;‡Ï"=zÅ‘JÂ5U2ć^íl2šNæDIƒToA¥:i߬!N[¤ë9`ïÌ:c嚪 j/“R ³:°1(-Knº«Écñ“\ùò8¸sìàï¥}sl‘ í§Ï‘ÂÃbgÀìGGµ¯ºö0µ¯Žn|1ÎÏ  Kê˜+«Q\ˆð s¼XLj R‡«ú-(Ç< ?œÈAvkõ>OÇ©¿]R6xøsS»å-373‰ô-Gtdãc ŒÜIÖ'¸ü˜m¢Ø¯aéPµPÃóŽ6uÁ^rc¨Ë!`i²™ƒWV çƸË÷ˆW- fµÖu2üì T£ Õè)5ÆS$æ1V¢Â¸ÃH³²ÃÊÉZÆW8lª&àÆQ(ø×e¶\šàäÈ›"û2+UM*Kxjú‹‚õÆœ ÚŠ>Eoy óÓò’’ä&øfÙÖèéú•æ¹zŠyšr¨Ú5’y ÞˆR‡ò F Ó òGg8 þÈdóve¤3²4 ¡²S?Œe'¤tt£d½£`•ö_ÍÜNÐ$Yì,°@Ú*á0ubLU4ŠI£ÖXÓÆ3ݽ§{¶›|êÖ*.¡5â·X ·gÛIG=v]’aq§il4*€×UÔPîê«ÀÇí)Û ½Ê%éMÑ–këœþ*³¦ÄÌQæRç"ùdò",Y©– •”b‡ì¤5¾ÀÛÓ:Þ¬ì€8«¬Tê» IN?äój[׎§Çl…×$â0qQ‡PCRÇd> â„Ö’ec^g-_L¼ˆºþ²NØh*Ðòò(®½Û 7Èi\µ¥PŒ¬á©t\M§Ã0+|‚*F®ÞÔä*~™ý¨~Xv¨TUl^ÃhƒþÅüç%ª[¦újîèȨ‹ ·–ú¢ñc½¬™zÂk‚—Õõ(7¶µ­mIËÝ]I;Áئ#\~l' ¾ ý9Ê.•û’-w*#œOEå2OŠkÖ•Xí•òŠZ„ïRÚ G`òç`¢BØ”]/~vÆÀ¸6Ý1IâÍë8ix)à•­Žƒ¯9†Ã°¹«FðNØÜÂ%LiAÂÔDǪœ‡ì1xíÝÃöܵŸŒ«æËSÞº*LX;àÅ®DÍœ5ÔFa{¡Æ¹è£JþR:¼QœN eøh–ÆDškGö»¹µªžÊ„Ð ÈrGz÷TSªôµÍˆ"IúI­’j§1WÈ×s“ §Lð^8(ÆÃ—*%î˜UL|-ŠGÔ‘í­THu±ÂïEökeÿæõåæifMî0a¾T%ãç4™b©’âlNœ‚¯s•¥´uMEÂÊäð-”±jhM:Çš½š¦§A’òiÞÜLAŽð‘€€ÌÛ #ów²Ž^*¬å­"SúœxdòåÀ†8É8lSq|kÄΊi„.wéT{3Bœª(­=ëÈÂUÈZ6nñ”ÕÙCÒ¤q*O³ iŽvGœÌmÎԣɓ`'Cðõ&ÒØ»(Vˆlu”è(‡"ÀJoO[—@Q(»Lň]œ#Þ@QWÀ&>ÕKQyX+ƒ4É/¹ÔY‡ >ñBiÇVp'mú:‘ÖÍÞ-\q,œ\@ÝÔ†„=5fhaÍ1Û/‹u„ƒM­-j4gÚP£œq­ÉD3@雦¦OPµAâQìòUÐ "œJEo|GI(¶K–ÏV¿L‘¢G ‰"×y§dJ¯4Ï•UÜg$Âc2"ûµ¥yº æµÝf,çÎÙX=Mà½e–ÇÌò‡&T$¿Ù‰h’d­DR Öj j¢8 ëì!­rƒ¹ô¶?§ ¶1ƒü¥‹©-ÑóX­J„ãÒû B¬ªý jL:äŒGªFWrÅE•ºœ«ŒuÉP ®´¨¤£ Â,k± 7b;¦‡œtˆ™]¨Y©")ý‰_ÁX$§S{ËÊÁ-™3֔ݗ`í Œ®\Àôe3ê^Þôȵp(`×–$ƒÉ4Uœî\ U/9éÕ)ÙJ‚&¡G¤êÌ„Œñ]fäîP’l‚§b|WùÊ6}ú8-¡&º&µbÒ¦\AŒûšªX\CŸ<¯¥‘c5²<*(W«WQ™X7FJ+s²‘Ë65Ç”Lžx†Zƒ?@°ËÏlÃEÆTÓE™§‘Ú¡uÈ”y;S¦ÀUH;[FÍ?àŒ9”Ѩ¨ Âox×F¨š8Bm5 R›T¥š=Zm<2pðšñº‰ÏÐÕ +Ekg2€ U¯öÑàe`”{ØRFN"ÂÄâ¦a0Ú™|ä[ë‹)$Ѐ»SxDS*ݳQCžöç`#¬ìiD’´®žj[‚×;£²åq«ÿ(ÆÊäÃ(r™uË„0.Õ 9[óÂ8ÞV{;\V™kPyeÁmkh»O=¤0©¾&YUTÖ³7:D&'èµ{ÑœJXIÔ¨¹VTëH8°ªe-Ú¡jT¯–°/P#ä’œ ;d:æú"Ì5ÒâèˆÅ÷bÓ¸§˜TÒ/#¨¢uqÙÞ|³ 9ë £5gƒ£ Õ¨œ¯êÚ)ŠwKpýi.Þ ÔáݺºÏNõ<É%tÝÎ<„ €ê í1LC(/+íó"-ÁªR7ÀÊÁTd›ÄZŒ¬ÃuGh‡ó k_ü²Zþuùkè`ÐÚ"ÖŽt*^92dM¸00eख़˺v¬Ù{9ÑÚì41ì^ *$Ù„D·6rò ‰Š§Ñ061FÈ{ŽDWwà50)±©#B L™èígbf½mŒbÀSù[œð‰ŽçÚW?Xt)åÊòÌ{4:Še©üשg1='G™Vä®ql,:ç…äÏ ]Lªàlz‹ZåNË—ãô<þfthׇŀm±a˜¸9½hüZ‚ÿÌîßçQLWõ¤Qð mF¤®Ljmœ’é,–*8Q^ÇV|Åʈ‚FàµìýÔU7 ¦JXNΦo[—, Ę%ËÖ8·»”~©â@·Å‚¬r”ÛŒçoŒ:‚ÃÂ*À–Žd^XŠ5šA³Z|ÓÐò«"l0;zn:Èú nÞ´ÉËǹê¡!²ËÂЪJKeuY ¼UZŠäxµ29αk»¤²QRàW7rgòì´ñU2vÀ|…ò´¹¯^Ÿ¾9Û•sU›‡ƒ_ت›jòÄ‘&cùTaán SǤùЏ SG€Ý£*Ÿ&¾©%¤··4%[°£\ˆN+‘A`®€#álAÉÃèUôT c<ººJ{)ð‘—yã]„Ì%å«:”—Ë›G2®C&q‡GéÈß!Í3S„#³€nYÄF-ôˆ–gi˶¡‹С$dÒ¸:ßñä52H×r0!E_Úî!aµ¨¹LÁ§«°k¶‹ïµéꮓ–wuàÙÝÙÖµŽh†e–š¿‹ì×I‘áàöëf;%#šÆ0ŠÄd5hõ¹ÑuklÖÚtëR«);åTWàQìHK½´¹pȤ"ØqH˜ì…¿WE<ʃþÙÊ8öDÈ·—qÄFà©:ØUTÆUåÍÌþºkeóК*óšÏj‰¸¢U†„¦d%Ê$*jäßÈ4rï•ôš“˜ÁÞC¡‚ƒ¾eÞk!wŸ4 FÕÚ%¿¥‹Ù³é̬ƒ´¸Â%=™¿vÏ:\‡Î0šÉxë8ÆmS&²ÔŠƒ!šøºÓüZô¶\s³U–à!16}Ü0­‰£åánÄdNtÎPbæÇsJf\K•B›iN»öz`ƒW=ÞÊei£31ÜΖàôjí\™7:´B˜l¹ÖæKä”Õ ›xßÙ•ê]¶æ<ž©°üpкl¾\¹ža´ w4-•ÊÀÎSÙL°£6ë?5R¨s˜šˆ1ôa:Sm¯Üs73…›Ú»¤ÇÇŠ %çÃ5Xõ>5" k~b“™ÜÓDDí:¤‘§í»NÎ4/.Œ;©˜Ðã„ãÖÁ|ÁoE “\vi>¬P#“¨Ž!P½ÜÀbÀE°ÕŒt P£+øþ{“#6°6ü¤k…B†òÞxç°EÉb·ôòîì7ÔL?”ý˜ß9C±N«ß8k:€ÃÔ‘ñ8@Û­²µ% €ÈÔs«ˆÈŽìwÍå UQ_äåÛótC|ë¦*¿?ý¢Ù¯º¿&QöžŒO{⬣3椪2t«Óý»ÿ³5Zü”û¦±KP3•#‚H|%Ü^í[›áîbúQJîÉ-* ÁP¢nÀÅÁœ¨ƒ¹qÍåZt(”•Å;½†Œ( ðãšaÖs‡9â5=dG­W.Û͉™V· ‡ÐD%J#xÜÖÄ1?Xl«Óû»à¬¸Ñ! ÂÕGlÍ{Rqƒy×9TÖæF›79È‡ÙØ#"š1ki"ÍzÜÁÚþã¨9ç _\Ž7ärµ–†Pª¹ÃOÛšPž¶ 4Ĥ_Õƒ‰Œ Eï(ÈP3¸4ñi· t’ׯììhôài˜è$ 4—¬Õ?¾ÊQsÉ>yX(íN’"¢ba”¢Ø¡Ù+JXõp5Ù iÁÊfE+úË*ÎörÄѸFWEn„jsÑ®g!éáhr€öݪØ.׆ ëì½ûêCgÕû´«g”O¦X&c²ºQWYÀƒ –Ua:å•LʭƱÎVñjS”„y´C·[ƒ…¹1‘iÛr£-Mž¾Þ.[²¼ Y‹œ˜“½UcS ¾ÎŸ…1Ë[[ãý~í«¥·¥¨áÙlÜÅMÀk0#¨µÏ鋽Ž6ÄešAŽãñ )e21ˆ-8äo&&*Óó^‡‰Z:C7ÝŠæ·Ti¾T¥eÜÄ(I^vn·(ä¥ \¹)ËHíÊÕÃè;Aª‘¦©çWuKc¡BõM:¥„52 §äu¥àkáF©.¦DC„Q§]”©B:0Q2J½¼­0Õ¬$øB°1Ið™êA¥ízªMth~å œ1‹se4Qz»Å!ˆ—§Ó¹II@DîˆÃúÆsBzD^yy¸>Ú×èC7WÝ~¡á^ÒB 6ó÷FG2 âˆÂs‡†ý‚Qƒ:wEZ6¸lÔ ¢èœïÞkúÏKDwb¿–À7–Hä m¡Ž u„Ô!DܶѢëWÚæ¿F]Êô[©ãK©pZ £"CŽØ­ÁñPªô ¹;” Ý3Ү̎!è]¡¤Ñ;þ\"Æmâ oyy7Á"y(å=ºÞ³MÕ\ë¯XLJ¢†:7t’ù!eº‡<Mä·AîV³”~SˆYå E ªjý ɦ“è‰uçV«•Ûu1N4.äŸJn†÷´`5™â’.1ºŽÅÈ!ëáiŠqu°²²‡ÜšV§‘åª2Ï0ÚNû½ÑdO^bÁk¥òÍí„A§tnÄãOþàÖ—uÌr2 ÊÐÇÍ8j‰’Yì)•Ð’fþñ-³Cßõ@£g"-ÕÆ>ª X'h£Æ_ó³šÚ_Ç ¥›£Òx—Ú¾ä]‚”<ñ j^Õˆwͬð°3: pg ‘!£(bâóœkè<ûñ©ÑÍUÔÁÚüXÄ`BÉk›VhW94Ø ¨¢g•¡ë‰7áP³Àyƒ¢RUði9Ò“Ù€¦R?oò¡ 5èXJ]ÓHò¡ô8#4ÇIØ„,¦g«¦ãã±i£ËÆ¡E\¥_±»I¶Á§¢ÅØ¡ÈÊ.ßT®*¾wXŒA32Üh,êbpã` å N¯VòE‹®â6’ØŽ’ 'µMÔw’éÖ¡±1.‹ Úˆšg® (ºò™RæÈøªlÇ™‘Œ:„[³G1»G‡²÷Q‹ç‰¹E[Ófqª‘džtª³R¤Æ ººŒº;ú¢¿Æša• _ÛìúqHShÈãH£&Èi&Wd°UEI…H#^VZ85&2øÃ™iR°Ô' š*´ ÒQê’À¨¨­Í4íƒUO+ø&Åc²#Ø,èUm1;#ô6*±66Í ·u¹* ¶¡„ªÈ}°R¶hbçÅ(¹ðL–¸~~GlkúFàR!ò’žTBŽÁ r1Mát¥;vÙDû¨:«Ç… ]rÆŽ ¬+ØGÆùêj×툽3=G‘Ù+4­Í΂âo.ç†$÷N&¸}‘* 4 ;Õ w¹e¯^ûæcž²ª|#]?6¶Ú÷¦ŽfÁøl<âPÌ·©ºÛÅ%=¡”2¢VÅTzƒ1:4 >=º?2õy{»‡1ÂÒNŠ{æýi”nguG`-¼Ù d\†Í!FÉ8Ò‰nÃÁ™]݉˜(-laxtpS:Ûµ|»Õ{ú×Óϸêä½®Ø=yÅ•'Ž^uÝÁ»óŽ}úY'N<õŒ³¼;¸{åÞ#®¼æÄe¯¾üè#ŽÜ»ò²cßwðn«_}ÿê?«ÿá]Wÿ‡ëÏ;zò䱫NÜǯ8qì>W^uþ#®:zݱ«¦ßÛÅiìKî}â²ó¯Û{È•Çõß{è'´åÔs¯xèå'žòèUßwÀÖ‡n’ÜÙ~×4·­«óÔCT%ŸcoßwðôóO^uʼn‡<õðá3vw¯Ùûá+O¥ßN+Î<ã«WÿÃVÇb?xæê¿ÜÊv;øHº*ó–0?ÿ½esm3›5× «JLÙ q—çeßš+j=Õ/Fq4ÀÔÌ»C@Á„ŒÊ·ª&=ùìnçߎyM£n>ƒÝ‡bŸØáËWOðÔž8qtïØezÕÑË®8¶Ú¼û¾é”ÿæŸ?ô‰Ñ¬,}þ×Cø¾S½Q{Þ;ðÕÒ=|øÀ>{Ð…ÿmP×ðn´z«ÿ¢×÷Pþ÷iÁ“ÛþH l|¨#›Ær$Ü1S]s‡Wä5*¤—JÙË}P£PGϨžƒÂ·l”dû]ã ›ò”$­ÎÐýÍ„X©±Wõç!¹G˜'ª“厊JM–³–FT¿tÓ+¤FaÔ¥ÔRÙÞU‡ªHPÛø¦cMZY‰2|Ö­ÉÚÈÐÙ1r2ÞØ[Ô"“ãPE6Ú“ØÔ)›SŒµrÞZ„E‘Æn#´jYÈÖç'¡·Ì6󠻀s(Z¿ÃyÓ‰šÞ‹Îp›ê5„ªÑ(Ÿ™ˆQr"£ÌC(¿™Gàzñ€ØPî®ê–âäÃ{RKðÀÞ°‰RŒ”‘¥9E‡óŸÒ°M9¸!Œb‘ŒÅnUe‡V7‚lÕð­DXb›†(j4gÅ~ cÖÀ+IcOp¡{Ä…$™f)Ò¢›\´;+‚“Cd!sêJ!U¨™Ø+kPQgZ_q†ÂøÂÈ,»ê5H£×€Fº$iä²-ñÓH³{ôI"ú}MßU;ˆTxÊÉ NÓ+%àµdäÛà ¥š*Èÿ"uF >Q0 ÷z&Ùb9`í0älF ˜sVüærÂc•iU€ÿˆdÃA‚"JÝ:ëV5tÐ7GÕ1M#T‘~¢âI_¡XÑ{Õ!ªéƒ(Ò‚Ø?&ÊR vŠÁN{'~[­÷âœáUŒ–Œ9B8œDá£ÈгWštˆTŒl,ñ¶M ÞÔ¦µOÔt7ýTÓÔ ZZ ¯ªÝNÖ×ýÙü5[1®Ÿî¢o½ Á^¬Ý³ÐšÉìLTD¼y} ”Öô!­ü ÖJQ1IM»C(° Mqš 9ý­ Ñéн6úgïà YÝìÏÚåT÷ ºšôÆ:æ¶ïÃÜç×ó¸F!<ßÅH±Ó=t γ!öÕ´[*hpãxLÑßtÖ(Äeš7ŒnKŠBªº®•` €(‹|#éI·)i#té½(Vr#Û‚Nß‚åÄH‹¶¦Ež”Rõ¸V«3ý¢HìQ;ËîŠù?Fí˜å3<ë$®Us€;º%DÅ0b“9Õ¤Ô1ÜÆÂä_·¸ök%VÖq¡ ô”raq„ÚÒƒåN(NxTÞ©Õ®Ž6yÞ B®#g=ûiŠ:|11ëq$^Ò–{.š?œ'Xæ{ƓȒÚ|nE„¤—¿V%öåû(z2n¼=Ú¢íÁ%øsÙ·µUA¢Û²„ ÈµXodùâ&FÇ¥-k¸i&v±â›"•ߥN¶~I]Cì‹ï®àúJÔæÇLb=±¯}ù]I=æ=‚²^µ…Í…åÄK]î?äÖ²XÒ¼SÞ¼¸-ûÚ~¿žÇ Ûîbì®, l/îP•­ªi?íÚ]ùÔÖ÷xº`(myúŽ‘àóÉÁ•½ãœæ½ß§’‡ 14¹ÇùE@ý·œvtAWËòl4ìý|Šîÿ8é×iý×Ëq§»([Nþµ{Žøõ–Ùm< äOƒÄÚ‡a‚ÆјFc­h\Ô_±r©<Þj¤²f<:6¦`0üÒŠbxXk ‹«+ÏÒÂ4ã€4̰٣Р÷miöIjÎ/ìC…‘ Û5c’91X5™žä°ˆ˜ìd¤R”T E×LZŠ’Š®Çd³rÍKS™bž>m1¬É“éÈçÀ 'O¦Ô¸4ØÉ‹‘Ú¶5óže ‘ù3й$Ç/ÝJÊDäV&ƒÜ›žúÒ!!!z×…òkR§·æèÐorkK·ˆFsð¬à@QZG)G–îVçÒžç,€ppe/uxqPFO4Ï ÚDž¿³Uªj&˜ƒˆÆ`jDÏV'8 ?$Å®¹áö æÝ5ßµÏéxºôÚE&wò‰™ 1ùMšV޹ìð·i ÿéä™3M^®›~|Ÿ3&q&ìà g¦â”lP¡&Âí%¡]Ë–~jD6xÖµoºûg”l’"›,Ì>F­X‹‰Ð‡ìáæWì~gé¬~Ñ6£2´m?ìÃ!®Hu0G´‡ $Ó–ØmGšE‘$jÔø°…œz‡ÄÈZ|Š:Á5E³hG1•)îż” ´eS”¬sŽ..cjÔ©CôQô8E꨹!R§Q=ÔºF,‰ÿq£iÄ-”á5¶( ¿–(äÚ/òikÊ`}ì"” s8 ì:_´H:wyß3¿Ð<É<ÊeÇãÈ"Õ6?º,©ÄéÑécÎãp/$‰Ù½|}I¼¦1^v2ÚiY$ƒÄED>HóJFú"Jéä´2)ŸãR_®còš&bû±ê œìràO_Q˜f?/dýöˆ+Ô ú‰>Íñ53â<ΫX?}–‰Å&Î7?“Äê6C0êf2Ì•¨ä*½,{Éf°íRwF® Kóà‘v–µ;.{â¶]êþL~{^ìÏ=ïÂ×¶Ø÷™g?¬”ÛžPr¦h‡SIÖqújÀg;îäcnýádðÙX4уÏ ¦/A?Ôå‘˺ ÓÖV¥ªM@çËø2,Š IuT˜Ì›ÈMÏCx½ ¤èÁ¯:ïUÐj;xˆž2ùöd;ýká*#ðbˆhLÃûLÄ, þ5¬5IxذfÀ°ŽjŸPkG°£¸µ‹ª²ï-Œ(Ö> ~²ÃÔäb­)#§U㌅ÿUM9Ž^º2 ¡†KêÙh&" ‹G4ªAÉÂ]“-gæ'éÁÑm†jÍÆê>ÌZ–gí}B`Šð‚+ØÌeö*úp×T¦]ã|Ìi·þëÕ¸qc\•ãÙ¼ èp,îyËì²àÆ6Ÿ=9¿ùä¶>ch-ë9bC¬u QBdY‰A²Àö! Ó/š|ae”ɇ‘m’`íJ”Ï>LÑGŠ•¼ïc6‡§¦ñ™kDÃ6c½SGªjMÕBÝ.óF'§þYÀ–áÌQú¡„™gyåPhDØG̪˜¢Â\ìP‚j€m“^ ¬Æ‚GÒXSÔlÀ3f!*cžýsˆÆGU†e¿V"IñÏ“*¥1ÓˆUhý3%•ºÔö1®,€`XmÆC ~v*[1ê…j] ^AÁù&“‡*9£¦×£WÜ‚{D¯ø.”ÈNÃWÜÔ§?ßòË}Æ”ð™ÜÁÐT³`w¨{oa9™Y±Hbªöüü‚Ý…é@!8Èë¡Dn¤Bï9”(¯?˜ÚÛ€©nŒ«¤x[îBÜþuâ½·”ÐÐXíÆZÙˆÁNxéHàee±97“ÿ;›‡$Ø(ñ™ï#‚aý®£œË9R@º´µ§ðõƳC°{ñ¤£Iñ.Æ…q±qr_¼oç+‘üu„¸ÿbÕ…i\[ŸH'¬­å`j³Óo÷u¾‡ék B²üöŒ-sþJ à™ñxæoÚƒÕ•î!L Ä€½¢A :èq¢Q”dö=lCœlsP¶”5R~ëÛ›%çÍpJÛæ¤‡´Üd-M9íÈ#9mÝ#÷¹¶ÑDét,Œ”êt€ŒìÚq3ÒµÓá4òºÓ16²Àk‡ ’¶l'$.kÓ#ºòlrõˆ“×ÏÚ•µ›†ÈRè°°Y8Ý3Ì“1Æ 4‰ý =…y„}ça¹ïåõ4K>ÙH#§¾f# üd#\ýd#Ìþš4p“4“4ðkVë@#L6îÀ-LÖð9¬ÙÎ1YÚ<1Ùäj±4à.c²ö‚c¸î±æC pÈä: Éð±ädÍ!•É}P–ÉÑÀ—5·pÀd&'rj&wsÀoÖœÓÖ™\Ù뙜ÞZs‘dhr¨¸hr½iÍQÀ¥É­§áÿ8ÔZ°``§Fda€¬¦Ä€d­…+€k n ¨×À°µ É€‘M!–7³PÌÀ¦­…m&$ÛòL˜·šrËàÑ„§¡¦ y7‚R†Ò[°&DßvMØ¿›‚ Žî Vh7mTâu«CŸݰ¥¶!‘­°C®«qAŽ9îm\x Ïèñë­Èǩڒ'Ú,9Õ¦1ˆû;^­r&sØG{¬ Fb–±ùÁ?]ªãÁ‚ç.Ivss‚»cökãOÂñÓ­+#—‚]@BíÌåXma T³ù=/Ì¢K(+­1Cµ…Y4|½Ýt]ýè©ÇÏ$t9‘#‹éké1J»f.RWnÄüÕ®îO)(ìCÙMÌ0È” ð€A`$‡LÀ;‡¤ÙÍäóÂðZ’k69K8ulHt­åYCÐjÞ„nÂgÓåÑ[®š5±îµyÌ“$ ³¢wÂöȘdsIçc6{4z”"‰XlQkÿrm~a²yƒÒÆ5“mÝ«Š+K{V/¸‹©÷"š=Ö»‰Ì³ŒÂ ­im#_!·Êj±ÍäIöd«¡W*Sÿj#SVMƱx+]ùSa§¾6ǚǟÀ¼‰tPXÓznÓ˜§HÁ× ¹¦ÝݳàÖétpC”‘A Þ ½Bµ@¹•ÞfOfå )@ª$³Š7ƒ0±"t `œàÀs¥ãIã«VJ¨­™gI ž_”˜†Jx†€团CQŒòÚHKš²2 uALŽk‹Š=ŽÉÀÇš?éì•ëðå0ƒ¨Ua¦7S“«ÙŽ®&éÀ­Ó˜çÈî¹m(‚4„Ћz35Ãùd2pnSø׸®÷—fSµNP™š ¨4„kªpÕ„Ð[0ŒUë§k! 2¨¢* È ]×g1ͼ‘ôAÚF¥5³ò(ª®Í ]0_†ì›ðÆ„e @kB“0€«ŠÕ¬adóŒ‘qìsê‹ ²¯dy1‹y†KôëP¦àpµMõ˨º¨õH¥ôèÅ2#pÃC¤€Zraeü$JÔSÂûkbüDÁ@fÞèÛ6¦1Oîõ)VÝå¶K m6o°Êwµ˜Íô‰iƒMlã!Qáiªk´ª² endstream endobj 79 0 obj <>stream xøëÓ˜§¸„®Éžu Œ¶-)ª%ÄÛ_“šÚÍ¥Ú4³XØ+-ëmT†Ÿ`°]üÍå¢ìJE½X¾ó˜&ÉI›fßúà“‘´OÅÎFæ(­í!LÎÖvœ §*‹bu‚ÛØŽpdЖ˜Ã:2OÍö fÜæËYÌS¤šõ¢{;‹ýîY(Wp@0R«wlâ­j£jJõ¶8ý)åY½½ôhC`w-qŠãÔXÞ@tôõ}âwÞ˜Æ9â<î°6èI[„ú5%ñΗ+sW¼ZÇIïµÝ„o²Øº[§±œ£Òs5­7s,ÚóÓÝðª4ûx¢Þ"%áú¼¸5²NÞ¢!å'(2©Ž.vŸMà²æÚù&lûªM娦{mË9ÆÜ5ÈäácŽÁ'½s×0E—šê „ȑהæZ¹F—ã–b ÎÐÝNhyç!¾2:óM(É*';“=çå4–&Ø.½@q†I±:ûU…¢Â°#+!j¢8Ô óœ óÜÓ4IÖ¹”´²òø®a©Í¦€:ãòºäpÇ{ÖF&B¬†ÿ^Nd«yˆäù0{+†ÀÖB¸&æ‹&ÏC±Y ¸/ßCEV”‡0 ³ /:¥ð£Ùv«¢Àç2^’=š‚Ý¢÷6„× ø~c"[]`%†/qÆJ´G$% ƒæIÙÎw jž¤Ždˆœ0ü*¥Ï&ÀFèÿ!R¹9€A&\3u ÌÇæ<–žwl]á@9M~·ž 4R"2vö»Â’­cc,+Ú‰S#4…ržÐN(ï#Â}!Pä8£ZãxFQ¨–ìÎõúH ¬ObžÊIÏÕ†ÒG{ ÜêWí÷ Rr.älk&ïa|¬W™IypR2@ Ž÷E¼nÇÇ.‘´iàn™#Ò ˆXŸ¥`Ü*†2ŒÛ4ÜþÐ9ÄÔùðT¡cç™gpɵ„Û® Ž §Â`ôP]Ý¡º |·ß-^u2Âî*Îk ÁíâC\.>ºA ÿóR'$P"vBÐÜYc¨šz*R*+mNæûÒºt}˺‚7ç±™¦¶$ °b#‰âJ2d™¦ƒVœ–‘wÈP¯k¬'õw°B4BÌIöƒ#ú)Æöµ-À+!¨mX!Á ˆkY‚ì›kÀ-rj/tàþ†FÆz½&hÞF€Þ`^űD-_æ9 Û1r0‚,&7FX›Æ6ÂW`BÍ .ÄxÃŽçnD\²;=F0Ä¡Ô'°aî¡)ò*ØïóºÛ°É^–©R†´2®Íbs2Hü¡1Ñ­Æ,{3cû¸OA†% ›áëU‡ðÒbÅ…³Ç°&¸j³ mu‚QÌî"Öb®Dkó˜×íÀ–©g;&éõºiq3ŠYK„|F›¨»síïp¸Å®›žu 6 Ùjóµ£Yä¥*ú Ÿ{sÓ$'ðß=™‘‚‹˜1…µX;à4ç£Ò¸"Rq”ޏ _jÔW’M¼æL/iPк3™q óô0õÿµzÏ»êʽc'/?vÍÕ †^pôú›HÈKj¥Z†Wo‡4DúZoPôJVÔÐýj%f‘ÎIRópíÑ fÐ{#ÆÕV²¨³!œ¥Q$Ì=)Úà°`æ[õ kÎ1'Qn·Fæ¹Î"Ðê'Ná%6|¤™™–8Æ¥‚îµ%©Y¯"¤#÷à 7sÃH]…3Ø¢i\ÇYêJPås9ÂIÏSÀÏ«§&ä7,†Ú$ÖABÆÊuM@Ïæ®ÊÎö ðkeô!iId¬¶Ûè–w`ÔA2@¡$2%ÁIü9TDgYÿ}Õ' À Ü—¤(VrUº{õÛ"AÀ­ðó¢ä;W^Ro®ëÝÊÆ\¼ÃÞÄ );Ê ãºÜ‚–ÒÑËÍAÅg‘B“–*R0¦¢jƒ_n¶iU‚¾Uñc¤¨%PR¾Êo†8ƪü}Sc’•{XõDWÆHÑÆnJ뚎§RbGX>-:…´‚’BŽ V¢±`E”åû®ŠŠ–ìON• ¡Oä+ãZ–Þ«oâ „²ybÏ‹[*!‹Ñ%¯Å9«…(Œ›–7°úækôS•i‘’ràù)-[t¦CÈßÃUmÒ«‡z-nVï!š"eUƒU|”Èî!%cJ<d€]Twù­—$Ð!Áî$A8ÕÓ&ê;b.û4èïSh"d!E 0X°‘ÅI‡#lBÝ\‘Q#ÓðgÊ^+QÓ`S#ïor}k›«8(sG%!_XeŸU'E®¯Ä®MªªL£&Të±gHB¥ÌÙ®ryCQ S´h¼vôø9GO^uÅ£ØH=rÆYgêðãW^µ']jž®lØË®|ȱKÎ8«_²ºóO^wüØ%㲓KÆç…—­=ÄðeW?vwü ÛØ?|ôê•¥¾jZ]j5—3Åè¿×±k¯Ø=¶zB׼܋I÷‚pPöÙÏæ£.¼®õçž|Ö 7<û‘¼óWþZi÷‰/ü…—<몳o÷¿ÔíwN>ç^qÃSŽÕ¯ø¥N9íAá+^öüGßK£?ìé/yù‹Ÿò°#_ùGx»s®yîK_úÜkÏýî¯ø¥N9õÂÇ<ÿç_øÄÝå+©ÕëzÜϼè¹×Þûf¸Ô)§?ø±Ï{Á3N|ÿWô"j8ºø'¯Þ“¯øÊ.ø¯þjþ¯;?ðš§>ë§/K_Ñk}í×òÝö̇?î)9¿¢×úµeÒƒù¸G]ò%®õÿ•zà_Ïÿ}êyäÕÎ_Ék}ãínÿ­ü?nsÏí¸äŒ[ïû˯þ²Mâ[ßñ{ÕH;õìK/¿ô¾ß³ï/¿æËµˆ¿õNþn:•[¶ó/yð9‡öýéWý—y±;¤»ûÛêÿ¾ý=pñù÷øïûþöë¾ñ˺حÃg$ÛØï|æ“ö5پ替óûÖþÈY÷ ¶nÕÎûÑ‹ÎÜ÷ý†oùºÿú¥Â½Ï9猻}›5ÜéÌ‹/½èÈöûý×~Û·ÿWgv›xæyçÿPŸ†¾õ÷_pÙC/>|p¿¿ø–[ßê›ÿk—J÷=ÿ‚óŽúö©í.ç{Ä•—Þw¿óòëou‡;Üú[þ+—:ëž¿X ·9ük{ÝÃιÓ>ôÍw¸ëÝîôŸvšV—zàE¼o\Û'ÜÅzÚ³ž|õ÷[ ·=ýîßÚ­þ+—:+Ýf­ý;ϽæÙ/ùùçÿÔŧoÿ»o;ýðÙ÷Îÿ)óçVñ¾Øv©SNùÁG<ïW^ÿÚ—=íŠ{niw¾Ïݯÿ'.v wŸ}.uJ¸üù¯{×»ßñÚ\{Á]·ýéϺäòËзüå>ÿ|ÏáûÓ¥n»¥ë».}Þ›ÞûñoyÙOÿȶòÝg;yÍ÷¿Éëmï~¿‹.8;o¿·û]ÿýÙ?|ì#þÎ_|Ìý·x}·¹÷Ãó„G»×MœØ-ÓÎEžS¶ÍjõÏÙÏ|Ûÿí³ŸþØ_¼ý†Gô-ý?xüI×?õšÜD‡ðÔûþèƒøûíçg=ëó™oüì?¾ï5O~Àwlö¹êY?÷¼Ç]rÓŒ ÛÞó¢ÝKwöÝaϾþ]ùü7Þø‰¼åyG7_Ëw>ð§^ð 7<õagÜâ¦\ë´\±wé½öy‚§œòCÏùÿð…Õµ>õ׿õ‚ÝÍ“Óí>õ¥¯ü…gî¾)׺ý}/ä5GÛ¾ýç<ÿwÿé‹|­·?÷âƒÝýÄséU/æû0ýüè'=öK8tçýÜ{>¾ºÔÿþ7=å¾›Ý÷¾î†WýÚËž¶{S ÉÛï\ýŒç?ýÄÝ÷ýÁE/{ÿ¿ÑµþùþÏë6õ½zê+^óêŸÂÅ7å;ôà'¾øå?÷¨Ãûõßåäk>ð©Õ¥>÷÷ï~Ñî÷ntßã'~öU¯{Õ ¹³e…nü“þÜ_}ý+Ÿzî~ý‡Ÿò¶¿ý=¿|ã6¤Sôä—¿öu¿øÌË÷}³Åz÷“/yÓ;~ó¥W†}~ûÀ~ÿc«¥ñù¾ç®Øø.ÞïºþÚ^ý¢Ÿ:ÿà>þU_=ýË=ýÊw½÷÷ßøÜK·G1]ýê?ÿ÷Õ´>ùÁ7?õ¬Þïß{ö/¿á ¯¼þaû®BõDäŸ3ûê÷|àïyÍ7G¢vžõNz„_üøüâñ}þ®—>å¯ãkVÓÚ7<öõ³¥uø ¯ÿ£|ôC¿÷KWo[µw;ñÊ÷ÿËjZŸýðÛŸ¾q3§^øø—¾þÍ¿ñÊ/ñq}íÙÐ:òÄßøóò_?øÛ7Fûîçþæ7öÖ§¼ûœ×ÿîûß÷?^ýÔá¯ZwÉnñ]ß5Mì{ŽÞðî 3ãÓùŸ¿ôËWvÖÓßò!Ú3nüÜß½ù±ËyÝáO|Õ»ÿìüŽ—¼ÇhÝpÿnyÇ;ÍÝ}žòæ¿â?ù¡w¾àèü•Ýåø+ÞûO4­¿ð¿óœå¾[®|É;þìo?üÇo~Þôa~õ†t«Sï6ŸÁ«eý>zÿ7~ñ_þüן4/ìûâ.n¼ñ_ßÿŠ-§üÄ׿ÿ#ûÈû_÷¸#£qñáò?·¾[¸ó·Nÿ~Þsßñ·Ÿá'õïùÅÃæ¼Óå/ýý~^®õé¿~Ëãgcã{òsïúпþû?¬¾ðiƒÿº é–w«aþ ¾ÿ'_û§|jÜø©¾íú‹m/ÿÁǾá/>!—Zíïÿ¥Ÿ˜ö×ÕŠúÃ~æ³}Ï‹/šFúÆ éÀ]àžq2±¾÷Ø‹ßý‘ÏòkùØû~õ:‹@Ýï¹ïú»ÏêµnüÌßýÎÏ+ç{ßÿÛ¿ø±÷Üð€iZß>?.}÷8ûÌ<Ù÷~üëÿô_dbýö眧­w~ø/òw¬ÿ|òƒïºá„íE÷zò›?¸úðþå_rÁç›n÷߬_ë»Ï8ÿ‚6Lð;]ú‚wý ¿±/|ü}¿|â.öÿòßíR7~ñßþê]/»öl]t÷yúÛþf5çOüé+/ã~ÃwÜé»çm‚þùÎ3~äè%÷ocᇫå}ÿ‚¼±·À¨8çY¿õáÏŽkÝø…O|è÷~åI–µsæ3ßñwŸ£%ó¦yÉÜÞå»®ùG·¼û…—ß=gZ@;+Û–W÷>úž—^Îfûw?D¿ñ1³OþÝ{_wý._ì¾ÏzçGV×úÂ?½çe»áwÔ#g„5cû´<üäUGï;CÇ_ñž¤“þÆOüÅëËA8ñ²÷|ô 7.þùôßÿÑŸw™ÓkÑ|ê¯ÞúôsÆûsÏÿ¡ºôîxîî{ÌÉ£÷ëãÌ'­v{î³ûÎç°íQñòkÝø™þñ›žóÕqpÖõï¤g¸zÁôk×›×=xéƒïß®émŽ{ô“~úä…ÃÆ¸óC~î·ùƒþâÇßû²‡Ò'æ®xÉ»ÿþsk׺ñ³ýã_æÝñ”³Ÿõ[lñÜø™¿ÿ½—íÁ–ÿoýÂ+N»ÿi‹‰¥?ú©Ï|•S<<]óª÷ÿ3­ðOü髯¥ö?öÜ·}èSë׺ñ3ÿðÞW=æ>+GémþŒ~&ï|áØ—O¿àÄ£®}èY‹£ó.<ù´ç^ÿøËï5ží=óíüןúÀo<öžÔpø1¿öþ­?ÄUÿ‡Þõ¢«Î;úLl•_¤Sö2ÝÙî|Þ‰Çþô£Žž÷ÛÛyü‰ÏûÙg]÷£Îšîú¿úÇÿJïÿƒo~"o§wÚ}Áo}ðß7®µÚ[^óÔKÎû©WÿÉ¿jÃ?ÿÙo^ÿà;é¸üÓŸ|Í4,½{Ìs^ø³O9~ÖH²žóœß¦eü™¿~Ë“Åæ¼ç£~ù÷?òé‹}â/ßôôsO¹ðç~_Äçþé^ûÓzÊ–ÝÇ]ÿì'îÝw^‹·ÿ¡ŸxÆ _ôœŸ¼x˜§_óÚ¿ü$]ë­O‘k}ÏEO{ýû?úÙõk}êCoyÆY§~âoâ¼¹ñ3ùŸ/ß“§xèâÇ<çgŸý“-¬ûtéãŸÿ¢<ùŠÉ¸àÅÿ÷Çy^z­SN»ôú7þÉÇÖ/öé¿ígžr×ã+ó»å'ÿŸ·^ÿcl ÜþÜkŸý¢<å¡ 'ã;Ϲú/¼áúkÎñÞÏxÇêû\½¯'ÝK[N»ìùoþÓ­-üÏ|ø­O»Ï)§œûì·Ëºúçóÿô‡¿úh^P§üà‰g½ø%ϹæÜE<^úøŸyÑó÷cã!zä?ô™ÿ_öÞ;Ê«*Mþýugîw?ׄ^=s;Ø]=ÝÚtO'u™ P‡ ˆ²¨$CQÂEP1‘d©¨€€¥ bãRAÁ,.IJ € ˆ„¥ ¡¾ý¼aŸó …hßžoÍé™îbÿÎÙgŸß½ßç}žïÖ?}ÍšäÕM{‹_¶÷Óç®7»š“®xD{¦]LÓPØoâœ{g\]¼E:þ¼ú›fN¿±_nê¬}týw‡ö|¸ht–æô½cñ‡;ЦÅïÖ?1ÖTÑ¿]rÇ«›µ¶¾ußÑ­.½~ÖÜY7\Vl …µ×Þ>cêˆó²SßÇ>ùîàÎ5Ì8~ßÛôMþe{>X07#ûЉoÖ<2šÌÄßt;ýÞÙêŠ ²ßvj˜:ó¶«/±•èŽ{þ‹ï~³òîü²næª/®Û•­™;WÝÕƒ~é<ýMÛ;vøø8n°3êo½kÖ„º’#ˆ¨ïÄ;gM`­ˆÎw¼¹íà¡ïÎ:¿è¶ ÿŒe¾ÍÞµã¥l‹7êïù艫¸•O|Ó¬××–lç~×ëú9÷M·»W·aáG{ÕÌËÝx÷›_fµøõÛwÈ&´ïãŸ}o¿kÑX¶I““¦ßvÍ¥Nq…sÆÏ}tþd5NzÌ|3Á7ïÞYºKˆ‡?´vwþ»ä†þÙ»v®Y0’+(îãmSÇ\Pºs<熇—vü³tfþ~ã‹“yö=þ¼&_USzÖ~Òóëv|÷íŽÍë?X»nã™pl~é†SKm¹~õƒ'¯j‹}öšZ±ß}òÔ8þ”V]9yò••t ³¹z÷+ ü{¿ývo6íZûHC~ÿû—vOznCnm9ðõÚgï{ûS«·Ù‡v¯}` ›Si¿ënž<ª{ÉN󜉋7”¯ñØô½=$÷ß?ŸzÖy=GNžksþŽ;?]ùúŠ ;²ò}³b6ïã;7ÜtÛ䊻>«Â߈åèG&Ô^Ð¥ë…C¯žtÛÝ —­úb÷¡¢;íÛõõ®½¹´¯ßš.ã»ÆL|“RüY¦µ*˜.tíýjí²GæÎ™3÷‘g–¾±jݦoöU¾/»¶/¿Ç÷Ão¹kÖÄ~aég­ØVñ³P»6¯[³jÕê6lújçwe†[ùe¾‹Æ÷.º~μ»n¬)vœ3¡rkÉuà»Ý;wîþvßþCMß“»L{ÑôsÆÈ™ ½çÚî¿É¿êÏæ¾Óägýeö+—"×Ú›~öÉ{¯,>kwóŸ|{ä<š{íýüÙñfœœ{ÝCK_]ìàöó†eû¯kï|uãOöaßnX|ËE™A_}Õc«·ÿˆ XѵË[óFŸkÏSN¸dÚ’õ?UW<¸í½E/ÎN¥Ü!÷¾¾ñ0ÆÍ±\ßo]¹hJm’þ¶¹êáw¿üI^vp׆׿¿ÐÍÞõ‡^“_ùS¼ìÀ®Ïß^tˀ꼙ݪ÷”ÇßÝ´çGîù‡ön_ÿæc· *µ¬™òèòÏvý¨½ñûo6®^:BŸSKŠ­z]sÿËoÿñÆÙ÷»6­}uáWôlU(»Nh?bÖó«7íþQ>íྛ?xýñÙW_vf剠ïͽññÖ=Çú¶Cû÷lÿüýמ˜uuß6Mz[_|ÍÝϾýɶoåmÌFxÝŠeÝyMŸv‡Ã9ŸÐ®ßõsŸ{gÝ–{ÈëØ·Çì¸W¾üÔýSÇÔV QÝâìç>óæÚ϶îܳ÷ûý6o:øýÞ=;·oùü㕯>5oÚøçÚ-ý{û˯ýØ’7Þûè“Ï7nÞòÕ×ßìùîûýªøÖC‡îß÷­yË>zï­W—<~ÿ­W è|z³#Z´ë3fÒŒy ŸYüâK¯¾ñŽÙQâÛ¶m/¿¶mÛºeÓg¯~ëÕŸ]4Ö­Æ^Þé´£ +9á䳺^>êš&N¹ù¶;ç-zîÅ—_}íõ7Þx³ôzã×_{yésß?ã–I×нC›“›SuåïKÎhsÖÙçœ×}ÐØ&O½åÖi·U¸¦ÝzËÔI×îß­ÃYÕ'ý!-Nªn×¾ý9çVºÎ9§ýÙmÏŒÿ $³âIÛîƒhR„Íž­ñ±&ÍFǶ«‚koÏhŸVµùþÏè*åÑâ z×’ÝX’œáõ|“£9´ÜP7¼^ƒwmrõÀþC‡öÜ·$¹Mÿ5— Ô»O¦\Zòj'Fhñá™qˆ;§6®H¬ÓR˜ìˆÄGÈv˜{ÂâY¼ì96*=lGÄ/‚¨yP©( ‚Ï!ôQÄ\L ´²æ©Pˆ0¢@U Àggl~ 0«É»lè­DÚ ¤=±#*ŽÄéËÏû­’ B±8`ÒŒLÊK¤ Âà$ªlù,«5þŠ¥UŠ˜Ÿ‚>ËÉH~ŠITÝ,`–>¢AP>¢þ#JP.$žñ{–&låã.VìÅÂG&üY@‘Ä©%Py‹8“±Š•+Í@CÙÞ$r8_IXÜ.rÀ3—²_ ïƒ>‘5HP,aZQÒ®’ Bˆ?DIñ'„¾ÌQÈÔçÙbÌ ²âç=KV}âòÉšö»¢€M ¾¤TµR‡¤ Ô:Ž[\€lêÍeŸ£r÷ÚÕ'ÿ."N¤½Lïô·h>L(V¤B%%òHdî6ŒÏJþ&LHa"$< °õ0Í1Üç&Ô»C‡)÷ùñXIÖ‚@Åa@ç° CÙòJ„8Ìï¬tdb—ønFÙXfý(:-¨{$Â]ã‚ÉóR æc]ÇE{ƒÎö̾ÇAéšÆ&Éu@Ôíci3·qÒçb‚ ŽÉ3ý˜ÙÉŽU§ÙåûožcäÙÑò¡¯:£y¤]\:U©›qëánüÈOð7ƒM'0³Ðß™Îÿú»£}¢ðz¤ë¨íŽ?jÊ ¿úh7Ög\Øî(Ÿ8wø€£ ïzý=|WþºðÖ9c+En5}õšþàÍ]|[îê:í¡éù¶ÜuÒ¸{§÷>ª' ßr[Ÿ£{âÔ±S¯8Êú½ôÆqB™wu»ª¡M¡ð?â‰Î#êüÂÏä˜GœŸ×¿S¡ð»#ðBüsƒÜ꒾Յ‰GèÁ¿ÎÊŸYw±S(ü¥©à!¹ŽÏªÏí ']tÖaGÖ¯r…öëúÁ7zJ&C¯ÌõÛ0Wèó‡üíÔÚKµœ”!yÛ^qùæ[÷һɸ³Vm3àÔÙãïœÀ³öÃFtlâ°Ûùö#ÛNZ¸h"ƒŽÜÞ£.¯±æöœ…|xvÕÒ+å*ôñuÎè«í»`á†moë…Ãë+–낉“u&h7óÃï¼?ξ½vtßÒØ\5·ß~‰üÙç¹o?¼ÚþtòÀ!殪!wÍÑ!7äµ}_“ýØ}X—ò' ýî?Tþ¼üå½ëÆg¿u=¤Âhì;ÿÉ©kíøØ×ë¯Í~ë1Ạ¡sµó—̽Tþž¸¾±ñÓ³ßjnŸVa"ºhî‹ GÈßõïhüò¶ì·áóï%(^ñ>ã¦Å‹gžÃwz|gã·OYÌã9³—.ˆ?~Ya0àÑמ"ßôyã¡·†ë/#—~ð"ýãßªŠžhç+¯Í<õ«MõN‘:=òéö·®À_'dÞšF-Yñ¤¼¤û‹û¿yBêg슽ûWÆ_Ì·†`ù> ß_>[‚zæïnÜÿö0ú³óÂí«è-²÷O˜CκoíúçúÓ¿{¼¼ßëj~Å{÷¿A‘TÉy9h)¾ñ½/¥ÇNø¸±±qÓ-ø³ãÂmßë+üºñÜõTgS9ó6’{çÁ&qÒ'û^£Êm×ët} Eá7lh<ônƒy×*Fµ½w%Óôü­ КAŸãuf‚HÞ±¹±ñóÙ…þ/ €ú£‰…ÂÐå­ ¯;ô0»¼ËúãáîÏrñÙ+q½ñžS W}ÐØ¸}!À4éÈëéÔuþÿöCº/B}1û”Â-Ÿ›ïž„».š4Eûv<üÀ©/z¾Ô½ýþøBÇE;÷/GŸ>yÜœ[zÉ]nœRcê}Þç%ì}eHáòWö6îX„¹®ÇmóíúÞçöi cÞ.uYnyè¼Â°7ö5~:wõ¿ûëBzÊø¹wô*œûÐÖ’ö¿mz_ßvî]=ÖÜuê Ý;@^ÑmÚ·u+ zu_ÉwozÐL í|ñÕ+hÈîw<›K£vÌ+ïЀï=cf?mð §ÞbêùjjŒO͸[HÎïÝÏrÛ¯¬^lMŸ·ôÐ'ºOœÜKŸødB¡ûKÔ©>¸Ž½rùæU˜¹†ß3Ñ‚ô;ŒŸpazƒéUS c©xû—]È¿Ž_»oç‹ ½qã§Í{bíUúÄeÛÄWËÚÜÍÇÈÍh¼¯OLiæg4®–/ïòT3;‡Þ½BFÙ{Í|Åw/Ñ]8k~3kªñ˸—Ô<ýuóØ¿R,®‹–N†M\[‘PÍ3o¿Y@Øo_·½ê‚{×6ž³oõôÌXì~ÏÊoŽôÀ÷kﲺÉUOþ¶oí]Š®Kî_ùõa€ûÞ¿»W¡ä:ïªGß)ãëÐÎU³/,}À\®zäÍ6–y¾ßñéêÅÓÊ7èê8ôê›måšµk?àkíÚ5+_]xÓØ¾‡Ûäu4jÜUWëuÕØQƒJã]þ×»¶‹\ÛÝJÕb*:¾Åà‡¢g‚câAâ@p“X„&“X} nêˆ0c¤îè—º¢§Búkê€H!‡ò‰¸â ªÊbà‰E;VW`d%¾Ô7“ª÷Y|·PÈpYSÍmå³?ÜÂKﲫZ29_x0Dó ¡ü²8§.*[~”f$‹r|Ÿâ!„’…ÀÑ¯ÚÆPËðÄKšîÕš(—D,ÅÞ!'%›(`o"Ÿ¿§!ÕvI''´N«Ð¾ÌúœT°´"<¼lùEŒŠ1 ÷ ¨…±ÚôX -U-Ïûi‘4¬Þš„*@íŠ^ê@CÚ1¹0V¡¢ZTè'HqܪÂI©›t 4ƒ8ŽD˜Iz©êñSÍ h¤…€k=ÀÏãkÔ•IPÇ“ LÄï ùŒÄªÚ«ãܤŠÃ<`qÞÄcQI®”PÀS™¾~¯0Ë@&BøÀEXÞE:…©HI0Ì@´¹ ììª.I8ÒІ” ¿±Oh'Ss‰ëôIKV‹òKìù"W¥žr©!g`)0i¢÷bû~QŸO¡ýê (Ãcdôl´–³£ ¬V%‡*'/ÈœP@<䤗 HOîiÀ_U-`Ò]¥l“ÀUhPÌ™"QÕ{ ˜Ãè ­ÂLZ6-ES4Q³( ´ЬJ¥UUr-²Ë [Õ‹6ÝÖµ sm•J¬w=qìrA^[m/‰D.ÚLG3ð=ÒÖÄ7:©öÍ5´`X%œ@Ö@óÙR®.Ø0ÜÒTÛËsc]odeRýc²yr_€9€† œL2Û´ÝëÛ™ JÃ< CíÇQs=†ç«ÈáÞ)^q¨Xæ "ΕÀŽY7&½:XMAà¶Ë§‚Ë12”1õ(¹ØÐ@ˆ\‹ÖB7€ fTGõeSFƒ„0\·4ƒ0¶ú€ÔÏItÃÈŽO¶:ˆWËi "¦´UYˆG¡bˆ…AÎ’0U$šN&9ŽbÆ“&:m…± R"’%ìé‚Z)KF d¥Õ(eÁpªZô¤¼O€î™ RÁ\©îȵ€R¡o»¢••*¬Š,o•ÝCi~ƒ½Šô"h€±‰ lªŒ.@W#Ov* }‡û1æ ™K ƒbNêbHxË@$ÂiÈi%’9Ï%>ëöš~"zcÆpÐ^-IWKŒT¬®/󹩟Č]i˜±¼%H¬ö$Fµ¨C‡\Õ¢×J –dòRƒ6vÌ“4”qͰò­=e’uñ€1ƒO‘È †ÕËj€Qm²­n 33-²¦Gè³9­R …ʘãŠéHf*}@êV'Év`èщÊ/ëlZÑ9 ½RûPoç&dTW­¯Äª¢Šòb€‰þEqxÆvSXÐaäÚŽ%k—´ [©¨_Ø*˜&`3“•#ÃÀ ”ÐuE§{‚È-?Œ8Zü5ƒ€K`jˆ Mî^D"è!¶Ë<—!1 Ùß@6ì M^0¬˜sõX‚5€ª[4¿<ÁùMùžÈ%« „.0wÂÐ긅Y/FÇà]‘IL\Ý„‘ZZø1`Qá2mX¥lÓ1R‡´»MZ ¡ÍjiÂÈ¥ñ:vù#ôa&S‰÷ë y-€(:˜cí°!½+0¿F®ö‚„t2IÞÎËÊ/‹oà[ûÃT€džµTàÄísÙ|Ñ6”3‹ÀÑm™éD2?û™F" ¶)}SP×ÏéA²µçÇÜ0-):ÀÉ*ÒkŒ–n“˜ /Hkä µ"Ï<5ø‘ÝVÅ}@J|äu1aüuè<#‰ )_€-˜XÕ‘F h¢î‹¤µs÷bô{´×ð­‚«Çë½Èª ãDº IVã#Í*Àç)¯%$…4_˜;É0V@0Ý89V0«£0e? „ YùÀerŧ"áŠdÁ#QŒ_Ï%.ë͸¦J £~¤ ¸Hô³ILD×׉µ š¶¦S Î QH·é"ë qb1¿¨º¼ØXñ¹­9’åpzŒ k9ûj@>ˇrbDÐgRÖ1DÉ!5¬²#gÞ˜±.†HLS[ìÖÊÓnâÈØLùˆ²Ñ®Ëì¦ÀcJt\6SÈxâ ›X‹ÆñäÞP¦‘POIäZ2HØJà ô0ÎØ®øMbƹWë0fLxb¥}irà-'Ãx{J}X6ó¦"RQ€E¾zDàèö4% q2pHɧ礲ÎsfþˆÉºdæz9åÄËÔÒµ#4éÅj|ÙÕð÷n ñHÚÚNlõëÍË©YêºT‰f”%~d'ÓÀeÝæ$‹­ué‡U¬5ªýŒã&5‰ÐбÀ§v‡ž‚nD¤Yµ]RÖÕ¶E(KÝÓëùä3àñ¢Ï“=¤G·öõ|ô£Ø•oEŒ”#'::7à¼ÎÑ!GÏ8¾ÂKŒñJÀ3ãË1¯ìíÈ[D­ß íê㊓Íh”ˆ2„´ð‰ŽyÞq¬H|Ì3&¼u5#7ÏÄ8#ÓÕÌŒgÞàC®ÜOCIÔÓ/Ó–òùèäƒ.=Ž=Uà]Ž8ÇPNhrÍïêZJBÛ,Û23c\±-€DYß5~RƒUTÊ;ÉÖr/·{ÐåÕ׳Lø^ì:ä ä/–¡mãZ¬ckJžL fÚPtŠÁ‰©¢ÌóŽ#ŽµÔº "V›çDǰÐÒ ÆŒaã ’gq$úÜþ8Y cÒ}çÃLÊÃb¦±Ý‚šKÎ ÓH€“ yAÖgõ÷ɪ ?/Å”+…˜ÒjØZkØZ,f¶– ±UKŽH邉&êAa™Ç³¶q-žó'„®8±éò8­¢ðÓÕ%À¬Ì.¬w!Mæ(2ßíª ‹oÚÏtkr¸ˆI  fª]vóðäøžXÖ‚Q&úHåú¿ÈÒŒªý/É’hl bµ86Å,ÕfôUŒd©p7~ä'ø¿›Éš½äß@$˹ÊðÈõÃ$²Š¯ü1ÄgÑ|u¤&¯ŸW»–ð¯þxìù]TQêèò8³í±‹ŽºÚ»ÄgtÞ)Gß×JHÏ?¥ð÷|?Š˜­|`Êß›Oíq÷Ø< E²|‡A›ÚÎ…àê¿nRѤìú§¼`Ò¯M'ë8jÜÅmÀR÷ÛÖMk_ÿò›œ Ü¯Z›—wŸzÏT"ú¥W.þSéúõ 'ä?¼´Ò.½ûé®pTð—#Äàpmžp’—/ñ g4Þï‘×-þõw…°œþéòÂv?‡°B«óÚø´î€lXòþ # …?žÛù‚ÒX•㟗7¡h ¿\Ø¿sþ–Ö5ƒ4ž°rËÊ …B‹š†a%*E¿KÃ"Ý?üδeÃuyEÂYc'*ú.Þ~ð«û §^unq&Qû(ÿÏ_y' 'Ìšœ§£ìzë¢Go¾ HËí/Ý6iÞý7žS”ljºE¹ý16™ô˜öМaN¡ uÕ}ÎòO>ÝÄ$‰»?[óæÂ±E/.œtÉEEâ= ÌÇõšñèÜQ§~Ù‚ª:N_‘ƒ0ïxoî%öþŸAi´Mß^ù‰æWzÀ%3ÜÑ×)´H©;üÁ+ [’ƒ™nYrÍérûï[ýÓe·aE\œ¿wQË—Íœ3ÖŒ5ç ôñ–]/jwñ½ë-Hw÷›7+ô3ìÒÌd§Ž™T“Ïäô¢hì¬›Ç ÎÄDÖqäÈŽ…‹žøJòØ»òvAp·î6j ýÙîÃ7手[žlÆH§Éw7ëÄ6§V™GN›Ô½P'AëïVVÊ o}èÓà…žóß~ûþ<ÔmçD¼Þ|Ldz°rþ-ße ÛùqF¬î~þ’Â?ÑÈòÜõ…6ýj©ú.½oÙ"ßoÝȵ:ÓôOšNz-X¿çëU,^³ýPãÞ7òuÒ©ûÉ…ÞZÿêÌ{¦ È¬~O¬^Ž€¢) ,ß6§PðiÎïóì¶ÆÆý;¿%¥œ÷s1G…B»ÁWÞðò×û÷lzÿiúôÂæ-¯\ß½0‹‘Á߯š<è2âÝ­y6×ì›ÈIÒå·/&°òîwX<ø¥];?|aÁz¡8޵⡱~rÖ9Àñ7‹³¨ÈŸÿºpæõ˶Sú·™å»P¨{q7P÷™”Ä–çÆñà¼yc–Éž—3…$ÄžwÿÜ!Þ¾¹¾wP8wa &zËã}ùæé›²Ä]K³æi….:ú]îß~ü Óg•À¤×ÏæÏïñlþåãþR8¡Ý™¦õÎ_$ï>°éù…N%ño_Vø™ùÌ3ïø(ƒ«ï~gª•Z:©;I¾Ü¤Øô}«ÆF¼SŒ"þlnÇŸ“ß.{j{–ñû³íLxb—^í ®{­Ø8½0³8ÈfßòQfÊ톼jqÚß®½'‹£Mzv£Y< (Ø¿þ©uÅtÛ;u.´º¨Ïé…‘ok ¿ûàžÉëé—ràÇ-_äÞ\\«›n7=¤¾áœÂŠàÿþ£¹ùÙä섯¾li¹¾ˆ½¶Î0Ãwâ ]²L>ŸŸŠº\?m̨q7½ôUÓy4~·ìòÂ÷MïUhx—»ðîçŠ5¤.¾kñK¯¯úôð¡ ;Þœ·ìõ‡.+ _Έñ S‹ò(ô{tÅú/H|»oÇŽÏžêSè+½öšâLF>ýˆ–7×WO÷.œ³€¿zõ•Eytœñâ7O{aûr0×–yí …Éèï÷Æäó8åÚg–N3ßôÚ‘Yƒ×Oκä{E%éyߪµÏô.æ®q$ùܰžþ^s]>“º§6îþâ‘Þ…¹GŒÈiÜd:Kaæ—ô÷º;òK¿ÅæéMo<±áˆy4îý`ÎÔ»×ðxøàæüº\ó,Šp YÜÆ¾Ú¸…óØûê°üç´»ÿËæ<_rmkjÆOpc3£Š®Ïo6Ožüá_ÅrµâðL~fZ;ìÚ¾…ššý—fô6u}5»pîÈ‘™…wΛŽüPéupí} Ý™=…kVÿ€ï9¸cËÇOÎõ”%?ŒÄwÇk×eÕíæ–F>6ïúæåñ¹hñú—›3”^?´.×ßΞþÞh ­¯LΩé™Åï®æDý_›^¸¥C¡èê>÷££$!ßôôè2Ëîs×±í¶G—fa® þ´ù·¾1­¢êçÀÇ>iæíÛñá³7WÖ_M?¸æë#æàž­ëW/ff¥øx¾ºÞþÌ;wîkZ‡âûÍï½ôÐÄ+‡÷>=È™}®™÷Âòï­^½z\ïøé¶=ûè’ñ7üm\ÿ:U:UñS[œû§ªÖ]ꇛ²TµèÒ¯fhÝ™ë÷é\S߯ëè¡uüÞmš¼©}›²¢)8 > ‰ñƒV©ïGßh$˜–„hêà'×fà±o¨Aü1(‘BgS7VL ðI »$76cšÂ”á°ê ^ÇÈKÀ¹*Î)0qF/þáHIã‚_ÂWå{¼£…%€¼å{„Âgl' Ò≓08ŒñKlàÂý8T)ö8j[ƒø¢@!: èC ŸðÁ‘§Ñ7©âzc X-}Þ¢mQ‰Pˆ%ò¼¡äÞ£Üjª]Ð<„BV.òH‚¹K- \K¼—Õ »†.3ŠÃ’T¢çupP®ž d2É P§ ÐÅb*xÛ £Û À…°:%V”FF í7Øé³Ø0ákVÛ¨%E0y"g\ªR(–=ÎBád|e÷­&·ˆ£˜âj—D“#¸Lcù6©˜ÛiG‰Bš_# óX‚€&d´“%'¹è“8Ð@´0TRü¬i@,ÌÎ@I¸–¬ÔZÝx¨Œ?V‚Œƒ %±£@][j`gmøˆ²~S®¾„Œ)ôµ!@hY»83.ãÔ-¶¡5:sëbJ8ò5"Å>¯0ެà ^Ša´:ur²pÈ,eqš~Q̈ PåIðs±…Œ ‰ -Ù?°¿\߀Õ:GC,a¾¬Ôð ^Ä\‚”©@GÄÅ\­oÖÆô#,$–`sGqö¤O‘꘎4Ø&qtS%¬Ý/ÄcÑþà¡æ;™¾žBðíúš&ˆ7"ƒ…m`ð©Ä‡Žî²è&¬Ò±fHb.Z'Ë@¾@[\¢Áì rKŠO“=(þe6ˆ2n„ü†a£‘{ òæ:”’ÜlZ»hBËJkÞŠ•ÎÂïÍÀ¬F_lqE)âP* ^®â.'"!ØbýYÂ3—$JÞŽ8ŽË Fá¡'+¨¬?Ye­•YÍ"”Ë·Ñt.ïÕ&|*æÏ@¢£y“« âÈ-¶¡Ýüh® Mç¸Q~½æÚbmƒürŸå`r³Þ%‘ÔËqŠEcIc^Z²z ›l/ÊÏGb^R¢:‘èHtŒ†'Jàû¹x:ðpƒ+G¬qThÐë)0SyòÏgÛ Á/'-»JßËèëËNsš…<õ› dpgâ™bgxScÁ˜ë ~0ãÆô&T‡ùœÊˆ)kV:ö3T,ÓnÇ8­\œÿë0ÓæÖã)˜)÷ 3«ÌtX˜iîn‚™ÒüßÍ!LwÃø¿(Ì´äúû#ßr„ëgÿÚÌ›þÃ?ÿ±™¨Æ¿o¢´ÿûøÂ‹Ð•Mã› ÛþW÷ÏÿŒ¼*cÓHÚ&Zý—§$…v]2‚èÂ?6]1ÿoé§_Ôs@Ÿhê×EóyÐÝÏ›Àƶ:v\¿ í÷þñ¹_«ò2è?;±XÃ^¯³G\ÓpA‰öëÔÉåÑvÿ9­¨úxö€=Šh´ã³´Z¤gU·ÌÿÔêœ6ÀÈþ%ÿE>éünÕÅàÅSz]È ûEÂ"¹ÄßwèÔï¢ 3ÙêìžÝN.e?eÀ•P½Þeõ5ná·¿ÈÿvúEçŸXøÕiçØluIÃÈrþ¾VýnºelûB¡ëu“z ¿pþ’«Ã¸×EIáøvÝ,kÛ1·NèV–E¡ÛÍ?|S—Bý¼y@œtVî;ÿØýSÀ“zu×ú?oÂ=·U ¦>ùÚEo¾òøœçßy}vׂߣ{”Êç\h*£Å—µ‘Ÿ;aÞœ¾åYjX¹ñËO7n\÷ê¬Áƒ.ïÔ\îÖ8Š/•–ÇÌ7¾eùi_ߺwÏk?\ñìŒQ—žnЯŽzê…Ï;wøÐÎ2¬zN{ð¶Kʳ(tyðãíŸ,¹ëÉ¥ONíA•ÿ[»÷ ä[‡‘õÝÑAþÎÔ˵G¨³«ªÁY—^Úº@—‘ƒ?ý`ÁëîzlÎe²õÔ’;Î-œ4|ò(þÎ3ÅŽjG½€ªÀëÛPcþøMkdÜuÚ¢Ç&µ-ËáÌ©O.‡ùiîìCÿÄßœ~¦ ãáØqä°³M'%¨¡ôŠûžž7î´Ò,úÜÿÌ=„tê}“K½:õ,tàï2óê9Ó[pûÈq£Í×Ä ó—>uËù…Bÿ‡–>D_Ôæâóxú¸dÎ KîÍÊÙ3Öìþn%Ävœòø’'çÝ{ÿt $ÚÞ²äíe3.(\ÿÚÚçé‹ÚÖ]ÌŸ“®zdÙSr£áÕ]f êï[òÚãw\=cÑÂÛP©ý¬\ÿîÓ÷¾¹õ›U“é—_*У³o\ôÂ=*ò‚ÇýÙ¿vÎí‹Þü𣧞_è?ÙsSÏ5M=ùÕ/¶}ùéŽÆÆo^0ÅN/»¼‹Î5æ,}v²£Ó½“{ÿÀW›wìÝûùÃÝÑ@/¿÷­Mß÷Á¶í›7îmlÜú̵CG ¿0›e¯}é …½Vߺ"äøŒÒG¾¸áÓW&™V¹réÚUOß·ÚÜñå«÷O¬Ë‰L]ùÁSÂY]÷̶<ª`QZ_öäæ=7eôг³/*ܸæûÆo×>2Jš±}¿‘WO{wÛ–h3veÞpרǶljÜ»Ü4ó€93LÛtyt㾯—OAêI ½öß^ûÅÞÆo^fÖù¶ó6æsh<ð.é&ÚØøÉôB§©wŽ;ïyíóæ>œ^ùÀKïÉÅ[½[û\ ¼æëçSžøØhï}è‘4»Ô<ôæójë5ïýo[qpÛ;pçør)lË3ã/(Ü €éþ/?Z6‰Fäi7>6ŸX€(Öz÷ú''\ÓƒBI½\Ïù惥¯ãWm{^ð°—NŸMx“°/‡6¿>ûÂÂ9<àkžÝYšEc£EÚn] (÷S¯= CóŠÈûàºGG·/üAØíÛ>¸¥< {m¼U»Á€¹^m:ã¢?þt>æ–à<ªO8&íËéšÅå¼ü ©qï£÷FÒÉÝ¥ƒ_ñîa\ß.QÐæÐ%¯¼·cá:À®Æ\&Lºý^¨PöúôAõŽ}wçŽ×îˆÜz'%õ¨¯áUò칇ãò>´ñ髹v»¹kÏÚ'Ö£È{_‚vC‡«'‘UmÄ+‡… n{oÑÍ×ß0kó ˆ¶¼|Ûu7Î~`Æ`¸íço<\ûw|¾î“ÍÅP¨o¿øhÕÛÏÝa²#„ìÐΟgm¾ ÛñæÍ¹eàü9ï7 5™¿ö­]d.u¿÷ã„ übATØXJ÷|pTyürñ°BÉuÁÜ£)ÇÞÏO(‡[u»gm3ëãÐÞ¯V?8´`ë‚{×6£]¾ÛºnõOO«`5âê:ûݯööù½_­yiÁÄ+‡]vFåLÛN{nõæ]ûç$’ãvaÿÐÊâ³j¡ƒ7 SsN,VÈm¥ZÊp.¦ ¨Q]v賿ÝXáyŽú—L±”þ¯b œ ÄJ ŸXš: $0Á] Þ™Ðr B Z8ùœ£-|sÌ= ÊLáž‘®O)lKaÔ&÷±µ)W(¯Y8G+6öÂÃéšalDTäÕ;rÔ2>cÆxH©Ø› "´A#¦åüc5¹sI‚⚎’_[»«¾Ëç "ÌX9€jàÁI¾M!_N-ïªÏœÞ ÜÆP.)Õ;ü‘pàgŒÎ©€Àõªp±Üó s1fÁe_o$4, 2Q.,8ÙCW°ÊeX¿0"dœòdX[œA˜#VwmÍä:7X£}éq `*¾2š%±ŠÀ‹p©šÇ––=rBáy°=Ù+Û’`âoÉ×Rø÷”ì0ÇU(/v®°ÐJˆ3¾#øˆX±VäÖö?/ƒ1rs‚P̺,Ï÷FJa V `âõTvÁ—¾‘q¡Âù¯DkðÕ Ÿ<Ô ôg¯® O@Ê&néP ÑÂá#A¬ôèß ‰nV-® @jj%šá&eøk®kEëÔE„%äÜ1‰2îþéPÞ/ôwù¶r”WZ9uj <‚À–óS¨×€¦¨AL¨ÞQî.`¼”>1¥ø”Eû;É‘[â ¹kB­à†Øòôfµc̼ϣidÖR¶¢³1‹æ|áX…›Vý×Â!Œ€¹gt²¨L“Âîè G]ˆßå«W:ƒÒñ®(WPzÊ1 /2i ‡ •KSâ;€qñƒüðhÓ<˜À2*O¡_Ó%™›@้€ðŒò‰sˆ âŒF DQ ƒ¶Jãaxúâú–?^iÇÚ°ÐØã$ÌŽÙ`¿5Js%æfÔc1«>ßé1¸=ÈÈòŠB0x ° =–ç7?ƒñai"Ë(V3+)+‡€vT—ƒØ²vz61›Š}?‡ÎÖ9xûa€ðêmš#å\]?±# ¸ósœ“06+² 1/ÅòD^Áèo\ f/wà,xbš “ k j.Ð’º­yÄÃOUˆQ›TA 'põDd™¢»åÿ/ÑÍ®ÆÿhHýÿqjÑQ•éfÑî&´=ÁÿÝ ´€ïùÿeÑÌ´TMùº›} ;Påë—•ýÜG¾þýúß4Ÿ\¨èÊÊ^õ»ÃÝ×ô••ýßN<Ü}M\—/ûâßuÿð³¼€øoN;õ¨¿ãW¿(NÌ<þñ9Éan.¡“¢úÿÅ~^(xm-"!èv~ËBé¥-UÊ^Ç/þ…N{uÓ€ï:÷>ÏâÔo~ÜñìºþÕñEþõŸLÝ·‚êú)ýG\¬0†Óz÷R¾‚¶@O9 ¥¬*ÁDüÆ´á šà _¯nùï~ÑÉòÅU¶]~w~mV¦€Q1$æ¿/üÊgÈCŸIרÃÕê Lÿ€/nØ~ÒùÊ1]Í;O9-O õ›¸Eáß*üÉc§‹r¹¹Î@ÔÇZœb¥¿{Þ<ûšS ¿ÃÙ9”…{ú¿~QÅ÷švï+ØÚ¾×©ÒÇ~Ó¦­–ºfî³óû ¿o×££Õo>ál ýo©¾î¾û¯×ÞÓúÕb>œJ{Z'E |ò½7§·5µÔ©w7Í‚à ­Û9…¶ãî^pçpáz8gôSùq•ùGÛž Shxm˦Åð;]Þ½³NÍå`Ž9ñ‚þ¦Ì]0ç*þˆ¶Cï|lîåø€3L×Lúô9]r¸ñÃýû×Ý G§aýØãÕiôªý®7ÜõÈÂ9c»“ëç¼i‹×|ø Ò¶©éuɈ+ˆ{ì‚g¾nlüúy8®;ŽFN ~ÚD:ÜïzócOÏÃD6g¾½mß·k'Ró›<õ¦k.áÞ~Ö¬u‡@ƒÏè4f$jwšrÿÄÃÒñ¦GL`2«3¦,‡í›gà5¾xÊ왓úKï¬$)‡Vƒ,äâñ Ôù.¼óñ{zãøÊ{g õÎ¥‹˜æâ“—Ú\që­×^.¥¶wo >¾Ö4Ï•S‡Q]:wñCLZP{û4ñÐ ÇèÏ]=†tQotís̲yz¡0èîÙ Eé=ÿ•'ع|É´[ÅOXÿ¶ø6ö¼àÆ¡3>¥Æù~í]ÓŸ{í±Ë)ñÂyË_ºš_0kf-ß8j¥º46̯5=ûýÉÂ)ë¯6oßüÃDªg­øàQ*ý¨…¹Ó•kÔòÀ?·ÃjÄ[9Ç˾U›rãšížÛ¹Ðû±Õ+ær[\ó‘ÍázóÏ?Ú14äµ¼ïoÃdNºáÐÁí+ÏyÓ·_¿Áª­Ó,ŧ·›žÒV§‡>Kò¾Ò ‰ž ó“¨ÞCßí€[òËÑ={gœß¾\W8£oosϺ?/k»ÿrÂ_•óâî{çS£æø=¶/½õŽ©#N×Ïÿ~ÞmôõbSõ}ž+¢yÚ³bÎK7çïÚùÁ²ûFX@ØÀeE”Û–Íœýr ãÌ÷_m-qÚm'§îÚ~n±dðw_m=²îËç®ÊÁC†¾xd~š’kÇëSòtm§¯>:'é¡íoL+bÉ+t›sT¾Ú=Ÿ.™RœA¡pþÝ«ç@/º¾ûâõû†žU(½ºÝ¾ôóæ|ÉÁÝ_¿ÿŠsËžG]Œœÿ滾?¬òó¡=›×¼tßÈ&]‹ç6Üûüë+?ܸ«2%Æ=[V/{`üÀòòçËÑgø˜\º|å{– |ŸlÙ¾mã‡ï.›?~`Åâ—¥nx1ÆUï|ÑÜëúƒ_±ÍÅŽÈãoàúo¯äQx%›ØÚÒÞõϼyíd·°|òš €ºŽ ýA¤F@//!™8ä÷YS¨ÎåH•cmSÖ`­Îr)È"Í"çËß×ÝÜýŸ²³v«Úð³åâPR¬ÊRRE§*Tq•Ô¬š½*“ÈâpôI0¹EøðË\QÙJ؇³\ËzN.0­GX@k òLjA÷=¡¯—‚E"˱U¦žs9ø~,’JApwFÁK-+‡rñgT üª"VN¦Y4|V¨ÖÓÞ]1¬­b\i¬œæPXW1¯<\O² Õ,O¢ÐŸÝ[‘£qh¹ãÚ°4ö¿C''—Õ6 ÑLM¤YùLØô ¹ÛŠÇUˆPÔ,ħ›Œ´Ü,œüí©" B ¯G¬bV†8UM Xƹt艪fs¢ï±R…Ïlš<©è2P€)'Æn"5a£/uÛQG§Šš8´&D¾i©/=ˆˆpºÛ›‰Þ…j^ý1iF–©Ÿag:Τ“pRˆ³…:™Q\™R¹RvÉVœg´Ä±z˜ÑýH£E|1 3‰>Â.ÈÐsáË&6ñ‹ X#ˆE'0áù¶c³F)gÙê†À)S„â^¨\KuÁÌ\dD ÃY8âG‡ñ%”‚y"7¶Ä9Ú©k¾†+ú!{¹©»Ò¾,»x1(5ØŠs/äÑI0-AÊ=6Þ˜„†`Ê}‚8l²Š#_5w–@KÌ~`ô*?XO @T]k!RôÓüÆdK` i•t„Í€ž`=žÃ$‡T! øfü†9‘;Džo—AèÞ“3ò¢¢, T”é`Æ­õR¬¦‡ž)SEêÈ`jÕŒdîài("‘ïY)Rô)EÈtiZæH„§ŒeØ*CY‘פE* —РH¨³$ì’®--„ãÚ±›*§†­å|¾j‡kPpäîØå ŸÁ,Ir)‰WÈš°îø6?èªB&-5ÏAi¬:£ ÞQr°XÚƒÖ” [º!ëã„2·X¬@æ6t+QfÊiEH2³+U¬¾ZQTåùr¯À.ŽhI‘ˆ†¹¶›Ù+Šdè(¡K"AòÕYLD_("OŽš QmTU–íÒ L?I¸–U€Ðqd$P¢%]•ïKD›NË*² aÈ$¿ð±Ì²Š T€“´±2±½ˆTß<V2V "¡IÇjRQ\?†žˆqjã1cº¬ˆSgÆÈóxÙÔqS– £3YÌ.ß :eêÀ’Ùe6C]ˈÊa§²åÉH¡€ä”uX2GiÅ…<¥°æ[ ¤|¡•RN™`° Ñ8Í¢‚Ä\E1º ÂuœE™1å¯s|½[ÖYI $?" ³^+Y)Á):±b¦U`]ÔêÄ$â ¹uML\MLTPècȶõ}-IY&âv¥Û§<ÄV«öb)Y™ !G¢…ä +H!rwdëN`.™i±„#‘bsÙâ©Ã;èjÛ³B‡ð¤Æ-¨)£ËfŠ2kzV 0²9 ·„;žûP97fO{· ³hê«ØfÌä”XX£8DcȾÉAmê GrÅœQ°2´McÝn” Æ™]ó4Ã9‹H¬–ÖF–0„”*ó€0Æ8Õ2'ØsËJ"g?¹DlõSý ­Ú›ô±ØÂÒb>È@•ëñ…a” 4t”5ö/+"ÖY5c Î?ÊUê(„ØÔñB­¸2éR­¸ B§%QËÕSõ3`lU‚M'ZXmi*¨[êe|g*k è±ke:A",.©ïÄRõAê LYXIHW„»I¸6WôjRò%ÍÇŠð£žÙt‘ÂÃâg⦎˰&KAŲ”‘$zˆEÐaè"î‡j—U Gɦ{±€Žì ŒŽ„β|P˜ñÅØ±+ €š—È"»c6}-ËšŸ£”ƒzº+‰±—d˜=³×ø>ó,¶$hnìP“ø.w²–•ifx“„3O cºû&av)p*Ø;ì y®G"¶ºÍò¸!¨†h{&›lÆ%BHZ¹¤À(+WNV‹sCMO”&˓ψ¬U‰mÇo•qóTdñ©ÄøÃ‡lö´py9ÉB´I@tc~jA›~ªBíi¶ÑòÓ§®…膱i& ŸÅÒ¨•ó­JðZŠ×,èÅóÇØSO”åeöƇs](Z´š‘ ŒÛX€–))UvNÚøq¢™ÖüIôžÙ‡!^% EÆ“==# ôH‡$¤su(‘b(ça-+q;õ´wÓ!(ÿ ‡È"ä…±Pà!7 Ëx«­/DÇvç®[;|= |#›Xš-9fÏCl+‚qKq»ÙárEo ¸§½›Öô½„MÏl¿†˜È5ÔyeÌ; ÿ‰" “åó(e³^:pÇ@9(Y.7Ò‘:­tÏB[OŽT‰PÌÕ…%·µGWeÌ8¸ eˈ6Qd…ï9ñY!Ôî&¸^P}Êî^NȾRî!©GŠ#N”̺Fa° ' ÿ@ &~ˆY™½øî$Ì t¶ú\Ž×É,1™pÍÖÆÇ†È“DbGlY™v\íÁØr@JȨӅIÛ±Fnäe:^¾®'&*N¹êØfëZÉî’ª¨•ÚjYAqvP¶ëIb!õ¤µOG¬q=ŽÃÖ3õ$:¥Ô-«ù!v„ð-ÜáZ*ÚÀq$”4*ÖD~èÚu9MxÛ4ÈþÀå8­ }6 G‘Ë^:Oj)!;øÈœ×‡`^ìÉÝN¢Î,ß¡š†^…t†ØŠ1¤I|芘j5T'†ìØçÊs•¿›ŽË(‘ÜÔZ 8¼h Çl'ÑSHäó†4óÇ(µV’r\–…D,“”ÆÊxî±6|Š˜naw”Ÿô¹“}üÀñ8wW~óT¡P£Òõ²É:uJ¾žOvÊý ¾rW¥R˜ rˆ#‹"%F6‹T"Í<Çaž;5H}9þ¢ùŒÍ>Ý…Ý$9û%Q-ÐÁ§jgÐx¢C£T\åd¨· +Y¡ãËÝÊ'Df%§f³"²ÑJ¤+æ²ðBùÁõãÌr51m)ŠuT2çSÕ•2…–žö…Q t‡øáa1¥ö&·?çTHßÄÒ†ØC4ÎÍ¥ÿô¨)÷5‰ 4íæ#Â:{%…uÄÇÑ*O…8ànßažö :|Ìî™ÑçDâã&,qcx ‹ Ðäì´R¿&Ã7XNÂX»ö΄ï¬V:ÂôÀ®Úžè Al&l~ “hd²ý€ýéy‡Êì¥røgßX|VB3:l¾-™ñU(T‚˜\A%EŒ#è „ÿr¾‹PFªÐ5ÖcæÁc–Èîˆ8KècQ1¡¯ÚOûµ¼Ô–ÁŒ©B´W·êYmùõ'âÐ…Gµí`,n‘€ë}cùÚ óó‰r8.!~N¶u,CZÂôËûK5"CÍÏ8¬r &€ÿÅ@™íºH4Ä`dŽÍ6ÊÞôPn¸8ôeÒ¡ðAB'A:äør„ìµ…×:ÀàUGÁ؆¯ªCåœ;÷ŸÇ<ÆñA Ä6¦ÔØ8ÃB3Æ–ÞLz *‘?ø£ý@œhÔ-Ñ~ôѾ#mï“á‚NèIµ4Õ3½TùeÏ ØÐؤ…(õ³\ÍUGf­” ”‚¹Ù½®-­g‘Y埀.À£CrF'²ßÚ]ƒäBCAž:QRÏò…ÃAÐh|¡5€Š¯}Þ Ì:C.;rTºÜQ ;æ@„¾7íÄOÃF¸¥zoD‡c©Ý'ú*—FÉ/ˆ–ºC]Ä*iЙ²Çܽ§ h‘W Ñ‘èU“ÑW-EŽÚш2½{±Ny‰“ÕK¬ÀIMÔÅŽ"‹ï…RU"Y$‘O yûÃdɉÅÌe¹¦ŽÒåJ ‰zr±Æxþ^Ä¿¸7Vv’|¤LQ^²è8l‘$¬¤Ê‡ƒxœ;¹-³^(‘CA&dŠ6ô¸i±¹[íî;¦ ´ ð°Z& ÙÂëÛ>0,¬„5š…gò™‰ërà鿆+E¥ÈŽ$Ä)èî´ $|d@¿@=DnÑI?ÈÇj‚Äå;qLjóÆj]bÒÐp³Äl*«»ÚÎPä+K#öÓˆ‘—¥6Ïîÿôì­t¶¶K¬‰Ì¾u²DÇ®°Ù†$;SChëh'ïŠ-Ïh~.SºVN>¹€Äe6Ý;v•× Ê§ãc…=\tÅ3”Aö‡c8Eá,|Ù±àuøfˆ= %ªË GA-† h.®н¾µd±H¹JHù©fˆïE<6·:d?”…¨!ÑãÀ%O‘@÷SœÅ1í¨Øéu,{*…2ÿð]•"ra_ÅYËΪcýƒöV”í8‘°> {Ǩð&…aÄva÷yï,²&í¡#¶Óà` ½°©é†³éV™ò"µb‰˜­lΕ¨pEჵ‰jc†gšTž¡SÇB>!ô6(1ÈB=|—Ñìò90Älj /œpcƒ€Žt…¤£ÍÇä<Ë®I©«aA„iYñ ŸO­+Ã3(‘£MÈy$šªë1¹,RW¶¢YŽÄ„qHt¬' l³¬YÄ…ˆ®&eËÁ&È5‘©¡f›‡ÔÁqàºzÞšò0ðkÆÌfÚ²òÎU³fp˜‚q¤•©âˆu‹9‘VÉ q-â,…T¨øéÖ’Ï DFûoöÊøÖýIžó\×N5ª“žZnÆlÑuLöÅ•Ö1ÎÂãøú!‘í!dÕ•À:ë—CE»“R1v šBYD‘¨°,øN%šªÂF^§»cØÊk?|3o½ß?|;OYTÚÐóÇ´¥·K›ÇÕïsH‹$J4½©zq·#‘ÉÕaœ„Aš[yK|3R¼cóΰ—úoÖAýýê†Wµ2°MßRÿt'¸³2ùäôÙÿ‡?á4Õ‰ØF/&ÆÕØ˜ÐÆÚ±îk¯îk"ÝfX©FÂþkH¨RèZ€- œ =tÉÍhà ždLÔ ï‹éÀC<Õ™ò•Õ$c„í‡ãêÂá[ŠpÄ%ÈUí0^’0YsB¬˜£rÖĦO1Þ0fÞ1jÒ Gœ²z¥dâ”c¾3Âct~ íB`¥ò#‡ 05ñè†%Êq$6±ö¸â{=a…¦¹r©ä@>¥ù³¨\ÀH‡–M1@|F°J2ÒˆNX¹´åÃ`.# íÁqÝ.âöS…­™žãñôR•ΖJt2Ÿ•m:Ñ0³Í;1ÁññË$(ˆX=¼Œ±&hŽ ǦðÔ©—•ÀuÏn9å³nœž[’JPNmq—Ë÷N_qØ/$®[Üå`_e™êyòp ­%#¡<ófõAøŠÙËc°ÉXD)Ζq§ç†8óqê…ÏÜî$<ŸÏ†¢n¼ˆÉb8'I·p˜JÂÍ ’p@¿¤ý7u¡Àa!õb_øOòá•°ÈÎ|÷ì¡:‚”ßeh¿Q锩2À8" @Ã-´=h²TÈ;û‡Â|"ÓMÍdæž„°äß sŠA%Ɔ½#ú‰d!˜p ÿU´B–‹Î†›BË+–Ž-[E<[Ò> …zL)Iˆ©ä­tÚlIØ@¡6æ·YKRn*쥸RȲ>D¬£@%JqúÙ Dè¥ î|­Øj'Gg9j\™Fîž)>Þ4Mhq¡†‘FârçÖKc Î*zƒÈ¨˜†5ö‚Ê %@Ê”DF”w>a¾†ÀcÒ.NôÊ׸ ðd2c„/6Þxâ_i „ %²Ãf‰0€|-m–ŒÝ˜ª¾„R¦½›Ã[Äi‹'™ƒ•x>}“ÔÆ¶áÏ€`¶^`CͲDc:Že®/mñ?Á€;b5‰€ì@)Iý{ÌR$–ND0Em¼SƒLÁÝécc¢‹+Ç­F¾ ¸¹¥T`EìI•6RžA|OYÒp–΀ïê‘Õ3Å•a½ ¬HNÈÒFKË™èWbêÆÀU;Ë@2òÆ\ÓYhh%±¼k¡vUßc…»VAF‹ÀØBi2,„“çêB Tª –_IK3ÖSÞ\c õ‰)ÂWª²6a§G.ú@ñÁøa| ±õPc‚ª€g#BJC¤ @ˆt–(‡ÄŠè%ÂÉF¬¢å"7M¬N£1u;îd:ô…â†݈«#ùBÌ…H÷" 6Uµ%Ðt…žÜë;Œ%:|RÕP|¯o÷ã¹—ù±£gÆ Ç: Ù)ú°Xý q°3Š*i”Wm-ã¤î’ ¥“Ò ™,)䤸hÙ'» Gj ænøêgÀ`‹„ƒÞk1l<^c©gÐɽ"‡h»M£U†úBº5ˆy ÓÁ*vXÚI 1då @j:tܦ¦ÖJêÇ–ÃT)Ûü”ûRlcÚÊ+FÖ@ê&!¤?uᙄ % ‡õ]a%DH‡JzÞƒÄÁÌ&*L.á}"¥6f¤òerg·P%P@ð#GbŽŠƒš°_àü‘¹="§Štµ8 J+~I±n©”žJµ©s/fE1l£•Ȉ§HŠ)I;W\=Â9ŧ[!ÇR§®2ò¥¼îŠWC!ª8dIù$Íã0aÍ€WÒ|¼DØ©‰ƒo()l¤ôVìƒQl…°áÌC”RàÖÕMþÃPWì.qcUÞ"6-3žFÇ•(ADÄg Šáˆ# íáãF¥'G–‹Ç6 úþ²ÖFØ—)Êã@˜ªª‹+²zNÆÃã(cŸç”»AøóŸhÔ'œwUóeU©Ð_kü…•q˜$*ÓÞ qÀ…1·tÄÁdÜzÚU1M‰ ZÚqÕY&nꂎ#ÝÊzQc&b`ækŒcÝ:Ó‹{¥´åD<#‡%´fr¯ôey¦{S€èëLð¢‰\Vœk:~ñ½¦lJäK€M+·éW©kUÄP_1Ó×äjg̾ú+Kj¶yË1>ÓåÐoÄ| ;H>SÂâÒŒAvkeÂÍüŸýL9„WÆËXúdv‘±ËZ©„5ª \HièIÊâØ]t=1 C…dšúo™­ ɉ憎^â©áÿôÅ/΀p)VêkŽ,y”,'ÀH÷‰X:P9xT¿Kg‰oDV´Y½Pæ/O ¡ž§‚c@iªÞ¾L"áL`=‰œ&ÚØÃ‡ž0D¢Ö•¯ÙPdt”)’Q±ÂØSÈ<‡•›k]–ÐLA´ó½!G%ó¨’P¬òþÂ6zL$av>ûÉ5®#ð"‰8¹{™ù3>&níH3¥^æFŽ,:ÀÍð ö@Îi=©A5 »¸›SÛk41Pc–Ö K…ÞÆf{¾¦:„˜p†f‚8–Ò†ÂOˆ—åüÛ~Ä®ž%=Ê9–¼L_Ÿ+b`È áBõHi”S^·<;{f>¦)–uôäÏ„§`QK!`E!OÎÌ”8ÑiÄL°”‰Ív7 ½¹V°1ba? ¤Í3ýáña¦Êý%Ù™œÃ´$x°/Ûø˜·Ë¼FÒ¾EKô¡+XÉ$!ß«Û/"…P=ÌŸOÂÌZDdÛÇ_Eçó…X\q´½O%1ä~sS™à‰â½¹±Š1oäÌ1\&:¨eõâó¥4ÑHPQÕ5mfg;f [Rž9С!D>±›>väa¯éi$…{Ó¢µ:Ùós ¸ÇË7‰Wl\î5œWeË{,–y:;'Xš€ÐBögšo ü2H, &ã†SZ{ š4R€;mÅä(ZqßrÄ`áµS›JçúiJžpØw•Hç’ PÌ! BW¹Öp\QP¹¢ XT0Ëæ¡'‘®H §5.¥VÏ|fï.Ó¤Êéï\AuÉ¡ð-™Þ‹÷ P”¿Ë;.×åc/v¬1ª–šı›tÊÄŠŽ*XYËü¦Ãt€„sÅ%gbÀÄ|`*ƒ‰¡NP7b©AjÄ‹hV€­a ž(ôâ´JM7'Õ½"Eþê~&VVr¢öˆ2K_Ú)¶„¦é’œÙT+{²X,ÊXI`N‹N$EìzÖl—ÐM0Ê2³Þ¯T錈å…Y# žæ² Q/ÂÉN‰è\¨¥@^«”ˆ©=pØa¨Z቞ :™™ë¡=aCbxÃ%JŒb¶âø˜IcËXA‚í|<E÷kÐ>NqÅåX{\;]ˆÖ'¡â 9^ÎcÞ\šœõÐ_ü¡g둎y)09"¦-_¦[ŽXǦßrÛ#€Ý¥gˆNxÍ,³Xö*]„¾¨L^1pÆ®Á]’#¶ÈªRà4¹W¹ܼx—²´Sð;¼ãL G™®q”áǾ}s áD™8(y!cË‹S ivY½6ÓXÇY9O5ð9$DÜ!ûTÚþ`°³J(z4«€ˆ¡¯«%æ¢D¢|bëÌJ@ýêëÈ"õlÆ€á.‘F39Æ‹0BÞW ¼¥‰Ãøà›_&2$ºo=¾àÃUl‚Ãij#€eÝávSF$L¶\Ÿ.X¿-c æ† º°Ä†I›ûø4´/`®Ž5«P¯rp;^pT•F¡Œ¥È W'öýtÜ€¦&|–º4Ñd9@_ãÕ%ÊÍÑ‘L ƉÂk“ÄÎ…¡+á¤LRÕ€É$Q߀+ì—šŠ6†utõ`µä»Ä4`—­8šÜ¼QiªŒŠn{K Væä¯ (ƒdlµå@ƒrPBF4Z†`¨u¨‹àªwe†u«r àgé?ä Ž‡+S£*œœú¢ á­ ŠÓŽÌäÎÐŽUéð„™Z*Ê”àè‡T:î)?RÝœˆ¹ÕÉÐQi)tU†é„Šæ'|CÊfZL+„¾.n ¤‡¾õÜÇ›OrÊÉiÊöÌ(®Z[o".Ö U ÙO‡´íkê„L«MÌE8Ç…ä ³.Ghx¡%èMÈUæÊÞ(ÉH…‰pÂñyŒfTjÞg?åÞɉtM6 ’dL‘Êd“i‘ùŠÅ¦ŒþØ:ð€tä8*àÓcœ ¸¼ƒ/?¿ÈøÜËO;*ŸŠ”ŸpO[*žËT8Ãá, ÅŸ›«[þÔµzCrXîDªÛCèǹO&Sн¾x c2x=SY‚2+Sg-A^j"’p9êöô#Bá|î*ERc®IäLYE,Ê›Zí•\¡ånSÑ+©ìd­èŽ-sÝÖÚ8ˆrGo¹SXŠWÙ…\ÉÙ\É1]ú…™»¢»»‚k\kT@ëi¶‹Æ~ÓÕ}áˆù X¼ )Ê…Ñ( r ¯Â–D>‡"y‘²6— › …=Z5´«¸‚c§Ò\/dE€8QO0ù¬ÙëÎaqEV(ñqèAEB !££+ƒ?Tp=+]EGu—vE÷7—¹¢³¼‚S½ÜûÎÏWòÔ7áÒ/qÿ×f3ž ÙžúsGÓp q V©GâÙ ¨ ¤‘rÅöÀÅsÅ&ÏÕ{ÙžXIõÄ=€hVvE‡_¢æsœÑ!i¸“xæ2ŠÞÈrÒÆ¯4ÁÂΉ[£â¼¶~Åãû²£þžö…M¸JÜ µ¶9ª¥("V!s1Òç…a¤TIªë³Ñ¬ßìå·d7C±¨I^~„×LÙ¦)-3›IöˆpŸ *­ 4©ÆJƲCé9DfEìf%œ'$”3BBèI*âC™Õ©ÿÊ‘'Ô¨t¡ß¢\ü´aXÓrþž¹TG·ViR´‡¦ˆ}™ó*QdôNãÅv=EË&‰Ä‹Î< b"Ú{å!™l¢pã{¢u¥5J“ e”(ci‰ÃL³©è^«äˆ«ä´ãݓ҂:X žÈ´qÐ9È…“€‚½4·36J,ãGQ e |)sEÄ~¸?»¹B(@Å  œEÅp„J •‚t[U1$¢ ¨žR1¥,æEr¨ SLÓ³ìî,ô¦bN¥€K¡\~L9ÈþĶð '’]Ɖ*¤>…#//ÅÈ:M<=Ù3vMÌõ¤®B¨sUÞ'›ÒDk•Æ'z¡'h¥‰OB,> Ú9dYH|¢·=«@iþ©8–çªxd›qM—B!2–øÀOuô‹¿ ›L;¸êöĆ5a¡_ßËë#Çe4Ç1…N4QDL´.[‰ÕsHŠcê#Br(¡"Ý-£·p—}ƒ~ßß9mˆ^zÞÁ‡÷\ßpß–-9™"ó?wÞPü’ð/Ž4ÿÝé²ËëjëkqFŸ!—ÕU9|äˆ~Uk×ô­^ÕixSˆÃÿVÅ?V× Ø¿ïðš¡ýú×Ê]‡ غʯZ_õ¨ˆÖnýSUK“Eþþ÷·XS_Uéþ¢[M%›{)‹&_Pü@ˆ:5Ô ,¾•²¨p¿çhaŽ˜5eá;¥ù›>Òi°iÞ~E7W÷«8 ªKíðþ—]6°Nï¥,*?ÐÆt°öƒ>WS”Eß~xÁðÚ!G*FWóª:× ®íŸÝÉuQéö jL'­2pÈðª.õÇ ¨k*wÊ‚Ÿi7²O]ë?UµângúiQ§û‘;oc:)÷ê$øzýÿ?»‚èWÔöfÛåøÅ!þ/r²ÿc/Ôÿâ¬ïÒ‹Í?=þRc3´ÉýI¾×/©èªÐVsbþÇcÍOòf§¨¦Í?}úæØ‘Zw¢OÎf,z±Y/¤µÄç¶læ7ÿ˜¡Òp7e+žvÐGÌÛmðàšAu}ªüÖUúôÖUâ=Ö¡ÑDYdF+)„åKå—œ?ua0K•”$úëV‡1¹i»´VþÊm“_JŠÂ÷‰½ò×-UÙòSR´¤¸ëŒö=ºRõ LùSä.õ£Ö8®õ¹ƒ‡\1˜þaLÂm†Œ¼ B:æªZŸg k̺Ög˱¡Nol]-Öb»þÍgâQÓú®â8õOô­å–¿Tz¨K}iºÃ>tf͈þµù'P—‡}Ä£¿v.÷šLò†¯ù¦!õÿQW;ÄX„}ð#ß&ŸVÕ\ݺ£Éºî?«N®:®ªE.Â'WÑ[«N>®ªuçšáõ¾¥zÈà>#û×7ñùPu—¼ urøWKæÆ3MÇ®jÑmD]Û†ºÁúôÁWRMgUG\UüÿŽ !@Ö𺌱ƒQHG¡3ûŠêÛ¾¹™µÍ£µëðšÁ#þsÈðA¢÷f_ßÂþÒª¦ÿPÓóy°™ßëd ´È=ÛºkÿúGìZ¶ÒêõI™ŠFü)ÿëðºÿhFtÏJ‰=s¤õÔÕ˜äµ5ëº_ÚÙÌ-uƒëéÇ’ŸÚÕÔÖ^”ýÒÁìÕFTÊíì¦s;»87þeøz3·]úÿµ÷Ýý‰ãÜÂïà; .˜’j ©¤N’ILI„±a÷™ýã~öW’›lK¶ dÊîìýÝy‚-«®stÎåNO6Wb{Ué¾(Ý®c‘ò 3|ïýƒ¶+«[ž#ÀR‡=mdÃLÞËÃQOû¼`ôü>ü .{Œž®ÚÀàoú.D0ÞRñcLhÀ‹&€v/ÂJÆ“æHnmcµóÒ=ù««ôåÑ•¬ôdØ3jv~æxÍ™ÛgÌÑÙ@r4€H¡Ò‡ÏlLÄá®{ñ+Ü¿+Ï’ô”`3XK‹šÔ¹bXxÕ^åÍ«D2¯ÿðª_žWý$¶3ëUâŸÆ<`Sêwé“AßU¶­™[ŸS§ÊTÿ×mOàÐ ô­ËÒQ†£˜Q󵫴ºãðÅ÷ѯhîx˜˜NV¡·ð%•€FZ?j/Õz`ºvúžóÍàæ+ØÍ¸>Œ‘7#w2;ÓÑ(ëìÞPASìãüør¤ö:Ý Øhüiì4ÆûÃöÛß=µ«©}t¾MÔñ»%Qô/€ÝÞûÇdF®…B£L*¯ôÔQ_þ®ýLÌI@~i@Ô°°!¤oÞò ï"Ös2%þ¶R±?P¾føf—Lèú(…ÿÝÌR‡”’7|ñwW~së<ð)]ßѾarõš’aàÚëPù=1å.fhŸÈƒö«íÁp2¶ IùUÓAò–0’ÿêÚÕ¹¥û“q×h »òƒdR0‰Rjî7\Z/ P³%Yù*ÖaEé|U*Í Ÿ6w;òüx¡ý¬·úç.<©ËUÚ^¸ÔŸ(T|±µ Œ7/C½RÏh·Û,ïï¤ hÛÝÄ"à¿èúþ·×·v í˨tQjÅáÃÈÿmµÆ;òXF*‹¡^ÂM]åd€ÅœÅ0ä%sÄÿ!ubOî)á’ 5ô_N‡øoºL’JŸE¢©ôúÄfž¥”åaP*ÐŽ²1áÝnÚ}¼YÔôg¨ô?ÅÐs.;S$¨|¼¯¡É{›™N#Òie62yv“ hhz»Cî ÿv¾Ó^Qmûœ Ö‚S¿ê ’B­þ ckÐBâ¨7&8:²ò¦.oÂn@oSŠF€R(ĸtÖLDÎ$S4³”!úÏ@ j»¯à«j«JûçÈÕŸ%öÛÝ_ƤŸ•€¬°îÀE5ús*ɘß1»B !˜¶Áà5 ¢É¢:cÍò4€ùþcwJêÊÜ,Jÿ/nþ£@„¯Ñ¯-/ ©/iŸ×.ÅN@sºï®`ØÿEí$”fÛ‹ŸbÙÿ9Vø L=É~¬`{äXaî–cNÒ­üÏ0çÔ;<ôcd±ËÆ)¤›ûCº?‰tÑ¥/“®Õ‰©0~iÒÍ}&åþToÃÕVŒ3¼…ÕüÓ8,hQGæ­òDöºÿè>ÿ©"û'˜ySM0Öþ¥Úq¼ýUN7’¹eDŽpPg‘ž§k˜^"Û4¾(‡M<Ø4þÓ8ù†¯/·Dõž‚Vß^‰‡îi€~k@˜ gŒhР·€`DÒ@ñ9?'DC©‹æµ²8æUÝy`ÄŠ¼vAEö·…©Í™X¡ã ¢ íT:gÀ+¯§–P ñ9ñæ?  X96lPª tìÈé5±) ø«÷·Eþ÷…Î5Í„+Ü b8೺p5keP@Qø½A¡³Š‚dˆR‹kšrÃ<€€€è\³ø[ƒÂHÁ1U)(xã6ЇÌÔ¯¸Ÿœ§óŸ0nLÏøYïO[‹ÍZk œ5ÝÞFà,)L–pÞÇèy3~L¿f°ÿÀWкýªEöý|Ûð_‚Ä›ÑàF’´hgþl~±¯?×ÑÆ7ïãfsŒýŽÑ¦jÀ6SÑòMϱabÒO ÚÚ fàþø×Œø"9Ø?,6FE `* 9Øæ­Öe¨·ÌêG¶ÄËøûèg9y5Ö|åÆÏT&½Ä¸¿ D†õós·}/Q-÷•=—ÀCw!…÷äþóx8覵¦DÁgoÉ*ý¯N-÷6Etkj"·ÐØè™¿£øû›õ{[í£KðwßúþØ~ëjaÊ[WÝÀST·ŠWV¾«cXíoÈYÍ>ëÚÜíð~ß‚ï¸{–ûEîžæÏõKîŒ/_ Ò»ùëøÃ:~2ëÈþazˆ–‘ãd^5¨GqÛâØK‰ÝÊþ£xüá?€{¬ý¢Üã3ïø‘ë(ü,³ú®Þ‡/J﹇ŽIÿƒ3Ê12fD£ÐKÁ:ô*]ç1Q«ùBÊ1.•¸Ùœ¿ÑE=ë!-95X>³},ÐÍ“o“2˜Ÿë;'gæÏÊúM=þYÚõÖ×é_ÈÓ}þ}QÝþ¹4—ónÿla~ÿl¿ÿ¯qáçÏsdß§ò¤?~À„q³÷>ê›Â˜rtp>spW{‚4[âH£1¶T¡¼:èìšõÉ}‹œŸ”D„VtÚb//¿;Ÿ«€!<7ÿ„œÏC§m7´âׯ½qW{7sDØz Õè±^£>»íöa¦Šö]ÐÓUð}£÷n,aʘÐÉqïåu kh™]÷6[÷rhyœ¦p›7q„ãûÍr¸?|†[ðsmÞBŽÇ:Œ|\³Zžd$" F·h)ˆ²áøéîñÅÉq5œ¤ð¥5ý1è´d"œW¦á(:iÈŠÞèÚxƒS åXÉ¥6ãY‹Žˆ9ë:R¬¦¥z%~1Ž# |1œÀ ^3/Yå¢;´_Ò#„ç´WÍïï­avóÿ`Ñ ¹ÕU?àfÆ!¦„†Êèu~•å÷Ñ J5?ê`ÉÝp¹?QÇ&u (áÝÑÍ¶ŽšþÕEåÀüêý-‡€y)]UôÚSßRcV¾wǯ݉ L”„€ ~àÁ9°R”pmØï¡Ñ–/€}ÿ+Ãön^X³¡ØcÆø ˜-ü…I ð;~wÔíô&ïáó.J÷Ó¸YdL€›4»ãÉ(\ëC=概u‚톌Š wï†ølµœ®Ø£È™Æö¨—Öž™¢Wî÷TÇ#u4;½£ðYÔ™)^G²¦ÈÅ×á¤Ã»“ñ0|.ýÓ%9Ö€Tx„h@í½OúfuìѬÈZ9‡°5܆ž}}7GcèX Œü¿÷þ¼^ˆ=wõådvEÖZ}vsèkÕ~íõ;JW‘]n¼…ÿŒÑÅWðm|i >þ%+ê:†@xÓ¿dÄYQ[ø\¥´˜ø¤ÏDµýúM¡3ÐÜ‚~€bºÈ-焘Ӯ«ÕîõÂ3¬ `!»ð_ÞzNÛ?#$xOH0­¿'qÇ‚ø¾»ú“ ½ ãðý³Hýwâbk1/6eGåÏÃÃ5U†6Ô‰±¢ã§Ó˜Ë/4••ªÏÿÂÒø'“Úïµw^,æòi)g¼ÓÖúew¿ÿlæ+dói®+ú­æL¸ú³WÃóùt±è»˜¿µ¼Lÿým$pþÌEe¥4½8>‹zíB«—eUFËŸ¼W†qH[Pk8úN£û<>QzÚQ¶ïÒÜßüÂq½æp¢´»%èÄøéÒȨŸ=…÷îXÖ¢f›GqÆy,ttW vaî žïÂo`&'ã0ôl̦º›ÃíÝiȃ—‰üÒ ŸGFûœ$‰Õ5æÃŠa‡JBV(Ð[ axÞ2ðœpOöåq7Ü‚Gz~=FŸ¨1r<)uÃÝÿÃÕNo,·zýÞø;ã|[&È}'l5å­¢Ó°åQW}5]Lȇ„ùÐì,6G§l# Jû;€B¯VMÏ”ï$Løú® ƒ¯ÈÙæ{2xÏØ¥ØØR³Ûß“Çaöa-ÛýŠŠÞ’X—Ù²1lË}hÃãmñPÛ†£ÚAö¶»*+à;0zýÚk¿ž*Ãç^¿{Øýn§y[Ëê{«Ûqµ´akÜœ´Ôî¸6ŒÕs¼k ÙlÍaü‚îØõjvZ©Á– C%³Ø¦éTHÝg¶ 7ºuûnLçÂϦ³udà<ô9 ãWõþ Ýï^@Cïƒ^À¼}¾êU*T‹àtÅR j-ófÚZ*åVÿêƒÚpKî˃¶ÉÆ2Ø©¥ÿœ‡šN–Q=mš¥9.ÌYð8sCM<à%„w÷å=T%g‚FÉX"<ómØJ·á©ÊØÅðÍF€Ã†ðÒMxö¦´PÔ.V±¯ÎÙR}ëZ°o&…éŒi [ûƒçaØ"3Ž"µN0âìPkR7‚¾a¾©ÆüGô‰ÆŽ2Wn”pÜà©›mÛ(w³2Dü²Žøç4ÄGÃÓ›²ŒÀÁcÃ.A zõä4¨ÀÑ1Œ‰ô”:ZŽ]¹ª—róZãrÞÔ†„‚m-ðÒb* ‹…jæ¤ê™= ú™ rw© 7] €Ã8+ÌQ›¿ËÊ›jGc†Æ&}0´Å°‰†çÁ8Ýé”ç¡©¹2têàónàöKqªÀ6º4Ôǵ.­t¶Ãö2_¤¶Â]¥”­lº MBÙp‡&ŸºÞ E_ÃÏÜñV¯ §‡Ú…×|ƒI{ÎYoó—Ëêw¶B‘ÃF_¾íþò'j{Ôo§£Ö¦=P½ ÚŒ{}ÓÛE¥gÕÉõhƒ(ÔOb(…‘¦¬ÑŒmKˆmÔIËX•H}›_ƒÔ¢…R·&:È(ß §•Ú#Ê -#…ªH§Ã~Ï‹WŸéÌýA»?q~vâå óIìÖèBÛ,訌õî0ÏD>`ªRÆö; /=µÎo”áÀkМ»€QµäqCþÞU¼3ÞËAZ~WÍÑbÁƒ¨Ÿiå}kÊð}Wÿ=TÞ.<µêgç–4 öaÉOÓ¢~Ù0•®¬°†ƒaû&c.îÃÞ@"Y¢€\þ=Ð"Šö¡•¼Ûþ…û¤¶z °¶@ß[óöú°ÔïØbu7¼ö P˜ù%}½d{Šüm•ê|„<á\€-ðx/}7í:;¿Ûïøz`ˆ޹¿æ­ÅJ›~raÆrx~xå¾étñe”%OÇÑœCKc}Þê©>¾&vãø]ò&P~]Ñ4#üZ%—Þˆ‘«®h—ª˜€ó\ ½}1¾˜4Š'K–Êu·uÕëþͰ È äq÷âuòÞȽ¾J·¬ñýsx·9$*CäǦàBh9%€ñ ^iªsÙÇLF%iR€ÃôÕqüO6q3Ò¬ð¦º÷•®Õâ­Ø+’®ck ävÌî7 ØÜ<èf7xs`8©–ºFdfxóg¥û1±H–ÈÎðd£8‰?¨{jûý»o·õÛ·û ¨µ¨µhðì|žíƒ¬.ÅY´D×#þµß)'ÞžLYǽÞ•Ø‘W ‚¼†¼$>fky¥`È+C^)(òJìÈ+Ù‘7Mv”Ûº€¿’Ó¼ÿÌí(Ì1~àDáœ(0 °…% { P{8aÃ^ŽÑ9;¢û5¶á¢wË ˆÎ9–K÷Þ .®sAqÃqÝoò5ѹ@Œšs`9[kÅ•a¨áòwyà‹á\ çî Mžwy;îzc$á®à×2îò.ÜÍ=øp—Š»<;îòAp—„»| Üåá.OÁÝ#`Î l¹´ïÙÑ—„¾;ú vôõFJC_’™ak}úò>è+C_!(ú ìè+A_!ú ÐW„¾}õ‹yü0R€½B ìÙ±W´c¯7NŠözëÒb0ìrÚÇ6ƒ!¯yEväƒ ¯yÅ@È+B^‘‚¼ÚeT~ø(À]ѻƑüþà- /ØÁÎâ}®•]nJãh,¹ÝÚ+™“½âzMŽ)›¥æóÑBcc·‰lˆ‹ÿì¬ìŒ¥ÉZéäŸÊZÿþ‹DO•Hde9‰Ä¢¡êèë?xImrG9ÛçÁ *üÙÜÍ?¼ôÁ‹çðFÛ|½´Ó­£yÄzð½´sõð‘,¡+n¥êÓÖükiþÌ”„×–6ÐÏ‹œôÞ£ŸÕ§öþüÙGß–ÄÂú6\aý Åv.¾´×àƒmô V~~Øü'÷%7z­¶.¸hm£º6Kñ`·Ð½$K+g)ÐfƒOî.îÝWž/ž UY^^ÜMõ/8´´B!­ Ê¡ØîáM'—Û¿ÄRqéàç¡øÁBîòY‡ÜÊÛí!øoGM¼P§ÑÈÃòóöÀÈñý6ú[:‹\x~/¸¨ñ0ú­Þ|)ƒ‡'#óáöø}öÀ /ÿß–‰;‚•B§Ÿt‡+úͱG)gÐ+¹¥å}\w»Í¬+èìw:A„Õîz‚ÑùÆ»r âOˆ˜›Ü’žòÉí«V†Ë$V’Û¯cþ%d7ÎÖDóÅ™ùz±.n_ŒK•çbýmoá|S®"©×o{æÉv:I=vî")¡ÖŒÄ÷Ôüy›ÅHrks˪ââ>»}ò´Åí=lÃÉ’[¹•…JW)MªÉ£Æuåp?Ò4ÞVÞÒUÚ+>]Ô7C±êu©{¾“Q_62{»_+_jWÍ̘‚–ïà›Ó2@Š”#}¥›·YmÊ¥¡z¬ý¥¯´¡*J¶Òã27oy«I(f­P¹—ï²`…Ir«Yʪ‚zdLªP&·O-ð³Þç:K·¼ÛuõFyHTޏL¶Ç×üØ-ƒ/“_À(Qam|ÈàlO°A.sê Ò™ø¦Ð}R>Æ—Ö `|Ør+w.¯ ÄAÕÂ5Ot/[Œí¾‘݈.…bêòâpDZ«2yJ/Æ[‹ç÷¤A“Bƒ¶ÒÜÂÂÕ—cÉ`2¾o·_¸Z)wBp´ö­°8×OIƒrµçöuÐPlIÈÞVÉkÍÞv¸z]¹%ïjíãR(_´bà³ìе§Ëïkú §ËË`_ì»**W™W4(¿²ÛªÚwõNy¨\ÂAnTÊ>dÇéËUÒ ¡˜ò0Ú;°†u š;æÖhƒ¶•¯þ†<èqueá#79BƒifV]•j´A÷¶…ÿ…pµ‡½s4(Ä1'*©ë±·ÌU“8h=59¦ºÜ}Ù9! Ö¢lD2Š::]„î¸|V[ÙÎïD €ó#ç |éVôv5î4×l¼]¡AC1¾zÿV³­õË׸«JÄA£{jþmá,GôhEé‘ Åа;oå]m­®Aï\s­«’=\½?ìtScâ ÍÇíu4(”bîµßï”hƒ–¹«å›yÐÆÂ¤ùÒꃂQаW ~Hðe=SïÓ=ä®FâeÐíÄÕ×ë§ÝPŒ¸ÖëíÖ uÐÇÇÝñ5eÐû,÷pr‘p Fц=>yùvSÙX!ú0NŸQ}?M.ÝЭqg`âZOvÊÝ®Z&Zý¶š£ ZØ‹\s mP9:®£Aá(š¬‰l+“ë»,4é"š“…õÄ×Éû#tSqú´r¾¨úV\± *½.qGÇÒ”ê}ay+¾gp‘´¢¾,ÀAWÝì¡‘ŽÜ/äj`ÐÕ%Sï‡EmÐíx5…E£èŽìÖN–µAÆkvVx™\ßÛ<€ƒfÜ2õ’_Í7–¾Akç Joð1}ص³´}­{—¥ØÒTܾl4l+]¸S¥Ö’4œ›é—¢7ã³}0¨piвÛ\&câ†õ[*,ß^6îˆo'rdƒÛ¿OŽIo!ç——·xY=] ½{PKEb¥Å |K`k­A._[äá[ÒD÷^G¹ÁrNDTIz?Pò'{åíx\à·¾äÉo÷—";'×Õ3ë­M‹î×÷TòׇÜC#™”&”·¹Çã­É2é-ÐÇ¢‡‡Ï§kù«Uâ×…ã/|"¾}÷ߦܜŠ[4wÒñÜÒ¥|WÝÒ Fx¿¿*o\ïPÞ–V®•^‰òv/õXÎ]Ü[oí;Ú­}ÛLˆ ò×Çç¯ßÔÇj’òöæÛ»¨fÒ[±ã÷áê[·@þúöáÔÐ oVîLìv¿}ü¸BÜ1ùFØŒ¦ò5òÛîÍqm=é’ß>s¯Ëßö£ˆÅ®Ï:WñÈñ6ékEÙ|<wÎâqø6í~+”öOÎJïð­“ Af÷ñ]¶uÅz¿5JlŒ0 ²™­âÞâ7Ä4û¬¼ºrxR#O3=uãråpveªr~I]}mBkò"¿KLà_§À¦|+GV%Ì~ÛÚ¾Ù4wÐxÖÈ™£Â`˜‚7ÈÏã€9>o˜ƒ?ÓÛl%€–­ª…ÓŒ÷)QayótUSm¡ƒ1Ü­q™žHŒ@;çÍb·ø ÙÄ=âÉø°Ø ÑÚ×Uê ÈΡ T[`ç<âú˜mØÛ¯ƒÖ#}Phç˜ƒŠ¶A ÀÞ‡úÿ½1l½oð>h¶¹ˆƒ÷lç´³´´` Š´kP(+m†Úÿˆh´öÂQT õÊZs PûoÑ•=­sk6}Ì>,Ò)¨ƒBâ’ÞuPÈÇjûKŽ]åS@_@ã¿ô8žt˜Ú,tí€eAj=ÙŒ0ô¨Lßb·€k¶9„tÂÕ5%ðu*ŽùnÀ_e¨Ãí#ÀjR|ýäÀø(¥ÿ³Íí[Æ:„öYVͦÎm:ÿÖé`qËwe}òy Ltm¸5Šw.œ¬ _ʼv+1øÏ‚9À >€A‹`6w~¥ô­¦éÉ¢ÍûØÞÖV5†ý8£¥1Ÿéî2«ñéÒ‡ÑD_®5aî@ŠÅÀ(ð :ØŒ}f'æ *É­–¸‡ƒ|ýòü\‚æÃd…4%Ë£MJõžT¦·°–BÿhðÔ|.O òÆÄ9Òù‰@Gÿœãv5a}ÛüaÃo}àh%É7ï·¯.Žüö/u¤ã‹fÓØÖ‡FA+\_ñûþÕ›~~K*°<:»bFvÜâ#‹{^þ¸™³,ÈjT9äåÅå½Y oÂ=C‚»¾/A!ßRqݧDb>`Ê©“õTïË#|sõž¬GóÂÙwãk•¯>¨u³ ‘ Àúá’®”`W½?Û©Ò5ÄÛSðŸ;Ümê‚]ZÁ‡¶M¡ÊѾVÅÅõÃÆ,KCþ±ûP/i4D›ו/©« ÅŒu%–Ъȼý65B‚bʦz_IÛ0Ý$CžsÝÓô’]WÇ·i«~ÿA Àä@€y^‹¡Ié3i,)ôÀd¾ Þ™êZÂêcvº“£ ⪃Š|¹f65žìÞËT5¥ý£ï•vHáF‹–eØN]îë\9¢ ”,Gxjg™×arÓ=¯µšÜo BéKñ€Œ°©Rœ …ymÉ[a„6Ä´^Á¤À×—Š'¯ee=u–šµfD•–`ò×±ýíÔí\Õ-– (†b~ûûV˜Ì¬=é´&ߊx ®/ã;¥bÔCVZóaPéÀx¯ ´)íX4kí²’(;è£Ò=N–Y÷/óSéXéó­ ˜¢ÊÙU(6Ege¹h^&·twf(3-ÊJ6œg茪ÕM1‹×ÎbvŽp‘º_ËôÃ¥›ÛU»áºI¥:³vœÜoi|Ñ‹¯)A¦ƒ—=Võ:£é {NK|jª|Ù{˜”ÊÚy,:Û1*WÕe%tØÍ>7l4M n÷é;«±@Ûi•ÊB1†©a7ñÑ,qm*~\€e"vÝÒ˜ˆS·ô‰Ù;,Ö˜0u»ˆ*ÝWþSâuz™Î¯wà qЇ$±¤{HȈÆ.z¬ú;Г× £ÀÏ(fpÉ8õwsiˆöñÅy.->¥{óޏÄò~Ÿ÷®«¾];¤ŸYXÐÁ$¸Î%ÅÄÅâGvJÀØÀò¨øøú¬ I‡Ž‡¿gÃ} eÆ"svUúЩJÓ°hŸ¢L¿0+쑴Ѿs>ÌšðèÐ. ×Îæ@/‡NHãJx¾v± ?Ñ®[²¹lÅí˘|A¶Uwn|ìž `tèv¸| » £0CÐÁÝ7´Ytò ÐaÐe‘n™ˆ'íñ`U7Í@tçaÂìô*LáćÎ÷Uï5‡˜åì,Â^o«‹'ÃθYùJÀsg“=qí»È³ŸX9û±’ÓÎævŠÍ£òI…ÕKˆ±ŸG%ˆïß)÷,¹:³ŸêÌá¯7–¾irKðÔi°ºÐ`Wvqc÷ór¼ÀÙzúPÎøhJÄÍ#(qõÓÎÑìTù”X!p´Ë™9šµ/WÃ9p4õÈ„pë•£©oôCGC'ïdS v&ÌÌрЌÎNû— …ö/gæhÈ~Aý̬S ^æpöŠúy¤ípÝñeFÇ!›.€q~û–­sTwƒíèÐåqÃÃBõ‰,£“÷­GP×”„Õ_!3ÚSg8’ÛÉÀdC166 :óÔê½™¬'ƒÎfŽ~€q:N“?{e&çê}%ˆ)Pp ôã£È1Î&íðöLÛ‹&bè‡N9þ*9~š€:ãgèÌîÈJ¤²Pãc×sÓïï?H²0 Åm,F’…!w²±Þ“ùèM»Ê:|°S!ší.Î.Å®gviY»?»~M•…Á¤Ø5ƒ~OêÏ®5ú™FR6ìHðð'—†0$<å…Vä‹Éù§–†7^Ne=tJ‹èÆ1¨ë3û:¡m‰ ”AROß ±à£Q2kº «,çg¡îµ¸äçU``ÜÄ ê.Ñtbò #{žRp¸®ž+ÿp:ç”èDŠaDˆU0¥ FÚ-«X ù†Ñ“ÒÃHcˆ\³Ûû·ÎXz(Yˆ«tóS´-ììÃG´`òÅûôv6ž‰Ýcñ'c*†ídÀ¾“Žà[šVb”Óà[#2‡ñš”ãtªXU\OÖ‚Â ãáùrñóÅ<¼Œ¥ 3ã‘ÕÂê#Ê¡óΠ Åæ“CçAŠÍ'‡Î;ƒÎq{ÃÔ9tÞt¶lÁrè¼3èìÙ‚ÓçÐygÐ9³§Í¡óΠ Åæ“CçAçÈœ:‡Î;ƒNÏ}›9‡Î;ƒÎÊá-‡.é™AGõÌ¡óΠÃ|žÉô´·ƒÑk§gí£ÏX§dZ¯§KŠ_àöf+ÎHŠr±ÛȬžüÓ%ŸXrvO/€ÓiXrêÖ-Gýâ”Xáä̲±‡…tÏ– – '«+—ý;KÍi}fÞœIû®H:Öõ¥¦%2äì‡9§„e>ú¸Á<àä›2‡üÉ>¾c6„½M)T³öK ¢§'û…‚8,¾¯ÕYÜÆ¶¥­b1ŸQj>K  B‹´¿MHÁ AuñLžÞ*ë±a%‘Iæ§Ñu~ÆŒ*Y 3tFÍÏBg¾ÙC°€ÍZOÚ•ˆš·M€'ËѪOÉÇèuÆöÔX“L}SLåšÅþ ž<½m_ó<ËÖÜ$„HÇaÒí&éÔˆO¬Þ ôÄ~†,0GßÝØ[`Ïã³9[1ðòÀ|s‡Ž†x ¼Ç¤ÆÛ1ÉžZˆ<ð`RôxSdÚ¿â"iÿ¦‰"py0}÷Ï+Ï7'†ྸïA˜³()2Ø™EÎ<¢êƒCŒœ33%ÄèG!I¾ bvÇo^q†ÖÃL¿L.6ûeÏ7Q'vªßÒ?_ŽÒ…Õ•áX™¼öu·‰Ôí}ÔA>u¹v=Œ=¢*&”n£Kv¯uð.nY¬ëXÃ3â™*ǺCÍCOqó£}0ˆYiB p0äÈâúLpxi.{þWž,xùÆíz¤ð ¶Òv=rß/+Ö¡EÒ1ùAq[ø¥Çyd Ù¹=#Š!=™M“bÉø¢nÚô±‡q|i.pZvLÉAÄ 'o÷Ž<%°û>w¹ñ’6%1˜óʰ ä‘¡F§[iqÓÀÉî‘ÙæT×ÝâbqäcÓ±xd¶ùCç (SD©÷ÈPcàßæä‘K[ž=‚è€Á#bIC›Ù#³‹3x{d°ŒT¿ü¼<2†&Pz=9À&Ç„ÉlQ;WêÚYÄ?nœEYÎ#'qû’÷Ž`54-—ÉÈ©3:dˆœ ù§¡m&fNƒ±£^7‡±¦yßb!]˜96Sþ¨fñN¯çÊ«£¤Ø3…ýDPrý’* õ⺥#TŒ¼°ì8IÏâÞYDAG°_ê§ïó·#ûùçÇtÿØÌùpz´##nÞùpÁ"T§Í‡sÆõ5ç’=â̇›%[=N…8§|8#Ùž7ï|8Ý£8¯37J>é–€¥¹çÃ7·x…ZN•ç²Å(Ç:З2‡”Ž•Ýšê“/Æé¸d˜®[²ÄDº¢$¦£ýËÙÓë!bŒ„dèÇ}­Eà^ØÃxžr6P‰Ÿ9“ öã{©ïñ|ééóI'Ð æ CÂQLb @†"´Y`#f¾¶ì¸!»óÆiv2¬Þ_1PŽQɰzUt^Aûev2¼Íå6`ÔO2¤E©Á~æ@†°·-ô®­†ìp›bOå0°3û3~·Myx¥¡¯&qEð™c3¨aÒ<2Rï?昑 :›_FêýÇ2Rù¨3éfªŒT9z” Äï(© Ÿ9ðMÐ v22S?,æ“oF*û5Ð.-ç ÄãÒÔ AF=¤,"4GY‹ûl#Sá,>4['H*œ¡ÁÒüƒóI…à ÆäÏ™..˜ßrÚT8»rN©p^è’v^©pšW!Ót¦T8Ó?Ævåç7ÂS%rKµHL‘Wg-RåôQ´ŽÎ¨1Ž»Ȱ3ÊE†Áu˜–j¿dxÚÔ†ݨãÛE8À¸ºAŠ1ˆ,¯Ž #œÂÁðŽjâA÷iUãˆèl+ž¾{εÁKªòuóqó¢òÆ—K™ƒëÊB÷ YÙN6/B±ÍáS2þ®Ÿ‚–ËåÚÍ}­#,oE+š8Bî^ÌŸ|åÎ;+oã¹XŽrq W·§¶U{ ØÖZùî––ìvCMvS&Ok¼cP<ÃŽ«q+G”As ‹ùóÄ-ÙÍ3Ãn$zeØÕ¾\R]Þo¥_h¹X G.–£Ÿ$`ƒÚSÀÔåü’UêÕ™ìK\ö)Yg Ï »hMNSåj‡§”As ±ìq剞a÷è•춘£Z?[øBÖã‹ôŽdZ†Ý¹G.áñá}Ðjõ²fóÀƒaµ Œ¿ô\¼ÉÊfƾû”vb™óngTa~ZYÛeè1¹6W-Ñ Ö|›u*¢æŽ%N±|ä²W̽oÈ­#L~eWJX'DšÜ¯ p¢§ölËœglE¿ìš°ÿ”È1W`ReŸxRÆ,?Õ?æjªJr„)ÅB¬N^ßJr¬^8tíÙ\à4´‹yÿ¸¾ Eä|½pÓ‘cYŸQ÷5V×oJ¾µ˜Îš+`M‰èU`¨Ç>%è¾ñ¬,I wªËÓ;s6³f¦l:R.±9eÓ‘–š{6^æ›M7kæãôÇØ–DžW6I®›¾ñ¹eÓ±Ý2k6]‰‘]¨³À‰µxž¸3±–pE1x¶é-¥Ùo„•é+4<[Wc!LvQAù­»â JR½W¯j ­%œ‰ à™O‘&§%N¡¾d­Qí™r5œ&¡u5¿ †WCÖDOÚWߦ¨Së Õ_Ù]_ Í¡Æë–â©N«Q?3åsu¬\WO»*{rºý†CÖT‹@%2øðBÝkÅ•O´üᳬx½ÆÝlGäF…;ψf2ô«p nõ 3—E'V¸›¶R^0ò¡WÊ›K>ge.yIŒîX|ã³W¸sÖ{uÖ¸Ûb©pÇz«9 Ra*í—EטâÞQØÙ#C.,¦æÝ’šX+G[,.OÓåÅ8Í!ó‘á²ß{®´~fôf!ß8èg‰µ°J “Ãóï‡~/œG“™™â,—7u~»û :±ªï¾ of&C3?óàcÔ4& (ï”3†)éfJ³¸/7s»ÚvÌöéý–vˆyÛîìJ˜è9eæƒi†WtÆL1„SrÆ*¼•ß©–Ó«.ŰœÆ&L»µ‰É>»e(÷ˆÝwá_‘î•zSƒO¹G‚>VNû˜EÌWS®$?ˆ±ç¸–Óλù¦Öa\ñAìµgÏq…EòÜ"œõ̘éyÇ›S8xÜAdÑ/—©=®’Æ3Ò̺eEÙæcZŠÞÅvþ¶ò¥v{QùRUvv÷r¡X¹”n—Ë¥Ì! ãlŽ ÑëÛ§§{—uØ.Gý;r>ÜFäÎÊœÒ|¶Ü¿³µS•lùpÉõö - Oz]‰mD†¤AC1˜°EÏýS£µN†:(W»(QÍ-X9búî۳Ğ<­¯±AuØÖ’ª9(–šŠ!go^ë”Ü¿hœšš¦Lžxz^rcý¿Ì™†çQ]/{{ç•ù÷NL74²ÒjË ÒZÑ Kîk‡6h×+ ïìÆÆ-ixÇwuÊ …=[ñBç g®=EgâúÀß&¦¯‘ZÚ­3µËÞ7ìù•ô–‰S­.&9‚ÒinmÒwÕ~òôï¢Ê½Â&“îÛåN—†óªbF …¡zHèù?SNÉq¾&(†žmeÓtg©ÌrWñ‹kÃnjõñ$.û„ 1l²Åî*ÁB«<²ÒÈUÓd¥ùEhº±‰v̺óDÎ뻊ôXŸ7j†‚Lʯê uJöÓ˜wç§Å6%úˆe#wêÂ1X"YaìÐG5S˜S¿zßs(ÇÊ/.Þæ¥L yG»Ô{´q|Jw§9%¤L´ó{–TNš¦ôVô5˜÷ïjÕß²`ócÊ}öΈgëÞó¢TeùÿeŸ?OˆÑ‹lM1z‘Ÿ) –¥væJ¦k‡z ]¾Í¤”+Ðëj+ê9¬×€Y€¬9€:çŸÒŸÌšè¡[2d²æ2U1£À„½¢žG®(C k K– = =ÇŠ Ž`×Àx沑i§oÞ9€fÆk“ÚÓ¬Eù¼+²Í«(_0/Ü´EùBDm€6©i‹ò*²}BQ>2›wQ¾?œKQ>¤õÁ xŸZ”^-kžEù¨õ+g(Êç˜R#{o?Å#B.™Rƒº~ÖHUý¦ºŠP×oŠX¸)êúQ ¦Wõ›ÇÝP°®ßìѶ,uý|ã”æR×Ï»ªóÝP>uýX­®Ÿ•Žèy7ÔŒuý¼Ca6Ç<êúy+줢iêú9—k¯êGô)MQ×Ï;ž)äïÐeªëç½´Pl>uýæQÄ¿®Ÿ÷‚t)6s]?#áÎëVóÙëúyGœ‘s§L?ÂCOÌä#xͳ¶–Ùëú‘rÛ,ª›)+Í· ë T¬uý¼M]CSšµ®ŸmrU¿àõøæó>u]?ïª~³Ôãc?P¡çŒ«ëç†2RçQ×O?P¡TõÃrxgMOñ¨êg‹»˜¡®ŸçQd’¾/Áêú\ #;UΣ®ŸwU¿ùd¥Õ¼×¼€ñÍT×Ïû Ë•+:e]?ïª~3Ôã P$Ø«ßÌ·x˜UýæRÏW‰gÈæp×õcÌ{ FÛÎT×÷€])Š2S]?uý¼A ëŠÎ£®Ÿ 1¢7Ç}/KΓ»®_0¿å´uý¼& 7ON‘óô¨xWõ =èQ×Ï[1ÄøØLuý¼C×Iâ”uý( Ô«úÑNF‚Öõó>± ÅæS×Ï;˜˜];E]?*ÄP¦€ÿY[ =ï{víôuý¼…ƒ3‹sÚº~dáÐȦ‘p°ÒÈzLY“ ^—˜"×®¸X|Ë8»¡é“5ðÞž¶ètiY>,MV.ÙÈ>þŽ»¼c6 ‚ 4#ª€;»í–(Ì‹Äï“ÈjfùåXF UQu7²ò¢œeVckKâõ‘´+å’êë~f8‘—÷º…âÊöÝâ—hdœˆìÖÎ3ÑÛ¯¹µÅæõB%ö6h6–»¯£Õ\³ññ˜ë4^vÞžŽ_C±Ãn³X<¾ßû¸jò£ÃçæëY¯YÏM®ë‰øãc9™øv+};y?M®?’_vÆJ¬_Vq1v‡™·øºžøÒh_%‹É£øÖÇâ{ƒëÄEÙ^;¬<ÔÁZ"B餟\ogw¸·½ÅÕ.®k\}axÌÕOŽ_¥·½ªL^·–ÕåÔq .<¢gZn}T“›…ã;¸%”öÆU¯òŠúr°ÀeNºØ6áž^}_P~é–:®|©í6j›»›m«¤VGp¹ôqNVŸÏ6_/?”Aî8r}|˜D+ ňk<¥W–b7§‹…õ~)vÚ¬,?5÷7³Å¥£\ÒLÛt_]Í7–¾´HÖÔhm5¢ô20óˆ–Åf‹iTbiWO±¾Í· Õ ÝßZ²–fIÛùåµ¥¡­^—>®v2ã• à0Ål+Sª {;àéÑÁÎóåÅñî^îé8Y”6·kÅÅóNùá`a­T(Ý&«a£Kݶê×qxÂOVR±I-¾·¿ÏW¿®m”{r†‡›3¨¶ß>Š^nÞV…ǽNŠËÈ«PÆ/ˆˆUø5˜›Ã7qû2šFÇ5o_XFÆ—‘² ô@lg~®%ÑO@ÌçàçΪ~Êzì¦ÐßââÆÆSí1qwÈ=ÝyÙYoD0ïC|¢)nðd¾XÁ_”c-óE qÉwB1óUõ²ùl¾à°«‹û¯Æ‹ãZ)_oDeóYk\ÿšn£ÈF>^Å_Ö8ø,£‹阃 Kïü^®!ÀŸ‚ÖwëkÌìû,©5iøUøsÕd8‹Uâ{h”³´Ö¨+Ã~Î8tm<ßÞ;A?õnÛ_îxd¦p™ÛZ2sÔ|ÁÛ‹z+$rkcЋ´6 —X,pB¿ ¤X5UL|ÝYç®q”,Sc©ÈÂt[¯:ç=f=’úC–8sÖ#ŸYP7’—ëJnë2{¼›èÄ5jJ|iFþ‚5ß »ïÆŠí^_?Yè%$&7céײ•½M¨ ^kØ-T¾ìóÚWÚ'’þWÿRÐÿšÜ}E¤.Tò£+vT“gX®ìæ(†‘½I•¬dh;»‚I÷;u´h¿2‘OOˆd祥«càÁ»fJÆœ@ËÜëQjÒhrõ,ñTn àÒ½ ßg’Õ«›=Ê{=’Yâ㨼&ªƒ ~æW4Š—£Í,êÚ4únŠG ÖPø¤ù•¢[âàŸü†Æ2Ÿ/×îˆ.Àîu1ÿ/øÔòkRo'ëâzz5" Åô§$¤§ÃU6R_ó]“öAù«½òÓÛn*(ýR?:¨9¹D>´u¤…Êê]’ËÔw’p׎ðø1M7±Û0§e:»œi–¬°¼i*Ä®…‰žóY’†XXíY´¼žaó+[¦·ÖEu¡wêU$Ë‹ÛUÝ®DE›…xñV´d3znm×u5as¸‚+Sk\¬i~BÔ˜ëF¥Œ£ƒ››Ó]­x¯Âf/Žépè@ &´CÕûõUqiýŽøTIA6«i°èP ¯ÒÚ³õQDHZ« Gð×ãØ‚{H“Iú ÂË™Unê+Qëf(ù¢ðÅ­=K~Ù\ÐëÊ"¶Œ«và Gôhñí»0ÑlÝyK‚žÁ÷%{ûÅR’ìE‹Â0Ú…Vuèówá+~2¢•ªÓTQ›æ‚•¢“”yÛ Uk hr‰¯hr:Ž!`᱇¨,‰¦3.¬{3v®Wd¤Ae RØéÐ]ë¹ò¦)þ次v¡Ïû+¾ýËcÚFd6± ÎÛçV°.b‘'£‹MÁê"ÞZ<¿§ìd‚T€Éž³°w‘šr¦-ö”Xui*(ޱ,ƒ£t±)ØÚ¥ès b*ÅØ£9y­rú±qMÈ goLJbô™™¬¡4<×ï^9,;Î÷3+ؤâú©ãî¤ ™º£jde÷~7Jô1MŒ~ªJ®sËOVÉ5__ç“UrKçÿL•ÆÃ¥ü“Ur°/4zŽ*¹Åa>S%Ú8TÊ?Y%û•rÓ“7·lIÓ34%xó6®)ÁÕû]D+Z4Gz@fàç­v-ç2ãx©HÙ@fofý|À‹Ã!³ÛK <€Âè'øçv˜Ö m'ò SSi3§@}™lìgz7ã´vvÞK­%·׫¶ètó Aܾ:>4tgýøâR—ç[ù„ ãÀkò€ö·6“Ø39ºö­2âq¡ôår;Ó¹ÍÖ~†“Z‡ÛZŠñöÕ¨¤7©¯%Ö‹ ˜KAÛ¾~/uáåD׃wÿo+”/¤pA*äÙóI¿«œ(½—Þ œ ­‡2»û<9è kJ·{Ñý߸2lOÞ»ƒqx-œÙm–÷÷ R¥Ûvº 9õ“µ+ºËO÷É4Ý:¬áRª<ëo{ ç›rå™»ÝrºïâÞ&t߇b‘äÖÛF$Öå#©×oMø³¦)mšýæð kÊûP;s+ •®RšT“GëÊá~¤i©öHõ•ú­êGåKM&üîž´«l'_ïJOÇB3¸³?Û«š…†Œ»›rþ¼é=¶åI!ý~¼Ilgá2®à¬‚Y¬2‘Tbg>=ˆ$ϢǑd;} _lGVwÅN$ut³YùXP ¦ Ku“Ôv˜YëúÆ× "=Z$ÐÆý²…lG»½EB/½ï}ÌqñtF³»òc\ÿë[wE§8F/èçZcO3×à±]#«w¬Ä±aTîsVs{ò¸h ±¬8è`±¼i¼(¯b¬éÑ„EÖ @—/»Æ‹Þ|ñU7Ýê›+Ö3|äz9…¹#¾âc×÷ÓPXVÍ=’É ‚¿MÀ‹sýB=~žîX}?¢8ð¬†Dõ `aÝÂ6hf[µQ@¾IÐè$-õàcü¼DÝ®h›“9½MIÀ¿°±€ü`€4·U‹c£ Œÿ VÉÈKk/ƒåËÚF5ûÍ$¾¸n×oÎðcRŒÐ(‚iÊV·ŽN± ‡`Ý>Ômâ pV,Ôk;ËÝ‹Ê~g3¢ÓÕí oaò…€‰žDÿqÁ\rÖ‚Œ#ZëñДÎf[—Z7ßjì'À_@äk²¤õU€IsûØ·–,¢¿ìÇ0$·±ÁLúôg«@:߀À¶5.ú€ÉatYÒÍqM$ ôeœtW%¢Ë%šÈé“BWÁ!U"§«¢×UY“w€ì¡ÜÜ‹k±«¾AuoE'v>šÑ*Òfʰã!í£dF𴜆ÇÄ7¦ûÇ(ä"Õ2ä£EÀ ,haà Ù,w7·€àâñ5ƒŽ×V4Õ7Ž«Ý[;)MÊù¼t~oå\wÝ[êù§(çÙÔs‚r^²¶.øI*:GÕ®yüÄ“T´*tœú™'©¦óöSOR Xý¿­ Nè"z¬:¸{(‹'Íîx2‚ ¤ÇR÷¥7hÈß»JˆkÿÇÿƒÿæ‹a^(„I?$ø´Ñ ÅQÛ0Ÿ7c~Ìì*ãJ¯=î ²ò=¼Ý5.÷+áµ°Öö´]ÇÁl¸GмJ@ŸÔ#˜ácˆ ï‚ÿ¿ùüsâÒ9A”„b˜KK"üþÁ \ü!ˆ¼˜‡Oļ e‹è\6ÏÃ? Y‘φ㧻Ç'ÇÕpV— ´Š›·§/ óü8|þgÃGá».Ü38 ¹<_ ‹à¥œ” ¿‡DžKù¼õ¨¹|:+ÃbGÿ+ä‹ÚWù|šËòaW/åÐ3ø¨˜–²9ðU^­À oŽ×á9Ð^ á,'¦‹°ã,è°¿)Hi tc=°f#䤴À$Û³VFSð̆áPyÔ ¼‚}»çƒf V[³è!ü_8Çš“X„€9Áb y)œåy0˜½&Ççòè\˜¦ã ˜˜o|•ç ¥òÙ4¾Î‚þ ð!WÔŸë)†Û`e…´˜ËŠRQÊ#È ðkØH*Š ÐFëFJgÅ<€"z»FÌçÒ"j‡æ´ox!-D®è‘”CS¶€ŸO‹"k^ÐÖƒ‹Á¼x´|þx@…´PäÑ3>ˆP’¶EÐ-ìD( õfQû-ré<ø"Ëñ›Ê!øö—å8кˆ&ãø[<ì ~“Uˆ¼Ž©Å,\8 ÔP°‡“‚@Ä‚CÁ!¢hC8¡IÔ8¿/¢þÀÆ#R}Á¨þLä{¸¼”¾!àu 9–aÐ3ðC‚ð¹BNÈkÔ›ÎI…‚9A!ßo–ÃýáË0ÜêOº&¥Ã%ò  9mDc=+ä:ºÏD>]¸ùö­Ð °!Û#¸p c¾—%Pæ²Ö`ÚEÀšà“BQ‚lBH£ÅÁdÁ 7Ÿ5ðg`|~ ˆ˜ã ዘY€â|!g=i‡Ä¬.ft°Vb:—åµ9ð|AÀŸÖUÈkß™ÏÕ œ;ø# ñ<ݰ'€å‰íö Ð"W€­Ü$IDà Ù,šg¾˜/ZOàxÿ9{«<˜9zºÌòè Â_ȬÚIJRÞ|ÒÀŸiÀ¾òhq€5çЄ8È8|Ž$ë ʈ€f+Þ¬ ÀIŠ€ŒÛ¸ýY -×x–4&äôi#¸A6%ˆØ!ÍÁÝ£éÀžÐÜÀAÐ1%+äá´s`»à„,q$`ZÈ¢·pLTÁç´¾²Y¸¿è‰˜G EÛ°œ¶Oæ3°À%¬•¹R—·íS0<”Ñ*$‡_  Üúœˆ¹X@Û"B\…s$À‰¼õ¬?3…dBÛl Ö^IYïc­çBô“Ïsö_²ù  ¹(äÂVO&q˜ãa$fUD{bµÒ) d ì)ÏóÚÌ Å‚ÆåÈ#¦£iú³þŒKgóB l[m=àdpw5‰â°­7y.¶õÎ#Y!*™¬±n×EQ^“.N>ù+QWã™ýÁXSÎÂíáûh8tÂê«<ê†ß‡.¦©5JšÂÔG¤Ö­k&v*¿t/¹×êã‹*ÿÕ ËƒÁp,»#ð&ü¢tÕñP邇Ã'à£9PDOj¡ÿIHÈ” endstream endobj 89 0 obj <> endobj xref 0 94 0000000003 65535 f 0000000016 00000 n 0000019955 00000 n 0000000004 00000 f 0000000006 00000 f 0000020779 00000 n 0000000007 00000 f 0000000008 00000 f 0000000009 00000 f 0000000010 00000 f 0000000011 00000 f 0000000012 00000 f 0000000013 00000 f 0000000014 00000 f 0000000015 00000 f 0000000019 00000 f 0000020006 00000 n 0000020638 00000 n 0000020669 00000 n 0000000020 00000 f 0000000021 00000 f 0000000022 00000 f 0000000023 00000 f 0000000024 00000 f 0000000025 00000 f 0000000026 00000 f 0000000027 00000 f 0000000028 00000 f 0000000029 00000 f 0000000030 00000 f 0000000031 00000 f 0000000032 00000 f 0000000033 00000 f 0000000034 00000 f 0000000035 00000 f 0000000036 00000 f 0000000037 00000 f 0000000041 00000 f 0000020077 00000 n 0000020522 00000 n 0000020553 00000 n 0000000042 00000 f 0000000043 00000 f 0000000044 00000 f 0000000045 00000 f 0000000046 00000 f 0000000047 00000 f 0000000048 00000 f 0000000049 00000 f 0000000050 00000 f 0000000051 00000 f 0000000052 00000 f 0000000053 00000 f 0000000054 00000 f 0000000055 00000 f 0000000056 00000 f 0000000057 00000 f 0000000058 00000 f 0000000059 00000 f 0000000063 00001 f 0000020148 00000 n 0000020406 00000 n 0000020437 00000 n 0000000064 00000 f 0000000065 00000 f 0000000066 00000 f 0000000067 00000 f 0000000068 00001 f 0000000069 00000 f 0000000070 00000 f 0000000071 00000 f 0000000080 00000 f 0000023371 00000 n 0000023445 00000 n 0000023685 00000 n 0000024716 00000 n 0000035850 00000 n 0000101438 00000 n 0000167026 00000 n 0000232614 00000 n 0000000000 00001 f 0000020754 00000 n 0000020219 00000 n 0000020290 00000 n 0000020321 00000 n 0000022308 00000 n 0000022421 00000 n 0000022456 00000 n 0000021142 00000 n 0000285780 00000 n 0000022810 00000 n 0000022858 00000 n 0000022054 00000 n 0000000190 00000 n trailer <<879DB089327A454292F4CFF94C60DAE4>]>> startxref 285961 %%EOF bind9-9.10.3.dfsg.P4/doc/arm/man.host.html0000644000470500017500000003041312664710322017333 0ustar lamontlamont host

Name

host — DNS lookup utility

Synopsis

host [-aCdlnrsTwv] [-c class] [-N ndots] [-R number] [-t type] [-W wait] [-m flag] [-4] [-6] [-v] [-V] {name} [server]

DESCRIPTION

host is a simple utility for performing DNS lookups. It is normally used to convert names to IP addresses and vice versa. When no arguments or options are given, host prints a short summary of its command line arguments and options.

name is the domain name that is to be looked up. It can also be a dotted-decimal IPv4 address or a colon-delimited IPv6 address, in which case host will by default perform a reverse lookup for that address. server is an optional argument which is either the name or IP address of the name server that host should query instead of the server or servers listed in /etc/resolv.conf.

The -a (all) option is equivalent to setting the -v option and asking host to make a query of type ANY.

When the -C option is used, host will attempt to display the SOA records for zone name from all the listed authoritative name servers for that zone. The list of name servers is defined by the NS records that are found for the zone.

The -c option instructs to make a DNS query of class class. This can be used to lookup Hesiod or Chaosnet class resource records. The default class is IN (Internet).

Verbose output is generated by host when the -d or -v option is used. The two options are equivalent. They have been provided for backwards compatibility. In previous versions, the -d option switched on debugging traces and -v enabled verbose output.

List mode is selected by the -l option. This makes host perform a zone transfer for zone name. Transfer the zone printing out the NS, PTR and address records (A/AAAA). If combined with -a all records will be printed.

The -i option specifies that reverse lookups of IPv6 addresses should use the IP6.INT domain as defined in RFC1886. The default is to use IP6.ARPA.

The -N option sets the number of dots that have to be in name for it to be considered absolute. The default value is that defined using the ndots statement in /etc/resolv.conf, or 1 if no ndots statement is present. Names with fewer dots are interpreted as relative names and will be searched for in the domains listed in the search or domain directive in /etc/resolv.conf.

The number of UDP retries for a lookup can be changed with the -R option. number indicates how many times host will repeat a query that does not get answered. The default number of retries is 1. If number is negative or zero, the number of retries will default to 1.

Non-recursive queries can be made via the -r option. Setting this option clears the RD — recursion desired — bit in the query which host makes. This should mean that the name server receiving the query will not attempt to resolve name. The -r option enables host to mimic the behavior of a name server by making non-recursive queries and expecting to receive answers to those queries that are usually referrals to other name servers.

By default, host uses UDP when making queries. The -T option makes it use a TCP connection when querying the name server. TCP will be automatically selected for queries that require it, such as zone transfer (AXFR) requests.

The -4 option forces host to only use IPv4 query transport. The -6 option forces host to only use IPv6 query transport.

The -t option is used to select the query type. type can be any recognized query type: CNAME, NS, SOA, SIG, KEY, AXFR, etc. When no query type is specified, host automatically selects an appropriate query type. By default, it looks for A, AAAA, and MX records, but if the -C option was given, queries will be made for SOA records, and if name is a dotted-decimal IPv4 address or colon-delimited IPv6 address, host will query for PTR records. If a query type of IXFR is chosen the starting serial number can be specified by appending an equal followed by the starting serial number (e.g. -t IXFR=12345678).

The time to wait for a reply can be controlled through the -W and -w options. The -W option makes host wait for wait seconds. If wait is less than one, the wait interval is set to one second. When the -w option is used, host will effectively wait forever for a reply. The time to wait for a response will be set to the number of seconds given by the hardware's maximum value for an integer quantity.

The -s option tells host not to send the query to the next nameserver if any server responds with a SERVFAIL response, which is the reverse of normal stub resolver behavior.

The -m can be used to set the memory usage debugging flags record, usage and trace.

The -V option causes host to print the version number and exit.

IDN SUPPORT

If host has been built with IDN (internationalized domain name) support, it can accept and display non-ASCII domain names. host appropriately converts character encoding of domain name before sending a request to DNS server or displaying a reply from the server. If you'd like to turn off the IDN support for some reason, defines the IDN_DISABLE environment variable. The IDN support is disabled if the variable is set when host runs.

FILES

/etc/resolv.conf

SEE ALSO

dig(1), named(8).

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/man.ddns-confgen.html0000644000470500017500000002342512664710322020730 0ustar lamontlamont ddns-confgen

Name

ddns-confgen — ddns key generation tool

Synopsis

tsig-keygen [-a algorithm] [-h] [-r randomfile] [name]

ddns-confgen [-a algorithm] [-h] [-k keyname] [-q] [-r randomfile] [ -s name | -z zone ]

DESCRIPTION

tsig-keygen and ddns-confgen are invocation methods for a utility that generates keys for use in TSIG signing. The resulting keys can be used, for example, to secure dynamic DNS updates to a zone or for the rndc command channel.

When run as tsig-keygen, a domain name can be specified on the command line which will be used as the name of the generated key. If no name is specified, the default is tsig-key.

When run as ddns-confgen, the generated key is accompanied by configuration text and instructions that can be used with nsupdate and named when setting up dynamic DNS, including an example update-policy statement. (This usage similar to the rndc-confgen command for setting up command channel security.)

Note that named itself can configure a local DDNS key for use with nsupdate -l: it does this when a zone is configured with update-policy local;. ddns-confgen is only needed when a more elaborate configuration is required: for instance, if nsupdate is to be used from a remote system.

OPTIONS

-a algorithm

Specifies the algorithm to use for the TSIG key. Available choices are: hmac-md5, hmac-sha1, hmac-sha224, hmac-sha256, hmac-sha384 and hmac-sha512. The default is hmac-sha256. Options are case-insensitive, and the "hmac-" prefix may be omitted.

-h

Prints a short summary of options and arguments.

-k keyname

Specifies the key name of the DDNS authentication key. The default is ddns-key when neither the -s nor -z option is specified; otherwise, the default is ddns-key as a separate label followed by the argument of the option, e.g., ddns-key.example.com. The key name must have the format of a valid domain name, consisting of letters, digits, hyphens and periods.

-q

(ddns-confgen only.) Quiet mode: Print only the key, with no explanatory text or usage examples; This is essentially identical to tsig-keygen.

-r randomfile

Specifies a source of random data for generating the authorization. If the operating system does not provide a /dev/random or equivalent device, the default source of randomness is keyboard input. randomdev specifies the name of a character device or file containing random data to be used instead of the default. The special value keyboard indicates that keyboard input should be used.

-s name

(ddns-confgen only.) Generate configuration example to allow dynamic updates of a single hostname. The example named.conf text shows how to set an update policy for the specified name using the "name" nametype. The default key name is ddns-key.name. Note that the "self" nametype cannot be used, since the name to be updated may differ from the key name. This option cannot be used with the -z option.

-z zone

(ddns-confgen only.) Generate configuration example to allow dynamic updates of a zone: The example named.conf text shows how to set an update policy for the specified zone using the "zonesub" nametype, allowing updates to all subdomain names within that zone. This option cannot be used with the -s option.

SEE ALSO

nsupdate(1), named.conf(5), named(8), BIND 9 Administrator Reference Manual.

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/man.named-rrchecker.html0000644000470500017500000001100012664710322021377 0ustar lamontlamont named-rrchecker

Name

named-rrchecker — A syntax checker for individual DNS resource records

Synopsis

named-rrchecker [-h] [-o origin] [-p] [-u] [-C] [-T] [-P]

DESCRIPTION

named-rrchecker read a individual DNS resource record from standard input and checks if it is syntactically correct.

The -h prints out the help menu.

The -o origin option specifies a origin to be used when interpreting the record.

The -p prints out the resulting record in canonical form. If there is no canonical form defined then the record will be printed in unknown record format.

The -u prints out the resulting record in unknown record form.

The -C, -T and -P print out the known class, standard type and private type mnemonics respectively.

SEE ALSO

RFC 1034, RFC 1035, named(8)

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/Bv9ARM-book.xml0000644000470500017500000224527212664710322017405 0ustar lamontlamont]> BIND 9 Administrator Reference Manual 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 Internet Systems Consortium, Inc. ("ISC") 2000 2001 2002 2003 Internet Software Consortium. Introduction The Internet Domain Name System (DNS) consists of the syntax to specify the names of entities in the Internet in a hierarchical manner, the rules used for delegating authority over names, and the system implementation that actually maps names to Internet addresses. DNS data is maintained in a group of distributed hierarchical databases. Scope of Document The Berkeley Internet Name Domain (BIND) implements a domain name server for a number of operating systems. This document provides basic information about the installation and care of the Internet Systems Consortium (ISC) BIND version 9 software package for system administrators. Organization of This Document In this document, Chapter 1 introduces the basic DNS and BIND concepts. Chapter 2 describes resource requirements for running BIND in various environments. Information in Chapter 3 is task-oriented in its presentation and is organized functionally, to aid in the process of installing the BIND 9 software. The task-oriented section is followed by Chapter 4, which contains more advanced concepts that the system administrator may need for implementing certain options. Chapter 5 describes the BIND 9 lightweight resolver. The contents of Chapter 6 are organized as in a reference manual to aid in the ongoing maintenance of the software. Chapter 7 addresses security considerations, and Chapter 8 contains troubleshooting help. The main body of the document is followed by several appendices which contain useful reference information, such as a bibliography and historic information related to BIND and the Domain Name System. Conventions Used in This Document In this document, we use the following general typographic conventions: To describe: We use the style: a pathname, filename, URL, hostname, mailing list name, or new term or concept Fixed width literal user input Fixed Width Bold program output Fixed Width The following conventions are used in descriptions of the BIND configuration file: To describe: We use the style: keywords Fixed Width variables Fixed Width Optional input Text is enclosed in square brackets The Domain Name System (<acronym>DNS</acronym>) The purpose of this document is to explain the installation and upkeep of the BIND (Berkeley Internet Name Domain) software package, and we begin by reviewing the fundamentals of the Domain Name System (DNS) as they relate to BIND. DNS Fundamentals The Domain Name System (DNS) is a hierarchical, distributed database. It stores information for mapping Internet host names to IP addresses and vice versa, mail routing information, and other data used by Internet applications. Clients look up information in the DNS by calling a resolver library, which sends queries to one or more name servers and interprets the responses. The BIND 9 software distribution contains a name server, named, and a resolver library, liblwres. The older libbind resolver library is also available from ISC as a separate download. Domains and Domain Names The data stored in the DNS is identified by domain names that are organized as a tree according to organizational or administrative boundaries. Each node of the tree, called a domain, is given a label. The domain name of the node is the concatenation of all the labels on the path from the node to the root node. This is represented in written form as a string of labels listed from right to left and separated by dots. A label need only be unique within its parent domain. For example, a domain name for a host at the company Example, Inc. could be ourhost.example.com, where com is the top level domain to which ourhost.example.com belongs, example is a subdomain of com, and ourhost is the name of the host. For administrative purposes, the name space is partitioned into areas called zones, each starting at a node and extending down to the leaf nodes or to nodes where other zones start. The data for each zone is stored in a name server, which answers queries about the zone using the DNS protocol. The data associated with each domain name is stored in the form of resource records (RRs). Some of the supported resource record types are described in . For more detailed information about the design of the DNS and the DNS protocol, please refer to the standards documents listed in . Zones To properly operate a name server, it is important to understand the difference between a zone and a domain. As stated previously, a zone is a point of delegation in the DNS tree. A zone consists of those contiguous parts of the domain tree for which a name server has complete information and over which it has authority. It contains all domain names from a certain point downward in the domain tree except those which are delegated to other zones. A delegation point is marked by one or more NS records in the parent zone, which should be matched by equivalent NS records at the root of the delegated zone. For instance, consider the example.com domain which includes names such as host.aaa.example.com and host.bbb.example.com even though the example.com zone includes only delegations for the aaa.example.com and bbb.example.com zones. A zone can map exactly to a single domain, but could also include only part of a domain, the rest of which could be delegated to other name servers. Every name in the DNS tree is a domain, even if it is terminal, that is, has no subdomains. Every subdomain is a domain and every domain except the root is also a subdomain. The terminology is not intuitive and we suggest that you read RFCs 1033, 1034 and 1035 to gain a complete understanding of this difficult and subtle topic. Though BIND is called a "domain name server", it deals primarily in terms of zones. The master and slave declarations in the named.conf file specify zones, not domains. When you ask some other site if it is willing to be a slave server for your domain, you are actually asking for slave service for some collection of zones. Authoritative Name Servers Each zone is served by at least one authoritative name server, which contains the complete data for the zone. To make the DNS tolerant of server and network failures, most zones have two or more authoritative servers, on different networks. Responses from authoritative servers have the "authoritative answer" (AA) bit set in the response packets. This makes them easy to identify when debugging DNS configurations using tools like dig (). The Primary Master The authoritative server where the master copy of the zone data is maintained is called the primary master server, or simply the primary. Typically it loads the zone contents from some local file edited by humans or perhaps generated mechanically from some other local file which is edited by humans. This file is called the zone file or master file. In some cases, however, the master file may not be edited by humans at all, but may instead be the result of dynamic update operations. Slave Servers The other authoritative servers, the slave servers (also known as secondary servers) load the zone contents from another server using a replication process known as a zone transfer. Typically the data are transferred directly from the primary master, but it is also possible to transfer it from another slave. In other words, a slave server may itself act as a master to a subordinate slave server. Stealth Servers Usually all of the zone's authoritative servers are listed in NS records in the parent zone. These NS records constitute a delegation of the zone from the parent. The authoritative servers are also listed in the zone file itself, at the top level or apex of the zone. You can list servers in the zone's top-level NS records that are not in the parent's NS delegation, but you cannot list servers in the parent's delegation that are not present at the zone's top level. A stealth server is a server that is authoritative for a zone but is not listed in that zone's NS records. Stealth servers can be used for keeping a local copy of a zone to speed up access to the zone's records or to make sure that the zone is available even if all the "official" servers for the zone are inaccessible. A configuration where the primary master server itself is a stealth server is often referred to as a "hidden primary" configuration. One use for this configuration is when the primary master is behind a firewall and therefore unable to communicate directly with the outside world. Caching Name Servers The resolver libraries provided by most operating systems are stub resolvers, meaning that they are not capable of performing the full DNS resolution process by themselves by talking directly to the authoritative servers. Instead, they rely on a local name server to perform the resolution on their behalf. Such a server is called a recursive name server; it performs recursive lookups for local clients. To improve performance, recursive servers cache the results of the lookups they perform. Since the processes of recursion and caching are intimately connected, the terms recursive server and caching server are often used synonymously. The length of time for which a record may be retained in the cache of a caching name server is controlled by the Time To Live (TTL) field associated with each resource record. Forwarding Even a caching name server does not necessarily perform the complete recursive lookup itself. Instead, it can forward some or all of the queries that it cannot satisfy from its cache to another caching name server, commonly referred to as a forwarder. There may be one or more forwarders, and they are queried in turn until the list is exhausted or an answer is found. Forwarders are typically used when you do not wish all the servers at a given site to interact directly with the rest of the Internet servers. A typical scenario would involve a number of internal DNS servers and an Internet firewall. Servers unable to pass packets through the firewall would forward to the server that can do it, and that server would query the Internet DNS servers on the internal server's behalf. Name Servers in Multiple Roles The BIND name server can simultaneously act as a master for some zones, a slave for other zones, and as a caching (recursive) server for a set of local clients. However, since the functions of authoritative name service and caching/recursive name service are logically separate, it is often advantageous to run them on separate server machines. A server that only provides authoritative name service (an authoritative-only server) can run with recursion disabled, improving reliability and security. A server that is not authoritative for any zones and only provides recursive service to local clients (a caching-only server) does not need to be reachable from the Internet at large and can be placed inside a firewall. <acronym>BIND</acronym> Resource Requirements Hardware requirements DNS hardware requirements have traditionally been quite modest. For many installations, servers that have been pensioned off from active duty have performed admirably as DNS servers. The DNSSEC features of BIND 9 may prove to be quite CPU intensive however, so organizations that make heavy use of these features may wish to consider larger systems for these applications. BIND 9 is fully multithreaded, allowing full utilization of multiprocessor systems for installations that need it. CPU Requirements CPU requirements for BIND 9 range from i486-class machines for serving of static zones without caching, to enterprise-class machines if you intend to process many dynamic updates and DNSSEC signed zones, serving many thousands of queries per second. Memory Requirements The memory of the server has to be large enough to fit the cache and zones loaded off disk. The max-cache-size option can be used to limit the amount of memory used by the cache, at the expense of reducing cache hit rates and causing more DNS traffic. Additionally, if additional section caching () is enabled, the max-acache-size option can be used to limit the amount of memory used by the mechanism. It is still good practice to have enough memory to load all zone and cache data into memory — unfortunately, the best way to determine this for a given installation is to watch the name server in operation. After a few weeks the server process should reach a relatively stable size where entries are expiring from the cache as fast as they are being inserted. Name Server Intensive Environment Issues For name server intensive environments, there are two alternative configurations that may be used. The first is where clients and any second-level internal name servers query a main name server, which has enough memory to build a large cache. This approach minimizes the bandwidth used by external name lookups. The second alternative is to set up second-level internal name servers to make queries independently. In this configuration, none of the individual machines needs to have as much memory or CPU power as in the first alternative, but this has the disadvantage of making many more external queries, as none of the name servers share their cached data. Supported Operating Systems ISC BIND 9 compiles and runs on a large number of Unix-like operating systems and on Microsoft Windows Server 2003 and 2008, and Windows XP and Vista. For an up-to-date list of supported systems, see the README file in the top level directory of the BIND 9 source distribution. Name Server Configuration In this chapter we provide some suggested configurations along with guidelines for their use. We suggest reasonable values for certain option settings. Sample Configurations A Caching-only Name Server The following sample configuration is appropriate for a caching-only name server for use by clients internal to a corporation. All queries from outside clients are refused using the allow-query option. Alternatively, the same effect could be achieved using suitable firewall rules. // Two corporate subnets we wish to allow queries from. acl corpnets { 192.168.4.0/24; 192.168.7.0/24; }; options { // Working directory directory "/etc/namedb"; allow-query { corpnets; }; }; // Provide a reverse mapping for the loopback // address 127.0.0.1 zone "0.0.127.in-addr.arpa" { type master; file "localhost.rev"; notify no; }; An Authoritative-only Name Server This sample configuration is for an authoritative-only server that is the master server for "example.com" and a slave for the subdomain "eng.example.com". options { // Working directory directory "/etc/namedb"; // Do not allow access to cache allow-query-cache { none; }; // This is the default allow-query { any; }; // Do not provide recursive service recursion no; }; // Provide a reverse mapping for the loopback // address 127.0.0.1 zone "0.0.127.in-addr.arpa" { type master; file "localhost.rev"; notify no; }; // We are the master server for example.com zone "example.com" { type master; file "example.com.db"; // IP addresses of slave servers allowed to // transfer example.com allow-transfer { 192.168.4.14; 192.168.5.53; }; }; // We are a slave server for eng.example.com zone "eng.example.com" { type slave; file "eng.example.com.bk"; // IP address of eng.example.com master server masters { 192.168.4.12; }; }; Load Balancing A primitive form of load balancing can be achieved in the DNS by using multiple records (such as multiple A records) for one name. For example, if you have three WWW servers with network addresses of 10.0.0.1, 10.0.0.2 and 10.0.0.3, a set of records such as the following means that clients will connect to each machine one third of the time: Name TTL CLASS TYPE Resource Record (RR) Data www 600 IN A 10.0.0.1 600 IN A 10.0.0.2 600 IN A 10.0.0.3 When a resolver queries for these records, BIND will rotate them and respond to the query with the records in a different order. In the example above, clients will randomly receive records in the order 1, 2, 3; 2, 3, 1; and 3, 1, 2. Most clients will use the first record returned and discard the rest. For more detail on ordering responses, check the rrset-order sub-statement in the options statement, see . Name Server Operations Tools for Use With the Name Server Daemon This section describes several indispensable diagnostic, administrative and monitoring tools available to the system administrator for controlling and debugging the name server daemon. Diagnostic Tools The dig, host, and nslookup programs are all command line tools for manually querying name servers. They differ in style and output format. dig The domain information groper (dig) is the most versatile and complete of these lookup tools. It has two modes: simple interactive mode for a single query, and batch mode which executes a query for each in a list of several query lines. All query options are accessible from the command line. dig @server domain query-type query-class +query-option -dig-option %comment The usual simple use of dig will take the form dig @server domain query-type query-class For more information and a list of available commands and options, see the dig man page. host The host utility emphasizes simplicity and ease of use. By default, it converts between host names and Internet addresses, but its functionality can be extended with the use of options. host -aCdlnrsTwv -c class -N ndots -t type -W timeout -R retries -m flag -4 -6 hostname server For more information and a list of available commands and options, see the host man page. nslookup nslookup has two modes: interactive and non-interactive. Interactive mode allows the user to query name servers for information about various hosts and domains or to print a list of hosts in a domain. Non-interactive mode is used to print just the name and requested information for a host or domain. nslookup -option host-to-find - server Interactive mode is entered when no arguments are given (the default name server will be used) or when the first argument is a hyphen (`-') and the second argument is the host name or Internet address of a name server. Non-interactive mode is used when the name or Internet address of the host to be looked up is given as the first argument. The optional second argument specifies the host name or address of a name server. Due to its arcane user interface and frequently inconsistent behavior, we do not recommend the use of nslookup. Use dig instead. Administrative Tools Administrative tools play an integral part in the management of a server. named-checkconf The named-checkconf program checks the syntax of a named.conf file. named-checkconf -jvz -t directory filename named-checkzone The named-checkzone program checks a master file for syntax and consistency. named-checkzone -djqvD -c class -o output -t directory -w directory -k (ignore|warn|fail) -n (ignore|warn|fail) -W (ignore|warn) zone filename named-compilezone Similar to named-checkzone, but it always dumps the zone content to a specified file (typically in a different format). rndc The remote name daemon control (rndc) program allows the system administrator to control the operation of a name server. Since BIND 9.2, rndc supports all the commands of the BIND 8 ndc utility except ndc start and ndc restart, which were also not supported in ndc's channel mode. If you run rndc without any options it will display a usage message as follows: rndc -c config -s server -p port -y key command command See for details of the available rndc commands. rndc requires a configuration file, since all communication with the server is authenticated with digital signatures that rely on a shared secret, and there is no way to provide that secret other than with a configuration file. The default location for the rndc configuration file is /etc/rndc.conf, but an alternate location can be specified with the option. If the configuration file is not found, rndc will also look in /etc/rndc.key (or whatever sysconfdir was defined when the BIND build was configured). The rndc.key file is generated by running rndc-confgen -a as described in . The format of the configuration file is similar to that of named.conf, but limited to only four statements, the options, key, server and include statements. These statements are what associate the secret keys to the servers with which they are meant to be shared. The order of statements is not significant. The options statement has three clauses: default-server, default-key, and default-port. default-server takes a host name or address argument and represents the server that will be contacted if no option is provided on the command line. default-key takes the name of a key as its argument, as defined by a key statement. default-port specifies the port to which rndc should connect if no port is given on the command line or in a server statement. The key statement defines a key to be used by rndc when authenticating with named. Its syntax is identical to the key statement in named.conf. The keyword key is followed by a key name, which must be a valid domain name, though it need not actually be hierarchical; thus, a string like "rndc_key" is a valid name. The key statement has two clauses: algorithm and secret. While the configuration parser will accept any string as the argument to algorithm, currently only the strings "hmac-md5", "hmac-sha1", "hmac-sha224", "hmac-sha256", "hmac-sha384" and "hmac-sha512" have any meaning. The secret is a base-64 encoded string as specified in RFC 3548. The server statement associates a key defined using the key statement with a server. The keyword server is followed by a host name or address. The server statement has two clauses: key and port. The key clause specifies the name of the key to be used when communicating with this server, and the port clause can be used to specify the port rndc should connect to on the server. A sample minimal configuration file is as follows: key rndc_key { algorithm "hmac-sha256"; secret "c3Ryb25nIGVub3VnaCBmb3IgYSBtYW4gYnV0IG1hZGUgZm9yIGEgd29tYW4K"; }; options { default-server 127.0.0.1; default-key rndc_key; }; This file, if installed as /etc/rndc.conf, would allow the command: $ rndc reload to connect to 127.0.0.1 port 953 and cause the name server to reload, if a name server on the local machine were running with following controls statements: controls { inet 127.0.0.1 allow { localhost; } keys { rndc_key; }; }; and it had an identical key statement for rndc_key. Running the rndc-confgen program will conveniently create a rndc.conf file for you, and also display the corresponding controls statement that you need to add to named.conf. Alternatively, you can run rndc-confgen -a to set up a rndc.key file and not modify named.conf at all. Signals Certain UNIX signals cause the name server to take specific actions, as described in the following table. These signals can be sent using the kill command. SIGHUP Causes the server to read named.conf and reload the database. SIGTERM Causes the server to clean up and exit. SIGINT Causes the server to clean up and exit. Advanced DNS Features Notify DNS NOTIFY is a mechanism that allows master servers to notify their slave servers of changes to a zone's data. In response to a NOTIFY from a master server, the slave will check to see that its version of the zone is the current version and, if not, initiate a zone transfer. For more information about DNS NOTIFY, see the description of the notify option in and the description of the zone option also-notify in . The NOTIFY protocol is specified in RFC 1996. As a slave zone can also be a master to other slaves, named, by default, sends NOTIFY messages for every zone it loads. Specifying notify master-only; will cause named to only send NOTIFY for master zones that it loads. Dynamic Update Dynamic Update is a method for adding, replacing or deleting records in a master server by sending it a special form of DNS messages. The format and meaning of these messages is specified in RFC 2136. Dynamic update is enabled by including an allow-update or an update-policy clause in the zone statement. If the zone's update-policy is set to local, updates to the zone will be permitted for the key local-ddns, which will be generated by named at startup. See for more details. Dynamic updates using Kerberos signed requests can be made using the TKEY/GSS protocol by setting either the tkey-gssapi-keytab option, or alternatively by setting both the tkey-gssapi-credential and tkey-domain options. Once enabled, Kerberos signed requests will be matched against the update policies for the zone, using the Kerberos principal as the signer for the request. Updating of secure zones (zones using DNSSEC) follows RFC 3007: RRSIG, NSEC and NSEC3 records affected by updates are automatically regenerated by the server using an online zone key. Update authorization is based on transaction signatures and an explicit server policy. The journal file All changes made to a zone using dynamic update are stored in the zone's journal file. This file is automatically created by the server when the first dynamic update takes place. The name of the journal file is formed by appending the extension .jnl to the name of the corresponding zone file unless specifically overridden. The journal file is in a binary format and should not be edited manually. The server will also occasionally write ("dump") the complete contents of the updated zone to its zone file. This is not done immediately after each dynamic update, because that would be too slow when a large zone is updated frequently. Instead, the dump is delayed by up to 15 minutes, allowing additional updates to take place. During the dump process, transient files will be created with the extensions .jnw and .jbk; under ordinary circumstances, these will be removed when the dump is complete, and can be safely ignored. When a server is restarted after a shutdown or crash, it will replay the journal file to incorporate into the zone any updates that took place after the last zone dump. Changes that result from incoming incremental zone transfers are also journalled in a similar way. The zone files of dynamic zones cannot normally be edited by hand because they are not guaranteed to contain the most recent dynamic changes — those are only in the journal file. The only way to ensure that the zone file of a dynamic zone is up to date is to run rndc stop. If you have to make changes to a dynamic zone manually, the following procedure will work: Disable dynamic updates to the zone using rndc freeze zone. This will update the zone's master file with the changes stored in its .jnl file. Edit the zone file. Run rndc thaw zone to reload the changed zone and re-enable dynamic updates. rndc sync zone will update the zone file with changes from the journal file without stopping dynamic updates; this may be useful for viewing the current zone state. To remove the .jnl file after updating the zone file, use rndc sync -clean. Incremental Zone Transfers (IXFR) The incremental zone transfer (IXFR) protocol is a way for slave servers to transfer only changed data, instead of having to transfer the entire zone. The IXFR protocol is specified in RFC 1995. See . When acting as a master, BIND 9 supports IXFR for those zones where the necessary change history information is available. These include master zones maintained by dynamic update and slave zones whose data was obtained by IXFR. For manually maintained master zones, and for slave zones obtained by performing a full zone transfer (AXFR), IXFR is supported only if the option ixfr-from-differences is set to yes. When acting as a slave, BIND 9 will attempt to use IXFR unless it is explicitly disabled. For more information about disabling IXFR, see the description of the request-ixfr clause of the server statement. Split DNS Setting up different views, or visibility, of the DNS space to internal and external resolvers is usually referred to as a Split DNS setup. There are several reasons an organization would want to set up its DNS this way. One common reason for setting up a DNS system this way is to hide "internal" DNS information from "external" clients on the Internet. There is some debate as to whether or not this is actually useful. Internal DNS information leaks out in many ways (via email headers, for example) and most savvy "attackers" can find the information they need using other means. However, since listing addresses of internal servers that external clients cannot possibly reach can result in connection delays and other annoyances, an organization may choose to use a Split DNS to present a consistent view of itself to the outside world. Another common reason for setting up a Split DNS system is to allow internal networks that are behind filters or in RFC 1918 space (reserved IP space, as documented in RFC 1918) to resolve DNS on the Internet. Split DNS can also be used to allow mail from outside back in to the internal network. Example split DNS setup Let's say a company named Example, Inc. (example.com) has several corporate sites that have an internal network with reserved Internet Protocol (IP) space and an external demilitarized zone (DMZ), or "outside" section of a network, that is available to the public. Example, Inc. wants its internal clients to be able to resolve external hostnames and to exchange mail with people on the outside. The company also wants its internal resolvers to have access to certain internal-only zones that are not available at all outside of the internal network. In order to accomplish this, the company will set up two sets of name servers. One set will be on the inside network (in the reserved IP space) and the other set will be on bastion hosts, which are "proxy" hosts that can talk to both sides of its network, in the DMZ. The internal servers will be configured to forward all queries, except queries for site1.internal, site2.internal, site1.example.com, and site2.example.com, to the servers in the DMZ. These internal servers will have complete sets of information for site1.example.com, site2.example.com, site1.internal, and site2.internal. To protect the site1.internal and site2.internal domains, the internal name servers must be configured to disallow all queries to these domains from any external hosts, including the bastion hosts. The external servers, which are on the bastion hosts, will be configured to serve the "public" version of the site1 and site2.example.com zones. This could include things such as the host records for public servers (www.example.com and ftp.example.com), and mail exchange (MX) records (a.mx.example.com and b.mx.example.com). In addition, the public site1 and site2.example.com zones should have special MX records that contain wildcard (`*') records pointing to the bastion hosts. This is needed because external mail servers do not have any other way of looking up how to deliver mail to those internal hosts. With the wildcard records, the mail will be delivered to the bastion host, which can then forward it on to internal hosts. Here's an example of a wildcard MX record: * IN MX 10 external1.example.com. Now that they accept mail on behalf of anything in the internal network, the bastion hosts will need to know how to deliver mail to internal hosts. In order for this to work properly, the resolvers on the bastion hosts will need to be configured to point to the internal name servers for DNS resolution. Queries for internal hostnames will be answered by the internal servers, and queries for external hostnames will be forwarded back out to the DNS servers on the bastion hosts. In order for all this to work properly, internal clients will need to be configured to query only the internal name servers for DNS queries. This could also be enforced via selective filtering on the network. If everything has been set properly, Example, Inc.'s internal clients will now be able to: Look up any hostnames in the site1 and site2.example.com zones. Look up any hostnames in the site1.internal and site2.internal domains. Look up any hostnames on the Internet. Exchange mail with both internal and external people. Hosts on the Internet will be able to: Look up any hostnames in the site1 and site2.example.com zones. Exchange mail with anyone in the site1 and site2.example.com zones. Here is an example configuration for the setup we just described above. Note that this is only configuration information; for information on how to configure your zone files, see . Internal DNS server config: acl internals { 172.16.72.0/24; 192.168.1.0/24; }; acl externals { bastion-ips-go-here; }; options { ... ... forward only; // forward to external servers forwarders { bastion-ips-go-here; }; // sample allow-transfer (no one) allow-transfer { none; }; // restrict query access allow-query { internals; externals; }; // restrict recursion allow-recursion { internals; }; ... ... }; // sample master zone zone "site1.example.com" { type master; file "m/site1.example.com"; // do normal iterative resolution (do not forward) forwarders { }; allow-query { internals; externals; }; allow-transfer { internals; }; }; // sample slave zone zone "site2.example.com" { type slave; file "s/site2.example.com"; masters { 172.16.72.3; }; forwarders { }; allow-query { internals; externals; }; allow-transfer { internals; }; }; zone "site1.internal" { type master; file "m/site1.internal"; forwarders { }; allow-query { internals; }; allow-transfer { internals; } }; zone "site2.internal" { type slave; file "s/site2.internal"; masters { 172.16.72.3; }; forwarders { }; allow-query { internals }; allow-transfer { internals; } }; External (bastion host) DNS server config: acl internals { 172.16.72.0/24; 192.168.1.0/24; }; acl externals { bastion-ips-go-here; }; options { ... ... // sample allow-transfer (no one) allow-transfer { none; }; // default query access allow-query { any; }; // restrict cache access allow-query-cache { internals; externals; }; // restrict recursion allow-recursion { internals; externals; }; ... ... }; // sample slave zone zone "site1.example.com" { type master; file "m/site1.foo.com"; allow-transfer { internals; externals; }; }; zone "site2.example.com" { type slave; file "s/site2.foo.com"; masters { another_bastion_host_maybe; }; allow-transfer { internals; externals; } }; In the resolv.conf (or equivalent) on the bastion host(s): search ... nameserver 172.16.72.2 nameserver 172.16.72.3 nameserver 172.16.72.4 TSIG This is a short guide to setting up Transaction SIGnatures (TSIG) based transaction security in BIND. It describes changes to the configuration file as well as what changes are required for different features, including the process of creating transaction keys and using transaction signatures with BIND. BIND primarily supports TSIG for server to server communication. This includes zone transfer, notify, and recursive query messages. Resolvers based on newer versions of BIND 8 have limited support for TSIG. TSIG can also be useful for dynamic update. A primary server for a dynamic zone should control access to the dynamic update service, but IP-based access control is insufficient. The cryptographic access control provided by TSIG is far superior. The nsupdate program supports TSIG via the and command line options or inline by use of the key. Generate Shared Keys for Each Pair of Hosts A shared secret is generated to be shared between host1 and host2. An arbitrary key name is chosen: "host1-host2.". The key name must be the same on both hosts. Automatic Generation The following command will generate a 128-bit (16 byte) HMAC-SHA256 key as described above. Longer keys are better, but shorter keys are easier to read. Note that the maximum key length is the digest length, here 256 bits. dnssec-keygen -a hmac-sha256 -b 128 -n HOST host1-host2. The key is in the file Khost1-host2.+163+00000.private. Nothing directly uses this file, but the base-64 encoded string following "Key:" can be extracted from the file and used as a shared secret: Key: La/E5CjG9O+os1jq0a2jdA== The string "La/E5CjG9O+os1jq0a2jdA==" can be used as the shared secret. Manual Generation The shared secret is simply a random sequence of bits, encoded in base-64. Most ASCII strings are valid base-64 strings (assuming the length is a multiple of 4 and only valid characters are used), so the shared secret can be manually generated. Also, a known string can be run through mmencode or a similar program to generate base-64 encoded data. Copying the Shared Secret to Both Machines This is beyond the scope of DNS. A secure transport mechanism should be used. This could be secure FTP, ssh, telephone, etc. Informing the Servers of the Key's Existence Imagine host1 and host 2 are both servers. The following is added to each server's named.conf file: key host1-host2. { algorithm hmac-sha256; secret "La/E5CjG9O+os1jq0a2jdA=="; }; The secret is the one generated above. Since this is a secret, it is recommended that either named.conf be non-world readable, or the key directive be added to a non-world readable file that is included by named.conf. At this point, the key is recognized. This means that if the server receives a message signed by this key, it can verify the signature. If the signature is successfully verified, the response is signed by the same key. Instructing the Server to Use the Key Since keys are shared between two hosts only, the server must be told when keys are to be used. The following is added to the named.conf file for host1, if the IP address of host2 is 10.1.2.3: server 10.1.2.3 { keys { host1-host2. ;}; }; Multiple keys may be present, but only the first is used. This directive does not contain any secrets, so it may be in a world-readable file. If host1 sends a message that is a request to that address, the message will be signed with the specified key. host1 will expect any responses to signed messages to be signed with the same key. A similar statement must be present in host2's configuration file (with host1's address) for host2 to sign request messages to host1. TSIG Key Based Access Control BIND allows IP addresses and ranges to be specified in ACL definitions and allow-{ query | transfer | update } directives. This has been extended to allow TSIG keys also. The above key would be denoted key host1-host2. An example of an allow-update directive would be: allow-update { key host1-host2. ;}; This allows dynamic updates to succeed only if the request was signed by a key named "host1-host2.". See for a discussion of the more flexible update-policy statement. Errors The processing of TSIG signed messages can result in several errors. If a signed message is sent to a non-TSIG aware server, a FORMERR (format error) will be returned, since the server will not understand the record. This is a result of misconfiguration, since the server must be explicitly configured to send a TSIG signed message to a specific server. If a TSIG aware server receives a message signed by an unknown key, the response will be unsigned with the TSIG extended error code set to BADKEY. If a TSIG aware server receives a message with a signature that does not validate, the response will be unsigned with the TSIG extended error code set to BADSIG. If a TSIG aware server receives a message with a time outside of the allowed range, the response will be signed with the TSIG extended error code set to BADTIME, and the time values will be adjusted so that the response can be successfully verified. In any of these cases, the message's rcode (response code) is set to NOTAUTH (not authenticated). TKEY TKEY is a mechanism for automatically generating a shared secret between two hosts. There are several "modes" of TKEY that specify how the key is generated or assigned. BIND 9 implements only one of these modes, the Diffie-Hellman key exchange. Both hosts are required to have a Diffie-Hellman KEY record (although this record is not required to be present in a zone). The TKEY process must use signed messages, signed either by TSIG or SIG(0). The result of TKEY is a shared secret that can be used to sign messages with TSIG. TKEY can also be used to delete shared secrets that it had previously generated. The TKEY process is initiated by a client or server by sending a signed TKEY query (including any appropriate KEYs) to a TKEY-aware server. The server response, if it indicates success, will contain a TKEY record and any appropriate keys. After this exchange, both participants have enough information to determine the shared secret; the exact process depends on the TKEY mode. When using the Diffie-Hellman TKEY mode, Diffie-Hellman keys are exchanged, and the shared secret is derived by both participants. SIG(0) BIND 9 partially supports DNSSEC SIG(0) transaction signatures as specified in RFC 2535 and RFC 2931. SIG(0) uses public/private keys to authenticate messages. Access control is performed in the same manner as TSIG keys; privileges can be granted or denied based on the key name. When a SIG(0) signed message is received, it will only be verified if the key is known and trusted by the server; the server will not attempt to locate and/or validate the key. SIG(0) signing of multiple-message TCP streams is not supported. The only tool shipped with BIND 9 that generates SIG(0) signed messages is nsupdate. DNSSEC Cryptographic authentication of DNS information is possible through the DNS Security (DNSSEC-bis) extensions, defined in RFC 4033, RFC 4034, and RFC 4035. This section describes the creation and use of DNSSEC signed zones. In order to set up a DNSSEC secure zone, there are a series of steps which must be followed. BIND 9 ships with several tools that are used in this process, which are explained in more detail below. In all cases, the option prints a full list of parameters. Note that the DNSSEC tools require the keyset files to be in the working directory or the directory specified by the option, and that the tools shipped with BIND 9.2.x and earlier are not compatible with the current ones. There must also be communication with the administrators of the parent and/or child zone to transmit keys. A zone's security status must be indicated by the parent zone for a DNSSEC capable resolver to trust its data. This is done through the presence or absence of a DS record at the delegation point. For other servers to trust data in this zone, they must either be statically configured with this zone's zone key or the zone key of another zone above this one in the DNS tree. Generating Keys The dnssec-keygen program is used to generate keys. A secure zone must contain one or more zone keys. The zone keys will sign all other records in the zone, as well as the zone keys of any secure delegated zones. Zone keys must have the same name as the zone, a name type of ZONE, and must be usable for authentication. It is recommended that zone keys use a cryptographic algorithm designated as "mandatory to implement" by the IETF; currently the only one is RSASHA1. The following command will generate a 768-bit RSASHA1 key for the child.example zone: dnssec-keygen -a RSASHA1 -b 768 -n ZONE child.example. Two output files will be produced: Kchild.example.+005+12345.key and Kchild.example.+005+12345.private (where 12345 is an example of a key tag). The key filenames contain the key name (child.example.), algorithm (3 is DSA, 1 is RSAMD5, 5 is RSASHA1, etc.), and the key tag (12345 in this case). The private key (in the .private file) is used to generate signatures, and the public key (in the .key file) is used for signature verification. To generate another key with the same properties (but with a different key tag), repeat the above command. The dnssec-keyfromlabel program is used to get a key pair from a crypto hardware and build the key files. Its usage is similar to dnssec-keygen. The public keys should be inserted into the zone file by including the .key files using $INCLUDE statements. Signing the Zone The dnssec-signzone program is used to sign a zone. Any keyset files corresponding to secure subzones should be present. The zone signer will generate NSEC, NSEC3 and RRSIG records for the zone, as well as DS for the child zones if '-g' is specified. If '-g' is not specified, then DS RRsets for the secure child zones need to be added manually. The following command signs the zone, assuming it is in a file called zone.child.example. By default, all zone keys which have an available private key are used to generate signatures. dnssec-signzone -o child.example zone.child.example One output file is produced: zone.child.example.signed. This file should be referenced by named.conf as the input file for the zone. dnssec-signzone will also produce a keyset and dsset files and optionally a dlvset file. These are used to provide the parent zone administrators with the DNSKEYs (or their corresponding DS records) that are the secure entry point to the zone. Configuring Servers To enable named to respond appropriately to DNS requests from DNSSEC aware clients, dnssec-enable must be set to yes. (This is the default setting.) To enable named to validate answers from other servers, the dnssec-enable option must be set to yes, and the dnssec-validation options must be set to yes or auto. If dnssec-validation is set to auto, then a default trust anchor for the DNS root zone will be used. If it is set to yes, however, then at least one trust anchor must be configured with a trusted-keys or managed-keys statement in named.conf, or DNSSEC validation will not occur. The default setting is yes. trusted-keys are copies of DNSKEY RRs for zones that are used to form the first link in the cryptographic chain of trust. All keys listed in trusted-keys (and corresponding zones) are deemed to exist and only the listed keys will be used to validated the DNSKEY RRset that they are from. managed-keys are trusted keys which are automatically kept up to date via RFC 5011 trust anchor maintenance. trusted-keys and managed-keys are described in more detail later in this document. Unlike BIND 8, BIND 9 does not verify signatures on load, so zone keys for authoritative zones do not need to be specified in the configuration file. After DNSSEC gets established, a typical DNSSEC configuration will look something like the following. It has one or more public keys for the root. This allows answers from outside the organization to be validated. It will also have several keys for parts of the namespace the organization controls. These are here to ensure that named is immune to compromises in the DNSSEC components of the security of parent zones. managed-keys { /* Root Key */ "." initial-key 257 3 3 "BNY4wrWM1nCfJ+CXd0rVXyYmobt7sEEfK3clRbGaTwS JxrGkxJWoZu6I7PzJu/E9gx4UC1zGAHlXKdE4zYIpRh aBKnvcC2U9mZhkdUpd1Vso/HAdjNe8LmMlnzY3zy2Xy 4klWOADTPzSv9eamj8V18PHGjBLaVtYvk/ln5ZApjYg hf+6fElrmLkdaz MQ2OCnACR817DF4BBa7UR/beDHyp 5iWTXWSi6XmoJLbG9Scqc7l70KDqlvXR3M/lUUVRbke g1IPJSidmK3ZyCllh4XSKbje/45SKucHgnwU5jefMtq 66gKodQj+MiA21AfUVe7u99WzTLzY3qlxDhxYQQ20FQ 97S+LKUTpQcq27R7AT3/V5hRQxScINqwcz4jYqZD2fQ dgxbcDTClU0CRBdiieyLMNzXG3"; }; trusted-keys { /* Key for our organization's forward zone */ example.com. 257 3 5 "AwEAAaxPMcR2x0HbQV4WeZB6oEDX+r0QM6 5KbhTjrW1ZaARmPhEZZe3Y9ifgEuq7vZ/z GZUdEGNWy+JZzus0lUptwgjGwhUS1558Hb 4JKUbbOTcM8pwXlj0EiX3oDFVmjHO444gL kBOUKUf/mC7HvfwYH/Be22GnClrinKJp1O g4ywzO9WglMk7jbfW33gUKvirTHr25GL7S TQUzBb5Usxt8lgnyTUHs1t3JwCY5hKZ6Cq FxmAVZP20igTixin/1LcrgX/KMEGd/biuv F4qJCyduieHukuY3H4XMAcR+xia2nIUPvm /oyWR8BW/hWdzOvnSCThlHf3xiYleDbt/o 1OTQ09A0="; /* Key for our reverse zone. */ 2.0.192.IN-ADDRPA.NET. 257 3 5 "AQOnS4xn/IgOUpBPJ3bogzwc xOdNax071L18QqZnQQQAVVr+i LhGTnNGp3HoWQLUIzKrJVZ3zg gy3WwNT6kZo6c0tszYqbtvchm gQC8CzKojM/W16i6MG/eafGU3 siaOdS0yOI6BgPsw+YZdzlYMa IJGf4M4dyoKIhzdZyQ2bYQrjy Q4LB0lC7aOnsMyYKHHYeRvPxj IQXmdqgOJGq+vsevG06zW+1xg YJh9rCIfnm1GX/KMgxLPG2vXT D/RnLX+D3T3UL7HJYHJhAZD5L 59VvjSPsZJHeDCUyWYrvPZesZ DIRvhDD52SKvbheeTJUm6Ehkz ytNN2SN96QRk8j/iI8ib"; }; options { ... dnssec-enable yes; dnssec-validation yes; }; None of the keys listed in this example are valid. In particular, the root key is not valid. When DNSSEC validation is enabled and properly configured, the resolver will reject any answers from signed, secure zones which fail to validate, and will return SERVFAIL to the client. Responses may fail to validate for any of several reasons, including missing, expired, or invalid signatures, a key which does not match the DS RRset in the parent zone, or an insecure response from a zone which, according to its parent, should have been secure. When the validator receives a response from an unsigned zone that has a signed parent, it must confirm with the parent that the zone was intentionally left unsigned. It does this by verifying, via signed and validated NSEC/NSEC3 records, that the parent zone contains no DS records for the child. If the validator can prove that the zone is insecure, then the response is accepted. However, if it cannot, then it must assume an insecure response to be a forgery; it rejects the response and logs an error. The logged error reads "insecurity proof failed" and "got insecure response; parent indicates it should be secure". (Prior to BIND 9.7, the logged error was "not insecure". This referred to the zone, not the response.) IPv6 Support in <acronym>BIND</acronym> 9 BIND 9 fully supports all currently defined forms of IPv6 name to address and address to name lookups. It will also use IPv6 addresses to make queries when running on an IPv6 capable system. For forward lookups, BIND 9 supports only AAAA records. RFC 3363 deprecated the use of A6 records, and client-side support for A6 records was accordingly removed from BIND 9. However, authoritative BIND 9 name servers still load zone files containing A6 records correctly, answer queries for A6 records, and accept zone transfer for a zone containing A6 records. For IPv6 reverse lookups, BIND 9 supports the traditional "nibble" format used in the ip6.arpa domain, as well as the older, deprecated ip6.int domain. Older versions of BIND 9 supported the "binary label" (also known as "bitstring") format, but support of binary labels has been completely removed per RFC 3363. Many applications in BIND 9 do not understand the binary label format at all any more, and will return an error if given. In particular, an authoritative BIND 9 name server will not load a zone file containing binary labels. For an overview of the format and structure of IPv6 addresses, see . Address Lookups Using AAAA Records The IPv6 AAAA record is a parallel to the IPv4 A record, and, unlike the deprecated A6 record, specifies the entire IPv6 address in a single record. For example, $ORIGIN example.com. host 3600 IN AAAA 2001:db8::1 Use of IPv4-in-IPv6 mapped addresses is not recommended. If a host has an IPv4 address, use an A record, not a AAAA, with ::ffff:192.168.42.1 as the address. Address to Name Lookups Using Nibble Format When looking up an address in nibble format, the address components are simply reversed, just as in IPv4, and ip6.arpa. is appended to the resulting name. For example, the following would provide reverse name lookup for a host with address 2001:db8::1. $ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa. 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 14400 IN PTR ( host.example.com. ) The <acronym>BIND</acronym> 9 Lightweight Resolver The Lightweight Resolver Library Traditionally applications have been linked with a stub resolver library that sends recursive DNS queries to a local caching name server. IPv6 once introduced new complexity into the resolution process, such as following A6 chains and DNAME records, and simultaneous lookup of IPv4 and IPv6 addresses. Though most of the complexity was then removed, these are hard or impossible to implement in a traditional stub resolver. BIND 9 therefore can also provide resolution services to local clients using a combination of a lightweight resolver library and a resolver daemon process running on the local host. These communicate using a simple UDP-based protocol, the "lightweight resolver protocol" that is distinct from and simpler than the full DNS protocol. Running a Resolver Daemon To use the lightweight resolver interface, the system must run the resolver daemon lwresd or a local name server configured with a lwres statement. By default, applications using the lightweight resolver library will make UDP requests to the IPv4 loopback address (127.0.0.1) on port 921. The address can be overridden by lwserver lines in /etc/resolv.conf. The daemon currently only looks in the DNS, but in the future it may use other sources such as /etc/hosts, NIS, etc. The lwresd daemon is essentially a caching-only name server that responds to requests using the lightweight resolver protocol rather than the DNS protocol. Because it needs to run on each host, it is designed to require no or minimal configuration. Unless configured otherwise, it uses the name servers listed on nameserver lines in /etc/resolv.conf as forwarders, but is also capable of doing the resolution autonomously if none are specified. The lwresd daemon may also be configured with a named.conf style configuration file, in /etc/lwresd.conf by default. A name server may also be configured to act as a lightweight resolver daemon using the lwres statement in named.conf. <acronym>BIND</acronym> 9 Configuration Reference BIND 9 configuration is broadly similar to BIND 8; however, there are a few new areas of configuration, such as views. BIND 8 configuration files should work with few alterations in BIND 9, although more complex configurations should be reviewed to check if they can be more efficiently implemented using the new features found in BIND 9. BIND 4 configuration files can be converted to the new format using the shell script contrib/named-bootconf/named-bootconf.sh. Configuration File Elements Following is a list of elements used throughout the BIND configuration file documentation: acl_name The name of an address_match_list as defined by the acl statement. address_match_list A list of one or more ip_addr, ip_prefix, key_id, or acl_name elements, see . masters_list A named list of one or more ip_addr with optional key_id and/or ip_port. A masters_list may include other masters_lists. domain_name A quoted string which will be used as a DNS name, for example "my.test.domain". namelist A list of one or more domain_name elements. dotted_decimal One to four integers valued 0 through 255 separated by dots (`.'), such as 123, 45.67 or 89.123.45.67. ip4_addr An IPv4 address with exactly four elements in dotted_decimal notation. ip6_addr An IPv6 address, such as 2001:db8::1234. IPv6 scoped addresses that have ambiguity on their scope zones must be disambiguated by an appropriate zone ID with the percent character (`%') as delimiter. It is strongly recommended to use string zone names rather than numeric identifiers, in order to be robust against system configuration changes. However, since there is no standard mapping for such names and identifier values, currently only interface names as link identifiers are supported, assuming one-to-one mapping between interfaces and links. For example, a link-local address fe80::1 on the link attached to the interface ne0 can be specified as fe80::1%ne0. Note that on most systems link-local addresses always have the ambiguity, and need to be disambiguated. ip_addr An ip4_addr or ip6_addr. ip_dscp A number between 0 and 63, used to select a differentiated services code point (DSCP) value for use with outgoing traffic on operating systems that support DSCP. ip_port An IP port number. The number is limited to 0 through 65535, with values below 1024 typically restricted to use by processes running as root. In some cases, an asterisk (`*') character can be used as a placeholder to select a random high-numbered port. ip_prefix An IP network specified as an ip_addr, followed by a slash (`/') and then the number of bits in the netmask. Trailing zeros in a ip_addr may omitted. For example, 127/8 is the network 127.0.0.0 with netmask 255.0.0.0 and 1.2.3.0/28 is network 1.2.3.0 with netmask 255.255.255.240. When specifying a prefix involving a IPv6 scoped address the scope may be omitted. In that case the prefix will match packets from any scope. key_id A domain_name representing the name of a shared key, to be used for transaction security. key_list A list of one or more key_ids, separated by semicolons and ending with a semicolon. number A non-negative 32-bit integer (i.e., a number between 0 and 4294967295, inclusive). Its acceptable value might further be limited by the context in which it is used. path_name A quoted string which will be used as a pathname, such as zones/master/my.test.domain. port_list A list of an ip_port or a port range. A port range is specified in the form of range followed by two ip_ports, port_low and port_high, which represents port numbers from port_low through port_high, inclusive. port_low must not be larger than port_high. For example, range 1024 65535 represents ports from 1024 through 65535. In either case an asterisk (`*') character is not allowed as a valid ip_port. size_spec A 64-bit unsigned integer, or the keywords unlimited or default. Integers may take values 0 <= value <= 18446744073709551615, though certain parameters (such as max-journal-size) may use a more limited range within these extremes. In most cases, setting a value to 0 does not literally mean zero; it means "undefined" or "as big as possible", depending on the context. See the explanations of particular parameters that use size_spec for details on how they interpret its use. Numeric values can optionally be followed by a scaling factor: K or k for kilobytes, M or m for megabytes, and G or g for gigabytes, which scale by 1024, 1024*1024, and 1024*1024*1024 respectively. unlimited generally means "as big as possible", and is usually the best way to safely set a very large number. default uses the limit that was in force when the server was started. yes_or_no Either yes or no. The words true and false are also accepted, as are the numbers 1 and 0. dialup_option One of yes, no, notify, notify-passive, refresh or passive. When used in a zone, notify-passive, refresh, and passive are restricted to slave and stub zones. Address Match Lists Syntax address_match_list = address_match_list_element ; address_match_list_element; ... address_match_list_element = ! (ip_address /length | key key_id | acl_name | { address_match_list } ) Definition and Usage Address match lists are primarily used to determine access control for various server operations. They are also used in the listen-on and sortlist statements. The elements which constitute an address match list can be any of the following: an IP address (IPv4 or IPv6) an IP prefix (in `/' notation) a key ID, as defined by the key statement the name of an address match list defined with the acl statement a nested address match list enclosed in braces Elements can be negated with a leading exclamation mark (`!'), and the match list names "any", "none", "localhost", and "localnets" are predefined. More information on those names can be found in the description of the acl statement. The addition of the key clause made the name of this syntactic element something of a misnomer, since security keys can be used to validate access without regard to a host or network address. Nonetheless, the term "address match list" is still used throughout the documentation. When a given IP address or prefix is compared to an address match list, the comparison takes place in approximately O(1) time. However, key comparisons require that the list of keys be traversed until a matching key is found, and therefore may be somewhat slower. The interpretation of a match depends on whether the list is being used for access control, defining listen-on ports, or in a sortlist, and whether the element was negated. When used as an access control list, a non-negated match allows access and a negated match denies access. If there is no match, access is denied. The clauses allow-notify, allow-recursion, allow-recursion-on, allow-query, allow-query-on, allow-query-cache, allow-query-cache-on, allow-transfer, allow-update, allow-update-forwarding, and blackhole all use address match lists. Similarly, the listen-on option will cause the server to refuse queries on any of the machine's addresses which do not match the list. Order of insertion is significant. If more than one element in an ACL is found to match a given IP address or prefix, preference will be given to the one that came first in the ACL definition. Because of this first-match behavior, an element that defines a subset of another element in the list should come before the broader element, regardless of whether either is negated. For example, in 1.2.3/24; ! 1.2.3.13; the 1.2.3.13 element is completely useless because the algorithm will match any lookup for 1.2.3.13 to the 1.2.3/24 element. Using ! 1.2.3.13; 1.2.3/24 fixes that problem by having 1.2.3.13 blocked by the negation, but all other 1.2.3.* hosts fall through. Comment Syntax The BIND 9 comment syntax allows for comments to appear anywhere that whitespace may appear in a BIND configuration file. To appeal to programmers of all kinds, they can be written in the C, C++, or shell/perl style. Syntax /* This is a BIND comment as in C */ // This is a BIND comment as in C++ # This is a BIND comment as in common UNIX shells # and perl Definition and Usage Comments may appear anywhere that whitespace may appear in a BIND configuration file. C-style comments start with the two characters /* (slash, star) and end with */ (star, slash). Because they are completely delimited with these characters, they can be used to comment only a portion of a line or to span multiple lines. C-style comments cannot be nested. For example, the following is not valid because the entire comment ends with the first */: /* This is the start of a comment. This is still part of the comment. /* This is an incorrect attempt at nesting a comment. */ This is no longer in any comment. */ C++-style comments start with the two characters // (slash, slash) and continue to the end of the physical line. They cannot be continued across multiple physical lines; to have one logical comment span multiple lines, each line must use the // pair. For example: // This is the start of a comment. The next line // is a new comment, even though it is logically // part of the previous comment. Shell-style (or perl-style, if you prefer) comments start with the character # (number sign) and continue to the end of the physical line, as in C++ comments. For example: # This is the start of a comment. The next line # is a new comment, even though it is logically # part of the previous comment. You cannot use the semicolon (`;') character to start a comment such as you would in a zone file. The semicolon indicates the end of a configuration statement. Configuration File Grammar A BIND 9 configuration consists of statements and comments. Statements end with a semicolon. Statements and comments are the only elements that can appear without enclosing braces. Many statements contain a block of sub-statements, which are also terminated with a semicolon. The following statements are supported: acl defines a named IP address matching list, for access control and other uses. controls declares control channels to be used by the rndc utility. include includes a file. key specifies key information for use in authentication and authorization using TSIG. logging specifies what the server logs, and where the log messages are sent. lwres configures named to also act as a light-weight resolver daemon (lwresd). masters defines a named masters list for inclusion in stub and slave zones' masters or also-notify lists. options controls global server configuration options and sets defaults for other statements. server sets certain configuration options on a per-server basis. statistics-channels declares communication channels to get access to named statistics. trusted-keys defines trusted DNSSEC keys. managed-keys lists DNSSEC keys to be kept up to date using RFC 5011 trust anchor maintenance. view defines a view. zone defines a zone. The logging and options statements may only occur once per configuration. <command>acl</command> Statement Grammar acl acl-name { address_match_list }; <command>acl</command> Statement Definition and Usage The acl statement assigns a symbolic name to an address match list. It gets its name from a primary use of address match lists: Access Control Lists (ACLs). The following ACLs are built-in: any Matches all hosts. none Matches no hosts. localhost Matches the IPv4 and IPv6 addresses of all network interfaces on the system. When addresses are added or removed, the localhost ACL element is updated to reflect the changes. localnets Matches any host on an IPv4 or IPv6 network for which the system has an interface. When addresses are added or removed, the localnets ACL element is updated to reflect the changes. Some systems do not provide a way to determine the prefix lengths of local IPv6 addresses. In such a case, localnets only matches the local IPv6 addresses, just like localhost. When BIND 9 is built with GeoIP support, ACLs can also be used for geographic access restrictions. This is done by specifying an ACL element of the form: geoip db database field value The field indicates which field to search for a match. Available fields are "country", "region", "city", "continent", "postal" (postal code), "metro" (metro code), "area" (area code), "tz" (timezone), "isp", "org", "asnum", "domain" and "netspeed". value is the value to search for within the database. A string may be quoted if it contains spaces or other special characters. If this is an "asnum" search, then the leading "ASNNNN" string can be used, otherwise the full description must be used (e.g. "ASNNNN Example Company Name"). If this is a "country" search and the string is two characters long, then it must be a standard ISO-3166-1 two-letter country code, and if it is three characters long then it must be an ISO-3166-1 three-letter country code; otherwise it is the full name of the country. Similarly, if this is a "region" search and the string is two characters long, then it must be a standard two-letter state or province abbreviation; otherwise it is the full name of the state or province. The database field indicates which GeoIP database to search for a match. In most cases this is unnecessary, because most search fields can only be found in a single database. However, searches for country can be answered from the "city", "region", or "country" databases, and searches for region (i.e., state or province) can be answered from the "city" or "region" databases. For these search types, specifying a database will force the query to be answered from that database and no other. If database is not specified, then these queries will be answered from the "city", database if it is installed, or the "region" database if it is installed, or the "country" database, in that order. Some example GeoIP ACLs: geoip country US; geoip country JAP; geoip db country country Canada; geoip db region region WA; geoip city "San Francisco"; geoip region Oklahoma; geoip postal 95062; geoip tz "America/Los_Angeles"; geoip org "Internet Systems Consortium"; <command>controls</command> Statement Grammar controls { [ inet ( ip_addr | * ) [ port ip_port ] allow { address_match_list } keys { key_list }; ] [ inet ...; ] [ unix path perm number owner number group number keys { key_list }; ] [ unix ...; ] }; <command>controls</command> Statement Definition and Usage The controls statement declares control channels to be used by system administrators to control the operation of the name server. These control channels are used by the rndc utility to send commands to and retrieve non-DNS results from a name server. An inet control channel is a TCP socket listening at the specified ip_port on the specified ip_addr, which can be an IPv4 or IPv6 address. An ip_addr of * (asterisk) is interpreted as the IPv4 wildcard address; connections will be accepted on any of the system's IPv4 addresses. To listen on the IPv6 wildcard address, use an ip_addr of ::. If you will only use rndc on the local host, using the loopback address (127.0.0.1 or ::1) is recommended for maximum security. If no port is specified, port 953 is used. The asterisk "*" cannot be used for ip_port. The ability to issue commands over the control channel is restricted by the allow and keys clauses. Connections to the control channel are permitted based on the address_match_list. This is for simple IP address based filtering only; any key_id elements of the address_match_list are ignored. A unix control channel is a UNIX domain socket listening at the specified path in the file system. Access to the socket is specified by the perm, owner and group clauses. Note on some platforms (SunOS and Solaris) the permissions (perm) are applied to the parent directory as the permissions on the socket itself are ignored. The primary authorization mechanism of the command channel is the key_list, which contains a list of key_ids. Each key_id in the key_list is authorized to execute commands over the control channel. See in ) for information about configuring keys in rndc. If no controls statement is present, named will set up a default control channel listening on the loopback address 127.0.0.1 and its IPv6 counterpart ::1. In this case, and also when the controls statement is present but does not have a keys clause, named will attempt to load the command channel key from the file rndc.key in /etc (or whatever sysconfdir was specified as when BIND was built). To create a rndc.key file, run rndc-confgen -a. The rndc.key feature was created to ease the transition of systems from BIND 8, which did not have digital signatures on its command channel messages and thus did not have a keys clause. It makes it possible to use an existing BIND 8 configuration file in BIND 9 unchanged, and still have rndc work the same way ndc worked in BIND 8, simply by executing the command rndc-confgen -a after BIND 9 is installed. Since the rndc.key feature is only intended to allow the backward-compatible usage of BIND 8 configuration files, this feature does not have a high degree of configurability. You cannot easily change the key name or the size of the secret, so you should make a rndc.conf with your own key if you wish to change those things. The rndc.key file also has its permissions set such that only the owner of the file (the user that named is running as) can access it. If you desire greater flexibility in allowing other users to access rndc commands, then you need to create a rndc.conf file and make it group readable by a group that contains the users who should have access. To disable the command channel, use an empty controls statement: controls { };. <command>include</command> Statement Grammar include filename; <command>include</command> Statement Definition and Usage The include statement inserts the specified file at the point where the include statement is encountered. The include statement facilitates the administration of configuration files by permitting the reading or writing of some things but not others. For example, the statement could include private keys that are readable only by the name server. <command>key</command> Statement Grammar key key_id { algorithm algorithm_id; secret secret_string; }; <command>key</command> Statement Definition and Usage The key statement defines a shared secret key for use with TSIG (see ) or the command channel (see ). The key statement can occur at the top level of the configuration file or inside a view statement. Keys defined in top-level key statements can be used in all views. Keys intended for use in a controls statement (see ) must be defined at the top level. The key_id, also known as the key name, is a domain name uniquely identifying the key. It can be used in a server statement to cause requests sent to that server to be signed with this key, or in address match lists to verify that incoming requests have been signed with a key matching this name, algorithm, and secret. The algorithm_id is a string that specifies a security/authentication algorithm. Named supports hmac-md5, hmac-sha1, hmac-sha224, hmac-sha256, hmac-sha384 and hmac-sha512 TSIG authentication. Truncated hashes are supported by appending the minimum number of required bits preceded by a dash, e.g. hmac-sha1-80. The secret_string is the secret to be used by the algorithm, and is treated as a base-64 encoded string. <command>logging</command> Statement Grammar logging { [ channel channel_name { ( file path_name [ versions ( number | unlimited ) ] [ size size_spec ] | syslog syslog_facility | stderr | null ); [ severity ( | | | | | [ level ] | ); ] [ print-category or ; ] [ print-severity or ; ] [ print-time or ; ] }; ] [ category category_name { channel_name ; [ channel_name ; ... ] }; ] ... }; <command>logging</command> Statement Definition and Usage The logging statement configures a wide variety of logging options for the name server. Its channel phrase associates output methods, format options and severity levels with a name that can then be used with the category phrase to select how various classes of messages are logged. Only one logging statement is used to define as many channels and categories as are wanted. If there is no logging statement, the logging configuration will be: logging { category default { default_syslog; default_debug; }; category unmatched { null; }; }; In BIND 9, the logging configuration is only established when the entire configuration file has been parsed. In BIND 8, it was established as soon as the logging statement was parsed. When the server is starting up, all logging messages regarding syntax errors in the configuration file go to the default channels, or to standard error if the "" option was specified. The <command>channel</command> Phrase All log output goes to one or more channels; you can make as many of them as you want. Every channel definition must include a destination clause that says whether messages selected for the channel go to a file, to a particular syslog facility, to the standard error stream, or are discarded. It can optionally also limit the message severity level that will be accepted by the channel (the default is info), and whether to include a named-generated time stamp, the category name and/or severity level (the default is not to include any). The null destination clause causes all messages sent to the channel to be discarded; in that case, other options for the channel are meaningless. The file destination clause directs the channel to a disk file. It can include limitations both on how large the file is allowed to become, and how many versions of the file will be saved each time the file is opened. If you use the versions log file option, then named will retain that many backup versions of the file by renaming them when opening. For example, if you choose to keep three old versions of the file lamers.log, then just before it is opened lamers.log.1 is renamed to lamers.log.2, lamers.log.0 is renamed to lamers.log.1, and lamers.log is renamed to lamers.log.0. You can say versions unlimited to not limit the number of versions. If a size option is associated with the log file, then renaming is only done when the file being opened exceeds the indicated size. No backup versions are kept by default; any existing log file is simply appended. The size option for files is used to limit log growth. If the file ever exceeds the size, then named will stop writing to the file unless it has a versions option associated with it. If backup versions are kept, the files are rolled as described above and a new one begun. If there is no versions option, no more data will be written to the log until some out-of-band mechanism removes or truncates the log to less than the maximum size. The default behavior is not to limit the size of the file. Example usage of the size and versions options: channel an_example_channel { file "example.log" versions 3 size 20m; print-time yes; print-category yes; }; The syslog destination clause directs the channel to the system log. Its argument is a syslog facility as described in the syslog man page. Known facilities are kern, user, mail, daemon, auth, syslog, lpr, news, uucp, cron, authpriv, ftp, local0, local1, local2, local3, local4, local5, local6 and local7, however not all facilities are supported on all operating systems. How syslog will handle messages sent to this facility is described in the syslog.conf man page. If you have a system which uses a very old version of syslog that only uses two arguments to the openlog() function, then this clause is silently ignored. On Windows machines syslog messages are directed to the EventViewer. The severity clause works like syslog's "priorities", except that they can also be used if you are writing straight to a file rather than using syslog. Messages which are not at least of the severity level given will not be selected for the channel; messages of higher severity levels will be accepted. If you are using syslog, then the syslog.conf priorities will also determine what eventually passes through. For example, defining a channel facility and severity as daemon and debug but only logging daemon.warning via syslog.conf will cause messages of severity info and notice to be dropped. If the situation were reversed, with named writing messages of only warning or higher, then syslogd would print all messages it received from the channel. The stderr destination clause directs the channel to the server's standard error stream. This is intended for use when the server is running as a foreground process, for example when debugging a configuration. The server can supply extensive debugging information when it is in debugging mode. If the server's global debug level is greater than zero, then debugging mode will be active. The global debug level is set either by starting the named server with the flag followed by a positive integer, or by running rndc trace. The global debug level can be set to zero, and debugging mode turned off, by running rndc notrace. All debugging messages in the server have a debug level, and higher debug levels give more detailed output. Channels that specify a specific debug severity, for example: channel specific_debug_level { file "foo"; severity debug 3; }; will get debugging output of level 3 or less any time the server is in debugging mode, regardless of the global debugging level. Channels with dynamic severity use the server's global debug level to determine what messages to print. If print-time has been turned on, then the date and time will be logged. print-time may be specified for a syslog channel, but is usually pointless since syslog also logs the date and time. If print-category is requested, then the category of the message will be logged as well. Finally, if print-severity is on, then the severity level of the message will be logged. The print- options may be used in any combination, and will always be printed in the following order: time, category, severity. Here is an example where all three print- options are on: 28-Feb-2000 15:05:32.863 general: notice: running There are four predefined channels that are used for named's default logging as follows. How they are used is described in . channel default_syslog { // send to syslog's daemon facility syslog daemon; // only send priority info and higher severity info; channel default_debug { // write to named.run in the working directory // Note: stderr is used instead of "named.run" if // the server is started with the '-f' option. file "named.run"; // log at the server's current debug level severity dynamic; }; channel default_stderr { // writes to stderr stderr; // only send priority info and higher severity info; }; channel null { // toss anything sent to this channel null; }; The default_debug channel has the special property that it only produces output when the server's debug level is nonzero. It normally writes to a file called named.run in the server's working directory. For security reasons, when the "" command line option is used, the named.run file is created only after named has changed to the new UID, and any debug output generated while named is starting up and still running as root is discarded. If you need to capture this output, you must run the server with the "" option and redirect standard error to a file. Once a channel is defined, it cannot be redefined. Thus you cannot alter the built-in channels directly, but you can modify the default logging by pointing categories at channels you have defined. The <command>category</command> Phrase There are many categories, so you can send the logs you want to see wherever you want, without seeing logs you don't want. If you don't specify a list of channels for a category, then log messages in that category will be sent to the default category instead. If you don't specify a default category, the following "default default" is used: category default { default_syslog; default_debug; }; As an example, let's say you want to log security events to a file, but you also want keep the default logging behavior. You'd specify the following: channel my_security_channel { file "my_security_file"; severity info; }; category security { my_security_channel; default_syslog; default_debug; }; To discard all messages in a category, specify the null channel: category xfer-out { null; }; category notify { null; }; Following are the available categories and brief descriptions of the types of log information they contain. More categories may be added in future BIND releases. default The default category defines the logging options for those categories where no specific configuration has been defined. general The catch-all. Many things still aren't classified into categories, and they all end up here. database Messages relating to the databases used internally by the name server to store zone and cache data. security Approval and denial of requests. config Configuration file parsing and processing. resolver DNS resolution, such as the recursive lookups performed on behalf of clients by a caching name server. xfer-in Zone transfers the server is receiving. xfer-out Zone transfers the server is sending. notify The NOTIFY protocol. client Processing of client requests. unmatched Messages that named was unable to determine the class of or for which there was no matching view. A one line summary is also logged to the client category. This category is best sent to a file or stderr, by default it is sent to the null channel. network Network operations. update Dynamic updates. update-security Approval and denial of update requests. queries Specify where queries should be logged to. At startup, specifying the category queries will also enable query logging unless querylog option has been specified. The query log entry reports the client's IP address and port number, and the query name, class and type. Next it reports whether the Recursion Desired flag was set (+ if set, - if not set), if the query was signed (S), EDNS was in use (E), if TCP was used (T), if DO (DNSSEC Ok) was set (D), or if CD (Checking Disabled) was set (C). After this the destination address the query was sent to is reported. client 127.0.0.1#62536 (www.example.com): query: www.example.com IN AAAA +SE client ::1#62537 (www.example.net): query: www.example.net IN AAAA -SE (The first part of this log message, showing the client address/port number and query name, is repeated in all subsequent log messages related to the same query.) query-errors Information about queries that resulted in some failure. dispatch Dispatching of incoming packets to the server modules where they are to be processed. dnssec DNSSEC and TSIG protocol processing. lame-servers Lame servers. These are misconfigurations in remote servers, discovered by BIND 9 when trying to query those servers during resolution. delegation-only Delegation only. Logs queries that have been forced to NXDOMAIN as the result of a delegation-only zone or a delegation-only in a forward, hint or stub zone declaration. edns-disabled Log queries that have been forced to use plain DNS due to timeouts. This is often due to the remote servers not being RFC 1034 compliant (not always returning FORMERR or similar to EDNS queries and other extensions to the DNS when they are not understood). In other words, this is targeted at servers that fail to respond to DNS queries that they don't understand. Note: the log message can also be due to packet loss. Before reporting servers for non-RFC 1034 compliance they should be re-tested to determine the nature of the non-compliance. This testing should prevent or reduce the number of false-positive reports. Note: eventually named will have to stop treating such timeouts as due to RFC 1034 non compliance and start treating it as plain packet loss. Falsely classifying packet loss as due to RFC 1034 non compliance impacts on DNSSEC validation which requires EDNS for the DNSSEC records to be returned. RPZ Information about errors in response policy zone files, rewritten responses, and at the highest debug levels, mere rewriting attempts. rate-limit The start, periodic, and final notices of the rate limiting of a stream of responses are logged at info severity in this category. These messages include a hash value of the domain name of the response and the name itself, except when there is insufficient memory to record the name for the final notice The final notice is normally delayed until about one minute after rate limit stops. A lack of memory can hurry the final notice, in which case it starts with an asterisk (*). Various internal events are logged at debug 1 level and higher. Rate limiting of individual requests is logged in the query-errors category. cname Logs nameservers that are skipped due to them being a CNAME rather than A / AAAA records. The <command>query-errors</command> Category The query-errors category is specifically intended for debugging purposes: To identify why and how specific queries result in responses which indicate an error. Messages of this category are therefore only logged with debug levels. At the debug levels of 1 or higher, each response with the rcode of SERVFAIL is logged as follows: client 127.0.0.1#61502: query failed (SERVFAIL) for www.example.com/IN/AAAA at query.c:3880 This means an error resulting in SERVFAIL was detected at line 3880 of source file query.c. Log messages of this level will particularly help identify the cause of SERVFAIL for an authoritative server. At the debug levels of 2 or higher, detailed context information of recursive resolutions that resulted in SERVFAIL is logged. The log message will look like as follows: fetch completed at resolver.c:2970 for www.example.com/A in 30.000183: timed out/success [domain:example.com, referral:2,restart:7,qrysent:8,timeout:5,lame:0,neterr:0, badresp:1,adberr:0,findfail:0,valfail:0] The first part before the colon shows that a recursive resolution for AAAA records of www.example.com completed in 30.000183 seconds and the final result that led to the SERVFAIL was determined at line 2970 of source file resolver.c. The following part shows the detected final result and the latest result of DNSSEC validation. The latter is always success when no validation attempt is made. In this example, this query resulted in SERVFAIL probably because all name servers are down or unreachable, leading to a timeout in 30 seconds. DNSSEC validation was probably not attempted. The last part enclosed in square brackets shows statistics information collected for this particular resolution attempt. The domain field shows the deepest zone that the resolver reached; it is the zone where the error was finally detected. The meaning of the other fields is summarized in the following table. referral The number of referrals the resolver received throughout the resolution process. In the above example this is 2, which are most likely com and example.com. restart The number of cycles that the resolver tried remote servers at the domain zone. In each cycle the resolver sends one query (possibly resending it, depending on the response) to each known name server of the domain zone. qrysent The number of queries the resolver sent at the domain zone. timeout The number of timeouts since the resolver received the last response. lame The number of lame servers the resolver detected at the domain zone. A server is detected to be lame either by an invalid response or as a result of lookup in BIND9's address database (ADB), where lame servers are cached. neterr The number of erroneous results that the resolver encountered in sending queries at the domain zone. One common case is the remote server is unreachable and the resolver receives an ICMP unreachable error message. badresp The number of unexpected responses (other than lame) to queries sent by the resolver at the domain zone. adberr Failures in finding remote server addresses of the domain zone in the ADB. One common case of this is that the remote server's name does not have any address records. findfail Failures of resolving remote server addresses. This is a total number of failures throughout the resolution process. valfail Failures of DNSSEC validation. Validation failures are counted throughout the resolution process (not limited to the domain zone), but should only happen in domain. At the debug levels of 3 or higher, the same messages as those at the debug 1 level are logged for other errors than SERVFAIL. Note that negative responses such as NXDOMAIN are not regarded as errors here. At the debug levels of 4 or higher, the same messages as those at the debug 2 level are logged for other errors than SERVFAIL. Unlike the above case of level 3, messages are logged for negative responses. This is because any unexpected results can be difficult to debug in the recursion case. <command>lwres</command> Statement Grammar This is the grammar of the lwres statement in the named.conf file: lwres { listen-on { ip_addr port ip_port dscp ip_dscp ; ip_addr port ip_port dscp ip_dscp ; ... }; view view_name; search { domain_name ; domain_name ; ... }; ndots number; }; <command>lwres</command> Statement Definition and Usage The lwres statement configures the name server to also act as a lightweight resolver server. (See .) There may be multiple lwres statements configuring lightweight resolver servers with different properties. The listen-on statement specifies a list of IPv4 addresses (and ports) that this instance of a lightweight resolver daemon should accept requests on. If no port is specified, port 921 is used. If this statement is omitted, requests will be accepted on 127.0.0.1, port 921. The view statement binds this instance of a lightweight resolver daemon to a view in the DNS namespace, so that the response will be constructed in the same manner as a normal DNS query matching this view. If this statement is omitted, the default view is used, and if there is no default view, an error is triggered. The search statement is equivalent to the search statement in /etc/resolv.conf. It provides a list of domains which are appended to relative names in queries. The ndots statement is equivalent to the ndots statement in /etc/resolv.conf. It indicates the minimum number of dots in a relative domain name that should result in an exact match lookup before search path elements are appended. <command>masters</command> Statement Grammar masters name port ip_port dscp ip_dscp { ( masters_list | ip_addr port ip_port key key ) ; ... }; <command>masters</command> Statement Definition and Usage masters lists allow for a common set of masters to be easily used by multiple stub and slave zones in their masters or also-notify lists. <command>options</command> Statement Grammar This is the grammar of the options statement in the named.conf file: options { attach-cache cache_name; version version_string; hostname hostname_string; server-id server_id_string; directory path_name; geoip-directory path_name; key-directory path_name; managed-keys-directory path_name; named-xfer path_name; tkey-gssapi-keytab path_name; tkey-gssapi-credential principal; tkey-domain domainname; tkey-dhkey key_name key_tag; cache-file path_name; dump-file path_name; bindkeys-file path_name; secroots-file path_name; session-keyfile path_name; session-keyname key_name; session-keyalg algorithm_id; memstatistics yes_or_no; memstatistics-file path_name; pid-file path_name; recursing-file path_name; statistics-file path_name; zone-statistics full | terse | none; auth-nxdomain yes_or_no; deallocate-on-exit yes_or_no; dialup dialup_option; fake-iquery yes_or_no; fetch-glue yes_or_no; flush-zones-on-shutdown yes_or_no; has-old-clients yes_or_no; host-statistics yes_or_no; host-statistics-max number; minimal-responses yes_or_no; multiple-cnames yes_or_no; notify yes_or_no | explicit | master-only; recursion yes_or_no; request-sit yes_or_no; request-nsid yes_or_no; rfc2308-type1 yes_or_no; use-id-pool yes_or_no; maintain-ixfr-base yes_or_no; ixfr-from-differences (yes_or_no | master | slave); dnssec-enable yes_or_no; dnssec-validation (yes_or_no | auto); dnssec-lookaside ( auto | no | domain trust-anchor domain ); dnssec-must-be-secure domain yes_or_no; dnssec-accept-expired yes_or_no; forward ( only | first ); forwarders { ip_addr port ip_port dscp ip_dscp ; ... }; dual-stack-servers port ip_port dscp ip_dscp { ( domain_name port ip_port dscp ip_dscp | ip_addr port ip_port dscp ip_dscp) ; ... }; check-names ( master | slave | response ) ( warn | fail | ignore ); check-dup-records ( warn | fail | ignore ); check-mx ( warn | fail | ignore ); check-wildcard yes_or_no; check-integrity yes_or_no; check-mx-cname ( warn | fail | ignore ); check-srv-cname ( warn | fail | ignore ); check-sibling yes_or_no; check-spf ( warn | ignore ); allow-new-zones { yes_or_no }; allow-notify { address_match_list }; allow-query { address_match_list }; allow-query-on { address_match_list }; allow-query-cache { address_match_list }; allow-query-cache-on { address_match_list }; allow-transfer { address_match_list }; allow-recursion { address_match_list }; allow-recursion-on { address_match_list }; allow-update { address_match_list }; allow-update-forwarding { address_match_list }; update-check-ksk yes_or_no; dnssec-update-mode ( maintain | no-resign ); dnssec-dnskey-kskonly yes_or_no; dnssec-loadkeys-interval number; dnssec-secure-to-insecure yes_or_no ; try-tcp-refresh yes_or_no; allow-v6-synthesis { address_match_list }; blackhole { address_match_list }; no-case-compress { address_match_list }; use-v4-udp-ports { port_list }; avoid-v4-udp-ports { port_list }; use-v6-udp-ports { port_list }; avoid-v6-udp-ports { port_list }; listen-on port ip_port dscp ip_dscp { address_match_list }; listen-on-v6 port ip_port dscp ip_dscp { address_match_list }; query-source ( ( ip4_addr | * ) port ( ip_port | * ) dscp ip_dscp | address ( ip4_addr | * ) port ( ip_port | * ) ) dscp ip_dscp ; query-source-v6 ( ( ip6_addr | * ) port ( ip_port | * ) dscp ip_dscp | address ( ip6_addr | * ) port ( ip_port | * ) ) dscp ip_dscp ; use-queryport-pool yes_or_no; queryport-pool-ports number; queryport-pool-updateinterval number; max-transfer-time-in number; max-transfer-time-out number; max-transfer-idle-in number; max-transfer-idle-out number; reserved-sockets number; recursive-clients number; tcp-clients number; clients-per-query number ; max-clients-per-query number ; fetches-per-server number (drop | fail); fetch-quota-params number fixedpoint fixedpoint fixedpoint ; fetches-per-zonenumber (drop | fail); serial-query-rate number; serial-queries number; tcp-listen-queue number; transfer-format ( one-answer | many-answers ); transfers-in number; transfers-out number; transfers-per-ns number; transfer-source (ip4_addr | *) port ip_port dscp ip_dscp ; transfer-source-v6 (ip6_addr | *) port ip_port dscp ip_dscp ; alt-transfer-source (ip4_addr | *) port ip_port dscp ip_dscp ; alt-transfer-source-v6 (ip6_addr | *) port ip_port dscp ip_dscp ; use-alt-transfer-source yes_or_no; notify-delay seconds ; notify-source (ip4_addr | *) port ip_port dscp ip_dscp ; notify-source-v6 (ip6_addr | *) port ip_port dscp ip_dscp ; notify-to-soa yes_or_no ; also-notify { ip_addr port ip_port dscp ip_dscp key keyname ; ip_addr port ip_port dscp ip_dscp key keyname ; ... }; max-ixfr-log-size number; max-journal-size size_spec; coresize size_spec ; datasize size_spec ; files size_spec ; stacksize size_spec ; cleaning-interval number; heartbeat-interval number; interface-interval number; statistics-interval number; topology { address_match_list }; sortlist { address_match_list }; rrset-order { order_spec ; order_spec ; ... }; lame-ttl number; max-ncache-ttl number; max-cache-ttl number; max-zone-ttl number ; sig-validity-interval number number ; sig-signing-nodes number ; sig-signing-signatures number ; sig-signing-type number ; min-roots number; use-ixfr yes_or_no ; provide-ixfr yes_or_no; request-ixfr yes_or_no; treat-cr-as-space yes_or_no ; min-refresh-time number ; max-refresh-time number ; min-retry-time number ; max-retry-time number ; port ip_port; dscp ip_dscp ; additional-from-auth yes_or_no ; additional-from-cache yes_or_no ; random-device path_name ; max-cache-size size_spec ; match-mapped-addresses yes_or_no; filter-aaaa-on-v4 ( yes_or_no | break-dnssec ); filter-aaaa-on-v6 ( yes_or_no | break-dnssec ); filter-aaaa { address_match_list }; dns64 ipv6-prefix { clients { address_match_list }; mapped { address_match_list }; exclude { address_match_list }; suffix IPv6-address; recursive-only yes_or_no; break-dnssec yes_or_no; }; ; dns64-server name dns64-contact name preferred-glue ( A | AAAA | NONE ); edns-udp-size number; max-udp-size number; max-rsa-exponent-size number; root-delegation-only exclude { namelist } ; querylog yes_or_no ; disable-algorithms domain { algorithm; algorithm; }; disable-ds-digests domain { digest_type; digest_type; }; acache-enable yes_or_no ; acache-cleaning-interval number; max-acache-size size_spec ; max-recursion-depth number ; max-recursion-queries number ; masterfile-format (text|raw|map) ; empty-server name ; empty-contact name ; empty-zones-enable yes_or_no ; disable-empty-zone zone_name ; zero-no-soa-ttl yes_or_no ; zero-no-soa-ttl-cache yes_or_no ; resolver-query-timeout number ; deny-answer-addresses { address_match_list } except-from { namelist } ; deny-answer-aliases { namelist } except-from { namelist } ; prefetch number number ; rate-limit { responses-per-second number ; referrals-per-second number ; nodata-per-second number ; nxdomains-per-second number ; errors-per-second number ; all-per-second number ; window number ; log-only yes_or_no ; qps-scale number ; ipv4-prefix-length number ; ipv6-prefix-length number ; slip number ; exempt-clients { address_match_list } ; max-table-size number ; min-table-size number ; } ; response-policy { zone zone_name policy (given | disabled | passthru | drop | nxdomain | nodata | cname domain) recursive-only yes_or_no max-policy-ttl number ; ... } recursive-only yes_or_no max-policy-ttl number break-dnssec yes_or_no min-ns-dots number qname-wait-recurse yes_or_no ; }; <command>options</command> Statement Definition and Usage The options statement sets up global options to be used by BIND. This statement may appear only once in a configuration file. If there is no options statement, an options block with each option set to its default will be used. attach-cache Allows multiple views to share a single cache database. Each view has its own cache database by default, but if multiple views have the same operational policy for name resolution and caching, those views can share a single cache to save memory and possibly improve resolution efficiency by using this option. The attach-cache option may also be specified in view statements, in which case it overrides the global attach-cache option. The cache_name specifies the cache to be shared. When the named server configures views which are supposed to share a cache, it creates a cache with the specified name for the first view of these sharing views. The rest of the views will simply refer to the already created cache. One common configuration to share a cache would be to allow all views to share a single cache. This can be done by specifying the attach-cache as a global option with an arbitrary name. Another possible operation is to allow a subset of all views to share a cache while the others to retain their own caches. For example, if there are three views A, B, and C, and only A and B should share a cache, specify the attach-cache option as a view A (or B)'s option, referring to the other view name: view "A" { // this view has its own cache ... }; view "B" { // this view refers to A's cache attach-cache "A"; }; view "C" { // this view has its own cache ... }; Views that share a cache must have the same policy on configurable parameters that may affect caching. The current implementation requires the following configurable options be consistent among these views: check-names, cleaning-interval, dnssec-accept-expired, dnssec-validation, max-cache-ttl, max-ncache-ttl, max-cache-size, and zero-no-soa-ttl. Note that there may be other parameters that may cause confusion if they are inconsistent for different views that share a single cache. For example, if these views define different sets of forwarders that can return different answers for the same question, sharing the answer does not make sense or could even be harmful. It is administrator's responsibility to ensure configuration differences in different views do not cause disruption with a shared cache. directory The working directory of the server. Any non-absolute pathnames in the configuration file will be taken as relative to this directory. The default location for most server output files (e.g. named.run) is this directory. If a directory is not specified, the working directory defaults to `.', the directory from which the server was started. The directory specified should be an absolute path. geoip-directory Specifies the directory containing GeoIP .dat database files for GeoIP initialization. By default, this option is unset and the GeoIP support will use libGeoIP's built-in directory. (For details, see about the geoip ACL.) key-directory When performing dynamic update of secure zones, the directory where the public and private DNSSEC key files should be found, if different than the current working directory. (Note that this option has no effect on the paths for files containing non-DNSSEC keys such as bind.keys, rndc.key or session.key.) managed-keys-directory Specifies the directory in which to store the files that track managed DNSSEC keys. By default, this is the working directory. If named is not configured to use views, then managed keys for the server will be tracked in a single file called managed-keys.bind. Otherwise, managed keys will be tracked in separate files, one file per view; each file name will be the SHA256 hash of the view name, followed by the extension .mkeys. named-xfer This option is obsolete. It was used in BIND 8 to specify the pathname to the named-xfer program. In BIND 9, no separate named-xfer program is needed; its functionality is built into the name server. tkey-gssapi-keytab The KRB5 keytab file to use for GSS-TSIG updates. If this option is set and tkey-gssapi-credential is not set, then updates will be allowed with any key matching a principal in the specified keytab. tkey-gssapi-credential The security credential with which the server should authenticate keys requested by the GSS-TSIG protocol. Currently only Kerberos 5 authentication is available and the credential is a Kerberos principal which the server can acquire through the default system key file, normally /etc/krb5.keytab. The location keytab file can be overridden using the tkey-gssapi-keytab option. Normally this principal is of the form "DNS/server.domain". To use GSS-TSIG, tkey-domain must also be set if a specific keytab is not set with tkey-gssapi-keytab. tkey-domain The domain appended to the names of all shared keys generated with TKEY. When a client requests a TKEY exchange, it may or may not specify the desired name for the key. If present, the name of the shared key will be client specified part + tkey-domain. Otherwise, the name of the shared key will be random hex digits + tkey-domain. In most cases, the domainname should be the server's domain name, or an otherwise non-existent subdomain like "_tkey.domainname". If you are using GSS-TSIG, this variable must be defined, unless you specify a specific keytab using tkey-gssapi-keytab. tkey-dhkey The Diffie-Hellman key used by the server to generate shared keys with clients using the Diffie-Hellman mode of TKEY. The server must be able to load the public and private keys from files in the working directory. In most cases, the keyname should be the server's host name. cache-file This is for testing only. Do not use. dump-file The pathname of the file the server dumps the database to when instructed to do so with rndc dumpdb. If not specified, the default is named_dump.db. memstatistics-file The pathname of the file the server writes memory usage statistics to on exit. If not specified, the default is named.memstats. pid-file The pathname of the file the server writes its process ID in. If not specified, the default is /var/run/named/named.pid. The PID file is used by programs that want to send signals to the running name server. Specifying pid-file none disables the use of a PID file — no file will be written and any existing one will be removed. Note that none is a keyword, not a filename, and therefore is not enclosed in double quotes. recursing-file The pathname of the file the server dumps the queries that are currently recursing when instructed to do so with rndc recursing. If not specified, the default is named.recursing. statistics-file The pathname of the file the server appends statistics to when instructed to do so using rndc stats. If not specified, the default is named.stats in the server's current directory. The format of the file is described in . bindkeys-file The pathname of a file to override the built-in trusted keys provided by named. See the discussion of dnssec-lookaside and dnssec-validation for details. If not specified, the default is /etc/bind.keys. secroots-file The pathname of the file the server dumps security roots to when instructed to do so with rndc secroots. If not specified, the default is named.secroots. session-keyfile The pathname of the file into which to write a TSIG session key generated by named for use by nsupdate -l. If not specified, the default is /var/run/named/session.key. (See , and in particular the discussion of the update-policy statement's local option for more information about this feature.) session-keyname The key name to use for the TSIG session key. If not specified, the default is "local-ddns". session-keyalg The algorithm to use for the TSIG session key. Valid values are hmac-sha1, hmac-sha224, hmac-sha256, hmac-sha384, hmac-sha512 and hmac-md5. If not specified, the default is hmac-sha256. port The UDP/TCP port number the server uses for receiving and sending DNS protocol traffic. The default is 53. This option is mainly intended for server testing; a server using a port other than 53 will not be able to communicate with the global DNS. dscp The global Differentiated Services Code Point (DSCP) value to classify outgoing DNS traffic on operating systems that support DSCP. Valid values are 0 through 63. It is not configured by default. random-device The source of entropy to be used by the server. Entropy is primarily needed for DNSSEC operations, such as TKEY transactions and dynamic update of signed zones. This options specifies the device (or file) from which to read entropy. If this is a file, operations requiring entropy will fail when the file has been exhausted. If not specified, the default value is /dev/random (or equivalent) when present, and none otherwise. The random-device option takes effect during the initial configuration load at server startup time and is ignored on subsequent reloads. preferred-glue If specified, the listed type (A or AAAA) will be emitted before other glue in the additional section of a query response. The default is not to prefer any type (NONE). root-delegation-only Turn on enforcement of delegation-only in TLDs (top level domains) and root zones with an optional exclude list. DS queries are expected to be made to and be answered by delegation only zones. Such queries and responses are treated as an exception to delegation-only processing and are not converted to NXDOMAIN responses provided a CNAME is not discovered at the query name. If a delegation only zone server also serves a child zone it is not always possible to determine whether an answer comes from the delegation only zone or the child zone. SOA NS and DNSKEY records are apex only records and a matching response that contains these records or DS is treated as coming from a child zone. RRSIG records are also examined to see if they are signed by a child zone or not. The authority section is also examined to see if there is evidence that the answer is from the child zone. Answers that are determined to be from a child zone are not converted to NXDOMAIN responses. Despite all these checks there is still a possibility of false negatives when a child zone is being served. Similarly false positives can arise from empty nodes (no records at the name) in the delegation only zone when the query type is not ANY. Note some TLDs are not delegation only (e.g. "DE", "LV", "US" and "MUSEUM"). This list is not exhaustive. options { root-delegation-only exclude { "de"; "lv"; "us"; "museum"; }; }; disable-algorithms Disable the specified DNSSEC algorithms at and below the specified name. Multiple disable-algorithms statements are allowed. Only the best match disable-algorithms clause will be used to determine which algorithms are used. If all supported algorithms are disabled, the zones covered by the disable-algorithms will be treated as insecure. disable-ds-digests Disable the specified DS/DLV digest types at and below the specified name. Multiple disable-ds-digests statements are allowed. Only the best match disable-ds-digests clause will be used to determine which digest types are used. If all supported digest types are disabled, the zones covered by the disable-ds-digests will be treated as insecure. dnssec-lookaside When set, dnssec-lookaside provides the validator with an alternate method to validate DNSKEY records at the top of a zone. When a DNSKEY is at or below a domain specified by the deepest dnssec-lookaside, and the normal DNSSEC validation has left the key untrusted, the trust-anchor will be appended to the key name and a DLV record will be looked up to see if it can validate the key. If the DLV record validates a DNSKEY (similarly to the way a DS record does) the DNSKEY RRset is deemed to be trusted. If dnssec-lookaside is set to auto, then built-in default values for the DLV domain and trust anchor will be used, along with a built-in key for validation. If dnssec-lookaside is set to no, then dnssec-lookaside is not used. The default DLV key is stored in the file bind.keys; named will load that key at startup if dnssec-lookaside is set to auto. A copy of the file is installed along with BIND 9, and is current as of the release date. If the DLV key expires, a new copy of bind.keys can be downloaded from https://www.isc.org/solutions/dlv/. (To prevent problems if bind.keys is not found, the current key is also compiled in to named. Relying on this is not recommended, however, as it requires named to be recompiled with a new key when the DLV key expires.) NOTE: named only loads certain specific keys from bind.keys: those for the DLV zone and for the DNS root zone. The file cannot be used to store keys for other zones. dnssec-must-be-secure Specify hierarchies which must be or may not be secure (signed and validated). If yes, then named will only accept answers if they are secure. If no, then normal DNSSEC validation applies allowing for insecure answers to be accepted. The specified domain must be under a trusted-keys or managed-keys statement, or dnssec-lookaside must be active. dns64 This directive instructs named to return mapped IPv4 addresses to AAAA queries when there are no AAAA records. It is intended to be used in conjunction with a NAT64. Each dns64 defines one DNS64 prefix. Multiple DNS64 prefixes can be defined. Compatible IPv6 prefixes have lengths of 32, 40, 48, 56, 64 and 96 as per RFC 6052. Additionally a reverse IP6.ARPA zone will be created for the prefix to provide a mapping from the IP6.ARPA names to the corresponding IN-ADDR.ARPA names using synthesized CNAMEs. dns64-server and dns64-contact can be used to specify the name of the server and contact for the zones. These are settable at the view / options level. These are not settable on a per-prefix basis. Each dns64 supports an optional clients ACL that determines which clients are affected by this directive. If not defined, it defaults to any;. Each dns64 supports an optional mapped ACL that selects which IPv4 addresses are to be mapped in the corresponding A RRset. If not defined it defaults to any;. Normally, DNS64 won't apply to a domain name that owns one or more AAAA records; these records will simply be returned. The optional exclude ACL allows specification of a list of IPv6 addresses that will be ignored if they appear in a domain name's AAAA records, and DNS64 will be applied to any A records the domain name owns. If not defined, exclude defaults to none. A optional suffix can also be defined to set the bits trailing the mapped IPv4 address bits. By default these bits are set to ::. The bits matching the prefix and mapped IPv4 address must be zero. If recursive-only is set to yes the DNS64 synthesis will only happen for recursive queries. The default is no. If break-dnssec is set to yes the DNS64 synthesis will happen even if the result, if validated, would cause a DNSSEC validation failure. If this option is set to no (the default), the DO is set on the incoming query, and there are RRSIGs on the applicable records, then synthesis will not happen. acl rfc1918 { 10/8; 192.168/16; 172.16/12; }; dns64 64:FF9B::/96 { clients { any; }; mapped { !rfc1918; any; }; exclude { 64:FF9B::/96; ::ffff:0000:0000/96; }; suffix ::; }; dnssec-update-mode If this option is set to its default value of maintain in a zone of type master which is DNSSEC-signed and configured to allow dynamic updates (see ), and if named has access to the private signing key(s) for the zone, then named will automatically sign all new or changed records and maintain signatures for the zone by regenerating RRSIG records whenever they approach their expiration date. If the option is changed to no-resign, then named will sign all new or changed records, but scheduled maintenance of signatures is disabled. With either of these settings, named will reject updates to a DNSSEC-signed zone when the signing keys are inactive or unavailable to named. (A planned third option, external, will disable all automatic signing and allow DNSSEC data to be submitted into a zone via dynamic update; this is not yet implemented.) max-zone-ttl Specifies a maximum permissible TTL value. When loading a zone file using a of text or raw, any record encountered with a TTL higher than will cause the zone to be rejected. This is useful in DNSSEC-signed zones because when rolling to a new DNSKEY, the old key needs to remain available until RRSIG records have expired from caches. The option guarantees that the largest TTL in the zone will be no higher the set value. (NOTE: Because map-format files load directly into memory, this option cannot be used with them.) zone-statistics If full, the server will collect statistical data on all zones (unless specifically turned off on a per-zone basis by specifying zone-statistics terse or zone-statistics none in the zone statement). The default is terse, providing minimal statistics on zones (including name and current serial number, but not query type counters). These statistics may be accessed via the statistics-channel or using rndc stats, which will dump them to the file listed in the statistics-file. See also . For backward compatibility with earlier versions of BIND 9, the zone-statistics option can also accept yes or no; yes has the same meaning as full. As of BIND 9.10, no has the same meaning as none; previously, it was the same as terse. Boolean Options automatic-interface-scan If yes and supported by the OS, automatically rescan network interfaces when the interface addresses are added or removed. The default is yes. Currently the OS needs to support routing sockets for automatic-interface-scan to be supported. allow-new-zones If yes, then zones can be added at runtime via rndc addzone or deleted via rndc delzone. The default is no. auth-nxdomain If yes, then the AA bit is always set on NXDOMAIN responses, even if the server is not actually authoritative. The default is no; this is a change from BIND 8. If you are using very old DNS software, you may need to set it to yes. deallocate-on-exit This option was used in BIND 8 to enable checking for memory leaks on exit. BIND 9 ignores the option and always performs the checks. memstatistics Write memory statistics to the file specified by memstatistics-file at exit. The default is no unless '-m record' is specified on the command line in which case it is yes. dialup If yes, then the server treats all zones as if they are doing zone transfers across a dial-on-demand dialup link, which can be brought up by traffic originating from this server. This has different effects according to zone type and concentrates the zone maintenance so that it all happens in a short interval, once every heartbeat-interval and hopefully during the one call. It also suppresses some of the normal zone maintenance traffic. The default is no. The dialup option may also be specified in the view and zone statements, in which case it overrides the global dialup option. If the zone is a master zone, then the server will send out a NOTIFY request to all the slaves (default). This should trigger the zone serial number check in the slave (providing it supports NOTIFY) allowing the slave to verify the zone while the connection is active. The set of servers to which NOTIFY is sent can be controlled by notify and also-notify. If the zone is a slave or stub zone, then the server will suppress the regular "zone up to date" (refresh) queries and only perform them when the heartbeat-interval expires in addition to sending NOTIFY requests. Finer control can be achieved by using notify which only sends NOTIFY messages, notify-passive which sends NOTIFY messages and suppresses the normal refresh queries, refresh which suppresses normal refresh processing and sends refresh queries when the heartbeat-interval expires, and passive which just disables normal refresh processing. dialup mode normal refresh heart-beat refresh heart-beat notify no (default) yes no no yes no yes yes notify yes no yes refresh no yes no passive no no no notify-passive no no yes Note that normal NOTIFY processing is not affected by dialup. fake-iquery In BIND 8, this option enabled simulating the obsolete DNS query type IQUERY. BIND 9 never does IQUERY simulation. fetch-glue This option is obsolete. In BIND 8, fetch-glue yes caused the server to attempt to fetch glue resource records it didn't have when constructing the additional data section of a response. This is now considered a bad idea and BIND 9 never does it. flush-zones-on-shutdown When the nameserver exits due receiving SIGTERM, flush or do not flush any pending zone writes. The default is flush-zones-on-shutdown no. has-old-clients This option was incorrectly implemented in BIND 8, and is ignored by BIND 9. To achieve the intended effect of has-old-clients yes, specify the two separate options auth-nxdomain yes and rfc2308-type1 no instead. host-statistics In BIND 8, this enables keeping of statistics for every host that the name server interacts with. Not implemented in BIND 9. maintain-ixfr-base This option is obsolete. It was used in BIND 8 to determine whether a transaction log was kept for Incremental Zone Transfer. BIND 9 maintains a transaction log whenever possible. If you need to disable outgoing incremental zone transfers, use provide-ixfr no. minimal-responses If yes, then when generating responses the server will only add records to the authority and additional data sections when they are required (e.g. delegations, negative responses). This may improve the performance of the server. The default is no. multiple-cnames This option was used in BIND 8 to allow a domain name to have multiple CNAME records in violation of the DNS standards. BIND 9.2 onwards always strictly enforces the CNAME rules both in master files and dynamic updates. notify If yes (the default), DNS NOTIFY messages are sent when a zone the server is authoritative for changes, see . The messages are sent to the servers listed in the zone's NS records (except the master server identified in the SOA MNAME field), and to any servers listed in the also-notify option. If master-only, notifies are only sent for master zones. If explicit, notifies are sent only to servers explicitly listed using also-notify. If no, no notifies are sent. The notify option may also be specified in the zone statement, in which case it overrides the options notify statement. It would only be necessary to turn off this option if it caused slaves to crash. notify-to-soa If yes do not check the nameservers in the NS RRset against the SOA MNAME. Normally a NOTIFY message is not sent to the SOA MNAME (SOA ORIGIN) as it is supposed to contain the name of the ultimate master. Sometimes, however, a slave is listed as the SOA MNAME in hidden master configurations and in that case you would want the ultimate master to still send NOTIFY messages to all the nameservers listed in the NS RRset. recursion If yes, and a DNS query requests recursion, then the server will attempt to do all the work required to answer the query. If recursion is off and the server does not already know the answer, it will return a referral response. The default is yes. Note that setting recursion no does not prevent clients from getting data from the server's cache; it only prevents new data from being cached as an effect of client queries. Caching may still occur as an effect the server's internal operation, such as NOTIFY address lookups. See also fetch-glue above. request-nsid If yes, then an empty EDNS(0) NSID (Name Server Identifier) option is sent with all queries to authoritative name servers during iterative resolution. If the authoritative server returns an NSID option in its response, then its contents are logged in the resolver category at level info. The default is no. request-sit If yes, then a SIT (Source Identity Token) EDNS option is sent along with the query. If the resolver has previously talked to the server, the SIT returned in the previous transaction is sent. This is used by the server to determine whether the resolver has talked to it before. A resolver sending the correct SIT is assumed not to be an off-path attacker sending a spoofed-source query; the query is therefore unlikely to be part of a reflection/amplification attack, so resolvers sending a correct SIT option are not subject to response rate limiting (RRL). Resolvers which do not send a correct SIT option may be limited to receiving smaller responses via the nosit-udp-size option. sit-secret If set, this is a shared secret used for generating and verifying Source Identity Token EDNS options within a anycast cluster. If not set the system will generate a random secret at startup. The shared secret is encoded as a hex string and needs to be 128 bits for AES128, 160 bits for SHA1 and 256 bits for SHA256. rfc2308-type1 Setting this to yes will cause the server to send NS records along with the SOA record for negative answers. The default is no. Not yet implemented in BIND 9. use-id-pool This option is obsolete. BIND 9 always allocates query IDs from a pool. use-ixfr This option is obsolete. If you need to disable IXFR to a particular server or servers, see the information on the provide-ixfr option in . See also . provide-ixfr See the description of provide-ixfr in . request-ixfr See the description of request-ixfr in . treat-cr-as-space This option was used in BIND 8 to make the server treat carriage return ("\r") characters the same way as a space or tab character, to facilitate loading of zone files on a UNIX system that were generated on an NT or DOS machine. In BIND 9, both UNIX "\n" and NT/DOS "\r\n" newlines are always accepted, and the option is ignored. additional-from-auth additional-from-cache These options control the behavior of an authoritative server when answering queries which have additional data, or when following CNAME and DNAME chains. When both of these options are set to yes (the default) and a query is being answered from authoritative data (a zone configured into the server), the additional data section of the reply will be filled in using data from other authoritative zones and from the cache. In some situations this is undesirable, such as when there is concern over the correctness of the cache, or in servers where slave zones may be added and modified by untrusted third parties. Also, avoiding the search for this additional data will speed up server operations at the possible expense of additional queries to resolve what would otherwise be provided in the additional section. For example, if a query asks for an MX record for host foo.example.com, and the record found is "MX 10 mail.example.net", normally the address records (A and AAAA) for mail.example.net will be provided as well, if known, even though they are not in the example.com zone. Setting these options to no disables this behavior and makes the server only search for additional data in the zone it answers from. These options are intended for use in authoritative-only servers, or in authoritative-only views. Attempts to set them to no without also specifying recursion no will cause the server to ignore the options and log a warning message. Specifying additional-from-cache no actually disables the use of the cache not only for additional data lookups but also when looking up the answer. This is usually the desired behavior in an authoritative-only server where the correctness of the cached data is an issue. When a name server is non-recursively queried for a name that is not below the apex of any served zone, it normally answers with an "upwards referral" to the root servers or the servers of some other known parent of the query name. Since the data in an upwards referral comes from the cache, the server will not be able to provide upwards referrals when additional-from-cache no has been specified. Instead, it will respond to such queries with REFUSED. This should not cause any problems since upwards referrals are not required for the resolution process. match-mapped-addresses If yes, then an IPv4-mapped IPv6 address will match any address match list entries that match the corresponding IPv4 address. This option was introduced to work around a kernel quirk in some operating systems that causes IPv4 TCP connections, such as zone transfers, to be accepted on an IPv6 socket using mapped addresses. This caused address match lists designed for IPv4 to fail to match. However, named now solves this problem internally. The use of this option is discouraged. filter-aaaa-on-v4 This option is only available when BIND 9 is compiled with the --enable-filter-aaaa option on the "configure" command line. It is intended to help the transition from IPv4 to IPv6 by not giving IPv6 addresses to DNS clients unless they have connections to the IPv6 Internet. This is not recommended unless absolutely necessary. The default is no. The filter-aaaa-on-v4 option may also be specified in view statements to override the global filter-aaaa-on-v4 option. If yes, the DNS client is at an IPv4 address, in filter-aaaa, and if the response does not include DNSSEC signatures, then all AAAA records are deleted from the response. This filtering applies to all responses and not only authoritative responses. If break-dnssec, then AAAA records are deleted even when DNSSEC is enabled. As suggested by the name, this makes the response not verify, because the DNSSEC protocol is designed detect deletions. This mechanism can erroneously cause other servers to not give AAAA records to their clients. A recursing server with both IPv6 and IPv4 network connections that queries an authoritative server using this mechanism via IPv4 will be denied AAAA records even if its client is using IPv6. This mechanism is applied to authoritative as well as non-authoritative records. A client using IPv4 that is not allowed recursion can erroneously be given AAAA records because the server is not allowed to check for A records. Some AAAA records are given to IPv4 clients in glue records. IPv4 clients that are servers can then erroneously answer requests for AAAA records received via IPv4. filter-aaaa-on-v6 Identical to filter-aaaa-on-v4, except it filters AAAA responses to queries from IPv6 clients instead of IPv4 clients. To filter all responses, set both options to yes. ixfr-from-differences When yes and the server loads a new version of a master zone from its zone file or receives a new version of a slave file via zone transfer, it will compare the new version to the previous one and calculate a set of differences. The differences are then logged in the zone's journal file such that the changes can be transmitted to downstream slaves as an incremental zone transfer. By allowing incremental zone transfers to be used for non-dynamic zones, this option saves bandwidth at the expense of increased CPU and memory consumption at the master. In particular, if the new version of a zone is completely different from the previous one, the set of differences will be of a size comparable to the combined size of the old and new zone version, and the server will need to temporarily allocate memory to hold this complete difference set. ixfr-from-differences also accepts master and slave at the view and options levels which causes ixfr-from-differences to be enabled for all master or slave zones respectively. It is off by default. multi-master This should be set when you have multiple masters for a zone and the addresses refer to different machines. If yes, named will not log when the serial number on the master is less than what named currently has. The default is no. dnssec-enable This indicates whether DNSSEC-related resource records are to be returned by named. If set to no, named will not return DNSSEC-related resource records unless specifically queried for. The default is yes. dnssec-validation Enable DNSSEC validation in named. Note dnssec-enable also needs to be set to yes to be effective. If set to no, DNSSEC validation is disabled. If set to auto, DNSSEC validation is enabled, and a default trust-anchor for the DNS root zone is used. If set to yes, DNSSEC validation is enabled, but a trust anchor must be manually configured using a trusted-keys or managed-keys statement. The default is yes. Whenever the resolver sends out queries to an EDNS-compliant server, it always sets the DO bit indicating it can support DNSSEC responses even if dnssec-validation is off. dnssec-accept-expired Accept expired signatures when verifying DNSSEC signatures. The default is no. Setting this option to yes leaves named vulnerable to replay attacks. querylog Specify whether query logging should be started when named starts. If querylog is not specified, then the query logging is determined by the presence of the logging category queries. check-names This option is used to restrict the character set and syntax of certain domain names in master files and/or DNS responses received from the network. The default varies according to usage area. For master zones the default is fail. For slave zones the default is warn. For answers received from the network (response) the default is ignore. The rules for legal hostnames and mail domains are derived from RFC 952 and RFC 821 as modified by RFC 1123. check-names applies to the owner names of A, AAAA and MX records. It also applies to the domain names in the RDATA of NS, SOA, MX, and SRV records. It also applies to the RDATA of PTR records where the owner name indicated that it is a reverse lookup of a hostname (the owner name ends in IN-ADDR.ARPA, IP6.ARPA, or IP6.INT). check-dup-records Check master zones for records that are treated as different by DNSSEC but are semantically equal in plain DNS. The default is to warn. Other possible values are fail and ignore. check-mx Check whether the MX record appears to refer to a IP address. The default is to warn. Other possible values are fail and ignore. check-wildcard This option is used to check for non-terminal wildcards. The use of non-terminal wildcards is almost always as a result of a failure to understand the wildcard matching algorithm (RFC 1034). This option affects master zones. The default (yes) is to check for non-terminal wildcards and issue a warning. check-integrity Perform post load zone integrity checks on master zones. This checks that MX and SRV records refer to address (A or AAAA) records and that glue address records exist for delegated zones. For MX and SRV records only in-zone hostnames are checked (for out-of-zone hostnames use named-checkzone). For NS records only names below top of zone are checked (for out-of-zone names and glue consistency checks use named-checkzone). The default is yes. The use of the SPF record for publishing Sender Policy Framework is deprecated as the migration from using TXT records to SPF records was abandoned. Enabling this option also checks that a TXT Sender Policy Framework record exists (starts with "v=spf1") if there is an SPF record. Warnings are emitted if the TXT record does not exist and can be suppressed with check-spf. check-mx-cname If check-integrity is set then fail, warn or ignore MX records that refer to CNAMES. The default is to warn. check-srv-cname If check-integrity is set then fail, warn or ignore SRV records that refer to CNAMES. The default is to warn. check-sibling When performing integrity checks, also check that sibling glue exists. The default is yes. check-spf If check-integrity is set then check that there is a TXT Sender Policy Framework record present (starts with "v=spf1") if there is an SPF record present. The default is warn. zero-no-soa-ttl When returning authoritative negative responses to SOA queries set the TTL of the SOA record returned in the authority section to zero. The default is yes. zero-no-soa-ttl-cache When caching a negative response to a SOA query set the TTL to zero. The default is no. update-check-ksk When set to the default value of yes, check the KSK bit in each key to determine how the key should be used when generating RRSIGs for a secure zone. Ordinarily, zone-signing keys (that is, keys without the KSK bit set) are used to sign the entire zone, while key-signing keys (keys with the KSK bit set) are only used to sign the DNSKEY RRset at the zone apex. However, if this option is set to no, then the KSK bit is ignored; KSKs are treated as if they were ZSKs and are used to sign the entire zone. This is similar to the dnssec-signzone -z command line option. When this option is set to yes, there must be at least two active keys for every algorithm represented in the DNSKEY RRset: at least one KSK and one ZSK per algorithm. If there is any algorithm for which this requirement is not met, this option will be ignored for that algorithm. dnssec-dnskey-kskonly When this option and update-check-ksk are both set to yes, only key-signing keys (that is, keys with the KSK bit set) will be used to sign the DNSKEY RRset at the zone apex. Zone-signing keys (keys without the KSK bit set) will be used to sign the remainder of the zone, but not the DNSKEY RRset. This is similar to the dnssec-signzone -x command line option. The default is no. If update-check-ksk is set to no, this option is ignored. dnssec-loadkeys-interval When a zone is configured with auto-dnssec maintain; its key repository must be checked periodically to see if any new keys have been added or any existing keys' timing metadata has been updated (see and ). The dnssec-loadkeys-interval option sets the frequency of automatic repository checks, in minutes. The default is 60 (1 hour), the minimum is 1 (1 minute), and the maximum is 1440 (24 hours); any higher value is silently reduced. try-tcp-refresh Try to refresh the zone using TCP if UDP queries fail. For BIND 8 compatibility, the default is yes. dnssec-secure-to-insecure Allow a dynamic zone to transition from secure to insecure (i.e., signed to unsigned) by deleting all of the DNSKEY records. The default is no. If set to yes, and if the DNSKEY RRset at the zone apex is deleted, all RRSIG and NSEC records will be removed from the zone as well. If the zone uses NSEC3, then it is also necessary to delete the NSEC3PARAM RRset from the zone apex; this will cause the removal of all corresponding NSEC3 records. (It is expected that this requirement will be eliminated in a future release.) Note that if a zone has been configured with auto-dnssec maintain and the private keys remain accessible in the key repository, then the zone will be automatically signed again the next time named is started. Forwarding The forwarding facility can be used to create a large site-wide cache on a few servers, reducing traffic over links to external name servers. It can also be used to allow queries by servers that do not have direct access to the Internet, but wish to look up exterior names anyway. Forwarding occurs only on those queries for which the server is not authoritative and does not have the answer in its cache. forward This option is only meaningful if the forwarders list is not empty. A value of first, the default, causes the server to query the forwarders first — and if that doesn't answer the question, the server will then look for the answer itself. If only is specified, the server will only query the forwarders. forwarders Specifies the IP addresses to be used for forwarding. The default is the empty list (no forwarding). Forwarding can also be configured on a per-domain basis, allowing for the global forwarding options to be overridden in a variety of ways. You can set particular domains to use different forwarders, or have a different forward only/first behavior, or not forward at all, see . Dual-stack Servers Dual-stack servers are used as servers of last resort to work around problems in reachability due the lack of support for either IPv4 or IPv6 on the host machine. dual-stack-servers Specifies host names or addresses of machines with access to both IPv4 and IPv6 transports. If a hostname is used, the server must be able to resolve the name using only the transport it has. If the machine is dual stacked, then the dual-stack-servers have no effect unless access to a transport has been disabled on the command line (e.g. named -4). Access Control Access to the server can be restricted based on the IP address of the requesting system. See for details on how to specify IP address lists. allow-notify Specifies which hosts are allowed to notify this server, a slave, of zone changes in addition to the zone masters. allow-notify may also be specified in the zone statement, in which case it overrides the options allow-notify statement. It is only meaningful for a slave zone. If not specified, the default is to process notify messages only from a zone's master. allow-query Specifies which hosts are allowed to ask ordinary DNS questions. allow-query may also be specified in the zone statement, in which case it overrides the options allow-query statement. If not specified, the default is to allow queries from all hosts. allow-query-cache is now used to specify access to the cache. allow-query-on Specifies which local addresses can accept ordinary DNS questions. This makes it possible, for instance, to allow queries on internal-facing interfaces but disallow them on external-facing ones, without necessarily knowing the internal network's addresses. Note that allow-query-on is only checked for queries that are permitted by allow-query. A query must be allowed by both ACLs, or it will be refused. allow-query-on may also be specified in the zone statement, in which case it overrides the options allow-query-on statement. If not specified, the default is to allow queries on all addresses. allow-query-cache is used to specify access to the cache. allow-query-cache Specifies which hosts are allowed to get answers from the cache. If allow-query-cache is not set then allow-recursion is used if set, otherwise allow-query is used if set unless recursion no; is set in which case none; is used, otherwise the default (localnets; localhost;) is used. allow-query-cache-on Specifies which local addresses can give answers from the cache. If not specified, the default is to allow cache queries on any address, localnets and localhost. allow-recursion Specifies which hosts are allowed to make recursive queries through this server. If allow-recursion is not set then allow-query-cache is used if set, otherwise allow-query is used if set, otherwise the default (localnets; localhost;) is used. allow-recursion-on Specifies which local addresses can accept recursive queries. If not specified, the default is to allow recursive queries on all addresses. allow-update Specifies which hosts are allowed to submit Dynamic DNS updates for master zones. The default is to deny updates from all hosts. Note that allowing updates based on the requestor's IP address is insecure; see for details. allow-update-forwarding Specifies which hosts are allowed to submit Dynamic DNS updates to slave zones to be forwarded to the master. The default is { none; }, which means that no update forwarding will be performed. To enable update forwarding, specify allow-update-forwarding { any; };. Specifying values other than { none; } or { any; } is usually counterproductive, since the responsibility for update access control should rest with the master server, not the slaves. Note that enabling the update forwarding feature on a slave server may expose master servers relying on insecure IP address based access control to attacks; see for more details. allow-v6-synthesis This option was introduced for the smooth transition from AAAA to A6 and from "nibble labels" to binary labels. However, since both A6 and binary labels were then deprecated, this option was also deprecated. It is now ignored with some warning messages. allow-transfer Specifies which hosts are allowed to receive zone transfers from the server. allow-transfer may also be specified in the zone statement, in which case it overrides the options allow-transfer statement. If not specified, the default is to allow transfers to all hosts. blackhole Specifies a list of addresses that the server will not accept queries from or use to resolve a query. Queries from these addresses will not be responded to. The default is none. filter-aaaa Specifies a list of addresses to which filter-aaaa-on-v4 is applies. The default is any. no-case-compress Specifies a list of addresses which require responses to use case-insensitive compression. This ACL can be used when named needs to work with clients that do not comply with the requirement in RFC 1034 to use case-insensitive name comparisons when checking for matching domain names. If left undefined, the ACL defaults to none: case-insensitive compression will be used for all clients. If the ACL is defined and matches a client, then case will be ignored when compressing domain names in DNS responses sent to that client. This can result in slightly smaller responses: if a response contains the names "example.com" and "example.COM", case-insensitive compression would treat the second one as a duplicate. It also ensures that the case of the query name exactly matches the case of the owner names of returned records, rather than matching the case of the records entered in the zone file. This allows responses to exactly match the query, which is required by some clients due to incorrect use of case-sensitive comparisons. Case-insensitive compression is always used in AXFR and IXFR responses, regardless of whether the client matches this ACL. There are circumstances in which named will not preserve the case of owner names of records: if a zone file defines records of different types with the same name, but the capitalization of the name is different (e.g., "www.example.com/A" and "WWW.EXAMPLE.COM/AAAA"), then all responses for that name will use the first version of the name that was used in the zone file. This limitation may be addressed in a future release. However, domain names specified in the rdata of resource records (i.e., records of type NS, MX, CNAME, etc) will always have their case preserved unless the client matches this ACL. resolver-query-timeout The amount of time the resolver will spend attempting to resolve a recursive query before failing. The default and minimum is 10 and the maximum is 30. Setting it to 0 will result in the default being used. Interfaces The interfaces and ports that the server will answer queries from may be specified using the listen-on option. listen-on takes an optional port and an address_match_list of IPv4 addresses. (IPv6 addresses are ignored, with a logged warning.) The server will listen on all interfaces allowed by the address match list. If a port is not specified, port 53 will be used. Multiple listen-on statements are allowed. For example, listen-on { 5.6.7.8; }; listen-on port 1234 { !1.2.3.4; 1.2/16; }; will enable the name server on port 53 for the IP address 5.6.7.8, and on port 1234 of an address on the machine in net 1.2 that is not 1.2.3.4. If no listen-on is specified, the server will listen on port 53 on all IPv4 interfaces. The listen-on-v6 option is used to specify the interfaces and the ports on which the server will listen for incoming queries sent using IPv6. If not specified, the server will listen on port 53 on all IPv6 interfaces. When { any; } is specified as the address_match_list for the listen-on-v6 option, the server does not bind a separate socket to each IPv6 interface address as it does for IPv4 if the operating system has enough API support for IPv6 (specifically if it conforms to RFC 3493 and RFC 3542). Instead, it listens on the IPv6 wildcard address. If the system only has incomplete API support for IPv6, however, the behavior is the same as that for IPv4. A list of particular IPv6 addresses can also be specified, in which case the server listens on a separate socket for each specified address, regardless of whether the desired API is supported by the system. IPv4 addresses specified in listen-on-v6 will be ignored, with a logged warning. Multiple listen-on-v6 options can be used. For example, listen-on-v6 { any; }; listen-on-v6 port 1234 { !2001:db8::/32; any; }; will enable the name server on port 53 for any IPv6 addresses (with a single wildcard socket), and on port 1234 of IPv6 addresses that is not in the prefix 2001:db8::/32 (with separate sockets for each matched address.) To make the server not listen on any IPv6 address, use listen-on-v6 { none; }; Query Address If the server doesn't know the answer to a question, it will query other name servers. query-source specifies the address and port used for such queries. For queries sent over IPv6, there is a separate query-source-v6 option. If address is * (asterisk) or is omitted, a wildcard IP address (INADDR_ANY) will be used. If port is * or is omitted, a random port number from a pre-configured range is picked up and will be used for each query. The port range(s) is that specified in the use-v4-udp-ports (for IPv4) and use-v6-udp-ports (for IPv6) options, excluding the ranges specified in the avoid-v4-udp-ports and avoid-v6-udp-ports options, respectively. The defaults of the query-source and query-source-v6 options are: query-source address * port *; query-source-v6 address * port *; If use-v4-udp-ports or use-v6-udp-ports is unspecified, named will check if the operating system provides a programming interface to retrieve the system's default range for ephemeral ports. If such an interface is available, named will use the corresponding system default range; otherwise, it will use its own defaults: use-v4-udp-ports { range 1024 65535; }; use-v6-udp-ports { range 1024 65535; }; Note: make sure the ranges be sufficiently large for security. A desirable size depends on various parameters, but we generally recommend it contain at least 16384 ports (14 bits of entropy). Note also that the system's default range when used may be too small for this purpose, and that the range may even be changed while named is running; the new range will automatically be applied when named is reloaded. It is encouraged to configure use-v4-udp-ports and use-v6-udp-ports explicitly so that the ranges are sufficiently large and are reasonably independent from the ranges used by other applications. Note: the operational configuration where named runs may prohibit the use of some ports. For example, UNIX systems will not allow named running without a root privilege to use ports less than 1024. If such ports are included in the specified (or detected) set of query ports, the corresponding query attempts will fail, resulting in resolution failures or delay. It is therefore important to configure the set of ports that can be safely used in the expected operational environment. The defaults of the avoid-v4-udp-ports and avoid-v6-udp-ports options are: avoid-v4-udp-ports {}; avoid-v6-udp-ports {}; Note: BIND 9.5.0 introduced the use-queryport-pool option to support a pool of such random ports, but this option is now obsolete because reusing the same ports in the pool may not be sufficiently secure. For the same reason, it is generally strongly discouraged to specify a particular port for the query-source or query-source-v6 options; it implicitly disables the use of randomized port numbers. use-queryport-pool This option is obsolete. queryport-pool-ports This option is obsolete. queryport-pool-updateinterval This option is obsolete. The address specified in the query-source option is used for both UDP and TCP queries, but the port applies only to UDP queries. TCP queries always use a random unprivileged port. Solaris 2.5.1 and earlier does not support setting the source address for TCP sockets. See also transfer-source and notify-source. Zone Transfers BIND has mechanisms in place to facilitate zone transfers and set limits on the amount of load that transfers place on the system. The following options apply to zone transfers. also-notify Defines a global list of IP addresses of name servers that are also sent NOTIFY messages whenever a fresh copy of the zone is loaded, in addition to the servers listed in the zone's NS records. This helps to ensure that copies of the zones will quickly converge on stealth servers. Optionally, a port may be specified with each also-notify address to send the notify messages to a port other than the default of 53. An optional TSIG key can also be specified with each address to cause the notify messages to be signed; this can be useful when sending notifies to multiple views. In place of explicit addresses, one or more named masters lists can be used. If an also-notify list is given in a zone statement, it will override the options also-notify statement. When a zone notify statement is set to no, the IP addresses in the global also-notify list will not be sent NOTIFY messages for that zone. The default is the empty list (no global notification list). max-transfer-time-in Inbound zone transfers running longer than this many minutes will be terminated. The default is 120 minutes (2 hours). The maximum value is 28 days (40320 minutes). max-transfer-idle-in Inbound zone transfers making no progress in this many minutes will be terminated. The default is 60 minutes (1 hour). The maximum value is 28 days (40320 minutes). max-transfer-time-out Outbound zone transfers running longer than this many minutes will be terminated. The default is 120 minutes (2 hours). The maximum value is 28 days (40320 minutes). max-transfer-idle-out Outbound zone transfers making no progress in this many minutes will be terminated. The default is 60 minutes (1 hour). The maximum value is 28 days (40320 minutes). serial-query-rate Slave servers will periodically query master servers to find out if zone serial numbers have changed. Each such query uses a minute amount of the slave server's network bandwidth. To limit the amount of bandwidth used, BIND 9 limits the rate at which queries are sent. The value of the serial-query-rate option, an integer, is the maximum number of queries sent per second. The default is 20 per second. The lowest possible rate is one per second; when set to zero, it will be silently raised to one. In addition to controlling the rate SOA refresh queries are issued at, serial-query-rate also controls the rate at which NOTIFY messages are sent from both master and slave zones. serial-queries In BIND 8, the serial-queries option set the maximum number of concurrent serial number queries allowed to be outstanding at any given time. BIND 9 does not limit the number of outstanding serial queries and ignores the serial-queries option. Instead, it limits the rate at which the queries are sent as defined using the serial-query-rate option. transfer-format Zone transfers can be sent using two different formats, one-answer and many-answers. The transfer-format option is used on the master server to determine which format it sends. one-answer uses one DNS message per resource record transferred. many-answers packs as many resource records as possible into a message. many-answers is more efficient, but is only supported by relatively new slave servers, such as BIND 9, BIND 8.x and BIND 4.9.5 onwards. The many-answers format is also supported by recent Microsoft Windows nameservers. The default is many-answers. transfer-format may be overridden on a per-server basis by using the server statement. transfers-in The maximum number of inbound zone transfers that can be running concurrently. The default value is 10. Increasing transfers-in may speed up the convergence of slave zones, but it also may increase the load on the local system. transfers-out The maximum number of outbound zone transfers that can be running concurrently. Zone transfer requests in excess of the limit will be refused. The default value is 10. transfers-per-ns The maximum number of inbound zone transfers that can be concurrently transferring from a given remote name server. The default value is 2. Increasing transfers-per-ns may speed up the convergence of slave zones, but it also may increase the load on the remote name server. transfers-per-ns may be overridden on a per-server basis by using the transfers phrase of the server statement. transfer-source transfer-source determines which local address will be bound to IPv4 TCP connections used to fetch zones transferred inbound by the server. It also determines the source IPv4 address, and optionally the UDP port, used for the refresh queries and forwarded dynamic updates. If not set, it defaults to a system controlled value which will usually be the address of the interface "closest to" the remote end. This address must appear in the remote end's allow-transfer option for the zone being transferred, if one is specified. This statement sets the transfer-source for all zones, but can be overridden on a per-view or per-zone basis by including a transfer-source statement within the view or zone block in the configuration file. Solaris 2.5.1 and earlier does not support setting the source address for TCP sockets. transfer-source-v6 The same as transfer-source, except zone transfers are performed using IPv6. alt-transfer-source An alternate transfer source if the one listed in transfer-source fails and use-alt-transfer-source is set. If you do not wish the alternate transfer source to be used, you should set use-alt-transfer-source appropriately and you should not depend upon getting an answer back to the first refresh query. alt-transfer-source-v6 An alternate transfer source if the one listed in transfer-source-v6 fails and use-alt-transfer-source is set. use-alt-transfer-source Use the alternate transfer sources or not. If views are specified this defaults to no otherwise it defaults to yes (for BIND 8 compatibility). notify-source notify-source determines which local source address, and optionally UDP port, will be used to send NOTIFY messages. This address must appear in the slave server's masters zone clause or in an allow-notify clause. This statement sets the notify-source for all zones, but can be overridden on a per-zone or per-view basis by including a notify-source statement within the zone or view block in the configuration file. Solaris 2.5.1 and earlier does not support setting the source address for TCP sockets. notify-source-v6 Like notify-source, but applies to notify messages sent to IPv6 addresses. UDP Port Lists use-v4-udp-ports, avoid-v4-udp-ports, use-v6-udp-ports, and avoid-v6-udp-ports specify a list of IPv4 and IPv6 UDP ports that will be used or not used as source ports for UDP messages. See about how the available ports are determined. For example, with the following configuration use-v6-udp-ports { range 32768 65535; }; avoid-v6-udp-ports { 40000; range 50000 60000; }; UDP ports of IPv6 messages sent from named will be in one of the following ranges: 32768 to 39999, 40001 to 49999, and 60001 to 65535. avoid-v4-udp-ports and avoid-v6-udp-ports can be used to prevent named from choosing as its random source port a port that is blocked by your firewall or a port that is used by other applications; if a query went out with a source port blocked by a firewall, the answer would not get by the firewall and the name server would have to query again. Note: the desired range can also be represented only with use-v4-udp-ports and use-v6-udp-ports, and the avoid- options are redundant in that sense; they are provided for backward compatibility and to possibly simplify the port specification. Operating System Resource Limits The server's usage of many system resources can be limited. Scaled values are allowed when specifying resource limits. For example, 1G can be used instead of 1073741824 to specify a limit of one gigabyte. unlimited requests unlimited use, or the maximum available amount. default uses the limit that was in force when the server was started. See the description of size_spec in . The following options set operating system resource limits for the name server process. Some operating systems don't support some or any of the limits. On such systems, a warning will be issued if the unsupported limit is used. coresize The maximum size of a core dump. The default is default. datasize The maximum amount of data memory the server may use. The default is default. This is a hard limit on server memory usage. If the server attempts to allocate memory in excess of this limit, the allocation will fail, which may in turn leave the server unable to perform DNS service. Therefore, this option is rarely useful as a way of limiting the amount of memory used by the server, but it can be used to raise an operating system data size limit that is too small by default. If you wish to limit the amount of memory used by the server, use the max-cache-size and recursive-clients options instead. files The maximum number of files the server may have open concurrently. The default is unlimited. stacksize The maximum amount of stack memory the server may use. The default is default. Server Resource Limits The following options set limits on the server's resource consumption that are enforced internally by the server rather than the operating system. max-ixfr-log-size This option is obsolete; it is accepted and ignored for BIND 8 compatibility. The option max-journal-size performs a similar function in BIND 9. max-journal-size Sets a maximum size for each journal file (see ). When the journal file approaches the specified size, some of the oldest transactions in the journal will be automatically removed. The largest permitted value is 2 gigabytes. The default is unlimited, which also means 2 gigabytes. This may also be set on a per-zone basis. host-statistics-max In BIND 8, specifies the maximum number of host statistics entries to be kept. Not implemented in BIND 9. recursive-clients The maximum number ("hard quota") of simultaneous recursive lookups the server will perform on behalf of clients. The default is 1000. Because each recursing client uses a fair bit of memory (on the order of 20 kilobytes), the value of the recursive-clients option may have to be decreased on hosts with limited memory. defines a "hard quota" limit for pending recursive clients: when more clients than this are pending, new incoming requests will not be accepted, and for each incoming request a previous pending request will also be dropped. A "soft quota" is also set. When this lower quota is exceeded, incoming requests are accepted, but for each one, a pending request will be dropped. If is greater than 1000, the soft quota is set to minus 100; otherwise it is set to 90% of . tcp-clients The maximum number of simultaneous client TCP connections that the server will accept. The default is 100. clients-per-query max-clients-per-query These set the initial value (minimum) and maximum number of recursive simultaneous clients for any given query (<qname,qtype,qclass>) that the server will accept before dropping additional clients. named will attempt to self tune this value and changes will be logged. The default values are 10 and 100. This value should reflect how many queries come in for a given name in the time it takes to resolve that name. If the number of queries exceed this value, named will assume that it is dealing with a non-responsive zone and will drop additional queries. If it gets a response after dropping queries, it will raise the estimate. The estimate will then be lowered in 20 minutes if it has remained unchanged. If clients-per-query is set to zero, then there is no limit on the number of clients per query and no queries will be dropped. If max-clients-per-query is set to zero, then there is no upper bound other than imposed by recursive-clients. fetches-per-zone The maximum number of simultaneous iterative queries to any one domain that the server will permit before blocking new queries for data in or beneath that zone. This value should reflect how many fetches would normally be sent to any one zone in the time it would take to resolve them. It should be smaller than . When many clients simultaneously query for the same name and type, the clients will all be attached to the same fetch, up to the limit, and only one iterative query will be sent. However, when clients are simultaneously querying for different names or types, multiple queries will be sent and is not effective as a limit. Optionally, this value may be followed by the keyword drop or fail, indicating whether queries which exceed the fetch quota for a zone will be dropped with no response, or answered with SERVFAIL. The default is drop. If fetches-per-zone is set to zero, then there is no limit on the number of fetches per query and no queries will be dropped. The default is zero. The current list of active fetches can be dumped by running rndc recursing. The list includes the number of active fetches for each domain and the number of queries that have been passed or dropped as a result of the limit. (Note: these counters are not cumulative over time; whenever the number of active fetches for a domain drops to zero, the counter for that domain is deleted, and the next time a fetch is sent to that domain, it is recreated with the counters set to zero.) (Note: This option is only available when BIND is built with configure --enable-fetchlimit.) fetches-per-server The maximum number of simultaneous iterative queries that the server will allow to be sent to a single upstream name server before blocking additional queries. This value should reflect how many fetches would normally be sent to any one server in the time it would take to resolve them. It should be smaller than . Optionally, this value may be followed by the keyword drop or fail, indicating whether queries will be dropped with no response, or answered with SERVFAIL, when all of the servers authoritative for a zone are found to have exceeded the per-server quota. The default is fail. If fetches-per-server is set to zero, then there is no limit on the number of fetches per query and no queries will be dropped. The default is zero. The fetches-per-server quota is dynamically adjusted in response to detected congestion. As queries are sent to a server and are either answered or time out, an exponentially weighted moving average is calculated of the ratio of timeouts to responses. If the current average timeout ratio rises above a "high" threshold, then fetches-per-server is reduced for that server. If the timeout ratio drops below a "low" threshold, then fetches-per-server is increased. The fetch-quota-params options can be used to adjust the parameters for this calculation. (Note: This option is only available when BIND is built with configure --enable-fetchlimit.) fetch-quota-params Sets the parameters to use for dynamic resizing of the quota in response to detected congestion. The first argument is an integer value indicating how frequently to recalculate the moving average of the ratio of timeouts to responses for each server. The default is 100, meaning we recalculate the average ratio after every 100 queries have either been answered or timed out. The remaining three arguments represent the "low" threshold (defaulting to a timeout ratio of 0.1), the "high" threshold (defaulting to a timeout ratio of 0.3), and the discount rate for the moving average (defaulting to 0.7). A higher discount rate causes recent events to weigh more heavily when calculating the moving average; a lower discount rate causes past events to weigh more heavily, smoothing out short-term blips in the timeout ratio. These arguments are all fixed-point numbers with precision of 1/100: at most two places after the decimal point are significant. (Note: This option is only available when BIND is built with configure --enable-fetchlimit.) reserved-sockets The number of file descriptors reserved for TCP, stdio, etc. This needs to be big enough to cover the number of interfaces named listens on, tcp-clients as well as to provide room for outgoing TCP queries and incoming zone transfers. The default is 512. The minimum value is 128 and the maximum value is 128 less than maxsockets (-S). This option may be removed in the future. This option has little effect on Windows. max-cache-size The maximum amount of memory to use for the server's cache, in bytes. When the amount of data in the cache reaches this limit, the server will cause records to expire prematurely based on an LRU based strategy so that the limit is not exceeded. The keyword unlimited, or the value 0, will place no limit on cache size; records will be purged from the cache only when their TTLs expire. Any positive values less than 2MB will be ignored and reset to 2MB. In a server with multiple views, the limit applies separately to the cache of each view. The default is unlimited. tcp-listen-queue The listen queue depth. The default and minimum is 10. If the kernel supports the accept filter "dataready" this also controls how many TCP connections that will be queued in kernel space waiting for some data before being passed to accept. Nonzero values less than 10 will be silently raised. A value of 0 may also be used; on most platforms this sets the listen queue length to a system-defined default value. Periodic Task Intervals cleaning-interval This interval is effectively obsolete. Previously, the server would remove expired resource records from the cache every cleaning-interval minutes. BIND 9 now manages cache memory in a more sophisticated manner and does not rely on the periodic cleaning any more. Specifying this option therefore has no effect on the server's behavior. heartbeat-interval The server will perform zone maintenance tasks for all zones marked as dialup whenever this interval expires. The default is 60 minutes. Reasonable values are up to 1 day (1440 minutes). The maximum value is 28 days (40320 minutes). If set to 0, no zone maintenance for these zones will occur. interface-interval The server will scan the network interface list every interface-interval minutes. The default is 60 minutes. The maximum value is 28 days (40320 minutes). If set to 0, interface scanning will only occur when the configuration file is loaded. After the scan, the server will begin listening for queries on any newly discovered interfaces (provided they are allowed by the listen-on configuration), and will stop listening on interfaces that have gone away. statistics-interval Name server statistics will be logged every statistics-interval minutes. The default is 60. The maximum value is 28 days (40320 minutes). If set to 0, no statistics will be logged. Not yet implemented in BIND 9. Topology All other things being equal, when the server chooses a name server to query from a list of name servers, it prefers the one that is topologically closest to itself. The topology statement takes an address_match_list and interprets it in a special way. Each top-level list element is assigned a distance. Non-negated elements get a distance based on their position in the list, where the closer the match is to the start of the list, the shorter the distance is between it and the server. A negated match will be assigned the maximum distance from the server. If there is no match, the address will get a distance which is further than any non-negated list element, and closer than any negated element. For example, topology { 10/8; !1.2.3/24; { 1.2/16; 3/8; }; }; will prefer servers on network 10 the most, followed by hosts on network 1.2.0.0 (netmask 255.255.0.0) and network 3, with the exception of hosts on network 1.2.3 (netmask 255.255.255.0), which is preferred least of all. The default topology is topology { localhost; localnets; }; The topology option is not implemented in BIND 9. The <command>sortlist</command> Statement The response to a DNS query may consist of multiple resource records (RRs) forming a resource records set (RRset). The name server will normally return the RRs within the RRset in an indeterminate order (but see the rrset-order statement in ). The client resolver code should rearrange the RRs as appropriate, that is, using any addresses on the local net in preference to other addresses. However, not all resolvers can do this or are correctly configured. When a client is using a local server, the sorting can be performed in the server, based on the client's address. This only requires configuring the name servers, not all the clients. The sortlist statement (see below) takes an address_match_list and interprets it even more specifically than the topology statement does (). Each top level statement in the sortlist must itself be an explicit address_match_list with one or two elements. The first element (which may be an IP address, an IP prefix, an ACL name or a nested address_match_list) of each top level list is checked against the source address of the query until a match is found. Once the source address of the query has been matched, if the top level statement contains only one element, the actual primitive element that matched the source address is used to select the address in the response to move to the beginning of the response. If the statement is a list of two elements, then the second element is treated the same as the address_match_list in a topology statement. Each top level element is assigned a distance and the address in the response with the minimum distance is moved to the beginning of the response. In the following example, any queries received from any of the addresses of the host itself will get responses preferring addresses on any of the locally connected networks. Next most preferred are addresses on the 192.168.1/24 network, and after that either the 192.168.2/24 or 192.168.3/24 network with no preference shown between these two networks. Queries received from a host on the 192.168.1/24 network will prefer other addresses on that network to the 192.168.2/24 and 192.168.3/24 networks. Queries received from a host on the 192.168.4/24 or the 192.168.5/24 network will only prefer other addresses on their directly connected networks. sortlist { // IF the local host // THEN first fit on the following nets { localhost; { localnets; 192.168.1/24; { 192.168.2/24; 192.168.3/24; }; }; }; // IF on class C 192.168.1 THEN use .1, or .2 or .3 { 192.168.1/24; { 192.168.1/24; { 192.168.2/24; 192.168.3/24; }; }; }; // IF on class C 192.168.2 THEN use .2, or .1 or .3 { 192.168.2/24; { 192.168.2/24; { 192.168.1/24; 192.168.3/24; }; }; }; // IF on class C 192.168.3 THEN use .3, or .1 or .2 { 192.168.3/24; { 192.168.3/24; { 192.168.1/24; 192.168.2/24; }; }; }; // IF .4 or .5 THEN prefer that net { { 192.168.4/24; 192.168.5/24; }; }; }; The following example will give reasonable behavior for the local host and hosts on directly connected networks. It is similar to the behavior of the address sort in BIND 4.9.x. Responses sent to queries from the local host will favor any of the directly connected networks. Responses sent to queries from any other hosts on a directly connected network will prefer addresses on that same network. Responses to other queries will not be sorted. sortlist { { localhost; localnets; }; { localnets; }; }; RRset Ordering When multiple records are returned in an answer it may be useful to configure the order of the records placed into the response. The rrset-order statement permits configuration of the ordering of the records in a multiple record response. See also the sortlist statement, . An order_spec is defined as follows: class class_name type type_name name "domain_name" order ordering If no class is specified, the default is ANY. If no type is specified, the default is ANY. If no name is specified, the default is "*" (asterisk). The legal values for ordering are: fixed Records are returned in the order they are defined in the zone file. random Records are returned in some random order. cyclic Records are returned in a cyclic round-robin order. If BIND is configured with the "--enable-fixed-rrset" option at compile time, then the initial ordering of the RRset will match the one specified in the zone file. For example: rrset-order { class IN type A name "host.example.com" order random; order cyclic; }; will cause any responses for type A records in class IN that have "host.example.com" as a suffix, to always be returned in random order. All other records are returned in cyclic order. If multiple rrset-order statements appear, they are not combined — the last one applies. By default, all records are returned in random order. In this release of BIND 9, the rrset-order statement does not support "fixed" ordering by default. Fixed ordering can be enabled at compile time by specifying "--enable-fixed-rrset" on the "configure" command line. Tuning lame-ttl Sets the number of seconds to cache a lame server indication. 0 disables caching. (This is NOT recommended.) The default is 600 (10 minutes) and the maximum value is 1800 (30 minutes). Lame-ttl also controls the amount of time DNSSEC validation failures are cached. There is a minimum of 30 seconds applied to bad cache entries if the lame-ttl is set to less than 30 seconds. max-ncache-ttl To reduce network traffic and increase performance, the server stores negative answers. max-ncache-ttl is used to set a maximum retention time for these answers in the server in seconds. The default max-ncache-ttl is 10800 seconds (3 hours). max-ncache-ttl cannot exceed 7 days and will be silently truncated to 7 days if set to a greater value. max-cache-ttl Sets the maximum time for which the server will cache ordinary (positive) answers. The default is one week (7 days). A value of zero may cause all queries to return SERVFAIL, because of lost caches of intermediate RRsets (such as NS and glue AAAA/A records) in the resolution process. min-roots The minimum number of root servers that is required for a request for the root servers to be accepted. The default is 2. Not implemented in BIND 9. sig-validity-interval Specifies the number of days into the future when DNSSEC signatures automatically generated as a result of dynamic updates () will expire. There is an optional second field which specifies how long before expiry that the signatures will be regenerated. If not specified, the signatures will be regenerated at 1/4 of base interval. The second field is specified in days if the base interval is greater than 7 days otherwise it is specified in hours. The default base interval is 30 days giving a re-signing interval of 7 1/2 days. The maximum values are 10 years (3660 days). The signature inception time is unconditionally set to one hour before the current time to allow for a limited amount of clock skew. The sig-validity-interval should be, at least, several multiples of the SOA expire interval to allow for reasonable interaction between the various timer and expiry dates. sig-signing-nodes Specify the maximum number of nodes to be examined in each quantum when signing a zone with a new DNSKEY. The default is 100. sig-signing-signatures Specify a threshold number of signatures that will terminate processing a quantum when signing a zone with a new DNSKEY. The default is 10. sig-signing-type Specify a private RDATA type to be used when generating signing state records. The default is 65534. It is expected that this parameter may be removed in a future version once there is a standard type. Signing state records are used to internally by named to track the current state of a zone-signing process, i.e., whether it is still active or has been completed. The records can be inspected using the command rndc signing -list zone. Once named has finished signing a zone with a particular key, the signing state record associated with that key can be removed from the zone by running rndc signing -clear keyid/algorithm zone. To clear all of the completed signing state records for a zone, use rndc signing -clear all zone. min-refresh-time max-refresh-time min-retry-time max-retry-time These options control the server's behavior on refreshing a zone (querying for SOA changes) or retrying failed transfers. Usually the SOA values for the zone are used, but these values are set by the master, giving slave server administrators little control over their contents. These options allow the administrator to set a minimum and maximum refresh and retry time either per-zone, per-view, or globally. These options are valid for slave and stub zones, and clamp the SOA refresh and retry times to the specified values. The following defaults apply. min-refresh-time 300 seconds, max-refresh-time 2419200 seconds (4 weeks), min-retry-time 500 seconds, and max-retry-time 1209600 seconds (2 weeks). edns-udp-size Sets the maximum advertised EDNS UDP buffer size in bytes, to control the size of packets received from authoritative servers in response to recursive queries. Valid values are 512 to 4096 (values outside this range will be silently adjusted to the nearest value within it). The default value is 4096. The usual reason for setting edns-udp-size to a non-default value is to get UDP answers to pass through broken firewalls that block fragmented packets and/or block UDP DNS packets that are greater than 512 bytes. When named first queries a remote server, it will advertise a UDP buffer size of 512, as this has the greatest chance of success on the first try. If the initial response times out, named will try again with plain DNS, and if that is successful, it will be taken as evidence that the server does not support EDNS. After enough failures using EDNS and successes using plain DNS, named will default to plain DNS for future communications with that server. (Periodically, named will send an EDNS query to see if the situation has improved.) However, if the initial query is successful with EDNS advertising a buffer size of 512, then named will advertise progressively larger buffer sizes on successive queries, until responses begin timing out or edns-udp-size is reached. The default buffer sizes used by named are 512, 1232, 1432, and 4096, but never exceeding edns-udp-size. (The values 1232 and 1432 are chosen to allow for an IPv4/IPv6 encapsulated UDP message to be sent without fragmentation at the minimum MTU sizes for Ethernet and IPv6 networks.) max-udp-size Sets the maximum EDNS UDP message size named will send in bytes. Valid values are 512 to 4096 (values outside this range will be silently adjusted to the nearest value within it). The default value is 4096. This value applies to responses sent by a server; to set the advertised buffer size in queries, see edns-udp-size. The usual reason for setting max-udp-size to a non-default value is to get UDP answers to pass through broken firewalls that block fragmented packets and/or block UDP packets that are greater than 512 bytes. This is independent of the advertised receive buffer (edns-udp-size). Setting this to a low value will encourage additional TCP traffic to the nameserver. masterfile-format Specifies the file format of zone files (see ). The default value is text, which is the standard textual representation, except for slave zones, in which the default value is raw. Files in other formats than text are typically expected to be generated by the named-compilezone tool, or dumped by named. Note that when a zone file in a different format than text is loaded, named may omit some of the checks which would be performed for a file in the text format. In particular, check-names checks do not apply for the raw format. This means a zone file in the raw format must be generated with the same check level as that specified in the named configuration file. Also, map format files are loaded directly into memory via memory mapping, with only minimal checking. This statement sets the masterfile-format for all zones, but can be overridden on a per-zone or per-view basis by including a masterfile-format statement within the zone or view block in the configuration file. max-recursion-depth Sets the maximum number of levels of recursion that are permitted at any one time while servicing a recursive query. Resolving a name may require looking up a name server address, which in turn requires resolving another name, etc; if the number of indirections exceeds this value, the recursive query is terminated and returns SERVFAIL. The default is 7. max-recursion-queries Sets the maximum number of iterative queries that may be sent while servicing a recursive query. If more queries are sent, the recursive query is terminated and returns SERVFAIL. Queries to look up top level comains such as "com" and "net" and the DNS root zone are exempt from this limitation. The default is 75. notify-delay The delay, in seconds, between sending sets of notify messages for a zone. The default is five (5) seconds. The overall rate that NOTIFY messages are sent for all zones is controlled by serial-query-rate. max-rsa-exponent-size The maximum RSA exponent size, in bits, that will be accepted when validating. Valid values are 35 to 4096 bits. The default zero (0) is also accepted and is equivalent to 4096. prefetch When a query is received for cached data which is to expire shortly, named can refresh the data from the authoritative server immediately, ensuring that the cache always has an answer available. The specifies the "trigger" TTL value at which prefetch of the current query will take place: when a cache record with a lower TTL value is encountered during query processing, it will be refreshed. Valid trigger TTL values are 1 to 10 seconds. Values larger than 10 seconds will be silently reduced to 10. Setting a trigger TTL to zero (0) causes prefetch to be disabled. The default trigger TTL is 2. An optional second argument specifies the "eligibility" TTL: the smallest original TTL value that will be accepted for a record to be eligible for prefetching. The eligibility TTL must be at least six seconds longer than the trigger TTL; if it isn't, named will silently adjust it upward. The default eligibility TTL is 9. Built-in server information zones The server provides some helpful diagnostic information through a number of built-in zones under the pseudo-top-level-domain bind in the CHAOS class. These zones are part of a built-in view (see ) of class CHAOS which is separate from the default view of class IN. Most global configuration options (allow-query, etc) will apply to this view, but some are locally overridden: notify, recursion and allow-new-zones are always set to no, and rate-limit is set to allow three responses per second. If you need to disable these zones, use the options below, or hide the built-in CHAOS view by defining an explicit view of class CHAOS that matches all clients. version The version the server should report via a query of the name version.bind with type TXT, class CHAOS. The default is the real version number of this server. Specifying version none disables processing of the queries. hostname The hostname the server should report via a query of the name hostname.bind with type TXT, class CHAOS. This defaults to the hostname of the machine hosting the name server as found by the gethostname() function. The primary purpose of such queries is to identify which of a group of anycast servers is actually answering your queries. Specifying hostname none; disables processing of the queries. server-id The ID the server should report when receiving a Name Server Identifier (NSID) query, or a query of the name ID.SERVER with type TXT, class CHAOS. The primary purpose of such queries is to identify which of a group of anycast servers is actually answering your queries. Specifying server-id none; disables processing of the queries. Specifying server-id hostname; will cause named to use the hostname as found by the gethostname() function. The default server-id is none. Built-in Empty Zones Named has some built-in empty zones (SOA and NS records only). These are for zones that should normally be answered locally and which queries should not be sent to the Internet's root servers. The official servers which cover these namespaces return NXDOMAIN responses to these queries. In particular, these cover the reverse namespaces for addresses from RFC 1918, RFC 4193, RFC 5737 and RFC 6598. They also include the reverse namespace for IPv6 local address (locally assigned), IPv6 link local addresses, the IPv6 loopback address and the IPv6 unknown address. Named will attempt to determine if a built-in zone already exists or is active (covered by a forward-only forwarding declaration) and will not create an empty zone in that case. The current list of empty zones is: 10.IN-ADDR.ARPA 16.172.IN-ADDR.ARPA 17.172.IN-ADDR.ARPA 18.172.IN-ADDR.ARPA 19.172.IN-ADDR.ARPA 20.172.IN-ADDR.ARPA 21.172.IN-ADDR.ARPA 22.172.IN-ADDR.ARPA 23.172.IN-ADDR.ARPA 24.172.IN-ADDR.ARPA 25.172.IN-ADDR.ARPA 26.172.IN-ADDR.ARPA 27.172.IN-ADDR.ARPA 28.172.IN-ADDR.ARPA 29.172.IN-ADDR.ARPA 30.172.IN-ADDR.ARPA 31.172.IN-ADDR.ARPA 168.192.IN-ADDR.ARPA 64.100.IN-ADDR.ARPA 65.100.IN-ADDR.ARPA 66.100.IN-ADDR.ARPA 67.100.IN-ADDR.ARPA 68.100.IN-ADDR.ARPA 69.100.IN-ADDR.ARPA 70.100.IN-ADDR.ARPA 71.100.IN-ADDR.ARPA 72.100.IN-ADDR.ARPA 73.100.IN-ADDR.ARPA 74.100.IN-ADDR.ARPA 75.100.IN-ADDR.ARPA 76.100.IN-ADDR.ARPA 77.100.IN-ADDR.ARPA 78.100.IN-ADDR.ARPA 79.100.IN-ADDR.ARPA 80.100.IN-ADDR.ARPA 81.100.IN-ADDR.ARPA 82.100.IN-ADDR.ARPA 83.100.IN-ADDR.ARPA 84.100.IN-ADDR.ARPA 85.100.IN-ADDR.ARPA 86.100.IN-ADDR.ARPA 87.100.IN-ADDR.ARPA 88.100.IN-ADDR.ARPA 89.100.IN-ADDR.ARPA 90.100.IN-ADDR.ARPA 91.100.IN-ADDR.ARPA 92.100.IN-ADDR.ARPA 93.100.IN-ADDR.ARPA 94.100.IN-ADDR.ARPA 95.100.IN-ADDR.ARPA 96.100.IN-ADDR.ARPA 97.100.IN-ADDR.ARPA 98.100.IN-ADDR.ARPA 99.100.IN-ADDR.ARPA 100.100.IN-ADDR.ARPA 101.100.IN-ADDR.ARPA 102.100.IN-ADDR.ARPA 103.100.IN-ADDR.ARPA 104.100.IN-ADDR.ARPA 105.100.IN-ADDR.ARPA 106.100.IN-ADDR.ARPA 107.100.IN-ADDR.ARPA 108.100.IN-ADDR.ARPA 109.100.IN-ADDR.ARPA 110.100.IN-ADDR.ARPA 111.100.IN-ADDR.ARPA 112.100.IN-ADDR.ARPA 113.100.IN-ADDR.ARPA 114.100.IN-ADDR.ARPA 115.100.IN-ADDR.ARPA 116.100.IN-ADDR.ARPA 117.100.IN-ADDR.ARPA 118.100.IN-ADDR.ARPA 119.100.IN-ADDR.ARPA 120.100.IN-ADDR.ARPA 121.100.IN-ADDR.ARPA 122.100.IN-ADDR.ARPA 123.100.IN-ADDR.ARPA 124.100.IN-ADDR.ARPA 125.100.IN-ADDR.ARPA 126.100.IN-ADDR.ARPA 127.100.IN-ADDR.ARPA 0.IN-ADDR.ARPA 127.IN-ADDR.ARPA 254.169.IN-ADDR.ARPA 2.0.192.IN-ADDR.ARPA 100.51.198.IN-ADDR.ARPA 113.0.203.IN-ADDR.ARPA 255.255.255.255.IN-ADDR.ARPA 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 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 8.B.D.0.1.0.0.2.IP6.ARPA D.F.IP6.ARPA 8.E.F.IP6.ARPA 9.E.F.IP6.ARPA A.E.F.IP6.ARPA B.E.F.IP6.ARPA Empty zones are settable at the view level and only apply to views of class IN. Disabled empty zones are only inherited from options if there are no disabled empty zones specified at the view level. To override the options list of disabled zones, you can disable the root zone at the view level, for example: disable-empty-zone "."; If you are using the address ranges covered here, you should already have reverse zones covering the addresses you use. In practice this appears to not be the case with many queries being made to the infrastructure servers for names in these spaces. So many in fact that sacrificial servers were needed to be deployed to channel the query load away from the infrastructure servers. The real parent servers for these zones should disable all empty zone under the parent zone they serve. For the real root servers, this is all built-in empty zones. This will enable them to return referrals to deeper in the tree. empty-server Specify what server name will appear in the returned SOA record for empty zones. If none is specified, then the zone's name will be used. empty-contact Specify what contact name will appear in the returned SOA record for empty zones. If none is specified, then "." will be used. empty-zones-enable Enable or disable all empty zones. By default, they are enabled. disable-empty-zone Disable individual empty zones. By default, none are disabled. This option can be specified multiple times. Additional Section Caching The additional section cache, also called acache, is an internal cache to improve the response performance of BIND 9. When additional section caching is enabled, BIND 9 will cache an internal short-cut to the additional section content for each answer RR. Note that acache is an internal caching mechanism of BIND 9, and is not related to the DNS caching server function. Additional section caching does not change the response content (except the RRsets ordering of the additional section, see below), but can improve the response performance significantly. It is particularly effective when BIND 9 acts as an authoritative server for a zone that has many delegations with many glue RRs. In order to obtain the maximum performance improvement from additional section caching, setting additional-from-cache to no is recommended, since the current implementation of acache does not short-cut of additional section information from the DNS cache data. One obvious disadvantage of acache is that it requires much more memory for the internal cached data. Thus, if the response performance does not matter and memory consumption is much more critical, the acache mechanism can be disabled by setting acache-enable to no. It is also possible to specify the upper limit of memory consumption for acache by using max-acache-size. Additional section caching also has a minor effect on the RRset ordering in the additional section. Without acache, cyclic order is effective for the additional section as well as the answer and authority sections. However, additional section caching fixes the ordering when it first caches an RRset for the additional section, and the same ordering will be kept in succeeding responses, regardless of the setting of rrset-order. The effect of this should be minor, however, since an RRset in the additional section typically only contains a small number of RRs (and in many cases it only contains a single RR), in which case the ordering does not matter much. The following is a summary of options related to acache. acache-enable If yes, additional section caching is enabled. The default value is no. acache-cleaning-interval The server will remove stale cache entries, based on an LRU based algorithm, every acache-cleaning-interval minutes. The default is 60 minutes. If set to 0, no periodic cleaning will occur. max-acache-size The maximum amount of memory in bytes to use for the server's acache. When the amount of data in the acache reaches this limit, the server will clean more aggressively so that the limit is not exceeded. In a server with multiple views, the limit applies separately to the acache of each view. The default is 16M. Content Filtering BIND 9 provides the ability to filter out DNS responses from external DNS servers containing certain types of data in the answer section. Specifically, it can reject address (A or AAAA) records if the corresponding IPv4 or IPv6 addresses match the given address_match_list of the deny-answer-addresses option. It can also reject CNAME or DNAME records if the "alias" name (i.e., the CNAME alias or the substituted query name due to DNAME) matches the given namelist of the deny-answer-aliases option, where "match" means the alias name is a subdomain of one of the name_list elements. If the optional namelist is specified with except-from, records whose query name matches the list will be accepted regardless of the filter setting. Likewise, if the alias name is a subdomain of the corresponding zone, the deny-answer-aliases filter will not apply; for example, even if "example.com" is specified for deny-answer-aliases, www.example.com. CNAME xxx.example.com. returned by an "example.com" server will be accepted. In the address_match_list of the deny-answer-addresses option, only ip_addr and ip_prefix are meaningful; any key_id will be silently ignored. If a response message is rejected due to the filtering, the entire message is discarded without being cached, and a SERVFAIL error will be returned to the client. This filtering is intended to prevent "DNS rebinding attacks," in which an attacker, in response to a query for a domain name the attacker controls, returns an IP address within your own network or an alias name within your own domain. A naive web browser or script could then serve as an unintended proxy, allowing the attacker to get access to an internal node of your local network that couldn't be externally accessed otherwise. See the paper available at http://portal.acm.org/citation.cfm?id=1315245.1315298 for more details about the attacks. For example, if you own a domain named "example.net" and your internal network uses an IPv4 prefix 192.0.2.0/24, you might specify the following rules: deny-answer-addresses { 192.0.2.0/24; } except-from { "example.net"; }; deny-answer-aliases { "example.net"; }; If an external attacker lets a web browser in your local network look up an IPv4 address of "attacker.example.com", the attacker's DNS server would return a response like this: attacker.example.com. A 192.0.2.1 in the answer section. Since the rdata of this record (the IPv4 address) matches the specified prefix 192.0.2.0/24, this response will be ignored. On the other hand, if the browser looks up a legitimate internal web server "www.example.net" and the following response is returned to the BIND 9 server www.example.net. A 192.0.2.2 it will be accepted since the owner name "www.example.net" matches the except-from element, "example.net". Note that this is not really an attack on the DNS per se. In fact, there is nothing wrong for an "external" name to be mapped to your "internal" IP address or domain name from the DNS point of view. It might actually be provided for a legitimate purpose, such as for debugging. As long as the mapping is provided by the correct owner, it is not possible or does not make sense to detect whether the intent of the mapping is legitimate or not within the DNS. The "rebinding" attack must primarily be protected at the application that uses the DNS. For a large site, however, it may be difficult to protect all possible applications at once. This filtering feature is provided only to help such an operational environment; it is generally discouraged to turn it on unless you are very sure you have no other choice and the attack is a real threat for your applications. Care should be particularly taken if you want to use this option for addresses within 127.0.0.0/8. These addresses are obviously "internal", but many applications conventionally rely on a DNS mapping from some name to such an address. Filtering out DNS records containing this address spuriously can break such applications. Response Policy Zone (RPZ) Rewriting BIND 9 includes a limited mechanism to modify DNS responses for requests analogous to email anti-spam DNS blacklists. Responses can be changed to deny the existence of domains (NXDOMAIN), deny the existence of IP addresses for domains (NODATA), or contain other IP addresses or data. Response policy zones are named in the response-policy option for the view or among the global options if there is no response-policy option for the view. Response policy zones are ordinary DNS zones containing RRsets that can be queried normally if allowed. It is usually best to restrict those queries with something like allow-query { localhost; };. A response-policy option can support multiple policy zones. To maximize performance, a radix tree is used to quickly identify response policy zones containing triggers that match the current query. This imposes an upper limit of 32 on the number of policy zones in a single response-policy option; more than that is a configuration error. Five policy triggers can be encoded in RPZ records. RPZ-CLIENT-IP IP records are triggered by the IP address of the DNS client. Client IP address triggers are encoded in records that have owner names that are subdomains of rpz-client-ip relativized to the policy zone origin name and encode an address or address block. IPv4 addresses are represented as prefixlength.B4.B3.B2.B1.rpz-client-ip. The IPv4 prefix length must be between 1 and 32. All four bytes, B4, B3, B2, and B1, must be present. B4 is the decimal value of the least significant byte of the IPv4 address as in IN-ADDR.ARPA. IPv6 addresses are encoded in a format similar to the standard IPv6 text representation, prefixlength.W8.W7.W6.W5.W4.W3.W2.W1.rpz-client-ip. Each of W8,...,W1 is a one to four digit hexadecimal number representing 16 bits of the IPv6 address as in the standard text representation of IPv6 addresses, but reversed as in IP6.ARPA. (Note that this representation of IPv6 address is different from IP6.ARPA where each hex digit occupies a label.) All 8 words must be present except when one set of consecutive zero words is replaced with .zz. analogous to double colons (::) in standard IPv6 text encodings. The IPv6 prefix length must be between 1 and 128. QNAME QNAME policy records are triggered by query names of requests and targets of CNAME records resolved to generate the response. The owner name of a QNAME policy record is the query name relativized to the policy zone. RPZ-IP IP triggers are IP addresses in an A or AAAA record in the ANSWER section of a response. They are encoded like client-IP triggers except as subdomains of rpz-ip. RPZ-NSDNAME NSDNAME triggers match names of authoritative servers for the query name, a parent of the query name, a CNAME for query name, or a parent of a CNAME. They are encoded as subdomains of rpz-nsdname relativized to the RPZ origin name. NSIP triggers match IP addresses in A and AAAA RRsets for domains that can be checked against NSDNAME policy records. RPZ-NSIP NSIP triggers are encoded like IP triggers except as subdomains of rpz-nsip. NSDNAME and NSIP triggers are checked only for names with at least min-ns-dots dots. The default value of min-ns-dots is 1 to exclude top level domains. The query response is checked against all response policy zones, so two or more policy records can be triggered by a response. Because DNS responses are rewritten according to at most one policy record, a single record encoding an action (other than DISABLED actions) must be chosen. Triggers or the records that encode them are chosen for the rewriting in the following order: Choose the triggered record in the zone that appears first in the response-policy option. Prefer CLIENT-IP to QNAME to IP to NSDNAME to NSIP triggers in a single zone. Among NSDNAME triggers, prefer the trigger that matches the smallest name under the DNSSEC ordering. Among IP or NSIP triggers, prefer the trigger with the longest prefix. Among triggers with the same prefix length, prefer the IP or NSIP trigger that matches the smallest IP address. When the processing of a response is restarted to resolve DNAME or CNAME records and a policy record set has not been triggered, all response policy zones are again consulted for the DNAME or CNAME names and addresses. RPZ record sets are any types of DNS record except DNAME or DNSSEC that encode actions or responses to individual queries. Any of the policies can be used with any of the triggers. For example, while the TCP-only policy is commonly used with client-IP triggers, it cn be used with any type of trigger to force the use of TCP for responses with owner names in a zone. PASSTHRU The whitelist policy is specified by a CNAME whose target is rpz-passthru. It causes the response to not be rewritten and is most often used to "poke holes" in policies for CIDR blocks. DROP The blacklist policy is specified by a CNAME whose target is rpz-drop. It causes the response to be discarded. Nothing is sent to the DNS client. TCP-Only The "slip" policy is specified by a CNAME whose target is rpz-tcp-only. It changes UDP responses to short, truncated DNS responses that require the DNS client to try again with TCP. It is used to mitigate distributed DNS reflection attacks. NXDOMAIN The domain undefined response is encoded by a CNAME whose target is the root domain (.) NODATA The empty set of resource records is specified by CNAME whose target is the wildcard top-level domain (*.). It rewrites the response to NODATA or ANCOUNT=1. Local Data A set of ordinary DNS records can be used to answer queries. Queries for record types not the set are answered with NODATA. A special form of local data is a CNAME whose target is a wildcard such as *.example.com. It is used as if were an ordinary CNAME after the astrisk (*) has been replaced with the query name. The purpose for this special form is query logging in the walled garden's authority DNS server. All of the actions specified in all of the individual records in a policy zone can be overridden with a policy clause in the response-policy option. An organization using a policy zone provided by another organization might use this mechanism to redirect domains to its own walled garden. GIVEN The placeholder policy says "do not override but perform the action specified in the zone." DISABLED The testing override policy causes policy zone records to do nothing but log what they would have done if the policy zone were not disabled. The response to the DNS query will be written (or not) according to any triggered policy records that are not disabled. Disabled policy zones should appear first, because they will often not be logged if a higher precedence trigger is found first. PASSTHRU, DROP, TCP-Only, NXDOMAIN, and NODATA override with the corresponding per-record policy. CNAME domain causes all RPZ policy records to act as if they were "cname domain" records. By default, the actions encoded in a response policy zone are applied only to queries that ask for recursion (RD=1). That default can be changed for a single policy zone or all response policy zones in a view with a recursive-only no clause. This feature is useful for serving the same zone files both inside and outside an RFC 1918 cloud and using RPZ to delete answers that would otherwise contain RFC 1918 values on the externally visible name server or view. Also by default, RPZ actions are applied only to DNS requests that either do not request DNSSEC metadata (DO=0) or when no DNSSEC records are available for request name in the original zone (not the response policy zone). This default can be changed for all response policy zones in a view with a break-dnssec yes clause. In that case, RPZ actions are applied regardless of DNSSEC. The name of the clause option reflects the fact that results rewritten by RPZ actions cannot verify. No DNS records are needed for a QNAME or Client-IP trigger. The name or IP address itself is sufficient, so in principle the query name need not be recursively resolved. However, not resolving the requested name can leak the fact that response policy rewriting is in use and that the name is listed in a policy zone to operators of servers for listed names. To prevent that information leak, by default any recursion needed for a request is done before any policy triggers are considered. Because listed domains often have slow authoritative servers, this default behavior can cost significant time. The qname-wait-recurse no option overrides that default behavior when recursion cannot change a non-error response. The option does not affect QNAME or client-IP triggers in policy zones listed after other zones containing IP, NSIP and NSDNAME triggers, because those may depend on the A, AAAA, and NS records that would be found during recursive resolution. It also does not affect DNSSEC requests (DO=1) unless break-dnssec yes is in use, because the response would depend on whether or not RRSIG records were found during resolution. Using this option can cause error responses such as SERVFAIL to appear to be rewritten, since no recursion is being done to discover problems at the authoritative server. The TTL of a record modified by RPZ policies is set from the TTL of the relevant record in policy zone. It is then limited to a maximum value. The max-policy-ttl clause changes that maximum from its default of 5. For example, you might use this option statement response-policy { zone "badlist"; }; and this zone statement zone "badlist" {type master; file "master/badlist"; allow-query {none;}; }; with this zone file $TTL 1H @ SOA LOCALHOST. named-mgr.example.com (1 1h 15m 30d 2h) NS LOCALHOST. ; QNAME policy records. There are no periods (.) after the owner names. nxdomain.domain.com CNAME . ; NXDOMAIN policy *.nxdomain.domain.com CNAME . ; NXDOMAIN policy nodata.domain.com CNAME *. ; NODATA policy *.nodata.domain.com CNAME *. ; NODATA policy bad.domain.com A 10.0.0.1 ; redirect to a walled garden AAAA 2001:2::1 bzone.domain.com CNAME garden.example.com. ; do not rewrite (PASSTHRU) OK.DOMAIN.COM ok.domain.com CNAME rpz-passthru. ; redirect x.bzone.domain.com to x.bzone.domain.com.garden.example.com *.bzone.domain.com CNAME *.garden.example.com. ; IP policy records that rewrite all responses containing A records in 127/8 ; except 127.0.0.1 8.0.0.0.127.rpz-ip CNAME . 32.1.0.0.127.rpz-ip CNAME rpz-passthru. ; NSDNAME and NSIP policy records ns.domain.com.rpz-nsdname CNAME . 48.zz.2.2001.rpz-nsip CNAME . ; blacklist and whitelist some DNS clients 112.zz.2001.rpz-client-ip CNAME rpz-drop. 8.0.0.0.127.rpz-client-ip CNAME rpz-drop. ; force some DNS clients and responses in the example.com zone to TCP 16.0.0.1.10.rpz-client-ip CNAME rpz-tcp-only. example.com CNAME rpz-tcp-only. *.example.com CNAME rpz-tcp-only. RPZ can affect server performance. Each configured response policy zone requires the server to perform one to four additional database lookups before a query can be answered. For example, a DNS server with four policy zones, each with all four kinds of response triggers, QNAME, IP, NSIP, and NSDNAME, requires a total of 17 times as many database lookups as a similar DNS server with no response policy zones. A BIND9 server with adequate memory and one response policy zone with QNAME and IP triggers might achieve a maximum queries-per-second rate about 20% lower. A server with four response policy zones with QNAME and IP triggers might have a maximum QPS rate about 50% lower. Responses rewritten by RPZ are counted in the RPZRewrites statistics. Response Rate Limiting Excessive almost identical UDP responses can be controlled by configuring a rate-limit clause in an options or view statement. This mechanism keeps authoritative BIND 9 from being used in amplifying reflection denial of service (DoS) attacks. Short truncated (TC=1) responses can be sent to provide rate-limited responses to legitimate clients within a range of forged, attacked IP addresses. Legitimate clients react to dropped or truncated response by retrying with UDP or with TCP respectively. This mechanism is intended for authoritative DNS servers. It can be used on recursive servers but can slow applications such as SMTP servers (mail receivers) and HTTP clients (web browsers) that repeatedly request the same domains. When possible, closing "open" recursive servers is better. Response rate limiting uses a "credit" or "token bucket" scheme. Each combination of identical response and client has a conceptual account that earns a specified number of credits every second. A prospective response debits its account by one. Responses are dropped or truncated while the account is negative. Responses are tracked within a rolling window of time which defaults to 15 seconds, but can be configured with the window option to any value from 1 to 3600 seconds (1 hour). The account cannot become more positive than the per-second limit or more negative than window times the per-second limit. When the specified number of credits for a class of responses is set to 0, those responses are not rate limited. The notions of "identical response" and "DNS client" for rate limiting are not simplistic. All responses to an address block are counted as if to a single client. The prefix lengths of addresses blocks are specified with ipv4-prefix-length (default 24) and ipv6-prefix-length (default 56). All non-empty responses for a valid domain name (qname) and record type (qtype) are identical and have a limit specified with responses-per-second (default 0 or no limit). All empty (NODATA) responses for a valid domain, regardless of query type, are identical. Responses in the NODATA class are limited by nodata-per-second (default responses-per-second). Requests for any and all undefined subdomains of a given valid domain result in NXDOMAIN errors, and are identical regardless of query type. They are limited by nxdomains-per-second (default base responses-per-second). This controls some attacks using random names, but can be relaxed or turned off (set to 0) on servers that expect many legitimate NXDOMAIN responses, such as from anti-spam blacklists. Referrals or delegations to the server of a given domain are identical and are limited by referrals-per-second (default responses-per-second). Responses generated from local wildcards are counted and limited as if they were for the parent domain name. This controls flooding using random.wild.example.com. All requests that result in DNS errors other than NXDOMAIN, such as SERVFAIL and FORMERR, are identical regardless of requested name (qname) or record type (qtype). This controls attacks using invalid requests or distant, broken authoritative servers. By default the limit on errors is the same as the responses-per-second value, but it can be set separately with errors-per-second. Many attacks using DNS involve UDP requests with forged source addresses. Rate limiting prevents the use of BIND 9 to flood a network with responses to requests with forged source addresses, but could let a third party block responses to legitimate requests. There is a mechanism that can answer some legitimate requests from a client whose address is being forged in a flood. Setting slip to 2 (its default) causes every other UDP request to be answered with a small truncated (TC=1) response. The small size and reduced frequency, and so lack of amplification, of "slipped" responses make them unattractive for reflection DoS attacks. slip must be between 0 and 10. A value of 0 does not "slip": no truncated responses are sent due to rate limiting, all responses are dropped. A value of 1 causes every response to slip; values between 2 and 10 cause every n'th response to slip. Some error responses including REFUSED and SERVFAIL cannot be replaced with truncated responses and are instead leaked at the slip rate. (NOTE: Dropped responses from an authoritative server may reduce the difficulty of a third party successfully forging a response to a recursive resolver. The best security against forged responses is for authoritative operators to sign their zones using DNSSEC and for resolver operators to validate the responses. When this is not an option, operators who are more concerned with response integrity than with flood mitigation may consider setting slip to 1, causing all rate-limited responses to be truncated rather than dropped. This reduces the effectiveness of rate-limiting against reflection attacks.) When the approximate query per second rate exceeds the qps-scale value, then the responses-per-second, errors-per-second, nxdomains-per-second and all-per-second values are reduced by the ratio of the current rate to the qps-scale value. This feature can tighten defenses during attacks. For example, with qps-scale 250; responses-per-second 20; and a total query rate of 1000 queries/second for all queries from all DNS clients including via TCP, then the effective responses/second limit changes to (250/1000)*20 or 5. Responses sent via TCP are not limited but are counted to compute the query per second rate. Communities of DNS clients can be given their own parameters or no rate limiting by putting rate-limit statements in view statements instead of the global option statement. A rate-limit statement in a view replaces, rather than supplementing, a rate-limit statement among the main options. DNS clients within a view can be exempted from rate limits with the exempt-clients clause. UDP responses of all kinds can be limited with the all-per-second phrase. This rate limiting is unlike the rate limiting provided by responses-per-second, errors-per-second, and nxdomains-per-second on a DNS server which are often invisible to the victim of a DNS reflection attack. Unless the forged requests of the attack are the same as the legitimate requests of the victim, the victim's requests are not affected. Responses affected by an all-per-second limit are always dropped; the slip value has no effect. An all-per-second limit should be at least 4 times as large as the other limits, because single DNS clients often send bursts of legitimate requests. For example, the receipt of a single mail message can prompt requests from an SMTP server for NS, PTR, A, and AAAA records as the incoming SMTP/TCP/IP connection is considered. The SMTP server can need additional NS, A, AAAA, MX, TXT, and SPF records as it considers the STMP Mail From command. Web browsers often repeatedly resolve the same names that are repeated in HTML <IMG> tags in a page. All-per-second is similar to the rate limiting offered by firewalls but often inferior. Attacks that justify ignoring the contents of DNS responses are likely to be attacks on the DNS server itself. They usually should be discarded before the DNS server spends resources making TCP connections or parsing DNS requests, but that rate limiting must be done before the DNS server sees the requests. The maximum size of the table used to track requests and rate limit responses is set with max-table-size. Each entry in the table is between 40 and 80 bytes. The table needs approximately as many entries as the number of requests received per second. The default is 20,000. To reduce the cold start of growing the table, min-table-size (default 500) can set the minimum table size. Enable rate-limit category logging to monitor expansions of the table and inform choices for the initial and maximum table size. Use log-only yes to test rate limiting parameters without actually dropping any requests. Responses dropped by rate limits are included in the RateDropped and QryDropped statistics. Responses that truncated by rate limits are included in RateSlipped and RespTruncated. <command>server</command> Statement Grammar server ip_addr[/prefixlen] { bogus yes_or_no ; provide-ixfr yes_or_no ; request-ixfr yes_or_no ; request-nsid yes_or_no ; request-sit yes_or_no ; edns yes_or_no ; edns-udp-size number ; nosit-udp-size number ; max-udp-size number ; transfers number ; transfer-format ( one-answer | many-answers ) ; ] keys { key_id }; transfer-source (ip4_addr | *) port ip_port dscp ip_dscp ; transfer-source-v6 (ip6_addr | *) port ip_port dscp ip_dscp ; notify-source (ip4_addr | *) port ip_port dscp ip_dscp ; notify-source-v6 (ip6_addr | *) port ip_port dscp ip_dscp ; query-source address ( ip_addr | * ) port ( ip_port | * ) dscp ip_dscp ; query-source-v6 address ( ip_addr | * ) port ( ip_port | * ) dscp ip_dscp ; use-queryport-pool yes_or_no; queryport-pool-ports number; queryport-pool-updateinterval number; }; <command>server</command> Statement Definition and Usage The server statement defines characteristics to be associated with a remote name server. If a prefix length is specified, then a range of servers is covered. Only the most specific server clause applies regardless of the order in named.conf. The server statement can occur at the top level of the configuration file or inside a view statement. If a view statement contains one or more server statements, only those apply to the view and any top-level ones are ignored. If a view contains no server statements, any top-level server statements are used as defaults. If you discover that a remote server is giving out bad data, marking it as bogus will prevent further queries to it. The default value of bogus is no. The provide-ixfr clause determines whether the local server, acting as master, will respond with an incremental zone transfer when the given remote server, a slave, requests it. If set to yes, incremental transfer will be provided whenever possible. If set to no, all transfers to the remote server will be non-incremental. If not set, the value of the provide-ixfr option in the view or global options block is used as a default. The request-ixfr clause determines whether the local server, acting as a slave, will request incremental zone transfers from the given remote server, a master. If not set, the value of the request-ixfr option in the view or global options block is used as a default. It may also be set in the zone block and, if set there, it will override the global or view setting for that zone. IXFR requests to servers that do not support IXFR will automatically fall back to AXFR. Therefore, there is no need to manually list which servers support IXFR and which ones do not; the global default of yes should always work. The purpose of the provide-ixfr and request-ixfr clauses is to make it possible to disable the use of IXFR even when both master and slave claim to support it, for example if one of the servers is buggy and crashes or corrupts data when IXFR is used. The edns clause determines whether the local server will attempt to use EDNS when communicating with the remote server. The default is yes. The edns-udp-size option sets the EDNS UDP size that is advertised by named when querying the remote server. Valid values are 512 to 4096 bytes (values outside this range will be silently adjusted to the nearest value within it). This option is useful when you wish to advertise a different value to this server than the value you advertise globally, for example, when there is a firewall at the remote site that is blocking large replies. (Note: Currently, this sets a single UDP size for all packets sent to the server; named will not deviate from this value. This differs from the behavior of edns-udp-size in options or view statements, where it specifies a maximum value. The server statement behavior may be brought into conformance with the options/view behavior in future releases.) The max-udp-size option sets the maximum EDNS UDP message size named will send. Valid values are 512 to 4096 bytes (values outside this range will be silently adjusted). This option is useful when you know that there is a firewall that is blocking large replies from named. The nosit-udp-size option sets the maximum size of UDP responses that will be sent to queries without a valid source identity token. The command max-udp-size option may further limit the response size. The server supports two zone transfer methods. The first, one-answer, uses one DNS message per resource record transferred. many-answers packs as many resource records as possible into a message. many-answers is more efficient, but is only known to be understood by BIND 9, BIND 8.x, and patched versions of BIND 4.9.5. You can specify which method to use for a server with the transfer-format option. If transfer-format is not specified, the transfer-format specified by the options statement will be used. transfers is used to limit the number of concurrent inbound zone transfers from the specified server. If no transfers clause is specified, the limit is set according to the transfers-per-ns option. The keys clause identifies a key_id defined by the key statement, to be used for transaction security (TSIG, ) when talking to the remote server. When a request is sent to the remote server, a request signature will be generated using the key specified here and appended to the message. A request originating from the remote server is not required to be signed by this key. Only a single key per server is currently supported. The transfer-source and transfer-source-v6 clauses specify the IPv4 and IPv6 source address to be used for zone transfer with the remote server, respectively. For an IPv4 remote server, only transfer-source can be specified. Similarly, for an IPv6 remote server, only transfer-source-v6 can be specified. For more details, see the description of transfer-source and transfer-source-v6 in . The notify-source and notify-source-v6 clauses specify the IPv4 and IPv6 source address to be used for notify messages sent to remote servers, respectively. For an IPv4 remote server, only notify-source can be specified. Similarly, for an IPv6 remote server, only notify-source-v6 can be specified. The query-source and query-source-v6 clauses specify the IPv4 and IPv6 source address to be used for queries sent to remote servers, respectively. For an IPv4 remote server, only query-source can be specified. Similarly, for an IPv6 remote server, only query-source-v6 can be specified. The request-nsid clause determines whether the local server will add a NSID EDNS option to requests sent to the server. This overrides request-nsid set at the view or option level. The request-sit clause determines whether the local server will add a SIT EDNS option to requests sent to the server. This overrides request-sit set at the view or option level. Named may determine that SIT is not supported by the remote server and not add a SIT EDNS option to requests. <command>statistics-channels</command> Statement Grammar statistics-channels { [ inet ( ip_addr | * ) [ port ip_port ] [ allow { address_match_list } ]; ] [ inet ...; ] }; <command>statistics-channels</command> Statement Definition and Usage The statistics-channels statement declares communication channels to be used by system administrators to get access to statistics information of the name server. This statement intends to be flexible to support multiple communication protocols in the future, but currently only HTTP access is supported. It requires that BIND 9 be compiled with libxml2 and/or json-c (also known as libjson0); the statistics-channels statement is still accepted even if it is built without the library, but any HTTP access will fail with an error. An inet control channel is a TCP socket listening at the specified ip_port on the specified ip_addr, which can be an IPv4 or IPv6 address. An ip_addr of * (asterisk) is interpreted as the IPv4 wildcard address; connections will be accepted on any of the system's IPv4 addresses. To listen on the IPv6 wildcard address, use an ip_addr of ::. If no port is specified, port 80 is used for HTTP channels. The asterisk "*" cannot be used for ip_port. The attempt of opening a statistics channel is restricted by the optional allow clause. Connections to the statistics channel are permitted based on the address_match_list. If no allow clause is present, named accepts connection attempts from any address; since the statistics may contain sensitive internal information, it is highly recommended to restrict the source of connection requests appropriately. If no statistics-channels statement is present, named will not open any communication channels. The statistics are available in various formats and views depending on the URI used to access them. For example, if the statistics channel is configured to listen on 127.0.0.1 port 8888, then the statistics are accessible in XML format at http://127.0.0.1:8888/ or http://127.0.0.1:8888/xml. A CSS file is included which can format the XML statistics into tables when viewed with a stylesheet-capable browser, and into charts and graphs using the Google Charts API when using a javascript-capable browser. Applications that depend on a particular XML schema can request http://127.0.0.1:8888/xml/v2 for version 2 of the statistics XML schema or http://127.0.0.1:8888/xml/v3 for version 3. If the requested schema is supported by the server, then it will respond; if not, it will return a "page not found" error. Broken-out subsets of the statistics can be viewed at http://127.0.0.1:8888/xml/v3/status (server uptime and last reconfiguration time), http://127.0.0.1:8888/xml/v3/server (server and resolver statistics), http://127.0.0.1:8888/xml/v3/zones (zone statistics), http://127.0.0.1:8888/xml/v3/net (network status and socket statistics), http://127.0.0.1:8888/xml/v3/mem (memory manager statistics), http://127.0.0.1:8888/xml/v3/tasks (task manager statistics). The full set of statistics can also be read in JSON format at http://127.0.0.1:8888/json, with the broken-out subsets at http://127.0.0.1:8888/json/v1/status (server uptime and last reconfiguration time), http://127.0.0.1:8888/json/v1/server (server and resolver statistics), http://127.0.0.1:8888/json/v1/zones (zone statistics), http://127.0.0.1:8888/json/v1/net (network status and socket statistics), http://127.0.0.1:8888/json/v1/mem (memory manager statistics), http://127.0.0.1:8888/json/v1/tasks (task manager statistics). <command>trusted-keys</command> Statement Grammar trusted-keys { string number number number string ; string number number number string ; ... }; <command>trusted-keys</command> Statement Definition and Usage The trusted-keys statement defines DNSSEC security roots. DNSSEC is described in . A security root is defined when the public key for a non-authoritative zone is known, but cannot be securely obtained through DNS, either because it is the DNS root zone or because its parent zone is unsigned. Once a key has been configured as a trusted key, it is treated as if it had been validated and proven secure. The resolver attempts DNSSEC validation on all DNS data in subdomains of a security root. All keys (and corresponding zones) listed in trusted-keys are deemed to exist regardless of what parent zones say. Similarly for all keys listed in trusted-keys only those keys are used to validate the DNSKEY RRset. The parent's DS RRset will not be used. The trusted-keys statement can contain multiple key entries, each consisting of the key's domain name, flags, protocol, algorithm, and the Base-64 representation of the key data. Spaces, tabs, newlines and carriage returns are ignored in the key data, so the configuration may be split up into multiple lines. trusted-keys may be set at the top level of named.conf or within a view. If it is set in both places, they are additive: keys defined at the top level are inherited by all views, but keys defined in a view are only used within that view. <command>managed-keys</command> Statement Grammar managed-keys { name initial-key flags protocol algorithm key-data ; name initial-key flags protocol algorithm key-data ; ... }; <command>managed-keys</command> Statement Definition and Usage The managed-keys statement, like trusted-keys, defines DNSSEC security roots. The difference is that managed-keys can be kept up to date automatically, without intervention from the resolver operator. Suppose, for example, that a zone's key-signing key was compromised, and the zone owner had to revoke and replace the key. A resolver which had the old key in a trusted-keys statement would be unable to validate this zone any longer; it would reply with a SERVFAIL response code. This would continue until the resolver operator had updated the trusted-keys statement with the new key. If, however, the zone were listed in a managed-keys statement instead, then the zone owner could add a "stand-by" key to the zone in advance. named would store the stand-by key, and when the original key was revoked, named would be able to transition smoothly to the new key. It would also recognize that the old key had been revoked, and cease using that key to validate answers, minimizing the damage that the compromised key could do. A managed-keys statement contains a list of the keys to be managed, along with information about how the keys are to be initialized for the first time. The only initialization method currently supported (as of BIND 9.7.0) is initial-key. This means the managed-keys statement must contain a copy of the initializing key. (Future releases may allow keys to be initialized by other methods, eliminating this requirement.) Consequently, a managed-keys statement appears similar to a trusted-keys, differing in the presence of the second field, containing the keyword initial-key. The difference is, whereas the keys listed in a trusted-keys continue to be trusted until they are removed from named.conf, an initializing key listed in a managed-keys statement is only trusted once: for as long as it takes to load the managed key database and start the RFC 5011 key maintenance process. The first time named runs with a managed key configured in named.conf, it fetches the DNSKEY RRset directly from the zone apex, and validates it using the key specified in the managed-keys statement. If the DNSKEY RRset is validly signed, then it is used as the basis for a new managed keys database. From that point on, whenever named runs, it sees the managed-keys statement, checks to make sure RFC 5011 key maintenance has already been initialized for the specified domain, and if so, it simply moves on. The key specified in the managed-keys is not used to validate answers; it has been superseded by the key or keys stored in the managed keys database. The next time named runs after a name has been removed from the managed-keys statement, the corresponding zone will be removed from the managed keys database, and RFC 5011 key maintenance will no longer be used for that domain. named only maintains a single managed keys database; consequently, unlike trusted-keys, managed-keys may only be set at the top level of named.conf, not within a view. In the current implementation, the managed keys database is stored as a master-format zone file called managed-keys.bind. When the key database is changed, the zone is updated. As with any other dynamic zone, changes will be written into a journal file, managed-keys.bind.jnl. They are committed to the master file as soon as possible afterward; in the case of the managed key database, this will usually occur within 30 seconds. So, whenever named is using automatic key maintenance, those two files can be expected to exist in the working directory. (For this reason among others, the working directory should be always be writable by named.) If the dnssec-validation option is set to auto, named will automatically initialize a managed key for the root zone. Similarly, if the dnssec-lookaside option is set to auto, named will automatically initialize a managed key for the zone dlv.isc.org. In both cases, the key that is used to initialize the key maintenance process is built into named, and can be overridden from bindkeys-file. <command>view</command> Statement Grammar view view_name class { match-clients { address_match_list }; match-destinations { address_match_list }; match-recursive-only yes_or_no ; view_option; ... zone_statement; ... }; <command>view</command> Statement Definition and Usage The view statement is a powerful feature of BIND 9 that lets a name server answer a DNS query differently depending on who is asking. It is particularly useful for implementing split DNS setups without having to run multiple servers. Each view statement defines a view of the DNS namespace that will be seen by a subset of clients. A client matches a view if its source IP address matches the address_match_list of the view's match-clients clause and its destination IP address matches the address_match_list of the view's match-destinations clause. If not specified, both match-clients and match-destinations default to matching all addresses. In addition to checking IP addresses match-clients and match-destinations can also take keys which provide an mechanism for the client to select the view. A view can also be specified as match-recursive-only, which means that only recursive requests from matching clients will match that view. The order of the view statements is significant — a client request will be resolved in the context of the first view that it matches. Zones defined within a view statement will only be accessible to clients that match the view. By defining a zone of the same name in multiple views, different zone data can be given to different clients, for example, "internal" and "external" clients in a split DNS setup. Many of the options given in the options statement can also be used within a view statement, and then apply only when resolving queries with that view. When no view-specific value is given, the value in the options statement is used as a default. Also, zone options can have default values specified in the view statement; these view-specific defaults take precedence over those in the options statement. Views are class specific. If no class is given, class IN is assumed. Note that all non-IN views must contain a hint zone, since only the IN class has compiled-in default hints. If there are no view statements in the config file, a default view that matches any client is automatically created in class IN. Any zone statements specified on the top level of the configuration file are considered to be part of this default view, and the options statement will apply to the default view. If any explicit view statements are present, all zone statements must occur inside view statements. Here is an example of a typical split DNS setup implemented using view statements: view "internal" { // This should match our internal networks. match-clients { 10.0.0.0/8; }; // Provide recursive service to internal // clients only. recursion yes; // Provide a complete view of the example.com // zone including addresses of internal hosts. zone "example.com" { type master; file "example-internal.db"; }; }; view "external" { // Match all clients not matched by the // previous view. match-clients { any; }; // Refuse recursive service to external clients. recursion no; // Provide a restricted view of the example.com // zone containing only publicly accessible hosts. zone "example.com" { type master; file "example-external.db"; }; }; <command>zone</command> Statement Grammar zone zone_name class { type master; allow-query { address_match_list }; allow-query-on { address_match_list }; allow-transfer { address_match_list }; allow-update { address_match_list }; update-check-ksk yes_or_no; dnssec-dnskey-kskonly yes_or_no; dnssec-loadkeys-interval number; update-policy local | { update_policy_rule ... }; also-notify { ip_addr port ip_port dscp ip_dscp ; ip_addr port ip_port dscp ip_dscp ; ... }; check-names (warn|fail|ignore) ; check-mx (warn|fail|ignore) ; check-wildcard yes_or_no; check-spf ( warn | ignore ); check-integrity yes_or_no ; dialup dialup_option ; file string ; masterfile-format (text|raw|map) ; journal string ; max-journal-size size_spec; forward (only|first) ; forwarders { ip_addr port ip_port dscp ip_dscp ; ... }; ixfr-base string ; ixfr-from-differences yes_or_no; ixfr-tmp-file string ; request-ixfr yes_or_no ; maintain-ixfr-base yes_or_no ; max-ixfr-log-size number ; max-transfer-idle-out number ; max-transfer-time-out number ; notify yes_or_no | explicit | master-only ; notify-delay seconds ; notify-to-soa yes_or_no; pubkey number number number string ; notify-source (ip4_addr | *) port ip_port dscp ip_dscp ; notify-source-v6 (ip6_addr | *) port ip_port dscp ip_dscp ; zone-statistics full | terse | none; sig-validity-interval number number ; sig-signing-nodes number ; sig-signing-signatures number ; sig-signing-type number ; database string ; min-refresh-time number ; max-refresh-time number ; min-retry-time number ; max-retry-time number ; key-directory path_name; auto-dnssec allow|maintain|off; inline-signing yes_or_no; zero-no-soa-ttl yes_or_no ; serial-update-method increment|unixtime; max-zone-ttl number ; }; zone zone_name class { type slave; allow-notify { address_match_list }; allow-query { address_match_list }; allow-query-on { address_match_list }; allow-transfer { address_match_list }; allow-update-forwarding { address_match_list }; dnssec-update-mode ( maintain | no-resign ); update-check-ksk yes_or_no; dnssec-dnskey-kskonly yes_or_no; dnssec-loadkeys-interval number; dnssec-secure-to-insecure yes_or_no ; try-tcp-refresh yes_or_no; also-notify port ip_port dscp ip_dscp { ( masters_list | ip_addr port ip_port dscp ip_dscp key key ) ; ... }; check-names (warn|fail|ignore) ; dialup dialup_option ; file string ; masterfile-format (text|raw|map) ; journal string ; max-journal-size size_spec; forward (only|first) ; forwarders { ip_addr port ip_port dscp ip_dscp ; ... }; ixfr-base string ; ixfr-from-differences yes_or_no; ixfr-tmp-file string ; maintain-ixfr-base yes_or_no ; masters port ip_port dscp ip_dscp { ( masters_list | ip_addr port ip_port dscp ip_dscp key key ) ; ... }; max-ixfr-log-size number ; max-transfer-idle-in number ; max-transfer-idle-out number ; max-transfer-time-in number ; max-transfer-time-out number ; notify yes_or_no | explicit | master-only ; notify-delay seconds ; notify-to-soa yes_or_no; pubkey number number number string ; transfer-source (ip4_addr | *) port ip_port dscp ip_dscp ; transfer-source-v6 (ip6_addr | *) port ip_port dscp ip_dscp ; alt-transfer-source (ip4_addr | *) port ip_port dscp ip_dscp ; alt-transfer-source-v6 (ip6_addr | *) port ip_port dscp ip_dscp ; use-alt-transfer-source yes_or_no; notify-source (ip4_addr | *) port ip_port dscp ip_dscp ; notify-source-v6 (ip6_addr | *) port ip_port dscp ip_dscp ; zone-statistics full | terse | none; sig-validity-interval number number ; sig-signing-nodes number ; sig-signing-signatures number ; sig-signing-type number ; database string ; min-refresh-time number ; max-refresh-time number ; min-retry-time number ; max-retry-time number ; key-directory path_name; auto-dnssec allow|maintain|off; inline-signing yes_or_no; multi-master yes_or_no ; zero-no-soa-ttl yes_or_no ; }; zone zone_name class { type hint; file string ; delegation-only yes_or_no ; check-names (warn|fail|ignore) ; // Not Implemented. }; zone zone_name class { type stub; allow-query { address_match_list }; allow-query-on { address_match_list }; check-names (warn|fail|ignore) ; dialup dialup_option ; delegation-only yes_or_no ; file string ; masterfile-format (text|raw|map) ; forward (only|first) ; forwarders { ip_addr port ip_port dscp ip_dscp ; ... }; masters port ip_port dscp ip_dscp { ( masters_list | ip_addr port ip_port dscp ip_dscp key key ) ; ... }; max-transfer-idle-in number ; max-transfer-time-in number ; pubkey number number number string ; transfer-source (ip4_addr | *) port ip_port dscp ip_dscp ; transfer-source-v6 (ip6_addr | *) port ip_port dscp ip_dscp ; alt-transfer-source (ip4_addr | *) port ip_port dscp ip_dscp ; alt-transfer-source-v6 (ip6_addr | *) port ip_port dscp ip_dscp ; use-alt-transfer-source yes_or_no; zone-statistics yes_or_no ; database string ; min-refresh-time number ; max-refresh-time number ; min-retry-time number ; max-retry-time number ; multi-master yes_or_no ; }; zone zone_name class { type static-stub; allow-query { address_match_list }; server-addresses { ip_addr ; ... }; server-names { namelist }; zone-statistics yes_or_no ; }; zone zone_name class { type forward; forward (only|first) ; forwarders { ip_addr port ip_port dscp ip_dscp ; ... }; delegation-only yes_or_no ; }; zone "." class { type redirect; file string ; masterfile-format (text|raw|map) ; allow-query { address_match_list }; max-zone-ttl number ; }; zone zone_name class { type delegation-only; }; zone zone_name class { in-view string ; }; <command>zone</command> Statement Definition and Usage Zone Types master The server has a master copy of the data for the zone and will be able to provide authoritative answers for it. slave A slave zone is a replica of a master zone. The masters list specifies one or more IP addresses of master servers that the slave contacts to update its copy of the zone. Masters list elements can also be names of other masters lists. By default, transfers are made from port 53 on the servers; this can be changed for all servers by specifying a port number before the list of IP addresses, or on a per-server basis after the IP address. Authentication to the master can also be done with per-server TSIG keys. If a file is specified, then the replica will be written to this file whenever the zone is changed, and reloaded from this file on a server restart. Use of a file is recommended, since it often speeds server startup and eliminates a needless waste of bandwidth. Note that for large numbers (in the tens or hundreds of thousands) of zones per server, it is best to use a two-level naming scheme for zone filenames. For example, a slave server for the zone example.com might place the zone contents into a file called ex/example.com where ex/ is just the first two letters of the zone name. (Most operating systems behave very slowly if you put 100000 files into a single directory.) stub A stub zone is similar to a slave zone, except that it replicates only the NS records of a master zone instead of the entire zone. Stub zones are not a standard part of the DNS; they are a feature specific to the BIND implementation. Stub zones can be used to eliminate the need for glue NS record in a parent zone at the expense of maintaining a stub zone entry and a set of name server addresses in named.conf. This usage is not recommended for new configurations, and BIND 9 supports it only in a limited way. In BIND 4/8, zone transfers of a parent zone included the NS records from stub children of that zone. This meant that, in some cases, users could get away with configuring child stubs only in the master server for the parent zone. BIND 9 never mixes together zone data from different zones in this way. Therefore, if a BIND 9 master serving a parent zone has child stub zones configured, all the slave servers for the parent zone also need to have the same child stub zones configured. Stub zones can also be used as a way of forcing the resolution of a given domain to use a particular set of authoritative servers. For example, the caching name servers on a private network using RFC1918 addressing may be configured with stub zones for 10.in-addr.arpa to use a set of internal name servers as the authoritative servers for that domain. static-stub A static-stub zone is similar to a stub zone with the following exceptions: the zone data is statically configured, rather than transferred from a master server; when recursion is necessary for a query that matches a static-stub zone, the locally configured data (nameserver names and glue addresses) is always used even if different authoritative information is cached. Zone data is configured via the server-addresses and server-names zone options. The zone data is maintained in the form of NS and (if necessary) glue A or AAAA RRs internally, which can be seen by dumping zone databases by rndc dumpdb -all. The configured RRs are considered local configuration parameters rather than public data. Non recursive queries (i.e., those with the RD bit off) to a static-stub zone are therefore prohibited and will be responded with REFUSED. Since the data is statically configured, no zone maintenance action takes place for a static-stub zone. For example, there is no periodic refresh attempt, and an incoming notify message will be rejected with an rcode of NOTAUTH. Each static-stub zone is configured with internally generated NS and (if necessary) glue A or AAAA RRs forward A "forward zone" is a way to configure forwarding on a per-domain basis. A zone statement of type forward can contain a forward and/or forwarders statement, which will apply to queries within the domain given by the zone name. If no forwarders statement is present or an empty list for forwarders is given, then no forwarding will be done for the domain, canceling the effects of any forwarders in the options statement. Thus if you want to use this type of zone to change the behavior of the global forward option (that is, "forward first" to, then "forward only", or vice versa, but want to use the same servers as set globally) you need to re-specify the global forwarders. hint The initial set of root name servers is specified using a "hint zone". When the server starts up, it uses the root hints to find a root name server and get the most recent list of root name servers. If no hint zone is specified for class IN, the server uses a compiled-in default set of root servers hints. Classes other than IN have no built-in defaults hints. redirect Redirect zones are used to provide answers to queries when normal resolution would result in NXDOMAIN being returned. Only one redirect zone is supported per view. allow-query can be used to restrict which clients see these answers. If the client has requested DNSSEC records (DO=1) and the NXDOMAIN response is signed then no substitution will occur. To redirect all NXDOMAIN responses to 100.100.100.2 and 2001:ffff:ffff::100.100.100.2, one would configure a type redirect zone named ".", with the zone file containing wildcard records that point to the desired addresses: "*. IN A 100.100.100.2" and "*. IN AAAA 2001:ffff:ffff::100.100.100.2". To redirect all Spanish names (under .ES) one would use similar entries but with the names "*.ES." instead of "*.". To redirect all commercial Spanish names (under COM.ES) one would use wildcard entries called "*.COM.ES.". Note that the redirect zone supports all possible types; it is not limited to A and AAAA records. Because redirect zones are not referenced directly by name, they are not kept in the zone lookup table with normal master and slave zones. Consequently, it is not currently possible to use rndc reload zonename to reload a redirect zone. However, when using rndc reload without specifying a zone name, redirect zones will be reloaded along with other zones. delegation-only This is used to enforce the delegation-only status of infrastructure zones (e.g. COM, NET, ORG). Any answer that is received without an explicit or implicit delegation in the authority section will be treated as NXDOMAIN. This does not apply to the zone apex. This should not be applied to leaf zones. delegation-only has no effect on answers received from forwarders. See caveats in . Class The zone's name may optionally be followed by a class. If a class is not specified, class IN (for Internet), is assumed. This is correct for the vast majority of cases. The hesiod class is named for an information service from MIT's Project Athena. It is used to share information about various systems databases, such as users, groups, printers and so on. The keyword HS is a synonym for hesiod. Another MIT development is Chaosnet, a LAN protocol created in the mid-1970s. Zone data for it can be specified with the CHAOS class. Zone Options allow-notify See the description of allow-notify in . allow-query See the description of allow-query in . allow-query-on See the description of allow-query-on in . allow-transfer See the description of allow-transfer in . allow-update See the description of allow-update in . update-policy Specifies a "Simple Secure Update" policy. See . allow-update-forwarding See the description of allow-update-forwarding in . also-notify Only meaningful if notify is active for this zone. The set of machines that will receive a DNS NOTIFY message for this zone is made up of all the listed name servers (other than the primary master) for the zone plus any IP addresses specified with also-notify. A port may be specified with each also-notify address to send the notify messages to a port other than the default of 53. A TSIG key may also be specified to cause the NOTIFY to be signed by the given key. also-notify is not meaningful for stub zones. The default is the empty list. check-names This option is used to restrict the character set and syntax of certain domain names in master files and/or DNS responses received from the network. The default varies according to zone type. For master zones the default is fail. For slave zones the default is warn. It is not implemented for hint zones. check-mx See the description of check-mx in . check-spf See the description of check-spf in . check-wildcard See the description of check-wildcard in . check-integrity See the description of check-integrity in . check-sibling See the description of check-sibling in . zero-no-soa-ttl See the description of zero-no-soa-ttl in . update-check-ksk See the description of update-check-ksk in . dnssec-update-mode See the description of dnssec-update-mode in . dnssec-dnskey-kskonly See the description of dnssec-dnskey-kskonly in . try-tcp-refresh See the description of try-tcp-refresh in . database Specify the type of database to be used for storing the zone data. The string following the database keyword is interpreted as a list of whitespace-delimited words. The first word identifies the database type, and any subsequent words are passed as arguments to the database to be interpreted in a way specific to the database type. The default is "rbt", BIND 9's native in-memory red-black-tree database. This database does not take arguments. Other values are possible if additional database drivers have been linked into the server. Some sample drivers are included with the distribution but none are linked in by default. dialup See the description of dialup in . delegation-only The flag only applies to forward, hint and stub zones. If set to yes, then the zone will also be treated as if it is also a delegation-only type zone. See caveats in . forward Only meaningful if the zone has a forwarders list. The only value causes the lookup to fail after trying the forwarders and getting no answer, while first would allow a normal lookup to be tried. forwarders Used to override the list of global forwarders. If it is not specified in a zone of type forward, no forwarding is done for the zone and the global options are not used. ixfr-base Was used in BIND 8 to specify the name of the transaction log (journal) file for dynamic update and IXFR. BIND 9 ignores the option and constructs the name of the journal file by appending ".jnl" to the name of the zone file. ixfr-tmp-file Was an undocumented option in BIND 8. Ignored in BIND 9. journal Allow the default journal's filename to be overridden. The default is the zone's filename with ".jnl" appended. This is applicable to master and slave zones. max-journal-size See the description of max-journal-size in . max-transfer-time-in See the description of max-transfer-time-in in . max-transfer-idle-in See the description of max-transfer-idle-in in . max-transfer-time-out See the description of max-transfer-time-out in . max-transfer-idle-out See the description of max-transfer-idle-out in . notify See the description of notify in . notify-delay See the description of notify-delay in . notify-to-soa See the description of notify-to-soa in . pubkey In BIND 8, this option was intended for specifying a public zone key for verification of signatures in DNSSEC signed zones when they are loaded from disk. BIND 9 does not verify signatures on load and ignores the option. zone-statistics If yes, the server will keep statistical information for this zone, which can be dumped to the statistics-file defined in the server options. server-addresses Only meaningful for static-stub zones. This is a list of IP addresses to which queries should be sent in recursive resolution for the zone. A non empty list for this option will internally configure the apex NS RR with associated glue A or AAAA RRs. For example, if "example.com" is configured as a static-stub zone with 192.0.2.1 and 2001:db8::1234 in a server-addresses option, the following RRs will be internally configured. example.com. NS example.com. example.com. A 192.0.2.1 example.com. AAAA 2001:db8::1234 These records are internally used to resolve names under the static-stub zone. For instance, if the server receives a query for "www.example.com" with the RD bit on, the server will initiate recursive resolution and send queries to 192.0.2.1 and/or 2001:db8::1234. server-names Only meaningful for static-stub zones. This is a list of domain names of nameservers that act as authoritative servers of the static-stub zone. These names will be resolved to IP addresses when named needs to send queries to these servers. To make this supplemental resolution successful, these names must not be a subdomain of the origin name of static-stub zone. That is, when "example.net" is the origin of a static-stub zone, "ns.example" and "master.example.com" can be specified in the server-names option, but "ns.example.net" cannot, and will be rejected by the configuration parser. A non empty list for this option will internally configure the apex NS RR with the specified names. For example, if "example.com" is configured as a static-stub zone with "ns1.example.net" and "ns2.example.net" in a server-names option, the following RRs will be internally configured. example.com. NS ns1.example.net. example.com. NS ns2.example.net. These records are internally used to resolve names under the static-stub zone. For instance, if the server receives a query for "www.example.com" with the RD bit on, the server initiate recursive resolution, resolve "ns1.example.net" and/or "ns2.example.net" to IP addresses, and then send queries to (one or more of) these addresses. sig-validity-interval See the description of sig-validity-interval in . sig-signing-nodes See the description of sig-signing-nodes in . sig-signing-signatures See the description of sig-signing-signatures in . sig-signing-type See the description of sig-signing-type in . transfer-source See the description of transfer-source in . transfer-source-v6 See the description of transfer-source-v6 in . alt-transfer-source See the description of alt-transfer-source in . alt-transfer-source-v6 See the description of alt-transfer-source-v6 in . use-alt-transfer-source See the description of use-alt-transfer-source in . notify-source See the description of notify-source in . notify-source-v6 See the description of notify-source-v6 in . min-refresh-time max-refresh-time min-retry-time max-retry-time See the description in . ixfr-from-differences See the description of ixfr-from-differences in . (Note that the ixfr-from-differences master and slave choices are not available at the zone level.) key-directory See the description of key-directory in . auto-dnssec Zones configured for dynamic DNS may also use this option to allow varying levels of automatic DNSSEC key management. There are three possible settings: auto-dnssec allow; permits keys to be updated and the zone fully re-signed whenever the user issues the command rndc sign zonename. auto-dnssec maintain; includes the above, but also automatically adjusts the zone's DNSSEC keys on schedule, according to the keys' timing metadata (see and ). The command rndc sign zonename causes named to load keys from the key repository and sign the zone with all keys that are active. rndc loadkeys zonename causes named to load keys from the key repository and schedule key maintenance events to occur in the future, but it does not sign the full zone immediately. Note: once keys have been loaded for a zone the first time, the repository will be searched for changes periodically, regardless of whether rndc loadkeys is used. The recheck interval is defined by dnssec-loadkeys-interval.) The default setting is auto-dnssec off. serial-update-method Zones configured for dynamic DNS may use this option to set the update method that will be used for the zone serial number in the SOA record. With the default setting of serial-update-method increment;, the SOA serial number will be incremented by one each time the zone is updated. When set to serial-update-method unixtime;, the SOA serial number will be set to the number of seconds since the UNIX epoch, unless the serial number is already greater than or equal to that value, in which case it is simply incremented by one. inline-signing If yes, this enables "bump in the wire" signing of a zone, where a unsigned zone is transferred in or loaded from disk and a signed version of the zone is served, with possibly, a different serial number. This behaviour is disabled by default. multi-master See the description of multi-master in . masterfile-format See the description of masterfile-format in . max-zone-ttl See the description of max-zone-ttl in . dnssec-secure-to-insecure See the description of dnssec-secure-to-insecure in . Dynamic Update Policies BIND 9 supports two alternative methods of granting clients the right to perform dynamic updates to a zone, configured by the allow-update and update-policy option, respectively. The allow-update clause works the same way as in previous versions of BIND. It grants given clients the permission to update any record of any name in the zone. The update-policy clause allows more fine-grained control over what updates are allowed. A set of rules is specified, where each rule either grants or denies permissions for one or more names to be updated by one or more identities. If the dynamic update request message is signed (that is, it includes either a TSIG or SIG(0) record), the identity of the signer can be determined. Rules are specified in the update-policy zone option, and are only meaningful for master zones. When the update-policy statement is present, it is a configuration error for the allow-update statement to be present. The update-policy statement only examines the signer of a message; the source address is not relevant. There is a pre-defined update-policy rule which can be switched on with the command update-policy local;. Switching on this rule in a zone causes named to generate a TSIG session key and place it in a file, and to allow that key to update the zone. (By default, the file is /var/run/named/session.key, the key name is "local-ddns" and the key algorithm is HMAC-SHA256, but these values are configurable with the session-keyfile, session-keyname and session-keyalg options, respectively). A client running on the local system, and with appropriate permissions, may read that file and use the key to sign update requests. The zone's update policy will be set to allow that key to change any record within the zone. Assuming the key name is "local-ddns", this policy is equivalent to: update-policy { grant local-ddns zonesub any; }; The command nsupdate -l sends update requests to localhost, and signs them using the session key. Other rule definitions look like this: ( grant | deny ) identity nametype name types Each rule grants or denies privileges. Once a message has successfully matched a rule, the operation is immediately granted or denied and no further rules are examined. A rule is matched when the signer matches the identity field, the name matches the name field in accordance with the nametype field, and the type matches the types specified in the type field. No signer is required for tcp-self or 6to4-self however the standard reverse mapping / prefix conversion must match the identity field. The identity field specifies a name or a wildcard name. Normally, this is the name of the TSIG or SIG(0) key used to sign the update request. When a TKEY exchange has been used to create a shared secret, the identity of the shared secret is the same as the identity of the key used to authenticate the TKEY exchange. TKEY is also the negotiation method used by GSS-TSIG, which establishes an identity that is the Kerberos principal of the client, such as "user@host.domain". When the identity field specifies a wildcard name, it is subject to DNS wildcard expansion, so the rule will apply to multiple identities. The identity field must contain a fully-qualified domain name. For nametypes krb5-self, ms-self, krb5-subdomain, and ms-subdomain the identity field specifies the Windows or Kerberos realm of the machine belongs to. The nametype field has 13 values: name, subdomain, wildcard, self, selfsub, selfwild, krb5-self, ms-self, krb5-subdomain, ms-subdomain, tcp-self, 6to4-self, zonesub, and external. name Exact-match semantics. This rule matches when the name being updated is identical to the contents of the name field. subdomain This rule matches when the name being updated is a subdomain of, or identical to, the contents of the name field. zonesub This rule is similar to subdomain, except that it matches when the name being updated is a subdomain of the zone in which the update-policy statement appears. This obviates the need to type the zone name twice, and enables the use of a standard update-policy statement in multiple zones without modification. When this rule is used, the name field is omitted. wildcard The name field is subject to DNS wildcard expansion, and this rule matches when the name being updated name is a valid expansion of the wildcard. self This rule matches when the name being updated matches the contents of the identity field. The name field is ignored, but should be the same as the identity field. The self nametype is most useful when allowing using one key per name to update, where the key has the same name as the name to be updated. The identity would be specified as * (an asterisk) in this case. selfsub This rule is similar to self except that subdomains of self can also be updated. selfwild This rule is similar to self except that only subdomains of self can be updated. ms-self This rule takes a Windows machine principal (machine$@REALM) for machine in REALM and and converts it machine.realm allowing the machine to update machine.realm. The REALM to be matched is specified in the identity field. ms-subdomain This rule takes a Windows machine principal (machine$@REALM) for machine in REALM and converts it to machine.realm allowing the machine to update subdomains of machine.realm. The REALM to be matched is specified in the identity field. krb5-self This rule takes a Kerberos machine principal (host/machine@REALM) for machine in REALM and and converts it machine.realm allowing the machine to update machine.realm. The REALM to be matched is specified in the identity field. krb5-subdomain This rule takes a Kerberos machine principal (host/machine@REALM) for machine in REALM and converts it to machine.realm allowing the machine to update subdomains of machine.realm. The REALM to be matched is specified in the identity field. tcp-self Allow updates that have been sent via TCP and for which the standard mapping from the initiating IP address into the IN-ADDR.ARPA and IP6.ARPA namespaces match the name to be updated. It is theoretically possible to spoof these TCP sessions. 6to4-self Allow the 6to4 prefix to be update by any TCP connection from the 6to4 network or from the corresponding IPv4 address. This is intended to allow NS or DNAME RRsets to be added to the reverse tree. It is theoretically possible to spoof these TCP sessions. external This rule allows named to defer the decision of whether to allow a given update to an external daemon. The method of communicating with the daemon is specified in the identity field, the format of which is "local:path", where path is the location of a UNIX-domain socket. (Currently, "local" is the only supported mechanism.) Requests to the external daemon are sent over the UNIX-domain socket as datagrams with the following format: Protocol version number (4 bytes, network byte order, currently 1) Request length (4 bytes, network byte order) Signer (null-terminated string) Name (null-terminated string) TCP source address (null-terminated string) Rdata type (null-terminated string) Key (null-terminated string) TKEY token length (4 bytes, network byte order) TKEY token (remainder of packet) The daemon replies with a four-byte value in network byte order, containing either 0 or 1; 0 indicates that the specified update is not permitted, and 1 indicates that it is. In all cases, the name field must specify a fully-qualified domain name. If no types are explicitly specified, this rule matches all types except RRSIG, NS, SOA, NSEC and NSEC3. Types may be specified by name, including "ANY" (ANY matches all types except NSEC and NSEC3, which can never be updated). Note that when an attempt is made to delete all records associated with a name, the rules are checked for each existing record type. Multiple views When multiple views are in use, a zone may be referenced by more than one of them. Often, the views will contain different zones with the same name, allowing different clients to receive different answers for the same queries. At times, however, it is desirable for multiple views to contain identical zones. The in-view zone option provides an efficient way to do this: it allows a view to reference a zone that was defined in a previously configured view. Example: view internal { match-clients { 10/8; }; zone example.com { type master; file "example-external.db"; }; }; view external { match-clients { any; }; zone example.com { in-view internal; }; }; An in-view option cannot refer to a view that is configured later in the configuration file. A zone statement which uses the in-view option may not use any other options with the exception of forward and forwarders. (These options control the behavior of the containing view, rather than changing the zone object itself.) Zone level acls (e.g. allow-query, allow-transfer) and other configuration details of the zone are all set in the view the referenced zone is defined in. Care need to be taken to ensure that acls are wide enough for all views referencing the zone. An in-view zone cannot be used as a response policy zone. An in-view zone is not intended to reference a forward zone. Zone File Types of Resource Records and When to Use Them This section, largely borrowed from RFC 1034, describes the concept of a Resource Record (RR) and explains when each is used. Since the publication of RFC 1034, several new RRs have been identified and implemented in the DNS. These are also included. Resource Records A domain name identifies a node. Each node has a set of resource information, which may be empty. The set of resource information associated with a particular name is composed of separate RRs. The order of RRs in a set is not significant and need not be preserved by name servers, resolvers, or other parts of the DNS. However, sorting of multiple RRs is permitted for optimization purposes, for example, to specify that a particular nearby server be tried first. See and . The components of a Resource Record are: owner name The domain name where the RR is found. type An encoded 16-bit value that specifies the type of the resource record. TTL The time-to-live of the RR. This field is a 32-bit integer in units of seconds, and is primarily used by resolvers when they cache RRs. The TTL describes how long a RR can be cached before it should be discarded. class An encoded 16-bit value that identifies a protocol family or instance of a protocol. RDATA The resource data. The format of the data is type (and sometimes class) specific. The following are types of valid RRs: A A host address. In the IN class, this is a 32-bit IP address. Described in RFC 1035. AAAA IPv6 address. Described in RFC 1886. A6 IPv6 address. This can be a partial address (a suffix) and an indirection to the name where the rest of the address (the prefix) can be found. Experimental. Described in RFC 2874. AFSDB Location of AFS database servers. Experimental. Described in RFC 1183. APL Address prefix list. Experimental. Described in RFC 3123. ATMA ATM Address. CAA Identifies which Certificate Authorities can issue certificates for this domain and what rules they need to follow when doing so. Defined in RFC 6844. CDNSKEY Identifies which DNSKEY records should be published as DS records in the parent zone. CDS Contains the set of DS records that should be published by the parent zone. CERT Holds a digital certificate. Described in RFC 2538. CNAME Identifies the canonical name of an alias. Described in RFC 1035. DHCID Is used for identifying which DHCP client is associated with this name. Described in RFC 4701. DLV A DNS Look-aside Validation record which contains the records that are used as trust anchors for zones in a DLV namespace. Described in RFC 4431. DNAME Replaces the domain name specified with another name to be looked up, effectively aliasing an entire subtree of the domain name space rather than a single record as in the case of the CNAME RR. Described in RFC 2672. DNSKEY Stores a public key associated with a signed DNS zone. Described in RFC 4034. DS Stores the hash of a public key associated with a signed DNS zone. Described in RFC 4034. EID End Point Identifier. EUI48 A 48-bit EUI address. Described in RFC 7043. EUI64 A 64-bit EUI address. Described in RFC 7043. GID Reserved. GPOS Specifies the global position. Superseded by LOC. HINFO Identifies the CPU and OS used by a host. Described in RFC 1035. HIP Host Identity Protocol Address. Described in RFC 5205. IPSECKEY Provides a method for storing IPsec keying material in DNS. Described in RFC 4025. ISDN Representation of ISDN addresses. Experimental. Described in RFC 1183. KEY Stores a public key associated with a DNS name. Used in original DNSSEC; replaced by DNSKEY in DNSSECbis, but still used with SIG(0). Described in RFCs 2535 and 2931. KX Identifies a key exchanger for this DNS name. Described in RFC 2230. L32 Holds 32-bit Locator values for Identifier-Locator Network Protocol. Described in RFC 6742. L64 Holds 64-bit Locator values for Identifier-Locator Network Protocol. Described in RFC 6742. LOC For storing GPS info. Described in RFC 1876. Experimental. LP Identifier-Locator Network Protocol. Described in RFC 6742. MB Mail Box. Historical. MD Mail Destination. Historical. MF Mail Forwarder. Historical. MG Mail Group. Historical. MINFO Mail Information. MR Mail Rename. Historical. MX Identifies a mail exchange for the domain with a 16-bit preference value (lower is better) followed by the host name of the mail exchange. Described in RFC 974, RFC 1035. NAPTR Name authority pointer. Described in RFC 2915. NID Holds values for Node Identifiers in Identifier-Locator Network Protocol. Described in RFC 6742. NIMLOC Nimrod Locator. NSAP A network service access point. Described in RFC 1706. NSAP-PTR Historical. NS The authoritative name server for the domain. Described in RFC 1035. NSEC Used in DNSSECbis to securely indicate that RRs with an owner name in a certain name interval do not exist in a zone and indicate what RR types are present for an existing name. Described in RFC 4034. NSEC3 Used in DNSSECbis to securely indicate that RRs with an owner name in a certain name interval do not exist in a zone and indicate what RR types are present for an existing name. NSEC3 differs from NSEC in that it prevents zone enumeration but is more computationally expensive on both the server and the client than NSEC. Described in RFC 5155. NSEC3PARAM Used in DNSSECbis to tell the authoritative server which NSEC3 chains are available to use. Described in RFC 5155. NULL This is an opaque container. NXT Used in DNSSEC to securely indicate that RRs with an owner name in a certain name interval do not exist in a zone and indicate what RR types are present for an existing name. Used in original DNSSEC; replaced by NSEC in DNSSECbis. Described in RFC 2535. OPENPGPKEY Used to hold an OPENPGPKEY. PTR A pointer to another part of the domain name space. Described in RFC 1035. PX Provides mappings between RFC 822 and X.400 addresses. Described in RFC 2163. RP Information on persons responsible for the domain. Experimental. Described in RFC 1183. RRSIG Contains DNSSECbis signature data. Described in RFC 4034. RT Route-through binding for hosts that do not have their own direct wide area network addresses. Experimental. Described in RFC 1183. SIG Contains DNSSEC signature data. Used in original DNSSEC; replaced by RRSIG in DNSSECbis, but still used for SIG(0). Described in RFCs 2535 and 2931. SOA Identifies the start of a zone of authority. Described in RFC 1035. SPF Contains the Sender Policy Framework information for a given email domain. Described in RFC 4408. SRV Information about well known network services (replaces WKS). Described in RFC 2782. SSHFP Provides a way to securely publish a secure shell key's fingerprint. Described in RFC 4255. TLSA Transport Layer Security Certificate Association. Described in RFC 6698. TXT Text records. Described in RFC 1035. UID Reserved. UINFO Reserved. UNSPEC Reserved. Historical. URI Holds a URI. Described in RFC 7553. WKS Information about which well known network services, such as SMTP, that a domain supports. Historical. X25 Representation of X.25 network addresses. Experimental. Described in RFC 1183. The following classes of resource records are currently valid in the DNS: IN The Internet. CH Chaosnet, a LAN protocol created at MIT in the mid-1970s. Rarely used for its historical purpose, but reused for BIND's built-in server information zones, e.g., version.bind. HS Hesiod, an information service developed by MIT's Project Athena. It is used to share information about various systems databases, such as users, groups, printers and so on. The owner name is often implicit, rather than forming an integral part of the RR. For example, many name servers internally form tree or hash structures for the name space, and chain RRs off nodes. The remaining RR parts are the fixed header (type, class, TTL) which is consistent for all RRs, and a variable part (RDATA) that fits the needs of the resource being described. The meaning of the TTL field is a time limit on how long an RR can be kept in a cache. This limit does not apply to authoritative data in zones; it is also timed out, but by the refreshing policies for the zone. The TTL is assigned by the administrator for the zone where the data originates. While short TTLs can be used to minimize caching, and a zero TTL prohibits caching, the realities of Internet performance suggest that these times should be on the order of days for the typical host. If a change can be anticipated, the TTL can be reduced prior to the change to minimize inconsistency during the change, and then increased back to its former value following the change. The data in the RDATA section of RRs is carried as a combination of binary strings and domain names. The domain names are frequently used as "pointers" to other data in the DNS. Textual expression of RRs RRs are represented in binary form in the packets of the DNS protocol, and are usually represented in highly encoded form when stored in a name server or resolver. In the examples provided in RFC 1034, a style similar to that used in master files was employed in order to show the contents of RRs. In this format, most RRs are shown on a single line, although continuation lines are possible using parentheses. The start of the line gives the owner of the RR. If a line begins with a blank, then the owner is assumed to be the same as that of the previous RR. Blank lines are often included for readability. Following the owner, we list the TTL, type, and class of the RR. Class and type use the mnemonics defined above, and TTL is an integer before the type field. In order to avoid ambiguity in parsing, type and class mnemonics are disjoint, TTLs are integers, and the type mnemonic is always last. The IN class and TTL values are often omitted from examples in the interests of clarity. The resource data or RDATA section of the RR are given using knowledge of the typical representation for the data. For example, we might show the RRs carried in a message as: ISI.EDU. MX 10 VENERA.ISI.EDU. MX 10 VAXA.ISI.EDU VENERA.ISI.EDU A 128.9.0.32 A 10.1.0.52 VAXA.ISI.EDU A 10.2.0.27 A 128.9.0.33 The MX RRs have an RDATA section which consists of a 16-bit number followed by a domain name. The address RRs use a standard IP address format to contain a 32-bit internet address. The above example shows six RRs, with two RRs at each of three domain names. Similarly we might see: XX.LCS.MIT.EDU. IN A 10.0.0.44 CH A MIT.EDU. 2420 This example shows two addresses for XX.LCS.MIT.EDU, each of a different class. Discussion of MX Records As described above, domain servers store information as a series of resource records, each of which contains a particular piece of information about a given domain name (which is usually, but not always, a host). The simplest way to think of a RR is as a typed pair of data, a domain name matched with a relevant datum, and stored with some additional type information to help systems determine when the RR is relevant. MX records are used to control delivery of email. The data specified in the record is a priority and a domain name. The priority controls the order in which email delivery is attempted, with the lowest number first. If two priorities are the same, a server is chosen randomly. If no servers at a given priority are responding, the mail transport agent will fall back to the next largest priority. Priority numbers do not have any absolute meaning — they are relevant only respective to other MX records for that domain name. The domain name given is the machine to which the mail will be delivered. It must have an associated address record (A or AAAA) — CNAME is not sufficient. For a given domain, if there is both a CNAME record and an MX record, the MX record is in error, and will be ignored. Instead, the mail will be delivered to the server specified in the MX record pointed to by the CNAME. For example: example.com. IN MX 10 mail.example.com. IN MX 10 mail2.example.com. IN MX 20 mail.backup.org. mail.example.com. IN A 10.0.0.1 mail2.example.com. IN A 10.0.0.2 Mail delivery will be attempted to mail.example.com and mail2.example.com (in any order), and if neither of those succeed, delivery to mail.backup.org will be attempted. Setting TTLs The time-to-live of the RR field is a 32-bit integer represented in units of seconds, and is primarily used by resolvers when they cache RRs. The TTL describes how long a RR can be cached before it should be discarded. The following three types of TTL are currently used in a zone file. SOA The last field in the SOA is the negative caching TTL. This controls how long other servers will cache no-such-domain (NXDOMAIN) responses from you. The maximum time for negative caching is 3 hours (3h). $TTL The $TTL directive at the top of the zone file (before the SOA) gives a default TTL for every RR without a specific TTL set. RR TTLs Each RR can have a TTL as the second field in the RR, which will control how long other servers can cache it. All of these TTLs default to units of seconds, though units can be explicitly specified, for example, 1h30m. Inverse Mapping in IPv4 Reverse name resolution (that is, translation from IP address to name) is achieved by means of the in-addr.arpa domain and PTR records. Entries in the in-addr.arpa domain are made in least-to-most significant order, read left to right. This is the opposite order to the way IP addresses are usually written. Thus, a machine with an IP address of 10.1.2.3 would have a corresponding in-addr.arpa name of 3.2.1.10.in-addr.arpa. This name should have a PTR resource record whose data field is the name of the machine or, optionally, multiple PTR records if the machine has more than one name. For example, in the example.com domain: $ORIGIN 2.1.10.in-addr.arpa 3 IN PTR foo.example.com. The $ORIGIN lines in the examples are for providing context to the examples only — they do not necessarily appear in the actual usage. They are only used here to indicate that the example is relative to the listed origin. Other Zone File Directives The Master File Format was initially defined in RFC 1035 and has subsequently been extended. While the Master File Format itself is class independent all records in a Master File must be of the same class. Master File Directives include $ORIGIN, $INCLUDE, and $TTL. The <command>@</command> (at-sign) When used in the label (or name) field, the asperand or at-sign (@) symbol represents the current origin. At the start of the zone file, it is the <zone_name> (followed by trailing dot). The <command>$ORIGIN</command> Directive Syntax: $ORIGIN domain-name comment $ORIGIN sets the domain name that will be appended to any unqualified records. When a zone is first read in there is an implicit $ORIGIN <zone_name>. (followed by trailing dot). The current $ORIGIN is appended to the domain specified in the $ORIGIN argument if it is not absolute. $ORIGIN example.com. WWW CNAME MAIN-SERVER is equivalent to WWW.EXAMPLE.COM. CNAME MAIN-SERVER.EXAMPLE.COM. The <command>$INCLUDE</command> Directive Syntax: $INCLUDE filename origin comment Read and process the file filename as if it were included into the file at this point. If origin is specified the file is processed with $ORIGIN set to that value, otherwise the current $ORIGIN is used. The origin and the current domain name revert to the values they had prior to the $INCLUDE once the file has been read. RFC 1035 specifies that the current origin should be restored after an $INCLUDE, but it is silent on whether the current domain name should also be restored. BIND 9 restores both of them. This could be construed as a deviation from RFC 1035, a feature, or both. The <command>$TTL</command> Directive Syntax: $TTL default-ttl comment Set the default Time To Live (TTL) for subsequent records with undefined TTLs. Valid TTLs are of the range 0-2147483647 seconds. $TTL is defined in RFC 2308. <acronym>BIND</acronym> Master File Extension: the <command>$GENERATE</command> Directive Syntax: $GENERATE range lhs ttl class type rhs comment $GENERATE is used to create a series of resource records that only differ from each other by an iterator. $GENERATE can be used to easily generate the sets of records required to support sub /24 reverse delegations described in RFC 2317: Classless IN-ADDR.ARPA delegation. $ORIGIN 0.0.192.IN-ADDR.ARPA. $GENERATE 1-2 @ NS SERVER$.EXAMPLE. $GENERATE 1-127 $ CNAME $.0 is equivalent to 0.0.0.192.IN-ADDR.ARPA. NS SERVER1.EXAMPLE. 0.0.0.192.IN-ADDR.ARPA. NS SERVER2.EXAMPLE. 1.0.0.192.IN-ADDR.ARPA. CNAME 1.0.0.0.192.IN-ADDR.ARPA. 2.0.0.192.IN-ADDR.ARPA. CNAME 2.0.0.0.192.IN-ADDR.ARPA. ... 127.0.0.192.IN-ADDR.ARPA. CNAME 127.0.0.0.192.IN-ADDR.ARPA. Generate a set of A and MX records. Note the MX's right hand side is a quoted string. The quotes will be stripped when the right hand side is processed. $ORIGIN EXAMPLE. $GENERATE 1-127 HOST-$ A 1.2.3.$ $GENERATE 1-127 HOST-$ MX "0 ." is equivalent to HOST-1.EXAMPLE. A 1.2.3.1 HOST-1.EXAMPLE. MX 0 . HOST-2.EXAMPLE. A 1.2.3.2 HOST-2.EXAMPLE. MX 0 . HOST-3.EXAMPLE. A 1.2.3.3 HOST-3.EXAMPLE. MX 0 . ... HOST-127.EXAMPLE. A 1.2.3.127 HOST-127.EXAMPLE. MX 0 . range This can be one of two forms: start-stop or start-stop/step. If the first form is used, then step is set to 1. start, stop and step must be positive integers between 0 and (2^31)-1. start must not be larger than stop. lhs This describes the owner name of the resource records to be created. Any single $ (dollar sign) symbols within the lhs string are replaced by the iterator value. To get a $ in the output, you need to escape the $ using a backslash \, e.g. \$. The $ may optionally be followed by modifiers which change the offset from the iterator, field width and base. Modifiers are introduced by a { (left brace) immediately following the $ as ${offset[,width[,base]]}. For example, ${-20,3,d} subtracts 20 from the current value, prints the result as a decimal in a zero-padded field of width 3. Available output forms are decimal (d), octal (o), hexadecimal (x or X for uppercase) and nibble (n or N\ for uppercase). The default modifier is ${0,0,d}. If the lhs is not absolute, the current $ORIGIN is appended to the name. In nibble mode the value will be treated as if it was a reversed hexadecimal string with each hexadecimal digit as a separate label. The width field includes the label separator. For compatibility with earlier versions, $$ is still recognized as indicating a literal $ in the output. ttl Specifies the time-to-live of the generated records. If not specified this will be inherited using the normal TTL inheritance rules. class and ttl can be entered in either order. class Specifies the class of the generated records. This must match the zone class if it is specified. class and ttl can be entered in either order. type Any valid type. rhs rhs, optionally, quoted string. The $GENERATE directive is a BIND extension and not part of the standard zone file format. BIND 8 does not support the optional TTL and CLASS fields. Additional File Formats In addition to the standard textual format, BIND 9 supports the ability to read or dump to zone files in other formats. The raw format is a binary representation of zone data in a manner similar to that used in zone transfers. Since it does not require parsing text, load time is significantly reduced. An even faster alternative is the map format, which is an image of a BIND 9 in-memory zone database; it is capable of being loaded directly into memory via the mmap() function; the zone can begin serving queries almost immediately. For a primary server, a zone file in raw or map format is expected to be generated from a textual zone file by the named-compilezone command. For a secondary server or for a dynamic zone, it is automatically generated (if this format is specified by the masterfile-format option) when named dumps the zone contents after zone transfer or when applying prior updates. If a zone file in a binary format needs manual modification, it first must be converted to a textual form by the named-compilezone command. All necessary modification should go to the text file, which should then be converted to the binary form by the named-compilezone command again. Note that map format is extremely architecture-specific. A map file cannot be used on a system with different pointer size, endianness or data alignment than the system on which it was generated, and should in general be used only inside a single system. While raw format uses network byte order and avoids architecture-dependent data alignment so that it is as portable as possible, it is also primarily expected to be used inside the same single system. To export a zone file in either raw or map format, or make a portable backup of such a file, conversion to text format is recommended. BIND9 Statistics BIND 9 maintains lots of statistics information and provides several interfaces for users to get access to the statistics. The available statistics include all statistics counters that were available in BIND 8 and are meaningful in BIND 9, and other information that is considered useful. The statistics information is categorized into the following sections. Incoming Requests The number of incoming DNS requests for each OPCODE. Incoming Queries The number of incoming queries for each RR type. Outgoing Queries The number of outgoing queries for each RR type sent from the internal resolver. Maintained per view. Name Server Statistics Statistics counters about incoming request processing. Zone Maintenance Statistics Statistics counters regarding zone maintenance operations such as zone transfers. Resolver Statistics Statistics counters about name resolution performed in the internal resolver. Maintained per view. Cache DB RRsets The number of RRsets per RR type and nonexistent names stored in the cache database. If the exclamation mark (!) is printed for a RR type, it means that particular type of RRset is known to be nonexistent (this is also known as "NXRRSET"). If a hash mark (#) is present then the RRset is marked for garbage collection. Maintained per view. Socket I/O Statistics Statistics counters about network related events. A subset of Name Server Statistics is collected and shown per zone for which the server has the authority when zone-statistics is set to yes. These statistics counters are shown with their zone and view names. In some cases the view names are omitted for the default view. There are currently two user interfaces to get access to the statistics. One is in the plain text format dumped to the file specified by the statistics-file configuration option. The other is remotely accessible via a statistics channel when the statistics-channels statement is specified in the configuration file (see .) The Statistics File The text format statistics dump begins with a line, like: +++ Statistics Dump +++ (973798949) The number in parentheses is a standard Unix-style timestamp, measured as seconds since January 1, 1970. Following that line is a set of statistics information, which is categorized as described above. Each section begins with a line, like: ++ Name Server Statistics ++ Each section consists of lines, each containing the statistics counter value followed by its textual description. See below for available counters. For brevity, counters that have a value of 0 are not shown in the statistics file. The statistics dump ends with the line where the number is identical to the number in the beginning line; for example: --- Statistics Dump --- (973798949) Statistics Counters The following tables summarize statistics counters that BIND 9 provides. For each row of the tables, the leftmost column is the abbreviated symbol name of that counter. These symbols are shown in the statistics information accessed via an HTTP statistics channel. The rightmost column gives the description of the counter, which is also shown in the statistics file (but, in this document, possibly with slight modification for better readability). Additional notes may also be provided in this column. When a middle column exists between these two columns, it gives the corresponding counter name of the BIND 8 statistics, if applicable. Name Server Statistics Counters Symbol BIND8 Symbol Description Requestv4 RQ IPv4 requests received. Note: this also counts non query requests. Requestv6 RQ IPv6 requests received. Note: this also counts non query requests. ReqEdns0 Requests with EDNS(0) received. ReqBadEDNSVer Requests with unsupported EDNS version received. ReqTSIG Requests with TSIG received. ReqSIG0 Requests with SIG(0) received. ReqBadSIG Requests with invalid (TSIG or SIG(0)) signature. ReqTCP RTCP TCP requests received. AuthQryRej RUQ Authoritative (non recursive) queries rejected. RecQryRej RURQ Recursive queries rejected. XfrRej RUXFR Zone transfer requests rejected. UpdateRej RUUpd Dynamic update requests rejected. Response SAns Responses sent. RespTruncated Truncated responses sent. RespEDNS0 Responses with EDNS(0) sent. RespTSIG Responses with TSIG sent. RespSIG0 Responses with SIG(0) sent. QrySuccess Queries resulted in a successful answer. This means the query which returns a NOERROR response with at least one answer RR. This corresponds to the success counter of previous versions of BIND 9. QryAuthAns Queries resulted in authoritative answer. QryNoauthAns SNaAns Queries resulted in non authoritative answer. QryReferral Queries resulted in referral answer. This corresponds to the referral counter of previous versions of BIND 9. QryNxrrset Queries resulted in NOERROR responses with no data. This corresponds to the nxrrset counter of previous versions of BIND 9. QrySERVFAIL SFail Queries resulted in SERVFAIL. QryFORMERR SFErr Queries resulted in FORMERR. QryNXDOMAIN SNXD Queries resulted in NXDOMAIN. This corresponds to the nxdomain counter of previous versions of BIND 9. QryRecursion RFwdQ Queries which caused the server to perform recursion in order to find the final answer. This corresponds to the recursion counter of previous versions of BIND 9. QryDuplicate RDupQ Queries which the server attempted to recurse but discovered an existing query with the same IP address, port, query ID, name, type and class already being processed. This corresponds to the duplicate counter of previous versions of BIND 9. QryDropped Recursive queries for which the server discovered an excessive number of existing recursive queries for the same name, type and class and were subsequently dropped. This is the number of dropped queries due to the reason explained with the clients-per-query and max-clients-per-query options (see the description about .) This corresponds to the dropped counter of previous versions of BIND 9. QryFailure Other query failures. This corresponds to the failure counter of previous versions of BIND 9. Note: this counter is provided mainly for backward compatibility with the previous versions. Normally a more fine-grained counters such as AuthQryRej and RecQryRej that would also fall into this counter are provided, and so this counter would not be of much interest in practice. XfrReqDone Requested zone transfers completed. UpdateReqFwd Update requests forwarded. UpdateRespFwd Update responses forwarded. UpdateFwdFail Dynamic update forward failed. UpdateDone Dynamic updates completed. UpdateFail Dynamic updates failed. UpdateBadPrereq Dynamic updates rejected due to prerequisite failure. RateDropped Responses dropped by rate limits. RateSlipped Responses truncated by rate limits. RPZRewrites Response policy zone rewrites. Zone Maintenance Statistics Counters Symbol Description NotifyOutv4 IPv4 notifies sent. NotifyOutv6 IPv6 notifies sent. NotifyInv4 IPv4 notifies received. NotifyInv6 IPv6 notifies received. NotifyRej Incoming notifies rejected. SOAOutv4 IPv4 SOA queries sent. SOAOutv6 IPv6 SOA queries sent. AXFRReqv4 IPv4 AXFR requested. AXFRReqv6 IPv6 AXFR requested. IXFRReqv4 IPv4 IXFR requested. IXFRReqv6 IPv6 IXFR requested. XfrSuccess Zone transfer requests succeeded. XfrFail Zone transfer requests failed. Resolver Statistics Counters Symbol BIND8 Symbol Description Queryv4 SFwdQ IPv4 queries sent. Queryv6 SFwdQ IPv6 queries sent. Responsev4 RR IPv4 responses received. Responsev6 RR IPv6 responses received. NXDOMAIN RNXD NXDOMAIN received. SERVFAIL RFail SERVFAIL received. FORMERR RFErr FORMERR received. OtherError RErr Other errors received. EDNS0Fail EDNS(0) query failures. Mismatch RDupR Mismatch responses received. The DNS ID, response's source address, and/or the response's source port does not match what was expected. (The port must be 53 or as defined by the port option.) This may be an indication of a cache poisoning attempt. Truncated Truncated responses received. Lame RLame Lame delegations received. Retry SDupQ Query retries performed. QueryAbort Queries aborted due to quota control. QuerySockFail Failures in opening query sockets. One common reason for such failures is a failure of opening a new socket due to a limitation on file descriptors. QueryTimeout Query timeouts. GlueFetchv4 SSysQ IPv4 NS address fetches invoked. GlueFetchv6 SSysQ IPv6 NS address fetches invoked. GlueFetchv4Fail IPv4 NS address fetch failed. GlueFetchv6Fail IPv6 NS address fetch failed. ValAttempt DNSSEC validation attempted. ValOk DNSSEC validation succeeded. ValNegOk DNSSEC validation on negative information succeeded. ValFail DNSSEC validation failed. QryRTTnn Frequency table on round trip times (RTTs) of queries. Each nn specifies the corresponding frequency. In the sequence of nn_1, nn_2, ..., nn_m, the value of nn_i is the number of queries whose RTTs are between nn_(i-1) (inclusive) and nn_i (exclusive) milliseconds. For the sake of convenience we define nn_0 to be 0. The last entry should be represented as nn_m+, which means the number of queries whose RTTs are equal to or over nn_m milliseconds. Socket I/O Statistics Counters Socket I/O statistics counters are defined per socket types, which are UDP4 (UDP/IPv4), UDP6 (UDP/IPv6), TCP4 (TCP/IPv4), TCP6 (TCP/IPv6), Unix (Unix Domain), and FDwatch (sockets opened outside the socket module). In the following table <TYPE> represents a socket type. Not all counters are available for all socket types; exceptions are noted in the description field. Symbol Description <TYPE>Open Sockets opened successfully. This counter is not applicable to the FDwatch type. <TYPE>OpenFail Failures of opening sockets. This counter is not applicable to the FDwatch type. <TYPE>Close Sockets closed. <TYPE>BindFail Failures of binding sockets. <TYPE>ConnFail Failures of connecting sockets. <TYPE>Conn Connections established successfully. <TYPE>AcceptFail Failures of accepting incoming connection requests. This counter is not applicable to the UDP and FDwatch types. <TYPE>Accept Incoming connections successfully accepted. This counter is not applicable to the UDP and FDwatch types. <TYPE>SendErr Errors in socket send operations. This counter corresponds to SErr counter of BIND 8. <TYPE>RecvErr Errors in socket receive operations. This includes errors of send operations on a connected UDP socket notified by an ICMP error message. Compatibility with <emphasis>BIND</emphasis> 8 Counters Most statistics counters that were available in BIND 8 are also supported in BIND 9 as shown in the above tables. Here are notes about other counters that do not appear in these tables. RFwdR,SFwdR These counters are not supported because BIND 9 does not adopt the notion of forwarding as BIND 8 did. RAXFR This counter is accessible in the Incoming Queries section. RIQ This counter is accessible in the Incoming Requests section. ROpts This counter is not supported because BIND 9 does not care about IP options in the first place. <acronym>BIND</acronym> 9 Security Considerations Access Control Lists Access Control Lists (ACLs) are address match lists that you can set up and nickname for future use in allow-notify, allow-query, allow-query-on, allow-recursion, allow-recursion-on, blackhole, allow-transfer, etc. Using ACLs allows you to have finer control over who can access your name server, without cluttering up your config files with huge lists of IP addresses. It is a good idea to use ACLs, and to control access to your server. Limiting access to your server by outside parties can help prevent spoofing and denial of service (DoS) attacks against your server. Here is an example of how to properly apply ACLs: // Set up an ACL named "bogusnets" that will block // RFC1918 space and some reserved space, which is // commonly used in spoofing attacks. acl bogusnets { 0.0.0.0/8; 192.0.2.0/24; 224.0.0.0/3; 10.0.0.0/8; 172.16.0.0/12; 192.168.0.0/16; }; // Set up an ACL called our-nets. Replace this with the // real IP numbers. acl our-nets { x.x.x.x/24; x.x.x.x/21; }; options { ... ... allow-query { our-nets; }; allow-recursion { our-nets; }; ... blackhole { bogusnets; }; ... }; zone "example.com" { type master; file "m/example.com"; allow-query { any; }; }; This allows recursive queries of the server from the outside unless recursion has been previously disabled. <command>Chroot</command> and <command>Setuid</command> On UNIX servers, it is possible to run BIND in a chrooted environment (using the chroot() function) by specifying the "" option for named. This can help improve system security by placing BIND in a "sandbox", which will limit the damage done if a server is compromised. Another useful feature in the UNIX version of BIND is the ability to run the daemon as an unprivileged user ( user ). We suggest running as an unprivileged user when using the chroot feature. Here is an example command line to load BIND in a chroot sandbox, /var/named, and to run named setuid to user 202: /usr/local/sbin/named -u 202 -t /var/named The <command>chroot</command> Environment In order for a chroot environment to work properly in a particular directory (for example, /var/named), you will need to set up an environment that includes everything BIND needs to run. From BIND's point of view, /var/named is the root of the filesystem. You will need to adjust the values of options like like directory and pid-file to account for this. Unlike with earlier versions of BIND, you typically will not need to compile named statically nor install shared libraries under the new root. However, depending on your operating system, you may need to set up things like /dev/zero, /dev/random, /dev/log, and /etc/localtime. Using the <command>setuid</command> Function Prior to running the named daemon, use the touch utility (to change file access and modification times) or the chown utility (to set the user id and/or group id) on files to which you want BIND to write. Note that if the named daemon is running as an unprivileged user, it will not be able to bind to new restricted ports if the server is reloaded. Dynamic Update Security Access to the dynamic update facility should be strictly limited. In earlier versions of BIND, the only way to do this was based on the IP address of the host requesting the update, by listing an IP address or network prefix in the allow-update zone option. This method is insecure since the source address of the update UDP packet is easily forged. Also note that if the IP addresses allowed by the allow-update option include the address of a slave server which performs forwarding of dynamic updates, the master can be trivially attacked by sending the update to the slave, which will forward it to the master with its own source IP address causing the master to approve it without question. For these reasons, we strongly recommend that updates be cryptographically authenticated by means of transaction signatures (TSIG). That is, the allow-update option should list only TSIG key names, not IP addresses or network prefixes. Alternatively, the new update-policy option can be used. Some sites choose to keep all dynamically-updated DNS data in a subdomain and delegate that subdomain to a separate zone. This way, the top-level zone containing critical data such as the IP addresses of public web and mail servers need not allow dynamic update at all. Troubleshooting Common Problems It's not working; how can I figure out what's wrong? The best solution to solving installation and configuration issues is to take preventative measures by setting up logging files beforehand. The log files provide a source of hints and information that can be used to figure out what went wrong and how to fix the problem. Incrementing and Changing the Serial Number Zone serial numbers are just numbers — they aren't date related. A lot of people set them to a number that represents a date, usually of the form YYYYMMDDRR. Occasionally they will make a mistake and set them to a "date in the future" then try to correct them by setting them to the "current date". This causes problems because serial numbers are used to indicate that a zone has been updated. If the serial number on the slave server is lower than the serial number on the master, the slave server will attempt to update its copy of the zone. Setting the serial number to a lower number on the master server than the slave server means that the slave will not perform updates to its copy of the zone. The solution to this is to add 2147483647 (2^31-1) to the number, reload the zone and make sure all slaves have updated to the new zone serial number, then reset the number to what you want it to be, and reload the zone again. Where Can I Get Help? The Internet Systems Consortium (ISC) offers a wide range of support and service agreements for BIND and DHCP servers. Four levels of premium support are available and each level includes support for all ISC programs, significant discounts on products and training, and a recognized priority on bug fixes and non-funded feature requests. In addition, ISC offers a standard support agreement package which includes services ranging from bug fix announcements to remote support. It also includes training in BIND and DHCP. To discuss arrangements for support, contact info@isc.org or visit the ISC web page at http://www.isc.org/services/support/ to read more. Release Notes A Brief History of the <acronym>DNS</acronym> and <acronym>BIND</acronym> Although the "official" beginning of the Domain Name System occurred in 1984 with the publication of RFC 920, the core of the new system was described in 1983 in RFCs 882 and 883. From 1984 to 1987, the ARPAnet (the precursor to today's Internet) became a testbed of experimentation for developing the new naming/addressing scheme in a rapidly expanding, operational network environment. New RFCs were written and published in 1987 that modified the original documents to incorporate improvements based on the working model. RFC 1034, "Domain Names-Concepts and Facilities", and RFC 1035, "Domain Names-Implementation and Specification" were published and became the standards upon which all DNS implementations are built. The first working domain name server, called "Jeeves", was written in 1983-84 by Paul Mockapetris for operation on DEC Tops-20 machines located at the University of Southern California's Information Sciences Institute (USC-ISI) and SRI International's Network Information Center (SRI-NIC). A DNS server for Unix machines, the Berkeley Internet Name Domain (BIND) package, was written soon after by a group of graduate students at the University of California at Berkeley under a grant from the US Defense Advanced Research Projects Administration (DARPA). Versions of BIND through 4.8.3 were maintained by the Computer Systems Research Group (CSRG) at UC Berkeley. Douglas Terry, Mark Painter, David Riggle and Songnian Zhou made up the initial BIND project team. After that, additional work on the software package was done by Ralph Campbell. Kevin Dunlap, a Digital Equipment Corporation employee on loan to the CSRG, worked on BIND for 2 years, from 1985 to 1987. Many other people also contributed to BIND development during that time: Doug Kingston, Craig Partridge, Smoot Carl-Mitchell, Mike Muuss, Jim Bloom and Mike Schwartz. BIND maintenance was subsequently handled by Mike Karels and Øivind Kure. BIND versions 4.9 and 4.9.1 were released by Digital Equipment Corporation (now Compaq Computer Corporation). Paul Vixie, then a DEC employee, became BIND's primary caretaker. He was assisted by Phil Almquist, Robert Elz, Alan Barrett, Paul Albitz, Bryan Beecher, Andrew Partan, Andy Cherenson, Tom Limoncelli, Berthold Paffrath, Fuat Baran, Anant Kumar, Art Harkin, Win Treese, Don Lewis, Christophe Wolfhugel, and others. In 1994, BIND version 4.9.2 was sponsored by Vixie Enterprises. Paul Vixie became BIND's principal architect/programmer. BIND versions from 4.9.3 onward have been developed and maintained by the Internet Systems Consortium and its predecessor, the Internet Software Consortium, with support being provided by ISC's sponsors. As co-architects/programmers, Bob Halley and Paul Vixie released the first production-ready version of BIND version 8 in May 1997. BIND version 9 was released in September 2000 and is a major rewrite of nearly all aspects of the underlying BIND architecture. BIND versions 4 and 8 are officially deprecated. No additional development is done on BIND version 4 or BIND version 8. BIND development work is made possible today by the sponsorship of several corporations, and by the tireless work efforts of numerous individuals. General <acronym>DNS</acronym> Reference Information IPv6 addresses (AAAA) IPv6 addresses are 128-bit identifiers for interfaces and sets of interfaces which were introduced in the DNS to facilitate scalable Internet routing. There are three types of addresses: Unicast, an identifier for a single interface; Anycast, an identifier for a set of interfaces; and Multicast, an identifier for a set of interfaces. Here we describe the global Unicast address scheme. For more information, see RFC 3587, "Global Unicast Address Format." IPv6 unicast addresses consist of a global routing prefix, a subnet identifier, and an interface identifier. The global routing prefix is provided by the upstream provider or ISP, and (roughly) corresponds to the IPv4 network section of the address range. The subnet identifier is for local subnetting, much the same as subnetting an IPv4 /16 network into /24 subnets. The interface identifier is the address of an individual interface on a given network; in IPv6, addresses belong to interfaces rather than to machines. The subnetting capability of IPv6 is much more flexible than that of IPv4: subnetting can be carried out on bit boundaries, in much the same way as Classless InterDomain Routing (CIDR), and the DNS PTR representation ("nibble" format) makes setting up reverse zones easier. The Interface Identifier must be unique on the local link, and is usually generated automatically by the IPv6 implementation, although it is usually possible to override the default setting if necessary. A typical IPv6 address might look like: 2001:db8:201:9:a00:20ff:fe81:2b32 IPv6 address specifications often contain long strings of zeros, so the architects have included a shorthand for specifying them. The double colon (`::') indicates the longest possible string of zeros that can fit, and can be used only once in an address. Bibliography (and Suggested Reading) Request for Comments (RFCs) Specification documents for the Internet protocol suite, including the DNS, are published as part of the Request for Comments (RFCs) series of technical notes. The standards themselves are defined by the Internet Engineering Task Force (IETF) and the Internet Engineering Steering Group (IESG). RFCs can be obtained online via FTP at: ftp://www.isi.edu/in-notes/RFCxxxx.txt (where xxxx is the number of the RFC). RFCs are also available via the Web at: http://www.ietf.org/rfc/. Standards RFC974 Partridge C. Mail Routing and the Domain System January 1986 RFC1034 Mockapetris P.V. Domain Names — Concepts and Facilities November 1987 RFC1035 Mockapetris P. V. Domain Names — Implementation and Specification November 1987 Proposed Standards RFC2181 Elz R., R. Bush Clarifications to the <acronym>DNS</acronym> Specification July 1997 RFC2308 Andrews M. Negative Caching of <acronym>DNS</acronym> Queries March 1998 RFC1995 Ohta M. Incremental Zone Transfer in <acronym>DNS</acronym> August 1996 RFC1996 Vixie P. A Mechanism for Prompt Notification of Zone Changes August 1996 RFC2136 Vixie P. S. Thomson Y. Rekhter J. Bound Dynamic Updates in the Domain Name System April 1997 RFC2671 P. Vixie Extension Mechanisms for DNS (EDNS0) August 1997 RFC2672 M. Crawford Non-Terminal DNS Name Redirection August 1999 RFC2845 Vixie P. O. Gudmundsson D. Eastlake 3rd B. Wellington Secret Key Transaction Authentication for <acronym>DNS</acronym> (TSIG) May 2000 RFC2930 D. Eastlake 3rd Secret Key Establishment for DNS (TKEY RR) September 2000 RFC2931 D. Eastlake 3rd DNS Request and Transaction Signatures (SIG(0)s) September 2000 RFC3007 B. Wellington Secure Domain Name System (DNS) Dynamic Update November 2000 RFC3645 S. Kwan P. Garg J. Gilroy L. Esibov J. Westhead R. Hall Generic Security Service Algorithm for Secret Key Transaction Authentication for DNS (GSS-TSIG) October 2003 <acronym>DNS</acronym> Security Proposed Standards RFC3225 D. Conrad Indicating Resolver Support of DNSSEC December 2001 RFC3833 D. Atkins R. Austein Threat Analysis of the Domain Name System (DNS) August 2004 RFC4033 R. Arends R. Austein M. Larson D. Massey S. Rose DNS Security Introduction and Requirements March 2005 RFC4034 R. Arends R. Austein M. Larson D. Massey S. Rose Resource Records for the DNS Security Extensions March 2005 RFC4035 R. Arends R. Austein M. Larson D. Massey S. Rose Protocol Modifications for the DNS Security Extensions March 2005 Other Important RFCs About <acronym>DNS</acronym> Implementation RFC1535 Gavron E. A Security Problem and Proposed Correction With Widely Deployed <acronym>DNS</acronym> Software. October 1993 RFC1536 Kumar A. J. Postel C. Neuman P. Danzig S. Miller Common <acronym>DNS</acronym> Implementation Errors and Suggested Fixes October 1993 RFC1982 Elz R. R. Bush Serial Number Arithmetic August 1996 RFC4074 Morishita Y. T. Jinmei Common Misbehaviour Against <acronym>DNS</acronym> Queries for IPv6 Addresses May 2005 Resource Record Types RFC1183 Everhart C.F. L. A. Mamakos R. Ullmann P. Mockapetris New <acronym>DNS</acronym> RR Definitions October 1990 RFC1706 Manning B. R. Colella <acronym>DNS</acronym> NSAP Resource Records October 1994 RFC2168 Daniel R. M. Mealling Resolution of Uniform Resource Identifiers using the Domain Name System June 1997 RFC1876 Davis C. P. Vixie T. Goodwin I. Dickinson A Means for Expressing Location Information in the Domain Name System January 1996 RFC2052 Gulbrandsen A. P. Vixie A <acronym>DNS</acronym> RR for Specifying the Location of Services. October 1996 RFC2163 Allocchio A. Using the Internet <acronym>DNS</acronym> to Distribute MIXER Conformant Global Address Mapping January 1998 RFC2230 Atkinson R. Key Exchange Delegation Record for the <acronym>DNS</acronym> October 1997 RFC2536 Eastlake D. 3rd DSA KEYs and SIGs in the Domain Name System (DNS) March 1999 RFC2537 Eastlake D. 3rd RSA/MD5 KEYs and SIGs in the Domain Name System (DNS) March 1999 RFC2538 Eastlake D. 3rd Gudmundsson O. Storing Certificates in the Domain Name System (DNS) March 1999 RFC2539 Eastlake D. 3rd Storage of Diffie-Hellman Keys in the Domain Name System (DNS) March 1999 RFC2540 Eastlake D. 3rd Detached Domain Name System (DNS) Information March 1999 RFC2782 Gulbrandsen A. Vixie P. Esibov L. A DNS RR for specifying the location of services (DNS SRV) February 2000 RFC2915 Mealling M. Daniel R. The Naming Authority Pointer (NAPTR) DNS Resource Record September 2000 RFC3110 Eastlake D. 3rd RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS) May 2001 RFC3123 Koch P. A DNS RR Type for Lists of Address Prefixes (APL RR) June 2001 RFC3596 Thomson S. C. Huitema V. Ksinant M. Souissi <acronym>DNS</acronym> Extensions to support IP version 6 October 2003 RFC3597 Gustafsson A. Handling of Unknown DNS Resource Record (RR) Types September 2003 <acronym>DNS</acronym> and the Internet RFC1101 Mockapetris P. V. <acronym>DNS</acronym> Encoding of Network Names and Other Types April 1989 RFC1123 Braden R. Requirements for Internet Hosts - Application and Support October 1989 RFC1591 Postel J. Domain Name System Structure and Delegation March 1994 RFC2317 Eidnes H. G. de Groot P. Vixie Classless IN-ADDR.ARPA Delegation March 1998 RFC2826 Internet Architecture Board IAB Technical Comment on the Unique DNS Root May 2000 RFC2929 Eastlake D. 3rd Brunner-Williams E. Manning B. Domain Name System (DNS) IANA Considerations September 2000 <acronym>DNS</acronym> Operations RFC1033 Lottor M. Domain administrators operations guide. November 1987 RFC1537 Beertema P. Common <acronym>DNS</acronym> Data File Configuration Errors October 1993 RFC1912 Barr D. Common <acronym>DNS</acronym> Operational and Configuration Errors February 1996 RFC2010 Manning B. P. Vixie Operational Criteria for Root Name Servers. October 1996 RFC2219 Hamilton M. R. Wright Use of <acronym>DNS</acronym> Aliases for Network Services. October 1997 Internationalized Domain Names RFC2825 IAB Daigle R. A Tangled Web: Issues of I18N, Domain Names, and the Other Internet protocols May 2000 RFC3490 Faltstrom P. Hoffman P. Costello A. Internationalizing Domain Names in Applications (IDNA) March 2003 RFC3491 Hoffman P. Blanchet M. Nameprep: A Stringprep Profile for Internationalized Domain Names March 2003 RFC3492 Costello A. Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA) March 2003 Other <acronym>DNS</acronym>-related RFCs Note: the following list of RFCs, although DNS-related, are not concerned with implementing software. RFC1464 Rosenbaum R. Using the Domain Name System To Store Arbitrary String Attributes May 1993 RFC1713 Romao A. Tools for <acronym>DNS</acronym> Debugging November 1994 RFC1794 Brisco T. <acronym>DNS</acronym> Support for Load Balancing April 1995 RFC2240 Vaughan O. A Legal Basis for Domain Name Allocation November 1997 RFC2345 Klensin J. T. Wolf G. Oglesby Domain Names and Company Name Retrieval May 1998 RFC2352 Vaughan O. A Convention For Using Legal Names as Domain Names May 1998 RFC3071 Klensin J. Reflections on the DNS, RFC 1591, and Categories of Domains February 2001 RFC3258 Hardie T. Distributing Authoritative Name Servers via Shared Unicast Addresses April 2002 RFC3901 Durand A. J. Ihren DNS IPv6 Transport Operational Guidelines September 2004 Obsolete and Unimplemented Experimental RFC RFC1712 Farrell C. M. Schulze S. Pleitner D. Baldoni <acronym>DNS</acronym> Encoding of Geographical Location November 1994 RFC2673 Crawford M. Binary Labels in the Domain Name System August 1999 RFC2874 Crawford M. Huitema C. DNS Extensions to Support IPv6 Address Aggregation and Renumbering July 2000 Obsoleted DNS Security RFCs Most of these have been consolidated into RFC4033, RFC4034 and RFC4035 which collectively describe DNSSECbis. RFC2065 Eastlake 3rd D. C. Kaufman Domain Name System Security Extensions January 1997 RFC2137 Eastlake 3rd D. Secure Domain Name System Dynamic Update April 1997 RFC2535 Eastlake 3rd D. Domain Name System Security Extensions March 1999 RFC3008 Wellington B. Domain Name System Security (DNSSEC) Signing Authority November 2000 RFC3090 Lewis E. DNS Security Extension Clarification on Zone Status March 2001 RFC3445 Massey D. Rose S. Limiting the Scope of the KEY Resource Record (RR) December 2002 RFC3655 Wellington B. Gudmundsson O. Redefinition of DNS Authenticated Data (AD) bit November 2003 RFC3658 Gudmundsson O. Delegation Signer (DS) Resource Record (RR) December 2003 RFC3755 Weiler S. Legacy Resolver Compatibility for Delegation Signer (DS) May 2004 RFC3757 Kolkman O. Schlyter J. Lewis E. Domain Name System KEY (DNSKEY) Resource Record (RR) Secure Entry Point (SEP) Flag April 2004 RFC3845 Schlyter J. DNS Security (DNSSEC) NextSECure (NSEC) RDATA Format August 2004 Internet Drafts Internet Drafts (IDs) are rough-draft working documents of the Internet Engineering Task Force. They are, in essence, RFCs in the preliminary stages of development. Implementors are cautioned not to regard IDs as archival, and they should not be quoted or cited in any formal documents unless accompanied by the disclaimer that they are "works in progress." IDs have a lifespan of six months after which they are deleted unless updated by their authors. Other Documents About <acronym>BIND</acronym> Albitz Paul Cricket Liu <acronym>DNS</acronym> and <acronym>BIND</acronym> 1998 Sebastopol, CA: O'Reilly and Associates BIND 9 DNS Library Support Manual pages bind9-9.10.3.dfsg.P4/doc/arm/Bv9ARM.ch08.html0000644000470500017500000001512412664710322017347 0ustar lamontlamont Chapter 8. Troubleshooting

Chapter 8. Troubleshooting

Common Problems

It's not working; how can I figure out what's wrong?

The best solution to solving installation and configuration issues is to take preventative measures by setting up logging files beforehand. The log files provide a source of hints and information that can be used to figure out what went wrong and how to fix the problem.

Incrementing and Changing the Serial Number

Zone serial numbers are just numbers — they aren't date related. A lot of people set them to a number that represents a date, usually of the form YYYYMMDDRR. Occasionally they will make a mistake and set them to a "date in the future" then try to correct them by setting them to the "current date". This causes problems because serial numbers are used to indicate that a zone has been updated. If the serial number on the slave server is lower than the serial number on the master, the slave server will attempt to update its copy of the zone.

Setting the serial number to a lower number on the master server than the slave server means that the slave will not perform updates to its copy of the zone.

The solution to this is to add 2147483647 (2^31-1) to the number, reload the zone and make sure all slaves have updated to the new zone serial number, then reset the number to what you want it to be, and reload the zone again.

Where Can I Get Help?

The Internet Systems Consortium (ISC) offers a wide range of support and service agreements for BIND and DHCP servers. Four levels of premium support are available and each level includes support for all ISC programs, significant discounts on products and training, and a recognized priority on bug fixes and non-funded feature requests. In addition, ISC offers a standard support agreement package which includes services ranging from bug fix announcements to remote support. It also includes training in BIND and DHCP.

To discuss arrangements for support, contact info@isc.org or visit the ISC web page at http://www.isc.org/services/support/ to read more.

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/html-fixup.pl0000644000470500017500000000151312664710322017347 0ustar lamontlamont#!/usr/bin/perl -w # # Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. while (<>) { s/쎶/ö/; print; } bind9-9.10.3.dfsg.P4/doc/arm/man.dnssec-settime.html0000644000470500017500000003253712664710322021316 0ustar lamontlamont dnssec-settime

Name

dnssec-settime — Set the key timing metadata for a DNSSEC key

Synopsis

dnssec-settime [-f] [-K directory] [-L ttl] [-P date/offset] [-A date/offset] [-R date/offset] [-I date/offset] [-D date/offset] [-h] [-V] [-v level] [-E engine] {keyfile}

DESCRIPTION

dnssec-settime reads a DNSSEC private key file and sets the key timing metadata as specified by the -P, -A, -R, -I, and -D options. The metadata can then be used by dnssec-signzone or other signing software to determine when a key is to be published, whether it should be used for signing a zone, etc.

If none of these options is set on the command line, then dnssec-settime simply prints the key timing metadata already stored in the key.

When key metadata fields are changed, both files of a key pair (Knnnn.+aaa+iiiii.key and Knnnn.+aaa+iiiii.private) are regenerated. Metadata fields are stored in the private file. A human-readable description of the metadata is also placed in comments in the key file. The private file's permissions are always set to be inaccessible to anyone other than the owner (mode 0600).

OPTIONS

-f

Force an update of an old-format key with no metadata fields. Without this option, dnssec-settime will fail when attempting to update a legacy key. With this option, the key will be recreated in the new format, but with the original key data retained. The key's creation date will be set to the present time. If no other values are specified, then the key's publication and activation dates will also be set to the present time.

-K directory

Sets the directory in which the key files are to reside.

-L ttl

Sets the default TTL to use for this key when it is converted into a DNSKEY RR. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence. If this value is not set and there is no existing DNSKEY RRset, the TTL will default to the SOA TTL. Setting the default TTL to 0 or none removes it from the key.

-h

Emit usage message and exit.

-V

Prints version information.

-v level

Sets the debugging level.

-E engine

Specifies the cryptographic hardware to use, when applicable.

When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (--enable-native-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "--with-pkcs11".

TIMING OPTIONS

Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24-hour days, ignoring leap years), months (defined as 30 24-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To unset a date, use 'none' or 'never'.

-P date/offset

Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it.

-A date/offset

Sets the date on which the key is to be activated. After that date, the key will be included in the zone and used to sign it.

-R date/offset

Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it.

-I date/offset

Sets the date on which the key is to be retired. After that date, the key will still be included in the zone, but it will not be used to sign it.

-D date/offset

Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.)

-S predecessor key

Select a key for which the key being modified will be an explicit successor. The name, algorithm, size, and type of the predecessor key must exactly match those of the key being modified. The activation date of the successor key will be set to the inactivation date of the predecessor. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days.

-i interval

Sets the prepublication interval for a key. If set, then the publication and activation dates must be separated by at least this much time. If the activation date is specified but the publication date isn't, then the publication date will default to this much time before the activation date; conversely, if the publication date is specified but activation date isn't, then activation will be set to this much time after publication.

If the key is being set to be an explicit successor to another key, then the default prepublication interval is 30 days; otherwise it is zero.

As with date offsets, if the argument is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the interval is measured in years, months, weeks, days, hours, or minutes, respectively. Without a suffix, the interval is measured in seconds.

PRINTING OPTIONS

dnssec-settime can also be used to print the timing metadata associated with a key.

-u

Print times in UNIX epoch format.

-p C/P/A/R/I/D/all

Print a specific metadata value or set of metadata values. The -p option may be followed by one or more of the following letters to indicate which value or values to print: C for the creation date, P for the publication date, A for the activation date, R for the revocation date, I for the inactivation date, or D for the deletion date. To print all of the metadata, use -p all.

SEE ALSO

dnssec-keygen(8), dnssec-signzone(8), BIND 9 Administrator Reference Manual, RFC 5011.

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/man.rndc-confgen.html0000644000470500017500000002703112664710322020723 0ustar lamontlamont rndc-confgen

Name

rndc-confgen — rndc key generation tool

Synopsis

rndc-confgen [-a] [-A algorithm] [-b keysize] [-c keyfile] [-h] [-k keyname] [-p port] [-r randomfile] [-s address] [-t chrootdir] [-u user]

DESCRIPTION

rndc-confgen generates configuration files for rndc. It can be used as a convenient alternative to writing the rndc.conf file and the corresponding controls and key statements in named.conf by hand. Alternatively, it can be run with the -a option to set up a rndc.key file and avoid the need for a rndc.conf file and a controls statement altogether.

OPTIONS

-a

Do automatic rndc configuration. This creates a file rndc.key in /etc (or whatever sysconfdir was specified as when BIND was built) that is read by both rndc and named on startup. The rndc.key file defines a default command channel and authentication key allowing rndc to communicate with named on the local host with no further configuration.

Running rndc-confgen -a allows BIND 9 and rndc to be used as drop-in replacements for BIND 8 and ndc, with no changes to the existing BIND 8 named.conf file.

If a more elaborate configuration than that generated by rndc-confgen -a is required, for example if rndc is to be used remotely, you should run rndc-confgen without the -a option and set up a rndc.conf and named.conf as directed.

-A algorithm

Specifies the algorithm to use for the TSIG key. Available choices are: hmac-md5, hmac-sha1, hmac-sha224, hmac-sha256, hmac-sha384 and hmac-sha512. The default is hmac-md5.

-b keysize

Specifies the size of the authentication key in bits. Must be between 1 and 512 bits; the default is the hash size.

-c keyfile

Used with the -a option to specify an alternate location for rndc.key.

-h

Prints a short summary of the options and arguments to rndc-confgen.

-k keyname

Specifies the key name of the rndc authentication key. This must be a valid domain name. The default is rndc-key.

-p port

Specifies the command channel port where named listens for connections from rndc. The default is 953.

-r randomfile

Specifies a source of random data for generating the authorization. If the operating system does not provide a /dev/random or equivalent device, the default source of randomness is keyboard input. randomdev specifies the name of a character device or file containing random data to be used instead of the default. The special value keyboard indicates that keyboard input should be used.

-s address

Specifies the IP address where named listens for command channel connections from rndc. The default is the loopback address 127.0.0.1.

-t chrootdir

Used with the -a option to specify a directory where named will run chrooted. An additional copy of the rndc.key will be written relative to this directory so that it will be found by the chrooted named.

-u user

Used with the -a option to set the owner of the rndc.key file generated. If -t is also specified only the file in the chroot area has its owner changed.

EXAMPLES

To allow rndc to be used with no manual configuration, run

rndc-confgen -a

To print a sample rndc.conf file and corresponding controls and key statements to be manually inserted into named.conf, run

rndc-confgen

SEE ALSO

rndc(8), rndc.conf(5), named(8), BIND 9 Administrator Reference Manual.

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/man.rndc.conf.html0000644000470500017500000002504212664710322020232 0ustar lamontlamont rndc.conf

Name

rndc.conf — rndc configuration file

Synopsis

rndc.conf

DESCRIPTION

rndc.conf is the configuration file for rndc, the BIND 9 name server control utility. This file has a similar structure and syntax to named.conf. Statements are enclosed in braces and terminated with a semi-colon. Clauses in the statements are also semi-colon terminated. The usual comment styles are supported:

C style: /* */

C++ style: // to end of line

Unix style: # to end of line

rndc.conf is much simpler than named.conf. The file uses three statements: an options statement, a server statement and a key statement.

The options statement contains five clauses. The default-server clause is followed by the name or address of a name server. This host will be used when no name server is given as an argument to rndc. The default-key clause is followed by the name of a key which is identified by a key statement. If no keyid is provided on the rndc command line, and no key clause is found in a matching server statement, this default key will be used to authenticate the server's commands and responses. The default-port clause is followed by the port to connect to on the remote name server. If no port option is provided on the rndc command line, and no port clause is found in a matching server statement, this default port will be used to connect. The default-source-address and default-source-address-v6 clauses which can be used to set the IPv4 and IPv6 source addresses respectively.

After the server keyword, the server statement includes a string which is the hostname or address for a name server. The statement has three possible clauses: key, port and addresses. The key name must match the name of a key statement in the file. The port number specifies the port to connect to. If an addresses clause is supplied these addresses will be used instead of the server name. Each address can take an optional port. If an source-address or source-address-v6 of supplied then these will be used to specify the IPv4 and IPv6 source addresses respectively.

The key statement begins with an identifying string, the name of the key. The statement has two clauses. algorithm identifies the authentication algorithm for rndc to use; currently only HMAC-MD5 (for compatibility), HMAC-SHA1, HMAC-SHA224, HMAC-SHA256 (default), HMAC-SHA384 and HMAC-SHA512 are supported. This is followed by a secret clause which contains the base-64 encoding of the algorithm's authentication key. The base-64 string is enclosed in double quotes.

There are two common ways to generate the base-64 string for the secret. The BIND 9 program rndc-confgen can be used to generate a random key, or the mmencode program, also known as mimencode, can be used to generate a base-64 string from known input. mmencode does not ship with BIND 9 but is available on many systems. See the EXAMPLE section for sample command lines for each.

EXAMPLE

      options {
        default-server  localhost;
        default-key     samplekey;
      };

      server localhost {
        key             samplekey;
      };

      server testserver {
        key		testkey;
        addresses	{ localhost port 5353; };
      };

      key samplekey {
        algorithm       hmac-sha256;
        secret          "6FMfj43Osz4lyb24OIe2iGEz9lf1llJO+lz";
      };

      key testkey {
        algorithm	hmac-sha256;
        secret		"R3HI8P6BKw9ZwXwN3VZKuQ==";
      };
    

In the above example, rndc will by default use the server at localhost (127.0.0.1) and the key called samplekey. Commands to the localhost server will use the samplekey key, which must also be defined in the server's configuration file with the same name and secret. The key statement indicates that samplekey uses the HMAC-SHA256 algorithm and its secret clause contains the base-64 encoding of the HMAC-SHA256 secret enclosed in double quotes.

If rndc -s testserver is used then rndc will connect to server on localhost port 5353 using the key testkey.

To generate a random secret with rndc-confgen:

rndc-confgen

A complete rndc.conf file, including the randomly generated key, will be written to the standard output. Commented-out key and controls statements for named.conf are also printed.

To generate a base-64 secret with mmencode:

echo "known plaintext for a secret" | mmencode

NAME SERVER CONFIGURATION

The name server must be configured to accept rndc connections and to recognize the key specified in the rndc.conf file, using the controls statement in named.conf. See the sections on the controls statement in the BIND 9 Administrator Reference Manual for details.

SEE ALSO

rndc(8), rndc-confgen(8), mmencode(1), BIND 9 Administrator Reference Manual.

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/man.nsupdate.html0000644000470500017500000006604512664710322020213 0ustar lamontlamont nsupdate

Name

nsupdate — Dynamic DNS update utility

Synopsis

nsupdate [-d] [-D] [-L level] [[-g] | [-o] | [-l] | [-y [hmac:]keyname:secret] | [-k keyfile]] [-t timeout] [-u udptimeout] [-r udpretries] [-R randomdev] [-v] [-T] [-P] [-V] [filename]

DESCRIPTION

nsupdate is used to submit Dynamic DNS Update requests as defined in RFC 2136 to a name server. This allows resource records to be added or removed from a zone without manually editing the zone file. A single update request can contain requests to add or remove more than one resource record.

Zones that are under dynamic control via nsupdate or a DHCP server should not be edited by hand. Manual edits could conflict with dynamic updates and cause data to be lost.

The resource records that are dynamically added or removed with nsupdate have to be in the same zone. Requests are sent to the zone's master server. This is identified by the MNAME field of the zone's SOA record.

Transaction signatures can be used to authenticate the Dynamic DNS updates. These use the TSIG resource record type described in RFC 2845 or the SIG(0) record described in RFC 2535 and RFC 2931 or GSS-TSIG as described in RFC 3645.

TSIG relies on a shared secret that should only be known to nsupdate and the name server. For instance, suitable key and server statements would be added to /etc/named.conf so that the name server can associate the appropriate secret key and algorithm with the IP address of the client application that will be using TSIG authentication. You can use ddns-confgen to generate suitable configuration fragments. nsupdate uses the -y or -k options to provide the TSIG shared secret. These options are mutually exclusive.

SIG(0) uses public key cryptography. To use a SIG(0) key, the public key must be stored in a KEY record in a zone served by the name server.

GSS-TSIG uses Kerberos credentials. Standard GSS-TSIG mode is switched on with the -g flag. A non-standards-compliant variant of GSS-TSIG used by Windows 2000 can be switched on with the -o flag.

OPTIONS

-d

Debug mode. This provides tracing information about the update requests that are made and the replies received from the name server.

-D

Extra debug mode.

-k keyfile

The file containing the TSIG authentication key. Keyfiles may be in two formats: a single file containing a named.conf-format key statement, which may be generated automatically by ddns-confgen, or a pair of files whose names are of the format K{name}.+157.+{random}.key and K{name}.+157.+{random}.private, which can be generated by dnssec-keygen. The -k may also be used to specify a SIG(0) key used to authenticate Dynamic DNS update requests. In this case, the key specified is not an HMAC-MD5 key.

-l

Local-host only mode. This sets the server address to localhost (disabling the server so that the server address cannot be overridden). Connections to the local server will use a TSIG key found in /var/run/named/session.key, which is automatically generated by named if any local master zone has set update-policy to local. The location of this key file can be overridden with the -k option.

-L level

Set the logging debug level. If zero, logging is disabled.

-p port

Set the port to use for connections to a name server. The default is 53.

-P

Print the list of private BIND-specific resource record types whose format is understood by nsupdate. See also the -T option.

-r udpretries

The number of UDP retries. The default is 3. If zero, only one update request will be made.

-R randomdev

Where to obtain randomness. If the operating system does not provide a /dev/random or equivalent device, the default source of randomness is keyboard input. randomdev specifies the name of a character device or file containing random data to be used instead of the default. The special value keyboard indicates that keyboard input should be used. This option may be specified multiple times.

-t timeout

The maximum time an update request can take before it is aborted. The default is 300 seconds. Zero can be used to disable the timeout.

-T

Print the list of IANA standard resource record types whose format is understood by nsupdate. nsupdate will exit after the lists are printed. The -T option can be combined with the -P option.

Other types can be entered using "TYPEXXXXX" where "XXXXX" is the decimal value of the type with no leading zeros. The rdata, if present, will be parsed using the UNKNOWN rdata format, (<backslash> <hash> <space> <length> <space> <hexstring>).

-u udptimeout

The UDP retry interval. The default is 3 seconds. If zero, the interval will be computed from the timeout interval and number of UDP retries.

-v

Use TCP even for small update requests. By default, nsupdate uses UDP to send update requests to the name server unless they are too large to fit in a UDP request in which case TCP will be used. TCP may be preferable when a batch of update requests is made.

-V

Print the version number and exit.

-y [hmac:]keyname:secret

Literal TSIG authentication key. keyname is the name of the key, and secret is the base64 encoded shared secret. hmac is the name of the key algorithm; valid choices are hmac-md5, hmac-sha1, hmac-sha224, hmac-sha256, hmac-sha384, or hmac-sha512. If hmac is not specified, the default is hmac-md5.

NOTE: Use of the -y option is discouraged because the shared secret is supplied as a command line argument in clear text. This may be visible in the output from ps(1) or in a history file maintained by the user's shell.

INPUT FORMAT

nsupdate reads input from filename or standard input. Each command is supplied on exactly one line of input. Some commands are for administrative purposes. The others are either update instructions or prerequisite checks on the contents of the zone. These checks set conditions that some name or set of resource records (RRset) either exists or is absent from the zone. These conditions must be met if the entire update request is to succeed. Updates will be rejected if the tests for the prerequisite conditions fail.

Every update request consists of zero or more prerequisites and zero or more updates. This allows a suitably authenticated update request to proceed if some specified resource records are present or missing from the zone. A blank input line (or the send command) causes the accumulated commands to be sent as one Dynamic DNS update request to the name server.

The command formats and their meaning are as follows:

server {servername} [port]

Sends all dynamic update requests to the name server servername. When no server statement is provided, nsupdate will send updates to the master server of the correct zone. The MNAME field of that zone's SOA record will identify the master server for that zone. port is the port number on servername where the dynamic update requests get sent. If no port number is specified, the default DNS port number of 53 is used.

local {address} [port]

Sends all dynamic update requests using the local address. When no local statement is provided, nsupdate will send updates using an address and port chosen by the system. port can additionally be used to make requests come from a specific port. If no port number is specified, the system will assign one.

zone {zonename}

Specifies that all updates are to be made to the zone zonename. If no zone statement is provided, nsupdate will attempt determine the correct zone to update based on the rest of the input.

class {classname}

Specify the default class. If no class is specified, the default class is IN.

ttl {seconds}

Specify the default time to live for records to be added. The value none will clear the default ttl.

key [hmac:] {keyname} {secret}

Specifies that all updates are to be TSIG-signed using the keyname secret pair. If hmac is specified, then it sets the signing algorithm in use; the default is hmac-md5. The key command overrides any key specified on the command line via -y or -k.

gsstsig

Use GSS-TSIG to sign the updated. This is equivalent to specifying -g on the commandline.

oldgsstsig

Use the Windows 2000 version of GSS-TSIG to sign the updated. This is equivalent to specifying -o on the commandline.

realm {[realm_name]}

When using GSS-TSIG use realm_name rather than the default realm in krb5.conf. If no realm is specified the saved realm is cleared.

[prereq] nxdomain {domain-name}

Requires that no resource record of any type exists with name domain-name.

[prereq] yxdomain {domain-name}

Requires that domain-name exists (has as at least one resource record, of any type).

[prereq] nxrrset {domain-name} [class] {type}

Requires that no resource record exists of the specified type, class and domain-name. If class is omitted, IN (internet) is assumed.

[prereq] yxrrset {domain-name} [class] {type}

This requires that a resource record of the specified type, class and domain-name must exist. If class is omitted, IN (internet) is assumed.

[prereq] yxrrset {domain-name} [class] {type} {data...}

The data from each set of prerequisites of this form sharing a common type, class, and domain-name are combined to form a set of RRs. This set of RRs must exactly match the set of RRs existing in the zone at the given type, class, and domain-name. The data are written in the standard text representation of the resource record's RDATA.

[update] del[ete] {domain-name} [ttl] [class] [type [data...]]

Deletes any resource records named domain-name. If type and data is provided, only matching resource records will be removed. The internet class is assumed if class is not supplied. The ttl is ignored, and is only allowed for compatibility.

[update] add {domain-name} {ttl} [class] {type} {data...}

Adds a new resource record with the specified ttl, class and data.

show

Displays the current message, containing all of the prerequisites and updates specified since the last send.

send

Sends the current message. This is equivalent to entering a blank line.

answer

Displays the answer.

debug

Turn on debugging.

version

Print version number.

help

Print a list of commands.

Lines beginning with a semicolon are comments and are ignored.

EXAMPLES

The examples below show how nsupdate could be used to insert and delete resource records from the example.com zone. Notice that the input in each example contains a trailing blank line so that a group of commands are sent as one dynamic update request to the master name server for example.com.

# nsupdate
> update delete oldhost.example.com A
> update add newhost.example.com 86400 A 172.16.1.1
> send

Any A records for oldhost.example.com are deleted. And an A record for newhost.example.com with IP address 172.16.1.1 is added. The newly-added record has a 1 day TTL (86400 seconds).

# nsupdate
> prereq nxdomain nickname.example.com
> update add nickname.example.com 86400 CNAME somehost.example.com
> send

The prerequisite condition gets the name server to check that there are no resource records of any type for nickname.example.com. If there are, the update request fails. If this name does not exist, a CNAME for it is added. This ensures that when the CNAME is added, it cannot conflict with the long-standing rule in RFC 1034 that a name must not exist as any other record type if it exists as a CNAME. (The rule has been updated for DNSSEC in RFC 2535 to allow CNAMEs to have RRSIG, DNSKEY and NSEC records.)

FILES

/etc/resolv.conf

used to identify default name server

/var/run/named/session.key

sets the default TSIG key for use in local-only mode

K{name}.+157.+{random}.key

base-64 encoding of HMAC-MD5 key created by dnssec-keygen(8).

K{name}.+157.+{random}.private

base-64 encoding of HMAC-MD5 key created by dnssec-keygen(8).

SEE ALSO

RFC 2136, RFC 3007, RFC 2104, RFC 2845, RFC 1034, RFC 2535, RFC 2931, named(8), ddns-confgen(8), dnssec-keygen(8).

BUGS

The TSIG key is redundantly stored in two separate files. This is a consequence of nsupdate using the DST library for its cryptographic operations, and may change in future releases.

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/man.named-journalprint.html0000644000470500017500000001115412664710322022170 0ustar lamontlamont named-journalprint

Name

named-journalprint — print zone journal in human-readable form

Synopsis

named-journalprint {journal}

DESCRIPTION

named-journalprint prints the contents of a zone journal file in a human-readable form.

Journal files are automatically created by named when changes are made to dynamic zones (e.g., by nsupdate). They record each addition or deletion of a resource record, in binary format, allowing the changes to be re-applied to the zone when the server is restarted after a shutdown or crash. By default, the name of the journal file is formed by appending the extension .jnl to the name of the corresponding zone file.

named-journalprint converts the contents of a given journal file into a human-readable text format. Each line begins with "add" or "del", to indicate whether the record was added or deleted, and continues with the resource record in master-file format.

SEE ALSO

named(8), nsupdate(8), BIND 9 Administrator Reference Manual.

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/Bv9ARM.ch02.html0000644000470500017500000001700212664710322017336 0ustar lamontlamont Chapter 2. BIND Resource Requirements

Chapter 2. BIND Resource Requirements

Hardware requirements

DNS hardware requirements have traditionally been quite modest. For many installations, servers that have been pensioned off from active duty have performed admirably as DNS servers.

The DNSSEC features of BIND 9 may prove to be quite CPU intensive however, so organizations that make heavy use of these features may wish to consider larger systems for these applications. BIND 9 is fully multithreaded, allowing full utilization of multiprocessor systems for installations that need it.

CPU Requirements

CPU requirements for BIND 9 range from i486-class machines for serving of static zones without caching, to enterprise-class machines if you intend to process many dynamic updates and DNSSEC signed zones, serving many thousands of queries per second.

Memory Requirements

The memory of the server has to be large enough to fit the cache and zones loaded off disk. The max-cache-size option can be used to limit the amount of memory used by the cache, at the expense of reducing cache hit rates and causing more DNS traffic. Additionally, if additional section caching (the section called “Additional Section Caching”) is enabled, the max-acache-size option can be used to limit the amount of memory used by the mechanism. It is still good practice to have enough memory to load all zone and cache data into memory — unfortunately, the best way to determine this for a given installation is to watch the name server in operation. After a few weeks the server process should reach a relatively stable size where entries are expiring from the cache as fast as they are being inserted.

Name Server Intensive Environment Issues

For name server intensive environments, there are two alternative configurations that may be used. The first is where clients and any second-level internal name servers query a main name server, which has enough memory to build a large cache. This approach minimizes the bandwidth used by external name lookups. The second alternative is to set up second-level internal name servers to make queries independently. In this configuration, none of the individual machines needs to have as much memory or CPU power as in the first alternative, but this has the disadvantage of making many more external queries, as none of the name servers share their cached data.

Supported Operating Systems

ISC BIND 9 compiles and runs on a large number of Unix-like operating systems and on Microsoft Windows Server 2003 and 2008, and Windows XP and Vista. For an up-to-date list of supported systems, see the README file in the top level directory of the BIND 9 source distribution.

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/Bv9ARM.ch11.html0000644000470500017500000012703512664710322017346 0ustar lamontlamont Appendix C. General DNS Reference Information

Appendix C. General DNS Reference Information

IPv6 addresses (AAAA)

IPv6 addresses are 128-bit identifiers for interfaces and sets of interfaces which were introduced in the DNS to facilitate scalable Internet routing. There are three types of addresses: Unicast, an identifier for a single interface; Anycast, an identifier for a set of interfaces; and Multicast, an identifier for a set of interfaces. Here we describe the global Unicast address scheme. For more information, see RFC 3587, "Global Unicast Address Format."

IPv6 unicast addresses consist of a global routing prefix, a subnet identifier, and an interface identifier.

The global routing prefix is provided by the upstream provider or ISP, and (roughly) corresponds to the IPv4 network section of the address range. The subnet identifier is for local subnetting, much the same as subnetting an IPv4 /16 network into /24 subnets. The interface identifier is the address of an individual interface on a given network; in IPv6, addresses belong to interfaces rather than to machines.

The subnetting capability of IPv6 is much more flexible than that of IPv4: subnetting can be carried out on bit boundaries, in much the same way as Classless InterDomain Routing (CIDR), and the DNS PTR representation ("nibble" format) makes setting up reverse zones easier.

The Interface Identifier must be unique on the local link, and is usually generated automatically by the IPv6 implementation, although it is usually possible to override the default setting if necessary. A typical IPv6 address might look like: 2001:db8:201:9:a00:20ff:fe81:2b32

IPv6 address specifications often contain long strings of zeros, so the architects have included a shorthand for specifying them. The double colon (`::') indicates the longest possible string of zeros that can fit, and can be used only once in an address.

Bibliography (and Suggested Reading)

Request for Comments (RFCs)

Specification documents for the Internet protocol suite, including the DNS, are published as part of the Request for Comments (RFCs) series of technical notes. The standards themselves are defined by the Internet Engineering Task Force (IETF) and the Internet Engineering Steering Group (IESG). RFCs can be obtained online via FTP at:

ftp://www.isi.edu/in-notes/RFCxxxx.txt

(where xxxx is the number of the RFC). RFCs are also available via the Web at:

http://www.ietf.org/rfc/.

Bibliography

Standards

[RFC974] C. Partridge. Mail Routing and the Domain System. January 1986.

[RFC1034] P.V. Mockapetris. Domain Names — Concepts and Facilities. November 1987.

[RFC1035] P. V. Mockapetris. Domain Names — Implementation and Specification. November 1987.

Proposed Standards

[RFC2181] R., R. Bush Elz. Clarifications to the DNS Specification. July 1997.

[RFC2308] M. Andrews. Negative Caching of DNS Queries. March 1998.

[RFC1995] M. Ohta. Incremental Zone Transfer in DNS. August 1996.

[RFC1996] P. Vixie. A Mechanism for Prompt Notification of Zone Changes. August 1996.

[RFC2136] P. Vixie, S. Thomson, Y. Rekhter, and J. Bound. Dynamic Updates in the Domain Name System. April 1997.

[RFC2671] P. Vixie. Extension Mechanisms for DNS (EDNS0). August 1997.

[RFC2672] M. Crawford. Non-Terminal DNS Name Redirection. August 1999.

[RFC2845] P. Vixie, O. Gudmundsson, D. Eastlake, 3rd, and B. Wellington. Secret Key Transaction Authentication for DNS (TSIG). May 2000.

[RFC2930] D. Eastlake, 3rd. Secret Key Establishment for DNS (TKEY RR). September 2000.

[RFC2931] D. Eastlake, 3rd. DNS Request and Transaction Signatures (SIG(0)s). September 2000.

[RFC3007] B. Wellington. Secure Domain Name System (DNS) Dynamic Update. November 2000.

[RFC3645] S. Kwan, P. Garg, J. Gilroy, L. Esibov, J. Westhead, and R. Hall. Generic Security Service Algorithm for Secret Key Transaction Authentication for DNS (GSS-TSIG). October 2003.

DNS Security Proposed Standards

[RFC3225] D. Conrad. Indicating Resolver Support of DNSSEC. December 2001.

[RFC3833] D. Atkins and R. Austein. Threat Analysis of the Domain Name System (DNS). August 2004.

[RFC4033] R. Arends, R. Austein, M. Larson, D. Massey, and S. Rose. DNS Security Introduction and Requirements. March 2005.

[RFC4034] R. Arends, R. Austein, M. Larson, D. Massey, and S. Rose. Resource Records for the DNS Security Extensions. March 2005.

[RFC4035] R. Arends, R. Austein, M. Larson, D. Massey, and S. Rose. Protocol Modifications for the DNS Security Extensions. March 2005.

Other Important RFCs About DNS Implementation

[RFC1535] E. Gavron. A Security Problem and Proposed Correction With Widely Deployed DNS Software.. October 1993.

[RFC1536] A. Kumar, J. Postel, C. Neuman, P. Danzig, and S. Miller. Common DNS Implementation Errors and Suggested Fixes. October 1993.

[RFC1982] R. Elz and R. Bush. Serial Number Arithmetic. August 1996.

[RFC4074] Y. Morishita and T. Jinmei. Common Misbehaviour Against DNS Queries for IPv6 Addresses. May 2005.

Resource Record Types

[RFC1183] C.F. Everhart, L. A. Mamakos, R. Ullmann, and P. Mockapetris. New DNS RR Definitions. October 1990.

[RFC1706] B. Manning and R. Colella. DNS NSAP Resource Records. October 1994.

[RFC2168] R. Daniel and M. Mealling. Resolution of Uniform Resource Identifiers using the Domain Name System. June 1997.

[RFC1876] C. Davis, P. Vixie, T., and I. Dickinson. A Means for Expressing Location Information in the Domain Name System. January 1996.

[RFC2052] A. Gulbrandsen and P. Vixie. A DNS RR for Specifying the Location of Services.. October 1996.

[RFC2163] A. Allocchio. Using the Internet DNS to Distribute MIXER Conformant Global Address Mapping. January 1998.

[RFC2230] R. Atkinson. Key Exchange Delegation Record for the DNS. October 1997.

[RFC2536] D. Eastlake, 3rd. DSA KEYs and SIGs in the Domain Name System (DNS). March 1999.

[RFC2537] D. Eastlake, 3rd. RSA/MD5 KEYs and SIGs in the Domain Name System (DNS). March 1999.

[RFC2538] D. Eastlake, 3rd and O. Gudmundsson. Storing Certificates in the Domain Name System (DNS). March 1999.

[RFC2539] D. Eastlake, 3rd. Storage of Diffie-Hellman Keys in the Domain Name System (DNS). March 1999.

[RFC2540] D. Eastlake, 3rd. Detached Domain Name System (DNS) Information. March 1999.

[RFC2782] A. Gulbrandsen. P. Vixie. L. Esibov. A DNS RR for specifying the location of services (DNS SRV). February 2000.

[RFC2915] M. Mealling. R. Daniel. The Naming Authority Pointer (NAPTR) DNS Resource Record. September 2000.

[RFC3110] D. Eastlake, 3rd. RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS). May 2001.

[RFC3123] P. Koch. A DNS RR Type for Lists of Address Prefixes (APL RR). June 2001.

[RFC3596] S. Thomson, C. Huitema, V. Ksinant, and M. Souissi. DNS Extensions to support IP version 6. October 2003.

[RFC3597] A. Gustafsson. Handling of Unknown DNS Resource Record (RR) Types. September 2003.

DNS and the Internet

[RFC1101] P. V. Mockapetris. DNS Encoding of Network Names and Other Types. April 1989.

[RFC1123] Braden. Requirements for Internet Hosts - Application and Support. October 1989.

[RFC1591] J. Postel. Domain Name System Structure and Delegation. March 1994.

[RFC2317] H. Eidnes, G. de Groot, and P. Vixie. Classless IN-ADDR.ARPA Delegation. March 1998.

[RFC2826] Internet Architecture Board. IAB Technical Comment on the Unique DNS Root. May 2000.

[RFC2929] D. Eastlake, 3rd, E. Brunner-Williams, and B. Manning. Domain Name System (DNS) IANA Considerations. September 2000.

DNS Operations

[RFC1033] M. Lottor. Domain administrators operations guide.. November 1987.

[RFC1537] P. Beertema. Common DNS Data File Configuration Errors. October 1993.

[RFC1912] D. Barr. Common DNS Operational and Configuration Errors. February 1996.

[RFC2010] B. Manning and P. Vixie. Operational Criteria for Root Name Servers.. October 1996.

[RFC2219] M. Hamilton and R. Wright. Use of DNS Aliases for Network Services.. October 1997.

Internationalized Domain Names

[RFC2825] IAB and R. Daigle. A Tangled Web: Issues of I18N, Domain Names, and the Other Internet protocols. May 2000.

[RFC3490] P. Faltstrom, P. Hoffman, and A. Costello. Internationalizing Domain Names in Applications (IDNA). March 2003.

[RFC3491] P. Hoffman and M. Blanchet. Nameprep: A Stringprep Profile for Internationalized Domain Names. March 2003.

[RFC3492] A. Costello. Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA). March 2003.

Other DNS-related RFCs

Note

Note: the following list of RFCs, although DNS-related, are not concerned with implementing software.

[RFC1464] R. Rosenbaum. Using the Domain Name System To Store Arbitrary String Attributes. May 1993.

[RFC1713] A. Romao. Tools for DNS Debugging. November 1994.

[RFC1794] T. Brisco. DNS Support for Load Balancing. April 1995.

[RFC2240] O. Vaughan. A Legal Basis for Domain Name Allocation. November 1997.

[RFC2345] J. Klensin, T. Wolf, and G. Oglesby. Domain Names and Company Name Retrieval. May 1998.

[RFC2352] O. Vaughan. A Convention For Using Legal Names as Domain Names. May 1998.

[RFC3071] J. Klensin. Reflections on the DNS, RFC 1591, and Categories of Domains. February 2001.

[RFC3258] T. Hardie. Distributing Authoritative Name Servers via Shared Unicast Addresses. April 2002.

[RFC3901] A. Durand and J. Ihren. DNS IPv6 Transport Operational Guidelines. September 2004.

Obsolete and Unimplemented Experimental RFC

[RFC1712] C. Farrell, M. Schulze, S. Pleitner, and D. Baldoni. DNS Encoding of Geographical Location. November 1994.

[RFC2673] M. Crawford. Binary Labels in the Domain Name System. August 1999.

[RFC2874] M. Crawford and C. Huitema. DNS Extensions to Support IPv6 Address Aggregation and Renumbering. July 2000.

Obsoleted DNS Security RFCs

Note

Most of these have been consolidated into RFC4033, RFC4034 and RFC4035 which collectively describe DNSSECbis.

[RFC2065] D. Eastlake, 3rd and C. Kaufman. Domain Name System Security Extensions. January 1997.

[RFC2137] D. Eastlake, 3rd. Secure Domain Name System Dynamic Update. April 1997.

[RFC2535] D. Eastlake, 3rd. Domain Name System Security Extensions. March 1999.

[RFC3008] B. Wellington. Domain Name System Security (DNSSEC) Signing Authority. November 2000.

[RFC3090] E. Lewis. DNS Security Extension Clarification on Zone Status. March 2001.

[RFC3445] D. Massey and S. Rose. Limiting the Scope of the KEY Resource Record (RR). December 2002.

[RFC3655] B. Wellington and O. Gudmundsson. Redefinition of DNS Authenticated Data (AD) bit. November 2003.

[RFC3658] O. Gudmundsson. Delegation Signer (DS) Resource Record (RR). December 2003.

[RFC3755] S. Weiler. Legacy Resolver Compatibility for Delegation Signer (DS). May 2004.

[RFC3757] O. Kolkman, J. Schlyter, and E. Lewis. Domain Name System KEY (DNSKEY) Resource Record (RR) Secure Entry Point (SEP) Flag. April 2004.

[RFC3845] J. Schlyter. DNS Security (DNSSEC) NextSECure (NSEC) RDATA Format. August 2004.

Internet Drafts

Internet Drafts (IDs) are rough-draft working documents of the Internet Engineering Task Force. They are, in essence, RFCs in the preliminary stages of development. Implementors are cautioned not to regard IDs as archival, and they should not be quoted or cited in any formal documents unless accompanied by the disclaimer that they are "works in progress." IDs have a lifespan of six months after which they are deleted unless updated by their authors.

Other Documents About BIND

Bibliography

Paul Albitz and Cricket Liu. DNS and BIND. Copyright © 1998 Sebastopol, CA: O'Reilly and Associates.

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/man.named-checkconf.html0000644000470500017500000001600712664710322021366 0ustar lamontlamont named-checkconf

Name

named-checkconf — named configuration file syntax checking tool

Synopsis

named-checkconf [-h] [-v] [-j] [-t directory] {filename} [-p] [-x] [-z]

DESCRIPTION

named-checkconf checks the syntax, but not the semantics, of a named configuration file. The file is parsed and checked for syntax errors, along with all files included by it. If no file is specified, /etc/named.conf is read by default.

Note: files that named reads in separate parser contexts, such as rndc.key and bind.keys, are not automatically read by named-checkconf. Configuration errors in these files may cause named to fail to run, even if named-checkconf was successful. named-checkconf can be run on these files explicitly, however.

OPTIONS

-h

Print the usage summary and exit.

-t directory

Chroot to directory so that include directives in the configuration file are processed as if run by a similarly chrooted named.

-v

Print the version of the named-checkconf program and exit.

-p

Print out the named.conf and included files in canonical form if no errors were detected.

-x

When printing the configuration files in canonical form, obscure shared secrets by replacing them with strings of question marks ('?'). This allows the contents of named.conf and related files to be shared — for example, when submitting bug reports — without compromising private data. This option cannot be used without -p.

-z

Perform a test load of all master zones found in named.conf.

-j

When loading a zonefile read the journal if it exists.

filename

The name of the configuration file to be checked. If not specified, it defaults to /etc/named.conf.

RETURN VALUES

named-checkconf returns an exit status of 1 if errors were detected and 0 otherwise.

SEE ALSO

named(8), named-checkzone(8), BIND 9 Administrator Reference Manual.

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/pkcs11.xml0000644000470500017500000006170312664710322016550 0ustar lamontlamont]> PKCS#11 (Cryptoki) support PKCS#11 (Public Key Cryptography Standard #11) defines a platform-independent API for the control of hardware security modules (HSMs) and other cryptographic support devices. BIND 9 is known to work with three HSMs: The AEP Keyper, which has been tested with Debian Linux, Solaris x86 and Windows Server 2003; the Thales nShield, tested with Debian Linux; and the Sun SCA 6000 cryptographic acceleration board, tested with Solaris x86. In addition, BIND can be used with all current versions of SoftHSM, a software-based HSM simulator library produced by the OpenDNSSEC project. PKCS#11 makes use of a "provider library": a dynamically loadable library which provides a low-level PKCS#11 interface to drive the HSM hardware. The PKCS#11 provider library comes from the HSM vendor, and it is specific to the HSM to be controlled. There are two available mechanisms for PKCS#11 support in BIND 9: OpenSSL-based PKCS#11 and native PKCS#11. When using the first mechanism, BIND uses a modified version of OpenSSL, which loads the provider library and operates the HSM indirectly; any cryptographic operations not supported by the HSM can be carried out by OpenSSL instead. The second mechanism enables BIND to bypass OpenSSL completely; BIND loads the provider library itself, and uses the PKCS#11 API to drive the HSM directly. Prerequisites See the documentation provided by your HSM vendor for information about installing, initializing, testing and troubleshooting the HSM. Native PKCS#11 Native PKCS#11 mode will only work with an HSM capable of carrying out every cryptographic operation BIND 9 may need. The HSM's provider library must have a complete implementation of the PKCS#11 API, so that all these functions are accessible. As of this writing, only the Thales nShield HSM and SoftHSMv2 can be used in this fashion. For other HSMs, including the AEP Keyper, Sun SCA 6000 and older versions of SoftHSM, use OpenSSL-based PKCS#11. (Note: Eventually, when more HSMs become capable of supporting native PKCS#11, it is expected that OpenSSL-based PKCS#11 will be deprecated.) To build BIND with native PKCS#11, configure as follows: $ cd bind9 $ ./configure --enable-native-pkcs11 \ --with-pkcs11=provider-library-path This will cause all BIND tools, including named and the dnssec-* and pkcs11-* tools, to use the PKCS#11 provider library specified in provider-library-path for cryptography. (The provider library path can be overridden using the in named and the dnssec-* tools, or the in the pkcs11-* tools.) Building SoftHSMv2 SoftHSMv2, the latest development version of SoftHSM, is available from https://github.com/opendnssec/SoftHSMv2 . It is a software library developed by the OpenDNSSEC project ( http://www.opendnssec.org ) which provides a PKCS#11 interface to a virtual HSM, implemented in the form of a SQLite3 database on the local filesystem. It provides less security than a true HSM, but it allows you to experiment with native PKCS#11 when an HSM is not available. SoftHSMv2 can be configured to use either OpenSSL or the Botan library to perform cryptographic functions, but when using it for native PKCS#11 in BIND, OpenSSL is required. By default, the SoftHSMv2 configuration file is prefix/etc/softhsm2.conf (where prefix is configured at compile time). This location can be overridden by the SOFTHSM2_CONF environment variable. The SoftHSMv2 cryptographic store must be installed and initialized before using it with BIND. $ cd SoftHSMv2 $ configure --with-crypto-backend=openssl --prefix=/opt/pkcs11/usr --enable-gost $ make $ make install $ /opt/pkcs11/usr/bin/softhsm-util --init-token 0 --slot 0 --label softhsmv2 OpenSSL-based PKCS#11 OpenSSL-based PKCS#11 mode uses a modified version of the OpenSSL library; stock OpenSSL does not fully support PKCS#11. ISC provides a patch to OpenSSL to correct this. This patch is based on work originally done by the OpenSolaris project; it has been modified by ISC to provide new features such as PIN management and key-by-reference. There are two "flavors" of PKCS#11 support provided by the patched OpenSSL, one of which must be chosen at configuration time. The correct choice depends on the HSM hardware: Use 'crypto-accelerator' with HSMs that have hardware cryptographic acceleration features, such as the SCA 6000 board. This causes OpenSSL to run all supported cryptographic operations in the HSM. Use 'sign-only' with HSMs that are designed to function primarily as secure key storage devices, but lack hardware acceleration. These devices are highly secure, but are not necessarily any faster at cryptography than the system CPU — often, they are slower. It is therefore most efficient to use them only for those cryptographic functions that require access to the secured private key, such as zone signing, and to use the system CPU for all other computationally-intensive operations. The AEP Keyper is an example of such a device. The modified OpenSSL code is included in the BIND 9 release, in the form of a context diff against the latest versions of OpenSSL. OpenSSL 0.9.8, 1.0.0, and 1.0.1 are supported; there are separate diffs for each version. In the examples to follow, we use OpenSSL 0.9.8, but the same methods work with OpenSSL 1.0.0 and 1.0.1. The latest OpenSSL versions as of this writing (January 2015) are 0.9.8zc, 1.0.0o, and 1.0.1j. ISC will provide updated patches as new versions of OpenSSL are released. The version number in the following examples is expected to change. Before building BIND 9 with PKCS#11 support, it will be necessary to build OpenSSL with the patch in place, and configure it with the path to your HSM's PKCS#11 provider library. Patching OpenSSL $ wget http://www.openssl.org/source/openssl-0.9.8zc.tar.gz Extract the tarball: $ tar zxf openssl-0.9.8zc.tar.gz Apply the patch from the BIND 9 release: $ patch -p1 -d openssl-0.9.8zc \ < bind9/bin/pkcs11/openssl-0.9.8zc-patch Note that the patch file may not be compatible with the "patch" utility on all operating systems. You may need to install GNU patch. When building OpenSSL, place it in a non-standard location so that it does not interfere with OpenSSL libraries elsewhere on the system. In the following examples, we choose to install into "/opt/pkcs11/usr". We will use this location when we configure BIND 9. Later, when building BIND 9, the location of the custom-built OpenSSL library will need to be specified via configure. Building OpenSSL for the AEP Keyper on Linux The AEP Keyper is a highly secure key storage device, but does not provide hardware cryptographic acceleration. It can carry out cryptographic operations, but it is probably slower than your system's CPU. Therefore, we choose the 'sign-only' flavor when building OpenSSL. The Keyper-specific PKCS#11 provider library is delivered with the Keyper software. In this example, we place it /opt/pkcs11/usr/lib: $ cp pkcs11.GCC4.0.2.so.4.05 /opt/pkcs11/usr/lib/libpkcs11.so This library is only available for Linux as a 32-bit binary. If we are compiling on a 64-bit Linux system, it is necessary to force a 32-bit build, by specifying -m32 in the build options. Finally, the Keyper library requires threads, so we must specify -pthread. $ cd openssl-0.9.8zc $ ./Configure linux-generic32 -m32 -pthread \ --pk11-libname=/opt/pkcs11/usr/lib/libpkcs11.so \ --pk11-flavor=sign-only \ --prefix=/opt/pkcs11/usr After configuring, run "make" and "make test". If "make test" fails with "pthread_atfork() not found", you forgot to add the -pthread above. Building OpenSSL for the SCA 6000 on Solaris The SCA-6000 PKCS#11 provider is installed as a system library, libpkcs11. It is a true crypto accelerator, up to 4 times faster than any CPU, so the flavor shall be 'crypto-accelerator'. In this example, we are building on Solaris x86 on an AMD64 system. $ cd openssl-0.9.8zc $ ./Configure solaris64-x86_64-cc \ --pk11-libname=/usr/lib/64/libpkcs11.so \ --pk11-flavor=crypto-accelerator \ --prefix=/opt/pkcs11/usr (For a 32-bit build, use "solaris-x86-cc" and /usr/lib/libpkcs11.so.) After configuring, run make and make test. Building OpenSSL for SoftHSM SoftHSM (version 1) is a software library developed by the OpenDNSSEC project ( http://www.opendnssec.org ) which provides a PKCS#11 interface to a virtual HSM, implemented in the form of a SQLite3 database on the local filesystem. SoftHSM uses the Botan library to perform cryptographic functions. Though less secure than a true HSM, it can allow you to experiment with PKCS#11 when an HSM is not available. The SoftHSM cryptographic store must be installed and initialized before using it with OpenSSL, and the SOFTHSM_CONF environment variable must always point to the SoftHSM configuration file: $ cd softhsm-1.3.7 $ configure --prefix=/opt/pkcs11/usr $ make $ make install $ export SOFTHSM_CONF=/opt/pkcs11/softhsm.conf $ echo "0:/opt/pkcs11/softhsm.db" > $SOFTHSM_CONF $ /opt/pkcs11/usr/bin/softhsm --init-token 0 --slot 0 --label softhsm SoftHSM can perform all cryptographic operations, but since it only uses your system CPU, there is no advantage to using it for anything but signing. Therefore, we choose the 'sign-only' flavor when building OpenSSL. $ cd openssl-0.9.8zc $ ./Configure linux-x86_64 -pthread \ --pk11-libname=/opt/pkcs11/usr/lib/libsofthsm.so \ --pk11-flavor=sign-only \ --prefix=/opt/pkcs11/usr After configuring, run "make" and "make test". Once you have built OpenSSL, run "apps/openssl engine pkcs11" to confirm that PKCS#11 support was compiled in correctly. The output should be one of the following lines, depending on the flavor selected: (pkcs11) PKCS #11 engine support (sign only) Or: (pkcs11) PKCS #11 engine support (crypto accelerator) Next, run "apps/openssl engine pkcs11 -t". This will attempt to initialize the PKCS#11 engine. If it is able to do so successfully, it will report [ available ]. If the output is correct, run "make install" which will install the modified OpenSSL suite to /opt/pkcs11/usr. Configuring BIND 9 for Linux with the AEP Keyper To link with the PKCS#11 provider, threads must be enabled in the BIND 9 build. The PKCS#11 library for the AEP Keyper is currently only available as a 32-bit binary. If we are building on a 64-bit host, we must force a 32-bit build by adding "-m32" to the CC options on the "configure" command line. $ cd ../bind9 $ ./configure CC="gcc -m32" --enable-threads \ --with-openssl=/opt/pkcs11/usr \ --with-pkcs11=/opt/pkcs11/usr/lib/libpkcs11.so Configuring BIND 9 for Solaris with the SCA 6000 To link with the PKCS#11 provider, threads must be enabled in the BIND 9 build. $ cd ../bind9 $ ./configure CC="cc -xarch=amd64" --enable-threads \ --with-openssl=/opt/pkcs11/usr \ --with-pkcs11=/usr/lib/64/libpkcs11.so (For a 32-bit build, omit CC="cc -xarch=amd64".) If configure complains about OpenSSL not working, you may have a 32/64-bit architecture mismatch. Or, you may have incorrectly specified the path to OpenSSL (it should be the same as the --prefix argument to the OpenSSL Configure). Configuring BIND 9 for SoftHSM $ cd ../bind9 $ ./configure --enable-threads \ --with-openssl=/opt/pkcs11/usr \ --with-pkcs11=/opt/pkcs11/usr/lib/libsofthsm.so After configuring, run "make", "make test" and "make install". (Note: If "make test" fails in the "pkcs11" system test, you may have forgotten to set the SOFTHSM_CONF environment variable.) PKCS#11 Tools BIND 9 includes a minimal set of tools to operate the HSM, including pkcs11-keygen to generate a new key pair within the HSM, pkcs11-list to list objects currently available, pkcs11-destroy to remove objects, and pkcs11-tokens to list available tokens. In UNIX/Linux builds, these tools are built only if BIND 9 is configured with the --with-pkcs11 option. (Note: If --with-pkcs11 is set to "yes", rather than to the path of the PKCS#11 provider, then the tools will be built but the provider will be left undefined. Use the -m option or the PKCS11_PROVIDER environment variable to specify the path to the provider.) Using the HSM For OpenSSL-based PKCS#11, we must first set up the runtime environment so the OpenSSL and PKCS#11 libraries can be loaded: $ export LD_LIBRARY_PATH=/opt/pkcs11/usr/lib:${LD_LIBRARY_PATH} This causes named and other binaries to load the OpenSSL library from /opt/pkcs11/usr/lib rather than from the default location. This step is not necessary when using native PKCS#11. Some HSMs require other environment variables to be set. For example, when operating an AEP Keyper, it is necessary to specify the location of the "machine" file, which stores information about the Keyper for use by the provider library. If the machine file is in /opt/Keyper/PKCS11Provider/machine, use: $ export KEYPER_LIBRARY_PATH=/opt/Keyper/PKCS11Provider Such environment variables must be set whenever running any tool that uses the HSM, including pkcs11-keygen, pkcs11-list, pkcs11-destroy, dnssec-keyfromlabel, dnssec-signzone, dnssec-keygen, and named. We can now create and use keys in the HSM. In this case, we will create a 2048 bit key and give it the label "sample-ksk": $ pkcs11-keygen -b 2048 -l sample-ksk To confirm that the key exists: $ pkcs11-list Enter PIN: object[0]: handle 2147483658 class 3 label[8] 'sample-ksk' id[0] object[1]: handle 2147483657 class 2 label[8] 'sample-ksk' id[0] Before using this key to sign a zone, we must create a pair of BIND 9 key files. The "dnssec-keyfromlabel" utility does this. In this case, we will be using the HSM key "sample-ksk" as the key-signing key for "example.net": $ dnssec-keyfromlabel -l sample-ksk -f KSK example.net The resulting K*.key and K*.private files can now be used to sign the zone. Unlike normal K* files, which contain both public and private key data, these files will contain only the public key data, plus an identifier for the private key which remains stored within the HSM. Signing with the private key takes place inside the HSM. If you wish to generate a second key in the HSM for use as a zone-signing key, follow the same procedure above, using a different keylabel, a smaller key size, and omitting "-f KSK" from the dnssec-keyfromlabel arguments: (Note: When using OpenSSL-based PKCS#11 the label is an arbitrary string which identifies the key. With native PKCS#11, the label is a PKCS#11 URI string which may include other details about the key and the HSM, including its PIN. See for details.) $ pkcs11-keygen -b 1024 -l sample-zsk $ dnssec-keyfromlabel -l sample-zsk example.net Alternatively, you may prefer to generate a conventional on-disk key, using dnssec-keygen: $ dnssec-keygen example.net This provides less security than an HSM key, but since HSMs can be slow or cumbersome to use for security reasons, it may be more efficient to reserve HSM keys for use in the less frequent key-signing operation. The zone-signing key can be rolled more frequently, if you wish, to compensate for a reduction in key security. (Note: When using native PKCS#11, there is no speed advantage to using on-disk keys, as cryptographic operations will be done by the HSM regardless.) Now you can sign the zone. (Note: If not using the -S option to dnssec-signzone, it will be necessary to add the contents of both K*.key files to the zone master file before signing it.) $ dnssec-signzone -S example.net Enter PIN: Verifying the zone using the following algorithms: NSEC3RSASHA1. Zone signing complete: Algorithm: NSEC3RSASHA1: ZSKs: 1, KSKs: 1 active, 0 revoked, 0 stand-by example.net.signed Specifying the engine on the command line When using OpenSSL-based PKCS#11, the "engine" to be used by OpenSSL can be specified in named and all of the BIND dnssec-* tools by using the "-E <engine>" command line option. If BIND 9 is built with the --with-pkcs11 option, this option defaults to "pkcs11". Specifying the engine will generally not be necessary unless for some reason you wish to use a different OpenSSL engine. If you wish to disable use of the "pkcs11" engine — for troubleshooting purposes, or because the HSM is unavailable — set the engine to the empty string. For example: $ dnssec-signzone -E '' -S example.net This causes dnssec-signzone to run as if it were compiled without the --with-pkcs11 option. When built with native PKCS#11 mode, the "engine" option has a different meaning: it specifies the path to the PKCS#11 provider library. This may be useful when testing a new provider library. Running named with automatic zone re-signing If you want named to dynamically re-sign zones using HSM keys, and/or to to sign new records inserted via nsupdate, then named must have access to the HSM PIN. In OpenSSL-based PKCS#11, this is accomplished by placing the PIN into the openssl.cnf file (in the above examples, /opt/pkcs11/usr/ssl/openssl.cnf). The location of the openssl.cnf file can be overridden by setting the OPENSSL_CONF environment variable before running named. Sample openssl.cnf: openssl_conf = openssl_def [ openssl_def ] engines = engine_section [ engine_section ] pkcs11 = pkcs11_section [ pkcs11_section ] PIN = <PLACE PIN HERE> This will also allow the dnssec-* tools to access the HSM without PIN entry. (The pkcs11-* tools access the HSM directly, not via OpenSSL, so a PIN will still be required to use them.) In native PKCS#11 mode, the PIN can be provided in a file specified as an attribute of the key's label. For example, if a key had the label pkcs11:object=local-zsk;pin-source=/etc/hsmpin, then the PIN would be read from the file /etc/hsmpin. Placing the HSM's PIN in a text file in this manner may reduce the security advantage of using an HSM. Be sure this is what you want to do before configuring the system in this way. bind9-9.10.3.dfsg.P4/doc/arm/man.named-checkzone.html0000644000470500017500000004731012664710322021415 0ustar lamontlamont named-checkzone

Name

named-checkzone, named-compilezone — zone file validity checking or converting tool

Synopsis

named-checkzone [-d] [-h] [-j] [-q] [-v] [-c class] [-f format] [-F format] [-J filename] [-i mode] [-k mode] [-m mode] [-M mode] [-n mode] [-l ttl] [-L serial] [-o filename] [-r mode] [-s style] [-S mode] [-t directory] [-T mode] [-w directory] [-D] [-W mode] {zonename} {filename}

named-compilezone [-d] [-j] [-q] [-v] [-c class] [-C mode] [-f format] [-F format] [-J filename] [-i mode] [-k mode] [-m mode] [-n mode] [-l ttl] [-L serial] [-r mode] [-s style] [-t directory] [-T mode] [-w directory] [-D] [-W mode] {-o filename} {zonename} {filename}

DESCRIPTION

named-checkzone checks the syntax and integrity of a zone file. It performs the same checks as named does when loading a zone. This makes named-checkzone useful for checking zone files before configuring them into a name server.

named-compilezone is similar to named-checkzone, but it always dumps the zone contents to a specified file in a specified format. Additionally, it applies stricter check levels by default, since the dump output will be used as an actual zone file loaded by named. When manually specified otherwise, the check levels must at least be as strict as those specified in the named configuration file.

OPTIONS

-d

Enable debugging.

-h

Print the usage summary and exit.

-q

Quiet mode - exit code only.

-v

Print the version of the named-checkzone program and exit.

-j

When loading a zone file, read the journal if it exists. The journal file name is assumed to be the zone file name appended with the string .jnl.

-J filename

When loading the zone file read the journal from the given file, if it exists. (Implies -j.)

-c class

Specify the class of the zone. If not specified, "IN" is assumed.

-i mode

Perform post-load zone integrity checks. Possible modes are "full" (default), "full-sibling", "local", "local-sibling" and "none".

Mode "full" checks that MX records refer to A or AAAA record (both in-zone and out-of-zone hostnames). Mode "local" only checks MX records which refer to in-zone hostnames.

Mode "full" checks that SRV records refer to A or AAAA record (both in-zone and out-of-zone hostnames). Mode "local" only checks SRV records which refer to in-zone hostnames.

Mode "full" checks that delegation NS records refer to A or AAAA record (both in-zone and out-of-zone hostnames). It also checks that glue address records in the zone match those advertised by the child. Mode "local" only checks NS records which refer to in-zone hostnames or that some required glue exists, that is when the nameserver is in a child zone.

Mode "full-sibling" and "local-sibling" disable sibling glue checks but are otherwise the same as "full" and "local" respectively.

Mode "none" disables the checks.

-f format

Specify the format of the zone file. Possible formats are "text" (default), "raw", and "map".

-F format

Specify the format of the output file specified. For named-checkzone, this does not cause any effects unless it dumps the zone contents.

Possible formats are "text" (default), which is the standard textual representation of the zone, and "map", "raw", and "raw=N", which store the zone in a binary format for rapid loading by named. "raw=N" specifies the format version of the raw zone file: if N is 0, the raw file can be read by any version of named; if N is 1, the file can be read by release 9.9.0 or higher; the default is 1.

-k mode

Perform "check-names" checks with the specified failure mode. Possible modes are "fail" (default for named-compilezone), "warn" (default for named-checkzone) and "ignore".

-l ttl

Sets a maximum permissible TTL for the input file. Any record with a TTL higher than this value will cause the zone to be rejected. This is similar to using the max-zone-ttl option in named.conf.

-L serial

When compiling a zone to "raw" or "map" format, set the "source serial" value in the header to the specified serial number. (This is expected to be used primarily for testing purposes.)

-m mode

Specify whether MX records should be checked to see if they are addresses. Possible modes are "fail", "warn" (default) and "ignore".

-M mode

Check if a MX record refers to a CNAME. Possible modes are "fail", "warn" (default) and "ignore".

-n mode

Specify whether NS records should be checked to see if they are addresses. Possible modes are "fail" (default for named-compilezone), "warn" (default for named-checkzone) and "ignore".

-o filename

Write zone output to filename. If filename is - then write to standard out. This is mandatory for named-compilezone.

-r mode

Check for records that are treated as different by DNSSEC but are semantically equal in plain DNS. Possible modes are "fail", "warn" (default) and "ignore".

-s style

Specify the style of the dumped zone file. Possible styles are "full" (default) and "relative". The full format is most suitable for processing automatically by a separate script. On the other hand, the relative format is more human-readable and is thus suitable for editing by hand. For named-checkzone this does not cause any effects unless it dumps the zone contents. It also does not have any meaning if the output format is not text.

-S mode

Check if a SRV record refers to a CNAME. Possible modes are "fail", "warn" (default) and "ignore".

-t directory

Chroot to directory so that include directives in the configuration file are processed as if run by a similarly chrooted named.

-T mode

Check if Sender Policy Framework (SPF) records exist and issues a warning if an SPF-formatted TXT record is not also present. Possible modes are "warn" (default), "ignore".

-w directory

chdir to directory so that relative filenames in master file $INCLUDE directives work. This is similar to the directory clause in named.conf.

-D

Dump zone file in canonical format. This is always enabled for named-compilezone.

-W mode

Specify whether to check for non-terminal wildcards. Non-terminal wildcards are almost always the result of a failure to understand the wildcard matching algorithm (RFC 1034). Possible modes are "warn" (default) and "ignore".

zonename

The domain name of the zone being checked.

filename

The name of the zone file.

RETURN VALUES

named-checkzone returns an exit status of 1 if errors were detected and 0 otherwise.

SEE ALSO

named(8), named-checkconf(8), RFC 1035, BIND 9 Administrator Reference Manual.

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/latex-fixup.pl0000644000470500017500000000421512664710322017522 0ustar lamontlamont#!/usr/bin/perl -w # # Copyright (C) 2005, 2007, 2012, 2015 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: latex-fixup.pl,v 1.5 2007/06/19 23:47:13 tbox Exp $ # Sadly, the final stages of generating a presentable PDF file always # seem to require some manual tweaking. Doesn't seem to matter what # typesetting tool one uses, sane forms of automation only go so far, # at least with present technology. # # This script is intended to be a collection of tweaks. The theory is # that, while we can't avoid the need for tweaking, we can at least # write the silly things down in a form that a program might be able # to execute. Undoubtedly everythig in here will break, eventually, # at which point it will need to be updated, but since the alternative # is to do the final editing by hand every time, this approach seems # the lesser of two evils. while (<>) { # Fix a db2latex oops. LaTeX2e does not like having tables with # duplicate names. Perhaps the dblatex project will fix this # someday, but we can get by with just deleting the offending # LaTeX commands for now. s/\\addtocounter\{table\}\{-1\}//g; # Line break in the middle of quoting one period looks weird. s/{\\texttt{{\.\\dbz{}}}}/\\mbox{{\\texttt{{\.\\dbz{}}}}}/; # Add any further tweaking here. # https://en.wikibooks.org/wiki/LaTeX/Special_Characters s/쎶/{\\"o}/; # umlaut o 쎶 or 쎶 # Write out whatever we have now. print; } bind9-9.10.3.dfsg.P4/doc/arm/dlz.xml0000644000470500017500000001506612664710322016240 0ustar lamontlamont DLZ (Dynamically Loadable Zones) DLZ (Dynamically Loadable Zones) is an extension to BIND 9 that allows zone data to be retrieved directly from an external database. There is no required format or schema. DLZ drivers exist for several different database backends including PostgreSQL, MySQL, and LDAP and can be written for any other. Historically, DLZ drivers had to be statically linked with the named binary and were turned on via a configure option at compile time (for example, "configure --with-dlz-ldap"). Currently, the drivers provided in the BIND 9 tarball in contrib/dlz/drivers are still linked this way. In BIND 9.8 and higher, it is possible to link some DLZ modules dynamically at runtime, via the DLZ "dlopen" driver, which acts as a generic wrapper around a shared object implementing the DLZ API. The "dlopen" driver is linked into named by default, so configure options are no longer necessary when using these dynamically linkable drivers, but are still needed for the older drivers in contrib/dlz/drivers. When the DLZ module provides data to named, it does so in text format. The response is converted to DNS wire format by named. This conversion, and the lack of any internal caching, places significant limits on the query performance of DLZ modules. Consequently, DLZ is not recommended for use on high-volume servers. However, it can be used in a hidden master configuration, with slaves retrieving zone updates via AXFR. (Note, however, that DLZ has no built-in support for DNS notify; slaves are not automatically informed of changes to the zones in the database.) Configuring DLZ A DLZ database is configured with a dlz statement in named.conf: dlz example { database "dlopen driver.so "; search yes; }; This specifies a DLZ module to search when answering queries; the module is implemented in driver.so and is loaded at runtime by the dlopen DLZ driver. Multiple dlz statements can be specified; when answering a query, all DLZ modules with set to yes will be queried to find out if they contain an answer for the query name; the best available answer will be returned to the client. The option in the above example can be omitted, because yes is the default value. If is set to no, then this DLZ module is not searched for the best match when a query is received. Instead, zones in this DLZ must be separately specified in a zone statement. This allows you to configure a zone normally using standard zone option semantics, but specify a different database back-end for storage of the zone's data. For example, to implement NXDOMAIN redirection using a DLZ module for back-end storage of redirection rules: dlz other { database "dlopen driver.so "; search no; }; zone "." { type redirect; dlz other; }; Sample DLZ Driver For guidance in implementation of DLZ modules, the directory contrib/dlz/example contains a basic dynamically-linkable DLZ module--i.e., one which can be loaded at runtime by the "dlopen" DLZ driver. The example sets up a single zone, whose name is passed to the module as an argument in the dlz statement: dlz other { database "dlopen driver.so example.nil"; }; In the above example, the module is configured to create a zone "example.nil", which can answer queries and AXFR requests, and accept DDNS updates. At runtime, prior to any updates, the zone contains an SOA, NS, and a single A record at the apex: example.nil. 3600 IN SOA example.nil. hostmaster.example.nil. ( 123 900 600 86400 3600 ) example.nil. 3600 IN NS example.nil. example.nil. 1800 IN A 10.53.0.1 The sample driver is capable of retrieving information about the querying client, and altering its response on the basis of this information. To demonstrate this feature, the example driver responds to queries for "source-addr.>/TXT" with the source address of the query. Note, however, that this record will *not* be included in AXFR or ANY responses. Normally, this feature would be used to alter responses in some other fashion, e.g., by providing different address records for a particular name depending on the network from which the query arrived. Documentation of the DLZ module API can be found in contrib/dlz/example/README. This directory also contains the header file dlz_minimal.h, which defines the API and should be included by any dynamically-linkable DLZ module. bind9-9.10.3.dfsg.P4/doc/arm/Bv9ARM.ch09.html0000644000470500017500000002105612664710322017351 0ustar lamontlamont Appendix A. Release Notes

Appendix A. Release Notes

Release Notes for BIND Version 9.10.3-P4

Introduction

This document summarizes changes since BIND 9.10.3:

BIND 9.10.3-P4 addresses the security issues described in CVE-2016-1285, CVE-2016-1286 and CVE-2016-2088.

BIND 9.10.3-P3 addresses the security issues described in CVE-2015-8704 and CVE-2015-8705. It also fixes a serious regression in authoritative server selection that was introduced in BIND 9.10.3.

BIND 9.10.3-P2 addresses the security issues described in CVE-2015-3193 (OpenSSL), CVE-2015-8000 and CVE-2015-8461.

BIND 9.10.3-P1 was incomplete and was withdrawn prior to publication.

Download

The latest versions of BIND 9 software can always be found at http://www.isc.org/downloads/. There you will find additional information about each release, source code, and pre-compiled versions for Microsoft Windows operating systems.

Security Fixes

  • Duplicate EDNS COOKIE options in a response could trigger an assertion failure. This flaw is disclosed in CVE-2016-2088. [RT #41809]

  • The resolver could abort with an assertion failure due to improper DNAME handling when parsing fetch reply messages. This flaw is disclosed in CVE-2016-1286. [RT #41753]

  • Malformed control messages can trigger assertions in named and rndc. This flaw is disclosed in CVE-2016-1285. [RT #41666]

  • Certain errors that could be encountered when printing out or logging an OPT record containing a CLIENT-SUBNET option could be mishandled, resulting in an assertion failure. This flaw is disclosed in CVE-2015-8705. [RT #41397]

  • Specific APL data could trigger an INSIST. This flaw is disclosed in CVE-2015-8704. [RT #41396]

  • Named is potentially vulnerable to the OpenSSL vulnerability described in CVE-2015-3193.

  • Incorrect reference counting could result in an INSIST failure if a socket error occurred while performing a lookup. This flaw is disclosed in CVE-2015-8461. [RT#40945]

  • Insufficient testing when parsing a message allowed records with an incorrect class to be be accepted, triggering a REQUIRE failure when those records were subsequently cached. This flaw is disclosed in CVE-2015-8000. [RT #40987]

New Features

  • None.

Feature Changes

  • Updated the compiled in addresses for H.ROOT-SERVERS.NET.

Bug Fixes

  • Authoritative servers that were marked as bogus (e.g. blackholed in configuration or with invalid addresses) were being queried anyway. [RT #41321]

End of Life

The end of life for BIND 9.10 is yet to be determined but will not be before BIND 9.12.0 has been released for 6 months. https://www.isc.org/downloads/software-support-policy/

Thank You

Thank you to everyone who assisted us in making this release possible. If you would like to contribute to ISC to assist us in continuing to make quality open source software, please visit our donations page at http://www.isc.org/donate/.

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/man.dnssec-checkds.html0000644000470500017500000001346212664710322021244 0ustar lamontlamont dnssec-checkds

Name

dnssec-checkds — A DNSSEC delegation consistency checking tool.

Synopsis

dnssec-checkds [-l domain] [-f file] [-d dig path] [-D dsfromkey path] {zone}

dnssec-dsfromkey [-l domain] [-f file] [-d dig path] [-D dsfromkey path] {zone}

DESCRIPTION

dnssec-checkds verifies the correctness of Delegation Signer (DS) or DNSSEC Lookaside Validation (DLV) resource records for keys in a specified zone.

OPTIONS

-f file

If a file is specified, then the zone is read from that file to find the DNSKEY records. If not, then the DNSKEY records for the zone are looked up in the DNS.

-l domain

Check for a DLV record in the specified lookaside domain, instead of checking for a DS record in the zone's parent. For example, to check for DLV records for "example.com" in ISC's DLV zone, use: dnssec-checkds -l dlv.isc.org example.com

-d dig path

Specifies a path to a dig binary. Used for testing.

-D dsfromkey path

Specifies a path to a dnssec-dsfromkey binary. Used for testing.

SEE ALSO

dnssec-dsfromkey(8), dnssec-keygen(8), dnssec-signzone(8),

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/man.arpaname.html0000644000470500017500000000676112664710322020153 0ustar lamontlamont arpaname

Name

arpaname — translate IP addresses to the corresponding ARPA names

Synopsis

arpaname {ipaddress ...}

DESCRIPTION

arpaname translates IP addresses (IPv4 and IPv6) to the corresponding IN-ADDR.ARPA or IP6.ARPA names.

SEE ALSO

BIND 9 Administrator Reference Manual.

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/arm/man.dnssec-coverage.html0000644000470500017500000002573012664710322021434 0ustar lamontlamont dnssec-coverage

Name

dnssec-coverage — checks future DNSKEY coverage for a zone

Synopsis

dnssec-coverage [-K directory] [-l length] [-f file] [-d DNSKEY TTL] [-m max TTL] [-r interval] [-c compilezone path] [-k] [-z] [zone]

DESCRIPTION

dnssec-coverage verifies that the DNSSEC keys for a given zone or a set of zones have timing metadata set properly to ensure no future lapses in DNSSEC coverage.

If zone is specified, then keys found in the key repository matching that zone are scanned, and an ordered list is generated of the events scheduled for that key (i.e., publication, activation, inactivation, deletion). The list of events is walked in order of occurrence. Warnings are generated if any event is scheduled which could cause the zone to enter a state in which validation failures might occur: for example, if the number of published or active keys for a given algorithm drops to zero, or if a key is deleted from the zone too soon after a new key is rolled, and cached data signed by the prior key has not had time to expire from resolver caches.

If zone is not specified, then all keys in the key repository will be scanned, and all zones for which there are keys will be analyzed. (Note: This method of reporting is only accurate if all the zones that have keys in a given repository share the same TTL parameters.)

OPTIONS

-K directory

Sets the directory in which keys can be found. Defaults to the current working directory.

-f file

If a file is specified, then the zone is read from that file; the largest TTL and the DNSKEY TTL are determined directly from the zone data, and the -m and -d options do not need to be specified on the command line.

-l duration

The length of time to check for DNSSEC coverage. Key events scheduled further into the future than duration will be ignored, and assumed to be correct.

The value of duration can be set in seconds, or in larger units of time by adding a suffix: 'mi' for minutes, 'h' for hours, 'd' for days, 'w' for weeks, 'mo' for months, 'y' for years.

-m maximum TTL

Sets the value to be used as the maximum TTL for the zone or zones being analyzed when determining whether there is a possibility of validation failure. When a zone-signing key is deactivated, there must be enough time for the record in the zone with the longest TTL to have expired from resolver caches before that key can be purged from the DNSKEY RRset. If that condition does not apply, a warning will be generated.

The length of the TTL can be set in seconds, or in larger units of time by adding a suffix: 'mi' for minutes, 'h' for hours, 'd' for days, 'w' for weeks, 'mo' for months, 'y' for years.

This option is mandatory unless the -f has been used to specify a zone file. (If -f has been specified, this option may still be used; it will override the value found in the file.)

-d DNSKEY TTL

Sets the value to be used as the DNSKEY TTL for the zone or zones being analyzed when determining whether there is a possibility of validation failure. When a key is rolled (that is, replaced with a new key), there must be enough time for the old DNSKEY RRset to have expired from resolver caches before the new key is activated and begins generating signatures. If that condition does not apply, a warning will be generated.

The length of the TTL can be set in seconds, or in larger units of time by adding a suffix: 'mi' for minutes, 'h' for hours, 'd' for days, 'w' for weeks, 'mo' for months, 'y' for years.

This option is mandatory unless the -f has been used to specify a zone file, or a default key TTL was set with the -L to dnssec-keygen. (If either of those is true, this option may still be used; it will override the value found in the zone or key file.)

-r resign interval

Sets the value to be used as the resign interval for the zone or zones being analyzed when determining whether there is a possibility of validation failure. This value defaults to 22.5 days, which is also the default in named. However, if it has been changed by the sig-validity-interval option in named.conf, then it should also be changed here.

The length of the interval can be set in seconds, or in larger units of time by adding a suffix: 'mi' for minutes, 'h' for hours, 'd' for days, 'w' for weeks, 'mo' for months, 'y' for years.

-k

Only check KSK coverage; ignore ZSK events. Cannot be used with -z.

-z

Only check ZSK coverage; ignore KSK events. Cannot be used with -k.

-c compilezone path

Specifies a path to a named-compilezone binary. Used for testing.

SEE ALSO

dnssec-checkds(8), dnssec-dsfromkey(8), dnssec-keygen(8), dnssec-signzone(8)

AUTHOR

Internet Systems Consortium

BIND 9.10.3-P4

bind9-9.10.3.dfsg.P4/doc/misc/0002755000470500017500000000000012672612753015103 5ustar lamontlamontbind9-9.10.3.dfsg.P4/doc/misc/ipv60000644000470500017500000001070212664710322015700 0ustar lamontlamontCopyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") Copyright (C) 2000, 2001 Internet Software Consortium. See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. Currently, there are multiple interesting problems with ipv6 implementations on various platforms. These problems range from not being able to use ipv6 with bind9 (or in particular the ISC socket library, contained in libisc) to listen-on lists not being respected, to strange warnings but seemingly correct behavior of named. COMPILE-TIME ISSUES ------------------- The socket library requires a certain level of support from the operating system. In particular, it must follow the advanced ipv6 socket API to be usable. The systems which do not follow this will currently not get any warnings or errors, but ipv6 will simply not function on them. These systems currently include, but are not limited to: AIX 3.4 (with ipv6 patches) RUN-TIME ISSUES --------------- In the original drafts of the ipv6 RFC documents, binding an ipv6 socket to the ipv6 wildcard address would also cause the socket to accept ipv4 connections and datagrams. When an ipv4 packet is received on these systems, it is mapped into an ipv6 address. For example, 1.2.3.4 would be mapped into ::ffff:1.2.3.4. The intent of this mapping was to make transition from an ipv4-only application into ipv6 easier, by only requiring one socket to be open on a given port. Later, it was discovered that this was generally a bad idea. For one, many firewalls will block connection to 1.2.3.4, but will let through ::ffff:1.2.3.4. This, of course, is bad. Also, access control lists written to accept only ipv4 addresses were suddenly ignored unless they were rewritten to handle the ipv6 mapped addresses as well. Partly because of these problems, the latest IPv6 API introduces an explicit knob (the "IPV6_V6ONLY" socket option ) to turn off the ipv6 mapped address usage. In bind9, we first check if both the advanced API and the IPV6_V6ONLY socket option are available. If both of them are available, bind9 named will bind to the ipv6 wildcard port for both TCP and UDP. Otherwise named will make a warning and try to bind to all available ipv6 addresses separately. In any case, bind9 named binds to specific addresses for ipv4 sockets. The followings are historical notes when we always bound to the ipv6 wildcard port regardless of the availability of the API support. These problems should not happen with the closer checks above. IPV6 Sockets Accept IPV4, Specific IPV4 Addresses Bindings Fail --------------------------------------------------------------- The only OS which seems to do this is (some kernel versions of) linux. If an ipv6 socket is bound to the ipv6 wildcard socket, and a specific ipv4 socket is later bound (say, to 1.2.3.4 port 53) the ipv4 binding will fail. What this means to bind9 is that the application will log warnings about being unable to bind to a socket because the address is already in use. Since the ipv6 socket will accept ipv4 packets and map them, however, the ipv4 addresses continue to function. The effect is that the config file listen-on directive will not be respected on these systems. IPV6 Sockets Accept IPV4, Specific IPV4 Address Bindings Succeed ---------------------------------------------------------------- In this case, the system allows opening an ipv6 wildcard address socket and then binding to a more specific ipv4 address later. An example of this type of system is Digital Unix with ipv6 patches applied. What this means to bind9 is that the application will respect listen-on in regards to ipv4 sockets, but it will use mapped ipv6 addresses for any that do not match the listen-on list. This, in effect, makes listen-on useless for these machines as well. IPV6 Sockets Do Not Accept IPV4 ------------------------------- On these systems, opening an IPV6 socket does not implicitly open any ipv4 sockets. An example of these systems are NetBSD-current with the latest KAME patch, and other systems which use the latest KAME patches as their ipv6 implementation. On these systems, listen-on is fully functional, as the ipv6 socket only accepts ipv6 packets, and the ipv4 sockets will handle the ipv4 packets. RELEVANT RFCs ------------- 3513: Internet Protocol Version 6 (IPv6) Addressing Architecture 3493: Basic Socket Interface Extensions for IPv6 3542: Advanced Sockets Application Program Interface (API) for IPv6 $Id: ipv6,v 1.9 2004/08/10 04:27:51 jinmei Exp $ bind9-9.10.3.dfsg.P4/doc/misc/SIT0000644000470500017500000000633312664710322015460 0ustar lamontlamontCopyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. Source Identity Token Source Identity Token (SIT) is based in Donald Eastlake 3rd's DNS Cookies[1]. The main differences are that the error code has been dropped and that the server cookie doesn't have a fixed length and may be missing. The error code has been dropped because it served no useful purpose for us. If it was to be restored it should be the first element of the option. We extended the server cookie to transmit server time and to include a server generated nonce. The purpose of these is to provide a short window of time (1 hour with a 5 minutes of clock skew for cluster time) where a previous cookie can be used for and to not require the server secret to be updated when it is shared by a cluster of servers. In particular the time of generation needed to be passed between servers via the client so that old cookie can be rejected. The option structure is: client cookie (64 bits) server cookie (128 bits) broken up into: - nonce (32 bits) - time (32 bits) - hash (64 bits) The initial requests just sends the client cookie. If the response contains a matching client cookie the entire response is saved and sent on the next transaction. A new server cookie is generated for every response. We are currently using EDNS Experimental code point 65001. This is subject to change. We have three supported hash method. AES, HMAC SHA 1 and HMAC SHA 256. A cluster of servers needs to choose one of them. AES memset(input, 0, sizeof(input)); cp = isc_buffer_used(buf); isc_buffer_putmem(buf, client->cookie, 8); isc_buffer_putuint32(buf, nonce); isc_buffer_putuint32(buf, when); memmove(input, cp, 16); isc_aes128_crypt(ns_g_server->secret, input, digest); for (i = 0; i < 8; i++) input[i] = digest[i] ^ digest[i + 8]; isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); switch (netaddr.family) { case AF_INET: memmove(input + 8, (unsigned char *)&netaddr.type.in, 4); memset(input + 12, 0, 4); isc_aes128_crypt(ns_g_server->secret, input, digest); break; case AF_INET6: memmove(input + 8, (unsigned char *)&netaddr.type.in6, 16); isc_aes128_crypt(ns_g_server->secret, input, digest); for (i = 0; i < 8; i++) input[i + 8] = digest[i] ^ digest[i + 8]; isc_aes128_crypt(ns_g_server->secret, input + 8, digest); break; } for (i = 0; i < 8; i++) digest[i] ^= digest[i + 8]; isc_buffer_putmem(buf, digest, 8); HMAC SHA1 hash = trunc(hmacsha1(secret, client|nonce|when|address), 8); HMAC SHA256 hash = trunc(hmacsha256(secret, client|nonce|when|address), 8); [1] INTERNET-DRAFT Donald Eastlake Intended Status: Proposed Standard Huawei Expires: July 21, 2014 January 22, 2014 Domain Name System (DNS) Cookies bind9-9.10.3.dfsg.P4/doc/misc/Makefile.in0000644000470500017500000000321512664710322017137 0ustar lamontlamont# Copyright (C) 2004, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.9 2009/07/10 23:47:58 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_MAKE_RULES@ PERL = @PERL@ MANOBJS = options doc man:: ${MANOBJS} docclean manclean maintainer-clean:: rm -f options # Do not make options depend on ../../bin/tests/cfg_test, doing so # will cause excessively clever versions of make to attempt to build # that program right here, right now, if it is missing, which will # cause make doc to bomb. CFG_TEST = ../../bin/tests/cfg_test options: FORCE if test -x ${CFG_TEST} ; \ then \ ${CFG_TEST} --named --grammar > $@.raw ; \ ${PERL} ${srcdir}/sort-options.pl < $@.raw > $@.sorted ; \ ${PERL} ${srcdir}/format-options.pl < $@.sorted > $@.new ; \ mv -f $@.new $@ ; \ rm -f $@.raw $@.sorted ; \ else \ rm -f $@.new $@.raw $@.sorted ; \ fi bind9-9.10.3.dfsg.P4/doc/misc/dnssec0000644000470500017500000000602312664710322016274 0ustar lamontlamontCopyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") Copyright (C) 2000-2002 Internet Software Consortium. See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. DNSSEC Release Notes This document summarizes the state of the DNSSEC implementation in this release of BIND9. OpenSSL Library Required To support DNSSEC, BIND 9 must be linked with version 0.9.6e or newer of the OpenSSL library. As of BIND 9.2, the library is no longer included in the distribution - it must be provided by the operating system or installed separately. To build BIND 9 with OpenSSL, use "configure --with-openssl". If the OpenSSL library is installed in a nonstandard location, you can specify a path as in "configure --with-openssl=/var". Key Generation and Signing The tools for generating DNSSEC keys and signatures are now in the bin/dnssec directory. Documentation for these programs can be found in doc/arm/Bv9ARM.4.html and the man pages. The random data used in generating DNSSEC keys and signatures comes from either /dev/random (if the OS supports it) or keyboard input. Alternatively, a device or file containing entropy/random data can be specified. Serving Secure Zones When acting as an authoritative name server, BIND9 includes KEY, SIG and NXT records in responses as specified in RFC2535 when the request has the DO flag set in the query. Secure Resolution Basic support for validation of DNSSEC signatures in responses has been implemented but should still be considered experimental. When acting as a caching name server, BIND9 is capable of performing basic DNSSEC validation of positive as well as nonexistence responses. This functionality is enabled by including a "trusted-keys" clause in the configuration file, containing the top-level zone key of the the DNSSEC tree. Validation of wildcard responses is not currently supported. In particular, a "name does not exist" response will validate successfully even if it does not contain the NXT records to prove the nonexistence of a matching wildcard. Proof of insecure status for insecure zones delegated from secure zones works when the zones are completely insecure. Privately secured zones delegated from secure zones will not work in all cases, such as when the privately secured zone is served by the same server as an ancestor (but not parent) zone. Handling of the CD bit in queries is now fully implemented. Validation is not attempted for recursive queries if CD is set. Secure Dynamic Update Dynamic update of secure zones has been implemented, but may not be complete. Affected NXT and SIG records are updated by the server when an update occurs. Advanced access control is possible using the "update-policy" statement in the zone definition. Secure Zone Transfers BIND 9 does not implement the zone transfer security mechanisms of RFC2535 section 5.6, and we have no plans to implement them in the future as we consider them inferior to the use of TSIG or SIG(0) to ensure the integrity of zone transfers. $Id: dnssec,v 1.19 2004/03/05 05:04:53 marka Exp $ bind9-9.10.3.dfsg.P4/doc/misc/sort-options.pl0000644000470500017500000000255212664710322020112 0ustar lamontlamont#!/bin/perl # # Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: sort-options.pl,v 1.3 2007/09/24 23:46:48 tbox Exp $ sub sortlevel() { my @options = (); my $fin = ""; my $i = 0; while (<>) { if (/^\s*};$/) { $fin = $_; # print 2, $_; last; } next if (/^$/); if (/{$/) { # print 3, $_; my $sec = $_; push(@options, $sec . sortlevel()); } else { push(@options, $_); # print 1, $_; } $i++; } my $result = ""; foreach my $i (sort @options) { $result = ${result}.${i}; $result = $result."\n" if ($i =~ /^[a-z]/i); # print 5, ${i}; } $result = ${result}.${fin}; return ($result); } print sortlevel(); bind9-9.10.3.dfsg.P4/doc/misc/roadmap0000644000470500017500000000376512664710322016452 0ustar lamontlamontCopyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") Copyright (C) 2000, 2001 Internet Software Consortium. See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. $Id: roadmap,v 1.2 2004/03/05 05:04:54 marka Exp $ Road Map to the BIND 9 Source Tree bin/named The name server. This relies heavily on the libraries in lib/isc and lib/dns. client.c Handling of incoming client requests query.c Query processing bin/rndc The remote name daemon control program bin/dig The "dig" program bin/dnssec The DNSSEC signer and other DNSSEC tools bin/nsupdate The "nsupdate" program bin/tests Test suites and miscellaneous test programs bin/tests/system System tests; see bin/tests/system/README lib/dns The DNS library resolver.c The "full resolver" (performs recursive lookups) validator.c The DNSSEC validator db.c The database interface sdb.c The simple database interface rbtdb.c The red-black tree database lib/dns/rdata Routines for handling the various RR types lib/dns/sec Cryptographic libraries for DNSSEC lib/isc The ISC library task.c Task library unix/socket.c Unix implementation of socket library lib/isccfg Routines for reading and writing ISC-style configuration files like named.conf and rndc.conf lib/isccc The command channel library, used by rndc. lib/tests Support code for the test suites. lib/lwres The lightweight resolver library. doc/draft Current internet-drafts pertaining to the DNS doc/rfc RFCs pertaining to the DNS doc/misc Miscellaneous documentation doc/arm The BIND 9 Administrator Reference Manual doc/man Man pages contrib Contributed and other auxiliary code contrib/idn/mdnkit The multilingual domain name evaluation kit contrib/sdb Sample drivers for the simple database interface make Makefile fragments, used by configure The library interfaces are mainly documented in the form of comments in the header files. For example, the task subsystem is documented in lib/isc/include/isc/task.h bind9-9.10.3.dfsg.P4/doc/misc/migration-4to90000644000470500017500000000401612664710322017603 0ustar lamontlamontCopyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") Copyright (C) 2001 Internet Software Consortium. See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. $Id: migration-4to9,v 1.4 2004/03/05 05:04:53 marka Exp $ BIND 4 to BIND 9 Migration Notes To transition from BIND 4 to BIND 9 you first need to convert your configuration file to the new format. There is a conversion tool in contrib/named-bootconf that allows you to do this. named-bootconf.sh < /etc/named.boot > /etc/named.conf BIND 9 uses a system assigned port for the UDP queries it makes rather than port 53 that BIND 4 uses. This may conflict with some firewalls. The following directives in /etc/named.conf allows you to specify a port to use. query-source address * port 53; transfer-source * port 53; notify-source * port 53; BIND 9 no longer uses the minimum field to specify the TTL of records without a explicit TTL. Use the $TTL directive to specify a default TTL before the first record without a explicit TTL. $TTL 3600 @ IN SOA ns1.example.com. hostmaster.example.com. ( 2001021100 7200 1200 3600000 7200 ) BIND 9 does not support multiple CNAMEs with the same owner name. Illegal: www.example.com. CNAME host1.example.com. www.example.com. CNAME host2.example.com. BIND 9 does not support "CNAMEs with other data" with the same owner name, ignoring the DNSSEC records (SIG, NXT, KEY) that BIND 4 did not support. Illegal: www.example.com. CNAME host1.example.com. www.example.com. MX 10 host2.example.com. BIND 9 is less tolerant of errors in master files, so check your logs and fix any errors reported. The named-checkzone program can also be to check master files. Outgoing zone transfers now use the "many-answers" format by default. This format is not understood by certain old versions of BIND 4. You can work around this problem using the option "transfer-format one-answer;", but since these old versions all have known security problems, the correct fix is to upgrade the slave servers. bind9-9.10.3.dfsg.P4/doc/misc/format-options.pl0000644000470500017500000000274612664710322020420 0ustar lamontlamont#!/usr/bin/perl # # Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: format-options.pl,v 1.5 2007/09/24 04:21:59 marka Exp $ print <) { chomp; s/\t/ /g; my $line = $_; m!^( *)!; my $indent = $1; my $comment = ""; if ( $line =~ m!//.*! ) { $comment = $&; $line =~ s!//.*!!; } my $start = ""; while (length($line) >= 79 - length($comment)) { $_ = $line; # this makes sure that the comment has something in front of it $len = 75 - length($comment); m!^(.{0,$len}) (.*)$!; $start = $start.$1."\n"; $line = $indent." ".$2; } print $start.$line.$comment."\n"; } bind9-9.10.3.dfsg.P4/doc/misc/rfc-compliance0000644000470500017500000000524312664710322017702 0ustar lamontlamontCopyright (C) 2004, 2015 Internet Systems Consortium, Inc. ("ISC") Copyright (C) 2001 Internet Software Consortium. See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. $Id: rfc-compliance,v 1.4 2004/03/05 05:04:53 marka Exp $ BIND 9 is striving for strict compliance with IETF standards. We believe this release of BIND 9 complies with the following RFCs, with the caveats and exceptions listed in the numbered notes below. Note that a number of these RFCs do not have the status of Internet standards but are proposed or draft standards, experimental RFCs, or Best Current Practice (BCP) documents. RFC1034 RFC1035 [1] [2] RFC1123 RFC1183 RFC1535 RFC1536 RFC1706 RFC1712 RFC1750 RFC1876 RFC1982 RFC1995 RFC1996 RFC2136 RFC2163 RFC2181 RFC2230 RFC2308 RFC2536 RFC2539 RFC2782 RFC2915 RFC2930 RFC2931 [5] RFC3007 RFC3110 RFC3123 RFC3225 RFC3226 RFC3363 [6] RFC3490 [7] RFC3491 (Obsoleted by 5890, 5891) [7] RFC3493 RFC3496 RFC3597 RFC3645 RFC4025 RFC4034 RFC4035 RFC4074 RFC4255 RFC4294 - Section 5.1 [8] RFC4343 RFC4398 RFC4408 RFC4431 RFC4470 [9] RFC4509 RFC4635 RFC4701 RFC4892 RFC4955 [10] RFC5001 RFC5011 RFC5155 RFC5205 RFC5452 [11] RFC5702 RFC5933 [12] RFC5936 RFC5952 RFC5966 RFC6052 RFC6147 [13] RFC6303 RFC6605 [14] RFC6672 RFC6698 RFC6742 RFC6840 [15] RFC6844 RFC6891 RFC7043 RFC7314 RFC7314 The following DNS related RFC have been obsoleted RFC2535 (Obsoleted by 4034, 4035) [3] [4] RFC2537 (Obsoleted by 3110) RFC2538 (Obsoleted by 4398) RFC2671 (Obsoleted by 6891) RFC2672 (Obsoleted by 6672) RFC2673 (Obsoleted by 6891) RFC3008 (Obsoleted by 4034, 4035) RFC3152 (Obsoleted by 3596) RFC3445 (Obsoleted by 4034, 4035) RFC3655 (Obsoleted by 4034, 4035) RFC3658 (Obsoleted by 4034, 4035) RFC3755 (Obsoleted by 4034, 4035) RFC3757 (Obsoleted by 4034, 4035) [1] Queries to zones that have failed to load return SERVFAIL rather than a non-authoritative response. This is considered a feature. [2] CLASS ANY queries are not supported. This is considered a feature. [3] Wildcard records are not supported in DNSSEC secure zones. [4] Servers authoritative for secure zones being resolved by BIND 9 must support EDNS0 (RFC2671), and must return all relevant SIGs and NXTs in responses rather than relying on the resolving server to perform separate queries for missing SIGs and NXTs. [5] When receiving a query signed with a SIG(0), the server will only be able to verify the signature if it has the key in its local authoritative data; it will not do recursion or validation to retrieve unknown keys. bind9-9.10.3.dfsg.P4/doc/misc/sdb0000644000470500017500000001462612664710322015575 0ustar lamontlamontCopyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") Copyright (C) 2000, 2001 Internet Software Consortium. See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. Using the BIND 9 Simplified Database Interface This document describes the care and feeding of the BIND 9 Simplified Database Interface, which allows you to extend BIND 9 with new ways of obtaining the data that is published as DNS zones. The Original BIND 9 Database Interface BIND 9 has a well-defined "back-end database interface" that makes it possible to replace the component of the name server responsible for the storage and retrieval of zone data, called the "database", on a per-zone basis. The default database is an in-memory, red-black-tree data structure commonly referred to as "rbtdb", but it is possible to write drivers to support any number of alternative database technologies such as in-memory hash tables, application specific persistent on-disk databases, object databases, or relational databases. The original BIND 9 database interface defined in is designed to efficiently support the full set of database functionality needed by a name server that implements the complete DNS protocols, including features such as zone transfers, dynamic update, and DNSSEC. Each of these aspects of name server operations places its own set of demands on the data store, with the result that the database API is quite complex and contains operations that are highly specific to the DNS. For example, data are stored in a binary format, the name space is tree structured, and sets of data records are conceptually associated with DNSSEC signature sets. For these reasons, writing a driver using this interface is a highly nontrivial undertaking. The Simplified Database Interface Many BIND users wish to provide access to various data sources through the DNS, but are not necessarily interested in completely replacing the in-memory "rbt" database or in supporting features like dynamic update, DNSSEC, or even zone transfers. Often, all you want is limited, read-only DNS access to an existing system. For example, you may have an existing relational database containing hostname/address mappings and wish to provide forvard and reverse DNS lookups based on this information. Or perhaps you want to set up a simple DNS-based load balancing system where the name server answers queries about a single DNS name with a dynamically changing set of A records. BIND 9.1 introduced a new, simplified database interface, or "sdb", which greatly simplifies the writing of drivers for these kinds of applications. The sdb Driver An sdb driver is an object module, typically written in C, which is linked into the name server and registers itself with the sdb subsystem. It provides a set of callback functions, which also serve to advertise its capabilities. When the name server receives DNS queries, invokes the callback functions to obtain the data to respond with. Unlike the full database interface, the sdb interface represents all domain names and resource records as ASCII text. Writing an sdb Driver When a driver is registered, it specifies its name, a list of callback functions, and flags. The flags specify whether the driver wants to use relative domain names where possible. The callback functions are as follows. The only one that must be defined is lookup(). - create(zone, argc, argv, driverdata, dbdata) Create a database object for "zone". - destroy(zone, driverdata, dbdata) Destroy the database object for "zone". - lookup(zone, name, dbdata, lookup) Return all the records at the domain name "name". - authority(zone, dbdata, lookup) Return the SOA and NS records at the zone apex. - allnodes(zone, dbdata, allnodes) Return all data in the zone, for zone transfers. For more detail about these functions and their parameters, see bind9/lib/dns/include/dns/sdb.h. For example drivers, see bind9/contrib/sdb. Rebuilding the Server The driver module and header file must be copied to (or linked into) the bind9/bin/named and bind9/bin/named/include directories respectively, and must be added to the DBDRIVER_OBJS and DBDRIVER_SRCS lines in bin/named/Makefile.in (e.g. for the timedb sample sdb driver, add timedb.c to DBDRIVER_SRCS and timedb.@O@ to DBDRIVER_OBJS). If the driver needs additional header files or libraries in nonstandard places, the DBDRIVER_INCLUDES and DBDRIVER_LIBS lines should also be updated. Calls to dns_sdb_register() and dns_sdb_unregister() (or wrappers, e.g. timedb_init() and timedb_clear() for the timedb sample sdb driver) must be inserted into the server, in bind9/bin/named/main.c. Registration should be in setup(), before the call to ns_server_create(). Unregistration should be in cleanup(), after the call to ns_server_destroy(). A #include should be added corresponding to the driver header file. You should try doing this with one or more of the sample drivers before attempting to write a driver of your own. Configuring the Server To make a zone use a new database driver, specify a "database" option in its "zone" statement in named.conf. For example, if the driver registers itself under the name "acmedb", you might say zone "foo.com" { database "acmedb"; }; You can pass arbitrary arguments to the create() function of the driver by adding any number of whitespace-separated words after the driver name: zone "foo.com" { database "acmedb -mode sql -connect 10.0.0.1"; }; Hints for Driver Writers - If a driver is generating data on the fly, it probably should not implement the allnodes() function, since a zone transfer will not be meaningful. The allnodes() function is more relevant with data from a database. - The authority() function is necessary if and only if the lookup() function will not add SOA and NS records at the zone apex. If SOA and NS records are provided by the lookup() function, the authority() function should be NULL. - When a driver is registered, an opaque object can be provided. This object is passed into the database create() and destroy() functions. - When a database is created, an opaque object can be created that is associated with that database. This object is passed into the lookup(), authority(), and allnodes() functions, and is destroyed by the destroy() function. Future Directions A future release may support dynamic loading of sdb drivers. $Id: sdb,v 1.6 2004/03/05 05:04:54 marka Exp $ bind9-9.10.3.dfsg.P4/doc/misc/migration0000644000470500017500000002611112664710322017006 0ustar lamontlamontCopyright (C) 2004, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") Copyright (C) 2000, 2001, 2003 Internet Software Consortium. See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. BIND 8 to BIND 9 Migration Notes BIND 9 is designed to be mostly upwards compatible with BIND 8, but there is still a number of caveats you should be aware of when upgrading an existing BIND 8 installation to use BIND 9. 1. Configuration File Compatibility 1.1. Unimplemented Options and Changed Defaults BIND 9 supports most, but not all of the named.conf options of BIND 8. For a complete list of implemented options, see doc/misc/options. If your named.conf file uses an unimplemented option, named will log a warning message. A message is also logged about each option whose default has changed unless the option is set explicitly in named.conf. The default of the "transfer-format" option has changed from "one-answer" to "many-answers". If you have slave servers that do not understand the many-answers zone transfer format (e.g., BIND 4.9.5 or older) you need to explicitly specify "transfer-format one-answer;" in either the options block or a server statement. BIND 9.4 onwards implements "allow-query-cache". The "allow-query" option is no longer used to specify access to the cache. The "allow-query" option continues to specify which hosts are allowed to ask ordinary DNS questions. The new "allow-query-cache" option is used to specify which hosts are allowed to get answers from the cache. Since BIND 9.4.1, if "allow-query-cache" is not set then "allow-recursion" is used if it is set, otherwise "allow-query" is used if it is set, otherwise the default localnets and localhost is used. 1.2. Handling of Configuration File Errors In BIND 9, named refuses to start if it detects an error in named.conf. Earlier versions would start despite errors, causing the server to run with a partial configuration. Errors detected during subsequent reloads do not cause the server to exit. Errors in master files do not cause the server to exit, but they do cause the zone not to load. 1.3. Logging The set of logging categories in BIND 9 is different from that in BIND 8. If you have customised your logging on a per-category basis, you need to modify your logging statement to use the new categories. Another difference is that the "logging" statement only takes effect after the entire named.conf file has been read. This means that when the server starts up, any messages about errors in the configuration file are always logged to the default destination (syslog) when the server first starts up, regardless of the contents of the "logging" statement. In BIND 8, the new logging configuration took effect immediately after the "logging" statement was read. 1.4. Notify messages and Refresh queries The source address and port for these is now controlled by "notify-source" and "transfer-source", respectively, rather that query-source as in BIND 8. 1.5. Multiple Classes. Multiple classes have to be put into explicit views for each class. 2. Zone File Compatibility 2.1. Strict RFC1035 Interpretation of TTLs in Zone Files BIND 9 strictly complies with the RFC1035 and RFC2308 rules regarding omitted TTLs in zone files. Omitted TTLs are replaced by the value specified with the $TTL directive, or by the previous explicit TTL if there is no $TTL directive. If there is no $TTL directive and the first RR in the file does not have an explicit TTL field, the zone file is illegal according to RFC1035 since the TTL of the first RR is undefined. Unfortunately, BIND 4 and many versions of BIND 8 accept such files without warning and use the value of the SOA MINTTL field as a default for missing TTL values. BIND 9.0 and 9.1 completely refused to load such files. BIND 9.2 emulates the nonstandard BIND 4/8 SOA MINTTL behaviour and loads the files anyway (provided the SOA is the first record in the file), but will issue the warning message "no TTL specified; using SOA MINTTL instead". To avoid problems, we recommend that you use a $TTL directive in each zone file. 2.2. Periods in SOA Serial Numbers Deprecated Some versions of BIND allow SOA serial numbers with an embedded period, like "3.002", and convert them into integers in a rather unintuitive way. This feature is not supported by BIND 9; serial numbers must be integers. 2.3. Handling of Unbalanced Quotes TXT records with unbalanced quotes, like 'host TXT "foo', were not treated as errors in some versions of BIND. If your zone files contain such records, you will get potentially confusing error messages like "unexpected end of file" because BIND 9 will interpret everything up to the next quote character as a literal string. 2.4. Handling of Line Breaks Some versions of BIND accept RRs containing line breaks that are not properly quoted with parentheses, like the following SOA: @ IN SOA ns.example. hostmaster.example. ( 1 3600 1800 1814400 3600 ) This is not legal master file syntax and will be treated as an error by BIND 9. The fix is to move the opening parenthesis to the first line. 2.5. Unimplemented BIND 8 Extensions $GENERATE: The "$$" construct for getting a literal $ into a domain name is deprecated. Use \$ instead. 2.6. TXT records are no longer automatically split. Some versions of BIND accepted strings in TXT RDATA consisting of more than 255 characters and silently split them to be able to encode the strings in a protocol conformant way. You may now see errors like this dns_rdata_fromtext: local.db:119: ran out of space if you have TXT RRs with too longs strings. Make sure to split the string in the zone data file at or before a single one reaches 255 characters. 3. Interoperability Impact of New Protocol Features 3.1. EDNS0 BIND 9 uses EDNS0 (RFC2671) to advertise its receive buffer size. It also sets DO EDNS flag bit in queries to indicate that it wishes to receive DNSSEC responses. Most older servers that do not support EDNS0, including prior versions of BIND, will send a FORMERR or NOTIMP response to these queries. When this happens, BIND 9 will automatically retry the query without EDNS0. Unfortunately, there exists at least one non-BIND name server implementation that silently ignores these queries instead of sending an error response. Resolving names in zones where all or most authoritative servers use this server will be very slow or fail completely. We have contacted the manufacturer of the name server in case, and they are working on a solution. When BIND 9 communicates with a server that does support EDNS0, such as another BIND 9 server, responses of up to 4096 bytes may be transmitted as a single UDP datagram which is subject to fragmentation at the IP level. If a firewall incorrectly drops IP fragments, it can cause resolution to slow down dramatically or fail. 3.2. Zone Transfers Outgoing zone transfers now use the "many-answers" format by default. This format is not understood by certain old versions of BIND 4. You can work around this problem using the option "transfer-format one-answer;", but since these old versions all have known security problems, the correct fix is to upgrade the slave servers. Zone transfers to Windows 2000 DNS servers sometimes fail due to a bug in the Windows 2000 DNS server where DNS messages larger than 16K are not handled properly. Obtain the latest service pack for Windows 2000 from Microsoft to address this issue. In the meantime, the problem can be worked around by setting "transfer-format one-answer;". http://support.microsoft.com/default.aspx?scid=kb;en-us;297936 4. Unrestricted Character Set BIND 9.2 only BIND 9 does not restrict the character set of domain names - it is fully 8-bit clean in accordance with RFC2181 section 11. It is strongly recommended that hostnames published in the DNS follow the RFC952 rules, but BIND 9 will not enforce this restriction. Historically, some applications have suffered from security flaws where data originating from the network, such as names returned by gethostbyaddr(), are used with insufficient checking and may cause a breach of security when containing unexpected characters; see for details. Some earlier versions of BIND attempt to protect these flawed applications from attack by discarding data containing characters deemed inappropriate in host names or mail addresses, under the control of the "check-names" option in named.conf and/or "options no-check-names" in resolv.conf. BIND 9 provides no such protection; if applications with these flaws are still being used, they should be upgraded. BIND 9.3 onwards implements check-names. 5. Server Administration Tools 5.1 Ndc Replaced by Rndc The "ndc" program has been replaced by "rndc", which is capable of remote operation. Unlike ndc, rndc requires a configuration file. The easiest way to generate a configuration file is to run "rndc-confgen -a"; see the man pages for rndc(8), rndc-confgen(8), and rndc.conf(5) for details. 5.2. Nsupdate Differences The BIND 8 implementation of nsupdate had an undocumented feature where an update request would be broken down into multiple requests based upon the discovered zones that contained the records. This behaviour has not been implemented in BIND 9. Each update request must pertain to a single zone, but it is still possible to do multiple updates in a single invocation of nsupdate by terminating each update with an empty line or a "send" command. 6. No Information Leakage between Zones BIND 9 stores the authoritative data for each zone in a separate data structure, as recommended in RFC1035 and as required by DNSSEC and IXFR. When a BIND 9 server is authoritative for both a child zone and its parent, it will have two distinct sets of NS records at the delegation point: the authoritative NS records at the child's apex, and a set of glue NS records in the parent. BIND 8 was unable to properly distinguish between these two sets of NS records and would "leak" the child's NS records into the parent, effectively causing the parent zone to be silently modified: responses and zone transfers from the parent contained the child's NS records rather than the glue configured into the parent (if any). In the case of children of type "stub", this behaviour was documented as a feature, allowing the glue NS records to be omitted from the parent configuration. Sites that were relying on this BIND 8 behaviour need to add any omitted glue NS records, and any necessary glue A records, to the parent zone. Although stub zones can no longer be used as a mechanism for injecting NS records into their parent zones, they are still useful as a way of directing queries for a given domain to a particular set of name servers. 7. Umask not Modified The BIND 8 named unconditionally sets the umask to 022. BIND 9 does not; the umask inherited from the parent process remains in effect. This may cause files created by named, such as journal files, to be created with different file permissions than they did in BIND 8. If necessary, the umask should be set explicitly in the script used to start the named process. $Id: migration,v 1.49 2008/03/18 15:42:53 jreed Exp $ bind9-9.10.3.dfsg.P4/doc/misc/options0000644000470500017500000010132612664710322016512 0ustar lamontlamont This is a summary of the named.conf options supported by this version of BIND 9. acl { ; ... }; controls { inet ( | | * ) [ port ( | * ) ] allow { ; ... } [ keys { ; ... } ]; unix perm owner group [ keys { ; ... } ]; }; dlz { database ; search ; }; key { algorithm ; secret ; }; logging { category { ; ... }; channel { file [ versions ( "unlimited" | ) ] [ size ]; null; print-category ; print-severity ; print-time ; severity ; stderr; syslog ; }; }; lwres { listen-on [ port ] [ dscp ] { ( | ) [ port ] [ dscp ]; ... }; ndots ; search { ; ... }; view ; }; managed-keys { ; ... }; masters [ port ] [ dscp ] { ( | [ port ] | [ port ] ) [ key ]; ... }; options { acache-cleaning-interval ; acache-enable ; additional-from-auth ; additional-from-cache ; allow-new-zones ; allow-notify { ; ... }; allow-query { ; ... }; allow-query-cache { ; ... }; allow-query-cache-on { ; ... }; allow-query-on { ; ... }; allow-recursion { ; ... }; allow-recursion-on { ; ... }; allow-transfer { ; ... }; allow-update { ; ... }; allow-update-forwarding { ; ... }; allow-v6-synthesis { ; ... }; // obsolete also-notify [ port ] [ dscp ] { ( | [ port ] | [ port ] ) [ key ]; ... }; alt-transfer-source ( | * ) [ port ( | * ) ] [ dscp ]; alt-transfer-source-v6 ( | * ) [ port ( | * ) ] [ dscp ]; attach-cache ; auth-nxdomain ; // default changed auto-dnssec ( allow | maintain | off ); automatic-interface-scan ; avoid-v4-udp-ports { ; ... }; avoid-v6-udp-ports { ; ... }; bindkeys-file ; blackhole { ; ... }; cache-file ; check-dup-records ( fail | warn | ignore ); check-integrity ; check-mx ( fail | warn | ignore ); check-mx-cname ( fail | warn | ignore ); check-names ( master | slave | response ) ( fail | warn | ignore ); check-sibling ; check-spf ( warn | ignore ); check-srv-cname ( fail | warn | ignore ); check-wildcard ; cleaning-interval ; clients-per-query ; coresize ; datasize ; deallocate-on-exit ; // obsolete deny-answer-addresses { ; ... } [ except-from { ; ... } ]; deny-answer-aliases { ; ... } [ except-from { ; ... } ]; dialup ; directory ; disable-algorithms { ; ... }; disable-ds-digests { ; ... }; disable-empty-zone ; dns64 { break-dnssec ; clients { ; ... }; exclude { ; ... }; mapped { ; ... }; recursive-only ; suffix ; }; dns64-contact ; dns64-server ; dnssec-accept-expired ; dnssec-dnskey-kskonly ; dnssec-enable ; dnssec-loadkeys-interval ; dnssec-lookaside ( trust-anchor | auto | no ); dnssec-must-be-secure ; dnssec-secure-to-insecure ; dnssec-update-mode ( maintain | no-resign ); dnssec-validation ( yes | no | auto ); dscp ; dual-stack-servers [ port ] { ( [ port ] [ dscp ] | [ port ] [ dscp ] | [ port ] [ dscp ] ); ... }; dump-file ; edns-udp-size ; empty-contact ; empty-server ; empty-zones-enable ; fake-iquery ; // obsolete fetch-glue ; // obsolete files ; filter-aaaa { ; ... }; // not configured filter-aaaa-on-v4 ; // not configured filter-aaaa-on-v6 ; // not configured flush-zones-on-shutdown ; forward ( first | only ); forwarders [ port ] [ dscp ] { ( | ) [ port ] [ dscp ]; ... }; geoip-directory ( | none ); // not configured has-old-clients ; // obsolete heartbeat-interval ; host-statistics ; // not implemented host-statistics-max ; // not implemented hostname ( | none ); inline-signing ; interface-interval ; ixfr-from-differences ; key-directory ; lame-ttl ; listen-on [ port ] [ dscp ] { ; ... }; listen-on-v6 [ port ] [ dscp ] { ; ... }; maintain-ixfr-base ; // obsolete managed-keys-directory ; masterfile-format ( text | raw | map ); match-mapped-addresses ; max-acache-size ; max-cache-size ; max-cache-ttl ; max-clients-per-query ; max-ixfr-log-size ; // obsolete max-journal-size ; max-ncache-ttl ; max-recursion-depth ; max-recursion-queries ; max-refresh-time ; max-retry-time ; max-rsa-exponent-size ; max-transfer-idle-in ; max-transfer-idle-out ; max-transfer-time-in ; max-transfer-time-out ; max-udp-size ; max-zone-ttl ; memstatistics ; memstatistics-file ; min-refresh-time ; min-retry-time ; min-roots ; // not implemented minimal-responses ; multi-master ; multiple-cnames ; // obsolete named-xfer ; // obsolete no-case-compress { ; ... }; nosit-udp-size ; // not configured notify ; notify-delay ; notify-source ( | * ) [ port ( | * ) ] [ dscp ]; notify-source-v6 ( | * ) [ port ( | * ) ] [ dscp ]; notify-to-soa ; nsec3-test-zone ; // test only pid-file ( | none ); port ; preferred-glue ; prefetch [ ]; provide-ixfr ; query-source ; query-source-v6 ; querylog ; queryport-pool-ports ; // obsolete queryport-pool-updateinterval ; // obsolete random-device ; rate-limit { all-per-second ; errors-per-second ; exempt-clients { ; ... }; ipv4-prefix-length ; ipv6-prefix-length ; log-only ; max-table-size ; min-table-size ; nodata-per-second ; nxdomains-per-second ; qps-scale ; referrals-per-second ; responses-per-second ; slip ; window ; }; recursing-file ; recursion ; recursive-clients ; request-ixfr ; request-nsid ; request-sit ; // not configured reserved-sockets ; resolver-query-timeout ; response-policy { zone [ policy ( given | disabled | passthru | no-op | drop | tcp-only | nxdomain | nodata | cname ) ] [ recursive-only ] [ max-policy-ttl ]; ... } [ recursive-only ] [ break-dnssec ] [ max-policy-ttl ] [ min-ns-dots ] [ qname-wait-recurse ]; rfc2308-type1 ; // not yet implemented root-delegation-only [ exclude { ; ... } ]; rrset-order { [ class ] [ type ] [ name ] ; ... }; secroots-file ; serial-queries ; // obsolete serial-query-rate ; serial-update-method ( increment | unixtime ); server-id ( | none | hostname ); session-keyalg ; session-keyfile ( | none ); session-keyname ; sig-signing-nodes ; sig-signing-signatures ; sig-signing-type ; sig-validity-interval [ ]; sit-secret ; // not configured sortlist { ; ... }; stacksize ; statistics-file ; statistics-interval ; // not yet implemented suppress-initial-notify ; // not yet implemented tcp-clients ; tcp-listen-queue ; tkey-dhkey ; tkey-domain ; tkey-gssapi-credential ; tkey-gssapi-keytab ; topology { ; ... }; // not implemented transfer-format ( many-answers | one-answer ); transfer-source ( | * ) [ port ( | * ) ] [ dscp ]; transfer-source-v6 ( | * ) [ port ( | * ) ] [ dscp ]; transfers-in ; transfers-out ; transfers-per-ns ; treat-cr-as-space ; // obsolete try-tcp-refresh ; update-check-ksk ; use-alt-transfer-source ; use-id-pool ; // obsolete use-ixfr ; use-queryport-pool ; // obsolete use-v4-udp-ports { ; ... }; use-v6-udp-ports { ; ... }; version ( | none ); zero-no-soa-ttl ; zero-no-soa-ttl-cache ; zone-statistics ; }; server { bogus ; edns ; edns-udp-size ; keys ; max-udp-size ; notify-source ( | * ) [ port ( | * ) ] [ dscp ]; notify-source-v6 ( | * ) [ port ( | * ) ] [ dscp ]; provide-ixfr ; query-source ; query-source-v6 ; request-ixfr ; request-nsid ; request-sit ; // not configured support-ixfr ; // obsolete transfer-format ( many-answers | one-answer ); transfer-source ( | * ) [ port ( | * ) ] [ dscp ]; transfer-source-v6 ( | * ) [ port ( | * ) ] [ dscp ]; transfers ; }; statistics-channels { inet ( | | * ) [ port ( | * ) ] [ allow { ; ... } ]; }; trusted-keys { ; ... }; view { acache-cleaning-interval ; acache-enable ; additional-from-auth ; additional-from-cache ; allow-new-zones ; allow-notify { ; ... }; allow-query { ; ... }; allow-query-cache { ; ... }; allow-query-cache-on { ; ... }; allow-query-on { ; ... }; allow-recursion { ; ... }; allow-recursion-on { ; ... }; allow-transfer { ; ... }; allow-update { ; ... }; allow-update-forwarding { ; ... }; allow-v6-synthesis { ; ... }; // obsolete also-notify [ port ] [ dscp ] { ( | [ port ] | [ port ] ) [ key ]; ... }; alt-transfer-source ( | * ) [ port ( | * ) ] [ dscp ]; alt-transfer-source-v6 ( | * ) [ port ( | * ) ] [ dscp ]; attach-cache ; auth-nxdomain ; // default changed auto-dnssec ( allow | maintain | off ); cache-file ; check-dup-records ( fail | warn | ignore ); check-integrity ; check-mx ( fail | warn | ignore ); check-mx-cname ( fail | warn | ignore ); check-names ( master | slave | response ) ( fail | warn | ignore ); check-sibling ; check-spf ( warn | ignore ); check-srv-cname ( fail | warn | ignore ); check-wildcard ; cleaning-interval ; clients-per-query ; deny-answer-addresses { ; ... } [ except-from { ; ... } ]; deny-answer-aliases { ; ... } [ except-from { ; ... } ]; dialup ; disable-algorithms { ; ... }; disable-ds-digests { ; ... }; disable-empty-zone ; dlz { database ; search ; }; dns64 { break-dnssec ; clients { ; ... }; exclude { ; ... }; mapped { ; ... }; recursive-only ; suffix ; }; dns64-contact ; dns64-server ; dnssec-accept-expired ; dnssec-dnskey-kskonly ; dnssec-enable ; dnssec-loadkeys-interval ; dnssec-lookaside ( trust-anchor | auto | no ); dnssec-must-be-secure ; dnssec-secure-to-insecure ; dnssec-update-mode ( maintain | no-resign ); dnssec-validation ( yes | no | auto ); dual-stack-servers [ port ] { ( [ port ] [ dscp ] | [ port ] [ dscp ] | [ port ] [ dscp ] ); ... }; edns-udp-size ; empty-contact ; empty-server ; empty-zones-enable ; fetch-glue ; // obsolete filter-aaaa { ; ... }; // not configured filter-aaaa-on-v4 ; // not configured filter-aaaa-on-v6 ; // not configured forward ( first | only ); forwarders [ port ] [ dscp ] { ( | ) [ port ] [ dscp ]; ... }; inline-signing ; ixfr-from-differences ; key { algorithm ; secret ; }; key-directory ; lame-ttl ; maintain-ixfr-base ; // obsolete managed-keys { ; ... }; masterfile-format ( text | raw | map ); match-clients { ; ... }; match-destinations { ; ... }; match-recursive-only ; max-acache-size ; max-cache-size ; max-cache-ttl ; max-clients-per-query ; max-ixfr-log-size ; // obsolete max-journal-size ; max-ncache-ttl ; max-recursion-depth ; max-recursion-queries ; max-refresh-time ; max-retry-time ; max-transfer-idle-in ; max-transfer-idle-out ; max-transfer-time-in ; max-transfer-time-out ; max-udp-size ; max-zone-ttl ; min-refresh-time ; min-retry-time ; min-roots ; // not implemented minimal-responses ; multi-master ; no-case-compress { ; ... }; nosit-udp-size ; // not configured notify ; notify-delay ; notify-source ( | * ) [ port ( | * ) ] [ dscp ]; notify-source-v6 ( | * ) [ port ( | * ) ] [ dscp ]; notify-to-soa ; nsec3-test-zone ; // test only preferred-glue ; prefetch [ ]; provide-ixfr ; query-source ; query-source-v6 ; queryport-pool-ports ; // obsolete queryport-pool-updateinterval ; // obsolete rate-limit { all-per-second ; errors-per-second ; exempt-clients { ; ... }; ipv4-prefix-length ; ipv6-prefix-length ; log-only ; max-table-size ; min-table-size ; nodata-per-second ; nxdomains-per-second ; qps-scale ; referrals-per-second ; responses-per-second ; slip ; window ; }; recursion ; request-ixfr ; request-nsid ; request-sit ; // not configured resolver-query-timeout ; response-policy { zone [ policy ( given | disabled | passthru | no-op | drop | tcp-only | nxdomain | nodata | cname ) ] [ recursive-only ] [ max-policy-ttl ]; ... } [ recursive-only ] [ break-dnssec ] [ max-policy-ttl ] [ min-ns-dots ] [ qname-wait-recurse ]; rfc2308-type1 ; // not yet implemented root-delegation-only [ exclude { ; ... } ]; rrset-order { [ class ] [ type ] [ name ] ; ... }; serial-update-method ( increment | unixtime ); server { bogus ; edns ; edns-udp-size ; keys ; max-udp-size ; notify-source ( | * ) [ port ( | * ) ] [ dscp ]; notify-source-v6 ( | * ) [ port ( | * ) ] [ dscp ]; provide-ixfr ; query-source ; query-source-v6 ; request-ixfr ; request-nsid ; request-sit ; // not configured support-ixfr ; // obsolete transfer-format ( many-answers | one-answer ); transfer-source ( | * ) [ port ( | * ) ] [ dscp ]; transfer-source-v6 ( | * ) [ port ( | * ) ] [ dscp ]; transfers ; }; sig-signing-nodes ; sig-signing-signatures ; sig-signing-type ; sig-validity-interval [ ]; sortlist { ; ... }; suppress-initial-notify ; // not yet implemented topology { ; ... }; // not implemented transfer-format ( many-answers | one-answer ); transfer-source ( | * ) [ port ( | * ) ] [ dscp ]; transfer-source-v6 ( | * ) [ port ( | * ) ] [ dscp ]; trusted-keys { ; ... }; try-tcp-refresh ; update-check-ksk ; use-alt-transfer-source ; use-queryport-pool ; // obsolete zero-no-soa-ttl ; zero-no-soa-ttl-cache ; zone { allow-notify { ; ... }; allow-query { ; ... }; allow-query-on { ; ... }; allow-transfer { ; ... }; allow-update { ; ... }; allow-update-forwarding { ; ... }; also-notify [ port ] [ dscp ] { ( | [ port ] | [ port ] ) [ key ]; ... }; alt-transfer-source ( | * ) [ port ( | * ) ] [ dscp ]; alt-transfer-source-v6 ( | * ) [ port ( | * ) ] [ dscp ]; auto-dnssec ( allow | maintain | off ); check-dup-records ( fail | warn | ignore ); check-integrity ; check-mx ( fail | warn | ignore ); check-mx-cname ( fail | warn | ignore ); check-names ( fail | warn | ignore ); check-sibling ; check-spf ( warn | ignore ); check-srv-cname ( fail | warn | ignore ); check-wildcard ; database ; delegation-only ; dialup ; dlz ; dnssec-dnskey-kskonly ; dnssec-loadkeys-interval ; dnssec-secure-to-insecure ; dnssec-update-mode ( maintain | no-resign ); file ; forward ( first | only ); forwarders [ port ] [ dscp ] { ( | ) [ port ] [ dscp ]; ... }; in-view ; inline-signing ; ixfr-base ; // obsolete ixfr-from-differences ; ixfr-tmp-file ; // obsolete journal ; key-directory ; maintain-ixfr-base ; // obsolete masterfile-format ( text | raw | map ); masters [ port ] [ dscp ] { ( | [ port ] | [ port ] ) [ key ]; ... }; max-ixfr-log-size ; // obsolete max-journal-size ; max-refresh-time ; max-retry-time ; max-transfer-idle-in ; max-transfer-idle-out ; max-transfer-time-in ; max-transfer-time-out ; max-zone-ttl ; min-refresh-time ; min-retry-time ; multi-master ; notify ; notify-delay ; notify-source ( | * ) [ port ( | * ) ] [ dscp ]; notify-source-v6 ( | * ) [ port ( | * ) ] [ dscp ]; notify-to-soa ; nsec3-test-zone ; // test only pubkey ; // obsolete request-ixfr ; serial-update-method ( increment | unixtime ); server-addresses { ( | ) [ port ]; ... }; server-names { ; ... }; sig-signing-nodes ; sig-signing-signatures ; sig-signing-type ; sig-validity-interval [ ]; transfer-source ( | * ) [ port ( | * ) ] [ dscp ]; transfer-source-v6 ( | * ) [ port ( | * ) ] [ dscp ]; try-tcp-refresh ; type ( master | slave | stub | static-stub | hint | forward | delegation-only | redirect ); update-check-ksk ; update-policy ( local | { ( grant | deny ) ( name | subdomain | wildcard | self | selfsub | selfwild | krb5-self | ms-self | krb5-subdomain | ms-subdomain | tcp-self | 6to4-self | zonesub | external ) [ ] ; ... }; use-alt-transfer-source ; zero-no-soa-ttl ; zone-statistics ; }; zone-statistics ; }; zone { allow-notify { ; ... }; allow-query { ; ... }; allow-query-on { ; ... }; allow-transfer { ; ... }; allow-update { ; ... }; allow-update-forwarding { ; ... }; also-notify [ port ] [ dscp ] { ( | [ port ] | [ port ] ) [ key ]; ... }; alt-transfer-source ( | * ) [ port ( | * ) ] [ dscp ]; alt-transfer-source-v6 ( | * ) [ port ( | * ) ] [ dscp ]; auto-dnssec ( allow | maintain | off ); check-dup-records ( fail | warn | ignore ); check-integrity ; check-mx ( fail | warn | ignore ); check-mx-cname ( fail | warn | ignore ); check-names ( fail | warn | ignore ); check-sibling ; check-spf ( warn | ignore ); check-srv-cname ( fail | warn | ignore ); check-wildcard ; database ; delegation-only ; dialup ; dlz ; dnssec-dnskey-kskonly ; dnssec-loadkeys-interval ; dnssec-secure-to-insecure ; dnssec-update-mode ( maintain | no-resign ); file ; forward ( first | only ); forwarders [ port ] [ dscp ] { ( | ) [ port ] [ dscp ]; ... }; in-view ; inline-signing ; ixfr-base ; // obsolete ixfr-from-differences ; ixfr-tmp-file ; // obsolete journal ; key-directory ; maintain-ixfr-base ; // obsolete masterfile-format ( text | raw | map ); masters [ port ] [ dscp ] { ( | [ port ] | [ port ] ) [ key ]; ... }; max-ixfr-log-size ; // obsolete max-journal-size ; max-refresh-time ; max-retry-time ; max-transfer-idle-in ; max-transfer-idle-out ; max-transfer-time-in ; max-transfer-time-out ; max-zone-ttl ; min-refresh-time ; min-retry-time ; multi-master ; notify ; notify-delay ; notify-source ( | * ) [ port ( | * ) ] [ dscp ]; notify-source-v6 ( | * ) [ port ( | * ) ] [ dscp ]; notify-to-soa ; nsec3-test-zone ; // test only pubkey ; // obsolete request-ixfr ; serial-update-method ( increment | unixtime ); server-addresses { ( | ) [ port ]; ... }; server-names { ; ... }; sig-signing-nodes ; sig-signing-signatures ; sig-signing-type ; sig-validity-interval [ ]; transfer-source ( | * ) [ port ( | * ) ] [ dscp ]; transfer-source-v6 ( | * ) [ port ( | * ) ] [ dscp ]; try-tcp-refresh ; type ( master | slave | stub | static-stub | hint | forward | delegation-only | redirect ); update-check-ksk ; update-policy ( local | { ( grant | deny ) ( name | subdomain | wildcard | self | selfsub | selfwild | krb5-self | ms-self | krb5-subdomain | ms-subdomain | tcp-self | 6to4-self | zonesub | external ) [ ] ; ... }; use-alt-transfer-source ; zero-no-soa-ttl ; zone-statistics ; }; bind9-9.10.3.dfsg.P4/config.sub0000644000470500017500000010541212664710322015354 0ustar lamontlamont#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2013 Free Software Foundation, Inc. timestamp='2013-10-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches with a ChangeLog entry to config-patches@gnu.org. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 \ | or1k | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or1k-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: bind9-9.10.3.dfsg.P4/configure0000755000470500017500000250575412664710322015322 0ustar lamontlamont#! /bin/sh # Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1996-2003 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for BIND 9.10. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and bind9-bugs@isc.org $0: about your system, including any error possibly output $0: before this message. Then install a modern shell, or $0: manually run the script under such a shell if you do $0: have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='BIND' PACKAGE_TARNAME='bind' PACKAGE_VERSION='9.10' PACKAGE_STRING='BIND 9.10' PACKAGE_BUGREPORT='bind9-bugs@isc.org' PACKAGE_URL='https://www.isc.org/downloads/BIND/' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='LTLIBOBJS LIBOBJS BUILD_LIBS BUILD_LDFLAGS BUILD_CPPFLAGS BUILD_CFLAGS BUILD_CC DLZ_SYSTEM_TEST DLZ_DRIVER_OBJS DLZ_DRIVER_SRCS DLZ_DRIVER_LIBS DLZ_DRIVER_INCLUDES CONTRIB_DLZ PG_CONFIG SO_TARGETS SO_LD SO_LDFLAGS SO_CFLAGS SO BIND9_CONFIGARGS BIND9_SRCID BIND9_VERSIONSTRING BIND9_MAJOR BIND9_VERSION BIND9_DESCRIPTION BIND9_PRODUCT BIND9_IRS_BUILDINCLUDE BIND9_BIND9_BUILDINCLUDE BIND9_LWRES_BUILDINCLUDE BIND9_DNS_BUILDINCLUDE BIND9_ISCCFG_BUILDINCLUDE BIND9_ISCCC_BUILDINCLUDE BIND9_ISC_BUILDINCLUDE BIND9_TOP_BUILDDIR UNITTESTS ATFLIBS ATFBIN ATFBUILD IDNLIBS XSLT_DB2LATEX_ADMONITIONS XSLT_DB2LATEX_STYLE XSLT_DOCBOOK_MAKETOC_XHTML XSLT_DOCBOOK_MAKETOC_HTML XSLT_DOCBOOK_CHUNKTOC_XHTML XSLT_DOCBOOK_CHUNKTOC_HTML XSLT_DOCBOOK_CHUNK_XHTML XSLT_DOCBOOK_CHUNK_HTML XSLT_DOCBOOK_STYLE_MAN XSLT_DOCBOOK_STYLE_XHTML XSLT_DOCBOOK_STYLE_HTML CURL DOXYGEN XMLLINT XSLTPROC W3M PDFLATEX LATEX ISC_ARCH_DIR ISC_PLATFORM_USEMACASM ISC_PLATFORM_USESTDASM ISC_PLATFORM_USEOSFASM ISC_PLATFORM_USEGCCASM ISC_PLATFORM_HAVEATOMICSTORE ISC_PLATFORM_HAVECMPXCHG ISC_PLATFORM_HAVEXADDQ ISC_PLATFORM_HAVEXADD ISC_PLATFORM_HAVEIFNAMETOINDEX ISC_PLATFORM_HAVESTRINGSH ISC_PLATFORM_BRACEPTHREADONCEINIT IRS_PLATFORM_USEDECLSPEC LWRES_PLATFORM_USEDECLSPEC ISC_PLATFORM_USEDECLSPEC ISC_PLATFORM_RLIMITTYPE ISC_PLATFORM_HAVESYSUNH LWRES_PLATFORM_QUADFORMAT ISC_PLATFORM_QUADFORMAT DST_EXTRA_SRCS DST_EXTRA_OBJS USE_ISC_SPNEGO ISC_EXTRA_SRCS ISC_EXTRA_OBJS LWRES_PLATFORM_NEEDVSNPRINTF LWRES_PLATFORM_NEEDSPRINTF ISC_PLATFORM_NEEDVSNPRINTF ISC_PLATFORM_NEEDSPRINTF ISC_PLATFORM_NEEDFPRINTF ISC_PLATFORM_NEEDPRINTF READLINE_LIB ISC_PLATFORM_NEEDSTRCASESTR ISC_PLATFORM_NEEDSTRLCAT LWRES_PLATFORM_NEEDSTRLCPY ISC_PLATFORM_NEEDSTRLCPY GENRANDOMLIB LWRES_PLATFORM_NEEDSTRTOUL ISC_PLATFORM_NEEDSTRTOUL ISC_PLATFORM_NEEDMEMMOVE ISC_PLATFORM_NEEDSTRSEP ISC_IRS_GETNAMEINFOSOCKLEN ISC_LWRES_GETNAMEINFOPROTO ISC_LWRES_GETADDRINFOPROTO ISC_LWRES_GETIPNODEPROTO ISC_LWRES_NEEDHERRNO ISC_LWRES_GETHOSTBYADDRVOID ISC_LWRES_ENDNETENTINT ISC_LWRES_SETNETENTINT ISC_LWRES_GETNETBYADDRINADDR ISC_LWRES_ENDHOSTENTINT ISC_LWRES_SETHOSTENTINT ISC_LWRES_NEEDRRSETINFO ISC_IRS_NEEDADDRINFO ISC_LWRES_NEEDADDRINFO ISC_PLATFORM_NEEDPORTT ISC_PLATFORM_MSGHDRFLAVOR LWRES_PLATFORM_HAVESALEN ISC_PLATFORM_HAVESALEN ISC_PLATFORM_NEEDPTON ISC_PLATFORM_NEEDNTOP ISC_PLATFORM_HAVEIF_LADDRCONF ISC_PLATFORM_HAVEIF_LADDRREQ ISC_PLATFORM_HAVESCOPEID LWRES_HAVE_SIN6_SCOPE_ID ISC_IPV6_C ISC_ISCIPV6_O ISC_IPV6_O ISC_IPV6_H ISC_PLATFORM_HAVESOCKADDRSTORAGE ISC_PLATFORM_FIXIN6ISADDR ISC_PLATFORM_HAVEIN6PKTINFO LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK ISC_PLATFORM_NEEDIN6ADDRLOOPBACK LWRES_PLATFORM_NEEDIN6ADDRANY ISC_PLATFORM_NEEDIN6ADDRANY LWRES_PLATFORM_HAVEINADDR6 ISC_PLATFORM_HAVEINADDR6 LWRES_PLATFORM_NEEDNETINET6IN6H ISC_PLATFORM_NEEDNETINET6IN6H LWRES_PLATFORM_NEEDNETINETIN6H ISC_PLATFORM_NEEDNETINETIN6H LWRES_PLATFORM_HAVEIPV6 ISC_PLATFORM_HAVEIPV6 BIND9_CO_RULE LIBTOOL_IN_MAIN LIBTOOL_ALLOW_UNDEFINED LIBTOOL_MODE_LINK LIBTOOL_MODE_INSTALL LIBTOOL_MODE_COMPILE LIBTOOL_MKDEP_SED SA A O ALWAYS_MAKE_SYMTABLE MKSYMTBL_PROGRAM ISC_PLATFORM_USEBACKTRACE PURIFY purify_path IRIX_DNSSEC_WARNINGS_HACK MKDEPPROG MKDEPCFLAGS MKDEPCC PKCS11_TEST PKCS11_GOST PKCS11_ECDSA CRYPTO PKCS11LINKSRCS PKCS11LINKOBJS PKCS11_PROVIDER ISC_ISCPK11_API_O ISC_ISCPK11_API_C ISC_PK11_RESULT_O ISC_PK11_RESULT_C ISC_PK11_API_O ISC_PK11_API_C ISC_PK11_O ISC_PK11_C PKCS11_ENGINE PKCS11_TOOLS USE_PKCS11 ISC_OPENSSL_LIBS ISC_OPENSSL_INC ISC_PLATFORM_OPENSSLHASH ISC_PLATFORM_WANTAES OPENSSL_GOST OPENSSL_ECDSA OPENSSLLINKSRCS OPENSSLLINKOBJS OPENSSLGOSTLINKSRCS OPENSSLGOSTLINKOBJS DST_OPENSSL_INC HAVE_SIT ISC_PLATFORM_USESIT INSTALL_LIBRARY ISC_THREAD_DIR THREADOPTSRCS THREADOPTOBJS ISC_PLATFORM_USETHREADS ALWAYS_DEFINES CHECK_DSA DNS_CRYPTO_LIBS DNS_GSSAPI_LIBS DST_GSSAPI_INC USE_GSSAPI ISC_PLATFORM_KRB5HEADER ISC_PLATFORM_GSSAPI_KRB5_HEADER ISC_PLATFORM_GSSAPIHEADER ISC_PLATFORM_HAVEGSSAPI GEOIPLINKOBJS GEOIPLINKSRCS LWRES_PLATFORM_NEEDSYSSELECTH ISC_PLATFORM_NEEDSYSSELECTH ISC_PLATFORM_HAVEDEVPOLL ISC_PLATFORM_HAVEEPOLL ISC_PLATFORM_HAVEKQUEUE ISC_PLATFORM_HAVELIFCONF ISC_PLATFORM_NORETURN_POST ISC_PLATFORM_NORETURN_PRE ISC_PLATFORM_HAVELONGLONG ISC_SOCKADDR_LEN_T PYTHON_TOOLS COVERAGE CHECKDS PYTHON PERL ETAGS LN ARFLAGS BACKTRACECFLAGS CCNOOPT CCOPT STD_CWARNINGS STD_CDEFINES STD_CINCLUDES INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM CPP OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL AWK RANLIB STRIP ac_ct_AR AR DLLTOOL OBJDUMP LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP SED OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC LIBTOOL SET_MAKE host_os host_vendor host_cpu host build_os build_vendor build_cpu build target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='BIND9_MAKE_INCLUDES BIND9_MAKE_RULES LIBISC_API LIBISCCC_API LIBISCCFG_API LIBDNS_API LIBDNS_MAPAPI LIBBIND9_API LIBLWRES_API LIBIRS_API DLZ_DRIVER_RULES' ac_user_opts=' enable_option_checking enable_shared enable_static with_pic enable_fast_install with_gnu_ld with_sysroot enable_libtool_lock enable_libbind enable_warn_shadow enable_warn_error enable_developer enable_seccomp with_python enable_kqueue enable_epoll enable_devpoll with_geoip with_gssapi with_randomdev enable_threads with_locktype with_libtool enable_native_pkcs11 with_openssl with_pkcs11 with_ecdsa with_gost with_aes enable_openssl_hash enable_sit with_sit_alg enable_openssl_version_check with_libxml2 with_libjson enable_largefile with_purify with_gperftools_profiler enable_backtrace enable_symtable enable_ipv6 with_kame enable_getifaddrs with_readline enable_isc_spnego enable_chroot enable_linux_caps with_rlimtype enable_atomic enable_fixed_rrset enable_rpz_nsip enable_rpz_nsdname enable_fetchlimit enable_filter_aaaa with_docbook_xsl with_idn with_libiconv with_iconv with_idnlib with_atf with_tuning enable_querytrace with_dlopen with_dlz_postgres with_dlz_mysql with_dlz_bdb with_dlz_filesystem with_dlz_ldap with_dlz_odbc with_dlz_stub with_make_clean enable_full_report ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures BIND 9.10 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/bind] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF NOTE: If PREFIX is not set, then the default values for --sysconfdir and --localstatedir are /etc and /var, respectively. System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of BIND 9.10:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --enable-libbind deprecated --enable-warn-shadow turn on -Wshadow when compiling --enable-warn-error turn on -Werror when compiling --enable-developer enable developer build settings --enable-seccomp enable support for libseccomp system call filtering [default=no] --enable-kqueue use BSD kqueue when available [default=yes] --enable-epoll use Linux epoll when available [default=auto] --enable-devpoll use /dev/poll when available [default=yes] --enable-threads enable multithreading --enable-native-pkcs11 use native PKCS11 for all crypto [default=no] --enable-openssl-hash use OpenSSL for hash functions [default=no] --enable-sit enable source identity token [default=no] --enable-openssl-version-check check OpenSSL version [default=yes] --enable-largefile 64-bit file support --enable-backtrace log stack backtrace on abort [default=yes] --enable-symtable use internal symbol table for backtrace [all|minimal(default)|none] --enable-ipv6 use IPv6 default=autodetect --enable-getifaddrs enable the use of getifaddrs() [yes|no]. --disable-isc-spnego use SPNEGO from GSSAPI library --disable-chroot disable chroot --disable-linux-caps disable linux capabilities --enable-atomic enable machine specific atomic operations [default=autodetect] --enable-fixed-rrset enable fixed rrset ordering [default=no] --disable-rpz-nsip disable rpz-nsip rules [default=enabled] --disable-rpz-nsdname disable rpz-nsdname rules [default=enabled] --enable-fetchlimit enable recursive fetch limits [default=no] --enable-filter-aaaa enable filtering of AAAA records [default=no] --enable-querytrace enable very verbose query trace logging [default=no] --enable-full-report report values of all configure options Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot=DIR Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-python=PATH specify path to python interpreter --with-geoip=PATH Build with GeoIP support (yes|no|path) --with-gssapi=PATH Specify path for system-supplied GSSAPI [default=yes] --with-randomdev=PATH Specify path for random device --with-locktype=ARG Specify mutex lock type (adaptive or standard) --with-libtool use GNU libtool --with-openssl=PATH Build with OpenSSL yes|no|path. (Crypto is required for DNSSEC) --with-pkcs11=PATH Build with PKCS11 support yes|no|path (PATH is for the PKCS11 provider) --with-ecdsa Crypto ECDSA --with-gost Crypto GOST yes|no|raw|asn1. --with-aes Crypto AES --with-sit-alg=ALG choose the algorithm for SIT [aes|sha1|sha256] --with-libxml2=PATH build with libxml2 library yes|no|path --with-libjson=PATH build with libjson0 library yes|no|path --with-purify=PATH use Rational purify --with-gperftools-profiler use gperftools CPU profiler --with-kame=PATH use Kame IPv6 default path /usr/local/v6 --with-readline=LIBSPEC specify readline library default auto --with-docbook-xsl=PATH specify path for Docbook-XSL stylesheets --with-idn=MPREFIX enable IDN support using idnkit default PREFIX --with-libiconv=IPREFIX GNU libiconv are in IPREFIX default PREFIX --with-iconv=LIBSPEC specify iconv library default -liconv --with-idnlib=ARG specify libidnkit --with-atf=ARG support Automated Test Framework --with-tuning=ARG Specify server tuning (large or default) --with-dlopen=ARG support dynamically loadable DLZ drivers --with-dlz-postgres=PATH Build with Postgres DLZ driver yes|no|path. (Required to use Postgres with DLZ) --with-dlz-mysql=PATH Build with MySQL DLZ driver yes|no|path. (Required to use MySQL with DLZ) --with-dlz-bdb=PATH Build with Berkeley DB DLZ driver yes|no|path. (Required to use Berkeley DB with DLZ) --with-dlz-filesystem=PATH Build with filesystem DLZ driver yes|no. (Required to use file system driver with DLZ) --with-dlz-ldap=PATH Build with LDAP DLZ driver yes|no|path. (Required to use LDAP with DLZ) --with-dlz-odbc=PATH Build with ODBC DLZ driver yes|no|path. (Required to use ODBC with DLZ) --with-dlz-stub=PATH Build with stub DLZ driver yes|no. (Required to use stub driver with DLZ) --with-make-clean run "make clean" at end of configure [yes|no] Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Professional support for BIND is provided by Internet Systems Consortium, Inc. Information about paid support and training options is available at https://www.isc.org/support. Help can also often be found on the BIND Users mailing list (https://lists.isc.org/mailman/listinfo/bind-users) or in the #bind channel of the Freenode IRC service. Report bugs to . BIND home page: . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF BIND configure 9.10 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* 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 $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## --------------------------------- ## ## Report this to bind9-bugs@isc.org ## ## --------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # 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 #include 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 config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by BIND $as_me 9.10, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi # # GNU libtool support # case $build_os in sunos*) # Just set the maximum command line length for sunos as it otherwise # takes a exceptionally long time to work it out. Required for libtool. lt_cv_sys_max_cmd_len=4096; ;; esac case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.2' macro_revision='1.3337' ltmain="$ac_aux_dir/ltmain.sh" # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case "$ECHO" in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $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 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n $lt_cv_sys_max_cmd_len ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 $as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 $as_echo "$xsi_shell" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 $as_echo_n "checking whether the shell understands \"+=\"... " >&6; } lt_shell_append=no ( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 $as_echo "$lt_shell_append" >&6; } if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test "$GCC" != yes; then reload_cmds=false fi ;; darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # `unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # which responds to the $file_magic_cmd with a given extended regex. # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 $as_echo "${with_sysroot}" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[012]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done # Set options enable_dlopen=no enable_win32_dll=no # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac else enable_shared=yes fi # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac else enable_static=yes fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac else pic_mode=default fi test -z "$pic_mode" && pic_mode=default # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac else enable_fast_install=yes fi # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/${ac_tool_prefix}file; then lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/file; then lt_cv_path_MAGIC_CMD="$ac_dir/file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC="$CC" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test "$GCC" = yes; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test x"$lt_cv_prog_compiler_pic_works" = xyes; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test x"$lt_cv_prog_compiler_static_works" = xyes; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='${wl}--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' link_all_deplibs=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' ${wl}-bernotok' allow_undefined_flag=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test x"$lt_cv_prog_compiler__b" = xyes; then archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test "$lt_cv_irix_exported_symbol" = yes; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-R$libdir' ;; *) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='${wl}-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='${wl}-z,text' allow_undefined_flag='${wl}-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='${wl}-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test "$ld_shlibs" = no && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([A-Za-z]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && test "$hardcode_minus_L" != no; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test "$hardcode_action" = relink || test "$inherit_rpath" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $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 dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=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_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen="shl_load" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $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 shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=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_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen="dlopen" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $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 dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=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_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $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 dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=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_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $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 dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=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_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi fi fi fi fi fi ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report which library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC="$lt_save_CC" ac_config_commands="$ac_config_commands libtool" # Only expand once: # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # Warn if the user specified libbind, which is now deprecated # Check whether --enable-libbind was given. if test "${enable_libbind+set}" = set; then : enableval=$enable_libbind; fi case "$enable_libbind" in yes) as_fn_error $? "'libbind' is no longer part of the BIND 9 distribution. It is available from http://www.isc.org as a separate download." "$LINENO" 5 ;; no|'') ;; esac # Check whether --enable-warn_shadow was given. if test "${enable_warn_shadow+set}" = set; then : enableval=$enable_warn_shadow; fi # Check whether --enable-warn_error was given. if test "${enable_warn_error+set}" = set; then : enableval=$enable_warn_error; fi # Check whether --enable-developer was given. if test "${enable_developer+set}" = set; then : enableval=$enable_developer; fi case "$enable_developer" in yes) STD_CDEFINES="$STD_CDEFINES -DISC_LIST_CHECKINIT=1" test "${enable_fixed_rrset+set}" = set || enable_fixed_rrset=yes test "${enable_querytrace+set}" = set || enable_querytrace=yes test "${with_atf+set}" = set || with_atf=yes test "${enable_filter_aaaa+set}" = set || enable_filter_aaaa=yes test "${with_dlz_filesystem+set}" = set || with_dlz_filesystem=yes test "${enable_symtable+set}" = set || enable_symtable=all test "${enable_sit+set}" = set || enable_sit=yes test "${enable_fetchlimit+set}" = set || enable_fetchlimit=yes test "${enable_warn_error+set}" = set || enable_warn_error=yes test "${enable_warn_shadow+set}" = set || enable_warn_shadow=yes ;; esac #libseccomp sandboxing # Check whether --enable-seccomp was given. if test "${enable_seccomp+set}" = set; then : enableval=$enable_seccomp; fi case "$enable_seccomp" in yes) case $host_os in linux*) ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: seccomp is not supported on non-linux platforms; disabling it" >&5 $as_echo "$as_me: WARNING: seccomp is not supported on non-linux platforms; disabling it" >&2;} enable_seccomp=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing seccomp_init" >&5 $as_echo_n "checking for library containing seccomp_init... " >&6; } if ${ac_cv_search_seccomp_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$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 seccomp_init (); int main () { return seccomp_init (); ; return 0; } _ACEOF for ac_lib in '' seccomp; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_seccomp_init=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_seccomp_init+:} false; then : break fi done if ${ac_cv_search_seccomp_init+:} false; then : else ac_cv_search_seccomp_init=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_seccomp_init" >&5 $as_echo "$ac_cv_search_seccomp_init" >&6; } ac_res=$ac_cv_search_seccomp_init if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi if test "$ac_cv_search_seccomp_init" = "-lseccomp" ; then if test "$cross_compiling" = 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 $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include #include int main(void) { int ret; ret = prctl(PR_GET_SECCOMP, 0, 0, 0, 0); if (ret < 0) { switch (errno) { case ENOSYS: return 1; case EINVAL: return 1; default: return 1; } } ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0); if (ret < 0) { switch (errno) { case EINVAL: return 1; case EFAULT: return 0; default: return 1; } } return 1; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : $as_echo "#define HAVE_LIBSECCOMP 1" >>confdefs.h fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi ;; *) ;; esac # # Make very sure that these are the first files processed by # config.status, since we use the processed output as the input for # AC_SUBST_FILE() substitutions in other files. # ac_config_files="$ac_config_files make/rules make/includes" # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_AR+:} false; then : $as_echo_n "(cached) " >&6 else case $AR in [\\/]* | ?:[\\/]*) ac_cv_path_AR="$AR" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi AR=$ac_cv_path_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ARFLAGS="cruv" # The POSIX ln(1) program. Non-POSIX systems may substitute # "copy" or something. LN=ln case "$AR" in "") as_fn_error $? " ar program not found. Please fix your PATH to include the directory in which ar resides, or set AR in the environment with the full path to ar. " "$LINENO" 5 ;; esac # # Etags. # for ac_prog in etags emacs-etags do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ETAGS+:} false; then : $as_echo_n "(cached) " >&6 else case $ETAGS in [\\/]* | ?:[\\/]*) ac_cv_path_ETAGS="$ETAGS" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ETAGS="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ETAGS=$ac_cv_path_ETAGS if test -n "$ETAGS"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ETAGS" >&5 $as_echo "$ETAGS" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ETAGS" && break done # # Some systems, e.g. RH7, have the Exuberant Ctags etags instead of # GNU emacs etags, and it requires the -L flag. # if test "X$ETAGS" != "X"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Exuberant Ctags etags" >&5 $as_echo_n "checking for Exuberant Ctags etags... " >&6; } if $ETAGS --version 2>&1 | grep 'Exuberant Ctags' >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ETAGS="$ETAGS -L" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi # # Perl is optional; it is used only by some of the system test scripts. # Note: the backtrace feature (see below) uses perl to build the symbol table, # but it still compiles without perl, in which case an empty table will be used. # for ac_prog in perl5 perl do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PERL+:} false; then : $as_echo_n "(cached) " >&6 else case $PERL in [\\/]* | ?:[\\/]*) ac_cv_path_PERL="$PERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PERL=$ac_cv_path_PERL if test -n "$PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 $as_echo "$PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$PERL" && break done # # Python is also optional; it is used by the tools in bin/python. # If python is unavailable, we simply don't build those. # # Check whether --with-python was given. if test "${with_python+set}" = set; then : withval=$with_python; use_python="$withval" else use_python="unspec" fi python="python python3 python3.4 python3.3 python3.2 python3.1 python3.0 python2 python2.7 python2.6 python2.5 python2.4" testscript='try: import argparse except: exit(1)' case "$use_python" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for python support" >&5 $as_echo_n "checking for python support... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 $as_echo "disabled" >&6; } ;; unspec|yes|*) case "$use_python" in unspec|yes|'') for p in $python do for ac_prog in $p do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PYTHON+:} false; then : $as_echo_n "(cached) " >&6 else case $PYTHON in [\\/]* | ?:[\\/]*) ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PYTHON=$ac_cv_path_PYTHON if test -n "$PYTHON"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 $as_echo "$PYTHON" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$PYTHON" && break done if test "X$PYTHON" = "X"; then continue; fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking python module 'argparse'" >&5 $as_echo_n "checking python module 'argparse'... " >&6; } if ${PYTHON:-false} -c "$testscript"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: found, using $PYTHON" >&5 $as_echo "found, using $PYTHON" >&6; } break fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 $as_echo "not found" >&6; } unset ac_cv_path_PYTHON unset PYTHON done if test "X$PYTHON" = "X" then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for python support" >&5 $as_echo_n "checking for python support... " >&6; } case "$use_python" in unspec) { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 $as_echo "disabled" >&6; } ;; yes) as_fn_error $? "missing python" "$LINENO" 5 ;; esac fi ;; *) case "$use_python" in /*) PYTHON="$use_python" ;; *) for ac_prog in $use_python do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PYTHON+:} false; then : $as_echo_n "(cached) " >&6 else case $PYTHON in [\\/]* | ?:[\\/]*) ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PYTHON=$ac_cv_path_PYTHON if test -n "$PYTHON"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 $as_echo "$PYTHON" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$PYTHON" && break done ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking python module 'argparse'" >&5 $as_echo_n "checking python module 'argparse'... " >&6; } if ${PYTHON:-false} -c "$testscript"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: found, using $PYTHON" >&5 $as_echo "found, using $PYTHON" >&6; } break else as_fn_error $? "not found" "$LINENO" 5 fi ;; esac ;; esac PYTHON_TOOLS='' CHECKDS='' COVERAGE='' if test "X$PYTHON" != "X"; then PYTHON_TOOLS=python CHECKDS=checkds COVERAGE=coverage fi # # Special processing of paths depending on whether --prefix, # --sysconfdir or --localstatedir arguments were given. What's # desired is some compatibility with the way previous versions # of BIND built; they defaulted to /usr/local for most parts of # the installation, but named.boot/named.conf was in /etc # and named.pid was in /var/run. # # So ... if none of --prefix, --sysconfdir or --localstatedir are # specified, set things up that way. If --prefix is given, use # it for sysconfdir and localstatedir the way configure normally # would. To change the prefix for everything but leave named.conf # in /etc or named.pid in /var/run, then do this the usual configure way: # ./configure --prefix=/somewhere --sysconfdir=/etc # ./configure --prefix=/somewhere --localstatedir=/var # # To put named.conf and named.pid in /usr/local with everything else, # set the prefix explicitly to /usr/local even though that's the default: # ./configure --prefix=/usr/local # case "$prefix" in NONE) case "$sysconfdir" in '${prefix}/etc') sysconfdir=/etc ;; esac case "$localstatedir" in '${prefix}/var') localstatedir=/var ;; esac ;; esac # # Make sure INSTALL uses an absolute path, else it will be wrong in all # Makefiles, since they use make/rules.in and INSTALL will be adjusted by # configure based on the location of the file where it is substituted. # Since in BIND9 INSTALL is only substituted into make/rules.in, an immediate # subdirectory of install-sh, This relative path will be wrong for all # directories more than one level down from install-sh. # case "$INSTALL" in /*) ;; *) # # Not all systems have dirname. # ac_dir="`echo $INSTALL | sed 's%/[^/]*$%%'`" ac_prog="`echo $INSTALL | sed 's%.*/%%'`" test "$ac_dir" = "$ac_prog" && ac_dir=. test -d "$ac_dir" && ac_dir="`(cd \"$ac_dir\" && pwd)`" INSTALL="$ac_dir/$ac_prog" ;; esac # # On these hosts, we really want to use cc, not gcc, even if it is # found. The gcc that these systems have will not correctly handle # pthreads. # # However, if the user sets $CC to be something, let that override # our change. # if test "X$CC" = "X" ; then case "$host" in *-dec-osf*) CC="cc" ;; *-solaris*) # Use Sun's cc if it is available, but watch # out for /usr/ucb/cc; it will never be the right # compiler to use. # # If setting CC here fails, the AC_PROG_CC done # below might still find gcc. IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. case "$ac_dir" in /usr/ucb) # exclude ;; *) if test -f "$ac_dir/cc"; then CC="$ac_dir/cc" break fi ;; esac done IFS="$ac_save_ifs" ;; *-hp-hpux*) CC="cc" ;; mips-sgi-irix*) CC="cc" ;; esac fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # # gcc's optimiser is broken at -02 for ultrasparc # if test "$ac_env_CFLAGS_set" != set -a "X$GCC" = "Xyes"; then case "$host" in sparc-*) CCFLAGS="-g -O1" ;; esac fi # # OS dependent CC flags # case "$host" in # OSF 5.0: recv/send are only available with -D_POSIX_PII_SOCKET or # -D_XOPEN_SOURCE_EXTENDED. *-dec-osf*) STD_CDEFINES="$STD_CDEFINES -D_POSIX_PII_SOCKET" CPPFLAGS="$CPPFLAGS -D_POSIX_PII_SOCKET" ;; #HP-UX: need -D_XOPEN_SOURCE_EXTENDED and -lxnet for CMSG macros *-hp-hpux*) STD_CDEFINES="$STD_CDEFINES -D_XOPEN_SOURCE_EXTENDED" CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE_EXTENDED" LIBS="-lxnet $LIBS" ;; # Solaris: need -D_XPG4_2 and -D__EXTENSIONS__ for CMSG macros *-solaris*) STD_CDEFINES="$STD_CDEFINES -D_XPG4_2 -D__EXTENSIONS__" CPPFLAGS="$CPPFLAGS -D_XPG4_2 -D__EXTENSIONS__" ;; # POSIX doesn't include the IPv6 Advanced Socket API and glibc hides # parts of the IPv6 Advanced Socket API as a result. This is stupid # as it breaks how the two halves (Basic and Advanced) of the IPv6 # Socket API were designed to be used but we have to live with it. # Define _GNU_SOURCE to pull in the IPv6 Advanced Socket API. *-linux* | *-kfreebsd*-gnu*) STD_CDEFINES="$STD_CDEFINES -D_GNU_SOURCE" CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE" ;; # # Starting with OSX 10.7 (Lion) we must choose which IPv6 API to use. # Setting this is sufficient to select the correct behavior for BIND 9. # *-darwin*) STD_CDEFINES="$STD_CDEFINES -D__APPLE_USE_RFC_3542" CPPFLAGS="$CPPFLAGS -D__APPLE_USE_RFC_3542" ;; esac # # CCNOOPT defaults to -O0 on gcc and disables optimization when is last # if test "X$CCNOOPT" = "X" -a "X$GCC" = "Xyes"; then CCNOOPT="-O0" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi for ac_header in fcntl.h regex.h sys/time.h unistd.h sys/mman.h sys/sockio.h sys/select.h sys/param.h sys/sysctl.h net/if6.h sys/socket.h net/route.h linux/netlink.h linux/rtnetlink.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default #ifdef HAVE_SYS_PARAM_H # include #endif #ifdef HAVE_SYS_SOCKET_H # include #endif " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if ${ac_cv_c_inline+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working volatile" >&5 $as_echo_n "checking for working volatile... " >&6; } if ${ac_cv_c_volatile+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { volatile int x; int * volatile y = (int *) 0; return !x && !y; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_volatile=yes else ac_cv_c_volatile=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_volatile" >&5 $as_echo "$ac_cv_c_volatile" >&6; } if test $ac_cv_c_volatile = no; then $as_echo "#define volatile /**/" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "sysctlbyname" "ac_cv_func_sysctlbyname" if test "x$ac_cv_func_sysctlbyname" = xyes; then : $as_echo "#define HAVE_SYSCTLBYNAME 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for flexible array members" >&5 $as_echo_n "checking for flexible array members... " >&6; } if ${ac_cv_c_flexmember+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include struct s { int n; double d[]; }; int main () { int m = getchar (); struct s *p = malloc (offsetof (struct s, d) + m * sizeof (double)); p->d[0] = 0.0; return p->d != (double *) NULL; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_flexmember=yes else ac_cv_c_flexmember=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_flexmember" >&5 $as_echo "$ac_cv_c_flexmember" >&6; } if test $ac_cv_c_flexmember = yes; then $as_echo "#define FLEXIBLE_ARRAY_MEMBER /**/" >>confdefs.h else $as_echo "#define FLEXIBLE_ARRAY_MEMBER 1" >>confdefs.h fi # # Check for the existence of mmap to enable the fast format zones # for ac_func in mmap do : ac_fn_c_check_func "$LINENO" "mmap" "ac_cv_func_mmap" if test "x$ac_cv_func_mmap" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_MMAP 1 _ACEOF fi done # # Older versions of HP/UX don't define seteuid() and setegid() # for ac_func in seteuid setresuid 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" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in setegid setresgid 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" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done # BSDI doesn't have ftello fseeko for ac_func in ftello fseeko 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" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done # # UnixWare 7.1.1 with the feature supplement to the UDK compiler # is reported to not support "static inline" (RT #1212). # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for static inline breakage" >&5 $as_echo_n "checking for static inline breakage... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ static inline int foo1() { return 0; } static inline int foo2() { return foo1(); } int main () { foo1(); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define inline /**/" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default" if test "x$ac_cv_type_ssize_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define ssize_t int _ACEOF fi ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" if test "x$ac_cv_type_uintptr_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define uintptr_t unsigned long _ACEOF fi ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" " #include #include " if test "x$ac_cv_type_socklen_t" = xyes; then : $as_echo "#define ISC_SOCKADDR_LEN_T socklen_t" >>confdefs.h else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int getsockname(int, struct sockaddr *, size_t *); int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define ISC_SOCKADDR_LEN_T size_t" >>confdefs.h else $as_echo "#define ISC_SOCKADDR_LEN_T int" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 $as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } if ${ac_cv_header_time+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_time=yes else ac_cv_header_time=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 $as_echo "$ac_cv_header_time" >&6; } if test $ac_cv_header_time = yes; then $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long" >&5 $as_echo_n "checking for long long... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { long long i = 0; return (0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_PLATFORM_HAVELONGLONG="#define ISC_PLATFORM_HAVELONGLONG 1" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_PLATFORM_HAVELONGLONG="#undef ISC_PLATFORM_HAVELONGLONG" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # # check for GCC noreturn attribute # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC noreturn attribute" >&5 $as_echo_n "checking for GCC noreturn attribute... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { void foo() __attribute__((noreturn)); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_PLATFORM_NORETURN_PRE="#define ISC_PLATFORM_NORETURN_PRE" ISC_PLATFORM_NORETURN_POST="#define ISC_PLATFORM_NORETURN_POST __attribute__((noreturn))" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_PLATFORM_NORETURN_PRE="#define ISC_PLATFORM_NORETURN_PRE" ISC_PLATFORM_NORETURN_POST="#define ISC_PLATFORM_NORETURN_POST" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # # check if we have lifconf # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct lifconf" >&5 $as_echo_n "checking for struct lifconf... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct lifconf lifconf; lifconf.lifc_len = 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_PLATFORM_HAVELIFCONF="#define ISC_PLATFORM_HAVELIFCONF 1" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_PLATFORM_HAVELIFCONF="#undef ISC_PLATFORM_HAVELIFCONF" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # # check if we have kqueue # # Check whether --enable-kqueue was given. if test "${enable_kqueue+set}" = set; then : enableval=$enable_kqueue; want_kqueue="$enableval" else want_kqueue="yes" fi case $want_kqueue in yes) ac_fn_c_check_func "$LINENO" "kqueue" "ac_cv_func_kqueue" if test "x$ac_cv_func_kqueue" = xyes; then : ac_cv_have_kqueue=yes else ac_cv_have_kqueue=no fi case $ac_cv_have_kqueue in yes) ISC_PLATFORM_HAVEKQUEUE="#define ISC_PLATFORM_HAVEKQUEUE 1" ;; *) ISC_PLATFORM_HAVEKQUEUE="#undef ISC_PLATFORM_HAVEKQUEUE" ;; esac ;; *) ISC_PLATFORM_HAVEKQUEUE="#undef ISC_PLATFORM_HAVEKQUEUE" ;; esac # # check if we have epoll. Linux kernel 2.4 has epoll_create() which fails, # so we need to try running the code, not just test its existence. # # Check whether --enable-epoll was given. if test "${enable_epoll+set}" = set; then : enableval=$enable_epoll; want_epoll="$enableval" else want_epoll="auto" fi case $want_epoll in auto) { $as_echo "$as_me:${as_lineno-$LINENO}: checking epoll support" >&5 $as_echo_n "checking epoll support... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_PLATFORM_HAVEEPOLL="#undef ISC_PLATFORM_HAVEEPOLL" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { if (epoll_create(1) < 0) return (1); return (0); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_PLATFORM_HAVEEPOLL="#define ISC_PLATFORM_HAVEEPOLL 1" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_PLATFORM_HAVEEPOLL="#undef ISC_PLATFORM_HAVEEPOLL" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ;; yes) ISC_PLATFORM_HAVEEPOLL="#define ISC_PLATFORM_HAVEEPOLL 1" ;; *) ISC_PLATFORM_HAVEEPOLL="#undef ISC_PLATFORM_HAVEEPOLL" ;; esac # # check if we support /dev/poll # # Check whether --enable-devpoll was given. if test "${enable_devpoll+set}" = set; then : enableval=$enable_devpoll; want_devpoll="$enableval" else want_devpoll="yes" fi case $want_devpoll in yes) for ac_header in sys/devpoll.h devpoll.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF ISC_PLATFORM_HAVEDEVPOLL="#define ISC_PLATFORM_HAVEDEVPOLL 1" else ISC_PLATFORM_HAVEDEVPOLL="#undef ISC_PLATFORM_HAVEDEVPOLL" fi done ;; *) ISC_PLATFORM_HAVEDEVPOLL="#undef ISC_PLATFORM_HAVEDEVPOLL" ;; esac # # check if we need to #include sys/select.h explicitly # case $ac_cv_header_unistd_h in yes) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if unistd.h or sys/types.h defines fd_set" >&5 $as_echo_n "checking if unistd.h or sys/types.h defines fd_set... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Ultrix */ #include int main () { fd_set read_set; return (0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_PLATFORM_NEEDSYSSELECTH="#undef ISC_PLATFORM_NEEDSYSSELECTH" LWRES_PLATFORM_NEEDSYSSELECTH="#undef LWRES_PLATFORM_NEEDSYSSELECTH" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } case $ac_cv_header_sys_select_h in yes) ISC_PLATFORM_NEEDSYSSELECTH="#define ISC_PLATFORM_NEEDSYSSELECTH 1" LWRES_PLATFORM_NEEDSYSSELECTH="#define LWRES_PLATFORM_NEEDSYSSELECTH 1" ;; no) as_fn_error $? "need either working unistd.h or sys/select.h" "$LINENO" 5 ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ;; no) case $ac_cv_header_sys_select_h in yes) ISC_PLATFORM_NEEDSYSSELECTH="#define ISC_PLATFORM_NEEDSYSSELECTH 1" LWRES_PLATFORM_NEEDSYSSELECTH="#define LWRES_PLATFORM_NEEDSYSSELECTH 1" ;; no) as_fn_error $? "need either unistd.h or sys/select.h" "$LINENO" 5 ;; esac ;; esac # # Find the machine's endian flavor. # { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } if ${ac_cv_c_bigendian+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown # See if we're dealing with a universal compiler. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __APPLE_CC__ not a universal capable compiler #endif typedef int dummy; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # Check for potential -arch flags. It is not universal unless # there are at least two -arch flags with different values. ac_arch= ac_prev= for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do if test -n "$ac_prev"; then case $ac_word in i?86 | x86_64 | ppc | ppc64) if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then ac_arch=$ac_word else ac_cv_c_bigendian=universal break fi ;; esac ac_prev= elif test "x$ac_word" = "x-arch"; then ac_prev=arch fi done fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_c_bigendian = unknown; then # See if sys/param.h defines the BYTE_ORDER macro. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ && LITTLE_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to _BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #ifndef _BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # Compile a test program. if test "$cross_compiling" = yes; then : # Try to guess by grepping values from an object file. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; int use_ascii (int i) { return ascii_mm[i] + ascii_ii[i]; } short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; int use_ebcdic (int i) { return ebcdic_mm[i] + ebcdic_ii[i]; } extern int foo; int main () { return use_ascii (foo) == use_ebcdic (foo); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long int l; char c[sizeof (long int)]; } u; u.l = 1; return u.c[sizeof (long int) - 1] == 1; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_bigendian=no else ac_cv_c_bigendian=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 $as_echo "$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in #( yes) $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h ;; #( no) ;; #( universal) $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h ;; #( *) as_fn_error $? "unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; esac # # GeoIP support? # GEOIPLINKSRCS= GEOIPLINKOBJS= # Check whether --with-geoip was given. if test "${with_geoip+set}" = set; then : withval=$with_geoip; use_geoip="$withval" else use_geoip="no" fi if test "$use_geoip" = "yes" then for d in /usr /usr/local /opt/local do if test -f $d/include/GeoIP.h then use_geoip=$d break fi done fi case "$use_geoip" in no|'') { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GeoIP support" >&5 $as_echo_n "checking for GeoIP support... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 $as_echo "disabled" >&6; } ;; *) if test -d "$use_geoip" -o -L "$use_geoip" then CFLAGS="$CFLAGS -I$use_geoip/include" CPPFLAGS="$CPPFLAGS -I$use_geoip/include" LIBS="$LIBS -L$use_geoip/lib" case "$host_os" in netbsd*|openbsd*|solaris*) LIBS="$LIBS -Wl,-rpath=$use_geoip/lib" ;; esac elif test "$use_geoip" = "yes" then as_fn_error $? "GeoIP path not found" "$LINENO" 5 else as_fn_error $? "GeoIP path $use_geoip does not exist" "$LINENO" 5 fi ac_fn_c_check_header_mongrel "$LINENO" "GeoIP.h" "ac_cv_header_GeoIP_h" "$ac_includes_default" if test "x$ac_cv_header_GeoIP_h" = xyes; then : else as_fn_error $? "GeoIP header file not found" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing GeoIP_open" >&5 $as_echo_n "checking for library containing GeoIP_open... " >&6; } if ${ac_cv_search_GeoIP_open+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$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 GeoIP_open (); int main () { return GeoIP_open (); ; return 0; } _ACEOF for ac_lib in '' GeoIP; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_GeoIP_open=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_GeoIP_open+:} false; then : break fi done if ${ac_cv_search_GeoIP_open+:} false; then : else ac_cv_search_GeoIP_open=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_GeoIP_open" >&5 $as_echo "$ac_cv_search_GeoIP_open" >&6; } ac_res=$ac_cv_search_GeoIP_open if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" else as_fn_error $? "GeoIP library not found" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing fabsf" >&5 $as_echo_n "checking for library containing fabsf... " >&6; } if ${ac_cv_search_fabsf+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$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 fabsf (); int main () { return fabsf (); ; return 0; } _ACEOF for ac_lib in '' m; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_fabsf=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_fabsf+:} false; then : break fi done if ${ac_cv_search_fabsf+:} false; then : else ac_cv_search_fabsf=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_fabsf" >&5 $as_echo "$ac_cv_search_fabsf" >&6; } ac_res=$ac_cv_search_fabsf if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" else as_fn_error $? "Math library not found" "$LINENO" 5 fi $as_echo "#define HAVE_GEOIP 1" >>confdefs.h GEOIPLINKSRCS='${GEOIPLINKSRCS}' GEOIPLINKOBJS='${GEOIPLINKOBJS}' { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GeoIP support" >&5 $as_echo_n "checking for GeoIP support... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GeoIP Country IPv6 support" >&5 $as_echo_n "checking for GeoIP Country IPv6 support... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct in6_addr in6; GeoIP_country_name_by_ipnum_v6(NULL, in6); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_GEOIP_V6 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GeoIP City IPv6 support" >&5 $as_echo_n "checking for GeoIP City IPv6 support... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct in6_addr in6; int i = GEOIP_CITY_EDITION_REV0_V6; GeoIP_record_by_ipnum_v6(NULL, in6); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_GEOIP_CITY_V6 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GSSAPI library" >&5 $as_echo_n "checking for GSSAPI library... " >&6; } # Check whether --with-gssapi was given. if test "${with_gssapi+set}" = set; then : withval=$with_gssapi; use_gssapi="$withval" else use_gssapi="yes" fi # gssapi is just the framework, we really require kerberos v5, so # look for those headers (the gssapi headers must be there, too) # The problem with this implementation is that it doesn't allow # for the specification of gssapi and krb5 headers in different locations, # which probably ought to be fixed although fixing might raise the issue of # trying to build with incompatible versions of gssapi and krb5. if test "$use_gssapi" = "yes" then # first, deal with the obvious if test \( -f /usr/include/kerberosv5/krb5.h -o \ -f /usr/include/krb5/krb5.h -o \ -f /usr/include/krb5.h \) -a \ \( -f /usr/include/gssapi.h -o \ -f /usr/include/gssapi/gssapi.h \) then use_gssapi=/usr else krb5dirs="/usr/local /usr/local/krb5 /usr/local/kerberosv5 /usr/local/kerberos /usr/pkg /usr/krb5 /usr/kerberosv5 /usr/kerberos /usr" for d in $krb5dirs do if test -f $d/include/gssapi/gssapi_krb5.h -o \ -f $d/include/krb5.h then if test -f $d/include/gssapi/gssapi.h -o \ -f $d/include/gssapi.h then use_gssapi=$d break fi fi use_gssapi="no" done fi fi case "$use_gssapi" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 $as_echo "disabled" >&6; } USE_GSSAPI='' ;; yes) as_fn_error $? "--with-gssapi must specify a path" "$LINENO" 5 ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: looking in $use_gssapi/lib" >&5 $as_echo "looking in $use_gssapi/lib" >&6; } USE_GSSAPI='-DGSSAPI' saved_cppflags="$CPPFLAGS" CPPFLAGS="-I$use_gssapi/include $CPPFLAGS" for ac_header in gssapi.h gssapi/gssapi.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF ISC_PLATFORM_GSSAPIHEADER="#define ISC_PLATFORM_GSSAPIHEADER <$ac_header>" gssapi_hack="#include <$ac_header>" fi done if test "$ISC_PLATFORM_GSSAPIHEADER" = ""; then as_fn_error $? "gssapi.h not found" "$LINENO" 5 fi for ac_header in gssapi_krb5.h gssapi/gssapi_krb5.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF ISC_PLATFORM_GSSAPI_KRB5_HEADER="#define ISC_PLATFORM_GSSAPI_KRB5_HEADER <$ac_header>" gssapi_krb5_hack="#include <$ac_header>" fi done for ac_header in krb5.h krb5/krb5.h kerberosv5/krb5.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF ISC_PLATFORM_KRB5HEADER="#define ISC_PLATFORM_KRB5HEADER <$ac_header>" krb5_hack="#include <$ac_header>" fi done if test "$ISC_PLATFORM_KRB5HEADER" = ""; then as_fn_error $? "krb5.h not found" "$LINENO" 5 fi # # XXXDCL This probably doesn't work right on all systems. # It will need to be worked on as problems become evident. # # Essentially the problems here relate to two different # areas. The first area is building with either KTH # or MIT Kerberos, particularly when both are present on # the machine. The other is static versus dynamic linking. # # On the KTH vs MIT issue, Both have libkrb5 that can mess # up the works if one implementation ends up trying to # use the other's krb. This is unfortunately a situation # that very easily arises. # # Dynamic linking when the dependency information is built # into MIT's libgssapi_krb5 or KTH's libgssapi magically makes # all such problems go away, but when that setup is not # present, because either the dynamic libraries lack # dependencies or static linking is being done, then the # problems start to show up. saved_libs="$LIBS" for TRY_LIBS in \ "-lgssapi_krb5" \ "-lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err" \ "-lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -lresolv" \ "-lgssapi" \ "-lgssapi -lkrb5 -ldes -lcrypt -lasn1 -lroken -lcom_err" \ "-lgssapi -lkrb5 -lcrypto -lcrypt -lasn1 -lroken -lcom_err" \ "-lgssapi -lkrb5 -lgssapi_krb5 -lcrypto -lcrypt -lasn1 -lroken -lcom_err" \ "-lgssapi -lkrb5 -lhx509 -lcrypto -lcrypt -lasn1 -lroken -lcom_err" \ "-lgss -lkrb5" do # Note that this does not include $saved_libs, because # on FreeBSD machines this configure script has added # -L/usr/local/lib to LIBS, which can make the # -lgssapi_krb5 test succeed with shared libraries even # when you are trying to build with KTH in /usr/lib. if test "$use_gssapi" = "/usr" then LIBS="$TRY_LIBS" else LIBS="-L$use_gssapi/lib $TRY_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking linking as $TRY_LIBS" >&5 $as_echo_n "checking linking as $TRY_LIBS... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include $gssapi_hack $gssapi_krb5_hack $krb5_hack int main () { gss_acquire_cred(NULL, NULL, 0, NULL, 0, NULL, NULL, NULL);krb5_init_context(NULL); #if defined(HAVE_GSSAPI_KRB5_H) || defined(HAVE_GSSAPI_GSSAPI_KRB5_H) gsskrb5_register_acceptor_identity(NULL); #endif ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gssapi_linked=yes else gssapi_linked=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext case $gssapi_linked in yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; break ;; no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac done CPPFLAGS="$saved_cppflags" case $gssapi_linked in no) as_fn_error $? "could not determine proper GSSAPI linkage" "$LINENO" 5 ;; esac # # XXXDCL Major kludge. Tries to cope with KTH in /usr/lib # but MIT in /usr/local/lib and trying to build with KTH. # /usr/local/lib can end up earlier on the link lines. # Like most kludges, this one is not only inelegant it # is also likely to be the wrong thing to do at least as # many times as it is the right thing. Something better # needs to be done. # if test "$use_gssapi" = "/usr" -a \ -f /usr/local/lib/libkrb5.a; then FIX_KTH_VS_MIT=yes fi case "$FIX_KTH_VS_MIT" in yes) case "$enable_static_linking" in yes) gssapi_lib_suffix=".a" ;; *) gssapi_lib_suffix=".so" ;; esac for lib in $LIBS; do case $lib in -L*) ;; -l*) new_lib=`echo $lib | sed -e s%^-l%$use_gssapi/lib/lib% \ -e s%$%$gssapi_lib_suffix%` NEW_LIBS="$NEW_LIBS $new_lib" ;; *) as_fn_error $? "KTH vs MIT Kerberos confusion!" "$LINENO" 5 ;; esac done LIBS="$NEW_LIBS" ;; esac DST_GSSAPI_INC="-I$use_gssapi/include" DNS_GSSAPI_LIBS="$LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: result: using GSSAPI from $use_gssapi/lib and $use_gssapi/include" >&5 $as_echo "using GSSAPI from $use_gssapi/lib and $use_gssapi/include" >&6; } LIBS="$saved_libs" ;; esac DNS_CRYPTO_LIBS="$DNS_GSSAPI_LIBS $DNS_CRYPTO_LIBS" # # Applications linking with libdns also need to link with these libraries. # # # was --with-randomdev specified? # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for random device" >&5 $as_echo_n "checking for random device... " >&6; } # Check whether --with-randomdev was given. if test "${with_randomdev+set}" = set; then : withval=$with_randomdev; use_randomdev="$withval" else use_randomdev="unspec" fi case "$use_randomdev" in unspec) case "$cross_compiling" in yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unspecified" >&5 $as_echo "unspecified" >&6; } as_fn_error $? " need --with-randomdev=PATH or --with-randomdev=no" "$LINENO" 5 esac case "$host" in *-openbsd*) devrandom=/dev/arandom ;; *) devrandom=/dev/random ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $devrandom" >&5 $as_echo "$devrandom" >&6; } as_ac_File=`$as_echo "ac_cv_file_$devrandom" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $devrandom" >&5 $as_echo_n "checking for $devrandom... " >&6; } if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r "$devrandom"; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define PATH_RANDOMDEV "$devrandom" _ACEOF fi ;; yes) as_fn_error $? "--with-randomdev must specify a path" "$LINENO" 5 ;; no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 $as_echo "disabled" >&6; } ;; *) cat >>confdefs.h <<_ACEOF #define PATH_RANDOMDEV "$use_randomdev" _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: result: using \"$use_randomdev\"" >&5 $as_echo "using \"$use_randomdev\"" >&6; } ;; esac # # Only check dsa signature generation on these platforms when performing # system tests. # CHECK_DSA=0 if grep "#define PATH_RANDOMDEV " confdefs.h > /dev/null then case "$host" in *darwin*|*freebsd*) CHECK_DSA=1 ;; esac fi # # Do we have arc4random(), etc ? arc4random_addrandom() has been removed # from OpenBSD 5.5 onwards. # ac_fn_c_check_func "$LINENO" "arc4random" "ac_cv_func_arc4random" if test "x$ac_cv_func_arc4random" = xyes; then : $as_echo "#define HAVE_ARC4RANDOM 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "arc4random_addrandom" "ac_cv_func_arc4random_addrandom" if test "x$ac_cv_func_arc4random_addrandom" = xyes; then : $as_echo "#define HAVE_ARC4RANDOM_ADDRANDOM 1" >>confdefs.h fi # # Begin pthreads checking. # # First, decide whether to use multithreading or not. # # Enable multithreading by default on systems where it is known # to work well, and where debugging of multithreaded programs # is supported. # { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with thread support" >&5 $as_echo_n "checking whether to build with thread support... " >&6; } case $host in *-dec-osf*) use_threads=true ;; *-solaris2.[0-6]) # Thread signals are broken on Solaris 2.6; they are sometimes # delivered to the wrong thread. use_threads=false ;; *-solaris*) use_threads=true ;; *-ibm-aix*) use_threads=true ;; *-hp-hpux10*) use_threads=false ;; *-hp-hpux11*) use_threads=true ;; *-sgi-irix*) use_threads=true ;; *-sco-sysv*uw*|*-*-sysv*UnixWare*) # UnixWare use_threads=false ;; *-*-sysv*OpenUNIX*) # UnixWare use_threads=true ;; *-netbsd[1234].*) # NetBSD earlier than NetBSD 5.0 has poor pthreads. # Don't use it by default. use_threads=false ;; *-netbsd*) use_threads=true ;; *-openbsd*) # OpenBSD users have reported that named dumps core on # startup when built with threads. use_threads=false ;; *-freebsd[1234567].*) # Threads are broken at least up to FreeBSD 4.11. # FreeBSD 5, 6 and 7 we have never officially supported threads # on. YMMV use_threads=false ;; *-freebsd*) use_threads=true ;; *-bsdi[234]*) # Thread signals do not work reliably on some versions of BSD/OS. use_threads=false ;; *-bsdi5*) use_threads=true ;; *-linux*) use_threads=true ;; *-darwin[123456789].*) use_threads=false ;; *-darwin*.*) use_threads=true ;; *) use_threads=true ;; esac # Check whether --enable-threads was given. if test "${enable_threads+set}" = set; then : enableval=$enable_threads; fi case "$enable_threads" in yes) use_threads=true ;; no) use_threads=false ;; '') # Use system-dependent default ;; *) as_fn_error $? "--enable-threads takes yes or no" "$LINENO" 5 ;; esac if $use_threads then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if $use_threads then # # Search for / configure pthreads in a system-dependent fashion. # case "$host" in *-freebsd*) # We don't want to set -lpthread as that break # the ability to choose threads library at final # link time and is not valid for all architectures. PTHREAD= if test "X$GCC" = "Xyes"; then saved_cc="$CC" CC="$CC -pthread" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc -pthread support" >&5 $as_echo_n "checking for gcc -pthread support... " >&6; }; cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { printf("%x\n", pthread_create); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : PTHREAD="yes" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CC="$saved_cc" fi if test "X$PTHREAD" != "Xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 $as_echo_n "checking for pthread_create in -lpthread... " >&6; } if ${ac_cv_lib_pthread_pthread_create+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $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 pthread_create (); int main () { return pthread_create (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthread_pthread_create=yes else ac_cv_lib_pthread_pthread_create=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_pthread_pthread_create" >&5 $as_echo "$ac_cv_lib_pthread_pthread_create" >&6; } if test "x$ac_cv_lib_pthread_pthread_create" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPTHREAD 1 _ACEOF LIBS="-lpthread $LIBS" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for thread_create in -lthr" >&5 $as_echo_n "checking for thread_create in -lthr... " >&6; } if ${ac_cv_lib_thr_thread_create+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lthr $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 thread_create (); int main () { return thread_create (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_thr_thread_create=yes else ac_cv_lib_thr_thread_create=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_thr_thread_create" >&5 $as_echo "$ac_cv_lib_thr_thread_create" >&6; } if test "x$ac_cv_lib_thr_thread_create" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBTHR 1 _ACEOF LIBS="-lthr $LIBS" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lc_r" >&5 $as_echo_n "checking for pthread_create in -lc_r... " >&6; } if ${ac_cv_lib_c_r_pthread_create+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc_r $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 pthread_create (); int main () { return pthread_create (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_c_r_pthread_create=yes else ac_cv_lib_c_r_pthread_create=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_c_r_pthread_create" >&5 $as_echo "$ac_cv_lib_c_r_pthread_create" >&6; } if test "x$ac_cv_lib_c_r_pthread_create" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBC_R 1 _ACEOF LIBS="-lc_r $LIBS" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lc" >&5 $as_echo_n "checking for pthread_create in -lc... " >&6; } if ${ac_cv_lib_c_pthread_create+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc $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 pthread_create (); int main () { return pthread_create (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_c_pthread_create=yes else ac_cv_lib_c_pthread_create=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_c_pthread_create" >&5 $as_echo "$ac_cv_lib_c_pthread_create" >&6; } if test "x$ac_cv_lib_c_pthread_create" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBC 1 _ACEOF LIBS="-lc $LIBS" else as_fn_error $? "\"could not find thread libraries\"" "$LINENO" 5 fi fi fi fi fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 $as_echo_n "checking for pthread_create in -lpthread... " >&6; } if ${ac_cv_lib_pthread_pthread_create+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $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 pthread_create (); int main () { return pthread_create (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthread_pthread_create=yes else ac_cv_lib_pthread_pthread_create=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_pthread_pthread_create" >&5 $as_echo "$ac_cv_lib_pthread_pthread_create" >&6; } if test "x$ac_cv_lib_pthread_pthread_create" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPTHREAD 1 _ACEOF LIBS="-lpthread $LIBS" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __pthread_create in -lpthread" >&5 $as_echo_n "checking for __pthread_create in -lpthread... " >&6; } if ${ac_cv_lib_pthread___pthread_create+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $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 __pthread_create (); int main () { return __pthread_create (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthread___pthread_create=yes else ac_cv_lib_pthread___pthread_create=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_pthread___pthread_create" >&5 $as_echo "$ac_cv_lib_pthread___pthread_create" >&6; } if test "x$ac_cv_lib_pthread___pthread_create" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPTHREAD 1 _ACEOF LIBS="-lpthread $LIBS" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __pthread_create_system in -lpthread" >&5 $as_echo_n "checking for __pthread_create_system in -lpthread... " >&6; } if ${ac_cv_lib_pthread___pthread_create_system+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $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 __pthread_create_system (); int main () { return __pthread_create_system (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthread___pthread_create_system=yes else ac_cv_lib_pthread___pthread_create_system=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_pthread___pthread_create_system" >&5 $as_echo "$ac_cv_lib_pthread___pthread_create_system" >&6; } if test "x$ac_cv_lib_pthread___pthread_create_system" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPTHREAD 1 _ACEOF LIBS="-lpthread $LIBS" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lc_r" >&5 $as_echo_n "checking for pthread_create in -lc_r... " >&6; } if ${ac_cv_lib_c_r_pthread_create+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc_r $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 pthread_create (); int main () { return pthread_create (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_c_r_pthread_create=yes else ac_cv_lib_c_r_pthread_create=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_c_r_pthread_create" >&5 $as_echo "$ac_cv_lib_c_r_pthread_create" >&6; } if test "x$ac_cv_lib_c_r_pthread_create" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBC_R 1 _ACEOF LIBS="-lc_r $LIBS" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lc" >&5 $as_echo_n "checking for pthread_create in -lc... " >&6; } if ${ac_cv_lib_c_pthread_create+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc $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 pthread_create (); int main () { return pthread_create (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_c_pthread_create=yes else ac_cv_lib_c_pthread_create=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_c_pthread_create" >&5 $as_echo "$ac_cv_lib_c_pthread_create" >&6; } if test "x$ac_cv_lib_c_pthread_create" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBC 1 _ACEOF LIBS="-lc $LIBS" else as_fn_error $? "\"could not find thread libraries\"" "$LINENO" 5 fi fi fi fi fi ;; esac fi if $use_threads then if test "X$GCC" = "Xyes"; then case "$host" in *-freebsd*) CC="$CC -pthread" CCOPT="$CCOPT -pthread" CCNOOPT="$CCNOOPT -pthread" STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE" ;; *-openbsd*) CC="$CC -pthread" CCOPT="$CCOPT -pthread" CCNOOPT="$CCNOOPT -pthread" ;; *-solaris*) LIBS="$LIBS -lthread" ;; *-ibm-aix*) STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE" ;; esac else case $host in *-dec-osf*) CC="$CC -pthread" CCOPT="$CCOPT -pthread" CCNOOPT="$CCNOOPT -pthread" ;; *-solaris*) CC="$CC -mt" CCOPT="$CCOPT -mt" CCNOOPT="$CCNOOPT -mt" ;; *-ibm-aix*) STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE" ;; *-sco-sysv*uw*|*-*-sysv*UnixWare*) CC="$CC -Kthread" CCOPT="$CCOPT -Kthread" CCNOOPT="$CCNOOPT -Kthread" ;; *-*-sysv*OpenUNIX*) CC="$CC -Kpthread" CCOPT="$CCOPT -Kpthread" CCNOOPT="$CCNOOPT -Kpthread" ;; esac fi ALWAYS_DEFINES="-D_REENTRANT" ISC_PLATFORM_USETHREADS="#define ISC_PLATFORM_USETHREADS 1" THREADOPTOBJS='${THREADOPTOBJS}' THREADOPTSRCS='${THREADOPTSRCS}' thread_dir=pthreads # # We'd like to use sigwait() too # ac_fn_c_check_func "$LINENO" "sigwait" "ac_cv_func_sigwait" if test "x$ac_cv_func_sigwait" = xyes; then : $as_echo "#define HAVE_SIGWAIT 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sigwait in -lc" >&5 $as_echo_n "checking for sigwait in -lc... " >&6; } if ${ac_cv_lib_c_sigwait+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc $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 sigwait (); int main () { return sigwait (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_c_sigwait=yes else ac_cv_lib_c_sigwait=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_c_sigwait" >&5 $as_echo "$ac_cv_lib_c_sigwait" >&6; } if test "x$ac_cv_lib_c_sigwait" = xyes; then : $as_echo "#define HAVE_SIGWAIT 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sigwait in -lpthread" >&5 $as_echo_n "checking for sigwait in -lpthread... " >&6; } if ${ac_cv_lib_pthread_sigwait+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $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 sigwait (); int main () { return sigwait (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthread_sigwait=yes else ac_cv_lib_pthread_sigwait=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_pthread_sigwait" >&5 $as_echo "$ac_cv_lib_pthread_sigwait" >&6; } if test "x$ac_cv_lib_pthread_sigwait" = xyes; then : $as_echo "#define HAVE_SIGWAIT 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _Psigwait in -lpthread" >&5 $as_echo_n "checking for _Psigwait in -lpthread... " >&6; } if ${ac_cv_lib_pthread__Psigwait+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $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 _Psigwait (); int main () { return _Psigwait (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthread__Psigwait=yes else ac_cv_lib_pthread__Psigwait=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_pthread__Psigwait" >&5 $as_echo "$ac_cv_lib_pthread__Psigwait" >&6; } if test "x$ac_cv_lib_pthread__Psigwait" = xyes; then : $as_echo "#define HAVE_SIGWAIT 1" >>confdefs.h fi fi fi fi ac_fn_c_check_func "$LINENO" "pthread_attr_getstacksize" "ac_cv_func_pthread_attr_getstacksize" if test "x$ac_cv_func_pthread_attr_getstacksize" = xyes; then : $as_echo "#define HAVE_PTHREAD_ATTR_GETSTACKSIZE 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "pthread_attr_setstacksize" "ac_cv_func_pthread_attr_setstacksize" if test "x$ac_cv_func_pthread_attr_setstacksize" = xyes; then : $as_echo "#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1" >>confdefs.h fi # Check whether --with-locktype was given. if test "${with_locktype+set}" = set; then : withval=$with_locktype; locktype="$withval" else locktype="adaptive" fi case "$locktype" in adaptive) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_MUTEX_ADAPTIVE_NP" >&5 $as_echo_n "checking for PTHREAD_MUTEX_ADAPTIVE_NP... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _GNU_SOURCE #include int main () { return (PTHREAD_MUTEX_ADAPTIVE_NP); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: using adaptive lock type" >&5 $as_echo "using adaptive lock type" >&6; } $as_echo "#define HAVE_PTHREAD_MUTEX_ADAPTIVE_NP 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: using standard lock type" >&5 $as_echo "using standard lock type" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ;; standard) { $as_echo "$as_me:${as_lineno-$LINENO}: result: using standard lock type" >&5 $as_echo "using standard lock type" >&6; } ;; *) as_fn_error $? "You must specify \"adaptive\" or \"standard\" for --with-locktype." "$LINENO" 5 ;; esac for ac_header in sched.h do : ac_fn_c_check_header_mongrel "$LINENO" "sched.h" "ac_cv_header_sched_h" "$ac_includes_default" if test "x$ac_cv_header_sched_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SCHED_H 1 _ACEOF fi done case "$host" in *solaris-*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sched_yield in -lrt" >&5 $as_echo_n "checking for sched_yield in -lrt... " >&6; } if ${ac_cv_lib_rt_sched_yield+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lrt $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 sched_yield (); int main () { return sched_yield (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_rt_sched_yield=yes else ac_cv_lib_rt_sched_yield=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_rt_sched_yield" >&5 $as_echo "$ac_cv_lib_rt_sched_yield" >&6; } if test "x$ac_cv_lib_rt_sched_yield" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBRT 1 _ACEOF LIBS="-lrt $LIBS" fi ;; esac for ac_func in sched_yield pthread_yield pthread_yield_np 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" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done # # Additional OS-specific issues related to pthreads and sigwait. # case "$host" in # # One more place to look for sigwait. # *-freebsd*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sigwait in -lc_r" >&5 $as_echo_n "checking for sigwait in -lc_r... " >&6; } if ${ac_cv_lib_c_r_sigwait+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc_r $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 sigwait (); int main () { return sigwait (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_c_r_sigwait=yes else ac_cv_lib_c_r_sigwait=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_c_r_sigwait" >&5 $as_echo "$ac_cv_lib_c_r_sigwait" >&6; } if test "x$ac_cv_lib_c_r_sigwait" = xyes; then : $as_echo "#define HAVE_SIGWAIT 1" >>confdefs.h fi case $host in *-freebsd5.[012]|*-freebsd5.[012].*);; *-freebsd5.[3456789]|*-freebsd5.[3456789].*) $as_echo "#define NEED_PTHREAD_SCOPE_SYSTEM 1" >>confdefs.h ;; *-freebsd6.*) $as_echo "#define NEED_PTHREAD_SCOPE_SYSTEM 1" >>confdefs.h ;; esac ;; # # BSDI 3.0 through 4.0.1 needs pthread_init() to be # called before certain pthreads calls. This is deprecated # in BSD/OS 4.1. # *-bsdi3.*|*-bsdi4.0*) $as_echo "#define NEED_PTHREAD_INIT 1" >>confdefs.h ;; # # LinuxThreads requires some changes to the way we # deal with signals. # *-linux*) $as_echo "#define HAVE_LINUXTHREADS 1" >>confdefs.h ;; # # Ensure the right sigwait() semantics on Solaris and make # sure we call pthread_setconcurrency. # *-solaris*) $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h ac_fn_c_check_func "$LINENO" "pthread_setconcurrency" "ac_cv_func_pthread_setconcurrency" if test "x$ac_cv_func_pthread_setconcurrency" = xyes; then : $as_echo "#define CALL_PTHREAD_SETCONCURRENCY 1" >>confdefs.h fi ;; # # UnixWare does things its own way. # *-sco-sysv*uw*|*-*-sysv*UnixWare*|*-*-sysv*OpenUNIX*) $as_echo "#define HAVE_UNIXWARE_SIGWAIT 1" >>confdefs.h ;; esac # # Look for sysconf to allow detection of the number of processors. # ac_fn_c_check_func "$LINENO" "sysconf" "ac_cv_func_sysconf" if test "x$ac_cv_func_sysconf" = xyes; then : $as_echo "#define HAVE_SYSCONF 1" >>confdefs.h fi else ISC_PLATFORM_USETHREADS="#undef ISC_PLATFORM_USETHREADS" thread_dir=nothreads THREADOPTOBJS="" THREADOPTSRCS="" ALWAYS_DEFINES="" fi ISC_THREAD_DIR=$thread_dir { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libtool" >&5 $as_echo_n "checking for libtool... " >&6; } # Check whether --with-libtool was given. if test "${with_libtool+set}" = set; then : withval=$with_libtool; use_libtool="$withval" else use_libtool="no" fi case $use_libtool in yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } O=lo A=la LIBTOOL_MKDEP_SED='s;\.o;\.lo;' LIBTOOL_MODE_COMPILE='--mode=compile --tag=CC' LIBTOOL_MODE_INSTALL='--mode=install --tag=CC' LIBTOOL_MODE_LINK='--mode=link --tag=CC' INSTALL_LIBRARY='${INSTALL_PROGRAM}' case "$host" in *) LIBTOOL_ALLOW_UNDEFINED= ;; esac case "$host" in *-ibm-aix*) LIBTOOL_IN_MAIN="-Wl,-bI:T_testlist.imp" ;; *) LIBTOOL_IN_MAIN= ;; esac; ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } O=o A=a LIBTOOL= LIBTOOL_MKDEP_SED= LIBTOOL_MODE_COMPILE= LIBTOOL_MODE_INSTALL= LIBTOOL_MODE_LINK= LIBTOOL_ALLOW_UNDEFINED= LIBTOOL_IN_MAIN= INSTALL_LIBRARY='${INSTALL_DATA}' ;; esac # # was --enable-native-pkcs11 specified? # (note it implies both --without-openssl and --with-pkcs11) # # Check whether --enable-native-pkcs11 was given. if test "${enable_native_pkcs11+set}" = set; then : enableval=$enable_native_pkcs11; want_native_pkcs11="$enableval" else want_native_pkcs11="no" fi # # was --with-openssl specified? # # Check whether --with-openssl was given. if test "${with_openssl+set}" = set; then : withval=$with_openssl; use_openssl="$withval" else use_openssl="auto" fi # # was --with-pkcs11 specified? # # Check whether --with-pkcs11 was given. if test "${with_pkcs11+set}" = set; then : withval=$with_pkcs11; use_pkcs11="$withval" else use_pkcs11="auto" fi # # were --with-ecdsa, --with-gost, --with-aes specified # # Check whether --with-ecdsa was given. if test "${with_ecdsa+set}" = set; then : withval=$with_ecdsa; with_ecdsa="$withval" else with_ecdsa="auto" fi # Check whether --with-gost was given. if test "${with_gost+set}" = set; then : withval=$with_gost; with_gost="$withval" else with_gost="auto" fi # Check whether --with-aes was given. if test "${with_aes+set}" = set; then : withval=$with_aes; with_aes="$withval" else with_aes="checksit" fi # # was --enable-openssl-hash specified? # # Check whether --enable-openssl-hash was given. if test "${enable_openssl_hash+set}" = set; then : enableval=$enable_openssl_hash; want_openssl_hash="$enableval" else want_openssl_hash="checksit" fi # # Enable Source Identity Token support # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Source Identity Token support" >&5 $as_echo_n "checking for Source Identity Token support... " >&6; } # Check whether --enable-sit was given. if test "${enable_sit+set}" = set; then : enableval=$enable_sit; enable_sit="$enableval" else enable_sit="no" fi HAVE_SIT= ISC_PLATFORM_USESIT="#undef ISC_PLATFORM_USESIT" case "$enable_sit" in yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_PLATFORM_USESIT="#define ISC_PLATFORM_USESIT 1" HAVE_SIT=1 ;; no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; *) as_fn_error $? "\"enable-sit requires yes or no\"" "$LINENO" 5 ;; esac # # Source Identity Token algorithm choice # # Check whether --with-sit-alg was given. if test "${with_sit_alg+set}" = set; then : withval=$with_sit_alg; with_sit_alg="$withval" else with_sit_alg="auto" fi if test "$enable_sit" = "yes" then case $with_sit_alg in *1) with_sit_alg="sha1" ;; *2*) with_sit_alg="sha256" ;; auto) if test "$with_aes" != "no" then with_aes="yes" fi ;; *) with_sit_alg="aes" if test "$with_aes" != "no" then with_aes="yes" fi ;; esac fi if test "with_aes" = "checksit" then with_aes="no" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL library" >&5 $as_echo_n "checking for OpenSSL library... " >&6; } OPENSSL_WARNING= openssldirs="/usr /usr/local /usr/local/ssl /usr/pkg /usr/sfw" if test "$use_openssl" = "auto" then if test "$want_native_pkcs11" = "yes" then use_openssl="native_pkcs11" else for d in $openssldirs do if test -f $d/include/openssl/opensslv.h then use_openssl=$d break fi done fi fi OPENSSL_ECDSA="" OPENSSL_GOST="" gosttype="raw" case "$with_gost" in raw) with_gost="yes" ;; asn1) $as_echo "#define PREFER_GOSTASN1 1" >>confdefs.h gosttype="asn1" with_gost="yes" ;; auto|yes|no) ;; *) as_fn_error $? "unknown GOST private key encoding" "$LINENO" 5 ;; esac case "$use_openssl" in native_pkcs11) { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled because of native PKCS11" >&5 $as_echo "disabled because of native PKCS11" >&6; } DST_OPENSSL_INC="" CRYPTO="-DPKCS11CRYPTO" OPENSSLGOSTLINKOBJS="" OPENSSLGOSTLINKSRS="" OPENSSLLINKOBJS="" OPENSSLLINKSRCS="" ;; no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } DST_OPENSSL_INC="" CRYPTO="" OPENSSLGOSTLINKOBJS="" OPENSSLGOSTLINKSRS="" OPENSSLLINKOBJS="" OPENSSLLINKSRCS="" ;; auto) DST_OPENSSL_INC="" CRYPTO="" OPENSSLGOSTLINKOBJS="" OPENSSLGOSTLINKSRS="" OPENSSLLINKOBJS="" OPENSSLLINKSRCS="" as_fn_error $? "OpenSSL was not found in any of $openssldirs; use --with-openssl=/path If you don't want OpenSSL, use --without-openssl" "$LINENO" 5 ;; *) if test "$want_native_pkcs11" = "yes" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5 $as_echo "" >&6; } as_fn_error $? "OpenSSL and native PKCS11 cannot be used together." "$LINENO" 5 fi if test "$use_openssl" = "yes" then # User did not specify a path - guess it for d in $openssldirs do if test -f $d/include/openssl/opensslv.h then use_openssl=$d break fi done if test "$use_openssl" = "yes" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 $as_echo "not found" >&6; } as_fn_error $? "OpenSSL was not found in any of $openssldirs; use --with-openssl=/path" "$LINENO" 5 fi elif ! test -f "$use_openssl"/include/openssl/opensslv.h then as_fn_error $? "\"$use_openssl/include/openssl/opensslv.h\" not found" "$LINENO" 5 fi CRYPTO='-DOPENSSL' if test "$use_openssl" = "/usr" then DST_OPENSSL_INC="" DST_OPENSSL_LIBS="-lcrypto" else DST_OPENSSL_INC="-I$use_openssl/include" case $host in *-solaris*) DST_OPENSSL_LIBS="-L$use_openssl/lib -R$use_openssl/lib -lcrypto" ;; *-hp-hpux*) DST_OPENSSL_LIBS="-L$use_openssl/lib -Wl,+b: -lcrypto" ;; *-apple-darwin*) # # Apple's ld seaches for serially for dynamic # then static libraries. This means you can't # use -L to override dynamic system libraries # with static ones when linking. Instead # we specify a absolute path. # if test -f "$use_openssl/lib/libcrypto.dylib" then DST_OPENSSL_LIBS="-L$use_openssl/lib -lcrypto" else DST_OPENSSL_LIBS="$use_openssl/lib/libcrypto.a" fi ;; *) DST_OPENSSL_LIBS="-L$use_openssl/lib -lcrypto" ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: using OpenSSL from $use_openssl/lib and $use_openssl/include" >&5 $as_echo "using OpenSSL from $use_openssl/lib and $use_openssl/include" >&6; } saved_cc="$CC" saved_cflags="$CFLAGS" saved_libs="$LIBS" CFLAGS="$CFLAGS $DST_OPENSSL_INC" LIBS="$LIBS $DST_OPENSSL_LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether linking with OpenSSL works" >&5 $as_echo_n "checking whether linking with OpenSSL works... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: assuming it does work on target platform" >&5 $as_echo "assuming it does work on target platform" >&6; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { ERR_clear_error(); return (0); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Could not run test program using OpenSSL from $use_openssl/lib and $use_openssl/include. Please check the argument to --with-openssl and your shared library configuration (e.g., LD_LIBRARY_PATH)." "$LINENO" 5 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether linking with OpenSSL requires -ldl" >&5 $as_echo_n "checking whether linking with OpenSSL requires -ldl... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { DSO_METHOD_dlfcn(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } else LIBS="$LIBS -ldl" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { DSO_METHOD_dlfcn(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } DST_OPENSSL_LIBS="$DST_OPENSSL_LIBS -ldl" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: unknown" >&5 $as_echo "unknown" >&6; } as_fn_error $? "OpenSSL has unsupported dynamic loading" "$LINENO" 5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # Check whether --enable-openssl-version-check was given. if test "${enable_openssl_version_check+set}" = set; then : enableval=$enable_openssl_version_check; fi case "$enable_openssl_version_check" in yes|'') { $as_echo "$as_me:${as_lineno-$LINENO}: checking OpenSSL library version" >&5 $as_echo_n "checking OpenSSL library version... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: assuming target platform has compatible version" >&5 $as_echo "assuming target platform has compatible version" >&6; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { if ((OPENSSL_VERSION_NUMBER >= 0x009070cfL && OPENSSL_VERSION_NUMBER < 0x00908000L) || (OPENSSL_VERSION_NUMBER >= 0x0090804fL && OPENSSL_VERSION_NUMBER < 0x10002000L) || OPENSSL_VERSION_NUMBER >= 0x1000205fL) return (0); printf("\n\nFound OPENSSL_VERSION_NUMBER %#010x\n", OPENSSL_VERSION_NUMBER); printf("Require OPENSSL_VERSION_NUMBER 0x009070cf or greater (0.9.7l)\n" "Require OPENSSL_VERSION_NUMBER 0x0090804f or greater (0.9.8d)\n" "Require OPENSSL_VERSION_NUMBER 0x1000000f or greater (1.0.0)\n" "Require OPENSSL_VERSION_NUMBER 0x1000100f or greater (1.0.1)\n" "Require OPENSSL_VERSION_NUMBER 0x1000205f or greater (1.0.2e)\n\n"); return (1); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: not compatible" >&5 $as_echo "not compatible" >&6; } OPENSSL_WARNING=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ;; no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: Skipped OpenSSL version check" >&5 $as_echo "Skipped OpenSSL version check" >&6; } ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL DSA support" >&5 $as_echo_n "checking for OpenSSL DSA support... " >&6; } if test -f $use_openssl/include/openssl/dsa.h then $as_echo "#define HAVE_OPENSSL_DSA 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi for ac_func in EVP_sha256 EVP_sha384 EVP_sha512 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" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL ECDSA support" >&5 $as_echo_n "checking for OpenSSL ECDSA support... " >&6; } have_ecdsa="" if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: using --with-ecdsa" >&5 $as_echo "using --with-ecdsa" >&6; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { EC_KEY *ec256, *ec384; #if !defined(HAVE_EVP_SHA256) || !defined(HAVE_EVP_SHA384) return (1); #endif ec256 = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); ec384 = EC_KEY_new_by_curve_name(NID_secp384r1); if (ec256 == NULL || ec384 == NULL) return (2); return (0); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_ecdsa="yes" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_ecdsa="no" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi case "$with_ecdsa" in yes) case "$have_ecdsa" in no) as_fn_error $? "ecdsa not supported" "$LINENO" 5 ;; *) have_ecdsa=yes ;; esac ;; no) have_ecdsa=no ;; *) case "$have_ecdsa" in yes|no) ;; *) as_fn_error $? "need --with-ecdsa=[yes or no]" "$LINENO" 5 ;; esac ;; esac case $have_ecdsa in yes) OPENSSL_ECDSA="yes" $as_echo "#define HAVE_OPENSSL_ECDSA 1" >>confdefs.h ;; *) ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL GOST support" >&5 $as_echo_n "checking for OpenSSL GOST support... " >&6; } have_gost="" case "$use_pkcs11" in auto|no) ;; *) if $use_threads; then CC="$CC -pthread" fi ;; esac if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: using --with-gost" >&5 $as_echo "using --with-gost" >&6; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { #if (OPENSSL_VERSION_NUMBER >= 0x10000000L) ENGINE *e; EC_KEY *ek; ek = NULL; OPENSSL_config(NULL); e = ENGINE_by_id("gost"); if (e == NULL) return (1); if (ENGINE_init(e) <= 0) return (1); return (0); #else return (1); #endif } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_gost="yes" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_gost="no" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi case "$with_gost" in yes) case "$have_gost" in no) as_fn_error $? "gost not supported" "$LINENO" 5 ;; *) have_gost=yes ;; esac ;; no) have_gost=no ;; *) case "$have_gost" in yes|no) ;; *) as_fn_error $? "need --with-gost=[yes, no, raw or asn1]" "$LINENO" 5 ;; esac ;; esac case $have_gost in yes) OPENSSL_GOST="yes" OPENSSLGOSTLINKOBJS='${OPENSSLGOSTLINKOBJS}' OPENSSLGOSTLINKSRCS='${OPENSSLGOSTLINKSRCS}' $as_echo "#define HAVE_OPENSSL_GOST 1" >>confdefs.h ;; *) ;; esac have_aes="no" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL AES support" >&5 $as_echo_n "checking for OpenSSL AES support... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: using --with-aes" >&5 $as_echo "using --with-aes" >&6; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { EVP_CIPHER *aes128, *aes192, *aes256; aes128 = EVP_aes_128_ecb(); aes192 = EVP_aes_192_ecb(); aes256 = EVP_aes_256_ecb(); if (aes128 == NULL || aes192 == NULL || aes256 == NULL) return (1); return (0); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_aes="evp" else ac_fn_c_check_func "$LINENO" "AES_encrypt" "ac_cv_func_AES_encrypt" if test "x$ac_cv_func_AES_encrypt" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_aes="yes" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ISC_OPENSSL_INC="" ISC_OPENSSL_LIBS="" if test "$with_aes" = "yes" then case "$have_aes" in evp) $as_echo "#define HAVE_OPENSSL_EVP_AES 1" >>confdefs.h ISC_OPENSSL_INC="$DST_OPENSSL_INC" ISC_OPENSSL_LIBS="$DST_OPENSSL_LIBS" ;; yes) $as_echo "#define HAVE_OPENSSL_AES 1" >>confdefs.h ISC_OPENSSL_INC="$DST_OPENSSL_INC" ISC_OPENSSL_LIBS="$DST_OPENSSL_LIBS" ;; *) ;; esac fi CC="$saved_cc" CFLAGS="$saved_cflags" LIBS="$saved_libs" OPENSSLLINKOBJS='${OPENSSLLINKOBJS}' OPENSSLLINKSRCS='${OPENSSLLINKSRCS}' ;; esac # # This would include the system openssl path (and linker options to use # it as needed) if it is found. # DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DST_OPENSSL_LIBS" ISC_PLATFORM_WANTAES="#undef ISC_PLATFORM_WANTAES" if test "$with_aes" = "yes" then if test "X$CRYPTO" = "X" then with_aes="no" fi fi if test "$with_aes" = "yes" then ISC_PLATFORM_WANTAES="#define ISC_PLATFORM_WANTAES 1" fi # # Choose SIT algorithm # if test "$enable_sit" = "yes" then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the Algorithm for SIT" >&5 $as_echo_n "checking for the Algorithm for SIT... " >&6; } if test "$with_sit_alg" = "auto" then if test "$with_aes" = "yes" then with_sit_alg="aes" else with_sit_alg="sha256" fi fi fi case $with_sit_alg in sha1) if test "$enable_sit" != "yes" then as_fn_error $? "\"with-sit-alg requires enable-sit\"" "$LINENO" 5; fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: sha1" >&5 $as_echo "sha1" >&6; } if test "$CRYPTO" = "-DOPENSSL" then if test "$want_openssl_hash" = "checksit" then want_openssl_hash="yes" fi fi $as_echo "#define HMAC_SHA1_SIT 1" >>confdefs.h ;; sha256) if test "$enable_sit" != "yes" then as_fn_error $? "\"with-sit-alg requires enable-sit\"" "$LINENO" 5; fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: sha256" >&5 $as_echo "sha256" >&6; } if test "$CRYPTO" = "-DOPENSSL" then if test "$want_openssl_hash" = "checksit" then want_openssl_hash="yes" fi fi $as_echo "#define HMAC_SHA256_SIT 1" >>confdefs.h ;; aes) if test "$enable_sit" != "yes" then as_fn_error $? "\"with-sit-alg requires enable-sit\"" "$LINENO" 5; fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: aes" >&5 $as_echo "aes" >&6; } if test "$with_aes" != "yes" then as_fn_error $? "\"SIT wants to use unavailable AES\"" "$LINENO" 5; fi $as_echo "#define AES_SIT 1" >>confdefs.h ;; esac if test "$want_openssl_hash" = "checksit" then want_openssl_hash="no" fi # # Use OpenSSL for hash functions # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for using OpenSSL for hash functions" >&5 $as_echo_n "checking for using OpenSSL for hash functions... " >&6; } ISC_PLATFORM_OPENSSLHASH="#undef ISC_PLATFORM_OPENSSLHASH" case $want_openssl_hash in yes) if test "$CRYPTO" != "-DOPENSSL" then as_fn_error $? "No OpenSSL for hash functions" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_PLATFORM_OPENSSLHASH="#define ISC_PLATFORM_OPENSSLHASH 1" ISC_OPENSSL_INC="$DST_OPENSSL_INC" ISC_OPENSSL_LIBS="$DST_OPENSSL_LIBS" saved_cflags="$CFLAGS" save_libs="$LIBS" CFLAGS="$CFLAGS $ISC_OPENSSL_INC" LIBS="$LIBS $ISC_OPENSSL_LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking HMAC_Init() return type" >&5 $as_echo_n "checking HMAC_Init() return type... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { HMAC_CTX ctx; int n = HMAC_Init(&ctx, NULL, 0, NULL); n += HMAC_Update(&ctx, NULL, 0); n += HMAC_Final(&ctx, NULL, NULL); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: int" >&5 $as_echo "int" >&6; } $as_echo "#define HMAC_RETURN_INT 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: void" >&5 $as_echo "void" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$saved_cflags" LIBS="$save_libs" ;; no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac # # PKCS11 (aka crypto hardware) support (--with moved just after openssl) # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PKCS11 support" >&5 $as_echo_n "checking for PKCS11 support... " >&6; } if test "$use_pkcs11" = "auto" then if test "$want_native_pkcs11" = "yes" then use_pkcs11="yes" else use_pkcs11="no" fi fi case "$use_pkcs11" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } USE_PKCS11="" PKCS11_TEST="" PKCS11_TOOLS="" ISC_PK11_C="" ISC_PK11_O="" ISC_PK11_API_C="" ISC_PK11_API_O="" ISC_PK11_RESULT_C="" ISC_PK11_RESULT_O="" ISC_ISCPK11_API_C="" ISC_ISCPK11_API_O="" ;; yes|*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } if ! $use_threads; then as_fn_error $? "PKCS11 requires thread support" "$LINENO" 5 fi if test "$CRYPTO" = "-DOPENSSL" then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL with PKCS11 support" >&5 $as_echo_n "checking for OpenSSL with PKCS11 support... " >&6; } saved_cc="$CC" saved_cflags="$CFLAGS" saved_libs="$LIBS" CC="$CC -pthread" CFLAGS="$CFLAGS $DST_OPENSSL_INC" LIBS="$LIBS $DST_OPENSSL_LIBS" if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: cross compile" >&5 $as_echo "cross compile" >&6; } PKCS11_TEST='' PKCS11_ENGINE='-DPKCS11_ENGINE=NULL' else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main() { ENGINE *e; OPENSSL_config(NULL); e = ENGINE_by_id("pkcs11"); if (e == NULL) return (1); if (ENGINE_init(e) <= 0) return (1); return (0); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } PKCS11_TEST=pkcs11ssl PKCS11_ENGINE='-DPKCS11_ENGINE="\"pkcs11\""' else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } PKCS11_TEST='' PKCS11_ENGINE='-DPKCS11_ENGINE=NULL' fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi CC="$saved_cc" CFLAGS="$saved_cflags" LIBS="$saved_libs" else PKCS11_TEST='' PKCS11_ENGINE='-DPKCS11_ENGINE=NULL' fi USE_PKCS11='-DUSE_PKCS11' PKCS11_TOOLS=pkcs11 ac_fn_c_check_func "$LINENO" "getpassphrase" "ac_cv_func_getpassphrase" if test "x$ac_cv_func_getpassphrase" = xyes; then : $as_echo "#define HAVE_GETPASSPHRASE 1" >>confdefs.h fi ISC_PK11_C="pk11.c" ISC_PK11_O="pk11.$O" ISC_PK11_API_C="pk11_api.c" ISC_PK11_API_O="pk11_api.$O" ISC_PK11_RESULT_C="pk11_result.c" ISC_PK11_RESULT_O="pk11_result.$O" ISC_ISCPK11_API_C="unix/pk11_api.c" ISC_ISCPK11_API_O="unix/pk11_api.$O" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PKCS11 tools" >&5 $as_echo_n "checking for PKCS11 tools... " >&6; } case "$use_pkcs11" in no) PKCS11_PROVIDER="undefined" { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 $as_echo "disabled" >&6; } ;; yes|'') PKCS11_PROVIDER="undefined" { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled" >&5 $as_echo "enabled" >&6; } ;; *) PKCS11_PROVIDER="$use_pkcs11" { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled, PKCS11 provider is $PKCS11_PROVIDER" >&5 $as_echo "enabled, PKCS11 provider is $PKCS11_PROVIDER" >&6; } ;; esac PKCS11_ECDSA="" PKCS11_GOST="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for native PKCS11" >&5 $as_echo_n "checking for native PKCS11... " >&6; } case "$want_native_pkcs11" in yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: using native PKCS11 crypto" >&5 $as_echo "using native PKCS11 crypto" >&6; } PKCS11LINKOBJS='${PKCS11LINKOBJS}' PKCS11LINKSRCS='${PKCS11LINKSRCS}' PKCS11_TEST=pkcs11 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PKCS11 ECDSA" >&5 $as_echo_n "checking for PKCS11 ECDSA... " >&6; } case "$with_ecdsa" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 $as_echo "disabled" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled" >&5 $as_echo "enabled" >&6; } PKCS11_ECDSA="yes" $as_echo "#define HAVE_PKCS11_ECDSA 1" >>confdefs.h ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PKCS11 GOST" >&5 $as_echo_n "checking for PKCS11 GOST... " >&6; } case "$with_gost" in yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled" >&5 $as_echo "enabled" >&6; } PKCS11_GOST="yes" $as_echo "#define HAVE_PKCS11_GOST 1" >>confdefs.h ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 $as_echo "disabled" >&6; } ;; esac ;; no|'') { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 $as_echo "disabled" >&6; } ;; esac # for PKCS11 benchmarks have_clock_gt=no ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime" if test "x$ac_cv_func_clock_gettime" = xyes; then : have_clock_gt=yes fi if test "$have_clock_gt" = "no"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5 $as_echo_n "checking for clock_gettime in -lrt... " >&6; } if ${ac_cv_lib_rt_clock_gettime+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lrt $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 clock_gettime (); int main () { return clock_gettime (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_rt_clock_gettime=yes else ac_cv_lib_rt_clock_gettime=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_rt_clock_gettime" >&5 $as_echo "$ac_cv_lib_rt_clock_gettime" >&6; } if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then : have_clock_gt=rt fi fi if test "$have_clock_gt" != "no"; then $as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h fi if test "$have_clock_gt" = "rt"; then LIBS="-lrt $LIBS" fi # # was --with-libxml2 specified? # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libxml2 library" >&5 $as_echo_n "checking for libxml2 library... " >&6; } # Check whether --with-libxml2 was given. if test "${with_libxml2+set}" = set; then : withval=$with_libxml2; use_libxml2="$withval" else use_libxml2="auto" fi case "$use_libxml2" in no) DST_LIBXML2_INC="" ;; auto|yes) case X`(xml2-config --version) 2>/dev/null` in X2.[6789].*) libxml2_libs=`xml2-config --libs` libxml2_cflags=`xml2-config --cflags` ;; *) if test "$use_libxml2" = "yes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "required libxml2 version not available" "$LINENO" 5 else libxml2_libs= libxml2_cflags= fi ;; esac ;; *) if test -f "$use_libxml2/bin/xml2-config" ; then libxml2_libs=`$use_libxml2/bin/xml2-config --libs` libxml2_cflags=`$use_libxml2/bin/xml2-config --cflags` fi ;; esac if test "X$libxml2_libs" != "X" then CFLAGS="$CFLAGS $libxml2_cflags" LIBS="$LIBS $libxml2_libs" # # Sanity check xml2-config output. # cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { return(xmlTextWriterStartElement(NULL, NULL)); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else as_fn_error $? "xml2-config returns badness" "$LINENO" 5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext $as_echo "#define HAVE_LIBXML2 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # # was --with-libjson specified? # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for json library" >&5 $as_echo_n "checking for json library... " >&6; } # Check whether --with-libjson was given. if test "${with_libjson+set}" = set; then : withval=$with_libjson; use_libjson="$withval" else use_libjson="auto" fi have_libjson="" have_libjson_c="" case "$use_libjson" in no) libjson_libs="" ;; auto|yes) for d in /usr /usr/local /opt/local do if test -f "${d}/include/json/json.h" then if test ${d} != /usr then libjson_cflags="-I ${d}/include" LIBS="$LIBS -L${d}/lib" fi have_libjson="yes" elif test -f "${d}/include/json-c/json.h" then if test ${d} != /usr then libjson_cflags="-I ${d}/include" LIBS="$LIBS -L${d}/lib" fi have_libjson="yes" have_libjson_c="yes" fi done ;; *) if test -f "${use_libjson}/include/json/json.h" then libjson_cflags="-I${use_libjson}/include" LIBS="$LIBS -L${use_libjson}/lib" have_libjson="yes" elif test -f "${use_libjson}/include/json-c/json.h" then libjson_cflags="-I${use_libjson}/include" LIBS="$LIBS -L${use_libjson}/lib" have_libjson="yes" have_libjson_c="yes" else as_fn_error $? "$use_libjson/include/json{,-c}/json.h not found." "$LINENO" 5 fi ;; esac if test "X${have_libjson}" != "X" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing json_object_new_int64" >&5 $as_echo_n "checking for library containing json_object_new_int64... " >&6; } if ${ac_cv_search_json_object_new_int64+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$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 json_object_new_int64 (); int main () { return json_object_new_int64 (); ; return 0; } _ACEOF for ac_lib in '' json json-c; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_json_object_new_int64=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_json_object_new_int64+:} false; then : break fi done if ${ac_cv_search_json_object_new_int64+:} false; then : else ac_cv_search_json_object_new_int64=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_json_object_new_int64" >&5 $as_echo "$ac_cv_search_json_object_new_int64" >&6; } ac_res=$ac_cv_search_json_object_new_int64 if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" else as_fn_error $? "found libjson include but not library." "$LINENO" 5 have_libjson="" fi elif test "X$use_libjson" = Xyes then as_fn_error $? "include/json{,-c}/json.h not found." "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "X${have_libjson}" != "X" then CFLAGS="$CFLAGS $libjson_cflags" $as_echo "#define HAVE_JSON 1" >>confdefs.h if test "X${have_libjson_c}" = Xyes then $as_echo "#define HAVE_JSON_C 1" >>confdefs.h fi fi # # In solaris 10, SMF can manage named service # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for smf_enable_instance in -lscf" >&5 $as_echo_n "checking for smf_enable_instance in -lscf... " >&6; } if ${ac_cv_lib_scf_smf_enable_instance+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lscf $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 smf_enable_instance (); int main () { return smf_enable_instance (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_scf_smf_enable_instance=yes else ac_cv_lib_scf_smf_enable_instance=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_scf_smf_enable_instance" >&5 $as_echo "$ac_cv_lib_scf_smf_enable_instance" >&6; } if test "x$ac_cv_lib_scf_smf_enable_instance" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBSCF 1 _ACEOF LIBS="-lscf $LIBS" fi # # flockfile is usually provided by pthreads, but we may want to use it # even if compiled with --disable-threads. getc_unlocked might also not # be defined. # ac_fn_c_check_func "$LINENO" "flockfile" "ac_cv_func_flockfile" if test "x$ac_cv_func_flockfile" = xyes; then : $as_echo "#define HAVE_FLOCKFILE 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "getc_unlocked" "ac_cv_func_getc_unlocked" if test "x$ac_cv_func_getc_unlocked" = xyes; then : $as_echo "#define HAVE_GETCUNLOCKED 1" >>confdefs.h fi # # Indicate what the final decision was regarding threads. # { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with threads" >&5 $as_echo_n "checking whether to build with threads... " >&6; } if $use_threads; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # # End of pthreads stuff. # # # Large File # # Check whether --enable-largefile was given. if test "${enable_largefile+set}" = set; then : enableval=$enable_largefile; want_largefile="yes" else want_largefile="no" fi case $want_largefile in yes) ALWAYS_DEFINES="$ALWAYS_DEFINES -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" ;; *) ;; esac # # Additional compiler settings. # MKDEPCC="$CC" MKDEPCFLAGS="-M" IRIX_DNSSEC_WARNINGS_HACK="" if test "X$GCC" = "Xyes"; then STD_CWARNINGS="$STD_CWARNINGS -W -Wall -Wmissing-prototypes -Wcast-qual -Wwrite-strings -Wformat -Wpointer-arith" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if \"$CC\" supports -fno-strict-aliasing" >&5 $as_echo_n "checking if \"$CC\" supports -fno-strict-aliasing... " >&6; } SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -fno-strict-aliasing" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : FNOSTRICTALIASING=yes else FNOSTRICTALIASING=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$SAVE_CFLAGS" if test "$FNOSTRICTALIASING" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } STD_CWARNINGS="$STD_CWARNINGS -fno-strict-aliasing" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # # turn off delete null pointer checks # { $as_echo "$as_me:${as_lineno-$LINENO}: checking if \"$CC\" supports -fno-delete-null-pointer-checks" >&5 $as_echo_n "checking if \"$CC\" supports -fno-delete-null-pointer-checks... " >&6; } SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -fno-delete-null-pointer-checks" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : FNODELETENULLPOINTERCHECKS=yes else FNODELETENULLPOINTERCHECKS=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$SAVE_CFLAGS" if test "$FNODELETENULLPOINTERCHECKS" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } STD_CWARNINGS="$STD_CWARNINGS -fno-delete-null-pointer-checks" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi case "$host" in *-hp-hpux*) CFLAGS="$CFLAGS -Wl,+vnocompatwarnings" BACKTRACECFLAGS="$BACKTRACECFLAGS -Wl,+vnocompatwarnings" ;; esac if test "X$enable_warn_shadow" = Xyes; then STD_CWARNINGS="$STD_CWARNINGS -Wshadow" fi if test "X$enable_warn_error" = Xyes; then STD_CWARNINGS="$STD_CWARNINGS -Werror" fi else case $host in *-dec-osf*) CC="$CC -std" CCOPT="$CCOPT -std" CCNOOPT="$CCNOOPT -std" MKDEPCC="$CC" ;; *-hp-hpux*) CC="$CC -Ae -z" # The version of the C compiler that constantly warns about # 'const' as well as alignment issues is unfortunately not # able to be discerned via the version of the operating # system, nor does cc have a version flag. case "`$CC +W 123 2>&1`" in *Unknown?option*) STD_CWARNINGS="+w1" ;; *) # Turn off the pointlessly noisy warnings. STD_CWARNINGS="+w1 +W 474,530,2193,2236" ;; esac CCOPT="$CCOPT -Ae -z" CCNOOPT="$CCNOOPT -Ae -z" CFLAGS="$CFLAGS -Wl,+vnocompatwarnings" BACKTRACECFLAGS="$BACKTRACECFLAGS -Wl,+vnocompatwarnings" MKDEPPROG='cc -Ae -E -Wp,-M >/dev/null 2>>$TMP' ;; *-sgi-irix*) STD_CWARNINGS="-fullwarn -woff 1209" # # Silence more than 250 instances of # "prototyped function redeclared without prototype" # and 11 instances of # "variable ... was set but never used" # from lib/dns/sec/openssl. # IRIX_DNSSEC_WARNINGS_HACK="-woff 1692,1552" ;; *-solaris*) MKDEPCFLAGS="-xM" ;; *-sco-sysv*uw*|*-*-sysv*UnixWare*|*-*-sysv*OpenUNIX*) # UnixWare CC="$CC -w" ;; esac fi # # NLS # ac_fn_c_check_func "$LINENO" "catgets" "ac_cv_func_catgets" if test "x$ac_cv_func_catgets" = xyes; then : $as_echo "#define HAVE_CATGETS 1" >>confdefs.h fi # # -lxnet buys us one big porting headache... standards, gotta love 'em. # # AC_CHECK_LIB(xnet, socket, , # AC_CHECK_LIB(socket, socket) # ) # # Use this for now, instead: # case "$host" in mips-sgi-irix*) ;; *-linux*) ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5 $as_echo_n "checking for socket in -lsocket... " >&6; } if ${ac_cv_lib_socket_socket+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $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 socket (); int main () { return socket (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_socket_socket=yes else ac_cv_lib_socket_socket=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_socket_socket" >&5 $as_echo "$ac_cv_lib_socket_socket" >&6; } if test "x$ac_cv_lib_socket_socket" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBSOCKET 1 _ACEOF LIBS="-lsocket $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_addr in -lnsl" >&5 $as_echo_n "checking for inet_addr in -lnsl... " >&6; } if ${ac_cv_lib_nsl_inet_addr+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $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 inet_addr (); int main () { return inet_addr (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nsl_inet_addr=yes else ac_cv_lib_nsl_inet_addr=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_nsl_inet_addr" >&5 $as_echo "$ac_cv_lib_nsl_inet_addr" >&6; } if test "x$ac_cv_lib_nsl_inet_addr" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBNSL 1 _ACEOF LIBS="-lnsl $LIBS" fi ;; esac # # Work around Solaris's select() limitations. # case "$host" in *-solaris2.[89]|*-solaris2.1?) $as_echo "#define FD_SETSIZE 65536" >>confdefs.h ;; esac # # Purify support # { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use purify" >&5 $as_echo_n "checking whether to use purify... " >&6; } # Check whether --with-purify was given. if test "${with_purify+set}" = set; then : withval=$with_purify; use_purify="$withval" else use_purify="no" fi case "$use_purify" in no) ;; yes) # Extract the first word of "purify", so it can be a program name with args. set dummy purify; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_purify_path+:} false; then : $as_echo_n "(cached) " >&6 else case $purify_path in [\\/]* | ?:[\\/]*) ac_cv_path_purify_path="$purify_path" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_purify_path="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_purify_path" && ac_cv_path_purify_path="purify" ;; esac fi purify_path=$ac_cv_path_purify_path if test -n "$purify_path"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $purify_path" >&5 $as_echo "$purify_path" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) purify_path="$use_purify" ;; esac case "$use_purify" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } PURIFY="" ;; *) if test -f $purify_path || test $purify_path = purify; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $purify_path" >&5 $as_echo "$purify_path" >&6; } PURIFYFLAGS="`echo $PURIFYOPTIONS`" PURIFY="$purify_path $PURIFYFLAGS" else as_fn_error $? "$purify_path not found. Please choose the proper path with the following command: configure --with-purify=PATH " "$LINENO" 5 fi ;; esac # # Google/Great Performance Tools CPU Profiler # { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use gperftools profiler" >&5 $as_echo_n "checking whether to use gperftools profiler... " >&6; } # Check whether --with-gperftools-profiler was given. if test "${with_gperftools_profiler+set}" = set; then : withval=$with_gperftools_profiler; use_profiler="$withval" else use_profiler="no" fi case $use_profiler in yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_GPERFTOOLS_PROFILER 1" >>confdefs.h LIBS="$LIBS -lprofiler" ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac # # enable/disable dumping stack backtrace. Also check if the system supports # glibc-compatible backtrace() function. # # Check whether --enable-backtrace was given. if test "${enable_backtrace+set}" = set; then : enableval=$enable_backtrace; want_backtrace="$enableval" else want_backtrace="yes" fi case $want_backtrace in yes) ISC_PLATFORM_USEBACKTRACE="#define ISC_PLATFORM_USEBACKTRACE 1" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { return (backtrace((void **)0, 0)); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_LIBCTRACE /**/" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ;; *) ISC_PLATFORM_USEBACKTRACE="#undef ISC_PLATFORM_USEBACKTRACE" ;; esac # Check whether --enable-symtable was given. if test "${enable_symtable+set}" = set; then : enableval=$enable_symtable; want_symtable="$enableval" else want_symtable="minimal" fi case $want_symtable in yes|all|minimal) # "yes" is a hidden value equivalent to "minimal" if test "$PERL" = "" then as_fn_error $? "Internal symbol table requires perl but no perl is found. Install perl or explicitly disable the feature by --disable-symtable." "$LINENO" 5 fi if test "$use_libtool" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Internal symbol table does not work with libtool. Disabling symbol table." >&5 $as_echo "$as_me: WARNING: Internal symbol table does not work with libtool. Disabling symbol table." >&2;} else # we generate the internal symbol table only for those systems # known to work to avoid unexpected build failure. Also, warn # about unsupported systems when the feature is enabled # manually. case $host_os in freebsd*|netbsd*|openbsd*|linux*|solaris*|darwin*) MKSYMTBL_PROGRAM="$PERL" if test $want_symtable = all; then ALWAYS_MAKE_SYMTABLE="yes" fi ;; *) if test $want_symtable = yes -o $want_symtable = all then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: this system is not known to generate internal symbol table safely; disabling it" >&5 $as_echo "$as_me: WARNING: this system is not known to generate internal symbol table safely; disabling it" >&2;} fi esac fi ;; *) ;; esac # # File name extension for static archive files, for those few places # where they are treated differently from dynamic ones. # SA=a BIND9_CO_RULE=".c.$O:" # # Here begins a very long section to determine the system's networking # capabilities. The order of the tests is significant. # # # IPv6 # # Check whether --enable-ipv6 was given. if test "${enable_ipv6+set}" = set; then : enableval=$enable_ipv6; fi case "$enable_ipv6" in yes|''|autodetect) $as_echo "#define WANT_IPV6 1" >>confdefs.h ;; no) ;; esac # # We do the IPv6 compilation checking after libtool so that we can put # the right suffix on the files. # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IPv6 structures" >&5 $as_echo_n "checking for IPv6 structures... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct sockaddr_in6 sin6; return (0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } found_ipv6=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } found_ipv6=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # # See whether IPv6 support is provided via a Kame add-on. # This is done before other IPv6 linking tests to LIBS is properly set. # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Kame IPv6 support" >&5 $as_echo_n "checking for Kame IPv6 support... " >&6; } # Check whether --with-kame was given. if test "${with_kame+set}" = set; then : withval=$with_kame; use_kame="$withval" else use_kame="no" fi case "$use_kame" in no) ;; yes) kame_path=/usr/local/v6 ;; *) kame_path="$use_kame" ;; esac case "$use_kame" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; *) if test -f $kame_path/lib/libinet6.a; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $kame_path/lib/libinet6.a" >&5 $as_echo "$kame_path/lib/libinet6.a" >&6; } LIBS="-L$kame_path/lib -linet6 $LIBS" else as_fn_error $? "$kame_path/lib/libinet6.a not found. Please choose the proper path with the following command: configure --with-kame=PATH " "$LINENO" 5 fi ;; esac # # Whether netinet6/in6.h is needed has to be defined in isc/platform.h. # Including it on Kame-using platforms is very bad, though, because # Kame uses #error against direct inclusion. So include it on only # the platform that is otherwise broken without it -- BSD/OS 4.0 through 4.1. # This is done before the in6_pktinfo check because that's what # netinet6/in6.h is needed for. # case "$host" in *-bsdi4.[01]*) ISC_PLATFORM_NEEDNETINET6IN6H="#define ISC_PLATFORM_NEEDNETINET6IN6H 1" LWRES_PLATFORM_NEEDNETINET6IN6H="#define LWRES_PLATFORM_NEEDNETINET6IN6H 1" isc_netinet6in6_hack="#include " ;; *) ISC_PLATFORM_NEEDNETINET6IN6H="#undef ISC_PLATFORM_NEEDNETINET6IN6H" LWRES_PLATFORM_NEEDNETINET6IN6H="#undef LWRES_PLATFORM_NEEDNETINET6IN6H" isc_netinet6in6_hack="" ;; esac # # This is similar to the netinet6/in6.h issue. # case "$host" in *-sco-sysv*uw*|*-*-sysv*UnixWare*|*-*-sysv*OpenUNIX*) # UnixWare ISC_PLATFORM_NEEDNETINETIN6H="#define ISC_PLATFORM_NEEDNETINETIN6H 1" LWRES_PLATFORM_NEEDNETINETIN6H="#define LWRES_PLATFORM_NEEDNETINETIN6H 1" ISC_PLATFORM_FIXIN6ISADDR="#define ISC_PLATFORM_FIXIN6ISADDR 1" isc_netinetin6_hack="#include " ;; *) ISC_PLATFORM_NEEDNETINETIN6H="#undef ISC_PLATFORM_NEEDNETINETIN6H" LWRES_PLATFORM_NEEDNETINETIN6H="#undef LWRES_PLATFORM_NEEDNETINETIN6H" ISC_PLATFORM_FIXIN6ISADDR="#undef ISC_PLATFORM_FIXIN6ISADDR" isc_netinetin6_hack="" ;; esac # # Now delve deeper into the suitability of the IPv6 support. # case "$found_ipv6" in yes) ISC_PLATFORM_HAVEIPV6="#define ISC_PLATFORM_HAVEIPV6 1" LWRES_PLATFORM_HAVEIPV6="#define LWRES_PLATFORM_HAVEIPV6 1" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for in6_addr" >&5 $as_echo_n "checking for in6_addr... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include $isc_netinetin6_hack $isc_netinet6in6_hack int main () { struct in6_addr in6; return (0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_PLATFORM_HAVEINADDR6="#undef ISC_PLATFORM_HAVEINADDR6" LWRES_PLATFORM_HAVEINADDR6="#undef LWRES_PLATFORM_HAVEINADDR6" isc_in_addr6_hack="" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_PLATFORM_HAVEINADDR6="#define ISC_PLATFORM_HAVEINADDR6 1" LWRES_PLATFORM_HAVEINADDR6="#define LWRES_PLATFORM_HAVEINADDR6 1" isc_in_addr6_hack="#define in6_addr in_addr6" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for in6addr_any" >&5 $as_echo_n "checking for in6addr_any... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include $isc_netinetin6_hack $isc_netinet6in6_hack $isc_in_addr6_hack int main () { struct in6_addr in6; in6 = in6addr_any; return (in6.s6_addr[0]); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_PLATFORM_NEEDIN6ADDRANY="#undef ISC_PLATFORM_NEEDIN6ADDRANY" LWRES_PLATFORM_NEEDIN6ADDRANY="#undef LWRES_PLATFORM_NEEDIN6ADDRANY" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_PLATFORM_NEEDIN6ADDRANY="#define ISC_PLATFORM_NEEDIN6ADDRANY 1" LWRES_PLATFORM_NEEDIN6ADDRANY="#define LWRES_PLATFORM_NEEDIN6ADDRANY 1" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for in6addr_loopback" >&5 $as_echo_n "checking for in6addr_loopback... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include $isc_netinetin6_hack $isc_netinet6in6_hack $isc_in_addr6_hack int main () { struct in6_addr in6; in6 = in6addr_loopback; return (in6.s6_addr[0]); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_PLATFORM_NEEDIN6ADDRLOOPBACK="#undef ISC_PLATFORM_NEEDIN6ADDRLOOPBACK" LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK="#undef LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_PLATFORM_NEEDIN6ADDRLOOPBACK="#define ISC_PLATFORM_NEEDIN6ADDRLOOPBACK 1" LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK="#define LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK 1" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sin6_scope_id in struct sockaddr_in6" >&5 $as_echo_n "checking for sin6_scope_id in struct sockaddr_in6... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include $isc_netinetin6_hack $isc_netinet6in6_hack int main () { struct sockaddr_in6 xyzzy; xyzzy.sin6_scope_id = 0; return (0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_PLATFORM_HAVESCOPEID="#define ISC_PLATFORM_HAVESCOPEID 1" result="#define LWRES_HAVE_SIN6_SCOPE_ID 1" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_PLATFORM_HAVESCOPEID="#undef ISC_PLATFORM_HAVESCOPEID" result="#undef LWRES_HAVE_SIN6_SCOPE_ID" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext LWRES_HAVE_SIN6_SCOPE_ID="$result" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for in6_pktinfo" >&5 $as_echo_n "checking for in6_pktinfo... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include $isc_netinetin6_hack $isc_netinet6in6_hack int main () { struct in6_pktinfo xyzzy; return (0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_PLATFORM_HAVEIN6PKTINFO="#define ISC_PLATFORM_HAVEIN6PKTINFO 1" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no -- disabling runtime ipv6 support" >&5 $as_echo "no -- disabling runtime ipv6 support" >&6; } ISC_PLATFORM_HAVEIN6PKTINFO="#undef ISC_PLATFORM_HAVEIN6PKTINFO" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ;; no) ISC_PLATFORM_HAVEIPV6="#undef ISC_PLATFORM_HAVEIPV6" LWRES_PLATFORM_HAVEIPV6="#undef LWRES_PLATFORM_HAVEIPV6" ISC_PLATFORM_NEEDIN6ADDRANY="#undef ISC_PLATFORM_NEEDIN6ADDRANY" LWRES_PLATFORM_NEEDIN6ADDRANY="#undef LWRES_PLATFORM_NEEDIN6ADDRANY" ISC_PLATFORM_HAVEIN6PKTINFO="#undef ISC_PLATFORM_HAVEIN6PKTINFO" LWRES_HAVE_SIN6_SCOPE_ID="#define LWRES_HAVE_SIN6_SCOPE_ID 1" ISC_PLATFORM_HAVESCOPEID="#define ISC_PLATFORM_HAVESCOPEID 1" ISC_IPV6_H="ipv6.h" ISC_IPV6_O="ipv6.$O" ISC_ISCIPV6_O="unix/ipv6.$O" ISC_IPV6_C="ipv6.c" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct sockaddr_storage" >&5 $as_echo_n "checking for struct sockaddr_storage... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include $isc_netinetin6_hack $isc_netinet6in6_hack int main () { struct sockaddr_storage storage; return (0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_PLATFORM_HAVESOCKADDRSTORAGE="#define ISC_PLATFORM_HAVESOCKADDRSTORAGE 1" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_PLATFORM_HAVESOCKADDRSTORAGE="#undef ISC_PLATFORM_HAVESOCKADDRSTORAGE" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct if_laddrreq" >&5 $as_echo_n "checking for struct if_laddrreq... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct if_laddrreq a; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_PLATFORM_HAVEIF_LADDRREQ="#define ISC_PLATFORM_HAVEIF_LADDRREQ 1" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_PLATFORM_HAVEIF_LADDRREQ="#undef ISC_PLATFORM_HAVEIF_LADDRREQ" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct if_laddrconf" >&5 $as_echo_n "checking for struct if_laddrconf... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct if_laddrconf a; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_PLATFORM_HAVEIF_LADDRCONF="#define ISC_PLATFORM_HAVEIF_LADDRCONF 1" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_PLATFORM_HAVEIF_LADDRCONF="#undef ISC_PLATFORM_HAVEIF_LADDRCONF" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # # Check for network functions that are often missing. We do this # after the libtool checking, so we can put the right suffix on # the files. It also needs to come after checking for a Kame add-on, # which provides some (all?) of the desired functions. # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntop with IPv6 support" >&5 $as_echo_n "checking for inet_ntop with IPv6 support... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: assuming inet_ntop not needed" >&5 $as_echo "assuming inet_ntop not needed" >&6; } ISC_PLATFORM_NEEDNTOP="#undef ISC_PLATFORM_NEEDNTOP" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include main() { char a[16],b[64]; return(inet_ntop(AF_INET6, a, b, sizeof(b)) == (char*)0);} _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_PLATFORM_NEEDNTOP="#undef ISC_PLATFORM_NEEDNTOP" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_EXTRA_OBJS="$ISC_EXTRA_OBJS inet_ntop.$O" ISC_EXTRA_SRCS="$ISC_EXTRA_SRCS inet_ntop.c" ISC_PLATFORM_NEEDNTOP="#define ISC_PLATFORM_NEEDNTOP 1" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi # On NetBSD 1.4.2 and maybe others, inet_pton() incorrectly accepts # addresses with less than four octets, like "1.2.3". Also leading # zeros should also be rejected. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working inet_pton with IPv6 support" >&5 $as_echo_n "checking for working inet_pton with IPv6 support... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: assuming inet_pton needed" >&5 $as_echo "assuming inet_pton needed" >&6; } ISC_EXTRA_OBJS="$ISC_EXTRA_OBJS inet_pton.$O" ISC_EXTRA_SRCS="$ISC_EXTRA_SRCS inet_pton.c" ISC_PLATFORM_NEEDPTON="#define ISC_PLATFORM_NEEDPTON 1" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include main() { char a[16]; return (inet_pton(AF_INET, "1.2.3", a) == 1 ? 1 : inet_pton(AF_INET, "1.2.3.04", a) == 1 ? 1 : (inet_pton(AF_INET6, "::1.2.3.4", a) != 1)); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_PLATFORM_NEEDPTON="#undef ISC_PLATFORM_NEEDPTON" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_EXTRA_OBJS="$ISC_EXTRA_OBJS inet_pton.$O" ISC_EXTRA_SRCS="$ISC_EXTRA_SRCS inet_pton.c" ISC_PLATFORM_NEEDPTON="#define ISC_PLATFORM_NEEDPTON 1" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi # # Look for a 4.4BSD-style sa_len member in struct sockaddr. # case "$host" in *-dec-osf*) # Turn on 4.4BSD style sa_len support. $as_echo "#define _SOCKADDR_LEN 1" >>confdefs.h ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sa_len in struct sockaddr" >&5 $as_echo_n "checking for sa_len in struct sockaddr... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct sockaddr sa; sa.sa_len = 0; return (0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_PLATFORM_HAVESALEN="#define ISC_PLATFORM_HAVESALEN 1" LWRES_PLATFORM_HAVESALEN="#define LWRES_PLATFORM_HAVESALEN 1" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_PLATFORM_HAVESALEN="#undef ISC_PLATFORM_HAVESALEN" LWRES_PLATFORM_HAVESALEN="#undef LWRES_PLATFORM_HAVESALEN" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # # Look for a 4.4BSD or 4.3BSD struct msghdr # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct msghdr flavor" >&5 $as_echo_n "checking for struct msghdr flavor... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct msghdr msg; msg.msg_flags = 0; return (0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: 4.4BSD" >&5 $as_echo "4.4BSD" >&6; } ISC_PLATFORM_MSGHDRFLAVOR="#define ISC_NET_BSD44MSGHDR 1" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: 4.3BSD" >&5 $as_echo "4.3BSD" >&6; } ISC_PLATFORM_MSGHDRFLAVOR="#define ISC_NET_BSD43MSGHDR 1" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # # Look for in_port_t. # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for type in_port_t" >&5 $as_echo_n "checking for type in_port_t... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { in_port_t port = 25; return (0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_PLATFORM_NEEDPORTT="#undef ISC_PLATFORM_NEEDPORTT" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_PLATFORM_NEEDPORTT="#define ISC_PLATFORM_NEEDPORTT 1" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # # Check for addrinfo # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct addrinfo" >&5 $as_echo_n "checking for struct addrinfo... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct addrinfo a; return (0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_LWRES_NEEDADDRINFO="#undef ISC_LWRES_NEEDADDRINFO" ISC_IRS_NEEDADDRINFO="#undef ISC_IRS_NEEDADDRINFO" $as_echo "#define HAVE_ADDRINFO 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_LWRES_NEEDADDRINFO="#define ISC_LWRES_NEEDADDRINFO 1" ISC_IRS_NEEDADDRINFO="#define ISC_IRS_NEEDADDRINFO 1" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # # Check for rrsetinfo # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct rrsetinfo" >&5 $as_echo_n "checking for struct rrsetinfo... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct rrsetinfo r; return (0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_LWRES_NEEDRRSETINFO="#undef ISC_LWRES_NEEDRRSETINFO" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_LWRES_NEEDRRSETINFO="#define ISC_LWRES_NEEDRRSETINFO 1" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int sethostent" >&5 $as_echo_n "checking for int sethostent... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int i = sethostent(0); return(0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_LWRES_SETHOSTENTINT="#define ISC_LWRES_SETHOSTENTINT 1" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_LWRES_SETHOSTENTINT="#undef ISC_LWRES_SETHOSTENTINT" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int endhostent" >&5 $as_echo_n "checking for int endhostent... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int i = endhostent(); return(0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_LWRES_ENDHOSTENTINT="#define ISC_LWRES_ENDHOSTENTINT 1" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_LWRES_ENDHOSTENTINT="#undef ISC_LWRES_ENDHOSTENTINT" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getnetbyaddr(in_addr_t, ...)" >&5 $as_echo_n "checking for getnetbyaddr(in_addr_t, ...)... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include struct netent *getnetbyaddr(in_addr_t, int); int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_LWRES_GETNETBYADDRINADDR="#define ISC_LWRES_GETNETBYADDRINADDR 1" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_LWRES_GETNETBYADDRINADDR="#undef ISC_LWRES_GETNETBYADDRINADDR" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int setnetent" >&5 $as_echo_n "checking for int setnetent... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int i = setnetent(0); return(0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_LWRES_SETNETENTINT="#define ISC_LWRES_SETNETENTINT 1" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_LWRES_SETNETENTINT="#undef ISC_LWRES_SETNETENTINT" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int endnetent" >&5 $as_echo_n "checking for int endnetent... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int i = endnetent(); return(0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_LWRES_ENDNETENTINT="#define ISC_LWRES_ENDNETENTINT 1" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_LWRES_ENDNETENTINT="#undef ISC_LWRES_ENDNETENTINT" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyaddr(const void *, size_t, ...)" >&5 $as_echo_n "checking for gethostbyaddr(const void *, size_t, ...)... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include struct hostent *gethostbyaddr(const void *, size_t, int); int main () { return(0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_LWRES_GETHOSTBYADDRVOID="#define ISC_LWRES_GETHOSTBYADDRVOID 1" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_LWRES_GETHOSTBYADDRVOID="#undef ISC_LWRES_GETHOSTBYADDRVOID" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for h_errno in netdb.h" >&5 $as_echo_n "checking for h_errno in netdb.h... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { h_errno = 1; return(0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_LWRES_NEEDHERRNO="#undef ISC_LWRES_NEEDHERRNO" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_LWRES_NEEDHERRNO="#define ISC_LWRES_NEEDHERRNO 1" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # # Sadly, the definitions of system-supplied getnameinfo(3) vary. Try to catch # known variations here: # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getnameinfo prototype definitions" >&5 $as_echo_n "checking for getnameinfo prototype definitions... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int getnameinfo(const struct sockaddr *, socklen_t, char *, socklen_t, char *, socklen_t, unsigned int); int main () { return (0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: socklen_t for buflen; u_int for flags" >&5 $as_echo "socklen_t for buflen; u_int for flags" >&6; } $as_echo "#define IRS_GETNAMEINFO_SOCKLEN_T socklen_t" >>confdefs.h $as_echo "#define IRS_GETNAMEINFO_BUFLEN_T socklen_t" >>confdefs.h $as_echo "#define IRS_GETNAMEINFO_FLAGS_T unsigned int" >>confdefs.h else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int getnameinfo(const struct sockaddr *, socklen_t, char *, size_t, char *, size_t, int); int main () { return (0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: size_t for buflen; int for flags" >&5 $as_echo "size_t for buflen; int for flags" >&6; } $as_echo "#define IRS_GETNAMEINFO_SOCKLEN_T socklen_t" >>confdefs.h $as_echo "#define IRS_GETNAMEINFO_BUFLEN_T size_t" >>confdefs.h $as_echo "#define IRS_GETNAMEINFO_FLAGS_T int" >>confdefs.h else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int getnameinfo(const struct sockaddr *, size_t, char *, size_t, char *, size_t, int); int main () { return (0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: size_t for buflen; int for flags" >&5 $as_echo "size_t for buflen; int for flags" >&6; } $as_echo "#define IRS_GETNAMEINFO_SOCKLEN_T size_t" >>confdefs.h $as_echo "#define IRS_GETNAMEINFO_BUFLEN_T size_t" >>confdefs.h $as_echo "#define IRS_GETNAMEINFO_FLAGS_T int" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: not match any subspecies; assume standard definition" >&5 $as_echo "not match any subspecies; assume standard definition" >&6; } $as_echo "#define IRS_GETNAMEINFO_SOCKLEN_T socklen_t" >>confdefs.h $as_echo "#define IRS_GETNAMEINFO_BUFLEN_T socklen_t" >>confdefs.h $as_echo "#define IRS_GETNAMEINFO_FLAGS_T int" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # # ...and same for gai_strerror(). # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gai_strerror prototype definitions" >&5 $as_echo_n "checking for gai_strerror prototype definitions... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include char *gai_strerror(int ecode); int main () { return (0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: returning char *" >&5 $as_echo "returning char *" >&6; } $as_echo "#define IRS_GAISTRERROR_RETURN_T char *" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: not match any subspecies; assume standard definition" >&5 $as_echo "not match any subspecies; assume standard definition" >&6; } $as_echo "#define IRS_GAISTRERROR_RETURN_T const char *" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_fn_c_check_func "$LINENO" "getipnodebyname" "ac_cv_func_getipnodebyname" if test "x$ac_cv_func_getipnodebyname" = xyes; then : ISC_LWRES_GETIPNODEPROTO="#undef ISC_LWRES_GETIPNODEPROTO" else ISC_LWRES_GETIPNODEPROTO="#define ISC_LWRES_GETIPNODEPROTO 1" fi ac_fn_c_check_func "$LINENO" "getnameinfo" "ac_cv_func_getnameinfo" if test "x$ac_cv_func_getnameinfo" = xyes; then : ISC_LWRES_GETNAMEINFOPROTO="#undef ISC_LWRES_GETNAMEINFOPROTO" else ISC_LWRES_GETNAMEINFOPROTO="#define ISC_LWRES_GETNAMEINFOPROTO 1" fi ac_fn_c_check_func "$LINENO" "getaddrinfo" "ac_cv_func_getaddrinfo" if test "x$ac_cv_func_getaddrinfo" = xyes; then : ISC_LWRES_GETADDRINFOPROTO="#undef ISC_LWRES_GETADDRINFOPROTO" $as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h else ISC_LWRES_GETADDRINFOPROTO="#define ISC_LWRES_GETADDRINFOPROTO 1" fi ac_fn_c_check_func "$LINENO" "gai_strerror" "ac_cv_func_gai_strerror" if test "x$ac_cv_func_gai_strerror" = xyes; then : $as_echo "#define HAVE_GAISTRERROR 1" >>confdefs.h fi # Check whether --enable-getifaddrs was given. if test "${enable_getifaddrs+set}" = set; then : enableval=$enable_getifaddrs; want_getifaddrs="$enableval" else want_getifaddrs="yes" fi # # This interface iteration code for getifaddrs() will fall back to using # /proc/net/if_inet6 if getifaddrs() in glibc doesn't return any IPv6 # addresses. # case $want_getifaddrs in glibc) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"--enable-getifaddrs=glibc is no longer required\"" >&5 $as_echo "$as_me: WARNING: \"--enable-getifaddrs=glibc is no longer required\"" >&2;} ac_fn_c_check_func "$LINENO" "getifaddrs" "ac_cv_func_getifaddrs" if test "x$ac_cv_func_getifaddrs" = xyes; then : $as_echo "#define HAVE_GETIFADDRS 1" >>confdefs.h fi ;; yes) ac_fn_c_check_func "$LINENO" "getifaddrs" "ac_cv_func_getifaddrs" if test "x$ac_cv_func_getifaddrs" = xyes; then : $as_echo "#define HAVE_GETIFADDRS 1" >>confdefs.h fi ;; no) ;; esac # # Look for a sysctl call to get the list of network interfaces. # case $ac_cv_header_sys_sysctl_h in yes) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for interface list sysctl" >&5 $as_echo_n "checking for interface list sysctl... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #ifdef NET_RT_IFLIST found_rt_iflist #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "found_rt_iflist" >/dev/null 2>&1; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_IFLIST_SYSCTL 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f conftest* ;; esac # # Check for some other useful functions that are not ever-present. # # We test for strsep() using AC_TRY_LINK instead of AC_CHECK_FUNC # because AIX 4.3.3 with patches for bos.adt.include to version 4.3.3.77 # reportedly defines strsep() without declaring it in when # -D_LINUX_SOURCE_COMPAT is not defined [RT #2190], and # AC_CHECK_FUNC() incorrectly succeeds because it declares # the function itself. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for correctly declared strsep()" >&5 $as_echo_n "checking for correctly declared strsep()... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char *sp; char *foo = strsep(&sp, "."); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; ISC_PLATFORM_NEEDSTRSEP="#undef ISC_PLATFORM_NEEDSTRSEP" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; ISC_PLATFORM_NEEDSTRSEP="#define ISC_PLATFORM_NEEDSTRSEP 1" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_fn_c_check_func "$LINENO" "memmove" "ac_cv_func_memmove" if test "x$ac_cv_func_memmove" = xyes; then : ISC_PLATFORM_NEEDMEMMOVE="#undef ISC_PLATFORM_NEEDMEMMOVE" else ISC_PLATFORM_NEEDMEMMOVE="#define ISC_PLATFORM_NEEDMEMMOVE 1" fi ac_fn_c_check_func "$LINENO" "strtoul" "ac_cv_func_strtoul" if test "x$ac_cv_func_strtoul" = xyes; then : ISC_PLATFORM_NEEDSTRTOUL="#undef ISC_PLATFORM_NEEDSTRTOUL" LWRES_PLATFORM_NEEDSTRTOUL="#undef LWRES_PLATFORM_NEEDSTRTOUL" GENRANDOMLIB="" else ISC_PLATFORM_NEEDSTRTOUL="#define ISC_PLATFORM_NEEDSTRTOUL 1" LWRES_PLATFORM_NEEDSTRTOUL="#define LWRES_PLATFORM_NEEDSTRTOUL 1" GENRANDOMLIB='${ISCLIBS}' fi ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy" if test "x$ac_cv_func_strlcpy" = xyes; then : ISC_PLATFORM_NEEDSTRLCPY="#undef ISC_PLATFORM_NEEDSTRLCPY" LWRES_PLATFORM_NEEDSTRLCPY="#undef LWRES_PLATFORM_NEEDSTRLCPY" else ISC_PLATFORM_NEEDSTRLCPY="#define ISC_PLATFORM_NEEDSTRLCPY 1" LWRES_PLATFORM_NEEDSTRLCPY="#define LWRES_PLATFORM_NEEDSTRLCPY 1" fi ac_fn_c_check_func "$LINENO" "strlcat" "ac_cv_func_strlcat" if test "x$ac_cv_func_strlcat" = xyes; then : ISC_PLATFORM_NEEDSTRLCAT="#undef ISC_PLATFORM_NEEDSTRLCAT" else ISC_PLATFORM_NEEDSTRLCAT="#define ISC_PLATFORM_NEEDSTRLCAT 1" fi ac_fn_c_check_func "$LINENO" "strcasestr" "ac_cv_func_strcasestr" if test "x$ac_cv_func_strcasestr" = xyes; then : ISC_PLATFORM_NEEDSTRCASESTR="#undef ISC_PLATFORM_NEEDSTRCASESTR" else ISC_PLATFORM_NEEDSTRCASESTR="#define ISC_PLATFORM_NEEDSTRCASESTR 1" fi # Check whether --with-readline was given. if test "${with_readline+set}" = set; then : withval=$with_readline; readline="$withval" else readline="auto" fi case "$readline" in no) ;; yes|auto) saved_LIBS="$LIBS" for readline in -ledit -lreadline do LIBS="$readline" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline with $readline" >&5 $as_echo "$as_me: checking for readline with $readline" >&6;} for ac_func in readline do : ac_fn_c_check_func "$LINENO" "readline" "ac_cv_func_readline" if test "x$ac_cv_func_readline" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_READLINE 1 _ACEOF fi done if test "$ac_cv_func_readline" = "yes" then READLINE_LIB="$readline" break fi if test "X$readline" = "X" then continue fi for lib in -lterminfo -ltermcap -lncurses -lcurses do { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline with $readline $lib" >&5 $as_echo "$as_me: checking for readline with $readline $lib" >&6;} unset ac_cv_func_readline LIBS="$readline $lib" for ac_func in readline do : ac_fn_c_check_func "$LINENO" "readline" "ac_cv_func_readline" if test "x$ac_cv_func_readline" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_READLINE 1 _ACEOF fi done if test "$ac_cv_func_readline" = "yes" then READLINE_LIB="$readline $lib" break fi done done LIBS="$saved_LIBS" ;; *) saved_LIBS="$LIBS" LIBS="$readline" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline with $readline" >&5 $as_echo "$as_me: checking for readline with $readline" >&6;} for ac_func in readline do : ac_fn_c_check_func "$LINENO" "readline" "ac_cv_func_readline" if test "x$ac_cv_func_readline" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_READLINE 1 _ACEOF fi done if test "$ac_cv_func_readline" = "yes" then READLINE_LIB="$readline" else for lib in -lterminfo -ltermcap -lncurses -lcurses do { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline with $readline $lib" >&5 $as_echo "$as_me: checking for readline with $readline $lib" >&6;} unset ac_cv_func_readline LIBS="$readline $lib" for ac_func in readline do : ac_fn_c_check_func "$LINENO" "readline" "ac_cv_func_readline" if test "x$ac_cv_func_readline" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_READLINE 1 _ACEOF fi done if test "$ac_cv_func_readline" = "yes" then READLINE_LIB="$readline $lib" break fi done fi LIBS="$saved_LIBS" ;; esac ISC_PRINT_OBJS= ISC_PRINT_SRCS= ISC_PLATFORM_NEEDPRINTF='#undef ISC_PLATFORM_NEEDPRINTF' ISC_PLATFORM_NEEDFPRINTF='#undef ISC_PLATFORM_NEEDFPRINTF' ISC_PLATFORM_NEEDSPRINTF='#undef ISC_PLATFORM_NEEDSPRINTF' ISC_PLATFORM_NEEDVSNPRINTF='#undef ISC_PLATFORM_NEEDVSNPRINTF' LWRES_PLATFORM_NEEDVSNPRINTF='#undef LWRES_PLATFORM_NEEDVSNPRINTF' { $as_echo "$as_me:${as_lineno-$LINENO}: checking sprintf return type" >&5 $as_echo_n "checking sprintf return type... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char buf[2]; return(*sprintf(buf,"x")); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: char *" >&5 $as_echo "char *" >&6; } ISC_PRINT_OBJS="print.$O" ISC_PRINT_SRCS="print.c" ISC_PLATFORM_NEEDSPRINTF="#define ISC_PLATFORM_NEEDSPRINTF" LWRES_PLATFORM_NEEDSPRINTF="#define LWRES_PLATFORM_NEEDSPRINTF" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: int" >&5 $as_echo "int" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf" if test "x$ac_cv_func_vsnprintf" = xyes; then : else ISC_PRINT_OBJS="print.$O" ISC_PRINT_SRCS="print.c" ISC_PLATFORM_NEEDVSNPRINTF="#define ISC_PLATFORM_NEEDVSNPRINTF 1" LWRES_PLATFORM_NEEDVSNPRINTF="#define LWRES_PLATFORM_NEEDVSNPRINTF 1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking printf for %z support" >&5 $as_echo_n "checking printf for %z support... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: assuming target platform supports %z" >&5 $as_echo "assuming target platform supports %z" >&6; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include main() { size_t j = 0; char buf[100]; buf[0] = 0; sprintf(buf, "%zu", j); exit(strcmp(buf, "0") != 0); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ISC_PRINT_OBJS="print.$O" ISC_PRINT_SRCS="print.c" ISC_PLATFORM_NEEDPRINTF='#define ISC_PLATFORM_NEEDPRINTF 1' ISC_PLATFORM_NEEDFPRINTF='#define ISC_PLATFORM_NEEDFPRINTF 1' ISC_PLATFORM_NEEDFSRINTF='#define ISC_PLATFORM_NEEDSPRINTF 1' ISC_PLATFORM_NEEDVSNPRINTF="#define ISC_PLATFORM_NEEDVSNPRINTF 1" LWRES_PLATFORM_NEEDVSNPRINTF="#define LWRES_PLATFORM_NEEDVSNPRINTF 1" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ISC_EXTRA_OBJS="$ISC_EXTRA_OBJS $ISC_PRINT_OBJS" ISC_EXTRA_SRCS="$ISC_EXTRA_SRCS $ISC_PRINT_SRCS" ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror" if test "x$ac_cv_func_strerror" = xyes; then : $as_echo "#define HAVE_STRERROR 1" >>confdefs.h fi # # Use our own SPNEGO implementation? # # Check whether --enable-isc-spnego was given. if test "${enable_isc_spnego+set}" = set; then : enableval=$enable_isc_spnego; fi if test -n "$USE_GSSAPI" then case "$enable_isc_spnego" in yes|'') USE_ISC_SPNEGO='-DUSE_ISC_SPNEGO' DST_EXTRA_OBJS="$DST_EXTRA_OBJS spnego.$O" DST_EXTRA_SRCS="$DST_EXTRA_SRCS spnego.c" { $as_echo "$as_me:${as_lineno-$LINENO}: result: using SPNEGO from lib/dns" >&5 $as_echo "using SPNEGO from lib/dns" >&6; } ;; no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: using SPNEGO from GSSAPI library" >&5 $as_echo "using SPNEGO from GSSAPI library" >&6; } ;; esac fi # Determine the printf format characters to use when printing # values of type isc_int64_t. This will normally be "ll", but where # the compiler treats "long long" as a alias for "long" and printf # doesn't know about "long long" use "l". Hopefully the sprintf # will produce a inconsistent result in the later case. If the compiler # fails due to seeing "%lld" we fall back to "l". # # Digital Unix 4.0 (gcc?) (long long) is 64 bits as is its long. It uses # %ld even for (long long)/ # # Win32 uses "%I64d", but that's defined elsewhere since we don't use # configure on Win32. # { $as_echo "$as_me:${as_lineno-$LINENO}: checking printf format modifier for 64-bit integers" >&5 $as_echo_n "checking printf format modifier for 64-bit integers... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: assuming target platform uses ll" >&5 $as_echo "assuming target platform uses ll" >&6; } ISC_PLATFORM_QUADFORMAT='#define ISC_PLATFORM_QUADFORMAT "ll"' LWRES_PLATFORM_QUADFORMAT='#define LWRES_PLATFORM_QUADFORMAT "ll"' else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include main() { long long int j = 0; char buf[100]; buf[0] = 0; sprintf(buf, "%lld", j); exit((sizeof(long long int) != sizeof(long int))? 0 : (strcmp(buf, "0") != 0)); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: ll" >&5 $as_echo "ll" >&6; } ISC_PLATFORM_QUADFORMAT='#define ISC_PLATFORM_QUADFORMAT "ll"' LWRES_PLATFORM_QUADFORMAT='#define LWRES_PLATFORM_QUADFORMAT "ll"' else { $as_echo "$as_me:${as_lineno-$LINENO}: result: l" >&5 $as_echo "l" >&6; } ISC_PLATFORM_QUADFORMAT='#define ISC_PLATFORM_QUADFORMAT "l"' LWRES_PLATFORM_QUADFORMAT='#define LWRES_PLATFORM_QUADFORMAT "l"' fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi # # Security Stuff # # Note it is very recommended to *not* disable chroot(), # this is only because chroot() was made obsolete by Posix. # Check whether --enable-chroot was given. if test "${enable_chroot+set}" = set; then : enableval=$enable_chroot; fi case "$enable_chroot" in yes|'') for ac_func in chroot do : ac_fn_c_check_func "$LINENO" "chroot" "ac_cv_func_chroot" if test "x$ac_cv_func_chroot" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_CHROOT 1 _ACEOF fi done ;; no) ;; esac # Check whether --enable-linux-caps was given. if test "${enable_linux_caps+set}" = set; then : enableval=$enable_linux_caps; fi case "$enable_linux_caps" in yes|'') for ac_header in linux/types.h do : ac_fn_c_check_header_mongrel "$LINENO" "linux/types.h" "ac_cv_header_linux_types_h" "$ac_includes_default" if test "x$ac_cv_header_linux_types_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LINUX_TYPES_H 1 _ACEOF fi done for ac_header in sys/capability.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/capability.h" "ac_cv_header_sys_capability_h" "$ac_includes_default" if test "x$ac_cv_header_sys_capability_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_CAPABILITY_H 1 _ACEOF fi done for ac_header in linux/capability.h do : ac_fn_c_check_header_compile "$LINENO" "linux/capability.h" "ac_cv_header_linux_capability_h" "#ifdef HAVE_LINUX_TYPES_H #include #endif " if test "x$ac_cv_header_linux_capability_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LINUX_CAPABILITY_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cap_set_proc in -lcap" >&5 $as_echo_n "checking for cap_set_proc in -lcap... " >&6; } if ${ac_cv_lib_cap_cap_set_proc+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcap $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 cap_set_proc (); int main () { return cap_set_proc (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_cap_cap_set_proc=yes else ac_cv_lib_cap_cap_set_proc=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_cap_cap_set_proc" >&5 $as_echo "$ac_cv_lib_cap_cap_set_proc" >&6; } if test "x$ac_cv_lib_cap_cap_set_proc" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBCAP 1 _ACEOF LIBS="-lcap $LIBS" fi ;; no) ;; esac for ac_header in sys/prctl.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/prctl.h" "ac_cv_header_sys_prctl_h" "$ac_includes_default" if test "x$ac_cv_header_sys_prctl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_PRCTL_H 1 _ACEOF fi done for ac_header in sys/un.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/un.h" "ac_cv_header_sys_un_h" "$ac_includes_default" if test "x$ac_cv_header_sys_un_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_UN_H 1 _ACEOF ISC_PLATFORM_HAVESYSUNH="#define ISC_PLATFORM_HAVESYSUNH 1" else ISC_PLATFORM_HAVESYSUNH="#undef ISC_PLATFORM_HAVESYSUNH" fi done case "$host" in *-solaris*) $as_echo "#define NEED_SECURE_DIRECTORY 1" >>confdefs.h ;; *-sunos*) $as_echo "#define NEED_SECURE_DIRECTORY 1" >>confdefs.h ;; esac # # Time Zone Stuff # ac_fn_c_check_func "$LINENO" "tzset" "ac_cv_func_tzset" if test "x$ac_cv_func_tzset" = xyes; then : $as_echo "#define HAVE_TZSET 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for optarg declaration" >&5 $as_echo_n "checking for optarg declaration... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { optarg = 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } GEN_NEED_OPTARG="-DNEED_OPTARG=1" $as_echo "#define NEED_OPTARG 1" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # # BSD/OS, and perhaps some others, don't define rlim_t. # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for type rlim_t" >&5 $as_echo_n "checking for type rlim_t... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { rlim_t rl = 19671212; return (0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ISC_PLATFORM_RLIMITTYPE="#define ISC_PLATFORM_RLIMITTYPE rlim_t" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking type of rlim_cur" >&5 $as_echo_n "checking type of rlim_cur... " >&6; } if test "$cross_compiling" = yes; then : # Check whether --with-rlimtype was given. if test "${with_rlimtype+set}" = set; then : withval=$with_rlimtype; rlimtype="$withval" else rlimtype="long long int" fi ISC_PLATFORM_RLIMITTYPE="#define ISC_PLATFORM_RLIMITTYPE $rlimtype" { $as_echo "$as_me:${as_lineno-$LINENO}: result: cannot determine type of rlim_cur when cross compiling - assuming $rlimtype" >&5 $as_echo "cannot determine type of rlim_cur when cross compiling - assuming $rlimtype" >&6; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include main() { struct rlimit r; exit(!(sizeof(r.rlim_cur) == sizeof(int)));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: int" >&5 $as_echo "int" >&6; } ISC_PLATFORM_RLIMITTYPE="#define ISC_PLATFORM_RLIMITTYPE int" else if test "$cross_compiling" = yes; then : as_fn_error $? "this cannot happen" "$LINENO" 5 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include main() { struct rlimit r; exit(!(sizeof(r.rlim_cur) == sizeof(long int)));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: long int" >&5 $as_echo "long int" >&6; } ISC_PLATFORM_RLIMITTYPE="#define ISC_PLATFORM_RLIMITTYPE long int" else if test "$cross_compiling" = yes; then : as_fn_error $? "this cannot happen" "$LINENO" 5 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include main() { struct rlimit r; exit((!sizeof(r.rlim_cur) == sizeof(long long int)));} _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: long long int" >&5 $as_echo "long long int" >&6; } ISC_PLATFORM_RLIMITTYPE="#define ISC_PLATFORM_RLIMITTYPE long long int" else as_fn_error $? "unable to determine sizeof rlim_cur" "$LINENO" 5 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # # Older HP-UX doesn't have gettune # case "$host" in *-hp-hpux*) for ac_header in sys/dyntune.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/dyntune.h" "ac_cv_header_sys_dyntune_h" "$ac_includes_default" if test "x$ac_cv_header_sys_dyntune_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_DYNTUNE_H 1 _ACEOF fi done ;; *) ;; esac # # Compaq TruCluster requires more code for handling cluster IP aliases # case "$host" in *-dec-osf*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clua_getaliasaddress in -lclua" >&5 $as_echo_n "checking for clua_getaliasaddress in -lclua... " >&6; } if ${ac_cv_lib_clua_clua_getaliasaddress+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lclua $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 clua_getaliasaddress (); int main () { return clua_getaliasaddress (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_clua_clua_getaliasaddress=yes else ac_cv_lib_clua_clua_getaliasaddress=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_clua_clua_getaliasaddress" >&5 $as_echo "$ac_cv_lib_clua_clua_getaliasaddress" >&6; } if test "x$ac_cv_lib_clua_clua_getaliasaddress" = xyes; then : LIBS="-lclua $LIBS" fi ac_fn_c_check_func "$LINENO" "clua_getaliasaddress" "ac_cv_func_clua_getaliasaddress" if test "x$ac_cv_func_clua_getaliasaddress" = xyes; then : $as_echo "#define HAVE_TRUCLUSTER 1" >>confdefs.h fi ;; *) ;; esac # # Some hosts need msg_namelen to match the size of the socket structure. # Some hosts don't set msg_namelen appropriately on return from recvmsg(). # case $host in *os2*|*hp-mpeix*) $as_echo "#define BROKEN_RECVMSG 1" >>confdefs.h ;; esac # # Microsoft has their own way of handling shared libraries that requires # additional qualifiers on extern variables. Unix systems don't need it. # ISC_PLATFORM_USEDECLSPEC="#undef ISC_PLATFORM_USEDECLSPEC" LWRES_PLATFORM_USEDECLSPEC="#undef LWRES_PLATFORM_USEDECLSPEC" IRS_PLATFORM_USEDECLSPEC="#undef IRS_PLATFORM_USEDECLSPEC" # # Random remaining OS-specific issues involving compiler warnings. # XXXDCL print messages to indicate some compensation is being done? # ISC_PLATFORM_BRACEPTHREADONCEINIT="#undef ISC_PLATFORM_BRACEPTHREADONCEINIT" case "$host" in *-aix5.[123].*) hack_shutup_pthreadonceinit=yes ;; *-bsdi3.1*) hack_shutup_sputaux=yes ;; *-bsdi4.0*) hack_shutup_sigwait=yes hack_shutup_sputaux=yes ;; *-bsdi4.[12]*) hack_shutup_stdargcast=yes ;; *-solaris2.[89]) hack_shutup_pthreadonceinit=yes ;; *-solaris2.1[0-9]) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { static pthread_once_t once_test = { PTHREAD_ONCE_INIT }; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : hack_shutup_pthreadonceinit=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ;; esac case "$hack_shutup_pthreadonceinit" in yes) # # Shut up PTHREAD_ONCE_INIT unbraced initializer warnings. # ISC_PLATFORM_BRACEPTHREADONCEINIT="#define ISC_PLATFORM_BRACEPTHREADONCEINIT 1" ;; esac case "$hack_shutup_sigwait" in yes) # # Shut up a -Wmissing-prototypes warning for sigwait(). # $as_echo "#define SHUTUP_SIGWAIT 1" >>confdefs.h ;; esac case "$hack_shutup_sputaux" in yes) # # Shut up a -Wmissing-prototypes warning from . # $as_echo "#define SHUTUP_SPUTAUX 1" >>confdefs.h ;; esac case "$hack_shutup_stdargcast" in yes) # # Shut up a -Wcast-qual warning from va_start(). # $as_echo "#define SHUTUP_STDARG_CAST 1" >>confdefs.h ;; esac for ac_header in strings.h do : ac_fn_c_check_header_mongrel "$LINENO" "strings.h" "ac_cv_header_strings_h" "$ac_includes_default" if test "x$ac_cv_header_strings_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRINGS_H 1 _ACEOF ISC_PLATFORM_HAVESTRINGSH="#define ISC_PLATFORM_HAVESTRINGSH 1" else ISC_PLATFORM_HAVESTRINGSH="#undef ISC_PLATFORM_HAVESTRINGSH" fi done # # Check for if_nametoindex() for IPv6 scoped addresses support # ac_fn_c_check_func "$LINENO" "if_nametoindex" "ac_cv_func_if_nametoindex" if test "x$ac_cv_func_if_nametoindex" = xyes; then : ac_cv_have_if_nametoindex=yes else ac_cv_have_if_nametoindex=no fi case $ac_cv_have_if_nametoindex in no) case "$host" in *-hp-hpux*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for if_nametoindex in -lipv6" >&5 $as_echo_n "checking for if_nametoindex in -lipv6... " >&6; } if ${ac_cv_lib_ipv6_if_nametoindex+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lipv6 $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 if_nametoindex (); int main () { return if_nametoindex (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ipv6_if_nametoindex=yes else ac_cv_lib_ipv6_if_nametoindex=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_ipv6_if_nametoindex" >&5 $as_echo "$ac_cv_lib_ipv6_if_nametoindex" >&6; } if test "x$ac_cv_lib_ipv6_if_nametoindex" = xyes; then : ac_cv_have_if_nametoindex=yes LIBS="-lipv6 $LIBS" fi ;; esac esac case $ac_cv_have_if_nametoindex in yes) ISC_PLATFORM_HAVEIFNAMETOINDEX="#define ISC_PLATFORM_HAVEIFNAMETOINDEX 1" $as_echo "#define HAVE_IF_NAMETOINDEX 1" >>confdefs.h ;; *) ISC_PLATFORM_HAVEIFNAMETOINDEX="#undef ISC_PLATFORM_HAVEIFNAMETOINDEX" ;; esac for ac_func in nanosleep usleep 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" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done # # Machine architecture dependent features # # Check whether --enable-atomic was given. if test "${enable_atomic+set}" = set; then : enableval=$enable_atomic; enable_atomic="$enableval" else enable_atomic="autodetect" fi case "$enable_atomic" in yes|''|autodetect) case "$host" in powerpc-ibm-aix*) if test "X$GCC" = "Xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if asm(\"isc\"); works" >&5 $as_echo_n "checking if asm(\"isc\"); works... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { main() { asm("ics"); exit(0); } ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } use_atomic=yes else saved_cflags="$CFLAGS" CFLAGS="$CFLAGS -Wa,-many" if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: cross compile, assume yes" >&5 $as_echo "cross compile, assume yes" >&6; } CFLAGS="$saved_cflags" use_atomic=yes else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ main() { asm("ics"); exit(0); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes, required -Wa,-many" >&5 $as_echo "yes, required -Wa,-many" >&6; } use_atomic=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, use_atomic disabled" >&5 $as_echo "no, use_atomic disabled" >&6; } CFLAGS="$saved_cflags" use_atomic=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else use_atomic=yes fi ;; *) use_atomic=yes ;; esac ;; no) use_atomic=no arch=noatomic ;; esac ISC_PLATFORM_USEOSFASM="#undef ISC_PLATFORM_USEOSFASM" ISC_PLATFORM_USEGCCASM="#undef ISC_PLATFORM_USEGCCASM" ISC_PLATFORM_USESTDASM="#undef ISC_PLATFORM_USESTDASM" ISC_PLATFORM_USEMACASM="#undef ISC_PLATFORM_USEMACASM" if test "$use_atomic" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking architecture type for atomic operations" >&5 $as_echo_n "checking architecture type for atomic operations... " >&6; } have_atomic=yes # set default case "$host" in i[3456]86-*) # XXX: some old x86 architectures actually do not support # (some of) these operations. Do we need stricter checks? # 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 void *" >&5 $as_echo_n "checking size of void *... " >&6; } if ${ac_cv_sizeof_void_p+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then : else if test "$ac_cv_type_void_p" = 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 (void *) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_void_p=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5 $as_echo "$ac_cv_sizeof_void_p" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_VOID_P $ac_cv_sizeof_void_p _ACEOF if test $ac_cv_sizeof_void_p = 8; then arch=x86_64 have_xaddq=yes else arch=x86_32 fi ;; x86_64-*|amd64-*) # 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 void *" >&5 $as_echo_n "checking size of void *... " >&6; } if ${ac_cv_sizeof_void_p+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then : else if test "$ac_cv_type_void_p" = 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 (void *) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_void_p=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5 $as_echo "$ac_cv_sizeof_void_p" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_VOID_P $ac_cv_sizeof_void_p _ACEOF if test $ac_cv_sizeof_void_p = 8; then arch=x86_64 have_xaddq=yes else arch=x86_32 fi ;; alpha*-*) arch=alpha ;; powerpc-*|powerpc64-*) arch=powerpc ;; mips-*|mipsel-*|mips64-*|mips64el-*) arch=mips ;; ia64-*) arch=ia64 ;; *) have_atomic=no arch=noatomic ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $arch" >&5 $as_echo "$arch" >&6; } fi if test "$have_atomic" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler support for inline assembly code" >&5 $as_echo_n "checking compiler support for inline assembly code... " >&6; } compiler=generic # Check whether the compiler supports the assembly syntax we provide. if test "X$GCC" = "Xyes"; then # GCC's ASM extension always works compiler=gcc if test $arch = "x86_64"; then # We can share the same code for gcc with x86_32 arch=x86_32 fi if test $arch = "powerpc"; then # # The MacOS (and maybe others) uses "r0" for register # zero. Under linux/ibm it is "0" for register 0. # Probe to see if we have a MacOS style assembler. # { $as_echo "$as_me:${as_lineno-$LINENO}: checking Checking for MacOS style assembler syntax" >&5 $as_echo_n "checking Checking for MacOS style assembler syntax... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { __asm__ volatile ("li r0, 0x0\n"::); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } compiler="mac" ISC_PLATFORM_USEMACASM="#define ISC_PLATFORM_USEMACASM 1" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi else case "$host" in alpha*-dec-osf*) # Tru64 compiler has its own syntax for inline # assembly. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __DECC #error "unexpected compiler" #endif return (0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : compiler=osf fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ;; powerpc-ibm-aix*) compiler=aix ;; esac fi case "$compiler" in gcc) ISC_PLATFORM_USEGCCASM="#define ISC_PLATFORM_USEGCCASM 1" ;; osf) ISC_PLATFORM_USEOSFASM="#define ISC_PLATFORM_USEOSFASM 1" ;; aix) ;; mac) ;; *) # See if the generic __asm function works. If not, # we need to disable the atomic operations. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { __asm("nop") ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : compiler="standard" ISC_PLATFORM_USESTDASM="#define ISC_PLATFORM_USESTDASM 1" else compiler="not supported (atomic operations disabled)" have_atomic=no arch=noatomic fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext; ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $compiler" >&5 $as_echo "$compiler" >&6; } fi if test "$have_atomic" = "yes"; then ISC_PLATFORM_HAVEXADD="#define ISC_PLATFORM_HAVEXADD 1" ISC_PLATFORM_HAVECMPXCHG="#define ISC_PLATFORM_HAVECMPXCHG 1" ISC_PLATFORM_HAVEATOMICSTORE="#define ISC_PLATFORM_HAVEATOMICSTORE 1" if test "$have_xaddq" = "yes"; then ISC_PLATFORM_HAVEXADDQ="#define ISC_PLATFORM_HAVEXADDQ 1" else ISC_PLATFORM_HAVEXADDQ="#undef ISC_PLATFORM_HAVEXADDQ" fi else ISC_PLATFORM_HAVEXADD="#undef ISC_PLATFORM_HAVEXADD" ISC_PLATFORM_HAVECMPXCHG="#undef ISC_PLATFORM_HAVECMPXCHG" ISC_PLATFORM_HAVEATOMICSTORE="#undef ISC_PLATFORM_HAVEATOMICSTORE" ISC_PLATFORM_HAVEXADDQ="#undef ISC_PLATFORM_HAVEXADDQ" fi ISC_ARCH_DIR=$arch # # Activate "rrset-order fixed" or not? # # Check whether --enable-fixed-rrset was given. if test "${enable_fixed_rrset+set}" = set; then : enableval=$enable_fixed_rrset; enable_fixed="$enableval" else enable_fixed="no" fi case "$enable_fixed" in yes) $as_echo "#define DNS_RDATASET_FIXED 1" >>confdefs.h ;; no) ;; *) ;; esac # # Enable response policy rewriting using NS IP addresses # # Check whether --enable-rpz-nsip was given. if test "${enable_rpz_nsip+set}" = set; then : enableval=$enable_rpz_nsip; enable_nsip="$enableval" else enable_nsip="yes" fi case "$enable_nsip" in yes) $as_echo "#define ENABLE_RPZ_NSIP 1" >>confdefs.h ;; no) ;; *) ;; esac # # Enable response policy rewriting using NS name # # Check whether --enable-rpz-nsdname was given. if test "${enable_rpz_nsdname+set}" = set; then : enableval=$enable_rpz_nsdname; enable_nsdname="$enableval" else enable_nsdname="yes" fi case "$enable_nsdname" in yes) $as_echo "#define ENABLE_RPZ_NSDNAME 1" >>confdefs.h ;; no) ;; *) ;; esac # # Activate recursive fetch limits # # Check whether --enable-fetchlimit was given. if test "${enable_fetchlimit+set}" = set; then : enableval=$enable_fetchlimit; enable_fetchlimit="$enableval" else enable_fetchlimit="no" fi case "$enable_fetchlimit" in yes) $as_echo "#define ENABLE_FETCHLIMIT 1" >>confdefs.h ;; no) ;; *) ;; esac # # Activate "filter-aaaa" or not? # # Check whether --enable-filter-aaaa was given. if test "${enable_filter_aaaa+set}" = set; then : enableval=$enable_filter_aaaa; enable_filter="$enableval" else enable_filter="no" fi case "$enable_filter" in yes) $as_echo "#define ALLOW_FILTER_AAAA 1" >>confdefs.h ;; no) ;; *) ;; esac # # The following sets up how non-blocking i/o is established. # Sunos, cygwin and solaris 2.x (x<5) require special handling. # case "$host" in *-sunos*) $as_echo "#define PORT_NONBLOCK O_NDELAY" >>confdefs.h ;; *-cygwin*) $as_echo "#define PORT_NONBLOCK O_NDELAY" >>confdefs.h ;; *-solaris2.[01234]) $as_echo "#define PORT_NONBLOCK O_NONBLOCK" >>confdefs.h $as_echo "#define USE_FIONBIO_IOCTL 1" >>confdefs.h ;; *) $as_echo "#define PORT_NONBLOCK O_NONBLOCK" >>confdefs.h ;; esac # # Solaris 2.5.1 and earlier cannot bind() then connect() a TCP socket. # This prevents the source address being set. # case "$host" in *-solaris2.[012345]|*-solaris2.5.1) $as_echo "#define BROKEN_TCP_BIND_BEFORE_CONNECT 1" >>confdefs.h ;; esac # # The following sections deal with tools used for formatting # the documentation. They are all optional, unless you are # a developer editing the documentation source. # # # Look for TeX. # for ac_prog in latex do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_LATEX+:} false; then : $as_echo_n "(cached) " >&6 else case $LATEX in [\\/]* | ?:[\\/]*) ac_cv_path_LATEX="$LATEX" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_LATEX="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi LATEX=$ac_cv_path_LATEX if test -n "$LATEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LATEX" >&5 $as_echo "$LATEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$LATEX" && break done test -n "$LATEX" || LATEX="latex" for ac_prog in pdflatex do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PDFLATEX+:} false; then : $as_echo_n "(cached) " >&6 else case $PDFLATEX in [\\/]* | ?:[\\/]*) ac_cv_path_PDFLATEX="$PDFLATEX" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PDFLATEX="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PDFLATEX=$ac_cv_path_PDFLATEX if test -n "$PDFLATEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PDFLATEX" >&5 $as_echo "$PDFLATEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$PDFLATEX" && break done test -n "$PDFLATEX" || PDFLATEX="pdflatex" # # Look for w3m # for ac_prog in w3m do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_W3M+:} false; then : $as_echo_n "(cached) " >&6 else case $W3M in [\\/]* | ?:[\\/]*) ac_cv_path_W3M="$W3M" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_W3M="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi W3M=$ac_cv_path_W3M if test -n "$W3M"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $W3M" >&5 $as_echo "$W3M" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$W3M" && break done test -n "$W3M" || W3M="w3m" # # Look for xsltproc (libxslt) # # Extract the first word of "xsltproc", so it can be a program name with args. set dummy xsltproc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_XSLTPROC+:} false; then : $as_echo_n "(cached) " >&6 else case $XSLTPROC in [\\/]* | ?:[\\/]*) ac_cv_path_XSLTPROC="$XSLTPROC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_XSLTPROC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_XSLTPROC" && ac_cv_path_XSLTPROC="xsltproc" ;; esac fi XSLTPROC=$ac_cv_path_XSLTPROC if test -n "$XSLTPROC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XSLTPROC" >&5 $as_echo "$XSLTPROC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # # Look for xmllint (libxml2) # # Extract the first word of "xmllint", so it can be a program name with args. set dummy xmllint; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_XMLLINT+:} false; then : $as_echo_n "(cached) " >&6 else case $XMLLINT in [\\/]* | ?:[\\/]*) ac_cv_path_XMLLINT="$XMLLINT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_XMLLINT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_XMLLINT" && ac_cv_path_XMLLINT="xmllint" ;; esac fi XMLLINT=$ac_cv_path_XMLLINT if test -n "$XMLLINT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XMLLINT" >&5 $as_echo "$XMLLINT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # # Look for Doxygen # # Extract the first word of "doxygen", so it can be a program name with args. set dummy doxygen; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DOXYGEN+:} false; then : $as_echo_n "(cached) " >&6 else case $DOXYGEN in [\\/]* | ?:[\\/]*) ac_cv_path_DOXYGEN="$DOXYGEN" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DOXYGEN="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_DOXYGEN" && ac_cv_path_DOXYGEN="doxygen" ;; esac fi DOXYGEN=$ac_cv_path_DOXYGEN if test -n "$DOXYGEN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOXYGEN" >&5 $as_echo "$DOXYGEN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # # Look for curl # # Extract the first word of "curl", so it can be a program name with args. set dummy curl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_CURL+:} false; then : $as_echo_n "(cached) " >&6 else case $CURL in [\\/]* | ?:[\\/]*) ac_cv_path_CURL="$CURL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_CURL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_CURL" && ac_cv_path_CURL="curl" ;; esac fi CURL=$ac_cv_path_CURL if test -n "$CURL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CURL" >&5 $as_echo "$CURL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # # Subroutine for searching for an ordinary file (e.g., a stylesheet) # in a number of directories: # # NOM_PATH_FILE(VARIABLE, FILENAME, DIRECTORIES) # # If the file FILENAME is found in one of the DIRECTORIES, the shell # variable VARIABLE is defined to its absolute pathname. Otherwise, # it is set to FILENAME, with no directory prefix (that's not terribly # useful, but looks less confusing in substitutions than leaving it # empty). The variable VARIABLE will be substituted into output files. # # # Look for Docbook-XSL stylesheets. Location probably varies by system. # If it's not explicitly specified, guess where it might be found, based on # where SGML stuff lives on some systems (FreeBSD is the only one we're sure # of at the moment). # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Docbook-XSL path" >&5 $as_echo_n "checking for Docbook-XSL path... " >&6; } # Check whether --with-docbook-xsl was given. if test "${with_docbook_xsl+set}" = set; then : withval=$with_docbook_xsl; docbook_path="$withval" else docbook_path="auto" fi case "$docbook_path" in auto) { $as_echo "$as_me:${as_lineno-$LINENO}: result: auto" >&5 $as_echo "auto" >&6; } docbook_xsl_trees="/usr/pkg/share/xsl/docbook /usr/local/share/xsl/docbook /usr/share/xsl/docbook /opt/local/share/xsl/docbook-xsl" ;; *) docbook_xsl_trees="$withval" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $docbook_xsl_trees" >&5 $as_echo "$docbook_xsl_trees" >&6; } ;; esac # # Look for stylesheets we need. # XSLT_DOCBOOK_STYLE_HTML="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for html/docbook.xsl" >&5 $as_echo_n "checking for html/docbook.xsl... " >&6; } for d in $docbook_xsl_trees do f=$d/html/docbook.xsl if test -f $f then XSLT_DOCBOOK_STYLE_HTML=$f { $as_echo "$as_me:${as_lineno-$LINENO}: result: $f" >&5 $as_echo "$f" >&6; } break fi done if test "X$XSLT_DOCBOOK_STYLE_HTML" = "X" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"not found\"" >&5 $as_echo "\"not found\"" >&6; }; XSLT_DOCBOOK_STYLE_HTML=html/docbook.xsl fi XSLT_DOCBOOK_STYLE_XHTML="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for xhtml/docbook.xsl" >&5 $as_echo_n "checking for xhtml/docbook.xsl... " >&6; } for d in $docbook_xsl_trees do f=$d/xhtml/docbook.xsl if test -f $f then XSLT_DOCBOOK_STYLE_XHTML=$f { $as_echo "$as_me:${as_lineno-$LINENO}: result: $f" >&5 $as_echo "$f" >&6; } break fi done if test "X$XSLT_DOCBOOK_STYLE_XHTML" = "X" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"not found\"" >&5 $as_echo "\"not found\"" >&6; }; XSLT_DOCBOOK_STYLE_XHTML=xhtml/docbook.xsl fi XSLT_DOCBOOK_STYLE_MAN="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for manpages/docbook.xsl" >&5 $as_echo_n "checking for manpages/docbook.xsl... " >&6; } for d in $docbook_xsl_trees do f=$d/manpages/docbook.xsl if test -f $f then XSLT_DOCBOOK_STYLE_MAN=$f { $as_echo "$as_me:${as_lineno-$LINENO}: result: $f" >&5 $as_echo "$f" >&6; } break fi done if test "X$XSLT_DOCBOOK_STYLE_MAN" = "X" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"not found\"" >&5 $as_echo "\"not found\"" >&6; }; XSLT_DOCBOOK_STYLE_MAN=manpages/docbook.xsl fi XSLT_DOCBOOK_CHUNK_HTML="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for html/chunk.xsl" >&5 $as_echo_n "checking for html/chunk.xsl... " >&6; } for d in $docbook_xsl_trees do f=$d/html/chunk.xsl if test -f $f then XSLT_DOCBOOK_CHUNK_HTML=$f { $as_echo "$as_me:${as_lineno-$LINENO}: result: $f" >&5 $as_echo "$f" >&6; } break fi done if test "X$XSLT_DOCBOOK_CHUNK_HTML" = "X" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"not found\"" >&5 $as_echo "\"not found\"" >&6; }; XSLT_DOCBOOK_CHUNK_HTML=html/chunk.xsl fi XSLT_DOCBOOK_CHUNK_XHTML="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for xhtml/chunk.xsl" >&5 $as_echo_n "checking for xhtml/chunk.xsl... " >&6; } for d in $docbook_xsl_trees do f=$d/xhtml/chunk.xsl if test -f $f then XSLT_DOCBOOK_CHUNK_XHTML=$f { $as_echo "$as_me:${as_lineno-$LINENO}: result: $f" >&5 $as_echo "$f" >&6; } break fi done if test "X$XSLT_DOCBOOK_CHUNK_XHTML" = "X" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"not found\"" >&5 $as_echo "\"not found\"" >&6; }; XSLT_DOCBOOK_CHUNK_XHTML=xhtml/chunk.xsl fi XSLT_DOCBOOK_CHUNKTOC_HTML="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for html/chunktoc.xsl" >&5 $as_echo_n "checking for html/chunktoc.xsl... " >&6; } for d in $docbook_xsl_trees do f=$d/html/chunktoc.xsl if test -f $f then XSLT_DOCBOOK_CHUNKTOC_HTML=$f { $as_echo "$as_me:${as_lineno-$LINENO}: result: $f" >&5 $as_echo "$f" >&6; } break fi done if test "X$XSLT_DOCBOOK_CHUNKTOC_HTML" = "X" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"not found\"" >&5 $as_echo "\"not found\"" >&6; }; XSLT_DOCBOOK_CHUNKTOC_HTML=html/chunktoc.xsl fi XSLT_DOCBOOK_CHUNKTOC_XHTML="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for xhtml/chunktoc.xsl" >&5 $as_echo_n "checking for xhtml/chunktoc.xsl... " >&6; } for d in $docbook_xsl_trees do f=$d/xhtml/chunktoc.xsl if test -f $f then XSLT_DOCBOOK_CHUNKTOC_XHTML=$f { $as_echo "$as_me:${as_lineno-$LINENO}: result: $f" >&5 $as_echo "$f" >&6; } break fi done if test "X$XSLT_DOCBOOK_CHUNKTOC_XHTML" = "X" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"not found\"" >&5 $as_echo "\"not found\"" >&6; }; XSLT_DOCBOOK_CHUNKTOC_XHTML=xhtml/chunktoc.xsl fi XSLT_DOCBOOK_MAKETOC_HTML="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for html/maketoc.xsl" >&5 $as_echo_n "checking for html/maketoc.xsl... " >&6; } for d in $docbook_xsl_trees do f=$d/html/maketoc.xsl if test -f $f then XSLT_DOCBOOK_MAKETOC_HTML=$f { $as_echo "$as_me:${as_lineno-$LINENO}: result: $f" >&5 $as_echo "$f" >&6; } break fi done if test "X$XSLT_DOCBOOK_MAKETOC_HTML" = "X" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"not found\"" >&5 $as_echo "\"not found\"" >&6; }; XSLT_DOCBOOK_MAKETOC_HTML=html/maketoc.xsl fi XSLT_DOCBOOK_MAKETOC_XHTML="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for xhtml/maketoc.xsl" >&5 $as_echo_n "checking for xhtml/maketoc.xsl... " >&6; } for d in $docbook_xsl_trees do f=$d/xhtml/maketoc.xsl if test -f $f then XSLT_DOCBOOK_MAKETOC_XHTML=$f { $as_echo "$as_me:${as_lineno-$LINENO}: result: $f" >&5 $as_echo "$f" >&6; } break fi done if test "X$XSLT_DOCBOOK_MAKETOC_XHTML" = "X" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"not found\"" >&5 $as_echo "\"not found\"" >&6; }; XSLT_DOCBOOK_MAKETOC_XHTML=xhtml/maketoc.xsl fi # # Same dance for db2latex # db2latex_xsl_trees="/usr/local/share/db2latex/xsl /usr/pkg/share/xsl/db2latex" # # Look for stylesheets we need. # XSLT_DB2LATEX_STYLE="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for docbook.xsl" >&5 $as_echo_n "checking for docbook.xsl... " >&6; } for d in $db2latex_xsl_trees do f=$d/docbook.xsl if test -f $f then XSLT_DB2LATEX_STYLE=$f { $as_echo "$as_me:${as_lineno-$LINENO}: result: $f" >&5 $as_echo "$f" >&6; } break fi done if test "X$XSLT_DB2LATEX_STYLE" = "X" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"not found\"" >&5 $as_echo "\"not found\"" >&6; }; XSLT_DB2LATEX_STYLE=docbook.xsl fi # # Look for "admonition" image directory. Can't use NOM_PATH_FILE() # because it's a directory, so just do the same things, inline. # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for db2latex xsl figures" >&5 $as_echo_n "checking for db2latex xsl figures... " >&6; } for d in $db2latex_xsl_trees do if test -d $d/figures then XSLT_DB2LATEX_ADMONITIONS=$d/figures { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d/figures" >&5 $as_echo "$d/figures" >&6; } break fi done if test "X$XSLT_DB2LATEX_ADMONITIONS" = "X" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 $as_echo "not found" >&6; } XSLT_DB2LATEX_ADMONITIONS=db2latex/xsl/figures fi # # IDN support # # Check whether --with-idn was given. if test "${with_idn+set}" = set; then : withval=$with_idn; use_idn="$withval" else use_idn="no" fi case "$use_idn" in yes) if test X$prefix = XNONE ; then idn_path=/usr/local else idn_path=$prefix fi ;; no) ;; *) idn_path="$use_idn" ;; esac iconvinc= iconvlib= # Check whether --with-libiconv was given. if test "${with_libiconv+set}" = set; then : withval=$with_libiconv; use_libiconv="$withval" else use_libiconv="no" fi case "$use_libiconv" in yes) if test X$prefix = XNONE ; then iconvlib="-L/usr/local/lib -R/usr/local/lib -liconv" else iconvlib="-L$prefix/lib -R$prefix/lib -liconv" fi ;; no) iconvlib= ;; *) iconvlib="-L$use_libiconv/lib -R$use_libiconv/lib -liconv" ;; esac # Check whether --with-iconv was given. if test "${with_iconv+set}" = set; then : withval=$with_iconv; iconvlib="$withval" fi case "$iconvlib" in no) iconvlib= ;; yes) iconvlib=-liconv ;; esac # Check whether --with-idnlib was given. if test "${with_idnlib+set}" = set; then : withval=$with_idnlib; idnlib="$withval" else idnlib="no" fi if test "$idnlib" = yes; then as_fn_error $? "You must specify ARG for --with-idnlib." "$LINENO" 5 fi IDNLIBS= if test "$use_idn" != no; then $as_echo "#define WITH_IDN 1" >>confdefs.h STD_CINCLUDES="$STD_CINCLUDES -I$idn_path/include" if test "$idnlib" != no; then IDNLIBS="$idnlib $iconvlib" else IDNLIBS="-L$idn_path/lib -lidnkit $iconvlib" fi fi # # Check whether to build Automated Test Framework unit tests # # Check whether --with-atf was given. if test "${with_atf+set}" = set; then : withval=$with_atf; atf="$withval" else atf="no" fi if test "$atf" = yes; then atf=`pwd`/unit/atf ATFBUILD=atf-src ac_config_commands="$ac_config_commands atf-config" { $as_echo "$as_me:${as_lineno-$LINENO}: result: building ATF from bind9/unit/atf-src" >&5 $as_echo "building ATF from bind9/unit/atf-src" >&6; } fi ATFLIBS= if test "$atf" != no; then $as_echo "#define ATF_TEST 1" >>confdefs.h STD_CINCLUDES="$STD_CINCLUDES -I$atf/include" ATFBIN="$atf/bin" ATFLIBS="-L$atf/lib -latf-c" UNITTESTS=tests fi for ac_header in locale.h do : ac_fn_c_check_header_mongrel "$LINENO" "locale.h" "ac_cv_header_locale_h" "$ac_includes_default" if test "x$ac_cv_header_locale_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LOCALE_H 1 _ACEOF fi done for ac_func in setlocale do : ac_fn_c_check_func "$LINENO" "setlocale" "ac_cv_func_setlocale" if test "x$ac_cv_func_setlocale" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SETLOCALE 1 _ACEOF fi done # # was --with-tuning specified? # # Check whether --with-tuning was given. if test "${with_tuning+set}" = set; then : withval=$with_tuning; use_tuning="$withval" else use_tuning="no" fi case "$use_tuning" in large) if ! $use_threads; then as_fn_error $? "Large-system tuning requires threads." "$LINENO" 5 fi $as_echo "#define TUNE_LARGE 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: using large-system tuning" >&5 $as_echo "using large-system tuning" >&6; } ;; no|default) { $as_echo "$as_me:${as_lineno-$LINENO}: result: using default tuning" >&5 $as_echo "using default tuning" >&6; } ;; yes|*) as_fn_error $? "You must specify \"large\" or \"default\" for --with-tuning." "$LINENO" 5 ;; esac # # was --enable-querytrace specified? # # Check whether --enable-querytrace was given. if test "${enable_querytrace+set}" = set; then : enableval=$enable_querytrace; want_querytrace="$enableval" else want_querytrace="no" fi case "$want_querytrace" in yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define WANT_QUERYTRACE 1" >>confdefs.h ;; no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; *) as_fn_error $? "\"--enable-querytrace requires yes or no\"" "$LINENO" 5 ;; esac # # Substitutions # BIND9_TOP_BUILDDIR=`pwd` if test "X$srcdir" != "X"; then BIND9_ISC_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/isc/include" BIND9_ISCCC_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/isccc/include" BIND9_ISCCFG_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/isccfg/include" BIND9_DNS_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/dns/include" BIND9_LWRES_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/lwres/include" BIND9_BIND9_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/bind9/include" BIND9_IRS_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/irs/include" else BIND9_ISC_BUILDINCLUDE="" BIND9_ISCCC_BUILDINCLUDE="" BIND9_ISCCFG_BUILDINCLUDE="" BIND9_DNS_BUILDINCLUDE="" BIND9_LWRES_BUILDINCLUDE="" BIND9_BIND9_BUILDINCLUDE="" BIND9_IRS_BUILDINCLUDE="" fi BIND9_MAKE_INCLUDES=$BIND9_TOP_BUILDDIR/make/includes BIND9_MAKE_RULES=$BIND9_TOP_BUILDDIR/make/rules . "$srcdir/version" BIND9_PRODUCT="PRODUCT=\"${PRODUCT}\"" BIND9_DESCRIPTION="DESCRIPTION=\"${DESCRIPTION}\"" BIND9_VERSION="VERSION=${MAJORVER}.${MINORVER}${PATCHVER:+.}${PATCHVER}${RELEASETYPE}${RELEASEVER}${EXTENSIONS}" BIND9_MAJOR="MAJOR=${MAJORVER}.${MINORVER}" BIND9_VERSIONSTRING="${PRODUCT} ${MAJORVER}.${MINORVER}${PATCHVER:+.}${PATCHVER}${RELEASETYPE}${RELEASEVER}${EXTENSIONS}${DESCRIPTION:+ }${DESCRIPTION}" BIND9_SRCID="SRCID=unset" if test -f "${srcdir}/srcid"; then . "${srcdir}/srcid" BIND9_SRCID="SRCID=$SRCID" elif test -d "${srcdir}/.git"; then BIND9_SRCID="SRCID="`(cd "${srcdir}";git rev-parse --short HEAD)` fi if test -z "$ac_configure_args"; then BIND9_CONFIGARGS="defaults" else for a in $ac_configure_args do BIND9_CONFIGARGS="$BIND9_CONFIGARGS $a" done fi BIND9_CONFIGARGS="`echo $BIND9_CONFIGARGS | sed 's/^ //'`" BIND9_CONFIGARGS="CONFIGARGS=${BIND9_CONFIGARGS}" LIBISC_API="$srcdir/lib/isc/api" LIBISCCC_API="$srcdir/lib/isccc/api" LIBISCCFG_API="$srcdir/lib/isccfg/api" LIBDNS_API="$srcdir/lib/dns/api" LIBDNS_MAPAPI="$srcdir/lib/dns/mapapi" LIBBIND9_API="$srcdir/lib/bind9/api" LIBLWRES_API="$srcdir/lib/lwres/api" LIBIRS_API="$srcdir/lib/irs/api" # # Configure any DLZ drivers. # # If config.dlz.in selects one or more DLZ drivers, it will set # CONTRIB_DLZ to a non-empty value, which will be our clue to # build DLZ drivers in contrib. # # This section has to come after the libtool stuff because it needs to # know how to name the driver object files. # CONTRIB_DLZ="" DLZ_DRIVER_INCLUDES="" DLZ_DRIVER_LIBS="" DLZ_DRIVER_SRCS="" DLZ_DRIVER_OBJS="" DLZ_SYSTEM_TEST="" # # Configure support for building a shared library object # # Even when libtool is available it can't always be relied upon # to build an object that can be dlopen()'ed, but this is necessary # for building the dlzexternal system test, so we'll try it the # old-fashioned way. # SO="so" SO_CFLAGS="" SO_LDFLAGS="" SO_LD="" SO_TARGETS="" # Check whether --with-dlopen was given. if test "${with_dlopen+set}" = set; then : withval=$with_dlopen; dlopen="$withval" else dlopen="yes" fi case $host in *-sunos*) dlopen="no" ;; esac if test "$dlopen" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $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 dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=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_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : have_dl=yes else have_dl=no fi if test "$have_dl" = "yes"; then LIBS="-ldl $LIBS" fi for ac_func in dlopen dlclose dlsym 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" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF else dlopen=no fi done fi if test "$dlopen" = "yes"; then case $host in *-linux*|*-gnu*) SO_CFLAGS="-fPIC" SO_LDFLAGS="" if test "$have_dl" = "yes" then if test "$use_libtool" = "yes"; then SO_LDFLAGS="-Xcompiler -shared" SO_LD="${CC}" else SO_LDFLAGS="-shared" SO_LD="${CC}" fi else SO_LDFLAGS="-shared" SO_LD="ld" fi ;; *-freebsd*|*-openbsd*|*-netbsd*) SO_CFLAGS="-fpic" SO_LDFLAGS="-Bshareable -x" SO_LD="ld" ;; *-solaris*) SO_CFLAGS="-KPIC" SO_LDFLAGS="-G -z text" SO_LD="ld" ;; *-hp-hpux*) SO=sl SO_CFLAGS="+z" SO_LDFLAGS="-b +vnocompatwarnings" SO_LD="ld" ;; *) SO_CFLAGS="-fPIC" ;; esac if test "X$GCC" = "Xyes"; then SO_CFLAGS="-fPIC" if test -z "$SO_LD" then if test "$use_libtool" = "yes"; then SO_LDFLAGS="-Xcompiler -shared" SO_LD="${CC}" else SO_LDFLAGS="-shared" SO_LD="${CC}" fi fi fi # If we still don't know how to make shared objects, don't make any. if test -n "$SO_LD"; then SO_TARGETS="\${SO_TARGETS}" $as_echo "#define ISC_DLZ_DLOPEN 1" >>confdefs.h fi fi # Copyright (C) 2005 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # # Shorthand. Note quoting: DLZ_DRIVER_DIR expanded in Makefile, not here. # dlzdir='${DLZ_DRIVER_DIR}' # # Private autoconf macro to simplify configuring drivers: # # DLZ_ADD_DRIVER(DEFINE, DRIVER, INCLUDES, LIBS) # # where: # DEFINE is FOO (to define -DDLZ_FOO) # DRIVER is dlz_foo_driver (sources without the .c) # INCLUDES is any necessary include definitions # LIBS is any necessary library definitions # # # Check for the various DLZ drivers # # # Was --with-dlz-postgres specified? # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Postgres DLZ driver" >&5 $as_echo_n "checking for Postgres DLZ driver... " >&6; } # Check whether --with-dlz_postgres was given. if test "${with_dlz_postgres+set}" = set; then : withval=$with_dlz_postgres; use_dlz_postgres="$withval" else use_dlz_postgres="no" fi if test "$use_dlz_postgres" != "no" then if test "$use_dlz_postgres" != "yes" then for ac_prog in pg_config do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PG_CONFIG="$PG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $use_dlz_postgres/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PG_CONFIG=$ac_cv_path_PG_CONFIG if test -n "$PG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PG_CONFIG" >&5 $as_echo "$PG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$PG_CONFIG" && break done test -n "$PG_CONFIG" || PG_CONFIG="not found" else for ac_prog in pg_config do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PG_CONFIG="$PG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PG_CONFIG=$ac_cv_path_PG_CONFIG if test -n "$PG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PG_CONFIG" >&5 $as_echo "$PG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$PG_CONFIG" && break done test -n "$PG_CONFIG" || PG_CONFIG="not found" fi if test "$PG_CONFIG" != "not found" then use_dlz_postgres=`$PG_CONFIG --includedir` use_dlz_postgres_lib=`$PG_CONFIG --libdir` else pgprefix="$use_dlz_postgres" use_dlz_postgres="$pgprefix/include" use_dlz_postgres_lib="$pgprefix/lib" fi fi if test "$use_dlz_postgres" = "yes/include" then # User did not specify path and Postgres didn't say - guess it pgdirs="/usr /usr/local /usr/local/pgsql /usr/pkg" for d in $pgdirs do if test -f $d/include/libpq-fe.h then use_dlz_postgres=$d/include use_dlz_postgres_lib=$d/lib break fi done fi if test "$use_dlz_postgres" = "yes/include" then # Still no joy, give up { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 $as_echo "not found" >&6; } as_fn_error $? "No pg_config and PostgreSQL was not found in any of $pgdirs; use --with-dlz-postgres=/path or put pg_config in your path" "$LINENO" 5 fi case "$use_dlz_postgres" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; *) CONTRIB_DLZ="$CONTRIB_DLZ -DDLZ_POSTGRES" for i in dlz_postgres_driver do DLZ_DRIVER_SRCS="$DLZ_DRIVER_SRCS $dlzdir/$i.c" DLZ_DRIVER_OBJS="$DLZ_DRIVER_OBJS $i.$O" done if test -n "-I$use_dlz_postgres" then DLZ_DRIVER_INCLUDES="$DLZ_DRIVER_INCLUDES -I$use_dlz_postgres" fi if test -n "-L$use_dlz_postgres_lib -lpq" then DLZ_DRIVER_LIBS="$DLZ_DRIVER_LIBS -L$use_dlz_postgres_lib -lpq" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: using PostgreSQL from $use_dlz_postgres_lib and $use_dlz_postgres" >&5 $as_echo "using PostgreSQL from $use_dlz_postgres_lib and $use_dlz_postgres" >&6; } ;; esac # # Was --with-dlz-mysql specified? # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for MySQL DLZ driver" >&5 $as_echo_n "checking for MySQL DLZ driver... " >&6; } # Check whether --with-dlz_mysql was given. if test "${with_dlz_mysql+set}" = set; then : withval=$with_dlz_mysql; use_dlz_mysql="$withval" else use_dlz_mysql="no" fi mysql_include="" mysql_lib="" if test "$use_dlz_mysql" = "yes" then # User did not specify a path - guess it mysqldirs="/usr /usr/local /usr/local/mysql /usr/pkg" for d in $mysqldirs do if test -f $d/include/mysql/mysql.h then use_dlz_mysql=$d mysql_include=$d/include/mysql if test -d $d/lib/mysql then mysql_lib=$d/lib/mysql else mysql_lib=$d/lib fi break elif test -f $d/include/mysql.h then use_dlz_mysql=$d mysql_include=$d/include if test -d $d/lib/mysql then mysql_lib=$d/lib/mysql else mysql_lib=$d/lib fi break fi done elif test "$use_dlz_mysql" != "no" then d=$use_dlz_mysql if test -f $d/include/mysql/mysql.h then mysql_include=$d/include/mysql if test -d $d/lib/mysql then mysql_lib=$d/lib/mysql else mysql_lib=$d/lib fi elif test -f $d/include/mysql.h then mysql_include=$d/include if test -d $d/lib/mysql then mysql_lib=$d/lib/mysql else mysql_lib=$d/lib fi fi fi if test "$use_dlz_mysql" = "yes" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 $as_echo "not found" >&6; } as_fn_error $? "MySQL was not found in any of $mysqldirs; use --with-dlz-mysql=/path" "$LINENO" 5 fi case "$use_dlz_mysql" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; *) CONTRIB_DLZ="$CONTRIB_DLZ -DDLZ_MYSQL" for i in dlz_mysql_driver do DLZ_DRIVER_SRCS="$DLZ_DRIVER_SRCS $dlzdir/$i.c" DLZ_DRIVER_OBJS="$DLZ_DRIVER_OBJS $i.$O" done if test -n "-I${mysql_include}" then DLZ_DRIVER_INCLUDES="$DLZ_DRIVER_INCLUDES -I${mysql_include}" fi if test -n "-L${mysql_lib} -lmysqlclient -lz -lcrypt -lm" then DLZ_DRIVER_LIBS="$DLZ_DRIVER_LIBS -L${mysql_lib} -lmysqlclient -lz -lcrypt -lm" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: using mysql from ${mysql_lib} and ${mysql_include}" >&5 $as_echo "using mysql from ${mysql_lib} and ${mysql_include}" >&6; } ;; esac # # Was --with-dlz-bdb specified? # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB DLZ driver..." >&5 $as_echo_n "checking for Berkeley DB DLZ driver...... " >&6; } # Check whether --with-dlz_bdb was given. if test "${with_dlz_bdb+set}" = set; then : withval=$with_dlz_bdb; use_dlz_bdb="$withval" else use_dlz_bdb="no" fi case "$use_dlz_bdb" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; *) if test "$use_dlz_bdb" = "yes" then # User did not specify a path - guess directories bdbdirs="/usr/local /usr/pkg /usr" elif test -d "$use_dlz_bdb" then # User specified directory and it exists bdbdirs="$use_dlz_bdb" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 $as_echo "not found" >&6; } as_fn_error $? "path $use_dlz_bdb does not exist" "$LINENO" 5 bdbdirs="" fi # Use path we were given or guessed. This is insanely # complicated because we have to search for a bunch of # platform-specific variations and have to check # separately for include and library directories. # Set both to yes, so we can check them later dlz_bdb_inc="yes" dlz_bdb_libs="yes" { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5 $as_echo "" >&6; } for dd in $bdbdirs do # Skip nonexistant directories if test ! -d "$dd" then continue fi # Check other locations for includes. # Order is important (sigh). bdb_incdirs="/db53 /db51 /db48 /db47 /db46 /db45 /db44 /db43 /db42 /db41 /db4 /db" # include a blank element first for d in "" $bdb_incdirs do if test -f "$dd/include${d}/db.h" then dlz_bdb_inc="-I$dd/include${d}" break fi done # Give up on this directory if we couldn't # find the include subdir if test "$dlz_bdb_inc" = "yes" then continue fi # Look for libname other than libdb.so. # Order is important (sigh). bdb_libnames="db53 db-5.3 db51 db-5.1 db48 db-4.8 db47 db-4.7 db46 db-4.6 db45 db-4.5 db44 db-4.4 db43 db-4.3 db42 db-4.2 db41 db-4.1 db" for d in $bdb_libnames do if test "$dd" = "/usr" then as_ac_Lib=`$as_echo "ac_cv_lib_$d''_db_create" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for db_create in -l$d" >&5 $as_echo_n "checking for db_create in -l$d... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-l$d $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 db_create (); int main () { return db_create (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : dlz_bdb_libs="-l${d}" fi if test $dlz_bdb_libs != "yes" then break fi elif test -f "$dd/lib/lib${d}.so" then dlz_bdb_libs="-L${dd}/lib -l${d}" break fi done # If we found both incdir and lib, we're done if test "$dlz_bdb_libs" != "yes" then break fi # Otherwise, we're starting over dlz_bdb_inc="yes" dlz_bdb_libs="yes" done # Done searching, now make sure we got everything. if test "$dlz_bdb_inc" = "yes" then as_fn_error $? "could not find Berkeley DB include directory" "$LINENO" 5 fi if test "$dlz_bdb_libs" = "yes" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 $as_echo "not found" >&6; } as_fn_error $? "could not find Berkeley DB library" "$LINENO" 5 fi CONTRIB_DLZ="$CONTRIB_DLZ -DDLZ_BDB" for i in dlz_bdb_driver dlz_bdbhpt_driver do DLZ_DRIVER_SRCS="$DLZ_DRIVER_SRCS $dlzdir/$i.c" DLZ_DRIVER_OBJS="$DLZ_DRIVER_OBJS $i.$O" done if test -n "$dlz_bdb_inc" then DLZ_DRIVER_INCLUDES="$DLZ_DRIVER_INCLUDES $dlz_bdb_inc" fi if test -n "$dlz_bdb_libs" then DLZ_DRIVER_LIBS="$DLZ_DRIVER_LIBS $dlz_bdb_libs" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: using Berkeley DB: $dlz_bdb_inc $dlz_bdb_libs" >&5 $as_echo "using Berkeley DB: $dlz_bdb_inc $dlz_bdb_libs" >&6; } ac_config_files="$ac_config_files contrib/dlz/bin/dlzbdb/Makefile" ;; esac # # Was --with-dlz-filesystem specified? # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file system DLZ driver" >&5 $as_echo_n "checking for file system DLZ driver... " >&6; } # Check whether --with-dlz_filesystem was given. if test "${with_dlz_filesystem+set}" = set; then : withval=$with_dlz_filesystem; use_dlz_filesystem="$withval" else use_dlz_filesystem="no" fi case "$use_dlz_filesystem" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; *) CONTRIB_DLZ="$CONTRIB_DLZ -DDLZ_FILESYSTEM" for i in dlz_filesystem_driver do DLZ_DRIVER_SRCS="$DLZ_DRIVER_SRCS $dlzdir/$i.c" DLZ_DRIVER_OBJS="$DLZ_DRIVER_OBJS $i.$O" done if test -n "" then DLZ_DRIVER_INCLUDES="$DLZ_DRIVER_INCLUDES " fi if test -n "" then DLZ_DRIVER_LIBS="$DLZ_DRIVER_LIBS " fi DLZ_SYSTEM_TEST=filesystem { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ;; esac # # Was --with-dlz-ldap specified? # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LDAP DLZ driver" >&5 $as_echo_n "checking for LDAP DLZ driver... " >&6; } # Check whether --with-dlz_ldap was given. if test "${with_dlz_ldap+set}" = set; then : withval=$with_dlz_ldap; use_dlz_ldap="$withval" else use_dlz_ldap="no" fi if test "$use_dlz_ldap" = "yes" then # User did not specify a path - guess it ldapdirs="/usr /usr/local /usr/pkg" for d in $ldapdirs do if test -f $d/include/ldap.h then use_dlz_ldap=$d break fi done fi if test "$use_dlz_ldap" = "yes" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 $as_echo "not found" >&6; } as_fn_error $? "LDAP headers were not found in any of $ldapdirs; use --with-dlz-ldap=/path" "$LINENO" 5 fi case "$use_dlz_ldap" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; *) CONTRIB_DLZ="$CONTRIB_DLZ -DDLZ_LDAP" for i in dlz_ldap_driver do DLZ_DRIVER_SRCS="$DLZ_DRIVER_SRCS $dlzdir/$i.c" DLZ_DRIVER_OBJS="$DLZ_DRIVER_OBJS $i.$O" done if test -n "-I$use_dlz_ldap/include" then DLZ_DRIVER_INCLUDES="$DLZ_DRIVER_INCLUDES -I$use_dlz_ldap/include" fi if test -n "-L$use_dlz_ldap/lib -lldap -llber" then DLZ_DRIVER_LIBS="$DLZ_DRIVER_LIBS -L$use_dlz_ldap/lib -lldap -llber" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: using LDAP from $use_dlz_ldap/lib and $use_dlz_ldap/include" >&5 $as_echo "using LDAP from $use_dlz_ldap/lib and $use_dlz_ldap/include" >&6; } ;; esac # # Was --with-dlz-odbc specified? # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ODBC DLZ driver" >&5 $as_echo_n "checking for ODBC DLZ driver... " >&6; } # Check whether --with-dlz_odbc was given. if test "${with_dlz_odbc+set}" = set; then : withval=$with_dlz_odbc; use_dlz_odbc="$withval" else use_dlz_odbc="no" fi if test "$use_dlz_odbc" = "yes" then # User did not specify a path - guess it libodbc_found=no sql_h_found=no ac_fn_c_check_header_mongrel "$LINENO" "sql.h" "ac_cv_header_sql_h" "$ac_includes_default" if test "x$ac_cv_header_sql_h" = xyes; then : sql_h_found=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SQLConnect in -lodbc" >&5 $as_echo_n "checking for SQLConnect in -lodbc... " >&6; } if ${ac_cv_lib_odbc_SQLConnect+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lodbc $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 SQLConnect (); int main () { return SQLConnect (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_odbc_SQLConnect=yes else ac_cv_lib_odbc_SQLConnect=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_odbc_SQLConnect" >&5 $as_echo "$ac_cv_lib_odbc_SQLConnect" >&6; } if test "x$ac_cv_lib_odbc_SQLConnect" = xyes; then : libodbc_found=yes fi if test $libodbc_found = "yes" -o $sql_h_found = "yes" then use_dlz_odbc=system dlz_odbc_include="" dlz_odbc_libs="-lodbc" else odbcdirs="/usr /usr/local /usr/pkg" for d in $odbcdirs do if test -f $d/include/sql.h -a -f $d/lib/libodbc.a then use_dlz_odbc=$d dlz_odbc_include="-I$use_dlz_odbc/include" dlz_odbc_libs="-L$use_dlz_odbc/lib -lodbc" break fi done fi fi case "$use_dlz_odbc" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 $as_echo "not found" >&6; } as_fn_error $? "ODBC headers were not found in any of $odbcdirs; use --with-dlz-odbc=/path" "$LINENO" 5 ;; *) CONTRIB_DLZ="$CONTRIB_DLZ -DDLZ_ODBC" for i in dlz_odbc_driver do DLZ_DRIVER_SRCS="$DLZ_DRIVER_SRCS $dlzdir/$i.c" DLZ_DRIVER_OBJS="$DLZ_DRIVER_OBJS $i.$O" done if test -n "$dlz_odbc_include" then DLZ_DRIVER_INCLUDES="$DLZ_DRIVER_INCLUDES $dlz_odbc_include" fi if test -n "$dlz_odbc_libs" then DLZ_DRIVER_LIBS="$DLZ_DRIVER_LIBS $dlz_odbc_libs" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: using ODBC from $use_dlz_odbc" >&5 $as_echo "using ODBC from $use_dlz_odbc" >&6; } ;; esac # # Was --with-dlz-stub specified? # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stub DLZ driver" >&5 $as_echo_n "checking for stub DLZ driver... " >&6; } # Check whether --with-dlz_stub was given. if test "${with_dlz_stub+set}" = set; then : withval=$with_dlz_stub; use_dlz_stub="$withval" else use_dlz_stub="no" fi case "$use_dlz_stub" in no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; *) CONTRIB_DLZ="$CONTRIB_DLZ -DDLZ_STUB" for i in dlz_stub_driver do DLZ_DRIVER_SRCS="$DLZ_DRIVER_SRCS $dlzdir/$i.c" DLZ_DRIVER_OBJS="$DLZ_DRIVER_OBJS $i.$O" done if test -n "" then DLZ_DRIVER_INCLUDES="$DLZ_DRIVER_INCLUDES " fi if test -n "" then DLZ_DRIVER_LIBS="$DLZ_DRIVER_LIBS " fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ;; esac # Add any additional DLZ drivers here. # # Finally, some generic stuff that applies to all drivers, assuming # we're compiling contrib DLZ drivers at all. # if test -n "$CONTRIB_DLZ" then CONTRIB_DLZ="-DCONTRIB_DLZ $CONTRIB_DLZ" # # Where to find DLZ driver header files. # DLZ_DRIVER_INCLUDES="-I$dlzdir/include $DLZ_DRIVER_INCLUDES" # # Initialization and shutdown wrappers, helper functions. # DLZ_DRIVER_SRCS="$dlzdir/dlz_drivers.c $dlzdir/sdlz_helper.c $DLZ_DRIVER_SRCS" DLZ_DRIVER_OBJS="dlz_drivers.$O sdlz_helper.$O $DLZ_DRIVER_OBJS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking contributed DLZ drivers" >&5 $as_echo_n "checking contributed DLZ drivers... " >&6; } if test -n "$CONTRIB_DLZ" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } DLZ_DRIVER_RULES=contrib/dlz/drivers/rules ac_config_files="$ac_config_files $DLZ_DRIVER_RULES" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } DLZ_DRIVER_RULES=/dev/null fi if test "$cross_compiling" = "yes"; then if test -z "$BUILD_CC"; then as_fn_error $? "BUILD_CC not set" "$LINENO" 5 fi BUILD_CFLAGS="$BUILD_CFLAGS" BUILD_CPPFLAGS="$BUILD_CPPFLAGS" BUILD_LDFLAGS="$BUILD_LDFLAGS" BUILD_LIBS="$BUILD_LIBS" else BUILD_CC="$CC" BUILD_CFLAGS="$CFLAGS" BUILD_CPPFLAGS="$CPPFLAGS $GEN_NEED_OPTARG" BUILD_LDFLAGS="$LDFLAGS" BUILD_LIBS="$LIBS" fi NEWFLAGS="" for e in $BUILD_LDFLAGS ; do case $e in -L*) case $host_os in netbsd*) ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; freebsd*) ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; solaris*) ee=`echo $e | sed -e 's%^-L%-R%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; *) NEWFLAGS="$NEWFLAGS $e" ;; esac ;; *) NEWFLAGS="$NEWFLAGS $e" ;; esac done BUILD_LDFLAGS="$NEWFLAGS" NEWFLAGS="" for e in $DNS_GSSAPI_LIBS ; do case $e in -L*) case $host_os in netbsd*) ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; freebsd*) ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; solaris*) ee=`echo $e | sed -e 's%^-L%-R%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; *) NEWFLAGS="$NEWFLAGS $e" ;; esac ;; *) NEWFLAGS="$NEWFLAGS $e" ;; esac done DNS_GSSAPI_LIBS="$NEWFLAGS" NEWFLAGS="" for e in $ISC_OPENSSL_LIBS ; do case $e in -L*) case $host_os in netbsd*) ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; freebsd*) ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; solaris*) ee=`echo $e | sed -e 's%^-L%-R%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; *) NEWFLAGS="$NEWFLAGS $e" ;; esac ;; *) NEWFLAGS="$NEWFLAGS $e" ;; esac done ISC_OPENSSL_LIBS="$NEWFLAGS" NEWFLAGS="" for e in $DNS_CRYPTO_LIBS ; do case $e in -L*) case $host_os in netbsd*) ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; freebsd*) ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; solaris*) ee=`echo $e | sed -e 's%^-L%-R%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; *) NEWFLAGS="$NEWFLAGS $e" ;; esac ;; *) NEWFLAGS="$NEWFLAGS $e" ;; esac done DNS_CRYPTO_LIBS="$NEWFLAGS" # # Commands to run at the end of config.status. # Don't just put these into configure, it won't work right if somebody # runs config.status directly (which autoconf allows). # ac_config_commands="$ac_config_commands chmod" # # Files to configure. These are listed here because we used to # specify them as arguments to AC_OUTPUT. It's (now) ok to move these # elsewhere if there's a good reason for doing so. # ac_config_files="$ac_config_files make/Makefile make/mkdep Makefile bin/Makefile bin/check/Makefile bin/confgen/Makefile bin/confgen/unix/Makefile bin/delv/Makefile bin/dig/Makefile bin/dnssec/Makefile bin/named/Makefile bin/named/unix/Makefile bin/nsupdate/Makefile bin/pkcs11/Makefile bin/python/Makefile bin/python/dnssec-checkds.py bin/python/dnssec-coverage.py bin/rndc/Makefile bin/tests/Makefile bin/tests/atomic/Makefile bin/tests/db/Makefile bin/tests/dst/Makefile bin/tests/dst/Kdh.+002+18602.key bin/tests/dst/Kdh.+002+18602.private bin/tests/dst/Kdh.+002+48957.key bin/tests/dst/Kdh.+002+48957.private bin/tests/dst/Ktest.+001+00002.key bin/tests/dst/Ktest.+001+54622.key bin/tests/dst/Ktest.+001+54622.private bin/tests/dst/Ktest.+003+23616.key bin/tests/dst/Ktest.+003+23616.private bin/tests/dst/Ktest.+003+49667.key bin/tests/dst/dst_2_data bin/tests/dst/t2_data_1 bin/tests/dst/t2_data_2 bin/tests/dst/t2_dsasig bin/tests/dst/t2_rsasig bin/tests/hashes/Makefile bin/tests/headerdep_test.sh bin/tests/master/Makefile bin/tests/mem/Makefile bin/tests/names/Makefile bin/tests/net/Makefile bin/tests/pkcs11/Makefile bin/tests/pkcs11/benchmarks/Makefile bin/tests/rbt/Makefile bin/tests/resolver/Makefile bin/tests/sockaddr/Makefile bin/tests/system/Makefile bin/tests/system/conf.sh bin/tests/system/builtin/Makefile bin/tests/system/dlz/prereq.sh bin/tests/system/dlzexternal/Makefile bin/tests/system/dlzexternal/ns1/named.conf bin/tests/system/dlzredir/prereq.sh bin/tests/system/fetchlimit/Makefile bin/tests/system/filter-aaaa/Makefile bin/tests/system/geoip/Makefile bin/tests/system/inline/checkdsa.sh bin/tests/system/lwresd/Makefile bin/tests/system/rpz/Makefile bin/tests/system/rsabigexponent/Makefile bin/tests/system/sit/prereq.sh bin/tests/system/statistics/Makefile bin/tests/system/tkey/Makefile bin/tests/system/tsiggss/Makefile bin/tests/tasks/Makefile bin/tests/timers/Makefile bin/tests/virtual-time/Makefile bin/tests/virtual-time/conf.sh bin/tools/Makefile contrib/scripts/check-secure-delegation.pl contrib/scripts/zone-edit.sh doc/Makefile doc/arm/Makefile doc/doxygen/Doxyfile doc/doxygen/Makefile doc/doxygen/doxygen-input-filter doc/misc/Makefile doc/xsl/Makefile doc/xsl/isc-docbook-chunk.xsl doc/xsl/isc-docbook-html.xsl doc/xsl/isc-docbook-latex.xsl doc/xsl/isc-manpage.xsl doc/xsl/isc-notes-html.xsl doc/xsl/isc-notes-latex.xsl isc-config.sh lib/Makefile lib/bind9/Makefile lib/bind9/include/Makefile lib/bind9/include/bind9/Makefile lib/dns/Makefile lib/dns/include/Makefile lib/dns/include/dns/Makefile lib/dns/include/dst/Makefile lib/dns/tests/Makefile lib/irs/Makefile lib/irs/include/Makefile lib/irs/include/irs/Makefile lib/irs/include/irs/netdb.h lib/irs/include/irs/platform.h lib/isc/$arch/Makefile lib/isc/$arch/include/Makefile lib/isc/$arch/include/isc/Makefile lib/isc/$thread_dir/Makefile lib/isc/$thread_dir/include/Makefile lib/isc/$thread_dir/include/isc/Makefile lib/isc/Makefile lib/isc/include/Makefile lib/isc/include/isc/Makefile lib/isc/include/isc/platform.h lib/isc/include/pk11/Makefile lib/isc/include/pkcs11/Makefile lib/isc/tests/Makefile lib/isc/nls/Makefile lib/isc/unix/Makefile lib/isc/unix/include/Makefile lib/isc/unix/include/isc/Makefile lib/isc/unix/include/pkcs11/Makefile lib/isccc/Makefile lib/isccc/include/Makefile lib/isccc/include/isccc/Makefile lib/isccfg/Makefile lib/isccfg/include/Makefile lib/isccfg/include/isccfg/Makefile lib/lwres/Makefile lib/lwres/include/Makefile lib/lwres/include/lwres/Makefile lib/lwres/include/lwres/netdb.h lib/lwres/include/lwres/platform.h lib/lwres/man/Makefile lib/lwres/tests/Makefile lib/lwres/unix/Makefile lib/lwres/unix/include/Makefile lib/lwres/unix/include/lwres/Makefile lib/tests/Makefile lib/tests/include/Makefile lib/tests/include/tests/Makefile lib/samples/Makefile lib/samples/Makefile-postinstall unit/Makefile unit/unittest.sh" # # Do it # cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by BIND $as_me 9.10, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to . BIND home page: ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ BIND config.status 9.10 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ nm_file_list_spec \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ sys_lib_dlsearch_path_spec; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' xsi_shell='$xsi_shell' lt_shell_append='$lt_shell_append' # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile' atfdir=`pwd`/unit/atf _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "make/rules") CONFIG_FILES="$CONFIG_FILES make/rules" ;; "make/includes") CONFIG_FILES="$CONFIG_FILES make/includes" ;; "atf-config") CONFIG_COMMANDS="$CONFIG_COMMANDS atf-config" ;; "contrib/dlz/bin/dlzbdb/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/dlz/bin/dlzbdb/Makefile" ;; "$DLZ_DRIVER_RULES") CONFIG_FILES="$CONFIG_FILES $DLZ_DRIVER_RULES" ;; "chmod") CONFIG_COMMANDS="$CONFIG_COMMANDS chmod" ;; "make/Makefile") CONFIG_FILES="$CONFIG_FILES make/Makefile" ;; "make/mkdep") CONFIG_FILES="$CONFIG_FILES make/mkdep" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "bin/Makefile") CONFIG_FILES="$CONFIG_FILES bin/Makefile" ;; "bin/check/Makefile") CONFIG_FILES="$CONFIG_FILES bin/check/Makefile" ;; "bin/confgen/Makefile") CONFIG_FILES="$CONFIG_FILES bin/confgen/Makefile" ;; "bin/confgen/unix/Makefile") CONFIG_FILES="$CONFIG_FILES bin/confgen/unix/Makefile" ;; "bin/delv/Makefile") CONFIG_FILES="$CONFIG_FILES bin/delv/Makefile" ;; "bin/dig/Makefile") CONFIG_FILES="$CONFIG_FILES bin/dig/Makefile" ;; "bin/dnssec/Makefile") CONFIG_FILES="$CONFIG_FILES bin/dnssec/Makefile" ;; "bin/named/Makefile") CONFIG_FILES="$CONFIG_FILES bin/named/Makefile" ;; "bin/named/unix/Makefile") CONFIG_FILES="$CONFIG_FILES bin/named/unix/Makefile" ;; "bin/nsupdate/Makefile") CONFIG_FILES="$CONFIG_FILES bin/nsupdate/Makefile" ;; "bin/pkcs11/Makefile") CONFIG_FILES="$CONFIG_FILES bin/pkcs11/Makefile" ;; "bin/python/Makefile") CONFIG_FILES="$CONFIG_FILES bin/python/Makefile" ;; "bin/python/dnssec-checkds.py") CONFIG_FILES="$CONFIG_FILES bin/python/dnssec-checkds.py" ;; "bin/python/dnssec-coverage.py") CONFIG_FILES="$CONFIG_FILES bin/python/dnssec-coverage.py" ;; "bin/rndc/Makefile") CONFIG_FILES="$CONFIG_FILES bin/rndc/Makefile" ;; "bin/tests/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/Makefile" ;; "bin/tests/atomic/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/atomic/Makefile" ;; "bin/tests/db/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/db/Makefile" ;; "bin/tests/dst/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/dst/Makefile" ;; "bin/tests/dst/Kdh.+002+18602.key") CONFIG_FILES="$CONFIG_FILES bin/tests/dst/Kdh.+002+18602.key" ;; "bin/tests/dst/Kdh.+002+18602.private") CONFIG_FILES="$CONFIG_FILES bin/tests/dst/Kdh.+002+18602.private" ;; "bin/tests/dst/Kdh.+002+48957.key") CONFIG_FILES="$CONFIG_FILES bin/tests/dst/Kdh.+002+48957.key" ;; "bin/tests/dst/Kdh.+002+48957.private") CONFIG_FILES="$CONFIG_FILES bin/tests/dst/Kdh.+002+48957.private" ;; "bin/tests/dst/Ktest.+001+00002.key") CONFIG_FILES="$CONFIG_FILES bin/tests/dst/Ktest.+001+00002.key" ;; "bin/tests/dst/Ktest.+001+54622.key") CONFIG_FILES="$CONFIG_FILES bin/tests/dst/Ktest.+001+54622.key" ;; "bin/tests/dst/Ktest.+001+54622.private") CONFIG_FILES="$CONFIG_FILES bin/tests/dst/Ktest.+001+54622.private" ;; "bin/tests/dst/Ktest.+003+23616.key") CONFIG_FILES="$CONFIG_FILES bin/tests/dst/Ktest.+003+23616.key" ;; "bin/tests/dst/Ktest.+003+23616.private") CONFIG_FILES="$CONFIG_FILES bin/tests/dst/Ktest.+003+23616.private" ;; "bin/tests/dst/Ktest.+003+49667.key") CONFIG_FILES="$CONFIG_FILES bin/tests/dst/Ktest.+003+49667.key" ;; "bin/tests/dst/dst_2_data") CONFIG_FILES="$CONFIG_FILES bin/tests/dst/dst_2_data" ;; "bin/tests/dst/t2_data_1") CONFIG_FILES="$CONFIG_FILES bin/tests/dst/t2_data_1" ;; "bin/tests/dst/t2_data_2") CONFIG_FILES="$CONFIG_FILES bin/tests/dst/t2_data_2" ;; "bin/tests/dst/t2_dsasig") CONFIG_FILES="$CONFIG_FILES bin/tests/dst/t2_dsasig" ;; "bin/tests/dst/t2_rsasig") CONFIG_FILES="$CONFIG_FILES bin/tests/dst/t2_rsasig" ;; "bin/tests/hashes/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/hashes/Makefile" ;; "bin/tests/headerdep_test.sh") CONFIG_FILES="$CONFIG_FILES bin/tests/headerdep_test.sh" ;; "bin/tests/master/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/master/Makefile" ;; "bin/tests/mem/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/mem/Makefile" ;; "bin/tests/names/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/names/Makefile" ;; "bin/tests/net/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/net/Makefile" ;; "bin/tests/pkcs11/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/pkcs11/Makefile" ;; "bin/tests/pkcs11/benchmarks/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/pkcs11/benchmarks/Makefile" ;; "bin/tests/rbt/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/rbt/Makefile" ;; "bin/tests/resolver/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/resolver/Makefile" ;; "bin/tests/sockaddr/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/sockaddr/Makefile" ;; "bin/tests/system/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/Makefile" ;; "bin/tests/system/conf.sh") CONFIG_FILES="$CONFIG_FILES bin/tests/system/conf.sh" ;; "bin/tests/system/builtin/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/builtin/Makefile" ;; "bin/tests/system/dlz/prereq.sh") CONFIG_FILES="$CONFIG_FILES bin/tests/system/dlz/prereq.sh" ;; "bin/tests/system/dlzexternal/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/dlzexternal/Makefile" ;; "bin/tests/system/dlzexternal/ns1/named.conf") CONFIG_FILES="$CONFIG_FILES bin/tests/system/dlzexternal/ns1/named.conf" ;; "bin/tests/system/dlzredir/prereq.sh") CONFIG_FILES="$CONFIG_FILES bin/tests/system/dlzredir/prereq.sh" ;; "bin/tests/system/fetchlimit/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/fetchlimit/Makefile" ;; "bin/tests/system/filter-aaaa/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/filter-aaaa/Makefile" ;; "bin/tests/system/geoip/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/geoip/Makefile" ;; "bin/tests/system/inline/checkdsa.sh") CONFIG_FILES="$CONFIG_FILES bin/tests/system/inline/checkdsa.sh" ;; "bin/tests/system/lwresd/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/lwresd/Makefile" ;; "bin/tests/system/rpz/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/rpz/Makefile" ;; "bin/tests/system/rsabigexponent/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/rsabigexponent/Makefile" ;; "bin/tests/system/sit/prereq.sh") CONFIG_FILES="$CONFIG_FILES bin/tests/system/sit/prereq.sh" ;; "bin/tests/system/statistics/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/statistics/Makefile" ;; "bin/tests/system/tkey/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/tkey/Makefile" ;; "bin/tests/system/tsiggss/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/tsiggss/Makefile" ;; "bin/tests/tasks/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/tasks/Makefile" ;; "bin/tests/timers/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/timers/Makefile" ;; "bin/tests/virtual-time/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/virtual-time/Makefile" ;; "bin/tests/virtual-time/conf.sh") CONFIG_FILES="$CONFIG_FILES bin/tests/virtual-time/conf.sh" ;; "bin/tools/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tools/Makefile" ;; "contrib/scripts/check-secure-delegation.pl") CONFIG_FILES="$CONFIG_FILES contrib/scripts/check-secure-delegation.pl" ;; "contrib/scripts/zone-edit.sh") CONFIG_FILES="$CONFIG_FILES contrib/scripts/zone-edit.sh" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "doc/arm/Makefile") CONFIG_FILES="$CONFIG_FILES doc/arm/Makefile" ;; "doc/doxygen/Doxyfile") CONFIG_FILES="$CONFIG_FILES doc/doxygen/Doxyfile" ;; "doc/doxygen/Makefile") CONFIG_FILES="$CONFIG_FILES doc/doxygen/Makefile" ;; "doc/doxygen/doxygen-input-filter") CONFIG_FILES="$CONFIG_FILES doc/doxygen/doxygen-input-filter" ;; "doc/misc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/misc/Makefile" ;; "doc/xsl/Makefile") CONFIG_FILES="$CONFIG_FILES doc/xsl/Makefile" ;; "doc/xsl/isc-docbook-chunk.xsl") CONFIG_FILES="$CONFIG_FILES doc/xsl/isc-docbook-chunk.xsl" ;; "doc/xsl/isc-docbook-html.xsl") CONFIG_FILES="$CONFIG_FILES doc/xsl/isc-docbook-html.xsl" ;; "doc/xsl/isc-docbook-latex.xsl") CONFIG_FILES="$CONFIG_FILES doc/xsl/isc-docbook-latex.xsl" ;; "doc/xsl/isc-manpage.xsl") CONFIG_FILES="$CONFIG_FILES doc/xsl/isc-manpage.xsl" ;; "doc/xsl/isc-notes-html.xsl") CONFIG_FILES="$CONFIG_FILES doc/xsl/isc-notes-html.xsl" ;; "doc/xsl/isc-notes-latex.xsl") CONFIG_FILES="$CONFIG_FILES doc/xsl/isc-notes-latex.xsl" ;; "isc-config.sh") CONFIG_FILES="$CONFIG_FILES isc-config.sh" ;; "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;; "lib/bind9/Makefile") CONFIG_FILES="$CONFIG_FILES lib/bind9/Makefile" ;; "lib/bind9/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/bind9/include/Makefile" ;; "lib/bind9/include/bind9/Makefile") CONFIG_FILES="$CONFIG_FILES lib/bind9/include/bind9/Makefile" ;; "lib/dns/Makefile") CONFIG_FILES="$CONFIG_FILES lib/dns/Makefile" ;; "lib/dns/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/dns/include/Makefile" ;; "lib/dns/include/dns/Makefile") CONFIG_FILES="$CONFIG_FILES lib/dns/include/dns/Makefile" ;; "lib/dns/include/dst/Makefile") CONFIG_FILES="$CONFIG_FILES lib/dns/include/dst/Makefile" ;; "lib/dns/tests/Makefile") CONFIG_FILES="$CONFIG_FILES lib/dns/tests/Makefile" ;; "lib/irs/Makefile") CONFIG_FILES="$CONFIG_FILES lib/irs/Makefile" ;; "lib/irs/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/irs/include/Makefile" ;; "lib/irs/include/irs/Makefile") CONFIG_FILES="$CONFIG_FILES lib/irs/include/irs/Makefile" ;; "lib/irs/include/irs/netdb.h") CONFIG_FILES="$CONFIG_FILES lib/irs/include/irs/netdb.h" ;; "lib/irs/include/irs/platform.h") CONFIG_FILES="$CONFIG_FILES lib/irs/include/irs/platform.h" ;; "lib/isc/$arch/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isc/$arch/Makefile" ;; "lib/isc/$arch/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isc/$arch/include/Makefile" ;; "lib/isc/$arch/include/isc/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isc/$arch/include/isc/Makefile" ;; "lib/isc/$thread_dir/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isc/$thread_dir/Makefile" ;; "lib/isc/$thread_dir/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isc/$thread_dir/include/Makefile" ;; "lib/isc/$thread_dir/include/isc/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isc/$thread_dir/include/isc/Makefile" ;; "lib/isc/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isc/Makefile" ;; "lib/isc/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isc/include/Makefile" ;; "lib/isc/include/isc/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isc/include/isc/Makefile" ;; "lib/isc/include/isc/platform.h") CONFIG_FILES="$CONFIG_FILES lib/isc/include/isc/platform.h" ;; "lib/isc/include/pk11/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isc/include/pk11/Makefile" ;; "lib/isc/include/pkcs11/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isc/include/pkcs11/Makefile" ;; "lib/isc/tests/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isc/tests/Makefile" ;; "lib/isc/nls/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isc/nls/Makefile" ;; "lib/isc/unix/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isc/unix/Makefile" ;; "lib/isc/unix/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isc/unix/include/Makefile" ;; "lib/isc/unix/include/isc/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isc/unix/include/isc/Makefile" ;; "lib/isc/unix/include/pkcs11/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isc/unix/include/pkcs11/Makefile" ;; "lib/isccc/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isccc/Makefile" ;; "lib/isccc/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isccc/include/Makefile" ;; "lib/isccc/include/isccc/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isccc/include/isccc/Makefile" ;; "lib/isccfg/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isccfg/Makefile" ;; "lib/isccfg/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isccfg/include/Makefile" ;; "lib/isccfg/include/isccfg/Makefile") CONFIG_FILES="$CONFIG_FILES lib/isccfg/include/isccfg/Makefile" ;; "lib/lwres/Makefile") CONFIG_FILES="$CONFIG_FILES lib/lwres/Makefile" ;; "lib/lwres/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/lwres/include/Makefile" ;; "lib/lwres/include/lwres/Makefile") CONFIG_FILES="$CONFIG_FILES lib/lwres/include/lwres/Makefile" ;; "lib/lwres/include/lwres/netdb.h") CONFIG_FILES="$CONFIG_FILES lib/lwres/include/lwres/netdb.h" ;; "lib/lwres/include/lwres/platform.h") CONFIG_FILES="$CONFIG_FILES lib/lwres/include/lwres/platform.h" ;; "lib/lwres/man/Makefile") CONFIG_FILES="$CONFIG_FILES lib/lwres/man/Makefile" ;; "lib/lwres/tests/Makefile") CONFIG_FILES="$CONFIG_FILES lib/lwres/tests/Makefile" ;; "lib/lwres/unix/Makefile") CONFIG_FILES="$CONFIG_FILES lib/lwres/unix/Makefile" ;; "lib/lwres/unix/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/lwres/unix/include/Makefile" ;; "lib/lwres/unix/include/lwres/Makefile") CONFIG_FILES="$CONFIG_FILES lib/lwres/unix/include/lwres/Makefile" ;; "lib/tests/Makefile") CONFIG_FILES="$CONFIG_FILES lib/tests/Makefile" ;; "lib/tests/include/Makefile") CONFIG_FILES="$CONFIG_FILES lib/tests/include/Makefile" ;; "lib/tests/include/tests/Makefile") CONFIG_FILES="$CONFIG_FILES lib/tests/include/tests/Makefile" ;; "lib/samples/Makefile") CONFIG_FILES="$CONFIG_FILES lib/samples/Makefile" ;; "lib/samples/Makefile-postinstall") CONFIG_FILES="$CONFIG_FILES lib/samples/Makefile-postinstall" ;; "unit/Makefile") CONFIG_FILES="$CONFIG_FILES unit/Makefile" ;; "unit/unittest.sh") CONFIG_FILES="$CONFIG_FILES unit/unittest.sh" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then if $AWK 'BEGIN { getline <"/dev/null" }' /dev/null; then ac_cs_awk_getline=: ac_cs_awk_pipe_init= ac_cs_awk_read_file=' while ((getline aline < (F[key])) > 0) print(aline) close(F[key])' ac_cs_awk_pipe_fini= else ac_cs_awk_getline=false ac_cs_awk_pipe_init="print \"cat <<'|#_!!_#|' &&\"" ac_cs_awk_read_file=' print "|#_!!_#|" print "cat " F[key] " &&" '$ac_cs_awk_pipe_init # The final `:' finishes the AND list. ac_cs_awk_pipe_fini='END { print "|#_!!_#|"; print ":" }' fi ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF # Create commands to substitute file output variables. { echo "cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1" && echo 'cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&' && echo "$ac_subst_files" | sed 's/.*/F["&"]="$&"/' && echo "_ACAWK" && echo "_ACEOF" } >conf$$files.sh && . ./conf$$files.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 rm -f conf$$files.sh { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" \$ac_cs_awk_pipe_init } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } if (nfields == 3 && !substed) { key = field[2] if (F[key] != "" && line ~ /^[ ]*@.*@[ ]*$/) { \$ac_cs_awk_read_file next } } print line } \$ac_cs_awk_pipe_fini _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | if $ac_cs_awk_getline; then $AWK -f "$ac_tmp/subs.awk" else $AWK -f "$ac_tmp/subs.awk" | $SHELL fi \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "libtool":C) # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # The names of the tagged configurations supported by this script. available_tags="" # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and in which our libraries should be installed. lt_sysroot=$lt_sysroot # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain="$ac_aux_dir/ltmain.sh" # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) if test x"$xsi_shell" = xyes; then sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ func_dirname ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ } # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_basename ()$/,/^} # func_basename /c\ func_basename ()\ {\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ func_dirname_and_basename ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ func_stripname ()\ {\ \ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ \ # positional parameters, so assign one to ordinary parameter first.\ \ func_stripname_result=${3}\ \ func_stripname_result=${func_stripname_result#"${1}"}\ \ func_stripname_result=${func_stripname_result%"${2}"}\ } # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ func_split_long_opt ()\ {\ \ func_split_long_opt_name=${1%%=*}\ \ func_split_long_opt_arg=${1#*=}\ } # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ func_split_short_opt ()\ {\ \ func_split_short_opt_arg=${1#??}\ \ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ } # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ func_lo2o ()\ {\ \ case ${1} in\ \ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ \ *) func_lo2o_result=${1} ;;\ \ esac\ } # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_xform ()$/,/^} # func_xform /c\ func_xform ()\ {\ func_xform_result=${1%.*}.lo\ } # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_arith ()$/,/^} # func_arith /c\ func_arith ()\ {\ func_arith_result=$(( $* ))\ } # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_len ()$/,/^} # func_len /c\ func_len ()\ {\ func_len_result=${#1}\ } # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$lt_shell_append" = xyes; then sed -e '/^func_append ()$/,/^} # func_append /c\ func_append ()\ {\ eval "${1}+=\\${2}"\ } # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ func_append_quoted ()\ {\ \ func_quote_for_eval "${2}"\ \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ } # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 $as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} fi mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ;; "atf-config":C) ( mkdir -p unit/atf-src; cd unit/atf-src; case "$srcdir" in /*) ;; *) srcdir="../../$srcdir";; esac ${SHELL} "${srcdir}${srcdir:+/unit/atf-src/}./configure" --enable-tools --disable-shared MISSING=: --prefix $atfdir; ) ;; "chmod":C) chmod a+x isc-config.sh doc/doxygen/doxygen-input-filter ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi # # Now that the Makefiles exist we can ensure that everything is rebuilt. # # Check whether --with-make-clean was given. if test "${with_make_clean+set}" = set; then : withval=$with_make_clean; make_clean="$withval" else make_clean="yes" fi case "$make_clean" in yes) make clean ;; esac # Check whether --enable-full-report was given. if test "${enable_full_report+set}" = set; then : enableval=$enable_full_report; fi echo "========================================================================" echo "Configuration summary:" echo "------------------------------------------------------------------------" echo "Optional features enabled:" if $use_threads; then echo " Multiprocessing support (--enable-threads)" if test "$enable_full_report" = "yes" -o "$locktype" = "standard"; then echo " Mutex lock type: $locktype" fi fi test "$use_tuning" = "large" && echo " Large-system tuning (--with-tuning)" test "$use_geoip" = "no" || echo " GeoIP access control (--with-geoip)" test "$use_gssapi" = "no" || echo " GSS-API (--with-gssapi)" test "$enable_fetchlimit" = "yes" && \ echo " Recursive fetch limits for DoS attack mitigation (--enable-fetchlimit)" if test "$enable_sit" != "no"; then echo " Source Identity Token support (--enable-sit)" if test "$enable_full_report" = "yes" -o "$with_sit_alg" != "aes"; then echo " Algorithm: $with_sit_alg" fi fi # these lines are only printed if run with --enable-full-report if test "$enable_full_report" = "yes"; then test "$enable_ipv6" = "no" -o "$found_ipv6" = "no" || \ echo " IPv6 support (--enable-ipv6)" test "X$CRYPTO" = "X" -o "$want_native_pkcs11" = "yes" || \ echo " OpenSSL cryptography/DNSSEC (--with-openssl)" test "X$PYTHON" = "X" || echo " Python tools (--with-python)" test "X$libxml2_libs" = "X" || echo " XML statistics (--with-libxml2)" test "X$have_libjson" = "X" || echo " JSON statistics (--with-libjson)" fi if test "$use_pkcs11" != "no"; then if test "$want_native_pkcs11" = "yes"; then echo " Native PKCS#11/Cryptoki support (--enable-native-pkcs11)" else echo " PKCS#11/Cryptoki support using OpenSSL (--with-pkcs11)" fi echo " Provider library: $PKCS11_PROVIDER" fi if test "$OPENSSL_GOST" = "yes" -o "$PKCS11_GOST" = "yes"; then echo " GOST algorithm support (encoding: $gosttype) (--with-gost)" fi test "$OPENSSL_ECDSA" = "yes" -o "$PKCS11_ECDSA" = "yes" && \ echo " ECDSA algorithm support (--with-ecdsa)" test "$enable_fixed" = "yes" && \ echo " Allow 'fixed' rrset-order (--enable-fixed-rrset)" test "$enable_filter" = "yes" && \ echo " AAAA filtering (--enable-filter-aaaa)" test "$enable_seccomp" = yes && \ echo " Use libseccomp system call filtering (--enable-seccomp)" test "$want_backtrace" = "yes" && \ echo " Print backtrace on crash (--enable-backtrace)" test "$want_symtable" = "minimal" && \ echo " Use symbol table for backtrace, named only (--enable-symtable)" test "$want_symtable" = "yes" -o "$want_symtable" = "all" && \ echo " Use symbol table for backtrace, all binaries (--enable-symtable=all)" test "$use_libtool" = "no" || echo " Use GNU libtool (--with-libtool)" test "$want_querytrace" = "yes" && \ echo " Very verbose query trace logging (--enable-querytrace)" test "$atf" = "no" || echo " Automated Testing Framework (--with-atf)" echo " Dynamically loadable zone (DLZ) drivers:" test "$use_dlz_bdb" = "no" || \ echo " Berkeley DB (--with-dlz-bdb)" test "$use_dlz_ldap" = "no" || \ echo " LDAP (--with-dlz-ldap)" test "$use_dlz_mysql" = "no" || \ echo " MySQL (--with-dlz-mysql)" test "$use_dlz_odbc" = "no" || \ echo " ODBC (--with-dlz-odbc)" test "$use_dlz_postgres" = "no" || \ echo " Postgres (--with-dlz-postgres)" test "$use_dlz_filesystem" = "no" || \ echo " Filesystem (--with-dlz-filesystem)" test "$use_dlz_stub" = "no" || \ echo " Stub (--with-dlz-stub)" test "$use_dlz_bdb $use_dlz_ldap $use_dlz_mysql $use_dlz_odbc $use_dlz_postgres $use_dlz_filesystem $use_dlz_stub" = "no no no no no no no" && echo " None" echo echo "Features disabled or unavailable on this platform:" $use_threads || echo " Multiprocessing support (--enable-threads)" test "$enable_ipv6" = "no" -o "$found_ipv6" = "no" && \ echo " IPv6 support (--enable-ipv6)" test "$use_tuning" = "large" || echo " Large-system tuning (--with-tuning)" test "$use_geoip" = "no" && echo " GeoIP access control (--with-geoip)" test "$use_gssapi" = "no" && echo " GSS-API (--with-gssapi)" test "$enable_fetchlimit" = "no" && \ echo " Recursive fetch limits for DoS attack mitigation (--enable-fetchlimit)" test "$enable_sit" = "no" && echo " Source Identity Token support (--enable-sit)" test "$enable_fixed" = "yes" || \ echo " Allow 'fixed' rrset-order (--enable-fixed-rrset)" if test "X$CRYPTO" = "X" -o "$want_native_pkcs11" = "yes" then echo " OpenSSL cryptography/DNSSEC (--with-openssl)" elif test "$use_pkcs11" = "no"; then echo " PKCS#11/Cryptoki support (--with-pkcs11)" fi test "$want_native_pkcs11" = "yes" || echo " Native PKCS#11/Cryptoki support (--enable-native-pkcs11)" test "X$CRYPTO" = "X" -o "$OPENSSL_GOST" = "yes" -o "$PKCS11_GOST" = "yes" || \ echo " GOST algorithm support (--with-gost)" test "X$CRYPTO" = "X" -o "$OPENSSL_ECDSA" = "yes" -o "$PKCS11_ECDSA" = "yes" || \ echo " ECDSA algorithm support (--with-ecdsa)" test "$enable_seccomp" = yes || \ echo " Use libseccomp system call filtering (--enable-seccomp)" test "$want_backtrace" = "yes" || \ echo " Print backtrace on crash (--enable-backtrace)" test "$want_querytrace" = "yes" || \ echo " Very verbose query trace logging (--enable-querytrace)" test "$use_libtool" = "yes" || echo " Use GNU libtool (--with-libtool)" test "$atf" = "no" && echo " Automated Testing Framework (--with-atf)" test "X$PYTHON" = "X" && echo " Python tools (--with-python)" test "X$libxml2_libs" = "X" && echo " XML statistics (--with-libxml2)" test "X$have_libjson" = "X" && echo " JSON statistics (--with-libjson)" if test "X$ac_unrecognized_opts" != "X"; then echo echo "Unrecognized options:" echo " $ac_unrecognized_opts" fi echo "========================================================================" if test "X$CRYPTO" = "X"; then cat << \EOF BIND 9 is being built without cryptography support. This means it will not have DNSSEC support. Use --with-openssl, or --with-pkcs11 and --enable-native-pkcs11 to enable cryptography. EOF fi if test "X$OPENSSL_WARNING" != "X"; then cat << \EOF WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING Your OpenSSL crypto library may be vulnerable to WARNING WARNING one or more of the the following known security WARNING WARNING flaws: WARNING WARNING WARNING WARNING CAN-2002-0659, CAN-2006-4339, CVE-2006-2937, WARNING WARNING CVE-2006-2940 and CVE-2015-3193. WARNING WARNING WARNING WARNING It is recommended that you upgrade to OpenSSL WARNING WARNING version 1.0.2e/1.0.1/1.0.0/0.9.9/0.9.8d/0.9.7l WARNING WARNING (or greater). WARNING WARNING WARNING WARNING You can disable this warning by specifying: WARNING WARNING WARNING WARNING --disable-openssl-version-check WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING EOF fi # Tell Emacs to edit this file in shell mode. # Local Variables: # mode: sh # End: bind9-9.10.3.dfsg.P4/Atffile0000644000470500017500000000013012664710322014660 0ustar lamontlamontContent-Type: application/X-atf-atffile; version="1" prop: test-suite = bind9 tp: lib bind9-9.10.3.dfsg.P4/isc-config.sh.docbook0000644000470500017500000001140612664710322017367 0ustar lamontlamont]> February 18, 2009 isc-config.sh 1 BIND9 2009 2014 Internet Systems Consortium, Inc. ("ISC") isc-config.sh Get information about the installed version of ISC BIND isc-config.sh libraries DESCRIPTION isc-config.sh prints information related to the installed version of ISC BIND, such as the compiler and linker flags required to compile and link programs that use ISC BIND libraries. The optional libraries are used to report specific details for compiling and linking for the listed libraries. The allowed choices are: , , , , , and . Multiple libraries may be listed on the command line. (Some libraries require other libraries, so are implied.) OPTIONS --cflags Prints the compiler command line options required to compile files that use ISC BIND. Use the command line argument(s) to print additional specific flags to pass to the C compiler. --exec-prefix Prints the directory prefix used in the ISC BIND installation for architecture dependent files to standard output. --libs Prints the linker command line options used to link with the ISC BIND libraries. Use the command line argument(s) to print additional specific flags. --prefix Prints the directory prefix used in the ISC BIND installation for architecture independent files to standard output. --version Prints the version of the installed ISC BIND suite. RETURN VALUES isc-config.sh returns an exit status of 1 if invoked with invalid arguments or no arguments at all. It returns 0 if information was successfully printed. AUTHOR Internet Systems Consortium bind9-9.10.3.dfsg.P4/configure.in0000644000470500017500000037716512664710322015725 0ustar lamontlamont# Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2003 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # Copyright (C) 1998-2003 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. dnl AC_DIVERT_PUSH(1)dnl esyscmd([sed -e 's/^/# /' -e '/Portions of this code/,$d' COPYRIGHT])dnl AC_DIVERT_POP()dnl AC_INIT(BIND, [9.10], [bind9-bugs@isc.org], [], [https://www.isc.org/downloads/BIND/]) AC_PREREQ(2.59) AC_CONFIG_HEADER(config.h) AC_CONFIG_MACRO_DIR([libtool.m4]) AC_CANONICAL_HOST AC_PROG_MAKE_SET # # GNU libtool support # case $build_os in sunos*) # Just set the maximum command line length for sunos as it otherwise # takes a exceptionally long time to work it out. Required for libtool. lt_cv_sys_max_cmd_len=4096; ;; esac AC_PROG_LIBTOOL AC_PROG_INSTALL AC_PROG_LN_S AC_SUBST(STD_CINCLUDES) AC_SUBST(STD_CDEFINES) AC_SUBST(STD_CWARNINGS) AC_SUBST(CCOPT) AC_SUBST(CCNOOPT) AC_SUBST(BACKTRACECFLAGS) # Warn if the user specified libbind, which is now deprecated AC_ARG_ENABLE(libbind, [ --enable-libbind deprecated]) case "$enable_libbind" in yes) AC_MSG_ERROR(['libbind' is no longer part of the BIND 9 distribution. It is available from http://www.isc.org as a separate download.]) ;; no|'') ;; esac AC_ARG_ENABLE(warn_shadow, [ --enable-warn-shadow turn on -Wshadow when compiling]) AC_ARG_ENABLE(warn_error, [ --enable-warn-error turn on -Werror when compiling]) AC_ARG_ENABLE(developer, [ --enable-developer enable developer build settings]) case "$enable_developer" in yes) STD_CDEFINES="$STD_CDEFINES -DISC_LIST_CHECKINIT=1" test "${enable_fixed_rrset+set}" = set || enable_fixed_rrset=yes test "${enable_querytrace+set}" = set || enable_querytrace=yes test "${with_atf+set}" = set || with_atf=yes test "${enable_filter_aaaa+set}" = set || enable_filter_aaaa=yes test "${with_dlz_filesystem+set}" = set || with_dlz_filesystem=yes test "${enable_symtable+set}" = set || enable_symtable=all test "${enable_sit+set}" = set || enable_sit=yes test "${enable_fetchlimit+set}" = set || enable_fetchlimit=yes test "${enable_warn_error+set}" = set || enable_warn_error=yes test "${enable_warn_shadow+set}" = set || enable_warn_shadow=yes ;; esac #libseccomp sandboxing AC_ARG_ENABLE(seccomp, AS_HELP_STRING([--enable-seccomp],[enable support for libseccomp system call filtering [default=no]])) case "$enable_seccomp" in yes) case $host_os in linux*) ;; *) AC_MSG_WARN([seccomp is not supported on non-linux platforms; disabling it]) enable_seccomp=no ;; esac AC_SEARCH_LIBS(seccomp_init, [seccomp]) if test "$ac_cv_search_seccomp_init" = "-lseccomp" ; then AC_TRY_RUN([ #include #include #include #include #include int main(void) { int ret; ret = prctl(PR_GET_SECCOMP, 0, 0, 0, 0); if (ret < 0) { switch (errno) { case ENOSYS: return 1; case EINVAL: return 1; default: return 1; } } ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0); if (ret < 0) { switch (errno) { case EINVAL: return 1; case EFAULT: return 0; default: return 1; } } return 1; } ] , AC_DEFINE([HAVE_LIBSECCOMP], 1, [Define to use libseccomp system call filtering.]) , [] ) fi ;; *) ;; esac # # Make very sure that these are the first files processed by # config.status, since we use the processed output as the input for # AC_SUBST_FILE() substitutions in other files. # AC_CONFIG_FILES([make/rules make/includes]) AC_PATH_PROG(AR, ar) ARFLAGS="cruv" AC_SUBST(AR) AC_SUBST(ARFLAGS) # The POSIX ln(1) program. Non-POSIX systems may substitute # "copy" or something. LN=ln AC_SUBST(LN) case "$AR" in "") AC_MSG_ERROR([ ar program not found. Please fix your PATH to include the directory in which ar resides, or set AR in the environment with the full path to ar. ]) ;; esac # # Etags. # AC_PATH_PROGS(ETAGS, etags emacs-etags) # # Some systems, e.g. RH7, have the Exuberant Ctags etags instead of # GNU emacs etags, and it requires the -L flag. # if test "X$ETAGS" != "X"; then AC_MSG_CHECKING(for Exuberant Ctags etags) if $ETAGS --version 2>&1 | grep 'Exuberant Ctags' >/dev/null 2>&1; then AC_MSG_RESULT(yes) ETAGS="$ETAGS -L" else AC_MSG_RESULT(no) fi fi AC_SUBST(ETAGS) # # Perl is optional; it is used only by some of the system test scripts. # Note: the backtrace feature (see below) uses perl to build the symbol table, # but it still compiles without perl, in which case an empty table will be used. # AC_PATH_PROGS(PERL, perl5 perl) AC_SUBST(PERL) # # Python is also optional; it is used by the tools in bin/python. # If python is unavailable, we simply don't build those. # AC_ARG_WITH(python, [ --with-python=PATH specify path to python interpreter], use_python="$withval", use_python="unspec") python="python python3 python3.4 python3.3 python3.2 python3.1 python3.0 python2 python2.7 python2.6 python2.5 python2.4" testscript='try: import argparse except: exit(1)' case "$use_python" in no) AC_MSG_CHECKING([for python support]) AC_MSG_RESULT(disabled) ;; unspec|yes|*) case "$use_python" in unspec|yes|'') for p in $python do AC_PATH_PROGS(PYTHON, $p) if test "X$PYTHON" = "X"; then continue; fi AC_MSG_CHECKING([python module 'argparse']) if ${PYTHON:-false} -c "$testscript"; then AC_MSG_RESULT([found, using $PYTHON]) break fi AC_MSG_RESULT([not found]) unset ac_cv_path_PYTHON unset PYTHON done if test "X$PYTHON" = "X" then AC_MSG_CHECKING([for python support]) case "$use_python" in unspec) AC_MSG_RESULT(disabled) ;; yes) AC_MSG_ERROR([missing python]) ;; esac fi ;; *) case "$use_python" in /*) PYTHON="$use_python" ;; *) AC_PATH_PROGS(PYTHON, $use_python) ;; esac AC_MSG_CHECKING([python module 'argparse']) if ${PYTHON:-false} -c "$testscript"; then AC_MSG_RESULT([found, using $PYTHON]) break else AC_MSG_ERROR([not found]) fi ;; esac ;; esac PYTHON_TOOLS='' CHECKDS='' COVERAGE='' if test "X$PYTHON" != "X"; then PYTHON_TOOLS=python CHECKDS=checkds COVERAGE=coverage fi AC_SUBST(CHECKDS) AC_SUBST(COVERAGE) AC_SUBST(PYTHON_TOOLS) # # Special processing of paths depending on whether --prefix, # --sysconfdir or --localstatedir arguments were given. What's # desired is some compatibility with the way previous versions # of BIND built; they defaulted to /usr/local for most parts of # the installation, but named.boot/named.conf was in /etc # and named.pid was in /var/run. # # So ... if none of --prefix, --sysconfdir or --localstatedir are # specified, set things up that way. If --prefix is given, use # it for sysconfdir and localstatedir the way configure normally # would. To change the prefix for everything but leave named.conf # in /etc or named.pid in /var/run, then do this the usual configure way: # ./configure --prefix=/somewhere --sysconfdir=/etc # ./configure --prefix=/somewhere --localstatedir=/var # # To put named.conf and named.pid in /usr/local with everything else, # set the prefix explicitly to /usr/local even though that's the default: # ./configure --prefix=/usr/local # case "$prefix" in NONE) case "$sysconfdir" in '${prefix}/etc') sysconfdir=/etc ;; esac case "$localstatedir" in '${prefix}/var') localstatedir=/var ;; esac ;; esac # # Make sure INSTALL uses an absolute path, else it will be wrong in all # Makefiles, since they use make/rules.in and INSTALL will be adjusted by # configure based on the location of the file where it is substituted. # Since in BIND9 INSTALL is only substituted into make/rules.in, an immediate # subdirectory of install-sh, This relative path will be wrong for all # directories more than one level down from install-sh. # case "$INSTALL" in /*) ;; *) # # Not all systems have dirname. # changequote({, }) ac_dir="`echo $INSTALL | sed 's%/[^/]*$%%'`" changequote([, ]) ac_prog="`echo $INSTALL | sed 's%.*/%%'`" test "$ac_dir" = "$ac_prog" && ac_dir=. test -d "$ac_dir" && ac_dir="`(cd \"$ac_dir\" && pwd)`" INSTALL="$ac_dir/$ac_prog" ;; esac # # On these hosts, we really want to use cc, not gcc, even if it is # found. The gcc that these systems have will not correctly handle # pthreads. # # However, if the user sets $CC to be something, let that override # our change. # if test "X$CC" = "X" ; then case "$host" in *-dec-osf*) CC="cc" ;; *-solaris*) # Use Sun's cc if it is available, but watch # out for /usr/ucb/cc; it will never be the right # compiler to use. # # If setting CC here fails, the AC_PROG_CC done # below might still find gcc. IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. case "$ac_dir" in /usr/ucb) # exclude ;; *) if test -f "$ac_dir/cc"; then CC="$ac_dir/cc" break fi ;; esac done IFS="$ac_save_ifs" ;; *-hp-hpux*) CC="cc" ;; mips-sgi-irix*) CC="cc" ;; esac fi AC_PROG_CC # # gcc's optimiser is broken at -02 for ultrasparc # if test "$ac_env_CFLAGS_set" != set -a "X$GCC" = "Xyes"; then case "$host" in sparc-*) CCFLAGS="-g -O1" ;; esac fi # # OS dependent CC flags # case "$host" in # OSF 5.0: recv/send are only available with -D_POSIX_PII_SOCKET or # -D_XOPEN_SOURCE_EXTENDED. *-dec-osf*) STD_CDEFINES="$STD_CDEFINES -D_POSIX_PII_SOCKET" CPPFLAGS="$CPPFLAGS -D_POSIX_PII_SOCKET" ;; #HP-UX: need -D_XOPEN_SOURCE_EXTENDED and -lxnet for CMSG macros *-hp-hpux*) STD_CDEFINES="$STD_CDEFINES -D_XOPEN_SOURCE_EXTENDED" CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE_EXTENDED" LIBS="-lxnet $LIBS" ;; # Solaris: need -D_XPG4_2 and -D__EXTENSIONS__ for CMSG macros *-solaris*) STD_CDEFINES="$STD_CDEFINES -D_XPG4_2 -D__EXTENSIONS__" CPPFLAGS="$CPPFLAGS -D_XPG4_2 -D__EXTENSIONS__" ;; # POSIX doesn't include the IPv6 Advanced Socket API and glibc hides # parts of the IPv6 Advanced Socket API as a result. This is stupid # as it breaks how the two halves (Basic and Advanced) of the IPv6 # Socket API were designed to be used but we have to live with it. # Define _GNU_SOURCE to pull in the IPv6 Advanced Socket API. *-linux* | *-kfreebsd*-gnu*) STD_CDEFINES="$STD_CDEFINES -D_GNU_SOURCE" CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE" ;; # # Starting with OSX 10.7 (Lion) we must choose which IPv6 API to use. # Setting this is sufficient to select the correct behavior for BIND 9. # *-darwin*) STD_CDEFINES="$STD_CDEFINES -D__APPLE_USE_RFC_3542" CPPFLAGS="$CPPFLAGS -D__APPLE_USE_RFC_3542" ;; esac # # CCNOOPT defaults to -O0 on gcc and disables optimization when is last # if test "X$CCNOOPT" = "X" -a "X$GCC" = "Xyes"; then CCNOOPT="-O0" fi AC_HEADER_STDC AC_CHECK_HEADERS(fcntl.h regex.h sys/time.h unistd.h sys/mman.h sys/sockio.h sys/select.h sys/param.h sys/sysctl.h net/if6.h sys/socket.h net/route.h linux/netlink.h linux/rtnetlink.h,,, [$ac_includes_default #ifdef HAVE_SYS_PARAM_H # include #endif #ifdef HAVE_SYS_SOCKET_H # include #endif ]) AC_C_CONST AC_C_INLINE AC_C_VOLATILE AC_CHECK_FUNC(sysctlbyname, AC_DEFINE(HAVE_SYSCTLBYNAME)) AC_C_FLEXIBLE_ARRAY_MEMBER # # Check for the existence of mmap to enable the fast format zones # AC_CHECK_FUNCS(mmap) # # Older versions of HP/UX don't define seteuid() and setegid() # AC_CHECK_FUNCS(seteuid setresuid) AC_CHECK_FUNCS(setegid setresgid) # BSDI doesn't have ftello fseeko AC_CHECK_FUNCS(ftello fseeko) # # UnixWare 7.1.1 with the feature supplement to the UDK compiler # is reported to not support "static inline" (RT #1212). # AC_MSG_CHECKING(for static inline breakage) AC_TRY_COMPILE([ static inline int foo1() { return 0; } static inline int foo2() { return foo1(); } ], [foo1();], [AC_MSG_RESULT(no)], [AC_MSG_RESULT(yes) AC_DEFINE(inline, ,[Define to empty if your compiler does not support "static inline".])]) AC_TYPE_SIZE_T AC_CHECK_TYPE(ssize_t, int) AC_CHECK_TYPE(uintptr_t,unsigned long) AC_CHECK_TYPE(socklen_t, [AC_DEFINE(ISC_SOCKADDR_LEN_T, socklen_t)], [ AC_TRY_COMPILE( [ #include #include int getsockname(int, struct sockaddr *, size_t *); ],[], [AC_DEFINE(ISC_SOCKADDR_LEN_T, size_t)], [AC_DEFINE(ISC_SOCKADDR_LEN_T, int)]) ], [ #include #include ]) AC_SUBST(ISC_SOCKADDR_LEN_T) AC_HEADER_TIME AC_MSG_CHECKING(for long long) AC_TRY_COMPILE([],[long long i = 0; return (0);], [AC_MSG_RESULT(yes) ISC_PLATFORM_HAVELONGLONG="#define ISC_PLATFORM_HAVELONGLONG 1"], [AC_MSG_RESULT(no) ISC_PLATFORM_HAVELONGLONG="#undef ISC_PLATFORM_HAVELONGLONG"]) AC_SUBST(ISC_PLATFORM_HAVELONGLONG) # # check for GCC noreturn attribute # AC_MSG_CHECKING(for GCC noreturn attribute) AC_TRY_COMPILE([],[void foo() __attribute__((noreturn));], [AC_MSG_RESULT(yes) ISC_PLATFORM_NORETURN_PRE="#define ISC_PLATFORM_NORETURN_PRE" ISC_PLATFORM_NORETURN_POST="#define ISC_PLATFORM_NORETURN_POST __attribute__((noreturn))"], [AC_MSG_RESULT(no) ISC_PLATFORM_NORETURN_PRE="#define ISC_PLATFORM_NORETURN_PRE" ISC_PLATFORM_NORETURN_POST="#define ISC_PLATFORM_NORETURN_POST"]) AC_SUBST(ISC_PLATFORM_NORETURN_PRE) AC_SUBST(ISC_PLATFORM_NORETURN_POST) # # check if we have lifconf # AC_MSG_CHECKING(for struct lifconf) AC_TRY_COMPILE([ #include #include #include ], [ struct lifconf lifconf; lifconf.lifc_len = 0; ] , [AC_MSG_RESULT(yes) ISC_PLATFORM_HAVELIFCONF="#define ISC_PLATFORM_HAVELIFCONF 1"], [AC_MSG_RESULT(no) ISC_PLATFORM_HAVELIFCONF="#undef ISC_PLATFORM_HAVELIFCONF"]) AC_SUBST(ISC_PLATFORM_HAVELIFCONF) # # check if we have kqueue # AC_ARG_ENABLE(kqueue, [ --enable-kqueue use BSD kqueue when available [[default=yes]]], want_kqueue="$enableval", want_kqueue="yes") case $want_kqueue in yes) AC_CHECK_FUNC(kqueue, ac_cv_have_kqueue=yes, ac_cv_have_kqueue=no) case $ac_cv_have_kqueue in yes) ISC_PLATFORM_HAVEKQUEUE="#define ISC_PLATFORM_HAVEKQUEUE 1" ;; *) ISC_PLATFORM_HAVEKQUEUE="#undef ISC_PLATFORM_HAVEKQUEUE" ;; esac ;; *) ISC_PLATFORM_HAVEKQUEUE="#undef ISC_PLATFORM_HAVEKQUEUE" ;; esac AC_SUBST(ISC_PLATFORM_HAVEKQUEUE) # # check if we have epoll. Linux kernel 2.4 has epoll_create() which fails, # so we need to try running the code, not just test its existence. # AC_ARG_ENABLE(epoll, [ --enable-epoll use Linux epoll when available [[default=auto]]], want_epoll="$enableval", want_epoll="auto") case $want_epoll in auto) AC_MSG_CHECKING(epoll support) AC_TRY_RUN([ #include int main() { if (epoll_create(1) < 0) return (1); return (0); } ], [AC_MSG_RESULT(yes) ISC_PLATFORM_HAVEEPOLL="#define ISC_PLATFORM_HAVEEPOLL 1"], [AC_MSG_RESULT(no) ISC_PLATFORM_HAVEEPOLL="#undef ISC_PLATFORM_HAVEEPOLL"], [AC_MSG_RESULT(no) ISC_PLATFORM_HAVEEPOLL="#undef ISC_PLATFORM_HAVEEPOLL"]) ;; yes) ISC_PLATFORM_HAVEEPOLL="#define ISC_PLATFORM_HAVEEPOLL 1" ;; *) ISC_PLATFORM_HAVEEPOLL="#undef ISC_PLATFORM_HAVEEPOLL" ;; esac AC_SUBST(ISC_PLATFORM_HAVEEPOLL) # # check if we support /dev/poll # AC_ARG_ENABLE(devpoll, [ --enable-devpoll use /dev/poll when available [[default=yes]]], want_devpoll="$enableval", want_devpoll="yes") case $want_devpoll in yes) AC_CHECK_HEADERS(sys/devpoll.h devpoll.h, ISC_PLATFORM_HAVEDEVPOLL="#define ISC_PLATFORM_HAVEDEVPOLL 1" , ISC_PLATFORM_HAVEDEVPOLL="#undef ISC_PLATFORM_HAVEDEVPOLL" ) ;; *) ISC_PLATFORM_HAVEDEVPOLL="#undef ISC_PLATFORM_HAVEDEVPOLL" ;; esac AC_SUBST(ISC_PLATFORM_HAVEDEVPOLL) # # check if we need to #include sys/select.h explicitly # case $ac_cv_header_unistd_h in yes) AC_MSG_CHECKING(if unistd.h or sys/types.h defines fd_set) AC_TRY_COMPILE([ #include /* Ultrix */ #include ], [fd_set read_set; return (0);], [AC_MSG_RESULT(yes) ISC_PLATFORM_NEEDSYSSELECTH="#undef ISC_PLATFORM_NEEDSYSSELECTH" LWRES_PLATFORM_NEEDSYSSELECTH="#undef LWRES_PLATFORM_NEEDSYSSELECTH"], [AC_MSG_RESULT(no) case $ac_cv_header_sys_select_h in yes) ISC_PLATFORM_NEEDSYSSELECTH="#define ISC_PLATFORM_NEEDSYSSELECTH 1" LWRES_PLATFORM_NEEDSYSSELECTH="#define LWRES_PLATFORM_NEEDSYSSELECTH 1" ;; no) AC_MSG_ERROR([need either working unistd.h or sys/select.h]) ;; esac ]) ;; no) case $ac_cv_header_sys_select_h in yes) ISC_PLATFORM_NEEDSYSSELECTH="#define ISC_PLATFORM_NEEDSYSSELECTH 1" LWRES_PLATFORM_NEEDSYSSELECTH="#define LWRES_PLATFORM_NEEDSYSSELECTH 1" ;; no) AC_MSG_ERROR([need either unistd.h or sys/select.h]) ;; esac ;; esac AC_SUBST(ISC_PLATFORM_NEEDSYSSELECTH) AC_SUBST(LWRES_PLATFORM_NEEDSYSSELECTH) # # Find the machine's endian flavor. # AC_C_BIGENDIAN # # GeoIP support? # GEOIPLINKSRCS= GEOIPLINKOBJS= AC_ARG_WITH(geoip, [ --with-geoip=PATH Build with GeoIP support (yes|no|path)], use_geoip="$withval", use_geoip="no") if test "$use_geoip" = "yes" then for d in /usr /usr/local /opt/local do if test -f $d/include/GeoIP.h then use_geoip=$d break fi done fi case "$use_geoip" in no|'') AC_MSG_CHECKING([for GeoIP support]) AC_MSG_RESULT([disabled]) ;; *) if test -d "$use_geoip" -o -L "$use_geoip" then CFLAGS="$CFLAGS -I$use_geoip/include" CPPFLAGS="$CPPFLAGS -I$use_geoip/include" LIBS="$LIBS -L$use_geoip/lib" case "$host_os" in netbsd*|openbsd*|solaris*) LIBS="$LIBS -Wl,-rpath=$use_geoip/lib" ;; esac elif test "$use_geoip" = "yes" then AC_MSG_ERROR([GeoIP path not found]) else AC_MSG_ERROR([GeoIP path $use_geoip does not exist]) fi AC_CHECK_HEADER(GeoIP.h, [], [AC_MSG_ERROR([GeoIP header file not found])] ) AC_SEARCH_LIBS(GeoIP_open, GeoIP, [], [AC_MSG_ERROR([GeoIP library not found])] ) AC_SEARCH_LIBS(fabsf, m, [], [AC_MSG_ERROR([Math library not found])] ) AC_DEFINE(HAVE_GEOIP, 1, Build with GeoIP support) GEOIPLINKSRCS='${GEOIPLINKSRCS}' GEOIPLINKOBJS='${GEOIPLINKOBJS}' AC_MSG_CHECKING([for GeoIP support]) AC_MSG_RESULT([yes]) AC_MSG_CHECKING([for GeoIP Country IPv6 support]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([ #include #include ], [ struct in6_addr in6; GeoIP_country_name_by_ipnum_v6(NULL, in6); ])], [ AC_MSG_RESULT([yes]) AC_DEFINE(HAVE_GEOIP_V6, 1, Build with GeoIP Country IPv6 support) ], [AC_MSG_RESULT([no])] ) AC_MSG_CHECKING([for GeoIP City IPv6 support]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([ #include #include #include ], [ struct in6_addr in6; int i = GEOIP_CITY_EDITION_REV0_V6; GeoIP_record_by_ipnum_v6(NULL, in6); ])], [ AC_MSG_RESULT([yes]) AC_DEFINE(HAVE_GEOIP_CITY_V6, 1, Build with GeoIP City IPv6 support) ], [AC_MSG_RESULT([no])] ) ;; esac AC_SUBST(GEOIPLINKSRCS) AC_SUBST(GEOIPLINKOBJS) AC_MSG_CHECKING(for GSSAPI library) AC_ARG_WITH(gssapi, [ --with-gssapi=PATH Specify path for system-supplied GSSAPI [[default=yes]]], use_gssapi="$withval", use_gssapi="yes") # gssapi is just the framework, we really require kerberos v5, so # look for those headers (the gssapi headers must be there, too) # The problem with this implementation is that it doesn't allow # for the specification of gssapi and krb5 headers in different locations, # which probably ought to be fixed although fixing might raise the issue of # trying to build with incompatible versions of gssapi and krb5. if test "$use_gssapi" = "yes" then # first, deal with the obvious if test \( -f /usr/include/kerberosv5/krb5.h -o \ -f /usr/include/krb5/krb5.h -o \ -f /usr/include/krb5.h \) -a \ \( -f /usr/include/gssapi.h -o \ -f /usr/include/gssapi/gssapi.h \) then use_gssapi=/usr else krb5dirs="/usr/local /usr/local/krb5 /usr/local/kerberosv5 /usr/local/kerberos /usr/pkg /usr/krb5 /usr/kerberosv5 /usr/kerberos /usr" for d in $krb5dirs do if test -f $d/include/gssapi/gssapi_krb5.h -o \ -f $d/include/krb5.h then if test -f $d/include/gssapi/gssapi.h -o \ -f $d/include/gssapi.h then use_gssapi=$d break fi fi use_gssapi="no" done fi fi case "$use_gssapi" in no) AC_MSG_RESULT(disabled) USE_GSSAPI='' ;; yes) AC_MSG_ERROR([--with-gssapi must specify a path]) ;; *) AC_MSG_RESULT(looking in $use_gssapi/lib) USE_GSSAPI='-DGSSAPI' saved_cppflags="$CPPFLAGS" CPPFLAGS="-I$use_gssapi/include $CPPFLAGS" AC_CHECK_HEADERS(gssapi.h gssapi/gssapi.h, [ISC_PLATFORM_GSSAPIHEADER="#define ISC_PLATFORM_GSSAPIHEADER <$ac_header>" gssapi_hack="#include <$ac_header>"]) if test "$ISC_PLATFORM_GSSAPIHEADER" = ""; then AC_MSG_ERROR([gssapi.h not found]) fi AC_CHECK_HEADERS(gssapi_krb5.h gssapi/gssapi_krb5.h, [ISC_PLATFORM_GSSAPI_KRB5_HEADER="#define ISC_PLATFORM_GSSAPI_KRB5_HEADER <$ac_header>" gssapi_krb5_hack="#include <$ac_header>"]) AC_CHECK_HEADERS(krb5.h krb5/krb5.h kerberosv5/krb5.h, [ISC_PLATFORM_KRB5HEADER="#define ISC_PLATFORM_KRB5HEADER <$ac_header>" krb5_hack="#include <$ac_header>"]) if test "$ISC_PLATFORM_KRB5HEADER" = ""; then AC_MSG_ERROR([krb5.h not found]) fi # # XXXDCL This probably doesn't work right on all systems. # It will need to be worked on as problems become evident. # # Essentially the problems here relate to two different # areas. The first area is building with either KTH # or MIT Kerberos, particularly when both are present on # the machine. The other is static versus dynamic linking. # # On the KTH vs MIT issue, Both have libkrb5 that can mess # up the works if one implementation ends up trying to # use the other's krb. This is unfortunately a situation # that very easily arises. # # Dynamic linking when the dependency information is built # into MIT's libgssapi_krb5 or KTH's libgssapi magically makes # all such problems go away, but when that setup is not # present, because either the dynamic libraries lack # dependencies or static linking is being done, then the # problems start to show up. saved_libs="$LIBS" for TRY_LIBS in \ "-lgssapi_krb5" \ "-lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err" \ "-lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -lresolv" \ "-lgssapi" \ "-lgssapi -lkrb5 -ldes -lcrypt -lasn1 -lroken -lcom_err" \ "-lgssapi -lkrb5 -lcrypto -lcrypt -lasn1 -lroken -lcom_err" \ "-lgssapi -lkrb5 -lgssapi_krb5 -lcrypto -lcrypt -lasn1 -lroken -lcom_err" \ "-lgssapi -lkrb5 -lhx509 -lcrypto -lcrypt -lasn1 -lroken -lcom_err" \ "-lgss -lkrb5" do # Note that this does not include $saved_libs, because # on FreeBSD machines this configure script has added # -L/usr/local/lib to LIBS, which can make the # -lgssapi_krb5 test succeed with shared libraries even # when you are trying to build with KTH in /usr/lib. if test "$use_gssapi" = "/usr" then LIBS="$TRY_LIBS" else LIBS="-L$use_gssapi/lib $TRY_LIBS" fi AC_MSG_CHECKING(linking as $TRY_LIBS) AC_TRY_LINK([ #include $gssapi_hack $gssapi_krb5_hack $krb5_hack ] , [gss_acquire_cred(NULL, NULL, 0, NULL, 0, NULL, NULL, NULL);krb5_init_context(NULL); #if defined(HAVE_GSSAPI_KRB5_H) || defined(HAVE_GSSAPI_GSSAPI_KRB5_H) gsskrb5_register_acceptor_identity(NULL); #endif], gssapi_linked=yes, gssapi_linked=no) case $gssapi_linked in yes) AC_MSG_RESULT(yes); break ;; no) AC_MSG_RESULT(no) ;; esac done CPPFLAGS="$saved_cppflags" case $gssapi_linked in no) AC_MSG_ERROR(could not determine proper GSSAPI linkage) ;; esac # # XXXDCL Major kludge. Tries to cope with KTH in /usr/lib # but MIT in /usr/local/lib and trying to build with KTH. # /usr/local/lib can end up earlier on the link lines. # Like most kludges, this one is not only inelegant it # is also likely to be the wrong thing to do at least as # many times as it is the right thing. Something better # needs to be done. # if test "$use_gssapi" = "/usr" -a \ -f /usr/local/lib/libkrb5.a; then FIX_KTH_VS_MIT=yes fi case "$FIX_KTH_VS_MIT" in yes) case "$enable_static_linking" in yes) gssapi_lib_suffix=".a" ;; *) gssapi_lib_suffix=".so" ;; esac for lib in $LIBS; do case $lib in -L*) ;; -l*) new_lib=`echo $lib | sed -e s%^-l%$use_gssapi/lib/lib% \ -e s%$%$gssapi_lib_suffix%` NEW_LIBS="$NEW_LIBS $new_lib" ;; *) AC_MSG_ERROR([KTH vs MIT Kerberos confusion!]) ;; esac done LIBS="$NEW_LIBS" ;; esac DST_GSSAPI_INC="-I$use_gssapi/include" DNS_GSSAPI_LIBS="$LIBS" AC_MSG_RESULT(using GSSAPI from $use_gssapi/lib and $use_gssapi/include) LIBS="$saved_libs" ;; esac AC_SUBST(ISC_PLATFORM_HAVEGSSAPI) AC_SUBST(ISC_PLATFORM_GSSAPIHEADER) AC_SUBST(ISC_PLATFORM_GSSAPI_KRB5_HEADER) AC_SUBST(ISC_PLATFORM_KRB5HEADER) AC_SUBST(USE_GSSAPI) AC_SUBST(DST_GSSAPI_INC) AC_SUBST(DNS_GSSAPI_LIBS) DNS_CRYPTO_LIBS="$DNS_GSSAPI_LIBS $DNS_CRYPTO_LIBS" # # Applications linking with libdns also need to link with these libraries. # AC_SUBST(DNS_CRYPTO_LIBS) # # was --with-randomdev specified? # AC_MSG_CHECKING(for random device) AC_ARG_WITH(randomdev, [ --with-randomdev=PATH Specify path for random device], use_randomdev="$withval", use_randomdev="unspec") case "$use_randomdev" in unspec) case "$cross_compiling" in yes) AC_MSG_RESULT(unspecified) AC_MSG_ERROR([ need --with-randomdev=PATH or --with-randomdev=no]) esac case "$host" in *-openbsd*) devrandom=/dev/arandom ;; *) devrandom=/dev/random ;; esac AC_MSG_RESULT($devrandom) AC_CHECK_FILE($devrandom, AC_DEFINE_UNQUOTED(PATH_RANDOMDEV, "$devrandom"),) ;; yes) AC_MSG_ERROR([--with-randomdev must specify a path]) ;; no) AC_MSG_RESULT(disabled) ;; *) AC_DEFINE_UNQUOTED(PATH_RANDOMDEV, "$use_randomdev") AC_MSG_RESULT(using "$use_randomdev") ;; esac # # Only check dsa signature generation on these platforms when performing # system tests. # CHECK_DSA=0 if grep "#define PATH_RANDOMDEV " confdefs.h > /dev/null then case "$host" in *darwin*|*freebsd*) CHECK_DSA=1 ;; esac fi AC_SUBST(CHECK_DSA) # # Do we have arc4random(), etc ? arc4random_addrandom() has been removed # from OpenBSD 5.5 onwards. # AC_CHECK_FUNC(arc4random, AC_DEFINE(HAVE_ARC4RANDOM)) AC_CHECK_FUNC(arc4random_addrandom, AC_DEFINE(HAVE_ARC4RANDOM_ADDRANDOM)) sinclude(config.threads.in)dnl if $use_threads then if test "X$GCC" = "Xyes"; then case "$host" in *-freebsd*) CC="$CC -pthread" CCOPT="$CCOPT -pthread" CCNOOPT="$CCNOOPT -pthread" STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE" ;; *-openbsd*) CC="$CC -pthread" CCOPT="$CCOPT -pthread" CCNOOPT="$CCNOOPT -pthread" ;; *-solaris*) LIBS="$LIBS -lthread" ;; *-ibm-aix*) STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE" ;; esac else case $host in *-dec-osf*) CC="$CC -pthread" CCOPT="$CCOPT -pthread" CCNOOPT="$CCNOOPT -pthread" ;; *-solaris*) CC="$CC -mt" CCOPT="$CCOPT -mt" CCNOOPT="$CCNOOPT -mt" ;; *-ibm-aix*) STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE" ;; *-sco-sysv*uw*|*-*-sysv*UnixWare*) CC="$CC -Kthread" CCOPT="$CCOPT -Kthread" CCNOOPT="$CCNOOPT -Kthread" ;; *-*-sysv*OpenUNIX*) CC="$CC -Kpthread" CCOPT="$CCOPT -Kpthread" CCNOOPT="$CCNOOPT -Kpthread" ;; esac fi ALWAYS_DEFINES="-D_REENTRANT" ISC_PLATFORM_USETHREADS="#define ISC_PLATFORM_USETHREADS 1" THREADOPTOBJS='${THREADOPTOBJS}' THREADOPTSRCS='${THREADOPTSRCS}' thread_dir=pthreads # # We'd like to use sigwait() too # AC_CHECK_FUNC(sigwait, AC_DEFINE(HAVE_SIGWAIT), AC_CHECK_LIB(c, sigwait, AC_DEFINE(HAVE_SIGWAIT), AC_CHECK_LIB(pthread, sigwait, AC_DEFINE(HAVE_SIGWAIT), AC_CHECK_LIB(pthread, _Psigwait, AC_DEFINE(HAVE_SIGWAIT),)))) AC_CHECK_FUNC(pthread_attr_getstacksize, AC_DEFINE(HAVE_PTHREAD_ATTR_GETSTACKSIZE),) AC_CHECK_FUNC(pthread_attr_setstacksize, AC_DEFINE(HAVE_PTHREAD_ATTR_SETSTACKSIZE),) AC_ARG_WITH(locktype, [ --with-locktype=ARG Specify mutex lock type (adaptive or standard)], locktype="$withval", locktype="adaptive") case "$locktype" in adaptive) AC_MSG_CHECKING([for PTHREAD_MUTEX_ADAPTIVE_NP]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #define _GNU_SOURCE #include ]], [[ return (PTHREAD_MUTEX_ADAPTIVE_NP); ]])], [ AC_MSG_RESULT(using adaptive lock type) AC_DEFINE([HAVE_PTHREAD_MUTEX_ADAPTIVE_NP], 1, [Support for PTHREAD_MUTEX_ADAPTIVE_NP]) ], [ AC_MSG_RESULT(using standard lock type) ]) ;; standard) AC_MSG_RESULT(using standard lock type) ;; *) AC_MSG_ERROR([You must specify "adaptive" or "standard" for --with-locktype.]) ;; esac AC_CHECK_HEADERS(sched.h) case "$host" in *solaris-*) AC_CHECK_LIB(rt, sched_yield) ;; esac AC_CHECK_FUNCS(sched_yield pthread_yield pthread_yield_np) # # Additional OS-specific issues related to pthreads and sigwait. # case "$host" in # # One more place to look for sigwait. # *-freebsd*) AC_CHECK_LIB(c_r, sigwait, AC_DEFINE(HAVE_SIGWAIT),) case $host in *-freebsd5.[[012]]|*-freebsd5.[[012]].*);; *-freebsd5.[[3456789]]|*-freebsd5.[[3456789]].*) AC_DEFINE(NEED_PTHREAD_SCOPE_SYSTEM) ;; *-freebsd6.*) AC_DEFINE(NEED_PTHREAD_SCOPE_SYSTEM) ;; esac ;; # # BSDI 3.0 through 4.0.1 needs pthread_init() to be # called before certain pthreads calls. This is deprecated # in BSD/OS 4.1. # *-bsdi3.*|*-bsdi4.0*) AC_DEFINE(NEED_PTHREAD_INIT) ;; # # LinuxThreads requires some changes to the way we # deal with signals. # *-linux*) AC_DEFINE(HAVE_LINUXTHREADS) ;; # # Ensure the right sigwait() semantics on Solaris and make # sure we call pthread_setconcurrency. # *-solaris*) AC_DEFINE(_POSIX_PTHREAD_SEMANTICS) AC_CHECK_FUNC(pthread_setconcurrency, AC_DEFINE(CALL_PTHREAD_SETCONCURRENCY)) ;; # # UnixWare does things its own way. # *-sco-sysv*uw*|*-*-sysv*UnixWare*|*-*-sysv*OpenUNIX*) AC_DEFINE(HAVE_UNIXWARE_SIGWAIT) ;; esac # # Look for sysconf to allow detection of the number of processors. # AC_CHECK_FUNC(sysconf, AC_DEFINE(HAVE_SYSCONF),) else ISC_PLATFORM_USETHREADS="#undef ISC_PLATFORM_USETHREADS" thread_dir=nothreads THREADOPTOBJS="" THREADOPTSRCS="" ALWAYS_DEFINES="" fi AC_SUBST(ALWAYS_DEFINES) AC_SUBST(ISC_PLATFORM_USETHREADS) AC_SUBST(THREADOPTOBJS) AC_SUBST(THREADOPTSRCS) ISC_THREAD_DIR=$thread_dir AC_SUBST(ISC_THREAD_DIR) AC_MSG_CHECKING(for libtool) AC_ARG_WITH(libtool, [ --with-libtool use GNU libtool], use_libtool="$withval", use_libtool="no") case $use_libtool in yes) AC_MSG_RESULT(yes) AM_PROG_LIBTOOL O=lo A=la LIBTOOL_MKDEP_SED='s;\.o;\.lo;' LIBTOOL_MODE_COMPILE='--mode=compile --tag=CC' LIBTOOL_MODE_INSTALL='--mode=install --tag=CC' LIBTOOL_MODE_LINK='--mode=link --tag=CC' INSTALL_LIBRARY='${INSTALL_PROGRAM}' case "$host" in *) LIBTOOL_ALLOW_UNDEFINED= ;; esac case "$host" in *-ibm-aix*) LIBTOOL_IN_MAIN="-Wl,-bI:T_testlist.imp" ;; *) LIBTOOL_IN_MAIN= ;; esac; ;; *) AC_MSG_RESULT(no) O=o A=a LIBTOOL= AC_SUBST(LIBTOOL) LIBTOOL_MKDEP_SED= LIBTOOL_MODE_COMPILE= LIBTOOL_MODE_INSTALL= LIBTOOL_MODE_LINK= LIBTOOL_ALLOW_UNDEFINED= LIBTOOL_IN_MAIN= INSTALL_LIBRARY='${INSTALL_DATA}' ;; esac AC_SUBST(INSTALL_LIBRARY) # # was --enable-native-pkcs11 specified? # (note it implies both --without-openssl and --with-pkcs11) # AC_ARG_ENABLE(native-pkcs11, [ --enable-native-pkcs11 use native PKCS11 for all crypto [[default=no]]], want_native_pkcs11="$enableval", want_native_pkcs11="no") # # was --with-openssl specified? # AC_ARG_WITH(openssl, [ --with-openssl[=PATH] Build with OpenSSL [yes|no|path]. (Crypto is required for DNSSEC)], use_openssl="$withval", use_openssl="auto") # # was --with-pkcs11 specified? # AC_ARG_WITH(pkcs11, [ --with-pkcs11[=PATH] Build with PKCS11 support [yes|no|path] (PATH is for the PKCS11 provider)], use_pkcs11="$withval", use_pkcs11="auto") # # were --with-ecdsa, --with-gost, --with-aes specified # AC_ARG_WITH(ecdsa, [ --with-ecdsa Crypto ECDSA], with_ecdsa="$withval", with_ecdsa="auto") AC_ARG_WITH(gost, [ --with-gost Crypto GOST [yes|no|raw|asn1].], with_gost="$withval", with_gost="auto") AC_ARG_WITH(aes, [ --with-aes Crypto AES], with_aes="$withval", with_aes="checksit") # # was --enable-openssl-hash specified? # AC_ARG_ENABLE(openssl-hash, [ --enable-openssl-hash use OpenSSL for hash functions [[default=no]]], want_openssl_hash="$enableval", want_openssl_hash="checksit") # # Enable Source Identity Token support # AC_MSG_CHECKING(for Source Identity Token support) AC_ARG_ENABLE(sit, [ --enable-sit enable source identity token [[default=no]]], enable_sit="$enableval", enable_sit="no") HAVE_SIT= ISC_PLATFORM_USESIT="#undef ISC_PLATFORM_USESIT" case "$enable_sit" in yes) AC_MSG_RESULT(yes) ISC_PLATFORM_USESIT="#define ISC_PLATFORM_USESIT 1" HAVE_SIT=1 ;; no) AC_MSG_RESULT(no) ;; *) AC_MSG_ERROR("enable-sit requires yes or no") ;; esac AC_SUBST(ISC_PLATFORM_USESIT) AC_SUBST(HAVE_SIT) # # Source Identity Token algorithm choice # AC_ARG_WITH(sit-alg, [ --with-sit-alg=ALG choose the algorithm for SIT [[aes|sha1|sha256]]], with_sit_alg="$withval", with_sit_alg="auto") if test "$enable_sit" = "yes" then case $with_sit_alg in *1) with_sit_alg="sha1" ;; *2*) with_sit_alg="sha256" ;; auto) if test "$with_aes" != "no" then with_aes="yes" fi ;; *) with_sit_alg="aes" if test "$with_aes" != "no" then with_aes="yes" fi ;; esac fi if test "with_aes" = "checksit" then with_aes="no" fi AC_MSG_CHECKING(for OpenSSL library) OPENSSL_WARNING= openssldirs="/usr /usr/local /usr/local/ssl /usr/pkg /usr/sfw" if test "$use_openssl" = "auto" then if test "$want_native_pkcs11" = "yes" then use_openssl="native_pkcs11" else for d in $openssldirs do if test -f $d/include/openssl/opensslv.h then use_openssl=$d break fi done fi fi OPENSSL_ECDSA="" OPENSSL_GOST="" gosttype="raw" case "$with_gost" in raw) with_gost="yes" ;; asn1) AC_DEFINE(PREFER_GOSTASN1, 1, [Define if GOST private keys are encoded in ASN.1.]) gosttype="asn1" with_gost="yes" ;; auto|yes|no) ;; *) AC_MSG_ERROR(unknown GOST private key encoding) ;; esac case "$use_openssl" in native_pkcs11) AC_MSG_RESULT(disabled because of native PKCS11) DST_OPENSSL_INC="" CRYPTO="-DPKCS11CRYPTO" OPENSSLGOSTLINKOBJS="" OPENSSLGOSTLINKSRS="" OPENSSLLINKOBJS="" OPENSSLLINKSRCS="" ;; no) AC_MSG_RESULT(no) DST_OPENSSL_INC="" CRYPTO="" OPENSSLGOSTLINKOBJS="" OPENSSLGOSTLINKSRS="" OPENSSLLINKOBJS="" OPENSSLLINKSRCS="" ;; auto) DST_OPENSSL_INC="" CRYPTO="" OPENSSLGOSTLINKOBJS="" OPENSSLGOSTLINKSRS="" OPENSSLLINKOBJS="" OPENSSLLINKSRCS="" AC_MSG_ERROR( [OpenSSL was not found in any of $openssldirs; use --with-openssl=/path If you don't want OpenSSL, use --without-openssl]) ;; *) if test "$want_native_pkcs11" = "yes" then AC_MSG_RESULT() AC_MSG_ERROR([OpenSSL and native PKCS11 cannot be used together.]) fi if test "$use_openssl" = "yes" then # User did not specify a path - guess it for d in $openssldirs do if test -f $d/include/openssl/opensslv.h then use_openssl=$d break fi done if test "$use_openssl" = "yes" then AC_MSG_RESULT(not found) AC_MSG_ERROR( [OpenSSL was not found in any of $openssldirs; use --with-openssl=/path]) fi elif ! test -f "$use_openssl"/include/openssl/opensslv.h then AC_MSG_ERROR(["$use_openssl/include/openssl/opensslv.h" not found]) fi CRYPTO='-DOPENSSL' if test "$use_openssl" = "/usr" then DST_OPENSSL_INC="" DST_OPENSSL_LIBS="-lcrypto" else DST_OPENSSL_INC="-I$use_openssl/include" case $host in *-solaris*) DST_OPENSSL_LIBS="-L$use_openssl/lib -R$use_openssl/lib -lcrypto" ;; *-hp-hpux*) DST_OPENSSL_LIBS="-L$use_openssl/lib -Wl,+b: -lcrypto" ;; *-apple-darwin*) # # Apple's ld seaches for serially for dynamic # then static libraries. This means you can't # use -L to override dynamic system libraries # with static ones when linking. Instead # we specify a absolute path. # if test -f "$use_openssl/lib/libcrypto.dylib" then DST_OPENSSL_LIBS="-L$use_openssl/lib -lcrypto" else DST_OPENSSL_LIBS="$use_openssl/lib/libcrypto.a" fi ;; *) DST_OPENSSL_LIBS="-L$use_openssl/lib -lcrypto" ;; esac fi AC_MSG_RESULT(using OpenSSL from $use_openssl/lib and $use_openssl/include) saved_cc="$CC" saved_cflags="$CFLAGS" saved_libs="$LIBS" CFLAGS="$CFLAGS $DST_OPENSSL_INC" LIBS="$LIBS $DST_OPENSSL_LIBS" AC_MSG_CHECKING(whether linking with OpenSSL works) AC_TRY_RUN([ #include int main() { ERR_clear_error(); return (0); } ], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no) AC_MSG_ERROR(Could not run test program using OpenSSL from $use_openssl/lib and $use_openssl/include. Please check the argument to --with-openssl and your shared library configuration (e.g., LD_LIBRARY_PATH).)], [AC_MSG_RESULT(assuming it does work on target platform)]) AC_MSG_CHECKING(whether linking with OpenSSL requires -ldl) AC_TRY_LINK([ #include #include ], [ DSO_METHOD_dlfcn(); ], [AC_MSG_RESULT(no)], [LIBS="$LIBS -ldl" AC_TRY_LINK([ #include #include ],[ DSO_METHOD_dlfcn(); ], [AC_MSG_RESULT(yes) DST_OPENSSL_LIBS="$DST_OPENSSL_LIBS -ldl" ], [AC_MSG_RESULT(unknown) AC_MSG_ERROR(OpenSSL has unsupported dynamic loading)], [AC_MSG_RESULT(assuming it does work on target platform)]) ], [AC_MSG_RESULT(assuming it does work on target platform)] ) AC_ARG_ENABLE(openssl-version-check, [AC_HELP_STRING([--enable-openssl-version-check], [check OpenSSL version @<:@default=yes@:>@])]) case "$enable_openssl_version_check" in yes|'') AC_MSG_CHECKING(OpenSSL library version) AC_TRY_RUN([ #include #include int main() { if ((OPENSSL_VERSION_NUMBER >= 0x009070cfL && OPENSSL_VERSION_NUMBER < 0x00908000L) || (OPENSSL_VERSION_NUMBER >= 0x0090804fL && OPENSSL_VERSION_NUMBER < 0x10002000L) || OPENSSL_VERSION_NUMBER >= 0x1000205fL) return (0); printf("\n\nFound OPENSSL_VERSION_NUMBER %#010x\n", OPENSSL_VERSION_NUMBER); printf("Require OPENSSL_VERSION_NUMBER 0x009070cf or greater (0.9.7l)\n" "Require OPENSSL_VERSION_NUMBER 0x0090804f or greater (0.9.8d)\n" "Require OPENSSL_VERSION_NUMBER 0x1000000f or greater (1.0.0)\n" "Require OPENSSL_VERSION_NUMBER 0x1000100f or greater (1.0.1)\n" "Require OPENSSL_VERSION_NUMBER 0x1000205f or greater (1.0.2e)\n\n"); return (1); } ], [AC_MSG_RESULT(ok)], [AC_MSG_RESULT(not compatible) OPENSSL_WARNING=yes ], [AC_MSG_RESULT(assuming target platform has compatible version)]) ;; no) AC_MSG_RESULT(Skipped OpenSSL version check) ;; esac AC_MSG_CHECKING(for OpenSSL DSA support) if test -f $use_openssl/include/openssl/dsa.h then AC_DEFINE(HAVE_OPENSSL_DSA) AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi AC_CHECK_FUNCS(EVP_sha256 EVP_sha384 EVP_sha512) AC_MSG_CHECKING(for OpenSSL ECDSA support) have_ecdsa="" AC_TRY_RUN([ #include #include int main() { EC_KEY *ec256, *ec384; #if !defined(HAVE_EVP_SHA256) || !defined(HAVE_EVP_SHA384) return (1); #endif ec256 = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); ec384 = EC_KEY_new_by_curve_name(NID_secp384r1); if (ec256 == NULL || ec384 == NULL) return (2); return (0); } ], [AC_MSG_RESULT(yes) have_ecdsa="yes"], [AC_MSG_RESULT(no) have_ecdsa="no"], [AC_MSG_RESULT(using --with-ecdsa)]) case "$with_ecdsa" in yes) case "$have_ecdsa" in no) AC_MSG_ERROR([ecdsa not supported]) ;; *) have_ecdsa=yes ;; esac ;; no) have_ecdsa=no ;; *) case "$have_ecdsa" in yes|no) ;; *) AC_MSG_ERROR([need --with-ecdsa=[[yes or no]]]) ;; esac ;; esac case $have_ecdsa in yes) OPENSSL_ECDSA="yes" AC_DEFINE(HAVE_OPENSSL_ECDSA, 1, [Define if your OpenSSL version supports ECDSA.]) ;; *) ;; esac AC_MSG_CHECKING(for OpenSSL GOST support) have_gost="" case "$use_pkcs11" in auto|no) ;; *) if $use_threads; then CC="$CC -pthread" fi ;; esac AC_TRY_RUN([ #include #include int main() { #if (OPENSSL_VERSION_NUMBER >= 0x10000000L) ENGINE *e; EC_KEY *ek; ek = NULL; OPENSSL_config(NULL); e = ENGINE_by_id("gost"); if (e == NULL) return (1); if (ENGINE_init(e) <= 0) return (1); return (0); #else return (1); #endif } ], [AC_MSG_RESULT(yes) have_gost="yes"], [AC_MSG_RESULT(no) have_gost="no"], [AC_MSG_RESULT(using --with-gost)]) case "$with_gost" in yes) case "$have_gost" in no) AC_MSG_ERROR([gost not supported]) ;; *) have_gost=yes ;; esac ;; no) have_gost=no ;; *) case "$have_gost" in yes|no) ;; *) AC_MSG_ERROR([need --with-gost=[[yes, no, raw or asn1]]]) ;; esac ;; esac case $have_gost in yes) OPENSSL_GOST="yes" OPENSSLGOSTLINKOBJS='${OPENSSLGOSTLINKOBJS}' OPENSSLGOSTLINKSRCS='${OPENSSLGOSTLINKSRCS}' AC_DEFINE(HAVE_OPENSSL_GOST, 1, [Define if your OpenSSL version supports GOST.]) ;; *) ;; esac have_aes="no" AC_MSG_CHECKING(for OpenSSL AES support) AC_TRY_RUN([ #include int main() { EVP_CIPHER *aes128, *aes192, *aes256; aes128 = EVP_aes_128_ecb(); aes192 = EVP_aes_192_ecb(); aes256 = EVP_aes_256_ecb(); if (aes128 == NULL || aes192 == NULL || aes256 == NULL) return (1); return (0); } ], [AC_MSG_RESULT(yes) have_aes="evp"], [AC_CHECK_FUNC(AES_encrypt, [AC_MSG_RESULT(yes) have_aes="yes"], [AC_MSG_RESULT(no)])], [AC_MSG_RESULT(using --with-aes)]) ISC_OPENSSL_INC="" ISC_OPENSSL_LIBS="" if test "$with_aes" = "yes" then case "$have_aes" in evp) AC_DEFINE(HAVE_OPENSSL_EVP_AES, 1, [Define if your OpenSSL version supports EVP AES]) ISC_OPENSSL_INC="$DST_OPENSSL_INC" ISC_OPENSSL_LIBS="$DST_OPENSSL_LIBS" ;; yes) AC_DEFINE(HAVE_OPENSSL_AES, 1, [Define if your OpenSSL version supports AES]) ISC_OPENSSL_INC="$DST_OPENSSL_INC" ISC_OPENSSL_LIBS="$DST_OPENSSL_LIBS" ;; *) ;; esac fi CC="$saved_cc" CFLAGS="$saved_cflags" LIBS="$saved_libs" OPENSSLLINKOBJS='${OPENSSLLINKOBJS}' OPENSSLLINKSRCS='${OPENSSLLINKSRCS}' ;; esac # # This would include the system openssl path (and linker options to use # it as needed) if it is found. # AC_SUBST(DST_OPENSSL_INC) AC_SUBST(OPENSSLGOSTLINKOBJS) AC_SUBST(OPENSSLGOSTLINKSRCS) AC_SUBST(OPENSSLLINKOBJS) AC_SUBST(OPENSSLLINKSRCS) AC_SUBST(OPENSSL_ECDSA) AC_SUBST(OPENSSL_GOST) DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DST_OPENSSL_LIBS" ISC_PLATFORM_WANTAES="#undef ISC_PLATFORM_WANTAES" if test "$with_aes" = "yes" then if test "X$CRYPTO" = "X" then with_aes="no" fi fi if test "$with_aes" = "yes" then ISC_PLATFORM_WANTAES="#define ISC_PLATFORM_WANTAES 1" fi AC_SUBST(ISC_PLATFORM_WANTAES) # # Choose SIT algorithm # if test "$enable_sit" = "yes" then AC_MSG_CHECKING(for the Algorithm for SIT) if test "$with_sit_alg" = "auto" then if test "$with_aes" = "yes" then with_sit_alg="aes" else with_sit_alg="sha256" fi fi fi case $with_sit_alg in sha1) if test "$enable_sit" != "yes" then AC_MSG_ERROR("with-sit-alg requires enable-sit"); fi AC_MSG_RESULT(sha1) if test "$CRYPTO" = "-DOPENSSL" then if test "$want_openssl_hash" = "checksit" then want_openssl_hash="yes" fi fi AC_DEFINE(HMAC_SHA1_SIT, 1, [Use HMAC-SHA1 for Source Identity Token generation]) ;; sha256) if test "$enable_sit" != "yes" then AC_MSG_ERROR("with-sit-alg requires enable-sit"); fi AC_MSG_RESULT(sha256) if test "$CRYPTO" = "-DOPENSSL" then if test "$want_openssl_hash" = "checksit" then want_openssl_hash="yes" fi fi AC_DEFINE(HMAC_SHA256_SIT, 1, [Use HMAC-SHA256 for Source Identity Token generation]) ;; aes) if test "$enable_sit" != "yes" then AC_MSG_ERROR("with-sit-alg requires enable-sit"); fi AC_MSG_RESULT(aes) if test "$with_aes" != "yes" then AC_MSG_ERROR("SIT wants to use unavailable AES"); fi AC_DEFINE(AES_SIT, 1, [Use AES for Source Identity Token generation]) ;; esac if test "$want_openssl_hash" = "checksit" then want_openssl_hash="no" fi # # Use OpenSSL for hash functions # AC_MSG_CHECKING(for using OpenSSL for hash functions) ISC_PLATFORM_OPENSSLHASH="#undef ISC_PLATFORM_OPENSSLHASH" case $want_openssl_hash in yes) if test "$CRYPTO" != "-DOPENSSL" then AC_MSG_ERROR([No OpenSSL for hash functions]) fi AC_MSG_RESULT(yes) ISC_PLATFORM_OPENSSLHASH="#define ISC_PLATFORM_OPENSSLHASH 1" ISC_OPENSSL_INC="$DST_OPENSSL_INC" ISC_OPENSSL_LIBS="$DST_OPENSSL_LIBS" saved_cflags="$CFLAGS" save_libs="$LIBS" CFLAGS="$CFLAGS $ISC_OPENSSL_INC" LIBS="$LIBS $ISC_OPENSSL_LIBS" AC_MSG_CHECKING([HMAC_Init() return type]) AC_TRY_COMPILE([ #include ],[ HMAC_CTX ctx; int n = HMAC_Init(&ctx, NULL, 0, NULL); n += HMAC_Update(&ctx, NULL, 0); n += HMAC_Final(&ctx, NULL, NULL);],[ AC_MSG_RESULT(int) AC_DEFINE(HMAC_RETURN_INT, 1, [HMAC_*() return ints])],[ AC_MSG_RESULT(void)]) CFLAGS="$saved_cflags" LIBS="$save_libs" ;; no) AC_MSG_RESULT(no) ;; esac AC_SUBST(ISC_PLATFORM_OPENSSLHASH) AC_SUBST(ISC_OPENSSL_INC) AC_SUBST(ISC_OPENSSL_LIBS) # # PKCS11 (aka crypto hardware) support (--with moved just after openssl) # AC_MSG_CHECKING(for PKCS11 support) if test "$use_pkcs11" = "auto" then if test "$want_native_pkcs11" = "yes" then use_pkcs11="yes" else use_pkcs11="no" fi fi case "$use_pkcs11" in no) AC_MSG_RESULT(no) USE_PKCS11="" PKCS11_TEST="" PKCS11_TOOLS="" ISC_PK11_C="" ISC_PK11_O="" ISC_PK11_API_C="" ISC_PK11_API_O="" ISC_PK11_RESULT_C="" ISC_PK11_RESULT_O="" ISC_ISCPK11_API_C="" ISC_ISCPK11_API_O="" ;; yes|*) AC_MSG_RESULT(yes) if ! $use_threads; then AC_MSG_ERROR([PKCS11 requires thread support]) fi if test "$CRYPTO" = "-DOPENSSL" then AC_MSG_CHECKING(for OpenSSL with PKCS11 support) saved_cc="$CC" saved_cflags="$CFLAGS" saved_libs="$LIBS" CC="$CC -pthread" CFLAGS="$CFLAGS $DST_OPENSSL_INC" LIBS="$LIBS $DST_OPENSSL_LIBS" AC_TRY_RUN([ #include #include int main() { ENGINE *e; OPENSSL_config(NULL); e = ENGINE_by_id("pkcs11"); if (e == NULL) return (1); if (ENGINE_init(e) <= 0) return (1); return (0); } ], [AC_MSG_RESULT(yes) PKCS11_TEST=pkcs11ssl PKCS11_ENGINE='-DPKCS11_ENGINE="\"pkcs11\""'], [AC_MSG_RESULT(no) PKCS11_TEST='' PKCS11_ENGINE='-DPKCS11_ENGINE=NULL'], [AC_MSG_RESULT(cross compile, defaulting to no) PKCS11_TEST='' PKCS11_ENGINE='-DPKCS11_ENGINE=NULL']) CC="$saved_cc" CFLAGS="$saved_cflags" LIBS="$saved_libs" else PKCS11_TEST='' PKCS11_ENGINE='-DPKCS11_ENGINE=NULL' fi USE_PKCS11='-DUSE_PKCS11' PKCS11_TOOLS=pkcs11 AC_CHECK_FUNC(getpassphrase, AC_DEFINE(HAVE_GETPASSPHRASE),) ISC_PK11_C="pk11.c" ISC_PK11_O="pk11.$O" ISC_PK11_API_C="pk11_api.c" ISC_PK11_API_O="pk11_api.$O" ISC_PK11_RESULT_C="pk11_result.c" ISC_PK11_RESULT_O="pk11_result.$O" ISC_ISCPK11_API_C="unix/pk11_api.c" ISC_ISCPK11_API_O="unix/pk11_api.$O" ;; esac AC_SUBST(USE_PKCS11) AC_SUBST(PKCS11_TOOLS) AC_SUBST(PKCS11_ENGINE) AC_SUBST(ISC_PK11_C) AC_SUBST(ISC_PK11_O) AC_SUBST(ISC_PK11_API_C) AC_SUBST(ISC_PK11_API_O) AC_SUBST(ISC_PK11_RESULT_C) AC_SUBST(ISC_PK11_RESULT_O) AC_SUBST(ISC_ISCPK11_API_C) AC_SUBST(ISC_ISCPK11_API_O) AC_MSG_CHECKING(for PKCS11 tools) case "$use_pkcs11" in no) PKCS11_PROVIDER="undefined" AC_MSG_RESULT(disabled) ;; yes|'') PKCS11_PROVIDER="undefined" AC_MSG_RESULT(enabled) ;; *) PKCS11_PROVIDER="$use_pkcs11" AC_MSG_RESULT([enabled, PKCS11 provider is $PKCS11_PROVIDER]) ;; esac AC_SUBST(PKCS11_PROVIDER) PKCS11_ECDSA="" PKCS11_GOST="" AC_MSG_CHECKING(for native PKCS11) case "$want_native_pkcs11" in yes) AC_MSG_RESULT(using native PKCS11 crypto) PKCS11LINKOBJS='${PKCS11LINKOBJS}' PKCS11LINKSRCS='${PKCS11LINKSRCS}' PKCS11_TEST=pkcs11 AC_MSG_CHECKING(for PKCS11 ECDSA) case "$with_ecdsa" in no) AC_MSG_RESULT(disabled) ;; *) AC_MSG_RESULT(enabled) PKCS11_ECDSA="yes" AC_DEFINE(HAVE_PKCS11_ECDSA, 1, [Define if your PKCS11 provider supports ECDSA.]) ;; esac AC_MSG_CHECKING(for PKCS11 GOST) case "$with_gost" in yes) AC_MSG_RESULT(enabled) PKCS11_GOST="yes" AC_DEFINE(HAVE_PKCS11_GOST, 1, [Define if your PKCS11 provider supports GOST.]) ;; *) AC_MSG_RESULT(disabled) ;; esac ;; no|'') AC_MSG_RESULT(disabled) ;; esac AC_SUBST(PKCS11LINKOBJS) AC_SUBST(PKCS11LINKSRCS) AC_SUBST(CRYPTO) AC_SUBST(PKCS11_ECDSA) AC_SUBST(PKCS11_GOST) AC_SUBST(PKCS11_TEST) # for PKCS11 benchmarks have_clock_gt=no AC_CHECK_FUNC(clock_gettime,have_clock_gt=yes,) if test "$have_clock_gt" = "no"; then AC_CHECK_LIB(rt,clock_gettime,have_clock_gt=rt,) fi if test "$have_clock_gt" != "no"; then AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [Define if clock_gettime is available.]) fi if test "$have_clock_gt" = "rt"; then LIBS="-lrt $LIBS" fi # # was --with-libxml2 specified? # AC_MSG_CHECKING(for libxml2 library) AC_ARG_WITH(libxml2, [ --with-libxml2[=PATH] build with libxml2 library [yes|no|path]], use_libxml2="$withval", use_libxml2="auto") case "$use_libxml2" in no) DST_LIBXML2_INC="" ;; auto|yes) case X`(xml2-config --version) 2>/dev/null` in X2.[[6789]].*) libxml2_libs=`xml2-config --libs` libxml2_cflags=`xml2-config --cflags` ;; *) if test "$use_libxml2" = "yes" ; then AC_MSG_RESULT(no) AC_MSG_ERROR(required libxml2 version not available) else libxml2_libs= libxml2_cflags= fi ;; esac ;; *) if test -f "$use_libxml2/bin/xml2-config" ; then libxml2_libs=`$use_libxml2/bin/xml2-config --libs` libxml2_cflags=`$use_libxml2/bin/xml2-config --cflags` fi ;; esac if test "X$libxml2_libs" != "X" then CFLAGS="$CFLAGS $libxml2_cflags" LIBS="$LIBS $libxml2_libs" # # Sanity check xml2-config output. # AC_TRY_LINK([#include ], [return(xmlTextWriterStartElement(NULL, NULL));], AC_MSG_RESULT(yes), AC_MSG_ERROR(xml2-config returns badness)) AC_DEFINE(HAVE_LIBXML2, 1, [Define if libxml2 was found]) else AC_MSG_RESULT(no) fi # # was --with-libjson specified? # AC_MSG_CHECKING(for json library) AC_ARG_WITH(libjson, [ --with-libjson[=PATH] build with libjson0 library [yes|no|path]], use_libjson="$withval", use_libjson="auto") have_libjson="" have_libjson_c="" case "$use_libjson" in no) libjson_libs="" ;; auto|yes) for d in /usr /usr/local /opt/local do if test -f "${d}/include/json/json.h" then if test ${d} != /usr then libjson_cflags="-I ${d}/include" LIBS="$LIBS -L${d}/lib" fi have_libjson="yes" elif test -f "${d}/include/json-c/json.h" then if test ${d} != /usr then libjson_cflags="-I ${d}/include" LIBS="$LIBS -L${d}/lib" fi have_libjson="yes" have_libjson_c="yes" fi done ;; *) if test -f "${use_libjson}/include/json/json.h" then libjson_cflags="-I${use_libjson}/include" LIBS="$LIBS -L${use_libjson}/lib" have_libjson="yes" elif test -f "${use_libjson}/include/json-c/json.h" then libjson_cflags="-I${use_libjson}/include" LIBS="$LIBS -L${use_libjson}/lib" have_libjson="yes" have_libjson_c="yes" else AC_MSG_ERROR([$use_libjson/include/json{,-c}/json.h not found.]) fi ;; esac if test "X${have_libjson}" != "X" then AC_MSG_RESULT(yes) AC_SEARCH_LIBS([json_object_new_int64], [json json-c], [], [AC_MSG_ERROR([found libjson include but not library.]) have_libjson=""]) elif test "X$use_libjson" = Xyes then AC_MSG_ERROR([include/json{,-c}/json.h not found.]) else AC_MSG_RESULT(no) fi if test "X${have_libjson}" != "X" then CFLAGS="$CFLAGS $libjson_cflags" AC_DEFINE(HAVE_JSON, 1, [Define if libjson was found]) if test "X${have_libjson_c}" = Xyes then AC_DEFINE(HAVE_JSON_C, 1, [Define if json-c was found]) fi fi # # In solaris 10, SMF can manage named service # AC_CHECK_LIB(scf, smf_enable_instance) # # flockfile is usually provided by pthreads, but we may want to use it # even if compiled with --disable-threads. getc_unlocked might also not # be defined. # AC_CHECK_FUNC(flockfile, AC_DEFINE(HAVE_FLOCKFILE),) AC_CHECK_FUNC(getc_unlocked, AC_DEFINE(HAVE_GETCUNLOCKED),) # # Indicate what the final decision was regarding threads. # AC_MSG_CHECKING(whether to build with threads) if $use_threads; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi # # End of pthreads stuff. # # # Large File # AC_ARG_ENABLE(largefile, [ --enable-largefile 64-bit file support], want_largefile="yes", want_largefile="no") case $want_largefile in yes) ALWAYS_DEFINES="$ALWAYS_DEFINES -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" ;; *) ;; esac # # Additional compiler settings. # MKDEPCC="$CC" MKDEPCFLAGS="-M" IRIX_DNSSEC_WARNINGS_HACK="" if test "X$GCC" = "Xyes"; then STD_CWARNINGS="$STD_CWARNINGS -W -Wall -Wmissing-prototypes -Wcast-qual -Wwrite-strings -Wformat -Wpointer-arith" AC_MSG_CHECKING(if "$CC" supports -fno-strict-aliasing) SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -fno-strict-aliasing" AC_TRY_COMPILE(,, [FNOSTRICTALIASING=yes],[FNOSTRICTALIASING=no]) CFLAGS="$SAVE_CFLAGS" if test "$FNOSTRICTALIASING" = "yes"; then AC_MSG_RESULT(yes) STD_CWARNINGS="$STD_CWARNINGS -fno-strict-aliasing" else AC_MSG_RESULT(no) fi # # turn off delete null pointer checks # AC_MSG_CHECKING(if "$CC" supports -fno-delete-null-pointer-checks) SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror -fno-delete-null-pointer-checks" AC_TRY_COMPILE(,, [FNODELETENULLPOINTERCHECKS=yes], [FNODELETENULLPOINTERCHECKS=no]) CFLAGS="$SAVE_CFLAGS" if test "$FNODELETENULLPOINTERCHECKS" = "yes"; then AC_MSG_RESULT(yes) STD_CWARNINGS="$STD_CWARNINGS -fno-delete-null-pointer-checks" else AC_MSG_RESULT(no) fi case "$host" in *-hp-hpux*) CFLAGS="$CFLAGS -Wl,+vnocompatwarnings" BACKTRACECFLAGS="$BACKTRACECFLAGS -Wl,+vnocompatwarnings" ;; esac if test "X$enable_warn_shadow" = Xyes; then STD_CWARNINGS="$STD_CWARNINGS -Wshadow" fi if test "X$enable_warn_error" = Xyes; then STD_CWARNINGS="$STD_CWARNINGS -Werror" fi else case $host in *-dec-osf*) CC="$CC -std" CCOPT="$CCOPT -std" CCNOOPT="$CCNOOPT -std" MKDEPCC="$CC" ;; *-hp-hpux*) CC="$CC -Ae -z" # The version of the C compiler that constantly warns about # 'const' as well as alignment issues is unfortunately not # able to be discerned via the version of the operating # system, nor does cc have a version flag. case "`$CC +W 123 2>&1`" in *Unknown?option*) STD_CWARNINGS="+w1" ;; *) # Turn off the pointlessly noisy warnings. STD_CWARNINGS="+w1 +W 474,530,2193,2236" ;; esac CCOPT="$CCOPT -Ae -z" CCNOOPT="$CCNOOPT -Ae -z" CFLAGS="$CFLAGS -Wl,+vnocompatwarnings" BACKTRACECFLAGS="$BACKTRACECFLAGS -Wl,+vnocompatwarnings" MKDEPPROG='cc -Ae -E -Wp,-M >/dev/null 2>>$TMP' ;; *-sgi-irix*) STD_CWARNINGS="-fullwarn -woff 1209" # # Silence more than 250 instances of # "prototyped function redeclared without prototype" # and 11 instances of # "variable ... was set but never used" # from lib/dns/sec/openssl. # IRIX_DNSSEC_WARNINGS_HACK="-woff 1692,1552" ;; *-solaris*) MKDEPCFLAGS="-xM" ;; *-sco-sysv*uw*|*-*-sysv*UnixWare*|*-*-sysv*OpenUNIX*) # UnixWare CC="$CC -w" ;; esac fi AC_SUBST(MKDEPCC) AC_SUBST(MKDEPCFLAGS) AC_SUBST(MKDEPPROG) AC_SUBST(IRIX_DNSSEC_WARNINGS_HACK) # # NLS # AC_CHECK_FUNC(catgets, AC_DEFINE(HAVE_CATGETS),) # # -lxnet buys us one big porting headache... standards, gotta love 'em. # # AC_CHECK_LIB(xnet, socket, , # AC_CHECK_LIB(socket, socket) # ) # # Use this for now, instead: # case "$host" in mips-sgi-irix*) ;; *-linux*) ;; *) AC_CHECK_LIB(socket, socket) AC_CHECK_LIB(nsl, inet_addr) ;; esac # # Work around Solaris's select() limitations. # case "$host" in *-solaris2.[[89]]|*-solaris2.1?) AC_DEFINE(FD_SETSIZE, 65536, [Solaris hack to get select_large_fdset.]) ;; esac # # Purify support # AC_MSG_CHECKING(whether to use purify) AC_ARG_WITH(purify, [ --with-purify[=PATH] use Rational purify], use_purify="$withval", use_purify="no") case "$use_purify" in no) ;; yes) AC_PATH_PROG(purify_path, purify, purify) ;; *) purify_path="$use_purify" ;; esac case "$use_purify" in no) AC_MSG_RESULT(no) PURIFY="" ;; *) if test -f $purify_path || test $purify_path = purify; then AC_MSG_RESULT($purify_path) PURIFYFLAGS="`echo $PURIFYOPTIONS`" PURIFY="$purify_path $PURIFYFLAGS" else AC_MSG_ERROR([$purify_path not found. Please choose the proper path with the following command: configure --with-purify=PATH ]) fi ;; esac AC_SUBST(PURIFY) # # Google/Great Performance Tools CPU Profiler # AC_MSG_CHECKING(whether to use gperftools profiler) AC_ARG_WITH(gperftools-profiler, [ --with-gperftools-profiler use gperftools CPU profiler], use_profiler="$withval", use_profiler="no") case $use_profiler in yes) AC_MSG_RESULT(yes) AC_DEFINE([HAVE_GPERFTOOLS_PROFILER], 1, [Define to use gperftools CPU profiler.]) LIBS="$LIBS -lprofiler" ;; *) AC_MSG_RESULT(no) ;; esac # # enable/disable dumping stack backtrace. Also check if the system supports # glibc-compatible backtrace() function. # AC_ARG_ENABLE(backtrace, [ --enable-backtrace log stack backtrace on abort [[default=yes]]], want_backtrace="$enableval", want_backtrace="yes") case $want_backtrace in yes) ISC_PLATFORM_USEBACKTRACE="#define ISC_PLATFORM_USEBACKTRACE 1" AC_TRY_LINK([#include ], [return (backtrace((void **)0, 0));], [AC_DEFINE([HAVE_LIBCTRACE], [], [if system have backtrace function])],) ;; *) ISC_PLATFORM_USEBACKTRACE="#undef ISC_PLATFORM_USEBACKTRACE" ;; esac AC_SUBST(ISC_PLATFORM_USEBACKTRACE) AC_ARG_ENABLE(symtable, [ --enable-symtable use internal symbol table for backtrace [[all|minimal(default)|none]]], want_symtable="$enableval", want_symtable="minimal") case $want_symtable in yes|all|minimal) # "yes" is a hidden value equivalent to "minimal" if test "$PERL" = "" then AC_MSG_ERROR([Internal symbol table requires perl but no perl is found. Install perl or explicitly disable the feature by --disable-symtable.]) fi if test "$use_libtool" = "yes"; then AC_MSG_WARN([Internal symbol table does not work with libtool. Disabling symbol table.]) else # we generate the internal symbol table only for those systems # known to work to avoid unexpected build failure. Also, warn # about unsupported systems when the feature is enabled # manually. case $host_os in freebsd*|netbsd*|openbsd*|linux*|solaris*|darwin*) MKSYMTBL_PROGRAM="$PERL" if test $want_symtable = all; then ALWAYS_MAKE_SYMTABLE="yes" fi ;; *) if test $want_symtable = yes -o $want_symtable = all then AC_MSG_WARN([this system is not known to generate internal symbol table safely; disabling it]) fi esac fi ;; *) ;; esac AC_SUBST(MKSYMTBL_PROGRAM) AC_SUBST(ALWAYS_MAKE_SYMTABLE) # # File name extension for static archive files, for those few places # where they are treated differently from dynamic ones. # SA=a AC_SUBST(O) AC_SUBST(A) AC_SUBST(SA) AC_SUBST(LIBTOOL_MKDEP_SED) AC_SUBST(LIBTOOL_MODE_COMPILE) AC_SUBST(LIBTOOL_MODE_INSTALL) AC_SUBST(LIBTOOL_MODE_LINK) AC_SUBST(LIBTOOL_ALLOW_UNDEFINED) AC_SUBST(LIBTOOL_IN_MAIN) BIND9_CO_RULE=".c.$O:" AC_SUBST(BIND9_CO_RULE) # # Here begins a very long section to determine the system's networking # capabilities. The order of the tests is significant. # # # IPv6 # AC_ARG_ENABLE(ipv6, [ --enable-ipv6 use IPv6 [default=autodetect]]) case "$enable_ipv6" in yes|''|autodetect) AC_DEFINE(WANT_IPV6) ;; no) ;; esac # # We do the IPv6 compilation checking after libtool so that we can put # the right suffix on the files. # AC_MSG_CHECKING(for IPv6 structures) AC_TRY_COMPILE([ #include #include #include ], [struct sockaddr_in6 sin6; return (0);], [AC_MSG_RESULT(yes) found_ipv6=yes], [AC_MSG_RESULT(no) found_ipv6=no]) # # See whether IPv6 support is provided via a Kame add-on. # This is done before other IPv6 linking tests to LIBS is properly set. # AC_MSG_CHECKING(for Kame IPv6 support) AC_ARG_WITH(kame, [ --with-kame[=PATH] use Kame IPv6 [default path /usr/local/v6]], use_kame="$withval", use_kame="no") case "$use_kame" in no) ;; yes) kame_path=/usr/local/v6 ;; *) kame_path="$use_kame" ;; esac case "$use_kame" in no) AC_MSG_RESULT(no) ;; *) if test -f $kame_path/lib/libinet6.a; then AC_MSG_RESULT($kame_path/lib/libinet6.a) LIBS="-L$kame_path/lib -linet6 $LIBS" else AC_MSG_ERROR([$kame_path/lib/libinet6.a not found. Please choose the proper path with the following command: configure --with-kame=PATH ]) fi ;; esac # # Whether netinet6/in6.h is needed has to be defined in isc/platform.h. # Including it on Kame-using platforms is very bad, though, because # Kame uses #error against direct inclusion. So include it on only # the platform that is otherwise broken without it -- BSD/OS 4.0 through 4.1. # This is done before the in6_pktinfo check because that's what # netinet6/in6.h is needed for. # changequote({, }) case "$host" in *-bsdi4.[01]*) ISC_PLATFORM_NEEDNETINET6IN6H="#define ISC_PLATFORM_NEEDNETINET6IN6H 1" LWRES_PLATFORM_NEEDNETINET6IN6H="#define LWRES_PLATFORM_NEEDNETINET6IN6H 1" isc_netinet6in6_hack="#include " ;; *) ISC_PLATFORM_NEEDNETINET6IN6H="#undef ISC_PLATFORM_NEEDNETINET6IN6H" LWRES_PLATFORM_NEEDNETINET6IN6H="#undef LWRES_PLATFORM_NEEDNETINET6IN6H" isc_netinet6in6_hack="" ;; esac changequote([, ]) # # This is similar to the netinet6/in6.h issue. # case "$host" in *-sco-sysv*uw*|*-*-sysv*UnixWare*|*-*-sysv*OpenUNIX*) # UnixWare ISC_PLATFORM_NEEDNETINETIN6H="#define ISC_PLATFORM_NEEDNETINETIN6H 1" LWRES_PLATFORM_NEEDNETINETIN6H="#define LWRES_PLATFORM_NEEDNETINETIN6H 1" ISC_PLATFORM_FIXIN6ISADDR="#define ISC_PLATFORM_FIXIN6ISADDR 1" isc_netinetin6_hack="#include " ;; *) ISC_PLATFORM_NEEDNETINETIN6H="#undef ISC_PLATFORM_NEEDNETINETIN6H" LWRES_PLATFORM_NEEDNETINETIN6H="#undef LWRES_PLATFORM_NEEDNETINETIN6H" ISC_PLATFORM_FIXIN6ISADDR="#undef ISC_PLATFORM_FIXIN6ISADDR" isc_netinetin6_hack="" ;; esac # # Now delve deeper into the suitability of the IPv6 support. # case "$found_ipv6" in yes) ISC_PLATFORM_HAVEIPV6="#define ISC_PLATFORM_HAVEIPV6 1" LWRES_PLATFORM_HAVEIPV6="#define LWRES_PLATFORM_HAVEIPV6 1" AC_MSG_CHECKING(for in6_addr) AC_TRY_COMPILE([ #include #include #include $isc_netinetin6_hack $isc_netinet6in6_hack ], [struct in6_addr in6; return (0);], [AC_MSG_RESULT(yes) ISC_PLATFORM_HAVEINADDR6="#undef ISC_PLATFORM_HAVEINADDR6" LWRES_PLATFORM_HAVEINADDR6="#undef LWRES_PLATFORM_HAVEINADDR6" isc_in_addr6_hack=""], [AC_MSG_RESULT(no) ISC_PLATFORM_HAVEINADDR6="#define ISC_PLATFORM_HAVEINADDR6 1" LWRES_PLATFORM_HAVEINADDR6="#define LWRES_PLATFORM_HAVEINADDR6 1" isc_in_addr6_hack="#define in6_addr in_addr6"]) AC_MSG_CHECKING(for in6addr_any) AC_TRY_LINK([ #include #include #include $isc_netinetin6_hack $isc_netinet6in6_hack $isc_in_addr6_hack ], [struct in6_addr in6; in6 = in6addr_any; return (in6.s6_addr[0]);], [AC_MSG_RESULT(yes) ISC_PLATFORM_NEEDIN6ADDRANY="#undef ISC_PLATFORM_NEEDIN6ADDRANY" LWRES_PLATFORM_NEEDIN6ADDRANY="#undef LWRES_PLATFORM_NEEDIN6ADDRANY"], [AC_MSG_RESULT(no) ISC_PLATFORM_NEEDIN6ADDRANY="#define ISC_PLATFORM_NEEDIN6ADDRANY 1" LWRES_PLATFORM_NEEDIN6ADDRANY="#define LWRES_PLATFORM_NEEDIN6ADDRANY 1"]) AC_MSG_CHECKING(for in6addr_loopback) AC_TRY_LINK([ #include #include #include $isc_netinetin6_hack $isc_netinet6in6_hack $isc_in_addr6_hack ], [struct in6_addr in6; in6 = in6addr_loopback; return (in6.s6_addr[0]);], [AC_MSG_RESULT(yes) ISC_PLATFORM_NEEDIN6ADDRLOOPBACK="#undef ISC_PLATFORM_NEEDIN6ADDRLOOPBACK" LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK="#undef LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK"], [AC_MSG_RESULT(no) ISC_PLATFORM_NEEDIN6ADDRLOOPBACK="#define ISC_PLATFORM_NEEDIN6ADDRLOOPBACK 1" LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK="#define LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK 1"]) AC_MSG_CHECKING(for sin6_scope_id in struct sockaddr_in6) AC_TRY_COMPILE([ #include #include #include $isc_netinetin6_hack $isc_netinet6in6_hack ], [struct sockaddr_in6 xyzzy; xyzzy.sin6_scope_id = 0; return (0);], [AC_MSG_RESULT(yes) ISC_PLATFORM_HAVESCOPEID="#define ISC_PLATFORM_HAVESCOPEID 1" result="#define LWRES_HAVE_SIN6_SCOPE_ID 1"], [AC_MSG_RESULT(no) ISC_PLATFORM_HAVESCOPEID="#undef ISC_PLATFORM_HAVESCOPEID" result="#undef LWRES_HAVE_SIN6_SCOPE_ID"]) LWRES_HAVE_SIN6_SCOPE_ID="$result" AC_MSG_CHECKING(for in6_pktinfo) AC_TRY_COMPILE([ #include #include #include $isc_netinetin6_hack $isc_netinet6in6_hack ], [struct in6_pktinfo xyzzy; return (0);], [AC_MSG_RESULT(yes) ISC_PLATFORM_HAVEIN6PKTINFO="#define ISC_PLATFORM_HAVEIN6PKTINFO 1"], [AC_MSG_RESULT(no -- disabling runtime ipv6 support) ISC_PLATFORM_HAVEIN6PKTINFO="#undef ISC_PLATFORM_HAVEIN6PKTINFO"]) ;; no) ISC_PLATFORM_HAVEIPV6="#undef ISC_PLATFORM_HAVEIPV6" LWRES_PLATFORM_HAVEIPV6="#undef LWRES_PLATFORM_HAVEIPV6" ISC_PLATFORM_NEEDIN6ADDRANY="#undef ISC_PLATFORM_NEEDIN6ADDRANY" LWRES_PLATFORM_NEEDIN6ADDRANY="#undef LWRES_PLATFORM_NEEDIN6ADDRANY" ISC_PLATFORM_HAVEIN6PKTINFO="#undef ISC_PLATFORM_HAVEIN6PKTINFO" LWRES_HAVE_SIN6_SCOPE_ID="#define LWRES_HAVE_SIN6_SCOPE_ID 1" ISC_PLATFORM_HAVESCOPEID="#define ISC_PLATFORM_HAVESCOPEID 1" ISC_IPV6_H="ipv6.h" ISC_IPV6_O="ipv6.$O" ISC_ISCIPV6_O="unix/ipv6.$O" ISC_IPV6_C="ipv6.c" ;; esac AC_MSG_CHECKING(for struct sockaddr_storage) AC_TRY_COMPILE([ #include #include $isc_netinetin6_hack $isc_netinet6in6_hack ], [struct sockaddr_storage storage; return (0);], [AC_MSG_RESULT(yes) ISC_PLATFORM_HAVESOCKADDRSTORAGE="#define ISC_PLATFORM_HAVESOCKADDRSTORAGE 1"], [AC_MSG_RESULT(no) ISC_PLATFORM_HAVESOCKADDRSTORAGE="#undef ISC_PLATFORM_HAVESOCKADDRSTORAGE"]) AC_SUBST(ISC_PLATFORM_HAVEIPV6) AC_SUBST(LWRES_PLATFORM_HAVEIPV6) AC_SUBST(ISC_PLATFORM_NEEDNETINETIN6H) AC_SUBST(LWRES_PLATFORM_NEEDNETINETIN6H) AC_SUBST(ISC_PLATFORM_NEEDNETINET6IN6H) AC_SUBST(LWRES_PLATFORM_NEEDNETINET6IN6H) AC_SUBST(ISC_PLATFORM_HAVEINADDR6) AC_SUBST(LWRES_PLATFORM_HAVEINADDR6) AC_SUBST(ISC_PLATFORM_NEEDIN6ADDRANY) AC_SUBST(LWRES_PLATFORM_NEEDIN6ADDRANY) AC_SUBST(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK) AC_SUBST(LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK) AC_SUBST(ISC_PLATFORM_HAVEIN6PKTINFO) AC_SUBST(ISC_PLATFORM_FIXIN6ISADDR) AC_SUBST(ISC_PLATFORM_HAVESOCKADDRSTORAGE) AC_SUBST(ISC_IPV6_H) AC_SUBST(ISC_IPV6_O) AC_SUBST(ISC_ISCIPV6_O) AC_SUBST(ISC_IPV6_C) AC_SUBST(LWRES_HAVE_SIN6_SCOPE_ID) AC_SUBST(ISC_PLATFORM_HAVESCOPEID) AC_MSG_CHECKING([for struct if_laddrreq]) AC_TRY_LINK([ #include #include ],[ struct if_laddrreq a; ], [AC_MSG_RESULT(yes) ISC_PLATFORM_HAVEIF_LADDRREQ="#define ISC_PLATFORM_HAVEIF_LADDRREQ 1"], [AC_MSG_RESULT(no) ISC_PLATFORM_HAVEIF_LADDRREQ="#undef ISC_PLATFORM_HAVEIF_LADDRREQ"]) AC_SUBST(ISC_PLATFORM_HAVEIF_LADDRREQ) AC_MSG_CHECKING([for struct if_laddrconf]) AC_TRY_LINK([ #include #include ],[ struct if_laddrconf a; ], [AC_MSG_RESULT(yes) ISC_PLATFORM_HAVEIF_LADDRCONF="#define ISC_PLATFORM_HAVEIF_LADDRCONF 1"], [AC_MSG_RESULT(no) ISC_PLATFORM_HAVEIF_LADDRCONF="#undef ISC_PLATFORM_HAVEIF_LADDRCONF"]) AC_SUBST(ISC_PLATFORM_HAVEIF_LADDRCONF) # # Check for network functions that are often missing. We do this # after the libtool checking, so we can put the right suffix on # the files. It also needs to come after checking for a Kame add-on, # which provides some (all?) of the desired functions. # AC_MSG_CHECKING([for inet_ntop with IPv6 support]) AC_TRY_RUN([ #include #include #include #include main() { char a[16],b[64]; return(inet_ntop(AF_INET6, a, b, sizeof(b)) == (char*)0);}], [AC_MSG_RESULT(yes) ISC_PLATFORM_NEEDNTOP="#undef ISC_PLATFORM_NEEDNTOP"], [AC_MSG_RESULT(no) ISC_EXTRA_OBJS="$ISC_EXTRA_OBJS inet_ntop.$O" ISC_EXTRA_SRCS="$ISC_EXTRA_SRCS inet_ntop.c" ISC_PLATFORM_NEEDNTOP="#define ISC_PLATFORM_NEEDNTOP 1"], [AC_MSG_RESULT(assuming inet_ntop not needed) ISC_PLATFORM_NEEDNTOP="#undef ISC_PLATFORM_NEEDNTOP"]) # On NetBSD 1.4.2 and maybe others, inet_pton() incorrectly accepts # addresses with less than four octets, like "1.2.3". Also leading # zeros should also be rejected. AC_MSG_CHECKING([for working inet_pton with IPv6 support]) AC_TRY_RUN([ #include #include #include #include main() { char a[16]; return (inet_pton(AF_INET, "1.2.3", a) == 1 ? 1 : inet_pton(AF_INET, "1.2.3.04", a) == 1 ? 1 : (inet_pton(AF_INET6, "::1.2.3.4", a) != 1)); }], [AC_MSG_RESULT(yes) ISC_PLATFORM_NEEDPTON="#undef ISC_PLATFORM_NEEDPTON"], [AC_MSG_RESULT(no) ISC_EXTRA_OBJS="$ISC_EXTRA_OBJS inet_pton.$O" ISC_EXTRA_SRCS="$ISC_EXTRA_SRCS inet_pton.c" ISC_PLATFORM_NEEDPTON="#define ISC_PLATFORM_NEEDPTON 1"], [AC_MSG_RESULT(assuming inet_pton needed) ISC_EXTRA_OBJS="$ISC_EXTRA_OBJS inet_pton.$O" ISC_EXTRA_SRCS="$ISC_EXTRA_SRCS inet_pton.c" ISC_PLATFORM_NEEDPTON="#define ISC_PLATFORM_NEEDPTON 1"]) AC_SUBST(ISC_PLATFORM_NEEDNTOP) AC_SUBST(ISC_PLATFORM_NEEDPTON) # # Look for a 4.4BSD-style sa_len member in struct sockaddr. # case "$host" in *-dec-osf*) # Turn on 4.4BSD style sa_len support. AC_DEFINE(_SOCKADDR_LEN) ;; esac AC_MSG_CHECKING(for sa_len in struct sockaddr) AC_TRY_COMPILE([ #include #include ], [struct sockaddr sa; sa.sa_len = 0; return (0);], [AC_MSG_RESULT(yes) ISC_PLATFORM_HAVESALEN="#define ISC_PLATFORM_HAVESALEN 1" LWRES_PLATFORM_HAVESALEN="#define LWRES_PLATFORM_HAVESALEN 1"], [AC_MSG_RESULT(no) ISC_PLATFORM_HAVESALEN="#undef ISC_PLATFORM_HAVESALEN" LWRES_PLATFORM_HAVESALEN="#undef LWRES_PLATFORM_HAVESALEN"]) AC_SUBST(ISC_PLATFORM_HAVESALEN) AC_SUBST(LWRES_PLATFORM_HAVESALEN) # # Look for a 4.4BSD or 4.3BSD struct msghdr # AC_MSG_CHECKING(for struct msghdr flavor) AC_TRY_COMPILE([ #include #include ], [struct msghdr msg; msg.msg_flags = 0; return (0);], [AC_MSG_RESULT(4.4BSD) ISC_PLATFORM_MSGHDRFLAVOR="#define ISC_NET_BSD44MSGHDR 1"], [AC_MSG_RESULT(4.3BSD) ISC_PLATFORM_MSGHDRFLAVOR="#define ISC_NET_BSD43MSGHDR 1"]) AC_SUBST(ISC_PLATFORM_MSGHDRFLAVOR) # # Look for in_port_t. # AC_MSG_CHECKING(for type in_port_t) AC_TRY_COMPILE([ #include #include ], [in_port_t port = 25; return (0);], [AC_MSG_RESULT(yes) ISC_PLATFORM_NEEDPORTT="#undef ISC_PLATFORM_NEEDPORTT"], [AC_MSG_RESULT(no) ISC_PLATFORM_NEEDPORTT="#define ISC_PLATFORM_NEEDPORTT 1"]) AC_SUBST(ISC_PLATFORM_NEEDPORTT) # # Check for addrinfo # AC_MSG_CHECKING(for struct addrinfo) AC_TRY_COMPILE([ #include ], [struct addrinfo a; return (0);], [AC_MSG_RESULT(yes) ISC_LWRES_NEEDADDRINFO="#undef ISC_LWRES_NEEDADDRINFO" ISC_IRS_NEEDADDRINFO="#undef ISC_IRS_NEEDADDRINFO" AC_DEFINE(HAVE_ADDRINFO)], [AC_MSG_RESULT(no) ISC_LWRES_NEEDADDRINFO="#define ISC_LWRES_NEEDADDRINFO 1" ISC_IRS_NEEDADDRINFO="#define ISC_IRS_NEEDADDRINFO 1"]) AC_SUBST(ISC_LWRES_NEEDADDRINFO) AC_SUBST(ISC_IRS_NEEDADDRINFO) # # Check for rrsetinfo # AC_MSG_CHECKING(for struct rrsetinfo) AC_TRY_COMPILE([ #include ], [struct rrsetinfo r; return (0);], [AC_MSG_RESULT(yes) ISC_LWRES_NEEDRRSETINFO="#undef ISC_LWRES_NEEDRRSETINFO"], [AC_MSG_RESULT(no) ISC_LWRES_NEEDRRSETINFO="#define ISC_LWRES_NEEDRRSETINFO 1"]) AC_SUBST(ISC_LWRES_NEEDRRSETINFO) AC_MSG_CHECKING(for int sethostent) AC_TRY_COMPILE([ #include ], [int i = sethostent(0); return(0);], [AC_MSG_RESULT(yes) ISC_LWRES_SETHOSTENTINT="#define ISC_LWRES_SETHOSTENTINT 1"], [AC_MSG_RESULT(no) ISC_LWRES_SETHOSTENTINT="#undef ISC_LWRES_SETHOSTENTINT"]) AC_SUBST(ISC_LWRES_SETHOSTENTINT) AC_MSG_CHECKING(for int endhostent) AC_TRY_COMPILE([ #include ], [int i = endhostent(); return(0);], [AC_MSG_RESULT(yes) ISC_LWRES_ENDHOSTENTINT="#define ISC_LWRES_ENDHOSTENTINT 1"], [AC_MSG_RESULT(no) ISC_LWRES_ENDHOSTENTINT="#undef ISC_LWRES_ENDHOSTENTINT"]) AC_SUBST(ISC_LWRES_ENDHOSTENTINT) AC_MSG_CHECKING(for getnetbyaddr(in_addr_t, ...)) AC_TRY_COMPILE([ #include struct netent *getnetbyaddr(in_addr_t, int);], [], [AC_MSG_RESULT(yes) ISC_LWRES_GETNETBYADDRINADDR="#define ISC_LWRES_GETNETBYADDRINADDR 1"], [AC_MSG_RESULT(no) ISC_LWRES_GETNETBYADDRINADDR="#undef ISC_LWRES_GETNETBYADDRINADDR"]) AC_SUBST(ISC_LWRES_GETNETBYADDRINADDR) AC_MSG_CHECKING(for int setnetent) AC_TRY_COMPILE([ #include ], [int i = setnetent(0); return(0);], [AC_MSG_RESULT(yes) ISC_LWRES_SETNETENTINT="#define ISC_LWRES_SETNETENTINT 1"], [AC_MSG_RESULT(no) ISC_LWRES_SETNETENTINT="#undef ISC_LWRES_SETNETENTINT"]) AC_SUBST(ISC_LWRES_SETNETENTINT) AC_MSG_CHECKING(for int endnetent) AC_TRY_COMPILE([ #include ], [int i = endnetent(); return(0);], [AC_MSG_RESULT(yes) ISC_LWRES_ENDNETENTINT="#define ISC_LWRES_ENDNETENTINT 1"], [AC_MSG_RESULT(no) ISC_LWRES_ENDNETENTINT="#undef ISC_LWRES_ENDNETENTINT"]) AC_SUBST(ISC_LWRES_ENDNETENTINT) AC_MSG_CHECKING(for gethostbyaddr(const void *, size_t, ...)) AC_TRY_COMPILE([ #include struct hostent *gethostbyaddr(const void *, size_t, int);], [return(0);], [AC_MSG_RESULT(yes) ISC_LWRES_GETHOSTBYADDRVOID="#define ISC_LWRES_GETHOSTBYADDRVOID 1"], [AC_MSG_RESULT(no) ISC_LWRES_GETHOSTBYADDRVOID="#undef ISC_LWRES_GETHOSTBYADDRVOID"]) AC_SUBST(ISC_LWRES_GETHOSTBYADDRVOID) AC_MSG_CHECKING(for h_errno in netdb.h) AC_TRY_COMPILE([ #include ], [h_errno = 1; return(0);], [AC_MSG_RESULT(yes) ISC_LWRES_NEEDHERRNO="#undef ISC_LWRES_NEEDHERRNO"], [AC_MSG_RESULT(no) ISC_LWRES_NEEDHERRNO="#define ISC_LWRES_NEEDHERRNO 1"]) AC_SUBST(ISC_LWRES_NEEDHERRNO) # # Sadly, the definitions of system-supplied getnameinfo(3) vary. Try to catch # known variations here: # AC_MSG_CHECKING(for getnameinfo prototype definitions) AC_TRY_COMPILE([ #include #include #include int getnameinfo(const struct sockaddr *, socklen_t, char *, socklen_t, char *, socklen_t, unsigned int);], [ return (0);], [AC_MSG_RESULT(socklen_t for buflen; u_int for flags) AC_DEFINE(IRS_GETNAMEINFO_SOCKLEN_T, socklen_t, [Define to the sockaddr length type used by getnameinfo(3).]) AC_DEFINE(IRS_GETNAMEINFO_BUFLEN_T, socklen_t, [Define to the buffer length type used by getnameinfo(3).]) AC_DEFINE(IRS_GETNAMEINFO_FLAGS_T, unsigned int, [Define to the flags type used by getnameinfo(3).])], [AC_TRY_COMPILE([ #include #include #include int getnameinfo(const struct sockaddr *, socklen_t, char *, size_t, char *, size_t, int);], [ return (0);], [AC_MSG_RESULT(size_t for buflen; int for flags) AC_DEFINE(IRS_GETNAMEINFO_SOCKLEN_T, socklen_t) AC_DEFINE(IRS_GETNAMEINFO_BUFLEN_T, size_t) AC_DEFINE(IRS_GETNAMEINFO_FLAGS_T, int)], [AC_TRY_COMPILE([ #include #include #include int getnameinfo(const struct sockaddr *, size_t, char *, size_t, char *, size_t, int);], [ return (0);], [AC_MSG_RESULT(size_t for buflen; int for flags) AC_DEFINE(IRS_GETNAMEINFO_SOCKLEN_T, size_t) AC_DEFINE(IRS_GETNAMEINFO_BUFLEN_T, size_t) AC_DEFINE(IRS_GETNAMEINFO_FLAGS_T, int)], [AC_MSG_RESULT(not match any subspecies; assume standard definition) AC_DEFINE(IRS_GETNAMEINFO_SOCKLEN_T, socklen_t) AC_DEFINE(IRS_GETNAMEINFO_BUFLEN_T, socklen_t) AC_DEFINE(IRS_GETNAMEINFO_FLAGS_T, int)])])]) # # ...and same for gai_strerror(). # AC_MSG_CHECKING(for gai_strerror prototype definitions) AC_TRY_COMPILE([ #include #include #include char *gai_strerror(int ecode);], [ return (0); ], [AC_MSG_RESULT(returning char *) AC_DEFINE([IRS_GAISTRERROR_RETURN_T], [char *], [return type of gai_strerror])], [AC_MSG_RESULT(not match any subspecies; assume standard definition) AC_DEFINE([IRS_GAISTRERROR_RETURN_T], [const char *])]) AC_CHECK_FUNC(getipnodebyname, [ISC_LWRES_GETIPNODEPROTO="#undef ISC_LWRES_GETIPNODEPROTO"], [ISC_LWRES_GETIPNODEPROTO="#define ISC_LWRES_GETIPNODEPROTO 1"]) AC_CHECK_FUNC(getnameinfo, [ISC_LWRES_GETNAMEINFOPROTO="#undef ISC_LWRES_GETNAMEINFOPROTO"], [ISC_LWRES_GETNAMEINFOPROTO="#define ISC_LWRES_GETNAMEINFOPROTO 1"]) AC_CHECK_FUNC(getaddrinfo, [ISC_LWRES_GETADDRINFOPROTO="#undef ISC_LWRES_GETADDRINFOPROTO" AC_DEFINE(HAVE_GETADDRINFO)], [ISC_LWRES_GETADDRINFOPROTO="#define ISC_LWRES_GETADDRINFOPROTO 1"]) AC_CHECK_FUNC(gai_strerror, AC_DEFINE(HAVE_GAISTRERROR)) AC_SUBST(ISC_LWRES_GETIPNODEPROTO) AC_SUBST(ISC_LWRES_GETADDRINFOPROTO) AC_SUBST(ISC_LWRES_GETNAMEINFOPROTO) AC_SUBST(ISC_IRS_GETNAMEINFOSOCKLEN) AC_ARG_ENABLE(getifaddrs, [ --enable-getifaddrs enable the use of getifaddrs() [[yes|no]].], want_getifaddrs="$enableval", want_getifaddrs="yes") # # This interface iteration code for getifaddrs() will fall back to using # /proc/net/if_inet6 if getifaddrs() in glibc doesn't return any IPv6 # addresses. # case $want_getifaddrs in glibc) AC_MSG_WARN("--enable-getifaddrs=glibc is no longer required") AC_CHECK_FUNC(getifaddrs, AC_DEFINE(HAVE_GETIFADDRS)) ;; yes) AC_CHECK_FUNC(getifaddrs, AC_DEFINE(HAVE_GETIFADDRS)) ;; no) ;; esac # # Look for a sysctl call to get the list of network interfaces. # case $ac_cv_header_sys_sysctl_h in yes) AC_MSG_CHECKING(for interface list sysctl) AC_EGREP_CPP(found_rt_iflist, [ #include #include #include #ifdef NET_RT_IFLIST found_rt_iflist #endif ], [AC_MSG_RESULT(yes) AC_DEFINE(HAVE_IFLIST_SYSCTL)], [AC_MSG_RESULT(no)]) ;; esac # # Check for some other useful functions that are not ever-present. # # We test for strsep() using AC_TRY_LINK instead of AC_CHECK_FUNC # because AIX 4.3.3 with patches for bos.adt.include to version 4.3.3.77 # reportedly defines strsep() without declaring it in when # -D_LINUX_SOURCE_COMPAT is not defined [RT #2190], and # AC_CHECK_FUNC() incorrectly succeeds because it declares # the function itself. AC_MSG_CHECKING(for correctly declared strsep()) AC_TRY_LINK([#include ], [char *sp; char *foo = strsep(&sp, ".");], [AC_MSG_RESULT(yes); ISC_PLATFORM_NEEDSTRSEP="#undef ISC_PLATFORM_NEEDSTRSEP"], [AC_MSG_RESULT(no); ISC_PLATFORM_NEEDSTRSEP="#define ISC_PLATFORM_NEEDSTRSEP 1"]) AC_SUBST(ISC_PLATFORM_NEEDSTRSEP) AC_CHECK_FUNC(memmove, [ISC_PLATFORM_NEEDMEMMOVE="#undef ISC_PLATFORM_NEEDMEMMOVE"], [ISC_PLATFORM_NEEDMEMMOVE="#define ISC_PLATFORM_NEEDMEMMOVE 1"]) AC_SUBST(ISC_PLATFORM_NEEDMEMMOVE) AC_CHECK_FUNC(strtoul, [ISC_PLATFORM_NEEDSTRTOUL="#undef ISC_PLATFORM_NEEDSTRTOUL" LWRES_PLATFORM_NEEDSTRTOUL="#undef LWRES_PLATFORM_NEEDSTRTOUL" GENRANDOMLIB=""], [ISC_PLATFORM_NEEDSTRTOUL="#define ISC_PLATFORM_NEEDSTRTOUL 1" LWRES_PLATFORM_NEEDSTRTOUL="#define LWRES_PLATFORM_NEEDSTRTOUL 1" GENRANDOMLIB='${ISCLIBS}']) AC_SUBST(ISC_PLATFORM_NEEDSTRTOUL) AC_SUBST(LWRES_PLATFORM_NEEDSTRTOUL) AC_SUBST(GENRANDOMLIB) AC_CHECK_FUNC(strlcpy, [ISC_PLATFORM_NEEDSTRLCPY="#undef ISC_PLATFORM_NEEDSTRLCPY" LWRES_PLATFORM_NEEDSTRLCPY="#undef LWRES_PLATFORM_NEEDSTRLCPY"], [ISC_PLATFORM_NEEDSTRLCPY="#define ISC_PLATFORM_NEEDSTRLCPY 1" LWRES_PLATFORM_NEEDSTRLCPY="#define LWRES_PLATFORM_NEEDSTRLCPY 1"]) AC_SUBST(ISC_PLATFORM_NEEDSTRLCPY) AC_SUBST(LWRES_PLATFORM_NEEDSTRLCPY) AC_CHECK_FUNC(strlcat, [ISC_PLATFORM_NEEDSTRLCAT="#undef ISC_PLATFORM_NEEDSTRLCAT"], [ISC_PLATFORM_NEEDSTRLCAT="#define ISC_PLATFORM_NEEDSTRLCAT 1"]) AC_SUBST(ISC_PLATFORM_NEEDSTRLCAT) AC_CHECK_FUNC(strcasestr, [ISC_PLATFORM_NEEDSTRCASESTR="#undef ISC_PLATFORM_NEEDSTRCASESTR"], [ISC_PLATFORM_NEEDSTRCASESTR="#define ISC_PLATFORM_NEEDSTRCASESTR 1"]) AC_SUBST(ISC_PLATFORM_NEEDSTRCASESTR) AC_SUBST(READLINE_LIB) AC_ARG_WITH(readline, [ --with-readline[=LIBSPEC] specify readline library [default auto]], readline="$withval", readline="auto") case "$readline" in no) ;; yes|auto) saved_LIBS="$LIBS" for readline in -ledit -lreadline do LIBS="$readline" AC_MSG_NOTICE(checking for readline with $readline) AC_CHECK_FUNCS(readline) if test "$ac_cv_func_readline" = "yes" then READLINE_LIB="$readline" break fi if test "X$readline" = "X" then continue fi for lib in -lterminfo -ltermcap -lncurses -lcurses do AC_MSG_NOTICE(checking for readline with $readline $lib) unset ac_cv_func_readline LIBS="$readline $lib" AC_CHECK_FUNCS(readline) if test "$ac_cv_func_readline" = "yes" then READLINE_LIB="$readline $lib" break fi done done LIBS="$saved_LIBS" ;; *) saved_LIBS="$LIBS" LIBS="$readline" AC_MSG_NOTICE(checking for readline with $readline) AC_CHECK_FUNCS(readline) if test "$ac_cv_func_readline" = "yes" then READLINE_LIB="$readline" else for lib in -lterminfo -ltermcap -lncurses -lcurses do AC_MSG_NOTICE(checking for readline with $readline $lib) unset ac_cv_func_readline LIBS="$readline $lib" AC_CHECK_FUNCS(readline) if test "$ac_cv_func_readline" = "yes" then READLINE_LIB="$readline $lib" break fi done fi LIBS="$saved_LIBS" ;; esac ISC_PRINT_OBJS= ISC_PRINT_SRCS= ISC_PLATFORM_NEEDPRINTF='#undef ISC_PLATFORM_NEEDPRINTF' ISC_PLATFORM_NEEDFPRINTF='#undef ISC_PLATFORM_NEEDFPRINTF' ISC_PLATFORM_NEEDSPRINTF='#undef ISC_PLATFORM_NEEDSPRINTF' ISC_PLATFORM_NEEDVSNPRINTF='#undef ISC_PLATFORM_NEEDVSNPRINTF' LWRES_PLATFORM_NEEDVSNPRINTF='#undef LWRES_PLATFORM_NEEDVSNPRINTF' AC_MSG_CHECKING(sprintf return type) AC_TRY_COMPILE([ #include ], [ char buf[2]; return(*sprintf(buf,"x"));], [AC_MSG_RESULT(char *) ISC_PRINT_OBJS="print.$O" ISC_PRINT_SRCS="print.c" ISC_PLATFORM_NEEDSPRINTF="#define ISC_PLATFORM_NEEDSPRINTF" LWRES_PLATFORM_NEEDSPRINTF="#define LWRES_PLATFORM_NEEDSPRINTF" ],[AC_MSG_RESULT(int)]) AC_CHECK_FUNC(vsnprintf, [], [ISC_PRINT_OBJS="print.$O" ISC_PRINT_SRCS="print.c" ISC_PLATFORM_NEEDVSNPRINTF="#define ISC_PLATFORM_NEEDVSNPRINTF 1" LWRES_PLATFORM_NEEDVSNPRINTF="#define LWRES_PLATFORM_NEEDVSNPRINTF 1"]) AC_MSG_CHECKING(printf for %z support) AC_TRY_RUN([ #include main() { size_t j = 0; char buf[100]; buf[0] = 0; sprintf(buf, "%zu", j); exit(strcmp(buf, "0") != 0); } ], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no) ISC_PRINT_OBJS="print.$O" ISC_PRINT_SRCS="print.c" ISC_PLATFORM_NEEDPRINTF='#define ISC_PLATFORM_NEEDPRINTF 1' ISC_PLATFORM_NEEDFPRINTF='#define ISC_PLATFORM_NEEDFPRINTF 1' ISC_PLATFORM_NEEDFSRINTF='#define ISC_PLATFORM_NEEDSPRINTF 1' ISC_PLATFORM_NEEDVSNPRINTF="#define ISC_PLATFORM_NEEDVSNPRINTF 1" LWRES_PLATFORM_NEEDVSNPRINTF="#define LWRES_PLATFORM_NEEDVSNPRINTF 1"], [AC_MSG_RESULT(assuming target platform supports %z)]) AC_SUBST(ISC_PLATFORM_NEEDPRINTF) AC_SUBST(ISC_PLATFORM_NEEDFPRINTF) AC_SUBST(ISC_PLATFORM_NEEDSPRINTF) AC_SUBST(ISC_PLATFORM_NEEDVSNPRINTF) AC_SUBST(LWRES_PLATFORM_NEEDSPRINTF) AC_SUBST(LWRES_PLATFORM_NEEDVSNPRINTF) ISC_EXTRA_OBJS="$ISC_EXTRA_OBJS $ISC_PRINT_OBJS" ISC_EXTRA_SRCS="$ISC_EXTRA_SRCS $ISC_PRINT_SRCS" AC_SUBST(ISC_EXTRA_OBJS) AC_SUBST(ISC_EXTRA_SRCS) AC_CHECK_FUNC(strerror, AC_DEFINE(HAVE_STRERROR)) # # Use our own SPNEGO implementation? # AC_ARG_ENABLE(isc-spnego, [ --disable-isc-spnego use SPNEGO from GSSAPI library]) if test -n "$USE_GSSAPI" then case "$enable_isc_spnego" in yes|'') USE_ISC_SPNEGO='-DUSE_ISC_SPNEGO' DST_EXTRA_OBJS="$DST_EXTRA_OBJS spnego.$O" DST_EXTRA_SRCS="$DST_EXTRA_SRCS spnego.c" AC_MSG_RESULT(using SPNEGO from lib/dns) ;; no) AC_MSG_RESULT(using SPNEGO from GSSAPI library) ;; esac fi AC_SUBST(USE_ISC_SPNEGO) AC_SUBST(DST_EXTRA_OBJS) AC_SUBST(DST_EXTRA_SRCS) # Determine the printf format characters to use when printing # values of type isc_int64_t. This will normally be "ll", but where # the compiler treats "long long" as a alias for "long" and printf # doesn't know about "long long" use "l". Hopefully the sprintf # will produce a inconsistent result in the later case. If the compiler # fails due to seeing "%lld" we fall back to "l". # # Digital Unix 4.0 (gcc?) (long long) is 64 bits as is its long. It uses # %ld even for (long long)/ # # Win32 uses "%I64d", but that's defined elsewhere since we don't use # configure on Win32. # AC_MSG_CHECKING(printf format modifier for 64-bit integers) AC_TRY_RUN([ #include main() { long long int j = 0; char buf[100]; buf[0] = 0; sprintf(buf, "%lld", j); exit((sizeof(long long int) != sizeof(long int))? 0 : (strcmp(buf, "0") != 0)); } ], [AC_MSG_RESULT(ll) ISC_PLATFORM_QUADFORMAT='#define ISC_PLATFORM_QUADFORMAT "ll"' LWRES_PLATFORM_QUADFORMAT='#define LWRES_PLATFORM_QUADFORMAT "ll"'], [AC_MSG_RESULT(l) ISC_PLATFORM_QUADFORMAT='#define ISC_PLATFORM_QUADFORMAT "l"' LWRES_PLATFORM_QUADFORMAT='#define LWRES_PLATFORM_QUADFORMAT "l"'], [AC_MSG_RESULT(assuming target platform uses ll) ISC_PLATFORM_QUADFORMAT='#define ISC_PLATFORM_QUADFORMAT "ll"' LWRES_PLATFORM_QUADFORMAT='#define LWRES_PLATFORM_QUADFORMAT "ll"']) AC_SUBST(ISC_PLATFORM_QUADFORMAT) AC_SUBST(LWRES_PLATFORM_QUADFORMAT) # # Security Stuff # # Note it is very recommended to *not* disable chroot(), # this is only because chroot() was made obsolete by Posix. AC_ARG_ENABLE(chroot, [ --disable-chroot disable chroot]) case "$enable_chroot" in yes|'') AC_CHECK_FUNCS(chroot) ;; no) ;; esac AC_ARG_ENABLE(linux-caps, [ --disable-linux-caps disable linux capabilities]) case "$enable_linux_caps" in yes|'') AC_CHECK_HEADERS(linux/types.h) AC_CHECK_HEADERS([sys/capability.h]) AC_CHECK_HEADERS([linux/capability.h], [], [], [#ifdef HAVE_LINUX_TYPES_H #include #endif ]) AC_CHECK_LIB(cap, cap_set_proc) ;; no) ;; esac AC_CHECK_HEADERS(sys/prctl.h) AC_CHECK_HEADERS(sys/un.h, ISC_PLATFORM_HAVESYSUNH="#define ISC_PLATFORM_HAVESYSUNH 1" , ISC_PLATFORM_HAVESYSUNH="#undef ISC_PLATFORM_HAVESYSUNH" ) AC_SUBST(ISC_PLATFORM_HAVESYSUNH) case "$host" in *-solaris*) AC_DEFINE(NEED_SECURE_DIRECTORY, 1, [Define if connect does not honour the permission on the UNIX domain socket.]) ;; *-sunos*) AC_DEFINE(NEED_SECURE_DIRECTORY, 1, [Define if connect does not honour the permission on the UNIX domain socket.]) ;; esac # # Time Zone Stuff # AC_CHECK_FUNC(tzset, AC_DEFINE(HAVE_TZSET)) AC_MSG_CHECKING(for optarg declaration) AC_TRY_COMPILE([ #include ], [optarg = 0;], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no) GEN_NEED_OPTARG="-DNEED_OPTARG=1" AC_DEFINE(NEED_OPTARG, 1, [Defined if extern char *optarg is not declared.])]) # # BSD/OS, and perhaps some others, don't define rlim_t. # AC_MSG_CHECKING(for type rlim_t) AC_TRY_COMPILE([ #include #include #include ], [rlim_t rl = 19671212; return (0);], [AC_MSG_RESULT(yes) ISC_PLATFORM_RLIMITTYPE="#define ISC_PLATFORM_RLIMITTYPE rlim_t"], [AC_MSG_RESULT(no) AC_MSG_CHECKING(type of rlim_cur) AC_TRY_RUN([ #include #include #include main() { struct rlimit r; exit(!(sizeof(r.rlim_cur) == sizeof(int)));}], [AC_MSG_RESULT(int) ISC_PLATFORM_RLIMITTYPE="#define ISC_PLATFORM_RLIMITTYPE int"], [ AC_TRY_RUN([ #include #include #include main() { struct rlimit r; exit(!(sizeof(r.rlim_cur) == sizeof(long int)));}], [AC_MSG_RESULT(long int) ISC_PLATFORM_RLIMITTYPE="#define ISC_PLATFORM_RLIMITTYPE long int"], [ AC_TRY_RUN([ #include #include #include main() { struct rlimit r; exit((!sizeof(r.rlim_cur) == sizeof(long long int)));}], [AC_MSG_RESULT(long long int) ISC_PLATFORM_RLIMITTYPE="#define ISC_PLATFORM_RLIMITTYPE long long int"], [AC_MSG_ERROR([unable to determine sizeof rlim_cur]) ],[AC_MSG_ERROR(this cannot happen)]) ],[AC_MSG_ERROR(this cannot happen)]) ],[ AC_ARG_WITH(rlimtype, , rlimtype="$withval", rlimtype="long long int") ISC_PLATFORM_RLIMITTYPE="#define ISC_PLATFORM_RLIMITTYPE $rlimtype" AC_MSG_RESULT(cannot determine type of rlim_cur when cross compiling - assuming $rlimtype)]) ]) AC_SUBST(ISC_PLATFORM_RLIMITTYPE) # # Older HP-UX doesn't have gettune # case "$host" in *-hp-hpux*) AC_CHECK_HEADERS(sys/dyntune.h) ;; *) ;; esac # # Compaq TruCluster requires more code for handling cluster IP aliases # case "$host" in *-dec-osf*) AC_CHECK_LIB(clua, clua_getaliasaddress, LIBS="-lclua $LIBS") AC_CHECK_FUNC(clua_getaliasaddress, AC_DEFINE(HAVE_TRUCLUSTER, 1, [Define if running under Compaq TruCluster])) ;; *) ;; esac # # Some hosts need msg_namelen to match the size of the socket structure. # Some hosts don't set msg_namelen appropriately on return from recvmsg(). # case $host in *os2*|*hp-mpeix*) AC_DEFINE(BROKEN_RECVMSG, 1, [Define if recvmsg() does not meet all of the BSD socket API specifications.]) ;; esac # # Microsoft has their own way of handling shared libraries that requires # additional qualifiers on extern variables. Unix systems don't need it. # AC_SUBST(ISC_PLATFORM_USEDECLSPEC) ISC_PLATFORM_USEDECLSPEC="#undef ISC_PLATFORM_USEDECLSPEC" AC_SUBST(LWRES_PLATFORM_USEDECLSPEC) LWRES_PLATFORM_USEDECLSPEC="#undef LWRES_PLATFORM_USEDECLSPEC" AC_SUBST(IRS_PLATFORM_USEDECLSPEC) IRS_PLATFORM_USEDECLSPEC="#undef IRS_PLATFORM_USEDECLSPEC" # # Random remaining OS-specific issues involving compiler warnings. # XXXDCL print messages to indicate some compensation is being done? # AC_SUBST(ISC_PLATFORM_BRACEPTHREADONCEINIT) ISC_PLATFORM_BRACEPTHREADONCEINIT="#undef ISC_PLATFORM_BRACEPTHREADONCEINIT" case "$host" in *-aix5.[[123]].*) hack_shutup_pthreadonceinit=yes ;; *-bsdi3.1*) hack_shutup_sputaux=yes ;; *-bsdi4.0*) hack_shutup_sigwait=yes hack_shutup_sputaux=yes ;; [*-bsdi4.[12]*]) hack_shutup_stdargcast=yes ;; [*-solaris2.[89]]) hack_shutup_pthreadonceinit=yes ;; *-solaris2.1[[0-9]]) AC_TRY_COMPILE([ #include ], [ static pthread_once_t once_test = { PTHREAD_ONCE_INIT }; ], [hack_shutup_pthreadonceinit=yes], ) ;; esac case "$hack_shutup_pthreadonceinit" in yes) # # Shut up PTHREAD_ONCE_INIT unbraced initializer warnings. # ISC_PLATFORM_BRACEPTHREADONCEINIT="#define ISC_PLATFORM_BRACEPTHREADONCEINIT 1" ;; esac case "$hack_shutup_sigwait" in yes) # # Shut up a -Wmissing-prototypes warning for sigwait(). # AC_DEFINE(SHUTUP_SIGWAIT) ;; esac case "$hack_shutup_sputaux" in yes) # # Shut up a -Wmissing-prototypes warning from . # AC_DEFINE(SHUTUP_SPUTAUX) ;; esac case "$hack_shutup_stdargcast" in yes) # # Shut up a -Wcast-qual warning from va_start(). # AC_DEFINE(SHUTUP_STDARG_CAST) ;; esac AC_CHECK_HEADERS(strings.h, ISC_PLATFORM_HAVESTRINGSH="#define ISC_PLATFORM_HAVESTRINGSH 1" , ISC_PLATFORM_HAVESTRINGSH="#undef ISC_PLATFORM_HAVESTRINGSH" ) AC_SUBST(ISC_PLATFORM_HAVESTRINGSH) # # Check for if_nametoindex() for IPv6 scoped addresses support # AC_CHECK_FUNC(if_nametoindex, ac_cv_have_if_nametoindex=yes, ac_cv_have_if_nametoindex=no) case $ac_cv_have_if_nametoindex in no) case "$host" in *-hp-hpux*) AC_CHECK_LIB(ipv6, if_nametoindex, ac_cv_have_if_nametoindex=yes LIBS="-lipv6 $LIBS",) ;; esac esac case $ac_cv_have_if_nametoindex in yes) ISC_PLATFORM_HAVEIFNAMETOINDEX="#define ISC_PLATFORM_HAVEIFNAMETOINDEX 1" AC_DEFINE(HAVE_IF_NAMETOINDEX, 1, [Define to 1 if you have the if_nametoindex function.]) ;; *) ISC_PLATFORM_HAVEIFNAMETOINDEX="#undef ISC_PLATFORM_HAVEIFNAMETOINDEX" ;; esac AC_SUBST(ISC_PLATFORM_HAVEIFNAMETOINDEX) AC_CHECK_FUNCS(nanosleep usleep) # # Machine architecture dependent features # AC_ARG_ENABLE(atomic, [ --enable-atomic enable machine specific atomic operations [[default=autodetect]]], enable_atomic="$enableval", enable_atomic="autodetect") case "$enable_atomic" in yes|''|autodetect) case "$host" in powerpc-ibm-aix*) if test "X$GCC" = "Xyes"; then AC_MSG_CHECKING([if asm("isc"); works]) AC_TRY_COMPILE(,[ main() { asm("ics"); exit(0); } ], [AC_MSG_RESULT(yes) use_atomic=yes], [ saved_cflags="$CFLAGS" CFLAGS="$CFLAGS -Wa,-many" AC_TRY_RUN([ main() { asm("ics"); exit(0); } ], [AC_MSG_RESULT([yes, required -Wa,-many]) use_atomic=yes], [AC_MSG_RESULT([no, use_atomic disabled]) CFLAGS="$saved_cflags" use_atomic=no], [AC_MSG_RESULT([cross compile, assume yes]) CFLAGS="$saved_cflags" use_atomic=yes]) ] ) else use_atomic=yes fi ;; *) use_atomic=yes ;; esac ;; no) use_atomic=no arch=noatomic ;; esac ISC_PLATFORM_USEOSFASM="#undef ISC_PLATFORM_USEOSFASM" ISC_PLATFORM_USEGCCASM="#undef ISC_PLATFORM_USEGCCASM" ISC_PLATFORM_USESTDASM="#undef ISC_PLATFORM_USESTDASM" ISC_PLATFORM_USEMACASM="#undef ISC_PLATFORM_USEMACASM" if test "$use_atomic" = "yes"; then AC_MSG_CHECKING([architecture type for atomic operations]) have_atomic=yes # set default case "$host" in [i[3456]86-*]) # XXX: some old x86 architectures actually do not support # (some of) these operations. Do we need stricter checks? AC_CHECK_SIZEOF([void *]) if test $ac_cv_sizeof_void_p = 8; then arch=x86_64 have_xaddq=yes else arch=x86_32 fi ;; x86_64-*|amd64-*) AC_CHECK_SIZEOF([void *]) if test $ac_cv_sizeof_void_p = 8; then arch=x86_64 have_xaddq=yes else arch=x86_32 fi ;; alpha*-*) arch=alpha ;; powerpc-*|powerpc64-*) arch=powerpc ;; mips-*|mipsel-*|mips64-*|mips64el-*) arch=mips ;; ia64-*) arch=ia64 ;; *) have_atomic=no arch=noatomic ;; esac AC_MSG_RESULT($arch) fi if test "$have_atomic" = "yes"; then AC_MSG_CHECKING([compiler support for inline assembly code]) compiler=generic # Check whether the compiler supports the assembly syntax we provide. if test "X$GCC" = "Xyes"; then # GCC's ASM extension always works compiler=gcc if test $arch = "x86_64"; then # We can share the same code for gcc with x86_32 arch=x86_32 fi if test $arch = "powerpc"; then # # The MacOS (and maybe others) uses "r0" for register # zero. Under linux/ibm it is "0" for register 0. # Probe to see if we have a MacOS style assembler. # AC_MSG_CHECKING([Checking for MacOS style assembler syntax]) AC_TRY_COMPILE(, [ __asm__ volatile ("li r0, 0x0\n"::); ], [ AC_MSG_RESULT(yes) compiler="mac" ISC_PLATFORM_USEMACASM="#define ISC_PLATFORM_USEMACASM 1" ], [AC_MSG_RESULT(no)]) fi else case "$host" in alpha*-dec-osf*) # Tru64 compiler has its own syntax for inline # assembly. AC_TRY_COMPILE(, [ #ifndef __DECC #error "unexpected compiler" #endif return (0);], [compiler=osf],) ;; powerpc-ibm-aix*) compiler=aix ;; esac fi case "$compiler" in gcc) ISC_PLATFORM_USEGCCASM="#define ISC_PLATFORM_USEGCCASM 1" ;; osf) ISC_PLATFORM_USEOSFASM="#define ISC_PLATFORM_USEOSFASM 1" ;; aix) ;; mac) ;; *) # See if the generic __asm function works. If not, # we need to disable the atomic operations. AC_TRY_LINK(, [ __asm("nop") ], [compiler="standard" ISC_PLATFORM_USESTDASM="#define ISC_PLATFORM_USESTDASM 1"], [compiler="not supported (atomic operations disabled)" have_atomic=no arch=noatomic ]); ;; esac AC_MSG_RESULT($compiler) fi if test "$have_atomic" = "yes"; then ISC_PLATFORM_HAVEXADD="#define ISC_PLATFORM_HAVEXADD 1" ISC_PLATFORM_HAVECMPXCHG="#define ISC_PLATFORM_HAVECMPXCHG 1" ISC_PLATFORM_HAVEATOMICSTORE="#define ISC_PLATFORM_HAVEATOMICSTORE 1" if test "$have_xaddq" = "yes"; then ISC_PLATFORM_HAVEXADDQ="#define ISC_PLATFORM_HAVEXADDQ 1" else ISC_PLATFORM_HAVEXADDQ="#undef ISC_PLATFORM_HAVEXADDQ" fi else ISC_PLATFORM_HAVEXADD="#undef ISC_PLATFORM_HAVEXADD" ISC_PLATFORM_HAVECMPXCHG="#undef ISC_PLATFORM_HAVECMPXCHG" ISC_PLATFORM_HAVEATOMICSTORE="#undef ISC_PLATFORM_HAVEATOMICSTORE" ISC_PLATFORM_HAVEXADDQ="#undef ISC_PLATFORM_HAVEXADDQ" fi AC_SUBST(ISC_PLATFORM_HAVEXADD) AC_SUBST(ISC_PLATFORM_HAVEXADDQ) AC_SUBST(ISC_PLATFORM_HAVECMPXCHG) AC_SUBST(ISC_PLATFORM_HAVEATOMICSTORE) AC_SUBST(ISC_PLATFORM_USEGCCASM) AC_SUBST(ISC_PLATFORM_USEOSFASM) AC_SUBST(ISC_PLATFORM_USESTDASM) AC_SUBST(ISC_PLATFORM_USEMACASM) ISC_ARCH_DIR=$arch AC_SUBST(ISC_ARCH_DIR) # # Activate "rrset-order fixed" or not? # AC_ARG_ENABLE(fixed-rrset, [ --enable-fixed-rrset enable fixed rrset ordering [[default=no]]], enable_fixed="$enableval", enable_fixed="no") case "$enable_fixed" in yes) AC_DEFINE(DNS_RDATASET_FIXED, 1, [Define to enable "rrset-order fixed" syntax.]) ;; no) ;; *) ;; esac # # Enable response policy rewriting using NS IP addresses # AC_ARG_ENABLE(rpz-nsip, [ --disable-rpz-nsip disable rpz-nsip rules [[default=enabled]]], enable_nsip="$enableval", enable_nsip="yes") case "$enable_nsip" in yes) AC_DEFINE(ENABLE_RPZ_NSIP, 1, [Define to enable rpz-nsip rules.]) ;; no) ;; *) ;; esac # # Enable response policy rewriting using NS name # AC_ARG_ENABLE(rpz-nsdname, [ --disable-rpz-nsdname disable rpz-nsdname rules [[default=enabled]]], enable_nsdname="$enableval", enable_nsdname="yes") case "$enable_nsdname" in yes) AC_DEFINE(ENABLE_RPZ_NSDNAME, 1, [Define to enable rpz-nsdname rules.]) ;; no) ;; *) ;; esac # # Activate recursive fetch limits # AC_ARG_ENABLE(fetchlimit, [ --enable-fetchlimit enable recursive fetch limits [[default=no]]], enable_fetchlimit="$enableval", enable_fetchlimit="no") case "$enable_fetchlimit" in yes) AC_DEFINE(ENABLE_FETCHLIMIT, 1, [Define to enable the "fetches-per-server" and "fetches-per-zone" options.]) ;; no) ;; *) ;; esac # # Activate "filter-aaaa" or not? # AC_ARG_ENABLE(filter-aaaa, [ --enable-filter-aaaa enable filtering of AAAA records [[default=no]]], enable_filter="$enableval", enable_filter="no") case "$enable_filter" in yes) AC_DEFINE(ALLOW_FILTER_AAAA, 1, [Define to enable the "filter-aaaa-on-v4" and "filter-aaaa-on-v6" options.]) ;; no) ;; *) ;; esac # # The following sets up how non-blocking i/o is established. # Sunos, cygwin and solaris 2.x (x<5) require special handling. # case "$host" in *-sunos*) AC_DEFINE(PORT_NONBLOCK, O_NDELAY);; *-cygwin*) AC_DEFINE(PORT_NONBLOCK, O_NDELAY);; *-solaris2.[[01234]]) AC_DEFINE(PORT_NONBLOCK, O_NONBLOCK) AC_DEFINE(USE_FIONBIO_IOCTL, 1, [Defined if you need to use ioctl(FIONBIO) instead a fcntl call to make non-blocking.]) ;; *) AC_DEFINE(PORT_NONBLOCK, O_NONBLOCK, [Sets which flag to pass to open/fcntl to make non-blocking (O_NDELAY/O_NONBLOCK).]) ;; esac # # Solaris 2.5.1 and earlier cannot bind() then connect() a TCP socket. # This prevents the source address being set. # case "$host" in *-solaris2.[[012345]]|*-solaris2.5.1) AC_DEFINE(BROKEN_TCP_BIND_BEFORE_CONNECT, 1, [Define if you cannot bind() before connect() for TCP sockets.]) ;; esac # # The following sections deal with tools used for formatting # the documentation. They are all optional, unless you are # a developer editing the documentation source. # # # Look for TeX. # AC_PATH_PROGS(LATEX, latex, latex) AC_SUBST(LATEX) AC_PATH_PROGS(PDFLATEX, pdflatex, pdflatex) AC_SUBST(PDFLATEX) # # Look for w3m # AC_PATH_PROGS(W3M, w3m, w3m) AC_SUBST(W3M) # # Look for xsltproc (libxslt) # AC_PATH_PROG(XSLTPROC, xsltproc, xsltproc) AC_SUBST(XSLTPROC) # # Look for xmllint (libxml2) # AC_PATH_PROG(XMLLINT, xmllint, xmllint) AC_SUBST(XMLLINT) # # Look for Doxygen # AC_PATH_PROG(DOXYGEN, doxygen, doxygen) AC_SUBST(DOXYGEN) # # Look for curl # AC_PATH_PROG(CURL, curl, curl) AC_SUBST(CURL) # # Subroutine for searching for an ordinary file (e.g., a stylesheet) # in a number of directories: # # NOM_PATH_FILE(VARIABLE, FILENAME, DIRECTORIES) # # If the file FILENAME is found in one of the DIRECTORIES, the shell # variable VARIABLE is defined to its absolute pathname. Otherwise, # it is set to FILENAME, with no directory prefix (that's not terribly # useful, but looks less confusing in substitutions than leaving it # empty). The variable VARIABLE will be substituted into output files. # AC_DEFUN(NOM_PATH_FILE, [ $1="" AC_MSG_CHECKING(for $2) for d in $3 do f=$d/$2 if test -f $f then $1=$f AC_MSG_RESULT($f) break fi done if test "X[$]$1" = "X" then AC_MSG_RESULT("not found"); $1=$2 fi AC_SUBST($1) ]) # # Look for Docbook-XSL stylesheets. Location probably varies by system. # If it's not explicitly specified, guess where it might be found, based on # where SGML stuff lives on some systems (FreeBSD is the only one we're sure # of at the moment). # AC_MSG_CHECKING(for Docbook-XSL path) AC_ARG_WITH(docbook-xsl, [ --with-docbook-xsl=PATH specify path for Docbook-XSL stylesheets], docbook_path="$withval", docbook_path="auto") case "$docbook_path" in auto) AC_MSG_RESULT(auto) docbook_xsl_trees="/usr/pkg/share/xsl/docbook /usr/local/share/xsl/docbook /usr/share/xsl/docbook /opt/local/share/xsl/docbook-xsl" ;; *) docbook_xsl_trees="$withval" AC_MSG_RESULT($docbook_xsl_trees) ;; esac # # Look for stylesheets we need. # NOM_PATH_FILE(XSLT_DOCBOOK_STYLE_HTML, html/docbook.xsl, $docbook_xsl_trees) NOM_PATH_FILE(XSLT_DOCBOOK_STYLE_XHTML, xhtml/docbook.xsl, $docbook_xsl_trees) NOM_PATH_FILE(XSLT_DOCBOOK_STYLE_MAN, manpages/docbook.xsl, $docbook_xsl_trees) NOM_PATH_FILE(XSLT_DOCBOOK_CHUNK_HTML, html/chunk.xsl, $docbook_xsl_trees) NOM_PATH_FILE(XSLT_DOCBOOK_CHUNK_XHTML, xhtml/chunk.xsl, $docbook_xsl_trees) NOM_PATH_FILE(XSLT_DOCBOOK_CHUNKTOC_HTML, html/chunktoc.xsl, $docbook_xsl_trees) NOM_PATH_FILE(XSLT_DOCBOOK_CHUNKTOC_XHTML, xhtml/chunktoc.xsl, $docbook_xsl_trees) NOM_PATH_FILE(XSLT_DOCBOOK_MAKETOC_HTML, html/maketoc.xsl, $docbook_xsl_trees) NOM_PATH_FILE(XSLT_DOCBOOK_MAKETOC_XHTML, xhtml/maketoc.xsl, $docbook_xsl_trees) # # Same dance for db2latex # db2latex_xsl_trees="/usr/local/share/db2latex/xsl /usr/pkg/share/xsl/db2latex" # # Look for stylesheets we need. # NOM_PATH_FILE(XSLT_DB2LATEX_STYLE, docbook.xsl, $db2latex_xsl_trees) # # Look for "admonition" image directory. Can't use NOM_PATH_FILE() # because it's a directory, so just do the same things, inline. # AC_MSG_CHECKING(for db2latex xsl figures) for d in $db2latex_xsl_trees do if test -d $d/figures then XSLT_DB2LATEX_ADMONITIONS=$d/figures AC_MSG_RESULT($d/figures) break fi done if test "X$XSLT_DB2LATEX_ADMONITIONS" = "X" then AC_MSG_RESULT(not found) XSLT_DB2LATEX_ADMONITIONS=db2latex/xsl/figures fi AC_SUBST(XSLT_DB2LATEX_ADMONITIONS) # # IDN support # AC_ARG_WITH(idn, [ --with-idn[=MPREFIX] enable IDN support using idnkit [default PREFIX]], use_idn="$withval", use_idn="no") case "$use_idn" in yes) if test X$prefix = XNONE ; then idn_path=/usr/local else idn_path=$prefix fi ;; no) ;; *) idn_path="$use_idn" ;; esac iconvinc= iconvlib= AC_ARG_WITH(libiconv, [ --with-libiconv[=IPREFIX] GNU libiconv are in IPREFIX [default PREFIX]], use_libiconv="$withval", use_libiconv="no") case "$use_libiconv" in yes) if test X$prefix = XNONE ; then iconvlib="-L/usr/local/lib -R/usr/local/lib -liconv" else iconvlib="-L$prefix/lib -R$prefix/lib -liconv" fi ;; no) iconvlib= ;; *) iconvlib="-L$use_libiconv/lib -R$use_libiconv/lib -liconv" ;; esac AC_ARG_WITH(iconv, [ --with-iconv[=LIBSPEC] specify iconv library [default -liconv]], iconvlib="$withval") case "$iconvlib" in no) iconvlib= ;; yes) iconvlib=-liconv ;; esac AC_ARG_WITH(idnlib, [ --with-idnlib=ARG specify libidnkit], idnlib="$withval", idnlib="no") if test "$idnlib" = yes; then AC_MSG_ERROR([You must specify ARG for --with-idnlib.]) fi IDNLIBS= if test "$use_idn" != no; then AC_DEFINE(WITH_IDN, 1, [define if idnkit support is to be included.]) STD_CINCLUDES="$STD_CINCLUDES -I$idn_path/include" if test "$idnlib" != no; then IDNLIBS="$idnlib $iconvlib" else IDNLIBS="-L$idn_path/lib -lidnkit $iconvlib" fi fi AC_SUBST(IDNLIBS) # # Check whether to build Automated Test Framework unit tests # AC_ARG_WITH(atf, [ --with-atf=ARG support Automated Test Framework], atf="$withval", atf="no") if test "$atf" = yes; then atf=`pwd`/unit/atf ATFBUILD=atf-src AC_SUBST(ATFBUILD) AC_CONFIG_COMMANDS([atf-config], [( mkdir -p unit/atf-src; cd unit/atf-src; case "$srcdir" in /*) ;; *) srcdir="../../$srcdir";; esac ${SHELL} "${srcdir}${srcdir:+/unit/atf-src/}./configure" --enable-tools --disable-shared MISSING=: --prefix $atfdir; ) ], [atfdir=`pwd`/unit/atf]) AC_MSG_RESULT(building ATF from bind9/unit/atf-src) fi ATFLIBS= if test "$atf" != no; then AC_DEFINE(ATF_TEST, 1, [define if ATF unit tests are to be built.]) STD_CINCLUDES="$STD_CINCLUDES -I$atf/include" ATFBIN="$atf/bin" ATFLIBS="-L$atf/lib -latf-c" UNITTESTS=tests fi AC_SUBST(ATFBIN) AC_SUBST(ATFLIBS) AC_SUBST(UNITTESTS) AC_CHECK_HEADERS(locale.h) AC_CHECK_FUNCS(setlocale) # # was --with-tuning specified? # AC_ARG_WITH(tuning, [ --with-tuning=ARG Specify server tuning (large or default)], use_tuning="$withval", use_tuning="no") case "$use_tuning" in large) if ! $use_threads; then AC_MSG_ERROR([Large-system tuning requires threads.]) fi AC_DEFINE(TUNE_LARGE, 1, [Define to use large-system tuning.]) AC_MSG_RESULT(using large-system tuning) ;; no|default) AC_MSG_RESULT(using default tuning) ;; yes|*) AC_MSG_ERROR([You must specify "large" or "default" for --with-tuning.]) ;; esac # # was --enable-querytrace specified? # AC_ARG_ENABLE(querytrace, [ --enable-querytrace enable very verbose query trace logging [[default=no]]], want_querytrace="$enableval", want_querytrace="no") case "$want_querytrace" in yes) AC_MSG_RESULT(yes) AC_DEFINE(WANT_QUERYTRACE, 1, [Define to enable very verbose query trace logging.]) ;; no) AC_MSG_RESULT(no) ;; *) AC_MSG_ERROR("--enable-querytrace requires yes or no") ;; esac # # Substitutions # AC_SUBST(BIND9_TOP_BUILDDIR) BIND9_TOP_BUILDDIR=`pwd` AC_SUBST(BIND9_ISC_BUILDINCLUDE) AC_SUBST(BIND9_ISCCC_BUILDINCLUDE) AC_SUBST(BIND9_ISCCFG_BUILDINCLUDE) AC_SUBST(BIND9_DNS_BUILDINCLUDE) AC_SUBST(BIND9_LWRES_BUILDINCLUDE) AC_SUBST(BIND9_BIND9_BUILDINCLUDE) AC_SUBST(BIND9_IRS_BUILDINCLUDE) if test "X$srcdir" != "X"; then BIND9_ISC_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/isc/include" BIND9_ISCCC_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/isccc/include" BIND9_ISCCFG_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/isccfg/include" BIND9_DNS_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/dns/include" BIND9_LWRES_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/lwres/include" BIND9_BIND9_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/bind9/include" BIND9_IRS_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/irs/include" else BIND9_ISC_BUILDINCLUDE="" BIND9_ISCCC_BUILDINCLUDE="" BIND9_ISCCFG_BUILDINCLUDE="" BIND9_DNS_BUILDINCLUDE="" BIND9_LWRES_BUILDINCLUDE="" BIND9_BIND9_BUILDINCLUDE="" BIND9_IRS_BUILDINCLUDE="" fi AC_SUBST_FILE(BIND9_MAKE_INCLUDES) BIND9_MAKE_INCLUDES=$BIND9_TOP_BUILDDIR/make/includes AC_SUBST_FILE(BIND9_MAKE_RULES) BIND9_MAKE_RULES=$BIND9_TOP_BUILDDIR/make/rules . "$srcdir/version" BIND9_PRODUCT="PRODUCT=\"${PRODUCT}\"" AC_SUBST(BIND9_PRODUCT) BIND9_DESCRIPTION="DESCRIPTION=\"${DESCRIPTION}\"" AC_SUBST(BIND9_DESCRIPTION) BIND9_VERSION="VERSION=${MAJORVER}.${MINORVER}${PATCHVER:+.}${PATCHVER}${RELEASETYPE}${RELEASEVER}${EXTENSIONS}" AC_SUBST(BIND9_VERSION) BIND9_MAJOR="MAJOR=${MAJORVER}.${MINORVER}" AC_SUBST(BIND9_MAJOR) BIND9_VERSIONSTRING="${PRODUCT} ${MAJORVER}.${MINORVER}${PATCHVER:+.}${PATCHVER}${RELEASETYPE}${RELEASEVER}${EXTENSIONS}${DESCRIPTION:+ }${DESCRIPTION}" AC_SUBST(BIND9_VERSIONSTRING) BIND9_SRCID="SRCID=unset" if test -f "${srcdir}/srcid"; then . "${srcdir}/srcid" BIND9_SRCID="SRCID=$SRCID" elif test -d "${srcdir}/.git"; then BIND9_SRCID="SRCID="`(cd "${srcdir}";git rev-parse --short HEAD)` fi AC_SUBST(BIND9_SRCID) if test -z "$ac_configure_args"; then BIND9_CONFIGARGS="defaults" else for a in $ac_configure_args do BIND9_CONFIGARGS="$BIND9_CONFIGARGS $a" done fi BIND9_CONFIGARGS="`echo $BIND9_CONFIGARGS | sed 's/^ //'`" BIND9_CONFIGARGS="CONFIGARGS=${BIND9_CONFIGARGS}" AC_SUBST(BIND9_CONFIGARGS) AC_SUBST_FILE(LIBISC_API) LIBISC_API="$srcdir/lib/isc/api" AC_SUBST_FILE(LIBISCCC_API) LIBISCCC_API="$srcdir/lib/isccc/api" AC_SUBST_FILE(LIBISCCFG_API) LIBISCCFG_API="$srcdir/lib/isccfg/api" AC_SUBST_FILE(LIBDNS_API) LIBDNS_API="$srcdir/lib/dns/api" AC_SUBST_FILE(LIBDNS_MAPAPI) LIBDNS_MAPAPI="$srcdir/lib/dns/mapapi" AC_SUBST_FILE(LIBBIND9_API) LIBBIND9_API="$srcdir/lib/bind9/api" AC_SUBST_FILE(LIBLWRES_API) LIBLWRES_API="$srcdir/lib/lwres/api" AC_SUBST_FILE(LIBIRS_API) LIBIRS_API="$srcdir/lib/irs/api" # # Configure any DLZ drivers. # # If config.dlz.in selects one or more DLZ drivers, it will set # CONTRIB_DLZ to a non-empty value, which will be our clue to # build DLZ drivers in contrib. # # This section has to come after the libtool stuff because it needs to # know how to name the driver object files. # CONTRIB_DLZ="" DLZ_DRIVER_INCLUDES="" DLZ_DRIVER_LIBS="" DLZ_DRIVER_SRCS="" DLZ_DRIVER_OBJS="" DLZ_SYSTEM_TEST="" # # Configure support for building a shared library object # # Even when libtool is available it can't always be relied upon # to build an object that can be dlopen()'ed, but this is necessary # for building the dlzexternal system test, so we'll try it the # old-fashioned way. # SO="so" SO_CFLAGS="" SO_LDFLAGS="" SO_LD="" SO_TARGETS="" AC_ARG_WITH(dlopen, [ --with-dlopen=ARG support dynamically loadable DLZ drivers], dlopen="$withval", dlopen="yes") case $host in *-sunos*) dlopen="no" ;; esac if test "$dlopen" = "yes"; then AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no) if test "$have_dl" = "yes"; then LIBS="-ldl $LIBS" fi AC_CHECK_FUNCS(dlopen dlclose dlsym,,dlopen=no) fi if test "$dlopen" = "yes"; then case $host in *-linux*|*-gnu*) SO_CFLAGS="-fPIC" SO_LDFLAGS="" if test "$have_dl" = "yes" then if test "$use_libtool" = "yes"; then SO_LDFLAGS="-Xcompiler -shared" SO_LD="${CC}" else SO_LDFLAGS="-shared" SO_LD="${CC}" fi else SO_LDFLAGS="-shared" SO_LD="ld" fi ;; *-freebsd*|*-openbsd*|*-netbsd*) SO_CFLAGS="-fpic" SO_LDFLAGS="-Bshareable -x" SO_LD="ld" ;; *-solaris*) SO_CFLAGS="-KPIC" SO_LDFLAGS="-G -z text" SO_LD="ld" ;; *-hp-hpux*) SO=sl SO_CFLAGS="+z" SO_LDFLAGS="-b +vnocompatwarnings" SO_LD="ld" ;; *) SO_CFLAGS="-fPIC" ;; esac if test "X$GCC" = "Xyes"; then SO_CFLAGS="-fPIC" if test -z "$SO_LD" then if test "$use_libtool" = "yes"; then SO_LDFLAGS="-Xcompiler -shared" SO_LD="${CC}" else SO_LDFLAGS="-shared" SO_LD="${CC}" fi fi fi # If we still don't know how to make shared objects, don't make any. if test -n "$SO_LD"; then SO_TARGETS="\${SO_TARGETS}" AC_DEFINE(ISC_DLZ_DLOPEN, 1, [Define to allow building of objects for dlopen().]) fi fi AC_SUBST(SO) AC_SUBST(SO_CFLAGS) AC_SUBST(SO_LDFLAGS) AC_SUBST(SO_LD) AC_SUBST(SO_TARGETS) sinclude(contrib/dlz/config.dlz.in) AC_MSG_CHECKING(contributed DLZ drivers) if test -n "$CONTRIB_DLZ" then AC_MSG_RESULT(yes) DLZ_DRIVER_RULES=contrib/dlz/drivers/rules AC_CONFIG_FILES([$DLZ_DRIVER_RULES]) else AC_MSG_RESULT(no) DLZ_DRIVER_RULES=/dev/null fi AC_SUBST(CONTRIB_DLZ) AC_SUBST(DLZ_DRIVER_INCLUDES) AC_SUBST(DLZ_DRIVER_LIBS) AC_SUBST(DLZ_DRIVER_SRCS) AC_SUBST(DLZ_DRIVER_OBJS) AC_SUBST(DLZ_SYSTEM_TEST) AC_SUBST_FILE(DLZ_DRIVER_RULES) if test "$cross_compiling" = "yes"; then if test -z "$BUILD_CC"; then AC_MSG_ERROR([BUILD_CC not set]) fi BUILD_CFLAGS="$BUILD_CFLAGS" BUILD_CPPFLAGS="$BUILD_CPPFLAGS" BUILD_LDFLAGS="$BUILD_LDFLAGS" BUILD_LIBS="$BUILD_LIBS" else BUILD_CC="$CC" BUILD_CFLAGS="$CFLAGS" BUILD_CPPFLAGS="$CPPFLAGS $GEN_NEED_OPTARG" BUILD_LDFLAGS="$LDFLAGS" BUILD_LIBS="$LIBS" fi NEWFLAGS="" for e in $BUILD_LDFLAGS ; do case $e in -L*) case $host_os in netbsd*) ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; freebsd*) ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; solaris*) ee=`echo $e | sed -e 's%^-L%-R%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; *) NEWFLAGS="$NEWFLAGS $e" ;; esac ;; *) NEWFLAGS="$NEWFLAGS $e" ;; esac done BUILD_LDFLAGS="$NEWFLAGS" NEWFLAGS="" for e in $DNS_GSSAPI_LIBS ; do case $e in -L*) case $host_os in netbsd*) ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; freebsd*) ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; solaris*) ee=`echo $e | sed -e 's%^-L%-R%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; *) NEWFLAGS="$NEWFLAGS $e" ;; esac ;; *) NEWFLAGS="$NEWFLAGS $e" ;; esac done DNS_GSSAPI_LIBS="$NEWFLAGS" NEWFLAGS="" for e in $ISC_OPENSSL_LIBS ; do case $e in -L*) case $host_os in netbsd*) ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; freebsd*) ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; solaris*) ee=`echo $e | sed -e 's%^-L%-R%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; *) NEWFLAGS="$NEWFLAGS $e" ;; esac ;; *) NEWFLAGS="$NEWFLAGS $e" ;; esac done ISC_OPENSSL_LIBS="$NEWFLAGS" NEWFLAGS="" for e in $DNS_CRYPTO_LIBS ; do case $e in -L*) case $host_os in netbsd*) ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; freebsd*) ee=`echo $e | sed -e 's%^-L%-Wl,-rpath,%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; solaris*) ee=`echo $e | sed -e 's%^-L%-R%'` NEWFLAGS="$NEWFLAGS $e $ee" ;; *) NEWFLAGS="$NEWFLAGS $e" ;; esac ;; *) NEWFLAGS="$NEWFLAGS $e" ;; esac done DNS_CRYPTO_LIBS="$NEWFLAGS" AC_SUBST(BUILD_CC) AC_SUBST(BUILD_CFLAGS) AC_SUBST(BUILD_CPPFLAGS) AC_SUBST(BUILD_LDFLAGS) AC_SUBST(BUILD_LIBS) # # Commands to run at the end of config.status. # Don't just put these into configure, it won't work right if somebody # runs config.status directly (which autoconf allows). # AC_CONFIG_COMMANDS( [chmod], [chmod a+x isc-config.sh doc/doxygen/doxygen-input-filter]) # # Files to configure. These are listed here because we used to # specify them as arguments to AC_OUTPUT. It's (now) ok to move these # elsewhere if there's a good reason for doing so. # AC_CONFIG_FILES([ make/Makefile make/mkdep Makefile bin/Makefile bin/check/Makefile bin/confgen/Makefile bin/confgen/unix/Makefile bin/delv/Makefile bin/dig/Makefile bin/dnssec/Makefile bin/named/Makefile bin/named/unix/Makefile bin/nsupdate/Makefile bin/pkcs11/Makefile bin/python/Makefile bin/python/dnssec-checkds.py bin/python/dnssec-coverage.py bin/rndc/Makefile bin/tests/Makefile bin/tests/atomic/Makefile bin/tests/db/Makefile bin/tests/dst/Makefile bin/tests/dst/Kdh.+002+18602.key bin/tests/dst/Kdh.+002+18602.private bin/tests/dst/Kdh.+002+48957.key bin/tests/dst/Kdh.+002+48957.private bin/tests/dst/Ktest.+001+00002.key bin/tests/dst/Ktest.+001+54622.key bin/tests/dst/Ktest.+001+54622.private bin/tests/dst/Ktest.+003+23616.key bin/tests/dst/Ktest.+003+23616.private bin/tests/dst/Ktest.+003+49667.key bin/tests/dst/dst_2_data bin/tests/dst/t2_data_1 bin/tests/dst/t2_data_2 bin/tests/dst/t2_dsasig bin/tests/dst/t2_rsasig bin/tests/hashes/Makefile bin/tests/headerdep_test.sh bin/tests/master/Makefile bin/tests/mem/Makefile bin/tests/names/Makefile bin/tests/net/Makefile bin/tests/pkcs11/Makefile bin/tests/pkcs11/benchmarks/Makefile bin/tests/rbt/Makefile bin/tests/resolver/Makefile bin/tests/sockaddr/Makefile bin/tests/system/Makefile bin/tests/system/conf.sh bin/tests/system/builtin/Makefile bin/tests/system/dlz/prereq.sh bin/tests/system/dlzexternal/Makefile bin/tests/system/dlzexternal/ns1/named.conf bin/tests/system/dlzredir/prereq.sh bin/tests/system/fetchlimit/Makefile bin/tests/system/filter-aaaa/Makefile bin/tests/system/geoip/Makefile bin/tests/system/inline/checkdsa.sh bin/tests/system/lwresd/Makefile bin/tests/system/rpz/Makefile bin/tests/system/rsabigexponent/Makefile bin/tests/system/sit/prereq.sh bin/tests/system/statistics/Makefile bin/tests/system/tkey/Makefile bin/tests/system/tsiggss/Makefile bin/tests/tasks/Makefile bin/tests/timers/Makefile bin/tests/virtual-time/Makefile bin/tests/virtual-time/conf.sh bin/tools/Makefile contrib/scripts/check-secure-delegation.pl contrib/scripts/zone-edit.sh doc/Makefile doc/arm/Makefile doc/doxygen/Doxyfile doc/doxygen/Makefile doc/doxygen/doxygen-input-filter doc/misc/Makefile doc/xsl/Makefile doc/xsl/isc-docbook-chunk.xsl doc/xsl/isc-docbook-html.xsl doc/xsl/isc-docbook-latex.xsl doc/xsl/isc-manpage.xsl doc/xsl/isc-notes-html.xsl doc/xsl/isc-notes-latex.xsl isc-config.sh lib/Makefile lib/bind9/Makefile lib/bind9/include/Makefile lib/bind9/include/bind9/Makefile lib/dns/Makefile lib/dns/include/Makefile lib/dns/include/dns/Makefile lib/dns/include/dst/Makefile lib/dns/tests/Makefile lib/irs/Makefile lib/irs/include/Makefile lib/irs/include/irs/Makefile lib/irs/include/irs/netdb.h lib/irs/include/irs/platform.h lib/isc/$arch/Makefile lib/isc/$arch/include/Makefile lib/isc/$arch/include/isc/Makefile lib/isc/$thread_dir/Makefile lib/isc/$thread_dir/include/Makefile lib/isc/$thread_dir/include/isc/Makefile lib/isc/Makefile lib/isc/include/Makefile lib/isc/include/isc/Makefile lib/isc/include/isc/platform.h lib/isc/include/pk11/Makefile lib/isc/include/pkcs11/Makefile lib/isc/tests/Makefile lib/isc/nls/Makefile lib/isc/unix/Makefile lib/isc/unix/include/Makefile lib/isc/unix/include/isc/Makefile lib/isc/unix/include/pkcs11/Makefile lib/isccc/Makefile lib/isccc/include/Makefile lib/isccc/include/isccc/Makefile lib/isccfg/Makefile lib/isccfg/include/Makefile lib/isccfg/include/isccfg/Makefile lib/lwres/Makefile lib/lwres/include/Makefile lib/lwres/include/lwres/Makefile lib/lwres/include/lwres/netdb.h lib/lwres/include/lwres/platform.h lib/lwres/man/Makefile lib/lwres/tests/Makefile lib/lwres/unix/Makefile lib/lwres/unix/include/Makefile lib/lwres/unix/include/lwres/Makefile lib/tests/Makefile lib/tests/include/Makefile lib/tests/include/tests/Makefile lib/samples/Makefile lib/samples/Makefile-postinstall unit/Makefile unit/unittest.sh ]) # # Do it # AC_OUTPUT # # Now that the Makefiles exist we can ensure that everything is rebuilt. # AC_ARG_WITH(make-clean, [ --with-make-clean run "make clean" at end of configure [[yes|no]]], make_clean="$withval", make_clean="yes") case "$make_clean" in yes) make clean ;; esac AC_ARG_ENABLE(full-report, [ --enable-full-report report values of all configure options]) echo "========================================================================" echo "Configuration summary:" echo "------------------------------------------------------------------------" echo "Optional features enabled:" if $use_threads; then echo " Multiprocessing support (--enable-threads)" if test "$enable_full_report" = "yes" -o "$locktype" = "standard"; then echo " Mutex lock type: $locktype" fi fi test "$use_tuning" = "large" && echo " Large-system tuning (--with-tuning)" test "$use_geoip" = "no" || echo " GeoIP access control (--with-geoip)" test "$use_gssapi" = "no" || echo " GSS-API (--with-gssapi)" test "$enable_fetchlimit" = "yes" && \ echo " Recursive fetch limits for DoS attack mitigation (--enable-fetchlimit)" if test "$enable_sit" != "no"; then echo " Source Identity Token support (--enable-sit)" if test "$enable_full_report" = "yes" -o "$with_sit_alg" != "aes"; then echo " Algorithm: $with_sit_alg" fi fi # these lines are only printed if run with --enable-full-report if test "$enable_full_report" = "yes"; then test "$enable_ipv6" = "no" -o "$found_ipv6" = "no" || \ echo " IPv6 support (--enable-ipv6)" test "X$CRYPTO" = "X" -o "$want_native_pkcs11" = "yes" || \ echo " OpenSSL cryptography/DNSSEC (--with-openssl)" test "X$PYTHON" = "X" || echo " Python tools (--with-python)" test "X$libxml2_libs" = "X" || echo " XML statistics (--with-libxml2)" test "X$have_libjson" = "X" || echo " JSON statistics (--with-libjson)" fi if test "$use_pkcs11" != "no"; then if test "$want_native_pkcs11" = "yes"; then echo " Native PKCS#11/Cryptoki support (--enable-native-pkcs11)" else echo " PKCS#11/Cryptoki support using OpenSSL (--with-pkcs11)" fi echo " Provider library: $PKCS11_PROVIDER" fi if test "$OPENSSL_GOST" = "yes" -o "$PKCS11_GOST" = "yes"; then echo " GOST algorithm support (encoding: $gosttype) (--with-gost)" fi test "$OPENSSL_ECDSA" = "yes" -o "$PKCS11_ECDSA" = "yes" && \ echo " ECDSA algorithm support (--with-ecdsa)" test "$enable_fixed" = "yes" && \ echo " Allow 'fixed' rrset-order (--enable-fixed-rrset)" test "$enable_filter" = "yes" && \ echo " AAAA filtering (--enable-filter-aaaa)" test "$enable_seccomp" = yes && \ echo " Use libseccomp system call filtering (--enable-seccomp)" test "$want_backtrace" = "yes" && \ echo " Print backtrace on crash (--enable-backtrace)" test "$want_symtable" = "minimal" && \ echo " Use symbol table for backtrace, named only (--enable-symtable)" test "$want_symtable" = "yes" -o "$want_symtable" = "all" && \ echo " Use symbol table for backtrace, all binaries (--enable-symtable=all)" test "$use_libtool" = "no" || echo " Use GNU libtool (--with-libtool)" test "$want_querytrace" = "yes" && \ echo " Very verbose query trace logging (--enable-querytrace)" test "$atf" = "no" || echo " Automated Testing Framework (--with-atf)" echo " Dynamically loadable zone (DLZ) drivers:" test "$use_dlz_bdb" = "no" || \ echo " Berkeley DB (--with-dlz-bdb)" test "$use_dlz_ldap" = "no" || \ echo " LDAP (--with-dlz-ldap)" test "$use_dlz_mysql" = "no" || \ echo " MySQL (--with-dlz-mysql)" test "$use_dlz_odbc" = "no" || \ echo " ODBC (--with-dlz-odbc)" test "$use_dlz_postgres" = "no" || \ echo " Postgres (--with-dlz-postgres)" test "$use_dlz_filesystem" = "no" || \ echo " Filesystem (--with-dlz-filesystem)" test "$use_dlz_stub" = "no" || \ echo " Stub (--with-dlz-stub)" test "$use_dlz_bdb $use_dlz_ldap $use_dlz_mysql $use_dlz_odbc $use_dlz_postgres $use_dlz_filesystem $use_dlz_stub" = "no no no no no no no" && echo " None" echo echo "Features disabled or unavailable on this platform:" $use_threads || echo " Multiprocessing support (--enable-threads)" test "$enable_ipv6" = "no" -o "$found_ipv6" = "no" && \ echo " IPv6 support (--enable-ipv6)" test "$use_tuning" = "large" || echo " Large-system tuning (--with-tuning)" test "$use_geoip" = "no" && echo " GeoIP access control (--with-geoip)" test "$use_gssapi" = "no" && echo " GSS-API (--with-gssapi)" test "$enable_fetchlimit" = "no" && \ echo " Recursive fetch limits for DoS attack mitigation (--enable-fetchlimit)" test "$enable_sit" = "no" && echo " Source Identity Token support (--enable-sit)" test "$enable_fixed" = "yes" || \ echo " Allow 'fixed' rrset-order (--enable-fixed-rrset)" if test "X$CRYPTO" = "X" -o "$want_native_pkcs11" = "yes" then echo " OpenSSL cryptography/DNSSEC (--with-openssl)" elif test "$use_pkcs11" = "no"; then echo " PKCS#11/Cryptoki support (--with-pkcs11)" fi test "$want_native_pkcs11" = "yes" || echo " Native PKCS#11/Cryptoki support (--enable-native-pkcs11)" test "X$CRYPTO" = "X" -o "$OPENSSL_GOST" = "yes" -o "$PKCS11_GOST" = "yes" || \ echo " GOST algorithm support (--with-gost)" test "X$CRYPTO" = "X" -o "$OPENSSL_ECDSA" = "yes" -o "$PKCS11_ECDSA" = "yes" || \ echo " ECDSA algorithm support (--with-ecdsa)" test "$enable_seccomp" = yes || \ echo " Use libseccomp system call filtering (--enable-seccomp)" test "$want_backtrace" = "yes" || \ echo " Print backtrace on crash (--enable-backtrace)" test "$want_querytrace" = "yes" || \ echo " Very verbose query trace logging (--enable-querytrace)" test "$use_libtool" = "yes" || echo " Use GNU libtool (--with-libtool)" test "$atf" = "no" && echo " Automated Testing Framework (--with-atf)" test "X$PYTHON" = "X" && echo " Python tools (--with-python)" test "X$libxml2_libs" = "X" && echo " XML statistics (--with-libxml2)" test "X$have_libjson" = "X" && echo " JSON statistics (--with-libjson)" if test "X$ac_unrecognized_opts" != "X"; then echo echo "Unrecognized options:" echo " $ac_unrecognized_opts" fi echo "========================================================================" if test "X$CRYPTO" = "X"; then cat << \EOF BIND 9 is being built without cryptography support. This means it will not have DNSSEC support. Use --with-openssl, or --with-pkcs11 and --enable-native-pkcs11 to enable cryptography. EOF fi if test "X$OPENSSL_WARNING" != "X"; then cat << \EOF WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING Your OpenSSL crypto library may be vulnerable to WARNING WARNING one or more of the the following known security WARNING WARNING flaws: WARNING WARNING WARNING WARNING CAN-2002-0659, CAN-2006-4339, CVE-2006-2937, WARNING WARNING CVE-2006-2940 and CVE-2015-3193. WARNING WARNING WARNING WARNING It is recommended that you upgrade to OpenSSL WARNING WARNING version 1.0.2e/1.0.1/1.0.0/0.9.9/0.9.8d/0.9.7l WARNING WARNING (or greater). WARNING WARNING WARNING WARNING You can disable this warning by specifying: WARNING WARNING WARNING WARNING --disable-openssl-version-check WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING EOF fi # Tell Emacs to edit this file in shell mode. # Local Variables: # mode: sh # End: bind9-9.10.3.dfsg.P4/aclocal.m40000644000470500017500000000131512664710322015231 0ustar lamontlamontsinclude(libtool.m4/libtool.m4)dnl sinclude(libtool.m4/ltoptions.m4)dnl sinclude(libtool.m4/ltsugar.m4)dnl sinclude(libtool.m4/ltversion.m4)dnl sinclude(libtool.m4/lt~obsolete.m4)dnl m4_divert_text(HELP_CANON, [[ NOTE: If PREFIX is not set, then the default values for --sysconfdir and --localstatedir are /etc and /var, respectively.]]) m4_divert_text(HELP_END, [[ Professional support for BIND is provided by Internet Systems Consortium, Inc. Information about paid support and training options is available at https://www.isc.org/support. Help can also often be found on the BIND Users mailing list (https://lists.isc.org/mailman/listinfo/bind-users) or in the #bind channel of the Freenode IRC service.]]) bind9-9.10.3.dfsg.P4/isc-config.sh.in0000644000470500017500000000642512664710322016362 0ustar lamontlamont#!/bin/sh # # Copyright (C) 2004, 2007, 2012, 2013, 2015 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000, 2001, 2003 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: isc-config.sh.in,v 1.17 2007/06/19 23:46:59 tbox Exp $ prefix=@prefix@ exec_prefix=@exec_prefix@ exec_prefix_set= includedir=@includedir@ libdir=@libdir@ usage() { cat << EOF Usage: isc-config [OPTIONS] [LIBRARIES] Options: [--prefix[=DIR]] [--exec-prefix[=DIR]] [--version] [--libs] [--cflags] Libraries: isc isccc isccfg dns lwres bind9 irs EOF exit $1 } if test $# -eq 0; then usage 1 1>&2 fi while test $# -gt 0; do case "$1" in -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) optarg= ;; esac case "$1" in --prefix=*) prefix=$optarg if test "x$exec_prefix_set" = x ; then exec_prefix=$prefix exec_prefix_set=true fi ;; --prefix) echo_prefix=true ;; --exec-prefix=*) exec_prefix=$optarg exec_prefix_set=true ;; --exec-prefix) echo_exec_prefix=true ;; --version) echo @BIND9_VERSION@ exit 0 ;; --cflags) echo_cflags=true ;; --libs) echo_libs=true; ;; irs) libirs=true; libdns=true; libisccfg=true; libisc=true; ;; isc) libisc=true; ;; isccc) libisccc=true; libisc=true; ;; isccfg) libisccfg=true; libisc=true; ;; dns) libdns=true; libisc=true; ;; lwres) liblwres=true; ;; bind9) libdns=true; libisc=true; libisccfg=true; libbind9=true; ;; *) usage 1 1>&2 esac shift done if test x"$echo_prefix" = x"true" ; then echo $prefix fi if test x"$echo_exec_prefix" = x"true" ; then echo $exec_prefix fi if test x"$echo_cflags" = x"true"; then if test x"${exec_prefix_set}" = x"true"; then includes="-I${exec_prefix}/include" else includes="-I${includedir}" fi if test x"$libisc" = x"true"; then includes="$includes @ALWAYS_DEFINES@ @STD_CINCLUDES@ @STD_CDEFINES@ @CCOPT@" fi echo $includes fi if test x"$echo_libs" = x"true"; then if test x"${exec_prefix_set}" = x"true"; then libs="-L${exec_prefix}/lib" else libs="-L${libdir}" fi if test x"$libirs" = x"true" ; then libs="$libs -lirs" fi if test x"$liblwres" = x"true" ; then libs="$libs -llwres" fi if test x"$libbind9" = x"true" ; then libs="$libs -lbind9" fi if test x"$libdns" = x"true" ; then libs="$libs -ldns @DNS_CRYPTO_LIBS@" fi if test x"$libisccfg" = x"true" ; then libs="$libs -lisccfg" fi if test x"$libisccc" = x"true" ; then libs="$libs -lisccc" fi if test x"$libisc" = x"true" ; then libs="$libs -lisc" needothers=true fi if test x"$needothers" = x"true" ; then libs="$libs @CCOPT@ @LIBS@" fi echo $libs fi bind9-9.10.3.dfsg.P4/bind.keys.h0000644000470500017500000001177412664710322015442 0ustar lamontlamont/* * Generated by bindkeys.pl 1.7 2011/01/04 23:47:13 tbox Exp * From bind.keys 1.7 2011/01/03 23:45:07 each Exp */ #define TRUSTED_KEYS "\ # The bind.keys file is used to override the built-in DNSSEC trust anchors\n\ # which are included as part of BIND 9. As of the current release, the only\n\ # trust anchors it contains are those for the DNS root zone (\".\"), and for\n\ # the ISC DNSSEC Lookaside Validation zone (\"dlv.isc.org\"). Trust anchors\n\ # for any other zones MUST be configured elsewhere; if they are configured\n\ # here, they will not be recognized or used by named.\n\ #\n\ # The built-in trust anchors are provided for convenience of configuration.\n\ # They are not activated within named.conf unless specifically switched on.\n\ # To use the built-in root key, set \"dnssec-validation auto;\" in\n\ # named.conf options. To use the built-in DLV key, set\n\ # \"dnssec-lookaside auto;\". Without these options being set,\n\ # the keys in this file are ignored.\n\ #\n\ # This file is NOT expected to be user-configured.\n\ #\n\ # These keys are current as of January 2011. If any key fails to\n\ # initialize correctly, it may have expired. In that event you should\n\ # replace this file with a current version. The latest version of\n\ # bind.keys can always be obtained from ISC at https://www.isc.org/bind-keys.\n\ \n\ trusted-keys {\n\ # ISC DLV: See https://www.isc.org/solutions/dlv for details.\n\ # NOTE: This key is activated by setting \"dnssec-lookaside auto;\"\n\ # in named.conf.\n\ dlv.isc.org. 257 3 5 \"BEAAAAPHMu/5onzrEE7z1egmhg/WPO0+juoZrW3euWEn4MxDCE1+lLy2\n\ brhQv5rN32RKtMzX6Mj70jdzeND4XknW58dnJNPCxn8+jAGl2FZLK8t+\n\ 1uq4W+nnA3qO2+DL+k6BD4mewMLbIYFwe0PG73Te9fZ2kJb56dhgMde5\n\ ymX4BI/oQ+cAK50/xvJv00Frf8kw6ucMTwFlgPe+jnGxPPEmHAte/URk\n\ Y62ZfkLoBAADLHQ9IrS2tryAe7mbBZVcOwIeU/Rw/mRx/vwwMCTgNboM\n\ QKtUdvNXDrYJDSHZws3xiRXF1Rf+al9UmZfSav/4NWLKjHzpT59k/VSt\n\ TDN0YUuWrBNh\";\n\ \n\ # ROOT KEY: See https://data.iana.org/root-anchors/root-anchors.xml\n\ # for current trust anchor information.\n\ # NOTE: This key is activated by setting \"dnssec-validation auto;\"\n\ # in named.conf.\n\ . 257 3 8 \"AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjF\n\ FVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoX\n\ bfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaD\n\ X6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpz\n\ W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relS\n\ Qageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulq\n\ QxA+Uk1ihz0=\";\n\ };\n\ " #define MANAGED_KEYS "\ # The bind.keys file is used to override the built-in DNSSEC trust anchors\n\ # which are included as part of BIND 9. As of the current release, the only\n\ # trust anchors it contains are those for the DNS root zone (\".\"), and for\n\ # the ISC DNSSEC Lookaside Validation zone (\"dlv.isc.org\"). Trust anchors\n\ # for any other zones MUST be configured elsewhere; if they are configured\n\ # here, they will not be recognized or used by named.\n\ #\n\ # The built-in trust anchors are provided for convenience of configuration.\n\ # They are not activated within named.conf unless specifically switched on.\n\ # To use the built-in root key, set \"dnssec-validation auto;\" in\n\ # named.conf options. To use the built-in DLV key, set\n\ # \"dnssec-lookaside auto;\". Without these options being set,\n\ # the keys in this file are ignored.\n\ #\n\ # This file is NOT expected to be user-configured.\n\ #\n\ # These keys are current as of January 2011. If any key fails to\n\ # initialize correctly, it may have expired. In that event you should\n\ # replace this file with a current version. The latest version of\n\ # bind.keys can always be obtained from ISC at https://www.isc.org/bind-keys.\n\ \n\ managed-keys {\n\ # ISC DLV: See https://www.isc.org/solutions/dlv for details.\n\ # NOTE: This key is activated by setting \"dnssec-lookaside auto;\"\n\ # in named.conf.\n\ dlv.isc.org. initial-key 257 3 5 \"BEAAAAPHMu/5onzrEE7z1egmhg/WPO0+juoZrW3euWEn4MxDCE1+lLy2\n\ brhQv5rN32RKtMzX6Mj70jdzeND4XknW58dnJNPCxn8+jAGl2FZLK8t+\n\ 1uq4W+nnA3qO2+DL+k6BD4mewMLbIYFwe0PG73Te9fZ2kJb56dhgMde5\n\ ymX4BI/oQ+cAK50/xvJv00Frf8kw6ucMTwFlgPe+jnGxPPEmHAte/URk\n\ Y62ZfkLoBAADLHQ9IrS2tryAe7mbBZVcOwIeU/Rw/mRx/vwwMCTgNboM\n\ QKtUdvNXDrYJDSHZws3xiRXF1Rf+al9UmZfSav/4NWLKjHzpT59k/VSt\n\ TDN0YUuWrBNh\";\n\ \n\ # ROOT KEY: See https://data.iana.org/root-anchors/root-anchors.xml\n\ # for current trust anchor information.\n\ # NOTE: This key is activated by setting \"dnssec-validation auto;\"\n\ # in named.conf.\n\ . initial-key 257 3 8 \"AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjF\n\ FVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoX\n\ bfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaD\n\ X6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpz\n\ W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relS\n\ Qageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulq\n\ QxA+Uk1ihz0=\";\n\ };\n\ " bind9-9.10.3.dfsg.P4/isc-config.sh.html0000644000470500017500000001044412664710322016714 0ustar lamontlamont isc-config.sh

Name

isc-config.sh — Get information about the installed version of ISC BIND

Synopsis

isc-config.sh [--cflags] [--exec-prefix] [--libs] [--prefix] [--version] [libraries...]

DESCRIPTION

isc-config.sh prints information related to the installed version of ISC BIND, such as the compiler and linker flags required to compile and link programs that use ISC BIND libraries.

The optional libraries are used to report specific details for compiling and linking for the listed libraries. The allowed choices are: isc, isccc, isccfg, dns, lwres, and bind9. Multiple libraries may be listed on the command line. (Some libraries require other libraries, so are implied.)

OPTIONS

--cflags

Prints the compiler command line options required to compile files that use ISC BIND. Use the libraries command line argument(s) to print additional specific flags to pass to the C compiler.

--exec-prefix

Prints the directory prefix used in the ISC BIND installation for architecture dependent files to standard output.

--libs

Prints the linker command line options used to link with the ISC BIND libraries. Use the libraries command line argument(s) to print additional specific flags.

--prefix

Prints the directory prefix used in the ISC BIND installation for architecture independent files to standard output.

--version

Prints the version of the installed ISC BIND suite.

RETURN VALUES

isc-config.sh returns an exit status of 1 if invoked with invalid arguments or no arguments at all. It returns 0 if information was successfully printed.

AUTHOR

Internet Systems Consortium

bind9-9.10.3.dfsg.P4/bin/0002755000470500017500000000000012672612753014153 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/nsupdate/0002755000470500017500000000000012672612753015776 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/nsupdate/nsupdate.html0000644000470500017500000006330612664710322020505 0ustar lamontlamont nsupdate

Name

nsupdate — Dynamic DNS update utility

Synopsis

nsupdate [-d] [-D] [-L level] [[-g] | [-o] | [-l] | [-y [hmac:]keyname:secret] | [-k keyfile]] [-t timeout] [-u udptimeout] [-r udpretries] [-R randomdev] [-v] [-T] [-P] [-V] [filename]

DESCRIPTION

nsupdate is used to submit Dynamic DNS Update requests as defined in RFC 2136 to a name server. This allows resource records to be added or removed from a zone without manually editing the zone file. A single update request can contain requests to add or remove more than one resource record.

Zones that are under dynamic control via nsupdate or a DHCP server should not be edited by hand. Manual edits could conflict with dynamic updates and cause data to be lost.

The resource records that are dynamically added or removed with nsupdate have to be in the same zone. Requests are sent to the zone's master server. This is identified by the MNAME field of the zone's SOA record.

Transaction signatures can be used to authenticate the Dynamic DNS updates. These use the TSIG resource record type described in RFC 2845 or the SIG(0) record described in RFC 2535 and RFC 2931 or GSS-TSIG as described in RFC 3645.

TSIG relies on a shared secret that should only be known to nsupdate and the name server. For instance, suitable key and server statements would be added to /etc/named.conf so that the name server can associate the appropriate secret key and algorithm with the IP address of the client application that will be using TSIG authentication. You can use ddns-confgen to generate suitable configuration fragments. nsupdate uses the -y or -k options to provide the TSIG shared secret. These options are mutually exclusive.

SIG(0) uses public key cryptography. To use a SIG(0) key, the public key must be stored in a KEY record in a zone served by the name server.

GSS-TSIG uses Kerberos credentials. Standard GSS-TSIG mode is switched on with the -g flag. A non-standards-compliant variant of GSS-TSIG used by Windows 2000 can be switched on with the -o flag.

OPTIONS

-d

Debug mode. This provides tracing information about the update requests that are made and the replies received from the name server.

-D

Extra debug mode.

-k keyfile

The file containing the TSIG authentication key. Keyfiles may be in two formats: a single file containing a named.conf-format key statement, which may be generated automatically by ddns-confgen, or a pair of files whose names are of the format K{name}.+157.+{random}.key and K{name}.+157.+{random}.private, which can be generated by dnssec-keygen. The -k may also be used to specify a SIG(0) key used to authenticate Dynamic DNS update requests. In this case, the key specified is not an HMAC-MD5 key.

-l

Local-host only mode. This sets the server address to localhost (disabling the server so that the server address cannot be overridden). Connections to the local server will use a TSIG key found in /var/run/named/session.key, which is automatically generated by named if any local master zone has set update-policy to local. The location of this key file can be overridden with the -k option.

-L level

Set the logging debug level. If zero, logging is disabled.

-p port

Set the port to use for connections to a name server. The default is 53.

-P

Print the list of private BIND-specific resource record types whose format is understood by nsupdate. See also the -T option.

-r udpretries

The number of UDP retries. The default is 3. If zero, only one update request will be made.

-R randomdev

Where to obtain randomness. If the operating system does not provide a /dev/random or equivalent device, the default source of randomness is keyboard input. randomdev specifies the name of a character device or file containing random data to be used instead of the default. The special value keyboard indicates that keyboard input should be used. This option may be specified multiple times.

-t timeout

The maximum time an update request can take before it is aborted. The default is 300 seconds. Zero can be used to disable the timeout.

-T

Print the list of IANA standard resource record types whose format is understood by nsupdate. nsupdate will exit after the lists are printed. The -T option can be combined with the -P option.

Other types can be entered using "TYPEXXXXX" where "XXXXX" is the decimal value of the type with no leading zeros. The rdata, if present, will be parsed using the UNKNOWN rdata format, (<backslash> <hash> <space> <length> <space> <hexstring>).

-u udptimeout

The UDP retry interval. The default is 3 seconds. If zero, the interval will be computed from the timeout interval and number of UDP retries.

-v

Use TCP even for small update requests. By default, nsupdate uses UDP to send update requests to the name server unless they are too large to fit in a UDP request in which case TCP will be used. TCP may be preferable when a batch of update requests is made.

-V

Print the version number and exit.

-y [hmac:]keyname:secret

Literal TSIG authentication key. keyname is the name of the key, and secret is the base64 encoded shared secret. hmac is the name of the key algorithm; valid choices are hmac-md5, hmac-sha1, hmac-sha224, hmac-sha256, hmac-sha384, or hmac-sha512. If hmac is not specified, the default is hmac-md5.

NOTE: Use of the -y option is discouraged because the shared secret is supplied as a command line argument in clear text. This may be visible in the output from ps(1) or in a history file maintained by the user's shell.

INPUT FORMAT

nsupdate reads input from filename or standard input. Each command is supplied on exactly one line of input. Some commands are for administrative purposes. The others are either update instructions or prerequisite checks on the contents of the zone. These checks set conditions that some name or set of resource records (RRset) either exists or is absent from the zone. These conditions must be met if the entire update request is to succeed. Updates will be rejected if the tests for the prerequisite conditions fail.

Every update request consists of zero or more prerequisites and zero or more updates. This allows a suitably authenticated update request to proceed if some specified resource records are present or missing from the zone. A blank input line (or the send command) causes the accumulated commands to be sent as one Dynamic DNS update request to the name server.

The command formats and their meaning are as follows:

server {servername} [port]

Sends all dynamic update requests to the name server servername. When no server statement is provided, nsupdate will send updates to the master server of the correct zone. The MNAME field of that zone's SOA record will identify the master server for that zone. port is the port number on servername where the dynamic update requests get sent. If no port number is specified, the default DNS port number of 53 is used.

local {address} [port]

Sends all dynamic update requests using the local address. When no local statement is provided, nsupdate will send updates using an address and port chosen by the system. port can additionally be used to make requests come from a specific port. If no port number is specified, the system will assign one.

zone {zonename}

Specifies that all updates are to be made to the zone zonename. If no zone statement is provided, nsupdate will attempt determine the correct zone to update based on the rest of the input.

class {classname}

Specify the default class. If no class is specified, the default class is IN.

ttl {seconds}

Specify the default time to live for records to be added. The value none will clear the default ttl.

key [hmac:] {keyname} {secret}

Specifies that all updates are to be TSIG-signed using the keyname secret pair. If hmac is specified, then it sets the signing algorithm in use; the default is hmac-md5. The key command overrides any key specified on the command line via -y or -k.

gsstsig

Use GSS-TSIG to sign the updated. This is equivalent to specifying -g on the commandline.

oldgsstsig

Use the Windows 2000 version of GSS-TSIG to sign the updated. This is equivalent to specifying -o on the commandline.

realm {[realm_name]}

When using GSS-TSIG use realm_name rather than the default realm in krb5.conf. If no realm is specified the saved realm is cleared.

[prereq] nxdomain {domain-name}

Requires that no resource record of any type exists with name domain-name.

[prereq] yxdomain {domain-name}

Requires that domain-name exists (has as at least one resource record, of any type).

[prereq] nxrrset {domain-name} [class] {type}

Requires that no resource record exists of the specified type, class and domain-name. If class is omitted, IN (internet) is assumed.

[prereq] yxrrset {domain-name} [class] {type}

This requires that a resource record of the specified type, class and domain-name must exist. If class is omitted, IN (internet) is assumed.

[prereq] yxrrset {domain-name} [class] {type} {data...}

The data from each set of prerequisites of this form sharing a common type, class, and domain-name are combined to form a set of RRs. This set of RRs must exactly match the set of RRs existing in the zone at the given type, class, and domain-name. The data are written in the standard text representation of the resource record's RDATA.

[update] del[ete] {domain-name} [ttl] [class] [type [data...]]

Deletes any resource records named domain-name. If type and data is provided, only matching resource records will be removed. The internet class is assumed if class is not supplied. The ttl is ignored, and is only allowed for compatibility.

[update] add {domain-name} {ttl} [class] {type} {data...}

Adds a new resource record with the specified ttl, class and data.

show

Displays the current message, containing all of the prerequisites and updates specified since the last send.

send

Sends the current message. This is equivalent to entering a blank line.

answer

Displays the answer.

debug

Turn on debugging.

version

Print version number.

help

Print a list of commands.

Lines beginning with a semicolon are comments and are ignored.

EXAMPLES

The examples below show how nsupdate could be used to insert and delete resource records from the example.com zone. Notice that the input in each example contains a trailing blank line so that a group of commands are sent as one dynamic update request to the master name server for example.com.

# nsupdate
> update delete oldhost.example.com A
> update add newhost.example.com 86400 A 172.16.1.1
> send

Any A records for oldhost.example.com are deleted. And an A record for newhost.example.com with IP address 172.16.1.1 is added. The newly-added record has a 1 day TTL (86400 seconds).

# nsupdate
> prereq nxdomain nickname.example.com
> update add nickname.example.com 86400 CNAME somehost.example.com
> send

The prerequisite condition gets the name server to check that there are no resource records of any type for nickname.example.com. If there are, the update request fails. If this name does not exist, a CNAME for it is added. This ensures that when the CNAME is added, it cannot conflict with the long-standing rule in RFC 1034 that a name must not exist as any other record type if it exists as a CNAME. (The rule has been updated for DNSSEC in RFC 2535 to allow CNAMEs to have RRSIG, DNSKEY and NSEC records.)

FILES

/etc/resolv.conf

used to identify default name server

/var/run/named/session.key

sets the default TSIG key for use in local-only mode

K{name}.+157.+{random}.key

base-64 encoding of HMAC-MD5 key created by dnssec-keygen(8).

K{name}.+157.+{random}.private

base-64 encoding of HMAC-MD5 key created by dnssec-keygen(8).

SEE ALSO

RFC 2136, RFC 3007, RFC 2104, RFC 2845, RFC 1034, RFC 2535, RFC 2931, named(8), ddns-confgen(8), dnssec-keygen(8).

BUGS

The TSIG key is redundantly stored in two separate files. This is a consequence of nsupdate using the DST library for its cryptographic operations, and may change in future releases.

bind9-9.10.3.dfsg.P4/bin/nsupdate/nsupdate.docbook0000644000470500017500000006513112664710322021157 0ustar lamontlamont]> April 18, 2014 nsupdate 1 BIND9 nsupdate Dynamic DNS update utility 2004 2005 2006 2007 2008 2009 2010 2011 2012 2014 2015 Internet Systems Consortium, Inc. ("ISC") 2000 2001 2002 2003 Internet Software Consortium. nsupdate filename DESCRIPTION nsupdate is used to submit Dynamic DNS Update requests as defined in RFC 2136 to a name server. This allows resource records to be added or removed from a zone without manually editing the zone file. A single update request can contain requests to add or remove more than one resource record. Zones that are under dynamic control via nsupdate or a DHCP server should not be edited by hand. Manual edits could conflict with dynamic updates and cause data to be lost. The resource records that are dynamically added or removed with nsupdate have to be in the same zone. Requests are sent to the zone's master server. This is identified by the MNAME field of the zone's SOA record. Transaction signatures can be used to authenticate the Dynamic DNS updates. These use the TSIG resource record type described in RFC 2845 or the SIG(0) record described in RFC 2535 and RFC 2931 or GSS-TSIG as described in RFC 3645. TSIG relies on a shared secret that should only be known to nsupdate and the name server. For instance, suitable key and server statements would be added to /etc/named.conf so that the name server can associate the appropriate secret key and algorithm with the IP address of the client application that will be using TSIG authentication. You can use ddns-confgen to generate suitable configuration fragments. nsupdate uses the or options to provide the TSIG shared secret. These options are mutually exclusive. SIG(0) uses public key cryptography. To use a SIG(0) key, the public key must be stored in a KEY record in a zone served by the name server. GSS-TSIG uses Kerberos credentials. Standard GSS-TSIG mode is switched on with the flag. A non-standards-compliant variant of GSS-TSIG used by Windows 2000 can be switched on with the flag. OPTIONS -d Debug mode. This provides tracing information about the update requests that are made and the replies received from the name server. -D Extra debug mode. -k keyfile The file containing the TSIG authentication key. Keyfiles may be in two formats: a single file containing a named.conf-format key statement, which may be generated automatically by ddns-confgen, or a pair of files whose names are of the format K{name}.+157.+{random}.key and K{name}.+157.+{random}.private, which can be generated by dnssec-keygen. The may also be used to specify a SIG(0) key used to authenticate Dynamic DNS update requests. In this case, the key specified is not an HMAC-MD5 key. -l Local-host only mode. This sets the server address to localhost (disabling the server so that the server address cannot be overridden). Connections to the local server will use a TSIG key found in /var/run/named/session.key, which is automatically generated by named if any local master zone has set update-policy to local. The location of this key file can be overridden with the option. -L level Set the logging debug level. If zero, logging is disabled. -p port Set the port to use for connections to a name server. The default is 53. -P Print the list of private BIND-specific resource record types whose format is understood by nsupdate. See also the option. -r udpretries The number of UDP retries. The default is 3. If zero, only one update request will be made. -R randomdev Where to obtain randomness. If the operating system does not provide a /dev/random or equivalent device, the default source of randomness is keyboard input. randomdev specifies the name of a character device or file containing random data to be used instead of the default. The special value keyboard indicates that keyboard input should be used. This option may be specified multiple times. -t timeout The maximum time an update request can take before it is aborted. The default is 300 seconds. Zero can be used to disable the timeout. -T Print the list of IANA standard resource record types whose format is understood by nsupdate. nsupdate will exit after the lists are printed. The option can be combined with the option. Other types can be entered using "TYPEXXXXX" where "XXXXX" is the decimal value of the type with no leading zeros. The rdata, if present, will be parsed using the UNKNOWN rdata format, (<backslash> <hash> <space> <length> <space> <hexstring>). -u udptimeout The UDP retry interval. The default is 3 seconds. If zero, the interval will be computed from the timeout interval and number of UDP retries. -v Use TCP even for small update requests. By default, nsupdate uses UDP to send update requests to the name server unless they are too large to fit in a UDP request in which case TCP will be used. TCP may be preferable when a batch of update requests is made. -V Print the version number and exit. -y hmac:keyname:secret Literal TSIG authentication key. keyname is the name of the key, and secret is the base64 encoded shared secret. hmac is the name of the key algorithm; valid choices are hmac-md5, hmac-sha1, hmac-sha224, hmac-sha256, hmac-sha384, or hmac-sha512. If hmac is not specified, the default is hmac-md5. NOTE: Use of the option is discouraged because the shared secret is supplied as a command line argument in clear text. This may be visible in the output from ps1 or in a history file maintained by the user's shell. INPUT FORMAT nsupdate reads input from filename or standard input. Each command is supplied on exactly one line of input. Some commands are for administrative purposes. The others are either update instructions or prerequisite checks on the contents of the zone. These checks set conditions that some name or set of resource records (RRset) either exists or is absent from the zone. These conditions must be met if the entire update request is to succeed. Updates will be rejected if the tests for the prerequisite conditions fail. Every update request consists of zero or more prerequisites and zero or more updates. This allows a suitably authenticated update request to proceed if some specified resource records are present or missing from the zone. A blank input line (or the send command) causes the accumulated commands to be sent as one Dynamic DNS update request to the name server. The command formats and their meaning are as follows: server servername port Sends all dynamic update requests to the name server servername. When no server statement is provided, nsupdate will send updates to the master server of the correct zone. The MNAME field of that zone's SOA record will identify the master server for that zone. port is the port number on servername where the dynamic update requests get sent. If no port number is specified, the default DNS port number of 53 is used. local address port Sends all dynamic update requests using the local address. When no local statement is provided, nsupdate will send updates using an address and port chosen by the system. port can additionally be used to make requests come from a specific port. If no port number is specified, the system will assign one. zone zonename Specifies that all updates are to be made to the zone zonename. If no zone statement is provided, nsupdate will attempt determine the correct zone to update based on the rest of the input. class classname Specify the default class. If no class is specified, the default class is IN. ttl seconds Specify the default time to live for records to be added. The value none will clear the default ttl. key hmac:keyname secret Specifies that all updates are to be TSIG-signed using the keyname secret pair. If hmac is specified, then it sets the signing algorithm in use; the default is hmac-md5. The key command overrides any key specified on the command line via or . gsstsig Use GSS-TSIG to sign the updated. This is equivalent to specifying on the commandline. oldgsstsig Use the Windows 2000 version of GSS-TSIG to sign the updated. This is equivalent to specifying on the commandline. realm realm_name When using GSS-TSIG use realm_name rather than the default realm in krb5.conf. If no realm is specified the saved realm is cleared. prereq nxdomain domain-name Requires that no resource record of any type exists with name domain-name. prereq yxdomain domain-name Requires that domain-name exists (has as at least one resource record, of any type). prereq nxrrset domain-name class type Requires that no resource record exists of the specified type, class and domain-name. If class is omitted, IN (internet) is assumed. prereq yxrrset domain-name class type This requires that a resource record of the specified type, class and domain-name must exist. If class is omitted, IN (internet) is assumed. prereq yxrrset domain-name class type data The data from each set of prerequisites of this form sharing a common type, class, and domain-name are combined to form a set of RRs. This set of RRs must exactly match the set of RRs existing in the zone at the given type, class, and domain-name. The data are written in the standard text representation of the resource record's RDATA. update delete domain-name ttl class type data Deletes any resource records named domain-name. If type and data is provided, only matching resource records will be removed. The internet class is assumed if class is not supplied. The ttl is ignored, and is only allowed for compatibility. update add domain-name ttl class type data Adds a new resource record with the specified ttl, class and data. show Displays the current message, containing all of the prerequisites and updates specified since the last send. send Sends the current message. This is equivalent to entering a blank line. answer Displays the answer. debug Turn on debugging. version Print version number. help Print a list of commands. Lines beginning with a semicolon are comments and are ignored. EXAMPLES The examples below show how nsupdate could be used to insert and delete resource records from the example.com zone. Notice that the input in each example contains a trailing blank line so that a group of commands are sent as one dynamic update request to the master name server for example.com. # nsupdate > update delete oldhost.example.com A > update add newhost.example.com 86400 A 172.16.1.1 > send Any A records for oldhost.example.com are deleted. And an A record for newhost.example.com with IP address 172.16.1.1 is added. The newly-added record has a 1 day TTL (86400 seconds). # nsupdate > prereq nxdomain nickname.example.com > update add nickname.example.com 86400 CNAME somehost.example.com > send The prerequisite condition gets the name server to check that there are no resource records of any type for nickname.example.com. If there are, the update request fails. If this name does not exist, a CNAME for it is added. This ensures that when the CNAME is added, it cannot conflict with the long-standing rule in RFC 1034 that a name must not exist as any other record type if it exists as a CNAME. (The rule has been updated for DNSSEC in RFC 2535 to allow CNAMEs to have RRSIG, DNSKEY and NSEC records.) FILES /etc/resolv.conf used to identify default name server /var/run/named/session.key sets the default TSIG key for use in local-only mode K{name}.+157.+{random}.key base-64 encoding of HMAC-MD5 key created by dnssec-keygen8 . K{name}.+157.+{random}.private base-64 encoding of HMAC-MD5 key created by dnssec-keygen8 . SEE ALSO RFC 2136, RFC 3007, RFC 2104, RFC 2845, RFC 1034, RFC 2535, RFC 2931, named8 , ddns-confgen8 , dnssec-keygen8 . BUGS The TSIG key is redundantly stored in two separate files. This is a consequence of nsupdate using the DST library for its cryptographic operations, and may change in future releases. bind9-9.10.3.dfsg.P4/bin/nsupdate/Makefile.in0000644000470500017500000000552212664710322020035 0ustar lamontlamont# Copyright (C) 2004, 2006-2009, 2012-2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000-2002 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.36 2009/12/05 23:31:40 each Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ @BIND9_MAKE_INCLUDES@ READLINE_LIB = @READLINE_LIB@ DST_GSSAPI_INC = @DST_GSSAPI_INC@ CINCLUDES = ${LWRES_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES} \ ${ISC_INCLUDES} ${ISCCFG_INCLUDES} ${DST_GSSAPI_INC} CDEFINES = -DVERSION=\"${VERSION}\" @USE_GSSAPI@ CWARNINGS = LWRESLIBS = ../../lib/lwres/liblwres.@A@ DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ BIND9LIBS = ../../lib/bind9/libbind9.@A@ ISCLIBS = ../../lib/isc/libisc.@A@ ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@ ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@ LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@ DNSDEPLIBS = ../../lib/dns/libdns.@A@ BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@ ISCDEPLIBS = ../../lib/isc/libisc.@A@ ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@ DEPLIBS = ${DNSDEPLIBS} ${BIND9DEPLIBS} ${ISCDEPLIBS} ${ISCCFGDEPLIBS} LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} ${ISCLIBS} @LIBS@ NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} ${ISCNOSYMLIBS} @LIBS@ SUBDIRS = TARGETS = nsupdate@EXEEXT@ OBJS = nsupdate.@O@ UOBJS = SRCS = nsupdate.c MANPAGES = nsupdate.1 HTMLPAGES = nsupdate.html MANOBJS = ${MANPAGES} ${HTMLPAGES} @BIND9_MAKE_RULES@ nsupdate.@O@: nsupdate.c ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ -DSESSION_KEYFILE=\"${localstatedir}/run/named/session.key\" \ -c ${srcdir}/nsupdate.c nsupdate@EXEEXT@: nsupdate.@O@ ${UOBJS} ${DEPLIBS} export BASEOBJS="nsupdate.@O@ ${READLINE_LIB} ${UOBJS}"; \ ${FINALBUILDCMD} doc man:: ${MANOBJS} docclean manclean maintainer-clean:: rm -f ${MANOBJS} clean distclean:: rm -f ${TARGETS} installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${bindir} $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man1 install:: nsupdate@EXEEXT@ installdirs ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} nsupdate@EXEEXT@ ${DESTDIR}${bindir} ${INSTALL_DATA} ${srcdir}/nsupdate.1 ${DESTDIR}${mandir}/man1 bind9-9.10.3.dfsg.P4/bin/nsupdate/nsupdate.c0000644000470500017500000024206212664710322017761 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef GSSAPI #include #ifdef WIN32 #include #else #include ISC_PLATFORM_KRB5HEADER #endif #endif #include #if defined(HAVE_READLINE) #include #include #endif #ifdef HAVE_ADDRINFO #ifdef HAVE_GETADDRINFO #ifdef HAVE_GAISTRERROR #define USE_GETADDRINFO #endif #endif #endif #ifndef USE_GETADDRINFO #ifndef ISC_PLATFORM_NONSTDHERRNO extern int h_errno; #endif #endif #define MAXCMD (128 * 1024) #define MAXWIRE (64 * 1024) #define PACKETSIZE ((64 * 1024) - 1) #define INITTEXT (2 * 1024) #define MAXTEXT (128 * 1024) #define FIND_TIMEOUT 5 #define TTL_MAX 2147483647U /* Maximum signed 32 bit integer. */ #define DNSDEFAULTPORT 53 /* Number of addresses to request from bind9_getaddresses() */ #define MAX_SERVERADDRS 4 static isc_uint16_t dnsport = DNSDEFAULTPORT; #ifndef RESOLV_CONF #define RESOLV_CONF "/etc/resolv.conf" #endif static isc_boolean_t debugging = ISC_FALSE, ddebugging = ISC_FALSE; static isc_boolean_t memdebugging = ISC_FALSE; static isc_boolean_t have_ipv4 = ISC_FALSE; static isc_boolean_t have_ipv6 = ISC_FALSE; static isc_boolean_t is_dst_up = ISC_FALSE; static isc_boolean_t usevc = ISC_FALSE; static isc_boolean_t usegsstsig = ISC_FALSE; static isc_boolean_t use_win2k_gsstsig = ISC_FALSE; static isc_boolean_t tried_other_gsstsig = ISC_FALSE; static isc_boolean_t local_only = ISC_FALSE; static isc_taskmgr_t *taskmgr = NULL; static isc_task_t *global_task = NULL; static isc_event_t *global_event = NULL; static isc_log_t *glctx = NULL; static isc_mem_t *gmctx = NULL; static dns_dispatchmgr_t *dispatchmgr = NULL; static dns_requestmgr_t *requestmgr = NULL; static isc_socketmgr_t *socketmgr = NULL; static isc_timermgr_t *timermgr = NULL; static dns_dispatch_t *dispatchv4 = NULL; static dns_dispatch_t *dispatchv6 = NULL; static dns_message_t *updatemsg = NULL; static dns_fixedname_t fuserzone; static dns_name_t *userzone = NULL; static dns_name_t *zname = NULL; static dns_name_t tmpzonename; static dns_name_t restart_master; static dns_tsig_keyring_t *gssring = NULL; static dns_tsigkey_t *tsigkey = NULL; static dst_key_t *sig0key = NULL; static lwres_context_t *lwctx = NULL; static lwres_conf_t *lwconf; static isc_sockaddr_t *servers = NULL; static isc_sockaddr_t *master_servers = NULL; static isc_boolean_t default_servers = ISC_TRUE; static int ns_inuse = 0; static int master_inuse = 0; static int ns_total = 0; static int master_total = 0; static isc_sockaddr_t *localaddr4 = NULL; static isc_sockaddr_t *localaddr6 = NULL; static const char *keyfile = NULL; static char *keystr = NULL; static isc_entropy_t *entropy = NULL; static isc_boolean_t shuttingdown = ISC_FALSE; static FILE *input; static isc_boolean_t interactive = ISC_TRUE; static isc_boolean_t seenerror = ISC_FALSE; static const dns_master_style_t *style; static int requests = 0; static unsigned int logdebuglevel = 0; static unsigned int timeout = 300; static unsigned int udp_timeout = 3; static unsigned int udp_retries = 3; static dns_rdataclass_t defaultclass = dns_rdataclass_in; static dns_rdataclass_t zoneclass = dns_rdataclass_none; static dns_message_t *answer = NULL; static isc_uint32_t default_ttl = 0; static isc_boolean_t default_ttl_set = ISC_FALSE; typedef struct nsu_requestinfo { dns_message_t *msg; isc_sockaddr_t *addr; } nsu_requestinfo_t; static void sendrequest(isc_sockaddr_t *destaddr, dns_message_t *msg, dns_request_t **request); static void send_update(dns_name_t *zonename, isc_sockaddr_t *master); ISC_PLATFORM_NORETURN_PRE static void fatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2) ISC_PLATFORM_NORETURN_POST; static void debug(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); static void ddebug(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); #ifdef GSSAPI static dns_fixedname_t fkname; static isc_sockaddr_t *kserver = NULL; static char *realm = NULL; static char servicename[DNS_NAME_FORMATSIZE]; static dns_name_t *keyname; typedef struct nsu_gssinfo { dns_message_t *msg; isc_sockaddr_t *addr; gss_ctx_id_t context; } nsu_gssinfo_t; static void start_gssrequest(dns_name_t *master); static void send_gssrequest(isc_sockaddr_t *destaddr, dns_message_t *msg, dns_request_t **request, gss_ctx_id_t context); static void recvgss(isc_task_t *task, isc_event_t *event); #endif /* GSSAPI */ static void error(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); #define STATUS_MORE (isc_uint16_t)0 #define STATUS_SEND (isc_uint16_t)1 #define STATUS_QUIT (isc_uint16_t)2 #define STATUS_SYNTAX (isc_uint16_t)3 typedef struct entropysource entropysource_t; struct entropysource { isc_entropysource_t *source; isc_mem_t *mctx; ISC_LINK(entropysource_t) link; }; static ISC_LIST(entropysource_t) sources; static void setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx) { isc_result_t result; isc_entropysource_t *source = NULL; entropysource_t *elt; int usekeyboard = ISC_ENTROPY_KEYBOARDMAYBE; REQUIRE(ectx != NULL); if (*ectx == NULL) { result = isc_entropy_create(mctx, ectx); if (result != ISC_R_SUCCESS) fatal("could not create entropy object"); ISC_LIST_INIT(sources); } if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) { usekeyboard = ISC_ENTROPY_KEYBOARDYES; randomfile = NULL; } result = isc_entropy_usebestsource(*ectx, &source, randomfile, usekeyboard); if (result != ISC_R_SUCCESS) fatal("could not initialize entropy source: %s", isc_result_totext(result)); if (source != NULL) { elt = isc_mem_get(mctx, sizeof(*elt)); if (elt == NULL) fatal("out of memory"); elt->source = source; elt->mctx = mctx; ISC_LINK_INIT(elt, link); ISC_LIST_APPEND(sources, elt, link); } } static void cleanup_entropy(isc_entropy_t **ectx) { entropysource_t *source; while (!ISC_LIST_EMPTY(sources)) { source = ISC_LIST_HEAD(sources); ISC_LIST_UNLINK(sources, source, link); isc_entropy_destroysource(&source->source); isc_mem_put(source->mctx, source, sizeof(*source)); } isc_entropy_detach(ectx); } static void master_from_servers(void) { if (master_servers != NULL && master_servers != servers) isc_mem_put(gmctx, master_servers, master_total * sizeof(isc_sockaddr_t)); master_servers = servers; master_total = ns_total; master_inuse = ns_inuse; } static dns_rdataclass_t getzoneclass(void) { if (zoneclass == dns_rdataclass_none) zoneclass = defaultclass; return (zoneclass); } static isc_boolean_t setzoneclass(dns_rdataclass_t rdclass) { if (zoneclass == dns_rdataclass_none || rdclass == dns_rdataclass_none) zoneclass = rdclass; if (zoneclass != rdclass) return (ISC_FALSE); return (ISC_TRUE); } static void fatal(const char *format, ...) { va_list args; va_start(args, format); vfprintf(stderr, format, args); va_end(args); fprintf(stderr, "\n"); exit(1); } static void error(const char *format, ...) { va_list args; va_start(args, format); vfprintf(stderr, format, args); va_end(args); fprintf(stderr, "\n"); } static void debug(const char *format, ...) { va_list args; if (debugging) { va_start(args, format); vfprintf(stderr, format, args); va_end(args); fprintf(stderr, "\n"); } } static void ddebug(const char *format, ...) { va_list args; if (ddebugging) { va_start(args, format); vfprintf(stderr, format, args); va_end(args); fprintf(stderr, "\n"); } } static inline void check_result(isc_result_t result, const char *msg) { if (result != ISC_R_SUCCESS) fatal("%s: %s", msg, isc_result_totext(result)); } static void * mem_alloc(void *arg, size_t size) { return (isc_mem_get(arg, size)); } static void mem_free(void *arg, void *mem, size_t size) { isc_mem_put(arg, mem, size); } static char * nsu_strsep(char **stringp, const char *delim) { char *string = *stringp; char *s; const char *d; char sc, dc; if (string == NULL) return (NULL); for (; *string != '\0'; string++) { sc = *string; for (d = delim; (dc = *d) != '\0'; d++) { if (sc == dc) break; } if (dc == 0) break; } for (s = string; *s != '\0'; s++) { sc = *s; for (d = delim; (dc = *d) != '\0'; d++) { if (sc == dc) { *s++ = '\0'; *stringp = s; return (string); } } } *stringp = NULL; return (string); } static void reset_system(void) { isc_result_t result; ddebug("reset_system()"); /* If the update message is still around, destroy it */ if (updatemsg != NULL) dns_message_reset(updatemsg, DNS_MESSAGE_INTENTRENDER); else { result = dns_message_create(gmctx, DNS_MESSAGE_INTENTRENDER, &updatemsg); check_result(result, "dns_message_create"); } updatemsg->opcode = dns_opcode_update; if (usegsstsig) { if (tsigkey != NULL) dns_tsigkey_detach(&tsigkey); if (gssring != NULL) dns_tsigkeyring_detach(&gssring); tried_other_gsstsig = ISC_FALSE; } } static isc_uint16_t parse_hmac(dns_name_t **hmac, const char *hmacstr, size_t len) { isc_uint16_t digestbits = 0; isc_result_t result; char buf[20]; REQUIRE(hmac != NULL && *hmac == NULL); REQUIRE(hmacstr != NULL); if (len >= sizeof(buf)) fatal("unknown key type '%.*s'", (int)(len), hmacstr); strncpy(buf, hmacstr, len); buf[len] = 0; if (strcasecmp(buf, "hmac-md5") == 0) { *hmac = DNS_TSIG_HMACMD5_NAME; } else if (strncasecmp(buf, "hmac-md5-", 9) == 0) { *hmac = DNS_TSIG_HMACMD5_NAME; result = isc_parse_uint16(&digestbits, &buf[9], 10); if (result != ISC_R_SUCCESS || digestbits > 128) fatal("digest-bits out of range [0..128]"); digestbits = (digestbits +7) & ~0x7U; } else if (strcasecmp(buf, "hmac-sha1") == 0) { *hmac = DNS_TSIG_HMACSHA1_NAME; } else if (strncasecmp(buf, "hmac-sha1-", 10) == 0) { *hmac = DNS_TSIG_HMACSHA1_NAME; result = isc_parse_uint16(&digestbits, &buf[10], 10); if (result != ISC_R_SUCCESS || digestbits > 160) fatal("digest-bits out of range [0..160]"); digestbits = (digestbits +7) & ~0x7U; } else if (strcasecmp(buf, "hmac-sha224") == 0) { *hmac = DNS_TSIG_HMACSHA224_NAME; } else if (strncasecmp(buf, "hmac-sha224-", 12) == 0) { *hmac = DNS_TSIG_HMACSHA224_NAME; result = isc_parse_uint16(&digestbits, &buf[12], 10); if (result != ISC_R_SUCCESS || digestbits > 224) fatal("digest-bits out of range [0..224]"); digestbits = (digestbits +7) & ~0x7U; } else if (strcasecmp(buf, "hmac-sha256") == 0) { *hmac = DNS_TSIG_HMACSHA256_NAME; } else if (strncasecmp(buf, "hmac-sha256-", 12) == 0) { *hmac = DNS_TSIG_HMACSHA256_NAME; result = isc_parse_uint16(&digestbits, &buf[12], 10); if (result != ISC_R_SUCCESS || digestbits > 256) fatal("digest-bits out of range [0..256]"); digestbits = (digestbits +7) & ~0x7U; } else if (strcasecmp(buf, "hmac-sha384") == 0) { *hmac = DNS_TSIG_HMACSHA384_NAME; } else if (strncasecmp(buf, "hmac-sha384-", 12) == 0) { *hmac = DNS_TSIG_HMACSHA384_NAME; result = isc_parse_uint16(&digestbits, &buf[12], 10); if (result != ISC_R_SUCCESS || digestbits > 384) fatal("digest-bits out of range [0..384]"); digestbits = (digestbits +7) & ~0x7U; } else if (strcasecmp(buf, "hmac-sha512") == 0) { *hmac = DNS_TSIG_HMACSHA512_NAME; } else if (strncasecmp(buf, "hmac-sha512-", 12) == 0) { *hmac = DNS_TSIG_HMACSHA512_NAME; result = isc_parse_uint16(&digestbits, &buf[12], 10); if (result != ISC_R_SUCCESS || digestbits > 512) fatal("digest-bits out of range [0..512]"); digestbits = (digestbits +7) & ~0x7U; } else fatal("unknown key type '%s'", buf); return (digestbits); } static int basenamelen(const char *file) { int len = strlen(file); if (len > 1 && file[len - 1] == '.') len -= 1; else if (len > 8 && strcmp(file + len - 8, ".private") == 0) len -= 8; else if (len > 4 && strcmp(file + len - 4, ".key") == 0) len -= 4; return (len); } static void setup_keystr(void) { unsigned char *secret = NULL; int secretlen; isc_buffer_t secretbuf; isc_result_t result; isc_buffer_t keynamesrc; char *secretstr; char *s, *n; dns_fixedname_t fkeyname; dns_name_t *mykeyname; char *name; dns_name_t *hmacname = NULL; isc_uint16_t digestbits = 0; dns_fixedname_init(&fkeyname); mykeyname = dns_fixedname_name(&fkeyname); debug("Creating key..."); s = strchr(keystr, ':'); if (s == NULL || s == keystr || s[1] == 0) fatal("key option must specify [hmac:]keyname:secret"); secretstr = s + 1; n = strchr(secretstr, ':'); if (n != NULL) { if (n == secretstr || n[1] == 0) fatal("key option must specify [hmac:]keyname:secret"); name = secretstr; secretstr = n + 1; digestbits = parse_hmac(&hmacname, keystr, s - keystr); } else { hmacname = DNS_TSIG_HMACMD5_NAME; name = keystr; n = s; } isc_buffer_init(&keynamesrc, name, (unsigned int)(n - name)); isc_buffer_add(&keynamesrc, (unsigned int)(n - name)); debug("namefromtext"); result = dns_name_fromtext(mykeyname, &keynamesrc, dns_rootname, 0, NULL); check_result(result, "dns_name_fromtext"); secretlen = strlen(secretstr) * 3 / 4; secret = isc_mem_allocate(gmctx, secretlen); if (secret == NULL) fatal("out of memory"); isc_buffer_init(&secretbuf, secret, secretlen); result = isc_base64_decodestring(secretstr, &secretbuf); if (result != ISC_R_SUCCESS) { fprintf(stderr, "could not create key from %s: %s\n", keystr, isc_result_totext(result)); goto failure; } secretlen = isc_buffer_usedlength(&secretbuf); debug("keycreate"); result = dns_tsigkey_create(mykeyname, hmacname, secret, secretlen, ISC_FALSE, NULL, 0, 0, gmctx, NULL, &tsigkey); if (result != ISC_R_SUCCESS) fprintf(stderr, "could not create key from %s: %s\n", keystr, dns_result_totext(result)); else dst_key_setbits(tsigkey->key, digestbits); failure: if (secret != NULL) isc_mem_free(gmctx, secret); } /* * Get a key from a named.conf format keyfile */ static isc_result_t read_sessionkey(isc_mem_t *mctx, isc_log_t *lctx) { cfg_parser_t *pctx = NULL; cfg_obj_t *sessionkey = NULL; const cfg_obj_t *key = NULL; const cfg_obj_t *secretobj = NULL; const cfg_obj_t *algorithmobj = NULL; const char *mykeyname; const char *secretstr; const char *algorithm; isc_result_t result; int len; if (! isc_file_exists(keyfile)) return (ISC_R_FILENOTFOUND); result = cfg_parser_create(mctx, lctx, &pctx); if (result != ISC_R_SUCCESS) goto cleanup; result = cfg_parse_file(pctx, keyfile, &cfg_type_sessionkey, &sessionkey); if (result != ISC_R_SUCCESS) goto cleanup; result = cfg_map_get(sessionkey, "key", &key); if (result != ISC_R_SUCCESS) goto cleanup; (void) cfg_map_get(key, "secret", &secretobj); (void) cfg_map_get(key, "algorithm", &algorithmobj); if (secretobj == NULL || algorithmobj == NULL) fatal("key must have algorithm and secret"); mykeyname = cfg_obj_asstring(cfg_map_getname(key)); secretstr = cfg_obj_asstring(secretobj); algorithm = cfg_obj_asstring(algorithmobj); len = strlen(algorithm) + strlen(mykeyname) + strlen(secretstr) + 3; keystr = isc_mem_allocate(mctx, len); snprintf(keystr, len, "%s:%s:%s", algorithm, mykeyname, secretstr); setup_keystr(); cleanup: if (pctx != NULL) { if (sessionkey != NULL) cfg_obj_destroy(pctx, &sessionkey); cfg_parser_destroy(&pctx); } if (keystr != NULL) isc_mem_free(mctx, keystr); return (result); } static void setup_keyfile(isc_mem_t *mctx, isc_log_t *lctx) { dst_key_t *dstkey = NULL; isc_result_t result; dns_name_t *hmacname = NULL; debug("Creating key..."); if (sig0key != NULL) dst_key_free(&sig0key); /* Try reading the key from a K* pair */ result = dst_key_fromnamedfile(keyfile, NULL, DST_TYPE_PRIVATE | DST_TYPE_KEY, mctx, &dstkey); /* If that didn't work, try reading it as a session.key keyfile */ if (result != ISC_R_SUCCESS) { result = read_sessionkey(mctx, lctx); if (result == ISC_R_SUCCESS) return; } if (result != ISC_R_SUCCESS) { fprintf(stderr, "could not read key from %.*s.{private,key}: " "%s\n", basenamelen(keyfile), keyfile, isc_result_totext(result)); return; } switch (dst_key_alg(dstkey)) { case DST_ALG_HMACMD5: hmacname = DNS_TSIG_HMACMD5_NAME; break; case DST_ALG_HMACSHA1: hmacname = DNS_TSIG_HMACSHA1_NAME; break; case DST_ALG_HMACSHA224: hmacname = DNS_TSIG_HMACSHA224_NAME; break; case DST_ALG_HMACSHA256: hmacname = DNS_TSIG_HMACSHA256_NAME; break; case DST_ALG_HMACSHA384: hmacname = DNS_TSIG_HMACSHA384_NAME; break; case DST_ALG_HMACSHA512: hmacname = DNS_TSIG_HMACSHA512_NAME; break; } if (hmacname != NULL) { result = dns_tsigkey_createfromkey(dst_key_name(dstkey), hmacname, dstkey, ISC_FALSE, NULL, 0, 0, mctx, NULL, &tsigkey); dst_key_free(&dstkey); if (result != ISC_R_SUCCESS) { fprintf(stderr, "could not create key from %s: %s\n", keyfile, isc_result_totext(result)); return; } } else { dst_key_attach(dstkey, &sig0key); dst_key_free(&dstkey); } } static void doshutdown(void) { isc_task_detach(&global_task); /* * The isc_mem_put of master_servers must be before the * isc_mem_put of servers as it sets the servers pointer * to NULL. */ if (master_servers != NULL && master_servers != servers) isc_mem_put(gmctx, master_servers, master_total * sizeof(isc_sockaddr_t)); if (servers != NULL) isc_mem_put(gmctx, servers, ns_total * sizeof(isc_sockaddr_t)); if (localaddr4 != NULL) isc_mem_put(gmctx, localaddr4, sizeof(isc_sockaddr_t)); if (localaddr6 != NULL) isc_mem_put(gmctx, localaddr6, sizeof(isc_sockaddr_t)); if (tsigkey != NULL) { ddebug("Freeing TSIG key"); dns_tsigkey_detach(&tsigkey); } if (sig0key != NULL) { ddebug("Freeing SIG(0) key"); dst_key_free(&sig0key); } if (updatemsg != NULL) dns_message_destroy(&updatemsg); if (is_dst_up) { ddebug("Destroy DST lib"); dst_lib_destroy(); is_dst_up = ISC_FALSE; } cleanup_entropy(&entropy); lwres_conf_clear(lwctx); lwres_context_destroy(&lwctx); ddebug("Destroying request manager"); dns_requestmgr_detach(&requestmgr); ddebug("Freeing the dispatchers"); if (have_ipv4) dns_dispatch_detach(&dispatchv4); if (have_ipv6) dns_dispatch_detach(&dispatchv6); ddebug("Shutting down dispatch manager"); dns_dispatchmgr_destroy(&dispatchmgr); } static void maybeshutdown(void) { ddebug("Shutting down request manager"); dns_requestmgr_shutdown(requestmgr); if (requests != 0) return; doshutdown(); } static void shutdown_program(isc_task_t *task, isc_event_t *event) { REQUIRE(task == global_task); UNUSED(task); ddebug("shutdown_program()"); isc_event_free(&event); shuttingdown = ISC_TRUE; maybeshutdown(); } static void setup_system(void) { isc_result_t result; isc_sockaddr_t bind_any, bind_any6; lwres_result_t lwresult; unsigned int attrs, attrmask; int i; isc_logconfig_t *logconfig = NULL; ddebug("setup_system()"); dns_result_register(); result = isc_net_probeipv4(); if (result == ISC_R_SUCCESS) have_ipv4 = ISC_TRUE; result = isc_net_probeipv6(); if (result == ISC_R_SUCCESS) have_ipv6 = ISC_TRUE; if (!have_ipv4 && !have_ipv6) fatal("could not find either IPv4 or IPv6"); result = isc_log_create(gmctx, &glctx, &logconfig); check_result(result, "isc_log_create"); isc_log_setcontext(glctx); dns_log_init(glctx); dns_log_setcontext(glctx); result = isc_log_usechannel(logconfig, "default_debug", NULL, NULL); check_result(result, "isc_log_usechannel"); isc_log_setdebuglevel(glctx, logdebuglevel); lwresult = lwres_context_create(&lwctx, gmctx, mem_alloc, mem_free, 1); if (lwresult != LWRES_R_SUCCESS) fatal("lwres_context_create failed"); (void)lwres_conf_parse(lwctx, RESOLV_CONF); lwconf = lwres_conf_get(lwctx); if (servers != NULL) { if (master_servers == servers) master_servers = NULL; isc_mem_put(gmctx, servers, ns_total * sizeof(isc_sockaddr_t)); } ns_inuse = 0; if (local_only || lwconf->nsnext <= 0) { struct in_addr in; struct in6_addr in6; if (local_only && keyfile == NULL) keyfile = SESSION_KEYFILE; default_servers = !local_only; ns_total = (have_ipv4 ? 1 : 0) + (have_ipv6 ? 1 : 0); servers = isc_mem_get(gmctx, ns_total * sizeof(isc_sockaddr_t)); if (servers == NULL) fatal("out of memory"); if (have_ipv4) { in.s_addr = htonl(INADDR_LOOPBACK); isc_sockaddr_fromin(&servers[0], &in, dnsport); } if (have_ipv6) { memset(&in6, 0, sizeof(in6)); in6.s6_addr[15] = 1; isc_sockaddr_fromin6(&servers[(have_ipv4 ? 1 : 0)], &in6, dnsport); } } else { ns_total = lwconf->nsnext; servers = isc_mem_get(gmctx, ns_total * sizeof(isc_sockaddr_t)); if (servers == NULL) fatal("out of memory"); for (i = 0; i < ns_total; i++) { if (lwconf->nameservers[i].family == LWRES_ADDRTYPE_V4) { struct in_addr in4; memmove(&in4, lwconf->nameservers[i].address, 4); isc_sockaddr_fromin(&servers[i], &in4, dnsport); } else { struct in6_addr in6; memmove(&in6, lwconf->nameservers[i].address, 16); isc_sockaddr_fromin6(&servers[i], &in6, dnsport); } } } setup_entropy(gmctx, NULL, &entropy); result = isc_hash_create(gmctx, entropy, DNS_NAME_MAXWIRE); check_result(result, "isc_hash_create"); isc_hash_init(); result = dns_dispatchmgr_create(gmctx, entropy, &dispatchmgr); check_result(result, "dns_dispatchmgr_create"); result = isc_socketmgr_create(gmctx, &socketmgr); check_result(result, "dns_socketmgr_create"); result = isc_timermgr_create(gmctx, &timermgr); check_result(result, "dns_timermgr_create"); result = isc_taskmgr_create(gmctx, 1, 0, &taskmgr); check_result(result, "isc_taskmgr_create"); result = isc_task_create(taskmgr, 0, &global_task); check_result(result, "isc_task_create"); result = isc_task_onshutdown(global_task, shutdown_program, NULL); check_result(result, "isc_task_onshutdown"); result = dst_lib_init(gmctx, entropy, 0); check_result(result, "dst_lib_init"); is_dst_up = ISC_TRUE; attrmask = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP; attrmask |= DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6; if (have_ipv6) { attrs = DNS_DISPATCHATTR_UDP; attrs |= DNS_DISPATCHATTR_MAKEQUERY; attrs |= DNS_DISPATCHATTR_IPV6; isc_sockaddr_any6(&bind_any6); result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, &bind_any6, PACKETSIZE, 4, 2, 3, 5, attrs, attrmask, &dispatchv6); check_result(result, "dns_dispatch_getudp (v6)"); } if (have_ipv4) { attrs = DNS_DISPATCHATTR_UDP; attrs |= DNS_DISPATCHATTR_MAKEQUERY; attrs |= DNS_DISPATCHATTR_IPV4; isc_sockaddr_any(&bind_any); result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, &bind_any, PACKETSIZE, 4, 2, 3, 5, attrs, attrmask, &dispatchv4); check_result(result, "dns_dispatch_getudp (v4)"); } result = dns_requestmgr_create(gmctx, timermgr, socketmgr, taskmgr, dispatchmgr, dispatchv4, dispatchv6, &requestmgr); check_result(result, "dns_requestmgr_create"); if (keystr != NULL) setup_keystr(); else if (local_only) { result = read_sessionkey(gmctx, glctx); if (result != ISC_R_SUCCESS) fatal("can't read key from %s: %s\n", keyfile, isc_result_totext(result)); } else if (keyfile != NULL) setup_keyfile(gmctx, glctx); } static void get_addresses(char *host, in_port_t port, isc_sockaddr_t *sockaddr, int naddrs) { int count; isc_result_t result; isc_app_block(); result = bind9_getaddresses(host, port, sockaddr, naddrs, &count); isc_app_unblock(); if (result != ISC_R_SUCCESS) fatal("couldn't get address for '%s': %s", host, isc_result_totext(result)); } static void version(void) { fputs("nsupdate " VERSION "\n", stderr); } #define PARSE_ARGS_FMT "dDML:y:ghlovk:p:Pr:R::t:Tu:V" static void pre_parse_args(int argc, char **argv) { dns_rdatatype_t t; int ch; char buf[100]; isc_boolean_t doexit = ISC_FALSE; while ((ch = isc_commandline_parse(argc, argv, PARSE_ARGS_FMT)) != -1) { switch (ch) { case 'M': /* was -dm */ debugging = ISC_TRUE; ddebugging = ISC_TRUE; memdebugging = ISC_TRUE; isc_mem_debugging = ISC_MEM_DEBUGTRACE | ISC_MEM_DEBUGRECORD; break; case '?': case 'h': if (isc_commandline_option != '?') fprintf(stderr, "%s: invalid argument -%c\n", argv[0], isc_commandline_option); fprintf(stderr, "usage: nsupdate [-dD] [-L level] [-l]" "[-g | -o | -y keyname:secret | -k keyfile] " "[-v] [-V] [-P] [-T] [filename]\n"); exit(1); case 'P': for (t = 0xff00; t <= 0xfffe; t++) { if (dns_rdatatype_ismeta(t)) continue; dns_rdatatype_format(t, buf, sizeof(buf)); if (strncmp(buf, "TYPE", 4) != 0) fprintf(stdout, "%s\n", buf); } doexit = ISC_TRUE; break; case 'T': for (t = 1; t <= 0xfeff; t++) { if (dns_rdatatype_ismeta(t)) continue; dns_rdatatype_format(t, buf, sizeof(buf)); if (strncmp(buf, "TYPE", 4) != 0) fprintf(stdout, "%s\n", buf); } doexit = ISC_TRUE; break; case 'V': version(); doexit = ISC_TRUE; break; default: break; } } if (doexit) exit(0); isc_commandline_reset = ISC_TRUE; isc_commandline_index = 1; } static void parse_args(int argc, char **argv, isc_mem_t *mctx, isc_entropy_t **ectx) { int ch; isc_uint32_t i; isc_result_t result; debug("parse_args"); while ((ch = isc_commandline_parse(argc, argv, PARSE_ARGS_FMT)) != -1) { switch (ch) { case 'd': debugging = ISC_TRUE; break; case 'D': /* was -dd */ debugging = ISC_TRUE; ddebugging = ISC_TRUE; break; case 'M': break; case 'l': local_only = ISC_TRUE; break; case 'L': result = isc_parse_uint32(&i, isc_commandline_argument, 10); if (result != ISC_R_SUCCESS) { fprintf(stderr, "bad library debug value " "'%s'\n", isc_commandline_argument); exit(1); } logdebuglevel = i; break; case 'y': keystr = isc_commandline_argument; break; case 'v': usevc = ISC_TRUE; break; case 'k': keyfile = isc_commandline_argument; break; case 'g': usegsstsig = ISC_TRUE; use_win2k_gsstsig = ISC_FALSE; break; case 'o': usegsstsig = ISC_TRUE; use_win2k_gsstsig = ISC_TRUE; break; case 'p': result = isc_parse_uint16(&dnsport, isc_commandline_argument, 10); if (result != ISC_R_SUCCESS) { fprintf(stderr, "bad port number " "'%s'\n", isc_commandline_argument); exit(1); } break; case 't': result = isc_parse_uint32(&timeout, isc_commandline_argument, 10); if (result != ISC_R_SUCCESS) { fprintf(stderr, "bad timeout '%s'\n", isc_commandline_argument); exit(1); } if (timeout == 0) timeout = UINT_MAX; break; case 'u': result = isc_parse_uint32(&udp_timeout, isc_commandline_argument, 10); if (result != ISC_R_SUCCESS) { fprintf(stderr, "bad udp timeout '%s'\n", isc_commandline_argument); exit(1); } if (udp_timeout == 0) udp_timeout = UINT_MAX; break; case 'r': result = isc_parse_uint32(&udp_retries, isc_commandline_argument, 10); if (result != ISC_R_SUCCESS) { fprintf(stderr, "bad udp retries '%s'\n", isc_commandline_argument); exit(1); } break; case 'R': setup_entropy(mctx, isc_commandline_argument, ectx); break; default: fprintf(stderr, "%s: unhandled option: %c\n", argv[0], isc_commandline_option); exit(1); } } if (keyfile != NULL && keystr != NULL) { fprintf(stderr, "%s: cannot specify both -k and -y\n", argv[0]); exit(1); } #ifdef GSSAPI if (usegsstsig && (keyfile != NULL || keystr != NULL)) { fprintf(stderr, "%s: cannot specify -g with -k or -y\n", argv[0]); exit(1); } #else if (usegsstsig) { fprintf(stderr, "%s: cannot specify -g or -o, " \ "program not linked with GSS API Library\n", argv[0]); exit(1); } #endif if (argv[isc_commandline_index] != NULL) { if (strcmp(argv[isc_commandline_index], "-") == 0) { input = stdin; } else { result = isc_stdio_open(argv[isc_commandline_index], "r", &input); if (result != ISC_R_SUCCESS) { fprintf(stderr, "could not open '%s': %s\n", argv[isc_commandline_index], isc_result_totext(result)); exit(1); } } interactive = ISC_FALSE; } } static isc_uint16_t parse_name(char **cmdlinep, dns_message_t *msg, dns_name_t **namep) { isc_result_t result; char *word; isc_buffer_t *namebuf = NULL; isc_buffer_t source; word = nsu_strsep(cmdlinep, " \t\r\n"); if (word == NULL || *word == 0) { fprintf(stderr, "could not read owner name\n"); return (STATUS_SYNTAX); } result = dns_message_gettempname(msg, namep); check_result(result, "dns_message_gettempname"); result = isc_buffer_allocate(gmctx, &namebuf, DNS_NAME_MAXWIRE); check_result(result, "isc_buffer_allocate"); dns_name_init(*namep, NULL); dns_name_setbuffer(*namep, namebuf); dns_message_takebuffer(msg, &namebuf); isc_buffer_init(&source, word, strlen(word)); isc_buffer_add(&source, strlen(word)); result = dns_name_fromtext(*namep, &source, dns_rootname, 0, NULL); check_result(result, "dns_name_fromtext"); isc_buffer_invalidate(&source); return (STATUS_MORE); } static isc_uint16_t parse_rdata(char **cmdlinep, dns_rdataclass_t rdataclass, dns_rdatatype_t rdatatype, dns_message_t *msg, dns_rdata_t *rdata) { char *cmdline = *cmdlinep; isc_buffer_t source, *buf = NULL, *newbuf = NULL; isc_region_t r; isc_lex_t *lex = NULL; dns_rdatacallbacks_t callbacks; isc_result_t result; if (cmdline == NULL) { rdata->flags = DNS_RDATA_UPDATE; return (STATUS_MORE); } while (*cmdline != 0 && isspace((unsigned char)*cmdline)) cmdline++; if (*cmdline != 0) { dns_rdatacallbacks_init(&callbacks); result = isc_lex_create(gmctx, strlen(cmdline), &lex); check_result(result, "isc_lex_create"); isc_buffer_init(&source, cmdline, strlen(cmdline)); isc_buffer_add(&source, strlen(cmdline)); result = isc_lex_openbuffer(lex, &source); check_result(result, "isc_lex_openbuffer"); result = isc_buffer_allocate(gmctx, &buf, MAXWIRE); check_result(result, "isc_buffer_allocate"); result = dns_rdata_fromtext(NULL, rdataclass, rdatatype, lex, dns_rootname, 0, gmctx, buf, &callbacks); isc_lex_destroy(&lex); if (result == ISC_R_SUCCESS) { isc_buffer_usedregion(buf, &r); result = isc_buffer_allocate(gmctx, &newbuf, r.length); check_result(result, "isc_buffer_allocate"); isc_buffer_putmem(newbuf, r.base, r.length); isc_buffer_usedregion(newbuf, &r); dns_rdata_fromregion(rdata, rdataclass, rdatatype, &r); isc_buffer_free(&buf); dns_message_takebuffer(msg, &newbuf); } else { fprintf(stderr, "invalid rdata format: %s\n", isc_result_totext(result)); isc_buffer_free(&buf); return (STATUS_SYNTAX); } } else { rdata->flags = DNS_RDATA_UPDATE; } *cmdlinep = cmdline; return (STATUS_MORE); } static isc_uint16_t make_prereq(char *cmdline, isc_boolean_t ispositive, isc_boolean_t isrrset) { isc_result_t result; char *word; dns_name_t *name = NULL; isc_textregion_t region; dns_rdataset_t *rdataset = NULL; dns_rdatalist_t *rdatalist = NULL; dns_rdataclass_t rdataclass; dns_rdatatype_t rdatatype; dns_rdata_t *rdata = NULL; isc_uint16_t retval; ddebug("make_prereq()"); /* * Read the owner name */ retval = parse_name(&cmdline, updatemsg, &name); if (retval != STATUS_MORE) return (retval); /* * If this is an rrset prereq, read the class or type. */ if (isrrset) { word = nsu_strsep(&cmdline, " \t\r\n"); if (word == NULL || *word == 0) { fprintf(stderr, "could not read class or type\n"); goto failure; } region.base = word; region.length = strlen(word); result = dns_rdataclass_fromtext(&rdataclass, ®ion); if (result == ISC_R_SUCCESS) { if (!setzoneclass(rdataclass)) { fprintf(stderr, "class mismatch: %s\n", word); goto failure; } /* * Now read the type. */ word = nsu_strsep(&cmdline, " \t\r\n"); if (word == NULL || *word == 0) { fprintf(stderr, "could not read type\n"); goto failure; } region.base = word; region.length = strlen(word); result = dns_rdatatype_fromtext(&rdatatype, ®ion); if (result != ISC_R_SUCCESS) { fprintf(stderr, "invalid type: %s\n", word); goto failure; } } else { rdataclass = getzoneclass(); result = dns_rdatatype_fromtext(&rdatatype, ®ion); if (result != ISC_R_SUCCESS) { fprintf(stderr, "invalid type: %s\n", word); goto failure; } } } else rdatatype = dns_rdatatype_any; result = dns_message_gettemprdata(updatemsg, &rdata); check_result(result, "dns_message_gettemprdata"); dns_rdata_init(rdata); if (isrrset && ispositive) { retval = parse_rdata(&cmdline, rdataclass, rdatatype, updatemsg, rdata); if (retval != STATUS_MORE) goto failure; } else rdata->flags = DNS_RDATA_UPDATE; result = dns_message_gettemprdatalist(updatemsg, &rdatalist); check_result(result, "dns_message_gettemprdatalist"); result = dns_message_gettemprdataset(updatemsg, &rdataset); check_result(result, "dns_message_gettemprdataset"); rdatalist->type = rdatatype; if (ispositive) { if (isrrset && rdata->data != NULL) rdatalist->rdclass = rdataclass; else rdatalist->rdclass = dns_rdataclass_any; } else rdatalist->rdclass = dns_rdataclass_none; rdata->rdclass = rdatalist->rdclass; rdata->type = rdatatype; ISC_LIST_APPEND(rdatalist->rdata, rdata, link); dns_rdatalist_tordataset(rdatalist, rdataset); ISC_LIST_INIT(name->list); ISC_LIST_APPEND(name->list, rdataset, link); dns_message_addname(updatemsg, name, DNS_SECTION_PREREQUISITE); return (STATUS_MORE); failure: if (name != NULL) dns_message_puttempname(updatemsg, &name); return (STATUS_SYNTAX); } static isc_uint16_t evaluate_prereq(char *cmdline) { char *word; isc_boolean_t ispositive, isrrset; ddebug("evaluate_prereq()"); word = nsu_strsep(&cmdline, " \t\r\n"); if (word == NULL || *word == 0) { fprintf(stderr, "could not read operation code\n"); return (STATUS_SYNTAX); } if (strcasecmp(word, "nxdomain") == 0) { ispositive = ISC_FALSE; isrrset = ISC_FALSE; } else if (strcasecmp(word, "yxdomain") == 0) { ispositive = ISC_TRUE; isrrset = ISC_FALSE; } else if (strcasecmp(word, "nxrrset") == 0) { ispositive = ISC_FALSE; isrrset = ISC_TRUE; } else if (strcasecmp(word, "yxrrset") == 0) { ispositive = ISC_TRUE; isrrset = ISC_TRUE; } else { fprintf(stderr, "incorrect operation code: %s\n", word); return (STATUS_SYNTAX); } return (make_prereq(cmdline, ispositive, isrrset)); } static isc_uint16_t evaluate_server(char *cmdline) { char *word, *server; long port; if (local_only) { fprintf(stderr, "cannot reset server in localhost-only mode\n"); return (STATUS_SYNTAX); } word = nsu_strsep(&cmdline, " \t\r\n"); if (word == NULL || *word == 0) { fprintf(stderr, "could not read server name\n"); return (STATUS_SYNTAX); } server = word; word = nsu_strsep(&cmdline, " \t\r\n"); if (word == NULL || *word == 0) port = dnsport; else { char *endp; port = strtol(word, &endp, 10); if (*endp != 0) { fprintf(stderr, "port '%s' is not numeric\n", word); return (STATUS_SYNTAX); } else if (port < 1 || port > 65535) { fprintf(stderr, "port '%s' is out of range " "(1 to 65535)\n", word); return (STATUS_SYNTAX); } } if (servers != NULL) { if (master_servers == servers) master_servers = NULL; isc_mem_put(gmctx, servers, ns_total * sizeof(isc_sockaddr_t)); } default_servers = ISC_FALSE; ns_total = MAX_SERVERADDRS; ns_inuse = 0; servers = isc_mem_get(gmctx, ns_total * sizeof(isc_sockaddr_t)); if (servers == NULL) fatal("out of memory"); memset(servers, 0, ns_total * sizeof(isc_sockaddr_t)); get_addresses(server, (in_port_t)port, servers, ns_total); return (STATUS_MORE); } static isc_uint16_t evaluate_local(char *cmdline) { char *word, *local; long port; struct in_addr in4; struct in6_addr in6; word = nsu_strsep(&cmdline, " \t\r\n"); if (word == NULL || *word == 0) { fprintf(stderr, "could not read server name\n"); return (STATUS_SYNTAX); } local = word; word = nsu_strsep(&cmdline, " \t\r\n"); if (word == NULL || *word == 0) port = 0; else { char *endp; port = strtol(word, &endp, 10); if (*endp != 0) { fprintf(stderr, "port '%s' is not numeric\n", word); return (STATUS_SYNTAX); } else if (port < 1 || port > 65535) { fprintf(stderr, "port '%s' is out of range " "(1 to 65535)\n", word); return (STATUS_SYNTAX); } } if (have_ipv6 && inet_pton(AF_INET6, local, &in6) == 1) { if (localaddr6 == NULL) localaddr6 = isc_mem_get(gmctx, sizeof(isc_sockaddr_t)); if (localaddr6 == NULL) fatal("out of memory"); isc_sockaddr_fromin6(localaddr6, &in6, (in_port_t)port); } else if (have_ipv4 && inet_pton(AF_INET, local, &in4) == 1) { if (localaddr4 == NULL) localaddr4 = isc_mem_get(gmctx, sizeof(isc_sockaddr_t)); if (localaddr4 == NULL) fatal("out of memory"); isc_sockaddr_fromin(localaddr4, &in4, (in_port_t)port); } else { fprintf(stderr, "invalid address %s", local); return (STATUS_SYNTAX); } return (STATUS_MORE); } static isc_uint16_t evaluate_key(char *cmdline) { char *namestr; char *secretstr; isc_buffer_t b; isc_result_t result; dns_fixedname_t fkeyname; dns_name_t *mykeyname; int secretlen; unsigned char *secret = NULL; isc_buffer_t secretbuf; dns_name_t *hmacname = NULL; isc_uint16_t digestbits = 0; char *n; namestr = nsu_strsep(&cmdline, " \t\r\n"); if (namestr == NULL || *namestr == 0) { fprintf(stderr, "could not read key name\n"); return (STATUS_SYNTAX); } dns_fixedname_init(&fkeyname); mykeyname = dns_fixedname_name(&fkeyname); n = strchr(namestr, ':'); if (n != NULL) { digestbits = parse_hmac(&hmacname, namestr, n - namestr); namestr = n + 1; } else hmacname = DNS_TSIG_HMACMD5_NAME; isc_buffer_init(&b, namestr, strlen(namestr)); isc_buffer_add(&b, strlen(namestr)); result = dns_name_fromtext(mykeyname, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) { fprintf(stderr, "could not parse key name\n"); return (STATUS_SYNTAX); } secretstr = nsu_strsep(&cmdline, "\r\n"); if (secretstr == NULL || *secretstr == 0) { fprintf(stderr, "could not read key secret\n"); return (STATUS_SYNTAX); } secretlen = strlen(secretstr) * 3 / 4; secret = isc_mem_allocate(gmctx, secretlen); if (secret == NULL) fatal("out of memory"); isc_buffer_init(&secretbuf, secret, secretlen); result = isc_base64_decodestring(secretstr, &secretbuf); if (result != ISC_R_SUCCESS) { fprintf(stderr, "could not create key from %s: %s\n", secretstr, isc_result_totext(result)); isc_mem_free(gmctx, secret); return (STATUS_SYNTAX); } secretlen = isc_buffer_usedlength(&secretbuf); if (tsigkey != NULL) dns_tsigkey_detach(&tsigkey); result = dns_tsigkey_create(mykeyname, hmacname, secret, secretlen, ISC_FALSE, NULL, 0, 0, gmctx, NULL, &tsigkey); isc_mem_free(gmctx, secret); if (result != ISC_R_SUCCESS) { fprintf(stderr, "could not create key from %s %s: %s\n", namestr, secretstr, dns_result_totext(result)); return (STATUS_SYNTAX); } dst_key_setbits(tsigkey->key, digestbits); return (STATUS_MORE); } static isc_uint16_t evaluate_zone(char *cmdline) { char *word; isc_buffer_t b; isc_result_t result; word = nsu_strsep(&cmdline, " \t\r\n"); if (word == NULL || *word == 0) { fprintf(stderr, "could not read zone name\n"); return (STATUS_SYNTAX); } dns_fixedname_init(&fuserzone); userzone = dns_fixedname_name(&fuserzone); isc_buffer_init(&b, word, strlen(word)); isc_buffer_add(&b, strlen(word)); result = dns_name_fromtext(userzone, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) { userzone = NULL; /* Lest it point to an invalid name */ fprintf(stderr, "could not parse zone name\n"); return (STATUS_SYNTAX); } return (STATUS_MORE); } static isc_uint16_t evaluate_realm(char *cmdline) { #ifdef GSSAPI char *word; char buf[1024]; int n; if (realm != NULL) { isc_mem_free(gmctx, realm); realm = NULL; } word = nsu_strsep(&cmdline, " \t\r\n"); if (word == NULL || *word == 0) return (STATUS_MORE); n = snprintf(buf, sizeof(buf), "@%s", word); if (n < 0 || (size_t)n >= sizeof(buf)) fatal("realm is too long"); realm = isc_mem_strdup(gmctx, buf); if (realm == NULL) fatal("out of memory"); return (STATUS_MORE); #else UNUSED(cmdline); return (STATUS_SYNTAX); #endif } static isc_uint16_t evaluate_ttl(char *cmdline) { char *word; isc_result_t result; isc_uint32_t ttl; word = nsu_strsep(&cmdline, " \t\r\n"); if (word == NULL || *word == 0) { fprintf(stderr, "could not ttl\n"); return (STATUS_SYNTAX); } if (!strcasecmp(word, "none")) { default_ttl = 0; default_ttl_set = ISC_FALSE; return (STATUS_MORE); } result = isc_parse_uint32(&ttl, word, 10); if (result != ISC_R_SUCCESS) return (STATUS_SYNTAX); if (ttl > TTL_MAX) { fprintf(stderr, "ttl '%s' is out of range (0 to %u)\n", word, TTL_MAX); return (STATUS_SYNTAX); } default_ttl = ttl; default_ttl_set = ISC_TRUE; return (STATUS_MORE); } static isc_uint16_t evaluate_class(char *cmdline) { char *word; isc_textregion_t r; isc_result_t result; dns_rdataclass_t rdclass; word = nsu_strsep(&cmdline, " \t\r\n"); if (word == NULL || *word == 0) { fprintf(stderr, "could not read class name\n"); return (STATUS_SYNTAX); } r.base = word; r.length = strlen(word); result = dns_rdataclass_fromtext(&rdclass, &r); if (result != ISC_R_SUCCESS) { fprintf(stderr, "could not parse class name: %s\n", word); return (STATUS_SYNTAX); } switch (rdclass) { case dns_rdataclass_none: case dns_rdataclass_any: case dns_rdataclass_reserved0: fprintf(stderr, "bad default class: %s\n", word); return (STATUS_SYNTAX); default: defaultclass = rdclass; } return (STATUS_MORE); } static isc_uint16_t update_addordelete(char *cmdline, isc_boolean_t isdelete) { isc_result_t result; dns_name_t *name = NULL; isc_uint32_t ttl; char *word; dns_rdataclass_t rdataclass; dns_rdatatype_t rdatatype; dns_rdata_t *rdata = NULL; dns_rdatalist_t *rdatalist = NULL; dns_rdataset_t *rdataset = NULL; isc_textregion_t region; isc_uint16_t retval; ddebug("update_addordelete()"); /* * Read the owner name. */ retval = parse_name(&cmdline, updatemsg, &name); if (retval != STATUS_MORE) return (retval); result = dns_message_gettemprdata(updatemsg, &rdata); check_result(result, "dns_message_gettemprdata"); dns_rdata_init(rdata); /* * If this is an add, read the TTL and verify that it's in range. * If it's a delete, ignore a TTL if present (for compatibility). */ word = nsu_strsep(&cmdline, " \t\r\n"); if (word == NULL || *word == 0) { if (!isdelete) { fprintf(stderr, "could not read owner ttl\n"); goto failure; } else { ttl = 0; rdataclass = dns_rdataclass_any; rdatatype = dns_rdatatype_any; rdata->flags = DNS_RDATA_UPDATE; goto doneparsing; } } result = isc_parse_uint32(&ttl, word, 10); if (result != ISC_R_SUCCESS) { if (isdelete) { ttl = 0; goto parseclass; } else if (default_ttl_set) { ttl = default_ttl; goto parseclass; } else { fprintf(stderr, "ttl '%s': %s\n", word, isc_result_totext(result)); goto failure; } } if (isdelete) ttl = 0; else if (ttl > TTL_MAX) { fprintf(stderr, "ttl '%s' is out of range (0 to %u)\n", word, TTL_MAX); goto failure; } /* * Read the class or type. */ word = nsu_strsep(&cmdline, " \t\r\n"); parseclass: if (word == NULL || *word == 0) { if (isdelete) { rdataclass = dns_rdataclass_any; rdatatype = dns_rdatatype_any; rdata->flags = DNS_RDATA_UPDATE; goto doneparsing; } else { fprintf(stderr, "could not read class or type\n"); goto failure; } } region.base = word; region.length = strlen(word); rdataclass = dns_rdataclass_any; result = dns_rdataclass_fromtext(&rdataclass, ®ion); if (result == ISC_R_SUCCESS && rdataclass != dns_rdataclass_any) { if (!setzoneclass(rdataclass)) { fprintf(stderr, "class mismatch: %s\n", word); goto failure; } /* * Now read the type. */ word = nsu_strsep(&cmdline, " \t\r\n"); if (word == NULL || *word == 0) { if (isdelete) { rdataclass = dns_rdataclass_any; rdatatype = dns_rdatatype_any; rdata->flags = DNS_RDATA_UPDATE; goto doneparsing; } else { fprintf(stderr, "could not read type\n"); goto failure; } } region.base = word; region.length = strlen(word); result = dns_rdatatype_fromtext(&rdatatype, ®ion); if (result != ISC_R_SUCCESS) { fprintf(stderr, "'%s' is not a valid type: %s\n", word, isc_result_totext(result)); goto failure; } } else { rdataclass = getzoneclass(); result = dns_rdatatype_fromtext(&rdatatype, ®ion); if (result != ISC_R_SUCCESS) { fprintf(stderr, "'%s' is not a valid class or type: " "%s\n", word, isc_result_totext(result)); goto failure; } } retval = parse_rdata(&cmdline, rdataclass, rdatatype, updatemsg, rdata); if (retval != STATUS_MORE) goto failure; if (isdelete) { if ((rdata->flags & DNS_RDATA_UPDATE) != 0) rdataclass = dns_rdataclass_any; else rdataclass = dns_rdataclass_none; } else { if ((rdata->flags & DNS_RDATA_UPDATE) != 0) { fprintf(stderr, "could not read rdata\n"); goto failure; } } doneparsing: result = dns_message_gettemprdatalist(updatemsg, &rdatalist); check_result(result, "dns_message_gettemprdatalist"); result = dns_message_gettemprdataset(updatemsg, &rdataset); check_result(result, "dns_message_gettemprdataset"); rdatalist->type = rdatatype; rdatalist->rdclass = rdataclass; rdatalist->covers = rdatatype; rdatalist->ttl = (dns_ttl_t)ttl; ISC_LIST_APPEND(rdatalist->rdata, rdata, link); dns_rdatalist_tordataset(rdatalist, rdataset); ISC_LIST_INIT(name->list); ISC_LIST_APPEND(name->list, rdataset, link); dns_message_addname(updatemsg, name, DNS_SECTION_UPDATE); return (STATUS_MORE); failure: if (name != NULL) dns_message_puttempname(updatemsg, &name); dns_message_puttemprdata(updatemsg, &rdata); return (STATUS_SYNTAX); } static isc_uint16_t evaluate_update(char *cmdline) { char *word; isc_boolean_t isdelete; ddebug("evaluate_update()"); word = nsu_strsep(&cmdline, " \t\r\n"); if (word == NULL || *word == 0) { fprintf(stderr, "could not read operation code\n"); return (STATUS_SYNTAX); } if (strcasecmp(word, "delete") == 0) isdelete = ISC_TRUE; else if (strcasecmp(word, "del") == 0) isdelete = ISC_TRUE; else if (strcasecmp(word, "add") == 0) isdelete = ISC_FALSE; else { fprintf(stderr, "incorrect operation code: %s\n", word); return (STATUS_SYNTAX); } return (update_addordelete(cmdline, isdelete)); } static void setzone(dns_name_t *zonename) { isc_result_t result; dns_name_t *name = NULL; dns_rdataset_t *rdataset = NULL; result = dns_message_firstname(updatemsg, DNS_SECTION_ZONE); if (result == ISC_R_SUCCESS) { dns_message_currentname(updatemsg, DNS_SECTION_ZONE, &name); dns_message_removename(updatemsg, name, DNS_SECTION_ZONE); for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_HEAD(name->list)) { ISC_LIST_UNLINK(name->list, rdataset, link); dns_rdataset_disassociate(rdataset); dns_message_puttemprdataset(updatemsg, &rdataset); } dns_message_puttempname(updatemsg, &name); } if (zonename != NULL) { result = dns_message_gettempname(updatemsg, &name); check_result(result, "dns_message_gettempname"); dns_name_init(name, NULL); dns_name_clone(zonename, name); result = dns_message_gettemprdataset(updatemsg, &rdataset); check_result(result, "dns_message_gettemprdataset"); dns_rdataset_makequestion(rdataset, getzoneclass(), dns_rdatatype_soa); ISC_LIST_INIT(name->list); ISC_LIST_APPEND(name->list, rdataset, link); dns_message_addname(updatemsg, name, DNS_SECTION_ZONE); } } static void show_message(FILE *stream, dns_message_t *msg, const char *description) { isc_result_t result; isc_buffer_t *buf = NULL; int bufsz; ddebug("show_message()"); setzone(userzone); bufsz = INITTEXT; do { if (bufsz > MAXTEXT) { fprintf(stderr, "could not allocate large enough " "buffer to display message\n"); exit(1); } if (buf != NULL) isc_buffer_free(&buf); result = isc_buffer_allocate(gmctx, &buf, bufsz); check_result(result, "isc_buffer_allocate"); result = dns_message_totext(msg, style, 0, buf); bufsz *= 2; } while (result == ISC_R_NOSPACE); if (result != ISC_R_SUCCESS) { fprintf(stderr, "could not convert message to text format.\n"); isc_buffer_free(&buf); return; } fprintf(stream, "%s\n%.*s", description, (int)isc_buffer_usedlength(buf), (char*)isc_buffer_base(buf)); isc_buffer_free(&buf); } static isc_uint16_t do_next_command(char *cmdline) { char *word; ddebug("do_next_command()"); word = nsu_strsep(&cmdline, " \t\r\n"); if (word == NULL || *word == 0) return (STATUS_SEND); if (word[0] == ';') return (STATUS_MORE); if (strcasecmp(word, "quit") == 0) return (STATUS_QUIT); if (strcasecmp(word, "prereq") == 0) return (evaluate_prereq(cmdline)); if (strcasecmp(word, "nxdomain") == 0) return (make_prereq(cmdline, ISC_FALSE, ISC_FALSE)); if (strcasecmp(word, "yxdomain") == 0) return (make_prereq(cmdline, ISC_TRUE, ISC_FALSE)); if (strcasecmp(word, "nxrrset") == 0) return (make_prereq(cmdline, ISC_FALSE, ISC_TRUE)); if (strcasecmp(word, "yxrrset") == 0) return (make_prereq(cmdline, ISC_TRUE, ISC_TRUE)); if (strcasecmp(word, "update") == 0) return (evaluate_update(cmdline)); if (strcasecmp(word, "delete") == 0) return (update_addordelete(cmdline, ISC_TRUE)); if (strcasecmp(word, "del") == 0) return (update_addordelete(cmdline, ISC_TRUE)); if (strcasecmp(word, "add") == 0) return (update_addordelete(cmdline, ISC_FALSE)); if (strcasecmp(word, "server") == 0) return (evaluate_server(cmdline)); if (strcasecmp(word, "local") == 0) return (evaluate_local(cmdline)); if (strcasecmp(word, "zone") == 0) return (evaluate_zone(cmdline)); if (strcasecmp(word, "class") == 0) return (evaluate_class(cmdline)); if (strcasecmp(word, "send") == 0) return (STATUS_SEND); if (strcasecmp(word, "debug") == 0) { if (debugging) ddebugging = ISC_TRUE; else debugging = ISC_TRUE; return (STATUS_MORE); } if (strcasecmp(word, "ttl") == 0) return (evaluate_ttl(cmdline)); if (strcasecmp(word, "show") == 0) { show_message(stdout, updatemsg, "Outgoing update query:"); return (STATUS_MORE); } if (strcasecmp(word, "answer") == 0) { if (answer != NULL) show_message(stdout, answer, "Answer:"); return (STATUS_MORE); } if (strcasecmp(word, "key") == 0) { usegsstsig = ISC_FALSE; return (evaluate_key(cmdline)); } if (strcasecmp(word, "realm") == 0) return (evaluate_realm(cmdline)); if (strcasecmp(word, "gsstsig") == 0) { #ifdef GSSAPI usegsstsig = ISC_TRUE; use_win2k_gsstsig = ISC_FALSE; #else fprintf(stderr, "gsstsig not supported\n"); #endif return (STATUS_MORE); } if (strcasecmp(word, "oldgsstsig") == 0) { #ifdef GSSAPI usegsstsig = ISC_TRUE; use_win2k_gsstsig = ISC_TRUE; #else fprintf(stderr, "gsstsig not supported\n"); #endif return (STATUS_MORE); } if (strcasecmp(word, "help") == 0) { fprintf(stdout, "nsupdate " VERSION ":\n" "local address [port] (set local resolver)\n" "server address [port] (set master server for zone)\n" "send (send the update request)\n" "show (show the update request)\n" "answer (show the answer to the last request)\n" "quit (quit, any pending update is not sent\n" "help (display this message_\n" "key [hmac:]keyname secret (use TSIG to sign the request)\n" "gsstsig (use GSS_TSIG to sign the request)\n" "oldgsstsig (use Microsoft's GSS_TSIG to sign the request)\n" "zone name (set the zone to be updated)\n" "class CLASS (set the zone's DNS class, e.g. IN (default), CH)\n" "[prereq] nxdomain name (does this name not exist)\n" "[prereq] yxdomain name (does this name exist)\n" "[prereq] nxrrset .... (does this RRset exist)\n" "[prereq] yxrrset .... (does this RRset not exist)\n" "[update] add .... (add the given record to the zone)\n" "[update] del[ete] .... (remove the given record(s) from the zone)\n"); return (STATUS_MORE); } if (strcasecmp(word, "version") == 0) { fprintf(stdout, "nsupdate " VERSION "\n"); return (STATUS_MORE); } fprintf(stderr, "incorrect section name: %s\n", word); return (STATUS_SYNTAX); } static isc_uint16_t get_next_command(void) { isc_uint16_t result = STATUS_QUIT; char cmdlinebuf[MAXCMD]; char *cmdline; isc_app_block(); if (interactive) { #ifdef HAVE_READLINE cmdline = readline("> "); if (cmdline != NULL) add_history(cmdline); #else fprintf(stdout, "> "); fflush(stdout); cmdline = fgets(cmdlinebuf, MAXCMD, input); #endif } else cmdline = fgets(cmdlinebuf, MAXCMD, input); isc_app_unblock(); if (cmdline != NULL) { char *tmp = cmdline; /* * Normalize input by removing any eol as readline() * removes eol but fgets doesn't. */ (void)nsu_strsep(&tmp, "\r\n"); result = do_next_command(cmdline); } #ifdef HAVE_READLINE if (interactive) free(cmdline); #endif return (result); } static isc_boolean_t user_interaction(void) { isc_uint16_t result = STATUS_MORE; ddebug("user_interaction()"); while ((result == STATUS_MORE) || (result == STATUS_SYNTAX)) { result = get_next_command(); if (!interactive && result == STATUS_SYNTAX) fatal("syntax error"); } if (result == STATUS_SEND) return (ISC_TRUE); return (ISC_FALSE); } static void done_update(void) { isc_event_t *event = global_event; ddebug("done_update()"); isc_task_send(global_task, &event); } static void check_tsig_error(dns_rdataset_t *rdataset, isc_buffer_t *b) { isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_any_tsig_t tsig; result = dns_rdataset_first(rdataset); check_result(result, "dns_rdataset_first"); dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &tsig, NULL); check_result(result, "dns_rdata_tostruct"); if (tsig.error != 0) { if (isc_buffer_remaininglength(b) < 1) check_result(ISC_R_NOSPACE, "isc_buffer_remaininglength"); isc_buffer_putstr(b, "(" /*)*/); result = dns_tsigrcode_totext(tsig.error, b); check_result(result, "dns_tsigrcode_totext"); if (isc_buffer_remaininglength(b) < 1) check_result(ISC_R_NOSPACE, "isc_buffer_remaininglength"); isc_buffer_putstr(b, /*(*/ ")"); } } static isc_boolean_t next_master(const char *caller, isc_sockaddr_t *addr, isc_result_t eresult) { char addrbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(addr, addrbuf, sizeof(addrbuf)); fprintf(stderr, "; Communication with %s failed: %s\n", addrbuf, isc_result_totext(eresult)); if (++master_inuse >= master_total) return (ISC_FALSE); ddebug("%s: trying next server", caller); return (ISC_TRUE); } static void update_completed(isc_task_t *task, isc_event_t *event) { dns_requestevent_t *reqev = NULL; isc_result_t result; dns_request_t *request; UNUSED(task); ddebug("update_completed()"); requests--; REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE); reqev = (dns_requestevent_t *)event; request = reqev->request; if (shuttingdown) { dns_request_destroy(&request); isc_event_free(&event); maybeshutdown(); return; } if (reqev->result != ISC_R_SUCCESS) { if (!next_master("recvsoa", &master_servers[master_inuse], reqev->result)) { seenerror = ISC_TRUE; goto done; } ddebug("Destroying request [%p]", request); dns_request_destroy(&request); dns_message_renderreset(updatemsg); dns_message_settsigkey(updatemsg, NULL); /* XXX MPA fix zonename is freed already */ send_update(zname, &master_servers[master_inuse]); isc_event_free(&event); return; } result = dns_message_create(gmctx, DNS_MESSAGE_INTENTPARSE, &answer); check_result(result, "dns_message_create"); result = dns_request_getresponse(request, answer, DNS_MESSAGEPARSE_PRESERVEORDER); switch (result) { case ISC_R_SUCCESS: if (answer->verify_attempted) ddebug("tsig verification successful"); break; case DNS_R_CLOCKSKEW: case DNS_R_EXPECTEDTSIG: case DNS_R_TSIGERRORSET: case DNS_R_TSIGVERIFYFAILURE: case DNS_R_UNEXPECTEDTSIG: case ISC_R_FAILURE: #if 0 if (usegsstsig && answer->rcode == dns_rcode_noerror) { /* * For MS DNS that violates RFC 2845, section 4.2 */ break; } #endif fprintf(stderr, "; TSIG error with server: %s\n", isc_result_totext(result)); seenerror = ISC_TRUE; break; default: check_result(result, "dns_request_getresponse"); } if (answer->rcode != dns_rcode_noerror) { seenerror = ISC_TRUE; if (!debugging) { char buf[64]; isc_buffer_t b; dns_rdataset_t *rds; isc_buffer_init(&b, buf, sizeof(buf) - 1); result = dns_rcode_totext(answer->rcode, &b); check_result(result, "dns_rcode_totext"); rds = dns_message_gettsig(answer, NULL); if (rds != NULL) check_tsig_error(rds, &b); fprintf(stderr, "update failed: %.*s\n", (int)isc_buffer_usedlength(&b), buf); } } if (debugging) show_message(stderr, answer, "\nReply from update query:"); done: dns_request_destroy(&request); if (usegsstsig) { dns_name_free(&tmpzonename, gmctx); dns_name_free(&restart_master, gmctx); } isc_event_free(&event); done_update(); } static void send_update(dns_name_t *zone, isc_sockaddr_t *master) { isc_result_t result; dns_request_t *request = NULL; unsigned int options = DNS_REQUESTOPT_CASE; isc_sockaddr_t *srcaddr; ddebug("send_update()"); setzone(zone); if (usevc) options |= DNS_REQUESTOPT_TCP; if (tsigkey == NULL && sig0key != NULL) { result = dns_message_setsig0key(updatemsg, sig0key); check_result(result, "dns_message_setsig0key"); } if (debugging) { char addrbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(master, addrbuf, sizeof(addrbuf)); fprintf(stderr, "Sending update to %s\n", addrbuf); } if (isc_sockaddr_pf(master) == AF_INET6) srcaddr = localaddr6; else srcaddr = localaddr4; /* Windows doesn't like the tsig name to be compressed. */ if (updatemsg->tsigname) updatemsg->tsigname->attributes |= DNS_NAMEATTR_NOCOMPRESS; result = dns_request_createvia3(requestmgr, updatemsg, srcaddr, master, options, tsigkey, timeout, udp_timeout, udp_retries, global_task, update_completed, NULL, &request); check_result(result, "dns_request_createvia3"); if (debugging) show_message(stdout, updatemsg, "Outgoing update query:"); requests++; } static void next_server(const char *caller, isc_sockaddr_t *addr, isc_result_t eresult) { char addrbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(addr, addrbuf, sizeof(addrbuf)); fprintf(stderr, "; Communication with %s failed: %s\n", addrbuf, isc_result_totext(eresult)); if (++ns_inuse >= ns_total) fatal("could not reach any name server"); else ddebug("%s: trying next server", caller); } static void recvsoa(isc_task_t *task, isc_event_t *event) { dns_requestevent_t *reqev = NULL; dns_request_t *request = NULL; isc_result_t result, eresult; dns_message_t *rcvmsg = NULL; dns_section_t section; dns_name_t *name = NULL; dns_rdataset_t *soaset = NULL; dns_rdata_soa_t soa; dns_rdata_t soarr = DNS_RDATA_INIT; int pass = 0; dns_name_t master; nsu_requestinfo_t *reqinfo; dns_message_t *soaquery = NULL; isc_sockaddr_t *addr; isc_sockaddr_t *srcaddr; isc_boolean_t seencname = ISC_FALSE; dns_name_t tname; unsigned int nlabels; UNUSED(task); ddebug("recvsoa()"); requests--; REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE); reqev = (dns_requestevent_t *)event; request = reqev->request; eresult = reqev->result; reqinfo = reqev->ev_arg; soaquery = reqinfo->msg; addr = reqinfo->addr; if (shuttingdown) { dns_request_destroy(&request); dns_message_destroy(&soaquery); isc_mem_put(gmctx, reqinfo, sizeof(nsu_requestinfo_t)); isc_event_free(&event); maybeshutdown(); return; } if (eresult != ISC_R_SUCCESS) { next_server("recvsoa", addr, eresult); ddebug("Destroying request [%p]", request); dns_request_destroy(&request); dns_message_renderreset(soaquery); dns_message_settsigkey(soaquery, NULL); sendrequest(&servers[ns_inuse], soaquery, &request); isc_mem_put(gmctx, reqinfo, sizeof(nsu_requestinfo_t)); isc_event_free(&event); setzoneclass(dns_rdataclass_none); return; } isc_mem_put(gmctx, reqinfo, sizeof(nsu_requestinfo_t)); reqinfo = NULL; isc_event_free(&event); reqev = NULL; ddebug("About to create rcvmsg"); result = dns_message_create(gmctx, DNS_MESSAGE_INTENTPARSE, &rcvmsg); check_result(result, "dns_message_create"); result = dns_request_getresponse(request, rcvmsg, DNS_MESSAGEPARSE_PRESERVEORDER); if (result == DNS_R_TSIGERRORSET && servers != NULL) { dns_message_destroy(&rcvmsg); ddebug("Destroying request [%p]", request); dns_request_destroy(&request); reqinfo = isc_mem_get(gmctx, sizeof(nsu_requestinfo_t)); if (reqinfo == NULL) fatal("out of memory"); reqinfo->msg = soaquery; reqinfo->addr = addr; dns_message_renderreset(soaquery); ddebug("retrying soa request without TSIG"); if (isc_sockaddr_pf(addr) == AF_INET6) srcaddr = localaddr6; else srcaddr = localaddr4; result = dns_request_createvia3(requestmgr, soaquery, srcaddr, addr, 0, NULL, FIND_TIMEOUT * 20, FIND_TIMEOUT, 3, global_task, recvsoa, reqinfo, &request); check_result(result, "dns_request_createvia"); requests++; return; } check_result(result, "dns_request_getresponse"); section = DNS_SECTION_ANSWER; POST(section); if (debugging) show_message(stderr, rcvmsg, "Reply from SOA query:"); if (rcvmsg->rcode != dns_rcode_noerror && rcvmsg->rcode != dns_rcode_nxdomain) fatal("response to SOA query was unsuccessful"); if (userzone != NULL && rcvmsg->rcode == dns_rcode_nxdomain) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(userzone, namebuf, sizeof(namebuf)); error("specified zone '%s' does not exist (NXDOMAIN)", namebuf); dns_message_destroy(&rcvmsg); dns_request_destroy(&request); dns_message_destroy(&soaquery); ddebug("Out of recvsoa"); done_update(); seenerror = ISC_TRUE; return; } lookforsoa: if (pass == 0) section = DNS_SECTION_ANSWER; else if (pass == 1) section = DNS_SECTION_AUTHORITY; else goto droplabel; result = dns_message_firstname(rcvmsg, section); if (result != ISC_R_SUCCESS) { pass++; goto lookforsoa; } while (result == ISC_R_SUCCESS) { name = NULL; dns_message_currentname(rcvmsg, section, &name); soaset = NULL; result = dns_message_findtype(name, dns_rdatatype_soa, 0, &soaset); if (result == ISC_R_SUCCESS) break; if (section == DNS_SECTION_ANSWER) { dns_rdataset_t *tset = NULL; if (dns_message_findtype(name, dns_rdatatype_cname, 0, &tset) == ISC_R_SUCCESS || dns_message_findtype(name, dns_rdatatype_dname, 0, &tset) == ISC_R_SUCCESS ) { seencname = ISC_TRUE; break; } } result = dns_message_nextname(rcvmsg, section); } if (soaset == NULL && !seencname) { pass++; goto lookforsoa; } if (seencname) goto droplabel; if (debugging) { char namestr[DNS_NAME_FORMATSIZE]; dns_name_format(name, namestr, sizeof(namestr)); fprintf(stderr, "Found zone name: %s\n", namestr); } result = dns_rdataset_first(soaset); check_result(result, "dns_rdataset_first"); dns_rdata_init(&soarr); dns_rdataset_current(soaset, &soarr); result = dns_rdata_tostruct(&soarr, &soa, NULL); check_result(result, "dns_rdata_tostruct"); dns_name_init(&master, NULL); dns_name_clone(&soa.origin, &master); /* * XXXMPA */ if (userzone != NULL) zname = userzone; else zname = name; if (debugging) { char namestr[DNS_NAME_FORMATSIZE]; dns_name_format(&master, namestr, sizeof(namestr)); fprintf(stderr, "The master is: %s\n", namestr); } if (default_servers) { char serverstr[DNS_NAME_MAXTEXT+1]; isc_buffer_t buf; size_t size; isc_buffer_init(&buf, serverstr, sizeof(serverstr)); result = dns_name_totext(&master, ISC_TRUE, &buf); check_result(result, "dns_name_totext"); serverstr[isc_buffer_usedlength(&buf)] = 0; if (master_servers != NULL && master_servers != servers) isc_mem_put(gmctx, master_servers, master_total * sizeof(isc_sockaddr_t)); master_total = MAX_SERVERADDRS; size = master_total * sizeof(isc_sockaddr_t); master_servers = isc_mem_get(gmctx, size); if (master_servers == NULL) fatal("out of memory"); memset(master_servers, 0, size); get_addresses(serverstr, dnsport, master_servers, master_total); master_inuse = 0; } else master_from_servers(); dns_rdata_freestruct(&soa); #ifdef GSSAPI if (usegsstsig) { dns_name_init(&tmpzonename, NULL); dns_name_dup(zname, gmctx, &tmpzonename); dns_name_init(&restart_master, NULL); dns_name_dup(&master, gmctx, &restart_master); start_gssrequest(&master); } else { send_update(zname, &master_servers[master_inuse]); setzoneclass(dns_rdataclass_none); } #else send_update(zname, &master_servers[master_inuse]); setzoneclass(dns_rdataclass_none); #endif dns_message_destroy(&soaquery); dns_request_destroy(&request); out: dns_message_destroy(&rcvmsg); ddebug("Out of recvsoa"); return; droplabel: result = dns_message_firstname(soaquery, DNS_SECTION_QUESTION); INSIST(result == ISC_R_SUCCESS); name = NULL; dns_message_currentname(soaquery, DNS_SECTION_QUESTION, &name); nlabels = dns_name_countlabels(name); if (nlabels == 1) fatal("could not find enclosing zone"); dns_name_init(&tname, NULL); dns_name_getlabelsequence(name, 1, nlabels - 1, &tname); dns_name_clone(&tname, name); dns_request_destroy(&request); dns_message_renderreset(soaquery); dns_message_settsigkey(soaquery, NULL); sendrequest(&servers[ns_inuse], soaquery, &request); goto out; } static void sendrequest(isc_sockaddr_t *destaddr, dns_message_t *msg, dns_request_t **request) { isc_result_t result; nsu_requestinfo_t *reqinfo; isc_sockaddr_t *srcaddr; reqinfo = isc_mem_get(gmctx, sizeof(nsu_requestinfo_t)); if (reqinfo == NULL) fatal("out of memory"); reqinfo->msg = msg; reqinfo->addr = destaddr; if (isc_sockaddr_pf(destaddr) == AF_INET6) srcaddr = localaddr6; else srcaddr = localaddr4; result = dns_request_createvia3(requestmgr, msg, srcaddr, destaddr, 0, default_servers ? NULL : tsigkey, FIND_TIMEOUT * 20, FIND_TIMEOUT, 3, global_task, recvsoa, reqinfo, request); check_result(result, "dns_request_createvia"); requests++; } #ifdef GSSAPI /* * Get the realm from the users kerberos ticket if possible */ static void get_ticket_realm(isc_mem_t *mctx) { krb5_context ctx; krb5_error_code rc; krb5_ccache ccache; krb5_principal princ; char *name, *ticket_realm; rc = krb5_init_context(&ctx); if (rc != 0) return; rc = krb5_cc_default(ctx, &ccache); if (rc != 0) { krb5_free_context(ctx); return; } rc = krb5_cc_get_principal(ctx, ccache, &princ); if (rc != 0) { krb5_cc_close(ctx, ccache); krb5_free_context(ctx); return; } rc = krb5_unparse_name(ctx, princ, &name); if (rc != 0) { krb5_free_principal(ctx, princ); krb5_cc_close(ctx, ccache); krb5_free_context(ctx); return; } ticket_realm = strrchr(name, '@'); if (ticket_realm != NULL) { realm = isc_mem_strdup(mctx, ticket_realm); } free(name); krb5_free_principal(ctx, princ); krb5_cc_close(ctx, ccache); krb5_free_context(ctx); if (realm != NULL && debugging) fprintf(stderr, "Found realm from ticket: %s\n", realm+1); } static void start_gssrequest(dns_name_t *master) { gss_ctx_id_t context; isc_buffer_t buf; isc_result_t result; isc_uint32_t val = 0; dns_message_t *rmsg; dns_request_t *request = NULL; dns_name_t *servname; dns_fixedname_t fname; char namestr[DNS_NAME_FORMATSIZE]; char mykeystr[DNS_NAME_FORMATSIZE]; char *err_message = NULL; debug("start_gssrequest"); usevc = ISC_TRUE; if (gssring != NULL) dns_tsigkeyring_detach(&gssring); gssring = NULL; result = dns_tsigkeyring_create(gmctx, &gssring); if (result != ISC_R_SUCCESS) fatal("dns_tsigkeyring_create failed: %s", isc_result_totext(result)); dns_name_format(master, namestr, sizeof(namestr)); if (kserver == NULL) { kserver = isc_mem_get(gmctx, sizeof(isc_sockaddr_t)); if (kserver == NULL) fatal("out of memory"); } if (servers == NULL) get_addresses(namestr, dnsport, kserver, 1); else memmove(kserver, &servers[ns_inuse], sizeof(isc_sockaddr_t)); dns_fixedname_init(&fname); servname = dns_fixedname_name(&fname); if (realm == NULL) get_ticket_realm(gmctx); result = isc_string_printf(servicename, sizeof(servicename), "DNS/%s%s", namestr, realm ? realm : ""); if (result != ISC_R_SUCCESS) fatal("isc_string_printf(servicename) failed: %s", isc_result_totext(result)); isc_buffer_init(&buf, servicename, strlen(servicename)); isc_buffer_add(&buf, strlen(servicename)); result = dns_name_fromtext(servname, &buf, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) fatal("dns_name_fromtext(servname) failed: %s", isc_result_totext(result)); dns_fixedname_init(&fkname); keyname = dns_fixedname_name(&fkname); isc_random_get(&val); result = isc_string_printf(mykeystr, sizeof(mykeystr), "%u.sig-%s", val, namestr); if (result != ISC_R_SUCCESS) fatal("isc_string_printf(mykeystr) failed: %s", isc_result_totext(result)); isc_buffer_init(&buf, mykeystr, strlen(mykeystr)); isc_buffer_add(&buf, strlen(mykeystr)); result = dns_name_fromtext(keyname, &buf, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) fatal("dns_name_fromtext(keyname) failed: %s", isc_result_totext(result)); /* Windows doesn't recognize name compression in the key name. */ keyname->attributes |= DNS_NAMEATTR_NOCOMPRESS; rmsg = NULL; result = dns_message_create(gmctx, DNS_MESSAGE_INTENTRENDER, &rmsg); if (result != ISC_R_SUCCESS) fatal("dns_message_create failed: %s", isc_result_totext(result)); /* Build first request. */ context = GSS_C_NO_CONTEXT; result = dns_tkey_buildgssquery(rmsg, keyname, servname, NULL, 0, &context, use_win2k_gsstsig, gmctx, &err_message); if (result == ISC_R_FAILURE) fatal("tkey query failed: %s", err_message != NULL ? err_message : "unknown error"); if (result != ISC_R_SUCCESS) fatal("dns_tkey_buildgssquery failed: %s", isc_result_totext(result)); send_gssrequest(kserver, rmsg, &request, context); } static void send_gssrequest(isc_sockaddr_t *destaddr, dns_message_t *msg, dns_request_t **request, gss_ctx_id_t context) { isc_result_t result; nsu_gssinfo_t *reqinfo; unsigned int options = 0; isc_sockaddr_t *srcaddr; debug("send_gssrequest"); reqinfo = isc_mem_get(gmctx, sizeof(nsu_gssinfo_t)); if (reqinfo == NULL) fatal("out of memory"); reqinfo->msg = msg; reqinfo->addr = destaddr; reqinfo->context = context; options |= DNS_REQUESTOPT_TCP; if (isc_sockaddr_pf(destaddr) == AF_INET6) srcaddr = localaddr6; else srcaddr = localaddr4; result = dns_request_createvia3(requestmgr, msg, srcaddr, destaddr, options, tsigkey, FIND_TIMEOUT * 20, FIND_TIMEOUT, 3, global_task, recvgss, reqinfo, request); check_result(result, "dns_request_createvia3"); if (debugging) show_message(stdout, msg, "Outgoing update query:"); requests++; } static void recvgss(isc_task_t *task, isc_event_t *event) { dns_requestevent_t *reqev = NULL; dns_request_t *request = NULL; isc_result_t result, eresult; dns_message_t *rcvmsg = NULL; nsu_gssinfo_t *reqinfo; dns_message_t *tsigquery = NULL; isc_sockaddr_t *addr; gss_ctx_id_t context; isc_buffer_t buf; dns_name_t *servname; dns_fixedname_t fname; char *err_message = NULL; UNUSED(task); ddebug("recvgss()"); requests--; REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE); reqev = (dns_requestevent_t *)event; request = reqev->request; eresult = reqev->result; reqinfo = reqev->ev_arg; tsigquery = reqinfo->msg; context = reqinfo->context; addr = reqinfo->addr; if (shuttingdown) { dns_request_destroy(&request); dns_message_destroy(&tsigquery); isc_mem_put(gmctx, reqinfo, sizeof(nsu_gssinfo_t)); isc_event_free(&event); maybeshutdown(); return; } if (eresult != ISC_R_SUCCESS) { next_server("recvgss", addr, eresult); ddebug("Destroying request [%p]", request); dns_request_destroy(&request); dns_message_renderreset(tsigquery); sendrequest(&servers[ns_inuse], tsigquery, &request); isc_mem_put(gmctx, reqinfo, sizeof(nsu_gssinfo_t)); isc_event_free(&event); return; } isc_mem_put(gmctx, reqinfo, sizeof(nsu_gssinfo_t)); isc_event_free(&event); reqev = NULL; ddebug("recvgss creating rcvmsg"); result = dns_message_create(gmctx, DNS_MESSAGE_INTENTPARSE, &rcvmsg); check_result(result, "dns_message_create"); result = dns_request_getresponse(request, rcvmsg, DNS_MESSAGEPARSE_PRESERVEORDER); check_result(result, "dns_request_getresponse"); if (debugging) show_message(stderr, rcvmsg, "recvmsg reply from GSS-TSIG query"); if (rcvmsg->rcode == dns_rcode_formerr && !tried_other_gsstsig) { ddebug("recvgss trying %s GSS-TSIG", use_win2k_gsstsig ? "Standard" : "Win2k"); if (use_win2k_gsstsig) use_win2k_gsstsig = ISC_FALSE; else use_win2k_gsstsig = ISC_TRUE; tried_other_gsstsig = ISC_TRUE; start_gssrequest(&restart_master); goto done; } if (rcvmsg->rcode != dns_rcode_noerror && rcvmsg->rcode != dns_rcode_nxdomain) fatal("response to GSS-TSIG query was unsuccessful"); dns_fixedname_init(&fname); servname = dns_fixedname_name(&fname); isc_buffer_init(&buf, servicename, strlen(servicename)); isc_buffer_add(&buf, strlen(servicename)); result = dns_name_fromtext(servname, &buf, dns_rootname, 0, NULL); check_result(result, "dns_name_fromtext"); tsigkey = NULL; result = dns_tkey_gssnegotiate(tsigquery, rcvmsg, servname, &context, &tsigkey, gssring, use_win2k_gsstsig, &err_message); switch (result) { case DNS_R_CONTINUE: send_gssrequest(kserver, tsigquery, &request, context); break; case ISC_R_SUCCESS: /* * XXXSRA Waaay too much fun here. There's no good * reason why we need a TSIG here (the people who put * it into the spec admitted at the time that it was * not a security issue), and Windows clients don't * seem to work if named complies with the spec and * includes the gratuitous TSIG. So we're in the * bizarre situation of having to choose between * complying with a useless requirement in the spec * and interoperating. This is nuts. If we can * confirm this behavior, we should ask the WG to * consider removing the requirement for the * gratuitous TSIG here. For the moment, we ignore * the TSIG -- this too is a spec violation, but it's * the least insane thing to do. */ #if 0 /* * Verify the signature. */ rcvmsg->state = DNS_SECTION_ANY; dns_message_setquerytsig(rcvmsg, NULL); result = dns_message_settsigkey(rcvmsg, tsigkey); check_result(result, "dns_message_settsigkey"); result = dns_message_checksig(rcvmsg, NULL); ddebug("tsig verification: %s", dns_result_totext(result)); check_result(result, "dns_message_checksig"); #endif /* 0 */ send_update(&tmpzonename, &master_servers[master_inuse]); setzoneclass(dns_rdataclass_none); break; default: fatal("dns_tkey_negotiategss: %s %s", isc_result_totext(result), err_message != NULL ? err_message : ""); } done: dns_request_destroy(&request); dns_message_destroy(&tsigquery); dns_message_destroy(&rcvmsg); ddebug("Out of recvgss"); } #endif static void start_update(void) { isc_result_t result; dns_rdataset_t *rdataset = NULL; dns_name_t *name = NULL; dns_request_t *request = NULL; dns_message_t *soaquery = NULL; dns_name_t *firstname; dns_section_t section = DNS_SECTION_UPDATE; ddebug("start_update()"); if (answer != NULL) dns_message_destroy(&answer); /* * If we have both the zone and the servers we have enough information * to send the update straight away otherwise we need to discover * the zone and / or the master server. */ if (userzone != NULL && !default_servers && !usegsstsig) { master_from_servers(); send_update(userzone, &master_servers[master_inuse]); setzoneclass(dns_rdataclass_none); return; } result = dns_message_create(gmctx, DNS_MESSAGE_INTENTRENDER, &soaquery); check_result(result, "dns_message_create"); if (default_servers) soaquery->flags |= DNS_MESSAGEFLAG_RD; result = dns_message_gettempname(soaquery, &name); check_result(result, "dns_message_gettempname"); result = dns_message_gettemprdataset(soaquery, &rdataset); check_result(result, "dns_message_gettemprdataset"); dns_rdataset_makequestion(rdataset, getzoneclass(), dns_rdatatype_soa); if (userzone != NULL) { dns_name_init(name, NULL); dns_name_clone(userzone, name); } else { dns_rdataset_t *tmprdataset; result = dns_message_firstname(updatemsg, section); if (result == ISC_R_NOMORE) { section = DNS_SECTION_PREREQUISITE; result = dns_message_firstname(updatemsg, section); } if (result != ISC_R_SUCCESS) { dns_message_puttempname(soaquery, &name); dns_rdataset_disassociate(rdataset); dns_message_puttemprdataset(soaquery, &rdataset); dns_message_destroy(&soaquery); done_update(); return; } firstname = NULL; dns_message_currentname(updatemsg, section, &firstname); dns_name_init(name, NULL); dns_name_clone(firstname, name); /* * Looks to see if the first name references a DS record * and if that name is not the root remove a label as DS * records live in the parent zone so we need to start our * search one label up. */ tmprdataset = ISC_LIST_HEAD(firstname->list); if (section == DNS_SECTION_UPDATE && !dns_name_equal(firstname, dns_rootname) && tmprdataset->type == dns_rdatatype_ds) { unsigned int labels = dns_name_countlabels(name); dns_name_getlabelsequence(name, 1, labels - 1, name); } } ISC_LIST_INIT(name->list); ISC_LIST_APPEND(name->list, rdataset, link); dns_message_addname(soaquery, name, DNS_SECTION_QUESTION); ns_inuse = 0; sendrequest(&servers[ns_inuse], soaquery, &request); } static void cleanup(void) { ddebug("cleanup()"); if (answer != NULL) dns_message_destroy(&answer); #ifdef GSSAPI if (tsigkey != NULL) { ddebug("detach tsigkey x%p", tsigkey); dns_tsigkey_detach(&tsigkey); } if (gssring != NULL) { ddebug("Detaching GSS-TSIG keyring"); dns_tsigkeyring_detach(&gssring); } if (kserver != NULL) { isc_mem_put(gmctx, kserver, sizeof(isc_sockaddr_t)); kserver = NULL; } if (realm != NULL) { isc_mem_free(gmctx, realm); realm = NULL; } #endif if (sig0key != NULL) dst_key_free(&sig0key); ddebug("Shutting down task manager"); isc_taskmgr_destroy(&taskmgr); ddebug("Destroying event"); isc_event_free(&global_event); ddebug("Shutting down socket manager"); isc_socketmgr_destroy(&socketmgr); ddebug("Shutting down timer manager"); isc_timermgr_destroy(&timermgr); ddebug("Destroying hash context"); isc_hash_destroy(); ddebug("Destroying name state"); dns_name_destroy(); ddebug("Removing log context"); isc_log_destroy(&glctx); ddebug("Destroying memory context"); if (memdebugging) isc_mem_stats(gmctx, stderr); isc_mem_destroy(&gmctx); } static void getinput(isc_task_t *task, isc_event_t *event) { isc_boolean_t more; UNUSED(task); if (shuttingdown) { maybeshutdown(); return; } if (global_event == NULL) global_event = event; reset_system(); more = user_interaction(); if (!more) { isc_app_shutdown(); return; } start_update(); return; } int main(int argc, char **argv) { isc_result_t result; style = &dns_master_style_debug; input = stdin; interactive = ISC_TF(isatty(0)); isc_app_start(); pre_parse_args(argc, argv); result = isc_mem_create(0, 0, &gmctx); check_result(result, "isc_mem_create"); parse_args(argc, argv, gmctx, &entropy); setup_system(); result = isc_app_onrun(gmctx, global_task, getinput, NULL); check_result(result, "isc_app_onrun"); (void)isc_app_run(); cleanup(); isc_app_finish(); if (seenerror) return (2); else return (0); } bind9-9.10.3.dfsg.P4/bin/nsupdate/win32/0002755000470500017500000000000012664730167016741 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/nsupdate/win32/nsupdate.dsw0000644000470500017500000000103512664710322021267 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "nsupdate"=".\nsupdate.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/bin/nsupdate/win32/nsupdate.vcxproj.filters.in0000644000470500017500000000137612664710322024251 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files bind9-9.10.3.dfsg.P4/bin/nsupdate/win32/nsupdate.dsp.in0000644000470500017500000001241112664710322021665 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="nsupdate" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 CFG=nsupdate - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "nsupdate.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "nsupdate.mak" CFG="nsupdate - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "nsupdate - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "nsupdate - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "nsupdate - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../include" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ @GSSAPI_INC@ @READLINE_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/lwres/win32/include" /I "../../../lib/lwres/include" /I "../../../lib/lwres/win32/include/lwres" /I "../../../lib/dns/include" /I "../../../lib/bind9/include" /I "../../../lib/isccfg/include" /D "WIN32" @USE_GSSAPI@ /D "USE_READLINE_STATIC" /D "__STDC__" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @MACHINE@ # ADD LINK32 @GSSAPI_LIB@ @KRB5_LIB@ @READLINE_LIB@ ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ../../../lib/lwres/win32/Release/liblwres.lib user32.lib advapi32.lib ws2_32.lib ../../../lib/bind9/win32/Release/libbind9.lib ../../../lib/isccfg/win32/Release/libisccfg.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/nsupdate.exe" !ELSEIF "$(CFG)" == "nsupdate - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../include" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ @GSSAPI_INC@ @READLINE_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/lwres/win32/include" /I "../../../lib/lwres/include" /I "../../../lib/lwres/win32/include/lwres" /I "../../../lib/dns/include" /I "../../../lib/bind9/include" /I "../../../lib/isccfg/include" /D "WIN32" @USE_GSSAPI@ /D "USE_READLINE_STATIC" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c # SUBTRACT CPP /X /u @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept # ADD LINK32 @GSSAPI_LIB@ @KRB5_LIB@ @READLINE_LIBD@ ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ../../../lib/lwres/win32/Debug/liblwres.lib user32.lib advapi32.lib ws2_32.lib ../../../lib/bind9/win32/Debug/libbind9.lib ../../../lib/isccfg/win32/Debug/libisccfg.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/nsupdate.exe" /pdbtype:sept !ENDIF # Begin Target # Name "nsupdate - @PLATFORM@ Release" # Name "nsupdate - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\nsupdate.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/bin/nsupdate/win32/nsupdate.vcxproj.user0000644000470500017500000000021712664710322023143 0ustar lamontlamont bind9-9.10.3.dfsg.P4/bin/nsupdate/win32/nsupdate.vcxproj.in0000644000470500017500000001622112664710322022575 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {C41266C7-E27E-4D60-9815-82D3B32BF82F} Win32Proj nsupdate Application true MultiByte Application false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ Level3 Disabled WIN32;@USE_GSSAPI@USE_READLINE_STATIC;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true .\;..\include;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@@GSSAPI_INC@@READLINE_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\lwres\win32\include;..\..\..\lib\lwres\include;..\..\..\lib\lwres\win32\include\lwres;..\..\..\lib\dns\include;..\..\..\lib\bind9\include;..\..\..\lib\isccfg\include;%(AdditionalIncludeDirectories) Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) ..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);..\..\..\lib\lwres\win32\$(Configuration);..\..\..\lib\bind9\win32\$(Configuration);..\..\..\lib\isccfg\win32\$(Configuration);%(AdditionalLibraryDirectories) @READLINE_LIBD@@GSSAPI_LIB@@KRB5_LIB@libisc.lib;libdns.lib;liblwres.lib;libbind9.lib;libisccfg.lib;ws2_32.lib;%(AdditionalDependencies) Level3 MaxSpeed true @INTRINSIC@ WIN32;@USE_GSSAPI@USE_READLINE_STATIC;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb .\;..\include;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@@GSSAPI_INC@@READLINE_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\lwres\win32\include;..\..\..\lib\lwres\include;..\..\..\lib\lwres\win32\include\lwres;..\..\..\lib\dns\include;..\..\..\lib\bind9\include;..\..\..\lib\isccfg\include;%(AdditionalIncludeDirectories) Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Default ..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);..\..\..\lib\lwres\win32\$(Configuration);..\..\..\lib\bind9\win32\$(Configuration);..\..\..\lib\isccfg\win32\$(Configuration);%(AdditionalLibraryDirectories) @READLINE_LIB@@GSSAPI_LIB@@KRB5_LIB@libisc.lib;libdns.lib;liblwres.lib;libbind9.lib;libisccfg.lib;ws2_32.lib;%(AdditionalDependencies) bind9-9.10.3.dfsg.P4/bin/nsupdate/win32/nsupdate.mak.in0000644000470500017500000002740512664710322021660 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on nsupdate.dsp !IF "$(CFG)" == "" CFG=nsupdate - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to nsupdate - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "nsupdate - @PLATFORM@ Release" && "$(CFG)" != "nsupdate - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "nsupdate.mak" CFG="nsupdate - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "nsupdate - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "nsupdate - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "nsupdate - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "nsupdate - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release !IF "$(RECURSE)" == "0" ALL : "..\..\..\Build\Release\nsupdate.exe" !ELSE ALL : "libbind9 - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" "libdns - @PLATFORM@ Release" "..\..\..\Build\Release\nsupdate.exe" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libdns - @PLATFORM@ ReleaseCLEAN" "libisc - @PLATFORM@ ReleaseCLEAN" "libbind9 - @PLATFORM@ ReleaseCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\nsupdate.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "..\..\..\Build\Release\nsupdate.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../include" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ @GSSAPI_INC@ @READLINE_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/lwres/win32/include" /I "../../../lib/lwres/include" /I "../../../lib/lwres/win32/include/lwres" /I "../../../lib/dns/include" /I "../../../lib/bind9/include" /I "../../../lib/isccfg/include" /D "WIN32" @USE_GSSAPI@ /D "USE_READLINE_STATIC" /D "__STDC__" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\nsupdate.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\nsupdate.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ../../../lib/lwres/win32/Release/liblwres.lib user32.lib advapi32.lib ws2_32.lib ../../../lib/bind9/win32/Release/libbind9.lib ../../../lib/isccfg/win32/Release/libisccfg.lib @GSSAPI_LIB@ @KRB5_LIB@ @READLINE_LIB@ /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\nsupdate.pdb" @MACHINE@ /out:"../../../Build/Release/nsupdate.exe" LINK32_OBJS= \ "$(INTDIR)\nsupdate.obj" \ "..\..\..\lib\dns\win32\Release\libdns.lib" \ "..\..\..\lib\isc\win32\Release\libisc.lib" \ "..\..\..\lib\bind9\win32\Release\libbind9.lib" \ "..\..\..\lib\isccfg\win32\Release\libisccfg.lib" "..\..\..\Build\Release\nsupdate.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "nsupdate - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros !IF "$(RECURSE)" == "0" ALL : "..\..\..\Build\Debug\nsupdate.exe" "$(OUTDIR)\nsupdate.bsc" !ELSE ALL : "libbind9 - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" "libdns - @PLATFORM@ Debug" "..\..\..\Build\Debug\nsupdate.exe" "$(OUTDIR)\nsupdate.bsc" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libdns - @PLATFORM@ DebugCLEAN" "libisc - @PLATFORM@ DebugCLEAN" "libbind9 - @PLATFORM@ DebugCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\nsupdate.obj" -@erase "$(INTDIR)\nsupdate.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\nsupdate.bsc" -@erase "$(OUTDIR)\nsupdate.pdb" -@erase "..\..\..\Build\Debug\nsupdate.exe" -@erase "..\..\..\Build\Debug\nsupdate.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../include" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ @GSSAPI_INC@ @READLINE_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/lwres/win32/include" /I "../../../lib/lwres/include" /I "../../../lib/lwres/win32/include/lwres" /I "../../../lib/dns/include" /I "../../../lib/bind9/include" /I "../../../lib/isccfg/include" /D "WIN32" @USE_GSSAPI@ /D "USE_READLINE_STATIC" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\nsupdate.bsc" BSC32_SBRS= \ "$(INTDIR)\nsupdate.sbr" "$(OUTDIR)\nsupdate.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ../../../lib/lwres/win32/Debug/liblwres.lib user32.lib advapi32.lib ws2_32.lib ../../../lib/bind9/win32/Debug/libbind9.lib ../../../lib/isccfg/win32/Debug/libisccfg.lib @GSSAPI_LIB@ @KRB5_LIB@ @READLINE_LIBD@ /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\nsupdate.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/nsupdate.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\nsupdate.obj" \ "..\..\..\lib\dns\win32\Debug\libdns.lib" \ "..\..\..\lib\isc\win32\Debug\libisc.lib" \ "..\..\..\lib\bind9\win32\Debug\libbind9.lib" \ "..\..\..\lib\isccfg\win32\Release\libisccfg.lib" "..\..\..\Build\Debug\nsupdate.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("nsupdate.dep") !INCLUDE "nsupdate.dep" !ELSE !MESSAGE Warning: cannot find "nsupdate.dep" !ENDIF !ENDIF !IF "$(CFG)" == "nsupdate - @PLATFORM@ Release" || "$(CFG)" == "nsupdate - @PLATFORM@ Debug" SOURCE=..\nsupdate.c !IF "$(CFG)" == "nsupdate - @PLATFORM@ Release" "$(INTDIR)\nsupdate.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "nsupdate - @PLATFORM@ Debug" "$(INTDIR)\nsupdate.obj" "$(INTDIR)\nsupdate.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !IF "$(CFG)" == "nsupdate - @PLATFORM@ Release" "libdns - @PLATFORM@ Release" : cd "..\..\..\lib\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" cd "..\..\..\bin\nsupdate\win32" "libdns - @PLATFORM@ ReleaseCLEAN" : cd "..\..\..\lib\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\..\bin\nsupdate\win32" !ELSEIF "$(CFG)" == "nsupdate - @PLATFORM@ Debug" "libdns - @PLATFORM@ Debug" : cd "..\..\..\lib\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" cd "..\..\..\bin\nsupdate\win32" "libdns - @PLATFORM@ DebugCLEAN" : cd "..\..\..\lib\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\..\bin\nsupdate\win32" !ENDIF !IF "$(CFG)" == "nsupdate - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" : cd "..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" cd "..\..\..\bin\nsupdate\win32" "libisc - @PLATFORM@ ReleaseCLEAN" : cd "..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\..\bin\nsupdate\win32" !ELSEIF "$(CFG)" == "nsupdate - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" : cd "..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" cd "..\..\..\bin\nsupdate\win32" "libisc - @PLATFORM@ DebugCLEAN" : cd "..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\..\bin\nsupdate\win32" !ENDIF !IF "$(CFG)" == "nsupdate - @PLATFORM@ Release" "libbind9 - @PLATFORM@ Release" : cd "..\..\..\lib\bind9\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libbind9.mak" CFG="libbind9 - @PLATFORM@ Release" cd "..\..\..\bin\nsupdate\win32" "libbind9 - @PLATFORM@ ReleaseCLEAN" : cd "..\..\..\lib\bind9\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libbind9.mak" CFG="libbind9 - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\..\bin\nsupdate\win32" !ELSEIF "$(CFG)" == "nsupdate - @PLATFORM@ Debug" "libbind9 - @PLATFORM@ Debug" : cd "..\..\..\lib\bind9\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libbind9.mak" CFG="libbind9 - @PLATFORM@ Debug" cd "..\..\..\bin\nsupdate\win32" "libbind9 - @PLATFORM@ DebugCLEAN" : cd "..\..\..\lib\bind9\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libbind9.mak" CFG="libbind9 - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\..\bin\nsupdate\win32" !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/bin/nsupdate/nsupdate.10000644000470500017500000003560312664710322017700 0ustar lamontlamont.\" Copyright (C) 2004-2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000-2003 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: nsupdate .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: April 18, 2014 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "NSUPDATE" "1" "April 18, 2014" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" nsupdate \- Dynamic DNS update utility .SH "SYNOPSIS" .HP 9 \fBnsupdate\fR [\fB\-d\fR] [\fB\-D\fR] [\fB\-L\ \fR\fB\fIlevel\fR\fR] [[\fB\-g\fR] | [\fB\-o\fR] | [\fB\-l\fR] | [\fB\-y\ \fR\fB\fI[hmac:]\fR\fIkeyname:secret\fR\fR] | [\fB\-k\ \fR\fB\fIkeyfile\fR\fR]] [\fB\-t\ \fR\fB\fItimeout\fR\fR] [\fB\-u\ \fR\fB\fIudptimeout\fR\fR] [\fB\-r\ \fR\fB\fIudpretries\fR\fR] [\fB\-R\ \fR\fB\fIrandomdev\fR\fR] [\fB\-v\fR] [\fB\-T\fR] [\fB\-P\fR] [\fB\-V\fR] [filename] .SH "DESCRIPTION" .PP \fBnsupdate\fR is used to submit Dynamic DNS Update requests as defined in RFC 2136 to a name server. This allows resource records to be added or removed from a zone without manually editing the zone file. A single update request can contain requests to add or remove more than one resource record. .PP Zones that are under dynamic control via \fBnsupdate\fR or a DHCP server should not be edited by hand. Manual edits could conflict with dynamic updates and cause data to be lost. .PP The resource records that are dynamically added or removed with \fBnsupdate\fR have to be in the same zone. Requests are sent to the zone's master server. This is identified by the MNAME field of the zone's SOA record. .PP Transaction signatures can be used to authenticate the Dynamic DNS updates. These use the TSIG resource record type described in RFC 2845 or the SIG(0) record described in RFC 2535 and RFC 2931 or GSS\-TSIG as described in RFC 3645. .PP TSIG relies on a shared secret that should only be known to \fBnsupdate\fR and the name server. For instance, suitable \fBkey\fR and \fBserver\fR statements would be added to \fI/etc/named.conf\fR so that the name server can associate the appropriate secret key and algorithm with the IP address of the client application that will be using TSIG authentication. You can use \fBddns\-confgen\fR to generate suitable configuration fragments. \fBnsupdate\fR uses the \fB\-y\fR or \fB\-k\fR options to provide the TSIG shared secret. These options are mutually exclusive. .PP SIG(0) uses public key cryptography. To use a SIG(0) key, the public key must be stored in a KEY record in a zone served by the name server. .PP GSS\-TSIG uses Kerberos credentials. Standard GSS\-TSIG mode is switched on with the \fB\-g\fR flag. A non\-standards\-compliant variant of GSS\-TSIG used by Windows 2000 can be switched on with the \fB\-o\fR flag. .SH "OPTIONS" .PP \-d .RS 4 Debug mode. This provides tracing information about the update requests that are made and the replies received from the name server. .RE .PP \-D .RS 4 Extra debug mode. .RE .PP \-k \fIkeyfile\fR .RS 4 The file containing the TSIG authentication key. Keyfiles may be in two formats: a single file containing a \fInamed.conf\fR\-format \fBkey\fR statement, which may be generated automatically by \fBddns\-confgen\fR, or a pair of files whose names are of the format \fIK{name}.+157.+{random}.key\fR and \fIK{name}.+157.+{random}.private\fR, which can be generated by \fBdnssec\-keygen\fR. The \fB\-k\fR may also be used to specify a SIG(0) key used to authenticate Dynamic DNS update requests. In this case, the key specified is not an HMAC\-MD5 key. .RE .PP \-l .RS 4 Local\-host only mode. This sets the server address to localhost (disabling the \fBserver\fR so that the server address cannot be overridden). Connections to the local server will use a TSIG key found in \fI/var/run/named/session.key\fR, which is automatically generated by \fBnamed\fR if any local master zone has set \fBupdate\-policy\fR to \fBlocal\fR. The location of this key file can be overridden with the \fB\-k\fR option. .RE .PP \-L \fIlevel\fR .RS 4 Set the logging debug level. If zero, logging is disabled. .RE .PP \-p \fIport\fR .RS 4 Set the port to use for connections to a name server. The default is 53. .RE .PP \-P .RS 4 Print the list of private BIND\-specific resource record types whose format is understood by \fBnsupdate\fR. See also the \fB\-T\fR option. .RE .PP \-r \fIudpretries\fR .RS 4 The number of UDP retries. The default is 3. If zero, only one update request will be made. .RE .PP \-R \fIrandomdev\fR .RS 4 Where to obtain randomness. If the operating system does not provide a \fI/dev/random\fR or equivalent device, the default source of randomness is keyboard input. \fIrandomdev\fR specifies the name of a character device or file containing random data to be used instead of the default. The special value \fIkeyboard\fR indicates that keyboard input should be used. This option may be specified multiple times. .RE .PP \-t \fItimeout\fR .RS 4 The maximum time an update request can take before it is aborted. The default is 300 seconds. Zero can be used to disable the timeout. .RE .PP \-T .RS 4 Print the list of IANA standard resource record types whose format is understood by \fBnsupdate\fR. \fBnsupdate\fR will exit after the lists are printed. The \fB\-T\fR option can be combined with the \fB\-P\fR option. .sp Other types can be entered using "TYPEXXXXX" where "XXXXX" is the decimal value of the type with no leading zeros. The rdata, if present, will be parsed using the UNKNOWN rdata format, ( ). .RE .PP \-u \fIudptimeout\fR .RS 4 The UDP retry interval. The default is 3 seconds. If zero, the interval will be computed from the timeout interval and number of UDP retries. .RE .PP \-v .RS 4 Use TCP even for small update requests. By default, \fBnsupdate\fR uses UDP to send update requests to the name server unless they are too large to fit in a UDP request in which case TCP will be used. TCP may be preferable when a batch of update requests is made. .RE .PP \-V .RS 4 Print the version number and exit. .RE .PP \-y \fI[hmac:]\fR\fIkeyname:secret\fR .RS 4 Literal TSIG authentication key. \fIkeyname\fR is the name of the key, and \fIsecret\fR is the base64 encoded shared secret. \fIhmac\fR is the name of the key algorithm; valid choices are hmac\-md5, hmac\-sha1, hmac\-sha224, hmac\-sha256, hmac\-sha384, or hmac\-sha512. If \fIhmac\fR is not specified, the default is hmac\-md5. .sp NOTE: Use of the \fB\-y\fR option is discouraged because the shared secret is supplied as a command line argument in clear text. This may be visible in the output from \fBps\fR(1) or in a history file maintained by the user's shell. .RE .SH "INPUT FORMAT" .PP \fBnsupdate\fR reads input from \fIfilename\fR or standard input. Each command is supplied on exactly one line of input. Some commands are for administrative purposes. The others are either update instructions or prerequisite checks on the contents of the zone. These checks set conditions that some name or set of resource records (RRset) either exists or is absent from the zone. These conditions must be met if the entire update request is to succeed. Updates will be rejected if the tests for the prerequisite conditions fail. .PP Every update request consists of zero or more prerequisites and zero or more updates. This allows a suitably authenticated update request to proceed if some specified resource records are present or missing from the zone. A blank input line (or the \fBsend\fR command) causes the accumulated commands to be sent as one Dynamic DNS update request to the name server. .PP The command formats and their meaning are as follows: .PP \fBserver\fR {servername} [port] .RS 4 Sends all dynamic update requests to the name server \fIservername\fR. When no server statement is provided, \fBnsupdate\fR will send updates to the master server of the correct zone. The MNAME field of that zone's SOA record will identify the master server for that zone. \fIport\fR is the port number on \fIservername\fR where the dynamic update requests get sent. If no port number is specified, the default DNS port number of 53 is used. .RE .PP \fBlocal\fR {address} [port] .RS 4 Sends all dynamic update requests using the local \fIaddress\fR. When no local statement is provided, \fBnsupdate\fR will send updates using an address and port chosen by the system. \fIport\fR can additionally be used to make requests come from a specific port. If no port number is specified, the system will assign one. .RE .PP \fBzone\fR {zonename} .RS 4 Specifies that all updates are to be made to the zone \fIzonename\fR. If no \fIzone\fR statement is provided, \fBnsupdate\fR will attempt determine the correct zone to update based on the rest of the input. .RE .PP \fBclass\fR {classname} .RS 4 Specify the default class. If no \fIclass\fR is specified, the default class is \fIIN\fR. .RE .PP \fBttl\fR {seconds} .RS 4 Specify the default time to live for records to be added. The value \fInone\fR will clear the default ttl. .RE .PP \fBkey\fR [hmac:] {keyname} {secret} .RS 4 Specifies that all updates are to be TSIG\-signed using the \fIkeyname\fR \fIsecret\fR pair. If \fIhmac\fR is specified, then it sets the signing algorithm in use; the default is hmac\-md5. The \fBkey\fR command overrides any key specified on the command line via \fB\-y\fR or \fB\-k\fR. .RE .PP \fBgsstsig\fR .RS 4 Use GSS\-TSIG to sign the updated. This is equivalent to specifying \fB\-g\fR on the commandline. .RE .PP \fBoldgsstsig\fR .RS 4 Use the Windows 2000 version of GSS\-TSIG to sign the updated. This is equivalent to specifying \fB\-o\fR on the commandline. .RE .PP \fBrealm\fR {[realm_name]} .RS 4 When using GSS\-TSIG use \fIrealm_name\fR rather than the default realm in \fIkrb5.conf\fR. If no realm is specified the saved realm is cleared. .RE .PP \fB[prereq]\fR\fB nxdomain\fR {domain\-name} .RS 4 Requires that no resource record of any type exists with name \fIdomain\-name\fR. .RE .PP \fB[prereq]\fR\fB yxdomain\fR {domain\-name} .RS 4 Requires that \fIdomain\-name\fR exists (has as at least one resource record, of any type). .RE .PP \fB[prereq]\fR\fB nxrrset\fR {domain\-name} [class] {type} .RS 4 Requires that no resource record exists of the specified \fItype\fR, \fIclass\fR and \fIdomain\-name\fR. If \fIclass\fR is omitted, IN (internet) is assumed. .RE .PP \fB[prereq]\fR\fB yxrrset\fR {domain\-name} [class] {type} .RS 4 This requires that a resource record of the specified \fItype\fR, \fIclass\fR and \fIdomain\-name\fR must exist. If \fIclass\fR is omitted, IN (internet) is assumed. .RE .PP \fB[prereq]\fR\fB yxrrset\fR {domain\-name} [class] {type} {data...} .RS 4 The \fIdata\fR from each set of prerequisites of this form sharing a common \fItype\fR, \fIclass\fR, and \fIdomain\-name\fR are combined to form a set of RRs. This set of RRs must exactly match the set of RRs existing in the zone at the given \fItype\fR, \fIclass\fR, and \fIdomain\-name\fR. The \fIdata\fR are written in the standard text representation of the resource record's RDATA. .RE .PP \fB[update]\fR\fB del\fR\fB[ete]\fR {domain\-name} [ttl] [class] [type\ [data...]] .RS 4 Deletes any resource records named \fIdomain\-name\fR. If \fItype\fR and \fIdata\fR is provided, only matching resource records will be removed. The internet class is assumed if \fIclass\fR is not supplied. The \fIttl\fR is ignored, and is only allowed for compatibility. .RE .PP \fB[update]\fR\fB add\fR {domain\-name} {ttl} [class] {type} {data...} .RS 4 Adds a new resource record with the specified \fIttl\fR, \fIclass\fR and \fIdata\fR. .RE .PP \fBshow\fR .RS 4 Displays the current message, containing all of the prerequisites and updates specified since the last send. .RE .PP \fBsend\fR .RS 4 Sends the current message. This is equivalent to entering a blank line. .RE .PP \fBanswer\fR .RS 4 Displays the answer. .RE .PP \fBdebug\fR .RS 4 Turn on debugging. .RE .PP \fBversion\fR .RS 4 Print version number. .RE .PP \fBhelp\fR .RS 4 Print a list of commands. .RE .PP Lines beginning with a semicolon are comments and are ignored. .SH "EXAMPLES" .PP The examples below show how \fBnsupdate\fR could be used to insert and delete resource records from the \fBexample.com\fR zone. Notice that the input in each example contains a trailing blank line so that a group of commands are sent as one dynamic update request to the master name server for \fBexample.com\fR. .sp .RS 4 .nf # nsupdate > update delete oldhost.example.com A > update add newhost.example.com 86400 A 172.16.1.1 > send .fi .RE .sp .PP Any A records for \fBoldhost.example.com\fR are deleted. And an A record for \fBnewhost.example.com\fR with IP address 172.16.1.1 is added. The newly\-added record has a 1 day TTL (86400 seconds). .sp .RS 4 .nf # nsupdate > prereq nxdomain nickname.example.com > update add nickname.example.com 86400 CNAME somehost.example.com > send .fi .RE .sp .PP The prerequisite condition gets the name server to check that there are no resource records of any type for \fBnickname.example.com\fR. If there are, the update request fails. If this name does not exist, a CNAME for it is added. This ensures that when the CNAME is added, it cannot conflict with the long\-standing rule in RFC 1034 that a name must not exist as any other record type if it exists as a CNAME. (The rule has been updated for DNSSEC in RFC 2535 to allow CNAMEs to have RRSIG, DNSKEY and NSEC records.) .SH "FILES" .PP \fB/etc/resolv.conf\fR .RS 4 used to identify default name server .RE .PP \fB/var/run/named/session.key\fR .RS 4 sets the default TSIG key for use in local\-only mode .RE .PP \fBK{name}.+157.+{random}.key\fR .RS 4 base\-64 encoding of HMAC\-MD5 key created by \fBdnssec\-keygen\fR(8). .RE .PP \fBK{name}.+157.+{random}.private\fR .RS 4 base\-64 encoding of HMAC\-MD5 key created by \fBdnssec\-keygen\fR(8). .RE .SH "SEE ALSO" .PP RFC 2136, RFC 3007, RFC 2104, RFC 2845, RFC 1034, RFC 2535, RFC 2931, \fBnamed\fR(8), \fBddns\-confgen\fR(8), \fBdnssec\-keygen\fR(8). .SH "BUGS" .PP The TSIG key is redundantly stored in two separate files. This is a consequence of nsupdate using the DST library for its cryptographic operations, and may change in future releases. .SH "COPYRIGHT" Copyright \(co 2004\-2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000\-2003 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/bin/rndc/0002755000470500017500000000000012672612753015101 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/rndc/rndc.html0000644000470500017500000007341512664710322016715 0ustar lamontlamont rndc

Name

rndc — name server control utility

Synopsis

rndc [-b source-address] [-c config-file] [-k key-file] [-s server] [-p port] [-q] [-V] [-y key_id] {command}

DESCRIPTION

rndc controls the operation of a name server. It supersedes the ndc utility that was provided in old BIND releases. If rndc is invoked with no command line options or arguments, it prints a short summary of the supported commands and the available options and their arguments.

rndc communicates with the name server over a TCP connection, sending commands authenticated with digital signatures. In the current versions of rndc and named, the only supported authentication algorithms are HMAC-MD5 (for compatibility), HMAC-SHA1, HMAC-SHA224, HMAC-SHA256 (default), HMAC-SHA384 and HMAC-SHA512. They use a shared secret on each end of the connection. This provides TSIG-style authentication for the command request and the name server's response. All commands sent over the channel must be signed by a key_id known to the server.

rndc reads a configuration file to determine how to contact the name server and decide what algorithm and key it should use.

OPTIONS

-b source-address

Use source-address as the source address for the connection to the server. Multiple instances are permitted to allow setting of both the IPv4 and IPv6 source addresses.

-c config-file

Use config-file as the configuration file instead of the default, /etc/rndc.conf.

-k key-file

Use key-file as the key file instead of the default, /etc/rndc.key. The key in /etc/rndc.key will be used to authenticate commands sent to the server if the config-file does not exist.

-s server

server is the name or address of the server which matches a server statement in the configuration file for rndc. If no server is supplied on the command line, the host named by the default-server clause in the options statement of the rndc configuration file will be used.

-p port

Send commands to TCP port port instead of BIND 9's default control channel port, 953.

-q

Quiet mode: Message text returned by the server will not be printed except when there is an error.

-V

Enable verbose logging.

-y key_id

Use the key key_id from the configuration file. key_id must be known by named with the same algorithm and secret string in order for control message validation to succeed. If no key_id is specified, rndc will first look for a key clause in the server statement of the server being used, or if no server statement is present for that host, then the default-key clause of the options statement. Note that the configuration file contains shared secrets which are used to send authenticated control commands to name servers. It should therefore not have general read or write access.

COMMANDS

A list of commands supported by rndc can be seen by running rndc without arguments.

Currently supported commands are:

addzone zone [class [view]] configuration

Add a zone while the server is running. This command requires the allow-new-zones option to be set to yes. The configuration string specified on the command line is the zone configuration text that would ordinarily be placed in named.conf.

The configuration is saved in a file called hash.nzf, where hash is a cryptographic hash generated from the name of the view. When named is restarted, the file will be loaded into the view configuration, so that zones that were added can persist after a restart.

This sample addzone command would add the zone example.com to the default view:

$ rndc addzone example.com '{ type master; file "example.com.db"; };'

(Note the brackets and semi-colon around the zone configuration text.)

See also rndc delzone and rndc modzone.

delzone [-clean] zone [class [view]]

Delete a zone while the server is running. Only zones that were originally added via rndc addzone can be deleted in this manner.

If the -clean is specified, the zone's master file (and journal file, if any) will be deleted along with the zone. Without the -clean option, zone files must be cleaned up by hand. (If the zone is of type "slave" or "stub", the files needing to be cleaned up will be reported in the output of the rndc delzone command.)

See also rndc addzone and rndc modzone.

dumpdb [-all|-cache|-zone|-adb|-bad] [view ...]

Dump the server's caches (default) and/or zones to the dump file for the specified views. If no view is specified, all views are dumped. (See the dump-file option in the BIND 9 Administrator Reference Manual.)

flush

Flushes the server's cache.

flushname name [view]

Flushes the given name from the server's DNS cache and, if applicable, from the server's nameserver address database or bad-server cache.

flushtree name [view]

Flushes the given name, and all of its subdomains, from the server's DNS cache, the address database, and the bad server cache.

freeze [zone [class [view]]]

Suspend updates to a dynamic zone. If no zone is specified, then all zones are suspended. This allows manual edits to be made to a zone normally updated by dynamic update. It also causes changes in the journal file to be synced into the master file. All dynamic update attempts will be refused while the zone is frozen.

See also rndc thaw.

halt [-p]

Stop the server immediately. Recent changes made through dynamic update or IXFR are not saved to the master files, but will be rolled forward from the journal files when the server is restarted. If -p is specified named's process id is returned. This allows an external process to determine when named had completed halting.

See also rndc stop.

loadkeys zone [class [view]]

Fetch all DNSSEC keys for the given zone from the key directory. If they are within their publication period, merge them into the zone's DNSKEY RRset. Unlike rndc sign, however, the zone is not immediately re-signed by the new keys, but is allowed to incrementally re-sign over time.

This command requires that the auto-dnssec zone option be set to maintain, and also requires the zone to be configured to allow dynamic DNS. (See "Dynamic Update Policies" in the Administrator Reference Manual for more details.)

See also rndc loadkeys.

notify zone [class [view]]

Resend NOTIFY messages for the zone.

notrace

Sets the server's debugging level to 0.

See also rndc trace.

querylog [on|off]

Enable or disable query logging. (For backward compatibility, this command can also be used without an argument to toggle query logging on and off.)

Query logging can also be enabled by explicitly directing the queries category to a channel in the logging section of named.conf or by specifying querylog yes; in the options section of named.conf.

reconfig

Reload the configuration file and load new zones, but do not reload existing zone files even if they have changed. This is faster than a full reload when there is a large number of zones because it avoids the need to examine the modification times of the zones files.

recursing

Dump the list of queries named is currently recursing on, and the list of domains to which iterative queries are currently being sent. (The second list includes the number of fetches currently active for the given domain, and how many have been passed or dropped because of the fetches-per-zone option.)

refresh zone [class [view]]

Schedule zone maintenance for the given zone.

reload

Reload configuration file and zones.

reload zone [class [view]]

Reload the given zone.

retransfer zone [class [view]]

Retransfer the given slave zone from the master server.

If the zone is configured to use inline-signing, the signed version of the zone is discarded; after the retransfer of the unsigned version is complete, the signed version will be regenerated with all new signatures.

scan

Scan the list of available network interfaces for changes, without performing a full reconfig or waiting for the interface-interval timer.

secroots [view ...]

Dump the server's security roots to the secroots file for the specified views. If no view is specified, security roots for all views are dumped.

sign zone [class [view]]

Fetch all DNSSEC keys for the given zone from the key directory (see the key-directory option in the BIND 9 Administrator Reference Manual). If they are within their publication period, merge them into the zone's DNSKEY RRset. If the DNSKEY RRset is changed, then the zone is automatically re-signed with the new key set.

This command requires that the auto-dnssec zone option be set to allow or maintain, and also requires the zone to be configured to allow dynamic DNS. (See "Dynamic Update Policies" in the Administrator Reference Manual for more details.)

See also rndc loadkeys.

signing [( -list | -clear keyid/algorithm | -clear all | -nsec3param ( parameters | none ) ) ] zone [class [view]]

List, edit, or remove the DNSSEC signing state records for the specified zone. The status of ongoing DNSSEC operations (such as signing or generating NSEC3 chains) is stored in the zone in the form of DNS resource records of type sig-signing-type. rndc signing -list converts these records into a human-readable form, indicating which keys are currently signing or have finished signing the zone, and which NSEC3 chains are being created or removed.

rndc signing -clear can remove a single key (specified in the same format that rndc signing -list uses to display it), or all keys. In either case, only completed keys are removed; any record indicating that a key has not yet finished signing the zone will be retained.

rndc signing -nsec3param sets the NSEC3 parameters for a zone. This is the only supported mechanism for using NSEC3 with inline-signing zones. Parameters are specified in the same format as an NSEC3PARAM resource record: hash algorithm, flags, iterations, and salt, in that order.

Currently, the only defined value for hash algorithm is 1, representing SHA-1. The flags may be set to 0 or 1, depending on whether you wish to set the opt-out bit in the NSEC3 chain. iterations defines the number of additional times to apply the algorithm when generating an NSEC3 hash. The salt is a string of data expressed in hexadecimal, a hyphen (`-') if no salt is to be used, or the keyword auto, which causes named to generate a random 64-bit salt.

So, for example, to create an NSEC3 chain using the SHA-1 hash algorithm, no opt-out flag, 10 iterations, and a salt value of "FFFF", use: rndc signing -nsec3param 1 0 10 FFFF zone. To set the opt-out flag, 15 iterations, and no salt, use: rndc signing -nsec3param 1 1 15 - zone.

rndc signing -nsec3param none removes an existing NSEC3 chain and replaces it with NSEC.

stats

Write server statistics to the statistics file. (See the statistics-file option in the BIND 9 Administrator Reference Manual.)

status

Display status of the server. Note that the number of zones includes the internal bind/CH zone and the default ./IN hint zone if there is not an explicit root zone configured.

stop [-p]

Stop the server, making sure any recent changes made through dynamic update or IXFR are first saved to the master files of the updated zones. If -p is specified named's process id is returned. This allows an external process to determine when named had completed stopping.

See also rndc halt.

sync [-clean] [zone [class [view]]]

Sync changes in the journal file for a dynamic zone to the master file. If the "-clean" option is specified, the journal file is also removed. If no zone is specified, then all zones are synced.

thaw [zone [class [view]]]

Enable updates to a frozen dynamic zone. If no zone is specified, then all frozen zones are enabled. This causes the server to reload the zone from disk, and re-enables dynamic updates after the load has completed. After a zone is thawed, dynamic updates will no longer be refused. If the zone has changed and the ixfr-from-differences option is in use, then the journal file will be updated to reflect changes in the zone. Otherwise, if the zone has changed, any existing journal file will be removed.

See also rndc freeze.

trace

Increment the servers debugging level by one.

trace level

Sets the server's debugging level to an explicit value.

See also rndc notrace.

tsig-delete keyname [view]

Delete a given TKEY-negotiated key from the server. (This does not apply to statically configured TSIG keys.)

tsig-list

List the names of all TSIG keys currently configured for use by named in each view. The list both statically configured keys and dynamic TKEY-negotiated keys.

validation ( on | off | check ) [view ...]

Enable, disable, or check the current status of DNSSEC validation. Note dnssec-enable also needs to be set to yes or auto to be effective. It defaults to enabled.

zonestatus zone [class [view]]

Displays the current status of the given zone, including the master file name and any include files from which it was loaded, when it was most recently loaded, the current serial number, the number of nodes, whether the zone supports dynamic updates, whether the zone is DNSSEC signed, whether it uses automatic DNSSEC key management or inline signing, and the scheduled refresh or expiry times for the zone.

LIMITATIONS

There is currently no way to provide the shared secret for a key_id without using the configuration file.

Several error messages could be clearer.

SEE ALSO

rndc.conf(5), rndc-confgen(8), named(8), named.conf(5), ndc(8), BIND 9 Administrator Reference Manual.

AUTHOR

Internet Systems Consortium

bind9-9.10.3.dfsg.P4/bin/rndc/rndc.conf.docbook0000644000470500017500000002221312664710322020303 0ustar lamontlamont]> March 14, 2013 rndc.conf 5 BIND9 rndc.conf rndc configuration file 2004 2005 2007 2013 2014 Internet Systems Consortium, Inc. ("ISC") 2000 2001 Internet Software Consortium. rndc.conf DESCRIPTION rndc.conf is the configuration file for rndc, the BIND 9 name server control utility. This file has a similar structure and syntax to named.conf. Statements are enclosed in braces and terminated with a semi-colon. Clauses in the statements are also semi-colon terminated. The usual comment styles are supported: C style: /* */ C++ style: // to end of line Unix style: # to end of line rndc.conf is much simpler than named.conf. The file uses three statements: an options statement, a server statement and a key statement. The statement contains five clauses. The clause is followed by the name or address of a name server. This host will be used when no name server is given as an argument to rndc. The clause is followed by the name of a key which is identified by a statement. If no is provided on the rndc command line, and no clause is found in a matching statement, this default key will be used to authenticate the server's commands and responses. The clause is followed by the port to connect to on the remote name server. If no option is provided on the rndc command line, and no clause is found in a matching statement, this default port will be used to connect. The and clauses which can be used to set the IPv4 and IPv6 source addresses respectively. After the keyword, the server statement includes a string which is the hostname or address for a name server. The statement has three possible clauses: , and . The key name must match the name of a key statement in the file. The port number specifies the port to connect to. If an clause is supplied these addresses will be used instead of the server name. Each address can take an optional port. If an or of supplied then these will be used to specify the IPv4 and IPv6 source addresses respectively. The statement begins with an identifying string, the name of the key. The statement has two clauses. identifies the authentication algorithm for rndc to use; currently only HMAC-MD5 (for compatibility), HMAC-SHA1, HMAC-SHA224, HMAC-SHA256 (default), HMAC-SHA384 and HMAC-SHA512 are supported. This is followed by a secret clause which contains the base-64 encoding of the algorithm's authentication key. The base-64 string is enclosed in double quotes. There are two common ways to generate the base-64 string for the secret. The BIND 9 program rndc-confgen can be used to generate a random key, or the mmencode program, also known as mimencode, can be used to generate a base-64 string from known input. mmencode does not ship with BIND 9 but is available on many systems. See the EXAMPLE section for sample command lines for each. EXAMPLE options { default-server localhost; default-key samplekey; }; server localhost { key samplekey; }; server testserver { key testkey; addresses { localhost port 5353; }; }; key samplekey { algorithm hmac-sha256; secret "6FMfj43Osz4lyb24OIe2iGEz9lf1llJO+lz"; }; key testkey { algorithm hmac-sha256; secret "R3HI8P6BKw9ZwXwN3VZKuQ=="; }; In the above example, rndc will by default use the server at localhost (127.0.0.1) and the key called samplekey. Commands to the localhost server will use the samplekey key, which must also be defined in the server's configuration file with the same name and secret. The key statement indicates that samplekey uses the HMAC-SHA256 algorithm and its secret clause contains the base-64 encoding of the HMAC-SHA256 secret enclosed in double quotes. If rndc -s testserver is used then rndc will connect to server on localhost port 5353 using the key testkey. To generate a random secret with rndc-confgen: rndc-confgen A complete rndc.conf file, including the randomly generated key, will be written to the standard output. Commented-out and statements for named.conf are also printed. To generate a base-64 secret with mmencode: echo "known plaintext for a secret" | mmencode NAME SERVER CONFIGURATION The name server must be configured to accept rndc connections and to recognize the key specified in the rndc.conf file, using the controls statement in named.conf. See the sections on the statement in the BIND 9 Administrator Reference Manual for details. SEE ALSO rndc8 , rndc-confgen8 , mmencode1 , BIND 9 Administrator Reference Manual. AUTHOR Internet Systems Consortium bind9-9.10.3.dfsg.P4/bin/rndc/rndc.conf.50000644000470500017500000001507212664710322017034 0ustar lamontlamont.\" Copyright (C) 2004, 2005, 2007, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: \fIrndc.conf\fR .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: March 14, 2013 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "\fIRNDC.CONF\fR" "5" "March 14, 2013" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" rndc.conf \- rndc configuration file .SH "SYNOPSIS" .HP 10 \fBrndc.conf\fR .SH "DESCRIPTION" .PP \fIrndc.conf\fR is the configuration file for \fBrndc\fR, the BIND 9 name server control utility. This file has a similar structure and syntax to \fInamed.conf\fR. Statements are enclosed in braces and terminated with a semi\-colon. Clauses in the statements are also semi\-colon terminated. The usual comment styles are supported: .PP C style: /* */ .PP C++ style: // to end of line .PP Unix style: # to end of line .PP \fIrndc.conf\fR is much simpler than \fInamed.conf\fR. The file uses three statements: an options statement, a server statement and a key statement. .PP The \fBoptions\fR statement contains five clauses. The \fBdefault\-server\fR clause is followed by the name or address of a name server. This host will be used when no name server is given as an argument to \fBrndc\fR. The \fBdefault\-key\fR clause is followed by the name of a key which is identified by a \fBkey\fR statement. If no \fBkeyid\fR is provided on the rndc command line, and no \fBkey\fR clause is found in a matching \fBserver\fR statement, this default key will be used to authenticate the server's commands and responses. The \fBdefault\-port\fR clause is followed by the port to connect to on the remote name server. If no \fBport\fR option is provided on the rndc command line, and no \fBport\fR clause is found in a matching \fBserver\fR statement, this default port will be used to connect. The \fBdefault\-source\-address\fR and \fBdefault\-source\-address\-v6\fR clauses which can be used to set the IPv4 and IPv6 source addresses respectively. .PP After the \fBserver\fR keyword, the server statement includes a string which is the hostname or address for a name server. The statement has three possible clauses: \fBkey\fR, \fBport\fR and \fBaddresses\fR. The key name must match the name of a key statement in the file. The port number specifies the port to connect to. If an \fBaddresses\fR clause is supplied these addresses will be used instead of the server name. Each address can take an optional port. If an \fBsource\-address\fR or \fBsource\-address\-v6\fR of supplied then these will be used to specify the IPv4 and IPv6 source addresses respectively. .PP The \fBkey\fR statement begins with an identifying string, the name of the key. The statement has two clauses. \fBalgorithm\fR identifies the authentication algorithm for \fBrndc\fR to use; currently only HMAC\-MD5 (for compatibility), HMAC\-SHA1, HMAC\-SHA224, HMAC\-SHA256 (default), HMAC\-SHA384 and HMAC\-SHA512 are supported. This is followed by a secret clause which contains the base\-64 encoding of the algorithm's authentication key. The base\-64 string is enclosed in double quotes. .PP There are two common ways to generate the base\-64 string for the secret. The BIND 9 program \fBrndc\-confgen\fR can be used to generate a random key, or the \fBmmencode\fR program, also known as \fBmimencode\fR, can be used to generate a base\-64 string from known input. \fBmmencode\fR does not ship with BIND 9 but is available on many systems. See the EXAMPLE section for sample command lines for each. .SH "EXAMPLE" .PP .RS 4 .nf options { default\-server localhost; default\-key samplekey; }; .fi .RE .sp .PP .RS 4 .nf server localhost { key samplekey; }; .fi .RE .sp .PP .RS 4 .nf server testserver { key testkey; addresses { localhost port 5353; }; }; .fi .RE .sp .PP .RS 4 .nf key samplekey { algorithm hmac\-sha256; secret "6FMfj43Osz4lyb24OIe2iGEz9lf1llJO+lz"; }; .fi .RE .sp .PP .RS 4 .nf key testkey { algorithm hmac\-sha256; secret "R3HI8P6BKw9ZwXwN3VZKuQ=="; }; .fi .RE .sp .PP In the above example, \fBrndc\fR will by default use the server at localhost (127.0.0.1) and the key called samplekey. Commands to the localhost server will use the samplekey key, which must also be defined in the server's configuration file with the same name and secret. The key statement indicates that samplekey uses the HMAC\-SHA256 algorithm and its secret clause contains the base\-64 encoding of the HMAC\-SHA256 secret enclosed in double quotes. .PP If \fBrndc \-s testserver\fR is used then \fBrndc\fR will connect to server on localhost port 5353 using the key testkey. .PP To generate a random secret with \fBrndc\-confgen\fR: .PP \fBrndc\-confgen\fR .PP A complete \fIrndc.conf\fR file, including the randomly generated key, will be written to the standard output. Commented\-out \fBkey\fR and \fBcontrols\fR statements for \fInamed.conf\fR are also printed. .PP To generate a base\-64 secret with \fBmmencode\fR: .PP \fBecho "known plaintext for a secret" | mmencode\fR .SH "NAME SERVER CONFIGURATION" .PP The name server must be configured to accept rndc connections and to recognize the key specified in the \fIrndc.conf\fR file, using the controls statement in \fInamed.conf\fR. See the sections on the \fBcontrols\fR statement in the BIND 9 Administrator Reference Manual for details. .SH "SEE ALSO" .PP \fBrndc\fR(8), \fBrndc\-confgen\fR(8), \fBmmencode\fR(1), BIND 9 Administrator Reference Manual. .SH "AUTHOR" .PP Internet Systems Consortium .SH "COPYRIGHT" Copyright \(co 2004, 2005, 2007, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000, 2001 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/bin/rndc/Makefile.in0000644000470500017500000000560712664710322017144 0ustar lamontlamont# Copyright (C) 2004, 2007, 2009, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000-2002 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.49 2009/12/05 23:31:40 each Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ @BIND9_MAKE_INCLUDES@ CINCLUDES = -I${srcdir}/include ${ISC_INCLUDES} ${ISCCC_INCLUDES} \ ${ISCCFG_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES} CDEFINES = CWARNINGS = ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@ ISCCCLIBS = ../../lib/isccc/libisccc.@A@ ISCLIBS = ../../lib/isc/libisc.@A@ ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@ DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ BIND9LIBS = ../../lib/bind9/libbind9.@A@ ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@ ISCCCDEPLIBS = ../../lib/isccc/libisccc.@A@ ISCDEPLIBS = ../../lib/isc/libisc.@A@ DNSDEPLIBS = ../../lib/dns/libdns.@A@ BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@ LIBS = ${ISCLIBS} @LIBS@ NOSYMLIBS = ${ISCNOSYMLIBS} @LIBS@ RNDCDEPLIBS = ${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${BIND9DEPLIBS} ${DNSDEPLIBS} ${ISCDEPLIBS} CONFDEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS} SRCS= rndc.c TARGETS = rndc@EXEEXT@ MANPAGES = rndc.8 rndc.conf.5 HTMLPAGES = rndc.html rndc.conf.html MANOBJS = ${MANPAGES} ${HTMLPAGES} @BIND9_MAKE_RULES@ rndc.@O@: rndc.c ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ -DVERSION=\"${VERSION}\" \ -DRNDC_CONFFILE=\"${sysconfdir}/rndc.conf\" \ -DRNDC_KEYFILE=\"${sysconfdir}/rndc.key\" \ -c ${srcdir}/rndc.c rndc@EXEEXT@: rndc.@O@ util.@O@ ${RNDCDEPLIBS} export BASEOBJS="rndc.@O@ util.@O@"; \ export LIBS0="${ISCCFGLIBS} ${ISCCCLIBS} ${BIND9LIBS} ${DNSLIBS}"; \ ${FINALBUILDCMD} doc man:: ${MANOBJS} docclean manclean maintainer-clean:: rm -f ${MANOBJS} installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man5 install:: rndc@EXEEXT@ installdirs ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} rndc@EXEEXT@ ${DESTDIR}${sbindir} ${INSTALL_DATA} ${srcdir}/rndc.8 ${DESTDIR}${mandir}/man8 ${INSTALL_DATA} ${srcdir}/rndc.conf.5 ${DESTDIR}${mandir}/man5 clean distclean maintainer-clean:: rm -f ${TARGETS} bind9-9.10.3.dfsg.P4/bin/rndc/rndc.docbook0000644000470500017500000007051412664710322017366 0ustar lamontlamont]> August 15, 2014 rndc 8 BIND9 rndc name server control utility 2004 2005 2007 2013 2014 2015 Internet Systems Consortium, Inc. ("ISC") 2000 2001 Internet Software Consortium. rndc command DESCRIPTION rndc controls the operation of a name server. It supersedes the ndc utility that was provided in old BIND releases. If rndc is invoked with no command line options or arguments, it prints a short summary of the supported commands and the available options and their arguments. rndc communicates with the name server over a TCP connection, sending commands authenticated with digital signatures. In the current versions of rndc and named, the only supported authentication algorithms are HMAC-MD5 (for compatibility), HMAC-SHA1, HMAC-SHA224, HMAC-SHA256 (default), HMAC-SHA384 and HMAC-SHA512. They use a shared secret on each end of the connection. This provides TSIG-style authentication for the command request and the name server's response. All commands sent over the channel must be signed by a key_id known to the server. rndc reads a configuration file to determine how to contact the name server and decide what algorithm and key it should use. OPTIONS -b source-address Use source-address as the source address for the connection to the server. Multiple instances are permitted to allow setting of both the IPv4 and IPv6 source addresses. -c config-file Use config-file as the configuration file instead of the default, /etc/rndc.conf. -k key-file Use key-file as the key file instead of the default, /etc/rndc.key. The key in /etc/rndc.key will be used to authenticate commands sent to the server if the config-file does not exist. -s server server is the name or address of the server which matches a server statement in the configuration file for rndc. If no server is supplied on the command line, the host named by the default-server clause in the options statement of the rndc configuration file will be used. -p port Send commands to TCP port port instead of BIND 9's default control channel port, 953. -q Quiet mode: Message text returned by the server will not be printed except when there is an error. -V Enable verbose logging. -y key_id Use the key key_id from the configuration file. key_id must be known by named with the same algorithm and secret string in order for control message validation to succeed. If no key_id is specified, rndc will first look for a key clause in the server statement of the server being used, or if no server statement is present for that host, then the default-key clause of the options statement. Note that the configuration file contains shared secrets which are used to send authenticated control commands to name servers. It should therefore not have general read or write access. COMMANDS A list of commands supported by rndc can be seen by running rndc without arguments. Currently supported commands are: addzone zone class view configuration Add a zone while the server is running. This command requires the allow-new-zones option to be set to yes. The configuration string specified on the command line is the zone configuration text that would ordinarily be placed in named.conf. The configuration is saved in a file called hash.nzf, where hash is a cryptographic hash generated from the name of the view. When named is restarted, the file will be loaded into the view configuration, so that zones that were added can persist after a restart. This sample addzone command would add the zone example.com to the default view: $ rndc addzone example.com '{ type master; file "example.com.db"; };' (Note the brackets and semi-colon around the zone configuration text.) See also rndc delzone and rndc modzone. delzone -clean zone class view Delete a zone while the server is running. Only zones that were originally added via rndc addzone can be deleted in this manner. If the is specified, the zone's master file (and journal file, if any) will be deleted along with the zone. Without the option, zone files must be cleaned up by hand. (If the zone is of type "slave" or "stub", the files needing to be cleaned up will be reported in the output of the rndc delzone command.) See also rndc addzone and rndc modzone. dumpdb -all|-cache|-zone|-adb|-bad view ... Dump the server's caches (default) and/or zones to the dump file for the specified views. If no view is specified, all views are dumped. (See the dump-file option in the BIND 9 Administrator Reference Manual.) flush Flushes the server's cache. flushname name view Flushes the given name from the server's DNS cache and, if applicable, from the server's nameserver address database or bad-server cache. flushtree name view Flushes the given name, and all of its subdomains, from the server's DNS cache, the address database, and the bad server cache. freeze zone class view Suspend updates to a dynamic zone. If no zone is specified, then all zones are suspended. This allows manual edits to be made to a zone normally updated by dynamic update. It also causes changes in the journal file to be synced into the master file. All dynamic update attempts will be refused while the zone is frozen. See also rndc thaw. halt -p Stop the server immediately. Recent changes made through dynamic update or IXFR are not saved to the master files, but will be rolled forward from the journal files when the server is restarted. If is specified named's process id is returned. This allows an external process to determine when named had completed halting. See also rndc stop. loadkeys zone class view Fetch all DNSSEC keys for the given zone from the key directory. If they are within their publication period, merge them into the zone's DNSKEY RRset. Unlike rndc sign, however, the zone is not immediately re-signed by the new keys, but is allowed to incrementally re-sign over time. This command requires that the auto-dnssec zone option be set to maintain, and also requires the zone to be configured to allow dynamic DNS. (See "Dynamic Update Policies" in the Administrator Reference Manual for more details.) See also rndc loadkeys. notify zone class view Resend NOTIFY messages for the zone. notrace Sets the server's debugging level to 0. See also rndc trace. querylog on|off Enable or disable query logging. (For backward compatibility, this command can also be used without an argument to toggle query logging on and off.) Query logging can also be enabled by explicitly directing the queries category to a channel in the logging section of named.conf or by specifying querylog yes; in the options section of named.conf. reconfig Reload the configuration file and load new zones, but do not reload existing zone files even if they have changed. This is faster than a full reload when there is a large number of zones because it avoids the need to examine the modification times of the zones files. recursing Dump the list of queries named is currently recursing on, and the list of domains to which iterative queries are currently being sent. (The second list includes the number of fetches currently active for the given domain, and how many have been passed or dropped because of the option.) refresh zone class view Schedule zone maintenance for the given zone. reload Reload configuration file and zones. reload zone class view Reload the given zone. retransfer zone class view Retransfer the given slave zone from the master server. If the zone is configured to use inline-signing, the signed version of the zone is discarded; after the retransfer of the unsigned version is complete, the signed version will be regenerated with all new signatures. scan Scan the list of available network interfaces for changes, without performing a full reconfig or waiting for the interface-interval timer. secroots view ... Dump the server's security roots to the secroots file for the specified views. If no view is specified, security roots for all views are dumped. sign zone class view Fetch all DNSSEC keys for the given zone from the key directory (see the key-directory option in the BIND 9 Administrator Reference Manual). If they are within their publication period, merge them into the zone's DNSKEY RRset. If the DNSKEY RRset is changed, then the zone is automatically re-signed with the new key set. This command requires that the auto-dnssec zone option be set to allow or maintain, and also requires the zone to be configured to allow dynamic DNS. (See "Dynamic Update Policies" in the Administrator Reference Manual for more details.) See also rndc loadkeys. signing ( -list | -clear keyid/algorithm | -clear all | -nsec3param ( parameters | none ) ) zone class view List, edit, or remove the DNSSEC signing state records for the specified zone. The status of ongoing DNSSEC operations (such as signing or generating NSEC3 chains) is stored in the zone in the form of DNS resource records of type sig-signing-type. rndc signing -list converts these records into a human-readable form, indicating which keys are currently signing or have finished signing the zone, and which NSEC3 chains are being created or removed. rndc signing -clear can remove a single key (specified in the same format that rndc signing -list uses to display it), or all keys. In either case, only completed keys are removed; any record indicating that a key has not yet finished signing the zone will be retained. rndc signing -nsec3param sets the NSEC3 parameters for a zone. This is the only supported mechanism for using NSEC3 with inline-signing zones. Parameters are specified in the same format as an NSEC3PARAM resource record: hash algorithm, flags, iterations, and salt, in that order. Currently, the only defined value for hash algorithm is 1, representing SHA-1. The may be set to 0 or 1, depending on whether you wish to set the opt-out bit in the NSEC3 chain. defines the number of additional times to apply the algorithm when generating an NSEC3 hash. The is a string of data expressed in hexadecimal, a hyphen (`-') if no salt is to be used, or the keyword auto, which causes named to generate a random 64-bit salt. So, for example, to create an NSEC3 chain using the SHA-1 hash algorithm, no opt-out flag, 10 iterations, and a salt value of "FFFF", use: rndc signing -nsec3param 1 0 10 FFFF zone. To set the opt-out flag, 15 iterations, and no salt, use: rndc signing -nsec3param 1 1 15 - zone. rndc signing -nsec3param none removes an existing NSEC3 chain and replaces it with NSEC. stats Write server statistics to the statistics file. (See the statistics-file option in the BIND 9 Administrator Reference Manual.) status Display status of the server. Note that the number of zones includes the internal bind/CH zone and the default ./IN hint zone if there is not an explicit root zone configured. stop -p Stop the server, making sure any recent changes made through dynamic update or IXFR are first saved to the master files of the updated zones. If is specified named's process id is returned. This allows an external process to determine when named had completed stopping. See also rndc halt. sync -clean zone class view Sync changes in the journal file for a dynamic zone to the master file. If the "-clean" option is specified, the journal file is also removed. If no zone is specified, then all zones are synced. thaw zone class view Enable updates to a frozen dynamic zone. If no zone is specified, then all frozen zones are enabled. This causes the server to reload the zone from disk, and re-enables dynamic updates after the load has completed. After a zone is thawed, dynamic updates will no longer be refused. If the zone has changed and the ixfr-from-differences option is in use, then the journal file will be updated to reflect changes in the zone. Otherwise, if the zone has changed, any existing journal file will be removed. See also rndc freeze. trace Increment the servers debugging level by one. trace level Sets the server's debugging level to an explicit value. See also rndc notrace. tsig-delete keyname view Delete a given TKEY-negotiated key from the server. (This does not apply to statically configured TSIG keys.) tsig-list List the names of all TSIG keys currently configured for use by named in each view. The list both statically configured keys and dynamic TKEY-negotiated keys. validation ( on | off | check ) view ... Enable, disable, or check the current status of DNSSEC validation. Note dnssec-enable also needs to be set to yes or auto to be effective. It defaults to enabled. zonestatus zone class view Displays the current status of the given zone, including the master file name and any include files from which it was loaded, when it was most recently loaded, the current serial number, the number of nodes, whether the zone supports dynamic updates, whether the zone is DNSSEC signed, whether it uses automatic DNSSEC key management or inline signing, and the scheduled refresh or expiry times for the zone. LIMITATIONS There is currently no way to provide the shared secret for a without using the configuration file. Several error messages could be clearer. SEE ALSO rndc.conf5 , rndc-confgen8 , named8 , named.conf5 , ndc8 , BIND 9 Administrator Reference Manual. AUTHOR Internet Systems Consortium bind9-9.10.3.dfsg.P4/bin/rndc/rndc.80000644000470500017500000004144712664710322016120 0ustar lamontlamont.\" Copyright (C) 2004, 2005, 2007, 2013-2015 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: rndc .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: August 15, 2014 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "RNDC" "8" "August 15, 2014" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" rndc \- name server control utility .SH "SYNOPSIS" .HP 5 \fBrndc\fR [\fB\-b\ \fR\fB\fIsource\-address\fR\fR] [\fB\-c\ \fR\fB\fIconfig\-file\fR\fR] [\fB\-k\ \fR\fB\fIkey\-file\fR\fR] [\fB\-s\ \fR\fB\fIserver\fR\fR] [\fB\-p\ \fR\fB\fIport\fR\fR] [\fB\-q\fR] [\fB\-V\fR] [\fB\-y\ \fR\fB\fIkey_id\fR\fR] {command} .SH "DESCRIPTION" .PP \fBrndc\fR controls the operation of a name server. It supersedes the \fBndc\fR utility that was provided in old BIND releases. If \fBrndc\fR is invoked with no command line options or arguments, it prints a short summary of the supported commands and the available options and their arguments. .PP \fBrndc\fR communicates with the name server over a TCP connection, sending commands authenticated with digital signatures. In the current versions of \fBrndc\fR and \fBnamed\fR, the only supported authentication algorithms are HMAC\-MD5 (for compatibility), HMAC\-SHA1, HMAC\-SHA224, HMAC\-SHA256 (default), HMAC\-SHA384 and HMAC\-SHA512. They use a shared secret on each end of the connection. This provides TSIG\-style authentication for the command request and the name server's response. All commands sent over the channel must be signed by a key_id known to the server. .PP \fBrndc\fR reads a configuration file to determine how to contact the name server and decide what algorithm and key it should use. .SH "OPTIONS" .PP \-b \fIsource\-address\fR .RS 4 Use \fIsource\-address\fR as the source address for the connection to the server. Multiple instances are permitted to allow setting of both the IPv4 and IPv6 source addresses. .RE .PP \-c \fIconfig\-file\fR .RS 4 Use \fIconfig\-file\fR as the configuration file instead of the default, \fI/etc/rndc.conf\fR. .RE .PP \-k \fIkey\-file\fR .RS 4 Use \fIkey\-file\fR as the key file instead of the default, \fI/etc/rndc.key\fR. The key in \fI/etc/rndc.key\fR will be used to authenticate commands sent to the server if the \fIconfig\-file\fR does not exist. .RE .PP \-s \fIserver\fR .RS 4 \fIserver\fR is the name or address of the server which matches a server statement in the configuration file for \fBrndc\fR. If no server is supplied on the command line, the host named by the default\-server clause in the options statement of the \fBrndc\fR configuration file will be used. .RE .PP \-p \fIport\fR .RS 4 Send commands to TCP port \fIport\fR instead of BIND 9's default control channel port, 953. .RE .PP \-q .RS 4 Quiet mode: Message text returned by the server will not be printed except when there is an error. .RE .PP \-V .RS 4 Enable verbose logging. .RE .PP \-y \fIkey_id\fR .RS 4 Use the key \fIkey_id\fR from the configuration file. \fIkey_id\fR must be known by \fBnamed\fR with the same algorithm and secret string in order for control message validation to succeed. If no \fIkey_id\fR is specified, \fBrndc\fR will first look for a key clause in the server statement of the server being used, or if no server statement is present for that host, then the default\-key clause of the options statement. Note that the configuration file contains shared secrets which are used to send authenticated control commands to name servers. It should therefore not have general read or write access. .RE .SH "COMMANDS" .PP A list of commands supported by \fBrndc\fR can be seen by running \fBrndc\fR without arguments. .PP Currently supported commands are: .PP \fBaddzone \fR\fB\fIzone\fR\fR\fB \fR\fB[\fIclass\fR [\fIview\fR]]\fR\fB \fR\fB\fIconfiguration\fR\fR\fB \fR .RS 4 Add a zone while the server is running. This command requires the \fBallow\-new\-zones\fR option to be set to \fByes\fR. The \fIconfiguration\fR string specified on the command line is the zone configuration text that would ordinarily be placed in \fInamed.conf\fR. .sp The configuration is saved in a file called \fI\fIhash\fR\fR\fI.nzf\fR, where \fIhash\fR is a cryptographic hash generated from the name of the view. When \fBnamed\fR is restarted, the file will be loaded into the view configuration, so that zones that were added can persist after a restart. .sp This sample \fBaddzone\fR command would add the zone example.com to the default view: .sp $\fBrndc addzone example.com '{ type master; file "example.com.db"; };'\fR .sp (Note the brackets and semi\-colon around the zone configuration text.) .sp See also \fBrndc delzone\fR and \fBrndc modzone\fR. .RE .PP \fBdelzone \fR\fB[\-clean]\fR\fB \fR\fB\fIzone\fR\fR\fB \fR\fB[\fIclass\fR [\fIview\fR]]\fR\fB \fR .RS 4 Delete a zone while the server is running. Only zones that were originally added via \fBrndc addzone\fR can be deleted in this manner. .sp If the \fB\-clean\fR is specified, the zone's master file (and journal file, if any) will be deleted along with the zone. Without the \fB\-clean\fR option, zone files must be cleaned up by hand. (If the zone is of type "slave" or "stub", the files needing to be cleaned up will be reported in the output of the \fBrndc delzone\fR command.) .sp See also \fBrndc addzone\fR and \fBrndc modzone\fR. .RE .PP \fBdumpdb \fR\fB[\-all|\-cache|\-zone|\-adb|\-bad]\fR\fB \fR\fB[\fIview ...\fR]\fR .RS 4 Dump the server's caches (default) and/or zones to the dump file for the specified views. If no view is specified, all views are dumped. (See the \fBdump\-file\fR option in the BIND 9 Administrator Reference Manual.) .RE .PP \fBflush\fR .RS 4 Flushes the server's cache. .RE .PP \fBflushname\fR \fIname\fR [\fIview\fR] .RS 4 Flushes the given name from the server's DNS cache and, if applicable, from the server's nameserver address database or bad\-server cache. .RE .PP \fBflushtree\fR \fIname\fR [\fIview\fR] .RS 4 Flushes the given name, and all of its subdomains, from the server's DNS cache, the address database, and the bad server cache. .RE .PP \fBfreeze \fR\fB[\fIzone\fR [\fIclass\fR [\fIview\fR]]]\fR .RS 4 Suspend updates to a dynamic zone. If no zone is specified, then all zones are suspended. This allows manual edits to be made to a zone normally updated by dynamic update. It also causes changes in the journal file to be synced into the master file. All dynamic update attempts will be refused while the zone is frozen. .sp See also \fBrndc thaw\fR. .RE .PP \fBhalt \fR\fB[\-p]\fR .RS 4 Stop the server immediately. Recent changes made through dynamic update or IXFR are not saved to the master files, but will be rolled forward from the journal files when the server is restarted. If \fB\-p\fR is specified \fBnamed\fR's process id is returned. This allows an external process to determine when \fBnamed\fR had completed halting. .sp See also \fBrndc stop\fR. .RE .PP \fBloadkeys \fR\fB\fIzone\fR\fR\fB \fR\fB[\fIclass\fR [\fIview\fR]]\fR .RS 4 Fetch all DNSSEC keys for the given zone from the key directory. If they are within their publication period, merge them into the zone's DNSKEY RRset. Unlike \fBrndc sign\fR, however, the zone is not immediately re\-signed by the new keys, but is allowed to incrementally re\-sign over time. .sp This command requires that the \fBauto\-dnssec\fR zone option be set to maintain, and also requires the zone to be configured to allow dynamic DNS. (See "Dynamic Update Policies" in the Administrator Reference Manual for more details.) .sp See also \fBrndc loadkeys\fR. .RE .PP \fBnotify \fR\fB\fIzone\fR\fR\fB \fR\fB[\fIclass\fR [\fIview\fR]]\fR .RS 4 Resend NOTIFY messages for the zone. .RE .PP \fBnotrace\fR .RS 4 Sets the server's debugging level to 0. .sp See also \fBrndc trace\fR. .RE .PP \fBquerylog\fR [on|off] .RS 4 Enable or disable query logging. (For backward compatibility, this command can also be used without an argument to toggle query logging on and off.) .sp Query logging can also be enabled by explicitly directing the \fBqueries\fR \fBcategory\fR to a \fBchannel\fR in the \fBlogging\fR section of \fInamed.conf\fR or by specifying \fBquerylog yes;\fR in the \fBoptions\fR section of \fInamed.conf\fR. .RE .PP \fBreconfig\fR .RS 4 Reload the configuration file and load new zones, but do not reload existing zone files even if they have changed. This is faster than a full \fBreload\fR when there is a large number of zones because it avoids the need to examine the modification times of the zones files. .RE .PP \fBrecursing\fR .RS 4 Dump the list of queries \fBnamed\fR is currently recursing on, and the list of domains to which iterative queries are currently being sent. (The second list includes the number of fetches currently active for the given domain, and how many have been passed or dropped because of the \fBfetches\-per\-zone\fR option.) .RE .PP \fBrefresh \fR\fB\fIzone\fR\fR\fB \fR\fB[\fIclass\fR [\fIview\fR]]\fR .RS 4 Schedule zone maintenance for the given zone. .RE .PP \fBreload\fR .RS 4 Reload configuration file and zones. .RE .PP \fBreload \fR\fB\fIzone\fR\fR\fB \fR\fB[\fIclass\fR [\fIview\fR]]\fR .RS 4 Reload the given zone. .RE .PP \fBretransfer \fR\fB\fIzone\fR\fR\fB \fR\fB[\fIclass\fR [\fIview\fR]]\fR .RS 4 Retransfer the given slave zone from the master server. .sp If the zone is configured to use \fBinline\-signing\fR, the signed version of the zone is discarded; after the retransfer of the unsigned version is complete, the signed version will be regenerated with all new signatures. .RE .PP \fBscan\fR .RS 4 Scan the list of available network interfaces for changes, without performing a full \fBreconfig\fR or waiting for the \fBinterface\-interval\fR timer. .RE .PP \fBsecroots \fR\fB[\fIview ...\fR]\fR .RS 4 Dump the server's security roots to the secroots file for the specified views. If no view is specified, security roots for all views are dumped. .RE .PP \fBsign \fR\fB\fIzone\fR\fR\fB \fR\fB[\fIclass\fR [\fIview\fR]]\fR .RS 4 Fetch all DNSSEC keys for the given zone from the key directory (see the \fBkey\-directory\fR option in the BIND 9 Administrator Reference Manual). If they are within their publication period, merge them into the zone's DNSKEY RRset. If the DNSKEY RRset is changed, then the zone is automatically re\-signed with the new key set. .sp This command requires that the \fBauto\-dnssec\fR zone option be set to allow or maintain, and also requires the zone to be configured to allow dynamic DNS. (See "Dynamic Update Policies" in the Administrator Reference Manual for more details.) .sp See also \fBrndc loadkeys\fR. .RE .PP \fBsigning \fR\fB[( \-list | \-clear \fIkeyid/algorithm\fR | \-clear all | \-nsec3param ( \fIparameters\fR | none ) ) ]\fR\fB \fR\fB\fIzone\fR\fR\fB \fR\fB[\fIclass\fR [\fIview\fR]]\fR\fB \fR .RS 4 List, edit, or remove the DNSSEC signing state records for the specified zone. The status of ongoing DNSSEC operations (such as signing or generating NSEC3 chains) is stored in the zone in the form of DNS resource records of type \fBsig\-signing\-type\fR. \fBrndc signing \-list\fR converts these records into a human\-readable form, indicating which keys are currently signing or have finished signing the zone, and which NSEC3 chains are being created or removed. .sp \fBrndc signing \-clear\fR can remove a single key (specified in the same format that \fBrndc signing \-list\fR uses to display it), or all keys. In either case, only completed keys are removed; any record indicating that a key has not yet finished signing the zone will be retained. .sp \fBrndc signing \-nsec3param\fR sets the NSEC3 parameters for a zone. This is the only supported mechanism for using NSEC3 with \fBinline\-signing\fR zones. Parameters are specified in the same format as an NSEC3PARAM resource record: hash algorithm, flags, iterations, and salt, in that order. .sp Currently, the only defined value for hash algorithm is 1, representing SHA\-1. The \fBflags\fR may be set to 0 or 1, depending on whether you wish to set the opt\-out bit in the NSEC3 chain. \fBiterations\fR defines the number of additional times to apply the algorithm when generating an NSEC3 hash. The \fBsalt\fR is a string of data expressed in hexadecimal, a hyphen (`\-') if no salt is to be used, or the keyword auto, which causes \fBnamed\fR to generate a random 64\-bit salt. .sp So, for example, to create an NSEC3 chain using the SHA\-1 hash algorithm, no opt\-out flag, 10 iterations, and a salt value of "FFFF", use: \fBrndc signing \-nsec3param 1 0 10 FFFF \fR\fB\fIzone\fR\fR. To set the opt\-out flag, 15 iterations, and no salt, use: \fBrndc signing \-nsec3param 1 1 15 \- \fR\fB\fIzone\fR\fR. .sp \fBrndc signing \-nsec3param none\fR removes an existing NSEC3 chain and replaces it with NSEC. .RE .PP \fBstats\fR .RS 4 Write server statistics to the statistics file. (See the \fBstatistics\-file\fR option in the BIND 9 Administrator Reference Manual.) .RE .PP \fBstatus\fR .RS 4 Display status of the server. Note that the number of zones includes the internal \fBbind/CH\fR zone and the default \fB./IN\fR hint zone if there is not an explicit root zone configured. .RE .PP \fBstop \fR\fB[\-p]\fR .RS 4 Stop the server, making sure any recent changes made through dynamic update or IXFR are first saved to the master files of the updated zones. If \fB\-p\fR is specified \fBnamed\fR's process id is returned. This allows an external process to determine when \fBnamed\fR had completed stopping. .sp See also \fBrndc halt\fR. .RE .PP \fBsync \fR\fB[\-clean]\fR\fB \fR\fB[\fIzone\fR [\fIclass\fR [\fIview\fR]]]\fR .RS 4 Sync changes in the journal file for a dynamic zone to the master file. If the "\-clean" option is specified, the journal file is also removed. If no zone is specified, then all zones are synced. .RE .PP \fBthaw \fR\fB[\fIzone\fR [\fIclass\fR [\fIview\fR]]]\fR .RS 4 Enable updates to a frozen dynamic zone. If no zone is specified, then all frozen zones are enabled. This causes the server to reload the zone from disk, and re\-enables dynamic updates after the load has completed. After a zone is thawed, dynamic updates will no longer be refused. If the zone has changed and the \fBixfr\-from\-differences\fR option is in use, then the journal file will be updated to reflect changes in the zone. Otherwise, if the zone has changed, any existing journal file will be removed. .sp See also \fBrndc freeze\fR. .RE .PP \fBtrace\fR .RS 4 Increment the servers debugging level by one. .RE .PP \fBtrace \fR\fB\fIlevel\fR\fR .RS 4 Sets the server's debugging level to an explicit value. .sp See also \fBrndc notrace\fR. .RE .PP \fBtsig\-delete\fR \fIkeyname\fR [\fIview\fR] .RS 4 Delete a given TKEY\-negotiated key from the server. (This does not apply to statically configured TSIG keys.) .RE .PP \fBtsig\-list\fR .RS 4 List the names of all TSIG keys currently configured for use by \fBnamed\fR in each view. The list both statically configured keys and dynamic TKEY\-negotiated keys. .RE .PP \fBvalidation ( on | off | check ) \fR\fB[\fIview ...\fR]\fR\fB \fR .RS 4 Enable, disable, or check the current status of DNSSEC validation. Note \fBdnssec\-enable\fR also needs to be set to \fByes\fR or \fBauto\fR to be effective. It defaults to enabled. .RE .PP \fBzonestatus \fR\fB\fIzone\fR\fR\fB \fR\fB[\fIclass\fR [\fIview\fR]]\fR .RS 4 Displays the current status of the given zone, including the master file name and any include files from which it was loaded, when it was most recently loaded, the current serial number, the number of nodes, whether the zone supports dynamic updates, whether the zone is DNSSEC signed, whether it uses automatic DNSSEC key management or inline signing, and the scheduled refresh or expiry times for the zone. .RE .SH "LIMITATIONS" .PP There is currently no way to provide the shared secret for a \fBkey_id\fR without using the configuration file. .PP Several error messages could be clearer. .SH "SEE ALSO" .PP \fBrndc.conf\fR(5), \fBrndc\-confgen\fR(8), \fBnamed\fR(8), \fBnamed.conf\fR(5), \fBndc\fR(8), BIND 9 Administrator Reference Manual. .SH "AUTHOR" .PP Internet Systems Consortium .SH "COPYRIGHT" Copyright \(co 2004, 2005, 2007, 2013\-2015 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000, 2001 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/bin/rndc/include/0002755000470500017500000000000012672612753016524 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/rndc/include/rndc/0002755000470500017500000000000012664710322017442 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/rndc/include/rndc/os.h0000644000470500017500000000235512664710322020237 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: os.h,v 1.12 2009/06/10 00:27:21 each Exp $ */ /*! \file */ #ifndef RNDC_OS_H #define RNDC_OS_H 1 #include #include ISC_LANG_BEGINDECLS int set_user(FILE *fd, const char *user); /*%< * Set the owner of the file referenced by 'fd' to 'user'. * Returns: * 0 success * -1 insufficient permissions, or 'user' does not exist. */ ISC_LANG_ENDDECLS #endif bind9-9.10.3.dfsg.P4/bin/rndc/win32/0002755000470500017500000000000012664730167016044 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/rndc/win32/rndcutil.vcxproj.in0000644000470500017500000001262712664710322021707 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {7C8681A1-E3A8-470E-9EEF-16054D111A19} Win32Proj rndcutil StaticLibrary true MultiByte StaticLibrary false true MultiByte true .\$(Configuration)\ .\$(Configuration)\ util false .\$(Configuration)\ .\$(Configuration)\ util Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true .\;..\..\..\;..\include;..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) $(OutDir)$(TargetName)$(TargetExt) Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb .\;..\..\..\;..\include;..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) $(OutDir)$(TargetName)$(TargetExt) bind9-9.10.3.dfsg.P4/bin/rndc/win32/rndc.vcxproj.in0000644000470500017500000001560612664710322021011 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {39721F26-8B80-4AA9-9826-2AEF7322C3D5} Win32Proj rndc Application true MultiByte Application false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true .\;..\..\..\;@LIBXML2_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\isccc\include;..\..\..\lib\isccfg\include;..\..\..\lib\bind9\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);..\..\..\lib\isccfg\win32\$(Configuration);..\..\..\lib\isccc\win32\$(Configuration);..\..\..\lib\bind9\win32\$(Configuration);%(AdditionalLibraryDirectories) util.lib;libisc.lib;libdns.lib;libisccfg.lib;libisccc.lib;libbind9.lib;ws2_32.lib;%(AdditionalDependencies) Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb .\;..\..\..\;@LIBXML2_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\isccc\include;..\..\..\lib\isccfg\include;..\..\..\lib\bind9\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Default $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);..\..\..\lib\isccfg\win32\$(Configuration);..\..\..\lib\isccc\win32\$(Configuration);..\..\..\lib\bind9\win32\$(Configuration);%(AdditionalLibraryDirectories) util.lib;libisc.lib;libdns.lib;libisccfg.lib;libisccc.lib;libbind9.lib;ws2_32.lib;%(AdditionalDependencies) bind9-9.10.3.dfsg.P4/bin/rndc/win32/rndc.vcxproj.filters.in0000644000470500017500000000206512664710322022453 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Header Files Source Files bind9-9.10.3.dfsg.P4/bin/rndc/win32/rndc.dsp.in0000644000470500017500000001157412664710322020104 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="rndc" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 CFG=rndc - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "rndc.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "rndc.mak" CFG="rndc - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "rndc - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "rndc - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "rndc - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/isccc/include" /I "../../../lib/isccfg/include" /I "../../../lib/bind9/include" /I "../../../lib/dns/include" /D "WIN32" /D "NDEBUG" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @MACHINE@ # ADD LINK32 user32.lib advapi32.lib ws2_32.lib Release/util.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ../../../lib/isccfg/win32/Release/libisccfg.lib ../../../lib/isccc/win32/Release/libisccc.lib ../../../lib/bind9/win32/Release/libbind9.lib /nologo /subsystem:console /profile @MACHINE@ /out:"../../../Build/Release/rndc.exe" !ELSEIF "$(CFG)" == "rndc - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/isccc/include" /I "../../../lib/isccfg/include" /I "../../../lib/bind9/include" /I "../../../lib/dns/include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c # SUBTRACT CPP /X @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib ws2_32.lib Debug/util.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ../../../lib/isccfg/win32/Debug/libisccfg.lib ../../../lib/isccc/win32/Debug/libisccc.lib ../../../lib/bind9/win32/Debug/libbind9.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/rndc.exe" /pdbtype:sept !ENDIF # Begin Target # Name "rndc - @PLATFORM@ Release" # Name "rndc - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\rndc.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=..\util.h # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/bin/rndc/win32/rndcutil.dsw0000644000470500017500000000103512664710322020373 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "rndcutil"=".\rndcutil.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/bin/rndc/win32/rndcutil.vcxproj.user0000644000470500017500000000021712664710322022247 0ustar lamontlamont bind9-9.10.3.dfsg.P4/bin/rndc/win32/rndc.dsw0000644000470500017500000000102512664710322017474 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "rndc"=".\rndc.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/bin/rndc/win32/rndcutil.dsp.in0000644000470500017500000000756312664710322021005 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="rndcutil" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Static-Link Library" 0x0104 CFG=rndcutil - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "rndcutil.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "rndcutil.mak" CFG="rndcutil - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "rndcutil - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Static-Link Library") !MESSAGE "rndcutil - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Static-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "rndcutil - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" @COPTY@ /FD /c /Fdutil # SUBTRACT CPP /X # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 # ADD LINK32 /out:"Release/util.lib" LIB32=lib.exe # ADD BASE LIB32 # ADD LIB32 /out:"Release/util.lib" !ELSEIF "$(CFG)" == "rndcutil - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /FR @COPTY@ /FD /GZ /c /Fdutil # SUBTRACT CPP /X # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 # ADD LINK32 /debug /out:"Debug/util.lib" LIB32=lib.exe # ADD BASE LIB32 # ADD LIB32 /out:"Debug/util.lib" !ENDIF # Begin Target # Name "rndcutil - @PLATFORM@ Release" # Name "rndcutil - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # Begin Group "Main Dns Lib" # PROP Default_Filter "c" # Begin Source File SOURCE=..\util.c # End Source File # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/bin/rndc/win32/rndc.vcxproj.user0000644000470500017500000000021712664710322021351 0ustar lamontlamont bind9-9.10.3.dfsg.P4/bin/rndc/win32/rndcutil.vcxproj.filters.in0000644000470500017500000000206512664710322023351 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Header Files Source Files bind9-9.10.3.dfsg.P4/bin/rndc/win32/rndc.mak.in0000644000470500017500000003103212664710322020055 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on rndc.dsp !IF "$(CFG)" == "" CFG=rndc - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to rndc - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "rndc - @PLATFORM@ Release" && "$(CFG)" != "rndc - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "rndc.mak" CFG="rndc - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "rndc - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "rndc - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "rndc - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "rndc - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release !IF "$(RECURSE)" == "0" ALL : "..\..\..\Build\Release\rndc.exe" !ELSE ALL : "libbind9 - @PLATFORM@ Release" "libisccfg - @PLATFORM@ Release" "libisccc - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" "..\..\..\Build\Release\rndc.exe" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libisc - @PLATFORM@ ReleaseCLEAN" "libisccc - @PLATFORM@ ReleaseCLEAN" "libisccfg - @PLATFORM@ ReleaseCLEAN" "libbind9 - @PLATFORM@ ReleaseCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\rndc.obj" -@erase "$(INTDIR)\util.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "..\..\..\Build\Release\rndc.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/isccc/include" /I "../../../lib/isccfg/include" /I "../../../lib/bind9/include" /I "../../../lib/dns/include" /D "WIN32" /D "NDEBUG" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\rndc.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\rndc.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ../../../lib/isccfg/win32/Release/libisccfg.lib ../../../lib/isccc/win32/Release/libisccc.lib ../../../lib/bind9/win32/Release/libbind9.lib /nologo /subsystem:console /profile @MACHINE@ /out:"../../../Build/Release/rndc.exe" LINK32_OBJS= \ "$(INTDIR)\rndc.obj" \ "$(INTDIR)\util.obj" \ "..\..\..\lib\isc\win32\Release\libisc.lib" \ "..\..\..\lib\isccc\win32\Release\libisccc.lib" \ "..\..\..\lib\isccfg\win32\Release\libisccfg.lib" \ "..\..\..\lib\bind9\win32\Release\libbind9.lib" "..\..\..\Build\Release\rndc.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "rndc - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros !IF "$(RECURSE)" == "0" ALL : "..\..\..\Build\Debug\rndc.exe" "$(OUTDIR)\rndc.bsc" !ELSE ALL : "libbind9 - @PLATFORM@ Debug" "libisccfg - @PLATFORM@ Debug" "libisccc - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" "..\..\..\Build\Debug\rndc.exe" "$(OUTDIR)\rndc.bsc" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libisc - @PLATFORM@ DebugCLEAN" "libisccc - @PLATFORM@ DebugCLEAN" "libisccfg - @PLATFORM@ DebugCLEAN" "libbind9 - @PLATFORM@ DebugCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\rndc.obj" -@erase "$(INTDIR)\rndc.sbr" -@erase "$(INTDIR)\util.obj" -@erase "$(INTDIR)\util.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\rndc.bsc" -@erase "$(OUTDIR)\rndc.pdb" -@erase "..\..\..\Build\Debug\rndc.exe" -@erase "..\..\..\Build\Debug\rndc.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/isccc/include" /I "../../../lib/isccfg/include" /I "../../../lib/bind9/include" /I "../../../lib/dns/include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\rndc.bsc" BSC32_SBRS= \ "$(INTDIR)\rndc.sbr" \ "$(INTDIR)\util.sbr" "$(OUTDIR)\rndc.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ../../../lib/isccfg/win32/Debug/libisccfg.lib ../../../lib/isccc/win32/Debug/libisccc.lib ../../../lib/bind9/win32/Debug/libbind9.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\rndc.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/rndc.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\rndc.obj" \ "$(INTDIR)\util.obj" \ "..\..\..\lib\isc\win32\Debug\libisc.lib" \ "..\..\..\lib\isccc\win32\Debug\libisccc.lib" \ "..\..\..\lib\isccfg\win32\Debug\libisccfg.lib" \ "..\..\..\lib\bind9\win32\Debug\libbind9.lib" "..\..\..\Build\Debug\rndc.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("rndc.dep") !INCLUDE "rndc.dep" !ELSE !MESSAGE Warning: cannot find "rndc.dep" !ENDIF !ENDIF !IF "$(CFG)" == "rndc - @PLATFORM@ Release" || "$(CFG)" == "rndc - @PLATFORM@ Debug" SOURCE=..\rndc.c !IF "$(CFG)" == "rndc - @PLATFORM@ Release" "$(INTDIR)\rndc.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "rndc - @PLATFORM@ Debug" "$(INTDIR)\rndc.obj" "$(INTDIR)\rndc.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\util.c !IF "$(CFG)" == "rndc - @PLATFORM@ Release" "$(INTDIR)\util.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "rndc - @PLATFORM@ Debug" "$(INTDIR)\util.obj" "$(INTDIR)\util.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !IF "$(CFG)" == "rndc - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" : cd "..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" cd "..\..\..\bin\rndc\win32" "libisc - @PLATFORM@ ReleaseCLEAN" : cd "..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\..\bin\rndc\win32" !ELSEIF "$(CFG)" == "rndc - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" : cd "..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" cd "..\..\..\bin\rndc\win32" "libisc - @PLATFORM@ DebugCLEAN" : cd "..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\..\bin\rndc\win32" !ENDIF !IF "$(CFG)" == "rndc - @PLATFORM@ Release" "libisccc - @PLATFORM@ Release" : cd "..\..\..\lib\isccc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccc.mak" CFG="libisccc - @PLATFORM@ Release" cd "..\..\..\bin\rndc\win32" "libisccc - @PLATFORM@ ReleaseCLEAN" : cd "..\..\..\lib\isccc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccc.mak" CFG="libisccc - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\..\bin\rndc\win32" !ELSEIF "$(CFG)" == "rndc - @PLATFORM@ Debug" "libisccc - @PLATFORM@ Debug" : cd "..\..\..\lib\isccc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccc.mak" CFG="libisccc - @PLATFORM@ Debug" cd "..\..\..\bin\rndc\win32" "libisccc - @PLATFORM@ DebugCLEAN" : cd "..\..\..\lib\isccc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccc.mak" CFG="libisccc - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\..\bin\rndc\win32" !ENDIF !IF "$(CFG)" == "rndc - @PLATFORM@ Release" "libisccfg - @PLATFORM@ Release" : cd "..\..\..\lib\isccfg\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Release" cd "..\..\..\bin\rndc\win32" "libisccfg - @PLATFORM@ ReleaseCLEAN" : cd "..\..\..\lib\isccfg\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\..\bin\rndc\win32" !ELSEIF "$(CFG)" == "rndc - @PLATFORM@ Debug" "libisccfg - @PLATFORM@ Debug" : cd "..\..\..\lib\isccfg\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Debug" cd "..\..\..\bin\rndc\win32" "libisccfg - @PLATFORM@ DebugCLEAN" : cd "..\..\..\lib\isccfg\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\..\bin\rndc\win32" !ENDIF !IF "$(CFG)" == "rndc - @PLATFORM@ Release" "libbind9 - @PLATFORM@ Release" : cd "..\..\..\lib\bind9\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libbind9.mak" CFG="libbind9 - @PLATFORM@ Release" cd "..\..\..\bin\rndc\win32" "libbind9 - @PLATFORM@ ReleaseCLEAN" : cd "..\..\..\lib\bind9\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libbind9.mak" CFG="libbind9 - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\..\bin\rndc\win32" !ELSEIF "$(CFG)" == "rndc - @PLATFORM@ Debug" "libbind9 - @PLATFORM@ Debug" : cd "..\..\..\lib\bind9\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libbind9.mak" CFG="libbind9 - @PLATFORM@ Debug" cd "..\..\..\bin\rndc\win32" "libbind9 - @PLATFORM@ DebugCLEAN" : cd "..\..\..\lib\bind9\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libbind9.mak" CFG="libbind9 - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\..\bin\rndc\win32" !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/bin/rndc/rndc.conf.html0000644000470500017500000002233412664710322017633 0ustar lamontlamont rndc.conf

Name

rndc.conf — rndc configuration file

Synopsis

rndc.conf

DESCRIPTION

rndc.conf is the configuration file for rndc, the BIND 9 name server control utility. This file has a similar structure and syntax to named.conf. Statements are enclosed in braces and terminated with a semi-colon. Clauses in the statements are also semi-colon terminated. The usual comment styles are supported:

C style: /* */

C++ style: // to end of line

Unix style: # to end of line

rndc.conf is much simpler than named.conf. The file uses three statements: an options statement, a server statement and a key statement.

The options statement contains five clauses. The default-server clause is followed by the name or address of a name server. This host will be used when no name server is given as an argument to rndc. The default-key clause is followed by the name of a key which is identified by a key statement. If no keyid is provided on the rndc command line, and no key clause is found in a matching server statement, this default key will be used to authenticate the server's commands and responses. The default-port clause is followed by the port to connect to on the remote name server. If no port option is provided on the rndc command line, and no port clause is found in a matching server statement, this default port will be used to connect. The default-source-address and default-source-address-v6 clauses which can be used to set the IPv4 and IPv6 source addresses respectively.

After the server keyword, the server statement includes a string which is the hostname or address for a name server. The statement has three possible clauses: key, port and addresses. The key name must match the name of a key statement in the file. The port number specifies the port to connect to. If an addresses clause is supplied these addresses will be used instead of the server name. Each address can take an optional port. If an source-address or source-address-v6 of supplied then these will be used to specify the IPv4 and IPv6 source addresses respectively.

The key statement begins with an identifying string, the name of the key. The statement has two clauses. algorithm identifies the authentication algorithm for rndc to use; currently only HMAC-MD5 (for compatibility), HMAC-SHA1, HMAC-SHA224, HMAC-SHA256 (default), HMAC-SHA384 and HMAC-SHA512 are supported. This is followed by a secret clause which contains the base-64 encoding of the algorithm's authentication key. The base-64 string is enclosed in double quotes.

There are two common ways to generate the base-64 string for the secret. The BIND 9 program rndc-confgen can be used to generate a random key, or the mmencode program, also known as mimencode, can be used to generate a base-64 string from known input. mmencode does not ship with BIND 9 but is available on many systems. See the EXAMPLE section for sample command lines for each.

EXAMPLE

      options {
        default-server  localhost;
        default-key     samplekey;
      };

      server localhost {
        key             samplekey;
      };

      server testserver {
        key		testkey;
        addresses	{ localhost port 5353; };
      };

      key samplekey {
        algorithm       hmac-sha256;
        secret          "6FMfj43Osz4lyb24OIe2iGEz9lf1llJO+lz";
      };

      key testkey {
        algorithm	hmac-sha256;
        secret		"R3HI8P6BKw9ZwXwN3VZKuQ==";
      };
    

In the above example, rndc will by default use the server at localhost (127.0.0.1) and the key called samplekey. Commands to the localhost server will use the samplekey key, which must also be defined in the server's configuration file with the same name and secret. The key statement indicates that samplekey uses the HMAC-SHA256 algorithm and its secret clause contains the base-64 encoding of the HMAC-SHA256 secret enclosed in double quotes.

If rndc -s testserver is used then rndc will connect to server on localhost port 5353 using the key testkey.

To generate a random secret with rndc-confgen:

rndc-confgen

A complete rndc.conf file, including the randomly generated key, will be written to the standard output. Commented-out key and controls statements for named.conf are also printed.

To generate a base-64 secret with mmencode:

echo "known plaintext for a secret" | mmencode

NAME SERVER CONFIGURATION

The name server must be configured to accept rndc connections and to recognize the key specified in the rndc.conf file, using the controls statement in named.conf. See the sections on the controls statement in the BIND 9 Administrator Reference Manual for details.

SEE ALSO

rndc(8), rndc-confgen(8), mmencode(1), BIND 9 Administrator Reference Manual.

AUTHOR

Internet Systems Consortium

bind9-9.10.3.dfsg.P4/bin/rndc/util.h0000644000470500017500000000300212664710322016210 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: util.h,v 1.12 2009/09/29 23:48:03 tbox Exp $ */ #ifndef RNDC_UTIL_H #define RNDC_UTIL_H 1 /*! \file */ #include #include #include #define NS_CONTROL_PORT 953 #undef DO #define DO(name, function) \ do { \ result = function; \ if (result != ISC_R_SUCCESS) \ fatal("%s: %s", name, isc_result_totext(result)); \ else \ notify("%s", name); \ } while (0) ISC_LANG_BEGINDECLS void notify(const char *fmt, ...) ISC_FORMAT_PRINTF(1, 2); ISC_PLATFORM_NORETURN_PRE void fatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2) ISC_PLATFORM_NORETURN_POST; ISC_LANG_ENDDECLS #endif /* RNDC_UTIL_H */ bind9-9.10.3.dfsg.P4/bin/rndc/rndc.c0000644000470500017500000006371512664710322016175 0ustar lamontlamont/* * Copyright (C) 2004-2016 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ /* * Principal Author: DCL */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "util.h" #define SERVERADDRS 10 const char *progname; isc_boolean_t verbose; static const char *admin_conffile; static const char *admin_keyfile; static const char *version = VERSION; static const char *servername = NULL; static isc_sockaddr_t serveraddrs[SERVERADDRS]; static isc_sockaddr_t local4, local6; static isc_boolean_t local4set = ISC_FALSE, local6set = ISC_FALSE; static int nserveraddrs; static int currentaddr = 0; static unsigned int remoteport = 0; static isc_socketmgr_t *socketmgr = NULL; static unsigned char databuf[2048]; static isccc_ccmsg_t ccmsg; static isc_uint32_t algorithm; static isccc_region_t secret; static isc_boolean_t failed = ISC_FALSE; static isc_boolean_t c_flag = ISC_FALSE; static isc_mem_t *rndc_mctx; static int sends, recvs, connects; static char *command; static char *args; static char program[256]; static isc_socket_t *sock = NULL; static isc_uint32_t serial; static isc_boolean_t quiet = ISC_FALSE; static void rndc_startconnect(isc_sockaddr_t *addr, isc_task_t *task); ISC_PLATFORM_NORETURN_PRE static void usage(int status) ISC_PLATFORM_NORETURN_POST; static void usage(int status) { fprintf(stderr, "\ Usage: %s [-b address] [-c config] [-s server] [-p port]\n\ [-k key-file ] [-y key] [-V] command\n\ \n\ command is one of the following:\n\ \n\ addzone zone [class [view]] { zone-options }\n\ Add zone to given view. Requires new-zone-file option.\n\ delzone [-clean] zone [class [view]]\n\ Removes zone from given view. Requires new-zone-file option.\n\ dumpdb [-all|-cache|-zones|-adb|-bad|-fail] [view ...]\n\ Dump cache(s) to the dump file (named_dump.db).\n\ flush Flushes all of the server's caches.\n\ flush [view] Flushes the server's cache for a view.\n\ flushname name [view]\n\ Flush the given name from the server's cache(s)\n\ flushtree name [view]\n\ Flush all names under the given name from the server's cache(s)\n\ freeze Suspend updates to all dynamic zones.\n\ freeze zone [class [view]]\n\ Suspend updates to a dynamic zone.\n\ halt Stop the server without saving pending updates.\n\ halt -p Stop the server without saving pending updates reporting\n\ process id.\n\ loadkeys zone [class [view]]\n\ Update keys without signing immediately.\n\ notify zone [class [view]]\n\ Resend NOTIFY messages for the zone.\n\ notrace Set debugging level to 0.\n\ querylog newstate\n\ Enable / disable query logging.\n\ reconfig Reload configuration file and new zones only.\n\ recursing Dump the queries that are currently recursing (named.recursing)\n\ refresh zone [class [view]]\n\ Schedule immediate maintenance for a zone.\n\ reload Reload configuration file and zones.\n\ reload zone [class [view]]\n\ Reload a single zone.\n\ retransfer zone [class [view]]\n\ Retransfer a single zone without checking serial number.\n\ scan Scan available network interfaces for changes.\n\ secroots [view ...]\n\ Write security roots to the secroots file.\n\ sign zone [class [view]]\n\ Update zone keys, and sign as needed.\n\ signing -clear all zone [class [view]]\n\ Remove the private records for all keys that have\n\ finished signing the given zone.\n\ signing -clear / zone [class [view]]\n\ Remove the private record that indicating the given key\n\ has finished signing the given zone.\n\ signing -list zone [class [view]]\n\ List the private records showing the state of DNSSEC\n\ signing in the given zone.\n\ signing -nsec3param hash flags iterations salt zone [class [view]]\n\ Add NSEC3 chain to zone if already signed.\n\ Prime zone with NSEC3 chain if not yet signed.\n\ signing -nsec3param none zone [class [view]]\n\ Remove NSEC3 chains from zone.\n\ stats Write server statistics to the statistics file.\n\ status Display status of the server.\n\ stop Save pending updates to master files and stop the server.\n\ stop -p Save pending updates to master files and stop the server\n\ reporting process id.\n\ sync [-clean] Dump changes to all dynamic zones to disk, and optionally\n\ remove their journal files.\n\ sync [-clean] zone [class [view]]\n\ Dump a single zone's changes to disk, and optionally\n\ remove its journal file.\n\ thaw Enable updates to all dynamic zones and reload them.\n\ thaw zone [class [view]]\n\ Enable updates to a frozen dynamic zone and reload it.\n\ trace Increment debugging level by one.\n\ trace level Change the debugging level.\n\ tsig-delete keyname [view]\n\ Delete a TKEY-negotiated TSIG key.\n\ tsig-list List all currently active TSIG keys, including both statically\n\ configured and TKEY-negotiated keys.\n\ validation newstate [view]\n\ Enable / disable DNSSEC validation.\n\ zonestatus zone [class [view]]\n\ Display the current status of a zone.\n\ \n\ Version: %s\n", progname, version); exit(status); } static void get_addresses(const char *host, in_port_t port) { isc_result_t result; int found = 0, count; if (*host == '/') { result = isc_sockaddr_frompath(&serveraddrs[nserveraddrs], host); if (result == ISC_R_SUCCESS) nserveraddrs++; } else { count = SERVERADDRS - nserveraddrs; result = bind9_getaddresses(host, port, &serveraddrs[nserveraddrs], count, &found); nserveraddrs += found; } if (result != ISC_R_SUCCESS) fatal("couldn't get address for '%s': %s", host, isc_result_totext(result)); INSIST(nserveraddrs > 0); } static void rndc_senddone(isc_task_t *task, isc_event_t *event) { isc_socketevent_t *sevent = (isc_socketevent_t *)event; UNUSED(task); sends--; if (sevent->result != ISC_R_SUCCESS) fatal("send failed: %s", isc_result_totext(sevent->result)); isc_event_free(&event); if (sends == 0 && recvs == 0) { isc_socket_detach(&sock); isc_task_shutdown(task); RUNTIME_CHECK(isc_app_shutdown() == ISC_R_SUCCESS); } } static void rndc_recvdone(isc_task_t *task, isc_event_t *event) { isccc_sexpr_t *response = NULL; isccc_sexpr_t *data; isccc_region_t source; char *errormsg = NULL; char *textmsg = NULL; isc_result_t result; recvs--; if (ccmsg.result == ISC_R_EOF) fatal("connection to remote host closed\n" "This may indicate that\n" "* the remote server is using an older version of" " the command protocol,\n" "* this host is not authorized to connect,\n" "* the clocks are not synchronized, or\n" "* the key is invalid."); if (ccmsg.result != ISC_R_SUCCESS) fatal("recv failed: %s", isc_result_totext(ccmsg.result)); source.rstart = isc_buffer_base(&ccmsg.buffer); source.rend = isc_buffer_used(&ccmsg.buffer); DO("parse message", isccc_cc_fromwire(&source, &response, algorithm, &secret)); data = isccc_alist_lookup(response, "_data"); if (!isccc_alist_alistp(data)) fatal("bad or missing data section in response"); result = isccc_cc_lookupstring(data, "err", &errormsg); if (result == ISC_R_SUCCESS) { failed = ISC_TRUE; fprintf(stderr, "%s: '%s' failed: %s\n", progname, command, errormsg); } else if (result != ISC_R_NOTFOUND) fprintf(stderr, "%s: parsing response failed: %s\n", progname, isc_result_totext(result)); result = isccc_cc_lookupstring(data, "text", &textmsg); if (result == ISC_R_SUCCESS) { if ((!quiet || failed) && strlen(textmsg) != 0U) fprintf(failed ? stderr : stdout, "%s\n", textmsg); } else if (result != ISC_R_NOTFOUND) fprintf(stderr, "%s: parsing response failed: %s\n", progname, isc_result_totext(result)); isc_event_free(&event); isccc_sexpr_free(&response); if (sends == 0 && recvs == 0) { isc_socket_detach(&sock); isc_task_shutdown(task); RUNTIME_CHECK(isc_app_shutdown() == ISC_R_SUCCESS); } } static void rndc_recvnonce(isc_task_t *task, isc_event_t *event) { isccc_sexpr_t *response = NULL; isccc_sexpr_t *_ctrl; isccc_region_t source; isc_result_t result; isc_uint32_t nonce; isccc_sexpr_t *request = NULL; isccc_time_t now; isc_region_t r; isccc_sexpr_t *data; isccc_region_t message; isc_uint32_t len; isc_buffer_t b; recvs--; if (ccmsg.result == ISC_R_EOF) fatal("connection to remote host closed\n" "This may indicate that\n" "* the remote server is using an older version of" " the command protocol,\n" "* this host is not authorized to connect,\n" "* the clocks are not synchronized,\n" "* the key signing algorithm is incorrect, or\n" "* the key is invalid."); if (ccmsg.result != ISC_R_SUCCESS) fatal("recv failed: %s", isc_result_totext(ccmsg.result)); source.rstart = isc_buffer_base(&ccmsg.buffer); source.rend = isc_buffer_used(&ccmsg.buffer); DO("parse message", isccc_cc_fromwire(&source, &response, algorithm, &secret)); _ctrl = isccc_alist_lookup(response, "_ctrl"); if (!isccc_alist_alistp(_ctrl)) fatal("bad or missing ctrl section in response"); nonce = 0; if (isccc_cc_lookupuint32(_ctrl, "_nonce", &nonce) != ISC_R_SUCCESS) nonce = 0; isc_stdtime_get(&now); DO("create message", isccc_cc_createmessage(1, NULL, NULL, ++serial, now, now + 60, &request)); data = isccc_alist_lookup(request, "_data"); if (data == NULL) fatal("_data section missing"); if (isccc_cc_definestring(data, "type", args) == NULL) fatal("out of memory"); if (nonce != 0) { _ctrl = isccc_alist_lookup(request, "_ctrl"); if (_ctrl == NULL) fatal("_ctrl section missing"); if (isccc_cc_defineuint32(_ctrl, "_nonce", nonce) == NULL) fatal("out of memory"); } message.rstart = databuf + 4; message.rend = databuf + sizeof(databuf); DO("render message", isccc_cc_towire(request, &message, algorithm, &secret)); len = sizeof(databuf) - REGION_SIZE(message); isc_buffer_init(&b, databuf, 4); isc_buffer_putuint32(&b, len - 4); r.length = len; r.base = databuf; isccc_ccmsg_cancelread(&ccmsg); DO("schedule recv", isccc_ccmsg_readmessage(&ccmsg, task, rndc_recvdone, NULL)); recvs++; DO("send message", isc_socket_send(sock, &r, task, rndc_senddone, NULL)); sends++; isc_event_free(&event); isccc_sexpr_free(&response); return; } static void rndc_connected(isc_task_t *task, isc_event_t *event) { char socktext[ISC_SOCKADDR_FORMATSIZE]; isc_socketevent_t *sevent = (isc_socketevent_t *)event; isccc_sexpr_t *request = NULL; isccc_sexpr_t *data; isccc_time_t now; isccc_region_t message; isc_region_t r; isc_uint32_t len; isc_buffer_t b; isc_result_t result; connects--; if (sevent->result != ISC_R_SUCCESS) { isc_sockaddr_format(&serveraddrs[currentaddr], socktext, sizeof(socktext)); if (sevent->result != ISC_R_CANCELED && ++currentaddr < nserveraddrs) { notify("connection failed: %s: %s", socktext, isc_result_totext(sevent->result)); isc_socket_detach(&sock); isc_event_free(&event); rndc_startconnect(&serveraddrs[currentaddr], task); return; } else fatal("connect failed: %s: %s", socktext, isc_result_totext(sevent->result)); } isc_stdtime_get(&now); DO("create message", isccc_cc_createmessage(1, NULL, NULL, ++serial, now, now + 60, &request)); data = isccc_alist_lookup(request, "_data"); if (data == NULL) fatal("_data section missing"); if (isccc_cc_definestring(data, "type", "null") == NULL) fatal("out of memory"); message.rstart = databuf + 4; message.rend = databuf + sizeof(databuf); DO("render message", isccc_cc_towire(request, &message, algorithm, &secret)); len = sizeof(databuf) - REGION_SIZE(message); isc_buffer_init(&b, databuf, 4); isc_buffer_putuint32(&b, len - 4); r.length = len; r.base = databuf; isccc_ccmsg_init(rndc_mctx, sock, &ccmsg); isccc_ccmsg_setmaxsize(&ccmsg, 1024 * 1024); DO("schedule recv", isccc_ccmsg_readmessage(&ccmsg, task, rndc_recvnonce, NULL)); recvs++; DO("send message", isc_socket_send(sock, &r, task, rndc_senddone, NULL)); sends++; isc_event_free(&event); } static void rndc_startconnect(isc_sockaddr_t *addr, isc_task_t *task) { isc_result_t result; int pf; isc_sockettype_t type; char socktext[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(addr, socktext, sizeof(socktext)); notify("using server %s (%s)", servername, socktext); pf = isc_sockaddr_pf(addr); if (pf == AF_INET || pf == AF_INET6) type = isc_sockettype_tcp; else type = isc_sockettype_unix; DO("create socket", isc_socket_create(socketmgr, pf, type, &sock)); switch (isc_sockaddr_pf(addr)) { case AF_INET: DO("bind socket", isc_socket_bind(sock, &local4, 0)); break; case AF_INET6: DO("bind socket", isc_socket_bind(sock, &local6, 0)); break; default: break; } DO("connect", isc_socket_connect(sock, addr, task, rndc_connected, NULL)); connects++; } static void rndc_start(isc_task_t *task, isc_event_t *event) { isc_event_free(&event); currentaddr = 0; rndc_startconnect(&serveraddrs[currentaddr], task); } static void parse_config(isc_mem_t *mctx, isc_log_t *log, const char *keyname, cfg_parser_t **pctxp, cfg_obj_t **configp) { isc_result_t result; const char *conffile = admin_conffile; const cfg_obj_t *addresses = NULL; const cfg_obj_t *defkey = NULL; const cfg_obj_t *options = NULL; const cfg_obj_t *servers = NULL; const cfg_obj_t *server = NULL; const cfg_obj_t *keys = NULL; const cfg_obj_t *key = NULL; const cfg_obj_t *defport = NULL; const cfg_obj_t *secretobj = NULL; const cfg_obj_t *algorithmobj = NULL; cfg_obj_t *config = NULL; const cfg_obj_t *address = NULL; const cfg_listelt_t *elt; const char *secretstr; const char *algorithmstr; static char secretarray[1024]; const cfg_type_t *conftype = &cfg_type_rndcconf; isc_boolean_t key_only = ISC_FALSE; const cfg_listelt_t *element; if (! isc_file_exists(conffile)) { conffile = admin_keyfile; conftype = &cfg_type_rndckey; if (c_flag) fatal("%s does not exist", admin_conffile); if (! isc_file_exists(conffile)) fatal("neither %s nor %s was found", admin_conffile, admin_keyfile); key_only = ISC_TRUE; } else if (! c_flag && isc_file_exists(admin_keyfile)) { fprintf(stderr, "WARNING: key file (%s) exists, but using " "default configuration file (%s)\n", admin_keyfile, admin_conffile); } DO("create parser", cfg_parser_create(mctx, log, pctxp)); /* * The parser will output its own errors, so DO() is not used. */ result = cfg_parse_file(*pctxp, conffile, conftype, &config); if (result != ISC_R_SUCCESS) fatal("could not load rndc configuration"); if (!key_only) (void)cfg_map_get(config, "options", &options); if (key_only && servername == NULL) servername = "127.0.0.1"; else if (servername == NULL && options != NULL) { const cfg_obj_t *defserverobj = NULL; (void)cfg_map_get(options, "default-server", &defserverobj); if (defserverobj != NULL) servername = cfg_obj_asstring(defserverobj); } if (servername == NULL) fatal("no server specified and no default"); if (!key_only) { (void)cfg_map_get(config, "server", &servers); if (servers != NULL) { for (elt = cfg_list_first(servers); elt != NULL; elt = cfg_list_next(elt)) { const char *name; server = cfg_listelt_value(elt); name = cfg_obj_asstring(cfg_map_getname(server)); if (strcasecmp(name, servername) == 0) break; server = NULL; } } } /* * Look for the name of the key to use. */ if (keyname != NULL) ; /* Was set on command line, do nothing. */ else if (server != NULL) { DO("get key for server", cfg_map_get(server, "key", &defkey)); keyname = cfg_obj_asstring(defkey); } else if (options != NULL) { DO("get default key", cfg_map_get(options, "default-key", &defkey)); keyname = cfg_obj_asstring(defkey); } else if (!key_only) fatal("no key for server and no default"); /* * Get the key's definition. */ if (key_only) DO("get key", cfg_map_get(config, "key", &key)); else { DO("get config key list", cfg_map_get(config, "key", &keys)); for (elt = cfg_list_first(keys); elt != NULL; elt = cfg_list_next(elt)) { key = cfg_listelt_value(elt); if (strcasecmp(cfg_obj_asstring(cfg_map_getname(key)), keyname) == 0) break; } if (elt == NULL) fatal("no key definition for name %s", keyname); } (void)cfg_map_get(key, "secret", &secretobj); (void)cfg_map_get(key, "algorithm", &algorithmobj); if (secretobj == NULL || algorithmobj == NULL) fatal("key must have algorithm and secret"); secretstr = cfg_obj_asstring(secretobj); algorithmstr = cfg_obj_asstring(algorithmobj); if (strcasecmp(algorithmstr, "hmac-md5") == 0) algorithm = ISCCC_ALG_HMACMD5; else if (strcasecmp(algorithmstr, "hmac-sha1") == 0) algorithm = ISCCC_ALG_HMACSHA1; else if (strcasecmp(algorithmstr, "hmac-sha224") == 0) algorithm = ISCCC_ALG_HMACSHA224; else if (strcasecmp(algorithmstr, "hmac-sha256") == 0) algorithm = ISCCC_ALG_HMACSHA256; else if (strcasecmp(algorithmstr, "hmac-sha384") == 0) algorithm = ISCCC_ALG_HMACSHA384; else if (strcasecmp(algorithmstr, "hmac-sha512") == 0) algorithm = ISCCC_ALG_HMACSHA512; else fatal("unsupported algorithm: %s", algorithmstr); secret.rstart = (unsigned char *)secretarray; secret.rend = (unsigned char *)secretarray + sizeof(secretarray); DO("decode base64 secret", isccc_base64_decode(secretstr, &secret)); secret.rend = secret.rstart; secret.rstart = (unsigned char *)secretarray; /* * Find the port to connect to. */ if (remoteport != 0) ; /* Was set on command line, do nothing. */ else { if (server != NULL) (void)cfg_map_get(server, "port", &defport); if (defport == NULL && options != NULL) (void)cfg_map_get(options, "default-port", &defport); } if (defport != NULL) { remoteport = cfg_obj_asuint32(defport); if (remoteport > 65535 || remoteport == 0) fatal("port %u out of range", remoteport); } else if (remoteport == 0) remoteport = NS_CONTROL_PORT; if (server != NULL) result = cfg_map_get(server, "addresses", &addresses); else result = ISC_R_NOTFOUND; if (result == ISC_R_SUCCESS) { for (element = cfg_list_first(addresses); element != NULL; element = cfg_list_next(element)) { isc_sockaddr_t sa; address = cfg_listelt_value(element); if (!cfg_obj_issockaddr(address)) { unsigned int myport; const char *name; const cfg_obj_t *obj; obj = cfg_tuple_get(address, "name"); name = cfg_obj_asstring(obj); obj = cfg_tuple_get(address, "port"); if (cfg_obj_isuint32(obj)) { myport = cfg_obj_asuint32(obj); if (myport > ISC_UINT16_MAX || myport == 0) fatal("port %u out of range", myport); } else myport = remoteport; if (nserveraddrs < SERVERADDRS) get_addresses(name, (in_port_t) myport); else fprintf(stderr, "too many address: " "%s: dropped\n", name); continue; } sa = *cfg_obj_assockaddr(address); if (isc_sockaddr_getport(&sa) == 0) isc_sockaddr_setport(&sa, remoteport); if (nserveraddrs < SERVERADDRS) serveraddrs[nserveraddrs++] = sa; else { char socktext[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(&sa, socktext, sizeof(socktext)); fprintf(stderr, "too many address: %s: dropped\n", socktext); } } } if (!local4set && server != NULL) { address = NULL; cfg_map_get(server, "source-address", &address); if (address != NULL) { local4 = *cfg_obj_assockaddr(address); local4set = ISC_TRUE; } } if (!local4set && options != NULL) { address = NULL; cfg_map_get(options, "default-source-address", &address); if (address != NULL) { local4 = *cfg_obj_assockaddr(address); local4set = ISC_TRUE; } } if (!local6set && server != NULL) { address = NULL; cfg_map_get(server, "source-address-v6", &address); if (address != NULL) { local6 = *cfg_obj_assockaddr(address); local6set = ISC_TRUE; } } if (!local6set && options != NULL) { address = NULL; cfg_map_get(options, "default-source-address-v6", &address); if (address != NULL) { local6 = *cfg_obj_assockaddr(address); local6set = ISC_TRUE; } } *configp = config; } int main(int argc, char **argv) { isc_result_t result = ISC_R_SUCCESS; isc_boolean_t show_final_mem = ISC_FALSE; isc_taskmgr_t *taskmgr = NULL; isc_task_t *task = NULL; isc_log_t *log = NULL; isc_logconfig_t *logconfig = NULL; isc_logdestination_t logdest; cfg_parser_t *pctx = NULL; cfg_obj_t *config = NULL; const char *keyname = NULL; struct in_addr in; struct in6_addr in6; char *p; size_t argslen; int ch; int i; result = isc_file_progname(*argv, program, sizeof(program)); if (result != ISC_R_SUCCESS) memmove(program, "rndc", 5); progname = program; admin_conffile = RNDC_CONFFILE; admin_keyfile = RNDC_KEYFILE; isc_sockaddr_any(&local4); isc_sockaddr_any6(&local6); result = isc_app_start(); if (result != ISC_R_SUCCESS) fatal("isc_app_start() failed: %s", isc_result_totext(result)); isc_commandline_errprint = ISC_FALSE; while ((ch = isc_commandline_parse(argc, argv, "b:c:hk:Mmp:qs:Vy:")) != -1) { switch (ch) { case 'b': if (inet_pton(AF_INET, isc_commandline_argument, &in) == 1) { isc_sockaddr_fromin(&local4, &in, 0); local4set = ISC_TRUE; } else if (inet_pton(AF_INET6, isc_commandline_argument, &in6) == 1) { isc_sockaddr_fromin6(&local6, &in6, 0); local6set = ISC_TRUE; } break; case 'c': admin_conffile = isc_commandline_argument; c_flag = ISC_TRUE; break; case 'k': admin_keyfile = isc_commandline_argument; break; case 'M': isc_mem_debugging = ISC_MEM_DEBUGTRACE; break; case 'm': show_final_mem = ISC_TRUE; break; case 'p': remoteport = atoi(isc_commandline_argument); if (remoteport > 65535 || remoteport == 0) fatal("port '%s' out of range", isc_commandline_argument); break; case 'q': quiet = ISC_TRUE; break; case 's': servername = isc_commandline_argument; break; case 'V': verbose = ISC_TRUE; break; case 'y': keyname = isc_commandline_argument; break; case '?': if (isc_commandline_option != '?') { fprintf(stderr, "%s: invalid argument -%c\n", program, isc_commandline_option); usage(1); } /* FALLTHROUGH */ case 'h': usage(0); break; default: fprintf(stderr, "%s: unhandled option -%c\n", program, isc_commandline_option); exit(1); } } argc -= isc_commandline_index; argv += isc_commandline_index; if (argc < 1) usage(1); isc_random_get(&serial); DO("create memory context", isc_mem_create(0, 0, &rndc_mctx)); DO("create socket manager", isc_socketmgr_create(rndc_mctx, &socketmgr)); DO("create task manager", isc_taskmgr_create(rndc_mctx, 1, 0, &taskmgr)); DO("create task", isc_task_create(taskmgr, 0, &task)); DO("create logging context", isc_log_create(rndc_mctx, &log, &logconfig)); isc_log_setcontext(log); DO("setting log tag", isc_log_settag(logconfig, progname)); logdest.file.stream = stderr; logdest.file.name = NULL; logdest.file.versions = ISC_LOG_ROLLNEVER; logdest.file.maximum_size = 0; DO("creating log channel", isc_log_createchannel(logconfig, "stderr", ISC_LOG_TOFILEDESC, ISC_LOG_INFO, &logdest, ISC_LOG_PRINTTAG|ISC_LOG_PRINTLEVEL)); DO("enabling log channel", isc_log_usechannel(logconfig, "stderr", NULL, NULL)); parse_config(rndc_mctx, log, keyname, &pctx, &config); isccc_result_register(); command = *argv; /* * Convert argc/argv into a space-delimited command string * similar to what the user might enter in interactive mode * (if that were implemented). */ argslen = 0; for (i = 0; i < argc; i++) argslen += strlen(argv[i]) + 1; args = isc_mem_get(rndc_mctx, argslen); if (args == NULL) DO("isc_mem_get", ISC_R_NOMEMORY); p = args; for (i = 0; i < argc; i++) { size_t len = strlen(argv[i]); memmove(p, argv[i], len); p += len; *p++ = ' '; } p--; *p++ = '\0'; INSIST(p == args + argslen); notify("%s", command); if (strcmp(command, "restart") == 0) fatal("'%s' is not implemented", command); if (nserveraddrs == 0) get_addresses(servername, (in_port_t) remoteport); DO("post event", isc_app_onrun(rndc_mctx, task, rndc_start, NULL)); result = isc_app_run(); if (result != ISC_R_SUCCESS) fatal("isc_app_run() failed: %s", isc_result_totext(result)); if (connects > 0 || sends > 0 || recvs > 0) isc_socket_cancel(sock, task, ISC_SOCKCANCEL_ALL); isc_task_detach(&task); isc_taskmgr_destroy(&taskmgr); isc_socketmgr_destroy(&socketmgr); isc_log_destroy(&log); isc_log_setcontext(NULL); cfg_obj_destroy(pctx, &config); cfg_parser_destroy(&pctx); isc_mem_put(rndc_mctx, args, argslen); isccc_ccmsg_invalidate(&ccmsg); dns_name_destroy(); if (show_final_mem) isc_mem_stats(rndc_mctx, stderr); isc_mem_destroy(&rndc_mctx); if (failed) return (1); return (0); } bind9-9.10.3.dfsg.P4/bin/rndc/util.c0000644000470500017500000000274212664710322016215 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: util.c,v 1.7 2007/06/19 23:46:59 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include "util.h" extern isc_boolean_t verbose; extern const char *progname; void notify(const char *fmt, ...) { va_list ap; if (verbose) { va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); fputs("\n", stderr); } } void fatal(const char *format, ...) { va_list args; fprintf(stderr, "%s: ", progname); va_start(args, format); vfprintf(stderr, format, args); va_end(args); fprintf(stderr, "\n"); exit(1); } bind9-9.10.3.dfsg.P4/bin/rndc/rndc.conf0000644000470500017500000000250412664710322016665 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Sample rndc configuration file. */ options { default-server localhost; default-key "key"; }; server localhost { key "key"; }; key "cc64b3d1db63fc88d7cb5d2f9f57d258" { algorithm hmac-sha256; secret "34f88008d07deabbe65bd01f1d233d47"; }; server "test1" { key "cc64b3d1db63fc88d7cb5d2f9f57d258"; port 5353; addresses { 10.53.0.1; }; }; key "key" { algorithm hmac-sha256; secret "c3Ryb25nIGVub3VnaCBmb3IgYSBtYW4gYnV0IG1hZGUgZm9yIGEgd29tYW4K"; }; bind9-9.10.3.dfsg.P4/bin/python/0002755000470500017500000000000012672612753015474 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/python/dnssec-coverage.html0000644000470500017500000002277012664710322021430 0ustar lamontlamont dnssec-coverage

Name

dnssec-coverage — checks future DNSKEY coverage for a zone

Synopsis

dnssec-coverage [-K directory] [-l length] [-f file] [-d DNSKEY TTL] [-m max TTL] [-r interval] [-c compilezone path] [-k] [-z] [zone]

DESCRIPTION

dnssec-coverage verifies that the DNSSEC keys for a given zone or a set of zones have timing metadata set properly to ensure no future lapses in DNSSEC coverage.

If zone is specified, then keys found in the key repository matching that zone are scanned, and an ordered list is generated of the events scheduled for that key (i.e., publication, activation, inactivation, deletion). The list of events is walked in order of occurrence. Warnings are generated if any event is scheduled which could cause the zone to enter a state in which validation failures might occur: for example, if the number of published or active keys for a given algorithm drops to zero, or if a key is deleted from the zone too soon after a new key is rolled, and cached data signed by the prior key has not had time to expire from resolver caches.

If zone is not specified, then all keys in the key repository will be scanned, and all zones for which there are keys will be analyzed. (Note: This method of reporting is only accurate if all the zones that have keys in a given repository share the same TTL parameters.)

OPTIONS

-K directory

Sets the directory in which keys can be found. Defaults to the current working directory.

-f file

If a file is specified, then the zone is read from that file; the largest TTL and the DNSKEY TTL are determined directly from the zone data, and the -m and -d options do not need to be specified on the command line.

-l duration

The length of time to check for DNSSEC coverage. Key events scheduled further into the future than duration will be ignored, and assumed to be correct.

The value of duration can be set in seconds, or in larger units of time by adding a suffix: 'mi' for minutes, 'h' for hours, 'd' for days, 'w' for weeks, 'mo' for months, 'y' for years.

-m maximum TTL

Sets the value to be used as the maximum TTL for the zone or zones being analyzed when determining whether there is a possibility of validation failure. When a zone-signing key is deactivated, there must be enough time for the record in the zone with the longest TTL to have expired from resolver caches before that key can be purged from the DNSKEY RRset. If that condition does not apply, a warning will be generated.

The length of the TTL can be set in seconds, or in larger units of time by adding a suffix: 'mi' for minutes, 'h' for hours, 'd' for days, 'w' for weeks, 'mo' for months, 'y' for years.

This option is mandatory unless the -f has been used to specify a zone file. (If -f has been specified, this option may still be used; it will override the value found in the file.)

-d DNSKEY TTL

Sets the value to be used as the DNSKEY TTL for the zone or zones being analyzed when determining whether there is a possibility of validation failure. When a key is rolled (that is, replaced with a new key), there must be enough time for the old DNSKEY RRset to have expired from resolver caches before the new key is activated and begins generating signatures. If that condition does not apply, a warning will be generated.

The length of the TTL can be set in seconds, or in larger units of time by adding a suffix: 'mi' for minutes, 'h' for hours, 'd' for days, 'w' for weeks, 'mo' for months, 'y' for years.

This option is mandatory unless the -f has been used to specify a zone file, or a default key TTL was set with the -L to dnssec-keygen. (If either of those is true, this option may still be used; it will override the value found in the zone or key file.)

-r resign interval

Sets the value to be used as the resign interval for the zone or zones being analyzed when determining whether there is a possibility of validation failure. This value defaults to 22.5 days, which is also the default in named. However, if it has been changed by the sig-validity-interval option in named.conf, then it should also be changed here.

The length of the interval can be set in seconds, or in larger units of time by adding a suffix: 'mi' for minutes, 'h' for hours, 'd' for days, 'w' for weeks, 'mo' for months, 'y' for years.

-k

Only check KSK coverage; ignore ZSK events. Cannot be used with -z.

-z

Only check ZSK coverage; ignore KSK events. Cannot be used with -k.

-c compilezone path

Specifies a path to a named-compilezone binary. Used for testing.

SEE ALSO

dnssec-checkds(8), dnssec-dsfromkey(8), dnssec-keygen(8), dnssec-signzone(8)

AUTHOR

Internet Systems Consortium

bind9-9.10.3.dfsg.P4/bin/python/Makefile.in0000644000470500017500000000363112664710322017532 0ustar lamontlamont# Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id$ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_MAKE_INCLUDES@ PYTHON = @PYTHON@ TARGETS = dnssec-checkds dnssec-coverage PYSRCS = dnssec-checkds.py dnssec-coverage.py MANPAGES = dnssec-checkds.8 dnssec-coverage.8 HTMLPAGES = dnssec-checkds.html dnssec-coverage.html MANOBJS = ${MANPAGES} ${HTMLPAGES} @BIND9_MAKE_RULES@ dnssec-checkds: dnssec-checkds.py cp -f dnssec-checkds.py dnssec-checkds chmod +x dnssec-checkds dnssec-coverage: dnssec-coverage.py cp -f dnssec-coverage.py dnssec-coverage chmod +x dnssec-coverage doc man:: ${MANOBJS} docclean manclean maintainer-clean:: rm -f ${MANOBJS} installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 install:: ${TARGETS} installdirs ${INSTALL_SCRIPT} dnssec-checkds@EXEEXT@ ${DESTDIR}${sbindir} ${INSTALL_SCRIPT} dnssec-coverage@EXEEXT@ ${DESTDIR}${sbindir} ${INSTALL_DATA} ${srcdir}/dnssec-checkds.8 ${DESTDIR}${mandir}/man8 ${INSTALL_DATA} ${srcdir}/dnssec-coverage.8 ${DESTDIR}${mandir}/man8 clean distclean:: rm -f ${TARGETS} distclean:: rm -f dnssec-checkds.py dnssec-coverage.py bind9-9.10.3.dfsg.P4/bin/python/dnssec-coverage.docbook0000644000470500017500000002463212664710322022103 0ustar lamontlamont]> January 11, 2014 dnssec-coverage 8 BIND9 dnssec-coverage checks future DNSKEY coverage for a zone 2013 2014 Internet Systems Consortium, Inc. ("ISC") dnssec-coverage zone DESCRIPTION dnssec-coverage verifies that the DNSSEC keys for a given zone or a set of zones have timing metadata set properly to ensure no future lapses in DNSSEC coverage. If is specified, then keys found in the key repository matching that zone are scanned, and an ordered list is generated of the events scheduled for that key (i.e., publication, activation, inactivation, deletion). The list of events is walked in order of occurrence. Warnings are generated if any event is scheduled which could cause the zone to enter a state in which validation failures might occur: for example, if the number of published or active keys for a given algorithm drops to zero, or if a key is deleted from the zone too soon after a new key is rolled, and cached data signed by the prior key has not had time to expire from resolver caches. If is not specified, then all keys in the key repository will be scanned, and all zones for which there are keys will be analyzed. (Note: This method of reporting is only accurate if all the zones that have keys in a given repository share the same TTL parameters.) OPTIONS -K directory Sets the directory in which keys can be found. Defaults to the current working directory. -f file If a is specified, then the zone is read from that file; the largest TTL and the DNSKEY TTL are determined directly from the zone data, and the and options do not need to be specified on the command line. -l duration The length of time to check for DNSSEC coverage. Key events scheduled further into the future than will be ignored, and assumed to be correct. The value of can be set in seconds, or in larger units of time by adding a suffix: 'mi' for minutes, 'h' for hours, 'd' for days, 'w' for weeks, 'mo' for months, 'y' for years. -m maximum TTL Sets the value to be used as the maximum TTL for the zone or zones being analyzed when determining whether there is a possibility of validation failure. When a zone-signing key is deactivated, there must be enough time for the record in the zone with the longest TTL to have expired from resolver caches before that key can be purged from the DNSKEY RRset. If that condition does not apply, a warning will be generated. The length of the TTL can be set in seconds, or in larger units of time by adding a suffix: 'mi' for minutes, 'h' for hours, 'd' for days, 'w' for weeks, 'mo' for months, 'y' for years. This option is mandatory unless the has been used to specify a zone file. (If has been specified, this option may still be used; it will override the value found in the file.) -d DNSKEY TTL Sets the value to be used as the DNSKEY TTL for the zone or zones being analyzed when determining whether there is a possibility of validation failure. When a key is rolled (that is, replaced with a new key), there must be enough time for the old DNSKEY RRset to have expired from resolver caches before the new key is activated and begins generating signatures. If that condition does not apply, a warning will be generated. The length of the TTL can be set in seconds, or in larger units of time by adding a suffix: 'mi' for minutes, 'h' for hours, 'd' for days, 'w' for weeks, 'mo' for months, 'y' for years. This option is mandatory unless the has been used to specify a zone file, or a default key TTL was set with the to dnssec-keygen. (If either of those is true, this option may still be used; it will override the value found in the zone or key file.) -r resign interval Sets the value to be used as the resign interval for the zone or zones being analyzed when determining whether there is a possibility of validation failure. This value defaults to 22.5 days, which is also the default in named. However, if it has been changed by the option in named.conf, then it should also be changed here. The length of the interval can be set in seconds, or in larger units of time by adding a suffix: 'mi' for minutes, 'h' for hours, 'd' for days, 'w' for weeks, 'mo' for months, 'y' for years. -k Only check KSK coverage; ignore ZSK events. Cannot be used with . -z Only check ZSK coverage; ignore KSK events. Cannot be used with . -c compilezone path Specifies a path to a named-compilezone binary. Used for testing. SEE ALSO dnssec-checkds8 , dnssec-dsfromkey8 , dnssec-keygen8 , dnssec-signzone8 AUTHOR Internet Systems Consortium bind9-9.10.3.dfsg.P4/bin/python/dnssec-coverage.80000644000470500017500000001446112664710322020631 0ustar lamontlamont.\" Copyright (C) 2013, 2014 Internet Systems Consortium, Inc. ("ISC") .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: dnssec\-coverage .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: January 11, 2014 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "DNSSEC\-COVERAGE" "8" "January 11, 2014" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" dnssec\-coverage \- checks future DNSKEY coverage for a zone .SH "SYNOPSIS" .HP 16 \fBdnssec\-coverage\fR [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-l\ \fR\fB\fIlength\fR\fR] [\fB\-f\ \fR\fB\fIfile\fR\fR] [\fB\-d\ \fR\fB\fIDNSKEY\ TTL\fR\fR] [\fB\-m\ \fR\fB\fImax\ TTL\fR\fR] [\fB\-r\ \fR\fB\fIinterval\fR\fR] [\fB\-c\ \fR\fB\fIcompilezone\ path\fR\fR] [\fB\-k\fR] [\fB\-z\fR] [zone] .SH "DESCRIPTION" .PP \fBdnssec\-coverage\fR verifies that the DNSSEC keys for a given zone or a set of zones have timing metadata set properly to ensure no future lapses in DNSSEC coverage. .PP If \fBzone\fR is specified, then keys found in the key repository matching that zone are scanned, and an ordered list is generated of the events scheduled for that key (i.e., publication, activation, inactivation, deletion). The list of events is walked in order of occurrence. Warnings are generated if any event is scheduled which could cause the zone to enter a state in which validation failures might occur: for example, if the number of published or active keys for a given algorithm drops to zero, or if a key is deleted from the zone too soon after a new key is rolled, and cached data signed by the prior key has not had time to expire from resolver caches. .PP If \fBzone\fR is not specified, then all keys in the key repository will be scanned, and all zones for which there are keys will be analyzed. (Note: This method of reporting is only accurate if all the zones that have keys in a given repository share the same TTL parameters.) .SH "OPTIONS" .PP \-K \fIdirectory\fR .RS 4 Sets the directory in which keys can be found. Defaults to the current working directory. .RE .PP \-f \fIfile\fR .RS 4 If a \fBfile\fR is specified, then the zone is read from that file; the largest TTL and the DNSKEY TTL are determined directly from the zone data, and the \fB\-m\fR and \fB\-d\fR options do not need to be specified on the command line. .RE .PP \-l \fIduration\fR .RS 4 The length of time to check for DNSSEC coverage. Key events scheduled further into the future than \fBduration\fR will be ignored, and assumed to be correct. .sp The value of \fBduration\fR can be set in seconds, or in larger units of time by adding a suffix: 'mi' for minutes, 'h' for hours, 'd' for days, 'w' for weeks, 'mo' for months, 'y' for years. .RE .PP \-m \fImaximum TTL\fR .RS 4 Sets the value to be used as the maximum TTL for the zone or zones being analyzed when determining whether there is a possibility of validation failure. When a zone\-signing key is deactivated, there must be enough time for the record in the zone with the longest TTL to have expired from resolver caches before that key can be purged from the DNSKEY RRset. If that condition does not apply, a warning will be generated. .sp The length of the TTL can be set in seconds, or in larger units of time by adding a suffix: 'mi' for minutes, 'h' for hours, 'd' for days, 'w' for weeks, 'mo' for months, 'y' for years. .sp This option is mandatory unless the \fB\-f\fR has been used to specify a zone file. (If \fB\-f\fR has been specified, this option may still be used; it will override the value found in the file.) .RE .PP \-d \fIDNSKEY TTL\fR .RS 4 Sets the value to be used as the DNSKEY TTL for the zone or zones being analyzed when determining whether there is a possibility of validation failure. When a key is rolled (that is, replaced with a new key), there must be enough time for the old DNSKEY RRset to have expired from resolver caches before the new key is activated and begins generating signatures. If that condition does not apply, a warning will be generated. .sp The length of the TTL can be set in seconds, or in larger units of time by adding a suffix: 'mi' for minutes, 'h' for hours, 'd' for days, 'w' for weeks, 'mo' for months, 'y' for years. .sp This option is mandatory unless the \fB\-f\fR has been used to specify a zone file, or a default key TTL was set with the \fB\-L\fR to \fBdnssec\-keygen\fR. (If either of those is true, this option may still be used; it will override the value found in the zone or key file.) .RE .PP \-r \fIresign interval\fR .RS 4 Sets the value to be used as the resign interval for the zone or zones being analyzed when determining whether there is a possibility of validation failure. This value defaults to 22.5 days, which is also the default in \fBnamed\fR. However, if it has been changed by the \fBsig\-validity\-interval\fR option in \fInamed.conf\fR, then it should also be changed here. .sp The length of the interval can be set in seconds, or in larger units of time by adding a suffix: 'mi' for minutes, 'h' for hours, 'd' for days, 'w' for weeks, 'mo' for months, 'y' for years. .RE .PP \-k .RS 4 Only check KSK coverage; ignore ZSK events. Cannot be used with \fB\-z\fR. .RE .PP \-z .RS 4 Only check ZSK coverage; ignore KSK events. Cannot be used with \fB\-k\fR. .RE .PP \-c \fIcompilezone path\fR .RS 4 Specifies a path to a \fBnamed\-compilezone\fR binary. Used for testing. .RE .SH "SEE ALSO" .PP \fBdnssec\-checkds\fR(8), \fBdnssec\-dsfromkey\fR(8), \fBdnssec\-keygen\fR(8), \fBdnssec\-signzone\fR(8) .SH "AUTHOR" .PP Internet Systems Consortium .SH "COPYRIGHT" Copyright \(co 2013, 2014 Internet Systems Consortium, Inc. ("ISC") .br bind9-9.10.3.dfsg.P4/bin/python/dnssec-coverage.py.in0000755000470500017500000007007712664710322021527 0ustar lamontlamont#!@PYTHON@ ############################################################################ # Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. ############################################################################ import argparse import os import glob import sys import re import time import calendar from collections import defaultdict import pprint prog='dnssec-coverage' # These routines permit platform-independent location of BIND 9 tools if os.name == 'nt': import win32con import win32api def prefix(bindir = ''): if os.name != 'nt': return os.path.join('@prefix@', bindir) bind_subkey = "Software\\ISC\\BIND" hKey = None keyFound = True try: hKey = win32api.RegOpenKeyEx(win32con.HKEY_LOCAL_MACHINE, bind_subkey) except: keyFound = False if keyFound: try: (namedBase, _) = win32api.RegQueryValueEx(hKey, "InstallDir") except: keyFound = False win32api.RegCloseKey(hKey) if keyFound: return os.path.join(namedBase, bindir) return os.path.join(win32api.GetSystemDirectory(), bindir) ######################################################################## # Class Event ######################################################################## class Event: """ A discrete key metadata event, e.g., Publish, Activate, Inactive, Delete. Stores the date of the event, and identifying information about the key to which the event will occur.""" def __init__(self, _what, _key): now = time.time() self.what = _what self.when = _key.metadata[_what] self.key = _key self.keyid = _key.keyid self.sep = _key.sep self.zone = _key.zone self.alg = _key.alg def __repr__(self): return repr((self.when, self.what, self.keyid, self.sep, self.zone, self.alg)) def showtime(self): return time.strftime("%a %b %d %H:%M:%S UTC %Y", self.when) def showkey(self): return self.key.showkey() def showkeytype(self): return self.key.showkeytype() ######################################################################## # Class Key ######################################################################## class Key: """An individual DNSSEC key. Identified by path, zone, algorithm, keyid. Contains a dictionary of metadata events.""" def __init__(self, keyname): directory = os.path.dirname(keyname) key = os.path.basename(keyname) (zone, alg, keyid) = key.split('+') keyid = keyid.split('.')[0] key = [zone, alg, keyid] key_file = directory + os.sep + '+'.join(key) + ".key" private_file = directory + os.sep + '+'.join(key) + ".private" self.zone = zone[1:-1] self.alg = int(alg) self.keyid = int(keyid) kfp = open(key_file, "r") for line in kfp: if line[0] == ';': continue tokens = line.split() if not tokens: continue if tokens[1].lower() in ('in', 'ch', 'hs'): septoken = 3 self.ttl = args.keyttl if not self.ttl: vspace() print("WARNING: Unable to determine TTL for DNSKEY %s." % self.showkey()) print("\t Using 1 day (86400 seconds); re-run with the -d " "option for more\n\t accurate results.") self.ttl = 86400 else: septoken = 4 self.ttl = int(tokens[1]) if not args.keyttl else args.keyttl if (int(tokens[septoken]) & 0x1) == 1: self.sep = True else: self.sep = False kfp.close() pfp = open(private_file, "rU") propDict = dict() for propLine in pfp: propDef = propLine.strip() if len(propDef) == 0: continue if propDef[0] in ('!', '#'): continue punctuation = [propDef.find(c) for c in ':= '] + [len(propDef)] found = min([ pos for pos in punctuation if pos != -1 ]) name = propDef[:found].rstrip() value = propDef[found:].lstrip(":= ").rstrip() propDict[name] = value if("Publish" in propDict): propDict["Publish"] = time.strptime(propDict["Publish"], "%Y%m%d%H%M%S") if("Activate" in propDict): propDict["Activate"] = time.strptime(propDict["Activate"], "%Y%m%d%H%M%S") if("Inactive" in propDict): propDict["Inactive"] = time.strptime(propDict["Inactive"], "%Y%m%d%H%M%S") if("Delete" in propDict): propDict["Delete"] = time.strptime(propDict["Delete"], "%Y%m%d%H%M%S") if("Revoke" in propDict): propDict["Revoke"] = time.strptime(propDict["Revoke"], "%Y%m%d%H%M%S") pfp.close() self.metadata = propDict def showkey(self): return "%s/%03d/%05d" % (self.zone, self.alg, self.keyid); def showkeytype(self): return ("KSK" if self.sep else "ZSK") # ensure that the gap between Publish and Activate is big enough def check_prepub(self): now = time.time() if (not "Activate" in self.metadata): debug_print("No Activate information in key: %s" % self.showkey()) return False a = calendar.timegm(self.metadata["Activate"]) if (not "Publish" in self.metadata): debug_print("No Publish information in key: %s" % self.showkey()) if a > now: vspace() print("WARNING: Key %s (%s) is scheduled for activation but \n" "\t not for publication." % (self.showkey(), self.showkeytype())) return False p = calendar.timegm(self.metadata["Publish"]) now = time.time() if p < now and a < now: return True if p == a: vspace() print ("WARNING: %s (%s) is scheduled to be published and\n" "\t activated at the same time. This could result in a\n" "\t coverage gap if the zone was previously signed." % (self.showkey(), self.showkeytype())) print("\t Activation should be at least %s after publication." % duration(self.ttl)) return True if a < p: vspace() print("WARNING: Key %s (%s) is active before it is published" % (self.showkey(), self.showkeytype())) return False if (a - p < self.ttl): vspace() print("WARNING: Key %s (%s) is activated too soon after\n" "\t publication; this could result in coverage gaps due to\n" "\t resolver caches containing old data." % (self.showkey(), self.showkeytype())) print("\t Activation should be at least %s after publication." % duration(self.ttl)) return False return True # ensure that the gap between Inactive and Delete is big enough def check_postpub(self, timespan = None): if not timespan: timespan = self.ttl now = time.time() if (not "Delete" in self.metadata): debug_print("No Delete information in key: %s" % self.showkey()) return False d = calendar.timegm(self.metadata["Delete"]) if (not "Inactive" in self.metadata): debug_print("No Inactive information in key: %s" % self.showkey()) if d > now: vspace() print("WARNING: Key %s (%s) is scheduled for deletion but\n" "\t not for inactivation." % (self.showkey(), self.showkeytype())) return False i = calendar.timegm(self.metadata["Inactive"]) if d < now and i < now: return True if (d < i): vspace() print("WARNING: Key %s (%s) is scheduled for deletion before\n" "\t inactivation." % (self.showkey(), self.showkeytype())) return False if (d - i < timespan): vspace() print("WARNING: Key %s (%s) scheduled for deletion too soon after\n" "\t deactivation; this may result in coverage gaps due to\n" "\t resolver caches containing old data." % (self.showkey(), self.showkeytype())) print("\t Deletion should be at least %s after inactivation." % duration(timespan)) return False return True ######################################################################## # class Zone ######################################################################## class Zone: """Stores data about a specific zone""" def __init__(self, _name, _keyttl = None, _maxttl = None): self.name = _name self.keyttl = _keyttl self.maxttl = _maxttl def load(self, filename): if not args.compilezone: sys.stderr.write(prog + ': FATAL: "named-compilezone" not found\n') exit(1) if not self.name: return maxttl = keyttl = None fp = os.popen("%s -o - %s %s 2> /dev/null" % (args.compilezone, self.name, filename)) for line in fp: fields = line.split() if not maxttl or int(fields[1]) > maxttl: maxttl = int(fields[1]) if fields[3] == "DNSKEY": keyttl = int(fields[1]) fp.close() self.keyttl = keyttl self.maxttl = maxttl ############################################################################ # debug_print: ############################################################################ def debug_print(debugVar): """pretty print a variable iff debug mode is enabled""" if not args.debug_mode: return if type(debugVar) == str: print("DEBUG: " + debugVar) else: print("DEBUG: " + pprint.pformat(debugVar)) return ############################################################################ # vspace: ############################################################################ _firstline = True def vspace(): """adds vertical space between two sections of output text if and only if this is *not* the first section being printed""" global _firstline if _firstline: _firstline = False else: print('') ############################################################################ # vreset: ############################################################################ def vreset(): """reset vertical spacing""" global _firstline _firstline = True ############################################################################ # getunit ############################################################################ def getunit(secs, size): """given a number of seconds, and a number of seconds in a larger unit of time, calculate how many of the larger unit there are and return both that and a remainder value""" bigunit = secs // size if bigunit: secs %= size return (bigunit, secs) ############################################################################ # addtime ############################################################################ def addtime(output, unit, t): """add a formatted unit of time to an accumulating string""" if t: output += ("%s%d %s%s" % ((", " if output else ""), t, unit, ("s" if t > 1 else ""))) return output ############################################################################ # duration: ############################################################################ def duration(secs): """given a length of time in seconds, print a formatted human duration in larger units of time """ # define units: minute = 60 hour = minute * 60 day = hour * 24 month = day * 30 year = day * 365 # calculate time in units: (years, secs) = getunit(secs, year) (months, secs) = getunit(secs, month) (days, secs) = getunit(secs, day) (hours, secs) = getunit(secs, hour) (minutes, secs) = getunit(secs, minute) output = '' output = addtime(output, "year", years) output = addtime(output, "month", months) output = addtime(output, "day", days) output = addtime(output, "hour", hours) output = addtime(output, "minute", minutes) output = addtime(output, "second", secs) return output ############################################################################ # parse_time ############################################################################ def parse_time(s): """convert a formatted time (e.g., 1y, 6mo, 15mi, etc) into seconds""" s = s.strip() # if s is an integer, we're done already try: n = int(s) return n except: pass # try to parse as a number with a suffix indicating unit of time r = re.compile('([0-9][0-9]*)\s*([A-Za-z]*)') m = r.match(s) if not m: raise Exception("Cannot parse %s" % s) (n, unit) = m.groups() n = int(n) unit = unit.lower() if unit[0] == 'y': return n * 31536000 elif unit[0] == 'm' and unit[1] == 'o': return n * 2592000 elif unit[0] == 'w': return n * 604800 elif unit[0] == 'd': return n * 86400 elif unit[0] == 'h': return n * 3600 elif unit[0] == 'm' and unit[1] == 'i': return n * 60 elif unit[0] == 's': return n else: raise Exception("Invalid suffix %s" % unit) ############################################################################ # algname: ############################################################################ def algname(alg): """return the mnemonic for a DNSSEC algorithm""" names = (None, 'RSAMD5', 'DH', 'DSA', 'ECC', 'RSASHA1', 'NSEC3DSA', 'NSEC3RSASHA1', 'RSASHA256', None, 'RSASHA512', None, 'ECCGOST', 'ECDSAP256SHA256', 'ECDSAP384SHA384') name = None if alg in range(len(names)): name = names[alg] return (name if name else str(alg)) ############################################################################ # list_events: ############################################################################ def list_events(eventgroup): """print a list of the events in an eventgroup""" if not eventgroup: return print (" " + eventgroup[0].showtime() + ":") for event in eventgroup: print (" %s: %s (%s)" % (event.what, event.showkey(), event.showkeytype())) ############################################################################ # process_events: ############################################################################ def process_events(eventgroup, active, published): """go through the events in an event group in time-order, add to active list upon Activate event, add to published list upon Publish event, remove from active list upon Inactive event, and remove from published upon Delete event. Emit warnings when inconsistant states are reached""" for event in eventgroup: if event.what == "Activate": active.add(event.keyid) elif event.what == "Publish": published.add(event.keyid) elif event.what == "Inactive": if event.keyid not in active: vspace() print ("\tWARNING: %s (%s) scheduled to become inactive " "before it is active" % (event.showkey(), event.showkeytype())) else: active.remove(event.keyid) elif event.what == "Delete": if event.keyid in published: published.remove(event.keyid) else: vspace() print ("WARNING: key %s (%s) is scheduled for deletion before " "it is published, at %s" % (event.showkey(), event.showkeytype())) elif event.what == "Revoke": # We don't need to worry about the logic of this one; # just stop counting this key as either active or published if event.keyid in published: published.remove(event.keyid) if event.keyid in active: active.remove(event.keyid) return (active, published) ############################################################################ # check_events: ############################################################################ def check_events(eventsList, ksk): """create lists of events happening at the same time, check for inconsistancies""" active = set() published = set() eventgroups = list() eventgroup = list() keytype = ("KSK" if ksk else "ZSK") # collect up all events that have the same time eventsfound = False for event in eventsList: # if checking ZSKs, skip KSKs, and vice versa if (ksk and not event.sep) or (event.sep and not ksk): continue # we found an appropriate (ZSK or KSK event) eventsfound = True # add event to current eventgroup if (not eventgroup or eventgroup[0].when == event.when): eventgroup.append(event) # if we're at the end of the list, we're done. if # we've found an event with a later time, start a new # eventgroup if (eventgroup[0].when != event.when): eventgroups.append(eventgroup) eventgroup = list() eventgroup.append(event) if eventgroup: eventgroups.append(eventgroup) for eventgroup in eventgroups: if (args.checklimit and calendar.timegm(eventgroup[0].when) > args.checklimit): print("Ignoring events after %s" % time.strftime("%a %b %d %H:%M:%S UTC %Y", time.gmtime(args.checklimit))) return True (active, published) = \ process_events(eventgroup, active, published) list_events(eventgroup) # and then check for inconsistencies: if len(active) == 0: print ("ERROR: No %s's are active after this event" % keytype) return False elif len(published) == 0: sys.stdout.write("ERROR: ") print ("ERROR: No %s's are published after this event" % keytype) return False elif len(published.intersection(active)) == 0: sys.stdout.write("ERROR: ") print (("ERROR: No %s's are both active and published " + "after this event") % keytype) return False if not eventsfound: print ("ERROR: No %s events found in '%s'" % (keytype, args.path)) return False return True ############################################################################ # check_zones: # ############################################################################ def check_zones(eventsList): """scan events per zone, algorithm, and key type, in order of occurrance, noting inconsistent states when found""" global foundprob foundprob = False zonesfound = False for zone in eventsList: if args.zone and zone != args.zone: continue zonesfound = True for alg in eventsList[zone]: if not args.no_ksk: vspace() print("Checking scheduled KSK events for zone %s, algorithm %s..." % (zone, algname(alg))) if not check_events(eventsList[zone][alg], True): foundprob = True else: print ("No errors found") if not args.no_zsk: vspace() print("Checking scheduled ZSK events for zone %s, algorithm %s..." % (zone, algname(alg))) if not check_events(eventsList[zone][alg], False): foundprob = True else: print ("No errors found") if not zonesfound: print("ERROR: No key events found for %s in '%s'" % (args.zone, args.path)) exit(1) ############################################################################ # fill_eventsList: ############################################################################ def fill_eventsList(eventsList): """populate the list of events""" for zone, algorithms in keyDict.items(): for alg, keys in algorithms.items(): for keyid, keydata in keys.items(): if("Publish" in keydata.metadata): eventsList[zone][alg].append(Event("Publish", keydata)) if("Activate" in keydata.metadata): eventsList[zone][alg].append(Event("Activate", keydata)) if("Inactive" in keydata.metadata): eventsList[zone][alg].append(Event("Inactive", keydata)) if("Delete" in keydata.metadata): eventsList[zone][alg].append(Event("Delete", keydata)) eventsList[zone][alg] = sorted(eventsList[zone][alg], key=lambda event: event.when) foundprob = False if not keyDict: print("ERROR: No key events found in '%s'" % args.path) exit(1) ############################################################################ # set_path: ############################################################################ def set_path(command, default=None): """find the location of a specified command. if a default is supplied and it works, we use it; otherwise we search PATH for a match. If not found, error and exit""" fpath = default if not fpath or not os.path.isfile(fpath) or not os.access(fpath, os.X_OK): path = os.environ["PATH"] if not path: path = os.path.defpath for directory in path.split(os.pathsep): fpath = directory + os.sep + command if os.path.isfile(fpath) or os.access(fpath, os.X_OK): break fpath = None return fpath ############################################################################ # parse_args: ############################################################################ def parse_args(): """Read command line arguments, set global 'args' structure""" global args compilezone = set_path('named-compilezone', os.path.join(prefix('bin'), 'named-compilezone')) parser = argparse.ArgumentParser(description=prog + ': checks future ' + 'DNSKEY coverage for a zone') parser.add_argument('zone', type=str, help='zone to check') parser.add_argument('-K', dest='path', default='.', type=str, help='a directory containing keys to process', metavar='dir') parser.add_argument('-f', dest='filename', type=str, help='zone master file', metavar='file') parser.add_argument('-m', dest='maxttl', type=str, help='the longest TTL in the zone(s)', metavar='time') parser.add_argument('-d', dest='keyttl', type=str, help='the DNSKEY TTL', metavar='time') parser.add_argument('-r', dest='resign', default='1944000', type=str, help='the RRSIG refresh interval ' 'in seconds [default: 22.5 days]', metavar='time') parser.add_argument('-c', dest='compilezone', default=compilezone, type=str, help='path to \'named-compilezone\'', metavar='path') parser.add_argument('-l', dest='checklimit', type=str, default='0', help='Length of time to check for ' 'DNSSEC coverage [default: 0 (unlimited)]', metavar='time') parser.add_argument('-z', dest='no_ksk', action='store_true', default=False, help='Only check zone-signing keys (ZSKs)') parser.add_argument('-k', dest='no_zsk', action='store_true', default=False, help='Only check key-signing keys (KSKs)') parser.add_argument('-D', '--debug', dest='debug_mode', action='store_true', default=False, help='Turn on debugging output') parser.add_argument('-v', '--version', action='version', version='9.9.1') args = parser.parse_args() if args.no_zsk and args.no_ksk: print("ERROR: -z and -k cannot be used together."); exit(1) # convert from time arguments to seconds try: if args.maxttl: m = parse_time(args.maxttl) args.maxttl = m except: pass try: if args.keyttl: k = parse_time(args.keyttl) args.keyttl = k except: pass try: if args.resign: r = parse_time(args.resign) args.resign = r except: pass try: if args.checklimit: lim = args.checklimit r = parse_time(args.checklimit) if r == 0: args.checklimit = None else: args.checklimit = time.time() + r except: pass # if we've got the values we need from the command line, stop now if args.maxttl and args.keyttl: return # load keyttl and maxttl data from zonefile if args.zone and args.filename: try: zone = Zone(args.zone) zone.load(args.filename) if not args.maxttl: args.maxttl = zone.maxttl if not args.keyttl: args.keyttl = zone.maxttl except Exception as e: print("Unable to load zone data from %s: " % args.filename, e) if not args.maxttl: vspace() print ("WARNING: Maximum TTL value was not specified. Using 1 week\n" "\t (604800 seconds); re-run with the -m option to get more\n" "\t accurate results.") args.maxttl = 604800 ############################################################################ # Main ############################################################################ def main(): global keyDict parse_args() path=args.path print ("PHASE 1--Loading keys to check for internal timing problems") keyDict = defaultdict(lambda : defaultdict(dict)) files = glob.glob(os.path.join(path, '*.private')) for infile in files: key = Key(infile) if args.zone and key.zone != args.zone: continue keyDict[key.zone][key.alg][key.keyid] = key key.check_prepub() if key.sep: key.check_postpub() else: key.check_postpub(args.maxttl + args.resign) vspace() print ("PHASE 2--Scanning future key events for coverage failures") vreset() eventsList = defaultdict(lambda : defaultdict(list)) fill_eventsList(eventsList) check_zones(eventsList) if foundprob: exit(1) else: exit(0) if __name__ == "__main__": main() bind9-9.10.3.dfsg.P4/bin/python/dnssec-checkds.py.in0000644000470500017500000002524112664710322021326 0ustar lamontlamont#!@PYTHON@ ############################################################################ # Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. ############################################################################ import argparse import pprint import os prog='dnssec-checkds' # These routines permit platform-independent location of BIND 9 tools if os.name == 'nt': import win32con import win32api def prefix(bindir = ''): if os.name != 'nt': return os.path.join('@prefix@', bindir) bind_subkey = "Software\\ISC\\BIND" hKey = None keyFound = True try: hKey = win32api.RegOpenKeyEx(win32con.HKEY_LOCAL_MACHINE, bind_subkey) except: keyFound = False if keyFound: try: (namedBase, _) = win32api.RegQueryValueEx(hKey, "InstallDir") except: keyFound = False win32api.RegCloseKey(hKey) if keyFound: return os.path.join(namedBase, bindir) return os.path.join(win32api.GetSystemDirectory(), bindir) def shellquote(s): if os.name == 'nt': return '"' + s.replace('"', '"\\"') + '"' return "'" + s.replace("'", "'\\''") + "'" ############################################################################ # DSRR class: # Delegation Signer (DS) resource record ############################################################################ class DSRR: hashalgs = {1: 'SHA-1', 2: 'SHA-256', 3: 'GOST', 4: 'SHA-384' } rrname='' rrclass='IN' rrtype='DS' keyid=None keyalg=None hashalg=None digest='' ttl=0 def __init__(self, rrtext): if not rrtext: return fields = rrtext.split() if len(fields) < 7: return self.rrname = fields[0].lower() fields = fields[1:] if fields[0].upper() in ['IN','CH','HS']: self.rrclass = fields[0].upper() fields = fields[1:] else: self.ttl = int(fields[0]) self.rrclass = fields[1].upper() fields = fields[2:] if fields[0].upper() != 'DS': raise Exception self.rrtype = 'DS' self.keyid = int(fields[1]) self.keyalg = int(fields[2]) self.hashalg = int(fields[3]) self.digest = ''.join(fields[4:]).upper() def __repr__(self): return('%s %s %s %d %d %d %s' % (self.rrname, self.rrclass, self.rrtype, self.keyid, self.keyalg, self.hashalg, self.digest)) def __eq__(self, other): return self.__repr__() == other.__repr__() ############################################################################ # DLVRR class: # DNSSEC Lookaside Validation (DLV) resource record ############################################################################ class DLVRR: hashalgs = {1: 'SHA-1', 2: 'SHA-256', 3: 'GOST', 4: 'SHA-384' } parent='' dlvname='' rrname='IN' rrclass='IN' rrtype='DLV' keyid=None keyalg=None hashalg=None digest='' ttl=0 def __init__(self, rrtext, dlvname): if not rrtext: return fields = rrtext.split() if len(fields) < 7: return self.dlvname = dlvname.lower() parent = fields[0].lower().strip('.').split('.') parent.reverse() dlv = dlvname.split('.') dlv.reverse() while len(dlv) != 0 and len(parent) != 0 and parent[0] == dlv[0]: parent = parent[1:] dlv = dlv[1:] if len(dlv) != 0: raise Exception parent.reverse() self.parent = '.'.join(parent) self.rrname = self.parent + '.' + self.dlvname + '.' fields = fields[1:] if fields[0].upper() in ['IN','CH','HS']: self.rrclass = fields[0].upper() fields = fields[1:] else: self.ttl = int(fields[0]) self.rrclass = fields[1].upper() fields = fields[2:] if fields[0].upper() != 'DLV': raise Exception self.rrtype = 'DLV' self.keyid = int(fields[1]) self.keyalg = int(fields[2]) self.hashalg = int(fields[3]) self.digest = ''.join(fields[4:]).upper() def __repr__(self): return('%s %s %s %d %d %d %s' % (self.rrname, self.rrclass, self.rrtype, self.keyid, self.keyalg, self.hashalg, self.digest)) def __eq__(self, other): return self.__repr__() == other.__repr__() ############################################################################ # checkds: # Fetch DS RRset for the given zone from the DNS; fetch DNSKEY # RRset from the masterfile if specified, or from DNS if not. # Generate a set of expected DS records from the DNSKEY RRset, # and report on congruency. ############################################################################ def checkds(zone, masterfile = None): dslist=[] fp=os.popen("%s +noall +answer -t ds -q %s" % (shellquote(args.dig), shellquote(zone))) for line in fp: dslist.append(DSRR(line)) dslist = sorted(dslist, key=lambda ds: (ds.keyid, ds.keyalg, ds.hashalg)) fp.close() dsklist=[] if masterfile: fp = os.popen("%s -f %s %s " % (shellquote(args.dsfromkey), shellquote(masterfile), shellquote(zone))) else: fp = os.popen("%s +noall +answer -t dnskey -q %s | %s -f - %s" % (shellquote(args.dig), shellquote(zone), shellquote(args.dsfromkey), shellquote(zone))) for line in fp: dsklist.append(DSRR(line)) fp.close() if (len(dsklist) < 1): print ("No DNSKEY records found in zone apex") return False found = False for ds in dsklist: if ds in dslist: print ("DS for KSK %s/%03d/%05d (%s) found in parent" % (ds.rrname.strip('.'), ds.keyalg, ds.keyid, DSRR.hashalgs[ds.hashalg])) found = True else: print ("DS for KSK %s/%03d/%05d (%s) missing from parent" % (ds.rrname.strip('.'), ds.keyalg, ds.keyid, DSRR.hashalgs[ds.hashalg])) if not found: print ("No DS records were found for any DNSKEY") return found ############################################################################ # checkdlv: # Fetch DLV RRset for the given zone from the DNS; fetch DNSKEY # RRset from the masterfile if specified, or from DNS if not. # Generate a set of expected DLV records from the DNSKEY RRset, # and report on congruency. ############################################################################ def checkdlv(zone, lookaside, masterfile = None): dlvlist=[] fp=os.popen("%s +noall +answer -t dlv -q %s" % (shellquote(args.dig), shellquote(zone + '.' + lookaside))) for line in fp: dlvlist.append(DLVRR(line, lookaside)) dlvlist = sorted(dlvlist, key=lambda dlv: (dlv.keyid, dlv.keyalg, dlv.hashalg)) fp.close() # # Fetch DNSKEY records from DNS and generate DLV records from them # dlvklist=[] if masterfile: fp = os.popen("%s -f %s -l %s %s " % (args.dsfromkey, masterfile, lookaside, zone)) else: fp = os.popen("%s +noall +answer -t dnskey %s | %s -f - -l %s %s" % (shellquote(args.dig), shellquote(zone), shellquote(args.dsfromkey), shellquote(lookaside), shellquote(zone))) for line in fp: dlvklist.append(DLVRR(line, lookaside)) fp.close() if (len(dlvklist) < 1): print ("No DNSKEY records found in zone apex") return False found = False for dlv in dlvklist: if dlv in dlvlist: print ("DLV for KSK %s/%03d/%05d (%s) found in %s" % (dlv.parent, dlv.keyalg, dlv.keyid, DLVRR.hashalgs[dlv.hashalg], dlv.dlvname)) found = True else: print ("DLV for KSK %s/%03d/%05d (%s) missing from %s" % (dlv.parent, dlv.keyalg, dlv.keyid, DLVRR.hashalgs[dlv.hashalg], dlv.dlvname)) if not found: print ("No DLV records were found for any DNSKEY") return found ############################################################################ # parse_args: # Read command line arguments, set global 'args' structure ############################################################################ def parse_args(): global args parser = argparse.ArgumentParser(description=prog + ': checks DS coverage') bindir = 'bin' if os.name == 'nt': sbindir = 'bin' else: sbindir = 'sbin' parser.add_argument('zone', type=str, help='zone to check') parser.add_argument('-f', '--file', dest='masterfile', type=str, help='zone master file') parser.add_argument('-l', '--lookaside', dest='lookaside', type=str, help='DLV lookaside zone') parser.add_argument('-d', '--dig', dest='dig', default=os.path.join(prefix(bindir), 'dig'), type=str, help='path to \'dig\'') parser.add_argument('-D', '--dsfromkey', dest='dsfromkey', default=os.path.join(prefix(sbindir), 'dnssec-dsfromkey'), type=str, help='path to \'dig\'') parser.add_argument('-v', '--version', action='version', version='9.9.1') args = parser.parse_args() args.zone = args.zone.strip('.') if args.lookaside: lookaside = args.lookaside.strip('.') ############################################################################ # Main ############################################################################ def main(): parse_args() if args.lookaside: found = checkdlv(args.zone, args.lookaside, args.masterfile) else: found = checkds(args.zone, args.masterfile) exit(0 if found else 1) if __name__ == "__main__": main() bind9-9.10.3.dfsg.P4/bin/python/dnssec-checkds.docbook0000644000470500017500000001200312664710322021701 0ustar lamontlamont]> January 01, 2013 dnssec-checkds 8 BIND9 dnssec-checkds A DNSSEC delegation consistency checking tool. 2012 2013 2014 Internet Systems Consortium, Inc. ("ISC") dnssec-checkds zone dnssec-dsfromkey zone DESCRIPTION dnssec-checkds verifies the correctness of Delegation Signer (DS) or DNSSEC Lookaside Validation (DLV) resource records for keys in a specified zone. OPTIONS -f file If a is specified, then the zone is read from that file to find the DNSKEY records. If not, then the DNSKEY records for the zone are looked up in the DNS. -l domain Check for a DLV record in the specified lookaside domain, instead of checking for a DS record in the zone's parent. For example, to check for DLV records for "example.com" in ISC's DLV zone, use: dnssec-checkds -l dlv.isc.org example.com -d dig path Specifies a path to a dig binary. Used for testing. -D dsfromkey path Specifies a path to a dnssec-dsfromkey binary. Used for testing. SEE ALSO dnssec-dsfromkey8 , dnssec-keygen8 , dnssec-signzone8 , AUTHOR Internet Systems Consortium bind9-9.10.3.dfsg.P4/bin/python/dnssec-checkds.html0000644000470500017500000001065212664710322021235 0ustar lamontlamont dnssec-checkds

Name

dnssec-checkds — A DNSSEC delegation consistency checking tool.

Synopsis

dnssec-checkds [-l domain] [-f file] [-d dig path] [-D dsfromkey path] {zone}

dnssec-dsfromkey [-l domain] [-f file] [-d dig path] [-D dsfromkey path] {zone}

DESCRIPTION

dnssec-checkds verifies the correctness of Delegation Signer (DS) or DNSSEC Lookaside Validation (DLV) resource records for keys in a specified zone.

OPTIONS

-f file

If a file is specified, then the zone is read from that file to find the DNSKEY records. If not, then the DNSKEY records for the zone are looked up in the DNS.

-l domain

Check for a DLV record in the specified lookaside domain, instead of checking for a DS record in the zone's parent. For example, to check for DLV records for "example.com" in ISC's DLV zone, use: dnssec-checkds -l dlv.isc.org example.com

-d dig path

Specifies a path to a dig binary. Used for testing.

-D dsfromkey path

Specifies a path to a dnssec-dsfromkey binary. Used for testing.

SEE ALSO

dnssec-dsfromkey(8), dnssec-keygen(8), dnssec-signzone(8),

AUTHOR

Internet Systems Consortium

bind9-9.10.3.dfsg.P4/bin/python/dnssec-checkds.80000644000470500017500000000524412664710322020441 0ustar lamontlamont.\" Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC") .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: dnssec\-checkds .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: January 01, 2013 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "DNSSEC\-CHECKDS" "8" "January 01, 2013" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" dnssec\-checkds \- A DNSSEC delegation consistency checking tool. .SH "SYNOPSIS" .HP 15 \fBdnssec\-checkds\fR [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-f\ \fR\fB\fIfile\fR\fR] [\fB\-d\ \fR\fB\fIdig\ path\fR\fR] [\fB\-D\ \fR\fB\fIdsfromkey\ path\fR\fR] {zone} .HP 17 \fBdnssec\-dsfromkey\fR [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-f\ \fR\fB\fIfile\fR\fR] [\fB\-d\ \fR\fB\fIdig\ path\fR\fR] [\fB\-D\ \fR\fB\fIdsfromkey\ path\fR\fR] {zone} .SH "DESCRIPTION" .PP \fBdnssec\-checkds\fR verifies the correctness of Delegation Signer (DS) or DNSSEC Lookaside Validation (DLV) resource records for keys in a specified zone. .SH "OPTIONS" .PP \-f \fIfile\fR .RS 4 If a \fBfile\fR is specified, then the zone is read from that file to find the DNSKEY records. If not, then the DNSKEY records for the zone are looked up in the DNS. .RE .PP \-l \fIdomain\fR .RS 4 Check for a DLV record in the specified lookaside domain, instead of checking for a DS record in the zone's parent. For example, to check for DLV records for "example.com" in ISC's DLV zone, use: \fBdnssec\-checkds \-l dlv.isc.org example.com\fR .RE .PP \-d \fIdig path\fR .RS 4 Specifies a path to a \fBdig\fR binary. Used for testing. .RE .PP \-D \fIdsfromkey path\fR .RS 4 Specifies a path to a \fBdnssec\-dsfromkey\fR binary. Used for testing. .RE .SH "SEE ALSO" .PP \fBdnssec\-dsfromkey\fR(8), \fBdnssec\-keygen\fR(8), \fBdnssec\-signzone\fR(8), .SH "AUTHOR" .PP Internet Systems Consortium .SH "COPYRIGHT" Copyright \(co 2012\-2014 Internet Systems Consortium, Inc. ("ISC") .br bind9-9.10.3.dfsg.P4/bin/check/0002755000470500017500000000000012672612753015230 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/check/named-checkconf.html0000644000470500017500000001317312664710322021116 0ustar lamontlamont named-checkconf

Name

named-checkconf — named configuration file syntax checking tool

Synopsis

named-checkconf [-h] [-v] [-j] [-t directory] {filename} [-p] [-x] [-z]

DESCRIPTION

named-checkconf checks the syntax, but not the semantics, of a named configuration file. The file is parsed and checked for syntax errors, along with all files included by it. If no file is specified, /etc/named.conf is read by default.

Note: files that named reads in separate parser contexts, such as rndc.key and bind.keys, are not automatically read by named-checkconf. Configuration errors in these files may cause named to fail to run, even if named-checkconf was successful. named-checkconf can be run on these files explicitly, however.

OPTIONS

-h

Print the usage summary and exit.

-t directory

Chroot to directory so that include directives in the configuration file are processed as if run by a similarly chrooted named.

-v

Print the version of the named-checkconf program and exit.

-p

Print out the named.conf and included files in canonical form if no errors were detected.

-x

When printing the configuration files in canonical form, obscure shared secrets by replacing them with strings of question marks ('?'). This allows the contents of named.conf and related files to be shared — for example, when submitting bug reports — without compromising private data. This option cannot be used without -p.

-z

Perform a test load of all master zones found in named.conf.

-j

When loading a zonefile read the journal if it exists.

filename

The name of the configuration file to be checked. If not specified, it defaults to /etc/named.conf.

RETURN VALUES

named-checkconf returns an exit status of 1 if errors were detected and 0 otherwise.

SEE ALSO

named(8), named-checkzone(8), BIND 9 Administrator Reference Manual.

AUTHOR

Internet Systems Consortium

bind9-9.10.3.dfsg.P4/bin/check/Makefile.in0000644000470500017500000000672512664710322017275 0ustar lamontlamont# Copyright (C) 2004-2007, 2009, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000-2003 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.36 2009/12/05 23:31:40 each Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ @BIND9_MAKE_INCLUDES@ CINCLUDES = ${BIND9_INCLUDES} ${DNS_INCLUDES} ${ISCCFG_INCLUDES} \ ${ISC_INCLUDES} CDEFINES = -DNAMED_CONFFILE=\"${sysconfdir}/named.conf\" CWARNINGS = DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@ ISCLIBS = ../../lib/isc/libisc.@A@ ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@ BIND9LIBS = ../../lib/bind9/libbind9.@A@ DNSDEPLIBS = ../../lib/dns/libdns.@A@ ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@ ISCDEPLIBS = ../../lib/isc/libisc.@A@ BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@ LIBS = ${ISCLIBS} @LIBS@ NOSYMLIBS = ${ISCNOSYMLIBS} @LIBS@ SUBDIRS = # Alphabetically TARGETS = named-checkconf@EXEEXT@ named-checkzone@EXEEXT@ # Alphabetically SRCS = named-checkconf.c named-checkzone.c check-tool.c MANPAGES = named-checkconf.8 named-checkzone.8 HTMLPAGES = named-checkconf.html named-checkzone.html MANOBJS = ${MANPAGES} ${HTMLPAGES} @BIND9_MAKE_RULES@ named-checkconf.@O@: named-checkconf.c ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ -DVERSION=\"${VERSION}\" \ -c ${srcdir}/named-checkconf.c named-checkzone.@O@: named-checkzone.c ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ -DVERSION=\"${VERSION}\" \ -c ${srcdir}/named-checkzone.c named-checkconf@EXEEXT@: named-checkconf.@O@ check-tool.@O@ ${ISCDEPLIBS} \ ${DNSDEPLIBS} ${ISCCFGDEPLIBS} ${BIND9DEPLIBS} export BASEOBJS="named-checkconf.@O@ check-tool.@O@"; \ export LIBS0="${BIND9LIBS} ${ISCCFGLIBS} ${DNSLIBS}"; \ ${FINALBUILDCMD} named-checkzone@EXEEXT@: named-checkzone.@O@ check-tool.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} export BASEOBJS="named-checkzone.@O@ check-tool.@O@"; \ export LIBS0="${ISCCFGLIBS} ${DNSLIBS}"; \ ${FINALBUILDCMD} doc man:: ${MANOBJS} docclean manclean maintainer-clean:: rm -f ${MANOBJS} installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 install:: named-checkconf@EXEEXT@ named-checkzone@EXEEXT@ installdirs ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named-checkconf@EXEEXT@ ${DESTDIR}${sbindir} ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named-checkzone@EXEEXT@ ${DESTDIR}${sbindir} (cd ${DESTDIR}${sbindir}; rm -f named-compilezone@EXEEXT@; ${LINK_PROGRAM} named-checkzone@EXEEXT@ named-compilezone@EXEEXT@) for m in ${MANPAGES}; do ${INSTALL_DATA} ${srcdir}/$$m ${DESTDIR}${mandir}/man8; done (cd ${DESTDIR}${mandir}/man8; rm -f named-compilezone.8; ${LINK_PROGRAM} named-checkzone.8 named-compilezone.8) clean distclean:: rm -f ${TARGETS} r1.htm bind9-9.10.3.dfsg.P4/bin/check/check-tool.h0000644000470500017500000000362412664710322017424 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2010, 2011, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: check-tool.h,v 1.18 2011/12/09 23:47:02 tbox Exp $ */ #ifndef CHECK_TOOL_H #define CHECK_TOOL_H /*! \file */ #include #include #include #include #include ISC_LANG_BEGINDECLS isc_result_t setup_logging(isc_mem_t *mctx, FILE *errout, isc_log_t **logp); isc_result_t load_zone(isc_mem_t *mctx, const char *zonename, const char *filename, dns_masterformat_t fileformat, const char *classname, dns_ttl_t maxttl, dns_zone_t **zonep); isc_result_t dump_zone(const char *zonename, dns_zone_t *zone, const char *filename, dns_masterformat_t fileformat, const dns_master_style_t *style, const isc_uint32_t rawversion); #ifdef _WIN32 void InitSockets(void); void DestroySockets(void); #endif extern int debug; extern const char *journal; extern isc_boolean_t nomerge; extern isc_boolean_t docheckmx; extern isc_boolean_t docheckns; extern isc_boolean_t dochecksrv; extern unsigned int zone_options; extern unsigned int zone_options2; ISC_LANG_ENDDECLS #endif bind9-9.10.3.dfsg.P4/bin/check/named-checkzone.c0000644000470500017500000003474612664710322020433 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: named-checkzone.c,v 1.65.32.2 2012/02/07 02:45:21 each Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "check-tool.h" static int quiet = 0; static isc_mem_t *mctx = NULL; static isc_entropy_t *ectx = NULL; dns_zone_t *zone = NULL; dns_zonetype_t zonetype = dns_zone_master; static int dumpzone = 0; static const char *output_filename; static char *prog_name = NULL; static const dns_master_style_t *outputstyle = NULL; static enum { progmode_check, progmode_compile } progmode; #define ERRRET(result, function) \ do { \ if (result != ISC_R_SUCCESS) { \ if (!quiet) \ fprintf(stderr, "%s() returned %s\n", \ function, dns_result_totext(result)); \ return (result); \ } \ } while (0) ISC_PLATFORM_NORETURN_PRE static void usage(void) ISC_PLATFORM_NORETURN_POST; static void usage(void) { fprintf(stderr, "usage: %s [-djqvD] [-c class] " "[-f inputformat] [-F outputformat] [-J filename] " "[-t directory] [-w directory] [-k (ignore|warn|fail)] " "[-n (ignore|warn|fail)] [-m (ignore|warn|fail)] " "[-r (ignore|warn|fail)] " "[-i (full|full-sibling|local|local-sibling|none)] " "[-M (ignore|warn|fail)] [-S (ignore|warn|fail)] " "[-W (ignore|warn)] " "%s zonename filename\n", prog_name, progmode == progmode_check ? "[-o filename]" : "-o filename"); exit(1); } static void destroy(void) { if (zone != NULL) dns_zone_detach(&zone); dns_name_destroy(); } /*% main processing routine */ int main(int argc, char **argv) { int c; char *origin = NULL; char *filename = NULL; isc_log_t *lctx = NULL; isc_result_t result; char classname_in[] = "IN"; char *classname = classname_in; const char *workdir = NULL; const char *inputformatstr = NULL; const char *outputformatstr = NULL; dns_masterformat_t inputformat = dns_masterformat_text; dns_masterformat_t outputformat = dns_masterformat_text; dns_masterrawheader_t header; isc_uint32_t rawversion = 1, serialnum = 0; dns_ttl_t maxttl = 0; isc_boolean_t snset = ISC_FALSE; isc_boolean_t logdump = ISC_FALSE; FILE *errout = stdout; char *endp; /* * Uncomment the following line if memory debugging is needed: * isc_mem_debugging |= ISC_MEM_DEBUGRECORD; */ outputstyle = &dns_master_style_full; prog_name = strrchr(argv[0], '/'); if (prog_name == NULL) prog_name = strrchr(argv[0], '\\'); if (prog_name != NULL) prog_name++; else prog_name = argv[0]; /* * Libtool doesn't preserve the program name prior to final * installation. Remove the libtool prefix ("lt-"). */ if (strncmp(prog_name, "lt-", 3) == 0) prog_name += 3; #define PROGCMP(X) \ (strcasecmp(prog_name, X) == 0 || strcasecmp(prog_name, X ".exe") == 0) if (PROGCMP("named-checkzone")) progmode = progmode_check; else if (PROGCMP("named-compilezone")) progmode = progmode_compile; else INSIST(0); /* Compilation specific defaults */ if (progmode == progmode_compile) { zone_options |= (DNS_ZONEOPT_CHECKNS | DNS_ZONEOPT_FATALNS | DNS_ZONEOPT_CHECKSPF | DNS_ZONEOPT_CHECKDUPRR | DNS_ZONEOPT_CHECKNAMES | DNS_ZONEOPT_CHECKNAMESFAIL | DNS_ZONEOPT_CHECKWILDCARD); } else zone_options |= (DNS_ZONEOPT_CHECKDUPRR | DNS_ZONEOPT_CHECKSPF); #define ARGCMP(X) (strcmp(isc_commandline_argument, X) == 0) isc_commandline_errprint = ISC_FALSE; while ((c = isc_commandline_parse(argc, argv, "c:df:hi:jJ:k:L:l:m:n:qr:s:t:o:vw:DF:M:S:T:W:")) != EOF) { switch (c) { case 'c': classname = isc_commandline_argument; break; case 'd': debug++; break; case 'i': if (ARGCMP("full")) { zone_options |= DNS_ZONEOPT_CHECKINTEGRITY | DNS_ZONEOPT_CHECKSIBLING; docheckmx = ISC_TRUE; docheckns = ISC_TRUE; dochecksrv = ISC_TRUE; } else if (ARGCMP("full-sibling")) { zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; docheckmx = ISC_TRUE; docheckns = ISC_TRUE; dochecksrv = ISC_TRUE; } else if (ARGCMP("local")) { zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; zone_options |= DNS_ZONEOPT_CHECKSIBLING; docheckmx = ISC_FALSE; docheckns = ISC_FALSE; dochecksrv = ISC_FALSE; } else if (ARGCMP("local-sibling")) { zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; docheckmx = ISC_FALSE; docheckns = ISC_FALSE; dochecksrv = ISC_FALSE; } else if (ARGCMP("none")) { zone_options &= ~DNS_ZONEOPT_CHECKINTEGRITY; zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; docheckmx = ISC_FALSE; docheckns = ISC_FALSE; dochecksrv = ISC_FALSE; } else { fprintf(stderr, "invalid argument to -i: %s\n", isc_commandline_argument); exit(1); } break; case 'f': inputformatstr = isc_commandline_argument; break; case 'F': outputformatstr = isc_commandline_argument; break; case 'j': nomerge = ISC_FALSE; break; case 'J': journal = isc_commandline_argument; nomerge = ISC_FALSE; break; case 'k': if (ARGCMP("warn")) { zone_options |= DNS_ZONEOPT_CHECKNAMES; zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL; } else if (ARGCMP("fail")) { zone_options |= DNS_ZONEOPT_CHECKNAMES | DNS_ZONEOPT_CHECKNAMESFAIL; } else if (ARGCMP("ignore")) { zone_options &= ~(DNS_ZONEOPT_CHECKNAMES | DNS_ZONEOPT_CHECKNAMESFAIL); } else { fprintf(stderr, "invalid argument to -k: %s\n", isc_commandline_argument); exit(1); } break; case 'L': snset = ISC_TRUE; endp = NULL; serialnum = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') { fprintf(stderr, "source serial number " "must be numeric"); exit(1); } break; case 'l': zone_options2 |= DNS_ZONEOPT2_CHECKTTL; endp = NULL; maxttl = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') { fprintf(stderr, "maximum TTL " "must be numeric"); exit(1); } break; case 'n': if (ARGCMP("ignore")) { zone_options &= ~(DNS_ZONEOPT_CHECKNS| DNS_ZONEOPT_FATALNS); } else if (ARGCMP("warn")) { zone_options |= DNS_ZONEOPT_CHECKNS; zone_options &= ~DNS_ZONEOPT_FATALNS; } else if (ARGCMP("fail")) { zone_options |= DNS_ZONEOPT_CHECKNS| DNS_ZONEOPT_FATALNS; } else { fprintf(stderr, "invalid argument to -n: %s\n", isc_commandline_argument); exit(1); } break; case 'm': if (ARGCMP("warn")) { zone_options |= DNS_ZONEOPT_CHECKMX; zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; } else if (ARGCMP("fail")) { zone_options |= DNS_ZONEOPT_CHECKMX | DNS_ZONEOPT_CHECKMXFAIL; } else if (ARGCMP("ignore")) { zone_options &= ~(DNS_ZONEOPT_CHECKMX | DNS_ZONEOPT_CHECKMXFAIL); } else { fprintf(stderr, "invalid argument to -m: %s\n", isc_commandline_argument); exit(1); } break; case 'o': output_filename = isc_commandline_argument; break; case 'q': quiet++; break; case 'r': if (ARGCMP("warn")) { zone_options |= DNS_ZONEOPT_CHECKDUPRR; zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL; } else if (ARGCMP("fail")) { zone_options |= DNS_ZONEOPT_CHECKDUPRR | DNS_ZONEOPT_CHECKDUPRRFAIL; } else if (ARGCMP("ignore")) { zone_options &= ~(DNS_ZONEOPT_CHECKDUPRR | DNS_ZONEOPT_CHECKDUPRRFAIL); } else { fprintf(stderr, "invalid argument to -r: %s\n", isc_commandline_argument); exit(1); } break; case 's': if (ARGCMP("full")) outputstyle = &dns_master_style_full; else if (ARGCMP("relative")) { outputstyle = &dns_master_style_default; } else { fprintf(stderr, "unknown or unsupported style: %s\n", isc_commandline_argument); exit(1); } break; case 't': result = isc_dir_chroot(isc_commandline_argument); if (result != ISC_R_SUCCESS) { fprintf(stderr, "isc_dir_chroot: %s: %s\n", isc_commandline_argument, isc_result_totext(result)); exit(1); } break; case 'v': printf(VERSION "\n"); exit(0); case 'w': workdir = isc_commandline_argument; break; case 'D': dumpzone++; break; case 'M': if (ARGCMP("fail")) { zone_options &= ~DNS_ZONEOPT_WARNMXCNAME; zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; } else if (ARGCMP("warn")) { zone_options |= DNS_ZONEOPT_WARNMXCNAME; zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; } else if (ARGCMP("ignore")) { zone_options |= DNS_ZONEOPT_WARNMXCNAME; zone_options |= DNS_ZONEOPT_IGNOREMXCNAME; } else { fprintf(stderr, "invalid argument to -M: %s\n", isc_commandline_argument); exit(1); } break; case 'S': if (ARGCMP("fail")) { zone_options &= ~DNS_ZONEOPT_WARNSRVCNAME; zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; } else if (ARGCMP("warn")) { zone_options |= DNS_ZONEOPT_WARNSRVCNAME; zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; } else if (ARGCMP("ignore")) { zone_options |= DNS_ZONEOPT_WARNSRVCNAME; zone_options |= DNS_ZONEOPT_IGNORESRVCNAME; } else { fprintf(stderr, "invalid argument to -S: %s\n", isc_commandline_argument); exit(1); } break; case 'T': if (ARGCMP("warn")) { zone_options |= DNS_ZONEOPT_CHECKSPF; } else if (ARGCMP("ignore")) { zone_options &= ~DNS_ZONEOPT_CHECKSPF; } else { fprintf(stderr, "invalid argument to -T: %s\n", isc_commandline_argument); exit(1); } break; case 'W': if (ARGCMP("warn")) zone_options |= DNS_ZONEOPT_CHECKWILDCARD; else if (ARGCMP("ignore")) zone_options &= ~DNS_ZONEOPT_CHECKWILDCARD; break; case '?': if (isc_commandline_option != '?') fprintf(stderr, "%s: invalid argument -%c\n", prog_name, isc_commandline_option); /* FALLTHROUGH */ case 'h': usage(); default: fprintf(stderr, "%s: unhandled option -%c\n", prog_name, isc_commandline_option); exit(1); } } if (workdir != NULL) { result = isc_dir_chdir(workdir); if (result != ISC_R_SUCCESS) { fprintf(stderr, "isc_dir_chdir: %s: %s\n", workdir, isc_result_totext(result)); exit(1); } } if (inputformatstr != NULL) { if (strcasecmp(inputformatstr, "text") == 0) inputformat = dns_masterformat_text; else if (strcasecmp(inputformatstr, "raw") == 0) inputformat = dns_masterformat_raw; else if (strncasecmp(inputformatstr, "raw=", 4) == 0) { inputformat = dns_masterformat_raw; fprintf(stderr, "WARNING: input format raw, version ignored\n"); } else if (strcasecmp(inputformatstr, "map") == 0) { inputformat = dns_masterformat_map; } else { fprintf(stderr, "unknown file format: %s\n", inputformatstr); exit(1); } } if (outputformatstr != NULL) { if (strcasecmp(outputformatstr, "text") == 0) { outputformat = dns_masterformat_text; } else if (strcasecmp(outputformatstr, "raw") == 0) { outputformat = dns_masterformat_raw; } else if (strncasecmp(outputformatstr, "raw=", 4) == 0) { char *end; outputformat = dns_masterformat_raw; rawversion = strtol(outputformatstr + 4, &end, 10); if (end == outputformatstr + 4 || *end != '\0' || rawversion > 1U) { fprintf(stderr, "unknown raw format version\n"); exit(1); } } else if (strcasecmp(outputformatstr, "map") == 0) { outputformat = dns_masterformat_map; } else { fprintf(stderr, "unknown file format: %s\n", outputformatstr); exit(1); } } if (progmode == progmode_compile) { dumpzone = 1; /* always dump */ logdump = !quiet; if (output_filename == NULL) { fprintf(stderr, "output file required, but not specified\n"); usage(); } } if (output_filename != NULL) dumpzone = 1; /* * If we are outputing to stdout then send the informational * output to stderr. */ if (dumpzone && (output_filename == NULL || strcmp(output_filename, "-") == 0 || strcmp(output_filename, "/dev/fd/1") == 0 || strcmp(output_filename, "/dev/stdout") == 0)) { errout = stderr; logdump = ISC_FALSE; } if (isc_commandline_index + 2 != argc) usage(); #ifdef _WIN32 InitSockets(); #endif RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); if (!quiet) RUNTIME_CHECK(setup_logging(mctx, errout, &lctx) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE) == ISC_R_SUCCESS); dns_result_register(); origin = argv[isc_commandline_index++]; filename = argv[isc_commandline_index++]; result = load_zone(mctx, origin, filename, inputformat, classname, maxttl, &zone); if (snset) { dns_master_initrawheader(&header); header.flags = DNS_MASTERRAW_SOURCESERIALSET; header.sourceserial = serialnum; dns_zone_setrawdata(zone, &header); } if (result == ISC_R_SUCCESS && dumpzone) { if (logdump) { fprintf(errout, "dump zone to %s...", output_filename); fflush(errout); } result = dump_zone(origin, zone, output_filename, outputformat, outputstyle, rawversion); if (logdump) fprintf(errout, "done\n"); } if (!quiet && result == ISC_R_SUCCESS) fprintf(errout, "OK\n"); destroy(); if (lctx != NULL) isc_log_destroy(&lctx); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); #ifdef _WIN32 DestroySockets(); #endif return ((result == ISC_R_SUCCESS) ? 0 : 1); } bind9-9.10.3.dfsg.P4/bin/check/named-checkconf.80000644000470500017500000000707612664710322020326 0ustar lamontlamont.\" Copyright (C) 2004, 2005, 2007, 2009, 2014 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000-2002 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: named\-checkconf .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: January 10, 2014 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "NAMED\-CHECKCONF" "8" "January 10, 2014" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" named\-checkconf \- named configuration file syntax checking tool .SH "SYNOPSIS" .HP 16 \fBnamed\-checkconf\fR [\fB\-h\fR] [\fB\-v\fR] [\fB\-j\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] {filename} [\fB\-p\fR] [\fB\-x\fR] [\fB\-z\fR] .SH "DESCRIPTION" .PP \fBnamed\-checkconf\fR checks the syntax, but not the semantics, of a \fBnamed\fR configuration file. The file is parsed and checked for syntax errors, along with all files included by it. If no file is specified, \fI/etc/named.conf\fR is read by default. .PP Note: files that \fBnamed\fR reads in separate parser contexts, such as \fIrndc.key\fR and \fIbind.keys\fR, are not automatically read by \fBnamed\-checkconf\fR. Configuration errors in these files may cause \fBnamed\fR to fail to run, even if \fBnamed\-checkconf\fR was successful. \fBnamed\-checkconf\fR can be run on these files explicitly, however. .SH "OPTIONS" .PP \-h .RS 4 Print the usage summary and exit. .RE .PP \-t \fIdirectory\fR .RS 4 Chroot to \fIdirectory\fR so that include directives in the configuration file are processed as if run by a similarly chrooted named. .RE .PP \-v .RS 4 Print the version of the \fBnamed\-checkconf\fR program and exit. .RE .PP \-p .RS 4 Print out the \fInamed.conf\fR and included files in canonical form if no errors were detected. .RE .PP \-x .RS 4 When printing the configuration files in canonical form, obscure shared secrets by replacing them with strings of question marks ('?'). This allows the contents of \fInamed.conf\fR and related files to be shared \(em for example, when submitting bug reports \(em without compromising private data. This option cannot be used without \fB\-p\fR. .RE .PP \-z .RS 4 Perform a test load of all master zones found in \fInamed.conf\fR. .RE .PP \-j .RS 4 When loading a zonefile read the journal if it exists. .RE .PP filename .RS 4 The name of the configuration file to be checked. If not specified, it defaults to \fI/etc/named.conf\fR. .RE .SH "RETURN VALUES" .PP \fBnamed\-checkconf\fR returns an exit status of 1 if errors were detected and 0 otherwise. .SH "SEE ALSO" .PP \fBnamed\fR(8), \fBnamed\-checkzone\fR(8), BIND 9 Administrator Reference Manual. .SH "AUTHOR" .PP Internet Systems Consortium .SH "COPYRIGHT" Copyright \(co 2004, 2005, 2007, 2009, 2014 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000\-2002 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/bin/check/named-checkconf.docbook0000644000470500017500000001464212664710322021574 0ustar lamontlamont]> January 10, 2014 named-checkconf 8 BIND9 2004 2005 2007 2009 2014 Internet Systems Consortium, Inc. ("ISC") 2000 2001 2002 Internet Software Consortium. named-checkconf named configuration file syntax checking tool named-checkconf filename DESCRIPTION named-checkconf checks the syntax, but not the semantics, of a named configuration file. The file is parsed and checked for syntax errors, along with all files included by it. If no file is specified, /etc/named.conf is read by default. Note: files that named reads in separate parser contexts, such as rndc.key and bind.keys, are not automatically read by named-checkconf. Configuration errors in these files may cause named to fail to run, even if named-checkconf was successful. named-checkconf can be run on these files explicitly, however. OPTIONS -h Print the usage summary and exit. -t directory Chroot to directory so that include directives in the configuration file are processed as if run by a similarly chrooted named. -v Print the version of the named-checkconf program and exit. -p Print out the named.conf and included files in canonical form if no errors were detected. -x When printing the configuration files in canonical form, obscure shared secrets by replacing them with strings of question marks ('?'). This allows the contents of named.conf and related files to be shared — for example, when submitting bug reports — without compromising private data. This option cannot be used without . -z Perform a test load of all master zones found in named.conf. -j When loading a zonefile read the journal if it exists. filename The name of the configuration file to be checked. If not specified, it defaults to /etc/named.conf. RETURN VALUES named-checkconf returns an exit status of 1 if errors were detected and 0 otherwise. SEE ALSO named8 , named-checkzone8 , BIND 9 Administrator Reference Manual. AUTHOR Internet Systems Consortium bind9-9.10.3.dfsg.P4/bin/check/named-checkzone.80000644000470500017500000002307112664710322020345 0ustar lamontlamont.\" Copyright (C) 2004-2007, 2009-2014 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000-2002 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: named\-checkzone .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: February 19, 2014 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "NAMED\-CHECKZONE" "8" "February 19, 2014" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" named\-checkzone, named\-compilezone \- zone file validity checking or converting tool .SH "SYNOPSIS" .HP 16 \fBnamed\-checkzone\fR [\fB\-d\fR] [\fB\-h\fR] [\fB\-j\fR] [\fB\-q\fR] [\fB\-v\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-f\ \fR\fB\fIformat\fR\fR] [\fB\-F\ \fR\fB\fIformat\fR\fR] [\fB\-J\ \fR\fB\fIfilename\fR\fR] [\fB\-i\ \fR\fB\fImode\fR\fR] [\fB\-k\ \fR\fB\fImode\fR\fR] [\fB\-m\ \fR\fB\fImode\fR\fR] [\fB\-M\ \fR\fB\fImode\fR\fR] [\fB\-n\ \fR\fB\fImode\fR\fR] [\fB\-l\ \fR\fB\fIttl\fR\fR] [\fB\-L\ \fR\fB\fIserial\fR\fR] [\fB\-o\ \fR\fB\fIfilename\fR\fR] [\fB\-r\ \fR\fB\fImode\fR\fR] [\fB\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-S\ \fR\fB\fImode\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-T\ \fR\fB\fImode\fR\fR] [\fB\-w\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-W\ \fR\fB\fImode\fR\fR] {zonename} {filename} .HP 18 \fBnamed\-compilezone\fR [\fB\-d\fR] [\fB\-j\fR] [\fB\-q\fR] [\fB\-v\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-C\ \fR\fB\fImode\fR\fR] [\fB\-f\ \fR\fB\fIformat\fR\fR] [\fB\-F\ \fR\fB\fIformat\fR\fR] [\fB\-J\ \fR\fB\fIfilename\fR\fR] [\fB\-i\ \fR\fB\fImode\fR\fR] [\fB\-k\ \fR\fB\fImode\fR\fR] [\fB\-m\ \fR\fB\fImode\fR\fR] [\fB\-n\ \fR\fB\fImode\fR\fR] [\fB\-l\ \fR\fB\fIttl\fR\fR] [\fB\-L\ \fR\fB\fIserial\fR\fR] [\fB\-r\ \fR\fB\fImode\fR\fR] [\fB\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-T\ \fR\fB\fImode\fR\fR] [\fB\-w\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-W\ \fR\fB\fImode\fR\fR] {\fB\-o\ \fR\fB\fIfilename\fR\fR} {zonename} {filename} .SH "DESCRIPTION" .PP \fBnamed\-checkzone\fR checks the syntax and integrity of a zone file. It performs the same checks as \fBnamed\fR does when loading a zone. This makes \fBnamed\-checkzone\fR useful for checking zone files before configuring them into a name server. .PP \fBnamed\-compilezone\fR is similar to \fBnamed\-checkzone\fR, but it always dumps the zone contents to a specified file in a specified format. Additionally, it applies stricter check levels by default, since the dump output will be used as an actual zone file loaded by \fBnamed\fR. When manually specified otherwise, the check levels must at least be as strict as those specified in the \fBnamed\fR configuration file. .SH "OPTIONS" .PP \-d .RS 4 Enable debugging. .RE .PP \-h .RS 4 Print the usage summary and exit. .RE .PP \-q .RS 4 Quiet mode \- exit code only. .RE .PP \-v .RS 4 Print the version of the \fBnamed\-checkzone\fR program and exit. .RE .PP \-j .RS 4 When loading a zone file, read the journal if it exists. The journal file name is assumed to be the zone file name appended with the string \fI.jnl\fR. .RE .PP \-J \fIfilename\fR .RS 4 When loading the zone file read the journal from the given file, if it exists. (Implies \-j.) .RE .PP \-c \fIclass\fR .RS 4 Specify the class of the zone. If not specified, "IN" is assumed. .RE .PP \-i \fImode\fR .RS 4 Perform post\-load zone integrity checks. Possible modes are \fB"full"\fR (default), \fB"full\-sibling"\fR, \fB"local"\fR, \fB"local\-sibling"\fR and \fB"none"\fR. .sp Mode \fB"full"\fR checks that MX records refer to A or AAAA record (both in\-zone and out\-of\-zone hostnames). Mode \fB"local"\fR only checks MX records which refer to in\-zone hostnames. .sp Mode \fB"full"\fR checks that SRV records refer to A or AAAA record (both in\-zone and out\-of\-zone hostnames). Mode \fB"local"\fR only checks SRV records which refer to in\-zone hostnames. .sp Mode \fB"full"\fR checks that delegation NS records refer to A or AAAA record (both in\-zone and out\-of\-zone hostnames). It also checks that glue address records in the zone match those advertised by the child. Mode \fB"local"\fR only checks NS records which refer to in\-zone hostnames or that some required glue exists, that is when the nameserver is in a child zone. .sp Mode \fB"full\-sibling"\fR and \fB"local\-sibling"\fR disable sibling glue checks but are otherwise the same as \fB"full"\fR and \fB"local"\fR respectively. .sp Mode \fB"none"\fR disables the checks. .RE .PP \-f \fIformat\fR .RS 4 Specify the format of the zone file. Possible formats are \fB"text"\fR (default), \fB"raw"\fR, and \fB"map"\fR. .RE .PP \-F \fIformat\fR .RS 4 Specify the format of the output file specified. For \fBnamed\-checkzone\fR, this does not cause any effects unless it dumps the zone contents. .sp Possible formats are \fB"text"\fR (default), which is the standard textual representation of the zone, and \fB"map"\fR, \fB"raw"\fR, and \fB"raw=N"\fR, which store the zone in a binary format for rapid loading by \fBnamed\fR. \fB"raw=N"\fR specifies the format version of the raw zone file: if N is 0, the raw file can be read by any version of \fBnamed\fR; if N is 1, the file can be read by release 9.9.0 or higher; the default is 1. .RE .PP \-k \fImode\fR .RS 4 Perform \fB"check\-names"\fR checks with the specified failure mode. Possible modes are \fB"fail"\fR (default for \fBnamed\-compilezone\fR), \fB"warn"\fR (default for \fBnamed\-checkzone\fR) and \fB"ignore"\fR. .RE .PP \-l \fIttl\fR .RS 4 Sets a maximum permissible TTL for the input file. Any record with a TTL higher than this value will cause the zone to be rejected. This is similar to using the \fBmax\-zone\-ttl\fR option in \fInamed.conf\fR. .RE .PP \-L \fIserial\fR .RS 4 When compiling a zone to "raw" or "map" format, set the "source serial" value in the header to the specified serial number. (This is expected to be used primarily for testing purposes.) .RE .PP \-m \fImode\fR .RS 4 Specify whether MX records should be checked to see if they are addresses. Possible modes are \fB"fail"\fR, \fB"warn"\fR (default) and \fB"ignore"\fR. .RE .PP \-M \fImode\fR .RS 4 Check if a MX record refers to a CNAME. Possible modes are \fB"fail"\fR, \fB"warn"\fR (default) and \fB"ignore"\fR. .RE .PP \-n \fImode\fR .RS 4 Specify whether NS records should be checked to see if they are addresses. Possible modes are \fB"fail"\fR (default for \fBnamed\-compilezone\fR), \fB"warn"\fR (default for \fBnamed\-checkzone\fR) and \fB"ignore"\fR. .RE .PP \-o \fIfilename\fR .RS 4 Write zone output to \fIfilename\fR. If \fIfilename\fR is \fI\-\fR then write to standard out. This is mandatory for \fBnamed\-compilezone\fR. .RE .PP \-r \fImode\fR .RS 4 Check for records that are treated as different by DNSSEC but are semantically equal in plain DNS. Possible modes are \fB"fail"\fR, \fB"warn"\fR (default) and \fB"ignore"\fR. .RE .PP \-s \fIstyle\fR .RS 4 Specify the style of the dumped zone file. Possible styles are \fB"full"\fR (default) and \fB"relative"\fR. The full format is most suitable for processing automatically by a separate script. On the other hand, the relative format is more human\-readable and is thus suitable for editing by hand. For \fBnamed\-checkzone\fR this does not cause any effects unless it dumps the zone contents. It also does not have any meaning if the output format is not text. .RE .PP \-S \fImode\fR .RS 4 Check if a SRV record refers to a CNAME. Possible modes are \fB"fail"\fR, \fB"warn"\fR (default) and \fB"ignore"\fR. .RE .PP \-t \fIdirectory\fR .RS 4 Chroot to \fIdirectory\fR so that include directives in the configuration file are processed as if run by a similarly chrooted named. .RE .PP \-T \fImode\fR .RS 4 Check if Sender Policy Framework (SPF) records exist and issues a warning if an SPF\-formatted TXT record is not also present. Possible modes are \fB"warn"\fR (default), \fB"ignore"\fR. .RE .PP \-w \fIdirectory\fR .RS 4 chdir to \fIdirectory\fR so that relative filenames in master file $INCLUDE directives work. This is similar to the directory clause in \fInamed.conf\fR. .RE .PP \-D .RS 4 Dump zone file in canonical format. This is always enabled for \fBnamed\-compilezone\fR. .RE .PP \-W \fImode\fR .RS 4 Specify whether to check for non\-terminal wildcards. Non\-terminal wildcards are almost always the result of a failure to understand the wildcard matching algorithm (RFC 1034). Possible modes are \fB"warn"\fR (default) and \fB"ignore"\fR. .RE .PP zonename .RS 4 The domain name of the zone being checked. .RE .PP filename .RS 4 The name of the zone file. .RE .SH "RETURN VALUES" .PP \fBnamed\-checkzone\fR returns an exit status of 1 if errors were detected and 0 otherwise. .SH "SEE ALSO" .PP \fBnamed\fR(8), \fBnamed\-checkconf\fR(8), RFC 1035, BIND 9 Administrator Reference Manual. .SH "AUTHOR" .PP Internet Systems Consortium .SH "COPYRIGHT" Copyright \(co 2004\-2007, 2009\-2014 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000\-2002 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/bin/check/named-checkzone.docbook0000644000470500017500000004661112664710322021623 0ustar lamontlamont]> February 19, 2014 named-checkzone 8 BIND9 2004 2005 2006 2007 2009 2010 2011 2012 2013 2014 Internet Systems Consortium, Inc. ("ISC") 2000 2001 2002 Internet Software Consortium. named-checkzone named-compilezone zone file validity checking or converting tool named-checkzone zonename filename named-compilezone zonename filename DESCRIPTION named-checkzone checks the syntax and integrity of a zone file. It performs the same checks as named does when loading a zone. This makes named-checkzone useful for checking zone files before configuring them into a name server. named-compilezone is similar to named-checkzone, but it always dumps the zone contents to a specified file in a specified format. Additionally, it applies stricter check levels by default, since the dump output will be used as an actual zone file loaded by named. When manually specified otherwise, the check levels must at least be as strict as those specified in the named configuration file. OPTIONS -d Enable debugging. -h Print the usage summary and exit. -q Quiet mode - exit code only. -v Print the version of the named-checkzone program and exit. -j When loading a zone file, read the journal if it exists. The journal file name is assumed to be the zone file name appended with the string .jnl. -J filename When loading the zone file read the journal from the given file, if it exists. (Implies -j.) -c class Specify the class of the zone. If not specified, "IN" is assumed. -i mode Perform post-load zone integrity checks. Possible modes are "full" (default), "full-sibling", "local", "local-sibling" and "none". Mode "full" checks that MX records refer to A or AAAA record (both in-zone and out-of-zone hostnames). Mode "local" only checks MX records which refer to in-zone hostnames. Mode "full" checks that SRV records refer to A or AAAA record (both in-zone and out-of-zone hostnames). Mode "local" only checks SRV records which refer to in-zone hostnames. Mode "full" checks that delegation NS records refer to A or AAAA record (both in-zone and out-of-zone hostnames). It also checks that glue address records in the zone match those advertised by the child. Mode "local" only checks NS records which refer to in-zone hostnames or that some required glue exists, that is when the nameserver is in a child zone. Mode "full-sibling" and "local-sibling" disable sibling glue checks but are otherwise the same as "full" and "local" respectively. Mode "none" disables the checks. -f format Specify the format of the zone file. Possible formats are "text" (default), "raw", and "map". -F format Specify the format of the output file specified. For named-checkzone, this does not cause any effects unless it dumps the zone contents. Possible formats are "text" (default), which is the standard textual representation of the zone, and "map", "raw", and "raw=N", which store the zone in a binary format for rapid loading by named. "raw=N" specifies the format version of the raw zone file: if N is 0, the raw file can be read by any version of named; if N is 1, the file can be read by release 9.9.0 or higher; the default is 1. -k mode Perform "check-names" checks with the specified failure mode. Possible modes are "fail" (default for named-compilezone), "warn" (default for named-checkzone) and "ignore". -l ttl Sets a maximum permissible TTL for the input file. Any record with a TTL higher than this value will cause the zone to be rejected. This is similar to using the max-zone-ttl option in named.conf. -L serial When compiling a zone to "raw" or "map" format, set the "source serial" value in the header to the specified serial number. (This is expected to be used primarily for testing purposes.) -m mode Specify whether MX records should be checked to see if they are addresses. Possible modes are "fail", "warn" (default) and "ignore". -M mode Check if a MX record refers to a CNAME. Possible modes are "fail", "warn" (default) and "ignore". -n mode Specify whether NS records should be checked to see if they are addresses. Possible modes are "fail" (default for named-compilezone), "warn" (default for named-checkzone) and "ignore". -o filename Write zone output to filename. If filename is - then write to standard out. This is mandatory for named-compilezone. -r mode Check for records that are treated as different by DNSSEC but are semantically equal in plain DNS. Possible modes are "fail", "warn" (default) and "ignore". -s style Specify the style of the dumped zone file. Possible styles are "full" (default) and "relative". The full format is most suitable for processing automatically by a separate script. On the other hand, the relative format is more human-readable and is thus suitable for editing by hand. For named-checkzone this does not cause any effects unless it dumps the zone contents. It also does not have any meaning if the output format is not text. -S mode Check if a SRV record refers to a CNAME. Possible modes are "fail", "warn" (default) and "ignore". -t directory Chroot to directory so that include directives in the configuration file are processed as if run by a similarly chrooted named. -T mode Check if Sender Policy Framework (SPF) records exist and issues a warning if an SPF-formatted TXT record is not also present. Possible modes are "warn" (default), "ignore". -w directory chdir to directory so that relative filenames in master file $INCLUDE directives work. This is similar to the directory clause in named.conf. -D Dump zone file in canonical format. This is always enabled for named-compilezone. -W mode Specify whether to check for non-terminal wildcards. Non-terminal wildcards are almost always the result of a failure to understand the wildcard matching algorithm (RFC 1034). Possible modes are "warn" (default) and "ignore". zonename The domain name of the zone being checked. filename The name of the zone file. RETURN VALUES named-checkzone returns an exit status of 1 if errors were detected and 0 otherwise. SEE ALSO named8 , named-checkconf8 , RFC 1035, BIND 9 Administrator Reference Manual. AUTHOR Internet Systems Consortium bind9-9.10.3.dfsg.P4/bin/check/win32/0002755000470500017500000000000012664730167016173 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/check/win32/checkconf.vcxproj.user0000644000470500017500000000021712664710322022475 0ustar lamontlamont bind9-9.10.3.dfsg.P4/bin/check/win32/checkzone.mak.in0000644000470500017500000002602612664710322021236 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on checkzone.dsp !IF "$(CFG)" == "" CFG=checkzone - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to checkzone - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "checkzone - @PLATFORM@ Release" && "$(CFG)" != "checkzone - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "checkzone.mak" CFG="checkzone - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "checkzone - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "checkzone - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF !IF "$(CFG)" == "checkzone - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "checkzone - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release !IF "$(RECURSE)" == "0" ALL : "..\..\..\Build\Release\named-checkzone.exe" !ELSE ALL : "libisc - @PLATFORM@ Release" "libdns - @PLATFORM@ Release" "..\..\..\Build\Release\named-checkzone.exe" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libdns - @PLATFORM@ ReleaseCLEAN" "libisc - @PLATFORM@ ReleaseCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\check-tool.obj" -@erase "$(INTDIR)\named-checkzone.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "..\..\..\Build\Release\named-checkzone.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /I "../../../lib/isccfg/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /Fp"$(INTDIR)\checkzone.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\checkzone.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/isccfg/win32/Release/libisccfg.lib ../../../lib/dns/win32/Release/libdns.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\named-checkzone.pdb" @MACHINE@ /out:"../../../Build/Release/named-checkzone.exe" LINK32_OBJS= \ "$(INTDIR)\check-tool.obj" \ "$(INTDIR)\named-checkzone.obj" \ "..\..\..\lib\dns\win32\Release\libdns.lib" \ "..\..\..\lib\isccfg\win32\Release\libisccfg.lib" \ "..\..\..\lib\isc\win32\Release\libisc.lib" "..\..\..\Build\Release\named-checkzone.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "checkzone - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros !IF "$(RECURSE)" == "0" ALL : "..\..\..\Build\Debug\named-checkzone.exe" "$(OUTDIR)\checkzone.bsc" !ELSE ALL : "libisc - @PLATFORM@ Debug" "libdns - @PLATFORM@ Debug" "..\..\..\Build\Debug\named-checkzone.exe" "$(OUTDIR)\checkzone.bsc" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libdns - @PLATFORM@ DebugCLEAN" "libisc - @PLATFORM@ DebugCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\check-tool.obj" -@erase "$(INTDIR)\check-tool.sbr" -@erase "$(INTDIR)\named-checkzone.obj" -@erase "$(INTDIR)\named-checkzone.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\named-checkzone.pdb" -@erase "$(OUTDIR)\checkzone.bsc" -@erase "..\..\..\Build\Debug\named-checkzone.exe" -@erase "..\..\..\Build\Debug\named-checkzone.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /I "../../../lib/isccfg/include" /D "_DEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\checkzone.bsc" BSC32_SBRS= \ "$(INTDIR)\check-tool.sbr" \ "$(INTDIR)\named-checkzone.sbr" "$(OUTDIR)\checkzone.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/isccfg/win32/Debug/libisccfg.lib ../../../lib/dns/win32/Debug/libdns.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\named-checkzone.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/named-checkzone.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\check-tool.obj" \ "$(INTDIR)\named-checkzone.obj" \ "..\..\..\lib\dns\win32\Debug\libdns.lib" \ "..\..\..\lib\isccfg\win32\Debug\libisccfg.lib" \ "..\..\..\lib\isc\win32\Debug\libisc.lib" "..\..\..\Build\Debug\named-checkzone.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("checkzone.dep") !INCLUDE "checkzone.dep" !ELSE !MESSAGE Warning: cannot find "checkzone.dep" !ENDIF !ENDIF !IF "$(CFG)" == "checkzone - @PLATFORM@ Release" || "$(CFG)" == "checkzone - @PLATFORM@ Debug" SOURCE="..\check-tool.c" !IF "$(CFG)" == "checkzone - @PLATFORM@ Release" "$(INTDIR)\check-tool.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "checkzone - @PLATFORM@ Debug" "$(INTDIR)\check-tool.obj" "$(INTDIR)\check-tool.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE="..\named-checkzone.c" !IF "$(CFG)" == "checkzone - @PLATFORM@ Release" "$(INTDIR)\named-checkzone.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "checkzone - @PLATFORM@ Debug" "$(INTDIR)\named-checkzone.obj" "$(INTDIR)\named-checkzone.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !IF "$(CFG)" == "checkzone - @PLATFORM@ Release" "libdns - @PLATFORM@ Release" : cd "..\..\..\lib\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" cd "..\..\..\bin\check\win32" "libdns - @PLATFORM@ ReleaseCLEAN" : cd "..\..\..\lib\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\..\bin\check\win32" !ELSEIF "$(CFG)" == "checkzone - @PLATFORM@ Debug" "libdns - @PLATFORM@ Debug" : cd "..\..\..\lib\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" cd "..\..\..\bin\check\win32" "libdns - @PLATFORM@ DebugCLEAN" : cd "..\..\..\lib\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\..\bin\check\win32" !ENDIF !IF "$(CFG)" == "checkzone - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" : cd "..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" cd "..\..\..\bin\check\win32" "libisc - @PLATFORM@ ReleaseCLEAN" : cd "..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\..\bin\check\win32" !ELSEIF "$(CFG)" == "checkzone - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" : cd "..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" cd "..\..\..\bin\check\win32" "libisc - @PLATFORM@ DebugCLEAN" : cd "..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\..\bin\check\win32" !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/bin/check/win32/checkzone.dsp.in0000644000470500017500000001135012664710322021246 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="checkzone" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 CFG=checkzone - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "checkzone.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "checkzone.mak" CFG="checkzone - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "checkzone - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "checkzone - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "checkzone - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /I "../../../lib/isccfg/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" @COPTY@ /FD /c # SUBTRACT CPP /Fr # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @MACHINE@ # ADD LINK32 user32.lib advapi32.lib ws2_32.lib Release/checktool.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/isccfg/win32/Release/libisccfg.lib ../../../lib/dns/win32/Release/libdns.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/named-checkzone.exe" !ELSEIF "$(CFG)" == "checkzone - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /I "../../../lib/isccfg/include" /D "_DEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c # SUBTRACT CPP /X @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib ws2_32.lib Debug/checktool.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/isccfg/win32/Debug/libisccfg.lib ../../../lib/dns/win32/Debug/libdns.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/named-checkzone.exe" /pdbtype:sept !ENDIF # Begin Target # Name "checkzone - @PLATFORM@ Release" # Name "checkzone - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE="..\named-checkzone.c" # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE="..\check-tool.h" # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/bin/check/win32/checktool.vcxproj.user0000644000470500017500000000021712664710322022525 0ustar lamontlamont bind9-9.10.3.dfsg.P4/bin/check/win32/checkzone.vcxproj.user0000644000470500017500000000021712664710322022523 0ustar lamontlamont bind9-9.10.3.dfsg.P4/bin/check/win32/checktool.vcxproj.in0000644000470500017500000001277312664710322022167 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {2C1F7096-C5B5-48D4-846F-A7ACA454335D} Win32Proj checktool StaticLibrary true MultiByte StaticLibrary false true MultiByte .\$(Configuration)\ .\$(Configuration)\ .\$(Configuration)\ .\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\include;..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\isccfg\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) .\$(Configuration)\$(TargetName)$(TargetExt) Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\include;..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\isccfg\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) .\$(Configuration)\$(TargetName)$(TargetExt) bind9-9.10.3.dfsg.P4/bin/check/win32/checkconf.vcxproj.filters.in0000644000470500017500000000210612664710322023573 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Header Files Source Files bind9-9.10.3.dfsg.P4/bin/check/win32/checkconf.mak.in0000644000470500017500000003075412664710322021213 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on checkconf.dsp !IF "$(CFG)" == "" CFG=checkconf - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to checkconf - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "checkconf - @PLATFORM@ Release" && "$(CFG)" != "checkconf - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "checkconf.mak" CFG="checkconf - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "checkconf - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "checkconf - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "checkconf - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "checkconf - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release # Begin Custom Macros OutDir=.\Release # End Custom Macros !IF "$(RECURSE)" == "0" ALL : "..\..\..\Build\Release\named-checkconf.exe" "$(OUTDIR)\checkconf.bsc" !ELSE ALL : "libdns - @PLATFORM@ Release" "libisccfg - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" "..\..\..\Build\Release\named-checkconf.exe" "$(OUTDIR)\checkconf.bsc" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libisc - @PLATFORM@ ReleaseCLEAN" "libisccfg - @PLATFORM@ ReleaseCLEAN" "libdns - @PLATFORM@ ReleaseCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\check-tool.obj" -@erase "$(INTDIR)\check-tool.sbr" -@erase "$(INTDIR)\named-checkconf.obj" -@erase "$(INTDIR)\named-checkconf.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(OUTDIR)\checkconf.bsc" -@erase "..\..\..\Build\Release\named-checkconf.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /I "../../../lib/bind9/include" /I "../../../lib/isccfg/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\checkconf.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\checkconf.bsc" BSC32_SBRS= \ "$(INTDIR)\check-tool.sbr" \ "$(INTDIR)\named-checkconf.sbr" "$(OUTDIR)\checkconf.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ../../../lib/isccfg/win32/Release/libisccfg.lib ../../../lib/bind9/win32/Release/libbind9.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\named-checkconf.pdb" @MACHINE@ /out:"../../../Build/Release/named-checkconf.exe" LINK32_OBJS= \ "$(INTDIR)\check-tool.obj" \ "$(INTDIR)\named-checkconf.obj" \ "..\..\..\lib\isc\win32\Release\libisc.lib" \ "..\..\..\lib\isccfg\win32\Release\libisccfg.lib" \ "..\..\..\lib\dns\win32\Release\libdns.lib" "..\..\..\Build\Release\named-checkconf.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "checkconf - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros !IF "$(RECURSE)" == "0" ALL : "..\..\..\Build\Debug\named-checkconf.exe" "$(OUTDIR)\checkconf.bsc" !ELSE ALL : "libdns - @PLATFORM@ Debug" "libisccfg - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" "..\..\..\Build\Debug\named-checkconf.exe" "$(OUTDIR)\checkconf.bsc" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libisc - @PLATFORM@ DebugCLEAN" "libisccfg - @PLATFORM@ DebugCLEAN" "libdns - @PLATFORM@ DebugCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\check-tool.obj" -@erase "$(INTDIR)\check-tool.sbr" -@erase "$(INTDIR)\named-checkconf.obj" -@erase "$(INTDIR)\named-checkconf.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\named-checkconf.pdb" -@erase "$(OUTDIR)\checkconf.bsc" -@erase "..\..\..\Build\Debug\named-checkconf.exe" -@erase "..\..\..\Build\Debug\named-checkconf.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /I "../../../lib/bind9/include" /I "../../../lib/isccfg/include" /D "_DEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\checkconf.bsc" BSC32_SBRS= \ "$(INTDIR)\check-tool.sbr" \ "$(INTDIR)\named-checkconf.sbr" "$(OUTDIR)\checkconf.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ws2_32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ../../../lib/isccfg/win32/Debug/libisccfg.lib ../../../lib/bind9/win32/Debug/libbind9.lib ../../../lib/bind9/win32/Debug/libbind9.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\named-checkconf.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/named-checkconf.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\check-tool.obj" \ "$(INTDIR)\named-checkconf.obj" \ "..\..\..\lib\isc\win32\Debug\libisc.lib" \ "..\..\..\lib\isccfg\win32\Debug\libisccfg.lib" \ "..\..\..\lib\dns\win32\Debug\libdns.lib" "..\..\..\Build\Debug\named-checkconf.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("checkconf.dep") !INCLUDE "checkconf.dep" !ELSE !MESSAGE Warning: cannot find "checkconf.dep" !ENDIF !ENDIF !IF "$(CFG)" == "checkconf - @PLATFORM@ Release" || "$(CFG)" == "checkconf - @PLATFORM@ Debug" SOURCE="..\check-tool.c" "$(INTDIR)\check-tool.obj" "$(INTDIR)\check-tool.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE="..\named-checkconf.c" "$(INTDIR)\named-checkconf.obj" "$(INTDIR)\named-checkconf.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !IF "$(CFG)" == "checkconf - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" : cd "..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" cd "..\..\..\bin\check\win32" "libisc - @PLATFORM@ ReleaseCLEAN" : cd "..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\..\bin\check\win32" !ELSEIF "$(CFG)" == "checkconf - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" : cd "..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" cd "..\..\..\bin\check\win32" "libisc - @PLATFORM@ DebugCLEAN" : cd "..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\..\bin\check\win32" !ENDIF !IF "$(CFG)" == "checkconf - @PLATFORM@ Release" "libisccfg - @PLATFORM@ Release" : cd "..\..\..\lib\isccfg\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Release" cd "..\..\..\bin\check\win32" "libisccfg - @PLATFORM@ ReleaseCLEAN" : cd "..\..\..\lib\isccfg\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\..\bin\check\win32" !ELSEIF "$(CFG)" == "checkconf - @PLATFORM@ Debug" "libisccfg - @PLATFORM@ Debug" : cd "..\..\..\lib\isccfg\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Debug" cd "..\..\..\bin\check\win32" "libisccfg - @PLATFORM@ DebugCLEAN" : cd "..\..\..\lib\isccfg\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\..\bin\check\win32" !ENDIF !IF "$(CFG)" == "checkconf - @PLATFORM@ Release" "libdns - @PLATFORM@ Release" : cd "..\..\..\lib\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" cd "..\..\..\bin\check\win32" "libdns - @PLATFORM@ ReleaseCLEAN" : cd "..\..\..\lib\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\..\bin\check\win32" !ELSEIF "$(CFG)" == "checkconf - @PLATFORM@ Debug" "libdns - @PLATFORM@ Debug" : cd "..\..\..\lib\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" cd "..\..\..\bin\check\win32" "libdns - @PLATFORM@ DebugCLEAN" : cd "..\..\..\lib\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\..\bin\check\win32" !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/bin/check/win32/checktool.dsw0000644000470500017500000000103712664710322020653 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "checktool"=".\checktool.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/bin/check/win32/checkconf.dsp.in0000644000470500017500000001163712664710322021230 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="checkconf" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 CFG=checkconf - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "checkconf.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "checkconf.mak" CFG="checkconf - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "checkconf - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "checkconf - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "checkconf - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /I "../../../lib/bind9/include" /I "../../../lib/isccfg/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR @COPTY@ /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @MACHINE@ # ADD LINK32 user32.lib advapi32.lib ws2_32.lib Release/checktool.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib ../../../lib/isccfg/win32/Release/libisccfg.lib ../../../lib/bind9/win32/Release/libbind9.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/named-checkconf.exe" !ELSEIF "$(CFG)" == "checkconf - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /I "../../../lib/bind9/include" /I "../../../lib/isccfg/include" /D "_DEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c # SUBTRACT CPP /X @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib ws2_32.lib Debug/checktool.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib ../../../lib/isccfg/win32/Debug/libisccfg.lib ../../../lib/bind9/win32/Debug/libbind9.lib ../../../lib/bind9/win32/Debug/libbind9.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/named-checkconf.exe" /pdbtype:sept !ENDIF # Begin Target # Name "checkconf - @PLATFORM@ Release" # Name "checkconf - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE="..\named-checkconf.c" # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE="..\check-tool.h" # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/bin/check/win32/checkconf.vcxproj.in0000644000470500017500000001576212664710322022140 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {03A96113-CB14-43AA-AEB2-48950E3915C5} Win32Proj checkconf Application true MultiByte Application false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ named-$(ProjectName) false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ named-$(ProjectName) Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;..\..\..\lib\bind9\include;..\..\..\lib\isccfg\include;%(AdditionalIncludeDirectories) Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);..\..\..\lib\isccfg\win32\$(Configuration);..\..\..\lib\isccc\win32\$(Configuration);..\..\..\lib\bind9\win32\$(Configuration);%(AdditionalLibraryDirectories) checktool.lib;libisc.lib;libdns.lib;libisccfg.lib;libisccc.lib;libbind9.lib;ws2_32.lib;%(AdditionalDependencies) Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;..\..\..\lib\bind9\include;..\..\..\lib\isccfg\include;%(AdditionalIncludeDirectories) Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);..\..\..\lib\isccfg\win32\$(Configuration);..\..\..\lib\isccc\win32\$(Configuration);..\..\..\lib\bind9\win32\$(Configuration);%(AdditionalLibraryDirectories) checktool.lib;libisc.lib;libdns.lib;libisccfg.lib;libisccc.lib;libbind9.lib;ws2_32.lib;%(AdditionalDependencies) Default bind9-9.10.3.dfsg.P4/bin/check/win32/checktool.vcxproj.filters.in0000644000470500017500000000140012664710322023617 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files bind9-9.10.3.dfsg.P4/bin/check/win32/checktool.dsp.in0000644000470500017500000000761512664710322021261 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="checktool" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Static-Link Library" 0x0104 CFG=checktool - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "checktool.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "checktool.mak" CFG="checktool - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "checktool - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Static-Link Library") !MESSAGE "checktool - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Static-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "checktool - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/isccfg/include" /I "../../../lib/dns/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" @COPTY@ /FD /c /Fdchecktool # SUBTRACT CPP /X # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 # ADD LINK32 /out:"Release/checktool.lib" !ELSEIF "$(CFG)" == "checktool - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/isccfg/include" /I "../../../lib/dns/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /FR @COPTY@ /FD /GZ /c /Fdchecktool # SUBTRACT CPP /X # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 # ADD LINK32 /debug out:"Debug/checktool.lib" !ENDIF # Begin Target # Name "checktool - @PLATFORM@ Release" # Name "checktool - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # Begin Group "Main Dns Lib" # PROP Default_Filter "c" # Begin Source File SOURCE=..\check-tool.c # End Source File # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/bin/check/win32/checkzone.dsw0000644000470500017500000000103712664710322020651 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "checkzone"=".\checkzone.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/bin/check/win32/checkconf.dsw0000644000470500017500000000103712664710322020623 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "checkconf"=".\checkconf.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/bin/check/win32/checkzone.vcxproj.in0000644000470500017500000001627512664710322022166 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {66028555-7DD5-4016-B601-9EF9A1EE8BFA} Win32Proj checkzone Application true MultiByte Application false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ named-$(ProjectName) false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ named-$(ProjectName) Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;..\..\..\lib\bind9\include;%(AdditionalIncludeDirectories) Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);..\..\..\lib\isccfg\win32\$(Configuration);..\..\..\lib\bind9\win32\$(Configuration);%(AdditionalLibraryDirectories) checktool.lib;libisc.lib;libdns.lib;libisccfg.lib;libbind9.lib;ws2_32.lib;%(AdditionalDependencies) cd ..\..\..\Build\$(Configuration) copy /Y named-checkzone.exe named-compilezone.exe copy /Y named-checkzone.ilk named-compilezone.ilk Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;..\..\..\lib\bind9\include;%(AdditionalIncludeDirectories) Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);..\..\..\lib\isccfg\win32\$(Configuration);..\..\..\lib\bind9\win32\$(Configuration);%(AdditionalLibraryDirectories) checktool.lib;libisc.lib;libdns.lib;libisccfg.lib;libbind9.lib;ws2_32.lib;%(AdditionalDependencies) Default cd ..\..\..\Build\$(Configuration) copy /Y named-checkzone.exe named-compilezone.exe bind9-9.10.3.dfsg.P4/bin/check/win32/checkzone.vcxproj.filters.in0000644000470500017500000000210612664710322023621 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Header Files Source Files bind9-9.10.3.dfsg.P4/bin/check/named-checkzone.html0000644000470500017500000004453412664710322021151 0ustar lamontlamont named-checkzone

Name

named-checkzone, named-compilezone — zone file validity checking or converting tool

Synopsis

named-checkzone [-d] [-h] [-j] [-q] [-v] [-c class] [-f format] [-F format] [-J filename] [-i mode] [-k mode] [-m mode] [-M mode] [-n mode] [-l ttl] [-L serial] [-o filename] [-r mode] [-s style] [-S mode] [-t directory] [-T mode] [-w directory] [-D] [-W mode] {zonename} {filename}

named-compilezone [-d] [-j] [-q] [-v] [-c class] [-C mode] [-f format] [-F format] [-J filename] [-i mode] [-k mode] [-m mode] [-n mode] [-l ttl] [-L serial] [-r mode] [-s style] [-t directory] [-T mode] [-w directory] [-D] [-W mode] {-o filename} {zonename} {filename}

DESCRIPTION

named-checkzone checks the syntax and integrity of a zone file. It performs the same checks as named does when loading a zone. This makes named-checkzone useful for checking zone files before configuring them into a name server.

named-compilezone is similar to named-checkzone, but it always dumps the zone contents to a specified file in a specified format. Additionally, it applies stricter check levels by default, since the dump output will be used as an actual zone file loaded by named. When manually specified otherwise, the check levels must at least be as strict as those specified in the named configuration file.

OPTIONS

-d

Enable debugging.

-h

Print the usage summary and exit.

-q

Quiet mode - exit code only.

-v

Print the version of the named-checkzone program and exit.

-j

When loading a zone file, read the journal if it exists. The journal file name is assumed to be the zone file name appended with the string .jnl.

-J filename

When loading the zone file read the journal from the given file, if it exists. (Implies -j.)

-c class

Specify the class of the zone. If not specified, "IN" is assumed.

-i mode

Perform post-load zone integrity checks. Possible modes are "full" (default), "full-sibling", "local", "local-sibling" and "none".

Mode "full" checks that MX records refer to A or AAAA record (both in-zone and out-of-zone hostnames). Mode "local" only checks MX records which refer to in-zone hostnames.

Mode "full" checks that SRV records refer to A or AAAA record (both in-zone and out-of-zone hostnames). Mode "local" only checks SRV records which refer to in-zone hostnames.

Mode "full" checks that delegation NS records refer to A or AAAA record (both in-zone and out-of-zone hostnames). It also checks that glue address records in the zone match those advertised by the child. Mode "local" only checks NS records which refer to in-zone hostnames or that some required glue exists, that is when the nameserver is in a child zone.

Mode "full-sibling" and "local-sibling" disable sibling glue checks but are otherwise the same as "full" and "local" respectively.

Mode "none" disables the checks.

-f format

Specify the format of the zone file. Possible formats are "text" (default), "raw", and "map".

-F format

Specify the format of the output file specified. For named-checkzone, this does not cause any effects unless it dumps the zone contents.

Possible formats are "text" (default), which is the standard textual representation of the zone, and "map", "raw", and "raw=N", which store the zone in a binary format for rapid loading by named. "raw=N" specifies the format version of the raw zone file: if N is 0, the raw file can be read by any version of named; if N is 1, the file can be read by release 9.9.0 or higher; the default is 1.

-k mode

Perform "check-names" checks with the specified failure mode. Possible modes are "fail" (default for named-compilezone), "warn" (default for named-checkzone) and "ignore".

-l ttl

Sets a maximum permissible TTL for the input file. Any record with a TTL higher than this value will cause the zone to be rejected. This is similar to using the max-zone-ttl option in named.conf.

-L serial

When compiling a zone to "raw" or "map" format, set the "source serial" value in the header to the specified serial number. (This is expected to be used primarily for testing purposes.)

-m mode

Specify whether MX records should be checked to see if they are addresses. Possible modes are "fail", "warn" (default) and "ignore".

-M mode

Check if a MX record refers to a CNAME. Possible modes are "fail", "warn" (default) and "ignore".

-n mode

Specify whether NS records should be checked to see if they are addresses. Possible modes are "fail" (default for named-compilezone), "warn" (default for named-checkzone) and "ignore".

-o filename

Write zone output to filename. If filename is - then write to standard out. This is mandatory for named-compilezone.

-r mode

Check for records that are treated as different by DNSSEC but are semantically equal in plain DNS. Possible modes are "fail", "warn" (default) and "ignore".

-s style

Specify the style of the dumped zone file. Possible styles are "full" (default) and "relative". The full format is most suitable for processing automatically by a separate script. On the other hand, the relative format is more human-readable and is thus suitable for editing by hand. For named-checkzone this does not cause any effects unless it dumps the zone contents. It also does not have any meaning if the output format is not text.

-S mode

Check if a SRV record refers to a CNAME. Possible modes are "fail", "warn" (default) and "ignore".

-t directory

Chroot to directory so that include directives in the configuration file are processed as if run by a similarly chrooted named.

-T mode

Check if Sender Policy Framework (SPF) records exist and issues a warning if an SPF-formatted TXT record is not also present. Possible modes are "warn" (default), "ignore".

-w directory

chdir to directory so that relative filenames in master file $INCLUDE directives work. This is similar to the directory clause in named.conf.

-D

Dump zone file in canonical format. This is always enabled for named-compilezone.

-W mode

Specify whether to check for non-terminal wildcards. Non-terminal wildcards are almost always the result of a failure to understand the wildcard matching algorithm (RFC 1034). Possible modes are "warn" (default) and "ignore".

zonename

The domain name of the zone being checked.

filename

The name of the zone file.

RETURN VALUES

named-checkzone returns an exit status of 1 if errors were detected and 0 otherwise.

SEE ALSO

named(8), named-checkconf(8), RFC 1035, BIND 9 Administrator Reference Manual.

AUTHOR

Internet Systems Consortium

bind9-9.10.3.dfsg.P4/bin/check/check-tool.c0000644000470500017500000005075612664710322017427 0ustar lamontlamont/* * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: check-tool.c,v 1.44 2011/12/22 07:32:39 each Exp $ */ /*! \file */ #include #include #ifdef _WIN32 #include #endif #include "check-tool.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef CHECK_SIBLING #define CHECK_SIBLING 1 #endif #ifndef CHECK_LOCAL #define CHECK_LOCAL 1 #endif #ifdef HAVE_ADDRINFO #ifdef HAVE_GETADDRINFO #ifdef HAVE_GAISTRERROR #define USE_GETADDRINFO #endif #endif #endif #define CHECK(r) \ do { \ result = (r); \ if (result != ISC_R_SUCCESS) \ goto cleanup; \ } while (0) #define ERR_IS_CNAME 1 #define ERR_NO_ADDRESSES 2 #define ERR_LOOKUP_FAILURE 3 #define ERR_EXTRA_A 4 #define ERR_EXTRA_AAAA 5 #define ERR_MISSING_GLUE 5 #define ERR_IS_MXCNAME 6 #define ERR_IS_SRVCNAME 7 static const char *dbtype[] = { "rbt" }; int debug = 0; const char *journal = NULL; isc_boolean_t nomerge = ISC_TRUE; #if CHECK_LOCAL isc_boolean_t docheckmx = ISC_TRUE; isc_boolean_t dochecksrv = ISC_TRUE; isc_boolean_t docheckns = ISC_TRUE; #else isc_boolean_t docheckmx = ISC_FALSE; isc_boolean_t dochecksrv = ISC_FALSE; isc_boolean_t docheckns = ISC_FALSE; #endif unsigned int zone_options = DNS_ZONEOPT_CHECKNS | DNS_ZONEOPT_CHECKMX | DNS_ZONEOPT_MANYERRORS | DNS_ZONEOPT_CHECKNAMES | DNS_ZONEOPT_CHECKINTEGRITY | #if CHECK_SIBLING DNS_ZONEOPT_CHECKSIBLING | #endif DNS_ZONEOPT_CHECKWILDCARD | DNS_ZONEOPT_WARNMXCNAME | DNS_ZONEOPT_WARNSRVCNAME; unsigned int zone_options2 = 0; /* * This needs to match the list in bin/named/log.c. */ static isc_logcategory_t categories[] = { { "", 0 }, { "client", 0 }, { "network", 0 }, { "update", 0 }, { "queries", 0 }, { "unmatched", 0 }, { "update-security", 0 }, { "query-errors", 0 }, { NULL, 0 } }; static isc_symtab_t *symtab = NULL; static isc_mem_t *sym_mctx; static void freekey(char *key, unsigned int type, isc_symvalue_t value, void *userarg) { UNUSED(type); UNUSED(value); isc_mem_free(userarg, key); } static void add(char *key, int value) { isc_result_t result; isc_symvalue_t symvalue; if (sym_mctx == NULL) { result = isc_mem_create(0, 0, &sym_mctx); if (result != ISC_R_SUCCESS) return; } if (symtab == NULL) { result = isc_symtab_create(sym_mctx, 100, freekey, sym_mctx, ISC_FALSE, &symtab); if (result != ISC_R_SUCCESS) return; } key = isc_mem_strdup(sym_mctx, key); if (key == NULL) return; symvalue.as_pointer = NULL; result = isc_symtab_define(symtab, key, value, symvalue, isc_symexists_reject); if (result != ISC_R_SUCCESS) isc_mem_free(sym_mctx, key); } static isc_boolean_t logged(char *key, int value) { isc_result_t result; if (symtab == NULL) return (ISC_FALSE); result = isc_symtab_lookup(symtab, key, value, NULL); if (result == ISC_R_SUCCESS) return (ISC_TRUE); return (ISC_FALSE); } static isc_boolean_t checkns(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner, dns_rdataset_t *a, dns_rdataset_t *aaaa) { #ifdef USE_GETADDRINFO dns_rdataset_t *rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; struct addrinfo hints, *ai, *cur; char namebuf[DNS_NAME_FORMATSIZE + 1]; char ownerbuf[DNS_NAME_FORMATSIZE]; char addrbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123")]; isc_boolean_t answer = ISC_TRUE; isc_boolean_t match; const char *type; void *ptr = NULL; int result; REQUIRE(a == NULL || !dns_rdataset_isassociated(a) || a->type == dns_rdatatype_a); REQUIRE(aaaa == NULL || !dns_rdataset_isassociated(aaaa) || aaaa->type == dns_rdatatype_aaaa); if (a == NULL || aaaa == NULL) return (answer); memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; dns_name_format(name, namebuf, sizeof(namebuf) - 1); /* * Turn off search. */ if (dns_name_countlabels(name) > 1U) strcat(namebuf, "."); dns_name_format(owner, ownerbuf, sizeof(ownerbuf)); result = getaddrinfo(namebuf, NULL, &hints, &ai); dns_name_format(name, namebuf, sizeof(namebuf) - 1); switch (result) { case 0: /* * Work around broken getaddrinfo() implementations that * fail to set ai_canonname on first entry. */ cur = ai; while (cur != NULL && cur->ai_canonname == NULL && cur->ai_next != NULL) cur = cur->ai_next; if (cur != NULL && cur->ai_canonname != NULL && strcasecmp(cur->ai_canonname, namebuf) != 0 && !logged(namebuf, ERR_IS_CNAME)) { dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' (out of zone) " "is a CNAME '%s' (illegal)", ownerbuf, namebuf, cur->ai_canonname); /* XXX950 make fatal for 9.5.0 */ /* answer = ISC_FALSE; */ add(namebuf, ERR_IS_CNAME); } break; case EAI_NONAME: #if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) case EAI_NODATA: #endif if (!logged(namebuf, ERR_NO_ADDRESSES)) { dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' (out of zone) " "has no addresses records (A or AAAA)", ownerbuf, namebuf); add(namebuf, ERR_NO_ADDRESSES); } /* XXX950 make fatal for 9.5.0 */ return (ISC_TRUE); default: if (!logged(namebuf, ERR_LOOKUP_FAILURE)) { dns_zone_log(zone, ISC_LOG_WARNING, "getaddrinfo(%s) failed: %s", namebuf, gai_strerror(result)); add(namebuf, ERR_LOOKUP_FAILURE); } return (ISC_TRUE); } /* * Check that all glue records really exist. */ if (!dns_rdataset_isassociated(a)) goto checkaaaa; result = dns_rdataset_first(a); while (result == ISC_R_SUCCESS) { dns_rdataset_current(a, &rdata); match = ISC_FALSE; for (cur = ai; cur != NULL; cur = cur->ai_next) { if (cur->ai_family != AF_INET) continue; ptr = &((struct sockaddr_in *)(cur->ai_addr))->sin_addr; if (memcmp(ptr, rdata.data, rdata.length) == 0) { match = ISC_TRUE; break; } } if (!match && !logged(namebuf, ERR_EXTRA_A)) { dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' " "extra GLUE A record (%s)", ownerbuf, namebuf, inet_ntop(AF_INET, rdata.data, addrbuf, sizeof(addrbuf))); add(namebuf, ERR_EXTRA_A); /* XXX950 make fatal for 9.5.0 */ /* answer = ISC_FALSE; */ } dns_rdata_reset(&rdata); result = dns_rdataset_next(a); } checkaaaa: if (!dns_rdataset_isassociated(aaaa)) goto checkmissing; result = dns_rdataset_first(aaaa); while (result == ISC_R_SUCCESS) { dns_rdataset_current(aaaa, &rdata); match = ISC_FALSE; for (cur = ai; cur != NULL; cur = cur->ai_next) { if (cur->ai_family != AF_INET6) continue; ptr = &((struct sockaddr_in6 *)(cur->ai_addr))->sin6_addr; if (memcmp(ptr, rdata.data, rdata.length) == 0) { match = ISC_TRUE; break; } } if (!match && !logged(namebuf, ERR_EXTRA_AAAA)) { dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' " "extra GLUE AAAA record (%s)", ownerbuf, namebuf, inet_ntop(AF_INET6, rdata.data, addrbuf, sizeof(addrbuf))); add(namebuf, ERR_EXTRA_AAAA); /* XXX950 make fatal for 9.5.0. */ /* answer = ISC_FALSE; */ } dns_rdata_reset(&rdata); result = dns_rdataset_next(aaaa); } checkmissing: /* * Check that all addresses appear in the glue. */ if (!logged(namebuf, ERR_MISSING_GLUE)) { isc_boolean_t missing_glue = ISC_FALSE; for (cur = ai; cur != NULL; cur = cur->ai_next) { switch (cur->ai_family) { case AF_INET: rdataset = a; ptr = &((struct sockaddr_in *)(cur->ai_addr))->sin_addr; type = "A"; break; case AF_INET6: rdataset = aaaa; ptr = &((struct sockaddr_in6 *)(cur->ai_addr))->sin6_addr; type = "AAAA"; break; default: continue; } match = ISC_FALSE; if (dns_rdataset_isassociated(rdataset)) result = dns_rdataset_first(rdataset); else result = ISC_R_FAILURE; while (result == ISC_R_SUCCESS && !match) { dns_rdataset_current(rdataset, &rdata); if (memcmp(ptr, rdata.data, rdata.length) == 0) match = ISC_TRUE; dns_rdata_reset(&rdata); result = dns_rdataset_next(rdataset); } if (!match) { dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' " "missing GLUE %s record (%s)", ownerbuf, namebuf, type, inet_ntop(cur->ai_family, ptr, addrbuf, sizeof(addrbuf))); /* XXX950 make fatal for 9.5.0. */ /* answer = ISC_FALSE; */ missing_glue = ISC_TRUE; } } if (missing_glue) add(namebuf, ERR_MISSING_GLUE); } freeaddrinfo(ai); return (answer); #else return (ISC_TRUE); #endif } static isc_boolean_t checkmx(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) { #ifdef USE_GETADDRINFO struct addrinfo hints, *ai, *cur; char namebuf[DNS_NAME_FORMATSIZE + 1]; char ownerbuf[DNS_NAME_FORMATSIZE]; int result; int level = ISC_LOG_ERROR; isc_boolean_t answer = ISC_TRUE; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; dns_name_format(name, namebuf, sizeof(namebuf) - 1); /* * Turn off search. */ if (dns_name_countlabels(name) > 1U) strcat(namebuf, "."); dns_name_format(owner, ownerbuf, sizeof(ownerbuf)); result = getaddrinfo(namebuf, NULL, &hints, &ai); dns_name_format(name, namebuf, sizeof(namebuf) - 1); switch (result) { case 0: /* * Work around broken getaddrinfo() implementations that * fail to set ai_canonname on first entry. */ cur = ai; while (cur != NULL && cur->ai_canonname == NULL && cur->ai_next != NULL) cur = cur->ai_next; if (cur != NULL && cur->ai_canonname != NULL && strcasecmp(cur->ai_canonname, namebuf) != 0) { if ((zone_options & DNS_ZONEOPT_WARNMXCNAME) != 0) level = ISC_LOG_WARNING; if ((zone_options & DNS_ZONEOPT_IGNOREMXCNAME) == 0) { if (!logged(namebuf, ERR_IS_MXCNAME)) { dns_zone_log(zone, level, "%s/MX '%s' (out of zone)" " is a CNAME '%s' " "(illegal)", ownerbuf, namebuf, cur->ai_canonname); add(namebuf, ERR_IS_MXCNAME); } if (level == ISC_LOG_ERROR) answer = ISC_FALSE; } } freeaddrinfo(ai); return (answer); case EAI_NONAME: #if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) case EAI_NODATA: #endif if (!logged(namebuf, ERR_NO_ADDRESSES)) { dns_zone_log(zone, ISC_LOG_ERROR, "%s/MX '%s' (out of zone) " "has no addresses records (A or AAAA)", ownerbuf, namebuf); add(namebuf, ERR_NO_ADDRESSES); } /* XXX950 make fatal for 9.5.0. */ return (ISC_TRUE); default: if (!logged(namebuf, ERR_LOOKUP_FAILURE)) { dns_zone_log(zone, ISC_LOG_WARNING, "getaddrinfo(%s) failed: %s", namebuf, gai_strerror(result)); add(namebuf, ERR_LOOKUP_FAILURE); } return (ISC_TRUE); } #else return (ISC_TRUE); #endif } static isc_boolean_t checksrv(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) { #ifdef USE_GETADDRINFO struct addrinfo hints, *ai, *cur; char namebuf[DNS_NAME_FORMATSIZE + 1]; char ownerbuf[DNS_NAME_FORMATSIZE]; int result; int level = ISC_LOG_ERROR; isc_boolean_t answer = ISC_TRUE; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; dns_name_format(name, namebuf, sizeof(namebuf) - 1); /* * Turn off search. */ if (dns_name_countlabels(name) > 1U) strcat(namebuf, "."); dns_name_format(owner, ownerbuf, sizeof(ownerbuf)); result = getaddrinfo(namebuf, NULL, &hints, &ai); dns_name_format(name, namebuf, sizeof(namebuf) - 1); switch (result) { case 0: /* * Work around broken getaddrinfo() implementations that * fail to set ai_canonname on first entry. */ cur = ai; while (cur != NULL && cur->ai_canonname == NULL && cur->ai_next != NULL) cur = cur->ai_next; if (cur != NULL && cur->ai_canonname != NULL && strcasecmp(cur->ai_canonname, namebuf) != 0) { if ((zone_options & DNS_ZONEOPT_WARNSRVCNAME) != 0) level = ISC_LOG_WARNING; if ((zone_options & DNS_ZONEOPT_IGNORESRVCNAME) == 0) { if (!logged(namebuf, ERR_IS_SRVCNAME)) { dns_zone_log(zone, level, "%s/SRV '%s'" " (out of zone) is a " "CNAME '%s' (illegal)", ownerbuf, namebuf, cur->ai_canonname); add(namebuf, ERR_IS_SRVCNAME); } if (level == ISC_LOG_ERROR) answer = ISC_FALSE; } } freeaddrinfo(ai); return (answer); case EAI_NONAME: #if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) case EAI_NODATA: #endif if (!logged(namebuf, ERR_NO_ADDRESSES)) { dns_zone_log(zone, ISC_LOG_ERROR, "%s/SRV '%s' (out of zone) " "has no addresses records (A or AAAA)", ownerbuf, namebuf); add(namebuf, ERR_NO_ADDRESSES); } /* XXX950 make fatal for 9.5.0. */ return (ISC_TRUE); default: if (!logged(namebuf, ERR_LOOKUP_FAILURE)) { dns_zone_log(zone, ISC_LOG_WARNING, "getaddrinfo(%s) failed: %s", namebuf, gai_strerror(result)); add(namebuf, ERR_LOOKUP_FAILURE); } return (ISC_TRUE); } #else return (ISC_TRUE); #endif } isc_result_t setup_logging(isc_mem_t *mctx, FILE *errout, isc_log_t **logp) { isc_logdestination_t destination; isc_logconfig_t *logconfig = NULL; isc_log_t *log = NULL; RUNTIME_CHECK(isc_log_create(mctx, &log, &logconfig) == ISC_R_SUCCESS); isc_log_registercategories(log, categories); isc_log_setcontext(log); dns_log_init(log); dns_log_setcontext(log); cfg_log_init(log); destination.file.stream = errout; destination.file.name = NULL; destination.file.versions = ISC_LOG_ROLLNEVER; destination.file.maximum_size = 0; RUNTIME_CHECK(isc_log_createchannel(logconfig, "stderr", ISC_LOG_TOFILEDESC, ISC_LOG_DYNAMIC, &destination, 0) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_log_usechannel(logconfig, "stderr", NULL, NULL) == ISC_R_SUCCESS); *logp = log; return (ISC_R_SUCCESS); } /*% scan the zone for oversize TTLs */ static isc_result_t check_ttls(dns_zone_t *zone, dns_ttl_t maxttl) { isc_result_t result; dns_db_t *db = NULL; dns_dbversion_t *version = NULL; dns_dbnode_t *node = NULL; dns_dbiterator_t *dbiter = NULL; dns_rdatasetiter_t *rdsiter = NULL; dns_rdataset_t rdataset; dns_fixedname_t fname; dns_name_t *name; dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_rdataset_init(&rdataset); CHECK(dns_zone_getdb(zone, &db)); INSIST(db != NULL); CHECK(dns_db_newversion(db, &version)); CHECK(dns_db_createiterator(db, 0, &dbiter)); for (result = dns_dbiterator_first(dbiter); result == ISC_R_SUCCESS; result = dns_dbiterator_next(dbiter)) { result = dns_dbiterator_current(dbiter, &node, name); if (result == DNS_R_NEWORIGIN) result = ISC_R_SUCCESS; CHECK(result); CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsiter)); for (result = dns_rdatasetiter_first(rdsiter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsiter)) { dns_rdatasetiter_current(rdsiter, &rdataset); if (rdataset.ttl > maxttl) { char nbuf[DNS_NAME_FORMATSIZE]; char tbuf[255]; isc_buffer_t b; isc_region_t r; dns_name_format(name, nbuf, sizeof(nbuf)); isc_buffer_init(&b, tbuf, sizeof(tbuf) - 1); CHECK(dns_rdatatype_totext(rdataset.type, &b)); isc_buffer_usedregion(&b, &r); r.base[r.length] = 0; dns_zone_log(zone, ISC_LOG_ERROR, "%s/%s TTL %d exceeds " "maximum TTL %d", nbuf, tbuf, rdataset.ttl, maxttl); dns_rdataset_disassociate(&rdataset); CHECK(ISC_R_RANGE); } dns_rdataset_disassociate(&rdataset); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; CHECK(result); dns_rdatasetiter_destroy(&rdsiter); dns_db_detachnode(db, &node); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; cleanup: if (node != NULL) dns_db_detachnode(db, &node); if (rdsiter != NULL) dns_rdatasetiter_destroy(&rdsiter); if (dbiter != NULL) dns_dbiterator_destroy(&dbiter); if (version != NULL) dns_db_closeversion(db, &version, ISC_FALSE); if (db != NULL) dns_db_detach(&db); return (result); } /*% load the zone */ isc_result_t load_zone(isc_mem_t *mctx, const char *zonename, const char *filename, dns_masterformat_t fileformat, const char *classname, dns_ttl_t maxttl, dns_zone_t **zonep) { isc_result_t result; dns_rdataclass_t rdclass; isc_textregion_t region; isc_buffer_t buffer; dns_fixedname_t fixorigin; dns_name_t *origin; dns_zone_t *zone = NULL; REQUIRE(zonep == NULL || *zonep == NULL); if (debug) fprintf(stderr, "loading \"%s\" from \"%s\" class \"%s\"\n", zonename, filename, classname); CHECK(dns_zone_create(&zone, mctx)); dns_zone_settype(zone, dns_zone_master); isc_buffer_constinit(&buffer, zonename, strlen(zonename)); isc_buffer_add(&buffer, strlen(zonename)); dns_fixedname_init(&fixorigin); origin = dns_fixedname_name(&fixorigin); CHECK(dns_name_fromtext(origin, &buffer, dns_rootname, 0, NULL)); CHECK(dns_zone_setorigin(zone, origin)); CHECK(dns_zone_setdbtype(zone, 1, (const char * const *) dbtype)); CHECK(dns_zone_setfile2(zone, filename, fileformat)); if (journal != NULL) CHECK(dns_zone_setjournal(zone, journal)); DE_CONST(classname, region.base); region.length = strlen(classname); CHECK(dns_rdataclass_fromtext(&rdclass, ®ion)); dns_zone_setclass(zone, rdclass); dns_zone_setoption(zone, zone_options, ISC_TRUE); dns_zone_setoption2(zone, zone_options2, ISC_TRUE); dns_zone_setoption(zone, DNS_ZONEOPT_NOMERGE, nomerge); dns_zone_setmaxttl(zone, maxttl); if (docheckmx) dns_zone_setcheckmx(zone, checkmx); if (docheckns) dns_zone_setcheckns(zone, checkns); if (dochecksrv) dns_zone_setchecksrv(zone, checksrv); CHECK(dns_zone_load(zone)); /* * When loading map files we can't catch oversize TTLs during * load, so we check for them here. */ if (fileformat == dns_masterformat_map && maxttl != 0) { CHECK(check_ttls(zone, maxttl)); } if (zonep != NULL) { *zonep = zone; zone = NULL; } cleanup: if (zone != NULL) dns_zone_detach(&zone); return (result); } /*% dump the zone */ isc_result_t dump_zone(const char *zonename, dns_zone_t *zone, const char *filename, dns_masterformat_t fileformat, const dns_master_style_t *style, const isc_uint32_t rawversion) { isc_result_t result; FILE *output = stdout; const char *flags; flags = (fileformat == dns_masterformat_text) ? "w+" : "wb+"; if (debug) { if (filename != NULL && strcmp(filename, "-") != 0) fprintf(stderr, "dumping \"%s\" to \"%s\"\n", zonename, filename); else fprintf(stderr, "dumping \"%s\"\n", zonename); } if (filename != NULL && strcmp(filename, "-") != 0) { result = isc_stdio_open(filename, flags, &output); if (result != ISC_R_SUCCESS) { fprintf(stderr, "could not open output " "file \"%s\" for writing\n", filename); return (ISC_R_FAILURE); } } result = dns_zone_dumptostream3(zone, output, fileformat, style, rawversion); if (output != stdout) (void)isc_stdio_close(output); return (result); } #ifdef _WIN32 void InitSockets(void) { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(2, 0); err = WSAStartup( wVersionRequested, &wsaData ); if (err != 0) { fprintf(stderr, "WSAStartup() failed: %d\n", err); exit(1); } } void DestroySockets(void) { WSACleanup(); } #endif bind9-9.10.3.dfsg.P4/bin/check/named-checkconf.c0000644000470500017500000004147012664710322020375 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2009-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: named-checkconf.c,v 1.56 2011/03/12 04:59:46 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "check-tool.h" static const char *program = "named-checkconf"; isc_log_t *logc = NULL; #define CHECK(r)\ do { \ result = (r); \ if (result != ISC_R_SUCCESS) \ goto cleanup; \ } while (0) /*% usage */ ISC_PLATFORM_NORETURN_PRE static void usage(void) ISC_PLATFORM_NORETURN_POST; static void usage(void) { fprintf(stderr, "usage: %s [-h] [-j] [-p] [-v] [-z] [-t directory] " "[named.conf]\n", program); exit(1); } /*% directory callback */ static isc_result_t directory_callback(const char *clausename, const cfg_obj_t *obj, void *arg) { isc_result_t result; const char *directory; REQUIRE(strcasecmp("directory", clausename) == 0); UNUSED(arg); UNUSED(clausename); /* * Change directory. */ directory = cfg_obj_asstring(obj); result = isc_dir_chdir(directory); if (result != ISC_R_SUCCESS) { cfg_obj_log(obj, logc, ISC_LOG_ERROR, "change directory to '%s' failed: %s\n", directory, isc_result_totext(result)); return (result); } return (ISC_R_SUCCESS); } static isc_boolean_t get_maps(const cfg_obj_t **maps, const char *name, const cfg_obj_t **obj) { int i; for (i = 0;; i++) { if (maps[i] == NULL) return (ISC_FALSE); if (cfg_map_get(maps[i], name, obj) == ISC_R_SUCCESS) return (ISC_TRUE); } } static isc_boolean_t get_checknames(const cfg_obj_t **maps, const cfg_obj_t **obj) { const cfg_listelt_t *element; const cfg_obj_t *checknames; const cfg_obj_t *type; const cfg_obj_t *value; isc_result_t result; int i; for (i = 0;; i++) { if (maps[i] == NULL) return (ISC_FALSE); checknames = NULL; result = cfg_map_get(maps[i], "check-names", &checknames); if (result != ISC_R_SUCCESS) continue; if (checknames != NULL && !cfg_obj_islist(checknames)) { *obj = checknames; return (ISC_TRUE); } for (element = cfg_list_first(checknames); element != NULL; element = cfg_list_next(element)) { value = cfg_listelt_value(element); type = cfg_tuple_get(value, "type"); if (strcasecmp(cfg_obj_asstring(type), "master") != 0) continue; *obj = cfg_tuple_get(value, "mode"); return (ISC_TRUE); } } } static isc_result_t configure_hint(const char *zfile, const char *zclass, isc_mem_t *mctx) { isc_result_t result; dns_db_t *db = NULL; dns_rdataclass_t rdclass; isc_textregion_t r; if (zfile == NULL) return (ISC_R_FAILURE); DE_CONST(zclass, r.base); r.length = strlen(zclass); result = dns_rdataclass_fromtext(&rdclass, &r); if (result != ISC_R_SUCCESS) return (result); result = dns_rootns_create(mctx, rdclass, zfile, &db); if (result != ISC_R_SUCCESS) return (result); dns_db_detach(&db); return (ISC_R_SUCCESS); } /*% configure the zone */ static isc_result_t configure_zone(const char *vclass, const char *view, const cfg_obj_t *zconfig, const cfg_obj_t *vconfig, const cfg_obj_t *config, isc_mem_t *mctx) { int i = 0; isc_result_t result; const char *zclass; const char *zname; const char *zfile = NULL; const cfg_obj_t *maps[4]; const cfg_obj_t *mastersobj = NULL; const cfg_obj_t *zoptions = NULL; const cfg_obj_t *classobj = NULL; const cfg_obj_t *typeobj = NULL; const cfg_obj_t *fileobj = NULL; const cfg_obj_t *dlzobj = NULL; const cfg_obj_t *dbobj = NULL; const cfg_obj_t *obj = NULL; const cfg_obj_t *fmtobj = NULL; dns_masterformat_t masterformat; dns_ttl_t maxttl = 0; zone_options = DNS_ZONEOPT_CHECKNS | DNS_ZONEOPT_MANYERRORS; zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); classobj = cfg_tuple_get(zconfig, "class"); if (!cfg_obj_isstring(classobj)) zclass = vclass; else zclass = cfg_obj_asstring(classobj); zoptions = cfg_tuple_get(zconfig, "options"); maps[i++] = zoptions; if (vconfig != NULL) maps[i++] = cfg_tuple_get(vconfig, "options"); if (config != NULL) { cfg_map_get(config, "options", &obj); if (obj != NULL) maps[i++] = obj; } maps[i] = NULL; cfg_map_get(zoptions, "type", &typeobj); if (typeobj == NULL) return (ISC_R_FAILURE); /* * Skip checks when using an alternate data source. */ cfg_map_get(zoptions, "database", &dbobj); if (dbobj != NULL && strcmp("rbt", cfg_obj_asstring(dbobj)) != 0 && strcmp("rbt64", cfg_obj_asstring(dbobj)) != 0) return (ISC_R_SUCCESS); cfg_map_get(zoptions, "dlz", &dlzobj); if (dlzobj != NULL) return (ISC_R_SUCCESS); cfg_map_get(zoptions, "file", &fileobj); if (fileobj != NULL) zfile = cfg_obj_asstring(fileobj); /* * Check hints files for hint zones. * Skip loading checks for any type other than * master and redirect */ if (strcasecmp(cfg_obj_asstring(typeobj), "hint") == 0) return (configure_hint(zfile, zclass, mctx)); else if ((strcasecmp(cfg_obj_asstring(typeobj), "master") != 0) && (strcasecmp(cfg_obj_asstring(typeobj), "redirect") != 0)) return (ISC_R_SUCCESS); /* * Is the redirect zone configured as a slave? */ if (strcasecmp(cfg_obj_asstring(typeobj), "redirect") == 0) { cfg_map_get(zoptions, "masters", &mastersobj); if (mastersobj != NULL) return (ISC_R_SUCCESS); } if (zfile == NULL) return (ISC_R_FAILURE); obj = NULL; if (get_maps(maps, "check-dup-records", &obj)) { if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { zone_options |= DNS_ZONEOPT_CHECKDUPRR; zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL; } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { zone_options |= DNS_ZONEOPT_CHECKDUPRR; zone_options |= DNS_ZONEOPT_CHECKDUPRRFAIL; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { zone_options &= ~DNS_ZONEOPT_CHECKDUPRR; zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL; } else INSIST(0); } else { zone_options |= DNS_ZONEOPT_CHECKDUPRR; zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL; } obj = NULL; if (get_maps(maps, "check-mx", &obj)) { if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { zone_options |= DNS_ZONEOPT_CHECKMX; zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { zone_options |= DNS_ZONEOPT_CHECKMX; zone_options |= DNS_ZONEOPT_CHECKMXFAIL; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { zone_options &= ~DNS_ZONEOPT_CHECKMX; zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; } else INSIST(0); } else { zone_options |= DNS_ZONEOPT_CHECKMX; zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; } obj = NULL; if (get_maps(maps, "check-integrity", &obj)) { if (cfg_obj_asboolean(obj)) zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; else zone_options &= ~DNS_ZONEOPT_CHECKINTEGRITY; } else zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; obj = NULL; if (get_maps(maps, "check-mx-cname", &obj)) { if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { zone_options |= DNS_ZONEOPT_WARNMXCNAME; zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { zone_options &= ~DNS_ZONEOPT_WARNMXCNAME; zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { zone_options |= DNS_ZONEOPT_WARNMXCNAME; zone_options |= DNS_ZONEOPT_IGNOREMXCNAME; } else INSIST(0); } else { zone_options |= DNS_ZONEOPT_WARNMXCNAME; zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; } obj = NULL; if (get_maps(maps, "check-srv-cname", &obj)) { if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { zone_options |= DNS_ZONEOPT_WARNSRVCNAME; zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { zone_options &= ~DNS_ZONEOPT_WARNSRVCNAME; zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { zone_options |= DNS_ZONEOPT_WARNSRVCNAME; zone_options |= DNS_ZONEOPT_IGNORESRVCNAME; } else INSIST(0); } else { zone_options |= DNS_ZONEOPT_WARNSRVCNAME; zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; } obj = NULL; if (get_maps(maps, "check-sibling", &obj)) { if (cfg_obj_asboolean(obj)) zone_options |= DNS_ZONEOPT_CHECKSIBLING; else zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; } obj = NULL; if (get_maps(maps, "check-spf", &obj)) { if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { zone_options |= DNS_ZONEOPT_CHECKSPF; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { zone_options &= ~DNS_ZONEOPT_CHECKSPF; } else INSIST(0); } else { zone_options |= DNS_ZONEOPT_CHECKSPF; } obj = NULL; if (get_checknames(maps, &obj)) { if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { zone_options |= DNS_ZONEOPT_CHECKNAMES; zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL; } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { zone_options |= DNS_ZONEOPT_CHECKNAMES; zone_options |= DNS_ZONEOPT_CHECKNAMESFAIL; } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { zone_options &= ~DNS_ZONEOPT_CHECKNAMES; zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL; } else INSIST(0); } else { zone_options |= DNS_ZONEOPT_CHECKNAMES; zone_options |= DNS_ZONEOPT_CHECKNAMESFAIL; } masterformat = dns_masterformat_text; fmtobj = NULL; if (get_maps(maps, "masterfile-format", &fmtobj)) { const char *masterformatstr = cfg_obj_asstring(fmtobj); if (strcasecmp(masterformatstr, "text") == 0) masterformat = dns_masterformat_text; else if (strcasecmp(masterformatstr, "raw") == 0) masterformat = dns_masterformat_raw; else if (strcasecmp(masterformatstr, "map") == 0) masterformat = dns_masterformat_map; else INSIST(0); } obj = NULL; if (get_maps(maps, "max-zone-ttl", &obj)) { maxttl = cfg_obj_asuint32(obj); zone_options2 |= DNS_ZONEOPT2_CHECKTTL; } result = load_zone(mctx, zname, zfile, masterformat, zclass, maxttl, NULL); if (result != ISC_R_SUCCESS) fprintf(stderr, "%s/%s/%s: %s\n", view, zname, zclass, dns_result_totext(result)); return (result); } /*% configure a view */ static isc_result_t configure_view(const char *vclass, const char *view, const cfg_obj_t *config, const cfg_obj_t *vconfig, isc_mem_t *mctx) { const cfg_listelt_t *element; const cfg_obj_t *voptions; const cfg_obj_t *zonelist; isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; voptions = NULL; if (vconfig != NULL) voptions = cfg_tuple_get(vconfig, "options"); zonelist = NULL; if (voptions != NULL) (void)cfg_map_get(voptions, "zone", &zonelist); else (void)cfg_map_get(config, "zone", &zonelist); for (element = cfg_list_first(zonelist); element != NULL; element = cfg_list_next(element)) { const cfg_obj_t *zconfig = cfg_listelt_value(element); tresult = configure_zone(vclass, view, zconfig, vconfig, config, mctx); if (tresult != ISC_R_SUCCESS) result = tresult; } return (result); } /*% load zones from the configuration */ static isc_result_t load_zones_fromconfig(const cfg_obj_t *config, isc_mem_t *mctx) { const cfg_listelt_t *element; const cfg_obj_t *classobj; const cfg_obj_t *views; const cfg_obj_t *vconfig; const char *vclass; isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; views = NULL; (void)cfg_map_get(config, "view", &views); for (element = cfg_list_first(views); element != NULL; element = cfg_list_next(element)) { const char *vname; vclass = "IN"; vconfig = cfg_listelt_value(element); if (vconfig != NULL) { classobj = cfg_tuple_get(vconfig, "class"); if (cfg_obj_isstring(classobj)) vclass = cfg_obj_asstring(classobj); } vname = cfg_obj_asstring(cfg_tuple_get(vconfig, "name")); tresult = configure_view(vclass, vname, config, vconfig, mctx); if (tresult != ISC_R_SUCCESS) result = tresult; } if (views == NULL) { tresult = configure_view("IN", "_default", config, NULL, mctx); if (tresult != ISC_R_SUCCESS) result = tresult; } return (result); } static void output(void *closure, const char *text, int textlen) { UNUSED(closure); if (fwrite(text, 1, textlen, stdout) != (size_t)textlen) { perror("fwrite"); exit(1); } } /*% The main processing routine */ int main(int argc, char **argv) { int c; cfg_parser_t *parser = NULL; cfg_obj_t *config = NULL; const char *conffile = NULL; isc_mem_t *mctx = NULL; isc_result_t result; int exit_status = 0; isc_entropy_t *ectx = NULL; isc_boolean_t load_zones = ISC_FALSE; isc_boolean_t print = ISC_FALSE; unsigned int flags = 0; isc_commandline_errprint = ISC_FALSE; /* * Process memory debugging argument first. */ #define CMDLINE_FLAGS "dhjm:t:pvxz" while ((c = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { switch (c) { case 'm': if (strcasecmp(isc_commandline_argument, "record") == 0) isc_mem_debugging |= ISC_MEM_DEBUGRECORD; if (strcasecmp(isc_commandline_argument, "trace") == 0) isc_mem_debugging |= ISC_MEM_DEBUGTRACE; if (strcasecmp(isc_commandline_argument, "usage") == 0) isc_mem_debugging |= ISC_MEM_DEBUGUSAGE; if (strcasecmp(isc_commandline_argument, "size") == 0) isc_mem_debugging |= ISC_MEM_DEBUGSIZE; if (strcasecmp(isc_commandline_argument, "mctx") == 0) isc_mem_debugging |= ISC_MEM_DEBUGCTX; break; default: break; } } isc_commandline_reset = ISC_TRUE; RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); while ((c = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != EOF) { switch (c) { case 'd': debug++; break; case 'j': nomerge = ISC_FALSE; break; case 'm': break; case 't': result = isc_dir_chroot(isc_commandline_argument); if (result != ISC_R_SUCCESS) { fprintf(stderr, "isc_dir_chroot: %s\n", isc_result_totext(result)); exit(1); } break; case 'p': print = ISC_TRUE; break; case 'v': printf(VERSION "\n"); exit(0); case 'x': flags |= CFG_PRINTER_XKEY; break; case 'z': load_zones = ISC_TRUE; docheckmx = ISC_FALSE; docheckns = ISC_FALSE; dochecksrv = ISC_FALSE; break; case '?': if (isc_commandline_option != '?') fprintf(stderr, "%s: invalid argument -%c\n", program, isc_commandline_option); /* FALLTHROUGH */ case 'h': usage(); default: fprintf(stderr, "%s: unhandled option -%c\n", program, isc_commandline_option); exit(1); } } if (((flags & CFG_PRINTER_XKEY) != 0) && !print) { fprintf(stderr, "%s: -x cannot be used without -p\n", program); exit(1); } if (isc_commandline_index + 1 < argc) usage(); if (argv[isc_commandline_index] != NULL) conffile = argv[isc_commandline_index]; if (conffile == NULL || conffile[0] == '\0') conffile = NAMED_CONFFILE; #ifdef _WIN32 InitSockets(); #endif RUNTIME_CHECK(setup_logging(mctx, stdout, &logc) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE) == ISC_R_SUCCESS); dns_result_register(); RUNTIME_CHECK(cfg_parser_create(mctx, logc, &parser) == ISC_R_SUCCESS); cfg_parser_setcallback(parser, directory_callback, NULL); if (cfg_parse_file(parser, conffile, &cfg_type_namedconf, &config) != ISC_R_SUCCESS) exit(1); result = bind9_check_namedconf(config, logc, mctx); if (result != ISC_R_SUCCESS) exit_status = 1; if (result == ISC_R_SUCCESS && load_zones) { result = load_zones_fromconfig(config, mctx); if (result != ISC_R_SUCCESS) exit_status = 1; } if (print && exit_status == 0) cfg_printx(config, flags, output, NULL); cfg_obj_destroy(parser, &config); cfg_parser_destroy(&parser); dns_name_destroy(); isc_log_destroy(&logc); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); #ifdef _WIN32 DestroySockets(); #endif return (exit_status); } bind9-9.10.3.dfsg.P4/bin/Makefile.in0000644000470500017500000000213012664710322016202 0ustar lamontlamont# Copyright (C) 2004, 2007, 2009, 2012-2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.29 2009/10/05 12:07:08 fdupont Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ SUBDIRS = named rndc dig delv dnssec tools tests nsupdate \ check confgen @PYTHON_TOOLS@ @PKCS11_TOOLS@ TARGETS = @BIND9_MAKE_RULES@ bind9-9.10.3.dfsg.P4/bin/dnssec/0002755000470500017500000000000012672612753015432 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-verify.html0000644000470500017500000001435612664710322021100 0ustar lamontlamont dnssec-verify

Name

dnssec-verify — DNSSEC zone verification tool

Synopsis

dnssec-verify [-c class] [-E engine] [-I input-format] [-o origin] [-v level] [-V] [-x] [-z] {zonefile}

DESCRIPTION

dnssec-verify verifies that a zone is fully signed for each algorithm found in the DNSKEY RRset for the zone, and that the NSEC / NSEC3 chains are complete.

OPTIONS

-c class

Specifies the DNS class of the zone.

-E engine

Specifies the cryptographic hardware to use, when applicable.

When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (--enable-native-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "--with-pkcs11".

-I input-format

The format of the input zone file. Possible formats are "text" (default) and "raw". This option is primarily intended to be used for dynamic signed zones so that the dumped zone file in a non-text format containing updates can be verified independently. The use of this option does not make much sense for non-dynamic zones.

-o origin

The zone origin. If not specified, the name of the zone file is assumed to be the origin.

-v level

Sets the debugging level.

-V

Prints version information.

-x

Only verify that the DNSKEY RRset is signed with key-signing keys. Without this flag, it is assumed that the DNSKEY RRset will be signed by all active keys. When this flag is set, it will not be an error if the DNSKEY RRset is not signed by zone-signing keys. This corresponds to the -x option in dnssec-signzone.

-z

Ignore the KSK flag on the keys when determining whether the zone if correctly signed. Without this flag it is assumed that there will be a non-revoked, self-signed DNSKEY with the KSK flag set for each algorithm and that RRsets other than DNSKEY RRset will be signed with a different DNSKEY without the KSK flag set.

With this flag set, we only require that for each algorithm, there will be at least one non-revoked, self-signed DNSKEY, regardless of the KSK flag state, and that other RRsets will be signed by a non-revoked key for the same algorithm that includes the self-signed key; the same key may be used for both purposes. This corresponds to the -z option in dnssec-signzone.

zonefile

The file containing the zone to be signed.

SEE ALSO

dnssec-signzone(8), BIND 9 Administrator Reference Manual, RFC 4033.

AUTHOR

Internet Systems Consortium

bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-verify.c0000644000470500017500000002057012664710322020351 0ustar lamontlamont/* * Copyright (C) 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef PKCS11CRYPTO #include #endif #include "dnssectool.h" const char *program = "dnssec-verify"; int verbose; static isc_stdtime_t now; static isc_mem_t *mctx = NULL; static isc_entropy_t *ectx = NULL; static dns_masterformat_t inputformat = dns_masterformat_text; static dns_db_t *gdb; /* The database */ static dns_dbversion_t *gversion; /* The database version */ static dns_rdataclass_t gclass; /* The class */ static dns_name_t *gorigin; /* The database origin */ static isc_boolean_t ignore_kskflag = ISC_FALSE; static isc_boolean_t keyset_kskonly = ISC_FALSE; /*% * Load the zone file from disk */ static void loadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) { isc_buffer_t b; int len; dns_fixedname_t fname; dns_name_t *name; isc_result_t result; len = strlen(origin); isc_buffer_init(&b, origin, len); isc_buffer_add(&b, len); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) fatal("failed converting name '%s' to dns format: %s", origin, isc_result_totext(result)); result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone, rdclass, 0, NULL, db); check_result(result, "dns_db_create()"); result = dns_db_load2(*db, file, inputformat); if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) fatal("failed loading zone from '%s': %s", file, isc_result_totext(result)); } ISC_PLATFORM_NORETURN_PRE static void usage(void) ISC_PLATFORM_NORETURN_POST; static void usage(void) { fprintf(stderr, "Usage:\n"); fprintf(stderr, "\t%s [options] zonefile [keys]\n", program); fprintf(stderr, "\n"); fprintf(stderr, "Version: %s\n", VERSION); fprintf(stderr, "Options: (default value in parenthesis) \n"); fprintf(stderr, "\t-v debuglevel (0)\n"); fprintf(stderr, "\t-V:\tprint version information\n"); fprintf(stderr, "\t-o origin:\n"); fprintf(stderr, "\t\tzone origin (name of zonefile)\n"); fprintf(stderr, "\t-I format:\n"); fprintf(stderr, "\t\tfile format of input zonefile (text)\n"); fprintf(stderr, "\t-c class (IN)\n"); fprintf(stderr, "\t-E engine:\n"); #if defined(PKCS11CRYPTO) fprintf(stderr, "\t\tpath to PKCS#11 provider library " "(default is %s)\n", PK11_LIB_LOCATION); #elif defined(USE_PKCS11) fprintf(stderr, "\t\tname of an OpenSSL engine to use " "(default is \"pkcs11\")\n"); #else fprintf(stderr, "\t\tname of an OpenSSL engine to use\n"); #endif fprintf(stderr, "\t-x:\tDNSKEY record signed with KSKs only, " "not ZSKs\n"); fprintf(stderr, "\t-z:\tAll records signed with KSKs\n"); exit(0); } int main(int argc, char *argv[]) { char *origin = NULL, *file = NULL; char *inputformatstr = NULL; isc_result_t result; isc_log_t *log = NULL; #ifdef USE_PKCS11 const char *engine = PKCS11_ENGINE; #else const char *engine = NULL; #endif char *classname = NULL; dns_rdataclass_t rdclass; char *endp; int ch; #define CMDLINE_FLAGS \ "hm:o:I:c:E:v:Vxz" /* * Process memory debugging argument first. */ while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { switch (ch) { case 'm': if (strcasecmp(isc_commandline_argument, "record") == 0) isc_mem_debugging |= ISC_MEM_DEBUGRECORD; if (strcasecmp(isc_commandline_argument, "trace") == 0) isc_mem_debugging |= ISC_MEM_DEBUGTRACE; if (strcasecmp(isc_commandline_argument, "usage") == 0) isc_mem_debugging |= ISC_MEM_DEBUGUSAGE; if (strcasecmp(isc_commandline_argument, "size") == 0) isc_mem_debugging |= ISC_MEM_DEBUGSIZE; if (strcasecmp(isc_commandline_argument, "mctx") == 0) isc_mem_debugging |= ISC_MEM_DEBUGCTX; break; default: break; } } isc_commandline_reset = ISC_TRUE; check_result(isc_app_start(), "isc_app_start"); result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) fatal("out of memory"); #ifdef PKCS11CRYPTO pk11_result_register(); #endif dns_result_register(); isc_commandline_errprint = ISC_FALSE; while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { switch (ch) { case 'c': classname = isc_commandline_argument; break; case 'E': engine = isc_commandline_argument; break; case 'I': inputformatstr = isc_commandline_argument; break; case 'm': break; case 'o': origin = isc_commandline_argument; break; case 'v': endp = NULL; verbose = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') fatal("verbose level must be numeric"); break; case 'x': keyset_kskonly = ISC_TRUE; break; case 'z': ignore_kskflag = ISC_TRUE; break; case '?': if (isc_commandline_option != '?') fprintf(stderr, "%s: invalid argument -%c\n", program, isc_commandline_option); /* FALLTHROUGH */ case 'h': /* Does not return. */ usage(); case 'V': /* Does not return. */ version(program); default: fprintf(stderr, "%s: unhandled option -%c\n", program, isc_commandline_option); exit(1); } } if (ectx == NULL) setup_entropy(mctx, NULL, &ectx); result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (result != ISC_R_SUCCESS) fatal("could not create hash context"); result = dst_lib_init2(mctx, ectx, engine, ISC_ENTROPY_BLOCKING); if (result != ISC_R_SUCCESS) fatal("could not initialize dst: %s", isc_result_totext(result)); isc_stdtime_get(&now); rdclass = strtoclass(classname); setup_logging(mctx, &log); argc -= isc_commandline_index; argv += isc_commandline_index; if (argc < 1) usage(); file = argv[0]; argc -= 1; argv += 1; POST(argc); POST(argv); if (origin == NULL) origin = file; if (inputformatstr != NULL) { if (strcasecmp(inputformatstr, "text") == 0) inputformat = dns_masterformat_text; else if (strcasecmp(inputformatstr, "raw") == 0) inputformat = dns_masterformat_raw; else fatal("unknown file format: %s\n", inputformatstr); } gdb = NULL; fprintf(stderr, "Loading zone '%s' from file '%s'\n", origin, file); loadzone(file, origin, rdclass, &gdb); gorigin = dns_db_origin(gdb); gclass = dns_db_class(gdb); gversion = NULL; result = dns_db_newversion(gdb, &gversion); check_result(result, "dns_db_newversion()"); verifyzone(gdb, gversion, gorigin, mctx, ignore_kskflag, keyset_kskonly); dns_db_closeversion(gdb, &gversion, ISC_FALSE); dns_db_detach(&gdb); cleanup_logging(&log); dst_lib_destroy(); isc_hash_destroy(); cleanup_entropy(&ectx); dns_name_destroy(); if (verbose > 10) isc_mem_stats(mctx, stdout); isc_mem_destroy(&mctx); (void) isc_app_finish(); return (0); } bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-settime.c0000644000470500017500000004107412664710322020521 0ustar lamontlamont/* * Copyright (C) 2009-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef PKCS11CRYPTO #include #endif #include "dnssectool.h" const char *program = "dnssec-settime"; int verbose; static isc_mem_t *mctx = NULL; ISC_PLATFORM_NORETURN_PRE static void usage(void) ISC_PLATFORM_NORETURN_POST; static void usage(void) { fprintf(stderr, "Usage:\n"); fprintf(stderr, " %s [options] keyfile\n\n", program); fprintf(stderr, "Version: %s\n", VERSION); fprintf(stderr, "General options:\n"); #if defined(PKCS11CRYPTO) fprintf(stderr, " -E engine: specify PKCS#11 provider " "(default: %s)\n", PK11_LIB_LOCATION); #elif defined(USE_PKCS11) fprintf(stderr, " -E engine: specify OpenSSL engine " "(default \"pkcs11\")\n"); #else fprintf(stderr, " -E engine: specify OpenSSL engine\n"); #endif fprintf(stderr, " -f: force update of old-style " "keys\n"); fprintf(stderr, " -K directory: set key file location\n"); fprintf(stderr, " -L ttl: set default key TTL\n"); fprintf(stderr, " -v level: set level of verbosity\n"); fprintf(stderr, " -V: print version information\n"); fprintf(stderr, " -h: help\n"); fprintf(stderr, "Timing options:\n"); fprintf(stderr, " -P date/[+-]offset/none: set/unset key " "publication date\n"); fprintf(stderr, " -A date/[+-]offset/none: set/unset key " "activation date\n"); fprintf(stderr, " -R date/[+-]offset/none: set/unset key " "revocation date\n"); fprintf(stderr, " -I date/[+-]offset/none: set/unset key " "inactivation date\n"); fprintf(stderr, " -D date/[+-]offset/none: set/unset key " "deletion date\n"); fprintf(stderr, "Printing options:\n"); fprintf(stderr, " -p C/P/A/R/I/D/all: print a particular time " "value or values\n"); fprintf(stderr, " -u: print times in unix epoch " "format\n"); fprintf(stderr, "Output:\n"); fprintf(stderr, " K++.key, " "K++.private\n"); exit (-1); } static void printtime(dst_key_t *key, int type, const char *tag, isc_boolean_t epoch, FILE *stream) { isc_result_t result; const char *output = NULL; isc_stdtime_t when; if (tag != NULL) fprintf(stream, "%s: ", tag); result = dst_key_gettime(key, type, &when); if (result == ISC_R_NOTFOUND) { fprintf(stream, "UNSET\n"); } else if (epoch) { fprintf(stream, "%d\n", (int) when); } else { time_t timet = when; output = ctime(&timet); fprintf(stream, "%s", output); } } int main(int argc, char **argv) { isc_result_t result; #ifdef USE_PKCS11 const char *engine = PKCS11_ENGINE; #else const char *engine = NULL; #endif char *filename = NULL, *directory = NULL; char newname[1024]; char keystr[DST_KEY_FORMATSIZE]; char *endp, *p; int ch; isc_entropy_t *ectx = NULL; const char *predecessor = NULL; dst_key_t *prevkey = NULL; dst_key_t *key = NULL; isc_buffer_t buf; dns_name_t *name = NULL; dns_secalg_t alg = 0; unsigned int size = 0; isc_uint16_t flags = 0; int prepub = -1; dns_ttl_t ttl = 0; isc_stdtime_t now; isc_stdtime_t pub = 0, act = 0, rev = 0, inact = 0, del = 0; isc_stdtime_t prevact = 0, previnact = 0, prevdel = 0; isc_boolean_t setpub = ISC_FALSE, setact = ISC_FALSE; isc_boolean_t setrev = ISC_FALSE, setinact = ISC_FALSE; isc_boolean_t setdel = ISC_FALSE, setttl = ISC_FALSE; isc_boolean_t unsetpub = ISC_FALSE, unsetact = ISC_FALSE; isc_boolean_t unsetrev = ISC_FALSE, unsetinact = ISC_FALSE; isc_boolean_t unsetdel = ISC_FALSE; isc_boolean_t printcreate = ISC_FALSE, printpub = ISC_FALSE; isc_boolean_t printact = ISC_FALSE, printrev = ISC_FALSE; isc_boolean_t printinact = ISC_FALSE, printdel = ISC_FALSE; isc_boolean_t force = ISC_FALSE; isc_boolean_t epoch = ISC_FALSE; isc_boolean_t changed = ISC_FALSE; isc_log_t *log = NULL; if (argc == 1) usage(); result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) fatal("Out of memory"); setup_logging(mctx, &log); #ifdef PKCS11CRYPTO pk11_result_register(); #endif dns_result_register(); isc_commandline_errprint = ISC_FALSE; isc_stdtime_get(&now); #define CMDLINE_FLAGS "A:D:E:fhI:i:K:L:P:p:R:S:uv:V" while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { switch (ch) { case 'E': engine = isc_commandline_argument; break; case 'f': force = ISC_TRUE; break; case 'p': p = isc_commandline_argument; if (!strcasecmp(p, "all")) { printcreate = ISC_TRUE; printpub = ISC_TRUE; printact = ISC_TRUE; printrev = ISC_TRUE; printinact = ISC_TRUE; printdel = ISC_TRUE; break; } do { switch (*p++) { case 'C': printcreate = ISC_TRUE; break; case 'P': printpub = ISC_TRUE; break; case 'A': printact = ISC_TRUE; break; case 'R': printrev = ISC_TRUE; break; case 'I': printinact = ISC_TRUE; break; case 'D': printdel = ISC_TRUE; break; case ' ': break; default: usage(); break; } } while (*p != '\0'); break; case 'u': epoch = ISC_TRUE; break; case 'K': /* * We don't have to copy it here, but do it to * simplify cleanup later */ directory = isc_mem_strdup(mctx, isc_commandline_argument); if (directory == NULL) { fatal("Failed to allocate memory for " "directory"); } break; case 'L': ttl = strtottl(isc_commandline_argument); setttl = ISC_TRUE; break; case 'v': verbose = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') fatal("-v must be followed by a number"); break; case 'P': if (setpub || unsetpub) fatal("-P specified more than once"); changed = ISC_TRUE; pub = strtotime(isc_commandline_argument, now, now, &setpub); unsetpub = !setpub; break; case 'A': if (setact || unsetact) fatal("-A specified more than once"); changed = ISC_TRUE; act = strtotime(isc_commandline_argument, now, now, &setact); unsetact = !setact; break; case 'R': if (setrev || unsetrev) fatal("-R specified more than once"); changed = ISC_TRUE; rev = strtotime(isc_commandline_argument, now, now, &setrev); unsetrev = !setrev; break; case 'I': if (setinact || unsetinact) fatal("-I specified more than once"); changed = ISC_TRUE; inact = strtotime(isc_commandline_argument, now, now, &setinact); unsetinact = !setinact; break; case 'D': if (setdel || unsetdel) fatal("-D specified more than once"); changed = ISC_TRUE; del = strtotime(isc_commandline_argument, now, now, &setdel); unsetdel = !setdel; break; case 'S': predecessor = isc_commandline_argument; break; case 'i': prepub = strtottl(isc_commandline_argument); break; case '?': if (isc_commandline_option != '?') fprintf(stderr, "%s: invalid argument -%c\n", program, isc_commandline_option); /* Falls into */ case 'h': /* Does not return. */ usage(); case 'V': /* Does not return. */ version(program); default: fprintf(stderr, "%s: unhandled option -%c\n", program, isc_commandline_option); exit(1); } } if (argc < isc_commandline_index + 1 || argv[isc_commandline_index] == NULL) fatal("The key file name was not specified"); if (argc > isc_commandline_index + 1) fatal("Extraneous arguments"); if (ectx == NULL) setup_entropy(mctx, NULL, &ectx); result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (result != ISC_R_SUCCESS) fatal("Could not initialize hash"); result = dst_lib_init2(mctx, ectx, engine, ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); if (result != ISC_R_SUCCESS) fatal("Could not initialize dst: %s", isc_result_totext(result)); isc_entropy_stopcallbacksources(ectx); if (predecessor != NULL) { int major, minor; if (prepub == -1) prepub = (30 * 86400); if (setpub || unsetpub) fatal("-S and -P cannot be used together"); if (setact || unsetact) fatal("-S and -A cannot be used together"); result = dst_key_fromnamedfile(predecessor, directory, DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, mctx, &prevkey); if (result != ISC_R_SUCCESS) fatal("Invalid keyfile %s: %s", filename, isc_result_totext(result)); if (!dst_key_isprivate(prevkey) && !dst_key_isexternal(prevkey)) fatal("%s is not a private key", filename); name = dst_key_name(prevkey); alg = dst_key_alg(prevkey); size = dst_key_size(prevkey); flags = dst_key_flags(prevkey); dst_key_format(prevkey, keystr, sizeof(keystr)); dst_key_getprivateformat(prevkey, &major, &minor); if (major != DST_MAJOR_VERSION || minor < DST_MINOR_VERSION) fatal("Predecessor has incompatible format " "version %d.%d\n\t", major, minor); result = dst_key_gettime(prevkey, DST_TIME_ACTIVATE, &prevact); if (result != ISC_R_SUCCESS) fatal("Predecessor has no activation date. " "You must set one before\n\t" "generating a successor."); result = dst_key_gettime(prevkey, DST_TIME_INACTIVE, &previnact); if (result != ISC_R_SUCCESS) fatal("Predecessor has no inactivation date. " "You must set one before\n\t" "generating a successor."); pub = prevact - prepub; if (pub < now && prepub != 0) fatal("Predecessor will become inactive before the\n\t" "prepublication period ends. Either change " "its inactivation date,\n\t" "or use the -i option to set a shorter " "prepublication interval."); result = dst_key_gettime(prevkey, DST_TIME_DELETE, &prevdel); if (result != ISC_R_SUCCESS) fprintf(stderr, "%s: warning: Predecessor has no " "removal date;\n\t" "it will remain in the zone " "indefinitely after rollover.\n", program); else if (prevdel < previnact) fprintf(stderr, "%s: warning: Predecessor is " "scheduled to be deleted\n\t" "before it is scheduled to be " "inactive.\n", program); changed = setpub = setact = ISC_TRUE; } else { if (prepub < 0) prepub = 0; if (prepub > 0) { if (setpub && setact && (act - prepub) < pub) fatal("Activation and publication dates " "are closer together than the\n\t" "prepublication interval."); if (setpub && !setact) { setact = ISC_TRUE; act = pub + prepub; } else if (setact && !setpub) { setpub = ISC_TRUE; pub = act - prepub; } if ((act - prepub) < now) fatal("Time until activation is shorter " "than the\n\tprepublication interval."); } } if (directory != NULL) { filename = argv[isc_commandline_index]; } else { result = isc_file_splitpath(mctx, argv[isc_commandline_index], &directory, &filename); if (result != ISC_R_SUCCESS) fatal("cannot process filename %s: %s", argv[isc_commandline_index], isc_result_totext(result)); } result = dst_key_fromnamedfile(filename, directory, DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, mctx, &key); if (result != ISC_R_SUCCESS) fatal("Invalid keyfile %s: %s", filename, isc_result_totext(result)); if (!dst_key_isprivate(key) && !dst_key_isexternal(key)) fatal("%s is not a private key", filename); dst_key_format(key, keystr, sizeof(keystr)); if (predecessor != NULL) { if (!dns_name_equal(name, dst_key_name(key))) fatal("Key name mismatch"); if (alg != dst_key_alg(key)) fatal("Key algorithm mismatch"); if (size != dst_key_size(key)) fatal("Key size mismatch"); if (flags != dst_key_flags(key)) fatal("Key flags mismatch"); } prevdel = previnact = 0; if ((setdel && setinact && del < inact) || (dst_key_gettime(key, DST_TIME_INACTIVE, &previnact) == ISC_R_SUCCESS && setdel && !setinact && del < previnact) || (dst_key_gettime(key, DST_TIME_DELETE, &prevdel) == ISC_R_SUCCESS && setinact && !setdel && prevdel < inact) || (!setdel && !setinact && prevdel < previnact)) fprintf(stderr, "%s: warning: Key is scheduled to " "be deleted before it is\n\t" "scheduled to be inactive.\n", program); if (force) set_keyversion(key); else check_keyversion(key, keystr); if (verbose > 2) fprintf(stderr, "%s: %s\n", program, keystr); /* * Set time values. */ if (setpub) dst_key_settime(key, DST_TIME_PUBLISH, pub); else if (unsetpub) dst_key_unsettime(key, DST_TIME_PUBLISH); if (setact) dst_key_settime(key, DST_TIME_ACTIVATE, act); else if (unsetact) dst_key_unsettime(key, DST_TIME_ACTIVATE); if (setrev) { if ((dst_key_flags(key) & DNS_KEYFLAG_REVOKE) != 0) fprintf(stderr, "%s: warning: Key %s is already " "revoked; changing the revocation date " "will not affect this.\n", program, keystr); if ((dst_key_flags(key) & DNS_KEYFLAG_KSK) == 0) fprintf(stderr, "%s: warning: Key %s is not flagged as " "a KSK, but -R was used. Revoking a " "ZSK is legal, but undefined.\n", program, keystr); dst_key_settime(key, DST_TIME_REVOKE, rev); } else if (unsetrev) { if ((dst_key_flags(key) & DNS_KEYFLAG_REVOKE) != 0) fprintf(stderr, "%s: warning: Key %s is already " "revoked; removing the revocation date " "will not affect this.\n", program, keystr); dst_key_unsettime(key, DST_TIME_REVOKE); } if (setinact) dst_key_settime(key, DST_TIME_INACTIVE, inact); else if (unsetinact) dst_key_unsettime(key, DST_TIME_INACTIVE); if (setdel) dst_key_settime(key, DST_TIME_DELETE, del); else if (unsetdel) dst_key_unsettime(key, DST_TIME_DELETE); if (setttl) dst_key_setttl(key, ttl); /* * No metadata changes were made but we're forcing an upgrade * to the new format anyway: use "-P now -A now" as the default */ if (force && !changed) { dst_key_settime(key, DST_TIME_PUBLISH, now); dst_key_settime(key, DST_TIME_ACTIVATE, now); changed = ISC_TRUE; } if (!changed && setttl) changed = ISC_TRUE; /* * Print out time values, if -p was used. */ if (printcreate) printtime(key, DST_TIME_CREATED, "Created", epoch, stdout); if (printpub) printtime(key, DST_TIME_PUBLISH, "Publish", epoch, stdout); if (printact) printtime(key, DST_TIME_ACTIVATE, "Activate", epoch, stdout); if (printrev) printtime(key, DST_TIME_REVOKE, "Revoke", epoch, stdout); if (printinact) printtime(key, DST_TIME_INACTIVE, "Inactive", epoch, stdout); if (printdel) printtime(key, DST_TIME_DELETE, "Delete", epoch, stdout); if (changed) { isc_buffer_init(&buf, newname, sizeof(newname)); result = dst_key_buildfilename(key, DST_TYPE_PUBLIC, directory, &buf); if (result != ISC_R_SUCCESS) { fatal("Failed to build public key filename: %s", isc_result_totext(result)); } result = dst_key_tofile(key, DST_TYPE_PUBLIC|DST_TYPE_PRIVATE, directory); if (result != ISC_R_SUCCESS) { dst_key_format(key, keystr, sizeof(keystr)); fatal("Failed to write key %s: %s", keystr, isc_result_totext(result)); } printf("%s\n", newname); isc_buffer_clear(&buf); result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory, &buf); if (result != ISC_R_SUCCESS) { fatal("Failed to build private key filename: %s", isc_result_totext(result)); } printf("%s\n", newname); } if (prevkey != NULL) dst_key_free(&prevkey); dst_key_free(&key); dst_lib_destroy(); isc_hash_destroy(); cleanup_entropy(&ectx); if (verbose > 10) isc_mem_stats(mctx, stdout); cleanup_logging(&log); isc_mem_free(mctx, directory); isc_mem_destroy(&mctx); return (0); } bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-keygen.80000644000470500017500000003321712664710322020256 0ustar lamontlamont.\" Copyright (C) 2004, 2005, 2007-2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000-2003 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: dnssec\-keygen .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: February 06, 2014 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "DNSSEC\-KEYGEN" "8" "February 06, 2014" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" dnssec\-keygen \- DNSSEC key generation tool .SH "SYNOPSIS" .HP 14 \fBdnssec\-keygen\fR [\fB\-a\ \fR\fB\fIalgorithm\fR\fR] [\fB\-b\ \fR\fB\fIkeysize\fR\fR] [\fB\-n\ \fR\fB\fInametype\fR\fR] [\fB\-3\fR] [\fB\-A\ \fR\fB\fIdate/offset\fR\fR] [\fB\-C\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-G\fR] [\fB\-g\ \fR\fB\fIgenerator\fR\fR] [\fB\-h\fR] [\fB\-I\ \fR\fB\fIdate/offset\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-L\ \fR\fB\fIttl\fR\fR] [\fB\-k\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-q\fR] [\fB\-R\ \fR\fB\fIdate/offset\fR\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-S\ \fR\fB\fIkey\fR\fR] [\fB\-s\ \fR\fB\fIstrength\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-V\fR] [\fB\-z\fR] {name} .SH "DESCRIPTION" .PP \fBdnssec\-keygen\fR generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034. It can also generate keys for use with TSIG (Transaction Signatures) as defined in RFC 2845, or TKEY (Transaction Key) as defined in RFC 2930. .PP The \fBname\fR of the key is specified on the command line. For DNSSEC keys, this must match the name of the zone for which the key is being generated. .SH "OPTIONS" .PP \-a \fIalgorithm\fR .RS 4 Selects the cryptographic algorithm. For DNSSEC keys, the value of \fBalgorithm\fR must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512, ECCGOST, ECDSAP256SHA256 or ECDSAP384SHA384. For TSIG/TKEY, the value must be DH (Diffie Hellman), HMAC\-MD5, HMAC\-SHA1, HMAC\-SHA224, HMAC\-SHA256, HMAC\-SHA384, or HMAC\-SHA512. These values are case insensitive. .sp If no algorithm is specified, then RSASHA1 will be used by default, unless the \fB\-3\fR option is specified, in which case NSEC3RSASHA1 will be used instead. (If \fB\-3\fR is used and an algorithm is specified, that algorithm will be checked for compatibility with NSEC3.) .sp Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended. For TSIG, HMAC\-MD5 is mandatory. .sp Note 2: DH, HMAC\-MD5, and HMAC\-SHA1 through HMAC\-SHA512 automatically set the \-T KEY option. .RE .PP \-b \fIkeysize\fR .RS 4 Specifies the number of bits in the key. The choice of key size depends on the algorithm used. RSA keys must be between 512 and 2048 bits. Diffie Hellman keys must be between 128 and 4096 bits. DSA keys must be between 512 and 1024 bits and an exact multiple of 64. HMAC keys must be between 1 and 512 bits. Elliptic curve algorithms don't need this parameter. .sp The key size does not need to be specified if using a default algorithm. The default key size is 1024 bits for zone signing keys (ZSK's) and 2048 bits for key signing keys (KSK's, generated with \fB\-f KSK\fR). However, if an algorithm is explicitly specified with the \fB\-a\fR, then there is no default key size, and the \fB\-b\fR must be used. .RE .PP \-n \fInametype\fR .RS 4 Specifies the owner type of the key. The value of \fBnametype\fR must either be ZONE (for a DNSSEC zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with a host (KEY)), USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). These values are case insensitive. Defaults to ZONE for DNSKEY generation. .RE .PP \-3 .RS 4 Use an NSEC3\-capable algorithm to generate a DNSSEC key. If this option is used and no algorithm is explicitly set on the command line, NSEC3RSASHA1 will be used by default. Note that RSASHA256, RSASHA512, ECCGOST, ECDSAP256SHA256 and ECDSAP384SHA384 algorithms are NSEC3\-capable. .RE .PP \-C .RS 4 Compatibility mode: generates an old\-style key, without any metadata. By default, \fBdnssec\-keygen\fR will include the key's creation date in the metadata stored with the private key, and other dates may be set there as well (publication date, activation date, etc). Keys that include this data may be incompatible with older versions of BIND; the \fB\-C\fR option suppresses them. .RE .PP \-c \fIclass\fR .RS 4 Indicates that the DNS record containing the key should have the specified class. If not specified, class IN is used. .RE .PP \-E \fIengine\fR .RS 4 Specifies the cryptographic hardware to use, when applicable. .sp When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (\-\-enable\-native\-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "\-\-with\-pkcs11". .RE .PP \-f \fIflag\fR .RS 4 Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flags are KSK (Key Signing Key) and REVOKE. .RE .PP \-G .RS 4 Generate a key, but do not publish it or sign with it. This option is incompatible with \-P and \-A. .RE .PP \-g \fIgenerator\fR .RS 4 If generating a Diffie Hellman key, use this generator. Allowed values are 2 and 5. If no generator is specified, a known prime from RFC 2539 will be used if possible; otherwise the default is 2. .RE .PP \-h .RS 4 Prints a short summary of the options and arguments to \fBdnssec\-keygen\fR. .RE .PP \-K \fIdirectory\fR .RS 4 Sets the directory in which the key files are to be written. .RE .PP \-k .RS 4 Deprecated in favor of \-T KEY. .RE .PP \-L \fIttl\fR .RS 4 Sets the default TTL to use for this key when it is converted into a DNSKEY RR. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence. If this value is not set and there is no existing DNSKEY RRset, the TTL will default to the SOA TTL. Setting the default TTL to 0 or none is the same as leaving it unset. .RE .PP \-p \fIprotocol\fR .RS 4 Sets the protocol value for the generated key. The protocol is a number between 0 and 255. The default is 3 (DNSSEC). Other possible values for this argument are listed in RFC 2535 and its successors. .RE .PP \-q .RS 4 Quiet mode: Suppresses unnecessary output, including progress indication. Without this option, when \fBdnssec\-keygen\fR is run interactively to generate an RSA or DSA key pair, it will print a string of symbols to \fIstderr\fR indicating the progress of the key generation. A '.' indicates that a random number has been found which passed an initial sieve test; '+' means a number has passed a single round of the Miller\-Rabin primality test; a space means that the number has passed all the tests and is a satisfactory key. .RE .PP \-r \fIrandomdev\fR .RS 4 Specifies the source of randomness. If the operating system does not provide a \fI/dev/random\fR or equivalent device, the default source of randomness is keyboard input. \fIrandomdev\fR specifies the name of a character device or file containing random data to be used instead of the default. The special value \fIkeyboard\fR indicates that keyboard input should be used. .RE .PP \-S \fIkey\fR .RS 4 Create a new key which is an explicit successor to an existing key. The name, algorithm, size, and type of the key will be set to match the existing key. The activation date of the new key will be set to the inactivation date of the existing one. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days. .RE .PP \-s \fIstrength\fR .RS 4 Specifies the strength value of the key. The strength is a number between 0 and 15, and currently has no defined purpose in DNSSEC. .RE .PP \-T \fIrrtype\fR .RS 4 Specifies the resource record type to use for the key. \fBrrtype\fR must be either DNSKEY or KEY. The default is DNSKEY when using a DNSSEC algorithm, but it can be overridden to KEY for use with SIG(0). Using any TSIG algorithm (HMAC\-* or DH) forces this option to KEY. .RE .PP \-t \fItype\fR .RS 4 Indicates the use of the key. \fBtype\fR must be one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default is AUTHCONF. AUTH refers to the ability to authenticate data, and CONF the ability to encrypt data. .RE .PP \-v \fIlevel\fR .RS 4 Sets the debugging level. .RE .PP \-V .RS 4 Prints version information. .RE .SH "TIMING OPTIONS" .PP Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '\-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24\-hour days, ignoring leap years), months (defined as 30 24\-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To explicitly prevent a date from being set, use 'none' or 'never'. .PP \-P \fIdate/offset\fR .RS 4 Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it. If not set, and if the \-G option has not been used, the default is "now". .RE .PP \-A \fIdate/offset\fR .RS 4 Sets the date on which the key is to be activated. After that date, the key will be included in the zone and used to sign it. If not set, and if the \-G option has not been used, the default is "now". If set, if and \-P is not set, then the publication date will be set to the activation date minus the prepublication interval. .RE .PP \-R \fIdate/offset\fR .RS 4 Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it. .RE .PP \-I \fIdate/offset\fR .RS 4 Sets the date on which the key is to be retired. After that date, the key will still be included in the zone, but it will not be used to sign it. .RE .PP \-D \fIdate/offset\fR .RS 4 Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.) .RE .PP \-i \fIinterval\fR .RS 4 Sets the prepublication interval for a key. If set, then the publication and activation dates must be separated by at least this much time. If the activation date is specified but the publication date isn't, then the publication date will default to this much time before the activation date; conversely, if the publication date is specified but activation date isn't, then activation will be set to this much time after publication. .sp If the key is being created as an explicit successor to another key, then the default prepublication interval is 30 days; otherwise it is zero. .sp As with date offsets, if the argument is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the interval is measured in years, months, weeks, days, hours, or minutes, respectively. Without a suffix, the interval is measured in seconds. .RE .SH "GENERATED KEYS" .PP When \fBdnssec\-keygen\fR completes successfully, it prints a string of the form \fIKnnnn.+aaa+iiiii\fR to the standard output. This is an identification string for the key it has generated. .TP 4 \(bu \fInnnn\fR is the key name. .TP 4 \(bu \fIaaa\fR is the numeric representation of the algorithm. .TP 4 \(bu \fIiiiii\fR is the key identifier (or footprint). .PP \fBdnssec\-keygen\fR creates two files, with names based on the printed string. \fIKnnnn.+aaa+iiiii.key\fR contains the public key, and \fIKnnnn.+aaa+iiiii.private\fR contains the private key. .PP The \fI.key\fR file contains a DNS KEY record that can be inserted into a zone file (directly or with a $INCLUDE statement). .PP The \fI.private\fR file contains algorithm\-specific fields. For obvious security reasons, this file does not have general read permission. .PP Both \fI.key\fR and \fI.private\fR files are generated for symmetric encryption algorithms such as HMAC\-MD5, even though the public and private key are equivalent. .SH "EXAMPLE" .PP To generate a 768\-bit DSA key for the domain \fBexample.com\fR, the following command would be issued: .PP \fBdnssec\-keygen \-a DSA \-b 768 \-n ZONE example.com\fR .PP The command would print a string of the form: .PP \fBKexample.com.+003+26160\fR .PP In this example, \fBdnssec\-keygen\fR creates the files \fIKexample.com.+003+26160.key\fR and \fIKexample.com.+003+26160.private\fR. .SH "SEE ALSO" .PP \fBdnssec\-signzone\fR(8), BIND 9 Administrator Reference Manual, RFC 2539, RFC 2845, RFC 4034. .SH "AUTHOR" .PP Internet Systems Consortium .SH "COPYRIGHT" Copyright \(co 2004, 2005, 2007\-2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000\-2003 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-signzone.docbook0000644000470500017500000007671012664710322022106 0ustar lamontlamont]> February 18, 2014 dnssec-signzone 8 BIND9 dnssec-signzone DNSSEC zone signing tool 2004 2005 2006 2007 2008 2009 2011 2012 2013 2014 Internet Systems Consortium, Inc. ("ISC") 2000 2001 2002 2003 Internet Software Consortium. dnssec-signzone zonefile key DESCRIPTION dnssec-signzone signs a zone. It generates NSEC and RRSIG records and produces a signed version of the zone. The security status of delegations from the signed zone (that is, whether the child zones are secure or not) is determined by the presence or absence of a keyset file for each child zone. OPTIONS -a Verify all generated signatures. -c class Specifies the DNS class of the zone. -C Compatibility mode: Generate a keyset-zonename file in addition to dsset-zonename when signing a zone, for use by older versions of dnssec-signzone. -d directory Look for dsset- or keyset- files in . -D Output only those record types automatically managed by dnssec-signzone, i.e. RRSIG, NSEC, NSEC3 and NSEC3PARAM records. If smart signing () is used, DNSKEY records are also included. The resulting file can be included in the original zone file with $INCLUDE. This option cannot be combined with , , or serial number updating. -E engine When applicable, specifies the hardware to use for cryptographic operations, such as a secure key store used for signing. When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (--enable-native-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "--with-pkcs11". -g Generate DS records for child zones from dsset- or keyset- file. Existing DS records will be removed. -K directory Key repository: Specify a directory to search for DNSSEC keys. If not specified, defaults to the current directory. -k key Treat specified key as a key signing key ignoring any key flags. This option may be specified multiple times. -l domain Generate a DLV set in addition to the key (DNSKEY) and DS sets. The domain is appended to the name of the records. -M maxttl Sets the maximum TTL for the signed zone. Any TTL higher than maxttl in the input zone will be reduced to maxttl in the output. This provides certainty as to the largest possible TTL in the signed zone, which is useful to know when rolling keys because it is the longest possible time before signatures that have been retrieved by resolvers will expire from resolver caches. Zones that are signed with this option should be configured to use a matching in named.conf. (Note: This option is incompatible with , because it modifies non-DNSSEC data in the output zone.) -s start-time Specify the date and time when the generated RRSIG records become valid. This can be either an absolute or relative time. An absolute start time is indicated by a number in YYYYMMDDHHMMSS notation; 20000530144500 denotes 14:45:00 UTC on May 30th, 2000. A relative start time is indicated by +N, which is N seconds from the current time. If no is specified, the current time minus 1 hour (to allow for clock skew) is used. -e end-time Specify the date and time when the generated RRSIG records expire. As with , an absolute time is indicated in YYYYMMDDHHMMSS notation. A time relative to the start time is indicated with +N, which is N seconds from the start time. A time relative to the current time is indicated with now+N. If no is specified, 30 days from the start time is used as a default. must be later than . -X extended end-time Specify the date and time when the generated RRSIG records for the DNSKEY RRset will expire. This is to be used in cases when the DNSKEY signatures need to persist longer than signatures on other records; e.g., when the private component of the KSK is kept offline and the KSK signature is to be refreshed manually. As with , an absolute time is indicated in YYYYMMDDHHMMSS notation. A time relative to the start time is indicated with +N, which is N seconds from the start time. A time relative to the current time is indicated with now+N. If no is specified, the value of is used as the default. (, in turn, defaults to 30 days from the start time.) must be later than . -f output-file The name of the output file containing the signed zone. The default is to append .signed to the input filename. If is set to "-", then the signed zone is written to the standard output, with a default output format of "full". -h Prints a short summary of the options and arguments to dnssec-signzone. -V Prints version information. -i interval When a previously-signed zone is passed as input, records may be resigned. The option specifies the cycle interval as an offset from the current time (in seconds). If a RRSIG record expires after the cycle interval, it is retained. Otherwise, it is considered to be expiring soon, and it will be replaced. The default cycle interval is one quarter of the difference between the signature end and start times. So if neither or are specified, dnssec-signzone generates signatures that are valid for 30 days, with a cycle interval of 7.5 days. Therefore, if any existing RRSIG records are due to expire in less than 7.5 days, they would be replaced. -I input-format The format of the input zone file. Possible formats are "text" (default), "raw", and "map". This option is primarily intended to be used for dynamic signed zones so that the dumped zone file in a non-text format containing updates can be signed directly. The use of this option does not make much sense for non-dynamic zones. -j jitter When signing a zone with a fixed signature lifetime, all RRSIG records issued at the time of signing expires simultaneously. If the zone is incrementally signed, i.e. a previously-signed zone is passed as input to the signer, all expired signatures have to be regenerated at about the same time. The option specifies a jitter window that will be used to randomize the signature expire time, thus spreading incremental signature regeneration over time. Signature lifetime jitter also to some extent benefits validators and servers by spreading out cache expiration, i.e. if large numbers of RRSIGs don't expire at the same time from all caches there will be less congestion than if all validators need to refetch at mostly the same time. -L serial When writing a signed zone to "raw" or "map" format, set the "source serial" value in the header to the specified serial number. (This is expected to be used primarily for testing purposes.) -n ncpus Specifies the number of threads to use. By default, one thread is started for each detected CPU. -N soa-serial-format The SOA serial number format of the signed zone. Possible formats are "keep" (default), "increment" and "unixtime". "keep" Do not modify the SOA serial number. "increment" Increment the SOA serial number using RFC 1982 arithmetics. "unixtime" Set the SOA serial number to the number of seconds since epoch. -o origin The zone origin. If not specified, the name of the zone file is assumed to be the origin. -O output-format The format of the output file containing the signed zone. Possible formats are "text" (default), which is the standard textual representation of the zone; "full", which is text output in a format suitable for processing by external scripts; and "map", "raw", and "raw=N", which store the zone in binary formats for rapid loading by named. "raw=N" specifies the format version of the raw zone file: if N is 0, the raw file can be read by any version of named; if N is 1, the file can be read by release 9.9.0 or higher; the default is 1. -p Use pseudo-random data when signing the zone. This is faster, but less secure, than using real random data. This option may be useful when signing large zones or when the entropy source is limited. -P Disable post sign verification tests. The post sign verification test ensures that for each algorithm in use there is at least one non revoked self signed KSK key, that all revoked KSK keys are self signed, and that all records in the zone are signed by the algorithm. This option skips these tests. -Q Remove signatures from keys that are no longer active. Normally, when a previously-signed zone is passed as input to the signer, and a DNSKEY record has been removed and replaced with a new one, signatures from the old key that are still within their validity period are retained. This allows the zone to continue to validate with cached copies of the old DNSKEY RRset. The forces dnssec-signzone to remove signatures from keys that are no longer active. This enables ZSK rollover using the procedure described in RFC 4641, section 4.2.1.1 ("Pre-Publish Key Rollover"). -R Remove signatures from keys that are no longer published. This option is similar to , except it forces dnssec-signzone to signatures from keys that are no longer published. This enables ZSK rollover using the procedure described in RFC 4641, section 4.2.1.2 ("Double Signature Zone Signing Key Rollover"). -r randomdev Specifies the source of randomness. If the operating system does not provide a /dev/random or equivalent device, the default source of randomness is keyboard input. randomdev specifies the name of a character device or file containing random data to be used instead of the default. The special value keyboard indicates that keyboard input should be used. -S Smart signing: Instructs dnssec-signzone to search the key repository for keys that match the zone being signed, and to include them in the zone if appropriate. When a key is found, its timing metadata is examined to determine how it should be used, according to the following rules. Each successive rule takes priority over the prior ones: If no timing metadata has been set for the key, the key is published in the zone and used to sign the zone. If the key's publication date is set and is in the past, the key is published in the zone. If the key's activation date is set and in the past, the key is published (regardless of publication date) and used to sign the zone. If the key's revocation date is set and in the past, and the key is published, then the key is revoked, and the revoked key is used to sign the zone. If either of the key's unpublication or deletion dates are set and in the past, the key is NOT published or used to sign the zone, regardless of any other metadata. -T ttl Specifies a TTL to be used for new DNSKEY records imported into the zone from the key repository. If not specified, the default is the TTL value from the zone's SOA record. This option is ignored when signing without , since DNSKEY records are not imported from the key repository in that case. It is also ignored if there are any pre-existing DNSKEY records at the zone apex, in which case new records' TTL values will be set to match them, or if any of the imported DNSKEY records had a default TTL value. In the event of a a conflict between TTL values in imported keys, the shortest one is used. -t Print statistics at completion. -u Update NSEC/NSEC3 chain when re-signing a previously signed zone. With this option, a zone signed with NSEC can be switched to NSEC3, or a zone signed with NSEC3 can be switch to NSEC or to NSEC3 with different parameters. Without this option, dnssec-signzone will retain the existing chain when re-signing. -v level Sets the debugging level. -x Only sign the DNSKEY RRset with key-signing keys, and omit signatures from zone-signing keys. (This is similar to the dnssec-dnskey-kskonly yes; zone option in named.) -z Ignore KSK flag on key when determining what to sign. This causes KSK-flagged keys to sign all records, not just the DNSKEY RRset. (This is similar to the update-check-ksk no; zone option in named.) -3 salt Generate an NSEC3 chain with the given hex encoded salt. A dash (salt) can be used to indicate that no salt is to be used when generating the NSEC3 chain. -H iterations When generating an NSEC3 chain, use this many iterations. The default is 10. -A When generating an NSEC3 chain set the OPTOUT flag on all NSEC3 records and do not generate NSEC3 records for insecure delegations. Using this option twice (i.e., ) turns the OPTOUT flag off for all records. This is useful when using the option to modify an NSEC3 chain which previously had OPTOUT set. zonefile The file containing the zone to be signed. key Specify which keys should be used to sign the zone. If no keys are specified, then the zone will be examined for DNSKEY records at the zone apex. If these are found and there are matching private keys, in the current directory, then these will be used for signing. EXAMPLE The following command signs the example.com zone with the DSA key generated by dnssec-keygen (Kexample.com.+003+17247). Because the -S option is not being used, the zone's keys must be in the master file (db.example.com). This invocation looks for dsset files, in the current directory, so that DS records can be imported from them (-g). % dnssec-signzone -g -o example.com db.example.com \ Kexample.com.+003+17247 db.example.com.signed % In the above example, dnssec-signzone creates the file db.example.com.signed. This file should be referenced in a zone statement in a named.conf file. This example re-signs a previously signed zone with default parameters. The private keys are assumed to be in the current directory. % cp db.example.com.signed db.example.com % dnssec-signzone -o example.com db.example.com db.example.com.signed % SEE ALSO dnssec-keygen8 , BIND 9 Administrator Reference Manual, RFC 4033, RFC 4641. AUTHOR Internet Systems Consortium bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-signzone.html0000644000470500017500000007004112664710322021421 0ustar lamontlamont dnssec-signzone

Name

dnssec-signzone — DNSSEC zone signing tool

Synopsis

dnssec-signzone [-a] [-c class] [-d directory] [-D] [-E engine] [-e end-time] [-f output-file] [-g] [-h] [-K directory] [-k key] [-L serial] [-l domain] [-M domain] [-i interval] [-I input-format] [-j jitter] [-N soa-serial-format] [-o origin] [-O output-format] [-P] [-p] [-R] [-r randomdev] [-S] [-s start-time] [-T ttl] [-t] [-u] [-v level] [-V] [-X extended end-time] [-x] [-z] [-3 salt] [-H iterations] [-A] {zonefile} [key...]

DESCRIPTION

dnssec-signzone signs a zone. It generates NSEC and RRSIG records and produces a signed version of the zone. The security status of delegations from the signed zone (that is, whether the child zones are secure or not) is determined by the presence or absence of a keyset file for each child zone.

OPTIONS

-a

Verify all generated signatures.

-c class

Specifies the DNS class of the zone.

-C

Compatibility mode: Generate a keyset-zonename file in addition to dsset-zonename when signing a zone, for use by older versions of dnssec-signzone.

-d directory

Look for dsset- or keyset- files in directory.

-D

Output only those record types automatically managed by dnssec-signzone, i.e. RRSIG, NSEC, NSEC3 and NSEC3PARAM records. If smart signing (-S) is used, DNSKEY records are also included. The resulting file can be included in the original zone file with $INCLUDE. This option cannot be combined with -O raw, -O map, or serial number updating.

-E engine

When applicable, specifies the hardware to use for cryptographic operations, such as a secure key store used for signing.

When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (--enable-native-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "--with-pkcs11".

-g

Generate DS records for child zones from dsset- or keyset- file. Existing DS records will be removed.

-K directory

Key repository: Specify a directory to search for DNSSEC keys. If not specified, defaults to the current directory.

-k key

Treat specified key as a key signing key ignoring any key flags. This option may be specified multiple times.

-l domain

Generate a DLV set in addition to the key (DNSKEY) and DS sets. The domain is appended to the name of the records.

-M maxttl

Sets the maximum TTL for the signed zone. Any TTL higher than maxttl in the input zone will be reduced to maxttl in the output. This provides certainty as to the largest possible TTL in the signed zone, which is useful to know when rolling keys because it is the longest possible time before signatures that have been retrieved by resolvers will expire from resolver caches. Zones that are signed with this option should be configured to use a matching max-zone-ttl in named.conf. (Note: This option is incompatible with -D, because it modifies non-DNSSEC data in the output zone.)

-s start-time

Specify the date and time when the generated RRSIG records become valid. This can be either an absolute or relative time. An absolute start time is indicated by a number in YYYYMMDDHHMMSS notation; 20000530144500 denotes 14:45:00 UTC on May 30th, 2000. A relative start time is indicated by +N, which is N seconds from the current time. If no start-time is specified, the current time minus 1 hour (to allow for clock skew) is used.

-e end-time

Specify the date and time when the generated RRSIG records expire. As with start-time, an absolute time is indicated in YYYYMMDDHHMMSS notation. A time relative to the start time is indicated with +N, which is N seconds from the start time. A time relative to the current time is indicated with now+N. If no end-time is specified, 30 days from the start time is used as a default. end-time must be later than start-time.

-X extended end-time

Specify the date and time when the generated RRSIG records for the DNSKEY RRset will expire. This is to be used in cases when the DNSKEY signatures need to persist longer than signatures on other records; e.g., when the private component of the KSK is kept offline and the KSK signature is to be refreshed manually.

As with start-time, an absolute time is indicated in YYYYMMDDHHMMSS notation. A time relative to the start time is indicated with +N, which is N seconds from the start time. A time relative to the current time is indicated with now+N. If no extended end-time is specified, the value of end-time is used as the default. (end-time, in turn, defaults to 30 days from the start time.) extended end-time must be later than start-time.

-f output-file

The name of the output file containing the signed zone. The default is to append .signed to the input filename. If output-file is set to "-", then the signed zone is written to the standard output, with a default output format of "full".

-h

Prints a short summary of the options and arguments to dnssec-signzone.

-V

Prints version information.

-i interval

When a previously-signed zone is passed as input, records may be resigned. The interval option specifies the cycle interval as an offset from the current time (in seconds). If a RRSIG record expires after the cycle interval, it is retained. Otherwise, it is considered to be expiring soon, and it will be replaced.

The default cycle interval is one quarter of the difference between the signature end and start times. So if neither end-time or start-time are specified, dnssec-signzone generates signatures that are valid for 30 days, with a cycle interval of 7.5 days. Therefore, if any existing RRSIG records are due to expire in less than 7.5 days, they would be replaced.

-I input-format

The format of the input zone file. Possible formats are "text" (default), "raw", and "map". This option is primarily intended to be used for dynamic signed zones so that the dumped zone file in a non-text format containing updates can be signed directly. The use of this option does not make much sense for non-dynamic zones.

-j jitter

When signing a zone with a fixed signature lifetime, all RRSIG records issued at the time of signing expires simultaneously. If the zone is incrementally signed, i.e. a previously-signed zone is passed as input to the signer, all expired signatures have to be regenerated at about the same time. The jitter option specifies a jitter window that will be used to randomize the signature expire time, thus spreading incremental signature regeneration over time.

Signature lifetime jitter also to some extent benefits validators and servers by spreading out cache expiration, i.e. if large numbers of RRSIGs don't expire at the same time from all caches there will be less congestion than if all validators need to refetch at mostly the same time.

-L serial

When writing a signed zone to "raw" or "map" format, set the "source serial" value in the header to the specified serial number. (This is expected to be used primarily for testing purposes.)

-n ncpus

Specifies the number of threads to use. By default, one thread is started for each detected CPU.

-N soa-serial-format

The SOA serial number format of the signed zone. Possible formats are "keep" (default), "increment" and "unixtime".

"keep"

Do not modify the SOA serial number.

"increment"

Increment the SOA serial number using RFC 1982 arithmetics.

"unixtime"

Set the SOA serial number to the number of seconds since epoch.

-o origin

The zone origin. If not specified, the name of the zone file is assumed to be the origin.

-O output-format

The format of the output file containing the signed zone. Possible formats are "text" (default), which is the standard textual representation of the zone; "full", which is text output in a format suitable for processing by external scripts; and "map", "raw", and "raw=N", which store the zone in binary formats for rapid loading by named. "raw=N" specifies the format version of the raw zone file: if N is 0, the raw file can be read by any version of named; if N is 1, the file can be read by release 9.9.0 or higher; the default is 1.

-p

Use pseudo-random data when signing the zone. This is faster, but less secure, than using real random data. This option may be useful when signing large zones or when the entropy source is limited.

-P

Disable post sign verification tests.

The post sign verification test ensures that for each algorithm in use there is at least one non revoked self signed KSK key, that all revoked KSK keys are self signed, and that all records in the zone are signed by the algorithm. This option skips these tests.

-Q

Remove signatures from keys that are no longer active.

Normally, when a previously-signed zone is passed as input to the signer, and a DNSKEY record has been removed and replaced with a new one, signatures from the old key that are still within their validity period are retained. This allows the zone to continue to validate with cached copies of the old DNSKEY RRset. The -Q forces dnssec-signzone to remove signatures from keys that are no longer active. This enables ZSK rollover using the procedure described in RFC 4641, section 4.2.1.1 ("Pre-Publish Key Rollover").

-R

Remove signatures from keys that are no longer published.

This option is similar to -Q, except it forces dnssec-signzone to signatures from keys that are no longer published. This enables ZSK rollover using the procedure described in RFC 4641, section 4.2.1.2 ("Double Signature Zone Signing Key Rollover").

-r randomdev

Specifies the source of randomness. If the operating system does not provide a /dev/random or equivalent device, the default source of randomness is keyboard input. randomdev specifies the name of a character device or file containing random data to be used instead of the default. The special value keyboard indicates that keyboard input should be used.

-S

Smart signing: Instructs dnssec-signzone to search the key repository for keys that match the zone being signed, and to include them in the zone if appropriate.

When a key is found, its timing metadata is examined to determine how it should be used, according to the following rules. Each successive rule takes priority over the prior ones:

If no timing metadata has been set for the key, the key is published in the zone and used to sign the zone.

If the key's publication date is set and is in the past, the key is published in the zone.

If the key's activation date is set and in the past, the key is published (regardless of publication date) and used to sign the zone.

If the key's revocation date is set and in the past, and the key is published, then the key is revoked, and the revoked key is used to sign the zone.

If either of the key's unpublication or deletion dates are set and in the past, the key is NOT published or used to sign the zone, regardless of any other metadata.

-T ttl

Specifies a TTL to be used for new DNSKEY records imported into the zone from the key repository. If not specified, the default is the TTL value from the zone's SOA record. This option is ignored when signing without -S, since DNSKEY records are not imported from the key repository in that case. It is also ignored if there are any pre-existing DNSKEY records at the zone apex, in which case new records' TTL values will be set to match them, or if any of the imported DNSKEY records had a default TTL value. In the event of a a conflict between TTL values in imported keys, the shortest one is used.

-t

Print statistics at completion.

-u

Update NSEC/NSEC3 chain when re-signing a previously signed zone. With this option, a zone signed with NSEC can be switched to NSEC3, or a zone signed with NSEC3 can be switch to NSEC or to NSEC3 with different parameters. Without this option, dnssec-signzone will retain the existing chain when re-signing.

-v level

Sets the debugging level.

-x

Only sign the DNSKEY RRset with key-signing keys, and omit signatures from zone-signing keys. (This is similar to the dnssec-dnskey-kskonly yes; zone option in named.)

-z

Ignore KSK flag on key when determining what to sign. This causes KSK-flagged keys to sign all records, not just the DNSKEY RRset. (This is similar to the update-check-ksk no; zone option in named.)

-3 salt

Generate an NSEC3 chain with the given hex encoded salt. A dash (salt) can be used to indicate that no salt is to be used when generating the NSEC3 chain.

-H iterations

When generating an NSEC3 chain, use this many iterations. The default is 10.

-A

When generating an NSEC3 chain set the OPTOUT flag on all NSEC3 records and do not generate NSEC3 records for insecure delegations.

Using this option twice (i.e., -AA) turns the OPTOUT flag off for all records. This is useful when using the -u option to modify an NSEC3 chain which previously had OPTOUT set.

zonefile

The file containing the zone to be signed.

key

Specify which keys should be used to sign the zone. If no keys are specified, then the zone will be examined for DNSKEY records at the zone apex. If these are found and there are matching private keys, in the current directory, then these will be used for signing.

EXAMPLE

The following command signs the example.com zone with the DSA key generated by dnssec-keygen (Kexample.com.+003+17247). Because the -S option is not being used, the zone's keys must be in the master file (db.example.com). This invocation looks for dsset files, in the current directory, so that DS records can be imported from them (-g).

% dnssec-signzone -g -o example.com db.example.com \
Kexample.com.+003+17247
db.example.com.signed
%

In the above example, dnssec-signzone creates the file db.example.com.signed. This file should be referenced in a zone statement in a named.conf file.

This example re-signs a previously signed zone with default parameters. The private keys are assumed to be in the current directory.

% cp db.example.com.signed db.example.com
% dnssec-signzone -o example.com db.example.com
db.example.com.signed
%

SEE ALSO

dnssec-keygen(8), BIND 9 Administrator Reference Manual, RFC 4033, RFC 4641.

AUTHOR

Internet Systems Consortium

bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-verify.80000644000470500017500000001014412664710322020272 0ustar lamontlamont.\" Copyright (C) 2012, 2014 Internet Systems Consortium, Inc. ("ISC") .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: dnssec\-verify .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: January 15, 2014 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "DNSSEC\-VERIFY" "8" "January 15, 2014" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" dnssec\-verify \- DNSSEC zone verification tool .SH "SYNOPSIS" .HP 14 \fBdnssec\-verify\fR [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-I\ \fR\fB\fIinput\-format\fR\fR] [\fB\-o\ \fR\fB\fIorigin\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-V\fR] [\fB\-x\fR] [\fB\-z\fR] {zonefile} .SH "DESCRIPTION" .PP \fBdnssec\-verify\fR verifies that a zone is fully signed for each algorithm found in the DNSKEY RRset for the zone, and that the NSEC / NSEC3 chains are complete. .SH "OPTIONS" .PP \-c \fIclass\fR .RS 4 Specifies the DNS class of the zone. .RE .PP \-E \fIengine\fR .RS 4 Specifies the cryptographic hardware to use, when applicable. .sp When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (\-\-enable\-native\-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "\-\-with\-pkcs11". .RE .PP \-I \fIinput\-format\fR .RS 4 The format of the input zone file. Possible formats are \fB"text"\fR (default) and \fB"raw"\fR. This option is primarily intended to be used for dynamic signed zones so that the dumped zone file in a non\-text format containing updates can be verified independently. The use of this option does not make much sense for non\-dynamic zones. .RE .PP \-o \fIorigin\fR .RS 4 The zone origin. If not specified, the name of the zone file is assumed to be the origin. .RE .PP \-v \fIlevel\fR .RS 4 Sets the debugging level. .RE .PP \-V .RS 4 Prints version information. .RE .PP \-x .RS 4 Only verify that the DNSKEY RRset is signed with key\-signing keys. Without this flag, it is assumed that the DNSKEY RRset will be signed by all active keys. When this flag is set, it will not be an error if the DNSKEY RRset is not signed by zone\-signing keys. This corresponds to the \fB\-x\fR option in \fBdnssec\-signzone\fR. .RE .PP \-z .RS 4 Ignore the KSK flag on the keys when determining whether the zone if correctly signed. Without this flag it is assumed that there will be a non\-revoked, self\-signed DNSKEY with the KSK flag set for each algorithm and that RRsets other than DNSKEY RRset will be signed with a different DNSKEY without the KSK flag set. .sp With this flag set, we only require that for each algorithm, there will be at least one non\-revoked, self\-signed DNSKEY, regardless of the KSK flag state, and that other RRsets will be signed by a non\-revoked key for the same algorithm that includes the self\-signed key; the same key may be used for both purposes. This corresponds to the \fB\-z\fR option in \fBdnssec\-signzone\fR. .RE .PP zonefile .RS 4 The file containing the zone to be signed. .RE .SH "SEE ALSO" .PP \fBdnssec\-signzone\fR(8), BIND 9 Administrator Reference Manual, RFC 4033. .SH "AUTHOR" .PP Internet Systems Consortium .SH "COPYRIGHT" Copyright \(co 2012, 2014 Internet Systems Consortium, Inc. ("ISC") .br bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-keyfromlabel.docbook0000644000470500017500000004774112664710322022730 0ustar lamontlamont]> February 27, 2014 dnssec-keyfromlabel 8 BIND9 dnssec-keyfromlabel DNSSEC key generation tool 2008 2009 2010 2011 2012 2014 Internet Systems Consortium, Inc. ("ISC") dnssec-keyfromlabel -l label name DESCRIPTION dnssec-keyfromlabel generates a key pair of files that referencing a key object stored in a cryptographic hardware service module (HSM). The private key file can be used for DNSSEC signing of zone data as if it were a conventional signing key created by dnssec-keygen, but the key material is stored within the HSM, and the actual signing takes place there. The of the key is specified on the command line. This must match the name of the zone for which the key is being generated. OPTIONS -a algorithm Selects the cryptographic algorithm. The value of must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512, ECCGOST, ECDSAP256SHA256 or ECDSAP384SHA384. These values are case insensitive. If no algorithm is specified, then RSASHA1 will be used by default, unless the option is specified, in which case NSEC3RSASHA1 will be used instead. (If is used and an algorithm is specified, that algorithm will be checked for compatibility with NSEC3.) Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended. Note 2: DH automatically sets the -k flag. -3 Use an NSEC3-capable algorithm to generate a DNSSEC key. If this option is used and no algorithm is explicitly set on the command line, NSEC3RSASHA1 will be used by default. -E engine Specifies the cryptographic hardware to use. When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (--enable-native-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "--with-pkcs11". -l label Specifies the label for a key pair in the crypto hardware. When BIND 9 is built with OpenSSL-based PKCS#11 support, the label is an arbitrary string that identifies a particular key. It may be preceded by an optional OpenSSL engine name, followed by a colon, as in "pkcs11:keylabel". When BIND 9 is built with native PKCS#11 support, the label is a PKCS#11 URI string in the format "pkcs11:=value;=value;..." Keywords include "token", which identifies the HSM; "object", which identifies the key; and "pin-source", which identifies a file from which the HSM's PIN code can be obtained. The label will be stored in the on-disk "private" file. If the label contains a field, tools using the generated key files will be able to use the HSM for signing and other operations without any need for an operator to manually enter a PIN. Note: Making the HSM's PIN accessible in this manner may reduce the security advantage of using an HSM; be sure this is what you want to do before making use of this feature. -n nametype Specifies the owner type of the key. The value of must either be ZONE (for a DNSSEC zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with a host (KEY)), USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). These values are case insensitive. -C Compatibility mode: generates an old-style key, without any metadata. By default, dnssec-keyfromlabel will include the key's creation date in the metadata stored with the private key, and other dates may be set there as well (publication date, activation date, etc). Keys that include this data may be incompatible with older versions of BIND; the option suppresses them. -c class Indicates that the DNS record containing the key should have the specified class. If not specified, class IN is used. -f flag Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flags are KSK (Key Signing Key) and REVOKE. -G Generate a key, but do not publish it or sign with it. This option is incompatible with -P and -A. -h Prints a short summary of the options and arguments to dnssec-keyfromlabel. -K directory Sets the directory in which the key files are to be written. -k Generate KEY records rather than DNSKEY records. -L ttl Sets the default TTL to use for this key when it is converted into a DNSKEY RR. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence. Setting the default TTL to 0 or none removes it. -p protocol Sets the protocol value for the key. The protocol is a number between 0 and 255. The default is 3 (DNSSEC). Other possible values for this argument are listed in RFC 2535 and its successors. -S key Generate a key as an explicit successor to an existing key. The name, algorithm, size, and type of the key will be set to match the predecessor. The activation date of the new key will be set to the inactivation date of the existing one. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days. -t type Indicates the use of the key. must be one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default is AUTHCONF. AUTH refers to the ability to authenticate data, and CONF the ability to encrypt data. -v level Sets the debugging level. -V Prints version information. -y Allows DNSSEC key files to be generated even if the key ID would collide with that of an existing key, in the event of either key being revoked. (This is only safe to use if you are sure you won't be using RFC 5011 trust anchor maintenance with either of the keys involved.) TIMING OPTIONS Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24-hour days, ignoring leap years), months (defined as 30 24-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To explicitly prevent a date from being set, use 'none' or 'never'. -P date/offset Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it. If not set, and if the -G option has not been used, the default is "now". -A date/offset Sets the date on which the key is to be activated. After that date, the key will be included in the zone and used to sign it. If not set, and if the -G option has not been used, the default is "now". -R date/offset Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it. -I date/offset Sets the date on which the key is to be retired. After that date, the key will still be included in the zone, but it will not be used to sign it. -D date/offset Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.) -i interval Sets the prepublication interval for a key. If set, then the publication and activation dates must be separated by at least this much time. If the activation date is specified but the publication date isn't, then the publication date will default to this much time before the activation date; conversely, if the publication date is specified but activation date isn't, then activation will be set to this much time after publication. If the key is being created as an explicit successor to another key, then the default prepublication interval is 30 days; otherwise it is zero. As with date offsets, if the argument is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the interval is measured in years, months, weeks, days, hours, or minutes, respectively. Without a suffix, the interval is measured in seconds. GENERATED KEY FILES When dnssec-keyfromlabel completes successfully, it prints a string of the form Knnnn.+aaa+iiiii to the standard output. This is an identification string for the key files it has generated. nnnn is the key name. aaa is the numeric representation of the algorithm. iiiii is the key identifier (or footprint). dnssec-keyfromlabel creates two files, with names based on the printed string. Knnnn.+aaa+iiiii.key contains the public key, and Knnnn.+aaa+iiiii.private contains the private key. The .key file contains a DNS KEY record that can be inserted into a zone file (directly or with a $INCLUDE statement). The .private file contains algorithm-specific fields. For obvious security reasons, this file does not have general read permission. SEE ALSO dnssec-keygen8 , dnssec-signzone8 , BIND 9 Administrator Reference Manual, RFC 4034, The PKCS#11 URI Scheme (draft-pechanec-pkcs11uri-13). AUTHOR Internet Systems Consortium bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-importkey.c0000644000470500017500000002721512664710322021073 0ustar lamontlamont/* * Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef PKCS11CRYPTO #include #endif #include "dnssectool.h" #ifndef PATH_MAX #define PATH_MAX 1024 /* AIX, WIN32, and others don't define this. */ #endif const char *program = "dnssec-importkey"; int verbose; static dns_rdataclass_t rdclass; static dns_fixedname_t fixed; static dns_name_t *name = NULL; static isc_mem_t *mctx = NULL; static isc_boolean_t setpub = ISC_FALSE, setdel = ISC_FALSE; static isc_boolean_t setttl = ISC_FALSE; static isc_stdtime_t pub = 0, del = 0; static dns_ttl_t ttl = 0; static isc_result_t initname(char *setname) { isc_result_t result; isc_buffer_t buf; dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); isc_buffer_init(&buf, setname, strlen(setname)); isc_buffer_add(&buf, strlen(setname)); result = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL); return (result); } static void db_load_from_stream(dns_db_t *db, FILE *fp) { isc_result_t result; dns_rdatacallbacks_t callbacks; dns_rdatacallbacks_init(&callbacks); result = dns_db_beginload(db, &callbacks); if (result != ISC_R_SUCCESS) fatal("dns_db_beginload failed: %s", isc_result_totext(result)); result = dns_master_loadstream(fp, name, name, rdclass, 0, &callbacks, mctx); if (result != ISC_R_SUCCESS) fatal("can't load from input: %s", isc_result_totext(result)); result = dns_db_endload(db, &callbacks); if (result != ISC_R_SUCCESS) fatal("dns_db_endload failed: %s", isc_result_totext(result)); } static isc_result_t loadset(const char *filename, dns_rdataset_t *rdataset) { isc_result_t result; dns_db_t *db = NULL; dns_dbnode_t *node = NULL; char setname[DNS_NAME_FORMATSIZE]; dns_name_format(name, setname, sizeof(setname)); result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone, rdclass, 0, NULL, &db); if (result != ISC_R_SUCCESS) fatal("can't create database"); if (strcmp(filename, "-") == 0) { db_load_from_stream(db, stdin); filename = "input"; } else { result = dns_db_load3(db, filename, dns_masterformat_text, DNS_MASTER_NOTTL); if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) fatal("can't load %s: %s", filename, isc_result_totext(result)); } result = dns_db_findnode(db, name, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) fatal("can't find %s node in %s", setname, filename); result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0, 0, rdataset, NULL); if (result == ISC_R_NOTFOUND) fatal("no DNSKEY RR for %s in %s", setname, filename); else if (result != ISC_R_SUCCESS) fatal("dns_db_findrdataset"); if (node != NULL) dns_db_detachnode(db, &node); if (db != NULL) dns_db_detach(&db); return (result); } static void loadkey(char *filename, unsigned char *key_buf, unsigned int key_buf_size, dns_rdata_t *rdata) { isc_result_t result; dst_key_t *key = NULL; isc_buffer_t keyb; isc_region_t r; dns_rdata_init(rdata); isc_buffer_init(&keyb, key_buf, key_buf_size); result = dst_key_fromnamedfile(filename, NULL, DST_TYPE_PUBLIC, mctx, &key); if (result != ISC_R_SUCCESS) fatal("invalid keyfile name %s: %s", filename, isc_result_totext(result)); if (verbose > 2) { char keystr[DST_KEY_FORMATSIZE]; dst_key_format(key, keystr, sizeof(keystr)); fprintf(stderr, "%s: %s\n", program, keystr); } result = dst_key_todns(key, &keyb); if (result != ISC_R_SUCCESS) fatal("can't decode key"); isc_buffer_usedregion(&keyb, &r); dns_rdata_fromregion(rdata, dst_key_class(key), dns_rdatatype_dnskey, &r); rdclass = dst_key_class(key); dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); result = dns_name_copy(dst_key_name(key), name, NULL); if (result != ISC_R_SUCCESS) fatal("can't copy name"); dst_key_free(&key); } static void emit(const char *dir, dns_rdata_t *rdata) { isc_result_t result; char keystr[DST_KEY_FORMATSIZE]; char pubname[1024]; char priname[1024]; isc_buffer_t buf; dst_key_t *key = NULL, *tmp = NULL; isc_buffer_init(&buf, rdata->data, rdata->length); isc_buffer_add(&buf, rdata->length); result = dst_key_fromdns(name, rdclass, &buf, mctx, &key); if (result != ISC_R_SUCCESS) { fatal("dst_key_fromdns: %s", isc_result_totext(result)); } isc_buffer_init(&buf, pubname, sizeof(pubname)); result = dst_key_buildfilename(key, DST_TYPE_PUBLIC, dir, &buf); if (result != ISC_R_SUCCESS) { fatal("Failed to build public key filename: %s", isc_result_totext(result)); } isc_buffer_init(&buf, priname, sizeof(priname)); result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, dir, &buf); if (result != ISC_R_SUCCESS) { fatal("Failed to build private key filename: %s", isc_result_totext(result)); } result = dst_key_fromfile(dst_key_name(key), dst_key_id(key), dst_key_alg(key), DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, dir, mctx, &tmp); if (result == ISC_R_SUCCESS) { if (dst_key_isprivate(tmp) && !dst_key_isexternal(tmp)) fatal("Private key already exists in %s", priname); dst_key_free(&tmp); } dst_key_setexternal(key, ISC_TRUE); if (setpub) dst_key_settime(key, DST_TIME_PUBLISH, pub); if (setdel) dst_key_settime(key, DST_TIME_DELETE, del); if (setttl) dst_key_setttl(key, ttl); result = dst_key_tofile(key, DST_TYPE_PUBLIC|DST_TYPE_PRIVATE, dir); if (result != ISC_R_SUCCESS) { dst_key_format(key, keystr, sizeof(keystr)); fatal("Failed to write key %s: %s", keystr, isc_result_totext(result)); } printf("%s\n", pubname); isc_buffer_clear(&buf); result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, dir, &buf); if (result != ISC_R_SUCCESS) { fatal("Failed to build private key filename: %s", isc_result_totext(result)); } printf("%s\n", priname); dst_key_free(&key); } ISC_PLATFORM_NORETURN_PRE static void usage(void) ISC_PLATFORM_NORETURN_POST; static void usage(void) { fprintf(stderr, "Usage:\n"); fprintf(stderr, " %s options [-K dir] keyfile\n\n", program); fprintf(stderr, " %s options -f file [keyname]\n\n", program); fprintf(stderr, "Version: %s\n", VERSION); fprintf(stderr, "Options:\n"); fprintf(stderr, " -f file: read key from zone file\n"); fprintf(stderr, " -K : directory in which to store " "the key files\n"); fprintf(stderr, " -L ttl: set default key TTL\n"); fprintf(stderr, " -v \n"); fprintf(stderr, " -V: print version information\n"); fprintf(stderr, " -h: print usage and exit\n"); fprintf(stderr, "Timing options:\n"); fprintf(stderr, " -P date/[+-]offset/none: set/unset key " "publication date\n"); fprintf(stderr, " -D date/[+-]offset/none: set/unset key " "deletion date\n"); exit (-1); } int main(int argc, char **argv) { char *classname = NULL; char *filename = NULL, *dir = NULL, *namestr; char *endp; int ch; isc_result_t result; isc_log_t *log = NULL; isc_entropy_t *ectx = NULL; dns_rdataset_t rdataset; dns_rdata_t rdata; isc_stdtime_t now; dns_rdata_init(&rdata); isc_stdtime_get(&now); if (argc == 1) usage(); result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) fatal("out of memory"); #ifdef PKCS11CRYPTO pk11_result_register(); #endif dns_result_register(); isc_commandline_errprint = ISC_FALSE; #define CMDLINE_FLAGS "D:f:hK:L:P:v:V" while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { switch (ch) { case 'D': if (setdel) fatal("-D specified more than once"); del = strtotime(isc_commandline_argument, now, now, &setdel); break; case 'K': dir = isc_commandline_argument; if (strlen(dir) == 0U) fatal("directory must be non-empty string"); break; case 'L': ttl = strtottl(isc_commandline_argument); setttl = ISC_TRUE; break; case 'P': if (setpub) fatal("-P specified more than once"); pub = strtotime(isc_commandline_argument, now, now, &setpub); break; case 'f': filename = isc_commandline_argument; break; case 'v': verbose = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') fatal("-v must be followed by a number"); break; case '?': if (isc_commandline_option != '?') fprintf(stderr, "%s: invalid argument -%c\n", program, isc_commandline_option); /* FALLTHROUGH */ case 'h': /* Does not return. */ usage(); case 'V': /* Does not return. */ version(program); default: fprintf(stderr, "%s: unhandled option -%c\n", program, isc_commandline_option); exit(1); } } rdclass = strtoclass(classname); if (argc < isc_commandline_index + 1 && filename == NULL) fatal("the key file name was not specified"); if (argc > isc_commandline_index + 1) fatal("extraneous arguments"); if (ectx == NULL) setup_entropy(mctx, NULL, &ectx); result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (result != ISC_R_SUCCESS) fatal("could not initialize hash"); result = dst_lib_init(mctx, ectx, ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); if (result != ISC_R_SUCCESS) fatal("could not initialize dst: %s", isc_result_totext(result)); isc_entropy_stopcallbacksources(ectx); setup_logging(mctx, &log); dns_rdataset_init(&rdataset); if (filename != NULL) { if (argc < isc_commandline_index + 1) { /* using filename as zone name */ namestr = filename; } else namestr = argv[isc_commandline_index]; result = initname(namestr); if (result != ISC_R_SUCCESS) fatal("could not initialize name %s", namestr); result = loadset(filename, &rdataset); if (result != ISC_R_SUCCESS) fatal("could not load DNSKEY set: %s\n", isc_result_totext(result)); for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_init(&rdata); dns_rdataset_current(&rdataset, &rdata); emit(dir, &rdata); } } else { unsigned char key_buf[DST_KEY_MAXSIZE]; loadkey(argv[isc_commandline_index], key_buf, DST_KEY_MAXSIZE, &rdata); emit(dir, &rdata); } if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); cleanup_logging(&log); dst_lib_destroy(); isc_hash_destroy(); cleanup_entropy(&ectx); dns_name_destroy(); if (verbose > 10) isc_mem_stats(mctx, stdout); isc_mem_destroy(&mctx); fflush(stdout); if (ferror(stdout)) { fprintf(stderr, "write error\n"); return (1); } else return (0); } bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-importkey.docbook0000644000470500017500000002071612664710322022270 0ustar lamontlamont]> February 20, 2014 dnssec-importkey 8 BIND9 dnssec-importkey Import DNSKEY records from external systems so they can be managed. 2013 2014 Internet Systems Consortium, Inc. ("ISC") dnssec-importkey dnssec-importkey DESCRIPTION dnssec-importkey reads a public DNSKEY record and generates a pair of .key/.private files. The DNSKEY record may be read from an existing .key file, in which case a corresponding .private file will be generated, or it may be read from any other file or from the standard input, in which case both .key and .private files will be generated. The newly-created .private file does not contain private key data, and cannot be used for signing. However, having a .private file makes it possible to set publication () and deletion () times for the key, which means the public key can be added to and removed from the DNSKEY RRset on schedule even if the true private key is stored offline. OPTIONS -f filename Zone file mode: instead of a public keyfile name, the argument is the DNS domain name of a zone master file, which can be read from . If the domain name is the same as , then it may be omitted. If is set to "-", then the zone data is read from the standard input. -K directory Sets the directory in which the key files are to reside. -L ttl Sets the default TTL to use for this key when it is converted into a DNSKEY RR. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence. Setting the default TTL to 0 or none removes it. -h Emit usage message and exit. -v level Sets the debugging level. -V Prints version information. TIMING OPTIONS Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24-hour days, ignoring leap years), months (defined as 30 24-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To explicitly prevent a date from being set, use 'none' or 'never'. -P date/offset Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it. -D date/offset Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.) FILES A keyfile can be designed by the key identification Knnnn.+aaa+iiiii or the full file name Knnnn.+aaa+iiiii.key as generated by dnssec-keygen8. SEE ALSO dnssec-keygen8 , dnssec-signzone8 , BIND 9 Administrator Reference Manual, RFC 5011. AUTHOR Internet Systems Consortium bind9-9.10.3.dfsg.P4/bin/dnssec/Makefile.in0000644000470500017500000001032112664710322017462 0ustar lamontlamont# Copyright (C) 2004, 2005, 2007-2009, 2012-2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000-2002 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.42.332.1 2011/03/16 06:37:51 each Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ @BIND9_MAKE_INCLUDES@ CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES} CDEFINES = -DVERSION=\"${VERSION}\" @USE_PKCS11@ @PKCS11_ENGINE@ \ @CRYPTO@ -DPK11_LIB_LOCATION=\"@PKCS11_PROVIDER@\" CWARNINGS = DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ ISCLIBS = ../../lib/isc/libisc.@A@ ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@ DNSDEPLIBS = ../../lib/dns/libdns.@A@ ISCDEPLIBS = ../../lib/isc/libisc.@A@ DEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS} LIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@ NOSYMLIBS = ${DNSLIBS} ${ISCNOSYMLIBS} @LIBS@ # Alphabetically TARGETS = dnssec-keygen@EXEEXT@ dnssec-signzone@EXEEXT@ \ dnssec-keyfromlabel@EXEEXT@ dnssec-dsfromkey@EXEEXT@ \ dnssec-revoke@EXEEXT@ dnssec-settime@EXEEXT@ \ dnssec-verify@EXEEXT@ dnssec-importkey@EXEEXT@ OBJS = dnssectool.@O@ SRCS = dnssec-dsfromkey.c dnssec-keyfromlabel.c dnssec-keygen.c \ dnssec-revoke.c dnssec-settime.c dnssec-signzone.c \ dnssec-verify.c dnssec-importkey.c dnssectool.c MANPAGES = dnssec-dsfromkey.8 dnssec-keyfromlabel.8 dnssec-keygen.8 \ dnssec-revoke.8 dnssec-settime.8 dnssec-signzone.8 \ dnssec-verify.8 dnssec-importkey.8 HTMLPAGES = dnssec-dsfromkey.html dnssec-keyfromlabel.html \ dnssec-keygen.html dnssec-revoke.html \ dnssec-settime.html dnssec-signzone.html \ dnssec-verify.html dnssec-importkey.html MANOBJS = ${MANPAGES} ${HTMLPAGES} @BIND9_MAKE_RULES@ dnssec-dsfromkey@EXEEXT@: dnssec-dsfromkey.@O@ ${OBJS} ${DEPLIBS} export BASEOBJS="dnssec-dsfromkey.@O@ ${OBJS}"; \ ${FINALBUILDCMD} dnssec-keyfromlabel@EXEEXT@: dnssec-keyfromlabel.@O@ ${OBJS} ${DEPLIBS} export BASEOBJS="dnssec-keyfromlabel.@O@ ${OBJS}"; \ ${FINALBUILDCMD} dnssec-keygen@EXEEXT@: dnssec-keygen.@O@ ${OBJS} ${DEPLIBS} export BASEOBJS="dnssec-keygen.@O@ ${OBJS}"; \ ${FINALBUILDCMD} dnssec-signzone.@O@: dnssec-signzone.c ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -DVERSION=\"${VERSION}\" \ -c ${srcdir}/dnssec-signzone.c dnssec-signzone@EXEEXT@: dnssec-signzone.@O@ ${OBJS} ${DEPLIBS} export BASEOBJS="dnssec-signzone.@O@ ${OBJS}"; \ ${FINALBUILDCMD} dnssec-verify.@O@: dnssec-verify.c ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -DVERSION=\"${VERSION}\" \ -c ${srcdir}/dnssec-verify.c dnssec-verify@EXEEXT@: dnssec-verify.@O@ ${OBJS} ${DEPLIBS} export BASEOBJS="dnssec-verify.@O@ ${OBJS}"; \ ${FINALBUILDCMD} dnssec-revoke@EXEEXT@: dnssec-revoke.@O@ ${OBJS} ${DEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ dnssec-revoke.@O@ ${OBJS} ${LIBS} dnssec-settime@EXEEXT@: dnssec-settime.@O@ ${OBJS} ${DEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ dnssec-settime.@O@ ${OBJS} ${LIBS} dnssec-importkey@EXEEXT@: dnssec-importkey.@O@ ${OBJS} ${DEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ dnssec-importkey.@O@ ${OBJS} ${LIBS} doc man:: ${MANOBJS} docclean manclean maintainer-clean:: rm -f ${MANOBJS} installdirs: $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 install:: ${TARGETS} installdirs for t in ${TARGETS}; do ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} $$t ${DESTDIR}${sbindir}; done for m in ${MANPAGES}; do ${INSTALL_DATA} ${srcdir}/$$m ${DESTDIR}${mandir}/man8; done clean distclean:: rm -f ${TARGETS} bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-signzone.80000644000470500017500000004245212664710322020631 0ustar lamontlamont.\" Copyright (C) 2004-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000-2003 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: dnssec\-signzone .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: February 18, 2014 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "DNSSEC\-SIGNZONE" "8" "February 18, 2014" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" dnssec\-signzone \- DNSSEC zone signing tool .SH "SYNOPSIS" .HP 16 \fBdnssec\-signzone\fR [\fB\-a\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-d\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-e\ \fR\fB\fIend\-time\fR\fR] [\fB\-f\ \fR\fB\fIoutput\-file\fR\fR] [\fB\-g\fR] [\fB\-h\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-k\ \fR\fB\fIkey\fR\fR] [\fB\-L\ \fR\fB\fIserial\fR\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-M\ \fR\fB\fIdomain\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-I\ \fR\fB\fIinput\-format\fR\fR] [\fB\-j\ \fR\fB\fIjitter\fR\fR] [\fB\-N\ \fR\fB\fIsoa\-serial\-format\fR\fR] [\fB\-o\ \fR\fB\fIorigin\fR\fR] [\fB\-O\ \fR\fB\fIoutput\-format\fR\fR] [\fB\-P\fR] [\fB\-p\fR] [\fB\-R\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-S\fR] [\fB\-s\ \fR\fB\fIstart\-time\fR\fR] [\fB\-T\ \fR\fB\fIttl\fR\fR] [\fB\-t\fR] [\fB\-u\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-V\fR] [\fB\-X\ \fR\fB\fIextended\ end\-time\fR\fR] [\fB\-x\fR] [\fB\-z\fR] [\fB\-3\ \fR\fB\fIsalt\fR\fR] [\fB\-H\ \fR\fB\fIiterations\fR\fR] [\fB\-A\fR] {zonefile} [key...] .SH "DESCRIPTION" .PP \fBdnssec\-signzone\fR signs a zone. It generates NSEC and RRSIG records and produces a signed version of the zone. The security status of delegations from the signed zone (that is, whether the child zones are secure or not) is determined by the presence or absence of a \fIkeyset\fR file for each child zone. .SH "OPTIONS" .PP \-a .RS 4 Verify all generated signatures. .RE .PP \-c \fIclass\fR .RS 4 Specifies the DNS class of the zone. .RE .PP \-C .RS 4 Compatibility mode: Generate a \fIkeyset\-\fR\fI\fIzonename\fR\fR file in addition to \fIdsset\-\fR\fI\fIzonename\fR\fR when signing a zone, for use by older versions of \fBdnssec\-signzone\fR. .RE .PP \-d \fIdirectory\fR .RS 4 Look for \fIdsset\-\fR or \fIkeyset\-\fR files in \fBdirectory\fR. .RE .PP \-D .RS 4 Output only those record types automatically managed by \fBdnssec\-signzone\fR, i.e. RRSIG, NSEC, NSEC3 and NSEC3PARAM records. If smart signing (\fB\-S\fR) is used, DNSKEY records are also included. The resulting file can be included in the original zone file with \fB$INCLUDE\fR. This option cannot be combined with \fB\-O raw\fR, \fB\-O map\fR, or serial number updating. .RE .PP \-E \fIengine\fR .RS 4 When applicable, specifies the hardware to use for cryptographic operations, such as a secure key store used for signing. .sp When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (\-\-enable\-native\-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "\-\-with\-pkcs11". .RE .PP \-g .RS 4 Generate DS records for child zones from \fIdsset\-\fR or \fIkeyset\-\fR file. Existing DS records will be removed. .RE .PP \-K \fIdirectory\fR .RS 4 Key repository: Specify a directory to search for DNSSEC keys. If not specified, defaults to the current directory. .RE .PP \-k \fIkey\fR .RS 4 Treat specified key as a key signing key ignoring any key flags. This option may be specified multiple times. .RE .PP \-l \fIdomain\fR .RS 4 Generate a DLV set in addition to the key (DNSKEY) and DS sets. The domain is appended to the name of the records. .RE .PP \-M \fImaxttl\fR .RS 4 Sets the maximum TTL for the signed zone. Any TTL higher than \fImaxttl\fR in the input zone will be reduced to \fImaxttl\fR in the output. This provides certainty as to the largest possible TTL in the signed zone, which is useful to know when rolling keys because it is the longest possible time before signatures that have been retrieved by resolvers will expire from resolver caches. Zones that are signed with this option should be configured to use a matching \fBmax\-zone\-ttl\fR in \fInamed.conf\fR. (Note: This option is incompatible with \fB\-D\fR, because it modifies non\-DNSSEC data in the output zone.) .RE .PP \-s \fIstart\-time\fR .RS 4 Specify the date and time when the generated RRSIG records become valid. This can be either an absolute or relative time. An absolute start time is indicated by a number in YYYYMMDDHHMMSS notation; 20000530144500 denotes 14:45:00 UTC on May 30th, 2000. A relative start time is indicated by +N, which is N seconds from the current time. If no \fBstart\-time\fR is specified, the current time minus 1 hour (to allow for clock skew) is used. .RE .PP \-e \fIend\-time\fR .RS 4 Specify the date and time when the generated RRSIG records expire. As with \fBstart\-time\fR, an absolute time is indicated in YYYYMMDDHHMMSS notation. A time relative to the start time is indicated with +N, which is N seconds from the start time. A time relative to the current time is indicated with now+N. If no \fBend\-time\fR is specified, 30 days from the start time is used as a default. \fBend\-time\fR must be later than \fBstart\-time\fR. .RE .PP \-X \fIextended end\-time\fR .RS 4 Specify the date and time when the generated RRSIG records for the DNSKEY RRset will expire. This is to be used in cases when the DNSKEY signatures need to persist longer than signatures on other records; e.g., when the private component of the KSK is kept offline and the KSK signature is to be refreshed manually. .sp As with \fBstart\-time\fR, an absolute time is indicated in YYYYMMDDHHMMSS notation. A time relative to the start time is indicated with +N, which is N seconds from the start time. A time relative to the current time is indicated with now+N. If no \fBextended end\-time\fR is specified, the value of \fBend\-time\fR is used as the default. (\fBend\-time\fR, in turn, defaults to 30 days from the start time.) \fBextended end\-time\fR must be later than \fBstart\-time\fR. .RE .PP \-f \fIoutput\-file\fR .RS 4 The name of the output file containing the signed zone. The default is to append \fI.signed\fR to the input filename. If \fBoutput\-file\fR is set to "\-", then the signed zone is written to the standard output, with a default output format of "full". .RE .PP \-h .RS 4 Prints a short summary of the options and arguments to \fBdnssec\-signzone\fR. .RE .PP \-V .RS 4 Prints version information. .RE .PP \-i \fIinterval\fR .RS 4 When a previously\-signed zone is passed as input, records may be resigned. The \fBinterval\fR option specifies the cycle interval as an offset from the current time (in seconds). If a RRSIG record expires after the cycle interval, it is retained. Otherwise, it is considered to be expiring soon, and it will be replaced. .sp The default cycle interval is one quarter of the difference between the signature end and start times. So if neither \fBend\-time\fR or \fBstart\-time\fR are specified, \fBdnssec\-signzone\fR generates signatures that are valid for 30 days, with a cycle interval of 7.5 days. Therefore, if any existing RRSIG records are due to expire in less than 7.5 days, they would be replaced. .RE .PP \-I \fIinput\-format\fR .RS 4 The format of the input zone file. Possible formats are \fB"text"\fR (default), \fB"raw"\fR, and \fB"map"\fR. This option is primarily intended to be used for dynamic signed zones so that the dumped zone file in a non\-text format containing updates can be signed directly. The use of this option does not make much sense for non\-dynamic zones. .RE .PP \-j \fIjitter\fR .RS 4 When signing a zone with a fixed signature lifetime, all RRSIG records issued at the time of signing expires simultaneously. If the zone is incrementally signed, i.e. a previously\-signed zone is passed as input to the signer, all expired signatures have to be regenerated at about the same time. The \fBjitter\fR option specifies a jitter window that will be used to randomize the signature expire time, thus spreading incremental signature regeneration over time. .sp Signature lifetime jitter also to some extent benefits validators and servers by spreading out cache expiration, i.e. if large numbers of RRSIGs don't expire at the same time from all caches there will be less congestion than if all validators need to refetch at mostly the same time. .RE .PP \-L \fIserial\fR .RS 4 When writing a signed zone to "raw" or "map" format, set the "source serial" value in the header to the specified serial number. (This is expected to be used primarily for testing purposes.) .RE .PP \-n \fIncpus\fR .RS 4 Specifies the number of threads to use. By default, one thread is started for each detected CPU. .RE .PP \-N \fIsoa\-serial\-format\fR .RS 4 The SOA serial number format of the signed zone. Possible formats are \fB"keep"\fR (default), \fB"increment"\fR and \fB"unixtime"\fR. .RS 4 .PP \fB"keep"\fR .RS 4 Do not modify the SOA serial number. .RE .PP \fB"increment"\fR .RS 4 Increment the SOA serial number using RFC 1982 arithmetics. .RE .PP \fB"unixtime"\fR .RS 4 Set the SOA serial number to the number of seconds since epoch. .RE .RE .RE .PP \-o \fIorigin\fR .RS 4 The zone origin. If not specified, the name of the zone file is assumed to be the origin. .RE .PP \-O \fIoutput\-format\fR .RS 4 The format of the output file containing the signed zone. Possible formats are \fB"text"\fR (default), which is the standard textual representation of the zone; \fB"full"\fR, which is text output in a format suitable for processing by external scripts; and \fB"map"\fR, \fB"raw"\fR, and \fB"raw=N"\fR, which store the zone in binary formats for rapid loading by \fBnamed\fR. \fB"raw=N"\fR specifies the format version of the raw zone file: if N is 0, the raw file can be read by any version of \fBnamed\fR; if N is 1, the file can be read by release 9.9.0 or higher; the default is 1. .RE .PP \-p .RS 4 Use pseudo\-random data when signing the zone. This is faster, but less secure, than using real random data. This option may be useful when signing large zones or when the entropy source is limited. .RE .PP \-P .RS 4 Disable post sign verification tests. .sp The post sign verification test ensures that for each algorithm in use there is at least one non revoked self signed KSK key, that all revoked KSK keys are self signed, and that all records in the zone are signed by the algorithm. This option skips these tests. .RE .PP \-Q .RS 4 Remove signatures from keys that are no longer active. .sp Normally, when a previously\-signed zone is passed as input to the signer, and a DNSKEY record has been removed and replaced with a new one, signatures from the old key that are still within their validity period are retained. This allows the zone to continue to validate with cached copies of the old DNSKEY RRset. The \fB\-Q\fR forces \fBdnssec\-signzone\fR to remove signatures from keys that are no longer active. This enables ZSK rollover using the procedure described in RFC 4641, section 4.2.1.1 ("Pre\-Publish Key Rollover"). .RE .PP \-R .RS 4 Remove signatures from keys that are no longer published. .sp This option is similar to \fB\-Q\fR, except it forces \fBdnssec\-signzone\fR to signatures from keys that are no longer published. This enables ZSK rollover using the procedure described in RFC 4641, section 4.2.1.2 ("Double Signature Zone Signing Key Rollover"). .RE .PP \-r \fIrandomdev\fR .RS 4 Specifies the source of randomness. If the operating system does not provide a \fI/dev/random\fR or equivalent device, the default source of randomness is keyboard input. \fIrandomdev\fR specifies the name of a character device or file containing random data to be used instead of the default. The special value \fIkeyboard\fR indicates that keyboard input should be used. .RE .PP \-S .RS 4 Smart signing: Instructs \fBdnssec\-signzone\fR to search the key repository for keys that match the zone being signed, and to include them in the zone if appropriate. .sp When a key is found, its timing metadata is examined to determine how it should be used, according to the following rules. Each successive rule takes priority over the prior ones: .RS 4 .PP .RS 4 If no timing metadata has been set for the key, the key is published in the zone and used to sign the zone. .RE .PP .RS 4 If the key's publication date is set and is in the past, the key is published in the zone. .RE .PP .RS 4 If the key's activation date is set and in the past, the key is published (regardless of publication date) and used to sign the zone. .RE .PP .RS 4 If the key's revocation date is set and in the past, and the key is published, then the key is revoked, and the revoked key is used to sign the zone. .RE .PP .RS 4 If either of the key's unpublication or deletion dates are set and in the past, the key is NOT published or used to sign the zone, regardless of any other metadata. .RE .RE .RE .PP \-T \fIttl\fR .RS 4 Specifies a TTL to be used for new DNSKEY records imported into the zone from the key repository. If not specified, the default is the TTL value from the zone's SOA record. This option is ignored when signing without \fB\-S\fR, since DNSKEY records are not imported from the key repository in that case. It is also ignored if there are any pre\-existing DNSKEY records at the zone apex, in which case new records' TTL values will be set to match them, or if any of the imported DNSKEY records had a default TTL value. In the event of a a conflict between TTL values in imported keys, the shortest one is used. .RE .PP \-t .RS 4 Print statistics at completion. .RE .PP \-u .RS 4 Update NSEC/NSEC3 chain when re\-signing a previously signed zone. With this option, a zone signed with NSEC can be switched to NSEC3, or a zone signed with NSEC3 can be switch to NSEC or to NSEC3 with different parameters. Without this option, \fBdnssec\-signzone\fR will retain the existing chain when re\-signing. .RE .PP \-v \fIlevel\fR .RS 4 Sets the debugging level. .RE .PP \-x .RS 4 Only sign the DNSKEY RRset with key\-signing keys, and omit signatures from zone\-signing keys. (This is similar to the \fBdnssec\-dnskey\-kskonly yes;\fR zone option in \fBnamed\fR.) .RE .PP \-z .RS 4 Ignore KSK flag on key when determining what to sign. This causes KSK\-flagged keys to sign all records, not just the DNSKEY RRset. (This is similar to the \fBupdate\-check\-ksk no;\fR zone option in \fBnamed\fR.) .RE .PP \-3 \fIsalt\fR .RS 4 Generate an NSEC3 chain with the given hex encoded salt. A dash (\fIsalt\fR) can be used to indicate that no salt is to be used when generating the NSEC3 chain. .RE .PP \-H \fIiterations\fR .RS 4 When generating an NSEC3 chain, use this many iterations. The default is 10. .RE .PP \-A .RS 4 When generating an NSEC3 chain set the OPTOUT flag on all NSEC3 records and do not generate NSEC3 records for insecure delegations. .sp Using this option twice (i.e., \fB\-AA\fR) turns the OPTOUT flag off for all records. This is useful when using the \fB\-u\fR option to modify an NSEC3 chain which previously had OPTOUT set. .RE .PP zonefile .RS 4 The file containing the zone to be signed. .RE .PP key .RS 4 Specify which keys should be used to sign the zone. If no keys are specified, then the zone will be examined for DNSKEY records at the zone apex. If these are found and there are matching private keys, in the current directory, then these will be used for signing. .RE .SH "EXAMPLE" .PP The following command signs the \fBexample.com\fR zone with the DSA key generated by \fBdnssec\-keygen\fR (Kexample.com.+003+17247). Because the \fB\-S\fR option is not being used, the zone's keys must be in the master file (\fIdb.example.com\fR). This invocation looks for \fIdsset\fR files, in the current directory, so that DS records can be imported from them (\fB\-g\fR). .sp .RS 4 .nf % dnssec\-signzone \-g \-o example.com db.example.com \\ Kexample.com.+003+17247 db.example.com.signed % .fi .RE .PP In the above example, \fBdnssec\-signzone\fR creates the file \fIdb.example.com.signed\fR. This file should be referenced in a zone statement in a \fInamed.conf\fR file. .PP This example re\-signs a previously signed zone with default parameters. The private keys are assumed to be in the current directory. .sp .RS 4 .nf % cp db.example.com.signed db.example.com % dnssec\-signzone \-o example.com db.example.com db.example.com.signed % .fi .RE .SH "SEE ALSO" .PP \fBdnssec\-keygen\fR(8), BIND 9 Administrator Reference Manual, RFC 4033, RFC 4641. .SH "AUTHOR" .PP Internet Systems Consortium .SH "COPYRIGHT" Copyright \(co 2004\-2009, 2011\-2014 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000\-2003 Internet Software Consortium. .br bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-revoke.docbook0000644000470500017500000001236712664710322021543 0ustar lamontlamont]> January 15, 2014 dnssec-revoke 8 BIND9 dnssec-revoke Set the REVOKED bit on a DNSSEC key 2009 2011 2014 Internet Systems Consortium, Inc. ("ISC") dnssec-revoke keyfile DESCRIPTION dnssec-revoke reads a DNSSEC key file, sets the REVOKED bit on the key as defined in RFC 5011, and creates a new pair of key files containing the now-revoked key. OPTIONS -h Emit usage message and exit. -K directory Sets the directory in which the key files are to reside. -r After writing the new keyset files remove the original keyset files. -v level Sets the debugging level. -V Prints version information. -E engine Specifies the cryptographic hardware to use, when applicable. When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (--enable-native-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "--with-pkcs11". -f Force overwrite: Causes dnssec-revoke to write the new key pair even if a file already exists matching the algorithm and key ID of the revoked key. -R Print the key tag of the key with the REVOKE bit set but do not revoke the key. SEE ALSO dnssec-keygen8 , BIND 9 Administrator Reference Manual, RFC 5011. AUTHOR Internet Systems Consortium bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-importkey.80000644000470500017500000001142312664710322021012 0ustar lamontlamont.\" Copyright (C) 2013, 2014 Internet Systems Consortium, Inc. ("ISC") .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: dnssec\-importkey .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: February 20, 2014 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "DNSSEC\-IMPORTKEY" "8" "February 20, 2014" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" dnssec\-importkey \- Import DNSKEY records from external systems so they can be managed. .SH "SYNOPSIS" .HP 17 \fBdnssec\-importkey\fR [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-L\ \fR\fB\fIttl\fR\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-h\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-V\fR] {\fBkeyfile\fR} .HP 17 \fBdnssec\-importkey\fR {\fB\-f\ \fR\fB\fIfilename\fR\fR} [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-L\ \fR\fB\fIttl\fR\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-h\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-V\fR] [\fBdnsname\fR] .SH "DESCRIPTION" .PP \fBdnssec\-importkey\fR reads a public DNSKEY record and generates a pair of .key/.private files. The DNSKEY record may be read from an existing .key file, in which case a corresponding .private file will be generated, or it may be read from any other file or from the standard input, in which case both .key and .private files will be generated. .PP The newly\-created .private file does \fInot\fR contain private key data, and cannot be used for signing. However, having a .private file makes it possible to set publication (\fB\-P\fR) and deletion (\fB\-D\fR) times for the key, which means the public key can be added to and removed from the DNSKEY RRset on schedule even if the true private key is stored offline. .SH "OPTIONS" .PP \-f \fIfilename\fR .RS 4 Zone file mode: instead of a public keyfile name, the argument is the DNS domain name of a zone master file, which can be read from \fBfile\fR. If the domain name is the same as \fBfile\fR, then it may be omitted. .sp If \fBfile\fR is set to "\-", then the zone data is read from the standard input. .RE .PP \-K \fIdirectory\fR .RS 4 Sets the directory in which the key files are to reside. .RE .PP \-L \fIttl\fR .RS 4 Sets the default TTL to use for this key when it is converted into a DNSKEY RR. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence. Setting the default TTL to 0 or none removes it. .RE .PP \-h .RS 4 Emit usage message and exit. .RE .PP \-v \fIlevel\fR .RS 4 Sets the debugging level. .RE .PP \-V .RS 4 Prints version information. .RE .SH "TIMING OPTIONS" .PP Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '\-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24\-hour days, ignoring leap years), months (defined as 30 24\-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To explicitly prevent a date from being set, use 'none' or 'never'. .PP \-P \fIdate/offset\fR .RS 4 Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it. .RE .PP \-D \fIdate/offset\fR .RS 4 Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.) .RE .SH "FILES" .PP A keyfile can be designed by the key identification \fIKnnnn.+aaa+iiiii\fR or the full file name \fIKnnnn.+aaa+iiiii.key\fR as generated by dnssec\-keygen(8). .SH "SEE ALSO" .PP \fBdnssec\-keygen\fR(8), \fBdnssec\-signzone\fR(8), BIND 9 Administrator Reference Manual, RFC 5011. .SH "AUTHOR" .PP Internet Systems Consortium .SH "COPYRIGHT" Copyright \(co 2013, 2014 Internet Systems Consortium, Inc. ("ISC") .br bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-keyfromlabel.c0000644000470500017500000005011112664710322021513 0ustar lamontlamont/* * Copyright (C) 2007-2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef PKCS11CRYPTO #include #endif #include "dnssectool.h" #define MAX_RSA 4096 /* should be long enough... */ const char *program = "dnssec-keyfromlabel"; int verbose; #define DEFAULT_ALGORITHM "RSASHA1" #define DEFAULT_NSEC3_ALGORITHM "NSEC3RSASHA1" static const char *algs = "RSA | RSAMD5 | DH | DSA | RSASHA1 |" " NSEC3DSA | NSEC3RSASHA1 |" " RSASHA256 | RSASHA512 | ECCGOST |" " ECDSAP256SHA256 | ECDSAP384SHA384"; ISC_PLATFORM_NORETURN_PRE static void usage(void) ISC_PLATFORM_NORETURN_POST; static void usage(void) { fprintf(stderr, "Usage:\n"); fprintf(stderr, " %s -l label [options] name\n\n", program); fprintf(stderr, "Version: %s\n", VERSION); fprintf(stderr, "Required options:\n"); fprintf(stderr, " -l label: label of the key pair\n"); fprintf(stderr, " name: owner of the key\n"); fprintf(stderr, "Other options:\n"); fprintf(stderr, " -a algorithm: %s\n", algs); fprintf(stderr, " (default: RSASHA1, or " "NSEC3RSASHA1 if using -3)\n"); fprintf(stderr, " -3: use NSEC3-capable algorithm\n"); fprintf(stderr, " -c class (default: IN)\n"); fprintf(stderr, " -E :\n"); #if defined(PKCS11CRYPTO) fprintf(stderr, " path to PKCS#11 provider library " "(default is %s)\n", PK11_LIB_LOCATION); #elif defined(USE_PKCS11) fprintf(stderr, " name of an OpenSSL engine to use " "(default is \"pkcs11\")\n"); #else fprintf(stderr, " name of an OpenSSL engine to use\n"); #endif fprintf(stderr, " -f keyflag: KSK | REVOKE\n"); fprintf(stderr, " -K directory: directory in which to place " "key files\n"); fprintf(stderr, " -k: generate a TYPE=KEY key\n"); fprintf(stderr, " -L ttl: default key TTL\n"); fprintf(stderr, " -n nametype: ZONE | HOST | ENTITY | USER | OTHER\n"); fprintf(stderr, " (DNSKEY generation defaults to ZONE\n"); fprintf(stderr, " -p protocol: default: 3 [dnssec]\n"); fprintf(stderr, " -t type: " "AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF " "(default: AUTHCONF)\n"); fprintf(stderr, " -y: permit keys that might collide\n"); fprintf(stderr, " -v verbose level\n"); fprintf(stderr, " -V: print version information\n"); fprintf(stderr, "Date options:\n"); fprintf(stderr, " -P date/[+-]offset: set key publication date\n"); fprintf(stderr, " -A date/[+-]offset: set key activation date\n"); fprintf(stderr, " -R date/[+-]offset: set key revocation date\n"); fprintf(stderr, " -I date/[+-]offset: set key inactivation date\n"); fprintf(stderr, " -D date/[+-]offset: set key deletion date\n"); fprintf(stderr, " -G: generate key only; do not set -P or -A\n"); fprintf(stderr, " -C: generate a backward-compatible key, omitting" " all dates\n"); fprintf(stderr, " -S : generate a successor to an existing " "key\n"); fprintf(stderr, " -i : prepublication interval for " "successor key " "(default: 30 days)\n"); fprintf(stderr, "Output:\n"); fprintf(stderr, " K++.key, " "K++.private\n"); exit (-1); } int main(int argc, char **argv) { char *algname = NULL, *freeit = NULL; char *nametype = NULL, *type = NULL; const char *directory = NULL; const char *predecessor = NULL; dst_key_t *prevkey = NULL; #ifdef USE_PKCS11 const char *engine = PKCS11_ENGINE; #else const char *engine = NULL; #endif char *classname = NULL; char *endp; dst_key_t *key = NULL; dns_fixedname_t fname; dns_name_t *name; isc_uint16_t flags = 0, kskflag = 0, revflag = 0; dns_secalg_t alg; isc_boolean_t oldstyle = ISC_FALSE; isc_mem_t *mctx = NULL; int ch; int protocol = -1, signatory = 0; isc_result_t ret; isc_textregion_t r; char filename[255]; isc_buffer_t buf; isc_log_t *log = NULL; isc_entropy_t *ectx = NULL; dns_rdataclass_t rdclass; int options = DST_TYPE_PRIVATE | DST_TYPE_PUBLIC; char *label = NULL; dns_ttl_t ttl = 0; isc_stdtime_t publish = 0, activate = 0, revoke = 0; isc_stdtime_t inactive = 0, delete = 0; isc_stdtime_t now; int prepub = -1; isc_boolean_t setpub = ISC_FALSE, setact = ISC_FALSE; isc_boolean_t setrev = ISC_FALSE, setinact = ISC_FALSE; isc_boolean_t setdel = ISC_FALSE, setttl = ISC_FALSE; isc_boolean_t unsetpub = ISC_FALSE, unsetact = ISC_FALSE; isc_boolean_t unsetrev = ISC_FALSE, unsetinact = ISC_FALSE; isc_boolean_t unsetdel = ISC_FALSE; isc_boolean_t genonly = ISC_FALSE; isc_boolean_t use_nsec3 = ISC_FALSE; isc_boolean_t avoid_collisions = ISC_TRUE; isc_boolean_t exact; unsigned char c; if (argc == 1) usage(); RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); #ifdef PKCS11CRYPTO pk11_result_register(); #endif dns_result_register(); isc_commandline_errprint = ISC_FALSE; isc_stdtime_get(&now); #define CMDLINE_FLAGS "3A:a:Cc:D:E:Ff:GhI:i:kK:L:l:n:P:p:R:S:t:v:Vy" while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { switch (ch) { case '3': use_nsec3 = ISC_TRUE; break; case 'a': algname = isc_commandline_argument; break; case 'C': oldstyle = ISC_TRUE; break; case 'c': classname = isc_commandline_argument; break; case 'E': engine = isc_commandline_argument; break; case 'f': c = (unsigned char)(isc_commandline_argument[0]); if (toupper(c) == 'K') kskflag = DNS_KEYFLAG_KSK; else if (toupper(c) == 'R') revflag = DNS_KEYFLAG_REVOKE; else fatal("unknown flag '%s'", isc_commandline_argument); break; case 'K': directory = isc_commandline_argument; ret = try_dir(directory); if (ret != ISC_R_SUCCESS) fatal("cannot open directory %s: %s", directory, isc_result_totext(ret)); break; case 'k': options |= DST_TYPE_KEY; break; case 'L': ttl = strtottl(isc_commandline_argument); setttl = ISC_TRUE; break; case 'l': label = isc_mem_strdup(mctx, isc_commandline_argument); break; case 'n': nametype = isc_commandline_argument; break; case 'p': protocol = strtol(isc_commandline_argument, &endp, 10); if (*endp != '\0' || protocol < 0 || protocol > 255) fatal("-p must be followed by a number " "[0..255]"); break; case 't': type = isc_commandline_argument; break; case 'v': verbose = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') fatal("-v must be followed by a number"); break; case 'y': avoid_collisions = ISC_FALSE; break; case 'G': genonly = ISC_TRUE; break; case 'P': if (setpub || unsetpub) fatal("-P specified more than once"); publish = strtotime(isc_commandline_argument, now, now, &setpub); unsetpub = !setpub; break; case 'A': if (setact || unsetact) fatal("-A specified more than once"); activate = strtotime(isc_commandline_argument, now, now, &setact); unsetact = !setact; break; case 'R': if (setrev || unsetrev) fatal("-R specified more than once"); revoke = strtotime(isc_commandline_argument, now, now, &setrev); unsetrev = !setrev; break; case 'I': if (setinact || unsetinact) fatal("-I specified more than once"); inactive = strtotime(isc_commandline_argument, now, now, &setinact); unsetinact = !setinact; break; case 'D': if (setdel || unsetdel) fatal("-D specified more than once"); delete = strtotime(isc_commandline_argument, now, now, &setdel); unsetdel = !setdel; break; case 'S': predecessor = isc_commandline_argument; break; case 'i': prepub = strtottl(isc_commandline_argument); break; case 'F': /* Reserved for FIPS mode */ /* FALLTHROUGH */ case '?': if (isc_commandline_option != '?') fprintf(stderr, "%s: invalid argument -%c\n", program, isc_commandline_option); /* FALLTHROUGH */ case 'h': /* Does not return. */ usage(); case 'V': /* Does not return. */ version(program); default: fprintf(stderr, "%s: unhandled option -%c\n", program, isc_commandline_option); exit(1); } } if (ectx == NULL) setup_entropy(mctx, NULL, &ectx); ret = dst_lib_init2(mctx, ectx, engine, ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); if (ret != ISC_R_SUCCESS) fatal("could not initialize dst: %s", isc_result_totext(ret)); setup_logging(mctx, &log); if (predecessor == NULL) { if (label == NULL) fatal("the key label was not specified"); if (argc < isc_commandline_index + 1) fatal("the key name was not specified"); if (argc > isc_commandline_index + 1) fatal("extraneous arguments"); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); isc_buffer_init(&buf, argv[isc_commandline_index], strlen(argv[isc_commandline_index])); isc_buffer_add(&buf, strlen(argv[isc_commandline_index])); ret = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL); if (ret != ISC_R_SUCCESS) fatal("invalid key name %s: %s", argv[isc_commandline_index], isc_result_totext(ret)); if (strchr(label, ':') == NULL) { char *l; int len; len = strlen(label) + 8; l = isc_mem_allocate(mctx, len); if (l == NULL) fatal("cannot allocate memory"); snprintf(l, len, "pkcs11:%s", label); isc_mem_free(mctx, label); label = l; } if (algname == NULL) { if (use_nsec3) algname = strdup(DEFAULT_NSEC3_ALGORITHM); else algname = strdup(DEFAULT_ALGORITHM); if (algname == NULL) fatal("strdup failed"); freeit = algname; if (verbose > 0) fprintf(stderr, "no algorithm specified; " "defaulting to %s\n", algname); } if (strcasecmp(algname, "RSA") == 0) { fprintf(stderr, "The use of RSA (RSAMD5) is not " "recommended.\nIf you still wish to " "use RSA (RSAMD5) please specify " "\"-a RSAMD5\"\n"); if (freeit != NULL) free(freeit); return (1); } else { r.base = algname; r.length = strlen(algname); ret = dns_secalg_fromtext(&alg, &r); if (ret != ISC_R_SUCCESS) fatal("unknown algorithm %s", algname); if (alg == DST_ALG_DH) options |= DST_TYPE_KEY; } if (use_nsec3 && alg != DST_ALG_NSEC3DSA && alg != DST_ALG_NSEC3RSASHA1 && alg != DST_ALG_RSASHA256 && alg != DST_ALG_RSASHA512 && alg != DST_ALG_ECCGOST && alg != DST_ALG_ECDSA256 && alg != DST_ALG_ECDSA384) { fatal("%s is incompatible with NSEC3; " "do not use the -3 option", algname); } if (type != NULL && (options & DST_TYPE_KEY) != 0) { if (strcasecmp(type, "NOAUTH") == 0) flags |= DNS_KEYTYPE_NOAUTH; else if (strcasecmp(type, "NOCONF") == 0) flags |= DNS_KEYTYPE_NOCONF; else if (strcasecmp(type, "NOAUTHCONF") == 0) flags |= (DNS_KEYTYPE_NOAUTH | DNS_KEYTYPE_NOCONF); else if (strcasecmp(type, "AUTHCONF") == 0) /* nothing */; else fatal("invalid type %s", type); } if (!oldstyle && prepub > 0) { if (setpub && setact && (activate - prepub) < publish) fatal("Activation and publication dates " "are closer together than the\n\t" "prepublication interval."); if (!setpub && !setact) { setpub = setact = ISC_TRUE; publish = now; activate = now + prepub; } else if (setpub && !setact) { setact = ISC_TRUE; activate = publish + prepub; } else if (setact && !setpub) { setpub = ISC_TRUE; publish = activate - prepub; } if ((activate - prepub) < now) fatal("Time until activation is shorter " "than the\n\tprepublication interval."); } } else { char keystr[DST_KEY_FORMATSIZE]; isc_stdtime_t when; int major, minor; if (prepub == -1) prepub = (30 * 86400); if (algname != NULL) fatal("-S and -a cannot be used together"); if (nametype != NULL) fatal("-S and -n cannot be used together"); if (type != NULL) fatal("-S and -t cannot be used together"); if (setpub || unsetpub) fatal("-S and -P cannot be used together"); if (setact || unsetact) fatal("-S and -A cannot be used together"); if (use_nsec3) fatal("-S and -3 cannot be used together"); if (oldstyle) fatal("-S and -C cannot be used together"); if (genonly) fatal("-S and -G cannot be used together"); ret = dst_key_fromnamedfile(predecessor, directory, DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, mctx, &prevkey); if (ret != ISC_R_SUCCESS) fatal("Invalid keyfile %s: %s", predecessor, isc_result_totext(ret)); if (!dst_key_isprivate(prevkey)) fatal("%s is not a private key", predecessor); name = dst_key_name(prevkey); alg = dst_key_alg(prevkey); flags = dst_key_flags(prevkey); dst_key_format(prevkey, keystr, sizeof(keystr)); dst_key_getprivateformat(prevkey, &major, &minor); if (major != DST_MAJOR_VERSION || minor < DST_MINOR_VERSION) fatal("Key %s has incompatible format version %d.%d\n\t" "It is not possible to generate a successor key.", keystr, major, minor); ret = dst_key_gettime(prevkey, DST_TIME_ACTIVATE, &when); if (ret != ISC_R_SUCCESS) fatal("Key %s has no activation date.\n\t" "You must use dnssec-settime -A to set one " "before generating a successor.", keystr); ret = dst_key_gettime(prevkey, DST_TIME_INACTIVE, &activate); if (ret != ISC_R_SUCCESS) fatal("Key %s has no inactivation date.\n\t" "You must use dnssec-settime -I to set one " "before generating a successor.", keystr); publish = activate - prepub; if (publish < now) fatal("Key %s becomes inactive\n\t" "sooner than the prepublication period " "for the new key ends.\n\t" "Either change the inactivation date with " "dnssec-settime -I,\n\t" "or use the -i option to set a shorter " "prepublication interval.", keystr); ret = dst_key_gettime(prevkey, DST_TIME_DELETE, &when); if (ret != ISC_R_SUCCESS) fprintf(stderr, "%s: WARNING: Key %s has no removal " "date;\n\t it will remain in the zone " "indefinitely after rollover.\n\t " "You can use dnssec-settime -D to " "change this.\n", program, keystr); setpub = setact = ISC_TRUE; } if (nametype == NULL) { if ((options & DST_TYPE_KEY) != 0) /* KEY */ fatal("no nametype specified"); flags |= DNS_KEYOWNER_ZONE; /* DNSKEY */ } else if (strcasecmp(nametype, "zone") == 0) flags |= DNS_KEYOWNER_ZONE; else if ((options & DST_TYPE_KEY) != 0) { /* KEY */ if (strcasecmp(nametype, "host") == 0 || strcasecmp(nametype, "entity") == 0) flags |= DNS_KEYOWNER_ENTITY; else if (strcasecmp(nametype, "user") == 0) flags |= DNS_KEYOWNER_USER; else fatal("invalid KEY nametype %s", nametype); } else if (strcasecmp(nametype, "other") != 0) /* DNSKEY */ fatal("invalid DNSKEY nametype %s", nametype); rdclass = strtoclass(classname); if (directory == NULL) directory = "."; if ((options & DST_TYPE_KEY) != 0) /* KEY */ flags |= signatory; else if ((flags & DNS_KEYOWNER_ZONE) != 0) { /* DNSKEY */ flags |= kskflag; flags |= revflag; } if (protocol == -1) protocol = DNS_KEYPROTO_DNSSEC; else if ((options & DST_TYPE_KEY) == 0 && protocol != DNS_KEYPROTO_DNSSEC) fatal("invalid DNSKEY protocol: %d", protocol); if ((flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) { if ((flags & DNS_KEYFLAG_SIGNATORYMASK) != 0) fatal("specified null key with signing authority"); } if ((flags & DNS_KEYFLAG_OWNERMASK) == DNS_KEYOWNER_ZONE && alg == DNS_KEYALG_DH) fatal("a key with algorithm '%s' cannot be a zone key", algname); isc_buffer_init(&buf, filename, sizeof(filename) - 1); /* associate the key */ ret = dst_key_fromlabel(name, alg, flags, protocol, rdclass, "pkcs11", label, NULL, mctx, &key); isc_entropy_stopcallbacksources(ectx); if (ret != ISC_R_SUCCESS) { char namestr[DNS_NAME_FORMATSIZE]; char algstr[DNS_SECALG_FORMATSIZE]; dns_name_format(name, namestr, sizeof(namestr)); dns_secalg_format(alg, algstr, sizeof(algstr)); fatal("failed to get key %s/%s: %s", namestr, algstr, isc_result_totext(ret)); /* NOTREACHED */ exit(-1); } /* * Set key timing metadata (unless using -C) * * Publish and activation dates are set to "now" by default, but * can be overridden. Creation date is always set to "now". */ if (!oldstyle) { dst_key_settime(key, DST_TIME_CREATED, now); if (genonly && (setpub || setact)) fatal("cannot use -G together with -P or -A options"); if (setpub) dst_key_settime(key, DST_TIME_PUBLISH, publish); else if (setact) dst_key_settime(key, DST_TIME_PUBLISH, activate); else if (!genonly && !unsetpub) dst_key_settime(key, DST_TIME_PUBLISH, now); if (setact) dst_key_settime(key, DST_TIME_ACTIVATE, activate); else if (!genonly && !unsetact) dst_key_settime(key, DST_TIME_ACTIVATE, now); if (setrev) { if (kskflag == 0) fprintf(stderr, "%s: warning: Key is " "not flagged as a KSK, but -R " "was used. Revoking a ZSK is " "legal, but undefined.\n", program); dst_key_settime(key, DST_TIME_REVOKE, revoke); } if (setinact) dst_key_settime(key, DST_TIME_INACTIVE, inactive); if (setdel) dst_key_settime(key, DST_TIME_DELETE, delete); } else { if (setpub || setact || setrev || setinact || setdel || unsetpub || unsetact || unsetrev || unsetinact || unsetdel || genonly) fatal("cannot use -C together with " "-P, -A, -R, -I, -D, or -G options"); /* * Compatibility mode: Private-key-format * should be set to 1.2. */ dst_key_setprivateformat(key, 1, 2); } /* Set default key TTL */ if (setttl) dst_key_setttl(key, ttl); /* * Do not overwrite an existing key. Warn LOUDLY if there * is a risk of ID collision due to this key or another key * being revoked. */ if (key_collision(key, name, directory, mctx, &exact)) { isc_buffer_clear(&buf); ret = dst_key_buildfilename(key, 0, directory, &buf); if (ret != ISC_R_SUCCESS) fatal("dst_key_buildfilename returned: %s\n", isc_result_totext(ret)); if (exact) fatal("%s: %s already exists\n", program, filename); if (avoid_collisions) fatal("%s: %s could collide with another key upon " "revokation\n", program, filename); fprintf(stderr, "%s: WARNING: Key %s could collide with " "another key upon revokation. If you plan " "to revoke keys, destroy this key and " "generate a different one.\n", program, filename); } ret = dst_key_tofile(key, options, directory); if (ret != ISC_R_SUCCESS) { char keystr[DST_KEY_FORMATSIZE]; dst_key_format(key, keystr, sizeof(keystr)); fatal("failed to write key %s: %s\n", keystr, isc_result_totext(ret)); } isc_buffer_clear(&buf); ret = dst_key_buildfilename(key, 0, NULL, &buf); if (ret != ISC_R_SUCCESS) fatal("dst_key_buildfilename returned: %s\n", isc_result_totext(ret)); printf("%s\n", filename); dst_key_free(&key); if (prevkey != NULL) dst_key_free(&prevkey); cleanup_logging(&log); cleanup_entropy(&ectx); dst_lib_destroy(); dns_name_destroy(); if (verbose > 10) isc_mem_stats(mctx, stdout); isc_mem_free(mctx, label); isc_mem_destroy(&mctx); if (freeit != NULL) free(freeit); return (0); } bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-dsfromkey.c0000644000470500017500000003645612664710322021062 0ustar lamontlamont/* * Copyright (C) 2008-2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef PKCS11CRYPTO #include #endif #include "dnssectool.h" #ifndef PATH_MAX #define PATH_MAX 1024 /* AIX, WIN32, and others don't define this. */ #endif const char *program = "dnssec-dsfromkey"; int verbose; static dns_rdataclass_t rdclass; static dns_fixedname_t fixed; static dns_name_t *name = NULL; static isc_mem_t *mctx = NULL; static isc_uint32_t ttl; static isc_boolean_t emitttl = ISC_FALSE; static isc_result_t initname(char *setname) { isc_result_t result; isc_buffer_t buf; dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); isc_buffer_init(&buf, setname, strlen(setname)); isc_buffer_add(&buf, strlen(setname)); result = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL); return (result); } static void db_load_from_stream(dns_db_t *db, FILE *fp) { isc_result_t result; dns_rdatacallbacks_t callbacks; dns_rdatacallbacks_init(&callbacks); result = dns_db_beginload(db, &callbacks); if (result != ISC_R_SUCCESS) fatal("dns_db_beginload failed: %s", isc_result_totext(result)); result = dns_master_loadstream(fp, name, name, rdclass, 0, &callbacks, mctx); if (result != ISC_R_SUCCESS) fatal("can't load from input: %s", isc_result_totext(result)); result = dns_db_endload(db, &callbacks); if (result != ISC_R_SUCCESS) fatal("dns_db_endload failed: %s", isc_result_totext(result)); } static isc_result_t loadset(const char *filename, dns_rdataset_t *rdataset) { isc_result_t result; dns_db_t *db = NULL; dns_dbnode_t *node = NULL; char setname[DNS_NAME_FORMATSIZE]; dns_name_format(name, setname, sizeof(setname)); result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone, rdclass, 0, NULL, &db); if (result != ISC_R_SUCCESS) fatal("can't create database"); if (strcmp(filename, "-") == 0) { db_load_from_stream(db, stdin); filename = "input"; } else { result = dns_db_load(db, filename); if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) fatal("can't load %s: %s", filename, isc_result_totext(result)); } result = dns_db_findnode(db, name, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) fatal("can't find %s node in %s", setname, filename); result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0, 0, rdataset, NULL); if (result == ISC_R_NOTFOUND) fatal("no DNSKEY RR for %s in %s", setname, filename); else if (result != ISC_R_SUCCESS) fatal("dns_db_findrdataset"); if (node != NULL) dns_db_detachnode(db, &node); if (db != NULL) dns_db_detach(&db); return (result); } static isc_result_t loadkeyset(char *dirname, dns_rdataset_t *rdataset) { isc_result_t result; char filename[PATH_MAX + 1]; isc_buffer_t buf; dns_rdataset_init(rdataset); isc_buffer_init(&buf, filename, sizeof(filename)); if (dirname != NULL) { /* allow room for a trailing slash */ if (strlen(dirname) >= isc_buffer_availablelength(&buf)) return (ISC_R_NOSPACE); isc_buffer_putstr(&buf, dirname); if (dirname[strlen(dirname) - 1] != '/') isc_buffer_putstr(&buf, "/"); } if (isc_buffer_availablelength(&buf) < 7) return (ISC_R_NOSPACE); isc_buffer_putstr(&buf, "keyset-"); result = dns_name_tofilenametext(name, ISC_FALSE, &buf); check_result(result, "dns_name_tofilenametext()"); if (isc_buffer_availablelength(&buf) == 0) return (ISC_R_NOSPACE); isc_buffer_putuint8(&buf, 0); return (loadset(filename, rdataset)); } static void loadkey(char *filename, unsigned char *key_buf, unsigned int key_buf_size, dns_rdata_t *rdata) { isc_result_t result; dst_key_t *key = NULL; isc_buffer_t keyb; isc_region_t r; dns_rdata_init(rdata); isc_buffer_init(&keyb, key_buf, key_buf_size); result = dst_key_fromnamedfile(filename, NULL, DST_TYPE_PUBLIC, mctx, &key); if (result != ISC_R_SUCCESS) fatal("invalid keyfile name %s: %s", filename, isc_result_totext(result)); if (verbose > 2) { char keystr[DST_KEY_FORMATSIZE]; dst_key_format(key, keystr, sizeof(keystr)); fprintf(stderr, "%s: %s\n", program, keystr); } result = dst_key_todns(key, &keyb); if (result != ISC_R_SUCCESS) fatal("can't decode key"); isc_buffer_usedregion(&keyb, &r); dns_rdata_fromregion(rdata, dst_key_class(key), dns_rdatatype_dnskey, &r); rdclass = dst_key_class(key); dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); result = dns_name_copy(dst_key_name(key), name, NULL); if (result != ISC_R_SUCCESS) fatal("can't copy name"); dst_key_free(&key); } static void logkey(dns_rdata_t *rdata) { isc_result_t result; dst_key_t *key = NULL; isc_buffer_t buf; char keystr[DST_KEY_FORMATSIZE]; isc_buffer_init(&buf, rdata->data, rdata->length); isc_buffer_add(&buf, rdata->length); result = dst_key_fromdns(name, rdclass, &buf, mctx, &key); if (result != ISC_R_SUCCESS) return; dst_key_format(key, keystr, sizeof(keystr)); fprintf(stderr, "%s: %s\n", program, keystr); dst_key_free(&key); } static void emit(unsigned int dtype, isc_boolean_t showall, char *lookaside, isc_boolean_t cds, dns_rdata_t *rdata) { isc_result_t result; unsigned char buf[DNS_DS_BUFFERSIZE]; char text_buf[DST_KEY_MAXTEXTSIZE]; char name_buf[DNS_NAME_MAXWIRE]; char class_buf[10]; isc_buffer_t textb, nameb, classb; isc_region_t r; dns_rdata_t ds; dns_rdata_dnskey_t dnskey; isc_buffer_init(&textb, text_buf, sizeof(text_buf)); isc_buffer_init(&nameb, name_buf, sizeof(name_buf)); isc_buffer_init(&classb, class_buf, sizeof(class_buf)); dns_rdata_init(&ds); result = dns_rdata_tostruct(rdata, &dnskey, NULL); if (result != ISC_R_SUCCESS) fatal("can't convert DNSKEY"); if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0 && !showall) return; result = dns_ds_buildrdata(name, rdata, dtype, buf, &ds); if (result != ISC_R_SUCCESS) fatal("can't build record"); result = dns_name_totext(name, ISC_FALSE, &nameb); if (result != ISC_R_SUCCESS) fatal("can't print name"); /* Add lookaside origin, if set */ if (lookaside != NULL) { if (isc_buffer_availablelength(&nameb) < strlen(lookaside)) fatal("DLV origin '%s' is too long", lookaside); isc_buffer_putstr(&nameb, lookaside); if (lookaside[strlen(lookaside) - 1] != '.') { if (isc_buffer_availablelength(&nameb) < 1) fatal("DLV origin '%s' is too long", lookaside); isc_buffer_putstr(&nameb, "."); } } result = dns_rdata_tofmttext(&ds, (dns_name_t *) NULL, 0, 0, 0, "", &textb); if (result != ISC_R_SUCCESS) fatal("can't print rdata"); result = dns_rdataclass_totext(rdclass, &classb); if (result != ISC_R_SUCCESS) fatal("can't print class"); isc_buffer_usedregion(&nameb, &r); printf("%.*s ", (int)r.length, r.base); if (emitttl) printf("%u ", ttl); isc_buffer_usedregion(&classb, &r); printf("%.*s", (int)r.length, r.base); if (lookaside == NULL) { if (cds) printf(" CDS "); else printf(" DS "); } else printf(" DLV "); isc_buffer_usedregion(&textb, &r); printf("%.*s\n", (int)r.length, r.base); } ISC_PLATFORM_NORETURN_PRE static void usage(void) ISC_PLATFORM_NORETURN_POST; static void usage(void) { fprintf(stderr, "Usage:\n"); fprintf(stderr, " %s options [-K dir] keyfile\n\n", program); fprintf(stderr, " %s options [-K dir] [-c class] -s dnsname\n\n", program); fprintf(stderr, " %s options -f zonefile (as zone name)\n\n", program); fprintf(stderr, " %s options -f zonefile zonename\n\n", program); fprintf(stderr, "Version: %s\n", VERSION); fprintf(stderr, "Options:\n"); fprintf(stderr, " -v \n"); fprintf(stderr, " -V: print version information\n"); fprintf(stderr, " -K : directory in which to find " "key file or keyset file\n"); fprintf(stderr, " -a algorithm: digest algorithm " "(SHA-1, SHA-256, GOST or SHA-384)\n"); fprintf(stderr, " -1: use SHA-1\n"); fprintf(stderr, " -2: use SHA-256\n"); fprintf(stderr, " -C: print CDS record\n"); fprintf(stderr, " -l: add lookaside zone and print DLV records\n"); fprintf(stderr, " -s: read keyset from keyset- file\n"); fprintf(stderr, " -c class: rdata class for DS set (default: IN)\n"); fprintf(stderr, " -T TTL\n"); fprintf(stderr, " -f file: read keyset from zone file\n"); fprintf(stderr, " -A: when used with -f, " "include all keys in DS set, not just KSKs\n"); fprintf(stderr, "Output: DS or DLV RRs\n"); exit (-1); } int main(int argc, char **argv) { char *algname = NULL, *classname = NULL; char *filename = NULL, *dir = NULL, *namestr; char *lookaside = NULL; char *endp; int ch; unsigned int dtype = DNS_DSDIGEST_SHA1; isc_boolean_t cds = ISC_FALSE; isc_boolean_t both = ISC_TRUE; isc_boolean_t usekeyset = ISC_FALSE; isc_boolean_t showall = ISC_FALSE; isc_result_t result; isc_log_t *log = NULL; isc_entropy_t *ectx = NULL; dns_rdataset_t rdataset; dns_rdata_t rdata; dns_rdata_init(&rdata); if (argc == 1) usage(); result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) fatal("out of memory"); #ifdef PKCS11CRYPTO pk11_result_register(); #endif dns_result_register(); isc_commandline_errprint = ISC_FALSE; #define OPTIONS "12Aa:Cc:d:Ff:K:l:sT:v:hV" while ((ch = isc_commandline_parse(argc, argv, OPTIONS)) != -1) { switch (ch) { case '1': dtype = DNS_DSDIGEST_SHA1; both = ISC_FALSE; break; case '2': dtype = DNS_DSDIGEST_SHA256; both = ISC_FALSE; break; case 'A': showall = ISC_TRUE; break; case 'a': algname = isc_commandline_argument; both = ISC_FALSE; break; case 'C': if (lookaside != NULL) fatal("lookaside and CDS are mutually" " exclusive"); cds = ISC_TRUE; break; case 'c': classname = isc_commandline_argument; break; case 'd': fprintf(stderr, "%s: the -d option is deprecated; " "use -K\n", program); /* fall through */ case 'K': dir = isc_commandline_argument; if (strlen(dir) == 0U) fatal("directory must be non-empty string"); break; case 'f': filename = isc_commandline_argument; break; case 'l': if (cds) fatal("lookaside and CDS are mutually" " exclusive"); lookaside = isc_commandline_argument; if (strlen(lookaside) == 0U) fatal("lookaside must be a non-empty string"); break; case 's': usekeyset = ISC_TRUE; break; case 'T': emitttl = ISC_TRUE; ttl = atol(isc_commandline_argument); break; case 'v': verbose = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') fatal("-v must be followed by a number"); break; case 'F': /* Reserved for FIPS mode */ /* FALLTHROUGH */ case '?': if (isc_commandline_option != '?') fprintf(stderr, "%s: invalid argument -%c\n", program, isc_commandline_option); /* FALLTHROUGH */ case 'h': /* Does not return. */ usage(); case 'V': /* Does not return. */ version(program); default: fprintf(stderr, "%s: unhandled option -%c\n", program, isc_commandline_option); exit(1); } } if (algname != NULL) { if (strcasecmp(algname, "SHA1") == 0 || strcasecmp(algname, "SHA-1") == 0) dtype = DNS_DSDIGEST_SHA1; else if (strcasecmp(algname, "SHA256") == 0 || strcasecmp(algname, "SHA-256") == 0) dtype = DNS_DSDIGEST_SHA256; #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) else if (strcasecmp(algname, "GOST") == 0) dtype = DNS_DSDIGEST_GOST; #endif else if (strcasecmp(algname, "SHA384") == 0 || strcasecmp(algname, "SHA-384") == 0) dtype = DNS_DSDIGEST_SHA384; else fatal("unknown algorithm %s", algname); } rdclass = strtoclass(classname); if (usekeyset && filename != NULL) fatal("cannot use both -s and -f"); /* When not using -f, -A is implicit */ if (filename == NULL) showall = ISC_TRUE; if (argc < isc_commandline_index + 1 && filename == NULL) fatal("the key file name was not specified"); if (argc > isc_commandline_index + 1) fatal("extraneous arguments"); if (ectx == NULL) setup_entropy(mctx, NULL, &ectx); result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (result != ISC_R_SUCCESS) fatal("could not initialize hash"); result = dst_lib_init(mctx, ectx, ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); if (result != ISC_R_SUCCESS) fatal("could not initialize dst: %s", isc_result_totext(result)); isc_entropy_stopcallbacksources(ectx); setup_logging(mctx, &log); dns_rdataset_init(&rdataset); if (usekeyset || filename != NULL) { if (argc < isc_commandline_index + 1 && filename != NULL) { /* using zone name as the zone file name */ namestr = filename; } else namestr = argv[isc_commandline_index]; result = initname(namestr); if (result != ISC_R_SUCCESS) fatal("could not initialize name %s", namestr); if (usekeyset) result = loadkeyset(dir, &rdataset); else result = loadset(filename, &rdataset); if (result != ISC_R_SUCCESS) fatal("could not load DNSKEY set: %s\n", isc_result_totext(result)); for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_init(&rdata); dns_rdataset_current(&rdataset, &rdata); if (verbose > 2) logkey(&rdata); if (both) { emit(DNS_DSDIGEST_SHA1, showall, lookaside, cds, &rdata); emit(DNS_DSDIGEST_SHA256, showall, lookaside, cds, &rdata); } else emit(dtype, showall, lookaside, cds, &rdata); } } else { unsigned char key_buf[DST_KEY_MAXSIZE]; loadkey(argv[isc_commandline_index], key_buf, DST_KEY_MAXSIZE, &rdata); if (both) { emit(DNS_DSDIGEST_SHA1, showall, lookaside, cds, &rdata); emit(DNS_DSDIGEST_SHA256, showall, lookaside, cds, &rdata); } else emit(dtype, showall, lookaside, cds, &rdata); } if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); cleanup_logging(&log); dst_lib_destroy(); isc_hash_destroy(); cleanup_entropy(&ectx); dns_name_destroy(); if (verbose > 10) isc_mem_stats(mctx, stdout); isc_mem_destroy(&mctx); fflush(stdout); if (ferror(stdout)) { fprintf(stderr, "write error\n"); return (1); } else return (0); } bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-keygen.docbook0000644000470500017500000005765612664710322021544 0ustar lamontlamont]> February 06, 2014 dnssec-keygen 8 BIND9 dnssec-keygen DNSSEC key generation tool 2004 2005 2007 2008 2009 2010 2011 2012 2014 2015 Internet Systems Consortium, Inc. ("ISC") 2000 2001 2002 2003 Internet Software Consortium. dnssec-keygen name DESCRIPTION dnssec-keygen generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034. It can also generate keys for use with TSIG (Transaction Signatures) as defined in RFC 2845, or TKEY (Transaction Key) as defined in RFC 2930. The of the key is specified on the command line. For DNSSEC keys, this must match the name of the zone for which the key is being generated. OPTIONS -a algorithm Selects the cryptographic algorithm. For DNSSEC keys, the value of must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512, ECCGOST, ECDSAP256SHA256 or ECDSAP384SHA384. For TSIG/TKEY, the value must be DH (Diffie Hellman), HMAC-MD5, HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512. These values are case insensitive. If no algorithm is specified, then RSASHA1 will be used by default, unless the option is specified, in which case NSEC3RSASHA1 will be used instead. (If is used and an algorithm is specified, that algorithm will be checked for compatibility with NSEC3.) Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended. For TSIG, HMAC-MD5 is mandatory. Note 2: DH, HMAC-MD5, and HMAC-SHA1 through HMAC-SHA512 automatically set the -T KEY option. -b keysize Specifies the number of bits in the key. The choice of key size depends on the algorithm used. RSA keys must be between 512 and 2048 bits. Diffie Hellman keys must be between 128 and 4096 bits. DSA keys must be between 512 and 1024 bits and an exact multiple of 64. HMAC keys must be between 1 and 512 bits. Elliptic curve algorithms don't need this parameter. The key size does not need to be specified if using a default algorithm. The default key size is 1024 bits for zone signing keys (ZSK's) and 2048 bits for key signing keys (KSK's, generated with ). However, if an algorithm is explicitly specified with the , then there is no default key size, and the must be used. -n nametype Specifies the owner type of the key. The value of must either be ZONE (for a DNSSEC zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with a host (KEY)), USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). These values are case insensitive. Defaults to ZONE for DNSKEY generation. -3 Use an NSEC3-capable algorithm to generate a DNSSEC key. If this option is used and no algorithm is explicitly set on the command line, NSEC3RSASHA1 will be used by default. Note that RSASHA256, RSASHA512, ECCGOST, ECDSAP256SHA256 and ECDSAP384SHA384 algorithms are NSEC3-capable. -C Compatibility mode: generates an old-style key, without any metadata. By default, dnssec-keygen will include the key's creation date in the metadata stored with the private key, and other dates may be set there as well (publication date, activation date, etc). Keys that include this data may be incompatible with older versions of BIND; the option suppresses them. -c class Indicates that the DNS record containing the key should have the specified class. If not specified, class IN is used. -E engine Specifies the cryptographic hardware to use, when applicable. When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (--enable-native-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "--with-pkcs11". -f flag Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flags are KSK (Key Signing Key) and REVOKE. -G Generate a key, but do not publish it or sign with it. This option is incompatible with -P and -A. -g generator If generating a Diffie Hellman key, use this generator. Allowed values are 2 and 5. If no generator is specified, a known prime from RFC 2539 will be used if possible; otherwise the default is 2. -h Prints a short summary of the options and arguments to dnssec-keygen. -K directory Sets the directory in which the key files are to be written. -k Deprecated in favor of -T KEY. -L ttl Sets the default TTL to use for this key when it is converted into a DNSKEY RR. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence. If this value is not set and there is no existing DNSKEY RRset, the TTL will default to the SOA TTL. Setting the default TTL to 0 or none is the same as leaving it unset. -p protocol Sets the protocol value for the generated key. The protocol is a number between 0 and 255. The default is 3 (DNSSEC). Other possible values for this argument are listed in RFC 2535 and its successors. -q Quiet mode: Suppresses unnecessary output, including progress indication. Without this option, when dnssec-keygen is run interactively to generate an RSA or DSA key pair, it will print a string of symbols to stderr indicating the progress of the key generation. A '.' indicates that a random number has been found which passed an initial sieve test; '+' means a number has passed a single round of the Miller-Rabin primality test; a space means that the number has passed all the tests and is a satisfactory key. -r randomdev Specifies the source of randomness. If the operating system does not provide a /dev/random or equivalent device, the default source of randomness is keyboard input. randomdev specifies the name of a character device or file containing random data to be used instead of the default. The special value keyboard indicates that keyboard input should be used. -S key Create a new key which is an explicit successor to an existing key. The name, algorithm, size, and type of the key will be set to match the existing key. The activation date of the new key will be set to the inactivation date of the existing one. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days. -s strength Specifies the strength value of the key. The strength is a number between 0 and 15, and currently has no defined purpose in DNSSEC. -T rrtype Specifies the resource record type to use for the key. must be either DNSKEY or KEY. The default is DNSKEY when using a DNSSEC algorithm, but it can be overridden to KEY for use with SIG(0). Using any TSIG algorithm (HMAC-* or DH) forces this option to KEY. -t type Indicates the use of the key. must be one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default is AUTHCONF. AUTH refers to the ability to authenticate data, and CONF the ability to encrypt data. -v level Sets the debugging level. -V Prints version information. TIMING OPTIONS Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24-hour days, ignoring leap years), months (defined as 30 24-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To explicitly prevent a date from being set, use 'none' or 'never'. -P date/offset Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it. If not set, and if the -G option has not been used, the default is "now". -A date/offset Sets the date on which the key is to be activated. After that date, the key will be included in the zone and used to sign it. If not set, and if the -G option has not been used, the default is "now". If set, if and -P is not set, then the publication date will be set to the activation date minus the prepublication interval. -R date/offset Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it. -I date/offset Sets the date on which the key is to be retired. After that date, the key will still be included in the zone, but it will not be used to sign it. -D date/offset Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.) -i interval Sets the prepublication interval for a key. If set, then the publication and activation dates must be separated by at least this much time. If the activation date is specified but the publication date isn't, then the publication date will default to this much time before the activation date; conversely, if the publication date is specified but activation date isn't, then activation will be set to this much time after publication. If the key is being created as an explicit successor to another key, then the default prepublication interval is 30 days; otherwise it is zero. As with date offsets, if the argument is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the interval is measured in years, months, weeks, days, hours, or minutes, respectively. Without a suffix, the interval is measured in seconds. GENERATED KEYS When dnssec-keygen completes successfully, it prints a string of the form Knnnn.+aaa+iiiii to the standard output. This is an identification string for the key it has generated. nnnn is the key name. aaa is the numeric representation of the algorithm. iiiii is the key identifier (or footprint). dnssec-keygen creates two files, with names based on the printed string. Knnnn.+aaa+iiiii.key contains the public key, and Knnnn.+aaa+iiiii.private contains the private key. The .key file contains a DNS KEY record that can be inserted into a zone file (directly or with a $INCLUDE statement). The .private file contains algorithm-specific fields. For obvious security reasons, this file does not have general read permission. Both .key and .private files are generated for symmetric encryption algorithms such as HMAC-MD5, even though the public and private key are equivalent. EXAMPLE To generate a 768-bit DSA key for the domain example.com, the following command would be issued: dnssec-keygen -a DSA -b 768 -n ZONE example.com The command would print a string of the form: Kexample.com.+003+26160 In this example, dnssec-keygen creates the files Kexample.com.+003+26160.key and Kexample.com.+003+26160.private. SEE ALSO dnssec-signzone8 , BIND 9 Administrator Reference Manual, RFC 2539, RFC 2845, RFC 4034. AUTHOR Internet Systems Consortium bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-settime.docbook0000644000470500017500000003227112664710322021716 0ustar lamontlamont]> February 06, 2014 dnssec-settime 8 BIND9 dnssec-settime Set the key timing metadata for a DNSSEC key 2009 2010 2011 2014 2015 Internet Systems Consortium, Inc. ("ISC") dnssec-settime keyfile DESCRIPTION dnssec-settime reads a DNSSEC private key file and sets the key timing metadata as specified by the , , , , and options. The metadata can then be used by dnssec-signzone or other signing software to determine when a key is to be published, whether it should be used for signing a zone, etc. If none of these options is set on the command line, then dnssec-settime simply prints the key timing metadata already stored in the key. When key metadata fields are changed, both files of a key pair (Knnnn.+aaa+iiiii.key and Knnnn.+aaa+iiiii.private) are regenerated. Metadata fields are stored in the private file. A human-readable description of the metadata is also placed in comments in the key file. The private file's permissions are always set to be inaccessible to anyone other than the owner (mode 0600). OPTIONS -f Force an update of an old-format key with no metadata fields. Without this option, dnssec-settime will fail when attempting to update a legacy key. With this option, the key will be recreated in the new format, but with the original key data retained. The key's creation date will be set to the present time. If no other values are specified, then the key's publication and activation dates will also be set to the present time. -K directory Sets the directory in which the key files are to reside. -L ttl Sets the default TTL to use for this key when it is converted into a DNSKEY RR. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence. If this value is not set and there is no existing DNSKEY RRset, the TTL will default to the SOA TTL. Setting the default TTL to 0 or none removes it from the key. -h Emit usage message and exit. -V Prints version information. -v level Sets the debugging level. -E engine Specifies the cryptographic hardware to use, when applicable. When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (--enable-native-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "--with-pkcs11". TIMING OPTIONS Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24-hour days, ignoring leap years), months (defined as 30 24-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To unset a date, use 'none' or 'never'. -P date/offset Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it. -A date/offset Sets the date on which the key is to be activated. After that date, the key will be included in the zone and used to sign it. -R date/offset Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it. -I date/offset Sets the date on which the key is to be retired. After that date, the key will still be included in the zone, but it will not be used to sign it. -D date/offset Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.) -S predecessor key Select a key for which the key being modified will be an explicit successor. The name, algorithm, size, and type of the predecessor key must exactly match those of the key being modified. The activation date of the successor key will be set to the inactivation date of the predecessor. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days. -i interval Sets the prepublication interval for a key. If set, then the publication and activation dates must be separated by at least this much time. If the activation date is specified but the publication date isn't, then the publication date will default to this much time before the activation date; conversely, if the publication date is specified but activation date isn't, then activation will be set to this much time after publication. If the key is being set to be an explicit successor to another key, then the default prepublication interval is 30 days; otherwise it is zero. As with date offsets, if the argument is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the interval is measured in years, months, weeks, days, hours, or minutes, respectively. Without a suffix, the interval is measured in seconds. PRINTING OPTIONS dnssec-settime can also be used to print the timing metadata associated with a key. -u Print times in UNIX epoch format. -p C/P/A/R/I/D/all Print a specific metadata value or set of metadata values. The option may be followed by one or more of the following letters to indicate which value or values to print: for the creation date, for the publication date, for the activation date, for the revocation date, for the inactivation date, or for the deletion date. To print all of the metadata, use . SEE ALSO dnssec-keygen8 , dnssec-signzone8 , BIND 9 Administrator Reference Manual, RFC 5011. AUTHOR Internet Systems Consortium bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-verify.docbook0000644000470500017500000001601612664710322021547 0ustar lamontlamont]> January 15, 2014 dnssec-verify 8 BIND9 dnssec-verify DNSSEC zone verification tool 2012 2014 Internet Systems Consortium, Inc. ("ISC") dnssec-verify zonefile DESCRIPTION dnssec-verify verifies that a zone is fully signed for each algorithm found in the DNSKEY RRset for the zone, and that the NSEC / NSEC3 chains are complete. OPTIONS -c class Specifies the DNS class of the zone. -E engine Specifies the cryptographic hardware to use, when applicable. When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (--enable-native-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "--with-pkcs11". -I input-format The format of the input zone file. Possible formats are "text" (default) and "raw". This option is primarily intended to be used for dynamic signed zones so that the dumped zone file in a non-text format containing updates can be verified independently. The use of this option does not make much sense for non-dynamic zones. -o origin The zone origin. If not specified, the name of the zone file is assumed to be the origin. -v level Sets the debugging level. -V Prints version information. -x Only verify that the DNSKEY RRset is signed with key-signing keys. Without this flag, it is assumed that the DNSKEY RRset will be signed by all active keys. When this flag is set, it will not be an error if the DNSKEY RRset is not signed by zone-signing keys. This corresponds to the option in dnssec-signzone. -z Ignore the KSK flag on the keys when determining whether the zone if correctly signed. Without this flag it is assumed that there will be a non-revoked, self-signed DNSKEY with the KSK flag set for each algorithm and that RRsets other than DNSKEY RRset will be signed with a different DNSKEY without the KSK flag set. With this flag set, we only require that for each algorithm, there will be at least one non-revoked, self-signed DNSKEY, regardless of the KSK flag state, and that other RRsets will be signed by a non-revoked key for the same algorithm that includes the self-signed key; the same key may be used for both purposes. This corresponds to the option in dnssec-signzone. zonefile The file containing the zone to be signed. SEE ALSO dnssec-signzone8 , BIND 9 Administrator Reference Manual, RFC 4033. AUTHOR Internet Systems Consortium bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-signzone.c0000644000470500017500000032561012664710322020704 0ustar lamontlamont/* * Portions Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef PKCS11CRYPTO #include #endif #include "dnssectool.h" #ifndef PATH_MAX #define PATH_MAX 1024 /* AIX, WIN32, and others don't define this. */ #endif const char *program = "dnssec-signzone"; int verbose; typedef struct hashlist hashlist_t; static int nsec_datatype = dns_rdatatype_nsec; #define IS_NSEC3 (nsec_datatype == dns_rdatatype_nsec3) #define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0) #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0) #define BUFSIZE 2048 #define MAXDSKEYS 8 #define SIGNER_EVENTCLASS ISC_EVENTCLASS(0x4453) #define SIGNER_EVENT_WRITE (SIGNER_EVENTCLASS + 0) #define SIGNER_EVENT_WORK (SIGNER_EVENTCLASS + 1) #define SOA_SERIAL_KEEP 0 #define SOA_SERIAL_INCREMENT 1 #define SOA_SERIAL_UNIXTIME 2 typedef struct signer_event sevent_t; struct signer_event { ISC_EVENT_COMMON(sevent_t); dns_fixedname_t *fname; dns_dbnode_t *node; }; static dns_dnsseckeylist_t keylist; static unsigned int keycount = 0; isc_rwlock_t keylist_lock; static isc_stdtime_t starttime = 0, endtime = 0, dnskey_endtime = 0, now; static int cycle = -1; static int jitter = 0; static isc_boolean_t tryverify = ISC_FALSE; static isc_boolean_t printstats = ISC_FALSE; static isc_mem_t *mctx = NULL; static isc_entropy_t *ectx = NULL; static dns_ttl_t zone_soa_min_ttl; static dns_ttl_t soa_ttl; static FILE *outfp = NULL; static char *tempfile = NULL; static const dns_master_style_t *masterstyle; static dns_masterformat_t inputformat = dns_masterformat_text; static dns_masterformat_t outputformat = dns_masterformat_text; static isc_uint32_t rawversion = 1, serialnum = 0; static isc_boolean_t snset = ISC_FALSE; static unsigned int nsigned = 0, nretained = 0, ndropped = 0; static unsigned int nverified = 0, nverifyfailed = 0; static const char *directory = NULL, *dsdir = NULL; static isc_mutex_t namelock, statslock; static isc_taskmgr_t *taskmgr = NULL; static dns_db_t *gdb; /* The database */ static dns_dbversion_t *gversion; /* The database version */ static dns_dbiterator_t *gdbiter; /* The database iterator */ static dns_rdataclass_t gclass; /* The class */ static dns_name_t *gorigin; /* The database origin */ static int nsec3flags = 0; static dns_iterations_t nsec3iter = 10U; static unsigned char saltbuf[255]; static unsigned char *gsalt = saltbuf; static size_t salt_length = 0; static isc_task_t *master = NULL; static unsigned int ntasks = 0; static isc_boolean_t shuttingdown = ISC_FALSE, finished = ISC_FALSE; static isc_boolean_t nokeys = ISC_FALSE; static isc_boolean_t removefile = ISC_FALSE; static isc_boolean_t generateds = ISC_FALSE; static isc_boolean_t ignore_kskflag = ISC_FALSE; static isc_boolean_t keyset_kskonly = ISC_FALSE; static dns_name_t *dlv = NULL; static dns_fixedname_t dlv_fixed; static dns_master_style_t *dsstyle = NULL; static unsigned int serialformat = SOA_SERIAL_KEEP; static unsigned int hash_length = 0; static isc_boolean_t unknownalg = ISC_FALSE; static isc_boolean_t disable_zone_check = ISC_FALSE; static isc_boolean_t update_chain = ISC_FALSE; static isc_boolean_t set_keyttl = ISC_FALSE; static dns_ttl_t keyttl; static isc_boolean_t smartsign = ISC_FALSE; static isc_boolean_t remove_orphansigs = ISC_FALSE; static isc_boolean_t remove_inactkeysigs = ISC_FALSE; static isc_boolean_t output_dnssec_only = ISC_FALSE; static isc_boolean_t output_stdout = ISC_FALSE; isc_boolean_t set_maxttl = ISC_FALSE; static dns_ttl_t maxttl = 0; #define INCSTAT(counter) \ if (printstats) { \ LOCK(&statslock); \ counter++; \ UNLOCK(&statslock); \ } static void sign(isc_task_t *task, isc_event_t *event); static void dumpnode(dns_name_t *name, dns_dbnode_t *node) { dns_rdataset_t rds; dns_rdatasetiter_t *iter = NULL; isc_buffer_t *buffer = NULL; isc_region_t r; isc_result_t result; unsigned bufsize = 4096; if (outputformat != dns_masterformat_text) return; if (!output_dnssec_only) { result = dns_master_dumpnodetostream(mctx, gdb, gversion, node, name, masterstyle, outfp); check_result(result, "dns_master_dumpnodetostream"); return; } result = dns_db_allrdatasets(gdb, node, gversion, 0, &iter); check_result(result, "dns_db_allrdatasets"); dns_rdataset_init(&rds); result = isc_buffer_allocate(mctx, &buffer, bufsize); check_result(result, "isc_buffer_allocate"); for (result = dns_rdatasetiter_first(iter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(iter)) { dns_rdatasetiter_current(iter, &rds); if (rds.type != dns_rdatatype_rrsig && rds.type != dns_rdatatype_nsec && rds.type != dns_rdatatype_nsec3 && rds.type != dns_rdatatype_nsec3param && (!smartsign || rds.type != dns_rdatatype_dnskey)) { dns_rdataset_disassociate(&rds); continue; } for (;;) { result = dns_master_rdatasettotext(name, &rds, masterstyle, buffer); if (result != ISC_R_NOSPACE) break; bufsize <<= 1; isc_buffer_free(&buffer); result = isc_buffer_allocate(mctx, &buffer, bufsize); check_result(result, "isc_buffer_allocate"); } check_result(result, "dns_master_rdatasettotext"); isc_buffer_usedregion(buffer, &r); result = isc_stdio_write(r.base, 1, r.length, outfp, NULL); check_result(result, "isc_stdio_write"); isc_buffer_clear(buffer); dns_rdataset_disassociate(&rds); } isc_buffer_free(&buffer); dns_rdatasetiter_destroy(&iter); } /*% * Sign the given RRset with given key, and add the signature record to the * given tuple. */ static void signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dst_key_t *key, dns_ttl_t ttl, dns_diff_t *add, const char *logmsg) { isc_result_t result; isc_stdtime_t jendtime, expiry; char keystr[DST_KEY_FORMATSIZE]; dns_rdata_t trdata = DNS_RDATA_INIT; unsigned char array[BUFSIZE]; isc_buffer_t b; dns_difftuple_t *tuple; dst_key_format(key, keystr, sizeof(keystr)); vbprintf(1, "\t%s %s\n", logmsg, keystr); if (rdataset->type == dns_rdatatype_dnskey) expiry = dnskey_endtime; else expiry = endtime; jendtime = (jitter != 0) ? isc_random_jitter(expiry, jitter) : expiry; isc_buffer_init(&b, array, sizeof(array)); result = dns_dnssec_sign(name, rdataset, key, &starttime, &jendtime, mctx, &b, &trdata); isc_entropy_stopcallbacksources(ectx); if (result != ISC_R_SUCCESS) { fatal("dnskey '%s' failed to sign data: %s", keystr, isc_result_totext(result)); } INCSTAT(nsigned); if (tryverify) { result = dns_dnssec_verify(name, rdataset, key, ISC_TRUE, mctx, &trdata); if (result == ISC_R_SUCCESS) { vbprintf(3, "\tsignature verified\n"); INCSTAT(nverified); } else { vbprintf(3, "\tsignature failed to verify\n"); INCSTAT(nverifyfailed); } } tuple = NULL; result = dns_difftuple_create(mctx, DNS_DIFFOP_ADDRESIGN, name, ttl, &trdata, &tuple); check_result(result, "dns_difftuple_create"); dns_diff_append(add, &tuple); } static inline isc_boolean_t issigningkey(dns_dnsseckey_t *key) { return (key->force_sign || key->hint_sign); } static inline isc_boolean_t ispublishedkey(dns_dnsseckey_t *key) { return ((key->force_publish || key->hint_publish) && !key->hint_remove); } static inline isc_boolean_t iszonekey(dns_dnsseckey_t *key) { return (ISC_TF(dns_name_equal(dst_key_name(key->key), gorigin) && dst_key_iszonekey(key->key))); } static inline isc_boolean_t isksk(dns_dnsseckey_t *key) { return (key->ksk); } static inline isc_boolean_t iszsk(dns_dnsseckey_t *key) { return (ignore_kskflag || !key->ksk); } /*% * Find the key that generated an RRSIG, if it is in the key list. If * so, return a pointer to it, otherwise return NULL. * * No locking is performed here, this must be done by the caller. */ static dns_dnsseckey_t * keythatsigned_unlocked(dns_rdata_rrsig_t *rrsig) { dns_dnsseckey_t *key; for (key = ISC_LIST_HEAD(keylist); key != NULL; key = ISC_LIST_NEXT(key, link)) { if (rrsig->keyid == dst_key_id(key->key) && rrsig->algorithm == dst_key_alg(key->key) && dns_name_equal(&rrsig->signer, dst_key_name(key->key))) return (key); } return (NULL); } /*% * Finds the key that generated a RRSIG, if possible. First look at the keys * that we've loaded already, and then see if there's a key on disk. */ static dns_dnsseckey_t * keythatsigned(dns_rdata_rrsig_t *rrsig) { isc_result_t result; dst_key_t *pubkey = NULL, *privkey = NULL; dns_dnsseckey_t *key = NULL; isc_rwlock_lock(&keylist_lock, isc_rwlocktype_read); key = keythatsigned_unlocked(rrsig); isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_read); if (key != NULL) return (key); /* * We did not find the key in our list. Get a write lock now, since * we may be modifying the bits. We could do the tryupgrade() dance, * but instead just get a write lock and check once again to see if * it is on our list. It's possible someone else may have added it * after all. */ isc_rwlock_lock(&keylist_lock, isc_rwlocktype_write); key = keythatsigned_unlocked(rrsig); if (key != NULL) { isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write); return (key); } result = dst_key_fromfile(&rrsig->signer, rrsig->keyid, rrsig->algorithm, DST_TYPE_PUBLIC, directory, mctx, &pubkey); if (result != ISC_R_SUCCESS) { isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write); return (NULL); } result = dst_key_fromfile(&rrsig->signer, rrsig->keyid, rrsig->algorithm, DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, directory, mctx, &privkey); if (result == ISC_R_SUCCESS) { dst_key_free(&pubkey); result = dns_dnsseckey_create(mctx, &privkey, &key); } else result = dns_dnsseckey_create(mctx, &pubkey, &key); if (result == ISC_R_SUCCESS) { key->force_publish = ISC_FALSE; key->force_sign = ISC_FALSE; key->index = keycount++; ISC_LIST_APPEND(keylist, key, link); } isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write); return (key); } /*% * Check to see if we expect to find a key at this name. If we see a RRSIG * and can't find the signing key that we expect to find, we drop the rrsig. * I'm not sure if this is completely correct, but it seems to work. */ static isc_boolean_t expecttofindkey(dns_name_t *name) { unsigned int options = DNS_DBFIND_NOWILD; dns_fixedname_t fname; isc_result_t result; char namestr[DNS_NAME_FORMATSIZE]; dns_fixedname_init(&fname); result = dns_db_find(gdb, name, gversion, dns_rdatatype_dnskey, options, 0, NULL, dns_fixedname_name(&fname), NULL, NULL); switch (result) { case ISC_R_SUCCESS: case DNS_R_NXDOMAIN: case DNS_R_NXRRSET: return (ISC_TRUE); case DNS_R_DELEGATION: case DNS_R_CNAME: case DNS_R_DNAME: return (ISC_FALSE); } dns_name_format(name, namestr, sizeof(namestr)); fatal("failure looking for '%s DNSKEY' in database: %s", namestr, isc_result_totext(result)); /* NOTREACHED */ return (ISC_FALSE); /* removes a warning */ } static inline isc_boolean_t setverifies(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, dns_rdata_t *rrsig) { isc_result_t result; result = dns_dnssec_verify(name, set, key, ISC_FALSE, mctx, rrsig); if (result == ISC_R_SUCCESS) { INCSTAT(nverified); return (ISC_TRUE); } else { INCSTAT(nverifyfailed); return (ISC_FALSE); } } /*% * Signs a set. Goes through contortions to decide if each RRSIG should * be dropped or retained, and then determines if any new SIGs need to * be generated. */ static void signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name, dns_rdataset_t *set) { dns_rdataset_t sigset; dns_rdata_t sigrdata = DNS_RDATA_INIT; dns_rdata_rrsig_t rrsig; dns_dnsseckey_t *key; isc_result_t result; isc_boolean_t nosigs = ISC_FALSE; isc_boolean_t *wassignedby, *nowsignedby; int arraysize; dns_difftuple_t *tuple; dns_ttl_t ttl; int i; char namestr[DNS_NAME_FORMATSIZE]; char typestr[TYPE_FORMATSIZE]; char sigstr[SIG_FORMATSIZE]; dns_name_format(name, namestr, sizeof(namestr)); type_format(set->type, typestr, sizeof(typestr)); ttl = ISC_MIN(set->ttl, endtime - starttime); dns_rdataset_init(&sigset); result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_rrsig, set->type, 0, &sigset, NULL); if (result == ISC_R_NOTFOUND) { vbprintf(2, "no existing signatures for %s/%s\n", namestr, typestr); result = ISC_R_SUCCESS; nosigs = ISC_TRUE; } if (result != ISC_R_SUCCESS) fatal("failed while looking for '%s RRSIG %s': %s", namestr, typestr, isc_result_totext(result)); vbprintf(1, "%s/%s:\n", namestr, typestr); arraysize = keycount; if (!nosigs) arraysize += dns_rdataset_count(&sigset); wassignedby = isc_mem_get(mctx, arraysize * sizeof(isc_boolean_t)); nowsignedby = isc_mem_get(mctx, arraysize * sizeof(isc_boolean_t)); if (wassignedby == NULL || nowsignedby == NULL) fatal("out of memory"); for (i = 0; i < arraysize; i++) wassignedby[i] = nowsignedby[i] = ISC_FALSE; if (nosigs) result = ISC_R_NOMORE; else result = dns_rdataset_first(&sigset); while (result == ISC_R_SUCCESS) { isc_boolean_t expired, future; isc_boolean_t keep = ISC_FALSE, resign = ISC_FALSE; dns_rdataset_current(&sigset, &sigrdata); result = dns_rdata_tostruct(&sigrdata, &rrsig, NULL); check_result(result, "dns_rdata_tostruct"); future = isc_serial_lt(now, rrsig.timesigned); key = keythatsigned(&rrsig); sig_format(&rrsig, sigstr, sizeof(sigstr)); if (key != NULL && issigningkey(key)) expired = isc_serial_gt(now + cycle, rrsig.timeexpire); else expired = isc_serial_gt(now, rrsig.timeexpire); if (isc_serial_gt(rrsig.timesigned, rrsig.timeexpire)) { /* rrsig is dropped and not replaced */ vbprintf(2, "\trrsig by %s dropped - " "invalid validity period\n", sigstr); } else if (key == NULL && !future && expecttofindkey(&rrsig.signer)) { /* rrsig is dropped and not replaced */ vbprintf(2, "\trrsig by %s dropped - " "private dnskey not found\n", sigstr); } else if (key == NULL || future) { keep = (!expired && !remove_orphansigs); vbprintf(2, "\trrsig by %s %s - dnskey not found\n", keep ? "retained" : "dropped", sigstr); } else if (!dns_dnssec_keyactive(key->key, now) && remove_inactkeysigs) { keep = ISC_FALSE; vbprintf(2, "\trrsig by %s dropped - key inactive\n", sigstr); } else if (issigningkey(key)) { wassignedby[key->index] = ISC_TRUE; if (!expired && rrsig.originalttl == set->ttl && setverifies(name, set, key->key, &sigrdata)) { vbprintf(2, "\trrsig by %s retained\n", sigstr); keep = ISC_TRUE; } else { vbprintf(2, "\trrsig by %s dropped - %s\n", sigstr, expired ? "expired" : rrsig.originalttl != set->ttl ? "ttl change" : "failed to verify"); resign = ISC_TRUE; } } else if (!ispublishedkey(key) && remove_orphansigs) { vbprintf(2, "\trrsig by %s dropped - dnskey removed\n", sigstr); } else if (iszonekey(key)) { wassignedby[key->index] = ISC_TRUE; if (!expired && rrsig.originalttl == set->ttl && setverifies(name, set, key->key, &sigrdata)) { vbprintf(2, "\trrsig by %s retained\n", sigstr); keep = ISC_TRUE; } else { vbprintf(2, "\trrsig by %s dropped - %s\n", sigstr, expired ? "expired" : rrsig.originalttl != set->ttl ? "ttl change" : "failed to verify"); } } else if (!expired) { vbprintf(2, "\trrsig by %s retained\n", sigstr); keep = ISC_TRUE; } else { vbprintf(2, "\trrsig by %s expired\n", sigstr); } if (keep) { if (key != NULL) nowsignedby[key->index] = ISC_TRUE; INCSTAT(nretained); if (sigset.ttl != ttl) { vbprintf(2, "\tfixing ttl %s\n", sigstr); tuple = NULL; result = dns_difftuple_create(mctx, DNS_DIFFOP_DELRESIGN, name, sigset.ttl, &sigrdata, &tuple); check_result(result, "dns_difftuple_create"); dns_diff_append(del, &tuple); result = dns_difftuple_create(mctx, DNS_DIFFOP_ADDRESIGN, name, ttl, &sigrdata, &tuple); check_result(result, "dns_difftuple_create"); dns_diff_append(add, &tuple); } } else { tuple = NULL; vbprintf(2, "removing signature by %s\n", sigstr); result = dns_difftuple_create(mctx, DNS_DIFFOP_DELRESIGN, name, sigset.ttl, &sigrdata, &tuple); check_result(result, "dns_difftuple_create"); dns_diff_append(del, &tuple); INCSTAT(ndropped); } if (resign) { INSIST(!keep); signwithkey(name, set, key->key, ttl, add, "resigning with dnskey"); nowsignedby[key->index] = ISC_TRUE; } dns_rdata_reset(&sigrdata); dns_rdata_freestruct(&rrsig); result = dns_rdataset_next(&sigset); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; check_result(result, "dns_rdataset_first/next"); if (dns_rdataset_isassociated(&sigset)) dns_rdataset_disassociate(&sigset); for (key = ISC_LIST_HEAD(keylist); key != NULL; key = ISC_LIST_NEXT(key, link)) { if (nowsignedby[key->index]) continue; if (!issigningkey(key)) continue; if (set->type == dns_rdatatype_dnskey && dns_name_equal(name, gorigin)) { isc_boolean_t have_ksk; dns_dnsseckey_t *tmpkey; have_ksk = isksk(key); for (tmpkey = ISC_LIST_HEAD(keylist); tmpkey != NULL; tmpkey = ISC_LIST_NEXT(tmpkey, link)) { if (dst_key_alg(key->key) != dst_key_alg(tmpkey->key)) continue; if (REVOKE(tmpkey->key)) continue; if (isksk(tmpkey)) have_ksk = ISC_TRUE; } if (isksk(key) || !have_ksk || (iszsk(key) && !keyset_kskonly)) signwithkey(name, set, key->key, ttl, add, "signing with dnskey"); } else if (set->type == dns_rdatatype_cds || set->type == dns_rdatatype_cdnskey || iszsk(key)) { signwithkey(name, set, key->key, ttl, add, "signing with dnskey"); } } isc_mem_put(mctx, wassignedby, arraysize * sizeof(isc_boolean_t)); isc_mem_put(mctx, nowsignedby, arraysize * sizeof(isc_boolean_t)); } struct hashlist { unsigned char *hashbuf; size_t entries; size_t size; size_t length; }; static void hashlist_init(hashlist_t *l, unsigned int nodes, unsigned int length) { l->entries = 0; l->length = length + 1; if (nodes != 0) { l->size = nodes; l->hashbuf = malloc(l->size * l->length); if (l->hashbuf == NULL) l->size = 0; } else { l->size = 0; l->hashbuf = NULL; } } static void hashlist_add(hashlist_t *l, const unsigned char *hash, size_t len) { REQUIRE(len <= l->length); if (l->entries == l->size) { l->size = l->size * 2 + 100; l->hashbuf = realloc(l->hashbuf, l->size * l->length); if (l->hashbuf == NULL) fatal("unable to grow hashlist: out of memory"); } memset(l->hashbuf + l->entries * l->length, 0, l->length); memmove(l->hashbuf + l->entries * l->length, hash, len); l->entries++; } static void hashlist_add_dns_name(hashlist_t *l, /*const*/ dns_name_t *name, unsigned int hashalg, unsigned int iterations, const unsigned char *salt, size_t salt_len, isc_boolean_t speculative) { char nametext[DNS_NAME_FORMATSIZE]; unsigned char hash[NSEC3_MAX_HASH_LENGTH + 1]; unsigned int len; size_t i; len = isc_iterated_hash(hash, hashalg, iterations, salt, (int)salt_len, name->ndata, name->length); if (verbose) { dns_name_format(name, nametext, sizeof nametext); for (i = 0 ; i < len; i++) fprintf(stderr, "%02x", hash[i]); fprintf(stderr, " %s\n", nametext); } hash[len++] = speculative ? 1 : 0; hashlist_add(l, hash, len); } static int hashlist_comp(const void *a, const void *b) { return (isc_safe_memcompare(a, b, hash_length + 1)); } static void hashlist_sort(hashlist_t *l) { qsort(l->hashbuf, l->entries, l->length, hashlist_comp); } static isc_boolean_t hashlist_hasdup(hashlist_t *l) { unsigned char *current; unsigned char *next = l->hashbuf; size_t entries = l->entries; /* * Skip initial speculative wild card hashs. */ while (entries > 0U && next[l->length-1] != 0U) { next += l->length; entries--; } current = next; while (entries-- > 1U) { next += l->length; if (next[l->length-1] != 0) continue; if (isc_safe_memequal(current, next, l->length - 1)) return (ISC_TRUE); current = next; } return (ISC_FALSE); } static const unsigned char * hashlist_findnext(const hashlist_t *l, const unsigned char hash[NSEC3_MAX_HASH_LENGTH]) { size_t entries = l->entries; const unsigned char *next = bsearch(hash, l->hashbuf, l->entries, l->length, hashlist_comp); INSIST(next != NULL); do { if (next < l->hashbuf + (l->entries - 1) * l->length) next += l->length; else next = l->hashbuf; if (next[l->length - 1] == 0) break; } while (entries-- > 1U); INSIST(entries != 0U); return (next); } static isc_boolean_t hashlist_exists(const hashlist_t *l, const unsigned char hash[NSEC3_MAX_HASH_LENGTH]) { if (bsearch(hash, l->hashbuf, l->entries, l->length, hashlist_comp)) return (ISC_TRUE); else return (ISC_FALSE); } static void addnowildcardhash(hashlist_t *l, /*const*/ dns_name_t *name, unsigned int hashalg, unsigned int iterations, const unsigned char *salt, size_t salt_len) { dns_fixedname_t fixed; dns_name_t *wild; dns_dbnode_t *node = NULL; isc_result_t result; char namestr[DNS_NAME_FORMATSIZE]; dns_fixedname_init(&fixed); wild = dns_fixedname_name(&fixed); result = dns_name_concatenate(dns_wildcardname, name, wild, NULL); if (result == ISC_R_NOSPACE) return; check_result(result,"addnowildcardhash: dns_name_concatenate()"); result = dns_db_findnode(gdb, wild, ISC_FALSE, &node); if (result == ISC_R_SUCCESS) { dns_db_detachnode(gdb, &node); return; } if (verbose) { dns_name_format(wild, namestr, sizeof(namestr)); fprintf(stderr, "adding no-wildcardhash for %s\n", namestr); } hashlist_add_dns_name(l, wild, hashalg, iterations, salt, salt_len, ISC_TRUE); } static void opendb(const char *prefix, dns_name_t *name, dns_rdataclass_t rdclass, dns_db_t **dbp) { char filename[PATH_MAX]; isc_buffer_t b; isc_result_t result; isc_buffer_init(&b, filename, sizeof(filename)); if (dsdir != NULL) { /* allow room for a trailing slash */ if (strlen(dsdir) >= isc_buffer_availablelength(&b)) fatal("path '%s' is too long", dsdir); isc_buffer_putstr(&b, dsdir); if (dsdir[strlen(dsdir) - 1] != '/') isc_buffer_putstr(&b, "/"); } if (strlen(prefix) > isc_buffer_availablelength(&b)) fatal("path '%s' is too long", dsdir); isc_buffer_putstr(&b, prefix); result = dns_name_tofilenametext(name, ISC_FALSE, &b); check_result(result, "dns_name_tofilenametext()"); if (isc_buffer_availablelength(&b) == 0) { char namestr[DNS_NAME_FORMATSIZE]; dns_name_format(name, namestr, sizeof(namestr)); fatal("name '%s' is too long", namestr); } isc_buffer_putuint8(&b, 0); result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, rdclass, 0, NULL, dbp); check_result(result, "dns_db_create()"); result = dns_db_load3(*dbp, filename, inputformat, DNS_MASTER_HINT); if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) dns_db_detach(dbp); } /*% * Load the DS set for a child zone, if a dsset-* file can be found. * If not, try to find a keyset-* file from an earlier version of * dnssec-signzone, and build DS records from that. */ static isc_result_t loadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) { dns_db_t *db = NULL; dns_dbversion_t *ver = NULL; dns_dbnode_t *node = NULL; isc_result_t result; dns_rdataset_t keyset; dns_rdata_t key, ds; unsigned char dsbuf[DNS_DS_BUFFERSIZE]; dns_diff_t diff; dns_difftuple_t *tuple = NULL; opendb("dsset-", name, gclass, &db); if (db != NULL) { result = dns_db_findnode(db, name, ISC_FALSE, &node); if (result == ISC_R_SUCCESS) { dns_rdataset_init(dsset); result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ds, 0, 0, dsset, NULL); dns_db_detachnode(db, &node); if (result == ISC_R_SUCCESS) { vbprintf(2, "found DS records\n"); dsset->ttl = ttl; dns_db_detach(&db); return (result); } } dns_db_detach(&db); } /* No DS records found; try again, looking for DNSKEY records */ opendb("keyset-", name, gclass, &db); if (db == NULL) { return (ISC_R_NOTFOUND); } result = dns_db_findnode(db, name, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) { dns_db_detach(&db); return (result); } dns_rdataset_init(&keyset); result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0, 0, &keyset, NULL); if (result != ISC_R_SUCCESS) { dns_db_detachnode(db, &node); dns_db_detach(&db); return (result); } vbprintf(2, "found DNSKEY records\n"); result = dns_db_newversion(db, &ver); check_result(result, "dns_db_newversion"); dns_diff_init(mctx, &diff); for (result = dns_rdataset_first(&keyset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&keyset)) { dns_rdata_init(&key); dns_rdata_init(&ds); dns_rdataset_current(&keyset, &key); result = dns_ds_buildrdata(name, &key, DNS_DSDIGEST_SHA1, dsbuf, &ds); check_result(result, "dns_ds_buildrdata"); result = dns_difftuple_create(mctx, DNS_DIFFOP_ADDRESIGN, name, ttl, &ds, &tuple); check_result(result, "dns_difftuple_create"); dns_diff_append(&diff, &tuple); dns_rdata_reset(&ds); result = dns_ds_buildrdata(name, &key, DNS_DSDIGEST_SHA256, dsbuf, &ds); check_result(result, "dns_ds_buildrdata"); result = dns_difftuple_create(mctx, DNS_DIFFOP_ADDRESIGN, name, ttl, &ds, &tuple); check_result(result, "dns_difftuple_create"); dns_diff_append(&diff, &tuple); } result = dns_diff_apply(&diff, db, ver); check_result(result, "dns_diff_apply"); dns_diff_clear(&diff); dns_db_closeversion(db, &ver, ISC_TRUE); result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ds, 0, 0, dsset, NULL); check_result(result, "dns_db_findrdataset"); dns_rdataset_disassociate(&keyset); dns_db_detachnode(db, &node); dns_db_detach(&db); return (result); } static isc_boolean_t secure(dns_name_t *name, dns_dbnode_t *node) { dns_rdataset_t dsset; isc_result_t result; if (dns_name_equal(name, gorigin)) return (ISC_FALSE); dns_rdataset_init(&dsset); result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_ds, 0, 0, &dsset, NULL); if (dns_rdataset_isassociated(&dsset)) dns_rdataset_disassociate(&dsset); return (ISC_TF(result == ISC_R_SUCCESS)); } /*% * Signs all records at a name. */ static void signname(dns_dbnode_t *node, dns_name_t *name) { isc_result_t result; dns_rdataset_t rdataset; dns_rdatasetiter_t *rdsiter; isc_boolean_t isdelegation = ISC_FALSE; dns_diff_t del, add; char namestr[DNS_NAME_FORMATSIZE]; dns_rdataset_init(&rdataset); dns_name_format(name, namestr, sizeof(namestr)); /* * Determine if this is a delegation point. */ if (is_delegation(gdb, gversion, gorigin, name, node, NULL)) isdelegation = ISC_TRUE; /* * Now iterate through the rdatasets. */ dns_diff_init(mctx, &del); dns_diff_init(mctx, &add); rdsiter = NULL; result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); check_result(result, "dns_db_allrdatasets()"); result = dns_rdatasetiter_first(rdsiter); while (result == ISC_R_SUCCESS) { dns_rdatasetiter_current(rdsiter, &rdataset); /* If this is a RRSIG set, skip it. */ if (rdataset.type == dns_rdatatype_rrsig) goto skip; /* * If this name is a delegation point, skip all records * except NSEC and DS sets. Otherwise check that there * isn't a DS record. */ if (isdelegation) { if (rdataset.type != nsec_datatype && rdataset.type != dns_rdatatype_ds) goto skip; } else if (rdataset.type == dns_rdatatype_ds) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(name, namebuf, sizeof(namebuf)); fatal("'%s': found DS RRset without NS RRset\n", namebuf); } signset(&del, &add, node, name, &rdataset); skip: dns_rdataset_disassociate(&rdataset); result = dns_rdatasetiter_next(rdsiter); } if (result != ISC_R_NOMORE) fatal("rdataset iteration for name '%s' failed: %s", namestr, isc_result_totext(result)); dns_rdatasetiter_destroy(&rdsiter); result = dns_diff_applysilently(&del, gdb, gversion); if (result != ISC_R_SUCCESS) fatal("failed to delete SIGs at node '%s': %s", namestr, isc_result_totext(result)); result = dns_diff_applysilently(&add, gdb, gversion); if (result != ISC_R_SUCCESS) fatal("failed to add SIGs at node '%s': %s", namestr, isc_result_totext(result)); dns_diff_clear(&del); dns_diff_clear(&add); } static inline isc_boolean_t active_node(dns_dbnode_t *node) { dns_rdatasetiter_t *rdsiter = NULL; dns_rdatasetiter_t *rdsiter2 = NULL; isc_boolean_t active = ISC_FALSE; isc_result_t result; dns_rdataset_t rdataset; dns_rdatatype_t type; dns_rdatatype_t covers; isc_boolean_t found; dns_rdataset_init(&rdataset); result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); check_result(result, "dns_db_allrdatasets()"); result = dns_rdatasetiter_first(rdsiter); while (result == ISC_R_SUCCESS) { dns_rdatasetiter_current(rdsiter, &rdataset); if (rdataset.type != dns_rdatatype_nsec && rdataset.type != dns_rdatatype_nsec3 && rdataset.type != dns_rdatatype_rrsig) active = ISC_TRUE; dns_rdataset_disassociate(&rdataset); if (!active) result = dns_rdatasetiter_next(rdsiter); else result = ISC_R_NOMORE; } if (result != ISC_R_NOMORE) fatal("rdataset iteration failed: %s", isc_result_totext(result)); if (!active && nsec_datatype == dns_rdatatype_nsec) { /*% * The node is empty of everything but NSEC / RRSIG records. */ for (result = dns_rdatasetiter_first(rdsiter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsiter)) { dns_rdatasetiter_current(rdsiter, &rdataset); result = dns_db_deleterdataset(gdb, node, gversion, rdataset.type, rdataset.covers); check_result(result, "dns_db_deleterdataset()"); dns_rdataset_disassociate(&rdataset); } if (result != ISC_R_NOMORE) fatal("rdataset iteration failed: %s", isc_result_totext(result)); } else { /* * Delete RRSIGs for types that no longer exist. */ result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter2); check_result(result, "dns_db_allrdatasets()"); for (result = dns_rdatasetiter_first(rdsiter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsiter)) { dns_rdatasetiter_current(rdsiter, &rdataset); type = rdataset.type; covers = rdataset.covers; dns_rdataset_disassociate(&rdataset); /* * Delete the NSEC chain if we are signing with * NSEC3. */ if (nsec_datatype == dns_rdatatype_nsec3 && (type == dns_rdatatype_nsec || covers == dns_rdatatype_nsec)) { result = dns_db_deleterdataset(gdb, node, gversion, type, covers); check_result(result, "dns_db_deleterdataset(nsec/rrsig)"); continue; } if (type != dns_rdatatype_rrsig) continue; found = ISC_FALSE; for (result = dns_rdatasetiter_first(rdsiter2); !found && result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsiter2)) { dns_rdatasetiter_current(rdsiter2, &rdataset); if (rdataset.type == covers) found = ISC_TRUE; dns_rdataset_disassociate(&rdataset); } if (!found) { if (result != ISC_R_NOMORE) fatal("rdataset iteration failed: %s", isc_result_totext(result)); result = dns_db_deleterdataset(gdb, node, gversion, type, covers); check_result(result, "dns_db_deleterdataset(rrsig)"); } else if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS) fatal("rdataset iteration failed: %s", isc_result_totext(result)); } if (result != ISC_R_NOMORE) fatal("rdataset iteration failed: %s", isc_result_totext(result)); dns_rdatasetiter_destroy(&rdsiter2); } dns_rdatasetiter_destroy(&rdsiter); return (active); } /*% * Extracts the minimum TTL from the SOA record, and the SOA record's TTL. */ static void get_soa_ttls(void) { dns_rdataset_t soaset; dns_fixedname_t fname; dns_name_t *name; isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_rdataset_init(&soaset); result = dns_db_find(gdb, gorigin, gversion, dns_rdatatype_soa, 0, 0, NULL, name, &soaset, NULL); if (result != ISC_R_SUCCESS) fatal("failed to find an SOA at the zone apex: %s", isc_result_totext(result)); result = dns_rdataset_first(&soaset); check_result(result, "dns_rdataset_first"); dns_rdataset_current(&soaset, &rdata); zone_soa_min_ttl = dns_soa_getminimum(&rdata); soa_ttl = soaset.ttl; if (set_maxttl) { zone_soa_min_ttl = ISC_MIN(zone_soa_min_ttl, maxttl); soa_ttl = ISC_MIN(soa_ttl, maxttl); } dns_rdataset_disassociate(&soaset); } /*% * Increment (or set if nonzero) the SOA serial */ static isc_result_t setsoaserial(isc_uint32_t serial) { isc_result_t result; dns_dbnode_t *node = NULL; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; isc_uint32_t old_serial, new_serial; result = dns_db_getoriginnode(gdb, &node); if (result != ISC_R_SUCCESS) return result; dns_rdataset_init(&rdataset); result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_soa, 0, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_rdataset_first(&rdataset); RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_rdataset_current(&rdataset, &rdata); old_serial = dns_soa_getserial(&rdata); if (serial) { /* Set SOA serial to the value provided. */ new_serial = serial; } else { /* Increment SOA serial using RFC 1982 arithmetics */ new_serial = (old_serial + 1) & 0xFFFFFFFF; if (new_serial == 0) new_serial = 1; } /* If the new serial is not likely to cause a zone transfer * (a/ixfr) from servers having the old serial, warn the user. * * RFC1982 section 7 defines the maximum increment to be * (2^(32-1))-1. Using u_int32_t arithmetic, we can do a single * comparison. (5 - 6 == (2^32)-1, not negative-one) */ if (new_serial == old_serial || (new_serial - old_serial) > 0x7fffffffU) fprintf(stderr, "%s: warning: Serial number not advanced, " "zone may not transfer\n", program); dns_soa_setserial(new_serial, &rdata); result = dns_db_deleterdataset(gdb, node, gversion, dns_rdatatype_soa, 0); check_result(result, "dns_db_deleterdataset"); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_db_addrdataset(gdb, node, gversion, 0, &rdataset, 0, NULL); check_result(result, "dns_db_addrdataset"); if (result != ISC_R_SUCCESS) goto cleanup; cleanup: dns_rdataset_disassociate(&rdataset); if (node != NULL) dns_db_detachnode(gdb, &node); dns_rdata_reset(&rdata); return (result); } /*% * Delete any RRSIG records at a node. */ static void cleannode(dns_db_t *db, dns_dbversion_t *dbversion, dns_dbnode_t *node) { dns_rdatasetiter_t *rdsiter = NULL; dns_rdataset_t set; isc_result_t result, dresult; if (outputformat != dns_masterformat_text || !disable_zone_check) return; dns_rdataset_init(&set); result = dns_db_allrdatasets(db, node, dbversion, 0, &rdsiter); check_result(result, "dns_db_allrdatasets"); result = dns_rdatasetiter_first(rdsiter); while (result == ISC_R_SUCCESS) { isc_boolean_t destroy = ISC_FALSE; dns_rdatatype_t covers = 0; dns_rdatasetiter_current(rdsiter, &set); if (set.type == dns_rdatatype_rrsig) { covers = set.covers; destroy = ISC_TRUE; } dns_rdataset_disassociate(&set); result = dns_rdatasetiter_next(rdsiter); if (destroy) { dresult = dns_db_deleterdataset(db, node, dbversion, dns_rdatatype_rrsig, covers); check_result(dresult, "dns_db_deleterdataset"); } } if (result != ISC_R_NOMORE) fatal("rdataset iteration failed: %s", isc_result_totext(result)); dns_rdatasetiter_destroy(&rdsiter); } /*% * Set up the iterator and global state before starting the tasks. */ static void presign(void) { isc_result_t result; gdbiter = NULL; result = dns_db_createiterator(gdb, 0, &gdbiter); check_result(result, "dns_db_createiterator()"); } /*% * Clean up the iterator and global state after the tasks complete. */ static void postsign(void) { dns_dbiterator_destroy(&gdbiter); } /*% * Sign the apex of the zone. * Note the origin may not be the first node if there are out of zone * records. */ static void signapex(void) { dns_dbnode_t *node = NULL; dns_fixedname_t fixed; dns_name_t *name; isc_result_t result; dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); result = dns_dbiterator_seek(gdbiter, gorigin); check_result(result, "dns_dbiterator_seek()"); result = dns_dbiterator_current(gdbiter, &node, name); check_dns_dbiterator_current(result); signname(node, name); dumpnode(name, node); cleannode(gdb, gversion, node); dns_db_detachnode(gdb, &node); result = dns_dbiterator_first(gdbiter); if (result == ISC_R_NOMORE) finished = ISC_TRUE; else if (result != ISC_R_SUCCESS) fatal("failure iterating database: %s", isc_result_totext(result)); } /*% * Assigns a node to a worker thread. This is protected by the master task's * lock. */ static void assignwork(isc_task_t *task, isc_task_t *worker) { dns_fixedname_t *fname; dns_name_t *name; dns_dbnode_t *node; sevent_t *sevent; dns_rdataset_t nsec; isc_boolean_t found; isc_result_t result; static dns_name_t *zonecut = NULL; /* Protected by namelock. */ static dns_fixedname_t fzonecut; /* Protected by namelock. */ static unsigned int ended = 0; /* Protected by namelock. */ if (shuttingdown) return; LOCK(&namelock); if (finished) { ended++; if (ended == ntasks) { isc_task_detach(&task); isc_app_shutdown(); } goto unlock; } fname = isc_mem_get(mctx, sizeof(dns_fixedname_t)); if (fname == NULL) fatal("out of memory"); dns_fixedname_init(fname); name = dns_fixedname_name(fname); node = NULL; found = ISC_FALSE; while (!found) { result = dns_dbiterator_current(gdbiter, &node, name); check_dns_dbiterator_current(result); /* * The origin was handled by signapex(). */ if (dns_name_equal(name, gorigin)) { dns_db_detachnode(gdb, &node); goto next; } /* * Sort the zone data from the glue and out-of-zone data. * For NSEC zones nodes with zone data have NSEC records. * For NSEC3 zones the NSEC3 nodes are zone data but * outside of the zone name space. For the rest we need * to track the bottom of zone cuts. * Nodes which don't need to be signed are dumped here. */ dns_rdataset_init(&nsec); result = dns_db_findrdataset(gdb, node, gversion, nsec_datatype, 0, 0, &nsec, NULL); if (dns_rdataset_isassociated(&nsec)) dns_rdataset_disassociate(&nsec); if (result == ISC_R_SUCCESS) { found = ISC_TRUE; } else if (nsec_datatype == dns_rdatatype_nsec3) { if (dns_name_issubdomain(name, gorigin) && (zonecut == NULL || !dns_name_issubdomain(name, zonecut))) { if (is_delegation(gdb, gversion, gorigin, name, node, NULL)) { dns_fixedname_init(&fzonecut); zonecut = dns_fixedname_name(&fzonecut); dns_name_copy(name, zonecut, NULL); if (!OPTOUT(nsec3flags) || secure(name, node)) found = ISC_TRUE; } else found = ISC_TRUE; } } if (!found) { dumpnode(name, node); dns_db_detachnode(gdb, &node); } next: result = dns_dbiterator_next(gdbiter); if (result == ISC_R_NOMORE) { finished = ISC_TRUE; break; } else if (result != ISC_R_SUCCESS) fatal("failure iterating database: %s", isc_result_totext(result)); } if (!found) { ended++; if (ended == ntasks) { isc_task_detach(&task); isc_app_shutdown(); } isc_mem_put(mctx, fname, sizeof(dns_fixedname_t)); goto unlock; } sevent = (sevent_t *) isc_event_allocate(mctx, task, SIGNER_EVENT_WORK, sign, NULL, sizeof(sevent_t)); if (sevent == NULL) fatal("failed to allocate event\n"); sevent->node = node; sevent->fname = fname; isc_task_send(worker, ISC_EVENT_PTR(&sevent)); unlock: UNLOCK(&namelock); } /*% * Start a worker task */ static void startworker(isc_task_t *task, isc_event_t *event) { isc_task_t *worker; worker = (isc_task_t *)event->ev_arg; assignwork(task, worker); isc_event_free(&event); } /*% * Write a node to the output file, and restart the worker task. */ static void writenode(isc_task_t *task, isc_event_t *event) { isc_task_t *worker; sevent_t *sevent = (sevent_t *)event; worker = (isc_task_t *)event->ev_sender; dumpnode(dns_fixedname_name(sevent->fname), sevent->node); cleannode(gdb, gversion, sevent->node); dns_db_detachnode(gdb, &sevent->node); isc_mem_put(mctx, sevent->fname, sizeof(dns_fixedname_t)); assignwork(task, worker); isc_event_free(&event); } /*% * Sign a database node. */ static void sign(isc_task_t *task, isc_event_t *event) { dns_fixedname_t *fname; dns_dbnode_t *node; sevent_t *sevent, *wevent; sevent = (sevent_t *)event; node = sevent->node; fname = sevent->fname; isc_event_free(&event); signname(node, dns_fixedname_name(fname)); wevent = (sevent_t *) isc_event_allocate(mctx, task, SIGNER_EVENT_WRITE, writenode, NULL, sizeof(sevent_t)); if (wevent == NULL) fatal("failed to allocate event\n"); wevent->node = node; wevent->fname = fname; isc_task_send(master, ISC_EVENT_PTR(&wevent)); } /*% * Update / remove the DS RRset. Preserve RRSIG(DS) if possible. */ static void add_ds(dns_name_t *name, dns_dbnode_t *node, isc_uint32_t nsttl) { dns_rdataset_t dsset; dns_rdataset_t sigdsset; isc_result_t result; dns_rdataset_init(&dsset); dns_rdataset_init(&sigdsset); result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_ds, 0, 0, &dsset, &sigdsset); if (result == ISC_R_SUCCESS) { dns_rdataset_disassociate(&dsset); result = dns_db_deleterdataset(gdb, node, gversion, dns_rdatatype_ds, 0); check_result(result, "dns_db_deleterdataset"); } result = loadds(name, nsttl, &dsset); if (result == ISC_R_SUCCESS) { result = dns_db_addrdataset(gdb, node, gversion, 0, &dsset, 0, NULL); check_result(result, "dns_db_addrdataset"); dns_rdataset_disassociate(&dsset); if (dns_rdataset_isassociated(&sigdsset)) dns_rdataset_disassociate(&sigdsset); } else if (dns_rdataset_isassociated(&sigdsset)) { result = dns_db_deleterdataset(gdb, node, gversion, dns_rdatatype_rrsig, dns_rdatatype_ds); check_result(result, "dns_db_deleterdataset"); dns_rdataset_disassociate(&sigdsset); } } /* * Remove records of the given type and their signatures. */ static void remove_records(dns_dbnode_t *node, dns_rdatatype_t which, isc_boolean_t checknsec) { isc_result_t result; dns_rdatatype_t type, covers; dns_rdatasetiter_t *rdsiter = NULL; dns_rdataset_t rdataset; dns_rdataset_init(&rdataset); /* * Delete any records of the given type at the apex. */ result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); check_result(result, "dns_db_allrdatasets()"); for (result = dns_rdatasetiter_first(rdsiter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsiter)) { dns_rdatasetiter_current(rdsiter, &rdataset); type = rdataset.type; covers = rdataset.covers; dns_rdataset_disassociate(&rdataset); if (type == which || covers == which) { if (which == dns_rdatatype_nsec && checknsec && !update_chain) fatal("Zone contains NSEC records. Use -u " "to update to NSEC3."); if (which == dns_rdatatype_nsec3param && checknsec && !update_chain) fatal("Zone contains NSEC3 chains. Use -u " "to update to NSEC."); result = dns_db_deleterdataset(gdb, node, gversion, type, covers); check_result(result, "dns_db_deleterdataset()"); continue; } } dns_rdatasetiter_destroy(&rdsiter); } /* * Remove signatures covering the given type. If type == 0, * then remove all signatures, unless this is a delegation, in * which case remove all signatures except for DS or nsec_datatype */ static void remove_sigs(dns_dbnode_t *node, isc_boolean_t delegation, dns_rdatatype_t which) { isc_result_t result; dns_rdatatype_t type, covers; dns_rdatasetiter_t *rdsiter = NULL; dns_rdataset_t rdataset; dns_rdataset_init(&rdataset); result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); check_result(result, "dns_db_allrdatasets()"); for (result = dns_rdatasetiter_first(rdsiter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsiter)) { dns_rdatasetiter_current(rdsiter, &rdataset); type = rdataset.type; covers = rdataset.covers; dns_rdataset_disassociate(&rdataset); if (type != dns_rdatatype_rrsig) continue; if (which == 0 && delegation && (dns_rdatatype_atparent(covers) || (nsec_datatype == dns_rdatatype_nsec && covers == nsec_datatype))) continue; if (which != 0 && covers != which) continue; result = dns_db_deleterdataset(gdb, node, gversion, type, covers); check_result(result, "dns_db_deleterdataset()"); } dns_rdatasetiter_destroy(&rdsiter); } /*% * Generate NSEC records for the zone and remove NSEC3/NSEC3PARAM records. */ static void nsecify(void) { dns_dbiterator_t *dbiter = NULL; dns_dbnode_t *node = NULL, *nextnode = NULL; dns_fixedname_t fname, fnextname, fzonecut; dns_name_t *name, *nextname, *zonecut; dns_rdataset_t rdataset; dns_rdatasetiter_t *rdsiter = NULL; dns_rdatatype_t type, covers; isc_boolean_t done = ISC_FALSE; isc_result_t result; isc_uint32_t nsttl = 0; dns_rdataset_init(&rdataset); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_fixedname_init(&fnextname); nextname = dns_fixedname_name(&fnextname); dns_fixedname_init(&fzonecut); zonecut = NULL; /* * Remove any NSEC3 chains. */ result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter); check_result(result, "dns_db_createiterator()"); for (result = dns_dbiterator_first(dbiter); result == ISC_R_SUCCESS; result = dns_dbiterator_next(dbiter)) { result = dns_dbiterator_current(dbiter, &node, name); check_dns_dbiterator_current(result); result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); check_result(result, "dns_db_allrdatasets()"); for (result = dns_rdatasetiter_first(rdsiter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsiter)) { dns_rdatasetiter_current(rdsiter, &rdataset); type = rdataset.type; covers = rdataset.covers; dns_rdataset_disassociate(&rdataset); result = dns_db_deleterdataset(gdb, node, gversion, type, covers); check_result(result, "dns_db_deleterdataset(nsec3param/rrsig)"); } dns_rdatasetiter_destroy(&rdsiter); dns_db_detachnode(gdb, &node); } dns_dbiterator_destroy(&dbiter); result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter); check_result(result, "dns_db_createiterator()"); result = dns_dbiterator_first(dbiter); check_result(result, "dns_dbiterator_first()"); while (!done) { result = dns_dbiterator_current(dbiter, &node, name); check_dns_dbiterator_current(result); /* * Skip out-of-zone records. */ if (!dns_name_issubdomain(name, gorigin)) { result = dns_dbiterator_next(dbiter); if (result == ISC_R_NOMORE) done = ISC_TRUE; else check_result(result, "dns_dbiterator_next()"); dns_db_detachnode(gdb, &node); continue; } if (dns_name_equal(name, gorigin)) remove_records(node, dns_rdatatype_nsec3param, ISC_TRUE); if (is_delegation(gdb, gversion, gorigin, name, node, &nsttl)) { zonecut = dns_fixedname_name(&fzonecut); dns_name_copy(name, zonecut, NULL); remove_sigs(node, ISC_TRUE, 0); if (generateds) add_ds(name, node, nsttl); } result = dns_dbiterator_next(dbiter); nextnode = NULL; while (result == ISC_R_SUCCESS) { isc_boolean_t active = ISC_FALSE; result = dns_dbiterator_current(dbiter, &nextnode, nextname); check_dns_dbiterator_current(result); active = active_node(nextnode); if (!active) { dns_db_detachnode(gdb, &nextnode); result = dns_dbiterator_next(dbiter); continue; } if (!dns_name_issubdomain(nextname, gorigin) || (zonecut != NULL && dns_name_issubdomain(nextname, zonecut))) { remove_sigs(nextnode, ISC_FALSE, 0); remove_records(nextnode, dns_rdatatype_nsec, ISC_FALSE); dns_db_detachnode(gdb, &nextnode); result = dns_dbiterator_next(dbiter); continue; } dns_db_detachnode(gdb, &nextnode); break; } if (result == ISC_R_NOMORE) { dns_name_clone(gorigin, nextname); done = ISC_TRUE; } else if (result != ISC_R_SUCCESS) fatal("iterating through the database failed: %s", isc_result_totext(result)); dns_dbiterator_pause(dbiter); result = dns_nsec_build(gdb, gversion, node, nextname, zone_soa_min_ttl); check_result(result, "dns_nsec_build()"); dns_db_detachnode(gdb, &node); } dns_dbiterator_destroy(&dbiter); } static void addnsec3param(const unsigned char *salt, size_t salt_len, dns_iterations_t iterations) { dns_dbnode_t *node = NULL; dns_rdata_nsec3param_t nsec3param; unsigned char nsec3parambuf[5 + 255]; dns_rdatalist_t rdatalist; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; isc_buffer_t b; isc_result_t result; dns_rdataset_init(&rdataset); nsec3param.common.rdclass = gclass; nsec3param.common.rdtype = dns_rdatatype_nsec3param; ISC_LINK_INIT(&nsec3param.common, link); nsec3param.mctx = NULL; nsec3param.flags = 0; nsec3param.hash = unknownalg ? DNS_NSEC3_UNKNOWNALG : dns_hash_sha1; nsec3param.iterations = iterations; nsec3param.salt_length = (unsigned char)salt_len; DE_CONST(salt, nsec3param.salt); isc_buffer_init(&b, nsec3parambuf, sizeof(nsec3parambuf)); result = dns_rdata_fromstruct(&rdata, gclass, dns_rdatatype_nsec3param, &nsec3param, &b); check_result(result, "dns_rdata_fromstruct()"); dns_rdatalist_init(&rdatalist); rdatalist.rdclass = rdata.rdclass; rdatalist.type = rdata.type; ISC_LIST_APPEND(rdatalist.rdata, &rdata, link); result = dns_rdatalist_tordataset(&rdatalist, &rdataset); check_result(result, "dns_rdatalist_tordataset()"); result = dns_db_findnode(gdb, gorigin, ISC_TRUE, &node); check_result(result, "dns_db_find(gorigin)"); /* * Delete any current NSEC3PARAM records. */ result = dns_db_deleterdataset(gdb, node, gversion, dns_rdatatype_nsec3param, 0); if (result == DNS_R_UNCHANGED) result = ISC_R_SUCCESS; check_result(result, "dddnsec3param: dns_db_deleterdataset()"); result = dns_db_addrdataset(gdb, node, gversion, 0, &rdataset, DNS_DBADD_MERGE, NULL); if (result == DNS_R_UNCHANGED) result = ISC_R_SUCCESS; check_result(result, "addnsec3param: dns_db_addrdataset()"); dns_db_detachnode(gdb, &node); } static void addnsec3(dns_name_t *name, dns_dbnode_t *node, const unsigned char *salt, size_t salt_len, unsigned int iterations, hashlist_t *hashlist, dns_ttl_t ttl) { unsigned char hash[NSEC3_MAX_HASH_LENGTH]; const unsigned char *nexthash; unsigned char nsec3buffer[DNS_NSEC3_BUFFERSIZE]; dns_fixedname_t hashname; dns_rdatalist_t rdatalist; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; dns_dbnode_t *nsec3node = NULL; char namebuf[DNS_NAME_FORMATSIZE]; size_t hash_len; dns_name_format(name, namebuf, sizeof(namebuf)); dns_fixedname_init(&hashname); dns_rdataset_init(&rdataset); dns_name_downcase(name, name, NULL); result = dns_nsec3_hashname(&hashname, hash, &hash_len, name, gorigin, dns_hash_sha1, iterations, salt, salt_len); check_result(result, "addnsec3: dns_nsec3_hashname()"); nexthash = hashlist_findnext(hashlist, hash); result = dns_nsec3_buildrdata(gdb, gversion, node, unknownalg ? DNS_NSEC3_UNKNOWNALG : dns_hash_sha1, nsec3flags, iterations, salt, salt_len, nexthash, ISC_SHA1_DIGESTLENGTH, nsec3buffer, &rdata); check_result(result, "addnsec3: dns_nsec3_buildrdata()"); dns_rdatalist_init(&rdatalist); rdatalist.rdclass = rdata.rdclass; rdatalist.type = rdata.type; rdatalist.ttl = ttl; ISC_LIST_APPEND(rdatalist.rdata, &rdata, link); result = dns_rdatalist_tordataset(&rdatalist, &rdataset); check_result(result, "dns_rdatalist_tordataset()"); result = dns_db_findnsec3node(gdb, dns_fixedname_name(&hashname), ISC_TRUE, &nsec3node); check_result(result, "addnsec3: dns_db_findnode()"); result = dns_db_addrdataset(gdb, nsec3node, gversion, 0, &rdataset, 0, NULL); if (result == DNS_R_UNCHANGED) result = ISC_R_SUCCESS; check_result(result, "addnsec3: dns_db_addrdataset()"); dns_db_detachnode(gdb, &nsec3node); } /*% * Clean out NSEC3 record and RRSIG(NSEC3) that are not in the hash list. * * Extract the hash from the first label of 'name' then see if it * is in hashlist. If 'name' is not in the hashlist then delete the * any NSEC3 records which have the same parameters as the chain we * are building. * * XXXMPA Should we also check that it of the form .? */ static void nsec3clean(dns_name_t *name, dns_dbnode_t *node, unsigned int hashalg, unsigned int iterations, const unsigned char *salt, size_t salt_len, hashlist_t *hashlist) { dns_label_t label; dns_rdata_nsec3_t nsec3; dns_rdata_t rdata, delrdata; dns_rdatalist_t rdatalist; dns_rdataset_t rdataset, delrdataset; isc_boolean_t delete_rrsigs = ISC_FALSE; isc_buffer_t target; isc_result_t result; unsigned char hash[NSEC3_MAX_HASH_LENGTH + 1]; isc_boolean_t exists; /* * Get the first label. */ dns_name_getlabel(name, 0, &label); /* * We want just the label contents. */ isc_region_consume(&label, 1); /* * Decode base32hex string. */ isc_buffer_init(&target, hash, sizeof(hash) - 1); result = isc_base32hex_decoderegion(&label, &target); if (result != ISC_R_SUCCESS) return; hash[isc_buffer_usedlength(&target)] = 0; exists = hashlist_exists(hashlist, hash); /* * Verify that the NSEC3 parameters match the current ones * otherwise we are dealing with a different NSEC3 chain. */ dns_rdataset_init(&rdataset); dns_rdataset_init(&delrdataset); result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_nsec3, 0, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) return; /* * Delete any NSEC3 records which are not part of the current * NSEC3 chain. */ for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_init(&rdata); dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &nsec3, NULL); check_result(result, "dns_rdata_tostruct"); if (exists && nsec3.hash == hashalg && nsec3.iterations == iterations && nsec3.salt_length == salt_len && isc_safe_memequal(nsec3.salt, salt, salt_len)) continue; dns_rdatalist_init(&rdatalist); rdatalist.rdclass = rdata.rdclass; rdatalist.type = rdata.type; if (set_maxttl) rdatalist.ttl = ISC_MIN(rdataset.ttl, maxttl); dns_rdata_init(&delrdata); dns_rdata_clone(&rdata, &delrdata); ISC_LIST_APPEND(rdatalist.rdata, &delrdata, link); result = dns_rdatalist_tordataset(&rdatalist, &delrdataset); check_result(result, "dns_rdatalist_tordataset()"); result = dns_db_subtractrdataset(gdb, node, gversion, &delrdataset, 0, NULL); dns_rdataset_disassociate(&delrdataset); if (result != ISC_R_SUCCESS && result != DNS_R_NXRRSET) check_result(result, "dns_db_subtractrdataset(NSEC3)"); delete_rrsigs = ISC_TRUE; } dns_rdataset_disassociate(&rdataset); if (result != ISC_R_NOMORE) check_result(result, "dns_rdataset_first/next"); if (!delete_rrsigs) return; /* * Delete the NSEC3 RRSIGs */ result = dns_db_deleterdataset(gdb, node, gversion, dns_rdatatype_rrsig, dns_rdatatype_nsec3); if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED) check_result(result, "dns_db_deleterdataset(RRSIG(NSEC3))"); } static void rrset_cleanup(dns_name_t *name, dns_rdataset_t *rdataset, dns_diff_t *add, dns_diff_t *del) { isc_result_t result; unsigned int count1 = 0; dns_rdataset_t tmprdataset; char namestr[DNS_NAME_FORMATSIZE]; char typestr[TYPE_FORMATSIZE]; dns_name_format(name, namestr, sizeof(namestr)); type_format(rdataset->type, typestr, sizeof(typestr)); dns_rdataset_init(&tmprdataset); for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdata_t rdata1 = DNS_RDATA_INIT; unsigned int count2 = 0; count1++; dns_rdataset_current(rdataset, &rdata1); dns_rdataset_clone(rdataset, &tmprdataset); for (result = dns_rdataset_first(&tmprdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&tmprdataset)) { dns_rdata_t rdata2 = DNS_RDATA_INIT; dns_difftuple_t *tuple = NULL; count2++; dns_rdataset_current(&tmprdataset, &rdata2); if (count1 < count2 && dns_rdata_casecompare(&rdata1, &rdata2) == 0) { vbprintf(2, "removing duplicate at %s/%s\n", namestr, typestr); result = dns_difftuple_create(mctx, DNS_DIFFOP_DELRESIGN, name, rdataset->ttl, &rdata2, &tuple); check_result(result, "dns_difftuple_create"); dns_diff_append(del, &tuple); } else if (set_maxttl && rdataset->ttl > maxttl) { vbprintf(2, "reducing ttl of %s/%s " "from %d to %d\n", namestr, typestr, rdataset->ttl, maxttl); result = dns_difftuple_create(mctx, DNS_DIFFOP_DELRESIGN, name, rdataset->ttl, &rdata2, &tuple); check_result(result, "dns_difftuple_create"); dns_diff_append(del, &tuple); tuple = NULL; result = dns_difftuple_create(mctx, DNS_DIFFOP_ADDRESIGN, name, maxttl, &rdata2, &tuple); check_result(result, "dns_difftuple_create"); dns_diff_append(add, &tuple); } } dns_rdataset_disassociate(&tmprdataset); } } static void cleanup_zone(void) { isc_result_t result; dns_dbiterator_t *dbiter = NULL; dns_rdatasetiter_t *rdsiter = NULL; dns_diff_t add, del; dns_dbnode_t *node = NULL; dns_rdataset_t rdataset; dns_fixedname_t fname; dns_name_t *name; dns_diff_init(mctx, &add); dns_diff_init(mctx, &del); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_rdataset_init(&rdataset); result = dns_db_createiterator(gdb, 0, &dbiter); check_result(result, "dns_db_createiterator()"); for (result = dns_dbiterator_first(dbiter); result == ISC_R_SUCCESS; result = dns_dbiterator_next(dbiter)) { result = dns_dbiterator_current(dbiter, &node, name); check_dns_dbiterator_current(result); result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); check_result(result, "dns_db_allrdatasets()"); for (result = dns_rdatasetiter_first(rdsiter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsiter)) { dns_rdatasetiter_current(rdsiter, &rdataset); rrset_cleanup(name, &rdataset, &add, &del); dns_rdataset_disassociate(&rdataset); } if (result != ISC_R_NOMORE) fatal("rdatasets iteration failed."); dns_rdatasetiter_destroy(&rdsiter); dns_db_detachnode(gdb, &node); } if (result != ISC_R_NOMORE) fatal("zone iteration failed."); result = dns_diff_applysilently(&del, gdb, gversion); check_result(result, "dns_diff_applysilently"); result = dns_diff_applysilently(&add, gdb, gversion); check_result(result, "dns_diff_applysilently"); dns_diff_clear(&del); dns_diff_clear(&add); dns_dbiterator_destroy(&dbiter); } /* * Generate NSEC3 records for the zone. */ static void nsec3ify(unsigned int hashalg, dns_iterations_t iterations, const unsigned char *salt, size_t salt_len, hashlist_t *hashlist) { dns_dbiterator_t *dbiter = NULL; dns_dbnode_t *node = NULL, *nextnode = NULL; dns_fixedname_t fname, fnextname, fzonecut; dns_name_t *name, *nextname, *zonecut; dns_rdataset_t rdataset; int order; isc_boolean_t active; isc_boolean_t done = ISC_FALSE; isc_result_t result; isc_uint32_t nsttl = 0; unsigned int count, nlabels; dns_rdataset_init(&rdataset); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_fixedname_init(&fnextname); nextname = dns_fixedname_name(&fnextname); dns_fixedname_init(&fzonecut); zonecut = NULL; /* * Walk the zone generating the hash names. */ result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter); check_result(result, "dns_db_createiterator()"); result = dns_dbiterator_first(dbiter); check_result(result, "dns_dbiterator_first()"); while (!done) { result = dns_dbiterator_current(dbiter, &node, name); check_dns_dbiterator_current(result); /* * Skip out-of-zone records. */ if (!dns_name_issubdomain(name, gorigin)) { result = dns_dbiterator_next(dbiter); if (result == ISC_R_NOMORE) done = ISC_TRUE; else check_result(result, "dns_dbiterator_next()"); dns_db_detachnode(gdb, &node); continue; } if (dns_name_equal(name, gorigin)) remove_records(node, dns_rdatatype_nsec, ISC_TRUE); result = dns_dbiterator_next(dbiter); nextnode = NULL; while (result == ISC_R_SUCCESS) { result = dns_dbiterator_current(dbiter, &nextnode, nextname); check_dns_dbiterator_current(result); active = active_node(nextnode); if (!active) { dns_db_detachnode(gdb, &nextnode); result = dns_dbiterator_next(dbiter); continue; } if (!dns_name_issubdomain(nextname, gorigin) || (zonecut != NULL && dns_name_issubdomain(nextname, zonecut))) { remove_sigs(nextnode, ISC_FALSE, 0); dns_db_detachnode(gdb, &nextnode); result = dns_dbiterator_next(dbiter); continue; } if (is_delegation(gdb, gversion, gorigin, nextname, nextnode, &nsttl)) { zonecut = dns_fixedname_name(&fzonecut); dns_name_copy(nextname, zonecut, NULL); remove_sigs(nextnode, ISC_TRUE, 0); if (generateds) add_ds(nextname, nextnode, nsttl); if (OPTOUT(nsec3flags) && !secure(nextname, nextnode)) { dns_db_detachnode(gdb, &nextnode); result = dns_dbiterator_next(dbiter); continue; } } dns_db_detachnode(gdb, &nextnode); break; } if (result == ISC_R_NOMORE) { dns_name_copy(gorigin, nextname, NULL); done = ISC_TRUE; } else if (result != ISC_R_SUCCESS) fatal("iterating through the database failed: %s", isc_result_totext(result)); dns_name_downcase(name, name, NULL); hashlist_add_dns_name(hashlist, name, hashalg, iterations, salt, salt_len, ISC_FALSE); dns_db_detachnode(gdb, &node); /* * Add hashs for empty nodes. Use closest encloser logic. * The closest encloser either has data or is a empty * node for another span so we don't add * it here. Empty labels on nextname are within the span. */ dns_name_downcase(nextname, nextname, NULL); dns_name_fullcompare(name, nextname, &order, &nlabels); addnowildcardhash(hashlist, name, hashalg, iterations, salt, salt_len); count = dns_name_countlabels(nextname); while (count > nlabels + 1) { count--; dns_name_split(nextname, count, NULL, nextname); hashlist_add_dns_name(hashlist, nextname, hashalg, iterations, salt, salt_len, ISC_FALSE); addnowildcardhash(hashlist, nextname, hashalg, iterations, salt, salt_len); } } dns_dbiterator_destroy(&dbiter); /* * We have all the hashes now so we can sort them. */ hashlist_sort(hashlist); /* * Check for duplicate hashes. If found the salt needs to * be changed. */ if (hashlist_hasdup(hashlist)) fatal("Duplicate hash detected. Pick a different salt."); /* * Generate the nsec3 records. */ zonecut = NULL; done = ISC_FALSE; addnsec3param(salt, salt_len, iterations); /* * Clean out NSEC3 records which don't match this chain. */ result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter); check_result(result, "dns_db_createiterator()"); for (result = dns_dbiterator_first(dbiter); result == ISC_R_SUCCESS; result = dns_dbiterator_next(dbiter)) { result = dns_dbiterator_current(dbiter, &node, name); check_dns_dbiterator_current(result); nsec3clean(name, node, hashalg, iterations, salt, salt_len, hashlist); dns_db_detachnode(gdb, &node); } dns_dbiterator_destroy(&dbiter); /* * Generate / complete the new chain. */ result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter); check_result(result, "dns_db_createiterator()"); result = dns_dbiterator_first(dbiter); check_result(result, "dns_dbiterator_first()"); while (!done) { result = dns_dbiterator_current(dbiter, &node, name); check_dns_dbiterator_current(result); /* * Skip out-of-zone records. */ if (!dns_name_issubdomain(name, gorigin)) { result = dns_dbiterator_next(dbiter); if (result == ISC_R_NOMORE) done = ISC_TRUE; else check_result(result, "dns_dbiterator_next()"); dns_db_detachnode(gdb, &node); continue; } result = dns_dbiterator_next(dbiter); nextnode = NULL; while (result == ISC_R_SUCCESS) { result = dns_dbiterator_current(dbiter, &nextnode, nextname); check_dns_dbiterator_current(result); active = active_node(nextnode); if (!active) { dns_db_detachnode(gdb, &nextnode); result = dns_dbiterator_next(dbiter); continue; } if (!dns_name_issubdomain(nextname, gorigin) || (zonecut != NULL && dns_name_issubdomain(nextname, zonecut))) { dns_db_detachnode(gdb, &nextnode); result = dns_dbiterator_next(dbiter); continue; } if (is_delegation(gdb, gversion, gorigin, nextname, nextnode, NULL)) { zonecut = dns_fixedname_name(&fzonecut); dns_name_copy(nextname, zonecut, NULL); if (OPTOUT(nsec3flags) && !secure(nextname, nextnode)) { dns_db_detachnode(gdb, &nextnode); result = dns_dbiterator_next(dbiter); continue; } } dns_db_detachnode(gdb, &nextnode); break; } if (result == ISC_R_NOMORE) { dns_name_copy(gorigin, nextname, NULL); done = ISC_TRUE; } else if (result != ISC_R_SUCCESS) fatal("iterating through the database failed: %s", isc_result_totext(result)); /* * We need to pause here to release the lock on the database. */ dns_dbiterator_pause(dbiter); addnsec3(name, node, salt, salt_len, iterations, hashlist, zone_soa_min_ttl); dns_db_detachnode(gdb, &node); /* * Add NSEC3's for empty nodes. Use closest encloser logic. */ dns_name_fullcompare(name, nextname, &order, &nlabels); count = dns_name_countlabels(nextname); while (count > nlabels + 1) { count--; dns_name_split(nextname, count, NULL, nextname); addnsec3(nextname, NULL, salt, salt_len, iterations, hashlist, zone_soa_min_ttl); } } dns_dbiterator_destroy(&dbiter); } /*% * Load the zone file from disk */ static void loadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) { isc_buffer_t b; int len; dns_fixedname_t fname; dns_name_t *name; isc_result_t result; len = strlen(origin); isc_buffer_init(&b, origin, len); isc_buffer_add(&b, len); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) fatal("failed converting name '%s' to dns format: %s", origin, isc_result_totext(result)); result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone, rdclass, 0, NULL, db); check_result(result, "dns_db_create()"); result = dns_db_load2(*db, file, inputformat); if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) fatal("failed loading zone from '%s': %s", file, isc_result_totext(result)); } /*% * Finds all public zone keys in the zone, and attempts to load the * private keys from disk. */ static void loadzonekeys(isc_boolean_t preserve_keys, isc_boolean_t load_public) { dns_dbnode_t *node; dns_dbversion_t *currentversion = NULL; isc_result_t result; dns_rdataset_t rdataset, keysigs, soasigs; node = NULL; result = dns_db_findnode(gdb, gorigin, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) fatal("failed to find the zone's origin: %s", isc_result_totext(result)); dns_db_currentversion(gdb, ¤tversion); dns_rdataset_init(&rdataset); dns_rdataset_init(&soasigs); dns_rdataset_init(&keysigs); /* Make note of the keys which signed the SOA, if any */ result = dns_db_findrdataset(gdb, node, currentversion, dns_rdatatype_soa, 0, 0, &rdataset, &soasigs); if (result != ISC_R_SUCCESS) goto cleanup; /* Preserve the TTL of the DNSKEY RRset, if any */ dns_rdataset_disassociate(&rdataset); result = dns_db_findrdataset(gdb, node, currentversion, dns_rdatatype_dnskey, 0, 0, &rdataset, &keysigs); if (result != ISC_R_SUCCESS) goto cleanup; if (set_keyttl && keyttl != rdataset.ttl) { fprintf(stderr, "User-specified TTL %d conflicts " "with existing DNSKEY RRset TTL.\n", keyttl); fprintf(stderr, "Imported keys will use the RRSet " "TTL %d instead.\n", rdataset.ttl); } keyttl = rdataset.ttl; /* Load keys corresponding to the existing DNSKEY RRset. */ result = dns_dnssec_keylistfromrdataset(gorigin, directory, mctx, &rdataset, &keysigs, &soasigs, preserve_keys, load_public, &keylist); if (result != ISC_R_SUCCESS) fatal("failed to load the zone keys: %s", isc_result_totext(result)); cleanup: if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (dns_rdataset_isassociated(&keysigs)) dns_rdataset_disassociate(&keysigs); if (dns_rdataset_isassociated(&soasigs)) dns_rdataset_disassociate(&soasigs); dns_db_detachnode(gdb, &node); dns_db_closeversion(gdb, ¤tversion, ISC_FALSE); } static void loadexplicitkeys(char *keyfiles[], int n, isc_boolean_t setksk) { isc_result_t result; int i; for (i = 0; i < n; i++) { dns_dnsseckey_t *key = NULL; dst_key_t *newkey = NULL; result = dst_key_fromnamedfile(keyfiles[i], directory, DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, mctx, &newkey); if (result != ISC_R_SUCCESS) fatal("cannot load dnskey %s: %s", keyfiles[i], isc_result_totext(result)); if (!dns_name_equal(gorigin, dst_key_name(newkey))) fatal("key %s not at origin\n", keyfiles[i]); if (!dst_key_isprivate(newkey)) fatal("cannot sign zone with non-private dnskey %s", keyfiles[i]); /* Skip any duplicates */ for (key = ISC_LIST_HEAD(keylist); key != NULL; key = ISC_LIST_NEXT(key, link)) { if (dst_key_id(key->key) == dst_key_id(newkey) && dst_key_alg(key->key) == dst_key_alg(newkey)) break; } if (key == NULL) { /* We haven't seen this key before */ dns_dnsseckey_create(mctx, &newkey, &key); ISC_LIST_APPEND(keylist, key, link); key->source = dns_keysource_user; } else { dst_key_free(&key->key); key->key = newkey; } key->force_publish = ISC_TRUE; key->force_sign = ISC_TRUE; if (setksk) key->ksk = ISC_TRUE; } } static void report(const char *format, ...) { va_list args; va_start(args, format); vfprintf(stderr, format, args); va_end(args); putc('\n', stderr); } static void build_final_keylist(void) { isc_result_t result; dns_dbversion_t *ver = NULL; dns_diff_t diff; dns_dnsseckeylist_t matchkeys; char name[DNS_NAME_FORMATSIZE]; /* * Find keys that match this zone in the key repository. */ ISC_LIST_INIT(matchkeys); result = dns_dnssec_findmatchingkeys(gorigin, directory, mctx, &matchkeys); if (result == ISC_R_NOTFOUND) result = ISC_R_SUCCESS; check_result(result, "dns_dnssec_findmatchingkeys"); result = dns_db_newversion(gdb, &ver); check_result(result, "dns_db_newversion"); dns_diff_init(mctx, &diff); /* * Update keylist with information from from the key repository. */ dns_dnssec_updatekeys(&keylist, &matchkeys, NULL, gorigin, keyttl, &diff, ignore_kskflag, mctx, report); dns_name_format(gorigin, name, sizeof(name)); result = dns_diff_applysilently(&diff, gdb, ver); if (result != ISC_R_SUCCESS) fatal("failed to update DNSKEY RRset at node '%s': %s", name, isc_result_totext(result)); dns_db_closeversion(gdb, &ver, ISC_TRUE); dns_diff_clear(&diff); } static void warnifallksk(dns_db_t *db) { dns_dbversion_t *currentversion = NULL; dns_dbnode_t *node = NULL; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; dns_rdata_dnskey_t dnskey; isc_boolean_t have_non_ksk = ISC_FALSE; dns_db_currentversion(db, ¤tversion); result = dns_db_findnode(db, gorigin, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) fatal("failed to find the zone's origin: %s", isc_result_totext(result)); dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, currentversion, dns_rdatatype_dnskey, 0, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) fatal("failed to find keys at the zone apex: %s", isc_result_totext(result)); result = dns_rdataset_first(&rdataset); check_result(result, "dns_rdataset_first"); while (result == ISC_R_SUCCESS) { dns_rdata_reset(&rdata); dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &dnskey, NULL); check_result(result, "dns_rdata_tostruct"); if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0) { have_non_ksk = ISC_TRUE; result = ISC_R_NOMORE; } else result = dns_rdataset_next(&rdataset); dns_rdata_freestruct(&dnskey); } dns_rdataset_disassociate(&rdataset); dns_db_detachnode(db, &node); dns_db_closeversion(db, ¤tversion, ISC_FALSE); if (!have_non_ksk && !ignore_kskflag) { if (disable_zone_check) fprintf(stderr, "%s: warning: No non-KSK DNSKEY found; " "supply a ZSK or use '-z'.\n", program); else fatal("No non-KSK DNSKEY found; " "supply a ZSK or use '-z'."); } } static void set_nsec3params(isc_boolean_t update, isc_boolean_t set_salt, isc_boolean_t set_optout, isc_boolean_t set_iter) { isc_result_t result; dns_dbversion_t *ver = NULL; dns_dbnode_t *node = NULL; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_nsec3_t nsec3; dns_fixedname_t fname; dns_name_t *hashname; unsigned char orig_salt[255]; size_t orig_saltlen; dns_hash_t orig_hash; isc_uint16_t orig_iter; dns_db_currentversion(gdb, &ver); dns_rdataset_init(&rdataset); orig_saltlen = sizeof(orig_salt); result = dns_db_getnsec3parameters(gdb, ver, &orig_hash, NULL, &orig_iter, orig_salt, &orig_saltlen); if (result != ISC_R_SUCCESS) goto cleanup; nsec_datatype = dns_rdatatype_nsec3; if (!update && set_salt) { if (salt_length != orig_saltlen || !isc_safe_memequal(saltbuf, orig_salt, salt_length)) fatal("An NSEC3 chain exists with a different salt. " "Use -u to update it."); } else if (!set_salt) { salt_length = orig_saltlen; memmove(saltbuf, orig_salt, orig_saltlen); gsalt = saltbuf; } if (!update && set_iter) { if (nsec3iter != orig_iter) fatal("An NSEC3 chain exists with different " "iterations. Use -u to update it."); } else if (!set_iter) nsec3iter = orig_iter; /* * Find an NSEC3 record to get the current OPTOUT value. * (This assumes all NSEC3 records agree.) */ dns_fixedname_init(&fname); hashname = dns_fixedname_name(&fname); result = dns_nsec3_hashname(&fname, NULL, NULL, gorigin, gorigin, dns_hash_sha1, orig_iter, orig_salt, orig_saltlen); check_result(result, "dns_nsec3_hashname"); result = dns_db_findnsec3node(gdb, hashname, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_db_findrdataset(gdb, node, ver, dns_rdatatype_nsec3, 0, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_rdataset_first(&rdataset); check_result(result, "dns_rdataset_first"); dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &nsec3, NULL); check_result(result, "dns_rdata_tostruct"); if (!update && set_optout) { if (nsec3flags != nsec3.flags) fatal("An NSEC3 chain exists with%s OPTOUT. " "Use -u -%s to %s it.", OPTOUT(nsec3.flags) ? "" : "out", OPTOUT(nsec3.flags) ? "AA" : "A", OPTOUT(nsec3.flags) ? "clear" : "set"); } else if (!set_optout) nsec3flags = nsec3.flags; dns_rdata_freestruct(&nsec3); cleanup: if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (node != NULL) dns_db_detachnode(gdb, &node); dns_db_closeversion(gdb, &ver, ISC_FALSE); } static void writeset(const char *prefix, dns_rdatatype_t type) { char *filename; char namestr[DNS_NAME_FORMATSIZE]; dns_db_t *db = NULL; dns_dbversion_t *dbversion = NULL; dns_diff_t diff; dns_difftuple_t *tuple = NULL; dns_fixedname_t fixed; dns_name_t *name; dns_rdata_t rdata, ds; isc_boolean_t have_ksk = ISC_FALSE; isc_boolean_t have_non_ksk = ISC_FALSE; isc_buffer_t b; isc_buffer_t namebuf; isc_region_t r; isc_result_t result; dns_dnsseckey_t *key, *tmpkey; unsigned char dsbuf[DNS_DS_BUFFERSIZE]; unsigned char keybuf[DST_KEY_MAXSIZE]; unsigned int filenamelen; const dns_master_style_t *style = (type == dns_rdatatype_dnskey) ? masterstyle : dsstyle; isc_buffer_init(&namebuf, namestr, sizeof(namestr)); result = dns_name_tofilenametext(gorigin, ISC_FALSE, &namebuf); check_result(result, "dns_name_tofilenametext"); isc_buffer_putuint8(&namebuf, 0); filenamelen = strlen(prefix) + strlen(namestr); if (dsdir != NULL) filenamelen += strlen(dsdir) + 1; filename = isc_mem_get(mctx, filenamelen + 1); if (filename == NULL) fatal("out of memory"); if (dsdir != NULL) sprintf(filename, "%s/", dsdir); else filename[0] = 0; strcat(filename, prefix); strcat(filename, namestr); dns_diff_init(mctx, &diff); if (type == dns_rdatatype_dlv) { dns_name_t tname; unsigned int labels; dns_name_init(&tname, NULL); dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); labels = dns_name_countlabels(gorigin); dns_name_getlabelsequence(gorigin, 0, labels - 1, &tname); result = dns_name_concatenate(&tname, dlv, name, NULL); check_result(result, "dns_name_concatenate"); } else name = gorigin; for (key = ISC_LIST_HEAD(keylist); key != NULL; key = ISC_LIST_NEXT(key, link)) { if (REVOKE(key->key)) continue; if (isksk(key)) { have_ksk = ISC_TRUE; have_non_ksk = ISC_FALSE; } else { have_ksk = ISC_FALSE; have_non_ksk = ISC_TRUE; } for (tmpkey = ISC_LIST_HEAD(keylist); tmpkey != NULL; tmpkey = ISC_LIST_NEXT(tmpkey, link)) { if (dst_key_alg(key->key) != dst_key_alg(tmpkey->key)) continue; if (REVOKE(tmpkey->key)) continue; if (isksk(tmpkey)) have_ksk = ISC_TRUE; else have_non_ksk = ISC_TRUE; } if (have_ksk && have_non_ksk && !isksk(key)) continue; dns_rdata_init(&rdata); dns_rdata_init(&ds); isc_buffer_init(&b, keybuf, sizeof(keybuf)); result = dst_key_todns(key->key, &b); check_result(result, "dst_key_todns"); isc_buffer_usedregion(&b, &r); dns_rdata_fromregion(&rdata, gclass, dns_rdatatype_dnskey, &r); if (type != dns_rdatatype_dnskey) { result = dns_ds_buildrdata(gorigin, &rdata, DNS_DSDIGEST_SHA1, dsbuf, &ds); check_result(result, "dns_ds_buildrdata"); if (type == dns_rdatatype_dlv) ds.type = dns_rdatatype_dlv; result = dns_difftuple_create(mctx, DNS_DIFFOP_ADDRESIGN, name, 0, &ds, &tuple); check_result(result, "dns_difftuple_create"); dns_diff_append(&diff, &tuple); dns_rdata_reset(&ds); result = dns_ds_buildrdata(gorigin, &rdata, DNS_DSDIGEST_SHA256, dsbuf, &ds); check_result(result, "dns_ds_buildrdata"); if (type == dns_rdatatype_dlv) ds.type = dns_rdatatype_dlv; result = dns_difftuple_create(mctx, DNS_DIFFOP_ADDRESIGN, name, 0, &ds, &tuple); } else result = dns_difftuple_create(mctx, DNS_DIFFOP_ADDRESIGN, gorigin, zone_soa_min_ttl, &rdata, &tuple); check_result(result, "dns_difftuple_create"); dns_diff_append(&diff, &tuple); } result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, gclass, 0, NULL, &db); check_result(result, "dns_db_create"); result = dns_db_newversion(db, &dbversion); check_result(result, "dns_db_newversion"); result = dns_diff_apply(&diff, db, dbversion); check_result(result, "dns_diff_apply"); dns_diff_clear(&diff); result = dns_master_dump(mctx, db, dbversion, style, filename); check_result(result, "dns_master_dump"); isc_mem_put(mctx, filename, filenamelen + 1); dns_db_closeversion(db, &dbversion, ISC_FALSE); dns_db_detach(&db); } static void print_time(FILE *fp) { time_t currenttime; if (outputformat != dns_masterformat_text) return; currenttime = time(NULL); fprintf(fp, "; File written on %s", ctime(¤ttime)); } static void print_version(FILE *fp) { if (outputformat != dns_masterformat_text) return; fprintf(fp, "; dnssec_signzone version " VERSION "\n"); } ISC_PLATFORM_NORETURN_PRE static void usage(void) ISC_PLATFORM_NORETURN_POST; static void usage(void) { fprintf(stderr, "Usage:\n"); fprintf(stderr, "\t%s [options] zonefile [keys]\n", program); fprintf(stderr, "\n"); fprintf(stderr, "Version: %s\n", VERSION); fprintf(stderr, "Options: (default value in parenthesis) \n"); fprintf(stderr, "\t-S:\tsmart signing: automatically finds key files\n" "\t\tfor the zone and determines how they are to " "be used\n"); fprintf(stderr, "\t-K directory:\n"); fprintf(stderr, "\t\tdirectory to find key files (.)\n"); fprintf(stderr, "\t-d directory:\n"); fprintf(stderr, "\t\tdirectory to find dsset-* files (.)\n"); fprintf(stderr, "\t-g:\t"); fprintf(stderr, "update DS records based on child zones' " "dsset-* files\n"); fprintf(stderr, "\t-s [YYYYMMDDHHMMSS|+offset]:\n"); fprintf(stderr, "\t\tRRSIG start time " "- absolute|offset (now - 1 hour)\n"); fprintf(stderr, "\t-e [YYYYMMDDHHMMSS|+offset|\"now\"+offset]:\n"); fprintf(stderr, "\t\tRRSIG end time " "- absolute|from start|from now " "(now + 30 days)\n"); fprintf(stderr, "\t-X [YYYYMMDDHHMMSS|+offset|\"now\"+offset]:\n"); fprintf(stderr, "\t\tDNSKEY RRSIG end " "- absolute|from start|from now " "(matches -e)\n"); fprintf(stderr, "\t-i interval:\n"); fprintf(stderr, "\t\tcycle interval - resign " "if < interval from end ( (end-start)/4 )\n"); fprintf(stderr, "\t-j jitter:\n"); fprintf(stderr, "\t\trandomize signature end time up to jitter seconds\n"); fprintf(stderr, "\t-v debuglevel (0)\n"); fprintf(stderr, "\t-V:\tprint version information\n"); fprintf(stderr, "\t-o origin:\n"); fprintf(stderr, "\t\tzone origin (name of zonefile)\n"); fprintf(stderr, "\t-f outfile:\n"); fprintf(stderr, "\t\tfile the signed zone is written in " "(zonefile + .signed)\n"); fprintf(stderr, "\t-I format:\n"); fprintf(stderr, "\t\tfile format of input zonefile (text)\n"); fprintf(stderr, "\t-O format:\n"); fprintf(stderr, "\t\tfile format of signed zone file (text)\n"); fprintf(stderr, "\t-N format:\n"); fprintf(stderr, "\t\tsoa serial format of signed zone file (keep)\n"); fprintf(stderr, "\t-D:\n"); fprintf(stderr, "\t\toutput only DNSSEC-related records\n"); fprintf(stderr, "\t-r randomdev:\n"); fprintf(stderr, "\t\ta file containing random data\n"); fprintf(stderr, "\t-a:\t"); fprintf(stderr, "verify generated signatures\n"); fprintf(stderr, "\t-c class (IN)\n"); fprintf(stderr, "\t-E engine:\n"); #if defined(PKCS11CRYPTO) fprintf(stderr, "\t\tpath to PKCS#11 provider library " "(default is %s)\n", PK11_LIB_LOCATION); #elif defined(USE_PKCS11) fprintf(stderr, "\t\tname of an OpenSSL engine to use " "(default is \"pkcs11\")\n"); #else fprintf(stderr, "\t\tname of an OpenSSL engine to use\n"); #endif fprintf(stderr, "\t-p:\t"); fprintf(stderr, "use pseudorandom data (faster but less secure)\n"); fprintf(stderr, "\t-P:\t"); fprintf(stderr, "disable post-sign verification\n"); fprintf(stderr, "\t-Q:\t"); fprintf(stderr, "remove signatures from keys that are no " "longer active\n"); fprintf(stderr, "\t-R:\t"); fprintf(stderr, "remove signatures from keys that no longer exist\n"); fprintf(stderr, "\t-T TTL:\tTTL for newly added DNSKEYs\n"); fprintf(stderr, "\t-t:\t"); fprintf(stderr, "print statistics\n"); fprintf(stderr, "\t-u:\t"); fprintf(stderr, "update or replace an existing NSEC/NSEC3 chain\n"); fprintf(stderr, "\t-x:\tsign DNSKEY record with KSKs only, not ZSKs\n"); fprintf(stderr, "\t-z:\tsign all records with KSKs\n"); fprintf(stderr, "\t-C:\tgenerate a keyset file, for compatibility\n" "\t\twith older versions of dnssec-signzone -g\n"); fprintf(stderr, "\t-n ncpus (number of cpus present)\n"); fprintf(stderr, "\t-k key_signing_key\n"); fprintf(stderr, "\t-l lookasidezone\n"); fprintf(stderr, "\t-3 NSEC3 salt\n"); fprintf(stderr, "\t-H NSEC3 iterations (10)\n"); fprintf(stderr, "\t-A NSEC3 optout\n"); fprintf(stderr, "\n"); fprintf(stderr, "Signing Keys: "); fprintf(stderr, "(default: all zone keys that have private keys)\n"); fprintf(stderr, "\tkeyfile (Kname+alg+tag)\n"); exit(0); } static void removetempfile(void) { if (removefile) isc_file_remove(tempfile); } static void print_stats(isc_time_t *timer_start, isc_time_t *timer_finish, isc_time_t *sign_start, isc_time_t *sign_finish) { isc_uint64_t time_us; /* Time in microseconds */ isc_uint64_t time_ms; /* Time in milliseconds */ isc_uint64_t sig_ms; /* Signatures per millisecond */ FILE *out = output_stdout ? stderr : stdout; fprintf(out, "Signatures generated: %10d\n", nsigned); fprintf(out, "Signatures retained: %10d\n", nretained); fprintf(out, "Signatures dropped: %10d\n", ndropped); fprintf(out, "Signatures successfully verified: %10d\n", nverified); fprintf(out, "Signatures unsuccessfully " "verified: %10d\n", nverifyfailed); time_us = isc_time_microdiff(sign_finish, sign_start); time_ms = time_us / 1000; fprintf(out, "Signing time in seconds: %7u.%03u\n", (unsigned int) (time_ms / 1000), (unsigned int) (time_ms % 1000)); if (time_us > 0) { sig_ms = ((isc_uint64_t)nsigned * 1000000000) / time_us; fprintf(out, "Signatures per second: %7u.%03u\n", (unsigned int) sig_ms / 1000, (unsigned int) sig_ms % 1000); } time_us = isc_time_microdiff(timer_finish, timer_start); time_ms = time_us / 1000; fprintf(out, "Runtime in seconds: %7u.%03u\n", (unsigned int) (time_ms / 1000), (unsigned int) (time_ms % 1000)); } int main(int argc, char *argv[]) { int i, ch; char *startstr = NULL, *endstr = NULL, *classname = NULL; char *dnskey_endstr = NULL; char *origin = NULL, *file = NULL, *output = NULL; char *inputformatstr = NULL, *outputformatstr = NULL; char *serialformatstr = NULL; char *dskeyfile[MAXDSKEYS]; int ndskeys = 0; char *endp; isc_time_t timer_start, timer_finish; isc_time_t sign_start, sign_finish; dns_dnsseckey_t *key; isc_result_t result; isc_log_t *log = NULL; isc_boolean_t pseudorandom = ISC_FALSE; #ifdef USE_PKCS11 const char *engine = PKCS11_ENGINE; #else const char *engine = NULL; #endif unsigned int eflags; isc_boolean_t free_output = ISC_FALSE; int tempfilelen = 0; dns_rdataclass_t rdclass; isc_task_t **tasks = NULL; isc_buffer_t b; int len; hashlist_t hashlist; isc_boolean_t make_keyset = ISC_FALSE; isc_boolean_t set_salt = ISC_FALSE; isc_boolean_t set_optout = ISC_FALSE; isc_boolean_t set_iter = ISC_FALSE; isc_boolean_t nonsecify = ISC_FALSE; /* Unused letters: Bb G J q Yy (and F is reserved). */ #define CMDLINE_FLAGS \ "3:AaCc:Dd:E:e:f:FghH:i:I:j:K:k:L:l:m:M:n:N:o:O:PpQRr:s:ST:tuUv:VX:xzZ:" /* * Process memory debugging argument first. */ while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { switch (ch) { case 'm': if (strcasecmp(isc_commandline_argument, "record") == 0) isc_mem_debugging |= ISC_MEM_DEBUGRECORD; if (strcasecmp(isc_commandline_argument, "trace") == 0) isc_mem_debugging |= ISC_MEM_DEBUGTRACE; if (strcasecmp(isc_commandline_argument, "usage") == 0) isc_mem_debugging |= ISC_MEM_DEBUGUSAGE; if (strcasecmp(isc_commandline_argument, "size") == 0) isc_mem_debugging |= ISC_MEM_DEBUGSIZE; if (strcasecmp(isc_commandline_argument, "mctx") == 0) isc_mem_debugging |= ISC_MEM_DEBUGCTX; break; default: break; } } isc_commandline_reset = ISC_TRUE; masterstyle = &dns_master_style_explicitttl; check_result(isc_app_start(), "isc_app_start"); result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) fatal("out of memory"); #ifdef PKCS11CRYPTO pk11_result_register(); #endif dns_result_register(); isc_commandline_errprint = ISC_FALSE; while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { switch (ch) { case '3': set_salt = ISC_TRUE; nsec_datatype = dns_rdatatype_nsec3; if (strcmp(isc_commandline_argument, "-") != 0) { isc_buffer_t target; char *sarg; sarg = isc_commandline_argument; isc_buffer_init(&target, saltbuf, sizeof(saltbuf)); result = isc_hex_decodestring(sarg, &target); check_result(result, "isc_hex_decodestring(salt)"); salt_length = isc_buffer_usedlength(&target); } break; case 'A': set_optout = ISC_TRUE; if (OPTOUT(nsec3flags)) nsec3flags &= ~DNS_NSEC3FLAG_OPTOUT; else nsec3flags |= DNS_NSEC3FLAG_OPTOUT; break; case 'a': tryverify = ISC_TRUE; break; case 'C': make_keyset = ISC_TRUE; break; case 'c': classname = isc_commandline_argument; break; case 'd': dsdir = isc_commandline_argument; if (strlen(dsdir) == 0U) fatal("DS directory must be non-empty string"); result = try_dir(dsdir); if (result != ISC_R_SUCCESS) fatal("cannot open directory %s: %s", dsdir, isc_result_totext(result)); break; case 'D': output_dnssec_only = ISC_TRUE; break; case 'E': engine = isc_commandline_argument; break; case 'e': endstr = isc_commandline_argument; break; case 'f': output = isc_commandline_argument; if (strcmp(output, "-") == 0) output_stdout = ISC_TRUE; break; case 'g': generateds = ISC_TRUE; break; case 'H': set_iter = ISC_TRUE; nsec3iter = strtoul(isc_commandline_argument, &endp, 0); if (*endp != '\0') fatal("iterations must be numeric"); if (nsec3iter > 0xffffU) fatal("iterations too big"); break; case 'I': inputformatstr = isc_commandline_argument; break; case 'i': endp = NULL; cycle = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0' || cycle < 0) fatal("cycle period must be numeric and " "positive"); break; case 'j': endp = NULL; jitter = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0' || jitter < 0) fatal("jitter must be numeric and positive"); break; case 'K': directory = isc_commandline_argument; break; case 'k': if (ndskeys == MAXDSKEYS) fatal("too many key-signing keys specified"); dskeyfile[ndskeys++] = isc_commandline_argument; break; case 'L': snset = ISC_TRUE; endp = NULL; serialnum = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') { fprintf(stderr, "source serial number " "must be numeric"); exit(1); } break; case 'l': len = strlen(isc_commandline_argument); isc_buffer_init(&b, isc_commandline_argument, len); isc_buffer_add(&b, len); dns_fixedname_init(&dlv_fixed); dlv = dns_fixedname_name(&dlv_fixed); result = dns_name_fromtext(dlv, &b, dns_rootname, 0, NULL); check_result(result, "dns_name_fromtext(dlv)"); break; case 'M': endp = NULL; set_maxttl = ISC_TRUE; maxttl = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') { fprintf(stderr, "maximum TTL " "must be numeric"); exit(1); } break; case 'm': break; case 'N': serialformatstr = isc_commandline_argument; break; case 'n': endp = NULL; ntasks = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0' || ntasks > ISC_INT32_MAX) fatal("number of cpus must be numeric"); break; case 'O': outputformatstr = isc_commandline_argument; break; case 'o': origin = isc_commandline_argument; break; case 'P': disable_zone_check = ISC_TRUE; break; case 'p': pseudorandom = ISC_TRUE; break; case 'Q': remove_inactkeysigs = ISC_TRUE; break; case 'R': remove_orphansigs = ISC_TRUE; break; case 'r': setup_entropy(mctx, isc_commandline_argument, &ectx); break; case 'S': smartsign = ISC_TRUE; break; case 's': startstr = isc_commandline_argument; break; case 'T': endp = NULL; set_keyttl = ISC_TRUE; keyttl = strtottl(isc_commandline_argument); break; case 't': printstats = ISC_TRUE; break; case 'U': /* Undocumented for testing only. */ unknownalg = ISC_TRUE; break; case 'u': update_chain = ISC_TRUE; break; case 'v': endp = NULL; verbose = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') fatal("verbose level must be numeric"); break; case 'X': dnskey_endstr = isc_commandline_argument; break; case 'x': keyset_kskonly = ISC_TRUE; break; case 'z': ignore_kskflag = ISC_TRUE; break; case 'F': /* Reserved for FIPS mode */ /* FALLTHROUGH */ case '?': if (isc_commandline_option != '?') fprintf(stderr, "%s: invalid argument -%c\n", program, isc_commandline_option); /* FALLTHROUGH */ case 'h': /* Does not return. */ usage(); case 'V': /* Does not return. */ version(program); case 'Z': /* Undocumented test options */ if (!strcmp(isc_commandline_argument, "nonsecify")) nonsecify = ISC_TRUE; break; default: fprintf(stderr, "%s: unhandled option -%c\n", program, isc_commandline_option); exit(1); } } if (ectx == NULL) setup_entropy(mctx, NULL, &ectx); eflags = ISC_ENTROPY_BLOCKING; if (!pseudorandom) eflags |= ISC_ENTROPY_GOODONLY; result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (result != ISC_R_SUCCESS) fatal("could not create hash context"); result = dst_lib_init2(mctx, ectx, engine, eflags); if (result != ISC_R_SUCCESS) fatal("could not initialize dst: %s", isc_result_totext(result)); isc_stdtime_get(&now); if (startstr != NULL) { starttime = strtotime(startstr, now, now, NULL); } else starttime = now - 3600; /* Allow for some clock skew. */ if (endstr != NULL) endtime = strtotime(endstr, now, starttime, NULL); else endtime = starttime + (30 * 24 * 60 * 60); if (dnskey_endstr != NULL) { dnskey_endtime = strtotime(dnskey_endstr, now, starttime, NULL); if (endstr != NULL && dnskey_endtime == endtime) fprintf(stderr, "WARNING: -e and -X were both set, " "but have identical values.\n"); } else dnskey_endtime = endtime; if (cycle == -1) cycle = (endtime - starttime) / 4; if (ntasks == 0) ntasks = isc_os_ncpus() * 2; vbprintf(4, "using %d cpus\n", ntasks); rdclass = strtoclass(classname); if (directory == NULL) directory = "."; setup_logging(mctx, &log); argc -= isc_commandline_index; argv += isc_commandline_index; if (argc < 1) usage(); file = argv[0]; argc -= 1; argv += 1; if (origin == NULL) origin = file; if (output == NULL) { free_output = ISC_TRUE; output = isc_mem_allocate(mctx, strlen(file) + strlen(".signed") + 1); if (output == NULL) fatal("out of memory"); sprintf(output, "%s.signed", file); } if (inputformatstr != NULL) { if (strcasecmp(inputformatstr, "text") == 0) inputformat = dns_masterformat_text; else if (strcasecmp(inputformatstr, "map") == 0) inputformat = dns_masterformat_map; else if (strcasecmp(inputformatstr, "raw") == 0) inputformat = dns_masterformat_raw; else if (strncasecmp(inputformatstr, "raw=", 4) == 0) { inputformat = dns_masterformat_raw; fprintf(stderr, "WARNING: input format version ignored\n"); } else fatal("unknown file format: %s", inputformatstr); } if (outputformatstr != NULL) { if (strcasecmp(outputformatstr, "text") == 0) { outputformat = dns_masterformat_text; } else if (strcasecmp(outputformatstr, "full") == 0) { outputformat = dns_masterformat_text; masterstyle = &dns_master_style_full; } else if (strcasecmp(outputformatstr, "map") == 0) { outputformat = dns_masterformat_map; } else if (strcasecmp(outputformatstr, "raw") == 0) { outputformat = dns_masterformat_raw; } else if (strncasecmp(outputformatstr, "raw=", 4) == 0) { char *end; outputformat = dns_masterformat_raw; outputformat = dns_masterformat_raw; rawversion = strtol(outputformatstr + 4, &end, 10); if (end == outputformatstr + 4 || *end != '\0' || rawversion > 1U) { fprintf(stderr, "unknown raw format version\n"); exit(1); } } else fatal("unknown file format: %s", outputformatstr); } if (serialformatstr != NULL) { if (strcasecmp(serialformatstr, "keep") == 0) serialformat = SOA_SERIAL_KEEP; else if (strcasecmp(serialformatstr, "increment") == 0 || strcasecmp(serialformatstr, "incr") == 0) serialformat = SOA_SERIAL_INCREMENT; else if (strcasecmp(serialformatstr, "unixtime") == 0) serialformat = SOA_SERIAL_UNIXTIME; else fatal("unknown soa serial format: %s", serialformatstr); } if (output_dnssec_only && outputformat != dns_masterformat_text) fatal("option -D can only be used with \"-O text\""); if (output_dnssec_only && serialformat != SOA_SERIAL_KEEP) fatal("option -D can only be used with \"-N keep\""); if (output_dnssec_only && set_maxttl) fatal("option -D cannot be used with -M"); result = dns_master_stylecreate(&dsstyle, DNS_STYLEFLAG_NO_TTL, 0, 24, 0, 0, 0, 8, mctx); check_result(result, "dns_master_stylecreate"); gdb = NULL; TIME_NOW(&timer_start); loadzone(file, origin, rdclass, &gdb); gorigin = dns_db_origin(gdb); gclass = dns_db_class(gdb); get_soa_ttls(); if (set_maxttl && set_keyttl && keyttl > maxttl) { fprintf(stderr, "%s: warning: Specified key TTL %d " "exceeds maximum zone TTL; reducing to %d\n", program, keyttl, maxttl); keyttl = maxttl; } if (!set_keyttl) keyttl = soa_ttl; /* * Check for any existing NSEC3 parameters in the zone, * and use them as defaults if -u was not specified. */ if (update_chain && !set_optout && !set_iter && !set_salt) nsec_datatype = dns_rdatatype_nsec; else set_nsec3params(update_chain, set_salt, set_optout, set_iter); /* * We need to do this early on, as we start messing with the list * of keys rather early. */ ISC_LIST_INIT(keylist); result = isc_rwlock_init(&keylist_lock, 0, 0); if (result != ISC_R_SUCCESS) fatal("could not initialize keylist_lock: %s", isc_result_totext(result)); /* * Fill keylist with: * 1) Keys listed in the DNSKEY set that have * private keys associated, *if* no keys were * set on the command line. * 2) ZSKs set on the command line * 3) KSKs set on the command line * 4) Any keys remaining in the DNSKEY set which * do not have private keys associated and were * not specified on the command line. */ if (argc == 0 || smartsign) loadzonekeys(!smartsign, ISC_FALSE); loadexplicitkeys(argv, argc, ISC_FALSE); loadexplicitkeys(dskeyfile, ndskeys, ISC_TRUE); loadzonekeys(!smartsign, ISC_TRUE); /* * If we're doing smart signing, look in the key repository for * key files with metadata, and merge them with the keylist * we have now. */ if (smartsign) build_final_keylist(); /* Now enumerate the key list */ for (key = ISC_LIST_HEAD(keylist); key != NULL; key = ISC_LIST_NEXT(key, link)) { key->index = keycount++; } if (keycount == 0) { if (disable_zone_check) fprintf(stderr, "%s: warning: No keys specified " "or found\n", program); else fatal("No signing keys specified or found."); nokeys = ISC_TRUE; } warnifallksk(gdb); if (IS_NSEC3) { unsigned int max; isc_boolean_t answer; hash_length = dns_nsec3_hashlength(dns_hash_sha1); hashlist_init(&hashlist, dns_db_nodecount(gdb) * 2, hash_length); result = dns_nsec_nseconly(gdb, gversion, &answer); if (result == ISC_R_NOTFOUND) fprintf(stderr, "%s: warning: NSEC3 generation " "requested with no DNSKEY; ignoring\n", program); else if (result != ISC_R_SUCCESS) check_result(result, "dns_nsec_nseconly"); else if (answer) fatal("NSEC3 generation requested with " "NSEC-only DNSKEY"); result = dns_nsec3_maxiterations(gdb, NULL, mctx, &max); check_result(result, "dns_nsec3_maxiterations()"); if (nsec3iter > max) fatal("NSEC3 iterations too big for weakest DNSKEY " "strength. Maximum iterations allowed %u.", max); } gversion = NULL; result = dns_db_newversion(gdb, &gversion); check_result(result, "dns_db_newversion()"); switch (serialformat) { case SOA_SERIAL_INCREMENT: setsoaserial(0); break; case SOA_SERIAL_UNIXTIME: setsoaserial(now); break; case SOA_SERIAL_KEEP: default: /* do nothing */ break; } /* Remove duplicates and cap TTLs at maxttl */ cleanup_zone(); if (!nonsecify) { if (IS_NSEC3) nsec3ify(dns_hash_sha1, nsec3iter, gsalt, salt_length, &hashlist); else nsecify(); } if (!nokeys) { writeset("dsset-", dns_rdatatype_ds); if (make_keyset) writeset("keyset-", dns_rdatatype_dnskey); if (dlv != NULL) { writeset("dlvset-", dns_rdatatype_dlv); } } if (output_stdout) { outfp = stdout; if (outputformatstr == NULL) masterstyle = &dns_master_style_full; } else { tempfilelen = strlen(output) + 20; tempfile = isc_mem_get(mctx, tempfilelen); if (tempfile == NULL) fatal("out of memory"); result = isc_file_mktemplate(output, tempfile, tempfilelen); check_result(result, "isc_file_mktemplate"); if (outputformat == dns_masterformat_text) result = isc_file_openunique(tempfile, &outfp); else result = isc_file_bopenunique(tempfile, &outfp); if (result != ISC_R_SUCCESS) fatal("failed to open temporary output file: %s", isc_result_totext(result)); removefile = ISC_TRUE; setfatalcallback(&removetempfile); } print_time(outfp); print_version(outfp); result = isc_taskmgr_create(mctx, ntasks, 0, &taskmgr); if (result != ISC_R_SUCCESS) fatal("failed to create task manager: %s", isc_result_totext(result)); master = NULL; result = isc_task_create(taskmgr, 0, &master); if (result != ISC_R_SUCCESS) fatal("failed to create task: %s", isc_result_totext(result)); tasks = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *)); if (tasks == NULL) fatal("out of memory"); for (i = 0; i < (int)ntasks; i++) { tasks[i] = NULL; result = isc_task_create(taskmgr, 0, &tasks[i]); if (result != ISC_R_SUCCESS) fatal("failed to create task: %s", isc_result_totext(result)); } RUNTIME_CHECK(isc_mutex_init(&namelock) == ISC_R_SUCCESS); if (printstats) RUNTIME_CHECK(isc_mutex_init(&statslock) == ISC_R_SUCCESS); presign(); TIME_NOW(&sign_start); signapex(); if (!finished) { /* * There is more work to do. Spread it out over multiple * processors if possible. */ for (i = 0; i < (int)ntasks; i++) { result = isc_app_onrun(mctx, master, startworker, tasks[i]); if (result != ISC_R_SUCCESS) fatal("failed to start task: %s", isc_result_totext(result)); } (void)isc_app_run(); if (!finished) fatal("process aborted by user"); } else isc_task_detach(&master); shuttingdown = ISC_TRUE; for (i = 0; i < (int)ntasks; i++) isc_task_detach(&tasks[i]); isc_taskmgr_destroy(&taskmgr); isc_mem_put(mctx, tasks, ntasks * sizeof(isc_task_t *)); postsign(); TIME_NOW(&sign_finish); if (!disable_zone_check) verifyzone(gdb, gversion, gorigin, mctx, ignore_kskflag, keyset_kskonly); if (outputformat != dns_masterformat_text) { dns_masterrawheader_t header; dns_master_initrawheader(&header); if (rawversion == 0U) header.flags = DNS_MASTERRAW_COMPAT; else if (snset) { header.flags = DNS_MASTERRAW_SOURCESERIALSET; header.sourceserial = serialnum; } result = dns_master_dumptostream3(mctx, gdb, gversion, masterstyle, outputformat, &header, outfp); check_result(result, "dns_master_dumptostream3"); } DESTROYLOCK(&namelock); if (printstats) DESTROYLOCK(&statslock); if (!output_stdout) { result = isc_stdio_close(outfp); check_result(result, "isc_stdio_close"); removefile = ISC_FALSE; result = isc_file_rename(tempfile, output); if (result != ISC_R_SUCCESS) fatal("failed to rename temp file to %s: %s", output, isc_result_totext(result)); printf("%s\n", output); } dns_db_closeversion(gdb, &gversion, ISC_FALSE); dns_db_detach(&gdb); while (!ISC_LIST_EMPTY(keylist)) { key = ISC_LIST_HEAD(keylist); ISC_LIST_UNLINK(keylist, key, link); dns_dnsseckey_destroy(mctx, &key); } if (tempfilelen != 0) isc_mem_put(mctx, tempfile, tempfilelen); if (free_output) isc_mem_free(mctx, output); dns_master_styledestroy(&dsstyle, mctx); cleanup_logging(&log); dst_lib_destroy(); isc_hash_destroy(); cleanup_entropy(&ectx); dns_name_destroy(); if (verbose > 10) isc_mem_stats(mctx, stdout); isc_mem_destroy(&mctx); (void) isc_app_finish(); if (printstats) { TIME_NOW(&timer_finish); print_stats(&timer_start, &timer_finish, &sign_start, &sign_finish); } return (0); } bind9-9.10.3.dfsg.P4/bin/dnssec/dnssectool.c0000644000470500017500000014753512664710322017760 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ /*% * DNSSEC Support Routines. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dnssectool.h" static isc_heap_t *expected_chains, *found_chains; struct nsec3_chain_fixed { isc_uint8_t hash; isc_uint8_t salt_length; isc_uint8_t next_length; isc_uint16_t iterations; /* unsigned char salt[0]; */ /* unsigned char owner[0]; */ /* unsigned char next[0]; */ }; extern int verbose; extern const char *program; typedef struct entropysource entropysource_t; struct entropysource { isc_entropysource_t *source; isc_mem_t *mctx; ISC_LINK(entropysource_t) link; }; static ISC_LIST(entropysource_t) sources; static fatalcallback_t *fatalcallback = NULL; void fatal(const char *format, ...) { va_list args; fprintf(stderr, "%s: fatal: ", program); va_start(args, format); vfprintf(stderr, format, args); va_end(args); fprintf(stderr, "\n"); if (fatalcallback != NULL) (*fatalcallback)(); exit(1); } void setfatalcallback(fatalcallback_t *callback) { fatalcallback = callback; } void check_result(isc_result_t result, const char *message) { if (result != ISC_R_SUCCESS) fatal("%s: %s", message, isc_result_totext(result)); } void vbprintf(int level, const char *fmt, ...) { va_list ap; if (level > verbose) return; va_start(ap, fmt); fprintf(stderr, "%s: ", program); vfprintf(stderr, fmt, ap); va_end(ap); } void version(const char *name) { fprintf(stderr, "%s %s\n", name, VERSION); exit(0); } void type_format(const dns_rdatatype_t type, char *cp, unsigned int size) { isc_buffer_t b; isc_region_t r; isc_result_t result; isc_buffer_init(&b, cp, size - 1); result = dns_rdatatype_totext(type, &b); check_result(result, "dns_rdatatype_totext()"); isc_buffer_usedregion(&b, &r); r.base[r.length] = 0; } void sig_format(dns_rdata_rrsig_t *sig, char *cp, unsigned int size) { char namestr[DNS_NAME_FORMATSIZE]; char algstr[DNS_NAME_FORMATSIZE]; dns_name_format(&sig->signer, namestr, sizeof(namestr)); dns_secalg_format(sig->algorithm, algstr, sizeof(algstr)); snprintf(cp, size, "%s/%s/%d", namestr, algstr, sig->keyid); } void setup_logging(isc_mem_t *mctx, isc_log_t **logp) { isc_result_t result; isc_logdestination_t destination; isc_logconfig_t *logconfig = NULL; isc_log_t *log = NULL; int level; if (verbose < 0) verbose = 0; switch (verbose) { case 0: /* * We want to see warnings about things like out-of-zone * data in the master file even when not verbose. */ level = ISC_LOG_WARNING; break; case 1: level = ISC_LOG_INFO; break; default: level = ISC_LOG_DEBUG(verbose - 2 + 1); break; } RUNTIME_CHECK(isc_log_create(mctx, &log, &logconfig) == ISC_R_SUCCESS); isc_log_setcontext(log); dns_log_init(log); dns_log_setcontext(log); RUNTIME_CHECK(isc_log_settag(logconfig, program) == ISC_R_SUCCESS); /* * Set up a channel similar to default_stderr except: * - the logging level is passed in * - the program name and logging level are printed * - no time stamp is printed */ destination.file.stream = stderr; destination.file.name = NULL; destination.file.versions = ISC_LOG_ROLLNEVER; destination.file.maximum_size = 0; result = isc_log_createchannel(logconfig, "stderr", ISC_LOG_TOFILEDESC, level, &destination, ISC_LOG_PRINTTAG|ISC_LOG_PRINTLEVEL); check_result(result, "isc_log_createchannel()"); RUNTIME_CHECK(isc_log_usechannel(logconfig, "stderr", NULL, NULL) == ISC_R_SUCCESS); *logp = log; } void cleanup_logging(isc_log_t **logp) { isc_log_t *log; REQUIRE(logp != NULL); log = *logp; if (log == NULL) return; isc_log_destroy(&log); isc_log_setcontext(NULL); dns_log_setcontext(NULL); logp = NULL; } void setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx) { isc_result_t result; isc_entropysource_t *source = NULL; entropysource_t *elt; int usekeyboard = ISC_ENTROPY_KEYBOARDMAYBE; REQUIRE(ectx != NULL); if (*ectx == NULL) { result = isc_entropy_create(mctx, ectx); if (result != ISC_R_SUCCESS) fatal("could not create entropy object"); ISC_LIST_INIT(sources); } if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) { usekeyboard = ISC_ENTROPY_KEYBOARDYES; randomfile = NULL; } result = isc_entropy_usebestsource(*ectx, &source, randomfile, usekeyboard); if (result != ISC_R_SUCCESS) fatal("could not initialize entropy source: %s", isc_result_totext(result)); if (source != NULL) { elt = isc_mem_get(mctx, sizeof(*elt)); if (elt == NULL) fatal("out of memory"); elt->source = source; elt->mctx = mctx; ISC_LINK_INIT(elt, link); ISC_LIST_APPEND(sources, elt, link); } } void cleanup_entropy(isc_entropy_t **ectx) { entropysource_t *source; while (!ISC_LIST_EMPTY(sources)) { source = ISC_LIST_HEAD(sources); ISC_LIST_UNLINK(sources, source, link); isc_entropy_destroysource(&source->source); isc_mem_put(source->mctx, source, sizeof(*source)); } isc_entropy_detach(ectx); } static isc_stdtime_t time_units(isc_stdtime_t offset, char *suffix, const char *str) { switch (suffix[0]) { case 'Y': case 'y': return (offset * (365 * 24 * 3600)); case 'M': case 'm': switch (suffix[1]) { case 'O': case 'o': return (offset * (30 * 24 * 3600)); case 'I': case 'i': return (offset * 60); case '\0': fatal("'%s' ambiguous: use 'mi' for minutes " "or 'mo' for months", str); default: fatal("time value %s is invalid", str); } /* NOTREACHED */ break; case 'W': case 'w': return (offset * (7 * 24 * 3600)); case 'D': case 'd': return (offset * (24 * 3600)); case 'H': case 'h': return (offset * 3600); case 'S': case 's': case '\0': return (offset); default: fatal("time value %s is invalid", str); } /* NOTREACHED */ return(0); /* silence compiler warning */ } static inline isc_boolean_t isnone(const char *str) { return (ISC_TF((strcasecmp(str, "none") == 0) || (strcasecmp(str, "never") == 0))); } dns_ttl_t strtottl(const char *str) { const char *orig = str; dns_ttl_t ttl; char *endp; if (isnone(str)) return ((dns_ttl_t) 0); ttl = strtol(str, &endp, 0); if (ttl == 0 && endp == str) fatal("TTL must be numeric"); ttl = time_units(ttl, endp, orig); return (ttl); } isc_stdtime_t strtotime(const char *str, isc_int64_t now, isc_int64_t base, isc_boolean_t *setp) { isc_int64_t val, offset; isc_result_t result; const char *orig = str; char *endp; size_t n; if (isnone(str)) { if (setp != NULL) *setp = ISC_FALSE; return ((isc_stdtime_t) 0); } if (setp != NULL) *setp = ISC_TRUE; if ((str[0] == '0' || str[0] == '-') && str[1] == '\0') return ((isc_stdtime_t) 0); /* * We accept times in the following formats: * now([+-]offset) * YYYYMMDD([+-]offset) * YYYYMMDDhhmmss([+-]offset) * [+-]offset */ n = strspn(str, "0123456789"); if ((n == 8u || n == 14u) && (str[n] == '\0' || str[n] == '-' || str[n] == '+')) { char timestr[15]; strlcpy(timestr, str, sizeof(timestr)); timestr[n] = 0; if (n == 8u) strlcat(timestr, "000000", sizeof(timestr)); result = dns_time64_fromtext(timestr, &val); if (result != ISC_R_SUCCESS) fatal("time value %s is invalid: %s", orig, isc_result_totext(result)); base = val; str += n; } else if (strncmp(str, "now", 3) == 0) { base = now; str += 3; } if (str[0] == '\0') return ((isc_stdtime_t) base); else if (str[0] == '+') { offset = strtol(str + 1, &endp, 0); offset = time_units((isc_stdtime_t) offset, endp, orig); val = base + offset; } else if (str[0] == '-') { offset = strtol(str + 1, &endp, 0); offset = time_units((isc_stdtime_t) offset, endp, orig); val = base - offset; } else fatal("time value %s is invalid", orig); return ((isc_stdtime_t) val); } dns_rdataclass_t strtoclass(const char *str) { isc_textregion_t r; dns_rdataclass_t rdclass; isc_result_t ret; if (str == NULL) return dns_rdataclass_in; DE_CONST(str, r.base); r.length = strlen(str); ret = dns_rdataclass_fromtext(&rdclass, &r); if (ret != ISC_R_SUCCESS) fatal("unknown class %s", str); return (rdclass); } isc_result_t try_dir(const char *dirname) { isc_result_t result; isc_dir_t d; isc_dir_init(&d); result = isc_dir_open(&d, dirname); if (result == ISC_R_SUCCESS) { isc_dir_close(&d); } return (result); } /* * Check private key version compatibility. */ void check_keyversion(dst_key_t *key, char *keystr) { int major, minor; dst_key_getprivateformat(key, &major, &minor); INSIST(major <= DST_MAJOR_VERSION); /* invalid private key */ if (major < DST_MAJOR_VERSION || minor < DST_MINOR_VERSION) fatal("Key %s has incompatible format version %d.%d, " "use -f to force upgrade to new version.", keystr, major, minor); if (minor > DST_MINOR_VERSION) fatal("Key %s has incompatible format version %d.%d, " "use -f to force downgrade to current version.", keystr, major, minor); } void set_keyversion(dst_key_t *key) { int major, minor; dst_key_getprivateformat(key, &major, &minor); INSIST(major <= DST_MAJOR_VERSION); if (major != DST_MAJOR_VERSION || minor != DST_MINOR_VERSION) dst_key_setprivateformat(key, DST_MAJOR_VERSION, DST_MINOR_VERSION); /* * If the key is from a version older than 1.3, set * set the creation date */ if (major < 1 || (major == 1 && minor <= 2)) { isc_stdtime_t now; isc_stdtime_get(&now); dst_key_settime(key, DST_TIME_CREATED, now); } } isc_boolean_t key_collision(dst_key_t *dstkey, dns_name_t *name, const char *dir, isc_mem_t *mctx, isc_boolean_t *exact) { isc_result_t result; isc_boolean_t conflict = ISC_FALSE; dns_dnsseckeylist_t matchkeys; dns_dnsseckey_t *key = NULL; isc_uint16_t id, oldid; isc_uint32_t rid, roldid; dns_secalg_t alg; if (exact != NULL) *exact = ISC_FALSE; id = dst_key_id(dstkey); rid = dst_key_rid(dstkey); alg = dst_key_alg(dstkey); ISC_LIST_INIT(matchkeys); result = dns_dnssec_findmatchingkeys(name, dir, mctx, &matchkeys); if (result == ISC_R_NOTFOUND) return (ISC_FALSE); while (!ISC_LIST_EMPTY(matchkeys) && !conflict) { key = ISC_LIST_HEAD(matchkeys); if (dst_key_alg(key->key) != alg) goto next; oldid = dst_key_id(key->key); roldid = dst_key_rid(key->key); if (oldid == rid || roldid == id || id == oldid) { conflict = ISC_TRUE; if (id != oldid) { if (verbose > 1) fprintf(stderr, "Key ID %d could " "collide with %d\n", id, oldid); } else { if (exact != NULL) *exact = ISC_TRUE; if (verbose > 1) fprintf(stderr, "Key ID %d exists\n", id); } } next: ISC_LIST_UNLINK(matchkeys, key, link); dns_dnsseckey_destroy(mctx, &key); } /* Finish freeing the list */ while (!ISC_LIST_EMPTY(matchkeys)) { key = ISC_LIST_HEAD(matchkeys); ISC_LIST_UNLINK(matchkeys, key, link); dns_dnsseckey_destroy(mctx, &key); } return (conflict); } isc_boolean_t is_delegation(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin, dns_name_t *name, dns_dbnode_t *node, isc_uint32_t *ttlp) { dns_rdataset_t nsset; isc_result_t result; if (dns_name_equal(name, origin)) return (ISC_FALSE); dns_rdataset_init(&nsset); result = dns_db_findrdataset(db, node, ver, dns_rdatatype_ns, 0, 0, &nsset, NULL); if (dns_rdataset_isassociated(&nsset)) { if (ttlp != NULL) *ttlp = nsset.ttl; dns_rdataset_disassociate(&nsset); } return (ISC_TF(result == ISC_R_SUCCESS)); } static isc_boolean_t goodsig(dns_name_t *origin, dns_rdata_t *sigrdata, dns_name_t *name, dns_rdataset_t *keyrdataset, dns_rdataset_t *rdataset, isc_mem_t *mctx) { dns_rdata_dnskey_t key; dns_rdata_rrsig_t sig; dst_key_t *dstkey = NULL; isc_result_t result; result = dns_rdata_tostruct(sigrdata, &sig, NULL); check_result(result, "dns_rdata_tostruct()"); for (result = dns_rdataset_first(keyrdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(keyrdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(keyrdataset, &rdata); result = dns_rdata_tostruct(&rdata, &key, NULL); check_result(result, "dns_rdata_tostruct()"); result = dns_dnssec_keyfromrdata(origin, &rdata, mctx, &dstkey); if (result != ISC_R_SUCCESS) return (ISC_FALSE); if (sig.algorithm != key.algorithm || sig.keyid != dst_key_id(dstkey) || !dns_name_equal(&sig.signer, origin)) { dst_key_free(&dstkey); continue; } result = dns_dnssec_verify(name, rdataset, dstkey, ISC_FALSE, mctx, sigrdata); dst_key_free(&dstkey); if (result == ISC_R_SUCCESS) return(ISC_TRUE); } return (ISC_FALSE); } static isc_result_t verifynsec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_dbnode_t *node, dns_name_t *nextname) { unsigned char buffer[DNS_NSEC_BUFFERSIZE]; char namebuf[DNS_NAME_FORMATSIZE]; char nextbuf[DNS_NAME_FORMATSIZE]; char found[DNS_NAME_FORMATSIZE]; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_t tmprdata = DNS_RDATA_INIT; dns_rdata_nsec_t nsec; isc_result_t result; dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) { dns_name_format(name, namebuf, sizeof(namebuf)); fprintf(stderr, "Missing NSEC record for %s\n", namebuf); goto failure; } result = dns_rdataset_first(&rdataset); check_result(result, "dns_rdataset_first()"); dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &nsec, NULL); check_result(result, "dns_rdata_tostruct()"); /* Check bit next name is consistent */ if (!dns_name_equal(&nsec.next, nextname)) { dns_name_format(name, namebuf, sizeof(namebuf)); dns_name_format(nextname, nextbuf, sizeof(nextbuf)); dns_name_format(&nsec.next, found, sizeof(found)); fprintf(stderr, "Bad NSEC record for %s, next name " "mismatch (expected:%s, found:%s)\n", namebuf, nextbuf, found); goto failure; } /* Check bit map is consistent */ result = dns_nsec_buildrdata(db, ver, node, nextname, buffer, &tmprdata); check_result(result, "dns_nsec_buildrdata()"); if (dns_rdata_compare(&rdata, &tmprdata) != 0) { dns_name_format(name, namebuf, sizeof(namebuf)); fprintf(stderr, "Bad NSEC record for %s, bit map " "mismatch\n", namebuf); goto failure; } result = dns_rdataset_next(&rdataset); if (result != ISC_R_NOMORE) { dns_name_format(name, namebuf, sizeof(namebuf)); fprintf(stderr, "Multipe NSEC records for %s\n", namebuf); goto failure; } dns_rdataset_disassociate(&rdataset); return (ISC_R_SUCCESS); failure: if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); return (ISC_R_FAILURE); } static void check_no_rrsig(dns_db_t *db, dns_dbversion_t *ver, dns_rdataset_t *rdataset, dns_name_t *name, dns_dbnode_t *node) { char namebuf[DNS_NAME_FORMATSIZE]; char typebuf[80]; dns_rdataset_t sigrdataset; dns_rdatasetiter_t *rdsiter = NULL; isc_result_t result; dns_rdataset_init(&sigrdataset); result = dns_db_allrdatasets(db, node, ver, 0, &rdsiter); check_result(result, "dns_db_allrdatasets()"); for (result = dns_rdatasetiter_first(rdsiter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsiter)) { dns_rdatasetiter_current(rdsiter, &sigrdataset); if (sigrdataset.type == dns_rdatatype_rrsig && sigrdataset.covers == rdataset->type) break; dns_rdataset_disassociate(&sigrdataset); } if (result == ISC_R_SUCCESS) { dns_name_format(name, namebuf, sizeof(namebuf)); type_format(rdataset->type, typebuf, sizeof(typebuf)); fprintf(stderr, "Warning: Found unexpected signatures for " "%s/%s\n", namebuf, typebuf); } if (dns_rdataset_isassociated(&sigrdataset)) dns_rdataset_disassociate(&sigrdataset); dns_rdatasetiter_destroy(&rdsiter); } static isc_boolean_t chain_compare(void *arg1, void *arg2) { struct nsec3_chain_fixed *e1 = arg1, *e2 = arg2; size_t len; /* * Do each element in turn to get a stable sort. */ if (e1->hash < e2->hash) return (ISC_TRUE); if (e1->hash > e2->hash) return (ISC_FALSE); if (e1->iterations < e2->iterations) return (ISC_TRUE); if (e1->iterations > e2->iterations) return (ISC_FALSE); if (e1->salt_length < e2->salt_length) return (ISC_TRUE); if (e1->salt_length > e2->salt_length) return (ISC_FALSE); if (e1->next_length < e2->next_length) return (ISC_TRUE); if (e1->next_length > e2->next_length) return (ISC_FALSE); len = e1->salt_length + 2 * e1->next_length; if (memcmp(e1 + 1, e2 + 1, len) < 0) return (ISC_TRUE); return (ISC_FALSE); } static isc_boolean_t chain_equal(struct nsec3_chain_fixed *e1, struct nsec3_chain_fixed *e2) { size_t len; if (e1->hash != e2->hash) return (ISC_FALSE); if (e1->iterations != e2->iterations) return (ISC_FALSE); if (e1->salt_length != e2->salt_length) return (ISC_FALSE); if (e1->next_length != e2->next_length) return (ISC_FALSE); len = e1->salt_length + 2 * e1->next_length; if (memcmp(e1 + 1, e2 + 1, len) != 0) return (ISC_FALSE); return (ISC_TRUE); } static isc_result_t record_nsec3(const unsigned char *rawhash, const dns_rdata_nsec3_t *nsec3, isc_mem_t *mctx, isc_heap_t *chains) { struct nsec3_chain_fixed *element; size_t len; unsigned char *cp; isc_result_t result; len = sizeof(*element) + nsec3->next_length * 2 + nsec3->salt_length; element = isc_mem_get(mctx, len); if (element == NULL) return (ISC_R_NOMEMORY); memset(element, 0, len); element->hash = nsec3->hash; element->salt_length = nsec3->salt_length; element->next_length = nsec3->next_length; element->iterations = nsec3->iterations; cp = (unsigned char *)(element + 1); memmove(cp, nsec3->salt, nsec3->salt_length); cp += nsec3->salt_length; memmove(cp, rawhash, nsec3->next_length); cp += nsec3->next_length; memmove(cp, nsec3->next, nsec3->next_length); result = isc_heap_insert(chains, element); if (result != ISC_R_SUCCESS) { fprintf(stderr, "isc_heap_insert failed: %s\n", isc_result_totext(result)); isc_mem_put(mctx, element, len); } return (result); } static isc_result_t match_nsec3(dns_name_t *name, isc_mem_t *mctx, dns_rdata_nsec3param_t *nsec3param, dns_rdataset_t *rdataset, unsigned char types[8192], unsigned int maxtype, unsigned char *rawhash, size_t rhsize) { unsigned char cbm[8244]; char namebuf[DNS_NAME_FORMATSIZE]; dns_rdata_nsec3_t nsec3; isc_result_t result; unsigned int len; /* * Find matching NSEC3 record. */ for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &nsec3, NULL); check_result(result, "dns_rdata_tostruct()"); if (nsec3.hash == nsec3param->hash && nsec3.next_length == rhsize && nsec3.iterations == nsec3param->iterations && nsec3.salt_length == nsec3param->salt_length && memcmp(nsec3.salt, nsec3param->salt, nsec3param->salt_length) == 0) break; } if (result != ISC_R_SUCCESS) { dns_name_format(name, namebuf, sizeof(namebuf)); fprintf(stderr, "Missing NSEC3 record for %s\n", namebuf); return (result); } /* * Check the type list. */ len = dns_nsec_compressbitmap(cbm, types, maxtype); if (nsec3.len != len || memcmp(cbm, nsec3.typebits, len) != 0) { dns_name_format(name, namebuf, sizeof(namebuf)); fprintf(stderr, "Bad NSEC3 record for %s, bit map " "mismatch\n", namebuf); return (ISC_R_FAILURE); } /* * Record chain. */ result = record_nsec3(rawhash, &nsec3, mctx, expected_chains); check_result(result, "record_nsec3()"); /* * Make sure there is only one NSEC3 record with this set of * parameters. */ for (result = dns_rdataset_next(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &nsec3, NULL); check_result(result, "dns_rdata_tostruct()"); if (nsec3.hash == nsec3param->hash && nsec3.iterations == nsec3param->iterations && nsec3.salt_length == nsec3param->salt_length && memcmp(nsec3.salt, nsec3param->salt, nsec3.salt_length) == 0) { dns_name_format(name, namebuf, sizeof(namebuf)); fprintf(stderr, "Multiple NSEC3 records with the " "same parameter set for %s", namebuf); result = DNS_R_DUPLICATE; break; } } if (result != ISC_R_NOMORE) return (result); result = ISC_R_SUCCESS; return (result); } static isc_boolean_t innsec3params(dns_rdata_nsec3_t *nsec3, dns_rdataset_t *nsec3paramset) { dns_rdata_nsec3param_t nsec3param; isc_result_t result; for (result = dns_rdataset_first(nsec3paramset); result == ISC_R_SUCCESS; result = dns_rdataset_next(nsec3paramset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(nsec3paramset, &rdata); result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); check_result(result, "dns_rdata_tostruct()"); if (nsec3param.flags == 0 && nsec3param.hash == nsec3->hash && nsec3param.iterations == nsec3->iterations && nsec3param.salt_length == nsec3->salt_length && memcmp(nsec3param.salt, nsec3->salt, nsec3->salt_length) == 0) return (ISC_TRUE); } return (ISC_FALSE); } static isc_result_t record_found(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx, dns_name_t *name, dns_dbnode_t *node, dns_rdataset_t *nsec3paramset) { unsigned char owner[NSEC3_MAX_HASH_LENGTH]; dns_rdata_nsec3_t nsec3; dns_rdataset_t rdataset; dns_label_t hashlabel; isc_buffer_t b; isc_result_t result; if (nsec3paramset == NULL || !dns_rdataset_isassociated(nsec3paramset)) return (ISC_R_SUCCESS); dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, 0, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) return (ISC_R_SUCCESS); dns_name_getlabel(name, 0, &hashlabel); isc_region_consume(&hashlabel, 1); isc_buffer_init(&b, owner, sizeof(owner)); result = isc_base32hex_decoderegion(&hashlabel, &b); if (result != ISC_R_SUCCESS) goto cleanup; for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &nsec3, NULL); check_result(result, "dns_rdata_tostruct()"); if (nsec3.next_length != isc_buffer_usedlength(&b)) continue; /* * We only care about NSEC3 records that match a NSEC3PARAM * record. */ if (!innsec3params(&nsec3, nsec3paramset)) continue; /* * Record chain. */ result = record_nsec3(owner, &nsec3, mctx, found_chains); check_result(result, "record_nsec3()"); } cleanup: dns_rdataset_disassociate(&rdataset); return (ISC_R_SUCCESS); } static isc_boolean_t isoptout(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin, dns_rdata_t *nsec3rdata) { dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_nsec3_t nsec3; dns_rdata_nsec3param_t nsec3param; dns_fixedname_t fixed; dns_name_t *hashname; isc_result_t result; dns_dbnode_t *node = NULL; unsigned char rawhash[NSEC3_MAX_HASH_LENGTH]; size_t rhsize = sizeof(rawhash); isc_boolean_t ret; result = dns_rdata_tostruct(nsec3rdata, &nsec3param, NULL); check_result(result, "dns_rdata_tostruct()"); dns_fixedname_init(&fixed); result = dns_nsec3_hashname(&fixed, rawhash, &rhsize, origin, origin, nsec3param.hash, nsec3param.iterations, nsec3param.salt, nsec3param.salt_length); check_result(result, "dns_nsec3_hashname()"); dns_rdataset_init(&rdataset); hashname = dns_fixedname_name(&fixed); result = dns_db_findnsec3node(db, hashname, ISC_FALSE, &node); if (result == ISC_R_SUCCESS) result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, 0, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) return (ISC_FALSE); result = dns_rdataset_first(&rdataset); check_result(result, "dns_rdataset_first()"); dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &nsec3, NULL); if (result != ISC_R_SUCCESS) ret = ISC_FALSE; else ret = ISC_TF((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0); if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (node != NULL) dns_db_detachnode(db, &node); return (ret); } static isc_result_t verifynsec3(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin, isc_mem_t *mctx, dns_name_t *name, dns_rdata_t *rdata, isc_boolean_t delegation, isc_boolean_t empty, unsigned char types[8192], unsigned int maxtype) { char namebuf[DNS_NAME_FORMATSIZE]; char hashbuf[DNS_NAME_FORMATSIZE]; dns_rdataset_t rdataset; dns_rdata_nsec3param_t nsec3param; dns_fixedname_t fixed; dns_name_t *hashname; isc_result_t result; dns_dbnode_t *node = NULL; unsigned char rawhash[NSEC3_MAX_HASH_LENGTH]; size_t rhsize = sizeof(rawhash); isc_boolean_t optout; result = dns_rdata_tostruct(rdata, &nsec3param, NULL); check_result(result, "dns_rdata_tostruct()"); if (nsec3param.flags != 0) return (ISC_R_SUCCESS); if (!dns_nsec3_supportedhash(nsec3param.hash)) return (ISC_R_SUCCESS); optout = isoptout(db, ver, origin, rdata); dns_fixedname_init(&fixed); result = dns_nsec3_hashname(&fixed, rawhash, &rhsize, name, origin, nsec3param.hash, nsec3param.iterations, nsec3param.salt, nsec3param.salt_length); check_result(result, "dns_nsec3_hashname()"); /* * We don't use dns_db_find() here as it works with the choosen * nsec3 chain and we may also be called with uncommitted data * from dnssec-signzone so the secure status of the zone may not * be up to date. */ dns_rdataset_init(&rdataset); hashname = dns_fixedname_name(&fixed); result = dns_db_findnsec3node(db, hashname, ISC_FALSE, &node); if (result == ISC_R_SUCCESS) result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, 0, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS && (!delegation || (empty && !optout) || (!empty && dns_nsec_isset(types, dns_rdatatype_ds)))) { dns_name_format(name, namebuf, sizeof(namebuf)); dns_name_format(hashname, hashbuf, sizeof(hashbuf)); fprintf(stderr, "Missing NSEC3 record for %s (%s)\n", namebuf, hashbuf); } else if (result == ISC_R_NOTFOUND && delegation && (!empty || optout)) { result = ISC_R_SUCCESS; } else if (result == ISC_R_SUCCESS) { result = match_nsec3(name, mctx, &nsec3param, &rdataset, types, maxtype, rawhash, rhsize); } if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (node != NULL) dns_db_detachnode(db, &node); return (result); } static isc_result_t verifynsec3s(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin, isc_mem_t *mctx, dns_name_t *name, dns_rdataset_t *nsec3paramset, isc_boolean_t delegation, isc_boolean_t empty, unsigned char types[8192], unsigned int maxtype) { isc_result_t result; for (result = dns_rdataset_first(nsec3paramset); result == ISC_R_SUCCESS; result = dns_rdataset_next(nsec3paramset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(nsec3paramset, &rdata); result = verifynsec3(db, ver, origin, mctx, name, &rdata, delegation, empty, types, maxtype); if (result != ISC_R_SUCCESS) break; } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; return (result); } static void verifyset(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin, isc_mem_t *mctx, dns_rdataset_t *rdataset, dns_name_t *name, dns_dbnode_t *node, dns_rdataset_t *keyrdataset, unsigned char *act_algorithms, unsigned char *bad_algorithms) { unsigned char set_algorithms[256]; char namebuf[DNS_NAME_FORMATSIZE]; char algbuf[80]; char typebuf[80]; dns_rdataset_t sigrdataset; dns_rdatasetiter_t *rdsiter = NULL; isc_result_t result; int i; dns_rdataset_init(&sigrdataset); result = dns_db_allrdatasets(db, node, ver, 0, &rdsiter); check_result(result, "dns_db_allrdatasets()"); for (result = dns_rdatasetiter_first(rdsiter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsiter)) { dns_rdatasetiter_current(rdsiter, &sigrdataset); if (sigrdataset.type == dns_rdatatype_rrsig && sigrdataset.covers == rdataset->type) break; dns_rdataset_disassociate(&sigrdataset); } if (result != ISC_R_SUCCESS) { dns_name_format(name, namebuf, sizeof(namebuf)); type_format(rdataset->type, typebuf, sizeof(typebuf)); fprintf(stderr, "No signatures for %s/%s\n", namebuf, typebuf); for (i = 0; i < 256; i++) if (act_algorithms[i] != 0) bad_algorithms[i] = 1; dns_rdatasetiter_destroy(&rdsiter); return; } memset(set_algorithms, 0, sizeof(set_algorithms)); for (result = dns_rdataset_first(&sigrdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&sigrdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_rrsig_t sig; dns_rdataset_current(&sigrdataset, &rdata); result = dns_rdata_tostruct(&rdata, &sig, NULL); check_result(result, "dns_rdata_tostruct()"); if (rdataset->ttl != sig.originalttl) { dns_name_format(name, namebuf, sizeof(namebuf)); type_format(rdataset->type, typebuf, sizeof(typebuf)); fprintf(stderr, "TTL mismatch for %s %s keytag %u\n", namebuf, typebuf, sig.keyid); continue; } if ((set_algorithms[sig.algorithm] != 0) || (act_algorithms[sig.algorithm] == 0)) continue; if (goodsig(origin, &rdata, name, keyrdataset, rdataset, mctx)) set_algorithms[sig.algorithm] = 1; } dns_rdatasetiter_destroy(&rdsiter); if (memcmp(set_algorithms, act_algorithms, sizeof(set_algorithms))) { dns_name_format(name, namebuf, sizeof(namebuf)); type_format(rdataset->type, typebuf, sizeof(typebuf)); for (i = 0; i < 256; i++) if ((act_algorithms[i] != 0) && (set_algorithms[i] == 0)) { dns_secalg_format(i, algbuf, sizeof(algbuf)); fprintf(stderr, "No correct %s signature for " "%s %s\n", algbuf, namebuf, typebuf); bad_algorithms[i] = 1; } } dns_rdataset_disassociate(&sigrdataset); } static isc_result_t verifynode(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin, isc_mem_t *mctx, dns_name_t *name, dns_dbnode_t *node, isc_boolean_t delegation, dns_rdataset_t *keyrdataset, unsigned char *act_algorithms, unsigned char *bad_algorithms, dns_rdataset_t *nsecset, dns_rdataset_t *nsec3paramset, dns_name_t *nextname) { unsigned char types[8192]; unsigned int maxtype = 0; dns_rdataset_t rdataset; dns_rdatasetiter_t *rdsiter = NULL; isc_result_t result, tresult; memset(types, 0, sizeof(types)); result = dns_db_allrdatasets(db, node, ver, 0, &rdsiter); check_result(result, "dns_db_allrdatasets()"); result = dns_rdatasetiter_first(rdsiter); dns_rdataset_init(&rdataset); while (result == ISC_R_SUCCESS) { dns_rdatasetiter_current(rdsiter, &rdataset); /* * If we are not at a delegation then everything should be * signed. If we are at a delegation then only the DS set * is signed. The NS set is not signed at a delegation but * its existance is recorded in the bit map. Anything else * other than NSEC and DS is not signed at a delegation. */ if (rdataset.type != dns_rdatatype_rrsig && rdataset.type != dns_rdatatype_dnskey && (!delegation || rdataset.type == dns_rdatatype_ds || rdataset.type == dns_rdatatype_nsec)) { verifyset(db, ver, origin, mctx, &rdataset, name, node, keyrdataset, act_algorithms, bad_algorithms); dns_nsec_setbit(types, rdataset.type, 1); if (rdataset.type > maxtype) maxtype = rdataset.type; } else if (rdataset.type != dns_rdatatype_rrsig && rdataset.type != dns_rdatatype_dnskey) { if (rdataset.type == dns_rdatatype_ns) dns_nsec_setbit(types, rdataset.type, 1); check_no_rrsig(db, ver, &rdataset, name, node); } else dns_nsec_setbit(types, rdataset.type, 1); dns_rdataset_disassociate(&rdataset); result = dns_rdatasetiter_next(rdsiter); } if (result != ISC_R_NOMORE) fatal("rdataset iteration failed: %s", isc_result_totext(result)); dns_rdatasetiter_destroy(&rdsiter); result = ISC_R_SUCCESS; if (nsecset != NULL && dns_rdataset_isassociated(nsecset)) result = verifynsec(db, ver, name, node, nextname); if (nsec3paramset != NULL && dns_rdataset_isassociated(nsec3paramset)) { tresult = verifynsec3s(db, ver, origin, mctx, name, nsec3paramset, delegation, ISC_FALSE, types, maxtype); if (result == ISC_R_SUCCESS && tresult != ISC_R_SUCCESS) result = tresult; } return (result); } static isc_boolean_t is_empty(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node) { dns_rdatasetiter_t *rdsiter = NULL; isc_result_t result; result = dns_db_allrdatasets(db, node, ver, 0, &rdsiter); check_result(result, "dns_db_allrdatasets()"); result = dns_rdatasetiter_first(rdsiter); dns_rdatasetiter_destroy(&rdsiter); if (result == ISC_R_NOMORE) return (ISC_TRUE); return (ISC_FALSE); } static void check_no_nsec(dns_name_t *name, dns_dbnode_t *node, dns_db_t *db, dns_dbversion_t *ver) { dns_rdataset_t rdataset; isc_result_t result; dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, 0, &rdataset, NULL); if (result != ISC_R_NOTFOUND) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(name, namebuf, sizeof(namebuf)); fatal("unexpected NSEC RRset at %s\n", namebuf); } if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); } static isc_boolean_t newchain(const struct nsec3_chain_fixed *first, const struct nsec3_chain_fixed *e) { if (first->hash != e->hash || first->iterations != e->iterations || first->salt_length != e->salt_length || first->next_length != e->next_length || memcmp(first + 1, e + 1, first->salt_length) != 0) return (ISC_TRUE); return (ISC_FALSE); } static void free_element(isc_mem_t *mctx, struct nsec3_chain_fixed *e) { size_t len; len = sizeof(*e) + e->salt_length + 2 * e->next_length; isc_mem_put(mctx, e, len); } static isc_boolean_t checknext(const struct nsec3_chain_fixed *first, const struct nsec3_chain_fixed *e) { char buf[512]; const unsigned char *d1 = (const unsigned char *)(first + 1); const unsigned char *d2 = (const unsigned char *)(e + 1); isc_buffer_t b; isc_region_t sr; d1 += first->salt_length + first->next_length; d2 += e->salt_length; if (memcmp(d1, d2, first->next_length) == 0) return (ISC_TRUE); DE_CONST(d1 - first->next_length, sr.base); sr.length = first->next_length; isc_buffer_init(&b, buf, sizeof(buf)); isc_base32hex_totext(&sr, 1, "", &b); fprintf(stderr, "Break in NSEC3 chain at: %.*s\n", (int) isc_buffer_usedlength(&b), buf); DE_CONST(d1, sr.base); sr.length = first->next_length; isc_buffer_init(&b, buf, sizeof(buf)); isc_base32hex_totext(&sr, 1, "", &b); fprintf(stderr, "Expected: %.*s\n", (int) isc_buffer_usedlength(&b), buf); DE_CONST(d2, sr.base); sr.length = first->next_length; isc_buffer_init(&b, buf, sizeof(buf)); isc_base32hex_totext(&sr, 1, "", &b); fprintf(stderr, "Found: %.*s\n", (int) isc_buffer_usedlength(&b), buf); return (ISC_FALSE); } #define EXPECTEDANDFOUND "Expected and found NSEC3 chains not equal\n" static isc_result_t verify_nsec3_chains(isc_mem_t *mctx) { isc_result_t result = ISC_R_SUCCESS; struct nsec3_chain_fixed *e, *f = NULL; struct nsec3_chain_fixed *first = NULL, *prev = NULL; while ((e = isc_heap_element(expected_chains, 1)) != NULL) { isc_heap_delete(expected_chains, 1); if (f == NULL) f = isc_heap_element(found_chains, 1); if (f != NULL) { isc_heap_delete(found_chains, 1); /* * Check that they match. */ if (chain_equal(e, f)) { free_element(mctx, f); f = NULL; } else { if (result == ISC_R_SUCCESS) fprintf(stderr, EXPECTEDANDFOUND); result = ISC_R_FAILURE; /* * Attempt to resync found_chain. */ while (f != NULL && !chain_compare(e, f)) { free_element(mctx, f); f = isc_heap_element(found_chains, 1); if (f != NULL) isc_heap_delete(found_chains, 1); if (f != NULL && chain_equal(e, f)) { free_element(mctx, f); f = NULL; break; } } } } else if (result == ISC_R_SUCCESS) { fprintf(stderr, EXPECTEDANDFOUND); result = ISC_R_FAILURE; } if (first == NULL || newchain(first, e)) { if (prev != NULL) { if (!checknext(prev, first)) result = ISC_R_FAILURE; if (prev != first) free_element(mctx, prev); } if (first != NULL) free_element(mctx, first); prev = first = e; continue; } if (!checknext(prev, e)) result = ISC_R_FAILURE; if (prev != first) free_element(mctx, prev); prev = e; } if (prev != NULL) { if (!checknext(prev, first)) result = ISC_R_FAILURE; if (prev != first) free_element(mctx, prev); } if (first != NULL) free_element(mctx, first); do { if (f != NULL) { if (result == ISC_R_SUCCESS) { fprintf(stderr, EXPECTEDANDFOUND); result = ISC_R_FAILURE; } free_element(mctx, f); } f = isc_heap_element(found_chains, 1); if (f != NULL) isc_heap_delete(found_chains, 1); } while (f != NULL); return (result); } static isc_result_t verifyemptynodes(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin, isc_mem_t *mctx, dns_name_t *name, dns_name_t *prevname, isc_boolean_t isdelegation, dns_rdataset_t *nsec3paramset) { dns_namereln_t reln; int order; unsigned int labels, nlabels, i; dns_name_t suffix; isc_result_t result = ISC_R_SUCCESS, tresult; reln = dns_name_fullcompare(prevname, name, &order, &labels); if (order >= 0) return (result); nlabels = dns_name_countlabels(name); if (reln == dns_namereln_commonancestor || reln == dns_namereln_contains) { dns_name_init(&suffix, NULL); for (i = labels + 1; i < nlabels; i++) { dns_name_getlabelsequence(name, nlabels - i, i, &suffix); if (nsec3paramset != NULL && dns_rdataset_isassociated(nsec3paramset)) { tresult = verifynsec3s(db, ver, origin, mctx, &suffix, nsec3paramset, isdelegation, ISC_TRUE, NULL, 0); if (result == ISC_R_SUCCESS && tresult != ISC_R_SUCCESS) result = tresult; } } } return (result); } /*% * Verify that certain things are sane: * * The apex has a DNSKEY record with at least one KSK, and at least * one ZSK if the -x flag was not used. * * The DNSKEY record was signed with at least one of the KSKs in this * set. * * The rest of the zone was signed with at least one of the ZSKs * present in the DNSKEY RRSET. */ void verifyzone(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin, isc_mem_t *mctx, isc_boolean_t ignore_kskflag, isc_boolean_t keyset_kskonly) { char algbuf[80]; dns_dbiterator_t *dbiter = NULL; dns_dbnode_t *node = NULL, *nextnode = NULL; dns_fixedname_t fname, fnextname, fprevname, fzonecut; dns_name_t *name, *nextname, *prevname, *zonecut; dns_rdata_dnskey_t dnskey; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_t keyset, soaset; dns_rdataset_t keysigs, soasigs; dns_rdataset_t nsecset, nsecsigs; dns_rdataset_t nsec3paramset, nsec3paramsigs; int i; isc_boolean_t done = ISC_FALSE; isc_boolean_t first = ISC_TRUE; isc_boolean_t goodksk = ISC_FALSE; isc_boolean_t goodzsk = ISC_FALSE; isc_result_t result, vresult = ISC_R_UNSET; unsigned char revoked_ksk[256]; unsigned char revoked_zsk[256]; unsigned char standby_ksk[256]; unsigned char standby_zsk[256]; unsigned char ksk_algorithms[256]; unsigned char zsk_algorithms[256]; unsigned char bad_algorithms[256]; unsigned char act_algorithms[256]; result = isc_heap_create(mctx, chain_compare, NULL, 1024, &expected_chains); check_result(result, "isc_heap_create()"); result = isc_heap_create(mctx, chain_compare, NULL, 1024, &found_chains); check_result(result, "isc_heap_create()"); result = dns_db_findnode(db, origin, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) fatal("failed to find the zone's origin: %s", isc_result_totext(result)); dns_rdataset_init(&keyset); dns_rdataset_init(&keysigs); dns_rdataset_init(&soaset); dns_rdataset_init(&soasigs); dns_rdataset_init(&nsecset); dns_rdataset_init(&nsecsigs); dns_rdataset_init(&nsec3paramset); dns_rdataset_init(&nsec3paramsigs); result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 0, 0, &keyset, &keysigs); if (result != ISC_R_SUCCESS) fatal("Zone contains no DNSSEC keys\n"); result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0, 0, &soaset, &soasigs); if (result != ISC_R_SUCCESS) fatal("Zone contains no SOA record\n"); result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, 0, &nsecset, &nsecsigs); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) fatal("NSEC lookup failed\n"); result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0, 0, &nsec3paramset, &nsec3paramsigs); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) fatal("NSEC3PARAM lookup failed\n"); if (!dns_rdataset_isassociated(&keysigs)) fatal("DNSKEY is not signed (keys offline or inactive?)\n"); if (!dns_rdataset_isassociated(&soasigs)) fatal("SOA is not signed (keys offline or inactive?)\n"); if (dns_rdataset_isassociated(&nsecset) && !dns_rdataset_isassociated(&nsecsigs)) fatal("NSEC is not signed (keys offline or inactive?)\n"); if (dns_rdataset_isassociated(&nsec3paramset) && !dns_rdataset_isassociated(&nsec3paramsigs)) fatal("NSEC3PARAM is not signed (keys offline or inactive?)\n"); if (!dns_rdataset_isassociated(&nsecset) && !dns_rdataset_isassociated(&nsec3paramset)) fatal("No valid NSEC/NSEC3 chain for testing\n"); dns_db_detachnode(db, &node); memset(revoked_ksk, 0, sizeof(revoked_ksk)); memset(revoked_zsk, 0, sizeof(revoked_zsk)); memset(standby_ksk, 0, sizeof(standby_ksk)); memset(standby_zsk, 0, sizeof(standby_zsk)); memset(ksk_algorithms, 0, sizeof(ksk_algorithms)); memset(zsk_algorithms, 0, sizeof(zsk_algorithms)); memset(bad_algorithms, 0, sizeof(bad_algorithms)); memset(act_algorithms, 0, sizeof(act_algorithms)); /* * Check that the DNSKEY RR has at least one self signing KSK * and one ZSK per algorithm in it (or, if -x was used, one * self-signing KSK). */ for (result = dns_rdataset_first(&keyset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&keyset)) { dns_rdataset_current(&keyset, &rdata); result = dns_rdata_tostruct(&rdata, &dnskey, NULL); check_result(result, "dns_rdata_tostruct"); if ((dnskey.flags & DNS_KEYOWNER_ZONE) == 0) ; else if ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0) { if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 && !dns_dnssec_selfsigns(&rdata, origin, &keyset, &keysigs, ISC_FALSE, mctx)) { char namebuf[DNS_NAME_FORMATSIZE]; char buffer[1024]; isc_buffer_t buf; dns_name_format(origin, namebuf, sizeof(namebuf)); isc_buffer_init(&buf, buffer, sizeof(buffer)); result = dns_rdata_totext(&rdata, NULL, &buf); check_result(result, "dns_rdata_totext"); fatal("revoked KSK is not self signed:\n" "%s DNSKEY %.*s", namebuf, (int)isc_buffer_usedlength(&buf), buffer); } if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 && revoked_ksk[dnskey.algorithm] != 255) revoked_ksk[dnskey.algorithm]++; else if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0 && revoked_zsk[dnskey.algorithm] != 255) revoked_zsk[dnskey.algorithm]++; } else if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0) { if (dns_dnssec_selfsigns(&rdata, origin, &keyset, &keysigs, ISC_FALSE, mctx)) { if (ksk_algorithms[dnskey.algorithm] != 255) ksk_algorithms[dnskey.algorithm]++; goodksk = ISC_TRUE; } else { if (standby_ksk[dnskey.algorithm] != 255) standby_ksk[dnskey.algorithm]++; } } else if (dns_dnssec_selfsigns(&rdata, origin, &keyset, &keysigs, ISC_FALSE, mctx)) { if (zsk_algorithms[dnskey.algorithm] != 255) zsk_algorithms[dnskey.algorithm]++; goodzsk = ISC_TRUE; } else if (dns_dnssec_signs(&rdata, origin, &soaset, &soasigs, ISC_FALSE, mctx)) { if (zsk_algorithms[dnskey.algorithm] != 255) zsk_algorithms[dnskey.algorithm]++; } else { if (standby_zsk[dnskey.algorithm] != 255) standby_zsk[dnskey.algorithm]++; } dns_rdata_freestruct(&dnskey); dns_rdata_reset(&rdata); } dns_rdataset_disassociate(&keysigs); dns_rdataset_disassociate(&soaset); dns_rdataset_disassociate(&soasigs); if (dns_rdataset_isassociated(&nsecsigs)) dns_rdataset_disassociate(&nsecsigs); if (dns_rdataset_isassociated(&nsec3paramsigs)) dns_rdataset_disassociate(&nsec3paramsigs); if (ignore_kskflag ) { if (!goodksk && !goodzsk) fatal("No self-signed DNSKEY found."); } else if (!goodksk) fatal("No self-signed KSK DNSKEY found. Supply an active\n" "key with the KSK flag set, or use '-P'."); fprintf(stderr, "Verifying the zone using the following algorithms:"); for (i = 0; i < 256; i++) { if (ignore_kskflag) act_algorithms[i] = (ksk_algorithms[i] != 0 || zsk_algorithms[i] != 0) ? 1 : 0; else act_algorithms[i] = ksk_algorithms[i] != 0 ? 1 : 0; if (act_algorithms[i] != 0) { dns_secalg_format(i, algbuf, sizeof(algbuf)); fprintf(stderr, " %s", algbuf); } } fprintf(stderr, ".\n"); if (!ignore_kskflag && !keyset_kskonly) { for (i = 0; i < 256; i++) { /* * The counts should both be zero or both be non-zero. * Mark the algorithm as bad if this is not met. */ if ((ksk_algorithms[i] != 0) == (zsk_algorithms[i] != 0)) continue; dns_secalg_format(i, algbuf, sizeof(algbuf)); fprintf(stderr, "Missing %s for algorithm %s\n", (ksk_algorithms[i] != 0) ? "ZSK" : "self-signed KSK", algbuf); bad_algorithms[i] = 1; } } /* * Check that all the other records were signed by keys that are * present in the DNSKEY RRSET. */ dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_fixedname_init(&fnextname); nextname = dns_fixedname_name(&fnextname); dns_fixedname_init(&fprevname); prevname = NULL; dns_fixedname_init(&fzonecut); zonecut = NULL; result = dns_db_createiterator(db, DNS_DB_NONSEC3, &dbiter); check_result(result, "dns_db_createiterator()"); result = dns_dbiterator_first(dbiter); check_result(result, "dns_dbiterator_first()"); while (!done) { isc_boolean_t isdelegation = ISC_FALSE; result = dns_dbiterator_current(dbiter, &node, name); check_dns_dbiterator_current(result); if (!dns_name_issubdomain(name, origin)) { check_no_nsec(name, node, db, ver); dns_db_detachnode(db, &node); result = dns_dbiterator_next(dbiter); if (result == ISC_R_NOMORE) done = ISC_TRUE; else check_result(result, "dns_dbiterator_next()"); continue; } if (is_delegation(db, ver, origin, name, node, NULL)) { zonecut = dns_fixedname_name(&fzonecut); dns_name_copy(name, zonecut, NULL); isdelegation = ISC_TRUE; } nextnode = NULL; result = dns_dbiterator_next(dbiter); while (result == ISC_R_SUCCESS) { result = dns_dbiterator_current(dbiter, &nextnode, nextname); check_dns_dbiterator_current(result); if (!dns_name_issubdomain(nextname, origin) || (zonecut != NULL && dns_name_issubdomain(nextname, zonecut))) { check_no_nsec(nextname, nextnode, db, ver); dns_db_detachnode(db, &nextnode); result = dns_dbiterator_next(dbiter); continue; } if (is_empty(db, ver, nextnode)) { dns_db_detachnode(db, &nextnode); result = dns_dbiterator_next(dbiter); continue; } dns_db_detachnode(db, &nextnode); break; } if (result == ISC_R_NOMORE) { done = ISC_TRUE; nextname = origin; } else if (result != ISC_R_SUCCESS) fatal("iterating through the database failed: %s", isc_result_totext(result)); result = verifynode(db, ver, origin, mctx, name, node, isdelegation, &keyset, act_algorithms, bad_algorithms, &nsecset, &nsec3paramset, nextname); if (vresult == ISC_R_UNSET) vresult = ISC_R_SUCCESS; if (vresult == ISC_R_SUCCESS && result != ISC_R_SUCCESS) vresult = result; if (prevname != NULL) { result = verifyemptynodes(db, ver, origin, mctx, name, prevname, isdelegation, &nsec3paramset); } else prevname = dns_fixedname_name(&fprevname); dns_name_copy(name, prevname, NULL); if (vresult == ISC_R_SUCCESS && result != ISC_R_SUCCESS) vresult = result; dns_db_detachnode(db, &node); } dns_dbiterator_destroy(&dbiter); result = dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbiter); check_result(result, "dns_db_createiterator()"); for (result = dns_dbiterator_first(dbiter); result == ISC_R_SUCCESS; result = dns_dbiterator_next(dbiter) ) { result = dns_dbiterator_current(dbiter, &node, name); check_dns_dbiterator_current(result); result = verifynode(db, ver, origin, mctx, name, node, ISC_FALSE, &keyset, act_algorithms, bad_algorithms, NULL, NULL, NULL); check_result(result, "verifynode"); record_found(db, ver, mctx, name, node, &nsec3paramset); dns_db_detachnode(db, &node); } dns_dbiterator_destroy(&dbiter); dns_rdataset_disassociate(&keyset); if (dns_rdataset_isassociated(&nsecset)) dns_rdataset_disassociate(&nsecset); if (dns_rdataset_isassociated(&nsec3paramset)) dns_rdataset_disassociate(&nsec3paramset); result = verify_nsec3_chains(mctx); if (vresult == ISC_R_UNSET) vresult = ISC_R_SUCCESS; if (result != ISC_R_SUCCESS && vresult == ISC_R_SUCCESS) vresult = result; isc_heap_destroy(&expected_chains); isc_heap_destroy(&found_chains); /* * If we made it this far, we have what we consider a properly signed * zone. Set the good flag. */ for (i = 0; i < 256; i++) { if (bad_algorithms[i] != 0) { if (first) fprintf(stderr, "The zone is not fully signed " "for the following algorithms:"); dns_secalg_format(i, algbuf, sizeof(algbuf)); fprintf(stderr, " %s", algbuf); first = ISC_FALSE; } } if (!first) { fprintf(stderr, ".\n"); fatal("DNSSEC completeness test failed."); } if (vresult != ISC_R_SUCCESS) fatal("DNSSEC completeness test failed (%s).", dns_result_totext(vresult)); if (goodksk || ignore_kskflag) { /* * Print the success summary. */ fprintf(stderr, "Zone fully signed:\n"); for (i = 0; i < 256; i++) { if ((ksk_algorithms[i] != 0) || (standby_ksk[i] != 0) || (revoked_zsk[i] != 0) || (zsk_algorithms[i] != 0) || (standby_zsk[i] != 0) || (revoked_zsk[i] != 0)) { dns_secalg_format(i, algbuf, sizeof(algbuf)); fprintf(stderr, "Algorithm: %s: KSKs: " "%u active, %u stand-by, %u revoked\n", algbuf, ksk_algorithms[i], standby_ksk[i], revoked_ksk[i]); fprintf(stderr, "%*sZSKs: " "%u active, %u %s, %u revoked\n", (int) strlen(algbuf) + 13, "", zsk_algorithms[i], standby_zsk[i], keyset_kskonly ? "present" : "stand-by", revoked_zsk[i]); } } } } bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-settime.80000644000470500017500000001736212664710322020451 0ustar lamontlamont.\" Copyright (C) 2009-2011, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: dnssec\-settime .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: February 06, 2014 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "DNSSEC\-SETTIME" "8" "February 06, 2014" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" dnssec\-settime \- Set the key timing metadata for a DNSSEC key .SH "SYNOPSIS" .HP 15 \fBdnssec\-settime\fR [\fB\-f\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-L\ \fR\fB\fIttl\fR\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-A\ \fR\fB\fIdate/offset\fR\fR] [\fB\-R\ \fR\fB\fIdate/offset\fR\fR] [\fB\-I\ \fR\fB\fIdate/offset\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-h\fR] [\fB\-V\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] {keyfile} .SH "DESCRIPTION" .PP \fBdnssec\-settime\fR reads a DNSSEC private key file and sets the key timing metadata as specified by the \fB\-P\fR, \fB\-A\fR, \fB\-R\fR, \fB\-I\fR, and \fB\-D\fR options. The metadata can then be used by \fBdnssec\-signzone\fR or other signing software to determine when a key is to be published, whether it should be used for signing a zone, etc. .PP If none of these options is set on the command line, then \fBdnssec\-settime\fR simply prints the key timing metadata already stored in the key. .PP When key metadata fields are changed, both files of a key pair (\fIKnnnn.+aaa+iiiii.key\fR and \fIKnnnn.+aaa+iiiii.private\fR) are regenerated. Metadata fields are stored in the private file. A human\-readable description of the metadata is also placed in comments in the key file. The private file's permissions are always set to be inaccessible to anyone other than the owner (mode 0600). .SH "OPTIONS" .PP \-f .RS 4 Force an update of an old\-format key with no metadata fields. Without this option, \fBdnssec\-settime\fR will fail when attempting to update a legacy key. With this option, the key will be recreated in the new format, but with the original key data retained. The key's creation date will be set to the present time. If no other values are specified, then the key's publication and activation dates will also be set to the present time. .RE .PP \-K \fIdirectory\fR .RS 4 Sets the directory in which the key files are to reside. .RE .PP \-L \fIttl\fR .RS 4 Sets the default TTL to use for this key when it is converted into a DNSKEY RR. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence. If this value is not set and there is no existing DNSKEY RRset, the TTL will default to the SOA TTL. Setting the default TTL to 0 or none removes it from the key. .RE .PP \-h .RS 4 Emit usage message and exit. .RE .PP \-V .RS 4 Prints version information. .RE .PP \-v \fIlevel\fR .RS 4 Sets the debugging level. .RE .PP \-E \fIengine\fR .RS 4 Specifies the cryptographic hardware to use, when applicable. .sp When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (\-\-enable\-native\-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "\-\-with\-pkcs11". .RE .SH "TIMING OPTIONS" .PP Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '\-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24\-hour days, ignoring leap years), months (defined as 30 24\-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To unset a date, use 'none' or 'never'. .PP \-P \fIdate/offset\fR .RS 4 Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it. .RE .PP \-A \fIdate/offset\fR .RS 4 Sets the date on which the key is to be activated. After that date, the key will be included in the zone and used to sign it. .RE .PP \-R \fIdate/offset\fR .RS 4 Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it. .RE .PP \-I \fIdate/offset\fR .RS 4 Sets the date on which the key is to be retired. After that date, the key will still be included in the zone, but it will not be used to sign it. .RE .PP \-D \fIdate/offset\fR .RS 4 Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.) .RE .PP \-S \fIpredecessor key\fR .RS 4 Select a key for which the key being modified will be an explicit successor. The name, algorithm, size, and type of the predecessor key must exactly match those of the key being modified. The activation date of the successor key will be set to the inactivation date of the predecessor. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days. .RE .PP \-i \fIinterval\fR .RS 4 Sets the prepublication interval for a key. If set, then the publication and activation dates must be separated by at least this much time. If the activation date is specified but the publication date isn't, then the publication date will default to this much time before the activation date; conversely, if the publication date is specified but activation date isn't, then activation will be set to this much time after publication. .sp If the key is being set to be an explicit successor to another key, then the default prepublication interval is 30 days; otherwise it is zero. .sp As with date offsets, if the argument is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the interval is measured in years, months, weeks, days, hours, or minutes, respectively. Without a suffix, the interval is measured in seconds. .RE .SH "PRINTING OPTIONS" .PP \fBdnssec\-settime\fR can also be used to print the timing metadata associated with a key. .PP \-u .RS 4 Print times in UNIX epoch format. .RE .PP \-p \fIC/P/A/R/I/D/all\fR .RS 4 Print a specific metadata value or set of metadata values. The \fB\-p\fR option may be followed by one or more of the following letters to indicate which value or values to print: \fBC\fR for the creation date, \fBP\fR for the publication date, \fBA\fR for the activation date, \fBR\fR for the revocation date, \fBI\fR for the inactivation date, or \fBD\fR for the deletion date. To print all of the metadata, use \fB\-p all\fR. .RE .SH "SEE ALSO" .PP \fBdnssec\-keygen\fR(8), \fBdnssec\-signzone\fR(8), BIND 9 Administrator Reference Manual, RFC 5011. .SH "AUTHOR" .PP Internet Systems Consortium .SH "COPYRIGHT" Copyright \(co 2009\-2011, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") .br bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-keygen.c0000644000470500017500000007601612664710322020335 0ustar lamontlamont/* * Portions Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef PKCS11CRYPTO #include #endif #include "dnssectool.h" #define MAX_RSA 4096 /* should be long enough... */ const char *program = "dnssec-keygen"; int verbose; #define DEFAULT_ALGORITHM "RSASHA1" #define DEFAULT_NSEC3_ALGORITHM "NSEC3RSASHA1" ISC_PLATFORM_NORETURN_PRE static void usage(void) ISC_PLATFORM_NORETURN_POST; static void progress(int p); static void usage(void) { fprintf(stderr, "Usage:\n"); fprintf(stderr, " %s [options] name\n\n", program); fprintf(stderr, "Version: %s\n", VERSION); fprintf(stderr, " name: owner of the key\n"); fprintf(stderr, "Options:\n"); fprintf(stderr, " -K : write keys into directory\n"); fprintf(stderr, " -a :\n"); fprintf(stderr, " RSA | RSAMD5 | DSA | RSASHA1 | NSEC3RSASHA1" " | NSEC3DSA |\n"); fprintf(stderr, " RSASHA256 | RSASHA512 | ECCGOST |\n"); fprintf(stderr, " ECDSAP256SHA256 | ECDSAP384SHA384 |\n"); fprintf(stderr, " DH | HMAC-MD5 | HMAC-SHA1 | HMAC-SHA224 | " "HMAC-SHA256 | \n"); fprintf(stderr, " HMAC-SHA384 | HMAC-SHA512\n"); fprintf(stderr, " (default: RSASHA1, or " "NSEC3RSASHA1 if using -3)\n"); fprintf(stderr, " -3: use NSEC3-capable algorithm\n"); fprintf(stderr, " -b :\n"); fprintf(stderr, " RSAMD5:\t[512..%d]\n", MAX_RSA); fprintf(stderr, " RSASHA1:\t[512..%d]\n", MAX_RSA); fprintf(stderr, " NSEC3RSASHA1:\t[512..%d]\n", MAX_RSA); fprintf(stderr, " RSASHA256:\t[512..%d]\n", MAX_RSA); fprintf(stderr, " RSASHA512:\t[1024..%d]\n", MAX_RSA); fprintf(stderr, " DH:\t\t[128..4096]\n"); fprintf(stderr, " DSA:\t\t[512..1024] and divisible by 64\n"); fprintf(stderr, " NSEC3DSA:\t[512..1024] and divisible " "by 64\n"); fprintf(stderr, " ECCGOST:\tignored\n"); fprintf(stderr, " ECDSAP256SHA256:\tignored\n"); fprintf(stderr, " ECDSAP384SHA384:\tignored\n"); fprintf(stderr, " HMAC-MD5:\t[1..512]\n"); fprintf(stderr, " HMAC-SHA1:\t[1..160]\n"); fprintf(stderr, " HMAC-SHA224:\t[1..224]\n"); fprintf(stderr, " HMAC-SHA256:\t[1..256]\n"); fprintf(stderr, " HMAC-SHA384:\t[1..384]\n"); fprintf(stderr, " HMAC-SHA512:\t[1..512]\n"); fprintf(stderr, " (if using the default algorithm, key size\n" " defaults to 2048 for KSK, or 1024 for all " "others)\n"); fprintf(stderr, " -n : ZONE | HOST | ENTITY | " "USER | OTHER\n"); fprintf(stderr, " (DNSKEY generation defaults to ZONE)\n"); fprintf(stderr, " -c : (default: IN)\n"); fprintf(stderr, " -d (0 => max, default)\n"); fprintf(stderr, " -E :\n"); #if defined(PKCS11CRYPTO) fprintf(stderr, " path to PKCS#11 provider library " "(default is %s)\n", PK11_LIB_LOCATION); #elif defined(USE_PKCS11) fprintf(stderr, " name of an OpenSSL engine to use " "(default is \"pkcs11\")\n"); #else fprintf(stderr, " name of an OpenSSL engine to use\n"); #endif fprintf(stderr, " -f : KSK | REVOKE\n"); fprintf(stderr, " -g : use specified generator " "(DH only)\n"); fprintf(stderr, " -L : default key TTL\n"); fprintf(stderr, " -p : (default: 3 [dnssec])\n"); fprintf(stderr, " -r : a file containing random data\n"); fprintf(stderr, " -s : strength value this key signs DNS " "records with (default: 0)\n"); fprintf(stderr, " -T : DNSKEY | KEY (default: DNSKEY; " "use KEY for SIG(0))\n"); fprintf(stderr, " -t : " "AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF " "(default: AUTHCONF)\n"); fprintf(stderr, " -h: print usage and exit\n"); fprintf(stderr, " -m :\n"); fprintf(stderr, " usage | trace | record | size | mctx\n"); fprintf(stderr, " -v : set verbosity level (0 - 10)\n"); fprintf(stderr, " -V: print version information\n"); fprintf(stderr, "Timing options:\n"); fprintf(stderr, " -P date/[+-]offset/none: set key publication date " "(default: now)\n"); fprintf(stderr, " -A date/[+-]offset/none: set key activation date " "(default: now)\n"); fprintf(stderr, " -R date/[+-]offset/none: set key " "revocation date\n"); fprintf(stderr, " -I date/[+-]offset/none: set key " "inactivation date\n"); fprintf(stderr, " -D date/[+-]offset/none: set key deletion date\n"); fprintf(stderr, " -G: generate key only; do not set -P or -A\n"); fprintf(stderr, " -C: generate a backward-compatible key, omitting " "all dates\n"); fprintf(stderr, " -S : generate a successor to an existing " "key\n"); fprintf(stderr, " -i : prepublication interval for " "successor key " "(default: 30 days)\n"); fprintf(stderr, "Output:\n"); fprintf(stderr, " K++.key, " "K++.private\n"); exit (-1); } static isc_boolean_t dsa_size_ok(int size) { return (ISC_TF(size >= 512 && size <= 1024 && size % 64 == 0)); } static void progress(int p) { char c = '*'; switch (p) { case 0: c = '.'; break; case 1: c = '+'; break; case 2: c = '*'; break; case 3: c = ' '; break; default: break; } (void) putc(c, stderr); (void) fflush(stderr); } int main(int argc, char **argv) { char *algname = NULL, *freeit = NULL; char *nametype = NULL, *type = NULL; char *classname = NULL; char *endp; dst_key_t *key = NULL; dns_fixedname_t fname; dns_name_t *name; isc_uint16_t flags = 0, kskflag = 0, revflag = 0; dns_secalg_t alg; isc_boolean_t conflict = ISC_FALSE, null_key = ISC_FALSE; isc_boolean_t oldstyle = ISC_FALSE; isc_mem_t *mctx = NULL; int ch, generator = 0, param = 0; int protocol = -1, size = -1, signatory = 0; isc_result_t ret; isc_textregion_t r; char filename[255]; const char *directory = NULL; const char *predecessor = NULL; dst_key_t *prevkey = NULL; isc_buffer_t buf; isc_log_t *log = NULL; isc_entropy_t *ectx = NULL; #ifdef USE_PKCS11 const char *engine = PKCS11_ENGINE; #else const char *engine = NULL; #endif dns_rdataclass_t rdclass; int options = DST_TYPE_PRIVATE | DST_TYPE_PUBLIC; int dbits = 0; dns_ttl_t ttl = 0; isc_boolean_t use_default = ISC_FALSE, use_nsec3 = ISC_FALSE; isc_stdtime_t publish = 0, activate = 0, revokekey = 0; isc_stdtime_t inactive = 0, delete = 0; isc_stdtime_t now; int prepub = -1; isc_boolean_t setpub = ISC_FALSE, setact = ISC_FALSE; isc_boolean_t setrev = ISC_FALSE, setinact = ISC_FALSE; isc_boolean_t setdel = ISC_FALSE, setttl = ISC_FALSE; isc_boolean_t unsetpub = ISC_FALSE, unsetact = ISC_FALSE; isc_boolean_t unsetrev = ISC_FALSE, unsetinact = ISC_FALSE; isc_boolean_t unsetdel = ISC_FALSE; isc_boolean_t genonly = ISC_FALSE; isc_boolean_t quiet = ISC_FALSE; isc_boolean_t show_progress = ISC_FALSE; unsigned char c; if (argc == 1) usage(); #ifdef PKCS11CRYPTO pk11_result_register(); #endif dns_result_register(); isc_commandline_errprint = ISC_FALSE; /* * Process memory debugging argument first. */ #define CMDLINE_FLAGS "3A:a:b:Cc:D:d:E:eFf:Gg:hI:i:K:kL:m:n:P:p:qR:r:S:s:T:t:" \ "v:V" while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { switch (ch) { case 'm': if (strcasecmp(isc_commandline_argument, "record") == 0) isc_mem_debugging |= ISC_MEM_DEBUGRECORD; if (strcasecmp(isc_commandline_argument, "trace") == 0) isc_mem_debugging |= ISC_MEM_DEBUGTRACE; if (strcasecmp(isc_commandline_argument, "usage") == 0) isc_mem_debugging |= ISC_MEM_DEBUGUSAGE; if (strcasecmp(isc_commandline_argument, "size") == 0) isc_mem_debugging |= ISC_MEM_DEBUGSIZE; if (strcasecmp(isc_commandline_argument, "mctx") == 0) isc_mem_debugging |= ISC_MEM_DEBUGCTX; break; default: break; } } isc_commandline_reset = ISC_TRUE; RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); isc_stdtime_get(&now); while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { switch (ch) { case '3': use_nsec3 = ISC_TRUE; break; case 'a': algname = isc_commandline_argument; break; case 'b': size = strtol(isc_commandline_argument, &endp, 10); if (*endp != '\0' || size < 0) fatal("-b requires a non-negative number"); break; case 'C': oldstyle = ISC_TRUE; break; case 'c': classname = isc_commandline_argument; break; case 'd': dbits = strtol(isc_commandline_argument, &endp, 10); if (*endp != '\0' || dbits < 0) fatal("-d requires a non-negative number"); break; case 'E': engine = isc_commandline_argument; break; case 'e': fprintf(stderr, "phased-out option -e " "(was 'use (RSA) large exponent)\n"); break; case 'f': c = (unsigned char)(isc_commandline_argument[0]); if (toupper(c) == 'K') kskflag = DNS_KEYFLAG_KSK; else if (toupper(c) == 'R') revflag = DNS_KEYFLAG_REVOKE; else fatal("unknown flag '%s'", isc_commandline_argument); break; case 'g': generator = strtol(isc_commandline_argument, &endp, 10); if (*endp != '\0' || generator <= 0) fatal("-g requires a positive number"); break; case 'K': directory = isc_commandline_argument; ret = try_dir(directory); if (ret != ISC_R_SUCCESS) fatal("cannot open directory %s: %s", directory, isc_result_totext(ret)); break; case 'k': fatal("The -k option has been deprecated.\n" "To generate a key-signing key, use -f KSK.\n" "To generate a key with TYPE=KEY, use -T KEY.\n"); break; case 'L': ttl = strtottl(isc_commandline_argument); setttl = ISC_TRUE; break; case 'n': nametype = isc_commandline_argument; break; case 'm': break; case 'p': protocol = strtol(isc_commandline_argument, &endp, 10); if (*endp != '\0' || protocol < 0 || protocol > 255) fatal("-p must be followed by a number " "[0..255]"); break; case 'q': quiet = ISC_TRUE; break; case 'r': setup_entropy(mctx, isc_commandline_argument, &ectx); break; case 's': signatory = strtol(isc_commandline_argument, &endp, 10); if (*endp != '\0' || signatory < 0 || signatory > 15) fatal("-s must be followed by a number " "[0..15]"); break; case 'T': if (strcasecmp(isc_commandline_argument, "KEY") == 0) options |= DST_TYPE_KEY; else if (strcasecmp(isc_commandline_argument, "DNSKEY") == 0) /* default behavior */ ; else fatal("unknown type '%s'", isc_commandline_argument); break; case 't': type = isc_commandline_argument; break; case 'v': endp = NULL; verbose = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') fatal("-v must be followed by a number"); break; case 'z': /* already the default */ break; case 'G': genonly = ISC_TRUE; break; case 'P': if (setpub || unsetpub) fatal("-P specified more than once"); publish = strtotime(isc_commandline_argument, now, now, &setpub); unsetpub = !setpub; break; case 'A': if (setact || unsetact) fatal("-A specified more than once"); activate = strtotime(isc_commandline_argument, now, now, &setact); unsetact = !setact; break; case 'R': if (setrev || unsetrev) fatal("-R specified more than once"); revokekey = strtotime(isc_commandline_argument, now, now, &setrev); unsetrev = !setrev; break; case 'I': if (setinact || unsetinact) fatal("-I specified more than once"); inactive = strtotime(isc_commandline_argument, now, now, &setinact); unsetinact = !setinact; break; case 'D': if (setdel || unsetdel) fatal("-D specified more than once"); delete = strtotime(isc_commandline_argument, now, now, &setdel); unsetdel = !setdel; break; case 'S': predecessor = isc_commandline_argument; break; case 'i': prepub = strtottl(isc_commandline_argument); break; case 'F': /* Reserved for FIPS mode */ /* FALLTHROUGH */ case '?': if (isc_commandline_option != '?') fprintf(stderr, "%s: invalid argument -%c\n", program, isc_commandline_option); /* FALLTHROUGH */ case 'h': /* Does not return. */ usage(); case 'V': /* Does not return. */ version(program); default: fprintf(stderr, "%s: unhandled option -%c\n", program, isc_commandline_option); exit(1); } } if (!isatty(0)) quiet = ISC_TRUE; if (ectx == NULL) setup_entropy(mctx, NULL, &ectx); ret = dst_lib_init2(mctx, ectx, engine, ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); if (ret != ISC_R_SUCCESS) fatal("could not initialize dst: %s", isc_result_totext(ret)); setup_logging(mctx, &log); if (predecessor == NULL) { if (prepub == -1) prepub = 0; if (argc < isc_commandline_index + 1) fatal("the key name was not specified"); if (argc > isc_commandline_index + 1) fatal("extraneous arguments"); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); isc_buffer_init(&buf, argv[isc_commandline_index], strlen(argv[isc_commandline_index])); isc_buffer_add(&buf, strlen(argv[isc_commandline_index])); ret = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL); if (ret != ISC_R_SUCCESS) fatal("invalid key name %s: %s", argv[isc_commandline_index], isc_result_totext(ret)); if (algname == NULL) { use_default = ISC_TRUE; if (use_nsec3) algname = strdup(DEFAULT_NSEC3_ALGORITHM); else algname = strdup(DEFAULT_ALGORITHM); if (algname == NULL) fatal("strdup failed"); freeit = algname; if (verbose > 0) fprintf(stderr, "no algorithm specified; " "defaulting to %s\n", algname); } if (strcasecmp(algname, "RSA") == 0) { fprintf(stderr, "The use of RSA (RSAMD5) is not " "recommended.\nIf you still wish to " "use RSA (RSAMD5) please specify " "\"-a RSAMD5\"\n"); INSIST(freeit == NULL); return (1); } else if (strcasecmp(algname, "HMAC-MD5") == 0) alg = DST_ALG_HMACMD5; else if (strcasecmp(algname, "HMAC-SHA1") == 0) alg = DST_ALG_HMACSHA1; else if (strcasecmp(algname, "HMAC-SHA224") == 0) alg = DST_ALG_HMACSHA224; else if (strcasecmp(algname, "HMAC-SHA256") == 0) alg = DST_ALG_HMACSHA256; else if (strcasecmp(algname, "HMAC-SHA384") == 0) alg = DST_ALG_HMACSHA384; else if (strcasecmp(algname, "HMAC-SHA512") == 0) alg = DST_ALG_HMACSHA512; else { r.base = algname; r.length = strlen(algname); ret = dns_secalg_fromtext(&alg, &r); if (ret != ISC_R_SUCCESS) fatal("unknown algorithm %s", algname); if (alg == DST_ALG_DH) options |= DST_TYPE_KEY; } if (!dst_algorithm_supported(alg)) fatal("unsupported algorithm: %d", alg); if (use_nsec3 && alg != DST_ALG_NSEC3DSA && alg != DST_ALG_NSEC3RSASHA1 && alg != DST_ALG_RSASHA256 && alg!= DST_ALG_RSASHA512 && alg != DST_ALG_ECCGOST && alg != DST_ALG_ECDSA256 && alg != DST_ALG_ECDSA384) { fatal("%s is incompatible with NSEC3; " "do not use the -3 option", algname); } if (type != NULL && (options & DST_TYPE_KEY) != 0) { if (strcasecmp(type, "NOAUTH") == 0) flags |= DNS_KEYTYPE_NOAUTH; else if (strcasecmp(type, "NOCONF") == 0) flags |= DNS_KEYTYPE_NOCONF; else if (strcasecmp(type, "NOAUTHCONF") == 0) { flags |= (DNS_KEYTYPE_NOAUTH | DNS_KEYTYPE_NOCONF); if (size < 0) size = 0; } else if (strcasecmp(type, "AUTHCONF") == 0) /* nothing */; else fatal("invalid type %s", type); } if (size < 0) { if (use_default) { if ((kskflag & DNS_KEYFLAG_KSK) != 0) size = 2048; else size = 1024; if (verbose > 0) fprintf(stderr, "key size not " "specified; defaulting" " to %d\n", size); } else if (alg != DST_ALG_ECCGOST && alg != DST_ALG_ECDSA256 && alg != DST_ALG_ECDSA384) fatal("key size not specified (-b option)"); } if (!oldstyle && prepub > 0) { if (setpub && setact && (activate - prepub) < publish) fatal("Activation and publication dates " "are closer together than the\n\t" "prepublication interval."); if (!setpub && !setact) { setpub = setact = ISC_TRUE; publish = now; activate = now + prepub; } else if (setpub && !setact) { setact = ISC_TRUE; activate = publish + prepub; } else if (setact && !setpub) { setpub = ISC_TRUE; publish = activate - prepub; } if ((activate - prepub) < now) fatal("Time until activation is shorter " "than the\n\tprepublication interval."); } } else { char keystr[DST_KEY_FORMATSIZE]; isc_stdtime_t when; int major, minor; if (prepub == -1) prepub = (30 * 86400); if (algname != NULL) fatal("-S and -a cannot be used together"); if (size >= 0) fatal("-S and -b cannot be used together"); if (nametype != NULL) fatal("-S and -n cannot be used together"); if (type != NULL) fatal("-S and -t cannot be used together"); if (setpub || unsetpub) fatal("-S and -P cannot be used together"); if (setact || unsetact) fatal("-S and -A cannot be used together"); if (use_nsec3) fatal("-S and -3 cannot be used together"); if (oldstyle) fatal("-S and -C cannot be used together"); if (genonly) fatal("-S and -G cannot be used together"); ret = dst_key_fromnamedfile(predecessor, directory, DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, mctx, &prevkey); if (ret != ISC_R_SUCCESS) fatal("Invalid keyfile %s: %s", predecessor, isc_result_totext(ret)); if (!dst_key_isprivate(prevkey)) fatal("%s is not a private key", predecessor); name = dst_key_name(prevkey); alg = dst_key_alg(prevkey); size = dst_key_size(prevkey); flags = dst_key_flags(prevkey); dst_key_format(prevkey, keystr, sizeof(keystr)); dst_key_getprivateformat(prevkey, &major, &minor); if (major != DST_MAJOR_VERSION || minor < DST_MINOR_VERSION) fatal("Key %s has incompatible format version %d.%d\n\t" "It is not possible to generate a successor key.", keystr, major, minor); ret = dst_key_gettime(prevkey, DST_TIME_ACTIVATE, &when); if (ret != ISC_R_SUCCESS) fatal("Key %s has no activation date.\n\t" "You must use dnssec-settime -A to set one " "before generating a successor.", keystr); ret = dst_key_gettime(prevkey, DST_TIME_INACTIVE, &activate); if (ret != ISC_R_SUCCESS) fatal("Key %s has no inactivation date.\n\t" "You must use dnssec-settime -I to set one " "before generating a successor.", keystr); publish = activate - prepub; if (publish < now) fatal("Key %s becomes inactive\n\t" "sooner than the prepublication period " "for the new key ends.\n\t" "Either change the inactivation date with " "dnssec-settime -I,\n\t" "or use the -i option to set a shorter " "prepublication interval.", keystr); ret = dst_key_gettime(prevkey, DST_TIME_DELETE, &when); if (ret != ISC_R_SUCCESS) fprintf(stderr, "%s: WARNING: Key %s has no removal " "date;\n\t it will remain in the zone " "indefinitely after rollover.\n\t " "You can use dnssec-settime -D to " "change this.\n", program, keystr); setpub = setact = ISC_TRUE; } switch (alg) { case DNS_KEYALG_RSAMD5: case DNS_KEYALG_RSASHA1: case DNS_KEYALG_NSEC3RSASHA1: case DNS_KEYALG_RSASHA256: if (size != 0 && (size < 512 || size > MAX_RSA)) fatal("RSA key size %d out of range", size); break; case DNS_KEYALG_RSASHA512: if (size != 0 && (size < 1024 || size > MAX_RSA)) fatal("RSA key size %d out of range", size); break; case DNS_KEYALG_DH: if (size != 0 && (size < 128 || size > 4096)) fatal("DH key size %d out of range", size); break; case DNS_KEYALG_DSA: case DNS_KEYALG_NSEC3DSA: if (size != 0 && !dsa_size_ok(size)) fatal("invalid DSS key size: %d", size); break; case DST_ALG_ECCGOST: size = 256; break; case DST_ALG_ECDSA256: size = 256; break; case DST_ALG_ECDSA384: size = 384; break; case DST_ALG_HMACMD5: options |= DST_TYPE_KEY; if (size < 1 || size > 512) fatal("HMAC-MD5 key size %d out of range", size); if (dbits != 0 && (dbits < 80 || dbits > 128)) fatal("HMAC-MD5 digest bits %d out of range", dbits); if ((dbits % 8) != 0) fatal("HMAC-MD5 digest bits %d not divisible by 8", dbits); break; case DST_ALG_HMACSHA1: options |= DST_TYPE_KEY; if (size < 1 || size > 160) fatal("HMAC-SHA1 key size %d out of range", size); if (dbits != 0 && (dbits < 80 || dbits > 160)) fatal("HMAC-SHA1 digest bits %d out of range", dbits); if ((dbits % 8) != 0) fatal("HMAC-SHA1 digest bits %d not divisible by 8", dbits); break; case DST_ALG_HMACSHA224: options |= DST_TYPE_KEY; if (size < 1 || size > 224) fatal("HMAC-SHA224 key size %d out of range", size); if (dbits != 0 && (dbits < 112 || dbits > 224)) fatal("HMAC-SHA224 digest bits %d out of range", dbits); if ((dbits % 8) != 0) fatal("HMAC-SHA224 digest bits %d not divisible by 8", dbits); break; case DST_ALG_HMACSHA256: options |= DST_TYPE_KEY; if (size < 1 || size > 256) fatal("HMAC-SHA256 key size %d out of range", size); if (dbits != 0 && (dbits < 128 || dbits > 256)) fatal("HMAC-SHA256 digest bits %d out of range", dbits); if ((dbits % 8) != 0) fatal("HMAC-SHA256 digest bits %d not divisible by 8", dbits); break; case DST_ALG_HMACSHA384: options |= DST_TYPE_KEY; if (size < 1 || size > 384) fatal("HMAC-384 key size %d out of range", size); if (dbits != 0 && (dbits < 192 || dbits > 384)) fatal("HMAC-SHA384 digest bits %d out of range", dbits); if ((dbits % 8) != 0) fatal("HMAC-SHA384 digest bits %d not divisible by 8", dbits); break; case DST_ALG_HMACSHA512: options |= DST_TYPE_KEY; if (size < 1 || size > 512) fatal("HMAC-SHA512 key size %d out of range", size); if (dbits != 0 && (dbits < 256 || dbits > 512)) fatal("HMAC-SHA512 digest bits %d out of range", dbits); if ((dbits % 8) != 0) fatal("HMAC-SHA512 digest bits %d not divisible by 8", dbits); break; } if (alg != DNS_KEYALG_DH && generator != 0) fatal("specified DH generator for a non-DH key"); if (nametype == NULL) { if ((options & DST_TYPE_KEY) != 0) /* KEY / HMAC */ fatal("no nametype specified"); flags |= DNS_KEYOWNER_ZONE; /* DNSKEY */ } else if (strcasecmp(nametype, "zone") == 0) flags |= DNS_KEYOWNER_ZONE; else if ((options & DST_TYPE_KEY) != 0) { /* KEY / HMAC */ if (strcasecmp(nametype, "host") == 0 || strcasecmp(nametype, "entity") == 0) flags |= DNS_KEYOWNER_ENTITY; else if (strcasecmp(nametype, "user") == 0) flags |= DNS_KEYOWNER_USER; else fatal("invalid KEY nametype %s", nametype); } else if (strcasecmp(nametype, "other") != 0) /* DNSKEY */ fatal("invalid DNSKEY nametype %s", nametype); rdclass = strtoclass(classname); if (directory == NULL) directory = "."; if ((options & DST_TYPE_KEY) != 0) /* KEY / HMAC */ flags |= signatory; else if ((flags & DNS_KEYOWNER_ZONE) != 0) { /* DNSKEY */ flags |= kskflag; flags |= revflag; } if (protocol == -1) protocol = DNS_KEYPROTO_DNSSEC; else if ((options & DST_TYPE_KEY) == 0 && protocol != DNS_KEYPROTO_DNSSEC) fatal("invalid DNSKEY protocol: %d", protocol); if ((flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) { if (size > 0) fatal("specified null key with non-zero size"); if ((flags & DNS_KEYFLAG_SIGNATORYMASK) != 0) fatal("specified null key with signing authority"); } if ((flags & DNS_KEYFLAG_OWNERMASK) == DNS_KEYOWNER_ZONE && (alg == DNS_KEYALG_DH || alg == DST_ALG_HMACMD5 || alg == DST_ALG_HMACSHA1 || alg == DST_ALG_HMACSHA224 || alg == DST_ALG_HMACSHA256 || alg == DST_ALG_HMACSHA384 || alg == DST_ALG_HMACSHA512)) fatal("a key with algorithm '%s' cannot be a zone key", algname); switch(alg) { case DNS_KEYALG_RSAMD5: case DNS_KEYALG_RSASHA1: case DNS_KEYALG_NSEC3RSASHA1: case DNS_KEYALG_RSASHA256: case DNS_KEYALG_RSASHA512: show_progress = ISC_TRUE; break; case DNS_KEYALG_DH: param = generator; break; case DNS_KEYALG_DSA: case DNS_KEYALG_NSEC3DSA: case DST_ALG_ECCGOST: case DST_ALG_ECDSA256: case DST_ALG_ECDSA384: show_progress = ISC_TRUE; /* fall through */ case DST_ALG_HMACMD5: case DST_ALG_HMACSHA1: case DST_ALG_HMACSHA224: case DST_ALG_HMACSHA256: case DST_ALG_HMACSHA384: case DST_ALG_HMACSHA512: param = 0; break; } if ((flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) null_key = ISC_TRUE; isc_buffer_init(&buf, filename, sizeof(filename) - 1); do { conflict = ISC_FALSE; if (!quiet && show_progress) { fprintf(stderr, "Generating key pair."); ret = dst_key_generate2(name, alg, size, param, flags, protocol, rdclass, mctx, &key, &progress); putc('\n', stderr); fflush(stderr); } else { ret = dst_key_generate2(name, alg, size, param, flags, protocol, rdclass, mctx, &key, NULL); } isc_entropy_stopcallbacksources(ectx); if (ret != ISC_R_SUCCESS) { char namestr[DNS_NAME_FORMATSIZE]; char algstr[DNS_SECALG_FORMATSIZE]; dns_name_format(name, namestr, sizeof(namestr)); dns_secalg_format(alg, algstr, sizeof(algstr)); fatal("failed to generate key %s/%s: %s\n", namestr, algstr, isc_result_totext(ret)); /* NOTREACHED */ exit(-1); } dst_key_setbits(key, dbits); /* * Set key timing metadata (unless using -C) * * Creation date is always set to "now". * * For a new key without an explicit predecessor, publish * and activation dates are set to "now" by default, but * can both be overridden. * * For a successor key, activation is set to match the * predecessor's inactivation date. Publish is set to 30 * days earlier than that (XXX: this should be configurable). * If either of the resulting dates are in the past, that's * an error; the inactivation date of the predecessor key * must be updated before a successor key can be created. */ if (!oldstyle) { dst_key_settime(key, DST_TIME_CREATED, now); if (genonly && (setpub || setact)) fatal("cannot use -G together with " "-P or -A options"); if (setpub) dst_key_settime(key, DST_TIME_PUBLISH, publish); else if (setact && !unsetpub) dst_key_settime(key, DST_TIME_PUBLISH, activate - prepub); else if (!genonly && !unsetpub) dst_key_settime(key, DST_TIME_PUBLISH, now); if (setact) dst_key_settime(key, DST_TIME_ACTIVATE, activate); else if (!genonly && !unsetact) dst_key_settime(key, DST_TIME_ACTIVATE, now); if (setrev) { if (kskflag == 0) fprintf(stderr, "%s: warning: Key is " "not flagged as a KSK, but -R " "was used. Revoking a ZSK is " "legal, but undefined.\n", program); dst_key_settime(key, DST_TIME_REVOKE, revokekey); } if (setinact) dst_key_settime(key, DST_TIME_INACTIVE, inactive); if (setdel) { if (setinact && delete < inactive) fprintf(stderr, "%s: warning: Key is " "scheduled to be deleted " "before it is scheduled to be " "made inactive.\n", program); dst_key_settime(key, DST_TIME_DELETE, delete); } } else { if (setpub || setact || setrev || setinact || setdel || unsetpub || unsetact || unsetrev || unsetinact || unsetdel || genonly) fatal("cannot use -C together with " "-P, -A, -R, -I, -D, or -G options"); /* * Compatibility mode: Private-key-format * should be set to 1.2. */ dst_key_setprivateformat(key, 1, 2); } /* Set the default key TTL */ if (setttl) dst_key_setttl(key, ttl); /* * Do not overwrite an existing key, or create a key * if there is a risk of ID collision due to this key * or another key being revoked. */ if (key_collision(key, name, directory, mctx, NULL)) { conflict = ISC_TRUE; if (null_key) { dst_key_free(&key); break; } if (verbose > 0) { isc_buffer_clear(&buf); ret = dst_key_buildfilename(key, 0, directory, &buf); if (ret == ISC_R_SUCCESS) fprintf(stderr, "%s: %s already exists, or " "might collide with another " "key upon revokation. " "Generating a new key\n", program, filename); } dst_key_free(&key); } } while (conflict == ISC_TRUE); if (conflict) fatal("cannot generate a null key due to possible key ID " "collision"); ret = dst_key_tofile(key, options, directory); if (ret != ISC_R_SUCCESS) { char keystr[DST_KEY_FORMATSIZE]; dst_key_format(key, keystr, sizeof(keystr)); fatal("failed to write key %s: %s\n", keystr, isc_result_totext(ret)); } isc_buffer_clear(&buf); ret = dst_key_buildfilename(key, 0, NULL, &buf); if (ret != ISC_R_SUCCESS) fatal("dst_key_buildfilename returned: %s\n", isc_result_totext(ret)); printf("%s\n", filename); dst_key_free(&key); if (prevkey != NULL) dst_key_free(&prevkey); cleanup_logging(&log); cleanup_entropy(&ectx); dst_lib_destroy(); dns_name_destroy(); if (verbose > 10) isc_mem_stats(mctx, stdout); isc_mem_destroy(&mctx); if (freeit != NULL) free(freeit); return (0); } bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-keyfromlabel.80000644000470500017500000002663312664710322021454 0ustar lamontlamont.\" Copyright (C) 2008-2012, 2014 Internet Systems Consortium, Inc. ("ISC") .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: dnssec\-keyfromlabel .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: February 27, 2014 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "DNSSEC\-KEYFROMLABEL" "8" "February 27, 2014" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" dnssec\-keyfromlabel \- DNSSEC key generation tool .SH "SYNOPSIS" .HP 20 \fBdnssec\-keyfromlabel\fR {\-l\ \fIlabel\fR} [\fB\-3\fR] [\fB\-a\ \fR\fB\fIalgorithm\fR\fR] [\fB\-A\ \fR\fB\fIdate/offset\fR\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-G\fR] [\fB\-I\ \fR\fB\fIdate/offset\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-k\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-L\ \fR\fB\fIttl\fR\fR] [\fB\-n\ \fR\fB\fInametype\fR\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-R\ \fR\fB\fIdate/offset\fR\fR] [\fB\-S\ \fR\fB\fIkey\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-V\fR] [\fB\-y\fR] {name} .SH "DESCRIPTION" .PP \fBdnssec\-keyfromlabel\fR generates a key pair of files that referencing a key object stored in a cryptographic hardware service module (HSM). The private key file can be used for DNSSEC signing of zone data as if it were a conventional signing key created by \fBdnssec\-keygen\fR, but the key material is stored within the HSM, and the actual signing takes place there. .PP The \fBname\fR of the key is specified on the command line. This must match the name of the zone for which the key is being generated. .SH "OPTIONS" .PP \-a \fIalgorithm\fR .RS 4 Selects the cryptographic algorithm. The value of \fBalgorithm\fR must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512, ECCGOST, ECDSAP256SHA256 or ECDSAP384SHA384. These values are case insensitive. .sp If no algorithm is specified, then RSASHA1 will be used by default, unless the \fB\-3\fR option is specified, in which case NSEC3RSASHA1 will be used instead. (If \fB\-3\fR is used and an algorithm is specified, that algorithm will be checked for compatibility with NSEC3.) .sp Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended. .sp Note 2: DH automatically sets the \-k flag. .RE .PP \-3 .RS 4 Use an NSEC3\-capable algorithm to generate a DNSSEC key. If this option is used and no algorithm is explicitly set on the command line, NSEC3RSASHA1 will be used by default. .RE .PP \-E \fIengine\fR .RS 4 Specifies the cryptographic hardware to use. .sp When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (\-\-enable\-native\-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "\-\-with\-pkcs11". .RE .PP \-l \fIlabel\fR .RS 4 Specifies the label for a key pair in the crypto hardware. .sp When BIND 9 is built with OpenSSL\-based PKCS#11 support, the label is an arbitrary string that identifies a particular key. It may be preceded by an optional OpenSSL engine name, followed by a colon, as in "pkcs11:\fIkeylabel\fR". .sp When BIND 9 is built with native PKCS#11 support, the label is a PKCS#11 URI string in the format "pkcs11:\fBkeyword\fR=\fIvalue\fR[;\fBkeyword\fR=\fIvalue\fR;...]" Keywords include "token", which identifies the HSM; "object", which identifies the key; and "pin\-source", which identifies a file from which the HSM's PIN code can be obtained. The label will be stored in the on\-disk "private" file. .sp If the label contains a \fBpin\-source\fR field, tools using the generated key files will be able to use the HSM for signing and other operations without any need for an operator to manually enter a PIN. Note: Making the HSM's PIN accessible in this manner may reduce the security advantage of using an HSM; be sure this is what you want to do before making use of this feature. .RE .PP \-n \fInametype\fR .RS 4 Specifies the owner type of the key. The value of \fBnametype\fR must either be ZONE (for a DNSSEC zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with a host (KEY)), USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). These values are case insensitive. .RE .PP \-C .RS 4 Compatibility mode: generates an old\-style key, without any metadata. By default, \fBdnssec\-keyfromlabel\fR will include the key's creation date in the metadata stored with the private key, and other dates may be set there as well (publication date, activation date, etc). Keys that include this data may be incompatible with older versions of BIND; the \fB\-C\fR option suppresses them. .RE .PP \-c \fIclass\fR .RS 4 Indicates that the DNS record containing the key should have the specified class. If not specified, class IN is used. .RE .PP \-f \fIflag\fR .RS 4 Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flags are KSK (Key Signing Key) and REVOKE. .RE .PP \-G .RS 4 Generate a key, but do not publish it or sign with it. This option is incompatible with \-P and \-A. .RE .PP \-h .RS 4 Prints a short summary of the options and arguments to \fBdnssec\-keyfromlabel\fR. .RE .PP \-K \fIdirectory\fR .RS 4 Sets the directory in which the key files are to be written. .RE .PP \-k .RS 4 Generate KEY records rather than DNSKEY records. .RE .PP \-L \fIttl\fR .RS 4 Sets the default TTL to use for this key when it is converted into a DNSKEY RR. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence. Setting the default TTL to 0 or none removes it. .RE .PP \-p \fIprotocol\fR .RS 4 Sets the protocol value for the key. The protocol is a number between 0 and 255. The default is 3 (DNSSEC). Other possible values for this argument are listed in RFC 2535 and its successors. .RE .PP \-S \fIkey\fR .RS 4 Generate a key as an explicit successor to an existing key. The name, algorithm, size, and type of the key will be set to match the predecessor. The activation date of the new key will be set to the inactivation date of the existing one. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days. .RE .PP \-t \fItype\fR .RS 4 Indicates the use of the key. \fBtype\fR must be one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default is AUTHCONF. AUTH refers to the ability to authenticate data, and CONF the ability to encrypt data. .RE .PP \-v \fIlevel\fR .RS 4 Sets the debugging level. .RE .PP \-V .RS 4 Prints version information. .RE .PP \-y .RS 4 Allows DNSSEC key files to be generated even if the key ID would collide with that of an existing key, in the event of either key being revoked. (This is only safe to use if you are sure you won't be using RFC 5011 trust anchor maintenance with either of the keys involved.) .RE .SH "TIMING OPTIONS" .PP Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '\-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24\-hour days, ignoring leap years), months (defined as 30 24\-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To explicitly prevent a date from being set, use 'none' or 'never'. .PP \-P \fIdate/offset\fR .RS 4 Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it. If not set, and if the \-G option has not been used, the default is "now". .RE .PP \-A \fIdate/offset\fR .RS 4 Sets the date on which the key is to be activated. After that date, the key will be included in the zone and used to sign it. If not set, and if the \-G option has not been used, the default is "now". .RE .PP \-R \fIdate/offset\fR .RS 4 Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it. .RE .PP \-I \fIdate/offset\fR .RS 4 Sets the date on which the key is to be retired. After that date, the key will still be included in the zone, but it will not be used to sign it. .RE .PP \-D \fIdate/offset\fR .RS 4 Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.) .RE .PP \-i \fIinterval\fR .RS 4 Sets the prepublication interval for a key. If set, then the publication and activation dates must be separated by at least this much time. If the activation date is specified but the publication date isn't, then the publication date will default to this much time before the activation date; conversely, if the publication date is specified but activation date isn't, then activation will be set to this much time after publication. .sp If the key is being created as an explicit successor to another key, then the default prepublication interval is 30 days; otherwise it is zero. .sp As with date offsets, if the argument is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the interval is measured in years, months, weeks, days, hours, or minutes, respectively. Without a suffix, the interval is measured in seconds. .RE .SH "GENERATED KEY FILES" .PP When \fBdnssec\-keyfromlabel\fR completes successfully, it prints a string of the form \fIKnnnn.+aaa+iiiii\fR to the standard output. This is an identification string for the key files it has generated. .TP 4 \(bu \fInnnn\fR is the key name. .TP 4 \(bu \fIaaa\fR is the numeric representation of the algorithm. .TP 4 \(bu \fIiiiii\fR is the key identifier (or footprint). .PP \fBdnssec\-keyfromlabel\fR creates two files, with names based on the printed string. \fIKnnnn.+aaa+iiiii.key\fR contains the public key, and \fIKnnnn.+aaa+iiiii.private\fR contains the private key. .PP The \fI.key\fR file contains a DNS KEY record that can be inserted into a zone file (directly or with a $INCLUDE statement). .PP The \fI.private\fR file contains algorithm\-specific fields. For obvious security reasons, this file does not have general read permission. .SH "SEE ALSO" .PP \fBdnssec\-keygen\fR(8), \fBdnssec\-signzone\fR(8), BIND 9 Administrator Reference Manual, RFC 4034, The PKCS#11 URI Scheme (draft\-pechanec\-pkcs11uri\-13). .SH "AUTHOR" .PP Internet Systems Consortium .SH "COPYRIGHT" Copyright \(co 2008\-2012, 2014 Internet Systems Consortium, Inc. ("ISC") .br bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-revoke.80000644000470500017500000000561012664710322020263 0ustar lamontlamont.\" Copyright (C) 2009, 2011, 2014 Internet Systems Consortium, Inc. ("ISC") .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: dnssec\-revoke .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: January 15, 2014 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "DNSSEC\-REVOKE" "8" "January 15, 2014" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" dnssec\-revoke \- Set the REVOKED bit on a DNSSEC key .SH "SYNOPSIS" .HP 14 \fBdnssec\-revoke\fR [\fB\-hr\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-V\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-f\fR] [\fB\-R\fR] {keyfile} .SH "DESCRIPTION" .PP \fBdnssec\-revoke\fR reads a DNSSEC key file, sets the REVOKED bit on the key as defined in RFC 5011, and creates a new pair of key files containing the now\-revoked key. .SH "OPTIONS" .PP \-h .RS 4 Emit usage message and exit. .RE .PP \-K \fIdirectory\fR .RS 4 Sets the directory in which the key files are to reside. .RE .PP \-r .RS 4 After writing the new keyset files remove the original keyset files. .RE .PP \-v \fIlevel\fR .RS 4 Sets the debugging level. .RE .PP \-V .RS 4 Prints version information. .RE .PP \-E \fIengine\fR .RS 4 Specifies the cryptographic hardware to use, when applicable. .sp When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (\-\-enable\-native\-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "\-\-with\-pkcs11". .RE .PP \-f .RS 4 Force overwrite: Causes \fBdnssec\-revoke\fR to write the new key pair even if a file already exists matching the algorithm and key ID of the revoked key. .RE .PP \-R .RS 4 Print the key tag of the key with the REVOKE bit set but do not revoke the key. .RE .SH "SEE ALSO" .PP \fBdnssec\-keygen\fR(8), BIND 9 Administrator Reference Manual, RFC 5011. .SH "AUTHOR" .PP Internet Systems Consortium .SH "COPYRIGHT" Copyright \(co 2009, 2011, 2014 Internet Systems Consortium, Inc. ("ISC") .br bind9-9.10.3.dfsg.P4/bin/dnssec/win32/0002755000470500017500000000000012672612753016374 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/dnssec/win32/verify.vcxproj.in0000644000470500017500000001472312664710322021717 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {FD653434-F1A8-44A9-85B2-A7468491DA6D} Win32Proj verify Application true MultiByte Application false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ dnssec-$(ProjectName) false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ dnssec-$(ProjectName) Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) dnssectool.lib;libisc.lib;libdns.lib;%(AdditionalDependencies) $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Default dnssectool.lib;libisc.lib;libdns.lib;%(AdditionalDependencies) $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) bind9-9.10.3.dfsg.P4/bin/dnssec/win32/keygen.dsp.in0000644000470500017500000001067212664710322020767 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="keygen" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 CFG=keygen - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "keygen.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "keygen.mak" CFG="keygen - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "keygen - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "keygen - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "keygen - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @MACHINE@ # ADD LINK32 user32.lib advapi32.lib Release/dnssectool.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/dnssec-keygen.exe" !ELSEIF "$(CFG)" == "keygen - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c # SUBTRACT CPP /X @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib Debug/dnssectool.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-keygen.exe" /pdbtype:sept !ENDIF # Begin Target # Name "keygen - @PLATFORM@ Release" # Name "keygen - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE="..\dnssec-keygen.c" # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/bin/dnssec/win32/keyfromlabel.vcxproj.filters.in0000644000470500017500000000141112664710322024524 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files bind9-9.10.3.dfsg.P4/bin/dnssec/win32/keygen.vcxproj.filters.in0000644000470500017500000000140312664710322023333 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files bind9-9.10.3.dfsg.P4/bin/dnssec/win32/verify.vcxproj.user0000644000470500017500000000021712664710322022260 0ustar lamontlamont bind9-9.10.3.dfsg.P4/bin/dnssec/win32/dsfromkey.vcxproj.filters.in0000644000470500017500000000140612664710322024057 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files bind9-9.10.3.dfsg.P4/bin/dnssec/win32/signzone.vcxproj.in0000644000470500017500000001472712664710322022253 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {205ED8A9-2E4C-41CC-9385-F3613402AA90} Win32Proj signzone Application true MultiByte Application false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ dnssec-$(ProjectName) false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ dnssec-$(ProjectName) Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) dnssectool.lib;libisc.lib;libdns.lib;%(AdditionalDependencies) Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Default $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) dnssectool.lib;libisc.lib;libdns.lib;%(AdditionalDependencies) bind9-9.10.3.dfsg.P4/bin/dnssec/win32/keygen.vcxproj.in0000644000470500017500000001472312664710322021675 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {0BF11E21-168C-4CAA-B784-429D126BBAE5} Win32Proj keygen Application true MultiByte Application false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ dnssec-$(ProjectName) false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ dnssec-$(ProjectName) Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) dnssectool.lib;libisc.lib;libdns.lib;%(AdditionalDependencies) $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Default dnssectool.lib;libisc.lib;libdns.lib;%(AdditionalDependencies) $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) bind9-9.10.3.dfsg.P4/bin/dnssec/win32/importkey.vcxproj.in0000644000470500017500000001473312664710322022437 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {AB6690A0-055E-458f-BAC5-BF38BCC5834F} Win32Proj importkey Application true MultiByte Application false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ dnssec-$(ProjectName) false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ dnssec-$(ProjectName) Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) dnssectool.lib;libisc.lib;libdns.lib;%(AdditionalDependencies) Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Default $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) dnssectool.lib;libisc.lib;libdns.lib;%(AdditionalDependencies) bind9-9.10.3.dfsg.P4/bin/dnssec/win32/signzone.dsp.in0000644000470500017500000001072612664710322021341 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="signzone" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 CFG=signzone - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "signzone.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "signzone.mak" CFG="signzone - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "signzone - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "signzone - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "signzone - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @MACHINE@ # ADD LINK32 user32.lib advapi32.lib Release/dnssectool.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/dnssec-signzone.exe" !ELSEIF "$(CFG)" == "signzone - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c # SUBTRACT CPP /X @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib Debug/dnssectool.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-signzone.exe" /pdbtype:sept !ENDIF # Begin Target # Name "signzone - @PLATFORM@ Release" # Name "signzone - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE="..\dnssec-signzone.c" # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/bin/dnssec/win32/importkey.mak.in0000644000470500017500000002057612664710322021516 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on importkey.dsp !IF "$(CFG)" == "" CFG=importkey - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to importkey - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "importkey - @PLATFORM@ Release" && "$(CFG)" != "importkey - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "importkey.mak" CFG="importkey - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "importkey - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "importkey - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF !IF "$(CFG)" == "importkey - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "importkey - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release ALL : "..\..\..\Build\Release\dnssec-importkey.exe" CLEAN : -@erase "$(INTDIR)\dnssec-importkey.obj" -@erase "$(INTDIR)\dnssectool.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "..\..\..\Build\Release\dnssec-importkey.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\importkey.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\importkey.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\dnssec-importkey.pdb" @MACHINE@ /out:"../../../Build/Release/dnssec-importkey.exe" LINK32_OBJS= \ "$(INTDIR)\dnssec-importkey.obj" \ "$(INTDIR)\dnssectool.obj" "..\..\..\Build\Release\dnssec-importkey.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "importkey - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros ALL : "..\..\..\Build\Debug\dnssec-importkey.exe" "$(OUTDIR)\importkey.bsc" CLEAN : -@erase "$(INTDIR)\dnssec-importkey.obj" -@erase "$(INTDIR)\dnssec-importkey.sbr" -@erase "$(INTDIR)\dnssectool.obj" -@erase "$(INTDIR)\dnssectool.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\dnssec-importkey.pdb" -@erase "$(OUTDIR)\importkey.bsc" -@erase "..\..\..\Build\Debug\dnssec-importkey.exe" -@erase "..\..\..\Build\Debug\dnssec-importkey.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\importkey.bsc" BSC32_SBRS= \ "$(INTDIR)\dnssec-importkey.sbr" \ "$(INTDIR)\dnssectool.sbr" "$(OUTDIR)\importkey.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\dnssec-importkey.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-importkey.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\dnssec-importkey.obj" \ "$(INTDIR)\dnssectool.obj" "..\..\..\Build\Debug\dnssec-importkey.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("importkey.dep") !INCLUDE "importkey.dep" !ELSE !MESSAGE Warning: cannot find "importkey.dep" !ENDIF !ENDIF !IF "$(CFG)" == "importkey - @PLATFORM@ Release" || "$(CFG)" == "importkey - @PLATFORM@ Debug" SOURCE="..\dnssec-importkey.c" !IF "$(CFG)" == "importkey - @PLATFORM@ Release" "$(INTDIR)\dnssec-importkey.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "importkey - @PLATFORM@ Debug" "$(INTDIR)\dnssec-importkey.obj" "$(INTDIR)\dnssec-importkey.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\dnssectool.c !IF "$(CFG)" == "importkey - @PLATFORM@ Release" "$(INTDIR)\dnssectool.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "importkey - @PLATFORM@ Debug" "$(INTDIR)\dnssectool.obj" "$(INTDIR)\dnssectool.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/bin/dnssec/win32/revoke.dsw0000644000470500017500000000103112664710322020367 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "revoke"=".\revoke.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/bin/dnssec/win32/keyfromlabel.mak.in0000644000470500017500000002102112664710322022131 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on keyfromlabel.dsp !IF "$(CFG)" == "" CFG=keyfromlabel - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to keyfromlabel - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "keyfromlabel - @PLATFORM@ Release" && "$(CFG)" != "keyfromlabel - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "keyfromlabel.mak" CFG="keyfromlabel - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "keyfromlabel - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "keyfromlabel - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF !IF "$(CFG)" == "keyfromlabel - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "keyfromlabel - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release ALL : "..\..\..\Build\Release\dnssec-keyfromlabel.exe" CLEAN : -@erase "$(INTDIR)\dnssec-keyfromlabel.obj" -@erase "$(INTDIR)\dnssectool.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "..\..\..\Build\Release\dnssec-keyfromlabel.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\keyfromlabel.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\keyfromlabel.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\dnssec-keyfromlabel.pdb" @MACHINE@ /out:"../../../Build/Release/dnssec-keyfromlabel.exe" LINK32_OBJS= \ "$(INTDIR)\dnssec-keyfromlabel.obj" \ "$(INTDIR)\dnssectool.obj" "..\..\..\Build\Release\dnssec-keyfromlabel.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "keyfromlabel - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros ALL : "..\..\..\Build\Debug\dnssec-keyfromlabel.exe" "$(OUTDIR)\keyfromlabel.bsc" CLEAN : -@erase "$(INTDIR)\dnssec-keyfromlabel.obj" -@erase "$(INTDIR)\dnssec-keyfromlabel.sbr" -@erase "$(INTDIR)\dnssectool.obj" -@erase "$(INTDIR)\dnssectool.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\dnssec-keyfromlabel.pdb" -@erase "$(OUTDIR)\keyfromlabel.bsc" -@erase "..\..\..\Build\Debug\dnssec-keyfromlabel.exe" -@erase "..\..\..\Build\Debug\dnssec-keyfromlabel.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\keyfromlabel.bsc" BSC32_SBRS= \ "$(INTDIR)\dnssec-keyfromlabel.sbr" \ "$(INTDIR)\dnssectool.sbr" "$(OUTDIR)\keyfromlabel.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\dnssec-keyfromlabel.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-keyfromlabel.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\dnssec-keyfromlabel.obj" \ "$(INTDIR)\dnssectool.obj" "..\..\..\Build\Debug\dnssec-keyfromlabel.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("keyfromlabel.dep") !INCLUDE "keyfromlabel.dep" !ELSE !MESSAGE Warning: cannot find "keyfromlabel.dep" !ENDIF !ENDIF !IF "$(CFG)" == "keyfromlabel - @PLATFORM@ Release" || "$(CFG)" == "keyfromlabel - @PLATFORM@ Debug" SOURCE="..\dnssec-keyfromlabel.c" !IF "$(CFG)" == "keyfromlabel - @PLATFORM@ Release" "$(INTDIR)\dnssec-keyfromlabel.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "keyfromlabel - @PLATFORM@ Debug" "$(INTDIR)\dnssec-keyfromlabel.obj" "$(INTDIR)\dnssec-keyfromlabel.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\dnssectool.c !IF "$(CFG)" == "keyfromlabel - @PLATFORM@ Release" "$(INTDIR)\dnssectool.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "keyfromlabel - @PLATFORM@ Debug" "$(INTDIR)\dnssectool.obj" "$(INTDIR)\dnssectool.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/bin/dnssec/win32/signzone.vcxproj.filters.in0000644000470500017500000000140512664710322023707 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files bind9-9.10.3.dfsg.P4/bin/dnssec/win32/dsfromkey.dsw0000644000470500017500000000103712664710322021105 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "dsfromkey"=".\dsfromkey.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/bin/dnssec/win32/dsfromkey.vcxproj.in0000644000470500017500000001575112664710322022420 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {6E6297F4-69D7-4533-85E1-BD17C30017C8} Win32Proj dsfromkey Application true MultiByte Application false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ dnssec-$(ProjectName) false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ dnssec-$(ProjectName) Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) dnssectool.lib;libisc.lib;libdns.lib;%(AdditionalDependencies) @IF PYTHON cd ..\..\python copy /Y dnssec-checkds.py ..\..\Build\$(Configuration)\dnssec-checkds.py copy /Y dnssec-coverage.py ..\..\Build\$(Configuration)\dnssec-coverage.py @END PYTHON Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Default $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) dnssectool.lib;libisc.lib;libdns.lib;%(AdditionalDependencies) @IF PYTHON cd ..\..\python copy /Y dnssec-checkds.py ..\..\Build\$(Configuration)\dnssec-checkds.py copy /Y dnssec-coverage.py ..\..\Build\$(Configuration)\dnssec-coverage.py @END PYTHON bind9-9.10.3.dfsg.P4/bin/dnssec/win32/settime.vcxproj.user0000644000470500017500000000021712664710322022426 0ustar lamontlamont bind9-9.10.3.dfsg.P4/bin/dnssec/win32/importkey.vcxproj.filters.in0000644000470500017500000000141012664710322024072 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files bind9-9.10.3.dfsg.P4/bin/dnssec/win32/signzone.dsw0000644000470500017500000000103512664710322020734 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "signzone"=".\signzone.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/bin/dnssec/win32/settime.dsp.in0000644000470500017500000001071012664710322021150 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="settime" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 CFG=settime - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "settime.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "settime.mak" CFG="settime - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "settime - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "settime - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "settime - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @MACHINE@ # ADD LINK32 user32.lib advapi32.lib Release/dnssectool.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/dnssec-settime.exe" !ELSEIF "$(CFG)" == "settime - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c # SUBTRACT CPP /X @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib Debug/dnssectool.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-settime.exe" /pdbtype:sept !ENDIF # Begin Target # Name "settime - @PLATFORM@ Release" # Name "settime - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE="..\dnssec-settime.c" # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/bin/dnssec/win32/settime.mak.in0000644000470500017500000002043412664710322021136 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on settime.dsp !IF "$(CFG)" == "" CFG=settime - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to settime - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "settime - @PLATFORM@ Release" && "$(CFG)" != "settime - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "settime.mak" CFG="settime - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "settime - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "settime - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF !IF "$(CFG)" == "settime - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "settime - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release ALL : "..\..\..\Build\Release\dnssec-settime.exe" CLEAN : -@erase "$(INTDIR)\dnssec-settime.obj" -@erase "$(INTDIR)\dnssectool.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "..\..\..\Build\Release\dnssec-settime.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\settime.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\settime.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\dnssec-settime.pdb" @MACHINE@ /out:"../../../Build/Release/dnssec-settime.exe" LINK32_OBJS= \ "$(INTDIR)\dnssec-settime.obj" \ "$(INTDIR)\dnssectool.obj" "..\..\..\Build\Release\dnssec-settime.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "settime - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros ALL : "..\..\..\Build\Debug\dnssec-settime.exe" "$(OUTDIR)\settime.bsc" CLEAN : -@erase "$(INTDIR)\dnssec-settime.obj" -@erase "$(INTDIR)\dnssec-settime.sbr" -@erase "$(INTDIR)\dnssectool.obj" -@erase "$(INTDIR)\dnssectool.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\dnssec-settime.pdb" -@erase "$(OUTDIR)\settime.bsc" -@erase "..\..\..\Build\Debug\dnssec-settime.exe" -@erase "..\..\..\Build\Debug\dnssec-settime.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\settime.bsc" BSC32_SBRS= \ "$(INTDIR)\dnssec-settime.sbr" \ "$(INTDIR)\dnssectool.sbr" "$(OUTDIR)\settime.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\dnssec-settime.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-settime.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\dnssec-settime.obj" \ "$(INTDIR)\dnssectool.obj" "..\..\..\Build\Debug\dnssec-settime.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("settime.dep") !INCLUDE "settime.dep" !ELSE !MESSAGE Warning: cannot find "settime.dep" !ENDIF !ENDIF !IF "$(CFG)" == "settime - @PLATFORM@ Release" || "$(CFG)" == "settime - @PLATFORM@ Debug" SOURCE="..\dnssec-settime.c" !IF "$(CFG)" == "settime - @PLATFORM@ Release" "$(INTDIR)\dnssec-settime.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "settime - @PLATFORM@ Debug" "$(INTDIR)\dnssec-settime.obj" "$(INTDIR)\dnssec-settime.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\dnssectool.c !IF "$(CFG)" == "settime - @PLATFORM@ Release" "$(INTDIR)\dnssectool.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "settime - @PLATFORM@ Debug" "$(INTDIR)\dnssectool.obj" "$(INTDIR)\dnssectool.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/bin/dnssec/win32/dsfromkey.vcxproj.user0000644000470500017500000000021712664710322022757 0ustar lamontlamont bind9-9.10.3.dfsg.P4/bin/dnssec/win32/signzone.vcxproj.user0000644000470500017500000000021712664710322022610 0ustar lamontlamont bind9-9.10.3.dfsg.P4/bin/dnssec/win32/revoke.vcxproj.user0000644000470500017500000000021712664710322022247 0ustar lamontlamont bind9-9.10.3.dfsg.P4/bin/dnssec/win32/revoke.mak.in0000644000470500017500000002035312664710322020757 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on revoke.dsp !IF "$(CFG)" == "" CFG=revoke - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to revoke - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "revoke - @PLATFORM@ Release" && "$(CFG)" != "revoke - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "revoke.mak" CFG="revoke - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "revoke - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "revoke - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF !IF "$(CFG)" == "revoke - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "revoke - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release ALL : "..\..\..\Build\Release\dnssec-revoke.exe" CLEAN : -@erase "$(INTDIR)\dnssec-revoke.obj" -@erase "$(INTDIR)\dnssectool.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "..\..\..\Build\Release\dnssec-revoke.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\revoke.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\revoke.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\dnssec-revoke.pdb" @MACHINE@ /out:"../../../Build/Release/dnssec-revoke.exe" LINK32_OBJS= \ "$(INTDIR)\dnssec-revoke.obj" \ "$(INTDIR)\dnssectool.obj" "..\..\..\Build\Release\dnssec-revoke.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "revoke - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros ALL : "..\..\..\Build\Debug\dnssec-revoke.exe" "$(OUTDIR)\revoke.bsc" CLEAN : -@erase "$(INTDIR)\dnssec-revoke.obj" -@erase "$(INTDIR)\dnssec-revoke.sbr" -@erase "$(INTDIR)\dnssectool.obj" -@erase "$(INTDIR)\dnssectool.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\dnssec-revoke.pdb" -@erase "$(OUTDIR)\revoke.bsc" -@erase "..\..\..\Build\Debug\dnssec-revoke.exe" -@erase "..\..\..\Build\Debug\dnssec-revoke.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\revoke.bsc" BSC32_SBRS= \ "$(INTDIR)\dnssec-revoke.sbr" \ "$(INTDIR)\dnssectool.sbr" "$(OUTDIR)\revoke.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\dnssec-revoke.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-revoke.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\dnssec-revoke.obj" \ "$(INTDIR)\dnssectool.obj" "..\..\..\Build\Debug\dnssec-revoke.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("revoke.dep") !INCLUDE "revoke.dep" !ELSE !MESSAGE Warning: cannot find "revoke.dep" !ENDIF !ENDIF !IF "$(CFG)" == "revoke - @PLATFORM@ Release" || "$(CFG)" == "revoke - @PLATFORM@ Debug" SOURCE="..\dnssec-revoke.c" !IF "$(CFG)" == "revoke - @PLATFORM@ Release" "$(INTDIR)\dnssec-revoke.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "revoke - @PLATFORM@ Debug" "$(INTDIR)\dnssec-revoke.obj" "$(INTDIR)\dnssec-revoke.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\dnssectool.c !IF "$(CFG)" == "revoke - @PLATFORM@ Release" "$(INTDIR)\dnssectool.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "revoke - @PLATFORM@ Debug" "$(INTDIR)\dnssectool.obj" "$(INTDIR)\dnssectool.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/bin/dnssec/win32/dsfromkey.dsp.in0000644000470500017500000001074412664710322021510 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="dsfromkey" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 CFG=dsfromkey - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "dsfromkey.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "dsfromkey.mak" CFG="dsfromkey - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "dsfromkey - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "dsfromkey - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "dsfromkey - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @MACHINE@ # ADD LINK32 user32.lib advapi32.lib Release/dnssectool.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/dnssec-dsfromkey.exe" !ELSEIF "$(CFG)" == "dsfromkey - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c # SUBTRACT CPP /X @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib Debug/dnssectool.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-dsfromkey.exe" /pdbtype:sept !ENDIF # Begin Target # Name "dsfromkey - @PLATFORM@ Release" # Name "dsfromkey - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE="..\dnssec-dsfromkey.c" # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/bin/dnssec/win32/dnssectool.vcxproj.user0000644000470500017500000000021712664710322023131 0ustar lamontlamont bind9-9.10.3.dfsg.P4/bin/dnssec/win32/keygen.vcxproj.user0000644000470500017500000000021712664710322022236 0ustar lamontlamont bind9-9.10.3.dfsg.P4/bin/dnssec/win32/verify.dsp.in0000644000470500017500000001067212664710322021011 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="verify" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 CFG=verify - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "verify.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "verify.mak" CFG="verify - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "verify - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "verify - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "verify - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @MACHINE@ # ADD LINK32 user32.lib advapi32.lib Release/dnssectool.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/dnssec-verify.exe" !ELSEIF "$(CFG)" == "verify - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c # SUBTRACT CPP /X @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib Debug/dnssectool.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-verify.exe" /pdbtype:sept !ENDIF # Begin Target # Name "verify - @PLATFORM@ Release" # Name "verify - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE="..\dnssec-verify.c" # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/bin/dnssec/win32/keyfromlabel.dsp.in0000644000470500017500000001101612664710322022152 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="keyfromlabel" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 CFG=keyfromlabel - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "keyfromlabel.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "keyfromlabel.mak" CFG="keyfromlabel - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "keyfromlabel - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "keyfromlabel - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "keyfromlabel - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @MACHINE@ # ADD LINK32 user32.lib advapi32.lib Release/dnssectool.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/dnssec-keyfromlabel.exe" !ELSEIF "$(CFG)" == "keyfromlabel - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c # SUBTRACT CPP /X @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib Debug/dnssectool.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-keyfromlabel.exe" /pdbtype:sept !ENDIF # Begin Target # Name "keyfromlabel - @PLATFORM@ Release" # Name "keyfromlabel - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE="..\dnssec-keyfromlabel.c" # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/bin/dnssec/win32/keygen.mak.in0000644000470500017500000002035312664710322020746 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on keygen.dsp !IF "$(CFG)" == "" CFG=keygen - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to keygen - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "keygen - @PLATFORM@ Release" && "$(CFG)" != "keygen - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "keygen.mak" CFG="keygen - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "keygen - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "keygen - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF !IF "$(CFG)" == "keygen - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "keygen - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release ALL : "..\..\..\Build\Release\dnssec-keygen.exe" CLEAN : -@erase "$(INTDIR)\dnssec-keygen.obj" -@erase "$(INTDIR)\dnssectool.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "..\..\..\Build\Release\dnssec-keygen.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\keygen.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\keygen.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\dnssec-keygen.pdb" @MACHINE@ /out:"../../../Build/Release/dnssec-keygen.exe" LINK32_OBJS= \ "$(INTDIR)\dnssec-keygen.obj" \ "$(INTDIR)\dnssectool.obj" "..\..\..\Build\Release\dnssec-keygen.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "keygen - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros ALL : "..\..\..\Build\Debug\dnssec-keygen.exe" "$(OUTDIR)\keygen.bsc" CLEAN : -@erase "$(INTDIR)\dnssec-keygen.obj" -@erase "$(INTDIR)\dnssec-keygen.sbr" -@erase "$(INTDIR)\dnssectool.obj" -@erase "$(INTDIR)\dnssectool.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\dnssec-keygen.pdb" -@erase "$(OUTDIR)\keygen.bsc" -@erase "..\..\..\Build\Debug\dnssec-keygen.exe" -@erase "..\..\..\Build\Debug\dnssec-keygen.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\keygen.bsc" BSC32_SBRS= \ "$(INTDIR)\dnssec-keygen.sbr" \ "$(INTDIR)\dnssectool.sbr" "$(OUTDIR)\keygen.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\dnssec-keygen.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-keygen.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\dnssec-keygen.obj" \ "$(INTDIR)\dnssectool.obj" "..\..\..\Build\Debug\dnssec-keygen.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("keygen.dep") !INCLUDE "keygen.dep" !ELSE !MESSAGE Warning: cannot find "keygen.dep" !ENDIF !ENDIF !IF "$(CFG)" == "keygen - @PLATFORM@ Release" || "$(CFG)" == "keygen - @PLATFORM@ Debug" SOURCE="..\dnssec-keygen.c" !IF "$(CFG)" == "keygen - @PLATFORM@ Release" "$(INTDIR)\dnssec-keygen.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "keygen - @PLATFORM@ Debug" "$(INTDIR)\dnssec-keygen.obj" "$(INTDIR)\dnssec-keygen.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\dnssectool.c !IF "$(CFG)" == "keygen - @PLATFORM@ Release" "$(INTDIR)\dnssectool.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "keygen - @PLATFORM@ Debug" "$(INTDIR)\dnssectool.obj" "$(INTDIR)\dnssectool.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/bin/dnssec/win32/verify.mak.in0000644000470500017500000002035312664710322020770 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on verify.dsp !IF "$(CFG)" == "" CFG=verify - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to verify - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "verify - @PLATFORM@ Release" && "$(CFG)" != "verify - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "verify.mak" CFG="verify - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "verify - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "verify - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF !IF "$(CFG)" == "verify - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "verify - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release ALL : "..\..\..\Build\Release\dnssec-verify.exe" CLEAN : -@erase "$(INTDIR)\dnssec-verify.obj" -@erase "$(INTDIR)\dnssectool.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "..\..\..\Build\Release\dnssec-verify.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\verify.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\verify.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\dnssec-verify.pdb" @MACHINE@ /out:"../../../Build/Release/dnssec-verify.exe" LINK32_OBJS= \ "$(INTDIR)\dnssec-verify.obj" \ "$(INTDIR)\dnssectool.obj" "..\..\..\Build\Release\dnssec-verify.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "verify - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros ALL : "..\..\..\Build\Debug\dnssec-verify.exe" "$(OUTDIR)\verify.bsc" CLEAN : -@erase "$(INTDIR)\dnssec-verify.obj" -@erase "$(INTDIR)\dnssec-verify.sbr" -@erase "$(INTDIR)\dnssectool.obj" -@erase "$(INTDIR)\dnssectool.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\dnssec-verify.pdb" -@erase "$(OUTDIR)\verify.bsc" -@erase "..\..\..\Build\Debug\dnssec-verify.exe" -@erase "..\..\..\Build\Debug\dnssec-verify.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\verify.bsc" BSC32_SBRS= \ "$(INTDIR)\dnssec-verify.sbr" \ "$(INTDIR)\dnssectool.sbr" "$(OUTDIR)\verify.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\dnssec-verify.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-verify.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\dnssec-verify.obj" \ "$(INTDIR)\dnssectool.obj" "..\..\..\Build\Debug\dnssec-verify.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("verify.dep") !INCLUDE "verify.dep" !ELSE !MESSAGE Warning: cannot find "verify.dep" !ENDIF !ENDIF !IF "$(CFG)" == "verify - @PLATFORM@ Release" || "$(CFG)" == "verify - @PLATFORM@ Debug" SOURCE="..\dnssec-verify.c" !IF "$(CFG)" == "verify - @PLATFORM@ Release" "$(INTDIR)\dnssec-verify.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "verify - @PLATFORM@ Debug" "$(INTDIR)\dnssec-verify.obj" "$(INTDIR)\dnssec-verify.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\dnssectool.c !IF "$(CFG)" == "verify - @PLATFORM@ Release" "$(INTDIR)\dnssectool.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "verify - @PLATFORM@ Debug" "$(INTDIR)\dnssectool.obj" "$(INTDIR)\dnssectool.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/bin/dnssec/win32/dnssectool.dsw0000644000470500017500000000104112664710322021252 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "dnssectool"=".\dnssectool.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/bin/dnssec/win32/settime.dsw0000644000470500017500000000103312664710322020550 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "settime"=".\settime.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/bin/dnssec/win32/keyfromlabel.vcxproj.user0000644000470500017500000000021712664710322023430 0ustar lamontlamont bind9-9.10.3.dfsg.P4/bin/dnssec/win32/importkey.dsp.in0000644000470500017500000001074412664710322021530 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="importkey" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 CFG=importkey - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "importkey.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "importkey.mak" CFG="importkey - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "importkey - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "importkey - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "importkey - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @MACHINE@ # ADD LINK32 user32.lib advapi32.lib Release/dnssectool.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/dnssec-importkey.exe" !ELSEIF "$(CFG)" == "importkey - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c # SUBTRACT CPP /X @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib Debug/dnssectool.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-importkey.exe" /pdbtype:sept !ENDIF # Begin Target # Name "importkey - @PLATFORM@ Release" # Name "importkey - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE="..\dnssec-importkey.c" # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/bin/dnssec/win32/verify.vcxproj.filters.in0000644000470500017500000000140312664710322023355 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files bind9-9.10.3.dfsg.P4/bin/dnssec/win32/settime.vcxproj.filters.in0000644000470500017500000000140412664710322023524 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files bind9-9.10.3.dfsg.P4/bin/dnssec/win32/dsfromkey.mak.in0000644000470500017500000002057612664710322021476 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on dsfromkey.dsp !IF "$(CFG)" == "" CFG=dsfromkey - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to dsfromkey - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "dsfromkey - @PLATFORM@ Release" && "$(CFG)" != "dsfromkey - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "dsfromkey.mak" CFG="dsfromkey - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "dsfromkey - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "dsfromkey - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF !IF "$(CFG)" == "dsfromkey - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "dsfromkey - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release ALL : "..\..\..\Build\Release\dnssec-dsfromkey.exe" CLEAN : -@erase "$(INTDIR)\dnssec-dsfromkey.obj" -@erase "$(INTDIR)\dnssectool.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "..\..\..\Build\Release\dnssec-dsfromkey.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\dsfromkey.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\dsfromkey.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\dnssec-dsfromkey.pdb" @MACHINE@ /out:"../../../Build/Release/dnssec-dsfromkey.exe" LINK32_OBJS= \ "$(INTDIR)\dnssec-dsfromkey.obj" \ "$(INTDIR)\dnssectool.obj" "..\..\..\Build\Release\dnssec-dsfromkey.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "dsfromkey - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros ALL : "..\..\..\Build\Debug\dnssec-dsfromkey.exe" "$(OUTDIR)\dsfromkey.bsc" CLEAN : -@erase "$(INTDIR)\dnssec-dsfromkey.obj" -@erase "$(INTDIR)\dnssec-dsfromkey.sbr" -@erase "$(INTDIR)\dnssectool.obj" -@erase "$(INTDIR)\dnssectool.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\dnssec-dsfromkey.pdb" -@erase "$(OUTDIR)\dsfromkey.bsc" -@erase "..\..\..\Build\Debug\dnssec-dsfromkey.exe" -@erase "..\..\..\Build\Debug\dnssec-dsfromkey.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\dsfromkey.bsc" BSC32_SBRS= \ "$(INTDIR)\dnssec-dsfromkey.sbr" \ "$(INTDIR)\dnssectool.sbr" "$(OUTDIR)\dsfromkey.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\dnssec-dsfromkey.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-dsfromkey.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\dnssec-dsfromkey.obj" \ "$(INTDIR)\dnssectool.obj" "..\..\..\Build\Debug\dnssec-dsfromkey.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("dsfromkey.dep") !INCLUDE "dsfromkey.dep" !ELSE !MESSAGE Warning: cannot find "dsfromkey.dep" !ENDIF !ENDIF !IF "$(CFG)" == "dsfromkey - @PLATFORM@ Release" || "$(CFG)" == "dsfromkey - @PLATFORM@ Debug" SOURCE="..\dnssec-dsfromkey.c" !IF "$(CFG)" == "dsfromkey - @PLATFORM@ Release" "$(INTDIR)\dnssec-dsfromkey.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "dsfromkey - @PLATFORM@ Debug" "$(INTDIR)\dnssec-dsfromkey.obj" "$(INTDIR)\dnssec-dsfromkey.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\dnssectool.c !IF "$(CFG)" == "dsfromkey - @PLATFORM@ Release" "$(INTDIR)\dnssectool.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "dsfromkey - @PLATFORM@ Debug" "$(INTDIR)\dnssectool.obj" "$(INTDIR)\dnssectool.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/bin/dnssec/win32/revoke.dsp.in0000644000470500017500000001067212664710322021000 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="revoke" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 CFG=revoke - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "revoke.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "revoke.mak" CFG="revoke - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "revoke - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "revoke - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "revoke - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @MACHINE@ # ADD LINK32 user32.lib advapi32.lib Release/dnssectool.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib /nologo /subsystem:console @MACHINE@ /out:"../../../Build/Release/dnssec-revoke.exe" !ELSEIF "$(CFG)" == "revoke - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c # SUBTRACT CPP /X @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept # ADD LINK32 user32.lib advapi32.lib Debug/dnssectool.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib /nologo /subsystem:console /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-revoke.exe" /pdbtype:sept !ENDIF # Begin Target # Name "revoke - @PLATFORM@ Release" # Name "revoke - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE="..\dnssec-revoke.c" # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/bin/dnssec/win32/signzone.mak.in0000644000470500017500000002051512664710322021320 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on signzone.dsp !IF "$(CFG)" == "" CFG=signzone - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to signzone - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "signzone - @PLATFORM@ Release" && "$(CFG)" != "signzone - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "signzone.mak" CFG="signzone - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "signzone - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "signzone - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF !IF "$(CFG)" == "signzone - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "signzone - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release ALL : "..\..\..\Build\Release\dnssec-signzone.exe" CLEAN : -@erase "$(INTDIR)\dnssec-signzone.obj" -@erase "$(INTDIR)\dnssectool.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "..\..\..\Build\Release\dnssec-signzone.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "NDEBUG" /D "__STDC__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\signzone.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\signzone.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Release/libisc.lib ../../../lib/dns/win32/Release/libdns.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\dnssec-signzone.pdb" @MACHINE@ /out:"../../../Build/Release/dnssec-signzone.exe" LINK32_OBJS= \ "$(INTDIR)\dnssec-signzone.obj" \ "$(INTDIR)\dnssectool.obj" "..\..\..\Build\Release\dnssec-signzone.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "signzone - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros ALL : "..\..\..\Build\Debug\dnssec-signzone.exe" "$(OUTDIR)\signzone.bsc" CLEAN : -@erase "$(INTDIR)\dnssec-signzone.obj" -@erase "$(INTDIR)\dnssec-signzone.sbr" -@erase "$(INTDIR)\dnssectool.obj" -@erase "$(INTDIR)\dnssectool.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\dnssec-signzone.pdb" -@erase "$(OUTDIR)\signzone.bsc" -@erase "..\..\..\Build\Debug\dnssec-signzone.exe" -@erase "..\..\..\Build\Debug\dnssec-signzone.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "_DEBUG" /D "WIN32" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\signzone.bsc" BSC32_SBRS= \ "$(INTDIR)\dnssec-signzone.sbr" \ "$(INTDIR)\dnssectool.sbr" "$(OUTDIR)\signzone.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib ../../../lib/isc/win32/Debug/libisc.lib ../../../lib/dns/win32/Debug/libdns.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\dnssec-signzone.pdb" /debug @MACHINE@ /out:"../../../Build/Debug/dnssec-signzone.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\dnssec-signzone.obj" \ "$(INTDIR)\dnssectool.obj" "..\..\..\Build\Debug\dnssec-signzone.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("signzone.dep") !INCLUDE "signzone.dep" !ELSE !MESSAGE Warning: cannot find "signzone.dep" !ENDIF !ENDIF !IF "$(CFG)" == "signzone - @PLATFORM@ Release" || "$(CFG)" == "signzone - @PLATFORM@ Debug" SOURCE="..\dnssec-signzone.c" !IF "$(CFG)" == "signzone - @PLATFORM@ Release" "$(INTDIR)\dnssec-signzone.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "signzone - @PLATFORM@ Debug" "$(INTDIR)\dnssec-signzone.obj" "$(INTDIR)\dnssec-signzone.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF SOURCE=..\dnssectool.c !IF "$(CFG)" == "signzone - @PLATFORM@ Release" "$(INTDIR)\dnssectool.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "signzone - @PLATFORM@ Debug" "$(INTDIR)\dnssectool.obj" "$(INTDIR)\dnssectool.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/bin/dnssec/win32/importkey.dsw0000644000470500017500000000103712664710322021125 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "importkey"=".\importkey.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/bin/dnssec/win32/keygen.dsw0000644000470500017500000000103112664710322020356 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "keygen"=".\keygen.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/bin/dnssec/win32/revoke.vcxproj.filters.in0000644000470500017500000000140312664710322023344 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files bind9-9.10.3.dfsg.P4/bin/dnssec/win32/dnssectool.dsp.in0000644000470500017500000000753212664710322021663 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="dnssectool" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Static-Link Library" 0x0104 CFG=dnssectool - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "dnssectool.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "dnssectool.mak" CFG="dnssectool - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "dnssectool - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Static-Link Library") !MESSAGE "dnssectool - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Static-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "dnssectool - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" @COPTY@ /FD /c /Fddnssectool # SUBTRACT CPP /X # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 # ADD LINK32 /out:"Release/dnssectool.lib" !ELSEIF "$(CFG)" == "dnssectool - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../" @LIBXML2_INC@ @OPENSSL_INC@ /I "../include" /I "../../../lib/isc/win32" /I "../../../lib/isc/win32/include" /I "../../../lib/isc/include" /I "../../../lib/dns/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "__STDC__" /D "_MBCS" /FR @COPTY@ /FD /GZ /c /Fddnssectool # SUBTRACT CPP /X # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 # ADD LINK32 /debug out:"Debug/dnssectool.lib" !ENDIF # Begin Target # Name "dnssectool - @PLATFORM@ Release" # Name "dnssectool - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # Begin Group "Main Dns Lib" # PROP Default_Filter "c" # Begin Source File SOURCE=..\dnssectool.c # End Source File # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/bin/dnssec/win32/keyfromlabel.vcxproj.in0000644000470500017500000001473712664710322023074 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {17455DC6-5FBB-47C3-8F44-7DB574A188D3} Win32Proj keyfromlabel Application true MultiByte Application false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ dnssec-$(ProjectName) false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ dnssec-$(ProjectName) Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) dnssectool.lib;libisc.lib;libdns.lib;%(AdditionalDependencies) Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Default $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) dnssectool.lib;libisc.lib;libdns.lib;%(AdditionalDependencies) bind9-9.10.3.dfsg.P4/bin/dnssec/win32/revoke.vcxproj.in0000644000470500017500000001472312664710322021706 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {D171F185-D3C2-4463-9CF3-ED1D0B1D6832} Win32Proj revoke Application true MultiByte Application false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ dnssec-$(ProjectName) false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ dnssec-$(ProjectName) Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) dnssectool.lib;libisc.lib;libdns.lib;%(AdditionalDependencies) Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Default $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) dnssectool.lib;libisc.lib;libdns.lib;%(AdditionalDependencies) bind9-9.10.3.dfsg.P4/bin/dnssec/win32/dnssectool.vcxproj.filters.in0000644000470500017500000000210112664710322024222 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Header Files Source Files bind9-9.10.3.dfsg.P4/bin/dnssec/win32/verify.dsw0000644000470500017500000000103112664710322020400 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "verify"=".\verify.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/bin/dnssec/win32/settime.vcxproj.in0000644000470500017500000001472512664710322022067 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {03FB7588-C5A7-4572-968F-14F1206BC69C} Win32Proj settime Application true MultiByte Application false true MultiByte true ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ dnssec-$(ProjectName) false ..\..\..\Build\$(Configuration)\ .\$(Configuration)\ dnssec-$(ProjectName) Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) Console true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) dnssectool.lib;libisc.lib;libdns.lib;%(AdditionalDependencies) $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(ProjectName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) Console false true true ..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Default dnssectool.lib;libisc.lib;libdns.lib;%(AdditionalDependencies) $(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories) bind9-9.10.3.dfsg.P4/bin/dnssec/win32/keyfromlabel.dsw0000644000470500017500000000104512664710322021555 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "keyfromlabel"=".\keyfromlabel.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/bin/dnssec/win32/dnssectool.vcxproj.in0000644000470500017500000001336212664710322022566 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {2CB7DC75-023B-4AA3-AF3A-AE5046A4EE70} Win32Proj dnssectool StaticLibrary true MultiByte StaticLibrary false true MultiByte .\$(Configuration)\ .\$(Configuration)\ .\$(Configuration)\ .\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\include;..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) Windows true Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb .\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\include;..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories) Windows true true true false bind9-9.10.3.dfsg.P4/bin/dnssec/win32/importkey.vcxproj.user0000644000470500017500000000021712664710322022777 0ustar lamontlamont bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-revoke.c0000644000470500017500000001672112664710322020343 0ustar lamontlamont/* * Copyright (C) 2009-2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /*! \file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef PKCS11CRYPTO #include #endif #include "dnssectool.h" const char *program = "dnssec-revoke"; int verbose; static isc_mem_t *mctx = NULL; ISC_PLATFORM_NORETURN_PRE static void usage(void) ISC_PLATFORM_NORETURN_POST; static void usage(void) { fprintf(stderr, "Usage:\n"); fprintf(stderr, " %s [options] keyfile\n\n", program); fprintf(stderr, "Version: %s\n", VERSION); #if defined(PKCS11CRYPTO) fprintf(stderr, " -E engine: specify PKCS#11 provider " "(default: %s)\n", PK11_LIB_LOCATION); #elif defined(USE_PKCS11) fprintf(stderr, " -E engine: specify OpenSSL engine " "(default \"pkcs11\")\n"); #else fprintf(stderr, " -E engine: specify OpenSSL engine\n"); #endif fprintf(stderr, " -f: force overwrite\n"); fprintf(stderr, " -K directory: use directory for key files\n"); fprintf(stderr, " -h: help\n"); fprintf(stderr, " -r: remove old keyfiles after " "creating revoked version\n"); fprintf(stderr, " -v level: set level of verbosity\n"); fprintf(stderr, " -V: print version information\n"); fprintf(stderr, "Output:\n"); fprintf(stderr, " K++.key, " "K++.private\n"); exit (-1); } int main(int argc, char **argv) { isc_result_t result; #ifdef USE_PKCS11 const char *engine = PKCS11_ENGINE; #else const char *engine = NULL; #endif char *filename = NULL, *dir = NULL; char newname[1024], oldname[1024]; char keystr[DST_KEY_FORMATSIZE]; char *endp; int ch; isc_entropy_t *ectx = NULL; dst_key_t *key = NULL; isc_uint32_t flags; isc_buffer_t buf; isc_boolean_t force = ISC_FALSE; isc_boolean_t removefile = ISC_FALSE; isc_boolean_t id = ISC_FALSE; if (argc == 1) usage(); result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) fatal("Out of memory"); #ifdef PKCS11CRYPTO pk11_result_register(); #endif dns_result_register(); isc_commandline_errprint = ISC_FALSE; while ((ch = isc_commandline_parse(argc, argv, "E:fK:rRhv:V")) != -1) { switch (ch) { case 'E': engine = isc_commandline_argument; break; case 'f': force = ISC_TRUE; break; case 'K': /* * We don't have to copy it here, but do it to * simplify cleanup later */ dir = isc_mem_strdup(mctx, isc_commandline_argument); if (dir == NULL) { fatal("Failed to allocate memory for " "directory"); } break; case 'r': removefile = ISC_TRUE; break; case 'R': id = ISC_TRUE; break; case 'v': verbose = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') fatal("-v must be followed by a number"); break; case '?': if (isc_commandline_option != '?') fprintf(stderr, "%s: invalid argument -%c\n", program, isc_commandline_option); /* Falls into */ case 'h': /* Does not return. */ usage(); case 'V': /* Does not return. */ version(program); default: fprintf(stderr, "%s: unhandled option -%c\n", program, isc_commandline_option); exit(1); } } if (argc < isc_commandline_index + 1 || argv[isc_commandline_index] == NULL) fatal("The key file name was not specified"); if (argc > isc_commandline_index + 1) fatal("Extraneous arguments"); if (dir != NULL) { filename = argv[isc_commandline_index]; } else { result = isc_file_splitpath(mctx, argv[isc_commandline_index], &dir, &filename); if (result != ISC_R_SUCCESS) fatal("cannot process filename %s: %s", argv[isc_commandline_index], isc_result_totext(result)); if (strcmp(dir, ".") == 0) { isc_mem_free(mctx, dir); dir = NULL; } } if (ectx == NULL) setup_entropy(mctx, NULL, &ectx); result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (result != ISC_R_SUCCESS) fatal("Could not initialize hash"); result = dst_lib_init2(mctx, ectx, engine, ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); if (result != ISC_R_SUCCESS) fatal("Could not initialize dst: %s", isc_result_totext(result)); isc_entropy_stopcallbacksources(ectx); result = dst_key_fromnamedfile(filename, dir, DST_TYPE_PUBLIC|DST_TYPE_PRIVATE, mctx, &key); if (result != ISC_R_SUCCESS) fatal("Invalid keyfile name %s: %s", filename, isc_result_totext(result)); if (id) { fprintf(stdout, "%u\n", dst_key_rid(key)); goto cleanup; } dst_key_format(key, keystr, sizeof(keystr)); if (verbose > 2) fprintf(stderr, "%s: %s\n", program, keystr); if (force) set_keyversion(key); else check_keyversion(key, keystr); flags = dst_key_flags(key); if ((flags & DNS_KEYFLAG_REVOKE) == 0) { isc_stdtime_t now; if ((flags & DNS_KEYFLAG_KSK) == 0) fprintf(stderr, "%s: warning: Key is not flagged " "as a KSK. Revoking a ZSK is " "legal, but undefined.\n", program); isc_stdtime_get(&now); dst_key_settime(key, DST_TIME_REVOKE, now); dst_key_setflags(key, flags | DNS_KEYFLAG_REVOKE); isc_buffer_init(&buf, newname, sizeof(newname)); dst_key_buildfilename(key, DST_TYPE_PUBLIC, dir, &buf); if (access(newname, F_OK) == 0 && !force) { fatal("Key file %s already exists; " "use -f to force overwrite", newname); } result = dst_key_tofile(key, DST_TYPE_PUBLIC|DST_TYPE_PRIVATE, dir); if (result != ISC_R_SUCCESS) { dst_key_format(key, keystr, sizeof(keystr)); fatal("Failed to write key %s: %s", keystr, isc_result_totext(result)); } isc_buffer_clear(&buf); dst_key_buildfilename(key, 0, dir, &buf); printf("%s\n", newname); /* * Remove old key file, if told to (and if * it isn't the same as the new file) */ if (removefile && dst_key_alg(key) != DST_ALG_RSAMD5) { isc_buffer_init(&buf, oldname, sizeof(oldname)); dst_key_setflags(key, flags & ~DNS_KEYFLAG_REVOKE); dst_key_buildfilename(key, DST_TYPE_PRIVATE, dir, &buf); if (strcmp(oldname, newname) == 0) goto cleanup; (void)unlink(oldname); isc_buffer_clear(&buf); dst_key_buildfilename(key, DST_TYPE_PUBLIC, dir, &buf); (void)unlink(oldname); } } else { dst_key_format(key, keystr, sizeof(keystr)); fatal("Key %s is already revoked", keystr); } cleanup: dst_key_free(&key); dst_lib_destroy(); isc_hash_destroy(); cleanup_entropy(&ectx); if (verbose > 10) isc_mem_stats(mctx, stdout); if (dir != NULL) isc_mem_free(mctx, dir); isc_mem_destroy(&mctx); return (0); } bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-dsfromkey.docbook0000644000470500017500000002400512664710322022243 0ustar lamontlamont]> May 02, 2012 dnssec-dsfromkey 8 BIND9 dnssec-dsfromkey DNSSEC DS RR generation tool 2008 2009 2010 2011 2012 2014 2015 Internet Systems Consortium, Inc. ("ISC") dnssec-dsfromkey keyfile dnssec-dsfromkey -s dnsname dnssec-dsfromkey DESCRIPTION dnssec-dsfromkey outputs the Delegation Signer (DS) resource record (RR), as defined in RFC 3658 and RFC 4509, for the given key(s). OPTIONS -1 Use SHA-1 as the digest algorithm (the default is to use both SHA-1 and SHA-256). -2 Use SHA-256 as the digest algorithm. -a algorithm Select the digest algorithm. The value of must be one of SHA-1 (SHA1), SHA-256 (SHA256), GOST or SHA-384 (SHA384). These values are case insensitive. -C Generate CDS records rather than DS records. This is mutually exclusive with generating lookaside records. -T TTL Specifies the TTL of the DS records. -K directory Look for key files (or, in keyset mode, keyset- files) in . -f file Zone file mode: in place of the keyfile name, the argument is the DNS domain name of a zone master file, which can be read from . If the zone name is the same as , then it may be omitted. If is set to "-", then the zone data is read from the standard input. This makes it possible to use the output of the dig command as input, as in: dig dnskey example.com | dnssec-dsfromkey -f - example.com -A Include ZSK's when generating DS records. Without this option, only keys which have the KSK flag set will be converted to DS records and printed. Useful only in zone file mode. -l domain Generate a DLV set instead of a DS set. The specified is appended to the name for each record in the set. The DNSSEC Lookaside Validation (DLV) RR is described in RFC 4431. This is mutually exclusive with generating CDS records. -s Keyset mode: in place of the keyfile name, the argument is the DNS domain name of a keyset file. -c class Specifies the DNS class (default is IN). Useful only in keyset or zone file mode. -v level Sets the debugging level. -h Prints usage information. -V Prints version information. EXAMPLE To build the SHA-256 DS RR from the Kexample.com.+003+26160 keyfile name, the following command would be issued: dnssec-dsfromkey -2 Kexample.com.+003+26160 The command would print something like: example.com. IN DS 26160 5 2 3A1EADA7A74B8D0BA86726B0C227AA85AB8BBD2B2004F41A868A54F0 C5EA0B94 FILES The keyfile can be designed by the key identification Knnnn.+aaa+iiiii or the full file name Knnnn.+aaa+iiiii.key as generated by dnssec-keygen8. The keyset file name is built from the , the string keyset- and the . CAVEAT A keyfile error can give a "file not found" even if the file exists. SEE ALSO dnssec-keygen8 , dnssec-signzone8 , BIND 9 Administrator Reference Manual, RFC 3658, RFC 4431. RFC 4509. AUTHOR Internet Systems Consortium bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-dsfromkey.html0000644000470500017500000002127112664710322021571 0ustar lamontlamont dnssec-dsfromkey

Name

dnssec-dsfromkey — DNSSEC DS RR generation tool

Synopsis

dnssec-dsfromkey [-v level] [-1] [-2] [-a alg] [-C] [-l domain] [-T TTL] {keyfile}

dnssec-dsfromkey {-s} [-1] [-2] [-a alg] [-K directory] [-l domain] [-s] [-c class] [-T TTL] [-f file] [-A] [-v level] {dnsname}

dnssec-dsfromkey [-h] [-V]

DESCRIPTION

dnssec-dsfromkey outputs the Delegation Signer (DS) resource record (RR), as defined in RFC 3658 and RFC 4509, for the given key(s).

OPTIONS

-1

Use SHA-1 as the digest algorithm (the default is to use both SHA-1 and SHA-256).

-2

Use SHA-256 as the digest algorithm.

-a algorithm

Select the digest algorithm. The value of algorithm must be one of SHA-1 (SHA1), SHA-256 (SHA256), GOST or SHA-384 (SHA384). These values are case insensitive.

-C

Generate CDS records rather than DS records. This is mutually exclusive with generating lookaside records.

-T TTL

Specifies the TTL of the DS records.

-K directory

Look for key files (or, in keyset mode, keyset- files) in directory.

-f file

Zone file mode: in place of the keyfile name, the argument is the DNS domain name of a zone master file, which can be read from file. If the zone name is the same as file, then it may be omitted.

If file is set to "-", then the zone data is read from the standard input. This makes it possible to use the output of the dig command as input, as in:

dig dnskey example.com | dnssec-dsfromkey -f - example.com

-A

Include ZSK's when generating DS records. Without this option, only keys which have the KSK flag set will be converted to DS records and printed. Useful only in zone file mode.

-l domain

Generate a DLV set instead of a DS set. The specified domain is appended to the name for each record in the set. The DNSSEC Lookaside Validation (DLV) RR is described in RFC 4431. This is mutually exclusive with generating CDS records.

-s

Keyset mode: in place of the keyfile name, the argument is the DNS domain name of a keyset file.

-c class

Specifies the DNS class (default is IN). Useful only in keyset or zone file mode.

-v level

Sets the debugging level.

-h

Prints usage information.

-V

Prints version information.

EXAMPLE

To build the SHA-256 DS RR from the Kexample.com.+003+26160 keyfile name, the following command would be issued:

dnssec-dsfromkey -2 Kexample.com.+003+26160

The command would print something like:

example.com. IN DS 26160 5 2 3A1EADA7A74B8D0BA86726B0C227AA85AB8BBD2B2004F41A868A54F0 C5EA0B94

FILES

The keyfile can be designed by the key identification Knnnn.+aaa+iiiii or the full file name Knnnn.+aaa+iiiii.key as generated by dnssec-keygen(8).

The keyset file name is built from the directory, the string keyset- and the dnsname.

CAVEAT

A keyfile error can give a "file not found" even if the file exists.

SEE ALSO

dnssec-keygen(8), dnssec-signzone(8), BIND 9 Administrator Reference Manual, RFC 3658, RFC 4431. RFC 4509.

AUTHOR

Internet Systems Consortium

bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-dsfromkey.80000644000470500017500000001160312664710322020772 0ustar lamontlamont.\" Copyright (C) 2008-2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") .\" .\" Permission to use, copy, modify, and/or distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $Id$ .\" .hy 0 .ad l .\" Title: dnssec\-dsfromkey .\" Author: .\" Generator: DocBook XSL Stylesheets v1.71.1 .\" Date: May 02, 2012 .\" Manual: BIND9 .\" Source: BIND9 .\" .TH "DNSSEC\-DSFROMKEY" "8" "May 02, 2012" "BIND9" "BIND9" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .SH "NAME" dnssec\-dsfromkey \- DNSSEC DS RR generation tool .SH "SYNOPSIS" .HP 17 \fBdnssec\-dsfromkey\fR [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-1\fR] [\fB\-2\fR] [\fB\-a\ \fR\fB\fIalg\fR\fR] [\fB\-C\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-T\ \fR\fB\fITTL\fR\fR] {keyfile} .HP 17 \fBdnssec\-dsfromkey\fR {\-s} [\fB\-1\fR] [\fB\-2\fR] [\fB\-a\ \fR\fB\fIalg\fR\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-s\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-T\ \fR\fB\fITTL\fR\fR] [\fB\-f\ \fR\fB\fIfile\fR\fR] [\fB\-A\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] {dnsname} .HP 17 \fBdnssec\-dsfromkey\fR [\fB\-h\fR] [\fB\-V\fR] .SH "DESCRIPTION" .PP \fBdnssec\-dsfromkey\fR outputs the Delegation Signer (DS) resource record (RR), as defined in RFC 3658 and RFC 4509, for the given key(s). .SH "OPTIONS" .PP \-1 .RS 4 Use SHA\-1 as the digest algorithm (the default is to use both SHA\-1 and SHA\-256). .RE .PP \-2 .RS 4 Use SHA\-256 as the digest algorithm. .RE .PP \-a \fIalgorithm\fR .RS 4 Select the digest algorithm. The value of \fBalgorithm\fR must be one of SHA\-1 (SHA1), SHA\-256 (SHA256), GOST or SHA\-384 (SHA384). These values are case insensitive. .RE .PP \-C .RS 4 Generate CDS records rather than DS records. This is mutually exclusive with generating lookaside records. .RE .PP \-T \fITTL\fR .RS 4 Specifies the TTL of the DS records. .RE .PP \-K \fIdirectory\fR .RS 4 Look for key files (or, in keyset mode, \fIkeyset\-\fR files) in \fBdirectory\fR. .RE .PP \-f \fIfile\fR .RS 4 Zone file mode: in place of the keyfile name, the argument is the DNS domain name of a zone master file, which can be read from \fBfile\fR. If the zone name is the same as \fBfile\fR, then it may be omitted. .sp If \fBfile\fR is set to "\-", then the zone data is read from the standard input. This makes it possible to use the output of the \fBdig\fR command as input, as in: .sp \fBdig dnskey example.com | dnssec\-dsfromkey \-f \- example.com\fR .RE .PP \-A .RS 4 Include ZSK's when generating DS records. Without this option, only keys which have the KSK flag set will be converted to DS records and printed. Useful only in zone file mode. .RE .PP \-l \fIdomain\fR .RS 4 Generate a DLV set instead of a DS set. The specified \fBdomain\fR is appended to the name for each record in the set. The DNSSEC Lookaside Validation (DLV) RR is described in RFC 4431. This is mutually exclusive with generating CDS records. .RE .PP \-s .RS 4 Keyset mode: in place of the keyfile name, the argument is the DNS domain name of a keyset file. .RE .PP \-c \fIclass\fR .RS 4 Specifies the DNS class (default is IN). Useful only in keyset or zone file mode. .RE .PP \-v \fIlevel\fR .RS 4 Sets the debugging level. .RE .PP \-h .RS 4 Prints usage information. .RE .PP \-V .RS 4 Prints version information. .RE .SH "EXAMPLE" .PP To build the SHA\-256 DS RR from the \fBKexample.com.+003+26160\fR keyfile name, the following command would be issued: .PP \fBdnssec\-dsfromkey \-2 Kexample.com.+003+26160\fR .PP The command would print something like: .PP \fBexample.com. IN DS 26160 5 2 3A1EADA7A74B8D0BA86726B0C227AA85AB8BBD2B2004F41A868A54F0 C5EA0B94\fR .SH "FILES" .PP The keyfile can be designed by the key identification \fIKnnnn.+aaa+iiiii\fR or the full file name \fIKnnnn.+aaa+iiiii.key\fR as generated by dnssec\-keygen(8). .PP The keyset file name is built from the \fBdirectory\fR, the string \fIkeyset\-\fR and the \fBdnsname\fR. .SH "CAVEAT" .PP A keyfile error can give a "file not found" even if the file exists. .SH "SEE ALSO" .PP \fBdnssec\-keygen\fR(8), \fBdnssec\-signzone\fR(8), BIND 9 Administrator Reference Manual, RFC 3658, RFC 4431. RFC 4509. .SH "AUTHOR" .PP Internet Systems Consortium .SH "COPYRIGHT" Copyright \(co 2008\-2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") .br bind9-9.10.3.dfsg.P4/bin/dnssec/dnssectool.h0000644000470500017500000000552112664710322017751 0ustar lamontlamont/* * Copyright (C) 2004, 2007-2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: dnssectool.h,v 1.33 2011/10/20 23:46:51 tbox Exp $ */ #ifndef DNSSECTOOL_H #define DNSSECTOOL_H 1 #include #include #include #include #define check_dns_dbiterator_current(result) \ check_result((result == DNS_R_NEWORIGIN) ? ISC_R_SUCCESS : result, \ "dns_dbiterator_current()") typedef void (fatalcallback_t)(void); ISC_PLATFORM_NORETURN_PRE void fatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2) ISC_PLATFORM_NORETURN_POST; void setfatalcallback(fatalcallback_t *callback); void check_result(isc_result_t result, const char *message); void vbprintf(int level, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3); void version(const char *program); void type_format(const dns_rdatatype_t type, char *cp, unsigned int size); #define TYPE_FORMATSIZE 20 void sig_format(dns_rdata_rrsig_t *sig, char *cp, unsigned int size); #define SIG_FORMATSIZE (DNS_NAME_FORMATSIZE + DNS_SECALG_FORMATSIZE + sizeof("65535")) void setup_logging(isc_mem_t *mctx, isc_log_t **logp); void cleanup_logging(isc_log_t **logp); void setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx); void cleanup_entropy(isc_entropy_t **ectx); dns_ttl_t strtottl(const char *str); isc_stdtime_t strtotime(const char *str, isc_int64_t now, isc_int64_t base, isc_boolean_t *setp); dns_rdataclass_t strtoclass(const char *str); isc_result_t try_dir(const char *dirname); void check_keyversion(dst_key_t *key, char *keystr); void set_keyversion(dst_key_t *key); isc_boolean_t key_collision(dst_key_t *key, dns_name_t *name, const char *dir, isc_mem_t *mctx, isc_boolean_t *exact); isc_boolean_t is_delegation(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin, dns_name_t *name, dns_dbnode_t *node, isc_uint32_t *ttlp); void verifyzone(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin, isc_mem_t *mctx, isc_boolean_t ignore_kskflag, isc_boolean_t keyset_kskonly); #endif /* DNSSEC_DNSSECTOOL_H */ bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-keygen.html0000644000470500017500000005240212664710322021050 0ustar lamontlamont dnssec-keygen

Name

dnssec-keygen — DNSSEC key generation tool

Synopsis

dnssec-keygen [-a algorithm] [-b keysize] [-n nametype] [-3] [-A date/offset] [-C] [-c class] [-D date/offset] [-E engine] [-f flag] [-G] [-g generator] [-h] [-I date/offset] [-i interval] [-K directory] [-L ttl] [-k] [-P date/offset] [-p protocol] [-q] [-R date/offset] [-r randomdev] [-S key] [-s strength] [-t type] [-v level] [-V] [-z] {name}

DESCRIPTION

dnssec-keygen generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034. It can also generate keys for use with TSIG (Transaction Signatures) as defined in RFC 2845, or TKEY (Transaction Key) as defined in RFC 2930.

The name of the key is specified on the command line. For DNSSEC keys, this must match the name of the zone for which the key is being generated.

OPTIONS

-a algorithm

Selects the cryptographic algorithm. For DNSSEC keys, the value of algorithm must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512, ECCGOST, ECDSAP256SHA256 or ECDSAP384SHA384. For TSIG/TKEY, the value must be DH (Diffie Hellman), HMAC-MD5, HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512. These values are case insensitive.

If no algorithm is specified, then RSASHA1 will be used by default, unless the -3 option is specified, in which case NSEC3RSASHA1 will be used instead. (If -3 is used and an algorithm is specified, that algorithm will be checked for compatibility with NSEC3.)

Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended. For TSIG, HMAC-MD5 is mandatory.

Note 2: DH, HMAC-MD5, and HMAC-SHA1 through HMAC-SHA512 automatically set the -T KEY option.

-b keysize

Specifies the number of bits in the key. The choice of key size depends on the algorithm used. RSA keys must be between 512 and 2048 bits. Diffie Hellman keys must be between 128 and 4096 bits. DSA keys must be between 512 and 1024 bits and an exact multiple of 64. HMAC keys must be between 1 and 512 bits. Elliptic curve algorithms don't need this parameter.

The key size does not need to be specified if using a default algorithm. The default key size is 1024 bits for zone signing keys (ZSK's) and 2048 bits for key signing keys (KSK's, generated with -f KSK). However, if an algorithm is explicitly specified with the -a, then there is no default key size, and the -b must be used.

-n nametype

Specifies the owner type of the key. The value of nametype must either be ZONE (for a DNSSEC zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with a host (KEY)), USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). These values are case insensitive. Defaults to ZONE for DNSKEY generation.

-3

Use an NSEC3-capable algorithm to generate a DNSSEC key. If this option is used and no algorithm is explicitly set on the command line, NSEC3RSASHA1 will be used by default. Note that RSASHA256, RSASHA512, ECCGOST, ECDSAP256SHA256 and ECDSAP384SHA384 algorithms are NSEC3-capable.

-C

Compatibility mode: generates an old-style key, without any metadata. By default, dnssec-keygen will include the key's creation date in the metadata stored with the private key, and other dates may be set there as well (publication date, activation date, etc). Keys that include this data may be incompatible with older versions of BIND; the -C option suppresses them.

-c class

Indicates that the DNS record containing the key should have the specified class. If not specified, class IN is used.

-E engine

Specifies the cryptographic hardware to use, when applicable.

When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (--enable-native-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "--with-pkcs11".

-f flag

Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flags are KSK (Key Signing Key) and REVOKE.

-G

Generate a key, but do not publish it or sign with it. This option is incompatible with -P and -A.

-g generator

If generating a Diffie Hellman key, use this generator. Allowed values are 2 and 5. If no generator is specified, a known prime from RFC 2539 will be used if possible; otherwise the default is 2.

-h

Prints a short summary of the options and arguments to dnssec-keygen.

-K directory

Sets the directory in which the key files are to be written.

-k

Deprecated in favor of -T KEY.

-L ttl

Sets the default TTL to use for this key when it is converted into a DNSKEY RR. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence. If this value is not set and there is no existing DNSKEY RRset, the TTL will default to the SOA TTL. Setting the default TTL to 0 or none is the same as leaving it unset.

-p protocol

Sets the protocol value for the generated key. The protocol is a number between 0 and 255. The default is 3 (DNSSEC). Other possible values for this argument are listed in RFC 2535 and its successors.

-q

Quiet mode: Suppresses unnecessary output, including progress indication. Without this option, when dnssec-keygen is run interactively to generate an RSA or DSA key pair, it will print a string of symbols to stderr indicating the progress of the key generation. A '.' indicates that a random number has been found which passed an initial sieve test; '+' means a number has passed a single round of the Miller-Rabin primality test; a space means that the number has passed all the tests and is a satisfactory key.

-r randomdev

Specifies the source of randomness. If the operating system does not provide a /dev/random or equivalent device, the default source of randomness is keyboard input. randomdev specifies the name of a character device or file containing random data to be used instead of the default. The special value keyboard indicates that keyboard input should be used.

-S key

Create a new key which is an explicit successor to an existing key. The name, algorithm, size, and type of the key will be set to match the existing key. The activation date of the new key will be set to the inactivation date of the existing one. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days.

-s strength

Specifies the strength value of the key. The strength is a number between 0 and 15, and currently has no defined purpose in DNSSEC.

-T rrtype

Specifies the resource record type to use for the key. rrtype must be either DNSKEY or KEY. The default is DNSKEY when using a DNSSEC algorithm, but it can be overridden to KEY for use with SIG(0).

Using any TSIG algorithm (HMAC-* or DH) forces this option to KEY.

-t type

Indicates the use of the key. type must be one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default is AUTHCONF. AUTH refers to the ability to authenticate data, and CONF the ability to encrypt data.

-v level

Sets the debugging level.

-V

Prints version information.

TIMING OPTIONS

Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24-hour days, ignoring leap years), months (defined as 30 24-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To explicitly prevent a date from being set, use 'none' or 'never'.

-P date/offset

Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it. If not set, and if the -G option has not been used, the default is "now".

-A date/offset

Sets the date on which the key is to be activated. After that date, the key will be included in the zone and used to sign it. If not set, and if the -G option has not been used, the default is "now". If set, if and -P is not set, then the publication date will be set to the activation date minus the prepublication interval.

-R date/offset

Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it.

-I date/offset

Sets the date on which the key is to be retired. After that date, the key will still be included in the zone, but it will not be used to sign it.

-D date/offset

Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.)

-i interval

Sets the prepublication interval for a key. If set, then the publication and activation dates must be separated by at least this much time. If the activation date is specified but the publication date isn't, then the publication date will default to this much time before the activation date; conversely, if the publication date is specified but activation date isn't, then activation will be set to this much time after publication.

If the key is being created as an explicit successor to another key, then the default prepublication interval is 30 days; otherwise it is zero.

As with date offsets, if the argument is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the interval is measured in years, months, weeks, days, hours, or minutes, respectively. Without a suffix, the interval is measured in seconds.

GENERATED KEYS

When dnssec-keygen completes successfully, it prints a string of the form Knnnn.+aaa+iiiii to the standard output. This is an identification string for the key it has generated.

  • nnnn is the key name.

  • aaa is the numeric representation of the algorithm.

  • iiiii is the key identifier (or footprint).

dnssec-keygen creates two files, with names based on the printed string. Knnnn.+aaa+iiiii.key contains the public key, and Knnnn.+aaa+iiiii.private contains the private key.

The .key file contains a DNS KEY record that can be inserted into a zone file (directly or with a $INCLUDE statement).

The .private file contains algorithm-specific fields. For obvious security reasons, this file does not have general read permission.

Both .key and .private files are generated for symmetric encryption algorithms such as HMAC-MD5, even though the public and private key are equivalent.

EXAMPLE

To generate a 768-bit DSA key for the domain example.com, the following command would be issued:

dnssec-keygen -a DSA -b 768 -n ZONE example.com

The command would print a string of the form:

Kexample.com.+003+26160

In this example, dnssec-keygen creates the files Kexample.com.+003+26160.key and Kexample.com.+003+26160.private.

SEE ALSO

dnssec-signzone(8), BIND 9 Administrator Reference Manual, RFC 2539, RFC 2845, RFC 4034.

AUTHOR

Internet Systems Consortium

bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-importkey.html0000644000470500017500000001724012664710322021612 0ustar lamontlamont dnssec-importkey

Name

dnssec-importkey — Import DNSKEY records from external systems so they can be managed.

Synopsis

dnssec-importkey [-K directory] [-L ttl] [-P date/offset] [-D date/offset] [-h] [-v level] [-V] {keyfile}

dnssec-importkey {-f filename} [-K directory] [-L ttl] [-P date/offset] [-D date/offset] [-h] [-v level] [-V] [dnsname]

DESCRIPTION

dnssec-importkey reads a public DNSKEY record and generates a pair of .key/.private files. The DNSKEY record may be read from an existing .key file, in which case a corresponding .private file will be generated, or it may be read from any other file or from the standard input, in which case both .key and .private files will be generated.

The newly-created .private file does not contain private key data, and cannot be used for signing. However, having a .private file makes it possible to set publication (-P) and deletion (-D) times for the key, which means the public key can be added to and removed from the DNSKEY RRset on schedule even if the true private key is stored offline.

OPTIONS

-f filename

Zone file mode: instead of a public keyfile name, the argument is the DNS domain name of a zone master file, which can be read from file. If the domain name is the same as file, then it may be omitted.

If file is set to "-", then the zone data is read from the standard input.

-K directory

Sets the directory in which the key files are to reside.

-L ttl

Sets the default TTL to use for this key when it is converted into a DNSKEY RR. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence. Setting the default TTL to 0 or none removes it.

-h

Emit usage message and exit.

-v level

Sets the debugging level.

-V

Prints version information.

TIMING OPTIONS

Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24-hour days, ignoring leap years), months (defined as 30 24-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To explicitly prevent a date from being set, use 'none' or 'never'.

-P date/offset

Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it.

-D date/offset

Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.)

FILES

A keyfile can be designed by the key identification Knnnn.+aaa+iiiii or the full file name Knnnn.+aaa+iiiii.key as generated by dnssec-keygen(8).

SEE ALSO

dnssec-keygen(8), dnssec-signzone(8), BIND 9 Administrator Reference Manual, RFC 5011.

AUTHOR

Internet Systems Consortium

bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-revoke.html0000644000470500017500000001066212664710322021063 0ustar lamontlamont dnssec-revoke

Name

dnssec-revoke — Set the REVOKED bit on a DNSSEC key

Synopsis

dnssec-revoke [-hr] [-v level] [-V] [-K directory] [-E engine] [-f] [-R] {keyfile}

DESCRIPTION

dnssec-revoke reads a DNSSEC key file, sets the REVOKED bit on the key as defined in RFC 5011, and creates a new pair of key files containing the now-revoked key.

OPTIONS

-h

Emit usage message and exit.

-K directory

Sets the directory in which the key files are to reside.

-r

After writing the new keyset files remove the original keyset files.

-v level

Sets the debugging level.

-V

Prints version information.

-E engine

Specifies the cryptographic hardware to use, when applicable.

When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (--enable-native-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "--with-pkcs11".

-f

Force overwrite: Causes dnssec-revoke to write the new key pair even if a file already exists matching the algorithm and key ID of the revoked key.

-R

Print the key tag of the key with the REVOKE bit set but do not revoke the key.

SEE ALSO

dnssec-keygen(8), BIND 9 Administrator Reference Manual, RFC 5011.

AUTHOR

Internet Systems Consortium

bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-settime.html0000644000470500017500000002762412664710322021250 0ustar lamontlamont dnssec-settime

Name

dnssec-settime — Set the key timing metadata for a DNSSEC key

Synopsis

dnssec-settime [-f] [-K directory] [-L ttl] [-P date/offset] [-A date/offset] [-R date/offset] [-I date/offset] [-D date/offset] [-h] [-V] [-v level] [-E engine] {keyfile}

DESCRIPTION

dnssec-settime reads a DNSSEC private key file and sets the key timing metadata as specified by the -P, -A, -R, -I, and -D options. The metadata can then be used by dnssec-signzone or other signing software to determine when a key is to be published, whether it should be used for signing a zone, etc.

If none of these options is set on the command line, then dnssec-settime simply prints the key timing metadata already stored in the key.

When key metadata fields are changed, both files of a key pair (Knnnn.+aaa+iiiii.key and Knnnn.+aaa+iiiii.private) are regenerated. Metadata fields are stored in the private file. A human-readable description of the metadata is also placed in comments in the key file. The private file's permissions are always set to be inaccessible to anyone other than the owner (mode 0600).

OPTIONS

-f

Force an update of an old-format key with no metadata fields. Without this option, dnssec-settime will fail when attempting to update a legacy key. With this option, the key will be recreated in the new format, but with the original key data retained. The key's creation date will be set to the present time. If no other values are specified, then the key's publication and activation dates will also be set to the present time.

-K directory

Sets the directory in which the key files are to reside.

-L ttl

Sets the default TTL to use for this key when it is converted into a DNSKEY RR. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence. If this value is not set and there is no existing DNSKEY RRset, the TTL will default to the SOA TTL. Setting the default TTL to 0 or none removes it from the key.

-h

Emit usage message and exit.

-V

Prints version information.

-v level

Sets the debugging level.

-E engine

Specifies the cryptographic hardware to use, when applicable.

When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (--enable-native-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "--with-pkcs11".

TIMING OPTIONS

Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24-hour days, ignoring leap years), months (defined as 30 24-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To unset a date, use 'none' or 'never'.

-P date/offset

Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it.

-A date/offset

Sets the date on which the key is to be activated. After that date, the key will be included in the zone and used to sign it.

-R date/offset

Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it.

-I date/offset

Sets the date on which the key is to be retired. After that date, the key will still be included in the zone, but it will not be used to sign it.

-D date/offset

Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.)

-S predecessor key

Select a key for which the key being modified will be an explicit successor. The name, algorithm, size, and type of the predecessor key must exactly match those of the key being modified. The activation date of the successor key will be set to the inactivation date of the predecessor. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days.

-i interval

Sets the prepublication interval for a key. If set, then the publication and activation dates must be separated by at least this much time. If the activation date is specified but the publication date isn't, then the publication date will default to this much time before the activation date; conversely, if the publication date is specified but activation date isn't, then activation will be set to this much time after publication.

If the key is being set to be an explicit successor to another key, then the default prepublication interval is 30 days; otherwise it is zero.

As with date offsets, if the argument is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the interval is measured in years, months, weeks, days, hours, or minutes, respectively. Without a suffix, the interval is measured in seconds.

PRINTING OPTIONS

dnssec-settime can also be used to print the timing metadata associated with a key.

-u

Print times in UNIX epoch format.

-p C/P/A/R/I/D/all

Print a specific metadata value or set of metadata values. The -p option may be followed by one or more of the following letters to indicate which value or values to print: C for the creation date, P for the publication date, A for the activation date, R for the revocation date, I for the inactivation date, or D for the deletion date. To print all of the metadata, use -p all.

SEE ALSO

dnssec-keygen(8), dnssec-signzone(8), BIND 9 Administrator Reference Manual, RFC 5011.

AUTHOR

Internet Systems Consortium

bind9-9.10.3.dfsg.P4/bin/dnssec/dnssec-keyfromlabel.html0000644000470500017500000004342612664710322022250 0ustar lamontlamont dnssec-keyfromlabel

Name

dnssec-keyfromlabel — DNSSEC key generation tool

Synopsis

dnssec-keyfromlabel {-l label} [-3] [-a algorithm] [-A date/offset] [-c class] [-D date/offset] [-E engine] [-f flag] [-G] [-I date/offset] [-i interval] [-k] [-K directory] [-L ttl] [-n nametype] [-P date/offset] [-p protocol] [-R date/offset] [-S key] [-t type] [-v level] [-V] [-y] {name}

DESCRIPTION

dnssec-keyfromlabel generates a key pair of files that referencing a key object stored in a cryptographic hardware service module (HSM). The private key file can be used for DNSSEC signing of zone data as if it were a conventional signing key created by dnssec-keygen, but the key material is stored within the HSM, and the actual signing takes place there.

The name of the key is specified on the command line. This must match the name of the zone for which the key is being generated.

OPTIONS

-a algorithm

Selects the cryptographic algorithm. The value of algorithm must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512, ECCGOST, ECDSAP256SHA256 or ECDSAP384SHA384. These values are case insensitive.

If no algorithm is specified, then RSASHA1 will be used by default, unless the -3 option is specified, in which case NSEC3RSASHA1 will be used instead. (If -3 is used and an algorithm is specified, that algorithm will be checked for compatibility with NSEC3.)

Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended.

Note 2: DH automatically sets the -k flag.

-3

Use an NSEC3-capable algorithm to generate a DNSSEC key. If this option is used and no algorithm is explicitly set on the command line, NSEC3RSASHA1 will be used by default.

-E engine

Specifies the cryptographic hardware to use.

When BIND is built with OpenSSL PKCS#11 support, this defaults to the string "pkcs11", which identifies an OpenSSL engine that can drive a cryptographic accelerator or hardware service module. When BIND is built with native PKCS#11 cryptography (--enable-native-pkcs11), it defaults to the path of the PKCS#11 provider library specified via "--with-pkcs11".

-l label

Specifies the label for a key pair in the crypto hardware.

When BIND 9 is built with OpenSSL-based PKCS#11 support, the label is an arbitrary string that identifies a particular key. It may be preceded by an optional OpenSSL engine name, followed by a colon, as in "pkcs11:keylabel".

When BIND 9 is built with native PKCS#11 support, the label is a PKCS#11 URI string in the format "pkcs11:keyword=value[;keyword=value;...]" Keywords include "token", which identifies the HSM; "object", which identifies the key; and "pin-source", which identifies a file from which the HSM's PIN code can be obtained. The label will be stored in the on-disk "private" file.

If the label contains a pin-source field, tools using the generated key files will be able to use the HSM for signing and other operations without any need for an operator to manually enter a PIN. Note: Making the HSM's PIN accessible in this manner may reduce the security advantage of using an HSM; be sure this is what you want to do before making use of this feature.

-n nametype

Specifies the owner type of the key. The value of nametype must either be ZONE (for a DNSSEC zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with a host (KEY)), USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). These values are case insensitive.

-C

Compatibility mode: generates an old-style key, without any metadata. By default, dnssec-keyfromlabel will include the key's creation date in the metadata stored with the private key, and other dates may be set there as well (publication date, activation date, etc). Keys that include this data may be incompatible with older versions of BIND; the -C option suppresses them.

-c class

Indicates that the DNS record containing the key should have the specified class. If not specified, class IN is used.

-f flag

Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flags are KSK (Key Signing Key) and REVOKE.

-G

Generate a key, but do not publish it or sign with it. This option is incompatible with -P and -A.

-h

Prints a short summary of the options and arguments to dnssec-keyfromlabel.

-K directory

Sets the directory in which the key files are to be written.

-k

Generate KEY records rather than DNSKEY records.

-L ttl

Sets the default TTL to use for this key when it is converted into a DNSKEY RR. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence. Setting the default TTL to 0 or none removes it.

-p protocol

Sets the protocol value for the key. The protocol is a number between 0 and 255. The default is 3 (DNSSEC). Other possible values for this argument are listed in RFC 2535 and its successors.

-S key

Generate a key as an explicit successor to an existing key. The name, algorithm, size, and type of the key will be set to match the predecessor. The activation date of the new key will be set to the inactivation date of the existing one. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days.

-t type

Indicates the use of the key. type must be one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default is AUTHCONF. AUTH refers to the ability to authenticate data, and CONF the ability to encrypt data.

-v level

Sets the debugging level.

-V

Prints version information.

-y

Allows DNSSEC key files to be generated even if the key ID would collide with that of an existing key, in the event of either key being revoked. (This is only safe to use if you are sure you won't be using RFC 5011 trust anchor maintenance with either of the keys involved.)

TIMING OPTIONS

Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24-hour days, ignoring leap years), months (defined as 30 24-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To explicitly prevent a date from being set, use 'none' or 'never'.

-P date/offset

Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it. If not set, and if the -G option has not been used, the default is "now".

-A date/offset

Sets the date on which the key is to be activated. After that date, the key will be included in the zone and used to sign it. If not set, and if the -G option has not been used, the default is "now".

-R date/offset

Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it.

-I date/offset

Sets the date on which the key is to be retired. After that date, the key will still be included in the zone, but it will not be used to sign it.

-D date/offset

Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.)

-i interval

Sets the prepublication interval for a key. If set, then the publication and activation dates must be separated by at least this much time. If the activation date is specified but the publication date isn't, then the publication date will default to this much time before the activation date; conversely, if the publication date is specified but activation date isn't, then activation will be set to this much time after publication.

If the key is being created as an explicit successor to another key, then the default prepublication interval is 30 days; otherwise it is zero.

As with date offsets, if the argument is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the interval is measured in years, months, weeks, days, hours, or minutes, respectively. Without a suffix, the interval is measured in seconds.

GENERATED KEY FILES

When dnssec-keyfromlabel completes successfully, it prints a string of the form Knnnn.+aaa+iiiii to the standard output. This is an identification string for the key files it has generated.

  • nnnn is the key name.

  • aaa is the numeric representation of the algorithm.

  • iiiii is the key identifier (or footprint).

dnssec-keyfromlabel creates two files, with names based on the printed string. Knnnn.+aaa+iiiii.key contains the public key, and Knnnn.+aaa+iiiii.private contains the private key.

The .key file contains a DNS KEY record that can be inserted into a zone file (directly or with a $INCLUDE statement).

The .private file contains algorithm-specific fields. For obvious security reasons, this file does not have general read permission.

SEE ALSO

dnssec-keygen(8), dnssec-signzone(8), BIND 9 Administrator Reference Manual, RFC 4034, The PKCS#11 URI Scheme (draft-pechanec-pkcs11uri-13).

AUTHOR

Internet Systems Consortium

bind9-9.10.3.dfsg.P4/bin/tests/0002755000470500017500000000000012672612753015315 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/tests/virtual-time/0002755000470500017500000000000012672612753017737 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/tests/virtual-time/runall.sh0000644000470500017500000000221712664710322021560 0ustar lamontlamont#!/bin/sh # # Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: runall.sh,v 1.2 2010/06/17 05:38:05 marka Exp $ # # Run all the virtual time tests. # SYSTEMTESTTOP=. . $SYSTEMTESTTOP/conf.sh $PERL testsock.pl || { echo "I:Network interface aliases not set up. Skipping tests." >&2; echo "R:UNTESTED" >&2; echo "E:virtual-time:`date`" >&2; exit 0; } status=0 for d in $SUBDIRS do sh run.sh $d || status=1 done exit $status bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/cleanall.sh0000644000470500017500000000231612664710322022036 0ustar lamontlamont#!/bin/sh # # Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: cleanall.sh,v 1.2 2010/06/17 05:38:05 marka Exp $ # # Clean up after system tests. # SYSTEMTESTTOP=. . $SYSTEMTESTTOP/conf.sh find . -type f \( \ -name 'K*' -o -name '*~' -o -name '*.core' -o -name '*.log' \ -o -name '*.pid' -o -name '*.keyset' -o -name named.run \ -o -name lwresd.run -o -name ans.run \) -print | xargs rm -f status=0 for d in $SUBDIRS do test ! -f $d/clean.sh || ( cd $d && sh clean.sh ) done bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/autosign-ksk/0002755000470500017500000000000012672612753022356 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/tests/virtual-time/autosign-ksk/setup.sh0000644000470500017500000000210512664710322024036 0ustar lamontlamont#!/bin/sh -e # # Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: setup.sh,v 1.2 2010/06/21 02:31:45 marka Exp $ SYSTEMTESTTOP=.. . $SYSTEMTESTTOP/conf.sh . ./clean.sh ../../../tools/genrandom 800 random.data dd if=random.data of=random.data1 bs=1k count=400 2> /dev/null dd if=random.data of=random.data2 bs=1k skip=400 2> /dev/null cd ns1 && sh sign.sh bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/autosign-ksk/tests.sh0000644000470500017500000000741412664710322024050 0ustar lamontlamont#!/bin/sh # # Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: tests.sh,v 1.2 2010/06/21 02:31:45 marka Exp $ SYSTEMTESTTOP=.. . $SYSTEMTESTTOP/conf.sh status=0 n=0 DIGOPTS="+noadd +nosea +nostat +nocmd +noauth +dnssec -p 5300" ksk=ns1/`cat ns1/keyname`.key kskpat=`awk '/DNSKEY/ { print $8 }' $ksk` kskid=`sed 's/^Kexample\.+005+0*//' < ns1/keyname` rkskid=`expr \( $kskid + 128 \) \% 65536` echo "I:checking for KSK not yet published ($n)" ret=0 $DIG $DIGOPTS -t dnskey example. @10.53.0.1 > dig.out.ns1.test$n || ret=1 # Note - this is looking for failure, hence the && tr -d ' ' < dig.out.ns1.test$n | grep $kskpat > /dev/null && ret=1 n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` # 5s real, 55s virtual, P +20 sleep 4 echo "I:checking for KSK published but not yet active ($n)" ret=0 $DIG $DIGOPTS -t dnskey example. @10.53.0.1 > dig.out.ns1.test$n || ret=1 tr -d ' ' < dig.out.ns1.test$n | grep $kskpat > /dev/null || ret=1 # Note - this is looking for failure, hence the && grep 'RRSIG.*'" $kskid "'example\. ' dig.out.ns1.test$n > /dev/null && ret=1 n=`expr $n + 1` if [ $ret != 0 ] ; then echo "I:failed"; fi status=`expr $status + $ret` # 10s real, 2h15mn virtual, A +1h sleep 5 echo "I:checking for KSK active ($n)" ret=0 $DIG $DIGOPTS -t dnskey example. @10.53.0.1 > dig.out.ns1.test$n || ret=1 tr -d ' ' < dig.out.ns1.test$n | grep $kskpat > /dev/null || ret=1 grep 'RRSIG.*'" $kskid "'example\. ' dig.out.ns1.test$n > /dev/null || ret=1 n=`expr $n + 1` if [ $ret != 0 ] ; then echo "I:failed"; fi status=`expr $status + $ret` # 11s real, 6h7,m virtual, R +6h sleep 1 echo "I:checking for KSK revoked ($n)" ret=0 $DIG $DIGOPTS -t dnskey example. @10.53.0.1 > dig.out.ns1.test$n || ret=1 tr -d ' ' < dig.out.ns1.test$n | grep $kskpat > /dev/null || ret=1 awk 'BEGIN { $noksk=1 } \ /DNSKEY/ { $5==385 && $noksk=0 } \ END { exit $noksk }' < dig.out.ns1.test$n > /dev/null || ret=1 # Note - this is looking for failure, hence the && grep 'RRSIG.*'" $kskid "'example\. ' dig.out.ns1.test$n > /dev/null && ret=1 grep 'RRSIG.*'" $rkskid "'example\. ' dig.out.ns1.test$n > /dev/null || ret=1 n=`expr $n + 1` if [ $ret != 0 ] ; then echo "I:failed"; fi status=`expr $status + $ret` # 13s real, 45h virtual, I +1d sleep 2 echo "I:checking for KSK retired but not yet deleted ($n)" ret=0 $DIG $DIGOPTS -t dnskey example. @10.53.0.1 > dig.out.ns1.test$n || ret=1 tr -d ' ' < dig.out.ns1.test$n | grep $kskpat > /dev/null || ret=1 n=`expr $n + 1` if [ $ret != 0 ] ; then echo "I:failed"; fi status=`expr $status + $ret` # 17s real, 103d virtual, D +1mo sleep 4 echo "I:checking for KSK deleted ($n)" ret=0 $DIG $DIGOPTS -t dnskey example. @10.53.0.1 > dig.out.ns1.test$n || ret=1 # Note - this is looking for failure, hence the && tr -d ' ' < dig.out.ns1.test$n | grep $kskpat > /dev/null && ret=1 # Note - this is looking for failure, hence the && grep 'RRSIG.*'" $rkskid "'example\. ' dig.out.ns1.test$n > /dev/null && ret=1 n=`expr $n + 1` if [ $ret != 0 ] ; then echo "I:failed"; fi status=`expr $status + $ret` echo "I:exit status: $status" exit $status bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/autosign-ksk/clean.sh0000644000470500017500000000201712664710322023762 0ustar lamontlamont# Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: clean.sh,v 1.2 2010/06/21 02:31:45 marka Exp $ # # Clean up after virtual time tests. # rm -f */K* */dsset-* */*.signed */*.jnl */tmp* rm -f dig.out.* rm -f random.data* rm -f */named.memstats rm -f */*vtwrapper.* rm -f ns1/example.db rm -f ns1/keyname bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/autosign-ksk/ns1/0002755000470500017500000000000012672612753023057 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/tests/virtual-time/autosign-ksk/ns1/root.db0000644000470500017500000000221612664710322024340 0ustar lamontlamont; Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above ; copyright notice and this permission notice appear in all copies. ; ; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. ; $Id: root.db,v 1.3 2010/06/21 23:46:48 tbox Exp $ $TTL 300 . IN SOA gson.nominum.com. a.root.servers.nil. ( 2000082401 ; serial 1800 ; refresh (30 minutes) 1800 ; retry (30 minutes) 1814400 ; expire (3 weeks) 3600 ; minimum (1 hour) ) . NS a.root-servers.nil. a.root-servers.nil. A 10.53.0.1 example NS ns.example ns.example A 10.53.0.1 bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/autosign-ksk/ns1/example.db.in0000644000470500017500000000211412664710322025412 0ustar lamontlamont; Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above ; copyright notice and this permission notice appear in all copies. ; ; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. ; $Id: example.db.in,v 1.3 2010/06/21 23:46:48 tbox Exp $ $TTL 60 ; 1 mn (to avoid to delay activation with ttl > prepublish) @ IN SOA ns root ( 2000042100 ; serial 600 ; refresh 600 ; retry 12000 ; expire 600 ; minimum ) NS ns ns A 10.53.0.1 txt TXT "recursed" bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/autosign-ksk/ns1/sign.sh0000644000470500017500000000257412664710322024351 0ustar lamontlamont#!/bin/sh -e # # Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: sign.sh,v 1.2 2010/06/21 02:31:45 marka Exp $ SYSTEMTESTTOP=../.. . $SYSTEMTESTTOP/conf.sh RANDFILE=../random.data1 RANDFILE2=../random.data2 zone=example. infile=example.db.in zonefile=example.db zskname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 768 -n zone $zone` kskname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -f KSK -n zone $zone` cat $infile $zskname.key $kskname.key > $zonefile $SIGNER -P -e +1000d -r $RANDFILE -o $zone $zonefile > /dev/null # ksk keyname=`$KEYGEN -q -r $RANDFILE2 -a RSASHA1 -b 1024 -n zone \ -f KSK -P +20 -A +1h -R +6h -I +1d -D +1mo $zone` echo $keyname > keyname bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/autosign-ksk/ns1/named.conf0000644000470500017500000000271612664710322025006 0ustar lamontlamont/* * Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: named.conf,v 1.2 2010/06/21 02:31:45 marka Exp $ */ controls { /* empty */ }; options { query-source address 10.53.0.1; notify-source 10.53.0.1; transfer-source 10.53.0.1; port 5300; pid-file "named.pid"; listen-on { 10.53.0.1; }; listen-on-v6 { none; }; recursion no; notify no; dnssec-enable yes; dnssec-validation yes; sig-validity-interval 20; }; key rndc_key { secret "1234abcd8765"; algorithm hmac-md5; }; controls { inet 10.53.0.1 port 9953 allow { any; } keys { rndc_key; }; }; zone "." { type master; file "root.db"; }; zone "example." { type master; file "example.db.signed"; allow-query { any; }; allow-update { any; }; auto-dnssec maintain; }; bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/autosign-ksk/ns1/wrap.sh0000644000470500017500000000162412664710322024355 0ustar lamontlamont# Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: wrap.sh,v 1.3 2010/06/21 23:46:48 tbox Exp $ # # Wrapper for named # LD_PRELOAD=../../libvtwrapper.so export LD_PRELOAD exec $* bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/setup.sh0000644000470500017500000000223012664710322021416 0ustar lamontlamont#!/bin/sh # # Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: setup.sh,v 1.2 2010/06/17 05:38:05 marka Exp $ # # Run a system test. # SYSTEMTESTTOP=. . $SYSTEMTESTTOP/conf.sh test $# -gt 0 || { echo "usage: $0 test-directory" >&2; exit 1; } test=$1 shift test -d $test || { echo "$0: $test: no such test" >&2; exit 1; } # Set up any dynamically generated test data if test -f $test/setup.sh then ( cd $test && sh setup.sh "$@" ) fi bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/vtwrapper.c0000644000470500017500000001546312664710322022134 0ustar lamontlamont/* * Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: vtwrapper.c,v 1.4 2010/08/12 09:31:50 fdupont Exp $ */ #define _GNU_SOURCE #include #include #include #include #include #include #include #ifdef SYS_select #include #endif #ifdef SYS_poll #include #endif #ifdef SYS_kevent #include #endif #ifdef SYS_epoll_wait #include #endif #ifdef SYS_gettimeofday #define VIRTUAL_TIME #ifdef VIRTUAL_TIME static struct timeval epoch = { 0, 0 }; static int _init_called = 0; void _init(void) { (void)syscall(SYS_gettimeofday, &epoch, NULL); _init_called = 1; } static void absolute_inflate(struct timeval *vt, struct timeval *rt) { double d; rt->tv_sec = vt->tv_sec; rt->tv_usec = vt->tv_usec; if ((epoch.tv_sec > vt->tv_sec) || ((epoch.tv_sec == vt->tv_sec) && (epoch.tv_usec > vt->tv_usec))) return; rt->tv_sec -= epoch.tv_sec; rt->tv_usec -= epoch.tv_usec; while (rt->tv_usec < 0) { rt->tv_sec -= 1; rt->tv_usec += 1000000; } if (rt->tv_sec == 0) goto done; d = (double) (rt->tv_sec - 1); d += (double) rt->tv_usec / 1000000.; d = exp(d); rt->tv_sec = (time_t) d; d -= (double) rt->tv_sec; rt->tv_usec = (suseconds_t) (d * 1000000.); done: rt->tv_sec += epoch.tv_sec; rt->tv_usec += epoch.tv_usec; while (rt->tv_usec >= 1000000) { rt->tv_sec += 1; rt->tv_usec -= 1000000; } return; } static void absolute_deflate(struct timeval *rt, struct timeval *vt) { double d; vt->tv_sec = rt->tv_sec; vt->tv_usec = rt->tv_usec; if ((epoch.tv_sec > rt->tv_sec) || ((epoch.tv_sec == rt->tv_sec) && (epoch.tv_usec > rt->tv_usec))) return; vt->tv_sec -= epoch.tv_sec; vt->tv_usec -= epoch.tv_usec; while (vt->tv_usec < 0) { vt->tv_sec -= 1; vt->tv_usec += 1000000; } if (vt->tv_sec == 0) goto done; d = (double) vt->tv_sec; d += (double) vt->tv_usec / 1000000.; d = log(d); vt->tv_sec = (time_t) d; d -= (double) vt->tv_sec; vt->tv_sec += 1; vt->tv_usec = (suseconds_t) (d * 1000000.); done: vt->tv_sec += epoch.tv_sec; vt->tv_usec += epoch.tv_usec; while (vt->tv_usec >= 1000000) { vt->tv_sec += 1; vt->tv_usec -= 1000000; } return; } static void interval_inflate(struct timeval *vt, struct timeval *rt) { struct timeval now, tv; (void) gettimeofday(&now, NULL); absolute_deflate(&now, &tv); tv.tv_sec += vt->tv_sec; tv.tv_usec += vt->tv_usec; while (tv.tv_usec >= 1000000) { tv.tv_sec += 1; tv.tv_usec -= 1000000; } absolute_inflate(&tv, rt); rt->tv_sec -= now.tv_sec; rt->tv_usec -= now.tv_usec; if (rt->tv_usec < 0) { rt->tv_sec -= 1; rt->tv_usec += 1000000; } return; } static void interval_deflate(struct timeval *rt, struct timeval *vt) { struct timeval now, tv; vt->tv_sec = rt->tv_sec; vt->tv_usec = rt->tv_usec; if ((vt->tv_sec == 0) && (vt->tv_usec <= 10000)) return; (void) gettimeofday(&now, NULL); tv.tv_sec = now.tv_sec + rt->tv_sec; tv.tv_usec = now.tv_usec + rt->tv_usec; while (tv.tv_usec >= 1000000) { tv.tv_sec += 1; tv.tv_usec -= 1000000; } absolute_deflate(&now, &now); absolute_deflate(&tv, vt); vt->tv_sec -= now.tv_sec; vt->tv_usec -= now.tv_usec; while (vt->tv_usec < 0) { vt->tv_sec -= 1; vt->tv_usec += 1000000; } if ((vt->tv_sec == 0) && (vt->tv_usec < 10000)) vt->tv_usec = 10000; return; } #endif int gettimeofday(struct timeval *tv, struct timezone *tz) { #ifdef VIRTUAL_TIME struct timeval now; int ret; if (!_init_called) _init(); if (epoch.tv_sec == 0) return syscall(SYS_gettimeofday, tv, tz); ret = syscall(SYS_gettimeofday, &now, tz); if (ret == 0) absolute_inflate(&now, tv); return ret; #else return syscall(SYS_gettimeofday, tv, tz); #endif } #ifdef SYS_select int select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds, struct timeval *timeout) { #ifdef VIRTUAL_TIME struct timeval tv; if (!_init_called) _init(); if (epoch.tv_sec == 0 || timeout == NULL || (timeout->tv_sec == 0 && timeout->tv_usec == 0)) return syscall(SYS_select, nfds, rfds, wfds, xfds, timeout); interval_deflate(timeout, &tv); return syscall(SYS_select, nfds, rfds, wfds, xfds, &tv); #else return syscall(SYS_select, nfds, rfds, wfds, xfds, timeout); #endif } #endif #ifdef SYS_poll int poll(struct pollfd fds[], nfds_t nfds, int timeout) { #ifdef VIRTUAL_TIME struct timeval in, out; if (!_init_called) _init(); if (timeout <= 0 || epoch.tv_sec == 0) return syscall(SYS_poll, fds, nfds, timeout); in.tv_sec = timeout / 1000; in.tv_usec = (timeout % 1000) * 1000; interval_deflate(&in, &out); timeout = out.tv_sec * 1000 + out.tv_usec / 1000; return syscall(SYS_poll, fds, nfds, timeout); #else return syscall(SYS_poll, fds, nfds, timeout); #endif } #endif #ifdef SYS_kevent int kevent(int kq, struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout) { #ifdef VIRTUAL_TIME struct timeval in, out; struct timespec ts; if (!_init_called) _init(); if (epoch.tv_sec == 0 || timeout == NULL || (timeout->tv_sec == 0 && timeout->tv_nsec == 0)) return syscall(SYS_kevent, kq, changelist, nchanges, eventlist, nevents, timeout); in.tv_sec = timeout->tv_sec; in.tv_usec = timeout->tv_nsec / 1000; interval_deflate(&in, &out); ts.tv_sec = out.tv_sec; ts.tv_nsec = out.tv_usec * 1000; return syscall(SYS_kevent, kq, changelist, nchanges, eventlist, nevents, &ts); #else return syscall(SYS_kevent, kq, changelist, nchanges, eventlist, nevents, timeout); #endif } #endif #ifdef SYS_epoll_wait int epoll_wait(int fd, struct epoll_event *events, int maxevents, int timeout) { #ifdef VIRTUAL_TIME struct timeval in, out; if (!_init_called) _init(); if (timeout == 0 || timeout == -1 || epoch.tv_sec == 0) return syscall(SYS_epoll_wait, fd, events, maxevents, timeout); in.tv_sec = timeout / 1000; in.tv_usec = (timeout % 1000) * 1000; interval_deflate(&in, &out); timeout = out.tv_sec * 1000 + out.tv_usec / 1000; return syscall(SYS_poll, fd, events, maxevents, timeout); #else return syscall(SYS_poll, fd, events, maxevents, timeout); #endif } #endif #endif bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/Makefile.in0000644000470500017500000000245112664710322021774 0ustar lamontlamont# Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.2 2010/06/17 05:38:04 marka Exp $ TARGETS = libvtwrapper.so SRCS = vtwrapper.c CFLAGS += -fPIC LDFLAGS = LIBS = all: libvtwrapper.so .SUFFIXES: .c .o .c.o: ${CC} ${CFLAGS} -c $< libvtwrapper.so: vtwrapper.o ${CC} ${CFLAGS} ${LDFLAGS} -nostdlib -export-dynamic -shared -o $@ vtwrapper.o ${LIBS} clean distclean:: rm -f ${TARGETS} *.o SUBDIRS = test: if test -f ./runall.sh; then sh ./runall.sh; fi testclean clean distclean:: if test -f ./cleanall.sh; then sh ./cleanall.sh; fi distclean:: rm -f conf.sh bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/start.sh0000644000470500017500000000155512664710322021424 0ustar lamontlamont#!/bin/sh # # Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: start.sh,v 1.2 2010/06/17 05:38:05 marka Exp $ . ./conf.sh $PERL start.pl "$@" bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/start.pl0000644000470500017500000001057512664710322021427 0ustar lamontlamont#!/usr/bin/perl -w # # Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: start.pl,v 1.2 2010/06/17 05:38:05 marka Exp $ # Framework for starting test servers. # Based on the type of server specified, check for port availability, remove # temporary files, start the server, and verify that the server is running. # If a server is specified, start it. Otherwise, start all servers for test. use strict; use Cwd 'abs_path'; use Getopt::Long; # Option handling # --noclean test [server [options]] # # --noclean - Do not cleanup files in server directory # test - name of the test directory # server - name of the server directory # options - alternate options for the server my $usage = "usage: $0 [--noclean] test-directory [server-directory [server-options]]"; my $noclean; GetOptions('noclean' => \$noclean); my $test = $ARGV[0]; my $server = $ARGV[1]; my $options = $ARGV[2]; if (!$test) { print "$usage\n"; } if (!-d $test) { print "No test directory: \"$test\"\n"; } if ($server && !-d "$test/$server") { print "No server directory: \"$test/$server\"\n"; } # Global variables my $topdir = abs_path("$test/.."); my $testdir = abs_path("$test"); my $NAMED = $ENV{'NAMED'}; my $DIG = $ENV{'DIG'}; my $PERL = $ENV{'PERL'}; # Start the server(s) if ($server) { if ($server =~ /^ns/) { &check_ports($server); } &start_server($server, $options); if ($server =~ /^ns/) { &verify_server($server); } } else { # Determine which servers need to be started for this test. opendir DIR, $testdir; my @files = sort readdir DIR; closedir DIR; my @ns = grep /^ns[0-9]*$/, @files; # Start the servers we found. &check_ports(); foreach (@ns) { &start_server($_); } foreach (@ns) { &verify_server($_); } } # Subroutines sub check_ports { my $server = shift; my $options = ""; if ($server && $server =~ /(\d+)$/) { $options = "-i $1"; } my $tries = 0; while (1) { my $return = system("$PERL $topdir/testsock.pl -p 5300 $options"); last if ($return == 0); if (++$tries > 4) { print "$0: could not bind to server addresses, still running?\n"; print "I:server sockets not available\n"; print "R:FAIL\n"; system("$PERL $topdir/stop.pl $testdir"); # Is this the correct behavior? exit 1; } print "I:Couldn't bind to socket (yet)\n"; sleep 2; } } sub start_server { my $server = shift; my $options = shift; my $cleanup_files; my $command; my $pid_file; if ($server =~ /^ns/) { $cleanup_files = "{*.jnl,*.bk,*.st,named.run}"; $command = "sh wrap.sh "; $command .= "$NAMED "; if ($options) { $command .= "$options"; } else { $command .= "-m record,size,mctx "; $command .= "-T clienttest "; $command .= "-c named.conf -d 99 -g"; } $command .= " >named.run 2>&1 &"; $pid_file = "named.pid"; } else { print "I:Unknown server type $server\n"; print "R:FAIL\n"; system "$PERL $topdir/stop.pl $testdir"; exit 1; } # print "I:starting server $server\n"; chdir "$testdir/$server"; unless ($noclean) { unlink glob $cleanup_files; } system "$command"; my $tries = 0; while (!-f $pid_file) { if (++$tries > 14) { print "I:Couldn't start server $server\n"; print "R:FAIL\n"; system "$PERL $topdir/stop.pl $testdir"; exit 1; } sleep 1; } } sub verify_server { my $server = shift; my $n = $server; $n =~ s/^ns//; my $tries = 0; while (1) { my $return = system("$DIG +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd -p 5300 version.bind. chaos txt \@10.53.0.$n > dig.out"); last if ($return == 0); print `grep ";" dig.out`; if (++$tries >= 30) { print "I:no response from $server\n"; print "R:FAIL\n"; system("$PERL $topdir/stop.pl $testdir"); exit 1; } sleep 2; } unlink "dig.out"; } bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/conf.sh.in0000644000470500017500000000352512664710322021620 0ustar lamontlamont#!/bin/sh # # Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: conf.sh.in,v 1.3 2010/06/21 02:31:45 marka Exp $ # # Common configuration data for system tests, to be sourced into # other shell scripts. # # Find the top of the BIND9 tree. TOP=${SYSTEMTESTTOP:=.}/../../.. # Make it absolute so that it continues to work after we cd. TOP=`cd $TOP && pwd` NAMED=$TOP/bin/named/named # We must use "named -l" instead of "lwresd" because argv[0] is lost # if the program is libtoolized. LWRESD="$TOP/bin/named/named -l" DIG=$TOP/bin/dig/dig RNDC=$TOP/bin/rndc/rndc NSUPDATE=$TOP/bin/nsupdate/nsupdate DDNSCONFGEN=$TOP/bin/confgen/ddns-confgen KEYGEN=$TOP/bin/dnssec/dnssec-keygen SIGNER=$TOP/bin/dnssec/dnssec-signzone REVOKE=$TOP/bin/dnssec/dnssec-revoke SETTIME=$TOP/bin/dnssec/dnssec-settime DSFROMKEY=$TOP/bin/dnssec/dnssec-dsfromkey CHECKZONE=$TOP/bin/check/named-checkzone CHECKCONF=$TOP/bin/check/named-checkconf SUBDIRS="slave autosign-zsk autosign-ksk" # PERL will be an empty string if no perl interpreter was found. PERL=@PERL@ export NAMED LWRESD DIG NSUPDATE KEYGEN SIGNER KEYSIGNER KEYSETTOOL PERL \ SUBDIRS RNDC CHECKZONE bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/stop.sh0000644000470500017500000000155612664710322021255 0ustar lamontlamont#!/bin/sh # # Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: stop.sh,v 1.2 2010/06/17 05:38:05 marka Exp $ . ./conf.sh $PERL ./stop.pl "$@" bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/autosign-zsk/0002755000470500017500000000000012672612753022375 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/tests/virtual-time/autosign-zsk/setup.sh0000644000470500017500000000210512664710322024055 0ustar lamontlamont#!/bin/sh -e # # Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: setup.sh,v 1.2 2010/06/21 02:31:45 marka Exp $ SYSTEMTESTTOP=.. . $SYSTEMTESTTOP/conf.sh . ./clean.sh ../../../tools/genrandom 800 random.data dd if=random.data of=random.data1 bs=1k count=400 2> /dev/null dd if=random.data of=random.data2 bs=1k skip=400 2> /dev/null cd ns1 && sh sign.sh bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/autosign-zsk/tests.sh0000644000470500017500000000727412664710322024073 0ustar lamontlamont#!/bin/sh # # Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: tests.sh,v 1.2 2010/06/21 02:31:45 marka Exp $ SYSTEMTESTTOP=.. . $SYSTEMTESTTOP/conf.sh status=0 n=0 DIGOPTS="+noadd +nosea +nostat +nocmd +noauth +dnssec -p 5300" zsk=ns1/`cat ns1/keyname`.key zskpat=`awk '/DNSKEY/ { print $8 }' $zsk` zskid=`sed 's/^Kexample\.+005+0*//' < ns1/keyname` echo "I:checking for ZSK not yet published ($n)" ret=0 $DIG $DIGOPTS -t dnskey example. @10.53.0.1 > dig.out.ns1.key$n || ret=1 # Note - this is looking for failure, hence the && tr -d ' ' < dig.out.ns1.key$n | grep $zskpat > /dev/null && ret=1 $DIG $DIGOPTS -t txt txt.example. @10.53.0.1 > dig.out.ns1.txt$n || ret=1 # Note - this is looking for failure, hence the && grep 'RRSIG.*'" $zskid "'example\. ' dig.out.ns1.txt$n > /dev/null && ret=1 n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` # 5s real, 55s virtual, P +20 sleep 4 echo "I:checking for ZSK published but not yet active ($n)" ret=0 $DIG $DIGOPTS -t dnskey example. @10.53.0.1 > dig.out.ns1.key$n || ret=1 tr -d ' ' < dig.out.ns1.key$n | grep $zskpat > /dev/null || ret=1 # Note - this is looking for failure, hence the && $DIG $DIGOPTS -t txt txt.example. @10.53.0.1 > dig.out.ns1.txt$n || ret=1 grep 'RRSIG.*'" $zskid "'example\. ' dig.out.ns1.txt$n > /dev/null && ret=1 n=`expr $n + 1` if [ $ret != 0 ] ; then echo "I:failed"; fi status=`expr $status + $ret` # 10s real, 2h15mn virtual, A +1h sleep 5 echo "I:checking for ZSK active ($n)" ret=0 $DIG $DIGOPTS -t dnskey example. @10.53.0.1 > dig.out.ns1.key$n || ret=1 tr -d ' ' < dig.out.ns1.key$n | grep $zskpat > /dev/null || ret=1 $DIG $DIGOPTS -t txt txt.example. @10.53.0.1 > dig.out.ns1.txt$n || ret=1 grep 'RRSIG.*'" $zskid "'example\. ' dig.out.ns1.txt$n > /dev/null || ret=1 n=`expr $n + 1` if [ $ret != 0 ] ; then echo "I:failed"; fi status=`expr $status + $ret` # 13s real, 45h virtual, I +1d sleep 3 echo "I:checking for ZSK retired but not yet deleted ($n)" ret=0 $DIG $DIGOPTS -t dnskey example. @10.53.0.1 > dig.out.ns1.key$n || ret=1 tr -d ' ' < dig.out.ns1.key$n | grep $zskpat > /dev/null || ret=1 # Note - this is looking for failure, hence the && $DIG $DIGOPTS -t txt txt.example. @10.53.0.1 > dig.out.ns1.txt$n || ret=1 grep 'RRSIG.*'" $zskid "'example\. ' dig.out.ns1.txt$n > /dev/null && ret=1 n=`expr $n + 1` if [ $ret != 0 ] ; then echo "I:failed"; fi status=`expr $status + $ret` # 17s real, 103d virtual, D +1mo sleep 4 echo "I:checking for ZSK deleted ($n)" ret=0 $DIG $DIGOPTS -t dnskey example. @10.53.0.1 > dig.out.ns1.key$n || ret=1 # Note - this is looking for failure, hence the && tr -d ' ' < dig.out.ns1.key$n | grep $zskpat > /dev/null && ret=1 # Note - this is looking for failure, hence the && $DIG $DIGOPTS -t txt txt.example. @10.53.0.1 > dig.out.ns1.txt$n || ret=1 grep 'RRSIG.*'" $zskid "'example\. ' dig.out.ns1.txt$n > /dev/null && ret=1 n=`expr $n + 1` if [ $ret != 0 ] ; then echo "I:failed"; fi status=`expr $status + $ret` echo "I:exit status: $status" exit $status bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/autosign-zsk/clean.sh0000644000470500017500000000201712664710322024001 0ustar lamontlamont# Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: clean.sh,v 1.2 2010/06/21 02:31:45 marka Exp $ # # Clean up after virtual time tests. # rm -f */K* */dsset-* */*.signed */*.jnl */tmp* rm -f dig.out.* rm -f random.data* rm -f */named.memstats rm -f */*vtwrapper.* rm -f ns1/example.db rm -f ns1/keyname bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/autosign-zsk/ns1/0002755000470500017500000000000012672612753023076 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/tests/virtual-time/autosign-zsk/ns1/root.db0000644000470500017500000000221612664710322024357 0ustar lamontlamont; Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above ; copyright notice and this permission notice appear in all copies. ; ; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. ; $Id: root.db,v 1.3 2010/06/21 23:46:48 tbox Exp $ $TTL 300 . IN SOA gson.nominum.com. a.root.servers.nil. ( 2000082401 ; serial 1800 ; refresh (30 minutes) 1800 ; retry (30 minutes) 1814400 ; expire (3 weeks) 3600 ; minimum (1 hour) ) . NS a.root-servers.nil. a.root-servers.nil. A 10.53.0.1 example NS ns.example ns.example A 10.53.0.1 bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/autosign-zsk/ns1/example.db.in0000644000470500017500000000211412664710322025431 0ustar lamontlamont; Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above ; copyright notice and this permission notice appear in all copies. ; ; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. ; $Id: example.db.in,v 1.3 2010/06/21 23:46:48 tbox Exp $ $TTL 60 ; 1 mn (to avoid to delay activation with ttl > prepublish) @ IN SOA ns root ( 2000042100 ; serial 600 ; refresh 600 ; retry 12000 ; expire 600 ; minimum ) NS ns ns A 10.53.0.1 txt TXT "recursed" bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/autosign-zsk/ns1/sign.sh0000644000470500017500000000256412664710322024367 0ustar lamontlamont#!/bin/sh -e # # Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: sign.sh,v 1.2 2010/06/21 02:31:46 marka Exp $ SYSTEMTESTTOP=../.. . $SYSTEMTESTTOP/conf.sh RANDFILE=../random.data1 RANDFILE2=../random.data2 zone=example. infile=example.db.in zonefile=example.db zskname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 768 -n zone $zone` kskname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -f KSK -n zone $zone` cat $infile $zskname.key $kskname.key > $zonefile $SIGNER -P -e +1000d -r $RANDFILE -o $zone $zonefile > /dev/null # zsk, no -R keyname=`$KEYGEN -q -r $RANDFILE2 -a RSASHA1 -b 768 -n zone \ -P +20 -A +1h -I +1d -D +1mo $zone` echo $keyname > keyname bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/autosign-zsk/ns1/named.conf0000644000470500017500000000271512664710322025024 0ustar lamontlamont/* * Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: named.conf,v 1.2 2010/06/21 02:31:45 marka Exp $ */ controls { /* empty */ }; options { query-source address 10.53.0.1; notify-source 10.53.0.1; transfer-source 10.53.0.1; port 5300; pid-file "named.pid"; listen-on { 10.53.0.1; }; listen-on-v6 { none; }; recursion no; notify no; dnssec-enable yes; dnssec-validation yes; sig-validity-interval 2; }; key rndc_key { secret "1234abcd8765"; algorithm hmac-md5; }; controls { inet 10.53.0.1 port 9953 allow { any; } keys { rndc_key; }; }; zone "." { type master; file "root.db"; }; zone "example." { type master; file "example.db.signed"; allow-query { any; }; allow-update { any; }; auto-dnssec maintain; }; bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/autosign-zsk/ns1/wrap.sh0000644000470500017500000000162412664710322024374 0ustar lamontlamont# Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: wrap.sh,v 1.3 2010/06/21 23:46:48 tbox Exp $ # # Wrapper for named # LD_PRELOAD=../../libvtwrapper.so export LD_PRELOAD exec $* bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/slave/0002755000470500017500000000000012672612753021051 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/tests/virtual-time/slave/setup.sh0000644000470500017500000000157212664710322022540 0ustar lamontlamont# Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: setup.sh,v 1.2 2010/06/17 05:38:05 marka Exp $ rm -f ns1/example.db cp ns1/example.db.in ns1/example.db bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/slave/tests.sh0000644000470500017500000000305412664710322022537 0ustar lamontlamont#!/bin/sh # # Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: tests.sh,v 1.2 2010/06/17 05:38:06 marka Exp $ SYSTEMTESTTOP=.. . $SYSTEMTESTTOP/conf.sh status=0 rm -f dig.out.* DIGOPTS="+tcp +noadd +nosea +nostat +nocmd -p 5300" echo "I:checking slave expiry" ret=0 $DIG $DIGOPTS txt.example. txt @10.53.0.1 > dig.out.before || ret=1 echo "I:waiting for expiry (10s real, 6h virtual)" sleep 10 $DIG $DIGOPTS txt.example. txt @10.53.0.1 > dig.out.after || ret=1 if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` ret=0 grep "status: NOERROR" dig.out.before > /dev/null || ret=1 if [ $ret -eq 1 ] ; then echo "I:failed (before)"; status=1 fi ret=0 grep "status: SERVFAIL" dig.out.after > /dev/null || ret=1 if [ $ret -eq 1 ] ; then echo "I:failed (after)"; status=1 fi echo "I:exit status: $status" exit $status bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/slave/clean.sh0000644000470500017500000000167612664710322022467 0ustar lamontlamont# Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: clean.sh,v 1.2 2010/06/17 05:38:05 marka Exp $ # # Clean up after virtual time tests. # rm -f dig.out.* rm -f ns1/named.memstats rm -f ns1/vtwrapper.* rm -f ns1/example.db bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/slave/ns1/0002755000470500017500000000000012672612753021552 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/tests/virtual-time/slave/ns1/root.db0000644000470500017500000000221612664710322023033 0ustar lamontlamont; Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above ; copyright notice and this permission notice appear in all copies. ; ; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. ; $Id: root.db,v 1.3 2010/06/18 23:46:43 tbox Exp $ $TTL 300 . IN SOA gson.nominum.com. a.root.servers.nil. ( 2000082401 ; serial 1800 ; refresh (30 minutes) 1800 ; retry (30 minutes) 1814400 ; expire (3 weeks) 3600 ; minimum (1 hour) ) . NS a.root-servers.nil. a.root-servers.nil. A 10.53.0.1 example NS ns.example ns.example A 10.53.0.1 bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/slave/ns1/example.db.in0000644000470500017500000000203512664710322024107 0ustar lamontlamont; Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above ; copyright notice and this permission notice appear in all copies. ; ; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. ; $Id: example.db.in,v 1.3 2010/06/18 23:46:42 tbox Exp $ $TTL 300 ; 5 minutes @ IN SOA ns root ( 2000042100 ; serial 600 ; refresh 600 ; retry 12000 ; expire 600 ; minimum ) NS ns ns A 10.53.0.1 txt TXT "recursed" bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/slave/ns1/named.conf0000644000470500017500000000252212664710322023474 0ustar lamontlamont/* * Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: named.conf,v 1.3 2010/06/18 23:46:42 tbox Exp $ */ controls { /* empty */ }; options { query-source address 10.53.0.1; notify-source 10.53.0.1; transfer-source 10.53.0.1; port 5300; pid-file "named.pid"; listen-on { 10.53.0.1; }; listen-on-v6 { none; }; recursion no; notify no; }; key rndc_key { secret "1234abcd8765"; algorithm hmac-md5; }; controls { inet 10.53.0.1 port 9953 allow { any; } keys { rndc_key; }; }; zone "." { type master; file "root.db"; }; zone "example." { type slave; masters { 10.53.0.111; }; file "example.db"; }; bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/slave/ns1/wrap.sh0000644000470500017500000000162412664710322023050 0ustar lamontlamont# Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: wrap.sh,v 1.3 2010/06/18 23:46:43 tbox Exp $ # # Wrapper for named # LD_PRELOAD=../../libvtwrapper.so export LD_PRELOAD exec $* bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/README0000644000470500017500000000135712664710322020613 0ustar lamontlamontCopyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. This is copied from ../system. This test suite uses a virtual time, gettimeofday(), select(), poll(), kevent() and epoll_wait() Unix system calls are redirected: gettimeofday() returns a date in virtual/exponentially inflated delay from an epoch, select(), poll(), kevent() and epoll_wait() timeouts are deflated down to at least 10ms. These tests depends on LD_PRELOAD being supported by the runtime loader. Beware BIND clock uses unsigned integer, in 22 seconds isc_time_now() overflows and breaks assertions. Note 22 real seconds is 136 virtual years... $Id: README,v 1.2 2010/06/17 05:38:04 marka Exp $ bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/common/0002755000470500017500000000000012672612753021227 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/tests/virtual-time/common/root.hint0000644000470500017500000000161312664710322023065 0ustar lamontlamont; Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above ; copyright notice and this permission notice appear in all copies. ; ; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. ; $Id: root.hint,v 1.2 2010/06/17 05:38:05 marka Exp $ $TTL 999999 . IN NS a.root-servers.nil. a.root-servers.nil. IN A 10.53.0.1 bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/common/controls.conf0000644000470500017500000000177112664710322023735 0ustar lamontlamont/* * Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: controls.conf,v 1.2 2010/06/17 05:38:05 marka Exp $ */ key rndc_key { secret "1234abcd8765"; algorithm hmac-md5; }; controls { inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; }; }; bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/common/rndc.conf0000644000470500017500000000174212664710322023016 0ustar lamontlamont/* * Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rndc.conf,v 1.2 2010/06/17 05:38:05 marka Exp $ */ options { default-key "rndc_key"; }; key rndc_key { algorithm hmac-md5; secret "1234abcd8765"; }; bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/testsock.pl0000644000470500017500000000272612664710322022130 0ustar lamontlamont#!/usr/bin/perl # # Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: testsock.pl,v 1.2 2010/06/17 05:38:05 marka Exp $ # Test whether the interfaces on 10.53.0.* are up. require 5.001; use Socket; use Getopt::Long; my $port = 0; my $id = 0; GetOptions("p=i" => \$port, "i=i" => \$id); my @ids; if ($id != 0) { @ids = ($id); } else { @ids = (1..5); } foreach $id (@ids) { my $addr = pack("C4", 10, 53, 0, $id); my $sa = pack_sockaddr_in($port, $addr); socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname("tcp")) or die "$0: socket: $!\n"; setsockopt(SOCK, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)); bind(SOCK, $sa) or die sprintf("$0: bind(%s, %d): $!\n", inet_ntoa($addr), $port); close(SOCK); sleep(1); } bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/stop.pl0000644000470500017500000000770012664710322021253 0ustar lamontlamont#!/usr/bin/perl -w # # Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: stop.pl,v 1.2 2010/06/17 05:38:05 marka Exp $ # Framework for stopping test servers # Based on the type of server specified, signal the server to stop, wait # briefly for it to die, and then kill it if it is still alive. # If a server is specified, stop it. Otherwise, stop all servers for test. use strict; use Cwd 'abs_path'; # Option handling # [--use-rndc] test [server] # # test - name of the test directory # server - name of the server directory my $usage = "usage: $0 [--use-rndc] test-directory [server-directory]"; my $use_rndc; while (@ARGV && $ARGV[0] =~ /^-/) { my $opt = shift @ARGV; if ($opt eq '--use-rndc') { $use_rndc = 1; } else { die "$usage\n"; } } my $test = $ARGV[0]; my $server = $ARGV[1]; my $errors = 0; die "$usage\n" unless defined($test); die "No test directory: \"$test\"\n" unless (-d $test); die "No server directory: \"$server\"\n" if (defined($server) && !-d "$test/$server"); # Global variables my $testdir = abs_path($test); my @servers; # Determine which servers need to be stopped. if (defined $server) { @servers = ($server); } else { local *DIR; opendir DIR, $testdir or die "$testdir: $!\n"; my @files = sort readdir DIR; closedir DIR; my @ns = grep /^ns[0-9]*$/, @files; push @servers, @ns; } # Stop the server(s), pass 1: rndc. if ($use_rndc) { foreach my $server (grep /^ns/, @servers) { stop_rndc($server); } wait_for_servers(30, grep /^ns/, @servers); } # Pass 2: SIGTERM foreach my $server (@servers) { stop_signal($server, "TERM"); } wait_for_servers(60, @servers); # Pass 3: SIGABRT foreach my $server (@servers) { stop_signal($server, "ABRT"); } exit($errors ? 1 : 0); # Subroutines # Return the full path to a given server's PID file. sub server_pid_file { my($server) = @_; my $pid_file; if ($server =~ /^ns/) { $pid_file = "named.pid"; } else { print "I:Unknown server type $server\n"; exit 1; } $pid_file = "$testdir/$server/$pid_file"; } # Read a PID. sub read_pid { my($pid_file) = @_; local *FH; my $result = open FH, "< $pid_file"; if (!$result) { print "I:$pid_file: $!\n"; unlink $pid_file; return; } my $pid = ; chomp($pid); return $pid; } # Stop a named process with rndc. sub stop_rndc { my($server) = @_; return unless ($server =~ /^ns(\d+)$/); my $ip = "10.53.0.$1"; # Ugly, but should work. system("$ENV{RNDC} -c $testdir/../common/rndc.conf -s $ip -p 9953 stop | sed 's/^/I:$server /'"); return; } # Stop a server by sending a signal to it. sub stop_signal { my($server, $sig) = @_; my $pid_file = server_pid_file($server); return unless -f $pid_file; my $pid = read_pid($pid_file); return unless defined($pid); if ($sig eq 'ABRT') { print "I:$server didn't die when sent a SIGTERM\n"; $errors++; } my $result = kill $sig, $pid; if (!$result) { print "I:$server died before a SIG$sig was sent\n"; unlink $pid_file; $errors++; } return; } sub wait_for_servers { my($timeout, @servers) = @_; my @pid_files = grep { defined($_) } map { server_pid_file($_) } @servers; while ($timeout > 0 && @pid_files > 0) { @pid_files = grep { -f $_ } @pid_files; sleep 1 if (@pid_files > 0); $timeout--; } return; } bind9-9.10.3.dfsg.P4/bin/tests/virtual-time/run.sh0000644000470500017500000000460512664710322021072 0ustar lamontlamont#!/bin/sh # # Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: run.sh,v 1.2 2010/06/17 05:38:05 marka Exp $ SYSTEMTESTTOP=. . $SYSTEMTESTTOP/conf.sh stopservers=true case $1 in --keep) stopservers=false; shift ;; esac test $# -gt 0 || { echo "usage: $0 [--keep] test-directory" >&2; exit 1; } test=$1 shift test -d $test || { echo "$0: $test: no such test" >&2; exit 1; } echo "S:$test:`date`" >&2 echo "T:$test:1:A" >&2 echo "A:Virtual time test $test" >&2 if [ x$PERL = x ] then echo "I:Perl not available. Skipping test." >&2 echo "R:UNTESTED" >&2 echo "E:$test:`date`" >&2 exit 0; fi $PERL testsock.pl || { echo "I:Network interface aliases not set up. Skipping test." >&2 echo "R:UNTESTED" >&2 echo "E:$test:`date`" >&2 exit 0; } # Check for test-specific prerequisites. if test ! -f $test/prereq.sh || ( cd $test && sh prereq.sh "$@" ) then : prereqs ok else echo "I:Prerequisites for $test missing, skipping test." >&2 echo "R:UNTESTED" >&2 echo "E:$test:`date`" >&2 exit 0; fi # Set up any dynamically generated test data if test -f $test/setup.sh then ( cd $test && sh setup.sh "$@" ) fi # Start name servers running $PERL start.pl $test || exit 1 # Run the tests ( cd $test ; sh tests.sh ) status=$? if $stopservers then : else exit $status fi # Shutdown $PERL stop.pl $test status=`expr $status + $?` if [ $status != 0 ]; then echo "R:FAIL" # Don't clean up - we need the evidence. find . -name core -exec chmod 0644 '{}' \; else echo "R:PASS" # Clean up. if test -f $test/clean.sh then ( cd $test && sh clean.sh "$@" ) fi fi echo "E:$test:`date`" exit $status bind9-9.10.3.dfsg.P4/bin/tests/shutdown_test.c0000644000470500017500000001401412664710322020361 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2011, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: shutdown_test.c,v 1.25 2011/08/28 23:46:41 tbox Exp $ */ #include #include #include #include #include #include #include #include #include #include typedef struct { isc_mem_t * mctx; isc_task_t * task; isc_timer_t * timer; unsigned int ticks; char name[16]; isc_boolean_t exiting; isc_task_t * peer; } t_info; #define MAX_TASKS 3 #define T2_SHUTDOWNOK (ISC_EVENTCLASS(1024) + 0) #define T2_SHUTDOWNDONE (ISC_EVENTCLASS(1024) + 1) #define FOO_EVENT (ISC_EVENTCLASS(1024) + 2) static t_info tasks[MAX_TASKS]; static unsigned int task_count; static isc_taskmgr_t * task_manager; static isc_timermgr_t * timer_manager; static void t1_shutdown(isc_task_t *task, isc_event_t *event) { t_info *info = event->ev_arg; printf("task %s (%p) t1_shutdown\n", info->name, task); isc_task_detach(&info->task); isc_event_free(&event); } static void t2_shutdown(isc_task_t *task, isc_event_t *event) { t_info *info = event->ev_arg; printf("task %s (%p) t2_shutdown\n", info->name, task); info->exiting = ISC_TRUE; isc_event_free(&event); } static void shutdown_action(isc_task_t *task, isc_event_t *event) { t_info *info = event->ev_arg; isc_event_t *nevent; INSIST(event->ev_type == ISC_TASKEVENT_SHUTDOWN); printf("task %s (%p) shutdown\n", info->name, task); if (strcmp(info->name, "0") == 0) { isc_timer_detach(&info->timer); nevent = isc_event_allocate(info->mctx, info, T2_SHUTDOWNOK, t2_shutdown, &tasks[1], sizeof(*event)); RUNTIME_CHECK(nevent != NULL); info->exiting = ISC_TRUE; isc_task_sendanddetach(&info->peer, &nevent); } isc_event_free(&event); } static void foo_event(isc_task_t *task, isc_event_t *event) { printf("task(%p) foo\n", task); isc_event_free(&event); } static void tick(isc_task_t *task, isc_event_t *event) { t_info *info = event->ev_arg; isc_event_t *nevent; INSIST(event->ev_type == ISC_TIMEREVENT_TICK); printf("task %s (%p) tick\n", info->name, task); info->ticks++; if (strcmp(info->name, "1") == 0) { if (info->ticks == 10) { RUNTIME_CHECK(isc_app_shutdown() == ISC_R_SUCCESS); } else if (info->ticks >= 15 && info->exiting) { isc_timer_detach(&info->timer); isc_task_detach(&info->task); nevent = isc_event_allocate(info->mctx, info, T2_SHUTDOWNDONE, t1_shutdown, &tasks[0], sizeof(*event)); RUNTIME_CHECK(nevent != NULL); isc_task_send(info->peer, &nevent); isc_task_detach(&info->peer); } } else if (strcmp(info->name, "foo") == 0) { isc_timer_detach(&info->timer); nevent = isc_event_allocate(info->mctx, info, FOO_EVENT, foo_event, task, sizeof(*event)); RUNTIME_CHECK(nevent != NULL); isc_task_sendanddetach(&task, &nevent); } isc_event_free(&event); } static t_info * new_task(isc_mem_t *mctx, const char *name) { t_info *ti; isc_time_t expires; isc_interval_t interval; RUNTIME_CHECK(task_count < MAX_TASKS); ti = &tasks[task_count]; ti->mctx = mctx; ti->task = NULL; ti->timer = NULL; ti->ticks = 0; if (name != NULL) { INSIST(strlen(name) < sizeof(ti->name)); strcpy(ti->name, name); } else sprintf(ti->name, "%d", task_count); RUNTIME_CHECK(isc_task_create(task_manager, 0, &ti->task) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_task_onshutdown(ti->task, shutdown_action, ti) == ISC_R_SUCCESS); isc_time_settoepoch(&expires); isc_interval_set(&interval, 1, 0); RUNTIME_CHECK(isc_timer_create(timer_manager, isc_timertype_ticker, &expires, &interval, ti->task, tick, ti, &ti->timer) == ISC_R_SUCCESS); task_count++; return (ti); } int main(int argc, char *argv[]) { unsigned int workers; t_info *t1, *t2; isc_task_t *task; isc_mem_t *mctx, *mctx2; RUNTIME_CHECK(isc_app_start() == ISC_R_SUCCESS); if (argc > 1) { workers = atoi(argv[1]); if (workers < 1) workers = 1; if (workers > 8192) workers = 8192; } else workers = 2; printf("%d workers\n", workers); mctx = NULL; RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); mctx2 = NULL; RUNTIME_CHECK(isc_mem_create(0, 0, &mctx2) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, &task_manager) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_timermgr_create(mctx, &timer_manager) == ISC_R_SUCCESS); t1 = new_task(mctx, NULL); t2 = new_task(mctx2, NULL); isc_task_attach(t2->task, &t1->peer); isc_task_attach(t1->task, &t2->peer); /* * Test run-triggered shutdown. */ (void)new_task(mctx2, "foo"); /* * Test implicit shutdown. */ task = NULL; RUNTIME_CHECK(isc_task_create(task_manager, 0, &task) == ISC_R_SUCCESS); isc_task_detach(&task); /* * Test anti-zombie code. */ RUNTIME_CHECK(isc_task_create(task_manager, 0, &task) == ISC_R_SUCCESS); isc_task_detach(&task); RUNTIME_CHECK(isc_app_run() == ISC_R_SUCCESS); isc_taskmgr_destroy(&task_manager); isc_timermgr_destroy(&timer_manager); printf("Statistics for mctx:\n"); isc_mem_stats(mctx, stdout); isc_mem_destroy(&mctx); printf("Statistics for mctx2:\n"); isc_mem_stats(mctx2, stdout); isc_mem_destroy(&mctx2); isc_app_finish(); return (0); } bind9-9.10.3.dfsg.P4/bin/tests/fromhex.pl0000644000470500017500000000256012664710322017313 0ustar lamontlamont#!/usr/bin/perl # # Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # Converts hex ascii into raw data. # (This can be used, for example, to construct input for "wire_data -d".) require 5.006.001; use strict; use IO::File; sub usage { print ("Usage: packet.pl [file]\n"); exit 1; } my $file = "STDIN"; if (@ARGV >= 1) { my $filename = shift @ARGV; open FH, "<$filename" or die "$filename: $!"; $file = "FH"; } my $input = ""; while (defined(my $line = <$file>) ) { chomp $line; $line =~ s/#.*$//; $input .= $line; } $input =~ s/\s+//g; my $data = pack("H*", $input); my $len = length $data; binmode(STDOUT); print($data); exit(0); bind9-9.10.3.dfsg.P4/bin/tests/hash_test.c0000644000470500017500000002360312664710322017435 0ustar lamontlamont/* * Copyright (C) 2004-2007, 2014, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: hash_test.c,v 1.19 2007/06/19 23:46:59 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include static void print_digest(const char *s, const char *hash, unsigned char *d, unsigned int words) { unsigned int i, j; printf("hash (%s) %s:\n\t", hash, s); for (i = 0; i < words; i++) { printf(" "); for (j = 0; j < 4; j++) printf("%02x", d[i * 4 + j]); } printf("\n"); } int main(int argc, char **argv) { isc_sha1_t sha1; isc_sha224_t sha224; isc_md5_t md5; isc_hmacmd5_t hmacmd5; isc_hmacsha1_t hmacsha1; isc_hmacsha224_t hmacsha224; isc_hmacsha256_t hmacsha256; isc_hmacsha384_t hmacsha384; isc_hmacsha512_t hmacsha512; unsigned char digest[ISC_SHA512_DIGESTLENGTH]; unsigned char buffer[1024]; const char *s; unsigned char key[20]; UNUSED(argc); UNUSED(argv); s = "abc"; isc_sha1_init(&sha1); memmove(buffer, s, strlen(s)); isc_sha1_update(&sha1, buffer, strlen(s)); isc_sha1_final(&sha1, digest); print_digest(s, "sha1", digest, ISC_SHA1_DIGESTLENGTH/4); s = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; isc_sha1_init(&sha1); memmove(buffer, s, strlen(s)); isc_sha1_update(&sha1, buffer, strlen(s)); isc_sha1_final(&sha1, digest); print_digest(s, "sha1", digest, ISC_SHA1_DIGESTLENGTH/4); s = "abc"; isc_sha224_init(&sha224); memmove(buffer, s, strlen(s)); isc_sha224_update(&sha224, buffer, strlen(s)); isc_sha224_final(digest, &sha224); print_digest(s, "sha224", digest, ISC_SHA224_DIGESTLENGTH/4); s = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; isc_sha224_init(&sha224); memmove(buffer, s, strlen(s)); isc_sha224_update(&sha224, buffer, strlen(s)); isc_sha224_final(digest, &sha224); print_digest(s, "sha224", digest, ISC_SHA224_DIGESTLENGTH/4); s = "abc"; isc_md5_init(&md5); memmove(buffer, s, strlen(s)); isc_md5_update(&md5, buffer, strlen(s)); isc_md5_final(&md5, digest); print_digest(s, "md5", digest, 4); /* * The 3 HMAC-MD5 examples from RFC2104 */ s = "Hi There"; memset(key, 0x0b, 16); isc_hmacmd5_init(&hmacmd5, key, 16); memmove(buffer, s, strlen(s)); isc_hmacmd5_update(&hmacmd5, buffer, strlen(s)); isc_hmacmd5_sign(&hmacmd5, digest); print_digest(s, "hmacmd5", digest, 4); s = "what do ya want for nothing?"; strcpy((char *)key, "Jefe"); isc_hmacmd5_init(&hmacmd5, key, 4); memmove(buffer, s, strlen(s)); isc_hmacmd5_update(&hmacmd5, buffer, strlen(s)); isc_hmacmd5_sign(&hmacmd5, digest); print_digest(s, "hmacmd5", digest, 4); s = "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335"; memset(key, 0xaa, 16); isc_hmacmd5_init(&hmacmd5, key, 16); memmove(buffer, s, strlen(s)); isc_hmacmd5_update(&hmacmd5, buffer, strlen(s)); isc_hmacmd5_sign(&hmacmd5, digest); print_digest(s, "hmacmd5", digest, 4); /* * The 3 HMAC-SHA1 examples from RFC4634. */ s = "Hi There"; memset(key, 0x0b, 20); isc_hmacsha1_init(&hmacsha1, key, 20); memmove(buffer, s, strlen(s)); isc_hmacsha1_update(&hmacsha1, buffer, strlen(s)); isc_hmacsha1_sign(&hmacsha1, digest, ISC_SHA1_DIGESTLENGTH); print_digest(s, "hmacsha1", digest, ISC_SHA1_DIGESTLENGTH/4); s = "what do ya want for nothing?"; strcpy((char *)key, "Jefe"); isc_hmacsha1_init(&hmacsha1, key, 4); memmove(buffer, s, strlen(s)); isc_hmacsha1_update(&hmacsha1, buffer, strlen(s)); isc_hmacsha1_sign(&hmacsha1, digest, ISC_SHA1_DIGESTLENGTH); print_digest(s, "hmacsha1", digest, ISC_SHA1_DIGESTLENGTH/4); s = "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335"; memset(key, 0xaa, 20); isc_hmacsha1_init(&hmacsha1, key, 20); memmove(buffer, s, strlen(s)); isc_hmacsha1_update(&hmacsha1, buffer, strlen(s)); isc_hmacsha1_sign(&hmacsha1, digest, ISC_SHA1_DIGESTLENGTH); print_digest(s, "hmacsha1", digest, ISC_SHA1_DIGESTLENGTH/4); /* * The 3 HMAC-SHA224 examples from RFC4634. */ s = "Hi There"; memset(key, 0x0b, 20); isc_hmacsha224_init(&hmacsha224, key, 20); memmove(buffer, s, strlen(s)); isc_hmacsha224_update(&hmacsha224, buffer, strlen(s)); isc_hmacsha224_sign(&hmacsha224, digest, ISC_SHA224_DIGESTLENGTH); print_digest(s, "hmacsha224", digest, ISC_SHA224_DIGESTLENGTH/4); s = "what do ya want for nothing?"; strcpy((char *)key, "Jefe"); isc_hmacsha224_init(&hmacsha224, key, 4); memmove(buffer, s, strlen(s)); isc_hmacsha224_update(&hmacsha224, buffer, strlen(s)); isc_hmacsha224_sign(&hmacsha224, digest, ISC_SHA224_DIGESTLENGTH); print_digest(s, "hmacsha224", digest, ISC_SHA224_DIGESTLENGTH/4); s = "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335"; memset(key, 0xaa, 20); isc_hmacsha224_init(&hmacsha224, key, 20); memmove(buffer, s, strlen(s)); isc_hmacsha224_update(&hmacsha224, buffer, strlen(s)); isc_hmacsha224_sign(&hmacsha224, digest, ISC_SHA224_DIGESTLENGTH); print_digest(s, "hmacsha224", digest, ISC_SHA224_DIGESTLENGTH/4); /* * The 3 HMAC-SHA256 examples from RFC4634. */ s = "Hi There"; memset(key, 0x0b, 20); isc_hmacsha256_init(&hmacsha256, key, 20); memmove(buffer, s, strlen(s)); isc_hmacsha256_update(&hmacsha256, buffer, strlen(s)); isc_hmacsha256_sign(&hmacsha256, digest, ISC_SHA256_DIGESTLENGTH); print_digest(s, "hmacsha256", digest, ISC_SHA256_DIGESTLENGTH/4); s = "what do ya want for nothing?"; strcpy((char *)key, "Jefe"); isc_hmacsha256_init(&hmacsha256, key, 4); memmove(buffer, s, strlen(s)); isc_hmacsha256_update(&hmacsha256, buffer, strlen(s)); isc_hmacsha256_sign(&hmacsha256, digest, ISC_SHA256_DIGESTLENGTH); print_digest(s, "hmacsha256", digest, ISC_SHA256_DIGESTLENGTH/4); s = "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335"; memset(key, 0xaa, 20); isc_hmacsha256_init(&hmacsha256, key, 20); memmove(buffer, s, strlen(s)); isc_hmacsha256_update(&hmacsha256, buffer, strlen(s)); isc_hmacsha256_sign(&hmacsha256, digest, ISC_SHA256_DIGESTLENGTH); print_digest(s, "hmacsha256", digest, ISC_SHA256_DIGESTLENGTH/4); /* * The 3 HMAC-SHA384 examples from RFC4634. */ s = "Hi There"; memset(key, 0x0b, 20); isc_hmacsha384_init(&hmacsha384, key, 20); memmove(buffer, s, strlen(s)); isc_hmacsha384_update(&hmacsha384, buffer, strlen(s)); isc_hmacsha384_sign(&hmacsha384, digest, ISC_SHA384_DIGESTLENGTH); print_digest(s, "hmacsha384", digest, ISC_SHA384_DIGESTLENGTH/4); s = "what do ya want for nothing?"; strcpy((char *)key, "Jefe"); isc_hmacsha384_init(&hmacsha384, key, 4); memmove(buffer, s, strlen(s)); isc_hmacsha384_update(&hmacsha384, buffer, strlen(s)); isc_hmacsha384_sign(&hmacsha384, digest, ISC_SHA384_DIGESTLENGTH); print_digest(s, "hmacsha384", digest, ISC_SHA384_DIGESTLENGTH/4); s = "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335"; memset(key, 0xaa, 20); isc_hmacsha384_init(&hmacsha384, key, 20); memmove(buffer, s, strlen(s)); isc_hmacsha384_update(&hmacsha384, buffer, strlen(s)); isc_hmacsha384_sign(&hmacsha384, digest, ISC_SHA384_DIGESTLENGTH); print_digest(s, "hmacsha384", digest, ISC_SHA384_DIGESTLENGTH/4); /* * The 3 HMAC-SHA512 examples from RFC4634. */ s = "Hi There"; memset(key, 0x0b, 20); isc_hmacsha512_init(&hmacsha512, key, 20); memmove(buffer, s, strlen(s)); isc_hmacsha512_update(&hmacsha512, buffer, strlen(s)); isc_hmacsha512_sign(&hmacsha512, digest, ISC_SHA512_DIGESTLENGTH); print_digest(s, "hmacsha512", digest, ISC_SHA512_DIGESTLENGTH/4); s = "what do ya want for nothing?"; strcpy((char *)key, "Jefe"); isc_hmacsha512_init(&hmacsha512, key, 4); memmove(buffer, s, strlen(s)); isc_hmacsha512_update(&hmacsha512, buffer, strlen(s)); isc_hmacsha512_sign(&hmacsha512, digest, ISC_SHA512_DIGESTLENGTH); print_digest(s, "hmacsha512", digest, ISC_SHA512_DIGESTLENGTH/4); s = "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335"; memset(key, 0xaa, 20); isc_hmacsha512_init(&hmacsha512, key, 20); memmove(buffer, s, strlen(s)); isc_hmacsha512_update(&hmacsha512, buffer, strlen(s)); isc_hmacsha512_sign(&hmacsha512, digest, ISC_SHA512_DIGESTLENGTH); print_digest(s, "hmacsha512", digest, ISC_SHA512_DIGESTLENGTH/4); return (0); } bind9-9.10.3.dfsg.P4/bin/tests/gxba_test.c0000644000470500017500000000500312664710322017425 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: gxba_test.c,v 1.13 2007/06/19 23:46:59 tbox Exp $ */ /*! \file */ #include #include #include #include #include static void print_he(struct hostent *he, int error, const char *fun, const char *name) { char **c; int i; if (he != NULL) { printf("%s(%s):\n", fun, name); printf("\tname = %s\n", he->h_name); printf("\taddrtype = %d\n", he->h_addrtype); printf("\tlength = %d\n", he->h_length); c = he->h_aliases; i = 1; while (*c != NULL) { printf("\talias[%d] = %s\n", i, *c); i++; c++; } c = he->h_addr_list; i = 1; while (*c != NULL) { char buf[128]; inet_ntop(he->h_addrtype, *c, buf, sizeof(buf)); printf("\taddress[%d] = %s\n", i, buf); c++; i++; } } else { printf("%s(%s): error = %d (%s)\n", fun, name, error, hstrerror(error)); } } int main(int argc, char **argv) { struct hostent *he; int error; struct in_addr in_addr; struct in6_addr in6_addr; void *addr; int af; size_t len; (void)argc; while (argv[1] != NULL) { if (inet_pton(AF_INET, argv[1], &in_addr) == 1) { af = AF_INET; addr = &in_addr; len = sizeof(in_addr); } else if (inet_pton(AF_INET6, argv[1], &in6_addr) == 1) { af = AF_INET6; addr = &in6_addr; len = sizeof(in6_addr); } else { printf("unable to convert \"%s\" to an address\n", argv[1]); argv++; continue; } he = gethostbyaddr(addr, len, af); print_he(he, h_errno, "gethostbyaddr", argv[1]); he = getipnodebyaddr(addr, len, af, &error); print_he(he, error, "getipnodebyaddr", argv[1]); if (he != NULL) freehostent(he); argv++; } return (0); } bind9-9.10.3.dfsg.P4/bin/tests/resolver/0002755000470500017500000000000012672612753017156 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/tests/resolver/Makefile.in0000644000470500017500000000332612664710322021215 0ustar lamontlamont# Copyright (C) 2011, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.3 2011/02/03 12:18:10 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_MAKE_INCLUDES@ CINCLUDES = ${TEST_INCLUDES} ${DNS_INCLUDES} ${ISC_INCLUDES} CDEFINES = CWARNINGS = # Note that we do not want to use libtool for libt_api DNSLIBS = ../../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ ISCLIBS = ../../../lib/isc/libisc.@A@ DNSDEPLIBS = ../../../lib/dns/libdns.@A@ ISCDEPLIBS = ../../../lib/isc/libisc.@A@ DEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS} LIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@ TLIB = ../../../lib/tests/libt_api.@A@ TARGETS = t_resolver@EXEEXT@ SRCS = t_resolver.c @BIND9_MAKE_RULES@ t_resolver@EXEEXT@: t_resolver.@O@ ${DEPLIBS} ${TLIB} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ t_resolver.@O@ ${TLIB} ${LIBS} test: t_resolver@EXEEXT@ -@./t_resolver@EXEEXT@ -c @top_srcdir@/t_config -b @srcdir@ -a testhelp: @./t_resolver@EXEEXT@ -h clean distclean:: rm -f ${TARGETS} bind9-9.10.3.dfsg.P4/bin/tests/resolver/t_resolver.c0000644000470500017500000001524512664710322021503 0ustar lamontlamont/* * Copyright (C) 2011-2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: t_resolver.c,v 1.3 2011/02/03 12:18:11 tbox Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include char *progname; #define CHECK(x) RUNTIME_CHECK(ISC_R_SUCCESS == (x)) isc_mem_t *mctx = NULL; isc_timermgr_t *timer_manager = NULL; isc_socketmgr_t *socket_manager = NULL; isc_taskmgr_t *task_manager = NULL; dns_dispatchmgr_t *dispatch_manager = NULL; dns_view_t *view = NULL; dns_dispatch_t *dispatch_v4 = NULL; static void setup_create_dispatch_v4(void) { isc_sockaddr_t local_address; isc_sockaddr_any(&local_address); CHECK(dns_dispatch_getudp(dispatch_manager, socket_manager, task_manager, &local_address, 4096, 100, 100, 100, 500, 0, 0, &dispatch_v4)); } static void setup(void) { /* 1 */ CHECK(isc_mem_create(0, 0, &mctx)); /* 2 */ CHECK(isc_timermgr_create(mctx, &timer_manager)); /* 3 */ CHECK(isc_taskmgr_create(mctx, 1, 0, &task_manager)); /* 4 */ CHECK(isc_socketmgr_create(mctx, &socket_manager)); /* 5 */ CHECK(dns_dispatchmgr_create(mctx, NULL, &dispatch_manager)); /* 6 */ CHECK(dns_view_create(mctx, dns_rdataclass_in, "testview", &view)); /* 7 */ setup_create_dispatch_v4(); } static void teardown(void) { /* 7 */ dns_dispatch_detach(&dispatch_v4); /* 6 */ dns_view_detach(&view); /* 5 */ dns_dispatchmgr_destroy(&dispatch_manager); /* 4 */ isc_socketmgr_destroy(&socket_manager); /* 3 */ isc_taskmgr_destroy(&task_manager); /* 2 */ isc_timermgr_destroy(&timer_manager); /* 1 */ isc_mem_destroy(&mctx); } static isc_result_t make_resolver(dns_resolver_t **resolverp) { isc_result_t result; result = dns_resolver_create(view, task_manager, 1, 1, socket_manager, timer_manager, 0, /* unsigned int options, */ dispatch_manager, dispatch_v4, NULL, /* dns_dispatch_t *dispatchv6, */ resolverp); return (result); } static void destroy_resolver(dns_resolver_t **resolverp) { dns_resolver_shutdown(*resolverp); dns_resolver_detach(resolverp); } static void test_dns_resolver_create(void) { dns_resolver_t *resolver = NULL; t_assert("test_dns_resolver_create", 1, T_REQUIRED, "%s", "a resolver can be created successfully"); setup(); CHECK(make_resolver(&resolver)); destroy_resolver(&resolver); teardown(); t_result(T_PASS); } static void test_dns_resolver_gettimeout(void) { dns_resolver_t *resolver = NULL; int test_result; unsigned int timeout; t_assert("test_dns_resolver_gettimeout", 1, T_REQUIRED, "%s", "The default timeout is returned from _gettimeout()"); setup(); CHECK(make_resolver(&resolver)); timeout = dns_resolver_gettimeout(resolver); t_info("The default timeout is %d second%s\n", timeout, (timeout == 1 ? "" : "s")); test_result = (timeout > 0) ? T_PASS : T_FAIL; destroy_resolver(&resolver); teardown(); t_result(test_result); } static void test_dns_resolver_settimeout(void) { dns_resolver_t *resolver = NULL; int test_result; unsigned int default_timeout, timeout; t_assert("test_dns_resolver_settimeout", 1, T_REQUIRED, "%s", "_settimeout() can change the timeout to a non-default"); setup(); CHECK(make_resolver(&resolver)); default_timeout = dns_resolver_gettimeout(resolver); t_info("The default timeout is %d second%s\n", default_timeout, (default_timeout == 1 ? "" : "s")); dns_resolver_settimeout(resolver, default_timeout + 1); timeout = dns_resolver_gettimeout(resolver); t_info("The new timeout is %d second%s\n", timeout, (timeout == 1 ? "" : "s")); test_result = (timeout == default_timeout + 1) ? T_PASS : T_FAIL; destroy_resolver(&resolver); teardown(); t_result(test_result); } static void test_dns_resolver_settimeout_to_default(void) { dns_resolver_t *resolver = NULL; int test_result; unsigned int default_timeout, timeout; t_assert("test_dns_resolver_settimeout_to_default", 1, T_REQUIRED, "%s", "_settimeout() can change the timeout back to a default value" " by specifying 0 as the timeout."); setup(); CHECK(make_resolver(&resolver)); default_timeout = dns_resolver_gettimeout(resolver); t_info("The default timeout is %d second%s\n", default_timeout, (default_timeout == 1 ? "" : "s")); dns_resolver_settimeout(resolver, default_timeout - 1); timeout = dns_resolver_gettimeout(resolver); t_info("The new timeout is %d second%s\n", timeout, (timeout == 1 ? "" : "s")); dns_resolver_settimeout(resolver, 0); timeout = dns_resolver_gettimeout(resolver); test_result = (timeout == default_timeout) ? T_PASS : T_FAIL; destroy_resolver(&resolver); teardown(); t_result(test_result); } static void test_dns_resolver_settimeout_over_maximum(void) { dns_resolver_t *resolver = NULL; int test_result; unsigned int timeout; t_assert("test_dns_resolver_settimeout_over_maximum", 1, T_REQUIRED, "%s", "_settimeout() cannot set the value larger than the maximum."); setup(); CHECK(make_resolver(&resolver)); dns_resolver_settimeout(resolver, 4000000); timeout = dns_resolver_gettimeout(resolver); t_info("The new timeout is %d second%s\n", timeout, (timeout == 1 ? "" : "s")); test_result = (timeout < 4000000 && timeout > 0) ? T_PASS : T_FAIL; destroy_resolver(&resolver); teardown(); t_result(test_result); } testspec_t T_testlist[] = { { (PFV) test_dns_resolver_create, "dns_resolver_create" }, { (PFV) test_dns_resolver_settimeout, "dns_resolver_settimeout" }, { (PFV) test_dns_resolver_gettimeout, "dns_resolver_gettimeout" }, { (PFV) test_dns_resolver_settimeout_to_default, "test_dns_resolver_settimeout_to_default" }, { (PFV) test_dns_resolver_settimeout_over_maximum, "test_dns_resolver_settimeout_over_maximum" }, { (PFV) 0, NULL } }; #ifdef WIN32 int main(int argc, char **argv) { t_settests(T_testlist); return (t_main(argc, argv)); } #endif bind9-9.10.3.dfsg.P4/bin/tests/resolver/win32/0002755000470500017500000000000012664730167020121 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/tests/resolver/win32/t_resolver.dsw0000644000470500017500000000104112664710322023005 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "t_resolver"=".\t_resolver.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/bin/tests/resolver/win32/t_resolver.mak.in0000644000470500017500000002674612664710322023410 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on t_resolver.dsp !IF "$(CFG)" == "" CFG=t_resolver - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to t_resolver - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "t_resolver - @PLATFORM@ Release" && "$(CFG)" != "t_resolver - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "t_resolver.mak" CFG="t_resolver - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "t_resolver - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "t_resolver - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF CPP=cl.exe RSC=rc.exe LIBXML=@LIBXML2_LIB@ !IF "$(CFG)" == "t_resolver - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "t_resolver - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release !IF "$(RECURSE)" == "0" ALL : "..\..\..\..\Build\Release\t_resolver.exe" !ELSE ALL : "libtests - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" "libdns - @PLATFORM@ Release" "..\..\..\..\Build\Release\t_resolver.exe" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libdns - @PLATFORM@ ReleaseCLEAN" "libisc - @PLATFORM@ ReleaseCLEAN" "libtests - @PLATFORM@ ReleaseCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\t_resolver.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "..\..\..\..\Build\Release\t_resolver.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../../" @LIBXML2_INC@ @GEOIP_INC@ /I "../../../../lib/isc/win32" /I "../../../../lib/isc/win32/include" /I "../../../../lib/isc/include" /I "../../../../lib/dns/win32/include" /I "../../../../lib/dns/include" /I "../../../../lib/tests/include" /D "WIN32" /D "NDEBUG" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\t_resolver.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\t_resolver.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib kernel32.lib ws2_32.lib ../../../../lib/isc/win32/Release/libisc.lib ../../../../lib/dns/win32/Release/libdns.lib ../../../../lib/tests/win32/Release/libtests.lib $(LIBXML) /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\t_resolver.pdb" @MACHINE@ /out:"../../../../Build/Release/t_resolver.exe" LINK32_OBJS= \ "$(INTDIR)\t_resolver.obj" \ "..\..\..\..\lib\dns\win32\Release\libdns.lib" \ "..\..\..\..\lib\isc\win32\Release\libisc.lib" \ "..\..\..\..\lib\tests\win32\Release\libtests.lib" "..\..\..\..\Build\Release\t_resolver.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "t_resolver - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros !IF "$(RECURSE)" == "0" ALL : "..\..\..\..\Build\Debug\t_resolver.exe" "$(OUTDIR)\t_resolver.bsc" !ELSE ALL : "libtests - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" "libdns - @PLATFORM@ Debug" "..\..\..\..\Build\Debug\t_resolver.exe" "$(OUTDIR)\t_resolver.bsc" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libdns - @PLATFORM@ DebugCLEAN" "libisc - @PLATFORM@ DebugCLEAN" "libtests - @PLATFORM@ DebugCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\t_resolver.obj" -@erase "$(INTDIR)\t_resolver.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\t_resolver.bsc" -@erase "$(OUTDIR)\t_resolver.map" -@erase "$(OUTDIR)\t_resolver.pdb" -@erase "..\..\..\..\Build\Debug\t_resolver.exe" -@erase "..\..\..\..\Build\Debug\t_resolver.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../../" @LIBXML2_INC@ @GEOIP_INC@ /I "../../../../lib/isc/win32" /I "../../../../lib/isc/win32/include" /I "../../../../lib/isc/include" /I "../../../../lib/dns/win32/include" /I "../../../../lib/dns/include" /I "../../../../lib/tests/include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "i386" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\t_resolver.bsc" BSC32_SBRS= \ "$(INTDIR)\t_resolver.sbr" "$(OUTDIR)\t_resolver.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib kernel32.lib ws2_32.lib ../../../../lib/isc/win32/Debug/libisc.lib ../../../../lib/dns/win32/Debug/libdns.lib ../../../../lib/tests/win32/Debug/libtests.lib $(LIBXML) /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\t_resolver.pdb" /map:"$(INTDIR)\t_resolver.map" /debug @MACHINE@ /out:"../../../../Build/Debug/t_resolver.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\t_resolver.obj" \ "..\..\..\..\lib\dns\win32\Debug\libdns.lib" \ "..\..\..\..\lib\isc\win32\Debug\libisc.lib" \ "..\..\..\..\lib\tests\win32\Debug\libtests.lib" "..\..\..\..\Build\Debug\t_resolver.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("t_resolver.dep") !INCLUDE "t_resolver.dep" !ELSE !MESSAGE Warning: cannot find "t_resolver.dep" !ENDIF !ENDIF !IF "$(CFG)" == "t_resolver - @PLATFORM@ Release" || "$(CFG)" == "t_resolver - @PLATFORM@ Debug" SOURCE=..\t_resolver.c !IF "$(CFG)" == "t_resolver - @PLATFORM@ Release" "$(INTDIR)\t_resolver.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "t_resolver - @PLATFORM@ Debug" "$(INTDIR)\t_resolver.obj" "$(INTDIR)\t_resolver.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !IF "$(CFG)" == "t_resolver - @PLATFORM@ Release" "libdns - @PLATFORM@ Release" : cd "..\..\..\..\lib\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" cd "..\..\..\bin\tests\resolver\win32" "libdns - @PLATFORM@ ReleaseCLEAN" : cd "..\..\..\..\lib\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\..\bin\tests\resolver\win32" !ELSEIF "$(CFG)" == "t_resolver - @PLATFORM@ Debug" "libdns - @PLATFORM@ Debug" : cd "..\..\..\..\lib\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" cd "..\..\..\bin\tests\resolver\win32" "libdns - @PLATFORM@ DebugCLEAN" : cd "..\..\..\..\lib\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\..\bin\tests\resolver\win32" !ENDIF !IF "$(CFG)" == "t_resolver - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" : cd "..\..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" cd "..\..\..\bin\tests\resolver\win32" "libisc - @PLATFORM@ ReleaseCLEAN" : cd "..\..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\..\bin\tests\resolver\win32" !ELSEIF "$(CFG)" == "t_resolver - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" : cd "..\..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" cd "..\..\..\bin\tests\resolver\win32" "libisc - @PLATFORM@ DebugCLEAN" : cd "..\..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\..\bin\tests\resolver\win32" !ENDIF !IF "$(CFG)" == "t_resolver - @PLATFORM@ Release" "libtests - @PLATFORM@ Release" : cd "..\..\..\..\lib\tests\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libtests.mak" CFG="libtests - @PLATFORM@ Release" cd "..\..\..\bin\tests\resolver\win32" "libtests - @PLATFORM@ ReleaseCLEAN" : cd "..\..\..\..\lib\tests\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libtests.mak" CFG="libtests - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\..\bin\tests\resolver\win32" !ELSEIF "$(CFG)" == "t_resolver - @PLATFORM@ Debug" "libtests - @PLATFORM@ Debug" : cd "..\..\..\..\lib\tests\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libtests.mak" CFG="libtests - @PLATFORM@ Debug" cd "..\..\..\bin\tests\resolver\win32" "libtests - @PLATFORM@ DebugCLEAN" : cd "..\..\..\..\lib\tests\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libtests.mak" CFG="libtests - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\..\bin\tests\resolver\win32" !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/bin/tests/resolver/win32/t_resolver.vcxproj.in0000644000470500017500000001507412664710322024323 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {66E58849-A764-44E4-8D32-7C1107246A26} Win32Proj t_resolver Application true MultiByte Application false true MultiByte true ..\..\..\..\Build\$(Configuration)\ .\$(Configuration)\ false ..\..\..\..\Build\$(Configuration)\ .\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true .\;..\..\..\..\;@LIBXML2_INC@@GEOIP_INC@..\..\..\..\lib\isc\win32;..\..\..\..\lib\isc\win32\include;..\..\..\..\lib\isc\include;..\..\..\..\lib\dns\include;..\..\..\..\lib\tests\include;%(AdditionalIncludeDirectories) Console true ..\..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) ..\..\..\..\lib\isc\win32\$(Configuration);..\..\..\..\lib\dns\win32\$(Configuration);..\..\..\..\lib\tests\win32\$(Configuration);%(AdditionalLibraryDirectories) @LIBXML2_LIB@libisc.lib;libdns.lib;libtests.lib;ws2_32.lib;%(AdditionalDependencies) Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb .\;..\..\..\..\;@LIBXML2_INC@@GEOIP_INC@..\..\..\..\lib\isc\win32;..\..\..\..\lib\isc\win32\include;..\..\..\..\lib\isc\include;..\..\..\..\lib\dns\include;..\..\..\..\lib\tests\include;%(AdditionalIncludeDirectories) Console false true true ..\..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Default ..\..\..\..\lib\isc\win32\$(Configuration);..\..\..\..\lib\dns\win32\$(Configuration);..\..\..\..\lib\tests\win32\$(Configuration);%(AdditionalLibraryDirectories) @LIBXML2_LIB@libisc.lib;libdns.lib;libtests.lib;ws2_32.lib;%(AdditionalDependencies) bind9-9.10.3.dfsg.P4/bin/tests/resolver/win32/t_resolver.dsp.in0000644000470500017500000001116712664710322023415 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="t_resolver" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 CFG=t_resolver - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "t_resolver.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "t_resolver.mak" CFG="t_resolver - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "t_resolver - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "t_resolver - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "t_resolver - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../../" @LIBXML2_INC@ @GEOIP_INC@ /I "../../../../lib/isc/win32" /I "../../../../lib/isc/win32/include" /I "../../../../lib/isc/include" /I "../../../../lib/dns/win32/include" /I "../../../../lib/dns/include" /I "../../../../lib/tests/include" /D "WIN32" /D "NDEBUG" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @MACHINE@ # ADD LINK32 @LIBXML2_LIB@ user32.lib advapi32.lib kernel32.lib ws2_32.lib ../../../../lib/isc/win32/Release/libisc.lib ../../../../lib/dns/win32/Release/libdns.lib ../../../../lib/tests/win32/Release/libtests.lib /nologo /subsystem:console @MACHINE@ /out:"../../../../Build/Release/t_resolver.exe" !ELSEIF "$(CFG)" == "t_resolver - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../../" @LIBXML2_INC@ @GEOIP_INC@ /I "../../../../lib/isc/win32" /I "../../../../lib/isc/win32/include" /I "../../../../lib/isc/include" /I "../../../../lib/dns/win32/include" /I "../../../../lib/dns/include" /I "../../../../lib/tests/include" /I "../../../../lib/bind9/include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "i386" /FR /FD /GZ /c # SUBTRACT CPP /X @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept # ADD LINK32 @LIBXML2_LIB@ user32.lib advapi32.lib kernel32.lib ws2_32.lib ../../../../lib/isc/win32/Debug/libisc.lib ../../../../lib/dns/win32/Debug/libdns.lib ../../../../lib/tests/win32/Debug/libtests.lib /nologo /subsystem:console /map /debug @MACHINE@ /out:"../../../../Build/Debug/t_resolver.exe" /pdbtype:sept !ENDIF # Begin Target # Name "t_resolver - @PLATFORM@ Release" # Name "t_resolver - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\t_resolver.c # End Source File # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/bin/tests/resolver/win32/t_resolver.vcxproj.filters.in0000644000470500017500000000170012664710322025761 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files bind9-9.10.3.dfsg.P4/bin/tests/resolver/win32/t_resolver.vcxproj.user0000644000470500017500000000021712664710322024664 0ustar lamontlamont bind9-9.10.3.dfsg.P4/bin/tests/sock_test.c0000644000470500017500000002420312664710322017446 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2008, 2012-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: sock_test.c,v 1.55 2008/07/23 23:27:54 marka Exp $ */ #include #include #include #include #include #include #include #include #include #include isc_mem_t *mctx; isc_taskmgr_t *manager; static void my_shutdown(isc_task_t *task, isc_event_t *event) { char *name = event->ev_arg; printf("shutdown %s (%p)\n", name, task); fflush(stdout); isc_event_free(&event); } static void my_send(isc_task_t *task, isc_event_t *event) { isc_socket_t *sock; isc_socketevent_t *dev; sock = event->ev_sender; dev = (isc_socketevent_t *)event; printf("my_send: %s task %p\n\t(sock %p, base %p, length %d, n %d, " "result %d)\n", (char *)(event->ev_arg), task, sock, dev->region.base, dev->region.length, dev->n, dev->result); if (dev->result != ISC_R_SUCCESS) { isc_socket_detach(&sock); isc_task_shutdown(task); } if (dev->region.base != NULL) isc_mem_put(mctx, dev->region.base, dev->region.length); isc_event_free(&event); } static void my_recv(isc_task_t *task, isc_event_t *event) { isc_socket_t *sock; isc_socketevent_t *dev; isc_region_t region; char buf[1024]; char host[256]; sock = event->ev_sender; dev = (isc_socketevent_t *)event; printf("Socket %s (sock %p, base %p, length %d, n %d, result %d)\n", (char *)(event->ev_arg), sock, dev->region.base, dev->region.length, dev->n, dev->result); if (dev->address.type.sa.sa_family == AF_INET6) { inet_ntop(AF_INET6, &dev->address.type.sin6.sin6_addr, host, sizeof(host)); printf("\tFrom: %s port %d\n", host, ntohs(dev->address.type.sin6.sin6_port)); } else { inet_ntop(AF_INET, &dev->address.type.sin.sin_addr, host, sizeof(host)); printf("\tFrom: %s port %d\n", host, ntohs(dev->address.type.sin.sin_port)); } if (dev->result != ISC_R_SUCCESS) { isc_socket_detach(&sock); if (dev->region.base != NULL) isc_mem_put(mctx, dev->region.base, dev->region.length); isc_event_free(&event); isc_task_shutdown(task); return; } /* * Echo the data back. */ if (strcmp(event->ev_arg, "so2") != 0) { region = dev->region; sprintf(buf, "\r\nReceived: %.*s\r\n\r\n", (int)dev->n, (char *)region.base); region.base = isc_mem_get(mctx, strlen(buf) + 1); if (region.base != NULL) { region.length = strlen(buf) + 1; strcpy((char *)region.base, buf); /* strcpy is safe */ } else region.length = 0; isc_socket_send(sock, ®ion, task, my_send, event->ev_arg); } else { region = dev->region; printf("\r\nReceived: %.*s\r\n\r\n", (int)dev->n, (char *)region.base); } isc_socket_recv(sock, &dev->region, 1, task, my_recv, event->ev_arg); isc_event_free(&event); } static void my_http_get(isc_task_t *task, isc_event_t *event) { isc_socket_t *sock; isc_socketevent_t *dev; sock = event->ev_sender; dev = (isc_socketevent_t *)event; printf("my_http_get: %s task %p\n\t(sock %p, base %p, length %d, " "n %d, result %d)\n", (char *)(event->ev_arg), task, sock, dev->region.base, dev->region.length, dev->n, dev->result); if (dev->result != ISC_R_SUCCESS) { isc_socket_detach(&sock); isc_task_shutdown(task); if (dev->region.base != NULL) isc_mem_put(mctx, dev->region.base, dev->region.length); isc_event_free(&event); return; } isc_socket_recv(sock, &dev->region, 1, task, my_recv, event->ev_arg); isc_event_free(&event); } static void my_connect(isc_task_t *task, isc_event_t *event) { isc_socket_t *sock; isc_socket_connev_t *dev; isc_region_t region; char buf[1024]; sock = event->ev_sender; dev = (isc_socket_connev_t *)event; printf("%s: Connection result: %d\n", (char *)(event->ev_arg), dev->result); if (dev->result != ISC_R_SUCCESS) { isc_socket_detach(&sock); isc_event_free(&event); isc_task_shutdown(task); return; } /* * Send a GET string, and set up to receive (and just display) * the result. */ strcpy(buf, "GET / HTTP/1.1\r\nHost: www.flame.org\r\n" "Connection: Close\r\n\r\n"); region.base = isc_mem_get(mctx, strlen(buf) + 1); if (region.base != NULL) { region.length = strlen(buf) + 1; strcpy((char *)region.base, buf); /* This strcpy is safe. */ } else region.length = 0; isc_socket_send(sock, ®ion, task, my_http_get, event->ev_arg); isc_event_free(&event); } static void my_listen(isc_task_t *task, isc_event_t *event) { char *name = event->ev_arg; isc_socket_newconnev_t *dev; isc_region_t region; isc_socket_t *oldsock; isc_task_t *newtask; dev = (isc_socket_newconnev_t *)event; printf("newcon %s (task %p, oldsock %p, newsock %p, result %d)\n", name, task, event->ev_sender, dev->newsocket, dev->result); fflush(stdout); if (dev->result == ISC_R_SUCCESS) { /* * Queue another listen on this socket. */ RUNTIME_CHECK(isc_socket_accept(event->ev_sender, task, my_listen, event->ev_arg) == ISC_R_SUCCESS); region.base = isc_mem_get(mctx, 20); region.length = 20; /* * Create a new task for this socket, and queue up a * recv on it. */ newtask = NULL; RUNTIME_CHECK(isc_task_create(manager, 0, &newtask) == ISC_R_SUCCESS); isc_socket_recv(dev->newsocket, ®ion, 1, newtask, my_recv, event->ev_arg); isc_task_detach(&newtask); } else { printf("detaching from socket %p\n", event->ev_sender); oldsock = event->ev_sender; isc_socket_detach(&oldsock); isc_event_free(&event); isc_task_shutdown(task); return; } isc_event_free(&event); } static void timeout(isc_task_t *task, isc_event_t *event) { isc_socket_t *sock = event->ev_arg; printf("Timeout, canceling IO on socket %p (task %p)\n", sock, task); isc_socket_cancel(sock, NULL, ISC_SOCKCANCEL_ALL); isc_timer_detach((isc_timer_t **)&event->ev_sender); isc_event_free(&event); } static char one[] = "1"; static char two[] = "2"; static char xso1[] = "so1"; static char xso2[] = "so2"; int main(int argc, char *argv[]) { isc_task_t *t1, *t2; isc_timermgr_t *timgr; isc_time_t expires; isc_interval_t interval; isc_timer_t *ti1; unsigned int workers; isc_socketmgr_t *socketmgr; isc_socket_t *so1, *so2; isc_sockaddr_t sockaddr; struct in_addr ina; struct in6_addr in6a; isc_result_t result; int pf; if (argc > 1) { workers = atoi(argv[1]); if (workers < 1) workers = 1; if (workers > 8192) workers = 8192; } else workers = 2; printf("%d workers\n", workers); if (isc_net_probeipv6() == ISC_R_SUCCESS) pf = PF_INET6; else pf = PF_INET; /* * EVERYTHING needs a memory context. */ mctx = NULL; RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); /* * The task manager is independent (other than memory context) */ manager = NULL; RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, &manager) == ISC_R_SUCCESS); /* * Timer manager depends only on the memory context as well. */ timgr = NULL; RUNTIME_CHECK(isc_timermgr_create(mctx, &timgr) == ISC_R_SUCCESS); t1 = NULL; RUNTIME_CHECK(isc_task_create(manager, 0, &t1) == ISC_R_SUCCESS); t2 = NULL; RUNTIME_CHECK(isc_task_create(manager, 0, &t2) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_task_onshutdown(t1, my_shutdown, one) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_task_onshutdown(t2, my_shutdown, two) == ISC_R_SUCCESS); printf("task 1 = %p\n", t1); printf("task 2 = %p\n", t2); socketmgr = NULL; RUNTIME_CHECK(isc_socketmgr_create(mctx, &socketmgr) == ISC_R_SUCCESS); /* * Open up a listener socket. */ so1 = NULL; if (pf == PF_INET6) { in6a = in6addr_any; isc_sockaddr_fromin6(&sockaddr, &in6a, 5544); } else { ina.s_addr = INADDR_ANY; isc_sockaddr_fromin(&sockaddr, &ina, 5544); } RUNTIME_CHECK(isc_socket_create(socketmgr, pf, isc_sockettype_tcp, &so1) == ISC_R_SUCCESS); result = isc_socket_bind(so1, &sockaddr, ISC_SOCKET_REUSEADDRESS); RUNTIME_CHECK(result == ISC_R_SUCCESS); RUNTIME_CHECK(isc_socket_listen(so1, 0) == ISC_R_SUCCESS); /* * Queue up the first accept event. */ RUNTIME_CHECK(isc_socket_accept(so1, t1, my_listen, xso1) == ISC_R_SUCCESS); isc_time_settoepoch(&expires); isc_interval_set(&interval, 10, 0); ti1 = NULL; RUNTIME_CHECK(isc_timer_create(timgr, isc_timertype_once, &expires, &interval, t1, timeout, so1, &ti1) == ISC_R_SUCCESS); /* * Open up a socket that will connect to www.flame.org, port 80. * Why not. :) */ so2 = NULL; ina.s_addr = inet_addr("204.152.184.97"); if (0 && pf == PF_INET6) isc_sockaddr_v6fromin(&sockaddr, &ina, 80); else isc_sockaddr_fromin(&sockaddr, &ina, 80); RUNTIME_CHECK(isc_socket_create(socketmgr, isc_sockaddr_pf(&sockaddr), isc_sockettype_tcp, &so2) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_socket_connect(so2, &sockaddr, t2, my_connect, xso2) == ISC_R_SUCCESS); /* * Detaching these is safe, since the socket will attach to the * task for any outstanding requests. */ isc_task_detach(&t1); isc_task_detach(&t2); /* * Wait a short while. */ #ifndef WIN32 sleep(10); #else Sleep(10000); #endif fprintf(stderr, "Destroying socket manager\n"); isc_socketmgr_destroy(&socketmgr); fprintf(stderr, "Destroying timer manager\n"); isc_timermgr_destroy(&timgr); fprintf(stderr, "Destroying task manager\n"); isc_taskmgr_destroy(&manager); isc_mem_stats(mctx, stdout); isc_mem_destroy(&mctx); return (0); } bind9-9.10.3.dfsg.P4/bin/tests/entropy2_test.c0000644000470500017500000001000712664710322020266 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: entropy2_test.c,v 1.16 2007/06/19 23:46:59 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include #include #include #include #include static void hex_dump(const char *msg, void *data, unsigned int length) { unsigned int len; unsigned char *base; isc_boolean_t first = ISC_TRUE; base = data; printf("DUMP of %d bytes: %s\n\t", length, msg); for (len = 0; len < length; len++) { if (len % 16 == 0 && !first) printf("\n\t"); printf("%02x ", base[len]); first = ISC_FALSE; } printf("\n"); } static void CHECK(const char *msg, isc_result_t result) { if (result != ISC_R_SUCCESS) { printf("FAILURE: %s: %s\n", msg, isc_result_totext(result)); exit(1); } } static isc_result_t start(isc_entropysource_t *source, void *arg, isc_boolean_t blocking) { isc_keyboard_t *kbd = (isc_keyboard_t *)arg; UNUSED(source); if (blocking) printf("start called, blocking mode.\n"); else printf("start called, non-blocking mode.\n"); return (isc_keyboard_open(kbd)); } static void stop(isc_entropysource_t *source, void *arg) { isc_keyboard_t *kbd = (isc_keyboard_t *)arg; UNUSED(source); printf("ENOUGH! Stop typing, please.\r\n"); (void)isc_keyboard_close(kbd, 3); printf("stop called\n"); } static isc_result_t get(isc_entropysource_t *source, void *arg, isc_boolean_t blocking) { isc_keyboard_t *kbd = (isc_keyboard_t *)arg; isc_result_t result; isc_time_t t; isc_uint32_t sample; isc_uint32_t extra; unsigned char c; if (!blocking) return (ISC_R_NOENTROPY); result = isc_keyboard_getchar(kbd, &c); if (result != ISC_R_SUCCESS) return (result); TIME_NOW(&t); sample = isc_time_nanoseconds(&t); extra = c; result = isc_entropy_addcallbacksample(source, sample, extra); if (result != ISC_R_SUCCESS) { printf("\r\n"); return (result); } printf("."); fflush(stdout); return (result); } int main(int argc, char **argv) { isc_mem_t *mctx; unsigned char buffer[512]; isc_entropy_t *ent; isc_entropysource_t *source; unsigned int returned; unsigned int flags; isc_result_t result; isc_keyboard_t kbd; UNUSED(argc); UNUSED(argv); mctx = NULL; CHECK("isc_mem_create()", isc_mem_create(0, 0, &mctx)); ent = NULL; CHECK("isc_entropy_create()", isc_entropy_create(mctx, &ent)); isc_entropy_stats(ent, stderr); source = NULL; result = isc_entropy_createcallbacksource(ent, start, get, stop, &kbd, &source); CHECK("isc_entropy_createcallbacksource()", result); fprintf(stderr, "Reading 32 bytes of GOOD random data only, partial OK\n"); flags = 0; flags |= ISC_ENTROPY_GOODONLY; flags |= ISC_ENTROPY_PARTIAL; flags |= ISC_ENTROPY_BLOCKING; returned = 0; result = isc_entropy_getdata(ent, buffer, 32, &returned, flags); if (result == ISC_R_NOENTROPY) { fprintf(stderr, "No entropy.\r\n"); } isc_entropy_stopcallbacksources(ent); hex_dump("good data only:", buffer, returned); isc_entropy_stats(ent, stderr); isc_entropy_destroysource(&source); isc_entropy_detach(&ent); isc_mem_stats(mctx, stderr); isc_mem_destroy(&mctx); return (0); } bind9-9.10.3.dfsg.P4/bin/tests/backtrace_test.c0000644000470500017500000000436712664710322020437 0ustar lamontlamont/* * Copyright (C) 2009, 2013, 2015 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: backtrace_test.c,v 1.4 2009/09/02 23:48:01 tbox Exp $ */ #include #include #include #include #include #include const char *expected_symbols[] = { "func3", "func2", "func1", "main" }; static int func3() { void *tracebuf[16]; int i, nframes; int error = 0; const char *fname; isc_result_t result; unsigned long offset; result = isc_backtrace_gettrace(tracebuf, 16, &nframes); if (result != ISC_R_SUCCESS) { printf("isc_backtrace_gettrace failed: %s\n", isc_result_totext(result)); return (1); } if (nframes < 4) error++; for (i = 0; i < 4 && i < nframes; i++) { fname = NULL; result = isc_backtrace_getsymbol(tracebuf[i], &fname, &offset); if (result != ISC_R_SUCCESS) { error++; continue; } if (strcmp(fname, expected_symbols[i]) != 0) error++; } if (error) { printf("Unexpected result:\n"); printf(" # of frames: %d (expected: at least 4)\n", nframes); printf(" symbols:\n"); for (i = 0; i < nframes; i++) { fname = NULL; result = isc_backtrace_getsymbol(tracebuf[i], &fname, &offset); if (result == ISC_R_SUCCESS) printf(" [%d] %s\n", i, fname); else { printf(" [%d] %p getsymbol failed: %s\n", i, tracebuf[i], isc_result_totext(result)); } } } return (error); } static int func2() { return (func3()); } static int func1() { return (func2()); } int main() { return (func1()); } bind9-9.10.3.dfsg.P4/bin/tests/sockaddr/0002755000470500017500000000000012672612753017107 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/tests/sockaddr/Makefile.in0000644000470500017500000000323312664710322021143 0ustar lamontlamont# Copyright (C) 2004, 2007, 2009, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1999-2002 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.25 2009/12/05 23:31:40 each Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_MAKE_INCLUDES@ CINCLUDES = ${TEST_INCLUDES} ${ISC_INCLUDES} CDEFINES = CWARNINGS = ISCLIBS = ../../../lib/isc/libisc.@A@ @ISC_OPENSSL_LIBS@ TAPIDEPLIBS = ../../../lib/tests/libt_api.@A@ ISCDEPLIBS = ../../../lib/isc/libisc.@A@ TAPILIBS = ../../../lib/tests/libt_api.@A@ DEPLIBS = ${TAPIDEPLIBS} ${ISCDEPLIBS} LIBS = ${TAPILIBS} ${ISCLIBS} ${ISCLIBS} @LIBS@ TARGETS = t_sockaddr@EXEEXT@ SRCS = t_sockaddr.c @BIND9_MAKE_RULES@ t_sockaddr@EXEEXT@: t_sockaddr.@O@ ${DEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ t_sockaddr.@O@ ${LIBS} test: t_sockaddr@EXEEXT@ -@./t_sockaddr@EXEEXT@ -b @srcdir@ -a testhelp: @./t_sockaddr@EXEEXT@ -h clean distclean:: rm -f ${TARGETS} bind9-9.10.3.dfsg.P4/bin/tests/sockaddr/t_sockaddr.c0000644000470500017500000000767712664710322021377 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: t_sockaddr.c,v 1.14 2007/06/19 23:47:00 tbox Exp $ */ #include #include #include #include #include static int test_isc_sockaddr_eqaddrprefix(void) { struct in_addr ina_a; struct in_addr ina_b; struct in_addr ina_c; isc_sockaddr_t isa_a; isc_sockaddr_t isa_b; isc_sockaddr_t isa_c; if (inet_pton(AF_INET, "194.100.32.87", &ina_a) < 0) return T_FAIL; if (inet_pton(AF_INET, "194.100.32.80", &ina_b) < 0) return T_FAIL; if (inet_pton(AF_INET, "194.101.32.87", &ina_c) < 0) return T_FAIL; isc_sockaddr_fromin(&isa_a, &ina_a, 0); isc_sockaddr_fromin(&isa_b, &ina_b, 42); isc_sockaddr_fromin(&isa_c, &ina_c, 0); if (isc_sockaddr_eqaddrprefix(&isa_a, &isa_b, 0) != ISC_TRUE) return T_FAIL; if (isc_sockaddr_eqaddrprefix(&isa_a, &isa_b, 29) != ISC_TRUE) return T_FAIL; if (isc_sockaddr_eqaddrprefix(&isa_a, &isa_b, 30) != ISC_FALSE) return T_FAIL; if (isc_sockaddr_eqaddrprefix(&isa_a, &isa_b, 32) != ISC_FALSE) return T_FAIL; if (isc_sockaddr_eqaddrprefix(&isa_a, &isa_c, 8) != ISC_TRUE) return T_FAIL; if (isc_sockaddr_eqaddrprefix(&isa_a, &isa_c, 16) != ISC_FALSE) return T_FAIL; return T_PASS; } static void t1(void) { int result; t_assert("isc_sockaddr_eqaddrprefix", 1, T_REQUIRED, "isc_sockaddr_eqaddrprefix() returns ISC_TRUE when " "prefixes of a and b are equal, and ISC_FALSE when " "they are not equal"); result = test_isc_sockaddr_eqaddrprefix(); t_result(result); } static int test_isc_netaddr_masktoprefixlen(void) { struct in_addr na_a; struct in_addr na_b; struct in_addr na_c; struct in_addr na_d; isc_netaddr_t ina_a; isc_netaddr_t ina_b; isc_netaddr_t ina_c; isc_netaddr_t ina_d; unsigned int plen; if (inet_pton(AF_INET, "0.0.0.0", &na_a) < 0) return T_FAIL; if (inet_pton(AF_INET, "255.255.255.254", &na_b) < 0) return T_FAIL; if (inet_pton(AF_INET, "255.255.255.255", &na_c) < 0) return T_FAIL; if (inet_pton(AF_INET, "255.255.255.0", &na_d) < 0) return T_FAIL; isc_netaddr_fromin(&ina_a, &na_a); isc_netaddr_fromin(&ina_b, &na_b); isc_netaddr_fromin(&ina_c, &na_c); isc_netaddr_fromin(&ina_d, &na_d); if (isc_netaddr_masktoprefixlen(&ina_a, &plen) != ISC_R_SUCCESS) return T_FAIL; if (plen != 0) return T_FAIL; if (isc_netaddr_masktoprefixlen(&ina_b, &plen) != ISC_R_SUCCESS) return T_FAIL; if (plen != 31) return T_FAIL; if (isc_netaddr_masktoprefixlen(&ina_c, &plen) != ISC_R_SUCCESS) return T_FAIL; if (plen != 32) return T_FAIL; if (isc_netaddr_masktoprefixlen(&ina_d, &plen) != ISC_R_SUCCESS) return T_FAIL; if (plen != 24) return T_FAIL; return T_PASS; } static void t2(void) { int result; t_assert("isc_netaddr_masktoprefixlen", 1, T_REQUIRED, "isc_netaddr_masktoprefixlen() calculates " "correct prefix lengths "); result = test_isc_netaddr_masktoprefixlen(); t_result(result); } testspec_t T_testlist[] = { { (PFV) t1, "isc_sockaddr_eqaddrprefix" }, { (PFV) t2, "isc_netaddr_masktoprefixlen" }, { (PFV) 0, NULL } }; #ifdef WIN32 int main(int argc, char **argv) { t_settests(T_testlist); return (t_main(argc, argv)); } #endif bind9-9.10.3.dfsg.P4/bin/tests/sockaddr/win32/0002755000470500017500000000000012664730167020052 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/tests/sockaddr/win32/t_sockaddr.dsp.in0000644000470500017500000001056712664710322023302 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="t_sockaddr" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 CFG=t_sockaddr - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "t_sockaddr.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "t_sockaddr.mak" CFG="t_sockaddr - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "t_sockaddr - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "t_sockaddr - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "t_sockaddr - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../../" @LIBXML2_INC@ /I "../../../../lib/isc/win32" /I "../../../../lib/isc/win32/include" /I "../../../../lib/isc/include" /I "../../../../lib/tests/include" /D "WIN32" /D "NDEBUG" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @MACHINE@ # ADD LINK32 @LIBXML2_LIB@ user32.lib advapi32.lib kernel32.lib ws2_32.lib ../../../../lib/isc/win32/Release/libisc.lib ../../../../lib/tests/win32/Release/libtests.lib /nologo /subsystem:console @MACHINE@ /out:"../../../../Build/Release/t_sockaddr.exe" !ELSEIF "$(CFG)" == "t_sockaddr - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../../" @LIBXML2_INC@ /I "../../../../lib/isc/win32" /I "../../../../lib/isc/win32/include" /I "../../../../lib/isc/include" /I "../../../../lib/tests/include" /I "../../../../lib/bind9/include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "i386" /FR /FD /GZ /c # SUBTRACT CPP /X @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept # ADD LINK32 @LIBXML2_LIB@ user32.lib advapi32.lib kernel32.lib ws2_32.lib ../../../../lib/isc/win32/Debug/libisc.lib ../../../../lib/tests/win32/Debug/libtests.lib /nologo /subsystem:console /map /debug @MACHINE@ /out:"../../../../Build/Debug/t_sockaddr.exe" /pdbtype:sept !ENDIF # Begin Target # Name "t_sockaddr - @PLATFORM@ Release" # Name "t_sockaddr - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\t_sockaddr.c # End Source File # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/bin/tests/sockaddr/win32/t_sockaddr.vcxproj.filters.in0000644000470500017500000000170012664710322025643 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files bind9-9.10.3.dfsg.P4/bin/tests/sockaddr/win32/t_sockaddr.dsw0000644000470500017500000000104112664710322022667 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "t_sockaddr"=".\t_sockaddr.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/bin/tests/sockaddr/win32/t_sockaddr.mak.in0000644000470500017500000002420112664710322023252 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on t_sockaddr.dsp !IF "$(CFG)" == "" CFG=t_sockaddr - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to t_sockaddr - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "t_sockaddr - @PLATFORM@ Release" && "$(CFG)" != "t_sockaddr - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "t_sockaddr.mak" CFG="t_sockaddr - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "t_sockaddr - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "t_sockaddr - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF CPP=cl.exe RSC=rc.exe LIBXML=@LIBXML2_LIB@ !IF "$(CFG)" == "t_sockaddr - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "t_sockaddr - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release !IF "$(RECURSE)" == "0" ALL : "..\..\..\..\Build\Release\t_sockaddr.exe" !ELSE ALL : "libtests - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" "..\..\..\..\Build\Release\t_sockaddr.exe" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libisc - @PLATFORM@ ReleaseCLEAN" "libtests - @PLATFORM@ ReleaseCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\t_sockaddr.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "..\..\..\..\Build\Release\t_sockaddr.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../../" @LIBXML2_INC@ /I "../../../../lib/isc/win32" /I "../../../../lib/isc/win32/include" /I "../../../../lib/isc/include" /I "../../../../lib/tests/include" /D "WIN32" /D "NDEBUG" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\t_sockaddr.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\t_sockaddr.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib kernel32.lib ws2_32.lib ../../../../lib/isc/win32/Release/libisc.lib ../../../../lib/tests/win32/Release/libtests.lib $(LIBXML) /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\t_sockaddr.pdb" @MACHINE@ /out:"../../../../Build/Release/t_sockaddr.exe" LINK32_OBJS= \ "$(INTDIR)\t_sockaddr.obj" \ "..\..\..\..\lib\isc\win32\Release\libisc.lib" \ "..\..\..\..\lib\tests\win32\Release\libtests.lib" "..\..\..\..\Build\Release\t_sockaddr.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "t_sockaddr - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros !IF "$(RECURSE)" == "0" ALL : "..\..\..\..\Build\Debug\t_sockaddr.exe" "$(OUTDIR)\t_sockaddr.bsc" !ELSE ALL : "libtests - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" "..\..\..\..\Build\Debug\t_sockaddr.exe" "$(OUTDIR)\t_sockaddr.bsc" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libisc - @PLATFORM@ DebugCLEAN" "libtests - @PLATFORM@ DebugCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\t_sockaddr.obj" -@erase "$(INTDIR)\t_sockaddr.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\t_sockaddr.bsc" -@erase "$(OUTDIR)\t_sockaddr.map" -@erase "$(OUTDIR)\t_sockaddr.pdb" -@erase "..\..\..\..\Build\Debug\t_sockaddr.exe" -@erase "..\..\..\..\Build\Debug\t_sockaddr.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../../" @LIBXML2_INC@ /I "../../../../lib/isc/win32" /I "../../../../lib/isc/win32/include" /I "../../../../lib/isc/include" /I "../../../../lib/tests/include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "i386" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\t_sockaddr.bsc" BSC32_SBRS= \ "$(INTDIR)\t_sockaddr.sbr" "$(OUTDIR)\t_sockaddr.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib kernel32.lib ws2_32.lib ../../../../lib/isc/win32/Debug/libisc.lib ../../../../lib/tests/win32/Debug/libtests.lib $(LIBXML) /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\t_sockaddr.pdb" /map:"$(INTDIR)\t_sockaddr.map" /debug @MACHINE@ /out:"../../../../Build/Debug/t_sockaddr.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\t_sockaddr.obj" \ "..\..\..\..\lib\isc\win32\Debug\libisc.lib" \ "..\..\..\..\lib\tests\win32\Debug\libtests.lib" "..\..\..\..\Build\Debug\t_sockaddr.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("t_sockaddr.dep") !INCLUDE "t_sockaddr.dep" !ELSE !MESSAGE Warning: cannot find "t_sockaddr.dep" !ENDIF !ENDIF !IF "$(CFG)" == "t_sockaddr - @PLATFORM@ Release" || "$(CFG)" == "t_sockaddr - @PLATFORM@ Debug" SOURCE=..\t_sockaddr.c !IF "$(CFG)" == "t_sockaddr - @PLATFORM@ Release" "$(INTDIR)\t_sockaddr.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "t_sockaddr - @PLATFORM@ Debug" "$(INTDIR)\t_sockaddr.obj" "$(INTDIR)\t_sockaddr.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !IF "$(CFG)" == "t_sockaddr - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" : cd "..\..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" cd "..\..\..\bin\tests\sockaddr\win32" "libisc - @PLATFORM@ ReleaseCLEAN" : cd "..\..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\..\bin\tests\sockaddr\win32" !ELSEIF "$(CFG)" == "t_sockaddr - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" : cd "..\..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" cd "..\..\..\bin\tests\sockaddr\win32" "libisc - @PLATFORM@ DebugCLEAN" : cd "..\..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\..\bin\tests\sockaddr\win32" !ENDIF !IF "$(CFG)" == "t_sockaddr - @PLATFORM@ Release" "libtests - @PLATFORM@ Release" : cd "..\..\..\..\lib\tests\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libtests.mak" CFG="libtests - @PLATFORM@ Release" cd "..\..\..\bin\tests\sockaddr\win32" "libtests - @PLATFORM@ ReleaseCLEAN" : cd "..\..\..\..\lib\tests\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libtests.mak" CFG="libtests - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\..\bin\tests\sockaddr\win32" !ELSEIF "$(CFG)" == "t_sockaddr - @PLATFORM@ Debug" "libtests - @PLATFORM@ Debug" : cd "..\..\..\..\lib\tests\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libtests.mak" CFG="libtests - @PLATFORM@ Debug" cd "..\..\..\bin\tests\sockaddr\win32" "libtests - @PLATFORM@ DebugCLEAN" : cd "..\..\..\..\lib\tests\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libtests.mak" CFG="libtests - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\..\bin\tests\sockaddr\win32" !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/bin/tests/sockaddr/win32/t_sockaddr.vcxproj.user0000644000470500017500000000021712664710322024546 0ustar lamontlamont bind9-9.10.3.dfsg.P4/bin/tests/sockaddr/win32/t_sockaddr.vcxproj.in0000644000470500017500000001460212664710322024201 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {351D3872-707B-46AD-8BC0-5A668B8C745B} Win32Proj t_sockaddr Application true MultiByte Application false true MultiByte true ..\..\..\..\Build\$(Configuration)\ .\$(Configuration)\ false ..\..\..\..\Build\$(Configuration)\ .\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true .\;..\..\..\..\;@LIBXML2_INC@..\..\..\..\lib\isc\win32;..\..\..\..\lib\isc\win32\include;..\..\..\..\lib\isc\include;..\..\..\..\lib\tests\include;%(AdditionalIncludeDirectories) Console true ..\..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) ..\..\..\..\lib\isc\win32\$(Configuration);..\..\..\..\lib\tests\win32\$(Configuration);%(AdditionalLibraryDirectories) @LIBXML2_LIB@libisc.lib;libtests.lib;ws2_32.lib;%(AdditionalDependencies) Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb .\;..\..\..\..\;@LIBXML2_INC@..\..\..\..\lib\isc\win32;..\..\..\..\lib\isc\win32\include;..\..\..\..\lib\isc\include;..\..\..\..\lib\tests\include;%(AdditionalIncludeDirectories) Console false true true ..\..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Default ..\..\..\..\lib\isc\win32\$(Configuration);..\..\..\..\lib\tests\win32\$(Configuration);%(AdditionalLibraryDirectories) @LIBXML2_LIB@libisc.lib;libtests.lib;ws2_32.lib;%(AdditionalDependencies) bind9-9.10.3.dfsg.P4/bin/tests/bigtest/0002755000470500017500000000000012672612753016756 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/tests/bigtest/rndc.key0000644000470500017500000000013412664710322020402 0ustar lamontlamontkey "rndc-key" { algorithm hmac-md5; secret "xxxxxxxxxxxxxxxxxxxxHg=="; }; bind9-9.10.3.dfsg.P4/bin/tests/bigtest/zones0000644000470500017500000000136112664710322020026 0ustar lamontlamontnoedns-1.tld 1 ns%u.%s P . x x -T noedns dropedns-1.tld 1 ns%u.%s P . x x -T dropedns maxudp512-1.tld 1 ns%u.%s S . x x -T maxudp=512 maxudp1460-1.tld 1 ns%u.%s S . x x -T maxudp=1460 plain-1.tld 1 ns%u.%s S . x x noedns-3.tld 3 ns%u.%s P . 2 x -T noedns dropedns-3.tld 3 ns%u.%s P . 2 x -T dropedns maxudp512-3.tld 3 ns%u.%s S . x x -T maxudp=512 maxudp1460-3.tld 3 ns%u.%s S . x x -T maxudp=1460 plain-3.tld 3 ns%u.%s S . x 3 noedns-5.tld 5 ns%u.%s P . 3 x -T noedns dropedns-5.tld 5 ns%u.%s P . x x -T dropedns maxudp512-5.tld 5 ns%u.%s S . x x -T maxudp=512 maxudp1460-5.tld 5 ns%u.%s S . x x -T maxudp=1460 400ms-1.tld 5 ns%u.%s S 400/400/400/400/400 2 x plain-5.tld 5 ns%u.%s S . x x tld 12 ns%u.%s S . 5 8 . 12 ns%u.root-servers.nil%s S . x x bind9-9.10.3.dfsg.P4/bin/tests/bigtest/buildzones.sh0000644000470500017500000001536712664710322021472 0ustar lamontlamont#!/bin/bash # # Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. SYSTEMTESTTOP=.. . ../conf.sh addr=127.127.0.0 ttl=300 named=${NAMED} keygen=${KEYGEN} dsfromkey=${DSFROMKEY} nextaddr() { OLDIF="$IFS" IFS="${IFS}." set $1 IFS="$OLDIFS" _a=$1 _b=$2 _c=$3 _d=$4 _d=$(($_d + 1)) case $_d in 256) _c=$(($_c + 1)); _d=0;; esac case $_c in 256) _b=$(($_b + 1)); _c=0;; esac echo $_a.$_b.$_c.$_d } parent() { OLDIF="$IFS" IFS="${IFS}." set $1 IFS="$OLDIFS" shift while [ $# -ne 0 ] do printf %s ${1} shift printf %s ${1:+.} done } blackhole() { echo 'options {' echo ' port 5300;' echo " listen-on { $1; };" echo " query-source $1;" echo " notify-source $1;" echo " transfer-source $1;" echo ' key-directory "keys";' echo " recursion ${2:-no};" echo ' pid-file "pids/'"${addr}"'.pid";' echo ' blackhole { 127.127.0.0; };' echo '};' } refuse() { echo 'options {' echo ' port 5300;' echo " listen-on { $1; };" echo " query-source $1;" echo " notify-source $1;" echo " transfer-source $1;" echo ' key-directory "keys";' echo " recursion ${2:-no};" echo ' pid-file "pids/'"${addr}"'.pid";' echo ' allow-query { !127.127.0.0; any; };' echo '};' } options() { echo 'options {' echo ' port 5300;' echo " listen-on { $1; };" echo " query-source $1;" echo " notify-source $1;" echo " transfer-source $1;" echo ' key-directory "keys";' echo " recursion ${2:-no};" echo ' pid-file "pids/'"${addr}"'.pid";' echo '};' } controls() { echo 'include "rndc.key";' echo "controls { inet $addr port 9953 allow { any; } keys { "rndc-key"; }; };" } delay() { _s=$1 OLDIF="$IFS" IFS="${IFS}/" set ${2:-.} IFS="$OLDIFS" case $1 in .) _d=;; *) _d=$1;; esac case $_s in 1) echo -T delay=${_d:-100};; 2) echo -T delay=${2:-50};; 3) echo -T delay=${3:-150};; 4) echo -T delay=${4:-250};; 5) echo -T delay=${5:-125};; 6) echo -T delay=${6:-25};; 7) echo -T delay=${7:-75};; 8) echo -T delay=${8:-125};; 9) echo -T delay=${9:-10};; 10) echo -T delay=${10:-40};; 11) echo -T delay=${11:-80};; 12) echo -T delay=${12:-90};; *) echo -T delay=50;; esac } trusted-keys () { awk '$3 == "DNSKEY" { b = ""; for (i=7; i <= NF; i++) { b = b $i; }; print "trusted-keys { \""$1"\"",$4,$5,$6,"\""b"\"; };" };' } signed-zone () { echo "zone "'"'"${1:-.}"'"'" {" echo " type master;" echo " file "'"'"master/${2}.db"'"'";" echo " auto-dnssec maintain;" echo " allow-update { any; };" echo "};" } unsigned-zone () { echo "zone "'"'"${1:-.}"'"'" {" echo " type master;" echo " file "'"'"master/${2}.db"'"'";" echo "};" } slave-zone () { echo "zone "'"'"${zone:-.}"'"'" {" echo " type slave;" echo " masters { ${master}; };" echo "};" } rm -rf servers master keys setup teardown run mkdir -p servers mkdir -p master mkdir -p keys echo "ifconfig lo0 $addr netmask 0xffffffff alias" >> setup echo "ifconfig lo0 $addr -alias" >> teardown controls $addr > named.conf options $addr yes >> named.conf echo 'zone "." { type hint; file "master/hint.db"; };' >> named.conf while read zone servers nsfmt signed delay blackhole refuse flags do i=1 case "${zone}" in .) file=root zone=;; *) file="$zone";; esac if [ "${zone}" != "" ] ; then p=$(parent $zone) case "${p}" in "") p=root;; esac else p=hint fi #echo "zone='${zone}' parent='${p}'" addr=$(nextaddr $addr) ns=$(printf "$nsfmt" ${i} "${zone}") d=$(delay $i ${delay:-.}) echo "${zone}. ${ttl} soa ${ns}. hostmaster.${zone}${zone:+.} 1 3600 1200 604800 1200" >> master/${file}.db echo "${zone}. ${ttl} ns ${ns}." >> master/${file}.db echo "${ns}. ${ttl} a ${addr}" >> master/${file}.db echo "${zone}. ${ttl} ns ${ns}." >> master/${p}.db echo "${ns}. ${ttl} a ${addr}" >> master/${p}.db if [ $signed = "S" ]; then kskkey=`${keygen} -K keys -f KSK ${zone:-.}` zskkey=`${keygen} -K keys ${zone:-.}` if [ "${zone}" != "" ] ; then ${dsfromkey} -T ${ttl} keys/${kskkey}.key >> master/${p}.db else trusted-keys < keys/${kskkey}.key >> named.conf fi fi echo "ifconfig lo0 $addr netmask 0xffffffff alias" >> setup echo "ifconfig lo0 $addr -alias" >> teardown echo "${named} -D bigtest -c servers/${addr}.conf $d $flags" >> run options ${addr} > servers/${addr}.conf case ${signed} in S) signed-zone ${zone:-.} ${file} >> servers/${addr}.conf;; P) unsigned-zone ${zone:-.} ${file} >> servers/${addr}.conf;; *) echo ${signed}; exit 1;; esac # slave servers while [ $i -lt $servers ] do master=$addr i=$(($i + 1)) ns=$(printf "$nsfmt" ${i} "${zone}") d=$(delay $i ${delay:-.}) addr=$(nextaddr $addr) echo "${zone}. ${ttl} ns ${ns}." >> master/${file}.db echo "${ns}. ${ttl} a ${addr}" >> master/${file}.db echo "${zone}. ${ttl} ns ${ns}." >> master/${p}.db echo "${ns}. ${ttl} a ${addr}" >> master/${p}.db echo "ifconfig lo0 $addr netmask 0xffffffff alias" >> setup echo "ifconfig lo0 $addr -alias" >> teardown echo "${named} -D bigtest -c servers/${addr}.conf $d $flags" >> run if [ $i = ${refuse:-.} ] then refuse $addr > servers/${addr}.conf elif [ $i = ${blackhole:-.} ] then blackhole $addr > servers/${addr}.conf else options $addr > servers/${addr}.conf fi slave-zone ${zone:-.} ${master} >> servers/${addr}.conf done if [ "${zone}" != "" ] ; then echo "www.${zone}. ${ttl} a 127.0.0.1" >> master/${file}.db echo "www.${zone}. ${ttl} aaaa ::1" >> master/${file}.db echo "${zone}. ${ttl} mx 10 mail.${zone}." >> master/${file}.db echo "mail.${zone}. ${ttl} a 127.0.0.1" >> master/${file}.db echo "mail.${zone}. ${ttl} aaaa ::1" >> master/${file}.db echo "*.big.${zone}. ${ttl} txt (" >> master/${file}.db i=0 while [ $i -lt 150 ] do echo "1234567890" >> master/${file}.db i=$(($i + 1)) done echo ")" >> master/${file}.db echo "*.medium.${zone}. ${ttl} txt (" >> master/${file}.db i=0 while [ $i -lt 120 ] do echo "1234567890" >> master/${file}.db i=$(($i + 1)) done echo ")" >> master/${file}.db echo "*.medium.${zone}. ${ttl} txt (" >> master/${file}.db i=0 while [ $i -lt 120 ] do echo "1234567890" >> master/${file}.db i=$(($i + 1)) done echo ")" >> master/${file}.db fi done bind9-9.10.3.dfsg.P4/bin/tests/bigtest/tests.sh0000644000470500017500000000415412664710322020446 0ustar lamontlamont#!/bin/bash # # Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. TOP=$( (cd ../../.. && pwd) ) dig=${TOP}/bin/dig/dig cmd="${dig} -p 5300 @127.127.0.0 txt" inner() { zone=$1 i=$2 to=$3 x=$i dout=dig$x.out tout=time$x.out while [ $i -lt $to ] do case $zone in .) zone=;; esac (time -p $cmd $i.${sub}$zone > $dout ) 2> $tout s=`sed -n '/real/s/[^0-9]*\([0-9]*\)\..*/\1/p' $tout` case $s in 0);; 1) t1=`expr ${t1:-0} + 1`;; 2) t2=`expr ${t2:-0} + 1`;; 3) t3=`expr ${t3:-0} + 1`;; *) echo $i `grep real $tout`;; esac grep "status: \(NXDOMAIN\|NOERROR\)" $dout > /dev/null || { echo $cmd $i.${sub}$zone cat $dout } i=`expr $i + 1` done if test ${t1:-0} -ne 0 -o ${t2:-0} -ne 0 -o ${t3:-0} -ne 0 then echo "$x timeouts: t1=${t1:-0} t2=${t2:-0} t3=${t3:-0}" fi } while read zone rest do for sub in "" medium. big. do case $zone in .) echo doing ${sub:-.};; *) echo doing $sub$zone;; esac ( inner $zone 1 100) & ( inner $zone 101 200) & ( inner $zone 201 300) & ( inner $zone 301 400) & ( inner $zone 401 500) & ( inner $zone 501 600) & ( inner $zone 601 700) & ( inner $zone 701 800) & ( inner $zone 801 900) & ( inner $zone 901 1000) & ( inner $zone 1001 1100) & ( inner $zone 1101 1200) & ( inner $zone 1201 1300) & ( inner $zone 1301 1400) & ( inner $zone 1401 1500) & ( inner $zone 1501 1600) & ( inner $zone 1601 1700) & wait done done bind9-9.10.3.dfsg.P4/bin/tests/bigtest/README0000644000470500017500000000072212664710322017625 0ustar lamontlamontCopyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. bash buildzones.sh < zones # creates setup, run, servers/* master/* # named.conf sudo sh setup # configure interfaces sh run # setup ../named/named [-g] -c named.conf sh tests.sh < zones sudo sh teardown # teardown interfaces The test server can controlled with rndc -k rndc.key -s 127.127.0.0 -p 5300 bind9-9.10.3.dfsg.P4/bin/tests/ndc.conf-include0000644000470500017500000000201212664710322020332 0ustar lamontlamont/* * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: ndc.conf-include,v 1.6 2007/06/19 23:46:59 tbox Exp $ */ key "another-key" { algorithm "al-gore-rhythm"; secret "R29yZSBpbiAyMDA0IQo"; # "Gore in 2004!" }; bind9-9.10.3.dfsg.P4/bin/tests/keyboard_test.c0000644000470500017500000000363212664710322020312 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: keyboard_test.c,v 1.13 2007/06/19 23:46:59 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include static void CHECK(const char *msg, isc_result_t result) { if (result != ISC_R_SUCCESS) { printf("FAILURE: %s: %s\n", msg, isc_result_totext(result)); exit(1); } } int main(int argc, char **argv) { isc_keyboard_t kbd; unsigned char c; isc_result_t res; unsigned int count; UNUSED(argc); UNUSED(argv); printf("Type Q to exit.\n"); res = isc_keyboard_open(&kbd); CHECK("isc_keyboard_open()", res); c = 'x'; count = 0; while (res == ISC_R_SUCCESS && c != 'Q') { res = isc_keyboard_getchar(&kbd, &c); printf("."); fflush(stdout); count++; if (count % 64 == 0) printf("\r\n"); } printf("\r\n"); if (res != ISC_R_SUCCESS) { printf("FAILURE: keyboard getchar failed: %s\r\n", isc_result_totext(res)); goto errout; } errout: res = isc_keyboard_close(&kbd, 3); CHECK("isc_keyboard_close()", res); return (0); } bind9-9.10.3.dfsg.P4/bin/tests/lex_test.c0000644000470500017500000001011612664710322017275 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: lex_test.c,v 1.23 2007/06/19 23:46:59 tbox Exp $ */ /*! \file */ #include #include #include #include #include #include isc_mem_t *mctx; isc_lex_t *lex; isc_lexspecials_t specials; static void print_token(isc_token_t *tokenp, FILE *stream) { switch (tokenp->type) { case isc_tokentype_unknown: fprintf(stream, "UNKNOWN"); break; case isc_tokentype_string: fprintf(stream, "STRING %.*s", (int)tokenp->value.as_region.length, tokenp->value.as_region.base); break; case isc_tokentype_number: fprintf(stream, "NUMBER %lu", tokenp->value.as_ulong); break; case isc_tokentype_qstring: fprintf(stream, "QSTRING \"%.*s\"", (int)tokenp->value.as_region.length, tokenp->value.as_region.base); break; case isc_tokentype_eol: fprintf(stream, "EOL"); break; case isc_tokentype_eof: fprintf(stream, "EOF"); break; case isc_tokentype_initialws: fprintf(stream, "INITIALWS"); break; case isc_tokentype_special: fprintf(stream, "SPECIAL %c", tokenp->value.as_char); break; case isc_tokentype_nomore: fprintf(stream, "NOMORE"); break; default: FATAL_ERROR(__FILE__, __LINE__, "Unexpected type %d", tokenp->type); } } int main(int argc, char *argv[]) { isc_token_t token; isc_result_t result; int quiet = 0; int c; int masterfile = 1; int stats = 0; unsigned int options = 0; int done = 0; while ((c = isc_commandline_parse(argc, argv, "qmcs")) != -1) { switch (c) { case 'q': quiet = 1; break; case 'm': masterfile = 1; break; case 'c': masterfile = 0; break; case 's': stats = 1; break; } } RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_lex_create(mctx, 256, &lex) == ISC_R_SUCCESS); if (masterfile) { /* Set up to lex DNS master file. */ specials['('] = 1; specials[')'] = 1; specials['"'] = 1; isc_lex_setspecials(lex, specials); options = ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE | ISC_LEXOPT_EOF | ISC_LEXOPT_QSTRING | ISC_LEXOPT_NOMORE; isc_lex_setcomments(lex, ISC_LEXCOMMENT_DNSMASTERFILE); } else { /* Set up to lex DNS config file. */ specials['{'] = 1; specials['}'] = 1; specials[';'] = 1; specials['/'] = 1; specials['"'] = 1; specials['!'] = 1; specials['*'] = 1; isc_lex_setspecials(lex, specials); options = ISC_LEXOPT_EOF | ISC_LEXOPT_QSTRING | ISC_LEXOPT_NUMBER | ISC_LEXOPT_NOMORE; isc_lex_setcomments(lex, (ISC_LEXCOMMENT_C| ISC_LEXCOMMENT_CPLUSPLUS| ISC_LEXCOMMENT_SHELL)); } RUNTIME_CHECK(isc_lex_openstream(lex, stdin) == ISC_R_SUCCESS); while ((result = isc_lex_gettoken(lex, options, &token)) == ISC_R_SUCCESS && !done) { if (!quiet) { char *name = isc_lex_getsourcename(lex); print_token(&token, stdout); printf(" line = %lu file = %s\n", isc_lex_getsourceline(lex), (name == NULL) ? "" : name); } if (token.type == isc_tokentype_eof) isc_lex_close(lex); if (token.type == isc_tokentype_nomore) done = 1; } if (result != ISC_R_SUCCESS) printf("Result: %s\n", isc_result_totext(result)); isc_lex_close(lex); isc_lex_destroy(&lex); if (!quiet && stats) isc_mem_stats(mctx, stdout); isc_mem_destroy(&mctx); return (0); } bind9-9.10.3.dfsg.P4/bin/tests/db/0002755000470500017500000000000012672612753015702 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_findnode_2_data0000644000470500017500000000023012664710322022117 0ustar lamontlamont# # test data for dns_db_findnode 2 # # format: # filename type origin class cache newname # dns_db_findnode_2.data rbt vix.com. in zone a.b.c.vix.com. bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_load_soa_not_top0000644000470500017500000000027512664710322022453 0ustar lamontlamont# # test data for dns_db_load_soa_not_top # # format: # filename type origin cache class findname expected_result # dns_db_load_25.data rbt . zone in DNS_R_NOTZONETOP a. A DNS_R_DELEGATION bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_iszone_2.data0000644000470500017500000000036012664710322021563 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a in ns ns.vix.com. a in ns ns2.vix.com. a in ns ns3.vix.com. b in a 1.2.3.4 bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_find_1_data0000644000470500017500000000036012664710322021254 0ustar lamontlamont# # test data for dns_db_find best match # # format: # dbfile dbtype dborigin dbclass dbcache findname findtype findopts findtime expected_results # dns_db_find_1.data rbt vix.com. in zone a.b.c.vix.com. NS DNS_DB_GLUEOK 0 DNS_R_DELEGATION bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_class_1.data0000644000470500017500000000036012664710322021360 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a in ns ns.vix.com. a in ns ns2.vix.com. a in ns ns3.vix.com. b in a 1.2.3.4 bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_find_7.data0000644000470500017500000000033712664710322021205 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a.b.c.d in A 1.2.3.4 a.b in A 1.2.3.4 a in NS ns1.vix.com. bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_currentversion.data0000644000470500017500000000036512664710322023130 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a.b.c.vix.com. a 1.2.3.4 a in ns ns2.vix.com. a in ns ns3.vix.com. b in a 1.2.3.4 bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_closeversion_2_data0000644000470500017500000000033312664710322023050 0ustar lamontlamont# # test data for dns_db_closeversion test 2 # # format: # filename type origin class cache new_name new_type existing_name existing_type # dns_db_closeversion_1.data rbt vix.com. in zone a.b.c.vix.com. A a.vix.com. NS bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_find_2.data0000644000470500017500000000031212664710322021171 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum fx in ns a.fx.vix.com. a.fx in a 1.2.3.4 bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_find_3_data0000644000470500017500000000065712664710322021267 0ustar lamontlamont# # test data for dns_db_find DNS_R_DELAGATION # # format: # dbfile dbtype dborigin dbclass dbcache findname findtype findopts findtime expected_results # dns_db_find_3.data rbt vix.com. in zone a.b.c.vix.com. NS DNS_DB_GLUEOK 0 DNS_R_DELEGATION dns_db_find_3.data rbt vix.com. in zone a.a.b.c.vix.com. NS DNS_DB_GLUEOK 0 DNS_R_DELEGATION dns_db_find_3.data rbt vix.com. in zone a.a.b.c.vix.com. A DNS_DB_GLUEOK 0 DNS_R_DELEGATION bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_iscache_1.data0000644000470500017500000000036012664710322021652 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a in ns ns.vix.com. a in ns ns2.vix.com. a in ns ns3.vix.com. b in a 1.2.3.4 bind9-9.10.3.dfsg.P4/bin/tests/db/Makefile.in0000644000470500017500000000346412664710322017744 0ustar lamontlamont# Copyright (C) 2004, 2007, 2009, 2010, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1999-2002 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.34 2010/08/13 23:47:03 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_MAKE_INCLUDES@ CINCLUDES = ${TEST_INCLUDES} ${DNS_INCLUDES} ${ISC_INCLUDES} CDEFINES = CWARNINGS = DNSLIBS = ../../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ ISCLIBS = ../../../lib/isc/libisc.@A@ ISCCFGLIBS = ../../../lib/isccfg/libisccfg.@A@ DNSDEPLIBS = ../../../lib/dns/libdns.@A@ ISCDEPLIBS = ../../../lib/isc/libisc.@A@ ISCCFGDEPLIBS = ../../../lib/isccfg/libisccfg.@A@ DEPLIBS = ${DNSDEPLIBS} ${ISCCFGDEPLIBS} ${ISCDEPLIBS} LIBS = ${DNSLIBS} ${ISCCFGLIBS} ${ISCLIBS} @LIBS@ TLIB = ../../../lib/tests/libt_api.@A@ SRCS = t_db.c TARGETS = t_db@EXEEXT@ @BIND9_MAKE_RULES@ t_db@EXEEXT@: t_db.@O@ ${DEPLIBS} ${TLIB} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ t_db.@O@ ${TLIB} ${LIBS} test: t_db@EXEEXT@ -@./t_db@EXEEXT@ -c @top_srcdir@/t_config -b @srcdir@ -a testhelp: @./t_db -h clean distclean:: rm -f ${TARGETS} bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_find_6.data0000644000470500017500000000030612664710322021200 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum exploder in CNAME mx mx in A 1.2.3.4 bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_iscache_2_data0000644000470500017500000000016512664710322021737 0ustar lamontlamont# # test data for dns_db_iscache test 1 # # format: # filename db_type origin class # dns_db_iscache_2.data rbt . in bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_findnode_2.data0000644000470500017500000000036012664710322022042 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a in ns ns.vix.com. a in ns ns2.vix.com. a in ns ns3.vix.com. b in a 1.2.3.4 bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_expirenode.data0000644000470500017500000000036012664710322022175 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a in ns ns.vix.com. a in ns ns2.vix.com. a in ns ns3.vix.com. b in a 1.2.3.4 bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_load_1.data0000644000470500017500000000036012664710322021172 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a in ns ns.vix.com. a in ns ns2.vix.com. a in ns ns3.vix.com. b in a 1.2.3.4 bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_expirenode_data0000644000470500017500000000026412664710322022261 0ustar lamontlamont# # test data for dns_db_expirenode # # format: # filename type origin class existing_name existing_type # dns_db_expirenode.data rbt vix.com. in a.vix.com. 10000 0 ISC_R_NOTFOUND bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_find_4.data0000644000470500017500000000030512664710322021175 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a.b.c in ns b b.a.b.c in a 10.0.0.2 bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_find_9.data0000644000470500017500000000037712664710322021213 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a.b.c.d in NS ns1.vix.com. a.b.c in A 1.2.3.4 a.b in NS ns1.vix.com. a in NS ns1.vix.com. bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_find_10_data0000644000470500017500000000050312664710322021333 0ustar lamontlamont# # test data for dns_db_find expiration time handling # # format: # dbfile dbtype dborigin dbclass dbcache findname findtype findopts findtime expected_results # dns_db_find_10.data rbt vix.com. in cache a.b.c.vix.com. NS 0 1010 ISC_R_NOTFOUND dns_db_find_10.data rbt vix.com. in cache a.b.c.vix.com. NS 0 0 ISC_R_SUCCESS bind9-9.10.3.dfsg.P4/bin/tests/db/t_db.c0000644000470500017500000023305212664710322016751 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2009, 2011-2013, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: t_db.c,v 1.41 2011/03/12 04:59:46 tbox Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static isc_result_t t_create(const char *db_type, const char *origin, const char *class, const char *model, isc_mem_t *mctx, dns_db_t **db) { int len; isc_result_t dns_result; dns_dbtype_t dbtype; isc_textregion_t region; isc_buffer_t origin_buffer; dns_fixedname_t dns_origin; dns_rdataclass_t rdataclass; dbtype = dns_dbtype_zone; if (strcasecmp(model, "cache") == 0) dbtype = dns_dbtype_cache; dns_fixedname_init(&dns_origin); len = strlen(origin); isc_buffer_constinit(&origin_buffer, origin, len); isc_buffer_add(&origin_buffer, len); dns_result = dns_name_fromtext(dns_fixedname_name(&dns_origin), &origin_buffer, NULL, 0, NULL); if (dns_result != ISC_R_SUCCESS) { t_info("dns_name_fromtext failed %s\n", dns_result_totext(dns_result)); return(dns_result); } DE_CONST(class, region.base); region.length = strlen(class); dns_result = dns_rdataclass_fromtext(&rdataclass, ®ion); if (dns_result != ISC_R_SUCCESS) { t_info("dns_rdataclass_fromtext failed %s\n", dns_result_totext(dns_result)); return(dns_result); } dns_result = dns_db_create(mctx, db_type, dns_fixedname_name(&dns_origin), dbtype, rdataclass, 0, NULL, db); if (dns_result != ISC_R_SUCCESS) t_info("dns_db_create failed %s\n", dns_result_totext(dns_result)); return(dns_result); } static int t_dns_db_load(char **av) { char *filename; char *db_type; char *origin; char *model; char *class; char *expected_load_result; char *findname; char *find_type; char *expected_find_result; int result; int len; dns_db_t *db; isc_result_t dns_result; isc_result_t isc_result; isc_mem_t *mctx; isc_entropy_t *ectx; dns_dbnode_t *nodep; isc_textregion_t textregion; isc_buffer_t findname_buffer; dns_fixedname_t dns_findname; dns_fixedname_t dns_foundname; dns_rdataset_t rdataset; dns_rdatatype_t rdatatype; dns_dbversion_t *versionp; isc_result_t exp_load_result; isc_result_t exp_find_result; db = NULL; mctx = NULL; ectx = NULL; filename = T_ARG(0); db_type = T_ARG(1); origin = T_ARG(2); model = T_ARG(3); class = T_ARG(4); expected_load_result = T_ARG(5); findname = T_ARG(6); find_type = T_ARG(7); expected_find_result = T_ARG(8); t_info("testing using file %s and name %s\n", filename, findname); exp_load_result = t_dns_result_fromtext(expected_load_result); exp_find_result = t_dns_result_fromtext(expected_find_result); isc_result = isc_mem_create(0, 0, &mctx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mem_create failed %s\n", isc_result_totext(isc_result)); return(T_UNRESOLVED); } isc_result = isc_entropy_create(mctx, &ectx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_entropy_create failed %s\n", isc_result_totext(isc_result)); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (isc_result != ISC_R_SUCCESS) { t_info("isc_hash_create failed %s\n", isc_result_totext(isc_result)); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = t_create(db_type, origin, class, model, mctx, &db); if (dns_result != ISC_R_SUCCESS) { isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_db_load(db, filename); if (dns_result != exp_load_result) { t_info("dns_db_load returned %s, expected %s\n", dns_result_totext(dns_result), dns_result_totext(exp_load_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_FAIL); } if (dns_result != ISC_R_SUCCESS) { result = T_PASS; goto cleanup_db; } dns_fixedname_init(&dns_findname); len = strlen(findname); isc_buffer_init(&findname_buffer, findname, len); isc_buffer_add(&findname_buffer, len); dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname), &findname_buffer, NULL, 0, NULL); if (dns_result != ISC_R_SUCCESS) { t_info("dns_name_fromtext failed %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } textregion.base = find_type; textregion.length = strlen(find_type); dns_result = dns_rdatatype_fromtext(&rdatatype, &textregion); if (dns_result != ISC_R_SUCCESS) { t_info("dns_rdatatype_fromtext %s failed %s\n", find_type, dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } versionp = NULL; dns_fixedname_init(&dns_foundname); dns_rdataset_init(&rdataset); if (dns_db_iszone(db)) dns_db_currentversion(db, &versionp); nodep = NULL; dns_result = dns_db_find(db, dns_fixedname_name(&dns_findname), versionp, rdatatype, DNS_DBFIND_GLUEOK, 0, &nodep, dns_fixedname_name(&dns_foundname), &rdataset, NULL); if (dns_result != exp_find_result) { t_info("dns_db_find returned %s, expected %s\n", dns_result_totext(dns_result), dns_result_totext(exp_find_result)); result = T_FAIL; } else { result = T_PASS; } if (dns_result != ISC_R_NOTFOUND) { dns_db_detachnode(db, &nodep); if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); } if (dns_db_iszone(db)) dns_db_closeversion(db, &versionp, ISC_FALSE); cleanup_db: dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(result); } static const char *a1 = "A call to dns_db_load(db, filename) loads the contents of " "the database in filename into db."; static void t1(void) { int result; t_assert("dns_db_load", 1, T_REQUIRED, "%s", a1); result = t_eval("dns_db_load_data", t_dns_db_load, 9); t_result(result); } static const char *a2 = "When the database db has cache semantics, a call to " "dns_db_iscache(db) returns ISC_TRUE."; static int t_dns_db_zc_x(char *filename, char *db_type, char *origin, char *class, dns_dbtype_t dbtype, isc_boolean_t(*cf)(dns_db_t *), isc_boolean_t exp_result) { int result; int len; dns_db_t *db; isc_result_t dns_result; isc_result_t isc_result; isc_mem_t *mctx; isc_entropy_t *ectx; dns_rdataclass_t rdataclass; isc_textregion_t textregion; isc_buffer_t origin_buffer; dns_fixedname_t dns_origin; db = NULL; mctx = NULL; ectx = NULL; t_info("testing using file %s\n", filename); dns_fixedname_init(&dns_origin); len = strlen(origin); isc_buffer_init(&origin_buffer, origin, len); isc_buffer_add(&origin_buffer, len); dns_result = dns_name_fromtext(dns_fixedname_name(&dns_origin), &origin_buffer, NULL, 0, NULL); if (dns_result != ISC_R_SUCCESS) { t_info("dns_name_fromtext failed %s\n", dns_result_totext(dns_result)); return(T_UNRESOLVED); } textregion.base = class; textregion.length = strlen(class); dns_result = dns_rdataclass_fromtext(&rdataclass, &textregion); if (dns_result != ISC_R_SUCCESS) { t_info("dns_rdataclass_fromtext failed %s\n", dns_result_totext(dns_result)); return(T_UNRESOLVED); } isc_result = isc_mem_create(0, 0, &mctx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mem_create failed %s\n", isc_result_totext(isc_result)); return(T_UNRESOLVED); } isc_result = isc_entropy_create(mctx, &ectx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_entropy_create failed %s\n", isc_result_totext(isc_result)); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (isc_result != ISC_R_SUCCESS) { t_info("isc_hash_create failed %s\n", isc_result_totext(isc_result)); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_db_create(mctx, db_type, dns_fixedname_name(&dns_origin), dbtype, rdataclass, 0, NULL, &db); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_create failed %s\n", dns_result_totext(dns_result)); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_db_load(db, filename); if (dns_result == ISC_R_SUCCESS) { if ((*cf)(db) == exp_result) result = T_PASS; else result = T_FAIL; } else { t_info("dns_db_load failed %s\n", dns_result_totext(dns_result)); result = T_FAIL; } dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(result); } static int test_dns_db_zc_x(const char *filename, dns_dbtype_t dbtype, isc_boolean_t(*cf)(dns_db_t *), isc_boolean_t exp_result) { FILE *fp; char *p; int line; int cnt; int result; int nfails; int nprobs; char *tokens[T_MAXTOKS]; nfails = 0; nprobs = 0; fp = fopen(filename, "r"); if (fp != NULL) { line = 0; while ((p = t_fgetbs(fp)) != NULL) { ++line; /* * Skip comment lines. */ if ((isspace((unsigned char)*p)) || (*p == '#')) { (void)free(p); continue; } cnt = t_bustline(p, tokens); if (cnt == 4) { result = t_dns_db_zc_x(tokens[0], /* file */ tokens[1], /* type */ tokens[2], /* origin */ tokens[3], /* class */ dbtype, /* cache */ cf, /* check func */ exp_result);/* expect */ if (result != T_PASS) { if (result == T_FAIL) ++nfails; else ++nprobs; } } else { t_info("bad format in %s at line %d\n", filename, line); ++nprobs; } (void)free(p); } (void)fclose(fp); } else { t_info("Missing datafile %s\n", filename); ++nprobs; } result = T_UNRESOLVED; if (nfails == 0 && nprobs == 0) result = T_PASS; else if (nfails) result = T_FAIL; return(result); } static void t2(void) { int result; t_assert("dns_db_iscache", 2, T_REQUIRED, "%s", a2); result = test_dns_db_zc_x("dns_db_iscache_1_data", dns_dbtype_cache, dns_db_iscache, ISC_TRUE); t_result(result); } static const char *a3 = "When the database db has zone semantics, a call to " "dns_db_iscache(db) returns ISC_FALSE."; static void t3(void) { int result; t_assert("dns_db_iscache", 3, T_REQUIRED, "%s", a3); result = test_dns_db_zc_x("dns_db_iscache_2_data", dns_dbtype_zone, dns_db_iscache, ISC_FALSE); t_result(result); } static const char *a4 = "When the database db has zone semantics, a call to " "dns_db_iszone(db) returns ISC_TRUE."; static void t4(void) { int result; t_assert("dns_db_iszone", 4, T_REQUIRED, "%s", a4); result = test_dns_db_zc_x("dns_db_iszone_1_data", dns_dbtype_zone, dns_db_iszone, ISC_TRUE); t_result(result); } static const char *a5 = "When the database db has cache semantics, a call to " "dns_db_iszone(db) returns ISC_FALSE."; static void t5(void) { int result; t_assert("dns_db_iszone", 5, T_REQUIRED, "%s", a5); result = test_dns_db_zc_x("dns_db_iszone_2_data", dns_dbtype_cache, dns_db_iszone, ISC_FALSE); t_result(result); } static int t_dns_db_origin(char **av) { char *filename; char *origin; int result; int len; int order; isc_result_t dns_result; isc_result_t isc_result; isc_mem_t *mctx; isc_entropy_t *ectx; dns_db_t *db; dns_fixedname_t dns_origin; dns_fixedname_t dns_dborigin; isc_buffer_t origin_buffer; db = NULL; mctx = NULL; ectx = NULL; filename = T_ARG(0); origin = T_ARG(1); t_info("testing with database %s and origin %s\n", filename, origin); isc_result = isc_mem_create(0, 0, &mctx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mem_create failed %s\n", isc_result_totext(isc_result)); return(T_UNRESOLVED); } isc_result = isc_entropy_create(mctx, &ectx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_entropy_create failed %s\n", isc_result_totext(isc_result)); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (isc_result != ISC_R_SUCCESS) { t_info("isc_hash_create failed %s\n", isc_result_totext(isc_result)); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = t_create("rbt", origin, "in", "isc_true", mctx, &db); if (dns_result != ISC_R_SUCCESS) { t_info("t_create failed %s\n", dns_result_totext(dns_result)); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_fixedname_init(&dns_origin); dns_fixedname_init(&dns_dborigin); len = strlen(origin); isc_buffer_init(&origin_buffer, origin, len); isc_buffer_add(&origin_buffer, len); dns_result = dns_db_load(db, filename); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_load failed %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_name_fromtext(dns_fixedname_name(&dns_origin), &origin_buffer, NULL, 0, NULL); if (dns_result != ISC_R_SUCCESS) { t_info("dns_name_fromtext failed %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } order = dns_name_compare(dns_fixedname_name(&dns_origin), dns_db_origin(db)); if (order == 0) { result = T_PASS; } else { t_info("dns_name_compare returned %d\n", order); result = T_FAIL; } dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(result); } static const char *a6 = "A call to dns_db_origin(db) returns the origin of the database."; static void t6(void) { int result; t_assert("dns_db_origin", 6, T_REQUIRED, "%s", a6); result = t_eval("dns_db_origin_data", t_dns_db_origin, 2); t_result(result); } static const char *a7 = "A call to dns_db_class(db) returns the class of the database."; #define CLASSBUFLEN 256 static int t_dns_db_class(char **av) { char *filename; char *class; int result; isc_result_t dns_result; isc_result_t isc_result; isc_mem_t *mctx; isc_entropy_t *ectx; dns_db_t *db; dns_rdataclass_t rdataclass; dns_rdataclass_t db_rdataclass; isc_textregion_t textregion; filename = T_ARG(0); class = T_ARG(1); db = NULL; mctx = NULL; ectx = NULL; t_info("testing with database %s and class %s\n", filename, class); textregion.base = class; textregion.length = strlen(class); dns_result = dns_rdataclass_fromtext(&rdataclass, &textregion); if (dns_result != ISC_R_SUCCESS) { t_info("dns_rdataclass_fromtext failed %s\n", dns_result_totext(dns_result)); return(T_UNRESOLVED); } isc_result = isc_mem_create(0, 0, &mctx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mem_create failed %s\n", isc_result_totext(isc_result)); return(T_UNRESOLVED); } isc_result = isc_entropy_create(mctx, &ectx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_entropy_create failed %s\n", isc_result_totext(isc_result)); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (isc_result != ISC_R_SUCCESS) { t_info("isc_hash_create failed %s\n", isc_result_totext(isc_result)); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = t_create("rbt", ".", class, "isc_true", mctx, &db); if (dns_result != ISC_R_SUCCESS) { t_info("t_create failed %s\n", dns_result_totext(dns_result)); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_db_load(db, filename); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_load failed %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } db_rdataclass = dns_db_class(db); if (db_rdataclass == rdataclass) result = T_PASS; else { char classbuf[DNS_RDATACLASS_FORMATSIZE]; dns_rdataclass_format(db_rdataclass, classbuf, sizeof(classbuf)); t_info("dns_db_class returned %s, expected %s\n", classbuf, class); result = T_FAIL; } dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(result); } static void t7(void) { int result; t_assert("dns_db_class", 7, T_REQUIRED, "%s", a7); result = t_eval("dns_db_class_data", t_dns_db_class, 2); t_result(result); } static const char *a8 = "A call to dns_db_currentversion() opens the current " "version for reading."; static int t_dns_db_currentversion(char **av) { char *filename; char *db_type; char *origin; char *class; char *model; char *findname; char *findtype; int result; int len; dns_db_t *db; isc_result_t dns_result; isc_result_t isc_result; isc_mem_t *mctx; isc_entropy_t *ectx; dns_dbnode_t *nodep; isc_textregion_t textregion; isc_buffer_t findname_buffer; dns_fixedname_t dns_findname; dns_fixedname_t dns_foundname; dns_rdataset_t rdataset; dns_rdatatype_t rdatatype; dns_dbversion_t *cversionp; dns_dbversion_t *nversionp; filename = T_ARG(0); db_type = T_ARG(1); origin = T_ARG(2); class = T_ARG(3); model = T_ARG(4); findname = T_ARG(5); findtype = T_ARG(6); db = NULL; mctx = NULL; ectx = NULL; t_info("testing using file %s and name %s\n", filename, findname); isc_result = isc_mem_create(0, 0, &mctx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mem_create failed %s\n", isc_result_totext(isc_result)); return(T_UNRESOLVED); } isc_result = isc_entropy_create(mctx, &ectx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_entropy_create failed %s\n", isc_result_totext(isc_result)); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (isc_result != ISC_R_SUCCESS) { t_info("isc_hash_create failed %s\n", isc_result_totext(isc_result)); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = t_create(db_type, origin, class, model, mctx, &db); if (dns_result != ISC_R_SUCCESS) { isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_db_load(db, filename); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_load returned %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_fixedname_init(&dns_findname); len = strlen(findname); isc_buffer_init(&findname_buffer, findname, len); isc_buffer_add(&findname_buffer, len); dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname), &findname_buffer, NULL, 0, NULL); if (dns_result != ISC_R_SUCCESS) { t_info("dns_name_fromtext failed %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } textregion.base = findtype; textregion.length = strlen(findtype); dns_result = dns_rdatatype_fromtext(&rdatatype, &textregion); if (dns_result != ISC_R_SUCCESS) { t_info("dns_rdatatype_fromtext %s failed %s\n", findtype, dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } /* * find a name we know is there */ cversionp = NULL; dns_fixedname_init(&dns_foundname); dns_rdataset_init(&rdataset); dns_db_currentversion(db, &cversionp); nodep = NULL; dns_result = dns_db_find(db, dns_fixedname_name(&dns_findname), cversionp, rdatatype, 0, 0, &nodep, dns_fixedname_name(&dns_foundname), &rdataset, NULL); if (dns_result != ISC_R_SUCCESS) { t_info("unable to find %s using current version\n", findname); dns_db_closeversion(db, &cversionp, ISC_FALSE); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } /* * create a new version * delete the found rdataset in the new version * attempt to find the rdataset again and expect the find to fail * close/commit the new version * attempt to find the rdataset in the current version and * expect the find to succeed */ nversionp = NULL; dns_result = dns_db_newversion(db, &nversionp); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_newversion failed %s\n", dns_result_totext(dns_result)); dns_db_detachnode(db, &nodep); dns_rdataset_disassociate(&rdataset); dns_db_closeversion(db, &cversionp, ISC_FALSE); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } /* * Delete the found rdataset in the new version. */ dns_result = dns_db_deleterdataset(db, nodep, nversionp, rdatatype, 0); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_deleterdataset failed %s\n", dns_result_totext(dns_result)); dns_rdataset_disassociate(&rdataset); dns_db_detachnode(db, &nodep); dns_db_closeversion(db, &nversionp, ISC_FALSE); dns_db_closeversion(db, &cversionp, ISC_FALSE); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } /* * Don't need these now. */ dns_rdataset_disassociate(&rdataset); dns_db_detachnode(db, &nodep); nodep = NULL; /* * Find the deleted rdataset and expect it to fail. */ dns_result = dns_db_find(db, dns_fixedname_name(&dns_findname), nversionp, rdatatype, 0, 0, &nodep, dns_fixedname_name(&dns_foundname), &rdataset, NULL); if ((dns_result != ISC_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) { t_info("unexpectedly found %s using current version\n", findname); dns_db_closeversion(db, &cversionp, ISC_FALSE); dns_db_closeversion(db, &nversionp, ISC_FALSE); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_FAIL); } /* * Close/commit the new version. */ dns_db_closeversion(db, &nversionp, ISC_TRUE); /* * Find the deleted rdata in the current version. */ dns_result = dns_db_find(db, dns_fixedname_name(&dns_findname), cversionp, rdatatype, DNS_DBFIND_GLUEOK, 0, &nodep, dns_fixedname_name(&dns_foundname), &rdataset, NULL); /* * And expect it to succeed. */ if (dns_result == ISC_R_SUCCESS) { result = T_PASS; } else { t_info("cound not find %s using current version\n", findname); dns_db_closeversion(db, &cversionp, ISC_FALSE); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); result = T_FAIL; } dns_db_detachnode(db, &nodep); dns_rdataset_disassociate(&rdataset); dns_db_closeversion(db, &cversionp, ISC_FALSE); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(result); } static void t8(void) { int result; t_assert("dns_db_currentversion", 8, T_REQUIRED, "%s", a8); result = t_eval("dns_db_currentversion_data", t_dns_db_currentversion, 7); t_result(result); } static const char *a9 = "A call to dns_db_newversion() opens a new version for " "reading and writing."; static int t_dns_db_newversion(char **av) { char *filename; char *db_type; char *origin; char *class; char *model; char *newname; char *newtype; int result; int len; int rval; dns_db_t *db; isc_result_t dns_result; isc_result_t isc_result; isc_mem_t *mctx; isc_entropy_t *ectx; dns_dbnode_t *nodep; dns_dbnode_t *found_nodep; isc_textregion_t textregion; isc_buffer_t newname_buffer; dns_fixedname_t dns_newname; dns_fixedname_t dns_foundname; dns_rdata_t added_rdata = DNS_RDATA_INIT; const char * added_rdata_data; dns_rdataset_t added_rdataset; dns_rdata_t found_rdata = DNS_RDATA_INIT; dns_rdataset_t found_rdataset; dns_rdatatype_t rdatatype; dns_rdataclass_t rdataclass; dns_dbversion_t *nversionp; dns_rdatalist_t rdatalist; filename = T_ARG(0); db_type = T_ARG(1); origin = T_ARG(2); class = T_ARG(3); model = T_ARG(4); newname = T_ARG(5); newtype = T_ARG(6); db = NULL; mctx = NULL; ectx = NULL; /* * Open a new version, add some data, commit it, * close it, open a new version, and check that changes * are present. */ t_info("testing using file %s and name %s\n", filename, newname); isc_result = isc_mem_create(0, 0, &mctx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mem_create failed %s\n", isc_result_totext(isc_result)); return(T_UNRESOLVED); } isc_result = isc_entropy_create(mctx, &ectx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_entropy_create failed %s\n", isc_result_totext(isc_result)); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (isc_result != ISC_R_SUCCESS) { t_info("isc_hash_create failed %s\n", isc_result_totext(isc_result)); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = t_create(db_type, origin, class, model, mctx, &db); if (dns_result != ISC_R_SUCCESS) { isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_db_load(db, filename); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_load returned %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } /* * Add a new name. */ dns_fixedname_init(&dns_newname); len = strlen(newname); isc_buffer_init(&newname_buffer, newname, len); isc_buffer_add(&newname_buffer, len); dns_result = dns_name_fromtext(dns_fixedname_name(&dns_newname), &newname_buffer, NULL, 0, NULL); if (dns_result != ISC_R_SUCCESS) { t_info("dns_name_fromtext failed %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } nodep = NULL; dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_newname), ISC_TRUE, &nodep); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_findnode failed %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } /* * Open a new version and associate some rdata with the new name. */ textregion.base = newtype; textregion.length = strlen(newtype); dns_result = dns_rdatatype_fromtext(&rdatatype, &textregion); if (dns_result != ISC_R_SUCCESS) { t_info("dns_rdatatype_fromtext %s failed %s\n", newtype, dns_result_totext(dns_result)); dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } textregion.base = class; textregion.length = strlen(class); dns_result = dns_rdataclass_fromtext(&rdataclass, &textregion); if (dns_result != ISC_R_SUCCESS) { t_info("dns_rdataclass_fromtext failed %s\n", dns_result_totext(dns_result)); dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_rdata_init(&added_rdata); added_rdata_data = "\x10\x00\x00\x01"; DE_CONST(added_rdata_data, added_rdata.data); added_rdata.length = 4; added_rdata.rdclass = rdataclass; added_rdata.type = rdatatype; dns_rdatalist_init(&rdatalist); rdatalist.type = rdatatype; rdatalist.rdclass = rdataclass; ISC_LIST_APPEND(rdatalist.rdata, &added_rdata, link); dns_rdataset_init(&added_rdataset); dns_result = dns_rdatalist_tordataset(&rdatalist, &added_rdataset); if (dns_result != ISC_R_SUCCESS) { t_info("dns_rdatalist_tordataset failed %s\n", dns_result_totext(dns_result)); dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } nversionp = NULL; dns_result = dns_db_newversion(db, &nversionp); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_newversion failed %s\n", dns_result_totext(dns_result)); dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_db_addrdataset(db, nodep, nversionp, 0, &added_rdataset, 0, NULL); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_addrdataset failed %s\n", dns_result_totext(dns_result)); dns_db_closeversion(db, &nversionp, ISC_FALSE); dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } /* * Close and commit the version. */ dns_db_closeversion(db, &nversionp, ISC_TRUE); dns_db_detachnode(db, &nodep); if (dns_rdataset_isassociated(&added_rdataset)) dns_rdataset_disassociate(&added_rdataset); nodep = NULL; /* * Open a new version and find the data we added. */ dns_fixedname_init(&dns_foundname); dns_rdataset_init(&found_rdataset); nversionp = NULL; found_nodep = NULL; dns_db_newversion(db, &nversionp); /* * Find the recently added name and rdata. */ dns_result = dns_db_find(db, dns_fixedname_name(&dns_newname), nversionp, rdatatype, 0, 0, &found_nodep, dns_fixedname_name(&dns_foundname), &found_rdataset, NULL); if (dns_result != ISC_R_SUCCESS) { /* XXXWPK - NXRRSET ??? reference counts ??? */ t_info("dns_db_find failed %s\n", dns_result_totext(dns_result)); dns_db_closeversion(db, &nversionp, ISC_FALSE); dns_db_detachnode(db, &found_nodep); if (dns_rdataset_isassociated(&found_rdataset)) dns_rdataset_disassociate(&found_rdataset); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_FAIL); } dns_result = dns_rdataset_first(&found_rdataset); if (dns_result != ISC_R_SUCCESS) { t_info("dns_rdataset_first failed %s\n", dns_result_totext(dns_result)); dns_db_detachnode(db, &nodep); if (dns_rdataset_isassociated(&found_rdataset)) dns_rdataset_disassociate(&found_rdataset); dns_db_closeversion(db, &nversionp, ISC_FALSE); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_FAIL); } /* * Now make sure its what we expect. */ dns_rdata_init(&found_rdata); dns_rdataset_current(&found_rdataset, &found_rdata); rval = dns_rdata_compare(&added_rdata, &found_rdata); if (rval == 0) { result = T_PASS; } else { t_info("dns_rdata_compare returned %d\n", rval); result = T_FAIL; } /* * Don't need these now. */ dns_db_closeversion(db, &nversionp, ISC_FALSE); if (dns_rdataset_isassociated(&found_rdataset)) dns_rdataset_disassociate(&found_rdataset); dns_db_detachnode(db, &found_nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(result); } static void t9(void) { int result; t_assert("dns_db_newversion", 9, T_REQUIRED, "%s", a9); result = t_eval("dns_db_newversion_data", t_dns_db_newversion, 7); t_result(result); } static const char *a10 = "When versionp points to a read-write version and commit is " "ISC_TRUE, a call to dns_db_closeversion(db, versionp, commit) " "causes all changes made in the version to take effect, " "and returns ISC_R_SUCCESS."; static int t_dns_db_closeversion_1(char **av) { char *filename; char *db_type; char *origin; char *class; char *model; char *new_name; char *new_type; char *existing_name; char *existing_type; int result; int len; int rval; int nfails; dns_db_t *db; isc_result_t dns_result; isc_result_t isc_result; isc_mem_t *mctx; isc_entropy_t *ectx; dns_dbnode_t *nodep; isc_textregion_t textregion; isc_buffer_t name_buffer; dns_fixedname_t dns_newname; dns_fixedname_t dns_foundname; dns_fixedname_t dns_existingname; dns_rdata_t added_rdata = DNS_RDATA_INIT; const char * added_rdata_data; dns_rdataset_t added_rdataset; dns_rdata_t found_rdata = DNS_RDATA_INIT; dns_rdataset_t found_rdataset; dns_rdatatype_t new_rdatatype; dns_rdatatype_t existing_rdatatype; dns_rdataclass_t rdataclass; dns_dbversion_t *nversionp; dns_dbversion_t *cversionp; dns_rdatalist_t rdatalist; filename = T_ARG(0); db_type = T_ARG(1); origin = T_ARG(2); class = T_ARG(3); model = T_ARG(4); new_name = T_ARG(5); new_type = T_ARG(6); existing_name = T_ARG(7); existing_type = T_ARG(8); nfails = 0; db = NULL; mctx = NULL; ectx = NULL; /* * Open a new version, add some data, * remove some data, close with commit, open the current * version and check that changes are present. */ t_info("testing using file %s and name %s\n", filename, new_name); isc_result = isc_mem_create(0, 0, &mctx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mem_create failed %s\n", isc_result_totext(isc_result)); return(T_UNRESOLVED); } isc_result = isc_entropy_create(mctx, &ectx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_entropy_create failed %s\n", isc_result_totext(isc_result)); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (isc_result != ISC_R_SUCCESS) { t_info("isc_hash_create failed %s\n", isc_result_totext(isc_result)); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = t_create(db_type, origin, class, model, mctx, &db); if (dns_result != ISC_R_SUCCESS) { isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_db_load(db, filename); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_load returned %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } /* * Remove all rdata for an existing name. */ dns_fixedname_init(&dns_existingname); len = strlen(existing_name); isc_buffer_init(&name_buffer, existing_name, len); isc_buffer_add(&name_buffer, len); dns_result = dns_name_fromtext(dns_fixedname_name(&dns_existingname), &name_buffer, NULL, 0, NULL); if (dns_result != ISC_R_SUCCESS) { t_info("dns_name_fromtext failed %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } textregion.base = existing_type; textregion.length = strlen(existing_type); dns_result = dns_rdatatype_fromtext(&existing_rdatatype, &textregion); if (dns_result != ISC_R_SUCCESS) { t_info("dns_rdatatype_fromtext %s failed %s\n", existing_type, dns_result_totext(dns_result)); dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } nodep = NULL; dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_existingname), ISC_FALSE, &nodep); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_findnode %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } /* open a new version */ nversionp = NULL; dns_result = dns_db_newversion(db, &nversionp); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_newversion failed %s\n", dns_result_totext(dns_result)); dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_db_deleterdataset(db, nodep, nversionp, existing_rdatatype, 0); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_deleterdataset failed %s\n", dns_result_totext(dns_result)); dns_db_closeversion(db, &nversionp, ISC_FALSE); dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } /* * add a new name and associate some rdata with it */ dns_db_detachnode(db, &nodep); nodep = NULL; dns_fixedname_init(&dns_newname); len = strlen(new_name); isc_buffer_init(&name_buffer, new_name, len); isc_buffer_add(&name_buffer, len); dns_result = dns_name_fromtext(dns_fixedname_name(&dns_newname), &name_buffer, NULL, 0, NULL); if (dns_result != ISC_R_SUCCESS) { t_info("dns_name_fromtext failed %s\n", dns_result_totext(dns_result)); dns_db_closeversion(db, &nversionp, ISC_FALSE); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_newname), ISC_TRUE, &nodep); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_findnode failed %s\n", dns_result_totext(dns_result)); dns_db_closeversion(db, &nversionp, ISC_FALSE); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } /* * associate some rdata with the new name */ textregion.base = new_type; textregion.length = strlen(new_type); dns_result = dns_rdatatype_fromtext(&new_rdatatype, &textregion); if (dns_result != ISC_R_SUCCESS) { t_info("dns_rdatatype_fromtext %s failed %s\n", new_type, dns_result_totext(dns_result)); dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } textregion.base = class; textregion.length = strlen(class); dns_result = dns_rdataclass_fromtext(&rdataclass, &textregion); if (dns_result != ISC_R_SUCCESS) { t_info("dns_rdataclass_fromtext failed %s\n", dns_result_totext(dns_result)); dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_rdata_init(&added_rdata); added_rdata_data = "\x10\x00\x00\x01"; DE_CONST(added_rdata_data, added_rdata.data); added_rdata.length = 4; added_rdata.rdclass = rdataclass; added_rdata.type = new_rdatatype; dns_rdatalist_init(&rdatalist); rdatalist.type = new_rdatatype; rdatalist.rdclass = rdataclass; ISC_LIST_APPEND(rdatalist.rdata, &added_rdata, link); dns_rdataset_init(&added_rdataset); dns_result = dns_rdatalist_tordataset(&rdatalist, &added_rdataset); if (dns_result != ISC_R_SUCCESS) { t_info("dns_rdatalist_tordataset failed %s\n", dns_result_totext(dns_result)); dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_db_addrdataset(db, nodep, nversionp, 0, &added_rdataset, 0, NULL); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_addrdataset failed %s\n", dns_result_totext(dns_result)); dns_db_closeversion(db, &nversionp, ISC_FALSE); dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } /* close and commit the version */ dns_db_closeversion(db, &nversionp, ISC_TRUE); dns_db_detachnode(db, &nodep); nodep = NULL; /* open the current version and check changes */ dns_fixedname_init(&dns_foundname); dns_rdataset_init(&found_rdataset); cversionp = NULL; dns_db_currentversion(db, &cversionp); /* find the recently added name and rdata */ dns_result = dns_db_find(db, dns_fixedname_name(&dns_newname), cversionp, new_rdatatype, 0, 0, &nodep, dns_fixedname_name(&dns_foundname), &found_rdataset, NULL); if (dns_result != ISC_R_SUCCESS) { /* XXXWPK NXRRSET ??? reference counting ??? */ t_info("dns_db_find failed %s\n", dns_result_totext(dns_result)); dns_db_closeversion(db, &cversionp, ISC_FALSE); dns_db_detachnode(db, &nodep); if (dns_rdataset_isassociated(&found_rdataset)) dns_rdataset_disassociate(&found_rdataset); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_FAIL); } dns_result = dns_rdataset_first(&found_rdataset); if (dns_result != ISC_R_SUCCESS) { t_info("dns_rdataset_first failed %s\n", dns_result_totext(dns_result)); dns_db_detachnode(db, &nodep); if (dns_rdataset_isassociated(&found_rdataset)) dns_rdataset_disassociate(&found_rdataset); dns_db_closeversion(db, &cversionp, ISC_FALSE); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_FAIL); } /* * Now make sure its what we expect. */ dns_rdata_init(&found_rdata); dns_rdataset_current(&found_rdataset, &found_rdata); rval = dns_rdata_compare(&added_rdata, &found_rdata); if (rval != 0) { t_info("dns_rdata_compare returned %d\n", rval); ++nfails; } /* * Now check the rdata deletion. */ if (dns_rdataset_isassociated(&found_rdataset)) dns_rdataset_disassociate(&found_rdataset); dns_rdataset_init(&found_rdataset); dns_db_detachnode(db, &nodep); nodep = NULL; dns_fixedname_init(&dns_foundname); dns_result = dns_db_find(db, dns_fixedname_name(&dns_existingname), cversionp, existing_rdatatype, 0, 0, &nodep, dns_fixedname_name(&dns_foundname), &found_rdataset, NULL); if ((dns_result != ISC_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) { dns_rdataset_disassociate(&found_rdataset); dns_db_detachnode(db, &nodep); t_info("dns_db_find %s returned %s\n", existing_name, dns_result_totext(dns_result)); ++nfails; } dns_db_closeversion(db, &cversionp, ISC_FALSE); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); if (nfails == 0) result = T_PASS; else result = T_FAIL; return(result); } static void t10(void) { int result; t_assert("dns_db_closeversion", 10, T_REQUIRED, "%s", a10); result = t_eval("dns_db_closeversion_1_data", t_dns_db_closeversion_1, 9); t_result(result); } static const char *a11 = "When versionp points to a read-write version and commit is " "ISC_FALSE, a call to dns_db_closeversion(db, versionp, commit) " "causes all changes made in the version to to be rolled back, " "and returns ISC_R_SUCCESS."; static int t_dns_db_closeversion_2(char **av) { char *filename; char *db_type; char *origin; char *class; char *model; char *new_name; char *new_type; char *existing_name; char *existing_type; int result; int len; int rval; int nfails; dns_db_t *db; isc_result_t dns_result; isc_result_t isc_result; isc_mem_t *mctx; isc_entropy_t *ectx; dns_dbnode_t *nodep; isc_textregion_t textregion; isc_buffer_t name_buffer; dns_fixedname_t dns_newname; dns_fixedname_t dns_foundname; dns_fixedname_t dns_existingname; dns_rdata_t added_rdata = DNS_RDATA_INIT; const char * added_rdata_data; dns_rdataset_t added_rdataset; dns_rdata_t found_rdata = DNS_RDATA_INIT; dns_rdataset_t found_rdataset; dns_rdatatype_t new_rdatatype; dns_rdatatype_t existing_rdatatype; dns_rdataclass_t rdataclass; dns_dbversion_t *nversionp; dns_dbversion_t *cversionp; dns_rdatalist_t rdatalist; filename = T_ARG(0); db_type = T_ARG(1); origin = T_ARG(2); class = T_ARG(3); model = T_ARG(4); new_name = T_ARG(5); new_type = T_ARG(6); existing_name = T_ARG(7); existing_type = T_ARG(8); nfails = 0; db = NULL; mctx = NULL; ectx = NULL; /* * Open a new version, add some data, * remove some data, close with commit, open the current * version and check that changes are present. */ t_info("testing using file %s and name %s\n", filename, new_name); isc_result = isc_mem_create(0, 0, &mctx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mem_create failed %s\n", isc_result_totext(isc_result)); return(T_UNRESOLVED); } isc_result = isc_entropy_create(mctx, &ectx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_entropy_create failed %s\n", isc_result_totext(isc_result)); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (isc_result != ISC_R_SUCCESS) { t_info("isc_hash_create failed %s\n", isc_result_totext(isc_result)); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = t_create(db_type, origin, class, model, mctx, &db); if (dns_result != ISC_R_SUCCESS) { isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_db_load(db, filename); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_load returned %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } /* * Remove all rdata for an existing name. */ dns_fixedname_init(&dns_existingname); len = strlen(existing_name); isc_buffer_init(&name_buffer, existing_name, len); isc_buffer_add(&name_buffer, len); dns_result = dns_name_fromtext(dns_fixedname_name(&dns_existingname), &name_buffer, NULL, 0, NULL); if (dns_result != ISC_R_SUCCESS) { t_info("dns_name_fromtext failed %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } textregion.base = existing_type; textregion.length = strlen(existing_type); dns_result = dns_rdatatype_fromtext(&existing_rdatatype, &textregion); if (dns_result != ISC_R_SUCCESS) { t_info("dns_rdatatype_fromtext %s failed %s\n", existing_type, dns_result_totext(dns_result)); dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } nodep = NULL; dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_existingname), ISC_FALSE, &nodep); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_findnode %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } /* * Open a new version. */ nversionp = NULL; dns_result = dns_db_newversion(db, &nversionp); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_newversion failed %s\n", dns_result_totext(dns_result)); dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_db_deleterdataset(db, nodep, nversionp, existing_rdatatype, 0); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_deleterdataset failed %s\n", dns_result_totext(dns_result)); dns_db_closeversion(db, &nversionp, ISC_FALSE); dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } /* * add a new name and associate some rdata with it */ dns_db_detachnode(db, &nodep); nodep = NULL; dns_fixedname_init(&dns_newname); len = strlen(new_name); isc_buffer_init(&name_buffer, new_name, len); isc_buffer_add(&name_buffer, len); dns_result = dns_name_fromtext(dns_fixedname_name(&dns_newname), &name_buffer, NULL, 0, NULL); if (dns_result != ISC_R_SUCCESS) { t_info("dns_name_fromtext failed %s\n", dns_result_totext(dns_result)); dns_db_closeversion(db, &nversionp, ISC_FALSE); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_newname), ISC_TRUE, &nodep); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_findnode failed %s\n", dns_result_totext(dns_result)); dns_db_closeversion(db, &nversionp, ISC_FALSE); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } textregion.base = new_type; textregion.length = strlen(new_type); dns_result = dns_rdatatype_fromtext(&new_rdatatype, &textregion); if (dns_result != ISC_R_SUCCESS) { t_info("dns_rdatatype_fromtext %s failed %s\n", new_type, dns_result_totext(dns_result)); dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } textregion.base = class; textregion.length = strlen(class); dns_result = dns_rdataclass_fromtext(&rdataclass, &textregion); if (dns_result != ISC_R_SUCCESS) { t_info("dns_rdataclass_fromtext failed %s\n", dns_result_totext(dns_result)); dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_rdata_init(&added_rdata); added_rdata_data = "\x10\x00\x00\x01"; DE_CONST(added_rdata_data, added_rdata.data); added_rdata.length = 4; added_rdata.rdclass = rdataclass; added_rdata.type = new_rdatatype; dns_rdatalist_init(&rdatalist); rdatalist.type = new_rdatatype; rdatalist.rdclass = rdataclass; ISC_LIST_APPEND(rdatalist.rdata, &added_rdata, link); dns_rdataset_init(&added_rdataset); dns_result = dns_rdatalist_tordataset(&rdatalist, &added_rdataset); if (dns_result != ISC_R_SUCCESS) { t_info("dns_rdatalist_tordataset failed %s\n", dns_result_totext(dns_result)); dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_db_addrdataset(db, nodep, nversionp, 0, &added_rdataset, 0, NULL); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_addrdataset failed %s\n", dns_result_totext(dns_result)); dns_db_closeversion(db, &nversionp, ISC_FALSE); dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } /* * Check that our changes took. */ dns_db_detachnode(db, &nodep); nodep = NULL; dns_fixedname_init(&dns_foundname); dns_rdataset_init(&found_rdataset); /* * Find the recently added name and rdata. */ dns_result = dns_db_find(db, dns_fixedname_name(&dns_newname), nversionp, new_rdatatype, 0, 0, &nodep, dns_fixedname_name(&dns_foundname), &found_rdataset, NULL); if ((dns_result == ISC_R_NOTFOUND) || (dns_result == DNS_R_NXDOMAIN) || (dns_result == DNS_R_NXRRSET)) { t_info("dns_db_find failed %s\n", dns_result_totext(dns_result)); dns_db_closeversion(db, &nversionp, ISC_FALSE); dns_db_detachnode(db, &nodep); if (dns_rdataset_isassociated(&found_rdataset)) dns_rdataset_disassociate(&found_rdataset); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_FAIL); } dns_result = dns_rdataset_first(&found_rdataset); if (dns_result != ISC_R_SUCCESS) { t_info("dns_rdataset_first failed %s\n", dns_result_totext(dns_result)); dns_db_detachnode(db, &nodep); if (dns_rdataset_isassociated(&found_rdataset)) dns_rdataset_disassociate(&found_rdataset); dns_db_closeversion(db, &nversionp, ISC_FALSE); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_FAIL); } /* * Now make sure its what we expect. */ dns_rdata_init(&found_rdata); dns_rdataset_current(&found_rdataset, &found_rdata); rval = dns_rdata_compare(&added_rdata, &found_rdata); if (rval != 0) { t_info("dns_rdata_compare returned %d\n", rval); ++nfails; } /* * Now check the rdata deletion. */ if (dns_rdataset_isassociated(&found_rdataset)) dns_rdataset_disassociate(&found_rdataset); dns_rdataset_init(&found_rdataset); dns_db_detachnode(db, &nodep); nodep = NULL; dns_fixedname_init(&dns_foundname); dns_result = dns_db_find(db, dns_fixedname_name(&dns_existingname), nversionp, existing_rdatatype, 0, 0, &nodep, dns_fixedname_name(&dns_foundname), &found_rdataset, NULL); if ((dns_result != ISC_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) { t_info("dns_db_find %s returned %s\n", existing_name, dns_result_totext(dns_result)); if (dns_rdataset_isassociated(&found_rdataset)) dns_rdataset_disassociate(&found_rdataset); dns_db_detachnode(db, &nodep); ++nfails; } /* * Close the version without a commit. */ dns_db_closeversion(db, &nversionp, ISC_FALSE); /* * Open the current version and check changes. */ dns_fixedname_init(&dns_foundname); dns_rdataset_init(&found_rdataset); cversionp = NULL; dns_db_currentversion(db, &cversionp); /* * Find the recently added name and rdata. */ dns_result = dns_db_find(db, dns_fixedname_name(&dns_newname), cversionp, new_rdatatype, 0, 0, &nodep, dns_fixedname_name(&dns_foundname), &found_rdataset, NULL); if ((dns_result != ISC_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) { t_info("dns_db_find %s returned %s\n", new_name, dns_result_totext(dns_result)); dns_rdataset_disassociate(&found_rdataset); dns_db_detachnode(db, &nodep); dns_db_closeversion(db, &cversionp, ISC_FALSE); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_FAIL); } /* * Now check the rdata deletion. */ nodep = NULL; dns_rdataset_init(&found_rdataset); dns_fixedname_init(&dns_foundname); dns_result = dns_db_find(db, dns_fixedname_name(&dns_existingname), cversionp, existing_rdatatype, 0, 0, &nodep, dns_fixedname_name(&dns_foundname), &found_rdataset, NULL); if ((dns_result == ISC_R_NOTFOUND) || (dns_result == DNS_R_NXDOMAIN) || (dns_result == DNS_R_NXRRSET)) { t_info("dns_db_find %s returned %s\n", existing_name, dns_result_totext(dns_result)); dns_rdataset_disassociate(&found_rdataset); dns_db_detachnode(db, &nodep); ++nfails; } dns_db_detachnode(db, &nodep); dns_rdataset_disassociate(&found_rdataset); dns_db_closeversion(db, &cversionp, ISC_FALSE); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); if (nfails == 0) result = T_PASS; else result = T_FAIL; return(result); } static void t11(void) { int result; t_assert("dns_db_closeversion", 11, T_REQUIRED, "%s", a11); result = t_eval("dns_db_closeversion_2_data", t_dns_db_closeversion_2, 9); t_result(result); } static const char *a12 = "A call to dns_db_expirenode() marks as stale all records at node " "which expire at or before 'now'. If 'now' is zero, then the current " "time will be used."; static int t_dns_db_expirenode(char **av) { char *filename; char *db_type; char *origin; char *class; char *existing_name; char *node_xtime; char *find_xtime; char *exp_find_result; int result; int len; dns_db_t *db; isc_result_t dns_result; isc_result_t exp_result; isc_result_t isc_result; isc_mem_t *mctx; isc_entropy_t *ectx; dns_dbnode_t *nodep; isc_buffer_t name_buffer; dns_fixedname_t dns_foundname; dns_fixedname_t dns_existingname; isc_stdtime_t node_expire_time; isc_stdtime_t find_expire_time; isc_stdtime_t now; dns_rdataset_t rdataset; filename = T_ARG(0); db_type = T_ARG(1); origin = T_ARG(2); class = T_ARG(3); existing_name = T_ARG(4); node_xtime = T_ARG(5); find_xtime = T_ARG(6); exp_find_result = T_ARG(7); mctx = NULL; ectx = NULL; /* * Find a node, mark it as stale, do a dns_db_find on the name and * expect it to fail. */ t_info("testing using file %s and name %s\n", filename, existing_name); node_expire_time = (isc_stdtime_t) strtol(node_xtime, NULL, 10); find_expire_time = (isc_stdtime_t) strtol(find_xtime, NULL, 10); exp_result = t_dns_result_fromtext(exp_find_result); isc_stdtime_get(&now); dns_fixedname_init(&dns_existingname); len = strlen(existing_name); isc_buffer_init(&name_buffer, existing_name, len); isc_buffer_add(&name_buffer, len); dns_result = dns_name_fromtext(dns_fixedname_name(&dns_existingname), &name_buffer, NULL, 0, NULL); if (dns_result != ISC_R_SUCCESS) { t_info("dns_name_fromtext failed %s\n", dns_result_totext(dns_result)); return(T_UNRESOLVED); } isc_result = isc_mem_create(0, 0, &mctx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mem_create failed %s\n", isc_result_totext(isc_result)); return(T_UNRESOLVED); } isc_result = isc_entropy_create(mctx, &ectx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_entropy_create failed %s\n", isc_result_totext(isc_result)); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (isc_result != ISC_R_SUCCESS) { t_info("isc_hash_create failed %s\n", isc_result_totext(isc_result)); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } db = NULL; dns_result = t_create(db_type, origin, class, "cache", mctx, &db); if (dns_result != ISC_R_SUCCESS) { isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_db_load(db, filename); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_load returned %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } nodep = NULL; /* * Check that the node is there. */ dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_existingname), ISC_FALSE, &nodep); if (dns_result != ISC_R_SUCCESS) { t_info("unable to find %s\n", existing_name); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } /* * Expire it. */ if (node_expire_time != 0) node_expire_time += now; dns_result = dns_db_expirenode(db, nodep, node_expire_time); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_expirenode failed %s\n", dns_result_totext(dns_result)); dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_FAIL); } dns_fixedname_init(&dns_foundname); dns_rdataset_init(&rdataset); dns_db_detachnode(db, &nodep); nodep = NULL; if (find_expire_time != 0) find_expire_time += now; dns_result = dns_db_find(db, dns_fixedname_name(&dns_existingname), NULL, dns_rdatatype_any, 0, find_expire_time, &nodep, dns_fixedname_name(&dns_foundname), &rdataset, NULL); if (dns_result == exp_result) { result = T_PASS; } else { t_info("dns_db_find %s returned %s\n", existing_name, dns_result_totext(dns_result)); result = T_FAIL; } if ((dns_result != ISC_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN) && (dns_result != DNS_R_NXRRSET)) { /* * Don't need to disassociate the rdataset because * we're searching with dns_rdatatype_any. */ dns_db_detachnode(db, &nodep); } dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(result); } static void t12(void) { int result; t_assert("dns_db_expirenode", 12, T_REQUIRED, "%s", a12); result = t_eval("dns_db_expirenode_data", t_dns_db_expirenode, 8); t_result(result); } static const char *a13 = "If the node name exists, then a call to " "dns_db_findnode(db, name, ISC_FALSE, nodep) initializes nodep " "to point to the node and returns ISC_R_SUCCESS, otherwise " "it returns ISC_R_NOTFOUND."; static int t_dns_db_findnode_1(char **av) { char *filename; char *db_type; char *origin; char *class; char *model; char *find_name; char *find_type; char *expected_result; int result; int len; dns_db_t *db; isc_result_t dns_result; isc_result_t isc_result; isc_mem_t *mctx; isc_entropy_t *ectx; dns_dbnode_t *nodep; isc_buffer_t name_buffer; dns_rdataset_t rdataset; dns_rdatatype_t rdatatype; isc_textregion_t textregion; dns_fixedname_t dns_name; dns_dbversion_t *cversionp; isc_result_t exp_result; filename = T_ARG(0); db_type = T_ARG(1); origin = T_ARG(2); class = T_ARG(3); model = T_ARG(4); find_name = T_ARG(5); find_type = T_ARG(6); expected_result = T_ARG(7); db = NULL; mctx = NULL; ectx = NULL; t_info("testing using file %s and name %s\n", filename, find_name); exp_result = t_dns_result_fromtext(expected_result); textregion.base = find_type; textregion.length = strlen(find_type); dns_result = dns_rdatatype_fromtext(&rdatatype, &textregion); if (dns_result != ISC_R_SUCCESS) { t_info("dns_rdatatype_fromtext %s failed %s\n", find_type, dns_result_totext(dns_result)); return(T_UNRESOLVED); } isc_result = isc_mem_create(0, 0, &mctx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mem_create failed %s\n", isc_result_totext(isc_result)); return(T_UNRESOLVED); } isc_result = isc_entropy_create(mctx, &ectx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_entropy_create failed %s\n", isc_result_totext(isc_result)); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (isc_result != ISC_R_SUCCESS) { t_info("isc_hash_create failed %s\n", isc_result_totext(isc_result)); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = t_create(db_type, origin, class, model, mctx, &db); if (dns_result != ISC_R_SUCCESS) { isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_db_load(db, filename); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_load returned %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } nodep = NULL; dns_fixedname_init(&dns_name); len = strlen(find_name); isc_buffer_init(&name_buffer, find_name, len); isc_buffer_add(&name_buffer, len); dns_result = dns_name_fromtext(dns_fixedname_name(&dns_name), &name_buffer, NULL, 0, NULL); if (dns_result != ISC_R_SUCCESS) { t_info("dns_name_fromtext failed %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_name), ISC_FALSE, &nodep); if (dns_result != exp_result) { t_info("dns_db_findnode failed %s\n", dns_result_totext(dns_result)); if (dns_result == ISC_R_SUCCESS) dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_mem_destroy(&mctx); return(T_FAIL); } /* * if we're expecting the find to succeed and it did, * check that the node has been initialized * by checking for the specified type of rdata * and expecting the search to succeed */ if (dns_result == ISC_R_SUCCESS) { cversionp = NULL; dns_db_currentversion(db, &cversionp); dns_rdataset_init(&rdataset); dns_result = dns_db_findrdataset(db, nodep, cversionp, rdatatype, 0, 0, &rdataset, NULL); if (dns_result == ISC_R_SUCCESS) { dns_rdataset_disassociate(&rdataset); result = T_PASS; } else { t_info("dns_db_findrdataset failed %s\n", dns_result_totext(dns_result)); result = T_FAIL; } dns_db_closeversion(db, &cversionp, ISC_FALSE); dns_db_detachnode(db, &nodep); } else { result = T_PASS; } dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(result); } static void t13(void) { int result; t_assert("dns_db_findnode", 13, T_REQUIRED, "%s", a13); result = t_eval("dns_db_findnode_1_data", t_dns_db_findnode_1, 8); t_result(result); } static const char *a14 = "If the node name does not exist and create is ISC_TRUE, " "then a call to dns_db_findnode(db, name, create, nodep) " "creates the node, initializes nodep to point to the node, " "and returns ISC_R_SUCCESS."; static int t_dns_db_findnode_2(char **av) { char *filename; char *db_type; char *origin; char *class; char *model; char *newname; int nfails; int result; int len; dns_db_t *db; isc_result_t dns_result; isc_result_t isc_result; isc_mem_t *mctx; isc_entropy_t *ectx; dns_dbnode_t *nodep; dns_dbnode_t *newnodep; isc_buffer_t name_buffer; dns_rdataset_t rdataset; dns_fixedname_t dns_name; dns_fixedname_t dns_foundname; dns_dbversion_t *cversionp; filename = T_ARG(0); db_type = T_ARG(1); origin = T_ARG(2); class = T_ARG(3); model = T_ARG(4); newname = T_ARG(5); db = NULL; mctx = NULL; ectx = NULL; nfails = 0; t_info("testing using file %s and name %s\n", filename, newname); isc_result = isc_mem_create(0, 0, &mctx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mem_create failed %s\n", isc_result_totext(isc_result)); return(T_UNRESOLVED); } isc_result = isc_entropy_create(mctx, &ectx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_entropy_create failed %s\n", isc_result_totext(isc_result)); return(T_UNRESOLVED); } isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (isc_result != ISC_R_SUCCESS) { t_info("isc_hash_create failed %s\n", isc_result_totext(isc_result)); return(T_UNRESOLVED); } dns_result = t_create(db_type, origin, class, model, mctx, &db); if (dns_result != ISC_R_SUCCESS) { isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_db_load(db, filename); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_load returned %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } nodep = NULL; dns_fixedname_init(&dns_name); /* * Make sure the name isn't there */ len = strlen(newname); isc_buffer_init(&name_buffer, newname, len); isc_buffer_add(&name_buffer, len); dns_result = dns_name_fromtext(dns_fixedname_name(&dns_name), &name_buffer, NULL, 0, NULL); if (dns_result != ISC_R_SUCCESS) { t_info("dns_name_fromtext returned %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_name), ISC_FALSE, &nodep); if ((dns_result != ISC_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN) && (dns_result != DNS_R_NXRRSET)) { t_info("dns_db_findnode %s\n", dns_result_totext(dns_result)); dns_db_detachnode(db, &nodep); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } /* * Add it. */ dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_name), ISC_TRUE, &nodep); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_findnode %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_FAIL); } /* * Check it. */ newnodep = NULL; dns_rdataset_init(&rdataset); dns_fixedname_init(&dns_foundname); cversionp = NULL; dns_db_currentversion(db, &cversionp); /* * First try dns_db_find DNS_R_NXDOMAIN. */ dns_result = dns_db_find(db, dns_fixedname_name(&dns_name), cversionp, dns_rdatatype_any, 0, 0, &newnodep, dns_fixedname_name(&dns_foundname), &rdataset, NULL); if ((dns_result != ISC_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) { dns_db_detachnode(db, &newnodep); } if (dns_result != DNS_R_NXDOMAIN) { t_info("dns_db_find %s\n", dns_result_totext(dns_result)); ++nfails; } /* * Then try dns_db_findnode ISC_R_SUCCESS. */ dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_name), ISC_FALSE, &newnodep); t_info("dns_db_findnode %s\n", dns_result_totext(dns_result)); if (dns_result == ISC_R_SUCCESS) { dns_db_detachnode(db, &newnodep); } else { t_info("dns_db_findnode %s failed %s\n", newname, dns_result_totext(dns_result)); ++nfails; } dns_db_detachnode(db, &nodep); dns_db_closeversion(db, &cversionp, ISC_FALSE); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); if (nfails == 0) result = T_PASS; else result = T_FAIL; return(result); } static void t14(void) { int result; t_assert("dns_db_findnode", 14, T_REQUIRED, "%s", a14); result = t_eval("dns_db_findnode_2_data", t_dns_db_findnode_2, 6); t_result(result); } static int t_dns_db_find_x(char **av) { char *dbfile; char *dbtype; char *dborigin; char *dbclass; char *dbmodel; char *findname; char *findtype; char *findopts; char *findtime; char *expected_result; int result; int len; int opts; dns_db_t *db; isc_result_t dns_result; isc_result_t isc_result; isc_stdtime_t ftime; isc_stdtime_t now; isc_result_t exp_result; isc_mem_t *mctx; isc_entropy_t *ectx; dns_dbnode_t *nodep; isc_textregion_t textregion; isc_buffer_t findname_buffer; dns_fixedname_t dns_findname; dns_fixedname_t dns_foundname; dns_rdataset_t rdataset; dns_rdatatype_t rdatatype; dns_dbversion_t *cversionp; dbfile = T_ARG(0); dbtype = T_ARG(1); dborigin = T_ARG(2); dbclass = T_ARG(3); dbmodel = T_ARG(4); findname = T_ARG(5); findtype = T_ARG(6); findopts = T_ARG(7); findtime = T_ARG(8); expected_result = T_ARG(9); db = NULL; mctx = NULL; ectx = NULL; opts = 0; t_info("testing using %s, name %s, type %s\n", dbfile, findname, findtype); isc_result = isc_mem_create(0, 0, &mctx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mem_create failed %s\n", isc_result_totext(isc_result)); return(T_UNRESOLVED); } isc_result = isc_entropy_create(mctx, &ectx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_entropy_create failed %s\n", isc_result_totext(isc_result)); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (isc_result != ISC_R_SUCCESS) { t_info("isc_hash_create failed %s\n", isc_result_totext(isc_result)); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = t_create(dbtype, dborigin, dbclass, dbmodel, mctx, &db); if (dns_result != ISC_R_SUCCESS) { isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } dns_result = dns_db_load(db, dbfile); if (dns_result != ISC_R_SUCCESS) { t_info("dns_db_load returned %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } exp_result = t_dns_result_fromtext(expected_result); dns_fixedname_init(&dns_findname); len = strlen(findname); isc_buffer_init(&findname_buffer, findname, len); isc_buffer_add(&findname_buffer, len); dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname), &findname_buffer, NULL, 0, NULL); if (dns_result != ISC_R_SUCCESS) { t_info("dns_name_fromtext failed %s\n", dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } textregion.base = findtype; textregion.length = strlen(findtype); dns_result = dns_rdatatype_fromtext(&rdatatype, &textregion); if (dns_result != ISC_R_SUCCESS) { t_info("dns_rdatatype_fromtext %s failed %s\n", findtype, dns_result_totext(dns_result)); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } if (strstr(findopts, "DNS_DBFIND_GLUEOK")) opts |= DNS_DBFIND_GLUEOK; if (strstr(findopts, "DNS_DBFIND_VALIDATEGLUE")) opts |= DNS_DBFIND_VALIDATEGLUE; isc_stdtime_get(&now); ftime = strtol(findtime, NULL, 10); if (ftime != 0) ftime += now; cversionp = NULL; dns_fixedname_init(&dns_foundname); dns_rdataset_init(&rdataset); if (dns_db_iszone(db)) dns_db_currentversion(db, &cversionp); nodep = NULL; dns_result = dns_db_find(db, dns_fixedname_name(&dns_findname), cversionp, rdatatype, opts, ftime, &nodep, dns_fixedname_name(&dns_foundname), &rdataset, NULL); if (dns_result != exp_result) { t_info("dns_db_find %s %s unexpectedly returned %s, " "expected %s\n", findname, findtype, dns_result_totext(dns_result), dns_result_totext(exp_result)); result = T_FAIL; } else { result = T_PASS; } if ((dns_result != ISC_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) { if ((dns_result != DNS_R_NXRRSET) && (dns_result != DNS_R_ZONECUT)) if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); dns_db_detachnode(db, &nodep); } if (dns_db_iszone(db)) dns_db_closeversion(db, &cversionp, ISC_FALSE); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); return(result); } static const char *a15 = "A call to dns_db_find(db, name, version, type, options, now, ...) " "finds the best match for 'name' and 'type' in version 'version' " "of 'db'."; static void t15(void) { int result; t_assert("dns_db_find", 15, T_REQUIRED, "%s", a15); result = t_eval("dns_db_find_1_data", t_dns_db_find_x, 10); t_result(result); } static const char *a16 = "When the desired node and type were found, but are glue, " "and the DNS_DBFIND_GLUEOK option is set, a call to " "dns_db_find(db, name, version, type, options, now, ...) " "returns DNS_R_GLUE."; static void t16(void) { int result; t_assert("dns_db_find", 16, T_REQUIRED, "%s", a16); result = t_eval("dns_db_find_2_data", t_dns_db_find_x, 10); t_result(result); } static const char *a17 = "A call to dns_db_find() returns DNS_R_DELEGATION when the data " "requested is beneath a zone cut."; static void t17(void) { int result; t_assert("dns_db_find", 17, T_REQUIRED, "%s", a17); result = t_eval("dns_db_find_3_data", t_dns_db_find_x, 10); t_result(result); } static const char *a18 = "A call to dns_db_find() returns DNS_R_DELEGATION when type is " "dns_rdatatype_any and the desired node is a zone cut."; static void t18(void) { int result; t_assert("dns_db_find", 18, T_REQUIRED, "%s", a18); result = t_eval("dns_db_find_4_data", t_dns_db_find_x, 10); t_result(result); } static const char *a19 = "A call to dns_db_find() returns DNS_R_DNAME when the data " "requested is beneath a DNAME."; static void t19(void) { int result; t_assert("dns_db_find", 19, T_REQUIRED, "%s", a19); result = t_eval("dns_db_find_5_data", t_dns_db_find_x, 10); t_result(result); } static const char *a20 = "A call to dns_db_find() returns DNS_R_CNAME when the requested " "rdataset was not found but there is a CNAME at the desired name."; static void t20(void) { int result; t_assert("dns_db_find", 20, T_REQUIRED, "%s", a20); result = t_eval("dns_db_find_6_data", t_dns_db_find_x, 10); t_result(result); } static const char *a21 = "A call to dns_db_find() returns DNS_R_NXDOMAIN when name " "does not exist."; static void t21(void) { int result; t_assert("dns_db_find", 21, T_REQUIRED, "%s", a21); result = t_eval("dns_db_find_7_data", t_dns_db_find_x, 10); t_result(result); } static const char *a22 = "A call to dns_db_find() returns DNS_R_NXRRSET when " "the desired name exists, but the desired type does not."; static void t22(void) { int result; t_assert("dns_db_find", 22, T_REQUIRED, "%s", a22); result = t_eval("dns_db_find_8_data", t_dns_db_find_x, 10); t_result(result); } static const char *a23 = "When db is a cache database, a call to dns_db_find() " "returns ISC_R_NOTFOUND when the desired name does not exist, " "and no delegation could be found."; static void t23(void) { int result; t_assert("dns_db_find", 23, T_REQUIRED, "%s", a23); result = t_eval("dns_db_find_9_data", t_dns_db_find_x, 10); t_result(result); } static const char *a24 = "When db is a cache database, an rdataset will be found only " "if at least one rdataset at the found node expires after 'now'."; static void t24(void) { int result; t_assert("dns_db_find", 24, T_REQUIRED, "%s", a24); result = t_eval("dns_db_find_10_data", t_dns_db_find_x, 10); t_result(result); } static const char *a25 = "A call to dns_db_load(db, filename) returns DNS_R_NOTZONETOP " "when the zone data contains a SOA not at the zone apex."; static void t25(void) { int result; t_assert("dns_db_load", 25, T_REQUIRED, "%s", a25); result = t_eval("dns_db_load_soa_not_top", t_dns_db_load, 9); t_result(result); } testspec_t T_testlist[] = { { (PFV) t1, "dns_db_load" }, { (PFV) t2, "dns_db_iscache" }, { (PFV) t3, "dns_db_iscache" }, { (PFV) t4, "dns_db_iszone" }, { (PFV) t5, "dns_db_iszone" }, { (PFV) t6, "dns_db_origin" }, { (PFV) t7, "dns_db_class" }, { (PFV) t8, "dns_db_currentversion" }, { (PFV) t9, "dns_db_newversion" }, { (PFV) t10, "dns_db_closeversion" }, { (PFV) t11, "dns_db_closeversion" }, { (PFV) t12, "dns_db_expirenode" }, { (PFV) t13, "dns_db_findnode" }, { (PFV) t14, "dns_db_findnode" }, { (PFV) t15, "dns_db_find" }, { (PFV) t16, "dns_db_find" }, { (PFV) t17, "dns_db_find" }, { (PFV) t18, "dns_db_find" }, { (PFV) t19, "dns_db_find" }, { (PFV) t20, "dns_db_find" }, { (PFV) t21, "dns_db_find" }, { (PFV) t22, "dns_db_find" }, { (PFV) t23, "dns_db_find" }, { (PFV) t24, "dns_db_find" }, { (PFV) t25, "dns_db_load" }, { (PFV) 0, NULL } }; #ifdef WIN32 int main(int argc, char **argv) { t_settests(T_testlist); return (t_main(argc, argv)); } #endif bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_currentversion_data0000644000470500017500000000022412664710322023203 0ustar lamontlamont# # test data for dns_db_currentversion # # format: # filename findname findtype # dns_db_currentversion.data rbt vix.com. IN zone a.b.c.vix.com. A bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_find_5_data0000644000470500017500000000046012664710322021261 0ustar lamontlamont# # test data for dns_db_find DNS_R_DNAME # # format: # dbfile dbtype dborigin dbclass dbcache findname findtype findopts findtime expected_results # dns_db_find_5.data rbt vix.com. in zone x.a.b.c.vix.com. ANY 0 0 DNS_R_DNAME dns_db_find_5.data rbt vix.com. in zone a.a.b.c.vix.com. ANY 0 0 DNS_R_DNAME bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_load_data0000644000470500017500000000025512664710322021036 0ustar lamontlamont# # test data for dns_db_load # # format: # filename type origin cache class findname expected_result # dns_db_load_1.data rbt . zone in ISC_R_SUCCESS a. A DNS_R_DELEGATION bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_find_6_data0000644000470500017500000000046212664710322021264 0ustar lamontlamont# # test data for dns_db_find DNS_R_CNAME # # format: # dbfile dbtype dborigin dbclass dbcache findname findtype findopts findtime expected_results # dns_db_find_6.data rbt vix.com. in zone exploder.vix.com. A 0 0 DNS_R_CNAME dns_db_find_6.data rbt vix.com. in zone exploder.vix.com. ANY 0 0 ISC_R_SUCCESS bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_class_data0000644000470500017500000000016112664710322021220 0ustar lamontlamont# # test data for dns_db_class # # format: # filename class # # dns_db_class_1.data in # dns_db_class_1.data any bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_origin_1.data0000644000470500017500000000036012664710322021542 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a in ns ns.vix.com. a in ns ns2.vix.com. a in ns ns3.vix.com. b in a 1.2.3.4 bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_iszone_1_data0000644000470500017500000000016312664710322021644 0ustar lamontlamont# # test data for dns_db_iszone test 1 # # format: # filename db_type origin class # dns_db_iszone_1.data rbt . in bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_load_25.data0000644000470500017500000000023512664710322021261 0ustar lamontlamont$TTL 5 @ IN SOA ns1 hostmaster 1 3600 1200 3600000 3600 @ IN NS ns1 ns1 IN A 10.0.0.1 sub IN SOA ns2 hostmaster 1 3600 1200 3600000 3600 ns2 IN A 10.0.0.2 bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_find_1.data0000644000470500017500000000037712664710322021203 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a in ns ns.vix.com. a in ns ns2.vix.com. a in ns ns3.vix.com. b in a 1.2.3.4 a.b.c in ns b bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_newversion_data0000644000470500017500000000024212664710322022312 0ustar lamontlamont# # test data for dns_db_newversion # # format: # filename type origin class cache newname newtype # dns_db_newversion.data rbt vix.com. in zone a.b.c.vix.com. A bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_find_4_data0000644000470500017500000000035312664710322021261 0ustar lamontlamont# # test data for dns_db_find DNS_R_DELEGATION # # format: # dbfile dbtype dborigin dbclass dbcache findname findtype findopts findtime expected_results # dns_db_find_4.data rbt vix.com. in zone a.b.c.vix.com. ANY 0 0 DNS_R_DELEGATION bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_find_9_data0000644000470500017500000000034712664710322021271 0ustar lamontlamont# # test data for dns_db_find ISC_R_NOTFOUND # # format: # dbfile dbtype dborigin dbclass dbcache findname findtype findopts findtime expected_results # dns_db_find_9.data rbt vix.com. in cache a.b.c.vix.com. NS 0 0 ISC_R_NOTFOUND bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_findnode_1_data0000644000470500017500000000052512664710322022125 0ustar lamontlamont# # test data for dns_db_findnode, case ISC_R_SUCCESS # # format: # filename type origin class cache existingname rdatatype # dns_db_findnode_1.data rbt vix.com. in zone a.vix.com. NS ISC_R_SUCCESS dns_db_findnode_1.data rbt vix.com. in zone b.vix.com. A ISC_R_SUCCESS dns_db_findnode_1.data rbt vix.com. in zone c.vix.com. A ISC_R_NOTFOUND bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_find_7_data0000644000470500017500000000034712664710322021267 0ustar lamontlamont# # test data for dns_db_find DNS_R_NXDOMAIN # # format: # dbfile dbtype dborigin dbclass dbcache findname findtype findopts findtime expected_results # dns_db_find_7.data rbt vix.com. in zone a.b.c.vix.com. ANY 0 0 DNS_R_NXDOMAIN bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_find_2_data0000644000470500017500000000064012664710322021256 0ustar lamontlamont# # test data for dns_db_find DNS_R_GLUE # # format: # dbfile dbtype dborigin dbclass dbcache findname findtype findopts findtime expected_results # dns_db_find_2.data rbt vix.com. in zone a.fx.vix.com. A DNS_DBFIND_GLUEOK 0 DNS_R_GLUE dns_db_find_2.data rbt vix.com. in zone fx.vix.com. NS DNS_DBFIND_GLUEOK 0 DNS_R_GLUE dns_db_find_2.data rbt vix.com. in zone a.fx.vix.com. NS DNS_DBFIND_GLUEOK 0 DNS_R_DELEGATION bind9-9.10.3.dfsg.P4/bin/tests/db/win32/0002755000470500017500000000000012664730167016645 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/tests/db/win32/t_db.vcxproj.in0000644000470500017500000001532012664710322021565 0ustar lamontlamont Debug @PLATFORM@ Release @PLATFORM@ {E6338E67-3224-4E66-9463-7AD719DA9346} Win32Proj t_db Application true MultiByte Application false true MultiByte true ..\..\..\..\Build\$(Configuration)\ .\$(Configuration)\ false ..\..\..\..\Build\$(Configuration)\ .\$(Configuration)\ Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb true .\;..\..\..\..\;@LIBXML2_INC@..\..\..\..\lib\isc\win32;..\..\..\..\lib\isc\win32\include;..\..\..\..\lib\isc\include;..\..\..\..\lib\dns\include;..\..\..\..\lib\isccfg\include;..\..\..\..\lib\tests\include;%(AdditionalIncludeDirectories) Console true ..\..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) ..\..\..\..\lib\isc\win32\$(Configuration);..\..\..\..\lib\dns\win32\$(Configuration);..\..\..\..\lib\isccfg\win32\$(Configuration);..\..\..\..\lib\tests\win32\$(Configuration);%(AdditionalLibraryDirectories) @LIBXML2_LIB@libisc.lib;libdns.lib;libisccfg.lib;libtests.lib;ws2_32.lib;%(AdditionalDependencies) Level3 MaxSpeed true @INTRINSIC@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) OnlyExplicitInline false true .\$(Configuration)\$(TargetName).pch .\$(Configuration)\ .\$(Configuration)\ $(OutDir)$(TargetName).pdb .\;..\..\..\..\;@LIBXML2_INC@..\..\..\..\lib\isc\win32;..\..\..\..\lib\isc\win32\include;..\..\..\..\lib\isc\include;..\..\..\..\lib\dns\include;..\..\..\..\lib\isccfg\include;..\..\..\..\lib\tests\include;%(AdditionalIncludeDirectories) Console false true true ..\..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt) Default ..\..\..\..\lib\isc\win32\$(Configuration);..\..\..\..\lib\dns\win32\$(Configuration);..\..\..\..\lib\isccfg\win32\$(Configuration);..\..\..\..\lib\tests\win32\$(Configuration);%(AdditionalLibraryDirectories) @LIBXML2_LIB@libisc.lib;libdns.lib;libisccfg.lib;libtests.lib;ws2_32.lib;%(AdditionalDependencies) bind9-9.10.3.dfsg.P4/bin/tests/db/win32/t_db.dsw0000644000470500017500000000102512664710322020257 0ustar lamontlamontMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "t_db"=".\t_db.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### bind9-9.10.3.dfsg.P4/bin/tests/db/win32/t_db.dsp.in0000644000470500017500000001127112664710322020661 0ustar lamontlamont# Microsoft Developer Studio Project File - Name="t_db" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "@PLATFORM@ (x86) Console Application" 0x0103 CFG=t_db - @PLATFORM@ Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "t_db.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "t_db.mak" CFG="t_db - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "t_db - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "t_db - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "t_db - @PLATFORM@ Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 @COPTX@ @COPTI@ /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD CPP /nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../../" @LIBXML2_INC@ /I "../../../../lib/isc/win32" /I "../../../../lib/isc/win32/include" /I "../../../../lib/isc/include" /I "../../../../lib/dns/win32/include" /I "../../../../lib/dns/include" /I "../../../../lib/isccfg/include" /I "../../../../lib/tests/include" /D "WIN32" /D "NDEBUG" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console @MACHINE@ # ADD LINK32 @LIBXML2_LIB@ user32.lib advapi32.lib kernel32.lib ws2_32.lib ../../../../lib/isc/win32/Release/libisc.lib ../../../../lib/dns/win32/Release/libdns.lib ../../../../lib/isccfg/win32/Release/libisccfg.lib ../../../../lib/tests/win32/Release/libtests.lib /nologo /subsystem:console @MACHINE@ /out:"../../../../Build/Release/t_db.exe" !ELSEIF "$(CFG)" == "t_db - @PLATFORM@ Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" @COPTY@ /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../../" @LIBXML2_INC@ /I "../../../../lib/isc/win32" /I "../../../../lib/isc/win32/include" /I "../../../../lib/isc/include" /I "../../../../lib/dns/win32/include" /I "../../../../lib/dns/include" /I "../../../../lib/isccfg/include" /I "../../../../lib/tests/include" /I "../../../../lib/bind9/include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "i386" /FR /FD /GZ /c # SUBTRACT CPP /X @COPTY@ # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug @MACHINE@ /pdbtype:sept # ADD LINK32 @LIBXML2_LIB@ user32.lib advapi32.lib kernel32.lib ws2_32.lib ../../../../lib/isc/win32/Debug/libisc.lib ../../../../lib/dns/win32/Debug/libdns.lib ../../../../lib/isccfg/win32/Release/libisccfg.lib ../../../../lib/tests/win32/Debug/libtests.lib /nologo /subsystem:console /map /debug @MACHINE@ /out:"../../../../Build/Debug/t_db.exe" /pdbtype:sept !ENDIF # Begin Target # Name "t_db - @PLATFORM@ Release" # Name "t_db - @PLATFORM@ Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\t_db.c # End Source File # End Group # End Target # End Project bind9-9.10.3.dfsg.P4/bin/tests/db/win32/t_db.vcxproj.filters.in0000644000470500017500000000167212664710322023241 0ustar lamontlamont {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Source Files bind9-9.10.3.dfsg.P4/bin/tests/db/win32/t_db.vcxproj.user0000644000470500017500000000021712664710322022134 0ustar lamontlamont bind9-9.10.3.dfsg.P4/bin/tests/db/win32/t_db.mak.in0000644000470500017500000003053712664710322020651 0ustar lamontlamont# Microsoft Developer Studio Generated NMAKE File, Based on t_db.dsp !IF "$(CFG)" == "" CFG=t_db - @PLATFORM@ Debug !MESSAGE No configuration specified. Defaulting to t_db - @PLATFORM@ Debug. !ENDIF !IF "$(CFG)" != "t_db - @PLATFORM@ Release" && "$(CFG)" != "t_db - @PLATFORM@ Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "t_db.mak" CFG="t_db - @PLATFORM@ Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "t_db - @PLATFORM@ Release" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE "t_db - @PLATFORM@ Debug" (based on "@PLATFORM@ (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF CPP=cl.exe RSC=rc.exe LIBXML=@LIBXML2_LIB@ !IF "$(CFG)" == "t_db - @PLATFORM@ Release" _VC_MANIFEST_INC=0 _VC_MANIFEST_BASENAME=__VC80 !ELSE _VC_MANIFEST_INC=1 _VC_MANIFEST_BASENAME=__VC80.Debug !ENDIF #################################################### # Specifying name of temporary resource file used only in incremental builds: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_AUTO_RES=$(_VC_MANIFEST_BASENAME).auto.res !else _VC_MANIFEST_AUTO_RES= !endif #################################################### # _VC_MANIFEST_EMBED_EXE - command to embed manifest in EXE: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1 !endif #################################################### # _VC_MANIFEST_EMBED_DLL - command to embed manifest in DLL: !if "$(_VC_MANIFEST_INC)" == "1" #MT_SPECIAL_RETURN=1090650113 #MT_SPECIAL_SWITCH=-notify_resource_update MT_SPECIAL_RETURN=0 MT_SPECIAL_SWITCH= _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -out:$(_VC_MANIFEST_BASENAME).auto.manifest $(MT_SPECIAL_SWITCH) & \ if "%ERRORLEVEL%" == "$(MT_SPECIAL_RETURN)" \ rc /r $(_VC_MANIFEST_BASENAME).auto.rc & \ link $** /out:$@ $(LFLAGS) !else _VC_MANIFEST_EMBED_EXE= \ if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2 !endif #################################################### # _VC_MANIFEST_CLEAN - command to clean resources files generated temporarily: !if "$(_VC_MANIFEST_INC)" == "1" _VC_MANIFEST_CLEAN=-del $(_VC_MANIFEST_BASENAME).auto.res \ $(_VC_MANIFEST_BASENAME).auto.rc \ $(_VC_MANIFEST_BASENAME).auto.manifest !else _VC_MANIFEST_CLEAN= !endif !IF "$(CFG)" == "t_db - @PLATFORM@ Release" OUTDIR=.\Release INTDIR=.\Release !IF "$(RECURSE)" == "0" ALL : "..\..\..\..\Build\Release\t_db.exe" !ELSE ALL : "libtests - @PLATFORM@ Release" "libisccfg - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" "libdns - @PLATFORM@ Release" "..\..\..\..\Build\Release\t_db.exe" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libdns - @PLATFORM@ ReleaseCLEAN" "libisc - @PLATFORM@ ReleaseCLEAN" "libtests - @PLATFORM@ ReleaseCLEAN" "libisccfg - @PLATFORM@ ReleaseCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\t_db.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "..\..\..\..\Build\Release\t_db.exe" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MD /W3 @COPTX@ @COPTI@ /O2 /I "./" /I "../../../../" @LIBXML2_INC@ /I "../../../../lib/isc/win32" /I "../../../../lib/isc/win32/include" /I "../../../../lib/isc/include" /I "../../../../lib/dns/win32/include" /I "../../../../lib/dns/include" /I "../../../../lib/isccfg/include" /I "../../../../lib/tests/include" /D "WIN32" /D "NDEBUG" /D "__STDC__" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\t_db.pch" @COPTY@ /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\t_db.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib kernel32.lib ws2_32.lib ../../../../lib/isc/win32/Release/libisc.lib ../../../../lib/dns/win32/Release/libdns.lib ../../../../lib/isccfg/win32/Release/libisccfg.lib ../../../../lib/tests/win32/Release/libtests.lib $(LIBXML) /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\t_db.pdb" @MACHINE@ /out:"../../../../Build/Release/t_db.exe" LINK32_OBJS= \ "$(INTDIR)\t_db.obj" \ "..\..\..\..\lib\dns\win32\Release\libdns.lib" \ "..\..\..\..\lib\isc\win32\Release\libisc.lib" \ "..\..\..\..\lib\isccfg\win32\Release\libisccfg.lib" \ "..\..\..\..\lib\tests\win32\Release\libtests.lib" "..\..\..\..\Build\Release\t_db.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ELSEIF "$(CFG)" == "t_db - @PLATFORM@ Debug" OUTDIR=.\Debug INTDIR=.\Debug # Begin Custom Macros OutDir=.\Debug # End Custom Macros !IF "$(RECURSE)" == "0" ALL : "..\..\..\..\Build\Debug\t_db.exe" "$(OUTDIR)\t_db.bsc" !ELSE ALL : "libtests - @PLATFORM@ Debug" "libisccfg - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" "libdns - @PLATFORM@ Debug" "..\..\..\..\Build\Debug\t_db.exe" "$(OUTDIR)\t_db.bsc" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"libdns - @PLATFORM@ DebugCLEAN" "libisc - @PLATFORM@ DebugCLEAN" "libtests - @PLATFORM@ DebugCLEAN" "libisccfg - @PLATFORM@ DebugCLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\t_db.obj" -@erase "$(INTDIR)\t_db.sbr" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\t_db.bsc" -@erase "$(OUTDIR)\t_db.map" -@erase "$(OUTDIR)\t_db.pdb" -@erase "..\..\..\..\Build\Debug\t_db.exe" -@erase "..\..\..\..\Build\Debug\t_db.ilk" -@$(_VC_MANIFEST_CLEAN) "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MDd /W3 /Gm @COPTX@ @COPTI@ /ZI /Od /I "./" /I "../../../../" @LIBXML2_INC@ /I "../../../../lib/isc/win32" /I "../../../../lib/isc/win32/include" /I "../../../../lib/isc/include" /I "../../../../lib/dns/win32/include" /I "../../../../lib/dns/include" /I "../../../../lib/isccfg/include" /I "../../../../lib/tests/include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "i386" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\t_db.bsc" BSC32_SBRS= \ "$(INTDIR)\t_db.sbr" "$(OUTDIR)\t_db.bsc" : "$(OUTDIR)" $(BSC32_SBRS) $(BSC32) @<< $(BSC32_FLAGS) $(BSC32_SBRS) << LINK32=link.exe LINK32_FLAGS=user32.lib advapi32.lib kernel32.lib ws2_32.lib ../../../../lib/isc/win32/Debug/libisc.lib ../../../../lib/dns/win32/Debug/libdns.lib ../../../../lib/isccfg/win32/Debug/libisccfg.lib ../../../../lib/tests/win32/Debug/libtests.lib $(LIBXML) /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\t_db.pdb" /map:"$(INTDIR)\t_db.map" /debug @MACHINE@ /out:"../../../../Build/Debug/t_db.exe" /pdbtype:sept LINK32_OBJS= \ "$(INTDIR)\t_db.obj" \ "..\..\..\..\lib\dns\win32\Debug\libdns.lib" \ "..\..\..\..\lib\isc\win32\Debug\libisc.lib" \ "..\..\..\..\lib\isccfg\win32\Debug\libisccfg.lib" \ "..\..\..\..\lib\tests\win32\Debug\libtests.lib" "..\..\..\..\Build\Debug\t_db.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << $(_VC_MANIFEST_EMBED_EXE) !ENDIF .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << !IF "$(NO_EXTERNAL_DEPS)" != "1" !IF EXISTS("t_db.dep") !INCLUDE "t_db.dep" !ELSE !MESSAGE Warning: cannot find "t_db.dep" !ENDIF !ENDIF !IF "$(CFG)" == "t_db - @PLATFORM@ Release" || "$(CFG)" == "t_db - @PLATFORM@ Debug" SOURCE=..\t_db.c !IF "$(CFG)" == "t_db - @PLATFORM@ Release" "$(INTDIR)\t_db.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "t_db - @PLATFORM@ Debug" "$(INTDIR)\t_db.obj" "$(INTDIR)\t_db.sbr" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF !IF "$(CFG)" == "t_db - @PLATFORM@ Release" "libdns - @PLATFORM@ Release" : cd "..\..\..\..\lib\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" cd "..\..\..\bin\tests\db\win32" "libdns - @PLATFORM@ ReleaseCLEAN" : cd "..\..\..\..\lib\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\..\bin\tests\db\win32" !ELSEIF "$(CFG)" == "t_db - @PLATFORM@ Debug" "libdns - @PLATFORM@ Debug" : cd "..\..\..\..\lib\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" cd "..\..\..\bin\tests\db\win32" "libdns - @PLATFORM@ DebugCLEAN" : cd "..\..\..\..\lib\dns\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libdns.mak" CFG="libdns - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\..\bin\tests\db\win32" !ENDIF !IF "$(CFG)" == "t_db - @PLATFORM@ Release" "libisc - @PLATFORM@ Release" : cd "..\..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" cd "..\..\..\bin\tests\db\win32" "libisc - @PLATFORM@ ReleaseCLEAN" : cd "..\..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\..\bin\tests\db\win32" !ELSEIF "$(CFG)" == "t_db - @PLATFORM@ Debug" "libisc - @PLATFORM@ Debug" : cd "..\..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" cd "..\..\..\bin\tests\db\win32" "libisc - @PLATFORM@ DebugCLEAN" : cd "..\..\..\..\lib\isc\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisc.mak" CFG="libisc - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\..\bin\tests\db\win32" !ENDIF !IF "$(CFG)" == "t_db - @PLATFORM@ Release" "libisccfg - @PLATFORM@ Release" : cd "..\..\..\..\lib\isccfg\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Release" cd "..\..\..\bin\tests\db\win32" "libisccfg - @PLATFORM@ ReleaseCLEAN" : cd "..\..\..\..\lib\isccfg\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\..\bin\tests\db\win32" !ELSEIF "$(CFG)" == "t_db - @PLATFORM@ Debug" "libisccfg - @PLATFORM@ Debug" : cd "..\..\..\..\lib\isccfg\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Debug" cd "..\..\..\bin\tests\db\win32" "libisccfg - @PLATFORM@ DebugCLEAN" : cd "..\..\..\..\lib\isccfg\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libisccfg.mak" CFG="libisccfg - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\..\bin\tests\db\win32" !ENDIF !IF "$(CFG)" == "t_db - @PLATFORM@ Release" "libtests - @PLATFORM@ Release" : cd "..\..\..\..\lib\tests\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libtests.mak" CFG="libtests - @PLATFORM@ Release" cd "..\..\..\bin\tests\db\win32" "libtests - @PLATFORM@ ReleaseCLEAN" : cd "..\..\..\..\lib\tests\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libtests.mak" CFG="libtests - @PLATFORM@ Release" RECURSE=1 CLEAN cd "..\..\..\bin\tests\db\win32" !ELSEIF "$(CFG)" == "t_db - @PLATFORM@ Debug" "libtests - @PLATFORM@ Debug" : cd "..\..\..\..\lib\tests\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libtests.mak" CFG="libtests - @PLATFORM@ Debug" cd "..\..\..\bin\tests\db\win32" "libtests - @PLATFORM@ DebugCLEAN" : cd "..\..\..\..\lib\tests\win32" $(MAKE) /$(MAKEFLAGS) /F ".\libtests.mak" CFG="libtests - @PLATFORM@ Debug" RECURSE=1 CLEAN cd "..\..\..\bin\tests\db\win32" !ENDIF !ENDIF #################################################### # Commands to generate initial empty manifest file and the RC file # that references it, and for generating the .res file: $(_VC_MANIFEST_BASENAME).auto.res : $(_VC_MANIFEST_BASENAME).auto.rc $(_VC_MANIFEST_BASENAME).auto.rc : $(_VC_MANIFEST_BASENAME).auto.manifest type <<$@ #include 1RT_MANIFEST"$(_VC_MANIFEST_BASENAME).auto.manifest" << KEEP $(_VC_MANIFEST_BASENAME).auto.manifest : type <<$@ << KEEP bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_find_10.data0000644000470500017500000000031612664710322021254 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a.b.c in NS ns1.vix.com. a.b.c in A 1.2.3.4 bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_iscache_2.data0000644000470500017500000000036012664710322021653 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a in ns ns.vix.com. a in ns ns2.vix.com. a in ns ns3.vix.com. b in a 1.2.3.4 bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_origin_data0000644000470500017500000000016512664710322021406 0ustar lamontlamont# # test data for dns_db_origin # # format: # filename origin # dns_db_origin_1.data . dns_db_origin_1.data vix.com. bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_find_5.data0000644000470500017500000000031412664710322021176 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a.b.c in DNAME x.y.z a.x.y.z in A 1.2.3.4 bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_iscache_1_data0000644000470500017500000000016512664710322021736 0ustar lamontlamont# # test data for dns_db_iscache test 1 # # format: # filename db_type origin class # dns_db_iscache_1.data rbt . in bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_find_8_data0000644000470500017500000000034412664710322021265 0ustar lamontlamont# # test data for dns_db_find DNS_R_NXRRSET # # format: # dbfile dbtype dborigin dbclass dbcache findname findtype findopts findtime expected_results # dns_db_find_8.data rbt vix.com. in zone a.b.c.vix.com. NS 0 0 DNS_R_NXRRSET bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_iszone_1.data0000644000470500017500000000036012664710322021562 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a in ns ns.vix.com. a in ns ns2.vix.com. a in ns ns3.vix.com. b in a 1.2.3.4 bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_closeversion_1_data0000644000470500017500000000033312664710322023047 0ustar lamontlamont# # test data for dns_db_closeversion test 1 # # format: # filename type origin class cache new_name new_type existing_name existing_type # dns_db_closeversion_1.data rbt vix.com. in zone a.b.c.vix.com. A a.vix.com. NS bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_newversion.data0000644000470500017500000000036012664710322022232 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a in ns ns.vix.com. a in ns ns2.vix.com. a in ns ns3.vix.com. b in a 1.2.3.4 bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_find_8.data0000644000470500017500000000036312664710322021205 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a.b.c.d in A 1.2.3.4 a.b.c in A 1.2.3.4 a.b in A 1.2.3.4 a in NS ns1.vix.com. bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_find_3.data0000644000470500017500000000032612664710322021177 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a.b.c in ns b a.a.b.c in a 10.0.0.1 b in a 10.0.0.2 bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_closeversion_1.data0000644000470500017500000000036012664710322022766 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a in ns ns.vix.com. a in ns ns2.vix.com. a in ns ns3.vix.com. b in a 1.2.3.4 bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_closeversion_2.data0000644000470500017500000000036012664710322022767 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a in ns ns.vix.com. a in ns ns2.vix.com. a in ns ns3.vix.com. b in a 1.2.3.4 bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_findnode_1.data0000644000470500017500000000036012664710322022041 0ustar lamontlamont$TTL 1000 @ in soa localhost. postmaster.localhost. ( 1993050801 ;serial 3600 ;refresh 1800 ;retry 604800 ;expiration 3600 ) ;minimum a in ns ns.vix.com. a in ns ns2.vix.com. a in ns ns3.vix.com. b in a 1.2.3.4 bind9-9.10.3.dfsg.P4/bin/tests/db/dns_db_iszone_2_data0000644000470500017500000000016312664710322021645 0ustar lamontlamont# # test data for dns_db_iszone test 2 # # format: # filename db_type origin class # dns_db_iszone_2.data rbt . in bind9-9.10.3.dfsg.P4/bin/tests/headerdep_test.sh.in0000644000470500017500000000306212664710322021225 0ustar lamontlamont#!/bin/sh # # Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000, 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: headerdep_test.sh.in,v 1.8 2007/06/19 23:46:59 tbox Exp $ # # Check the installed bind9 headers to make sure that no header # depends on another header having been included first. # prefix=@prefix@ tmp=/tmp/thdr$$.tmp status=0 echo "Checking for header interdependencies..." # Make a list of header files. (cd $prefix/include; find . -name '*.h' -print | sed 's!^./!!') > $tmp # Check each header. while read h do echo " - <$h>" # Build a test program. cat <test.c #include <$h> EOF # Compile the test program. if gcc @STD_CWARNINGS@ @STD_CINCLUDES@ -I$prefix/include -c test.c 2>&1 then : else status=1 fi done <$tmp rm -f test.c test.o $tmp exit $status bind9-9.10.3.dfsg.P4/bin/tests/rwlock_test.c0000644000470500017500000001000712664710322020005 0ustar lamontlamont/* * Copyright (C) 2004, 2005, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: rwlock_test.c,v 1.26 2007/06/19 23:46:59 tbox Exp $ */ #include #include #include #include #include #include #include #include #include #ifdef WIN32 #define sleep(x) Sleep(1000 * x) #endif #ifdef ISC_PLATFORM_USETHREADS isc_rwlock_t lock; static isc_threadresult_t #ifdef WIN32 WINAPI #endif run1(void *arg) { char *message = arg; RUNTIME_CHECK(isc_rwlock_lock(&lock, isc_rwlocktype_read) == ISC_R_SUCCESS); printf("%s got READ lock\n", message); sleep(1); printf("%s giving up READ lock\n", message); RUNTIME_CHECK(isc_rwlock_unlock(&lock, isc_rwlocktype_read) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_rwlock_lock(&lock, isc_rwlocktype_read) == ISC_R_SUCCESS); printf("%s got READ lock\n", message); sleep(1); printf("%s giving up READ lock\n", message); RUNTIME_CHECK(isc_rwlock_unlock(&lock, isc_rwlocktype_read) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_rwlock_lock(&lock, isc_rwlocktype_write) == ISC_R_SUCCESS); printf("%s got WRITE lock\n", message); sleep(1); printf("%s giving up WRITE lock\n", message); RUNTIME_CHECK(isc_rwlock_unlock(&lock, isc_rwlocktype_write) == ISC_R_SUCCESS); return ((isc_threadresult_t)0); } static isc_threadresult_t #ifdef WIN32 WINAPI #endif run2(void *arg) { char *message = arg; RUNTIME_CHECK(isc_rwlock_lock(&lock, isc_rwlocktype_write) == ISC_R_SUCCESS); printf("%s got WRITE lock\n", message); sleep(1); printf("%s giving up WRITE lock\n", message); RUNTIME_CHECK(isc_rwlock_unlock(&lock, isc_rwlocktype_write) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_rwlock_lock(&lock, isc_rwlocktype_write) == ISC_R_SUCCESS); printf("%s got WRITE lock\n", message); sleep(1); printf("%s giving up WRITE lock\n", message); RUNTIME_CHECK(isc_rwlock_unlock(&lock, isc_rwlocktype_write) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_rwlock_lock(&lock, isc_rwlocktype_read) == ISC_R_SUCCESS); printf("%s got READ lock\n", message); sleep(1); printf("%s giving up READ lock\n", message); RUNTIME_CHECK(isc_rwlock_unlock(&lock, isc_rwlocktype_read) == ISC_R_SUCCESS); return ((isc_threadresult_t)0); } int main(int argc, char *argv[]) { unsigned int nworkers; unsigned int i; isc_thread_t workers[100]; char name[100]; void *dupname; if (argc > 1) nworkers = atoi(argv[1]); else nworkers = 2; if (nworkers > 100) nworkers = 100; printf("%d workers\n", nworkers); RUNTIME_CHECK(isc_rwlock_init(&lock, 5, 10) == ISC_R_SUCCESS); for (i = 0; i < nworkers; i++) { sprintf(name, "%02u", i); dupname = strdup(name); RUNTIME_CHECK(dupname != NULL); if (i != 0 && i % 3 == 0) RUNTIME_CHECK(isc_thread_create(run1, dupname, &workers[i]) == ISC_R_SUCCESS); else RUNTIME_CHECK(isc_thread_create(run2, dupname, &workers[i]) == ISC_R_SUCCESS); } for (i = 0; i < nworkers; i++) (void)isc_thread_join(workers[i], NULL); isc_rwlock_destroy(&lock); return (0); } #else int main(int argc, char *argv[]) { UNUSED(argc); UNUSED(argv); fprintf(stderr, "This test requires threads.\n"); return(1); } #endif bind9-9.10.3.dfsg.P4/bin/tests/serial_test.c0000644000470500017500000000300112664710322017757 0ustar lamontlamont/* * Copyright (C) 2004, 2007, 2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: serial_test.c,v 1.15 2007/06/19 23:46:59 tbox Exp $ */ #include #include #include #include #include int main() { isc_uint32_t a, b; char buf[1024]; char *s, *e; while (fgets(buf, sizeof(buf), stdin) != NULL) { buf[sizeof(buf) - 1] = '\0'; s = buf; a = strtoul(s, &e, 0); if (s == e) continue; s = e; b = strtoul(s, &e, 0); if (s == e) continue; fprintf(stdout, "%u %u gt:%d lt:%d ge:%d le:%d eq:%d ne:%d\n", a, b, isc_serial_gt(a,b), isc_serial_lt(a,b), isc_serial_ge(a,b), isc_serial_le(a,b), isc_serial_eq(a,b), isc_serial_ne(a,b)); } return (0); } bind9-9.10.3.dfsg.P4/bin/tests/dst/0002755000470500017500000000000012672612753016107 5ustar lamontlamontbind9-9.10.3.dfsg.P4/bin/tests/dst/Ktest.+003+49667.key.in0000644000470500017500000000003212664710322021350 0ustar lamontlamonttest. IN DNSKEY 49152 2 3 bind9-9.10.3.dfsg.P4/bin/tests/dst/Ktest.+001+54622.key.in0000644000470500017500000000021112664710322021330 0ustar lamontlamonttest. IN DNSKEY 257 3 1 AQPQjwSpaVzxIgRCpiUoozUQKGh2oX8NIFKDOvtxK+tn536OZg2cROKTlgGEHXJK9YHfW/6nzQULTVpb63P+SQMmjCCidb8IYyhItixRztVeJQ== bind9-9.10.3.dfsg.P4/bin/tests/dst/Kdh.+002+18602.key.in0000644000470500017500000000024012664710322020745 0ustar lamontlamontdh. IN KEY 0 2 2 AAEBAAAAYIHI/wjtOagNga9GILSoS02IVelgLilPE/TfhtvShsiDAXqb IfxQcj2JkuOnNLs5ttb2WZXWl5/jsSjIxHMwMF2XY4gwt/lwHBf/vgYH r7aIxnKXov1jk9rymTLHGKIOtg== bind9-9.10.3.dfsg.P4/bin/tests/dst/Makefile.in0000644000470500017500000000474412664710322020153 0ustar lamontlamont# Copyright (C) 2004, 2006-2010, 2012-2014 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1999-2002 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id: Makefile.in,v 1.52 2010/12/24 23:47:05 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ @BIND9_MAKE_INCLUDES@ CINCLUDES = ${TEST_INCLUDES} ${DNS_INCLUDES} \ ${ISC_INCLUDES} @DST_GSSAPI_INC@ CDEFINES = @USE_GSSAPI@ CWARNINGS = DNSLIBS = ../../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ ISCLIBS = ../../../lib/isc/libisc.@A@ DNSDEPLIBS = ../../../lib/dns/libdns.@A@ ISCDEPLIBS = ../../../lib/isc/libisc.@A@ DEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS} LIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@ TLIB = ../../../lib/tests/libt_api.@A@ TARGETS = dst_test@EXEEXT@ t_dst@EXEEXT@ gsstest@EXEEXT@ SRCS = dst_test.c t_dst.c gsstest.c @BIND9_MAKE_RULES@ dst_test@EXEEXT@: dst_test.@O@ ${DEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ dst_test.@O@ ${LIBS} t_dst@EXEEXT@: t_dst.@O@ ${DEPLIBS} ${TLIB} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ t_dst.@O@ ${TLIB} ${LIBS} gsstest@EXEEXT@: gsstest.@O@ ${DEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ gsstest.@O@ ${LIBS} test: t_dst@EXEEXT@ randomfile ../../tools/genrandom@EXEEXT@ 100 randomfile -@ ./t_dst@EXEEXT@ -q 1800 -a randomfile: ../../tools/genrandom@EXEEXT@ 100 randomfile clean distclean:: rm -f ${TARGETS} randomfile distclean:: rm -f Kdh.+002+18602.key rm -f Kdh.+002+18602.private rm -f Kdh.+002+48957.key rm -f Kdh.+002+48957.private rm -f Ktest.+001+00002.key rm -f Ktest.+001+54622.key rm -f Ktest.+001+54622.private rm -f Ktest.+003+23616.key rm -f Ktest.+003+23616.private rm -f Ktest.+003+49667.key rm -f dst_2_data rm -f t2_data_1 rm -f t2_data_2 rm -f t2_dsasig rm -f t2_rsasig bind9-9.10.3.dfsg.P4/bin/tests/dst/Kdh.+002+48957.private.in0000644000470500017500000000075612664710322021663 0ustar lamontlamontPrivate-key-format: v1.2 Algorithm: 2 (DH) Prime(p): ///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxObIlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjo2IP////////// Generator(g): Ag== Private_value(x): WJG0moh+QoZV+DYhqW7Z6O6TYpYGtSlN0Ym6JV6VRnzeH69OqMUFivqZorj3a3ofR/4zogNVyy5KLLj2NFTaLGP4Hcvt7uETJik6HrjLMhGf40QPXYgVK57Im0rv88Ca Public_value(y): 65oqPIxdhqZ7YXr9kV0SZe/RrZ50H7r08RmCsTEDpImWK+fgqoCx8Eev/7QEJv7ud9Z4wNKHYFedLNaRcXXAxoIcy7P0SV4bWAoUp5VD2AqWLzwJvz+Nui9YKGsYE2nb bind9-9.10.3.dfsg.P4/bin/tests/dst/Ktest.+001+54622.private.in0000644000470500017500000000120512664710322022216 0ustar lamontlamontPrivate-key-format: v1.2 Algorithm: 1 (RSA) Modulus: 0I8EqWlc8SIEQqYlKKM1EChodqF/DSBSgzr7cSvrZ+d+jmYNnETik5YBhB1ySvWB31v+p80FC01aW+tz/kkDJowgonW/CGMoSLYsUc7VXiU= PublicExponent: Aw== PrivateExponent: iwoDG5uTS2wC1xluGxd4tXBFpGuqCMA3AidSS3Kc7++ptEQJEtiXC9kfCJMvZhGfQLaujft2OgrmkcuDVtPIbQWEENhyJhb4Lk82kFXbfus= Prime1: /rSKuzcZY7R5cY2YWD4CiBNyj9WJMq1wWmBnb9+5M08nTl5E9NW5qQ== Prime2: 0Z5shXQYd16E2Gs6e5WxtO0Oqlly2KkSqXohwTQWDWTb8Pw0WTZmHQ== Exponent1: qc2x0iS7l82mS7O65X6sWrehtTkGIcj1kZWaSpUmIjTE3umDTePRGw== Exponent2: i77zA6K6+j8DOvIm/Q52eJ4JxuZMkHC3G6bBK3gOs5iSoKgi5iREEw== Coefficient: 3+wYZB0SJad7z2EsjzgbSlg6CawoaOvrROGSbwSiW5DCsMFROudOTw== bind9-9.10.3.dfsg.P4/bin/tests/dst/t2_data_2.in0000644000470500017500000035726512664710322020206 0ustar lamontlamontNetwork Working Group P. Mockapetris Request for Comments: 1035 ISI November 1987 Obsoletes: RFCs 882, 883, 973 DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION 1. STATUS OF THIS MEMO This RFC describes the details of the domain system and protocol, and assumes that the reader is familiar with the concepts discussed in a companion RFC, "Domain Names - Concepts and Facilities" [RFC-4301]. The domain system is a mixture of functions and data types which are an official protocol and functions and data types which are still experimental. Since the domain system is intentionally extensible, new data types and experimental behavior should always be expected in parts of the system beyond the official protocol. The official protocol parts include standard queries, responses and the Internet class RR data formats (e.g., host addresses). Since the previous RFC set, several definitions have changed, so some previous definitions are obsolete. Experimental or obsolete features are clearly marked in these RFCs, and such information should be used with caution. The reader is especially cautioned not to depend on the values which appear in examples to be current or complete, since their purpose is primarily pedagogical. Distribution of this memo is unlimited. Table of Contents 1. STATUS OF THIS MEMO 1 2. INTRODUCTION 3 2.1. Overview 3 2.2. Common configurations 4 2.3. Conventions 7 2.3.1. Preferred name syntax 7 2.3.2. Data Transmission Order 8 2.3.3. Character Case 9 2.3.4. Size limits 10 3. DOMAIN NAME SPACE AND RR DEFINITIONS 10 3.1. Name space definitions 10 3.2. RR definitions 11 3.2.1. Format 11 3.2.2. TYPE values 12 3.2.3. QTYPE values 12 3.2.4. CLASS values 13 Mockapetris [Page 1] RFC 1035 Domain Implementation and Specification November 1987 3.2.5. QCLASS values 13 3.3. Standard RRs 13 3.3.1. CNAME RDATA format 14 3.3.2. HINFO RDATA format 14 3.3.3. MB RDATA format (EXPERIMENTAL) 14 3.3.4. MD RDATA format (Obsolete) 15 3.3.5. MF RDATA format (Obsolete) 15 3.3.6. MG RDATA format (EXPERIMENTAL) 16 3.3.7. MINFO RDATA format (EXPERIMENTAL) 16 3.3.8. MR RDATA format (EXPERIMENTAL) 17 3.3.9. MX RDATA format 17 3.3.10. NULL RDATA format (EXPERIMENTAL) 17 3.3.11. NS RDATA format 18 3.3.12. PTR RDATA format 18 3.3.13. SOA RDATA format 19 3.3.14. TXT RDATA format 20 3.4. ARPA Internet specific RRs 20 3.4.1. A RDATA format 20 3.4.2. WKS RDATA format 21 3.5. IN-ADDR.ARPA domain 22 3.6. Defining new types, classes, and special namespaces 24 4. MESSAGES 25 4.1. Format 25 4.1.1. Header section format 26 4.1.2. Question section format 28 4.1.3. Resource record format 29 4.1.4. Message compression 30 4.2. Transport 32 4.2.1. UDP usage 32 4.2.2. TCP usage 32 5. MASTER FILES 33 5.1. Format 33 5.2. Use of master files to define zones 35 5.3. Master file example 36 6. NAME SERVER IMPLEMENTATION 37 6.1. Architecture 37 6.1.1. Control 37 6.1.2. Database 37 6.1.3. Time 39 6.2. Standard query processing 39 6.3. Zone refresh and reload processing 39 6.4. Inverse queries (Optional) 40 6.4.1. The contents of inverse queries and responses 40 6.4.2. Inverse query and response example 41 6.4.3. Inverse query processing 42 Mockapetris [Page 2] RFC 1035 Domain Implementation and Specification November 1987 6.5. Completion queries and responses 42 7. RESOLVER IMPLEMENTATION 43 7.1. Transforming a user request into a query 43 7.2. Sending the queries 44 7.3. Processing responses 46 7.4. Using the cache 47 8. MAIL SUPPORT 47 8.1. Mail exchange binding 48 8.2. Mailbox binding (Experimental) 48 9. REFERENCES and BIBLIOGRAPHY 50 Index 54 2. INTRODUCTION 2.1. Overview The goal of domain names is to provide a mechanism for naming resources in such a way that the names are usable in different hosts, networks, protocol families, internets, and administrative organizations. From the user's point of view, domain names are useful as arguments to a local agent, called a resolver, which retrieves information associated with the domain name. Thus a user might ask for the host address or mail information associated with a particular domain name. To enable the user to request a particular type of information, an appropriate query type is passed to the resolver with the domain name. To the user, the domain tree is a single information space; the resolver is responsible for hiding the distribution of data among name servers from the user. From the resolver's point of view, the database that makes up the domain space is distributed among various name servers. Different parts of the domain space are stored in different name servers, although a particular data item will be stored redundantly in two or more name servers. The resolver starts with knowledge of at least one name server. When the resolver processes a user query it asks a known name server for the information; in return, the resolver either receives the desired information or a referral to another name server. Using these referrals, resolvers learn the identities and contents of other name servers. Resolvers are responsible for dealing with the distribution of the domain space and dealing with the effects of name server failure by consulting redundant databases in other servers. Name servers manage two kinds of data. The first kind of data held in sets called zones; each zone is the complete database for a particular "pruned" subtree of the domain space. This data is called authoritative. A name server periodically checks to make sure that its zones are up to date, and if not, obtains a new copy of updated zones Mockapetris [Page 3] RFC 1035 Domain Implementation and Specification November 1987 from master files stored locally or in another name server. The second kind of data is cached data which was acquired by a local resolver. This data may be incomplete, but improves the performance of the retrieval process when non-local data is repeatedly accessed. Cached data is eventually discarded by a timeout mechanism. This functional structure isolates the problems of user interface, failure recovery, and distribution in the resolvers and isolates the database update and refresh problems in the name servers. 2.2. Common configurations A host can participate in the domain name system in a number of ways, depending on whether the host runs programs that retrieve information from the domain system, name servers that answer queries from other hosts, or various combinations of both functions. The simplest, and perhaps most typical, configuration is shown below: Local Host | Foreign | +---------+ +----------+ | +--------+ | | user queries | |queries | | | | User |-------------->| |---------|->|Foreign | | Program | | Resolver | | | Name | | |<--------------| |<--------|--| Server | | | user responses| |responses| | | +---------+ +----------+ | +--------+ | A | cache additions | | references | V | | +----------+ | | cache | | +----------+ | User programs interact with the domain name space through resolvers; the format of user queries and user responses is specific to the host and its operating system. User queries will typically be operating system calls, and the resolver and its cache will be part of the host operating system. Less capable hosts may choose to implement the resolver as a subroutine to be linked in with every program that needs its services. Resolvers answer user queries with information they acquire via queries to foreign name servers and the local cache. Note that the resolver may have to make several queries to several different foreign name servers to answer a particular user query, and hence the resolution of a user query may involve several network accesses and an arbitrary amount of time. The queries to foreign name servers and the corresponding responses have a standard format described Mockapetris [Page 4] RFC 1035 Domain Implementation and Specification November 1987 in this memo, and may be datagrams. Depending on its capabilities, a name server could be a stand alone program on a dedicated machine or a process or processes on a large timeshared host. A simple configuration might be: Local Host | Foreign | +---------+ | / /| | +---------+ | +----------+ | +--------+ | | | | |responses| | | | | | | Name |---------|->|Foreign | | Master |-------------->| Server | | |Resolver| | files | | | |<--------|--| | | |/ | | queries | +--------+ +---------+ +----------+ | Here a primary name server acquires information about one or more zones by reading master files from its local file system, and answers queries about those zones that arrive from foreign resolvers. The DNS requires that all zones be redundantly supported by more than one name server. Designated secondary servers can acquire zones and check for updates from the primary server using the zone transfer protocol of the DNS. This configuration is shown below: Local Host | Foreign | +---------+ | / /| | +---------+ | +----------+ | +--------+ | | | | |responses| | | | | | | Name |---------|->|Foreign | | Master |-------------->| Server | | |Resolver| | files | | | |<--------|--| | | |/ | | queries | +--------+ +---------+ +----------+ | A |maintenance | +--------+ | +------------|->| | | queries | |Foreign | | | | Name | +------------------|--| Server | maintenance responses | +--------+ In this configuration, the name server periodically establishes a virtual circuit to a foreign name server to acquire a copy of a zone or to check that an existing copy has not changed. The messages sent for Mockapetris [Page 5] RFC 1035 Domain Implementation and Specification November 1987 these maintenance activities follow the same form as queries and responses, but the message sequences are somewhat different. The information flow in a host that supports all aspects of the domain name system is shown below: Local Host | Foreign | +---------+ +----------+ | +--------+ | | user queries | |queries | | | | User |-------------->| |---------|->|Foreign | | Program | | Resolver | | | Name | | |<--------------| |<--------|--| Server | | | user responses| |responses| | | +---------+ +----------+ | +--------+ | A | cache additions | | references | V | | +----------+ | | Shared | | | database | | +----------+ | A | | +---------+ refreshes | | references | / /| | V | +---------+ | +----------+ | +--------+ | | | | |responses| | | | | | | Name |---------|->|Foreign | | Master |-------------->| Server | | |Resolver| | files | | | |<--------|--| | | |/ | | queries | +--------+ +---------+ +----------+ | A |maintenance | +--------+ | +------------|->| | | queries | |Foreign | | | | Name | +------------------|--| Server | maintenance responses | +--------+ The shared database holds domain space data for the local name server and resolver. The contents of the shared database will typically be a mixture of authoritative data maintained by the periodic refresh operations of the name server and cached data from previous resolver requests. The structure of the domain data and the necessity for synchronization between name servers and resolvers imply the general characteristics of this database, but the actual format is up to the local implementor. Mockapetris [Page 6] RFC 1035 Domain Implementation and Specification November 1987 Information flow can also be tailored so that a group of hosts act together to optimize activities. Sometimes this is done to offload less capable hosts so that they do not have to implement a full resolver. This can be appropriate for PCs or hosts which want to minimize the amount of new network code which is required. This scheme can also allow a group of hosts can share a small number of caches rather than maintaining a large number of separate caches, on the premise that the centralized caches will have a higher hit ratio. In either case, resolvers are replaced with stub resolvers which act as front ends to resolvers located in a recursive server in one or more name servers known to perform that service: Local Hosts | Foreign | +---------+ | | | responses | | Stub |<--------------------+ | | Resolver| | | | |----------------+ | | +---------+ recursive | | | queries | | | V | | +---------+ recursive +----------+ | +--------+ | | queries | |queries | | | | Stub |-------------->| Recursive|---------|->|Foreign | | Resolver| | Server | | | Name | | |<--------------| |<--------|--| Server | +---------+ responses | |responses| | | +----------+ | +--------+ | Central | | | cache | | +----------+ | In any case, note that domain components are always replicated for reliability whenever possible. 2.3. Conventions The domain system has several conventions dealing with low-level, but fundamental, issues. While the implementor is free to violate these conventions WITHIN HIS OWN SYSTEM, he must observe these conventions in ALL behavior observed from other hosts. 2.3.1. Preferred name syntax The DNS specifications attempt to be as general as possible in the rules for constructing domain names. The idea is that the name of any existing object can be expressed as a domain name with minimal changes. Mockapetris [Page 7] RFC 1035 Domain Implementation and Specification November 1987 However, when assigning a domain name for an object, the prudent user will select a name which satisfies both the rules of the domain system and any existing rules for the object, whether these rules are published or implied by existing programs. For example, when naming a mail domain, the user should satisfy both the rules of this memo and those in RFC-822. When creating a new host name, the old rules for HOSTS.TXT should be followed. This avoids problems when old software is converted to use domain names. The following syntax will result in fewer problems with many applications that use domain names (e.g., mail, TELNET). ::= | " " ::=

6bD*'!fAD?+ND=3Mi9"?MgJ;EgS++6'Z\kah=\ZaKE %>qL]\o+SkL%Ve?e:dI!M3@W#_fab53O5pUM8``NiE/$+F;C4PJr2qhQ^T+uD %)F0k\QuIs63*=-u1]oLXrpGZ.?6)XV`8.3Q0ta@,lMOLJ9'STKoerGa>KM6RkNg"\?iT$(qQKo&B0t)rZ>Wthh&!`8lbQtiSd$%M %`(SLI=DZ2@3(X=XlK4/sl_q8rWK5$ihAb1CW`]'63$[\Ki%.J!=Yn?a?m+<.jJgo:#(#VmmI20)jHG(K,*aj#1l_Vmp %T0Q"c!\C2$/(WD9r+n3TT(t&UEmIt$YM-%E.)VqH96&3lIdA0de,5Cb[[ %KZpTOh-d4anYMoT>4f_oi8ku&^Xiqd]XXGu=X.2/Fs!hY1b^Et\;4-p!*n-PbQj_='QWZBOQ2Amk9L.,fhZj\jV0+f/*9g`5Pi>8 %Q4gXeo;DKT/CgL$\l9B2Qn0p@TW[N(Bk$2l59q(DH;K;Gb1pL;L!*]0?7K5m;O%jY\`:cqhs6;L6[o8EkiX";I=)5j4sqZ\4DM/& %ai!1^97Rj?cn]qZ<(b`H/WEq)kUunH>=SfHa;AmW]9gT8![[.!Vqa9`G+(%Zk0#4\/2u4:sX@+B:1B"hb,mGTG98 %#0jskP!,oRW+45qf'f/YLu7"dbL.P(_?Q81pEOQha75gC_?uc_Xd^V_E5t7pL$u"G%d$d4g28k(50;7OUf=AfkDF6T?DPE'1H'!S %oIequ$='3F"pK3co\dG^J0,?QYlKD%,@2OA?U8Mo;R_e'GC*4Ebor%5EQ=.fQPT+9cm@"&[nC,#^t8Pil3iDuJ_T7N"DC:(]AEuc4PtpRPU9VejD)1/CXMp/[%sIU'M#`aB)*Db@ZYGNd+Ikp=$%)VZHWGS7qgl%7XPY2$#s_7\fCWZnWS]9g$YWOc %@]@<`<10Ner3&.O(>OK&E,ON--Q;;!mD7Qb?p!<,(T\*$.9,&j"NQKYSh*+N)t'uuGFO:>/4ugdpXc40 %k9n33Gf+scf1un"5n!(kmHD?:$=7nB`dE3o06UaB7I(G,XoO+0cinr9_&h]8QrCDXS+\V,L$9;-+Qlcj-:^\RE7[Z'C[S#g3J]\]Mo)2RToM1PI'OiM"lf!]:d %/l6`_H4l+\ZNE1:WtrC#0SduI=Td8j`YmTU_ca)1>3r1F_=m=>Mb8Rg:39@g]6Bs0S,>kQ6$3Y_hc#"*i'2.n.8X< %:2"6^bcI+"GeL)cl^cN6G+T$LU.V-FJfO[[_n`QUFPc%,.b(9)_\'=JrV34!]G@A %3A[)]r$h&(du;-LYZV1m6HppQ!IJOjF%;a/Nbs:_H;J\C1sYZscX5(oYeAJq\r/,.BAF\\0)Y=6--*ae?#_r!PT[<9aQa^+?+8Cl %dUXQqZ-PdgCF(g!$WPt_(UG"$:knCq0SC:G-aZMKf9NeV$U\mP4Jd3-?fkMqe%>o5.c/u_cP5BI_rpVj^8dFjSpGt#'m"Tq;DpL9 %/JH0A[+!q*0^ORg4MD@^%fH[Y&aRm`; %^CQK?Dp,bCSWa<4k.!0mbeWPDri]-DYM=FU_90)=?!!`uGN;eV2l2$*n+d\l_&/HI]QPtqm3Vi];MV>\)(1;ejsge-E&/?E]@8Eq %5H[b7!QL,E">KcH#1&6Z?;lDb8BpE*;FQNFc5@kC*5GrJTP>:X=*OlDh#@@*jYF0e<0PR+"k?AeirH'#7,2^lF='EnGV_'b"aOa\ %iq0&M-)[d<=WYX:))T6AY"#V`Cc^4OD^;4>C(W4X_finOG;H1Lr %1)E&a/9,=6+NflhA`U-Jkb3F%!%@:g(F9etH-WU*d+j'@?H58>G@k`X[jaHnf?XjJ[`sU.m %n*Y\>_5t%UA!OlN%%OTs?UfY&I&u_(A[p?6P!fm!"3#X:4ZKV`)hH%SD[Po`pG_laX78rI&LMu?L?mhjFj^V(H>9'^=hF0rj.q(p %5;`n9I",$4k>>^P6#Op0pV$Eo?NRedS]QAq_5)Id3_=\5WG#"/.$6<^SGDf%Ca%/Ebn%gAl.*U;J@KC`k`1Lu;20&rT1).YeULqk9:>*%b %2-J\7VZ4q<&/JNVohuTka&VZubAfnbR9pEbg6\?fP[r.=k8.Bu(c+,IP`Cc_`aL07?Ic)?ZZI4s@Wnd6.GXsW?ch%0/5BQ3B3?I)85ZZ#?`\4:j\Pg9LpjuXIa$@R>mo;!/HqE`bW!JV6DoWW3[cV:J %%bsZGq;4*c_/LpHXabii0Mh@se;_/<:0epqp!=Ng;M]\S2').mQgPGcq<]#Has"FXIVD7YNm3<*n*@%V&*[6%`b/#p--Qg<4ZjcG %7:D':,N9X--bfJ(VJ#:u"5N^q&33&bA'Y^)Ag_KLG2LL%=jXKjcR99lIFY1PT0;U$UB4\d]V:he %@AD#)QE:a!gaZ:]530sfm?k\'$u31jmY6!=([H.Y/@"dBh7u'iBoTeMh4uMEkRP_h_;(S\hdE*>MO3&&A(X/5a(LcO$`^>m&P!R>Q6581K!o<%VF>E%.*oJdir?7unYaDucu)d$i>dl`05IUhmb.T6j;u %/']#\X!J4I!->>8GcBL/Sot3sOl&7k@+M`M-.ipm\!CpDiS&ROUAFcVlS]DHpCf8"FeTBL-=j?sJc_&=AfBhFnUT"bDMNp_^oBXOh;jl(m._hUoE'8)sE^)/)-K4WHj)U6\;'-Yk,qlM2S&2-`j]DD]f9,m&\r7 %Ip;6s]?`/EDH4W%6&f:T=o5D*DQ?brPf1[jV;6qb.;]o041*M1]Qc_PEc"9^ %37@cd0BM,S7F'.(;b7<2+3YFQ/*ui,;.^_a^YNPJD5_.7XX),&Fu&YD(ruj2"\F?30[M+>FT!`JL7;f^DAR*<I^oOOHP_sk? %I`9abp@]#:3Vd`M=gtf\ED(lU!*.\"9ps\b)e2!#=iUMoC[;`3MND %3Cij1-&'-,eqPgC_<[eX?Q4+u]@!LtdGUkhjerp%KMoGYf0r#O3/;"qQ %i;X'Z#qZ6>aJ-$#.=X"Al+j0RGm(S#pHXsi\*u;CjBW5=o0^?ggh:XJ5ZoqRK1fgs<#0MkRYBN^5;$FJgen$iO&d)DS?m"M+j@Rq9/h)>Q>9VJ#k\Q, %keL@H]J%&X_F7fS=iI_9E[K.]6GNc>5ipO-/`ijN.-QHFXRYeC/@o!G0H*I9&fq0hB&V`t(rN@6T*f2UVh1N3q)&Jg1,p](<&IE7 %a]-4b41D&!E]fc-nL^\r'j#DoQl-`BWbZ$JKlmbX8+0(9V__jJYAS9uJplKVA&oLm;.%BmZ;CbYinpot>hLe'I4%On;1SK9OF#EK %J.Y$9Jm%DF??OB>c6AkAiqU[*U0E=1N,'^OZkp'aX)L4ue[EALi!'LDN@TXF %hDIk7@4@2HGH9HoN@Ht<_\)arFP-aAd(U[PtF*,0AuBc,e]jt0&7^4CoC:\VE_ %1do@/CL;cRBY?ae/KK\O%?<&ACiEa"4/CZ(\=^r58O;$=O*#WMBsY>]fbWoF>^38d8FCkY:!M;qoD1fqWXE5L0b'5^0qHj*6F9\A %K.lRA*`+5f>uE0jRVJ\g:9nGU.T:dbO:,m8Rp>'QhK[kCq_qCi\XE6+cX@_3N=47(qNT+?5_T&c.d;@"Gh_,+R<^[,\FE4:XF6F( %^8-;%TTm+H$26$ZJO)#^kKG:Vn,U2N1?].*Oc0&i`$1VuM8f(AQuYcA5DnjmNf<._#r@!ZJI89;j,]G\m80po_P-i%0uJIAp6TV= %A$d0=_Mu3M>E$l@()*``)6PnA;NPcRie]/l#L;V:q1UbfMaJf54/* %P_dLT3L&/i\iJc2l1"[9-S_#efR\310ZM.&$=Gs7-\TuC`q4rNB8!<`ZWX_o':Q=mEgq)!6Xc&WL)1Z3HNF`hZ)NOaH#j)6-YmZ/25KUN_[Rb[J6I*!ob`JAe$%#rqbjJ89W7oqP50]"HCqq9?-C!TTHQE3S7jRnF&u)/$i>^Wl%]Q9\qNIAh\9P %C1=OkB\Q4hW4#4Q)mY,c:IZ,0ASX!$l0hM0EY]uq_IfiXE?46Dn&ec:UF.;$Vic)*nn>+,'1-/9dE)9Kc;& %=Sre"!IH,=5:jCa<'_3%%?N"pV\l/0:<$$'>aVh7A1ekHI2V8WS9L,]Se4s=+Muepa6I3l<$cTkUhOPARsAI`P6:A*1@^PoZ^,$2 %MH^?G:efKHn&W^oj;)OsAEh$VbU0)h]?i*VYbAA"2s"7D+A*$T9%keMF9Mq".g>69D(eGC0M8g_X=)Fj:Sn9mMEi6$:)jlfs/\oV9$.SP3qUD1+Wu\pm(6IOQ$[>T^KShpkS!XpbZEIRU2p\D.E=1oZGm6N<7-7So9QlHc)S+r %$o[nfaL7a3ZK7!N%%ECmE6H9!U72`.].d!E1Cd4*7.T#SZ"@JSB25FZ#Y[1Ia^c!@]4Te*.e-,u!VLnP"*9[p3?ph5Y,'#I!RB_OWEMiJ$p`tQ*[jmR2p7ZCNoUh/.)Tkd %/CAW.*]l`L88$F3L0ib$'%niFmQ=Y=ju<[q@%"tMP5G(`!Z7ATB=c^AMAqZ9.82?g,/,*W>[@/ADoE4_!X*R?!?FOZm/h]in1cJ?QB[T&IEKfso>bcneU!a1&aFGb3`#8O=/C^i/1hKb'# %jXC#%U(Uc*&"ml+rkMLTPnRG_[jV3Q;ElWS,d#%K5I`+-'GmoAd)`.:8o"&OaNlsT-o`TYK'.L[%mUJX?l=/r/j'86@*sqPYXeN2 %I),he?=_BJ\F=ic``@B9#K.E7La3pF(Z>L'q?6A.T-L\2:d'K'iNMqa1GgNGk4ldPEh?%5,KjP+(aRS+HDcr7cok[FL4$7P=O*$H %Q\\OaJRrj^C".3*I&4]QEqp)J@<@\,)K?YmRU4p[hNs1jo9`X(WB#/gJ;fsbl&2a+%_%,(#Y:T8HY=V=2 %!(Cd"Z'DrR,P`@s?Ys3%Y<1].od?#V1ft^;>^`jLg?sX`Y,u0*bJ/UI9(nnZ.Po6109RR_>h2&]Zf&6S+ua&0CUFi_56][S %r?d%_HnD-NbMWr%VtV*e*Mp&tMD&c$[sDm-lg;ZIT*JC1q_[6r>gj^Wa1I,7XBQ^.-kL*D5he"h"!b`G44``XljOKT&Df3)]>UV* %dG>]WA-"`j,".,YUK"ESK2Y>9pK+#6;;CVRT8W(gbm6c %')iUH!Y6Ar_*;;SQRiJ5cg1kgX>*L3&5g']Cfg,)N=9bboB'&5T4RaF.Z5f]BfHHC"2ca9G0QR)H9ASF!#8U3,"+u`87"G25H"^2WCiSQ$XWC?ZNFKYNedRRY$XjRg\62uU?T)_c %MIjn'?o3@fQd:C4GZnNX4O-O)Ziq_d9&1BCIN\GF3E](Ip6a_8i!g)j\LVduu&MV7&"_jX]%s_+gFHf+h'4[[Rp-bTf+P %gidRAR.c;%[q!!hjVt#?,LiI>mutC8:LoM2\p5KpL><$9e^XD)j1U>%e[;dg<@(SMX"p=rG1l>3#-Z?`+3CgQIDUpcTZh]B#'9+4 %=!5CU&k1T`fOY?hq"6AZ=`?/I^M7K.X@1,bT'Sbq7gr^r<30u]NP-mQ2%@"b8'8:M'^'QPK=.>8)mHaj'IV.dkSIM$IHkB$[C4/` %m,/eSLg+#D`HWi][1'R=>$buMSEdulr;)f>;4GDe]N*ejEd#sBU'D[TJn[A1&cCZ`ac]qVko(VMr-]RXehR=[.nO(rrr2j0uM,PQnr6fdaGS&?N.Fl]3GObgnn(0gXF_U6q8#@gSB %cl^4o,s6=P#6S9C0=f6e20a8M8!Q`l6L"8W163V)a==HlUTVT:i;=3Do4K<@/eV7ralUWr8$7Cm2e_U3*F9.ng %5m#d^G,(d4I%%`noG2g-GF25-&cuG0q4p62"i7AN$51^[V/f403(l-a<-kYupjK2n]7iCNr9>Xm_g&L[9!I=7>Fa\G^6bgX;$YZQ %j-/S@2L(I65Io4Qbl_KL2FWO$fQ3O_#_<(D<*iRLaWMWQ=58.O8N9,q&hU?0m@GXIK>S0g`B'46c=eY[`EEeXT"+%0?>[eCAb(=^ %\uA]CVH]0;6X/p_MQHF*m],e%rIfi180fe)\0N@f=cPs=J'l-h5ZSIgHH-lKA^EaL:2mZ %e#$fagY0t7N;&3XbN?lHji,*HA;;9T0$>&@fjKA@`Mp6fG7[9PulcsaZ6TNW3,]oT>?g&[8(g6*f\&jVN[?n.JNR@@`"`"<)%fFkn)Na]aOPI(6#o_^HS!QLUJ)t0E7atGOO %,>V*K"W*U#r1lhO:-2"aL2XU7kl`\W,k"M^rG;rWjudBd%W$_aGmmD=aX[\\S@sOOib^%>74\WtU/1VBBJ=4q %3Ol1*E)FEb+/d=X$Abp!^H@&!gQN%Hm)Vl0Z'k$r"K?Td*oSVG8'cjA\1UtCns,pGYU#1eQ4hP"%XD(beE2TtnKGI-)-+H]gJPqP %q#G\ho(U5+[&?hkTFP/T>URMYO2>XO,V6UEAUR7)[um'o"3#c8M!p!"Y3*,A7ZoOX5``1I-:p@pm%,:W0g %]OS[TdO:Nge\9KbbL+/t#q$Ou?_!(.J#VFDB*+*S_Cgb/:/)LZV-RRrlf+P^Dl`&d"^ap9`UBeI'"rpC!ao9"X\Vo,)),t\\#6fE %W#ob1R)^:9hXdE"m3M_D?F118r23DS!E#1_DI=B#I1_J!YQn`0Mfkkc/lo&\7emTVkN.I")o$0EBOo4c@ %`CsIUNb>^KB-t,U?"N@NHlYRd34f-H?fNCdPWA>j>j/^NPDH&Zs'SZR]?.o8@@ng!ZIcHI<4)jb?%%'N;J'OS-dkf\Wo`J03XsW2[EiZqG3Br%3M!!?Vg_5]' %q943Vi=uNII@;G?Q>(@f@h/b@!:GIjR5QFQps=QSO_2UJ@=,5EEr:OFf\\U%;bgtO5t&aFt:Ba`5f %?Fq3:Q9TC`G&gJ4ZnkfWnl4\kR6km>M;I80JLfQ2GIe^: %Ii$<[mWsj#]lb<4H?bLc+94mHlV:>rH?UB'8r]/a)$D5Iq)gF;HSE%Lq?$9R"o@=Bh6bRm?V>gV%8K*A,N?OXofEom9(P-u^)!D! %2@CRt?JOkh(Fa\_5lMfJ/,#76_6;\W.OA<#F[PoW-TtS:`_es"NN).P/F,gi!`MV"pa7aKt*:#*;;A!]t %Vo<4J0t6=9#G0]XWZlL="A&kaE=WpS=2m?AbsYg7$0,GE4j%jj'sUi4"nf)]171;mlTXn<[.r*6UMIP/J\"ru'&MR'8I5Sb?hFn+6pCa\o2o3g( %$`l"K";f2L$sV>]cU-[Jb)Fs\=\Ao'#X-\oQ@!^7_$nOjGZ-c<\)baj.^^sahGtXFdlrFO$gr)QD%`7e)A\k6pDug4LCie8 %[Y36_BAp?.WYs7R8hB*%-/sJIX56ReDV=b"u(ih42)_C&+kSbG]OMc2d %WJ=/!!UCs1j@\.cMKL"4NpaNr*9nmn!?c_SGQdh&p(E$UK5p.;-G)u7GOE0La9Y7g$2 %`EFI+]FNG<-rWa?%Ef3.*G<+fKCO\8s+V!D7KW)N@tk4*cl75V?o^KlO<@>uJUlG>^IqY^cO@7Pq+j+0odO/SDMGcN75fq*i1@S, %ap^&rn`t$u?+Q&k/s(Wj1UZ[sqYQ^u6 %k/PnBgI6[^3oIHAFU3r_7^1-YL-!ZbS.Wq6I@iB&7_6@1\#3Ql8.mi?%[L/$n=gQpjeb*e1^_5Io'b@*RAfJ*a_I#U=L:<0OtMuM %8`cY9K1SP[o2XTGr/dM9@2=Jhk*AGWA/oXZ!]]@N')rl/WFT0OIuh:iY`fp,p3]&R%Z@k3Yd*AD.'5H>c."dFlK02uZg_Njg#,_(e)c:(jbgt)9@,5+E#n`1HVR_*AhK04mZDBLE8.K@[t %d$IuaGmSmnd45PK%U-.C+Gu<21#]=8FL5Lfd2G>bh;rVeN.%f#u0nmN'%*$:dACPlC+:h.U*eF[2\5jr)l%2"peW`IQ>>/A8e%*%L6oEJ)&)Vn#\B>GoVbJ#9< %J!-_B5gNo7!7XtR;!0eZ"uZjc$-V>-%*0Z(n?_q,ulqcOuT3mSRpb&kCpPCYjGn(ed7[\2%mJ(korED[Z7gi5c0Wl45"-qiZhe!oGk?C\"Zc""uZ33a^^3$Wjk2'[/PU!d+d=F(bg5.[^EU %ml_j^Hk2Na4Vi*+qtugiRWdJK)dDlqnIrl)7Bh,JF-k7;>K=8lVZYOU2d+46P-H]20f5sKGaP2/[?VQ\T<+10E`:Et-KfaoR^rV,.2[bcf85>!`5gRIH %qNt^@HL"HBX<(VT-&Wh7j;YII0$4MO-p9O71r#ha^kP2`VuL6P[:&?C0^9@mmnC2>HbOqm49*ITEnpdI"E%DDMFD1gSXhs6,,1&IE\p"FosktFs%nu_?dFPKXXKo %mK,XV&0TYs\'dPaQ:`Pb^^.Sp2ATEJXY.MZFUZK]i>SAOCHj>:>N#9X!=OfR)7Z@/'9WMIi(b>A;N`o!$']%6$19H&@H:_6bVrr$ %=d"':JTQ#kYk?r/[X>8*[uLM %+9`ldh]KIK;d3(FpQg"O:ThdN'lY&=p5_f5'dW1o('.u9YTN_T'j$8P8c)l770krq<93HZan5tN[%\Z,./sTY,?9=n6\#oR3GFpO\:_0Edrd2!(,e4f=htNQ'WG;i %^B?O5'kIUHKh9Qc-H$Lf6'5?DoUt,*CF@3@)H\ZY+F?rYI;)mrP?1"S_Ya`E93Y#*i$=QhVP0Eo%2Hc!kZ([H='-\L]m!,bS[!lS %^n-c\CW=UU!T/J]p$6+BR,PC=nrg.8+q52$sa2>RL %nVT*YpBB!i>Fb3mgbL2EfuU=<=-V.>d2@#_&T6)%ggN^L!/-^PSj7V9YV6?@E6bdK`2h'Lq.9_S7P:I4aO'o@g0+hU;*M"/JP&]Yc*AGnHF;EKeiDkcd4KJ26E\N6K8-H555?T*6 %YscU+G*0l2F\1^FHAtb>SG<)fn?bCbbFl.s^^Ghqh"J%=!>hUc,afIO[15[OZ0g`0*D@Ou_j:UeI6e;LMh,feYTLIjm`>A):?;g_ %%:@iUN?4IAa>_kkm2;QV>?BTMeh$607"o%6dg0-^RVcI7G9n3Ac%$26&g2u$JLub'128-\mj(D&1j7+H4r421.2A`!SG@6%8)%P[cbaHHn50rj0mm)19E-kPf*#g`gPi^dgB7utg^Ftf&2&I=EkYL96m9'Alk@Cb@m:!H._riB %\Xj+,WQph%q9e/j[CUee9<,)R%V*b-&A(;rR_,Q,h6--ZgTc>@,('iH[NW]-r,Z_3;9?^D#*A0L$U;DG^9n^UCg1^>[Gh:9rAauh %!LA"Mko'69"Qt>Ni3Q\?gVX;k-05o$&.8TV3)Q-!5"[Yk%R[A_+;>rH1JsJ1@B!@C[fHCbolb!?fYqWMSeYlF!PSg%dWE3$!hlb=;JU@Tlf5C`T7W9.h4HV,$Km\[MniW-pVF\\52$XQRsBE60eUt1lAk7KSO_)NZeaB'7Nnu/f%^-H;et(k%)0/kSK>4lVaYDC$FV"?gm*oJ %)I'V\2"5*n^VX3Z3pBP2^_lPD5MlUj7^O%m-O%l<,bqc&OaS:hZ=r?tBjaM41KP'2Ra5T-L,K'@P5G*CiH*\LiS$lB<0O@eqII+Y %dO1[n:iML9:PVt3>Fu\h^]1J(,kp%7I/R>hq61'DcDbB^[A@TF[H/5T`emY7KakPK/;u53G2`-$mX:Qg9,XSfk:g7m9q=f/5Gh2L %ocMZZCoo:'nD(Wi]SW;t]a6+II-\`WP)qjF\,dXqU*&&)bY".<&&-(lPK6lb7Pb`HBdmoA9O^6,U[)$Y/s0#\%7p7:.) %RfIbf;TDcbNU5n2'RoAjV#$lt41\N>:*4T^=U`?$)c@=\a7YKk?-AiDPZLULp*RnUIN!>Eb4N3=(doIanhuA)'VXl>>Je'Xhgt)+ %oXiT?l]p\"]72Ocf"_H[4eQG0l@CogIfeq5LMdFKZ$]Z&Z(F;G6%0fSUG92il9RFilRT2N^;;W2LHW^kf6,!s]EDf,:X2I)I; %6+4+?qq$;.dUZh>IBsL-aQl+Zd]Fh(kT;ML<@F;E:+B/u-WdA!_E$NJ@`%_e#fm#IpbaXses>58FZsEaj""^BLrSYBI4')/#,jdh]KZfoDCm>akW1*/b1;!lB-j%9TTNF&Cq7j:m&Cn752hr'_'2(OUgD,rDKlJ;eKZZ&<#/*B478C$Oo(QeN0 %RWMUK9kqt0J/Xe*C+`5Y-fqcMOWA58-Qbc]c<+S+]1=BG]?;3Oe9u8GKCWtZ!7mW>.!6T(m0mmV[-2HmllSJHcHg-)'%-IDqA-`d %*;'hZdG$j#!R?ns,2Z`,[K:IjZra4%-*LN7T6.-L2M__'JCh/H+FA&DF/93tC[QFogSYNL:4pS)s#r[0aT9Q$4uJA+AFMEj00fW[ %2!(a>8?J1AiBH-%*4+=/P02keOG>J*LpU/9V5AFiB7[oDJ=t*f?$$S=nUJQqDf#e=W^#"V[3)Nj$ug'36PHGOWm1UI4`FeY[`1]2-tckQ[5mmLu#K\ %?"=B:$mUhh[W;ciP(PJF*_UmBh%bX2%:&W4jDnC%a.m>nO4)IA[Z,j:TZf;dN]RY4CKBn$L>*#pbe*q.;Ks@mf`^`aDKU1MSaM#f %^uA.RUmEu8!uJ6u-7P\.a0$PG[n->)g9E&6OK$*=DCRkq+g4EiMcW`"4$kG3n23Sk")6]4j?eKo8>FPBHJC/e0U&H=R$LPs"LO8\/)iSY,YO-[->((A %UkIKc_UTi.m\CcU1/*DW9?J^8@8qVlTV$V<]gF %q(>^X1D$Ci/X/+*f*tEN:ij@jQ>=uX+?$QgKgKcI^r[#-/)6()\W5`3[??6:fDcTh/(FJ3Wh,6$9gJBEWnCKb;9VgGICb'9_OSIT %'k@/<@.oef0]KiW,+U!"0\X\tULg]G442-4JY#.SA(4c,.`&9m*ElI=m:&39,:Vf0KLf$9taR5)RAeZpq %,j%jbA?-:KAh;,#*5L>p(t^'O!.L-4.cER$.j?cqN/[,5=R-PFO0WpYcho)ue@R2t5;#ddI %+^(XN+X7$"?qfr9d:8tIpO9c+?Gc/hDr>fhK]e+N2\N!2Pd7Q?KIa+Ceril2#E'19O?Ijep[ZBl9NYVfh5]asdOh6.fWVb*!<,iG %Ysef[Raue$0H"/c!!*[o8au?3Dq]XB^--6!_#[Vp#Gj'M6gT%E&ARBb5Wq0e^p5r@W$h*.L4,6HPp*u]mO3pr,n;p]pCJE9A^kR>-=FN#e9:3 %9SSu`Mu2/en"!*ZCaYg^O,Wks"Orbk'YICn%GkO/ln;a4XEbYQ/D>GP2(6oYYSC4W>>(rP$>(''IGL/(["^0K"G$$\^/T'`)MQeK %N#YmMM-A0ZR]KOr(OY06q(8d'se!Qj@?ET@9]YS1[k]0*b$t89I("OH^7Ee=*RhJN,X*Ag*j(XF(Ce=!7CoK1E:>Ye1aVKV(0MY^L2#.=(k7k4+LN5$ %g%L;iNnS=CR1OqWA19Rg;43\0^o*B<?U2#U/)eK[T!8?nJQLhW4\$jr6V$a__>"7;NGn3f7;"XCj1)F>V %+:3R$a4tABnhc.XKbhXTj">@D5/a_hm?QE,5RJo!a7.CFl;`O:#'ThKCg.$gnn$l4hI%huXEa,jPEo"Q"#G>$Z"#(Uh6WE\W"Km` %Rr-_7:mkTXMK";Mg4NaVa^"?.k:!>J`B#+VS#e6F(u]lnfY_@JLrRN$kaAsdCe,AD29BAu!Ke]`$"02k'"@NT35sXbPb0dp\+P1# %HduFF9DJoM5Snsf6Y2i(dP@`$=;Gk9Z!=1EmYgf$7)\ch7'QY!P*?"*-]H(+aOus%CqW07Xf!AV&kmVV0,TZnB/sChU)EsrPn__a %h$D;PDaEPri5?WM0C'@+4ENIJ/NPXKeIWI'<1)AnQWdI'_l\=JT9"r>BY%cW2"O<-#K0BW`!^u2HeT']#<6/K*36nmX88]s5" %jQg<1cNB*f6E*VOB[[iWQCN^b]@r2]aTn/cG]bJ_-P?U4Z?u":-g2\,iIOqt81IBn5h'j83=m;4*pZ!1C--23nu2KaR+n?AW972M %JTr6P[&9*n;?W5!EKNpn9\jRf`#_pi$+QpIr:JNC0J&sqEH%,r#ZB[`pc0@q7Z.o'S>nCQa># %"eH'5CAEC"9?\,"=*fCDK(^eD+>HS5C*?_Q#$C8[8rG]=t5=_QcQHD\95]s,+aqm"(e^PPJ %V"'d,"%s:kFGR9Q\6;C():/ajU066g2Q$A%4B>]KQ@ZqZRObpGJ_!k`];0<`mA*\-GP'CE5e9NJ3d:BOf6gWf8ThNJ3@8sfJl0F_ %K6bfmk_BrXG_CZ]6u6s5Z)j&kieqj>E>Ech3`8%tggFQ6e@*B4\@dHhS?W0ma;m`P`%lAC7`M7H8S:Zg\FW\T_*\MGRbTsN(0$k8 %mK)2'FlKsU,Q,\;n!=hh:q@ArU));]]s^DoZ^kG[;XV7$-L&^K".!Ch&hAb7LtP?ci[O; %g0j^fHsmH^,#N<0="ZrCUS=r)q`N&a+/**3[.]9#g\F_'OojoW.A1"JJIs%^$"2,;:'537HUL=Z-$_!EggEgUXWsTig-fJ):sSkJ %J?g$$d%jimb^(j3ecD>@J[NF32-VWV8[>nfLK#rf%on/Si9R/UK*A/6Qt*@qR)_#f#EIPH^l;_=%sU=D*AAu:,p8_=D`oKcPkFmW %f?SF(pXH<,WZcElaKfr$!fW,T[=cDYaZ;2_f[8?(K&I+-i$j'E4"PCH?FU!'SUjWbQ:QVNQ;o8l6mt])(n$kH4[L4_>/9t"0P"Cj %c@RR'V-UUsb8NDp$`@EL]rte,4>s'QYXU7@YI2mm#($G*Sr:.s]YLF9!-9s$7Cctt(A>7\a`,)-mh4]!<:KK1ZN,%\mKE>6F&gA+ %`f@1?H'm>(gWn_sMpVMdrOUB:05K6)#)G*Nd96_[X.7gD@%=3%k2KLL8[.%okp3N!L=KG0L>O[FMjC#tZcUAsZR>M0OU5b[NsThQ %NSsOe@b22!R`/pBN#dIQ:'KM)R>JW-Pom.'H^8X^1\(>i!0,%B,+;r6Kn %7bBePc,@Xg:RQbec0,c/'>K"P5lmTTER4gH`sDbl3O(:5.mRS`B9J]p*^'?Sa-l2:@">Y%k=SXBn/:;ij8En8-C#?K)b^@;B1T0t %Y'STe2/p+/_8.H5LoVr3B1)tUIIt1LXi,%)a[uISK&(6l]2$rtJqP#;]07Y41k@TAO9&7p0m41@D]n>R!2UXXi*>\oW@NmXHP;?1kl$97c>&b`0&#cT&/09d-%e8<+fkN?dWi4PI\$,s\YG]1%HYOek$^:YnF]r`O7 %-K;]^3HR^^lF+S&d^N.JLg/G/i#/?!d(j)/k2$:&_d9XWCNOu9o30Q9XIptN4^W2#j3eq<6> %2)/6XCRW:TATRq%6%pH$ouBe;RdV1<-,OA__(2G[5u0?*&Q+N2X7iJkKG%F2VA"IH2[ %,R`L/n(c=8)0S=?*eR[;'W#sf+")4!aNNTen(a!4rN>7+fU9L&D:\IZjDBCL)-a7B0V1Zcoj^g-47_ICMCf7MY1"-LN:G#8[S*fb %/>$onR(q/r=9n7..-7NTMn:#p(aajeUhWPeH_Kh)gO2`,!YNng8BUns@dJahQIm(js_@l3!g;3nH5BCc^4ClIB;u&!Cf7Z@/!uh&cN:h/(i=-\$>OIcf0,`"0hcA/d_F:(J@.,@n,5X[WT8"S>MTBs %,7,OT,N>Hf2,0jOrCbmcLeCD6l-%,,:k=Y/@)^^#%1i'n`sgE9h*="c)X)'O$G^@)h@l;GjeCVi)S`o]V84@K5R)BgYQ?n&Zm*'2 %.+l>A@>b'$+j>!bDcJA;Ts",.J"Ro)3";t!N8!ArohA57Ep1]/,7t(grO1t"?j-\Sq,X+\%a=dRZ5KYE9/]-TmFht!?7';cL9PcJ %=p"h(qk(ZK<%EjY@>;e/DQsG@R/fn]KCKK<`Z+.-5-E9@3\ERk@:`"to-/eP`P1j(LU+rLTQ3dK[)$7e9c*qd %^-;D/<^]>jmLA5PQ=+(@)QB+E8VT\-mrI+LFlWi!%4ZZj^<*c[%r6(OiMFL %U=n>1-jO^ed6G+'.CVj)h:$9mmX0H=X`upB]J=f;(.&gFnBM;/dU(SGQR&T,36p?a %73pA(-]stR2M3SsO)%#rAPQuWWN0Y7LMg?Ko\"-nLcS_\YT#M>`/5ZpV(Q=21rd<*1)MT0;rqk^.55nB4,3Ko(B#hkhBKq\Kp3[Q %K$kBu'$T4e0gP1+7()n%Q9g&J@TC9ra5gt?a28#;A^u,4qf6e>O=m?/?JmVPqFgY7u-9oQkPQKR! %U>if8gBPA7sMFCkMP3l2A %)bg=mIIg;U!tL=_JAIS8RFK&HjROur/>?)7*tYmT)T;4VE@5IZi5-s#Pt*1+eXBa/!DEX`nHtn15Y&qf*E"gcEG*3K1YKK+>'0Of %7"MGrer6+8;c"s_cU%7)Gp,kdMcW/!4s0JkUFDV)(F-Eo.p0T_b?nE9j=V[TJOm]3j7YnBb_Y''\@&D(2DY_KDV#7Yp>SYgh5MMU %_m0_ %SIUEV7U`#]Jh5sI0AWF!jIogo_2$WX[ %^Q1^KhNg%Q?Ca6'#]P,W:N(ncIKM30;S)Ydb,"[HVE&#t"t/OM6*r:e5?95iLg#$/4u9Tt7> %Y=kiZI.B0YG&2DGWle;(*[iG?RiH%oQ3!C7?:EDp:Xr@JjTN:dA'2-Hn]'%g?HTJXa;d"d/==Q/oK11m.UB92,+u_^C\T!YFfGE( %j4ccA]hP`f$VPtuh';CG[OXMrBgCDBbuSE1f`+r#pf_"D(h^AmIfaf*LVkJF^2)Pc]gsCVgu>R9/MqI`ihNeCe83$l_e2DQ$dbI*e %Q#BjKiHQOrE\dC%?nYFS9?eL/P/cOhM*!rXI9&H;iKn_5Y4o\CE!%2/)-1)%IZ$]3>glsQ4?[0>GL1]f?%KCD,?''1Err< %SVOudVtP2;h&j,)B/KDDUH]7X%,U/1K>K4j@<1)D_]$UV!Lu5p7=jItEA)GDnEp>?n0X/Zj/1h`$CD^dR12,+Ok;h/DC^@5W %>0+G2_$I5\e5@$l.a1`+2QGJg*oE\r-''P7q>Bu&8='[lVlu.!G*W)g8I&rg?tqTFBBcV(BC(]CG;9N%+=7P_lCo&i`X5nD\H;2/ %gH^d9'9G^aZ@8'#Zqm$W)G<+t'>9tk8,Uct)rYu`PM03PG;?jHn9G %c-+#6+GQ2_VOHA?d.GfU0jb3l"42;"/Ha"B"LHg[hFOAJ^HYn3R5!N.SD*qDWitt"C0:(-ot)cu=Yg/$o=?HM-?YuUfotfc]Ct;' %i#Y+8j%eHNW%\?'!3/n7q^om,!M$e1f8/a=5Hn#ajH,`SoTV)XN8;B1fH7CJH'mn/2FrRg000T1V&q\cDN$L %-i4`#'notHLmIXE+Ko#8^4BOr3aOSV/=GlfVe''N7.%9c5V9V![QosYTQ=GbdsdAco1+nCFqRWU4KQ?b<\)D %_0Xi;ZWddZ/#7;Q?hXd:-A,G$HWs+;CpRt"n:S2a?dhB>EZT`OjQ=noeE0[jZ5cN6ABP9m_.$r7Q5p"KHf&JOXkOX_W;bR5E)V'? %>n65BGqChhhIU`.?LH@2en8AqSor)PQJoPVqNWO/diY,bK8.kslL"o>NdYj60$ %A,q)BJ&.(HB`l-YAU@>\3@Xb%V/:'qFaKBJYLN`RBo,LMmuP":.26<)2iqf?DoJPCp-)jr%1Deh)+]?#Qlfo#MTm1RDEZA$^:'8a %]ukK-IE%mE0eJUiRjI7F?WTr0A]SQensIe4$>'e_o_84[T*T,dilJuI_Eh^Nn&T!RRna3&@;==6'[CG(AbBaQ+qET*r?(YJG*Kou4I1(Dn[raPN'Y>[<8'&?OAbr.8>d+`/cmA0BPu %ROt%7/X,U$Yc&cR;JNK^oP.&7Hm[!73T6narDG"JM[Lu;Pc/L8<$s`+J5?Sc!NBd67%kFQM-ePtZfNVO"NrHd`ue>Mm_`664:m;L5G&]Sck?\-phbQIL[L/9t4F %$'lrPSTNa/Wq,LpNo)lZooq'[m:jNk?fn/A:KMZ_j(YG=`U>VZL2+m"2`4%r*/)s;KL1A=F[\l1)KS;3"&!tRrb`I4m+FU:>2T#r %$R,5!I3UTOY1bJ4_7U=;:m=C`Ki8M6MlR`&;VT^Z&[M)+jbi><_0J[Q0Q2dTat5=_B%>2U4fu_oW]Sld%9d9uY:Xmp7>IWKabKH(4XU1qD=]toZ"KH^Fffsa`@hQN5 %XUQ%^SYT8%M`Qj4g;OFB^ES"T!ii^KMl>mqfH]1@'CidScB]OqUE;PVq3#e(cEFCT-&-tA)7an_m/l0&'$!($lHDFMo\",g;CQmd#Q,(XZ\$_)"cVhLYXbP5#V'#1I:+MiZ:;^(M+9ROGrVDo?lak`7'7NZEf*;)e;Dj'GA.Rh9j1;h8$=\b:CZO'GLQOQ@l'Vc/KE:#eF#c13JBo-j*d>#eXC6$4=p)6bKMIsY:[>rdUq%NR\gt9dM03)_3-96>tV\m?^:^oYl$R\._:l:H3Ge_J+_[L"I1nrs,PT>dchp/%a(rW %D:9@T'ta5J+X$B%lZFKo\A">0Uf51De1@S'OVSjAWkrS'@MY;V=-k0X>]Pu$ %O-%WrrsA]1muH[.LW&QO0$0>LWQ?/+>5'BJXIJ+:d.#OU(-G%S;aOqB./mbG8(T\j6+J<2@o]?2CW%>cDfZ'D+-h:mC:uPbN^H6E01Lshga7$P1r:9 %4c05:H1LIOhU\+Go^l$V>2'*W].1%uDTT$8Fr;N)pTACN_&tGbTB3N;"RoSH4b2*C^B/N$5GjWMFSaDeIK4d0Vd-5A<`J=WH3Bkb %9?fpPEs87L;no?@<67cLUS@ci[usWWka8T&T!jF2PN`e(qq(K;lbBL(cperY,OGk#N;J+qHF9Ws"PIl$01H/T!BA@Z<>*j=kFhD= %k?0(>O.%c+mISsWX#qa1eZaYs_q),Y.nOR^CQMB;Ru@WObu!gW[25hlWPLo__%!MtHrO;UeZm]6^q:@1kc827"'LNS$4UNQG:bVO %D0+mfhF\mX(ITb\*?3f7#=o$9hT?*MO9[7W>V0U't`!T %hr/om_(P`$JZ'b^O9354;BD;[!:e30nleBm3fHU]%S@6;i_c9O3+*JLtroABu?:*=e\2JecZu&;:&<`ki\%/pUlV#DNda*sk)lYX;3AFmrA?%%+F0.]O#ZC_I/Qj^`:=cn.otF\F&WiT!D(1Kj %Q()Z2?/4[Gf.BAflFK&6!Gn8)n%Ok((h?3,I>'6%W)Bt#,CAnd!@Rq>GSZCETIi=b+F9+p1DLEGPqadS6eH33b=i7TC>1;+fqf %N45*!>38=Xc>"PgpK\)8/3b2!EDOXN@(2TCmC9UT45%)Ye[:+;pXEnIPS++:G5_E%RR:d"gG,artW`s["9NnJu.+jAt.WQ?2:kRq6+CI3K6f, %HLf[l\"$Nc67TUgBhl$N2?9*P/H[0^Z9OLa[nJK'=I0A!!A+l=Yg@55,.&mAkQ(R$#\cKKTO46U"QB9*_$?oZbGBHD %j=`.K,6`J3-]-J0'p/F?a//>7V'GGDW5kJ/SO[R$Remcf5a(5N]E2K0MQ^f#]/-6"&-q$M<:\MN26Ve7f'1j-^%7NNEMc2;/1<)-_h$WeM\n-s$<0 %a5$/m5SE)).LJG0`@_d!:4a38moAG4Ceb^l7IUrlU5!LPDA0@L#!HMh<bT@OIA14/Dk'KpKmle\q`- %4,np^2:q4BAMosILaE(?`kC+tc>QV[RQg6h:aiJ"'J/OQX&TjIOi.^H8/&MOE0Z;rrA'- %dm4p=H>2;`Sm4[%9ZIMSV&(@^#3b`:GI_Fa*!@$2YGSjJ$)At+JSKu%tDi-AZ`AKb?]KAMamU<&\^],;FhIO0Kb^aS^, %'';6FVCWtG^0si3)rDEtiHt,Glm,"Q92sU(`+!8#fMhT#5@In$nZo`mdcgBffV4<=:4kpf%4aV260)V+8-rK?:R'`Ybo3LGOL0i/ %F['__h*@/^2SIf\.+e,I@n:QbLU1ica;RU58$`Yh+euHA,p_$.%]3%.$h1U>-_j1X.OD*o>b,WOOHM-p't8908*b0abkLD0";# %rqB&ki*?>pg'"4&8BheOM?!ghX<0$t.m5:JN^tb&;7j#IgUs_&9Mbt.pX.`9KijjGRH9e[IFMk+JK)jK;V%AiAog@o.1$5n+@Ah_ %3/PCXpL00+;8h!rit8MS3Cea5IsuK\Np4[l,g0Hj%O,b^h>7'5D4?Xn;;]%l85Nh-hG$cpTO(\h[U'^lD-u2/V==q#JI.l([#'d? %5)r`>b,3d&D1-Gm?U'&uBAEJV!B%X?/6Jdh+2HH[1/$aB;39q&B!%;?;lcTDI4eES[]8Et@fdGfpSkUq1A3Na]ejh11*AW:$j[#< %QFH0f#+'I"[%Ai(&>&WC"XVqpO!V&lQRP*SFS)MqoW7HiTS:-Uk.KQOj.\urPikF+PL9o/kC^p2A.PU@;1*-?X/+3O$D#PO9>>/V %l,cs[S`Zd+2$^`n^_q)lVDE[6Tb;K#(FXs(.R2DQ0>#DsML/7^#gL_@BC,D]!@A^nrVN?,4+UiBH(tjHcH_9">N2d$E9mq,hsDQ.N3T=d/-;]tZa7a4b=fr`$PT#(!D):9(E`OIXra %Vrn7LVla:k3^5?l=X5"u8er-d=W-^D5`B/=\@-,u:FotBPdX(rGp02K^'X.&2!q`o_$BZX>G]2hh6"W2D %em.GaM]*d#Lf.\O0&g.:7lK[bW)TbSd:$]..\I-haeN%%\bbAi%SeBL8U]sLEmpGBp!@9:'i/ptMh#&*>";"6q!u"=]s$uZ]k(6Y %OX4%n>\#RhJDYPnquf'Ki)fAu^Z0`;&'I#Q1,\E0p1'o4!]?h^*QqMpgDTX@ %5nm/"4KP?-"/oJO(VD&2].5XU.1[3<2O[D2l46sWe%m^)u5^3K%!,`lZc[B&:iE/=Pr>'34^h'EY\')1XK.pDrfl1E<^MOQo"o/"?!50U73-!c>MfJaLKV-ID?Vm+'U`Zg*,`PO.bc_] %pVZT[#(I^lhUtrsXkE8N!/l#u&^S7'c(]bt=H<bQ%//\UC@o`YC,j>$ %mfLKlQk^Dd=U*aFnEurpAXB\(L;hNtEuj;C/ZL/lQM5A8ARWF'2T!K]0MGaYFus6WmGPrUVI`"KE6ls/)1Q6PbE8S0cG4E/Jmkc# %?JY%\dtl&QJH#f^o4W_s%pI]hok_$+pZlEFHd#^Bk_gfWqrNj=*BFW9Z4AA'YAH3VA8XB*pp_4d*/ %"lJY;hY'7[VtR'EpV>W?BcAdO5CthtZ9J[=LjIT-\?At6BFYudNRtiiMe_`ofYEZ4P.&VL*n%WgE*o7n]5'?=.tMRIKAHLX[iVk? %V.5:m*8HG,I(<*X4psKN%*'B+p0Q[bmGO(uC/$%7'+V+(u7^/Ji$\`\&D<].Xp04q]NlZQV(29'a%f1S]lf(u5=/;BI, %^0h2?qi7k]t8tC:tp!MaM?"oi'^]$`rYB9Kr0oKYMA]VBG %d@u20i0_R3S9t/+p98JN,e'dK=?Uf$t\lD[!r?3t!IcUeG>SqUVH4b8A0[Q.X&DS["0]aS2!'QG0Q-XQ&@kMY(^SZRE: %Q$GLd>Q%eQ7!id7Vi!'ek`Q_$*\8d#i(8I]Gkngg6f:^%-GDQ/&q_)YqQ!%CpmbL2"uYuelAcCu61*sL$N %/)qq)M@<\UYFok.[_d3a>9t$BkJu@9=&Odtp29CtC:%ktDB/>R#2XtR%G?bV^h)u8*lre2O$ZM5?obm&"h4=\5RrKo=b%KEDqc%p %a-$dKE#us'OT.*b-Ykk]B_4/hpBRqhmS/49ZhmfpA%^%H:a5&0W%J%!lJ?[HP3'1dH\-^%raS3Vh,N5a2Z,r=A.N4[0ns6[X'lhI %\OC:ES0eOPGm8YC=%',)OgXr_8GVlX*Y4%U3O.nnb,WTWjGF[&3&ZJVnMlKP`\5CFn!Npq(+k:.]_AHWn+XAr=QdAg8psq^/)G"# %b':KsVj7#U;mtn8m-sQ#kIk6UcCWK'5l]g$*6.IX&/G$;YRLiaIi*)5E5+i;i9Q.g1D4Iuj/picWY>9n#f(iVm5mdsbHM$D#Ig2M %lZd-^4*^Z+a0i1_hqfnK+WTminT4K_1&N5'FH"Z``6Z&`+ff+S*ldePa!870p755u`5=e4i-=4YOb'as%FNYV2YmIK^S]J!?5YXbd:q&>4o[P&hj7\.X_@"qTrpc:Ak`*SWS0!tIG,;X&+*KYU/bI?#.d4@ %*ZK@WC)D(m552j*]Go2]dXI=uJl/KIf"gAQVhR2$7"W3ce?"X"A':C1)Gt)K1e73610PAF^n\fCO`1-W@bDAQltJa+6,>(-4c3)K %-T1VRkp&hZl38Zf9F"LT`Te0Fmpa,L]UiXe^ittbm*.#QhVE>aOG<:T)FKo[Nh]/PfN\">/I!WA4%iR:0ZBO/MgpVpD.R;9YGEtJ %fu!9c9NN,S)n9/m7Y\Ek`e^PMg=9t'_ji;?q#F917RFEp;=b&hC]7`H"O'Cn0CuX3U(boh-KiP3i>-'Y)T@.^.aZBD1bbe=ND>qI %=rks714@pbn22.UQ6aXmYo'CX2]n%2P#jgON(*CG4PFQ[ %FQ6u'6/XVinMhSL;\]q`W(H[5^hID&jY.l`r!-K]9&<(R=H"!f3c>JWCQd"`>\Q-TCB\r9]U>&>o[*.>+!/\I[AD4BA;kD+^%&CrB8$EC`pq-;MfChqJ>6Q_YDmd!o^'Ig-)bgF^7I2l]9u42,I,1e\g-R/6Y?t#X_r8?&.RMNmP)FnC*?[SJX5` %j,>2>NQX,(VZ^/s5!uPiCh0549JUh`S&U+&KuYJ3mj8"[L2APdJ21W^4S_!8"/)RF %,H1@nlEtir&]5?)1$XB>?5,J3MM-N&H9Chm)p@4L6d)mNl`3/j2iQA6!r,YmiN"ON6KuK(Q%VjT9W3(N(aefYh1jm#7e(%/pFuO" %LIX-EmWTmbo3tu!JGnLF\<^*ucYl:].Z"g=ho\Ln&@2ZO*2J/_[@e>k>BMEIR+!9siO/4L#Yp,!dI+]!@ie%Ik)ksW4G)$:hDL=% %M_A7F!t#W)hTSA'hDO/9&8%QWV\+lNqlSBCp=-ltD&?3SO2ced,>3]hOPI!%NS\D..//!E1:`I$#'fNP3R]Oi40Rg`i)i&KPU6ll %_7<*G62gZ=IP$pUT4-SG^'MTj7;t.?#p(`eSDu)r%W/a(FEI0tG^^=d+('\;c]3G.I^XDJC'p@:\8'I!`G]+8!DUP-s/c%p::OqDbD/Y,*l:fXEYJ0WueGbiGMd%I@[(PG#MBN-YP;&&S6lX?CE? %UU9%SYHE9'iks$uSke"L<:]IGWi4lMJ,aR7j?.Va*D!u*=VM$764Rq[CP.cpESkZ_<[pog'UC:H'h0ANUUKi;D&Bt:bC>n:'tr4O %+Sn4Xm*c%bUAG2#&qrNeHoE+KT#Ne]HtiWubl)-4j2eYq_"dW^n_.Mg?ROWM?pJ_4PA51rE$.fO;6cr>T!!3D.bY%5p?@;`h9^6K %VbSB0HHg4Jgu@7pj(5\bf_+o@.X,tin@Bj9l-LE0&('*WD)?Ppo)9./!1LN,94P3.:0[798K`1H\F>c;YN,VKZl\S9GfoWtnVEsA %k]f4NLRsRJGDiXB)rVYuNCEenH=+D=dG&>F,b+rIj7*P>q_U=jM9N,,%c$*c4m6GH %;/XD%TDgs-_nd:J:Nb#%i_%Q8^>;?)_/YReV65S<5E/93Hi*<9\FuSN`Im$GAFZg_CZAtJXi@$F2/o"P*dKOkq;YnS3B87&Z\)s) %=4Y_63SQ]q.dn4ZhpD/&XIdY+(`EWf-skmb0:C_`aJ"VCGd*Q1UGAD^Veb@U+86;gqmBl)2gZGFNSt^6ebEf=<;V%T\Vh0u %\>"$%D$3[lmJ`c'eSk1.n+Zr=NN'kiLPPC4H5[#394HLmr/^R67*WdDnWmSfkLeN3Sr_H2=*Uu*F0Jb4^&:dgjm"B#)>?T %GL>rrLCRar5a$#r@Y&-FY#mr"LX'l^GAb(2T8/Y-i3.q&OheG*.mC>]`Om0*.`#dTF#+;)ot*"%VV/]9R]=2rcce9Mab^V;>o+3U]GIPr([L %Rtq!rc05/IBiM;)!D5IBd12pQX?PF6>I!8)o'Y,HM`rUkhi(1j?ishLam7u!2^>pZ1TM&bBqlJe^\?ZZaLpjT+84Y*!%AsH %ZO\uO"F6&,#HH'4J.u=6m^,jO2]rU]I="(6Tdo'"gSlX7i1kk08DnJ#M98qUnaNZuB0QQZ&-)VgoYd0ZE;JT;OW7ml%Pl)(/["_% %gNhjV,;CMF@HWKdH$\Y)k><)Q,j.*dj@'ZqM<)->u=6s4u*gr4GRHKCTrU/9`fVUg,.[Za1(b4TYjLJkDQ2Xj7T(1Vt,Q5FtV %W()teR=kd/8u(k910^d1F[!@MM1*->:aa,`2.KXJ8ZnR9(>,o5^FjR?XiuiMjm/]sl1"Eli>&X?[gomPoRZ,1[EB;S7BNH0Y'*UUH+O#m%*o7]lHj#mnD/8kM]$%ur\*@SQ %bhfgarkj-P;`@n8j-;4H(bVR$h5"3D)B3T`Q]Q"VrkcsXm;d'm!!fAS;F#-^-Im=afG(*+0WMGj`]&j#h3EuQK&Aqaa?::G9iJr1e:))HUsbOIikem>[HQ7[HCr4Kb3bWm@@!?GLhXeK8Y$oI1XR[Z%"!Mb %?"VWI&`^95.Bcq3XIbq7A%so:XKg(l!CnlC.b9[s`XWlf=2]JYXRX@h_A(,Zobh?t]M?#tVN*E))J?Fj/LJg!.Tn]j.`q@MJ?9R-uuG)>OcFalC[b %nIC9YhiF0NVr.2]`(IrP_X'p`'X'5X*1";8X`,R*@)n:=04(@m[/71,`=)GR0gj9p0ODuNC(*K%i*e+,Nt@of2gao-m1K-1O2jC& %Qqj!XR=1P1j09CM/p^0Ln"6+r^j]=JNMOE=EYLBEZr:$r;in>KZJ?+^J@hW7kT)8(me;^#I@+Vh5S)+Ckd6J,$S&5f@ %r+I3:qR$[([eMRu@/Tl[^XnhB(8qC`CEfM^r`7i,UMdIi@4Tfo4$Pd?D]/ %2209c@W]#p4JCMY1NjbL@p,Og%<,`9c>pYSSZVa+GX!@k[5_WE^,mJ#ajYIpe+e$,Q/hAkJ+t\rh-^03Dh%L?s75i,s75J_rSqhr %nF=9-9`OV>?N9U5^VBb4-0co"=fVq8"bT5( %LW^L`QWnI6YX+%\]#2&F1r1NIH04XL)7O1?gl9d]\TqEHdqE3WKUKOT`&/]g[`PRi0Mg:6F-,g`XE8;G:[HkOPX4m9r*^[34C9[s %14Jb\YV-LQCOaDTYuVP?WAGO\^IVS.+!&IW]?(6\9%qf^WS6bsW:Qu%CdAABY`J%!5W?s,,&$N)))j!FWUnJ/P$8U=5Yde@?k1:5 %fsJpTj$;t28N\qO+q4\ofRstOe]EK%'A)J/q7QBQ=!^n`/(m<*EX/iiB_TXMgeQ42`*lr45m,,sHuNBZ)DV]'+&MAo>qe5GIsdD_ %'/-9U4-T\QTm6/U*Yt'fn\]*D#WJKMQZ:OOpl[8i>.i9=$*=L?XA""l"jZdPKKlHU5+defDD]aR_D'?J'l_ulqVYg6P:kDY`\D4N %b=!#WTN$p]0>%f%"f@!)#^+'%gB="-3%5k=8nX!#-FfMTfZ]ZK-P^Gt.R(p#VA43Z9lO3b>;ioi@@RVGFNo;''4\4d1nf:d],F"V %@]UNgKdD %+/kA^.c"Qb`B[Oe/!WM/>9Ik %Cn&%q@&1l]N=+^RHB5BK;`=_o_N)Q48LH1++d`L902#pk4U.3WNA4BPq]E_sr+\pHNK@OGBo>HQ@hMSC-!]f[4O;21>%Y3Mc"ph^ %N+TD]KObbFj?iP)b,`Rgd>%-5gYI,61h432[]WPd\^;KfMo&-G+D$(Ze9F_dA7+kD5p/nU?DA+eG<6@%dkdaR5p45RS2Vk&J %NQ@eHWo0Eg51+WAut*A%,6`)E8S@Lf-J<%:jUIaYjcIqDm59d>cShYaU*"p %42F$oBn@%gV[W63ifE6.,O+V$^\UBrr6(W,Vu1nun7B'-bImfj)?A@,4,O%l[0<.D#h[''eUj.a"u!=pXGM.c'4,E)4QnN4GnVj] %)uce]K@`c#-JfQ"GZL2.YhoELV..DZD2SW>N+h3:2rjLf+'ts`]W^/]ogKNIe3!Z>IL)Ef?f/l+!sSG>qpUkefM2afp>_RPQV)Bc_A4U4JZ22_XfCT!WUl7!"K)_/9q*K64G$,Q0)H(+j)H_EGq:SUtOa=Fr#OkX5OiM`1H7ccUJ1-Z&,#0Kp2R_Lp>ZD#=D"?I6cCZ+ebZfmT7RD$8YHlVXgCK(5LI` %N+dU8BiaM:eRmXl'PV+lU$1V)Q/OJsgQu/">-UOOaoNlYBULW,T$oJH=3QUS97Ih]:9/bZ.j3hGXFV@t=ca@EZKh@lZb"rFU$["s %]tjcO@M]gLkMq>@rnpkaQ0f*,>m]OP%UJYd$Jq^t>5,K9aU$9'.^3>Ae/=;`,XKPdUGKabqfjSgo2fhtX:s(JSEc`MT+IH-L5KZ"$4^lrE+g5"?RAor=ib7rP4fTA"]) %f4,IeHn=LQOXVd.D7O&qY2[<_L9B0j*U@A_D[pa'E?ZE;2l6H$jN>*MJ]E3$'(sT_HfAfS'=`m\^@MHQ!e3hK/;h%cs %rJt81MZ&`o,hK,r:<0@7Bi/eLjT*uN[c9GuJA3;J]q13F\P[,cZ&-+0p9LGKA]or-)!(34O?4je/%KrhKM3MI-q\UM`6updj`%#D %Y(OLohPlt5ZG+1C/I"-'Z?!iE2'*h(5suA>W^j_'1\"G.Jkc0"$5R9RMgJ;02Xn#(`lhO):N\\M`&gs]?Io!uWXZfl?<.\a=``Z' %5)D/eZC8lsF\eTDUf\9`/#p6\Hf_5%$_)BDe`CB@Q\Sa!d004o;HX3,2,Y;dh(^]4YJdQ$N>_m6Oi,onB]3-:$8+4Q6&^FBR$W5- %29rJHd=f2FX,k_S^XD\Kd>R-L(%#EC01u/T-jK=de.-(a[C/)4t]YG4-p.pkJR( %B%r^caI'pEC_%0=(l[&3qY92IXKiEa"Q`O?4Ya8Ad\qt#oR]:Q@sHjKGVeo&0Ld^ucS1Eg+-#+b;98%g\<9S)&'#,TiuAuC\Jn$g %rFf[(8P!P*`a9J@[B&8$E,CXdYAZA:;3W0rXQ0*7o@"5.+lQ]1^aCk3/1Wc+>WFBsm&>?K'\p@rnj^H7L/u:`ipP2:q4Uj,V&Q2E %1:kJ?#fLOP`8=!mDoS3I[YCN5,(p#o2+_W&P30_cC'!29.W@gSB1V18Fe;A:/p"o#:!.huUS?O5'-8hNd%#!VZqM)dqh:tbF]693 %P,XHn$fGMU=]kNhYXj(L'A#a&-jY&8Y9P2*eI8Ilr^`^BK!fD7O3oM9D_bt303l2*`o>*LMaaT+#@&/VJ<6HhoZCr$8ta0A`jBFO %PJ6sVl\5T\!6&4H3o8LY#*q2N:506gfa@J0%pBE]tu[B$XIM.5NP1QGsI?$j@6 %NX@DbQIRU#1m&_`ju%KeH/@oLLGT>-_DP/"UBc>A/iArKGG4UjRV6C:&-grYH_I91(&)!I=2IlF`dI,lnfVf.6',Fu7U9X8$oXLT %0hMq?)7>!C1i_o]r1Qfs:#hkEb*Xnj2j'P$ZbEWME5O)2AH:j9INH[3< %Ku5rY.(.u8sA+jHF/Qj`ugHVKCM6N!O)^[a]rjSH`4NQs;!f[os.d0,!+^dDWMd?u)\a%sG5>djc*Th$/^ %R7qM:9@h.O2N<"+#U5?0);H6ro`R>S_\JeJ9`Ok]1BlJS)6We1/D(EmB@qFbnA=?>(]R4?\'!D&F %8$":6kSDWrn9LSce3me!1h+!,<)dfbHI^b#jpYj/M\4!H"casiGu,BY7eBIro3F7l=A?\'N&)>D527%#$f73g_l4E?/MQ8%*)/:k %Fs;,n5c\m$ndDiCXU/DDR#k0)G/=b^e7+"teBY4i,-k.b5O%;,fkEiSU9*4TS5;o=5m<_"JC-@-._9/%@&sN?r\Wgc`>PT@M@t@X %X[;?Y^n;Ond>.T0CV70'^G#k%MX=#?*3QA)=lP9!jCO6V;)mKTA&3-I&VN1qJ:kB'uVUK(eWecsI`YOk:0_>V6BrEb/LfQC6 %o;BU6EMX_(@hbi*co(kY0jY7/2C%K5?aa!U$ena$!+H;ECVs`s=a/WZ'HZirXqbVn64+(QcFQErAjt[[=A\:_lhJ;TQuh^6LOf2- %]nuLbq:TC6OPYE#&qWrb18[++klabkY)Hp8BjCTiXJ$t(4,59.+,d1"jQ$hb_VU=lLE!RG]OIDO_(0MH'pW0*CJZ8Hft4BK\=%WT %Za4>JpEJ9"]1#cRKJ&6n9`?.a-(m^:HlW`L-U_;>k8-?nH8jNaXYjJ#n73][<22ZOpcmX,85Ka\*R(Y\N$?/K7%a."5@>2.jtU7i %f6'A]:0:sa]en\")27l+E_n/D>/1Z#ea[*>EeO;?enbcfRAdh7O-/V>bAsSeR"/6b"'-MRkmX-9iWA;!.hqLl^?qesH:/qf[-%7as-P-[d1LFEi!B<`g+S21b7WDg]_+< %Eu!.X\qq8F;?pu2g\G>6h;-T(B'`X&qk;:9kZhTd=$9b7apH4C) %$e[@P`qe,NHNbQ/#f.L]3cnnAB,[YK&c+=n]\GZKhC/?a[d?s7k@m-r??"$A]kc.(X"\tFj?Bb_TGe?hV)SkZDXH_DrUH,I;q3WZ %?9Se#bUngL$0-\RpBnQ*V49@uf$rrPlsXfg>OWf)5TlO\i.`#qIEslI9RojU%uMCF5FU)oKo=L4$h=,fHG2FY2F3s*N7?$4_Y!E:oo1,?V^aJV]qf',^6.*'052Z\1%fiijaZJ(4aR+Ps0Wl1/e+.nsNnWd(.IZ&#Lj9)i&$DHLR?/I2#>IK7?\ %2[cIM&S21DFXXUs2@X1,M/D?Y$^R.=5CCmeh)8O?O.M?A'j$kZc.f#bm3SQ#ldnJB.)E0JV:_8=$24G)$U$u?fL!_9 %\D"$CJ6QR_Qt-iPY>q.VqeSIus+f[tA^oM(pPkWPo\;ju70^rnd#/T/\EZ8p.t\]?>!lsm8l:7>Yf%D(5NijsJdc[SjmJW?O29I. %6jRu_Bp=d;5nJkp895,ia6WL+N4a`Z$It6[;KNA>^/,e2.U)OG$#$ti5.,&BSPj=E4p;$]k7BPO8,QmV&ui!kIkT/NqiQXr`E,!!j4oH"?i;0u@ap4HfqFbL?/]I6I$ %BE1Nh>FoN\KJQ"B+c&Nfk71k=Nl6sIEL%S%"-CCGr+O\T+,^qma+6dRsNgA<#*1Eo7f>9mp>`moLrG4ajNU>Ha'%lEQ*3?#Qls7mPN<_C33:mbnSu+188NH[6Be)Q,ZTX-BQVfa^CdPG7#I!!_^FXp> %%:=r(\^+_AA7(('WkiCEE\9c7/r6,no%&b:1J=E!2jteQ2ds),lNcJZ$1>2NmT3'&IWlj+8fS"6I!oQsCbt0p.K@,&RTU('d1rGhO25LIkZ;0!r:$2+:$eLugVG$V>0_;5R %7pV\Q?98:$JG8jdEoG]X-Efe&m5-7]<.3-[1*3+SRB/D7'\'"H?_(I)hJ8EOe%@E]@%8gEjqjpDON+b1R'@sW"eVI[o-ojA/k0Y- %F8/7#`g;(0isapD4K7q;.6a#mRFh>@Bj*\#R8Op-/bkEHjW.-V>X*1<85ed_NWV;VIGMA^&Mj/0)YHu$TK5j;*& %(;D"LS@o^:X'X;'r:"MbRdbL<:]DY@[o_t2pF[eN!$J:Z`X:d9-*Oq)J00Q=/qUI$K%S!0f*q-6U#IiFdhep^mGg2`$cRPp.91+F %)!aHB@Ak6'Yre,2GC-XKPY`32DH1bOfd,$42n`dDah%lL %&;+CU1HLJNoiR02^tBjVBL)i^5q*>bIfYc<:\m3QGDaB71&[:B*Z@rRE;[KN0O-*QB^/l7>\riNbaJs)kfdWP %;XMW>C&)3-@^#\sDtPl#H9rIDKk:2!iRA>pY4cgjd46T5d&b]kM9PH#lU#`&hj_gboeim)2Am %O2H33\aK0+<#ZRP>QmThk1L#/C@$`PQMc7XDg,Iu;8onU]@N+4DH-&1(c=q&-GZK[J0Z(F8;slLKFFh&,l4(?!o3s-._pu[V2#RX$bF1&ru"<:e6FG)j-;g4W+3STP]9=Kn'Gl4"r*$5dS`<"?T)`Fq,_B%/gTj%/*OSGoPdYW!C#`Ga!)HL"U5A[()ZJ&aZ_Z;`"P4ti-:Z@%FiTX.$G&2LHmbEb\-L,@[:%[G>WfTeeQ`[FlO9F %@WBD.9%;[_%'(!Ag=]?iNfi`LfB%1,\V\`G+I'),2/5f#e_d8E`VT(uhYm]euc[RHql.B%&VsBjBdGms+'V7Of*5QL(OogIU %AN?qFB+RW2N3):W0=c>uCC+9,$+l9hGbc2@G;:gG=FeL`M^Fag&`h\V.29dqS1q\RR)S?4'Y)YlB?!49@Td-q9b.'BOJBlnN(ol- %0O@,;MU_6(&2fnQq2KMt9"c*F.J5Bhh66k4-E?$Q+cK:c$K[ %iDWCJfb,")+Y_;sQN+=6?u>sb2/A^\f1DdY+o-^&o$IRR/#'KM@19Q:Rh5he+.HB+,V$EI6?91`hIs8ghtmP+11 %k&C]ro_Ia,&T>$j5n]$+>PqeY('O/tenE\m/NaD!)WkBlKC+lFT;![TU"1PWWE/?H61?Ju4hkt!NkAV]`SHrXj4]cB>)EHGqNJgR7=`0lL8Tu&$+ %Dp%nWA#\2_D+f;qnOOpfOht7=:0-1E7h`!qkTYhfYY#646SJ %I5,:I?LtKg[5@E'`sm0K.(cSJi[[MHO\1+B:OI+hFSn(c,57*%&7pq&$`[DG/.'DitBb6iRW"+IiVrbd7$3[oYdjbZTl6 %`mX.E+Br)8=O+#=26o.q#-P,-1@W>?-Y[B.7.fsP,DZRb_RiSSo(MPr18<2Xdc3^U`"93j?_4'-$RL>7Y)hK9i).u6&jpPZI(\92 %>3K[KI+a@OLX3K\2ufRS$qPi_:_BI"_o6'"tJ'&U"aY6Qn,Tc$t8`[Uto5&;oSG:)DWEkCe %4AV,tDp^hr&9]H2a(8b@%jf:nT(2H %cZ+Df-]QDirduYSR>r^UT7afT*F,X0Wd)*9,XhTrbM(?&NK":@09ef6?p.*1Iu>D[$eYUlP2+B"rjHU:7:CL$"sr>6e*quGnL@rR %20N`k^C\JQ0)igO25emC^\lhnrU/^(bMOAmqu/6cs1A=!=9%o:J,&_erq]._qd9BoTE""SYl*2/5CWLS5Q=c%rT>9Na1o4b %q[`_s_s]hNO+6hll_"4>qX;2t+Bc9K4D9uc)aimZ?Oj=@*$X5tANc2[1IYPe1T %-OV?QEA%onKU@/ZMoN4:\#5m%gPmRERYY$dh!?_h@rJR.mUms]DI;/tPP%.@s'&e,>qA/,)r;gbdh4g+G-sZ7lt;`\%kl1hbP;_r %jfs'CB0I9^'4r^ik-JtjC8pgn*N#Hn=q2#QDe>'dTS'(]/$eDA+"fdS;j0P)4[6YujMsJ^Hg]uCk>M167$p71C-]HRH;DGC5fM3V %rquCUb^iiZj`t=K4[)Zc\,b>+VsV\'rA7WoOaJ#$T:^QlVS]B*oDH&-?N4ZM<<&HFb5L1Gr;D,T)SN9(Ij#3nrtfHn'pp=8PYVci %hdC?5Z"p"A4(luPh6pmI*%%YZ,E/1s+&6f`2U0`UF07U.2ra&i%fd]jueH/1ouM<7oS&WV9pL(htLZD`OJU\:?]+cahE[8js4i*)WlCr5@$ %iRlU_;![n&kG6l@NQQK4.]EbGDHcn#pA_XG\/8F,.eu@A6O]`obX^?I*>!NAPag[+KR:&G_[E-b5!]q+6+^JC"64(f0V1E5o?gdE %6eV&/\Va3QbC4gDV3,mSQ7Edd=jf2@gnkf53>CtIG1J@0jCXBcMdRQCXjieicm)C=dV(.^Uff/+E*R`acXKdK=0%Rn4cJ,, %F"SamMcrkc*dZB=QV,!/1b-]u;OsS>;4L!`BS5JVRICo]o'G]([5p(.VjYN,32&\-83*$G]qLZYn39pnfZ,YHTU0;;KC4I._t09A %26kX9@lEVr_t2%X)f(1cHk0%Dac!hJo'VodaD!M-B9#s[f.LX+[p,ngna+)+m[ep)[5L^EBMmM`Z@MaV[M;Eq_#hKG_Q3gU.2n;m %V#1c6],Qfrj>9XCZ>,Q.I7;6FIF=AFbLH^p"u:n)/?Ls3:_KcF@RLW5B?tOZZ:C+dN\mZUcUO\'@a5+6+^0cC]obukn8os.F\kQ3 %\gnmupR^F(>#@-@i(0i1\J`R/\5KXcD*oC=(72$d-r%;::8lHAMCL&/6?n*S&S;o;/Jm?4eVOmbjnVlb$%G/H8th1/D#P>d').t4c\TJk.JG%C7V%=2*P %bAEoZjN+3H)!qcSJ1]rl.Yknc=N$U;j03hJech%?1>KPKt+)u0rHOn3hb^irWnk>#j.U]M^uV;XagQUOL,Jgi3W-*cH8 %I"9uc86g-"<9'9l_%8Pt?1t9*lrjpS"\NRYkqB7/-K'Tk,^s1p]!W2T!S$<Yod03]e,h6[.5`k9WZecDPBfM958/%*7h#a8Qd+9XqN2F&D(?k*/D"-YsW+KlmSdWA/3rW:sK %`JC9t5o)KMWK46$7`q/F/%s<):.P$KY/j37K)O&V,pVOgjN.I6g*/Iu8!1lF.;d8F;i813Ej#r5&:eX*UQS %q'[khEc]b[S,2["QQ4c*^<%.BQa]=HoRK$eMMUm%m/nd=)5R)f,_Kg:E15LPH%KgghOJ1BRI`"g]_QV)_Xq"j".j.e.k^jkhIt4, %4;[[Dp!D"uA8UUiBc:f^,j;B;fa);7r4-34)GuSqAQLA*-9XOiMWs6_A"465MLq%jJ6AnTmX$5o@^N?Jk2B@m?oMnBd6VHl;n018qfKp;:VIc?he*gJ%RN+1rWjOZ%.oQ(Sg%TAt(d5rh]6+6[s7MDCGeVZ[Dp %BTJoUr*j_MPEsDW85k*fq;QQ7Y<'6Fb*Zl[9`#F_P\YFp*nVcONAV_V.,`8R%`8EQ*D1bE;9)r4%2QaGf=0f;R%S](Rj8si^5lad %"leQS>_RdkDA:AnKBk:O!Gh(SGT`$]qKQOfFWGP%7KW[mScTmQe^^ %B5HBW.ZO]_5k+=bf]:G3A+&c"gAEmG8co\P6BYj'U:Lb_\3,G$0rn+rpV_=6N$GI(DjAb %jEF"H(khjJfT:,UIsuL\rqnk;6e9%s7>TTOmt_PnPP;\`7*]]Lq/IV,["!P#aBJAA=HPK2?-sj5id9ZRf"h#JN3%a%MA\R!io`^h %ls5'Agur0KrLCq@#K:o*Ni\*+MB:G%rN>o--i2/L+PFs9Sf!W5iHq:if"uXMOWNAsc\Wp0V=P_4,a'ao,FV"acZdB52Yc]9[r9DH-Y9:dU.F!F@R#Q+VVQU.k8-^+7K>9mfa4aaN?E)f+HFr;"_eH\h-J %2e`pY,#1f?pl:_?A?%dZ^Ycp-ZbbNilMJ-U\+S^,n8Gc)ZOq/+7B]N[qr,/+9"+[=8>S36?!&D^p?t6sDb2;MGZA^#It#=n]B.A" %=g8K%5A\@ljuWWgs*mRHpc#tdjY),VnZRE5Rid-*A&Ki3p(7Q/J&,q9%DQDM:`hnHe[&cB\]5"?Fr>9 %>d0;X&TP1X`E%_YJjR`RY6aTih%:)%MHs@<0:TE*Bj=.=_Q5d)M$7c>=sgWfcp6B$m8Skd['YF99gh %5RZ/CjtH<<6jOQ8\",Iq[8IQe)R\*cbd?h-3`P\?`Q'!_]cB9r`3ncqh8`Tak>:;#R$4XE2&a1sn#L3r[eL3"9Z8)45,/CNdQ"ni %FuJ8W7!)i3aep(j2"3=@Q$W(\-#:$'.4LT5s&^qPX)"TM20/F&MrZf2$iY!PM?`%ie:F0'PA/JpThF)e"5lnF?4]IVk/Gl[":agm %L<6O'Wcg/AEau#RM54k]REahjCX1[&'9Ik5]TVs7+]BR.V)ks>RZp7]>!*p-W.!3mR_us0F*+]tk7E$=(*$oFS!751=ZHAMYnBB.lr$$LkEN'R$''QC( %KoOOGeKSfFZ9^W-&Ig/EQY'3NP8DQ>?'%"rH0U*j-DeL*oSgL>p2;h#6or\jWt[(jSP+]!*TEu:B]Bt_<>LoHFTeP5f;k3rSNMZu %lq"?\^6t2n\P/1';m(\C4DV&j&Pe/A*Ed0C=mG!tZ\XB%BT*Ig-/^[0_`+GIX0CC;HIo8RFZ,oY+mF8!oIS?&,R6^\;Dlq77XpUlmZ_F=72NIg$3H(!lNk]<5"dOK]eLnMPt" %TWX!'_=I03+5?A:Vtk<*pK$?B,@bT>-Vc6<%QC2h'.7Rb-6BTh/Hoq)Kt@oGf:A\jW$tdFcI9BJjlOI\jTCo_V@83jD>pSlB>JS" %3?MJfK+o+Uca0:%;T07s0:OuYcX5Vt5?Wa*Ut!TmqImL'puN6*>`2&;.n_CKCKi@H->E>,etEgHAVmq!2HW`^Fd)L*5#<@:74aYD %gTdo5C9r?mOelWHe;o9:[!B3i&q7N=%T[A=)nFtq"2BLAR\F8.30PcAU?6'EBRT+@]-`k)*"ZPE7=1MsU6[QjA\W4.STQ#@E^#[9G8M2K*#+9RF\7YUJgoGXB_!(l,s,cp'.nTP)6r35)J_sA"``%nP#4D^sIKeC)[BE"/ %cd6bcAQT1q#MFHd&"BUK0.55"B'N3K@a?9_P#+H4I,OW$\Sdpm+i0sWPX)2aX@'nOF;I-7Chuc %50O$Ilt!_6`/HN3fU+$Z@R9>:"bdF$Oqrk2Ra'<,*6Gi`F1eCW"'`8ElF5b3S![=8-P9l(ZGK[DM;i %Gk9IMg([EN>^hkOhis*K=3fm?4hC&1/g>j[;ItI@"WtLJ]TjO"#A_(2X&Gob&q,P%aMl(O5d>Mj@PuEH/Es6L[8AR8/(P_Sr[8d@ %nO-=-5aZ7o>F!RNeceBLrirSANXbqB*hG/2*AQ!%It!4W1chJQV%TM]'?UeM&UlYD&LRVo7dqO2c=^)MagD'2f,4Y">d;nt,o"/V %=;J!Pd:MO5N]i>0U"cVt*a)!,27T63`5&46c'8MB)8\C$o[&Mo$0GND!:e]^FJ)dDQ4@0SX$:^!U?%!?!mmOg0*O>:tuC@54B`EhC)B5Tdn.(+%m %`tK#h'5h0PaRCV,=!!'@Q`8`TKe69di/.(>q50Og\U"$@R%miR:fcp>`/4NUog&NC,@'?O(!G'^'7"\Hfp@ZD/$pA81UT^MG-FU5 %>k'VXAKn-1&c6*<8_1%R"Q!Ufm&)M3E`7ld'\eQ(WYR4\gIbD5mP!V4`N$p^J5hu&1E`H;E4ff:OmT)!?$bR$B %92N3,9$G-ql$@\_1UJTUX6e_(*Ji)5W;=4V-84PD^@>Hujl4*,2BX[#e,4<#hN/bTI'3\CS&P-1Xi?tI#oTW:,pE[4u&*3XNU$bYbR"88,uU9UOF"&"N_/RhtTG^;nh %':i.&jG06rUeQ8KT&@5eCTVi7(t1Sn!&&8X9gGXOLN5`5#1b9'b()WN@L)-KU1kSf,MarSC]bsKiI\`r()r/S^U#[YY@4Wc46si. %ea_`^qI7]lE^\=<\5qh##/()=*2Q:gk*5?<7K]djEN_:AjZmt)qbUr>aS&de\J6\FCeXk'&'1#&UAPR`m!N9$Fn %(GM?*]si0#@1uEXJ4jmZNm/1A6Q#m#9opkG`2GT`FB%<9AQsieHd::[)ZHn'[_7Re3GU_D-C8m?/;pc4f'F@#ouK"M`/OS(Rp6W_;:\#VVd^94 %;O%f9@\b>^cT"(qQ=J_jd+?me1!7p?-\V/1_W7=qT?D&aH$,!kH/S09$;)VtgZjH\s$>$_H.MPXX(!a[V.9,>"a]8_g$jFS>eP6s?FXh&`!Zh=[4D%M628_(F!iIAH)`cmOLU(A4ShK;9;]P?(GZ?;O5<2n0r8O?Df!SL!=+`q.#'EALJodE7J98@#r.+shW/oVIen_OC!SM\!p@H`X%.UbTmMNG6;+i!M7$H]sOMr]baW7!:V=\+"YafW!D1SoY68Q=i5*7;_WrIT**R:J)@icT'AYIIX!ZM]AkLTUt9@<)kY2AY-%2M,3bDDGN/pcRe(C?YrW?@hRd2mAiB.TEqANAqiWdpE@4+Rc_--L,[lC0/4o>r>M\#i>Z/< %gcN6$TPPQ:"kG)f?q"(tFA_'"3L]cN`UHm9X$XI6esNnZgm0J-.BTBdm4&H*PS(WsTIH)Rc:Gk+=Q3L"0Rkp=i$UXkJUW$ %X;?$(MSGYcE)qTtP;+GcHtUs6`Bi+XFsm>3@,C4JOJFW!04`bWh#Fp7AlEK%mUE2q$F!h4opN`9Js:)Vr.6&s-G(l`ch/NO:g`)KPRIk]XVkB6eTITtTfCCT]iI:NS-dT;\seDEXVCLeV_maT0RoTeon+sESeGs1MV7-D/[J65 %gHU7#A8b>-$q!b.&QWadmDFm)qMK;blK24(9g*2!VIUtqI_rK]X&9EP/kJ)ZC>fFoVIF,D3YBj?>!IkWY$moqKfpY^97[HKi&H*T %VN"#*e4?0cAEEI7JLn\$OZ]]1S=/=Z8c,Bn_H]`b0DO8B_:8kUE>Q.CY0> %^e\J',g!=>=0/N=B`i,n>g5j^Iq\mc0=tFZi!Z\f]Z,t8-j_(eXJ3t>f`/m*Zge5<:)EK8XAYPmc.b#6JgS%nXh'Ic=01$XKleVP %8u8g.0'j3kZX+ASft)$CIfeUK3L2^#1b/_*$[Bg\;$.5mIj06M[6*^m/KBh)_Krnk<02O&_p6u$;U+&',;e#gdN;)_Bc*NQY^r7* %F0em$INq36M5R/o2IQekK\aX+h1H'7]_VcB,()ZmCk@I=TPkOah@MuOQ]pjnA`=#h5'`&o>0G2GZ/3[Ko!m5h`*5'+;BqrNq9.$# %7WMQBSB6/YCA]EJ,0R8He_AQK(gZL(%"OW#=?&a!L)Fm%`-8>2U6+"([$h?TG*8K%!#RPeSLF3SUo%DF1QT0Q4r^aFZW[A`26I?0 %%d[@Vl9n^KeasDoF)tb-+F/WNRGj@?/='CQm/(\loaRtM*"*(<8pg>lB#t6dZp9u.;%U:e$2Xg*EB[J^[)IuPD>:c$^N$YMaX7,Q %n@/i)Clf(uKZ;7Bm]!(D&>)3*Es7dT<\Qi-.Po%@nm"(E^oh`\L94a_)j8(;g>D>5!M[aPTH*$;eU6=p9KA!g?hS9\/PfMtnJd`"X?8-63)L=e:- %qmJ!kAqAL;$8813XU/@Y>Zn-@+_@.M8M*(`q8Fhs(I>/"TUP\o5us4W?@i3-p=FfnnLsq1GB*idph,(((r0MYprd%Cdrj7ApOE'! %G-_.Ss7+oD5U(Ahp$^GGs&>eVlJJ^@+WW4FLcuAcsd;;0_-1)'imq>_)4#aljS2b4K/4hPW3d)q4X_Ak(L^H>[gMlJu;RWt_uR %%!f`+$tio\+lNfcS%=FV1jhV(L.*R<3W@Q18C?+qWeg4Oq$"@#Y$mjUOgM.])odDWA=1!0`3]Zq4*0Ub3elu*Fa3j"?qY:_gLN/[ %e;-_!C2?j+#ShD8f=#A$NM@7C%(c^4m3#N94dpF:L\e3E#'L>WKn2YBC9S^Q,-]PS`o=WCV9(4.$FBQM$[Fln&*SmVl[QE7$;SLk %nJ02+.OT&5WGTb6oPDYn:J_8hH7_q\.X%5_=>eN^$Hu;OhK< %PdWi/X;[5Khec!"iIIu!2Z8LSAW[MSl(ko7%+Zf&hi`^@8Ot_$Q(B@O7TR$(XFI$[=14*qnB7upfJ'Y_/#6NA-Tr?VgPgqPW#HZ3 %RMBTPDf%(b$RLkL'cq=CY5)\_V$a]L;_,SED_I*K.@0,mi5GX!D.Xa>ibsiNAfkeI%U2EdWZfq9*o&Bl]3K3gnH]Ff3W0k^+OT=S %#[Lh`P$msam\spr1:71j'P#Gq#lqR*I)34#GN>H4B_7Ji1=mt#R,Mnk73U7EYuRo'\rf\+(bb,#>slEQ/*Y.8Qkn4!a/9l@5Vj!h)kS='P*sMAfk,6hX?c^WXO@h-`W%Lr@0)[9 %?7>be7TN8'[5PG?[Dl_.%XS@]9'u^jD^1t[F5,,)/Ea(V<1&P.4R,Fq*>Ejo'XT9a[e9#UT[jZ %70d[d+hX7[D6ekf3-R]WD_phH7A#+RlR"nu>rQD'j"u\%.h*(h,?[8e.2.c&SrP'aY)*m^d8;WE$q3,A[gt=!F#CFX7C3*c#8q9) %14UMu*,1Y\Wj+0QK0C/9'YA(g2uno.BD9[&01Kh*)sSWa-L2&%Rb7op6o^!;joDC8h9\]4I2YUOhi."Zmmf %"p.Op/TiXK*MCl[EH`@,io=l9Bl %_n77S+"`4Gnm2mH.!6Uo1ltfQ4[o=.Eru?kp]QTR2"DY\W+%$qN'e,u7+f<`Sp-+e_oShaC2O`b>khdYY\6J0>KrrRoL2mZ>5F,3 %r+n=AlmNP[QH*j^.-Ss_:h+WXS)/c+@TW;(G7b3^[?&Da1&+k1Fmq3HP?:)k71Sr9fjc0`R[?+2[^IoUOqB6Q[TOip[Xn2I@6m/0 %EOCJ.)L2N@A]4g1\Maft;T9e=fnf',W0%g"e6JQTaMM]0DIKfFe>Uu$n,V8nmD$hr'dJ&:kbsrjVR]EIRn0fJ*7\r0T&bZL]IQ/1=q:a$0;,Oc3m=nKAhmqK7jQu92;e`% %\sXED5*F[l.[]*%Ni94nE@aoP"Cs"E!dOD'm@),i7]b$)D_lm%K=dabN,0_&+(Xjt*'0HjNmjPte5T=)eY?N>Y3(`J'`hnUe+E`n %SGUKS*G1PGK"Zg(Omg:1>m#BW@VS:Pkrd^&Vn/P$9F]I%i9JCNjJf=BQ0G6D0#h0-iu:`LBiZQ*j+NSRO\93S`OX#a_gC'.jXV7b %a_)jdK>X&[5c'#i_cY^(GSk:jB=cb+H/Pc?cQb:,FJBqU]-U0c%g[\VET9M;@%NHJAD(YC@a#90%;+_,>?I#VS!1\*%;^eh)i@Wk3;.5Q-"m)u:Dt7(4c=#pRIPSQV#+qLJ?Ph[i+Lf^m$"p3 %&O&VZOfMqCC:t.k=lPLZQS(r.5hs`B)E7+m#Q+fF8uX2"ent. %/3%jPfk:_%:*0#8rQ9(XgVh6he;Y3]hLth?$+*3)oX^@(.nM:,lU3/%mrr6lM5OsaRoJ`/C;f@:;*WYjcqY8M#]<#Wj7% %;aAc>i`FaYl>$CpoNl*RUM?lQpb6NMT-n6RBZ2daZ:jSBd3r:0>Y)5"Z\?D`fk9f\,`9nKFTd]r_H;W7HC5U-)ml%=5@Qadj %/?\WbDH5W>Z!X2i!"Q,kAI1b=N,SBj$]UHWUIJC/#^ch-hYSX?b+M!I&Q4T(i"RDA=#$`lB7n))I4mNGqk@F5ZrUb)!s*)tqL6Cq %LPVW*"-&f+6h;]LROl`.2nK;N$crespe-^,S-62a(h-ScS.=d%^fO)V-ks3g8WYTEOanJ[G!V#:-JLs>2]lET2LQ_e %L8Jc-N,,JHne8/X#d/ep#hR68'P/a@((q4H[kVPl=^+fIFFejU[55Um!/g+%!X"`I-BCfs(`!8%@02!J)#\Up(1sQ9]iA+fd_F;q %WRTVe+qJ#oKiLq14Mq)d)/[tD8^a3?i-*9M+O_)!,`U$RCR)B@ake$:NCRsV[tF]2d&p)Z83UVUidfbchCINiCF?F#$B;>% %+qQ"[a9FdorhirFRT>gT8.]fNAHW>j2FJUlSbCq0EN(I["3CbCA.'>S2:\IoAAprb7UWfBV@\q:iZZlR*5WAc@";b+:gTa"N@Sf' %MsWi]i$K3ae):ra10\Q70ltdgNXCeY&9EWg@9N)6!Nm#'cAm_1%`!'$-u7s4>btjNqIksaRG=rCLc&/$_J7AM,_DOJf(p4I3,][P %kW/kIiAAIV5c#^+=BFtV?0A):Co"8u3Y\.GT592o43QUQ(h).UbIqk %T81U.OiAMhh`_5Y0[ZYJ2T9SoC4b"Q8AeWlIbW+Pb#H>B%GMY.n'f#pae"bm]#o17\h2&H)2_I>6o@GR8XY1oD0LM4=VVT>+'OAi %S/@*GW-Rhto>$/"%dtltNF@Jcj^Buq:Y`AASY351"qL=F_W`#M"[^;NR0 %7q7^jCT3_A$52ilj/(QOHa3o;$)*n\=f,N[oiaBs;/CeuFR^P$*!2.'B6b2]BJu/O1D9=&ksWGF"e@uOOl;b)aQHA:?9n.[%9>fT"hEXA"F/1D %*.%^Yal*2VB+"=m@GJLSGam/aUM;-WWOUB^/FQQ*3mrjQi"G>$Rg7K:TdT#&b!J]3-i*"R+68[Q+CXpu-5jZ.0KNtp1]"U3q2:^+CFXl*iaZsa,6bsBmFu#&X%j?N-t"q*ZD)gj*U,(gJ9p8 %S#C0C89QTuQDk_>_\%5M@s&_CKIGr'N(P;M!W[3lKB@DNUCPqC:?P[Y9cVJO1]E2i/Ell:q<`2MfAJM9`@-Dc7[t.%X*15ACmi'p*"%B=MKTiIlc!4+GO=*n_9=i%)cV(jp&ef;(?DSRUa3sm %O/75A(0iqjErZ6XMlcbofM@@[B!e9l0H5"5bXh:9BHO,kJLZ3ADGC*f %UWYSG9FBu\p*lZ)h(qP5kCsQK>E;+rp(BHj,q(l<:Sf#""i`qo7'6d9W-'6u)Zh$L`^Tqt$H&;Ea)a-+=Z^$GuM.HV2?69P=X@pU+d@/e\WJlO1A+C@Y*8KXTZ[EZ3/l3!@J@=58tjUX@Iq"QW"*8juPY! %D[#V^6?3QJ.$L_e9?tu:N8Zh.dkh:YCT(5Y#&`MF/ge:H9+P1X;B4c!4QUT^9$Y09e9"c%Ak)F^6F!9!Or@ar&>H#V)kcb6c98VY %9u^i=W@W1mb_]4O!4uG/[%n\r=!PCuV8HNcf.X.@ir0PI,g3/HEEP.o4`O#kUVo*$YYZ6_;rgg/'-fTOf`qNf:!:A\Q;UF>L[aF[ %2/1IsR"M7*Y/;Hn^m\t3GdCPEo@siL-WfhE3;O9EKRej9P5rruHtcTFh9psCVQ<[QHpu1mB>#5J_qN97c=LN,iH#l67G4>llooIb %`B?,G9oZ1o/iRe%9qNG$SZuO5?2=X&*df&l.$EYBcbqsIm7iekZSTV*)#ludi$TLB^eLGMT[33^*p`.KaJkGj/7j>LZ&"P:"U3;5\=F"]4Bs!4%Q!hsHIgVRlq1a%g1"Q\6$>]dA9nSX?4:pO%gg.n/8]V5a %6#5!dU++XPC.p7sj#T/lR8KUfCeKkI,YjZ+a9_$@Z;UE>:I$=jF)=-E1-Zp(2#N"Z:pQ(!Kfj*l4SG?REh^B1f/G,;N>GQi!)J\+Z8U: %)F+XiqEp7Y%E>+I_qmG5i+$'4iDA]X&ulF)>EW#544Mm)N7tCK>_Vc_qCA(%:9OS)<^;p:%9ift;ek&/+>TOMW,6;)KrN7`S5h2m %gX$H9)Ku7FeE[p)uZogu_ %Q^8NKY(.A=[3\@5mT9qcE%sZApK1;>aQ1t'a94FZK8_op %**[7h=>Q.,,FBq-:6&cYB9W,D1P3ja77d3*-pOlS8fbi]no$5BqdC4;0cg;qTqEM?&',P3:<\MHWCG?X\5^8P;]L.onCqDT&&j-J %)8a2WPh\>eb46mp%M7R(1]Sdn?DGPp>t<+0@hT^oY9?dmq(:;KHrf&rX9X^i8;50uf#:b@pS\1Ch"3!:N6kJK2NN]:`i;b%:"mgre2hfEUei9Ul\\3K>;_&ZfT6^u:PJE[kpn7LM@h*lO>-J76AM%`\"$`=#/*1=9+GKCU5U?K>(APJ_9%[+)SiNLM$[RNIefZ&5E-;Pk$!=BS=1A*l\tCIS/^]N>\fi#Eo/Ff'd6o**<& %@15]!;pHH0PJT('fdV5Y+WErui;W"1///CH7pDLcRYc\\5`n;l=fJ,sq0uRd %"r1gWPd:p?ZO=i'5:NX3rh1%*Ep#Qd>?K:/cc$B-Oj/u1sl$+&5*8>`o7Q\uP'1#qA+03sn=ml3P1<\RhfLmlMcM)MP* %]*$_b/o7K:47.-g.FmM#C8F_/$oj42pt:>`#V#)4l7bOZ(1tqFVA$;4-42Ggl%';[S*$13-[1M#EWE"WD7[ %aWcs_H>\V/,%ogV5mihpl-BgENQjH&AgG\lNadVd8uj5:`YPQ*ZW,:d=DUC4E_PA$H$M?f+oMjbOTCM1JT'">UrOBE"A%2rTi*^f %+9ULP#Er22)R4-(f08u?,1H"9=Ogj<#)A_XFlYJ,QOE#[$_YL3L2clOYFA#BW!MNga;V3NB\4dcc&>*Q>-e1(*JY>7%Ma``Ck$_. %Lms3p$0g*q2\*-qW#D!1l`qo-:aPTk3";\[nIKRN$8[6__c/$&1=a?lk;t] %h)iFiD1I4,.l3e5>c,Ef'BL$eatX@>!PQa4.Dsa>Xh7c9&).99V2;pX!H^=rbgN?"gKd&pST0(=euK\a9&5a8ZGiQ+F&2dX[a4O_ %55WKu?io[m7!3*#6>K*W,,;nDW])0`gm#B3q(2qGETsl%Tb.J;;X(ZaAYbZ1?o?'Cgn^:f21X4DmSe1CFRW(i2^c.XfrD4+7Do\? %OO/!f,b@%75SV9NW5`?ZGGr^Jp="FUXhj7;5(]7mZjA+u#-)#82s]99>)*bfW)Lg,26o%`B;;0a7H[Ng*>NE[olDhk@$A=),4]9! %HAuk($JLfmP4PV6,@O>N0mY_+"W[K/"SgT.Zq\Yn@JbiQ!9iP.NJsdV=Qe@8%Ul-\-/+J&8WnM2/\oqpk4#@I^qtoOFLYKW6cNZ' %G"`tF8>q/u)$pEc@>M)qZ62MK3C@X^G>60+X;S %2Qi2\>D`p[\0]7Im3*/g:i6DQW%(sPdk]`o*_,+TknKN(:U=/-->DrNg+J/7V\MmOYJQ,ArOo4MZh3E;I@Utg_l\#TjD)'ui3d&+KFA`#:D`K&&m&npd*q7[Vbru7N+>a#mZL&)*/HUcB/PJ_ %#YOVD@1B1hHl4?$Ws=JDit?HUof"%d>`>mrc6AW)1-]A`*YPH$,%BuU-8M:E3(`'S!0b`>EE$ckj#e`[E'^72T#u4#_DEF+VTs4U %EFk/]d+\#ace9`:B[c4M;q!DQ-ml)'>tTr(ANsKt\2ZM#,AdrP,V.(!^nu*"G+up.SKu4"C))3c#"=`kAmM4=ED'7DMJ4?6+I4;) %eV7H!fWM4;m_mTgA[_HX3N\+%)@+ruA_Rr)"-)oN8ZokKW0g+Pbu%RFot@[,J7_1hIm\gW %'J!.KPMLCA6Ar,]4.dY@!t#?bPBF59`%7(/^56V@b&hgLFB1t2Q]&0bPW++k+Ho5d['B]Hi69Y8)=qD>VJ1YE`3flqRB]SN.$s>r %$s@;f%ejYe5-PejWl24WitVK8-`re/-?5No5cU/9j=ECreZ\<:]UuRpl2&s2V(>gHcaG+S!Ud;%,_-OiF %'1>uhXhjm5J=tSpj"k[ZHnI'?YC91O1W[W]_T@)Y,85Dcj0fm[K,$'sZd$2nrH"%0ark@-X)1c"FW:i7VmUIjkZn+Df4Id^ZBp>u %!FR`i$QM/Y'L^3k%E/W>!s!$sE,&rS'J3b$DkYBl[&Wm%Rl-V3'5JEac4a]Ub+_l>b6d1Tkp';;I6Wk02sQ++-kE,fW/8m*h9Q47 %m/SLrD0S!k]Ga"WeJ$m5!XpoTYrIuU=`Hr1XT0JFf*"sadfj-jH*mn=Z;M312k\JVPopZ:OBN8LR[)Y9j%m0#[0?$NEWTnFTEt4B %?*Q0.IZ#pBJQZtr[[[5=?E3,"fjq[YM^#:`=98!*)O\L-RP0se'!%J9gMF:$^[hAlmskH\WBIsb]GQ=9b!GcfH:KT.]:_b:RU'*9 %$#Y01f4sf89QufugAl>>Ej]me2@2"[@$jR&!^a$<\`G:kCITVrg[&X>%2>ErR9k:k^9TWJcVT0K?o %Y]an:B'bg$V>FrLI__igAjdBA6Y=FnU7&L^.*nZLELTL+LNa6.<0>tP,oSB7Ls[TK7;nOF,*K7,>uF5YnBZn5.H%s'@pd:RHN&aM))up)B*XiPH,5; %GCTb.i[4ul9$gl[XQ_Qf5bl]=A-:UW,Wst01SUY.4BSYV;.7u-_j?aC2h5D*,/Lo-!14ZDJQt@P3,39fUmRiUV):@j\i#\LaY'XM %TZKe7cH;?I$+%MXNKV?n7P%H98)gQMj<8-^T,K6L*/>a&lXk$8WP2q$pO3nRfQo@*MXmmZ;%IPQ94SQ0PsW\GL_[bm`@Q$e\h99u %hQ[)N7i.)&g/hC_uTKRW5kjfH-WX:_s8lPA0I5q %G6NdpXAGk^^+XBM1)/-,cHJS@mnge15+iPJ52);5`C@hY=;D@Bc4o\U[0n_dMclRo_g*.^(Ad!^qoERb1XB=\nV#tlj8'@W)[@#p %")JT+>b&b7n)gtk6m$N@%f0+[hHZ=8^G7FurVHhp=W>6afb2DjBUKb>A$fX>cj&AibFg&_=NnMcnrmCl`Qu %%u!(Cg?cWG1),\3Y!Y$e6GZ9Q8;LLUOYB4+D4MXI:o\)X5Z4OiQ43hNEcW7A9O-]WrZ.s>.qDA?V3KX2G;)#Z8S)&7K?g^"KqQH% %r[WorNF"ana-YmRUJIB>_S=6:ffDDjF/5p:Kk=O`/Mjh$OZoZ(MK,Q2F,;:]0qpBM@,_:-EEcURiY;4oGb*Mq:S=8] %5+nk&X?\jQe3Jk+(^:+(+E$rZ/-R%3bJfS"+6bD"*[Q5!#UYnL.nj5:Xb,"`>ED?UhhZic9o2eKq_$>`$%uCsb2DdL0'7a5@U6pP %AlQq'i;k$I(nJX)N1G/>W4[@X?f*G"oiM/"b>8("MEPSfHbTL*5CFBI8c$T/e7Ot7Zf6]YDE\6i(?ji.8kRf!L\%ZXcBR-(gH"E@c<,+(p8XY#R-S(e)727$U@gS7ghtR3Lik7[FFRXFtO!_8f)<[:me %>`k.l,\/fLYB$V^EPM!g2$8=6Am%IC?6e)i;B_4(%#SC8/rH$9mT#*m'1\C[.S$NaX0J'hW@9-2U]sAdHa%&1kLS>hGsjAVH*XQ; %-&/3NjQ]`YPg_KF;N=m4&.8(CgDa#V6qc-DA2[Pr%AYU2]?FVO"Yo8D6CP!uD2]h+)2*O9/qdhifH[WiZt?J!Q_@H<.5%SDBr^VG %E*>4qUf*5ER"fFY-n[;+2AbV0,#d'1"kcPnVPULDQ5G&1l4[=4#t=H?E/AH#QFUKq<&Jubp/n1iVe-Y:'r.U@r]eW?mB.bYFX6Y` %pDrZD!TPo'Y0-52i?-L!%EiG&L'B!S(`3>;L`X`IP6*>D^pj&u=:m(LFC,K9!Bh8+U7,lLWEm+c.s#:'=:mNrkF_i@B[$5`/-$du %DFf_I'!.T_X4Ms>at8Yg7)P]h[S`RF\B$Anq`C>kG%,\D8WMf7l,u??cC,f7-2Jm^mHBfS73/Ra>GZSf7S%mT]K6r^YCB1gIb;P! %0'gZ(%/jfn.ud3[(gjpVok=3q/Ymn_OL+eJIPss:+pZHK/H^i>`sN#G5J@Id#g_CMD"sA-b#n.("-!/!]Q\AH+t!8u6k>3f]jL+Tsf9#1![.oRHp6^,&VHs)!f#^XuE%?97FXfF?^`L&\?oT4@5>HA\/MZ6Eko3HiLog=)m %3"R((Fn;lZc`)(ff`k0leLUF+bt8cI4jnh\QHdHQff&Cia+cn;\FcLFW6#\aZE0`;:,.-Y/fR@5>;:I=242UP((3["BE[dfCcnq" %#=#P'_JEt(?*8(H3[JMP?L&au5\"HMk+>5J>2#;eIR??/VqJsONp)DpdWX5]h_[G"dgq1nQ/gHVcjq8JhO\<\bs1YEcG\fFJfmr4C@OC2X)jb97#F7CKUOug3A)3C4P3\qL#r:eaf+Jo=hni#g$tA %=6XDZQb^2mof+Pq4"d&p>[-G\EQ@M:Zbf<:QWtd)3a^S>HGqB)9eX8LIWoNmoPC9GbudVdhep?h)VYVU(9(6WJO/O%WnW3._VVWF %e0K#4">QK\g)K]8[>S54Nc1AKN8q:,OpUuh>qYF.+b"K'l`!Bq`HrEAmY@ad)83#fSUrc8>.1na1W`C. %44Q%\@6=?na(CJd]hU1Z/?Fi%J(5:h %alAqsYCBVcT_U;\[.M/a8BhA5SO#jFp/mgA1^\U8\f'B&=eT'-eO6Ir[$nn:M\hjb;aF->L,am4n" %+IK9.E'\Gc)^KGWs6_i)2DOl>OZp6l5+bgr'[.$mo<&qtYKMl?/PiT\pTU2GmLET4&h%gFc!DV`]n)bJ$1 %L/SYZYLjPr;ZbUF^4[a"LMQalf+G;$X5"JkKeib8DnPg>4\H&bD2iI/X43T$8fnHKLMOYnc=dV([Rc,0[&I&N%D?+7F2e-@*N"si %C;8ZH6`u79i4a[;6XEfL`Eb4AB86+WjGI8X7atqr,H'j#L0SmKq=.5g(lko,]>gAdr7'>9n-i_ukP0 %k[fJj]66Ufn"PI'JoctLN>uD`H=lV+/%o9u'2>gQ+CYqn>(6g'dY^cP_-Y;NUCOL;M>`@ME<#H)BV@S.'Te9)>26'U*UbiN30_:B#Qk`JfD_l8[=j.Np@4FZ+`m8>C;X(RnE`H"51?q`K=[W9+ %o(J9b4i?M9,F1?UF]BOIZqs`98EBf.2RF2+kKOLs6Ye1:K#;K8G)Ds0:4.Bt\+>lj41#A*h'Y*5b?h`),7:-P@k91^&[J%eCicnl %L,H,;F>1Ub?>7Of)r*BGa7@ct02g&&*q?HH9tChkh*JX^_+mPE]I&s>9goB)p=bRQAQ=B6U7lVjTka"YK %6_:`VZKX28TY%$\oMAG;0I9ZiF*gkPe>V?aaC%&F2l1:%mN)Reg3Xb&@/ZNk&F7`oo<+u&%8a,0BnbCV\*));N^[P%0i,Fr@;or%+*a%/.*q7MbE6[K79:TD44^K6fA0%:GD*kdR.ZWF%$W4>rS#/>VpN!klb;7sg%#mV3%#R;!6*9p*KKe4jh0DKiGh%9Yk#@HQknMZo$+<-]'K?DVJgZ;LGOP6FO8l?#T));jdUm1ePDR;kXI7nIX#0MPeHAc %oNkQm2!.PL`]QgcE>kO^D?ha"bOETWC5aKXo;a\a1$EZ;O[SS2]l8UPb1eVb9E$6H7h)gr]#Q%ON%9)D_pB02UTPX5lZ'#"0/J0T %BkiZ9k-_<"4fsVPZ-@tHMP`g^SIQ]o"8X8`6H[(laR-)7,Pi==F@!*#4+U1HBa&B7%dObnQ6Sk6^HWp,_*>PjB9q0L^Hjd3 %C8o0:XYi)_8\5';%Fh`?l9W3.Af^3<_L7/gI>p-th3P)JLh'iNi)!TUS8C!l*-K*?)OH))*\luf45.`B/J09#?"k5I[p)c#[-8mV %WBbm#5_WYk?ie#).a!pBJqI2O.rAG0"q7.93FG[d2q#0`;dmnIp@A]OC)Nh\;J`h-<2DS82>`8JXDURQP%/n0ZdHd[/7\9GW]$NU=C&[l\er#HoC8]`mX3 %3dEMr?'?9U1WFT@=Ns1g$Anu;:9t/BgF$rTgX&/nV%);_p$YCeg)q#:D.K\oFuZ^)P]kZ+XD350qNPB_g1[F!>sQRQK/>KC]\s`l5[p9IUl=DfXne3HC+1dZ/(^Gi,C=L %[I1hVlElsr=]al>K!gnr]N4:0f!2HG$2oW[bA4a[1IZ)?B697(-%QbpRT76?;h)J]DE.(otKfP:El8E\F7;, %[I.(4nF&^i1?f#[bC-M9d)"c#V.kiHm\Dh.#8OMIA4^*FIur@a#`T.+Ib4J6>c;fXUR?sddufsGP:s.\/BKF18CG4#TsUu>r0 %QMhpNhXNRBH[#ZaAedV*]l"T@(X+H@1Rd5HqmE,3%t#XS[T`-.,iM`"lE5#:7^o[*Nl5W-2sbY8*e?6SW6'505ZP3+cB>:O4_jWH %['O]T]*A^JIpVR-LG03g3r:XCLm$8X.3-G<43OZfd6$3Sce?L/]@!Cq1kKeYX-"6K^ma@^hH.T,NjY(aeEFX1=I\GT;LR4VR'H8i %kCu$in?"&=>YuXD4IF^mkW9`L;.E]sme;+,5H:N&kCB$`XYfM!pinU^Q040GN*g,\iLS78eC@5iZB5pT8JD1(.2QGYjO7-A[h^UUk1q4@#?-"EAsYBL8sKL# %bOSdJ*tU)$ECDM7=6SS3\hoj`Bfg1ZnM>Q?;c&Q2Q;J^rW!#kg;%Q/J\D<8$G9UV3Y)toNd@l10kA=g"8eM0LZ %&\PJ^D6`R#4n-u["2RpjkJ1[m\>BnKEO@1*4:Rr,/927tZ,CY4YKUu35\3&?KVrXP)(s=F8!6g1YXQ)Sa7NT/jfc9YgM"%$!]@9[B9Y7G7%DmdM@skLW=A(e85aY*U9O1ee.93!f!;5oXa^+YE:eE?mJ[@bm7@NahlD?(r@dU %0pi!SCfeG\&Cf+nGT"u!Ep?JGp]Q$K:sk4\\]NYQhuRK&duD`X1ZX7BP%kQ`fp\r-iHgH6@mc6[n=X2S+u8ME^DS&ZQb*A3`!$+C %oOS4C*ausL/!7E*(-`)i;TH]7B?62[_M6!p2*?S&&CNC*b?=GR>'cAibN;-f_Rk*X'ikAq+>677QSI[M)3LQ=F5.p>2#^^@5'mp^=/StNR9?-Q89MBE) %cH'?=Nac?eAoD[/$>/fY4VYC4dY$du*T'B"h%7:Bo[>hP"Oj\hoSc'O- %R>u^m=X$o;j4b97KYM8W.W$,&.qC?]H%\&korN;E/iRfWQ7.OT]=@LEYcg-kTIKmeMQIn&lS8V&\.U6uF_,?9>'OpKJJ$CPOK+Ib %Bo=YAoLf2FpRnD[-?kP/YGYUI1q<>ndtF6Ta"LeMY6&5s"A19m\Bs&b1Zhu*TM,KXh&JY6X%E(mbO-o#2&YO3+l[Ajl"@Iua=a$s %SnkQFR:&E&V70G35=p#`;r#jg;KNg=sdTn_1c9I-,MIT;cce,gS+55t, %&s'=+/p/&F?`A`bA)tQBM4n7/GgZsj@s01I-AF$?XO+O?KJ@M)oEI<.T+L([C\"pGf*>K+<4P48?mUcW7Y*#((SYtSZO0!5`CuOS0H]P>9E:r9G %mRN_qHh'7">bZdDe!X*h)@=6NA6'%%(t^qQ7XHau,i]Y4Z1kaAf5,Ss:-3Z30DE$4CkT?_6+E\B,D)fXaoBfiVl_:H6N#'8RMG2P %lj7W7%s91;5&)i"A_c7I<3&e[6cIUO,3O(XF9A$<+Z:VMXA9.oc"-/c2nm^rC0?0QF)H`?`BcFY[1<6t\R1TZ`sPN9.AX>CNI)#f %)c>\o`(`_7NRIC7^1icTo_mujnH8p@Y2fN`CsA(.9TKS>(&ce))O8>1.=X+p6(bQe[78GO>J%9>LnK+6D5SrQA+_I'f=[Bf[iI*E %h*9RLcZq>r,oc!D,5!5V'QN!@%%2IRS%3Di\Y(3/:b4:uoo/'-6'rCNUjfJNq3J,bppo40Bs&5qC7QM%!/4NSlc+JM35"+@?RoPW %cYPBHj+1Kjmh!%DasHH\^bbFai1XX>N._ni_$PO!q)=Y4qZ$Qj;Bjj#$CWIa4]3ps&/4Y$=YNHejHO*6;*[KmCWj=="i1tJIN=6t %k)e]XIkUC%qg!Z(8F@]_-k&mW_sIk=QtF&g6obqCFX^E:-Up#L^"IFC?=oHjeT)UIZ#ON*0^gW(gi,at)ZW0XadtQ.OZ;Gcbmd\AR1(uU;U=Vd_ %lVdKtO00h=@aCVYp7V(2a,8@6EZX+aF>);n(b"umQKNC7%uO]KBgl`I5JQE%+Vn7/WUBYMMcBmu_4,WS;u#lOIfdMsHP(:ggIfNf-6;*LU<\CJS"`UUU9g7YV:fU;,A24n=M#i0EVK,pCjL-(kq9f %9q"m7XMN%e2r]'d1m-a]KH(8-8NQ!fp3UFrRfVQd`==t %X:F9`C\uA&E$h@6`SbS5"6"'#Ps$S\Oa:N<($HLaBWq':oE@AB1opE?>qB6k)acLDQCb_\s9[]_AQcn0!>^md9PDrojlELXb3;=+i&o;P,?Ll-dK8%gTGuQF*9Z`@_Yp7O.o1F4##]Q[mkF) %bOQ0mCj3Q'e0rRr^ls$('EO!qZ#]1hF"1qF[As`s%<7Aj83jM8,mT"`LGi%4WuR1&KY>ObM8m#jV2LMuWun%Vn'K=dK&4oc`'8/C %IqDpH]uLZQk"=4,F<81H>a#Ca)e7^Ri\GD'K.GEuI714_gm%c9<_.Lt^^7H:!,^i;@8g"gh;]OTK*YdX)qgi2QV\iB-_,SKf=Ceh%%6A@<71`k!;M8Y!T?&DS)-#bq%D+CRfILZp24QfHe5$pdpG9C,9=&0)o4;-/1ET18^c`+o %%t^Y%]SUgE+,=jGEq_J4pPCVdSPO'hohU\0#Js)sg<=_X<$nV8]+DdWBT['dc,!/K%(C#al+!4k]CW%UkkZ&#:t[3l"/3@%"Rc/$ %l#aGi6gPq.!J4GM[J`]\d[GQ@IUtHC-/<*C;=^*1WWs;Yj'5'BUt^R^M`,N3RZooE7in/ta==SU!i?3-2!M9"BOZROdUfLmbW]`! %&([O.fWi=S4kB$m.le"]LSHcHRf+!e+a4jqh8RiachF3W%>T^FM2qG,L7Kp@/:?(G@,>]oA,n-hfGB,CJZ@G%Oc %d'NP?_9j5b:$ua(CoNBp`)Cd=(2i9>'Uo!M*nI?>-B_Q]Q54&FgW6*LrV3@YgIJ1?;&C@R>QV3r2;uj5W`%Ul`sSqG1],cr';d+u %QB9-HS,<'/"2[hI"/obL3Dh]/,Q2#>=0d<9[46D(%#PIdaW%oeD"F-LQ?HC4l3*Cu1*1okM^c!GnBC5F45IMV>=keCh\1iOk'9.o %0WqMZMm?0m\<$'WQ5WoXZ^gJ.4i>EB7XM';:lF"Dod3pNnT[5JDndSVZu\2/9._ZHf$YGr+jqq52R_.;X$.)DZS[iWmFD%*M&R?l %bO=)%Qrki>$D#bm'!Ch,ULr^k(B\`)-Q)3l/Cam?kV?CUm\9p'^Za;sc(u^B.E%s*)`h?W'uO?R3qOpJ=Q?dNDf30B'C9G!EM&ik %Vkf7qC@9_k]EGuM77-pRC(XXp5i,OFl/VWj;(!Js*@#e'`epH`/pm$NXHK8FiDY7tVmPEBk"/b!USjW/8csN:2&EV):,CtE+ib+-`3OC.jGX*"90,?mTl=Q@qaSg\suL\b,#k/"LCUKn+E/Io?1\<>Pl`lbWtJ;oQAnn@.HnpA,n+tp;2D7CFppg %P(9lDTD'_+60>*)J_cB=5%jJ2='3t61m=MS=^;K-4-I1BQRu2Kgki(sCrVjia;mRQ %T3!_91p"/P:u_-h_0-1BBmDm\Tm_Ko%aSo7Rj4<(+Mu9[G02kiPN)%)3Urc+VoibcDaCajO?au[!(nTqjHK3+A[dW2.O#f;=.o>#2kIrq@H4rm)a91!Y`I4=:Ae#0Z))0J&Fhj;P8)5r^pXauSC%_m::0hhl4"G@6jl!Mk%60L!'J"AJiiH4_ZMU'!>Ja1UMhX3lk^uq^PFkh3a'9I)S]!6_O5'1g-+k]'`(hJ4EMY/C %j+J&CWmfnN!A*Jb3a,7?2`_-lTs %pR)bM4'P;g>S]tC&!B_-H.E];fXpk!e7DT0CMt@(*Ploih>>nDG#*Tbl4\DN_H;t.pK13.X-o':EcAM])S@V:ZsB!FpQ5Y6fX;m: %9;4E%'kE=*2c<&S*)`I-bg@>"*=hglhRD#BJ+`j%bE?+Z7N8Gn7)AhQ07B4>NP %jO^:@GBu"VI.4em5"!^L+3#)]1$r3ahdk/X(60!W>;h]>ctf?U_qZ'e@@kig+t&:Y.OYM %JT&-qfUXMnHMUVGBGf5S_PWYc^N6.Y&bf_VgQq)r$U&;#=JK!Za'6eNgTT(bNEKLX>"P1J&eQ-]f$K[XXgL:r,Rmfju"ak7bVj/AiMbH=rQ*R7:7X'u\'Ed`INPG9kao#lH %;6hF2U9^qa&?.S`VbcDL)1WXc`!E>jNG>m>,:K4q#"[\$L14)3lIBRJ]3e@7$C^+tH6P4AlOGE5[00Ltn?p.KUra/^8MKhbhqk$<7k`V"S>.?'.[+e$3cHe)?UI/UD]G!$R)XO@>U`$q.c4i_T&+#bH&P+BN^C..jB4g:1_tF%8-h*p4;\^Ngb4maBm1[!r)d.r=dLfel)5ktV %5Zh%f=R/Q^>PAH&,3']VV(>F,OD!C[!r/e@jN$).0>OuXQL29IIai4OFpdD(HhMTXXrL3@XZ!Jel[+r5G0n2OVl=Rs1Lg^9G>Vm$ %VK1R^_r]O@\H;E=jbtALjEXdIEI&+sSg(3@Wot^27h7u5;EYgtl4mqM.#BJ@_XE#j)BoXOE<_$=tBF&_a:70g=V^lJ[?WPZUF*O %E+SnhZuh`Unq^BqPW/QYlHHhT'J,)MAHU+L$nJU4qRA,D?fIM"N--KBRLf;KZ1&+4@/u/[l.?KbnE2#Y>BKekFfsXt(P_h>YMJHp %i1eMlM]0>eYFn#GG+ApB]'X7'C@WfZ5G\Yu^@Kp/j4u2OXR'.QIQgua$r6Tk1d5$rFrtp"f8[EJ,qG:-g:dUphXG9N>^D[#262>J %(N>1^j4)9'P5nuHX-q5(6mB6qgJY4GYd]nV/gm_P&Wp$C\MF7k1c4dT++,ocnGQi[Tm5b;1 %0]s'>I*&UfYAA:8:\q"`]+M]>#rGVb@ea+r/!dsT&@J]p2716(LYd&9\Z0i4T88Elm.Pl+]n6NCT'DcX,uJP#bHN>\>!A8<2?7:$ %_A*rT!?`7'!EiCb+Q,^hB^JFi$P9-'bQ^jM'ZC%/l!E%\T9Z-;Z<3(ptS.a?u_O#QC>+uAE6j,qc?CqKB8 %Du;PefcD,W=FgEblF]tb$!&KimG#qCC\C`CeSB94tB;d[%qeec`qiZ%EYB+,*BH6jll;1G?7b#Fis@+ %(?GZZH^l5&cYa8#cjQYnK'(1t2$/)OOEn5C[SlP(NaK2p\bHc"A;/(>$JUjZh/FA6gJ6)e.k09YDCf.tYSNWnXOpBo93SMP+0'Vi %)Kj"J^pGi%>P[iu',XSiBMYVpmA,8lfKn8sA7i%7')#+a=AaEZ9pJ2ho\Hs$pO4)'!7?&jd7R1um(rHHQIXT2J_AT%A3%UNpQ[TR %ga)Oqmm*T5co2->8MKqG_W*Dn38KN>-+/=4g3WJ\?8[#'p)dQ('NuTme7crsRdlVf-VQ#.VQ!@fa.Bj*UO-kqS0H"u-AqFjZ0dd_ %B4d@u2VWGZHH_^]8%E)gMIY`d"[0l[UeO`A/h(\L0KeHq*A,leSekr#iXYFpLGE!E[=i+pSL`UJSnZ)5Gaa)M$)-cdi]O=WljI+) %&K8]`E`gImQ#kg@+pk-)BtkX(br]!?9J%]I-/B#d7^dUq=&T*&MXOXt0gq`WL))]r2L4@s.h:R(#"(3()NR\=*4#iWW*lnGDaPsp %*(in*a_$IED0f[s&HM3f1(0jF='R;&(V7/gbiJ6_H5T0_L@\7.^^aS@;>W@Up5?/HQWnlV`bui!O.Pq*TZDm@SjB73h)j##o"h2gMn#R3T^u(:6G='^4JLo(V_AX;_VNs(!jY8seg`Z9$/:>Nknsc5&?N5#AaK/O&&SOhe%=a:sKi?(AHX\M/%CV41a,DVQpO84,d0D,_JF_\QW %)Ll%/i5Lb5dLUrrmGO+#0&EuHcl5C.:C0,VFj(QihHcmk,BAJU'#Sr-5&5M>+spYp:<(qX#lbhAe:J95,7clA8aY=F=:G;8Ta$E. %3k"?U9S5L3Cr04^W#42N&_eAt=a>mbk%J().?Tp0X^W4HRYG&ZR52M:V%o5Lq4"Y,L`Y&OE]-;!Kn]%iSsSm\H8&fF7Sj_"Ug&'1 %a@^H]hQ1VoGib'jDPF[L-l(Y6Phe#LT3FB?@!u=m*-U[te$4,H&8!`['O*H.6F4\4q8N6`R*NKk%f8?O_C@9KP&Rbn$N7^VY,e1+O*?RLP=,umP=ZP# %[lk!B*e]5oO2H-LJrQW(.M#u]oH]DAd1G1_D4ctfg\AJs``]R8=WY*H^&/Wue$UK"MQ0'?WEN`:6b7H+YCJ>Zm=Q!If5k_iS(ZIp$R/9.!;jCT[geM@FkH1HHWUc\QbV5A;0K %^Z*OHN#"O`e^!nFZ%s.]'RTNHK&^?s0(kDF1cYm$?jFR2_AeHmO[W#FE,'NUFr\%:Lus&0(#aG&W`2 %n8b:]r,H`)RLLED4rH1AP20&X41q]\;PI06*.nh-,:gH:GOaf9HPC1KCmI;*G97T*]Wo2P'pEhE;os!]]RlEEHh]&nC5np`ClH1M %DlI:B+`%;o\0AjS`$"@p@8FU.*-n#-9Oe5RiBi%P27^C0=X%?0(^"Z1PdW@sOt[Tam%5[3N@,S-F/Z''UVJ7%]p1XpF](6MFtpmk %9nK1C`PU;['\BFq26JsRd30(3gk^-uQoS.36;Zo[oa[QGZ2<&FElh']Ke@8#h8JHd7\V!Hh2#="-b*V9[BCAAH)tA>;^gSBJJKAfCJLR@CSl3ZVc^/icrl`8RNj,hUPSeP>*7'U);^L^ %J'kMfDSTT+q&5OeEVI@^]l;)`gAhE9#*,k9]Q3inJ?Y>$G,LlR[$egK\L;HbicO&gj.g5XUlUqRqhebqqKAGJum.eb8T/ %a+i:Z_O<`O%r6C.jA=5&LL?BE)0/uIaC]G$/T^)WS_/rPe-'2Sc:fK.c\@f`TV4.jJGVrd'>`i)$4*)%/dP&EEfRV'Z608#Th %_dg3]dp$;hERJ/:VX^)>g7-7WOa-U3#^XsE<6$3"iB`3X8J*.I"-pd$6q1;b$66m\'8M0NQSru"oUZ(1X#"7:G>c+N9-2!U-V&EB %Y+[C]$#2(9&!+Q+hJUD4@XNkh/O*KGIj3Z0Fp=&De*k&h]f7m>RU5Z,]2;C!WY?o(*6 %EnrbQ7)q6=`=F)*[i^[]DNCWa=9Ho8E`ZPtiAa[]Wi59[Xp?`T,#]SCPo,qm*Q#@W*`_BWF,A %_[bK7(LItDbFVRXC'<=NAIsAs %jtaR!NB2\d'!T:AkH:bI/5h!#teJM8E>>4dE;DJN3p]N&nEgkFZLeg'B/.+-H94;Onl'bTEP/'h2`"C4=bW]lVB:&9AR#_@sD`^k:B %9fTUg7c].Q*I["BMBSs)01r=NDeCbX4KD[c/0PtQ:0$"A(.:]\R=]?A3?7.ea0E_oUu>/C:0?kSWMVk?!qn/9qe^8q9QR7hQkINM %/_fDdIa;0]LL\G?O-3ZWWlHLTqfg83;`T#aN0h(&bp9r1)_oEhfO8BZ:$eN%f$7D?a0l*lO![#B]g%+GGD=rt0$FYWh+#-V$*G4i %'..")2_V8qXg,kL>2',U^b&HR2M**pL=5i\-83)`/*?!h0%C817IR+c]bXfm=e3Tqi$DV)a\qcJW'kAk3 %?M#]KDcGdm[bZ-5jM+HNqYuMY-8LI:74ips&,6/BSS#>'5Y[YQ@5An=.(c:0[V:Cc^+(ZP+EuEJ;td=FpH?_h2F7J-g8*%rCFUL/ %)3P&rY"@SN@]4<#B?*VNXB_6Mahblkn4bNcb#`; %)Y%F[YshdC73E:b0<8ZJYG^;Gdn%@J6]4aQYtQ)RV"aY^)*JC.V;?V]H*Xc,nm.)<7TVSX8q,m"Zb%B)$j2\sHl0SF"i>`(lYXP' %cCH(-Q@D*(\4.%%2')qDrK[#P]F/e`&gMX]n; %Oea5\*`O^>Z$SkMV7QDn4tLDa(Ypu5E(TD`2^:;KT>F-5.MTG&T@cb#5$-jKd%Q>ip`+selg][nM^9F)0u.>-itYVGb$]gAR.m+0 %5Jl^T>hQba"V0Rh20)G3\En8=(c;p>e36nlZmhaj[Tca!S(\Sfff^2+oT0Zi>eqOs+fMYs@&uM$5*/A&Ns*`LXal[[8)l"D/u]I= %GkS`$^78*(P^/Rc\F:sV.2FN$M^OqPmAF;")]NpZ\Rd[Y]N3Mkfs(BXVmtol'"m<;ESfVe+\>3['tJk>BV/8kG8eo8"i]l%ZsCbn %UNlo(JH6YhDd8U3A!c^BPUas>gAh"!O(m/;F1&nqZIJiLeq,Q65sqa-`]]CM!KUq)08F3)d3.]N!%r!ljKat]Fp6D,62Tna-o=@o %a9,Sb?%$e$7K+Ki^s^aV(e3'+2Y5nR$\OZP781Sp]qD7[KcS_uEp.7k];Y'>?6@QjrFk&c87R9tp:LACTUZ1Gk2/i$dRj[NtG]*n=<.-^dO1Bqq)Wbdo#0/j/ac/=s7'p5I=#PVq*ZqbrL(T8lCn*O_2#338?#IO&MGi$"@lHeFjIQ*f_V+-p' %F?SUI@LRF>@70n#fdGA-L%Rqfr#7O6qHs^M6,f^&l'B*N94RpMn %E>W#n>J>XP<==:0%:rA9e@(#p=6%pq%3qh4`4AT2GuAsQ^H(Lj3:adGNYRX6`rR%+\I!*#/B^r&\S:5S9Bqh,Xmo-O;Gj(WD@X67 %]sb27H)Et8n@`5UU&<8UK7:sV*.65ZDI,l[A(^p4q8T?N*O+X_LU\C>3%4%&2+Ob_?1brSU7kF0E!V=CWh;Z3OP^.h@4!?U[2=WP %I6V@UE[(Y"]?bY<^/9*>29&8=luf/K*J2+(F3rIT[[%I=EtPW=c73(28IZY^`b=1[J'dRg2QZ4S+K^gGm?MP?!#6$a3MWOWjNh@u %eC`9+@jqKrd#oA1ej6=t#a0np=PMC=qF@P",em?C@Bc1>V&$gq#MI?k=F2&Lkc&Met@NS*er# %*Emh!+7#dSnNBSN&Te]*kp@cuJ+o#EcCL]=4fK[5^KuMq:NH\UI]@D`.R.?f5:o0`7\=BmeYe&e5dsWFE]D>_&qUD#`>Ju/Ph_Rd %`ciT068\aR?e\%[RcK!Sh3`D28%%CUS\Q,*=$a[]u?X?a(%!^''/G0>\_E0!H:-g=<`Ip;'bN2l<.?e$Mtk6us2a!f-p4\nqi:-W;*e08.k`:_.T*'K=ao>38;= %3f\ok*UalqYr+LEaosNA)9RP)J\kS-*jlIr^3@WRj4HG/lGrT$H"tRo\:DI3\mc/./!0)]]H0^bC0b3'r%j^VV(6ot4rfJ#4Sj&q %[##d8as1S57mn.um7s^R0N6pnZp"b!E%YE3_0L+I`3>gj!D9_J9IKH"2.KGY<7]@GTt#^@8On4[cJ38#$t:-Ej7Wn6h*cTH`@F"i %gSK3oq#h#*-ne!X%aGuLj/.bY4Jt+&Wnr?G^:d1cm[5..b5WQ6;\fW?2\hBqb,+r9*Va@G!B4j:`C&>G=,!V()-]8?12,s/b0W+3 %i^`3GaF*bWQsJ@Aoh_^@TsBYgHUpJP0a+a=c;smPhb.]Ekm;7R7(e)o_54j*G]X>>/,iRC?u]Bb>ieQjh92dtWVN0RfZpN,bnV^-%/Zk5kZ,uD %'#NYA*^UZ%kO,M+AQk+-a*S9Z.%r\0!TLZIVuBZ/(E2K`&J*1m"+k_+o_5=_BcV<+)X"e %`PN@*NWKF@LN0[R=]N1j#I=,bib>O]0o7%1PQ9Aj9,]H`Z&JfAh-AC[*^Fs!WKR\SC!Gi`aaATJf8!e,?rmTZ/g?G]$>a:>dA1', %Y\Sc"W)aR*M+0\Tp8L2`=(rZsCgg1^S^5t/5D;3T'kkT:ZQYMZ$XB6,nQA$hTh]hM)E*@>o\sQ%`Z>#Khm?Wn0 %ZG(apg=9QP^$ROKAbZ#^_GV9-]6^?G!ApOFn4idu&RrQgp&;Sa.]6#VGH1CJmG$K.[g-*J;t(>J'AHeoT<;NNGW@=]` %d?/%d83Q@1frS-eX:L>X!5?iZ[sZp5Pgr(/)t,$U@jGH*r+m3?>ga44P![tWQP.D#1a,mX*a#FoQ%s9&K#ar:n(4GhZCB?Si('_' %BRr^Z[T*t`iEV7$Kh.=*Cm7fWB"M7X6$4/g5r,&ILgoQMTMBlm5!*eneP=Qb=dd5jePu$]rL0%/5-M233'5pM5=7(=QTB+2>P8h> %E?gIlnV@I/UO$L$,8\_c'51`EP,q:FKUfGO\l4Fj/EBp.EET#.+W.%VACe`r5*UJb\rGBA2b`Go:C'm$*4^J$4lH]^,rbc*TaN,D %Mi:for^mrJYiEOu_#.T=:kFu=8*WcMEATUY'nO_6^SWg`;%-J@\+%ZoCQP-9)d0"HJ;.aenI[UWM;dUAQ@uOlJ2,8nT_j!;c,Q!T %k.?AHRM`=*Q"V=_FgS46fg7t.*eSd:Kn=-b;&o!Nn#F'7*YH,Wm"Qt']3f]d5Qf'WoZkKZ[8WIp#\`M9q]hJhEO^MtENCu8M(V'4U/T,r1^"P0Aj?K3fVTH2Cn %P3P,mc@Xu[kR3#4Crqm+R'n.\I96Z,5B$Wk]8isIF%%dQ`l/Jur,jU_Q$YM@;mQ%NCf>n6XKlt[UTFL,O"Z"ATd='0M] %03&'CH&(M4?.GUi'm;L>*B6lpoW&M!Gbo073dcM/SYQ8t8J`?:;7dBAO#Ed^+]j=1W0&.;fW4SEpZZbj3e?_8mIh+r",:da %m3dBda^_rf%6S\MaK?X0u@bWLp-PG>hgNZ7-c=r^l`5YB:+Uca4<43=3cqp-G$P@]\3JTuME$2?R+a7YSUVYG)Qh<5@1 %>[s7)LpU#[ahkr5Wu)Aldc';"4NZ-/QO=SM;2EaQ9uL"a`#is>54Yqk8#be8B<\+jM8f,0Run\F"/p7f$P"M+3N(J]ESab^h.a-Nh1&uC`'V>>pFMeNpkbshfb]$"g*Yq`R@:Qoakk/(/OUd:*/f=C#D0c$#n$uWBI$XE`tRR01;jEc!);nn<"D!c;^KX %9L-)LAL.]'1$kMtCOlaA42GYFH^>m%H/4*-"m#>m_.i]RCFD'\>\h!Q*hUWD#cY$eccb;c+RIlmGZ4"0`l %2E"Gc;N,%9CLMLJ'lmVmOqqPS$qpt %EB2J]mrXPnVag$B9Q2#le.GCK0Aufb@@*RaJ'jLi'@0^`RC'h*9jGM*dUTPK'?6Kn"srZW5c5&+(';&<>_#_'=cLAjKh6_cdrL!h %atTBPGOO(Q#q@9`i[m\V%/ %!1VsOQV]Td+:.*PA^F#`pn%sr_n*k`i96sCi(BN@LYINl*N#TUQR[7^"^fg47\< %9"_Y-8+8+&ijHK^G$&pSq@X*Zb7jpm!"@K3Yg84h^CnR_24LN!>qjbK1_+%6cc<:>^LeJj"gqt!Ys0q",+:](g=.QJnkCisbIWb8 %kM6?fp+@Uc4i^&%23cB\lC>j:/sEFiVeUU&<2\Vk7Ki'*3&:jU6&M/SSKCUb3s@4fJYMRC5-=Djn@MSY(meejcg?GXQl9jDNj(<; %VYDASq.Bh%BobsrRFh'p"!tYT\BoVI(Q%uo6159qgkHcnDMK`a$3BQ_\29H7=a19O %&g\PqABNn5G:V_g&!DjBpSS5*Aulm(:A7]$]+Y&^B:aMWp0!LJM$^ECmO?"H1Z/LQPt2EnD!4[$L(#HbSsf8dD!$tj0IPbF2or:1 %fe+HiD@[`--]fo44nnmK,UGrs?(V"[.$Dj:4W=R?L;#0RNSAJo2Q"rt'^\='e]V4lLq*.WX+QE%D>'G^2_kOYi>3+(-`L!2J7 %Xe0TAkl?Qht=VX/6DfVfo#$no7^fR\g-1B_qknEY2b"6ou+[o4fHd8HE2CFY[Qc_--CRN`BC? %\2sKTkKm1%m+Ei"1*_PhN91*:TQ)3n6K\K\J=e)-Zp8Ed!n@.'T^2d36fNlOC_mfM(M76p&+cRSF7;o9eHF%J03o_dKcogFB:[T. %q%%,/Q^8rB/k/BC;22,/lIiMV"QH@6c^me]4F>9>p+@iG?O'6;eM'3`-9YVf*R`O;VIPZ(^S)#TS%'S0a*lfmk;E&-8>*pfgB*pd %@NIUO1(nFIc`=b][8Y$NVP_8!Zm]U>SKEtDd0QA6Z[?'0J"I6/K!eM3IR`_nZf)9$Z$@2A/'uuU+rC2ipc84B;Kd9;[>*4_@d"RX7o^&iSglA!ko:N#p_d@6:W6bnS>%:n6Gs0ekJ9?WWP+*eo'fMjgXS28h6ppp21\"6Kmdjo]`tE[/U.m4pj80*IX1(#/)/cAo9&X4J'`rSaiZA<537C^fXPdf)Eud4;VZGQh;!38I^6G)$Um\hc@,dj/Mm]AH!9$`%9t=hLu;ik+cD_\N$PC[42dKpm908WLaWnXS@XQ %_\:8mU;qi`R[l)Vh#A5:lt?O#&N`fB\&13:KDh#[D0p8,iI]*>HMFE[XQRUu=MM2lBb=o'3jFLdeEq4E2hD?6Veu^VQg5iV@n@$S %n%.;5dY6eIa%.P^Zn#BrJts_Li<8!%5DIGtoG'oRT&JpDQ*p_!:ickng#:].UKLs$4q9*q/8/LI_eR<]/hp'^CN:.;*D)VUjj/(+ %'>YXn,D?FqR(_)^a4>;,$Ht/:W@h=_3V*t&4tH&.?o"&[:Guf*Q'(VkD+8dBmuOU==e$cm$c9c;&S8.+.()D7;P#pkAR-CI)7j%, %*rL\[4V9-%>M\8ZJXg-<%Qu\`?gY(B/Za#k<#q#W:6uhsH'E(]o]AXMmDi^,nS:'/d#EJ!m@!Dc4@$1C(%$Ers"nU\7(IdtH*7oE %M"Ru-c>cWVC;IGr)hf'fR*%Va+P*G1RAHJFJA+q-UUV>c99$.5:&sg(X>9?lH3oFCcMJ4G'dt/9\9JC-g0eqn/]fTXSl7,]G$AXZ %)m+?c+$9).N9mI68+aZU7ot"Ph'p!cR0\:Hdlp+TITrZJESP=f:n*DT;q>e=;YJCHs4q\j\Y,4+g]r'f>ooDuZKNYq;#J %@4?d4R]csOE?-4kbPfB/Y]]r0jcV,3fF%HV]Zsl^o62QSMm^0nls6$iTP'Vjc?dNR:oNWl2NF'8.`EO#<3c4e0UQtRFumOb/dG9W3735H<3_[hta[q>"H %&?e-'1EP@K9:7p:*TFL5hD/U[Q[F^?X`MtCI)ZClXf=ah2hG8uF[`q4jAf1.^>]hoII-aE.cJos(kPffY3`Jl0Xt?M%X#`r\$%AA %BFK3V_ViDre:ME2SrYpC/-i!sUNTRk$4d6`^.>rPS:Rs)$\rRAirNJ6W\_"p^?#k6TgO38->o*G$dVOk1uA*h,nmQXHlfP,k'(NL %<3bo,H-0uu7$Dc8CG-&eON65`FG@$1l`I,/#sg2%IejgH)6h(WqV/g'jQM>Lc:ni!3#X+UI/"SqRfSCXjX:S@=e>K7s-o"[Pq+kAS(dCNS]2,gKEP*urO#,^I[t]gPQQXmRg,Uf[NCknIV3D?XAYVO?cS0/Jc2i,J)ZtgZ %c+)9;W<#AY^c9o\+ADj6h@Ah9`fVQCES/N4WMm_<_3W`^28o=IiL.IB.Dec4+'e*W.020ndUX6A1R&b3WBHh/PjT'ZO!a-)5p9ab %&1L%H`SPfaSDog-kT[+UNZD^?WucML%b*>mK<"KkcEQa(%sB#-[ne1$$"_6!H5q2_,)!Sf0lPs+BO[!YAt<>R<=#nVjZJU<+!9\r %b3bs.WmV,OJDfblG[3McM3cASDA\a[;' %b@AHeTJ,#Bq\^icYMc\J_O$C"LL?$GY>8#29WP[7bE>3n@c=uf4Tp&"-oJaje>hOC/,!FloT`&AX>*-4:>rP2Ms)D/=ntShk:jEB %AbRVfN``>%Zp>X&&RhpI5up/@6a1j5J*R_)uMlWl$o"6Yn$.h@f8tpBZq? %&pp>W%'J_kA#E'>'#YGS]gY3)Kb,*QWEI]0_/tDh!P`k_1KJLf]6f[U#K*CF^g.PI=Gfnf`5KV"eft0H::1L8h$?fe3-ks6k0Ic0 %#)TA+TEk'L=5=rCBAS)m!,fjB!TUOm>SRZ*6k#qUnf*@g(bWiTqt4mh5n`S_P33>S*o9\uHK-@WGE(q/bV_2!$jO\DKi`js*c'n# %R+;fMa4r'OlLO4@dk\B#O1\f%GB``Y%l"?m1q=gg7UMJtX)1dS5cS-ZM`!Y8i>S4@qp#uXl5.o^2Ur5dT">^hCF`8nog!k %<3au`J7t_!5)#i7PT'e^j"85!Sqd1>:ZUsLI*I?VE3*sJ5)Dj\b/?9iGV*TUk@hd=,?!uBR7VRgm'uI!,_7q!kW^_3]u0q=B>n)@ %@R!cq=5;55/WDa/X]@T6:f;0l>V$aTg>IMa1PjVjF,DA#o)ie(FHpU.e(\SU"@nS?;RJPX.3?`n8 %BR(=uD3t$jKs1luO>91U$J:\t+l:@?KY38I,5Pm?!IN^GMUf("Pt2\*XB'6I(MT(QMWlHXlp['&I*Qg%@&IE@IFFH;s'cVEgF1$X %.j;Th&8eqFZ"MERhIA^_f,_$a[@I?hVV`X6Nfhig![G(I9:YVTjr_NR^QEG %4aVS(d;T_SIJe2n07lNV3@8c4LA`HW]Gt8Ckb:G\+:*n^TTI4bdN"TYcN'djkL@?!_Lc@c%OXCfPBWWCZ7dC1/Mdlc&H9@V"cH8@ %K!3F3d?Wt\,IQf^\W9nVY0Y_\^;F?eg;4F-8uU`'W-RG2DYndP,%#1.fX2g"B8@!XEgYC*3_Rj'N.?025;j1\O."aF5^=QPQ+I0@7#84ZLNV-^0*n[`3;/iuO*N45I> %i'?h)[W\VqCK8EA]Gl)N>ZFpC"U^&jc1qpp'N*5\3MghZBflaMb-Q %deB]mH@"K5Tj+ReB=8Wj^.7ZY-Ga3L\IRO=Ka8eq$22M3aBJDR50V38OMTKQo%XE.-D/R6XZEJp"W=o6Et#G?@p=2C+;bf+k]GW8 %2QBb*K %_>A_[i;_B`nb+R=R*RdaHBn_SXcQGD/ %Pp0['=I*g%:I'kO\=3`l%(,H.F6)-W%b#tO\eVHHW5=AJ(F;ZVAX']^I21`UP"":6_VVe'&Q`Mi?LoC1gWC0W^^%eBie'+sNiiKq %3!Ou#LYs\>PUA#5q6Sk5"MKsUK6;AI/&0?r[Ff]:L=5\-@[ZZ),:]_]&I[fLEJ.1(a2D;V/*`#3aa'N,T0t2ae %k0.8s):[`(i!afGQ7\@<6&36>\fZAk[BKdrM-'gt&eHeH8)XZRp_CT#8MValFM>KiW?JUI]3BO#iC-B<6L**!CS=UrB`$B<" %p2(dr-WU3,!S,dQmp`\4ljpLmZeg=PN>:h7W'A+`V=S9/mDi!-D/JB %cjW.,?@Fn%Z+B+!*<`kmm_YL1>Q&^d\GE/%\JZ5m4WBojAb/K?&GOi&YW0`faIF#3e\D=hGZlaXU_7X$Su,N\,YTW5giff_ZQjWf %G-Vqip]0rtFX4Y?cSfVTp[8_J34im]0;1$XW$Be,hANsH>.5Rs!5>dtS])eZC8'WnDn?+\['Q%3e<-p-eMoq&W"M6IB]AEEFY5^]Nk`cD)#8K+^)k+-"(VJfKk+.LH),]Z'KNhWpjgd=^D/]iNOE[=Kl\IGgsou1rjA'D'aZXVB^>\@c?Zb-?/tWQ]sB(Z?/+lj\`m[nNpZ)H?Bo4P_A+sgH0k:[9gMti#Xg[G %iOFZ'QJM`+""*Ier$O;(#55[b$:oN))uKBk]B+5'fOn=N %:+^,43:/6$PfLd2dU%bhS8m[?HLG@jMUJMN4'K'KaiqR,2m$&-2lmZ[3F&Pn0cLlmKan4&&(#_L^g(a)RU(8NJ4\d^H;1GH]Rs);G+[Pj7fget]-aN79\h4%KmR;$9CufHb6V5"3%jU5ep1.%SEmMc,P$CItr>SgGAfcuNFJ4`4cAGHNS(Xf8_V %g78[qLK^p&/g'c>K-TdQ^1%cS-#]9K:qCa-5Ne;jc;^ht)g>1X:!M:_rjkY.@Y9Ma4:^:ui;Im(iK.ng=uEeVeMmR([\;6@49i`0Ur^p#<%N]6JjBmXNJX#:]=7EeAcb.<6ju&$m>+(]+^Yf1];m[<^k&LkPZ"46"W:IGR.ADn/ %d[mq!>"\_.=t9l]U34S]5#)]\%X_omkFJicm-W%sSAK/9FkgU#^=I$>al8Shi\YZ3dI-@/EU_,b"SM?$H"eT\*`p1,T"Y:a#WdOh %m5Q$WD3GL-%BoX+^fWnBY%8![PLll%%j:YgfDTjkd@1kN?h8l$`GUgjCN@L<8TC/FJQ.hS!9V@BVtF(9NdVlJlcT?p%'Ehtd*Q_o02()D^]\2\T]BKJu1N]tggjQbV[i_%`K$hu'IiV90r`_o8@+inq5;JSF^JHaMVj7ns %G\A;cj6LcNnPT/<:eU0OTN*_`O9'Jeps`$K]hoi["a&dk?TB@)(bBN>kVP6/%j1GpifBaLL1)IE$^YIk,;i7>0(=us)=PtYn>k[D^bSX[d.pf$nI*l9ZEfasQ\SP:"ho>gMQn2uhX`5`TlR'&G-A&D9JOun$]cHG%i$[eU)-*96itXe %"9nS`5Z^?S*ET[uNEinHI\S$?fsL*5`'^S/1cG#:B8Kd=(@#dP"**o>[tc#=`bh57&f]WhT7Ft\IR"XArT^."J#q(_2=@\JHG._9VkkfLnmZOJZmq)>hQG554lIL9l/ %AOgms-p.cd'$2%fUKH(5Vs;T72cF\r]j)kKc*(lsHEp=@#Y^jZI\>i/RS$d/K`pV"Yp>E$a2bYoG$?Fq]&=3$6G;'?8WsthJU@4q %O7>3K#a,">O4-3C]fd9b]uE!j!)CAn'Kq6dpgE:Eml%kA[*g&?5L(/%G!7\G7;uHq1=uL^&=cA5I>X19k);ctGT]@lr(Q'h#'Y=q %hp16i9pUi1bB9=9E5dP4YN8LAA[_?!j2IaPlbQJPbX1[Fkqb.,"aF\Go+!PF-ZNR]>`$DT?nc,)f[]a>hpQIMr^SgO27+MI[t7A- %jQsK2X5j$EMepqI8BCF8n%eD\oJ`Y/<`>hirl0ECgU>^o)8m.eMh7B3cZ'P.Wp'*uJ+,s%Q`]iUV?*Snb#gKqE#"_hM79!/b%Rf^ %=Dj@dAlI4k/qs];gkt%$p>Zk=*%Fh=Q^Z42[O8AB/J^KpSenrYGj5_*HWV7&-]._D2,"]Z9YPT6CAWA1!V6/#UI>`nD9hb,]K %]8*a;n;P9>$4Gpk,*uM:#L,Va'dfEJ&f/4J5*Koi^,Sli!I/7VIDdo0KlTTekj'bmG%N-4Y(*pX-!p_n$fOH6!Ocf@RONq"j %EJ>D#kcX&#+Sa*g8Bm74EL^($2%YM^jnO%Al[(oG7=<`oNK+%pWJ;#=YFmgiB^OTg[4SgO*j+PDd:0J`*n6@r7`Y)@.2'D,SD1mP %/:L:7hA'XI>uVfP4@N)q3`PINV/glOf^4\0k\HiM[g%o\oY)K2(8n*c[a7UA`IQTk(o@fZe$B8B)F5h!+Sa"qYQJC%':DFT]^%'Q %gmNtE9".a$HaLg^Lr"ZRS>e-Y80h(JO&*;,dPc6nk>_q?+^iN*m%>%0Uf(L3%%HXt^t82qbLQ %YYnOg+.aYg]Rntq]<+1,X9WG#pq1`e1&S9W#pb@^D695;"&$[1XIA2UnN1r,,-m@$(IRc,7`Zs6E4&FBeD'S(R+?LJ;^8kos]PZn'-c[LY %i.EP##dD7CWnfc2aqD.caT,:Et=b?rD]d'J\6Pea0Mk.#j33'CAfP2M\Md+"/6r#4\<;7,C\QX)%r?V9`\-$\lWG\>ocN?5nt?KPatr!V-Spd**ZP=um7$bkc:l<9)5n.TsWY9lt[ %LVWHC4B46\i!CfV7KrZ:d_kIJ=1g)g;jAB!=K]iO4Z5lc^j2"n^fIPS?Aj%Mrh;-(Z,'Sl'`Yi!\@q-:d4.Ak=K$(+#96 %'qtbj9(f-3Xs6s!JiSI%[\3+#6g"2r@%.r(`Xur7?h8p'DJc=Ok2"9M#]pBQg:1#!Mp;#&>p')9+E9[V*@]Kgp*5aQJjW4lc*>@m7pL6cbV6oDh$.4u1a;I&qX9GM7(F(at7:n[:U<;;1_X7\VTif6i?9$h"cj!B"+6 %&)4+okB6;":.7\^D<_,[D"m7:mM>]IA'#%M?rTjf7pu/)X*\)4[)Oa,j,qr7QIj`[`tEF8!YA%4dA#()00(?R'V[:/4PG7b-/WB. %r1r9,GQ:j-r193'*;8PTl?M0F:e#6q,3Ck+d,jgH.XEsX1F-C3;JQn5buebcd'pVMY2PZ8p]KoKE$pffAqBJD,HU;$lMGRY=(^Ti %YOjraX*BJeNF.&Sc\Jp@0a)Bt*>^-FCPgWGrV1G(?"(VSQDR"#k4))M]9sMHrp)j(@A\VKl(,JsXB)=^uj@C)aSYJYGRAW]C %JXTIB!%pppOV03d@M(@'EHU#C=\.6T'B3X&#JPB2U?eN?h#Pu;AdY806_*]u7&IcM4;g]"QLFXrTE#"^.MOa9seGR9:;\.mo"jsOf %^e>u$H]S\kkH@fkW_VM`E1D.3*pV.ZJet%Vd>sm=DG0]/?a6ar:/UtbB2>?5Fk^8d:P`CcV*Fh?c7(;*EbA<6K$D,D`1%%]No3#/ %*;i(L55f=mH6IKIe)7IB(-hWb]S(eXWRIXoM$,ji0;VKu74fDTTUaHu3ZO3oGZ %B'ICiqhJOpZjn/t"dqmeW:P,/"O2/ZkBV?p`ZEb&hG^U14*l*PMkAa4TRsJ(0J!rT,Ik17cfX2KI=KpF5MZd"/TBXCr2qID@`.%d %oRHVRIb`Sui2s+=?2AZ#&.n#*rq-'FK>-u/mdmam>4SBph@@tLl1%-0nJKAZO;]4O3^B-!TGS(Pf6r-ZYsT,?kXKXb4dq[ki#HLE %q7P5`%3W9icemJ(6\@sf#n?)hAca-4hZGirLTqV`qMO=gKY\tK?NEmrm0M:3P&7cMBA5U %.,fLYaIRB=1.^U90C@Oimr5'#UN;O0$I0:eFN2o"jJ5$hV.g*k:Qu;9`>qZK!J#%4rR0I75rgZ^c7'2'A7n?mXKkW?qW11D %,fLqZ`bq/W93B_Y.Sm\4FEEN5ClsiLpQFO$3:S-pNU#M$2\Mo&DtO=;Zg5C3[783oD)N/^j`ZK%?U!qlVs:.kAVHR[(fcK:`TYc" %7Wc(Feji36;%ee`f>l^#5YYA,Xm:(S!#ONBl\_>-$d\I5P>_-BFGF1KmX=6JF_t>GZ1B4$Fn5')RJsVL-qA2-chu+)#s8.2[>g&4N0.;^jNr9\=;lua.a0NJXl%=$Ap%/4]qT&X7 %$N8/omH=N2kCX/6O^A)Ut@BY**DCl7)O>L\l3YG8k5*o=W',@&mV4#h<&GH"#,GS#;*TOn:>+@fdp*??Uo;Fdd-,n$Wk"MPE6g.e3C,A;Rd-[AjH)'SoO9F\0sW4l8g+E8rlp^%!nXtBH]1,M98DVda_f=ihD9obC3kp %Hrl@!?Yt,[f3eRJO2(XCfmD2HbHA-U2##W]V,tu>RKHGG5QiR)I=kiLg.lR."`ei<^8\!&6J0G9]1gFRWTN_FA%?)b;;; %9.B%]TOUf8957..I(+=(nIg&T^Y@cRY#20+Xo@cm.3_Br_#R_OA-en5\]U$*:-r1-NC+>MHj";e*or@^k %L12s0P_tqS2bThhIA@:W1>do!!+%_@.t]UZj!KY'U8lhHc2)8@$/c#@muScaRLpZ7JD-8!Q$F&S#qEJW0L![AU>h\2F@N!uK<,nP %b0G8+WNj9o:hbeuF0Rg"@R?ckU17LcHc8AZ.;VB9Af8D&L\Tp]C-!.G/)t5C)IiNBGK_mV"X/62.\iZKAR&m15a4.Dj&-bVr>P=\ %3CZ-9c)_2OP %5S"Ee>O_u)1[dF%['Z-pCPhA;r]2M929YR+bDH)@o#M^8f;MJG^YC&LDn!f.5,mpmjo2*K=mI6ZK#`FDX7X/8H1!0'?mYBNJ9YQF5r.gX^*"-n]g32Tr?@P__)k6;^j=7 %.$C^<%Fe@^?*2hdURc.0T?O*pY1r.77VVV%rE#D3faP1M/CU[k,BenP%S,3Q!UIp\=#n"JS?T+S>?tIf9F8"VI$:&)!=+E=:>['B %#6O#Ma1De8n]MOqeQl/h_5U;4lNh6#?Nn/Q/'KqOUoE"GIC,5^"]"G+:d:K=6lA1I&8 %Cc1NS^$ubWTKr\mLu/LB`%96Y9jK5LFO2Rdl+qDejL@_-mnhPQBnTkb&0D'rJ%U4K$Y1NXRnu.e&p;S&#\^%oj#S&2Mrl^X.oelo %gg2kqR.)fRNR3YaJ]@Mpo@(-F2dX>gp,<*67E[H>Cmr##4ij,_7S]E^_ECnq2HdW/frbJWmj>,kY['Mqg-h6J8&%Wp5iLj+U)>Wd %QfgX?m;ZC#71bKJX%G-J<,aTe]4r&lTYUijqBgU+R)O0fUn*HYJ:rP=5imZ3*s#`;W9NjF'jGCem.O\Y<\a4:E0(<8$DjK&.V7D6 %`$:,%hX2e[I#e1=cVTK$$SrenHRM7`"Xnoc!HqE>WMoUQ7Y0nto,*"+mc,4[)nbqP_J^G's/qa)/>3l53B`8+!Z7muc3,>c1;Z+^fI4jgK-QKF[N8QUnF8SbVY[r`-NRGjlZ=B=4L@WADa*[H"S6KZ@K %*a`TieJY[(A5$5RCU"AVFqL`.=c'+D2?I5l(!dRlp\;mgE%#FqK9Cm7DL'_5D$QA5a"47Y^h!f= %(6)U>A$H,RmCV'-r]/AM[Ts"iYhl2e[n+V&_D51P_Vi;iqO<64'GG@b95nEG^dmdb#Xl`FFU5MJ&Z:qa_A#abD9[ZY'I4,j#DL5E %f+mP]Fn"[:2KN;_TU-qF]mSU<\39@k`X?G1-Z*r:^et^jQW$.rMH@e0]NAB-QH?3$ %\-X:Jcj0q2(LcaZdaI6O+^S<)>W3uW@FX\Jg&2_tr[sLV0-/%GIN!@BAeG!r[bc5;IKabR&\fQ/r!Ltr@]FQOcKWIdW[@nb&epp0 %9$MBsZLin8[?>g5$a)SOhBeY9@cOeB]*e2YEM46P14lNpkBr.h1P88[*roMW:pdCi@]4N72nGr4(PfjeC8l'shfL/#>N\hc2Gt9)L<=X-JA$\?a'SR9aHXjsNWCtD&5PZ-"-pWF`V2\6Yr+dAWcD9G,dTP4PgL!uM4=q1!!JEe %"J]B0667b?$dDNkhE0F"Ld[IZ?q9+7d[X=V*Zj3T%SZ^E#AOY)k66g#:0E$(%>J/4"!H"1OQTgmLlAF>(.$0b,h5dG>3f:`(!LQ? %@PU2+`H7mQink)#*(Vmr.:HsG:psQ`9EQd+*TQB>1TE\?nKt_o::o8q1:8>UGh#*N_=dVNBNCLG2Nfg2>6&Z%QZ%a?b\ffmG)TN4 %#btB>f(n*+Z/O\78X=u=.Za]-:_?3mj]"O/12M?-H)Z&8%7W %#bs79o@L`u@,ol2IaP6q"Y+PV2fXYK%h&U&ok9qK7n"lU[3/d&C!su'_NZ9CGi=4s@cp61H2[4hS$37CWi7>79b.7M\U=mJocY[: %Q=s5<+G3&O:_as6k]1p_gsL,*lDJ:JLNiCB9rF,Oog(PHAJZuO84@:+UhOA-n@0I16$Nll"=FYPDin=8OrulBn]NCD]a:(l5$0E: %?)p]1MH[/>l>*;)()*:rBU5QhJVpI@QOD %i"q(_HFHZ)L\99W`cB:rH`moL9[1"6h7T*Z-]g-rU,m\"oJL<>KST+jr %F2jNX2K07AO&)YCH&5N\4%+gBAdUcq*W+aa;HTeB]E24l7K4J?94hm6GSE.73+e`b]M,>`u@b*n$Jb_PV\kO"mMs(`pTtp2& %[V_677ARGT^0ch&KZQh)@8&HR9_%mWQ0al\WAtSdcU.BG>UH!P2Gn#cdZ+dpmF&JeHGr4[gs&f2?NS0lj7?bBXXV#gf%,l+SS7Ka %_6Vl@a,:TUE*!\pWM#9s!-?!%j2'-Ye6fL1/4.,mn"sg/G\=Q$l0h)`^"_MHc%t`OjCf)^7d6FC$aJ"^9@YhuM[9HCVmrT_QgL<_ %\^Ts5P!PtRA,L4aKX#!"DV4ps(Gk %^a7YL_J/MAke7smXEe)BOYu.-%3>OO?JG.bh,YQJ[rU&sY^:4dJ#c8dL>Y$$-@(1>0eO5rk?LkJ6mQ]iYgD'.b`P[DOAKt5l_lo( %c5()^AR:0Q5e`C>r)j@u-4m?=[T\8I:/T(ED,%HPbLfi/Nm:Z0X[&&\7sQdH"n8M907aUT[5=mp?T)!5me4U'5;8I)OCaNemEO(X %AS+Y^;_L,7[94DVK]p^9hl\h0,H=n2>a(4`!cQ3Y\hd;of<)anI2:#lno?]<.;2]lEBsjFRL'jhk_,,EFlfDT2d[g%6+!8[!XXHL %h#u>#MPs)-:6S"M)'H_#U6cA'-Z=o'>G/e_h)..&(@26%m?E]ki0[S$=fA@IFhZPk<(75+M"KF36GeJ`CMY.cDdS5^Y/@p!PZQM-/PHL(@*u; %/UC`7+VL&09L;0CY/?U0X+lWsqf5imOB5^/&#Tf/9G9lFI:^dtaj^\caB*Y7:dl#jJVt3G%Z\7L!Nd6YiLBbFg(Yo9>l+ %#aj$-%8.ff!o3?_9$GPG_r#-m9/VP+2g+#\40ZA"[X\_`2C1M%CbbJ9s%<1"!3H[GLCmJbCA^:Hl6":a8m`AZHr`$Aaq0.'VMp^*^h5ci"(K/G0320["(!=.crE$QW5Sim %:LSpD[<:G]/cU2T-Cb"/)0gbPTROC_CG0)O\'el:@3qKLqKHLU3[AOU!WF7V/7S5D9fFkQ2M?!L2dNEZj`u-(\&H0WT-11I[J[B9 %RWstuYg*E%h[l%9aem)8,H<)!ohqQ0c=HUb^g]M&$ls'Og,Fk88f7bt97s:l_\A!&ociHs]Ia?WE.CkE5k::.`4B?S(Ja>4b*J@6 %dW>fr_:"S2&$S?hp7l;l18Ga!!&iqN:1lA\6&aCgK"ItEME/lNB#&J/<74VX[\EQ!ntUB0P4A^Tl>S@ %c<77OZ_a>n6.&KuOND1`!\t$'"U28)?7cR:]IJHY^88k,"5FL``:M.o::IA_cnbJt-@aC+g)PW+J(fk>l^c^h?f=uS9gl1>]&YfcO %\Yq2(0%tBh$=:P;=CDqAq2MZmPL&HpEm`m#/EJB^9cS3e9J65?X*>!CqNh)LbblZ\/AWR;V.B,*&!4G?\fisPoo7C:eQ %=Uk31HbC,e#>JD;,tKW[BERMCpW1V9@a#h+`35`SX4>&Z)QeD@:n4hX[HX4/,%,QG;#q`Fg`r>d'^3g&QMP!SCVV%6[4Ff,+LXnO %X0k(7A5HrS9nT%_aE"#f7gr3EaO3qHl)[9&g%jCXBrH1C[Qd_S>,5;#loD&3XPh*-[aFN,8^['-V3sXT2jCQ %L)5kSZW1KcHB/shMRooX],;3Cks4PrcU$k'Whggp^;Io:!H1G[bQPNdLouW4T.YI`=&rPJ``U/YSM@)3`?fK8qVg[.6W(+=dQlp@ %TV*4U&%a5GMdL4e!qPu;f::Ys&!b5!^sn3mKT-LlGO'E;gVao.pqPRkX8d5mQ_-Hl#lq]R]5dKT %-U9#E<>W')K@I;!%6H8%JZJW;H\sFX4(*gV$0Ocb^_A>!'%/aW\jO2cmq'lDb&5($Dr=?$Ap=2"95*:ePm`O45S6b\>AQ>j3#UMM %78oD??5FT^Q;+1Uf1h'Y\3_Ynb0R,I(H&Ll2t"LNO:!`]GK6"=Fg]c&qLETJ3n %R6hM(Ru8@Whf:ZY3\*DfFlIdlc%]+f4YHVec39Bne/32.Z&(3L%'Q.%PjMHi7F[nJmGhZ!$lrf'Zq`mC3[%/j-p,j&,f,IJ&kdAG %,&p,j"lZ[I3r\c>0XDFA)0F"]`T9hX"M*0#]O-reTFO#DG3jifm8bXF;Al=1qRR-#WDiB7!\NHKS*Xq;?^h=9(N+Q(Jga6uobHKb %dQVHCp6YQ,pR0TJf>;40<;*1!Y9/TQHi!A"aGAmA$[n)Q=t1Nub),V?n2sl#GA$^PDCj96g:4a8S^+Y6K?VGQ4]?XDh&@@Y8OZE\ %d;#I--g>-@&Ptic4GA_>8Y6-)F+c@qI@M4^aO0;5Mr8]Q1"U"_,PD+X2Y+[8eG4mP[7SW<"OImI%&kYOaCWf?lP)>LkX\Na'XC`I %,eQ.(2.Z[I,TFpAFeBIY%sqsS5g;-TmHF%/8m(/TPt&i3:k6[QC=RALo2nUhN*Fir?]#JY:lTT!5mqWm/.r84R^a3.3>B+]V84<, %$24cDDoi.G,jiFU(+mcD>!726YYihYMCNe18hlS^V!qlM>,iVK9eBFNTflaN(lG+V-'64tLg@bI %/hS+NX`]m":8c.1Ca&.+5X%=/CS@Pn8c91[:%3BQjjo8lmB8%QXs84/eU(+:b0AMMN'7\lIOK)RInFYH'&b %U^=SO_15F^4A>!iH8.T0pjlEJjpqcA/u-^JR2?1$;NILKiT.u9;p#iOYO#(Z6q\]W-fPql+VLI?9qd4oMcta\^k6Nu#CP'\NAr]E %O;/s,2Q3Wqk(jcfmljnmF:rnlSW++jQl@%WE(C(=65@N0Wk)!)0S]MQP&6KrZf]^"qW:RT7g0s5)SI%F?k,AL!Y?hgcrA@c`#D#: %frjL!U&R7)27OK>gr%:"72a`+hJ>r#<6NWAAH!e/.id*7mFmcNBJt!4LTe8n3<)hMMdk@4>9,9;"S$UTjAC3,qG9ZmTP]SHXcToR %f9)"kN>'W7?i`L&.BLu':o;KKon8UW\YtZ4!Ds5LRq#2oHHR"T6:__*KS1>WZjpB5*N(O5AkAcEPd(rCB8oE)I(?Zl>h/J.Jlai? %#T(r&MF+hT;79b7!Upi0BHnPWLgCH35sQG'`F"fr\IOR^6QF``\Nj=l"R0c`HUSClR-9tf9%)HBA)EY7$7[%X($_9&oio[3P%'qfH6/>S,@Zab[f)=0+b6$dmtXBghVJWsSU1 %U.f'u63fk(!*V`1,h9,/*DlE$6Pk]EZqeLfB%C)XOJ=.T,G"J/>Yt\=E2mJYF18UYY*0<)%]l'.jsn9=UMfp%$a;R4TXc?Frlr/+ %6\mUQJB!F&T-Dmd:EB3C5S+"n(Z%MoT.W$VBM+Pa*LhBZfhUReZ?T(J!D*f#]BZt+],Gq$'8c-?D4oejfm"VQVehA99r51(Ep0Hs %+h,abO<*X`p/D51O0aQDgI-LDQ];^(co5&M?)PQLUjq#.-f^8#f9U@!i#,$JIdncPQV:;8kur$?Z:Qf8R2!K_S-HfZ.TLC=p!M?l %Xj7)+nCB!3MTOWo5R#ATEfk2F:;fcG][cCseMq^jKScSG\ho*1Ua<+9o(#ri.3.H>JdPf,#a96"a<./i)R[Pih6NiHPi[XM6\"cL %^u>nQmbag6HG"$Gm=Wn^").*m7>M5Q0aCZ33btDr/ij(EJIcNlFBgg[dV&._iXS_DmU8i+:j3O[SF!EbY,YeP0[,VDm+B^b9o/-a %La%Nm(h'h)>!tTL\cUAMeKf7)C]X!HQ65&U.suChW]WI7'k)lG12_I3`Mj0ZbRd]C2ga)?q$F,R1,**6iaFT!D5`;n91/tp;B99Y %WYnHj@+&\^Np:&#KD/0Bdq08GkQm>@);OMMRpNJ]"F=FDa,J/Aqh$iUakfg2[Qio7XOgj.EG`ohQDD;'DTo]Y>b9`6,*<@YSFSZ* %kb09O,:cfbH-mmtR7A,gOE,@:Wq(,oaR)DV[Rpi@(?*]IBiFu/CTj!&;.p6KuOLd>FZr'1aPWB02rli;4NNp;2 %T!V"6`h?LH%@*32XL`g_pjKQt_n3u5RJ)Ge#KTB\5"rR33s3ns`"g/k@0&N6;IZ7ZTL#Q=q'fpK.^'2DS>$DqXp=keg+_l(NGm\0>3'TG:b"fP %#Hb53A3SQfNJ\DoiW@@W9T@2[FMroi.PIcJ^u0[,<&p/oJ-23K3)+*Tf^Ct&Kscf5.UMql7t>)l-7PK#QTFCLgGr8#0^,3C=a72K %@h*)4_InEf@Dj'@Cdk^sI'DNI#@s2UKW%^\%i@\+=Ht*W%>$Pm-bU&1d9jj:OgZ]?6K+`g[0(/*PeUf8?%-WM-Y7R29^%9C'?39T %5Y9KXJBjr;U\@W`NH158DC\G7c(ecpYJk_tV\QG@?4[trc:'Ne0t)-MJ]Np<"m&GGETO36,Vjsals\,q-n %MCDL#>27#Fn.@U8O>FGhp]d\-.S#[g/=[uLV,8Bfg_c9PM-4\U9LBY6MM_tf&GGG$AR**5*8,d^lX0/$V5LqDOCsGci_i[e2,-48 %r5D)T0G<#j`Tle..:Om-f'mGk3eABsn8^2fi[i>!O?9YCH:?UI">Di%aGl.oUuX)3c>jRN@9;B;i+,TKVR0l=\u3QGF(eO+"rZkI %Z0F;Q]0oM2^P;63icMQTI+=M(%I+dV99ZP_`+)Ur]FjT^h()&/^Wk/W&/*A7AV35`OOt6MS&cPJ9!6,@%JLmIUG:ki:7ZZ'E/WD# %-ZN_0C$7bW.@qU1JnD#@A`k="Oqr-a$'ZRZMlGE5T3X\lO="hb()<'6Oh%iLm>+ZV^l=lHR%fSVl/!K3"6:is!ZL`I:7CM-+^CXe %%<4aHkVreMEl,)tZA#&@68q#S0iQq?%b1#+i?CkQMaqGZW/lfYq!@Qh^lt.p#(1HEi>HA3V'J09AKl%$]MPa]eUZGhJZK)nMNXTT %.0^bXS(18mNY/#1G"Y+1oW$dq2feO*"/AS##sY0<[U %i"69aK#qeS"Xld_'P[c!@fi$WL>\'l1-7#FkS>BjKa#:d1a<-ug6WC<@9?OY:S`4MMN/&/@EV7\A%`>Z$OJ._ERC&ljeYhrKl(Y^ %ac#+(kYC%N/);j[?HP3"UfhQCcUu*8iIGMiWq+,F>!PIi;u/$XZT;P_0Y=$#`0'n4=M)G6XA`On&,e@)P1%E>?o$t%Zmr"(7ofiu %fYH+2@7e("nRsOD;oJSXL9H\E_;hGo9QDE7lRA3uE/FY4nKoX^LoaS7]WMui:6!B@BkLVhX-k98S.Vf;W^J3TPM_N\0?*0sU9=0?ot,#62hL`REbmN%R@:pkY1gD0pc[A'8i14&ZAT3O)M)KOCY(K09le:t5q<10kSN %fimjTj\@Eh0QadlCI(0UXrQ:;*TIf3(^GKU]!%4M)R8s,JJ3NW_9ZN-eLg"Ade%Ej$h6O'S[UdOhbf6k]E'_+;L[teg'r6oKYdaT %/m?RLhn!YW=]'H5?M9N[B"g&B$cS[UpSHoaf--pSb\h-6kI;E^J3m>J27[]fg$Du'%d+D["CdP$`k07,eO!cGbDKDB)cG//bT?Gt %.XEaaDt8$#!"*ocQ.;#)-`Pn@<)hF0PF"6-pHtg@r"OPqr#cDIDcUdcl?74V],lr %:+.o/_c56s93P;BN7\0F6l8u[Ggh4N$Q,$o1M0B0l\^`%!gK@>$utXl_i&ogO*RUm)QLZA"0US;oBhH.h;(0!`^U/eJcCh:C-X;ZcQmfTDVbl4Z_7%&Q:$s9O@:[oA;_ph=iO#P5lNf_o!r\F5!#pD+5 %pl)iSi:AA1_;`U,;p%BDRGE6,KJ&;]W&]L2NP9pWFPL%/:;9+1nA,ZfLnkN`]%e14f0R#1N=CPFOrT6@$Y=F@'(-U_\]9X=j!LaO %'Lr1?>r5k[K(Lu!_ld$X'D_GUe@jWsY32@TA.Q_+O@pV*ea7b97Y12]mr\W6KU6ba#e!Fl:a3YC&GmWSaD)ZoU=h,L,B.;&LU+9]%t$`&-,Zj=P>` %RHjkl\"&fS#CR()S"qY3aLQP**U%_M(<]nXGK/K&%n*YBI@p;"]#HrBZ=#-e6,ckT)U6[N/tk-o@FPiM2.<\/JRV;^,aX %S]j]*)25SgBO3PHcZG+_a=^Q@r`$%#Q)<-KL8Y0'eu_GQ%,bnudTnPdpnG#9@H,Pc[^$aXXcN*'G=XKR3_3UhB68g*6hapS %m*EC0r"!:"j_[j%gqBAVsk6#5t4-Lf/T9pP_mE=W+_:O-1"PYNeR. %)W*ZnZp6g7>#;5d&\K09aA&+!78Y5:"1P0qn!t2?!gp!m]"$b9CSN-dQp08oFY9M=8XC7Wn0rf28^sbf;::hr<%agrfn)ZpaQBGq %n?_b$;E_C>;l>^_H@mZjG7e?3=).qGjT@C=)_p0j2\.;YC*H9k5AD8Y4RDQXB_I96oi`7`&EHLQo0DPnG? %7eHt-,18?J6DQ!mVbge\?L8kA)dL)5nRrTog>!:V3j+a?dMUa4?OQ@Y4,T#'Ci%I>;4Uh/080tRL6-GjWbGH*pTuZ,Eb5$4p`__e %3Ia\-2cN6Tm+ASY^XMr/^pg*6cY=4;D#k%djUFT#^p,h3g7L6n4\cUE,%oC8.`5*ad9nDK3`s0[l];A?*'T9'o]R/,7k+hs<65[n %HF:*$BKDOp,n3UG]`j\dUj]S(3,Oe\kCC6%l\q*EW\16`Hq[-ib]`8n^rE%S/@k#J*[Hfc:NGR?j5A4fK>3cHc*9\e[%BNP$9&HQ %6(@s#YTFn9^?XFie@muTn\mIPs+,bQWFN)1X@@1M+Mp(]nRTMB9SUD/Bo>O(8U"(8XhC %J"`@uAqtH#pD>6q,aM\pnrSRaFE-D>@7"WD3,f4dK<3^dKZe+JCG9 %F:H-bZlKB12\m^(SH+mX!*`GCD?4;(*!YSR%+82VhJU0-ekk*XOud&>1f4N%N^d^97:;qGsmc&BFF %bus@/iU&+;?&,Ek44qZ<3lkjOET9NIJOjC+F/,a/ma/@C:2lfq<6Wg*pJhmZi3s`,MVJJ@('O^/8"=5%9Ro$S#F!-lPh)VYGb+M$ %im4Z$L]BWXWk"a=,\"-4:QC5[%bMJB+Br,J@70TpZSKsudPpcb"gMZ"7QhkH>+\uh^`^ZZL`Ft'NnbEcI]O\b4D%W77QEEdQ(`0a %JAm&ENB_spIHX622)dm3PWkW<`XBus=5@j$YSn!da*_J+jGPZ2e]?Yn'bJtsLJ-q%P_%ZQp2',"?:mLpEI+&fRK*A0SVjZ %=@X)53bAp-caMiP=^=Cg"-.E^+O;-p2rmR6U%2.VF;uY\YmWl=!.9#R%E!UWjT-[^@M>9-)3120\C`6f/AgF1RF %I!GNGK&JZ2MAR.0@N4U2'DUHPR\_Go"!)K:#qJOb[2T66Vl0S+cXX170aA!pP?CL/0'snoY;rX5(frW7VYa3EX`.WN!@-1M6'/$SK"u? %$d/IV%\cXb3i'$i`A!&m=I6$WR6hh5,3gS<.,gue#k.G@&Cakg([oIpR0UrmnL@p'A._]rihV==,a097Ee2!2EAu"(&GWBpCilK+ %FC'-0nk^\K&Ea<)R4$NAB/(\k:40%K<=9,EXduH#e@P)_&\_qkN/h!b_g82h'VUE6-aSOVDS)?K?HIhUVUM#T!!&R]b,2G;P[R*= %Ih>eL)3(XXY8@Qk0*"S(FjkOJd7(;rONqhKF3cm6L-9$=W^?h[d5]k4T`;1cY4@m9^S.T1jVR6g]YhHd^L4DOc:090edVqAQYS_nma_fBo$65L8@8f64M7&g=-:Qac2uHLOc5CAe&-MJU3h*j"B46 %?F;>OeQUSHn-?6X3])@L:g%n!2EY$8VplPZOdO0kM$dnR%O96@%P&oB)..7=Yc4(A)ad#e+Q-UnflCeYP9Y"'m/P2/<&LX+iMl&p %$J$/;/ne`CqHu,q^#agh:WlC'P!>DnRq3O@USmEZRcirb''*cLTk`1Mjs>6s8fc&Y1`0(<$qr%i+._@=p`l!IgKBc'cH+EjKZ['g %0UA8k,1+_sP4aieoQ$Jifl$A[4'8PnK[tt:@Y*=+D'p@sfQBc?`Bg#k %Z-fLp!+&`(6b08$!Zse<8#0sRB(RR>Uc1_HY,udACT,IG&i3%G9:_"%P6K$+Lp1Ed>(TdE:l6:!P=j@"!cLkE#j<7QZa'[Bi2j4j %:oWn5,T/T?30;IeD-]54S0#!O?B^2_`*GbO64HL,PPHbcCNL+kDfeN6P`8ObSIr5VD(l.a,3o$J3ane_5[VUUUU^"YCkLReVfC7- %PX7+1L8WHc6?"fQ%`>Aind2<5\U%2I*&)20WIPS'P5aj?%H0_Ia@I8S@'Y=u8 %F4O/,L$aR4kG""eq+KuA7WCIHJmO]#UKJKKBs&K0n)i3$H7BRpF"e`[*U2BY9rZRm2C"))kpNl2Wgu>l>Tr^7PsS"U]m.gLplc/I %beFY!!"e_G=\FQQ2^JTbDeARb]Sae'$A*r5K]@d!9hkBD!h(33_JWk>@^6Mt<7]4=.]'0##V1M+^8cWS*$<'d\k-*985E(gJ-]2L %SATnZW75CC1*c3W/Eebo]+V*iYIR-aOE^m %1%DY"*`5G9[o+C"`S(F!r,G[Vm27^VXq,3K:T/Y2/MPWq&ZUm,r$GK!R>"ZaFi!Wk,q.pR1TbR6\mD9+baWN_[a[#,Pkl#YjHad3)KiZr$l4L.]#nZp98;U$ONL,Be'eGQUB?!=,"e<%hB67-.jZ %%+6E9jAKV2K)#8_$`+kJ_4@stGN_F]=uR7B[rcZ0Z#F^aF]04lp=,J'Kf(g/Cqgr@%b)('$oYN%W6lQ$u %0Y29*HdJ,(W-`g=,M0f+J6c@tO8o\9do:=uF"(&hI(\O9G?1VP.s2,dKH?8U1D;NI`-7W3]0f/q$(d%E?#AX5.,.Sjl/T,nKUQ<4 %Rad3dRrSZemVAg`?uZX(nf5<.7ZQ$?'(Dim>ch=<6tKi`(^2=ibfN=,gXI3A13j)`)/9W[E,5Nj/jH[:$l9d[9c%B45"'.@efduS %m7\Of!`pQ4C`*O9#Q0*.k"nOBU4N`eiE[CrC>oN,8^o"J8o7IkCA)>Kn]2Q__+SG[`9Sa66W\oC'K$)rS]LjY<5%!UK9q-dmQ"ZJ %)**NZ'8lrPR"iFNBP6lRODh6SVN=%FmS;^Q9rW4>bXN%eg7O"WYd1/=8^b1rWbi&Kmu5DTa$$O'UDPMFIWeh%QP\5Xh,jD<'K %,N*ec=RAuPE*6bT604AS"LkM,m6:2j!0G'nqO1qp;-D6%kQh`fS=ig1mR;1H@3ndGk&+9uXWuf?Wg:&+LLLOf;$k!@_S/9pOCq+) %1&t/;E&bpE-V!!1?>ME.#c`I%??$@UN4)KCSrT;/]%+X\Tg&0H\?V/l97;[ %o5l7EcuhGA&1.ecWY6efa"Rsr]WAKdMmNUGW_2(I.gK"8D%^VI1.JJXf+f8GTH2<&.'.jebA-k)jf^h?K0a:2=?Fs1Gid#.2;uEf %&WfUb(#S7X)g;qBg-7YTV?bk=4(a8?.&ma=Ef>+3#VN(p60P(I&sT6`?`,*<`>J6;*+`;ZOLmEjYs#>TS/7>Q2fpdRK!X\nC6^k4?]NV,AG?P"d@jhf('=P[[WTNC@H(2G %oV1kk$2u`mJ"K4cBjB20O@I'=Zl,";19%[$8uApsWo-9j*F&%K.jGB>J_.4%;[7DDh'A@;@6nW23'!JBD-aFu&7_"W>N=N,;Ym5I %G6$Gs'FV4hI8Ff;Sl`QZl3IkE#cdr03g+bs.Fr/:c"ccC6U8huMQjp!3:%(;\`k50kY"/h\9WGJ-8-J(WeZ>M/dk%I.P6q9AMrs$ %<,!eEj42<536/2hP0-6cJR@6SS]S4e``H0]fE(S0(4+'Nk.Z.iC2E\-Cfen^D&s19@B4:GaV.15N9*ulKtAd-D&`Y>jt#F@9H=.W %O*[aPReWbG#a!p"dZeRaNcH:(X[EAE27`jL(eB=d"XO\S=4&*d.?*f\@d# %FD"e_e2jIi20 %-nuMNaVqPE"MbYk0c=O_iq9hFe=)8k5kMbsRfdGX]33)UW`;WX%sP*B7$"j1lKC^Xb0;IS.RDU?5;g!M_S`o0*%!+5.H$rWP&QX6 %+4p/#O#Ei8S2r]/DLD=p6u%AgJ/?kAS*cH!BH"c:&sLk=4_iL07b=cI=^u-oX\5dnm$(FSJOcsi/bRQS_K?ubMI?J'+^qYmra$h;&NH#7l3%!l`P)hbsP!7Wm#6BX!Qb_1ZOYFC$C;J!r+5l]4mR&-<]J!1-KD5g(q35-aAOMuL1oT4:@i7DdM(8Rbu$IE<`t$0`7X^%6c-2W %Ng>I4&X,6&3CAWdRNKj)R;lXp/6*$oVE%*3g(W\$%:8^P/!m)lG0\$F4'RJ6gBbR7%UjU3Y=@#]XTZ`UgcZO'969%o*)lDJP:+;V>7>^<^;XiRQ1X\,\5`Mr)qsQ[ANnEh8I;\Ng %=6GQHmH,#!fe)TdW0o_.9_;ZXf:)B8V_p!@dtAtud[]Ij>f>ZS[)'P?(tK`i %[FB8D#NFgAaeNR'L.K%f+H7S9q=3(q%ePQMRGl1,d6*f4-ngW0S&H/e0*s=Og2Lmss%+cM38J800cBsfqb0[7cpE/c$F3N3KnP^XuS&R'HbuB]/,4Uq;HT=?uDf(6@Ms3_\\L4kb///4SM7N^L %'L)_AU)H!"k/K9FCXJhPW&sXl)i,KE4'?C#YZ)pcFm-fP4i^S]R %$T5;sZhNmgf8Q %7U9R+%t[tsK*X;9MlGbd8CD/D@IBD`^H\@b8H8I1jM.WHFn"8nht#1EahdYoN$rG.JPrR(-9AbDaAJ]NV@Yn %[BGnQQD+RuKP.W2(UjCJ_.\e#eioubp,4tc&=7)83?F-+"NDr_Um+0d`#uMHOM@3N%&ckGHQ=GJkmZBi/"5?nV>4#S5*TJp';Hgq %GhKX`U6(^&1iVQR/0hPQh(Ec7>+,9eMl`W&d$S(0V"-fbp,:b$S58@pW=5),_S"b`%.n+^s\(q5>P]]J82!ZQsVTp5:69'CTI3d`baF032d0e%qt %7d/XS8J^BBPj'7[E!/(]hZgVqC!9KO9d+,6F"A#VW2fC/AJ\joWD;N;Jjl/%'qm6toGG')$>bfo%dnqS/PT`WC2^@,?BrI/2p)